aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kabaev <kan@FreeBSD.org>2004-07-28 03:11:36 +0000
committerAlexander Kabaev <kan@FreeBSD.org>2004-07-28 03:11:36 +0000
commit9a63ad9273061dc19cbd117762e365ea9634e241 (patch)
tree052f4bb635f2bea2c5e350bd60c902be100a0d1e
parentfe349557597c18e74a14e9a0d2bdb422892159d8 (diff)
downloadsrc-9a63ad9273061dc19cbd117762e365ea9634e241.tar.gz
src-9a63ad9273061dc19cbd117762e365ea9634e241.zip
Gcc 3.4.2 20040728.
Notes
Notes: svn path=/vendor/gcc/dist/; revision=132718
-rw-r--r--contrib/gcc/ChangeLog21097
-rw-r--r--contrib/gcc/ChangeLog.14
-rw-r--r--contrib/gcc/ChangeLog.1016352
-rw-r--r--contrib/gcc/ChangeLog.26
-rw-r--r--contrib/gcc/ChangeLog.36
-rw-r--r--contrib/gcc/ChangeLog.42
-rw-r--r--contrib/gcc/ChangeLog.52
-rw-r--r--contrib/gcc/ChangeLog.68
-rw-r--r--contrib/gcc/ChangeLog.74
-rw-r--r--contrib/gcc/ChangeLog.814448
-rw-r--r--contrib/gcc/ChangeLog.921488
-rw-r--r--contrib/gcc/Makefile.in3068
-rw-r--r--contrib/gcc/README.Portability226
-rw-r--r--contrib/gcc/aclocal.m41078
-rw-r--r--contrib/gcc/alias.c764
-rw-r--r--contrib/gcc/alloc-pool.c367
-rw-r--r--contrib/gcc/alloc-pool.h55
-rw-r--r--contrib/gcc/ansidecl.h11
-rw-r--r--contrib/gcc/attribs.c59
-rw-r--r--contrib/gcc/basic-block.h572
-rw-r--r--contrib/gcc/bb-reorder.c1242
-rw-r--r--contrib/gcc/bitmap.c153
-rw-r--r--contrib/gcc/bitmap.h43
-rw-r--r--contrib/gcc/bt-load.c1377
-rw-r--r--contrib/gcc/builtin-attrs.def100
-rw-r--r--contrib/gcc/builtin-types.def122
-rw-r--r--contrib/gcc/builtins.c4429
-rw-r--r--contrib/gcc/builtins.def1157
-rw-r--r--contrib/gcc/c-aux-info.c55
-rw-r--r--contrib/gcc/c-common.c2834
-rw-r--r--contrib/gcc/c-common.def3
-rw-r--r--contrib/gcc/c-common.h582
-rw-r--r--contrib/gcc/c-convert.c8
-rw-r--r--contrib/gcc/c-cppbuiltin.c591
-rw-r--r--contrib/gcc/c-decl.c5788
-rw-r--r--contrib/gcc/c-dump.c18
-rw-r--r--contrib/gcc/c-errors.c34
-rw-r--r--contrib/gcc/c-format.c913
-rw-r--r--contrib/gcc/c-incpath.c364
-rw-r--r--contrib/gcc/c-incpath.h23
-rw-r--r--contrib/gcc/c-lang.c111
-rw-r--r--contrib/gcc/c-lex.c752
-rw-r--r--contrib/gcc/c-objc-common.c304
-rw-r--r--contrib/gcc/c-opts.c1640
-rw-r--r--contrib/gcc/c-parse.in928
-rw-r--r--contrib/gcc/c-pch.c433
-rw-r--r--contrib/gcc/c-ppoutput.c415
-rw-r--r--contrib/gcc/c-pragma.c89
-rw-r--r--contrib/gcc/c-pragma.h33
-rw-r--r--contrib/gcc/c-pretty-print.c2213
-rw-r--r--contrib/gcc/c-pretty-print.h197
-rw-r--r--contrib/gcc/c-semantics.c536
-rw-r--r--contrib/gcc/c-tree.h346
-rw-r--r--contrib/gcc/c-typeck.c2775
-rw-r--r--contrib/gcc/c.opt825
-rw-r--r--contrib/gcc/caller-save.c115
-rw-r--r--contrib/gcc/calls.c1770
-rw-r--r--contrib/gcc/cfg.c460
-rw-r--r--contrib/gcc/cfganal.c191
-rw-r--r--contrib/gcc/cfgbuild.c128
-rw-r--r--contrib/gcc/cfgcleanup.c664
-rw-r--r--contrib/gcc/cfghooks.c48
-rw-r--r--contrib/gcc/cfghooks.h83
-rw-r--r--contrib/gcc/cfglayout.c826
-rw-r--r--contrib/gcc/cfglayout.h26
-rw-r--r--contrib/gcc/cfgloop.c420
-rw-r--r--contrib/gcc/cfgloop.h341
-rw-r--r--contrib/gcc/cfgloopanal.c1482
-rw-r--r--contrib/gcc/cfgloopmanip.c1244
-rw-r--r--contrib/gcc/cfgrtl.c1427
-rw-r--r--contrib/gcc/cgraph.c644
-rw-r--r--contrib/gcc/cgraph.h192
-rw-r--r--contrib/gcc/cgraphunit.c1613
-rw-r--r--contrib/gcc/collect2.c1209
-rw-r--r--contrib/gcc/collect2.h27
-rw-r--r--contrib/gcc/combine.c1488
-rw-r--r--contrib/gcc/common.opt808
-rw-r--r--contrib/gcc/config.build123
-rw-r--r--contrib/gcc/config.gcc2762
-rw-r--r--contrib/gcc/config.host155
-rw-r--r--contrib/gcc/config.in830
-rw-r--r--contrib/gcc/config/alpha/alpha-modes.def23
-rw-r--r--contrib/gcc/config/alpha/alpha-protos.h245
-rw-r--r--contrib/gcc/config/alpha/alpha.c2906
-rw-r--r--contrib/gcc/config/alpha/alpha.h528
-rw-r--r--contrib/gcc/config/alpha/alpha.md697
-rw-r--r--contrib/gcc/config/alpha/elf.h73
-rw-r--r--contrib/gcc/config/alpha/ev4.md8
-rw-r--r--contrib/gcc/config/alpha/ev5.md8
-rw-r--r--contrib/gcc/config/alpha/ev6.md8
-rw-r--r--contrib/gcc/config/alpha/freebsd.h24
-rw-r--r--contrib/gcc/config/alpha/gnu.h6
-rw-r--r--contrib/gcc/config/alpha/lib1funcs.asm2
-rw-r--r--contrib/gcc/config/alpha/linux-elf.h18
-rw-r--r--contrib/gcc/config/alpha/linux.h18
-rw-r--r--contrib/gcc/config/alpha/netbsd.h13
-rw-r--r--contrib/gcc/config/alpha/openbsd.h50
-rw-r--r--contrib/gcc/config/alpha/osf.h48
-rw-r--r--contrib/gcc/config/alpha/osf5.h22
-rw-r--r--contrib/gcc/config/alpha/t-osf-pthread5
-rw-r--r--contrib/gcc/config/alpha/t-osf44
-rw-r--r--contrib/gcc/config/alpha/unicosmk.h91
-rw-r--r--contrib/gcc/config/alpha/vms-cc.c81
-rw-r--r--contrib/gcc/config/alpha/vms-crt0-64.c10
-rw-r--r--contrib/gcc/config/alpha/vms-crt0.c10
-rw-r--r--contrib/gcc/config/alpha/vms-dwarf2.asm8
-rw-r--r--contrib/gcc/config/alpha/vms-dwarf2eh.asm8
-rw-r--r--contrib/gcc/config/alpha/vms-ld.c74
-rw-r--r--contrib/gcc/config/alpha/vms-psxcrt0-64.c10
-rw-r--r--contrib/gcc/config/alpha/vms-psxcrt0.c10
-rw-r--r--contrib/gcc/config/alpha/vms.h98
-rw-r--r--contrib/gcc/config/alpha/vms64.h8
-rw-r--r--contrib/gcc/config/alpha/vms_tramp.asm8
-rw-r--r--contrib/gcc/config/alpha/xm-vms.h11
-rw-r--r--contrib/gcc/config/arm/README-interworking2
-rw-r--r--contrib/gcc/config/arm/aof.h295
-rw-r--r--contrib/gcc/config/arm/aout.h154
-rw-r--r--contrib/gcc/config/arm/arm-modes.def66
-rw-r--r--contrib/gcc/config/arm/arm-protos.h346
-rw-r--r--contrib/gcc/config/arm/arm.c4192
-rw-r--r--contrib/gcc/config/arm/arm.h1374
-rw-r--r--contrib/gcc/config/arm/arm.md3143
-rw-r--r--contrib/gcc/config/arm/cirrus.md478
-rw-r--r--contrib/gcc/config/arm/coff.h50
-rw-r--r--contrib/gcc/config/arm/crtn.asm2
-rw-r--r--contrib/gcc/config/arm/ecos-elf.h26
-rw-r--r--contrib/gcc/config/arm/elf.h75
-rw-r--r--contrib/gcc/config/arm/fpa.md752
-rw-r--r--contrib/gcc/config/arm/freebsd.h49
-rw-r--r--contrib/gcc/config/arm/ieee754-df.S1224
-rw-r--r--contrib/gcc/config/arm/ieee754-sf.S816
-rw-r--r--contrib/gcc/config/arm/iwmmxt.md1524
-rw-r--r--contrib/gcc/config/arm/kaos-arm.h24
-rw-r--r--contrib/gcc/config/arm/kaos-strongarm.h24
-rw-r--r--contrib/gcc/config/arm/lib1funcs.asm668
-rw-r--r--contrib/gcc/config/arm/linux-elf.h52
-rw-r--r--contrib/gcc/config/arm/linux-gas.h32
-rw-r--r--contrib/gcc/config/arm/mmintrin.h1257
-rw-r--r--contrib/gcc/config/arm/netbsd-elf.h36
-rw-r--r--contrib/gcc/config/arm/netbsd.h38
-rw-r--r--contrib/gcc/config/arm/pe.c41
-rw-r--r--contrib/gcc/config/arm/pe.h86
-rw-r--r--contrib/gcc/config/arm/rtems-elf.h27
-rw-r--r--contrib/gcc/config/arm/semi.h32
-rw-r--r--contrib/gcc/config/arm/semiaof.h30
-rw-r--r--contrib/gcc/config/arm/strongarm-coff.h26
-rw-r--r--contrib/gcc/config/arm/strongarm-elf.h26
-rw-r--r--contrib/gcc/config/arm/strongarm-pe.h26
-rw-r--r--contrib/gcc/config/arm/t-arm-coff2
-rw-r--r--contrib/gcc/config/arm/t-arm-elf35
-rw-r--r--contrib/gcc/config/arm/t-linux3
-rw-r--r--contrib/gcc/config/arm/t-netbsd5
-rw-r--r--contrib/gcc/config/arm/t-pe8
-rw-r--r--contrib/gcc/config/arm/t-semi6
-rw-r--r--contrib/gcc/config/arm/t-strongarm-pe5
-rw-r--r--contrib/gcc/config/arm/t-vxworks10
-rw-r--r--contrib/gcc/config/arm/t-wince-pe37
-rw-r--r--contrib/gcc/config/arm/t-xscale-elf4
-rw-r--r--contrib/gcc/config/arm/uclinux-elf.h26
-rw-r--r--contrib/gcc/config/arm/unknown-elf.h39
-rw-r--r--contrib/gcc/config/arm/vxworks.h95
-rw-r--r--contrib/gcc/config/arm/wince-pe.h29
-rw-r--r--contrib/gcc/config/arm/xscale-elf.h51
-rw-r--r--contrib/gcc/config/darwin-c.c33
-rw-r--r--contrib/gcc/config/darwin-protos.h170
-rw-r--r--contrib/gcc/config/darwin.c609
-rw-r--r--contrib/gcc/config/darwin.h154
-rw-r--r--contrib/gcc/config/dbx.h8
-rw-r--r--contrib/gcc/config/dbxcoff.h16
-rw-r--r--contrib/gcc/config/dbxelf.h16
-rw-r--r--contrib/gcc/config/elfos.h86
-rw-r--r--contrib/gcc/config/fp-bit.c104
-rw-r--r--contrib/gcc/config/fp-bit.h8
-rw-r--r--contrib/gcc/config/freebsd-nthr.h8
-rw-r--r--contrib/gcc/config/freebsd-spec.h17
-rw-r--r--contrib/gcc/config/freebsd.h11
-rw-r--r--contrib/gcc/config/frv/cmovd.c17
-rw-r--r--contrib/gcc/config/frv/cmovh.c17
-rw-r--r--contrib/gcc/config/frv/cmovw.c17
-rw-r--r--contrib/gcc/config/frv/frv-abi.h8
-rw-r--r--contrib/gcc/config/frv/frv-asm.h18
-rw-r--r--contrib/gcc/config/frv/frv-modes.def14
-rw-r--r--contrib/gcc/config/frv/frv-protos.h329
-rw-r--r--contrib/gcc/config/frv/frv.c1736
-rw-r--r--contrib/gcc/config/frv/frv.h392
-rw-r--r--contrib/gcc/config/frv/frv.md70
-rw-r--r--contrib/gcc/config/frv/frvbegin.c33
-rw-r--r--contrib/gcc/config/frv/frvend.c19
-rw-r--r--contrib/gcc/config/frv/lib1funcs.asm17
-rw-r--r--contrib/gcc/config/frv/t-frv6
-rw-r--r--contrib/gcc/config/gnu.h12
-rw-r--r--contrib/gcc/config/gofast.h146
-rw-r--r--contrib/gcc/config/i386/athlon.md1033
-rw-r--r--contrib/gcc/config/i386/att.h30
-rw-r--r--contrib/gcc/config/i386/beos-elf.h11
-rw-r--r--contrib/gcc/config/i386/biarch64.h8
-rw-r--r--contrib/gcc/config/i386/bsd.h27
-rw-r--r--contrib/gcc/config/i386/crtdll.h27
-rw-r--r--contrib/gcc/config/i386/cygming.h391
-rw-r--r--contrib/gcc/config/i386/cygwin.asm42
-rw-r--r--contrib/gcc/config/i386/cygwin.h560
-rw-r--r--contrib/gcc/config/i386/cygwin1.c54
-rw-r--r--contrib/gcc/config/i386/cygwin2.c67
-rw-r--r--contrib/gcc/config/i386/darwin.h27
-rw-r--r--contrib/gcc/config/i386/djgpp.h29
-rw-r--r--contrib/gcc/config/i386/emmintrin.h22
-rw-r--r--contrib/gcc/config/i386/freebsd-aout.h12
-rw-r--r--contrib/gcc/config/i386/freebsd.h28
-rw-r--r--contrib/gcc/config/i386/freebsd64.h13
-rw-r--r--contrib/gcc/config/i386/gas.h18
-rw-r--r--contrib/gcc/config/i386/gnu.h10
-rw-r--r--contrib/gcc/config/i386/gthr-win32.c4
-rw-r--r--contrib/gcc/config/i386/i386-aout.h8
-rw-r--r--contrib/gcc/config/i386/i386-coff.h15
-rw-r--r--contrib/gcc/config/i386/i386-interix.h78
-rw-r--r--contrib/gcc/config/i386/i386-interix3.h10
-rw-r--r--contrib/gcc/config/i386/i386-modes.def42
-rw-r--r--contrib/gcc/config/i386/i386-protos.h400
-rw-r--r--contrib/gcc/config/i386/i386.c4972
-rw-r--r--contrib/gcc/config/i386/i386.h872
-rw-r--r--contrib/gcc/config/i386/i386.md5228
-rw-r--r--contrib/gcc/config/i386/i386elf.h18
-rw-r--r--contrib/gcc/config/i386/k6.md14
-rw-r--r--contrib/gcc/config/i386/kaos-i386.h24
-rw-r--r--contrib/gcc/config/i386/kfreebsdgnu.h35
-rw-r--r--contrib/gcc/config/i386/linux-aout.h13
-rw-r--r--contrib/gcc/config/i386/linux.h45
-rw-r--r--contrib/gcc/config/i386/linux64.h41
-rw-r--r--contrib/gcc/config/i386/lynx-ng.h15
-rw-r--r--contrib/gcc/config/i386/lynx.h15
-rw-r--r--contrib/gcc/config/i386/mingw32.h63
-rw-r--r--contrib/gcc/config/i386/mmintrin.h8
-rw-r--r--contrib/gcc/config/i386/moss.h9
-rw-r--r--contrib/gcc/config/i386/netbsd-elf.h16
-rw-r--r--contrib/gcc/config/i386/netbsd.h2
-rw-r--r--contrib/gcc/config/i386/netbsd64.h14
-rw-r--r--contrib/gcc/config/i386/nto.h99
-rw-r--r--contrib/gcc/config/i386/openbsd.h13
-rw-r--r--contrib/gcc/config/i386/pentium.md20
-rw-r--r--contrib/gcc/config/i386/pmmintrin.h12
-rw-r--r--contrib/gcc/config/i386/ppro.md12
-rw-r--r--contrib/gcc/config/i386/ptx4-i.h18
-rw-r--r--contrib/gcc/config/i386/rtemself.h9
-rw-r--r--contrib/gcc/config/i386/sco5.h17
-rw-r--r--contrib/gcc/config/i386/sol2.h25
-rw-r--r--contrib/gcc/config/i386/svr3dbx.h10
-rw-r--r--contrib/gcc/config/i386/svr3gas.h12
-rw-r--r--contrib/gcc/config/i386/sysv3.h15
-rw-r--r--contrib/gcc/config/i386/sysv4-cpp.h10
-rw-r--r--contrib/gcc/config/i386/sysv4.h27
-rw-r--r--contrib/gcc/config/i386/sysv5.h8
-rw-r--r--contrib/gcc/config/i386/t-beos3
-rw-r--r--contrib/gcc/config/i386/t-cygming19
-rw-r--r--contrib/gcc/config/i386/t-cygwin27
-rw-r--r--contrib/gcc/config/i386/t-interix5
-rw-r--r--contrib/gcc/config/i386/t-nto4
-rw-r--r--contrib/gcc/config/i386/t-sco51
-rw-r--r--contrib/gcc/config/i386/t-vxworks8
-rw-r--r--contrib/gcc/config/i386/unix.h10
-rw-r--r--contrib/gcc/config/i386/uwin.h14
-rw-r--r--contrib/gcc/config/i386/vsta.h8
-rw-r--r--contrib/gcc/config/i386/vxworks.h74
-rw-r--r--contrib/gcc/config/i386/winnt.c379
-rw-r--r--contrib/gcc/config/i386/x-mingw324
-rw-r--r--contrib/gcc/config/i386/x86-64.h24
-rw-r--r--contrib/gcc/config/i386/xm-cygwin.h23
-rw-r--r--contrib/gcc/config/i386/xm-djgpp.h23
-rw-r--r--contrib/gcc/config/i386/xm-mingw32.h40
-rw-r--r--contrib/gcc/config/i386/xmmintrin.h31
-rw-r--r--contrib/gcc/config/ia64/crtbegin.asm269
-rw-r--r--contrib/gcc/config/ia64/crtend.asm102
-rw-r--r--contrib/gcc/config/ia64/crti.asm20
-rw-r--r--contrib/gcc/config/ia64/crtn.asm14
-rw-r--r--contrib/gcc/config/ia64/elf.h10
-rw-r--r--contrib/gcc/config/ia64/fde-glibc.c14
-rw-r--r--contrib/gcc/config/ia64/freebsd.h19
-rw-r--r--contrib/gcc/config/ia64/hpux.h55
-rw-r--r--contrib/gcc/config/ia64/ia64-c.c20
-rw-r--r--contrib/gcc/config/ia64/ia64-modes.def51
-rw-r--r--contrib/gcc/config/ia64/ia64-protos.h222
-rw-r--r--contrib/gcc/config/ia64/ia64.c5224
-rw-r--r--contrib/gcc/config/ia64/ia64.h286
-rw-r--r--contrib/gcc/config/ia64/ia64.md1861
-rw-r--r--contrib/gcc/config/ia64/itanium1.md1616
-rw-r--r--contrib/gcc/config/ia64/itanium2.md1762
-rw-r--r--contrib/gcc/config/ia64/lib1funcs.asm46
-rw-r--r--contrib/gcc/config/ia64/linux.h124
-rw-r--r--contrib/gcc/config/ia64/quadlib.c8
-rw-r--r--contrib/gcc/config/ia64/sysv4.h26
-rw-r--r--contrib/gcc/config/ia64/t-hpux11
-rw-r--r--contrib/gcc/config/ia64/t-ia6413
-rw-r--r--contrib/gcc/config/ia64/unwind-ia64.c168
-rw-r--r--contrib/gcc/config/ia64/unwind-ia64.h8
-rw-r--r--contrib/gcc/config/interix.h21
-rw-r--r--contrib/gcc/config/interix3.h8
-rw-r--r--contrib/gcc/config/kaos.h31
-rw-r--r--contrib/gcc/config/kfreebsdgnu.h41
-rw-r--r--contrib/gcc/config/libgloss.h8
-rw-r--r--contrib/gcc/config/linux-aout.h18
-rw-r--r--contrib/gcc/config/linux.h53
-rw-r--r--contrib/gcc/config/lynx-ng.h8
-rw-r--r--contrib/gcc/config/lynx.h27
-rw-r--r--contrib/gcc/config/netbsd-aout.h12
-rw-r--r--contrib/gcc/config/netbsd-elf.h9
-rw-r--r--contrib/gcc/config/netbsd.h21
-rw-r--r--contrib/gcc/config/openbsd-oldgas.h8
-rw-r--r--contrib/gcc/config/openbsd.h23
-rw-r--r--contrib/gcc/config/ptx4.h49
-rw-r--r--contrib/gcc/config/rs6000/40x.md107
-rw-r--r--contrib/gcc/config/rs6000/440.md120
-rw-r--r--contrib/gcc/config/rs6000/603.md127
-rw-r--r--contrib/gcc/config/rs6000/6xx.md234
-rw-r--r--contrib/gcc/config/rs6000/7450.md162
-rw-r--r--contrib/gcc/config/rs6000/7xx.md167
-rw-r--r--contrib/gcc/config/rs6000/8540.md235
-rw-r--r--contrib/gcc/config/rs6000/aix.h134
-rw-r--r--contrib/gcc/config/rs6000/aix41.h29
-rw-r--r--contrib/gcc/config/rs6000/aix43.h41
-rw-r--r--contrib/gcc/config/rs6000/aix51.h46
-rw-r--r--contrib/gcc/config/rs6000/aix52.h46
-rw-r--r--contrib/gcc/config/rs6000/altivec-defs.h30
-rw-r--r--contrib/gcc/config/rs6000/altivec.h69
-rw-r--r--contrib/gcc/config/rs6000/altivec.md486
-rw-r--r--contrib/gcc/config/rs6000/beos.h30
-rw-r--r--contrib/gcc/config/rs6000/biarch64.h22
-rw-r--r--contrib/gcc/config/rs6000/crtsavres.asm102
-rw-r--r--contrib/gcc/config/rs6000/darwin-ldouble.c205
-rw-r--r--contrib/gcc/config/rs6000/darwin.h170
-rw-r--r--contrib/gcc/config/rs6000/default64.h24
-rw-r--r--contrib/gcc/config/rs6000/eabi-ci.asm2
-rw-r--r--contrib/gcc/config/rs6000/eabi-cn.asm2
-rw-r--r--contrib/gcc/config/rs6000/eabi.h39
-rw-r--r--contrib/gcc/config/rs6000/eabialtivec.h34
-rw-r--r--contrib/gcc/config/rs6000/eabisim.h33
-rw-r--r--contrib/gcc/config/rs6000/eabispe.h70
-rw-r--r--contrib/gcc/config/rs6000/freebsd.h29
-rw-r--r--contrib/gcc/config/rs6000/gnu.h30
-rw-r--r--contrib/gcc/config/rs6000/host-darwin.c189
-rw-r--r--contrib/gcc/config/rs6000/kaos-ppc.h24
-rw-r--r--contrib/gcc/config/rs6000/libgcc-ppc64.ver7
-rw-r--r--contrib/gcc/config/rs6000/linux.h60
-rw-r--r--contrib/gcc/config/rs6000/linux64.h686
-rw-r--r--contrib/gcc/config/rs6000/linuxaltivec.h32
-rw-r--r--contrib/gcc/config/rs6000/linuxspe.h70
-rw-r--r--contrib/gcc/config/rs6000/lynx.h80
-rw-r--r--contrib/gcc/config/rs6000/lynxbase.h45
-rw-r--r--contrib/gcc/config/rs6000/mpc.md99
-rw-r--r--contrib/gcc/config/rs6000/netbsd.h50
-rw-r--r--contrib/gcc/config/rs6000/power4.md392
-rw-r--r--contrib/gcc/config/rs6000/power5.md299
-rw-r--r--contrib/gcc/config/rs6000/ppc-asm.h38
-rw-r--r--contrib/gcc/config/rs6000/ppc64-fp.c55
-rw-r--r--contrib/gcc/config/rs6000/rios1.md179
-rw-r--r--contrib/gcc/config/rs6000/rios2.md117
-rw-r--r--contrib/gcc/config/rs6000/rs6000-c.c41
-rw-r--r--contrib/gcc/config/rs6000/rs6000-modes.def43
-rw-r--r--contrib/gcc/config/rs6000/rs6000-protos.h350
-rw-r--r--contrib/gcc/config/rs6000/rs6000.c7611
-rw-r--r--contrib/gcc/config/rs6000/rs6000.h934
-rw-r--r--contrib/gcc/config/rs6000/rs6000.md3233
-rw-r--r--contrib/gcc/config/rs6000/rs64.md128
-rw-r--r--contrib/gcc/config/rs6000/rtems.h27
-rw-r--r--contrib/gcc/config/rs6000/sol-ci.asm2
-rw-r--r--contrib/gcc/config/rs6000/sol-cn.asm2
-rw-r--r--contrib/gcc/config/rs6000/spe.h649
-rw-r--r--contrib/gcc/config/rs6000/spe.md530
-rw-r--r--contrib/gcc/config/rs6000/sysv4.h656
-rw-r--r--contrib/gcc/config/rs6000/sysv4le.h41
-rw-r--r--contrib/gcc/config/rs6000/t-beos17
-rw-r--r--contrib/gcc/config/rs6000/t-darwin9
-rw-r--r--contrib/gcc/config/rs6000/t-fprules29
-rw-r--r--contrib/gcc/config/rs6000/t-linux6453
-rw-r--r--contrib/gcc/config/rs6000/t-newas17
-rw-r--r--contrib/gcc/config/rs6000/t-ppccomm23
-rw-r--r--contrib/gcc/config/rs6000/t-ppcgas7
-rw-r--r--contrib/gcc/config/rs6000/t-rs600031
-rw-r--r--contrib/gcc/config/rs6000/t-spe68
-rw-r--r--contrib/gcc/config/rs6000/t-vxworks10
-rw-r--r--contrib/gcc/config/rs6000/tramp.asm2
-rw-r--r--contrib/gcc/config/rs6000/vxworks.h82
-rw-r--r--contrib/gcc/config/rs6000/windiss.h42
-rw-r--r--contrib/gcc/config/rs6000/x-darwin4
-rw-r--r--contrib/gcc/config/rs6000/x-linux642
-rw-r--r--contrib/gcc/config/rs6000/xcoff.h165
-rw-r--r--contrib/gcc/config/rtems.h24
-rw-r--r--contrib/gcc/config/s390/2064.md131
-rw-r--r--contrib/gcc/config/s390/2084.md262
-rw-r--r--contrib/gcc/config/s390/fixdfdi.h24
-rw-r--r--contrib/gcc/config/s390/linux.h73
-rw-r--r--contrib/gcc/config/s390/s390-modes.def60
-rw-r--r--contrib/gcc/config/s390/s390-protos.h161
-rw-r--r--contrib/gcc/config/s390/s390.c3889
-rw-r--r--contrib/gcc/config/s390/s390.h457
-rw-r--r--contrib/gcc/config/s390/s390.md5624
-rw-r--r--contrib/gcc/config/s390/s390x.h25
-rw-r--r--contrib/gcc/config/s390/t-tpf13
-rw-r--r--contrib/gcc/config/s390/tpf.h112
-rw-r--r--contrib/gcc/config/sol2.h47
-rw-r--r--contrib/gcc/config/sparc/aout.h26
-rw-r--r--contrib/gcc/config/sparc/biarch64.h10
-rw-r--r--contrib/gcc/config/sparc/cypress.md8
-rw-r--r--contrib/gcc/config/sparc/elf.h30
-rw-r--r--contrib/gcc/config/sparc/freebsd.h37
-rw-r--r--contrib/gcc/config/sparc/gmon-sol2.c29
-rw-r--r--contrib/gcc/config/sparc/hypersparc.md8
-rw-r--r--contrib/gcc/config/sparc/linux.h89
-rw-r--r--contrib/gcc/config/sparc/linux64.h102
-rw-r--r--contrib/gcc/config/sparc/lite.h18
-rw-r--r--contrib/gcc/config/sparc/litecoff.h19
-rw-r--r--contrib/gcc/config/sparc/liteelf.h25
-rw-r--r--contrib/gcc/config/sparc/netbsd-elf.h41
-rw-r--r--contrib/gcc/config/sparc/openbsd.h29
-rw-r--r--contrib/gcc/config/sparc/openbsd64.h19
-rw-r--r--contrib/gcc/config/sparc/pbd.h39
-rw-r--r--contrib/gcc/config/sparc/rtemself.h23
-rw-r--r--contrib/gcc/config/sparc/sol2-64.h11
-rw-r--r--contrib/gcc/config/sparc/sol2-bi.h80
-rw-r--r--contrib/gcc/config/sparc/sol2-gas-bi.h6
-rw-r--r--contrib/gcc/config/sparc/sol2-gld-bi.h27
-rw-r--r--contrib/gcc/config/sparc/sol2-gld.h5
-rw-r--r--contrib/gcc/config/sparc/sol2.h86
-rw-r--r--contrib/gcc/config/sparc/sol26-sld.h7
-rw-r--r--contrib/gcc/config/sparc/sp64-aout.h10
-rw-r--r--contrib/gcc/config/sparc/sp64-elf.h22
-rw-r--r--contrib/gcc/config/sparc/sp86x-elf.h25
-rw-r--r--contrib/gcc/config/sparc/sparc-modes.def24
-rw-r--r--contrib/gcc/config/sparc/sparc-protos.h177
-rw-r--r--contrib/gcc/config/sparc/sparc.c2926
-rw-r--r--contrib/gcc/config/sparc/sparc.h525
-rw-r--r--contrib/gcc/config/sparc/sparc.md729
-rw-r--r--contrib/gcc/config/sparc/sparclet.md8
-rw-r--r--contrib/gcc/config/sparc/supersparc.md8
-rw-r--r--contrib/gcc/config/sparc/sysv4-only.h35
-rw-r--r--contrib/gcc/config/sparc/sysv4.h24
-rw-r--r--contrib/gcc/config/sparc/t-sol23
-rw-r--r--contrib/gcc/config/sparc/ultra1_2.md58
-rw-r--r--contrib/gcc/config/sparc/ultra3.md29
-rw-r--r--contrib/gcc/config/svr3.h81
-rw-r--r--contrib/gcc/config/svr4.h39
-rw-r--r--contrib/gcc/config/t-darwin18
-rw-r--r--contrib/gcc/config/t-freebsd3
-rw-r--r--contrib/gcc/config/t-gnu2
-rw-r--r--contrib/gcc/config/t-kfreebsd-gnu16
-rw-r--r--contrib/gcc/config/t-libunwind6
-rw-r--r--contrib/gcc/config/t-linux7
-rw-r--r--contrib/gcc/config/t-netbsd3
-rw-r--r--contrib/gcc/config/t-openbsd3
-rw-r--r--contrib/gcc/config/t-rtems3
-rw-r--r--contrib/gcc/config/t-slibgcc-darwin30
-rw-r--r--contrib/gcc/config/t-slibgcc-elf-ver5
-rw-r--r--contrib/gcc/config/t-vxworks22
-rw-r--r--contrib/gcc/config/usegas.h8
-rw-r--r--contrib/gcc/config/vxlib.c325
-rw-r--r--contrib/gcc/config/vxworks.h64
-rw-r--r--contrib/gcc/config/windiss.h38
-rwxr-xr-xcontrib/gcc/configure15684
-rw-r--r--contrib/gcc/configure.ac3169
-rw-r--r--contrib/gcc/conflict.c81
-rw-r--r--contrib/gcc/convert.c222
-rw-r--r--contrib/gcc/convert.h12
-rw-r--r--contrib/gcc/coretypes.h65
-rw-r--r--contrib/gcc/coverage.c972
-rw-r--r--contrib/gcc/coverage.h48
-rw-r--r--contrib/gcc/cp-demangle.c6977
-rw-r--r--contrib/gcc/cp-demangle.h149
-rw-r--r--contrib/gcc/cp-demint.c241
-rw-r--r--contrib/gcc/cp/ChangeLog17372
-rw-r--r--contrib/gcc/cp/ChangeLog.14
-rw-r--r--contrib/gcc/cp/ChangeLog.28
-rw-r--r--contrib/gcc/cp/ChangeLog.322648
-rw-r--r--contrib/gcc/cp/Make-lang.in241
-rw-r--r--contrib/gcc/cp/NEWS4
-rw-r--r--contrib/gcc/cp/call.c2688
-rw-r--r--contrib/gcc/cp/cfns.gperf5
-rw-r--r--contrib/gcc/cp/class.c2641
-rw-r--r--contrib/gcc/cp/config-lang.in14
-rw-r--r--contrib/gcc/cp/cp-lang.c132
-rw-r--r--contrib/gcc/cp/cp-tree.def85
-rw-r--r--contrib/gcc/cp/cp-tree.h2421
-rw-r--r--contrib/gcc/cp/cvt.c419
-rw-r--r--contrib/gcc/cp/cxx-pretty-print.c1737
-rw-r--r--contrib/gcc/cp/cxx-pretty-print.h52
-rw-r--r--contrib/gcc/cp/decl.c7183
-rw-r--r--contrib/gcc/cp/decl.h15
-rw-r--r--contrib/gcc/cp/decl2.c3146
-rw-r--r--contrib/gcc/cp/dump.c91
-rw-r--r--contrib/gcc/cp/error.c1404
-rw-r--r--contrib/gcc/cp/except.c316
-rw-r--r--contrib/gcc/cp/expr.c46
-rw-r--r--contrib/gcc/cp/friend.c222
-rw-r--r--contrib/gcc/cp/g++spec.c133
-rw-r--r--contrib/gcc/cp/init.c1505
-rw-r--r--contrib/gcc/cp/lang-specs.h34
-rw-r--r--contrib/gcc/cp/lex.c895
-rw-r--r--contrib/gcc/cp/lex.h53
-rw-r--r--contrib/gcc/cp/mangle.c717
-rw-r--r--contrib/gcc/cp/method.c679
-rw-r--r--contrib/gcc/cp/name-lookup.c4923
-rw-r--r--contrib/gcc/cp/name-lookup.h335
-rw-r--r--contrib/gcc/cp/operators.def22
-rw-r--r--contrib/gcc/cp/optimize.c84
-rw-r--r--contrib/gcc/cp/parser.c15323
-rw-r--r--contrib/gcc/cp/pt.c4362
-rw-r--r--contrib/gcc/cp/ptree.c84
-rw-r--r--contrib/gcc/cp/repo.c101
-rw-r--r--contrib/gcc/cp/rtti.c472
-rw-r--r--contrib/gcc/cp/search.c1552
-rw-r--r--contrib/gcc/cp/semantics.c2558
-rw-r--r--contrib/gcc/cp/tree.c1400
-rw-r--r--contrib/gcc/cp/typeck.c2444
-rw-r--r--contrib/gcc/cp/typeck2.c450
-rw-r--r--contrib/gcc/cplus-dem.c113
-rw-r--r--contrib/gcc/cppcharset.c1411
-rw-r--r--contrib/gcc/cppdefault.c51
-rw-r--r--contrib/gcc/cppdefault.h30
-rw-r--r--contrib/gcc/cpperror.c107
-rw-r--r--contrib/gcc/cppexp.c279
-rw-r--r--contrib/gcc/cppfiles.c1829
-rw-r--r--contrib/gcc/cpphash.c39
-rw-r--r--contrib/gcc/cpphash.h347
-rw-r--r--contrib/gcc/cppinit.c1139
-rw-r--r--contrib/gcc/cpplex.c1906
-rw-r--r--contrib/gcc/cpplib.c901
-rw-r--r--contrib/gcc/cpplib.h429
-rw-r--r--contrib/gcc/cppmacro.c367
-rw-r--r--contrib/gcc/cpppch.c717
-rw-r--r--contrib/gcc/cppspec.c22
-rw-r--r--contrib/gcc/cpptrad.c418
-rw-r--r--contrib/gcc/cppucnid.h336
-rw-r--r--contrib/gcc/cppucnid.pl130
-rw-r--r--contrib/gcc/cppucnid.tab239
-rw-r--r--contrib/gcc/crtstuff.c42
-rw-r--r--contrib/gcc/cse.c1289
-rw-r--r--contrib/gcc/cselib.c567
-rw-r--r--contrib/gcc/cselib.h22
-rw-r--r--contrib/gcc/dbxout.c946
-rw-r--r--contrib/gcc/dbxout.h11
-rw-r--r--contrib/gcc/debug.c34
-rw-r--r--contrib/gcc/debug.h86
-rw-r--r--contrib/gcc/defaults.h187
-rw-r--r--contrib/gcc/demangle.h368
-rw-r--r--contrib/gcc/df.c1092
-rw-r--r--contrib/gcc/df.h216
-rw-r--r--contrib/gcc/diagnostic.c1516
-rw-r--r--contrib/gcc/diagnostic.def2
-rw-r--r--contrib/gcc/diagnostic.h213
-rw-r--r--contrib/gcc/doc/bugreport.texi8
-rw-r--r--contrib/gcc/doc/c-tree.texi162
-rw-r--r--contrib/gcc/doc/compat.texi6
-rw-r--r--contrib/gcc/doc/configfiles.texi4
-rw-r--r--contrib/gcc/doc/configterms.texi6
-rw-r--r--contrib/gcc/doc/contrib.texi74
-rw-r--r--contrib/gcc/doc/contribute.texi4
-rw-r--r--contrib/gcc/doc/cpp.texi555
-rw-r--r--contrib/gcc/doc/cppenv.texi4
-rw-r--r--contrib/gcc/doc/cppinternals.texi22
-rw-r--r--contrib/gcc/doc/cppopts.texi125
-rw-r--r--contrib/gcc/doc/extend.texi1829
-rw-r--r--contrib/gcc/doc/fragments.texi3
-rw-r--r--contrib/gcc/doc/frontends.texi95
-rw-r--r--contrib/gcc/doc/gcc.texi65
-rw-r--r--contrib/gcc/doc/gccint.texi43
-rw-r--r--contrib/gcc/doc/gcov.texi294
-rw-r--r--contrib/gcc/doc/gty.texi77
-rw-r--r--contrib/gcc/doc/hostconfig.texi212
-rw-r--r--contrib/gcc/doc/include/gcc-common.texi21
-rw-r--r--contrib/gcc/doc/include/texinfo.tex4654
-rw-r--r--contrib/gcc/doc/interface.texi27
-rw-r--r--contrib/gcc/doc/invoke.texi3404
-rw-r--r--contrib/gcc/doc/libgcc.texi484
-rw-r--r--contrib/gcc/doc/makefile.texi58
-rw-r--r--contrib/gcc/doc/md.texi495
-rw-r--r--contrib/gcc/doc/objc.texi34
-rw-r--r--contrib/gcc/doc/passes.texi141
-rw-r--r--contrib/gcc/doc/portability.texi15
-rw-r--r--contrib/gcc/doc/rtl.texi230
-rw-r--r--contrib/gcc/doc/sourcebuild.texi259
-rw-r--r--contrib/gcc/doc/standards.texi8
-rw-r--r--contrib/gcc/doc/tm.texi4254
-rw-r--r--contrib/gcc/doc/trouble.texi219
-rw-r--r--contrib/gcc/dojump.c999
-rw-r--r--contrib/gcc/doloop.c63
-rw-r--r--contrib/gcc/dominance.c437
-rw-r--r--contrib/gcc/dummy-conditions.c12
-rw-r--r--contrib/gcc/dwarf2.h7
-rw-r--r--contrib/gcc/dwarf2asm.c258
-rw-r--r--contrib/gcc/dwarf2asm.h59
-rw-r--r--contrib/gcc/dwarf2out.c3846
-rw-r--r--contrib/gcc/dwarf2out.h15
-rw-r--r--contrib/gcc/emit-rtl.c1981
-rw-r--r--contrib/gcc/errors.c49
-rw-r--r--contrib/gcc/errors.h15
-rw-r--r--contrib/gcc/et-forest.c1113
-rw-r--r--contrib/gcc/et-forest.h66
-rw-r--r--contrib/gcc/except.c608
-rw-r--r--contrib/gcc/except.h103
-rw-r--r--contrib/gcc/explow.c256
-rw-r--r--contrib/gcc/expmed.c471
-rw-r--r--contrib/gcc/expr.c3648
-rw-r--r--contrib/gcc/expr.h530
-rw-r--r--contrib/gcc/f/ChangeLog4011
-rw-r--r--contrib/gcc/f/Make-lang.in287
-rw-r--r--contrib/gcc/f/ansify.c6
-rw-r--r--contrib/gcc/f/bad.c11
-rw-r--r--contrib/gcc/f/bld.c2540
-rw-r--r--contrib/gcc/f/bld.h278
-rw-r--r--contrib/gcc/f/bugs.texi13
-rw-r--r--contrib/gcc/f/com-rt.def18
-rw-r--r--contrib/gcc/f/com.c675
-rw-r--r--contrib/gcc/f/com.h27
-rw-r--r--contrib/gcc/f/data.c10
-rw-r--r--contrib/gcc/f/equiv.c9
-rw-r--r--contrib/gcc/f/expr.c996
-rw-r--r--contrib/gcc/f/ffe.texi17
-rw-r--r--contrib/gcc/f/fini.c4
-rw-r--r--contrib/gcc/f/g77.texi53
-rw-r--r--contrib/gcc/f/g77spec.c54
-rw-r--r--contrib/gcc/f/global.c43
-rw-r--r--contrib/gcc/f/global.h4
-rw-r--r--contrib/gcc/f/implic.c8
-rw-r--r--contrib/gcc/f/info.c4
-rw-r--r--contrib/gcc/f/intdoc.c13
-rw-r--r--contrib/gcc/f/intdoc.in4
-rw-r--r--contrib/gcc/f/intdoc.texi4
-rw-r--r--contrib/gcc/f/intrin.c7
-rw-r--r--contrib/gcc/f/invoke.texi12
-rw-r--r--contrib/gcc/f/lab.c10
-rw-r--r--contrib/gcc/f/lab.h4
-rw-r--r--contrib/gcc/f/lang-specs.h10
-rw-r--r--contrib/gcc/f/lang.opt402
-rw-r--r--contrib/gcc/f/lex.c183
-rw-r--r--contrib/gcc/f/malloc.c37
-rw-r--r--contrib/gcc/f/name.c5
-rw-r--r--contrib/gcc/f/news.texi36
-rw-r--r--contrib/gcc/f/parse.c9
-rw-r--r--contrib/gcc/f/proj.h6
-rw-r--r--contrib/gcc/f/root.texi2
-rw-r--r--contrib/gcc/f/src.c4
-rw-r--r--contrib/gcc/f/st.c34
-rw-r--r--contrib/gcc/f/sta.c342
-rw-r--r--contrib/gcc/f/stb.c7439
-rw-r--r--contrib/gcc/f/stb.h78
-rw-r--r--contrib/gcc/f/stc.c3630
-rw-r--r--contrib/gcc/f/stc.h128
-rw-r--r--contrib/gcc/f/std.c1762
-rw-r--r--contrib/gcc/f/std.h106
-rw-r--r--contrib/gcc/f/ste.c227
-rw-r--r--contrib/gcc/f/ste.h28
-rw-r--r--contrib/gcc/f/storag.c11
-rw-r--r--contrib/gcc/f/storag.h4
-rw-r--r--contrib/gcc/f/str.h7
-rw-r--r--contrib/gcc/f/stt.c56
-rw-r--r--contrib/gcc/f/stw.c10
-rw-r--r--contrib/gcc/f/symbol.c44
-rw-r--r--contrib/gcc/f/symbol.h4
-rw-r--r--contrib/gcc/f/target.c15
-rw-r--r--contrib/gcc/f/target.h307
-rw-r--r--contrib/gcc/f/top.c815
-rw-r--r--contrib/gcc/f/top.h3
-rw-r--r--contrib/gcc/f/type.c13
-rw-r--r--contrib/gcc/f/where.c4
-rw-r--r--contrib/gcc/fibheap.c2
-rw-r--r--contrib/gcc/fibheap.h5
-rw-r--r--contrib/gcc/filenames.h51
-rw-r--r--contrib/gcc/final.c990
-rw-r--r--contrib/gcc/fix-header.c207
-rwxr-xr-xcontrib/gcc/fixproto58
-rw-r--r--contrib/gcc/flags.h213
-rw-r--r--contrib/gcc/flow.c753
-rw-r--r--contrib/gcc/fold-const.c3550
-rw-r--r--contrib/gcc/fp-test.c4
-rw-r--r--contrib/gcc/function.c2040
-rw-r--r--contrib/gcc/function.h145
-rw-r--r--contrib/gcc/gbl-ctors.h6
-rw-r--r--contrib/gcc/gcc.c2123
-rw-r--r--contrib/gcc/gcc.h27
-rwxr-xr-xcontrib/gcc/gccbug.in8
-rw-r--r--contrib/gcc/gccspec.c17
-rw-r--r--contrib/gcc/gcov-dump.c436
-rw-r--r--contrib/gcc/gcov-io.c544
-rw-r--r--contrib/gcc/gcov-io.h780
-rw-r--r--contrib/gcc/gcov-iov.c68
-rw-r--r--contrib/gcc/gcov.c2511
-rw-r--r--contrib/gcc/gcse.c2754
-rw-r--r--contrib/gcc/gdbinit.in2
-rw-r--r--contrib/gcc/gen-protos.c27
-rw-r--r--contrib/gcc/genattr.c142
-rw-r--r--contrib/gcc/genattrtab.c1527
-rw-r--r--contrib/gcc/genattrtab.h59
-rw-r--r--contrib/gcc/genautomata.c3695
-rw-r--r--contrib/gcc/gencheck.c33
-rw-r--r--contrib/gcc/gencodes.c21
-rw-r--r--contrib/gcc/genconditions.c50
-rw-r--r--contrib/gcc/genconfig.c58
-rw-r--r--contrib/gcc/genconstants.c19
-rw-r--r--contrib/gcc/genemit.c159
-rw-r--r--contrib/gcc/genextract.c87
-rw-r--r--contrib/gcc/genflags.c61
-rw-r--r--contrib/gcc/gengenrtl.c104
-rw-r--r--contrib/gcc/gengtype-lex.l59
-rw-r--r--contrib/gcc/gengtype-yacc.y4
-rw-r--r--contrib/gcc/gengtype.c2047
-rw-r--r--contrib/gcc/gengtype.h52
-rw-r--r--contrib/gcc/genmodes.c1220
-rw-r--r--contrib/gcc/genmultilib88
-rw-r--r--contrib/gcc/genopinit.c122
-rw-r--r--contrib/gcc/genoutput.c292
-rw-r--r--contrib/gcc/genpeep.c62
-rw-r--r--contrib/gcc/genpreds.c14
-rw-r--r--contrib/gcc/genrecog.c368
-rw-r--r--contrib/gcc/gensupport.c178
-rw-r--r--contrib/gcc/gensupport.h20
-rw-r--r--contrib/gcc/ggc-common.c660
-rw-r--r--contrib/gcc/ggc-none.c29
-rw-r--r--contrib/gcc/ggc-page.c671
-rw-r--r--contrib/gcc/ggc-simple.c189
-rw-r--r--contrib/gcc/ggc-zone.c1398
-rw-r--r--contrib/gcc/ggc.h255
-rw-r--r--contrib/gcc/ginclude/float.h8
-rw-r--r--contrib/gcc/ginclude/iso646.h8
-rw-r--r--contrib/gcc/ginclude/stdarg.h8
-rw-r--r--contrib/gcc/ginclude/stdbool.h8
-rw-r--r--contrib/gcc/ginclude/stddef.h21
-rw-r--r--contrib/gcc/global.c248
-rw-r--r--contrib/gcc/graph.c97
-rw-r--r--contrib/gcc/graph.h8
-rw-r--r--contrib/gcc/gthr-dce.h7
-rw-r--r--contrib/gcc/gthr-gnat.c81
-rw-r--r--contrib/gcc/gthr-gnat.h43
-rw-r--r--contrib/gcc/gthr-posix.c207
-rw-r--r--contrib/gcc/gthr-posix.h22
-rw-r--r--contrib/gcc/gthr-rtems.h11
-rw-r--r--contrib/gcc/gthr-solaris.h7
-rw-r--r--contrib/gcc/gthr-vxworks.h285
-rw-r--r--contrib/gcc/gthr-win32.h20
-rw-r--r--contrib/gcc/gthr.h2
-rw-r--r--contrib/gcc/haifa-sched.c890
-rw-r--r--contrib/gcc/hard-reg-set.h4
-rw-r--r--contrib/gcc/hashtab.c249
-rw-r--r--contrib/gcc/hashtab.h31
-rw-r--r--contrib/gcc/hashtable.c138
-rw-r--r--contrib/gcc/hashtable.h30
-rw-r--r--contrib/gcc/hex.c21
-rw-r--r--contrib/gcc/hooks.c178
-rw-r--r--contrib/gcc/hooks.h52
-rw-r--r--contrib/gcc/host-default.c28
-rw-r--r--contrib/gcc/hosthooks-def.h37
-rw-r--r--contrib/gcc/hosthooks.h37
-rw-r--r--contrib/gcc/hwint.h205
-rw-r--r--contrib/gcc/ifcvt.c779
-rw-r--r--contrib/gcc/input.h48
-rw-r--r--contrib/gcc/integrate.c346
-rw-r--r--contrib/gcc/integrate.h35
-rw-r--r--contrib/gcc/intl.c35
-rw-r--r--contrib/gcc/intl.h19
-rw-r--r--contrib/gcc/jump.c339
-rw-r--r--contrib/gcc/langhooks-def.h166
-rw-r--r--contrib/gcc/langhooks.c308
-rw-r--r--contrib/gcc/langhooks.h268
-rw-r--r--contrib/gcc/lbasename.c20
-rw-r--r--contrib/gcc/lcm.c217
-rw-r--r--contrib/gcc/libfuncs.h207
-rw-r--r--contrib/gcc/libgcc-darwin.ver219
-rw-r--r--contrib/gcc/libgcc-std.ver29
-rw-r--r--contrib/gcc/libgcc2.c1131
-rw-r--r--contrib/gcc/libgcc2.h32
-rw-r--r--contrib/gcc/libgcov.c583
-rw-r--r--contrib/gcc/libiberty.h8
-rw-r--r--contrib/gcc/line-map.c64
-rw-r--r--contrib/gcc/line-map.h37
-rw-r--r--contrib/gcc/lists.c30
-rw-r--r--contrib/gcc/local-alloc.c334
-rw-r--r--contrib/gcc/longlong.h84
-rw-r--r--contrib/gcc/loop-init.c220
-rw-r--r--contrib/gcc/loop-unroll.c1383
-rw-r--r--contrib/gcc/loop-unswitch.c409
-rw-r--r--contrib/gcc/loop.c1598
-rw-r--r--contrib/gcc/loop.h71
-rw-r--r--contrib/gcc/machmode.def295
-rw-r--r--contrib/gcc/machmode.h114
-rw-r--r--contrib/gcc/main.c10
-rw-r--r--contrib/gcc/mips-tdump.c255
-rw-r--r--contrib/gcc/mips-tfile.c864
-rw-r--r--contrib/gcc/mkconfig.sh116
-rw-r--r--contrib/gcc/mkdeps.c124
-rw-r--r--contrib/gcc/mkdeps.h30
-rw-r--r--contrib/gcc/mkheaders.in20
-rw-r--r--contrib/gcc/mklibgcc.in123
-rw-r--r--contrib/gcc/mode-classes.def31
-rw-r--r--contrib/gcc/objc/Make-lang.in117
-rw-r--r--contrib/gcc/objc/config-lang.in15
-rw-r--r--contrib/gcc/objc/lang-specs.h35
-rw-r--r--contrib/gcc/objc/objc-act.c4717
-rw-r--r--contrib/gcc/objc/objc-act.h178
-rw-r--r--contrib/gcc/objc/objc-lang.c50
-rw-r--r--contrib/gcc/objc/objc-tree.def14
-rw-r--r--contrib/gcc/obstack.h40
-rw-r--r--contrib/gcc/optabs.c2131
-rw-r--r--contrib/gcc/optabs.h195
-rw-r--r--contrib/gcc/opts.c1878
-rw-r--r--contrib/gcc/opts.h56
-rw-r--r--contrib/gcc/opts.sh175
-rw-r--r--contrib/gcc/output.h331
-rw-r--r--contrib/gcc/params.c18
-rw-r--r--contrib/gcc/params.def152
-rw-r--r--contrib/gcc/params.h8
-rw-r--r--contrib/gcc/pex-unix.c166
-rw-r--r--contrib/gcc/postreload.c1560
-rw-r--r--contrib/gcc/predict.c415
-rw-r--r--contrib/gcc/predict.def5
-rw-r--r--contrib/gcc/predict.h17
-rw-r--r--contrib/gcc/prefix.c47
-rw-r--r--contrib/gcc/prefix.h6
-rw-r--r--contrib/gcc/pretty-print.c548
-rw-r--r--contrib/gcc/pretty-print.h273
-rw-r--r--contrib/gcc/print-rtl.c143
-rw-r--r--contrib/gcc/print-tree.c96
-rw-r--r--contrib/gcc/profile.c1257
-rw-r--r--contrib/gcc/protoize.c485
-rw-r--r--contrib/gcc/ra-build.c491
-rw-r--r--contrib/gcc/ra-colorize.c332
-rw-r--r--contrib/gcc/ra-debug.c151
-rw-r--r--contrib/gcc/ra-rewrite.c218
-rw-r--r--contrib/gcc/ra.c112
-rw-r--r--contrib/gcc/ra.h131
-rw-r--r--contrib/gcc/read-rtl.c102
-rw-r--r--contrib/gcc/real.c1526
-rw-r--r--contrib/gcc/real.h159
-rw-r--r--contrib/gcc/recog.c754
-rw-r--r--contrib/gcc/recog.h157
-rw-r--r--contrib/gcc/reg-stack.c416
-rw-r--r--contrib/gcc/regclass.c572
-rw-r--r--contrib/gcc/regmove.c287
-rw-r--r--contrib/gcc/regrename.c279
-rw-r--r--contrib/gcc/regs.h19
-rw-r--r--contrib/gcc/reload.c678
-rw-r--r--contrib/gcc/reload.h107
-rw-r--r--contrib/gcc/reload1.c2130
-rw-r--r--contrib/gcc/reorg.c306
-rw-r--r--contrib/gcc/resource.c109
-rw-r--r--contrib/gcc/resource.h23
-rw-r--r--contrib/gcc/rtl-error.c77
-rw-r--r--contrib/gcc/rtl.c271
-rw-r--r--contrib/gcc/rtl.def175
-rw-r--r--contrib/gcc/rtl.h1280
-rw-r--r--contrib/gcc/rtlanal.c660
-rw-r--r--contrib/gcc/sbitmap.c153
-rw-r--r--contrib/gcc/sbitmap.h95
-rw-r--r--contrib/gcc/scan-decls.c22
-rw-r--r--contrib/gcc/scan.c41
-rw-r--r--contrib/gcc/scan.h38
-rw-r--r--contrib/gcc/sched-deps.c527
-rw-r--r--contrib/gcc/sched-ebb.c405
-rw-r--r--contrib/gcc/sched-int.h180
-rw-r--r--contrib/gcc/sched-rgn.c673
-rw-r--r--contrib/gcc/sched-vis.c70
-rw-r--r--contrib/gcc/sdbout.c282
-rw-r--r--contrib/gcc/sdbout.h6
-rw-r--r--contrib/gcc/sibcall.c79
-rw-r--r--contrib/gcc/simplify-rtx.c1742
-rw-r--r--contrib/gcc/splay-tree.c4
-rw-r--r--contrib/gcc/splay-tree.h25
-rw-r--r--contrib/gcc/sreal.c561
-rw-r--r--contrib/gcc/sreal.h65
-rw-r--r--contrib/gcc/stack.h8
-rw-r--r--contrib/gcc/stmt.c1440
-rw-r--r--contrib/gcc/stor-layout.c840
-rw-r--r--contrib/gcc/stringpool.c162
-rw-r--r--contrib/gcc/stub-objc.c71
-rw-r--r--contrib/gcc/system.h187
-rw-r--r--contrib/gcc/target-def.h137
-rw-r--r--contrib/gcc/target.h290
-rw-r--r--contrib/gcc/targhooks.c213
-rw-r--r--contrib/gcc/targhooks.h39
-rw-r--r--contrib/gcc/timevar.c124
-rw-r--r--contrib/gcc/timevar.def15
-rw-r--r--contrib/gcc/timevar.h25
-rw-r--r--contrib/gcc/tlink.c145
-rw-r--r--contrib/gcc/toplev.c4925
-rw-r--r--contrib/gcc/toplev.h162
-rw-r--r--contrib/gcc/tracer.c98
-rw-r--r--contrib/gcc/tree-dump.c145
-rw-r--r--contrib/gcc/tree-dump.h23
-rw-r--r--contrib/gcc/tree-inline.c848
-rw-r--r--contrib/gcc/tree-inline.h24
-rw-r--r--contrib/gcc/tree-optimize.c231
-rw-r--r--contrib/gcc/tree.c1661
-rw-r--r--contrib/gcc/tree.def133
-rw-r--r--contrib/gcc/tree.h1527
-rw-r--r--contrib/gcc/tsystem.h17
-rw-r--r--contrib/gcc/unroll.c305
-rw-r--r--contrib/gcc/unwind-c.c10
-rw-r--r--contrib/gcc/unwind-dw2-fde-darwin.c99
-rw-r--r--contrib/gcc/unwind-dw2-fde-glibc.c29
-rw-r--r--contrib/gcc/unwind-dw2-fde.c185
-rw-r--r--contrib/gcc/unwind-dw2-fde.h34
-rw-r--r--contrib/gcc/unwind-dw2.c216
-rw-r--r--contrib/gcc/unwind-pe.h30
-rw-r--r--contrib/gcc/unwind-sjlj.c29
-rw-r--r--contrib/gcc/unwind.h9
-rw-r--r--contrib/gcc/unwind.inc11
-rw-r--r--contrib/gcc/value-prof.c708
-rw-r--r--contrib/gcc/value-prof.h64
-rw-r--r--contrib/gcc/varasm.c1814
-rw-r--r--contrib/gcc/varray.c219
-rw-r--r--contrib/gcc/varray.h60
-rw-r--r--contrib/gcc/version.c3
-rw-r--r--contrib/gcc/vmsdbgout.c285
-rw-r--r--contrib/gcc/web.c306
-rw-r--r--contrib/gcc/xcoff.h17
-rw-r--r--contrib/gcc/xcoffout.c73
-rw-r--r--contrib/gcc/xcoffout.h28
-rw-r--r--contrib/gcc/xexit.c53
-rw-r--r--contrib/gcc/xmalloc.c183
-rw-r--r--contrib/gcc/xstrdup.c34
-rw-r--r--contrib/gcc/xstrerror.c67
916 files changed, 319636 insertions, 200115 deletions
diff --git a/contrib/gcc/ChangeLog b/contrib/gcc/ChangeLog
index eb90643cbdec..efcecf7bd7ab 100644
--- a/contrib/gcc/ChangeLog
+++ b/contrib/gcc/ChangeLog
@@ -1,17812 +1,5931 @@
-2003-11-05 Roger Sayle <roger@eyesopen.com>
+2004-07-24 Alexander Kabaev <kan@freebsd.org>
+
+ * config/ia64/ia64.h (SUBTARGET_EXTRA_SPECS): Default to nothing.
+ (EXTRA_SPECS): Use SUBTARGET_EXTRA_SPECS.
+
+2004-07-26 David Edelsohn <edelsohn@gnu.org>
+
+ PR target/16239
+ * config/rs6000/rs6000.md (movdi_internal64): Further disparage
+ f->f.
+
+2004-07-26 Richard Sandiford <rsandifo@redhat.com>
+
+ PR rtl-optimization/16643
+ * cfglayout.h (cfg_layout_initialize): Add a flags parameter.
+ * cfglayout.c (cfg_layout_initialize): Pass it to cleanup_cfg.
+ * basic-block.h (reorder_basic_blocks): Add a flags parameter.
+ * cfglayout.c (reorder_basic_blocks): Pass it to cfg_layout_initialize.
+ * loop-init.c (loop_optimizer_init): Pass 0 to cfg_layout_initialize.
+ * rtl.h (tracer): Add a flags parameter.
+ * tracer.c (tracer): Pass it to cfg_layout_initialise.
+ * toplev.c (rest_of_handle_stack_regs): Pass 0 to reorder_basic_blocks.
+ (rest_of_handle_reorder_blocks): Update calls to tracer and
+ reorder_basic_blocks, passing CLEANUP_UPDATE_LIFE if appropriate.
+ (rest_of_handle_tracer): Pass 0 to tracer.
+
+2004-07-24 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/hpux.h: Do not disable TLS.
+
+2004-07-24 Alexander Kabaev <kan@freebsd.org>
+ Zack Weinberg <zack@codesourcery.com
+
+ PR 16684
+ * c-decl.c (diagnose_mismatched_decls): Don't issue a
+ redundant-declaration warning the first time a builtin is
+ declared explicitly.
+
+2004-07-21 Jakub Jelinek <jakub@redhat.com>
+ Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/15345
+ PR c/16450
+ * toplev.c (rest_of_handle_inlining): Set DECL_DEFER_OUTPUT on C
+ nested functions as well.
+ * tree-optimize.c (tree_rest_of_compilation): Don't clear decl rtls
+ for deferred nested inlines.
+
+2004-07-17 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * libgcc2.c (__enable_execute_stack): New symbol.
+ * libgcc-std.ver (GCC_3.4.2): New version. Inherit from GCC_3.4
+ and declare __enable_execute_stack.
+ * mklibgcc.in (lib2funcs): Add _enable_execute_stack.
+ * config/netbsd.h (NETBSD_ENABLE_EXECUTE_STACK): ANSIfy.
+ * config/sol2.h (TRANSFER_FROM_TRAMPOLINE): Rename into
+ ENABLE_EXECUTE_STACK and ANSIfy.
+ * config/alpha/alpha.c (alpha_initialize_trampoline): Conditionalize
+ on ENABLE_EXECUTE_STACK instead of TRANSFER_FROM_TRAMPOLINE.
+ * config/alpha/netbsd.h (TRANSFER_FROM_TRAMPOLINE): Rename into
+ ENABLE_EXECUTE_STACK.
+ * config/alpha/osf.h (TRANSFER_FROM_TRAMPOLINE): Likewise.
+ * config/i386/i386.c (x86_initialize_trampoline): Conditionalize
+ on ENABLE_EXECUTE_STACK instead of TRANSFER_FROM_TRAMPOLINE.
+ * config/i386/netbsd-elf.h (TRANSFER_FROM_TRAMPOLINE): Rename into
+ ENABLE_EXECUTE_STACK.
+ * config/i386/netbsd.h (TRANSFER_FROM_TRAMPOLINE): Likewise.
+ * config/i386/netbsd64.h (TRANSFER_FROM_TRAMPOLINE): Likewise.
+ * config/sparc/freebsd.h (TRANSFER_FROM_TRAMPOLINE): Likewise.
+ * config/sparc/netbsd-elf.h (TRANSFER_FROM_TRAMPOLINE): Likewise.
+ * config/sparc/sparc.c (sparc_initialize_trampoline): Conditionalize
+ on ENABLE_EXECUTE_STACK instead of TRANSFER_FROM_TRAMPOLINE.
+ (sparc64_initialize_trampoline): Likewise.
+ * doc/tm.texi (trampolines): Add ENABLE_EXECUTE_STACK macro.
+
+2004-07-16 Andris Pavenis <pavenis@latnet.lv>
+
+ PR preprocessor/16366
+ * internal.h (struct cpp_reader): New field dir_hash.
+ * files.c (make_cpp_dir): Use dir_hash, not file_hash.
+ (_cpp_init_files, _cpp_cleanup_files): Update for new field.
+
+2004-07-15 James E Wilson <wilson@specifixinc.com>
- PR optimization/10339
- * builtins.c (expand_builtin_strcmp): Try to emit cmpstrsi insn
- directly instead of unsafely transforming call into a memcmp.
- (expand_builtin_strncmp): Likewise.
-
-2003-11-03 Alexander Kabaev <ak03@gte.com>
-
- * real.c (encode_ieee_single): Ensure proper promotion.
-
-2003-11-04 H.J. Lu <hongjiu.lu@intel.com>
-
- Backport from 3.4-branch
-
- 2003-07-13 Andreas Jaeger <aj@suse.de>
-
- * config.gcc: Add pmmintrin.h for x86_64-*-*.
-
- 2003-06-26 H.J. Lu <hongjiu.lu@intel.com>
-
- * config.gcc (extra_headers): Add pmmintrin.h for i[34567]86-*-*.
-
- * config/i386/i386.c (override_options): Turn on MASK_SSE2
- for -mpni.
- (bdesc_2arg): Add PNI builtins with 2 args.
- (bdesc_1arg): Add PNI builtins with 1 arg.
- (ix86_init_mmx_sse_builtins): Handle PNI builtins.
- (ix86_expand_builtin): Likewise.
-
- * config/i386/i386.h (MASK_3DNOW, MASK_3DNOW_A,
- MASK_128BIT_LONG_DOUBLE, MASK_64BIT, MASK_MS_BITFIELD_LAYOUT,
- MASK_TLS_DIRECT_SEG_REFS): Renumbered.
- (TARGET_PNI): New.
- (TARGET_SWITCHES): Add -mpni and -mno-pni.
- (TARGET_CPU_CPP_BUILTINS): Defined __PNI__ for PNI.
- (ix86_builtins): Add PNI builtins.
- (config/i386/i386.md): Add PNI patterns.
-
- * config/i386/pmmintrin.h: New file.
-
- * config/i386/i386.c (override_options): Turn on MASK_SSE for
- -msse2.
- (MASK_SSE1): Removed.
- (MASK_SSE164): Removed.
- (MASK_SSE264): Removed.
- (bdesc_2arg): Replace MASK_SSE1 with MASK_SSE. Replace
- MASK_SSE164 with MASK_SSE | MASK_64BIT. Replace MASK_SSE264
- with MASK_SSE2 | MASK_64BIT.
- (bdesc_1arg): Likewise.
- (ix86_init_mmx_sse_builtins): Likewise.
-
- * config/i386/i386.h (TARGET_SSE): Remove MASK_SSE2.
-
- 2003-06-20 H.J. Lu <hongjiu.lu@intel.com>
-
- * doc/extend.texi: Document new builtin functions for Intel
- Prescott New Intrunctions.
-
- * doc/invoke.texi: Document new command-line options, -mpni and
- -mno-pni, for Intel Prescott New Intrunctions.
-
- 2003-06-05 H.J. Lu <hongjiu.lu@intel.com>
-
- * config.gcc (extra_headers): Add emmintrin.h for i[34567]86-*-*
- and x86_64-*-*.
-
- * config/i386/mmintrin.h: Update version and add alternate
- intrinsic names.
- * config/i386/xmmintrin.h: Likewise.
-
- * config/i386/xmmintrin.h: Include <emmintrin.h>. Move SSE2
- intrinsics to ...
- * config/i386/emmintrin.h: Here. New file.
-
-2003-11-04 H.J. Lu <hongjiu.lu@intel.com>
-
- Backport from 3.4-branch
- 2003-04-25 H.J. Lu <hjl@gnu.org>
-
- * config/ia64/ia64.c (ia64_expand_compare_and_swap): Add rmode
- for return mode.
- (ia64_expand_builtin): Set rmode to SImode for
- IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_SI,
- IA64_BUILTIN_VAL_COMPARE_AND_SWAP_SI and
- IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_DI. Set remode to DImode
- for IA64_BUILTIN_VAL_COMPARE_AND_SWAP_DI.
-
- 2003-04-24 H.J. Lu <hjl@gnu.org>
-
- * config/ia64/ia64.c (ia64_init_builtins): Add si_ftype_pdi_di_di
- for __sync_bool_compare_and_swap_di for int return type.
-
- * config/ia64/ia64intrin.h (__sync_bool_compare_and_swap_di):
- Change return type to int.
- (__sync_bool_compare_and_swap): Likewise.
-
-2003-11-03 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
-
- * doc/contrib.texi: Add Giovanni Bajo, Dara Hazeghi, Falk Hueffner,
- and Andrew Pinski.
-
-2003-11-03 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
-
- * fixinc/inclhack.def (stdio_va_list): Allow tab before va_list.
- Merge two substitutions.
- * fixinc/fixincl.x: Regenerate.
- Fixes PR bootstrap/12666.
-
-2003-10-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
-
- PR target/11598
- PR libgcj/10610
- * config/rs6000/sysv4.h (PREFERRED_STACK_BOUNDARY): New macro.
-
-2003-10-27 Falk Hueffner <falk@debian.org>
-
- PR target/12654
- * config/alpha/alpha.c (alpha_emit_conditional_branch): Don't do
- comparison against constant by adjusting the argument except for
- EQ and NE.
-
-2003-10-26 Ottavio Campana <ottavio@campana.vi.it>
-
- PR target/12690
- * config/i386/mmintrin.h (_mm_set1_pi8): Fix comment.
-
-2003-10-25 Bruce Korb <bkorb@gnu.org>
-
- * gcc/fixinc/tests/base/ansi/string.h:
- This fixes a result from a broken sed or a hand-edited output file.
- The '__GNUC__' wrappers were misplaced.
-
-2003-10-25 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR target/12712
- * reg-stack.c (convert_regs_1): Create an arbitrary input stack
- if the block has no predecessors.
- (convert_regs_2): Document the problem with successors whose
- only predecessor is the block to be processed.
- (convert_regs): Don't create the arbitrary input stack here.
-
-2003-10-22 David Taylor <dtaylor@emc.com>
-
- PR debug/12500
- * dbxout.c (dbxout_typedefs): Use COMPLETE_OR_VOID_TYPE_P.
-
-2003-10-20 Zack Weinberg <zack@codesourcery.com>
-
- * fixinc/inclhack.def (hpux11_snprintf): New edit.
- * fixinc/fixincl.x: Regenerate.
- * fixinc/tests/base/stdio.h: Add test for hpux11_snprintf.
-
-2003-05-16 Jakub Jelinek <jakub@redhat.com>
-
- * config/ia64/unwind-ia64.c (uw_update_reg_address): Handle
- .save XX, r0.
-
-2003-10-19 Mark Mitchell <mark@codesourcery.com>
-
- * doc/include/gcc-common.texi: Bump version number.
- * version.c (version_string): Reset to prerelease format.
-
-2003-10-18 Kazu Hirata <kazu@cs.umass.edu>
-
- * doc/extend.texi: Fix typos.
-
-2003-10-16 Release Manager
-
- * GCC 3.3.2 Released.
-
-2003-10-14 Jason Merrill <jason@redhat.com>
-
- PR c/11885
- * stor-layout.c (update_alignment_for_field): Packed non-bit-fields
- get byte alignment.
-
-2003-10-14 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
-
- * fixinc/inclhack.def (alpha_pthread_gcc): New fix.
- * fixinc/fixincl.x: Regenerate.
- * fixinc/tests/base/pthread.h [ALPHA_PTHREAD_GCC_CHECK]: New
- testcase.
- Fixes PR bootstrap/9330.
-
-2003-10-14 Steven Bosscher <steven@gcc.gnu.org>
-
- PR target/11087
- Backport from gcc-3_3-rhl-branch and mainline.
-
- 2003-07-17 Jakub Jelinek <jakub@redhat.com>
-
- * loop.c (basic_induction_var): Check if convert_modes
- emitted any instructions. Remove them and return 0 if so.
-
-2003-10-13 Matt Kraai <kraai@alumni.cmu.edu>
-
- PR target/11949
Backport from mainline:
+ 2004-02-19 Steve Ellcey <sje@cup.hp.com>
+ * config/ia64/ia64.h (HARD_REGNO_CALLER_SAVE_MODE): New macro.
+ * testsuite/gcc.dg/20040219-1.c: New test.
- 2003-05-05 Aldy Hernandez <aldyh@redhat.com>
+2004-07-15 Aldy Hernandez <aldyh@redhat.com>
- * testsuite/gcc.c-torture/compile/simd-6.c: New.
- * c-typeck.c (digest_init): Handle arrays of vector constants.
+ * config/rs6000/rs6000.md ("*cceq_ior_compare"): Allow
+ unconditionally.
+ * config/rs6000/spe.md ("e500_cceq_ior_compare"): Remove.
-2003-10-11 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-07-14 James E Wilson <wilson@specifixinc.com>
- PR optimization/12544
- * function.c (put_var_into_stack): Don't generate ADDRESSOFs
- for DECL_NONLOCAL decls.
+ PR target/16325
+ * config/mips/mips.h (STARTING_FRAME_OFFSET): When flag_profile_value
+ and ! TARGET_64BIT, include REG_PARM_STACK_SPACE.
-2003-10-09 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-07-14 Eric Botcazou <ebotcazou@libertysurf.fr>
- PR optimization/12510
Backport from mainline:
+ 2004-07-13 Eric Botcazou <ebotcazou@libertysurf.fr>
- 2003-09-08 Jakub Jelinek <jakub@redhat.com>
-
- * toplev.c (rest_of_compilation): Call split_all_insns before
- regstack if optimizing but not scheduling after reload.
-
-2003-10-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
-
- * fixinc/inclhack.def (stdio_va_list): Removed _ap fix.
- (irix_stdio_va_list): Don't require leading printf, IRIX 6.5.21
- introduced some multi-line prototypes.
- * fixinc/fixincl.x: Regenerate.
- Fixes PR libf2c/12263.
-
-2003-10-08 Timo Kokkonen <tjko@iki.fi>
- Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR bootstrap/12490
- * scan-decls.c (MAX_EXTERN_C_BRACES): New preprocessor constant
- to define the size of the extern_C_braces array. Set it to 200.
- (scan_decls): Abort when extern_C_braces_length is out-of-bounds.
-
-2003-10-06 Eric Botcazou <ebotcazou@libertysurf.fr>
+ PR target/13926
+ * config/sparc/sparc-protos.h (output_ubranch): New prototype.
+ * config/sparc/sparc.c (output_ubranch): New function.
+ * config/sparc/sparc.md (jump pattern): Use it.
- PR optimization/12215
- * cse.c (cse_set_around_loop): Emit the move at the beginning
- of the next basic block for trapping sets.
+2004-07-13 Richard Sandiford <rsandifo@redhat.com>
-2003-10-06 Eric Botcazou <ebotcazou@libertysurf.fr>
+ PR rtl-optimization/16380
+ * loop.c (check_dbra_loop): Sink comparison instructions if they
+ do something other than set cc0.
- PR optimization/11637
- * combine.c (adjust_for_new_dest): New function to adjust the
- notes and LOG_LINKS when the dest of an insn has changed.
- (try_combine): Use it when deleting the first insn of a two-insn
- parallel or splitting a two-load parallel.
+2004-07-13 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-10-04 Stephane Carrez <stcarrez@nerim.fr>
+ PR target/16494
+ * config/sparc/sparc.c (output_cbranch): Properly guard
+ the code handling far branches with TARGET_V9.
+ * config/sparc/sparc.md (length attribute): Document the
+ side-effect of having a length greater or equal to 3.
- * config/m68hc11/t-m68hc11-gas (MULTILIB_MATCHES): m68hcs12 is
- identical to m68hc12 as far as libraries are concerned.
+2004-07-13 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Lloyd Parkes <lloyd@must-have-coffee.gen.nz>
-2003-10-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+ PR target/15186
+ * config/sparc/sol2-bi.h (LINK_ARCH64_SPEC_BASE): Pass
+ /usr/ucblib/sparcv9 as -R path when -compat-bsd is specified.
- PR c/12446
- * c-typeck.c (convert_for_assignment): Issue an error for
- array to pointer assignment after default conversion.
- (digest_init): Likewise.
+2004-07-13 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Martin Sebor <sebor@roguewave.com>
-2003-10-03 Gerald Pfeifer <gerald@pfeifer.com>
+ PR target/12602
+ * doc/invoke.texi (SPARC options): Document -threads
+ and -pthreads on Solaris.
- * doc/extend.texi (Function Attributes): Fix title of GNU C
- Preprocessor manual.
- (C++ Extensions): Fix reference to "Predefined Macros" in the
- GNU C Preprocessor manual.
+2004-07-13 Anthony Heading <aheading@jpmorgan.com>
-2003-10-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
-
- PR/11883
- * cfgloop.c (flow_loops_find): Fix handling of abnormal edges.
-
-2003-10-02 Mark Mitchell <mark@codesourcery.com>
-
- PR optimization/12180
- * c-objc-common.c (inline_forbidden_p): Do not permit inlining of
- functions containing calls to __builtin_next_arg.
-
-2003-10-02 Josef Zlomek <zlomekj@suse.cz>
-
- PR/12292
- * combine.c (make_field_assignment): Check whether rtx's code
- is CONST_INT before using INTVAL.
-
-2003-10-02 Josef Zlomek <zlomekj@suse.cz>
-
- Waldek Hebisch <hebisch@math.uni.wroc.pl>
- PR/12072
- * varasm.c (compare_constant): Fix thinko.
-
-2003-10-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- * aclocal.m4: Add hpux10* and hpux11.00 to /dev/zero blacklist.
+ * configure.ac (gcc_cv_as_offsetable_lo10): Fix a typo.
* configure: Rebuilt.
-2003-10-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2004-07-12 Vladimir Makarov <vmakarov@redhat.com>
- * aclocal.m4: Add ultrix* to /dev/zero blacklist.
- * configure: Rebuilt.
+ PR target/16445
+ * config/ia64/ia64.c (bundling): Don't count ignored insns.
-2003-10-01 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+2004-07-10 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
- * config.gcc (sparc-*-solaris2*): Handle Solaris 10 and up like
- Solaris 7-9.
+ * pa.c (output_indirect_call): Only use %r2 as the link register in
+ indirect calls with the long PA 2.0 pc-relative branch.
- * fixinc/inclhack.def (solaris_widec): Replace solaris2.[0-5]* by
- wildcards which explicitly match micro versions.
- * fixinc/fixincl.x: Regenerate.
-
-2003-10-01 Richard Henderson <rth@redhat.com>
-
- * dwarf2out.c (expand_builtin_init_dwarf_reg_sizes): Honor
- DWARF_ALT_FRAME_RETURN_COLUMN.
- * unwind-dw2.c (dwarf_reg_size_table): Expand by one.
- (_Unwind_GetGR, _Unwind_SetGR): Validate lookup column.
- (uw_frame_state_for): Return end-of-stack for null return address.
-
- * config/alpha/alpha.c (alpha_sa_mask): Add r31 for eh_return.
- (alpha_expand_prologue): Store a zero for it.
- (alpha_expand_epilogue): Don't reload it.
- * config/alpha/alpha.h (DWARF_ALT_FRAME_RETURN_COLUMN): New.
- * config/alpha/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Use column 64
- for the sigframe return address.
-
-2003-10-01 Nick Clifton <nickc@redhat.com>
-
- * Import this patch from mainline:
-
- 2003-02-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- * collect2.c (pexecute_pid): Rename to pid.
- (collect_wait, collect_execute, scan_prog_file, scan_libraries): Use
- pid.
-
-2003-09-23 David S. Miller <davem@redhat.com>
-
- * config/sparc/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Undefine
- before redefining.
- * config/sparc/linux64.h (LINK_GCC_C_SEQUENCE_SPEC): Likewise.
-
-2003-10-01 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-07-10 James E Wilson <wilson@specifixinc.com>
- PR optimization/11753
- * config/sparc/sparc.md (length attribute) [fcc branch]: Add 1 to
- the length in the non-V9 case.
+ * config/gofast.h (gofast_maybe_init_libfuncs): Use SImode for litodp.
-2003-09-27 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-07-10 Jakub Jelinek <jakub@redhat.com>
- PR optimization/12340
- * loop.h (struct induction): Document the new semantics
- of the 'same' field for bivs.
- * unroll.c (biv_total_increment): Don't count the same
- biv increment several times.
- (loop_iterations) [GENERAL_INDUCT]: Likewise.
+ * Backport from mainline:
+ 2004-07-08 Paolo Bonzini <bonzini@gnu.org>
+ Jakub Jelinek <jakub@redhat.com>
-2003-09-26 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+ * config/i386/i386.c (override_options): Enable
+ SSE prefetches with -mtune, as long as we are
+ compiling for i686 or higher. All i686 processors
+ accept SSE prefetches as NOPS, some i586's don't.
- PR bootstrap/12358
- * pa.c (output_bvb): Fix typo.
+ 2004-07-07 Jakub Jelinek <jakub@redhat.com>
-2003-09-24 Alexandre Oliva <aoliva@redhat.com>
+ * config/i386/i386.c (override_options): Don't set x86_prefetch_sse
+ from -mtune= option.
- * cpplib.c (do_pragma): Reintroduce cb_line_change call in the
- code path that calls a handler.
+2004-07-10 Jakub Jelinek <jakub@redhat.com>
-2003-09-23 Geoffrey Keating <geoffk@apple.com>
+ PR tree-optimization/16372
+ * fold-const.c (build_range_check): Use TYPE_MODE's precision for
+ enumerals.
- * config/t-darwin (crt2.o): Add stmp-int-hdrs to dependencies.
+2004-07-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
- * config/rs6000/rs6000.c (function_arg_pass_by_reference): Don't
- pass zero-size arrays by reference.
- (rs6000_va_arg): Likewise.
+ PR target/16459
+ * pa.c (output_indirect_call): Use %r2 as the link register when
+ calling $$dyncall with a pc-relative branch.
-2003-09-22 Joel Sherrill <joel@oarcorp.com>
+2004-07-08 Gerald Pfeifer <gerald@pfeifer.com>
- * combine.c, config/mips/t-elf, config/c4x/rtems.h: Revert patches
- which should not have been committed with other RTEMS changes.
+ * doc/install.texi (Binaries): Mention OpenPKG.
-2003-09-22 Olivier Hainque <hainque@act-europe.fr>
+2004-07-09 Eric Botcazou <ebotcazou@libertysurf.fr>
- PR target/9786
- * reg-stack.c (convert_regs_1): Purge possible dead eh edges
- after potential deletion of trapping insn. Avoids later ICE
- from call to fixup_abnormal_edges.
- (convert_regs_2): Stack the current block successors before
- processing this block, that is, before the potential deletion of
- dead edges by convert_regs_1, because these edges have been used
- to initialize the predecessors count.
+ PR target/16416
+ * config/sparc/sol2-bi.h (OPTION_DEFAULT_SPECS): New macro.
+ Override default settings to account for -m32 and -m64.
-2003-09-21 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-07-08 Vladimir Makarov <vmakarov@redhat.com>
- PR target/12301
- * reorg.c (stop_search_p): Return 1 for insns that can
- throw internally.
+ PR target/16414
+ * config/ia64/ia64.c (ia64_dfa_new_cycle): Fix typo in comparison
+ of asm_noperands result.
-2003-09-19 Joel Sherrill <joel@oarcorp.com>
+2004-07-08 Eric Botcazou <ebotcazou@libertysurf.fr>
- * config/m68k/t-m68kbare, config/m68k/t-rtems: Change 68681 to
- 68881.
+ PR target/16430
+ * config/sparc/sparc.c (function_value): In 64-bit mode,
+ return the aggregates larger than 16 bytes like unions.
-2003-09-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
-
- * config/m68k/t-rtems (m68k-*-rtems*): New.
- * config.gcc: Use config/m68k/t-rtems.
-
-2003-09-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
-
- * config/mips/t-rtems: New.
- * config.gcc (mips*-*-rtems*): Use config/mips/t-rtems.
-
-2003-09-19 T. Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
- Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR target/12166
- * config/sparc/sol2-c1.asm (start): Set __Argv if GCRT1.
-
-2003-09-18 Mark Mitchell <mark@codesourcery.com>
-
- PR target/11184
- * builtins.c (expand_builtin_apply): Use convert_memory_address
- before returning the value.
-
-2003-09-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
-
- * configure.in (gcc_cv_as_hidden): Only disable if no GNU ld
- detected.
- * configure: Regenerate.
- Fixes PR target/12248.
+2004-07-08 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-09-17 Richard Henderson <rth@redhat.com>
+ PR target/16199
+ * config/sparc/sparc.c (sparc_emit_set_symbolic_const64): When
+ 'temp' is zero, generate new pseudos as needed and emit the
+ sequence of insns in single-assignment form. Resync comments
+ with code.
+ (sparc_emit_set_const64): Pass zero as 'temp' argument to above
+ function before reload.
- * config/alpha/alpha.c (alpha_expand_mov): Do gen_movdi_er_maybe_g
- always during initial code generation.
- * config/alpha/alpha.md (movdi_er_maybe_g): Don't conditionalize
- on flag_inline_functions.
+2004-07-07 Richard Sandiford <rsandifo@redhat.com>
-2003-09-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+ PR target/16407
+ * config/mips/mips-protos.h (mips_declare_common_object): Declare.
+ * config/mips/mips.c (mips_declare_common_object): New function,
+ mostly split out from...
+ (mips_output_aligned_decl_common): ...here.
+ * config/mips/mips.h (ASM_OUTPUT_LOCAL): Remove in favor of...
+ (ASM_OUTPUT_ALIGNED_LOCAL): ...this new definition.
+ * config/mips/iris6.h (ASM_OUTPUT_ALIGNED_LOCAL): Undefine this
+ rather than ASM_OUTPUT_LOCAL. Call mips_declare_common_object.
- PR optimization/11646
- * cfgrtl.c (purge_dead_edges) [JUMP_INSN]: Rematerialize the
- EDGE_ABNORMAL flag for EH edges.
- * toplev.c (rest_of_compilation): Delete unreachable blocks
- if dead edges were purged after the first CSE pass.
+2004-07-07 Jason Merrill <jason@redhat.com>
-2003-09-16 Jakub Jelinek <jakub@redhat.com>
+ PR c++/15815
+ * doc/extend.texi (C++ Interface): Correct information and
+ discourage use.
- * config/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
- * config/alpha/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
- * config/arm/linux-elf.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
- * config/rs6000/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
- * config/rs6000/linux64.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
- * config/sh/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
- * config/sparc/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
- * config/sparc/linux64.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+2004-07-07 Andreas Schwab <schwab@suse.de>
-2003-09-15 Alexandre Oliva <aoliva@redhat.com>
+ * config/ia64/ia64.md: Define new attribute "empty".
+ (prologue_use, nop_x, insn_group_barrier): Set it.
- * cpplib.c (do_pragma): Remove unnecessary cb_line_change.
+ * config/ia64/ia64.c (ia64_reorg): When looking for trailing call
+ skip over "empty" insns.
-2003-09-14 Alexandre Oliva <aoliva@redhat.com>
+2004-07-07 Vladimir Makarov <vmakarov@redhat.com>
- * cppmain.c (cb_line_change): Revert 2003-08-04's change.
- * c-lex.c (cb_line_change): Skip line changing whenever
- cppmain.c would.
+ PR target/16130
+ PR target/16142
+ PR target/16143
+ * config/ia64/ia64.c (ia64_dfa_new_cycle): Reset DFA state for asm
+ insn.
-2003-09-11 Alexandre Oliva <aoliva@redhat.com>
+2004-07-06 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
- PR fortran/11522
- * dwarf2out.c (gen_inlined_subroutine_die): Emit abstract function
- for ultimate origin even if block is abstract.
-
-2003-09-10 Martin Husemann <martin@duskware.de>
-
- PR target/11965
- * config/sparc/sparc.c (sparc_v8plus_shift): Protect against
- constants greater than 63.
- * config/sparc/sparc.md (ashlsi3, ashrsi3, lshrsi3): Protect
- against constants greater than 31.
- (*ashldi3_sp64, *ashrdi3_sp64, *lshrdi3_sp64): Protect against
- constants greater than 63.
-
-2003-09-09 Richard Henderson <rth@redhat.com>
-
- PR target/12224:
- * config/ia64/ia64.c (ia64_expand_move): Properly truncate
- result when op0 is SImode.
+ PR target/1679.
+ * config/m32r/m32r.c (m32r_function_symbol): New function:
+ Generate a symbol name RTX with the correct m32r specific flags
+ set.
+ (block_move_call): Use new function to generate correct symbol.
+ * config/m32r/m32r-protos.h: Add prototype for new funcion.
+ * config/m32r/m32r.h (INITIALIZE_TRAMPOLINE): Use the new
+ function.
-2003-09-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+2004-07-07 Richard Sandiford <rsandifo@redhat.com>
- * configure.in (gcc_cv_as_ix86_cmov_sun_syntax): Check if
- assembler supports Sun syntax for cmov.
- * configure: Regenerate.
- * config.in: Li{ewise.
- * config/i386/i386.c: Rename CMOV_SUN_AS_SYNTAX to
- HAVE_AS_IX86_CMOV_SUN_SYNTAX.
- * config/i386/sol2.h (CMOV_SUN_AS_SYNTAX): Remove.
- Fixes PR target/12101.
+ PR target/16357
+ * config/mips/mips.c (mips_block_move_straight): Pass BLKmode memrefs
+ to mips_expand_unaligned_load, mips_expand_unaligned_store, and
+ move_by_pieces.
-2003-09-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+2004-07-07 Richard Sandiford <rsandifo@redhat.com>
- * configure.in (gcc_cv_as_hidden): Disable unless using GNU ld.
- * configure: Regenerate.
+ PR target/15869
+ * config/mips/mips.c (mips_avoid_hazards): Call split_all_insns_noflow.
-2003-09-08 Mark Mitchell <mark@codesourcery.com>
+2004-07-06 Mark Mitchell <mark@codesourcery.com>
- * mklibgcc.in (libcc.a): Depend on stmp-dirs.
- (libgov.a): Likewise.
- (libgcc_eh.a): Likewise.
+ * doc/include/gcc-common.texi: Increment version number.
+ * version.c (version_string): Likewise.
-2003-09-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-07-06 Joseph S. Myers <jsm@polyomino.org.uk>
- PR target/11689
- * config/i386/i386.c (memory_address_length): Fix computation when
- the base is esp or ebp.
+ * doc/sourcebuild.texi: Use semicolons instead of commas in
+ section title.
-2003-09-07 Mark Mitchell <mark@codesourcery.com>
+2004-07-06 Joseph S. Myers <jsm@polyomino.org.uk>
- PR c++/11852
- * varasm.c (initializer_constant_valid_p): Correct logic for
- CONSTRUCTORs.
+ * doc/bugreport.texi, doc/configterms.texi, doc/contrib.texi,
+ doc/contribute.texi, doc/cpp.texi, doc/cppinternals.texi,
+ doc/extend.texi, doc/install.texi, doc/invoke.texi, doc/md.texi,
+ doc/portability.texi, doc/trouble.texi: Avoid some first-person
+ references and patronizing comments. Based on printed manual.
+ * doc/invoke.texi: Don't reference fortran@gnu.org.
+ * doc/trouble.texi (Warning when a non-void function value is
+ ignored): Rewrite. From Russ Allbery and Chris Devers.
-Sun Sep 7 14:53:36 CEST 2003 Jan Hubicka <jh@suse.cz>
+2004-07-06 Joseph S. Myers <jsm@polyomino.org.uk>
- * cfgcleanup.c (try_simplify_condjump): Fix again the preivous patch.
+ * doc/cppinternals.texi, doc/install.texi, doc/invoke.texi,
+ doc/md.texi, doc/sourcebuild.texi, doc/tm.texi, doc/trouble.texi:
+ Use terminology "testsuite" and "enumerated".
-2003-09-07 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
+2004-07-06 Eric Christopher <echristo@redhat.com>
- PR optimization/11662
+ PR rtl-optimization/14700
Backport from mainline:
+ 2004-06-30 Zack Weinberg <zack@codesourcery.com>
+ * combine.c (distribute_notes): Don't look at global_regs for
+ pseudos.
- 2003-07-10 Denis Chertykov <denisc@overta.ru>
- Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * combine.c (gen_binary): Handle the CLOBBER rtx and
- don't build a binary operation with it.
-
-Sat Sep 6 23:16:35 CEST 2003 Jan Hubicka <jh@suse.cz>
-
- * cfgcleanup.c (try_simplify_condjump): Fix my previous patch.
-
- PR target/12070
- * calls.c (emit_library_call_value_1): Fix saving of BLKmode arguments.
-
- PR opt/12082
- * cfgcleanup.c (try_simplify_condjump): Avoid unreachable code warning.
-
-2003-09-06 Steven Bosscher <steven@gcc.gnu.org>
-
- PR c/9862
- * c-decl.c (c_expand_body): Move return warning from here...
- (finish_function): ...to here.
-
-2003-09-05 Jan Hubicka <jh@suse.cz>
-
- PR target/8869
- * expr.c (convert_modes): Deal properly with integer to vector
- constant conversion.
-
-2003-09-05 Andrew Pinski <pinskia@physics.uc.edu>
-
- PR c/10962
- * c-decl.c (field_decl_cmp): Add back function.
- (finish_struct): Sort fields if number greater than 15
- and no anymous structs/unions.
-
-2003-09-04 Jakub Jelinek <jakub@redhat.com>
-
- * config/ia64/libgcc-ia64.ver: Export _Unwind_GetBSP@@GCC_3.3.2.
- * config/ia64/unwind-ia64.c (_Unwind_GetBSP): New function.
- * unwind.h (_Unwind_GetBSP): New prototype.
- * libgcc-std.ver: Add empty GCC_3.3.2 version.
- * mkmap-symver.awk: For symbol versions with no exported symbols,
- don't put anything into version script, just change all symbol
- versions which inherit from it to inherit from its ancestor.
-
-2003-09-02 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
-
- This is a fix for PR 10988:
- * m32r.c (m32r_print_operand): Correct comment.
- (m32r_expand_block_move): Correct the handling of leftover/small
- blocks.
- (m32r_block_small_immediate_operand): New predicate.
- * m32r.md (movstrsi_small_internal): New pattern.
- * m32r.h (PREDICATE_CODES): Add m32r_block_small_immediate_operand.
- * m32r-protos.h: Add prototype for m32r_block_small_immediate_operand.
-
-2003-08-25 Richard Henderson <rth@redhat.com>
-
- * config/i386.i386.c (ix86_return_in_memory): Reformat. Return true
- for 16-byte vector modes if sse not enabled; warn for abi change.
- (ix86_value_regno): Only return xmm0 for 16-byte vector types.
-
-2003-08-25 Zack Weinberg <zack@codesourcery.com>
-
- * config.gcc (hppa*-*-hpux11*, ia64*-*-hpux*): Remove
- commented-out logic to use DCE threads (if present), add
- support for POSIX threads.
- * config/ia64/hpux.h: Define CPP_SPEC to set appropriate
- #defines for -pthread. Add -lpthread to LIB_SPEC when
- -pthread. In both cases take -mt as a synonym for -pthread
- for acc compatibility.
- Define GTHREAD_USE_WEAK to 0.
- * config/pa/pa-hpux11.h: Likewise for CPP_SPEC and LIB_SPEC.
- Remove old logic for DCE threads from LIB_SPEC.
- * config/pa/pa64-hpux.h: Define GTHREAD_USE_WEAK to 0.
-
-2003-08-25 Ulrich Weigand <uweigand@de.ibm.com>
-
- * combine.c (distribute_notes): Handle REG_ALWAYS_RETURN.
-
-2003-08-23 Jakub Jelinek <jakub@redhat.com>
-
- * c-decl.c (pushdecl): Only put decls which finish_struct will do
- something about onto incomplete chain.
- (finish_struct): If not removing type from incomplete
- list, update prev.
-
-2003-08-23 Alexandre Oliva <aoliva@redhat.com>
-
- * cppmain.c (cb_line_change): Don't skip line changing while
- parsing macro arguments in the top-level context.
-
-2003-08-22 Mark Mitchell <mark@codesourcery.com>
-
- * config/ia64/hpux.h (SUPPORTS_INIT_PRIORITY): Define to 0.
-
- * config/ia64/ia64.c (ia64_output_mi_thunk): Support ILP32 mode.
-
-2003-08-21 Kazu Hirata <kazu@cs.umass.edu>
-
- PR target/11805
- * config/h8300/h8300.md (two anonymous patterns): Remove.
-
-2003-08-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * stmt.c (expand_asm_operands): Avoid string concatenation.
- * tree.c (default_flag_random_seed): Avoid ISO C definition.
- * varasm.c (output_constant_def): Delete unused variable.
-
-2003-08-18 Matt Kraai <kraai@alumni.cmu.edu>
-
- PR c/11207
- * c-typeck.c (set_init_index): Check for negative index.
-
-2003-08-14 Mark Mitchell <mark@codesourcery.com>
-
- * version.c (version_string): Use "prerelease" not "experimental".
-
-2003-08-11 James E Wilson <wilson@tuliptree.org>
-
- PR optimization/11319
- PR target/10021
- * alias.c (find_base_value, case REG): Return 0 not src if no base
- found.
-
-2003-08-11 Kean Johnston <jkj@sco.com>
-
- * fixinc/inclhack.def (sco_math): Updated test text and select trigger
- according to bkorb's review.
- * fixinc/inclhack.def (sco_regset): Ditto.
- * fixinc/inclhack.def (AAB_svr4_replace_byteorder): Remove all mach
- lines so that this file is unconditionally replaced.
- * fixinc/inclhack.def (sco_string): Use ansi/string.h as the first file
- to check so that the Ultrix string.h check doesnt overwrite the test
- case with its replacement text.
- * fixinc/fixincl.x: Regenerated
- * fixinc/tests/base/math.h: Updated sco_math result text
- * fixinc/tests/base/ansi/string.h: New file.
- * fixinc/tests/base/sys/regset.h: Compacted result text to fewer lines.
-
-2003-08-11 Dale Johannesen <dalej@apple.com>
- * config/rs6000/rs6000.md (ctrsi, ctrdi): Reenable handling of
- decrement-and-branch farther away than 32 bits.
-
-2003-08-10 Zack Weinberg <zack@codesourcery.com>
-
- Backport the following changes from mainline:
-
- 2003-05-08 David Mosberger <davidm@hpl.hp.com>
-
- * unwind-libunwind.c (_Unwind_FindEnclosingFunction): New.
-
- 2003-04-03 Richard Henderson <rth@redhat.com>
-
- * unwind-libunwind.c (_Unwind_GetCFA): New.
-
- 2003-03-27 David Mosberger <davidm@hpl.hp.com>
-
- * unwind-libunwind.c (uw_frame_state_for): Adjust for libunwind
- v0.9 API change: replace read of UNW_REG_HANDLER with
- unw_get_proc_info().
- (_Unwind_GetLanguageSpecificData): Replace read of UNW_REG_LSDA
- with unw_get_proc_info().
- (_Unwind_GetRegionStart): Replace UNW_REG_PROC_START with
- unw_get_proc_info().
-
- 2003-03-13 Nathanael Nerode <neroden@gcc.gnu.org>
-
- * unwind-libunwind.c: Replace "GNU CC" with "GCC".
-
- 2002-10-02 David Mosberger-Tang <David.Mosberger@acm.org>
-
- * config/t-libunwind: Mention unwind-sjlj.c.
- * unwind-libunwind.c: Change #ifdef __USING_LIBUNWIND_EXCEPTIONS__
- to #ifndef __USING_SJLJ_EXCEPTIONS__.
-
- * configure.in: Move sjlj-exceptions and --enable-libunwind-exceptions
- before inclusion of config.gcc, but after configuring the compiler etc.
- Determine default value for --enable-libunwind-exceptions based on
- whether the host has a libunwind library (not guaranteed to be correct,
- but it's a reasonable first guess and can always be overridden with an
- explicit --enable/disable-libunwind-exceptions.
- * config.gcc: For target ia64*-*-linux*, mention t-libunwind as a
- tmake_file when $use_libunwind_exceptions is enabled.
- * Makefile.in: Update comment: LIB2ADDEH is updated not just by
- ia64 (e.g., config/t-linux also updates it).
- * gcc.c (init_spec) [USE_LIBUNWIND_EXCEPTIONS]: Mention -lunwind
- along with the shared version of libgcc since the latter requires
- the former.
-
- * unwind-libunwind.c: New file.
- * config/t-libunwind: Ditto.
-
-2003-08-10 Richard Henderson <rth@redhat.com>
-
- PR target/11693
- * config/ia64/ia64.c (ia64_emit_nops): Skip L slots when
- padding before inline assembly.
-
-2003-08-10 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- PR c++/11712
- * pa-hpux.h, pa-hpux10.h, pa-hpux11.h (TARGET_OS_CPP_BUILTINS): Define
- __STDC_EXT__ when using C++ dialect.
-
-2003-08-08 Kean Johnston <jkj@sco.com>
-
- PR target/9877
- PR target/8336
- * config.gcc (sco3.2v5*): Use elfos.h and dbxelf.h in tm_file;
- Eliminate need for t-sco5gas target fragment.
- No longer build crt{begin,end}S.o, that were used for COFF support.
- * tlink.c (recompile_files): Add missing = in putenv() calls.
- * unwind-dw2.c (_Unwind_GetCFA): Correct return cast.
- * config/i386/sco5.h: Major overhaul to remove all COFF support
- * config/i386/t-sco5: Multilib for PIC support
- * config/i386/t-sco5gas: Remove
- * config/i386/i386.c: Check value as well as presence of
- SUPPORTS_ONE_ONLY
- * doc/install.texi: Update for modern SCO instructions
- * fixinc/check.tpl: Allow user to specify diff program for make check
- * fixinc/inclhack.def: Fix several SCO header files, namely string.h,
- math.h, sys/byteorder.h and sys/regset.h.
- * fixinc/fixincl.x: Regenerate
- * fixinc/tests/base/math.h: Update
- * fixinc/tests/base/sys/byteorder.h: Update
- * fixinc/tests/base/string.h: Added
- * fixinc/tests/base/sys/regset.h: Added
- * testsuite/gcc.dg/nest.c: Allow failure on SCO (-pg not supported)
-
-2003-08-08 Roger Sayle <roger@eyesopen.com>
-
- PR c/11370
- * calls.c (emit_call_1): Don't bother popping the arguments off of
- the stack after a noreturn function call; The adjustment is dead.
- (expand_call): Likewise.
-
-2003-08-08 SUGIOKA Toshinobu <sugioka@itonet.co.jp>
-
- * config.gcc: Do not override sh/t-linux with sh/t-le.
-
-2003-08-08 Kaz Kojima <kkojima@gcc.gnu.org>
-
- * config/sh/linux.h (SUBTARGET_LINK_SPEC): Don't set rpath.
- (LIB_SPEC): Set -lpthread always when -pthread set. Set -lieee
- when -mieee-fp set and -shared not set.
-
-2003-08-08 Richard Henderson <rth@redhat.com>
-
- PR target/11535
- * config/ia64/ia64.c (ia64_initial_elimination_offset): Remove
- RETURN_ADDRESS_POINTER_REGNUM.
- (ia64_expand_prologue): Don't frob it.
- (ia64_output_function_epilogue): Likewise.
- (ia64_return_addr_rtx): New.
- (ia64_split_return_addr_rtx): New.
- * config/ia64/ia64-protos.h: Update.
- * config/ia64/ia64.h (FIRST_PSEUDO_REGISTER): Decrement.
- (RETURN_ADDRESS_POINTER_REGNUM): Remove.
- (GENERAL_REGNO_P): Don't check it.
- (AR_*_REGNUM): Renumber.
- (FIXED_REGISTERS): Remove RETURN_ADDRESS_POINTER_REGNUM.
- (CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS): Likewise.
- (REG_ALLOC_ORDER, REG_CLASS_CONTENTS): Likewise.
- (ELIMINABLE_REGS, REGISTER_NAMES): Likewise.
- (RETURN_ADDR_RTX): Use ia64_return_addr_rtx.
- * config/ia64/ia64.md (UNSPEC_RET_ADDR): New.
- (movdi_ret_addr): New.
-
-2003-08-03 Geoffrey Keating <geoffk@apple.com>
-
- PR 11709
- * varasm.c (output_constant_def_contents): Use
- ASM_DECLARE_CONSTANT_NAME if defined.
- * doc/tm.texi (Label Output): Document ASM_DECLARE_CONSTANT_NAME.
- * config/darwin.h (ASM_DECLARE_OBJECT_NAME): Ensure zero-sized
- objects get at least one byte to prevent assembler problems.
- (ASM_DECLARE_CONSTANT_NAME): New.
-
-2003-08-07 Mark Mitchell <mark@codesourcery.com>
-
- * version.c (version_string): Reset to prerelease.
- * doc/include/gcc-common.texi: Update version.
-
-2003-08-04 Release Manager
-
- * GCC 3.3.1 Released.
-
-2003-08-04 Release Manager
-
- * GCC 3.3.1 Released.
-
-2003-08-03 Neil Booth <neil@daikokuya.co.uk>
-
- PR preprocessor/11534
- * cppexp.c (parse_defined): Warn only if -pedantic.
-
-2003-08-03 Mark Mitchell <mark@codesourcery.com>
-
- * Makefile.in (ORDINARY_FLAGS_TO_PASS): Pass AR.
-
- * Makefile.in (STAGE2_FLAGS_TO_PASS): Pass AR_FOR_TARGET and
- RANLIB_FOR_TARGET.
- (stage1_build): Likewise.
-
-2003-08-03 Jan Hubicka <jh@suse.cz>
-
- PR 10510
- * config/pa/pa.h (MAYBE_FP_REG_CLASS_P): New.
- (SECONDARY_MEMORY_NEEDED): Use it.
-
-2003-08-01 Geoffrey Keating <geoffk@apple.com>
-
- PR 11709 (partial fix)
- * config/rs6000/rs6000.c (rs6000_output_function_epilogue): Don't
- insert a label at the end of an function under Mach-O.
-
- PR 11313
- * c-pragma.c (maybe_apply_pragma_weak): Don't get DECL_ASSEMBLER_NAME
- when it's not needed.
-
-2003-07-29 Richard Henderson <rth@redhat.com>
-
- PR target/10681
-
- 2003-06-27 J"orn Rennecke <joern.rennecke@superh.com>
- * flow.c (propagate_one_insn): Use proper test for a register
- being part of the return value.
-
- 2003-06-26 Richard Henderson <rth@redhat.com>
- * flow.c (propagate_one_insn): Preserve live-at-end registers
- across tail calls.
-
- 2003-06-26 Richard Henderson <rth@redhat.com>
- * config/ia64/ia64.c (ia64_expand_call): Don't add ar.pfs for sibcalls.
- (ia64_split_call): Only load descriptor for GP register inputs.
- (ia64_expand_epilogue): Check current_frame_info.mask not
- current_function_is_leaf to restore ar.pfs.
-
-2003-07-26 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/install.texi (Testing): Adjust required versions of DejaGnu.
-
-2003-07-24 Aldy Hernandez <aldyh@redhat.com>
+ 2004-06-24 Eric Christopher <echristo@redhat.com>
+ * combine.c (distribute_notes): Don't delete sets to
+ global register variables.
- Backport the folling patch.
+2004-07-04 Gerald Pfeifer <gerald@pfeifer.com>
- 2003-04-01 Aldy Hernandez <aldyh@redhat.com>
+ * doc/contrib.texi (Contributors): Adjust link for GNU Classpath.
- PR/8878
- * expr.c (expand_expr): Handle VECTOR_CST.
- (const_vector_from_tree): New.
+2004-07-01 Release Manager
- * varasm.c (output_constant): Handle VECTOR_CST.
+ * GCC 3.4.1 released.
- * c-typeck.c (digest_init): Build a vector constant from a
- VECTOR_TYPE.
+2004-06-28 Neil Booth <neil@duron.akihabara.co.uk>
-2003-07-23 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+ PR preprocessor/16192
+ PR preprocessor/15913
+ PR preprocessor/15572
+ * cppexp.c (_cpp_parse_expr): Handle remaining cases where an
+ expression is missing.
+ * cppinit.c (post_options): Traditional cpp doesn't do // comments.
+ * doc/cpp.texi: Don't document what we do for ill-formed expressions.
+ * doc/cppopts.texi: Clarify processing of command-line defines.
- PR target/11607 and PR target/11516
- * pa.md (extzv, extv, insv): Revert latter half of last patch.
+2004-06-28 Richard Sandiford <rsandifo@redhat.com>
-2003-07-23 Mark Mitchell <mark@codesourcery.com>
+ PR target/16176
+ * config/mips/mips.c (mips_expand_unaligned_load): Use a temporary
+ register for the destination of the lwl or ldl.
- PR optimization/10679
- * tree-inline.c (inlinable_function_p): Honor MIN_INLINE_INSNS.
+2004-06-25 Philip Blundell <philb@gnu.org>
-2003-07-22 Bob Wilson <bob.wilson@acm.org>
+ PR wrong-code/15089
+ * loop.c (scan_loop): Do not move user-specified register
+ assignments.
- * unwind-c.c (PERSONALITY_FUNCTION): Delete duplicate define.
+2004-06-25 Mark Mitchell <mark@codesourcery.com>
-2003-07-23 Dave Fluri <dave.fluri@onlink.net>
+ PR wrong-code/16129
+ * alias.c (get_alias_set): Adjust setting of
+ DECL_POINTER_ALIAS_SET for pointers to aggregates.
- * doc/extend.texi: Fixes to spelling, grammar, and diction.
+2004-06-25 Richard Sandiford <rsandifo@redhat.com>
-2003-07-21 H.J. Lu <hongjiu.lu@intel.com>
+ PR target/16144
+ * config/mips/mips.md (divsf, divdf): Don't FAIL if the first operand
+ is 1.0; force it into a register instead.
- PR optimization/11599
- * config/ia64/ia64.md (prefetch): Support predicate.
+2004-06-24 Alan Modra <amodra@bigpond.net.au>
-2003-07-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+ * calls.c (expand_call): Call INIT_CUMULATIVE_ARGS earlier, and
+ pass raw n_named_args to it.
- PR optimization/11536
- * unroll.c (loop_iterations): Do not replace a register holding
- the final value by its equivalent before the loop if it is not
- invariant.
+2004-06-22 Richard Henderson <rth@redhat.com>
-2003-07-21 Ben Elliston <bje@wasabisystems.com>
+ PR middle-end/16026
+ * function.c (assign_parms): Don't abort for overaligned PARALLEL.
- * doc/invoke.texi (V850 Options): Spelling fixes.
+2004-06-21 Kelley Cook <kcook@gcc.gnu.org>
-2003-07-21 Lisa M. Goldstein <opus@gnu.org>
+ PR target/15551
+ * config/i386/i386.md: Change UNSPEC_STACK_PROBE to UNSPECV_STACK_PROBE.
+ (allocate_stack_worker): Make unspec_volatile.
+ (allocate_stack_worker_rex64): Likewise.
+ (allocate_stack_worker_postreload): Likewise.
+ (allocate_stack_worker_rex64_postreload): Likewise.
- * doc/invoke.texi: Fixes to style, grammar and diction.
+2004-06-21 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-2003-07-20 Mark Mitchell <mark@codesourcery.com>
+ PR rtl-optimization/14782
+ * pa.c (emit_move_sequence): Use SFmode for 4-byte modes when doing
+ the address checks for secondary reloads for loads from and stores
+ to floating-point registers.
+ * pa.h (EXTRA_CONSTRAINT, case T): Use SFmode for 4-byte modes
+ in the address check. Move work around for ELF32 targets to
+ GO_IF_LEGITIMATE_ADDRESS.
+ (GO_IF_LEGITIMATE_ADDRESS): Require constant offsets to be
+ correctly aligned for DImode loads and stores. Don't allow long
+ SFmode displacements on ELF32.
- PR debug/11279
- * dwarf2out.c (gen_enumeration_type_die): Remember that
- enumerators can be unsigned.
+2004-06-21 Richard Henderson <rth@redhat.com>
-2003-07-19 Kelley Cook <kelleycook@wideopenwest.com>
+ PR rtl-opt/16114
+ * cse.c (merge_equiv_classes): Also rehash in response to
+ delete_reg_equiv changes.
+ (rehash_using_reg): Don't exclude REGs from rehashing.
- * c-tree.texi: Backport changes from mainline.
- * c-tree.texi: Ditto.
- * collect2.texi: Ditto.
- * cpp.texi: Ditto.
- * cppopts.texi: Ditto.
- * extend.texi: Ditto.
- * fragments.texi: Ditto.
- * headerdirs.texi: Ditto.
- * install.texi: Ditto.
- * invoke.texi: Ditto.
- * md.texi: Ditto.
- * portability.texi: Ditto.
- * rtl.texi: Ditto.
- * sourcebuild.texi: Ditto.
- * trouble.texi: Ditto.
+2004-06-21 Richard Sandiford <rsandifo@redhat.com>
-2003-07-19 Kelley Cook <kelleycook@wideopenwest.com>
+ PR rtl-optimization/15159
+ * tree.c (unsafe_for_reeval): Return 2 for TRY_CATCH_EXPRs.
- PR optimization/4490
- * doc/invoke.texi (m96bit-long-double, m128bit-long-double): Reword
- documentation to accurately reflect what these options do.
+2004-06-19 Richard Henderson <rth@redhat.com>
-2003-07-18 Richard Henderson <rth@redhat.com>
- David S. Miller <davem@redhat.com>
+ PR target/15941
+ * function.c (assign_parms): If not padding upward or intentionally
+ forcing upward padding, take offset_rtx into account when determining
+ the alignment for stack_parm.
- PR target/11556
- * optabs.c (prepare_operand): Fail gracefully instead of abort
- if the predicate doesn't satisfy.
- (gen_cond_trap): Allow prepare_operand to fail.
- Pass correct opnum argument to prepare_operand.
+2004-06-19 Richard Henderson <rth@redhat.com>
-2003-07-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+ PR target/15550
+ * ifcvt.c (noce_try_move): Recognize all generated instructions.
- PR optimization/11083
- * toplev.c (rest_of_compilation): Delete unreachable blocks
- if dead edges were purged after the addressof pass.
+2004-06-19 Andrew Pinski <pinskia@physics.uc.edu>
-2003-07-17 Mark Mitchell <mark@codesourcery.com>
+ PR target/10129
+ * config/darwin.c (darwin_encode_section_info): When the decl has
+ a DECL_INITIAL, it is only defined also when it is not a common.
- PR optimization/11557
- * calls.c (flags_from_decl_or_type): Do not set ECF_LIBCALL_BLOCK
- unless we know which function is being called.
+2004-06-17 Zack Weinberg <zack@codesourcery.com>
-2003-07-17 Nathanael Nerode <neroden@gcc.gnu.org>
+ Bug 14610
+ * Makefile.in (min-insn-modes.o): Correct dependencies.
+ * real.c (encode_ieee_extended, decode_ieee_extended): Always
+ produce/consume 12-byte little-endian Intel format.
+ (encode_ieee_extended_128, decode_ieee_extended_128): Delete.
+ (encode_ieee_extended_motorola, decode_ieee_extended_motorola)
+ (encode_ieee_extended_intel_96, decode_ieee_extended_intel_96)
+ (encode_ieee_extended_intel_128, decode_ieee_extended_intel_128):
+ New functions which convert between 12-byte little-endian Intel
+ format and the desired format.
+ (ieee_extended_motorola_format, ieee_extended_intel_96_round_53_format)
+ (ieee_extended_intel_96_format, ieee_extended_intel_128_format):
+ Update.
- PR bootstrap/11043
- * config/arc/t-arc: Replace bogus references to "x-crtinit.o",
- "x-crtfini.o" with "crtinit.o", "crtfini.o".
+2004-06-16 James E Wilson <wilson@specifixinc.com>
-2003-07-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+ PR c++/14808
+ * config/i386/cygwin.h (TARGET_IS_PE_COFF): Delete duplicate macro.
- PR other/11466
- * doc/invoke.texi (SPARC Options): Document "-mlittle-endian"
- and its restrictions for the SPARC64 port.
+2004-06-16 Bernardo Innocenti <bernie@develer.com>
Backport from mainline:
- 2003-06-13 Florian Weimer <fw@deneb.enyo.de>
-
- * doc/invoke.texi (SPARC Options): Document "-mimpure-text".
+ 2004-06-16 Bernardo Innocenti <bernie@develer.com>
-2003-07-17 Eric Botcazou <ebotcazou@libertysurf.fr>
- Phil Edwards <phil@jaj.com>
+ PR target/13292
+ * config/m68k/m68k.h (TARGET_SWITCHES): Don't remove MASK_68040_ONLY
+ on -msoft-float.
+ (TARGET_FLT_EVAL_METHOD): Don't advertise extended precision for
+ 68040 and soft-float.
+ * config/m68k/m68k.md (truncdfsf2): Explicitly require TARGET_68881
+ in the TARGET_68040_ONLY case.
- * doc/install.texi (*-*-solaris2*): Document the step-by-step
- procedure to bootstrap and install.
- Document the preference for the legacy Sun tools in /usr/bin
- over the POSIX tools in /usr/xpg4/bin for the build process.
+2004-06-16 Vladimir Makarov <vmakarov@redhat.com>
-2003-07-16 Richard Henderson <rth@redhat.com>
+ PR target/15653
+ * config/ia64/ia64.c (ia64_dfa_new_cycle): Do not insert nops
+ after shifts before asm.
- PR target/10907
- * config/ia64/ia64.c (ia64_epilogue_uses): GP is live at end
- even with !TARGET_CONST_GP.
- (ia64_function_ok_for_sibcall): Reject non-local functions.
+2004-06-15 Chris Demetriou <cgd@broadcom.com>
-2003-07-15 Geoffrey Keating <geoffk@apple.com>
-
- * config/darwin.c (machopic_select_section): Use decl_readonly_section
- to do most of the work.
-
-2003-07-15 David S. Miller <davem@redhat.com>
+ * config/mips/linux.h (ASM_PREFERRED_EH_DATA_FORMAT): Remove
+ definition.
+ * config/mips/linux64.h (ASM_PREFERRED_EH_DATA_FORMAT): Remove
+ #undef and #if 0'd definition.
- * config/sparc/sparc.c (sparc_nonflat_function_epilogue): Only
- emit nop if the last real insn is CALL_INSN.
+2004-06-15 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
-2003-07-15 Loren James Rittle <ljrittle@acm.org>
+ * config/m32r/m32r.h (RETURN_ADDR_RTX): Define.
+ (INCOMING_RETURN_ADDR_RTX): Define.
+ * config/m32r/m32r-protos.h (m32r_return_addr): Added.
+ * config/m32r/m32r.c (m32r_exppand_prologue): Changed for
+ __builtin_return_address(0).
+ (m32r_return_addr): Added for __builtin_return_address(0).
+ (m32r_reload_lr): Ditto.
- * config/i386/freebsd.h (SET_ASM_OP): Remove.
- (SUBTARGET_OVERRIDE_OPTIONS): Handle TARGET_64BIT case.
- (ASM_COMMENT_START, ASM_APP_ON, ASM_APP_OFF, DBX_REGISTER_NUMBER
- MCOUNT_NAME, SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE_SIZE): Whitespace.
+ * longlong.h: Fix macros for m32r add_ssaaaa and sub_ddmmss.
-2003-07-15 Mark Mitchell <mark@codesourcery.com>
+2004-06-15 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- PR debug/11473
- * dbxout.c (dbxout_type): Use TYPE_SIZE to determine the sizes of
- base classes.
+ * gccbug.in: Update optimization -> tree-optimization/rtl-optimization.
-2003-07-15 James A. Morrison <ja2morri@student.math.uwaterloo.ca>
+2004-06-14 Eric Botcazou <ebotcazou@libertysurf.fr>
- * doc/include/texinfo.tex: Upgrade to texinfo 4.6.
+ * real.c: Fix bit count in head comment.
-2003-07-15 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-06-14 Jakub Jelinek <jakub@redhat.com>
- PR optimization/11320
- * sched-int.h (struct deps) [reg_conditional_sets]: New field.
- (struct sched_info) [compute_jump_reg_dependencies]: New prototype.
- * sched-deps.c (sched_analyze_insn) [JUMP_INSN]: Update call to
- current_sched_info->compute_jump_reg_dependencies. Record which
- registers are used and which registers are set by the jump.
- Clear deps->reg_conditional_sets after a barrier.
- Set deps->reg_conditional_sets if the insn is a COND_EXEC.
- Clear deps->reg_conditional_sets if the insn is not a COND_EXEC.
- (init_deps): Initialize reg_conditional_sets.
- (free_deps): Clear reg_conditional_sets.
- * sched-ebb.c (compute_jump_reg_dependencies): New prototype.
- Mark registers live on entry of the fallthrough block and conditionally
- set as set by the jump. Mark registers live on entry of non-fallthrough
- blocks as used by the jump.
- * sched-rgn.c (compute_jump_reg_dependencies): New prototype.
- Mark new parameters as unused.
+ PR middle-end/15945
+ * simplify-rtx.c (simplify_binary_operation): Don't optimize out
+ Inf + -Inf, Inf - Inf, Inf / Inf and 0 * Inf if flag_trapping_math.
-2003-07-14 Mark Mitchell <mark@codesourcery.com>
+2004-06-14 Jakub Jelinek <jakub@redhat.com>
- PR debug/11098
- * integrate.c (copy_decl_for_inlining): Do not mark copied decls
- as DECL_ABSTRACT.
+ PR target/15178
+ * config/i386/sol2.h (ASM_OUTPUT_DEF_FROM_DECLS): Define.
-2003-07-14 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+2004-06-14 Alan Modra <amodra@bigpond.net.au>
- PR optimization/11440
- * gcse.c (try_replace_reg): Don't attach notes to ZERO_EXTRACT or
- SIGN_EXTRACT SETs.
+ * config/rs6000/rs6000.h (ASM_CPU_SPEC): Handle -mpowerpc64 and -mcpu
+ for power5 and rs64a. Correct condition for default. Correct power3,
+ 620, 630, 7400, 7450, G4, 970 and G5 -mcpu entries. Add -many.
-2003-07-13 Aaron W. LaFramboise <awlaframboise@aol.com>
+2004-06-13 Alan Modra <amodra@bigpond.net.au>
- * config/i386/gthr-win32.c (__GTHREAD_HIDE_WIN32API): Define to 1.
+ Apply mainline 2004-01-27 Alan Modra <amodra@bigpond.net.au>
+ * config/rs6000/rs6000.h: Correct target_flags free bits comment.
+ (PREDICATE_CODES): Remove duplicate.
+ * config/rs6000/linux64.h (CPP_SYSV_SPEC): Don't define.
+ (SUBSUBTARGET_OVERRIDE_OPTIONS): Disallow 32 bit TARGET_PROFILE_KERNEL.
+ (MASK_PROFILE_KERNEL): Adjust define.
-2003-07-13 Roger Sayle <roger@eyesopen.com>
+2004-06-13 Hans-Peter Nilsson <hp@axis.com>
- PR optimization/11059
- * expr.c (can_store_by_pieces): Return true if length is zero.
- (store_by_pieces): Do nothing if length is zero.
- (clear_by_pieces): Do nothing if length is zero.
- (clear_storage): Do nothing if length is zero.
- (store_constructor): Simplify code when size is zero, or the
- target has already been cleared. This avoids emitting a
- blockage instruction when initializing empty structures.
+ PR rtl-optimization/15296
+ * reorg.c (fill_simple_delay_slots): Use next_real_insn when
+ getting last consecutive label at a branch.
+ (relax_delay_slots): Similar, near top of loop.
-2003-07-13 Richard Henderson <rth@redhat.com>
+2004-06-12 Andreas Jaeger <aj@suse.de>
- * libgcc-std.ver (GCC_3.3.1): Export __gcc_personality_sj0,
- __gcc_personality_v0.
+ * libgcc-std.ver: Add __unorddf2 and __unordsf2 with version 3.3.4.
+ * libgcc-darwin.ver: Likewise.
-2003-07-11 Dara Hazeghi <dhazeghi@yahoo.com>
+2004-06-11 Bernardo Innocenti <bernie@develer.com>
- PR optimization/10877
- * doc/install.tex: Update required binutils for i?86-*-linux*
+ PR target/8309
+ PR target/13312
+ Backport from mainline:
-2003-07-11 Ben Elliston <bje@redhat.com>
+ 2004-05-27 Peter Jakubek <peter@laseranimation.com>
- PR c++/1607
- * doc/extend.texi (Function Attributes): Document the effect of
- the C++ "this" parameter on the counting of arguments for the
- "format" and "format_arg" attributes.
+ * reload.c (find_reloads): Force reload for pseudo registers on big
+ endian machines.
-2003-07-11 Danny Smith <dannysmith@users.sourceforge.net>
+2004-06-11 J"orn Rennecke <joern.rennecke@superh.com>
- Backport from mainline.
+ * sh.c (dump_table): New argument start. Changed caller.
+ (fixup_mova): New function.
+ (find_barrier): Use it.
+ (sh_reorg): Likewise. Check for CODE_FOR_casesi_worker_2.
+ If the label a mova refers to is above the mova itself, change
+ the mova into a load.
+ * sh.md (*casesi_worker): Rename to:
+ (casesi_worker_1).
+ (casesi_worker_2): New insn.
- 2003-05-13 Richard Henderson <rth@redhat.com>
+2004-06-11 Hartmut Penner <hpenner@de.ibm.com>
- * c-decl.c (duplicate_decls): Re-invoke make_decl_rtl if
- the old decl had instantiated DECL_RTL.
+ Backport from mainline:
- 2003-05-21 Danny Smith <dannysmitx@users.sourceforge.net>
+ * config/rs6000/rs6000.c (output_vec_const_move):
+ Find all cases of EASY_VECTOR_15_ADD_SELF.
+ (easy_vector_constant_add_self): Accept
+ all vector constant loadable by vsplt* and vadd*.
+ (easy_vector_same): Use easy_vector_splat_const.
+ (easy_vector_const): Use easy_vector_splat_const.
+ (easy_vector_splat_const): New function.
+ (gen_easy_vector_constant_add_self): New function.
- PR c++/9738
- * config/i386/winnt.c (i386_pe_encode_section_info): Enable
- even if not first.
+ * config/rs6000/rs6000-protos.c (gen_easy_vector_constant_add_self):
+ New prototype.
- 2003-07-04 Danny Smith <dannysmith@users.sourceforge.net>
+ * config/rs6000/altivec.md (movv4si splitter): Change to
+ emit move insn with halfed vector constant.
+ (*movv8hi splitter): Likewise.
+ (*movv16qi splitter): Likewise.
- PR c++/5287, PR c++/7910, PR c++/11021
- * config/i386/winnt.c (ix86_handle_dll_attribute): Don't add
- dllimport attribute if function is defined at declaration, but
- report error instead. Likewise for dllimport'd variable
- definitions. Set implicit TREE_PUBLIC for dllimport'd variables
- declared within functions, Report error if dllimport or dllexport
- symbol is not global.
- (i386_pe_dllimport_p): Ignore dllimport attribute of functions
- if defined after declaration or if inlined. Don't allow definition
- of static data members of C++ classes. Don't dllimport virtual
- methods.
- (i386_pe_mark_dllexport): Warn about inconsistent dll attributes.
- (i386_pe_mark_dllimport): Remove unnecessary checks.
- (i386_pe_encode_section_info): Warn if the dllimport attribute
- and symbol prefix have been instantiated and then overridden.
+2004-06-10 Joseph S. Myers <jsm@polyomino.org.uk>
- * doc/extend.texi: Document dllimport and dllexport attributes.
+ * doc/sourcebuild.texi (Front End): Add details of more
+ installation documentation required.
-2003-07-10 James E Wilson <wilson@tuliptree.org>
+2004-06-10 Vladimir Makarov <vmakarov@redhat.com>
- PR optimization/9745
- * loop.c (loop_iv_add_mult_emit_before): Call loop_regs_update before
- loop_insn_emit_before.
- (loop_iv_add_mult_sink, loop_iv_add_mult_hoist): Likewise.
+ PR target/15653
+ * haifa-sched.c (schedule_block): Finish cycle after issuing asm
+ insn.
-2003-07-10 Dara Hazeghi <dhazeghi@yahoo.com>
+2004-06-10 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
- PR bootstrap/10758
- * doc/install.texi: Document requirements for ia64-*-hpux* target.
+ PR web/15263
+ * doc/install.texi: Remove superfluous linebreak.
-2003-07-09 Mark Mitchell <mark@codesourcery.com>
+2004-06-10 Bernardo Innocenti <bernie@develer.com>
- PR c++/10032
- * doc/invoke.texi (C++ Dialect Options): Change documentation of
- -fpermissive.
+ PR target/13803
+ Backport from mainline:
-2003-07-10 Matt Kraai <kraai@alumni.cmu.edu>
+ 2004-05-05 Peter Barada <peter@the-baradas.com>
- * doc/invoke.texi: Fix misspelling of "@item".
+ * config/m68k/m68k.h(EXTRA_CONSTRAINT): Add 'U' for register offset
+ addressing.
+ * config/m68k/m68k.md: Add 'U,U' alternative to ColdFire variants of
+ movsi, movhi, movqi insn patterns.
-2003-07-09 Hans-Peter Nilsson <hp@bitrange.com>
+2004-06-10 Alan Modra <amodra@bigpond.net.au>
- * doc/install.texi (Configuration): Document the valgrind option
- to --enable-checking.
+ Apply from mainline:
+ 2004-03-12 Jakub Jelinek <jakub@redhat.com>
+ * config/rs6000/rs6000-protos.h (rs6000_output_dwarf_dtprel): Add
+ prototype.
+ * config/rs6000/rs6000.c (rs6000_output_dwarf_dtprel): New.
+ * config/rs6000/rs6000.h (ASM_OUTPUT_DWARF_DTPREL): Define.
+
+2004-06-10 Jakub Jelinek <jakub@redhat.com>
+
+ * config/ia64/unwind-ia64.c (uw_frame_state_for): Don't assume a
+ leaf function without unwind info at RP 0.
+
+2004-06-10 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/15191
+ 2004-05-15 Alan Modra <amodra@bigpond.net.au>
+ * config/rs6000/rs6000.c (rs6000_va_arg <ABI_V4>): Don't use
+ UNITS_PER_WORD to calculate gpr size. Re-instate code to set reg
+ count to 8 to handle n_reg > 2.
+ 2004-05-10 Alan Modra <amodra@bigpond.net.au>
+ * config/rs6000/rs6000.c (function_arg_boundary): Always align
+ AltiVec vectors.
+ (function_arg_advance): Pass TARGET_32BIT -mabi=no-altivec AltiVec
+ vectors by refererence. Align the same for TARGET_64BIT to a 16
+ byte boundary. Remove useless code. Add function comment.
+ (function_arg): Similarly. Move gpr rs6000_mixed_function_arg
+ call to where it belongs.
+ (function_arg_partial_nregs): Return true for all TARGET_32BIT
+ -mabi=no-altivec AltiVec vectors. Fix debug output.
+ (rs6000_va_arg): Adjust for AltiVec change.
+ 2004-05-10 Alan Modra <amodra@bigpond.net.au>
+ * config/rs6000/rs6000.c (function_arg_boundary): Align for ABI_V4
+ when size is 8 bytes.
+ (function_arg_advance): Account for stack space used by AltiVec
+ args when -mabi=altivec. Simplify alignment calculations. For
+ ABI_V4, pass AltiVec vectors by reference when -mabi=no-altivec.
+ (function_arg): Similarly.
+ (function_arg_pass_by_reference): True for ABI_V4 AltiVec when
+ not AltiVec ABI.
+ (rs6000_va_arg): Correct fp arg test. Adjust for AltiVec change.
+ Correct alignment, and align before testing reg count. Remove
+ TREE_THIS_VOLATILE from reg. Don't emit unused labels.
+ (rs6000_complex_function_value): Check TARGET_HARD_FLOAT and
+ TARGET_FPRS here..
+ (rs6000_function_value): .. not here before call.
+ 2004-05-07 Alan Modra <amodra@bigpond.net.au>
+ * config/rs6000/rs6000.h (STACK_BOUNDARY): Use 128 bit for either
+ TARGET_ALTIVEC or TARGET_ALTIVEC_ABI.
+ * config/rs6000/sysv4.h (ABI_STACK_BOUNDARY): Likewise.
+ (STACK_BOUNDARY): Delete.
+
+2004-06-10 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/14960
+ 2004-04-24 Alan Modra <amodra@bigpond.net.au>
+ * config/rs6000/rs6000.c (rs6000_stack_info): Rename total_raw_size
+ to non_fixed_size, and leave out fixed_size from the sum.
+ (generate_set_vrsave): Correct clobbers.
+ (rs6000_emit_epilogue): Test TARGET_ALTIVEC with TARGET_ALTIVEC_SAVE.
+ (rs6000_function_value): Test TARGET_ALTIVEC and TARGET_ALTIVEC_ABI.
+ (rs6000_libcall_value): Likewise.
+ * config/rs6000/rs6000.h (FUNCTION_VALUE_REGNO_P): Likewise.
+ (FUNCTION_ARG_REGNO_P): Likewise.
+
+2004-06-10 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/14567
+ 2004-03-13 Alan Modra <amodra@bigpond.net.au>
+ * config/rs6000/rs6000.h (UNITS_PER_ARG, RS6000_ARG_SIZE): Delete.
+ (HARD_REGNO_MODE_OK): Disallow TFmode for fp31.
+ * config/rs6000/rs6000.c (rs6000_arg_size): New function.
+ Update all users of RS6000_ARG_SIZE.
+ (function_arg_advance): Count fregno using mode size.
+ (function_arg): Handle long double split over regs and memory.
+ (function_arg_partial_nregs): Likewise.
+ (rs6000_va_arg): Repackage complex args.
+ 2004-02-23 Fariborz Jahanian <fjahanian@apple.com>
+ * config/rs6000/rs6000.c (function_arg): call to
+ rs6000_mixed_function_arg for DFmode moved to allow
+ normal DFmode incoming register assignment.
+
+2004-06-09 Mark Mitchell <mark@codesourcery.com>
+
+ Revert:
+ PR c++/15815
+ 2004-06-07 Mark Mitchell <mark@codesourcery.com>
+ * doc/extend.texi: Deprecate #pragma interface and #pragma
+ implementation.
+
+2004-06-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR rtl-optimization/15761
+ * cfgloopanal.c (count_strange_loop_iterations,
+ count_loop_iterations): Use gen_int_mode instead
+ of GEN_INT.
+
+2004-06-08 Roger Sayle <roger@eyesopen.com>
+
+ PR c/14649
+ * c-typeck.c (require_constant_value, require_constant_elements):
+ Move declarations to the top of the file.
+ (build_function_call): If we require a constant value, fold with
+ fold_initializer. If the result is a constant, and the function
+ wasn't called using __builtin_foo, issue a pedantic warning.
+ (build_unary_op): If we require a constant value, fold tree with
+ fold_initializer.
+ (build_binary_op): Use require_constant_value to determine whether
+ to call fold or fold_initializer.
+
+2004-06-08 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/15228
+ * function.c (assign_parms): Always set_mem_align with the computed
+ FUNCTION_ARG_BOUNDARY. Don't clear stack_parm if !STRICT_ALIGNMENT.
+
+2004-06-08 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/15598
+ * config/ia64/ia64.c (bundling): Add missed TYPE_A.
+
+2004-06-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR rtl-optimization/15717
+ * config/i386/i386.c (legitimate_constant_p): Do not allow
+ x - symbol_ref.
+
+2004-06-07 James E Wilson <wilson@specifixinc.com>
+
+ PR target/15569
+ * config/ia64/ia64.md (call_value_nogp): Add constraints for op0.
+ (vall_value_gp): Likewise.
+
+2004-06-07 Dan Kegel <dank@kegel.com>
+
+ PR c++/14808
+ * config/i386/cygwin.h (TARGET_IS_PE_COFF): New.
+ * config/i386/cygming.h (TARGET_IS_PE_COFF): New.
+
+2004-06-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/15783
+ * config/sparc/sparc.c (function_arg_union_value): Add 'mode'
+ parameter. Enumerate the registers inside the PARALLEL.
+ (function_arg): Adjust call to function_arg_union_value.
+ (function_value): Likewise.
-2003-07-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2004-06-07 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
- PR Target/11453
- * pa.md: Disparage all mtsar constraints.
- (extzv, extv, insv): Don't fail on length of {32|64}.
+ * pa.c (emit_move_sequence): Fix loading of non 14-bit CONST operands
+ when generating PIC code.
-2003-07-08 James E Wilson <wilson@tuliptree.org>
+ * pa.md: Disable the peephole2 patterns that generate indexed
+ floating-point stores when indexing is disabled.
- PR target/10021
- * emit-rtl.c (set_mem_attribute_minus_bitpos): When handle ARRAY_REF,
- loop over new variable t2 instead of t.
+2004-06-07 Joseph S. Myers <jsm@polyomino.org.uk>
-2003-07-08 Stephane Carrez <stcarrez@nerim.fr>
+ PR c/14765
+ * c-parse.in (compstmt_primary_start): Set last_expr_type to
+ NULL_TREE.
- * config/m68hc11/m68hc11.h (HAVE_AS_DWARF2_DEBUG_LINE): Don't define
- as .file/.loc directives are incompatible with linker relaxation.
+2004-06-07 Mark Mitchell <mark@codesourcery.com>
-2003-07-08 Jakub Jelinek <jakub@redhat.com>
+ PR c++/15815
+ * doc/extend.texi: Deprecate #pragma interface and #pragma
+ implementation.
- PR c/11420
- * config/i386/i386.c (ix86_check_movabs): New function.
- * config/i386/i386-protos.h (ix86_check_movabs): New prototype.
- * config/i386/i386.md (movabs[shqd]i_1_rex64): Kill broken alternative.
- (movabs[shqd]i_[12]_rex64): Add ix86_check_movabs check to conditions.
+2004-06-07 Richard Henderson <rth@redhat.com>
- * config/i386/i386.md (movdi_1_rex64): Set Y<-m alternative's type
- to ssemov.
+ PR rtl-opt/15193
+ * expmed.c (extract_bit_field): Fix vector_extract return.
-2003-07-08 Jakub Jelinek <jakub@redhat.com>
+2004-06-07 Mark Mitchell <mark@codesourcery.com>
- * unroll.c (reg_dead_after_loop): Check for reg in REG_EQUAL and
- REG_EQUIV notes as well.
+ PR c++/15337
+ * c-common.c (c_sizeof_or_alignof_type): Use more detailed error
+ message.
-2003-07-07 Dale Johannesen <dalej@apple.com>
+2004-06-06 Stephane Carrez <stcarrez@nerim.fr>
- PR 10900
- * config/rs6000/darwin-tramp.asm: Fix trampolines.
+ PR target/14542
+ * config/m68hc11/m68hc11.md (move peephole2): Emit a use note to avoid
+ a live change of a register after peephole replacement.
-2003-07-07 Andrew Pinski <pinskia@physics.uc.edu>
+2004-06-06 Stephane Carrez <stcarrez@nerim.fr>
- PR optimization/11368
- * doc/invoke.texi (-falign-functions): Document that
- when n is zero then a machine-dependent default is used.
- (-falign-labels): Document that when n is zero then a
- machine-dependent default is used and that -falign-labels =1
- is equivalent to -fno-align-labels.
- (-falign-loops): Likewise.
- (-falign-jumps): Likewise.
+ PR target/14457
+ * config/m68hc11/m68hc11.c (splitable_operand): New predicate.
+ * config/m68hc11/m68hc11-protos.h (splitable_operand): Declare.
+ * config/m68hc11/m68hc11.h (PREDICATE_CODES): Register it.
+ (inhibit_libc): Must define.
+ * config/m68hc11/m68hc11.md ("movhi_const0"): Use splitable_operand.
+ ("*andhi3_gen", "iorhi3", "*iorhi3_gen"): Likewise.
+ ("xorhi3"): Likewise.
-2003-07-07 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
- Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-06-05 David S. Miller <davem@nuts.davemloft.net>
- PR optimization/11198
- * alias.c (objects_must_conflict_p): Return 1 if the types have
- the same alias set, not if the alias sets only conflict.
+ * config/sparc/linux.h (TARGET_C99_FUNCTIONS): Set.
+ * config/sparc/linux64.h (TARGET_C99_FUNCTIONS): Likewise.
-2003-07-06 Matthias Klose <doko@debian.org>
+2004-06-04 Eric Christopher <echristo@redhat.com>
Backport from mainline:
+ 2004-06-02 Eric Christopher <echristo@redhat.com>
- 2003-07-04 Zack Weinberg <zack@codesourcery.com>
-
- * doc/extend.texi: Delete entire section on multiline strings.
-
-2003-07-04 H.J. Lu <hongjiu.lu@intel.com>
+ * c-typeck.c (common_type): Don't lose type qualifiers
+ when creating new variants.
- * Makefile.in: Replace PWD with PWD_COMMAND.
+2004-06-03 Bernardo Innocenti <bernie@develer.com>
-2003-07-03 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR optimization/11304
+ PR target/15782
Backport from mainline:
- 2003-04-18 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * cfgcleanup.c (flow_find_cross_jump): Use INSN_P, not active_insn_p.
+ 2004-06-01 Peter Barada <peter@the-baradas.com>
+ Peter Jakubek <peter@laseranimation.com>
-2003-07-03 Roger Sayle <roger@eyesopen.com>
+ * config/m68k/m68k.c(m68k_output_mi_thunk): For ColdFire, use %d0 as
+ a scratch to perform an add to memory.
- PR target/10700
- * fold-const.c (extract_muldiv_1): There's nothing that can be done
- if the expression is a SAVE_EXPR.
+2004-06-01 Paul Eggert <eggert@cs.ucla.edu>
-2003-07-03 Eric Botcazou <ebotcazou@libertysurf.fr>
+ PR target/15626
+ * doc/install.texi (sparc-sun-solaris2*): Document messages issued
+ by the Sun linker in conjunction with the Sun assembler.
+ (sparc-sun-solaris2.7): Update revision info for Sun patch 106950.
- PR optimization/11381
- * simplify-rtx.c (simplify_relational_operation): Check that
- two equal operands have no side-effects before simplifying
- the comparison.
+2004-06-01 Nicola Pero <nicola@brainstorm.co.uk>
-2003-07-01 Zack Weinberg <zack@codesourcery.com>
+ PR objc/7993
+ * objc-act.c (is_private): Do not emit the 'instance variable %s
+ is declared private' error.
+ (is_public): Emit the error after calling is_private.
+ (lookup_objc_ivar): If the instance variable is private, return 0
+ - the instance variable is invisible here.
- PR 2873
- * fixinc/inclhack.def (avoid_wchar_t_type): Add bypass
- expressions to prevent triggering on recent curses.h,
- linux/nls.h, or X11/Xlib.h.
- (stdio_va_list): Add _G_va_list to bypass pattern.
- (strict_ansi_not): Add bypass pattern for __SCO_VERSION__.
- * fixinc/fixincl.x: Regenerate.
+2004-06-01 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-07-02 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
-
- * fixinc/inclhack.def (irix_stdio_va_list): Apply to IRIX 6.5
- <internal/stdio_core.h> too.
- (stdio_va_list): Apply to IRIX 6.5 <internal/stdio_core.h> and
- <internal/wchar_core.h> too.
- Substitute va_list uses in inline definition.
- * fixinc/fixincl.x: Regenerate.
+ * doc/invoke.texi (-static-libgcc): Explicitly mention
+ non-GNU linkers.
-2003-07-01 Richard Henderson <rth@redhat.com>
- (blame to: Loren James Rittle <ljrittle@acm.org>)
+2004-05-31 Kaz Kojima <kkojima@gcc.gnu.org>
- * real.h (ieee_extended_intel_96_round_53_format): New.
- * real.c (ieee_extended_intel_96_round_53_format): New.
- * config/i386/freebsd.h (SUBTARGET_OVERRIDE_OPTIONS): Use it
- for XFmode and TFmode.
-
-2003-07-01 Kazu Hirata <kazu@cs.umass.edu>
-
- * doc/contrib.texi: Fix typos.
- * doc/sourcebuild.texi: Likewise.
-
-2003-06-27 Gunther Nikl <gni@gecko.de>
-
- PR target/11014
- * config/m68k/m68k.c (m68k_output_mi_thunk): Use correct assembly
- syntax for MIT / MOTOROLA.
-
-2003-06-27 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.h (SECONDARY_OUTPUT_RELOAD_CLASS): Define.
- * config/s390/s390.c (s390_secondary_output_reload_class): New function.
- * config/s390/s390-protos.h (s390_secondary_output_reload_class):
- Declare it.
- * config/s390/s390.md ("reload_outti", "reload_outdi",
- "reload_outdf"): New expanders.
-
- * config/s390/s390.md ("movti" + splitters): Handle non-offsettable
- memory operands as source.
- ("movdi" + splitters): Likewise.
- ("movdf" + splitters): Likewise.
- * config/s390/s390.c (s390_split_ok_p): New function.
- * config/s390/s390-protos.h (s390_split_ok_p): Declare it.
+ PR target/13250
+ Backport from mainline:
-2003-06-27 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+ 2004-05-28 Kaz Kojima <kkojima@gcc.gnu.org>
+ * config/sh/sh.md (rotlsi3): Use emit_move_insn.
- * config/mips/mips.md (trap): Use break 0 when !TARGET_GAS.
+2004-05-31 H.J. Lu <hongjiu.lu@intel.com>
- * config/mips/iris6-o32.h (MIPS_ISA_DEFAULT): Remove.
- (MIPS_CPU_STRING_DEFAULT): Redefine to mips2.
+ PR middle-end/15666
+ * cgraph.c (cgraph_remove_node): Don't call htab_clear_slot if
+ we can't find the slot. Abort if we can't find slot and the
+ node isn't for a builtin function.
- * config/mips/mips.c (TARGET_ASM_UNALIGNED_DI_OP) [TARGET_IRIX5 &&
- !TARGET_IRIX6]: Define as NULL.
+2004-05-31 Roger Sayle <roger@eyesopen.com>
- * config/mips/iris5gas.h (MDEBUG_ASM_SPEC): Override to match
- DWARF 2 default.
+ PR middle-end/15069
+ * fold-const.c (fold_single_bit_test): Only perform "(X & C) != 0"
+ into "X < 0" (where C is the signbit) if X's type is a full mode.
- * config/mips/dbxmdebug.h: New file.
- * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix5*): Use it with
- gas and --with-stabs.
+2004-05-31 Joseph S. Myers <jsm@polyomino.org.uk>
-2003-06-27 Andreas Schwab <schwab@suse.de>
+ PR c/15749
+ * c-decl.c (grokdeclarator, finish_struct): Don't pedwarn for
+ misuses of structures with flexible array members if
+ in_system_header.
- * config.gcc (m68k-*-linux*): Don't override extra_parts and
- gnu_ld, use the generic *-*-linux* settings instead.
+2004-05-31 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-06-26 Roger Sayle <roger@eyesopen.com>
+ PR target/15693
+ * config/sparc/sparc.c (compare_operand): New predicate.
+ * config/sparc/sparc.h (PREDICATE_CODES): Add it.
+ * config/sparc/sparc.md (cmpsi expander): Use it. If the first
+ operand is a ZERO_EXTRACT and the second operand is not zero,
+ force the former to a register.
+ (cmpdi expander): Likewise.
- PR optimization/11054
- * rtlanal.c (reg_overlap_mentioned_p): Handle ZERO_EXTRACT
- and SIGN_EXTRACT.
+2004-05-31 Danny Smith <dannysmith@users.sourceforge.net>
-2003-06-25 Zack Weinberg <zack@codesourcery.com>
+ * c-incpath.c (add_path): Canonicalize paths to use '/' if
+ HAVE_DOS_BASED_FILESYSTEM.
- PR bootstrap/3163
- * aclocal.m4 (AC_FUNC_MMAP_ANYWHERE, AC_FUNC_MMAP_FILE): Delete.
- (gcc_AC_FUNC_MMAP_BLACKLIST): New.
- * configure.in: Check for sys/mman.h and mmap in AC_CHECK_HEADERS
- and AC_CHECK_FUNCS lists, respectively. Use
- gcc_AC_FUNC_MMAP_BLACKLIST, not AC_FUNC_MMAP_ANYWHERE nor
- AC_FUNC_MMAP_FILE.
- * configure, config.in: Regenerate.
+2004-05-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
- * ggc-page.c (init_gcc): Call fatal_io_error, not abort,
- if opening /dev/zero fails.
+ PR bootstrap/14671
+ * alias.c (init_alias_analysis): Allocate alias_invariant array with
+ ggc_calloc instead of xrealloc.
+ (end_alias_analysis): Don't free alias_invariant.
-2003-06-25 Roger Sayle <roger@eyesopen.com>
+2004-05-28 DJ Delorie <dj@redhat.com>
- * builtins.c (expand_builtin_strcpy): Construct new argument list
- manually instead of using chainon to modify the original arglist.
- (expand_builtin_strcmp): Likewise.
+ * stor-layout.c (place_field): Revert erroneous commit.
-2003-06-25 David O'Brien <obrien@FreeBSD.org>
+2004-05-28 Nick Clifton <nickc@redhat.com>
- * config/i386/i386.h (builtin_define): Remove duplicate __amd64
- and __amd64__.
+ Bug 14093
+ * config/sh/sh-protos.h (sh_promote_prototypes): Declare.
+ * config/sh/sh.c (sh_promote_prototypes): Remove declaration.
+ Delete static from definition.
+ * config/sh/sh.h (FUNCTION_VALUE): Add sh_promote_prototypes call.
-2003-06-25 Dhananjay Deshpande <dhananjayd@kpitcummins.com>
+2004-05-27 Kaz Kojima <kkojima@gcc.gnu.org>
- * config/sh/sh.c (sh_register_move_cost):
- Add case for moving between MAC_REGS.
+ Backport from mainline:
-2003-06-24 Jerry Quinn <jlquinn@optonline.net>
+ * config/sh/t-linux (SHLIB_MAPFILES): Use sh specific
+ libgcc-std.ver.
+ * config/sh/libgcc-std.ver: New file.
- PR other/11280
- * gcc/doc/invoke.texi (Optimization Options): Remove -Os from
- -freorder-functions description.
+2004-05-27 Olivier Hainque <hainque@act-europe.fr>
-2003-06-25 Richard Sandiford <rsandifo@redhat.com>
+ * expr.c (store_constructor): Restore sanity check on
+ the size of the type before clearing.
- PR target/11084
- * config/mips/mips.c (mips_expand_prologue): Fix setting of regno
- for the end of a variable argument list.
+2004-05-27 Alan Modra <amodra@bigpond.net.au>
-2003-06-25 Josef Zlomek <zlomekj@suse.cz>
+ PR target/14478
+ * config/rs6000/rs6000.c (reg_or_neg_short_operand): Don't allow zero.
- * dwarf2out.c (gen_field_die): Return if type of decl is error mark.
+2004-05-26 Aldy Hernandez <aldyh@redhat.com>
-2003-06-24 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+ PR/14924
+ * config/rs6000/rs6000.c (spe_expand_stv_builtin): New.
- PR target/11260
- * config/alpha/alpha.md (sqrtdf2): Fix operand substitution.
+2004-05-23 Joseph S. Myers <jsm@polyomino.org.uk>
-2003-06-24 Jakub Jelinek <jakub@redhat.com>
+ * doc/gcc.texi, doc/gccint.texi, doc/include/gcc-common.texi:
+ Update based on printed manual. Enable setting of offsets for
+ FSFPRINT and move it to gcc-common.texi.
+ * doc/gcc.texi: Update FSF printing details.
+ * doc/gccint.texi: Remove FSF printing details.
- * builtins.c (expand_builtin_strcpy): Don't evaluate side-effects in
- src twice.
+2004-05-21 Jakub Jelinek <jakub@redhat.com>
-2003-06-23 Jakub Jelinek <jakub@redhat.com>
+ * config/sparc/linux64.h (OPTION_DEFAULT_SPECS): If SPARC_BI_ARCH,
+ override sparc.h definition.
- * config/s390/s390.c (s390_output_mi_thunk): Avoid .plt in -m31
- mode, as it requires pic register loaded.
+2004-05-20 Jakub Jelinek <jakub@redhat.com>
-2003-06-23 Kazu Hirata <kazu@cs.umass.edu>
+ * config/sparc/linux64.h (TARGET_DEFAULT): Make 64-bit by default
+ also for TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3.
- * doc/extend.texi: Fix typos.
- * doc/md.texi: Likewise.
+2004-05-18 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-2003-06-23 Roger Sayle <roger@eyesopen.com>
- Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+ PR target/15202
+ * pa.md (movdi, movsi, movhi, movqi): Support move from shift amount
+ register to general register for DI, SI, HI and QI modes. Remove
+ move to shift amount register in DF mode.
- * doc/contrib.texi (Contributors): Add a note on testing and
- remove duplicates from testers list.
+2004-05-18 Ulrich Weigand <uweigand@de.ibm.com>
-2003-06-23 Kazu Hirata <kazu@cs.umass.edu>
+ PR middle-end/15054
+ * expr.c (expand_expr_real): Do not call preserve_temp_slots
+ on a TARGET_EXPR temp.
+ * function.c (assign_stack_temp_for_type): Set 'keep' flag for
+ TARGET_EXPR temp slots.
- * doc/invoke.texi: Document dump options, dT and dW.
+2004-05-18 Kaz Kojima <kkojima@gcc.gnu.org>
-2003-06-23 Andreas Schwab <schwab@suse.de>
+ PR optimization/15100
+ Backport from mainline:
- * doc/invoke.texi: Remove leading `-' from options in index.
+ 2004-05-11 Kaz Kojima <kkojima@gcc.gnu.org>
+ * combine.c (distribute_notes): Don't create a dangling
+ REG_LIBCALL/REG_RETVAL note.
-2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
+2004-05-17 H.J. Lu <hongjiu.lu@intel.com>
- * doc/invoke.texi: Document dump, .cfg.
+ Backport from mainline
-2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
+ PR target/15301
+ PR target/15302
+ 2004-05-17 Jan Hubicka <jh@suse.cz>
- * doc/invoke.texi: Alphabetize dump options.
+ * i386.c (construct_container): Do not produce BLKmode registers.
+ (classify_argument): Properly compute alignment of complex types.
-2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
+2004-05-15 Joseph S. Myers <jsm@polyomino.org.uk>
- * doc/invoke.texi: Remove a duplicate -dk.
+ * doc/extend.texi: Update WG14 URL.
-2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
+2004-05-11 Aldy Hernandez <aldyh@redhat.com>
- * doc/rtl.texi: Fix the @findex for pre_modify.
+ * config/rs6000/spe.md (spe_evneg): Rename to negv2si2.
-Sat Jun 21 13:37:52 CEST 2003 Jan Hubicka <jh@suse.cz>
+ * config/rs6000/rs6000.c (bdesc_1arg): Change spe_evneg to
+ negv2si2.
- * i386.c (ix86_va_arg): Fix allocation of temporary slot.
+2004-05-10 Kaz Kojima <kkojima@gcc.gnu.org>
-2003-06-21 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+ PR target/15130
+ Backport from mainline:
- * doc/contrib.texi (Contributors): Use Windows instead of Win32.
+ * config/sh/sh-protos.h (sh_expand_epilogue): Change prototype.
+ * config/sh/sh.c (output_stack_adjust): Take the sibcall epilogue
+ into account. Compute the correct number of general registers
+ for the return value. Generate a special push/pop sequence when
+ failing to get a temporary register for non SHmedia epilogue.
+ (sh_expand_epilogue): Add an argument to show whether it's for
+ sibcall or not. Set the 3rd argument of output_stack_adjust to
+ -1 if needed.
+ (sh_need_epilogue): Call sh_expand_epilogue with 0.
+ * config/sh/sh.md (sibcall_epilogue): Call sh_expand_epilogue
+ with 1.
+ (epilogue): Call sh_expand_epilogue with 0.
- Update Andreas Jaeger's entry.
+2004-05-09 Aldy Hernandez <aldyh@redhat.com>
- Merge the two entries of Kaveh Ghazi, David Edelsohn, and
- Loren J. Rittle.
+ * config/rs6000/spe.md ("tstsflt_gpr"): Fix typo in unspec.
-2003-06-20 Geoffrey Keating <geoffk@apple.com>
+2004-05-08 Eric Botcazou <ebotcazou@libertysurf.fr>
- PR c++/9393
- * doc/invoke.texi (Debugging Options): Document -frandom-seed.
- * configure.in: Check for gettimeofday.
- * tree.c (flag_random_seed): Define.
- (default_flag_random_seed): New.
- (append_random_chars): Use flag_random_seed rather than trying
- to acquire randomness here.
- * tree.h (default_flag_random_seed): Declare.
- * toplev.c (display_help): Add -frandom-seed and -fstack-limit-*
- descriptions.
- (decode_f_option): Handle -frandom-seed.
- (print_switch_values): Call default_flag_random_seed.
- * flags.h (flag_random_seed): Declare.
- * configure: Regenerate.
- * config.in: Regenerate.
+ * doc/install.texi (sparc-sun-solaris2*): Document bootstrap
+ problems with earlier versions of the GNU compiler.
-2003-06-20 Mark Mitchell <mark@codesourcery.com>
+2004-05-07 Eric Botcazou <ebotcazou@libertysurf.fr>
- PR c++/10888
- * tree-inline.c (expand_call_inline): Do not warn about failing to
- inline functions declared in system headers.
- * doc/invoke.texi (-Winline): Expand on documentation.
+ PR c++/14962
+ * c-pragma.c (handle_pragma_redefine_extname): Only change
+ the assembler name of FUNCTION_DECLs and VAR_DECLs.
-2003-06-20 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+2004-05-07 Loren James Rittle <ljrittle@acm.org>
- * configure.in (gcc_cv_as_gstabs_flag): Disable if assembler warns.
- * configure: Regenerate.
- Fixes PR driver/9362.
+ * config/alpha/freebsd.h (SUBTARGET_EXTRA_SPECS): Proper redefinition.
+ * config/arm/freebsd.h: Likewise.
+ * config/ia64/freebsd.h: Likewise.
+ * config/sparc/freebsd.h: Likewise.
-2003-06-19 Vladimir Makarov <vmakarov@redhat.com>
+2004-05-06 Richard Henderson <rth@redhat.com>
- * haifa-sched.c (max_isse): Backport from the mainline.
- (choice_entry): New structure.
- (choice_stack, cycle_issued_insns, max_lookahead_tries,
- cached_first_cycle_multipass_dfa_lookahead, cached_issue_rate):
- New variables.
- (choose_ready): Calculate max_lookahead_tries. Initiate
- ready_try.
- (schedule_block): Allocate/deallocate choice_stack. Change
- cycle_issued_insns value as necessary.
- (sched_init): Check cached_issue_rate.
+ * stmt.c (parse_output_constraint): Don't warn for read-write
+ memory operand.
-2003-06-20 Daniel Egger <degger@fhm.edu>
- Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+2004-05-06 Jan Hubicka <jh@suse.cz>
- * doc/install.texi (Building): Correct and improve statement
- about parallel builds.
+ PR c/15004
+ * function.c (do_warn_unused_parameter): Break out form ...
+ (expand_function_end): ... here; warn only when not using cgraphunit.
+ * function.h (do_warn_unused_parameter): Declare.
+ * cgraphunit.c: Include function.h.
+ (cgraph_finalize_function): Do unused parameter warning.
+ * Makefile.in (cgraphunit.o): Depend on function.h
-2003-06-20 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-05-05 H.J. Lu <hongjiu.lu@intel.com>
- * doc/install.texi (--with-gnu-as): Mention SPARC/Solaris and
- SPARC64/Solaris as platforms where --with-gnu-as makes a difference.
- (--with-as): Add @anchor.
- (--with-gnu-ld): Fix typo.
- (--with-ld): Add @uref to --with-as.
+ PR target/15290
+ * config/i386/i386.c (ix86_split_to_parts): Use real_to_target
+ instead of REAL_VALUE_TO_TARGET_LONG_DOUBLE.
-2003-06-19 Kazu Hirata <kazu@cs.umass.edu>
+2004-05-03 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- * flow.c (initialize_uninitialized_subregs): Use
- emit_move_insn instead of emitting a hardcoded move.
+ * fixinc/inclhack.def (svr4_profil): Don't apply on IRIX 5/6.
+ * fixinc/fixincl.x: Regenerate.
-2003-06-19 David Edelsohn <edelsohn@gnu.org>
+2004-05-02 Josef Zlomek <zlomekj@suse.cz>
- * config/rs6000/rs6000.c (init_cumulative_args): Limit CALL_LIBCALL
- to ABI_V4.
+ * cfgrtl.c (cfg_layout_redirect_edge_and_branch): Print the debug
+ message before redirecting the edge.
-2003-06-19 DJ Delorie <dj@redhat.com>
+2004-05-02 Eric Botcazou <ebotcazou@libertysurf.fr>
- PR preprocessor/11022
- * cppmacro.c (warn_of_redefinition): Handle cases where the two
- definitions have different numbers of tokens.
+ PR optimization/15112
+ * reload1.c (reload): Don't record unchanging memory locations.
-2003-06-18 Richard Henderson <rth@redhat.com>
+2004-04-30 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- * config/ia64/unwind-ia64.c (_Unwind_GetCFA): New.
- (_Unwind_FindEnclosingFunction): Implement.
+ PR other/1963
+ * config/alpha/osf.h (SWITCHES_NEED_SPACES): Define.
-2003-06-18 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+2004-04-30 David Edelsohn <edelsohn@gnu.org>
- * config/rs6000/rs6000.c (init_cumulative_args): Add and handle LIBCALL
- argument.
- (function_arg): Handle CALL_LIBCALL flag.
- * config/rs6000/rs6000-protos.h (init_cumulative_args): Update
- prototype.
- * config/rs6000/rs6000.h (CALL_LIBCALL): New macro.
- (INIT_CUMULATIVE_LIBCALL_ARGS): New macro.
- (INIT_CUMULATIVE_ARGS): Add LIBCALL argument.
- (INIT_CUMULATIVE_INCOMING_ARGS): Likewise.
+ Backport from mainline:
-2003-06-17 Jason Merrill <jason@redhat.com>
+ 2004-04-19 David Edelsohn <edelsohn@gnu.org>
- PR c++/10929
- * tree-inline.c (expand_call_inline): Don't warn about failing to
- inline a function which was made inline by -finline-functions.
+ * doc/install.texi (*-ibm-aix*): Add AIX 5.1 assembler and archiver
+ fix information.
+
+ 2004-04-17 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/14715
+ * config/rs6000/rs6000.c (rs6000_stack_info): Make parm_size agree
+ with STARTING_FRAME_OFFSET.
+
+ 2004-04-07 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (processor_target_table): Add MASK_MFCRF
+ to power4 and power5 entries.
+
+ 2004-04-05 David Edelsohn
+
+ * config/rs6000/rs6000.c (VTABLE_NAME_P): Add _ZTI to special
+ symbol handling.
+
+ 2004-03-30 Hartmut Penner <hpenner@de.ibm.com>
+
+ PR 11591
+ * config/rs6000/rs6000.c (rs6000_legitimate_address):
+ Allow any offset to argument pointer in no-strict case.
+
+ 2004-03-25 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_always_hint): New variable.
+ (rs6000_sched_groups): New variable.
+ (processor_target_table): Add power5.
+ (rs6000_override_options): Set rs6000_sched_insert_nops,
+ rs6000_sched_costly_dep and rs6000_sched_restricted_insns_priority
+ from rs6000_sched_groups.
+ (output_cbranch): Use rs6000_always_hint.
+ (rs6000_variable_issue): Use rs6000_sched_groups.
+ (rs6000_adjust_cost): Add CPU_POWER5.
+ (is_microcoded_insn): Use rs6000_sched_groups.
+ (is_dispatch_slot_restricted): Use rs6000_sched_groups.
+ Return 2 for POWER5 cracked instructions.
+ (is_cracked_insn): Use rs6000_sched_groups.
+ (is_branch_slot_insn): Use rs6000_sched_groups.
+ (rs6000_issue_rate): Add CPU_POWER5.
+ (rs6000_sched_finish): Use rs6000_sched_groups.
+ (rs6000_rtx_costs): Add PROCESSOR_POWER5.
+ * config/rs6000/rs6000.h (processor_type): Add PROCESSOR_POWER5.
+ (DEFAULT_SCHED_COSTLY_DEP): Delete.
+ (DEFAULT_RESTRICTED_INSNS_PRIORITY): Delete.
+ (DEFAULT_SCHED_FINISH_NOP_INSERTION_SCHEME): Delete.
+ * config/rs6000/rs6000.md (define_attr "cpu"): Add power5.
+ * config/rs6000/power5.md: New file.
+ * doc/invoke.texi: Add power5 option.
+
+ 2004-03-17 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_stack_info): correct reg_size
+ for mixed mode.
+ (rs6000_emit_prologue): Ditto.
+ (rs6000_emit_epilogue): Ditto.
+ * config/rs6000/rs6000.h: Definition of DWARF_CIE_DATA_ALIGNMENT
+ macro for mixed mode.
+
+ 2004-03-04 David Edelsohn <edelsohn@gnu.org>
+ GP <gp@qnx.com>
-2003-06-17 Ranjit Mathew <rmathew@hotmail.com>
+ * config/rs6000/rs6000.c (output_function_profiler): Append @plt
+ when compiling PIC.
- * install.texi (Testing): Add information on how to run Java
- runtime tests separately.
+2004-04-30 Paolo Bonzini <bonzini@gnu.org>
+
+ * config/altivec/altivec.h [__cplusplus] (vec_subsubs): Rename
+ to vec_sububs.
+ [__cplusplus] (vec_subsuhs): Rename to vec_subuhs,
+ eliminating duplicates.
-2003-06-17 Christopher Faylor <cgf@redhat.com>
+2004-04-29 Richard Sandiford <rsandifo@redhat.com>
- * doc/install.texi: Add msvc rebuild caveat.
+ PR target/15189
+ * config/mips/mips.md (load_df_low): Use default length.
+ (load_df_high, store_df_high): Likewise.
-2003-06-17 Kazu Hirata <kazu@cs.umass.edu>
+2004-04-29 Philip Blundell <philb@gnu.org>
- * doc/contrib.texi: Replace Hitachi with Renesas.
- * doc/install.texi: Likewise.
- * doc/invoke.texi: Likewise.
+ * Merge from trunk:
+ 2004-04-20 Paul Brook <paul@codesourcery.com>
-2003-06-17 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+ * config/arm/arm.c (arm_legitimate_address_p): Use rtx_equal_p.
- * config/rs6000/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Partly revert
- 2003-01-23 patch. Corrected to handle kernels with changed ucontext.
+2004-04-29 Aldy Hernandez <aldyh@redhat.com>
- * config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Error on invalid
- -msdata=eabi usages.
+ PR/12028
+ * config/rs6000/rs6000.c (rs6000_emit_cmove): Disable comparisons
+ of floats on the E500.
+ (branch_positive_comparison_operator): Do not allow NE even on the
+ E500.
+ (ccr_bit): Remove E500 specific code.
+ Remove miscompilation warning for e500.
+ (print_operand): Add 'c' and 'D'.
+ (rs6000_generate_compare): Rewrite to generate correct rtl.
+ (rs6000_emit_sCOND): Handle E500.
+ (output_cbranch): Adjust for changes in rs6000_generate_compare.
+ (output_e500_flip_gt_bit): New.
+ (rs6000_override_options): Error when user wants altivec and e500
+ instructions.
+
+ * config/rs6000/rs6000.md (UNSPEC_MV_CR_GT): New constant.
+ (move_from_CR_gt_bit): New.
+ (cceq_ior_compare): Name previously unnamed pattern. Disable for
+ E500.
+ (cceq_rev_compare): Name previously unnamed pattern. Allow for
+ E500.
+
+ * config/rs6000/spe.md (cmpsfeq_gpr): Rewrite as unspec.
+ (tstsfeq_gpr): Same.
+ (cmpsfgt_gpr): Same.
+ (tstsfgt_gpr): Same.
+ (cmpsflt_gpr): Same.
+ (tstsflt_gpr): Same.
+ (e500_cceq_ior_compare): New.
+ (e500_flip_gt_bit): New.
+
+ * config/rs6000/rs6000-protos.h (output_e500_flip_gt_bit):
+ Protoize.
+
+2004-04-28 Ben Elliston <bje@au.ibm.com>
+
+ * doc/invoke.texi (Objective-C Dialect Options): Don't prefix
+ options with "-" in the option index.
+ (SPARC Options): Likewise.
+ (M32R/D Options): Likewise.
+
+2004-04-28 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Makefile.in ($(DESTDIR)$(infodir)/%.info): Don't condition
+ calling install-info on $(DESTDIR)$(infodir)/dir already being
+ present.
+
+2004-04-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/15084
+ * config/i386/i386.md (*movsi_insv_1_rex64): Changed to DImode
+ and renamed to movdi_insv_1_rex64.
+ (insv): Support SImode for 32bit and DImode for 64bit.
+
+2004-04-27 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-2003-06-14 Richard Earnshaw <rearnsha@arm.com>
+ PR debug/14829
+ * dwarf2out.c (reg_number): Rename to dbx_reg_number. Adjust all
+ callers.
+ (multiple_reg_loc_descriptor, reg_loc_descriptor): Use gcc register
+ number for indexing hard_regno_nregs array.
- PR optimization/10842
- From trunk:
- 2003-01-20 Nick Clifton <nickc@redhat.com>
+2004-04-27 Bob Wilson <bob.wilson@acm.org>
- * config/arm/arm.md (sibcall_epilogue): Add an
- UNSPEC_PROLOGUE_USE to prevent the link register from being
- considered dead.
+ * config/xtensa/xtensa.c (call_insn_operand): Check
+ SYMBOL_REF_EXTERNAL_P in addition to SYMBOL_REF_LOCAL_P.
+ * config/xtensa/xtensa.h (LEGITIMATE_PIC_OPERAND): Likewise.
+ * config/xtensa/xtensa.md (call, call_value): Likewise.
- 2003-02-02 Richard Earnshaw <rearnsha@arm.com>
+2004-04-26 Zack Weinberg <zack@codesourcery.com>
- * arm.md (sibcall_epilogue): Set the "conds" to "clob".
- (epilogue_insns): Likewise.
+ * config/ia64/hpux.h: Predefine __STDCPP__ when compiling C++.
+ * config/pa/pa-hpux10.h: Likewise.
+ * config/pa/pa-hpux11.h: Likewise.
-2003-06-14 Richard Earnshaw <rearnsha@arm.com>
+2004-04-23 Eric Botcazou <ebotcazou@libertysurf.fr>
- PR target/11183
- * arm.c (output_move_double): Pass SImode to adjust_address.
+ PR optimization/13985
+ * cfgloopmanip.c (fix_loop_placements): New prototype.
+ Call fix_bb_placements on the preheader of loops that have
+ been reparented.
+ (remove_path): Adjust call to fix_loop_placements.
-2003-06-13 Janis Johnson <janis187@us.ibm.com>
+2004-04-23 Nick Clifton <nickc@redhat.com>
- * doc/install.texi (m32r-*-elf): Change company to Renesas.
+ * Import this patch from mainline:
+ 2004-04-16 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
-2003-06-13 Richard Earnshaw <rearnsha@arm.com>
+ * config/m32r/m32r.h (BIG_ENDIAN_BIT): Deleted to fix endian
+ bug.
+ (TARGET_LITTLE_ENDIAN, TARGET_BIG_ENDIAN,
+ TARGET_DEFAULT): Changed. Ditto.
+ (LITTLE_ENDIAN_BIT, TARGET_CPU_DEFAULT,
+ TARGET_ENDIAN_DEFAULT): Added. Ditto.
+ * config/m32r/little.h (TARGET_LITTLE_ENDIAN): Deleted.
+ (TARGET_ENDIAN_DEFAULT): Added.
- * arm.c (output_call_mem): If the address references the link-register
- use an instruction sequence that avoids early-clobbering IP.
- (eliminate_lr2ip): Delete.
+2004-04-22 Per Bothner <per@bothner.com>
-2003-06-12 Richard Henderson <rth@redhat.com>
+ * cppinit.c (cpp_read_main_file): Return NULL rather than false.
+ Fixes PR preprocessor/15067.
- PR target/11089
- * config/i386/i386.md (sse_movaps): Use an expander to force
- one operand to be a register.
- (sse_movups): Likewise.
+2004-04-22 Ulrich Weigand <uweigand@de.ibm.com>
-2003-06-12 Richard Henderson <rth@redhat.com>
+ * function.c (thread_prologue_and_epilogue): Move
+ NOTE_INSN_FUNCTION_END and NOTE_INSN_FUNCTION_BEG notes
+ before the epilogue.
- PR middle-end/10557
- * rtlanal.c (subreg_offset_representable_p): Relax subreg check.
+2004-04-22 Ulrich Weigand <uweigand@de.ibm.com>
-2003-06-13 Eric Botcazou <ebotcazou@libertysurf.fr>
- Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
+ * dbxout.c (dbxout_symbol_location): Do not output references
+ to optimized-out constant pool symbols.
- PR target/10142
- * config/sparc/sparc.c (function_arg_record_value_parms): Add
- new 'stack' field.
- (function_arg_record_value_1): Set 'stack' to 1 if we run out of
- integer slots for an integer field.
- (function_arg_record_value_3): Shift vector index.
- (function_arg_record_value_2): Likewise.
- (function_arg_record_value): Initialize 'stack' to 0.
- Set 'stack' to 1 if we run out of integer slots for an integer field.
- Generate (parallel [(expr_list (nil) ...) ...]) if 'stack' is set to 1.
+2004-04-22 Ulrich Weigand <uweigand@de.ibm.com>
-2003-06-13 Eric Botcazou <ebotcazou@libertysurf.fr>
+ * expr.c (store_constructor): Use gen_int_mode to correctly
+ sign-extend CONST_INT value.
- PR optimization/10955
- * unroll.c (unroll_loop): Fix off-by-one bug.
+2004-04-22 Ulrich Weigand <uweigand@de.ibm.com>
-2003-06-12 Richard Henderson <rth@redhat.com>
+ * combine.c (if_then_else_cond): Check for NULL return value of
+ simplify_gen_subreg.
- PR middle-end/10475
- * expmed.c (emit_store_flag): Use simplify_gen_subreg directly
- for extracting sub-words.
+2004-04-22 Ulrich Weigand <uweigand@de.ibm.com>
-2003-06-12 Richard Henderson <rth@redhat.com>
+ * reload1.c (emit_reload_insns): Set reg_has_output_reload to one
+ after setting reg_last_reload_reg for optional output reloads.
- PR target/7594
- * config/m68k/m68k.md (zero_extendhisi2): Use gen_lowpart_SUBREG.
- (zero_extendqihi2, zero_extendqisi2): Likewise.
+2004-04-22 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-2003-06-12 Richard Henderson <rth@redhat.com>
+ * pa64-regs.h (DBX_REGISTER_NUMBER): Simplify and correct mapping of
+ SAR register. Fix comment.
+ (ADDITIONAL_REGISTER_NAMES): Correct register number of SAR register
+ (%cr11).
- PR inline-asm/4823
- * reg-stack.c (any_malformed_asm): New.
- (check_asm_stack_operands): Set it.
- (convert_regs_1): Check it before aborting.
+2004-04-21 Kaz Kojima <kkojima@gcc.gnu.org>
-2003-06-12 Jakub Jelinek <jakub@redhat.com>
+ Backport from mainline:
- * c-decl.c (c_expand_body): Save input_filename and lineno,
- set it before tree inlining and restore before return.
+ 2004-04-05 Kaz Kojima <kkojima@gcc.gnu.org>
+ * config/sh/sh.c (prepare_move_operands): Use emit_call_insn
+ when the TLS address is generated by a function call.
+ * config/sh/sh.md (tls_global_dynamic): Use a call expression.
+ (tls_local_dynamic): Likewise.
-2003-06-12 Ulrich Weigand <uweigand@de.ibm.com>
+2004-04-21 H.J. Lu <hongjiu.lu@intel.com>
- * config/s390/s390.c (s390_emit_prologue): Use LA instead of AR
- to initialize GOT register.
+ PR target/14813
+ Backport from mainline:
-2003-06-12 Jakub Jelinek <jakub@redhat.com>
+ * config/ia64/crtend.asm: Move pointer to __do_global_ctors_aux
+ in .init_array section to ...
+ * config/ia64/crtbegin.asm: Here.
- * c-opts.c (complain_wrong_lang): Add on argument.
- Print no- switch if on is false.
- (c_common_decode_option): Adjust caller.
+ * config/ia64/crtend.asm: Mark __do_global_ctors_aux global
+ and hidden if HAVE_INITFINI_ARRAY is defined.
-2003-06-11 Richard Henderson <rth@redhat.com>
+2004-04-21 Richard Henderson <rth@redhat.com>
- * stmt.c (expand_asm_operands): Don't warn for memories with
- queued addresses.
+ PR bootstrap/14671
+ * alias.c (alias_invariant, alias_invariant_size): Mark GTY.
+ (reg_known_value, reg_known_value_size): Likewise; make static.
+ (reg_known_equiv_p): Make static.
+ (clear_reg_alias_info): Update for new indexing.
+ (get_reg_known_value, set_reg_known_value): New.
+ (get_reg_known_equiv_p, set_reg_known_equiv_p): New.
+ (canon_rtx): Use them.
+ (init_alias_analysis): Likewise. Allocate reg_known_value with gc.
+ Don't play queer offsetting games with reg_known_value and
+ reg_known_equiv_p.
+ (end_alias_analysis): Don't free reg_known_value.
+ * rtl.h (get_reg_known_value, get_reg_known_equiv_p): Declare.
+ * sched-deps.c (reg_known_equiv_p, reg_known_value): Remove.
+ (deps_may_trap_p, sched_analyze_1, sched_analyze_2): Use the new
+ functions instead.
-2003-06-11 Andrew Pinski <pinskia@physics.uc.edu>
+2004-04-21 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
- PR target/8787
- * config/i386/djgpp.h (ASM_FILE_START): emit `.intel_syntax'
- if -masm=intel.
+ * pa64-hpux.h (LIB_SPEC): Fix library specification used with GNU ld.
-2003-06-10 Andrew Haley <aph@redhat.com>
+2004-04-21 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- * langhooks-def.h (LANG_HOOKS_DECL_OK_FOR_SIBCALL): New.
- (LANG_HOOKS_DECLS): Add LANG_HOOKS_DECL_OK_FOR_SIBCALL.
- (lhd_decl_ok_for_sibcall): New.
- * langhooks.c (lhd_decl_ok_for_sibcall): New.
- * langhooks.h (lang_hooks_for_decls.ok_for_sibcall): New field.
- * calls.c (expand_call): Check lang_hook before generating a
- sibcall.
+ * doc/install.texi (Specific, mips-sgi-irix5): Fix IRIX 5.3 IDO
+ download URL.
-2003-06-09 Richard Henderson <rth@redhat.com>
+2004-04-21 H.J. Lu <hongjiu.lu@intel.com>
- 2003-05-11 Ulrich Weigand <uweigand@de.ibm.com>
- * except.c (EH_RETURN_STACKADJ_RTX): Do not define.
- (EH_RETURN_HANDLER_RTX): Likewise.
- (expand_builtin_eh_return): Do not copy stack adjustment
- if EH_RETURN_STACKADJ_RTX is not defined.
- (expand_eh_return): Likewise. Also, do not pass stack
- adjustment as argument to the eh_return pattern.
- * except.h (MUST_USE_SJLJ_EXCEPTIONS): Do not define just
- because EH_RETURN_STACKADJ_RTX is not defined.
- * unwind-dw.c (uw_update_context_1): If EH_RETURN_STACKADJ_RTX
- is not defined, treat stack pointer like a regular register.
- (uw_init_context_1): Set up fake initial stack pointer register.
- (uw_install_context_1): Do not compute stack adjustment if
- EH_RETURN_STACKADJ_RTX is not defined.
+ PR target/14857
+ Backport from mainline:
- * config/i386/i386.md ("eh_return"): Remove first argument.
- * config/mips/mips.md ("eh_return"): Likewise.
- * config/rs6000/rs6000.md ("eh_return"): Likewise.
- * config/sh/sh.md ("eh_return"): Likewise.
+ * config/ia64/ia64.c (ia64_encode_section_info): Don't prod
+ global register variables.
- * config/s390/s390.h (EH_RETURN_STACKADJ_RTX): Remove.
+2004-04-21 H.J. Lu <hongjiu.lu@intel.com>
-2003-06-08 Richard Henderson <rth@redhat.com>
+ * PR target/14723
+ Backport from mainline:
+ 2004-02-14 Jan Hubicka <jh@suse.cz>
- * stmt.c (expand_asm_operands): Re-word warning.
+ * config.gcc: Add support for nocona/prescott/pentium-m/pentium3m
+ /pentium4m.
+ * i386.c (override_options): Add support for new CPUs.
+ * i386.h (TARGET_CPU_DEFAULT_NAMES): New names.
+ (TARGET_CPU_DEFAULT_pentium_m, TARGET_CPU_DEFAULT_pentium4e): New
+ constants.
+ * invoke.texi: Extend documentation of -mtune/-march for new CPUs.
-2003-06-08 Richard Henderson <rth@redhat.com>
+2004-04-20 Mark Mitchell <mark@codesourcery.com>
- * expr.h (EXPAND_MEMORY): New.
- * expr.c (expand_expr): Check it.
- * stmt.c (expand_asm_operands): Provide it when the constraint
- requires a memory. Warn for memory input constraints without
- a memory operand.
+ * version.c (version_string): Mark as prerelease.
+ * doc/include/gcc-common.texi: Bump version number.
-2003-06-07 Richard Henderson <rth@redhat.com>
+2004-04-18 Release Manager
- * c-common.c (cb_register_builtins): Define __EXCEPTIONS for C also.
+ * GCC 3.4.0 released.
-2003-06-07 Kelley Cook <kelleycook@wideopenwest.com>
+2004-04-18 Alan Modra <amodra@bigpond.net.au>
- * configure.in (HAVE_LD_RO_RW_SECTION_MIXING): Remove quotes in
- section names.
+ PR bootstrap/14992
+ * configure.ac: Define HAVE_LD_AS_NEEDED only for linux.
* configure: Regenerate.
+ * gcc.c (init_gcc_specs): Revert earlier change.
-2003-06-07 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/linux64.h (CRT_CALL_STATIC_FUNCTION): Define.
-
-2003-06-06 James E Wilson <wilson@tuliptree.org>
-
- PR inline-asm/10890
- * reload1.c (merge_assigned_reloads): Abort only if two reloads have
- different in fields.
-
-2003-06-06 Richard Earnshaw <rearnsha@arm.com>
-
- PR target/11052
- * ifcvt.c (noce_process_if_block): Fail if the destination has
- side-effects.
-
-2003-06-06 Dan Kegel <dank@kegel.com>
- Kaz Kojima <kkojima@gcc.gnu.org>
-
- PR target/10331
- * config/sh/t-linux (STMP_FIXPROTO): Define.
-
- PR target/11096
- * config/sh/linux.h (CPLUSPLUS_CPP_SPEC): Redefine so to include
- -D_GNU_SOURCE.
-
-2003-06-05 David Miller <davem@redhat.com>
- Richard Henderson <rth@redhat.com>
+2004-04-18 Mark Mitchell <mark@codesourcery.com>
- * optabs.c (HAVE_conditional_trap): Provide default.
- (gen_conditional_trap): Likewise.
- (init_optabs): Merge init_traps.
- (gen_cond_trap): Use prepare_operand. Restructure and avoid ifdef.
+ PR other/14918
+ * doc/invoke.texi (-fprofile-generate): Document requirement to
+ use -fprofile-generate when linking.
-2003-06-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+ PR bootstrap/14992
+ * gcc.c (init_gcc_specs): Only honor HAVE_LD_AS_NEEDED on
+ GNU/Linux.
- * doc/md.texi (Machine Constraints): Correct the meaning of
- constraints related to floating-point registers on SPARC.
+ * doc/extend.texi (Strong Using): Warn users against using this
+ feature.
-2003-06-05 Eric Botcazou <ebotcazou@libertysurf.fr>
- Paolo Bonzini <bonzini@gnu.org>
+2004-04-17 Richard Sandiford <rsandifo@redhat.com>
- PR target/10663
- * configure.in (HAVE_LD_RO_RW_SECTION_MIXING): Redirect
- assembler and linker output to /dev/null.
- Use a 'sed' construct instead of 'grep -A1'.
+ * configure.ac (gcc_cv_ld_as_needed): Use AC_CACHE_CHECK.
* configure: Regenerate.
-2003-06-04 David Edelsohn <edelsohn@gnu.org>
-
- * doc/install.texi (*-ibm-aix*): Native as and ld required
- to bootstrap on AIX 5L.
-
-2003-06-04 Richard Henderson <rth@redhat.com>
-
- * c-common.c (handle_cleanup_attribute): New.
- (c_common_attributes): Add it.
- * c-decl.c (finish_decl): Honor the cleanup attribute.
- * doc/extend.texi (Variable Attributes): Document it.
-
- * unwind-c.c: New file.
- * Makefile.in (LIB2ADDEH): Add it.
- * config/t-darwin, config/t-linux, config/t-linux-gnulibc1,
- config/ia64/t-ia64: Likewise.
-
-2003-06-04 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR optimization/11018
- * config/sparc/sparc.c (sparc_v8plus_shift): Use which_alternative
- consistently to decide whether the scratch register is really
- required.
-
-2003-06-04 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR optimization/10876
- * config/sparc/sparc.h (CONST_OK_FOR_LETTER): Add
- new 'O' constraint for constant 4096.
- (CONST_DOUBLE_OK_FOR_LETTER_P): Likewise.
- * config/sparc/sparc.md (adddi3 expander): Canonicalize pattern.
- Do not transform into MINUS insn for constant 4096.
- (*adddi3_sp64 insn): Canonicalize pattern. Add new alternative
- for constant 4096 as third operand.
- (addsi3 expander): Remove.
- (*addsi3 insn): Rename into 'addsi3'. Canonicalize pattern. Add
- new alternative for constant 4096 as third operand.
- (subdi3 expander): Do not transform into PLUS insn for constant 4096.
- (*subdi3_sp64 insn): Add new alternative for constant 4096 as third
- operand.
- (subsi3 expander): Remove.
- (*subsi3 insn): Rename into 'subsi3'. Add new alternative for
- constant 4096 as third operand.
- * doc/md.texi (Machine Constraints): Document new 'O' constraint for
- the SPARC port.
-
-2003-06-03 Richard Henderson <rth@redhat.com>
-
- * unwind.inc (_Unwind_Resume_or_Rethrow): Fix return type.
- * unwind.h (_Unwind_Resume_or_Rethrow): Update.
- (_Unwind_SjLj_Resume_or_Rethrow): Likewise.
-
-2003-06-03 Douglas B Rupp <rupp@gnat.com>
-
- * Makefile.in (TEXI_GCC_FILES): Remove vms.texi entry.
- * doc/gcc.texi: Remove vms.texi section.
- * doc/vms.texi: Remove obsolete file.
-
-2003-06-03 Richard Henderson <rth@redhat.com>
-
- PR target/10673
- * config/i386/i386.c (ix86_split_long_move): Fix base register
- mode for XFmode splits for TARGET_64BIT.
-
-2003-06-02 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
-
- * gcc/config.gcc Add support multilib parts for m32rx processor.
-
-2003-06-01 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR target/11044
- * config/i386/i386.md (length attribute): Set length to 4
- for instructions of type "fcmp".
-
-2003-06-01 Josef Zlomek <zlomekj@suse.cz>
-
- * rtl.def (CONST_DOUBLE): Update comment.
-
-2003-06-01 Seth Arnold <sarnold@wirex.com>
- Aldy Hernandez <aldyh@redhat.com>
-
- PR10871
- * config/rs6000/rs6000.c (rs6000_stack_info): Do not add
- vrsave_size twice.
-
-2003-05-31 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- * doc/install.texi (mips-sgi-irix5): Add missing
- HTML <hr> marker.
-
-2003-05-31 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- * doc/md.texi (Machine Constraints): Document
- missing SPARC constraints.
-
-2003-05-31 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-04-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- * doc/md.texi (Automaton pipeline description): Use
- "type" instead of "cpu" as the attribute in the examples.
+ * config.gcc (i[34567]86-*-solaris2*): Default to DWARF-2
+ debugging on Solaris 7 and up.
-2003-05-30 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+2004-04-16 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- * config/mips/mips.h (SUBTARGET_ASM_DEBUGGING_SPEC): Move
- -mdebug/-no-mdebug switches ...
- (MDEBUG_ASM_SPEC): ... here.
- Use only with gas.
- (EXTRA_SPECS): Initialize mdebug_asm_spec.
- (CONSTANT_ADDRESS_P): Allow native IRIX 6 O32 assembler.
+ * doc/install.texi (Specific, mips-sgi-irix5): Reflect working
+ IRIX 5 port.
+ Remove -save-temps workaround, handled automatically.
+ Require GNU binutils 2.15 for debugging.
+ Remove SGI make warnings since GNU make is now required.
+ (Specific, mips-sgi-irix6): Some markup fixes.
+ Describe MIPSpro C problems and workarounds.
+ Mention working O32 ABI support.
+ Recommend GNU as 2.15 for O32 with debugging.
+ Remove description of fixed structure pass/return bug.
-2003-05-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+2004-04-16 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- * diagnostic.h (output_verbatim): Remove printf attribute.
- (verbatim): Likewise.
- * diagnostic.c (output_pointer): New function.
- (output_format): Use it. Handle %p format specifier.
-
-2003-05-27 Denis Chertykov <denisc@overta.ru>
-
- * cselib.c (cselib_invalidate_regno): Abort if hardreg have a
- VOIDmode.
- * cselib.c (cselib_process_insn): Pass reg_raw_mode for hardreg in
- call of cselib_invalidate_regno.
-
-2003-05-25 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/contrib.texi (Contributors): Update Kean Johnston.
-
-Fri May 23 21:19:31 CEST 2003 Jan Hubicka <jh@suse.cz>
- Andreas Jaeger <aj@suse.de>
-
- * i386.h (TARGET_CPU_CPP_BUILTINS): Define __amd64 and __amd64__;
- do not use assertion.
-
-Fri May 23 20:55:39 CEST 2003 Jan Hubicka <jh@suse.cz>
-
- * i386.md (sse_loadss, sse_loadss_1, sse2_loadsd, sse2_loadsd_1):
- Rewrite
-
-2003-05-23 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- * doc/install.texi: Remove sparc64-*-*. Add sparc64-*-solaris2*.
- Document sparcv9-*-solaris2* as a synonym for sparc64-*-solaris2*.
-
-2003-05-22 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR bootstrap/10805
- * doc/install.texi (sparc-sun-solaris2.7): Document bootstrap
- failure with Sun assembler 5.0 Alpha 03/27/98.
-
-2003-03-21 Loren James Rittle <ljrittle@acm.org>
-
- * config/sparc/freebsd.h (CPP_CPU64_DEFAULT_SPEC): Add -D__sparcv9
- -D__sparc__ to match system compiler convention.
-
-2003-05-20 Kevin Ryde <user42@zip.com.au>
- Wolfgang Bangerth <bangerth@dealii.org>
-
- PR c/10355
- * doc/extend.texi: Put a warning into the documentation
- of attribute regparm.
-
-2003-05-20 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.md ("*iordi3_oi"): Do not mark commutative.
- ("*iorsi3_oi"): Likewise.
-
-2003-05-19 John David Anglin <dave.anglin@nrc-gnrc.gc.ca>
-
- * pa/milli64.S ($$mulI): Fix typo.
-
-2003-05-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * hashtable.h (struct ht_identifier): Add new field "hash_value".
- * hashtable.c (ht_lookup): Use it.
- (ht_expand): Likewise. Avoid doing the same computation twice.
- * tree.h (IDENTIFIER_HASH_VALUE): New macro.
-
-2003-05-19 Nick Clifton <nickc@redhat.com>
-
- * config/arm/arm.c (use_return_insn): Do not use a single return
- instruction for interrupt handlers which have to create a stack
- frame.
- (arm_expand_prologue): Do not pre-bias the return address of
- interrupt handlers which create a stack frame.
+ * aclocal.m4 (gcc_AC_PROG_GNAT): Check if ${CC} produces object
+ file for Ada compilation.
+ Fix gcc_cv_cc_supports_ada spelling.
+ * configure: Regenerate.
-2003-05-19 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-04-14 Zack Weinberg <zack@codesourcery.com>
+ PR 14936
Backport from mainline:
+ 2004-03-12 Matt Austern <austern@apple.com>
- 2003-05-10 Alexander Aganichev <aaganichev@yandex.ru>
-
- * config/i386/i386.h (MODES_TIEABLE_P): Fix typo.
-
-2003-05-16 Wolfgang Bangerth <bangerth@dealii.org>
-
- * doc/bugreport.texi: Remove most of the preface of the
- bugs section.
-
-2003-05-16 Nick Clifton <nickc@redhat.com>
-
- * config/mcore/mcore.md (jump): Use emit_jump_insn to generate the
- jump insn.
-
-2003-05-15 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+ * varasm.c (make_decl_one_only): Don't use DECL_COMMON if
+ we're compiling for a SUPPORTS_ONE_ONLY target.
- * doc/invoke.texi (Warning Options): Mark -Wmissing-declarations
- as a C only option.
+2004-04-09 Zack Weinberg <zack@codesourcery.com>
-2003-05-15 Wolfgang Bangerth <bangerth@dealii.org>
-
- * doc/bugreport.texi: Remove most of the bug reporting
- instructions and merge them into bugs.html.
-
-2003-05-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * sparc.c (print_operand): Fix uninitialized warning.
-
-2003-05-14 Mark Mitchell <mark@codesourcery.com>
-
- * version.c: Reset to prerelease format.
- * doc/include/gcc-common.texi: Update version number.
-
-2003-05-13 Release Manager
-
- * GCC 3.3 Released.
-
-2003-05-12 Mark Mitchell <mark@codesourcery.com>
-
- PR other/10745
- * configure.in: Correct detection of GNU ld version number.
- * configure: Regenerated.
+ * config/ia64/hpux.h (MEMBER_TYPE_FORCES_BLK): Look only at
+ mode argument.
+ * config/ia64/ia64.c (ia64_hpux_file_end): Check
+ TREE_SYMBOL_REFERENCED on DECL_ASSEMBLER_NAME, not DECL_NAME.
-2003-05-08 J"orn Rennecke <joern.rennecke@superh.com>
+2004-04-08 Mark Mitchell <mark@codesourcery.com>
- * sh.c (gen_block_redirect, split_branches): Use
- CODE_FOR_jump_compact instead of CODE_FOR_jump
+ * doc/invoke.texi (Precompiled Headers): Warn about known
+ problems.
-2003-05-06 Eric Christopher <echristo@redhat.com>
+2004-04-08 Joel Sherrill <joel@oarcorp.com>
- * config/mips/linux.h: Fix typo.
+ PR ada/14538
+ * ada/5rosinte.adb: Remove fake mprotect() body.
+ * ada/5rosinte.ads: Add SA_SIGINFO. Make pthread_key_t a type
+ which can be set since Finalize_TCB in 7staprop.adb does not
+ go through the Set_Specific interface.
+ * ada/5rtpopsp.adb: Rewrite to use new interface.
+ * ada/init.c: Reorder so the simple single OS conditional __rtems__
+ is tested before more complex ones which mix UNIX and embedded
+ systems in the conditional.
-2003-05-06 Ulrich Weigand <uweigand@de.ibm.com>
+2004-04-08 Joel Sherrill <joel@oarcorp.com>
- PR other/10650
- * unwind-dw2.c (uw_update_context_1): Don't set sp as cfa on s390.
- (uw_init_context_1): Set initial sp to outer cfa on s390.
+ PR ada/14665
+ * ada/osint.adb (Find_Program_Name): Rework to properly handle
+ filenames which end in .exe or have versioning suffixes like VMS.
-2003-05-06 Mark Mitchell <mark@codesourcery.com>
+2004-04-08 Joseph S. Myers <jsm@polyomino.org.uk>
- PR other/10658
- * gcc.c (process_command): Update copyright date.
-
-2003-05-06 Bruce Korb <bkorb@gnu.org>
-
- * inclhack.def: fix up whitespace differences from mainline.
- mark fix tests that fail on BSD systems (like mainline).
- Fixup the solaris_mutex_init test to cope with Sol. 2.6 (like mainline).
- Removed unused SONY commentary (its obsolete anyway).
- (svr4_mach_defines): remove i860 machine from comment (like mainline).
- * gcc/fixinc/tests/base/pthread.h: solaris_mutex_init fix tests
- * gcc/fixinc/tests/base/testing.h: remove ^M chars from some mistake
- * gcc/fixinc/tests/base/Xm/Traversal.h: accommodate BSD's sed
- * gcc/fixinc/tests/base/sys/stat.h: accommodate BSD's sed
- * gcc/fixinc/fixincl.x: regenerated
-
-2003-05-06 Phil Edwards <pme@gcc.gnu.org>
-
- * doc/install.texi (mips-*-*): Add note about libstdc++.
-
-2003-05-05 Mark Mitchell <mark@codesourcery.com>
- Kean Johnston <jkj@sco.com>
-
- * toplev.c (check_global_declarations): Do not warn about unused
- static consts.
-
-2003-05-05 Richard Henderson <rth@redhat.com>
-
- * builtins.c (expand_builtin) <BUILT_IN_DWARF_FP_REGNUM>: Remove.
- <BUILT_IN_DWARF_SP_COLUMN>: New.
- * builtins.def (BUILT_IN_DWARF_FP_REGNUM): Remove.
- (BUILT_IN_DWARF_SP_COLUMN): New.
- * dwarf2out.c (expand_builtin_dwarf_fp_regnum): Remove.
- (expand_builtin_dwarf_sp_column): New.
- * except.h: Update to match.
- * unwind-dw2.c (execute_stack_op): Correct stack push typo.
- (execute_cfa_program): Record location expression address
- before extracting length.
- (uw_update_context_1): Install old CFA into stack pointer column.
- (uw_init_context_1): Set cfa_reg to stack pointer column.
-
-2003-05-05 David O'Brien <obrien@FreeBSD.org>
-
- * config/rs6000/sysv4.h (CPP_OS_FREEBSD_SPEC): Add __ELF__ to mirror
- other FreeBSD ports.
- (LINK_OS_FREEBSD_SPEC): Mirror conventions on other FreeBSD ports.
-
-2003-05-05 Jason Merrill <jason@redhat.com>
-
- * stor-layout.c (update_alignment_for_field): Set DECL_ALIGN for
- the field.
-
-2003-05-02 Zack Weinberg <zack@codesourcery.com>
-
- PR c/10604
- * c-opts.c (c_common_decode_option <OPT_Wall>): Set
- warn_sign_compare for C++ only.
- * doc/invoke.texi: Clarify documentation of -Wsign-compare.
-
-2003-05-03 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
- Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/contrib.texi (Contributors): Add Zdenek Dvorak, Aldy
- Hernandez, and Kazu Hirata.
-
-2003-05-02 Richard Henderson <rth@redhat.com>
-
- PR c++/10570
- * except.c: Revert 04-01 and 04-02 forced-unwind changes.
- * flags.h, toplev.c, doc/invoke.texi: Likewise.
-
- * unwind-dw2.c (_Unwind_GetCFA): Fix ptr->int conversion warning.
- * unwind.inc (_Unwind_DeleteException): Check for null
- exception_cleanup.
-
- * unwind-sjlj.c (_Unwind_SjLj_Resume_or_Rethrow): New.
- * unwind.inc (_Unwind_Resume_or_Rethrow): New.
- * unwind.h: Declare them.
- * libgcc-std.ver (GCC_3.3): Export them.
-
-2003-05-02 Steven Bosscher <steven@gcc.gnu.org>
-
- * tree-inline.c (find_alloca_call):
- Use walk_tree_without_duplicates, instead of walk_tree.
- (find_builtin_longjmp_call): Ditto.
- * c-objc-common.c (c_cannot_inline_fn): Ditto.
-
-2003-05-02 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/contrib.texi (Contributors): Add Daniel Berlin.
-
-2003-05-01 Rodney Brown <rbrown64@csc.com.au>
-
- * rtl.h (subreg_offset_representable_p): Prototype.
-
-2003-05-01 Roger Sayle <roger@eyesopen.com>
-
- PR fortran/9974
- * gcse.c (reg_killed_on_edge): New function to test whether the
- given reg is overwritten by any instruction queued on an edge.
- (bypass_block): Ignore substitutions killed on incoming edges.
- Don't bypass outgoing edges that have queued instructions.
-
-2003-04-30 Andreas Schwab <schwab@suse.de>
+ * fixinc/inclhack.def (rpc_xdr_lvalue_cast_a,
+ rpc_xdr_lvalue_cast_b): New fixes.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/rpc/xdr.h: Add new tests.
- * doc/extend.texi (Other Builtins): Enclose multiple word data
- type in braces for @deftypefn.
+2004-04-06 Mark Mitchell <mark@codesourcery.com>
-2003-04-29 Jason Merrill <jason@redhat.com>
+ * config/darwin.h (LINK_COMMAND_SPEC): Change c++filt3 to c++filt.
- PR middle-end/10336
- * jump.c (never_reached_warning): Really stop looking if we reach
- the beginning of the function.
+2004-04-05 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-Tue Apr 29 21:07:00 CEST 2003 Jan Hubicka <jh@suse.cz>
+ * doc/install.texi: Update HP-UX 11 installation procedure.
- * cse.c (count_reg_usage): Revert my previous patch.
+2004-04-05 Jakub Jelinek <jakuB@redhat.com>
+ John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-2003-04-29 Alexander Kabaev <kan@FreeBSD.ORG>
+ PR optimization/13424 (hppa), bootstrap/14462, c/14828
+ * pa.md: Use replace_equiv_address to retain the attributes of the
+ memory operands used in the split and peephole2 patterns for optimizing
+ the pre-reload movstrsi, movstrdi, clrstrsi and clrstrdi patterns.
- bootstrap/10452
- * gengtype-yacc.y: Improve portability.
+2004-04-05 Alexandre Oliva <aoliva@redhat.com>
-2003-04-29 Zack Weinberg <zack@codesourcery.com>
+ * cppinit.c (cpp_read_main_file): Return file name obtained by
+ read_original_filename. Missed in 2004-02-04's check in to 3.4
+ branch by Per Bothner.
- * config.gcc: Install obsolete target list for GCC 3.3.
- * doc/install.texi: Mention in specific-target instructions
- that certain configurations are deprecated.
+2004-04-05 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-04-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ * config/sparc/sol2-bi.h (PREFERRED_DEBUGGING_TYPE): Set
+ to DWARF2_DEBUG unconditionally.
+ (ASM_DEBUG_SPEC): Set the default to --gdwarf2 unconditionally.
- * c-pragma.c (maybe_apply_renaming_pragma): Fix typo.
- * gcc.c (display_help): Likewise.
- * toplev.c (f_options): Likewise.
- * params.def (PARAM_MAX_INLINE_SCOPE): Likewise.
- * config/c4x/c4x.h (TARGET_SWITCHES): Likewise.
- * config/mcore/mcore.h (TARGET_SWITCHES): Likewise.
- * config/s390/s390.h (TARGET_SWITCHES): Likewise.
- * config/v850/v850.h (TARGET_SWITCHES): Likewise.
+2004-04-04 Mark Mitchell <mark@codesourcery.com>
-2003-04-29 Danny Smith <dannysmith@users.sourceforge.net>
+ PR c++/14804
+ * varasm.c (initializer_constant_valid_p): Allow NOP_EXPRs to
+ RECORD_TYPEs.
- * config/i386/mingw32.h (LIBGCC_SPEC): Add libmingwex.a.
- Update copyright.
- * config/i386/cygwin.h (LIBGCC_SPEC): Add libmingwex.a, for
- -mno-cygwin case.
+2004-04-02 Jakub Jelinek <jakub@redhat.com>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-04-29 J"orn Rennecke <joern.rennecke@superh.com>
+ PR optimization/13424, optimization/12419
+ * explow.c (maybe_set_unchanging): Revert 2003-04-07 patch.
+ Set RTX_UNCHANGING_P even for read-only DECL_EXTERNAL decls.
+ * expr.c (store_constructor): When clearing aggregate because
+ of an incomplete or mostly zero constructor, do the clearing
+ without /u flag and then emit a blockage.
- * varasm.c (default_assemble_visibility): Use assemble_name.
+2004-04-01 Alan Modra <amodra@bigpond.net.au>
+ Jakub Jelinek <jakub@redhat.com>
-2003-04-29 David O'Brien <obrien@FreeBSD.org>
+ * gcc.c (init_gcc_specs): If HAVE_LD_AS_NEEDED, link with
+ -lgcc --as-needed -lgcc_s --no-as-needed by default.
+ * configure.ac (HAVE_LD_AS_NEEDED): Check for ld --as-needed.
+ * configure: Rebuilt.
+ * config.in: Rebuilt.
+ * Makefile.in (stage1-start): Copy also libgcc_s*$(SHLIB_EXT).
+ (stage2-start, stage3-start, stage4-start): Likewise.
+ (stageprofile-start, stagefeedback-start): Likewise.
+
+2004-04-01 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/sparc.h (DITF_CONVERSION_LIBFUNCS): Define to 0.
+ * config/sparc/linux.h (DITF_CONVERSION_LIBFUNCS): Redefine to 1.
+ * config/sparc/linux64.h (DITF_CONVERSION_LIBFUNCS): Redefine to 1.
+ * config/sparc/sol2.h (DITF_CONVERSION_LIBFUNCS): Redefine to 1.
+ (SOLARIS_CONVERSION_LIBFUNCS): Rename to SUN_CONVERSION_LIBFUNCS.
+ * config/sparc/sparc.c (sparc_init_libfuncs): Initialize optabs
+ with _Q_qtoll, _Q_qtoull and _Q_lltoq if DITF_CONVERSION_LIBFUNCS.
+ * config.gcc (sparc-*-linux*): Revert 2004-03-23 change.
+ * config/sparc/t-linux64 (TARGET_LIBGCC2_CFLAGS): Likewise.
+ * config/sparc/t-linux: Removed.
+
+2004-04-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/14755
+ * fold-const.c (fold) <EQ_EXPR>: Properly compute newconst in
+ "bitfld++ == const" to "++bitfld == const + incr" transformations.
+
+2004-03-30 Aldy Hernandez <aldyh@redhat.com>
+
+ PR 14219
+ * c-typeck.c (build_binary_op): Do not allow comparisons of
+ vectors.
+
+2004-03-26 Ian Lance Taylor <ian@wasabisystems.com>
+
+ PR target/14206
+ * doc/install.texi (Specific): Document that exec-shield-randomize
+ interferes with precompiled headers.
+
+2004-03-26 Richard Henderson <rth@redhat.com>
+
+ PR 11527
+ * c-typeck.c (pop_init_level): Emit pending init elements earlier
+ rather than later.
+
+2004-03-25 Jakub Jelinek <jakub@redhat.com>
+
+ * config.gcc (sparc-*-linux*): Add sparc/t-linux to tmake_file.
+ * config/sparc/t-linux64 (TARGET_LIBGCC2_CFLAGS): Set.
+ * config/sparc/t-linux: New file.
+
+2004-03-25 Jan Hubicka <jh@suse.cz>
+
+ PR debug/13974
+ * cfgrtl.c (try_redirect_by_replacing_jump,
+ force_nonfallthru_and_redirect, commit_one_edge_insertion,
+ cfg_layout_merge_blocks): Do not attach any line number information
+ to newly inserted instructions.
+ * emit-rtl.c (emit_insn*_before, emit_insn*_after): Rename to
+ emit_insn_*_noloc.
+ (emit_*insn_before, emit_insn*_after): New.
+ (emit_*insn_before_setloc, emit_*insn_after_setloc): Do not overwrite
+ existing locators.
+ * rtl.h (emit_*insn_before_noloc, emit_*insn_after_noloc): Declare.
+ (emit_*insn_before_sameloc, emit_*insn_after_sameloc): Kill.
+
+2004-03-24 Steven Bosscher <stevenb@suse.de>
+
+ PR pch/14137
+ * c-pch.c (struct c_pch_validity): New flags_info field.
+ (FLAG_UNIT_AT_A_TIME_SET): New definition.
+ (pch_init): Write out the flags_info field to the PCH. Set the
+ FLAG_UNIT_AT_A_TIME_SET bit of the field if flag_unit_at_a_time
+ is set.
+ (c_common_valid_pch): Make sure the flag settings used for compiling
+ the PCH are the same as those used in the current compilation.
- * config/i386/freebsd64.h (LINK_SPEC): Mirror FreeBSD linker.
- * config/rs6000/freebsd.h (LINK_SHLIB_SPEC): New macro.
- (SIZE_TYPE): New macro.
- * config/i386/freebsd-aout.h (NO_PROFILE_COUNTERS): New macro.
- (SET_ASM_OP): New macro.
- (HANDLE_SYSV_PRAGMA): New macro.
- (ASM_WEAKEN_LABEL): New macro.
+2004-03-24 Alexandre Oliva <aoliva@redhat.com>
-2003-04-28 Mark Mitchell <mark@codesourcery.com>
+ PR preprocessor/14438
+ * cpplib.c (do_pragma): Remove line_change call after pragma
+ handler.
- PR c++/10180
- * tree-inline.c (expand_call_inline): Call push_srcloc when
- encountering EXPR_WITH_FILE_LOCATION. Honor warn_inline.
+2004-03-23 Ian Lance Taylor <ian@wasabisystems.com>
-2003-04-28 Mike Stump <mrs@apple.com>
+ * doc/extend.texi (ARM Built-in Functions): Replace with correct
+ declarations.
- * gdbinit.in: Update to reflect new identifier structure.
+2004-03-23 Kazu Hirata <kazu@cs.umass.edu>
-2003-04-28 Richard Henderson <rth@redhat.com>
+ PR optimization/14669
+ * fold-const.c (fold): Only unwiden integer comparisons for equality
+ and inequality operators, or when the signedness doesn't change.
- * config/sparc/sparc.c (print_operand): Add 's' to sign-extend.
- * config/sparc/sparc.md (const_mulsidi3_v8plus): Fix mode of
- integral constant mult operand.
- (const_mulsidi3_sp32, const_mulsidi3_sp64): Likewise.
- (const_smulsi3_highpart_v8plus): Likewise.
- (const_smulsi3_highpart): Likewise.
- (const_umulsidi3_sp32): Likewise; sign-extend it in the output.
- (const_umulsidi3_sp64, const_umulsidi3_v8plus): Likewise.
- (const_umulsi3_highpart_v8plus): Likewise.
- (const_umulsi3_highpart): Likewise.
+2004-03-23 Jason Merrill <jason@redhat.com>
-2003-04-28 David O'Brien <obrien@FreeBSD.org>
+ PR c++/14587
+ * config/i386/winnt.c (associated_type): Look for attributes on
+ the TYPE_MAIN_VARIANT of *this.
- * config/i386/i386.h (builtin_define): Add __amd64 and __amd64__.
+2004-03-21 Mark Mitchell <mark@codesourcery.com>
-Mon Apr 28 09:54:56 CEST 2003 Jan Hubicka <jh@suse.cz>
+ PR c/13129
+ * c-decl.c (warn_if_shadowing): Don't warn about a new declaration
+ of a file-scope entity.
- PR c/10308
- * reload.c (find_reloads_address_1): Reload plus at the place of
- index register.
+2004-03-22 Jakub Jelinek <jakub@redhat.com>
-2003-04-26 Richard Henderson <rth@redhat.com>
+ PR c/14069
+ * c-decl.c (finish_struct): Change type of incorrect flexible array
+ field into error_mark_node.
- * config/ia64/ia64.c (ia64_compute_frame_size): Allow inline asm
- to clobber ar.pfs and ar.unat.
- (ia64_expand_prologue): Force alloc instruction if ar.pfs saved;
- fix test for spilling ar.pfs to the stack.
+2004-03-22 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
-2003-04-26 Stephane Carrez <stcarrez@nerim.fr>
+ PR target/14260
+ * config/rtems.h: Add STD_LIB_SPEC and LIB_SPEC.
- * doc/install.texi (Binaries): Mention binaries for HC11/HC12.
+2004-03-22 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-04-26 Stephane Carrez <stcarrez@nerim.fr>
+ PR middle-end/14470
+ * expr.c (mark_queue): New function.
+ (emit_insns_enqueued_after_mark): New function replacing
+ emit_queue. Clear the body of emitted queued insns.
+ (emit_queue): Call emit_insns_enqueued_after_mark.
+ (store_expr): Mark the increment queue on entry. Emit
+ only the incrementations queued when expanding the source.
- * doc/extend.texi (Function Attributes): Document "near" and "far"
- for 68HC11 and 68HC12.
+2004-03-22 Danny Smith <dannysmith@users.sourceforge.net>
-2003-04-25 Bob Wilson <bob.wilson@acm.org>
+ * gcov-io.h: Update copyright year.
- * config/xtensa/linux.h (TARGET_OS_CPP_BUILTINS): Back out previous
- addition of __PIC__ and __pic__ macros.
- * config/xtensa/xtensa.h: Clean up indentation.
+2004-03-22 Danny Smith <dannysmith@users.sourceforge.net>
-2003-04-25 Bob Wilson <bob.wilson@acm.org>
+ PR target/14291
+ * gcov-io.h (gcov_truncate): Define ftruncate as _chsize for
+ __MINGW32__.
- * config/xtensa/linux.h (TARGET_OS_CPP_BUILTINS): Remove definition of
- _GNU_SOURCE. Add definitions of __PIC__ and __pic__.
- (SUBTARGET_CPP_SPEC): Define.
- (LIB_SPEC): Delete.
- * config/xtensa/xtensa-protos.h (xtensa_declare_object): Delete.
- * config/xtensa/xtensa.c (xtensa_declare_object): Delete.
- * config/xtensa/xtensa.h (CPP_SPEC, SUBTARGET_CPP_SPEC, EXTRA_SPECS):
- Define.
- (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL): Delete.
- (ASM_OUTPUT_ALIGNED_BSS, BSS_SECTION_ASM_OP): Define.
+2004-03-21 Roger Sayle <roger@eyesopen.com>
-2003-04-25 Richard Henderson <rth@redhat.com>
+ PR target/13889
+ * cse.c (fold_rtx): Avoid substituting constants into unary
+ conversion operations.
- PR opt/10315
- * config/rs6000/rs6000.c (rs6000_emit_move): Only elide proper
- checks during reload; use validize_mem instead of adjust_address.
+2004-03-21 Joseph S. Myers <jsm@polyomino.org.uk>
-Fri Apr 25 15:43:23 CEST 2003 Jan Hubicka <jh@suse.cz>
+ * frontends.texi: Add missing line.
- * emit-rtl.c (subreg_hard_regno): Check that register is
- representable.
- * reload.c (reload_inner_reg_of_subreg): When register is not
- representable, reload the whole thing.
- (find_reloads): Likewsie.
- * rtlanal.c (subreg_representable_p): New function.
+2004-03-21 Zack Weinberg <zack@codesourcery.com>
+ Chris Devers <cdevers@pobox.com>
+ Joseph S. Myers <jsm@polyomino.org.uk>
-Sun Apr 20 18:23:18 CEST 2003 Richard Henderson <rth@redhat.com>
+ * doc/frontends.texi: Rewrite.
+ * doc/gcc.texi: Update last modification date.
- (backported to 3.3 by Jan Hubicka)
+2004-03-20 Ian Lance Taylor <ian@wasabisystems.com>
- * config/ia64/ia64.md (UNSPECV_SETJMP_RECEIVER): New.
- (builtin_setjmp_receiver): Delay call to ia64_reload_gp
- until after reload.
+ PR c/12373
+ * c-typeck.c (tagged_types_tu_compatible_p): Don't use
+ DECL_ORIGINAL_TYPE if there isn't one.
- * emit-rtl.c (try_split): Handle 1-1 splits of call insns properly.
+2004-03-20 Joseph S. Myers <jsm@polyomino.org.uk>
- * config/ia64/ia64.c (TARGET_FUNCTION_OK_FOR_SIBCALL): New.
- (ia64_gp_save_reg): Remove.
- (struct ia64_frame_info): Move to the beginning of the file;
- add reg_save_gp.
- (ia64_expand_call): Rearrange for new call patterns.
- (ia64_reload_gp): New.
- (ia64_split_call): New.
- (ia64_compute_frame_size): Allocate reg_save_gp.
- (ia64_expand_prologue): Save reg_save_gp.
- (ia64_expand_epilogue): Don't restore gp.
- (ia64_hard_regno_rename_ok): Remove R4 hack.
- (ia64_function_ok_for_sibcall): New.
- (ia64_output_mi_thunk): Set reload_completed, no_new_pseudos;
- call try_split on sibcall pattern.
- * config/ia64/ia64-protos.h: Update.
- * config/ia64/ia64.md (call_nogp, call_value_nogp, sibcall_nogp):
- Rename from nopic versions. Confiscate 2nd argument to call as
- a marker.
- (call_pic, call_value_pic, sibcall_pic): Remove.
- (call_gp, call_value_gp, sibcall_gp): New.
- (builtin_setjmp_setup): Remove.
- (builtin_setjmp_receiver): Call ia64_reload_gp.
+ PR other/14630
+ * doc/install.texi: Add info directory category and entry.
-2003-04-24 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2004-03-20 Joseph S. Myers <jsm@polyomino.org.uk>
- PR opt/8705
- * gcse.c (try_replace_reg): On a successful substitution of a constant
- into a single set, try to simplify the source of the set.
- * loop.c (scan_loop): Don't try to optimize a MODE_CC set with a
- constant source.
+ PR c/14635
+ * builtins.def (nan, nanf, nanl, nans, nansf, nansl): Change to
+ DEF_GCC_BUILTIN.
-2003-04-24 Alexander Kabaev <kan@FreeBSD.ORG>
+2004-03-18 Mark Mitchell <mark@codesourcery.com>
- bootstrap/10453
- * config/sparc/sparc.md (umulsidi3, mulsidi3): Avoid using
- const_umulsidi3_sp32 and const_mulsidi3_sp32 on 64bit targets
- where they might be not present. Use their _sp64 equivalent
- instead.
+ * c-common.c (pointer_int_sum): Do not complain about using
+ pointers to pointers-to-members.
-2003-04-23 Richard Henderson <rth@redhat.com>
+ * c-decl.c (grokdeclarator): Do not complain about redeclaring
+ visible "static" identifiers "extern" in a local scope.
+ * dwarf2out.c (loc_descriptor_from_tree): Handle pre- and
+ post-increments/decrements.
- PR opt/8300
- * toplev.c (rest_of_compilation): Delay no_new_pseudos until
- after initialize_uninitialized_subregs; update reg info assuming
- new pseudos were created.
+2004-03-17 Jakub Jelinek <jakub@redhat.com>
-2003-04-23 Olivier Hainque <hainque@act-europe.fr>
+ * config/rs6000/t-linux64 (bispecs): Don't add -mlong-double-128 for
+ 32-bit builds when defaulting to 32-bit.
- * config/pa/pa.md (extv, extzv): FAIL if the bitfield length is zero.
+2004-03-17 Richard Sandiford <rsandifo@redhat.com>
-2003-04-23 James A Morrison <ja2morri@uwaterloo.ca>
+ PR target/14599
+ * config/mips/mips.md (UNSPEC_GP): New constant.
+ * config/mips/mips.c (CONST_GP_P): Expect the CONST to contain
+ an UNSPEC instead of (reg $gp).
+ (mips16_gp_pseudo_reg): Change accordingly.
+ (print_operand): Print $gp directly when handling CONST_GP_P.
- * invoke.texi: Eliminate extra white-space caused by @gccoptlist{
- on its own line.
- Ensure there are two spaces between each pair of options and add
- @gol where appropriate.
+2004-03-16 Mark Mitchell <mark@codesourcery.com>
-2003-04-23 Ulrich Weigand <uweigand@de.ibm.com>
+ PR c++/14481
+ * fold-const.c (fold): Set TREE_NO_UNUSED_WARNING on implicitly
+ generated COMPOUND_EXPRs.
- * config/s390/s390.c (s390_expand_cmpstr): Disable CLC loop.
+2004-03-16 Nathanael Nerode <neroden@gcc.gnu.org>
-2003-04-22 Devang Patel <dpatel@apple.com>
+ PR bootstrap/12974
+ * Makefile.in: Pass $(INCLUDES) down to libgcc.mk explicitly.
- * cpptrad.c (_cpp_replacement_text_len): Add check for macro parameter count.
- (_cpp_copy_replacement_text): Same.
+2004-03-16 Richard Henderson <rth@redhat.com>
-2003-04-22 Richard Henderson <rth@redhat.com>
+ PR middle-end/14535
+ * except.c (collect_one_action_chain): Create action record for
+ cleanup outer of exception spec.
- PR 8866
- * rtl.h (MEM_NOTRAP_P): New.
- (MEM_COPY_ATTRIBUTES): Copy it.
- * rtlanal.c (may_trap_p): Check it.
- * expr.c (do_tablejump): Set it.
+2004-03-16 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
- * cfgrtl.c (try_redirect_by_replacing_jump): Revert last three changes.
+ PR target/14577
+ * config.gcc: Switch sh-*-rtems* to ELF. Add sh-*-rtemscoff.
-2003-04-22 David Turner <novalis@gnu.org>
+2004-03-15 Richard Henderson <rth@redhat.com>
- * gbl-ctors.h: Add special license exception.
- * libgcc2.h: Likewise.
- * tsystem.h: Likewise.
- * gcov-io.h: Likewise.
+ PR target/14547
+ * target.h (struct gcc_target): Move calls substructure before
+ booleans. Add split_complex_arg.
+ * function.c (assign_parms, split_complex_args): Use it.
+ * calls.c (expand_call): Likewise.
+ (split_complex_values): Likewise. Check for splittable types
+ before allocating memory.
+ (split_complex_types): Likewise.
+ * system.h (SPLIT_COMPLEX_ARGS): Poison.
+ * expr.h (SPLIT_COMPLEX_ARGS): Remove.
+ * target-def.h (TARGET_SPLIT_COMPLEX_ARG): New.
+ * config/alpha/alpha.c (alpha_split_complex_arg): New.
+ (TARGET_SPLIT_COMPLEX_ARG): New.
+ * config/alpha/alpha.h (SPLIT_COMPLEX_ARGS): Remove.
+ * config/rs6000/rs6000.c (TARGET_SPLIT_COMPLEX_ARG): New.
+ (rs6000_override_options): Zap it for non-AIX.
+ (rs6000_function_value): Use targetm.calls.split_complex_arg.
+ * config/rs6000/rs6000.h (SPLIT_COMPLEX_ARGS): Remove.
+ * config/xtensa/xtensa.c (TARGET_SPLIT_COMPLEX_ARG): New.
+ * config/xtensa/xtensa.h (SPLIT_COMPLEX_ARGS): Remove.
+ * doc/tm.texi (TARGET_SPLIT_COMPLEX_ARG): Modify from old
+ SPLIT_COMPLEX_ARGS entry.
-2003-04-21 Mark Mitchell <mark@codesourcery.com>
+2004-03-15 Eric Botcazou <ebotcazou@act-europe.fr>
- * Makefile.in (calls.o): Depend on except.h.
- * calls.c: Include except.h.
- (emit_call_1): Call note_eh_region_may_contain_throw if
- appropriate.
- * except.c (eh_region): Add may_contain_throw.
- (expand_eh_region_end_cleanup): Do not include handler code when
- it cannot be reached.
- (note_eh_region_may_contain_throw): New function.
- * except.h (note_eh_region_may_contain_throw): New function.
+ * config/sparc/sparc.h: Rework comments about the code model
+ in 64-bit environment and the mode 'Pmode'.
+ * doc/invoke.texi (SPARC options): Rework description of the
+ different code models supported in 64-bit environment.
-2003-04-21 Mark Mitchell <mark@codesourcery.com>
+2004-03-14 Joseph S. Myers <jsm@polyomino.org.uk>
- * config/i386/winnt.c (i386_pe_mark_dllimport): Revert previous
- changes.
+ * doc/contrib.texi, doc/extend.texi, doc/gcov.texi,
+ doc/install.texi, doc/invoke.texi, doc/makefile.texi,
+ doc/sourcebuild.texi, doc/tm.texi, doc/trouble.texi: Capitalize
+ "gcc", "g++" and "g77" or mark up with appropriate markup. Adjust
+ wording and grammar.
-2003-04-21 Mark Mitchell <mark@codesourcery.com>
+2004-03-13 Eric Botcazou <ebotcazou@libertysurf.fr>
- * config/i386/winnt.c (i386_pe_}ark_dllimport): Make the new RTL
- have the same form as the old RTL.
+ PR c/14114
+ * c-decl.c (merge_decls): Do not copy the C_DECL_INVISIBLE flag
+ from the new decl to the old decl.
+ (pushdecl): Use lookup_name to search for a previous decl with the
+ same identifier.
-2003-04-18 Mark Mitchell <mark@codesourcery.com>
+2004-03-13 Dara Hazeghi <dhazeghi@yahoo.com>
- * cfgrtl.c (try_redirect_by_replacing_jump): Create a basic block
- for orphaned jump tables.
+ * doc/install.texi: Note status of -fnew-ra.
-2003-04-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2004-03-13 Eric Botcazou <ebotcazou@libertysurf.fr>
- PR/8705
- * pa.md (movccfp): New expander.
- (setccfp0, setccfp1): Rename to movccfp0 and movccfp1, respectively.
- Reverse fcmp conditions.
+ PR middle-end/14470
+ * expr.c (store_expr): Call emit_queue before generating the move
+ from the temporary to the original target. Protect the temporary
+ from emit_queue.
-2003-04-20 Marek Michalkiewicz <marekm@amelek.gda.pl>
+2004-03-13 Jakub Jelinek <jakub@redhat.com>
- * config/avr/avr.md (*cmpqi_sign_extend): Handle negative values
- of operand 1 correctly.
+ PR target/14533
+ * config/s390/s390.c (legitimize_pic_address): Don't abort on UNSPEC
+ other than UNSPEC_GOTOFF.
-2003-04-19 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2004-03-13 Dean Ferreyra <dferreyra@igc.org>
- * cfgrtl.c (try_redirect_by_replacing_jump): Remove unused variables.
- * flow.c (life_analysis): Fix warning.
+ PR target/14047
+ * config/avr/avr.c (avr_progmem_p): Add "attributes" parameter.
+ (avr_insert_attributes): Pass "attributes" to avr_progmem_p.
+ * config/avr/avr-protos.h (avr_progmem_p): Change prototype.
-2003-04-18 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+2004-03-12 David Edelsohn <edelsohn@gnu.org>
- * doc/contrib.texi (Contributors): Prefer "bug fix" over "bugfix".
- Add Segher Boessenkool.
+ * doc/install.texi (*-ibm-aix*): Document assembler and achiver
+ fixes required by libstdc++ and update installation instructions
+ for libstdc++.a. Document use of Bash to speed up configuration.
-2003-04-18 Alexander Sotirov <sluncho@mirizma.org>
+2004-03-12 Eric Botcazou <ebotcazou@libertysurf.fr>
- PR c/9177
- * c-decl.c (c_expand_body): Don't garbage collect the function
- body if we are going to dump it later.
+ * doc/tm.texi (registers) <Values in Registers>: Add
+ entry for REGMODE_NATURAL_SIZE.
-2003-04-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-03-11 Richard Henderson <rth@redhat.com>
- PR optimization/7675
- * c-typeck.c (build_external_ref): Set the DECL_NONLOCAL flag
- on VAR_DECL, PARM_DECL and FUNCTION_DECL from within
- nested functions if they refer to declarations from parent functions.
- * stmt.c (expand_decl): Don't put automatic variables in registers
- if the DECL_NONLOCAL flag is set.
+ PR target/14539
+ * config/alpha/alpha.h (STACK_BOUNDARY): Set to 128.
-2003-04-17 Janis Johnson <janis187@us.ibm.com>
+2004-03-12 Alan Modra <amodra@bigpond.net.au>
- * doc/sourcebuild.texi (Test Suites): Document support for testing
- binary compatibility (moved from testsuite/README.compat).
+ * real.c (encode_ibm_extended): Do round low word.
-2003-04-17 Simon Law <sfllaw@engmail.uwaterloo.ca>
+2004-03-11 Richard Henderson <rth@redhat.com>
- * doc/include/gpl.texi: Fix double-spacing after "MA" to match
- the one provided by the FSF.
+ PR middle-end/14477
+ * except.c (remove_unreachable_regions): Look thru CALL_PLACEHOLDER.
-2003-04-17 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+2004-03-11 Richard Sandiford <rsandifo@redhat.com>
- * doc/install.texi (Binaries): Update URL and list of platforms
- provided by ftp.thewrittenword.com.
+ PR target/14496
+ * config/mips/mips.h (UNITS_PER_FPVALUE): Fix value for
+ TARGET_SINGLE_FLOAT.
-2003-04-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-03-11 Kelley Cook <kcook@gcc.gnu.org>
- * doc/invoke.texi (inline-limit): Fix pasto.
+ PR other/14536
+ * configure: Regenerated with autoconf 2.57.
+ * config.in: Regenerated with autoheader 2.57.
-2003-04-16 Mark Mitchell <mark@codesourcery.com>
+2004-03-11 Alan Modra <amodra@bigpond.net.au>
- PR middle-end/8866
- * cfgtrl.c (try_redirect_by_replacing_jump): Do not delete
- jumptables.
+ * config/rs6000/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Don't
+ bump retaddr here.
-2003-04-16 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2004-03-11 Alan Modra <amodra@bigpond.net.au>
- PR/10271
- * pa-protos.h (function_arg): Remove last argument.
- * pa.c (function_arg): Likewise. Use CUMULATIVE_ARGS struct instead.
- * pa.h (struct hppa_args): Add member incoming.
- (INIT_CUMULATIVE_ARGS, INIT_CUMULATIVE_INCOMING_ARGS): Initialize
- member incoming.
- (FUNCTION_ARG): Revise call to function_arg.
- (FUNCTION_INCOMING_ARG): Delete.
+ * config/rs6000/t-linux64 (LIB2FUNCS_EXTRA): Add darwin-ldouble.c.
+ (SHLIB_MAPFILES): Add libgcc-ppc64.ver.
+ (SHLIB_MKMAP_OPTS): Delete.
+ (TARGET_LIBGCC2_CFLAGS): Add -specs.
+ (bispecs): Add rule.
+ * config/rs6000/libgcc-ppc64.ver: New file.
+ * config/rs6000/ppc64-fp.c (__fixtfdi, __floatditf): New functions.
+ (__floatdidf, __floatdisf): Optimize multiply.
+ (__fixunstfdi): New function.
+ * config/rs6000/rs6000.c (rs6000_complex_function_value): Allow for
+ real and imag parts larger than one register.
+ (function_arg): Correct type of reg used when fp arg split partially
+ to stack.
+ * config/rs6000/darwin-ldouble.c: Protect with #if !_SOFT_FLOAT
+ and __MACH__ or __powerpc64__.
-2003-04-15 J"orn Rennecke <joern.rennecke@superh.com>
+2004-03-10 Richard Henderson <rth@redhat.com>
- PR target/9594:
- * sh.c (barrier_align): Also recognize stuff_delay_slot as
- an indicator that a barrier was created by branch splitting.
+ PR c/14517
+ * c-decl.c (grokdeclarator): Don't warn for duplicate qualifiers
+ except for pedantic c90 mode.
- merge from mainline:
+2004-03-10 Andrew Haley <aph@redhat.com>
- 2003-03-05 J"orn Rennecke <joern.rennecke@superh.com>
+ PR optimization/14381
+ * function.c (expand_function_end): Emit a blockage insn before
+ the epilogue when -fnon-call-exceptions is used.
- * sh.h (OVERRIDE_OPTIONS): For TARGET_SHMEDIA, the minimum value
- for align_jumps is 4.
+2004-03-10 Joel Sherrill <joel@oarcorp.com>
- (SECONDARY_INPUT_RELOAD_CLASS): If reloading a PLUS into FPUL,
- use GENERAL_REGS.
+ PR target/14480
+ * config.gcc (powerpc*-*-rtems*): Use rs6000/t-rtems.
- 2003-03-03 J"orn Rennecke <joern.rennecke@superh.com>
+2004-03-10 Roman Zippel <zippel@linux-m68k.org>
- * sh.h (OVERRIDE_OPTIONS): Set default values for align_loops
- and align_jumps if not set.
- Force align_jumps to be at least 2.
- When relaxing, force align_functions to be at least the maximum of
- align_loops, align_jumps and 4.
- * sh.c (find_barrier, barrier_align): Honour align_jumps_log.
- (sh_loop_align): Honour align_loops_log.
+ PR bootstrap/12371
+ * config/m68k/m68k.h (FIXED_REGISTERS): Add arg pointer.
+ (CALL_USED_REGISTERS): Likewise.
+ (REG_CLASS_CONTENTS): Likewise.
+ (REG_ALLOC_ORDER): New.
+ (REGNO_REG_CLASS): Use regno_reg_class.
+ * config/m68k/m68k.c: Add regno_reg_class array.
- * sh.md (length attribute): Use prev_nonnote_insn instead of PREV_INSN
- to check for indirect_jump_scratch.
- (indirect_jump_scratch): Add second set.
- * sh.c (output_far_jump): Use prev_nonnote_insn instead of PREV_INSN
- when looking for indirect_jump_scratch.
- Extract scratch register taking new structure of indirect_jump_scratch
- into account.
- (gen_block_redirect): Set INSN_SCOPE for indirect_jump_scratch.
+2004-03-10 Alan Modra <amodra@bigpond.net.au>
+ Hartmut Penner <hpenner@de.ibm.com>
-2003-04-15 James A. Morrison <ja2morri@uwaterloo.ca>
+ * config/rs6000/rs6000.c (invalid_gpr_mem): New function.
+ (base_reg_operand): New function.
+ (legitimate_offset_address_p): Don't test modes in an attempt to
+ distinguish gpr vs fpr mem loads/stores. Don't prohibit offsets
+ invalid for 64-bit gpr loads/stores here.
+ (secondary_reload_class): Add "inp" parameter. Generate a reload
+ for 64-bit gpr loads/stores.
+ * config/rs6000/rs6000.h (SECONDARY_RELOAD_CLASS): Delete.
+ (SECONDARY_INPUT_RELOAD_CLASS, SECONDARY_OUTPUT_RELOAD_CLASS): Define.
+ (PREDICATE_CODES): Add invalid_gpr_mem and base_reg_operand.
+ (DISPARAGE_RELOAD_CLASS): Define.
+ * config/rs6000/rs6000-protos.h (secondary_reload_class): Update.
+ * config/rs6000/rs6000.md (movdf_hardfloat64): Correct attrs.
+ Add m->b alternative and split.
+ (movdi_internal64): Replace r->m and m->r with r->Y and Y->r.
+ Add m->b alternative and split.
+ * reload.c (find_reloads): Invoke DISPARAGE_RELOAD_CLASS.
- * invoke.texi (Spec Files): Wrap if-exists-else example.
- (MCore): Remove duplicate @itemx entries and @opindex entries.
+2004-03-10 Hans-Peter Nilsson <hp@axis.com>
-2003-04-15 Ulrich Weigand <uweigand@de.ibm.com>
+ PR other/14474
+ * doc/md.texi (Pattern Ordering, Dependent Patterns)
+ (Jump Patterns, Looping Patterns): Wrap in separate "@ifset
+ INTERNALS".
- * unwind.inc (_Unwind_Backtrace): New function.
- * unwind.h (_Unwind_Backtrace): Declare it.
- * libgcc-std.ver (_Unwind_Backtrace): Export it.
+2004-03-09 Zack Weinberg <zack@codesourcery.com>
-2003-04-15 Jason Merrill <jason@redhat.com>
+ * config/ia64/hpux.h (MULTILIB_DEFAULTS): Define.
+ (LIBGCC_SPEC): Update to match.
+
+2004-03-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * config/h8300/t-rtems (h8300-*-rtems*): New.
+ * config.gcc: Use config/h8300/t-rtems.
+
+2004-03-09 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/14289
+ * c-typeck.c (c_mark_addressable): A register variable should
+ be considered global if its not automatic, i.e. TREE_PUBLIC,
+ TREE_STATIC or DECL_EXTERNAL.
+ * function.c (put_var_into_stack): Call abort when placing a
+ hard register into the stack, if x_parm_reg_stack_loc is NULL.
+
+2004-03-08 David Edelsohn <edelsohn@gnu.org>
+
+ * collect2.c (main): Only export initfunc and finifunc if
+ LD_INIT_SWITCH not defined.
+ (scan_prog_file): Only export constructors and destructors if
+ LD_INIT_SWITCH not defined. Only export symbols not found in
+ shared objects.
+
+2004-03-09 Alan Modra <amodra@bigpond.net.au>
+
+ * doc/tm.texi (INIT_CUMULATIVE_ARGS): Update doco.
+ * calls.c (expand_call): Pass n_named_args to INIT_CUMULATIVE_ARGS.
+ (emit_library_call_value_1): Likewise pass nargs.
+ * expr.c (block_move_libcall_safe_for_call_parm): Pass 3 here.
+ * function.c (assign_parms): Pass -1 to INIT_CUMULATIVE_ARGS.
+ * config/rs6000/rs6000.c (init_cumulative_args): Use n_named_args
+ parameter instead of scanning TYPE_ARGS_TYPES to count args.
+ * config/rs6000/rs6000-protos.h (init_cumulative_args): Update
+ prototype.
+ * config/rs6000/rs6000.h (INIT_CUMULATIVE_ARGS): Pass extra arg.
+ (INIT_CUMULATIVE_INCOMING_ARGS): Set extra arg to 1000.
+ (INIT_CUMULATIVE_LIBCALL_ARGS): Set extra arg to 0.
+ * config/sh/sh.c (sh_output_mi_thunk): Pass 1 as n_named_args to
+ INIT_CUMULATIVE_ARGS.
+ * config/alpha/alpha.h (INIT_CUMULATIVE_ARGS): Update.
+ * config/alpha/unicosmk.h, config/alpha/vms.h, config/arc/arc.h,
+ config/arm/arm.h, config/avr/avr.h, config/c4x/c4x.h,
+ config/cris/cris.h, config/d30v/d30v.h, config/dsp16xx/dsp16xx.h,
+ config/fr30/fr30.h, config/frv/frv.h, config/h8300/h8300.h,
+ config/i370/i370.h, config/i386/i386.h, config/i860/i860.h,
+ config/i960/i960.h, config/ia64/ia64.h, config/ip2k/ip2k.h,
+ config/iq2000/iq2000.c, config/iq2000/iq2000.h, config/m32r/m32r.h,
+ config/m68hc11/m68hc11.h, config/m68k/m68k.h, config/mcore/mcore.h,
+ config/mips/mips.h, config/mmix/mmix.h, config/mn10300/mn10300.h,
+ config/ns32k/ns32k.h, config/pa/pa.h, config/pdp11/pdp11.h,
+ config/s390/s390.h, config/sh/sh.h, config/sparc/sparc.h,
+ config/stormy16/stormy16.h, config/v850/v850.h, config/vax/vax.h,
+ config/xtensa/xtensa.h: Likewise.
+
+2004-03-09 Alan Modra <amodra@bigpond.net.au>
+
+ PR debug/11983
+ * dwarf2out.c (enum dw_val_class): Rename dw_val_class_float to
+ dw_val_class_vec. Replace use throughout file.
+ (dw_float_const): Delete.
+ (dw_vec_const): New.
+ (dw_val_struct_union): Rename val_float to val_vec. Replace use
+ throughout file.
+ (add_AT_vec): Rename from add_AT_float. Add elt_size param.
+ (same_dw_val_p): Adjust vec comparison. Use memcmp.
+ (size_of_die): Adjust dw_val_class_vec sizing.
+ (output_die): Output dw_val_class_vec.
+ (insert_int, extract_int, insert_float): New functions.
+ (add_const_value_attribute): Use insert_float for CONST_DOUBLE.
+ Handle CONST_VECTOR.
+ (add_location_or_const_value_attribute): Handle CONST_VECTOR.
+
+2004-03-08 Joel Sherrill <joel@oarcorp.com>
+
+ PR target/14480
+ * config/rs6000/t-rtems: Add missing file on branch.
+
+2004-03-08 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold) <EQ_EXPR>: Rewrite optimization to transform
+ "foo++ == const" into "++foo == const+incr".
+
+2004-03-08 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*extendqidi2_short_displ"): Add CC clobber.
+ ("*extendqisi2_short_displ"): Likewise.
+
+2004-03-08 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * expr.c (highest_pow2_factor_for_type): Rename into
+ highest_pow2_factor_for_target. Use DECL_ALIGN instead of
+ TYPE_ALIGN when the target is a COMPONENT_REF.
+ (expand_assignment): Ajust call to highest_pow2_factor_for_type.
+
+2004-03-08 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c: Formatting fix.
+ (legitimate_offset_address_p): Correct offset range check.
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Don't override
+ -msoft-float by -mcpu. Consolidate similar code for MASK_MULTIPLE
+ and MASK_STRING.
+
+2004-03-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.md (ashrdi3): Do not call ashrdi3_no_power
+ for little endian.
+ ("ashrdi3_no_power"): Disable for little endian.
+ (ashrdi3): Same.
+
+2004-03-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_parse_abi_options): SPE and
+ AltiVec abi cannot co-exist.
+
+ * config/rs6000/eabispe.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Same.
+
+2004-03-07 Hans-Peter Nilsson <hp@axis.com>
+
+ PR target/14471
+ * configure.ac (Target-specific assembler checks) <cris-*-*>: New
+ case, checking for -no-mul-bug-abort option.
+ * configure, config.in: Regenerate.
+ * doc/invoke.texi (CRIS Options): Document -mmul-bug-workaround
+ and -mno-mul-bug-workaround.
+ * config/cris/cris.md ("smulsi3_highpart", "umulsi3_highpart")
+ ("mulsidi3", "umulsidi3"): Prefix output template with "%!".
+ ("umulhisi3", "umulqihi3", "mulsi3", "mulqihi3", "mulhisi3"):
+ Ditto. Make attribute "slottable" dependent on TARGET_MUL_BUG.
+ * config/cris/mulsi3.asm (__Mul) [__CRIS_arch_version >= 10]: Make
+ sure mulu.d is not last on cache-line.
+ * config/cris/cris.h (ASM_SPEC): Translate -mno-mul-bug-workaround
+ into -no-mul-bug-abort depending on HAVE_AS_MUL_BUG_ABORT_OPTION.
+ (TARGET_MASK_MUL_BUG, TARGET_MUL_BUG): New macros.
+ (TARGET_SWITCHES): New options -mmul-bug-workaround and
+ -mno-mul-bug-workaround.
+ (TARGET_DEFAULT): Include TARGET_MASK_MUL_BUG.
+ (PRINT_OPERAND_PUNCT_VALID_P): Include '!'.
+ * config/cris/cris.c (cris_operand_extend_operator): Clarify
+ relation to MULT in head comment.
+ (cris_op_str): Abort for MULT.
+ (cris_print_operand) <case '!'>: New case.
+
+2004-03-07 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("*lshrsi3_const"): Disable for 68HC12.
+ ("*lshrsi3"): Also accept an immediate for 68HC12.
+ ("*ashrsi3_const"): Likewise.
+ ("*ashrsi3"): Likewise.
+ ("*ashlsi3_const"): Likewise.
+ ("*ashlsi3"): Likewise.
+ ("cmphi_1_hc12"): Compare two hard register by pushing them and
+ comparing with a pop; don't use a split for that.
+ ("cmphi split"): Disable compare split for 68HC12.
- PR middle-end/10336, c++/10401
- * jump.c (never_reached_warning): Also stop looking if we reach the
- beginning of the function.
+ * config/m68hc11/m68hc11.c (m68hc11_notice_update_cc): Invalidate
+ the status operands if they have side effects.
-2003-04-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+2004-03-07 Richard Sandiford <rsandifo@redhat.com>
- PR target/10338
- PR bootstrap/10198
- PR bootstrap/10140
- * fixinc/gnu-regex.c (regerror): Use mempcpy not __mempcpy.
+ * config/mips/mips.c (mips_in_small_data_p): Return false if
+ TARGET_ABICALLS.
-2003-04-15 Jakub Jelinek <jakub@redhat.com>
+2004-03-06 Stephane Carrez <stcarrez@nerim.fr>
- * config/rs6000/rs6000.h (EPILOGUE_USES): Use register 2,
- instead of TOC_REGISTER in epilogue in
- current_function_calls_eh_return functions.
+ * config/m68hc11/m68hc11.c (m68hc11_gen_movhi): Use 2,-sp to push
+ the stack register.
+ (expand_prologue): Don't make an interrupt or a trap handler a far
+ symbol.
+ (m68hc11_initial_elimination_offset): Likewise.
-2003-04-14 Hans-Peter Nilsson <hp@axis.com>
+2004-03-06 Richard Henderson <rth@redhat.com>
- PR target/10377
- * config/cris/cris.md ("*mov_sideqi", "*mov_sidehi")
- ("*mov_sidesi", "*mov_sideqi_mem", "*mov_sidehi_mem")
- ("*mov_sidesi_mem", "*clear_sidesi", "*clear_sidehi")
- ("*clear_sideqi", "*ext_sideqihi", "*ext_sideqisi")
- ("*ext_sidehisi", "*op_sideqi", "*op_sidehi", "*op_sidesi")
- ("*op_swap_sideqi", "*op_swap_sidehi", "*op_swap_sidesi")
- ("*extopqihi_side", "*extopqisi_side", "*extophisi_side")
- ("*extopqihi_swap_side", "*extopqisi_swap_side")
- ("*extophisi_swap_side", 8th, 9th, 10th, 11th, 14th peepholes):
- When next to constraint R, replace constraint i with n.
+ * config/alpha/alpha.c (alpha_in_small_data_p): False for functions.
-Mon Apr 14 16:14:37 CEST 2003 Jan Hubicka <jh@suse.cz>
+2004-03-06 Richard Henderson <rth@redhat.com>
- PR opt/10024
- * cfgrtl.c (force_nonfallthru_and_redirect): Use unchecked_make_edge.
+ * config/alpha/alpha.h (MASK_LONG_DOUBLE_128): New.
+ (TARGET_LONG_DOUBLE_128): New.
+ (TARGET_SWITCHES): Add long-double-{128,64}.
+ (TARGET_HAS_XFLOATING_LIBS): Default to TARGET_LONG_DOUBLE_128.
+ (LONG_DOUBLE_TYPE_SIZE): Honor TARGET_LONG_DOUBLE_128.
+ (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): New.
+ (WIDEST_HARDWARE_FP_SIZE): New.
+ (TARGET_CPU_CPP_BUILTINS): Define __LONG_DOUBLE_128__.
+ * config/alpha/alpha.c (override_options): Clear MASK_LONG_DOUBLE_128
+ if TARGET_VAX_FLOAT.
+ * config/alpha/osf5.h (LONG_DOUBLE_TYPE_SIZE): Remove.
+ (TARGET_DEFAULT): Set MASK_LONG_DOUBLE_128.
-2003-04-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+2004-03-06 Ulrich Weigand <uweigand@de.ibm.com>
- * doc/contrib.texi (Contributors): Correct my entry.
+ * config/s390/s390.md ("load_multiple", "*load_multiple_di",
+ "*load_multiple_si"): Allow only if reload_completed.
+ ("store_multiple", "*store_multiple_di", "*store_multiple_si"):
+ Likewise.
-2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
+2004-03-06 Eric Botcazou <ebotcazou@libertysurf.fr>
- * config/m68hc11/m68hc11-protos.h
- (m68hc11_eq_compare_operator): Declare
- * config/m68hc11/m68hc11.h (PREDICATE_CODES): Register new predicate.
- * config/m68hc11/m68hc11.c (m68hc11_eq_compare_operator): New predicate
- (d_register_operand): Check the operand mode.
- (hard_addr_reg_operand): Likewise.
+ PR c/14465
+ PR c/14114
+ * c-decl (pushdecl): Revert previous change.
-2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
+2004-03-06 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
- * config/m68hc11/m68hc11.md ("decrement_and_branch_until_zero"): New
- pattern for dbcc/ibcc generation for 68HC12.
- ("doloop_end"): New pattern.
- ("m68hc12_dbcc_dec_hi"): New pattern for dbeq/dbne.
- ("m68hc12_dbcc_inc_hi"): New pattern for ibeq/ibne.
- ("m68hc12_dbcc_dec_qi"): New pattern.
- ("m68hc12_dbcc_inc_qi"): New pattern.
- (split): Add split for the above when we can't use dbcc/ibcc due to
- reloading.
- (peephole2): Add peephole2 to generate the above when possible.
+ * pa.md (icacheflush): Reorder operands to make match_scratch operand
+ last.
+ * pa.h (INITIALIZE_TRAMPOLINE): Remove unnecessary scratch argument
+ from calls to gen_icacheflush.
-2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
+2004-03-06 Eric Botcazou <ebotcazou@libertysurf.fr>
- * config/m68hc11/m68hc11.md ("bitcmpqi" split): No need to test the
- mode of operand 0.
- (peephole2 optimize const load): Likewise for operand 2.
- ("*rotlhi3_with_carry"): Change pattern to a const 1 rotate which
- clobbers CC_REGNUM.
- ("*rotrhi3_with_carry"): Likewise.
- (ashift:DI 1 split): Update pattern to create the above rotate.
- (lshiftrt:DI 1 split): Likewise.
+ PR target/14343
+ * config/i386/i386.md (movv2di_internal): Conditionalize on
+ TARGET_SSE, not TARGET_SSE2.
-2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
+2004-03-06 Eric Botcazou <ebotcazou@libertysurf.fr>
- * config/m68hc11/m68hc11.md (SOFT_Z_REGNUM): New constant.
- ("tstqi_z_used" split): Use it.
- ("cmphi_z_used"): Likewise.
- ("bitcmpqi_z_used"): Likewise; also use SP_REGNUM constant.
- ("cmpqi_z_used"): Likewise.
+ PR c/14114
+ * c-decl (pushdecl): Do not record a previous, not-in-scope,
+ external decl for restoration.
-2003-04-12 Mark Mitchell <mark@codesourcery.com>
+2004-03-05 Waldek Hebisch <hebisch@math.uni.wroc.pl>
- PR c++/7910
- * config/i386/winnt.c (i386_pe_mark_dllimport): Fix thinko.
+ PR middle-end/14203
+ * function.c (uninitialized_vars_warning): Use DECL_RTL_SET_P
+ instead of testing whether DECL_RTL is not NULL.
-2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
+2004-03-05 Andreas Krebbel <krebbel1@de.ibm.com>
- * config/m68hc11/m68hc11.h (TARGET_SWITCHES): Fix -mnominmax option;
- recognize -mnorelax.
- (reg_class): Add Z_OR_S_REGS to represent soft registers with Z
- (REG_CLASS_NAMES): Add its name.
- (REG_CLASS_CONTENTS): Define its content.
+ * rtl.h (mem_expr_equal_p): Function prototype added.
+ * cfgcleanup.c (merge_memattrs): New function.
+ (flow_find_cross_jump): Call merge_memattrs for matching insns.
+ * emit-rtl.c (mem_expr_equal_p): New function.
-2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
+2004-03-05 Bob Wilson <bob.wilson@acm.org>
- * config/m68hc11/larith.asm (memcpy): Use ARG macro to access stack
- parameters so that offsets are valid for far definition.
- (__mulsi3): Likewise and use ret to return.
- (___adddi3, ___subdi3, ___notdi2, ): Don't use it to save the result.
+ * config/xtensa/xtensa.c (function_arg): Handle 16-byte aligned args.
+ (xtensa_va_start): Initialize __va_stk to ($arg_ptr - 32). Adjust
+ __va_ndx by 2 words when referencing an argument on the stack.
+ (xtensa_va_arg): Handle 16-byte aligned args. Adjust __va_ndx by 2
+ words when an arg on the stack is first seen.
-2003-04-11 Geoffrey Keating <geoffk@apple.com>
+2004-03-05 Nathan Sidwell <nathan@codesourcery.com>
- * doc/extend.texi (Empty Structures): New.
+ PR driver/13577
+ * gcc.c (cc1_options): Robustify -auxbase-strip from multiple -o
+ options.
-2003-04-11 Richard Henderson <rth@redhat.com>
+2004-03-04 Bob Wilson <bob.wilson@acm.org>
- PR c++/10202
- * expr.c (expand_expr): Use COMPLETE_OR_UNBOUND_ARRAY_TYPE_P
- not COMPLETE_TYPE_P for re-invoking layout_decl.
+ * config/xtensa/xtensa.c (xtensa_return_in_msb): New function.
+ (TARGET_RETURN_IN_MSB): Define to xtensa_return_in_msb.
-2003-04-11 Simon Law <sfllaw@engmail.uwaterloo.ca>
+2004-03-04 Alan Modra <amodra@bigpond.net.au>
- * doc/bugreport.texi: Fix paragraph breaking between sections
- in preparation for TeXinfo's paragraph indentation fixes.
- * doc/extend.texi: Ditto.
- * doc/invoke.texi: Ditto.
- * doc/objc.texi: Ditto.
- * doc/gcov.texi: Wrap 'gcov' in @command{}.
- * doc/invoke.texi (Darwin Options): Add a preamble.
+ * real.c (encode_ibm_extended): Don't bother rounding low double.
+ * c-cppbuiltin.c (builtin_define_float_constants): Tweak MAX
+ when fmt->pnan < fmt->p.
-2003-04-11 Richard Henderson <rth@redhat.com>
+2004-03-04 Alan Modra <amodra@bigpond.net.au>
- PR c/10201
- * expr.c (expand_expr): Move DECL_RTL frobbing ...
- * stor-layout.c (layout_decl): ... here.
+ PR target/14406
+ * config/rs6000/rs6000.md (abstf2, abstf2+1): Delete define_insn.
+ (abstf2, abstf2_internal): New define_expand.
-2003-04-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2004-03-04 Eric Botcazou <ebotcazou@libertysurf.fr>
- * doc/install.texi (hppa): Update links for HP-UX patches. Revise
- notes on linker selection and configuration for 64-bit HP-UX port.
- * doc/invoke.texi (hppa): Remove hppa text from description for
- -ffunction-sections and -fdata-sections. Document -static, -nolibdld
- and -threads options.
+ PR optimization/14235
+ * expr.c (convert_move): Copy the source to a new pseudo
+ when converting from a sub-word source to a larger-than-word
+ register which conflicts with the source.
- * pa-hpux10.h (LIB_SPEC): Add link options to resolve dependency of
- libc.a on libdld.sl when -static is specified and -nolibdld is not
- specified.
- * pa64-hpux.h (LIB_SPEC): Likewise.
- * pa-hpux11.h (LIB_SPEC): Likewise.
- (LINK_SPEC): Add __gcc_plt_call as an undefined symbol when -shared
- is not specified.
+2004-03-03 Zack Weinberg <zack@codesourcery.com>
-2003-04-08 Jonathan Wakely <redi@gcc.gnu.org>
+ PR 13728
+ * c-decl.c (diagnose_mismatched_decls): Issue an error for two
+ parameters with the same name, unless one is a forward decl.
+ Do not issue a redundant-redeclaration warning for forward
+ decls of parameters.
- * doc/extend.texi (Template Instantiation): Refer to ISO standard,
- not Working Paper.
- * doc/invoke.texi (C++ Dialect Options): Same.
+2004-03-03 Stephane Carrez <stcarrez@nerim.fr>
-Fri Apr 11 00:12:14 CEST 2003 Jan Hubicka <jh@suse.cz>
+ * config/m68hc11/m68hc11.c (m68hc11_override_options): Disable -fweb
+ because it breaks the 32-bit shift patterns that rely on a match_dup.
+ (print_operand): Don't print a * before the base address.
- PR inline-asm/8803
- * function.c (instantate_virtual_regs): Verify that all ASM statements
- match after the virutal regs instantiation.
+2003-03-03 Richard Henderson <rth@redhat.com>
-2003-04-10 Steve Ellcey <sje@cup.hp.com>
+ PR opt/13862
+ * cselib.c (cselib_record_sets): Don't record multiple sets in
+ asm insns.
+
+2004-03-03 Nicolas Pitre <nico@cam.org>
+
+ * config/arm/ieee754-df.S (muldf3, divdf3): Fix denormalization of
+ small negative values.
+
+2004-03-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (___fixunssfsi): Change the
+ threshold to 0x4f.
+
+ Revert:
+ 2004-02-27 Kazu Hirata <kazu@cs.umass.edu>
+ * config/h8300/fixunssfsi.c (__fixunssfsi): Enable on H8/300
+ as well.
+ * config/h8300/lib1funcs.asm (___fixunssfsi): Remove.
+ * config/h8300/t-h8300 (LIB1ASMFUNCS): Remove _fixunssfsi_asm.
+
+2004-03-02 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/11767
+ * coverage.c (coverage_counter_ref): Set MEM_NOTRAP_P.
+ * optabs.c (prepare_cmp_insn): Force trapping memories to registers
+ before the compare, if flag_non_call_exceptions.
+
+2004-03-02 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/14327
+ * stmt.c (expand_computed_goto): Do do_pending_stack_adjust before
+ emitting the label, not after.
+
+2004-03-02 David O'Brien <obrien@FreeBSD.org>
+
+ * config/freebsd-spec.h (FBSD_DYNAMIC_LINKER): Add.
+ * config/alpha/freebsd.h (SUBTARGET_EXTRA_SPECS): Define
+ %(fbsd_dynamic_linker),
+ (LINK_SPEC): Use %(fbsd_dynamic_linker), and sync style with
+ config/i386/freebsd.h
+ * config/arm/freebsd.h: Ditto.
+ * config/i386/freebsd.h: Ditto.
+ * config/i386/freebsd64.h: Ditto.
+ * config/ia64/freebsd.h: Ditto.
+ * config/rs6000/sysv4.h: Ditto.
+ * config/sparc/freebsd.h: Ditto.
+
+2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (m68hc11_addr_mode): New variable.
+ (m68hc11_mov_addr_mode): Likewise.
+ (m68hc11_override_options): Initialize them based on target.
+ (register_indirect_p): Allow a MEM for indirect addressing modes and
+ use flags to control what is allowed.
+ (m68hc11_small_indexed_indirect_p): Use m68hc11_mov_addr_mode for
+ supported addressing modes.
+ (m68hc11_register_indirect_p): Use m68hc11_addr_mode.
+ (go_if_legitimate_address_internal): Likewise.
+ (m68hc11_indirect_p): Likewise and check the mode.
+ (print_operand): Allow a (MEM (MEM)) and generate indirect addressing.
+
+2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md (move peephole2): New peepholes to optimize
+ sequences of moves.
+ (add peepholes): New peepholes to optimize sequences adding small
+ constants.
+ (bset peepholes): New peepholes to transform an OR in a bset form
+ (bclr peepholes): Likewise for bclr form.
+ (cmp peepholes): New peepholes to avoid register copies when comparing.
+
+2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("*pushdi_internal"): New insn and split
+ to separate push from moves.
+ ("*pushdf_internal"): Likewise.
+ ("*pushsf_internal"): Likewise.
+ ("*pushsi_internal"): Likewise.
+ ("movdi_internal"): Use define_insn_and_split; non push operand.
+ ("movdf_internal"): Likewise.
+ ("movsf_internal"): Likewise.
+ ("movsi_internal"): Likewise.
+ ("*movhi_68hc12", "*addhi3_68hc12"): Fix and tune constraints
+ ("*addhi3", "*subhi3", "*andhi3_mem", "*iorhi3_mem"): Likewise.
+ ("*ashlsi3_const1", "*lshrsi3_const1"): Likewise.
- * ia64-protos.h (addp4_optimize_ok): New.
- * ia64.c (addp4_optimize_ok): New.
- * ia64.md (*ptr_extend_plus_1): Use addp4_optimize_ok.
- (*ptr_extend_plus_2): Ditto.
+2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
-2003-04-10 Steve Ellcey <sje@cup.hp.com>
+ * config/m68hc11/m68hc11.md ("tstqi_z_used"): Use define_insn_and_split.
+ ("cmphi_z_used", "cmpqi_z_used"): Likewise.
+ ("movstrictsi", "movstricthi", "movstrictqi"): Likewise.
+ ("anddi3", "andsi3", "iordi3", "iorsi3"): Likewise.
+ ("xordi3", "xorsi3", "*logicalsi3_zexthi"): Likewise.
+ ("*logicalsi3_zextqi", "*logicalhi3_zexthi_ashift8"): Likewise.
+ ("logicalhi3_zexthi", "*logicalsi3_silshr16"): Likewise.
+ ("*logicalsi3_silshl16", "*logicalsi3_silshl16_zext"): Likewise.
+ ("*ashldi3_const32", "*ashldi3_const1", "addsi_silshr16"): Likewise.
+ ("addsi_andshr16", "*ashlsi3_const16_zexthi"): Likewise.
+ ("*lshrdi3_const32", "*lshrdi_const1"): Likewise.
- * expr.c (expand_assignment): Extend offset_rtx with convert_to_mode
- not with convert_memory_address.
- (store_constructor): Ditto, and same for copy_size_rtx.
- (expand_expr): Ditto.
+2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
-2003-04-10 Ulrich Weigand <uweigand@de.ibm.com>
+ * config/m68hc11/m68hc11.md (SOFT_TMP_REGNUM): Define.
+ (SOFT_XY_REGNUM): Define.
+ (cmp split): Use the above instead of hard coded numbers.
+ (8-bit op split): No need to check the mode; allow Q_REG.
+ (ashift split): Adjust the first operand if it uses the SP and we
+ are pushing the shifted value.
+ (plus shift split): Fix when a source is in register D+X.
+ ("doloop_end"): Pass dummy arguments to gen_rtx_NE.
- * config/s390/s390.c (larl_operand): Do not allow symbols
- marked with '@'.
- (s390_encode_section_info): Mark symbols with forced 1-byte
- alignment with '@'.
- (s390_strip_name_encoding): Strip '@'.
- (legitimize_pic_address): Handle symbols that are not valid
- LARL operands in 64-bit mode.
+2004-03-02 Stephane Carrez <stcarrez@nerim.fr>
-2003-04-10 Andrew Haley <aph@redhat.com>
+ * config/m68hc11/m68hc11.c (m68hc11_check_z_replacement): Fix when
+ comparing with Z register.
- * tree-inline.c (inlinable_function_p): Disable inlining for
- synchronized methods.
+2004-03-02 Loren James Rittle <ljrittle@acm.org>
-2003-04-09 Alexandre Oliva <aoliva@redhat.com>
+ * gcc/doc/install.texi (*-*-freebsd*): Update target information.
- * config/fp-bit.c (unpack_d): Handle pair of doubles with
- different signs correctly.
+2004-03-01 Mark Mitchell <mark@codesourcery.com>
-2003-04-08 Richard Henderson <rth@redhat.com>
+ PR bootstrap/14356
+ * gcc.c (process_command): Remove const-qualification from argv.
+ (main): Likewise.
- PR target/9886
- * config/ia64/ia64.md (cmovdi_internal): Use 'n' not 'i' constraints.
- (cmovsi_internal): Likewise.
+2004-03-01 Mircea Namolaru <namolaru@il.ibm.com>
-2003-04-07 Matt Kraai <kraai@alumni.cmu.edu>
+ * cfgloop.h (get_var_set_from_bct, is_bct_cond): Declaration of
+ new functions.
+ * cfgloopanal.c: Include loop.h.
+ (get_var_set_from_bct): New function.
+ (is_bct_cond): New function.
+ (blocks_single_set_registers): Handle branch and count jumps.
+ (count_loop_iterations): Likewise.
+ (simple_increment): Likewise
+ * doloop.c (doloop_condition_get): Export.
+ * loop-init.c (fixup_loop_exit_succesor): New function.
+ (loop_optimizer_finalize): Handle loops ending with branch and
+ count jumps.
+ * loop-unroll.c: Include toplev.h
+ (discard_increment): New function.
+ (expand_bct): New function.
+ (peel_loop_completely): Handle the removal of branch and count jumps.
+ (unroll_loop_constant_iterations): Likewise.
+ (unroll_loop_runtime_iterations): Likewise
+ * loop.h (doloop_condition_get): Declare.
- * doc/install.texi: Use @command and @samp for single- and
- multi-word commands respectively.
- * doc/makefile.texi: Likewise.
- * doc/sourcebuild.texi: Likewise.
+2004-02-29 Mark Mitchell <mark@codesourcery.com>
-2003-04-07 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
- Richard Henderson <rth@redhat.com>
+ PR debug/14328
+ * dwarf2out.c (gen_enumeration_type_die): Output all enumeration
+ constants as signed values.
- PR c/9516
- * expr.c (safe_from_p): Rearrange to avoid deep recursion in
- favour of looping and tail recursion for TREE_LIST and binops.
+2004-02-29 Mark Mitchell <mark@codesourcery.com>
-2003-04-07 Glen Nakamura <glen@imodulo.com>
+ PR middle-end/13448
+ * c-tree.h (readonly_warning): Rename to ...
+ (readonly_error): ... this.
+ * c-typeck.c (build_unary_op): Adjust accordingly.
+ (readonly_warning): Rename to ...
+ (readonly_error): ... this and issue errors, not warnings.
+ (build_modify_expr): Call readonly_error, not readonly_warning.
+ (c_expand_asm_operands): Likewise.
+ * tree-inline.c (optimize_inline_calls): Do not inline functions
+ after errors have occurred.
- PR opt/8634
- * explow.c (maybe_set_unchanging): Don't flag non-static const
- aggregate type initializers with RTX_UNCHANGING_P.
+2004-02-29 Kazu Hirata <kazu@cs.umass.edu>
-2003-04-07 Richard Henderson <rth@redhat.com>
+ * doc/cppopts.texi: Fix a typo.
- PR opt/8634
- * function.c (purge_addressof_1): Don't try arithmetics for
- unchanging memories.
+2004-02-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-2003-04-07 Janis Johnson <janis187@us.ibm.com>
+ * pa64-hpux.h (LIB_SPEC): Fix linking under HP-UX 11.00 with -p and -pg.
- * doc/sourcebuild.texi (Test Suites): Document testing support for
- gcov and profile-directed optimizations; describe gcc.misc-tests.
+2004-02-27 Ian Lance Taylor <ian@wasabisystems.com>
-2003-04-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+ PR optimization/7871
+ * flow.c (mark_set_1): Don't add LOG_LINKS for global registers
+ from or to call insns.
- * doc/rtl.texi (Comparison operations): Update to
- record the allowed comparison modes.
+2004-02-27 Eric Botcazou <ebotcazou@libertysurf.fr>
-Mon Apr 7 22:13:38 CEST 2003 Jan Hubicka <jh@suse.cz>
+ PR optimization/7871
+ * flow.c (propagate_one_insn): Interpret calls as setting global
+ registers, not merely clobbering them.
- PR target/10077
- * i386.md (movsi_1): Fix SSEMOV alternative.
+2004-02-27 Kazu Hirata <kazu@cs.umass.edu>
-Mon Apr 7 15:56:30 CEST 2003 Jan Hubicka <jh@suse.cz>
+ * config/h8300/fixunssfsi.c (__fixunssfsi): Enable on H8/300
+ as well.
+ * config/h8300/lib1funcs.asm (___fixunssfsi): Remove.
+ * config/h8300/t-h8300 (LIB1ASMFUNCS): Remove _fixunssfsi_asm.
- PR opt/10024
- Revert Zack's change
- * cfglayout.c (cfg_layout_redirect_edge):
- Redirect any branch edges unified with the fallthru one.
- * cfgrtl.c (force_nonfallthru_and_redirect): Do not special
- case fallthru edges when called via cfglayout.c
+2004-02-27 Daniel Jacobowitz <drow@mvista.com>
-2003-04-07 James A Morrison <ja2morri@student.math.uwaterloo.ca>
+ * config/arm/arm.c (arm_legitimate_address_p): Don't check the mode
+ size for minipool references.
- * doc/extend.texi (Darwin Pragmas): Fix spelling of Mac OS.
+2004-02-27 Eric Botcazou <ebotcazou@act-europe.fr>
+ Roger Sayle <roger@eyesopen.com>
-2003-04-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+ * fold-const.c (fold): Revert 2004-02-25 change. Use the original
+ operands to build a tree with swapped operands.
+ * expr.c (expand_expr_real) <MAX_EXPR>: Consistently use the
+ 'unsignedp' predicate to specify the signedness.
- * c-decl.c (set_save_expr_context): Prototype.
+2004-02-26 Aldy Hernandez <aldyh@redhat.com>
-2003-04-05 David Edelsohn <edelsohn@gnu.org>
+ * config/rs6000/rs6000.md: Add fixuns_truncsfsi2 and
+ fix_truncsfsi2.
- * config/rs6000/rs6000.h (RTX_COSTS): Halve Power multiply costs.
- * config/rs6000/rs6000.md: Correct Power4 multiply latency.
+ * config/rs6000/spe.md: Delete spe_efsctuiz.
+ Add spe_fixuns_truncsfsi2.
+ Add spe_fix_truncsfsi2.
-2003-04-05 Zack Weinberg <zack@codesourcery.com>
+2004-02-26 Bob Wilson <bob.wilson@acm.org>
- PR optimization/10024
- * cfgrtl.c (force_nonfallthru_and_redirect): If e is the edge
- we want, use it.
+ * config/xtensa/xtensa.h (TARGET_CPU_CPP_BUILTINS): Define __xtensa__.
-2003-04-05 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+2004-02-25 James E Wilson <wilson@specifixinc.com>
- PR bootstrap/10267
- * doc/install.texi (*-*-solaris2): /bin/ksh is not just recommended
- for configuring.
+ * gcc-simple.c (rtl_zone, tree_zone, garbage_zone, ggc_alloc_typed,
+ ggc_alloc_zone): New.
+ (ggc_pch_count_object, gcc_pch_alloc_object, ggc_pch_write_object):
+ Add bool is_string parameter.
-2003-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+2004-02-26 Alan Modra <amodra@bigpond.net.au>
- * c-decl.c (set_save_expr_context): Use traditional-style function
- definition.
+ * gcse.c (delete_null_pointer_checks_1): Set stop_insn to end, not
+ beginning of block. Do not delete CC setter unless HAVE_cc0.
-2003-04-04 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+2004-02-25 Kelley Cook <kcook@gcc.gnu.org>
- * doc/contrib.texi (Contributors): Add entries for Wolfgang
- Bangerth, DJ Delorie, Christian Ehrhardt, Christopher Faylor,
- Nathanael Nerode, Diego Novillo, Hartmut Penner, Volker Reichelt,
- Danny Smith, and Ulrich Weigand.
- Update Kriang Lerdsuwanakij and fix a typo in Janis Johnson's
- entry.
+ * doc/contrib.texi: Add an entry for myself.
-2003-04-04 Zack Weinberg <zack@codesourcery.com>
+2004-02-25 Kelley Cook <kcook@gcc.gnu.org>
- PR bootstrap/10216
- * configure.in: Check whether it is necessary to link against
- libm to use ldexp.
+ * config.gcc: Add comment describing extra_gcc_objs.
+ i[34567]86-*-cygwin*): Replace host_extra_gcc_objs with extra_gcc_objs.
+ * configure.ac (extra_gcc_objs): New substitution variable.
+ (host_extra_gcc_objs): Don't substitute.
* configure: Regenerate.
- * Makefile.in: Add LDEXP_LIB substitution variable.
-
-2003-04-03 Jason Merrill <jason@redhat.com>
-
- PR c/10175
- * jump.c (never_reached_warning): Revert patch of 2002-11-02.
- Look backwards for a line note.
-
-2003-04-02 Mike Stump <mrs@apple.com>
-
- * doc/extend.texi (PowerPC AltiVec Built-in Functions): Split up
- some to avoid faulting makeinfo --html.
-
-2003-04-02 Richard Henderson <rth@redhat.com>
-
- * libgcc-std.ver (_Unwind_GetCFA): New.
- * unwind-dw2.c (_Unwind_GetCFA): New.
- * unwind-sjlj.c (_Unwind_GetCFA): New.
- * unwind.h: Declare it.
-
-2003-04-02 Mike Stump <mrs@apple.com>
-
- * doc/install.texi (Specific): Update pointers to apple.com.
-
-2003-04-01 Jan Hubicka <jh@suse.cz>
-
- PR inline-asm/8088
- * i386.c (ix86_hard_regno_mode_ok): Return 0 for MMX/SSE registers
- when MMX/SSE is not available.
-
-2003-04-02 Richard Henderson <rth@redhat.com>
-
- * except.c (sjlj_find_directly_reachable_regions): Recognize when
- must-not-throw region has been deleted.
-
-2003-04-02 Richard Henderson <rth@redhat.com>
-
- * dwarf2out.c (output_call_frame_info): Ignore fde->nothrow as an
- optimization when flag_exceptions not enabled.
-
-2003-04-01 Richard Henderson <rth@redhat.com>
-
- * except.c (convert_from_eh_region_ranges_1): Smash REG_EH_REGION
- notes for nothrow calls if flag_forced_unwind_exceptions.
- (build_post_landing_pads): Mind flag_forced_unwind_exceptions.
- (sjlj_find_directly_reachable_regions): Likewise.
- (reachable_handlers): Likewise.
- (can_throw_external): Likewise.
- (collect_one_action_chain): Record cleanups after catch-all and
- must-not-throw if flag_forced_unwind_exceptions.
- * flags.h (flag_forced_unwind_exceptions): Declare.
- * toplev.c (flag_forced_unwind_exceptions): New.
- (lang_independent_options): Add it.
- * doc/invoke.texi: Add it.
-
-2003-04-01 Geoffrey Keating <geoffk@apple.com>
-
- * unwind-dw2-fde-darwin.c (DESTRUCTOR_MAY_BE_CALLED_LIVE): New.
- (live_image_destructor): Reset image to initial state.
- (examine_objects): Set DESTRUCTOR_MAY_BE_CALLED_LIVE.
-
-2003-04-01 Dale Johannesen <dalej@apple.com>
-
- * cse.c (count_reg_usage): Fix handling of REG_EQUAL notes.
- (Zdenek Dvorak's fix from 3.4 branch)
-
-2003-04-01 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c (s390_fixup_clobbered_return_reg):
- Do nothing if __builtin_return_address was not used.
-
-2003-04-01 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.c (function_arg_pass_by_reference):
- Return true for variable sized types.
- (rs6000_va_arg): Handle variable sized types passed by reference
- on non-SVR4 ABI.
-
-2003-03-31 Mark Mitchell <mark@codesourcery.com>
-
- PR c/9936
- * c-decl.c (grokdeclarator): Clear SAVE_EXPR_CONTEXT for
- variably-sized arrays in parameters.
- (set_save_expr_context): New function.
- (c_expand_body): Use it, via walk_tree.
-
-2003-03-31 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.c (hard_reg_operand): Check the mode.
-
-2003-03-31 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.c (m68hc11_gen_movhi): Don't rely on REG_WAS_0
- notes as they are boggus.
- (m68hc11_gen_movqi): Likewise.
-
-2003-03-31 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.c (expand_prologue): For an interrupt handler
- save the soft registers after the frame pointer so that gdb can unwind
- the frame more easily.
- (expand_epilogue): Likewise in opposite order; allow to use X register
- as scratch if the return value is by reference.
-
-2003-03-31 Jason Merrill <jason@redhat.com>
-
- PR java/10145
- * stor-layout.c (update_alignment_for_field): Respect
- DECL_USER_ALIGN for zero-length bitfields, too.
- * c-decl.c (finish_struct): Don't set DECL_ALIGN for normal
- fields.
-
-2003-03-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- PR other/6955
- * collect2.c (collect_wait): Use WCOREDUMP and fix output message.
- * system.h (WCOREDUMP, WCOREFLG): Define if necessary.
-
-2003-03-30 Richard Henderson <rth@redhat.com>
-
- PR c/10083
- * config/alpha/alpha.md (umuldi3_highpart): Change to expander;
- don't zero_extend const inputs.
-
-2003-03-29 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/contrib.texi: Add Eric Botcazou and Roger Sayle.
- Uniformly use bugfix instead of bug fix.
-
-2003-03-29 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- PR doc/895
- * ONEWS: Remove those items that already appear in the EGCS
- release notes on our web pages.
-
-2003-03-29 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.h (FUNCTION_VALUE_REGNO_P): Respect
- TARGET_HARD_FLOAT. Reformat.
- (FUNCTION_ARG_REGNO_P): Likewise, and remove unneeded casts.
-
-2003-03-29 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c (s390_emit_prologoue): Make sure backchain is
- set up before any trapping memory access if flag_non_call_exceptions.
-
-2003-03-29 Alan Modra <amodra@bigpond.net.au>
-
- * reload1.c (reload_as_needed): Allow a USE in asm reloads.
-
- * loop.c: (find_mem_in_note_1, find_mem_in_note): Comment.
-
-2003-03-28 Loren James Rittle <ljrittle@acm.org>
-
- * doc/install.texi (*-*-freebsd*): Update with known status.
-
-2003-03-28 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.md ("literal_pool_31"): Output pool anchor
- label even if pool empty when generating PIC.
- ("literal_pool_31", "literal_pool_64"): Coding style cleanup.
-
-2003-03-28 Kazu Hirata <kazu@cs.umass.edu>,
- Dhananjay Deshpande <dhananjayd@kpit.com>
-
- PR target/10205
- * config/h8300/h8300.c (h8300_initial_elimination_offset):
- Correct the offset computation when TARGET_NORMAL.
-
-2003-03-28 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR target/10067
- * config/sparc/sparc.md (jump pattern): Correct order
- when issuing the annuling marker.
-
-2003-03-28 Alan Modra <amodra@bigpond.net.au>
-
- * loop.c: (find_mem_in_note_1, find_mem_in_note): New functions.
- (replace_loop_mems): Add "written" param. Remove invalid REG_EQUAL
- notes after hoisting.
- (load_mems): Adjust replace_loop_mems call.
-
-2003-03-28 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR c/8281
- * config/sparc/sparc.md (movdi_insn_sp32_v9): Remove 'f-f' alternative.
- (movdi reg/reg split): Match only on sparc32, and v9 when int regs.
-
-2003-03-28 Eric Botcazou <ebotcazou@libertysurf.fr>
- Richard Henderson <rth@redhat.com>
-
- PR target/10114 and PR target/10084
- * dwarf2out.c (mem_loc_descriptor): Handle LO_SUM.
-
-2003-03-27 Olivier Hainque <hainque@act-europe.fr>
-
- PR ada/9953
- * ada/Makefile.in (gnatlib configuration for HPUX): Split
- the general section for HPUX into specific sections for
- HPUX 10 and HPUX 11. Fix the setting of TGT_LIB in the HPUX
- 11 case.
-
-2003-03-26 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c (s390_optimize_prolog): Do not save/restore
- registers used for global asm variables.
- (s390_frame_info, s390_arg_frame_offset): Likewise.
- (s390_emit_prologue, s390_emit_epilogue): Likewise.
-
-2003-03-26 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/contrib.texi (Contributors): Update Janis Johnson.
-
-2003-03-26 Jakub Jelinek <jakub@redhat.com>
-
- * config/ia64/ia64.c (ia64_expand_op_and_fetch): Fix comment.
- (ia64_expand_compare_and_swap): Use always DImode ar.ccv,
- zero extend old to it.
- * config/ia64/ia64.md (cmpxchg_acq_si): Remove mode from ccv
- operand.
-
-2003-03-26 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR target/7784
- * reload.c (find_reloads_address): Handle
- (PLUS (PLUS (REG) (REG)) (CONST_INT)) form for
- all base registers.
-
-2003-03-25 Marcelo Abreu <mmabreu@inf.ufrgs.br>
-
- PR other/10203
- * version.c: Reference the GCC web site in the URL.
-
-2003-03-25 Jan Hubicka <jh@suse.cz>
-
- PR opt/10056
- * cfglayout.c (fixup_reorder_chain): Fix dealing with the conditional
- jump jumping to the next instruction.
- * cfgrtl.c (force_nonfallthru_and_redirect): Likewise.
- * cfg.c (unchecked_make_edge): New.
- * basic-block.h (unchecked_make_edge): Declare.
+ * Makefile.in: Use extra_gcc_objs.
+
+2004-02-25 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * fold-const.c (fold): Treat MAX_EXPR and MIN_EXPR like
+ comparisons with regard to signedness.
+
+2004-02-25 Jakub Jelinek <jakub@redhat.com>
+
+ * gcov-io.c (gcov_open) [GCOV_LOCKED]: Use open + fdopen instead of
+ fopen.
+ * libgcov.c: Include sys/stat.h.
+ * config/rs6000/linux.h (TARGET_HAS_F_SETLKW): Define.
+ * config/rs6000/linux64.h (TARGET_HAS_F_SETLKW): Define.
+ * config/sparc/linux.h (TARGET_HAS_F_SETLKW): Define.
+ * config/sparc/linux64.h (TARGET_HAS_F_SETLKW): Define.
+
+2004-02-25 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_legitimate_index_p): For QImode the range of an offset
+ is -4095...+4095 inclusive.
+
+2004-02-25 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/install.texi (sparc-sun-solaris2* specific notes): Document
+ the bootstrap failure with Sun CC 5.4 and 5.5.
+
+2004-02-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cse.c (cse_change_cc_mode_insns): Stop at any instruction
+ which modifies NEWREG.
+ (cse_condition_code_reg): Update the mode of CC_REG in
+ CC_SRC_INSN on our own.
+
+2004-02-24 Michael Matz <matz@suse.de>
+
+ * config/i386/i386.c (ix86_comp_type_attributes): Check for
+ regparm attributes.
+
+2004-02-24 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md (spe_fix_truncsfsi2): Delete.
+ (spe_fixuns_truncsfsi2): Delete.
+
+ * config/rs6000/rs6000.md (fix_truncsfsi2): Delete.
+ (fixuns_truncsfsi2): Delete.
+
+2004-02-24 Josef Zlomek <zlomekj@suse.cz>
+
+ PR/14240
+ * rtlanal.c (replace_label): Fix replacing labels in constant pool.
+
+2004-02-24 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa-protos.h (xtensa_copy_incoming_a7): Update.
+ (init_cumulative_args): Likewise.
+ (a7_overlap_mentioned_p): Delete prototype.
+ * config/xtensa/xtensa.c (struct machine_function): Replace
+ incoming_a7_copied field with need_a7_copy and vararg_a7 flags.
+ Add set_frame_ptr_insn field.
+ (xtensa_emit_move_sequence): Update call to xtensa_copy_incoming_a7.
+ (xtensa_copy_incoming_a7): Rewrite to check need_a7_copy flag and check
+ if the operand is an argument in a7. If so, copy a7 to a new pseudo
+ at the function entry and replace the operand with the pseudo.
+ (init_cumulative_args): Remove unused arguments. Add new "incoming"
+ argument and record this flag in CUMULATIVE_ARGS.
+ (function_arg): Remove result_mode and special-case code to handle
+ arguments in a7. Instead, set need_a7_copy flag when there is an
+ incoming argument in a7.
+ (xtensa_expand_prologue): Remove code to search for set_frame_ptr insn
+ and use the value recorded in cfun->machine->set_frame_ptr_insn.
+ (xtensa_builtin_saveregs): Check for negative gp_left value. Set
+ need_a7_copy and vararg_a7 flags. Use move_block_from_reg instead of
+ special-case code.
+ (a7_overlap_mentioned_p): Delete.
+ * config/xtensa/xtensa.h (CUMULATIVE_ARGS): Add "incoming" flag.
+ (INIT_CUMULATIVE_ARGS, INIT_CUMULATIVE_INCOMING_ARGS): Remove useless
+ arguments to init_cumulative_args and pass "incoming" flag instead.
+ (BLOCK_REG_PADDING): Delete.
+ * config/xtensa/xtensa.md (movdi, movsf, movdf): Remove unnecessary
+ checks for reload_in_progress and reload_completed. Update calls to
+ xtensa_copy_incoming_a7.
+ (ashlsi3): Rename existing insn to ashlsi3_internal. Add expander
+ to call xtensa_copy_incoming_a7.
+
+2004-02-24 Richard Earnshaw <rearnsha@arm.com>
+
+ * invoke.texi (ARM Options): Mark -mapcs-26 and -mno-alignment-traps
+ as deprecated. Remove already deprecated synonyms.
+ * arm.c (arm_override_options): Generate an inform message if the
+ user tries to invoke the compiler in apcs-26 mode.
+ * arm.h (TARGET_SWITCHES): Remove help comments from deprecated
+ switches. Delete deprecated synonyms for -malignment-traps.
+ (TARGET_DEFAULT): Default to alignment traps.
+ * arm/coff.h (TARGET_DEFAULT): Default to alignment traps.
+ * arm/elf.h arm/netbsd.h arm/pe.h arm/semi.h arm/semiaof.h: Likewise.
+ * arm/unknown-elf.h arm/wince-pe.h: Likewise.
+
+2004-02-23 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.h: Deprecate -mpni/-mno-pni.
+
+2004-02-23 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config/i386/i386.c: Rename pni to sse3.
+ * config/i386/i386.h: Likewise.
+ * config/i386/i386.md: Likewise.
+ * config/i386/pmmintrin.h: Likewise.
+ * doc/extend.texi: Likewise.
+ * doc/invoke.texi: Likewise.
-2003-03-25 Jason Merrill <jason@redhat.com>
+2004-02-23 Andrew Pinski <pinskia@physics.uc.edu>
- PR optimization/10171
- * unroll.c (unroll_loop): Don't delete the jump at the end unless
- we also delete a jump at the beginning.
+ * config/rs6000/linux.h (OS_MISSING_POWERPC64): Define.
+ * config/rs6000/linux64.h (OS_MISSING_POWERPC64): Define.
-2003-03-25 Stephane Carrez <stcarrez@nerim.fr>
+2004-02-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Falk Hueffner <falk@debian.org>
- * doc/contrib.texi (Contributors): Mention self as 68HC11/68HC12
- contributor.
-
-2003-03-25 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/passes.texi (Passes): Properly document that we do not
- perform jump2 any longer; remove command-line option -dJ.
+ PR c/14188
+ * builtins.c (expand_builtin_va_arg): Emit an informative message
+ if a trap is generated.
+ * c-typeck.c (build_function_call): Likewise.
-2003-03-25 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR optimization/8746
- * config/i386/i386.md (and promoting splitters): Disable HImode to
- SImode promoting when the sign bit matters and is not preserved, or
- when TARGET_FAST_PREFIX is true. Disable promoting when optimizing
- for size.
+2004-02-22 Christopher Faylor <cgf@redhat.com>
-2003-03-24 Stephane Carrez <stcarrez@nerim.fr>
+ * config.gcc (i[34567]86-*-pe|i[34567]86-*-cygwin*): *Really* specify
+ extra host object file when targetting cygwin rather than generic
+ object files.
- * config/m68hc11/t-m68hc11-gas (LIB1ASMFUNCS): Add _call_far and
- _return_far
- (MULTILIB_OPTIONS): Don't multilib on -mlong-calls.
- (MULTILIB_EXCEPTIONS): Likewise.
- * config/m68hc11/m68hc11.md ("call"): Support far calls for 68HC11
- by calling some board support routine.
- ("call_value"): Likewise.
- ("*return_void"): Likewise for return.
- ("*return_16bit"): Likewise.
- ("*return_32bit"): Likewise.
- * config/m68hc11/m68hc11.h (ASM_DECLARE_FUNCTION_NAME): Generate .far
- for 68HC11 too.
- (DWARF2_ADDR_SIZE): Use 4 so that addresses can
- * config/m68hc11/m68hc11.c (m68hc11_override_options): Accept
- -mlong-calls for 68HC11.
- * config/m68hc11/larith.asm (declare_near): New macro.
- (__premain, ___negsi2, ___one_cmplsi2, ___ashlsi3): Use it.
- (___ashrsi3, ___lshrsi3, ___lshrhi3, ___lshlhi3): Likewise.
- (___rotrhi3, ___rotlhi3, ___ashrhi3, ___ashrqi3): Likewise.
- (___lshlqi3, __divmodhi4, ___mulqi3, ___mulhi3): Likewise.
- (__mulhi32): Likewise.
- (ret): Update macro for 68HC11.
- (__far_trampoline): Implement for 68HC11.
- (__call_a16, __call_a32, __return_void, __return_16): New support
- routines for 68HC11 memory bank switching calling support.
- (__return_32): Likewise.
+2004-02-22 Matthias Klose <doko@debian.org>
-2003-03-21 Glen Nakamura <glen@imodulo.com>
+ Taken from mainline:
- PR opt/10087
- * loop.c (loop_givs_reduce): Skip bivs with duplicate locations
- while incrementing giv.
- (record_biv): Check for duplicate biv locations and
- set (struct induction *) v->same if found.
+ 2004-02-12 Geoffrey Keating <geoffk@apple.com>
-2003-03-24 Janis Johnson <janis187@us.ibm.com>
+ * Makefile.in (install-man): Use $(CPP_INSTALL_NAME) and
+ $(GCOV_INSTALL_NAME) to install manpages. Remove generic rule
+ for installing .1 manpages. Add rules for installing cpp
+ and gcov manpages under their installed names.
- * doc/install.texi (Testing): Mention test result links from build
- status pages.
+2004-02-22 Hans-Peter Nilsson <hp@axis.com>
-2003-03-24 Mark Mitchell <mark@codesourcery.com>
+ PR target/14209
+ * config/cris/cris.md ("*andsi_movu", "*andhi_movu"): Tweak
+ constraints to not match postincrement. Adjust the predicate to
+ exclude a volatile memory reference.
+ ("*andsi_clear"): Tweak constraints to not match postincrement.
+ Adjust the predicate to exclude a volatile memory reference.
+ ("*andhi_clear"): Ditto. Rename from "*andhi_clear_signed".
+ ("*andhi_clear_unsigned"): Remove, non-matching pattern.
- * function.c (put_var_into_stack): Change bool parameter to int.
- (gen_mem_addressof): Likewise.
- * rtl.h (gen_mem_addressof): Likewise.
- * tree.h (put_var_into_stack): Likewise.
- * config/alpha/alpha.c (alpha_gp_save_rtx): Adjust call to
- gen_mem_addressof or put_var_into_stack.
- * config/c4x/c4x.c (c4x_expand_builtin): Likewise.
+2004-02-21 Christopher Faylor <cgf@redhat.com>
-2003-03-24 Andreas Schwab <schwab@suse.de>
+ * config.gcc (i[34567]86-*-pe|i[34567]86-*-cygwin*): Specify extra host
+ object file when targetting cygwin.
+ * config/i386/t-cygwin (EXTRA_GCC_OBJS): Remove definition since it is
+ overridden by top-level Makefile.
- * config/ia64/ia64.c (spill_tfmode_operand): Adjust calls to
- gen_mem_addressof.
+2004-02-21 Alan Modra <amodra@bigpond.net.au>
-2003-03-24 Jakub Jelinek <jakub@redhat.com>
+ * combine.c (can_combine_p): Don't ignore SETs marked with
+ REG_EH_REGION notes.
- * expr.c (do_jump): Handle UNSAVE_EXPR specially.
+2004-02-21 Jan Hubicka <jh@suse.cz>
-2003-03-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+ * params.def (max-peeled-insns, max-completely-peeled-insns,
+ max-once-peeled-insns): Set to 400.
- PR target/10072
- * combine.c (simplify_if_then_else): Check that the mode
- has MODE_INT class before applying the (OP Z (mult COND C2))
- transformation.
+2004-02-20 Falk Hueffner <falk@debian.org>
-2003-03-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+ PR target/14201
+ * config/alpha/alpha.md (*fix_truncsfsi_ieee): Fix typoed operand
+ numbers.
- PR optimization/9414
- * config/sparc/sparc.md (widening peepholes): Use
- widen_memory_access instead of change_address.
+2004-02-20 Mohan Embar <gnustuff@thisiscool.com>
+ Tom Tromey <tromey@redhat.com>
-2003-03-23 Mark Mitchell <mark@codesourcery.com>
+ * doc/install.texi: Moved --disable-libgcj and
+ --with-system-zlib documentation to new section for
+ Java-specific options.
+ Added explicit Cross-Compiler-Specific Options subheading.
+ Added section for Java-specific options.
- PR c++/7086
- * c-typeck.c (c_mark_addressable): Adjust calls to
- put_var_into_stack.
- * expr.c (expand_expr): Likewise.
- * function.c (put_var_into_stack): Add rescan parameter. Do not
- call fixup_var_refs when rescan is false.
- (gen_mem_addressof): Likewise.
- (assign_parms): Adjust calls to put_var_into_stack.
- (setjmp_protect): Likewise.
- (setjmp_protect_args): Likewise.
- * rtl.h (gen_mem_addressof): Change prototype.
- * stmt.c (expand_decl): Adjust calls to put_var_into_stack.
- * tree.h (put_var_into_stack): Change prototype.
-
-2003-03-23 Arpad Beszedes <beszedes@cc.u-szeged.hu>
-
- PR middle-end/9967
- * builtins.c (expand_builtin_fputs): When optimizing for size,
- don't transform fputs into fwrite.
-
-2003-03-24 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_BSS): Remove unnecessary
- globalize_label.
-
- Merge from mainline.
- 2003-01-13 Andreas Schwab <schwab@suse.de>
- * config/rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_LOCAL): Output type
- directive.
-
-2003-03-23 Glen Nakamura <glen@imodulo.com>
-
- PR c/8224
- * fold-const.c (extract_muldiv_1): Don't pass through type conversions
- when signedness changes for division or modulus.
+2004-02-20 James E Wilson <wilson@specifixinc.com>
-2003-03-23 Richard Henderson <rth@redhat.com>
+ * toplev.c (dump_file_index, dump_file): Put ce3 before rnreg.
- * cfgcleanup.c (try_optimize_cfg): Allow merging of tablejumps
- before flow2.
- * cfgrtl.c (try_redirect_by_replacing_jump): Similarly.
+2004-02-20 Josef Zlomek <zlomekj@suse.cz>
-2003-03-23 Richard Henderson <rth@redhat.com>
+ * tree-inline.c (copy_body_r): Do not replace ret_label.
- PR opt/10116
- * ifcvt.c (find_if_block): Disallow tablejump insns outgoing
- from then_bb or else_bb after flow2.
- * jump.c (tablejump_p): New.
- * rtl.h: Declare it.
+2004-02-20 Kazu Hirata <kazu@cs.umass.edu>
-2003-03-22 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+ * gcc.c (process_command): Allow translation of the copyright
+ symbol but not the rest of the copyright message.
+ * gcov.c (print_version): Likewise. Allow translation of the
+ message about warranty.
- * pa.c (output_cbranch): Fix typo in comment.
+2004-02-19 Aldy Hernandez <aldyh@redhat.com>
-2003-03-22 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+ * config/rs6000/spe.md (spe_fixunssfsi2): Rename to
+ spe_fixuns_truncsfsi2.
- * pa.c (output_cbranch, output_bb, output_bvb): Output nop for
- conditional branch to the following instruction. Use next_real_insn
- instead of next_active_insn.
- (output_dbra, output_movb, jump_in_call_delay): Use next_real_insn
- instead of next_active_insn.
+ * config/rs6000/rs6000.md (fixunssfsi2): Rename to
+ fixuns_truncsfsi2.
-2003-03-22 Ulrich Weigand <uweigand@de.ibm.com>
+2004-02-19 Richard Sandiford <rsandifo@redhat.com>
+ Maciej W. Rozycki <macro@ds2.pg.gda.pl>
- * config/s390/s390.md ("movti", "*movdi_31", "*movdf_31"): Use 'o' instead
- of 'm' constraint in forced-split alternatives.
- ("*adddi3_31", "*subdi3_31"): Likewise. Also, pass 0 instead of 1 as
- VALIDATE_ADDRESS parameter to operand_subword.
+ * config/mips/mips.c (mips_address_insns): Treat BLKmode specially.
+ * config/mips/mips.md: Expand comment above unaligned loads and stores.
-2003-03-22 Svein E. Seldal <Svein.Seldal@solidas.com>
+2004-02-20 Alan Modra <amodra@bigpond.net.au>
- * config/c4x/t-c4x (MULTILIB_MATCHES): Make gcc recognize a c33 as
- a c30 instead of a c40 processor.
+ * function.c (assign_parms): Correct leakage of mainline code
+ in last commit. Also leakage from INIT_CUMULATIVE_ARGS patch.
-2003-03-21 Richard Henderson <rth@redhat.com>
+2004-02-19 Zack Weinberg <zack@codesourcery.com>
- PR opt/2001
- * bb-reorder.c (maybe_duplicate_computed_goto_succ): New.
- (make_reorder_chain_1): Call it.
+ * config/ia64/ia64.c (ia64_function_arg): In big-endian mode,
+ when passing single SFmode quantities in general registers,
+ put them in the high half.
+ (struct extern_func_list, extern_func_head): Mark with GTY(()).
+ (ia64_hpux_add_extern_decl): Save the decl, not the name string.
+ Allocate memory with ggc_alloc. No need to copy anything.
+ (ia64_hpux_file_end): Update to match.
- * function.h (struct function): Add computed_goto_common_label,
- computed_goto_common_reg.
- * function.c (free_after_compilation): Zap them.
- * stmt.c (expand_computed_goto): Use them to produce one
- indirect branch per function.
+2004-02-19 David Daney <ddaney@avtrex.com>
-2003-03-22 Stephane Carrez <stcarrez@nerim.fr>
+ PR preprocessor/14198
+ * config/mips/linux.h (TARGET_OS_CPP_BUILTINS): Add
+ builtin_assert ("machine=mips")
- * config/m68hc11/m68hc11.md ("call_value"): Fix trap check.
+2004-02-19 Ulrich Weigand <uweigand@de.ibm.com>
-2003-03-22 Stephane Carrez <stcarrez@nerim.fr>
+ * config/s390/s390.md ("*subdf3_cc", "*subdf3_cconly", "*subsf3_cc",
+ "*subsf3_cconly"): Subtraction is not commutative.
- * config/m68hc11/m68hc11.h (ASM_DECLARE_FUNCTION_NAME): Fix typo in
- writing .interrupt command.
- * config/m68hc11/m68hc11.md ("call"): Look at the symbol to see
- if it's a far or near function.
- ("call_value"): Likewise.
- * config/m68hc11/m68hc11.c (m68hc11_attribute_table): Add far and
- near attributes.
- (m68hc11_handle_fntype_attribute): Accept attributes on methods.
- (m68hc11_override_options): Ignore -mlong-calls for 68HC11.
- (m68hc11_initial_elimination_offset): Set current_function_far
- according to attributes.
- (expand_prologue): Likewise.
- (trap_handler_symbol): New global to keep track of trap handlers.
- (m68hc11_encode_section_info): Mark symbol as far if needed; set
- trap symbol.
- (m68hc11_is_far_symbol): New function.
- (m68hc11_is_trap_symbol): New function.
- * config/m68hc11/m68hc11-protos.h (m68hc11_is_far_symbol): Declare.
- (m68hc11_is_trap_symbol): Declare.
+2004-02-19 Alan Modra <amodra@bigpond.net.au>
-2003-03-21 Jan Hubicka <jh@suse.cz>
+ * function.c (assign_parms): When building decl_rtl for
+ SPLIT_COMPLEX_ARGS, ensure inner modes of concat match outer.
- PR inline-asm/7916
+2004-02-19 Olivier Hainque <hainque@act-europe.fr>
- * function.c (instantiate_virtual_regs_lossage): New function.
- (instantiate_virtual_regs_1): Use it.
- (instantiate_virtual_regs): Do not continue in substition when insn has
- been deleted.
+ * expr.c (is_aligning_offset): Check if we are aligning the
+ expressions's address over BIGGEST_ALIGNMENT in bytes, not
+ in bits.
-2003-03-21 Ulrich Weigand <uweigand@de.ibm.com>
+2004-02-19 Jan Hubicka <jh@suse.cz>
- * config/s390/s390.h: Do not include fixdfdi.h on s390x.
- (TARGET_64BIT): Define as compile-time constant when IN_LIBGCC2.
- (MIN_UNITS_PER_WORD): Do not define when IN_LIBGCC2.
+ * genextract.c (main): Do not output the memset when not checking.
-2003-03-21 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+2004-02-18 Jakub Jelinek <jakub@redhat.com>
- PR doc-bug/9813
- * doc/extend.texi: Move misplaced paragraph about underscores in
- variables in macros.
+ * config/i386/i386.c (override_options): Don't imply 3DNow! for -m64
+ by default.
-2003-03-21 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+2004-02-18 Ulrich Weigand <uweigand@de.ibm.com>
- * doc/invoke.texi: Fix table environment.
+ * config/s390/s390.md ("divmoddisi3"): Fix incorrect mode.
-2003-03-21 Richard Earnshaw <rearnsha@arm.com>
+2004-02-18 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
- * ifcvt.c (find_if_case_1): If we add a new bb, update the dominance
- information.
+ * pa.h (PIC_OFFSET_TABLE_REGNUM): Define to INVALID_REGNUM when not
+ generating PIC code.
-2003-03-21 Eric Botcazou <ebotcazou@libertysurf.fr>
- Richard Henderson <rth@redhat.com>
+2004-02-18 Ulrich Weigand <uweigand@de.ibm.com>
- PR optimization/8366
- * config/sparc/sparc.h: (SYMBOLIC_CONST): New macro.
- (GO_IF_LEGITIMATE_ADDRESS): Use it. Reject the form
- PIC+SYMBOLIC_CONST in other modes than Pmode.
- (GO_IF_MODE_DEPENDENT_ADDRESS): Use it. Mark
- the form PIC+SYMBOLIC_CONST as mode dependent.
+ * config/s390/s390.c (s390_mainpool_start): Delete the main pool
+ placeholder insn when chunkifying the pool.
-2003-03-20 Richard Henderson <rth@redhat.com>
+2004-02-18 Per Bothner <per@bothner.com>
- * fold-const.c (extract_muldiv_1): Revert changing order of
- operands in case MULT_EXPR of 2003-02-16 patch.
+ * cpphash.h (struct cpp_buffer): Restore return_at_eof field. This
+ partly reverts my 2003-10-01 change, because we're back to logically
+ including <command line> inside the main line.
+ * cpplex.c (_cpp_get_fresh_line): Check return_at_eof field.
+ * cppmacro.c (cpp_scan_nooutput): Set return_at_eof of current buffer.
+ Fixes PR preprocessor/14103.
-2003-03-20 Richard Henderson <rth@redhat.com>
+2004-02-18 Richard Earnshaw <rearnsha@arm.com>
- PR c/8602
- * integrate.c (output_inline_function): Reset input_filename
- and lineno from the decl before rest_of_compilation.
+ PR target/13866
+ * arm.c (load_multiple_operation): Don't insist that the source reg
+ of a post-increment component is the same as the destination.
+ (store_multiple_operation): Likewise.
-2003-03-20 Richard Earnshaw <rearnsha@arm.com>
+2004-02-18 Paul Brook <paul@codesourcery.com>
- PR 10066
- * arm.md (UNSPEC_PIC_BASE): New constant.
- (pic_add_dot_plus_four): Wrap with unspec.
- (pic_add_dot_plus_eight): Likewise.
+ * rtlanal.c (rtx_varies_p): Return 0 for NULL_RTX
-2003-03-19 Ulrich Weigand <uweigand@de.ibm.com>
+2004-02-18 Mark Mitchell <mark@codesourcery.com>
- * config/s390/s390.c (s390_preferred_reload_class): Do not
- force constants to the pool unless necessary.
- (s390_decompose_address): Prefer to use pointer as base,
- not index register.
- * config/s390/s390.md ("*tsthiCCT_only"): Remove '?' from
- Q alternative.
- ("*movdi_64", "*movsi", "movhi", "movqi_64", "movqi",
- "*movdf_64", "*movsf"): Add '?' to Q->Q alternatives.
- ("*extractqi", "*extracthi", "*zero_extendhisi2_31",
- "*zero_extendqisi2_31", "*zero_extendqihi2_31",
- "*adddi3_31", "*subdi3_31"): Do not set "type" attribute.
+ PR c++/11326
+ * config/ia64/ia64.c (ia64_struct_value_rtx): Cope with NULL
+ fntype.
-2003-03-19 Jakub Jelinek <jakub@redhat.com>
+2004-02-18 Paul Brook <paul@codesourcery.com>
- * config/rs6000/rs6000.c (rs6000_emit_load_toc_table): Don't call
- rs6000_maybe_dead if !fromprolog.
+ PR debug/12934
+ * dwarf2out.c (loc_descriptor_from_tree): Handle
+ EXPR_WITH_FILE_LOCATION.
-2003-03-19 Jakub Jelinek <jakub@redhat.com>
+2004-02-17 Mark Mitchell <mark@codesourcery.com>
- * ifcvt.c (dead_or_predicable): Fail if there are any references
- to tablejump in merge_bb other than the final JUMP_INSN.
+ PR c++/11326
+ * c-common.c (flag_abi_version): Remove.
+ * c-common.h (flag_abi_version): Likewise.
+ * c-opts.c (c_common_handle_option): Remove OPT_fabi_version case.
+ * c.opt (fabi-version): Remove.
+ * calls.c (expand_call): Always pass a function type to
+ struct_value_rtx. Use convert_memory_address.
+ * common.opt (fabi-version): Add it.
+ * flags.h (flag_abi_version): Likewise.
+ (abi_version_at_least): New macro.
+ * opts.c (common_handle_option): Add OPT_fabi_version.
+ * toplev.c (flag_abi_version): Define it.
+ * config/ia64/ia64.h (STRUCT_VALUE_REGNUM): Remove.
+ * config/ia64/ia64.c (TARGET_STRUCT_VALUE_RTX): Define it.
+ (ia64_struct_retval_addr_is_first_parm_p):
+ New function.
+ (ia64_output_mi_thunk): Use it.
+ (ia64_struct_value_rtx): New function.
-2003-03-19 Jakub Jelinek <jakub@redhat.com>
+2004-02-18 Alan Modra <amodra@bigpond.net.au>
- * stmt.c (expand_start_case): Call emit_queue ().
+ PR optimization/14119
+ * combine.c (try_combine): When attemting to fix unrecognized insns,
+ don't delete SETs marked with REG_EH_REGION notes.
-2003-03-19 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2004-02-17 Jan Hubicka <jh@suse.cz>
- PR 10062
- * config/pa/pa-hpux.h (TARGET_HPUX_UNWIND_LIBRARY): Redefine.
- * pa-protos.h (output_lbranch): New prototype.
- * pa.c (compute_frame_size): Change size of the frame marker on the
- 64-bit ports to 48 bytes.
- (pa_output_function_prologue): Document why SAVE_SP is set.
- (hppa_expand_prologue): Save previous stack pointer into frame marker
- on targets which use the hpux unwind library.
- (output_cbranch): Use output_lbranch.
- (output_lbranch): New function to output long unconditional branches.
- * pa.h (TARGET_HPUX_UNWIND_LIBRARY): Define.
- (STACK_POINTER_OFFSET): Update offset for 48-byte frame marker on
- 64-bit ports.
- * pa.md (jump): Use output_lbranch.
- (allocate_stack): New expander for dynamic stack allocation.
+ PR bootstrap/14180
+ * cselib.c (remove_useless_values): Do not access released
+ memory.
-2003-03-18 Alexandre Oliva <aoliva@redhat.com>
+2004-02-17 Ulrich Weigand <uweigand@de.ibm.com>
- * toplev.c (independent_decode_option): Return success for --help,
- --target-help and --version.
+ * combine.c (simplify_if_then_else): Do not replace
+ (if_then_else (ne reg 0) (0) (const_int)) by (reg) if the
+ modes differ.
-2003-03-19 Alan Modra <amodra@bigpond.net.au>
+2004-02-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- PR target/10073
- * combine.c (force_to_mode <NOT>): Use gen_int_mode.
+ * config/mips/t-iris6gld: Renamed to ...
+ * config/mips/t-irix-gld: ... this.
+ * config.gcc (mips-sgi-irix6*): Reflect this
+ (mips-sgi-irix5*): Use it with GNU ld.
-2003-03-18 Andreas Schwab <schwab@suse.de>
+ * config/mips/irix6-crti.asm, config/mips/irix6-crtn.asm: Renamed
+ to ...
+ * config/mips/irix-crti.asm, config/mips/irix-crtn.asm: ... this.
+ * config/mips/t-irix-gld: Reflect this.
+ * config/mips/iris6gld.h (STARTFILE_SPEC, ENDFILE_SPEC): Likewise.
- PR target/7248
- * config/m68k/m68k.md (iordi3): Fix setting low half to -1. From
- martin@blom.org.
+ * config/mips/iris5gld.h: New file.
+ * config.gcc (mips-sgi-irix5*): Use it with GNU ld.
+ Only use collect2 without gas.
-2003-03-17 Jason Merrill <jason@redhat.com>
+ * config/mips/iris6.h (IRIX6_STARTFILE_SPEC, IRIX6_ENDFILE_SPEC):
+ Renamed to IRIX_STARTFILE_SPEC, IRIX_ENDFILE_SPEC.
+ (STARTFILE_SPEC, ENDFILE_SPEC, SUBTARGET_EXTRA_SPECS): Reflect this.
+ * config/mips/iris6gld.h (STARTFILE_SPEC, ENDFILE_SPEC): Likewise.
- PR c++/10091
- * expr.c (expand_expr) [ADDR_EXPR]: Disallow taking the address of
- an unaligned member of TREE_ADDRESSABLE type.
+ * config/mips/iris6.h (SUBTARGET_EXTRA_SPECS): Moved ...
+ * config/mips/iris5.h: ... here.
-2003-03-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+ * config/mips/iris5.h (STARTFILE_SPEC, ENDFILE_SPEC): Renamed to
+ IRIX_STARTFILE_SPEC, IRIX_ENDFILE_SPEC.
+ (STARTFILE_SPEC, ENDFILE_SPEC): Define.
- * dwarf2asm.h: Delete obsolete comment.
- (dw2_asm_output_data, dw2_asm_output_delta, dw2_asm_output_offset,
- dw2_asm_output_pcrel, dw2_asm_output_addr,
- dw2_asm_output_addr_rtx, dw2_asm_output_encoded_addr_rtx,
- dw2_asm_output_nstring, dw2_asm_output_data_uleb128,
- dw2_asm_output_data_sleb128, dw2_asm_output_delta_uleb128,
- dw2_asm_output_delta_sleb128): Add ATTRIBUTE_NULL_PRINTF.
+ * config/mips/iris5gas.h (STARTFILE_SPEC, ENDFILE_SPEC): Simplify
+ using irix_startfile_spec, irix_endfile_spec.
+ * patches.summary (http):
-2003-03-17 Steve Ellcey <sje@cup.hp.com>
+2004-02-17 Andrew Pinski <pinskia@physics.uc.edu>
- * stmt.c (tail_recursion_args): Call promote_mode to set
- unsignedp flag correctly before calling convert_move.
+ PR c++/14178
+ * doc/invoke.texi (fabi-version): The default is 2 now.
-2003-03-17 Dave Love <fx@gnu.org>
- Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+2004-02-17 Jonathan Wakely <redi@gcc.gnu.org>
- * config/alpha/osf.h (TARGET_OS_CPP_BUILTINS): Define __digital__,
- __arch64__ to match Compaq cc.
+ * doc/install.texi: Update description of --gxx-include-dir to
+ give correct default value. (merged from mainline)
-2003-03-17 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+2004-02-16 Matthias Klose <doko@debian.org>
- * function.c (thread_prologue_and_epilogue_insns): Set delete_unused
- argument to 0 for redirect_jump.
+ * config/t-slibgcc-elf-ver: Define SHLIB_NAME and SHLIB_SONAME
+ in terms of SHLIB_SOVERSION.
+ * config/m68k/t-slibgcc-elf-ver: New file.
+ * config/pa/t-slibgcc-elf-ver: New file.
+ * config.gcc (m68k-linux, parisc-linux): Use them when not
+ sjlj exceptions are not configured.
-2003-03-16 Mark Mitchell <mark@codesourcery.com>
+2004-02-16 Eric Botcazou <ebotcazou@libertysurf.fr>
- PR c++/8805
- * except.c (eh_region_u_cleanup): Add prev_try.
- (expand_eh_region_end_cleanup): Set it.
- (reachable_handlers): Use it to skip over cleanup blocks.
+ * config/sparc/sparc.c (get_pc_symbol_name): Mark with GTY(()).
-2003-03-16 Richard Henderson <rth@redhat.com>
+2004-02-16 Joseph S. Myers <jsm@polyomino.org.uk>
- PR opt/6798
- * cfgcleanup.c: Include params.h.
- (try_crossjump_bb): Use PARAM_MAX_CROSSJUMP_EDGES. Fix test for
- too many outgoing edges from a block.
- * Makefile.in (cfgcleanup.o): Depend on PARAMS_H.
- * params.def (max-crossjump-edges): New.
- * doc/invoke.texi: Document it.
+ * doc/sourcebuild.texi: Mention backends.html.
-2003-03-16 Richard Henderson <rth@redhat.com>
+2004-02-15 Roger Sayle <roger@eyesopen.com>
- * config/i386/i386.md (movstrictqi, movstrictqi_1): Check
- optimize_size as well.
+ Backport from mainline:
-2003-03-16 Stephane Carrez <stcarrez@nerim.fr>
+ 2004-02-07 Roger Sayle <roger@eyesopen.com>
+ PR middle-end/13696
+ * fold-const.c (fold_convert): New function to provide type
+ conversion to the middle-end without using convert.
+ (negate_expr, associate_trees, size_diffop, omit_one_operand,
+ operand_equal_for_comparison_p, pedantic_omit_one_operand,
+ invert_truthvalue, optimize_bit_field_compare, range_binop,
+ decode_field_reference, make_range, build_range_check, unextend,
+ fold_truthop, extract_muldiv_1, fold_mathfn_compare,
+ fold_binary_op_with_conditional_arg, fold_inf_compare,
+ fold_single_bit_test, fold, multiple_of_p): Replace all calls to
+ convert with calls to fold_convert.
+
+ 2004-02-09 Roger Sayle <roger@eyesopen.com>
+ * fold-const.c (fold) <NOP_EXPR>: Use the original type conversion
+ tree code rather than call fold_convert, which doesn't specify a
+ default floating point to integer conversion.
+
+ 2004-02-10 Paolo Bonzini <bonzini@gnu.org>
+ PR c/14092
+ * fold-const.c (fold) <NEGATE_EXPR>: Convert result of
+ negate_expr back to the original type.
+
+2004-02-15 SUGIOKA Toshinobu <sugioka@itonet.co.jp>
- * config/m68hc11/m68hc11.c (print_operand): Handle 'b' modifier
- for D register to specify the low part of it, aka B.
- (m68hc11_gen_movhi): Use REG_WAS_0 note and increment or decrement
- the register if we are loading 1 or -1 to it; avoid using temp
- register when moving X/Y to Y/X.
- (m68hc11_gen_movqi): Likewise.
- (m68hc11_check_z_replacement): Fix last insn setting for compare case.
+ Backport from mainline:
-2003-03-14 Mark Mitchell <mark@codesourcery.com>
+ 2004-02-05 SUGIOKA Toshinobu <sugioka@itonet.co.jp>
+ * config/sh/t-linux (SHLIB_INSTALL): Prepend $$(DESTDIR)
+ to $$(slibdir) in the installation commands.
- PR optimization/9016
- * config/i386/i386.c (ix86_expand_move): Force more CONST_DOUBLEs
- into the constant pool.
+2004-02-15 Roger Sayle <roger@eyesopen.com>
-2003-03-16 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+ Backport from mainline:
- PR target/9164
- * tree.c (get_narrower): For extensions with unchanged bit number,
- return the unsignedness of the outer mode.
+ 2004-01-20 Roger Sayle <roger@eyesopen.com>
+ * fold-const.c (fold_convert): Rename to fold_convert_const.
+ (fold_convert_const): Change arguments to take a tree_code,
+ a type and the operand/expression to be converted. Return
+ NULL_TREE if no simplification is possible.
+ (fold): Adjust call to fold_convert to match new fold_convert_const.
+ Avoid modifying the tree passed to fold in-place.
-2003-03-16 Roger Sayle <roger@eyesopen.com>
+2004-02-15 Jan Hubicka <jh@suse.cz>
- * c-typeck.c (build_component_ref): Turn "for" into "do .. while"
- to avoid "may be used uninitialized" warning on ia64-hpux.
- * config/ia64/ia64-c.c: Include "tm_p.h" for function prototypes.
+ * cselib.c (value_pool): New.
+ (new_cselib_val): Use pool.
+ (cselib_init): Initialize value_pool
+ (cselib_finish): Free pool.
-2003-03-16 Neil Booth <neil@daikokuya.co.uk>
+ * cselib.c: Include alloc-pool.h
+ (empty_vals, empty_elt_lists, empty_elt_loc_lists): Kill.
+ (elt_loc_list_pool, elt_list_pool, cselib_val_pool): Declare.
+ (new_elt_list, new_elt_loc_list, unchain_one_elt_list,
+ unchain_one_elt_loc_list_pool, unchain_one_value,
+ new_cselib_val): Simplify using allocpool.
+ (cselib_init): Initialize allocpools.
+ (cselib_finish): Finish allocpools.
- * cppinit.c: Remove support of -A-.
- * doc/cppopts.texi: Remove documentation of -A-.
+2004-02-14 Richard Sandiford <rsandifo@redhat.com>
-2003-03-15 Richard Henderson <rth@redhat.com>
+ Backport from mainline:
- 2003-01-14 Richard Henderson <rth@redhat.com>
- * config/alpha/alpha.c (alpha_expand_mov): Use correct mode
- for force_const_mem.
+ 2002-04-08 Richard Sandiford <rsandifo@redhat.com>
+ * real.c (encode_ibm_extended): Normalize the input value before
+ converting it to a double. Handle the case where a normal value
+ rounds to infinity.
-2003-03-15 Richard Henderson <rth@redhat.com>
+2004-02-14 Olivier Hainque <hainque@act-europe.fr>
- PR target/9700
- * config/alpha/alpha.c (alpha_va_start): Account for
- current_function_pretend_args_size in the AP offset.
+ * loop.c (check_dbra_loop): Use gen_int_mode instead of GEN_INT
+ for start_value when it is directly moved into reg, and factorize
+ the retrieval of GET_MODE (reg).
-2003-03-15 Jason Merrill <jason@redhat.com>
+2004-02-13 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- PR debug/6387
- * dwarf2out.c (dwarf2out_decl): If we're at -g1, just stick nested
- function DIEs at toplevel.
- (decls_for_scope): At -g1, don't descend into subblocks.
+ * configure.ac: Search for as, ld below libexec/gcc.
+ * configure: Regenerate.
-2003-03-15 Ulrich Weigand <uweigand@de.ibm.com>
+2004-02-13 Jan Hubicka <jh@suse.cz>
- * varasm.c (struct rtx_const): Change type of un.addr member
- to struct holding an additional 'symbol' member.
- (decode_rtx_const): Re-enable optimization to count SYMBOL_REFs
- with equal string addresses as equal.
- (simplify_subtraction): Adapt to struct rtx_const change.
+ * combine.c (recog_for_combine): Avoid allocating unnecesary RTX.
-2003-03-15 Glen Nakamura <glen@imodulo.com>
+ * genrecog.c (find_operand): add extra argument stop.
+ (validate_pattern): Verify that mach_dup is duplicating operand
+ defined lexically earlier.
- * reload1.c (choose_reload_regs): Use && instead of ||
- with REG_CANNOT_CHANGE_MODE_P condition.
+2004-02-13 Ian Lance Taylor <ian@wasabisystems.com>
-2003-03-15 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+ PR other/10584
+ * c-opts.c (c_common_post_options): Disable function inlining when
+ using -finstrument-functions.
+ * doc/invoke.texi (Code Gen Options): Document this restriction.
- PR optimization/9387
- * function.c (thread_prologue_and_epilogue_insns): Use redirect jump
- for conditional returns.
+2004-02-12 Chris Demetriou <cgd@broadcom.com>
-2003-03-14 Jason Merrill <jason@redhat.com>
+ * config/mips/mips.md (casesi_internal, casesi_internal_di):
+ Use ".set macro" to avoid warnings about multi-instruction
+ macros, since they're intentional.
- PR optimization/6871
- * varasm.c (assemble_variable): Leave constant zeroes in .rodata.
+2004-02-13 Jan Hubicka <jh@suse.cz>
-2003-03-12 Andrew Lewycky <andrew@mxc.ca>
+ * alias.c (find_base_term, get_addr): Do not dereference NULL
+ pointer when all VALUE's locations has been invalidated.
+ (rtx_equal_for_memref_p): Simplify checking of VALUEs.
- PR c++/7050
- * expr.c (store_expr): Don't attempt to store void-typed trees,
- just evaluate them for side effects.
+ * cselib.c (discard_useless_values): Clear out value pointer pointing
+ to datastructure to be recycled.
-2003-03-14 Eric Botcazou <ebotcazou@libertysurf.fr>
+ * gcse.c (bypass_block): Prevent edges to be unified when we are
+ about to emit compenstation code.
- PR optimization/8396
- * tree-inline.c (initialize_inlined_parameters): Make sure the value
- of read-only constant arguments is passed with the right type.
+ * gcse.c (bypass_block): Fix a typo in the previous check-in
+ to the file.
-2003-03-14 Andreas Jaeger <aj@suse.de>
- Gwenole Beauchesne <gbeauchesne@mandrakesoft.com>
+ * alloc-pool.c (align_four): Kill.
+ (create_alloc_pool): Align size to eight.
+ (free_alloc_pool, free_pool): Invalidate deallocated data.
- * linux64.h (TARGET_OS_CPP_BUILTINS): Define _LP64 and __LP64__ in
- 64-bit mode.
+2004-02-12 Richard Sandiford <rsandifo@redhat.com>
-2003-03-13 Mike Stump <mrs@apple.com>
+ PR bootstrap/13617
+ * config/mips/mips-protos.h (mips_output_aligned_decl_common): Declare.
+ (mips_declare_object): Make variadic.
+ * config/mips/mips.h (ASM_OUTPUT_ALIGNED_DECL_COMMON): Use
+ mips_output_aligned_decl_common.
+ * config/mips/mips.c (mips_output_aligned_decl_common): New function.
+ (mips_declare_object): Make variadic.
- * ggc-page.c (struct page_entry): Remove varray.h header.
- Add index_by_depth field.
- Remove save_in_use_p field.
- (struct globals): Add depth_in_use, depth_max, by_depth_in_use,
- by_depth_max, by_depth, and save_in_use fields.
- (INITIAL_PTE_COUNT): Add.
- (save_in_use_p_i): Add.
- (save_in_use_p): Add.
- (adjust_depth): Add.
- (push_depth): Add.
- (push_by_depth): Add.
- (prefetch): Add.
- (free_page): Add support for and use faster data structures.
- (ggc_alloc): Likewise.
- (init_ggc): Likewise.
- (ggc_recalculate_in_use_p): Likewise.
- (ggc_pop_context): Likewise.
- (clear_marks): Likewise.
- * Makefile.in (ggc-page.o): Remove varray.h.
+2004-02-12 Jan Hubicka <jh@suse.cz>
-2003-03-12 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+ * tree-optimize.c (tree_rest_of_compilation): Do not release DECL_ARGUMENTS
- * pa.c (pa_init_builtins): Fix warning.
+2004-02-12 Ian Lance Taylor <ian@wasabisystems.com>
-2003-03-12 Richard Henderson <rth@redhat.com>
+ PR inline-asm/6162
+ * reload.c (find_reloads): Only support one pair of commutative
+ operands.
- PR opt/8178
- * config/i386/i386.md (ffssi2): Tighten op1 predicate to
- the requirements of the output insns.
+2004-02-12 Ian Lance Taylor <ian@wasabisystems.com>
-2003-03-12 Steve Ellcey <sje@cup.hp.com>
+ PR target/1532
+ Backport from mainline:
- * config/ia64/ia64.h (ASM_OUTPUT_XDATA_CHAR): Remove.
- (ASM_OUTPUT_XDATA_SHORT): Remove.
- (ASM_OUTPUT_XDATA_INT): Remove.
- (ASM_OUTPUT_XDATA_DOUBLE_INT): Remove.
- (ASM_OUTPUT_ADDR_DIFF_ELT): Handled 32 bit address diffs.
- (ASM_PREFERRED_EH_DATA_FORMAT): Handle 32 bit EH pointers.
- (CASE_VECTOR_MODE): Handle 32 bit pointers in case statement.
+ 2004-02-11 Richard Henderson <rth@redhat.com>
-2003-03-12 Andrew Lewycky <andrew@mxc.ca>
+ * flow.c (insn_dead_p): A clobber of a dead hard register is a
+ dead insn after reload.
- PR c++/7050
- * expr.c (store_expr): Don't attempt to store void-typed trees,
- just evaluate them for side effects.
+ 2004-01-24 Ian Lance Taylor <ian@wasabisystems.com>
-2003-03-12 Bob Wilson <bob.wilson@acm.org>
+ * cse.c (cse_cc_succs): Change the mode of the source expression
+ as soon as decide we need a new mode. Don't permit changing modes
+ if we found a match in a successor block.
+ (cse_condition_code_reg): Save original mode of source expression
+ so that we know whether we have to change the mode in other
+ insns.
+ 2004-01-24 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * cse.c: (cse_cc_succs) Fix comparison warning.
+
+ 2004-01-23 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * cse.c (cse_change_cc_mode): New static function.
+ (cse_change_cc_mode_insns, cse_cc_succs): Likewise.
+ (cse_condition_code_reg): New function.
+ * rtl.h (cse_condition_code_reg): Declare.
+ * toplev.c (rest_of_handle_cse2): Call cse_condition_code_reg.
+ * target.h (struct gcc_target): Add fixed_condition_code_regs and
+ cc_modes_compatible.
+ * target-def.h (TARGET_FIXED_CONDITION_CODE_REGS): Define.
+ (TARGET_CC_MODES_COMPATIBLE): Define.
+ (TARGET_INITIALIZER): Add new initializers.
+ * targhooks.c (default_cc_modes_compatible): New function.
+ * targhooks.c (default_cc_modes_compatible): Declare.
+ * hooks.c (hook_bool_intp_intp_false): New function.
+ * hooks.h (hook_bool_intp_intp_false): Declare.
+ * config/i386/i386.c (TARGET_FIXED_CONDITION_CODE_REGS): Define.
+ (TARGET_CC_MODES_COMPATIBLE): Define.
+ (ix86_fixed_condition_code_regs): New static function.
+ (ix86_cc_modes_compatible): Likewise.
+ * doc/tm.texi (Condition Code): Document new hooks.
+
+2004-02-12 Hartmut Penner <hpenner@de.ibm.com>
+
+ * config/rs6000/altivec.md (*movv4si_internal): At least one
+ operand must be register_operand.
+ (*movv8hi_internal1): Likewise.
+ (*movv16qi_internal1): Likewise.
+ (*movv4sf_internal1): Likewise.
+
+2004-02-12 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/14113
Backport from mainline:
- 2003-03-12 Bob Wilson <bob.wilson@acm.org>
- * config/xtensa/xtensa.md (adddi3): Don't clobber source operand used
- to detect carry.
- (subdi3): Reorder emitted instructions.
+ 2004-02-03 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-03-12 Jan Hubicka <jh@suse.cz>
+ * config/sparc/sparc.md (call followed by jump define_peephole's):
+ Delete.
- * i386.c (ix86_setup_incoming_varargs): Set stack_alignment_needed to 128.
+2004-02-12 Hartmut Penner <hpenner@de.ibm.com>
-2003-03-12 Daniel Jacobowitz <drow@mvista.com>
+ * gcc/config/rs6000/rs6000.c (rs6000_override_options)
+ Set AltiVec ABI and vrsave as default for ppc64 linux.
+ (init_cumulative_args): Post error, if try to return
+ value in AltiVec register without enable AltiVec.
+ (function_arg_advance): Ditto for passing arguments.
- Fix PR target/9797 and PR c/9853.
- * stmt.c (expand_decl_init): Call push_temp_slots () and
- pop_temp_slots ().
+2004-02-11 Joseph S. Myers <jsm@polyomino.org.uk>
-2003-03-12 Hans-Peter Nilsson <hp@bitrange.com>
+ PR c/456
+ * cppexp.c (num_binary_op): Don't allow comma operators in #if
+ constant expressions at all outside C99 mode if pedantic.
- * configure.in (rlim_t): Define to long if no valid definition
- found in sys/resource.h.
- * config.in, configure: Regenerate.
+2004-02-10 Aldy Hernandez <aldyh@redhat.com>
-2003-03-12 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR c/9928
- * c-decl.c (duplicate_decls): Discard the initializer of the new decl
- only if it is a VAR_DECL.
+ * config/rs6000/spe.md ("*movv2si_internal"): Check for register
+ operand.
+ (movv4hi_internal): Same.
+ (movv2sf_internal): Same.
+ (movv1di_internal): Same.
-2003-03-12 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-02-11 Richard Sandiford <rsandifo@redhat.com>
- PR optimization/9888
- * config/i386/i386.md (jcc_1): Fix range.
- (jcc_2): Likewise.
- (jump): LIkewise.
- (doloop_end_internal): Likewise.
+ * emit-rtl.c (mark_label_nuses): Check that a LABEL_REF refers to
+ a label before updating its usage count.
-2003-03-12 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-02-10 Danny Smith <dannysmith@users.sourceforge.net>
- PR optimization/9888
- * config/i386/i386.md (movsi_1): Remove special alternatives
- for %eax register.
- (movhi_1): Likewise.
- * config/i386/i386.c (memory_address_length): Do not use
- short displacement when there is no base.
- (ix86_attr_length_address_default): Handle LEA instructions.
+ PR c/14088
+ real.c (real_from_string): Look for 'X' as well as 'x' in
+ hexfloat strings.
-2003-03-11 Loren James Rittle <ljrittle@acm.org>
+2004-02-10 Per Bothner <per@bothner.com>
- (per-port preprocessor fix, concurrent to Neil's cppinit.c fix)
- * config/freebsd-spec.h (FBSD_CPP_PREDEFINES): Remove.
- (FBSD_TARGET_OS_CPP_BUILTINS): New port-specific macro.
- (FBSD_TARGET_CPU_CPP_BUILTINS): New port-specific macro.
- * config/freebsd.h (CPP_PREDEFINES): Remove.
- (TARGET_OS_CPP_BUILTINS): New.
- * config/alpha/freebsd.h: Use overridden FBSD_TARGET_CPU_CPP_BUILTINS
- instead of TARGET_OS_CPP_BUILTINS.
- * config/sparc/freebsd.h (CPP_PREDEFINES): Remove.
+ * c-opts.c (c_common_post_options): Don't emit working directory
+ in cpp output if -P was specified.
-2003-03-11 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+2004-02-10 Jakub Jelinek <jakub@redhat.com>
- PR bootstrap/9994
+ PR optimization/13424
Backport from mainline:
- 2003-02-18 Roger Sayle <roger@eyesopen.com>
-
- * sbitmap.c (sbitmap_resize): New function.
- * sbitmap.h (sbitmap_resize): Prototype here.
- * recog.c (split_all_insns): Use sbitmap_resize.
-
- Mon Feb 17 16:16:54 CET 2003 Jan Hubicka <jh@suse.cz>
-
- * recog.c (split_all_insns): Fix memory overflow.
-
- 2003-02-15 Richard Henderson <rth@redhat.com>
-
- * recog.c (split_all_insns): Include new blocks in life update;
- do a global life update.
-
-2003-03-11 Hans-Peter Nilsson <hp@bitrange.com>
-
- * config/cris/cris.md: Remove lingering EGCS reference.
- ("*extopqihi_side_biap"): For HI operation, match
- cris_additive_operand_extend_operator, not
- cris_operand_extend_operator. Adjust condition.
- ("*extopqihi_side", "*extopqihi"): Ditto.
- ("*extopqisi_side_biap"): Correct operand numbers in condition.
- ("*extophisi_side_biap", "*extopqisi_swap_side_biap"): Ditto.
- ("*extophisi_swap_side_biap", "*extopqisi_swap"): Ditto.
- ("*extophisi_swap"): Ditto.
- ("*extopqihi_swap_side_biap"): For HI operation, match a simple
- PLUS, not cris_operand_extend_operator. Adjust condition and
- output template.
- ("*extopqihi_swap_side", "*extopqihi_swap"): Ditto.
- * config/cris/cris.h (PREDICATE_CODES): Add
- cris_additive_operand_extend_operator.
- * config/cris/cris.c (cris_additive_operand_extend_operator):
- New predicate.
-
- * config/cris/aout.h (ENDFILE_SPEC): Undef.
- (CRIS_CPP_SUBTARGET_SPEC): Move -D__AOUT__ to...
- (TARGET_OS_CPP_BUILTINS): New macro.
- (HAVE_GAS_HIDDEN): Undef.
- * config/cris/cris.h: Remove EGCS references.
- (CPP_SPEC): Remove "-$".
- (INIT_CUMULATIVE_ARGS): Correct comment.
- * config/cris/cris.h (CRIS_CPP_SUBTARGET_SPEC): Move -D__ELF__ to...
- (TARGET_OS_CPP_BUILTINS): New macro.
- (CPP_PREDEFINES): Don't define. Move old definitions and...
- (CPP_SPEC): ...move -D__CRIS_ABI_version=2 to...
- (TARGET_CPU_CPP_BUILTINS): New macro.
- * config/cris/linux.h (CRIS_CPP_SUBTARGET_SPEC): Move constant
- definitions and the optional __PIC__, __pic__ and
- __NO_UNDERSCORES__ definitions to...
- (TARGET_OS_CPP_BUILTINS): New macro.
-
-2003-03-10 Devang Patel <dpatel@apple.com>
-
- PR c++/9394
- * gcc.c (DEFAULT_SWITCH_TAKES_ARG): Remove.
- (DEFAULT_WORD_SWITCH_TAKES_ARG): Remove.
- * gcc.h (DEFAULT_SWITCH_TAKES_ARG): Add.
- (DEFAULT_WORD_SWITCH_TAKES_ARG): Add.
- * cppspec.c (DEFAULT_SWTICH_TAKES_ARG): Remove.
- (DEFAULT_WORD_SWITCH_TAKES_ARG): Remove.
-
-2003-03-10 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.h (HARD_REGNO_RENAME_OK): Define.
- * config/m68hc11/m68hc11-protos.h (m68hc11_hard_regno_rename_ok):
- Declare.
- * config/m68hc11/m68hc11.c (m68hc11_hard_regno_rename_ok): New function
- for reg rename optimization to avoid using Z and Y registers.
-
-2003-03-10 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.md ("*addhi3_68hc12"): Accept any constant
- when adding to X and Y since leax/leay are fast.
- ("*addhi3"): Accept 'I' constraint when adding to address register.
- ("rotlhi3"): Operand 1 must be a register_operand.
- (peephole2): New peephole to optimize some adds.
- * config/m68hc11/m68hc11.h (CONST_OK_FOR_LETTER_P): Use 'I' constraint
- to represent -2 .. 2 small integer range.
-
-2003-03-10 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.c (m68hc11_gen_rotate): Set carry before
- each 16-bit rotation.
-
-2003-03-10 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/spe.h: Merge from mainline.
-
-2003-03-10 Jan Hubicka <jh@suse.cz>
-
- * toplev.c (rest_of_compilation): Revert the previous patch.
-
-2003-03-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- PR middle-end/9986
- * c-common.c (c_common_nodes_and_builtins): Initialize target builtins
- after the common builtins.
- * pa-hpux.h (DONT_HAVE_FPUTC_UNLOCKED): Define.
- * pa.c (TARGET_INIT_BUILTINS): Define.
- (pa_init_builtins): New function.
-
- * pa.md (call, call_value, sibcall, sibcall_value): When sufficient
- space has been allocated for the outgoing arguments, set the arg
- pointer for a call emitted after virtuals have been instantiated
- using the stack pointer offset, otherwise abort.
-
-2003-03-06 Jan Hubicka <jh@suse.cz>
-
- * toplev.c (rest_of_compilation): Defer RTL compilation only when
- RTL inlining is done.
-
- * i386.c (ix86_expand_vector_move): Do not crash when offloading
- to memory in PIC mode.
-
-2003-03-08 Neil Booth <neil@daikokuya.co.uk>
-
- * cppinit.c (cpp_finish_options): Set first_unused_line to -1.
-
-2003-03-08 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR middle-end/7796
- * unroll.c (calculate_giv_inc): Handle constants being
- loaded with LSHIFTRT.
-
-2003-03-07 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR optimization/8726
- Backport patch from mainline:
-
- 2003-01-08 Dale Johannesen <dalej@apple.com>
-
- * function.c (assign_parms): Don't set pretend_args_size if
- REG_PARM_STACK_SPACE.
-
-2003-03-06 Kurt Garloff <garloff@suse.de>
- Geoffrey Keating <geoffk@apple.com>
- Dale Johannesen <dalej@apple.com>
- * params.def: Introduce parameter max-inline-insns-rtl for
- a separate limit for the RTL inliner.
- * params.h: Likewise.
- * integrate.c (function_cannot_inline_p): Use it.
- * toplev.c (decode_f_option): Set multiple parameters
- controlling inlining with -finline-limit.
- * params.def: Fix orthographic and typographic errors.
- * doc/invoke.texi: Document parameters controlling inlining
- and the way -finline-limit sets multiple of them.
- * tree.h (struct tree_decl): Introduce inlined_function_flag,
- recording whether the function became eligible for inlining
- by a compiler flag rather than the declaration.
- Provide DID_INLINE_FUNC macro to access it.
- * c-decl.c (grokdeclarator): Set DID_INLINE_FUNC.
- * cp/decl.c (grokfndecl): Likewise.
- * toplev.c (rest_of_compilation): Likewise.
- * cp/optimize (maybe_clone_body): Copy DID_INLINE_FUNC.
- * print-tree.c (print_node): Report it.
- * params.def: Introduce new max-inline-insns-auto limit.
- * params.h: Likewise.
- * tree-inline.c (inlinable_function_p): Apply it to functions
- with DID_INLINE_FUNC set.
- * toplev.c (decode_f_option): Initialize it from -finline-limit
- value.
- * doc/invoke.texi: Document new parameter.
-
-2003-03-06 Michael Matz <matz@suse.de>
-
- * i386/i386.c (ix86_save_reg): Also test
- current_function_uses_const_pool.
-
-2003-03-05 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- * pa.md (return_external_pic): Add !TARGET_PA_20 to constraint.
- (epilogue): Don't generate return_external_pic when emitting PA 2.0
- code.
-
-2003-03-05 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.h (PAD_VARARGS_DOWN): Define and return
- according to va_arg type.
- (EXPAND_BUILTIN_VA_ARG): Remove.
- * config/m68hc11/m68hc11.c (m68hc11_va_arg): Remove.
- * config/m68hc11/m68hc11-protos.h (m68hc11_va_arg): Remove.
+ 2004-01-29 Jakub Jelinek <jakub@redhat.com>
+ * emit-rtl.c (change_address): Use XEXP (memref, 0) instead
+ of addr when creating MEM copy.
+
+ 2004-01-28 Jakub Jelinek <jakub@redhat.com>
+ * expr.c (store_constructor): Revert 2003-12-03 change.
+
+ * emit-rtl.c (change_address): Check also if MEM_ATTRS is set as
+ expected before returning early. Avoid sharing RTL if they
+ need to be changed.
+
+ * config/i386/i386.c (ix86_expand_movstr): Rework rep_mov and strmov
+ handling so that memory attributes are preserved. Don't call
+ ix86_set_move_mem_attrs.
+ (ix86_set_move_mem_attrs_1, ix86_set_move_mem_attrs): Removed.
+ (ix86_expand_clrstr): Rename src argument to
+ dst. Rework rep_stos and strset handling so that memory attributes
+ are preserved.
+ (ix86_expand_strlen): Pass src argument to
+ ix86_expand_strlensi_unroll_1. Rework strlenqi_1 handling so that
+ memory attributes are preserved.
+ (ix86_expand_strlensi_unroll_1): Add src argument. Use
+ change_address instead of gen_rtx_MEM.
+ * config/i386/i386.md (strmov, strmov_singleop, rep_mov): New
+ expanders.
+ (strmovdi_rex64, strmovsi, strmovsi_rex64, strmovhi, strmovhi_rex64,
+ strmovqi, strmovqi_rex64): Remove.
+ (rep_mov*, strmov*): Prefix insn names with *.
+ (strset, strset_singleop, rep_stos): New expanders.
+ (strsetdi_rex64, strsetsi, strsetsi_rex64, strsethi, strsethi_rex64,
+ strsetqi, strsetqi_rex64): Remove.
+ (rep_stos*, strset*): Prefix insn names with *.
+ (rep_stosqi_rex64): Likewise. Fix mode of dirflag reg from DImode
+ to SImode.
+ (cmpstrsi): Rework cmpstrqi_1 handling so that memory attributes
+ are preserved.
+ (cmpstrqi_nz_1, cmpstrqi_nz_rex_1, cmpstrqi_1, cmpstrqi_rex_1):
+ Prefix insn names with *.
+ (cmpstrqi_nz_1, cmpstrqi_1): New expanders.
+ (strlenqi_1, strlenqi_rex_1): Prefix insn names with *.
+ (strlenqi_1): New expander.
+ * config/i386/i386.h (ix86_set_move_mem_attrs): Remove prototype.
+
+ 2004-01-24 Jan Hubicka <jh@suse.cz>
+ * emit-rtl.c (change_address, adjust_address_1, offset_address,
+ widen_memory_access): Return early when there is nothing to change.
+
+2004-02-10 David Edelsohn <edelsohn@gnu.org>
+
+ * configure.ac (gcc_cv_as_powerpc_mfcrf): Correct test for mfcr.
+ * configure: Regenerate.
-2003-03-05 Jan Hubicka <jh@suse.cz>
+2004-02-10 Ulrich Weigand <uweigand@de.ibm.com>
- * toplev.c (rest_of_compilation): Do duplicate loop headers when
- optimizing for size.
+ * cfganal.c (flow_call_edges_add): Never split a libcall block.
-2003-03-05 Michael Matz <matz@suse.de>
+2004-02-10 Richard Sandiford <rsandifo@redhat.com>
- * unwind.h: Add the GPL exception.
- * Makefile.in (USER_H): Add unwind.h.
+ * config/mips/mips.h (TARGET_GPWORD): Return false for TARGET_NEWABI
+ && TARGET_IRIX.
-2003-03-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-02-09 Geoffrey Keating <geoffk@apple.com>
- PR c/9799
- * c-typeck.c (push_init_level): Add sanity check.
+ PR 12028
+ * config/rs6000/rs6000.c (ccr_bit): Don't let consistency check
+ failure stop compilation, just print helpful message.
-2003-03-04 Steve Ellcey <sje@cup.hp.com>
+2004-02-09 Fariborz Jahanian <fjahanian@apple.com>
- * expr.c (convert_modes): Check for legal hard register.
+ * expr.c (emit_group_load): split constant
+ correctly into register components of PARALLEL insn.
-2003-03-04 Andreas Schwab <schwab@suse.de>
+2004-02-09 DJ Delorie <dj@redhat.com>
- * config/m68k/m68k.c (m68k_output_function_prologue): Fix CFA
- offset without frame pointer.
+ * config/i386/xm-djgpp.h (GCC_DRIVER_HOST_INITIALIZATION): No
+ longer modify standard_exec_prefix, standard_bindir_prefix, or
+ standard_startfile_prefix.
-2003-03-04 Steve Ellcey <sje@cup.hp.com>
+2004-02-09 James E Wilson <wilson@specifixinc.com>
- * expr.c (expand_expr): Call promote_mode to set unsignedp.
+ PR c++/11295
+ * c-common.c (c_expand_expr, case STMT_EXPR): Change expand_expr call
+ to expand_expr_real call, and pass in alt_rtl as last argument.
-2003-03-04 Roger Sayle <roger@eyesopen.com>
+ PR libstdc++/5625
+ * builtin-types.def (BT_WORD, BT_FN_WORD_PTR): New.
+ * builtins.c (expand_builtin): Handle BUILT_IN_EXTEND_POINTER.
+ * builtins.def (BUILT_IN_EXTEND_POINTER): New.
+ * except.c (expand_builtin_extend_pointer): New.
+ * except.h (expand_builtin_extend_pointer): Declare.
- PR c++/9367
- * builtin-types.def (DEF_FUNCTION_TYPE_VAR_3): New macro.
- (BT_FN_INT_CONST_STRING_VALIST_ARG,
- BT_FN_INT_STRING_CONST_STRING_VALIST_ARG,
- BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG,
- BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG,
- BT_FN_INT_STRING_CONST_STRING_VAR,
- BT_FN_INT_CONST_STRING_CONST_STRING_VAR,
- BT_FN_INT_STRING_SIZE_CONST_STRING_VAR): New built-in types.
- * builtin-attrs.def (ATTR_NONNULL_1, ATTR_NONNULL_2,
- ATTR_NONNULL_3): Also include the nothrow attribute.
- (sprintf, scanf, sscanf, vprintf, vsprintf, snprintf,
- vsnprintf, vscanf, vsscanf): Don't define attributes here.
- * builtins.def (putchar, puts): Make full C89 built-ins.
- (snprintf, sprintf, scanf, sscanf, vprintf, vscanf,
- vsscanf, vsnprintf, vsprintf): New built-ins.
- * c-common.c (c_common_nodes_and_builtins): Handle new macro
- DEF_FUNCTION_TYPE_VAR_3.
+2004-02-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- * doc/extend.texi: Document these new built-in functions.
-
-2003-03-04 Jan Hubicka <jh@suse.cz>
-
- * calls.c (rtx_for_function_call): Take the address as an argument
- (expand_call): Do not modify the expression.
-
-2003-03-04 Kevin Buettner <kevinb@redhat.com>
+ * config/mips/iris5.h (BSS_SECTION_ASM_OP): Define.
+ * config/mips/iris6.h (BSS_SECTION_ASM_OP): Undef.
- * dwarf2out.c (rtl_for_decl_location): Don't return NULL_RTX for
- global register variables.
-
-2003-03-03 Richard Henderson <rth@redhat.com>
+ * config/mips/iris6.h (TARGET_ASM_NAMED_SECTION): Moved ...
+ * config/mips/iris5.h: ... here.
+ * config/mips/iris5gas.h (TARGET_ASM_NAMED_SECTION): Remove.
- * configure.in (HAVE_AS_LTOFFX_LDXMOV_RELOCS): New ia64 test.
- * config.in, configure: Rebuild.
- * config/ia64/ia64.c (ia64_ld_address_bypass_p): Accept lo_sum.
- * config/ia64/ia64.md (load_symptr): Use high/lo_sum for the
- paired ldtoffx and ldxmov annotations.
- (load_symptr_internal1): Remove.
- (load_symptr_high, load_symptr_low): New.
- * config/ia64/ia64.h (HAVE_AS_LTOFFX_LDXMOV_RELOCS): Default to 0.
+ * config/mips/iris6.h (EXTRA_SECTION_FUNCTIONS): Move ...
+ * config/mips/iris5.h: ... here.
-2003-03-03 Jason Merrill <jason@redhat.com>
+2004-02-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- * calls.c (compute_argument_addresses): Give the new MEMs a
- minimum alignment of PARM_BOUNDARY.
+ * configure.ac: Remove default executable files before AC_PROG_CC.
+ * configure: Regenerate.
-2003-03-03 Geoffrey Keating <geoffk@apple.com>
+2004-02-09 Kazu Hirata <kazu@cs.umass.edu>
- * doc/install.texi (Specific): Update entry for powerpc-darwin.
+ PR target/13721
+ * config/h8300/h8300.c (byte_reg): Call abort() if asked to
+ print a operand other than a register.
-2003-03-03 Jan Hubicka <jh@suse.cz>
- * toplev.c (rest_of_compilation): Avoid cfg_cleanup calls when not
- optimizing.
+2004-02-09 Nick Clifton <nickc@redhat.com>
-2003-02-28 Jan Hubicka <jh@suse.cz>
+ * Import these patches from mainline sources:
- * combine.c (gen_lowpart_for_combine): Update handling of subregs_of_mode
- * flow.c (life_analysis, mark_used_regs): Likewise.
- * regclass.c (subregs_of_mode): Turn into single bitmap.
- (cannot_change-mode_set_regs, invalid_mode_change_p): Update
- dealing with subregs_of_mode
- * regs.h (subregs_of_mode): Update prototype.
+ 2004-01-21 Inaoka Kazuhiro <inaoka.kazuhiro@renesas.com>
-2003-02-28 Jan Hubicka <jh@suse.cz>
+ * config/m32r/m32r.h (CPP_SPEC): Define.
- * toplev.c (rest_of_compilation): Rearrange insn splitting
- * reg-stack.c (reg_to_stack): Do not split insns.
+ 2004-01-20 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
-2003-03-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+ * config/m32r/m32r.h (TARGET_M32R2). Test for TARGET_M32R2_MASK
+ not TARGET_M32RX_MASK.
- * ggc-common.c (ggc_rlimit_bound): Cast RLIM_INFINITY to avoid
- warnings.
+2004-02-09 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-03-02 Stephane Carrez <stcarrez@nerim.fr>
+ * cpplib.h (cpp_get_line_maps): Un-constify the structure
+ pointed to by the pointer returned by the function.
+ * cpplib.c (cpp_get_line_maps): Likewise.
- * config/m68hc11/m68hc11.c (m68hc11_override_options): Don't enable
- min/max instructions by default as may result in reload errors.
+2004-02-08 Kazu Hirata <kazu@cs.umass.edu>
-2003-03-02 Stephane Carrez <stcarrez@nerim.fr>
+ * c-objc-common.c (c_cannot_inline_tree_fn): Fix a typo in a
+ warning.
- * config/m68hc11/m68hc11.md ("mulqi3"): Allow address register to
- avoid reload problems; define split for it.
+2004-02-08 Joseph S. Myers <jsm@polyomino.org.uk>
-2003-03-02 Stephane Carrez <stcarrez@nerim.fr>
+ * README.Portability: Change "ISO C89" to "ISO C90".
+ * c-parse.in (primary, initelt): Likewise.
- * config/m68hc11/m68hc11.c (m68hc11_shift_operator): New function.
- * config/m68hc11/m68hc11-protos.h (m68hc11_shift_operator): Declare.
- * config/m68hc11/m68hc11.h (PREDICATE_CODES): Register.
- * config/m68hc11/m68hc11.md ("rotrhi3", "rotlhi3"): New patterns for
- rotatert and rotate.
- ("rotrhi3_const", "rotlhi3_const"): Rename of old 'rotrhi3' insns.
- ("*rotrhi3", "*rotlhi3"): New insn pattern for non-const rotatert.
- ("*rotrhi3_addr"): New split for shift insns on address register.
- ("*lshrhi3", "*ashrhi3", "*ashlhi3_2"): Use new split.
- * config/m68hc11/larith.asm (___rotlhi3): New asm function.
- (___rotrhi3): Likewise.
- * config/m68hc11/t-m68hc11-gas (LIB1ASMFUNCS): Build them.
+2004-02-07 Zack Weinberg <zack@codesourcery.com>
-2003-03-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+ Bug 13856
+ * c-decl.c (diagnose_mismatched_decls): Only give special
+ treatment when olddecl is DECL_BUILT_IN, if C_DECL_INVISIBLE
+ is also true.
+ (merge_decls): Don't clear DECL_BUILT_IN_CLASS and
+ DECL_FUNCTION_CODE when defining a built-in function.
+ Don't update DECL_ESTIMATED_INSNS.
+ * dwarf2out.c (dwarf2out_decl): Don't ignore built-in
+ FUNCTION_DECLs.
+ * tree.h: Delete DECL_ESTIMATED_INSNS.
+ * tree-inline.c (struct inline_data): Delete inlined_insns field.
+ (expand_call_inline, optimize_inline_calls): Don't update
+ DECL_ESTIMATED_INSNS nor inlined_insns.
+ * cgraphunit.c (cgraph_analyze_function): Don't update
+ DECL_ESTIMATED_INSNS.
- * fp-bit.h (float_to_usi): Fix condition wrapping prototype.
+2004-02-07 Zack Weinberg <zack@codesourcery.com>
-2003-03-02 Ashif Harji <asharji@uwaterloo.ca>
+ * c-common.c (shadow_warning): Delete.
+ * c-common.h (free_parser_stacks, shadow_warning, sw_kind): Delete.
+ * c-decl.c (warn_if_shadowing): Issue shadow warnings directly.
+ * c-opts.c (c_common_parse_file): Don't call free_parser_stacks.
+ * c-parse.in (free_parser_stacks): Delete.
- * gcc.c (default_compilers): Add -no-integrated-cpp flag to invoke
- an external cpp during compilation.
- (option_map): Likewise.
- * objc/lang-specs.h (default_compilers): Similarly.
- * doc/invoke.texi: Document -no-integrated-cpp flag.
+2004-02-07 Kazu Hirata <kazu@cs.umass.edu>
-2003-03-01 Jason Thorpe <thorpej@wasabisystems.com>
+ * c-opts.c, c-ppoutput.c, cppfiles.c, cpphash.h, cppinit.c,
+ cpplib.h, diagnostic.h, fix-header.c, config/fp-bit.c,
+ config/mips/iris5.h, doc/makefile.texi: Update copyright.
- * config.gcc (*-*-netbsd[2-9]*, *-*-netbsdelf[2-9]*): Enable
- POSIX thread support by default.
+2004-02-06 James E Wilson <wilson@specifixinc.com>
-2003-03-01 Roger Sayle <roger@eyesopen.com>
+ * config/ia64/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Only define for
+ glibc 2.3 or better.
- PR bootstrap/7389.
- * basic-block.h (flow_bb_inside_loop_p): Correct prototype.
+2004-02-06 Ulrich Weigand <uweigand@de.ibm.com>
-2003-02-28 Jason Thorpe <thorpej@wasabisystems.com>
+ * loop.c (force_movables): Transitively increase the priorities of
+ all insns forces by an insn, not just the first one.
- * config/netbsd.h: Update copyright years.
- (NETBSD_CPP_SPEC): Define _REENTRANT and _PTHREADS if
- -pthread is specified on the command line.
+2004-02-06 Falk Hueffner <falk@debian.org>
-2003-02-28 Bob Wilson <bob.wilson@acm.org>
+ PR target/12898
+ * config/alpha/alpha.c (alpha_emit_set_const_1): If
+ no_new_pseudos, use gen_rtx_SET directly for SImode constants
+ which need multiple instructions to emit.
- Backport following patch:
+2004-02-06 H.J. Lu <hongjiu.lu@intel.com>
- 2003-02-28 Bob Wilson <bob.wilson@acm.org>
- * config.gcc (xtensa-*-linux*): Add t-slibgcc-elf-ver to tmake_file.
+ * doc/invoke.texi: Remove the pni option from -mfpmath=.
-2003-02-27 Joel Sherrill <joel@OARcorp.com>
+2004-02-05 Kelley Cook <kcook@gcc.gnu.org>
- PR 9638/other
- * config/i386/i386.c (DEFAULT_PCC_STRUCT_RETURN): Ensure the
- this constant defaults to 1.
+ * doc/install.texi: Update automake and autoconf version
+ requirements. Note where to find gcj automake version.
-2003-02-28 Richard Sandiford <rsandifo@redhat.com>
+2004-02-05 Kelley Cook <kcook@gcc.gnu.org>
- * config/mips/mips.md: Disable the movstrsi define_split.
+ * Makefile.in (generate-manpages): Move dependencies to ...
+ (man): here.
+ * doc/makefile.texi: Document new targets.
+ * doc/sourcebuild.texi (Make-lang.in): Document new langhooks.
-2003-02-28 Richard Sandiford <rsandifo@redhat.com>
+2004-02-05 Kelley Cook <kcook@gcc.gnu.org>
- * config/mips/mips.h (CRT_CALL_STATIC_FUNCTION): Wrap in
- #ifndef __mips16.
+ PR/13485
+ Makefile.in (srcextra): Add a level of indirection to ...
+ (gcc.srcextra): ... here.
+ (po-generated): Delete.
+ (po/$(PACKAGE).pot: Use srcextra instead of po-generated. Depend on
+ options.c.
+ (start.encap): Remove superfluous lang.srcextra dependency.
+ objc/Make-lang.in (po-generated): Delete.
-2003-02-27 Geert Bosch <bosch@gnat.com>
+2004-02-05 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- * toplev.c (print_version): Add indentation for GGC heuristics and
- output after printing version information.
+ * config/mips/iris5gas.h (PREFERRED_DEBUGGING_TYPE): Define.
-2003-02-27 James E Wilson <wilson@tuliptree.org>
+2004-02-05 Andreas Krebbel <krebbel1@de.ibm.com>
- PR bootstrap/9255
- * combine.c (simplify_comparison): Require integral mode when
- permuting SUBREG with AND.
+ * config/s390/s390.md ("*tmqidi_ext"): New insn.
+ ("*extendqidi2_short_displ", "*extendsiqi2_short_displ"): Old
+ pre-reload splitters are transformed to post-reload
+ define_insn_and_split patterns.
+ ("*tmqisi_ext"): Renamed old "*tmqi_ext".
-2003-02-27 Steve Ellcey <sje@cup.hp.com>
+2004-02-05 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- * config/ia64/hpux.h (STARTFILE_PREFIX_SPEC): Remove.
+ PR middle-end/13750
+ Revert:
+ 2004-01-15 Geoffrey Keating <geoffk@apple.com>
+ PR pch/13361
+ * c-typeck.c (constructor_asmspec): Delete.
+ (struct initializer_stack): Delete field 'asmspec'.
+ (start_init): Delete saving of asmspec.
+ (finish_init): Don't update constructor_asmspec.
+ * dwarf2out.c (rtl_for_decl_location): Duplicate string from tree.
+ * stmt.c (expand_asm): Duplicate strings from tree.
+ (expand_asm_operands): Likewise.
+ * tree.c (tree_size): Update computation of size of STRING_CST.
+ (make_node): Don't make STRING_CST nodes.
+ (build_string): Allocate string with tree node.
+ * tree.def (STRING_CST): Update comment.
+ * tree.h (TREE_STRING_POINTER): Adjust for change to STRING_CST.
+ (tree_string): Place contents of string in tree node.
+ * config/sh/sh.c (sh_handle_sp_switch_attribute): Duplicate string
+ from tree.
-2003-02-27 Alan Modra <amodra@bigpond.net.au>
+2004-02-05 Joseph S. Myers <jsm@polyomino.org.uk>
- * config/rs6000/rs6000.md: Add TI constant splitter.
+ * diagnostic.h (DEFINE_DIAGNOSTIC_KIND): Change parameter M to
+ msgid.
-2003-02-26 Jan Hubicka <jh@suse.cz>
+2004-02-05 Paul Brook <paul@codesourcery.com>
- * expr.c (emit_group_store): Fix crash when converting single
- register into complex register.
+ Backport from mainline.
-2003-02-26 Michael Matz <matz@suse.de>
+ 2003-11-22 Phil Edwards <phil@codesourcery.com>
+
+ PR target/12476
+ * config/arm/arm.c (arm_output_mi_thunk): In Thumb mode, use
+ 'bx' instead of 'b' to avoid branch range restrictions. Output
+ the thunk immediately before the thunked-to function.
+ * config/arm/arm.h (ARM_DECLARE_FUNCTION_NAME): Do not emit
+ .thumb_func if a thunk is being generated. Emit .code 16 along
+ with .thumb_func if a thunk is not being generated.
+
+ 2003-11-05 Mark Mitchell <mark@codesourcery.com>
+
+ * calls.c (initialize_argument_information): Add CALL_FROM_THUNK_P
+ parameter. Use it instead of current_function_is_thunk.
+ * function.h (struct function): Update documentation for is_thunk.
+ * tree.h (CALL_FROM_THUNK_P): New macro.
+ * config/alpha/alpha.c (alpha_sa_mask): Do not check
+ no_new_pseudos when testing current_function_is_thunk.
+ * config/rs6000/rs6000.c (rs6000_ra_ever_killed): Likeiwse.
+
+2004-02-05 Joseph S. Myers <jsm@polyomino.org.uk>
- * ra-colorize.c (merge_moves): Fix list handling.
+ * sourcebuild.texi (Test Idioms): Update testcase naming
+ conventions.
+
+2004-02-04 Per Bothner <per@bothner.com>
+
+ Partially revert/redo 2003-10-01 change; fix -fworking-directory.
+ * c-ppoutput.c (pp_dir_change): New function.
+ * c-common.h (pp_dir_change): New declaration.
+ * cpplib.h (struct cpp_options): Remove working_directory field.
+ * cppinit.c (cpp_find_main_file, cpp_push_main_file): Merge back to
+ (cpp_read_main_file): as before 10-01. Call _cpp_stack_file.
+ Don't handle -fworking_directory here, but in c_common_post_options.
+ (read_original_directory): Don't back up when done.
+ Don't clear no-longer used working_directory flag.
+ * cpplib.h: Update declarations to match.
+ * c-lex.c (cb_dir_change): Move to c-opts.c.
+ (init_c_lex): Don't set dir_change callback here, since we want
+ to set it even if flag_preprocess_only.
+ * c-opts.c (cb_dir_change): Function moved from c-lex.c.
+ (c_common_post_options): Set dir_change callback.
+ Call pp_dir_change if approporiate.
+ (finish_options): Don't call cpp_find_main_file here. Hence remove
+ unneeded parameter and result. Do LC_RENAME for <built-in>.
+ (c_common_post_options): Call cpp_read_main_file here instead.
+ (c_common_init): Update accordingly.
+ (push_command_line_include): Don't cpp_push_main_file.
+ Do LC_RENAME rather than LC_LEASE to get back to main file.
+ Compared to pre-10-01 version, inline cpp_rename_to_main_file.
+ (c_common_parse_file): Call cpp_read_main_file for subsequent main
+ files, but call finish_options for all files.
+ * c-opts.c (sanitize_cpp_opts): Don't set cpp_opts->working_directory.
+ * fix-header.c (read_scan_file): Call cpp_read_main_file instead of
+ cpp_find_main_file + cpp_push_main_file.
+ * c-lex.c (fe_file_change): Don't set main_input_filename here.
+ * opts.c (handle_options): Only set main_input_filename first time.
+
+2004-02-04 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * Makefile.in: Move target, host overrides after per-language
+ fragments.
+
+ * config/mips/t-iris5-as (FORCE_DEBUG_ADAFLAGS): Clear.
+ (GNATLIBCFLAGS): Remove -g.
+
+2004-02-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_pass_by_reference): Return 1
+ for all modes whose size is greater than 8 bytes if ARCH32.
+ (sparc_va_arg): Handle all modes whose size is greater than 8 bytes
+ by reference if ARCH32.
+
+2004-02-04 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*la_64" + peepholes, "reload_indi"): Move
+ to before adddi3 insn patterns.
+ ("*la_31" + peepholes, "*la_31_and", "*la_31_and_cc", "force_la_31",
+ "reload_insi"): Move to before addsi3 insn patterns.
+
+2004-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/interface.texi, doc/tm.texi, doc/trouble.texi: Don't
+ mention deprecated target macros.
+
+2004-02-03 Wolfgang Bangerth <bangerth@dealii.org>
+
+ * doc/invoke.texi (x86 options): Fix spelling/wording.
+
+2004-02-03 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/iris5.h (ASM_OUTPUT_ASCII): Use mips_output_ascii to
+ put the original string in a comment.
+ * config/mips/mips-protos.h (mips_output_ascii): Add prefix argument.
+ * config/mips/mips.c (mips_output_ascii): Likewise.
+ * config/mips/mips.h (ASM_OUTPUT_ASCII): Adjust accordingly.
+
+2004-02-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13975
+ * tree.h (enum tree_index): Add TI_PUBLIC, TI_PROTECTED, and
+ TI_PRIVATE.
+ (access_public_node): Redefine.
+ (access_protected_node): Likewise.
+ (access_private_node): Likewise.
+ * tree.c (build_common_tree_nodes): Create access_public_node,
+ access_protected_node, and access_private_node.
+
+2004-02-03 Alan Modra <amodra@bigpond.net.au>
-2003-02-26 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+ PR target/13914
+ * config/rs6000/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Use ap
+ for retaddr_column.
+
+2004-02-03 Kelley Cook <kcook@gcc.gnu.org>
+
+ * opts.c (OPT_fwritable_strings): Deprecate -fwritable-strings.
- * pa.c (compute_frame_size): Don't assume PREFERRED_STACK_BOUNDARY
- is 8 * STACK_BOUNDARY.
- * pa.h (PREFERRED_STACK_BOUNDARY): Change to 128 on 64-bit port.
+2004-02-03 Steven Bosscher <s.bosscher@student.tudelft.nl>
-2003-02-26 Alan Modra <amodra@bigpond.net.au>
+ * toplev.c: Fix broken checkin of 2003-12-30, again.
- PR target/9681
- * tlink.c (scan_linker_output): Drop leading '.' from symbol names.
+2004-02-02 Eric Christopher <echristo@redhat.com>
+ Zack Weinberg <zack@codesourcery.com>
-2003-02-25 Richard Henderson <rth@redhat.com>
+ * c-opts.c (c_common_handle_option): Add -finput-charset.
+ * c.opt: Ditto.
+ * cppcharset.c (_cpp_convert_input): New function.
+ (_cpp_default_encoding): Ditto.
+ * cpphash.h: Add prototypes for above.
+ * cppfiles.c (read_file_guts): Use _cpp_convert_input.
+ * cppinit.c (cpp_create_reader): Use _cpp_default_encoding
+ for narrow execution and input character sets.
+ * doc/cppopts.texi: Document -finput-charset.
- * config/i386/i386.c (function_arg): Pass variable sized
- structures correctly on the stack.
+2004-02-02 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-02-25 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+ * doc/invoke.texi (SPARC options): Further improve.
- PR target/9732
- * config/rs6000/rs6000.c (first_reg_to_save): Handle
- PIC_OFFSET_TABLE_REGNUM for -fPIC too.
- (rs6000_emit_prologue): Likewise.
- (rs6000_emit_epilogue): Likewise.
- * config/rs6000/rs6000.h (CONDITIONAL_REGISTER_USAGE): Make
- PIC_OFFSET_TABLE_REGNUM a fixed register for -fPIC.
+2004-02-02 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-02-25 Richard Henderson <rth@redhat.com>
+ * config/sparc/sparc.c (function_arg_slotno): Align TImode
+ arguments on a 16-byte boundary in the parameter array if ARCH64.
+ Split handling of TFmode.
- * real.c (real_to_integer2): Force overflow result only for
- unsigned overflow.
+2004-02-02 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-02-25 Jan Hubicka <jh@suse.cz>
+ * doc/invoke.texi (SPARC options): Document that -mflat is deprecated.
- PR target/8343
- * m68k.md (umulsidi, mulsidi expanders): Use register operand.
+2004-02-01 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-02-24 Svein E. Seldal <Svein.Seldal@solidas.com>
+ * config/sparc/sol2-bi.h: Handle TARGET_CPU_ultrasparc3.
+ (CPP_CPU_SPEC): Handle -mcpu=ultrasparc3.
+ (ASM_CPU_SPEC): Likewise
+ * config/sparc/sol2.h: Handle TARGET_CPU_ultrasparc3.
+ (ASM_CPU_SPEC): Remove -mcpu=v8plus. Handle -mcpu=ultrasparc3.
- * config/c4x/c4x.h (ASM_FILE_START): Added support for the c33
- processor.
+2004-02-01 Jan Hubicka <jh@suse.cz>
-2003-02-24 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+ PR c++/12850
+ * cgraph.c (cgraph_remove_node): Clear out saved/insns/arguments and
+ initial pointers.
+ * cgraphunit.c (cgraph_finalize_function): Clear out DECL_SAVED_INSNS
+ for functions that will be only inlined.
+ (cgraph_mark_function_to_output): Likewise.
+ (cgraph_expand_function): Sanity check that DECL_DEFER_OUTPUT is clear;
+ do not clear function body.
+ * tree-optimize.c (clear_decl_rtl): Use decl_function_context.
+ (tree_rest_of_compilation): Reorganize the logic releasing function
+ body to use callgraph datastructure.
- * config/mips/iris6.h (TARGET_OS_CPP_BUILTINS): Define __c99 for
- ISO C99 and C++.
+2004-02-01 Richard Sandiford <rsandifo@redhat.com>
- * fixinc/inclhack.def (irix___restrict): Don't change __restrict
- for C++ on IRIX 6.5.1[89].
- * fixinc/tests/base/internal/sgimacros.h: New file.
+ * config/mips/mips.md (adddi3_internal_2): Remove superfluous %s.
- * fixinc/inclhack.def (irix_wcsftime): Use XPG5 variant for C99.
- * fixinc/tests/base/internal/wchar_core.h: New file.
+2004-01-31 Eric Botcazou <ebotcazou@libertysurf.fr>
- * fixinc/inclhack.def (irix_socklen_t): Fix broken IRIX 6.5.1[78]
- socklen_t definition.
- * fixinc/fixincl.x: Regenerate.
- * fixinc/tests/base/sys/socket.h: New file.
- Fixes PR libgcj/9652.
+ * doc/invoke.texi (SPARC options): Restructure and update.
-2003-02-24 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
- * config/alpha/osf.h (TARGET_OS_CPP_BUILTINS): Rename
- __EXTERN_PREFIX to __PRAGMA_EXTERN_PREFIX.
- * doc/extend.texi (Tru64 Pragmas): Reflect this.
+ * doc/invoke.texi: Follow spelling conventions.
+ * doc/tm.texi: Likewise.
- * fixinc/inclhack.def (alpha___extern_prefix): Indicate #pragma
- extern_prefix support for Tru64 UNIX V5 <sys/stat.h>.
- * fixinc/fixincl.x: Regenerate.
- * fixinc/tests/base/sys/stat.h [ALPHA___EXTERN_PREFIX_CHECK]: New
- testcase.
- Fixes PR c/5059, c/6126, other/9671.
-
-2003-02-24 Alan Modra <amodra@bigpond.net.au>
-
- PR 9297, PR 9722
- * calls.c (store_one_arg): Revert 1999-02-16 change. Revert
- 2000-12-17 change. Pass EXPAND_STACK_PARM to expand_expr.
- * expr.h (enum expand_modifier): Define EXPAND_STACK_PARM.
- (enum block_op_methods): Reorder for better store_expr optimization.
- * expr.c (store_expr): Test bit 1 of "want_value" for call param
- stores, test bit 0 for original want_value meaning. Pass
- BLOCK_OP_CALL_PARM to emit_block_move when bit 1 set. Adjust
- recursive calls, and calls to expand_param.
- (expand_expr): Handle EXPAND_STACK_PARM modifier. When cse
- expected, set target to 0 rather than to subtarget. Formatting.
-
-2003-02-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * doc/invoke.texi (ggc-min-expand, ggc-min-heapsize): Document
- new default behavior.
- * ggc-common.c: Include sys/resource.h.
- (ggc_rlimit_bound): New function.
- (ggc_min_expand_heuristic, ggc_min_heapsize_heuristic): Update
- defaults to account for rlimits.
-
-2003-02-22 Jan Hubicka <jh@suse.cz>
-
- * config/linux.h (TARGET_HAS_F_SETLKW): Define.
- * config/alpha/linux.h (TARGET_HAS_F_SETLKW): Likewise
-
-2003-02-22 Hans-Peter Nilsson <hp@axis.com>
-
- * regmove.c (optimize_reg_copy_1): Do not replace a hard register
- in an asm.
-
-2003-02-22 Jan Hubicka <jh@suse.cz>
-
- * i386.c (builtin_description): Add __builtin_ia32_paddq and
- __builtin_ia32_psubq. Fix __builtin_ia32_paddq128
- and __builtin_ia32_psubq128.
- * i386.h (IX86_BUILTIN_PADDQ, IX86_BUILTIN_PSUBQ): New.
- * i386.md (addv*, mmx_ior*, mmx_xoe*, mmx_and*): Add missing '%'.
- (mmx_adddi3, mmx_subdi3): New.
- * mmintrin.h (_mm_add_si64, _mm_sub_si64): New.
- * xmmintrin.h (_mm_movepi64_pi64): New.
- (_mm_add_epi64, _mm_sub_epi64): fix.
- (_mm_mul_pu16): Rename to...
- (_mm_mul_su32): ... this one.
-
- * i386.c (def_builtin): Special case 64bit builtins.
- (MASK_SSE164, MASK_SSE264): New constants.
- (builtin_description): Add 64bit builtins.
- (ix86_init_mmx_sse_builtins): Likewise.
- * i386.h (enum ix86_builtins): Likewise.
- * i386.md (cvtss2siq, cvttss2siq, cvtsd2siq, cvttsd2siq, cvtsi2sdq,
- sse2_movq2dq_rex64, sse2_movsq2q_rex64): New.
- (sse2_movq2dq, sse2_movsq2q): Disable for 64bit.
- * mmintrin.h (_mm_cvtsi64x_si64, _mm_set_pi64x, _mm_cvtsi64_si64x): New.
- * xmmintrin.h (_mm_cvtss_si64x, _mm_cvttss_si64x, _mm_cvtsi64x_ss,
- _mm_set_epi64x, _mm_set1_epi64x, _mm_cvtsd_si64x, _mm_cvttsd_si64x,
- _mm_cvtsi64x_sd, _mm_cvtsi64x_si128, _mm_cvtsi128_si64x): New.
-
- * builtins.c (expand_builtin_expect): Do not predict
- flag_guess_branch_prob is not set.
- * c-semantics.c (expand_stmt): Likewise.
- * predict.c (predict_insn): Likewise.
- * stmt.c (expand_continue_loop): Likewise.
- * toplev.c (rest_of_compilation): Do not call
- note_prediction_to_br_prob and note_prediction_to_br_prob
- when not optimizing.
-
- * basic-block.h (tidy_fallthru_edges): Kill.
- * cfgrtl.c (tidy_fallthru_edges): Kill.
- * cfgbuild.c (find_basic_blocks): Do not call tidy_fallthru_edges.
- * cfgcleanup.c (delete_unreachable_blocks): Likewise.
-
-2003-02-22 Steven Bosscher <s.bosscher@student.tudelft.nl>
-
- PR other/3782
- * toplev.c (process_options): If flag_detailed_statistics is set,
- then set time_report as well.
-
- PR c/8828
- * jump.c (never_reached_warning): Don't fall through BARRRIER
- insns. Update comments to reflect what the function really does.
-
-2003-02-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * doc/invoke.texi (ggc-min-expand, ggc-min-heapsize): Update
- documentation.
- * ggc-common.c: Include params.h
- (ggc_min_expand_heuristic, ggc_min_heapsize_heuristic,
- init_ggc_heuristics): New functions.
- * ggc.h (ggc_min_expand_heuristic, ggc_min_heapsize_heuristic,
- init_ggc_heuristics): Prototype.
- * toplev.c (print_version): Output GGC heuristics.
- (parse_options_and_default_flags): Call init_ggc_heuristics.
-
-2003-02-21 Jan Hubicka <jh@suse.cz>
-
- * cfgrtl.c (commit_edge_insertions): Call
- find_many_sub_basic_block only when some code has been emitted.
- (commit_edge_insertions_watch_calls): Bring into sync with
- commit_edge_insertions
-
-2003-02-21 Zack Weinberg <zack@codesourcery.com>
-
- * cpphash.h (struct lexer_state): Add directive_wants_padding.
- * cpplib.c (_cpp_handle_directive): Set directive_wants_padding
- for directives of type INCL.
- (glue_header_name, parse_include): Use get_token_no_padding.
- * cppmacro.c (replace_args): If directive_wants_padding,
- provide padding tokens.
-
-2003-02-21 Jan Hubicka <jh@suse.cz>
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
- * cfgrtl.c (commit_one_edge_insertion): Only mark BB for splitting.
- (commit_edge_insertions): Call find_many_sub_basic_blocks
-
- * reg-stack.c (convert_regs): Cleax aux for blocks.
-
-2003-02-21 Glen Nakamura <glen@imodulo.com>
-
- PR optimization/8613
- * builtins.c (expand_builtin): Emit postincrements before expanding
- builtin functions.
-
-2003-02-21 Toon Moene <toon@moene.indiv.nluug.nl>
-
- PR fortran/9038
- * c-opts.c (sanitize_cpp_opts): Add Fortran front end
- options to be ignored.
- (c_common_decode_option): Ignore them when preprocessing.
-
-2003-02-21 Ben Elliston <bje@redhat.com>
-
- PR other/5634
- * doc/install.texi (Configuration): Explain using $HOME instead of
- the ~ metacharacter when referring to home directories.
-
-2003-02-20 Richard Earnshaw <rearnsha@arm.com>
-
- * arm.c (arm_reload_in_hi): Ensure that the scratch register does
- not overlap the final result register.
-
-2003-02-20 Josef Zlomek <zlomekj@suse.cz>
-
- * combine.c (distribute_notes): Kill REG_EXEC_COUNT.
- * rtl.c (reg_note_name): Likewise.
- * rtl.h (enum reg_note): Likewise.
+ * doc/install.texi: Fix typos.
* doc/invoke.texi: Likewise.
- * doc/rtl.texi: Likewise.
-
-2003-01-30 Richard Henderson <rth@redhat.com>
-
- * tree-inline.c (walk_tree): Streamline duplicate hash table lookup.
-
-2003-02-19 Daniel Jacobowitz <drow@mvista.com>
-
- * expr.c (expand_expr): Use gen_int_mode for the argument
- to gen_rtx_MULT.
-
-2003-02-19 Jan Hubicka <jh@suse.cz>
-
- * i386.md (cosxf2): Fix conditional.
-
-2003-02-18 Matt Austern <austern@apple.com>
- * toplev.c, langhooks.c, langhooks-def.h: Move
- write_global_declarations from toplev.c to langhooks.c.
-
-2003-02-18 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (general_operand_src): Always check
- MODE.
- (general_operand_dst): Likewise.
-
-2003-02-18 Richard Henderson <rth@redhat.com>
-
- * c-common.c (handle_used_attribute): Accept static data too.
-
-2003-02-18 Jim Wilson <wilson@redhat.com>
-
- * config/ia64/ia64.md (floatdidf2, floatdisf2): Add %, before second
- instruction in output template.
- (bsp_value): Change output template from string to C code, add %,
- before actual instruction.
- (flushrs): Mark as not predicable.
-
-2003-02-18 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (*zero_extendhisi2_h8300): Fix the
- insn length.
- (extendqisi2): Likewise.
- (*extendhisi2_h8300): Likewise.
-
-2003-02-18 Matt Austern <austern@apple.com>
-
- * langhooks.h, langhooks-def.h: introduce new langhook,
- final_write_globals, with write_global_declarations as default.
- * toplev.c: Move invocation of wrapup_global_declarations from
- compile_file to new function, write_global_declarations. Change
- compile_file to use final_write_globals hook. Change
- wrapup_global_declarations so writing to DECL_DEFER_OUTPUT is
- conditional.
-
-2003-02-18 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- * pa.md: Correct and enhance comment.
-
-2003-02-16 Kai Henningsen <kaih@khms.westfalen.de>
- Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/install.texi (Specific): Fix link for m68k-att-sysv.
- (Binaries): Ditto for Sinix/Reliant Unix.
-
-2003-02-16 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
-
- * config/i386/i386-protos.h (function_arg_pass_by_reference): Declare.
- * config/i386/i386.h (FUNCTION_ARG_PASS_BY_REFERENCE): Use it.
- * config/i386/i386.c (function_arg_pass_by_reference): New.
- (ix86_va_arg): Support arguments passed by reference.
-
-2003-02-16 Arend Bayer <arend.bayer@web.de>
- Richard Henderson <rth@redhat.com>
-
- PR c/8068
- * fold-const.c (extract_muldiv_1): Rename from extract_muldiv;
- rearrange mult arguments for less recursion.
- (extract_muldiv): New. Prevent runaway recursion.
-
-2003-02-16 Danny Smith <dannysmith@users.sourceforge.net>
-
- * config/i386/cygwin.h (TARGET_SUBTARGET_DEFAULT): Set
- MASK_ALIGN_DOUBLE.
-
-2003-02-15 Adam Nemet <anemet@lnxw.com>
-
- PR opt/2391
- * combine.c: Fix spelling in comment.
- (cached_nonzero_bits): New function.
- (cached_num_sign_bit_copies): New function.
- (nonzero_bits_with_known): New macro.
- (num_sign_bit_copies_with_known): New macro.
- (nonzero_bits1): Rename from nonzero_bits. Add three new
- arguments. Change calls from nonzero_bits to
- nonzero_bits_with_known.
- (num_sign_bit_copies1): Rename from num_sign_bit_copies. Add
- three new arguments. Change calls from num_sign_bit_copies to
- num_sign_bit_copies_with_known.
- (nonzero_bits): New macro.
- (num_sign_bit_copies): New macro.
- (update_table_tick): Don't traverse identical subexpression more
- than once.
- (get_last_value_validate): Likewise.
-
-2003-02-15 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
-
- PR optimization/7702
- * reload1.c (reload_cse_simplify_set): Honor
- CANNOT_CHANGE_MODE_CLASS.
-
-2003-02-15 Jan Hubicka <jh@suse.cz>
-
- PR optimization/9258, PR fortran/7681
- * global.c (struct allocno): Add no_stack_reg.
- (global_conflicts): Set it.
- (find_reg): Use it.
-
-2003-02-14 Alexandre Oliva <aoliva@redhat.com>
-
- * config/mn10300/mn10300.c (mn10300_wide_const_load_uses_clr): New
- function.
- * config/mn10300/mn10300-protos.h: Declare it.
- * config/mn10300/mn10300.md (movdi, movdf): Use it to compute
- attribute cc of instructions that may use clr.
-
-2003-02-13 John David Anglin <dave.anglin@nrc-crnc.gc.ca>
-
- * inclhack.def (hpux_long_double): Tighten select and add bypass
- regexp.
- * fixincl.x: Rebuilt.
-
-2003-01-30 Richard Henderson <rth@redhat.com>
-
- * ggc-page.c (G.context_depth_allocations): New.
- (G.context_depth_collections): New.
- (alloc_page): Set G.context_depth_allocations.
- (ggc_collect): Set G.context_depth_collections.
- (ggc_push_context): Limit to HOST_BITS_PER_LONG contexts.
- (ggc_pop_context): Early exit for no allocations or collections.
-
-2003-01-25 Segher Boessenkool <segher@koffie.nl>
-
- * bitmap.h (BITMAP_WORD): New typedef: fundamental storage
- type for bitmaps. Use unsigned long.
- (nBITMAP_WORD_BITS): New macro.
- (BITMAP_WORD_BITS): New macro.
- (rest of file): Use it.
- * bitmap.c: Use it.
-
-2003-02-13 Josef Zlomek <zlomekj@suse.cz>
-
- * cfgcleanup.c (outgoing_edges_match): When there is single outgoing
- edge and block ends with a jump insn it must be simple jump.
-
-2003-02-13 Robert Lipe <robertlipe@usa.net>
- Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/install.texi (Specific): Update three SCO-related URLs.
-
-2003-02-12 Ranjit Mathew <rmathew@hotmail.com>
-
- * doc/tm.texi (MODIFY_JNI_METHOD_CALL): Document.
- * config/i386/cygwin.h (MODIFY_JNI_METHOD_CALL): New macro.
-
-2003-02-11 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/install.texi (Specific): Update AVR- and Darwin-related URLs.
-
-2003-02-11 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR c/9100
- Backport patch from mainline:
-
- 2003-01-12 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9264
- * c-lex.c (c_lex): Set the token value to error_mark_node for
- invalid numeric constants.
-
-2003-02-11 Jan Hubicka <jh@suse.cz>
-
- * i386.md (ahi?v*3): Set third operand type to TImode.
- * i386.c (ix86_expand_binop_builtin): Extend operand when needed.
-
- * i386.c (contains_128bit_aligned_vector_p): New function
- (ix86_function_arg_boundary): Properly align vector modes.
-
-2003-02-11 Bob Wilson <bob.wilson@acm.org>
-
- Backport following patch:
-
- 2003-02-11 Bob Wilson <bob.wilson@acm.org>
-
- * config/xtensa/xtensa.md (set_frame_ptr): Change rtl to set reg a7.
- * config/xtensa/xtensa.c (xtensa_reorg): Search for UNSPECV_SET_FP
- as a SET pattern.
-
-2003-02-11 Jan Hubicka <jh@suse.cz>
-
- * simplify-rtx.c (simplify_subreg): Fix conversion from vector into
- integer mode.
-
- * rtl.def (VEC_MERGE, VEC_SELECT, VEC_CONCAT, VEC_DUPLICATE):
- Change code so they are arithmetic expressions now.
- * simplify-rtx.c (simplify_unary_operation, simplify_binary_operation,
- simplify_ternary_operation): Deal with VEC_* expressions.
-
-2003-02-11 Richard Henderson <rth@redhat.com>
-
- 2003-01-15 Richard Henderson <rth@redhat.com>
- * config/alpha/alpha.c (find_lo_sum_using_gp): Rename from find_lo_sum;
- also check that GP is being used.
- (alpha_find_lo_sum_using_gp): New.
- (alpha_does_function_need_gp): Use get_attr_usegp.
- * config/alpha/alpha-protos.h: Update.
- * config/alpha/alpha.md (attr usegp): New. Annotate patterns
- as needed.
-
-2003-02-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- * inclhack.def (hpux_long_double, hpux10_ctype_declarations1,
- hpux10_ctype_declarations2, hpux_ctype_macros): New hacks.
- * fixincl.x: Rebuilt.
- * tests/base/stdlib.h: Update.
- * tests/base/ctype.h: New file.
-
-2003-02-11 Janis Johnson <janis187@us.ibm.com>
-
- * config/rs6000/ppc64-fp.c: New file.
- * config/rs6000/t-linux64 (LIB2FUNCS_EXTRA): Add ppc64-fp.c.
-
-2003-02-11 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
-
- PR optimization/9651
- * rtlanal.c (may_trap_p): Handle FIX.
-
-2003-02-11 Jan Hubicka <jh@suse.cz>
-
- * predict.c (choose_function_section): Choose sections correctly.
-
-2003-02-10 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- * reload1.c (first_label_num): New.
- (reload): Index offsets_known_at and offsets_at using difference of
- label number and first label number. Don't use offset pointers.
- (set_label_offsets, set_initial_label_offsets): Likewise.
-
-2003-02-10 Eric Botcazou <ebotcazou@libertysurf.fr>
- Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
- PR c/7741
- * c-decl.c (duplicate_decls): Discard the initializer of the
- new decl when the types are conflicting.
-
-2003-02-09 Wolfgang Bangerth <bangerth@ticam.utexas.edu>
-
- * doc/install.texi: Squeeze and streamline section on
- testing and regression checking.
-
-2003-02-07 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/t-netbsd (USER_H): Revert previous change.
-
-2003-02-07 Richard Henderson <rth@redhat.com>
-
- PR 9226
- * gcse.c (local_cprop_find_used_regs): New.
- (local_cprop_pass): Use it.
-
-2003-02-07 Jan Hubicka <jh@suse.cz>
-
- * i386.md (sse2_nandv2di3): Fix.
-
- * i386.md (movdi_rex64_1): Fix mmx<->int move opcode.
-
-2003-02-07 Andrey Petrov <petrov@netbsd.org>
-
- * optabs.c (expand_float): Search wider integer modes first.
-
-2003-02-06 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- * config.gcc (hppa*-*-linux*): Set MASK_NO_SPACE_REGS in
- target_cpu_default.
- * pa.c (attr_length_call): Add 8 to call length (long indirect PA 1.X)
- if not MASK_NO_SPACE_REGS.
- (output_call): Adjust return pointer, don't load new space register
- into %sr0, and use %sr4 for call if TARGET_NO_SPACE_REGS is true.
- (pa_asm_output_mi_thunk): Don't load new space register into %sr0 if
- TARGET_NO_SPACE_REGS is true.
- * pa.md (return_external_pic): Add TARGET_NO_SPACE_REGS to insn
- conditions.
- (epilogue): Always use return_internal if TARGET_NO_SPACE_REGS is true.
- (interspace_jump): Add new pattern for when TARGET_NO_SPACE_REGS is
- true. Use bve when TARGET_64BIT is true.
-
-2003-02-06 Eric Botcazou <ebotcazou@libertysurf.fr>
- Richard Henderson <rth@redhat.com>
-
- PR c/9530
- * config/i386/i386.h (FUNCTION_OK_FOR_SIBCALL): Forbid sibcalls
- from functions that return a float to functions that don't.
-
-2003-02-04 Ulrich Weigand <uweigand@de.ibm.com>
-
- * reload.c (find_reloads): Do not use the mode specified in the insn
- pattern as reload mode for address operands. Do not generate optional
- reloads for operands where a mandatory reload was already pushed.
-
-2003-02-04 Jan Hubicka <jh@suse.cz>
-
- * i386.md (movti_rex64): Fix constraint.
-
-2003-02-04 Rodney Brown <rbrown64@csc.com.au>
-
- * config/i386/i386.c (x86_function_profiler): Fix typo in format.
-
-2003-01-23 Mike Stump <mrs@apple.com>
-
- * regclass.c (init_reg_autoinc): New function.
- (regclass): Move initialization of forbidden_inc_dec_class from
- here...
- (init_regs): to here. Avoids reinitialization for each function,
- saving compilation time.
-
-2003-02-04 Phil Edwards <pme@gcc.gnu.org>
-
- * doc/install.texi (*-*-linux-gnu): Mention glibc requirements
- for recent libstdc++. Remove formatting cruft.
-
-2003-02-04 Joseph S. Myers <jsm@polyomino.org.uk>
-
- * doc/gcc.texi, doc/gccint.texi, doc/gcov.texi,
- doc/include/fdl.texi, doc/invoke.texi: Update to GFDL 1.2.
- * doc/install.texi: Update copyright dates. Update to GFDL 1.2.
-
-2003-02-03 Bob Wilson <bob.wilson@acm.org>
-
- * config/xtensa/xtensa.c (order_regs_for_local_alloc): Order the
- coprocessor registers before floating-point registers.
- * config/xtensa/xtensa.h (REG_ALLOC_ORDER): Adjust register numbers
- to account for a previously removed register.
- (SPEC_REG_FIRST, SPEC_REG_LAST, SPEC_REG_NUM, COUNT_REGISTER_REGNUM):
- Delete unused macros.
-
-2003-02-03 Jan Hubicka <jh@suse.cz>
-
- * i386.c (ix86_expand_store_builtin): Always force op1 to register.
- (mov*_internal): Fix predicates; require one of operands to not be memory.
- (SSE?MMX move expanders): Fix predicates; force one of operands to register.
- (SSE/MMX push patterns): Reorganize; fix x86-64 code generation.
- (movups/movupd/movdqu patterns): Force one of operands to not be memory.
-
-2003-02-03 Jan Hubicka <jh@suse.cz>
-
- * regclass.c (cannot_change_mode_set_regs): Correct argument order.
-
-2003-02-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * mips/_tilib.c: Don't include tsystem.h. Don't define
- LIBGCC2_WORDS_BIG_ENDIAN.
-
-2003-02-02 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2004-01-31 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_decompose_address): Do not treat virtual
+ registers as pointers.
+ * config/s390/s390.md ("*la_31" second peephole2): Fix incorrect mode.
+
+2004-01-31 Jan Hubicka <jh@suse.cz>
+
+ Revert the following patch until after AIX linker bug is fixed:
+ PR c++/12850
+ * cgraph.c (cgraph_remove_node): Clear out saved/insns/arguments and
+ initial pointers.
+ * cgraphunit.c (cgraph_finalize_function): Clear out DECL_SAVED_INSNS
+ for functions that will be only inlined.
+ (cgraph_mark_function_to_output): Likewise.
+ (cgraph_expand_function): Sanity check that DECL_DEFER_OUTPUT is clear;
+ do not clear function body.
+ * tree-optimize.c (clear_decl_rtl): Use decl_function_context.
+ (tree_rest_of_compilation): Reorganize the logic releasing function
+ body to use callgraph datastructure.
+
+2004-01-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ alloc-pool.c, alloc-pool.h, c-lex.c, c-pragma.h,
+ tree-optimize.c, config/alpha/alpha.c, config/alpha/alpha.h,
+ config/alpha/alpha.md, config/alpha/vms.h, config/arm/arm.h,
+ config/arm/linux-elf.h, config/avr/avr.c, config/c4x/c4x.c,
+ config/c4x/c4x.md, config/d30v/d30v.h,
+ config/frv/frv-protos.h, config/frv/frv.c, config/frv/frv.h,
+ config/frv/frv.md, config/frv/frvbegin.c, config/frv/frvend.c,
+ config/i386/cygming.h, config/i386/djgpp.h,
+ config/i386/emmintrin.h, config/i386/gthr-win32.c,
+ config/i386/i386-interix.h, config/i386/i386-protos.h,
+ config/i386/i386.c, config/i386/i386.h, config/i386/openbsd.h,
+ config/i386/winnt.c, config/i386/xm-mingw32.h,
+ config/i386/xmmintrin.h, config/ia64/ia64-protos.h,
+ config/ia64/ia64.c, config/ia64/ia64.md, config/ip2k/ip2k.c,
+ config/iq2000/iq2000-protos.h, config/iq2000/iq2000.c,
+ config/iq2000/iq2000.md, config/m32r/m32r-protos.h,
+ config/m32r/m32r.c, config/m32r/m32r.md, config/m68k/m68k.md,
+ config/m68k/netbsd-elf.h, config/mcore/mcore-elf.h,
+ config/mcore/mcore.c, config/mcore/mcore.h,
+ config/mcore/mcore.md, config/mips/elf.h, config/mips/elf64.h,
+ config/mips/iris5gas.h, config/mips/iris6.h,
+ config/mips/iris6gas.h, config/mips/linux.h,
+ config/mips/mips.md, config/mips/netbsd.h,
+ config/mips/openbsd.h, config/mips/windiss.h,
+ config/mn10300/mn10300.c, config/mn10300/mn10300.h,
+ config/pdp11/pdp11.c, config/rs6000/aix.h,
+ config/rs6000/altivec.h, config/rs6000/darwin.h,
+ config/rs6000/xcoff.h, config/s390/s390-protos.h,
+ config/s390/s390.c, config/s390/s390.h, config/s390/s390.md,
+ config/sh/netbsd-elf.h, config/sh/sh.h, config/sh/vxworks.h,
+ config/sparc/sol2.h, config/stormy16/stormy16.h: Update
+ copyright.
+
+2004-01-30 Dara Hazeghi <dhazeghi@yahoo.com>
+
+ PR bootstrap/9249
+ * doc/install.texi: document --enable-__cxa_atexit option.
+ * configure.ac: Disable __cxa_atexit if not supported.
+ * configure: Regenerate.
- * doc/install.texi (hppa*-hp-hpux11*): Update installation notes.
+2004-01-30 Herman A.J. ten Brugge <hermantenbrugge@home.nl>
+
+ PR target/12978
+ * c4x.md: (movstrqi*) Use match_scratch instead of match_dup.
+ Remove movstrqi_small because it conflicts with movstrqi_large.
+
+2004-01-30 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (abs_docdir, abs_srcdir): Define.
+ (doc/%.dvi, doc/gccinstall.dvi): Use $(abs_docdir).
+
+2004-01-30 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR optimization/12147
+ * reload1.c (reload_reg_free_p): RELOAD_OTHER conflicts with
+ RELOAD_FOR_OPADDR_ADDR.
+ (reload_reg_reaches_end_p): RELOAD_FOR_OTHER_ADDRESS register
+ might be reused as RELOAD_FOR_OPADDR_ADDR register.
+
+2004-01-30 Jan Hubicka <jh@suse.cz>
+
+ * reload.c (get_secondary_mem): Fix updating of
+ secondary_memlocs_elim_used.
+
+2004-01-30 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * toplev.c: Include alloc-pool.h.
+ * Makefile.in (toplev.c): Update dependencies.
+
+2004-01-30 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.h: Update copyright.
+
+2004-01-30 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/12818
+ * varasm.c (const_hash_1) <STRING_CST>: Use the
+ address to compute the hash value if flag_writable_strings.
+ (compare_constant) <STRING_CST>: Compare the addresses
+ if flag_writable_strings.
+ (build_constant_desc): Do not copy the expression for a
+ STRING_CST if flag_writable_strings.
+
+2004-01-30 Jan Hubicka <jh@suse.cz>
+
+ PR c++/12850
+ * cgraph.c (cgraph_remove_node): Clear out saved/insns/arguments and
+ initial pointers.
+ * cgraphunit.c (cgraph_finalize_function): Clear out DECL_SAVED_INSNS
+ for functions that will be only inlined.
+ (cgraph_mark_function_to_output): Likewise.
+ (cgraph_expand_function): Sanity check that DECL_DEFER_OUTPUT is clear;
+ do not clear function body.
+ * tree-optimize.c (clear_decl_rtl): Use decl_function_context.
+ (tree_rest_of_compilation): Reorganize the logic releasing function
+ body to use callgraph datastructure.
+
+ * reload.c (secondary_memlocs_elim_used): New static variable.
+ (get_secondary_mem): Update it.
+ (find_reloads): Use it.
+
+ * alias.c (reg_base_value): Turn into varray.
+ (reg_base_value_size): Kill.
+ (old_reg_base_value): New deletable varray.
+ (alias_invariant_size): New variable.
+ (REG_BASE_VALUE): Update to use varray.
+ (find_base_value): Likewise.
+ (record_set): Likewise.
+ (record_base_value): Likewise.
+ (memrefs_conflict_p): Likewise.
+ (record_set): Likewise
+ (record_base_value): Likewise.
+ (memrefs_conflict_p): Use alias_invariant_size.
+ (init_alias_analysis): Use varray; set alias_invariant_size;
+ rescale other arrays to be sized by maxreg.
+ (end_alias_analysis): Save reg_base_value; clear alias_invariant_size.
+
+ * basic-block.h (PROP_POSTRELOAD): New macro.
+ (CLEANUP_LOG_LINKS): New.
+ * cfgcleanup.c (cleanup_cfg): Only PROP_LOG_LINKS when asked to.
+ * toplev.c (rest_of_handle_life): Preserve LOG_LINKS trought cleanup_cfg.
+
+ * alloc-pool.c: Include hashtab.h
+ (alloc_pool_descriptor): New structure
+ (alloc_pool_hash): New global variable.
+ (hash_descriptor, eq_descriptor, alloc_pool_descriptor): New.
+ (create_alloc_pool): Update statistics.
+ (free_alloc_pool): Likewise.
+ (pool_alloc): Likewise.
+ (output_info): New structure
+ (print_statistics, dump_alloc_pool_statistics): New function.
+ * alloc-pool.h (alloc_pool_def): Turn name to be constant.
+ (dump_alloc_pool_statistics): Declare.
+ * toplev.c (finalize): Dump statistics.
+
+ * varray.c: Include hashtab.h
+ (varray_descriptor): New structure.
+ (hash_descriptor, eq_descriptor, varray_descriptor,
+ print_statistics): New static functions
+ (varray_init, varray_grow): Update statistics
+ (dump_varray_statistics): New function.
+ * varray.h (dump_varray_statistics): Declare.
+ * toplev.c (finalize): Call it.
+
+2004-01-30 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * configure.ac (gcc_cv_as_dwarf2_debug_line): Enable test for
+ s390*-*-* targets by specifying a 'nop' insn.
+ * configure: Regenerate.
-2003-02-02 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2004-01-30 Eric Botcazou <ebotcazou@libertysurf.fr>
- * pa-protos.h (attr_length_millicode_call): Remove second argument.
- (attr_length_indirect_call, attr_length_indirect_call,
- attr_length_save_restore_dltp): New prototypes.
- * pa.c (attr_length_millicode_call): Remove second argument. Check
- INSN_ADDRESSES_SET_P in distance calculation.
- (output_millicode_call): Check INSN_ADDRESSES_SET_P before using
- INSN_ADDRESSES.
- (attr_length_call): Check INSN_ADDRESSES_SET_P in distance calculation.
- (output_call): Check INSN_ADDRESSES_SET_P before using INSN_ADDRESSES.
- Call attr_length_call directly.
- (attr_length_indirect_call, output_indirect_call,
- attr_length_save_restore_dltp): New functions.
- * pa.md (attr_length_millicode_call): Drop second argument from all
- patterns.
- (return_internal_pic): Delete.
- (return_external_pic): Remove use of PIC register and pic operand and
- flag checks.
- (epilogue): Use return_internal for both normal and pic code.
- (call, call_value): Emit new 32-bit pic patterns for symref and
- indirect calls. Remove uses for arg pointer and pic register.
- (call_symref_pic, call_symref_pic_post_reload, call_reg_pic,
- call_reg_pic_post_reload, call_val_symref_pic,
- call_val_symref_pic_post_reload, call_val_reg_pic,
- call_val_reg_pic_post_reload): New pre and post reload insn patterns.
- Implement define_split and define_peephole2 patterns for pre reload
- patterns.
- (call_symref_64bit, call_internal_reg_64bit, call_value_symref_64bit,
- call_value_internal_reg_64bit): Shorten names.
- (all call patterns): Explicitly indicate registers used and clobbered.
- Use attr_length_indirect_call and attr_length_save_restore_dltp for
- attribute length calculation. Move code generation for indirect calls
- to output_indirect_call.
- (sibcall, sibcall_value): Don't restore PIC register.
- (exception_receiver, builtin_setjmp_receiver): Add blockage after PIC
- register retore.
+ PR target/11475
+ * config/sparc/sparc.md (movhi_lo_sum): Tighten predicates.
-2003-02-02 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+2004-01-29 Bruce Korb <bkorb@gnu.org>
- * doc/install.texi (Testing): Simplify and compress instructions
- concerning Dejagnu.
+ * fixinc/inclhack.def(math_exception): bypass only for glibc.
+ (matherr_decl): rename & relocate as exception_structure.
+ This fix must precede the math_exception fix.
+ * fixinc/fixincl.x: regen
-2003-02-01 Daniel Jacobowitz <drow@mvista.com>
+2004-01-29 Richard Henderson <rth@redhat.com>
- * dwarf2out.c (gen_type_die): Check for typedefs before calling
- for TYPE_MAIN_VARIANT.
+ * c-parse.in (extension): Use itype.
+ (SAVE_EXT_FLAGS): Don't allocate a tree.
+ (RESTORE_EXT_FLAGS): Don't read a tree.
-2003-02-01 Ulrich Weigand <uweigand@de.ibm.com>
+2004-01-29 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- * reload.c: Revert 2003-01-31 change.
+ * c-lex.c (c_lex): Rename to...
+ (c_lex_with_flags): Add new parameter to get CPP flags.
+ (c_lex): Thunk to c_lex_with_flags while keeping the old interface.
+ * c-pragma.h (c_lex_with_flags): Declare.
-2003-02-01 Jan Hubicka <jh@suse.cz>
+2004-01-29 Roger Sayle <roger@eyesopen.com>
- PR c/9506
- * i386.c (override_options): Use DEFAULT_PCC_STRUCT_RETURN.
+ PR java/13824
+ * tree.c (unsafe_for_reeval): Handle EXIT_BLOCK_EXPR nodes specially
+ as their EXIT_BLOCK_LABELED_BLOCK operands can lead to unbounded
+ recursion.
-2003-01-31 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2004-01-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
- * pa.c (pa_output_function_prologue, pa_output_function_epilogue): Move
- updating of total_code_bytes from prologue to epilogue.
+ * pa.md: Change predicate of a peephole2 pattern from reg_or_0_operand
+ to register_operand.
-2003-01-31 Ulrich Weigand <uweigand@de.ibm.com>
+2004-01-28 Zack Weinberg <zack@codesourcery.com>
- * regclass.c (record_reg_classes): Fix incorrect argument
- to EXTRA_ADDRESS_CONSTRAINT macro.
-
-2003-01-31 Ulrich Weigand <uweigand@de.ibm.com>
-
- * reload.c (find_reloads): Do not use the mode specified in the insn
- pattern as reload mode for address operands. Do not generate optional
- reloads for operands where a mandatory reload was already pushed.
- Generate optional reloads only in the final pass though find_reloads.
- (have_replacement_p): New function.
-
-2003-01-31 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/install.texi (Testing): Remove a reference to our obsolete
- /testresults web pages and strip redundant information concerning
- test results.
- (Binaries): Refer to Microsoft Windows instead of listing all
- possible variants.
-
-2003-02-01 Jan Hubicka <jh@suse.cz>
-
- * loop.c (emit_prefetch_instructions): Do conversion at right place in
- RTL chain.
-
- * combine.c (simplify_set): Reverse order of ragumetns to
- REG_CANNOT_CHANGE_MODE_P
- * df.c (df_def_record_1): Likewise.
- * recog.c (register_operand): Likewise.
- * simplify-rtx.c (simplify_subreg): Likewise.
- * hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): Update use of
- CANNOT_CHANGE_MODE_CLASS.
- * regclass.c (cannot_change_mode_set_regs, invalid_mode_change_p):
- Likewise.
- * reload.c (push_reload): Likewise.
- * alpha.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * ia64.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * mips.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * mips-protos.h (mips_cannot_change_mode_class): Update prototype.
- * mips.c (mips_cannot_change_mode_class): Update.
- * pa64-regs.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * rs6000.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * s390.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * sh.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * sh-protos.h (sh_cannot_change_mode_class): Update prototype.
- * sh.c (sh_cannot_change_mode_class): Update.
- * i386.h (CANNOT_CHANGE_MODE_CLASS): New.
- * tm.texi (CANNOT_CHANGE_MODE_CLASS): Update documentation.
+ * config/ia64/ia64.md (fetchadd_acq_si, fetchadd_acq_di)
+ (cmpxchg_acq_si, cmpxchg_acq_di): Exchange match_dup and
+ match_operand expressions so that all match_dups appear
+ lexically after their corresponding match_operands.
-2003-01-31 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+2004-01-28 Zack Weinberg <zack@codesourcery.com>
+ Jim Wilson <wilson@specifixinc.com>
- * pa32-regs.h (REGNO_REG_CLASS, REG_CLASS_FROM_LETTER): Delete
- duplicated code.
+ * config/ia64/ia64.c (ia64_split_tmode, ia64_split_tmode_move):
+ Rewrite to use POST_INC/POST_DEC/POST_MODIFY instead of a
+ scratch pointer.
+ (ia64_secondary_reload_class): Delete case GR_REGS.
+ * config/ia64/ia64.md (movti, *movti_internal, movtf, *movtf_internal):
+ Do not allocate a scratch register.
+ (reload_inti, reload_outti, reload_intf, reload_outtf): Delete.
-2003-01-30 Richard Earnshaw <rearnsha@arm.com>
+2004-01-27 Zack Weinberg <zack@codesourcery.com>
- * arm.c (arm_compute_initial_elimination_offset): If optimizing for
- size, the link register is always saved if any other register is
- saved.
+ * ia64.c (ia64_function_arg): When placing HFAs in integer
+ registers, do not special case the mode used for complex
+ types. Do not advance int_regs until the current register
+ is full.
-2003-01-30 Jerry Quinn <jlquinn@optonline.net>
+2004-01-28 Jan Hubicka <jh@suse.cz>
- * gcc/doc/invoke.texi (Optimization Options): Group together
- optional and experimental flags. Move trapv and bounds-check
- out of this section. Group floating point flags together.
- (Code Gen Options): Move trapv and bounds-check to here.
+ * function.c (allocate_struct_function): Do not initialize expr, emit
+ and varasm.
+ (prepare_function_start): Do it here.
+ * c-parse.in (maybe_type_qual): Do not produce line number notes.
-2003-01-30 Jerry Quinn <jlquinn@optonline.net>
+2004-01-28 Richard Sandiford <rsandifo@redhat.com>
- * gcc/doc/invoke.texi (Optimization Options): List -O levels
- for each optimization flag.
+ * config/fp-bit.c (pack_d): When using paired doubles to implement
+ a long double, round the high part separately.
+ (unpack_d): Fix the case in which the high part is a power of two
+ and the low part is a nonzero value of the opposite sign.
-2003-01-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+2004-01-27 Roger Sayle <roger@eyesopen.com>
- PR target/9316
- * config/rs6000/rtems.h: Add CPP_OS_DEFAULT_SPEC.
- * config/rs6000/sysv4.h: Add CPP_OS_RTEMS_SPEC.
- * config/rs6000/t-rtems: New file. multilib variants to match OS.
- * config.gcc (powerpc-*-rtems*): Use rs6000/t-rtems instead of
- rs6000/t-ppcgas so we get the desired multilibs.
+ * config/pa/pa.c (emit_move_sequence): Check that operand1 is a
+ CONST_INT before using INTVAL.
-2003-01-30 Alexandre Oliva <aoliva@redhat.com>
-
- * config/fp-bit.h (__make_dp): Declare if TMODES.
-
-2003-01-29 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/ia64.c (ia64_rwreloc_section_type_flags): New.
- * config/ia64/hpux.h (TARGET_SECTION_TYPE_FLAGS): New.
+2004-01-27 Ulrich Weigand <uweigand@de.ibm.com>
-2003-01-29 Steve Ellcey <sje@cup.hp.com>
+ * config/s390/s390.h (TARGET_DEFAULT): Default to !TARGET_BACKCHAIN.
+ * config/s390/s390.c (s390_return_addr_rtx): Fail for all but current
+ frame if !TARGET_BACKCHAIN.
+ * config/s390/s390.md ("allocate_stack"): Use pattern only if
+ TARGET_BACKCHAIN.
+ * doc/invoke.texi (-mbackchain/-mno-backchain): Document new default.
- * config/ia64/ia64.c (ia64_rwreloc_select_rtx_section): Rename
- from ia64_aix_select_rtx_section.
- (ia64_rwreloc_select_section): Simlarly; use default*_1 function
- instead of saving and restoring flag_pic.
- (ia64_rwreloc_unique_section): Similarly.
- * config/ia64/aix.h (TARGET_ASM_SELECT_SECTION,
- TARGET_ASM_UNIQUE_SECTION, TARGET_ASM_SELECT_RTX_SECTION): Update.
- * config/ia64/hpux.h (TARGET_ASM_SELECT_SECTION,
- TARGET_ASM_UNIQUE_SECTION, TARGET_ASM_SELECT_RTX_SECTION): New.
+2004-01-27 Richard Sandiford <rsandifo@redhat.com>
-2003-01-29 Joel Sherrill <joel@OARcorp.com>
+ PR target/7297
+ * except.c (init_eh): Use a 5-word __jbuf for __builtin_setjmp().
- PR bootstrap/9296
- * gthr-rtems.h: Define __GTHREAD_MUTEX_INIT. Apparently no code
- depended on it being defined until now.
+2004-01-27 Bob Wilson <bob.wilson@acm.org>
-2003-01-29 Joel Sherrill <joel@OARcorp.com>
+ * config/xtensa/xtensa.c (xtensa_copy_incoming_a7): Remove SUBREG
+ on CQImode and CHImode incoming arguments in register a7.
+ (function_arg): Wrap BLKmode argument in register a7 in a PARALLEL.
+ * config/xtensa/xtensa.h (BLOCK_REG_PADDING): Define.
+ * config/xtensa/xtensa.md (movdi, movdf): Only call force_reg or
+ xtensa_copy_incoming_a7 before reload.
- PR target/9295
- * config/mips/rtems.h: Predefine __USE_INIT_FINI__ so generic
- RTEMS code knows which C++ initialization style the toolset
- configuration is using.
+2004-01-27 Ian Lance Taylor <ian@wasabisystems.com>
-2003-01-29 Joel Sherrill <joel@OARcorp.com>
+ * config/arm/arm.c (output_return_instruction): Only restore IP
+ into SP if frame_pointer_needed.
- PR bootstrap/9293
- * config/m68k/t-crtstuff: Replace spaces with tabs, add
- $(MULTILIB_CFLAGS) as compiler option and multilib crtbegin/end.o.
+2004-01-27 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-01-29 Joel Sherrill <joel@OARcorp.com>
+ * config/sparc/sparc.c (function_arg_pass_by_reference): Return 1
+ for SCmode and DCmode if ARCH32.
+ (sparc_va_arg): Handle SCmode and DCmode by reference if ARCH32.
+ * config/sparc/sparc.h (RETURN_IN_MEMORY): Return 0 for TCmode
+ if ARCH32.
+ (BASE_RETURN_VALUE_REG): Return 32 for all FP modes except TFmode
+ if ARCH32.
+ (BASE_OUTGOING_VALUE_REG): Likewise.
- PR bootstrap/9292
- * config.gcc (hppa1.1-rtems): Did not include t-rtems nor enable
- RTEMS threads.
- * config/pa/rtems.h (LIB_SPEC): Use -N when linking.
+2004-01-27 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-01-25 Andrew Haley <aph@redhat.com>
+ PR target/10904
+ PR target/13058
+ * config/sparc/sparc.h (CANNOT_CHANGE_MODE_CLASS): New.
+ Forbid mode changes from SImode for lower FP regs if ARCH64.
- * tree-inline.c (walk_tree): Add CHAR_TYPE.
+2004-01-27 Jakub Jelinek <jakub@redhat.com>
-2003-01-28 Christian Cornelssen <ccorn@cs.tu-berlin.de>
+ * config/i386/i386.c (ix86_constant_alignment): Decrease alignment
+ of long string literals from 32 bytes to sizeof (void *) when !-Os
+ and to 1 with -Os.
- * doc/install.texi: Add documentation for installation into
- tooldirs and with DESTDIR.
+2004-01-27 Kaz Kojima <kkojima@gcc.gnu.org>
-2003-01-28 Andreas Schwab <schwab@suse.de>
+ PR optimization/13567
+ * cse.c (cse_basic_block): Call cse_insn with a non-null
+ libcall_insn for the last SET insn of a no-confilict block.
- * config/m68k/m68k.md (tablejump+2): Don't sign extend an address
- register.
- * config/m68k/apollo68.h (ASM_RETURN_CASE_JUMP): Likewise.
- * config/m68k/coff.h (ASM_RETURN_CASE_JUMP): Likewise.
- * config/m68k/linux.h (ASM_RETURN_CASE_JUMP): Likewise.
- * config/m68k/m68kelf.h (ASM_RETURN_CASE_JUMP): Likewise.
- * config/m68k/mot3300.h (ASM_RETURN_CASE_JUMP): Likewise.
- * config/m68k/netbsd-elf.h (ASM_RETURN_CASE_JUMP): Likewise.
- * config/m68k/pbb.h (ASM_RETURN_CASE_JUMP): Likewise.
+2004-01-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-2003-01-28 David Edelsohn <edelsohn@gnu.org>
+ * system.h (CHAR_BITFIELD): Delete.
+ (BOOL_BITFIELD): New.
+ * c-decl.c (c_scope): Use BOOL_BITFIELD.
+ * gengtype-lex.l: Recognize BOOL_BITFIELD instead of CHAR_BITFIELD.
- * config/rs6000/rs6000.md (movti_string): Remove clobber.
- * config/rs6000/rs6000.c (rs6000_emit_move, TImode): Explicitly
- generate PARALLEL with clobber for TARGET_POWER.
+2004-01-26 J"orn Rennecke <joern.rennecke@superh.com>
-2003-01-28 Richard Henderson <rth@redhat.com>
+ * doc/tm.texi: Insert some weasel words when LOAD_EXTEND_OP
+ may or may not return non-NIL.
+ * postreload.c (reload_cse_simplify_operands): In LOAD_EXTEND_OP code,
+ check CANNOT_CHANGE_MODE_CLASS
- * ifcvt.c (noce_process_if_block): Re-add check vs X being changed
- in no-else-block case. Add commentary.
+2004-01-26 Jeff Law <law@redhat.com>
-2003-01-28 Alexandre Oliva <aoliva@redhat.com>
+ * doc/contrib.texi: Minor cleanup for Paolo Carlini's entry. Add
+ acute accents for Petur Runolfsson's entry.
- * config/mips/mips.h (UNITS_PER_HWFPVALUE): Renamed from...
- (UNITS_PER_FPVALUE): Defined as the width of a long double, or
- zero if no hardware floating point.
- (LONG_DUBLE_TYPE_SIZE): Set to 128 on N32 and N64.
- (MAX_FIXED_MODE_SIZE): Define to LONG_DOUBLE_TYPE_SIZE.
- (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define.
- (BIGGEST_ALIGNMENT): Same as LONG_DOUBLE_TYPE_SIZE.
- (FUNCTION_VALUE_REGNO_P): Set for FP_RETURN+2 on N32 and N64.
- * config/mips/iris6.h (MIPS_TFMODE_FORMAT): Define.
- * config/mips/mips.c (override_options): Use it.
- (mips_arg_info): Pass TFmode values in even FP registers on N32
- and N64.
- (mips_setup_incoming_varargs): Use UNITS_PER_HWFPVALUE.
- (mips_va_start): Adjust alignment of ARG_POINTER_REGNUM.
- (mips_va_arg): Use UNITS_PER_HWFPVALUE. Impose additional
- even-register-like alignment to 128-bit arguments.
- (save_restore_insns): Use UNITS_PER_HWFPVALUE.
- (mips_function_value): Likewise. Return TFmode in $f0 and $f2
- on N32 or N64.
- * config/mips/_tilib.c (__negti2, __ashlti3, __lshrti3): New.
- * config/mips/t-iris6 (LIB2FUNCS_EXTRA): Add _tilib.c.
- (TPBIT): Set to tp-bit.c.
- (tp-bit.c): Create out of fp-bit.c.
-2003-01-27 Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
+2004-01-26 Eric Botcazou <ebotcazou@libertysurf.fr>
- * c-parse.in: Remove '%expect 32' directive when in objc mode.
+ Backport from mainline:
-2003-01-27 Josef Zlomek <zlomekj@suse.cz>
+ 2004-01-23 Eric Botcazou <ebotcazou@act-europe.fr>
+ Olivier Hainque <hainque@act-europe.fr>
- * gcse.c (constprop_register): Check NEXT_INSN (insn) != NULL.
+ * fold-const.c (fold_binary_op_with_conditional_arg): Only
+ build a COMPOUND_EXPR if 'arg' is really a SAVE_EXPR.
-2003-01-27 Richard Earnshaw <rearnsha@arm.com>
+2004-01-26 Eric Botcazou <ebotcazou@libertysurf.fr>
- PR optimization/9090
- * function.c (purge_addressof_1): After pushing an addressed register
- onto the stack, simplify the result.
+ PR target/13666
+ * config/sparc/sparc.c (function_arg_union_value): New function.
+ (function_arg): Use it to deal with unions.
+ (function_value): Likewise. Define 'regbase' only for ARCH64.
+ Replace a conditional statement by a simpler one.
-2003-01-27 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+2004-01-26 Richard Sandiford <rsandifo@redhat.com>
- * doc/extend.texi: Fix typo.
+ * config/mips/mips.c (mips16_optimize_gp): Delete.
+ (mips_reorg): Don't call it.
-2003-01-27 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+2004-01-25 Richard Sandiford <rsandifo@redhat.com>
- * doc/cppopts.texi: Fix typo.
- * doc/objc.texi: Likewise.
- * doc/passes.texi: Likewise.
+ * config/mips/mips.c (mips_offset_within_object_p): New function.
+ (mips_symbolic_constant_p): Use it in the SYMBOL_SMALL_DATA and
+ SYMBOL_CONSTANT_POOL cases. Also use it for SYMBOL_GENERAL if the
+ ABI has 64-bit pointers and the object file only allows 32-bit symbols.
-2003-01-27 Alexandre Oliva <aoliva@redhat.com>
+2004-01-25 Eric Botcazou <ebotcazou@act-europe.fr>
- * real.c (ibm_extended_format): Add 53 to minimum exponent.
- (encode_ibm_extended): Adjust.
+ PR bootstrap/13853
+ * cfgcleanup.c (try_optimize_cfg): Explicitly test against 0.
-2003-01-26 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-25 Richard Sandiford <rsandifo@redhat.com>
- * doc/gccint.texi: Update the copyright.
+ * config/mips/mips-protos.h (mips_reg_mode_ok_for_base_p): Delete.
+ (mips_regno_mode_ok_for_base_p): Declare.
+ * config/mips/mips.h (ARG_POINTER_REGNUM): Renumber to 77.
+ (FRAME_POINTER_REGNUM): Renumber to 78.
+ (FIRST_PSEUDO_REGISTER): Update comment accordingly.
+ (BASE_REG_P, GP_REG_OR_PSEUDO_STRICT_P): Delete.
+ (GP_REG_OR_PSEUDO_NONSTRICT_P): Delete.
+ (REGNO_MODE_OK_FOR_BASE_P): Use mips_regno_mode_ok_for_base_p.
+ (REG_MODE_OK_FOR_BASE_P): Likewise.
+ * config/mips/mips.c (mips_reg_names, mips_sw_reg_names): Change
+ entry for 77 to "$arg" and entry for 78 to "$frame".
+ (mips_regno_to_class): Map 77 and 78 to ALL_REGS.
+ (mips_reg_mode_ok_for_base_p): Remove.
+ (mips_regno_mode_ok_for_base_p): New function, derived from old
+ BASE_REG_P macro. Don't enforce the mips16 stack pointer
+ restrictions unless we're being strict.
+ (mips_valid_base_register_p): Use mips_regno_mode_ok_for_base_p.
-2003-01-26 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-24 Kazu Hirata <kazu@cs.umass.edu>
- * doc/cpp.texi: Fix typos.
- * doc/extend.texi: Likewise.
+ * doc/frontends.texi: Update copyright.
+ * doc/gcov.texi: Likewise.
* doc/gty.texi: Likewise.
- * doc/install.texi: Likewise.
- * doc/passes.texi: Likewise.
- * doc/rtl.texi: Likewise.
-
-2003-01-26 Christian Cornelssen <ccorn@cs.tu-berlin.de>
-
- * Makefile.in (ORDINARY_FLAGS_TO_PASS): Also pass DESTDIR.
- (install-cpp, installdirs, install-common)
- (install-driver, install-info, install-man)
- (install-headers, install-include-dir, install-headers-tar)
- (install-headers-cpio, install-headers-cp, install-mkheaders)
- (install-collect2, uninstall): Prepend $(DESTDIR) to
- destination paths in all (un)installation commands.
- (install-driver): Rewrite $(LN) commands to support DESTDIR
- with "ln" as well as with "ln -s".
- (installdirs): Simply use mkinstalldirs.
- (install-libgcc, install-multilib): Also pass DESTDIR.
- * mklibgcc.in: Prepend $(DESTDIR) to $(libsubdir) in the
- installation destination variable ldir.
- * config/alpha/t-osf4 (SHLIB_INSTALL): Prepend $$(DESTDIR)
- to $$(slibdir) in the installation commands.
- * config/arm/t-netbsd (SHLIB_INSTALL): Likewise.
- * config/ia64/t-hpux (SHLIB_INSTALL): Likewise.
- * config/mips/t-iris5-6 (SHLIB_INSTALL): Likewise.
- * config/pa/t-hpux-shlib (SHLIB_INSTALL): Likewise.
- * config/rs6000/t-aix43 (SHLIB_INSTALL): Likewise.
- * config/rs6000/t-aix52 (SHLIB_INSTALL): Likewise.
- * config/t-slibgcc-elf-ver (SHLIB_INSTALL): Likewise.
- * config/t-slibgcc-sld (SHLIB_INSTALL): Likewise.
- * config/arc/t-arc (install-multilib-arc): Prepend $(DESTDIR) to
- $(libsubdir) in the installation commands.
+ * doc/sourcebuild.texi: Likewise.
-2003-01-26 Alexandre Oliva <aoliva@redhat.com>
+2004-01-24 Kazu Hirata <kazu@cs.umass.edu>
- * fp-bit.h: Define macros for TFmode floating-point constants
- in IBM-extended TFmode types.
- (TMODES): Define if __LDBL_MANT_DIG__ has the newly-supported
- widths.
- * config/fp-bit.c (pack_d, unpack_d): Support IBM-extended
- TFmode type.
+ * config/h8300/coff.h: Update copyright.
+ * config/h8300/elf.h: Likewise.
+ * config/h8300/h8300-protos.h: Likewise.
+ * config/h8300/h8300.c: Likewise.
+ * config/h8300/h8300.h: Likewise.
+ * config/h8300/h8300.md: Likewise.
- * config/fp-bit.h: Define macros for TFmode floating-point
- constants in IEEE quad TFmode type. Declare functions according
- to L_ macros.
- (TMODES): Define if __LDBL_MANT_DIG__ is 113.
- (TFtype, TItype, UTItype): Define if TMODES is defined.
- (MAX_UDI_INT, MAX_DI_INT, BITS_PER_DI): Likewise.
- (F_T_BITOFF, D_T_BITOFF): Define.
- (IMPLICIT_1, IMPLICIT_2): Cast constants to types that are
- guaranteed to be wide enough.
- * config/fp-bit.c: Check for L_ macros for tf functions.
- (__thenan_tf): New.
- (nan): Adjust.
- (pack_d, unpack_d): Support IEEE 854 quad type.
- (_fpmul_parts): Support TFmode. Compute exponent adjustment
- from FRAC_NBITS, FRAC_BITS and NGARDS.
- (usi_to_float): Cast constants to be shifted to fractype
- instead of assuming long long is wide enough.
- (sf_to_tf, df_to_tf, __make_tp, tf_to_df, tf_to_sf): New.
+2004-01-24 Hartmut Penner <hpenner@de.ibm.com>
- * Makefile.in (FPBIT_FUNCS): Added _sf_to_tf.
- (DBBIT_FUNCS): Added _df_to_tf.
- (TPBIT_FUNCS): New.
- (libgcc.mk): Pass TPBIT and TPBIT_FUNCS down.
- (LIBGCC_DEPS): Added TPBIT.
- * mklibgcc.in: Support TPBIT and TPBIT_FUNCS.
+ PR target/13674
+ * config/rs6000/rs6000.md (movdf_hardfloat64): Do not disparage
+ loading into GPR.
- * optabs.c (expand_binop) <add, sub>: Return xtarget if we haven't
- been able to move the result to target.
+2004-01-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
- * expr.c (emit_group_store): Initialize dst with CONST0_RTX
- for the appropriate mode.
+ PR optimization/12440
+ * loop.c: Include ggc.h.
+ (loop_optimize): Run garbage collector between optimization of loops.
+ * Makefile.in (loop.o): Add GGC_H dependency.
- * calls.c (emit_library_call_value_1): Handle return values
- in a PARALLEL.
+2004-01-24 Jakub Jelinek <jakub@redhat.com>
- * rtl.c (get_mode_alignment): Moved to...
- * stor-layout.c: ... here.
+ * simplify-rtx.c (simplify_relational_operation): Don't
+ simplify address == constant into address + -constant == 0.
- * print-rtl.c (print_rtx): Don't print MEM details in
- GENERATOR_FILEs.
+2004-01-24 Kazu Hirata <kazu@cs.umass.edu>
-2003-01-26 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+ * gcc.c (process_command): Don't internationalize the
+ Copyright message.
+ * mips-tfile.c (main): Likewise.
- * df.c (df_uses_record): Handle CC0.
+2004-01-23 Kazu Hirata <kazu@cs.umass.edu>
-2003-01-25 Jan Hubicka <jh@suse.cz>
- Eric Botcazou <ebotcazou@libertysurf.fr>
+ * recog.c: Fix a typo in copyright.
- PR opt/8492
- * gcse.c (one_cprop_pass): Delete unreachable blocks.
+2004-01-23 Kazu Hirata <kazu@cs.umass.edu>
-2003-01-25 Ulrich Weigand <uweigand@de.ibm.com>
+ * alias.c, basic-block.h, c-common.c, c-common.h,
+ c-cppbuiltin.c, c-pragma.c, c-pretty-print.c, c-semantics.c,
+ calls.c, cfg.c, cfgcleanup.c, cfgrtl.c, cgraph.h, collect2.c,
+ combine.c, cppcharset.c, cpptrad.c, cse.c, cselib.c, cselib.h,
+ defaults.h, df.c, dominance.c, et-forest.c, expmed.c, expr.c,
+ expr.h, fold-const.c, function.h, gcc.c, gcse.c, genattrtab.c,
+ genautomata.c, genconditions.c, genflags.c, gengtype.c,
+ genopinit.c, genrecog.c, gensupport.c, ggc-zone.c, graph.c,
+ haifa-sched.c, integrate.c, langhooks-def.h, langhooks.c,
+ langhooks.h, local-alloc.c, optabs.c, optabs.h, postreload.c,
+ ra.h, recog.c, reg-stack.c, regmove.c, reload.c, reorg.c,
+ rtlanal.c, sched-deps.c, sched-ebb.c, sdbout.c, system.h,
+ target.h, targhooks.c, toplev.h, tree-inline.c,
+ unwind-dw2-fde.h, unwind-pe.h, unwind.h, varray.c, varray.h:
+ Update copyright.
- * reload.c (maybe_memory_address_p): New function.
- (find_reloads_address): Use it instead of memory_address_p.
+2004-01-23 Bob Wilson <bob.wilson@acm.org>
-2003-01-25 Kaz Kojima <kkojima@gcc.gnu.org>
+ * config/xtensa/xtensa.c (xtensa_va_arg): Handle complex values as
+ separate real and imaginary parts.
+ * config/xtensa/xtensa.h (SPLIT_COMPLEX_ARGS): Define.
- * final.c (shorten_branches): Align the address of code label
- when computing initial lengths and addresses.
+2004-01-23 Richard Henderson <rth@redhat.com>
-2003-01-25 Richard Henderson <rth@redhat.com>
+ PR opt/12941
+ * combine.c (SHIFT_COUNT_TRUNCATED): Provide default value.
+ (simplify_comparison): Don't simplify (eq (zero_extract c 1 r) 0)
+ if SHIFT_COUNT_TRUNCATED is set.
- 2002-02-19 Robert Lipe <robertlipe@usa.net>
- * config/i386/t-sco5gas: (CRTSTUFF_T_CFLAGS_S): Delete -mcoff.
+2004-01-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
-2003-01-23 Andreas Schwab <schwab@suse.de>
+ * fixinc/inclhack.def (alpha___extern_prefix): Renamed to ...
+ (alpha___extern_prefix_sys_stat): ... this.
+ Apply to <sys/mount.h>, too.
+ Tweak to match more variations.
+ * fixinc/tests/base/sys/stat.h: Adapt for new hackname.
- * config/ia64/crtend.asm [HAVE_INITFINI_ARRAY]: Make
- __do_global_ctors_aux hidden global and don't put it in
- .init_array.
- * config/ia64/crtbegin.asm [HAVE_INITFINI_ARRAY]: Put it here
- instead so that it comes first.
+ * fixinc/inclhack.def (alpha___extern_prefix,
+ alpha___extern_prefix_standards): New hacks to obey
+ __PRAGMA_EXTERN_PREFIX.
+ * fixinc/tests/base/testing.h [ALPHA___EXTERN_PREFIX_CHECK]: New
+ test.
+ * fixinc/tests/base/standards.h: Likewise.
-2003-01-25 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+ * fixincl/inclhack.def (alpha_pthread): Tweak to match more
+ variations.
+ New testcase.
+ * fixinc/tests/base/pthread.h: Handle it.
- * config/c4x/c4x.h (ASM_SPEC): Fix for new gas format.
+ * fixinc/fixincl.x: Regenerate.
-2003-01-24 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+2004-01-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- * calls.c (fix_unsafe_tree): Prototype.
- * loop.c (loop_invariant_p): Avoid signed/unsigned warning.
+ * fixinc/inclhack.def (bad_lval): Renamed to ...
+ (alpha_bad_lval): ... this.
+ Removed file list.
+ Restrict to alpha*-dec-osf*.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/libgen.h: Remove, moving test ...
+ * fixinc/tests/base/testing.h: ... here, reflecting new name.
-2003-01-24 Richard Henderson <rth@redhat.com>
+2004-01-23 Ian Lance Taylor <ian@wasabisystems.com>
- PR optimization/4382
- * tree-inline.c (find_builtin_longjmp_call_1): New.
- (find_builtin_longjmp_call): New.
- (inlinable_function_p): Use it.
+ * doc/invoke.texi (Optimize Options): Note that --param arguments
+ are subject to change without notice.
-2003-01-24 Ulrich Weigand <uweigand@de.ibm.com>
+2004-01-23 Zack Weinberg <zack@codesourcery.com>
- * configure.in (HAVE_AS_TLS): Add s390-*-* and s390x-*-* cases.
- * configure: Regenerate.
+ PR c/13814
+ * c-decl.c (diagnose_mismatched_decls): Also discard a
+ built-in if we encounter an old-style definition with the
+ same name.
- * config/s390/s390-protos.h (tls_symbolic_operand): Add prototype.
- (tls_symbolic_reference_mentioned_p): Add prototype.
- (s390_tls_get_offset): Add prototype.
- (emit_pic_move): Remove prototype, replace by ...
- (emit_symbolic_move): .. this new prototype.
-
- * config/s390/s390.c (TARGET_HAVE_TLS): Conditionally define.
- (tls_model_chars): New global variable.
- (s390_encode_section_info): Encode TLS model.
- Use targetm.binds_local_p to check for local symbols.
- (s390_strip_name_encoding): New function.
- (TARGET_STRIP_NAME_ENCODING): Define.
-
- (get_thread_pointer): New function.
- (legitimize_tls_address): New function.
- (legitimize_address): Call it.
- (emit_pic_move): Remove, replace by ...
- (emit_symbolic_move): ... this new function.
-
- (larl_operand): Handle TLS operands.
- (legitimate_constant_p): Likewise.
- (s390_decompose_address): Likewise.
- (s390_cannot_force_const_mem): New function.
- (TARGET_CANNOT_FORCE_CONST_MEM): Define.
-
- (s390_output_symbolic_const): Handle TLS unspecs.
- (print_operand): New code 'J'.
- (machine_function): Add struct member 'some_ld_name'.
- (get_some_local_dynamic_name, get_some_local_dynamic_name_1): New.
-
- (enum s390_builtin): New type.
- (code_for_builtin_64, code_for_builtin_31): New global variables.
- (s390_init_builtins, s390_expand_builtin): New functions.
- (TARGET_INIT_BUILTINS, TARGET_EXPAND_BUILTIN): Define.
-
- * config/s390/s390.h (TLS_SYMBOLIC_CONST): New macro.
- (ASM_OUTPUT_LABELREF): Define.
- (ASM_OUTPUT_SPECIAL_POOL_ENTRY): Handle TLS constants.
-
- * config/s390/s390.md: Define TLS UNSPEC constants.
- ("movdi", "movsi"): Handle TLS operands.
- ("get_tp_64", "get_tp_31", "set_tp_64", "set_tp_31"): New insns.
- ("*tls_load_64", "*tls_load_31"): New insns.
- ("call_value_tls", "call_value_tls_exp"): New expanders.
- ("brasl_tls", "bras_tls", "basr_tls_64", "basr_tls_31",
- "bas_tls_64", "bas_tls_31"): New insns.
-
-2003-01-24 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
-
- * doc/passes.texi: Fix typo.
-2003-02-01 Jan Hubicka <jh@suse.cz>
-
- * loop.c (emit_prefetch_instructions): Do conversion at right place in
- RTL chain.
-
- * combine.c (simplify_set): Reverse order of ragumetns to
- REG_CANNOT_CHANGE_MODE_P
- * df.c (df_def_record_1): Likewise.
- * recog.c (register_operand): Likewise.
- * simplify-rtx.c (simplify_subreg): Likewise.
- * hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): Update use of
- CANNOT_CHANGE_MODE_CLASS.
- * regclass.c (cannot_change_mode_set_regs, invalid_mode_change_p):
- Likewise.
- * reload.c (push_reload): Likewise.
- * alpha.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * ia64.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * mips.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * mips-protos.h (mips_cannot_change_mode_class): Update prototype.
- * mips.c (mips_cannot_change_mode_class): Update.
- * pa64-regs.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * rs6000.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * s390.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * sh.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
- * sh-protos.h (sh_cannot_change_mode_class): Update prototype.
- * sh.c (sh_cannot_change_mode_class): Update.
- * i386.h (CANNOT_CHANGE_MODE_CLASS): New.
- * tm.texi (CANNOT_CHANGE_MODE_CLASS): Update documentation.
-
-2003-01-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * timevar.def (TV_NAME_LOOKUP, TV_OVERLOAD,
- TV_TEMPLATE_INSTANTIATION): New timevar_id eumerations.
- * timevar.h (POP_TIMEVAR_AND_RETURN): New macro.
- * timevar.c (timevar_pop): Be verbose when aborting. Include
- "toplev.h".
-
-2003-01-24 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
-
- * doc/bugreport.texi: Use @command instead of @code for commands.
- * doc/collect2.texi: Likewise.
- * doc/headerdirs.texi: Likewise.
- * doc/invoke.texi: Likewise.
- * doc/standards.texi: Likewise.
- * doc/tm.texi: Likewise.
- * doc/trouble.texi: Likewise.
-
-2003-01-23 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+2004-01-23 Jakub Jelinek <jakub@redhat.com>
- PR java/6748
- * config/rs6000/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Don't destroy
- regs->nip. Fix rt_sigreturn frame layout. Add support for newer
- kernels.
+ * config.gcc (powerpc*-*): Clear $with_cpu or $with_tune if it was
+ set to default{32,64}.
-2003-01-23 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+2004-01-21 Jakub Jelinek <jakub@redhat.com>
- PR other/7341
- * invoke.texi (ftest-coverage): Fix broken cross-reference.
- Change @code to @command for gcov command.
+ * config/rs6000/linux64.h (MD_FALLBACK_FRAME_STATE_FOR)
+ [!__powerpc64__]: Corrected to handle kernels with changed ucontext.
- * gcc.texi: Adjust title of gcov section.
- Adjust copyright.
- * gcov.texi: Likewise.
+2003-11-30 Jan Hubicka <jh@suse.cz>
-2003-01-23 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+ * i386.c (ix86_emit_restore_regs_using_mov): Deal with large offsets.
- PR other/7448
- * doc/passes.texi (fssa-ccp): Remove misplaced line.
+2004-01-23 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-01-22 Ulrich Weigand <uweigand@de.ibm.com>
+ * config/sparc/sparc.c (scan_record_type): New function.
+ (function_arg_slotno): Use it to determine which kinds of
+ registers the record can be passed in.
- * config/s390/s390.h (HARD_REGNO_MODE_OK): Fix warning regression
- introduced by last change.
+2004-01-22 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
-2003-01-22 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * configure.in: Make --disable-checking the default.
+ * configure.ac (enable_werror): Fixed typo.
* configure: Regenerate.
-2003-01-22 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390-protos.h (preferred_la_operand_p):
- Remove second parameter.
- * config/s390/s390.c (preferred_la_operand_p): Likewise.
- * config/s390/s390.h (FRAME_REGNO_P, FRAME_REG_P): New macros.
- (HARD_REGNO_MODE_OK): Use FRAME_REGNO_P.
- * config/s390/s390.md ("*la_cc_64", "*la_cc_31", splitters): Remove.
- Add peepholes to transform ADD to LOAD ADDRESS.
-
-2003-01-20 Jan Hubicka <jh@suse.cz>
-
- * i386.md (SSE cmov splitter): Handle memory operand in operand 5.
-
-2003-01-21 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
-
- PR opt/7507
- * calls.c (fix_unsafe_tree): Split out from ...
- (expand_call): ... here. Use it on the function address too.
-
-2003-01-20 Richard Henderson <rth@redhat.com>
-
- PR opt/7154
- * stmt.c (expand_asm_operands): Validize memory operands.
-
-2003-01-20 Richard Henderson <rth@redhat.com>
-
- PR opt/8848
- * ifcvt.c (noce_process_if_block): Correct arguments to
- modified_between_p for no-else-block case.
-
-2003-01-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- * ifcvt.c (noce_emit_store_flag): Don't emit store flag if mode of x
- is not a scalar int mode.
-
-2003-01-20 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (notice_update_cc): Don't assume that
- recog_data.operands[0] is always associated with cc0.
-
-2003-01-19 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.c (stack_push_word, stack_pop_word,
- z_reg, z_reg_qi): Declare static and GTY().
- (da_reg): Remove.
- (create_regs_rtx): Don't create da_reg.
- ("gt-m68hc11.h"): Include for GTY roots.
- (m68hc11_autoinc_compatible_p): Remove.
- (autoinc_mode): Declare prototype.
- (m68hc11_make_autoinc_notes): Likewise.
- * config/m68hc11/m68hc11.h (ix_reg, iy_reg, d_reg): Declare extern
- and GTY() here.
- (m68hc11_compare_op0, m68hc11_compare_op1): Likewise.
- (m68hc11_soft_tmp_reg): Likewise.
- * config/m68hc11/m68hc11-protos.h: Remove above declarations.
-
-2003-01-18 Roger Sayle <roger@eyesopen.com>
-
- * config/pa/pa.md (muldi3): Avoid invalid sharing of SUBREG RTXs.
-
-2003-01-10 Geoffrey Keating <geoffk@apple.com>
-
- * varasm.c (struct constant_descriptor_rtx): Remove unused
- `label' field.
-
- * ggc-page.c (ggc_collect): Avoid overflow computing
- min_expand.
-
-2002-12-20 Geoffrey Keating <geoffk@apple.com>
-
- * integrate.c (output_inline_function): Don't hold private
- pointers to 'struct function' over GC calls.
-
-2003-01-17 Alexandre Oliva <aoliva@redhat.com>
-
- * config/mips/mips.h: Don't use #elif. Reported by Kaveh
- R. Ghazi.
-
-2003-01-16 Kaz Kojima <kkojima@gcc.gnu.org>
-
- * config/sh/sh.c (sh_initialize_trampoline): Emit rotrdi3_mextr
- instead of rotldi3_mextr.
+2004-01-22 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
-2003-01-16 Stephane Carrez <stcarrez@nerim.fr>
+ * config.gcc (mips-sgi-irix6*o32): Removed.
+ * config/mips/iris6-o32-as.h: Likewise.
+ * config/mips/iris6-o32-gas.h: Likewise.
+ * config/mips/iris6-o32.h: Likewise.
- * config/m68hc11/m68hc11.c (m68hc11_check_z_replacement): Fix handling
- 68HC12 pre/post inc/dec side effects.
+2004-01-22 Bob Wilson <bob.wilson@acm.org>
-2003-01-16 Stephane Carrez <stcarrez@nerim.fr>
+ * config/xtensa/xtensa.c (function_arg): Generalize logic so that it
+ handles complex and vector modes.
- * config/m68hc11/m68hc11.h (MASK_M6812): Define.
+2004-01-22 Daniel Jacobowitz <drow@mvista.com>
-2003-01-16 Stephane Carrez <stcarrez@nerim.fr>
+ * c-semantics.c (genrtl_while_stmt, genrtl_do_stmt_1)
+ (genrtl_for_stmt): Remove emit_nop calls.
- * config/m68hs11/m68hc11.c (expand_prologue): Use push/pop to
- allocate 4-bytes of locals on 68HC11.
- (expand_epilogue): Likewise.
- (m68hc11_memory_move_cost): Increase cost of HI/QI soft registers.
+2004-01-22 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-2003-01-15 John David Anglin <dave@hiauly1.hia.nrc.ca>
+ PR target/13713
+ PR target/13324
+ * pa.md (movstrsi_prereload, movstrsi_postreload, movstrdi_prereload,
+ movstrdi_postreload, clrstrsi_prereload, clrstrsi_postreload,
+ clrstrdi_prereload, clrstrdi_postreload): Fix constraints.
- * som.h (SUPPORTS_WEAK, SUPPORTS_ONE_ONLY, MAKE_DECL_ONE_ONLY,
- ASM_WEAKEN_LABEL, GTHREAD_USE_WEAK): Define.
- * pa.h (TARGET_SOM_SDEF): Define.
- * pa-hpux11.h (TARGET_SOM_SDEF): Define.
+2004-01-22 Daniel Jacobowitz <drow@mvista.com>
-2003-01-15 Stephane Carrez <stcarrez@nerim.fr>
+ * config/arm/arm.c: Include "debug.h".
+ (thumb_pushpop): Take two new arguments. Add some commentary.
+ Output frame information when pushing.
+ (thumb_exit, thumb_unexpanded_epilogue): Update calls to
+ thumb_pushpop.
+ (thumb_output_function_prologue): Likewise. Accumulate a CFA
+ offset, and pass it to thumb_pushpop. Output CFI information.
+ (thumb_expand_prologue): Add some frame-related markers and notes.
- * config/m68hc11/m68hc11.h (ASM_SPEC): Handle -m68hcs12; Pass -mshort
- and -mshort-double to the assembler to specify the ABI.
- (LINK_SPEC): Likewise.
- (CPP_SPEC): Pass HCS12 specific define.
- (MASK_M68S12): New define.
- (TARGET_M68S12): Likewise.
- (TARGET_SWITCHES): New options -m68hcs12 and -m68S12.
- (TARGET_VERSION): Update.
- * config/m68hc11/m68hc12.h (CPP_SPEC): Pass HCS12 specific define.
- (LINK_SPEC): Update.
- (ASM_SPEC): Update.
- * config/m68hc11/m68hc11.c (m68hc11_asm_file_start): Update.
- * doc/invoke.texi (M68hc1x Options): Document -m68hcs12.
+2004-01-22 Ulrich Weigand <uweigand@de.ibm.com>
-2003-01-15 John David Anglin <dave.anglin@nrc.gc.ca>
+ * config/s390/s390.c (s390_frame_info): Allow large frame sizes
+ for TARGET_64BIT.
+ (s390_arg_frame_offset): Change return type to HOST_WIDE_INT.
+ * config/s390/s390-protos.h (s390_arg_frame_offset): Likewise.
- * gengtype-lex.l (malloc, realloc): Move defines after include of
- system.h.
+2004-01-22 Kazu Hirata <kazu@cs.umass.edu>
-2003-01-15 Stephane Carrez <stcarrez@nerim.fr>
+ * doc/tm.texi (CASE_VECTOR_PC_RELATIVE): Mention that the
+ macro need not be defined if jump-tables should contain
+ relative addresses only when -fPIC or -fPIC is in effect.
- * config/m68hc11/m68hc11.md ("return"): Use emit_jump_insn to emit
- the return code.
+2004-01-22 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-01-15 Josef Zlomek <zlomekj@suse.cz>
-
- * cfganal.c (set_edge_can_fallthru_flag): Clear the EDGE_CAN_FALLTHRU
- flag before setting it.
-
-2003-01-15 Josef Zlomek <zlomekj@suse.cz>
-
- Segher Boessenkool <segher@koffie.nl>
-
- * predict.c (real_inv_br_prob_base): New variable.
- (propagate_freq): Use multiply by reciprocal instead of
- division. Don't divide by 1.0 at all.
- (estimate_bb_frequencies): Similar.
-
-2003-01-15 Alexandre Oliva <aoliva@redhat.com>
-
- * configure.in (libgcc_visibility): Force disabled on IRIX 6 too.
- * configure: Rebuilt.
-
- * config/mips/mips.h (CRT_CALL_STATIC_FUNCTION): Define so as
- to set $gp before the call.
-
-2003-01-10 Andrew Haley <aph@redhat.com>
-
- * config/i386/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Rename
- registers to be in correct order. Add rip.
-
-2003-01-14 Denis Chertykov <denisc@overta.ru>
-
- * config/ip2k/ip2k.h (VALID_MACHINE_DECL_ATTRIBUTE): Remove.
- (VALID_MACHINE_TYPE_ATTRIBUTE): Remove.
-
- * config/ip2k/ip2k.c (ip2k_attribute_table): New table of
- attributes.
- (TARGET_ATTRIBUTE_TABLE): New macro.
- (valid_machine_type_attribute): Remove.
- (valid_machine_decl_attribute): Remove.
- (ip2k_handle_progmem_attribute): New function.
- (ip2k_handle_fndecl_attribute): New function.
-
-2003-01-14 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR target/8870, PR target/9195
-
- Backport from mainline:
-
- 2003-01-10 Richard Henderson <rth@redhat.com>
-
- * combine.c (make_compound_operation): Use SCALAR_INT_MODE_P,
- not INTEGRAL_MODE_P when widening extensions.
-
-2003-01-13 Alexandre Oliva <aoliva@redhat.com>
-
- * aclocal.m4 (gcc_AC_PROG_GNAT): Don't try to prepend
- ${ac_tool_prefix} to ADAC or CC. Protect them from word
- splitting.
- * configure: Rebuilt.
-
-2003-01-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * unwind-dw2-fde.h (last_fde): Mark parameter with __attribute__
- ((__unused__)).
-
-2003-01-12 Alan Modra <amodra@bigpond.net.au>
-
- * expr.c (expand_expr <RDIV_EXPR>): Correct recursive call args.
-
-2003-01-11 Jan Hubicka <jh@suse.cz>
-
- PR target/9068
- * i386.c (output_fp_compare): Fix typo
-
-2003-01-10 Josef Zlomek <zlomekj@suse.cz>
-
- * jump.c (next_nonnote_insn_in_loop): New function.
- (copy_loop_headers): Use next_nonnote_insn_in_loop instead of
- next_nonnote_insn.
- (duplicate_loop_exit_test). Likewise.
-
-2003-01-08 Jan Hubicka <jh@suse.cz>
-
- PR target/8213
- * i386.c (ix86_expand_int_movcc): Fix RTL sharing problem.
-
-2003-01-09 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (*extzv_1_r_h8300): Correct the insn
- length.
- (*extzv_1_r_h8300hs): Likewise.
- (*extzv_1_r_inv_h8300): Likewise.
- (*extzv_1_r_inv_h8300hs): Likewise.
-
-2003-01-09 Josef Zlomek <zlomj9am@artax.karlin.mff.cuni.cz>
-
- * Makefile.in (optabs.o): Add dependency on basic-block.h.
- * basic-block.h (control_flow_insn_p): Fuction was exported.
- * cfgbuild.c (control_flow_insn_p): Fuction was made non-static.
- * optabs.c (emit_libcall_block): Emit REG_LIBCALL and REG_RETVAL
- notes only when the region is contained in a single basic block.
-
-2003-01-09 Josef Zlomek <zlomj9am@artax.karlin.mff.cuni.cz>
-
- * Makefile.in (PARTITION_H): New.
- (BASIC_BLOCK_H): Added hard-reg-set.h and $(PARTITION_H).
- * basic-block.h: Include hard-reg-set.h.
-
-2003-01-09 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR inline-asm/8832
- * tree.h (expand_asm): New prototype.
- * stmt.c (expand_asm): Set the MEM_VOLATILE_P flag if instructed
- to do so.
- * c-semantics (genrtl_asm_stmt): Pass the RID_VOLATILE qualifier
- down to expand_asm.
- * c-typeck.c (simple_asm_stmt): Set the RID_VOLATILE qualifier.
- * rtlanal.c (volatile_insn_p) [ASM_INPUT]: Test the MEM_VOLATILE_P flag.
- (volatile_refs_p) [ASM_INPUT]: Likewise.
- (side_effects_p) [ASM_INPUT]: Likewise.
-
-2003-01-09 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR c/8032
- * c-typeck.c (process_init_element) [RECORD_TYPE]: For
- an empty element, do not advance the pointer to unfilled
- fields if there are pending initializers.
-
-2003-01-09 Kaz Kojima <kkojima@gcc.gnu.org>
-
- * config/sh/sh.h (CASE_VECTOR_MODE): Use SImode for a
- non-optimizing compile.
- (ASM_OUTPUT_ADDR_VEC_ELT): Use .long for a non-optimizing
- compile.
-
-2003-01-09 Andreas Jaeger <aj@suse.de>
-
- * unwind-dw2-fde.h (last_fde): Revert last patch.
-
-2003-01-08 Danny Smith <dannysmith@users.sourceforge.net>
-
- PR optimization/8750
- * config/i386/i386.c (ix86_expand_prologue): Don't allow
- scheduling pass to move insns across __alloca call.
-
-2003-01-08 Jeff Sturm <jsturm@one-point.com>
-
- PR target/9210
- * config/rs6000/rs6000.c (rs6000_elf_encode_section_info):
- Set SYMBOL_REF_FLAG on local data sym_ref.
-
-2003-01-08 Jan Hubicka <jh@suse.cz>
-
- PR target/8322
- * i386.c (ix86_init_mmx_sse_builtins): Constify arguments of loads.
- * xmmintrin.h (_mm_load*_si128. _mm_store*_si128): Add casts.
-
- PR target/7782
- * reload1.c (delete_output_reload): Avoid repeated attempts
- to delete insn.
-
- * cselib.c (cselib_current_insn_in_libcall): New static variable.
- (new_elt_loc_list, cselib_process_insn, cselib_init): Keep track on whether
- we are inside libcall.
- * cselib.h (elt_loc_list): Add in_libcall.
- * gcse.c (do_local_cprop): Do not copy propagate using insns
- in libcalls.
-
-2003-01-07 Janis Johnson <janis187@us.ibm.com>
-
- PR other/8947
- * doc/invoke.texi (-malign-double): Explain that the option breaks
- binary compatibility.
-
-2003-01-07 Richard Henderson <rth@redhat.com>
-
- * alias.c (find_base_value): Only use new_reg_base_value shortcut
- if the register is set once.
-
-2003-01-07 Sylvain Pion <Sylvain.Pion@mpi-sb.mpg.de>
+ * config/sparc/sparc.c (function_arg_slotno): Use
+ FLOAT_TYPE_P to detect FP fields in structures.
+ (function_arg_record_value_1): Likewise.
+ (function_arg_record_value_2): Likewise.
- * config/i386/i386.c (ix86_init_mmx_sse_builtins):
- __builtin_ia32_ldmxcsr and __builtin_ia32_stmxcsr are SSE, not MXX.
- * config/i386/i386.md (ldmxcsr, stmxcsr): SSE, not MMX.
+2004-01-22 Eric Botcazou <ebotcazou@libertysurf.fr>
-2003-01-07 Benjamin Kosnik <bkoz@redhat.com>
- Sunil Davasam <sunil.k.davasam@intel.com>
+ PR target/13559
+ * config/sparc/sparc.c (function_arg_record_value_3): Revert
+ to 'word_mode' once the first slot has been filled.
- PR libstdc++/9076
- * unwind-dw2.c (execute_cfa_program): DW_CFA_undefined,
- DW_CFA_same_value, read next and ignore.
+2004-01-22 Olivier Hainque <hainque@act-europe.fr>
-2003-01-07 Richard Henderson <rth@redhat.com>
+ * config/sparc/sparc.c (function_arg_record_value_1): Fix
+ computation of the number of integer registers required.
- * cfganal.c (flow_call_edges_add): Don't crash on noreturn call.
+2004-01-22 Hartmut Penner <hpenner@de.ibm.com>
-2003-01-06 Aldy Hernandez <aldyh@redhat.com>
+ * gcc/config/rs6000/rs6000.c (function_arg) Handle
+ vector register special in function without prototype.
+ (function_arg_advance): Vector parameters get always
+ GPRs allocated for the linux64 target.
- Segher Boessenkool <segher@koffie.nl>
+2004-01-21 Andrew Pinski <apinski@apple.com>
- * config/rs6000/rs6000.c (rs6000_reg_names): Add missing registers.
- (alt_reg_names): Ditto, fix formatting.
- * config/rs6000/rs6000.h (DEBUG_REGISTER_NAMES): Fix formatting.
+ PR target/13785
+ * config/rs6000/rs6000.md (call_value): Force operand
+ 1 not operand 0 into a register.
-2003-01-06 Bruce Korb <bkorb@gnu.org>
+2004-01-21 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
- * fixinc/fixfixes.c(wrap_fix): the wrapper guard must be a function
- of *both* the file name and the fix name.
+ * pa-protos.h: Update copyright.
+ * pa.h: Likewise.
+ * pa.md: Likewise.
-2003-01-06 Richard Henderson <rth@redhat.com>
+ * fixinc/inclhack.def (hpux10_stdio_declarations, ultrix_const3,
+ ultrix_locale, ultrix_stdlib, ultrix_strings, ultrix_sys_time,
+ ultrix_unistd): New hacks.
+ * fixinc/tests/base/stdio.h (HPUX10_STDIO_DECLARATIONS_CHECK,
+ ULTRIX_CONST2_CHECK): Add checks.
+ * fixinc/tests/base/stdlib.h (ULTRIX_STDLIB_CHECK): Likewise.
+ * fixinc/tests/base/strings.h (ULTRIX_STRINGS2_CHECK): Likewise.
+ * fixinc/tests/base/unistd.h (ULTRIX_UNISTD_CHECK): Likewise.
+ * fixinc/tests/base/sys/time.h (ULTRIX_SYS_TIME_CHECK): Likewise.
+ * fixinc/tests/base/locale.h: New file.
+ * fixincl.x: Rebuilt.
- * config/alpha/alpha.c (alpha_encode_section_info): Adjust symbol_str
- properly when changing "local-ness".
- * config/alpha/alpha.md (movdi_er_high_g): Allow all symbols.
+2004-01-21 Andreas Jaeger <aj@suse.de>
+ Michael Matz <matz@suse.de>
-2003-01-05 Andreas Jaeger <aj@suse.de>
+ * doc/extend.texi (Extended Asm): Clarify memory clobber.
- * unwind-dw2-fde.h (last_fde): Add unused attribute for obj.
+2004-01-21 Zack Weinberg <zack@codesourcery.com>
-2003-01-05 John David Anglin <dave@hiauly1.hia.nrc.ca>
+ * c-decl.c (merge_decls): Kill different_binding_level and
+ different_tu arguments; simplify throughout.
+ (duplicate_decls): Likewise.
+ (pushdecl, merge_translation_unit_decls): Update calls to
+ duplicate_decls.
- * pa64-hpux.h (JCR_SECTION_NAME): Define.
- (PA_INIT_FRAME_DUMMY_ASM_OP): Check EH_FRAME_SECTION_NAME instead of
- USE_EH_FRAME_REGISTRY when defining.
+2004-01-20 Kelley Cook <kcook@gcc.gnu.org>
-2003-01-04 John David Anglin <dave.anglin@nrc.ca>
+ PR bootstrap/12730
+ * configure.ac: Delete definition and subsitution of docdir.
+ Add info, man, srcman and srcinfo to target hooks. Create doc/
+ directory.
+ * configure: Regenerate.
+ * Makefile.in: Don't substitute docdir and delete all references
+ throughout.
+ (MAKEINFOFLAGS): Define.
+ (stmp-docobjdir): Delete.
+ (INFOFILES, MANFILES): Define.
+ (info): Call lang.info, srcinfo and lang.srcinfo.
+ (generated-manpages): Call lang.man, srcman and lang.srcman.
+ (srcinfo, srcman): New rules to copy back files to source directory.
+ (doc/%.info, doc/%.dvi, doc/%.1, doc/%.7): New implict rule.
+ (install-man): Revamp rule.
+ (clean): Update dvi directory.
+ (distclean): Delete TAGS from front end directorys.
+ (maintainer-clean): Delete all document files in source directory.
+
+ objc/Make-lang.in (objc.man, objc.info): Dummy entries.
+ (objc.srcman, objc.srcinfo): Likewise.
+
+2004-01-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (pretty-print.o): Depend on $(CONFIG_H) and
+ $(SYSTEM_H).
+ (print-rtl1.o): Depend on $(SYSTEM_H).
+
+2004-01-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa-protos.h (compute_frame_size): Use HOST_WIDE_INT for frame sizes.
+ * pa.c (store_reg, store_reg_modify, load_reg, set_reg_plus_d):
+ Likewise. Handle frames larger than 0x7fffffff on 64-bit ports.
+ (emit_move_sequence): Check scratch_reg first in various if statements.
+ Extend source simplification to handle all 64-bit CONST_INTs.
+ (pa_output_function_prologue): Use HOST_WIDE_INT_PRINT_DEC for printing
+ frame size.
+ (hppa_expand_prologue, hppa_expand_epilogue): Use HOST_WIDE_INT for
+ frame offset calculations.
+ * pa.h (NEW_HP_ASSEMBLER): Add comment.
+ (MAX_LEGIT_64BIT_CONST_INT, MIN_LEGIT_64BIT_CONST_INT,
+ LEGITIMATE_64BIT_CONST_INT_P): Define.
+ (LEGITIMATE_CONSTANT_P): Use LEGITIMATE_64BIT_CONST_INT_P. Treat
+ any CONST_INT as legitimate during and after reload.
+ (VAL_32_BITS_P, INT_32_BITS): Define.
+ (LEGITIMIZE_RELOAD_ADDRESS): Handle large frame offsets.
+
+2004-01-21 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/sysv4.h (DWARF2_FRAME_REG_OUT): Define.
+ * dwarf2out.c (output_cfi): Map regs using DWARF2_FRAME_REG_OUT.
+ * doc/tm.texi (DWARF_FRAME_REGNUM, DWARF2_FRAME_REG_OUT): Document.
+
+2004-01-20 Geoffrey Keating <geoffk@apple.com>
+
+ * alias.c (new_alias_set): Mark last_alias_set for PCH.
+ (get_varargs_alias_set): Rename 'set' to 'varargs_set' and mark it
+ for PCH.
+ (get_frame_alias_set): Likewise, except rename it to 'frame_set'.
+ * config/rs6000/rs6000.c (rs6000_sr_alias_set): Mark for PCH.
+ (get_TOC_alias_set): Mark 'set' for PCH.
+
+2004-01-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_load_call_address): Make the call insn
+ use $gp if it could be calling a lazy binding stub.
+
+2004-01-20 Denis Chertykov <denisc@overta.ru>
+
+ PR bootstrap/13735
+ * config/avr/avr.h (BASE_REG_CLASS): Don't permit to use X
+ register as pointer after reload.
+
+2004-01-20 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/13557
+ * config/sparc/sparc.c (function_arg): Reorder the cases.
+
+2004-01-19 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (target_noncanonical, program_transform_name): Use
+ immediate define instead of deferred.
+ (GCC_INSTALL_NAME, GCC_TARGET_INSTALL_NAME, CPP_INSTALL_NAME,
+ PROTOIZE_INSTALL_NAME, UNPROTOIZE_INSTALL_NAME, GCOV_INSTALL_NAME,
+ GCCBUG_INSTALL_NAME): Define via a immediate $(shell) instead of
+ deferred backquote.
+
+2004-01-19 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (aligned_memory_operand): Check MEM_ALIGN,
+ don't check memory mode.
+ (unaligned_memory_operand): Likewise.
+ (reload_inqi, reload_inhi, reload_outqi, reload_outhi): Don't
+ abort for op0 not MEM.
+
+ * config/alpha/alpha.c (alpha_expand_mov_nobwx): If the destination
+ is not a reg, copy to a scratch first.
+ (aligned_loadqi, aligned_loadhi, unaligned_loadqi, unaligned_loadhi,
+ unaligned_loadqi_le, unaligned_loadqi_be, unaligned_loadhi_le,
+ unaligned_loadhi_be): Expect op0 in DImode; don't SUBREG.
+ (reload_inqi, reload_inhi): Fix mode of op0.
+ (reload_inqi_help, reload_inhi_help, reload_outqi_help,
+ reload_outhi_help): Likewise. Use define_insn_and_split.
+
+ * config/alpha/alpha.md (call peepholes): Check for REG_NORETURN
+ as well as $29 dead.
+
+2004-01-19 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sol2.h (ASM_DECLARE_OBJECT_NAME): New. Emit
+ "tls_object" for thread-local objects.
+ * config/sparc/sparc.c (sparc_elf_asm_named_section): Emit
+ "#tls" for thread-local sections.
+ * configure.ac (thread-local checks): Specify --fatal-warnings in
+ every binutils-specific checks. For sparc*-*-*, test whether the
+ OS is Solaris and the tools are native and act accordingly.
+ * configure: Rebuild.
+
+2004-01-19 Jeff Law <law@redhat.com>
+
+ * contrib.texi: Update Paolo Carlini's entry. New entries for
+ Jerry Quinn and Petur Runolfsson.
+
+2004-01-19 Richard Henderson <rth@redhat.com>
+
+ * alpha.h (HARD_REGNO_MODE_OK): Disallow SImode in FP regs.
+ * alpha.md (UNSPEC_NT_LDA): Remove.
+ (UNSPEC_CVTLQ, cvtlq): New.
+ (extendsidi2_1): Rename from extendsidi2_nofix; remove f/f.
+ (extendsidi2_fix): Remove.
+ (extendsidi2 splitter): Use cvtlq.
+ (extendsidi2 fp peepholes): Remove.
+ (cvtql): Use SFmode instead of SImode.
+ (fix_trunc?fsi): Update to match.
+ (floatsisf2_ieee, floatsisf2, floatsidf2_ieee, floatsidf2): New.
+ (movsi): Rename from movsi_nofix, remove f alternatives.
+ (movsi_nt_vms): Similarly.
+ (movsi_fix, movsi_nt_vms_fix): Remove.
+ (nt_lda): Remove.
+ * alpha.c (alpha_expand_prologue): Use adddi3, not nt_lda.
+
+2004-01-19 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_remove_node): Fix removal from linked list.
+ * cgraphunit.c (cgraph_finalize_compilation_unit): Clear next_needed
+ list.
+ (cgraph_remove_unreachable_nodes): New function
+ (cgraph_decide_inlining_of_small_function): Fix pasto.
+ (cgraph_decide_inlining_incrementally): Fix pasto.
+ (cgrpah_decide_inlining): Likewise; remove unreachable nodes.
- * config.gcc (hppa*64*-*-hpux11*): Define extra_parts. Don't use
- collect2.
- * pa-hpux11.h (LDD_SUFFIX, PARSE_LDD_OUTPUT): Undefine.
- (HAS_INIT_SECTION, LD_INIT_SWITCH, LD_FINI_SWITCH): Define.
- * pa64-hpux.h (HP_INIT_ARRAY_SECTION_ASM_OP,
- GNU_INIT_ARRAY_SECTION_ASM_OP, HP_FINI_ARRAY_SECTION_ASM_OP,
- GNU_FINI_ARRAY_SECTION_ASM_OP): Define.
- (CTORS_SECTION_ASM_OP, DTORS_SECTION_ASM_OP): Define when not using
- elfos.h.
- (EH_FRAME_IN_DATA_SECTION): Delete define.
- (HAS_INIT_SECTION, LD_INIT_SWITCH, LD_FINI_SWITCH): Undefine.
- (STARTFILE_SPEC): Use crtbegin.o.
- (ENDFILE_SPEC): Use crtend.o.
- (INIT_SECTION_ASM_OP, FINI_SECTION_ASM_OP, CRT_CALL_STATIC_FUNCTION,
- SUPPORTS_INIT_PRIORITY, PA_CXA_FINALIZE_STUB, PA_INIT_FINI_HACK,
- PA_INIT_FRAME_DUMMY_ASM_OP, PA_JV_REGISTERCLASSES_STUB,
- DTOR_LIST_BEGIN): Define.
- * pa.c (TARGET_ASM_CONSTRUCTOR): Define.
- (pa_asm_out_constructor, pa_asm_out_destructor): New functions.
- * som.h (SUPPORTS_INIT_PRIORITY): Delete define.
+2004-01-18 Roger Sayle <roger@eyesopen.com>
-2003-01-02 Eric Christopher <echristo@redhat.com>
+ * builtins.c (expand_builtin_expect_jump): Fix thinko of reusing
+ live "next" variable, which can lead to an infinite loop.
- * config/mips/mips.md (movdf_internal2): Fix constraints.
+2004-01-18 Daniel Jacobowitz <drow@mvista.com>
-2003-01-03 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+ * final.c (final_scan_insn): Make non-static again.
+ * output.h (final_scan_insn): Re-add prototype.
+ * config/arc/arc.c (arc_output_function_epilogue): Add NULL
+ to final_scan_insn call.
+ * config/cris/cris.c (cris_target_asm_function_epilogue): Likewise.
+ * config/mips/mips.c (mips_output_conditional_branch): Likewise.
+ * config/pa/pa.c (output_lbranch, output_call): Likewise.
+ * config/sh/sh.c (print_slot): Likewise.
+ * config/sparc/sparc.c (sparc_nonflat_function_epilogue): Likewise.
+ (output_sibcall, sparc_flat_function_epilogue): Likewise.
- * doc/install.texi (Configuration): Fix markup for reference to
- gcc/config.gcc.
+2004-01-18 Jan Hubicka <jh@suse.cz>
-2003-01-02 Kazu Hirata <kazu@cs.umass.edu>
+ * basic-block.h (try_redirect_by_replacing_jump): Declare.
+ * cfgcleanup.c (try_optimize_cfg): Use it.
+ * cfgrtl.c (try_redirect_by_replacing_jump): Export.
+ (rtl_redirect_edge_and_branch, cfg_layout_redirect_edge_and_branch):
+ Kill hack.
+ (cfg_layout_merge_blocks): Use try_redirect_by_replacing_jump.
- * config/h8300/h8300.c (stack_pointer_operand): New.
- (const_int_gt_2_operand): Likewise.
- (const_int_ge_8_operand): Likewise.
- * config/h8300/h8300.md (a splitter): Likewise.
- (a peephole2): Likewise.
- * config/h8300/h8300-protos.h: Add prototypes for the new
- functions above.
+2004-01-18 Andrew Pinski <pinskia@physics.uc.edu>
-2003-01-02 Neil Booth <neil@daikokuya.co.uk>
+ * config/rs6000/altivec.h: Wrap C++ functions in extern "C++"
+ block.
- * gccbug.in: Update for new categories.
+ * config/rs6000/rs6000.c (rs6000_special_round_type_align):
+ Check for NULL in the chain and remove repeated code.
-2002-12-31 Tom Tromey <tromey@redhat.com>
+2004-01-18 Jan Hubicka <jh@suse.cz>
- * doc/install.texi (Testing): Fixed typo.
+ * coverage.c (checksum_string): Rename to ...
+ (coverage_checksum_string): ... this one, Use crc32_string; recognize
+ names containing random number and zero the number out in order to get
+ match.
-2002-12-31 Jerry Quinn <jlquinn@optonline.net>
+2004-01-18 Richard Sandiford <rsandifo@redhat.com>
- * gcc/doc/invoke.texi (Optimization Options): Clean up -O flag
- descriptions.
+ * config/mips/mips.c (mips_got_alias_set): Mark for PCH.
-2002-12-31 Jerry Quinn <jlquinn@optonline.net>
+2004-01-18 Joseph S. Myers <jsm@polyomino.org.uk>
- * gcc/doc/invoke.texi (Optimization Options): List the options
- enabled by each -O flag.
+ * doc/c-tree.texi, doc/cpp.texi, doc/extend.texi,
+ doc/frontends.texi, doc/gcov.texi, doc/gty.texi, doc/install.texi,
+ doc/invoke.texi, doc/libgcc.texi, doc/md.texi, doc/rtl.texi,
+ doc/sourcebuild.texi, doc/standards.texi, doc/tm.texi,
+ doc/trouble.texi: Remove trailing whitespace.
-2002-12-31 David Edelsohn <edelsohn@gnu.org>
+2004-01-18 Richard Sandiford <rsandifo@redhat.com>
- * config/rs6000/rs6000.h (WIDEST_HARDWARE_FP_SIZE): Define.
+ PR target/7618
+ * config/mips/mips.c: Include cfglayout.h.
+ (TARGET_ASM_OUTPUT_MI_THUNK, TARGET_ASM_CAN_OUTPUT_MI_THUNK): Define.
+ (mips_unspec_offset_high): Add temporary register argument.
+ (mips_load_call_address): New function, split out from...
+ (mips_expand_call): ...here.
+ (mips_output_cplocal): New function.
+ (mips_output_function_prologue, mips_output_function_epilogue): Use it.
+ (mips_emit_loadgp): New function, split out from...
+ (mips_expand_prologue): ...here.
+ (mips_output_mi_thunk): New function.
-2002-12-31 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+2004-01-17 Roger Sayle <roger@eyesopen.com>
- * doc/install.texi (Configuration): Explicitly refer
- gcc/config.gcc for a list of cpu models.
+ * builtins.c (expand_builtin_expect_jump): Fix mistake in my
+ last patch. Use XEXP (x, 0) to get a LABEL_REF's CODE_LABEL.
-2002-12-30 Joseph S. Myers <jsm@polyomino.org.uk>
+2004-01-17 Andrew Pinski <pinskia@physics.uc.edu>
- * doc/gcc.texi, doc/gccint.texi: Update last modification dates.
+ * config/rs6000/rs6000.c (rs6000_special_round_type_align):
+ Return type is unsigned int not int.
+ * config/rs6000/rs6000-protos.h (rs6000_special_round_type_align):
+ Likewise.
-2002-12-30 Tom Tromey <tromey@redhat.com>
+2004-01-18 Joseph S. Myers <jsm@polyomino.org.uk>
- * doc/install.texi (Testing): Mention Jacks.
+ * doc/contrib.texi, doc/cppenv.texi, doc/extend.texi,
+ doc/install.texi, doc/invoke.texi, doc/tm.texi: Consistently use
+ "GNU/Linux" and "Microsoft Windows" terminology.
-2002-12-30 Joseph S. Myers <jsm@polyomino.org.uk>
+2004-01-18 Joseph S. Myers <jsm@polyomino.org.uk>
- * doc/service.texi: Uncomment and update FAQ link.
+ * doc/c-tree.texi, doc/compat.texi, doc/cpp.texi,
+ doc/cppopts.texi, doc/extend.texi, doc/install.texi,
+ doc/interface.texi, doc/invoke.texi, doc/libgcc.texi, doc/md.texi,
+ doc/objc.texi, doc/rtl.texi, doc/tm.texi, doc/trouble.texi: Use
+ @smallexample instead of @example.
-2002-12-28 Joseph S. Myers <jsm@polyomino.org.uk>
+2004-01-17 Ziemowit Laski <zlaski@apple.com>
- * doc/cpp.texi, doc/gcc.texi, doc/gccint.texi, doc/install.texi:
- Use @copying.
+ * objc/objc-act.c (build_objc_method_call): Use target
+ hooks instead of macros to determine if ..._stret
+ dispatchers should be used (NeXT runtime only).
-2002-12-28 Joseph S. Myers <jsm@polyomino.org.uk>
+2004-01-17 Daniel Jacobowitz <drow@mvista.com>
- * configure.in: Increase makeinfo version requirement to 4.[2-9].
- * configure: Regenerate.
- * doc/install.texi: Update Texinfo version requirement.
+ * rtl.h (emit_insn_before_sameloc, emit_jump_insn_before_sameloc)
+ (emit_call_insn_before_sameloc, emit_insn_after_sameloc)
+ (emit_jump_insn_after_sameloc, emit_call_insn_after_sameloc): New
+ macros.
+ * reload1.c (emit_reload_insns): Use them.
+ * emit-rtl.c (emit_insn_before_sameloc, emit_insn_after_sameloc)
+ (emit_jump_insn_after_sameloc, emit_call_insn_after_sameloc): Check
+ for NULL PATTERN.
-2002-12-27 Joseph S. Myers <jsm@polyomino.org.uk>
+2004-01-17 Daniel Jacobowitz <drow@mvista.com>
- * doc/include/texinfo.tex: Update to version 2002-12-26.16.
+ * final.c (SEEN_BB, SEEN_NOTE, SEEN_EMITTED): Define.
+ (final_scan_insn): Update to take an additional SEEN argument. Emit
+ a line note after the prologue. Make static.
+ (line_note_exists): Remove.
+ (final): Don't initialize line_note_exists. Update call to
+ final_scan_insn.
+ * output.h (final_scan_insn): Remove prologue.
+ * function.c (set_insn_locators): Update comment.
+ (thread_prologue_and_epilogue_insns): Add a comment.
-2002-12-26 Joseph S. Myers <jsm@polyomino.org.uk>
+2004-01-17 Joseph S. Myers <jsm@polyomino.org.uk>
- * doc/standards.texi, doc/invoke.texi: Point to 3.3 version of
+ * doc/invoke.texi, doc/standards.texi: Point to 3.4 version of
c99status.html.
-2002-12-26 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.h (IDENT_ASM_OP): End with a tab.
-
-2002-12-23 Larin Hennessy <larin@science.oregonstate.edu>
-
- * doc/install.texi: Remove i386-*-isc, i860-*-bsd,
- m68k-altos-sysv, m68k-isi-bsd, m68k-sony-bsd entries.
- * doc/invoke.texi: Remove AMD 29K, ARM RISC/iX, Clipper, Convex,
- DG/UX entries.
- * doc/md.texi: Remove AMD 29K entries.
- * doc/trouble.texi: Remove Alliant, DG/UX, Iris 4.0.5F, GAS
- 1.38.1, NewsOS, RT PC, WE32K entries.
-
-2002-12-23 Aldy Hernandez <aldyh@redhat.com>
-
- PR/8763
- * config/rs6000/altivec.md (mulv4sf3): Rewrite to add -0.0 vector.
- (altivec_vspltisw_v4sf): Name pattern.
- (altivec_vslw_v4sf): New pattern.
-
-2002-12-23 Joseph S. Myers <jsm@polyomino.org.uk>
-
- * doc/include/gcc-common.texi: Clear DEVELOPMENT.
-
-2002-12-23 David Edelsohn <edelsohn@gnu.org>
-
- PR middle-end/8784
- * expr.c (expand_assignment): Apply special treatment to
- ARRAY_TYPE.
-
-2002-12-21 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (zero_extendqisi2): Correct the
- length.
-
-2002-12-19 Devang Patel <dpatel@apple.com>
-
- * config/darwin.h (TARGET_OPTION_TRANSLATE_TABLE): Add support for -dynamic.
- (CPP_SPEC): Define __STATIC__ and __DYNAMIC__ depending on -dynamic.
- (LINK_SPEC): Pass -dynamic to linker.
- * config/rs6000/darwin.h: Reject conflicting -static and -dynamic.
-
-2002-12-19 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (pushqi_h8300): Don't push the stack
- pointer.
- (pushqi_h8300hs): Likewise.
- (pushhi_h8300): Likewise.
- (pushhi_h8300hs): Likewise.
-
-2002-12-19 Eric Botcazou <ebotcazou@libertysurf.fr>
+2004-01-17 Andrew Pinski <pinskia@physics.uc.edu>
- PR optimization/8988
- * loop.c (maybe_eliminate_biv): Kill REG_EQUAL notes mentioning
- the biv when eliminating.
-
-2002-12-19 Aldy Hernandez <aldyh@redhat.com>
-
- PR 8553
- * config/rs6000/altivec.md ("absv8hi2"): Add & to clobbered
- registers.
- ("absv16qi2"): Same.
- ("absv4si2"): Same.
- ("absv4sf2"): Same.
- ("altivec_abss_v16qi"): Same.
- ("altivec_abss_v8hi"): Same.
- ("altivec_abss_v4si"): Same.
-
-2002-12-19 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.md ("*tsthiCCT", "*tsthiCCT_cconly",
- "*tstqiCCT", "*tstqiCCT_cconly"): New insns.
+ PR target/10781
+ * config/rs6000/rs6000-protos.h (rs6000_special_round_type_align):
+ Prototype.
+ * config/rs6000/rs6000.c (rs6000_special_round_type_align):
+ New function.
+ * config/rs6000/linux64.h (ROUND_TYPE_ALIGN): Use it.
+ * config/rs6000/aix.h (ROUND_TYPE_ALIGN): Likewise.
+ * config/rs6000/darwin.h (ROUND_TYPE_ALIGN): Likewise.
-2002-12-18 Aldy Hernandez <aldyh@redhat.com>
+2004-01-17 Jan Hubicka <jh@suse.cz>
- * config/rs6000/altivec.h (vec_cmplt macro): Reverse arguments in
- macro.
- (vec_cmplt C++ functions): Reverse arguments.
+ * toplev.c (rest_of_handle_reorder_blocks): Fix pasto in previous
+ commit.
-2002-12-17 Kazu Hirata <kazu@cs.umass.edu>
+ * toplev.c (HAVE_conditional_execution): Provide default.
+ (rest_of_handle_reorder_blocks): For conditional_execution target
+ update liveness once after all transformations
+ (rest_of_compilation): Do crossjumping before ce3.
- * doc/c-tree.texi: Restore deliberate spelling mistakes.
+2004-01-17 J. Brobecker <brobecker@gnat.com>
-2002-12-17 Kazu Hirata <kazu@cs.umass.edu>
+ * dwarf2out.c (is_subrange_type): Renamed from is_ada_subrange_type().
+ Remove checks for is_ada() and TREE_UNSIGNED.
+ (subrange_type_die): Emit a byte_size attribute if the subrange
+ type size is different from the base type size.
+ (modified_type_die): Replace call to is_ada_subrange_type() by
+ call to is_subrange_type().
- * doc/c-tree.texi: Fix typos and follow spelling conventions.
- * doc/cpp.texi: Likewise.
- * doc/extend.texi: Likewise.
- * doc/gty.texi: Likewise.
- * doc/install.texi: Likewise.
- * doc/invoke.texi: Likewise.
- * doc/md.texi: Likewise.
- * doc/passes.texi: Likewise.
- * doc/rtl.texi: Likewise.
- * doc/sourcebuild.texi: Likewise.
- * doc/tm.texi: Likewise.
+2004-01-16 Mark Mitchell <mark@codesourcery.com>
-2002-12-17 Jerry Quinn <jlquinn@optonline.net>
-
- * doc/invoke.texi: Minor spelling and grammar fixes.
-
-2002-12-16 Mark Mitchell <mark@codesourcery.com>
+ * configure.ac: Do not do internal checking or -Werror by default.
+ * configure: Regenerated.
+ * doc/include/gcc-common.texi (DEVELOPMENT): @clear it.
* version.c (version_string): Mark as prerelease.
-2002-12-13 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa.c (output_millicode_call): Correct typo.
- (output_call): Likewise.
-
-2002-12-13 Alexandre Oliva <aoliva@redhat.com>
+2004-01-16 Andrew Pinski <pinskia@physics.uc.edu>
- * config/mn10300/mn10300.c (print_operand) <case N>: Check
- operand's range. Print value directly, without aid from
- output_address.
- <case U>: New.
- <case S>: Make sure argument to fprintf has the right type.
- * config/mn10300/mn10300.h (OK_FOR_T): New macro.
- (EXTRA_CONSTRAINT): Adjust.
- * config/mn10300/mn10300.md: Add new all-QImode pattern for
- bclr. Use %U for immediate operands of bset and bclr.
- (iorqi3): New expand, with insns for AM33 and mn10300.
+ * config/sh/sh.c: Include ggc.h.
-2002-12-13 J"orn Rennecke <joern.rennecke@superh.com>
+2004-01-17 Jan Hubicka <jh@suse.cz>
- * sh.c (sh_register_operand): New function.
- (prepare_move_operands): Use it.
- * sh.h (PREDICATE_CODES): Add entry for sh_register_operand.
- * sh.md (movsi_media, movsi_media_nofpu): Allow stores of 0.
- (movqi_media, movhi_media, movdi_media, movdi_media_nofpu): Likewise.
- (movdf_media, movdf_media_nofpu, movv4sf_i, movsf_media): Likewise.
- (movsf_media_nofpu, movv2hi_i, movv4hi_i, movv8qi_i): Likewise.
- (movv2si_i): Likewise.
+ * c-common.c (c_estimate_num_insns_1): Handle builtin_constant_p and
+ builtin_expect specially.
+ * params.def (PARAM_MAX_INLINE_INSNS_AUTO): Set to 100.
+ (PARAM_LARGE_FUNCTION_INSNS): Set to 3000.
+ * invoke.texi (max-inline-insns-single): Set to 100.
+ (large-function-insns): Set to 3000.
-2002-12-13 Jim Wilson <wilson@redhat.com>
+2004-01-16 Jan Hubicka <jh@suse.cz>
- * doc/extend.texi (Complex Numbers): Update info on debug info.
+ * i386.md (load_tp_di): Fix pasto.
-2002-12-13 Kazu Hirata <kazu@cs.umass.edu>
+ PR opt/13608
+ * i386.c (ix86_compute_frame_layout): Fix for alloca on leaf function.
- * config/h8300/h8300.md (addhi3_h8300): Remove the last
- alternative.
+ * c-pretty-print.c (pp_c_type_cast, pp_c_abstract_declarator,
+ pp_c_character_constant, pp_c_floating_constant,
+ pp_c_additive_expression, pp_c_shift_expression,
+ pp_c_equality_expression, pp_c_and_expression,
+ pp_c_exclusive_or_expression, pp_c_inclusive_or_expression,
+ pp_c_logical_and_expression): Remove inline modifier.
+ * dwarf2out.c (get_AT): Likewise.
+ * et-forest.c (et_splay): Likewise.
+ * ra.h (ra_alloc, ra_calloc): Likewise
-2002-12-12 Devang Patel <dpatel@apple.com>
+2004-01-16 Kazu Hirata <kazu@cs.umass.edu>
- * doc/invoke.texi: Document Darwin linker options, -bundle
- -bind_at_load, -all_load and -arch_errors_fatal
-
-2002-12-12 Jim Wilson <wilson@redhat.com>
-
- * dbxout.c (dbxout_fptype_value): New.
- (dbxout_type, case COMPLEX_TYPE): Call it. Use 'R' instead of 'r'.
-
-2002-12-12 Kazu Hirata <kazu@cs.umass.edu>
-
- * c-decl.c: Fix a comment typo.
- * cfg.c: Likewise.
- * cfgcleanup.c: Likewise.
- * cfglayout.c: Likewise.
- * cfgrtl.c: Likewise.
- * c-typeck.c: Likewise.
- * dominance.c: Likewise.
- * dwarf2asm.c: Likewise.
- * dwarfout.c: Likewise.
- * expmed.c: Likewise.
- * expr.c: Likewise.
- * final.c: Likewise.
- * flow.c: Likewise.
- * function.c: Likewise.
- * gcc.c: Likewise.
+ * config/frv/frv-protos.h: Fix comment formatting.
+ * config/frv/frv.c: Likewise.
+ * config/frv/frv.h: Likewise.
+ * config/frv/frv.md: Likewise.
+ * config/frv/frvbegin.c: Likewise.
+ * config/frv/frvend.c: Likewise.
+
+2004-01-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (LINKER_DOES_NOT_WORK_WITH_DWARF2): Poison.
+ * doc/tm.texi (PREFERRED_DEBUGGING_TYPE): Don't mention
+ LINKER_DOES_NOT_WORK_WITH_DWARF2.
+ (LINKER_DOES_NOT_WORK_WITH_DWARF2): Remove.
+
+2004-01-16 J"orn Rennecke <joern.rennecke@superh.com>
+
+ PR 11864
+ * postreload.c (reload_cse_simplify_operands): Don't remove
+ implicit extension from LOAD_EXTEND_OP.
+
+2004-01-16 Jan Hubicka <jh@suse.cz>
+
+ PR opt/11350
+ * cfgcleanup.c (try_optimize_cfg): Suppress tablejump removal
+ after reload.
+ * cfgrtl.c (rtl_can_merge_blocks, cfglayout_can_merge_blocks,
+ rtl_try_redirect_by_replacing_branch): Likewise.
+
+2004-01-15 Geoffrey Keating <geoffk@apple.com>
+
+ PR pch/13689
+ * alias.c (struct alias_set_entry): Mark for GC.
+ (alias_sets): Make static, mark for GC.
+ (record_alias_subset): Use GC to allocate alias structures.
+ * varray.c (element): Make generic varrays GCed.
+
+ PR pch/13361
+ * c-typeck.c (constructor_asmspec): Delete.
+ (struct initializer_stack): Delete field 'asmspec'.
+ (start_init): Delete saving of asmspec.
+ (finish_init): Don't update constructor_asmspec.
+ * dwarf2out.c (rtl_for_decl_location): Duplicate string from tree.
+ * stmt.c (expand_asm): Duplicate strings from tree.
+ (expand_asm_operands): Likewise.
+ * tree.c (tree_size): Update computation of size of STRING_CST.
+ (make_node): Don't make STRING_CST nodes.
+ (build_string): Allocate string with tree node.
+ * tree.def (STRING_CST): Update comment.
+ * tree.h (TREE_STRING_POINTER): Adjust for change to STRING_CST.
+ (tree_string): Place contents of string in tree node.
+ * config/sh/sh.c (sh_handle_sp_switch_attribute): Duplicate string
+ from tree.
+
+ * config/rs6000/rs6000.c (rs6000_va_arg): No need to special-case
+ altivec operands.
+
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-common.h: Fix comment formatting.
+ * c-cppbuiltin.c: Likewise.
+ * c-pragma.c: Likewise.
+ * calls.c: Likewise.
+ * collect2.c: Likewise.
+ * cppcharset.c: Likewise.
+ * cpptrad.c: Likewise.
+ * dbxout.c: Likewise.
+ * defaults.h: Likewise.
+ * dwarf2out.c: Likewise.
+ * fold-const.c: Likewise.
* genautomata.c: Likewise.
+ * genconditions.c: Likewise.
+ * genflags.c: Likewise.
+ * gengtype.c: Likewise.
* integrate.c: Likewise.
* loop.c: Likewise.
- * loop.h: Likewise.
- * output.h: Likewise.
- * profile.c: Likewise.
- * ra.h: Likewise.
- * reload1.c: Likewise.
- * reload.c: Likewise.
- * sched-rgn.c: Likewise.
- * stmt.c: Likewise.
- * tree.h: Likewise.
- * vmsdbgout.c: Likewise.
-
-2002-12-12 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md: Add a new peephole2.
-
-2002-12-12 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (a peephole2): Accept a constant
- that's accepted by CONST_OK_FOR_J.
-
-2002-12-12 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.h (CONST_OK_FOR_J): New.
- (CONST_OK_FOR_LETTER_P): Use CONST_OK_FOR_J.
- * config/h8300/h8300.md (*addhi_h8300): Add a new alternative.
- (*addhi_h8300hs): Likewise.
-
-2002-12-12 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.c (reg_class_from_letter): No longer const. Add 'e' entry.
- (sh_register_move_cost): Add clause for SImode fp-fp moves.
- Increase cost for moves involving multiple general purpose registers.
- * sh.h (OVERRIDE_OPTIONS): Set reg_class_from_letter['e'] according to
- TARGET_FMOVD.
- (HARD_REGNO_MODE_OK): Allow V2SFmode and V4SFmode in general purpose
- registers, and SImode in fp registers, for ! TARGET_SHMEDIA.
- (enum reg_class reg_class_from_letter): No longer const.
- (SECONDARY_OUTPUT_RELOAD_CLASS): Use REGCLASS_HAS_FP_REG /
- REGCLASS_HAS_GENERAL_REG.
- Handle SImode moves from/to fp registers.
- ! TARGET_SHMEDIA && TARGET_FMOVD.
- (SECONDARY_INPUT_RELOAD_CLASS): Use REGCLASS_HAS_FP_REG.
- * sh.md (movsi_ie): Add alternatives to move from / to fp regisyters.
-
-2002-12-12 Andreas Schwab <schwab@suse.de>
-
- * config/ia64/ia64.c (ia64_hpux_asm_file_end): Fix typo in last
- change and some warnings.
-
-2002-12-12 Kazu Hirata <kazu@cs.umass.edu>
-
- * doc/md.texi (pushm): Fix a typo.
-
-2002-12-12 Alexandre Oliva <aoliva@redhat.com>
-
- * config/mips/mips.c (mips_output_conditional_branch): Support
- PIC-safe out-of-range branch and branch-likely.
- * config/mips/mips.md (attr length): PIC-safe out-of-range
- branches are longer.
- ("jump"): Support PIC-safe out-of-range-for-branch jumps. Remove
- unused code to support indirect jumps.
-
-2002-12-11 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa.h (BIGGEST_ALIGNMENT): Change 32-bit value to 64 bits.
- (MAX_PARM_BOUNDARY, STACK_BOUNDARY): Express in terms of
- BIGGEST_ALIGNMENT.
- (PREFERRED_STACK_BOUNDARY): Express in terms of STACK_BOUNDARY.
- (FUNCTION_BOUNDARY): Express in terms of BITS_PER_WORD.
-
-2002-12-11 Kazu Hirata <kazu@cs.umass.edu>
-
- * doc/invoke.texi: Correct dump file names.
-
-2002-12-09 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/ia64.c (ia64_hpux_asm_file_end): Don't send stripped
- name to globalize_label or assemble_name.
-
-2002-12-11 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.h (REG_CLASS_HAS_GENERAL_REG): Only true for SIBCALL_REGS
- if not TARGET_SHMEDIA.
-
-2002-12-11 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.h (REG_CLASS_HAS_FP_REG): New.
- (REGISTER_MOVE_COST) Use it. Put body into a function and
- move it into:
- * sh.c (sh_register_move_cost).
- * sh-protos.h (sh_register_move_cost): Declare.
-
- * sh.c (sh_expand_builtin): Abort for unexpected nop values.
- (sh_adjust_cost): Always return a value.
-
-2002-12-11 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.h (REG_CLASS_HAS_GENERAL_REG): New.
- (REGISTER_MOVE_COST): Use it.
-
-2002-12-11 Richard Henderson <rth@redhat.com>
-
- * tree.h (MODULE_LOCAL_P): Kill.
- * varasm.c (default_binds_local_p_1): Use decl_visibility instead.
-
-2002-12-11 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (two define_peephole2): New.
-
-2002-12-11 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.h (CONST_OK_FOR_J): Remove.
- (CONST_OK_FOR_K): Likewise.
- (CONST_OK_FOR_M): Likewise.
- (CONST_OK_FOR_LETTER_P): Do not use the above macros.
-
-2002-12-11 Neil Booth <neil@daikokuya.co.uk>
-
- * c-common.c (builtin_define_type_max): Handle unsigned
- types too.
-
-2002-12-10 Janis Johnson <janis187@us.ibm.com>
-
- PR other/8882
- * doc/tm.texi (PUSH_ARGS): Remove misplaced line.
-
-2002-12-10 Devang Patel <dpatel@appple.com>
-
- * config/darwin.h(LINK_SPEC): Add darwin specific linker options.
- * doc/invoke.texi: Add new "Darwin Options" section.
-
-2002-12-10 Jim Wilson <wilson@redhat.com>
-
- * rs6000.h (RETURN_IN_MEMORY): If ABI_V4, then TFmode is returned in
- memory.
-
-2002-12-10 Andrew Haley <aph@redhat.com>
-
- * cse.c (cse_insn): Don't cse past a basic block boundary.
-
-2002-12-10 Jakub Jelinek <jakub@redhat.com>
-
- * config/linux.h (LIB_SPEC): If -pthread, add -lpthread even if
- -shared.
- * config/alpha/linux-elf.h (LIB_SPEC): Likewise.
- * config/alpha/linux.h (LIB_SPEC): Likewise.
- * config/arm/linux-elf.h (LIB_SPEC): Likewise.
- * config/pa/pa-linux.h (LIB_SPEC): Likewise.
- * config/sparc/linux.h (LIB_SPEC): Likewise.
- * config/sparc/linux64.h (LIB_SPEC): Likewise.
-
-2002-12-09 Larin Hennessy <larin@science.oregonstate.edu>
-
- * doc/invoke.texi: Document UltraSparc III option.
-
-2002-12-09 Richard Henderson <rth@redhat.com>
-
- * config/i386/i386.h (TARGET_CPU_CPP_BUILTINS): Define
- __tune_pentium2__ and __tune_pentium3__ as necessary.
-
-2002-12-09 Richard Henderson <rth@redhat.com>
-
- * target.h (gcc_target): Add cannot_force_const_mem.
- * target-def.h (TARGET_CANNOT_FORCE_CONST_MEM): New.
- (TARGET_INITIALIZER): Add it.
- * varasm.c (force_const_mem): Fail if cannot_force_const_mem.
- * expr.c (emit_move_insn): Be prepared for force_const_mem to fail.
- * reload1.c (reload): Likewise.
- * hooks.c (hook_bool_rtx_false): New.
- * hooks.h: Declare it.
-
- * config/i386/i386.c (ix86_cannot_force_const_mem): New.
- (TARGET_CANNOT_FORCE_CONST_MEM): New.
- (ix86_expand_move): Remove de-const-pooling hack.
-
-2002-12-09 Jan Hubicka <jh@suse.cz>
-
- * toplev.c (dump_file): Fix order to match reality.
-
-2002-12-08 Geoffrey Keating <geoffk@apple.com>
-
- * config/rs6000/rs6000.md (load_multiple): Use adjust_address_nv.
- (store_multiple): Likewise.
-
-2002-12-09 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa/fptr.c (__canonicalize_funcptr_for_compare): Don't canonicalize
- function pointers in page 0.
-
-2002-12-09 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/hpux.h (TARGET_STRUCT_ARG_REG_LITTLE_ENDIAN): Remove
- definition
- (MEMBER_TYPE_FORCES_BLK): Move.
- * config/ia64/ia64.c (ia64_function_arg): Use PARALLEL to pass
- aggregate arguments.
- (ia64_function_value): Use PARALLEL to return aggregate values.
-
-2002-12-09 Steve Ellcey <sje@cup.hp.com>
-
- * doc/tm.texi (FUNCTION_ARG_REG_LITTLE_ENDIAN): Remove definition.
- * defaults.h (FUNCTION_ARG_REG_LITTLE_ENDIAN): Remove definition.
- * calls.c (store_unaligned_arguments_into_pseudos) Remove
- FUNCTION_ARG_REG_LITTLE_ENDIAN.
- * stmt.c (expand_return): Ditto.
- * expr.c (move_block_from_reg): Ditto.
- (copy_blkmode_from_reg): Ditto.
- * expmed.c (store_bit_field): Ditto.
-
-2002-12-09 Svein E. Seldal <Svein.Seldal@solidas.com>
-
- * config.gcc: Added tic4x-* target as an alias to c4x-*
-
-2002-12-08 Jan Hubicka <jh@suse.cz>
-
- * i386.c (ix86_expand_int_movcc): Use force_operand instead of
- constructing insn directly.
-
-2002-12-07 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (*iorhi_shift_8): New.
-
-2002-12-06 Bernd Schmidt <bernds@redhat.com>
-
- * doc/invoke.texi: Document FRV port options.
- * doc/md.texi: Document FRV register classes.
-
-2002-12-07 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/install.texi (Configuration): Improve description of cases
- where `make distclean` may fail; clarify --with-gnu-as; fix grammar.
-
-2002-12-06 Dhananjay Deshpande <dhananjayd@kpit.com>
-
- * gcc/config/sh/sh.c (calc_live_regs): Save fpscr only if target has
- FPU.
- (push): Generate push_fpscr.
- (pop): Generate pop_fpscr.
- * gcc/config/sh/sh.md : Add define_expand "push_fpscr", "pop_fpscr".
- (fpu_switch): Add alternative to push fpscr. Enable for TARGET_SH3E.
-
-2002-12-06 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.c (dump_table): DImode pool constants need only 32 bit alignment.
- DFmode alignment depends on TARGET_FMOVD && TARGET_ALIGN_DOUBLE.
-
-2002-12-06 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.md (movdi_i): Name. Remove inappropriate comment.
-
-2002-12-06 J"orn Rennecke <joern.rennecke@superh.com>
- Merged from basic improvements branch (excerpt):
-
- 2002-11-19 Kaz Kojima <kkojima@gcc.gnu.org>
- * config/sh/sh.h (SH_DBX_REGISTER_NUMBER): Handle PR_MEDIA_REG.
-
-2002-12-06 Jakub Jelinek <jakub@redhat.com>
-
- * expr.c (expand_expr) <case COND_EXPR>: Never modify exp in place.
-
-2002-12-05 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa32-linux.h (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL): Move define.
- * pa.h (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL): To here.
-
-2002-12-05 Dale Johannesen <dalej@apple.com>
-
- * tree.c (unsafe_for_reeval): Consider callee child of CALL_EXPR.
-
-2002-12-05 Danny Smith <dannysmith@users.sourceforge.net>
-
- * config/i386/cygwin.h (SUBTARGET_PROLOGUE): Replace with
- PROFILE_HOOK.
- * config/i386/mingw32.h (SUBTARGET_PROLOGUE): Don't undef.
-
-2002-12-05 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/spe.h (__ev_mwlufi): Remove.
- (__ev_mwlufia): Remove.
- (__ev_mwlumfaaw): Remove.
- (__ev_mwlusfaaw): Remove.
- (__ev_mwlumfanw): Remove.
- (__ev_mwlusfanw): Remove.
-
-2002-12-05 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (*andorsi3_shift_8): New.
-
-2002-12-05 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (shift_alg_si): Optimize ashift:HI and
- lshiftrt:SI by 28, 29, and 30 bits when !TARGET_H8300.
- (get_shift_alg): Return optimal assembly instructions for the
- shifts mentioned above.
-
-2002-12-04 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (h8300_init_once): Do not use loop to
- implement ashiftrt:HI by 13 bits on H8S.
-
-2002-12-04 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa/fptr.c (__canonicalize_funcptr_for_compare): New file and function.
- * pa.md (canonicalize_funcptr_for_compare): Output library call to
- canonicalize_funcptr_for_compare_libfunc on TARGET_ELF32.
- * pa32-linux.h (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL,
- CTOR_LIST_BEGIN): New defines.
- * pa/t-linux (LIB2FUNCS_EXTRA): New define.
- (fptr.c): Add make rules.
-
-2002-12-04 Geoffrey Keating <geoffk@apple.com>
-
- * combine.c (combine_simplify_rtx): Add new canonicalizations.
- * doc/md.texi (Insn Canonicalizations): Document new
- canonicalizations for multiply/add combinations.
- * config/rs6000/rs6000.md: Add and modify floating add/multiply
- patterns to ensure they're used whenever they can be.
-
-2002-12-04 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c: Update the comments related to shifts.
-
-2002-12-04 Chris Demetriou <cgd@broadcom.com>
-
- * config/mips/mips.md (get_fnaddr): Correct length attribute.
-
-2002-12-04 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (*extzv_8_8): New.
- (*extzv_8_16): Likewise.
-
-2002-12-04 Jason Merrill <jason@redhat.com>
-
- PR c++/8461, c++/8625
- * integrate.c (copy_decl_for_inlining): Handle explicit invisible
- references.
- * tree-inline.c (initialize_inlined_parameters): Likewise.
-
- * tree.c (variably_modified_type_p): Just return an error_mark_node.
-
-2002-12-04 Chris Demetriou <cgd@broadcom.com>
-
- * config/mips/mips.md (get_fnaddr): Avoid placing an "la"
- macro instruction in a branch delay slot, to avoid assembler
- warnings.
-
-2002-12-04 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR c/7622
- * c-semantics (genrtl_scope_stmt): Do not output inlined
- nested functions that contain no code.
-
-2002-12-04 Jan Hubicka <jh@suse.cz>
-
- * cfgrtl.c (force_nonfallthru_and_redirect): Allow abnormal edge
- to be forced into nonfallthru.
-
-2002-12-03 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/t-netbsd (USER_H): Set to $(EXTRA_HEADERS).
-
-2002-12-03 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/spe.md (*movv1di_const0): New pattern.
-
-2002-12-03 Richard Henderson <rth@redhat.com>
-
- * libgcc-std.ver: Inherit GCC_3.3 from GCC_3.0.
-
-2002-12-03 Hans-Peter Nilsson <hp@bitrange.com>
-
- * bitmap.c (bitmap_ior_and_compl, bitmap_union_of_diff):
- Initialize tmp.using_obstack to 0.
-
-2002-12-03 Andreas Schwab <schwab@suse.de>
-
- * config/m68k/m68k.h (EH_RETURN_DATA_REGNO): Define.
- (EH_RETURN_STACKADJ_RTX): Define.
- (EH_RETURN_HANDLER_RTX): Define.
- (ASM_PREFERRED_EH_DATA_FORMAT): Define.
- * config/m68k/m68k.c (m68k_save_reg): New function. Handle eh
- registers and don't save fixed registers.
- (m68k_output_function_prologue): Use it.
- (use_return_insn): Likewise.
- (m68k_output_function_epilogue): Likewise.
-
-2002-12-03 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (single_one_operand): Fix a warning.
- (single_zero_operand): Likewise.
-
-2002-12-02 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (dosize): Replace argument op with
- sign.
- (h8300_output_function_prologue): Update the call to dosize.
- (h8300_output_function_epilogue): Likewise.
-
-2002-12-02 Bob Wilson <bob.wilson@acm.org>
-
- * config/xtensa/xtensa.h: Delete ifndefs with nothing inside them.
-
-2002-12-02 Craig Rodrigues <rodrigc@gcc.gnu.org>
-
- * configure.in: Use "missing" script to generate warning if
- flex or bison programs not found, instead of invoking "false".
- * configure: Rebuilt.
-
-2002-12-02 Jan Hubicka <jh@suse.cz>
-
- * unroll.c (copy_loop_body): Copy CONST_OR_PURE_CALL_P.
-
-2002-12-02 Jan Hubicka <jh@suse.cz>
-
- * i386.c (ix86_expand_int_movcc): Avoid overflow.
-
-2002-12-02 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (dosize): Output r7/er7 instead of sp.
- (push): Likewise.
- (pop): Likewise.
- (h8300_output_function_prologue): Likewise.
- (h8300_output_function_epilogue): Likewise.
-
-2002-12-02 J"orn Rennecke <joern.rennecke@superh.com>
-
- * expmed.c (store_bit_field): Use int_mode_for_mode to find
- corresponding mode of non-integer mode, unless it is VOIDmode.
-
-2002-12-02 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (stm_h8300s_2): New.
- (stm_h8300s_3): Likewise.
- (stm_h8300s_4): Likewise.
- (five define_peephole2): Likewise.
-
-2002-12-02 Kazu Hirata <kazu@cs.umass.edu>
-
- * ra-build.c: Fix a comment typo.
-
-2002-12-01 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (h8300_output_function_prologue):
- Remove variable idx.
- (h8300_output_function_epilogue): Likewise.
-
-2002-12-01 Zack Weinberg <zack@codesourcery.com>
-
- * config/frv/xm-frv.h: Delete, unnecessary.
-
-2002-12-01 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md: Add comments for define_peephole2.
-
-2002-12-01 Mark Mitchell <mark@codesourcery.com>
-
- * builtin-types.def (BT_SIZE): Use size_type_node.
- * builtins.c (fold_builtin): Make the builtin strlen returns a
- size_t, not a sizetype.
- * c-common.c (c_sizeof_or_alignof_type): Use size_type_node, not
- c_size_type_node.
- (c_alignof_expr): Likewise.
- (c_common_nodes_and_builtins): Likewise.
- * c-common.h (CTI_C_SIZE_TYPE): Remove.
- (c_size_type_node): Likewise.
- * c-format.c (T_ST): Use size_type_node, not c_size_type_node.
- * tree.h (TI_SIZE_TYPE): New enumeral.
- (size_type_node): Likewise.
-
-2002-11-30 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * cfg.c (dump_flow_info): Use max_reg_num () to determine the largest
- pseudo register number plus 1.
-
-2002-11-29 Hans-Peter Nilsson <hp@bitrange.com>
-
- * cpplib.c (_cpp_test_assertion): Default *value to 0.
-
- * cppexp.c (num_part_mul): Initialize result.unsignedp, to 1.
-
-2002-11-29 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/t-crtstuff: New target makefile fragment.
- * config.gcc [s390-*-linux, s390x-*-linux]: Use it.
-
-2002-11-29 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (movsi_h8300hs): Change the order of
- alternatives to correct the length when the memory operand is
- either pre_dec or post_inc.
-
-2002-11-29 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (an anonymous pattern): Give an
- internal name *tst_extzv_bitqi_1_n.
- Accept bit_operand instead of bit_memory_operand.
- Do not accept bit tests with the MSB.
- (*tst_extzv_memqi_1_n): New.
-
-2002-11-28 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (h8300_eightbit_constant_address_p):
- Fix a comment typo.
- (h8300_tiny_constant_address_p): Likewise.
-
-2002-11-28 Michael Matz <matz@suse.de>
-
- * doc/passes.texi: Mention the other register allocator.
-
-2002-11-28 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (6 new peephole2 patterns): New.
-
-2002-11-28 Jakub Jelinek <jakub@redhat.com>
-
- * config.gcc (x86_64-*-linux*) [tmake_file]: Remove i386/t-crtstuff.
- * config/t-linux (CRTSTUFF_T_CFLAGS_S): Add $(CRTSTUFF_T_CFLAGS).
- * config/i386/t-linux64 (CRTSTUFF_T_CFLAGS): Define.
-
-2002-11-28 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (h8300_and_costs): New.
- * config/h8300/h8300.h (RTX_COSTS): Use h8300_and_costs.
- * config/h8300/h8300-protos.h: Add a prototype for
- h8300_and_costs.
-
-2002-11-27 Zack Weinberg <zack@codesourcery.com>
-
- * config/rs6000/rs6000.c (altivec_init_builtins): Make the
- pointer argument in the prototypes of the following builtins
- be (const TYPE *) rather than (TYPE *):
- + __builtin_altivec_ld_internal_4sf
- + __builtin_altivec_ld_internal_4si
- + __builtin_altivec_ld_internal_8hi
- + __builtin_altivec_ld_internal_16qi
- + __builtin_altivec_lvsl
- + __builtin_altivec_lvsr
- + __builtin_altivec_lvebx
- + __builtin_altivec_lvehx
- + __builtin_altivec_lvewx
- + __builtin_altivec_lvxl
- + __builtin_altivec_lvx
- + __builtin_altivec_dst
- + __builtin_altivec_dstt
- + __builtin_altivec_dstst
- + __builtin_altivec_dststt
-
-2002-11-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * except.c (default_exception_section): Move variable into the
- scope where it is used.
-
-2002-11-27 Krister Walfridsson <cato@df.lth.se>
-
- * config.gcc (*-*-netbsd[2-9]*, *-*-netbsdelf[2-9]*): Test for
- correct version.
-
-2002-11-27 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.h (OK_FOR_U): Remove extra parentheses.
-
-2002-11-27 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (h8300_shift_costs): New.
- * config/h8300/h8300.h (RTX_COSTS): Use h8300_shift_costs.
- * config/h8300/h8300-protos.h: Add a prototype for
- h8300_shift_costs.
-
-2002-11-27 Jim Wilson <wilson@redhat.com>
-
- * config/rs6000/spe.md (spu_evsplatfi, spu_evsplati): Swap operands
- in output template.
-
-2002-11-27 Casper S. Hornstrup <chorns@users.sourceforge.net>
-
- * config/i386/i386.h (DLL_IMPORT_EXPORT_PREFIX): Define.
- * config/i386/winnt.c (i386_pe_dllexport_name_p): Use
- DLL_IMPORT_EXPORT_PREFIX, not '@'.
- (i386_pe_dllimport_name_p): Likewise.
- (i386_pe_mark_dllexport): Likewise.
- (i386_pe_mark_dllimport): Likewise.
- (i386_pe_encode_section_info): Likewise.
- (i386_pe_strip_name_encoding): Likewise.
-
-2002-11-27 Richard Henderson <rth@redhat.com>
-
- * mkmap-symver.awk (BEGIN): Set sawsymbol false.
- (nm && NF == 3): Set sawsymbol true.
- (END): Exit if no symbols seen.
- (output): Fix map syntax error if no globals for the version.
-
-2002-11-27 Jan Hubicka <jh@suse.cz>
-
- * builtins.def (DEF_C99_BUILTIN): Fix.
-
-2002-11-26 Andrew Haley <aph@redhat.com>
-
- * unwind-sjlj.c (_Unwind_FindEnclosingFunction): Rename
- from_Unwind_Find_Enclosing_Function.
- * unwind-dw2.c (_Unwind_FindEnclosingFunction): Likewise.
- * config/ia64/unwind-ia64.c (_Unwind_FindEnclosingFunction): Likewise.
- * libgcc-std.ver (_Unwind_FindEnclosingFunction): Rename from
- _Unwind_Find_Enclosing_Function, export @@GCC_3.3.
- * unwind.h (_Unwind_FindEnclosingFunction): Add.
-
-2002-11-26 Hartmut Penner <hpenner@de.ibm.com>
-
- * config/s390/s390.c (390_output_constant_pool): Set alignment
- before label in 64 bit mode, behind otherwise.
-
-2002-11-26 Richard Henderson <rth@redhat.com>
-
- * c-common.c (handle_visibility_attribute): Accept "default".
- * tree.h (enum symbol_visibility): New.
- (decl_visibility): Declare.
- * target.h (gcc_target.visibility): Take visibility arg as integer.
- * varasm.c (default_assemble_visibility): Likewise.
- (decl_visibility): New.
- (maybe_assemble_visibility): Use it.
- * output.h (default_assemble_visibility): Update prototype.
- * config/rs6000/rs6000.c (rs6000_assemble_visibility): Take
- visibility arg as integer.
- * doc/extend.texi: Document default visibility.
-
-2002-11-26 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c: Adjust spacing.
+ * predict.c: Likewise.
+ * sdbout.c: Likewise.
+
+2004-01-15 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/ia64.md (*movti_internal): C output template
+ extracted to ia64.c.
+ (*movti_internal_reg): Delete.
+ (reload_inti, reload_outti): Use the correct mode on operand 2
+ in the first place, don't fix it up in the output template.
+ (movtf, reload_ointf, reload_outtf): New expanders.
+ (*movtf_internal): New define_insn_and_split.
+ * config/ia64/ia64.c (ia64_split_timode): Rename to ia64_split_tmode;
+ make static; do not hand TFmode CONST_DOUBLEs to split_double.
+ (ia64_split_tmode_move): New function, body mostly pulled
+ from ia64.md:*movti_internal.
+ (ia64_function_arg_words): New function, extracted common
+ logic from ia64_function_arg et seq.
+ (ia64_function_arg_offset): Likewise. Handle correctly the
+ case of a scalar quantity 16 bytes wide with only 8-byte alignment.
+ (ia64_function_arg, ia64_function_arg_partial_nregs)
+ (ia64_function_arg_advance): Use ia64_function_arg_words and
+ ia64_function_arg_offset.
+ (ia64_function_value): TCmode does not go in float regs.
+ (ia64_secondary_reload_class): Also handle TFmode.
+ * config/ia64/ia64-protos.h: Remove prototype for
+ ia64_split_timode; add prototype for ia64_split_tmode_move.
+
+2004-01-15 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (MAINT): Make it an immediate assignment.
+
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.md: Remove useless calls to gen_lowpart.
+
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/coff.h: Replace Hitachi with Renesas.
+ * config/h8300/elf.h: Likewise.
+ * config/h8300/h8300-protos.h: Likewise.
+ * config/h8300/h8300.c: Likewise.
* config/h8300/h8300.h: Likewise.
+ * config/h8300/h8300.md: Likewise.
+ * config/h8300/lib1funcs.asm: Likewise.
-2002-11-26 Richard Henderson <rth@redhat.com>
-
- * hooks.c (hook_bool_void_false, hook_void_tree_int,
- hook_void_FILEptr_constcharptr): Rename so that the return
- type is first.
- (hook_int_tree_tree_1, hook_void_tree, hook_void_tree_treeptr,
- hook_bool_tree_false): New.
- * hooks.h: Update.
- * langhooks-def.h: Update for renames.
- * target-def.h: Likewise.
- * tree.c (default_comp_type_attributes,
- default_set_default_type_attributes, default_insert_attributes,
- default_function_attribute_inlinable_p,
- default_ms_bitfield_layout_p): Remove.
- * tree.h: Update.
-
-2002-11-26 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa-protos.h (function_value): New prototype.
- * pa.c (function_value): Use a PARALLEL to return small aggregates on
- TARGET_64BIT.
- * pa.h (FUNCTION_VALUE): Use function_value.
- * pa.md (call_value_internal_symref, call_value_internal_reg_64bit,
- call_value_internal_reg, sibcall_value_internal_symref,
- sibcall_value_internal_symref_64bit): Remove =rf constraint on return
- value.
-
-2002-11-26 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * expr.c (gen_group_rtx, emit_group_move): New functions.
- * expr.h (gen_group_rtx, emit_group_move): Prototype.
- * function.c (expand_function_start): Use gen_group_rtx to create a
- PARALLEL rtx to hold the return value when the real return rtx is a
- PARALLEL.
- (expand_function_end): Use emit_group_move to move the return value
- from a PARALLEL to the real return registers.
- * rtl.h (REG_FUNCTION_VALUE_P): Allow function values to be returned
- in PARALLELs.
-
-2002-11-26 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/t-libc-ok: Fix typo.
-
-2002-11-26 Jakub Jelinek <jakub@redhat.com>
-
- * configure.in: Move AC_CANONICAL_SYSTEM and AC_ARG_PROGRAM back
- before AC_PROG_CC.
- * configure: Rebuilt.
-
-2002-11-26 Nathan Sidwell <nathan@codesourcery.com>
-
- * c-decl.c: (start_struct): Commonize flag setting.
-
-2002-11-26 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/rs6000/rs6000.h (RS6000_CPU_CPP_ENDIAN_BUILTINS): New.
- * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Use
- RS6000_CPU_CPP_ENDIAN_BUILTINS.
- * config/rs6000/netbsd.h (RS6000_CPU_CPP_ENDIAN_BUILTINS): Redefine.
-
-2002-11-26 Hartmut Penner <hpenner@de.ibm.com>
-
- * config/s390/s390.md (literal_pool_64, literal_pool_31 ): New
- insns.
- * config/s390/s390.c (struct machine_function): Introduction of
- struct machine_function.
- (s390_output_symbolic_const): Use of cfun.
- (s390_optimize_prolog): Likewise.
- (s390_fixup_clobbered_return_reg): Likewise.
- (s390_frame_info): Likewise.
- (s390_emit_prologue, s390_emit_epilogue): Likewise.
- (s390_init_machine_status): New function.
- (override_options): call s390_init_machine_status.
- * config/s390/s390-protos.h (s390_output_constant_pool): Changed
- prototype.
-
-2002-11-26 Jakub Jelinek <jakub@redhat.com>
-
- * varasm.c (output_constant_pool): For pool constants in mergeable
- section ensure each constant is padded to multiple of entity size.
-
-2002-11-26 Jakub Jelinek <jakub@redhat.com>
-
- * varasm.c (default_exception_section): Move to...
- * except.c (default_exception_section): ... here. Make
- .gcc_except_table read-only if it is not expected to have any
- dynamic relocations and linker handles it.
- * dwarf2out.c (default_eh_frame_section): Make .eh_frame read-only
- if it is not expected to have any dynamic relocations and linker
- handles it.
- * configure.in (HAVE_LD_RO_RW_SECTION_MIXING): Check what ld does
- when linking read-only and read-write sections together.
- * configure, config.in: Rebuilt.
- * crtstuff.c (EH_FRAME_SECTION_CONST): Define.
- (__EH_FRAME_BEGIN__, __FRAME_END__): Add it.
-
-2002-11-25 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/spe.h (__ev_create_sfix32_fs): Change macro into
- new function.
- (__ev_create_ufix32_fs): Same.
- (__ev_get_sfix32_fs_internal): New.
- (__ev_get_sfix32_fs): Define to use function.
- (__ev_get_ufix32_fs_internal): New.
- (__ev_get_ufix32_fs): Define to use function.
- (__ev_get_upper_ufix32_fs): Call __ev_get_ufix32_fs.
- (__ev_get_lower_ufix32_fs): Same.
- (__ev_get_upper_sfix32_fs): Call __ev_get_sfix32_fs.
- (__ev_get_lower_sfix32_fs): Same.
- (__ev_set_sfix32_fs_internal): New.
- (__ev_set_ufix32_fs_internal): New.
- (__ev_set_sfix32_fs): Call __ev_set_sfix32_fs_internal.
- (__ev_set_ufix32_fs): Call __ev_set_ufix32_fs_internal.
- (__ev_set_upper_sfix32_fs): Call function.
- (__ev_set_lower_sfix32_fs): Same.
- (__ev_set_upper_ufix32_fs): Same.
- (__ev_set_lower_ufix32_fs): Same.
-
-2002-11-25 Douglas B Rupp <rupp@gnat.com>
-
- * gcc.c (do_spec_1): Reset delete_this_arg to zero.
-
-2002-11-25 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/elfos.h (HANDLE_SYSV_PRAGMA): Define as 1.
- * config/interix.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/linux-aout.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/lynx-ng.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/lynx.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/netbsd.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/openbsd.h (HANDLE_SYSV_PRAGMA: Likewise.
- * config/alpha/elf.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/arm/netbsd.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/cris/aout.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/d30v/d30v.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/frv/frv.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/i386/djgpp.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/i386/i386-interix.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/i386/vxi386.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/ia64/ia64.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/m88k/m88k.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/mmix/mmix.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/rs6000/aix.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/rs6000/darwin.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/sparc/linux-aout.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/sparc/vxsparc64.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/stormy16/stormy16.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/alpha/osf.h (HANDLE_SYSV_PRAGMA): Don't undef before
- defining.
- * config/i386/sco5.h (HANDLE_SYSV_PRAGMA): Likewise.
- * config/mips/iris5.h (HANDLE_SYSV_PRAGMA): Likewise.
-
-2002-11-25 Dave Pitts <dpitts@cozx.com>
-
- * gcc/fixinc/mkfixinc.sh: add i370-*-openedition to bypass fixinc list
-
-2002-11-25 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (an anonymous pattern): New.
-
-2002-11-25 Richard Henderson <rth@redhat.com>
-
- * alias.c (find_base_value): Use new_reg_base_value if it's live.
- (copying_arguments): Make boolean.
-
-2002-11-25 Jason Thorpe <thorpej@wasabisystems.com>
-
- * gcc.c (static_spec_functions): Add if-exists-else spec
- function.
- (if_exists_else_spec_function): New function.
- * doc/invoke.texi: Document the if-exists-else spec function.
-
- * config/netbsd-elf.h (NETBSD_STARTFILE_SPEC): For -static, use
- "%:if-exists-else(crtbeginT%O%s crtbegin%O%s)".
-
-2002-11-25 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config.gcc (powerpc-*-netbsd*): Replace "svr4.h" with
- "netbsd.h netbsd-elf.h" in tm_file. Set tmake_file to
- "${tmake_file} rs6000/t-netbsd".
- * config/rs6000/netbsd.h: Rewrite.
- * config/rs6000/t-netbsd: New file.
-
-2002-11-25 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (an anonymous pattern): Relax the
- condition for the pattern.
+2004-01-15 Andrew Pinski <apinski@apple.com>
-2002-11-25 Aldy Hernandez <aldyh@redhat.com>
+ * config/rs6000/rs6000.c (uses_TOC): Wrap #if TARGET_ELF
+ around it.
- * config/rs6000/rs6000.h (enum rs6000_builtins): Remove evmwlssf,
- evmwlsmf, evmwlssfa, evmwlsmfa, evmwlssfaaw, evmwlsmfaaw,
- evmwlssfanw, evmwlsmfanw.
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
- * config/rs6000/rs6000.c (bdesc_2arg): Same.
+ * config/h8300/h8300.c (h8300_return_in_memory): New.
+ (TARGET_STRUCT_VALUE_RTX): Likewise.
+ (TARGET_RETURN_IN_MEMORY): Likewise.
+ * config/h8300/h8300.h (STRUCT_VALUE): Remove.
+ (RETURN_IN_MEMORY): Likewise.
- * config/rs6000/spe.md: Same for patterns.
+2004-01-15 Richard Earnshaw <rearnsha@arm.com>
-2002-11-25 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
+ PR optimization/13375
+ * gcse.c (handle_avail_expr): Just return if the source is not a
+ single set.
- PR c/8639
- * fold-const.c (extract_muldiv): Don't propagate division unless
- both arguments are multiples of C.
+2004-01-15 Richard Earnshaw <rearnsha@arm.com>
+ Daniel Jacobowitz <drow@mvista.com>
-2002-11-25 Andrew Haley <aph@redhat.com>
+ * arm/lib1funcs.asm (ARM_FUNC_START): Correct interworking case.
+ (EQUIV): Define.
+ (ARM_FUNC_ALIAS): New macro.
+ * arm/ieee754-df.S (gedf2, ledf2, nedf2, eqdf2): Use it.
+ * arm/ieee754-sf.S (gesf2, lesf2, nesf2, eqsf2): Use it.
- * libgcc-std.ver (_Unwind_Find_Enclosing_Function): Add.
- * config/ia64/unwind-ia64.c (_Unwind_Find_Enclosing_Function): New.
- * unwind-sjlj.c (_Unwind_Find_Enclosing_Function): Likewise.
- * unwind-dw2.c (_Unwind_Find_Enclosing_Function): Likewise.
+2004-01-15 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-2002-11-24 Kazu Hirata <kazu@cs.umass.edu>
+ PR optimization/12372
+ * calls.c (expand_call): Add call_fusage data for stack arguments in
+ constant calls.
- * config/h8300/h8300.c (h8300_init_once): Fix a typo in the
- target help message.
+2004-01-15 Alan Modra <amodra@bigpond.net.au>
-2002-11-24 Jason Thorpe <thorpej@wasabisystems.com>
+ * config/rs6000/rs6000.c (uses_TOC): Correct comment. Make static.
+ (rs6000_elf_declare_function_name): Formatting.
+ * config/rs6000/rs6000-protos.h (uses_TOC): Remove declaration.
- * config.gcc (*-*-netbsd*1.[7-9]*, *-*-netbsd*[2-9]*): Set
- extra_parts to "crtbegin.o crtend.o crtbeginS.o crtendS.o
- crtbeginT.o".
- (arm*-*-netbsd*, i[34567]86-*-netbsd*, m68k*-*-netbsd*)
- (ns32k-*-netbsd*, sparc-*-netbsd*, vax-*-netbsd*): Set extra_parts
- to "" for a.out configurations.
- * config/t-netbsd (CRTSTUFF_T_CFLAGS): Set to "-fPIC".
+2004-01-15 Jan Hubicka <jh@suse.cz>
-2002-11-24 Jason Thorpe <thorpej@wasabisystems.com>
+ PR bootstrap/13692
+ * sched-deps.c (sched_analyze_1, sched_analyze_2): Fix thinko in
+ previous patch.
- * config/alpha/netbsd.h (CPP_SUBTARGET_SPEC): Just use
- NETBSD_CPP_SPEC directly.
- (SUBTARGET_EXTRA_SPECS): Remove netbsd_cpp_spec. Add
- netbsd_endfile_spec.
- (ENDFILE_SPEC): Use %(netbsd_endfile_spec).
+2004-01-15 Richard Henderson <rth@redhat.com>
-2002-11-24 Jason Thorpe <thorpej@wasabisystems.com>
+ * config/alpha/alpha.h (REG_ALLOC_ORDER): Reorder fp regs after
+ integer regs of the same call-savedness.
- * config/netbsd-elf.h (STARTFILE_SPEC): Rename to
- NETBSD_STARTFILE_SPEC.
- (STARTFILE_SPEC): Redefine in terms of NETBSD_STARTFILE_SPEC.
- (ENDFILE_SPEC): Likewise.
- * config/netbsd.h (LIB_SPEC, LIBGCC_SPEC): Likewise.
+2004-01-15 Andreas Schwab <schwab@suse.de>
-2002-11-24 Andreas Schwab <schwab@suse.de>
+ PR bootstrap/13562
+ * config/m68k/m68k.c (output_move_const_into_data_reg): Clear cc
+ status for NOTB/NOTW/NEGW methods.
- * Makefile.in (install-driver): Remove versioned link before
- trying to create it.
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
- * config/m68k/m68k.c: Fix typo in last change defining
- TARGET_ASM_CAN_OUTPUT_MI_THUNK.
+ * doc/invoke.texi: Update dump file names. Fix a typo.
-2002-11-23 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
- * config/h8300/h8300.c (print_operand): Update the use of
- h8300_tiny_constant_address_p.
- (h8300_adjust_insn_length): Likewise.
- (h8300_tiny_constant_address_p): Check if the given rtx is a
- variable declared with __attribute__ ((tiny_data)).
+ * builtins.c (expand_builtin_va_end): Don't use
+ EXPAND_BUILTIN_VA_END.
+ * system.h (EXPAND_BUILTIN_VA_END): Poison.
+ * config/d30v/d30v.h: Remove a commented-out definition of
+ EXPAND_BUILTIN_VA_END.
+ * config/stormy16/stormy16.h: Likewise.
-2002-11-22 Dale Johannesen <dalej@apple.com>
+2004-01-15 Kazu Hirata <kazu@cs.umass.edu>
- * toplev.c (rest_of_compilation): Fix comments.
+ * system.h (STRUCT_VALUE_INCOMING_REGNUM): Poison.
+ * targhooks.c (default_struct_value_rtx): Don't use
+ STRUCT_VALUE_INCOMING_REGNUM.
-2002-11-22 Geoffrey Keating <geoffk@apple.com>
+2004-01-15 Kelley Cook <kcook@gcc.gnu.org>
- * aclocal.m4 (ac_cv_func_mmap_dev_zero): Darwin does not
- allow mmap from /dev/zero. Don't make decisions for the host
- based on presence or absence of /dev/zero on the build machine.
- (ac_cv_func_mmap_anon): Darwin does have working MMAP_ANON.
- (AC_FUNC_MMAP_FILE): Darwin does have mmap of a file.
+ PR bootstrap/12744
+ * configure.in: Revamp enable-generated-files-in-srcdir rule to define
+ GENINSRC and not parsedir. Define srcextra as a langhook.
* configure: Regenerate.
-
-2002-11-22 Daniel Jacobowitz <drow@mvista.com>
-
- * gcc.c (make_relative_prefix, split_directories)
- (free_split_directories): Removed.
-
-2002-11-22 Daniel Jacobowitz <drow@mvista.com>
-
- * configure.in: Set insn=nop for DWARF-2 tests on ARM.
- * configure: Regenerated.
-
-2002-11-22 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (compute_a_shift_length): Fix the insn
- length computation when xor.l is output.
-
-2002-11-21 Jim Wilson <wilson@redhat.com>
-
- * config/rs6000/rs6000.c (function_arg): Set inner mode of SPE
- vectors to SI.
-
-2002-11-21 Bob Wilson <bob.wilson@acm.org>
-
- * config/xtensa/xtensa-protos.h (xtensa_copy_incoming_a7): Declare.
- * config/xtensa/xtensa.c (struct machine_function): Add
- incoming_a7_copied flag.
- (xtensa_copy_incoming_a7): Define.
- (xtensa_emit_move_sequence): Use xtensa_copy_incoming_a7.
- * config/xtensa/xtensa.md (movdi, movsf, movdf): Ditto.
-
-2002-11-21 Jan Hubicka <jH@suse.cz>
-
- * i386-protos.h (x86_64_sign_extended_value): Fix prototype.
- * i386.c (x86_64_general_operand, x86_64_szext_general_operand,
- x86_64_nonmemory_operand, x86_64_movabs_operand,
- x86_64_szext_nonmemory_operand, x86_64_immediate_operand,
- ix86_expand_int_movcc): Update call of x86_64_sign_extended_value.
- (local_symbolic_operand): Do not care the 64bit limits.
- (x86_64_sign_extended_value): Remove allow_rip support.
- (legitimate_pic_address_disp_p): Handle all cases allowed
- with RIP addressing.
- (legitimate_address_p): Use legitimate_pic_address_disp_p for PIC.
- (legitimize_pic_address): Reorganize.
- * i386.h (EXTRA_CONSTRAINT): Update call of x86_64_sign_extended_value.
-
-2002-11-21 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config.gcc (arm*-*-netbsdelf*): Enable configuration.
- * config/arm/netbsd-elf.h: New file.
-
-2002-11-21 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/arm/elf.h (SUBTARGET_EXTRA_SPECS): Add
- subtarget_asm_float_spec.
- (SUBTARGET_ASM_FLOAT_SPEC): Define, moving the
- defaults from...
- (ASM_SPEC): ...here. Use subtarget_asm_float_spec.
-
-2002-11-21 Nick Clifton <nickc@redhat.com>
-
- * config/fr30/fr30.md (movsf_constant_store): Move code to
- detect 0.0 into fr30.c.
- * config/fr30/fr30-protos.h (fr30_const_double_is_zero):
- Prototype.
- * config/fr30/fr30.c (fr30_const_double_is_zero): New
- function. Return true if the rtx is 0.0.
-
-2002-11-21 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/arm/elf.h (ASM_SPEC, LINK_SPEC): Pass -EL
- if -mlittle-endian is specified.
-
-2002-11-21 Richard Earnshaw <rearnsha@arm.com>
-
- PR optimization/2903
- * arm.md (anddi_notzesidi_di): Operand 2 is inverted not operand 1.
- (anddi_notsesidi_di): Likewise.
-
-2002-11-21 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (print_operand): Use
- h8300_eightbit_constant_address_p and
- h8300_tiny_constant_address_p.
- (h8300_adjust_insn_length): Likewise.
- * config/h8300/h8300.h (EIGHTBIT_CONSTANT_ADDRESS_P): Remove.
- (TINY_CONSTANT_ADDRESS_P): Likewise.
- (OK_FOR_U): Use eightbit_constant_address_p.
-
-2002-11-21 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/libgcc-libc.ver: Add multilib support.
- * config/s390/linux.h (MULTILIB_DEFAULT): Define.
- * config/s390/t-linux64 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES,
- MULTILIB_OSDIRNAMES, LIBGCC, INSTALL_LIBGCC,
- EXTRA_MULTILIB_PARTS): Define.
-
-2002-11-21 Richard Earnshaw <rearnsha@arm.com>
-
- * arm.c (arm_get_frame_size): A leaf function does not need its
- stack padding to an aligned boundary if it has no frame.
- (thumb_get_frame_size): Likewise.
-
-2002-11-20 Steve Ellcey <sje@cup.hp.com>
-
- * emit-rtl.c (gen_reg_rtx): Simplify mapping of Complex type
- to component type using GET_MODE_INNER.
- * expr.c (emit_move_insn_1): Ditto.
- * optabs.c (expand_binop): Ditto.
- (expand_unop): Ditto.
- (expand_complex_abs): Ditto.
-
-2002-11-20 Douglas B Rupp <rupp@gnat.com>
-
- * hwint.h (HAVE___INT64): Fix typo (was HAVE__INT64).
-
-2002-11-20 DJ Delorie <dj@redhat.com>
-
- * config/stormy16/stormy16.c (s16builtins,
- xstormy16_init_builtins, xstormy16_expand_builtin): New.
- * config/stormy16/stormy16.md (divmodhi4, sdivlh, udivlh): New.
-
-2002-11-20 Hans-Peter Nilsson <hp@bitrange.com>
-
- * Makefile.in (RUN_GEN, VALGRIND_DRIVER_DEFINES): New variables.
- (DRIVER_DEFINES): Add $(VALGRIND_DRIVER_DEFINES).
- (executing gencheck, genconfigs, genconditions, genflags,
- gencodes, genconstants, genemit, genrecog, genopinit, genextract,
- genpeep, genattr, genattrtab, genoutput, gengenrtl, genpreds,
- gengtype, genprotos): Prepend $(RUN_GEN).
- * configure.in: Move host compiler tests before --enable-checking
- tests.
- (--enable-checking=valgrind): New.
- * config.in, configure: Regenerate.
- * cppfiles.c [!ENABLE_VALGRIND_CHECKING] (VALGRIND_DISCARD):
- Define as empty.
- (read_include_file): When doing the mmap+1 trick,
- valgrind-annotate the byte after the mmap:ed area as readable.
- (purge_cache): Remove above annotation.
- * gcc.c (execute) [ENABLE_VALGRIND_CHECKING]: Arrange to prepend
- VALGRIND_PATH -q to each command.
-
- * ggc-common.c [!ENABLE_VALGRIND_CHECKING] (VALGRIND_DISCARD):
- Define as empty.
- (ggc_realloc): Update valgrind annotations.
- * ggc-page.c [!ENABLE_VALGRIND_CHECKING] (VALGRIND_DISCARD):
- Define as empty.
- (alloc_anon, free_page, ggc_alloc, poison_pages): Add machinery to
- valgrind-annotate memory.
-
-2002-11-20 Ulrich Weigand <uweigand@de.ibm.com>
-
- * recog.c (constrain_operands): Prefer exact match over reloadable
- EXTRA_MEMORY_CONSTRAINT or EXTRA_ADDRESS_CONSTRAINT.
-
- * reload.c (find_reloads): Always reload EXTRA_ADDRESS_CONSTRAINT
- operands in Pmode.
-
-2002-11-20 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR c/8518
- * c-decl.c (duplicate_decls): Outline the second definition
- of an extern inline function in all cases.
-
-2002-11-20 Richard Sandiford <rsandifo@redhat.com>
-
- * stor-layout.c (place_field): Update rli->offset as well as
- rli->bitpos.
-
-2002-11-20 Richard Sandiford <rsandifo@redhat.com>
-
- * sched-deps.c (sched_analyze): Check HARD_REGNO_CALL_PART_CLOBBERED.
-
-2002-11-20 Richard Sandiford <rsandifo@redhat.com>
-
- * config/sh/sh.md (udivsi3): Don't put udivsi3_i4_media instructions
- into a libcall block.
- (divsi3): Likewise divsi3_i4_media.
-
-2002-11-20 Richard Sandiford <rsandifo@redhat.com>
-
- * global.c (find_reg): Check HARD_REGNO_NREGS before kicking
- out another register.
-
-2002-11-20 Jakub Jelinek <jakub@redhat.com>
-
- * combine.c (force_to_mode): Only replace with (not Y) if all bits in fuller_mask
- (not just mask) are set in C.
-
-2002-11-19 Andreas Jaeger <aj@suse.de>
-
- * loop.c (record_giv): Initialize not_replaceable.
- (check_final_value): Likewise.
-
-2002-11-19 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (h8300_init_once): Replace 1 with
- MASK_H8300S.
-
-2002-11-19 Vijay L. Khuspe <vijayk1@kpit.com>
-
- * config/h8300/h8300.c (h8300_init_once): Allow -mn switch
- only if -mh or -ms present.
- (h8300_eightbit_constant_address_p): Support the normal mode.
- (h8300_tiny_constant_address_p): Likewise.
- * config/h8300/h8300.h (TARGET_NORMAL_MODE): New.
- (POINTER_SIZE): Add 16 bit pointer for the normal mode.
- (Pmode): Evaluate to HImode for the normal mode.
- (SIZE_TYPE): Evaluate to unsigned int for normal mode.
- (PTRDIFF_TYPE): Evaluate to int for the normal mode.
- (ASM_WORD_OP): Evaluate to word for the normal mode.
- * config/h8300/h8300.md (tablejump_normal_mode): New.
- (indirect_jump_normal_mode): New.
- * config/h8300/t-h8300 (MULTILIB_OPTIONS): Pass -mn option to
- directory.
- (MULTILIB_DIRNAMES): Create target dependent directory
- 'normal'.
- (MULTILIB_EXCEPTIONS): Don't turn on -mn on H8/300.
- * doc/invoke.texi (gccoptlist): Describe the new switch -mn.
-
-2002-11-19 Jan Hubicka <jh@suse.cz>
-
- * i386.md (length_immediate): Do not refer to insn address.
- (jcc*, jmp patterns): Compute length explicitly.
-
-2002-11-19 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR c/8588
- * optabs.c (expand_binop): Convert CONST_INTs in shift
- operations too.
-
-2002-11-19 Roger Sayle <roger@eyesopen.com>
-
- * gcse.c (gcse_emit_move_after): Correct typo in REG_EQUAL note.
-
-2002-11-19 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (an anonymous pattern): Relax the
- condition to accept the same operands and/or subregs.
-
-2002-11-19 Daniel Jacobowitz <drow@mvista.com>
-
- * config/sh/sh.c (gen_shl_and): Revert previous patch.
- * config/sh/sh.md (ashrdi3+1, ashrdi3+2): Predicate on
- reload_completed.
-
-2002-11-19 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (print_operand): Update the use of
- EIGHTBIT_CONSTANT_ADDRESS_P.
- (h8300_adjust_insn_length): Likewise.
- (h8300_eightbit_constant_address_p): Check if the given rtx is
- a variable with __attribute__((eightbit_data)).
- * config/h8300/h8300.h (OK_FOR_U): Update the use of
- EIGHTBIT_CONSTANT_ADDRESS_P.
-
-2002-11-19 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/contrib.texi (Contributors): Add self as second contact in
- addition to Jeff Law.
-
-2002-11-19 Andreas Jaeger <aj@suse.de>
-
- * tree-inline.c: Move prototpyes of find_alloca_call_1 and
- find_alloca_call to right place.
-
-2002-11-19 Kazu Hirata <kazu@cs.umass.edu>
-
- * cppfiles.c: Fix formatting.
-
-2002-11-19 Jason Thorpe <thorpej@wasabisystems.com>
-
- * gcc.c (The Specs Language): Document spec functions.
- (static_spec_functions, lookup_spec_function)
- (eval_spec_function, handle_spec_function)
- (if_exists_spec_function, alloc_args): New.
- (execute): Abort if processing_spec_function is true.
- (do_spec_1): Hand off spec to handle_spec_function if %:
- is encountered. If processing_spec_function is true,
- end any pending argument when the end of the string is reached.
- (main): Use alloc_args to allocate the initial argument vector.
- * gcc.h (struct spec_function): New.
- (lang_specific_spec_functions): New extern.
-
- * config/netbsd-elf.h (STARTFILE_SPEC): Add if-exists(crti%O%s).
- (ENDFILE_SPEC): Add if-exists(crtn%O%s).
- * config/alpha/netbsd.h (ENDFILE_SPEC): Likewise.
-
- * doc/invoke.texi: Document spec functions.
-
- * cppspec.c (lang_specific_spec_functions): New.
- * gccspec.c: Likewise.
-
-2002-11-18 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/hpux_longdouble.h (FIXUNS_TRUNCTFSI2_LIBCALL): New.
- (FIXUNS_TRUNCTFDI2_LIBCALL): New.
- (fixunstfsi_libfunc): Change.
- (fixunstfdi_libfunc): Change.
- (sdiv_optab): Don't zero out SImode handler.
- (udiv_optab): Don't zero out SImode handler.
- (smod_optab): Don't zero out SImode handler.
- (umod_optab): Don't zero out SImode handler.
-
-2002-11-18 Neil Booth <neil@daikokuya.co.uk>
-
- PR preprocessor/8524
- * cpplib.c (run_directive): Remove previous kludge to _Pragma.
- Add a new one in its place, which hopefully works.
- (skip_rest_of_line): Change test for bottom-of-context-stack.
-
-2002-11-18 Jan Hubicka <jh@suse.cz>
-
- * i386.md (addqi_1_slp): Fix output template.
- (subqi_1_slp): Fix type.
-
-2002-11-17 Jan Hubicka <jh@suse.cz>
-
- * calls.c (alloca_call_p): New global function.
- * tree.h (alloca_call_p): New.
- * tree-inline.c (inlinable_function_p): Do not inline when
- function calls alloca.
- (find_alloca_call, find_alloca_call_1): New functions.
-
-2002-11-18 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (*andorqi3): Use bor between bld and
- bst. Update the insn length.
- (*andorhi3): Likewise.
- (*andorsi3): Likewise.
-
-2002-11-18 Richard Sandiford <rsandifo@redhat.com>
-
- * config/sh/sh-protos.h (sh_mark_label): Declare.
- * config/sh/sh.c (sh_mark_label): New function, taken from
- movdi_const, but fixing the case when the address has an addend.
- * config/sh/sh.md (movdi_const, movdi_const_32bit): Use it.
-
-2002-11-18 Richard Sandiford <rsandifo@redhat.com>
-
- * config/sh/sh.c (pool_node): New field: part_of_sequence_p.
- (add_constant): Set it.
- (dump_table): Don't reorder a constant if part_of_sequence_p.
- (machine_dependent_reorg): Assume that float constants will
- stay in their original order if used as a sequence.
-
-2002-11-18 Richard Sandiford <rsandifo@redhat.com>
-
- * config/sh/sh.c (calc_live_regs): Update check for PIC liveness
- in compact code.
-
-2002-11-18 Richard Sandiford <rsandifo@redhat.com>
-
- * config/sh/sh.md (initialize_trampoline): Do not force the
- trampoline address into R0_REGS here.
-
-2002-11-17 Kazu Hirata <kazu@cs.umass.edu>
-
- * df.c: Fix formatting.
-
-2002-11-17 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (two anonymous patterns): Fix insn
- lengths.
-
-2002-11-17 Daniel Jacobowitz <drow@mvista.com>
-
- * sh.c (gen_shl_and): Don't create a zero_extend if the operand
- is not an arith_reg_operand.
-
-2002-11-17 Graham Stott <graham.stott@btinternet.com>
-
- * real.c (real_to_decimal): Fix buffer overrun when buffer size
- is smaller than representation.
-
-2002-11-17 Kazu Hirata <kazu@cs.umass.edu>
-
- * builtins.c: Fix formatting.
-
-2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (two anonymous patterns): Fix typos.
-
-2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md: Fix formatting.
-
-2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md: Replace spaces with tabs.
- * config/h8300/t-h8300: Remove a trailing empty line.
-
-2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
-
- * tlink.c: Fix formatting.
-
-2002-11-16 David Edelsohn <edelsohn@gnu.org>
-
- PR 8362
- * config/rs6000/rs6000.c (rs6000_outout_load_multiple): New function.
- * config/rs6000/rs6000.md (movti_string): Remove output modifier
- when scratch register never needed.
- (ldmsi[3-8]): New patterns.
-
-2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
-
- * hard-reg-set.h: Follow spelling conventions.
- * real.c: Likewise.
+ * Makefile.in: Suppress default .l.c rule. Don't substitute
+ parsedir and delete all references throughout. Conditionally define
+ rule for srcextra dependent on GENINSRC.
+ (stmp-docobjdir): Delete.
+ (c-parse.o, gengtype-lex.o, gengtype-yacc.o): Use implicit build rule.
+ (srcextra): Copy c-parse.y, c-parse.c, gengtype-lex.c, gengtype-yacc.c,
+ and gengtype-yacc.h back to source directory.
+ (maintainer-clean): Delete all parse files in source directory.
+ (distclean): Delete generated files.
+
+ * objc/Make-lang.in (objc-parse.o): Use implicit build rule.
+ (objc-parse.c, objc-parse.y): Don't use parsedir.
+ (objc.srcextra): Copy objc-parse.y and objc-parse.c back to source
+ directory if requested.
+ (po-generated): Don't use parsedir.
+ (objc.maintainer-clean): Delete above files from source directory.
+
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/tm.texi (FUNCTION_VALUE): Fix a typo.
+
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/tm.texi: Replace RETURN_IN_MEMORY with
+ TARGET_RETURN_IN_MEMORY.
+
+2004-01-15 Jan Hubicka <jh@suse.cz>
+
+ * builtins.c (std_expand_builtin_va_arg): Align operand when needed.
+ * i386.c (init_cumulative_args): Set warn_sse; fix handling of variadic
+ functions accepting SSE arguments
+ (function_arg): Warn only when asked to warn.
+ * i386.h (ix86_args): Add warn_sse/warn_mmx fiels.
+
+2004-01-14 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-parse.in (stmts_and_decls): Make label at end of compound
+ statement a hard error.
+
+2004-01-14 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (create_edge): Use local.redefined_extern_inline.
+ * cgraph.h (cgraph_local_info): Sort fields by size; add
+ redefined_extern_inline
+ (cgraph_global_info): Sort fields by size.
+ (cgraph_node): Likewise.
+ * cgraphunit.c (cgraph_finalize_function): Se
+ local.redefined_extern_inline on redefinition.
+ (cgraph_analyze_function): Use it; fix formating.
+
+2004-01-14 Jan Hubicka <jh@suse.cz>
+
+ PR c++/10776
+ * sched-deps.c (trye_dependency_cache, anti_dependency_cache,
+ outptu_dependency_cache, forward_dependency_cahe): Trun to vectors of
+ bitmaps
+ (cache_size): New variable
+ (add_dependence): Update use; canonize early memory locations
+ (sched_analyze_1): Likewise.
+ (sched_analyze_2): Likewise.
+ (init_dependency_caches): Initialize bitmaps.
+ (free_dependency_caches): Free bitmaps
+
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * calls.c: Replace STRICT_ARGUMENT_NAMING in comments with
+ targetm.calls.strict_argument_naming().
* target.h: Likewise.
-2002-11-16 Jakub Jelinek <jakub@redhat.com>
-
- * config/i386/x86-64.h (MCOUNT_NAME): Change into string literal.
-
-2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
-
- * optabs.c: Fix formatting.
-
-2002-11-16 Jan Hubicka <jh@suse.cz>
-
- * athlon.md, k6.md, pentium.md, ppro.md: Handle shift1, rotate1
- * i386.md (attribute type): Add type shift1 and rotate1.
- (*_slp): Rewrite to have just two operands to avoid reload problems.
-
-2002-11-15 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (4 anonymous patterns): New.
-
-2002-11-15 Geoffrey Keating <geoffk@apple.com>
-
- * params.def (GGC_MIN_HEAPSIZE): Fix GGC_ALWAYS_COLLECT problem.
- * doc/invoke.texi: Correct description of what needs to be done to
- force collection at every ggc_collect call.
-
-2002-11-15 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c (optimization_options): Set
- flag_asynchronous_unwind_tables to 1 by default.
-
-2002-11-15 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.h (ASM_PREFERRED_EH_DATA_FORMAT): Define.
-
-2002-11-15 Jan Hubicka <jh@suse.cz>
-
- * i386-protos.h (x86_function_profiler): New function
- * i386.h (MCOUNT_NAME): New.
- (PROFILE_COUNT_REGISTER): New.
- (FUNCTION_PROFILER): Move offline to ...
- * i386.c (x86_function_profiler) ... here; fix 64bit support
- * beos-elf.h (FUNCTION_PROFILER): Kill.
- (MCOUNT_NAME): New.
- * freebsd-aout.h (FUNCTION_PROFILER): Kill.
- (MCOUNT_NAME): New.
- (PROFILE_COUNT_REGISTER): New.
- * linux.h (FUNCTION_PROFILER): Kill.
- (MCOUNT_NAME): New.
- * x86-64.h (FUNCTION_PROFILER): Kill.
- (MCOUNT_NAME): New.
- * freebsd.h (FUNCTION_PROFILER): Kill.
- (MCOUNT_NAME): New.
-
-2002-11-14 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
-
- * config/arm/arm.h (EXPAND_BUILTIN_VA_ARG,
- FUNCTION_ARG_PASS_BY_REFERENCE): Define.
- * config/arm/arm.c (arm_va_arg,
- arm_function_arg_pass_by_reference): New.
- * config/arm/arm-protos.h: Add prototypes.
-
-2002-11-14 Kazu Hirata <kazu@cs.umass.edu>
-
- * gthr-single.h: Fix formatting.
-
-2002-11-14 Zack Weinberg <zack@codesourcery.com>
-
- * tree.c (tree_vec_elt_check_failed): New function.
- * tree.h (TREE_VEC_ELT_CHECK): New checking macro.
- (TREE_VEC_ELT): Use it.
-
- * tree-inline.c (optimize_inline_calls): Don't copy a
- zero-length vector.
-
-2002-11-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * diagnostic.c (sorry): Don't repeat "sorry, unimplemented" text.
-
-2002-11-14 Jakub Jelinek <jakub@redhat.com>
-
- * varasm.c (output_addressed_constants) [MINUS_EXPR]: Clear reloc if
- both operands contain local relocations.
- (categorize_decl_for_section): Don't use mergeable sections if
- initializer has any relocations.
-
-2002-11-14 Kazu Hirata <kazu@cs.umass.edu>
-
- * gthr-vxworks.h: Fix formatting.
-
-2002-11-13 Janis Johnson <janis187@us.ibm.com>
-
- * doc/install.texi (Testing): Document extra Java testing.
- * doc/sourcebuild.texi (Test Suites): Document libgcj testing.
-
-2002-11-13 John David Anglin <dave@hiauly1.hia.nrc.ca>
+2004-01-14 Richard Henderson <rth@redhat.com>
- * pa64-hpux.h (LINK_SPEC): Move "+Accept TypeMismatch" switch to the
- beginning of the spec.
- (LDD_SUFFIX, PARSE_LDD_OUTPUT): Delete.
- (LD_INIT_SWITCH, LD_FINI_SWITCH): Define but don't enable. Add comment
- regarding problems with global constructors when using GNU ld.
+ PR debug/13231
+ * dwarf2out.c (dwarf2out_stack_adjust): Skip prologue and epilogue
+ instructions.
-2002-11-13 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-14 Richard Henderson <rth@redhat.com>
- * gthr-solaris.h: Fix formatting.
+ PR c++/12491
+ * except.c (struct eh_region): Add u.fixup.resolved.
+ (resolve_one_fixup_region): Split out from ...
+ (resolve_fixup_regions): ... here.
-2002-11-13 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
- * gthr-posix.h: Fix formatting.
+ * config/mn10300/mn10300.h (STRUCT_VALUE): Change to 0.
-2002-11-12 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
- * config/h8300/h8300.md (*andorsi3): New.
+ * config/alpha/alpha.h (STRUCT_VALUE): Remove.
+ * config/alpha/vms.h (STRUCT_VALUE_REGNUM): Remove #undef.
+ (STRUCT_VALUE): Remove.
-2002-11-12 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+2003-01-14 Steven Bosscher <stevenb@suse.de>
- * doc/install.texi (powerpc-*-linux-gnu*): Update binutils requirement.
+ * system.h: Poison PROMOTED_MODE
+ * integrate.c (expand_inline_function): Don't mention the
+ PROMOTED_MODE.
+ * loop.c (update_giv_derive): Same.
+ * tree.h (DECL_RTL): Same.
-2002-11-12 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-14 J"orn Rennecke <joern.rennecke@superh.com>
- * config/h8300/h8300.c (tiny_constant_address_p): Parenthesize
- expressions appropriately.
+ PR target/9365
+ * sh.c (gen_block_redirect): Add special handling of RETURN.
+ (gen_far_branch) Don't call gen_stuff_delay_slot if there is no
+ far branch target (i.e. it's a return).
-2002-11-12 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
- * gthr-win32.h: Fix formatting.
+ * regrename.c (find_oldest_value_reg): Fix a warning.
-2002-11-12 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-14 Richard Earnshaw <rearnsha@arm.com>
- * config/h8300/h8300.c (single_one_operand): Correctly compute
- mask when mode is SImode.
- (single_zero_operand): Likewise.
- * config/h8300/h8300.md (two new anonymous insns): New.
+ PR bootstrap/12527
+ * config.gcc (arm*-*-linux*): Don't include unknown-elf.h in tm_file.
+ Move linux-gas.h and linux-elf.h before aout.h.
+ * arm/arm.h (INITIALIZE_TRAMPOLINE): Only define if not already.
+ * arm/linux-elf.h (SUBTARGET_CPU_DEFAULT): Define.
-2002-11-12 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+2004-01-14 Kazu Hirata <kazu@cs.umass.edu>
- * doc/contrib.texi (Contributors): Use GCJ instead of gcj to refer
- to that entire project.
+ * config/m32r/m32r.md: Use GEN_INT instead of gen_rtx
+ (CONST_INT, VOIDmode, ...).
-2002-11-12 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+2004-01-14 Richard Earnshaw <rearnsha@arm.com>
- * config/mips/t-iris6 (MULTILIB_OSDIRNAMES): Restore old
- directories.
+ * regrename.c (find_oldest_value_reg): If the replacement uses
+ multiple hard registers, check that all of them are in CLASS.
-2002-11-11 Zack Weinberg <zack@codesourcery.com>
+2004-01-14 Jan Hubicka <jh@suse.cz>
- * params.def (ggc-min-expand, ggc-min-heapsize): New parameters.
- * doc/invoke.texi: Document them.
+ * alias.c (get_alias_set): Initialize alias set to 0 when subset is
+ impossible.
- * ggc-page.c: Include params.h. Remove definitions of
- GGC_MIN_EXPAND_FOR_GC, GGC_MIN_LAST_ALLOCATED. Replace
- GGC_POISON with ENABLE_GC_CHECKING in ifdefs, delete #define.
- (init_gcc): Don't set G.allocated_last_gc here.
- (ggc_collect): Use PARAM_VALUE (GGC_MIN_HEAPSIZE) and
- PARAM_VALUE (GGC_MIN_EXPAND) to decide whether or not to
- perform collection.
- * ggc-simple.c: Similarly.
- * Makefile.in (ggc-common.o, ggc-simple.o): Add $(PARAMS_H) to
- dependencies.
+2004-01-14 Kelley Cook <kcook@gcc.gnu.org>
-2002-11-11 Kazu Hirata <kazu@cs.umass.edu>
+ * Makefile.in: Define MAINT from --enable-maintainer-mode.
- * gthr-dce.h: Fix formatting.
+2004-01-14 Hartmut Penner <hpenner@de.ibm.com>
-2002-11-11 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
-
- PR c/8467
- * stmt.c (tail_recursion_args): Handle DECL_MODE differing from the
- mode of DECL_RTL case.
-
-2002-11-11 Janis Johnson <janis187@us.ibm.com>
-
- * doc/contrib.texi: Merge in the list from the libstdc++ web pages.
-
-2002-11-11 Jan Hubicka <jh@suse.cz>
-
- * i386.c (construct_container): Fix handling of SSE_CLASS.
-
-2002-11-10 Joel Sherrill <joel@gcc.gnu.org>
-
- * config/m68k/t-crtstuff (crti.o): Use this...
- ($(T)crti.o): ... instead.
- (crtn.o): Use this...
- ($(T)crtn.o): ... instead.
-
-2002-11-10 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR c/8439
- * recog.c (validate_replace_rtx_1) [PLUS]: Simplify only
- if there is something new to be simplified.
-
-2002-11-10 H.J. Lu <hjl@gnu.org>
-
- * calls.c (PUSH_ARGS_REVERSED): Define only if not defined.
- * expr.c (PUSH_ARGS_REVERSED): Likewise.
-
- * config/i386/i386.h (PUSH_ARGS_REVERSED): Set to 1.
-
-2002-11-10 Zack Weinberg <zack@codesourcery.com>
-
- * config/rs6000/sysv4.h: Define NO_IMPLICIT_EXTERN_C here...
- * config/rs6000/linux.h, config/rs6000/linux64.h,
- config/rs6000/windiss.h: ... not here.
-
-2002-11-10 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/mips/netbsd.h (TARGET_OS_CPP_BUILTINS): Define
- __ABICALLS__ if TARGET_ABICALLS.
-
-2002-11-10 Jan Hubicka <jh@suse.cz>
-
- * i386.h (MIN_UNITS_PER_WORD): Define to 8 for x86-64 libgcc.
-
-2002-11-10 Joseph S. Myers <jsm@polyomino.org.uk>
-
- * c-decl.c (grokdeclarator): Make error for duplicate type
- qualifiers into a pedwarn, disabled for C99.
-
-2002-11-10 Hans-Peter Nilsson <hp@bitrange.com>
-
- * config/mmix/mmix.h (FUNCTION_ARG_CALLEE_COPIES): Define the same
- as FUNCTION_ARG_PASS_BY_REFERENCE.
-
-2002-11-09 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa.h (STARTING_FRAME_OFFSET): Change offset for TARGET_64BIT to 16.
-
- * config.gcc (hppa*64*-*-linux*): Shorten lines in tm_file define.
- (hppa*64*-*-hpux11*): Likewise. Use elfos.h with gas.
- * pa.c (output_millicode_call): Use symbol difference rather than
- $PIC_pcrel$0 when using HP assembler.
- * pa64-hpux.h (TARGET_GAS): Define to 1 or 0 depending on whether or
- not elfos.h (i.e., gas) is being used.
- (ASM_FILE_START, STRING_ASM_OP, TEXT_SECTION_ASM_OP,
- DATA_SECTION_ASM_OP, BSS_SECTION_ASM_OP, ASM_OUTPUT_ALIGNED_COMMON,
- ASM_OUTPUT_ALIGNED_LOCAL, GLOBAL_ASM_OP, ASM_DECLARE_FUNCTION_NAME,
- ASM_OUTPUT_EXTERNAL, ASM_OUTPUT_EXTERNAL_LIBCALL,
- ASM_OUTPUT_INTERNAL_LABEL, ASM_GENERATE_INTERNAL_LABEL): Define when
- using elfos.h.
- (TARGET_ASM_GLOBALIZE_LABEL): Undefine when using elfos.h.
- (DWARF2_ASM_LINE_DEBUG_INFO): Delete.
- (ASM_FILE_START): Add standard .SPACE and .SUBSPA defines when not
- using elfos.h.
- (TEXT_SECTION_ASM_OP, READONLY_DATA_SECTION_ASM_OP, DATA_SECTION_ASM_OP,
- BSS_SECTION_ASM_OP): New HP style defines when not using elfos.h.
- (TARGET_ASM_NAMED_SECTION, MAKE_DECL_ONE_ONLY, ASM_WEAKEN_LABEL):
- Don't define when not using elfos.h.
- (ASM_DECLARE_RESULT): Don't define.
- * doc/install.texi (hppa*-hp-hpux*): Remove statement that HP assembler
- doesn't work on hppa64-hp-hpux11.
- (hppa*-hp-hpux11): Update.
-
-2002-11-09 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/mips/netbsd.h (SUBTARGET_ASM_SPEC): Don't pass -KPIC
- to the assembler if -mno-abicalls was specified.
-
-2002-11-09 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa-linux.h (PREFERRED_DEBUGGING_TYPE, DWARF2_ASM_LINE_DEBUG_INFO,
- ASM_OUTPUT_DEF): Delete.
-
-2002-11-09 Neil Booth <neil@daikokuya.co.uk>
-
- * c-opts.c (COMMAND_LINE_OPTIONS): Fix -Wimplicit.
-
-2002-11-08 Dale Johannesen <dalej@apple.com>
-
- * dbxout.c (dbxout_type): Fix stabs info for vector types.
-
-2002-11-08 Neil Booth <neil@daikokuya.co.uk>
-
- PR preprocessor/8497
- PR preprocessor/8501
- * cpptrad.c (scan_out_logical_line): A '#' from a macro doesn't
- start a directive. In assembler, #NUM is not a line directive.
-
-2002-11-08 Neil Booth <neil@daikokuya.co.uk>
-
- * cppmain.c (cpp_preprocess_file): Loop to pop any -included
- buffers.
-
-2002-11-08 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (two anonymous test insns): New.
-
-2002-11-08 Jan Hubicka <jh@suse.cz>
-
- * jump.c (mark_jump_label): Handle subregs of label_refs.
-
-2002-11-07 David Mosberger <davidm@hpl.hp.com>
-
- * config/ia64/crtend.asm: Include "auto-host.h".
- [HAVE_INITFINI_ARRAY]: Invoke __do_global_ctors_aux via .init_array.
- * config/ia64/crtbegin.asm: Similarly.
- * config/ia64/t-ia64 (crtbegin.o): Include from current directory.
- (crtend.o, crtbeginS.o, crtendS.o): Likewise.
-
- * aclocal.m4 (gcc_AC_INITFINI_ARRAY): New.
- * configure.in: Use it if --enable-initfini-array not specified.
- * doc/install.texi (Configuration): Document --enable-initfini-array.
- * configure, config.in: Rebuild.
-
-2002-11-07 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/arm/arm-protos.h (arm_get_frame_size)
- (thumb_get_frame_size): New prototypes.
- * config/arm/arm.c (arm_get_frame_size)
- (thumb_get_frame_size): New functions.
- (use_return_insn, arm_output_epilogue, arm_output_function_epilogue)
- (arm_compute_initial_elimination_offset, arm_expand_prologue): Use
- arm_get_frame_size.
- (thumb_expand_prologue, thumb_expand_epilogue): Use
- thumb_get_frame_size.
- * config/arm/arm.h (PREFERRED_STACK_BOUNDARY): Define.
- (machine_function): Add frame_size member.
- (THUMB_INITIAL_ELIMINATION_OFFSET): Use thumb_get_frame_size.
-
-2002-11-07 Richard Earnshaw <rearnsha@arm.com>
-
- * arm.c (bit_count): Make argument unsigned long. Return unsigned.
- Adjust code to use portable unsigned bit manipulation.
- (insn_flags, tune_flags): Change type to unsigned.
- (struct processors): Make flags unsigned long.
- (arm_override_options): Change type of count and current_bit_count
- to unsigned.
-
-2002-11-07 Richard Earnshaw <rearnsha@arm.com>
-
- * arm/elf.h (TYPE_OPERAND_FMT): Prefix type with %.
-
-2002-11-07 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.h (DWARF_FRAME_RETURN_COLUMN): Use DWARF_FRAME_REGNUM.
-
-2002-11-07 Jan Hubicka <jh@suse.cz>
-
- * reg-stack.c (compensate_edge): Fix sanity check.
-
-2002-11-05 Geoffrey Keating <geoffk@apple.com>
-
- * config.gcc: Don't create crtbegin, crtend on Darwin; do create
- crt2.o. Rearrange t-darwin makefiles.
- * crtstuff.c [OBJECT_FORMAT_MACHO]: Delete.
- * unwind-dw2-fde-darwin.c: New.
- * unwind-dw2-fde-glibc.c: Correct comment.
- * unwind-dw2-fde.c (__register_frame_info_bases)
- [DWARF2_OBJECT_END_PTR_EXTENSION]: Clear fde_end.
- (classify_object_over_fdes): Use last_fde.
- (add_fdes): Likewise.
- (linear_search_fdes): Likewise.
- * unwind-dw2-fde.h (struct object)
- [DWARF2_OBJECT_END_PTR_EXTENSION]: Add fde_end field.
- (last_fde): New.
- * config/darwin.h (STARTFILE_SPEC): Include crt2.o not crtbegin.o.
- (ENDFILE_SPEC): No crtend.o.
- * config/t-darwin: New.
- * config/i386/t-darwin: Delete.
- * config/darwin-crt2.c: New.
- * config/rs6000/t-darwin: Delete contents duplicated in t-rs6000
- or config/t-darwin.
-
-2002-11-06 David Edelsohn <edelsohn@gnu.org>
-
- PR target/8480
- * config/rs6000/rs6000.md (movdi_internal64): Discourage
- FPR to FPR moves.
-
-2002-11-06 Janis Johnson <janis187@us.ibm.com>
-
- * doc/contrib.texi: Merge in the list from the Java web pages.
-
-2002-11-06 David O'Brien <obrien@FreeBSD.org>
-
- * config/sparc/freebsd: Fix typo.
-
-2002-11-06 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa64-hpux.h (LDD_SUFFIX, PARSE_LDD_OUTPUT): Define.
-
-2002-11-06 Alexandre Oliva <aoliva@redhat.com>
-
- * config/mips/mips.md (call_value_multiple_internal2): Use dla for
- non-SImode addresses.
-
-2002-11-05 Bob Wilson <bob.wilson@acm.org>
-
- * config/xtensa/elf.h (LIB_SPEC): Add "-lhal".
-
-2002-11-05 John David Anglin <dave2hiauly1.hia.nrc.ca>
-
- * pa64-hpux.h (LIB_SPEC): Fix p and pg options.
- (STARTFILE_SPEC): Remove p and pg options.
-
-2002-11-05 Andrew Haley <aph@redhat.com>
-
- * fold-const.c (fold): Don't transform (a0 op compound(a1,a2))
- to (compound(a1,a0 op a2)) if a0 or a1 have side effects.
-
-2002-11-05 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.h (CANNOT_CHANGE_MODE_CLASS): Move comment to...
- * config/mips/mips.c (mips_cannot_change_mode_class): ...here.
-
-2002-11-04 Dale Johannesen <dalej@apple.com>
-
- * doloop.c (doloop_modify_runtime): Fix loop count computation
- for unrolled loops.
- * loop.c (loop_invariant_p): Support calling from unroller.
-
-2002-11-04 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c (s390_decompose_address): Use arg_pointer_rtx
- for comparison.
-
-2002-11-04 Aldy Hernandez <aldyh@redhat.com>
-
- * hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): New.
-
- * config/rs6000/rs6000.h (CLASS_CANNOT_CHANGE_MODE_P): Remove.
- (CLASS_CANNOT_CHANGE_MODE): Remove.
- (CANNOT_CHANGE_MODE_CLASS): New.
-
- * config/alpha/alpha.h: Same.
-
- * config/ia64/ia64.h: Same.
-
- * config/mips/mips.h: Same.
-
- * config/s390/s390.h: Same.
-
- * config/sh/sh.h: Same.
-
- * config/pa/pa64-regs.h: Same.
-
- * config/sh/sh-protos.h (sh_cannot_change_mode_class): Add prototype.
-
- * config/sh/sh.c (sh_cannot_change_mode_class): New.
-
- * config/mips/mips-protos.h (mips_cannot_change_mode_class): Add
- prototype.
-
- * config/mips/mips.c (mips_cannot_change_mode_class): New.
-
- * doc/tm.texi (Register Classes): Remove
- CLASS_CANNOT_CHANGE_MODE and CLASS_CANNOT_CHANGE_MODE_P.
- Document CANNOT_CHANGE_MODE_CLASS.
-
- * reload.c (push_reload): Use CANNOT_CHANGE_MODE_CLASS.
- (push_reload): Same.
-
- * simplify-rtx.c (simplify_subreg): Same.
-
- * reload1.c (choose_reload_regs): Same.
-
- * recog.c (register_operand): Same.
-
- * regrename.c (mode_change_ok): Change to use new
- CANNOT_CHANGE_MODE_CLASS infrastructure.
-
- * regclass.c (cannot_change_mode_set_regs): New.
- Declare subregs_of_mode.
- (regclass): Use subregs_of_mode.
- Remove references to reg_changes_mode.
- (init_reg_sets_1): Remove class_can_change_mode and
- reg_changes_mode code.
- (invalid_mode_change_p): New.
- (dump_regclass): Use invalid_mode_change_p instead of
- class_can_change_mode.
- (regclass): Same.
- (record_operand_costs): Do not set reg_changes_mode.
-
- * local-alloc.c (struct qty): Remove changes_mode field.
- (alloc_qty): Remove changes_mode initialization.
- (update_qty_class): Remove set of changes_mode.
- (find_free_reg): Use subregs_of_mode.
-
- * global.c (find_reg): Use subregs_of_mode info.
-
- * rtl.h (cannot_change_mode_set_regs): New prototype.
- (invalid_mode_change_p): Same.
- (REG_CANNOT_CHANGE_MODE_P): New macro.
-
- * flow.c (mark_used_regs): Calculate subregs_of_mode. Remove
- REG_CHANGES_MODE.
- (life_analysis): Clear subregs_of_mode.
-
- * combine.c (subst): Pass class to CLASS_CANNOT_CHANGE_MODE_P.
- Remove use of CLASS_CANNOT_CHANGE_MODE.
- (simplify_set): Same.
- (gen_lowpart_for_combine): Calculate subregs_of_mode. Remove
- REG_CHANGES_MODE.
-
- * regs.h: Add extern for subregs_of_mode;
- Include hard-reg-set and basic-block.
- (REG_CHANGES_MODE): Delete.
-
-2002-11-03 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * jump.c (never_reached_warning): Don't set contains_insn until the
- first line note is seen.
-
-2002-11-03 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.md (movti_string): Use string instructions.
-
-2002-11-03 Roger Sayle <roger@eyesopen.com>
-
- PR c/7128
- * c-typeck.c (c_expand_asm_operands): Defend against
- error_mark_nodes in the output argument to avoid ICE.
-
-2002-11-03 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- PR middle-end/8408
- * genrecog.c (preds): Handle ADDRESSOF.
- (validate_pattern): Mark it as an lvalue.
-
-2002-11-02 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.c (rs6000_override_options): Use string
- instructions when optimizing for size.
-
-2002-11-02 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.h: Fix comment typos.
- * config/h8300/h8300.md: Likewise.
- * config/h8300/lib1funcs.asm: Likewise.
-
-2002-11-02 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- Revert this change:
-
- *doc/install.texi (Installing GCC: Configuration): Clarify
- the only supported ways to configure gcc.
-
-2002-11-01 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (anonymous and:QI pattern): Use 'n'
- instead of 'O' for the constraint for the second operand.
-
-2002-11-01 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/8391
- * toplev.c (rest_of_compilation): Do not refuse to output code for
- an inline function in a local class.
-
-2002-11-01 David O'Brien <obrien@FreeBSD.org>
-
- * config/sparc/freebsd.h (CPP_CPU64_DEFAULT_SPEC): Define __arch64__.
- (TRANSFER_FROM_TRAMPOLINE): Reformat.
- Add comment.
-
-2002-11-01 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.h (CAN_ELIMINATE): Simplify.
-
-2002-11-01 Toshiyasu Morita <toshiyasu.morita@hsa.hitachi.com>
-
- * config/h8300/h8300.h (OPTIMIZATION_OPTIONS): New.
-
-2002-11-01 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/ia64.h (MASK_INLINE_DIV_LAT): Remove.
- (MASK_INLINE_DIV_THR): Remove.
- (TARGET_INLINE_DIV_LAT): Remove.
- (TARGET_INLINE_DIV_THR): Remove.
- (TARGET_INLINE_DIV): Remove.
- (MASK_INLINE_FLOAT_DIV_LAT): New macro.
- (MASK_INLINE_FLOAT_DIV_THR): New macro.
- (MASK_INLINE_INT_DIV_LAT): New macro.
- (MASK_INLINE_INT_DIV_THR): New macro.
- (TARGET_INLINE_FLOAT_DIV_LAT): New macro.
- (TARGET_INLINE_FLOAT_DIV_THR): New macro.
- (TARGET_INLINE_INT_DIV_LAT): New macro.
- (TARGET_INLINE_INT_DIV_THR): New macro.
- (TARGET_INLINE_FLOAT_DIV): New macro.
- (TARGET_INLINE_INT_DIV): New macro.
- * config/ia64/ia64.md (divsi3): Change to use new macros.
- (modsi3): Ditto.
- (udivsi3): Ditto.
- (umodsi3): Ditto.
- (divsi3_internal): Ditto.
- (divdi3): Ditto.
- (moddi3): Ditto.
- (udivdi3): Ditto.
- (umoddi3): Ditto.
- (divdi3_internal_lat): Ditto.
- (divdi3_internal_thr): Ditto.
- (divsf3): Ditto.
- (divsf3_internal_lat): Ditto.
- (divsf3_internal_thr): Ditto.
- (divdf3): Ditto.
- (divdf3_internal_lat): Ditto.
- (divdf3_internal_thr): Ditto.
- (divtf3): Ditto.
- (divtf3_internal_lat): Ditto.
- (divtf3_internal_thr): Ditto.
- * config/ia64/ia64.c (ia64_override_options): Change
- to check new macros for conflicts in settings.
- * doc/invoke.texi (-minline-divide-min-latency): Remove.
- (-minline-divide-max-throughput): Remove.
- (-minline-float-divide-min-latency): New.
- (-minline-float-divide-max-throughput): New.
- (-minline-int-divide-min-latency): New.
- (-minline-int-divide-max-throughput): New.
-
-2002-11-01 Richard Earnshaw (rearnsha@arm.com)
-
- PR target/7856
- * arm.c (use_return_insn): Don't use a return insn if there are
- saved integer regs, but LR is not one of them.
-
-2002-11-01 Jan Hubicka <jh@suse.cz>
-
- * expr.c (emit_move_insn): Use SCALAR_FLOAT_MODE_P
- * machmode.h (SCALAR_FLOAT_MODE_P): New macro.
-
-2002-10-31 Nathanael Nerode <neroden@gcc.gnu.org>
-
- PR optimization/6162
- * doc/md.texi: Document restriction on commutative operand
- specification.
-
-2002-10-31 Eric Christopher <echristo@redhat.com>
-
- * explow.c (convert_memory_address): Use shallow_copy_rtx.
-
-2002-10-31 Steve Ellcey <sje@cup.hp.com>
-
- * expmed.c (store_bit_field): Check FUNCTION_ARG_REG_LITTLE_ENDIAN.
-
-2002-10-31 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/hpux.h (MEMBER_TYPE_FORCES_BLK): Set for non-floats.
-
-Thu Oct 31 Dale Johannesen <dalej@apple.com>
-
- * config/rs6000/darwin.h: Correct formatting in previous.
-
-Thu Oct 31 Dale Johannesen <dalej@apple.com>
-
- * config/rs6000/darwin.h: Enable -falign-xxx options.
-
-2002-10-31 Jan Hubicka <jh@suse.cz>
-
- * i386.c (override_options): Set defaults for flag_omit_frame_pointer,
- flag_asynchronous_unwind_tables, flag_pcc_struct_return.
- * i386.c (optimization_options): Set flag_omit_frame_pointer,
- flag_asynchronous_unwind_tables, flag_pcc_struct_return to 2.
- Do not clear -momit-leaf-frame-pointer when profiling.
- (ix86_frame_pointer_required): Frame pointer is always required when
- profiling.
-
-2002-10-31 Jan Hubicka <jh@suse.cz>
-
- * i386.md (negdf2_ifs_rex64): Don't allow GPR operand.
-
-2002-10-31 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.h (binary_logical_operator): Declare.
- * sh.c (binary_logical_operator): New function.
- * sh.md (xordi3+1): New combiner splitter pattern.
-
-2002-10-31 David O'Brien <obrien@FreeBSD.org>
-
- * config/sparc/freebsd.h (TRANSFER_FROM_TRAMPOLINE): Define
- __enable_execute_stack function.
-
-2002-10-30 Aldy Hernandez <aldyh@redhat.com>
-
- * c-common.c: Add GTY to vector_type_node_list.
-
-2002-10-30 John David Anglin <dave@hiauly.hia.nrc.ca>
-
- * pa-linux.h (ASM_OUTPUT_EXTERNAL_LIBCALL): Define.
- * pa-protos.h (attr_length_millicode_call, attr_length_call,
- pa_init_machine_status): Declare new global functions.
- * pa.c (void copy_fp_args, length_fp_args, get_plabel): Declare and
- implement new functions.
- (attr_length_millicode_call, attr_length_call): Implement.
- (total_code_bytes): Change type to long.
- (pa_output_function_prologue): Compute total_code_bytes on TARGET_64BIT.
- Reset counter if flag_function_sections.
- (output_deferred_plabels): Set output alignment to 3 for TARGET_64BIT.
- (output_cbranch): Move call to gen_label_rtx.
- (output_millicode_call): Rewrite adding long TARGET_64BIT call, expose
- delay slot in all variants, shorten pc-relative calls.
- (output_call): Rewrite adding long TARGET_64BIT call, improved delay
- slot usage and exposure, various new call variants, and shortened
- sequences for some variants on TARGET_PA_20.
- Miscellaneous format changes.
- * pa.h (total_code_bytes): Change type to long.
- (MASK_LONG_CALLS, TARGET_LONG_CALLS, TARGET_LONG_ABS_CALL,
- TARGET_LONG_PIC_SDIFF_CALL, TARGET_LONG_PIC_PCREL_CALL): Define.
- (TARGET_SWITCHES): Add "-mlong-calls" and "-mno-long-calls" options.
- (EXTRA_CONSTRAINT, GO_IF_LEGITIMATE_ADDRESS,
- LEGITIMIZE_RELOAD_ADDRESS): Don't use long floating point loads and
- stores on TARGET_ELF32.
- *pa.md (define_delay): Allow insns in delay on TARGET_PORTABLE_RUNTIME.
- (unnamed patterns for mulsi3, divsi3, udivsi3, modsi3, umodsi3 and
- canonicalize_funcptr_for_compare expanders): Calculate attribute length
- attr_length_millicode_call().
- (call_internal_symref, call_value_internal_symref): Clobber register 1.
- Calculate attribute length using attr_length_call().
- (call_internal_reg_64bit, call_value_internal_reg_64bit): Move gp load
- to delay slot.
- (sibcall, sibcall_value): Rewrite.
- (sibcall_internal_symref, sibcall_value_internal_symref): Clobber
- register 1. Use attr_length_call().
- (sibcall_internal_symref_64bit, sibcall_value_internal_symref_64bit):
- New patterns.
- (unamed pattern for canonicalize_funcptr_for_compare): Rewrite.
- * som.h (MEMBER_TYPE_FORCES_BLK): Define.
- * t-pa64 (TARGET_LIBGCC2_CFLAGS): Add "-mlong-calls".
- * doc/invoke.texi (mlong-calls): Document.
-
-2002-10-30 Roger Sayle <roger@eyesopen.com>
-
- * fold-const.c (fold_binary_op_with_conditional_arg): Improve
- handling of cases where one or both branches of the conditional
- have void type, i.e. throw an exception or don't return.
- (fold): Only apply (and undo) type conversion to the non-void
- branches of a COND_EXPR.
-
-2002-10-30 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/8333
- * varasm.c (asm_output_aligned_bss): Do not call
- ASM_GLOBALIZE_LABEL.
+ * gcc/config/rs6000/rs6000.c (rs6000_stack_info)
+ Calculate always vrsave_mask if TARGET_ALTIVEC.
+ (rs6000_emit_prologue): Emit code for vrsave
+ only if TARGET_ALTIVEC_VRSAVE.
+ (rs6000_emit_epilogue): Likewise.
-2002-10-30 David Edelsohn <edelsohn@gnu.org>
- Torbjorn Granlund <tege@swox.com>
+2004-01-14 Eric Botcazou <ebotcazou@libertysurf.fr>
- * config/rs6000/rs6000.md (load_toc_v4_PIC_1): Use preferred form
- for addressibility.
- (load_toc_v4_PIC_1b): Same.
+ * config/sparc/sparc.md (tie_add32): Fix pasto.
+ (tie_add64): Likewise.
-2002-10-30 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-14 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
- * config/h8300/h8300.c (h8300_eightbit_constant_address_p):
- Truncate the addresses for H8/300 using HImode.
+ * config/i386/i386.md (*addqi_1_slp): Do not access operands[2].
-2002-10-29 Hans-Peter Nilsson <hp@bitrange.com>
+2004-01-13 Kazu Hirata <kazu@cs.umass.edu>
- * toplev.c (rest_of_type_compilation): Return early in case of
- errors.
- (check_global_declarations): Don't call debug_hooks->global_decl
- in case of errors.
+ * config/iq2000/iq2000-protos.h: Fix comment formatting.
+ * config/iq2000/iq2000.c: Likewise.
+ * config/iq2000/iq2000.md: Likewise.
-2002-10-28 Andreas Bauer <baueran@in.tum.de>
+2004-01-14 J. Brobecker <brobecker@gnat.com>
- * doc/c-tree.texi (Tree overview): Fix typos.
+ * dwarf2out.c (is_ada_subrange_type): No longer check the TYPE_NAME.
+ (subrange_type_die): Add handle for nameless subrange types.
-2002-10-29 Phil Edwards <pme@gcc.gnu.org>
+2004-01-13 Kazu Hirata <kazu@cs.umass.edu>
- * Makefile.in (gnucompare*): Only record bad comparisons
- if there really was a bad comparison.
+ * config/h8300/h8300-protos.h: Replace do_movsi with
+ h8300_expand_movsi.
+ * config/h8300/h8300.c (do_movsi): Change to
+ h8300_expand_movsi.
+ * config/h8300/h8300.md (movsi): Replace do_movsi with
+ h8300_expand_movsi.
+ (movsf): Likewise.
-2002-10-29 Jan Hubicka <jh@suse.cz>
+2004-01-13 Kazu Hirata <kazu@cs.umass.edu>
- * i386.h (CONST_DOUBLE_OK_FOR_LETTER_P): Remove 'H'
- * i386.md (movsf*, movdf*): Use 'C' instead of 'H'
- * md.texi (machine dependent constraints): Document 'C'
+ * config/h8300/h8300.c (dosize): Change to
+ h8300_emit_stack_adjustment. Update callers.
- * simplify-rtx.c (simplify_subreg): Fix const_int->vector subregging.
+2004-01-13 Kazu Hirata <kazu@cs.umass.edu>
- * i386.c (ix86_expand_vector_move): Fix.
+ * config/h8300/h8300.md (movstrictqi): Add an alternative with
+ the source being post_inc. Tighten the predicate for the
+ destination to register_operand.
+ (movstricthi): Likewise.
- * i386.c (ix86_expand_builtin): Use sse2_maskmovdqu_rex64.
- * i386.md (sse2_maskmovdqu_rex64): New pattern
+2004-01-13 Kazu Hirata <kazu@cs.umass.edu>
- PR target/8322
- * xmmintrin.h (_mm_stream_pi, _mm_stream_pd): Fix cast.
- (ix86_init_mmx_sse_builtins): Fix type.
+ * system.h (SHARED_BSS_SECTION_ASM_OP): Poison.
+ * varasm.c (bss_section): Don't use SHARED_BSS_SECTION_ASM_OP.
+ * doc/tm.texi (SHARED_BSS_SECTION_ASM_OP): Remove.
-2002-10-29 Jason Thorpe <thorpej@wasabisystems.com>
+2004-01-14 Jan Hubicka <jh@suse.cz>
- * gthr-posix.h: Include <unistd.h> for feature tests.
- (sched_get_priority_max, sched_get_priority_min)
- (pthread_getschedparam, pthread_setschedparam): Only use
- if _POSIX_THREAD_PRIORITY_SCHEDULING is defined.
- (__gthread_objc_thread_set_priority): Don't treat all non-zero
- returns from sched_get_priority_max and sched_get_priority_min
- as an error.
+ Partial fix PR c++/12850
+ * cgraphunit.c (cgraph_finalize_function): Always ggc_collect when
+ at zero nest level.
-2002-10-29 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-13 Bernardo Innocenti <bernie@develer.com>
- * config/h8300/h8300.h (TARGET_DEFAULT): Make it
- MASK_QUICKCALL.
+ * config/m68k/netbsd-elf.h (REGISTER_NAMES): Add missing "argptr"
+ pseudo-register.
-2002-10-29 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-13 Devang Patel <dpatel@apple.com
- * config/h8300/h8300.c (h8300_eightbit_constant_address_p): New.
- (h8300_tiny_constant_address_p): Likewise.
- * config/h8300/h8300.h (EIGHTBIT_CONSTANT_ADDRESS_P): Use
- h8300_eightbit_constant_address_p.
- (TINY_CONSTANT_ADDRESS_P): Use h8300_tiny_constant_address_p.
- * config/h8300/h8300-protos.h: Add the prototypes for the two
- new functions.
+ PR debug/7078
+ * dbxout.c (dbxout_symbol_name): Emit mangled names for
+ NAMESPACE_DECL memebers.
-2002-10-29 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-13 Andrew Pinski <pinskia@physics.uc.edu>
- * reload1.c (update_eliminables): Unconditionally check if
- frame_pointer_needed has changed.
+ PR c++/12709
+ * c-common.c (finish_fname_decls): Use the chain only if the
+ tree is an expr_stmt.
-2002-10-29 Jan Hubicka <jh@suse.cz>
+2004-01-13 Vladimir Makarov <vmakarov@redhat.com>
- * toplev.c (rest_of_compilation): Reorganize way reg_scan is called
- before final pass.
+ * rtl.def: Add comment about new option in automata_option.
-2002-10-29 Eric Botcazou <ebotcazou@libertysurf.fr>
+ * genautomata.c (PROGRESS_OPTION): New macro.
+ (progress_flag): New global variable.
+ (gen_automata_option): Process `progress'.
+ (transform_insn_regexps, check_unit_distributions_to_automata,
+ make_automaton, NDFA_to_DFA, build_automaton, create_automata,
+ expand_automata, write_automata): Print about the progress only if
+ progress_flag. Remove fflush.
+ (initiate_automaton_gen): Process command line flag `-progress'.
- PR optimization/8334
- * expr.c (expand_expr) [PLUS]: Don't use simplify_binary_operation;
- check for zero operands explicitly.
+ * doc/md.texi: Describe the new option.
-2002-10-29 Richard Sandiford <rsandifo@redhat.com>
+2004-01-13 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
- * config/mips/mips.md (extv, extzv, insv): Set size of referenced
- memory after adjusting to BLKmode.
+ * cfg.c (dump_bb): Dump entry edges.
-2002-10-29 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-13 Richard Earnshaw <rearnsha@arm.com>
- * config/h8300/h8300.h (MASK_*): New.
- (TARGET_*): Use MASK_*.
+ * arm.c (thumb_legitimate_address_p): Only allow constant pool
+ references from SImode.
+ * arm.md (thumb_movhi_insn): Don't allow minipool references.
-2002-10-28 Jason Thorpe <thorpej@wasabisystems.com>
+2004-01-13 Kazu Hirata <kazu@cs.umass.edu>
- * config.gcc (*-*-netbsd*): Add NETBSD_ENABLE_PTHREADS to
- tm_defines if pthreads are enabled.
- * config/netbsd.h (LIB_SPEC): Only support the -pthread option
- if NETBSD_ENABLE_PTHREADS is defined.
+ * system.h (TEXT_SECTION): Poison.
+ * varasm.c (text_section): Don't use TEXT_SECTION.
+ * config/sh/sh.c (sh_file_start): Fix a comment typo.
+ * doc/tm.texi (TEXT_SECTION): Remove.
-2002-10-28 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-13 Ben Elliston <bje@wasabisystems.com>
- * ChangeLog.1: Fix typos.
- * cse.c: Fix a comment typo.
- * reload1.c: Likewise.
+ * doc/rtl.texi (Vector Operations): Remove defunct vec_const item.
-2002-10-27 Hans-Peter Nilsson <hp@bitrange.com>
+2004-01-12 James E Wilson <wilson@specifixinc.com>
- * fixinc/inclhack.def (libc1_G_va_list): Correct test_text.
- * fixinc/tests/base/_G_config.h: New file.
+ * unwind-libunwind.c: Delete.
-2002-10-27 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-12 Zack Weinberg <zack@codesourcery.com>
- * combine.c: Fix comment formatting.
- * loop.c: Likewise.
- * real.c: Likewise.
- * regclass.c: Likewise.
- * regmove.c: Likewise.
- * regrename.c: Likewise.
- * reg-stack.c: Likewise.
- * reload1.c: Likewise.
- * reload.c: Likewise.
- * reload.h: Likewise.
- * unroll.c: Likewise.
+ PR 13656
+ * c-decl.c (diagnose_mismatched_decls): Whenever newtype or
+ oldtype is set, set *newtypep or *oldtypep too. Do not set
+ them at the very end.
+ (validate_proto_after_old_defn): Restructure for comprehensibility;
+ make error messages clearer.
-2002-10-27 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-12 Zack Weinberg <zack@codesourcery.com>
- * reload1.c (reload): Fix a comment typo.
+ * varray.h (VARRAY_POP): Add checking variant, aborts on underflow.
+ (VARRAY_TOP): Use VARRAY_CHECK so the access is bounds-checked.
+ * varray.c: No need to prototype error.
+ (varray_check_failed): Wrap long string onto two lines.
+ (varray_underflow): New function.
-2002-10-27 Jan Hubicka <jh@suse.cz>
+2004-01-13 Steven Bosscher <stevenb@suse.de>
- * linux64.h (DEFAULT_PCC_STRUCT_RETURN): Define.
-
-2002-10-27 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
-
- * Makefile.in (dwarf2out.o): Add dependendcy on hashtab.h.
- * dwarf2out.c: Include hashtab.h.
- (is_main_source): New static variable.
- (attr_checksum, die_checksum): Modified to handle die references.
- (same_loc_p, same_dw_val_p, same_attr_p, same_die_p, same_die_p_wrap,
- unmark_all_dies, htab_cu_hash, htab_cu_eq, htab_cu_del, check_duplicate_cu,
- record_comdat_symbol_number): New static functions.
- (output_comp_unit, compute_section_prefix, is_type_die, break_out_includes,
- mark_dies, unmark_dies, dwarf2out_start_source_file): Modified.
- * toplev.c (rest_of_decl_compilation): Call of dwarf2out_decl for type
- declarations added.
-
-2002-10-26 Kazu Hirata <kazu@cs.umass.edu>
+ PR c++/13376
+ * function.h (struct function): Kill `name' field.
+ (current_function_name): Make it an extern function.
+ * function.c (current_function_name): New function.
+ * graph.c: Update all uses of current_function_name.
+ * gcse.c: Likewise.
+ * config/alpha/alpha.c, config/avr/avr.c, config/c4x/c4x.c,
+ config/mips/mips.c, config/pdp11/pdp11.c: Likewise.
+ * config/ip2k/ip2k.c (function_prologue): Use MAIN_NAME_P
+ instead of a strcmp with "main".
- * config/h8300/h8300.c (initial_offset): Change to
- h8300_initial_elimination_offset.
- * config/h8300/h8300.h (INITIAL_ELIMINATION_OFFSET): Use
- h8300_initial_elimination_offset.
- * config/h8300/h8300-protos.h: Update the prototype.
+2004-01-13 Jan Hubicka <jh@suse.cz>
-2002-10-26 Hans-Peter Nilsson <hp@bitrange.com>
+ * c-decl.c (diagnose_mismatched_decls): Fix warning calls.
- * config/mmix/mmix.h (LIBCALL_VALUE): Use
- MMIX_RETURN_VALUE_REGNUM, not MMIX_OUTGOING_RETURN_VALUE_REGNUM.
- (FUNCTION_VALUE_REGNO_P): Similar, but move code to...
- * config/mmix/mmix.c (mmix_function_value_regno_p): New.
- * config/mmix/mmix-protos.h: Remove needless ifdefs on TREE_CODE
- and RTX_CODE.
- (mmix_function_value_regno_p): Declare.
+ * cgraphunit.c (cgraph_optimize_function): Always do
+ optimize_inline_calls when there is always_inline callee.
+ (cgraph_decide_inlining): Fix formating.
+ * tree-inline.c (inlinable_function_p): Do sorry for alwaysinline
+ functions.
+ (expand_call_inline): Likewise.
+ * toplev.h (sorry): Fix prototype.
- * config/mmix/mmix.md ("fixuns_truncdfdi2"): Replace unsigned_fix,
- invalid for floating point mode result, with fix.
+2004-01-12 Roger Sayle <roger@eyesopen.com>
-2002-10-25 Mike Stump <mrs@apple.com>
+ * builtins.c (expand_builtin_expect_jump): Simplify logic. Handle
+ conditional jumps that drop through to unconditional jumps or the
+ end of the sequence.
- Fixes gcc.dg/warn-1.c.
- * c-typeck.c (warn_for_assignment): Don't print argument number, if zero.
+2004-01-13 Jan Hubicka <jh@suse.cz>
-2002-10-26 Jan Hubicka <jh@suse.cz>
+ * alias.c (new_alias_set): Construct the alias_set varray.
+ (init_alias_once): Don't do it here.
- * toplev.c (dump_file_index): Add DFI_ce3.
- (dump_file_info): Likewise.
- (rest_of_compilation): Run first ifcvt pass before tracer.
+2004-01-12 Marc Espie <espie@openbsd.org>
-2002-10-25 Steve Ellcey <sje@cup.hp.com>
+ * system.h: handle YYBYACC like YYBISON.
- * config/ia64/hpux.h (BITS_BIG_ENDIAN): Remove.
+2004-01-12 Jonathan Merriman <jonm@dualitymedia.com>
-2002-10-25 Richard Henderson <rth@redhat.com>
+ PR target/10847
+ * config.gcc: No longer includes conflicting header sparc/sol2.h when
+ building on sparc64-*-openbsd*.
- * real.c (real_to_decimal): If the >1 tens reduction loop results
- in a negative exponent, fall into the <1 pten computation.
+2004-01-12 Andrew Pinski <pinskia@physics.uc.edu>
-2002-10-25 Zack Weinberg <zack@codesourcery.com>
+ PR debug/13539
+ * dbxout.c (dbxout_type): Protected inheritance is not
+ private but protected.
- PR middle-end/6994
- * c-objc-common.c (inline_forbidden_p): Can not inline
- functions containing structures or unions containing VLAs.
- * tree-inline.c (walk_tree): For all class 't' nodes, walk
- TYPE_SIZE and TYPE_SIZE_UNIT.
- (copy_tree_r): Copy types if they are variably modified.
+2004-01-12 Richard Sandiford <rsandifo@redhat.com>
-2002-10-25 Ulrich Weigand <uweigand@de.ibm.com>
+ * config/mips/mips.c (mips_symbolic_constant_p): Revert last patch.
- * config/s390/s390.md: Remove old-style peepholes.
+2004-01-12 Kazu Hirata <kazu@cs.umass.edu>
-2002-10-25 Ulrich Weigand <uweigand@de.ibm.com>
+ PR optimization/12508.
+ * combine.c (try_combine): Remove a dead set in a parallel
+ even if its destination is a subreg.
- * config/s390/s390.c (s390_decompose_address): Do not range check the
- displacement if base or index is the argument pointer register.
+ Revert:
+ 2003-06-03 Kazu Hirata <kazu@cs.umass.edu>
+ * combine.c (simplify_set): Don't move a subreg in SET_SRC to
+ SET_DEST if WORD_REGISTER_OPERATIONS is not defined.
-2002-10-24 Hans-Peter Nilsson <hp@bitrange.com>
+2004-01-12 Geoffrey Keating <geoffk@apple.com>
- PR other/3337
- PR bootstrap/6763
- PR bootstrap/8122
- * fixinc/inclhack.def (libc1_G_va_list): New fix.
- * fixinc/fixincl.x: Regenerate.
- * config/i386/linux.h: Move MD_FALLBACK_FRAME_STATE_FOR inside
- ifndef IN_LIBGCC2. Wrap it together with signal.h and
- sys/ucontext.h inclusion in ifndef USE_GNULIBC_1.
- * configure.in (gcc_AC_CHECK_DECLS): Check vasprintf too.
- * config.in, configure: Regenerate.
+ * real.c: Update copyright date.
+ * emit-rtl.c: Likewise.
+ * rtl.h: Likewise.
+ * dwarf2out.c: Likewise.
+ * config/rs6000/darwin-ldouble.c: Likewise.
+ * config/rs6000/rs6000.md: Likewise.
-2002-10-24 Igor Shevlyakov <igor@microunity.com>
+2004-01-12 David Edelsohn <edelsohn@gnu.org>
- * varasm.c (struct rtx_const): Array size 16 for V16QImode.
+ * config/rs6000/rs6000.c (rs6000_init_libfuncs): Add AIX
+ TFmode to SImode libfuncs.
-2002-10-24 Richard Henderson <rth@redhat.com>
+2004-01-12 Roger Sayle <roger@eyesopen.com>
- * config/i386/i386.c (x86_output_mi_thunk): Fix x86_64 pic jump.
+ PR middle-end/11397
+ * varasm.c (assemble_alias): Remove weak aliases from weak_decls.
-2002-10-24 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-12 Jan Hubicka <jh@suse.cz>
- * config/h8300/h8300.c (initial_offset): Simplify by using
- round_frame_size.
+ PR opt/12826
+ * loop.c (insert_loop_mem): Preffer VOLATILE memory references to be
+ stored.
-2002-10-24 Marek Michalkiewicz <marekm@amelek.gda.pl>
+ PR opt/12863
+ * cfgcleanup.c (label_is_jump_target_p): Move to...
+ * rtlanal.c (label_is_jump_target_p): ... here.
+ * cfgrtl.c (cfg_layout_redirect_edge_and_branch): Fix redirecting of fallthru
+ edges unified with branch edges.
- * doc/install.texi (avr): Update required binutils version.
+2004-01-12 Richard Earnshaw <rearnsha@arm.com>
-2002-10-24 Theodore A. Roth <troth@openavr.org>
+ * simplify-rtx.c (simplify_immed_subreg): Correctly extract the
+ high word of an integral CONST_DOUBLE.
- * doc/install.texi: Point avr users at more up-to-date information.
+2004-01-12 Paul Brook <paul@codesourcery.com>
-2002-10-24 Ulrich Weigand <uweigand@de.ibm.com>
+ * simplify-rtx.c (simplify_plus_minus): Always generate canonical form.
- * config/s390/s390.md (movdi, movsi, movhi, movqi): Add peepholes2
- to pull operands out of the literal pool where possible.
+2004-01-12 J"orn Rennecke <joern.rennecke@superh.com>
-2002-10-24 Denis Chertykov <denisc@overta.ru>
+ PR target/13585
+ * sh-protos.h (check_use_sfunc_addr): Declare.
+ * sh.c (extract_sfunc_addr, check_use_sfunc_addr): New functions.
+ * sh.md (use_sfunc_addr): Use check_use_sfunc_addr in insn predicate.
- * config/avr/avr.c (init_cumulative_args): Test fntype for zero.
+2004-01-12 Jan Hubicka <jh@suse.cz>
-2002-10-24 Steve Ellcey <sje@cup.hp.com>
+ * alias.c: Invlude varray.h
+ (alias_sets): Turn into varray.
+ (get_alias_set_entry): Use VARRAY; mark inline.
+ (mems_in_disjoint_alias_sets_p): Mark inline.
+ (record_alias_subset): Use varray.
+ (init_alias_once): Initialize varray.
+ (new_alias_set): Grow array.
+ * varray.c: Make VARRAY_GENERIC_PTR non GTYized.
- * expr.c (convert_move): If unsignedp is less then zero there
- is no equivalent code.
+2004-01-12 Jan Hubicka <jh@suse.cz>
-2002-10-24 Zack Weinberg <zack@codesourcery.com>
+ Partial fix for PR opt/10776 II
+ * cselib.c: Include params.h
+ (cselib_invalidate_mem): Limit amount of nonconflicting memory
+ locations.
+ * params.def (PARAM_MAX_CSELIB_MEMORY_LOCATIONS): New.
+ * Makefile.in (cselib.o): Depend on params.h
- * tree.def: Delete mention of nonexistent ARRAY_TYPE fields.
+2004-01-12 Richard Sandiford <rsandifo@redhat.com>
-2002-10-24 Ulrich Weigand <uweigand@de.ibm.com>
+ * combine.c (combine_simplify_rtx): Don't pass VOIDmode to
+ simplify_unary_operation if the operand has a known mode.
- * config/s390/s390.h: Rework comments; re-sort target macro definitions
- according to the sequence they are defined in the manual.
- (POINTER_BOUNDARY): Remove.
+2004-01-12 Hartmut Penner <hpenner@de.ibm.com>
-2002-10-24 Kazu Hirata <kazu@cs.umass.edu>
+ PR target/13534
+ * gcc/config/rs6000/rs6000.c (word_offset_memref_operand): New
+ predicate to handle 'ld' conform addresses.
+ * gcc/config/rs6000/rs6000.h (EXTRA_CONSTRAINT): New 'Y'
+ contraint.
+ (EXTRA_MEMORY_CONSTRAINT): Tell reload which constraint
+ are memory contraints.
+ * gcc/config/rs6000/rs6000-protos.h (word_offset_memref_operand):
+ New prototype.
+ * gcc/config/rs6000/rs6000.md (*movdf_hardfloat64):
+ Change 'o' to 'Y' constraint.
+ (*movdf_softfloat64): Ditto.
- * config/h8300/h8300.c (round_frame_size): Replace 8 with
- BITS_PER_UNIT.
+2004-01-12 Bernardo Innocenti <bernie@develer.com>
-2002-10-24 Kazu Hirata <kazu@cs.umass.edu>
+ * gcc/config/m68k/m68k.md: Switch from the "*..." syntax to the
+ brace-enclosed syntax in all C output statements.
- * config/h8300/h8300.h (EIGHTBIT_CONSTANT_ADDRESS_P): Make it
- 64-bit safe.
- (TINY_CONSTANT_ADDRESS_P): Likewise.
+2004-01-12 David Edelsohn <edelsohn@gnu.org>
-2002-10-24 Richard Henderson <rth@redhat.com>
+ PR target/13401
+ * config/rs6000/rs6000.c (rs6000_output_function_epilogue):
+ Objective-C language type value is 14.
- * config/ia64/ia64.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): True.
- (ia64_output_mi_thunk): Rewrite to use rtl, and to handle the
- vcall offset.
+2004-01-12 Markus F.X.J. Oberhumer <markus@oberhumer.com>
-2002-10-24 Richard Henderson <rth@redhat.com>
+ PR c/12148
+ * config/m68k/fpgnulib.c: Fix `-mshort' bugs: Use `long' instead of
+ `int' in a number of places to make sure we always have a SImode
+ and not a HImode. Add a 'L' suffix to a number of constants.
- PR opt/7944
- * reload.c (find_reloads_toplev): Mode of X is not important
- when simplifying subregs of constants.
+2004-01-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-2002-10-24 Richard Sandiford <rsandifo@redhat.com>
+ * pa.c: Don't include obstack.h.
- * config.gcc (mips64vr-*-elf*, mips64vrel-*-elf*): Add
- MIPS_MARCH_CONTROLS_SOFT_FLOAT=1 to $tm_defines.
- * config/mips/mips.c (MIPS_MARCH_CONTROLS_SOFT_FLOAT): Default to 0.
- (override_options): Base default setting of MASK_SOFT_FLOAT on -march
- if MIPS_MARCH_CONTROLS_SOFT_FLOAT.
+ * pa.md: Correct constraint in pattern for loading PIC label address.
-2002-10-24 Richard Sandiford <rsandifo@redhat.com>
+2004-01-11 Kaz Kojima <kkojima@gcc.gnu.org>
- * optabs.c (expand_binop): Don't reuse the shift target in the
- middle of shift sequences.
+ * config/sh/linux.h (ASM_PREFERRED_EH_DATA_FORMAT): Undefine
+ before defining.
-2002-10-23 Ziemowit Laski <zlaski@apple.com>
+2004-01-11 Steven Bosscher <stevenb@suse.de>
- * objc/objc-act.c (get_static_reference): Remove unneeded
- TYPE_BINFO initialization.
- (get_object-reference): Likewise.
- (build_constructor): Tighten precondition check.
- (finish_message_expr): Likewise.
+ PR fortran/9972
+ * toplev.c (rest_of_handle_inline): Also consider functions
+ for deferral if the language is GNU F77.
-2002-10-23 Jakub Jelinek <jakub@redhat.com>
+2004-01-11 Zack Weinberg <zack@codesourcery.com>
- * config/i386/i386.c (local_symbolic_operand): Move LABEL_REF test
- after CONST test.
+ * c-decl.c (diagnose_arglist_conflict): Add missing space to
+ diagnostic messages.
-2002-10-23 Steve Ellcey <sje@cup.hp.com>
+2004-01-11 Jakub Jelinek <jakub@redhat.com>
- * config/ia64/ia64.c (hfa_element_mode): Don't allow 128 bit floats
- in HFAs.
+ PR middle-end/13392
+ * builtins.c (expand_builtin_expect_jump): Handle conditional jumps
+ to drop through label. Don't fall back to SCC even when conditional
+ jump has not been found.
-2002-10-23 Richard Henderson <rth@redhat.com>
+2004-01-11 Jan Hubicka <jh@suse.cz>
- * config/alpha/alpha.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): True.
- (alpha_output_mi_thunk_osf): Handle vcall_offset.
+ * invoke.texi: Fix syntax error in previous patch.
-2002-10-23 Zack Weinberg <zack@codesourcery.com>
+ Partial fix for PR opt/10776
+ * Makefile.in (reload.o): Include param.h
+ * params.def (PARAM_MAX_RELOAD_SEARCH_INSNS): New parameter.
+ * reload.c: Include params.h.
+ (find_equiv_reg): Work limiting check.
+ * invoke.texi: Document.
- * langhooks.h (struct lang_hooks_for_tree_inlining): Add
- var_mod_type_p.
- * langhooks-def.h: Default for tree_inlining.var_mod_type_p is
- hook_tree_bool_false.
+2004-01-11 Richard Sandiford <rsandifo@redhat.com>
- * tree.c (variably_modified_type_p): Moved here from
- cp/tree.c. Use lang_hooks.tree_inlining.var_mod_type_p for
- language-specific cases. Due to this, must weaken some 'if
- and only if' checks to merely 'if'.
- * tree.h: Prototype variably_modified_type_p.
+ * config/mips/mips.c (mips_symbolic_constant_p): Don't allow
+ out-of-bounds accesses to string constants. Simplify mips16
+ case accordingly.
- * tree-inline.c (walk_tree): #undef WALK_SUBTREE_TAIL at end.
+2004-01-11 Richard Sandiford <rsandifo@redhat.com>
-2002-10-23 Ulrich Weigand <uweigand@de.ibm.com>
+ PR optimization/13469
+ * toplev.c (rest_of_compilation): Call purge_all_dead_edges after
+ reload_cse_regs (-fnon-call-exceptions only).
- * config/s390/linux.h (CC1_SPEC, CC1PLUS_SPEC): Remove.
- * config/s390/s390.c (optimization_options): Disable -fcaller-saves.
+2004-01-11 Kazu Hirata <kazu@cs.umass.edu>
- * config/s390/s390-protos.h (fp_operand): Remove.
- * config/s390/s390.c (fp_operand): Remove.
- * config/s390/s390.md ("movdi"): Replace fp_operand by FP_REG_P.
- ("*movdi_lhi", "*movdi_lli", "*movdi_larl"): Likewise.
- ("movsi", "*movsi_lhi", "*movsi_lli"): Likewise.
- (movdi_31, movdf_31 splitters): Likewise.
+ * config/mcore/lib1.asm: Fix comment formatting.
+ * config/mcore/mcore-elf.h: Likewise.
+ * config/mcore/mcore.c: Likewise.
+ * config/mcore/mcore.h: Likewise.
+ * config/mcore/mcore.md: Likewise.
- * config/s390/s390.h (IEEE_FLOAT): Remove.
- (TARGET_FLOAT_FORMAT): Define in terms of TARGET_IEEE_FLOAT.
- (INT_REGNO_P): Rename to ...
- (GENERAL_REGNO_P): ... this.
- (FLOAT_REGNO_P): Rename to ...
- (FP_REGNO_P): ... this.
- (ADDR_REGNO_P): New macro.
- (GENERAL_REG_P, ADDR_REG_P, FP_REG_P, CC_REG_P): New macros.
- (REGNO_OK_FOR_DATA_P, REGNO_OK_FOR_FP_P): Remove.
- (DATA_REG_P, FP_REG_P, ADDRESS_REG_P): Likewise.
- (HARD_REGNO_NREGS): Adapt to macro renaming.
- (HARD_REGNO_MODE_OK): Likewise.
+2004-01-10 Zack Weinberg <zack@codesourcery.com>
-2002-10-23 David Edelsohn <edelsohn@gnu.org>
- Geoff Keating <geoffk@apple.com>
+ * c-decl.c (duplicate_decls): Break apart into...
+ (diagnose_arglist_conflict, validate_proto_after_old_defn)
+ (locate_old_defn, diagnose_mismatched_decls, merge_decls):
+ ... these new functions. Restructure for comprehensibility.
+ Remove various archaic special cases. Always report the
+ location of the previous declaration when a diagnostic is issued.
+ (redeclaration_error_message): Fold into diagnose_mismatched_decls.
+ (match_builtin_function_types): Delete unnecessary forward declaration.
- * config/rs6000/rs6000.c (rs6000_register_move_cost): New function.
- (rs6000_memory_move_cost): New function.
- * config/rs6000/rs6000-protos.h: Declare them.
- * config/rs6000/rs6000.h: Use them.
+2004-01-10 Zack Weinberg <zack@codesourcery.com>
-2002-10-23 Ulrich Weigand <uweigand@de.ibm.com>
+ * genautomata.c (make_automaton, NDFA_to_DFA):
+ Print progress bars with '.' characters instead of '*'.
+ (build_automaton): Change notes to match.
- * libgcc2.c (__udiv_w_sdiv): Use attribute ((always_inline)) when
- inlining it into other libgcc2 routines.
- (__udivmoddi4): Likewise.
+2004-01-10 Kazu Hirata <kazu@cs.umass.edu>
-2002-10-22 Nathanael Nerode <neroden@gcc.gnu.org>
+ * config/m32r/m32r.md: Use define_constants for unspec and
+ unspec_volatile.
- * doc/sourcebuild.texi (Test Suites): Improve.
+2004-01-10 Jan Hubicka <jh@suse.cz>
-2002-10-22 Stan Shebs <shebs@apple.com>
+ PR opt/11635
+ * expr.c (expand_expr_real): More curefully expand union casts.
- * config/rs6000/rs6000.c (rs6000_output_mi_thunk): Add missing
- case for Darwin.
+2004-01-10 Kazu Hirata <kazu@cs.umass.edu>
-2002-10-22 Jim Wilson <wilson@redhat.com>
+ * config/m32r/m32r.md (flush_icache): Use 1 for
+ unspec_volatile.
- * config/i386/i386.md (subdi3_1): Add call to ix86_binary_operator_ok.
+2004-01-10 David Edelsohn <edelsohn@gnu.org>
+ James E Wilson <wilson@specifixinc.com>
-2002-10-23 Jan Hubicka <jh@suse.cz>
+ PR debug/12860
+ * dbxout.c (dbxout_symbol): Remove initialization of
+ current_sym_code, current_sym_value, and current_sym_addr.
+ (dbxout_symbol_location): Same.
+ (dbxout_prepare_symbol): Zero current_sym_code,
+ current_sym_value, and current_sym_addr.
- PR other/8289
- * xmmintrin.h: Add const to the argument of loads.
+2004-01-10 Richard Sandiford <rsandifo@redhat.com>
- * i386.md (pushv2di): New pattern.
- PR target/6890
- * xmmintrin.h (_MM_TRANSPOSE4_PS): New.
+ * tree.c (get_unwidened): Reorder conditions so that the null pointer
+ check is done first.
-2002-10-22 Richard Henderson <rth@redhat.com>
+2004-01-09 Eric Christopher <echristo@redhat.com>
- * target.h (gcc_target.asm_out): Merge output_mi_thunk and
- output_mi_vcall_thunk into a single hook. Add can_output_mi_thunk.
- * target-def.h (TARGET_ASM_OUTPUT_MI_THUNK): Don't conditionalize.
- (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Remove.
- (TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
- (TARGET_ASM_OUT): Update.
- * hooks.c (hook_bool_tree_hwi_hwi_tree_false): New.
- (hook_bool_tree_hwi_hwi_tree_true): New.
- (default_can_output_mi_thunk_no_vcall): New.
- * hooks.h: Declare them.
- * system.h (ASM_OUTPUT_MI_THUNK): Poison.
+ * toplev.c (rest_of_handle_cfg): Add reg_scan pass
+ if we're running mark_constant_function.
- * config/alpha/alpha.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
- (alpha_output_mi_thunk_osf): Add VCALL_OFFSET parameter.
- * config/arm/arm.c, config/cris/cris.c, config/frv/frv.c,
- config/i960/i960.c, config/ia64/ia64.c, config/m68k/m68k.c,
- config/mmix/mmix.c, config/pa/pa.c, config/sparc/sparc.c,
- config/stormy16/stormy16.c: Similarly.
+2004-01-09 Jeff Bailey <jbailey@nisa.net>
- * config/i386/i386.c (x86_output_mi_thunk): Merge vcall_offset code.
- Handle 64-bit properly. Streamline.
- (x86_output_mi_vcall_thunk): Remove.
- (x86_this_parameter): Rename from ia32_this_parameter; handle 64-bit.
- (x86_can_output_mi_thunk): New.
- (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Remove.
- (TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
- (override_options): Don't zap targetm.asm_out.output_mi_vcall_thunk.
-
- * config/rs6000/rs6000.c (rs6000_output_mi_thunk): Rename from
- output_mi_thunk; make static; always use function_section.
- (TARGET_ASM_OUTPUT_MI_THUNK): New.
- (TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
- (rs6000_ra_ever_killed): Test no_new_pseudos not
- targetm.asm_out.output_mi_thunk in conjunction with thunks.
- * config/rs6000/rs6000-protos.h: Update.
- * config/rs6000/sysv4.h (TARGET_ASM_OUTPUT_MI_THUNK): Remove.
- * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Don't call
- xcoffout_declare_function when using rs6000_output_mi_thunk.
-
- * config/s390/s390.c (s390_output_mi_thunk): Rename from
- s390_output_mi_vcall_thunk.
- (TARGET_ASM_OUTPUT_MI_THUNK): Remove.
- (TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
-
- * config/vax/vax.c (vax_output_mi_thunk): Static; add vcall_offset.
- (TARGET_ASM_OUTPUT_MI_THUNK, TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
- * config/vax/vax-protos.h: Update.
- * config/vax/vax.h (ASM_OUTPUT_MI_THUNK): Remove.
-
-2002-10-23 Jan Hubicka <jh@suse,cz>
-
- * i386.c (standard_sse_constant_p): Accept vector and integer zeros too.
- * i386.h (EXTRA_CONSTRAINT): Recognize 'C'
- * i386.md (movti_internal): Use 'C'
-
- * xmmintrin.h (_mm_cmplt_epi*): New.
-
-2002-10-22 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.md ("*movdi_64"): Fix op_type attribute.
- ("*movdf_64"): Likewise.
- ("*lshrdi3_64"): Likewise.
- ("blockage"): Add length attribute.
- ("lit"): Likewise.
-
-2002-10-22 Jan Hubicka <jh@suse.cz>
-
- * i386.md: FIx typo.
- (sse2_cvtsi2sd, sse2_pslrdq): Fix template.
- (sse2_umulv2siv2di3): Fix predicate.
- (sse2_psadbw, ashrv8hi3, ashrv4si3, lshrv8hi3 lshrv4si3,
- lshrv2di3, ashlv8hi3, ashlv4si3, ashlv2di3): Likewise.
- * xmmintrin.h (_mm_mul_epu16): Rename to...
- (_mm_mul_epu32): This one.
- (_mm_cvtsi32_si128, _mm_cvtsi128_si32): New.
-
- (contains_128bit_aligned_vector_p): Undo accidental checkin.
-
-2002-10-22 Eric Christopher <echristo@redhat.com>
-
- * config/sparc/sparc.h: Add #error.
-
-2002-10-22 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config.gcc [s390-*-linux]: Remove s390/t-linux from tmake_file.
- [s390x-*-linux*]: Likewise.
- * config/s390/t-linux: Remove.
- * config/s390/s390.h: Include fixdfdi.h when building libgcc2.
-
-2002-10-22 Jan Hubicka <jh@suse.cz>
-
- * i386.c (builtin_description): Add IX86_BUILTIN_PUNPCKHQDQ128.
- (ix86_expand_builtin): Fix MASKMOVDQU expasion.
- * i386.h (ix86_builtins): Add IX86_BUILTIN_PUNPCKHQDQ128.
- * i386.md (mmx_punpck?dq): Simplify.
- (sse2_pubpcklqdq): Fix.
- (sse2_pubpckhqdq): New.
- * xmmintrin.h (_mm_unpackhi_epi32): New.
-
- * xmmintrin.h (_mm_cvt*, _mm_stream_pd): Fix prototypes.
- (_mm_shufflehi_epi16, _mm_shufflelo_epi16): Fix typo.
-
-2002-10-22 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/7209
- * fold_const.c (fold_binary_op_with_conditional_arg): Always
- build compound_expr if we used save_expr.
-
-2002-10-22 Alan Modra <amodra@bigpond.net.au>
-
- * output.h (SECTION_NOTYPE): Define.
- * varasm.c (default_section_type_flags_1): Set SECTION_NOTYPE for
- init array sections.
- (default_elf_asm_named_section): Mind SECTION_NOTYPE.
- * config/arm/arm.c (arm_elf_asm_named_section): Likewise. Also
- merge TLS support.
-
-2002-10-21 Richard Henderson <rth@redhat.com>
-
- * real.c (sticky_rshift_significand): Return inexact, don't
- or it in immediately.
- (sub_significands): Accept incomming carry.
- (div_significands, rtd_divmod): Update for sub_significands change.
- (round_for_format): Update for sticky_rshift_significand change.
- (do_add): Don't involve the inexact bit in addition, do give the
- inexact bit as the subtraction carry-in.
- (encode_internal, decode_internal, real_internal_format): New.
- * real.h (real_internal_format): Declare.
-
-2002-10-21 Ulrich Weigand <uweigand@de.ibm.com>
-
- * libgcc2.c: Fix __udiv_w_sdiv breakage on platforms that
- don't define sdiv_qrnnd.
-
-2002-10-21 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.h (EIGHTBIT_CONSTANT_ADDRESS_P): Simplify
- using IN_RANGE.
- (TINY_CONSTANT_ADDRESS_P): Likewise.
-
-2002-10-22 Jan Hubicka <jh@suse.cz>
-
- * i386.c (builtin_description): Add punpcklqdq and movdq2q
- (ix86_init_mmx_sse_builtins): Add v2di_ftype_void, di_ftype_v2di,
- v16qi_ftype_pchar, void_ftype_pchar_v16qi, v4si_ftype_pchar,
- void_ftype_pchar_v4si; Initialize __builtin_ia32_movdq2q,
- __builtin_ia32_loaddqa, __builtin_ia32_loaddqu, __builtin_ia32_loadd
- __builtin_ia32_storedqa, __builtin_ia32_storedqu, __builtin_ia32_stored
- __builtin_ia32_setzero128.
- (ix86_expand_builtin): Handle IX86_BUILTIN_CLRTI, IX86_BUILTIN_LOADDQA,
- IX86_BUILTIN_LOADDQU, IX86_BUILTIN_LOADD, IX86_BUILTIN_STOREDQA,
- IX86_BUILTIN_STOREDQU, IX86_BUILTIN_STORED, Ix86_BUILTIN_MOVQ.
- * i386.h (ix86_builtins): Add IX86_BUILTIN_LOADDQA, IX86_BUILTIN_LOADDQU,
- IX86_BUILTIN_STOREDQA, IX86_BUILTIN_STOREDQU, IX86_BUILTIN_LOADD,
- IX86_BUILTIN_STORED, IX86_BUILTIN_CLRTI, IX86_BUILTIN_MOVDQ2Q,
- IX86_BUILTIN_PUNPCKLQDQ128, Ix86_BUILTIN_MOVQ.
- * i386.md (sse2_punpcklqdq, sse2_movqsse2_loadd, sse2_stored,
- sse2_movq): New patterns.
- (sse2_movdqa, sse2_movdqu, sse2_movdq2q): Fix.
- * xmmintrin.h (_mm_load_si128, _mm_loadu_si128, _mm_loadl_epi64,
- _mm_store_si128, _mm_storeu_si128, _mm_storel_epi64,
- _mm_setzero_si128, _mm_set_epi64, _mm_set_epi32, _mm_set_epi16,
- _mm_set_epi8, _mm_set1_epi64, _mm_set1_epi32, _mm_set1_epi16,
- _mm_set1_epi8, _mm_setr_epi64, _mm_setr_epi32, _mm_setr_epi16,
- _mm_setr_epi8, _mm_unpacklo_epi64,_mm_set_moveq): New functions.
- (_mm_insert_epi16): Fix.
-
-2002-10-21 Dale Johannesen <dalej@apple.com>
-
- * config/rs6000/rs6000.c (rs6000_reverse_condition): Handle
- unsafe math reversals correctly for RTL generation.
- (output_cbranch): Replace rs6000_reverse_condition call
- by its former definition.
-
-2002-10-21 Jakub Jelinek <jakub@redhat.com>
-
- * config/i386/i386.c (x86_64_sign_extended_value): Add allow_rip
- argument. In CM_SMALL_PIC model consider SYMBOL_REFs binding locally or
- from constant pool or LABEL_REFs as sign extended if allow_rip.
- Change all +-1GB limits to +-16MB.
- (x86_64_general_operand, x86_64_szext_general_operand,
- x86_64_nonmemory_operand, x86_64_movabs_operand,
- x86_64_szext_nonmemory_operand, x86_64_immediate_operand,
- legitimate_address_p, ix86_expand_int_movcc): Update callers.
- (local_symbolic_operand): Don't allow offsets bigger than +-16MB
- in CM_SMALL_PIC model.
- (legitimate_pic_address_disp_p): Don't check offsets before
- calling local_symbolic_operand.
- (legitimize_pic_address): Force offsets bigger than +-16MB into
- register.
- * config/i386/i386.h (EXTRA_CONSTRAINT, CONST_COSTS): Likewise.
- * config/i386/i386-protos.h (x86_64_sign_extended_value): Update
- prototype.
+ PR target/12561
+ * config/t-gnu: Rename SYSTEM_HEADER_DIR to NATIVE_SYSTEM_HEADER_DIR.
- * configure.in: Test for @GOTNTPOFF and @INDNTPOFF on IA-32 too.
- Add x86-64 test. Set tls_first_minor to 14 on IA-32 and x86-64.
- * configure: Rebuilt.
- * config/i386/i386.c (x86_64_sign_extended_value): Don't allow TLS
- SYMBOL_REFs unless enclosed in UNSPEC. Handle UNSPEC_DTPOFF,
- UNSPEC_GOTNTPOFF and UNSPEC_NTPOFF.
- (legitimate_address_p): Allow foo@dtpoff(base) even on TARGET_64BIT
- -fpic.
- (ix86_encode_section_info): Don't ever generate TLSGD or TLSLD for
- non-pic code if TARGET_64BIT.
- (legitimize_address): Generate 64-bit TLS sequences.
- (output_pic_addr_const): Support x86-64 TLS operators.
- (i386_output_dwarf_dtprel): Output 64-bit DTPOFF as .long f@DTPOFF, 0.
- (print_operand_address): Use %fs instead of %gs on TARGET_64BIT.
- Don't append (%rip) in 64-bit TLSGD and TLSLD sequences.
- (output_addr_const_extra): Support x86-64 TLS operators.
- (maybe_get_pool_constant): Handle TARGET_64BIT -fpic.
- (ix86_tls_get_addr): Use __tls_get_addr on TARGET_64BIT
- unconditionally.
- * config/i386/i386.md (*tls_global_dynamic_gnu): Renamed to...
- (*tls_global_dynamic_32_gnu): ..., add !TARGET_64BIT.
- (*tls_global_dynamic_sun): Renamed to...
- (*tls_global_dynamic_32_sun): ..., add !TARGET_64BIT.
- (tls_global_dynamic): Renamed to...
- (tls_global_dynamic_32): ... this.
- (tls_global_dynamic_64, *tls_global_dynamic_64): New.
- (*tls_local_dynamic_base_dynamic_gnu): Renamed to...
- (*tls_local_dynamic_base_dynamic_32_gnu): ..., add !TARGET_64BIT.
- (*tls_local_dynamic_base_dynamic_sun): Renamed to...
- (*tls_local_dynamic_base_dynamic_32_sun): ..., add !TARGET_64BIT.
- (tls_local_dynamic_base_dynamic): Renamed to...
- (tls_local_dynamic_base_dynamic_32): ... this.
- (tls_local_dynamic_base_dynamic_64,
- *tls_local_dynamic_base_dynamic_64): New.
- (*tls_local_dynamic_once): Renamed to...
- (*tls_local_dynamic_32_once): ... this.
-
-2002-10-21 Ulrich Weigand <uweigand@de.ibm.com>
-
- * libgcc2.c: Inline __udiv_w_sdiv when compiling __udivdi3,
- __divdi3, __umoddi3, or __moddi3.
-
-2002-10-21 Ulrich Weigand <uweigand@de.ibm.com>
-
- * c-opts.c (missing_arg): Use cl_options[opt_index].opt_code
- instead of just opt_index as switch expression.
-
- * calls.c (store_one_arg): Change type of 'excess_align'
- to unsigned int.
-
- * profile.c (output_gcov_string): Change type of 'temp'
- to size_t.
-
-2002-10-21 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/fixdfdi.h (__fixunsdfdi, __fixdfdi): Add prototypes.
- (__fixunssfdi, __fixsfdi): Likewise.
- * config/s390/s390.c (s390_single_hi): Initialize 'value'.
- (s390_single_qi): Likewise.
- (s390_emit_epilogue): Initialize 'offset'. Remove signed vs.
- unsigned comparison warning.
- (s390_return_addr_rtx): New function.
- * config/s390/s390-protos.h (s390_return_addr_rtx): Declare it.
- * config/s390/s390.h (RETURN_ADDR_RTX): Use it.
- (HARD_REGNO_MODE_OK): Rewrite condition to silence warnings.
-
-2002-10-21 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c (s390_output_mi_vcall_thunk): New function.
- (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Define target hook.
- (s390_output_mi_thunk): Remove.
- (TARGET_ASM_OUTPUT_MI_THUNK): Remove.
-
-2002-10-21 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.h (N_REG_CLASSES): Parenthesize.
-
-2002-10-20 Richard Henderson <rth@redhat.com>
-
- * target.h (struct gcc_target): Line wrap.
-
- * config/alpha/alpha.c (alpha_output_mi_thunk_osf): Static.
- (TARGET_ASM_OUTPUT_MI_THUNK): Define here...
- * config/alpha/alpha.h: ... not here.
- * config/alpha/alpha-protos.h: Update.
-
- * config/arm/arm.c, config/arm/arm.h, config/arm/arm-protos.h
- config/cris/cris-protos.h, config/cris/cris.c, config/cris/cris.h,
- config/frv/frv-protos.h, config/frv/frv.c, config/frv/frv.h,
- config/i386/i386-protos.h, config/i386/i386.c, config/i386/openbsd.h,
- config/i386/unix.h, config/i960/i960-protos.h, config/i960/i960.c,
- config/i960/i960.h, config/ia64/ia64-protos.h, config/ia64/ia64.c,
- config/ia64/ia64.h, config/m68k/linux.h, config/m68k/m68k-protos.h,
- config/m68k/m68k.c, config/m68k/netbsd-elf.h, config/m68k/openbsd.h,
- config/mmix/mmix-protos.h, config/mmix/mmix.c, config/mmix/mmix.h,
- config/pa/pa-protos.h, config/pa/pa.c, config/pa/pa.h,
- config/s390/s390-protos.h, config/s390/s390.c, config/s390/s390.h,
- config/sparc/openbsd.h, config/sparc/sparc-protos.h,
- config/sparc/sparc.c, config/sparc/sparc.h,
- config/stormy16/stormy16-protos.h, config/stormy16/stormy16.c,
- config/stormy16/stormy16.h: Similarly.
-
- * config/m68k/m68k.c (m68k_output_mi_thunk): Replicate mnemonic
- selection logic from call patterns.
-
-2002-10-20 Mark Mitchell <mark@codesourcery.com>
-
- * config/m68k/m68k.c (m68k_output_mi_thunk): Fix typo.
-
-2002-10-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
-
- PR other/8202
- * i386.c (ix86_init_mmx_sse_builtins, ix86_expand_builtin): Define and
- expand __builtin_ia32_pslldqi128 and __builtin_ia32_psrldqi128.
- * i386.h (IX86_BUILTIN_PSLLDQI128, IX86_BUILTIN_PSRLDQI128): New.
- * xmmintrin.h (_mm_srli_si128, _mm_slli_si128): New.
-
-2002-10-20 Roger Sayle <roger@eyesopen.com>
-
- PR c/761
- * toplev.c (flag_unsafe_profile_arcs): Remove.
- (flag_bounded_pointers): Remove.
- (flag_bounds_check): Correct comments.
- (lang_independent_options): Remove -funsafe-profile-arcs and
- -fbounded-pointers. Correct -fbounds-check comments.
-
- * flags.h: Correct flag_schedule_interblock comments.
- (flag_bounded_pointers): Remove prototype.
- (flag_bounds_check): Correct comments.
-
- * c-opts.c (c_common_init_options): No need to mark
- flag_bounds_check as unspecified.
- (c_common_post_options): And no need to set it from
- flag_bounded_pointers if its still unspecified.
-
- * doc/invoke.texi: Fix some overfull hboxes in "make dvi".
- Document --version, -feliminate-dwarf-2-dups, -fno-sched-interblock,
- -fno-sched-spec, -fsched-spec-load, -fsched-spec-load-dangerous,
- -fsched-verbose=n, -fno-branch-count-reg and -fbounds-check.
-
-2002-10-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
- Mark Mitchell <mark@codesourcery.com>
-
- * alpha-protos.h (alpha_output_mi_thunk_osf): Update signature to
- match target.h.
- * arm-protos.h, arm.c (arm_output_mi_thunk): Likewise.
- * cris-protos.h, cris.c (cris_asm_output_mi_thunk): Likewise.
- * frv-protos.h, frv.c (frv_asm_output_mi_thunk): Likewise.
- * i386-protos.h, i386.c (x86_output_mi_vcall_thunk,
- x86_output_mi_thunk): Likewise.
- * i960-protos.h, i960.c (i960_output_mi_thunk): Likewise.
- * ia64-protos.h, ia64.c (ia64_output_mi_thunk): Likewise.
- * m68k-protos.h, m68k.c (m68k_output_mi_thunk): Likewise.
- * mmix-protos.h, mmix.c (mmix_asm_output_mi_thunk): Likewise.
- * rs6000-protos.h, rs6000.c (output_mi_thunk): Likewise.
- * s390-protos.h, s390.c (s390_output_mi_thunk): Likewise.
- * stormy16-protos.h, stormy16.c (xstormy16_asm_output_mi_thunk):
- Likewise.
- * vax-protos.h, vax.c (vax_output_mi_thunk): Likewise.
-
- * target.h (gcc_target): Update output_mi_thunk and
- output_mi_vcall_thunk to take a HOST_WIDE_INT delta and
- vcall_index.
-
- * config/alpha/alpha.c: Replace ASM_OUTPUT_MI_THUNK with
- TARGET_ASM_OUTPUT_MI_THUNK in comments.
- * config/alpha/vms.h (ASM_OUTPUT_MI_THUNK): Don't #undef it.
- (TARGET_ASM_OUTPUT_MI_THUNK): #undef it.
- * config/frv/frv.h (DEFAULT_VTABLE_THUNKS): Remove definition.
- * config/i386/i386-protos.h (x86_output_mi_vcall_thunk): Update
- signature.
- * config/i386/i386.c (x86_output_mi_vcall_thunk): Likewise.
- * config/i386/openbsd.h: Replace ASM_OUTPUT_MI_THUNK with
- TARGET_ASM_OUTPUT_MI_THUNK in comments.
- * config/i960/i960.h (ASM_OUTPUT_MI_THUNK): Don't define.
- (TARGET_ASM_OUTPUT_MI_THUNK): Do define.
- * config/m68k/openbsd.h: Replace ASM_OUTPUT_MI_THUNK with
- TARGET_ASM_OUTPUT_MI_THUNK in comments.
- * config/rs6000/rs6000.c (rs6000_ra_ever_killed): Remove #ifdef
- ASM_OUTPUT_MI_THUNK and replace with check of targetm.
-
- * doc/tm.texi (TARGET_ASM_OUTPUT_MI_THUNK): Update signature.
- (TARGET_ASM_OUTPU_MI_VCALL_THUNK): Likewise.
-
-2002-10-19 Brad Lucier <lucier@math.purdue.edu>
-
- * real.c (do_add): Fix 0+0 sign corner case.
- (do_divide): Fix Inf/0 corner case.
-
-2002-10-20 Jan Hubicka <jh@suse.cz>
-
- * i386.c (classify_argument): Pass MMX arguments in memory
- (ix86_expand_builtin): Expand proper address mode for cflush.
- * i386.md (movdqa): Fix typo.
- (sse2_cflush): Accept DImode addresses.
-
- * xmmintrin.h (_mm_sqrt_sd): Accept two arguments.
- (_mm_max_sd): Fix pasto.
- (_mm_storeh_pd, _mm_storel_pd): Fix.
-
- * i386.c (bdesc_comi): Fix to match specification.
- (ix86_expand_sse_comi): Emit the comparison properly.
- * i386.md (sse_comi, sse2_comi, sse_ucomi, sse2_ucomi):
- Do not use comparison operator.
- (vnmaskcmp): Fix template.
-
- * xmmintrin.h (_mm_cvtps_pi16): Fix.
-
-2002-10-19 Sebastian Pop <s.pop@laposte.net>
-
- * dependence.c : Removed.
- * Makefile.in : Remove dependence.o.
-
-2002-10-19 Jan Hubicka <jh@suse.cz>
-
- * mmintrin.h (__m64): typedef it to v2si.
- (_mm_cvtsi32_si64, _mm_cvtsi32_si64_mm_sll_pi16,
- _mm_sll_pi32, _mm_sll_pi64, _mm_slli_pi64, _mm_sra_pi16,
- _mm_sra_pi32, _mm_srl_pi16, _mm_srl_pi32, _mm_srl_pi64,
- _mm_srli_pi64, _mm_and_si64, _mm_andnot_si64,
- _mm_or_si64, _mm_xor_si64): Add neccesary casts.
- * xmmintrin.h (_mm_setzero_si64): Likewise.
-
- * i386.h (ALIGN_MODE_128): Update comment; add missing modes
- (SSE_REG_MODE_P, MMX_REG_MODE_P): New macros.
-
- PR target/7693
- Patch by Shawn Wagner
- * mmintrin.h: Replace pi64 by si64.
-
-2002-10-18 David Edelsohn <edelsohn@gnu.org>
-
- * rs6000.md (movdf_hardfloat32): Order alternatives consistently.
- Use length of 4 not *.
- (movdf_hardfloat64): Same. Support DFmode moves to/from CTR/LR.
- (movdf_softfloat64): Likewise.
- (movdi_internal32): Use length of 4 not *.
- (movti_power): Same.
- (ctrsi, ctrdi): Same.
-
-2002-10-18 Zack Weinberg <zack@codesourcery.com>
-
- * c-decl.c (start_decl): Point users of the old initialized-
- typedef extension at __typeof__.
-
-2002-10-18 Richard Henderson <rth@redhat.com>
-
- * real.c (cmp_significand_0, rtd_divmod, ten_to_mptwo): New.
- (real_to_decimal): Re-implement using the logic from the
- gcc 3.2 etoasc. Comment heavily.
- (div_significands): Simplify loop startup and comparison logic.
-
-2002-10-18 Mark Mitchell <mark@codesourcery.com>
-
- * target-def.h (TARGET_ASM_OUTPUT_MI_THUNK): Default to NULL.
- (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Likewise.
- (TARGET_ASM_OUT): Add them.
- * target.h (asm_out): Add output_mi_thunk and
- output_mi_vcall_thunk.
- * config/alpha/alpha.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/arm/arm-protos.h (arm_output_mi_thunk): Declare.
- * config/arm/arm.c (arm_output_mi_thunk): Define.
- * config/arm/arm.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/cris/cris.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/frv/frv.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/i386/i386-protos.h (x86_output_mi_thunk): Adjust
- prototype.
- (x86_output_mi_vcall_thunk): Declare.
- * config/i386/i386.c (override_options): Clear
- output_mi_vcall_thunk in 64-bit mode.
- (ix86_fntype_regparm): New function.
- (ix86_return_pops_args): Use it.
- (ia32_this_parameter): New function.
- (x86_output_mi_vcall_thunk): New function.
- (x86_output_mi_thunk): Use it
- * config/i386/unix.h (TARGET_ASM_OUTPUT_MI_THUNK): Adjust.
- (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Define.
- * config/i960/i960-protos.h (i960_output_mi_thunk): Declare.
- * config/i960/i960.c (i960_output_mi_thunk): New function.
- * config/i960/i960.h (ASM_OUTPUT_MI_THUNK): Adjust.
- * config/ia64/ia64-protos.h (ia64_output_mi_thunk): Declare.
- * config/ia64/ia64.c (ia64_output_mi_thunk): Define.
- * config/ia64/ia64.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/m68k/m68k-protos.h (m68k_output_mi_thunk): New function.
- * config/m68k/linux.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/m68k/netbsd-elf.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/mmix/mmix.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/pa/pa.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/rs6000/sysv4.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/s390/s390-protos.h (s390_output_mi_thunk): Declare.
- * config/s390/s390.c (s390_output_mi_thunk): Define.
- * config/s390/s390.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/sparc/sparc.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/stormy16/stormy16.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * config/vax/vax-protos.h (vax_output_mi_thunk): Declare.
- * config/vax/vax.c (vax_output_mi_thunk): Define.
- * config/vax/vax.h (ASM_OUTPUT_MI_THUNK): Rename to ...
- (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
- * doc/tm.texi: Adjust documentation.
-
-2002-10-18 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/netbsd.h (NETBSD_ENABLE_EXECUTE_STACK): Define
- __enable_execute_stack function.
- * config/alpha/netbsd.h (TRANSFER_FROM_TRAMPOLINE): Define
- as NETBSD_ENABLE_EXECUTE_STACK.
- * config/i386/netbsd-elf.h (TRANSFER_FROM_TRAMPOLINE): Ditto.
- * config/i386/netbsd.h (TRANSFER_FROM_TRAMPOLINE): Ditto.
- * config/i386/netbsd64.h (TRANSFER_FROM_TRAMPOLINE): Ditto.
- * config/sparc/netbsd-elf.h (TRANSFER_FROM_TRAMPOLINE): Ditto.
- * config/sparc/netbsd.h (TRANSFER_FROM_TRAMPOLINE): Ditto.
-
-2002-10-18 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/i386/i386.c (x86_initialize_trampoline): Emit a call
- to __enable_execute_stack with the address of the trampoline
- if TRANSFER_FROM_TRAMPOLINE is defined.
- * config/i386/i386.h (TARGET_64BIT): Expand to a compile-time
- constant if building libgcc2.
-
-2002-10-17 Roger Sayle <roger@eyesopen.com>
-
- * doc/c-tree.texi: Update description of COND_EXPR tree nodes.
-
-2002-10-17 Geoffrey Keating <geoffk@apple.com>
-
- * config/rs6000/rs6000.h (HARD_REGNO_MODE_OK): Allow arbitrary modes
- in CTR/LR/MQ.
- * config/rs6000/rs6000.md (movcc_internal1): Support CCmode moves
- to/from CTR/LR/MQ.
- (movsf_hardfloat): Support SFmode moves to/from CTR/LR/MQ.
- (movsf_softfloat): Likewise.
-
-2002-10-17 Janis Johnson <janis187@us.ibm.com>
-
- * Makefile.in (site.exp): Add ALT_CXX_UNDER_TEST and COMPAT_OPTIONS.
-
-2002-10-17 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/alpha/alpha.c (alpha_initialize_trampoline): Use
- tramp, not addr, to pass the trampoline address to
- __enable_execute_stack.
-
-2002-10-17 Jan Hubicka <jh@suse.cz>
-
- * mmintrin.h: Guard by __MMX__
- * xmmintrin.h: Guard by __SSE__
-
- PR other/8062
- * xmmintrin.h (_MM_SHUFFLE2): New macro.
- (_mm_load*_?d): New functions.
- (_mm_set*_?d): New functions.
- (_mm_store*_?d): New functions.
-
-2002-10-16 Jan Hubicka <jh@suse.cz>
-
- Really commit patch announced at Oct 14
- PR c/7344
- * predict.c (can_predict_insn_p): New function.
- (estimate_probability): Avoid unnecesary work.
- (process_note_prediction): Likewise.
- * toplev.c (rest_of_compilation): Account early branch prediction pass
- as TV_BRANCH_PROB.
-
- PR other/8048
- Found by Ian Ollmann
- * xmmintrin.h (_mm_shuffle_pd): Fix typo.
- (_mm_load?_pd): Likewise.
- (_mm_store?_pd): Likewise.
-
- PR target/7386
- * i386.c (builtin_description):Drop cmpg[te]s[sd].
- * xmmintrin.h (__mm_cmpg[te]_s[sd]): Rewrite using
- swapped alternative.
-
- PR opt/7630
- * reload1.c (reload_inner_reg_of_subreg): New argument output;
- (push_reload): Update call.
-
-2002-10-17 Richard Sandiford <rsandifo@redhat.com>
-
- * config.gcc (mips*-*-*): Add OBJECT_FORMAT_ELF to $tm_defines
- if using mips/elf.h or mips/elf64.h.
- * config/mips/elf.h (OBJECT_FORMAT_ELF): Remove.
- * config/mips/elf64.h (OBJECT_FORMAT_ELF): Remove.
-
-2002-10-16 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/rs6000.c (function_arg): Set inner mode of V1DI to
- SI.
-
-2002-10-16 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/linux.h (ASM_DOUBLE, _ASM_OUTPUT_LONG): Remove.
- (LPREFIX): Likewise.
- (ASM_COMMENT_START, LOCAL_LABEL_PREFIX, ASM_FORMAT_PRIVATE_NAME,
- ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT,
- ASM_OUTPUT_ALIGN, ASM_OUTPUT_SKIP, ASM_OUTPUT_ALIGNED_BSS,
- TEXT_SECTION_ASM_OP, DATA_SECTION_ASM_OP, BSS_SECTION_ASM_OP,
- GLOBAL_ASM_OP, ASM_OUTPUT_MI_THUNK): Move to s390.h.
+2004-01-09 Andrew Pinski <pinskia@physics.uc.edu>
- * config/s390/s390.h (ASM_COMMENT_START, LOCAL_LABEL_PREFIX,
- ASM_FORMAT_PRIVATE_NAME, ASM_OUTPUT_ALIGN, ASM_OUTPUT_SKIP,
- ASM_OUTPUT_ALIGNED_BSS, TEXT_SECTION_ASM_OP, DATA_SECTION_ASM_OP,
- BSS_SECTION_ASM_OP): Move from linux.h.
- (ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT): Likewise.
- Also, use ASM_GENERATE_INTERNAL_LABEL instead of LPREFIX.
+ PR debug/11231
+ * dbxout.c (dbxout_type_fields): Return if any item is
+ error_mark_node or the type is error_mark_node.
- * config/s390/s390.c (s390_function_profiler): Use
- ASM_GENERATE_INTERNAL_LABEL instead of LPREFIX.
+2004-01-09 Geoffrey Keating <geoffk@apple.com>
-2002-10-15 Richard Henderson <rth@redhat.com>
+ * config/rs6000/darwin-ldouble.c: Add big comment explaining
+ exactly what is expected as a 'long double'.
+ (_xlqadd): When a value to be returned is representable as a
+ 'double', just return it directly, do not construct it using a union.
+ Also, correct final fixup.
+ (_xlqmul): Likewise.
+ (_xlqdiv): Likewise.
+ * real.c (encode_ibm_extended): Make consistent with darwin-ldouble.c.
- * real.c (real_to_decimal): Accept BUF_SIZE and CROP_TRAILING_ZEROS
- as arguments. Bound DIGITS by the available buffer size.
- (real_to_hexadecimal): Likewise.
- * real.h (real_to_decimal, real_to_hexadecimal): Update prototypes.
- (REAL_VALUE_TO_DECIMAL): Remove.
- * c-common.c, c-pretty-print.c, print-rtl.c, print-tree.c,
- sched-vis.c, config/arc/arc.c, config/c4x/c4x.c, config/fr30/fr30.c,
- config/i370/i370.h, config/i386/i386.c, config/i960/i960.c,
- config/ip2k/ip2k.c, config/m32r/m32r.c, config/m68hc11/m68hc11.c,
- config/m68k/hp320.h, config/m68k/m68k.h, config/m68k/sun2o4.h,
- config/m68k/sun3.h, config/mips/mips.c, config/ns32k/ns32k.c,
- config/pdp11/pdp11.h, config/vax/vax.h: Update all callers to
- use real_to_decimal directly, and with the proper arguments.
- * doc/tm.texi (REAL_VALUE_TO_DECIMAL): Remove.
-
-2002-10-15 Jim Wilson <wilson@redhat.com>
-
- * reload1.c (merge_assigned_reloads): After converting overlapping
- reloads to RELOAD_OTHER, abort if there are now conflicting reloads.
-
- * config/i386/i386.md (adddi3_1): Add call to ix86_binary_operator_ok.
-
-2002-10-15 Jan Hubicka <jh@suse.cz>
-
- * expr.c (do_tablejump): Fix typo in my previous commit.
-
-2002-10-15 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/vr.h (DRIVER_SELF_SPECS): Change %<mgp32 to %{<mgp32}.
-
-2002-10-15 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c (s390_split_branches): Add return
- value. Add parameters TEMP_REG and TEMP_USED. Use unspec 104.
-
- (find_base_register_in_addr): New function.
- (find_base_register_ref): New function.
- (replace_base_register_ref): New function.
-
- (struct constant_pool): Add members pool_insn, insns, and anchor.
- Remove member last_insn.
- (s390_start_pool): Initialize them.
- (s390_end_pool): Emit pool placeholder insn.
- (s390_add_pool_insn): New function.
- (s390_find_pool): Use insns bitmap instead of addresses.
- (s390_dump_pool): Replace placeholder insn. Emit anchor.
- Replace unspec 104 by local-pool-relative references.
- (s390_output_constant_pool): Output anchor label if required.
- (s390_output_symbolic_const): Handle unspec 104 and 105.
- (s390_add_pool): Remove, replace by ...
- (s390_add_constant, s390_find_constant): ... these new functions.
- (s390_add_anchor): New function.
-
- (s390_chunkify_pool): Delete, replace by ...
- (s390_chunkify_start, s390_chunkify_finish,
- s390_chunkify_cancel): ... these new functions.
- (s390_optimize_prolog): Add parameter TEMP_REGNO.
- Recompute register live data for special registers.
- (s390_fixup_clobbered_return_reg): New function.
- (s390_machine_dependent_reorg): Rewrite to use new
- s390_chunkify_... routines.
+ * config/rs6000/rs6000.md (fix_trunctfdi2): Delete.
- config/s390/s390.md ("reload_base"): Rename to ...
- ("reload_base_31"): ... this.
- ("reload_base_64"): New insn.
- ("reload_base2"): Remove.
- ("reload_anchor"): New insn.
- ("pool"): New insn.
-
- s390.c (s390_pool_overflow): Remove.
- s390.h (s390_pool_overflow): Likewise.
- s390.md ("cjump", "icjump", "doloop_si"): Remove s390_pool_overflow.
+2004-01-09 Richard Henderson <rth@redhat.com>
-2002-10-15 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.md (movv8qi_i+2): Don't split if source is -1.
-
-2002-10-15 Janis Johnson <janis187@us.ibm.com>
-
- * doc/install.texi: Formatting changes for conformance to HTML 4.01.
-
-2002-10-15 Ulrich Weigand <uweigand@de.ibm.com>
-
- PR opt/7409
- * loop.c (loop_regs_scan): Mark registers used for function
- argument passing as MAY_NOT_OPTIMIZE.
-
-2002-10-14 Jan Hubicka <jh@suse.cz>
-
- * i386.md (movv2di_internal): New pattern.
- (movv2df_internal, movv8hi_internal, movv16qi_internal): Fix predicate.
- (movv2di): New expander.
- * i386.c (ix86_preferred_reload_class): Return NO_REGS for vector operands.
+ * recog.c (constrain_operands): Validate mem operands.
- * i386.c (ix86_expand_timode_binop_builtin): Delete.
- (builtin_description): Add SSE1 logicals; rename SSE2 logicals.
- (ix86_init_mmx_sse_builtins): Kill SSE1 logicals.
- (ix86_expand_builtin): Likewise.
- * i386.h (sse_andti4_df_1, sse_andti3_df_2, sse_andti3_sf_1, sse_andti3_sf_2,
- sse_andti3,
- sse_andnti4_df_1, sse_andti3_df_2, sse_andti3_sf_1, sse_andti3_sf_2,
- sse_andnti3,
- sse_orti4_df_1, sse_orti3_df_2, sse_orti3_sf_1, sse_orti3_sf_2,
- sse_orti3,
- sse_xorti4_df_1, sse_xorti3_df_2, sse_xorti3_sf_1, sse_xorti3_sf_2,
- sse_xorti3): Kill.
- (sse_andv4sf3, sse_andnv4sf3, sse_orv2df3, sse_xorv2df3, sse_andv2df3,
- sse_andnv2df3, sse_orv2df3, sse_xorv2df3): New expanders.
- (*sse_andv4sf3, *sse_andnv2df3, *sse_orv4sf3, *sse_xorv4sf3, *sse_andv2df3,
- *sse_andnv2df3, *sse_orv2df3, *sse_xorv2df3): New patterns.
- (*sse_andsf3, *sse_andndf3, *sse_ordf3, *sse_xordf3, *sse_anddf3,
- *sse_andndf3, *sse_orv2df3, *sse_xorv2df3): New patterns.
+2004-01-09 James E Wilson <wilson@specifixinc.com>
- * xmmintrin.h (__m128i): Define as __v2di.
+ * gcc.c (init_spec): Remove -lunwind from shared case.
+ * conifg/ia64/t-hpux (SHLIB_LINK): Add -lunwind.
- PR c++/6419
- (expand_expr): Use DECL_RTL_SET_P.
+2004-01-09 Steve Ellcey <sje@cup.hp.com>
-2002-10-14 Roger Sayle <roger@eyesopen.com>
+ * configure.ac: (gcc_cv_ld_hidden) Set to true for ia64*-*-hpux*.
+ * configure: Regenerate
- * combine.c (simplify_set): Treat MODE_CC registers like cc0.
+2004-01-09 Joseph S. Myers <jsm@polyomino.org.uk>
-2002-10-14 Roger Sayle <roger@eyesopen.com>
- Zack Weinberg <zack@codesourcery.com>
-
- * config/i386/i386.c (k6_cost): Correct typo.
-
-2002-10-14 Mark Mitchell <mark@codesourcery.com>
-
- PR optimization/6631
- * alias.c (objects_must_conflict_p): Check honor_readonly when
- examining TYPE_READONLY.
- * function.c (assign_stack_temp_for_type): Likewise.
-
-2002-10-14 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
-
- * config/alpha/alpha.md (extendsidi2_nofix, extendsidi2_fix):
- Swap zero extension arguments.
- (umaxhi3): Fix instruction class.
- PR target/7211
- (prefetch): Fix prefetch instructions.
- PR target/7238
- (pkwb): Fix output constraint.
-
-2002-10-14 Alexandre Oliva <aoliva@redhat.com>
-
- * config/mips/mips.c (print_operand): Increase buffer size for
- real numbers.
-
-2002-10-14 Richard Henderson <rth@redhat.com>
-
- PR opt/8165
- * gcse.c (adjust_libcall_notes): Revert last change.
- * simplify-rtx.c (simplify_replace_rtx): Handle LO_SUM.
-
-2002-10-14 Andrew Haley <aph@redhat.com>
-
- * tree-inline.c (remap_block): All local class initialization
- flags go in the outermost scope.
- (expand_call_inline): Call java_inlining_map_static_initializers.
- (expand_call_inline): Call java_inlining_merge_static_initializers.
- * java/lang.c (merge_init_test_initialization): New.
- (java_inlining_merge_static_initializers): New.
- (inline_init_test_initialization): New.
- (java_inlining_map_static_initializers): New.
-
- * tree-inline.c (expand_call_inline): Convert retvar to expected
+ PR c/11234
+ * c-typeck.c (build_c_cast): If pedantic, warn for conversions
+ between function and object pointers.
+ (digest_init): When comparing a pointer to function type to the
+ target type, only apply TREE_TYPE once to the pointer to function
type.
+ * except.c (for_each_eh_label_1): Treat data as a pointer to a
+ function pointer rather than casting it to a function pointer.
+ (for_each_eh_label): Update caller.
+ * recog.h (struct insn_data): Use a struct or union for output.
+ * genoutput.c (output_insn_data): Update.
+ * final.c (get_insn_template): Update.
+
+2004-01-09 Mark Mitchell <mark@codesourcery.com>
+
+ * expr.h (expand_expr): Make it a macro, not a function.
+ (expand_expr_real): New function.
+ * expr.c (store_expr): Adjust logic for deciding whether or not to
+ copy the value returned by expand_expr.
+ (expand_expr): Rename to ...
+ (expand_expr_real): ... this. Add alt_rtl parameter. Adjust
+ calls to language hooks.
+ * c-common.h (c_expand_expr): Adjust prototype.
+ * c-common.c (c_expand_expr): Add alt_rtl parameter.
+ * langhooks-def.h (lhd_expand_expr): Change prototype.
+ * langhooks.c (lhd_expand_expr): Add all_rtl parameter.
+ * langhooks.h (lang_hooks): Change type of expand_expr.
+ * stmt.c (stmt_status): Add x_last_expr_alt_rtl.
+ (last_expr_alt_rtl): Likewise.
+ (expand_expr_stmt_value): Set last_expr_alt_rtl.
+ (clear_last_expr): Clear it.
+ (expand_end_stmt_expr): Set RTL_EXPR_ATL_RTL.
+ (expand_end_bindings): Save and restor last_expr_alt_rtl.
+ * tree.def (RTL_EXPR): Give it an additional operand.
+ * tree.h (RTL_EXPR_ALT_RTL): New macro.
+
+2004-01-09 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/m32r/m32r.h (TARGET_CPU_CPP_BUILTINS): Add __m32r__.
+ * config/m32r/m32r.c (call26_operand): Allow in PIC mode.
+
+2004-01-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/13380.
+ * config/m32r/m32r.md: Replace (reg:SI 17) with (reg:CC 17)
+ or (ne:SI (reg:CC 17) (const_int 0)).
+ Be specific about modes wherever possible.
+
+2004-01-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.c (m32r_expand_block_move): Call
+ gen_movestrsi_internal with two more arguments.
+ (m32r_output_block_move): Adjust operand numbers.
+ Properly update the source and destination pointers.
+ * config/m32r/m32r.md (movstrsi_internal): Use 'r' instead of
+ 'r+'. Change the set detinations to match_operand.
+
+2004-01-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * final.c (FIRST_INSN_ADDRESS): Remove.
+ (shorten_branches): Don't use FIRST_INSN_ADDRESS.
+ * system.h (FIRST_INSN_ADDRESS): Poison.
+ * config/avr/avr.h: Remove a comment about FIRST_INSN_ADDRESS.
+ * config/m32r/m32r-protos.h: Remove the prototype for
+ m32r_first_insn_address.
+ * config/m32r/m32r.c (m32r_first_insn_address): Remove.
+ * config/m32r/m32r.h (FIRST_INSN_ADDRESS): Likewise.
+ * doc/md.texi (FIRST_INSN_ADDRESS): Likewise.
+
+2004-01-09 J. Brobecker <brobecker@gnat.com>
+
+ * dwarf2out.c (gen_enumeration_type_die): Return the DIE that
+ we just created.
+ (is_ada_subrange_type): DIEs for enumeration subtypes should be
+ emitted as subrange types too.
+ (subrange_type_die): Add handling of enumeration subtypes.
+
+2004-01-08 Richard Henderson <rth@redhat.com>
+
+ PR opt/12441
+ Revert: Sat Mar 30 14:08:55 CET 2002 Jan Hubicka <jh@suse.cz>
+ * i386.c (aligned_operand): Be prepared for SUBREGed registers.
+ (ix86_decompose_address): Use REG_P instead of GET_CODE (...) == REG.
+ (ix86_address_cost): Be prepared for SUBREGed registers.
+ (legitimate_address_p): Accept SUBREGed registers.
+
+2004-01-08 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in: Rename configure.in to configure.ac
+ * doc/sourcebuild.texi: Likewise.
+ * configure: Regenerate.
+ * config.in: Regenerate.
-2002-10-14 Graham Stott <graham.stott@btinternet.com>
-
- * stmt.c (decl_conflicts_with_clobbers_p): Add REG_P check.
-
-2002-10-14 Aldy Hernandez <aldyh@redhat.com>
-
- * stmt.c: Fix typo in comment.
-
-2002-10-14 J"orn Rennecke <joern.rennecke@superh.com>
-
- * c-common.c (c_common_type_for_mode): Add V2HImode case.
- * tree.c (build_common_tree_nodes_2): Initialize
- unsigned_V2HI_type_node and V2HI_type_node.
- * tree.h (enum tree_index): Add TI_UV2HI_TYPE and TI_V2HI_TYPE.
- (unsigned_V2HI_type_node, V2HI_type_node): Define.
-
-2002-10-14 Jakub Jelinek <jakub@redhat.com>
-
- * config/i386/i386.h (ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP):
- Handle TARGET_64BIT.
-
-2002-10-14 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/vr.h (DRIVER_SELF_SPECS): Define.
- * config/mips/t-vr (MULTILIB_OPTIONS): Remove mlong32.
- (MULTILIB_DIRNAMES): Remove long32.
- (MULTILIB_EXCEPTIONS): Don't build -mabi=32 -mgp32 multilibs.
- (MULTILIB_REDUNDANT_DIRS): Remove.
-
-2002-10-14 Richard Sandiford <rsandifo@redhat.com>
-
- * doc/tm.texi (DRIVER_SELF_SPECS): Document.
- * gcc.c (driver_self_specs): New variable.
- (do_self_spec): New function.
- (main): Use it to process driver_self_specs.
-
-2002-10-13 Richard Henderson <rth@redhat.com>
-
- * rtl.c (shallow_copy_rtx): Use memcpy for the entire node.
-
-2002-10-12 Neil Booth <neil@daikokuya.co.uk>
-
- PR preprocessor/7862
- PR preprocessor/8190
- * gcc.c (cpp_unique_options): Don't delete .d files.
- Remove stray whitespace.
-
-2002-10-12 Naohiko Shimizu <pshimizu@fa2.so-net.ne.jp>
-
- * pdp11.h (ASM_OUTPUT_SKIP): Add preceding 0 for octal constant.
- (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL): Likewise.
- * pdp11.c (pdp11_output_function_prologue): 0%o -> %#o.
- (pdp11_output_function_epilogue, output_ascii): Likewise.
- (output_addr_const_pdp11): Likewise.
- * pdp11.md (movdi): Use offsetable memory for floating store.
- (lshrsi3, negsi2): Delete irrelevant comment.
-
-2002-10-11 Geoffrey Keating <geoffk@apple.com>
-
- * cse.c (mention_regs): Set SUBREG_TICKED to the register number,
- not the address of the REG.
- (struct cse_reg_info): Make subreg_ticked unsigned.
-
-2002-10-11 Janis Johnson <janis187@us.ibm.com>
-
- * doc/compat.texi: Add info about C++ libraries.
-
-2002-10-11 Richard Henderson <rth@redhat.com>
-
- PR opt/8165
- * gcse.c (adjust_libcall_notes): Also adjust notes for INSN.
-
-2002-10-11 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * cfganal.c (dfs_enumerate_from): Use PARAMS.
- * genautomata.c (output_insn_code_cases): Likewise.
- * real.c (real_format): Likewise.
- * tree.c (tree_size): Revise expressions using TREE_CODE_LENGTH to
- ensure value is promoted before doing subtraction.
-
-2002-10-11 Jan Hubicka <jh@suse.cz>
-
- * calls.c (expand_call): Simplify noreturn call.
-
- PR c/7344
- * cfgbuild.c (make_edges): Create edge cache when we do have
- large jumptable.
- * expr.c (do_tablejump): Note size of maximal jumptable.
- * function.c (prepare_function_start): Zero out size.
- * function.h (function): Add max_jumptable_ents.
-
- * cfgcleanup.c (insn_match_p): Verify sibcall flag for calls to.
-
-2002-10-11 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.md (movv8qi_i+2): For V8QI destinations, generate V4HI
- register for mperm_w operation.
-
-2002-10-11 J"orn Rennecke <joern.rennecke@superh.com>
-
- * emit-rtl.c (gen_lowpart_common): When asked to make a vector from
- an integer, use simplify_gen_subreg.
-
-2002-10-10 Aldy Hernandez <aldyh@redhat.com>
-
- * extend.texi (Vector Extensions): Remove comment about single
- element vectors.
-
-2002-10-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * fold-const.c (size_htab_hash): Use htab_hash_pointer.
- * function.c (insns_for_mem_hash): Likewise.
- * varasm.c (STRHASH): Likewise.
-
-2002-10-10 Stuart Hastings <stuart@apple.com>
-
- * cse.c (struct cse_reg_info): Add subreg_ticked.
- (SUBREG_TICKED): New.
- (get_cse_reg_info): Initialize SUBREG_TICKED.
- (mention_regs): Use it.
- (invalidate): Set SUBREG_TICKED.
- (invalidate_for_call): Likewise.
- (addr_affects_sp_p): Likewise.
-
-2002-10-10 Jakub Jelinek <jakub@redhat.com>
-
- * config/i386/i386.md (tls_local_dynamic_base): Put pic reg
- into proper operand.
-
-2002-10-10 Denis Chertykov <denisc@overta.ru>
-
- * config/ip2k/ip2k.c (function_epilogue): Optimize stack
- deallocation.
- * config/ip2k/libgcc.S: Combine routines used by function
- epilogue.
-
-2002-10-10 Jim Wilson <wilson@redhat.com>
-
- * cse.c (fold_rtx): Don't perform associative optimization for DIV and
- UDIV.
-
-2002-10-10 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/aix52.h: New file.
- * config/rs6000/t-aix52: New File.
- * config.gcc (rs6000-ibm-aix5.1.*): New entry.
- (rs6000-ibm-aix[56789].*): Default to AIX 5.2.
-
-2002-10-10 Jan Hubicka <jh@suse.cz>
-
- PR target/5610
- * invoke.texi (-msse-math): Kill
- (-msse): Add note to mfpmath=sse.
-
-2002-10-10 Jan Hubicka <jh@suse.cz>
-
- PR target/7723
- * i386.c (ix86_expand_vector_move): Do not generate const0->mem moves.
-
-2002-10-10 Neil Booth <neil@daikokuya.co.uk>
-
- PR preprocessor/8179
- * gcc.c (cpp_options): Add {ansi}, move %{m*} to same location
- as cc1_options.
- (default_compilers): Pass debug options when preprocessing
- stdin.
-
-2002-10-06 Richard Henderson <rth@redhat.com>
-
- * toplev.c (rest_of_compilation): Revert opt/2960 change.
-
-2002-10-09 Zack Weinberg <zack@codesourcery.com>
-
- PR c/7353
- * c-decl.c (start_decl): Unconditionally issue error for
- 'typedef foo = bar'.
- (finish_decl): Remove special case for TYPE_DECL with initializer.
-
- * doc/extend.texi: Delete "Naming Types" section. Change all
- cross-references to that section to refer to "Typeof" instead.
- Add the useful safe-max()-macro example from "Naming Types" to
- "Typeof", rewritten using that extension. Add some compatibility
- notes to "Typeof."
-
-2002-10-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * loop.c: Revert 2002-08-15 change.
- (LOOP_REGNO_NREGS): Ensure type is int.
-
-2002-10-09 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.md (extenddftf2): Change to define_insn
- which copies first FPR and clears second.
- (extendsftf2): Same.
- (floatditf2): Fix typo.
- (floatsitf2): Same.
- (fix_trunctfdi2): Same.
- (fix_trunctfsi2): Same.
-
-2002-10-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * conflict.c (arc_hash): Change return type to hashval_t.
- * cselib.c (get_value_hash): Likewise.
- * genautomata.c (automaton_decl_hash, insn_decl_hash, decl_hash,
- state_hash, automata_list_hash): Likewise.
- * read-rtl.c (def_hash): Likewise.
- * tree.c (type_hash_hash): Likewise.
-
-2002-10-08 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/rs6000.c (rs6000_ra_ever_killed): Call
- prologue_epilogue_contains instead of using REG_MAYBE_DEAD notes.
-
-2002-10-09 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.md (ffssi2): Fix emitted code.
-
-2002-10-09 Ulrich Weigand <uweigand@de.ibm.com>
-
- * cse.c (insn_live_p): Pass insn pattern, not full insn
- to may_trap_p.
-
-2002-10-09 Neil Booth <neil@daikokuya.co.uk>
-
- * cppmacro.c (paste_tokens): Only allow / to paste with =.
-
-2002-10-09 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.md (movdf splitter): Use gen_int_mode on
- 64-bit hosts.
- (movtf_internal): Reference correct displacement for second value
- in memory.
- (movtf splitter): Correct generation of constants in 64-bit mode.
-
-2002-10-09 Alan Modra <amodra@bigpond.net.au>
-
- * libgcc2.c (__floatdisf): Properly cure double rounding.
-
-2002-10-09 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * c-common.c (cb_register_builtins): Define __WCHAR_MAX__.
- * doc/cpp.texi (Common Predefined Macros): Document.
-
-2002-10-09 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- PR doc/7484
- * doc/invoke.texi (Option Summary): List
- -Wmissing-declarations as a C only option.
-
-2002-10-08 Jakub Jelinek <jakub@redhat.com>
-
- * config/sparc/t-linux64 (MULTILIB_OPTIONS): Remove
- mno-app-regs|mcmodel=medany.
- (MULTILIB_DIRNAMES, MULTILIB_OSDIRNAMES): Remove alt.
- (MULTILIB_EXCEPTIONS, MULTILIB_EXCLUSIONS, MULTILIB_MATCHES): Remove.
- (CRTSTUFF_T_CFLAGS): Define.
-
-2002-10-08 Roger Sayle <roger@eyesopen.com>
-
- PR target/8087
- * simplify-rtx.c (avoid_constant_pool_reference): Allow constant
- pool references that are constructed using LO_SUM.
-
-2002-10-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * c-opts.c (c_common_decode_option): Add warn_strict_aliasing to
- -Wall.
- * c-typeck.c (build_c_cast): Use warn_strict_aliasing, tweak
- message.
- * flags.h (warn_strict_aliasing): Declare.
- * toplev.c (warn_strict_aliasing): Define.
- (lang_independent_options): Add it.
- * doc/invoke.texi (-Wstrict-aliasing): Document it.
-
-2002-10-08 Zack Weinberg <zack@codesourcery.com>
-
- * system.h (GCCBUGURL): Delete.
- * version.c (bug_report_url): New. Add commentary about
- modifying both these strings in modified distributions.
- * version.h: Declare bug_report_url.
-
- * diagnostic.c, gcc.c, gcov.c: Globally replace GCCBUGURL with
- bug_report_url.
-
-2002-10-08 Nick Clifton <nickc@redhat.com>
-
- * config/rs6000/spe.h (__ev_set_acc_u64): Use __ev_create_u64 to
- convert uint64_t into __ev64_opaque__.
- (__ev_set_acc_s64): Likewise, but using signed types.
-
-2002-10-08 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.md ("*doloop_si_long"): Add missing operand.
- ("*doloop_di_long"): Likewise.
-
-2002-10-08 Jan Hubicka <jh@suse.cz>
-
- * print-rtl.c (print_rtx): Increase buffer size for real numbers.
-
-2002-10-08 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.md (define_attr cpu): Add r4111.
-
-2002-10-08 Anthony Green <green@redhat.com>
-
- * bitmap.c (bitmap_equal_p): Clear all bitmap_head fields.
-
-2002-10-08 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
-
- * config/c4x/c4x.c (c4x_print_operand): Enlarge buffer
- for REAL_VALUE_TO_DECIMAL output.
-
-2002-10-07 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.c (rs6000_override_options): Set
- real_format_for_mode for IBM extended format, if enabled.
- (easy_fp_constant): Add TFmode.
- (rs6000_legitimize_address): Add TFmode.
- (rs6000_legitimate_address): Same.
- (function_arg_advance): TFmode uses two FPRs.
- (rs6000_emit_prologue): Fix warning.
- (rs6000_output_function_epilogue): Add TFmode.
- (output_toc): Add TFmode.
- * rs6000.h (SLOW_UNALIGNED_ACCESS): Add TFmode.
- (LEGITIMATE_OFFSET_ADDRESS_P): Add TFmode.
- * rs6000.md (movtf splitter): Load TFmode constant.
-
-2002-10-07 Dale Johannesen <dalej@apple.com>
-
- * rtl.h: Add NOTE_PRECONDITIONED.
- * unroll.c: Set it.
- * loop.c: Set loop_info->preconditioned from it.
- * doloop.c: Permit doloop treatment when loop_info->preconditoned.
-
-2002-10-07 Richard Henderson <rth@redhat.com>
-
- * config/i960/i960.c (i960_setup_incoming_varargs): Create a
- new rtx for comparing the argument pointer against zero.
- (i960_va_start): Similarly.
-
-2002-10-07 Richard Henderson <rth@redhat.com>
-
- * config/i960/i960.md (*): Use TFmode, not XFmode.
- * config/i960/i960.c (*): Likewise.
- (i960_arg_size_and_align): Remove XFmode alignment hack.
- (i960_round_align): Merge code from ROUND_TYPE_ALIGN.
- * config/i960/i960.h (LONG_DOUBLE_TYPE_SIZE): Use 128, not 96.
- (MAX_LONG_DOUBLE_TYPE_SIZE): Likewise.
- (DATA_ALIGNMENT, ROUND_TYPE_SIZE): Remove.
-
-2002-10-07 Richard Henderson <rth@redhat.com>
-
- * config/fp-bit.c (EXTENDED_FLOAT_STUBS): Flush out all XF/TFmode
- entry points; use void return value and argument list.
-
-2002-10-05 Naohiko Shimizu <nshimizu@keyaki.cc.u-tokai.ac.jp>
-
- * t-pdp11: Add MULTILIB support for msoft-float.
- * pdp11.h (LEGITIMATE_CONSTANT_P): Fix soft-float case.
-
- * t-pdp11: Add LIB2FUNCS_EXTRA.
- * pdp11.c (pdp11_output_function_prologue): Restrict offset to 16bit,
- add preceding 0 to the octal constant, rename 'fp' to 'r5', rename
- 'fldd' to 'ldd', rename 'fstd' to 'std'.
- (pdp11_output_function_epilogue): Likewise.
- (output_move_quad): Make the comment gas compatible.
- (output_ascii): Add preceding 0 to the octal constant.
- (print_operand_address): Add pre_modify, post_modify.
- (output_addr_const_pdp11): Add preceding 0 to the octal constant.
- * pdp11.h (GO_IF_LEGITIMATE_ADDRESS) : Add 'movb' pre_modify case
- with the indication of Paul Koning.
- (PRINT_OPERAND): Fix floating constant.
- * pdp11.md (movdi): Restrict matching pattern.
- (movqi): Generalize the matching pattern.
- (movdf): Restrict matching pattern.
- (zero_extendqihi2): Change constant representation.
- (floatsidf2): Fix wrong operands.
- (addqi3): Fix wrong instruction name.
- (subqi3): Fix wrong instruction name.
- (andsi3, andhi3, andqi3): Simplify and fix to use 'bic'.
- (xorsi3): Fix wrong insn.
- (one_cmplqi2): Add two operand pattern.
- (lsrsi3): New.
- (negsi2): New.
- (call): Add register indirect case.
- (mod): Fix wrong subreg.
-
-2002-10-06 Eric Botcazou <ebotcazou@libertysurf.fr>
- Volker Reichelt <reichelt@igpm.rwth-aachen.de>
-
- PR c/7411
- * expr.c (expand_expr) [PLUS]: Simplify after the operands
- have been expanded in EXPAND_NORMAL mode.
-
-2002-10-06 Richard Henderson <rth@redhat.com>
-
- * config/rs6000/rs6000.md (load_toc_v4_PIC_2): Fix base constraint.
-
-2002-10-06 Richard Henderson <rth@redhat.com>
-
- PR optimization/2960
- * toplev.c (rest_of_compilation): Don't copy_loop_headers if
- optimize_size.
-
-2002-10-06 Alexandre Oliva <aoliva@redhat.com>
-
- * config/mips/mips.h (SIZE_TYPE, PTRDIFF_TYPE): Override
- previously definitions.
-
-2002-10-06 Frank Ch. Eigler <fche@redhat.com>
-
- * cppinit.c (init_standard_includes, parse_option): Use strncmp.
- * c-opts.c (find_opt): Similarly.
-
-2002-10-05 Jakub Jelinek <jakub@redhat.com>
-
- * gcc.c (set_multilib_dir): Don't access *end.
- Use memcpy instead of strncpy. Don't write beyond malloced buffer.
- (print_multilib_info): Don't show paths starting with ".:".
- * genmultilib: Add new option, "yes" if multilibs are enabled.
- Update comments. If multilibs not enabled, print .:${osdirout}
- for each directory. If multilibs are enabled, always print
- ${dirout}:${osdirout}, even if the two are the same.
- * Makefile.in (s-mlib): Pass @enable_multilib@ to genmultilib.
- Pass all MULTILIB_* variables to genmultilib even if
- --disable-multilib but MULTILIB_OSDIRNAMES is not empty.
-
-2002-10-04 Bruce Korb <bkorb@gnu.org>
-
- * fixinc/inclhack.def(hpux11_abs): use format fix
- * fixinc/fixincl.x: regenerate
- * fixinc/tests/base/stdlib.h: accommodate new fix test
-
-2002-10-05 Jan Hubicka <jh@suse.cz>
-
- * c-common.c (cb_register_builtins): Use really_no_inline.
-
-2002-10-04 David Edelsohn <edelsohn@gnu.org>
-
- * unroll.c (copy_loop_body): Remove REG_EQUAL note attached to
- copied instruction if the note is not loop invariant.
-
-2002-10-04 Loren J. Rittle <ljrittle@acm.org>
-
- * gcc/ginclude/stddef.h: Support the FreeBSD 5 typedef system.
-
-2002-10-04 Steve Ellcey <sje@cup.hp.com>
-
- * doc/invoke.texi (HPPA): Add -mlinker-opt, -mgnu-ld,
- and -mhp-ld options to list of options. Add -mgnu-ld
- and -mhp-ld option descriptions.
-
-2002-10-04 Steve Ellcey <sje@cup.hp.com>
-
- * fixinc/inclhack.def (hpux11_abs): New.
- (stdio_va_list): change __va_list__ to __gnuc_va_list.
- * fixinc/fixincl.x: Rebuild.
-
-2002-10-04 Roger Sayle <roger@eyesopen.com>
-
- * config/i386/i386.h (processor_costs): Add new fields fadd,
- fmul, fdiv, fabs, fchs and fsqrt to costs structure.
- (RTX_COSTS): Use these fields to determine the RTX costs
- of floating point addition/subtraction, multiplication,
- division, fabs, negation and square root respectively.
- * config/i386/i386.c (size_cost): Provide instruction sizes
- for these new fields.
- (i386_cost, i486_cost, pentium_cost, pentiumpro_cost,
- k6_cost, athlon_cost, pentium4_cost): Provide typical cycle
- counts for these new fields for all x86 processor variants.
-
-2002-10-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * mips.c (mips_const_double_ok): Delete unused variable.
-
- * gengtype.c (rtx_next): Change type to int.
-
-2002-10-04 Andreas Jaeger <aj@suse.de>
-
- * config/i386/t-linux64 (MULTILIB_OSDIRNAMES): Fix value.
-
-2002-10-04 Richard Henderson <rth@redhat.com>
-
- * real.h (SIGNIFICAND_BITS): Add one more word.
- (CONST_DOUBLE_FORMAT): Accomodate 6 words.
- * real.c (times_pten): New.
- (real_to_decimal, real_from_string): Use it.
- (sticky_rshift_significand): Use & to find modulus.
- (rshift_significand, lshift_significand): Likewise.
- (do_divide): Apply sticky bit after normalization.
- (real_to_decimal, real_to_hexadecimal): Fix sign of Inf and NaN.
-
-2002-10-03 Andreas Jaeger <aj@suse.de>
-
- * gengtype.c (adjust_field_rtx_def): Cast variables of type size_t
- to unsigned long, adjust printf format string.
- (output_mangled_typename): Likewise.
-
-2002-10-03 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/vax/vax.c (vax_output_function_prologue): Use asm_fprintf.
- * config/vax/vax.h (VAX_FUNCTION_PROFILER_NAME): New.
- (FUNCTION_PROFILER): Rewrite to use ASM_GENERATE_INTERNAL_LABEL,
- assemble_name, asm_fprintf, and VAX_FUNCTION_PROFILER_NAME.
- (ASM_OUTPUT_MI_THUNK): Use asm_fprintf instead of REGISTER_PREFIX.
- (PRINT_OPERAND_PUNCT_VALID_P): Fix comment.
- * config/vax/elf.h (FUNCTION_PROFILER): Remove.
- (VAX_FUNCTION_PROFILER_NAME): Redefine as "__mcount".
-
-2002-10-03 Mark Mitchell <mark@codesourcery.com>
-
- * doc/invoke.texi (-Wabi): Document mangling bug.
-
-2002-10-04 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.c (rs6000_output_function_epilogue): Use a
- name for the tbtab label that depends on the function asm name.
- Don't output tbtab label unless optional_tbtab.
- (output_mi_thunk): Formatting.
-
-2002-10-03 Richard Henderson <rth@redhat.com>
-
- * config/m68k/m68k.h (OVERRIDE_OPTIONS): Move additional code ...
- * config/m68k/m68k.c (override_options): ... here.
- * config/m68k/m68kelf.h (OVERRIDE_OPTIONS): Remove.
- * config/m68k/m68kv4.h (OVERRIDE_OPTIONS): Remove.
- * config/m68k/linux.h (SUBTARGET_OVERRIDE_OPTIONS): Remove.
- * config/m68k/netbsd-elf.h (SUBTARGET_OVERRIDE_OPTIONS): Remove.
-
-2002-10-03 Richard Henderson <rth@redhat.com>
-
- * real.h (struct real_value): Use ENUM_BITFIELD.
-
-2002-10-03 Richard Henderson <rth@redhat.com>
-
- * config/i960/i960.md (call, call_value): Use emit_call_insn.
-
-2002-10-03 Steve Ellcey <sje@cup.hp.com>
-
- * config/pa/pa64-hpux.h (INIT_ENVIRONMENT): New.
-
-2002-10-03 Steve Ellcey <sje@cup.hp.com>
-
- * config.gcc (hppa*64*-*-hpux11*): Check gnu_ld.
- * config/pa/pa.h (MASK_GNU_LD): New.
- (TARGET_GNU_LD): New.
- * config/pa/pa64-hpux.h (LINK_SPEC): Set based
- on gnu-ld and MASK_GNU_LD.
- (SUBTARGET_SWITCHES): New gnu-ld & hp-ld flags.
-
-2002-10-03 Jan Hubicka <jh@suse.cz>
-
- * i386.c (athlon_cost): Fix the move costs.
-
-2002-10-03 Jan Hubicka <jh@suse.cz>
-
- * final.c (final): Use symbol name as function name for profiling.
- * profile.c (get_exec_counts): Likewise.
- (branch_prob): Likewise.
-
-2002-10-03 Jakub Jelinek <jakub@redhat.com>
-
- * longlong.h (__udiv_qrnnd): Remove PARAMS from prototype.
-
-2002-10-03 Jakub Jelinek <jakub@redhat.com>
-
- * gcc.c (print_multi_os_directory): New variable.
- (option_map): Support --print-multi-os-directory.
- (struct prefix_list): Add os_multilib field.
- (multilib_os_dir): New variable.
- (static_specs): Add multilib_options.
- (find_a_file): Add multilib argument. Search in GCC or OS multilib
- subdirs if non-zero.
- (read_specs, execute): Update callers.
- (find_file): Likewise. Don't prefix name with multilib_dir, instead
- pass 1 as multilib option.
- (display_help): Include --print-multi-os-directory.
- (add_prefix): Add os_multilib argument. Initialize pl->os_multilib.
- (process_command): Update callers. Handle --print-multi-os-directory.
- (do_spec_1) ['D']: Use multilib_os_directory if pl->os_multilib is
- set.
- (main): Update find_a_file and add_prefix callers.
- Handle print_multi_os_directory.
- (struct mdswitchstr): New.
- (mdswitches, n_mdswitches): New variables.
- (used_arg): Add MULTILIB_DEFAULT switches too if they are not
- present on the command line nor their mutually incompatible
- switches.
- (default_arg): Optimize.
- (set_multilib_dir): Compute multilib_os_dir. Initialize mdswitches
- array.
- (print_multilib_info): Only print GCC multilib dir name, not OS
- multilib dirname.
- * genmultilib: Add osdirnames parameter. Output multilib_options
- variable. If osdirnames is specified, output dirnames as
- dirname:osdirname.
- * mklibgcc.in: Use MULTILIB_OSDIRNAMES, --print-multi-directory
- and --print-multi-os-directory instead of SHLIB_SLIBDIR_SUFFIXES
- to compute libgcc_s soname and install path.
- * Makefile.in (libgcc.mk): Pass MULTILIB_OSDIRNAMES instead of
- SHLIB_SLIBDIR_SUFFIXES to mklibgcc.
- (s_mlib): Pass MULTILIB_OSDIRNAMES or nothing as last genmultilib
- argument.
-
- * config/sparc/t-linux64 (MULTILIB_OSDIRNAMES): Set.
- (SHLIB_SLIBDIR_SUFFIXES): Remove.
- * config/sparc/linux64.h (STARTFILE_SPEC32, STARTFILE_SPEC64,
- ENDFILE_SPEC32, ENDFILE_SPEC64, ENDFILE_COMMON): Remove.
- (STARTFILE_SPEC, ENDFILE_SPEC): Don't distinguish between -m32
- and -m64.
- * config/sparc/t-sol2-64 (MULTILIB_OSDIRNAMES): Set.
- (SHLIB_SLIBDIR_SUFFIXES): Remove.
- * config/sparc/sol2-bi.h (STARTFILE_ARCH64_SPEC): Remove.
- (STARTFILE_ARCH_SPEC): Remove.
- * config/i386/t-linux64 (MULTILIB_OSDIRNAMES): Set.
- (SHLIB_SLIBDIR_SUFFIXES): Remove.
- * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): Remove.
- * config/mips/t-iris6 (MULTILIB_OSDIRNAMES): Set.
- (SHLIB_SLIBDIR_SUFFIXES): Remove.
-
-2002-10-03 Jan Hubicka <jh@suse.cz>
-
- * predict.c (choose_function_section): Avoid choice for linkonce functions.
-
-2002-10-03 Jan Hubicka <jh@suse.cz>
-
- * i386.md (lea to mul peep2): Fix condition.
-
-2002-10-02 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa-linux.h (FUNCTION_OK_FOR_SIBCALL): Delete macro.
- * pa32-linux.h (FUNCTION_OK_FOR_SIBCALL): Define.
-
-2002-10-02 Richard Henderson <rth@redhat.com>
-
- PR opt/7124
- * config/i386/i386.c (ix86_register_move_cost): Increase cost
- for secondary_memory_needed pairs.
-
-2002-10-02 Nathanael Nerode <neroden@gcc.gnu.org>
-
- * doc/vms.texi: Blow away false include file section.
-
-2002-10-02 Roger Sayle <roger@eyesopen.com>
-
- PR optimization/6627
- * toplev.c (force_align_functions_log): New global variable.
- * flags.h (force_align_functions_log): Add extern prototype.
- * varasm.c (assemble_start_function): Use it to force minimum
- function alignment.
- * config/i386/i386.h (FUNCTION_BOUNDARY): Set the correct
- minimum function alignment to one byte.
- (TARGET_PTRMEMFUNC_VBIT_LOCATION): Store the virtual bit in
- the least significant bit of vtable member function pointers.
- * tree.h (enum ptrmemfunc_vbit_where_t): Move definition to
- here from cp/cp-tree.h.
-
-2002-10-02 Jan Hubicka <jh@suse.cz>
-
- * i386.c (print_operand_address): Use RIP addressing for offsetted
- label refs too.
-
-2002-09-30 David S. Miller <davem@redhat.com>
-
- PR middle-end/7151
- * config/sparc/sparc.md (movdi_insn_sp32_v9): Accept 'e' regs.
- (movdi reg/reg split): Match only on sparc32, and v9 when int regs.
-
-2002-10-01 Roger Sayle <roger@eyesopen.com>
-
- * unroll.c (loop_iterations): Revert 2002-09-08 change.
-
-2002-10-01 Richard Henderson <rth@redhat.com>
-
- * real.c (real_to_decimal): Crop trailing zeros for DIGITS < 0.
- (real_to_hexadecimal): Likewise.
- * print-rtl.c (print_rtx): If we are linked with real.c, don't
- dump the XWINT fields of a floating point CONST_DOUBLE.
-
-2002-10-01 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/vax/elf.h (FUNCTION_PROFILER): Fix __mcount call.
-
-2002-10-01 Richard Henderson <rth@redhat.com>
-
- * calls.c (precompute_register_parameters): Force non-legitimate
- constants into pseudos.
-
-2002-10-01 Nick Clifton <nickc@redhat.com>
-
- * config/rs6000/spe.md (spe_evrlwi): Add missing third operand
- to assembler template.
-
-2002-10-01 Richard Henderson <rth@redhat.com>
-
- * dwarf2out.c (loc_descriptor_from_tree): Relax requirement
- for TLS debug info to !DECL_EXTERNAL.
-
-2002-10-01 Matt Thomas <matt@3am-software.com>
- Jason Thorpe <thorpej@wasabisystems.com>
-
- * config.gcc (vax-*-netbsdelf*): Enable configuration.
- * config/elfos.h (PCC_BITFIELD_TYPE_MATTERS): Define only
- if not already defined.
- * config/vax/elf.h: New file.
- * config/vax/netbsd-elf.h: New file.
- * config/vax/vax.c: Include "debug.h".
- (vax_output_function_prologue): Add dwarf2 support. Use
- MAIN_NAME_P when checking for VMS_TARGET stack adjust.
- * config/vax/vax.h (CONST_OK_FOR_LETTER_P): Add cases for
- 'J' [0..63], 'K' [-128..127], 'L' [-32768..32767],
- 'M' [0..255], 'N' [0..65535], and, 'O' [-63..-1].
- (VAX_ISTREAM_SYNC): Remove.
- (INITIALIZE_TRAMPOLINE): Use gen_sync_istream.
- (JUMP_TABLES_IN_TEXT_SECTION): Define.
- (ASM_OUTPUT_REG_POP): Use reg_names for the stack pointer.
- (ASM_OUTPUT_ADDR_VEC_ELT): Use ASM_GENERATE_INTERNAL_LABEL
- and assemble_name.
- (ASM_OUTPUT_ADDR_DIFF_ELT): Likewise.
- (PRINT_OPERAND_PUNCT_VALID_P): Accept '|'.
- (PRINT_OPERAND): Output REGISTER_PREFIX for '|'.
- (INCOMING_RETURN_ADDR_RTX): Define.
- * config/vax/vax.md (VUNSPEC_BLOCKAGE)
- (VUNSPEC_SYNC_ISTREAM): Define.
- (blockage): Use VUNSPEC_BLOCKAGE.
- (sync_istream): New insn.
-
-2002-10-01 Richard Henderson <rth@redhat.com>
-
- * config/vax/vax.md (call_pop, *call_pop, call_value_pop)
- (*call_value_pop, call, call_value): Add dwarf2 EH support.
- (*call): New insn.
-
-2002-10-01 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c/8083
- * c-typeck.c (build_c_cast): Warn about type punning which breaks
- type based aliasing.
-
-2002-10-01 Mark Mitchell <mark@codesourcery.com>
-
- * stor-layout.c (update_alignment_for_field): New function.
- (place_union_field): Use it.
- (place_field): Likewise.
-
-2002-10-01 Nathan Sidwell <nathan@codesourcery.com>
-
- PR other/8077
- * gcc.c (cc1_options): Add space on -auxbase-strip.
-
-2002-10-01 Jim Wilson <wilson@redhat.com>
-
- * config/v850/v850.h (EPILOGUE_USES): Define.
-
-2002-09-30 Andrew Haley <aph@redhat.com>
-
- * flow.c (insn_dead_p): When using non-call-exceptions, don't
- eliminate insns that may trap.
- * cse.c (insn_live_p): Likewise.
-
-2002-10-01 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.h (PROCESSOR_R4121): Rename to PROCESSOR_R4120.
- (TARGET_MIPS4121): Rename to TARGET_MIPS4120.
- * config/mips/mips.c (mips_cpu_info): Rename vr4121 to vr4120.
- * config/mips/mips.md: Apply same renaming here.
-
-2002-10-01 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.c (PROCESSOR_R4320, TARGET_MIPS4320): Remove.
- (GENERATE_MULT3_SI): Remove use of TARGET_MIPS4320.
- * config/mips/mips.c (mips_cpu_info): Remove vr4320 entry.
- * config/mips/mips.md (define_attr cpu): Remove r4320.
- Remove vr4320 scheduler and uses of TARGET_MIPS4320.
-
-2002-10-01 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.c (mips16_strings): New variable.
- (mips_output_function_epilogue): Clear the SYMBOL_REF_FLAG of every
- symbol in mips16_strings. Free the list.
- (mips_encode_section_info): Keep track of local strings.
-
-2002-10-01 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.md (bunge, bltgt, bungt): New define_expands.
- (sordered_df, sordered_sf): Remove.
- * config/mips/mips.c (get_float_compare_codes): New fn.
- (gen_int_relational, gen_conditional_move): Use it.
-
-2002-10-01 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips-protos.h (mips_emit_fcc_reload): Declare.
- * config/mips/mips.h (PREDICATE_CODES): Add fcc_register_operand.
- * config/mips/mips.c (fcc_register_operand): New function.
- (mips_emit_fcc_reload): New function, extracted from reload_incc.
- (override_options): Allow TFmode values in float registers
- if ISA_HAS_8CC.
- * cnfig/mips/mips.md (reload_incc): Change destination prediate
- to fcc_register_operand. Remove misleading source constraint.
- Use mips_emit_fcc_reload.
- (reload_outcc): Duplicate reload_incc.
-
-2002-09-30 Ulrich Weigand <uweigand@de.ibm.com>
-
- * longlong.h: Partially synchronize with GMP-4.1 version:
- Use i370 definitions also for s390.
- Add generic definition of umul_ppmm in terms of smul_ppmm.
- [s390] (umul_ppmm): Remove.
- [s390] (smul_ppmm): Fix incorrect assembler constraints.
- [s390] (smul_ppmm, sdiv_qrnnd): Rename __xx to __x.
-
-2002-09-30 Bob Wilson <bob.wilson@acm.org>
-
- * config/xtensa/xtensa.h (REG_CLASS_NAMES, REG_CLASS_CONTENTS):
- Add new RL_REGS register class.
- (PREFERRED_RELOAD_CLASS, PREFERRED_OUTPUT_RELOAD_CLASS):
- Call xtensa_preferred_reload_class for both input and output reloads.
- * config/xtensa/xtensa.c (xtensa_regno_to_class): Use new RL_REGS class.
- (xtensa_preferred_reload_class): Handle output reloads; use RL_REGS
- instead of either AR_REGS or GR_REGS classes.
- (xtensa_secondary_reload_class): Use new RL_REGS class.
- * config/xtensa/xtensa-protos.h (xtensa_preferred_reload_class): Update.
-
-2002-09-30 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa.c (hppa_encode_label): Don't drop '*' from function labels.
- (pa_strip_name_encoding): Strip '@' and '*', in that order.
- * pa.h (ASM_OUTPUT_LABELREF): Output user_label_prefix except when
- there is a '*' prefix in NAME.
-
-2002-09-30 Jan Hubicka <jh@suse.cz>
-
- * reload.c (push_reload): Handle subregs and secondary memory.
- * reload1.c (gen_reload): Likewise.
-
- * jump.c (reg_or_subregno): New function.
- * rtl.h (reg_or_subregno): Declare
- * unroll.c (find_splittable_givs): Handle subregs.
-
-2002-09-30 Mark Mitchell <mark@codesourcery.com>
-
- * store-layout.c (finish_record_layout): Add free_p parameter.
- (layout_type): Pass it.
- * tree.h (finish_record_layout): Update prototype.
-
-2002-09-30 Jan Hubicka <jh@suse.cz>
-
- * i386.h (TARGET_CPP_CPU_BUILTINS): Define __SSE_MATH__.
-
- * gcse.c (cprop_jump): Check that the register has not
- been modified
- (cprop_jump): Likewise.
-
-2002-09-30 Richard Earnshaw <rearnsha@arm.com>
-
- * arm.h (BASE_REG_CLASS): Always return LO_REGS for Thumb.
- (MODE_BASE_REG_CLASS, case Thumb): Only return BASE_REGS if we know
- that we have a SImode access, and only then if reload hasn't completed;
- for all other cases, use LO_REGS.
-
-2002-09-29 Richard Henderson <rth@redhat.com>
-
- * real.c (real_from_string): Apply sign last. Tidy exponent handling.
-
-2002-09-29 Richard Henderson <rth@redhat.com>
-
- PR c/8002
- * combine.c (force_to_mode): Handle FLOAT_MODE destinations
- for CONST_INT.
-
-2002-09-29 David Edelsohn <edelsohn@gnu.org>
-
- * real.h (ibm_extended_format): Declare.
- * real.c (encode_ibm_extended, decode_ibm_extended): New
- functions.
-
-2002-09-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * darwin-protos.h (darwin_asm_output_dwarf_delta): Prototype.
-
- * ia64.c (ia64_hpux_asm_file_end): Const-ify.
-
-2002-09-29 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * expmed.c (extract_bit_field): Fix bit-field extraction from SUBREGs.
+2004-01-08 Stuart Hastings <stuart@apple.com>
-2002-09-29 Kazu Hirata <kazu@cs.umass.edu>
+ * config/i386/i386.md: Typos in MMX/SSE immediate shifts.
- * builtins.def: Fix comment formatting.
- * c-common.def: Likewise.
- * cfgcleanup.c: Likewise.
- * combine.c: Likewise.
- * gengtype.c: Likewise.
- * params.def: Likewise.
- * predict.def: Likewise.
- * rtl.def: Likewise.
- * stab.def: Likewise.
- * stor-layout.c: Likewise.
- * tree.def: Likewise.
- * config/darwin.c: Likewise.
- * config/darwin.h: Likewise.
- * config/dbxcoff.h: Likewise.
- * config/elfos.h: Likewise.
- * config/fp-bit.c: Likewise.
- * config/freebsd-spec.h: Likewise.
- * config/interix.h: Likewise.
- * config/libgloss.h: Likewise.
- * config/linux-aout.h: Likewise.
- * config/linux.h: Likewise.
- * config/lynx-ng.h: Likewise.
- * config/lynx.h: Likewise.
- * config/netbsd-aout.h: Likewise.
- * config/netbsd.h: Likewise.
- * config/netware.h: Likewise.
- * config/psos.h: Likewise.
- * config/ptx4.h: Likewise.
-
-2002-09-28 Kazu Hirata <kazu@cs.umass.edu>
-
- * ChangeLog.4: Fix typos.
- * ChangeLog.6: Likewise.
- * FSFChangeLog.10: Likewise.
- * genattrtab.c: Fix comment typos.
- * haifa-sched.c: Likewise.
- * real.c: Likewise.
- * tree.h: Likewise.
- * config/arm/arm.c: Likewise.
- * config/arm/crti.asm: Likewise.
- * config/arm/crtn.asm: Likewise.
- * config/frv/frv.c: Likewise.
- * config/frv/frv.md: Likewise.
- * config/h8300/h8300.md: Likewise.
- * config/i386/rtemself.h: Likewise.
- * config/ia64/unwind-ia64.c: Likewise.
- * config/ip2k/ip2k.h: Likewise.
- * config/m88k/m88k.c: Likewise.
- * config/m88k/m88k.md: Likewise.
- * config/mips/sr71k.md: Likewise.
- * config/mmix/mmix.c: Likewise.
- * config/rs6000/rs6000.c: Likewise.
- * config/sh/sh.md: Likewise.
-
-2002-09-26 Theodore A. Roth <troth@verinet.com>
-
- * config/avr/avr.c: Eliminate use of _PC_ in pc relative insns.
- * config/avr/avr.md: Ditto.
-
-2002-09-27 Alexander N. Kabaev <ak03@gte.com>
-
- PR preprocessor/8055
- * cppmacro.c (stringify_arg): Do not overflow the buffer
- with the terminating NUL when the argument to be stringified
- has no tokens.
-
-2002-09-27 Richard Henderson <rth@redhat.com>
-
- * unroll.c (simplify_cmp_and_jump_insns): New.
- (unroll_loop): Use it. Use simplify_gen_foo+force_operand
- instead of expand_simple_foo.
-
-2002-09-27 Richard Henderson <rth@redhat.com>
-
- PR optimization/7520
- * cfganal.c (flow_active_insn_p): New.
- (forwarder_block_p): Use it.
-
-2002-09-27 Richard Henderson <rth@redhat.com>
-
- * emit-rtl.c (active_insn_p): Revert last change.
-
-2002-09-27 Jakub Jelinek <jakub@redhat.com>
-
- * doc/extend.texi (tls_model): Document.
- * varasm.c (decl_tls_model): New.
- * c-common.c (handle_tls_model_attribute): New.
- (c_common_attribute_table): Add tls_model.
- * config/alpha/alpha.c (alpha_encode_section_info): Use
- decl_tls_model.
- * flags.h (enum tls_model, flag_tls_default): Move...
- * tree.h (enum tls_model, flag_tls_default): ...here.
- (decl_tls_model): New prototype.
- * config/ia64/ia64.c (ia64_encode_section_info): Likewise.
- * config/i386/i386.c (ix86_encode_section_info): Likewise.
- * config/i386/i386.md (tls_global_dynamic, tls_local_dynamic_base):
- Allow !flag_pic.
-
-2002-09-27 Kazu Hirata <kazu@cs.umass.edu>
-
- * LANGUAGES: Follow spelling conventions.
- * rtl.def: Likewise.
- * sbitmap.c: Likewise.
- * sched-int.h: Likewise.
- * sched-rgn.c: Likewise.
- * sibcall.c: Likewise.
- * simplify-rtx.c: Likewise.
- * ssa.c: Likewise.
- * stab.def: Likewise.
- * stmt.c: Likewise.
- * stor-layout.c: Likewise.
- * target.h: Likewise.
- * timevar.c: Likewise.
- * toplev.c: Likewise.
- * tree-dump.c: Likewise.
- * tree-inline.c: Likewise.
- * tree.c: Likewise.
- * tree.def: Likewise.
- * tree.h: Likewise.
- * unroll.c: Likewise.
- * varasm.c: Likewise.
- * vmsdbgout.c: Likewise.
- * treelang/treelang.texi: Likewise.
- * treelang/treetree.c: Likewise.
+2004-01-08 Jan Hubicka <jh@suse.cz>
-2002-09-27 Kazu Hirata <kazu@cs.umass.edu>
+ * cgraphunit.c (cgraph_decide_inlining): Fix typo.
- * config/h8300/h8300.c (compute_saved_regs): Use a macro
- instead of a hard register number.
- (get_shift_alg): Use an enumerated type instead of numbers.
- (h8300_shift_needs_scratch_p): Likewise.
+2004-01-08 Geoffrey Keating <geoffk@apple.com>
-2002-09-26 David S. Miller <davem@redhat.com>
+ * config/rs6000/rs6000.md (cmptf_internal1): Correct branch offset.
+ (UNSPEC_FIX_TRUNC_TF): New constant.
+ (movtf_internal): Make splitter active only when insn is active.
+ (extenddftf2): Rewrite to properly load zero into low part.
+ (extenddftf2_internal): New.
+ (extendsftf2): Rewrite.
+ (truncdftf2): Correct length.
+ (floatditf2): Delete.
+ (fix_trunc_helper): New.
+ (fix_trunctfdi2): Use fix_trunc_helper.
+ (fix_trunctfsi2): Likewise.fix_trunc
+ (fix_trunctfsi2_internal): New.
- PR optimization/7335
- * calls.c (emit_library_call_value_1): Passing args by reference
- converts a CONST function into a PURE one.
+ * config/rs6000/rs6000.c (legitimate_lo_sum_address_p): lo_sum
+ addresses are legitimate on Darwin even when flag_pic.
+ (rs6000_legitimize_reload_address) [TARGET_MACHO]: Don't create
+ non-offsettable addresses for loads of TFmode constants.
-2002-09-26 David Edelsohn <edelsohn@gnu.org>
+2004-01-08 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
- * dbxout.c (FORCE_TEXT): Switch to current_function_decl, not
- text_section.
- * xcoffout.h (DBX_STATIC_BLOCK_START): Remove explicit change to
- text section.
- * config/rs6000/rs6000.c (rs6000_override_options): Allow
- function-sections and data-sections functionality on AIX.
+ * config/m32r/m32r.h (ASM_OUTPUT_ALIGNED_BSS): Actually emit
+ variables in the appropriate bss section.
-2002-09-26 David Edelsohn <edelsohn@gnu.org>
- Dale Johannesen <dalej@apple.com>
+2004-01-09 Alan Modra <amodra@bigpond.net.au>
- * config/rs6000/rs6000.c (rs6000_emit_move): Insert zero-extend
- in RTL for sub-word loads from memory.
+ * config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Ensure
+ target_flags has MASK_POWERPC64 when -m64.
+ * config/rs6000/rs6000.c (processor_target_table): Add MASK_POWERPC64
+ to 620, 630, power3, power4 and rs64a entries.
+ * config/rs6000/rs6000.h (MASK_64BIT): Expand comment.
-2002-09-26 Richard Henderson <rth@redhat.com>
+2004-01-08 Richard Sandiford <rsandifo@redhat.com>
- PR c/7160
- * sched-deps.c (sched_analyze_insn): Make clobber insns depend
- on call insns.
+ * simplify-rtx.c (simplify_immed_subreg): Fix construction of
+ floating-point constants.
-2002-09-26 Richard Henderson <rth@redhat.com>
+2004-01-08 J. Brobecker <brobecker@gnat.com>
- * emit-rtl.c (const_double_htab_eq): Remove unused variable.
+ * dwarf2out.c (subrange_type_die): Add context_die parameter.
+ Create the subrange_type DIE using the given context DIE.
+ (modified_type_die): Update call to subrange_type_die.
-2002-09-26 Chris Lattner <sabre@nondot.org>
+2004-01-08 Zack Weinberg <zack@codesourcery.com>
- * ssa.c (rename_insn_1): Handle RENAME_NO_RTX correctly when
- handling undefined values.
+ * dwarf2.h, unwind-dw2-fde.h, unwind-pe.h, unwind.h:
+ Add multiple-include guard.
-2002-09-26 Richard Henderson <rth@redhat.com>
+2004-01-08 Hartmut Penner <hpenner@de.ibm.com>
- PR opt/7520
- * emit-rtl.c (active_insn_p): Consider a clobber of the
- function return value to be active even after reload.
+ * gcc/config/rs6000/rs6000.c (easy_vector_constant): Accept
+ all vector constant loadable by vsplt*.
+ (output_vec_const_move): Likewise.
-2002-09-27 Alan Modra <amodra@bigpond.net.au>
+2004-01-07 Joseph S. Myers <jsm@polyomino.org.uk>
- * doloop.c (doloop_modify_runtime <biv skips initial incr>): Adjust
- by absolute loop increment, not loop increment.
+ PR c/6024
+ * c-typeck.c (comptypes): Only treat enumerated types in the same
+ translation unit as compatible with each other when they are the
+ same type.
+ * doc/extend.texi: Update.
-2002-09-26 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-07 Joseph S. Myers <jsm@polyomino.org.uk>
- * c-common.h: Follow spelling conventions.
- * cpplex.c: Likewise.
- * cpplib.h: Likewise.
- * gthr-dce.h: Likewise.
- * gthr-posix.h: Likewise.
- * optabs.c: Likewise.
- * output.h: Likewise.
- * profile.c: Likewise.
- * protoize.c: Likewise.
- * ra-rewrite.c: Likewise.
- * real.c: Likewise.
- * recog.c: Likewise.
- * reg-stack.c: Likewise.
- * regclass.c: Likewise.
- * regmove.c: Likewise.
- * reload.c: Likewise.
- * reload.h: Likewise.
- * reload1.c: Likewise.
- * reorg.c: Likewise.
- * resource.c: Likewise.
- * rtl.h: Likewise.
- * rtlanal.c: Likewise.
+ PR c/12165
+ * c-decl.c (grokdeclarator): Take type qualifiers of typedefed
+ array type from the array element type.
-2002-09-26 Steve Ellcey <sje@cup.hp.com>
+2004-01-07 Alan Modra <amodra@bigpond.net.au>
- * config/ia64/ia64.c (ia64_expand_load_address): Ensure correct mode
- for symbol address.
+ * config/rs6000/rs6000.c (rs6000_dbx_register_number): New function.
+ * config/rs6000/rs6000-protos.h (rs6000_dbx_register_number): Declare.
+ * config/rs6000/rs6000.h (DWARF_FRAME_REGNUM): Define.
+ (DWARF_REG_TO_UNWIND_COLUMN): Correct column adjustment and comment.
+ * config/rs6000/sysv4.h (DBX_REGISTER_NUMBER): Define.
-2002-09-24 Eric Christopher <echristo@redhat.com>
+2004-01-06 Eric Christopher <echristo@redhat.com>
- * config/mips/elf.h: Add HANDLE_SYSV_PRAGMA.
+ * config/mips/mips.h (MDEBUG_ASM_SPEC): Change for dwarf2 default.
+ (DWARF2_DEBUGGING_INFO): Define.
+ (PREFERRED_DEBUGGING_TYPE): Set to dwarf2.
+ * config/mips/openbsd.h (PREFERRED_DEBUGGING_TYPE): Remove.
+ * config/mips/iris6.h (SUBTARGET_ASM_DEBUGGING_SPEC): Only pass -g0
+ for irix as.
+ (SUBTARGET_ASM_OPTIMIZING_SPEC): Only pass O0 for irix as.
+ * config/mips/iris6gas.h (MDEBUG_ASM_SPEC): Remove.
+ * config/mips/iris5gas.h: Ditto.
+ (DBX_DEBUGGING_INFO): Remove.
+ (DWARF2_DEBUGGING_INFO): Ditto.
+ (MIPS_DEBUGGING_INFO): Ditto.
+ (PREFERRED_DEBUGGING_TYPE): Ditto.
+ * config/mips/elf.h (DWARF2_DEBUGGING_INFO): Remove.
+ (PREFERRED_DEBUGGING_TYPE): Ditto.
+ (SUBTARGET_ASM_DEBUGGING_SPEC): Ditto.
* config/mips/elf64.h: Ditto.
-2002-09-24 Eric Christopher <echristo@redhat.com>
-
- * except.c (expand_builtin_extract_return_address): Handle case
- where Pmode != ptr_mode.
-
-2002-09-26 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/hpux.h (ASM_OUTPUT_EXTERNAL_LIBCALL): New
-
-2002-09-26 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/hpux.h (TARGET_DEFAULT): Include TARGET_ILP32.
-
-2002-09-26 Igor Shevlyakov <igor@microunity.com>
-
- * combine.c (simplify_set): Don't call to force_to_mode if size
- of integer type is larger than HOST_BITS_PER_WIDE_INT.
-
-2002-09-26 Janis Johnson <janis187@us.ibm.com>
-
- * Makefile.in (qmtest-g++): Fix file path.
-
-2002-09-26 Ulrich Weigand <uweigand@de.ibm.com>
-
- * expr.c (expand_expr) [MINUS_EXPR]: Convert A - const to
- A + (-const) on RTX level, even for unsigned types.
-
-2002-09-26 Ulrich Weigand <uweigand@de.ibm.com>
-
- * reload.c (dup_replacements): New function.
- (find_reloads): Use it to duplicate replacements at the top level
- of match_dup operands.
-
-2002-09-26 Miles Bader <miles@gnu.org>
-
- * v850.md ("length"): Change default value to 4.
-
-2002-09-26 Kazu Hirata <kazu@cs.umass.edu>
-
- * ChangeLog.1: Follow spelling conventions.
- * ChangeLog.4: Likewise.
- * ChangeLog.6: Likewise.
- * FSFChangeLog.11: Likewise.
- * doc/cpp.texi: Likewise.
- * doc/invoke.texi: Likewise.
- * doc/tm.texi: Likewise.
-
-2002-09-26 Nick Clifton <nickc@redhat.com>
-
- * config.gcc: Add x prefix to v850e case for handling
- --with-cpu=v850e.
-
-2002-09-25 David S. Miller <davem@redhat.com>
-
- PR target/7842
- * config/sparc/sparc.c (set_extends): SImode ASHIFT does not
- extend.
-
-2002-09-25 Richard Henderson <rth@redhat.com>
-
- * emit-rtl.c (const_double_htab_eq): Distinguish integer and
- fp CONST_DOUBLE; use real_identical.
-
-2002-09-25 Mark Mitchell <mark@codesourcery.com>
-
- * doc/invoke.texi: Add more -Wabi examples.
-
-2002-09-25 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.h (TARGET_MIPS4100): Add missing bracket.
-
-2002-09-24 Denis Chertykov <denisc@overta.ru>
-
- * config/ip2k/ip2k.c (function_epilogue): Fix wrong numbers in
- cases of optimizing "add sp,w" to "inc sp".
-
-2002-09-24 Adam Nemet <anemet@lnxw.com>
-
- * config/arm/arm.c (thumb_unexpanded_epilogue): Don't generate
- epilogue for naked functions.
+2004-01-06 Jan Hubicka <jh@suse.cz>
-2002-09-24 Adam Nemet <anemet@lnxw.com>
- Nick Clifton <nickc@redhat.com>
+ * Makefile.in (STAGEPROFILE_FLAGS_TO_PASS): Use -fprofile-generate.
+ (STAGEFEEDBACK_FLAGS_TO_PASS): Use -fprofile-use.
- * config/arm/arm.h (THUMB_FUNCTION_PROFILER): Remove.
- (FUNCTION_PROFILER): Only invoke THUMB_FUNCTION_PROFILER if it
- is defined.
+2004-01-06 Geoffrey Keating <geoffk@apple.com>
-2002-09-24 Ulrich Weigand <uweigand@de.ibm.com>
+ * config/rs6000/t-darwin (LIB2FUNCS_EXTRA): Compile darwin-ldouble.c.
+ (TARGET_LIBGCC2_CFLAGS): Use -mlong-double-128.
+ * config/rs6000/darwin-ldouble.c: New.
- * config/s390/s390.c (preferred_la_operand_p): New function.
- * config/s390/s390-protos.h (preferred_la_operand_p): Declare it.
- * config/s390/s390.md ("addaddr_esame", "*la_ccclobber"): Replace by ...
- ("*la_64_cc", "*la_31_cc", splitters): ... these.
- ("*la_31"): Deactivate for TARGET_64BIT.
- ("*la_31_and", "*la_31_and_cc"): New.
+ * emit-rtl.c (gen_lowpart_common): Use simplify_gen_subreg
+ for constants.
+ (constant_subword): Delete.
+ * rtl.h (constant_subword): Delete prototype.
+ (immed_double_const): Is not in varasm.c.
+ * simplify-rtx.c (simplify_immed_subreg): New.
+ (simplify_subreg): Use simplify_immed_subreg.
-2002-09-24 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+ * config/rs6000/rs6000.md (floatsitf2): Use expand_float rather
+ than trying to generate RTL directly.
+ (fix_trunctfsi2): Use expand_fix rather than trying to generate
+ RTL directly.
- * real.h (real_value): Make `exp' explicitly signed.
+ * dwarf2out.c (add_const_value_attribute): Remove incorrect comment.
-2002-09-24 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-06 David Edelsohn <edelsohn@gnu.org>
- * config/elfos.h: Follow spelling conventions.
- * config/alpha/alpha.h: Likewise.
- * config/arc/arc.h: Likewise.
- * config/arm/arm.md: Likewise.
- * config/avr/avr.h: Likewise.
- * config/cris/cris.md: Likewise.
- * config/d30v/d30v.h: Likewise.
- * config/frv/frv.c: Likewise.
- * config/frv/frv.h: Likewise.
- * config/h8300/h8300.c: Likewise.
- * config/h8300/h8300.h: Likewise.
- * config/h8300/h8300.md: Likewise.
- * config/i386/cygwin.h: Likewise.
- * config/i386/i386.h: Likewise.
- * config/i386/sysv3.h: Likewise.
- * config/i960/i960.h: Likewise.
- * config/ia64/ia64.h: Likewise.
- * config/ia64/ia64.md: Likewise.
- * config/ip2k/ip2k.h: Likewise.
- * config/m32r/m32r.h: Likewise.
- * config/m68k/m68k.h: Likewise.
- * config/m88k/m88k.h: Likewise.
- * config/mcore/mcore.c: Likewise.
- * config/mcore/mcore.h: Likewise.
- * config/mcore/mcore.md: Likewise.
- * config/mips/mips.h: Likewise.
- * config/mmix/mmix.h: Likewise.
- * config/mmix/mmix.md: Likewise.
- * config/ns32k/netbsd.h: Likewise.
- * config/ns32k/ns32k.h: Likewise.
- * config/ns32k/ns32k.md: Likewise.
- * config/pa/pa.h: Likewise.
- * config/romp/romp.h: Likewise.
- * config/rs6000/rs6000.h: Likewise.
- * config/rs6000/rs6000.md: Likewise.
- * config/sparc/sparc.h: Likewise.
- * config/stormy16/stormy-abi: Likewise.
- * config/stormy16/stormy16.h: Likewise.
- * config/vax/vax.h: Likewise.
-
-2002-09-23 Zack Weinberg <zack@codesourcery.com>
-
- * version.c (version_string): Now const char[].
- * version.h: Update to match.
-
-2002-09-23 Richard Henderson <rth@redhat.com>
-
- * config/i386/i386.h (MASK_ACCUMULATE_OUTGOING_ARGS_SET, MASK_MMX_SET,
- MASK_SSE_SET, MASK_SSE2_SET, MASK_3DNOW_SET, MASK_3DNOW_A_SET): Kill.
- (TARGET_SWITCHES): Don't reference them.
- * config/i386/i386.c (override_options): Use target_flags_explicit
- to examine bits set by the user.
-
-2002-09-23 Dale Johannesen <dalej@apple.com>
-
- * dbxout.c (dbxout_parms): Set current_sym_code for params
- passed on stack by invisible reference.
-
-2002-09-23 Richard Earnshaw <rearnsha@arm.com>
-
- * arm/unknown-elf.h (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Always allocate
- at least one byte of space.
-
-2002-09-23 Mark Mitchell <mark@codesourcery.com>
+ * config/rs6000/xcoff.h (EXTRA_SECTION_FUNCTIONS): Split each
+ function into a separate macro.
+ (read_only_data_section): Add void argument.
+ (private_data_section): Same.
+ (read_only_private_data_section): Same.
+ (toc_section): Same.
- * c-common.h (flag_abi_version): Fix typo in comment.
- * doc/invoke.texi (flag_abi_version): Document default value.
+2004-01-06 Jan Hubicka <jh@suse.cz>
-2002-09-23 Hans-Peter Nilsson <hp@axis.com>
+ * invoke.texi: Remove typo in last change.
- * doc/extend.texi (Extended Asm): Clarify that overlap between
- asm-declared register variables used in an asm and the asm clobber
- list is not allowed.
- * stmt.c (decl_conflicts_with_clobbers_p): New function.
- (expand_asm_operands): Keep track of clobbered registers. Call
- decl_conflicts_with_clobbers_p for each input and output operand.
- If no conflicts found before, also do conflict sanity check when
- emitting clobbers.
+ PR target/10301
+ * config.gcc: Accept opteron and athlon-64 as variants
+ of k8.
+ * i386.c (override_options): Likewise.
+ * invoke.texi (i386 -mtune): Expand documentation.
-2002-09-23 Richard Henderson <rth@redhat.com>
+2004-01-06 Kazu Hirata <kazu@cs.umass.edu>
- * c-common.c (cpp_define_data_format): Remove.
- (cb_register_builtins): Don't define __WCHAR_BIT__, __SHRT_BIT__,
- __INT_BIT__, __LONG_BIT__, __LONG_LONG_BIT__, __FLOAT_BIT__,
- __DOUBLE_BIT__, __LONG_DOUBLE_BIT__.
- * doc/cpp.texi: Don't document them either.
- (__SCHAR_MAX__, __SHRT_MAX__, __INT_MAX__, __LONG_MAX__,
- __LONG_LONG_MAX__): Document.
- (__TARGET_FLOAT_FORMAT__): Remove.
-
-2002-09-23 Richard Henderson <rth@redhat.com>
-
- * real.c (do_multiply): Normalize U before addition.
-
-2002-09-23 Mark Mitchell <mark@codesourcery.com>
-
- * c-common.c (flag_abi_version): New variable.
- * c-common.h (flag_abi_version): Declare it.
- * c-opts.c (missing_arg): Add -fabi-version.
- (c_common_decode_option): Process -fabi-version.
- * doc/invoke.texi (-fabi-version): Document it.
- (-Wabi): Add information about bit-fields in unions.
-
-2002-09-22 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/mips/netbsd.h (SUBTARGET_ASM_SPEC): Always pass -KPIC
- unless -fno-pic or -fno-PIC is specified.
-
-2002-09-22 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * c-common.c (preprocessing_trad_p): Define.
- * pa-hiux.h, pa-hpux.h, pa-hpux7.h (CPP_PREDEFINES): Delete.
- (TARGET_OS_CPP_BUILTINS, SUBTARGET_SWITCHES): Define.
- * pa-hpux10.h (TARGET_OS_CPP_BUILTINS, CPP_SPEC): Define.
- * pa-hpux11.h (TARGET_OS_CPP_BUILTINS): Define.
- * pa-linux.h (CPP_PREDEFINES): Delete.
- (TARGET_OS_CPP_BUILTINS, CPP_SPEC): Define.
- * pa32-linux.h, pa64-linux.h (CPP_SPEC): Delete.
- * pa-osf.h, pa-pro-end.h, rtems.h (CPP_PREDEFINES): Delete.
- (TARGET_OS_CPP_BUILTINS): Define.
- * pa.h (MASK_SIO, TARGET_SIO, TARGET_PA_10): Define.
- (TARGET_SWITCHES): Reformat. Use N_() macro. Add SUBTARGET_SWITCHES.
- (SUBTARGET_SWITCHES): Provide default definition.
- (TARGET_OPTIONS): Reformat. Use N_() macro.
- (CPP_PA10_SPEC, CPP_PA11_SPEC, CPP_PA20_SPEC, CPP_64BIT_SPEC,
- CPP_CPU_DEFAULT_SPEC, CPP_64BIT_DEFAULT_SPEC, SUBTARGET_EXTRA_SPECS,
- EXTRA_SPECS, CPP_SPEC, CPLUSPLUS_CPP_SPEC, CPP_PREDEFINES): Delete.
- (TARGET_CPU_CPP_BUILTINS): Define.
- (TARGET_OS_CPP_BUILTINS): Define for BSD-like systems.
- * doc/invoke.texi (msio, mwsio): Document new hppa options.
- * doc/tm.texi (TARGET_CPU_CPP_BUILTINS): Document macro
- preprocessing_trad_p().
-
-2002-09-22 Jason Thorpe <thorpej@wasabisystems.com>
-
- * doc/install.texi: Document behavior of --with-headers and
- --with-libs when arguments are omitted.
-
-2002-09-22 Kazu Hirata <kazu@cs.umass.edu>
-
- * dbxout.c: Follow spelling conventions.
- * defaults.h: Likewise.
+ * alias.c: Fix comment typos.
+ * builtins.c: Likewise.
+ * cfg.c: Likewise.
* df.c: Likewise.
- * diagnostic.h: Likewise.
- * doloop.c: Likewise.
+ * dominance.c: Likewise.
* dwarf2out.c: Likewise.
- * dwarfout.c: Likewise.
* emit-rtl.c: Likewise.
- * except.c: Likewise.
- * explow.c: Likewise.
- * expmed.c: Likewise.
* expr.c: Likewise.
- * expr.h: Likewise.
- * flags.h: Likewise.
- * flow.c: Likewise.
+ * final.c: Likewise.
* fold-const.c: Likewise.
- * function.c: Likewise.
- * function.h: Likewise.
- * gcc.c: Likewise.
- * gcov-io.h: Likewise.
- * gcov.c: Likewise.
* gcse.c: Likewise.
* genattrtab.c: Likewise.
- * genconfig.c: Likewise.
* genrecog.c: Likewise.
- * ggc-page.c: Likewise.
- * ggc.h: Likewise.
- * global.c: Likewise.
- * gthr-win32.h: Likewise.
+ * gensupport.c: Likewise.
+ * ggc-zone.c: Likewise.
* integrate.c: Likewise.
- * jump.c: Likewise.
- * langhooks.c: Likewise.
- * langhooks.h: Likewise.
- * line-map.h: Likewise.
* local-alloc.c: Likewise.
- * longlong.h: Likewise.
- * loop.c: Likewise.
- * loop.h: Likewise.
-
-2002-08-27 Jan Hubicka <jh@suse.cz>
-
- * i386.h (BIGGEST_FIELD_ALIGNMENT): Set proper default for x86_64.
-
-2002-08-27 Jan Hubicka <jh@suse.cz>
-
- * i386.c (overwrite_options): Set -mpreferred-stack-boundary to 128
- for -Os/TARGET_64BIT too.
-
-2002-09-21 Kazu Hirata <kazu@cs.umass.edu>
-
- * ChangeLog: Follow spelling conventions.
- * ChangeLog.0: Likewise.
- * ChangeLog.1: Likewise.
- * ChangeLog.2: Likewise.
- * ChangeLog.3: Likewise.
- * ChangeLog.4: Likewise.
- * ChangeLog.5: Likewise.
- * ChangeLog.6: Likewise.
- * FSFChangeLog.10: Likewise.
- * FSFChangeLog.11: Likewise.
- * alias.c: Likewise.
- * basic-block.h: Likewise.
- * c-aux-info.c: Likewise.
- * c-common.c: Likewise.
- * c-common.h: Likewise.
- * c-decl.c: Likewise.
- * c-format.c: Likewise.
- * c-semantics.c: Likewise.
- * c-typeck.c: Likewise.
- * calls.c: Likewise.
- * cfganal.c: Likewise.
- * cfgloop.c: Likewise.
- * collect2.c: Likewise.
- * combine.c: Likewise.
- * conflict.c: Likewise.
- * cppexp.c: Likewise.
- * cppfiles.c: Likewise.
- * cpphash.h: Likewise.
- * cppinit.c: Likewise.
- * cpplex.c: Likewise.
- * cpplib.c: Likewise.
- * cpplib.h: Likewise.
- * cppmacro.c: Likewise.
- * cse.c: Likewise.
-
-2002-09-21 Richard Earnshaw <rearnsha@arm.com>
-
- * netbsd-aout.h (NETBSD_LINK_SPEC_AOUT): New, takes old definition of
- LINK_SPEC.
- (LINK_SPEC): Define to NETBSD_LINK_SPEC_AOUT.
- * arm/netbsd.h (SUBTARGET_EXTRA_SEPCS): Add NETBSD_LINK_SPEC_AOUT.
- (LINK_SPEC): Rework to use NETBSD_LINK_SPEC_AOUT).
-
-2002-09-21 Richard Earnshaw <rearnsha@arm.com>
-
- PR opt/7930
- * cse.c (fold_rtx): Calculate old_cost before we fold each
- operand.
-
-2002-09-21 Richard Henderson <rth@redhat.com>
-
- * c-common.c (cpp_define_data_format): Remove __GCC_LITTLE_ENDIAN__,
- __GCC_BIG_ENDIAN__, __TARGET_BITS_ORDER__, __TARGET_BYTES_ORDER__,
- __TARGET_INT_WORDS_ORDER__, __TARGET_FLOAT_WORDS_ORDER__,
- __TARGET_USES_VAX_F_FLOAT__, __TARGET_USES_VAX_D_FLOAT__,
- __TARGET_USES_VAX_G_FLOAT__, __TARGET_USES_VAX_H_FLOAT__.
- * doc/cpp.texi: Don't document them.
-
-2002-09-21 Richard Henderson <rth@redhat.com>
-
- * c-common.c (builtin_define_float_constants): Use real_format
- to get the floating-point parameters.
-
-2002-09-21 Richard Henderson <rth@redhat.com>
-
- * real.c (struct real_format): Move to real.h.
- (real_format_for_mode): Rename from fmt_for_mode; update all users;
- initialize with ieee defaults.
- (real_to_target_fmt, real_from_target_fmt): New.
- (ieee_single_format, ieee_double_format, ieee_extended_motorola_format,
- ieee_extended_intel_96_format, ieee_extended_intel_128_format,
- ieee_quad_format, i370_single_format, i370_double_format,
- c4x_single_format, c4x_extended_format): Rename from s/_format//.
- (ieee_quad_format): Fix emin.
- (format_for_size, init_real_once): Remove.
- * real.h (struct real_format): Move from real.c.
- (real_format_for_mode): Declare.
- (real_to_target_fmt, real_from_target_fmt): Declare.
- (ieee_single_format, ieee_double_format, ieee_extended_motorola_format,
- ieee_extended_intel_96_format, ieee_extended_intel_128_format,
- ieee_quad_format, vax_f_format, vax_d_format, vax_g_format,
- i370_single_format, i370_double_format, c4x_single_format,
- c4x_extended_format): Declare.
- * toplev.c (do_compile): Don't call init_real_once.
-
- * defaults.h (INTEL_EXTENDED_IEEE_FORMAT): Remove.
- * doc/tm.texi (INTEL_EXTENDED_IEEE_FORMAT): Remove.
-
- * config/alpha/alpha.h (TARGET_FLOAT_FORMAT): Define.
- * config/alpha/osf5.h (LONG_DOUBLE_TYPE_SIZE): 64, if vax mode.
- * config/alpha/alpha.c (override_options): Set real_format_for_mode
- for VAX, if enabled.
-
- * config/c4x/c4x.c (c4x_override_options): Set real_format_for_mode
- for C4X.
-
- * config/i370/i370.h (OVERRIDE_OPTIONS): New.
- * config/i370/i370.c (override_options): New.
- * config/i370/i370-protos.h: Update.
-
- * config/i386/i386.c (override_options): Set real_format_for_mode
- for Intel 80-bit extended.
- * config/i386/i386.h (INTEL_EXTENDED_IEEE_FORMAT): Remove.
-
- * config/i960/i960.h (LONG_DOUBLE_TYPE_SIZE): Mind -mlong-double-64.
- (OVERRIDE_OPTIONS): Move code...
- * config/i960/i960.c (i960_initialize): ... here. Set
- real_format_for_mode for Intel 80-bit extended.
-
- * config/ia64/ia64.c (ia64_override_options): Set real_format_for_mode
- for Intel 80-bit extended, if enabled.
-
- * config/m68k/m68k.c (override_options): Set real_format_for_mode
- for Motorola 96-bit extended.
-
- * config/vax/vax.h (OVERRIDE_OPTIONS): New.
- * config/vax/vax.c (override_options): New.
- * config/vax/vax-protos.h: Update.
-
-2002-09-21 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.md (builtin_setjmp_receiver): Add
- #if TARGET_MACHO.
-
- * config/rs6000/rs6000.md (floatdisf2_internal2): Combine
- insns. Supply missing clobber of scratch reg.
-
-2002-09-20 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/m32r/m32r.c: Follow spelling conventions.
- * config/m32r/m32r.h: Likewise.
- * config/m32r/m32r.md: Likewise.
- * config/m68k/m68k.c: Likewise.
- * config/m88k/m88k.c: Likewise.
- * config/mcore/mcore.c: Likewise.
- * config/mips/mips.c: Likewise.
- * config/mips/mips.h: Likewise.
- * config/mmix/mmix.c: Likewise.
- * config/mn10200/mn10200.c: Likewise.
- * config/ns32k/ns32k.h: Likewise.
- * config/pa/pa.c: Likewise.
- * config/pa/pa64-linux.h: Likewise.
- * config/pdp11/pdp11.h: Likewise.
- * config/romp/romp.c: Likewise.
- * config/romp/romp.h: Likewise.
- * config/rs6000/eabi.asm: Likewise.
- * config/rs6000/linux64.h: Likewise.
- * config/rs6000/rs6000.c: Likewise.
- * config/rs6000/rs6000.h: Likewise.
- * config/rs6000/rs6000.md: Likewise.
- * config/rs6000/sysv4.h: Likewise.
- * config/rs6000/xcoff.h: Likewise.
-
-2002-09-20 Jim Wilson <wilson@redhat.com>
-
- * config/v850/v850/lib1funcs.asm (__muldi3): Change r5 to r28.
-
-2002-09-20 Jakub Jelinek <jakub@redhat.com>
-
- * config/i386/i386.md (UNSPEC_GOTNTPOFF, UNSPEC_INDNTPOFF): New.
- * config/i386/i386.c (legitimate_pic_address_disp_p): Handle
- UNSPEC_GOTNTPOFF and UNSPEC_INDNTPOFF like UNSPEC_GOTTPOFF.
- (legitimate_address_p): Likewise.
- (legitimize_address): Use @gotntpoff and @indntpoff.
- (output_pic_addr_const): Handle UNSPEC_GOTNTPOFF and UNSPEC_INDNTPOFF.
- (output_addr_const_extra): Likewise.
-
-2002-09-20 Jim Wilson <wilson@redhat.com>
-
- * combine.c (try_combine): When split an instruction pair, where the
- first has a sign_extend src, verify that the src and dest modes match.
-
-2002-09-20 Richard Henderson <rth@redhat.com>
-
- * config/mips/mips.c (dfhigh, dflow, sfhigh, sflow): Remove.
- (override_options): Do not initialize them.
- (mips_const_double_ok): Allow no fp constants except zero,
- and not even that for mips16.
- (const_float_1_operand): Use dconst1.
- * config/mips/mips.md (movsf, movsf_internal1, movsf_internal2,
- movdf, movdf_internal1, movdf_internal1a, movdf_internal2):
- Don't allow arbitrary constants; fix predicates and C constraint.
-
-2002-09-20 Neil Booth <neil@daikokuya.co.uk>
-
- * cppmacro.c: Don't warn about function-like macros without
- '(' during pre-expansion.
-
-2002-09-20 Jim Wilson <wilson@redhat.com>
-
- * config/v850/v850.c (current_function_anonymous_args): Delete.
- (expand_prologue): Use current_function_args_info.anonymous_args.
- (expand_epilogue): Delete use of current_function_anonymous_args.
- * config/v850/v850.h (struct cum_arg): Add anonymous_args field.
- (INIT_CUMULATIVE_ARGS): Clear anonymous_args field.
- (current_function_anonymous_args): Delete extern declaration.
- (SETUP_INCOMING_VARARGS): Set anonymous_args field.
-
-2002-09-20 Geoffrey Keating <geoffk@apple.com>
-
- * config/rs6000/rs6000.c (rs6000_emit_prologue): Update for change
- to load_macho_picbase.
- * config/rs6000/rs6000.md: Document Darwin-specific unspec IDs.
- (load_macho_picbase): Take the symbol to use as a parameter.
- (macho_correct_pic): New insn.
- (builtin_setjmp_reciever): On Darwin, restore the PIC register.
-
- * config/rs6000/rs6000.h (ELIMINABLE_REGS): Use
- RS6000_PIC_OFFSET_TABLE_REGNUM rather than hardcoding 30.
- (CAN_ELIMINATE): Likewise.
- (INITIAL_ELIMINATION_OFFSET): Likewise.
- (TOC_REGISTER): Likewise.
-
-2002-09-20 Richard Henderson <rth@redhat.com>
-
- * real.c (real_hash): New.
- * real.h: Declare it.
- * cse.c (canon_hash): Use it.
- * cselib.c (hash_rtx): Likewise.
- * emit-rtl.c (const_double_htab_hash): Likewise.
- * rtl.h (CONST_DOUBLE_REAL_VALUE): New.
- * varasm.c (struct rtx_const): Reduce vector size; separate
- integer and fp vectors.
- (HASHBITS): Remove.
- (const_hash_1): Rename from const_hash. Use real_hash. Do not
- take modulus MAX_HASH_TABLE.
- (const_hash): New. Do take modulus MAX_HASH_TABLE.
- (output_constant_def): Do not take modulus MAX_HASH_TABLE.
- (SYMHASH): Don't use HASHBITS.
- (decode_rtx_const): Copy only active bits from REAL_VALUE_TYPE.
- Fix CONST_VECTOR thinko wrt fp vectors. Fix kind comparison.
- (simplify_subtraction): Fix kind comparison.
- (const_hash_rtx): Return unsigned int. Don't use HASHBITS.
- Use a union to pun integer array.
- * config/rs6000/rs6000.c (rs6000_hash_constant): Use real_hash;
- only hash two words of integral CONST_DOUBLE.
-
-2002-09-20 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/hpux.h (STARTFILE_SPEC): Modify.
- (STARTFILE_PREFIX_SPEC): New.
- (LINK_SPEC): Modify.
- (LIB_SPEC): Modify.
- (LIBGCC_SPEC): New.
-
-2002-09-20 Jakub Jelinek <jakub@redhat.com>
-
- * config/i386/i386.c (legitimate_pic_address_disp_p): Allow
- UNSPEC_NTPOFF and UNSPEC_DTPOFF to be offsetted by constant.
-
-2002-09-20 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
-
- * config/arm/arm.md (sign_extract_onebit, not_signextract_onebit):
- Add clobber of the condition code register.
-
-2002-09-20 Richard Henderson <rth@redhat.com>
-
- * real.c (do_fix_trunc): Static.
- (encode_ieee_single, encode_ieee_double, encode_ieee_extended,
- encode_ieee_quad, encode_vax_f, encode_vax_d, encode_vax_g,
- encode_i370_single, encode_i370_double, encode_c4x_single,
- encode_c4x_extended): Add default abort case.
-
-2002-09-20 Richard Henderson <rth@redhat.com>
-
- * real.h (enum real_value_class, SIGNIFICAND_BITS, EXP_BITS,
- MAX_EXP, SIGSZ, SIG_MSB, struct real_value): Move from real.c.
- (struct realvaluetype): Remove.
- (REAL_VALUE_TYPE): Use struct real_value.
- (REAL_VALUE_TYPE_SIZE): Use SIGNIFICAND_BITS.
- (test_real_width): New.
- * real.c: Global replace struct real_value with REAL_VALUE_TYPE.
- (real_arithmetic): Avoid hoops for REAL_VALUE_TYPE parameters.
- (real_compare, real_exponent, real_ldexp, real_isinf, real_isnan,
- real_isneg, real_isnegzero, real_identical, exact_real_inverse,
- real_to_integer, real_to_integer2, real_to_decimal,
- real_to_hexadecimal, real_from_string, real_from_integer,
- real_inf, real_nan, real_2expN, real_convert, real_to_target,
- real_from_target): Likewise.
- * tree.h (struct tree_real_cst): Use real_value not realvaluetype.
- * gengtype-yacc.y (bitfieldopt): Accept an ID as well.
-
-2002-09-20 Richard Henderson <rth@redhat.com>
-
- * real.h (UNKNOWN_FLOAT_FORMAT, IEEE_FLOAT_FORMAT, VAX_FLOAT_FORMAT,
- IBM_FLOAT_FORMAT, C4X_FLOAT_FORMAT, TARGET_FLOAT_FORMAT): Move ...
- * defaults.h: ... here.
- * config/arm/arm.h, config/avr/avr.h, config/d30v/d30v.h,
- config/fr30/fr30.h, config/frv/frv.h, config/ia64/ia64.h,
- config/ip2k/ip2k.h, config/mips/mips.h, config/stormy16/stormy16.h,
- config/xtensa/xtensa.h (TARGET_FLOAT_FORMAT): Remove.
-
-2002-09-20 Hans-Peter Nilsson <hp@bitrange.com>
-
- * config/mmix/mmix.md ("negdf2"): Rewrite.
- ("*expanded_negdf2"): New.
-
-2002-09-19 Jim Wilson <wilson@redhat.com>
-
- * combine.c (simplify_set): When optimizing a subreg src with a
- cc0 dest, use GET_MODE (src) for mask instead of inner_mode.
-
-2002-09-19 Dale Johannesen <dalej@apple.com>
- * combine.c (make_extraction): Don't create
- invalid subreg.
-
-2002-09-19 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c (addr_generation_dependency_p): Handle SUBREG
- and STRICT_LOW_PART within SET_DEST.
- * config/s390/s390.md ("*extractqi", "*extracthi"): New insns with
- splitters, replacing pre-reload splitters.
- ("*zero_extendhisi2_31", "*zero_extendqisi2_31",
- "*zero_extendqihi2_31"): New insns.
- ("*zero_extendqihi2_64"): Do not clobber CC.
-
-2002-09-19 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/hpux.h (CTORS_SECTION_ASM_OP): New.
- (DTORS_SECTION_ASM_OP): Ditto.
- (READONLY_DATA_SECTION_ASM_OP): Moved.
- (DATA_SECTION_ASM_OP): New.
- (SDATA_SECTION_ASM_OP): New.
- (BSS_SECTION_ASM_OP): New.
- (SBSS_SECTION_ASM_OP): New.
- (TEXT_SECTION_ASM_OP): New.
-
-2002-09-19 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/fp-bit.c: Follow spelling conventions.
- * config/d30v/d30v.c: Likewise.
- * config/d30v/d30v.h: Likewise.
- * config/fr30/fr30.c: Likewise.
- * config/fr30/fr30.h: Likewise.
- * config/fr30/fr30.md: Likewise.
- * config/frv/frv.c: Likewise.
- * config/frv/frv.h: Likewise.
- * config/h8300/h8300.c: Likewise.
- * config/h8300/lib1funcs.asm: Likewise.
- * config/i370/i370.c: Likewise.
- * config/i386/i386.h: Likewise.
- * config/i386/i386.md: Likewise.
- * config/i386/pentium.md: Likewise.
- * config/i386/winnt.c: Likewise.
- * config/i960/i960.c: Likewise.
- * config/ia64/ia64.h: Likewise.
- * config/ip2k/ip2k.c: Likewise.
- * config/ip2k/ip2k.h: Likewise.
- * config/ip2k/ip2k.md: Likewise.
- * config/ip2k/libgcc.S: Likewise.
-
-2002-09-19 Stephen Clarke <stephen.clarke@superh.com>
-
- * config/sh/sh.h (UNSPEC_GOTOFF_P): Define.
- (GOTOFF_P): Extend to allow gotoff plus constant.
-
-2002-09-18 Richard Henderson <rth@redhat.com>
-
- * ifcvt.c (noce_process_if_block): Correctly detect X modified
- with INSN_B before COND_EARLIEST. Don't check A and B for
- modification in condition range. Reorder INSN_B for A==B properly.
- (if_convert): Iterate until no matches for a block.
-
-2002-09-18 Richard Henderson <rth@redhat.com>
-
- * calls.c (store_one_arg): Rename default_align to parm_align;
- always adjust parm_align for downward padding.
-
-2002-09-18 Richard Henderson <rth@redhat.com>
-
- * toplev.c (backend_init): Move init_real_once invocation ...
- (do_compile): ... here.
-
-2002-09-18 Richard Henderson <rth@redhat.com>
-
- * sibcall.c (optimize_sibling_and_tail_recursive_call): Also remove
- RTX_UNCHANGING_P markers for successful tail-recursive replacement.
-
-2002-09-18 Richard Henderson <rth@redhat.com>
-
- * real.c (round_for_format): Collect sticky as unsigned long, not bool.
-
-2002-09-19 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.md: (floatdisf2): Rename to
- floatdisf2_internal1.
- (floatdisf2): New define_expand.
- (floatdisf2_internal2): Likewise.
-
-2002-09-18 Richard Henderson <rth@redhat.com>
-
- * real.c (sticky_rshift_significand): Collect sticky as
- unsigned long, not bool.
-
-2002-09-18 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c (s390_address_cost): New function.
- config/s390/s390-protos.h (s390_address_cost): Add prototype.
- config/s390/s390.h (ADDRESS_COST): Call s390_address_cost.
- (RTX_COST): Use COSTS_N_INSNS.
-
-2002-09-18 Douglas Rupp <rupp@gnat.com>
- Donn Terry <donnte@microsoft.com>
-
- * stor-layout.c (place_field): Handle alignment of whole
- structures when MSVC compatible bitfields are involved.
- Change method of computing location of MS bitfields to
- be compatible with #pragma pack(n).
-
- * tree.h (record_layout_info): Add new field
- remaining_in_alignment.
-
- * doc/tm.texi: (TARGET_MS_BITFIELD_LAYOUT_P): Update.
- (pragma pack): Add paragraph on MSVC bit-field packing.
-
-2002-09-18 Richard Earnshaw (reanrsha@arm.com)
-
- PR optimization/7967
- * arm.md (ne_zeroextractsi): Add clobber of the condition code
- register.
-
-2002-09-18 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/s390/s390.c: Follow spelling conventions.
- * config/sh/lib1funcs.asm: Likewise.
- * config/sh/sh.c: Likewise.
- * config/sh/sh.h: Likewise.
- * config/sparc/sparc.c: Likewise.
- * config/sparc/sparc.h: Likewise.
- * config/sparc/sparc.md: Likewise.
- * config/stormy16/stormy16.c: Likewise.
- * config/stormy16/stormy16.h: Likewise.
- * config/v850/v850.c: Likewise.
- * config/v850/v850.h: Likewise.
- * config/vax/vax.c: Likewise.
- * config/vax/vax.h: Likewise.
-
-2002-09-18 Nick Clifton <nickc@redhat.com>
-
- * config/rs60000/rs6000.c (rs6000_emit_move): Handle V1DImode moves.
- * config/rs60000/rs6000.c (SPE_VECTOR_MODE): Include V1DImode.
- * config/rs6000/spe.md (movv1di, movv1di_internal): New patterns.
-
-2002-09-17 Zack Weinberg <zack@codesourcery.com>
-
- * ABOUT-GCC-NLS: Remove reference to enquire, and out-of-date
- statement that the only translation is to en_UK.
-
-2002-09-17 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/alpha/alpha.c: Follow spelling conventions.
- * config/alpha/alpha.h: Likewise.
- * config/alpha/alpha.md: Likewise.
- * config/arc/arc.h: Likewise.
- * config/arm/arm.c: Likewise.
- * config/arm/arm.h: Likewise.
- * config/arm/arm.md: Likewise.
- * config/arm/pe.c: Likewise.
- * config/arm/unknown-elf.h: Likewise.
- * config/avr/avr.c: Likewise.
- * config/avr/avr.h: Likewise.
- * config/c4x/c4x.c: Likewise.
- * config/cris/cris.c: Likewise.
- * config/cris/cris.h: Likewise.
-
-2002-09-17 Samuel Figueroa <figueroa@apple.com>
-
- * final.c (final_scan_insn): Use new macro ASM_OUTPUT_ALIGN_WITH_NOP.
- * config/sparc/sparc.h (ASM_OUTPUT_ALIGN_WITH_NOP) New macro.
- * doc/tm.texi (ASM_OUTPUT_ALIGN_WITH_NOP) New description.
-
-2002-09-17 Dale Johannesen <dalej@apple.com>
-
- * cfgcleanup.c (try_forward_edges): Do not forward a
- branch to just after a loop exit before loop optimization;
- this interfered with doloop detection.
-
-2002-09-17 Nick Clifton <nickc@redhat.com>
-
- * config/arm/arm.c (output_return_instruction): Do not
- writeback the stack pointer when it is being loaded.
- (arm_output_epilogue): Likewise.
-
-2002-09-17 Kazu Hirata <kazu@cs.umass.edu>
-
- * optabs.c (prepare_cmp_insn): Let emit_library_call_value
- generate a pseudo reg that receives the result of a libcall.
- (prepare_float_lib_cmp): Likewise.
-
-2002-09-17 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/elf.h: Remove CPP_PREDEFINES.
-
-2002-09-17 Nicola Pero <n.pero@mi.flashnet.it>
-
- Fix PR/7014 and related objc bugs:
- * c-typeck.c (comp_target_types): Added a reflexive argument.
- Pass it to ObjC when/if calling objc_comptypes(). Updated all
- callers to provide the appropriate reflexive argument.
- * objc/objc-act.c (objc_comptypes): Carefully checked and fixed
- typechecking for all cases of comparisons and assignments,
- particularly the obscure and less common ones involving protocols.
-
-2002-09-17 Nick Clifton <nickc@redhat.com>
-
- * machmode.def (V1DImode): New mode. A single element vector.
- * tree.h (TI_UV1DI_TYPE, TI_V1DI_TYPE): New tree_index enums.
- (unsigned_V1DI_type_node, V1D1_type_node): New type nodes.
- * tree.c (build_common_tree_nodes_2): Build
- unsigned_V1DI_type_node and V1D1_type_node.
- * c-common.c (c_common_type_for_mode): Return
- unsigned_V1DI_type_node or V1D1_type_node for V1DImode.
- * rtl.c (class_narrowest_): Start integer vector nodes with V1DImode.
-
-2002-09-17 Nicola Pero <n.pero@mi.flashnet.it>
-
- * doc/objc.texi (Constant string objects): Extended documentation
- to make clear that the constant string class ivar layout is
- completely fixed.
-
-2002-09-17 Roger Sayle <roger@eyesopen.com>
-
- * cfgrtl.c (flow_delete_block_noexpunge): Delete orphaned
- NOTE_INSN_LOOP_CONT notes when deleting basic blocks.
-
-2002-09-16 Richard Henderson <rth@redhat.com>
-
- * expr.c (emit_block_move): Set memory block size as appropriate
- for the copy.
-
-2002-09-16 Richard Henderson <rth@redhat.com>
-
- PR fortran/3924
- * sdbout.c (sdbout_symbol): Don't handle offsets from a symbol.
-
-2002-09-16 Richard Henderson <rth@redhat.com>
-
- * emit-rtl.c (set_mem_attributes_minus_bitpos): Adjust SIZE
- as well as OFFSET for BITPOS.
-
-2002-09-16 Jeff Garzik <jgarzik@mandrakesoft.com>
-
- * config.gcc: Treat winchip_c6-*|winchip2-*|c3-* as pentium-mmx.
- * config/i386/i386.c (processor_alias_table): Add winchip-c6,
- winchip2 and c3.
- * doc/invoke.texi: Mention new aliases.
-
-2002-09-16 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * calls.c (store_one_arg): Set default alignment for BLKmode arguments
- to BITS_PER_UNIT when ARGS_GROW_DOWNWARD and the padding direction is
- downward.
- * function.c (pad_below): Always compile.
- (locate_and_pad_parm): If defined ARGS_GROW_DOWNWARD, pad argument to
- alignment when it is not in a register or REG_PARM_STACK_SPACE is true.
- Pad below when the argument is not in a register and the padding
- direction is downward.
-
- * pa-64.h (MUST_PASS_IN_STACK): Move define to pa.h.
- (PAD_VARARGS_DOWN): Define.
- * pa.c (function_arg_padding): Revise padding directions to make them
- compatible with the 32 and 64-bit runtime architecture documentation.
- (hppa_va_arg): Add code to handle variable and size zero arguments
- passed by reference on TARGET_64BIT. Reformat.
- (function_arg): Use a PARALLEL for BLKmode and aggregates args on
- TARGET_64BIT. Use a DImode PARALLEL for BLKmode args 5 to 8 bytes
- wide when !TARGET_64BIT. Move forward check for mode==VOIDmode.
- Add comments.
- * pa.h (MAX_PARM_BOUNDARY): Correct define for TARGET_64BIT.
- (RETURN_IN_MEMORY): Return size zero types in memory.
- (FUNCTION_VALUE): Return TFmode in general registers.
- (MUST_PASS_IN_STACK): Define.
- (FUNCTION_ARG_BOUNDARY): Simplify.
- (FUNCTION_ARG_PASS_BY_REFERENCE): Pass variable and zero sized types
- by reference.
- (FUNCTION_ARG_CALLEE_COPIES): Define to FUNCTION_ARG_PASS_BY_REFERENCE.
-
-2002-09-16 Richard Henderson <rth@redhat.com>
-
- * real.c (do_fix_trunc): New.
- (real_arithmetic): Call it.
- * simplify-rtx.c (simplify_unary_operation): Handle FIX
- with a floating-point result mode.
-
-2002-09-16 Richard Henderson <rth@redhat.com>
-
- * builtin-types.def (BT_FN_FLOAT_CONST_STRING): New.
- (BT_FN_DOUBLE_CONST_STRING, BT_FN_LONG_DOUBLE_CONST_STRING): New.
- * builtins.def (__builtin_nan, __builtin_nanf, __builtin_nanl): New.
- (__builtin_nans, __builtin_nansf, __builtin_nansl): New.
- * builtins.c (fold_builtin_nan): New.
- (fold_builtin): Call it.
- * real.c (real_nan): Parse a non-empty string.
- (round_for_format): Fix NaN significand truncation.
- * real.h (real_nan): Return bool.
- * doc/extend.texi: Document new builtins.
-
-2002-09-16 Jason Merrill <jason@redhat.com>
- Danny Smith <dannysmith@users.sourceforge.net>
-
- * config/i386/winnt.c (ix86_handle_dll_attribute): Set
- DECL_EXTERN and TREE_PUBLIC for dllimported variables here...
- (i386_pe_mark_dllimport): Not here.
-
-2002-09-16 Nathan Sidwell <nathan@codesourcery.com>
-
- * c-semantics.c (genrtl_do_stmt): Cope with NULL cond.
-
-2002-09-16 Geoffrey Keating <geoffk@redhat.com>
-
- * config/rs6000/rs6000.c (build_mask64_2_operands): Suppress
- warnings about unused operands when HOST_BITS_PER_WIDE_INT is
- < 64.
- (rs6000_emit_cmove): Use real_isinf not target_isinf.
-
-2002-09-16 Kazu Hirata <kazu@cs.umass.edu>
-
- * calls.c (emit_library_call_value_1): Don't refer to
- hard_libcall_value.
- * optabs.c (prepare_float_lib_cmp): Likewise.
-
-2002-09-16 Geoffrey Keating <geoffk@apple.com>
-
- * ggc-common.c (ggc_mark_rtx_children_1): Update for changed name
- mangling.
-
- The following changes are merged from pch-branch:
-
- * doc/gty.texi (GTY Options): Document %a.
- * gengtype.c (do_scalar_typedef): New function.
- (process_gc_options): Handle `length' option.
- (set_gc_used_type): A pointer to an array of structures doesn't
- qualify as a pointer to a structure.
- (output_escaped_param): Add `%a' escape.
- (write_gc_structure_fields): Allow 'desc' on array of unions.
- (main): Define `uint8', `jword' and `JCF_u2' as scalars; use
- do_scalar_typedef.
-
- * gengtype.c (enum rtx_code): Make global.
- (rtx_format): Make global.
- (rtx_next): New.
- (gen_rtx_next): New.
- (write_rtx_next): New.
- (adjust_field_rtx_def): Skip fields marked by chain_next.
- (open_base_files): Delete redundant prototype.
- (write_enum_defn): New.
- (output_mangled_typename): Correct abort call.
- (write_gc_marker_routine_for_structure): Handle chain_next and
- chain_prev options.
- (finish_root_table): Don't output redundant \n.
- (main): Call gen_rtx_next, write_rtx_next, write_enum_defn.
- * c-tree.h (union lang_tree_node): Add chain_next option.
-
- * gengtype.h (NUM_PARAM): New definition.
- (struct type): For TYPE_PARAM_STRUCT, allow multiple parameters.
- * gengtype.c (find_param_structure): New.
- (adjust_field_type): Handle param<n>_is option.
- (process_gc_options): Detect use_params option. Update callers.
- (set_gc_used_type): Add 'param' parameter, update callers. Handle
- 'use_params' option.
- (open_base_files): Add splay-tree.h to list of files included.
- (output_mangled_typename): New.
- (write_gc_structure_fields): Update 'param' parameter to support
- multiple parameters. Change name mangling. Allow parameterized
- fields to have an apparent scalar type. Handle param<n>_is options,
- use_param option.
- (write_gc_marker_routine_for_structure): Update for change to name
- mangling. Better guess the output file for parameterized types.
- (write_gc_types): Update for change to name mangling.
- (write_gc_root): Update for change to name mangling. Handle (ignore)
- param<n>_is options.
- * doc/gty.texi (GTY Options): Add description of param<n>_is
- options, use_params option.
- * ggc.h (ggc_mark_rtx): Update for changed name mangling.
- * gengtype-lex.l: Produce token for param<n>_is.
- * gengtype-yacc.y: Parse param<n>_is.
-
- * gengtype.c (adjust_field_tree_exp): Don't name a variable 'rindex'.
-
- * rtl.c: Update comment describing rtx_format.
- * rtl.h (union rtunion): Separate definition and typedef.
- (struct rtx_def): Use gengtype to mark.
- * Makefile.in (gengtype.o): Also depend on rtl.def.
- * ggc.h (ggc_mark_rtx_children): Delete prototype.
- (ggc_mark_rtx): Change to alias of gengtype-generated routine.
- * ggc-common.c (ggc_mark_rtx_children): Delete.
- (ggc_mark_rtx_children_1): Delete.
- (gt_ggc_m_rtx_def): Delete.
- * gengtype.c (adjust_field_rtx_def): New.
- (adjust_field_type): Call adjust_field_rtx_def.
- (write_gc_structure_fields): Add 'default' case to switch if none
- is specified; remove unused code.
-
- * tree.h (struct tree_exp): Update for change to meaning
- of special.
- * gengtype.c (adjust_field_tree_exp): New function.
- (adjust_field_type): Handle `tree_exp' special here.
- (write_gc_structure_fields): Don't handle `tree_exp' special here.
- Handle new `dot' option.
-
- * gengtype.h: Make `info' a pointer-to-const.
- * gengtype-yacc.y (yacc_ids): Use xasprintf.
-
- * gengtype.c (write_gc_structure_fields): Remove implementation
- of `always' option, add `default' option.
- * doc/gty.texi (GTY Options): Remove documentation of `always',
- add `default'.
-
-2002-09-16 Hans-Peter Nilsson <hp@bitrange.com>
-
- * output.h: Remove #ifdef RTX_CODE and #ifdef TREE_CODE.
-
-2002-09-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * m68hc11.md (addhi_sp): Fix uninitialized variable bug.
-
- * c4x-c.c, c4x.c, darwin.c, i370-c.c, m32r.c: Include tm_p.h
- instead of the *-protos.h file directly.
- * t-c4x, t-i370, t-v850: Depend on $(TM_P_H).
- * darwin.c (machopic_output_stub): Move prototype ...
- * darwin-protos.h (machopic_output_stub): ... here.
- * rs6000-protos.h (machopic_output_stub): Don't declare.
-
-2002-09-16 Richard Henderson <rth@redhat.com>
-
- * c-common.c (builtin_define_float_constants): Emit __FOO_DENORM_MIN__.
-
-2002-09-16 Richard Henderson <rth@redhat.com>
-
- * real.c, real.h: Rewrite from scratch.
-
- * Makefile.in (simplify-rtx.o): Depend on TREE_H.
- (paranoia): New target.
- * builtins.c (fold_builtin_inf): Use new real.h interface.
- * c-common.c (builtin_define_with_hex_fp_value): Likewise.
- * c-lex.c (interpret_float): Likewise.
- * emit-rtl.c (gen_lowpart_common): Likewise.
- * optabs.c (expand_float): Use real_2expN.
- * config/ia64/ia64.md (divsi3, udivsi3): Likewise.
- * defaults.h (INTEL_EXTENDED_IEEE_FORMAT): New.
- (FLOAT_WORDS_BIG_ENDIAN): New.
- * cse.c (find_comparison_args): Don't pass FLOAT_STORE_FLAG_VALUE
- directly to REAL_VALUE_NEGATIVE.
- * loop.c (canonicalize_condition): Likewise.
- * simplify-rtx.c: Include tree.h.
- (simplify_unary_operation): Don't handle FIX and UNSIGNED_FIX
- with floating-point result modes.
- * toplev.c (backend_init): Call init_real_once.
-
- * fold-const.c (force_fit_type): Don't call CHECK_FLOAT_VALUE.
- * tree.c (build_real): Likewise.
- * config/alpha/alpha.c, config/vax/vax.c (float_strings,
- float_values, inited_float_values, check_float_value): Remove.
- * config/alpha/alpha.h, config/m68hc11/m68hc11.h,
- config/m88k/m88k.h, config/vax/vax.h (CHECK_FLOAT_VALUE): Remove.
- * doc/tm.texi (CHECK_FLOAT_VALUE): Remove.
- (VAX_HALFWORD_ORDER): Remove.
-
-2002-09-16 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c: (legitimize_la_operand): Remove, replace by ...
- (s390_load_address): ... this new function.
- (s390_decompose_address): Allow the argument pointer and all
- virtual registers as 'pointer' registers.
- (s390_expand_plus_operand): Use s390_load_address.
- config/s390/s390.md (movti, movdi, movdf splitters): Likewise.
- ("force_la_31"): New insn pattern.
- config/s390/s390-protos.h (legitimize_la_operand): Remove.
- (s390_load_address): Add prototype.
-
- * config/s390/s390.c: Include "optabs.h".
- (s390_expand_movstr, s390_expand_clrstr, s390_expand_cmpstr): New.
- config/s390/s390-protos.h (s390_expand_movstr, s390_expand_clrstr,
- s390_expand_cmpstr): Add prototypes.
- config/s390/s390.md ("movstrdi", "movstrsi"): Call s390_expand_movstr.
- ("movstrdi_short"): Rename to "movstr_short_64". Change predicates
- for operands 0 and 1 to "memory_operand". Add type attribute.
- ("movstrsi_short"): Rename to "movstr_short_31". Change predicates
- for operands 0 and 1 to "memory_operand". Add type attribute.
- ("movstrdi_long", "movstrsi_long"): Remove.
- ("movstrdi_64"): Rename to "movstr_long_64". Add type attribute.
- ("movstrsi_31"): Rename to "movstr_long_31". Add type attribute.
- ("clrstrdi", "clrstrsi"): Call s390_expand_clrstr.
- ("clrstrsico"): Remove, replace by ...
- ("clrstr_short_64", "clrstr_short_31"): ... these new patterns.
- ("clrstrsi_64"): Rename to "clrstr_long_64".
- ("clrstrsi_31"): Rename to "clrstr_long_31".
- ("cmpstrdi", "cmpstrsi"): Call s390_expand_cmpstr.
- ("cmpstr_const"): Remove, replace by ...
- ("cmpstr_short_64", "cmpstr_short_31"): ... these new patterns.
- ("cmpstr_64"): Rename to "cmpstr_long_64".
- ("cmpstr_31"): Rename to "cmpstr_long_31".
-
-2002-09-16 Kazu Hirata <kazu@cs.umass.edu>
-
- * ABOUT-NLS: Follow spelling conventions.
- * ChangeLog: Likewise.
- * ChangeLog.1: Likewise.
- * ChangeLog.2: Likewise.
- * ChangeLog.3: Likewise.
- * ChangeLog.4: Likewise.
- * ChangeLog.5: Likewise.
- * ChangeLog.6: Likewise.
- * FSFChangeLog.10: Likewise.
- * FSFChangeLog.11: Likewise.
- * c-common.c: Likewise.
- * c-lex.c: Likewise.
- * c-objc-common.c: Likewise.
- * cppexp.c: Likewise.
- * cppinit.c: Likewise.
- * cpplex.c: Likewise.
- * doloop.c: Likewise.
- * flow.c: Likewise.
- * function.c: Likewise.
- * integrate.c: Likewise.
* loop.c: Likewise.
+ * recog.c: Likewise.
+ * regmove.c: Likewise.
* reg-stack.c: Likewise.
- * reload.h: Likewise.
- * ssa.c: Likewise.
-
-2002-09-15 Kazu Hirata <kazu@cs.umass.edu>
-
- * ChangeLog: Follow spelling conventions.
- * ChangeLog.0: Likewise.
- * ChangeLog.1: Likewise.
- * ChangeLog.2: Likewise.
- * ChangeLog.4: Likewise.
- * ChangeLog.6: Likewise.
- * config.gcc: Likewise.
- * dwarfout.c: Likewise.
- * reload1.c: Likewise.
+ * reorg.c: Likewise.
+ * rtlanal.c: Likewise.
+ * rtl.h: Likewise.
+ * sched-ebb.c: Likewise.
* simplify-rtx.c: Likewise.
- * unwind-sjlj.c: Likewise.
- * config/avr/avr.h: Likewise.
- * config/d30v/d30v.h: Likewise.
- * config/frv/frv.c: Likewise.
- * config/frv/frv.h: Likewise.
- * config/ip2k/ip2k.h: Likewise.
- * config/m88k/m88k-move.sh: Likewise.
- * config/stormy16/stormy16.c: Likewise.
- * config/stormy16/stormy16.h: Likewise.
- * doc/extend.texi: Likewise.
- * doc/interface.texi: Likewise.
- * doc/invoke.texi: Likewise.
- * doc/md.texi: Likewise.
- * doc/rtl.texi: Likewise.
- * doc/tm.texi: Likewise.
- * doc/trouble.texi: Likewise.
- * ginclude/float.h: Likewise.
- * treelang/treelang.texi: Likewise.
+ * toplev.c: Likewise.
+ * varasm.c: Likewise.
-2002-09-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+2004-01-06 Kazu Hirata <kazu@cs.umass.edu>
- * i386-protos.h (i386_pe_dllexport_name_p,
- i386_pe_dllimport_name_p, i386_pe_unique_section,
- i386_pe_declare_function_type, i386_pe_record_external_function,
- i386_pe_record_exported_symbol, i386_pe_asm_file_end): Add
- prototype.
- * i386/t-cygwin (winnt.o): Depend on $(TM_P_H).
- * i386/t-interix (winnt.o): Likewise.
-
- * v850-protos.h (v850_output_addr_const_extra): Prototype.
-
-2002-09-15 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/mips/netbsd.h (TARGET_OS_CPP_BUILTINS): Add
- MIPS ABI CPP macros.
- (TARGET_CPU_CPP_BUILTINS): Redefine.
- (SUBTARGET_EXTRA_SPECS): Remove subtarget_endian_default.
- (SUBTARGET_ENDIAN_DEFAULT_SPEC): Remove.
-
-2002-09-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * ia64/aix.h (TARGET_OS_CPP_BUILTINS): Fix typo.
-
-2002-09-15 Kazu Hirata <kazu@cs.umass.edu>
-
- * ChangeLog: Follow spelling conventions.
- * ChangeLog.0: Likewise.
- * ChangeLog.1: Likewise.
- * ChangeLog.2: Likewise.
- * ChangeLog.3: Likewise.
- * ChangeLog.4: Likewise.
- * ChangeLog.5: Likewise.
- * ChangeLog.6: Likewise.
- * FSFChangeLog.10: Likewise.
- * FSFChangeLog.11: Likewise.
- * c-common.c: Likewise.
- * c-common.h: Likewise.
- * c-format.c: Likewise.
- * c-opts.c: Likewise.
- * cpplib.c: Likewise.
- * langhooks.h: Likewise.
- * real.c: Likewise.
- * reg-stack.c: Likewise.
- * toplev.c: Likewise.
- * config/arm/arm.c: Likewise.
- * config/arm/arm.md: Likewise.
- * config/arm/linux-gas.h: Likewise.
- * config/arm/netbsd.h: Likewise.
- * config/c4x/c4x.c: Likewise.
- * config/c4x/c4x.h: Likewise.
- * config/c4x/c4x.md: Likewise.
- * config/c4x/libgcc.S: Likewise.
- * config/fr30/fr30.md: Likewise.
- * config/frv/frv.md: Likewise.
- * config/ia64/ia64.md: Likewise.
- * config/mips/mips.h: Likewise.
- * config/mn10300/mn10300.c: Likewise.
- * config/stormy16/stormy16.c: Likewise.
- * config/v850/v850.md: Likewise.
- * doc/extend.texi: Likewise.
+ * doc/install.texi: Fix typos.
* doc/invoke.texi: Likewise.
* doc/md.texi: Likewise.
-2002-09-15 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/netbsd.h (LIB_SPEC): Include the appropriate pthread
- library if -pthread is specified.
+2004-01-06 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
-2002-09-15 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config.gcc (*-*-netbsd*): Set thread_file to 'posix'
- for --enable-threads=yes and --enable-threads=posix.
-
-2002-09-15 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/sparc/cypress.md: Replace Sparc with SPARC.
- * config/sparc/freebsd.h: Likewise.
- * config/sparc/gmon-sol2.c: Likewise.
- * config/sparc/hypersparc.md: Likewise.
- * config/sparc/lb1spc.asm: Likewise.
- * config/sparc/lb1spl.asm: Likewise.
- * config/sparc/linux.h: Likewise.
- * config/sparc/linux64.h: Likewise.
- * config/sparc/lynx.h: Likewise.
- * config/sparc/sol2.h: Likewise.
- * config/sparc/sparc-modes.def: Likewise.
- * config/sparc/sparc.c: Likewise.
- * config/sparc/sparc.h: Likewise.
- * config/sparc/sparc.md: Likewise.
- * config/sparc/sparclet.md: Likewise.
- * config/sparc/supersparc.md: Likewise.
- * config/sparc/sysv4.h: Likewise.
- * config/sparc/vxsim.h: Likewise.
- * config/sparc/vxsparc64.h: Likewise.
-
-2002-09-14 Marek Michalkiewicz <marekm@amelek.gda.pl>
-
- * config/avr/avr.c (output.h): Move after inclusion of tree.h.
-
-2002-09-14 Kazu Hirata <kazu@cs.umass.edu>
-
- * ChangeLog: Follow spelling conventions.
- * ChangeLog.0: Likewise.
- * ChangeLog.2: Likewise.
- * ChangeLog.3: Likewise.
- * ChangeLog.4: Likewise.
- * ChangeLog.5: Likewise.
- * ChangeLog.6: Likewise.
- * cppfiles.c: Likewise.
- * cppinit.c: Likewise.
- * cpplib.h: Likewise.
- * cse.c: Likewise.
- * debug.h: Likewise.
- * df.c: Likewise.
- * dominance.c: Likewise.
- * hashtable.c: Likewise.
- * hashtable.h: Likewise.
- * loop.c: Likewise.
- * config/arm/README-interworking: Likewise.
- * config/arm/arm.c: Likewise.
- * config/arm/arm.h: Likewise.
- * config/arm/arm.md: Likewise.
- * config/dsp16xx/dsp16xx.h: Likewise.
- * config/frv/frv.c: Likewise.
- * config/frv/frv.h: Likewise.
- * config/ip2k/ip2k.h: Likewise.
- * config/rs6000/rs6000.c: Likewise.
- * config/stormy16/stormy-abi: Likewise.
- * config/stormy16/stormy16.h: Likewise.
- * config/v850/v850.c: Likewise.
+ * config/m32r/m32r.h (TRAMPOLINE_LINE_SIZE): Changed
-2002-09-14 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-06 Jan Hubicka <jh@suse.cz>
- * loop.c: Fix a comment typo.
+ * i386.c (init_cumulative_args): Add handling of MMX_REGPARM.
+ (function_arg_advance): Do not pass aggregates in SSE; deal handling
+ of MMX_REGPARM.
+ (function_arg): Add new warnings about ABI changes; fix SSE_REGPARM;
+ add MMX_REGPARM.
+ * i386.h (ix86_args): Add mmx_words/mmx_regs/mmx_regno fields.
+ (SSE_REGPARM_MAX): Default to 3 on i386 -msse ABI.
+ (MMX_REGPARM_MAX): Similarly for -mmmx.
-2002-09-14 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
- * config/fr30/fr30.h: Fix comment typos.
- * config/frv/frv.c: Likewise.
- * config/i386/xmmintrin.h: Likewise.
- * config/mips/mips.c: Likewise.
- * config/sh/sh.c: Likewise.
-
-2002-09-14 Kazu Hirata <kazu@cs.umass.edu>
-
- * haifa-sched.c: Follow spelling conventions.
- * regclass.c: Likewise.
- * regrename.c: Likewise.
- * config/fp-bit.c: Likewise.
- * config/frv/frv.h: Likewise.
- * config/m88k/m88k.c: Likewise.
- * config/mcore/mcore.c: Likewise.
- * config/rs6000/darwin.h: Likewise.
- * config/rs6000/gnu.h: Likewise.
- * config/rs6000/linux.h: Likewise.
- * config/rs6000/linux64.h: Likewise.
- * config/rs6000/rs6000.c: Likewise.
- * config/rs6000/rs6000.h: Likewise.
+ * config/sh/linux.h: Fix comment formatting.
+ * config/sh/netbsd-elf.h: Likewise.
* config/sh/sh.c: Likewise.
- * config/sparc/sparc.c: Likewise.
- * config/sparc/ultra1_2.md: Likewise.
-
-2002-09-14 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.md ("movdi_internal"): Allow any offsetable
- memory operand when source is 0 (K constraint).
- ("movsi_internal"): Likewise.
- ("movdf_internal"): Likewise.
- ("movsf_internal"): Likewise.
-
-2002-09-14 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.c (rs6000_elf_encode_section_info): Use
- targetm.binds_local_p to set SYMBOL_REF_FLAG.
- (rs6000_xcoff_encode_section_info): Likewise.
- * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Likewise.
-
-2002-09-10 Theodore A. Roth <troth@verinet.com>
-
- * gcc/config/avr/avr.h: Set default options for C++ for avr.
-
-2002-09-13 Richard Henderson <rth@redhat.com>
-
- * Makefile.in (toplev.o): Depend on real.h.
- (print-rtl.o, varasm.o, ifcvt.o): Likewise.
-
-2002-09-14 Alan Modra <amodra@bigpond.net.au>
-
- * doc/tm.texi (DBX_OUTPUT_NFUN): Describe.
- * dbxout.c (dbxout_function_end): Use DBX_OUTPUT_NFUN.
- * config/rs6000/linux64.h (DBX_OUTPUT_NFUN): Define.
-
-2002-09-13 Nathan Sidwell <nathan@codesourcery.com>
-
- * ggc-common.c (ggc_mark_roots): Don't iterate NULL hash tables.
-
-2002-09-13 Steve Ellcey <sje@cup.hp.com>
-
- * config.gcc (ia64*-*-aix*, ia64*-*-elf*, ia64*-*-freebsd*,
- ia64*-*-linux*): Set extra_parts.
- * config/ia64/t-aix (EXTRA_PARTS): Remove.
- * config/ia64/t-ia64 (EXTRA_PARTS): Remove.
-
-2002-09-13 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/fixunssfsi.c: Replace H8/S with H8S.
- * config/h8300/h8300.c: Likewise.
- * config/h8300/h8300.h: Likewise.
- * config/h8300/h8300.md: Likewise.
- * doc/invoke.texi: Likewise.
-
-2002-09-13 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (h8300_init_once): Fix formatting.
-
-2002-09-13 Richard Henderson <rth@redhat.com>
-
- * config/alpha/alpha.md (attr type): Add callpal.
- (imb, trap, load_tp, set_tp): Use it.
- * config/alpha/ev4.md (ev4_callpal): New.
- * config/alpha/ev5.md (ev5_callpal): New.
- * config/alpha/ev6.md (ev6_ibr): Handle callpal.
- * config/alpha/alpha.c (alphaev4_insn_pipe): Handle TYPE_CALLPAL.
- (alphaev5_insn_pipe): Likewise.
-
-2002-09-13 Andreas Jaeger <aj@suse.de>
-
- * Makefile.in (print-rtl.o): Depend on CONFIG_H.
-
-2002-09-13 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/t-hpux (LIBGCC1_TEST, STMP_FIXPROTO,
- LIB2ADDEH): New, set to NULL.
- (SHLIB_EXT, SHLIB_LINK, SHLIB_INSTALL, SHLIB_MKMAP): New.
-
-2002-09-13 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/quadlib.c (_U_Qfcmp): Make extern.
- (_U_Qfcnvfxt_quad_to_sgl): Remove declaration.
- (_U_Qfeq, _U_Qfne, _U_Qfgt, _U_Qfge, U_Qflt, U_Qfle, _U_Qfcomp):
- Add declarations.
- (_U_Qfneg): Remove.
-
-2002-09-13 Dhananjay Deshpande <dhananjayd@kpit.com>
-
- * config/h8300/h8300.h (EIGHTBIT_CONSTANT_ADDRESS_P): Add support
- for H8/300, H8S aa:8 mode.
- (TINY_CONSTANT_ADDRESS_P): Add support for H8S aa:16 mode.
- * config/h8300/h8300.c (h8300_adjust_insn_length): Adjust length
- for H8/300 aa:8 mode.
-
-2002-09-13 Hartmut Penner <hpenner@de.ibm.com>
-
- * config/s390/s390.md ("trap", "conditional_trap", "*trap"): New
- insns.
-
-2002-09-12 Richard Henderson <rth@redhat.com>
-
- * Makefile.in (HOST_PRINT): Use print-rtl1.o
- (print-rtl.o): Don't define GENERATOR_FILE.
- (print-rtl1.o): Rename from $(BUILD_PREFIX_1)print-rtl.o.
- * print-rtl.c (print_rtx): Include CONST_DOUBLE fp decimal output
- unless GENERATOR_FILE.
-
-2002-09-12 Stan Shebs <shebs@apple.com>
-
- * config/darwin.h (USER_LABEL_PREFIX): Define here...
- * config/i386/darwin.h: ... instead of here.
-
- * target.h (struct gcc_target): New field
- terminate_dw2_eh_frame_info.
- * target-def.h (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Define.
- (TARGET_INITIALIZER): Add it.
- * dwarf2out.c (output_call_frame_info): Use target hook.
- * dwarf2asm.c (dw2_asm_output_delta): Use macro
- ASM_OUTPUT_DWARF_DELTA if defined.
- * doc/tm.texi (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Document.
- (ASM_OUTPUT_DWARF_DELTA): Ditto.
- (ASM_OUTPUT_DWARF_OFFSET): Ditto.
- (ASM_OUTPUT_DWARF_PCREL): Ditto.
- * config.gcc (i[34567]86-*-darwin*): Define extra_parts.
- (powerpc-*-darwin*): Ditto.
- * crtstuff.c [OBJECT_FORMAT_MACHO]: Update the Mach-O bits
- to work correctly for Darwin.
- * config/darwin.h (OBJECT_FORMAT_MACHO): Define.
- (STARTFILE_SPEC): Add crtbegin.o.
- (ENDFILE_SPEC): Define.
- (EXTRA_SECTION_FUNCTIONS): Put gcc_except_tab in data segment.
- (ASM_PREFERRED_EH_DATA_FORMAT): Handle more cases.
- (ASM_OUTPUT_DWARF_DELTA): Define.
- (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Define.
- * config/darwin.c (darwin_asm_output_dwarf_delta): New function.
-
-2002-09-13 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.c (rs6000_emit_load_toc_table): Remove "if"
- nesting. Correct test for non-PowerPC64 ELF ABI_AIX.
- * config/rs6000/rs6000.md (load_toc_v4_PIC*): Disable when ABI_AIX.
-
-2002-09-12 Zack Weinberg <zack@codesourcery.com>
-
- * toplev.c: Move default definition of USER_LABEL_PREFIX...
- * defaults.h: ... here.
-
-2002-09-12 Richard Henderson <rth@redhat.com>
-
- * vax.c: Include tree.h earlier.
-
-2002-09-12 Stan Shebs <shebs@apple.com>
-
- * config/darwin.c (machopic_finish): Remove #if 0 chunks.
- (machopic_operand_p): Ditto.
-
-2002-09-12 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/arm/arm.c (arm_compute_initial_elimination_offset):
- Fix a comment typo.
-
-2002-09-12 Kazu Hirata <kazu@cs.umass.edu>
-
- * toplev.c (do_abort): Fix a comment typo.
-
-2002-09-12 Kazu Hirata <kazu@cs.umass.edu>
-
- * cselib.c: Fix comment formatting.
- * gengtype.c: Likewise.
-
-2002-09-12 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (udivmodqi4): Do not use an expander.
- (udivmodhi4): Likewise.
-
-2002-09-12 Graham Stott <graham.stott@btinternet.com>
- Roger Sayle <roger@eyesopen.com>
-
- * i386.c (any_fp_register_operand, fp_register_operand,
- register_and_not_any_fp_reg_operand, register_and_not_fp_reg_operand):
- New predicate functions.
- * i386-protos.h: Add their prototypes.
- * i386.h: Add them to PREDICATE_CODES.
- * i386.md ("*pushsf_rex64"+2, "*pushsf_rex64"+3, "*pushdf_integer"+1,
- "*pushdf_integer"+2, "*pushtf_integer"+1, "*pushtf_integer"+2,
- "*pushtf_integer"+3, "*pushtf_integer"+4, "*dummy_extendsfdf2"+1,
- "*dummy_extendsfdf2"+2, "*dummy_extendsfxf2"+1,
- "*dummy_extendsftf2"+1, "*dummy_extendsftf2"+2,
- "*dummy_extenddfxf2"+1, "*dummy_extenddftf2"+1,
- "*dummy_extenddftf2"+2, "*negsf2_if"+1, "*negsf2_if"+2,
- "*negdf2_if_rex64"+1, "*negdf2_if_rex64"+2, "*negxf2_if"+1,
- "*negxf2_if"+2, "*negtf2_if"+1, "*negtf2_if"+2, "*abssf2_if"+1,
- "*abssf2_if"+2, "*absdf2_if_rex64"+1, "*absdf2_if_rex64"+2,
- "*absxf2_if"+1, "*absxf2_if"+2, "*abstf2_if"+1, "*abstf2_if"+2):
- Use these new predicates to simplify and correct the use of
- FP_REG_P, ANY_FP_REG_P, FP_REGNO_P and any ANY_FP_REGNO_P.
-
-2002-09-12 Jason Merrill <jason@redhat.com>
-
- * diagnostic.c (output_add_identifier): New fn.
- * diagnostic.h: Declare it.
-
- * calls.c (store_one_arg): Use size_in_bytes to determine the
- amount of space to push.
-
-2002-09-12 Jakub Jelinek <jakub@redhat.com>
-
- * config/sparc/linux64.h (STARTFILE_SPEC32): Fix a typo.
-
-2002-09-12 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390-modes.def (CCAPmode, CCANmode): New CC modes.
- * config/s390/s390.c (s390_match_ccmode_set): Support new CC modes.
- (s390_select_ccmode): Likewise.
- (s390_branch_condition_mask): Likewise.
- (optimization_options): Do not set flag_branch_on_count.
- (s390_split_branches): Handle doloop branches.
- (s390_chunkify_pool): Likewise.
- * config/s390/s390.md ("*adddi3_imm_cc", "*addsi3_imm_cc"): New insns.
- ("doloop_end"): New expander.
- ("doolop_si", "*doloop_si_long", "doloop_di", "*doloop_di_long",
- associated splitters): New.
-
-2002-09-11 Hartmut Penner <hpenner@de.ibm.com>
-
- * fold-const.c (make_range): Only narrow to signed range if
- the signed range is smaller than the unsigned range.
-
-2002-09-12 Alan Modra <amodra@bigpond.net.au>
-
- * emit-rtl.c (set_mem_size): New function.
- * expr.h (set_mem_size): Declare.
- * config/rs6000/rs6000.c (expand_block_move_mem): Exterminate.
- (expand_block_move): Instead, use adjust_address and
- replace_equiv_address to generate proper aliasing info.
- Move common code out of conditionals. Localize vars.
-
-2002-09-11 Eric Botcazou <ebotcazou@libertysurf.fr>
-
- * optabs.c (expand_binop): Minor cleanup.
- (expand_twoval_binop): Convert CONST_INTs like in expand_binop.
-
-2002-09-11 Dan Nicolaescu <dann@ics.uci.edu>
-
- * print-tree.c (print_node): Print the restrict qualifier.
-
-2002-09-11 Janis Johnson <janis187@us.ibm.com>
-
- * doc/install.texi: Fix typos.
-
-2002-09-11 Zack Weinberg <zack@codesourcery.com>
-
- * Makefile.in: Remove all references to s-under and underscore.c.
- * collect2.c, tlink.c: Change all uses of prepends_underscore
- to look directly at USER_LABEL_PREFIX.
-
-2002-09-11 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.c (rs6000_xcoff_asm_named_section): Append
- alignment to csect.
- (rs6000_xcoff_unique_section): Only set section name for public
- data.
- (rs6000_xcoff_section_type_flags): Store log2 alignment in flags.
- * config/rs6000/xcoff.h (TARGET_ASM_SELECT_SECTION): Remove
- duplicate definition.
-
-2002-09-10 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa.md (extzv): Check predicates before emitting extzv_32.
- (insv): Likewise.
-
-2002-09-10 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.h (MOVE_MAX): Define to correct value.
- (MAX_MOVE_MAX): Define.
- (MOVE_BY_PIECES_P): Define.
- (CLEAR_BY_PIECES_P): Define.
-
-2002-09-10 Denis Chertykov <denisc@overta.ru>
-
- * config/avr/avr.md (movstrhi): Use right operands for conversion.
-
-2002-09-10 Richard Earnshaw <rearnsha@arm.com>
-
- PR c/7873
- * arm.md (insv): Use reg_or_int_operand for operand[3].
-
-2002-09-10 David Edelsohn <edelsohn@gnu.org>
-
- * rs6000.c (rs6000_assemble_visibility): Protect declaration
- inside macro. Correct function definition typo.
- (rs6000_xcoff_section_type_flags): New function.
- (TARGET_SECTION_TYPE_FLAGS): Remove definition.
- (rs6000_elf_section_type_flags): Call default_section_type_flags_1
- with appropriate PIC test.
- (rs6000_xcoff_select_section): Use decl_readonly_section_1 to
- determine readonly.
- (rs6000_binds_local_p): Combine PIC flags.
- * sysv4.h (TARGET_SECTION_TYPE_FLAGS): Define.
- * xcoff.h (TARGET_SECTION_TYPE_FLAGS): Define.
-
-2002-09-09 Per Bothner <per@bothner.com>
-
- * print-tree.c (print_node): In a STRING_CST, escape non-ascii
- characters, and only print TREE_STRING_LENGTH chars.
-
-2002-09-09 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/hpux.h (TARGET_HPUX_LD): New, define true.
- (ASM_FILE_END) New.
- * config/ia64/ia64.h (TARGET_HPUX_LD): New, define false.
- * config/ia64/ia64-protos.h (ia64_hpux_asm_file_end): New.
- * config/ia64/ia64.c (ia64_asm_output_external): Create list
- of external functions if TARGET_HPUX_LD is true.
- (ia64_hpux_add_extern_decl): New, routine to put names on
- list of external functions.
- (ia64_hpux_asm_file_end): Put out declarations for external
- functions if and only if they are used.
-
-2002-09-09 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa.md (exception_receiver, builtin_setjmp_receiver): Add blockage
- on TARGET_64BIT before pic register restore.
-
-2002-09-09 David Edelsohn <edelsohn@gnu.org>
-
- * doc/tm.texi (TARGET_HAVE_SRODATA_SECTION): New description.
- (TARGET_HAVE_TLS): New description.
-
-2002-09-09 Janis Johnson <janis187@us.ibm.com>
-
- * doc/extend.texi (Statement Exprs): Fix broken link.
-
-2002-09-09 Denis Chertykov <denisc@overta.ru>
-
- * config/avr/avr.md (movstrhi, clrstrhi): Use gen_int_mode for
- right conversion of operands[1].
-
-2002-09-09 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.md ("*tmdi_reg", "*tmsi_reg"): Do not mark as
- commutative. Use "nonimmediate_operand" instead of "register_operand"
- as predicate for operand 0. Move to after the "*tmXX_mem" insns.
-
- ("*tmdi_mem", "*tmsi_mem", "*tmhi_mem", "*tmqi_mem"): Do not mark
- as commutative.
-
- ("*anddi3_ni", "*andsi3_ni", "*iordi3_ni", "*iorsi3_ni"): Do not
- mark as commutative. Use "nonimmediate_operand" instead of
- "register_operand" as predicate for operand 1.
-
- ("movstrictsi"): Fix typo in insn name.
-
-2002-09-09 Jan Hubicka <jh@suse.cz>
-
- * i386.c (index_register_operand): New.
- * i386.h (predicate_codes): Add new predicate.
- * i386.md (lea_general_*): Use index_register_operand
- (ashift to lea splitter): Do not produce invalid leas
- (ashift to mov+ashift split): New.
-
-2002-09-09 Nick Clifton <nickc@redhat.com>
-
- * config/fr30/fr30.c (output.h): Move after inclusion of tree.h.
- Fix folding marks.
-
-2002-09-09 Toshiyasu Morita <toshiyasu.morita@hsa.hitachi.com>
- J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh/sh.h (OVERRIDE_OPTIONS): align_functions is in bytes, not bits.
-
-2002-09-09 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.c (rs6000_binds_local_p): Return bool.
- (function_ok_for_sibcall): Use binds_local_p. Respect longcall
- attributes.
-
-2002-09-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * fr30.c (fr30_print_operand): Fix bug in output of CONST_DOUBLE.
-
-2002-09-08 Richard Henderson <rth@redhat.com>
-
- * dwarf2.h (DW_OP_call_ref): Rename from DW_OP_calli.
- (DW_OP_GNU_push_tls_address): New.
- (DW_OP_lo_user): Fix.
- * dwarf2out.c (INTERNAL_DW_OP_tls_addr): New.
- (dwarf_stack_op_name): Handle it, plus other dwarf3 opcodes.
- (size_of_loc_descr): Likewise.
- (output_loc_operands): Handle INTERNAL_DW_OP_tls_addr.
- (add_AT_location_description): Take a dw_loc_descr_ref not an rtx.
- (loc_descriptor_from_tree): Handle TLS variables.
- (rtl_for_decl_location): Do avoid_constant_pool_reference here ...
- (add_location_or_const_value_attribute): ... not here. Defer
- to loc_descriptor_from_tree for TLS variables.
-
- * config/i386/i386.h (ASM_OUTPUT_DWARF_DTPREL): New.
- * config/i386/i386.c (i386_output_dwarf_dtprel): New.
- * config/i386/i386-protos.h: Update.
-
-2002-09-08 Roger Sayle <roger@eyesopen.com>
-
- PR optimization/6405
- * unroll.c (loop_iterations): last_loop_insn should be the previous
- non-note instruction before loop->end.
- * loop.c (strength_reduce): The conditional jump is the last
- non-note instruction before loop->end (as above).
-
-2002-09-08 Roger Sayle <roger@eyesopen.com>
-
- * combine.c (try_combine): Handle the case that undobuf.other_insn
- has been turned into a return or unconditional jump, by inserting
- a BARRIER if necessary.
- (simplify_set): Test if a condition code setter has a constant
- comparison at compile time, if so convert this insn to a no-op move
- and update/simplify the condition code user (undobuf.other_insn).
-
-2002-09-08 Krister Walfridsson <cato@df.lth.se>
-
- * config/arm/netbsd.h (INITIALIZE_TRAMPOLINE): Redefine.
- (CLEAR_INSN_CACHE): Define.
-
-2002-09-08 Kazu Hirata <kazu@cs.umass.edu>
-
- * basic-block.h: Fix comment formatting.
- * c-common.c: Likewise.
- * c-common.h: Likewise.
- * c-lex.c: Likewise.
- * c-pretty-print.c: Likewise.
- * cfglayout.c: Likewise.
- * cfgloop.c: Likewise.
- * defaults.h: Likewise.
- * et-forest.c: Likewise.
- * explow.c: Likewise.
- * function.h: Likewise.
- * gcov.c: Likewise.
- * genattrtab.c: Likewise.
- * gengtype.c: Likewise.
- * ifcvt.c: Likewise.
- * libgcc2.c: Likewise.
- * loop.c: Likewise.
- * profile.c: Likewise.
- * ra-build.c: Likewise.
- * real.c: Likewise.
- * rtl.h: Likewise.
- * tracer.c: Likewise.
- * tree-inline.c: Likewise.
- * varasm.c: Likewise.
-
-2002-09-08 Jan Hubicka <jh@suse.cz>
-
- * emit-rtl.c (set_mem_attributes_minus_bitpos): Fix array_ref
- handling.
-
- * loop.c (loop_givs_reduce): Emit addition after.
-
-2002-09-08 Alan Modra <amodra@bigpond.net.au>
-
- * varasm.c (default_assemble_visibility): Rename from
- assemble_visibility.
- * output.h: Here too.
- * target-def.h (TARGET_ASM_ASSEMBLE_VISIBILITY): And here.
- * config/rs6000/rs6000.c (rs6000_assemble_visibility): And here.
-
-2002-09-08 Alan Modra <amodra@bigpond.net.au>
-
- * reload.c (find_reloads <p constraint>): Pass operand_mode to
- find_reloads_address.
-
-2002-09-08 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (udivmodqi4): Enable on H8/300.
- (anonymous pattern): Likewise.
-
-2002-09-07 Scott Snyder <snyder@fnal.gov>
-
- PR target/7374
- * config/alpha/alpha.md (abstf2): Fix typo: 'neg' for 'abs'.
-
-2002-09-07 Roger Sayle <roger@eyesopen.com>
-
- * basic-block.h (struct loop): Remove unused cont_dominator field.
-
-2002-09-07 Igor Shevlyakov <igor@microunity.com>
-
- * varasm.c (decode_rtx_const): Don't check undefined field for
- CONST_VECTOR.
-
-2002-09-07 Glen Nakamura <glen@imodulo.com>
-
- PR opt/7814
- * sched-deps.c (sched_analyze_insn): Make sure to add insn
- to reg_last->sets after flushing the dependency lists to guarantee
- that subsequent clobbers will be dependent on it.
-
-2002-09-07 Igor Shevlyakov <igor@microunity.com>
-
- * combine.c (simplify_shift_const): Calculate rotate count
- correctly for vector operands.
-
-2002-09-07 Ansgar Esztermann <ansgar@thphy.uni-duesseldorf.de>
-
- * c-typeck.c (c_tree_expr_nonnegative_p): New function.
- (build_binary_op): Call c_tree_expr_nonnegative_p rather than
- tree_expr_nonnegative_p.
- (build_conditional_expr): Likewise.
- * c-tree.h (c_tree_expr_nonnegative_p): Declare.
-
-2002-09-07 Richard Henderson <rth@redhat.com>
-
- * builtins.def (inf, inff, infl): Mark const.
- (huge_val, huge_valf, huge_vall): Likewise.
- (BUILT_IN_GETEXP, BUILT_IN_GETMAN): Remove.
-
- * real.c (ereal_inf): Clear E before use.
-
-2002-09-07 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.md (udivmodqi4): Split the pattern into
- an expander and an anonymous pattern. Zero out the upper half
- of the dividend in the expander.
- (udivmodqi4): Likewise.
-
-2002-09-07 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c: Fix formatting.
- * config/h8300/h8300.h: Likewise.
- * config/h8300/h8300.md: Likewise.
-
-2002-09-07 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
-
- * cfgcleanup.c (try_crossjump_to_edge): Fix updating of liveness
- information.
-
-2002-09-07 Graham Stott <graham.stott@btinternet.com>
-
- * rtlanal.c (dead_or_set_regno_p): Fix typo.
-
-2002-09-07 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/linux64.h (ASM_PREFERRED_EH_DATA_FORMAT): Define.
-
- * doc/tm.texi (TARGET_ASM_ASSEMBLE_VISIBILITY): Describe.
- * target-def.h (TARGET_ASM_ASSEMBLE_VISIBILITY): Define.
- (TARGET_ASM_OUT): Add the above here.
- * target.h (struct gcc_target): Add "visibility" field.
- * varasm.c (maybe_assemble_visibility): Call targetm visibility func.
- * config/rs6000/rs6000.c (rs6000_assemble_visibility): New function.
- (TARGET_ASM_ASSEMBLE_VISIBILITY): Define.
- (rs6000_legitimize_reload_address, first_reg_to_save): Formatting.
-
-2002-09-06 Ziemowit Laski <zlaski@apple.com>
-
- * c-lang.c (objc_is_id): New stub.
- * c-tree.h (objc_is_id): New forward declaration.
- * c-typeck.c (build_c_cast): Do not strip protocol
- qualifiers from 'id' type.
- * objc/objc-act.c (objc_comptypes): Correct handling
- of protocol qualifiers.
- (objc_is_id): New.
-
-2002-09-06 Jeffrey A Law (law@redhat.com)
-
- * pentium.md (pentium-firstvboth): Fix typo.
-
-2002-09-06 Dhananjay Deshpande <dhananjayd@kpit.com>
-
- * h8300.c (enum shift_alg): Move to earlier in h8300.c.
- (enum shift_type, enum h8_cpu): Likewise.
- (INL, ROT, LOP, SPC macros): Likewise.
- (shift_alg_qi, shift_alg_hi, shift_alg_si): Likewise. Lose
- const designator.
- (h8300_init_once): Update shift_alg_{qi,hi,si} to use more
- space efficient algorithms when optimize for codesize.
-
-2002-09-06 Nicola Pero <n.pero@mi.flashnet.it>
-
- Fix PR/1727 and long-standing failing testcase
- objc/formal-protocol-6.m.
- * objc-act.c (build_protocol_expr): If compiling for the GNU
- runtime, create a list of Protocol statically allocated instances
- if it doesn't exist, then add the Protocol object to this same
- list.
- (get_objc_string_decl): Fixed typo/bug - TREE_VALUE had been used
- instead of TREE_CHAIN.
-
-2002-09-06 Nicola Pero <n.pero@mi.flashnet.it>
-
- * objc/objc-act.c (dump_interface): Enlarged the char * buffer to
- 10k. Fixed category dumping - print out category names with the
- proper syntax. Print '@end\n' and not '\n@end' at the end of the
- interface.
- (finish_objc): Fixed the -gen-decls option. It was printing out
- only the last class. Dump an interface declaration of all classes
- being compiled instead.
-
-2002-09-06 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/arm/arm-protos.h (arm_gen_return_addr_mask): New
- prototype.
- * config/arm/arm.c (arm_gen_return_addr_mask): New function.
- * config/arm/arm.h (MASK_RETURN_ADDR): Use arm_gen_return_addr_mask
- if not APCS26 and not Thumb or ARMv4-or-higher. Use gen_int_mode
- rather than GEN_INT.
- * config/arm/arm.md (UNSPEC_CHECK_ARCH): Define.
- (return_addr_mask, *check_arch2): New.
-
-2002-09-06 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.md ("*adddi3_cc", "*adddi3_cconly",
- "*adddi3_cconly2", "*adddi3_64", "*adddi3_31", "adddi3",
- "*addsi3_carry1_cc", "*addsi3_carry1_cconly",
- "*addsi3_carry2_cc", "*addsi3_carry2_cconly",
- "*addsi3_cc", "*addsi3_cconly", "*addsi3_cconly2", "addsi3",
- "adddf3", "*adddf3", "*adddf3_ibm",
- "addsf3", "*addsf3", "*addsf3_ibm",
- "muldi3", "mulsi3", "mulsidi3",
- "muldf3", "*muldf3", "*muldf3_ibm",
- "mulsf3", "*mulsf3", "*mulsf3_ibm",
- "*anddi3_cc", "*anddi3_cconly", "anddi3",
- "*andsi3_cc", "*andsi3_cconly", "andsi3",
- "*iordi3_cc", "*iordi3_cconly", "iordi3",
- "*iorsi3_cc", "*iorsi3_cconly", "iorsi3",
- "*xordi3_cc", "*xordi3_cconly", "xordi3",
- "*xorsi3_cc", "*xorsi3_cconly", "xorsi3"): Use "nonimmediate_operand"
- instead of "register_operand" as predicate for "%0" operand.
-
-2002-09-06 Jakub Jelinek <jakub@redhat.com>
-
- * configure.in (HAVE_AS_OFFSETABLE_LO10): Use -xarch=v9
- unconditionally when gcc_cv_as_flags64 checks are gone.
- * configure: Rebuilt.
-
-2002-09-06 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.md (extzvsi_internal2): Revert most of
- 2002-07-26 change. Comment.
-
-2002-09-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * frv.c (frv_unique_section, frv_select_section,
- frv_select_rtx_section): Delete.
- (frv_in_small_data_p): New.
- (TARGET_ASM_UNIQUE_SECTION, TARGET_ASM_SELECT_SECTION,
- TARGET_ASM_SELECT_RTX_SECTION): Delete.
- (TARGET_IN_SMALL_DATA_P): Define.
-
-2002-09-05 Dale Johannesen <dalej@apple.com>
-
- * reload1.c (reload): Retain only those memory clobbers
- added for variable-array handling.
-
-2002-09-05 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/arm/arm.c (arm_return_in_memory): Implement ATPCS
- return-in-memory rules.
- * config/arm/arm.h (ARM_FLAG_ATPCS, TARGET_ATPCS): Define.
-
-2002-09-05 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/xcoff.h (HOT_TEXT_SECTION_NAME): Delete.
- (UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Delete.
-
-2002-09-05 Jason Thorpe <thorpej@wasabisystems.com>
-
- * real.c: Avoid parse error if FLOAT_WORDS_BIG_ENDIAN is
- not a compile-time constant for the non-IBM case.
- * config/arm/arm-protos.h (arm_float_words_big_endian): New
- prototype.
- * config/arm/arm.c (arm_float_words_big_endian): New function.
- * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define __VFP_FP__
- if TARGET_VFP and not TARGET_HARD_FLOAT.
- (ARM_FLAG_VFP, TARGET_VFP): Define.
- (FLOAT_WORDS_BIG_ENDIAN): Use arm_float_words_big_endian.
-
-2002-09-05 David Edelsohn <edelsohn@gnu.org>
-
- * doc/install.texi: Correct text of s390-*-linux* and s390x-*-linux*
- URLs. Fix AIX wording.
-
-2002-09-05 Stan Shebs <shebs@apple.com>
-
- * config/rs6000/rs6000.c (rs6000_override_options): Make -fpic and
- -fPIC equivalent on Darwin.
-
-2002-09-05 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.c (sh_expand_builtin): Return early if encountering an
- error_mark for a type.
-
-2002-09-05 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c (s390_expand_plus_operand): Do not require
- double-word scratch register.
- config/s390/s390.md ("reload_indi", "reload_insi"): Adapt.
-
- ("*tmqi_ext", "*tmdi_mem", "*tmsi_mem", "*tmhi_mem", "*tmqi_mem",
- "*cli"): Replace s_operand by memory_operand.
- ("cmpstrdi", "cmpstrsi"): Replace s_operand by general_operand.
-
-2002-09-05 Kazu Hirata <kazu@cs.umass.edu>
-
- * config/h8300/h8300.c (asm_file_start): Add a missing
- semicolon.
-
-2002-09-04 Krister Walfridsson <cato@df.lth.se>
-
- * config/i386/i386.h (GOT_SYMBOL_NAME): Define.
- * config/i386/i386.c (output_set_got): Use GOT_SYMBOL_NAME.
- (ix86_output_addr_diff_elt) Likewise.
- (x86_output_mi_thunk) Likewise.
- * config/i386/netbsd.h (GOT_SYMBOL_NAME): Redefine.
-
-2002-09-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * frv.c (frv_encode_section_info): Fix error in last change.
-
-2002-09-04 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.c (rs6000_flag_pic): New variable.
- (rs6000_elf_encode_section_info): ATTRIBUTE_UNUSED.
- (TARGET_BINDS_LOCAL_P): Define.
- (rs6000_override_options): Save original flag_pic value.
- (rs6000_elf_select_section): Call default_elf_select_section_1.
- (rs6000_elf_unique_section): Call default_unique_section_1.
- (rs6000_elf_in_small_data_p): New function.
- (rs6000_xcoff_asm_named_section): Determine storage mapping class.
- (rs6000_xcoff_select_section): Update based on defaults.
- (rs6000_xcoff_unique_section): Set to basic name if not common.
- (rs6000_binds_local_p): New function.
- * config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Set
- targetm.have_srodata_section if SDATA_EABI.
- (TARGET_IN_SMALL_DATA_P): Define.
-
-2002-09-04 Dale Johannesen <dalej@apple.com>
-
- * varasm.c (struct rtx_const, decode_rtx_const):
- Make veclo and vechi fields not share storage.
-
-2002-09-05 J"orn Rennecke <joern.rennecke@superh.com>
-
- * loop.c (scan_loop): Don't mark separate insns out of a libcall
- for moving.
- (move_movables): Abort if we see the first insn of a libcall.
-
-2002-09-04 Richard Henderson <rth@redhat.com>
-
- * builtin-types.def (BT_FN_FLOAT): New.
- (BT_FN_DOUBLE, BT_FN_LONG_DOUBLE): New.
- * builtins.def (BUILT_IN_INF, BUILT_IN_INFF, BUILT_IN_INFL,
- BUILT_IN_HUGE_VAL, BUILT_IN_HUGE_VALF, BUILT_IN_HUGE_VALL): New.
- * builtins.c (fold_builtin_inf): New.
- (fold_builtin): Call it.
- * real.c (ereal_inf): New.
- * real.h: Declare it.
- * doc/extend.texi: Document new builtins.
-
-2002-09-04 Richard Henderson <rth@redhat.com>
-
- * cse.c (cse_insn): Avoid subreg games if the equivalence
- is already in the proper mode.
-
-2002-09-04 Eric Botcazou <ebotcazou@multimania.com>
-
- PR c/7102
- * optabs.c (expand_binop): Convert CONST_INTs in all cases.
-
-2002-09-04 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa.md (setccfp0, setccfp1): New patterns.
-
-2002-09-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * frv-protos.h (frv_init_builtins, frv_expand_builtin,
- frv_select_section, frv_select_rtx_section,
- frv_encode_section_info, frv_unique_section): Delete.
- * frv.c: Update for target hooks.
- * frv.h (STRIP_NAME_ENCODING, SLOW_ZERO_EXTEND, SELECT_SECTION,
- SELECT_RTX_SECTION, ENCODE_SECTION_INFO, UNIQUE_SECTION,
- EASY_DIV_EXPR, MD_INIT_BUILTINS, MD_EXPAND_BUILTIN): Delete.
-
-2002-09-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * ip2k-protos.h (function_prologue, function_epilogue,
- encode_section_info): Update to match target hook specification.
- * ip2k.c: Wrap `MDR' code in IP2K_MD_REORG_PASS.
- (function_prologue, function_epilogue, encode_section_info):
- Update to match target hook specification.
- * ip2k.h (SELECT_SECTION, SELECT_RTX_SECTION, ASM_OPEN_PAREN,
- ASM_CLOSE_PAREN, EASY_DIV_EXPR): Delete.
- (NOTICE_UPDATE_CC): Cast to void.
- * ip2k.md: Add defaults in switch statements.
-
-2002-09-04 Janis Johnson <janis187@us.ibm.com>
-
- * doc/trouble.texi (Interoperation): Update information about C++ ABI
- issues.
-
-2002-09-04 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/sparc/t-netbsd64: Disable multilib for now.
-
-2002-09-04 David Edelsohn <edelsohn@gnu.org>
-
- * target-def.h (TARGET_HAVE_SRODATA_SECTION): New macro.
- * target.h (gcc_target): Add have_srodata_section member.
- * varasm.c (section_category): Add SECCAT_SRODATA.
- (categorize_decl_for_section): Return SECCAT_SRODATA for sdata if
- READONLY_SDATA_SECTION defined.
- (decl_readonly_section_1): True for SECCAT_SRODATA also.
- (default_elf_select_section_1): Map SECCAT_SRODATA to .sdata2.
- (default_unique_section_1): Likewise.
-
-2002-09-04 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * expr.c (emit_group_load): Revise to allow splitting TCmode source
- into DImode pieces.
-
- * pa-64.h (LONG_DOUBLE_TYPE_SIZE): Define to 128.
- * pa64-regs.h (CLASS_CANNOT_CHANGE_MODE_P): Inhibit changes from SImode
- for floating-point register class.
- * pa.c (function_arg): Fix handling of modes wider than one word for
- TARGET_64BIT.
-
-2002-09-04 J"orn Rennecke <joern.rennecke@superh.com>
-
- * combine.c (make_compound_operation): Don't generate zero / sign
- extensions in floating point modes.
-
-2002-09-04 Janis Johnson <janis187@us.ibm.com>
-
- * doc/c-tree.texi: Fix overfull hboxes.
- * doc/cppopts.texi: Ditto.
- * doc/extend.texi: Ditto.
- * doc/gty.texi: Ditto.
- * doc/invoke.texi: Ditto.
- * doc/makefile.texi: Ditto.
- * doc/rtl.texi: Ditto.
- * doc/standards.texi: Ditto.
- * doc/tm.texi: Ditto.
-
-2002-09-04 Richard Henderson <rth@redhat.com>
-
- * c-common.c (builtin_define_with_hex_fp_value): New.
- (builtin_define_float_constants): Use it. Fix H_FLOAT mant_dig.
-
-2002-09-04 Janis Johnson <janis187@us.ibm.com>
-
- * doc/invoke.texi (-fshort-wchar): Move to Code Generation Options.
- (-fpcc-struct-return, -freg-struct-return, -fshort-enums,
- -fshort-double, -fshort-wchar, -fpack-struct, -fleading-underscore):
- Warn that these options can break ABI compatibility.
-
-2002-09-04 Richard Henderson <rth@redhat.com>
-
- * real.c (ereal_to_decimal): Add digits parameter.
- * real.h (REAL_VALUE_TO_DECIMAL): Remove format; add digits parameter.
- * c-pretty-print.c (pp_c_real_literal): Update call.
- * print-rtl.c (print_rtx): Likewise.
- * print-tree.c (print_node_brief, print_node): Likewise.
- * sched-vis.c (print_value): Likewise.
- * config/arc/arc.c (arc_print_operand): Likewise.
- * config/c4x/c4x.c (c4x_print_operand): Likewise.
- * config/i370/i370.h (PRINT_OPERAND): Likewise.
- * config/i386/i386.c (print_operand): Likewise.
- * config/i960/i960.c (i960_print_operand): Likewise.
- * config/ip2k/ip2k.c (asm_output_float): Likewise.
- * config/m32r/m32r.c (m32r_print_operand): Likewise.
- * config/m68hc11/m68hc11.c (print_operand): Likewise.
- * config/m68k/hp320.h (PRINT_OPERAND, ASM_OUTPUT_FLOAT_OPERAND,
- ASM_OUTPUT_DOUBLE_OPERAND, ASM_OUTPUT_LONG_DOUBLE_OPERAND): Likewise.
- * config/m68k/m68k.h (ASM_OUTPUT_FLOAT_OPERAND,
- ASM_OUTPUT_DOUBLE_OPERAND, ASM_OUTPUT_LONG_DOUBLE_OPERAND): Likewise.
- * config/m68k/sun2o4.h (ASM_OUTPUT_FLOAT_OPERAND,
- ASM_OUTPUT_DOUBLE_OPERAND): Likewise.
- * config/m68k/sun3.h (ASM_OUTPUT_FLOAT_OPERAND,
- ASM_OUTPUT_DOUBLE_OPERAND): Likewise.
- * config/mips/mips.c (print_operand): Likewise.
- * config/ns32k/ns32k.c (print_operand): Likewise.
- * config/pdp11/pdp11.h (PRINT_OPERAND): Likewise.
- * config/vax/vax.h (PRINT_OPERAND): Likewise.
- * doc/tm.texi (REAL_VALUE_TO_DECIMAL): Update docs.
-
-2002-09-04 Bob Wilson <bob.wilson@acm.org>
-
- * config/xtensa/elf.h (TARGET_SECTION_TYPE_FLAGS): Define to
- xtensa_multibss_section_type_flags.
- * config/xtensa/xtensa.c (xtensa_multibss_section_type_flags): Define.
-
-2002-09-04 Richard Henderson <rth@redhat.com>
-
- * doc/install-old.texi: Don't mention enquire.
- * doc/sourcebuild.texi: Update float.h description.
-
-2002-09-04 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.md (mperm_w_little, mperm_w_big): Supply mode for zero_extract.
-
-2002-09-03 David Edelsohn <edelsohn@gnu.org>
-
- * varasm.c (default_section_type_flags): Append _1 to name with
- shlib parameter. Use original name to call new function with
- implicit flag_pic.
- (decl_readonly_section): Likewise.
- (default_elf_select_section): Likewise.
- (default_unique_section): Likewise.
- (default_bind_local_p): Likewise.
- (categorize_decl_for_section): Add shlib parameter to use in place
- of implicit flag_pic.
- * output.h: Declare new functions with _1 and shlib argument.
-
-2002-09-03 Janis Johnson <janis187@us.ibm.com>
-
- * doc/install.texi: Fix typos, formatting problems, and obvious
- overfull/underfull boxes.
-
- * Makefile.in (TEXI_GCC_FILES): Add compat.texi.
- * doc/gcc.texi (Top): Add new chapter, Binary Compatibility, and
- include its file, compat.texi.
- * doc/compat.texi: New file with new chapter, Binary Compatibility.
-
-2002-09-03 Neil Booth <neil@daikokuya.co.uk>
-
- Debian BTS Bug #157416
- * cpphash.h (FIRST, LAST, CUR, RLIMIT): Fix definitions.
- * cpplib.c (destringize_and_run): Kludge around getting
- tokens from in-progress macros.
- (_cpp_do__Pragma): Simplify.
-
-2002-09-03 Steve Ellcey <sje@cup.hp.com>
-
- * config/ia64/ia64.h (EXTRA_SPECS): Remove cpp_cpu.
- (CPP_CPU_SPEC): Remove.
- (TARGET_CPU_CPP_BUILTINS): New.
- * config/ia64/hpux.h (CPP_PREDEFINES): Remove.
- (CPP_SPEC): Remove.
- (TARGET_OS_CPP_BUILTINS): New.
- * config/ia64/linux.h (CPP_PREDEFINES): Remove.
- (TARGET_OS_CPP_BUILTINS): New.
- * config/ia64/aix.h (CPP_SPEC): Move some stuff to
- TARGET_OS_CPP_BUILTINS.
- (CPP_PREDEFINES): Remove.
- (CPLUSPLUS_CPP_SPEC): Remove.
- (TARGET_OS_CPP_BUILTINS): New.
-
-2002-09-03 Richard Henderson <rth@redhat.com>
-
- * Makefile.in (USER_H): Add ginclude/float.h.
- (FLOAT_H): Remove.
- (stmp-int-hdrs, install-mkheaders): Don't handle FLOAT_H.
- (mostlyclean): Don't remove float.h intermediate files.
- (distclean): Don't remove float.h.
- * config.gcc: Remove all float_format references.
- * configure.in (float_format, float_h_file): Remove.
-
- * c-common.c: Include tree-inline.h.
- (builtin_define_with_int_value): New.
- (builtin_define_type_precision): Use it.
- (builtin_define_float_constants): New.
- (cb_register_builtins): Use it. Define __FLT_RADIX__ and
- __FLT_EVAL_METHOD__.
- * defaults.h (TARGET_FLT_EVAL_METHOD): New.
- * config/i386/i386.h (TARGET_FLT_EVAL_METHOD): New.
- * config/m68k/m68k.h (TARGET_FLT_EVAL_METHOD): New.
- * doc/tm.texi (INTEL_EXTENDED_IEEE_FORMAT): Mention moto 96-bit format.
- (TARGET_FLT_EVAL_METHOD): New.
-
- * config/float-c4x.h, config/float-i128.h, config/float-i32.h,
- config/float-i386.h, config/float-i64.h, config/float-m68k.h,
- config/float-sh.h, config/float-sparc.h, config/float-vax.h: Remove.
- * ginclude/float.h: New.
-
-2002-09-03 Stan Shebs <shebs@apple.com>
-
- * config/darwin.h (WARN_FOUR_CHAR_CONSTANTS): Remove, never used.
- (DWARF2_DEBUGGING_INFO): Remove until assembler accepts Dwarf-2.
- (PREFERRED_DEBUGGING_TYPE): Ditto.
- (ASM_OUTPUT_IDENT): Remove empty definition.
-
-2002-09-03 Steve Ellcey <sje@cup.hp.com>
-
- * config.gcc (ia64*-*-hpux*): Add ia64-c.o to c_target and
- cxx_target.
- * config/ia64/hpux.h (REGISTER_TARGET_PRAGMAS): Register pragma
- handling routine for builtin pragma.
- * config/ia64/ia64-protos.h (ia64_hpux_handle_builtin_pragma):
- Registered pragma handling routine.
- * ia64-c.c (ia64_hpux_handle_builtin_pragma): Ditto.
- (ia64_hpux_add_pragma_builtin) New subroutine used by above.
- If builtin pragma seen for math routine and C89 conformance is
- requested use different math function in order to set errno.
- * t-ia64 (ia64-c.o): Add new rule for new file.
-
-2002-09-03 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.md ("movti"): Add Q->Q alternative.
- ("*movdi_64", "*movdi_31", "*movsi", "movhi", "movqi_64",
- "movqi", "*movdf_64", "*movdf_31", "*movsf"): Likewise.
-
- ("*movti_ss", "*movdi_ss", "*movsi_ss", "*movdf_ss",
- "*movsf_ss"): Remove.
-
-2002-09-03 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa32-regs.h (CLASS_CANNOT_CHANGE_MODE, CLASS_CANNOT_CHANGE_MODE_P):
- Delete macros.
-
-2002-09-03 Arati Dikey <aratid@kpit.com>
-
- * h8300.c (asm_file_start): Corrected optimization comment.
-
-2002-09-03 Stan Shebs <shebs@apple.com>
-
- * c-lang.c (recognize_objc_keyword): Remove, no longer used.
- * c-tree.h (recognize_objc_keyword): Remove decl.
- * c-typeck.c (comp_target_types): Update a comment.
-
-2002-09-03 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c (s390_decompose_address): Remove STRICT parameter
- and register validity checks.
- (general_s_operand): Adapt to s390_decompose_address interface change.
- (q_constraint): Likewise.
- (s390_expand_plus_operand): Likewise.
- (legitimiate_address_p): Likewise.
- (legitimate_la_operand_p): Likewise.
- (legitimize_la_operand): Likewise.
- (print_operand_address): Likewise.
- (print_operand): Likewise.
-
-2002-09-03 Nicola Pero <n.pero@mi.flashnet.it>
-
- PR objc/5956:
- * objc/objc-act.c (build_typed_selector_reference): Fix typo which
- was causing the new selector never to match the existing ones
- (Patch by Alexander Malmberg <alexander@malmberg.org>).
-
-2002-09-03 Graham Stott <graham.stott@btinternet.com>
-
- * config/i386/i386.md ("femms"): Add "memory" attr "none".
-
-2002-09-03 Graham Stott <graham.stott@btinternet.com>
-
- * expr.c (expand_expr): Remove extraneous comment and code.
-
-2002-08-31 Richard Henderson <rth@redhat.com>
-
- * expr.c (block_move_libcall_safe_for_call_parm): Fix thinko.
-
-2002-08-31 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa.c (pa_globalize_label): Add ATTRIBUTE_UNUSED to prototype.
-
-2002-08-30 Richard Henderson <rth@redhat.com>
-
- PR opt/7515
- * c-objc-common.c: Include target.h.
- (c_cannot_inline_tree_fn): Don't auto-inline functions that
- don't bind locally. Factor setting DECL_UNINLINABLE.
- * Makefile.in (c-objc-common.o): Update.
-
-2002-08-30 Janis Johnson <janis187@us.ibm.com>
-
- * doc/install.texi (Configuration, Building): Fix a typo and
- some formatting directives.
-
-2002-08-30 Paul Koning <pkoning@equallogic.com>
-
- * doc/c-tree.texi (RDIV_EXPR): Fix typo.
- * doc/rtl.texi (post_modify): Remove misplaced text, remove "not
- implemented" note.
- * doc/md.texi (IP2K): Move machine-specific constraints before MIPS
- for alphabetic order.
- * doc/tm.texi (TARGET_FLOAT_FORMAT): Update description for
- VAX_FLOAT_FORMAT. Remove reference to HOST_FLOAT_FORMAT.
- (VAX_HALFWORD_ORDER): Document.
- (LARGEST_EXPONENT_IS_NORMAL): Remove note about being only for
- IEEE float format.
- (TARGET_SCHED_ISSUE_RATE): Reword reference to MAX_DFA_ISSUE_RATE.
- (ASM_OUTPUT_LABEL_REF): Fix font.
- (CASE_VECTOR_SHORTEN_MODE): Ditto.
-
-2002-08-30 Denis Chertykov <denisc@overta.ru>
-
- * config/ip2k/ip2k.c (ip2k_set_compare): Remove all const_double
- stuff.
- (ip2k_gen_unsigned_comp_branch): Handle CONST_INT and
- CONST_DOUBLE constants.
-
-2002-08-30 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/alpha/alpha.h (TARGET_CPU_CPP_BUILTINS): Move language-
- related defines to...
- (SUBTARGET_LANGUAGE_CPP_BUILTINS): ...here.
- * config/alpha/netbsd.h (SUBTARGET_LANGUAGE_CPP_BUILTINS): Redefine
- as a no-op.
-
-2002-08-30 Krister Walfridsson <cato@df.lth.se>
-
- * config/arm/arm.c (arm_asm_output_labelref): New function.
- * config/arm/arm.h (ASM_OUTPUT_LABELREF): Call arm_asm_output_labelref.
- * config/arm/arm-protos.h: Add prototype for arm_asm_output_labelref.
-
-2002-08-29 Rodney Brown <rbrown64@csc.com.au>
-
- * doc/install.texi (Specific, alpha*-dec-osf*): Add "virtual
- memory exhausted" workarounds.
-
-2002-08-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * diagnostic.c (fancy_abort): Don't repeat "internal error".
- * toplev.c (crash_signal): Likewise.
-
-2002-08-30 Nicola Pero <n.pero@mi.flashnet.it>
-
- * doc/cpp.texi (__NEXT_RUNTIME__): Extended documentation.
- * doc/invoke.texi (-fnext-runtime, -Wno-protocol, -Wselector):
- Extended, updated documentation.
- (-Wundeclared-selector): Documented.
-
-2002-08-29 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/chorus.h: Consistently define *_DEBUGGING_INFO with
- the value 1. Do not undef before defining.
- * config/darwin.h: Likewise.
- * config/dbx.h: Likewise.
- * config/dbxcoff.h: Likewise.
- * config/dbxelf.h: Likewise.
- * config/elfos.h: Likewise.
- * config/interix.h: Likewise.
- * config/lynx-ng.h: Likewise.
- * config/lynx.h: Likewise.
- * config/netware.h: Likewise.
- * config/psos.h: Likewise.
- * config/svr3.h: Likewise.
- * config/alpha/alpha.h: Likewise.
- * config/alpha/elf.h: Likewise.
- * config/alpha/vms.h: Likewise.
- * config/arc/arc.h: Likewise.
- * config/arm/aout.h: Likewise.
- * config/arm/coff.h: Likewise.
- * config/c4x/c4x.h: Likewise.
- * config/h8300/h8300.h: Likewise.
- * config/i386/cygwin.h: Likewise.
- * config/i386/djgpp.h: Likewise.
- * config/i386/gas.h: Likewise.
- * config/i386/gstabs.h: Likewise.
- * config/i386/i386-coff.h: Likewise.
- * config/i386/i386-interix.h: Likewise.
- * config/i386/sco5.h: Likewise.
- * config/i386/svr3dbx.h: Likewise.
- * config/i386/sysv3.h: Likewise.
- * config/i386/win32.h: Likewise.
- * config/i386/x86-64.h: Likewise.
- * config/i960/i960.h: Likewise.
- * config/ia64/ia64.h: Likewise.
- * config/ip2k/ip2k.h: Likewise.
- * config/m32r/m32r.h: Likewise.
- * config/m68k/3b1.h: Likewise.
- * config/m68k/3b1g.h: Likewise.
- * config/m68k/ccur-GAS.h: Likewise.
- * config/m68k/coff.h: Likewise.
- * config/m68k/hp2bsd.h: Likewise.
- * config/m68k/hp310g.h: Likewise.
- * config/m68k/hp320g.h: Likewise.
- * config/m68k/hp3bsd.h: Likewise.
- * config/m68k/hp3bsd44.h: Likewise.
- * config/m68k/linux-aout.h: Likewise.
- * config/m68k/m68k-aout.h: Likewise.
- * config/m68k/mot3300.h: Likewise.
- * config/m68k/netbsd.h: Likewise.
- * config/m68k/openbsd.h: Likewise.
- * config/m68k/pbb.h: Likewise.
- * config/m68k/plexus.h: Likewise.
- * config/m68k/sun2.h: Likewise.
- * config/m68k/sun3.h: Likewise.
- * config/m68k/tower-as.h: Likewise.
- * config/m68k/vxm68k.h: Likewise.
- * config/m88k/aout-dbx.h: Likewise.
- * config/m88k/m88k-aout.h: Likewise.
- * config/mcore/mcore-elf.h: Likewise.
- * config/mcore/mcore-pe.h: Likewise.
- * config/mips/elf.h: Likewise.
- * config/mips/elf64.h: Likewise.
- * config/mips/iris5gas.h: Likewise.
- * config/mips/iris6.h: Likewise.
- * config/mips/mips.h: Likewise.
- * config/mips/sni-gas.h: Likewise.
- * config/mmix/mmix.h: Likewise.
- * config/ns32k/netbsd.h: Likewise.
- * config/pa/pa64-hpux.h: Likewise.
- * config/romp/romp.h: Likewise.
- * config/rs6000/sysv4.h: Likewise.
- * config/rs6000/xcoff.h: Likewise.
- * config/sh/coff.h: Likewise.
- * config/sh/elf.h: Likewise.
- * config/sparc/linux64.h: Likewise.
- * config/sparc/liteelf.h: Likewise.
- * config/sparc/netbsd.h: Likewise.
- * config/sparc/openbsd.h: Likewise.
- * config/sparc/pbd.h: Likewise.
- * config/sparc/sp64-elf.h: Likewise.
- * config/sparc/sp86x-elf.h: Likewise.
- * config/sparc/sparc.h: Likewise.
- * config/vax/vax.h: Likewise.
- * config/vax/vaxv.h: Likewise.
-
-2002-08-29 "Dhananjay R. Deshpande" <dhananjayd@kpit.com>
-
- * h8300.c (shift_alg_hi): Various tweaks to improve performance
- of HImode shifts.
- (get_shift_alg): Corresponding changes.
-
-2002-08-29 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * som.h (ALWAYS_STRIP_DOTDOT): Define to 1.
-
-2002-08-29 Richard Henderson <rth@redhat.com>
-
- * expr.h (enum block_op_methods): New.
- (emit_block_move): Update prototype.
- * expr.c (block_move_libcall_safe_for_call_parm): New.
- (emit_block_move_via_loop): New.
- (emit_block_move): Use them. New argument METHOD.
- (emit_push_insn): Always respect the given alignment.
- (expand_assignment): Update call to emit_block_move.
- (store_expr, store_field, expand_expr): Likewise.
- * builtins.c (expand_builtin_apply): Likewise.
- (expand_builtin_memcpy, expand_builtin_va_copy): Likewise.
- * function.c (expand_function_end): Likewise.
- * config/sh/sh.c (sh_initialize_trampoline): Likewise.
- * config/sparc/sparc.c (sparc_va_arg): Likewise.
- * calls.c (expand_call, emit_library_call_value_1): Likewise.
- (save_fixed_argument_area): Use emit_block_move with
- BLOCK_OP_CALL_PARM instead of move_by_pieces.
- (restore_fixed_argument_area): Likewise.
- (store_one_arg): Fix alignment parameter to emit_push_insn.
-
-2002-08-29 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * install.texi (hppa64-hp-hpux11*): Document installation procedure.
-
-2002-08-29 Catherine Moore <clm@redhat.com>
-
- * config/v850/v850.h (MULDI3_LIBCALL, UCMPDI2_LIBCALL, CMPDI2_LIBCALL,
- NEGDI2_LIBCALL, INIT_TARGET_OPTABS, MASK_STRICT_ALIGN): Define.
- (PREDICATE_CODES): Include new predicates.
- (RTX_COSTS): Handle UMOD and UDIV. Tune MULT for v850e.
- (TARGET_SWITCHES): Add strict-align.
- (TARGET_STRICT_ALIGN): New.
- (MASK_DEFAULT, STRICT_ALIGNMENT): Redefine.
- * config/v850/t-v850 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
- Define.
- (LIB1ASMFUNCS): Add v850_negdi2, v850_cmpdi2, v850_ucmpdi2,
- v850_muldi3.
- * config/v850/lib1funcs.asm (L_callt_save_r2_r29, L_return_r2_r29,
- L_callt_save_r2_r31, L_return_r2_r31,
- L_save_all_interrupt): Change addi to add.
- (L_save_interrupt, L_return_interrupt): Rework.
- (__return_r31): Correct .size directive.
- (mulsi3, divsi3, udivsi3, umodsi3, modsi3): Tune for v850e.
- (v850_negdi2, v850_cmpdi2, v850_ucmpdi2, v850_muldi3):
- New routines.
- * config/v850/v850.c (expand_prologue): Call
- gen_callt_save_interrupt, gen_callt_restore_all_interrupt,
- gen_callt_return_interrupt and gen_callt_save_all_interrupt.
- (reg_or_int9_operand): New predicate.
- (reg_or_const_operand): New routine.
- * config/v850/v850.md (return_interrupt): Changed from
- restore_interrupt.
- (callt_save_all_interrupt): Changed from save_all_interrupt_v850e.
- (callt_save_interrupt): Change save sequence.
- (callt_return_interrupt): New.
- (save_interrupt): Don't use runtime function for LONG_CALLS
- and TARGET_PROLOG_FUNCTION.
- (save_all_interrupt): Likewise.
- (mulsi3): Use new predicate.
- (moviscc): Disallow some combination of constants.
- Fix define_split for sasf insns, so that it will not generate bad
- code if operand0 and operand5 are the same.
- * config/v850/v850-protos.h: Prototype new predicates.
-
-2002-08-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * c-common.c (builtin_define_type_precision): New function.
- (cb_register_builtins): Use it. Define __WCHAR_UNSIGNED__ is
- wchar_t is unsigned in C++.
- * doc/cpp.texi (Common Predefined Macros): Document
- __WCHAR_UNSIGNED__, __CHAR_BIT__, __WCHAR_BIT__, __SHRT_BIT__,
- __INT_BIT__, __LONG_BIT__, __LONG_LONG_BIT__, __FLOAT_BIT__,
- __DOUBLE_BIT__, __LONG_DOUBLE_BIT__.
-
-2002-08-28 Sylvain Pion <pion@cs.nyu.edu>
-
- * doc/invoke.texi (-Wreorder): Remove remaining pieces from the generic
- section. Mention that it is enabled by -Wall.
- (-Wall): Mention that there can be language-specific warnings as well.
- (-Wctor-dtor-privacy): Mention that it is enabled by default.
- (-Wnon-virtual-dtor): Mention that it is enabled by -Wall.
-
-2002-08-28 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.c (calc_live_regs): Save FPSCR_REG in an interrupt handler
- if it is ever live.
-
- * sh.c (sh_handle_interrupt_handler_attribute): Reject interrupt_handler
- attribute for SHCOMPACT.
-
- * sh.h (OVERRIDE_OPTIONS): If align_function isn't set, set it
- appropriately.
- (FUNCTION_BOUNDARY): Specify only the minimum alignment required
- by the ABI.
-
- * sh.h (SH5_WOULD_BE_PARTIAL_NREGS): Also handle TImode case.
-
-2002-08-28 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config.gcc (mips*-*-netbsd*): Set target_cpu_default to
- "MASK_GAS|MASK_ABICALLS".
- * config/mips/netbsd.h (TARGET_ENDIAN_DEFAULT)
- (TARGET_DEFAULT): Remove.
- (MACHINE_TYPE): Undefine before defining.
- (DBX_DEBUGGING_INFO, PREFERRED_DEBUGGING_TYPE): Remove.
-
-2002-08-27 Mark Mitchell <mark@codesourcery.com>
-
- * c-common.c (warn_abi): New variable.
- * c-common.h (warn_abi): Likewise.
- * c-opts.c (COMMAND_LINE_OPTIONS): Add -Wabi.
- (c_common_decode_option): Handle it.
- * doc/invoke.texi: Document -Wabi.
-
-2002-08-27 Nicola Pero <n.pero@mi.flashnet.it>
-
- * c-common.c (warn_undeclared_selector): New variable.
- * c-common.h (warn_undeclared_selector): Idem.
- * c-opts.c (c_common_decode_option): Set warn_undeclared_selector
- to on when -Wundeclared-selector is found.
- (COMMAND_LINE_OPTIONS): Added -Wundeclared-selector.
- * objc/objc-act.c (build_selector_expr): If
- warn_undeclared_selector is set, check that the selector has
- already been defined, and emit a warning if not.
-
-2002-08-27 Nick Clifton <nickc@redhat.com>
- Catherine Moore <clm@redhat.com>
- Jim Wilson <wilson@cygnus.com>
-
- * config.gcc: Add v850e-*-* target.
- Add --with-cpu= support for v850.
- * config/v850/lib1funcs.asm: Add v850e callt functions.
- * config/v850/v850.h: Add support for v850e target.
- * config/v850/v850.c: Add functions to support v850e target.
- * config/v850/v850-protos.h: Add prototypes for new functions in v850.c.
- * config/v850/v850.md: Add patterns for v850e instructions.
- * doc/invoke.texi: Document new v850e command line switches.
-
-2002-08-27 J"orn Rennecke <joern.rennecke@superh.com>
- Aldy Hernandez <aldyh at redhat dot com>
-
- * doc/tm.texi: Applied numerous fixes to the automaton based
- scheduler descrition.
-
-2002-08-27 Jan Hubicka <jh@suse.cz>
-
- * i386.c (classify_argument): Handle variable sized objects.
-
-2002-08-27 Jan Hubicka <jh@suse.cz>
-
- * i386.c (ix86_expand_int_movcc): Fix RTL sharing problem
-
-2002-08-27 Jan Hubicka <jh@suse.cz>
-
- * libgcc2.c (__bb_exit_func): Properly write the summarized statistics.
-
-2002-08-27 Jan Hubicka <jh@suse.cz>
-
- * i386.c (classify_argument): Properly compute word size of the analyzed object.
-
-2002-08-27 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.md (attribute type): Add types mt_group, fload, pcfload, fpul_gp,
- mac_gp ftrc_s and cwb. Add / Adjust definitions in individual insn
- accordingly.
- (attribute insn_class): Provide default definitions based on type.
- Remove all insn-specific settings.
- (various function units): Remove old SH4 scheduling.
- (branch_zero, dfp_comp, late_fp_use, any_fp_comp, any_int_load):
- New attributes. Set them where appropriate.
- (cpu unit FS): Don't define / use.
- (F3, load_store): New cpu units.
- (F01): New reservation.
- (all insn_reservations): Make dependent on sh4 pipeline model.
- Fix latencies.
- (nil, reg_mov, freg_mov, sh4_fpul_gp, sh4_call): New insn_reservations.
- (sh4_mac_gp, fp_arith_ftrc, arith3, arith3b): Likewise.
- (mt insn_reservation): Use type mt_group.
- (insn_reservation load_store): Split into sh4_load, sh4_load_si,
- sh4_fload and sh4_store.
- (insn_reservation branch_zero and branch): Replace with sh4_branch.
- (insn_reservation branch_far): Replace with sh4_return.
- (insn_reservation return_from_exp): Rename to:
- (sh4_return_from_exp). Change to be just d_lock*5.
- (insn_reservation lds_to_pr): Rename to:
- (sh4_lds_to_pr). Change to be just d_lock*2.
- (insn_reservation ldsmem_to_pr, sts_from_pr): Change to be just
- d_lock*2.
- (insn_reservation prload_mem): Rename to:
- (sh4_prstore_mem). Change to d_lock*2,nothing,memory.
- (insn_reservation fpscr_store): Rename to:
- (fpscr_load). Change to d_lock,nothing,F1*3.
- (insn_reservation fpscr_store_mem): Rename to:
- (fpscr_load_mem). Change to d_lock,nothing,(F1+memory),F1*2.
- (insn_reservation multi): Change to
- d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2.
- (insn_reservation fp_arith): Change to issue,F01,F2.
- (insn_reservation fp_div: Change to issue,F01+F3,F2+F3,F3*7,F1+F3,F2.
- (insn_reservation dp_float): Change to issue,F01,F1+F2,F2.
- (insn_reservation fp_double_arith): Change to issue,F01,F1+F2,fpu*4,F2.
- (insn_reservation fp_double_cmp): Change to
- d_lock,(d_lock+F01),F1+F2,F2.
- (insn_reservation dp_div): Change to
- issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2.
- * sh.c (flow_dependent_p, flow_dependent_p_1): New functions.
- (sh_adjust_cost, SHcompact): Differentiate between different
- kinds of dependencies. Drop factor of ten for superscalar.
- Use new instruction types. Add new exception rules.
-
- * sh.md (mulhisi3, umulhisi3: Add a REG_EQUAL note.
-
- * sh.md (mperm_w): Add DONE.
-
-2002-08-27 David Edelsohn <edelsohn@gnu.org>
-
- * longlong.h: Import current PowerPC defintion from GMP-4.1.
-
- * config/rs6000/rs6000.h (MIN_UNITS_PER_WORD): Add IN_LIBGCC2 case.
-
- * config/rs6000/linux64.h (ADJUST_FIELD_ALIGN): Undef before define.
-
-2002-08-27 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.h (MAX_FIXED_MODE_SIZE): Define.
-
-2002-08-27 Gabriel Dos Reis <gdr@soliton.integrable-solutions.net>
-
- * doc/cpp.texi (Common Predefined Macros): Don't mess with table
- delimiter.
-
-2002-08-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * c-common.c (cpp_define_data_format): New function.
- (cb_register_builtins): Call it.
-
- * doc/cpp.texi (Common Predefined Macros): Document
- __TARGET_BITS_ORDER__, __TARGET_BYTES_ORDER__,
- __TARGET_INT_WORDS_ORDER__, __TARGET_FLOAT_WORDS_ORDER__,
- __TARGET_FLOAT_FORMAT__, __TARGET_USES_VAX_F_FLOAT__,
- __TARGET_USES_VAX_D_FLOAT__, __TARGET_USES_VAX_G_FLOAT__,
- __TARGET_USES_VAX_H_FLOAT__.
-
-2002-08-26 Ziemowit Laski <zlaski@apple.com>
-
- * objc/objc-act.c (get_super_receiver): If inside a class method
- of a category, cast the receiver to 'id' before accessing the 'isa'
- field so that <objc/objc-class.h> is not needed. For NeXT runtime.
-
-2002-08-26 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390-protos.h (s390_function_prologue,
- s390_function_epilogue): Remove.
- config/s390/s390.c (s390_function_prologue, s390_function_epilogue,
- TARGET_ASM_FUNCTION_PROLOGUE, TARGET_ASM_FUNCTION_EPILOGUE): Remove.
-
- config/s390/s390.c (s390_machine_dependent_recorg): New function.
- config/s390/s390-protos.h (s390_machine_dependent_reorg): Declare it.
- config/s390/s390.h (MACHINE_DEPENDENT_REORG): Call it.
- config/s390/s390.c (s390_split_branches, s390_chunkify_pool): Adapt
- to being called from MACHINE_DEPENDENT_REORG. Update regs_ever_live.
-
- config/s390/s390.c (s390_frame_info): Inline save_fprs_p. Always
- assume BASE_REGISTER and RETURN_REGNUM need to be saved.
- (s390_emit_prologue): Assume RETURN_REGNUM to be saved iff
- function is not a leaf function. Use save_gprs and restore_gprs.
- (s390_emit_epilogue): Likewise.
- (save_gprs, restore_gprs): New functions.
- (struct s390_frame): Remove return_reg_saved_p member.
- (save_fprs_p): Remove.
- (s390_optimize_prolog): New function.
- (s390_legitimate_reload_constant): Remove now unnecessary check.
-
- (s390_function_count): Remove.
- (s390_output_symbolic_const): Replace s390_function_count by
- current_function_funcdef_no.
- (s390_output_constant_pool): Likewise.
-
- (legitimize_pic_address): Use regs_ever_live to track PIC register
- instead of current_function_uses_pic_offset_table.
- (s390_emit_prologue): Likewise.
- config/s390/s390.md ("call", "call_value"): Likewise.
-
-2002-08-26 Neil Booth <neil@daikokuya.co.uk>
-
- * c-opts.c (find_opt): Don't complain about wrong languages
- here. Return exact matches even for wrong language.
- (c_common_decode_option): Complain about wrong languages
- here.
-
-2002-08-24 Stuart Hastings <stuart@apple.com>
-
- * function.h (struct function): Add flag
- all_throwers_are_sibcalls.
- * except.c (set_nothrow_function_flags): Replaces
- nothrow_function_p. Set new flag.
- * except.h (set_nothrow_function_flags): Replaces
- nothrow_function_p.
- * dwarf2out.c (struct dw_fde_struct): Add flag
- all_throwers_are_sibcalls.
- (output_call_frame_info): Test it.
- (dwarf2out_begin_prologue) Propagate it from cfun to
- dw_fde_struct.
- * toplev.c (rest_of_compilation): Update calls to
- nothrow_function_p.
-
-2002-08-23 Zack Weinberg <zack@codesourcery.com>
-
- * ggc-page.c (compute_inverse): Short circuit calculation for
- object sizes larger than half a page.
-
-2002-08-23 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.c (rs6000_elf_select_section): Treat
- DEFAULT_ABI == ABI_AIX like PIC. Test PIC & reloc for readonly
- default.
- (rs6000_elf_unique_section): Likewise.
-
-2002-08-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * ns32k.c (ns32k_globalize_label): Delete.
- * ns32k.h (ASM_OUTPUT_LABEL, TARGET_ASM_GLOBALIZE_LABEL): Delete.
-
-2002-08-23 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.c (output_mi_thunk): Don't determine insns
- for loading delta with num_insns_constant_wide. Calculate
- delta_low, delta_high without using a conditional.
-
-2002-08-22 Jason Merrill <jason@redhat.com>
-
- * c-common.h (RETURN_STMT_EXPR): Rename from RETURN_EXPR.
- * c-common.def: Adjust.
- * c-dump.c (c_dump_tree): Adjust.
- * c-semantics.c (genrtl_return_stmt): Adjust.
- * c-pretty-print.c (pp_c_statement): Adjust.
- * tree-inline.c (copy_body_r): Adjust.
-
-2002-08-22 Zack Weinberg <zack@codesourcery.com>
-
- * ggc-page.c: Avoid division in ggc_set_mark.
- (DIV_MULT, DIV_SHIFT, OFFSET_TO_BIT, inverse_table,
- compute_inverse): New.
- (ggc_set_mark, ggc_marked_p): Use OFFSET_TO_BIT.
- (init_ggc): Initialize inverse_table.
-
-2002-08-22 Tom Tromey <tromey@redhat.com>
-
- * doc/install.texi (Configuration): Document --datadir.
-
-2002-08-22 Alexandre Oliva <aoliva@redhat.com>
-
- * Makefile.in ($(BUILD_PREFIX_1)varray.o): Depend on $(GGC_H).
-
-2002-08-22 Hans-Peter Nilsson <hp@bitrange.com>
-
- * gengtype-lex.l (ID): Allow underscore as first character.
-
-2002-08-21 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.c (rs6000_xcoff_asm_globalize_label): New
- function.
- (rs6000_xcoff_asm_named_section): Rename.
- * config/rs6000/xcoff.h (TARGET_ASM_GLOBALIZE_LABEL): Define.
-
-2002-08-21 Tom Tromey <tromey@redhat.com>
-
- For PR java/6005 and PR java/7611:
- * fold-const.c (fold_truthop): Use can_use_bit_fields_p.
- (fold): Likewise.
- * langhooks.c (lhd_can_use_bit_fields_p): New function.
- * langhooks-def.h (lhd_can_use_bit_fields_p): Declare.
- (LANG_HOOKS_CAN_USE_BIT_FIELDS_P): New define.
- (LANG_HOOKS_INITIALIZER): Use it.
- * langhooks.h (struct lang_hooks) [can_use_bit_fields_p]: New
- field.
-
-2002-08-21 Stan Shebs <shebs@apple.com>
-
- * tree.c (finish_vector_type): Fix a typo in a comment.
- * Makefile.in: Fix "the the" stutters in comments.
- * genautomata.c: Ditto.
- * ifcvt.c: Ditto.
- * regrename.c: Ditto.
- * config/alpha/alpha.c: Ditto.
- * config/alpha/vms-crt0-64.c: Ditto.
- * config/alpha/vms-crt0.c: Ditto.
- * config/alpha/vms-psxcrt0-64.c: Ditto.
- * config/alpha/vms-psxcrt0.c: Ditto.
- * config/d30v/d30v.h: Ditto.
- * config/fr30/fr30.h: Ditto.
- * config/rs6000/rs6000.c: Ditto.
- * config/stormy16/stormy16.h: Ditto.
- * doc/md.texi: Ditto.
-
-2002-08-21 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * cppinit.c (remove_dup_nonsys_dirs): Fix warning and return value.
-
-2002-08-21 Joseph S. Myers <jsm@polyomino.org.uk>
-
- * c-decl.c (grokdeclarator): Make invalid combinations with long,
- short, signed or unsigned into hard errors. Fixes PR c/4319.
- Also make duplicate modifiers such as "short short" into hard
- errors.
-
-2002-08-21 Andrew Pinski <pinskia@physics.uc.edu>
- Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * doc/tm.texi (TARGET_ASM_GLOBALIZE_LABEL): Move '@end deftypefn'
- to the actual end. Add '@end table' and '@table @code'.
-
-2002-08-20 Geoffrey Keating <geoffk@redhat.com>
-
- * doc/tm.texi (Label Output): Add missing '@end deftypefn'.
-
- * unroll.c (biv_total_increment): Don't try to compute the total
- increment for FP BIVs.
-
-2002-08-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * alpha.c (TARGET_ASM_GLOBALIZE_LABEL): Define for unicosmk.
- * alpha/elf.h (ASM_OUTPUT_EXTERNAL_LIBCALL,
- ASM_OUTPUT_ALIGNED_BSS): Use target hook.
- * alpha/osf.h (ASM_OUTPUT_WEAK_ALIAS): Likewise.
- * alpha/unicosmk.h (ASM_GLOBALIZE_LABEL): Delete.
- * arm/aof.h (ASM_GLOBALIZE_LABEL): Likewise.
- (GLOBAL_ASM_OP): Define.
- * arm.c (aof_globalize_label): New function.
- (TARGET_ASM_GLOBALIZE_LABEL): Define for AOF.
- * arm/unknown-elf.h (ASM_OUTPUT_ALIGNED_BSS): Use target hook.
- * c4x.c (c4x_globalize_label): New function.
- (TARGET_ASM_GLOBALIZE_LABEL): Define for c4x.
- * c4x.h (ASM_GLOBALIZE_LABEL): Delete.
- (GLOBAL_ASM_OP): Define.
- * cris/aout.h (ASM_OUTPUT_EXTERNAL_LIBCALL): Use target hook.
- * darwin-protos.h (darwin_globalize_label): Declare.
- * darwin.c (darwin_globalize_label): New function.
- * darwin.h (ASM_DECLARE_CLASS_REFERENCE): Use target hook.
- (ASM_GLOBALIZE_LABEL): Delete.
- (GLOBAL_ASM_OP, TARGET_ASM_GLOBALIZE_LABEL): Define.
- * dsp16xx.c (asm_output_common): Use target hook.
- * elfos.h (ASM_OUTPUT_EXTERNAL_LIBCALL): Likewise.
- * frv.h (ASM_GLOBALIZE_LABEL): Delete.
- (GLOBAL_ASM_OP): Define.
- * i370.c (i370_globalize_label): New function.
- (TARGET_ASM_GLOBALIZE_LABEL): Define for i370.
- * i370.h (ASM_GLOBALIZE_LABEL): Delete.
- * i386.c (ix86_asm_file_end): Use target hook.
- * i386/sco5.h (ASM_GLOBALIZE_LABEL): Don't undef.
- (ASM_OUTPUT_EXTERNAL_LIBCALL): Use target hook.
- * ia64.c (ia64_asm_output_external): Likewise.
- * ia64/sysv4.h: Update comment.
- * m32r.h (ASM_OUTPUT_ALIGNED_BSS): Use target hook.
- * mips/elf.h (ASM_OUTPUT_ALIGNED_BSS): Likewise.
- * mips/iris5.h (ASM_OUTPUT_WEAK_ALIAS): Use target hook.
- * mips/linux.h (ASM_OUTPUT_ALIGNED_BSS): Likewise.
- * mips.h (ASM_OUTPUT_ALIGNED_DECL_COMMON): Use target hook.
- * mmix-protos.h (mmix_asm_globalize_label): Delete.
- * mmix.c (mmix_asm_globalize_label): Likewise.
- * mmix.h (ASM_GLOBALIZE_LABEL): Likewise.
- (GLOBAL_ASM_OP): Define.
- * ns32k.c (ns32k_globalize_label): New function.
- * ns32k.h (TARGET_ASM_GLOBALIZE_LABEL): Define for ns32k.
- (ASM_GLOBALIZE_LABEL): Delete.
- * pa/pa-linux.h (ASM_GLOBALIZE_LABEL): Don't undef.
- (TARGET_ASM_GLOBALIZE_LABEL): Undefine.
- * pa.c (pa_globalize_label): New function.
- * pa.h (ASM_GLOBALIZE_LABEL): Delete.
- (TARGET_ASM_GLOBALIZE_LABEL): Define for pa.
- * rs6000/darwin.h (ASM_GLOBALIZE_LABEL): Delete.
- (GLOBAL_ASM_OP): Define.
- (TARGET_ASM_GLOBALIZE_LABEL): Undef.
- * rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_BSS): Use target hook.
- * rs6000/xcoff.h (ASM_GLOBALIZE_LABEL): Delete.
- (GLOBAL_ASM_OP): Define.
- * v850.c (v850_output_aligned_bss): Use target hook.
- * vax.c (vms_globalize_label): New function.
- (TARGET_ASM_GLOBALIZE_LABEL): Define for vms.
- * vax/vms.h (ASM_GLOBALIZE_LABEL): Delete.
- (GLOBAL_ASM_OP): Define.
- * defaults.h (ASM_GLOBALIZE_LABEL): Delete.
- * doc/tm.texi: Update docs.
- * dwarf2out.c (default_eh_frame_section, output_die_symbol): Use
- target hook.
- * final.c (output_alternate_entry_point): Likewise.
- * hooks.c (hook_FILEptr_constcharptr_void): New function.
- * hooks.h (hook_FILEptr_constcharptr_void): Declare.
- * output.h (assemble_global): Delete.
- (default_globalize_label): Declare.
- * system.h (ASM_GLOBALIZE_LABEL): Poison.
- * target-def.h (TARGET_ASM_GLOBALIZE_LABEL): Define.
- (TARGET_ASM_OUT): Add TARGET_ASM_GLOBALIZE_LABEL.
- * target.h (gcc_target): Add globalize_label member.
- * varasm.c (asm_output_bss, asm_output_aligned_bss,
- globalize_decl): Use target hook.
- (assemble_global): Delete.
- (default_globalize_label): New function.
-
-2002-08-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * dsp16xx.h (dsp16xx_umulhi3_libcall): Delete.
-
-2002-08-20 Devang Patel <dpatel@apple.com>
- * tree.c (get_qualified_type): Add TYPE_CONTEXT check.
-
-2002-08-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * arc.c (output_shift): Use stdio instead of asm_fprintf.
- * arm.c (thumb_output_function_prologue): Likewise.
- * avr.c (print_operand): Likewise.
- * c4x.c (c4x_print_operand): Likewise.
- * c4x.h (ASM_OUTPUT_INTERNAL_LABEL, TRAMPOLINE_TEMPLATE,
- ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Likewise.
- * cris.c (cris_target_asm_function_prologue,
- cris_asm_output_mi_thunk): Likewise.
- * h8300.c (print_operand): Likewise.
- * h8300.h (ASM_OUTPUT_ADDR_VEC_ELT): Likewise.
- * ip2k.c (print_operand): Likewise. Fix format specifier.
- * m68hc11.c (asm_print_register, print_operand,
- print_operand_address): Use stdio instead of asm_fprintf.
- (print_operand_address): Fix format specifier.
- * m68hc11.h (FUNCTION_PROFILER, ASM_OUTPUT_ADDR_DIFF_ELT,
- ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ALIGN): Use stdio instead of
- asm_fprintf.
- * m68k/amix.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
- * m68k/atari.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
- * m68k.c (m68k_output_function_prologue,
- m68k_output_function_epilogue, print_operand): Likewise.
- * mmix.c (mmix_asm_output_mi_thunk, mmix_asm_weaken_label):
- Likewise. Fix format specifier.
- * mn10200.h (ASM_OUTPUT_ADDR_VEC_ELT): Likewise.
- * mn10300.h (ASM_OUTPUT_ADDR_VEC_ELT): Likewise.
- * v850.h (ASM_OUTPUT_ADDR_VEC_ELT): Likewise.
-
-2002-08-15 Eric Christopher <echristo@redhat.com>
- Jeff Knaggs <jknaggs@redhat.com>
-
- * config.gcc (mipsisa64sr71k-elf): New target.
- * config/mips/sr71k.md: New file.
- * config/mips/mips.md: Use it.
- (rot*): Add sr71k specifics.
- * config/mips/t-sr71k: New file.
- * config/mips/mips.h (sr71k): New cpu.
- (TARGET_SR71K): Use it.
- (TUNE_SR71K): Ditto.
- (GENERATE_BRANCHLIKELY): Ditto.
- (ISA_HAS_MULHI, ISA_HAS_MULS, ISA_HAS_MSAC, ISA_HAS_MACC,
- ISA_HAS_ROTR_SIISA_HAS_ROTR_DI): Ditto.
- * config/mips/mips.c (sr71k): New cpu.
- (mips_use_dfa_pipeline_interface): Use.
-
-2002-08-15 Eric Christopher <echristo@redhat.com>
- Richard Sandiford <rsandifo@redhat.com>
- Aldy Hernandez <aldyh@redhat.com>
- Graham Stott <grahams@redhat.com>
- Michael Meissner <meissner@redhat.com>
- Gavin Romig-Koch <gavin@redhat.com>
- Ken Raeburn <raeburn@cygnus.com>
- Alexandre Oliva <aoliva@redhat.com>
-
- * config.gcc (mips64vr-elf): New target.
- * config/mips/5400.md: New file.
- * config/mips/5500.md: Ditto.
- * config/mips/mips.md: Use them.
- (frsqrt): New.
- * config/mips/mips.c (vr4111, vr4121, vr4320, vr5400, vr5500): New
- cpus.
- (mips_issue_rate): Use them.
- (mips_use_dfa_pipeline_interface): New function. Use for 5400 and 5500.
- (TARGET_SCHEDUSE_DFA_PIPELINE_INTERFACE): Define. Use above.
- * config/mips/mips.h (vr4111, vr4121, vr4320, vr5400, vr5500): New
- cpus.
- (TARGET_MIPSx): Use them.
- (TUNE_MIPSx): Ditto.
- (GETNATE_MULT3_SI): Ditto.
- (ISA_HAS_BRANCHLIKELY): Ditto.
- (ISA_HAS_CONDMOVE): Ditto.
- (ISA_HAS_NMADD_NMSUB): Ditto.
- (ISA_HAS_MULHI): New. Ditto.
- (ISA_HAS_MULS): Ditto.
- (ISA_HAS_MSAC): Ditto.
- (ISA_HAS_MACC): Ditto.
- (ISA_HAS_ROTR_SI): Ditto.
- (ISA_HAS_ROTR_DI): Ditto.
- (RTX_COSTS): Use.
-
-2002-08-20 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * cppinit.c (remove_dup_dir): Add head_ptr argument to handle removal
- at head.
- (remove_dup_nonsys_dirs): New function.
- (remove_dup_dirs): Change argument head to head_ptr. Remove warnings.
- (merge_include_chains): Remove non-system include directories from
- quote and bracket include chains when they duplicate equivalent system
- directories.
- * doc/cpp.texi (-I): Update.
- * doc/cppopts.texi (-I): Update.
- * doc/install.texi (--with-local-prefix): Further document usage of
- this option.
- * doc/invoke.texi (-I): Update.
-
-2002-08-20 Richard Henderson <rth@redhat.com>
-
- * expr.c (TARGET_MEM_FUNCTIONS): Transform to boolean.
- (emit_block_move): Split out subroutines.
- (emit_block_move_via_movstr): New.
- (emit_block_move_via_libcall): New. Emit bcopy via normal call also.
- (emit_block_move_libcall_fn): New. Construct function prototype for
- bcopy as well.
- (clear_storage): Split out subroutines.
- (clear_storage_via_clrstr): New.
- (clear_storage_via_libcall): New. Emit bzero as a normal call also.
- (clear_storage_libcall_fn): New. Construct function prototype for
- bzero as well.
- (emit_push_insn): Use emit_block_move.
- (expand_assignment): Booleanize TARGET_MEM_FUNCTIONS.
- (store_constructor): Likewise.
-
-2002-08-19 Ziemowit Laski <zlaski@apple.com>
-
- * objc/objc-act.c (building_objc_message_expr): Rename to
- current_objc_message_selector.
-
-2002-08-19 Ziemowit Laski <zlaski@apple.com>
-
- * objc/objc-act.c (build_ivar_chain): Remove.
- (objc_copy_list): Likewise.
- (get_class_ivars): Inline call to removed build_ivar_chain
- function. Save off a clean copy of ivars in the CLASS_OWN_IVARS
- slot; use that slot (rather than CLASS_IVARS) when accessing
- ivars for base classes. Call copy_list and chainon instead of
- objc_copy_list.
- (build_private_template): Call get_class_ivars instead of
- build_ivar_chain.
- (start_class): Allocate room for the CLASS_OWN_IVARS slot.
- (continue_class): Call get_class_ivars instead of
- build_ivar_chain.
- (encode_field_decl): Check for DECL_BIT_FIELD_TYPE instead
- of DECL_BIT_FIELD (which may have been cleared).
- * objc/objc-act.h (CLASS_OWN_IVARS): New accessor macro.
-
-2002-08-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * genautomata.c (output_translate_vect, output_state_ainsn_table,
- output_min_issue_delay_table): Mark variable with ATTRIBUTE_UNUSED
- in output file.
- (output_internal_min_issue_delay_func): Initialize variable in
- output file.
-
-2002-08-19 Alexandre Oliva <aoliva@redhat.com>
-
- * Makefile.in (GCC_FOR_TARGET): Prepend STAGE_CC_WRAPPER.
- (stage2_build, stage3_build, stage4_build): Likewise, to CC.
-
-2002-08-19 Geoffrey Keating <geoffk@redhat.com>
- Steve Ellcey <sje@cup.hp.com>
-
- * machmode.h (SCALAR_INT_MODE_P): New macro to test for
- scaler integer mode (MODE_INT or MODE_PARTIAL_INT).
- * explow.c (trunc_int_for_mode): Abort when the mode is not
- a scaler integer mode.
- * combine.c (expand_compound_operation): Don't expand Vector
- or Complex modes into shifts.
- (expand_field_assignment): Don't do bitwise arithmatic and
- shifts on Vector or Complex modes.
- (simplify_comparison): Don't call trunc_int_for_mode
- for VOIDmode.
- * recog.c (general_operand): Likewise.
- (immediate_operand): Likewise.
- (nonmemory_operand): Likewise.
-
-2002-08-19 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.c (rs6000_emit_set_const): Inline
- multi-instruction SImode constant. Add REG_EQUAL note.
- * config/rs6000/rs6000.md (movsi splitter): Use
- rs6000_emit_set_const.
-
-2002-08-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * tree-inline.c (initialize_inlined_parameters): Wrap variable in
- the macro test controlling its use.
-
-2002-08-18 H.J. Lu (hjl@gnu.org)
-
- * config.gcc (*-*-linux*): Set extra_parts="crtbegin.o
- crtbeginS.o crtbeginT.o crtend.o crtendS.o", gas=yes and
- gnu_ld=yes.
- (alpha*-*-linux*, cris-*-linux*, i370-*-linux*,
- i[34567]86-*-linux*, x86_64-*-linux*, mips*-*-linux*,
- s390-*-linux*, s390x-*-linux*, sparc-*-linux*, sparc64-*-linux*,
- xtensa-*-linux*): Remove setting extra_parts, gas, and gnu_ld
- here.
- (cris-*-linux*): Remove setting thread_file here.
-
-2002-08-18 Neil Booth <neil@daikokuya.co.uk>
-
- PR preprocessor/7602
- * cppinit.c (path_include): Treat the system environment
- variables as being cxx_aware.
-
-2002-08-17 Joseph S. Myers <jsm@polyomino.org.uk>
-
- * c-decl.c (flexible_array_type_p): New function.
- (grokdeclarator, finish_struct): Use it.
- * doc/extend.texi: Document constraints on use of structures with
- flexible array members.
-
-2002-08-17 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/t-coff, config/mips/t-elf, config/mips/t-isa3264,
- config/mips/t-r3900 (MULTILIB_MATCHES): Define.
- * config/mips/mips.h (ASM_SPEC): Use %(endian_spec).
-
-2002-08-16 Stan Shebs <shebs@apple.com>
-
- * c-common.c (cb_register_builds): Define __NEXT_RUNTIME__
- for ObjC with -fnext-runtime.
- * doc/cpp.texi: Document it.
-
-2002-08-16 Janis Johnson <janis187@us.ibm.com>
-
- * doc/install.texi (Final installation): Replace links to individual
- build status pages with a link to a common page that lists them all.
-
-2002-08-16 Sylvain Pion <pion@cs.nyu.edu>
-
- * doc/invoke.texi: Fix typo.
-
-2002-08-16 David Edelsohn <edelsohn@gnu.org>
-
- * doc/install.texi (*-ibm-aix*): Explain AIX shared object versioning.
-
-2002-08-16 Andrew Haley <aph@redhat.com>
-
- * tree-inline.c: Add includes for Java inliner.
- (remap_decl): Don't handle anonymous types for Java.
- (remap_block): Add handling for Java trees.
- (copy_scope_stmt): Conditionalize for non-Java use only.
- (copy_body_r): Handle Java trees. Add handling for
- LABELED_BLOCK_EXPR, EXIT_BLOCK_EXPR, Java blocks.
- (initialize_inlined_parameters): Handle Java trees.
- (declare_return_variable): Likewise.
- (expand_call_inline): Handle Java trees.
- (walk_tree): Likewise.
- (copy_tree_r): Don't handle SCOPE_STMTs for Java.
- (add_stmt_to_compound): New function.
-
-2002-08-15 Richard Henderson <rth@redhat.com>
-
- * Makefile.in (LOOSE_WARN): Remove -fno-common.
- (NOCOMMON_FLAG): New substitution point.
- (GCC_WARN_CFLAGS): Include it.
- * configure.in (ac_checking): Set nocommon_flag.
- (nocommon_flag): New substitution point.
-
-2002-08-15 Alexandre Oliva <aoliva@redhat.com>
-
- * c-tree.h (skip_evaluation): Move declaration...
- * c-common.h: ... here.
- * c-typeck.c (build_external_ref): Don't assemble_external nor
- mark a tree as used if skip_evaluation is set.
- * c-parse.in (typeof): New non-terminal to set skip_evaluation
- around TYPEOF.
- (typespec_nonreserved_nonattr): Use it.
-
-2002-08-15 Douglas B Rupp <rupp@gnat.com>
-
- * dbxout.c (dbx_debug_hooks): Update end_prologue, end_epilogue.
- (xcoff_debug_hooks): Update end_prologue.
- * debug.c (do_nothing_debug_hooks): Update end_prologue, end_epilogue.
- * debug.h (end_prologue): Add file arg.
- (end_epilogue): Add line and file args.
- (dwarf2out_end_epilogue): Add line and file args.
- (vmsdbgout_after_prologue): Remove.
- * dwarf2out.c (dwarf2out_end_epilogue): Add line and file args.
- (dwarf2_debug_hooks): Update end_prologue.
- * dwarfout.c (dwarfout_end_epilogue): Add line and file args.
- (dwarfout_end_prologue): Add file arg.
- * final.c (vmsdbgout_after_prologue): Remove
- (final_end_function): Update end_epilogue call.
- (final_scan_insn): Update end_prologue call.
- * sdbout.c (sdbout_end_epilogue): Add line and file args.
- (sdbout_end_prologue): Add file arg.
- (sdb_debug_hooks): Update end_prologue.
- (sdb_begin_prologue): Update sdbout_end_prologue call.
- * vmsdbgout.c (vmsdbg_debug_hooks): Add vmsdbgout_end_prologue,
- vmsdbgout_end_function.
- (vmsdbgout_end_prologue): New function renamed from
- vmsdbgout_after_prologue. Call vmsdbgout_source_line.
- (vmsdbgout_end_function): New function.
- (vmsdbgout_end_epilogue): Add line and file args. Call
- vmsdbgout_source_line.
- (write_pclines): Write only valid line numbers.
- (write_srccorr): Don't write source correlation records if 0 lines.
- * xcoffout.c (xcoffout_end_epilogue): Add line and file args.
-
-2002-08-15 Steve Ellcey <sje@cup.hp.com>
-
- * gcc/unwind.h (_Unwind_Ptr): Make 64 bits on IA64 HP-UX.
- (_Unwind_Internal_Ptr): 32 bit version for use in
- read_encoded_value_with_base.
- * gcc/unwind-pe.h (read_encoded_value_with_base): Use
- _Unwind_Internal_Ptr instead of _Unwind_Ptr in order to get the
- right size.
-
-2002-08-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * loop.c (scan_loop, move_movables, count_one_set): Cast to avoid
- signed/unsigned warnings.
-
- * regclass.c (init_reg_sets_1, choose_hard_reg_mode,
- record_reg_classes): Likewise.
-
- * reload.c (reload_inner_reg_of_subreg, push_reload,
- find_reloads_address_1): Likewise.
-
-2002-08-15 David Edelsohn <edelsohn@gnu.org>
-
- * rs6000.c (output_mi_thunk): Return to function section on
- TARGET_ELF.
-
- * rs6000-c.c (rs6000_cpu_cpp_builtins): Define __PPC405__ if PPC405.
-
-2002-08-15 Ulrich Weigand <uweigand@de.ibm.com>
-
- * config/s390/s390.c (legitimize_address): Optimize loading
- of large displacements.
-
-2002-08-14 Douglas B Rupp <rupp@gnat.com>
-
- * config/alpha/alpha-protos.h: Update.
-
- * config/alpha/alpha.c: (LINKAGE_SYMBOL_REF_P): New macro.
- (alpha_legitimate_address_p): Test LINKAGE_SYMBOL_REF_P.
- (alpha_linkage_symbol_p): New static function.
- (print_operand_address): Print linkage operand.
-
- (alpha_funcs_num, alpha_funcs_tree, alpha_links_tree): New static
- variables.
- (reloc_kind): New enum.
- (struct alpha_funcs): New struct.
- (struct alpha_links): Add reloc_kind field. Rename links_kind field.
-
- (alpha_need_linkage): Rewrite.
- (alpha_use_linkage): New global function.
- (alpha_write_linkage): Rewrite and make static.
- (alpha_write_one_linkage): Rewrite
-
- (alpha_start_function): Remove procedure descriptor output.
- (alpha_end_function): Write linkages at end of each function.
-
- * config/alpha/alpha.md (call_vms, call_value_vms): Rewrite.
- (call_vms_1, call_value_vms_1): Rewrite.
-
- * config/alpha/vms.h (ASM_FILE_END): Remove.
-
-2002-08-14 Richard Henderson <rth@redhat.com>
-
- * ggc-page.c (RTL_SIZE): New.
- (extra_order_size_table): Add specializations for 2 and 10 rtl slots.
- * rtl.def (BARRIER, NOTE): Pad to 9 slots.
-
-2002-08-14 Richard Henderson <rth@redhat.com>
-
- * calls.c: Include target.h.
- * Makefile.in (calls.o): Update.
-
- * config/alpha/alpha.c (alpha_end_function): Use targetm.binds_local_p.
- * config/alpha/alpha.h (FUNCTION_OK_FOR_SIBCALL): Likewise.
-
-2002-08-14 Richard Henderson <rth@redhat.com>
-
- * Makefile.in (LOOSE_WARN): Add -fno-common.
- * c-common.h (constant_string_class_name): Add missing extern.
-
-2002-08-15 Neil Booth <neil@daikokuya.co.uk>
-
- PR preprocessor/7358
- * c-opts.c (check_deps_environment_vars): Ignore main file
- for SUNPRO_DEPENDENCIES.
- * cppfiles.c (stack_include_file): Ignore main file if
- appropriate.
- * cpplib.h (struct cpp_options): New member in deps.
- * doc/cppenv.texi: Update.
-
-2002-08-14 Neil Booth <neil@daikokuya.co.uk>
-
- PR preprocessor/7526
- * cpplib.c (run_directive): Kludge so _Pragma dependency works.
-
-2002-08-14 Nathan Sidwell <nathan@codesourcery.com>
-
- * doc/invoke.texi (-a): Remove documentation.
- (-fprofile-arcs): Remove reference to -a, -ax options.
- * doc/gcov.texi (Gcov Data Files): Data might be merged.
-
-2002-08-14 Gabriel Dos Reis <gdr@nerim.net>
-
- Fix PR/7566
- * c-semantics.c (genrtl_case_label): Don't (mis)use
- warning_with_decl.
-
-2002-08-14 Dale Johannesen <dalej@apple.com>
-
- * explow.c (emit_stack_restore): Emit memory clobbers
- preceding the stack pop, to prevent the scheduler from
- moving refs to variable arrays below this pop.
- * reload1.c (reload): Preserve these clobbers for sched2.
- * doc/rtl.texi: Document clobber (mem:BLK (scratch)).
-
-2002-08-14 Neil Booth <neil@daikokuya.co.uk>
-
- * c-opts.c (c_common_post_options): Correct test.
-
-2002-08-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * m88k.h (ASM_OUTPUT_SOURCE_FILENAME): Fix incorrect argument
- order in call to fprintf.
-
-2002-08-14 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
-
- * config/sparc/sol2.h (SUBTARGET_EXTRA_SPECS): Define.
-
-2002-08-14 Ulrich Weigand <uweigand@de.ibm.com>
-
- * reload.c (find_reloads): Handle constraint letters marked by
- EXTRA_ADDRESS_CONSTRAINT and EXTRA_MEMORY_CONSTRAINT.
- (alternative_allows_memconst): Likewise.
- * reload1.c (maybe_fix_stack_asms): Likewise.
- * recog.c (asm_operand_ok, preprocess_constraints,
- constrain_operands): Likewise.
- * regclass.c (record_operand_costs, record_reg_classes): Likewise.
- * local-alloc.c (block_alloc, requires_inout): Likewise.
- * stmt.c (parse_output_constraint, parse_input_constraint): Likewise.
-
- * defaults.h (EXTRA_MEMORY_CONSTRAINT): Provide a default.
- (EXTRA_ADDRESS_CONSTRAINT): Likewise.
- * doc/tm.texi: Document these two new target macros.
-
- * config/s390/s390.c (s390_expand_plus_operand): Accept already
- valid operands.
- (q_constraint): New function.
- config/s390/s390-protos.h (q_constraint): Declare it.
- config/s390/s390.h (EXTRA_CONSTRAINT): Use it.
- (EXTRA_MEMORY_CONSTRAINT): New macro.
-
- * config/s390/s390.md: Throughout the machine description,
- replace all instances of the constraint combinations 'Qo'
- or 'oQ' with simply 'Q'.
-
-2002-08-14 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.h (LINK_SPEC): Support -mrelax.
- * config/m68hc11/t-m68hc11-gas (LIBGCC2_DEBUG_CFLAGS): Can use -g now.
- (LIBGCC2_CFLAGS): Compile with -mrelax.
-
-2002-08-14 Stephane Carrez <stcarrez@nerim.fr>
-
- * doc/invoke.texi: Document -minmax for 68HC12.
-
- * config/m68hc11/m68hc11.md ("umaxqi3"): Use TARGET_MIN_MAX.
- ("uminqi3"): Likewise.
- ("uminhi3", "umaxhi3"): Likewise.
-
- * config/m68hc11/m68hc11.h (MASK_MIN_MAX): Define.
- (TARGET_MIN_MAX): Define.
- (TARGET_SWITCHES): New option -minmax/-mnominmax.
-
-2002-08-14 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/t-m68hc11-gas (LIB1ASMFUNCS): Build __far_trampoline.
- (MULTILIB_OPTIONS): Must also generate for -mlong-calls.
-
- * config/m68hc11/larith.asm: Put a mode for ELF ABI flags.
- (ret, declare, farsym): New gas macros.
- (__premain, exit, abort, _cleanup, memcpy, memset, ___adddi3,
- ___subdi3, ___notdi2, __mulhi32, __mulsi3): Use them to use 'rtc'
- and declare the symbol far when compiled with -mlong-calls.
- (__far_trampoline): New for 68HC12 trampoline code to invoke a
- far handler using jsr/bsr.
-
- * config/m68hc11/m68hc11-crt0.S: Put a mode for ELF ABI flags.
- (jsr): New macro to transform a 'jsr' into a 'call'.
-
-2002-08-14 Stephane Carrez <stcarrez@nerim.fr>
-
- * doc/invoke.texi: Document -mlong-calls for 68HC12.
-
- * config/m68hc11/m68hc11.h (CPP_SPEC): Pass -D__USE_RTC__ when
- -mlong-calls is specified.
- (ASM_DECLARE_FUNCTION_NAME): Define to generate .far and .interrupt
- assembler directives.
- (TARGET_LONG_CALL, MASK_LONG_CALL): Declare.
- (TARGET_SWITCHES): Add -mlong-calls options.
- (current_function_far): Declare.
-
- * config/m68hc11/m68hc11.c (m68hc11_initial_elimination_offset): Take
- into account the page register saved on the stack.
- (m68hc11_override_options): Take into account -mlong-calls option.
- (m68hc11_asm_file_start): Put a mode for the ELF flags ABI.
-
- * config/m68hc11/m68hc11.md ("*return_32bit"): Return rtc
- if the function is going to be in 68HC12 banked memory (-mlong-calls).
- ("*return_16bit"): Likewise.
- ("*return_void"): Likewise.
- ("call", "call_value"): Use call for a far function call.
-
-2002-08-14 Neil Booth <neil@daikokuya.co.uk>
-
- * toplev.c (parse_options_and_default_flags): Don't call
- post_options here.
- (general_init): Initialize GC, pools and tree hash here,
- instead of lang_independent_init.
- (lang_independent_init): Rename backend_init.
- (do_compile): Call post_options hook; exit early if there
- have been errors after switch processing.
- (toplev_main): Update.
-
-2002-08-14 Gabriel Dos Reis <gdr@nerim.net>
-
- * c-pretty-print.h: Guard against multiple inclusion.
- Robustify macros.
- (pp_c_attributes): Declare.
- * c-pretty-print.c (pp_c_attributes): New function.
-
-2002-08-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * m68k.c (m68k_output_function_prologue,
- m68k_output_function_epilogue): Delete versions for DPX2/MOTOROLA
- and NEWS/MOTOROLA.
- * genattrtab.c: Remove dpx2 comment.
- * libgcc2.c (__enable_execute_stack): Delete versions for
- NeXT/__MACH__, __convex__, __sysV88__, __pyr__ and
- sony_news/SYSTYPE_BSD.
- * longlong.h: Delete code for __a29k__, _AM29K, __clipper__,
- __gmicro__, __i860__, __NeXT__ and __pyr__.
- * rtl.h: Remove convex comment.
- * varasm.c: Likewise.
-
-2002-08-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * c-opts.c (lang_flags): Const-ify.
- * ra-build.c (undef_table): Likewise.
- * ra.c (eliminables): Likewise.
-
-2002-08-14 Gabriel Dos Reis <gdr@nerim.net>
-
- * tree.h: Guard against multiple inclusion.
-
-2002-08-14 Hans-Peter Nilsson <hp@bitrange.com>
-
- * reload1.c (reload_cse_simplify): Before checking
- REG_FUNCTION_VALUE_P, check REG_P.
-
-2002-08-13 Geoffrey Keating <geoffk@redhat.com>
-
- * Makefile.in (attribs.o): Remove $(OBSTACK_H) dependency.
-
-2002-08-13 Neil Booth <neil@daikokuya.co.uk>
-
- * c-opts.c (c_common_init_options): Extra braces needed.
-
-2002-08-13 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.c (sh_init_builtins): Add PARAMS to declaration.
- (sh_media_init_builtins, sh_expand_builtin): Likewise.
- (sh_expand_unop_v2sf): Use PARAMS for variable declaration.
- (sh_expand_binop_v2sf): Likewise.
- * sh-protos.h (sh_expand_unop_v2sf): Add PARAMS to declaration.
- (sh_expand_binop_v2sf, sh_cfun_interrupt_handler_p): Likewise.
- (sh_initialize_trampoline): Likewise.
-
-2002-08-13 Ulrich Weigand <uweigand@de.ibm.com>
-
- * s390-modes.def [CCL1, CCL2, CCT1, CCT2, CCT3, CCUR, CCSR]: Declare
- new condition code modes.
- s390.c (s390_match_ccmode_set): Handle those new CC modes.
- (s390_select_ccmode): Likewise.
- (s390_branch_condition_mask): Likewise.
-
- * s390-protos.h (s390_tm_ccmode): Declare.
- s390.c (s390_tm_ccmode): New function.
- (s390_match_ccmode): Allow VOIDmode as REQ_MODE.
-
- * s390.md ("*cmpdi_tm2"): Rename to "*tmdi_ext".
- ("*cmpsi_tm2"): Rename to "*tmsi_ext".
- ("*cmpqi_tm2"): Rename to "*tmqi_ext".
-
- ("*cmpdi_tm_reg", "*cmpdi_tm_mem", "*cmpsi_tm_reg", "*cmpsi_tm_mem",
- "*cmphi_tm_sub","*cmphi_cct_0", "*cmpqi_tm", "*cmpqi_tm_sub",
- "*cmpqi_cct_0", "*tm_0"): Remove, replace by ...
- ("*tmdi_reg", "*tmsi_reg", "*tmdi_mem", "*tmsi_mem", "*tmhi_mem",
- "*tmqi_mem", "*tmhi_full", "*tmqi_full"): ... these new patterns.
-
- ("*ltgr", "*cmpdi_ccs_0_64", "*cmpdi_ccs_0_31", "*ltr", "*icm15",
- "*icm15_cconly", "*cmpsi_ccs_0", "*icm3", "*cmphi_ccs_0", "*icm1",
- "*cmpqi_ccs_0"): Remove, replace by ...
- ("*tstdi_sign", "*tstdi", "*tstdi_cconly", "*tstdi_cconly_31",
- "*tstsi", "*tstsi_cconly", "*tstsi_cconly2", "*tsthi", "*tsthi_cconly",
- "*tstqi", "*tstqi_cconly"): ... these new patterns.
-
- ("*cmpsidi_ccs"): Remove, replace by ...
- ("*cmpsi_ccs_sign"): ... this new pattern.
- ("*cmpdi_ccs_sign", "*cmpdi_ccu_zero"): New patterns.
-
- ("*cmpqi_ccu_0", "*cmpqi_ccu_immed"): Remove, replace by ...
- ("*cli"): ... this new pattern.
-
- ("*adddi3_sign", "*adddi3_zero_cc", "*adddi3_zero_cconly",
- "*adddi3_zero", "*adddi3_cc", "*adddi3_cconly", "*adddi3_cconly2"):
- New patterns.
- ("adddi3_64"): Rename to "*adddi3_64".
- ("adddi3_31"): Replace by insn and splitter "*adddi3_31".
- ("adddi3"): Adapt expander.
-
- ("*addsi3_cc"): Allow "general_operand" for operand 2.
- ("*addsi3_carry1_cc", "*addsi3_carry1_cconly",
- "*addsi3_carry2_cc", "*addsi3_carry2_cconly"): New patterns.
-
- ("addhi3", "addqi3"): Remove, replace by ...
- ("*addsi3_sign", "*addsi3_sub"): ... these new patterns.
-
- ("*subdi3_sign", "*subdi3_zero_cc", "*subdi3_zero_cconly",
- "*subdi3_zero", "*subdi3_cc", "*subdi3_cconly"): New patterns.
- ("subdi3"): Replace by insn and splitter "*subdi3_31".
- ("subdi3"): New expander.
-
- ("*subsi3_borrow_cc", "*subsi3_borrow_cconly"): New patterns.
-
- ("subhi3", "subqi3"): Remove, replace by ...
- ("*subsi3_sign", "*subsi3_sub"): ... these new patterns.
-
- ("*muldi3_sign"): New pattern.
- ("muldi3"): Do not clobber CC.
- ("mulsi3"): Likewise.
- ("mulsi_6432"): Likewise.
-
-2002-08-13 Denis Chertykov <denisc@overta.ru>
-
- * config/avr/avr.md: Call CC_STATUS_INIT in all peepnoles
- which can change CC0.
-
-2002-08-13 J"orn Rennecke <joern.rennecke@superh.com>
-
- * gcse.c (adjust_libcall_notes): New function.
- (do_local_cprop): Use it. Add fourth parameter. Changed caller.
-
-2002-08-13 Nathan Sidwell <nathan@codesourcery.com>
-
- * libgcc2.c (L_bb): Remove unneeded #includes.
- (__global_counters, __gthreads_active): Remove unused globals.
- (__bb_exit_func): Merge counts into files rather than appending.
- * Makefile.in (INTERNAL_CFLAGS): Move COVERAGE_FLAGS from here ...
- (ALL_CFLAGS): ... to here.
-
-2002-08-13 Denis Chertykov <denisc@overta.ru>
-
- * config/ip2k/ip2k.c (commands_in_file): Variable removed.
- (function_epilogue): Don't calculate function size.
- (ip2k_set_compare): Don't use lookup_const_double.
- (asm_file_start): Initialization of commands_in_file removed.
- (asm_file_end): Output of commands_in_file removed.
-
- * config/ip2k/ip2k.c (CPP_PREDEFINES): Remove definition of
- __INT_MAX__.
-
-2002-08-13 Neil Booth <neil@daikokuya.co.uk>
-
- * c-opts.c (c_common_init_options): Check option array is
- sorted if checking enabled.
-
-2002-08-13 Gabriel Dos Reis <gdr@nerim.net>
-
- * c-pretty-print.c: #include "c-tree.h".
- (pp_c_simple_type_specifier): Tweak.
- (pp_c_storage_class_specifier): New.
- (pp_c_function_specifier): Likewise.
- (pp_c_declaration_specifiers): Likewise.
- (pp_c_init_declarator): Likewise.
- (pp_c_declaration): Likewise.
- (pp_c_direct_declarator): Stub.
- (pp_c_declarator): Likewise.
- (pp_c_parameter_declaration): Likewise.
-
-2002-08-13 Neil Booth <neil@daikokuya.co.uk>
-
- * c-opts.c (deps_seen, deps_file, deferred_count, deferred_size,
- handle_deferred_opts, sanitize_cpp_opts, defer_opt,
- struct deferred_opt): New.
- (COMMAND_LINE_OPTIONS): Add -M*.
- (missing_arg): Update.
- (c_common_decode_option): Handle -M*.
- (c_common_post_options): Handle -M*. Use sanitize_cpp_opts;
- don't call cpp_post_options.
- (c_common_finish, check_deps_environment_vars): Update.
- * cppfiles.c (stack_include_file, handle_missing_header): Update.
- * cpphash.h (CPP_PRINT_DEPS): Remove.
- * cppinit.c: Don't include version.h.
- (cpp_create_reader): Don't call deps_init. Initialize
- warn_long_long.
- (cpp_read_main_file): Init deps if necessary.
- (cpp_destroy): Conditionally free deps.
- (cpp_finish): Update.
- (no_tgt): Remove.
- (COMMAND_LINE_OPTIONS, cpp_handle_option): Remove -M*.
- (cpp_post_options): Rename post_options.
- * cpplib.h (struct cpp_options): Remove some dependency options;
- move others to a new structure.
- (cpp_post_options): Remove.
- (cpp_finish): Comment.
- * fix-header.c (read_scan_file): Don't call cpp_post_options.
-
-2002-08-12 Hans-Peter Nilsson <hp@bitrange.com>
-
- * config/mmix/mmix.md (define_constants): Add MMIX_rR_REGNUM.
- ("divdi3", "*divdi3_nonknuth", "moddi3", "*moddi3_nonknuth"): Mark
- MMIX_rR_REGNUM as clobbered.
- * config/mmix/mmix.h (MMIX_REMAINDER_REGNUM): Use MMIX_rR_REGNUM.
-
-2002-08-12 Gabriel Dos Reis <gdr@nerim.net>
-
- * diagnostic.h (output_formatted_scalar): Rename from
- output_formatted_integer.
- * diagnostic.def: Add DK_DEBUG.
- * diagnostic.c (output_decimal): Adjust.
- (output_long_decimal): Likewise.
- (output_unsigned_decimal): Likewise.
- (output_octal): Likewise.
- (output_long_octal): Likewise.
- (output_hexadecimal): Likewise.
- (output_long_hexadecimal): Likewise.
- * c-pretty-print.c (pp_c_type_specifier): New function.
- (pp_c_specifier_qualifier_list): Likewise.
- (pp_c_abstract_declarator): Likewise.
- (pp_c_char): Replace pp_format_integer with pp_format_scalar.
-
-2002-08-12 David Edelsohn <edelsohn@gnu.org>
-
- * doc/trouble.texi (Disappointments): Add static constructor and
- destructor dependency information for AIX.
-
-2002-08-12 Neil Booth <neil@daikokuya.co.uk>
-
- * cpphash.h (struct printer): New from cppmain.c.
- (cpp_reader): New member.
- * cppmain.c (struct printer): Move to cpphash.h.
- (options, print): Remove.
- (account_for_newlines, print_line, maybe_print_line,
- cpp_preprocess_file, setup_callbacks, scan_translation_unit,
- scan_translation_unit_trad, cb_line_change, cb_ident,
- cb_define, cb_undef, cb_include, cb_file_change, dump_macro,
- cb_def_pragma): Make reentrant.
-
-2002-08-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * real.c (ieee_64): Always define.
- (ieee_113): Guard with INTEL_EXTENDED_IEEE_FORMAT == 0.
- (dec_h): Not used yet, hide it.
- (emdnorm): Mark parameter in ATTRIBUTE_UNUSED. Guard label with
- macro controlling use.
- (TFbignan, TFlittlenan): Guard with INTEL_EXTENDED_IEEE_FORMAT == 0.
-
-2002-08-12 Jan Hubicka <jh@suse.cz>
-
- * i386.md (tablejump): Sign extend the operand.
- * i386.c (classify_argument): Fix missed case from previous patch.
-
-2002-08-12 Neil Booth <neil@daikokuya.co.uk>
-
- * c-common.c (STDC_0_IN_SYSTEM_HEADERS, c_common_init): Move
- to c-copts.c.
- (warn_multichar): Die.
- (cb_register_builtins): Export.
- * c-common.h (warn_multichar, preprocess_file): Remove.
- (cb_register_builtins): New.
- * c-lang.c (c_init): Remove.
- (LANG_HOOKS_INIT): Use c_objc_common_init.
- * c-lex.c (init_c_lex): Don't canonicalize filename.
- * c-opts.c (in_fname, STDC_0_IN_SYSTEM_HEADERS): New.
- (preprocess_file): Make static. Update for cpplib.
- (c_common_decode_option): Remove warn_multichar. Use in_fname.
- (c_common_post_options): Set some cpp options here.
- (c_common_init): Move from c-common.c.
- * cppinit.c (cpp_post_options): Don't canonicalize in_fname.
- * cpplib.h (struct cpp_options): Remove in_fname.
- (cpp_preprocess_file): Update.
- * cppmain.c (cpp_preprocess_file): Update for new prototypes.
-
-2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * config.gcc (mips*-*-netbsd*): Include ${tm_file}.
-
-2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * i370.h (TARGET_CPU_CPP_BUILTINS): Remove spurious trailing
- backslash in comment preceeding macro definition.
- * i370/linux.h (TARGET_OS_CPP_BUILTINS): Likewise.
- * i370/mvs.h (TARGET_OS_CPP_BUILTINS): Likewise.
- * i370/oe.h (TARGET_OS_CPP_BUILTINS): Likewise.
-
-2002-08-12 Hans-Peter Nilsson <hp@bitrange.com>
-
- * expr.c (store_expr): In condition for checking if value is
- generated in TARGET, move call to expr_size last.
-
-2002-08-11 Neil Booth <neil@daikokuya.co.uk>
-
- * c-common.c (c_common_init): Call preprocess_file instead.
- (c_common_finish): Move to c-opts.c.
- * c-common.h (preprocess_file): new.
- * c-opts.c (out_fname, out_stream, deps_append, preprocess_file,
- check_deps_environment_vars, c_common_finish): New.
- (c_common_decode_option): Update for out_fname and dependencies.
- * cppinit.c (init_dependency_output, output_deps): Remove.
- (cpp_destroy): Update prototype.
- (cpp_add_dependency_target): New.
- (cpp_read_main_file): Don't overlay a buffer.
- (cpp_finish): Take a deps output stream and write deps to it.
- Return the error count.
- (cpp_post_options): Don't canonicalize out_fname, or do anything
- with dependencies.
- * cpplib.h (struct cpp_options): Remove out_fname and
- preprocess_only.
- (cpp_add_dependency_target): New.
- (cpp_destroy, cpp_finish, cpp_preprocess_file): Update.
- * cppmain.c (cpp_preprocess_file): Update prototype. Don't
- set preprocess_only. Don't handle the output stream directly.
-
-2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * dsp16xx.c (print_operand): Fix format specifier.
- * dsp16xx.md: Avoid automatic aggregate initialization.
- * frv.h (REG_CLASS_FROM_LETTER): Avoid char as array index.
- * h8300.c (emit_a_rotate, h8300_adjust_insn_length): Avoid U
- integer constant modifier.
- * ip2k.c (ip2k_set_compare): Avoid signed/unsigned warning.
- * mmix-protos.h (mmix_use_simple_return): Move outside TREE_CODE
- guards.
- * sh/netbsd-elf.h (FUNCTION_PROFILER): Fix format specifier.
- * v850.c (v850_select_section): Mark parameter with
- ATTRIBUTE_UNUSED.
- * global.c (global_alloc): Const-ify.
- * ra-colorize.c (hardregset_to_string): Fix format specifier.
-
-2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * darwin-c.c (darwin_pragma_options): Const-ify.
- * darwin.c (machopic_non_lazy_ptr_name,
- machopic_validate_stub_or_non_lazy_ptr): Likewise.
- (machopic_indirect_data_reference): Wrap variables in macros
- controlling their use.
- (machopic_finish, update_non_lazy_ptrs, update_stubs): Const-ify.
- (machopic_select_section): Use parentheses around && within ||.
- * i386/darwin.h (ASM_OUTPUT_ALIGN): Avoid ambiguous-else.
-
-2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * ip2k.c (mdr_resequence_xy_yx, mdr_propagate_reg_equivs,
- mdr_try_move_dp_reload, ip2k_check_can_adjust_stack_ref,
- ip2k_adjust_stack_ref, mdr_try_move_pushes, mdr_try_propagate_clr,
- ip2k_xexp_not_uses_reg_for_mem, mdr_try_propagate_move,
- mdr_try_remove_redundant_insns, track_w_reload,
- mdr_try_wreg_elim): Make function static to match prototype.
- * mmix.c (mmix_target_asm_function_epilogue): Likewise. Mark
- parameter with ATTRIBUTE_UNUSED.
-
-2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * arc.c (arc_init): Don't use ISO C style function definitions.
- * arm.c (count_insns_for_constant, thumb_far_jump_used_p,
- arm_get_strip_length, arm_strip_name_encoding): Likewise.
- * avr.h (progmem_section): Likewise.
- * h8300.c h8300_asm_insn_count): Likewise.
- * m32r.c (init_idents): Likewise.
- * s390.c (s390_split_branches, s390_chunkify_pool): Likewise.
- * sh.c (sh_cfun_interrupt_handler_p): Likewise.
- * xtensa.c (xtensa_build_va_list): Likewise.
-
-2002-08-11 Neil Booth <neil@daikokuya.co.uk>
-
- * c-common.h (enum c_language_kind): Emphasize that clk_c is 0.
- * c-opts.c (parse_option): Rename find_opt.
- (set_std_c99): New function.
- (COMMAND_LINE_OPTIONS): Handle -remap and -o. Remove OPT_std_bad.
- (missing_arg): Remove OPT_std_bad. Handle -o.
- (c_common_decode_option): Handle input and output file names,
- -o and -remap. Clean up -std= handling.
- * cppinit.c (COMMAND_LINE_OPTIONS): Remove OPT_o and OPT_remap.
- (cpp_handle_option): Similarly. Don't handle filenames.
-
-2002-08-11 Jan Hubicka <jh@suse.cz>
-
- * i386.c (classify_argument): Fix computing of field's offsets.
-
-2002-08-11 Andreas Jaeger <aj@suse.de>
-
- PR target/7531:
- * doc/invoke.texi (i386 and x86-64 Options): Document -mcmodel.
-
-2002-08-10 Ziemowit Laski <zlaski@apple.com>
-
- * config/alpha/alpha.h (TARGET_CPU_CPP_BUILTINS): Replace
- reference to clk_objective_c with flag_objc.
- * config/i386/i386-interix.h (TARGET_OS_CPP_BUILTINS):
- Likewise.
- * config/mips/mips.h (TARGET_CPU_CPP_BUILTINS): Likewise.
-
-2002-08-10 Neil Booth <neil@daikokuya.co.uk>
-
- * c-opts.c (set_std_cxx98, set_std_c89): New.
- (COMMAND_LINE_OPTIONS): Move more from cppinit.c.
- (c_common_decode_option): Handle new switches from cppinit.c.
- Add -std=gnu++98.
- * cppinit.c (set_lang): Rename cpp_set_lang. Export.
- (no_arg, no_num): Remove.
- (COMMAND_LINE_OPTIONS): Move more to c-opts.c. Drop all lang-
- switches apart from -lang-objc and lang-asm.
- (cpp_handle_option): Similarly.
- * cpplib.h (cpp_set_lang): New.
- * doc/cppopts.texi, doc/invoke.texi: Document -std=c++98,
- -std=gnu++98.
- * objc/lang-specs.h: Remove -ansi.
-
-2002-08-10 Jan Hubicka <jh@suse.cz>
- Graham Stott
-
- * cfg.c (redirect_edge_succ_nodup): Avoid overflows due to roundoff
- errors.
-
-2002-08-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * emit-rtl.c (emit_jump_insn_before, emit_call_insn_before,
- emit_jump_insn): Fix uninitialized variable.
- * gcov.c (init_line_info): Likewise.
- * genautomata.c (transform_3): Add braces around ambiguous
- else.
- * ifcvt.c (cond_exec_process_insns): Mark parameter with
- ATTRIBUTE_UNUSED.
- * ra-build.c (parts_to_webs_1): Fix uninitialized variable.
- * regrename.c (copyprop_hardreg_forward): Fix uninitialized
- variable.
-
- * gengtype.c (write_gc_structure_fields): Avoid signed/unsigned
- warnings in output files.
-
-2002-08-09 Ziemowit Laski <zlaski@apple.com>
-
- * c-common.c (flag_objc): New.
- * c-common.h (c_language_kind): Get rid of clk_objective_c
- enum value.
- (flag_objc): New extern declaration.
- * c-decl.c (implicitly_declare): Call objc_check_decl
- instead of maybe_objc_check_decl.
- (finish_decl): Likewise.
- (grokfield): Likewise.
- (finish_struct): Likewise.
- * c-lang.c (maybe_objc_check_decl): Rename to objc_check_decl.
- (maybe_objc_comptypes): Rename to objc_comptypes.
- (maybe_building_objc_message_expr): Rename to
- objc_message_selector.
- * c-lex.c (lex_charconst): Remove uses of clk_objective_c,
- replace with flag_objc as needed.
- * c-opts.c (c_common_init_options): Likewise.
- (c_common_decode_option): Likewise.
- * c-parse.in (init_reswords): Likewise.
- * c-tree.h (maybe_objc_check_decl): Rename to objc_check_decl.
- (maybe_objc_comptypes): Rename to objc_comptypes.
- (maybe_building_objc_message_expr): Rename to
- objc_message_selector.
- * c-typeck.c (comptypes): Call objc_comptypes instead of
- maybe_objc_comptypes, and/or objc_message_selector instead of
- maybe_building_objc_message_expr.
- (comp_target_types): Likewise.
- (convert_for_assignment): Likewise.
- (warn_for_assignment): Likewise.
- * cppinit.c (init_builtins): Set __OBJC__ manifest constant
- independently of those for other languages.
- * objc/objc-act.c (maybe_objc_comptypes): Delete.
- (maybe_objc_check_decl): Delete.
- (maybe_building_objc_message_expr): Rename to
- objc_message_selector.
- * objc/objc-lang.c (objc_init_options): Use clk_c instead of
- clk_objective_c; set flag_objc flag.
-
-2002-08-09 Toshiyasu Morita <toshiyasu.morita@hsa.hitachi.com>
-
- * ifcvt.c (find_if_case_2): Test correct basic block for size.
-
-2002-08-09 Dale Johannesen <dalej@apple.com>
-
- * config/rs6000/rs6000.md: Add sibcall patterns.
- * config/rs6000/rs6000.h (FUNCTION_OK_FOR_SIBCALL): Define.
- * config/rs6000/rs6000.c (rs6000_ra_ever_killed):
- Rewritten to handle sibcalls.
- * config/rs6000/rs6000.c (function_ok_for_sibcall): New.
- * config/rs6000/rs6000-protos.h (function_ok_for_sibcall): New.
-
-2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * profile.c (da_file_name): New static var.
- (init_branch_prob): Initialize it.
- (end_branch_prob): Remove da file.
-
- * Makefile.in (stage1_build): Pass empty COVERAGE_FLAGS.
- * configure.in (coverage_flags): Default to nothing.
- * configure: Rebuilt.
-
-2002-08-09 Neil Booth <neil@daikokuya.co.uk>
-
- * Makefile.in (c-opts.o): Update
- * c-opts.c: Include intl.h.
- (print_help): Move from cppinit.c. Remove unused options.
- (COMMAND_LINE_OPTIONS): Move more from cppinit.c.
- (missing_arg): Complain for switches without an argument.
- (c_common_decode_option): Reject missing joined arguments.
- Handle new switches from cppinit.c.
- * cppinit.c (COMMAND_LINE_OPTIONS): Move some switches to c-opts.c.
- (cpp_handle_option): Similarly.
- (print_help): Moved to c-opts.c.
- * cpplib.h (struct cpp_options): Remove help_only.
- * gcc.c (cpp_unique_options): Remove -$.
- * doc/cppopts.texi: Undocument -h.
-
-2002-08-08 Jakub Jelinek <jakub@redhat.com>
-
- * config/i386/i386.c (legitimate_constant_p): UNSPEC_TP is not
- legitimate constant.
- (legitimate_pic_operand_p): Neither pic operand.
- (legitimate_address_p): But legitimate address.
- (get_thread_pointer): Generate MEM/u instead of CONST around
- UNSPEC_TP.
- (print_operand): Remove printing of UNSPEC_TP.
- (print_operand_address): And print it here.
-
-2002-08-08 Devang Patel <dpatel@apple.com>
-
- * objc/objc-act.c (build_selector_translation_table): Issue warning,
- when -Wselector is used,if method for which selector is being
- created does not exist.
-
-2002-08-08 Stephen Clarke <stephen.clarke@superh.com>
-
- * config/sh/sh.c (prepare_move_operands): Only call
- target_reg_operand if TARGET_SHMEDIA.
-
-2002-08-08 Jakub Jelinek <jakub@redhat.com>
-
- * config/rs6000/rs6000.h, config/rs6000/aix.h,
- config/rs6000/darwin.h, config/rs6000/linux64.h: Revert last
- two patches.
- * config/rs6000/sysv4.h: Likewise, remove #undef ADJUST_FIELD_ALIGN.
-
-2002-08-08 Lars Brinkhoff <lars@nocrew.org>
- Richard Henderson <rth@redhat.com>
-
- * emit-rtl.c (gen_rtx_REG): After reload, only return
- frame_pointer_rtx or hard_frame_pointer_rtx if frame_pointer_needed.
-
-2002-08-08 Jakub Jelinek <jakub@redhat.com>
-
- * config/rs6000/rs6000-protos.h (rs6000_field_alignment): Remove.
- * config/rs6000/rs6000.c (rs6000_field_alignment): Move...
- * config/rs6000/rs6000.h (ADJUST_FIELD_ALIGN): ...inline into the
- macro.
-
-2002-08-08 Adam Nemet <anemet@lnxw.com>
-
- * config/arm/arm.c (thumb_unexpanded_epilogue): Stack the PIC
- register.
- (thumb_expand_prologue): Likewise.
- (thumb_output_function_prologue): Likewise.
- * config/arm/arm.h (THUMB_INITIAL_ELIMINATION_OFFSET): Account for
- the additional push of the PIC register.
-
-2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * configure.in (enable_coverage): New enable switch.
- * configure: Rebuilt.
- * Makefile.in (COVERAGE_FLAGS, coverageexts): New variables.
- (INTERNAL_CFLAGS): Append COVERAGE_FLAGS.
- (ALL_FLAGS): Reorder so INTERNAL_CFLAGS comes after CFLAGS.
- (mostlyclean): Remove coverage files.
- * doc/install.texi: Document enable_coverage.
-
- * cp/Make-lang.in (c++.mostlyclean): Remove coverage files.
- * ada/Make-lang.in (ada.mostlyclean): Remove coverage files.
- * f/Make-lang.in (f.mostlyclean): Remove coverage files.
- * java/Make-lang.in (java.mostlyclean): Remove coverage files.
- * objc/Make-lang.in (objc.mostlyclean): Remove coverage files.
- * treelang/Make-lang.in (treelang.mostlyclean): Remove coverage
- files.
-
-2002-08-08 Neil Booth <neil@daikokuya.co.uk>
-
- * c-opts.c (cpp_opts): New.
- (COMMAND_LINE_OPTIONS): Add switches from cppinit.c.
- (c_common_decode_options): Handle cpplib switches.
- (c_common_init_options): Set cpp_opts.
- * cppinit.c (COMMAND_LINE_OPTIONS): Move some switches to c-opts.c.
- (cpp_handle_option): Similarly.
-
-2002-08-08 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/aix.h (TARGET_ALTIVEC): Define to 0.
- (TARGET_ALTIVEC_ABI): Same.
- (TARGET_ALTIVEC_VRSAVE): Same.
-
- * config/rs6000/rs6000.c (rs6000_expand_ternop_builtin): Check
- icode not CODE_FOR_nothing. Change switch to if.
-
-2002-08-08 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.h (ASM_CPU_SPEC): Pass -mpower4 when cpu=power4.
-
-2002-08-08 Jakub Jelinek <jakub@redhat.com>
-
- * stor-layout.c (place_union_field): For bitfields if
- PCC_BITFIELD_TYPE_MATTERS and TYPE_USER_ALIGN, set record's
- TYPE_USER_ALIGN.
-
-2002-08-07 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa.c (struct deferred_plabel): Constify name field.
-
-2002-08-07 Neil Booth <neil@daikokuya.co.uk>
-
- * cppmacro.c (_cpp_builtin_macro_text): Remove unused variable.
-
-2002-08-07 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * configure.in (PREFIX_INCLUDE_DIR): Don't define if prefix and
- local_prefix are the same.
- * configure: Rebuilt.
-
-2002-08-07 Jakub Jelinek <jakub@redhat.com>
- Richard Henderson <rth@redhat.com>
-
- * stor-layout.c (place_union_field): Apply ADJUST_FIELD_ALIGN
- to type_align when PCC_BITFIELD_TYPE_MATTERS. Only apply
- ADJUST_FIELD_ALIGN if not DECL_USER_ALIGN resp. TYPE_USER_ALIGN.
- (place_field): Likewise.
- * config/i386/i386.c (x86_field_alignment): Don't check
- DECL_USER_ALIGN here.
- * config/rs6000/rs6000.c (rs6000_field_alignment): New.
- * config/rs6000/rs6000-protos.h (rs6000_field_alignment): New
- prototype.
- * config/rs6000/rs6000.h (ADJUST_FIELD_ALIGN): Define.
- * config/rs6000/aix.h (ADJUST_FIELD_ALIGN): Remove.
- * config/rs6000/darwin.h (ADJUST_FIELD_ALIGN): Remove.
- * config/rs6000/linux64.h (ADJUST_FIELD_ALIGN): Remove.
- * config/rs6000/sysv4.h (ADJUST_FIELD_ALIGN): Remove.
- * doc/tm.texi (ADJUST_FIELD_ALIGN): Update description.
-
-2002-08-07 Neil Booth <neil@daikokuya.co.uk>
-
- * Makefile.in (c-opts.o, c-common.o, C_AND_OBJC_OBJS): Update.
- * c-common.c: Don't include tree-inline.h.
- (c_common_init_options, c_common_post_options): Move to c-opts.c.
- * c-common.h (c_common_decode_option): New.
- * c-decl.c (c_decode_option): Remove.
- * c-lang.c (LANG_HOOKS_DECODE_OPTION): Use c_common_decode_option.
- * c-opts.c: New file.
- * c-tree.h (c_decode_option): Remove.
- * doc/passes.texi: Update.
- * objc/objc-act.c (objc_decode_option): Remove.
- * objc/objc-act.h (objc_decode_option): Remove.
- * objc/ojbc-lang.c (LANG_HOOKS_DECODE_OPTION): Use
- c_common_decode_option.
-
-2002-08-07 Chris Demetriou <cgd@broadcom.com>
-
- * config/mips/mips.md (sunlt_sf, suneq_sf, sunle_sf): Remove
- dependency on TARGET_DOUBLE_FLOAT.
-
-2002-08-07 Stephen Clarke <stephen.clarke@superh.com>
-
- * config/sh/lib1funcs.asm (GCC_shcompact_incoming_args): Don't
- overwrite callee-save registers. Fix comment.
-
-2002-08-06 Chris Demetriou <cgd@broadcom.com>
-
- * config/mips/mips.c (override_options): Set MASK_BRANCHLIKELY
- in target_flags based on ISA, if it was not set on the command
- line. Warn if MASK_BRANCHLIKLEY is set but the ISA does not
- support Branch Likely instructions.
- * config/mips/mips.h (MASK_BRANCHLIKLEY): New macro.
- (TARGET_BRANCHLIKELY): Likewise.
- (TARGET_SWITCHES): Add -mbranch-likely and -mno-branch-likely.
- (GENERATE_BRANCHLIKELY): Use TARGET_BRANCHLIKELY rather than
- ISA_HAS_BRANCHLIKELY.
- (ISA_HAS_BRANCHLIKELY): Do not include MIPS16 check.
- * doc/invoke.texi: Document new MIPS -mbranch-likely and
- -mno-branch-likely options.
-
-2002-08-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * ip2k.c (ip2k_set_compare): Add missing iteration variable.
-
- * Makefile.in (dummy-conditions.o): Depend on $(HCONFIG_H) not
- $(GCONFIG_H).
-
-2002-08-06 Aldy Hernandez <aldyh@redhat.com>
-
- * c-decl.c (duplicate_decls): Error out for incompatible TLS
- declarations.
-
- * testsuite/gcc.dg/tls/diag-3.c: New.
-
-2002-08-06 Dale Johannesen <dalej@apple.com>
-
- * c-common.c (fname_decl): Use line number 0 for
- __func__, to avoid confusing debuggers.
-
-2002-08-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * gcov.c: Tidy.
- (struct line_info, struct coverage): New structures.
- (gcov_file_name, gcov_file): Remove globals.
- (output_data): Take source file parameter. Fix memory leak. Break
- up into ...
- (init_line_info, output_line_info, make_gcov_file_name,
- accumulate_branch_counts): ... here.
- (calculate_branch_probs, function_summary): Adjust.
- (main): Adjust.
- (function_*): Remove global variables.
-
-2002-08-06 Neil Booth <neil@daikokuya.co.uk>
-
- * dwarf2out.c: Remove unused macros.
-
-2002-08-06 Neil Booth <neil@daikokuya.co.uk>
-
- * function.c (TRAMPOLINE_ALIGNMENT): Always defined.
-
-2002-08-06 Neil Booth <neil@daikokuya.co.uk>
-
- * cppinit.c (struct lang_flags): Rename trigraphs std.
- (set_lang): Update.
- * cpplib.h (struct cpp_options): New member std.
- * cppmacro.c (_cpp_builtin_macro_text): Use std.
- (collect_args): Flag whether to swallow a possible future
- comma pasted with varargs.
- (replace_args): Use this flag.
- * doc/cpp.texi: Update varargs extension documentation.
-
-2002-08-06 Jakub Jelinek <jakub@redhat.com>
-
- * config/i386/mmintrin.h (__m64): Make the type 64-bit aligned.
-
-2002-08-06 Jakub Jelinek <jakub@redhat.com>
-
- * config/i386/i386.c (x86_field_alignment): Apply min for all MODE_INT
- and MODE_CLASS_INT modes.
-
-2002-08-06 Jakub Jelinek <jakub@redhat.com>
-
- * config.gcc (*-*-linux*): Default to --enable-threads=posix if no
- --{enable,disable}-threads is given to configure.
- (alpha*-*-linux*, hppa*-*-linux*, i[34567]86-*-linux*,
- x86_64-*-linux*, ia64*-*-linux*, m68k-*-linux*, mips*-*-linux*,
- powerpc-*-linux-gnualtivec*, powerpc-*-linux*, s390-*-linux*,
- s390x-*-linux*, sh-*-linux*, sparc-*-linux*, sparc64-*-linux*):
- Remove thread_file setting here.
-
-2002-08-06 David Edelsohn <edelsohn@gnu.org>
-
- * doc/install.texi (Binaries): Update Bull Freeware URL.
-
-2002-08-06 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * doc/gcc.texi (Top): Rename Index to Keyword Index.
-
-2002-08-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * gcov.c (output_data): Round to % to nearest, tweak formatting.
-
-2002-08-05 Jakub Jelinek <jakub@redhat.com>
-
- * fold-const.c (associate_trees): Only optimize NEGATE_EXPR in one
- of the operands into MINUS_EXPR if code is PLUS_EXPR.
-
-2002-08-05 Douglas B Rupp <rupp@gnat.com>
-
- * config.gcc (i[34567]86-*-interix*): Replace interix.o with winnt.o
- * config/i386/i386-interix.h (TARGET_NOP_FUN_DLLIMPORT,
- drectve_section): Define.
- * config/i386/t-interix: Replace interix.o rule with winnt.o.
- * config/i386/interix.c: Remove.
-
-2002-08-05 Geoffrey Keating <geoffk@redhat.com>
-
- * attribs.c: Don't include obstack.h.
- * builtins.c: Likewise.
- * cfganal.c: Likewise.
- * cfgbuild.c: Likewise.
- * cfgcleanup.c: Likewise.
- * emit-rtl.c: Likewise.
- * loop.c: Likewise.
- * stmt.c: Likewise.
-
- * Makefile.in (s-gtype): Re-add dependency on $(GTFILES).
-
-2002-08-05 Gabriel Dos Reis <gdr@nerim.net>
-
- * doc/c-tree.texi (Expression trees): Document VA_ARG_EXPR
-
-2002-08-04 Chris Demetriou <cgd@broadcom.com>
-
- * doc/invoke.texi: Remove duplicated paragraph describing
- TARGET_SWITCHES.
-
-2002-08-04 Geoffrey Keating <geoffk@redhat.com>
-
- * Makefile.in (sdbout.o): Doesn't need $(OBSTACK_H).
- * collect2.h (permanent_obstack): Delete declaration.
- * collect2.c (permanent_obstack): Delete definition.
- (main): Don't initialize permanent_obstack. Use xstrdup instead.
- * expr.c: Don't include obstack.h.
- (permanent_obstack): Delete declaration.
- * function.c: Don't include obstack.h.
- (permanent_obstack): Delete declaration.
- * integrate.c: Don't include obstack.h.
- (function_maybepermanent_obstack): Delete declaration.
- * print-tree.c (debug_tree): Use x*alloc not permalloc.
- * sdbout.c (gen_fake_label): Use x*alloc not permalloc.
- * tlink.c (pfgets): Use xstrdup not permanent_obstack.
- * toplev.c (lang_independent_init): Rename init_obstacks to init_ttree.
- * tree.h: Rename init_obstacks to init_ttree. Remove declarations
- of permalloc, expralloc, perm_calloc.
- * tree.c (permanent_obstack): Delete definition.
- (init_ttree): Rename from init_obstacks.
- (permalloc): Delete.
- (perm_calloc): Delete.
- (dump_tree_statistics): Don't print information about
- permanent_obstack.
- * varasm.c (assemble_start_function): Use xstrdup instead of
- permalloc/strcpy.
- (assemble_variable): Likewise.
- * config/alpha/alpha.c (unicosmk_need_dex): Use xmalloc instead of
- permalloc.
- (unicosmk_add_extern): Likewise.
- * config/c4x/c4x.c (c4x_external_ref): Likewise.
- (c4x_global_label): Likewise.
- * config/frv/frv.c (frv_encode_section_info): Likewise.
- * config/i386/winnt.c (i386_pe_record_external_function): Likewise.
- (i386_pe_record_exported_symbol): Likewise.
- * config/mips/mips.c (mips_output_external): Likewise.
- (mips_output_external_libcall): Likewise.
- * config/pa/pa.c: (permanent_obstack): Delete declaration.
- (output_call): Use ggc_strdup instead of allocating on
- permanent_obstack.
- * config/romp/romp.c: Include ggc.h.
- (get_symref): Don't declare permanent_obstack, use ggc_strdup
- intead of permanent_obstack.
- * config/rs6000/aix31.h (ASM_OUTPUT_EXTERNAL): Use concat
- instead of permalloc.
- * config/rs6000/rs6000.c (rs6000_gen_section_name): Use xmalloc
- instead of permalloc
- * config/rs6000/xcoff.h (ASM_OUTPUT_EXTERNAL): Use concat
- instead of permalloc.
- * config/vax/vax.c (vms_check_external): Use xmalloc instead of
- permalloc.
-
-2002-08-04 Bernd Schmidt <bernds@redhat.com>
-
- Contribute a port developed primarily by Michael Meissner,
- Catherine Moore, and Richard Sandiford <rsandifo@redhat.com>.
- * config.gcc: Add frv-elf target.
- * config/frv/cmovd.c: New file.
- * config/frv/cmovh.c: New file.
- * config/frv/cmovw.c: New file.
- * config/frv/frv-abi.h: New file.
- * config/frv/frv-asm.h: New file.
- * config/frv/frv-modes.def: New file.
- * config/frv/frv-protos.h: New file.
- * config/frv/frv.c: New file.
- * config/frv/frv.h: New file.
- * config/frv/frv.md: New file.
- * config/frv/frvbegin.c: New file.
- * config/frv/frvend.c: New file.
- * config/frv/lib1funcs.asm: New file.
- * config/frv/media.h: New file.
- * config/frv/modi.c: New file.
- * config/frv/t-frv: New file.
- * config/frv/uitod.c: New file.
- * config/frv/uitof.c: New file.
- * config/frv/ulltod.c: New file.
- * config/frv/ulltof.c: New file.
- * config/frv/umodi.c: New file.
- * config/frv/xm-frv.h: New file.
-
- * config/frv/media.h: Removed again.
-
-2002-08-04 Nathan Sidwell <nathan@codesourcery.com>
-
- * gcov.c (bb_file_time): New static variable.
- (object_directory): May also be object file.
- (preserve_paths): New static variable.
- (print_usage): Adjust.
- (options): Adjust.
- (process_args): Adjust.
- (open_files): Simplify. Cope when OBJECT_DIRECTORY is an object
- file. Find modification date on bb file.
- (read_profile): Don't rewind a NULL file.
- (format_hwint): New static function.
- (function_summary): Use format_hwint.
- (output_data): SOURCE_FILE_NAME is never relative to
- OBJECT_DIRECTORY. Use format_hwint. Adjust gcov file name
- mangling. Adjust output format to make it more machine readable.
- * doc/gcov.texi: Document & clarify semantics.
-
-2002-08-04 Joseph S. Myers <jsm@polyomino.org.uk>
-
- * doc/include/gcc-common.texi (version-GCC): Increase to 3.3.
-
-2002-08-04 Nathan Sidwell <nathan@codesourcery.com>
-
- * gcc.c (cc1_options): Pass output file as auxbase when
- appropriate.
- * profile.c (init_branch_prob): FILENAME has already had ending
- stripped.
- * final.c (end_final): Likewise.
- * toplev.c (aux_base_name): New global.
- (compile_file): Pass aux_base_name to init init_branch_prob and
- end_final.
- (independent_decode_option, case 'a'): New auxinfo options.
- (case 'd'): Protect against mising basename.
- (do_compile): Initialize aux_base_name.
- * toplev.h (aux_base_name): New global.
- * doc/invoke.texi: Adjust documentation.
-
-2002-08-04 Nathan Sidwell <nathan@codesourcery.com>
-
- * config/i386/i386.c (x86_field_alignment): Remove duplicate test
- of TARGET_ALIGN_DOUBLE.
-
-2002-08-04 Gabriel Dos Reis <gdr@nerim.net>
-
- * diagnostic.c (inform): New function.
- * diagnostic.h (inform): Declare.
-
-2002-08-03 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.md (movsi_internal1): Add nop mnemonic.
- (movhi_internal): Same.
- (movqi_internal): Same.
- (movdi_internal64): Same.
-
- * config/rs6000/t-ppccomm (MULTILIB_MATCHES_FLOAT): Add mcpu=405.
-
- * config/rs6000/xcoff.h (SKIP_ASM_OP): Define.
- (ASM_OUTPUT_SKIP): Use it. SIZE unsigned.
- (COMMON_ASM_OP): Define.
- (ASM_OUTPUT_ALIGNED_COMMON): Use it. SIZE unsigned.
- Use ALIGN parameter.
- (LOCAL_COMMON_ASM_OP): Define.
- (ASM_OUTPUT_LOCAL): Use it. SIZE unsigned.
-
-2002-08-03 Roger Sayle <roger@eyesopen.com>
-
- * builtins.def: Define new builtin functions exp, expf, expl,
- log, logf and logl (and their __builtin_* variants).
- * optabs.h (enum optab_index): Add new OTI_exp and OTI_log.
- Define exp_optab and log_optab.
- * optabs.c (init_optans): Initialize exp_optab and log_optab.
- * genopinit.c (optabs): Implement exp_optab and log_optab
- using exp?f2 and log?f2 patterns.
- * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_EXP*
- and BUILT_IN_LOG* using exp_optab and log_optab respectively.
- (expand_builtin): Ignore the new builtins (and all cos and
- sin variants) when not optimizing. Expand new builtins via
- expand_builtin_mathfn when flag_unsafe_math_optimizations.
-
- * doc/extend.texi: Document new exp and log builtins.
- * doc/md.texi: Document new exp?f2 and log?f2 patterns
- (and previously undocumented cos?f2 and sin?f2 patterns).
-
-2002-08-03 Jason Merrill <jason@redhat.com>
-
- * explow.c (int_expr_size): New fn.
- * expr.c (expand_expr) [CONSTRUCTOR]: Use it.
- * expr.h: Declare it.
-
-2002-08-02 Krister Walfridsson <cato@df.lth.se>
-
- * Makefile.in (gengtype-lex.o, gengtype-yacc.o): Add path to
- gengtype-* dependencies.
-
-2002-08-02 Eric Christopher <echristo@redhat.com>
-
- * config.gcc (mips*-*-linux*): Fix ordering of tm_file.
- * config/mips/mips.h (READONLY_DATA_SECTION_ASM_OP): Change
- #ifndef to #undef.
- (TARGET_MEM_FUNCTIONS): Define instead of define to 1.
-
-2002-08-02 David Edelsohn <edelsohn@gnu.org>
-
- PR optimize/7067
- * config/rs6000/rs6000.h (RTX_COSTS): Artificially make MULT
- small if optimizing for size.
-
-2002-08-02 Daniel Jacobowitz <drow@mvista.com>
-
- * configure.in (FORBUILD): Use $build_alias.
- * configure: Regenerated.
-
-2002-08-02 Richard Sandiford <rsandifo@redhat.com>
-
- * config.gcc: Don't include mips/abi64.h in $tm_file.
- * hard-reg-set.h (call_really_used_regs): Declare.
- * config/mips/abi64.h: Remove file.
- * config/mips/linux.h,
- * config/mips/iris6.h: Don't include it.
- * config/mips/mips-protos.h (mips_conditional_register_usage): Declare.
- * config/mips/mips.h (CONDITIONAL_REGISTER_USAGE): Use it.
- (REG_PARM_STACK_SPACE, STACK_BOUNDARY, STRICT_ARGUMENT_NAMING,
- FUNCTION_ARG_PASS_BY_REFERENCE, FUNCTION_ARG_PADDING,
- FUNCTION_ARG_CALLEE_COPIES, MUST_PASS_IN_STACK, MIPS_STACK_ALIGN):
- Bring across definitions from abi64.h.
- (GP_ARG_LAST, FP_ARG_LAST): Use MAX_ARGS_IN_REGISTERS.
- (BIGGEST_MAX_ARGS_IN_REGISTERS): New.
- (struct mips_args): Use it.
- * config/mips/mips.c (mips_conditional_register_usage): Define.
-
-2002-08-02 Jason Merrill <jason@redhat.com>
-
- * langhooks-def.h (LANG_HOOKS_EXPR_SIZE): New macro.
- * langhooks.c (lhd_expr_size): Define default.
- * langhooks.h (struct lang_hooks): Add expr_size.
- * explow.c (expr_size): Call it.
- * expr.c (store_expr): Don't copy an expression of size zero.
- (expand_expr) [CONSTRUCTOR]: Use expr_size to calculate how much
- to store.
- * Makefile.in (builtins.o): Depend on langhooks.h.
-
-2002-08-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * Makefile.in (ra-debug.o): Depend on $(TM_P_H).
- * ra-debug.c: Include "tm_p.h".
- * ra-rewrite.c (is_partly_live_1): Change return type to bool.
-
-2002-08-02 Toon Moene <toon@moene.indiv.nluug.nl>
-
- * simplify-rtx.c (simplify_binary_operation): x * 1 is allowed
- when not honoring signalling NaNs.
- (simplify_ternary_operation): a == b has a definite value
- when not honoring NaNs.
-
-2002-08-02 Jason Merrill <jason@redhat.com>
-
- * gdbinit.in (pct): New macro.
-
-2002-08-01 Stan Shebs <shebs@apple.com>
- Andreas Tobler <toa@pop.agri.ch>
-
- * ginclude/stddef.h (_BSD_SIZE_T_DEFINED_): Define if not defined,
- plays nice with Darwin headers.
- (_BSD_RUNE_T_DEFINED_): Likewise.
-
-2002-08-01 Zack Weinberg <zack@codesourcery.com>
-
- * c-common.c (c_common_init): -Wtraditional also implies -Wlong-long.
- * cppinit.c (cpp_post_options): Likewise.
-
- * cppexp.c (cpp_classify_number): Suppress -Wtraditional
- warning about 'LL' suffix (but not 'ULL' etc) when
- -Wno-long-long is in effect.
-
- * cppmacro.c (_cpp_builtin_macro_text) [BT_TIME, BT_DATE]:
- Check for failing time()/localtime(), issue a warning, and
- make __TIME__ and __DATE__ expand to fallback strings.
-
- * doc/cpp.texi, doc/extend.texi: Document behavior of __DATE__
- and __TIME__ when the date and time cannot be determined.
-
-2002-08-02 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.c (output_cbranch): Hint differently for power4.
-
-2002-08-01 Daniel Jacobowitz <drow@mvista.com>
-
- * Makefile.in ($(BUILD_PREFIX_1)ggc-none.o): Use $(GGC_H).
-
-2002-08-01 Chris Demetriou <cgd@broadcom.com>
-
- * config.gcc (mipsisa64sb1-*-elf*): New configuration.
- (mipsisa64sb1el-*-elf*): Likewise.
- * config/mips/mips.c (mips_cpu_info_table): Add sb1.
- * config/mips/mips.h (processor_type): Add PROCESSOR_SB1.
- (TARGET_SB1, TUNE_SB1): New macros.
- * doc/invoke.texi: Add sb1 to documentation for MIPS -march and
- -mtune flags.
-
-2002-08-01 David Edelsohn <edelsohn@gnu.org>
-
- * varasm.c (asm_emit_uninitialized): Return false if global BSS
- and ASM_EMIT_BSS not supported by target.
- (assemble_variable): Do not duplicate uninitialized logic.
- Fall through if asm_emit_uninitialized failed.
-
-2002-08-01 Chris Demetriou <cgd@broadcom.com>
-
- * config/mips/mips.h (BRANCH_LIKELY_P): Remove unused macro.
-
-2002-08-02 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/linux64.h (DBX_OUTPUT_BRAC): Define.
- (DBX_OUTPUT_LBRAC, DBX_OUTPUT_RBRAC): Define.
-
- * config/rs6000/rs6000.c (output_toc): Don't use lshift_double when
- HOST_BITS_PER_WIDE_INT == 64.
-
-2002-08-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * df.c (df_insn_table_realloc): Change parameter to unsigned.
- * optabs.c (expand_binop): Make variable unsigned.
- * simplify-rtx.c (simplify_subreg): Likewise.
- * unroll.c (unroll_loop): Cast to avoid signed/unsigned warnings.
-
-2002-08-01 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
-
- * c-common.c (cb_register_builtins): Always define __GXX_ABI_VERSION.
-
-2002-08-01 Richard Henderson <rth@redhat.com>
-
- * toplev.c (parse_options_and_default_flags): Don't set
- flag_reorder_blocks for -Os.
-
- * config/avr/avr.c (avr_optimization_options): Remove.
- * config/avr/avr.h (OPTIMIZATION_OPTIONS): Remove.
- * config/m68hc11/m68hc11.c (m68hc11_optimization_options): Remove.
- * config/m68hc11/m68hc11.h (OPTIMIZATION_OPTIONS): Remove.
-
-2002-08-01 H.J. Lu <hjl@gnu.org>
- Richard Henderson <rth@redhat.com>
-
- * output.h (DECL_READONLY_SECTION): Remove.
- (decl_readonly_section): Declare.
- * varasm.c (decl_readonly_section): New.
- (default_section_type_flags, default_select_section): Use it.
- * config/arm/pe.c (arm_pe_unique_section): Likewise.
- * config/i386/interix.c (i386_pe_unique_section): Likewise.
- * config/i386/winnt.c (i386_pe_unique_section): Likewise.
- * config/mcore/mcore.c (mcore_unique_section): Likewise.
- * config/mips/mips.c (mips_unique_section): Likewise.
-
-2002-08-01 Richard Henderson <rth@redhat.com>
-
- * integrate.c (copy_rtx_and_substitute): Squash MEM_EXPR when it
- refers to a subroutine parameter.
-
-2002-08-01 Jakub Jelinek <jakub@redhat.com>
-
- * varasm.c (assemble_visibility): Strip name encoding.
-
-2002-08-01 Ian Dall <ian@sibyl.beware.dropbear.id.au>
-
- * config/ns32k/ns32k.h (TARGET_IEEE_COMPARE): Correct earlier patch.
- (RETURN_ADDR_RTX): Cannot determine return address for FRAME > 0
- when there is no frame pointer.
- (INITIAL_FRAME_POINTER_OFFSET): Count stack space for saved fp
- registers properly.
- * config/ns32k/__unorddf2.c: New file.
- * config/ns32k/__unordsf2.c: New file.
- * config/ns32k/t-ns32k: New file.
- * config.gcc (ns32k-*-netbsd*): Use it.
-
-2002-08-01 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/rs6000.h (SPU_CONST_OFFSET_OK): Change to 0xff.
-
-2002-08-01 Neil Booth <neil@daikokuya.co.uk>
-
- * c-common.c (__GXX_ABI_VERSION): Correct spelling.
-
-2002-08-01 Benjamin Kosnik <bkoz@redhat.com>
-
- * c-common.c (cb_register_builtins): Set __GXX_ABI_VERSION__ to 102.
-
-2002-08-01 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.md: Add [!]TARGET_MIPS16 to sgtu conditions.
-
-2002-08-01 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
-
- * gcse.c (expr_hash_table_size, n_exprs, set_hash_table_size,
- n_sets): Removed.
- (expr_hash_table, set_hash_table): Type changed to ...
- (struct hash_table): New type.
- (hash_scan_insn, hash_scan_set, hash_scan_clobber, hash_scan_call,
- insert_expr_in_table, insert_set_in_table, compute_hash_table,
- dump_hash_table, lookup_expr, lookup_set, compute_local_properties,
- compute_ae_gen, compute_ae_kill): Modified to pass the table explicitly.
- (alloc_set_hash_table, alloc_expr_hash_table): Merged to ...
- (alloc_hash_table): New.
- (free_set_hash_table, free_expr_hash_table): Merged to ...
- (free_hash_table): New.
- (compute_set_hash_table, compute_expr_hash_table): Merged to ...
- (compute_hash_table_work): New.
- (classic_gcse, one_classic_gcse_pass, compute_cprop_data,
- find_avail_set, one_cprop_pass, find_bypass_set, compute_pre_data,
- pre_edge_insert, pre_insert_copies, pre_delete, pre_gcse,
- one_pre_gcse_pass, compute_transpout, compute_code_hoist_vbeinout,
- hoist_code, one_code_hoisting_pass,
- trim_ld_motion_mems): Altered due to changed type of hash tables.
-
-2002-08-01 Zack Weinberg <zack@codesourcery.com>
-
- * final.c (output_alternate_entry_point):
- If ASM_OUTPUT_TYPE_DIRECTIVE is defined, use it.
-
-2002-08-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * objc/objc-act.c (encode_complete_bitfield): Add prototype and
- avoid ISO C style function definition.
-
- * expr.c (expand_assignment): Delete unused variable.
-
-2002-08-01 Toon Moene <toon@moene.indiv.nluug.nl>
-
- * c-common.c (cb_register_builtins): Set
- __FINITE_MATH_ONLY__ to 1 if -ffinite-math-only
- is given, and to 0 otherwise.
- * combine.c (simplify_if_then_else): HONOR_NANS
- implies FLOAT_MODE_P.
-
-2002-08-01 Neil Booth <neil@daikokuya.co.uk>
-
- * cppinit.c (COMMAND_LINE_OPTIONS): Remove OPT_dollar.
- (cpp_handle_option): Don't handle it.
- (print_help): Update.
- * doc/cppopts.texi: Update.
-
-2002-08-01 Neil Booth <neil@daikokuya.co.uk>
-
- * c-common.c (cb_register_builtins): If C++, define
- __EXCEPTIONS, __DEPRECATED and __GXX_ABI_VERSION as appropriate.
- * gcc.c (cpp_unique_options): Remove __GXX_ABI_VERSION.
-cp:
- * lang-specs.h: Simplify in accordance with new code in
- c-common.c.
-
-2002-08-01 Neil Booth <neil@daikokuya.co.uk>
-
- * c-common.c: Define all C/ObjC/C++ warning and flag variables.
- * c-common.h: Declare all C/ObjC/C++ warning and flag variables.
- * c-decl.c: Move all warning and flag variables to c-common.c.
- * c-format.c: Move all warning variables to c-common.c.
- * c-tree.h: Move all warning and flag declarations to c-common.h.
- * objc/objc-act.c: Move all warning variables to c-common.c.
- (flag_warn_protocol): Rename warn_protocol.
-
-2002-07-31 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa-linux.h (GLOBAL_ASM_OP): Fix typo.
-
-2002-07-31 Graham Stott <graham.stott@btinternet.com>
-
- * config/stormy16/stormy16.h (BSS_SECTION_ASM_OP): Add missing
- .section prefix.
-
-2002-07-31 Stan Shebs <shebs@apple.com>
-
- * config.gcc (i[34567]86-*-darwin*): New configuration.
- * config/darwin.h (TARGET_ENCODE_SECTION_INFO): Undefine before
- defining.
- (TARGET_ENCODE_SECTION_INFO): Ditto.
- (ASM_PREFERRED_EH_DATA_FORMAT): Ditto.
- * config/darwin.c (machopic_indirect_data_reference): Remove
- setting of RTX_UNCHANGING_P.
- (machopic_legitimize_pic_address): Move RTX_UNCHANGING_P up so as
- not to be applied to sums.
- * config/i386/t-darwin: New file.
- * config/i386/darwin.h: New file.
- * config/i386/i386.h (TARGET_MACHO): Add default definition.
- * config/i386/i386.md (tablejump): Add TARGET_MACHO case.
- * config/i386/i386.c (output_set_got): For Mach-O, output Mach-O
- label and not the GOT add.
- (constant_address_p): For Mach-O, seeing a CONST is enough.
- (legitimate_pic_address_disp_p): Add a Mach-O case.
- (legitimate_address_p): Also test machopic_operand_p if Mach-O.
- (legitimize_pic_address): Use generic Mach-O code to legitimize.
- (output_pic_addr_const): Suppress @PLT if Mach-O, and parens
- if outputting a difference.
- (ix86_output_addr_diff_elt): Add Mach-O case.
- (ix86_expand_move): Similarly.
- (ix86_expand_call): Similarly.
- (current_machopic_label_num): New global.
- (machopic_output_stub): New function.
- (ix86_value_regno): New function.
- (ix86_function_value): Use it instead of VALUE_REGNO.
- (ix86_libcall_value): Ditto.
- * config/i386/unix.h (VALUE_REGNO): Remove.
-
-2002-07-31 Graham Stott <grahas@btinternet.com>
-
- * config/rs6000/rs6000.c(rs6000_hash_constant): Fix
- hash for LABEL_REF's.
-
-2002-07-31 Graham Stott <grahams@btinternet.com>
-
- * config/rs6000/rs6000.c (spe_init_builtins,
- altivec_init_builtins, rs6000_common_init_builtins):
- Replace ANSI with K&R function def.
-
-2002-07-31 David Edelsohn <edelsohn@gnu.org>
-
- * rs6000.c (validate_condition_mode): Test flag_finite_math_only
- for CCFPmode.
-
-2002-07-31 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/crtn.asm: Don't use __mips16 to determine the
- return-address offset. Define RA to a suitable temporary
- register for the return address.
-
-2002-07-31 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.md (eh_set_lr_si, eh_set_lr_di): Change
- constraints to 'd'.
-
-2002-07-30 Chris Demetriou <cgd@broadcom.com>
-
- * config/mips/elf.h (STARTFILE_SPEC): Define differently if
- default ABI is MEABI. (Undoes incorrect change in Eric Christopher's
- patch on 2002-07-29.)
- * config/mips/elf64.h (STARTFILE_SPEC): Likewise.
-
-2002-07-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * alpha.h, arc.h, arm/aout.h, avr.h, cris.h, d30v.h, dsp16xx.h,
- fr30.h, h8300.h, i370.h, i386/sco5.h, i386/unix.h, i960.h, ia64.h,
- ip2k.h, m32r.h, mcore.h, mips.h, mn10200.h, mn10300.h, ns32k.h,
- openbsd.h, pa/pa-linux.h, pdp11.h, romp.h, rs6000/sysv4.h,
- s390/linux.h, sh.h, sparc.h, stormy16.h, v850.h, vax.h, xtensa.h:
- (ASM_GLOBALIZE_LABEL): Delete.
- (GLOBAL_ASM_OP): Define.
-
- * m68hc11.h, m68k.h, m88k.h (ASM_GLOBALIZE_LABEL): Delete.
-
- * defaults.h (ASM_GLOBALIZE_LABEL): Provide a default.
- * doc/tm.texi (ASM_GLOBALIZE_LABEL): Update docs.
-
-2002-07-30 Geoffrey Keating <geoffk@redhat.com>
-
- * doc/extend.texi (Hints implementation): Document that GCC
- mostly ignores `register'.
-
-2002-07-30 Toon Moene <toon@moene.indiv.nluug.nl>
-
- * flags.h: Declare flag_finite_math_only.
- Use it in definition of HONOR_NANS and
- HONOR_INFINITIES.
- * c-common.c (cb_register_builtins): Emit
- __FINITE_MATH_ONLY__ when flag_finite_math_only
- is set.
- * combine.c (simplify_if_then_else): If
- flag_finite_math_only is set, a == b has a
- definite value.
- * toplev.c: Initialize flag_finite_math_only.
- (set_flags_fast_math): Set it on -ffast-math.
- (flag_fast_math_set_p): Test it.
- * doc/invoke.texi: Document -ffinite-math-only.
-
-2002-07-30 Richard Henderson <rth@redhat.com>
-
- * ifcvt.c (noce_get_alt_condition): Use reg_overlap_mentioned_p.
- (noce_process_if_block): Likewise.
-
-2002-07-30 Bernd Schmidt <bernds@redhat.com>
-
- * ifcvt.c (cond_exec_process_if_block): Fix a merging error.
- Bail out early if false_expr is NULL and we'd crash due to this.
- * genemit.c (gen_expand): Recognize return insns even if the return
- appears in a parallel.
- * libgcc2.c: Expand macro DECLARE_LIBRARY_RENAMES if it is defined.
- * config/fp-bit.c: Likewise.
- * doc/tm.texi: Document it.
-
-2002-07-30 David Edelsohn <edelsohn@gnu.org>
- Zack Weinberg <zack@codesourcery.com>
-
- * rs6000.c (rs6000_expand_unop_builtin): Check icode not
- CODE_FOR_nothing. Change switch to if.
- (rs6000_expand_binop_builtin): Same.
- (rs6000_expand_builtin): Expand builtin if target support enabled.
- (rs6000_init_builtins): Init builtin if target support enabled.
- (rs6000_common_init_builtins): Check icode not CODE_FOR_nothing.
-
-2002-07-30 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
-
- * gcc.c (cpp_unique_options): Define __GXX_ABI_VERSION, bump it to 101.
-
-2002-07-30 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.h (SUBTARGET_ASM_DEBUGGING_SPEC): Fix typo.
-
-2002-07-30 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.md (cond_delay_slot): New attribute.
- (cbranch delay): Use it for anulled-true case.
- (stuff_delay_slot): New pattern.
- * sh.c (print_operand, case '.'): Don't print .s / /s fore zero-length
- delay slot insn.
- (gen_far_branch): Emit stuff_delay_slot pattern.
-
-2002-07-30 J"orn Rennecke <joern.rennecke@superh.com>
-
- * unroll.c (copy_loop_body): Don't copy NOTE_INSN_LOOP_CONT.
-
-2002-07-30 Kazu Hirata <kazu@cs.umass.edu>
-
- * fold-const.c: Fix comment typos.
- * gcse.c: Likewise.
- * reload1.c: Likewise.
-
-2002-07-29 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/rs6000.md: Disallow CCEQ compare with crnor/crnot
- for TARGET_SPE.
-
-2002-07-30 Gabriel Dos Reis <gdr@nerim.net>
-
- * c-pretty-print.h (pp_c_statement): Declare.
- * c-pretty-print.c (pp_c_postfix_expression): #if 0 support for SRCLOC.
- (pp_c_statement): Define.
-
-2002-07-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * alpha.h, arc.h, arm/aout.h, avr.h, c4x.h, cris.h, d30v.h,
- darwin.h, dsp16xx.h, fr30.h, h8300.h, i370.h, i386.h, i960.h,
- ip2k.h, m32r.h, m68hc11.h, m68k.h, m88k.h, mcore.h, mips.h,
- mn10200.h, mn10300.h, ns32k.h, pa/pa-linux.h, pdp11.h, romp.h,
- rs6000/sysv4.h, s390/linux.h, sh.h, sparc.h, stormy16.h,
- v850.h, vax.h, xtensa.h (ASM_OUTPUT_LABEL): Delete definition.
-
- * defaults.h (ASM_OUTPUT_LABEL): Provide a default.
- * doc/tm.texi (ASM_OUTPUT_LABEL): Update docs.
-
-2002-07-30 Gabriel Dos Reis <gdr@nerim.net>
-
- * c-pretty-print.c (pp_c_primary_expression): Handle STMT_EXPR.
- (pp_c_postfix_expression): Handle ARROW_EXPR, FFS_EXPR,
- COMPOUND_LITERAL_EXPR, VA_ARG_EXPR.
- (pp_c_expression): Update.
-
-2002-07-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * alpha/vms-cc.c (preprocess_args, main): Use xstrdup and/or
- concat in lieu of xmalloc/strcpy/memcpy/sprintf.
- * alpha/vms-ld.c (main): Likewise.
- * dsp16xx.c (double_reg_to_memory): Likewise.
- * mcore.c (mcore_expand_prolog): Likewise.
- * cppfiles.c (read_name_map): Likewise.
- * gensupport.c (process_rtx, identify_predicable_attribute,
- alter_test_for_insn): Likewise.
- * vmsdbgout.c (write_rtnbeg, vmsdbgout_init): Likewise.
-
-2002-07-29 Roger Sayle <roger@eyesopen.com>
-
- * builtins.c (expand_builtin): Change the default behavior to
- only issue an error if the builtin function doesn't have a
- fallback library call. Remove several cases handled by the
- new default.
-
-2002-07-29 John David Anglin <dave@hiauly1.hia.nrc>
-
- * real.c (ieee_24, ieee_53, ieee_64, ieee_113): Define only if the
- floating point format of the target is IEEE.
- * (dec_f, dec_d, dec_g, dec_h): Define only if the floating point
- format of the target is DEC.
-
-2002-07-29 Richard Henderson <rth@redhat.com>
-
- * unroll.c (verify_addresses): Remove.
- (find_splittable_givs): Never split DEST_ADDR givs.
-
-2002-07-29 Geoffrey Keating <geoffk@redhat.com>
-
- * doc/gty.texi (GGC Roots): Clarify that the list of syntaxes
- is exhaustive.
- (Files): Improve documentation on generated source files.
-
- * doc/extend.texi (Translation implementation): Document what
- diagnostics look like.
- (Identifiers implementation): Document that there's normally no
- limit on identifier names.
- (Integers implementation): Document two's complement.
- (Hints implementation): Document that GCC honors 'inline', mostly.
- (Preprocessing directives implementation): Document that GCC
- requires the current time.
-
-2002-07-30 Gabriel Dos Reis <gdr@nerim.net>
-
- * c-pretty-print.h (struct c_pretty_print_info): Add new member.
- (pp_initializer): New macro.
- (pp_c_initializer): Declare.
- * c-pretty-print.c (pp_c_primary_expression): HAndle TARGET_EXPR.
- (pp_c_initializer): Define.
- (pp_c_initializer_list): New function.
- (pp_c_postfix_expression): Handle ABS_EXPR, COMPLEX_CST,
- VECTOR_CST, CONSTRUCTOR.
- (pp_c_unary_expression): Handle CONJ_EXPR, REALPART_EXPR,
- IMAGPART_EXPR.
- (pp_c_cast_expression): Handle FLOAT_EXPR.
- (pp_c_assignment_expression): Handle INIT_EXPR.
- (pp_c_expression): Update.
-
-2002-07-30 Neil Booth <neil@daikokuya.co.uk>
-
- * objc/objc-act.c (objc_init): Return immediately if filename
- is NULL.
-
-2002-07-29 Eric Christopher <echristo@redhat.com>
-
- * config/mips/elf.h: Remove ecoff.h and gofast includes.
- (DWARF2_DEBUGGING_INFO, DBX_DEBUGGING_INFO): Define unconditionally.
- (SDB_DEBUGGING_INFO): Undefine.
- (PREFERRED_DEBUGGING_TYPE): Set to DWARF2_DEBUG.
- (PUT_SDB_SIZE): Remove.
- (SUBTARGET_ASM_DEBUGGING_SPEC): Redefine.
- (STARTFILE_SPEC): Add isa3264 define.
- * config/mips/elf64.h: Ditto. Move TARGET_MEM_FUNCTIONS from here...
- * config/mips/ecoff.h: Remove. and here...
- * config/mips/iris3.h: and here...
- * config/mips/sni-svr4.h: and here...
- * config/mips/mips.h: To here. Remove OBJECT_FORMAT_ROSE ifdefs.
- Add assembler -mmdebug options for non-dwarf debugging.
- * config/mips/r3900.h: Remove debug info defines.
- * config/mips/isa32-linux.h: Remove, move functionality to config.gcc.
- * config/mips/isa3264.h: Ditto.
- * config/mips/t-isa3264: Fix up for file removal and gofast configure
- change.
- * config/mips/t-elf: Ditto.
- * config/mips/t-ecoff: Ditto.
- * config/mips/t-r3900: Ditto.
- * config/mips/t-iris5-6: Ditto.
- * config/mips/t-isa3264: Ditto.
- * config/mips/t-linux: Remove.
- * config/mips/t-netbsd: Remove.
- * config/mips/t-mips: New file.
- * config/mips/t-gofast: Ditto.
- * config/mips/netbsd.h: Remove unnecessary undefines.
- * config/mips/linux.h: Remove #include of mips.h.
- * config.gcc: Add mips.h include for elf targets. Remove tm_file
- for ecoff. Add gofast configure option for mips.
-
-2002-07-29 Chris Demetriou <cgd@broadcom.com>
-
- * configure.in (mips*-*-*): Add a test to see if MIPS libgloss
- linker scripts use STARTUP directives consistently.
- * configure: Regenerate.
- * config.in: Regenerate.
- * config/mips/elf.h (STARTFILE_SPEC): Define conditionally, based
- on whether HAVE_MIPS_LIBGLOSS_STARTUP_DIRECTIVES is defined.
- * config/mips/elf64.h (STARTFILE_SPEC): Likewise.
- * config/mips/isa3264.h (STARTFILE_SPEC): Do not redefine if
- HAVE_MIPS_LIBGLOSS_STARTUP_DIRECTIVES is set; the result
- will be the same.
-
-2002-07-29 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/rs6000.md ("cpu"): Add ppc8540 to attribute.
-
-2002-07-29 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/rs6000.h (RTX_COSTS): Add MULT case for 8540.
-
-2002-07-29 Aldy Hernandez <aldy@quesejoda.com>
-
- * config/rs6000/rs6000.md: Move altivec patterns from here...
-
- * config/rs6000/altivec.md: ...to here.
-
-2002-07-29 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/spe.md ("spe_evmra"): Change to unspec.
-
-2002-07-29 Richard Henderson <rth@redhat.com>
-
- * emit-rtl.c (set_mem_attributes_minus_bitpos): Rename from
- set_mem_attributes and add BITPOS argument. Subtract it from
- OFFSET when same is adjusted.
- (set_mem_attributes): New wrapper function.
- * expr.c (expand_assignment): Use set_mem_attributes_minus_bitpos;
- remove offset adjustment hack.
- * expr.h (set_mem_attributes_minus_bitpos): Declare.
-
-2002-07-29 Gabriel Dos Reis <gdr@nerim.net>
-
- * Makefile.in (C_OBJS): Include c-pretty-print.o
- (c-pretty-print.o): Add depency rule.
- * pretty-print.h: Add more macros.
- * c-pretty-print.c: New file.
- * c-pretty-print.h: Likewise.
-
-2002-07-29 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/spe.h (__internal_ev_mwhgumian): Cast vector
- constants to __ev64_s32__.
- (__internal_ev_mwhgsmian): Same.
- (__internal_ev_mwhgsmfan): Same.
- (__internal_ev_mwhgssfan): Same.
- (__internal_ev_mwhgumiaa): Same.
- (__internal_ev_mwhgsmiaa): Same.
- (__internal_ev_mwhgsmfaa): Same.
- (__internal_ev_mwhgssfaa): Same.
-
-2002-07-29 David Edelsohn <edelsohn@gnu.org>
-
- * varasm.c (assemble_variable): Narrow test for uninitialized
- without BSS target support.
-
-2002-07-29 Nathan Sidwell <nathan@codesourcery.com>
-
- * profile.c: Add file comment describing the overall algorithm and
- structures.
- (struct edge_info): Add comments.
- (struct bb_info): Add comments.
- * basic-block.h (EDGE_*): Add comments.
- * doc/gcov.texi (Gcov Data Files): Document bit flags.
-
-2002-07-29 Bob Wilson <bob.wilson@acm.org>
-
- * config/xtensa/elf.h, config/xtensa/linux.h
- (TARGET_OS_CPP_BUILTINS): Define.
- (CPP_PREDEFINES): Remove.
- * config/xtensa/xtensa.h (TARGET_CPU_CPP_BUILTINS): Define.
- (CPP_SPEC): Remove.
-
-2002-07-29 Zack Weinberg <zack@codesourcery.com>
-
- * gensupport.c: Include hashtab.h.
- (insn_elision, condition_table, hash_c_test, cmp_c_test,
- maybe_eval_c_test): New routines and data structures to
- support insn elision.
- (init_md_reader): Read and initialize the condition_table.
- (read_md_rtx): Discard insn patterns whose C test is provably
- always false.
- * gensupport.h: Declare new functions and data structures.
-
- * genconditions.c, dummy-conditions.c: New files.
- * Makefile.in: Build genconditions; run it to construct
- insn-conditions.c; build that and link it into most gen*
- programs.
- (HOST_SUPPORT, HOST_EARLY_SUPPORT): New variables.
- (GEN): Delete, unused.
- (STAGESTUFF): Update.
-
- * gencodes.c: (gen_insn): #define CODE_FOR_xxx equal to
- CODE_FOR_nothing for all elided patterns.
- (main): Tweaked to support this.
- * genflags.c (gen_proto): Emit a static inline generator
- function here for all elided patterns, which simply returns
- NULL_RTX.
- (gen_insn): Do not define HAVE_xxx for elided patterns.
- (main): Tweaked to support this. No need to forward-declare
- struct rtx_def.
- * genrecog.c: Do not bother emitting the C test if it's known
- to be true at compile time.
-
-2002-07-29 Mike Stump <mrs@apple.com>
-
- * config.gcc (target_gtfiles): Initialize, as otherwise cross
- compilers hosted on powerpc-apple-darwin6.0 won't even build.
-
-2002-07-29 Richard Earnshaw <rearnsha@arm.com>
-
- * arm.md (sibcall, sibcall_value): Add RETURN as part of the pattern,
- remove clobber of LR.
- (sibcall_insn, sibcall_value_insn): Update accordingly.
- (sibcall_epilogue): Remove debugging comment from assembler stream.
-
-2002-07-29 Gabriel Dos Reis <gdr@nerim.net>
-
- * pretty-print.h: Define more macros.
- * diagnostic.h (output_formatted_integer): Moved from...
- * diagnostic.c: ... here.
-
-2002-07-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * stormy16.h (ASM_OUTPUT_SYMBOL_REF): Use ASM_OUTPUT_LABEL_REF.
-
-2002-07-28 Zack Weinberg <zack@codesourcery.com>
-
- * defaults.h (ASM_OUTPUT_MEASURED_SIZE): Take only two
- arguments. Always use ".-symbol" as expression argument.
- * doc/tm.texi: Update to match. Document requirement for
- ".size symbol, .-symbol" to be acceptable to assembler.
+ * config/sh/sh.h: Likewise.
+ * config/sh/vxworks.h: Likewise.
- * config/elfos.h, config/netbsd-aout.h, config/openbsd.h,
- config/arm/elf.h, config/avr/avr.h, config/cris/aout.h,
- config/i386/freebsd-aout.h, config/i386/sco5.h,
- config/ip2k/ip2k.h, config/m88k/m88k.h, config/xtensa/elf.h,
- config/xtensa/linux.h: Update uses of ASM_OUTPUT_MEASURED_SIZE.
+2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
-2002-07-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+ * system.h (ASM_OUTPUT_MAIN_SOURCE_FILENAME): Poison.
+ * toplev.c (output_file_directive): Don't use
+ ASM_OUTPUT_MAIN_SOURCE_FILENAME.
- * Makefile.in (gengtype-lex.c): Fix error in last change.
+2004-01-05 Steven Bosscher <s.bosscher@student.tudelft.nl>
- * alpha/freebsd.h (TARGET_OS_CPP_BUILTINS): Add missing
- backslash.
+ * toplev.c: Fix broken checkin of 2003-12-30.
- * Makefile.in (vmsdbgout.o): Depend on function.h.
+2004-01-05 Daniel Berlin <dberlin@dberlin.org>
- * vmsdbgout.c: Include function.h.
+ * ggc-zone.c: Remove everything in #ifdef USING_MALLOC_PAGE_GROUPS
+ (USING_MMAP): We don't support non-mmap.
+ (struct alloc_chunk): Steal 1 bit from typecode, use it to mark
+ large objects.
+ (struct page_entry): Remove bytes_free.
+ (struct page_table_chain): Remove.
+ (struct globals): Remove page_table member.
+ (loookup_page_table_entry): Function deleted.
+ (set_page_table_entry): Ditto.
+ (ggc_allocated_p): No longer need page table lookups.
+ (ggc_marked_p): Ditto.
+ (alloc_small_page): Don't care about bytes_free anymore.
+ (alloc_large_page): Round up size.
+ (ggc_alloc_zone_1): Mark large objects as such, and calculate
+ their size the new way.
+ Remove page table lookups and setting.
+ (ggc_get_size): Calculate large object size the new way.
+ (sweep_pages): Redo to account for fact that we no longer have
+ bytes_free.
+ (ggc_collect): No longer need to reincrement bytes_free.
+ (ggc_pch_alloc_object): Handle new large objects properly.
+ (ggc_pch_read): Put PCH stuff into it's own uncollected zone.
-2002-07-28 Alan Modra <amodra@bigpond.net.au>
+2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
- * prefix.c (update_path): Don't strip single `.' path components
- unless stripping a later `..' component. Exit loop as soon as
- a valid path is found.
+ * doc/invoke.texi: Remove a page break.
-2002-07-27 Roger Sayle <roger@eyesopen.com>
+2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
- * builtins.def [DEF_GCC_BUILTIN]: Require an explicit ATTRS
- argument. Mark BUILT_IN_RETURN, BUILT_IN_EH_RETURN,
- BUILT_IN_LONGJMP and BUILT_IN_TRAP as noreturn, the ISO C99
- floating point unordered comparisons (e.g. __builtin_isgreater)
- as const, and leave the remaining GCC_BUILTINs unchanged.
+ * config/avr/avr.c (avr_output_function_prologue): Remove an
+ extra pair of curly braces.
- * c-decl.c (builtin_function): No need to explicitly mark
- BUILT_IN_RETURN and BUILT_IN_EH_RETURN as noreturn.
+2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
-2002-07-27 Roger Sayle <roger@eyesopen.com>
+ * config/mn10300/mn10300.c: Fix comment formatting.
+ * config/mn10300/mn10300.h: Likewise.
- * Makefile.in: rtlanal.o now depends upon real.h.
+2004-01-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
- * flags.h [flag_signaling_nans]: New flag.
- [HONOR_SNANS]: New macro.
+ * tree.h: Update documentation on nothrow_flag.
+ * print-tree.c (print_node): Print TREE_NOTHROW as "align-ok" for
+ types.
- * toplev.c [flag_signaling_nans]: Initialize to false.
- (f_options): Add processing for "-fsignaling-nans".
- (set_fast_math_flags): Clear flag_signaling_nans with -ffast-math.
- (process_options): flag_signaling_nans implies flag_trapping_math.
+2004-01-05 Kazu Hirata <kazu@cs.umass.edu>
- * c-common.c (cb_register_builtins): Define __SUPPORT_SNAN__
- when -fsignaling-nans. First step to implementing WG14's N965.
+ * doc/invoke.texi: Remove traces of dead ports.
- * fold-const.c (fold) [MULT_EXPR]: Conditionalize transforming
- 1.0 * x into x, and -1.0 * x into -x on !HONOR_SNANS.
- [RDIV_EXPR]: Conditionalize x/1.0 into x on !HONOR_SNANS.
+2004-01-05 Richard Sandiford <rsandifo@redhat.com>
- * simplify-rtx.c (simplify_relational_operation): Conditionalize
- transforming abs(x) < 0.0 into false on !HONOR_SNANS.
+ * doc/invoke.texi: Add documentation for the MIPS -mexplicit-relocs
+ option.
- * rtlanal.c: #include real.c for TARGET_FLOAT_FORMAT definitions
- required by HONOR_SNANS. (may_trap_p): Floating point DIV, MOD,
- UDIV, UMOD, GE, GT, LE, LT and COMPARE may always trap with
- -fsignaling_nans. EQ and NE only trap for flag_signaling_nans
- not flag_trapping_math (i.e. HONOR_SNANS but not HONOR_NANS).
+2004-01-05 Richard Sandiford <rsandifo@redhat.com>
- * doc/invoke.texi: Document new -fsignaling-nans compiler option.
+ PR target/12945
+ * coverage.c (coverage_counter_alloc): Set SYMBOL_FLAG_LOCAL for
+ counter labels.
+ * config/mips/mips.c (INTERNAL_SYMBOL_P): Delete.
+ (mips_classify_symbol): Always treat SYMBOL_REF_FLAG as indicating
+ string constants if TARGET_MIPS16. Use SYMBOL_REF_DECL to check
+ the binding of decl symbols, otherwise check SYMBOL_REF_LOCAL_P.
+ (mips_symbol_insns): Don't trust the local/global classification.
+ (m16_usym8_4, m16_usym5_4): Same mips16 change as mips_classify_symbol.
+ (override_options): Make -mabicalls -fno-unit-at-a-time imply
+ -mno-explicit-relocs.
+ (mips_encode_section_info): Don't use SYMBOL_REF_FLAG to distinguish
+ between local and global symbols.
-2002-07-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+2004-01-05 Richard Sandiford <rsandifo@redhat.com>
- * Makefile.in (gengtype-lex.c): Work around a bug in flex.
- * gengtype-lex.l (YY_USE_PROTOS): Undef.
- (YY_DECL): Define.
+ * config/mips/mips-protos.h (mips_dangerous_for_la25_p): Declare.
+ (mips_preferred_reload_class): Declare.
+ * config/mips/mips.h (DANGEROUS_FOR_LA25_P): Replace with function.
+ (EXTRA_CONSTRAINT): Update accordingly.
+ (PREFERRED_RELOAD_CLASS): Use mips_preferred_reload_class.
+ * config/mips/mips.c (mips_dangerous_for_la25_p): New function.
+ (mips_preferred_reload_class): New function. Prefer LEA_REGS if
+ mips_dangerous_for_la25_p.
+ (mips_secondary_reload_class): Use LEA_REGS rather than GR_REGS
+ if mips_dangerous_for_la25_p.
-2002-07-27 Roger Sayle <roger@eyesopen.com>
+2004-01-05 Bernardo Innocenti <bernie@develer.com>
- * doc/invoke.texi: Document that both -fno-builtin-foo and
- -fno-builtin are supported by the g++ front-end.
+ * config/m68k/m68k.c (output_andsi3): Fix signed/unsigned comparison
+ warning.
-2002-07-27 Stan Shebs <shebs@apple.com>
+2004-01-04 Nathanael Nerode <neroden@gcc.gnu.org>
- * configure.in: Rename config_gtfiles to target_gtfiles.
+ * configure.ac: Use AC_PROG_CPP_WERROR.
* configure: Regenerate.
- * doc/gty.texi: Update reference.
- * config.gcc (powerpc-*-darwin*): Set target_gtfiles
- instead of appending to it.
-
-2002-07-25 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/rs6000.c (function_arg_advance): SPE vararg
- vectors are split into two registers.
- (function_arg): Same.
-
-2002-07-26 J"orn Rennecke <joern.rennecke@superh.com>
-
- * pa.md (extv): Check predicates before emitting extv_32.
-
-2002-07-27 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.c (rs6000_traceback_name): New var.
- (rs6000_traceback): New var.
- (rs6000_override_options): Set rs6000_traceback.
- (rs6000_output_function_epilogue): Implement traceback options.
- * config/rs6000/rs6000.h (TARGET_OPTIONS): Add "traceback=".
- (rs6000_traceback_name): Declare.
-
- * config/rs6000/rs6000.c (output_profile_hook): Don't generate profile
- label reference when NO_PROFILE_COUNTERS.
-
-2002-07-26 Jason Merrill <jason@redhat.com>
-
- * function.c (assign_parms): Handle frontend-directed pass by
- invisible reference.
-
-2002-07-26 Neil Booth <neil@daikokuya.co.uk>
-
- * doc/cppopts.texi: Update.
-
-2002-07-26 Neil Booth <neil@daikokuya.co.uk>
-
- * cppmacro.c (_cpp_create_definition): Don't attempt redefinition
- warnings on assertions.
-
-2002-07-26 Neil Booth <neil@daikokuya.co.uk>
-
- * c-common.h (RID_AND, RID_AND_EQ, RID_NOT, RID_NOT_EQ,
- RID_OR, RID_OR_EQ, RID_XOR, RID_XOR_EQ, RID_BITAND, RID_BITOR,
- RID_COMPL): Remove.
- * c-parse.in (rid_to_yy): Similarly.
-
-2002-07-26 Jason Merrill <jason@redhat.com>
-
- * c-dump.c: Resurrect.
- * tree-dump.c: Move C-specific stuff to c-dump.c.
- * c-common.h: Declare c_dump_tree.
- * c-lang.c (LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN): Define.
- * Makefile.in (C_AND_OBJC_OBJS): Add c-dump.o.
- (c-dump.o): New rule.
-
-2002-07-26 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.md: Enable patterns using rlwinm for
- PowerPC64. Replace "T" and "S" constraints with "n" when the
- predicate will do. Formatting fixes.
- (extzvsi_internal2): Use "andi.", "andis." and attr type of "compare"
- as for extzvsi_internal1.
-
-2002-07-25 Neil Booth <neil@daikokuya.co.uk>
-
- * dwarfout.c (VERSION_ASM_OP, DERIV_BEGIN_LABEL_FMT,
- DERIV_END_LABEL_FMT): Remove.
- (SL_BEGIN_LABEL_FMT, SL_END_LABEL_FMT): Move.
-
-2002-07-25 Neil Booth <neil@daikokuya.co.uk>
-
- * objc/objc-act.c (UTAG_STATICS, UTAG_PROTOCOL_LIST, USERTYPE):
- Remove.
-
-2002-07-25 Stan Shebs <shebs@apple.com>
-
- * config/rs6000/rs6000.c (rs6000_emit_prologue): Remove unused
- local var dwarfp.
- (output_compiler_stub): Remove unused locals.
- (output_call): Always initialize line number.
-
-2002-07-25 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.h (LOAD_EXTEND_OP): QImode zero-extends on SHmedia.
- * sh.md (truncdiqi2, movqi_media): Likewise.
-
-2002-07-25 Neil Booth <neil@daikokuya.co.uk>
-
- * gcse.c (obstack_chunk_alloc): Remove.
- (gcse_alloc): Fix to count allocated bytes.
- * collect2.c (SYMBOL__MAIN): Remove.
-
-2002-07-25 Neil Booth <neil@daikokuya.co.uk>
-
- * gcc.c (TARGET_EXECUTABLE_SUFFIX): Only used if
- HAVE_TARGET_EXECUTABLE_SUFFIX.
-
-2002-07-25 J"orn Rennecke <joern.rennecke@superh.com>
-
- * rtl.h (mem_attrs): Spell out more clearly the roles of ALIGN,
- SIZE, EXPR and OFFSET.
-
-2002-07-25 Richard Henderson <rth@redhat.com>
-
- * emit-rtl.c (set_mem_attributes): Fix size and alignment thinkos
- in ARRAY_REF of DECL_P case.
-
-2002-07-25 Richard Sandiford <rsandifo@redhat.com>
-
- * doc/invoke.texi: Document -mabi=meabi, and expand on the EABI
- description. Document -mips32, -mips64, and the associated -march
- values. Describe the "mipsN" arguments to -march. Say that the
- -mipsN options are equivalent to -march. Reword the description
- of default type sizes.
- * toplev.h (target_flags_explicit): Declare.
- * toplev.c (target_flags_explicit): New var.
- (set_target_switch): Update target_flags_explicit.
- * config/mips/abi64.h (SUBTARGET_TARGET_OPTIONS): Undefine.
- * config/mips/elf64.h (MIPS_ISA_DEFAULT): Undefine.
- * config/mips/iris6.h (SUBTARGET_ASM_SPEC): -mabi=64 implies -mips3.
- * config/mips/isa3264.h (MIPS_ENABLE_EMBEDDED_O32): Undefine.
- * config/mips/mips.h (mips_cpu_info): New struct.
- (mips_cpu_string, mips_explicit_type_size_string): Remove.
- (mips_cpu_info_table, mips_arch_info, mips_tune_info): Declare.
- (MIPS_CPP_SET_PROCESSOR): New macro.
- (TARGET_CPP_BUILTINS): Declare a macro for each supported processor.
- Define _MIPS_ARCH and _MIPS_TUNE.
- (MIPS_ISA_DEFAULT): Don't provide a default value. Instead...
- (MIPS_CPU_STRING_DEFAULT): Set to "from-abi" if neither it nor
- MIPS_ISA_DEFAULT were already defined.
- (MULTILIB_DEFAULTS): Add MULTILIB_ABI_DEFAULT.
- (TARGET_OPTIONS): Remove -mcpu and -mexplicit-type-size.
- (ABI_NEEDS_32BIT_REGS, ABI_NEEDS_64BIT_REGS): New.
- (GAS_ASM_SPEC): Remove -march, -mcpu, -mgp* and -mabi rules.
- (ABI_GAS_ASM_SPEC): Remove.
- (MULTILIB_ABI_DEFAULT, ASM_ABI_DEFAULT_SPEC): New macros.
- (ASM_SPEC): Add -mgp32, -mgp64, -march, -mabi=eabi and -mabi=o64.
- Invoke %(asm_abi_default_spec) if no ABI was specified.
- (CC1_SPEC): Remove ISA -> register-size rules.
- (EXTRA_SPECS): Remove abi_gas_asm_spec. Add asm_abi_default_spec.
- * config/mips/mips.c (mips_arch_info, mips_tune_info): New vars.
- (mips_cpu_string, mips_explicit_type_size_string): Remove.
- (mips_cpu_info_table): New array.
- (mips_set_architecture, mips_set_tune): New fns.
- (override_options): Rework to make -mipsN equivalent to -march.
- Detect more erroneous cases, including those removed from CC1_SPEC.
- Don't change the ABI based on architecture, or vice versa.
- Unify logic with GAS.
- (mips_asm_file_start): Get architecture name from mips_arch_info.
- (mips_strict_matching_cpu_name_p, mips_matching_cpu_name_p): New fns.
- (mips_parse_cpu): Take the name of the option as argument. Handle
- 'from-abi'. Raise an error if the option is wrong.
- (mips_cpu_info_from_isa): New fn.
-
-2002-07-25 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.md (tablejump_mips161): Use gen_rtx_LABEL_REF.
- (tablejump_mips162): Likewise.
-
-2002-07-25 J"orn Rennecke <joern.rennecke@superh.com>
-
- * simpify-rtx.c (simplify_subreg): Don't pass MODE_CC mode to
- int_mode_for_mode.
-
-2002-07-25 Gabriel Dos Reis <gdr@nerim.net>
-
- * c-common.c (c_sizeof_or_alignof_type): Take a third argument for
- complaining.
- * c-common.h (c_sizeof): Adjust definition.
- (c_alignof): Likewise.
- * c-tree.h (c_sizeof_nowarn): Now macro.
- * c-typeck.c (c_sizeof_nowarn): Remove definition.
-
-2002-07-25 Neil Booth <neil@daikokuya.co.uk>
-
- * c-decl.c (c_decode_option): No need to handle switches
- cpplib handles.
-
-2002-07-24 Zack Weinberg <zack@codesourcery.com>
-
- * defaults.h (ASM_OUTPUT_TYPE_DIRECTIVE, ASM_OUTPUT_SIZE_DIRECTIVE,
- ASM_OUTPUT_MEASURED_SIZE): New default definitions of new macros.
- * doc/tm.texi: Document them. Also document SIZE_ASM_OP,
- TYPE_ASM_OP, and TYPE_OPERAND_FMT.
-
- * config/elfos.h, config/netbsd-aout.h, config/openbsd.h,
- config/alpha/elf.h, config/arm/elf.h, config/avr/avr.h,
- config/cris/aout.h, config/i386/freebsd-aout.h,
- config/i386/sco5.h, config/ia64/ia64.c, config/ip2k/ip2k.h,
- config/m68k/m68kelf.h, config/m68k/m68kv4.h, config/m88k/m88k.h,
- config/mcore/mcore-elf.h, config/mips/elf.h, config/mips/elf64.h,
- config/mips/iris6.h, config/mips/linux.h, config/pa/pa-linux.h,
- config/pa/pa64-hpux.h, config/rs6000/sysv4.h,
- config/xtensa/elf.h, config/xtensa/linux.h:
- Use the new macros.
- Where possible, remove redundant definitions of SIZE_ASM_OP,
- TYPE_ASM_OP, and TYPE_OPERAND_FMT.
-
-2002-07-24 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/eabi.h: Define TARGET_SPE_ABI, TARGET_SPE,
- TARGET_ISEL, and TARGET_FPRS.
-
- * doc/invoke.texi (RS/6000 and PowerPC Options): Document
- -mabi=spe, -mabi=no-spe, and -misel=.
-
- * config/rs6000/rs6000-protos.h: Add output_isel.
- Move vrsave_operation prototype here.
-
- * config/rs6000/rs6000.md (sminsi3): Allow pattern for TARGET_ISEL.
- (smaxsi3): Same.
- (uminsi3): Same.
- (umaxsi3): Same.
- (abssi2_nopower): Disallow when TARGET_ISEL.
- (*ne0): Same.
- (negsf2): Change to expand and rename old pattern to *negsf2.
- (abssf2): Change to expand and rename old pattern to *abssf2.
-
- New expanders: fix_truncsfsi2, floatunssisf2, floatsisf2,
- fixunssfsi2.
-
- Change patterns that check for TARGET_HARD_FLOAT or
- TARGET_SOFT_FLOAT to also check TARGET_FPRS.
-
- * config/rs6000/rs6000.c: New globals: rs6000_spe_abi,
- rs6000_isel, rs6000_fprs, rs6000_isel_string.
- (rs6000_override_options): Add 8540 case to
- processor_target_table.
- Set rs6000_isel for the 8540.
- Call rs6000_parse_isel_option.
- (enable_mask_for_builtins): New.
- (rs6000_parse_isel_option): New.
- (rs6000_parse_abi_options): Add spe and no-spe.
- (easy_fp_constant): Treat !TARGET_FPRS as soft-float.
- (rs6000_legitimize_address): Check for TARGET_FPRS when checking
- for TARGET_HARD_FLOAT.
- Add case for SPE_VECTOR_MODE.
- (rs6000_legitimize_reload_address): Handle SPE vector modes.
- (rs6000_legitimate_address): Disallow PRE_INC/PRE_DEC for SPE
- vector modes.
- Check for TARGET_FPRS when checking for TARGET_HARD_FLOAT.
- (rs6000_emit_move): Check for TARGET_FPRS.
- Add cases for SPE vector modes.
- (function_arg_boundary): Return 64 for SPE vector modes.
- (function_arg_advance): Check for TARGET_FPRS and
- Handle SPE vectors.
- (function_arg): Same.
- (setup_incoming_varargs): Check for TARGET_FPRS.
- (rs6000_va_arg): Same.
- (struct builtin_description): Un-constify mask field. Move up in
- file.
- (bdesc_2arg): Un-constify and add SPE builtins.
- (bdesc_1arg): Same.
- (bdesc_spe_predicates): New.
- (bdesc_spe_evsel): New.
- (rs6000_expand_unop_builtin): Add SPE 5-bit literal builtins.
- (rs6000_expand_binop_builtin): Same.
- (bdesc_2arg_spe): New.
- (spe_expand_builtin): New.
- (spe_expand_predicate_builtin): New.
- (spe_expand_evsel_builtin): New.
- (rs6000_expand_builtin): Call spe_expand_builtin for SPE.
- (rs6000_init_builtins): Initialize SPE builtins. Call
- rs6000_common_init_builtins.
- (altivec_init_builtins): Move all non-altivec builtin code to...
- (rs6000_common_init_builtins): ...here. New function.
- (branch_positive_comparison_operator): Allow NE code for SPE.
- (ccr_bit): Return correct ccr bit for SPE fp.
- (print_operand): Emit crnor in 'D' case for SPE.
- New case 't'.
- Add SPE code for 'y' case.
- (rs6000_generate_compare): Generate rtl for SPE fp.
- (output_cbranch): Handle SPE hard floats.
- (rs6000_emit_cmove): Handle isel.
- (rs6000_emit_int_cmove): New.
- (output_isel): New.
- (rs6000_stack_info): Adjust stack frame so GPRs are saved in
- 64-bits for SPE.
- (debug_stack_info): Add SPE info.
- (gen_frame_mem_offset): New.
- (rs6000_emit_prologue): Save GPRs in 64-bits for SPE abi.
- Change mode of frame pointer, when saving it, to Pmode.
- (rs6000_emit_epilogue): Restore GPRs in 64-bits for SPE abi.
- Misc cleanups and use gen_frame_mem_offset when appropriate.
-
- * config/rs6000/rs6000.h (processor_type): Add PROCESSOR_PPC8540.
- (TARGET_SPE_ABI): New.
- (TARGET_SPE): New.
- (TARGET_ISEL): New.
- (TARGET_FPRS): New.
- (FIXED_SCRATCH): New.
- (RTX_COSTS): Add PROCESSOR_PPC8540.
- (ASM_CPU_SPEC): Add case for 8540.
- (TARGET_OPTIONS): Add isel= case.
- (rs6000_spe_abi): New.
- (rs6000_isel): New.
- (rs6000_fprs): New.
- (rs6000_isel_string): New.
- (UNITS_PER_SPE_WORD): New.
- (LOCAL_ALIGNMENT): Adjust for SPE.
- (HARD_REGNO_MODE_OK): Same.
- (DATA_ALIGNMENT): Same.
- (MEMBER_TYPE_FORCES_BLK): New.
- (FIRST_PSEUDO_REGISTER): Set to 113.
- (FIXED_REGISTERS): Add SPE registers.
- (reg_class): Same.
- (REG_CLASS_NAMES): Same.
- (REG_CLASS_CONTENTS): Same.
- (REGNO_REG_CLASS): Same.
- (REGISTER_NAMES): Same.
- (DEBUG_REGISTER_NAMES): Same.
- (ADDITIONAL_REGISTER_NAMES): Same.
- (CALL_USED_REGISTERS): Same.
- (CALL_REALLY_USED_REGISTERS): Same.
- (SPE_ACC_REGNO): New.
- (SPEFSCR_REGNO): New.
- (SPE_SIMD_REGNO_P): New.
- (HARD_REGNO_NREGS): Adjust for SPE.
- (VECTOR_MODE_SUPPORTED_P): Same.
- (REGNO_REG_CLASS): Same.
- (FUNCTION_VALUE): Same.
- (LIBCALL_VALUE): Same.
- (LEGITIMATE_OFFSET_ADDRESS_P): Same.
- (SPE_VECTOR_MODE): New.
- (CONDITIONAL_REGISTER_USAGE): Disable FPRs when target does FP on
- the GPRs. Set FIXED_SCRATCH fixed in SPE case.
- (rs6000_stack): Add spe_gp_size, spe_padding_size,
- spe_gp_save_offset.
- (USE_FP_FOR_ARG_P): Check for TARGET_FPRS.
- (LEGITIMATE_LO_SUM_ADDRESS_P): Same.
- (SPE_CONST_OFFSET_OK): New.
- (rs6000_builtins): Add SPE builtins.
-
- * testsuite/gcc.dg/ppc-spe.c: New.
-
- * config/rs6000/eabispe.h: New.
-
- * config/rs6000/spe.h: New.
-
- * config/rs600/spe.md: New.
-
- * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Define
- __SIMD__ for TARGET_SPE.
-
- * config.gcc: Add powerpc-*-eabispe* case.
- Add spe.h to user headers for powerpc.
-
-2002-07-24 Chris Demetriou <cgd@broadcom.com>
-
- * config/mips/elf.h (STARTFILE_SPEC): Undo previous change.
- * config/mips/elf64.h (STARTFILE_SPEC): Likewise.
- * config/mips/isa3264.h (STARTFILE_SPEC): Likewise.
-
-2002-07-24 Richard Henderson <rth@redhat.com>
-
- * expr.c (expand_expr) [TRY_FINALLY_EXPR]: Use GOTO_SUBROUTINE_EXPR
- form when not optimizing.
-
-2002-07-24 David Mosberger <davidm@hpl.hp.com>
-
- * config/ia64/ia64.c (gen_thread_pointer): Fix typo in marking
- thread_pointer_rtx as unchanging.
-
-2002-07-24 Michael Matz <matz@suse.de>
-
- * ra-colorize.c (INV_REG_ALLOC_ORDER): New macro.
- (free_reg): Use it.
-
-2002-07-24 Richard Earnshaw <rearnsha@arm.com>
-
- * arm.md (arm_buneq, arm_bltgt): put '\' before ';' in output
- pattern.
- (arm_buneq_reversed, arm_bltgt_reversed): Likewise.
- (movsicc, movsfcc, movdfcc): FAIL if UNEQ or LTGT.
-
-2002-07-24 Chris Demetriou <cgd@broadcom.com>
-
- * config/mips/elf.h (STARTFILE_SPEC): Never include crt0.o.
- * config/mips/elf64.h (STARTFILE_SPEC): Likewise.
- * config/mips/isa3264.h (STARTFILE_SPEC): Do not redefine.
-
-2002-07-24 Jan Hubicka <jh@suse.cz>
-
- * toplev.c (rest_of_compilation): Dump loops before clobbering
- the structure.
-
-2002-07-24 Jan Hubicka <jh@suse.cz>
-
- * rtlanal.c (keep_with_call_p): Avoid overflow in fixed_regs.
-
-2002-07-24 Frank van der Linden <fvdl@wasabisystems.com>
-
- PR optimization/7291
- * config/i386/i386.c (ix86_expand_clrstr): Fix bzero alignment
- problem on x86_64.
-
-2002-07-24 Gabriel Dos Reis <gdr@nerim.net>
-
- * pretty-print.h: Add macros from cp/error.c
-
-2002-07-24 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000-protos.h (mask_operand_wrap): Declare.
- (mask64_2_operand): Declare.
- (build_mask64_2_operands): Declare.
- (and64_2_operand): Declare.
- (extract_MB): Declare.
- (extract_ME): Declare.
- * config/rs6000/rs6000.c (mask64_operand): Allow all ones. Remove
- CONST_DOUBLE code.
- (mask_operand_wrap): New insn predicate.
- (mask64_2_operand): Likewise.
- (and64_2_operand): Likewise.
- (build_mask64_2_operands): New function.
- (extract_MB): New function.
- (extract_ME): New function.
- (print_operand <case m,M>): Use extract_MB and extract_ME.
- (print_operand <case S>): Allow all ones. Remove CONST_DOUBLE support.
- * config/rs6000/rs6000.h (EXTRA_CONSTRAINT): Add 't'.
- (PREDICATE_CODES): Add and64_2_operand, mask_operand_wrap and
- mask64_2_operand. Remove CONST_DOUBLE from mask64_operand.
- * config/rs6000/rs6000.md (andsi3_internal3): New
- (andsi3_internal3+1): Enable split for powerpc64.
- (andsi3_internal3+2): New split.
- (andsi3_internal4): Renamed old andsi3_internal3.
- (andsi3_internal5): New.
- (andsi3_internal5+1): Enable split for powerpc64.
- (andsi3_internal5+2): New split.
- (andsi3_internal6, andsi3_internal7, andsi3_internal8): New.
- (anddi3): Handle 't' constraint.
- (anddi3+1): New split.
- (anddi3_internal2): Handle 't' constraint.
- (anddi3_internal2+1): New split.
- (anddi3_internal3): Handle 't' constraint.
- (anddi3_internal3+1): New split.
-
-2002-07-24 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.md: Remove scratch reg on insns using
- addze and similar (plus (comparison r1 r2) r3) insns. Add
- missing scratch reg in one case. Formatting fixes.
-
-2002-07-24 Neil Booth <neil@daikokuya.co.uk>
-
- * cppexp.c (parse_defined): Mark macro used.
- * cpphash.h (struct cpp_macro): New member "used".
- (_cpp_mark_macro_used, _cpp_warn_if_unused_macro): New.
- (struct cpp_reader): New member.
- * cppinit.c (cpp_finish_options): Set first_unused_line.
- (cpp_finish): Warn of unused macros if requested.
- (OPT_TABLE): New switches.
- (cpp_handle_option): Handle them.
- * cpplib.c (do_undef): Warn if macro unused.
- (do_ifdef, do_ifndef): Mark macro used.
- * cpplib.h (struct cpp_options): New member.
- * cppmacro.c (_cpp_warn_if_unused_macro): New.
- (enter_macro_context): Mark macro used.
- (_cpp_create_definition): Mark macro unused; warn if unused
- when redefined.
- * cpptrad.c (scan_out_logcial_line, push_replacement_text):
- Mark macros used.
- * doc/cppopts.texi: Update.
-
-2002-07-23 Neil Booth <neil@daikokuya.co.uk>
-
- * dwarf2out.c (SECTION_ASM_OP,
- ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL): Remove.
- * system.h (SECTION_ASM_OP): Poison.
- * tree.c (FILE_FUNCTION_PREFIX_LEN): Remove.
- * config/alpha/alpha-interix.h, config/mips/linux.h
- (ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL): Remove.
- * config/mmix/mmix-protos.h, config/mmix/mmix.c
- (mmix_asm_output_define_label_difference_symbol): Remove.
- * config/mmix/mmix.h
- (ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL): Remove.
- * doc/tm.texi: Remove documentation.
-
-2002-07-23 J"orn Rennecke <joern.rennecke@superh.com>
-
- * recog.c (asm_operand_ok): Allow float CONST_VECTORs for 'F'.
- (constrain_operands): Likewise.
- * regclass.c (record_reg_classes): Likewise.
- * reload.c (find_reloads): Likewise.
- * doc/md.texi: Likewise.
-
- * reload.c (find_reloads_toplev): Use simplify_gen_subreg.
- * simplify-rtx.c (simplify_subreg): When converting to a non-int
- mode, try to convert to an integer mode of matching size first.
-
- * simplify-rtx.x (simplify_subreg): When constructing a CONST_VECTOR
- from individual subregs, check that each subreg has been generated
- sucessfully.
-
-2002-07-23 Neil Booth <neil@daikokuya.co.uk>
-
- * genautomata.c (VLA_HWINT_SHORTEN, VLA_HWINT_LAST): Remove.
- * df.c (HANDLE_SUBREG, FOR_EACH_BB_IN_BITMAP_REV,
- FOR_EACH_BB_IN_SBITMAP): Remove.
- * gcse.c (NEVER_SET, FOLLOW_BACK_EDGES): Remove.
- * haifa-sched.c (DONE_PRIORITY, MAX_PRIORITY, TAIL_PRIORITY,
- LAUNCH_PRIORITY, DONE_PRIORITY_P, LOW_PRIORITY_P): Remove.
- * loop.c (PREFETCH_BLOACK_IN_LOOP_MIN,
- PREFETCH_LIMIT_TO_SIMULTANEOUS): Remove.
- * regrename.c (REGNO_MODE_OK_FOR_BASE_P): Remove.
-
-2002-07-23 Gabriel Dos Reis <gdr@nerim.net>
-
- * pretty-print.h: New file.
-
-2002-07-23 Paul Koning <pkoning@equallogic.com>
-
- * real.c (REAL_WORDS_BIG_ENDIAN): Make 1 for DEC.
- (LARGEST_EXPONENT_IS_NORMAL): Ditto.
- (VAX_HALFWORD_ORDER): Define (1 for DEC VAX, 0 otherwise).
- (TARGET_G_FLOAT): Default to 0 if not defined.
- (ieeetoe): New, common routine to convert target format floats
- to internal form.
- (e24toe, e53toe): Change to use ieeetoe, distinguish DEC
- vs. others.
- (e113toe): Change to use ieeetoe.
-
-2002-07-23 Roman Lechtchinsky <rl@cs.tu-berlin.de>
-
- * real.c (REAL_WORDS_BIG_ENDIAN): Make sure it is 0 for DEC and 1 for
- IBM.
- (e53toe): Assume IEEE if non of DEC, IBM and C4X is defined.
- (e64toe): Remove special cases for DEC and IBM. Remove support for
- ARM_EXTENDED_IEEE_FORMAT.
- (e24toe): Remove special cases for DEC.
- (significand_size): Simplify. Indent.
- (ieee_format, ieee_24, ieee_53, ieee_64, ieee_113): New.
- (etoieee, toieee): New.
- (etoe113, toe113, etoe64, toe64, etoe53, toe53, etoe24, toe24): Use
- etoieee and toieee for IEEE arithmetic.
-
-2002-07-23 Gabriel Dos Reis <gdr@nerim.net>
-
- * doc/extend.texi: Say ISO C90, not ISO C89.
- * doc/invoke.texi: Likewise.
- * doc/standards.texi: Likewise.
-
-2002-07-23 Steve Ellcey <sje@cup.hp.com>
-
- * gcc/explow.c (convert_memory_address): Fix conversion of CONSTs.
- Fix permutation of conversion and plus/mult.
- * gcc/builtins.c (expand_builtin_memcpy) Ensure return pointer is
- ptr_mode and not Pmode when POINTERS_EXTEND_UNSIGNED is defined.
- (expand_builtin_strncpy) Ditto.
- (expand_builtin_memset) Ditto.
-
-2002-07-23 Gabriel Dos Reis <gdr@nerim.net>
-
- Fix PR/7363:
- * c-common.c (c_sizeof_or_alignof_type): New function.
- (c_alignof): Remove definition.
- * c-common.h (c_sizeof, c_alignof): Define as macros.
- (c_sizeof_or_alignof_type): Declare.
- (my_friendly_assert): Moved from cp/cp-tree.h
- * c-typeck.c (c_sizeof): Remove definition.
-
-2002-07-23 Jan Hubicka <jh@suse.cz>
-
- * gcse.c (try_replace_reg): Use num_changes_pending.
- * recog.c (num_changes_pending): New function.
- (validate_replace_src): Use validate_repalce_src_group.
- (validate_replace_src_group): New.
- * recog.h (validate_repalce_src_group): New.
- (num_changes_pending): Likewise.
-
-2002-07-23 J"orn Rennecke <joern.rennecke@superh.com>
-
- * calls.c (emit_library_call_value_1): If
- FUNCTION_ARG_PASS_BY_REFERENCE is true, pretend this is neither
- libcall, const call nor pure call.
-
-2002-07-23 Neil Booth <neil@daikokuya.co.uk>
-
- * config/m88k/m88k.h (SECTION_ASM_OP): Remove.
-
-2002-07-23 Neil Booth <neil@daikokuya.co.uk>
-
- * vmsdbgout.c (SECTION_ASM_OP): Remove.
-
-2002-07-23 Neil Booth <neil@daikokuya.co.uk>
-
- * config/i386/i386.c (AT_BP): Remove.
-
-2002-07-23 Neil Booth <neil@daikokuya.co.uk>
-
- * defaults.h (obstack_chunk_alloc, obstack_chunk_free):
- Default definition.
- * gcse.c: Don't define obstack_chunk_free.
- * collect2.c, conflict.c, df.c, diagnostic.c, fix-header.c,
- flow.c, gcc.c, genattrtab.c, genautomata.c, genflags.c, gensupport.c,
- integrate.c, loop.c, ra.c, read-rtl.c, regrename.c, reload1.c,
- reorg.c, tlink.c, tree.c, config/arm/arm.c, objc/objc-act.c:
- Don't define obstack macros.
-
-2002-07-22 Stephane Carrez <stcarrez@nerim.fr>
-
- PR target/6744
- * config/m68hc11/m68hc11.c (m68hc11_z_replacement): Also replace
- ASM_OPERANDS instructions.
-
-2002-07-22 Stephane Carrez <stcarrez@nerim.fr>
-
- PR target/7361
- * config/m68hc11/m68hc11.c (go_if_legitimate_address_internal): Accept
- constant addresses only on 68HC12.
-
-2002-07-22 Neil Booth <neil@daikokuya.co.uk>
-
- * cppfiles.c (stack_include_file): Correct test of whether
- a dependency should be output.
-
-2002-07-22 David Edelsohn <edelsohn@gnu.org>
-
- * collect2.c (is_ctor_dtor): Add other possible JOINER values.
-
-2002-07-22 Richard Earnshaw <rearnsha@arm.com>
-
- * arm.md (movqi): If optimizing and we can create pseudos, use
- a ZERO_EXTEND to load from memory, then copy the result into the
- target.
- (movhi): Likewise, but only for ARMv4.
-
-2002-07-22 Neil Booth <neil@daikokuya.co.uk>
-
- * ssa-ccp.c (PHI_PARMS): Remove.
-
-2002-07-22 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.h (CLASS_CANNOT_CHANGE_MODE): Include FP_REGS
- on big-endian targets.
-
-2002-07-22 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * hwint.h (HOST_WIDE_INT_PRINT_DEC_SPACE,
- HOST_WIDE_INT_PRINT_UNSIGNED_SPACE,
- HOST_WIDEST_INT_PRINT_DEC_SPACE, HOST_WIDEST_INT_PRINT_DEC_SPACE):
- New formatting macros.
-
- * ra-debug.c (dump_static_insn_cost): Avoid string concatenation.
-
-2002-07-22 J"orn Rennecke <joern.rennecke@superh.com>
-
- * rtlanal.c (subreg_regno_offset): Return correct offset for
- big endian paradoxical subregs.
-
- * optabs.c (expand_vector_unop): Don't expand using sub_optab
- if we got the wrong mode.
-
- * hwint.c (define HOST_WIDE_INT_PRINT_DEC_C): New define.
- * genrecog.c (write_switch, write_cond): Use it.
- * genemit.c (gen_exp): Likewise.
-
-2002-07-22 Jakub Jelinek <jakub@redhat.com>
-
- * c-decl.c (build_compound_literal): Set decl TREE_READONLY from TYPE.
-
-2002-07-22 Jakub Jelinek <jakub@redhat.com>
-
- * c-decl.c (build_compound_literal): Defer compound literal decls
- until until file end to emit them only if they are actually used.
-
-2002-07-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * ra-build.c (check_conflict_numbers): Hide unused function.
- (livethrough_conflicts_bb): Avoid automatic aggregate
- initialization.
- (parts_to_webs_1): Avoid `U' integer constant modifier.
- (conflicts_between_webs): Wrap a variable in the macro controlling
- its usage.
- * ra-debug.c (ra_debug_msg): Use VA_OPEN/VA_CLOSE.
- (dump_igraph, dump_graph_cost): Avoid string concatenation
- (dump_static_insn_cost): Avoid automatic aggregate
- initialization.
- * ra-rewrite.c (insert_stores): Avoid automatic aggregate
- initialization.
- (dump_cost): Avoid string concatenation
-
-2002-07-21 Richard Henderson <rth@redhat.com>
-
- * expr.c (expand_expr) [TRY_FINALLY_EXPR]: Don't use
- GOTO_SUBROUTINE_EXPR when finally_block can be re-expanded.
-
-2002-07-21 Richard Henderson <rth@redhat.com>
-
- * unroll.c (find_splittable_givs): Do not split DEST_ADDR givs
- that are not unrolled completely.
-
-2002-07-21 Richard Henderson <rth@redhat.com>
-
- * loop.h (LOOP_AUTO_UNROLL): Rename from LOOP_FIRST_PASS.
- * loop.c (strength_reduce): Update.
- * toplev.c (rest_of_compilation): Do unrolling in the first
- loop pass, not the second.
-
-2002-07-21 Richard Henderson <rth@redhat.com>
-
- * emit-rtl.c (set_mem_attributes): Preserve indirection of PARM_DECL
- when flag_argument_noalias == 2.
- * alias.c (nonoverlapping_memrefs_p): Handle that.
- * print-rtl.c (print_mem_expr): Likewise.
-
-2002-07-21 Hartmut Schirmer <hartmut.schirmer@arcor.de>
-
- * libgcc2.c (__divdi3, __moddi3): Use unary minus operator
- instead of __negdi2 directly.
-
-2002-07-21 Neil Booth <neil@daikokuya.co.uk>
-
- * gengenrtl.c (gencode): Don't define obstack_alloc_rtx.
- * function.c (SYMBOL__MAIN): Remove definition.
- * global.c (SET_CONFLICT, REGBITP, ALLOCNO_LIVE_P): Remove.
- * predict.c (PROB_NEVER, PROB_LIKELY, PROB_UNLIKELY): Remove.
- * profile.c (GCOV_INDEX_TO_BB): Remove.
- * sched-rgn.c (ABS_VALUE, MIN_DIFF_PRIORITY, MIN_PROB_DIFF): Remove.
- * simplify-rtx.c (FIXED_BASE_PLUS_P): Remove.
-
-2002-07-21 Neil Booth <neil@daikokuya.co.uk>
-
- * c-lex.c (GET_ENVIRONMENT): Remove.
- * collect2.c (GET_ENV_PATH_LIST): Remove.
- (prefix_from_env): Use GET_ENVIRONMENT.
- * cppinit.c (GET_ENV_PATH_LIST): Remove.
- (init_standard_includes): Use GET_ENVIRONMENT.
- * defaults.h (GET_ENVIRONMENT): Define here if not already.
- * gcc.c (GET_ENV_PATH_LIST): Remove.
- (make_relative_prefix, process_command): Update.
- * protoize.c (GET_ENV_PATH_LIST): Remove.
- (do_processing): Update.
-
-2002-07-21 Gabriel Dos Reis <gdr@nerim.net>
-
- * c-decl.c (build_array_declarator): Say 'ISO C90', not 'ISO C89'.
- (grokdeclarator): Likewise.
- * c-format.c (C_STD_NAME): Likewise.
- * c-lex.c (interpret_integer): Likewise.
- * c-typeck.c (build_array_ref): Likewise.
- * cpplex.c (_cpp_lex_direct): Likewise.
- * toplev.c (documented_lang_options): Likewise.
-2002-07-21 Neil Booth <neil@daikokuya.co.uk>
+2004-01-04 Zack Weinberg <zack@codesourcery.com>
- * c-format.c (T99_I, T99_UI): Remove.
+ * .cvsignore: Add autom4te.cache.
-2002-07-21 Neil Booth <neil@daikokuya.co.uk>
+2004-01-04 Richard Sandiford <rsandifo@redhat.com>
- * c-typeck.c (SAVE_SPELLING_DEPTH): Remove.
+ * doc/invoke.texi: Revamp documentation of MIPS options. Remove
+ -mabi=meabi, -mabi-fake-default, -mmips-as, -mgas, -mmips-tfile,
+ -m4650, -mfix7000 and -(m)no-crt0. Put endianness options first,
+ then architecture options, then ABI options. General rewording.
-2002-07-21 Jan Hubicka <jh@suse.cz>
+2004-01-04 Joseph S. Myers <jsm@polyomino.org.uk>
- * gcse.c (do_local_cprop): Do not extend lifetimes of registers set by
- do_local_cprop.
+ PR c/3414
+ * doc/extend.texi: Clarify definition of malloc attribute.
-2002-07-21 Andreas Jaeger <aj@suse.de>
+2004-01-04 Jan Hubicka <jh@suse.cz>
- * reload1.c (fixup_abnormal_edges): Remove unused variable.
+ * Makefile.in (cgraph.o, cgraphunit.o): Add intl.h dependency.
+ * cgraph.c (create_edge, dump_cgraph): Update to use inline_failed
+ * cgraph.h (cgraph_edge): Replace inline_call by inline_failed
+ (cgraph_inline_p): Add extra argument reason.
+ * cgraphunit.c: Minor formating fixes.
+ cgraph_first_inlined_callee): New functions.
+ (record_call_1): Record builtins too.
+ (cgraph_analyze_function): Update inline_failed messages.
+ (cgraph_mark_functions_to_output, cgraph_expand_function, cgraph_inlined_into,
+ cgraph_inlined_callees, cgraph_estimate_growth): Update to use inline_failed.
+ (cgraph_check_inline_limits): Likewise; Add argument reason.
+ (cgraph_set_inline_failed): New static function.
+ (cgraph_decide_inlining_of_small_function, cgraph_decide_inlining): Set
+ reasons.
+ (cgraph_inline_p): Add new argument reason.
+ * tree-inline.c (expand_call_inline): Update warning.
-2002-07-21 Bernd Schmidt <bernds@redhat.com>
+2004-01-03 Nathanael Nerode <neroden@gcc.gnu.org>
- Improvements for the ifcvt pass from Michael Meissner, with patches
- by Richard Sandiford <rsandifo@redhat.com>
- * basic-block.h (struct ce_if_block, ce_if_block_t): New types.
- * ifcvt.c (cond_exec_changed_p): New static variable.
- (last_active_insn): New function, renamed from last_active_insn_p
- and changed to return the last active insn in a basic block. All
- callers updated.
- (block_fallthru): New function.
- (cond_exec_process_insns): New argument CE_INFO. Pass it to
- IFCVT_MODIFY_INSN. All callers updated.
- Return false if START or END are NULL.
- Handle case where we're processing an insn that is already
- conditional.
-
- (noce_process_if_block): CE_INFO argument rather than
- multiple args containing the involved basic blocks. All callers
- changed.
- (process_if_block, merge_if_block, find_if_block,
- cond_exec_process_if_block): Likewise.
-
- (cond_exec_process_if_block): New arg DO_MULTIPLE_P. All callers
- changed.
- Use new function last_active_insn to simplify some code.
- New code to handle multiple tests.
- Call IFCVT_MODIFY_CANCEL in all failure cases, otherwise set
- cond_exec_changed_p to TRUE.
-
- (process_if_block): New code to handle multiple tests.
- (merge_if_block): Likewise.
- (find_if_header): New arg PASS. Changed to return the currently
- processed basic block or NULL instead of true/false. All callers
- changed.
- Call IFCVT_INIT_EXTRA_FIELDS.
- (block_jumps_and_fallthru_p): New function.
- (find_if_block): Discover opportunities to convert multiple tests.
- Add additional debugging output.
- Update the ce_info structure before returning.
-
- (if_convert): Run multiple passes of if-conversion.
- * doc/tm.texi (IFCVT_MODIFY_TESTS, IFCVT_MODIFY_INSN,
- IFCVT_MODIFY_FINAL, IFCVT_MODIFY_CANCEL, IFCVT_MODIFY_MULTIPLE_TESTS,
- IFCVT_INIT_EXTRA_FIELDS, IFCVT_EXTRA_FIELDS): Update documentation for
- these macros.
-
-2002-07-21 Jan Hubicka <jh@suse.cz>
-
- * gcse.c: Include cselib.h
- (constptop_register): Break out from ...
- (cprop_insn): ... here; kill basic_block argument.
- (do_local_cprop, local_cprop_pass): New functions.
- (one_cprop_pass): Call local_cprop_pass.
-
-2002-07-20 Roger Sayle <roger@eyesopen.com>
-
- * simplify-rtx.c (simplify_relational_operation): Optimize
- abs(x) < 0.0 (and abs(x) >= 0.0 when using -ffast-math).
-
-2002-07-20 Michae Matz <matz@suse.de>
-
- * ra-build.c: (remember_web_was_spilled): Use GENERAL_REGS.
-
-2002-07-20 Neil Booth <neil@daikokuya.co.uk>
-
- * cppexp.c (struct op): Add token pointer.
- (check_promotion, CHECK_PROMOTION): New.
- (optab): Update.
- (_cpp_parse_expr): Update, use token pointer of struct op.
- (reduce): Warn about change of sign owing to promotion.
- * cppinit.c (cpp_handle_option): New warning if -Wall.
- * cpplib.h (struct cpp_options): New member.
-
-2002-07-19 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.md: Remove ppc630 fpcompare from single
- fpu list. Separate Power4 compare and delayed_compare. Correct
- Power4 fpcompare.
- (fix_truncdfsi2_internal): Restore FPR preference.
- * config/rs6000/t-aix43 (MULTILIB_MATCHES): Add mcpu?power3,
- mcpu?power4, mcpu?604e. Remove mpower, mpower2, mpowerpc.
-
-2002-07-19 Momchil Velikov <velco@fadata.bg>
-
- * reload1.c (reload_as_needed): Duplicate oldpat.
-
-2002-07-20 Alan Modra <amodra@bigpond.net.au>
-
- PR optimization/7130
- * loop.h (struct loop_info): Add "preconditioned".
- * unroll.c (unroll_loop): Set it.
- * doloop.c (doloop_modify_runtime): Correct count for unrolled loops.
-
-2002-07-19 Zack Weinberg <zack@codesourcery.com>
-
- * rtl.def (CODE_LABEL): Remove slot 8.
- * rtl.h (struct rtx_def): Document new uses of jump and call fields.
- (LABEL_ALTERNATE_NAME): Delete.
- (LABEL_KIND, SET_LABEL_KIND, LABEL_ALT_ENTRY_P): New.
- * defaults.h: Remove default for ASM_OUTPUT_ALTERNATE_LABEL_NAME.
-
- * final.c (output_alternate_entry_point): New.
- (final_scan_insn): Use it instead of
- ASM_OUTPUT_ALTERNATE_LABEL_NAME. Do not consider possibility
- of a case label being an alternate entry point.
-
- * cfgbuild.c (make_edges, find_bb_boundaries): Use LABEL_ALT_ENTRY_P.
- * emit-rtl.c (gen_label_rtx): Adjust call to gen_rtx_CODE_LABEL.
- Do not clear LABEL_NUSES (unnecessary) or LABEL_ALTERNATE_NAME
- (field deleted).
- * print-rtl.c, ra-debug.c: Update code to output CODE_LABELs.
-
- * doc/rtl.texi: Document LABEL_KIND, SET_LABEL_KIND, and
- LABEL_ALT_ENTRY_P; not LABEL_ALTERNATE_NAME.
- * doc/tm.texi: Delete documentation of
- ASM_OUTPUT_ALTERNATE_LABEL_NAME.
-
-2002-07-19 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
-
- * config/mips/iris5gas.h (DWARF2_DEBUGGING_INFO): Define.
- (PREFERRED_DEBUGGING_TYPE): Use DWARF2_DEBUG.
- (LINK_SPEC): Define.
- (STARTFILE_SPEC): Define.
- (ENDFILE_SPEC): Define.
-
- * config/mips/iris6-o32.h (LINK_SPEC): Move ...
- * config/mips/iris6-o32-as.h (LINK_SPEC): ... here.
-
- * config/mips/iris6-o32-gas.h: New file.
- * config.gcc (mips-sgi-irix6*o32): Use it.
-
- * config/mips/t-iris5-gas: New file.
- * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix5*): Use it.
-
-2002-07-19 Neil Booth <neil@daikokuya.co.uk>
-
- * cppexp.c (ALWAYS_EVAL): Remove.
- (optab, reduce): Always evaluate.
- (num_unary_op, num_binary_op, num_div_op): Issue diagnostics
- only if not skipping evaluation.
-
-2002-07-19 Marek Michalkiewicz <marekm@amelek.gda.pl>
-
- * config/avr/avr.c (debug_hard_reg_set): Remove.
-
-2002-07-19 Chris Demetriou <cgd@broadcom.com>
-
- * gcc.c (cpp_options): Include "%1" (cc1_spec).
-
-2002-07-19 Richard Henderson <rth@redhat.com>
-
- * loop.c (loop_givs_rescan): Delete the REG_EQUAL note, not the insn.
-
-2002-07-19 Alan Modra <amodra@bigpond.net.au>
-
- * prefix.c (update_path): Don't zap single `.' path components
- unless followed by another `.' and fix typo last patch.
-
-2002-07-18 Neil Booth <neil@daikokuya.co.uk>
-
- * cppexp.c (cpp_num_mul): Remove unused parameter.
- (UNARY, BINARY, OTHER, binary_handler): Remove.
- (ALWAYS_EVAL): New.
- (optab): Update.
- (reduce): Refactor to a large switch, don't use a function
- pointer.
-
-2002-07-18 Bo Thorsen <bo@berlioz.suse.de>
-
- * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): Define this always.
-
-2002-07-18 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh-protos.h (sh_expand_unop_v2sf): Move inside #ifdef RTX_CODE guard.
- (sh_expand_binop_v2sf): Likewise.
- * sh.c (machine_dependent_reorg): Add move for UNSPEC_MOVA.
- (int_gpr_dest, trunc_hi_operand): New functions.
- * sh.h (PREDICATE_CODES): Add any_register_operand, int_gpr_dest and
- trunc_hi_operand.
- (SPECIAL_MODE_PREDICATES, any_register_operand): Define.
- * sh.md (cmpeqdi_t+1): Remove comments that genrecog warns about.
- (adddi3_compact+1, subdi3_compact+1, ashlsi3_n+1, ashlhi3+1): Likewise.
- (ashrsi2_16+1, ashrsi2_31+1, lshrsi3_n+1, ashrdi3+[12]): Likewise.
- (and_shl_scratch+[12], zero_extendhidi2+1): Likewise.
- (zero_extendhisi2_media+1, extendhidi2+1, extendqidi2+1): Likewise.
- (extendhisi2_media+1, extendqisi2_media+1): Likewise.
- (movsi_media_nofpu+[12], movhi_media+1, movdi_media_nofpu+1): Likewise.
- (movdi_const_16bit+[12], movdf_i4+[123], reload_outdf+[2-5]): Likewise.
- (movsf_ie+1): Likewise.
- (loaddi_trunc): Use int_gpr_dest predicate.
- (use_sfunc_addr, indirect_jump_scratch, sibcall_compact): Add mode(s).
- (mova, mova_const, GOTaddr2picreg, ptrel, casesi_worker_0): Likewise.
- (casesi_worker_0+[12], casesi_worker): Likewise.
- (shcompact_preserve_incoming_args): Likewise.
- (mov_nop): Use any_register_operand predicate.
- (mperm_w0): Use trunc_hi_operand predicate.
-
-2002-07-18 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa-linux.h (DWARF2_UNWIND_INFO): Delete define.
- * pa.h (EH_RETURN_DATA_REGNO): Revise TARGET_64BIT and correct
- numbering.
-
-2002-07-18 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa.c (output_deferred_plabels): Remove unused millicode enum mulU.
-
-2002-07-18 Richard Henderson <rth@redhat.com>
-
- PR optimization/7147
- * ifcvt.c (noce_get_condition): Make certain that the condition
- is valid at JUMP.
-
-2002-07-18 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.c (barrier_align, push): Shut up compiler warnings.
- (initial_elimination_offset,sh_media_init_builtins): Likewise.
- (reg_no_subreg_operand): Delete.
-
-2002-07-17 Bo Thorsen <bo@suse.de>
-
- * config/i386/linux64.h (LINK_SPEC): Remove bogus -Y option.
- (STARTFILE_PREFIX_SPEC): Define for NATIVE_CROSS compilations.
- (STARTFILE_SPEC): Remove hardcoded library paths.
- (ENDFILE_SPEC): Likewise.
-
-2002-07-18 Jan Hubicka <jh@suse.cz>
-
- * gcse.c (hoist_expr_reaches_here_p): Stop once expr_bb is reached.
-
- * gcse.c (try_replace_reg): Do not return false positives.
-
-2002-07-18 Alan Modra <amodra@bigpond.net.au>
-
- * prefix.c: (update_path): Strip ".." components when prior dir
- doesn't exist. Pass correct var to UPDATE_PATH_HOST_CANONICALIZE.
-
- * config/rs6000/sysv4.h (ASM_OUTPUT_REG_PUSH): Remove 64-bit support.
- (ASM_OUTPUT_REG_POP): Likewise.
-
-2002-07-18 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/rs6000.c (first_reg_to_save): Remove bogus
- adjustments to first_reg for profiling case.
- (output_function_profiler): Correct lr save slot for ABI_AIX_NODESC.
- Disable profiling for 64 bit code on both ABI_V4 and ABI_AIX_NODESC.
- Save static chain reg to sp + 12 on ABI_AIX_NODESC.
- * config/rs6000/sysv4.h (ASM_OUTPUT_REG_PUSH): Define.
- (ASM_OUTPUT_REG_POP): Define.
- * config/rs6000/linux64.h (ASM_OUTPUT_REG_PUSH): Undef.
- (ASM_OUTPUT_REG_POP): Undef.
-
-2002-07-17 Neil Booth <neil@daikokuya.co.uk>
-
- * cpplib.c (do_sccs): Handle #sccs on all systems.
- * system.h (SCCS_DIRECTIVE): Poison.
- * config/darwin.h, config/freebsd.h, config/netbsd.h,
- config/ptx4.h, config/svr3.h, config/svr4.h, config/alpha/elf.h,
- config/arm/linux-elf.h, config/c4x/c4x.h, config/d30v/d30v.h,
- config/i370/i370.h, config/i386/gas.h, config/i386/sco5.h,
- config/i960/i960.h, config/m68hc11/m68hc11.h, config/m68k/3b1.h,
- config/m68k/3b1g.h, config/m68k/crds.h, config/m68k/mot3300.h,
- config/m68k/pbb.h, config/m88k/m88k.h, config/mips/mips.h,
- config/sparc/pbd.h, config/stormy16/stormy16.h, config/vax/vaxv.h:
- Remove all references to SCCS_DIRECTIVE.
- * doc/cpp.texi, doc/tm.texi: Update.
-
-2002-07-17 J"orn Rennecke <joern.rennecke@superh.com>
-
- * regrename.c (maybe_mode_change): New function.
- (find_oldest_value_reg, copyprop_hardreg_forward_1): Use it.
-
-2002-07-17 Rodney Brown <rbrown64@csc.com.au>
-
- * config/i386/i386.c (ix86_expand_int_movcc): In the general case
- suppress addition when either ct or cf are zero.
-
-2002-07-17 Eric Botcazou <ebotcazou@multimania.com>
- Glen Nakamura <glen@imodulo.com>
-
- PR optimization/6713
- * loop.c (loop_givs_rescan): Explicitly delete the insn that
- sets a non-replaceable giv after issuing the new one.
-
-2002-07-17 Neil Booth <neil@daikokuya.co.uk>
-
- * cppexp.c (cpp_interpret_integer, append_digit, parse_defined,
- eval_token): Clarify and correct use of "bool" variables.
- * cpplib.h (struct cpp_options): Similarly.
- * cppmacro.c (parse_params, _cpp_save_parameter): Ditto.
- * cpptrad.c (recursive_macro): Similarly.
-
-2002-07-17 J"orn Rennecke <joern.rennecke@superh.com>
-
- * config/sh/lib1funcs.asm (udivsi3_i4): Implement SHcompact version in
- SHmedia code.
-
- * sh.md (cmpgtudi_media): Remove spurious @.
-
- * config/sh/lib1funcs.asm (FMOVD_WORKS): Don't define for little endian.
- * sh.h (OVERRIDE_OPTIONS): Don't set FMOVD_BIT for little endian.
-
- * config/sh/lib1funcs.asm (init_trampoline): New entry point.
- * sh-protos.h (sh_initialize_trampoline): Declare.
- * sh.c (sh_initialize_trampoline): New function.
- * sh.h (TRAMPOLINE_SIZE): Only 24 for TARGET_SHMEDIA32.
- (TRAMPOLINE_ALIGNMENT): Need cache-line alignment for TARGET_SHMEDIA.
- (INITIALIZE_TRAMPOLINE): Call sh_initialize_trampoline.
- (TRAMPOLINE_ADJUST_ADDRESS): Not needed for SHcompact.
- * sh.md (initialize_trampoline, double_shori): New patterns.
- (initialize_trampoline_compact): Likewise.
- (shmedia32_initialize_trampoline_big): Remove.
- (shmedia32_initialize_trampoline_little): Likewise.
-
- * sh-protos.h (binary_float_operator): Remove declaration.
- (sh_expand_unop_v2sf, sh_expand_binop_v2sf): Declare.
- * sh.c (print_operand, case 'N'): Check against CONST0_RTX.
- (unary_float_operator, sh_expand_unop_v2sf): New functions.
- (sh_expand_binop_v2sf): Likewise.
- (zero_vec_operand): Delete.
- (SH_BLTIN_UDI): New builtin shared signature define. Renumbered
- all non-shared ones.
- (bdesc): Change all the mextr builtins to use SH_BLTIN_UDI.
- Enable nsb and byterev.
- * sh.h (CONDITIONAL_REGISTER_USAGE): Initialize DF_HI_REGS.
- (HARD_REGNO_MODE_OK): Allow TImode in fp regs. Allow V2SFmode
- in general regs.
- (enum reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add DF_HI_REGS.
- (SECONDARY_OUTPUT_RELOAD_CLASS): Likewise. Remove clause for
- immediate operands.
- (SECONDARY_INPUT_RELOAD_CLASS): Add clause for immediate operands.
- Add DF_HI_REGS.
- (CLASS_CANNOT_CHANGE_MODE, CLASS_CANNOT_CHANGE_MODE_P): Allow
- lowpart fp regs - only for big endian for now.
- (LEGITIMATE_CONSTANT_P): Don't allow nonzero float vectors
- when FPU is in use.
- (EXTRA_CONTRAINT_U): Check against CONST0_RTX.
- (LOAD_EXTEND_OP): NIL for SImode.
- (REGISTER_MOVE_COST): Add DF_HI_REGS. Const for moves between
- general and fp registers is 4.
- PREDICATE_CODES: Amend binary_float_operator entry.
- Remove zero_vec_operand. Add unary_float_operator.
- * sh.md (udivsi3_i4_media): Use truncate instead of paradoxical
- subreg SET_DEST.
- (truncdisi2, truncdihi2, movv2sf): Allow memory destinations.
- (truncdiqi2): Do sign extension.
- (movsi_media, movdi_media): Allow to use r63 to an fp register.
- (movdf_media, movsf_media): Likewise.
- (movv2sf_i, movv2sf_i+1): Don't use f{ld,st}.p or SUBREGS.
- Collapse to one define_insn_and_split. Allow immediate sources.
- (addv2sf3, subv2sf3, mulv2sf3, divv2sf3): New patterns.
- (movv4sf_i): Allow immediate sources. Use simplify_gen_subreg.
- (movv4sf): Allow immediate sources.
- (movsf_media_nofpu+1): Don't split moves to FP registers.
- (unary_sf_op, binary_sf_op, mshflo_w_x, concat_v2sf): New patterns.
- (movv8qi_i+3): Check against CONST0_RTX.
- (mextr1, mextr2. mextr3. mextr4, mextr5, mextr6, mextr7): Use DImode
- for input and output operands. Fix argument 3 to gen_mextr_rl.
- (mmul23_wl, mmul01_wl, mmulsum_wq_i): s/const_vector/parallel/
- (msad_ubq_i, mshf4_b, mshf0_b, mshf4_l, mshf0_l, mshf4_w): Likewise.
- (mshf0_w, fipr, ftrv): Likewise.
- (mshfhi_l_di): Now insn_and_split. Can handle FP regs.
-
-2002-07-17 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
-
- * arm.h (ARM_NUM_INTS, ARM_NUM_REGS, ARM_NUM_REGS2): Renamed from
- NUM_INTS, NUM_REGS and ARM_NUM_REGS2 respectively. All uses changed.
- * arm.c: Similarly.
-
-2002-07-17 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips-protos.h (mips_sign_extend): Declare.
- * config/mips/mips.h (MASK_DEBUG_H, TARGET_DEBUG_H_MODE): Remove.
- (TARGET_SWITCHES): Remove debugh.
- (ISA_HAS_TRUNC_W): New macro.
- (CLASS_CANNOT_CHANGE_MODE): Include FP_REGS if TARGET_FLOAT64.
- (PREDICATE_CODES): Remove se_nonimmediate_operand.
- * config/mips/mips.c (movdi_operand): Allow sign-extensions of
- any SImode move_operand.
- (se_nonimmediate_operand): Remove.
- (mips_sign_extend): New.
- (mips_move_2words): Use it for sign-extended source operands.
- (override_options): Allow integers to be put into single FPRs.
- (mips_secondary_reload_class): Handle integers in float registers.
- * config/mips/mips.md (extendsidi2): Turn into a define_expand.
- (fix_truncsfsi2, fix_truncdfsi2): Likewise.
- (fix_truncdfsi2_insn, fix_truncdfsi2_macro): New.
- (fix_truncsfsi2_insn, fix_truncsfsi2_macro): New.
- (fix_truncdfdi2): Provide only a single alternative, in which the
- integer is in a float register. Depend on TARGET_FLOAT64 rather
- than TARGET_64BIT.
- (fix_truncsfdi2, floatdidf2, floatdisf2): Likewise.
- (floatsidf2, floatsisf2): Likewise, but no TARGET_FLOAT64 dependency.
- (movdi_internal2): Don't allow the source operand to be sign-extended.
- Add alternatives for float registers.
- (*movdi_internal2_extend): New. Version of movdi_internal2 that
- allows sign-extension.
- (*movdi_internal2_mips16): Name the existing mips16 movdi pattern.
- (movsi_internal2): Rename to movsi_internal. Add alternatives for
- float registers. Remove TARGET_DEBUG_H_MODE test.
- (movhi_internal1): Rename to movhi_internal. Don't check
- TARGET_DEBUG_H_MODE. Fix transposed *d and *f source constraints.
- (movqi_internal1): Rename to movqi_internal and remove
- TARGET_DEBUG_H_MODE dependency.
- (movsi_internal1, movhi_internal2, movqi_internal2): Remove.
-
-2002-07-16 Jim Wilson <wilson@redhat.com>
-
- * toplev.c (lang_dependent_init): Create function context for
- init_expr_once.
-
-2002-07-16 Hans-Peter Nilsson <hp@axis.com>
-
- * config/cris/linux.h (CRIS_LINK_SUBTARGET_SPEC): Don't
- --gc-sections if -r.
- * config/cris/cris.h: Ditto.
-
-2002-07-16 Rodney Brown <rbrown64@csc.com.au>
-
- * config/i386/i386.c (ix86_expand_int_movcc): In the case where
- the comparison directly gives a mask suppress addition when cf is
- zero by complementing the mask.
-
-2002-07-16 Nathanael Nerode <neroden@gcc.gnu.org>
-
- * Makefile.in: Delete references to enquire.
- * enquire.c: Move to contrib.
-
-2002-07-16 Stan Shebs <shebs@apple.com>
-
- * config/darwin.h (ASM_OUTPUT_LABEL): Move to here from
- config/rs6000/darwin.h.
- (ASM_OUTPUT_SKIP): Ditto.
- (TEXT_SECTION_ASM_OP): Ditto.
- (DATA_SECTION_ASM_OP): Ditto.
- (ASM_APP_ON): Define.
- (ASM_APP_OFF): Define.
- * config/rs6000/darwin.h (ASM_OUTPUT_LABEL, ASM_OUTPUT_SKIP,
- TEXT_SECTION_ASM_OP, DATA_SECTION_ASM_OP): Remove.
-
- * config/darwin.c (func_name_maybe_scoped): Remove unused decl.
- (machopic_function_base_name): Declare result to be const.
- (machopic_non_lazy_ptr_name): Ditto.
- (machopic_stub_name): Ditto.
- * config/darwin-protos.h: Ditto for the prototypes.
-
-2002-07-17 Jan Hubicka <jh@suse.cz>
-
- * m68hc11.c (m68hc11_reorg): Do not rebuild CFG.
-
-2002-07-17 Jan Hubicka <jh@suse.cz>
-
- * i386.md (prefetch): Fix for 64bit mode.
- (prefetch_sse_rex, prefetch_3dnow_rex): New patterns.
-
-2002-07-17 Jan Hubicka <jh@suse.cz>
-
- * i386.h (MACHINE_DEPENDENT_REORG): New macro.
- * i386.c (x86_machine_dependent_reorg): New function.
- * i386-protos.h (x86_machine_dependent_reorg): Declare.
-
-2002-07-16 Zack Weinberg <zack@codesourcery.com>
-
- * builtins.c (std_expand_builtin_va_start): Remove unused
- first argument.
- (expand_builtin_va_start): Call EXPAND_BUILTIN_VA_START and
- std_expand_builtin_va_start with just two arguments.
- * expr.h: Update prototypes.
-
- * alpha-protos.h, alpha.h, alpha.c, arc-protos.h, arc.h,
- arc.c, d30v-protos.h, d30v.h, d30v.c, i386-protos.h, i386.h,
- i386.c, i960-protos.h, i960.h, i960.c, m88k-protos.h, m88k.h,
- m88k.c, mips-protos.h, mips.h, mips.c, mn10300-protos.h,
- mn10300.h, mn10300.c, pa-protos.h, pa.h, pa.c,
- rs6000-protos.h, rs6000.h, rs6000.c, s390-protos.h, s390.h,
- s390.c, sh-protos.h, sh.h, sh.c, sparc-protos.h, sparc.h,
- sparc.c, stormy16-protos.h, stormy16.h, stormy16.c,
- xtensa-protos.h, xtensa.h, xtensa.c: Remove unused first
- argument from all implementations of EXPAND_BUILTIN_VA_START
- and all uses of std_expand_builtin_va_start.
-
-2002-07-16 J"orn Rennecke <joern.rennecke@superh.com>
-
- * regrename.c (copy_value): Don't record high part copies.
-
-2002-07-16 Steve Ellcey <sje@cup.hp.com>
-
- * gcc/config/pa/long_double.h (FIXUNS_TRUNCTFDI2_LIBCALL): New define.
- (fixunstfdi_libfunc): Change to use FIXUNS_TRUNCTFDI2_LIBCALL.
- * gcc/config/pa/quadlib.c (_U_Qfcnvfxt_quad_to_udbl): New function.
-
-2002-07-16 Ian Dall <ian@sibyl.beware.dropbear.id.au>
-
- * doc/invoke.texi (NS32K Options): Document -mieee-compare option
-
- * config/ns32k/ns32k.md (addsi3, *frame_addr, *stack_addr): merge
- into addsi3 using register class "x" and "y".
-
- * config/ns32k/ns32k.md (*madddf, *maddsf, *msubdf, *msubsf):
- "earlyclobber" constraint modifier for some alternative.
-
- * config/ns32k/ns32k.md (tstdf, tstsf, cmpdf, cmpsf, blt, ble)
- (*ble, *blt): Flag to indicate bCOND and sCOND should check for
- unordered.
- config/ns32k/ns32k.h (CC_UNORD): define corresponding mask.
-
- * config/ns32k/ns32k.h (TARGET_IEEE_COMPARE, MASK_IEEE_COMPARE)
- (TARGET_SWITCHES): Add -mieee-compare option.
- (OVERRIDE_OPTIONS): 32332 is a subset of
- 32532. Don't use IEEE_COMPARE -funsafe-math-optimizations.
- (TARGET_SWITCHES): Fix description of bit-field option.
- * config/ns32k/netbsd.h (TARGET_DEFAULT): Add
- -mieee-compare option. Remove 32332 flag.
-
-2002-07-16 Steve Ellcey <sje@cup.hp.com>
-
- * explow.c (convert_memory_address): Remove special handling
- when POINTERS_EXTEND_UNSIGNED < 0.
- * config/ia64.md (movsi_symbolic): New instruction for ILP32 mode.
- (movedi_symbolic): Fix typo.
- (load_fptr): Remove mode restriction so it works for SI and DI.
- (load_fptr_internal1): Ditto.
- (load_gprel): Ditto.
- (load_symptr_internal1): Ditto.
- (call_pic): Ditto.
- * config/ia64.c (call_operand): Modify mode check.
- (ia64_expand_load_address): Handle DI and SI addresses and symbols.
- (ia64_expand_move): Ditto.
- (ia64_assemble_integer): Handle SImode function pointers.
- (ia64_expand_fetch_and_op): Handle SImode mem addresses.
- (ia64_expand_op_and_fetch): Ditto.
- (ia64_expand_compare_and_swap): Ditto.
- (ia64_expand_lock_test_and_set): Ditto.
- (ia64_expand_lock_release): Ditto.
-
-2002-07-16 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
-
- * arm.c (emit_sfm): Don't set RTX_FRAME_RELATED_P on DWARF.
-
-2002-07-16 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
- Richard Earnshaw <rearnsha@arm.com>
-
- * arm.h (LEGITIMATE_PIC_OPERAND_P): Only test
- CONSTANT_POOL_ADDRESS_P if a SYMBOL_REF. Simplify logic.
-
-2002-07-16 Richard Earnshaw <rearnsha@arm.com>
-
- * arm.md (stack_tie): New insn. Use an idiom that the alias code
- understands to be a memory clobber.
- * arm.c (arm_expand_prologue): Use it.
-
-2002-07-16 Daniel Berlin <dberlin@dberlin.org>
-
- * ra-rewrite.c: #include reload.h, insn-config.h
- * ra-build.c: #include reload.h
- * Makefile.in: Update ra-rewrite.o, ra-build.o dependencies to
- depend on reload.h, insn-config.h.
-
-2002-07-16 J"orn Rennecke <joern.rennecke@superh.com>
-
- * expr.c (emit_move_insn_1): Handle arbitrary moves that are
- the same size as a word.
-
- * regrename.c (find_oldest_value_reg): Take WORDS_BIG_ENDIAN /
- BYTES_BIG_ENDIAN into account.
-
-2002-07-16 Jan Hubicka <jh@suse.cz>
-
- * i386.md (prefetch): Fix for 64bit mode.
- (prefetch_sse_rex, prefetch_3dnow_rex): New patterns.
-
- * i386.md (movss, movsd): Use xorps/xorpd for Athlon.
-
-2002-07-16 Marek Michalkiewicz <marekm@amelek.gda.pl>
-
- * hard-reg-set.h (TEST_HARD_REG_BIT): Return 1 if the bit is set.
-
-2002-07-15 Zack Weinberg <zack@codesourcery.com>
-
- * ginclude/varargs.h: Replace with stub which issues #error.
- * ginclude/stdarg.h: __builtin_stdarg_start is renamed
- __builtin_va_start.
-
- * builtins.def (BUILT_IN_VARARGS_START): Delete.
- (BUILT_IN_VA_START): New.
- * builtins.c (expand_builtin_va_start): Eliminate first
- argument and code to implement pre-ISO varargs.
- (std_expand_builtin_va_start): Ignore first argument; it is
- always 1.
- (expand_builtin): Handle BUILT_IN_VA_START and
- BUILT_IN_STDARG_START identically. Delete
- BUILT_IN_VARARGS_START case.
-
- * function.c (assign_parms): Delete hide_last_arg and all
- its uses.
- (mark_varargs): Delete function.
- * function.h (struct function): Delete 'varargs' bit.
- (current_function_varargs): Delete macro.
- * tree.h: Don't declare mark_varargs.
-
- * c-decl.c (c_function_varargs, c_mark_varargs): Delete.
- (c_expand_body): Don't call mark_varargs.
- * c-objc-common.c: Handle BUILT_IN_VA_START and
- BUILT_IN_STDARG_START identically. Delete
- BUILT_IN_VARARGS_START case.
- * c-tree.h: Don't declare c_mark_varargs.
- * c-parse.in: Remove grammar rules for '&...' (which has been
- commented out since before 2.7.2) and for '...' in K+R
- argument declarations.
-
- * builtins.c, function.c, integrate.c, sibcall.c,
- config/alpha/unicosmk.h, config/arc/arc.c, config/arc/arc.h,
- config/avr/avr.c, config/cris/cris.c, config/fr30/fr30.c,
- config/i960/i960.c, config/i960/i960.md, config/m32r/m32r.c,
- config/m32r/m32r.h, config/m88k/m88k.c, config/m88k/m88k.h,
- config/mips/mips.c, config/mmix/mmix.c, config/mmix/mmix.h,
- config/mn10300/mn10300.c, config/pa/som.h, config/s390/s390.c,
- config/sh/sh.c, config/sh/sh.h, config/sparc/sparc.h,
- config/stormy16/stormy16.c: Delete all references to
- current_function_varargs, and code predicated on that flag.
-
- * config/alpha/alpha.c (alpha_va_start),
- config/arc/arc.c (arc_va_start),
- config/i386/i386.c (ix86_va_start),
- config/mips/mips.c (mips_va_start),
- config/mn10300/mn10300.c (mn10300_va_start),
- config/rs6000/rs6000.c (rs6000_va_start),
- config/s390/s390.c (s390_va_start),
- config/sh/sh.c (sh_va_start),
- Ignore first argument; it is always 1.
-
- * config/c4x/c4x-protos.h, config/c4x/c4x.c: Delete c4x_va_start.
- * config/ia64/ia64-protos.h, config/ia64/ia64.c: Delete ia64_va_start.
- * config/m68hc11/m68hc11-protos.h, config/m68hc11/m68hc11.c:
- Delete m68hc11_va_start.
- * config/c4x/c4x.h, config/ia64/ia64.h, config/m68hc11/m68hc11.h:
- No need to define EXPAND_BUILTIN_VA_START.
-
- * doc/invoke.texi, doc/sourcebuild.texi, doc/tm.texi,
- doc/trouble.texi: Remove references to GCC-provided <varargs.h>.
-
-2002-07-15 Eric Botcazou <ebotcazou@multimania.com>
-
- PR optimization/7153
- * regmove.c (optimize_reg_copy_3): Don't optimize if the register
- dies in more than one insn.
-
-2002-07-15 Jason Thorpe <thorpej@wasabisystems.com>
-
- * config/sparc/netbsd-elf.h (TRANSFER_FROM_TRAMPOLINE): Remove.
-
-2002-07-15 Michael Matz <matz@suse.de>,
- Daniel Berlin <dberlin@dberlin.org>,
- Denis Chertykov <denisc@overta.ru>
-
- Add a new register allocator.
-
- * ra.c: New file.
- * ra.h: New file.
- * ra-build.c: New file.
- * ra-colorize.c: New file.
- * ra-debug.c: New file.
- * ra-rewrite.c: New file.
-
- * Makefile.in (ra.o, ra-build.o, ra-colorize.o, ra-debug.o,
- (ra-rewrite.o): New .o files for libbackend.a.
- (GTFILES): Add basic-block.h.
-
- * toplev.c (flag_new_regalloc): New.
- (f_options): New option "new-ra".
- (rest_of_compilation): Call initialize_uninitialized_subregs()
- only for the old allocator. If flag_new_regalloc is set, call
- new allocator, instead of local_alloc(), global_alloc() and
- friends.
-
- * doc/invoke.texi: Document -fnew-ra.
- * basic-block.h (FOR_ALL_BB): New.
- * config/rs6000/rs6000.c (print_operand): Write small constants
- as @l+80.
-
- * df.c (read_modify_subreg_p): Narrow down cases for a rmw subreg.
- (df_reg_table_realloc): Make size at least as large as max_reg_num().
- (df_insn_table_realloc): Size argument now is absolute, not relative.
- Changed all callers.
-
- * gengtype.c (main): Add the pseudo-type "HARD_REG_SET".
- * regclass.c (reg_scan_mark_refs): Ignore NULL rtx's.
-
- 2002-06-20 Michael Matz <matz@suse.de>
-
- * df.h (struct ref.id): Make unsigned.
- * df.c (df_bb_reg_def_chain_create): Remove unsigned cast.
-
- 2002-06-13 Michael Matz <matz@suse.de>
-
- * df.h (DF_REF_MODE_CHANGE): New flag.
- * df.c (df_def_record_1, df_uses_record): Set this flag for refs
- involving subregs with invalid mode changes, when
- CLASS_CANNOT_CHANGE_MODE is defined.
-
- 2002-05-07 Michael Matz <matz@suse.de>
-
- * reload1.c (fixup_abnormal_edges): Don't insert on NULL edge.
-
- 2002-05-03 Michael Matz <matz@suse.de>
-
- * sbitmap.c (sbitmap_difference): Accept sbitmaps of different size.
-
- Sat Feb 2 18:58:07 2002 Denis Chertykov <denisc@overta.ru>
-
- * regclass.c (regclass): Work with all regs which have sets or
- refs.
- (reg_scan_mark_refs): Count regs inside (clobber ...).
-
- 2002-01-04 Michael Matz <matzmich@cs.tu-berlin.de>
-
- * df.c (df_ref_record): Correctly calculate SUBREGs of hardregs.
- (df_bb_reg_def_chain_create, df_bb_reg_use_chain_create): Only
- add new refs.
- (df_bb_refs_update): Don't clear insns_modified here, ...
- (df_analyse): ... but here.
-
- * sbitmap.c (dump_sbitmap_file): New.
- (debug_sbitmap): Use it.
-
- * sbitmap.h (dump_sbitmap_file): Add prototype.
-
- 2001-08-07 Daniel Berlin <dan@cgsoftware.com>
-
- * df.c (df_insn_modify): Grow the UID table if necessary, rather
- than assume all emits go through df_insns_modify.
-
- 2001-07-26 Daniel Berlin <dan@cgsoftware.com>
-
- * regclass.c (reg_scan_mark_refs): When we increase REG_N_SETS,
- increase REG_N_REFS (like flow does), so that regclass doesn't
- think a reg is useless, and thus, not calculate a class, when it
- really should have.
-
- 2001-01-28 Daniel Berlin <dberlin@redhat.com>
-
- * sbitmap.h (EXECUTE_IF_SET_IN_SBITMAP_REV): New macro, needed for
- dataflow analysis.
-
-2002-07-15 Jakub Jelinek <jakub@redhat.com>
-
- PR middle-end/7245
- * config/i386/i386.c (const_int_1_31_operand): New.
- * config/i386/i386.h (PREDICATE_CODES): Add it.
- * config/i386/i386.md (ashlsi3_cmp, ashlsi3_cmp_zext, ashlhi3_cmp,
- ashlqi3_cmp, ashrsi3_cmp, ashrsi3_cmp_zext, ashrhi3_cmp, ashrqi3_cmp,
- lshrsi3_cmp, lshrsi3_cmp_zext, lshrhi3_cmp, lshrqi3_cmp): Use it.
-
-2002-07-14 Alan Modra <amodra@bigpond.net.au>
-
- PR target/7282
- * config/rs6000/rs6000.md (floatsidf2): Enable for POWERPC64.
- (floatunssidf2): Likewise.
- (floatsidf_ppc64): New insn_and_split.
- (floatunssidf_ppc64): Likewise.
-
-2002-07-14 Andreas Jaeger <aj@suse.de>
-
- * config.gcc (sh64): Remove unused
- target_requires_64bit_host_wide_int.
-
-2002-07-12 Roger Sayle <roger@eyesopen.com>
-
- * expr.c [CLEAR_RATIO]: New macro defining the maximum number
- of move instructions to use when clearing memory, c.f. MOVE_RATIO.
- [CLEAR_BY_PIECES]: New macro, using CLEAR_RATIO, to determine
- whether clear_by_pieces should be used to clear storage.
- (clear_storage): Use CLEAR_BY_PIECES instead of MOVE_BY_PIECES.
-
- * doc/tm.texi: Document these two new target macros.
-
-2002-07-12 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.md ("zero_extendsidi2"): Use D_REG only for
- the scratch register.
- ("*movhi2_push"): Accept Z_REG because a split pattern can make use
- of it, forbid reload to use it.
-
-2002-07-12 Marek Michalkiewicz <marekm@amelek.gda.pl>
-
- * config/avr/avr.c (test_hard_reg_class): Fix TEST_HARD_REG_BIT
- usage on 64-bit hosts, return value was truncated to 32 bits.
-
-2002-07-12 J"orn Rennecke <joern.rennecke@superh.com>
-
- * simplify-rtx.c (simplify_subreg): Handle floating point
- CONST_DOUBLEs. When an integer subreg of a smaller mode than
- the element mode is requested, compute a subreg with an
- integer mode of the same size as the element mode first.
-
-2002-07-11 J"orn Rennecke <joern.rennecke@superh.com>
-
- * combine.c (try_combine): When converting a paradoxical subreg
- to an extension, take LOAD_EXTEND_OP into account.
-
-2002-07-11 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
-
- * config.gcc (mips-sgi-irix6*o32): New configuration.
-
- * configure.in (libgcc_visibility): Disable for mips-sgi-irix6*o32
- configurations.
+ * configure.ac: Replace AC_INIT, AC_OUTPUT, AC_CANONICAL_SYSTEM
+ with modern equivalents.
* configure: Regenerate.
- * config/mips/iris6-o32-as.h: New file.
- * config/mips/iris6-o32.h: New file.
-
- * config/mips/iris5gas.h (TARGET_ASM_NAMED_SECTION): Define.
- (NM_FLAGS): Define.
- (HAVE_AS_SHF_MERGE): Undefine.
-
- * config/mips/t-iris5-as: New file.
- * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix5*): Use it.
-
- * config/mips/t-iris6 (SHLIB_EXT, SHLIB_SOLINK, SHLIB_SONAME,
- SHLIB_NAME, SHLIB_MAP, SHLIB_OBJS, SHLIB_SLIBDIR_QUAL, SHLIB_LINK,
- SHLIB_INSTALL, SHLIB_MKMAP, SHLIB_MAPFILES, FPBIT, DPBIT,
- dp-bit.c, fp-bit.c): Move ...
- * config/mips/t-iris5-6: ... here.
- New file, shared by IRIX 5 and IRIX 6.
- * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix6*,
- mips-sgi-irix5*): Use it.
-
- * config/mips/iris6.h: Remove duplicate comment.
-
- * config/mips/mips.c (TARGET_ASM_UNALIGNED_DI_OP) [TARGET_IRIX5 &&
- !TARGET_IRIX6]: Define.
- (mips_asm_file_start): Don't emit mdebug.<ABI> sections on IRIX 5/6.
-
- * config/mips/mips.h (ASM_DECLARE_FUNCTION_NAME): Fix comment.
-
-2002-07-11 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa.md (adddi3): Change predicate of operand 2 to adddi3_operand
- and delete code to force constant to register.
- * pa-protos.h (adddi3_operand): Add prototype.
- * pa.c (adddi3_operand): New function.
-
-2002-07-11 Roger Sayle <roger@eyesopen.com>
-
- * c-decl.c (duplicate_decls): Preserve the noreturn attribute on
- non-ANSI builtin functions.
-
-2002-07-11 J"orn Rennecke <joern.rennecke@superh.com>
-
- * rtl.h (gen_rtx_CONST_VECTOR): Declare.
- * gengenrtl.c (special_rtx): Check for CONST_VECTOR.
- * emit-rtl.c (gen_rtx_CONST_VECTOR): New function.
- (gen_const_vector_0): Use it.
-
-2002-07-11 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * pa.md (adddi3): For 32-bit targets, force constants to a register
- if they don't fit in an 11-bit immediate. Change insn predicate to
- arith11_operand. Remove comment.
- * pa.c (cint_ok_for_move): Fix comment.
- (emit_move_sequence): Don't directly split DImode constants on 32-bit
- targets.
-
-2002-07-11 Tim Josling <tej@melbpc.org.au>
-
- Remove front end hard coding from gengtype.c.
-
- * Makefile.in
- (STAGESTUFF): add gtyp-gen.h
- (GTFILES): Remove front end specific files.
- (GTFILES_FILES_LANGS): New, from configure..
- (GTFILES_FILES_FILES): Likewise.
- (GTFILES_LANG_DIR_NAMES): Likewise.
- (GTFILES_SRCDIR): Likewise.
- (gtyp-gen.h): Build from configure information.
- (s-gtype): Remove command line parameters from gengtype.
- (gengtype.o): Remove dependency on GTFILES. Depend on gtyp-gen.h.
- (mostlyclean): Delete files generated by and for gengtype.
-
- * c-config-lang.in: New file.
-
- * configure.in (all_gtfiles_files_langs): New. Accumulate files
- for each language.
- (all_gtfiles_files_files): New. Accumulate language for each file
- accumulated.
- (gtfiles): Pick up value for C.
- (srcdir): AC-SUBST this variable.
- (all_gtfiles_files_langs): AC-SUBST this variable.
- (all_gtfiles_files_files): AC-SUBST this variable.
-
+ * configure.ac: Replace gcc_AC_CHECK_TYPE with AC_CHECK_TYPE.
+ * aclocal.m4 (gcc_AC_CHECK_TYPE): Remove.
* configure: Regenerate.
- * gengtype-lex.l (parse_file): Make parameter const.
-
- * gengtype.c (toplevel): include gtyp-gen.h.
- (BASE_FILE_<language> unnamed enum): Delete.
- (lang_names): Delete (replaced by gtyp-gen.h)
- (lang_dir_names): From gtyp-gen.h, replaces lang_names; changed
- all references.
- (NUM_GT_FILES): New.
- (NUM_LANG_FILES): New.
- (srcdir_len): New.
- (NUM_BASE_FILES): Change calculation.
- (open_base_files): Change prototype to avoid warning.
- (startswith): Delete.
- (get_file_basename): Iterate through generated language list not
- hard coded list.
- (get_base_file_bitmap): Use generated list of files and languages.
- (close_output_files): Add prototype to rmove warning.
- (main): Iterate through list of generated files from gtyp-gen.h
- rather than command line paramaters. Ignore duplicated file
- names.
-
- * gengtype.h (parse_file): Amend prototype for const parameter.
-
- * doc/sourcebuild.texi: Document gtfiles variable.
-
- * doc/gty.texi: Document changes to gtfiles variable for front
- ends.
-
- * objc/config-lang.in (gtfiles): Add files needed for objc front
- end.
-
-2002-07-10 Roger Sayle <roger@eyesopen.com>
+ * doc/install.texi: Note that 'gcc' is now a 2.57 directory.
- PR c/2454
- * combine.c (nonzero_bits): LOAD_EXTEND_OP should only apply
- to SUBREGs of MEMs. (num_sign_bit_copies): Likewise.
+ * configure.in: Rename to configure.ac.
+ * configure.ac: Renamed from configure.in; make minimum necessary
+ changes for autoconf 2.5x.
+ * aclocal.m4: Make minimum necessary changes for autoconf 2.5x.
+ * configure: Regenerate with autoconf 2.57.
-2002-07-10 Roger Sayle <roger@eyesopen.com>
- Zack Weinberg <zack@codesourcery.com>
+2004-01-03 Kazu Hirata <kazu@cs.umass.edu>
- * builtins.def: Make the argument types of abort and exit
- independent of the front-end.
-
-2002-07-11 Alan Modra <amodra@bigpond.net.au>
-
- * config/rs6000/linux64.h (ASM_SPEC): Define.
-
-2002-07-10 Aldy Hernandez <aldyh@redhat.com>
-
- * config/rs6000/rs6000.c (emit_frame_save): New.
- (rs6000_frame_related): Replace reg2 before reg.
- (rs6000_emit_prologue): Use emit_frame_save for saving gprs, fprs,
- and eh_return registers.
-
-2002-07-10 Toon Moene <toon@moene.indiv.nluug.nl>
-
- Revert all patches for optimization of Complex .op. Real.
- * complex_part_zero_p: Remove
- * expand_cmplxdiv_straight: Replace complex_part_zero_p(x)
- with x.
- * expand_cmplxdiv_wide: Ditto.
- * expand_binop: Ditto.
-
-2002-07-10 Marek Michalkiewicz <marekm@amelek.gda.pl>
-
- * config/avr/avr.md: Fix two 0x80000000 constants to make them
- negative also on 64-bit hosts.
-
- Default to -fno-reorder-blocks when optimizing for size.
- * config/avr/avr-protos.h (avr_optimization_options): Declare.
- * config/avr/avr.c (avr_optimization_options): New function.
- * config/avr/avr.h (OPTIMIZATION_OPTIONS): New.
-
- Optimize returning from simple functions.
- * config/avr/avr-protos.h (avr_simple_epilogue): Declare.
- * config/avr/avr.c (avr_simple_epilogue): New function.
- * config/avr/avr.md (return): New insn.
-
-2002-07-10 Douglas B Rupp <rupp@gnat.com>
-
- * config/i386/i386.c (ix86_svr3_asm_out_constructor): Add
- HAS_INIT_SECTION to protection.
-
-2002-07-10 Mark Mitchell <mark@codesourcery.com>
-
- * doc/invoke.texi (Debugging Options): Mention that -gdwarf is
- deprecated.
-
-2002-07-10 J"orn Rennecke <joern.rennecke@superh.com>
-
- * combine.c (gen_lowpart_for_combine): Handle vector modes.
- Supply non-VOID mode to simplify_gen_subreg.
-
-2002-07-10 Jan Hubicka <jh@suse.cz>
-
- * i386.c (ix86_init_mmx_sse_builtins): Fix thinko.
-
-2002-07-10 Jeffrey A Law <law@redhat.com>
-
- * mn10200.c (expand_prologue): Create REG_MAYBE_DEAD notes
- as appropriate.
-
- * mn10200.c (expand_epilogue): Fix test to determine which scratch
- register to use.
-
-2002-07-10 J"orn Rennecke <joern.rennecke@superh.com>
-
- * cse.c (cse_insn): Supply proper SUBREG_BYTE to simplify_gen_subreg.
- Get mode from dest.
- If simplify_gen_subreg fails, try next equivalent.
-
-2002-07-09 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * diagnostic.h: #include location.h
- (location_t): Move definition to..
- * location.h: ... here. New file.
- * tree.h: #include location.h
- (DECL_SOURCE_LOCATION): New macro.
- (DECL_SOURCE_FILE): Use.
- (DECL_SOURCE_LINE): Likewise.
- (struct tree_decl): REplace filename and linenum with locus.
- * Makefile.in (TREE_H): add location.h
- (diagnostic.o): Depends on gt-location.h
- (gt-location.h): Depends on s-gtype
-
-2002-07-09 Matt Kraai <kraai@alumni.cmu.edu>
-
- * config/rs6000/aix.h: Convert CPP_PREDEFINES to
- TARGET_OS_CPP_BUILTINS.
- * config/rs6000/aix31.h: Likewise.
- * config/rs6000/aix41.h: Likewise.
- * config/rs6000/aix43.h: Likewise.
- * config/rs6000/aix51.h: Likewise.
- * config/rs6000/beos.h: Likewise.
- * config/rs6000/darwin.h: Likewise.
- * config/rs6000/eabi.h: Likewise.
- * config/rs6000/eabisim.h: Likewise.
- * config/rs6000/linux.h: Likewise.
- * config/rs6000/linux64.h: Likewise.
- * config/rs6000/lynx.h: Likewise.
- * config/rs6000/mach.h: Likewise.
- * config/rs6000/rtems.h: Likewise.
- * config/rs6000/sysv4.h: Likewise.
- * config/rs6000/vxppc.h: Likewise.
-
-2002-07-09 Devang Patel <dpatel@apple.com>
- * objc/objc-act.c (adjust_type_for_id_default): Fix my previous patch.
- Do not allow ObjC objects as a parameter type for Objective-C methods.
- My previous patch restricted 'struct' also.
-
-2002-07-09 Neil Booth <neil@daikokuya.co.uk>
-
- * cpperror.c (cpp_error): Default to directive_line within
- directives here.
- * cppexp.c (cpp_interpret_integer): Only use traditional
- number semantics in directives.
- * cpplib.c (prepare_directive_trad): Don't reset pfile->line.
- (do_include_common): Similarly.
- * cpptrad.c (scan_out_logical_line): Implement accurate
- quoting of <> in #include.
- * doc/cpp.texi: Update.
-
-2002-07-09 Stephen Clarke <stephen.clarke@superh.com>
- J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.c (sh_adjust_cost): Special handling of SHMEDIA code.
- * sh.md (attribute issues): Replace with:
- (attribute pipe_model). All users changed.
- (attribute type): Change pt / ptabs to pt_media / ptabs_media.
- All users changed.
- (function units sh5issue, sh5fds): New.
- (attribute is_mac_media): New.
- (adddi3_media, subdi3_media, divsi3_i1_media, anddi3): Add type.
- (andcdi3, iordi3, xordi3, ashldi3_media, lshrdi3_media): Likewise.
- (ashrdi3_media, negdi_media, extendsidi2, movqi_media): Likewise.
- (movhi_media, shori_media, movv2sf_i, jump_media): Likewise.
- (call_media, call_value_media, sibcall_media): Likewise.
- (casesi_jump_media, casesi_shift_media, casesi_load_media): Likewise.
- (return_media_i, addsf3_media, subsf3_media, mulsf3_media): Likewise.
- (mac_media, divsf3_media, floatdisf2, floatsisf2_media): Likewise.
- (fix_truncsfdi2, fix_truncsfsi2_media, cmpeqsf_media): Likewise.
- (cmpgtsf_media, cmpgesf_media, cmpunsf_media, negsf2_media): Likewise.
- (sqrtsf2_media, abssf2_media, adddf3_media, subdf3_media): Likewise.
- (muldf3_media, divdf3_media, floatdidf2, floatsidf2_media): Likewise.
- (fix_truncdfdi2, fix_truncdfsi2_media, cmpeqdf_media): Likewise.
- (cmpgtdf_media, cmpgedf_media,cmpundf_media, negdf2_media): Likewise.
- (sqrtdf2_media, absdf2_media, extendsfdf2_media): Likewise.
- (truncdfsf2_media): Likewise.
- (movsi_media, movsi_media_nofpu, movdi_media): Use new types.
- (movdi_media_nofpui, movdf_media, movdf_media_nofpu): Likewise.
-
-2002-07-09 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.h (PREDICATE_CODES): Add general_extend_operand and inqhi_operand.
- * sh.c (general_extend_operand, inqhi_operand): New functions.
- * sh.md (cmpeqdi_media, cmpgtdi_media, cmpgtudi_media): Collapse
- alternatives using 'N' modifier. Add type.
- (adddi3z_media): Likewise. Enable generator function generation.
- (movdicc_false, movdicc_true, addsi3_media, subsi3_media): Use more
- exact predicates / constraints. Add type.
- (subsi3): Allow 0 for SHMEDIA.
- (udivsi3_i4_media): Use match_operand for input values
- rather than hard registers.
- (udivsi3 - TARGET_SHMEDIA_FPU case): Don't ferry values
- unnecessarily through hard registers. Keep copies of pseudo
- registers outside of the libcall sequence.
- (mulsidi3_media, umulsidi3_media): Use more exact predicates. Add type.
- (ashlsi3_media, ashrsi3_media, lshrsi3_media): Likewise.
- (zero_extendsidi2, zero_extendhidi2, zero_extendqidi2): Likewise.
- (extendhidi2, extendqidi2): Likewise.
- (andsi3_compact): Name.
- (andcdi3): Enable generator function generation.
- (zero_extendhisi2, zero_extendqisi2): Rename to
- (zero_extendhisi2_compact, zero_extendqisi2_compact).
- (extendhisi2, extendqisi2): Rename to
- (extendhisi2_compact, extendqisi2_compact).
- (rotldi3, rotldi3_mextr, rotrdi3, rotrdi3_mextr): New patterns.
- (loaddi_trunc, zero_extendhisi2, zero_extendhisi2_media): Likewise.
- (zero_extendhisi2_media+1, zero_extendqisi2): Likewise.
- (zero_extendqisi2_media, extendhisi2, extendhisi2_media): Likewise.
- (extendhisi2_media, extendhisi2_media+1, extendqisi2): Likewise.
- (extendqisi2_media, extendqisi2_media+1, truncdisi2): Likewise.
- (truncdihi2, truncdiqi2, reload_inqi, reload_inhi): Likewise.
- (shmedia32_initialize_trampoline_big): Likewise.
- (shmedia32_initialize_trampoline_little): Likewise.
- (nsb, nsbsi, nsbdi, ffsdi2, ffssi2, byterev): Likewise.
- (negdi2): Remove spurious T clobber.
- (zero_extendhidi2+1, extendhidi2+1, extendqidi2+1): Handle TRUNCATE.
- (movsi_media, movsi_media_nofpu): Remove spurious *k after b.
- (movdi_media, movdi_media_nofpu, pt, ptb): Likewise.
- (movsi_media_nofpu+2, movhi_media+1): Only do split after reload.
- (ic_invalidate_line_media): Write back data cache before invalidating
- instruction cache. Add type.
- (movsf_media): Sign-extend when the destination is a general
- purpose register. Add type.
- (bgt_media, bge_media, bgtu_media, bgeu_media, blt_media_i): Allow 0.
- (casesi_worker_0+1): Only increment ref count for proper label.
- (casesi_worker_0+2): Likewise.
-
-2002-07-09 Mark Mitchell <mark@codesourcery.com>
-
- * dwarfout.c (dwarfout_init): Warn that DWARF1 is deprecated.
-
-2002-07-09 Steve Ellcey <sje@cup.hp.com>
-
- * gcc/except.c (expand_eh_region_end_cleanup): Change exception pointer
- from Pmode to ptr_mode.
- (get_exception_pointer): Ditto.
- (connect_post_landing_pads): Ditto.
- (dw2_build_landing_pads): Ditto.
-
-2002-07-08 Steve Ellcey <sje@cup.hp.com>
- * gcc/c-pragma.h (add_to_renaming_pragma_list): New function.
- * gcc/c-pragma.c (add_to_renaming_pragma_list): New function.
- (handle_pragma_redefine_extname): Change to use new function.
-
-2002-07-08 Roger Sayle <roger@eyesopen.com>
-
- * combine.c (combine_simplify_rtx): Add an explicit cast
- to avoid signed/unsigned comparison warning.
- (simplify_if_then_else): Likewise.
- (extended_count): Likewise.
- (simplify_shift_const): Likewise.
- (simplify_comparison): Likewise.
-
-2002-07-08 Richard Sandiford <rsandifo@redhat.com>
-
- * config/mips/mips.md: Add imadd type. Update scheduler description
- to use imadd as well as imul.
- (*mul_acc_si, *madsi): Change imul alternatives to imadd.
- (*mul_acc_di, *mul_acc_64bit_di): Likewise.
- (*mul_sub_si): Likewise for first alternative. Change second
- alternative from imul to multi.
-
-2002-07-07 Neil Booth <neil@daikokuya.co.uk>
-
- * c-common.c (c_common_post_options): Update prototype;
- don't init backends if preprocessing only.
- * langhooks-def.h (LANG_HOOKS_POST_OPTIONS): Update.
- * langhooks.h (struct lang_hooks): Update post_options to
- return a boolean.
- * toplev.c (parse_options_and_default_flags, do_compile,
- lang_independent_init): Update prototypes. Allow the
- front end to specify that there is no need to initialize
- the back end.
- (general_init): Move call to hex_init here...
- (toplev_main): ...from here. Pass flag for back end init
- suppression.
-
-2002-07-07 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.h (PRINT_OPERAND_PUNCT_VALID_P): Allow '\''.
- (PREDICATE_CODES): Add entries for equality_comparison_operator,
- greater_comparison_operator and less_comparison_operator.
- * sh.c (print_operand): Add '\'' code. Make 'o' handle
- more operators.
- (equality_comparison_operator): New function.
- (greater_comparison_operator, less_comparison_operator): Likewise.
- * sh.md (beq_media_i): Disable generator function generation.
- Use match_operator to handle a whole class of comparisons. Add
- modifier in output template to provide branch prediction. Add type.
- (bgt_media_i, ble_media_i): Likewise. Allow zero operands.
- (bne_media_i, bge_media_i, bgtu_media_i, bgeu_media_i): Delete.
- (blt_media_i, bleu_media_i, bltu_media_i): Likewise.
- (bgt, blt, ble, bge, bgtu, bltu, bgeu, bleu): Allow zero operands.
-
-2002-07-07 Hans-Peter Nilsson <hp@bitrange.com>
-
- Emit MMIX function prologue and epilogue as rtl.
- * config/mmix/mmix.md ("call"): Use mmix_get_hard_reg_initial_val,
- not unprototyped get_hard_reg_initial_val.
- ("call_value", "nonlocal_goto_receiver"): Ditto.
- ("return"): Make define_expand. Move real insn to...
- ("*expanded_return"): New pattern.
- ("prologue", "epilogue"): New define_expands.
- * config/mmix/mmix.h (MMIX_rO_REGNUM): New macro.
- (struct machine_function): New member in_prologue.
- (FIRST_PSEUDO_REGISTER): Adjust for including rO as register.
- (FIXED_REGISTERS, CALL_USED_REGISTERS): Ditto.
- (MMIX_MMIXWARE_ABI_REG_ALLOC_ORDER): Ditto.
- (MMIX_GNU_ABI_REG_ALLOC_ORDER, REG_CLASS_CONTENTS): Ditto.
- (REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Ditto.
- (LOCAL_REGNO): Define. Adjust comment.
- * config/mmix/mmix.c (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS):
- Consider regs_ever_live[MMIX_rJ_REGNUM], not just
- leaf_function_p.
- (MMIX_OUTPUT_REGNO): Don't translate registers while outputting
- the prologue.
- (mmix_target_asm_function_prologue): Make static. Just mark that
- the prologue is being emitted. Move guts to...
- (mmix_expand_prologue): New function. Adjust for emitting
- prologue as rtl. For sizes, use HOST_WIDE_INT only.
- (mmix_target_asm_function_epilogue): Make static. Simply emit a
- \n. Move guts to...
- (mmix_expand_epilogue): New function. Adjust for emitting
- epilogue as rtl. For sizes, use HOST_WIDE_INT only.
- (mmix_target_asm_function_end_prologue): Mark that the prologue
- has ended.
- (TARGET_ASM_FUNCTION_END_PROLOGUE): Define.
- (mmix_conditional_register_usage): Improve comments.
- (mmix_local_regno): New function.
- (mmix_emit_sp_add, mmix_get_hard_reg_initial_val): Ditto.
- * config/mmix/mmix-protos.h (mmix_local_regno): Prototype.
- (mmix_expand_prologue, mmix_expand_epilogue): Ditto.
- (mmix_get_hard_reg_initial_val): Ditto.
-
-2002-07-06 Andreas Jaeger <aj@suse.de>
-
- * toplev.c (set_fast_math_flags): Don't use ISO C style function
- definitions.
- * gengtype.c (open_base_files): Likewise.
- (close_output_files): Likewise.
- * tracer.c (find_best_predecessor): Likewise.
- (find_best_successor): Likewise.
- (ignore_bb_p): Likewise.
-
-2002-07-05 Roger Sayle <roger@eyesopen.com>
-
- PR c++/7099
- * builtin-attrs.def: Define new attribute lists for use in
- builtins.def.
- * builtins.def [DEF_BUILTIN]: Modify to take an additional
- ATTRS argument, an enumerated value defined in builtin-attrs.def
- that represents the attribute list for the builtins. Modify
- all builtin functions to pass an appropriate attribute list.
- Specify "abort", "exit", "_exit" and "_Exit" builtins here with
- their required noreturn attributes.
- * tree.h (enum_builtin_function): Ignore the additional parameter
- to DEF_BUILTIN.
- * builtins.c (built_in_names): Likewise.
- * c-common.c: (builtin_function_2): Replace the "int noreturn_p"
- argument with a tree representing the functions attribute list.
- Pass this "attrs" argument to builtin_function. No longer handle
- the noreturn_p processing manually.
- (built_in_attributes): Move the definitions from builtin-attrs.def
- before c_common_nodes_and_builtins.
- (c_common_nodes_and_builtins): Handle the new ATTRS parameter in
- DEF_BUILTIN, passing it to both builtin_function and the changed
- builtin_function_2.
-
- * doc/extend.texi: Document __builtin_abort, __builtin_exit,
- __builtin__exit and __builtin__Exit.
-
-2002-07-05 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.md ("*movqi_68hc12"): Avoid allocating
- QI mode registers in soft registers.
- ("zero_extendqihi2"): Do not take into account soft registers
- for register allocation (use '*' constraint).
-
-2002-07-05 Stephane Carrez <stcarrez@nerim.fr>
-
- * config/m68hc11/m68hc11.md ("*ashlsi3"): Avoid saving y if we know
- it is dead.
- ("*ashrsi3"): Likewise.
- ("*lshrsi3"): Likewise.
+ * config/mips/linux.h: Fix comment formatting.
+ * config/mips/mips.c: Likewise.
+ * config/mips/mips.h: Likewise.
+ * config/mips/mips.md: Likewise.
+ * config/mips/netbsd.h: Likewise.
+ * config/mips/windiss.h: Likewise.
-2002-07-05 Vladimir Makarov <vmakarov@redhat.com>
+2004-01-02 Richard Henderson <rth@redhat.com>
- * genautomata.c (output_max_insn_queue_index_def): Take latencies
- into account.
+ * config/i386/i386.md (fp constant pool splitter): Reorg suppression
+ for sse and 387; add suppression for mmx.
-2002-07-05 Stephane Carrez <stcarrez@nerim.fr>
+2004-01-02 Andrew Pinski <pinskia@physics.uc.edu>
- * config/m68hc11/m68hc11.md (peephole2): New peephole2 to optimize
- address computation and memory moves.
+ * loop.c (loop_optimize): Free all loops_info's mems.
-2002-07-03 Mark Mitchell <mark@codesourcery.com>
+ * c-typeck.c (finish_init): Free spelling_base before
+ setting it again.
- PR c++/6706
- * dwarfout.c (output_reg_number): Fix warning message.
- (output_bound_representation): Check SAVE_EXPR_RTL is not NULL
- before using it.
+ * cfgloop.c (flow_loops_find): Always free the sbitmap
+ headers.
-2002-07-05 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+ * predict.c (estimate_probability): Free bbs after being
+ done with it.
- * gcc/gcc.c (asm_debug): Move initialization ...
- (init_spec): ... here.
+2004-01-02 Kazu Hirata <kazu@cs.umass.edu>
-2002-07-05 Nathan Sidwell <nathan@codesourcery.com>
+ * config/mn10300/mn10300.h (PREDICATE_CODES): Add
+ const_8bit_operand and call_address_operand.
- * c-parse.in (extdef): Append ';'.
- (old_style_parm_decls): Append ';'.
+2004-01-02 Jan Hubicka <jh@suse.cz>
-2002-07-04 Daniel Jacobowitz <drow@mvista.com>
+ * cgraphunit.c (cgraph_optimize_function): Call optimize_inline_calls
+ when there is nothing to inline but warnings are requested.
+ (cgraph_decide_inlining): Fix memory leak.
- * configure.in: Correct typos: gcc_cv_as_gdwarf2_debug_flag to
- gcc_cv_as_gdwarf2_flag and gcc_cv_as_gstabs_debug_flag
- to gcc_cv_as_gstabs_flag.
- * configure: Rebuilt.
+2004-01-02 Jan Hubicka <jh@suse.cz>
-2002-07-04 Geoffrey Keating <geoffk@redhat.com>
-
- * ggc.h (ggc_add_root): Document as obsolete.
-
-2002-07-04 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.md (mshfhi_b, mshflo_b, mshfhi_l, mshflo_l, mshfhi_w): Add DONE.
- (mshflo_w): Likewise.
-
-2002-07-04 J"orn Rennecke <joern.rennecke@superh.com>
-
- * simplify-rtx.c (simplify_subreg): Reduce problem of finding
- vector mode subregs of constants to finding integer mode
- subregs of constants.
- * cse.c (cse_insn): Use simplify_gen_subreg.
- * convert.c (convert_to_integer): Don't strip a NOP_EXPR
- From a vector mode expression of different size than the
- target mode.
-
-2002-07-03 Eric Christopher <echristo@redhat.com>
-
- * config/mips/linux.h: Add #undef for SUBTARGET_CPP_SPEC.
- * config/mips/mips.h: Remove deprecated -m<processor> options
- and cc1_cpu_spec associated.
- (CONSTANT_ADDRESS_P): Fix last patch.
- (ASM_DECLARE_FUNCTION_NAME): Declare. Fix comment.
- * config/mips/mips.md (bungt, bunge, sungt_df, sungt_sf, sunge_df,
- sunge_sf): Remove.
-
-2002-07-03 Stan Shebs <shebs@apple.com>
-
- * config/darwin.h (APPLE_CC): Remove, not meaningful in FSF GCC.
- (STRINGIFY_THIS, REALLY_STRINGIFY): Remove.
- (CPP_SPEC): Remove insertion of APPLE_CC definition.
+ * expr.c (store_constructor): Fix pasto in previous patch.
-2002-07-03 Roger Sayle <roger@eyesopen.com>
+2004-01-02 Kazu Hirata <kazu@cs.umass.edu>
- * combine.c (struct_undo): Change types of recorded substitutions
- to be either "int" or "rtx", instead of "unsigned int" and "rtx".
- (do_SUBST_INT): Change types of the substitution from unsigned int
- to int, to avoid compilation warning from SUBST_INT's only caller.
-
- (make_extraction): Add cast to avoid compilation warning.
- (force_to_mode): Remove cast to avoid compilation warning.
+ * config/i386/cygming.h: Fix comment formatting.
+ * config/i386/djgpp.h: Likewise.
+ * config/i386/gthr-win32.c: Likewise.
+ * config/i386/i386-interix.h: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/i386/i386.h: Likewise.
+ * config/i386/openbsd.h: Likewise.
+ * config/i386/winnt.c: Likewise.
+ * config/i386/xm-mingw32.h: Likewise.
-2002-07-03 Eric Botcazou <ebotcazou@multimania.com>
- Jeff Law <law@redhat.com>
+2004-01-02 Joseph S. Myers <jsm@polyomino.org.uk>
- * i386.md (length_immediate attribute): Fix typo.
- (length_address attribute): Likewise.
- (modrm attribute): Set it to 0 for immediate call instructions.
- (jcc_1 pattern): Set modrm attribute to 0.
- (jcc_2 pattern ): Likewise.
- (jump pattern): Likewise.
- (doloop_end_internal pattern): Explicitly set length.
- (leave pattern): Fix typo.
- (leave_rex64 pattern): Likewise.
-
-2002-07-03 David Edelsohn <edelsohn@gnu.org>
-
- * config/rs6000/rs6000.md (fix_truncdfsi2_internal): Ignore DImode
- in FPR as preference.
- (fctiwz): Same.
- (floatdidf2, fix_truncdfdi2): Same.
- (floatdisf2, floatditf2, fix_trunctfdi2): Same.
- (floatditf2): Same.
- (floatsitf2, fix_trunctfsi2): SImode in GPR.
- (ctrdi): Remove FPR alternative and splitter.
-
-2002-07-03 Will Cohen <wcohen@redhat.com>
-
- * config/i386/i386.c (x86_integer_DFmode_moves): Disable for PPro.
-
-2002-07-03 J"orn Rennecke <joern.rennecke@superh.com>
-
- * optabs.c (expand_vector_binop): Don't store using a SUBREG smaller
- than UNITS_PER_WORD, unless this is little endian and the first unit
- in this word. Let extract_bit_field decide how to load an element.
- Force arguments to matching mode.
- (expand_vector_unop): Likewise.
+ * doc/gcc.texi, doc/invoke.texi, doc/install.texi: Update
+ copyright and last modification dates.
- * simplify-rtx.c (simplify_subreg): Don't assume that all vectors
- consist of word_mode elements.
- * c-typeck.c (build_binary_op): Allow vector types for BIT_AND_EXPR,
- BIT_ANDTC_EXPR, BIT_IOR_EXPR and BIT_XOR_EXPR.
- (build_unary_op): Allow vector types for BIT_NOT_EPR.
- * emit-rtl.c (gen_lowpart_common): Use simplify_gen_subreg for
- CONST_VECTOR.
- * optabs.c (expand_vector_binop): Try to perform operation in
- smaller vector modes with same inner size. Add handling of AND, IOR
- and XOR. Reject expansion to inner-mode sized scalars when using
- OPTAB_DIRECT. Use simplify_gen_subreg on constants.
- (expand_vector_unop): Try to perform operation in smaller vector
- modes with same inner size. Add handling of one's complement.
- When there is no vector negate operation, try a vector subtract
- operation. Use simplify_gen_subreg on constants.
- * simplify-rtx.c (simplify_subreg): Add capability to convert vector
- constants into smaller vectors with same inner mode, and to
- integer CONST_DOUBLEs.
+2004-01-02 Andreas Jaeger <aj@suse.de>, Gerald Pfeifer <gp@suse.de>
-2002-07-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * c-parse.in (parsing_iso_function_signature): New variable.
- (extdef_1): New, copied from...
- (extdef): ... here. Reset parsing_iso_function_signature.
- (old_style_parm_decls): Reset parsing_iso_function_signature.
- (old_style_parm_decls_1): New, copied from old_style_parm_decls.
- Warn about ISO C style function definitions.
- (nested_function, notype_nested_function): Reset
- parsing_iso_function_signature.
- (parmlist_2): Set parsing_iso_function_signature.
-
- * doc/invoke.texi (-Wtraditional): Document new behavior.
-
-2002-07-02 Chris Demetriou <cgd@broadcom.com>
-
- * config.gcc (mips*el-*-*): Use tm_defines to set
- TARGET_ENDIAN_DEFAULT, rather than including mips/little.h.
- * config/mips/little.h: Remove.
-
-2002-07-02 Devang Patel <dpatel@apple.com>
-
- * objc/objc-act.c (adjust_type_for_id_default): Do not allow an
- object as parameter. Prevent something like 'NSObject' to be
- used as the type for a method argument.
-
-2002-07-03 Neil Booth <neil@daikokuya.co.uk>
-
- * cpptrad.c: Update comment.
-
-2002-07-02 Neil Booth <neil@daikokuya.co.uk>
-
- * doc/cpp.texi: Update for traditional preprocessing changes.
- * goc/cppopts.texi: Similarly.
-
-2002-07-02 Ziemowit Laski <zlaski@apple.com>
-
- * c-parse.in (designator): Enable designated initializers if ObjC.
- (objcmessageexpr): Remove references to objc_receiver_context.
- * objc/objc-act.h (objc_receiver_context): Remove decl.
- * objc/objc-act.c (objc_receiver_context): Remove.
- (lookup_objc_ivar): Test objc_method_context instead of
- objc_receiver_context.
-
-2002-07-02 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.c (print_operand, case 'N'): Allow zero vector.
- (arith_reg_or_0_operand): Likewise.
- (zero_vec_operand): Check for CONST_VECTOR, not PARALLEL.
- * sh.h (CONST_COSTS): 0 has 0 cost. Check OUTER_CODE for
- IOR, XOR, PLUS and SET and take their respective constant
- ranges into account.
- (PREDICATE_CODES, arith_reg_or_0_operand): Can be CONST_VECTOR.
- * sh.md (subdi3, subdi3_media): Allow zero operand.
- (movv8qi_i+3): Only vector that is not split is the zero vector.
- Fix operand 3 to simplify_subreg.
- (movv2si_i): Split alternative 1.
- (mshfhi_l_di_rev+1): New splitter.
-
-2002-07-02 Neil Booth <neil@daikokuya.co.uk>
-
- PR preprocessor/7029
- * cppinit.c (cpp_handle_option): Suppress warnings with an
- implicit "-w" for "-M" and "-MM".
- * doc/cppopts.texi: Update.
-
-2002-07-01 Roger Sayle <roger@eyesopen.com>
+ * doc/install.texi (Specific): Mention x86_64.
- * config/sh/sh.c (sh_media_init_builtins): Change use of poisoned
- identifier "bzero" to "memset". Pass extra NULL_TREE argument to
- builtin_function.
-
-2002-07-02 Alan Modra <amodra@bigpond.net.au>
-
- * README.Portability: Fix typos.
-
-2002-07-01 Hans-Peter Nilsson <hp@axis.com>
-
- PR target/7177
- * config/cris/cris.h (LEGITIMIZE_RELOAD_ADDRESS): Correct number
- of indirections for register inside sign-extended mem part.
-
-2002-07-01 Roger Sayle <roger@eyesopen.com>
-
- * tree.h: Modify builtin_function interface to take an extra
- argument ATTRS, which is a tree representing an attribute list.
+2004-01-01 Hans-Peter Nilsson <hp@bitrange.com>
- * c-decl.c (builtin_function): Accept additional parameter.
- * objc/objc-act.c (builtin_function): Likewise.
- * f/com.c (builtin_function): Likewise.
- * java/decl.c (builtin_function): Likewise.
- * ada/utils.c (builtin_function): Likewise.
- * cp/decl.c (builtin_function): Likewise.
- (builtin_function_1): Likewise.
+ * builtins.c (expand_builtin_apply_args_1) [STACK_GROWS_DOWNWARD]:
+ Call force_operand on plus_constant result.
- * c-common.c (c_common_nodes_and_builtins): Pass an additional
- NULL_TREE argument to builtin_function. (builtin_function_2):
- Likewise.
- * cp/call.c (build_java_interface_fn_ref): Likewise.
- * objc/objc-act.c (synth_module_prologue): Likewise.
- * java/decl.c (java_init_decl_processing): Likewise.
- * f/com.c (ffe_com_init_0): Likewise.
-
- * config/alpha/alpha.c (alpha_init_builtins): Pass an additional
- NULL_TREE argument to builtin_function.
- * config/arm/arm.c (def_builtin): Likewise.
- * config/c4x/c4x.c (c4x_init_builtins): Likewise.
- * config/i386/i386.c (def_builtin): Likewise.
- * config/ia64/ia64.c (def_builtin): Likewise.
- * config/rs6000/rs6000.c (def_builtin): Likewise.
-
-2002-07-01 Zack Weinberg <zack@codesourcery.com>
-
- * config/ip2k/t-ip2k: Remove LIBGCC1, CROSS_LIBGCC1, and LIBGCC1_TEST.
- * config/mips/t-isa3264: Likewise.
- * config/mmix/t-mmix: Likewise.
-
-2002-07-01 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * emit-rtl.c (init_emit_once): Add missing cast to HOST_WIDE_INT.
-
-2002-07-01 Roger Sayle <roger@eyesopen.com>
-
- PR opt/4046
- * fold-const.c (fold) [COND_EXPR]: Simplify A ? 0 : 1 to !A,
- A ? B : 0 to A && B and A ? B : 1 into !A || B if both A and
- B are truth values.
-
-2002-07-01 Nathanael Nerode <neroden@gcc.gnu.org>
-
- * config/mmix/t-mmix: Eliminate last reference to LIBGCC1_TEST.
-
-2002-07-01 Matt Kraai <kraai@alumni.cmu.edu>
-
- * README.Portability (Function prototypes): Give an example of
- declaring and defining a function with no arguments.
-
- * README.Portability (Function prototypes): Document new
- variable-argument function macros.
-
-2002-07-01 J"orn Rennecke <joern.rennecke@superh.com>
-
- * sh.c (langhooks.h): Include.
- (sh_init_builtins, sh_media_init_builtins): New functions.
- (sh_expand_builtin, arith_reg_dest,and_operand): Likewise.
- (mextr_bit_offset, extend_reg_operand, zero_vec_operand): Likewise.
- (sh_rep_vec, sh_1el_vec, sh_const_vec): Likewise.
- (builtin_description): New struct tag.
- (signature_args, bdesc): New arrays.
- (TARGET_INIT_BUILTINS, TARGET_EXPAND_BUILTIN): Undef / define.
- (print_operand): Add 'N' modifier.
- * sh.h (VECTOR_MODE_SUPPORTED_P): Add SHmedia vector modes.
- (EXTRA_CONSTRAINT_U, EXTRA_CONSTRAINT_W): New macros.
- (EXTRA_CONSTRAINT): Add 'U' and 'W' cases.
- (CONST_COSTS): Add special case for SHmedia AND.
- (PREDICATE_CODES): Add and_operand, arith_reg_dest,
- extend_reg_operand, extend_reg_or_0_operand, mextr_bit_offset,
- sh_const_vec, sh_1el_vec, sh_rep_vec, zero_vec_operand.
- target_operand can also be const or unspec.
- * sh.md (UNSPEC_INIT_TRAMP, UNSPEC_FCOSA UNSPEC_FSRRA): New constants.
- (UNSPEC_FSINA, UNSPEC_NSB, UNSPEC_ALLOCO): Likewise.
- (attribute type): Add new types.
- (anddi3): Add splitter.
- (movdi_const_16bit+1): Add code to handle vector constants and
- bitmasks efficiently.
- (shori_media): Have generator function made.
- (movv8qi, movv8qi_i, movv8qi_i+1, movv8qi_i+2): New patterns.
- (movv8qi_i+3, movv2hi, movv2hi_i, movv4hi, movv4hi_i): Likewise.
- (movv2si, movv2si_i, absv2si2, absv4hi2, addv2si3, addv4hi3): Likewise.
- (ssaddv2si3, usaddv8qi3, ssaddv4hi3, negcmpeqv8qi): Likewise.
- (negcmpeqv2si, negcmpeqv4hi, negcmpgtuv8qi, negcmpgtv2si): Likewise.
- (negcmpgtv4hi, mcmv, mcnvs_lw, mcnvs_wb, mcnvs_wub): Likewise.
- (mextr_rl, mextr_lr, mextr1, mextr2, mextr3, mextr4, mextr5): Likewise.
- (mextr6, mextr7, mmacfx_wl, mmacfx_wl_i, mmacnfx_wl): Likewise.
- (mmacnfx_wl_i, mulv2si3, mulv4hi3, mmulfx_l, mmulfx_w): Likewise.
- (mmulfxrp_w, mmulhi_wl, mmullo_wl, mmul23_wl, mmul01_wl): Likewise.
- (mmulsum_wq, mmulsum_wq_i, mperm_w, mperm_w_little): LIkewise.
- (mperm_w_big, mperm_w0, msad_ubq, msad_ubq_i, mshalds_l): Likewise.
- (mshalds_w, ashrv2si3, ashrv4hi3, mshards_q, mshfhi_b): Likewise.
- (mshflo_b, mshf4_b, mshf0_b, mshfhi_l, mshflo_l, mshf4_l): Likewsie.
- (mshf0_l, mshfhi_w, mshflo_w, mshf4_w, mshf0_w, mshfhi_l_di): Likewise.
- (mshfhi_l_di_rev, mshflo_l_di, mshflo_l_di_rev): Likewise.
- (mshflo_l_di_x, mshflo_l_di_x_rev, ashlv2si3, ashlv4hi3): Likewise.
- (lshrv2si3, lshrv4hi3, subv2si3, subv4hi3, sssubv2si3): Likewise.
- (ussubv8qi3, sssubv4hi3, fcosa_s, fsina_s, fipr, fsrra_s): Likewise.
- (ftrv): Likewise.
-
- (fpu_switch+1, fpu_switch+2): Remove constraint.
-
-2002-07-01 Aldy Hernandez <aldyh@redhat.com>
-
- * tree.c (build_function_type_list): Update function comment.
- Rename first argument to return_type.
-
-2002-07-01 Neil Booth <neil@daikokuya.co.uk>
-
- * Makefile.in: Remove all trace of tradcpp.c, tradcpp.h,
- tradcif.y and related files.
-
-2002-07-01 Neil Booth <neil@daikokuya.co.uk>
-
- * cpptrad.c (skip_whitespace): Pass pointer to prior char.
-
-2002-07-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * mips.h (FUNCTION_ARG_REGNO_P): Fix parentheses.
-
-See ChangeLog.7 for earlier changes.
+2004-01-01 Jan Hubicka <jh@suse.cz>
+ * expmed.c (store_bit_field, extract_bit_field): Use new named patterns
+ * expr.c (store_constructor): Use vec_init pattern.
+ * genopinit.c (optabs): Initailize vec_set/vec_extract/vec_init.
+ * optabs.h (optab_index): ADD OTI_vec_set/OTI_vec_extract/OTI_vec_init
+ (vec_set_optab, vec_extract_optab, vec_init_optab): New.
+ * i386.md (vec_setv2df, vec_extractv2df, vec_setv4sf, vec_extractv4sf):
+ New patterns.
+ (sse2_unpc?pd): Fix pattern.
+ (sse2_movlpd): Kill.
+ (sse2_movsd): Deal with movlpd too.
+ * i386.c (ix86_expand_builtin): Use sse2_movsd instead of sse2_movlpd.
+ (ix86_expand_vector_init): New.
+ * emmintrin.h (__mm_set_pd, __mm_set_ps): Use vector extensions.
+ * md.texi (vec_set, vec_extract): Document
+
+2003-12-31 Jan Hubicka <jh@suse.cz>
+
+ PR opt/13473
+ * recog.c (validate_replace_rtx_1): Take care for RTL sharing inside
+ ASM input operands
+
+ PR opt/12617
+ * toplev.c (dump_file_index): Reorder ce3 and bbro.
+ (dump_file): Likewise.
+ (rest_of_compilation): Likewise.
+
+ PR debug/13367
+ * cgraph.c (cgraph_function_possibly_inlined): Even with
+ flag_really_no_inline we inline always_inline functions.
+ * cgraphunit.c (cgraph_analyze_function): Clear inlinable flag
+ for non-always_inline functions when there is flag_really_no_inline.
+ (cgraph_decide_inlining): Limit work done when not inlining.
+ (cgraph_decide_inlining_incrementally): Likewise.
+ (cgraph_optimize_function): Check whether something got inlined.
+ * c-objc-common.c (c_disregard_inline_limits): Do not always inline
+ extern inline functions when not inlining.
+
+ * opts.c (decode_options): Disable crossjumping at -O1
+ * invoke.texi (-O1): Document change.
+
+See ChangeLog.10 for earlier changes.
diff --git a/contrib/gcc/ChangeLog.1 b/contrib/gcc/ChangeLog.1
index ef67034a5969..b99a93754a3a 100644
--- a/contrib/gcc/ChangeLog.1
+++ b/contrib/gcc/ChangeLog.1
@@ -1251,7 +1251,7 @@ Wed Apr 14 13:59:27 1999 Martin von Loewis <loewis@informatik.hu-berlin.de>
Wed Apr 14 00:18:22 1999 Jan Hubicka <hubicka@freesoft.cz>
- * i386.md (SImode logical compare): Avoid outputing non-pariable testw
+ * i386.md (SImode logical compare): Avoid outputting non-pariable testw
and testl on Pentium.
(register and memory bit tests): Likewise.
(setcc, normal and reversed conditional branches): Use shorter
@@ -3212,7 +3212,7 @@ Tue Mar 16 13:44:50 1999 Jim Wilson <wilson@cygnus.com>
unless it's necessary.
* cpplib.h (parse_marker): Removed.
- (struct cpp_buffer): Line_base is now a unsigned char *; add
+ (struct cpp_buffer): Line_base is now an unsigned char *; add
`mark' [long], remove `marks' [struct parse_marker *].
(parse_set_mark, parse_clear_mark, parse_goto_mark): Update
prototypes.
diff --git a/contrib/gcc/ChangeLog.10 b/contrib/gcc/ChangeLog.10
new file mode 100644
index 000000000000..b197c751d409
--- /dev/null
+++ b/contrib/gcc/ChangeLog.10
@@ -0,0 +1,16352 @@
+2003-12-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * print-rtl.c (print_rtx): For hard register, write out register
+ number and register name instead of calling PRINT_REG.
+ * defaults.h (PRINT_REG): Deleted.
+ * config/i386/i386.c (print_reg): Remove handling of CODE of -1.
+ Move comments here from i386.h.
+ (print_operand, print_operand_address): Call print_reg directly.
+ * config/i386/i386.h (PRINT_REG): Deleted.
+
+2003-12-31 Roger Sayle <roger@eyesopen.com>
+
+ * config/ia64/hpux.h (TARGET_OS_CPP_BUILTINS): Define
+ _INCLUDE_LONGLONG.
+
+2003-12-31 Zack Weinberg <zack@codesourcery.com>
+
+ * gcc.c (init_spec): Add -lunwind to shared case too if
+ USE_LIBUNWIND_EXCEPTIONS.
+
+2003-12-31 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/include/texinfo.tex: Update to version 2003-12-21.10.
+ * doc/gcc.texi, doc/gccint.texi: Don't set font for
+ @def... commands.
+ * doc/invoke.texi: Don't use empty @opindex.
+
+2003-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ * c-common.c (c_expand_expr): Remove code to return a value
+ different from that returned by expand_expr.
+ * expr.c (store_expr): Use the validity of a target MEM, rather
+ than checking DECL_RTL (exp), to figure out if a copy is
+ required.
+
+2003-12-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/v850/lib1funcs.asm: Fix comment formatting.
+ * config/v850/v850.c: Likewise.
+ * config/v850/v850.h: Likewise.
+ * config/v850/v850.md: Likewise.
+
+2003-12-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386.md (*movqi_insv_2): Remove AND in the
+ set source.
+
+2003-12-31 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config.gcc: Added m32r-linux m32rle-elf and m32le-linux targets.
+ * doc/invoke.texi: Document -mflush-func, -mflush-trap options.
+ Also add documentation for -mdebug, -malign-loops, -missue-rate,
+ and -mbranch-cost options.
+ * config/m32r/t-linux: New file: m32r-linux support.
+ * config/m32r/xm-linux.h: Likewise.
+ * config/m32r/xm-m32r.h: Likewise.
+ * config/m32r/linux.h: Likewise.
+ * config/m32r/little.h: New file: Little endian code generation
+ support.
+ * config/m32r/m32r-protos.h (m32r_legitimize_pic_address,
+ m32r_legitimate_pic_operand_p, load_pic_register): Add
+ prototypes.
+ * config/m32r/m32r.c (m32r_init): Add options for cache-flush.
+ (addr24_operand): Changes for PIC code generation.
+ * config/m32r/m32r.h (LABEL_ALIGN): Define to calculate PNOP
+ length at labels.
+ (ASM_SPEC): Add PIC support.
+ (FUNCTION_PROFILER): New define.
+ (TRAMPOLINE_SIZE, INITIALIZE_TRAMPOLINE): Changed to support
+ trampoline.
+ (CONDITIONAL_REGISTER_USAGE, CONSTANT_ADDRESS_P,
+ LEGITIMIZE_ADDRESS, JUMP_TABLES_IN_TEXT_SECTION,
+ PIC_OFFSET_TABLE_REGNUM, FINALIZE_PIC, LEGITIMATE_PIC_OPERAND_P,
+ ASM_OUTPUT_ADDR_DIFF_ELT, CASE_VECTOR_MODE): Define for PIC.
+ (move_src_operand, m32r_compute_frame_size, m32r_expand_prologue,
+ m32r_finalize_pic): Changes for PIC and profile support.
+ (global_offset_table, load_pic_register, m32r_legitimate_pic_operand_p,
+ m32r_legitimize_pic_address): Add for PIC support.
+ (m32r_file_start): Changed for little-endian-target.
+ * config/m32r/m32r.md (mvqi, movhi, movsi, movdi, movsf, movdf,
+ tablejump, tablejump_insn, call, call_value, call_value_via_label):
+ Changes for PIC.
+ (pic_load_addr, get_pc, builtin_setjmp_receiver): Added for PIC.
+ (flush_icache): Changes for cache-flush trap.
+
+2003-12-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386.h: Remove an unnecessary #undef.
+
+2003-12-30 Roger Sayle <roger@eyesopen.com>
+
+ * cppfiles.c (pch_open_file): Minor tweak to work-around native
+ HPPA compiler bug.
+
+2003-12-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/rs6000/aix.h: Fix comment formatting.
+ * config/rs6000/rs6000-modes.def: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/rs6000/rs6000.h: Likewise.
+ * config/rs6000/rs6000.md: Likewise.
+
+2003-12-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386-protos.h: Remove prototype for
+ const_int_1_operand.
+ * config/i386/i386.c (const_int_1_operand): Remove.
+ * config/i386/i386.h (PREDICATE_CODES): Remove
+ const_int_1_operand.
+ * config/i386/i386.md: Replace all uses of const_int_1_operand
+ with const1_operand.
+ * config/i386/pentium.md: Likewise.
+
+2003-12-30 Geoffrey Keating <geoffk@greed.local>
+
+ * doc/tm.texi (PREFERRED_RELOAD_CLASS): Describe use of NO_REGS
+ with constants.
+
+2003-12-30 Mark Mitchell <mark@codesourcery.com>
+
+ * stor-layout.c (layout_decl): Turn bitfields into ordinary
+ fields, even if they are the first field in a structure.
+
+2003-12-30 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold) <COND_EXPR>: Don't require strict type
+ equality, instead just prevent replacing a COND_EXPR of non-void
+ type by one of its operands of void type.
+
+2003-12-30 Andreas Schwab <schwab@suse.de>
+
+ * doc/c-tree.texi: Fix @item vs. @itemx.
+ * doc/cpp.texi: Likewise.
+ * doc/install.texi: Likewise.
+ * doc/invoke.texi: Likewise.
+
+2003-12-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * builtins.c (expand_builtin_apply_args_1): Fix typo in previous
+ change.
+
+2003-12-30 Jan Hubicka <jh@suse.cz>
+
+ PR target/11936
+ * i386.h (CLASS_LIKELY_SPILLED_P): Return true for
+ FP_TOP_REG/FP_SECOND_REG.
+
+2003-12-30 Steven Bosscher <steven@gcc.gnu.org>
+
+ Backport from tree-ssa (relevant changes only):
+ 2003-12-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * et-forest.h (et_forest_create, et_forest_delete,
+ et_forest_add_node, et_forest_add_edge, et_forest_remove_node,
+ et_forest_remove_edge, et_forest_parent,
+ et_forest_common_ancestor, et_forest_node_value,
+ et_forest_enumerate_sons): Declarations removed.
+ (struct et_node): New.
+ (et_new_tree, et_free_tree, et_set_father, et_split, et_nca,
+ et_below): Declare.
+ * et-forest.c (struct et_forest_occurrence, struct et_forest,
+ struct et_forest_node): Removed.
+ (et_forest_create, et_forest_delete,
+ et_forest_add_node, et_forest_add_edge, et_forest_remove_node,
+ et_forest_remove_edge, et_forest_parent,
+ et_forest_common_ancestor, et_forest_node_value,
+ et_forest_enumerate_sons, splay, remove_all_occurrences,
+ find_leftmost_node, find_rightmost_node, calculate_value): Removed.
+ (struct et_occ): New.
+ (et_nodes, et_occurences): New.
+ (set_depth, set_depth_add, set_prev, set_next, et_recomp_min,
+ et_check_occ_sanity, et_check_sanity, et_check_tree_sanity,
+ record_path_before_1, record_path_before, check_path_after_1,
+ check_path_after, et_splay, et_new_occ, et_new_tree,
+ et_free_tree, et_set_father, et_split, et_nca, et_below): New.
+ * basic-block.h (struct basic_block_def): New field dom.
+ (struct dominance_info): Type removed.
+ (calculate_dominance_info, free_dominance_info,
+ nearest_common_dominator, set_immediate_dominator,
+ get_immediate_dominator, dominated_by_p, get_dominated_by,
+ add_to_dominance_info, delete_from_dominance_info,
+ recount_dominator, redirect_immediate_dominators,
+ iterate_fix_dominators, verify_dominators): Declarations
+ changed.
+ (enum dom_state): New.
+ (dom_computed): New variable.
+ (first_dom_son, next_dom_son): Declare.
+ * dominance.c (struct dominance_info): Removed.
+ (BB_NODE, SET_BB_NODE): Removed.
+ (calculate_dominance_info, free_dominance_info,
+ nearest_common_dominator, set_immediate_dominator,
+ get_immediate_dominator, dominated_by_p, get_dominated_by,
+ add_to_dominance_info, delete_from_dominance_info,
+ recount_dominator, redirect_immediate_dominators,
+ iterate_fix_dominators, verify_dominators,
+ debug_dominance_info): Work over new datastructure. Access
+ dominance datastructures through CFG.
+ (assign_dfs_numbers, compute_dom_fast_query, first_dom_son,
+ next_dom_son): New.
+ * bt-load.c (dom): Variable removed.
+ (augment_live_range, combine_btr_defs, migrate_btr_def,
+ migrate_btr_defs, branch_target_load_optimize): Updated for the
+ new interface for dominance information.
+ * cfg.c {exit_entry_blocks): Update initializer.
+ * cfglayout.c (copy_bbs): Removed loops argument. Updated for
+ the new interface for dominance information.
+ * cfglayout.h (copy_bbs): Declaration changed.
+ * cfgloop.c (flow_loop_pre_header_find, flow_loops_cfg_dump,
+ flow_loop_scan, canonicalize_loop_headers, flow_loops_find): Updated
+ for the new interface for dominance information.
+ (flow_loop_scan): Loops argument removed.
+ (flow_loops_free): Don't release dominators.
+ * cfgloop.h (struct cfg): Dom field removed.
+ (flow_loop_scan, loop_split_edge_with, simple_loop_p,
+ just_once_each_iteration_p, split_loop_bb): Declaration changed.
+ * cfgloopanal.c (simple_loop_exit_p, simple_increment,
+ just_once_each_iteration_p, simple_loop_p): Remove loops argument.
+ Updated for the new interface for dominance information.
+ * cfgloopmanip.c (remove_bbs, find_path, create_preheader,
+ split_loop_bb, loopify, duplicate_loop_to_header_edge,
+ force_single_succ_latches, loop_split_edge_with): Ditto.
+ * gcse.c (dominators): Variable removed.
+ (free_code_hoist_mem, compute_code_hoist_data, hoist_code):
+ Updated for the new interface for dominance information.
+ * ifcvt.c (post_dominators): Variable removed.
+ (mark_loop_exit_edges, merge_if_block, find_if_header,
+ find_cond_trap, find_if_case_1, find_if_case_2, if_convert):
+ Updated for the new interface for dominance information.
+ * loop-init.c (rtl_loop_optimizer_init,
+ rtl_loop_optimizer_finalize): Ditto.
+ * loop-unroll.c (decide_peel_simple, decide_peel_once_rolling,
+ decide_peel_completely, decide_unroll_stupid,
+ decide_unroll_constant_iterations,
+ decide_unroll_runtime_iterations): Loops argument removed.
+ Updated for the new interface for dominance information.
+ (unroll_and_peel_loops, peel_loops_completely,
+ unroll_loop_runtime_iterations): Updated for the new interface for
+ dominance information.
+ * loop-unswitch.c (may_unswitch_on_p, unswitch_loops,
+ unswitch_single_loop, unswitch_loop): Updated for the new
+ interface for dominance information.
+ * predict.c (process_note_predictions, process_note_prediction,
+ estimate_probability, note_prediction_to_br_prob): Ditto.
+ * sched-rgn.c (find_rgns, init_regions): Ditto.
+ * toplev.c (rest_of_handle_branch_prob): Free the dominators.
+
+2003-12-30 Jan Hubicka <jh@suse.cz>
+
+ PR target/13456
+ * i386.md (allocate_stack_worker): Use different pattern for pre and
+ post reload expansion.
+ (allocate_stack_worker_1, allocate_stack_worker_rex64): Use
+ match_scratch.
+ (allocate_stack_worder_1_postreload,
+ allocate_stack_worker_rex64_postreload): New.
+
+2003-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * builtins.c (expand_builtin_apply_args_1): Add pretend args size
+ to the virtual incoming args pointer for downward stacks.
+
+2003-12-29 Roger Sayle <roger@eyesopen.com>
+
+ PR fortran/12632
+ * fold-const.c (fold) <COND_EXPR>: Don't fold a constant condition,
+ if the type of the selected branch doesn't match its' parent.
+
+2003-12-29 Jan Hubicka <jh@suse.cz>
+
+ * coverage.c (read_counts_file): Better error messages; cause corrupted
+ profiles to produce hard errors, not just warnings
+ (get_coverage_counts): Similarly.
+
+ * toplev.c (rest_of_handle_loop_optimize): Enable LOOP_AUTO_UNROLL.
+
+2003-12-29 Phil Edwards <phil@codesourcery.com>
+
+ * doc/cppopts.texi: Use of -idirafter, -iprefix, -iwithprefix, and
+ -iwithprefixbefore is not discouraged.
+
+2003-12-28 Mostafa Hagog <mustafa@il.ibm.com>
+
+ * sbitmap.c (sbitmap_union_of_diff_cg, sbitmap_a_and_b_cg,
+ sbitmap_a_xor_b_cg): Accumulate "changed" properly.
+ (sbitmap_not): Zero all bits past n_bit.
+
+2003-12-27 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR opt/13159
+ * cfgloopanal.c (mark_irreducible_loops): Fix the strongly connected
+ components detection.
+ * loop-unswitch.c (unswitch_loop): Preserve simple preheaders.
+
+2003-12-27 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/uclinux.h (LIB_SPEC): Add elf2flt magic required for
+ correct linking of executables using id-based shared libraries.
+
+2003-12-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386-interix.h: Remove uses of "register"
+ specifier in declarations of arguments and local variables.
+ * config/i386/i386.c: Likewise.
+ * config/i386/i386elf.h: Likewise.
+ * config/i386/ptx4-i.h: Likewise.
+ * config/i386/sysv4.h: Likewise.
+
+2003-12-26 Fariborz Jahanian <fjahanian@apple.com>
+ Geoffrey Keating <geoffk@apple.com>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (legitimate_offset_address_p): Do not
+ restrict DFmode and TFmode to word alignment.
+ * config/rs6000/rs6000.md (movdf_hardfloat64): Use 'o' constraint
+ for ld/std and order before mr.
+
+2003-12-26 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/darwin.h (LINK_COMMAND_SPEC): Arrange
+ -fprofile-generate to imply -lgcov.
+
+2003-12-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (ldm_h8300s_2_normal): Use HImode for
+ addresses.
+
+2003-12-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.md: Remove a constraint from a splitter.
+
+2003-12-25 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR C++/13429, C/11944
+ * c-common.c (c_build_qualified_type): Return early when type is
+ error_mark_node.
+ (c_apply_type_quals_to_decl): Likewise.
+
+2003-12-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha-modes.def: Fix comment formatting.
+ * config/alpha/alpha.c: Likewise.
+ * config/alpha/alpha.h: Likewise.
+ * config/alpha/elf.h: Likewise.
+ * config/alpha/lib1funcs.asm: Likewise.
+ * config/alpha/openbsd.h: Likewise.
+ * config/alpha/vms-cc.c: Likewise.
+ * config/alpha/vms-crt0-64.c: Likewise.
+ * config/alpha/vms-crt0.c: Likewise.
+ * config/alpha/vms-ld.c: Likewise.
+ * config/alpha/vms-psxcrt0-64.c: Likewise.
+ * config/alpha/vms-psxcrt0.c: Likewise.
+ * config/alpha/vms.h: Likewise.
+ * config/arc/arc.c: Likewise.
+ * config/arm/aof.h: Likewise.
+ * config/arm/arm-modes.def: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/arm/arm.h: Likewise.
+ * config/arm/arm.md: Likewise.
+ * config/arm/linux-elf.h: Likewise.
+ * config/arm/vxworks.h: Likewise.
+ * config/avr/avr.c: Likewise.
+ * config/avr/avr.h: Likewise.
+
+2003-12-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/xtensa/elf.h: Fix comment formatting.
+ * config/xtensa/xtensa-protos.h: Likewise.
+ * config/xtensa/xtensa.c: Likewise.
+ * config/xtensa/xtensa.h: Likewise.
+
+2003-12-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/avr/avr.c: Fix comment formatting.
+ * config/avr/avr.md: Likewise.
+
+2003-12-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/12721.
+ * config/avr/avr.c: Include ggc.h.
+ (tmp_reg_rtx): Declare with GTY.
+ (zero_reg_rtx): Likewise.
+ (ldi_reg_rtx): Remove.
+ (avr_override_options): Initialize zero_reg_rtx and
+ ldi_reg_rtx.
+ (avr_init): Remove.
+ Include gt-avr.h.
+ * config/avr/avr.h (LDI_REG_REGNO): Remove.
+ Remove externs for tmp_reg_rtx, zero_reg_rtx, and ldi_reg_rtx.
+
+2003-12-24 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/md.texi: Document PowerPC vector register constraint letter.
+
+2003-12-23 Mark Mitchell <mark@codesourcery.com>
+
+ * calls.c (expand_call): Recognize calls to "sqrt" and create
+ corresponding notes.
+
+2003-12-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/mips/mips.c (override_options): Use `inform' instead
+ of `warning' for -g -mabi=32 and native assembler.
+
+ * config/mips/t-iris6 (CRTSTUFF_T_CFLAGS, TARGET_LIBGCC2_CFLAGS):
+ Don't pass -Wno-error.
+
+2003-12-23 David Edelsohn <edelsohn@gnu.org>
+
+ * function.c (assign_parms): Update max_parm_reg and
+ parm_reg_stack_loc when adding new parm reg.
+
+2003-12-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/ns32k/ns32k.c: Convert to ISO-C.
+
+2003-12-23 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/ia64.c (ia64_va_arg): Pass pointer for
+ variable-sized type through convert_memory_address.
+ (ia64_in_small_data_p): Always return false for FUNCTION_DECLs.
+
+2003-12-23 Jan Hubicka <jh@suse.cz>
+
+ * common.opt (fprofile-generate,fprofile-use): Add.
+ * gcc.c (LINK_COMMAND_SPEC): Arrange -fprofile-generate to imply -lgcov
+ * opts.c (profile_arc_flag_set, flag_profile_values_set,
+ flag_unroll_loops_set, flag_tracer_set,
+ flag_value_profile_transformations_set,
+ flag_peel_loops_set): New static variables.
+ (common_handle_option): Deal with -fprofile-generate/-fprofile-use
+ * invoke.texi (-fprofile-generate, -fprofile-use): Describe.
+
+2003-12-23 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (OBJS-common): Remove dwarfout.o.
+ (dwarfout.o): Remove.
+ * common.opt: Remove -gdwarf, -gdwarf+.
+ * defaults.h (PREFERRED_DEBUGGING_TYPE): Do not check for
+ DWARF_DEBUGGING_INFO.
+ * dwarf2out.c: Fix typo in comment.
+ * dwarfout.c: Remove.
+ * opts.c (common_handle_option): Remove OPT_gdwarf, OPT_gdwarf_.
+ * toplev.c (process_options): Remove check for
+ DWARF_DEBUGGING_INFO.
+ * config/elfos.h (DWARF_DEBUGGING_INFO): Do not #define it or
+ #undef it.
+ * config/netware.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/ptx4.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/vxworks.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/alpha/unicosmk.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/arc/arc.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/i386/sco5.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/i386/x86-64.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/m32r/m32r.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/mcore/mcore-elf.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/sparc/linux64.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/sparc/liteelf.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/sparc/sol26-sld.h (DWARF_DEBUGGING_INFO): Likewise.
+ * config/sparc/sp86x-elf.h (DWARF_DEBUGGING_INFO): Likewise.
+ * doc/invoke.texi: Do not mention -gdwarf, -gdwarf-1, -gdwarf-1+,
+ or -gdwarf+.
+ * doc/tm.texi: Likewise.
+
+ * c-common.c (flag_abi_version): Default to 2.
+ * c-cppbuiltin.c (c_cpp_builtins): Define __GXX_ABI_VERSION
+ uniformly for versions above 2.
+ * doc/invoke.texi: Update documentation for -fabi-version.
+
+2003-12-22 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.md: Change many instances of '!
+ TARGET_POWERPC64' to 'TARGET_32BIT' when the pattern being guarded
+ was guarded only because it changed CR0 or the carry bit in XER.
+
+2003-12-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/13394
+ * toplev.c (rest_of_compilation): Move call to
+ check_function_return_warnings right after the sibcall
+ optimization pass.
+
+2003-12-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/13382
+ * c-typeck.c (convert_for_assignment): When converting from
+ integral type to pointer type, always call convert.
+
+2003-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/invoke.texi: Deprecate -fwritable-strings.
+
+ * c-common.c (flag_external_templates): Remove.
+ (flag_alt_external_templates): Likewise.
+ * c-common.h (flag_external_templates): Remove.
+ (flag_alt_external_templates): Likewise.
+ * c-opts.c (c_common_handle_option): Unsupport
+ -falt-external-templates and -ftemplates.
+ * doc/invoke.texi: Remove mention of -fexternal-templates and
+ -falt-external-templates.
+
+2003-12-22 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/13466
+ * config.gcc (powerpc-*-darwin): Remove overridden value of need_64bit_hwint.
+
+ * emit-rtl.c (copy_rtx_if_shared): Add comment about its use of
+ copy_rtx_if_shared_1.
+ (copy_rtx_if_shared_1): Add comment about what the function does.
+
+ * c-decl.c (finish_function): Change order of checks.
+ (c_expand_body): Likewise.
+
+2003-12-22 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (legitimate_offset_address_p): Correct
+ check for the legitimate offset when memory of
+ DImode/DFmode/TFmode/TImode mode is being referenced and target
+ is TARGET_POWERPC64.
+
+2003-12-22 Dale Johannesen <dalej@apple.com>
+
+ * reload1.c: Add reg_reloaded_call_part_clobbered.
+ (reload_as_needed): Use it.
+ (forget_old_reloads_1): Ditto.
+ (emit_reload_insns): Ditto.
+
+2003-12-22 Dale Johannesen <dalej@apple.com>
+
+ PR optimization/12828
+ * loop.c: Add find_regs_nested to look inside CLOBBER(MEM).
+ (scan_loop): Call it.
+ * regclass.c (reg_scan_mark_regs): Look inside CLOBBER(MEM).
+
+2003-12-22 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/9163
+ * c-decl.c (poplevel): Only set DECL_INITIAL of a current function
+ if it is non-null.
+ (finish_function): Check for error_mark_node or null on DECL_RESULT and
+ DECL_RESULT of fndecl.
+ (c_expand_body): Only expand when DECL_INITIAL of fndecl is not
+ error_mark_node and not null.
+
+2003-12-21 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * rtl.h (dump_rtx_statistics): Declare it.
+ * rtl.c (rtx_alloc_counts, rtx_alloc_sizes, rtvec_alloc_counts,
+ rtx_alloc_sizes): New static vars.
+ (rtx_alloc, rtvec_alloc): Update them.
+ (dump_rtx_statistics): New function.
+ * toplev.c (finalize): Call it.
+ * ggc-page.c (struct globals): Fix comments. Add new member
+ total_allocated_per_order.
+ (ggc_alloc): Keep track of the total allocated memory.
+ (ggc_print_statistics): Clarify message. Print total allocated
+ memory stats.
+ * configure.in (gather-detailed-mem-stats): New flag.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * doc/install.texi (Configuration): Document
+ --enable-gather-detailed-mem-stats.
+
+2003-12-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (CONVERT_HARD_REGISTER_TO_SSA_P): Poison.
+ * config/i386/i386.h (CONVERT_HARD_REGISTER_TO_SSA_P): Remove.
+
+2003-12-21 Roger Sayle <roger@eyesopen.com>
+
+ * config/ia64/hpux.h (TARGET_OS_CPP_BUILTINS): Define _ILP32
+ when compiling in ILP32 mode.
+
+2003-12-21 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/rs6000.c (rs6000_tls_referenced_p): Return early if
+ TARGET_HAVE_TLS is false.
+
+2003-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/ip2k/ip2k-protos.h: Remove the prototype for
+ asm_output_section_name.
+ * config/ip2k/ip2k.c (asm_output_section_name): Remove.
+
+2003-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alias.c: Fix comment formatting.
+ * alloc-pool.c: Likewise.
+ * bitmap.c: Likewise.
+ * bitmap.h: Likewise.
+ * bt-load.c: Likewise.
+ * c-common.c: Likewise.
+ * c-common.h: Likewise.
+ * c-decl.c: Likewise.
+ * c-opts.c: Likewise.
+ * c-pretty-print.c: Likewise.
+ * caller-save.c: Likewise.
+ * cfghooks.h: Likewise.
+ * cgraph.c: Likewise.
+ * collect2.c: Likewise.
+ * cppfiles.c: Likewise.
+ * cpplib.h: Likewise.
+ * dwarf2out.c: Likewise.
+ * dwarfout.c: Likewise.
+ * emit-rtl.c: Likewise.
+ * final.c: Likewise.
+ * function.c: Likewise.
+ * gcov.c: Likewise.
+ * gcse.c: Likewise.
+ * genemit.c: Likewise.
+ * ggc.h: Likewise.
+ * haifa-sched.c: Likewise.
+ * ifcvt.c: Likewise.
+ * libgcc2.h: Likewise.
+ * loop.c: Likewise.
+ * predict.h: Likewise.
+ * unwind-libunwind.c: Likewise.
+ * varasm.c: Likewise.
+
+2003-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/mn10300/mn10300.c (mn10300_encode_section_info): Fix
+ a warning.
+
+2003-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arm/arm.c: Convert to ISO-C.
+ * config/avr/avr.h: Likewise.
+ * config/fr30/fr30.c: Likewise.
+ * config/ip2k/ip2k.c: Likewise.
+ * config/mn10300/mn10300.c: Likewise.
+
+2003-12-20 Andrew Pinski <pinskia@gcc.gnu.org>
+ Matt Thomas <matt@3am-software.com>
+
+ PR target/12749
+ * config/i386/i386.c (print_operand): Print only the first
+ 8 characters of the float in hex.
+
+2003-12-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.h (TRAMPOLINE_TEMPLATE): Shorten sequence when generating PA
+ 2.0 code.
+ (TRAMPOLINE_CODE_SIZE, MIN_CACHELINE_SIZE): New defines.
+ (INITIALIZE_TRAMPOLINE): Rework to pass line length, and aligned start
+ and end addresses to I and D cache instruction patterns.
+ * pa.md (anddi3, iordi3): Change predicates of operands 1 and 2 to
+ and_operand and ior_operand, respectively. When generating 64-bit
+ code, only one operand needs to be a register operand.
+ (xordi3): Change predicates of operands 1 and 2 to register_operand.
+ (one_cmpldi2): Change predicate of operand 1 to register_operand.
+ (dcacheflush, icacheflush): Revise to flush an arbitrary number of
+ cache lines.
+
+2003-12-20 Josef Zlomek <zlomekj@suse.cz>
+
+ PR optimization/13430, PR optimization/12322
+ * bb-reorder.c (copy_bb_p): Do not allow block with many successors to
+ be copied.
+ (find_traces_1_round): Surround check for fake edges by
+ #ifdef ENABLE_CHECKING #endif.
+
+2003-12-20 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR other/7956
+ * genmultilib: New variable disable_multilib. Set it to 'yes'
+ if enable_multilib was set to 'no'. Emit DISABLE_MULTILIB
+ if disable_multilib was set to 'yes'.
+ * gcc.c: Include multilib.h before tm.h.
+ * config/sparc/sol2-bi.h (LINK_ARCH_SPEC): Emit an error
+ message for multiarch options if DISABLE_MULTILIB is set.
+ * config/sparc/sol2-gld-bi.h (LINK_ARCH_SPEC): Likewise.
+
+2003-12-20 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/12085
+ * c-typeck.c (build_function_call): Issue a warning if a
+ function is called through an incompatible prototype and
+ replace the call by a trap in this case.
+
+2003-12-19 James E Wilson <wilson@specifixinc.com>
+
+ * install.texi (ia64-*-linux): Document minimum libunwind version
+ number.
+
+2003-12-19 Per Bothner <per@bothner.com>
+
+ * langhooks.c (lhd_print_error_function): Fix for PR c/13110.
+ Don't do pp_newline; it causes an extra blank line.
+ * pretty-print.c (pp_base_flush): Clear pp_needs_newline.
+
+2003-12-19 Jason Merrill <jason@redhat.com>
+
+ * tree.c (get_unwidened): Decide whether to narrow a bitfield
+ reference based on TYPE_SIZE, not TYPE_PRECISION.
+
+ * stmt.c (parse_output_constraint): Warn about in-out constraint
+ that doesn't allow a register.
+ (parse_input_constraint): Warn about matching constraint that
+ doesn't allow a register.
+
+2003-12-19 James E Wilson <wilson@specifixinc.com>
+
+ * flow.c (mark_set_regs, case PARALLEL): Scan loop forwards.
+ Add case for ASM_OPERANDS.
+ * global.c (global_alloc): Set regs_ever_live for regs_asm_clobbered
+ registers.
+
+2003-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * expr.c (check_max_integer_computation_mode): Remove.
+ * dojump.c (do_jump): Don't use MAX_INTEGER_COMPUTATION_MODE.
+ * fold-const.c (fold): Likewise.
+ * system.h (MAX_INTEGER_COMPUTATION_MODE): Poison.
+ * doc/tm.texi (MAX_INTEGER_COMPUTATION_MODE): Remove.
+
+2003-12-19 James E Wilson <wilson@specifixinc.com>
+
+ * configure.in: Delete libunwind_has_eh_support test.
+ * configure: Regenerate.
+ * config.gcc (ia64*-*-linux*): Delete reference to t-libunwind-no-eh
+ and libunwind_has_eh_support check.
+ * config/t-libunwind-no-eh: Delete.
+
+2003-12-19 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-format.c (print_char_table): Allow 'I' flag on floating point
+ decimal formats.
+
+2003-12-19 Stuart Hastings <stuart@apple.com>
+
+ * gcc/config/i386/i386.c (ix86_expand_call, x86_output_mi_thunk):
+ Trivial fixes for i386.c on Darwin/x86.
+
+2003-12-19 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (legitimate_lo_sum_address_p): Add code to
+ recognize macho-style lo_sum adrress patterns.
+
+2003-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * dwarfout.c: Remove uses of "register" specifier in
+ declarations of arguments and local variables.
+ * gensupport.c: Likewise.
+ * local-alloc.c: Likewise.
+ * regclass.c: Likewise.
+
+2003-12-19 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * config.guess: Remove.
+
+2003-12-19 Jakub Jelinek <jakub@redhat.com>
+
+ * config/ia64/unwind-ia64.c (ia64_copy_rbs): New function.
+ (unw_access_gr): Only call ia64_rse_rnat_addr if addr is above
+ regstk_top.
+ (uw_frame_state_for): Handle locations inside bundles.
+ (uw_init_context_1): Initialize context->rnat.
+ Set context->regstk_top to lowest rbs address which has nat collection
+ in context->rnat.
+ (uw_install_context): Fix rnat restoring.
+ Restore ar.rsc to previous state.
+ * config/ia64/linux.h (MD_FALLBACK_FRAME_STATE_FOR,
+ MD_HANDLE_UNWABI): Handle unwinding through SA_ONSTACK frames.
+
+2003-12-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/13239
+ * builtins.c (expand_builtin_expect_jump): Update
+ TREE_VALUE (arglist) if unsave_expr_now langhook
+ created a new tree.
+
+2003-12-19 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (thumb_base_register_rtx_p): Use regno in comparison against
+ FIRST_PSEUDO_REGISTER.
+
+2003-12-18 Hartmut Penner <hpenner@de.ibm.com>
+
+ * gcc/config/rs6000/rs6000.c (USE_ALTIVEC_FOR_ARG_P): Don't check
+ for SVR4 ABI.
+
+2003-12-18 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/aix.h (OS_MISSING_POWERPC64): Define.
+ (OS_MISSING_ALTIVEC): Define.
+ * config/rs6000/darwin.h (ASM_SPEC): Be generous about supplying
+ -force_cpusubtype_ALL.
+ * config/rs6000/rs6000.c (rs6000_override_options): Rearrange
+ CPU information table; now always set all CPU-specific values.
+ Also, use Altivec and powerpc64 when chip and OS supports them.
+
+2003-12-18 Geoffrey Keating <geoffk@apple.com>
+
+ * fixinc/inclhack.def (darwin_macho_dyldh): New.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-12-18 Dara Hazeghi <dhazeghi@yahoo.com>
+
+ * version.c (version_string): Renumber as 3.4.0
+ * doc/include/gcc-common.texi: Likewise
+
+2003-12-18 Richard Henderson <rth@redhat.com>
+
+ * genrecog.c (print_host_wide_int): New.
+ (write_switch, write_cond): Use it.
+
+2003-12-18 Richard Henderson <rth@redhat.com>
+
+ * c-decl.c (check_bitfield_type_and_width): Remove enum special
+ case suppression of pedwarn.
+ * system.h (ENUM_BITFIELD): Use __extension__.
+ (CHAR_BITFIELD): Likewise.
+
+2003-12-18 Ulrich Weigand <uweigand@de.ibm.com>
+ Mark Dettinger <dettinge@de.ibm.com>
+
+ * config/s390/s390.md (UNSPEC_SRST): New constant.
+ ("strlendi", "strlensi"): New expanders.
+ ("*strlendi", "*strlensi"): New insns.
+
+2003-12-18 Mark Mitchell <mark@codesourcery.com>
+
+ * config/sol2.h (LINK_ARCH32_SPEC): Define in terms of ...
+ (LINK_ARCH32_SPEC_BASE): ... this new macro.
+ * config/sparc/sol2-bi.h (LINK_ARCH64_SPEC): Define in terms of
+ ...
+ (LINK_ARCH64_SPEC_BASE): ... this new macro.
+ * config/sparc/sol2-gld-bi.h (LINK_ARCH32_SPEC): New macro.
+ (LINK_ARCH64_SPEC): Likewise.
+
+2003-12-18 Jason Merrill <jason@redhat.com>
+
+ PR middle-end/13234
+ * tree-dump.c (dequeue_and_dump): Handle 'r' and 's' code
+ classes.
+
+2003-12-18 Steven Bosscher <stevenb@suse.de>
+
+ * Makefile.in (tracer.o, bb-reorder.o): Depend on timevar.h
+ * toplev.c (rest_of_handle_reorder_blocks, rest_of_handle_tracer):
+ Don't push and pop TV_REORDER_BLOCKS timevars, do it...
+ * bb-reorder.c (reorder_basic_blocks): ...here, and...
+ * tracer.c (tracer): here.
+
+2003-12-18 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * loop.c (move_movables): Handle combination of m->consec,
+ m->move_insn_first, and m->insert_temp all nonzero correctly.
+
+2003-12-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * calls.c (load_register_parameters): Don't use
+ LOAD_ARGS_REVERSED.
+ * system.h (LOAD_ARGS_REVERSED): Poison.
+ * doc/tm.texi (LOAD_ARGS_REVERSED): Remove.
+
+2003-12-17 Per Bothner <per@bothner.com>
+
+ * emit-rtl.c (set_new_first_and_last_label_num): Remove function.
+ * rtl.h (set_new_first_and_last_label_num): Remove declaration.
+
+2003-12-17 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/frv/frv.c (frv_ifcvt_modify_insn): Don't leave alone
+ scratch insns of the then branch that clobber regs needed by the
+ else branch.
+
+2003-12-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * calls.c (expand_call): Update comments.
+ * system.h (PRETEND_OUTGOING_VARARGS_NAMED): Poison.
+ * targhooks.c: Do not refer to PRETEND_OUTGOING_VARARGS_NAMED.
+
+2003-12-17 James E Wilson <wilson@specifixinc.com>
+ Roger Sayle <roger@eyesopen.com>
+
+ * Makefile.in (gcse.o): Add $(TREE_H) to dependencies.
+ * gcse.c: Include tree.h.
+ (implicit_set_cond_p): New.
+ (find_implicit_sets): Call it.
+
+2003-12-17 Santiago Vila <sanvila@unex.es>
+
+ * config/kfreebsdgnu.h (TARGET_OS_CPP_BUILTINS): Rename from
+ TARET_OS_CPP_BUILTINS.
+
+2003-12-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * emit-rtl.c: Fix signed/unsigned comparison warnings.
+
+2003-12-17 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * predict.c (struct block_info_def, struct edge_info_def): Change
+ bit-fields of width 1 to unsigned int.
+
+2003-12-16 Geoffrey Keating <geoffk@apple.com>
+
+ PR 12480
+ * c-pch.c (pch_init): Improve error message when precompiled
+ header can't be written.
+
+ PR 12606
+ * c-pch.c (pch_init): Make a PCH file appear invalid while it's
+ being written.
+ (c_common_write_pch): Make it valid once it's done.
+
+2003-12-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR target/11992
+ * config/s390/s390.md ("*cmpmem_long_64"): Use CLCLE instruction
+ instead of CLCL.
+ ("*cmpmem_long_31"): Likewise.
+
+2003-12-17 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/ia64/ia64.c: Add more comments about insn bundling.
+
+2003-12-17 Richard Earnshaw <rearnsha@arm.com>
+
+ PR optimization/10592
+ * caller-save.c (mark_referenced_regs): Don't short-circuit a reg
+ or subreg in SET_DEST if it isn't a hard register.
+
+2003-12-17 David Edelsohn <edelsohn@gnu.org>
+
+ * collect2.c (main): Add -fno-profile-arcs -fno-test-coverage
+ -fno-branch-probabilities to arguments when compiling ctors and
+ dtors.
+
+2003-12-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sol2.h: Set SUPPORTS_INIT_PRIORITY to 0.
+ * config/sparc/sol2-gld.h: Set SUPPORTS_INIT_PRIORITY to 1.
+
+2003-12-17 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (thumb_base_register_rtx_p): Don't allow virtual registers
+ as base registers for sub-word operations.
+ (thumb_legitimate_address_p): Simplify REG+REG test.
+
+2003-12-17 Segher Boessenkool <boessen@de.ibm.com>
+
+ * opts.c (wrap_help): Fix overflow.
+
+2003-12-17 Fred Fish <fnf@redhat.com>
+
+ * configure.in: Remove code to examine linker scripts and set
+ HAVE_MIPS_LIBGLOSS_STARTUP_DIRECTIVES.
+ * configure, config.in: Regenerate.
+
+2003-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12218
+ * varasm.c (initializer_constant_valid_p): Allow a conversion from
+ an integral constant to an OFFSET_TYPE.
+
+2003-12-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/11012
+ * config/m32r/m32r.c (gen_compare): Call gen_addsi3 instead of
+ gen_cmp_ne_small_const_insn.
+ * config/m32r/m32r.md (cmp_ne_small_const_insn): Remove.
+
+2003-12-17 Neil Booth <neil@daikokuya.co.uk>
+ Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/3347
+ * c-decl.c (enum_decl_context): Remove BITFIELD.
+ (grokdeclarator): Take bit-field width as an input.
+ Perform bit-field width validation with
+ check_bitfield_type_and_width rather than waiting for
+ finish_struct.
+ (groktypename, groktypename_in_parm_context, start_decl,
+ push_parm_decl, grokfield, start_function): Update calls to
+ grokdeclarator.
+ (check_bitfield_type_and_width): New function.
+ (finish_struct): Move bit-field validation to grokdeclarator
+ and check_bitfield_type_and_width.
+
+2003-12-16 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR bootstrap/13386
+ * configure.in (gcc_cv_ld_hidden): Set to yes on hppa64*-*-hpux* when
+ using HP native linker.
+ * configure: Rebuilt.
+
+2003-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13275
+ * c-common.h (enum rid): Add RID_OFFSETOF.
+ * c-parser.in (rid_to_yy): Ignore RID_OFFSETOF.
+ * ginclude/stddef.h (offsetof): Reimplement for C++, using
+ __offsetof__.
+ * doc/extend.texi: Document __offsetof__.
+
+2003-12-16 Stan Cox <scox@redhat.com>
+
+ * config/iq2000/iq2000.h: Formatting.
+ (MAX_INT_TYPE_SIZE, MAX_INT_TYPE_SIZE, CONST_COSTS, RTX_COSTS)
+ (ADDRESS_COST, ASM_OUTPUT_INTERNAL_LABEL, ASM_OUTPUT_INTERNAL_LABEL)
+ (IMPLICIT_FIX_EXPR, EASY_DIV_EXPR, SLOW_ZERO_EXTEND): Remove
+ * config/iq2000/iq2000.c: Formatting.
+ (iq2000_rtx_costs): New.
+
+2003-12-16 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (addsi3_carryin_shift): Add missing register constraints.
+
+2003-12-16 Loren James Rittle <ljrittle@acm.org>
+
+ * testsuite/g++.old-deja/g++.eh/badalloc1.C: Tweak to
+ pass with -pthread on FreeBSD systems.
+
+2003-12-16 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_file_end): Only write symbols that have
+ been referenced at some point.
+
+2003-12-16 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c: Include langhooks.h
+ (mips_build_builtin_va_list): Use lang_hooks.types.make_type.
+
+2003-12-16 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/13313
+ * combine.c (make_extraction) [REG]: Do not use
+ gen_lowpart_for_combine when POS is non-zero.
+
+2003-12-16 Hartmut Penner <hpenner@de.ibm.com>
+
+ * altivec.h (vec_cmple, vec_all_numeric): Fix typo.
+ * testsuite/gcc.dg/altivec-10.c: Test for above.
+
+2003-12-15 David O'Brien <obrien@FreeBSD.org>
+
+ * Makefile.in (CPPFLAGS): Initialize from configure.
+
+2003-12-15 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/13400
+ * ifcvt.c (noce_process_if_block): Disable unconditional write
+ optimizations if we could introduce a store to trapping memory
+ that wasn't present previously.
+
+2003-12-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * system.h (DEFAULT_CALLER_SAVES): Poison.
+ * toplev.c (flag_caller_saves): Always initialize with 0.
+ * doc/tm.texi (DEFAULT_CALLER_SAVES): Remove.
+
+2003-12-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * flow.c (EXIT_IGNORE_STACK): Move to ...
+ * defaults.h (EXIT_IGNORE_STACK): ... here.
+ * dojump.c (clear_pending_stack_adjust): Don't use #ifdef
+ EXIT_IGNORE_STACK.
+ * function.c (expand_function_end): Likewise.
+ * global.c (global_alloc): Likewise.
+ * ra.c (init_ra): Likewise.
+ * reload1.c (init_elim_table): Likewise.
+ * reorg.c (fill_simple_delay_slots): Likewise.
+ * resource.c (init_resource_info): Likewise.
+ * doc/tm.texi (EXIT_IGNORE_STACK): Document that the default
+ is 0.
+
+2003-12-15 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * reload.c (reg_overlap_mentioned_for_reload_p):
+ When looking at a PLUS in X, avoid spuriously returning nonzero
+ when IN is a REG or another simple PLUS, or a MEM containing one.
+
+ * loop.c (loop_invariant_p): Amend comment about where new registers
+ might come from.
+
+2003-12-15 Andreas Jaeger <aj@suse.de>
+
+ * config/rs6000/rs6000.c (rs6000_output_function_epilogue): Remove
+ handling of obsolete language CHILL.
+
+2003-12-15 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ * tree.c (initializer_zerop): Add test for empty set.
+ * integrate.c (function_cannot_inline_p): Forbid inlining
+ functions calling `longjmp'.
+
+2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11773
+ * doc/gcov.texi (Gcov and Optimization): Document inline function
+ behaviour. Fix some file suffixes.
+
+2003-12-14 David O'Brien <obrien@FreeBSD.org>
+
+ * config/i386/i386.h (__amd64, __amd64__): Remove duplicates.
+
+2003-12-14 Mark Mitchell <mark@codesourcery.com>
+
+ * c-common.h (c_parse_error): Declare it.
+ * c-common.c (c_parse_error): New function.
+ * c-parse.y (yyerror): Use it.
+
+2003-12-14 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR target/13054
+ * pa-protos.h (indexed_memory_operand, borx_reg_operand,
+ move_dest_operand, move_src_operand): New protypes.
+ (basereg_operand, move_operand, reg_or_nonsymb_mem_operand): Deleted.
+ * pa.c (copy_reg_pointer, indexed_memory_operand, move_dest_operand,
+ move_src_operand): New functions.
+ (basereg_operand, reg_or_nonsymb_mem_operand, move_operand): Delete.
+ (reg_or_0_or_nonsymb_mem_operand): Return false for unscaled indexed
+ address until cse is not expected on targets with non-equivalent
+ space registers.
+ (hppa_legitimize_address): Canonicalize unscaled indexed addresses
+ on targets non-equivalent space registers.
+ (emit_move_sequence): Break out indexed addresses from destination
+ operand. Similarly, break out unscaled indexed addresses from
+ source operand on targets with non-equivalent space registers. Fix
+ REG_POINTER flag when possible. Mark register pointer when creating
+ new pointers.
+ (print_operand): Handle unscaled index addresses.
+ * pa.h (IS_INDEX_ADDR_P, IS_LO_SUM_DLT_ADDR_P): New macro subroutines
+ for EXTRA_CONSTRAINT.
+ (EXTRA_CONSTRAINT): Rework to make more readable.
+ (MODE_OK_FOR_SCALED_INDEXING_P, MODE_OK_FOR_UNSCALED_INDEXING_P): New
+ subroutines for GO_IF_LEGITIMATE_ADDRESS.
+ (GO_IF_LEGITIMATE_ADDRESS): Rework using new subroutines. Allow scaled
+ and unscaled addresses. Canonicalize unscaled indexed addresses on
+ targets with non-equivalent space registers. Document issues in
+ handling indexed address modes on PA-RISC.
+ (PREDICATE_CODES): Update for new and deleted predicates.
+ * pa.md (move_dest_operand, move_src_operand, indexed_memory_operand):
+ Use new predicates in move patterns.
+ Add peephole2 patterns to optimize floating point stores. Fix
+ constrain preferencing in move patterns. Delete patterns for handling
+ unscaled indexed memory loads. Add missing load and store with
+ base-register modification patterns. Correct SFmode floating point
+ store pattern. Add missing zero extension loads.
+
+2003-12-13 Steven Bosscher <stevenb@suse.de>
+
+ * ggc-zone.c (struct alloc_zone): Don't pre-declare, it already
+ comes in with ggc.h. Add a new bool field `dead'.
+ (destroy_ggc_zone): Don't destroy a zone at once. Instead, only
+ set the `dead' flag for the dead zone. Wrap a sanity check in
+ ENABLE_CHECKING.
+ (ggc_collect_1): Always mark and sweep if a zone has the `dead'
+ flag set.
+ (ggc_collect): Free dead zones after collecting.
+
+2003-12-13 Jan Hubicka <jh@suse.cz>
+
+ * coverage.c (get_coverage_counts): Use inform instead of warning
+ about missing profile.
+
+2003-12-12 Steven Bosscher <stevenb@suse.de>
+
+ * Makefile.in (opts.o, explow.o): Depend on langhooks.h
+
+2003-12-12 Geoffrey Keating <geoffk@apple.com>
+
+ * config.gcc <i[34567]86-*-darwin*>: Don't use fixproto.
+ <powerpc-*-darwin*>: Likewise.
+
+2003-12-12 Jakub Jelinek <jakub@redhat.com>
+
+ * config/ia64/linux.h (IA64_GATE_AREA_END): Increase by 64K.
+ (MD_FALLBACK_FRAME_STATE_FOR): Set fpsr_loc, br_loc[6] and
+ br_loc[7]. Update comment.
+ (MD_HANDLE_UNWABI): Define.
+ * config/ia64/unwind-ia64.c (struct unw_state_record): Add
+ unwabi field.
+ (struct _Unwind_Context): Increase br_loc array size to 8 entries.
+ (desc_abi): Set unwabi.
+ (uw_update_reg_address): Allow br up to 7.
+ (uw_update_context): Invoke MD_HANDLE_UNWABI if defined.
+ (uw_install_context): Load b1..b5 from correct locations.
+ Fix insn loading ar.fpsr.
+ * doc/tm.texi: Document MD_HANDLE_UNWABI.
+
+2003-12-12 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/13037
+ * loop.c (update_giv_derive): Ignore redundant sets of a biv when
+ calculating how to derive a giv from a biv.
+
+2003-12-12 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/12935 preprocessor/12952 preprocessor/13046
+ * cpplib.c (prepare_directive_trad): Clear skipping only in
+ #if and #elif directives.
+ (do_undef): Call the handler even if the identifier is not a macro.
+ * cpptrad.c (scan_parameters): Emit an error message.
+ (_cpp_create_trad_definition): Remember the params list even on
+ failure.
+
+2003-12-11 Zack Weinberg <zack@codesourcery.com>
+
+ * arm.c (ARM_ADDRESS_COST, THUMB_ADDRESS_COST): Convert macros
+ to inline functions: arm_arm_address_cost, arm_thumb_address_cost
+ respectively.
+ (arm_address_cost): Use 'em.
+
+2003-12-12 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/alpha/osf.h (TARGET_OS_CPP_BUILTINS): Define
+ __STDC_VERSION__ to ISO C94 for C++.
+
+ * fixinc/inclhack.def (alpha_wchar): New fix.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/wchar.h: New file.
+
+2003-12-11 David Mosberger <davidm@hpl.hp.com>
+
+ * unwind-libunwind.c (_Unwind_SetGR): Clear the NaT bit as
+ required by C++ ABI for Itanium.
+ * config/t-libunwind (LIB2ADDEH): Remove unwind-libunwind.c.
+ * config/t-libunwind-no-eh: New file.
+ * configure.in: Check libunwind for _Unwind_Resume() and if it's
+ present, set libunwind_has_eh_support to "yes".
+ * configure: Regenerate.
+ * config.gcc (ia64*-*-linux*): If $libunwind_has_eh_support is
+ set to yes, use t-libunwind, otherwise, use t-libunwind-no-eh.
+
+2003-12-11 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_global_pointer): Force functions with
+ a nonlocal goto to set up $gp.
+
+2003-12-11 James E Wilson <wilson@specifixinc.com>
+
+ PR target/13132
+ * function.c (gen_mem_addressof): When no decl, explicitly clear flag
+ bits.
+
+2003-12-12 Nick Clifton <nickc@redhat.com>
+
+ * config/m32r/m32r.c: Convert to ISO-C
+
+2003-12-12 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * doc/invoke.texi: Replace Mitsubishi with Renesas.
+ * config/m32r/m32r.h: Ditto.
+ * config/m32r/m32r.c: Ditto.
+ * config/m32r/m32r.md: Ditto.
+
+2003-12-11 Steven Bosscher <steven@gcc.gnu.org>
+
+ * basic-block.h (BLOCK_HEAD, BLOCK_END): Remove.
+ (BLOCK_HEAD_TREE, BLOCK_END_TREE): Remove.
+ (basic_block_def): Rename `head' to `head_' and `end' to `end_'.
+ (BB_HEAD, BB_END): New accessor macros for the `head_' and `end_'
+ fields of a basic block.
+ * bb-reorder.c, bt-load.c, caller-save.c, cfg.c, cfganal.c,
+ cfgbuild.c, cfgcleanup.c, cfglayout.c, cfgloop.c, cfgloopanal.c,
+ cfgloopmanip.c, cfgrtl.c, combine.c, conflict.c, df.c, emit-rtl.c,
+ final.c, flow.c, function.c, gcse.c, global.c, graph.c,
+ haifa-sched.c, ifcvt.c, lcm.c, local-alloc.c, loop-unswitch.c,
+ loop.c, postreload.c, predict.c, profile.c, ra-build.c, ra-debug.c,
+ ra-rewrite.c, ra.c, recog.c, reg-stack.c, regclass.c, regmove.c,
+ regrename.c, reload1.c, resource.c, sched-ebb.c, sched-rgn.c,
+ sibcall.c, tracer.c, config/frv/frv.c, config/i386/i386.c,
+ config/ia64/ia64.c: Use the BB_HEAD and BB_END macros instead of
+ accessing the `head' and `end' fields of a basic block directly.
+
+ * gengtype.c: Teach about "void**" pointers and "void *" function
+ types. Fixes earlier commit.
+
+2003-12-10 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/extend.texi (Vector Extensions): Document that bitwise
+ operations also work on vectors.
+
+2003-12-10 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md: New split patterns for optimizing bitfield accesses.
+
+2003-12-10 Steven Bosscher <stevenb@suse.de>
+
+ * README.Portability: Remove K+R section.
+
+ * gengtype-lex.l: Teach about "void**" pointers and
+ "void*" function types.
+
+2003-12-10 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/13354
+ * config/sparc/sparc.c (sparc_output_mi_thunk): Load DELTA
+ manually if one can do that with only one instruction.
+
+2003-12-10 Nick Clifton <nickc@redhat.com>
+
+ * config.gcc (arm-linux): Include linux.h in tm_file so that
+ LINUX_TARGET_OS_CPP_BUILTINS is defined.
+ * config/arm/linux-elf.h (LIB_SPEC): Protect the definition.
+
+2003-12-09 James E Wilson <wilson@specifixinc.com>
+
+ * rtl.def (CODE_LABEL, NOTE): Correct operand numbers in comments.
+
+2003-12-09 Matt Austern <austern@apple.com>
+
+ PR c/13134
+ * c-decl.c (duplicate_decls): Copy visibility flag when appropriate.
+
+2003-12-09 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/m32r/m32r.h: Add support for m32r2 processor. Including
+ a new command line option -m32r2 to select it.
+ * config/m32r/m32r.c: Add support for the new processor variant.
+ * config/m32r/m32r.md: Likewise.
+ * config/m32r/t-m32r: Add m32r2 multilibs.
+ * doc/invoke.texi: Document the new command line switch.
+
+2003-12-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * defaults.h (LOCAL_REGNO): Give the default definition.
+ * flow.c (LOCAL_REGNO): Remove.
+ * reload1.c (LOCAL_REGNO): Likewise.
+
+2003-12-08 Geoffrey Keating <geoffk@apple.com>
+
+ PR target/11848
+ * rs6000.h (CANNOT_CHANGE_MODE_CLASS): Allow change of mode
+ in floating-point registers between TFmode and DImode.
+ * rs6000.c (rs6000_emit_move): Split moves early.
+ (secondary_reload_class): Random Whitespace Change.
+ (rs6000_split_multireg_move): Support moves involving FP registers.
+ Emit instructions directly.
+ * rs6000-protos.h (rs6000_split_multireg_move): Update prototype.
+ * altivec.md: Update for changes to rs6000_split_multireg_move.
+ * rs6000.md: Update for changes to rs6000_split_multireg_move.
+ (movtf_internal): Support moves to/from GPRs.
+
+2003-12-08 Stuart Hastings <stuart@apple.com>
+
+ * config/i386/i386.md: Typo in split of fp-valued if_then_else.
+
+2003-12-08 James E Wilson <wilson@specifixinc.com>
+
+ PR target/13132
+ * expmed.c (extract_bit_field): Only call mode_for_size for scalar
+ integer modes.
+
+2003-12-08 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * doc/install.texi: Revert change of Dec 7; gcc is still a 2.13
+ directory.
+
+2003-12-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/frv/frv.md (subdi2): Merge with _internal insn_and_split,
+ by using match_scratch.
+ (negdi2): New.
+
+2003-12-08 Jason Merrill <jason@redhat.com>
+ Daniel Berlin <dberlin@dberlin.org>
+
+ PR debug/11114
+ Support namespaces in DWARF 2 output.
+ * dwarf2out.c (gen_namespace_die): New function.
+ (force_namespace_die, setup_namespace_context): New fns.
+ (declare_in_namespace): New fn.
+ (gen_decl_die): Call declare_in_namespace. Handle namespaces.
+ (dwarf2out_decl): Handle namespaces.
+ (scope_die_for): Pass through a namespace scope.
+ (class_scope_p): Rename to class_or_namespace_scope_p.
+ (gen_subprogram_die, gen_variable_die): Adjust.
+ (gen_struct_or_union_die): Always emit a declaration
+ if context_die is a namespace.
+
+2003-12-08 Jan Hubicka <jh@suse.cz>
+
+ * unwind-pe.h (read_uleb128): Fix handling of large values
+ (read_sleb128): Fix handling of large values
+
+2003-12-08 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR middle-end/10060
+ * emit-rtl.c (copy_rtx_if_shared): Split out into ...
+ (copy_rtx_if_shared_1): here and optimize the last one
+ in the sequence into tail-recursion.
+ (reset_used_flags): Optimize the last one
+ in the sequence into tail-recursion.
+
+2003-12-08 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md: New split to transform ((X << y) - 1) into ~(~(X-1) << y)
+ for constant X.
+
+2003-12-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * calls.c (expand_call): Don't try using tail or recursive calls
+ after the function body has been expanded.
+
+2003-12-08 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (cmpstr expander): Obey TARGET_INLINE_ALL_STRINGOPS
+
+2003-12-08 Arnaud Charlet <charlet@act-europe.fr>
+
+ PR ada/13324, PR ada/12614
+ * doc/install.texi: Update requirements for building Ada.
+
+2003-12-07 David Edelsohn <edelsohn@gnu.org>
+ Graham Reed <greed@pobox.com>
+
+ * collect2.c (GCC_OK_SYMBOL): Add support for AIX C_WEAKEXT.
+ (GCC_UNDEF_SYMBOL): Same.
+
+2003-12-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * final.c (final_scan_insn): Don't use FINAL_PRESCAN_LABEL.
+ * system.h (FINAL_PRESCAN_LABEL): Poison.
+ * doc/tm.texi (FINAL_PRESCAN_LABEL): Remove.
+
+2003-12-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (compare): Combine toplevel and $(SUBDIRS) cases.
+
+2003-12-07 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in, aclocal.m4: Revert to pre-2.5x conversion status.
+ * configure: Regenerate with autoconf 2.13.
+
+ * configure.in: Replace AC_INIT, AC_OUTPUT, AC_CANONICAL_SYSTEM
+ with modern equivalents.
+ * configure: Regenerate.
+
+ * configure.in: Replace gcc_AC_CHECK_TYPE with AC_CHECK_TYPE.
+ * aclocal.m4 (gcc_AC_CHECK_TYPE): Remove.
+ * configure: Regenerate.
+
+ * configure: Regenerate with (preferred) autoconf 2.57.
+ * doc/install.texi: Note that 'gcc' is now a 2.57 directory.
+
+2003-12-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/12965
+ * caller-save.c (save_call_clobbered_regs): Do not save/restore
+ registers around no-return calls.
+
+2003-12-07 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Make minimum necessary changes for autoconf 2.5x.
+ * aclocal.m4: Make minimum necessary changes for autoconf 2.5x.
+ * configure: Regenerate with autoconf 2.58.
+
+2003-12-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/13318
+ * loop.c (express_from): Protect integer division from overflow.
+
+2003-12-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/13060
+ * function.c (fixup_var_refs_1) [SUBREG]: Recognize even if a
+ replacement already exists. Fix again the whole insn if that fails.
+
+2003-12-06 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/rs6000.c (macho_branch_islands): Use
+ HOST_WIDE_INT_PRINT_UNSIGNED.
+
+2003-12-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * varasm.c (incorporeal_function_p): New.
+ (assemble_external): Use it as a filter.
+ * config/mips/mips.c (mips_output_external): Don't check for builtin
+ functions here.
+
+2003-12-06 Richard Earnshaw <reanrsha@arm.com>
+
+ * arm.md (IOR (COMPARISON) (AND)): New define_splits.
+
+2003-12-06 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (program_transform_cross_name): Delete.
+ (GCC_CROSS_NAME, CPP_CROSS_NAME): Delete.
+ (PROTOIZE_CROSS_NAME, UNPROTOIZE_CROSS_NAME): Delete.
+ (AR_FOR_TARGET, RANLIB_FOR_TARGET, NM_FOR_TARGET): Adjust for above.
+ (install_cpp, install_driver, install-man, uninstall): Likewise.
+
+2003-12-06 Alan Modra <amodra@bigpond.net.au>
+
+ PR 13169
+ * basic-block.h (PROP_ASM_SCAN): Define.
+ * final.c (regs_asm_clobbered): New array.
+ * regs.h (regs_asm_clobbered): Declare.
+ * flow.c (life_analysis): Init it.
+ (mark_set_regs): Set PROP_ASM_SCAN for asms.
+ (mark_set_1): Set regs_asm_clobbered.
+ * global.c (global_alloc): Don't set eliminable_regset when
+ regs_asm_clobbered.
+
+2003-12-05 Mark Mitchell <mark@codesourcery.com>
+
+ * config/ia64/ia64.h (MUST_PASS_IN_STACK): Define.
+
+ PR c++/13314
+ * emit-rtl.c (set_mem_attributes_minus_bitpos): Robustify.
+
+2003-12-05 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR driver/13211
+ * gcc.c (execute) Increment execution_count when returning
+ early because verbose_only_flag is true.
+
+2003-12-05 Per Bothner <pbothner@apple.com>
+
+ * cppfiles.c (file_hash_hash): New static function.
+ (hash_string_eq): Renamed static function to file_hash_eq.
+ (_cpp_init_files): Create file_hash table with above callbacks.
+ (cpp_included): Must use htab_find_with_hash insead of htab_find.
+ (_cpp_find_find, make_cpp_dir): Must use htab_find_slot_with_hash.
+
+2003-12-05 Per Bothner <pbothner@apple.com>
+
+ * line-map.h (source_location): New typedef.
+ (fileline): Redefined as source_location.
+ (struct line_map, linemap_add, linemap_lookup): Replace filefile
+ by source_location.
+ * line-map.c (linemap_add, linemap_lookup): Use source_location.
+
+2003-12-05 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_build_builtin_va_list): Add dummy
+ field to suppress -Wpadded warnings.
+
+2003-12-05 Stuart Hastings <stuart@apple.com>
+
+ * config/rs6000/rs6000.md: Correct macro test of TARGET_MACHO.
+
+2003-12-05 Stuart Menefy <stuart.menefy@st.com>
+ J"orn Rennecke <joern.rennecke@superh.com>
+
+ PR target/13302
+ * sh.c (sh_build_builtin_va_list): Use (*lang_hooks.types.make_type).
+
+2003-12-05 Roger Sayle <roger@eyesopen.com>
+
+ * dojump.c (do_jump): If the expression being compared against
+ zero, is the subreg of a promoted variable, perform the comparison
+ in the promoted mode.
+ * simplify-rtx.c (simplify_unary_operation): Optimize sign and
+ zero-extensions of subregs of promoted variables where the
+ extension is identical to that used to promote the variable.
+
+2003-12-05 Hans-Peter Nilsson <hp@axis.com>
+
+ PR target/13256
+ * resource.h (enum mark_resource_type): Remove member MARK_DEST.
+ The only user changed as follows:
+ * resource.c (mark_set_resources) <case SET>: Always recurse for
+ SET_SRC (x).
+ <case SIGN_EXTRACT, case ZERO_EXTRACT>: Always recurse on
+ operands.
+ <case STRICT_LOW_PART>: Delete, deferring to default code.
+
+2003-12-05 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ * stmt.c (expand_nl_goto_receiver): Copy hard register clobbers
+ and ASM_INPUT barrier from expand_builtin_setjmp_receiver.
+
+2003-12-05 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_expand_call): Don't allow laziy binding
+ for n32 & n64 abicalls.
+
+2003-12-05 Richard Sandiford <rsandifo@redhat.com>
+
+ PR bootstrap/13145
+ * config/mips/mips.h (FIRST_PSEUDO_REGISTER): Adjust comment.
+ * config/mips/mips.c (mips_reg_names, mips_sw_reg_names): Add $fcall.
+ (mips_load_got): Always create a constant MEM.
+ (mips_expand_call): Use load_callsi and load_calldi.
+ * config/mips/mips.md (UNSPEC_LOAD_CALL, FAKE_CALL_REGNO): New consts.
+ (load_callsi, load_calldi): New patterns.
+
+2003-12-05 Peter Gerwinski <peter@gerwinski.de>
+
+ * tree.def (PLACEHOLDER_EXPR): Clarify commentary.
+
+2003-12-05 Steven Bosscher <stevenb@suse.de>
+
+ * config/d30v/d30v-protos.h , config/d30v/d30v.c,
+ config/dsp16xx/dsp16xx-protos.h, config/dsp16xx/dsp16xx.c,
+ config/fr30/fr30-protos.h, config/fr30/fr30.c,
+ config/i370/i370-protos.h, config/i370/i370.c,
+ config/i960/i960-protos.h, config/i960/i960.c,
+ config/ip2k/ip2k-protos.h, config/ip2k/ip2k.c,
+ config/m32r/m32r-protos.h, config/m32r/m32r.c,
+ config/mn10300/mn10300-protos.h, config/mn10300/mn10300.c,
+ config/ns32k/ns32k-protos.h, config/ns32k/ns32k.c:
+ Convert to ISO C90 function declarations and definitions.
+
+2003-12-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/extend.texi (Constructing Calls): Add warning about
+ the limitations of the functions.
+
+2003-12-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR middle-end/11151
+ * function.h (struct function): New field 'x_naked_return_label'.
+ * function.c (free_after_compilation): Set it to NULL.
+ (expand_function_end): Emit 'naked_return_label' if it exists.
+ * rtl.h (expand_naked_return): Declare.
+ * stmt.c (expand_naked_return): New function to generate a
+ jump to 'naked_return_label'.
+ * builtins.c (expand_builtin_return): Call expand_naked_return
+ instead of expand_null_return.
+ * config/sparc/sparc.md (untyped_return): Likewise.
+
+2003-12-04 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/11322
+ * config/sh/netbsd-elf.h (NO_PROFILE_COUNTERS): Define.
+
+ PR target/12467
+ * config/rs6000/altivec.md (altivec_vmsummbm): Fix typo.
+
+2003-12-04 Stuart Hastings <stuart@apple.com>
+
+ * rs6000.c (output_call, macho_branch_islands,
+ add_compiler_branch_island, no_previous_def, get_previous_label)
+ Revisions of xx_stub functions for branch islands,
+ add -fPIC support for Darwin.
+ * rs6000-protos.h (output_call) Prototype.
+ * rs6000.md Use output_call.
+ * invoke.texi Explain Darwin semantics of -longcall.
+ * testsuite/gcc.dg/darwin-abi-1.c Revise testcase for -longcall/jbsr.
+
+2003-12-04 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.md (addqi3_carry): Use q not r constraints.
+ (subqi3_carry): Likewise.
+
+2003-12-04 J"orn Rennecke <joern.rennecke@superh.com>
+
+ PR optimization/13260
+ * sh-protos.h (sh_expand_t_scc): Declare.
+ * sh.h (PREDICATE_CODES): Add cmpsi_operand.
+ * sh.c (cmpsi_operand, sh_expand_t_scc): New functions.
+ * sh.md (cmpsi): Use cmpsi_operand. If T_REG is compared to
+ something that is not a CONST_INT, copy it into a pseudo register.
+ (subc): Fix description of new T value.
+ (slt, sgt, sge, sgtu): Don't clobber T after rtl generation is over.
+ (sltu, sleu, sgeu): Likewise.
+ (seq, sne): Likewise. Use sh_expand_t_scc.
+
+2003-12-04 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Generalize the CONFIG_HEADERS pattern under which
+ we stamp cstamp-h.
+ * configure: Regenerate.
+
+ * configure.in: Pull AC_CHECK_HEADER call out of shell if statement
+ to avoid trouble when updating to autoconf 2.5x.
+ * configure: Regenerate (with autoconf 2.13 still).
+
+2003-12-04 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (truncdiqi2): Use andi opcode for immediate.
+ (reload_outdf+1,reload_outdf+2): Remove constraints.
+ (movv16sf_i): Fxi multiplier for SUBREG_BYTE.
+ (movv8qi_i+2): Zero-extend low byte before adding it to high byte.
+ (fipr, ftrv): Add .s suffix to opcode.
+
+2003-12-04 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/13186
+
+ Revert all of the following patch, except the addition of
+ hook_bool_machine_mode_true:
+
+ 2003-11-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * Makefile.in (targhooks.o, reload.o): Update dependencies.
+ (GTFILES): Add targhooks.c.
+ (gt-targhooks.h): New rule; depend on s-gtype.
+ * target.h (direct_pool_load_p): New hook.
+ * target-def.h (TARGET_DIRECT_POOL_LOAD_P): New macro.
+ (TARGET_INITIALIZER): Include it.
+ * targhooks.h (default_direct_pool_load_p): Declare.
+ (hook_bool_machine_mode_true): Declare.
+ * targhooks.c: Include insn-config.h, recog.h, ggc.h and
+ gt-targhooks.h.
+ (pool_symbol): New variable.
+ (default_direct_pool_load_p): New function.
+ (hook_bool_machine_mode_true): New function.
+ * reload.c: Include target.h.
+ (find_reloads): If an alternative will force a constant into memory,
+ count an extra reload if constant pool symbols are not valid
+ addresses. If an alternative uses memory to move values between
+ registers, count the move as two reloads rather than one.
+ * config/s390/s390.c (TARGET_DIRECT_POOL_LOAD_P): Define.
+ * doc/tm.texi (TARGET_DIRECT_POOL_LOAD_P): Document.
+
+2003-12-03 Mark Mitchell <mark@codesourcery.com>
+
+ * config/ia64/hpux.h (TARGET_HAVE_TLS): Define it to false.
+ * config/ia64/ia64.h (TARGET_HAVE_TLS): Define it to true if
+ HAVE_AS_TLS is true.
+ * config/ia64/ia64.c (TARGET_HAVE_TLS): Do not define it.
+
+2003-12-03 James E Wilson <wilson@specifixinc.com>
+
+ * gcc.c (init_spec): Pass -lunwind to init_gcc_specs in eh_name.
+
+ * gcc-page.c (extra_order_size_tab): Correct comment.
+
+2003-12-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (push): Call gen_push_h8300hs_advanced
+ instead of gen_push_h8300hs.
+ (pop): Call gen_pop_h8300hs_advanced instead of
+ gen_pop_h8300hs.
+ * config/h8300/h8300.h (TRAMPOLINE_SIZE): Use Pmode.
+ * config/h8300/h8300.md (*tablejump_h8300hs_advanced):
+ Tighten the predicate.
+ (*tablejump_h8300hs_normal): Tighten the predicate.
+ (push_h8300hs): Change to
+ push_h8300hs_advanced.
+ (pop_h8300hs): Change to pop_h8300hs_advanced.
+
+2003-12-03 Eric Christopher <echristo@redhat.com>
+
+ * rtl.c: Fix typo.
+ * config/mips/mips.h: Ditto. Fix formatting.
+
+2003-12-04 Ben Elliston <bje@wasabisystems.com>
+
+ * future.options: Remove. Move to gnu.org web pages.
+
+2003-12-03 Eric Christopher <echristo@redhat.com>
+
+ * c-parse.in (c_in_iteration_stmt, c_in_case_stmt): Move
+ from here...
+ * c-tree.h: to here.
+
+2003-12-03 Jan Hubicka <jh@suse.cz>
+
+ PR optimization/12324
+ * toplev.c (rest_of_decl_compilation): Do not deffer when compiling
+ in unit-at-a-time mode.
+
+2003-12-03 Jakub Jelinek <jakub@redhat.com>
+
+ * expr.c (store_constructor): Only set RTX_UNCHANGING_P for
+ read-only field if cleared is 0.
+
+2003-12-03 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Mark obsolete targets for GCC 3.4.
+
+2003-12-03 Zack Weinberg <zack@codesourcery.com>
+
+ * aclocal.m4 (AM_ICONV): Add explicit check for iconv.h.
+ * config.in, configure.in: Regenerate.
+ * cpphash.h: Check both HAVE_ICONV and HAVE_ICONV_H before
+ including iconv.h.
+
+2003-12-03 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/11229
+ * cse.c (cse_insn): Set classp using src_const_elt if
+ src_eqv_elt is NULL.
+
+2003-12-03 Richard Earnshaw <rearnsha@arm.com>
+
+ * gcse.c (reg_clear_last_set): New function.
+ (reg_set_info): If data is non-null, treat it as an sbitmap of
+ registers, set the bit for the register being set.
+ (compute_store_table): Allocate last_set_in with xcalloc. Do not
+ memset this array on each iteration. Pass reg_set_in_block[bb->index]
+ to note_stores while computing last_set_in instead of scanning
+ last_set_in after the first pass through the insns.
+ Clear last_set_in using reg_clear_last_set instead of explicitly
+ rescanning after each insn. If checking is enabled, assert that
+ last_set_in is completely zeroed after each bb has been processed.
+
+2003-12-02 Geoffrey Keating <geoffk@geoffk.org>
+
+ * df.c (df_uses_record) <MEM>: The argument of a MEM is read-only,
+ never read-write.
+ <REG>: Delete incorrect comment.
+ <SET>: Remove 'use_flags' variable.
+
+2003-12-03 David Edelsohn <edelsohn@gnu.org>
+
+ * function.c (assign_parms): Make sure parm PARALLEL combined
+ in reg is composed of more than one object and the mode really
+ produces a reg.
+
+2003-12-03 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (classify_argument): Make it 64bit clean.
+
+2003-12-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_output_external): Replace checks for
+ specific builtin-in functions with a check for DECL_BUILTIN_IN.
+
+2003-12-02 Richard Henderson <rth@redhat.com>
+
+ * rtl.h (PUT_CODE, PUT_MODE): Remove ENUM_BITFIELD cast.
+ * tree.h (TREE_SET_CODE): Likewise.
+ * recog.h (struct insn_operand_data): Move const after ENUM_BITFIELD.
+
+2003-12-02 Ben Elliston <bje@wasabisystems.com>
+
+ * dbxstclass.h: Rename from this ..
+ * xcoff.h: .. to this.
+ * xcoffout.c: Include xcoff.h.
+
+2003-12-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (GCC_CFLAGS): Add -Wold-style-definition.
+
+2003-12-01 James Lemke <jim@wasabisystems.com>
+
+ * config/arm/arm.c (arm_rtx_costs): Improve for xscale multiply.
+
+2003-12-01 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/11634
+ * recog.c (split_insn): Factor test of INSN_P and handling of
+ set_noop_p out of here into the two callers.
+ (split_all_insns): Add INSN_P test and set_noop_p handling here.
+ If deleting a no-op set after reload that has a REG_UNUSED note,
+ mark the basic block as changed and recalculate life information.
+ (split_all_insns_noflow): Add INSN_P test and set_noop_p handling
+ here.
+
+2003-12-01 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/12322
+ * gcse.c (struct ls_expr): Change type of hash_index from int to
+ unsigned int.
+ (hash_expr): Document hash_table_size parameter and wrap long line.
+ (ldst_entry): Calculate expression's hash_index and record in ptr.
+ (trim_ld_motion_mems): Use hash_index to search a single bucket
+ instead of scanning the entire hash_table. Remove the "del" local
+ variable and use the equivalent "expr == 0" instead. Change last
+ to be a pointer to the pointer to the current element, to simplify
+ and speed-up deleting from a linked list.
+
+2003-12-01 James E Wilson <wilson@specifixinc.com>
+
+ * doc/contrib.texi: Update David Mosberger.
+
+ * doc/c-tree.texi (CONSTRUCTOR): Clarify element order and handling
+ of missing fields.
+
+ PR target/8407
+ * config/ia64/ia64.c (ia64_function_arg): For single-reg HFA, call
+ gen_rtx_REG to create new reg with argument mode.
+
+2003-12-01 Steven Bosscher <stevenb@suse.de>
+
+ * ggc.h (struct alloc_zone): Move forward declaration up.
+ (new_ggc_zone): New function prototype.
+ (destroy_ggc_zone): Ditto.
+ * ggc-simple.c (new_ggc_zone): New function, does nothing.
+ (destroy_ggc_zone): Ditto.
+ * ggc-page.c (new_ggc_zone): New function, does nothing.
+ (destroy_ggc_zone): Ditto.
+ * ggc-zone.c (struct page_entry): Fix comment.
+ (ggc_alloc_typed): Use a switch statement instead of ifs.
+ (new_ggc_zone): New function to set up a new GC zone.
+ (destroy_ggc_zone): New function to remove a GC zone.
+ init_ggc): Use new_ggc_zone to set up the default zones.
+ (ggc_collect): Walk a list of zones, instead of just the
+ default zones. Report statistics using the zone name.
+
+2003-12-01 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * unroll.c (find_splittable_givs): Add missing extend_value_for_giv.
+
+2003-12-01 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/12628
+ * toplev.c (rest_of_handle_jump_bypass): Call reg_scan.
+ * regclass.c (reg_scan): Include allocate_reg_info time in
+ TV_REG_SCAN. Minor clean-ups.
+ (reg_scan_update): Minor clean-ups.
+
+2003-12-01 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config.gcc (s390x-ibm-tpf*): Add extra_parts.
+
+2003-12-01 James E Wilson <wilson@specifixinc.com>
+
+ * config/ia64/ia64.h (FUNCTION_ARG_REGNO_P): Use AR_REG_FIRST not
+ GR_ARG_FIRST.
+
+2003-12-01 Zack Weinberg <zack@codesourcery.com>
+
+ * common.opt: Remove -fgnu-linker.
+ * flags.h: Remove flag_gnu_linker.
+ * opts.c: Don't handle OPT_fgnu_linker.
+ * toplev.c: Don't initialize flag_gnu_linker.
+ Remove gnu-linker entry from f_options.
+ * config/dsp16xx/dsp16xx.h (OPTIMIZATION_OPTIONS):
+ Don't reset flag_gnu_linker.
+ * config/mips/mips.c (override_options): Likewise.
+ * doc/invoke.texi: Remove all mention of -fgnu-linker.
+
+2003-12-01 Daniel Berlin <dberlin@dberlin.org>
+
+ * ggc-zone.c (ggc_pch_write_object): Calculate object size using
+ ggc_get_size (which accounts for large objects properly).
+
+2003-12-01 Jeff Sturm <jsturm@one-point.com>
+
+ PR optimization/13024
+ * toplev.c (rest_of_handle_new_regalloc): Remove rebuild_notes
+ parameter.
+ (rest_of_handle_old_regalloc): Likewise. Add rebuild_notes
+ declaration. Rebuild jump labels following local_alloc if necessary.
+ (rest_of_compilation): Remove rebuild_label_notes_after_reload
+ declaration. Don't pass rebuild_notes parameter to
+ rest_of_handle_new_regalloc and rest_of_handle_old_regalloc.
+ Don't rebuild jump labels.
+
+2003-12-01 Jeff Law <law@redhat.com>
+
+ * flow.c (count_or_remove_death_notes_bb): New. Extracted from
+ count_or_remove_death_notes.
+ (count_or_remove_death_notes): Use EXECUTE_IF_SET_IN_SBITMAP.
+
+2003-12-01 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * builtins.c (expand_builtin_longjmp): Added two memory clobbers.
+
+2003-12-01 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * reload.c (find_reloads_address): Split addresses of type
+ (plus (plus (reg) (reg)) (const_int)) only if one register
+ is either a valid base register or else one of the stack
+ frame related registers (sp/fp/ap).
+
+2003-12-01 Steven Bosscher <stevenb@suse.de>
+
+ * function.c (update_epilogue_consts): Don't use PARAMS.
+ * rtl.h (web_main): Ditto.
+ * target.h (is_costly_dependence): Ditto
+
+2003-12-01 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR middle-end/7847
+ * expr.c (expand_expr) [normal_inner_ref]: When 'offset' is non-zero,
+ do not recheck that 'op0' is a MEM. Move comment. When testing for
+ unaligned objects, take also into account the alignment of 'op0' and
+ 'mode1' if 'op0' is a MEM.
+
+2003-12-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * doc/c-tree.texi (Function Bodies): Update HANDLER documentation.
+
+2003-12-01 Kelley Cook <kcook@gcc.gnu.org>
+
+ * doc/install.texi: Note that fastjar is built with automake 1.7.x
+ and autoconf 2.57.
+
+2003-12-01 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Test
+ target_flags directly rather than using TARGET_* defines.
+
+2003-11-30 Ben Elliston <bje@wasabisystems.com>
+
+ * doschk.c: Remove.
+
+2003-11-30 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/12727
+ * config/mips/mips.c (mips_save_reg): Fix frame information for sdc1
+ on 32-bit big-endian targets.
+
+2003-11-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genemit.c (register_constraints): Remove.
+
+2003-11-30 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.md ("tmdi_reg", "tmsi_reg", "*movdi_64", "*movdi_31",
+ "iordi3"): Insns now use multiple letter constraints.
+ ("*movdi_lhi", "*movdi_lli", "*movdi_lay"): Insns deleted. They are now
+ covered by "*movdi_64".
+ ("*movsi_lhi", "*movsi_lli", "*movsi_lay"): Insns deleted. They are now
+ covered by "*movsi_zarch" and "*movsi_esa".
+ ("*movsi_zarch", "*movsi_!zarch"): New insns.
+ ("*llgt_sisi_split", "*llgt_didi_split"): Insns deleted. Now covered
+ by "*andsi3_zarch" and "anddi3".
+ ("*anddi3_ni"): Insn merged with "anddi3".
+ ("*andsi3_ni"): Insn merged with "*andsi3_zarch".
+ ("*andsi3_zarch", "*andsi3_esa"): New insns.
+ ("*iordi3_oi"): Insn merged with "iordi3".
+ ("*iorsi3_oi"): Insn merged with "*iorsi3_zarch".
+ ("*iorsi3_zarch", "*iorsi3_esa"): New insns.
+
+ * config/s390/s390.c (s390_single_qi, s390_single_hi): Functions
+ merged to s390_single_part.
+ (s390_single_part): New function.
+ NOTE: Semantics have changed a bit. Now the value of the part must
+ be different from the others to get a non-negative return value.
+ (s390_extract_qi, s390_extract_hi): Functions merged to
+ s390_extract_part.
+ (s390_extract_part, s390_extra_constraint_str,
+ s390_const_ok_for_constraint_p): New functions. The L constraint got a
+ new meaning and the N constraint was added as a multiple letter
+ constraint.
+ (s390_extra_constraint): Function deleted.
+ (print_operand): New output modifier 'i' and 'j' added.
+ All uses of CONST_OK_FOR_LETTER_P were replaced by
+ CONST_OK_FOR_CONSTRAINT_P.
+
+ * config/s390/s390-protos.h: Function prototypes adapted.
+ * doc/md.texi: Documentation for new constraint letters added.
+
+2003-11-30 Andreas Schwab <schwab@suse.de>
+
+ * Makefile.in ($(DESTDIR)$(infodir)/%.info): Fix missing semicolon.
+
+2003-11-29 James E Wilson <wilson@specifixinc.com>
+
+ * gcc.c (init_spec): Pass -lunwind to init_gcc_specs in eh_name
+ instead of in shared_name.
+
+ * final.c (final_start_function): Delete code for NON_SAVING_SETJMP.
+ * reload1.c (reload): Re-add it here.
+
+2003-11-30 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_elf_section_type_flags): Don't
+ set SECTION_WRITE on TARGET_RELOCATABLE.
+
+2003-11-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (LIBCALL_VALUE): Use R0_REG.
+
+2003-11-28 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (MOTOROLA): Move from here...
+ * config/m68k/m68k.h (MOTOROLA): ... to here.
+ (OUTPUT_JUMP): Use do {...} while (0).
+ * config/m68k/m68k.md: Replace #ifdef MOTOROLA with C statements.
+
+2003-11-28 Gunther Nikl <gni@gecko.de>
+
+ * config.gcc (m68020-*-elf*, m68k-*-elf*, m68010-*-netbsdelf*,
+ m68k*-*-netbsdelf*, m68k-*-rtems*): Add tm_defines containing
+ MOTOROLA and USE_GAS.
+ * config/m68k/rtemself.h (MOTOROLA): Delete.
+ * config/m68k/netbsd-elf.h (MOTOROLA, USE_GAS): Delete.
+ * config/m68k/m68kelf.h (MOTOROLA, USE_GAS, SGS_CMP_ORDER): Delete.
+
+2003-11-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (WORDS_BIG_ENDIAN): Update the comment.
+
+2003-11-29 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (install-info): Install gccinstall.info too.
+
+2003-11-29 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("cmpint_di"): Fix incorrect instruction lengths.
+
+2003-11-29 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("movhi"): Do not emit extender pattern
+ when loading from a (MEM (ADDRESSOF ...)).
+ ("movqi"): Likewise.
+
+2003-11-29 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/10333
+ * c-parse.in (typespec_reserved_nonattr): Reject typeof on
+ bit-fields.
+
+2003-11-29 Richard Sandiford <rsandifo@redhat.com>
+
+ * stmt.c (expand_asm_operands): Check whether force_const_mem
+ succeeded.
+
+2003-11-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/gnu.h (HURD_TARGET_OS_CPP_BUILTINS): New.
+ * config/linux.h (LINUX_TARGET_OS_CPP_BUILTINS): New.
+
+ * config/alpha/gnu.h, config/alpha/linux.h,
+ config/arm/linux-elf.h, config/cris/cris.h, config/cris/linux.h,
+ config/i370/linux.h, config/i386/gnu.h, config/i386/i386.h,
+ config/i386/linux-aout.h, config/i386/linux.h,
+ config/i386/linux64.h, config/ia64/linux.h, config/m68k/linux.h,
+ config/m68k/uclinux.h, config/mips/linux.h,
+ config/mn10300/linux.h, config/pa/pa-linux.h,
+ config/rs6000/sysv4.h, config/s390/linux.h, config/sh/linux.h,
+ config/sparc/linux.h, config/sparc/linux64.h,
+ config/xtensa/linux.h (TARGET_OS_CPP_BUILTINS): Use
+ HURD_TARGET_OS_CPP_BUILTINS/LINUX_TARGET_OS_CPP_BUILTINS or ensure
+ all necessary assertions are included.
+
+2003-11-28 Jan Hubicka <jh@suse.cz>
+
+ * emit-rtl.c (set_used_flags): New.
+ (verify_rtx_sharing, verify_rtl_sharing): New.
+ (unshare_all_rtl_1): Rename to....
+ (unshare_all_rtl_in_chain): ... this one; make static.
+ (copy_rtx_if_shared): LABEL_REF chan be shared.
+ * ifcvt.c (unshare_ifcvt_sequence): New.
+ (noce_try_move, noce_try_store_flag, noce_try_store_flag_constants,
+ noce_try_addcc, noce_try_addcc, noce_try_store_flag_mask,
+ noce_try_cmove, noce_try_store_flag_mask, noce_try_minmax,
+ noce_try_abs, noce_process_if_block, find_cond_trap
+ * rtl.h (verify_rtl_sharing, set_used_flags, unshare_all_rtl_in_chain):
+ Declare.
+
+2003-11-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Fix a comment typo.
+
+2003-11-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*movsf_h8300h): Change to
+ *movsf_h8300hs.
+ (addsi_h8300): Change to *addsi_h8300.
+ (addsi_h8300h): Change to *addsi_h8300hs.
+ (subsi3_h8300): Change to *subsi3_h8300.
+ (subsi3_h8300h): Change to *subsi3_h8300hs.
+ (neghi2_h8300h): Change to *neghi2_h8300hs.
+ (negsi2_h8300h): Change to *negsi2_h8300hs.
+
+2003-11-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*subhi3_h8300): Remove '&' from the
+ constraint.
+ (*subhi3_h8300hs): Likewise.
+
+2003-11-28 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.h (MASK_MFCRF): New.
+ (TARGET_MFCRF): Test target_flags, not processor type.
+ (TARGET_SWITCHES): Add mfcrf and no-mfcrf.
+ Change Don't to Do not.
+ * config/rs6000/rs6000.c (processors_target_table): Add MASK_MFCRF
+ to power4, 970, G5.
+
+2003-11-27 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * cse.c (cse_set_around_loop): When changing a constant load
+ to a register -register copy, add a REG_EQUAL note.
+
+2003-11-27 Randolph Chung <tausq@debian.org>
+ John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (hppa_profile_hook): Split gen_call_profiler into separate
+ insns. Use the regular call expander for the call to the profiler.
+ * pa.md (call_profiler): Delete.
+ (load_offset_label_address): New insn to load the address of the
+ current function for the profiler.
+ (lcla1, lcla2): New insns to output a code label and load its address.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * final.c (final_scan_insn): Remove commented-out code.
+
+2003-11-27 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * doc/install.texi: Remove ADAC reference and make accurate.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (FUNCTION_VALUE): Use R0_REG.
+ (FUNCTION_VALUE_REGNO_P): Likewise.
+ * config/h8300/h8300.md: Define R0_REG.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c: Fix formatting.
+ * config/h8300/h8300.md: Likewise.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (ELIMINABLE_REGS): Update a comment.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Give names to anonymous insns.
+
+2003-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (extendqisi2): Remove constraints.
+
+2003-11-27 Gunther Nikl <gni@gecko.de>
+
+ * doc/tm.texi (SYSROOT_HEADERS_SUFFIX_SPEC): Fix typo.
+
+2003-11-27 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/13041
+ * final.c (frame_pointer_needed): Fix comment.
+ * reload1.c (reload): Decrease alignment of the frame
+ pointer if it was used for register allocation.
+
+2003-11-27 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/12900
+ * reg-stack (move_for_stack_reg): New prototype. Return
+ whether a control flow insn was deleted.
+ (subst_stack_regs_pat): Likewise, using the information provided
+ by move_for_stack_reg.
+ (subst_stack_regs): Likewise, using the information provided
+ by subst_stack_regs_pat.
+ (convert_regs_1): Record whether a control flow insn was deleted,
+ using the information provided by subst_stack_regs. Purge dead
+ edges only if a control flow insn was deleted.
+
+2003-11-27 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR middle-end/8028
+ PR middle-end/9890
+ PR middle-end/11151
+ PR middle-end/12210
+ PR middle-end/12503
+ PR middle-end/12692
+ * builtins.c (expand_builtin_apply): Use virtual_outgoing_args_rtx
+ as the base address to copy the memory arguments to.
+
+2003-11-26 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/cygming.h (ASM_OUTPUT_DEF_FROM_DECLS): Declare
+ function aliases as functions.
+
+2003-11-26 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * aclocal.m4 (gcc_AC_PROG_GNAT): Rewrite to account for removal
+ of ADAC.
+ * configure: Regenerate.
+
+ * Makefile.in: Remove references to ADAC.
+
+ * configure.in: Remove check for whether ${ADAC} accepts -Wno-long-long.
+ * configure: Regenerate.
+
+2003-11-26 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Olivier Hainque <hainque@act-europe.fr>
+
+ PR target/6466
+ * config/sparc/sparc-protos.h (compute_frame_size): New prototype.
+ (sparc_flat_compute_frame_size): Likewise.
+ (sparc_flat_save_restore): Move prototype...
+ * config/sparc/sparc.c (sparc_flat_save_restore): ...here.
+ (save_regs): New prototype.
+ (build_big_number): Likewise.
+ (apparent_fsize): Change type to HOST_WIDE_INT.
+ (actual_fsize): Likewise.
+ (frame_base_offset): Likewise.
+ (build_big_number): Add support for HOST_BITS_PER_WIDE_INT == 64.
+ Change string descriptor to HOST_WIDE_INT_PRINT_DEC.
+ [TARGET_ARCH64]: Use the sequence of sparc_emit_set_const64_longway
+ to load a 64-bit constant.
+ (sparc_nonflat_function_prologue): Change string descriptor to
+ HOST_WIDE_INT_PRINT_DEC. Change offset type to HOST_WIDE_INT.
+ (output_restore_regs): Change offset type to HOST_WIDE_INT.
+ (sparc_nonflat_function_epilogue): Change string descriptor to
+ HOST_WIDE_INT_PRINT_DEC. Use build_big_number.
+ (output_sibcall): Change size type to HOST_WIDE_INT. Use
+ build_big_number. Change string descriptor to HOST_WIDE_INT_PRINT_DEC.
+ (sparc_frame_info): Change types for several components.
+ (sparc_flat_compute_frame_size): Update types according to previous
+ change.
+ (sparc_flat_function_prologue): Change string descriptor to
+ HOST_WIDE_INT_PRINT_DEC. Change offset type to int. Use
+ build_big_number.
+ (sparc_flat_function_epilogue): Change offset type to int.
+ Rename 'size1' into 'reg_offset1'. Change string descriptor to
+ HOST_WIDE_INT_PRINT_DEC. Use build_big_number. Change big number
+ limit to 4096 instead of 4095.
+
+ * config/sparc/sparc.c (mems_ok_for_ldd_peep): Change offset type to
+ HOST_WIDE_INT.
+
+2003-11-24 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ * function.c: Make outer_function-chain external.
+ * function.h: Likewise.
+
+2003-11-24 Richard Sandiford <rsandifo@redhat.com>
+
+ * config.gcc (mips-sgi-irix6*): Add t-iris6gld to tmake_file when
+ using GNU ld.
+ * config/mips/iris6.h (IRIX6_STARTFILE_SPEC): New, taking the
+ whole of the previous STARTFILE_SPEC except crtbegin.o%s.
+ (IRIX6_ENDFILE_SPEC): Likewise ENDFILE_SPEC and crtend.o%s.
+ (STARTFILE_SPEC, ENDFILE_SPEC): Define in terms of the above.
+ (SUBTARGET_EXTRA_SPECS): Define.
+ * config/mips/iris6gld.h (LINK_SPEC): Change -init function
+ to __gcc_init and -fini function to __gcc_fini.
+ (STARTFILE_SPEC): Redefine, including irix6-crti.o before crtbegin.o.
+ (ENDFILE_SPEC): Likewise, including irix6-crtn.o after crtend.o.
+ (INIT_SECTION_ASM_OP, FINI_SECTION_ASM_OP): Define.
+ * config/mips/t-iris6gld,
+ * config/mips/irix6-crti.asm,
+ * config/mips/irix6-crtn.asm: New files.
+
+2003-11-24 Eric Christopher <echristo@redhat.com>
+
+ PR C/13014
+ * c-decl.c (c_in_iteration_stmt, c_in_case_stmt): New.
+ (start_function): Use.
+ (c_push_function_context): Ditto.
+ (c-pop_function_context): Ditto.
+ (language_function): Move...
+ * c-tree.h: ... here. Add x_in_iteration_stmt, and
+ x_in_case_stmt.
+ * c-parse.in (do_stmt_start, select_or_iter_stmt, stmt): Use
+ c_in_iteration_stmt, c_in_case_stmt for parser state. Move
+ check for valid break or continue statment here...
+ * c-semantics.c (genrtl_break_stmt, genrtl_continue_stmt): From
+ here. Change original errors to abort.
+
+2003-11-24 Jan Hubicka <jh@suse.cz>
+
+ * fold-const.c (fold): Do not return early when optimizing
+ COMPONENT_REF and constant.
+
+2003-11-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (tablejump_h8300): Change to
+ *tablejump_h8300.
+ (tablejump_h8300h): Change to *tablejump_h8300hs_advanced.
+ (tablejump_normal_mode): Change to *tablejump_h8300hs_normal.
+ (indirect_jump_h8300): Change to *indirect_jump_h8300.
+ (indirect_jump_h8300h): Change to
+ *indirect_jump_h8300hs_advanced.
+ (indirect_jump_normal_mode): Change to
+ *indirect_jump_h8300hs_normal.
+
+2003-11-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Remove constraints from expanders.
+
+2003-11-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: (stm_h8300s_2): Change the name to
+ stm_h8300s_2_advanced.
+ (stm_h8300s_2_normal): New.
+ (stm_h8300s_2): Likewise.
+ (stm_h8300s_3): Change the name to stm_h8300s_3_advanced.
+ (stm_h8300s_3_normal): New.
+ (stm_h8300s_3): Likewise.
+ (stm_h8300s_4): Change the name to stm_h8300s_4_advanced.
+ (stm_h8300s_4_normal): New.
+ (stm_h8300s_4): Likewise.
+ (ldm_h8300s_2): Change the name to ldm_h8300s_2_advanced.
+ (ldm_h8300s_2_normal): New.
+ (ldm_h8300s_2): Likewise.
+ (ldm_h8300s_3): Change the name to ldm_h8300s_3_advanced.
+ (ldm_h8300s_3_normal): New.
+ (ldm_h8300s_3): Likewise.
+ (ldm_h8300s_4): Change the name to ldm_h8300s_4_advanced.
+ (ldm_h8300s_4_normal): New.
+ (ldm_h8300s_4): Likewise.
+ (two peephole2's): Enable only with !TARGET_NORMAL_MODE.
+ (two peephole2's): New.
+
+2003-11-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * genattrtab.c (simplify_cond): Update indices correctly.
+ (attr_alt_subset_p, attr_alt_subset_of_compl_p, attr_alt_intersection,
+ attr_alt_union, attr_alt_complement, attr_alt_bit_p, mk_attr_alt): New.
+ (check_attr_test, encode_units_mask, compute_alternative_mask,
+ make_alternative_compare, simplify_and_tree,
+ attr_rtx_cost, simplify_test_exp, gen_attr,
+ write_test_expr, walk_attr_value): Handle EQ_ATTR_ALT.
+ * rtl.def (EQ_ATTR_ALT): New.
+
+2003-11-23 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * genattrtab.c (strcmp_check, DEF_ATTR_STRING): New macros.
+ (length_str, delay_type_str, delay_1_0_str, num_delay_slots_str):
+ New variables.
+ (main): Initialize them.
+ (find_attr): Canonicalize the attribute name string.
+ (attr_rtx_1, copy_boolean, expand_delays, gen_unit): Always canonicalize
+ string arguments.
+ (attr_printf, attr_eq): Use DEF_ATTR_STRING.
+ (check_attr_test, check_attr_value, make_length_attrs,
+ write_length_unit_log, simplify_by_exploding, gen_attr,
+ write_test_expr, write_attr_value, write_eligible_delay,
+ write_complex_function, make_internal_attr,
+ write_const_num_delay_slots): Changed due to change of type of
+ find_attr.
+ (fill_attr, evaluate_eq_attr, simplify_and_tree,
+ attr_rtx_cost, simplify_by_exploding, walk_attr_value): Use
+ strcmp_check.
+
+2003-11-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/13122
+ * config/h8300/h8300.c (push): Call push_h8300hs_normal in
+ normal mode.
+ (pop): Call pop_h8300hs_normal in normal mode.
+ * config/h8300/h8300.md: Likewise.
+ (pushqi1_h8300hs_normal): New.
+ (pushqi1): Call pushqi1_h8300hs_normal in normal mode.
+ (pushhi1_h8300hs_normal): New.
+ (pushhi1): Call pushhi1_h8300hs_normal in normal mode.
+ (push_h8300hs_normal): New.
+ (pop_h8300hs_normal): Likewise.
+
+2003-11-23 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * genattrtab.c (count_sub_rtxs): Removed.
+
+2003-11-23 Richard Earnshaw <rearnsha@arm.com>
+
+ * recog.c (preprocess_constraints): Only zero those elements of
+ recog_op_alt that are needed for this insn.
+ * arm.c (note_invalid_constants): A function can't contain invalid
+ constants if it has no constraints.
+
+2003-11-22 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (classify_argument): Pass __float128 in memory.
+ (ix86_return_in_memory): Likewise.
+ (ix86_libcall_value): Likewsie.
+
+2003-11-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (dosize): Convert to ISO-C.
+
+2003-11-22 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * flow.c (update_life_info): Amend comment about when a register
+ can become dead.
+
+2003-11-21 Kelley Cook <kcook@gcc.gnu.org>
+
+ * doc/.cvsignore: Delete.
+
+2003-11-21 Daniel Berlin <dberlin@dberlin.org>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * dwarf2out.c (add_location_or_const_value_attribute): Add support
+ for PARALLEL.
+
+2003-11-21 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/t-iris6 (CRTSTUFF_T_CFLAGS): Add -Wno-error.
+ (TARGET_LIBGCC2_CFLAGS): Define.
+
+ * crtstuff.c [HAS_INIT_SECTION] (__do_global_dtors): Declare.
+ (__do_global_ctors): Likewise.
+
+2003-11-21 Mark Wielaard <mark@klomp.org>
+
+ * doc/invoke.texi (-O2): Doesn't enable -fweb.
+
+2003-11-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Mention dV and dZ.
+
+2003-11-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Update dump file names.
+ Remove de, dW, and dX.
+
+2003-11-20 James E Wilson <wilson@specifixinc.com>
+
+ PR c/13133
+ * reload1.c (reload): Delete special handling for setjmp.
+
+2003-11-21 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * mklibgcc.in: Evaluate shlib_slibdir_qual during link
+ step too.
+ * config/t-slibgcc-darwin: Adjust install path.
+ * config/rs6000/t-darwin: Revert multilib matches since
+ it is not used on darwin.
+
+2003-11-20 Richard Henderson <rth@redhat.com>
+
+ * ssa.c, ssa-dce.c, ssa-ccp.c: Remove files.
+ * Makefile.in (OBJS-common, GTFILES): Don't reference them.
+ (gtype-desc.o, toplev.o, flow.o): Remove ssa.h.
+ (ssa.o, ssa-dce.o, ssa-ccp.o): Remove.
+ * flow.c: Don't include ssa.h.
+ (set_phi_alternative_reg): Remove.
+ (calculate_global_regs_live): Don't call it.
+ (mark_used_regs): Don't handle PHI.
+ * gengtype.c (open_base_files): Don't reference ssa.h.
+ * rtl.def (PHI): Remove.
+ * timevar.def (TV_TO_SSA, TV_SSA_CCP, TV_SSA_DCE, TV_FROM_SSA): Kill.
+ * common.opt: Remove -fssa, -fssa-ccp, -fssa-dce.
+ * opts.c (common_handle_option): Likewise.
+ * toplev.c (f_options): Likewise.
+ (DFI_ssa, DFI_ssa_ccp, DFI_ssa_dce, DFI_ussa): Remove.
+ (dump_file): Update to match.
+ (flag_ssa, flag_ssa_ccp, flag_ssa_dce): Remove.
+ (rest_of_handle_ssa): Remove.
+ (rest_of_compilation): Don't call it.
+ * toplev.h (flag_ssa, flag_ssa_dce, flag_ssa_ccp): Remove.
+ * doc/invoke.texi: Remove -fssa, -fssa-ccp, -fssa-dce.
+ * doc/passes.texi (SSA optimizations): Remove.
+
+2003-11-20 Bob Wilson <bob.wilson@acm.org>
+
+ * configure.in: Add xtensa-*-* targets to test for dwarf2 debug_line.
+ * configure: Regenerate.
+
+2003-11-20 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (Makefile): Pass along CONFIG_SHELL.
+
+2003-11-20 David Mosberger <davidm@hpl.hp.com>
+
+ * config/t-libunwind (LIB2ADDEH): Add unwind-c.c.
+ (SHLIB_LC): Define.
+ * unwind-libunwind.c (_Unwind_GetCFA): Implement.
+ (_Unwind_GetBSP) [UNW_TARGET_IA64]: New function.
+
+2003-11-20 Fariborz Jahanian <fjahanian@apple.com>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * calls.c (expand_call): Allocate new temp in pass1.
+ (store_one_arg): If PARALLEL, calculate excess using mode size of
+ rtvec elt.
+ * expr.c (emit_push_insn): If PARALLEL, calculate offset using
+ mode size of rtvec elt.
+ * function.c (assign_parms): Use parm in register, if available.
+
+2003-11-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (MOVP): Remove.
+ (ADDP): Likewise.
+ (CMPP): Likewise.
+
+2003-11-20 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (use_return_insn): New argument, SIBLING. Support returning
+ with a single instruction if the stack has been decremented by 4
+ and we have a frame pointer. Update all callers.
+ (output_return_instruction): Likewise.
+ (arm_output_epilogue): Change argument to SIBLING. Calculate
+ really_return from the new argument. Update all callers.
+ * arm.h (USE_RETURN_INSN): Pass NULL for the sibling.
+ * arm.md (sibcall_epilogue): Call use_return_insn directly, and
+ pass the sibling call.
+ * arm-protos.h (use_return_insn, arm_output_epilogue): Update
+ prototypes.
+
+2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Makefile.in (extraclean): Delete.
+ * configure.in (target_list): Remove extraclean.
+ * configure: Regenerate.
+ * doc/makefile.texi, doc/sourcebuild.texi: Update.
+ * objc/Make-lang.in (objc.extraclean): Delete.
+
+2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Makefile.in (lang_checks): Add.
+ (check-c++, check-f77, check-java, check-g++, check-g77,
+ check-objc): Remove hardcoded targets.
+ * doc/sourcebuild.texi: Document testsuite hooks.
+ * objc/Make-lang.in (check-objc, lang_checks): Add.
+
+2003-11-19 Scott Snyder <snyder@fnal.gov>
+
+ PR target/13131
+ * dwarf2out.c (gen_array_type_die): DW_AT_declaration should be a
+ flag, not a constant.
+
+2003-11-19 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config/arc/arc-protos.h: Update to C90 prototypes.
+ * config/arc/arc.c: Likewise.
+ * config/arc/initfini.c: Likewise.
+
+2003-11-19 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * stmt.c (expand_goto): Memory clobbers added.
+
+2003-11-19 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * reload.c (find_reloads): Added missing type casts.
+
+2003-11-19 James E Wilson <wilson@specifixinc.com>
+
+ * combine.c (sets_function_arg_p): Delete unused function.
+
+2003-11-19 Eric Christopher <echristo@redhat.com>
+
+ * reload1.c (reload): Revert 2 previous checkins.
+
+2003-11-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cpptrad.c (_cpp_scan_out_logical_line): Improve test for
+ whether directive begins at the beginning of a line.
+
+2003-11-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/frv/frv.c (frv_init_libfuncs): Correct ufix_optab entries.
+
+2003-11-19 Gerald Pfeifer <gp@suse.de>
+
+ * doc/install.texi (Specific): Remove information on old versions
+ of glibc versus old versions of GCC.
+
+2003-11-19 Richard SAndiford <rsandifo@redhat.com>
+
+ * emit-rtl.c (gen_lowpart): Don't force MEMs into a register unless
+ the register lowpart is a TRULY_NOOP_TRUNCATION.
+
+2003-11-19 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (print_reg): Handle QI and HI modes for
+ non Q regs.
+
+2003-11-19 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * config/config.gcc (powerpc-*-darwin*): Add libgcc build
+ specification file.
+ * config/t-slibgcc-darwin: New file, libgcc build specification.
+ * config/t-darwin: Add libgcc2 flag -fPIC.
+ * config/rs6000/t-darwin: Multilib matches float.
+ * libgcc-darwin.ver: New file, contains libgcc symbols.
+
+2003-11-18 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/ns32k/ns32k.h: Remove obsolete comment.
+
+2003-11-18 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11821
+ * config/arm/arm.c (arm_rtx_costs_1): Improve estimate of the code
+ size for calls to libgcc's div & mod subroutines when using -Os.
+
+2003-11-18 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (change_decl_assembler_name): Avoid bogus warnings.
+
+2003-11-18 Marc Espie <espie@openbsd.org>
+
+ * config/rs6000/sysv4.h: OpenBSD hooks.
+
+2003-11-18 Richard Henderson <rth@redhat.com>
+
+ * expr.c (expand_expr): Don't look through constant arrays if
+ they don't bind locally.
+
+2003-11-17 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (convert_move): Use GET_MODE_PRECISION instead of bitsize
+ when seeing if truncation or extension.
+
+2003-11-17 Eric Christopher <echristo@redhat.com>
+
+ * reload1.c (reload): Fix previous change.
+
+2003-11-17 Scott Snyder <snyder@fnal.gov>
+
+ PR debug/11325
+ * dwarf2out.c (struct die_struct): Add die_definition field.
+ (add_AT_specification): New.
+ (gen_subprogram_die, gen_variable_die,
+ gen_struct_or_union_type_die): Use it.
+ (prune_unused_types_mark): If we're marking a forward declaration,
+ also mark the full definition, if it exists.
+
+2003-11-16 Nick Clifton <nickc@redhat.com>
+
+ * config/stormy16/stormy16.h (BUILD_VA_LIST_TYPE): Delete.
+ * config/stormy16/stormy16-protos.h (xstormy16_build_va_list):
+ Remove prototype.
+ * config/stormy16/stormy16.c (xstormy16_build_va_list): Rename
+ to xstormy16_build_builtin_va_list and make static.
+ (TARGET_BUILD_BUILTIN_VA_LIST): Define.
+
+2003-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add the prototype for
+ same_cmp_following_p.
+ * config/h8300/h8300.c (same_cmp_following_p): New.
+ * config/h8300/h8300.md (peephole2): Use it.
+
+2003-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Don't use REGNO when its operand is
+ not guaranteed to be a REG.
+
+2003-11-16 Richard Sandiford <rsandifo@redhat.com>
+
+ * Makefile.in (expr.o): Depend on $(TARGET_H).
+ * target.h (return_in_msb): New target hook.
+ * target-def.h (TARGET_RETURN_IN_MSB): New macro.
+ (TARGET_CALLS): Include it.
+ * calls.c (shift_returned_value): New function.
+ (expand_call): Use it.
+ * expr.c: Include target.h.
+ (copy_blkmode_from_reg): Check targetm.calls.return_in_msb when
+ deciding what padding is needed. Change the name of the local
+ padding variable from big_endian_correction to padding_correction.
+ * stmt.c (shift_return_value): New function.
+ (expand_return): Use it. Adjust memory->register copy in the same
+ way as copy_blkmode_from_reg. Only change the return register's
+ mode if it was originally BLKmode.
+ * doc/tm.texi (TARGET_RETURN_IN_MSB): Document.
+ * config/mips/mips.c (TARGET_RETURN_IN_MSB): Define.
+ (mips_fpr_return_fields): New, split out from mips_function_value.
+ (mips_return_in_msb, mips_return_fpr_pair): New functions.
+ (mips_function_value): Rework to use the functions above.
+ * config/mips/irix6-libc-compat.c: Delete.
+ * config/mips/t-iris6 (LIB2FUNCS_STATIC_EXTRA): Undefine.
+
+2003-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/install.texi (--enable-checking): Update valgrind's URL.
+
+2003-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Fix warnings by replacing -2147483648
+ with -2147483647 - 1.
+
+2003-11-16 Gerald Pfeifer <gerald@pfeifer.com>
+
+ Fix links in online manuals.
+ * doc/invoke.texi (H8/300 Options): @xref to ld, not ld.info.
+ (Precompiled Headers): @pxref to cpp, not cpp.info.
+
+2003-11-16 Jason Merrill <jason@redhat.com>
+
+ * Makefile.in, objc/Make-lang.in (objc.tags): Create TAGS.sub
+ files in each directory and TAGS files that include them for each
+ front end.
+
+2003-11-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (divnorm): Store the sign in bit
+ 3 of S2L.
+ (modnorm): Likewise.
+ (exitdiv): Look at bit 3 of S2L only.
+
+2003-11-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (DO_GLOBAL_CTORS_BODY): Fix warnings.
+ (DO_GLOBAL_DTORS_BODY): Likewise.
+
+2003-11-15 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/install.texi (Prerequisites): Refine documentation of
+ autoconf, automake and perl requirements. Document required
+ gettext version.
+
+<2003-11-14 Jason Merrill <jason@redhat.com>
+
+ * function.c (assign_parms): Use TREE_TYPE to determine the real
+ type of the argument object.
+
+2003-11-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (___udivsi3): Peel off the first
+ iteration.
+
+2003-11-14 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_move_block_from_reg):
+ New routine to save vararg registers on stack. Support for
+ -mpowerpc64 in mixed mode.
+
+2003-11-14 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c: Use C statements instead of #ifdef's when testing
+ for MOTOROLA versus MIT syntax. Improves readability and provides
+ better compile-time error checking for both code paths.
+
+2003-11-14 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config/frv/frv-protos.h: Update for C90.
+ * config/frv/frv.h: Likewise.
+ * config/frv/frvbegin.c: Likewise.
+ * config/frv/frv.c: Likewise.
+ (frv_adjust_field_align): Delete unused variable.
+
+2003-11-14 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.md: Add 'DEFAULT_ABI == ABI_DARWIN'
+ to each place where TARGET_LONG_DOUBLE_128 is used with
+ DEFAULT_ABI == ABI_AIX.
+
+ * cppfiles.c (_cpp_find_file): Make 'one or more PCH files were found'
+ message comply with GNU standards.
+
+2003-11-14 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ PR/6552
+ * function.c (struct epi_info): New field const_equiv.
+ (update_epilogue_consts): New function.
+ (keep_stack_depressed): Clear new field and verify scratch register
+ doesn't have it set.
+ Call new function via note_stores.
+ (handle_epilogue_set): Allow setting SP equiv reg in different mode.
+ Allow PLUS where second operand is register known set to constant.
+ (emit_equiv_load): Write load using proper mode if source different.
+ * config/mips/mips.md (return_internal): Put (return) first.
+
+2003-11-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (___udivsi3): Add a comment.
+
+2003-11-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (modsi3): Don't save unused
+ registers.
+ (divsi3): Likewise.
+ (reti): Don't restore unused registers.
+
+2003-11-14 Nick Clifton <nickc@redhat.com>
+
+ * config/fr30/fr30.c: Include toplev.h
+
+2003-11-14 Richard Earnshaw <rearnsha@arm.com>
+
+ * except.c (sjlj_emit_function_enter): Mark internal label as LOCAL.
+
+2003-11-14 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_emit_vector_const, arm_output_load_gr): Use ISO C
+ function definition syntax.
+
+2003-11-14 Eric Christopher <echristo@redhat.com>
+
+ * reload1.c (reload): Revert previous patch. Make
+ check for assignment into reg_equiv_address stricter.
+
+2003-11-14 Arnaud Charlet <charlet@act-europe.fr>
+
+ * Makefile.in (POSTSTAGE1_FLAGS_TO_PASS): Pass ADAFLAGS.
+
+2003-11-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/frv/frv.c (frv_in_small_data_p): Return false for unknown
+ section names.
+
+2003-11-14 Jason Merrill <jason@redhat.com>
+
+ PR middle-end/12526
+ * tree.c (build): A CALL_EXPR has side-effects if its arguments do.
+ * calls.c (call_expr_flags): New fn.
+ * tree.h: Declare it.
+
+2003-11-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (__udivsi3): Remove.
+ (divmodsi3): Change the name to ___udivsi3.
+ Update all callers.
+
+2003-11-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * libgcc2.c (__negdi2, __addvsi3, __addvdi3, __subvsi3, __subvdi3,
+ __mulvsi3, __negvsi2, __negvdi2, __mulvdi3, __lshrdi3, __ashldi3,
+ __ashrdi3, __ffsDI2, __muldi3, __clzDI2, __ctzDI2, __parityDI2,
+ __udivmoddi4, __divdi3, __moddi3, __cmpdi2, __ucmpdi2,
+ __fixunstfDI, __fixunsxfDI, __fixunsdfDI, __fixunssfDI,
+ __floatdixf, __floatditf, __floatdidf, __floatdisf, __gcc_bcmp):
+ Const-ify and/or initialize automatic variables at declaration.
+
+2003-11-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (divmodsi4): Replace all the uses
+ of er4 with er3. Adjust all callers.
+
+2003-11-13 Andrew Pinski <apinski@apple.com>
+
+ * config/darwin.c (machopic_output_possible_stub_label):
+ Allow stub symbol be not defined when outputting possible
+ stub label.
+
+2003-11-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (___udivsi3): Jump to reti
+ instead of exitdiv.
+ (___umodsi3): Likewise.
+ (exitdiv): Do not restore any register.
+ (reti): Restore registers.
+
+2003-11-13 Steven Bosscher <stevenb@suse.de>
+
+ * tree-inline.c (walk_tree): Handle PLACEHOLDER_EXPR.
+
+2003-11-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm: Fix comment typos.
+
+2003-11-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (udivsi3): Don't save/restore
+ unused registers. Don't jump to exitdiv.
+ (umodsi3): Likewise.
+
+2003-11-13 Mark Mitchell <mark@codesourcery.com>
+ Kean Johnston <jkj@sco.com>
+
+ PR c/13029
+ * toplev.c (check_global_declarations): Do not warn about unused
+ static consts.
+
+2003-11-13 Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (DenHighNonZero): Optimize using
+ the approximate quotient method.
+
+2003-11-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * combine.c (distribute_notes): When re-distributing the notes from
+ an insn we are about to delete, ensure we can't end up with a cyclic
+ list of notes.
+
+2003-11-13 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/12926
+ * expr.c (expand_assignment) [COMPONENT_REF]: Don't put
+ the UNCHANGING_RTX_P flag on memory references to read-only
+ components that are not addressable.
+
+2003-11-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (divmodsi4): Clear S0P in
+ DenHighNonZero.
+
+2003-11-13 Jan Hubicka <jh@suse.cz>
+
+ PR opt/12275
+ * c-decl.c (finish_decl): Use change_decl_assembler_name.
+ * c-pragma.c (handle_pragma_redefine_extname): Likewise.
+ * varasm.c (make_decl_rtl): Likewise.
+ * cgraph.c (change_decl_assembler_name): New function.
+ * tree.h (set_decl_assembler_name): Kill dead declaration.
+ (change_decl_assembler_name): Declare.
+
+ * decl.c (make_rtl_for_nonlocal_decl): Use change_decl_assembler_name.
+ * decl2.c (make_rtl_for_nonlocal_decl): Use change_decl_assembler_name.
+
+2003-11-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm (___mulsi3): Don't save/restore
+ an unused register.
+
+2003-11-12 Richard Sandiford <rsandifo@redhat.com>
+
+ PR bootstrap/12752
+ * config/mips/t-iris6 (MULTILIB_OPTIONS): Put -mabi=n32 first.
+ (MULTILIB_OSDIRNAMES): Reorder accordingly.
+
+2003-11-12 Janis Johnson <janis187@us.ibm.com>
+
+ * rs6000-protos.h (rs6000_initial_elimination_offset): Add.
+ (rs6000_stack_info): Remove. (debug_stack_info): Remove.
+ (rs6000_emit_eh_reg_restore): Add
+ * rs6000.c (rs6000_stack_t): Move from rs6000.h, change data type
+ of vars_size and total_size to HOST_WIDE_INT.
+ (emit_frame_save): Change parameter size to HOST_WIDE_INT.
+ (rs6000_stack_info): Make static; change data size to HOST_WIDE_INT.
+ (debug_stack_info): Make static; change output format of HOST_WIDE_INT
+ values.
+ (rs6000_emit_eh_reg_restore): New, with code formerly in rs6000.md.
+ (rs6000_initial_elimination_offset): New, with code formerly in
+ INITIAL_ELIMINATION_OFFSET.
+ * rs6000.h (rs6000_stack_t): Remove.
+ (INITIAL_ELIMINATION_OFFSET): Replace code with call to function
+ rs6000_initial_elimination_offset.
+ * rs6000.md (UNSPECV_EH_RR split): Replace code with call to
+ rs6000_emit_eh_reg_restore.
+
+2003-11-12 Mike Stump <mrs@apple.com>
+
+ * c-typeck.c (c_convert_parm_for_inlining): Add argnum, which
+ is the argumnt we are processing so that warnings and errors
+ will have that information.
+ * c-tree.h (c_convert_parm_for_inlining): Add argnum.
+ * lang-hooks-def.h
+ (lhd_tree_inlining_convert_parm_for_inlining): Likewse.
+ * langhooks.c (lhd_tree_inlining_convert_parm_for_inlining): Likewise.
+ * langhooks.h (convert_parm_for_inlining): Likewise.
+ * tree-inline.c (initialize_inlined_parameters): Compute and
+ pass argnum down.
+
+2003-11-12 Alexey Starovoytov <alexey.starovoytov@sun.com>
+ Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/12953
+ * tree-inline.c (inline_forbidden_p_1): Added check for BUILT_IN
+ before switch by FUNCTION_CODE.
+
+2003-11-12 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (storehi): Avoid use of explicit subreg.
+ (storehi_bigend, storeinthi, movhi_bigend): Likewise.
+
+2003-11-12 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/sh/sh.md (prefetch): New pattern.
+
+2003-11-11 Eric Christopher <echristo@redhat.com>
+
+ * reload1.c (reload): Verify that addresses for
+ reg_equiv_* are valid for the architecture.
+
+2003-11-11 Eric Christopher <echristo@redhat.com>
+
+ * function.c (purge_addressof_1): Add libcall check.
+ Remove test for cached replacements on fallback case.
+ Simplify mode comparisons. Add libcall test for
+ paradoxical subregs.
+
+2003-11-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/t-h8300: Fix an obsolete comment.
+
+2003-11-11 James E Wilson <wilson@specifixinc.com>
+
+ * expmed.c (store_bit_field, extract_bit_field): Revert last two
+ changes.
+
+2003-11-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/lib1funcs.asm: Replace DenHighZero with
+ DenHighNonZero.
+
+2003-11-11 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_function_possibly_inlined_p): Use
+ really_no_inline.
+
+2003-11-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.h (TRAMPOLINE_TEMPLATE): Fix flushing of cache lines when
+ generating 64-bit code.
+
+2003-11-10 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (legitimate_lo_sum_address_p): Remove
+ accidental commit in previous change.
+
+2003-11-10 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.h (STACK_SIZE_MODE): Add definition.
+ * config/rs6000/rs6000.c (reg_or_mem_operand): Add macho-style
+ address recognition.
+ (macho_lo_sum_memory_operand): Routine to recognize macho-style
+ address recognition.
+
+2003-11-10 Richard Henderson <rth@redhat.com>
+
+ * dwarf2out.c (gen_label_die): Cope with DECL_RTL not set.
+
+2003-11-10 Matt Austern <austern@apple.com>
+
+ * config/darwin-protos.h (darwin_assemble_visibility): Declare.
+ * config/darwin.c (darwin_assemble_visibility): Define. Warn for
+ anything other than VISIBILITY_DEFAULT and VISIBILITY_HIDDEN.
+ * config/darwin.h (TARGET_ASM_ASSEMBLE_VISIBILITY): Use
+ darwin_assemble_visibility instead of default.
+
+2003-11-10 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ PR target/12865
+ * config/sparc/sparc.c (sparc_initialize_trampoline): Call
+ __enable_execute_stack only after writing onto the stack.
+ (sparc64_initialize_trampoline): Likewise.
+
+2003-11-09 Roger Sayle <roger@eyesopen.com>
+
+ * loop.c (check_dbra_loop): Try swapping the comparison operands
+ of the loop condition to identify a suitable induction variable.
+ * unroll.c (loop_iterations): Likewise.
+
+2003-11-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/sparc/sparc.h (TARGET_CPU_CPP_BUILTINS): Fix sparc vs
+ sparc64 #cpu and #machine assertions.
+
+2003-11-09 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (rtlanal.o): Depend on BASIC_BLOCK_H.
+
+2003-11-09 Jan Hubicka <jh@suse.cz>
+
+ * tree-optimize.c (tree_rest_of_compilation): Fix warning.
+
+ * cgraphunit.c (cgraph_expand_function): Use
+ cgraph_possibly_inlined_p.
+ * tree-optimize.c (tree_rest_of_compilation): Do not kill saved tree.
+
+ * opts.c (common_handle_option): Do not set max-inline-insns.
+ * params.def: Update comments.
+ (PARAM_MAX_INLINE_INSNS): Kill.
+ * invoke.texi (max-inline-insns): Kill.
+
+2003-11-08 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR c/3190
+ PR c/8714
+ * c-format.c (set_Wformat): Do not enable -Wformat-y2k by default.
+ * invoke.texi: Update.
+
+2003-11-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR optimization/12630
+ * pa.c (compute_movstrsi_length): Rename to compute_movstr_length.
+ Handle length computation 64-bit moves.
+ (compute_clrstr_length, output_block_clear): Implement block clear.
+ (output_block_move): Handle 64-bit moves.
+ (pa_adjust_insn_length): Use compute_movstr_length and
+ compute_clrstr_length.
+ * pa.md (movstrsi): Revise operand order and comments. Don't use
+ match_scratch.
+ (movstrsi_internal): Delete.
+ (movstrsi_prereload, movstrsi_postreload): New insns. Define splitter
+ and peephole2 patterns to transform prereload to postreload form.
+ (movstrdi, movstrdi_prereload, movstrdi_postreload, clrstrsi,
+ clrstrsi_prereload, clrstrsi_postreload, clrstrdi, clrstrdi_prereload,
+ clrstrdi_postreload): New patterns for 64-bit block move, and block
+ clear.
+ * pa-protos.h (output_block_clear): New prototype.
+
+2003-11-08 Andreas Schwab <schwab@suse.de>
+
+ * dbxout.c (current_file): Also wrap inside DBX_DEBUGGING_INFO ||
+ XCOFF_DEBUGGING_INFO.
+
+2003-11-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * dbxout.c (current_file): Wrap declaration in DBX_USE_BINCL.
+
+2003-11-07 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_legitimize_address): Remove
+ redundant parens.
+
+ * cppfiles.c (pch_open_file): New parameter 'invalid_pch', set it.
+ (find_file_in_dir): Likewise.
+ (_cpp_find_file): Print message if no header file is found
+ but an invalid PCH file was.
+
+2003-11-08 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-typeck.c (pedantic_lvalue_warning): Deprecate compound
+ expressions as lvalues.
+ (internal_build_compound_expr): Remove special handling for
+ non-pedantic case.
+ * doc/extend.texi: Document that all extended lvalues are now
+ deprecated.
+
+2003-11-07 Geoffrey Keating <geoffk@apple.com>
+
+ PR 11654
+ * dbxout.c (struct dbx_file): Do not save for PCH.
+ (current_file): Likewise.
+ (dbxout_init): Don't allocate struct dbx_file using GC.
+ (dbxout_start_source_file): Likewise.
+
+2003-11-07 Falk Hueffner <falk@debian.org>
+
+ * config/alpha/elf.h, config/alpha/unicosmk.h,
+ config/alpha/vms.h: Convert to ISO C90.
+
+2003-11-07 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/arm/pe.h: Convert to ISO C90.
+
+2003-11-07 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh-protos.h (sh_pch_valid_p): Declare.
+ * sh.c ("intl.h"): Include.
+ (TARGET_PCH_VALID_P): Override.
+ (sh_target_switches): New variable.
+ (target_switches): Define.
+ (sh_pch_valid_p): New function.
+
+ * sh.h (MODE_AFTER): Don't change mode unless TARGET_HITACHI.
+
+2003-11-07 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (x86_64_sign_extended_value): Return false from tls variables.
+ (x86_64_zero_extended_value): likewise.
+
+2003-11-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (loadgp): Take $25 as a second operand.
+ * config/mips/mips.c (mips_expand_prologue): Modify accordingly.
+
+2003-11-06 Matt Austern <austern@apple.com>
+
+ * c-common.c (handle_visibility_attribute): Set DECL_VISIBILITY
+ field instead of hanging an attribute object off the decl.
+ * tree.h (DECL_VISIBLITY): New accessor macro for
+ symbol_visibility field in struct tree_decl.
+ (enum symbol_visibility): Move definition to before tree_decl.
+ (struct tree_decl): Define new two-bit field, symbol_visibility.
+ (decl_visibility): Remove declaration.
+ * varasm.c (maybe_assemble_visibility): Use DECL_VISIBILITY
+ instead of decl_visibility.
+ (default_binds_local_p_1): Use DECL_VISIBILITY instead of
+ decl_visibility.
+ (decl_visibility): Remove.
+
+2003-11-06 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_emit_epilogue): Recognize more cases
+ where register 14 will be saved.
+
+2003-11-06 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.h (USE_FP_FOR_ARG_P): Move to rs6000.c.
+ (USE_ALTIVEC_FOR_ARG_P): Likewise.
+ * config/rs6000/rs6000.c (USE_FP_FOR_ARG_P): Move from rs6000.h.
+ Take a pointer as the CUM parameter. Update callers.
+ (USE_ALTIVEC_FOR_ARG_P): Likewise. Also correct for Darwin/AIX
+ 32-bit ABIs.
+ (function_arg_advance): Use USE_ALTIVEC_FOR_ARG_P. Correct case
+ of vector parameters as named arguments of stdarg function.
+ (function_arg): Likewise.
+
+ * config/rs6000/darwin.h (ASM_SPEC): Use -force_cpusubtype_ALL when
+ -maltivec is specified, not the non-existent -faltivec.
+
+2003-11-06 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_function_value): Declare.
+ * config/s390/s390.c (TARGET_RETURN_IN_MEMORY): Define.
+ (s390_return_in_memory): New function.
+ (s390_function_value): New function.
+ (s390_function_arg_float): Return false for all arguments larger
+ than 8 bytes.
+ (s390_function_arg_pass_by_reference): Likewise. Return true for
+ all vector arguments.
+ (s390_function_arg_integer): New function.
+ (s390_function_arg_advance): Call it. Add sanity checks.
+ (s390_function_arg): Likewise.
+ * config/s390/s390.h (FUNCTION_VALUE): Call s390_function_value.
+ (LIBCALL_VALUE): Likewise.
+ (RET_REG): Remove.
+ (RETURN_IN_MEMORY): Remove.
+
+2003-11-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_initial_elimination_offset): Change
+ return type to HOST_WIDE_INT.
+ * config/mips/mips.c (mips_frame_info): Give sizes type HOST_WIDE_INT.
+ Make initialized a bool. Make register masks unsigned ints.
+ (compute_frame_size): Make same mask change here. Use HOST_WIDE_INT
+ where appropriate.
+ (mips_initial_elimination_offset): Return a HOST_WIDE_INT.
+ (mips_output_function_prologue): Print sizes as HOST_WIDE_INTs.
+
+2003-11-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/frv/frv.c (frv_initial_elimination_offset): Remove bogus
+ negation.
+
+2003-11-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/frv/frv.h (ASM_OUTPUT_ALIGN_WITH_NOP): Define.
+
+2003-11-06 Momchil Velikov <velco@fadata.bg>
+
+ * config/mips/mips.c (override_options): Set MASK_SOFT_FLOAT
+ for VR4111 too.
+
+2003-11-06 Jan Hubicka <jh@suse.cz>
+
+ * builtins.c (simplify_builtin_strrchr, simplify_builtin_strpbrk): Add
+ missing casts.
+
+2003-11-06 Zack Weinberg <zack@codesourcery.com>
+
+ * genmodes.c: Change the word "bitsize" to "precision" throughout.
+ * machmode.def: Likewise.
+ * machmode.h (GET_MODE_SIZE): Cast value to unsigned short.
+ (GET_MODE_BITSIZE): Define as GET_MODE_SIZE * BITS_PER_UNIT.
+ (GET_MODE_PRECISION): New macro.
+ (mode_bitsize): Renamed mode_precision.
+ * stor-layout.c (mode_for_size, smallest_mode_for_size):
+ Use GET_MODE_PRECISION; clarify comments.
+
+2003-11-05 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/install-old.texi: Remove old documentation of building
+ cross-compilers.
+ * doc/install.texi: Move some of it to here.
+
+2003-11-05 Per Bothner <pbothner@apple.com>
+
+ PR preprocessor/12891
+ * c-opts.c (finish_options): Set include_cursor to disable premature
+ calls to push_command_line_include from cpp_scan_nooutput.
+ Fixes bug reported by DJ Delorie.
+
+2003-11-05 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.c (setup_incoming_varargs): Remove
+ code supporting old-style varargs.
+
+ * config/rs6000/rs6000.c (rs6000_machopic_legitimize_pic_address): Use
+ an intermediate register for better optimisation.
+
+2003-11-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR optimization/10080
+ * cfgloopanal.c (variable_initial_value, variable_initial_values,
+ simple_loop_exit_p): Record the fact that initial value is extended
+ from inner mode.
+ (count_strange_loop_iterations, count_loop_iterations): Handle
+ ivs that iterate in a narrower mode. Fix handling of overflows.
+ Improve handling of NE conditions.
+ (inverse, fits_in_mode_p): New static functions.
+ (simple_increment): Detect variables that iterate in a narrower mode.
+ * cfgloop.h (struct loop_desc): Fields inner_mode and extend added.
+
+2003-11-05 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.c (compute_vrsave_mask): Correct off-by-one
+ error.
+
+ * config/rs6000/darwin.h (SUBTARGET_OVERRIDE_OPTIONS): Darwin
+ needs VRSAVE.
+
+2003-11-05 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-typeck.c (pedantic_lvalue_warning): Deprecate use of
+ conditional expressions as lvalues.
+
+2003-11-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tsystem.h: Add the prototype of strlen.
+ * unwind-pe.h (read_encoded_value_with_base): Add an
+ appropriate cast to handle a case where the pointer size is
+ smaller than sizeof (int).
+
+2003-11-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_global_pic_constant_p): Delete.
+ (mips_delegitimize_address): Delete.
+ (mips_gotoff_global, mips_load_got_page): Declare.
+ (mips_load_got_global, mips_rewrite_small_data): Declare.
+
+ * config/mips/mips.h (FIND_BASE_TERM): Remove definition.
+ (DANGEROUS_FOR_LA25_P): Use global_got_operand.
+ (PREDICATE_CODES): Add global_got_operand, local_got_operand and
+ small_data_pattern. Remove CONST from const_arith_operand's entry.
+
+ * config/mips/mips.c (UNSPEC_ADDRESS_P, CONST_GP_P): New macros.
+ (UNSPEC_ADDRESS, UNSPEC_ADDRESS_TYPE): Likewise.
+ (mips_constant_type): Delete.
+ (mips_symbol_type): Add SYMBOL_GOTOFF_PAGE, SYMBOL_GOTOFF_GLOBAL,
+ SYMBOL_GOTOFF_CALL and SYMBOL_GOTOFF_LOADGP.
+ (NUM_SYMBOL_TYPES): New macro.
+ (mips_address_type): Remove ADDRESS_INVALID.
+ (machine_function): Add has_gp_insn_p.
+ (mips_constant_info): Delete.
+ (mips_address_info): Add the address type as an extra field. Replace
+ the c field with symbol_type.
+ (mips_split_p, mips_lo_relocs, mips_hi_relocs): New arrays.
+ (TARGET_DELEGITIMIZE_ADDRESS): Remove definition.
+ (mips_reloc_offset_ok_p, mips_classify_constant): Delete.
+ (mips_split_const, mips_symbolic_constant_p): New functions.
+ (mips_symbolic_address_p): Take the symbol type and mode as arguments.
+ (mips_classify_address): Return true if the address is valid, storing
+ its type in INFO. Use mips_symbolic_constant_p. Use mips_lo_relocs[]
+ to test whether a LO_SUM address is allowed.
+ (mips_symbol_insns): Return 0 for general mips16 symbols.
+ Reorder SYMBOL_GOT_GLOBAL case to match mips_symbol_type definition.
+ Handle the new SYMBOL_GOTOFF_*s.
+ (mips_address_insns): Update call to mips_classify_address.
+ (mips_const_insns): Be more fussy about HIGH constants. Remove use
+ of mips_classify_constant. Be more accurate about CONSTs.
+ (mips_global_pic_constant_p): Delete.
+ (const_arith_operand): Only accept CONST_INTs.
+ (call_insn_operand): Remove call to mips_classify_constant.
+ Let mips_symbolic_constant_p check for invalid offsets.
+ (move_operand): Check for general_operands first. Only accept symbolic
+ constants if they satisfy mips_symbolic_constant_p and cannot be split.
+ (symbolic_constant): Use mips_symbolic_constant_p.
+ (global_got_operand, local_got_operand): New predicates.
+ (stack_operand): Update call to mips_classify_address.
+ (mips_legitimate_address_p): Likewise.
+ (mips_reloc, mips_lui_reloc): Delete.
+ (mips_force_temporary): Only use the given temporary if no_new_pseudos.
+ Use emit_move_insn.
+ (mips_split_symbol, mips_unspec_address): New functions.
+ (mips_unspec_offset_high): New function.
+ (mips_load_got): Replace reloc argument with a symbol_type.
+ Use mips_unspec_address to create the address and put it in a
+ LO_SUM with the base register.
+ (mips_load_got16, mips_load_got32): Delete.
+ (mips_emit_high, mips_legitimize_symbol): Delete.
+ (mips_gotoff_global): New function.
+ (mips_load_got_page, mips_load_got_global): New functions.
+ (mips_legitimize_symbol): Inline handling of LO_SUM splits.
+ (mips_legitimize_const_move): Likewise. Remove HIGH handling.
+ Inline code to handle constants plus invalid offsets. Use
+ mips_split_symbol to legitimize constant pool addresses.
+ (mips_delegitimize_address): Delete.
+ (mips_rtx_costs): Give legitimate symbolic constants and CONST_DOUBLEs
+ a cost of 1 insn. Give the rest a cost of CONSTANT_POOL_ADDRESS.
+ (mips_subword): Pass memrefs through mips_rewrite_small_data.
+ (mips_output_move): Remove use of mips_classify_constant.
+ (mips_expand_call): Use mips_unspec_offset_high to calculate the
+ high part of the GOT address for calls to global functions.
+ (override_options): Initialize mips_split_p[], mips_lo_relocs[]
+ and mips_hi_relocs[].
+ (print_operand): Use print_operand_reloc to handle '%h' and '%R'.
+ Remove use of mips_classify_constant.
+ (mips_reloc_string): Delete.
+ (print_operand_reloc): New function.
+ (print_operand_address): Update call to mips_classify_address.
+ (mips_rewrite_small_data_p, small_data_pattern_1): New functions.
+ (small_data_pattern): New predicate.
+ (mips_rewrite_small_data_1, mips_rewrite_small_data): New functions.
+ (mips_function_has_gp_insn): New function.
+ (mips_global_pointer): Use it.
+ (mips_gp_insn): Delete.
+ (mips_expand_prologue): When compiling for n32/n64 abicalls, use a
+ single loadgp pattern to initialize $gp. Pass it the offset of _gp
+ from the start of the current function.
+ (mips16_gp_pseudo_reg): Revert last patch.
+
+ * config/mips/mips.md (RELOC_*): Delete.
+ (UNSPEC_LOADGP, UNSPEC_FIRST_ADDRESS): New constants.
+ (got): New insn attribute.
+ (type): Set to "load" if got == load.
+ (length): Set to 4 if got == load, 8 if got == xgot_high.
+ (lui[sd]i): Delete.
+ (*xgot_hi[sd]i, *xgot_lo[sd]i): New patterns.
+ (*got_disp[sd]i, *got_page[sd]i): Likewise.
+ (*low[sd]i): Change constraints to "d". Add a new define_split to
+ rewrite small data constants into LO_SUMs.
+ (loadgp): New insns.
+
+2003-11-04 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/_tilib.c: Use _ABI* in _MIPS_SIM tests.
+
+2003-11-04 DJ Delorie <dj@redhat.com>
+
+ * config/v850/v850.md (mulhisi3): Expand the const_int case
+ separately to avoid trying to sign extend the const.
+
+2003-11-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * emit-rtl.c (copy_rtx_if_shared): Don't allow MEMs with constant
+ addresses to be shared.
+ (force_const_mem): Return a copy of the pool entry.
+
+2003-11-03 Andreas Jaeger <aj@suse.de>
+
+ * Makefile.in (GCC_CFLAGS): Remove @WERROR@ again.
+
+2003-11-03 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (cpp.dvi): New target split from cpp.info.
+ (gcc.dvi): New target split from gcc.info.
+ (gccint.dvi): New target split from gccint.info.
+ (cppinternals.dvi): New target split from cppinternals.info
+ (gccinstall.info): New specific rule.
+ (gccinstall.dvi): Likewise.
+ (dvi): Move targets to $(docobjdir).
+ ($(docobjdir)/%.dvi): New implicit rule.
+
+2003-11-03 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * doc/gty.texi (tag, desc): Say more about role of desc values in
+ selecting between tags.
+
+2003-11-03 Alexander Kabaev <ak03@gte.com>
+
+ * real.c (encode_ieee_single): Ensure proper promotion.
+
+2003-11-03 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * doc/contrib.texi: Add Giovanni Bajo, Dara Hazeghi, Falk Hueffner,
+ and Andrew Pinski.
+
+2003-11-03 Syd Polk <spolk@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Add G3, G4, and G5
+ marketing names to the list of supported processors.
+ * config/rs6000/rs6000.h: Ditto.
+ * doc/invoke.texi: Ditto.
+ * config.gcc: Ditto.
+
+2003-11-03 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * fixinc/inclhack.def (stdio_va_list): Allow tab before va_list.
+ Merge two substitutions.
+ * fixinc/fixincl.x: Regenerate.
+ Fixes PR bootstrap/12666.
+
+2003-11-03 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/install-old.texi: Remove VMS documentation.
+
+2003-11-03 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (override_options): Remove hack enabling 128bit long double
+ commited by accident.
+
+2003-11-02 Per Bothner <per@bothner.com>
+
+ * c-opts.c (needValue): Do cpp_find_main_file before processing
+ any imacros flags, so pfile->main_file is set for the latter.
+
+2003-11-03 Andreas Jaeger <aj@suse.de>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (GCC_CFLAGS): Allow blacklisting of warnings.
+ (SYSCALLS.c.X-warn): Suppress warnings.
+
+2003-11-02 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR optimization/12845
+ * pa.c (output_cbranch): Use cmpb for DImode comparisons with 0.
+
+2003-11-02 Zack Weinberg <zack@codesourcery.com>
+
+ * print-rtl.c (print_rtx): Call PRINT_REG with second argument -1.
+ * config/i386/i386.c (print_reg): Abort on a virtual register
+ if code != -1; not if file == asm_out_file.
+ * config/i386/i386.h (PRINT_REG): Document meaning of CODE == -1.
+ (DEBUG_PRINT_REG): Delete, unused.
+
+2003-11-02 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/fde-glibc.c (_GNU_SOURCE): Define to 1 instead of
+ empty to avoid conflict with the definition from configure.
+
+2003-11-02 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/10817
+ * ifcvt.c (noce_emit_move_insn): Improve documentation comment.
+ (noce_try_move): New function to optimize an if-the-else into an
+ unconditional move, i.e. "if (a!=b) x=a; else x=b" into "x=a".
+ (noce_process_if_block): Attempt simplification with noce_try_move.
+
+ * simplify-rtx.c (simplify_ternary_operation): Some minor fixes
+ and improvements to the optimizations of IF_THEN_ELSE expressions.
+ (simplify_subreg): Silence signed/unsigned comparison warning.
+
+2003-11-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * Makefile.in (targhooks.o, reload.o): Update dependencies.
+ (GTFILES): Add targhooks.c.
+ (gt-targhooks.h): New rule; depend on s-gtype.
+ * target.h (direct_pool_load_p): New hook.
+ * target-def.h (TARGET_DIRECT_POOL_LOAD_P): New macro.
+ (TARGET_INITIALIZER): Include it.
+ * targhooks.h (default_direct_pool_load_p): Declare.
+ (hook_bool_machine_mode_true): Declare.
+ * targhooks.c: Include insn-config.h, recog.h, ggc.h and
+ gt-targhooks.h.
+ (pool_symbol): New variable.
+ (default_direct_pool_load_p): New function.
+ (hook_bool_machine_mode_true): New function.
+ * reload.c: Include target.h.
+ (find_reloads): If an alternative will force a constant into memory,
+ count an extra reload if constant pool symbols are not valid
+ addresses. If an alternative uses memory to move values between
+ registers, count the move as two reloads rather than one.
+ * config/s390/s390.c (TARGET_DIRECT_POOL_LOAD_P): Define.
+ * doc/tm.texi (TARGET_DIRECT_POOL_LOAD_P): Document.
+
+2003-11-02 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/12799
+ * postreload.c (reload_cse_move2add): Generate the add2
+ patterns manually.
+
+2003-11-02 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_partial_nregs) [TARGET_ARCH64]:
+ Return 0 for all complex modes whose size is lesser or equal to
+ a word. Add a ??? comment for the condition used with 16-byte
+ aligned modes.
+
+2003-11-01 Kelley Cook <kcook@gcc.gnu.org>
+
+ * .cvsignore: Remove c-parse* and tradcif.c.
+ * objc/.cvsignore: Delete.
+
+2003-11-01 Roger Sayle <roger@eyesopen.com>
+
+ * unwind-sjlj.c (_Unwind_GetCFA): Return (_Unwind_Word)0 instead
+ of NULL.
+
+2003-11-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * som.h (DO_GLOBAL_DTORS_BODY): Change to C90 declaration.
+
+ * libgcc2.c (SYMBOL__MAIN): Provide C90 declaration.
+
+ * collect2.c (scan_libraries): Fix typos.
+
+ PR preprocessor/12847
+ * cppfiles.c, cppexp.c, cpperror.c, cpplib.h, cpplib.c, cpplex.c,
+ cppinit.c, cpptrad.c, cppmacro.c, fix-header.c, cpppch.c, c-pch.c,
+ c-incpath.c, cppcharset.c (DL_WARNING, DL_WARNING_SYSHDR, DL_PEDWARN,
+ DL_ERROR, DL_ICE, DL_EXTRACT, DL_WARNING_P): Prefix macro names with
+ "CPP_".
+
+2003-11-01 Fariborz Jahanian <fjahanian@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_mixed_function_arg): Correct
+ no_units calculation.
+
+2003-11-01 Andreas Jaeger <aj@suse.de>
+
+ * unwind-dw2.c (_Unwind_FrameState): Remove commas at end of
+ enumeration list.
+
+2003-11-01 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/sysv4.h (SDATA_SECTION_FUNCTION): Update to C90
+ prototypes.
+ (SBSS_SECTION_FUNCTION): Likewise.
+
+2003-11-01 Andreas Jaeger <aj@suse.de>
+
+ * Makefile.in (GCC_CFLAGS): Add @WERROR@ for target files.
+
+2003-11-01 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * config/rs6000/sysv4.h (EXTRA_SECTION_FUNCTIONS): Update to C90
+ prototypes.
+
+2003-11-01 Andreas Jaeger <aj@suse.de>
+
+ * unwind-dw2.c (_Unwind_FindEnclosingFunction): Constify variable.
+ (uw_frame_state_for): Constify variables.
+ (extract_cie_info): Constify first argument.
+
+ * unwind-dw2-fde-darwin.c: Adjust prototype of
+ _Unwind_Find_registered_FDE for recent changes.
+ (examine_objects): Constify return value and local variable result.
+ (_Unwind_Find_FDE): Constify return value and local variable ret.
+
+2003-10-31 Per Bothner <pbothner@apple.com>
+
+ * c-opts.c (finish_options): Change to returns boolean - false iff
+ the call to cpp_find_main_file fails.
+ (c_common_init): Skip preprocess_file if finish_options failed.
+ (c_common_parse_file): Break if finish_options failed.
+ Fixes PR preprocessor/12545.
+
+2003-10-31 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * aclocal.m4: Blacklist ultrix* for mmap file.
+ * configure: Rebuilt.
+
+ * function.c (assign_parms): Add ATTRIBUTE_UNUSED to variable
+ reg_parm_stack_space.
+ * toplev.c (default_get_pch_validity): Fix warning.
+
+ * vax.c: Include toplev.h.
+ (vax_init_libfuncs): Fix typo (umod).
+ * vax.h (ASM_COMMENT_START): Define.
+ (PRINT_OPERAND): Fix warning when HOST_WIDE_INT is a long long.
+
+2003-10-31 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11968
+ * expr.c (expand_expr <MULT_EXPR>): Remove inappropriate and
+ confusing comment; distributivity isn't handled in expand_expr.
+ * fold-const.c (extract_muldiv_1 <PLUS_EXPR>): Allow overflow
+ in distributivity, if wrap-around semantics are specified with
+ -fwrapv.
+
+2003-11-01 Alan Modra <amodra@bigpond.net.au>
+
+ PR 12315
+ * final.c (profile_function): Allow for NULL svrtx.
+
+2003-10-31 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (pa_select_section): Use new style declaration.
+ * som.h (readonly_data): Likewise.
+
+2003-10-31 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config/rs6000/rs6000.c: Update to C90 prototypes.
+
+2003-10-31 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/7513
+ * arm.h (CONDITIONAL_REGISTER_USAGE): Disable use of LR in Thumb
+ code.
+
+2003-10-31 Andreas Jaeger <aj@suse.de>,
+ Zack Weinberg <zack@codesourcery.com>
+
+
+ * crtstuff.c (__register_frame_info, __register_frame_info_bases)
+ (__deregister_frame_info, __deregister_frame_info_bases):
+ Constify void * argument.
+ * unwind-dw2-fde.h (struct fde_vector):
+ Constify 'orig_data' and 'array' fields.
+ (__register_frame_info, __register_frame_info_bases)
+ (__deregister_frame_info, __deregister_frame_info_bases):
+ Constify void * argument.
+ (get_cie, next_fde, _Unwind_Find_FDE): Constify arguments,
+ return values, and casts of type fde *, struct dwarf_fde *,
+ and struct dwarf_cie *.
+ * unwind-dw2-fde.c (__register_frame_info, __register_frame_info_bases)
+ (__deregister_frame_info, __deregister_frame_info_bases):
+ Constify void * argument.
+ (get_cie_encoding, ): Constify struct dwarf_cie * argument.
+ (get_fde_encoding, fde_unencoded_compare, fde_single_encoding_compare)
+ (fde_mixed_encoding_compare, fde_compare_t, start_fde_sort, fde_insert)
+ fde_split, SWAP, frame_downheap, frame_heapsort)
+ (classify_object_over_fdes, add_fdes, linear_search_fdes,
+ binary_search_unencoded_fdes, binary_search_single_encoding_fdes,
+ binary_search_mixed_encoding_fdes, search_object, _Unwind_Find_FDE):
+ Constify arguments, local variables, return values, and casts
+ of type fde *, fde **, struct dwarf_fde *, and struct dwarf_cie *.
+ Use const pointer types in sizeof expressions, for clarity.
+ * unwind-dw2-fde-glibc.c
+ (_Unwind_find_registered_FDE, _Unwind_find_FDE): Constify return value.
+ (struct unw_eh_callback_data): Constify 'ret' field.
+
+2003-10-31 Fariborz Jahanian <fjahanian@apple.com>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_mixed_function_arg): New.
+ (function_arg): Call it.
+ (rs6000_function_value): Widen integral return value to mode based
+ on TARGET_32BIT, not word_mode.
+ * config/rs6000/rs6000.h (PROMOTE_MODE): Likewise.
+ (UNITS_PER_ARG): New.
+ (RS6000_ARG_SIZE): Use it.
+
+2003-10-31 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * .cvsignore: No longer ignore gengtype-lex.c, gengtype-yacc.c,
+ and gengtype-yacc.h.
+
+2003-10-31 Richard Earnshaw <rearnsha@arm.com>
+
+ PR optimization/8896
+ * postreload.c (reload_combine): Check that REGY doesn't die in an
+ insn of the form (set (regx) (plus (regx) (regy))), ie REGX != REGY.
+
+2003-10-31 Josef Zlomek <zlomekj@suse.cz>
+
+ PR/10239
+ * cfgrtl.c (delete_insn): Decrease LABEL_NUSES for all REG_LABEL notes.
+
+2003-10-31 Josef Zlomek <zlomekj@suse.cz>
+
+ PR/11640
+ * cfgrtl.c (try_redirect_by_replacing_jump): Move jump
+ immediatelly before BARRIER.
+
+2003-10-31 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (STRICT2_WARN): Add -Wold-style-definition.
+
+2003-10-31 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/11271
+ * reload.c (find_reloads_address): Handle any register in
+ (PLUS (PLUS (REG) (REG)) (CONST_INT).
+
+2003-10-31 Richard Earnshaw <rearnsha@arm.com>
+
+ * ggc-page.c (ggc_pch_read): Wrap call to poison_pages in
+ ENABLE_GC_CHECKING not in GGC_POISON.
+
+2003-10-31 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR bootstrap/9863
+ * configure.in: Bail out if awk is missing.
+ * configure: Regenerate.
+
+ PR ada/12761
+ * Makefile.in: Move default definitions of X_ADA_CFLAGS,
+ T_ADA_CFLAGS, X_ADAFLAGS, T_ADAFLAGS from ada/Make-lang.in to here.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * c-objc-common.c (c_tree_printer): Handle types correctly.
+ Factor code a bit.
+
+2003-10-30 Kelley Cook <kcook@gcc.gnu.org>
+
+ * value-prof.c, web.c: Update to C90.
+
+2003-10-30 Eric Christopher <echristo@redhat.com>
+
+ * function.c (purge_addressof_1): Add case for REG_RETVAL
+ notes when modes are unequal.
+
+2003-10-31 Jan Hubicka <jh@suse.cz>
+
+ * i386-modes.def: Add XFmode format adjustment.
+
+2003-10-30 Jan Hubicka <jh@suse.cz>
+
+ * real.c (encode_ieee_extended): Back out previous patch.
+
+2003-10-30 Jan Hubicka <jh@suse.cz>
+
+ * real.c (encode_ieee_extended): Initialize whole array.
+ * reg-stack.c (move_for_stack_reg0: Use always XFmode.
+ * i386-modes.def: Change definitions of TFmode and XFmode.
+ * i386.c (classify_argument): Rename TFmodes to XFmodes; add new TFmode
+ code.
+ (construct_container): Allow constructing of TFmode integer containers.
+ (ix86_return_in_memory): XFmode is not returned in memory.
+ (init_ext_80387_constants): Always use XFmode.
+ (print_operand): Likewise.
+ (ix86_prepare_fp_compare_regs): Likewise.
+ (split_to_parts): Deal with TFmode.
+ (split_long_move): Simplify.
+ (ix86_init_mmx_sse_builtins): Add __float80, __float128.
+ (ix86_memory_move_cost): Do not confuse TFmode.
+ * i386.h (LONG_DOUBLE_TYPE_SIZE): Set to 96.
+ (IS_STACK_MODE): TFmode is not stack mode.
+ (HARD_REGNO_NREGS, CLASS_MAX_NREGS): Deal nicely with XFmode.
+ (VALID_SSE_REG_MODE): Allow TFmode.
+ (VALID_FP_MODE_P): Disallow TFmode.
+ (VALID_INT_MODE_P): Allow TFmode in 64bit mode.
+ * i386.md (TFmode patterns): Kill.
+ (movtf, motf_rex64): New patterns.
+
+2003-10-30 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (adddi3): Fix typo in mips16 stack pointer code.
+
+2003-10-30 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (mov_lwl): Use memory_operand where appropriate.
+ (mov_lwr, mov_swl, mov_swr): Likewise.
+ (mov_ldl, mov_ldr, mov_sdl, mov_sdr): Likewise.
+
+2003-10-30 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_global_pointer): Don't try to use $25.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * config/mips/mips.c (mips_build_builtin_va_list): Use runtime
+ test for irix6 rather than preprocessor test.
+
+2003-10-30 Richard Henderson <rth@redhat.com>
+
+ * cppcharset.c (one_utf8_to_utf16): Initialize 's' to silence warning.
+
+2003-10-30 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (struct machine_function): Use save_return_addr_p
+ as a general flag that the return address register needs to be saved,
+ not necessarily because of __builtin_return_addr (0).
+ (s390_split_branches): Remove TEMP_REG and TEMP_USED arguments,
+ remove special handling of zSeries machines.
+ (s390_optimize_prolog): Remove TEMP_USED argument, treat the return
+ register as a regular register on zSeries machines.
+ (s390_reorg): Adjust calls to s390_split_branches and
+ s390_optimize_prolog.
+ (s390_frame_info): On zSeries machines, do not assume the return
+ register is always used. Update regs_ever_live with current data
+ for the special registers.
+ (s390_emit_epilogue): Use save_return_addr_p to determine whether
+ the return register was saved.
+ * config/s390/s390.h (CONDITIONAL_REGISTER_USAGE): Do not mark
+ RETURN_REGNUM fixed on zSeries machines.
+ (REG_ALLOC_ORDER): Use RETURN_REGNUM last.
+ * config/s390/s390.md ("*doloop_si"): Handle branch overflow
+ via ahi-jgne pair on zSeries machines.
+ ("*doloop_di"): Likewise.
+ ("*doloop_di_long"): Remove.
+
+2003-10-30 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_override_options): Revert change of arm_constant_limit
+ when optimizing for size.
+
+2003-10-29 Richard Henderson <rth@redhat.com>
+
+ * fold-const.c (fold_single_bit_test): Convert the input to the
+ operational intermediate type.
+
+2003-10-29 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (std_build_builtin_va_list): New.
+ * expr.h (std_build_builtin_va_list): Declare.
+ * defaults.h (BUILD_VA_LIST_TYPE): New.
+ * system.h (BUILD_VA_LIST_TYPE): Poison.
+ * target-def.h (TARGET_BUILD_BUILTIN_VA_LIST): New.
+ * target.h (struct gcc_target): Add build_builtin_va_list.
+ * tree.c (build_common_tree_nodes_2): Use it.
+
+ * config/alpha/alpha-protos.h, config/alpha/alpha.c,
+ config/alpha/alpha.h, config/alpha/unicosmk.h,
+ config/d30v/d30v-protos.h, config/d30v/d30v.c, config/d30v/d30v.h,
+ config/i386/i386-protos.h, config/i386/i386.c, config/i386/i386.h,
+ config/i860/i860-protos.h, config/i860/i860.c, config/i860/i860.h,
+ config/i960/i960-protos.h, config/i960/i960.c, config/i960/i960.h,
+ config/mips/iris6.h, config/mips/mips-protos.h, config/mips/mips.c,
+ config/mips/mips.h, config/rs6000/rs6000-protos.h,
+ config/rs6000/rs6000.c, config/rs6000/rs6000.h,
+ config/s390/s390-protos.h, config/s390/s390.c, config/s390/s390.h,
+ config/sh/sh-protos.h, config/sh/sh.c, config/sh/sh.h,
+ config/xtensa/xtensa-protos.h, config/xtensa/xtensa.c,
+ config/xtensa/xtensa.h: Rename foo_build_va_list to
+ foo_build_builtin_va_list; make it static. Define
+ TARGET_BUILD_BUILTIN_VA_LIST. Remove BUILD_VA_LIST_TYPE.
+ Update protos.
+
+ * config/i386/i386.c (ix86_expand_carry_flag_compare): Make static.
+ * config/iq2000/iq2000.h (BUILD_VA_LIST_TYPE): Remove.
+
+2003-10-29 James E Wilson <wilson@specifixinc.com>
+
+ * recog.c (asm_operand_ok): Add missing break after case 'X'.
+ Change if statements to else if statements in default case.
+ (extract_constrain_insn_cached): Fix misspelling of constrain_operands
+ in comment.
+ (constrain_operands_cached): Likewise.
+ (constrain_operands): Change if statements to else if statements in
+ default case.
+ * reload.c (find_reloads): Likewise.
+
+2003-10-29 Richard Henderson <rth@redhat.com>
+
+ * config/m68k/m68k.c (notice_update_cc): Clear cc status for
+ shifts and rotates.
+
+2003-10-30 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.md: Remove duplicate pattern.
+
+2003-10-29 Hans-Peter Nilsson <hp@axis.com>
+
+ * real.c (do_divide): Initialize result with a 0.
+
+ * configure.in <enable-checking for valgrind>: Look for
+ <valgrind/memcheck.h> first. AC_DEFINE HAVE_VALGRIND_MEMCHECK_H
+ if it exists.
+ * configure, config.in: Regenerate.
+ * ggc-common.c [ENABLE_VALGRIND_CHECKING &&
+ HAVE_VALGRIND_MEMCHECK_H]: Include <valgrind/memcheck.h>. Use
+ #elif for other alternatives.
+ * ggc-page.c: Ditto.
+ * ggc-zone.c: Don't assume <valgrind/memcheck.h>; instead copy
+ include structure from ggc-common.c.
+
+2003-10-29 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa-linux.h (ASM_OUTPUT_ADDR_VEC_ELT): Use label in big switch ELTs.
+ (ASM_OUTPUT_ADDR_DIFF_ELT): Use label difference in big switch ELTs.
+ * pa.c (pa_adjust_insn_length): Check for btable branches using
+ attribute TYPE_BTABLE_BRANCH.
+ (pa_reorg): Simplify.
+ * pa.h (CASE_VECTOR_MODE): Change big switch mode to SImode.
+ (ASM_OUTPUT_ADDR_VEC_ELT): As above.
+ (ASM_OUTPUT_ADDR_DIFF_ELT): As above.
+ * pa.md (btable_branch): New instruction type.
+ (in_branch_delay, in_nullified_branch_delay, in_call_delay): Disallow
+ btable branches.
+ (define_delay): Add btable branches to insn types that may have an
+ insn in the delay position.
+ (Z2, Z3): Add btable branch to list.
+ Simplify unamed pattern set copy pic_label_operand to register. Add
+ PA 2.0 variant.
+ (short_jump): New jump for use in branch tables.
+ (casesi, casesi0): Revise for new branch table formats.
+ (casesi32, casesi32p, casesi64p): New casesi patterns.
+ (indirect_jump): Move.
+
+2003-10-29 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.h (UNITS_PER_WORD): Revert to
+ !TARGET_POWERPC64.
+ (UNITS_PER_GPR_WORD): Delete.
+ (HARD_REGNO_NREGS): Revert to UNITS_PER_WORD.
+ (HARD_REGNO_MODE_OK): Same.
+ (CLASS_MAX_NREGS): Same.
+
+2003-10-29 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.h (ASM_COMMENT_START): Define.
+
+2003-10-29 Zack Weinberg <zack@codesourcery.com>
+
+ * genmodes.c (complete_mode): Record MODE_CC, MODE_INT,
+ MODE_FLOAT, and MODE_PARTIAL_INT modes as having one
+ component, not zero.
+
+2003-10-29 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/t-ia64 (LIB2ADDEH): Add $(srcdir)/gthr-gnat.c.
+
+2003-10-29 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_partial_nregs) [TARGET_ARCH64]:
+ Never return 1 for complex integral modes whose size is lesser or
+ equal to a word.
+ (function_arg_pass_by_reference) [TARGET_ARCH64]: Mention CTImode
+ in the comment.
+ (function_arg_advance) [TARGET_ARCH64]: Don't special-case complex
+ modes.
+ (sparc_va_arg) [TARGET_ARCH64]: Handle any types whose size is
+ greater than 16 bytes by reference.
+
+2003-10-29 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * config/ia64/ia64.c (ia64_assemble_integer): Test POINTER_SIZE,
+ not TARGET_ILP32.
+ (ia64_initialize_trampoline): Use globalize_label target call.
+
+2003-10-29 Andreas Schwab <schwab@suse.de>
+
+ * doc/install.texi (Building): Add a sentence about building Ada
+ for a canadian cross.
+
+2003-10-28 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/ia64.c (cmptf_libfunc): New static.
+ (ia64_expand_compare): Add logic to open-code calls to
+ _U_Qfcmp for TFmode comparisons.
+ (ia64_hpux_init_libfuncs): Initialize cmptf_libfunc.
+ Set libfuncs for TFmode eq/ne/gt/ge/lt/gt to 0; these should
+ never be generated anymore.
+ * config/ia64/ia64.md (cmptf): New expander.
+
+2003-10-28 Zack Weinberg <zack@codesourcery.com>
+
+ * ia64.md (UNSPEC_SETF_EXP,UNSPEC_FR_SQRT_RECIP_APPROX): New constants.
+ (*sqrt_approx): New instruction pattern for approximate square roots.
+ (*setf_exp_xf): New instruction pattern for exponentiation.
+ (*maddxf4_alts_truncsf): New instruction pattern for truncation.
+ (sqrtsf2_internal_thr): New define_and_split implementing
+ throughput-optimized inline calculation of SFmode square root.
+ (sqrtdf2_internal_thr): Likewise for DFmode.
+ (sqrtxf2_internal_thr): Likewise for XFmode.
+ (sqrtsf2, sqrtdf2, sqrtxf2): New expanders to choose between
+ latency- and throughput-optimized square root algorithms.
+ * ia64.h (MASK_INLINE_SQRT_LAT, MASK_INLINE_SQRT_THR,
+ TARGET_INLINE_SQRT_LAT, TARGET_INLINE_SQRT_THR, TARGET_INLINE_SQRT):
+ New macros.
+ (TARGET_SWITCHES): Add -minline-sqrt-min-latency and
+ -minline-sqrt-max-throughput.
+ * ia64.c (ia64_override_options): If both -minline-sqrt-min-latency
+ and -minline-sqrt-max-throughput are given, notify the user
+ that both options cannot be used simultaneously.
+ If -minline-sqrt-min-latency is given, notify the user that
+ this mode is not yet implemented.
+ (rtx_needs_barrier): Reformat initial comment to obey
+ 72-character width limit. Support UNSPEC_SETF_EXP and
+ UNSPEC_FR_SQRT_RECIP_APPROX.
+
+2003-10-29 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.md (movdf_softfloat64): Allow dummy ctr,ctr
+ moves.
+
+2003-10-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR target/11598
+ PR libgcj/10610
+ * config/rs6000/sysv4.h (PREFERRED_STACK_BOUNDARY): New macro.
+
+2003-10-28 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_output_epilogue): When using a frame pointer, don't emit
+ an extra stack adjustment insn if the stack pointer is already
+ pointing at the right place.
+ (use_return_insn): Allow a return insn to be used when we have a
+ frame pointer if the stack pointer is in the right place.
+ (output_return_instruction): Handle it.
+
+2003-10-28 Andreas Jaeger <aj@suse.de>
+
+ * ggc-zone.c (check_cookies): Add missing variable.
+ Add void to prototypes.
+
+2003-10-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/mips/irix6-libc-compat.c (inet_makeaddr): Prototype.
+ * crtstuff.c (__do_global_ctors_1): Move prototype.
+ * unwind-dw2.c (NO_SIZE_OF_ENCODED_VALUE): Define when
+ appropriate.
+ * unwind-sjlj.c (_Unwind_GetCFA, _Unwind_FindEnclosingFunction):
+ Mark parameter with __attribute__((unused)).
+
+2003-10-27 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (pushdecl): Clarify comment.
+
+2003-10-27 Arnaud Charlet <charlet@act-europe.fr>
+
+ * doc/install.texi: Update instructions for Ada cross builds
+
+ PR ada/5909:
+ * doc/sourcebuild.texi: Document Ada test suite.
+
+2003-10-27 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c: Convert to ISO C90.
+ * config/m68hc11/m68hc11-protos.h: Likewise.
+
+2003-10-27 Jan Hubicka <jh@suse.cz>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * toplev.c (enum dump_file_index, dump_file): Fix ordering of
+ webizer pass dump.
+
+2003-10-27 Jakub Jelinek <jakub@redhat.com>
+ Jan Hubicka <jh@suse.cz>
+
+ * reload1.c (struct elim_table): Change offset, initial_offset and
+ previous_offset fields to HOST_WIDE_INT.
+ (offsets_at): Change from int to HOST_WIDE_INT.
+ (reload): Adjust offsets_at initialization.
+ (eliminate_regs_in_insn): Change type of offset to HOST_WIDE_INT.
+ (verify_initial_elim_offsets): Change type of t to HOST_WIDE_INT.
+ * config/i386/i386.c (ix86_compute_frame_layout): Change offset type
+ to HOST_WIDE_INT. Don't save regs using mov for huge frame sizes
+ if TARGET_64BIT.
+ (pro_epilogue_adjust_stack): New function.
+ (ix86_expand_prologue, ix86_expand_epilogue): Use it.
+ * config/i386/i386.md (pro_epilogue_adjust_stack): Remove.
+ (pro_epilogue_adjust_stack_1): Remove * in front of name.
+ (pro_epilogue_adjust_stack_rex64): Handle -2147483648 properly.
+ (pro_epilogue_adjust_stack_rex64_2): New insn.
+
+ * config/i386/i386.c (ix86_expand_epilogue): Fix comment typo.
+
+ * config/i386/i386.c (ix86_expand_call): Replace 40 with
+ FIRST_REX_INT_REG + 3 /* R11 */.
+
+2003-10-26 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.md (attr cannot_copy): New.
+ (call_osf_2_er, call_value_osf_2_er, ldgp_er_1, ldgp_er_2,
+ prologue_ldgp_er_2, prologue_ldgp_1): Set it.
+ * config/alpha/alpha.c (alpha_cannot_copy_insn_p): Test it.
+
+2003-10-26 Daniel Berlin <dberlin@dberlin.org>
+
+ * ggc-zone.c: New file, zone allocating collector.
+ * configure: Accept zone option for --with-gc
+ * configure.in: Ditto.
+ * ggc.h (ggc_pch_count_object): Pass bool indicating
+ stringiness. Update all callers.
+ (ggc_pch_alloc_object): Ditto.
+ (ggc_pch_write_object): Ditto.
+ (ggc_alloc_rtx): Use typed allocation, since all RTX's are of a single
+ type.
+ (ggc_alloc_rtvec): Ditto.
+ (ggc_alloc_tree): Use zone allocation, since some things using this macro
+ aren't a single typecode.
+ * ggc-none.c (ggc_alloc_typed): New function.
+ (ggc_alloc_zone): Ditto.
+ * ggc-page.c: Ditto on both functions.
+
+2003-10-26 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_compute_frame_layout): Ensure FPU related
+ frame information is always valid.
+ (m68k_output_function_prologue): Remove superfluous TARGET_68881
+ test; fix formatting.
+
+2003-10-26 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_compute_frame_layout): Swap reg_mask and
+ reg_rev_mask computation.
+ (m68k_output_function_prologue): Fix usage of current_frame (one typo
+ and one missing); use reg_rev_mask not reg_mask.
+ (m68k_output_function_epilogue): Fix usage of current_frame;
+ use fpu_rev_mask not fpu_mask.
+
+2003-10-26 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c (m68k_output_function_prologue): Eliminate
+ num_saved_regs, use current_frame.reg_no instead.
+
+2003-10-26 Bernardo Innocenti <bernie@develer.com>
+ Paul Dale <pauli@snapgear.com>
+
+ * doc/extend.texi (interrupt_handler): Add m68k to the
+ list of processors implementing it.
+ * doc/invoke.texi (-msep-data): Document new m68k option.
+ (-mno-sep-data): Likewise.
+ (-mid-shared-library): Likewise.
+ (-mno-id-shared-library): Likewise.
+ (-mshared-library-id): Likewise.
+
+2003-10-26 Andreas Jaeger <aj@suse.de>
+
+ * unwind-dw2.c (_Unwind_GetGR): Avoid warning about unsigned
+ comparison.
+ (_Unwind_SetGR): Likewise.
+
+2003-10-26 Ottavio Campana <ottavio@campana.vi.it>
+
+ PR target/12690
+ * config/i386/mmintrin.h (_mm_set1_pi8): Fix comment.
+
+2003-10-26 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_output_function_prologue): Move front
+ comment from here to...
+ (m68k_save_reg): ...here. Fix comment formatting.
+ (m68k_output_function_prologue): Fix comment formatting.
+ (m68k_output_function_epilogue): Likewise.
+ (const_method): Likewise.
+
+2003-10-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * toplev.c (default_get_pch_validity): Guard the use of
+ target_options with #ifdef TARGET_OPTIONS.
+ (default_pch_valid_p): Likewise.
+
+2003-10-26 Andreas Jaeger <aj@suse.de>
+ Zack Weinberg <zack@codesourcery.com>
+ Andreas Tobler <toa@pop.agri.ch>
+
+ * dwarf2out.c (output_cfi): Use HOST_WIDE_INT_PRINT.
+ (output_die): Likewise.
+ (print_die): Likewise.
+
+2003-10-26 Andreas Jaeger <aj@suse.de>
+
+ * tree.h (dwarf2out_def_cfa, dwarf2out_args_size,
+ dwarf2out_reg_save, new_loc_descr): Update prototypes for recent
+ dwarf2out.c change.
+
+ * toplev.c (default_pch_valid_p): Fix warning.
+
+2003-10-25 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_replace_rtx): Avoid allocating duplicate
+ RTL nodes. If an operator's operands are unchanged, return the
+ original argument unchanged.
+
+2003-10-26 Graham Stott <graham.stott@btinternet.com>
+
+ Fix bootstrap failure.
+ * expmed.c (store_bit_field): Don't compare bitsize against
+ modes with zero bit-size.
+
+ (extract_bit_field): Likewise
+
+2003-10-25 Jan Hubicka <jh@suse.cz>
+
+ * dwarf2out.c (dw_cfi_oprnd_struct): Offset is HOST_WIDE_INT.
+ (cfa_loc): Likewise.
+ (reg_save, stack_adjust_offset, queue_reg_save): Replace long by
+ HOST_WIDE_INT.
+ (args_size, old_args_size): change type to HOST_WIDE_INT.
+ (dwarf2out_def_cfa, dwarf2out_args_size,
+ dwarf2out_reg_save, new_loc_descr): offset is HOST_WIDE_INT.
+ (dw_val_struct): integers, unsigneds and offsets are HOST_WIDE_INT.
+ (add_AT_int, add_AT_unsigned, att_AT_offset, AT_int, AT_unsigned,
+ AT_offset): Use HOST_WIDE_INT.
+ (based_loc_descr): offset is HOST_WIDE_INT.
+ (add_data_member): Likewise.
+ (add_const_value_attribute): Simplify.
+
+2003-10-25 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (ix86_eax_live_at_start_p): New.
+ (ix86_expand_prologue): Save and restore eax around stack probe
+ if it's live.
+
+2003-10-25 Jan Hubicka <jh@suse.cz>
+
+ * cppcharset.c (one_utf8_to_utf32): Initialize 's' to silence warning.
+
+2003-10-25 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/12712
+ * reg-stack.c (convert_regs_1): Create an arbitrary input stack
+ if the block has no predecessors.
+ (convert_regs_2): Document the problem with successors whose
+ only predecessor is the block to be processed.
+ (convert_regs): Don't create the arbitrary input stack here.
+
+2003-10-24 Zack Weinberg <zack@codesourcery.com>
+
+ * genmodes.c (struct mode_data): Add contained and next_cont
+ fields.
+ (complete_mode): Maintain linked list of modes that have a
+ given component.
+ (emit_mode_unit_size): Delete.
+ (emit_mode_nunits): New.
+ (emit_insn_modes_c): Update to match.
+ (emit_mode_adjustments): Propagate size and alignment
+ adjustments from component modes to their containers.
+ * machmode.h (mode_unit_size): Delete.
+ (mode_nunits): New.
+ (GET_MODE_NUNITS): Just return the value in the table.
+ (GET_MODE_UNIT_SIZE): Compute using GET_MODE_INNER and
+ GET_MODE_SIZE.
+ * expmed.c (store_bit_field, extract_bit_field): Can use a
+ plain move instruction if bitsize >= GET_MODE_BITSIZE of
+ destination/source mode, respectively.
+ * varasm.c (assemble_real): Write out the full size of the
+ constant, not just its bitsize.
+ (output_constant): Honor TYPE_MODE of TREE_REAL_CSTs.
+
+ * config/ia64/ia64-modes.def: Define XFmode as well as TFmode.
+ Use ADJUST_BYTESIZE and ADJUST_ALIGNMENT to set size and
+ alignment of XF and TF modes in compliance with ia64 ABIs.
+ Can now hardwire the format of both modes.
+ * config/ia64/ia64.c: Change TFmode to XFmode wherever appropriate.
+ (general_tfmode_operand, destination_tfmode_operand)
+ (tfreg_or_fp01_operand, spill_tfmode_operand): Rename to
+ general_xfmode_operand, destination_xfmode_operand,
+ xfreg_or_fp01_operand, spill_xfmode_operand respectively.
+ (ia64_init_builtins): Make TYPE_PRECISION of fpreg_type
+ and float80_type be 96 so they get XFmode. Use !TARGET_HPUX,
+ not INTEL_EXTENDED_IEEE_FORMAT, to decide how to define
+ __float128.
+ * config/ia64/ia64.h: Default TARGET_HPUX to 0.
+ Change TFmode to XFmode wherever appropriate. Remove all
+ references to INTEL_EXTENDED_IEEE_FORMAT.
+ (LONG_DOUBLE_TYPE_SIZE): Varies with TARGET_HPUX.
+ (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define (always 96).
+ (PREDICATE_CODES): Update to match function renames.
+ * config/ia64/ia64.md: Change TF to XF throughout; rename all
+ patterns to match. Remove all references to
+ INTEL_EXTENDED_IEEE_FORMAT. Update predicate calls to match
+ function renames.
+ * config/ia64/ia64-protos.c: Update all prototypes to match
+ renamed functions.
+ * config/ia64/hpux.h: Redefine TARGET_HPUX to 1.
+ Remove all references to INTEL_EXTENDED_IEEE_FORMAT.
+ * config/ia64/lib1funcs.asm: Add __divxf3 as new name for
+ __divtf3; keep old name for backward compatibility.
+ (L__compat): New section providing forwarding stubs for
+ __fixtfti, __fixunstfti, __floattitf.
+ * config/ia64/t-ia64: Add __compat to LIB1ASMFUNCS.
+
+2003-10-24 Geoffrey Keating <geoffk@apple.com>
+
+ PR 10757
+ * c-pch.c: Include target.h. Improve comments.
+ (struct c_pch_validity): Add target_data_length.
+ (pch_init): Add target's validity data.
+ (c_common_valid_pch): Check target's validity data.
+ * target-def.h (TARGET_GET_PCH_VALIDITY): New.
+ (TARGET_PCH_VALID_P): New.
+ (TARGET_INITIALIZER): Add new fields.
+ * target.h: Include tm.h.
+ (struct gcc_target): Add get_pch_validity, pch_valid_p.
+ * toplev.h (default_get_pch_validity): New prototype.
+ (default_pch_valid_p): New prototype.
+ * toplev.c (default_get_pch_validity): New routine.
+ (default_pch_valid_p): New routine.
+ * Makefile.in (TARGET_H): Add TM_H. Replace all users of
+ target.h with $(TARGET_H).
+ (c-pch.o): Add TARGET_H.
+ * doc/tm.texi (PCH Target): New node.
+ (TARGET_GET_PCH_VALIDITY): Document.
+ (TARGET_PCH_VALID_P): Document.
+
+2003-10-24 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in: Define a vpath for %.texi. Remove explicit $(docdir)
+ and $(docdir)/include from any *.texi dependencies.
+ ($(docobjdir)/%.dvi): Depend on stmp-docobjdir.
+ ($(docobjdir)/%.1): Depend on .pod instead of .texi.
+ ($(docobjdir)/%.7): Likewise.
+ (%.pod): New implicit rule.
+ (cpp.pod): New dependency only rule.
+ (gcc.pod): New intermediate rule with dependencies and commands.
+ (gfdl.pod): Likewise.
+ (fsf-funding.pod): Likewise.
+
+2003-10-24 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/mkfixinc.sh: Remove special cases for svr4 and ptx, and
+ related code.
+ * fixinc/fixinc.ptx: Remove.
+ * fixinc/fixinc.svr4: Remove.
+
+2003-10-24 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (load_multiple_operation): Allow both SImode
+ and DImode if word_mode is DImode.
+ (store_multiple_operation): Likewise.
+ * config/s390/s390.md ("load_multiple", "store_multiple"): Likewise.
+ ("*load_multiple_di"): Allow only if word_mode == DImode.
+ ("movqi"): Use LLGC whenever TARGET_ZARCH.
+ ("fix_truncdfsi2"): Fix incorrect temporary size.
+ ("fix_truncsfsi2"): Likewise.
+ ("*bras_r", "*brasl_r", "*basr_r"): Remove predicate and constraint
+ string for function return value operand.
+ ("*bras_tls", "*brasl_tls", "*basr_tls"): Likewise.
+
+2003-10-24 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-parse.in (array_declarator): Use expr_no_commas.
+ Fixes PR c/11943.
+
+2003-10-24 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/linux.h: Wrap MD_FALLBACK_FRAME_STATE_FOR and
+ associated includes in #ifndef inhibit_libc.
+
+2003-10-24 Roger Sayle <roger@eyesopen.com>
+
+ * doc/libgcc.texi: Document some more of the libgcc API.
+
+2003-10-24 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_rtx_costs_1, case TARGET_THUMB): Adjust costs for
+ comparing a constant with small negative numbers and add costing
+ for constants in conjunction with AND.
+ (note_invalid_constants): Tidy previous change.
+ (thumb_cmp_operand): Tidy.
+ (thumb_cmpneg_operand): New function.
+ * arm.h (CONDITIONAL_REGISTER_USAGE): Don't use HI regs if optimizing
+ for size.
+ (FIRST_LO_REGNUM, FIRST_HI_REGNUM, LAST_HI_REGNUM): Define.
+ (PREDICATE_CODES): Add thumb_cmpneg_operand.
+ * arm.md (cbranchsi4): Convert to define_expand. Handle comparison
+ with a negative constant.
+ (cbranchsi4_insn): Matcher for cbranchsi4.
+ (cbranchsi4_scratch): Similar, but a scratch is available for
+ handling negative constants.
+ (movsi_cbranchsi4): New pattern.
+ (tstsi3_cbranch): Renamed from andsi3_cbranch_scratch, remove scratch
+ and use the TST instruction.
+ (andsi3_cbranch, orrsi3_cbranch, xorsi3_cbranch, cbranchne_decr1)
+ (addsi3_cbranch, subsi3_cbranch): Ensure that register preferencing
+ cannot see high regs or memory alternatives.
+ (bicsi3_cbranch_scratch, bicsi3_cbranch): New patterns.
+
+2003-10-24 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (note_invalid_constants): Try to extract the constant
+ pool value using avoid_constant_pool_reference; only use
+ get_pool_constant if that returns the original reference.
+
+2003-10-24 Jan Hubicka <jh@suse.cz>
+
+ PR c++/12624
+ * varasm.c (notice_global_symbol): Disqualify global registers.
+
+2003-10-23 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11414
+ * loop.c (load_mems): Use redirect_jump to forward jumps from
+ the original loop end label to the new "loop sink" block's label.
+
+2003-10-23 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/12705
+ * optabs.c (expand_binop): When expanding complex operations
+ inline, always calculate result into a new temporary register.
+ Minor code clean-ups.
+
+2003-10-24 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * objc/lang-specs.h: Handle -print-objc-runtime-info.
+ * doc/invoke.texi (Objective-C Dialect Options): Document it.
+
+2003-10-24 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/cygwin.asm: Add copyright notice. Add comment
+ on why this code is needed.
+
+2003-10-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/clzhi2.c: Fix warnings.
+ * config/h8300/ctzhi2.c: Likewise.
+ * config/h8300/fixunssfsi.c: Likewise.
+ * config/h8300/parityhi2.c: Likewise.
+ * config/h8300/popcounthi2.c: Likewise.
+
+2003-10-23 James E Wilson <wilson@specifixinc.com>
+
+ * gcc.c (option_map): Delete --target and --use-version.
+
+2003-10-23 Fariborz Jahanian <fjahanian@apple.com>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.h (UNITS_PER_WORD): Use TARGET_32BIT, not
+ TARGET_POWREPC64.
+ (UNITS_PER_GPR_WORD): Define.
+ (HARD_REGNO_NREGS): Use UNITS_PER_GPR_WORD.
+ (HARD_REGNO_CALL_PART_CLOBBERED): Define.
+ (HARD_REGNO_MODE_OK): Use UNITS_PER_GPR_WORD.
+ (CLASS_MAX_NREGS): Use UNITS_PER_GPR_WORD.
+ * config/rs6000/rs6000.c (function_arg): Generate PARALLEL for
+ DFmode and DImode in 32-bit ABI / 64-bit computation mode.
+ (rs6000_emit_prologue): Select reg_mode and reg_size using
+ TARGET_32BIT, not TARGET_POWERPC64.
+ (rs6000_function_value): Generate PARALLEL for DImode in 32-bit
+ ABI / 64-bit computation mode
+
+2003-10-22 Andrew Haley <aph@redhat.com>
+
+ * toplev.c (output_file_directive): Allow for null input_name.
+
+2003-10-22 Waldek Hebisch <hebisch@math.uni.wroc.pl>
+
+ * config/i386/i386.c (classify_argument): Handle SET_TYPE.
+
+2003-10-22 Chris Demetriou <cgd@broadcom.com>
+
+ * configure.in: In --enable-generated-files-in-srcdir option
+ handling, fix default case handling.
+ * configure: Regenerate.
+
+2003-10-22 Phil Edwards <phil@codesourcery.com>
+
+ * config.gcc: Update *-*-vxworks* generic hook and comments.
+ (arm-wrs-vxworks, i[4567]86-wrs-vxworks, mips-wrs-vxworks,
+ mips-wrs-windiss, sh-wrs-vxworks): New stanzas.
+ * genmultilib: Allow the MULTILIB_OSDIRNAMES to be mapped directly.
+ * config/svr4.h (SWITCH_TAKES_ARG): Undefine it before redefining it.
+ * config/windiss.h: New file.
+ * config/arm/t-vxworks: New file.
+ * config/arm/vxworks.h: New file.
+ * config/i386/t-vxworks: New file.
+ * config/i386/vxworks.h: New file.
+ * config/mips/t-vxworks: New file.
+ * config/mips/vxworks.h: New file.
+ * config/mips/windiss.h: New file.
+ * config/sh/t-vxworks: New file.
+ * config/sh/vxworks.h: New file.
+
+2003-10-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_output_function_epilogue): Remove.
+ (h8300_saveall_function_p): New.
+ (h8300_insert_attributes): Insert the saveall attribute if
+ #pragma saveall is specified.
+ (h8300_attribute_table): Add saveall.
+ (TARGET_ASM_FUNCTION_EPILOGUE): Remove.
+ * doc/extend.texi: Mention the saveall attribute.
+
+2003-10-22 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-typeck.c (pedantic_lvalue_warning): Unconditionally warn of
+ deprecation of casts as lvalues.
+ * fixinc/inclhack.def (obstack_lvalue_cast): New fix.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/obstack.h: New test.
+
+2003-10-22 Andreas Schwab <schwab@suse.de>
+
+ PR target/12676
+ * config/m68k/m68k.c (output_addsi3): Fix range check to work on
+ LP64 platforms.
+
+2003-10-22 Jan Hubicka <jh@suse.cz>
+
+ * dwarf2out.c (dwarf2out_abstract_function): Use DW_AT to check
+ presence of DW_AT_inline.
+ (gen_subprogram_die): Likewise; do not abort instead of emitting
+ DW_AT_not_inline.
+
+2003-10-22 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_function_possibly_inlined_p): Be conservative when
+ global info is not ready.
+
+2003-10-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/extend.texi: Mention H8S wherever H8/300H is mentioned.
+
+2003-10-22 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("movstr_short_64", "movstr_short_31"): Merge ...
+ ("*movstr_short"): ... into this insn pattern.
+ ("movstr_short"): New expander.
+ ("*movstr_long_64"): Rename from "movstr_long_64", simplify.
+ ("*movstr_long_31"): Rename from "movstr_long_31", simplify.
+ ("movstr_long"): New expander.
+ ("clrstr_short_64", "clrstr_short_31"): Merge ...
+ ("*clrstr_short"): ... into this insn pattern.
+ ("clrstr_short"): New expander.
+ ("*clrstr_long_64"): Rename from "clrstr_long_64", simplify.
+ ("*clrstr_long_31"): Rename from "clrstr_long_31", simplify.
+ ("clrstr_long"): New expander.
+ ("cmpmem_short_64", "cmpmem_short_31"): Merge ...
+ ("*cmpmem_short"): ... into this insn pattern.
+ ("cmpmem_short"): New expander.
+ ("*cmpmem_long_64"): Rename from "cmpmem_long_64".
+ ("*cmpmem_long_31"): Rename from "cmpmem_long_31".
+ ("cmpmem_long"): New expander.
+ * config/s390/s390.c (s390_expand_movstr): Use new expanders.
+ (s390_expand_clrstr): Likewise.
+ (s390_expand_cmpmem): Likewise.
+
+2003-10-22 Mark Mitchell <mark@codesourcery.com>
+
+ * c-pch.c (struct c_pch_validity): Add pch_init field.
+ (pch_init): Set it.
+ (c_common_valid_pch): Check it.
+
+2003-10-22 David Taylor <dtaylor@emc.com>
+
+ PR debug/12500
+ * dbxout.c (dbxout_typedefs): Use COMPLETE_OR_VOID_TYPE_P.
+
+2003-10-22 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * config/alpha/alpha.c (function_value [ENABLE_CHECKING]): Don't call
+ alpha_return_in_memory if no VALTYPE specified.
+
+2003-10-22 Jan Hubicka <jh@suse.cz>
+
+ PR debug/12389
+ * Makefile.in (dwarf2out.o): Depend on cgraph.h.
+ * cgraph.c (cgraph_function_possibly_inlined_p): New function.
+ * cgraph.h (cgraph_function_possibly_inlined_p): Declare.
+ (cgraph_global_info): Add flag inlined
+ * dwarf2out.c (gen_subprogram_die, gen_decl_die): Use
+ cgraph_function_possibly_inded_p
+ * cgraphunit.c (mark_inline): Set inlined flag.
+ * toplev.c (rest_of_decl_compilation): Call outlining_inline_function
+ only for possibly inlined functions.
+ * c-decl.c (duplicate_decls): Never output abstract DIE representing old
+ body of function.
+
+2003-10-22 Andrew Haley <aph@redhat.com>
+
+ * varasm.c (output_constructor): Make constructor annotation
+ conditional on ASM_COMMENT_START.
+
+2003-10-21 Jason Merrill <jason@redhat.com>
+
+ * tree.c (get_unwidened): Check TREE_UNSIGNED on the field's type.
+ (get_narrower): Likewise.
+
+ * stor-layout.c (layout_decl): Do packed field alignment for
+ bit-fields, too.
+
+2003-10-21 Eric Christopher <echristo@redhat.com>
+
+ * expr.c (convert_move): Use FLOAT_EXTEND for extensions.
+
+2003-10-21 Geoffrey Keating <geoffk@apple.com>
+
+ * c-pch.c: Add comments in various places.
+ (struct c_pch_validity): Add the lengths of various strings.
+ (host_machine): New static.
+ (target_machine): New static.
+ (get_ident): Bump version number.
+ (pch_init): Write out version, host, target validity data.
+ (c_common_valid_pch): Check version, host, target.
+ * Makefile.in (c-pch.o): Add version.h; define HOST_MACHINE and
+ TARGET_MACHINE.
+
+2003-10-21 Jason Merrill <jason@redhat.com>
+
+ * tree.h (IS_EXPR_CODE_CLASS): Use strchr.
+ (EXPR_P): New macro.
+
+2003-10-21 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ia64/ia64.md (cmpxchg_acq_si): Mark operand 3 as DImode.
+ * config/ia64/ia64.c (ia64_expand_fetch_and_op,
+ ia64_expand_op_and_fetch): Make sure the REG for ar.ccv is
+ DImode. Use convert_move to load ar.ccv.
+ (ia64_expand_compare_and_swap): Likewise.
+ If expand_expr doesn't put 'old' and 'new' in the proper
+ modes, run them through convert_to_mode.
+
+2003-10-21 Eric Christopher <echristo@redhat.com>
+
+ * config/frv/frv.c (frv_adjust_field_align): Check DECL_ARTIFICIAL
+ for too large bitfields.
+
+2003-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in ($(docobjdir)/%.info): Honor BUILD_INFO.
+
+2003-10-21 Andrew Haley <aph@redhat.com>
+
+ * varasm.c (output_constructor): Annotate constructor.
+
+2003-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in ($(DESTDIR)$(infodir)/%.info): Conditionalize chmod
+ on existence of destination file.
+
+2003-10-21 Jan Hubicka <jh@suse.cz>
+
+ * haifa-sched.c (choose_ready): Initialize index.
+
+2003-10-21 Jason Merrill <jason@redhat.com>
+
+ * tree.c (build1): Fix off-by-one error.
+
+2003-10-21 Robert Millan <robertmh@gnu.org>
+
+ * config/i386/kfreebsdgnu.h: New. i386-*-kfreebsd-gnu definitions.
+ * config/kfreebsdgnu.h: New. *-*-kfreebsd-gnu definitions.
+ * config/t-kfreebsd-gnu: New. *-*-kfreebsd-gnu tmake_file.
+ * config.gcc: Add *-*-kfreebsd*-gnu and i[34567]86-*-kfreebsd*-gnu.
+
+2003-10-21 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * web.c: Fix various comments.
+
+2003-10-20 Nicolas Pitre <nico@cam.org>
+
+ * config/arm/arm.c (arm_override_options): Set arm_constant_limit
+ to 2 instead of 1 when optimize_size is true. Gather code based on
+ optimize_size together. Add comment about XScale load latency.
+
+2003-10-21 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_output_function_prologue): Remove
+ obsolete comments.
+
+2003-10-20 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in: Get parsedir and docobjdir from configure.
+ * configure.in: Recogonize --enable-generated-files-in-srcdir.
+ Pass along parsedir and docobjdir.
+ * configure: Regenerate.
+ * doc/install.texi: Document --enable-generated-files-in-srcdir.
+
+2003-10-20 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in: Define $(docdir) before the Make-lang.in fragments are
+ included.
+
+2003-10-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-common.c (expand_tree_builtin): Ensure creal and cimag
+ functions do not return lvalues.
+
+2003-10-20 Jason Merrill <jason@redhat.com>
+
+ PR c/12553
+ * tree.c (build1) <ADDR_EXPR>: Set TREE_SIDE_EFFECTS
+ appropriately.
+
+ PR c/11446
+ * stor-layout.c (layout_decl): Fix alignment handling.
+
+2003-10-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/extend.texi: Deprecate casts as lvalues.
+
+2003-10-20 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (rest_of_compilation): Fix webizer pass ordering.
+
+ * cgraphunit.c (decide_is_function_needed): Fix test dealing
+ with functions implicitly made inline.
+
+ * cgraphunit.c (cgraph_decide_inlining_incrementally): New function.
+ (cgraph_finalize_function): Use it.
+ (cgraph_mark_inline): Allow incrmental decisions
+ * invoke.texi (max-inline-slope, min-inline-insns): Kill.
+ * params.def (PARAM_MAX_INLINE_SLOPE, PARAM_MIN_INLINE_INSNS): Kill.
+ * tree-inline.c (limits_allow_inlining): Kill.
+ (expand_call_inline): Always use unit-at-a-time path.
+
+2003-10-20 Zack Weinberg <zack@codesourcery.com>
+
+ * fixinc/inclhack.def (hpux11_snprintf): New edit.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/stdio.h: Add test for hpux11_snprintf.
+
+2003-10-20 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (install-info): Simplify.
+ ($(DESTDIR)$(infodir)/%.info): New rule.
+ * configure.in (target_list): Remove install-info.
+ * doc/.cvsignore (gcc.info*): Remove.
+ (gccint.info*): Likewise.
+ (gccinstall.info*): Likewise.
+ (cpp.info*): Likewise.
+ (cppinternals.info*): Likewise.
+ (*.info*): Add it.
+ * doc/sourcebuild.texi: Update description of install-info.
+ * objc/Make-lang.in (objc.install-info): Remove.
+
+2003-10-20 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/linux.h (TARGET_OS_CPP_BUILTINS): Define _ABIO32.
+ Use it in _MIPS_SIM definition.
+ * config/mips/mips.h (CRT_CALL_STATIC_FUNCTION): Likewise.
+
+2003-10-20 Zack Weinberg <zack@codesourcery.com>
+
+ * config/i386/i386.c (print_reg): Abort if REGNO (x) is a
+ virtual register, but only if file == asm_out_file.
+ * config/i386/i386.h (HI_REGISTER_NAMES): Use "argp", not "",
+ for ARG_POINTER_REGNUM.
+
+2003-10-20 Zack Weinberg <zack@codesourcery.com>
+
+ * c-common.c (registered_builtin_types): New static.
+ (c_common_type_for_mode): Consult registered_builtin_types.
+ (c_register_builtin_type): Add type to registered_builtin_types.
+ * optabs.c (init_floating_libfuncs): Initialize libfuncs for
+ all MODE_FLOAT modes, not just the ones corresponding to
+ float_type_node, double_type_node, and long_double_type_node.
+
+2003-10-20 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.h (PREDICATE_CODES): Add normal_memory_operand.
+ * config/alpha/alpha-protos.h: Remove PREDICATE_CODES prototypes.
+
+2003-10-20 Dorit Naishlos <dorit@il.ibm.com>
+
+ * config/rs6000/rs6000.h: (rs6000_sched_insert_nops):
+ support new flag -minsert-sched-nops.
+ (DEFAULT_SCHED_FINISH_NOP_INSERTION_SCHEME): Define.
+ * config/rs6000/rs6000.c: (rs6000_sched_insert_nops):
+ support new flag -minsert-sched-nops.
+ (is_cracked_insn, is_microcoded_insn): New functions.
+ (rs6000_sched_finish): New function.
+ (rs6000_issue_rate): Return 5 for power4.
+ (get_next_active_insn, insn_terminates_group_p): New
+ functions.
+ (is_costly_group, force_new_group): New functions.
+ (redefine_groups, pad_groups): New functions.
+ (rs6000_variable_issue): Use new functions.
+ * doc/invoke.texi (-minsert-sched-nops): Document new
+ option.
+
+2003-10-20 David S. Miller <davem@redhat.com>
+
+ * config/sparc/sparc.md (type attribute): Add new insn types
+ fpa, fpm_pack, fgm_mul, fgm_pdist, and fgm_cmp for VIS.
+ (patterns emitting VIS insns): Use them.
+ * config/sparc/ultra1_2.md: Add VIS scheduling rules.
+ * config/sparc/ultra3.md: Likewise.
+
+2003-10-20 Falk Hueffner <falk@debian.org>
+
+ PR target/12654
+ * config/alpha/alpha.c (alpha_emit_conditional_branch): Don't do
+ comparison against constant by adjusting the argument except for
+ EQ and NE.
+
+2003-10-19 Mark Mitchell <mark@codesourcery.com>
+
+ * config.gcc: Add support for arm926ejs, arm1026ejs, arm1136js,
+ arm1136jfs, and armv6j.
+ * config/arm/arm.c (FL_ARCH6J): New macro.
+ (FL_VFPV2): Likewise.
+ (all_cores): Add entries for arm926ejs, arm1026ejs, arm1136js,
+ and arm1136jfs.
+ (all_architectures): Add entry for armv6j.
+ (arm_override_options): Add entries for arm926ejs, arm1026ejs,
+ arm1136js, and arm1136jfs.
+ * config/arm/arm.h (TARGET_CPU_arm926ej_s): New macro.
+ (TARGET_CPU_arm1026ej_s): Likewise.
+ (TARGET_CPU_arm1136j_s): Likewise.
+ (TARGET_CPU_arm1136jf_s): Likewise.
+ * doc/invoke.texi: Document new ARM cores and architecture
+ variants.
+
+2003-10-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (toplev.o): Add value-prof.h dependency.
+ (value-prof.o): Add REGS_H dependency.
+ * common.opt (fprofile-values, fvpt): New.
+ * flags.h (flag_value_profile_transformations): Declare.
+ * opts.c (common_handle_option): Handle -fprofile_values and
+ -fvpt.
+ * profile.c (branch_prob): Don't remove death notes here.
+ * timevar.def (TV_VPT): New.
+ * value-prof.c: Include regs.h.
+ (insn_divmod_values_to_profile, gen_divmod_fixed_value, gen_mod_pow2,
+ gen_mod_subtract, divmod_fixed_value_transform,mod_pow2_value_transform,
+ mod_subtract_transform, value_profile_transformations): New.
+ (insn_values_to_profile): Call insn_divmod_values_to_profile.
+ (find_values_to_profile): Add dumps.
+ * value-prof.h (value_profile_transformations): Declare.
+ * toplev.c: Include value-prof.h.
+ (rest_of_handle_value_profile_transformations): New.
+ (enum dump_file_index): Add DFI_vpt.
+ (dump_file): Add vpt dump.
+ (flag_value_profile_transformations): New.
+ (lang_independent_options): Add flag_profile_values and
+ flag_value_profile_transformations.
+ (rest_of_compilation): Call
+ rest_of_handle_value_profile_transformations.
+ (process_options): Let -fvpt imply -fprofile-values.
+ * doc/invoke.texi (-fvpt): Document.
+
+2003-10-19 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (print_reg): Do not abort on certain registers.
+
+ PR optimization/12612
+ * reg-stack.c (subst_stack_regs_pat): Use st(1) for clobbers.
+ * i386.md (fpatan, fyl2x, fscale patterns and expanders): Use
+ match_scratch; avoid bogus paralles.
+
+ PR target/12674
+ * i386.c (ix86_function_regparm): Disable implicit register passing
+ conventions when profiling.
+
+2003-10-19 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Richard Henderson <rth@redhat.com>
+
+ PR optimization/8178
+ * config/i386/i386.md (*movsi_zero): Delete.
+ (*ffs_no_cmove): Use ix86_expand_clear to zero the third operand.
+
+2003-10-19 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (fix_operator): New.
+ (divmod_operator): Tidy.
+ (alpha_emit_xfloating_cvt): Handle UNSIGNED_FIX.
+ * config/alpha/alpha.h (FIXUNS_TRUNC_LIKE_FIX_TRUNC): Remove.
+ (PREDICATE_CODES): Update.
+ * config/alpha/alpha.md (fix_truncdfsi_ieee): Use match_operator.
+ (fix_truncdfsi_internal, fix_truncdfdi_ieee): Likewise.
+ (fix_truncsfsi_ieee, fix_truncsfsi_internal): Likewise.
+ (fix_truncsfdi_ieee): Likewise.
+ (fix_truncdfdi2, fix_truncsfdi2): Turn into define_expand.
+ (fixuns_truncdfdi2, fixuns_truncsfdi2, fixuns_trunctfdi2): New.
+ * config/alpha/alpha-protos.h: Update.
+
+2003-10-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (INITIALIZE_TRAMPOLINE): Simplify.
+ * config/mips/mips.c (mips_load_got): Assume Pmode == ptr_mode.
+ * config/mips/mips.md (extendsidi2, *extendsidi2): Merge. Don't accept
+ constant operands.
+
+2003-10-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/extend.texi: Fix typos.
+ * doc/invoke.texi: Likewise.
+
+2003-10-18 Nicolas Pitre <nico@cam.org>
+
+ * config/arm/arm.c (arm_override_options): Use arm_tune_xscale for
+ XScale optimizations not arm_arch_xscale.
+ * config/arm/arm.h (CONSTANT_ALIGNMENT_FACTOR, MOVE_RATIO): Likewise.
+
+2003-10-18 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (shift_count_operand): Add prototype.
+ * config/s390/s390.c (shift_count_operand): New function.
+ (s390_extra_constraint): Use it to implement 'Y' constraint.
+ (print_shift_count_operand): New function.
+ (print_operand): Use it to implement '%Y'.
+ * config/s390/s390.h (EXTRA_ADDRESS_CONSTRAINT): Add 'Y' constraint.
+ (PREDICATE_CODES): Add shift_count_operand.
+ * config/s390/s390.md ("rotldi3"): Merge alternatives,
+ using "shift_count_operand" predicate and "Y" constraint,
+ and "%Y" to output the combined shift count.
+ ("rotlsi3"): Likewise.
+ ("ashldi3", "*ashldi3_31", "*ashldi3_64"): Likewise.
+ ("ashrdi3", "*ashrdi3_31", "*ashrdi3_64", "*ashrdi3_cc_31",
+ "*ashrdi3_cc_64", "*ashrdi3_cconly_31", "*ashrdi3_cconly_64"): Likewise.
+ ("ashlsi3", "ashrsi3", "*ashrsi3_cc", "*ashrsi3_cconly"): Likewise.
+ ("lshrdi3", "*lshrdi3_31", "*lshrdi3_64"): Likewise.
+ ("lshrsi3"): Likewise.
+
+2003-10-18 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_output_function_epilogue): Add missing
+ argument to asm_fprintf statement.
+
+2003-10-18 Fariborz Jahanian <fjahanian@apple.com>
+
+ * rs6000.md: Separate TARGET_POWERPC64 patterns for TARGET_64BIT or TARGET_32BIT.
+ (ashrdisi3_noppc64) Generate more efficient code for 32-bit right-shift of
+ a "long long" argument.
+
+2003-10-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * final.c (final_scan_insn): Run FINAL_PRESCAN_INSNS on asm insns
+ as well.
+
+2003-10-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * rtl.h (rtl_size): Declare.
+ (rtunion): Remove rtwint.
+ (rtx_def): Replace 'fld' with a union of an rtunion or a HOST_WIDE_INT.
+ (RTX_HDR_SIZE, RTX_SIZE): New macros.
+ (RTL_CHECK1): Adjust for new rtx_def layout.
+ (RTL_CHECK2, RTL_CHECKC1, RTL_CHECKC2): Likewise.
+ (XWINT, XCWINT): Likewise. Access the rtx structure directly.
+ (X0WINT): Remove.
+ (X0ANY): New macro.
+ * rtl.def: Adjust comments for new rtx_def layout.
+ * ggc.h (ggc_alloc_rtx): Take the rtx code as argument, not the
+ number of slots.
+ * rtl.c (rtx_size): New array.
+ (rtx_alloc): Adjust call to ggc_alloc_rtx. Use RTX_HDR_SIZE.
+ (copy_rtx): Use RTX_HDR_SIZE. Adjust for new rtx_def layout.
+ (shallow_copy_rtx): Adjust call to ggc_alloc_rtx. Use RTX_SIZE.
+ * integrate.c (copy_rtx_and_substitute): Use X0ANY to copy '0' fields.
+ * emit-rtl.c (copy_most_rtx): Likewise.
+ (copy_rtx_if_shared): Use RTX_SIZE.
+ (copy_insn_1): Use RTX_HDR_SIZE. Adjust for new rtx_def layout.
+ * gengenrtl.c (gendef): Adjust ggc_alloc_rtx call. Use RTX_HDR_SIZE.
+ * gengtype.c (write_rtx_next): Use RTX_HDR_SIZE.
+ (adjust_field_rtx_def): Expect "rtx_def" to be a union rather than
+ an array. Adjust output for new rtx_def layout.
+ * ggc-page.c (RTL_SIZE): Use RTX_HDR_SIZE.
+ * reload1.c (eliminate_regs): Use RTX_SIZE.
+ * rtlanal.c (loc_mentioned_in_p): Adjust for new rtx_def layout.
+ * gdbinit.in (pi): Likewise.
+
+2003-10-18 Jan Hubicka <jh@suse.cz>
+
+ * integrate.c (copy_decl_for_inlining): Revert previous patch.
+
+2003-10-18 Jan Hubicka <jh@suse.cz>
+
+ * integrate.c (copy_decl_for_inlining): Fix copying of copies.
+
+2003-10-18 Roger Sayle <roger@eyesopen.com>
+
+ * libgcc.texi: Group multi-word types, such as "long double" and
+ "unsigned int", using braces in @deftypefn and @deftypefnx nodes.
+ Document __unord?f2 as returning a non-zero value, not just one.
+
+2003-10-18 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/mmix/t-mmix (CRTSTUFF_T_CFLAGS): Define.
+ ($(T)crti.o, $(T)crtn.o): Pass CRTSTUFF_T_CFLAGS here too.
+
+2003-10-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/i386/k6.md (k6_alux): Use the 'mode' attribute instead of
+ match_operand.
+
+2003-10-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_record_value_1): New fourth
+ parameter packed_p. Search for a DECL_PACKED field only if
+ packed_p is false. Pass packed_p recursively.
+ (function_arg_record_value_2): Likewise.
+ (function_arg_record_value): Update calls to
+ function_arg_record_value_1 and function_arg_record_value_2.
+
+2003-10-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * cse.c (cse_insn) [src_folded]: Check that the tentative replacement
+ was successfully forced to memory before using the result.
+
+2003-10-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/8178
+ * config/i386/i386.md (*movsi_zero): New insn to set
+ a register to zero on TARGET_USE_MOV0 targets.
+
+2003-10-18 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Makefile.in (Makefile): Depend on the all Make-lang.in fragments.
+ (POSTSTAGE1_FLAGS_TO_PASS): Pass down MAKEINFO and MAKEINFOFLAGS.
+
+2003-10-17 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/invoke.texi (gcse-las): Fix typo.
+
+2003-10-17 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * doc/install.texi: Remove first part of the sentence for
+ zsh not working. Change gcc to GCC.
+
+ PR bootstrap/12546
+ * doc/install.texi: Document that zsh does not work when
+ configuring gcc.
+
+2003-10-17 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/ptx4.h: Switch to DWARF 2; update comments.
+
+2003-10-17 Segher Boessenkool <boessen@de.ibm.com>
+ Hartmut Penner <hpenner@de.ibm.com>
+
+ PR 10404, partial 11591, partial 11601
+ * config/rs6000/altivec.md ("altivec_dst", "altivec_dstt",
+ "altivec_dstst", "altivec_dststt", "altivec_lvsl", "altivec_lvsr",
+ "altivec_lvebx", "altivec_lvehx", "altivec_lvewx", "altivec_lvxl",
+ "altivec_lvx", "altivec_stvx", "altivec_stvxl", "altivec_stvebx",
+ "altivec_stvehx", "altivec_stvewx"): Use a memory_operand.
+ * config/rs6000/rs6000.c (altivec_expand_lv_builtin): New function.
+ (altivec_expand_stv_builtin): Adjust for the memory_operand.
+ (altivec_expand_builtin): Call altivec_expand_lv_builtin.
+ (altivec_init_builtins): Use `long int' for memory offsets.
+
+2003-10-17 Jan Hubicka <jh@suse.cz>
+
+ * opts.c (common_handle_option): Handle OPT_fweb
+ * invoke.texi (-fweb): Add missing parts of documentation.
+
+2003-10-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/linux.h (FUNCTION_NAME_ALREADY_DECLARED): Undef
+ before redefinition.
+
+2003-10-17 Mostafa Hagog <mustafa@il.ibm.com>
+
+ * common.opt: Add description of the new -fgcse-las flag.
+ * flags.h (flag_gcse_las): Declaration of global flag_gcse_las.
+ * gcse.c (hash_scan_set): Handle the case of store expression and
+ insert the memory expression to the hash table, this way we make it
+ possible to discover redundant loads after stores and remove them.
+ (pre_insert_copy_insn): moved the call to update_ld_motion_stores,
+ to pre_insert_copies, it is not the correct place to call it after
+ adding stores to be in the available expression hash table.
+ (pre_insert_copies): Added the call to update_ld_motion_stores when
+ one or more copies were inserted.
+ * opts.c (common_handle_option): Handle the -fgcse-las flag.
+ * toplev.c (flag_gcse_las): Initialization of flag_gcse_las.
+
+ * doc/invoke.tex: Document new -fgcse-las flag.
+
+2003-10-18 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/crtsavres.asm: Correct alignment of powerpc64 code
+ for posterity, then remove it.
+
+2003-10-17 Richard Earnshaw <rearnsha@arm.com>
+ Nathan Sidwell <nathan@codesourcery.com>
+
+ * config/arm/arm.c (use_return_insn): Not a single instruction, if
+ there's a frame pointer.
+ (arm_output_epilogue): Protect stack pointer from being corrupted
+ on interrupt.
+
+2003-10-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * ifcvt.c (noce_try_addcc): Handle ifs with 'else' case.
+
+2003-10-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * combine.c (simplify_set): Do not clear out undobuf.other_insn
+ already set elsewhere.
+
+2003-10-17 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config/i386/i386.c (ix86_expand_prologue): Use
+ gen_allocate_stack_worker.
+
+2003-10-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config.gcc (mips-sgi-irix6*o32): Only enable use_collect2
+ without gas.
+ (mips-sgi-irix6*): Likewise.
+
+ * config/mips/iris6gas.h: New file.
+ * gcc/config.gcc (mips-sgi-irix6*): Use it.
+
+ * config/mips/mips.h (TARGET_IRIX): Provide default.
+ (TARGET_IRIX5): Likewise.
+ (TARGET_SGI_O32_AS): Likewise.
+ * config/mips/iris5.h (TARGET_IRIX): Redefine as 1.
+ (TARGET_IRIX5): Likewise.
+ * config/mips/iris6.h (TARGET_IRIX6): Remove.
+ (TARGET_IRIX5): Redefine as 0.
+
+ * config/mips/mips.c (mips_output_external): Test for IRIX 6 O32
+ linker workaround with TARGET_IRIX and mips_abi instead of
+ ASM_OUTPUT_UNDEF_FUNCTION.
+ (mips_file_end): Inline old ASM_OUTPUT_UNDEF_FUNCTION definition,
+ testing TARGET_IRIX and mips_abi explicitly.
+ * config/mips/iris5.h (ASM_OUTPUT_UNDEF_FUNCTION): Remove.
+ * config/mips/iris6.h (ASM_OUTPUT_UNDEF_FUNCTION): Remove undef.
+
+ * config/mips/mips.c (irix_output_external_libcall): Renamed from
+ mips_output_external_libcall.
+ Use new TARGET_IRIX in guard.
+ * config/mips/mips-protos.h (irix_output_external_libcall): Match
+ this.
+ * config/mips/iris5.h (TARGET_ASM_EXTERNAL_LIBCALL): Likewise.
+
+ * config/mips/iris5gas.h (HAVE_GAS_SHF_MERGE): Update comment.
+ Define as 0.
+
+ * config/mips/iris6.h (FUNCTION_NAME_ALREADY_DECLARED): Define
+ depending on mips_abi.
+ * config/mips/linux.h (FUNCTION_NAME_ALREADY_DECLARED): Define as 1.
+ * config/mips/mips.c (mips_output_function_prologue): Test
+ FUNCTION_NAME_ALREADY_DECLARED at runtime.
+ (mips_output_function_epilogue): Likewise.
+ (build_mips16_function_stub): Likewise.
+ (build_mips16_call_stub): Likewise.
+ * config/mips/mips.h (FUNCTION_NAME_ALREADY_DECLARED): Provide
+ default.
+
+ * config/mips/iris6.h (DWARF2_UNWIND_INFO): Don't define for native
+ IRIX 6 O32 assembler.
+ (SUBTARGET_CC1_SPEC): Enforce mips2 ISA with O32 ABI.
+ (TARGET_OS_CPP_BUILTINS): Define _ABIO32, use it to define
+ _MIPS_SIM for O32 ABI.
+ (DWARF2_FRAME_INFO): Don't define for native IRIX 6 O32 assembler.
+ (ASM_DECLARE_FUNCTION_NAME): Integrate mips.h version.
+ (ASM_DECLARE_FUNCTION_SIZE): Move undef before redefinition.
+ Integrate O32 version.
+ (SUBTARGET_ASM_SPEC): Handle -mabi=32.
+ (SUBTARGET_ASM_DEBUGGING_SPEC): Add mdebug_asm_spec for gas with
+ O32 ABI.
+ (BSS_SECTION_ASM_OP_32): Define.
+ (BSS_SECTION_ASM_OP_64): Likewise.
+ (BSS_SECTION_ASM_OP): Define differently for O32 and N32/N64 ABIs
+ using them.
+ (TARGET_ASM_NAMED_SECTION): Reflect renaming.
+ Move up to allow override for O32 ABI without GNU as.
+ (EH_FRAME_SECTION_NAME): Define explicitly.
+ (MUST_USE_SJLJ_EXCEPTIONS): Define.
+ [_MIPS_SIM == _ABIO32 && !GAS] (CTORS_SECTION_ASM_OP,
+ DTORS_SECTION_ASM_OP): Dummy definitions.
+ (TARGET_ASM_NAMED_SECTION): Undef statically.
+ (EH_FRAME_SECTION_NAME): Likewise.
+ (ASM_OUTPUT_FILENAME): Integrate mips.h version.
+ (LINK_SPEC): Only use default options -call_shared -no_unresolved
+ without -r.
+ Don't pass -init, -fini with -mabi=32.
+ (COLLECT_PARSE_FLAG): Define.
+
+ * config/mips/mips.c (iris6_asm_named_section_1): Changed guard to
+ TARGET_IRIX.
+ Renamed to use irix_ prefix.
+ (iris6_asm_named_section): Likewise.
+ (iris_section_align_entry_eq): Likewise.
+ (iris_section_align_entry_hash): Likewise.
+ (iris6_file_start): Likewise.
+ (iris6_section_align_1): Likewise.
+ (iris6_file_end): Likewise.
+ (iris6_section_type_flags): Likewise.
+ (iris_section_align_htab): Likewise.
+ (iris_orig_asm_out_file): Likewise.
+ [TARGET_IRIX] (TARGET_ASM_FILE_START): Reflect rename.
+ (TARGET_ASM_FILE_END): Likewise.
+ (TARGET_SECTION_TYPE_FLAGS): Likewise.
+
+ * config/mips/mips.c [TARGET_IRIX5 && !TARGET_IRIX6]
+ (TARGET_ASM_UNALIGNED_HI_OP): Use runtime initialization in
+ override_options instead.
+ (TARGET_ASM_UNALIGNED_SI_OP): Likewise.
+ (TARGET_ASM_UNALIGNED_DI_OP): Likewise.
+ * config/mips/mips.c (override_options) [USE_COLLECT2]: Restore
+ flag_gnu_linker to defaults without USE_COLLECT2 for non-IRIX O32
+ assemblers.
+ Likewise for constructor/destructor handling.
+ (override_options): Handle IRIX O32 assembler quirks.
+ [TARGET_IRIX] (irix_asm_named_section): Handle O32 ABI with and
+ without gas.
+ (mips_file_start): Use new TARGET_IRIX.
+ (mips_declare_object_name): No special processing for IRIX O32
+ assembler.
+ (mips_finish_declare_object): Likewise.
+ (irix_asm_output_align): Renamed from iris6_asm_output_align.
+ Don't record alignment for O32 ABI.
+ (irix_file_start): Renamed from iris6_file_start.
+ Return early for O32 ABI.
+ (irix_file_end): Renamed from iris6_file_end.
+ Don't emit .section directives for O32 ABI.
+ * config/mips/iris6.h (ASM_OUTPUT_ALIGN): Reflect renaming.
+ * config/mips/mips-protos.h (irix_asm_output_align): Likewise.
+
+ * config/mips/t-iris6 (MULTILIB_OPTIONS): Add mabi=32.
+ (MULTILIB_OSDIRNAMES): Likewise.
+
+2003-10-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * collect2.c (COLLECT_PARSE_FLAG): Provide default.
+ (main): Use it.
+ * doc/tm.texi (COLLECT_PARSE_FLAG): Document it.
+
+2003-10-17 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm-modes.def (CC_Nmode): New condition code mode.
+ * arm.c (thumb_condition_code): Delete.
+ (arm_select_cc_mode): Handle single-bit test for Thumb.
+ (arm_print_operand, cases 'd' and 'D'): Don't special case the
+ condition code logic for Thumb.
+ (get_arm_condition_code): Handle CC_Nmode.
+ (thumb_cbrch_target_operand): New function.
+ * arm.h (PREDICATE_CODES): Add thumb_cbrch_target_operand.
+ * arm-protos.h (thumb_cbrch_target_operand): Add prototype.
+ * arm.md: Add Thumb split patterns for zero_extract and
+ sign_extract.
+ (tbit_cbranch, andsi3_cbranch_scratch, andsi3_cbranch)
+ (orrsi3_cbranch_scratch, orrsi3_cbranch, xorsi3_cbranch_scratch)
+ (xorsi3_cbranch, addsi3_cbranch, addsi3_cbranch_scratch)
+ (subsi3_cbranch, subsi3_cbranch_scratch): New Thumb patterns.
+ (cbranchne_decr1): Re-work to use CC_Nmode.
+
+ * arm.c (thumb_expand_epilogue): Add clobbers of registers restored
+ by the return instruction. Add a use of the link register if it
+ wasn't stored.
+
+2003-10-17 Richard Earnshaw <rearnsha@arm.com>
+
+ * flow.c (init_propagate_block_info): Don't abort if a conditional
+ jump is not a comparison of a register. Instead, just don't record
+ conditional life information.
+
+2003-10-16 Jan Hubicka <jh@suse.cz>
+
+ PR optimization/12630
+ * pa.md (movstrsi, movstrsi_internal): Use match_scratch in clobbers
+ for operands 7 and 8.
+
+2003-10-16 Kelley Cook <kcook@gcc.gnu.org>
+
+ * objc/Make-lang.in (objc-parse.o): Honor $(parsedir) for objc-parse.c.
+
+2003-10-16 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/cygming.h (ASM_OUTPUT_DEF_FROM_DECLS): Define.
+
+ * config/i386/winnt.c (gen_stdcall_suffix): Make static
+ (gen_fastcall_suffix): Likewise.
+ (i386_pe_dllexport_p): Likewise.
+ (i386_pe_dllimport_p): Likewise.
+ (i386_pe_mark_dllexport): Likewise.
+ (i386_pe_mark_dllimport): Likewise.
+ (i386_pe_asm_named_section): Fix formatting.
+
+2003-10-16 Zack Weinberg <zack@codesourcery.com>
+
+ * configure.in: Add snprintf to gcc_AC_CHECK_DECLS list.
+ * system.h: Declare snprintf if necessary.
+ * configure, config.in: Regenerate.
+
+2003-10-15 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_va_arg): Only align vector
+ arguments if TARGET_ALTIVEC_ABI.
+
+2003-10-15 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (fold_builtin_memcpy, fold_builtin_mempcpy,
+ fold_builtin_memmove, fold_builtin_strcpy, fold_builtin_strncpy,
+ fold_builtin_memcmp, fold_builtin_strcmp, fold_builtin_strncmp):
+ New functions.
+ (expand_builtin_memcpy): Use integer_zerop instead of testing
+ host_integerp and tree_low_cst directly. Move misapplied hunk
+ for optimization wher SRC and DEST point to the same location.
+ (expand_builtin_mempcpy): From here.
+ (expand_builtin_memmove): Use integer_zerop instead of testing
+ host_integerp and tree_low_cst_directly.
+ (expand_builtin_memset): Likewise.
+ (expand_builtin_memcmp): Likewise (and for integer_onep).
+ (expand_builtin_strncmp): Likewise.
+ (fold_builtin): Call the appropriate fold_builtin_foo functions
+ to optimize memcpy, mempcpy, memmove, strcpy, strncpy, memcmp,
+ strcmp and strncmp.
+
+2003-10-15 Geoffrey Keating <geoffk@apple.com>
+
+ * config/darwin-protos.h (machopic_non_lazy_ptr_name): Delete
+ prototype. Clean up some whitespace.
+ * config/darwin.c: Use gen_rtx_FOO (...) rather than
+ gen_rtx (FOO, ...).
+ (machopic_non_lazy_ptr_name): Make static.
+ (name_needs_quotes): Allow '.' and '$' unquoted.
+ (machopic_legitimize_pic_address): Improve codegen in dynamic-no-pic
+ case.
+
+2003-10-15 Gábor Lóki <alga@rgai.hu>
+
+ * fold-const.c (tree_swap_operands_p): Disable some features
+ when optimizing for size.
+
+2003-10-15 David Daney <ddaney@avtrex.com>
+
+ * config/mips/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New
+ * config/mips/mips.h (DWARF_FRAME_REGNUM): Fixed to allow unwind
+ from leaf functions.
+ (DWARF_FRAME_RETURN_COLUMN): Ditto.
+ (SIGNAL_UNWIND_RETURN_COLUMN): New, used
+ by MD_FALLBACK_FRAME_STATE_FOR.
+ * testsuite/gcc.dg/cleanup-9.c: Added mips*-*-linux* target.
+
+2003-10-15 Zack Weinberg <zack@codesourcery.com>
+
+ * genmodes.c: Include hashtab.h.
+ (modes_by_name, hash_mode, eq_mode, struct mode_adjust)
+ (adj_bytesize, adj_alignment, adj_format, new_adjust)
+ (_ADD_ADJUST, ADJUST_BYTESIZE, ADJUST_ALIGNMENT, ADJUST_FORMAT)
+ (print_maybe_const_decl, emit_mode_adjustments): New.
+ (known_modes): Rename to modes.
+ (find_mode): Kill class argument; look up in hash table.
+ (new_mode): Insert into hash table also.
+ (new_adjust): New.
+ (reset_float_format, make_partial_integer_mode)
+ (make_vector_mode): Tweak error reporting.
+ (reset_float_format): Correct type of fourth argument.
+ (emit_insn_modes_h): Add #defines to help make mode_size,
+ mode_base_align, and real_format_for_mode conditionally const.
+ (emit_mode_size, emit_mode_base_align): Use print_maybe_const_decl.
+ (emit_real_format_for_mode): Likewise, but temporarily disabled.
+ (emit_insn_modes_c): Call emit_mode_adjustments.
+ (main): Initialize modes_by_name.
+ * Makefile.in: Update dependencies.
+ * machmode.def: Document EXPR arguments and new ADJUST_* statements.
+ * machmode.h: Use CONST_MODE_SIZE and CONST_MODE_BASE_ALIGN in
+ declarations of mode_size and mode_base_align. Declare
+ init_adjust_machine_modes.
+ * toplev.c (backend_init): Call init_adjust_machine_modes.
+
+2003-10-15 Olivier Hainque <hainque@act-europe.fr>
+
+ * genmodes.c (calc_wider_mode): Allocate enough room for all the
+ entries we'll possibly assign in the sort buffer.
+
+2003-10-15 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config.gcc (s390x-ibm-tpf*): New target.
+ * doc/install.texi: Document it.
+ * config/s390/t-tpf: New file.
+ * config/s390/tpf.h: New file.
+
+2003-10-15 Hans-Peter Nilsson <hp@axis.com>
+
+ PR target/12598
+ * config/cris/cris.md (define_split "*mov_sidesi_biap_mem"+1)
+ (define_splits "*mov_sidesi_mem"+1, "casesi"+9, +10, +11, +12):
+ Use cris_mem_op and replace_equiv_address, not gen_rtx_MEM.
+ ("call", "call_value", define_split "*mov_sidesi_mem"+19, +20)
+ (define_split "*mov_sidesi_mem"+21, +22, +23, +24, +25, +26, +27)
+ (define_split "*mov_sidesi_mem"+28, +29, +30): Use
+ replace_equiv_address, not gen_rtx_MEM.
+ * config/cris/cris.c (cris_mem_op): New match_operator function.
+ (cris_notice_update_cc): Use replace_equiv_address, not
+ gen_rtx_MEM.
+ * config/cris/cris.h (PREDICATE_CODES): Add cris_mem_op.
+
+2003-10-15 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.h (MASK_SEP_DATA, TARGET_SEP_DATA,
+ MASK_ID_SHARED_LIBRARY, TARGET_ID_SHARED_LIBRARY): Move
+ definitions after the other flags.
+
+2003-10-14 Ziemowit Laski <zlaski@apple.com>
+
+ * c-parse.in (methoddef, methodproto): Call objc_add_method()
+ instead of add_method().
+ * objc/objc-act.c (objc_check_decl): Do not check for
+ constant_string_type.
+ (add_method): Rename to objc_add_method().
+ (really_start_method): Call objc_add_method() instead of
+ add_method().
+ * objc/objc-act.h (add_method): Rename to objc_add_method().
+
+2003-10-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_alc_comparison): Add prototype.
+ (s390_slb_comparison): Likewise.
+ * config/s390/s390.c (s390_alc_comparison, s390_slb_comparison):
+ New functions.
+ * config/s390/s390.h (PREDICATE_CODES): Add s390_alc_comparison
+ and s390_slb_comparison.
+ * config/s390/s390.md ("*adddi3_31", "*subdi3_31"): Do not use on
+ zSeries machines.
+ ("*adddi3_31z", "*subdi3_31z"): New insns.
+ ("*adddi3_alc_cc", "*adddi3_alc", "*subdi3_slb_cc", "*subdi3_slb",
+ "*addsi3_alc_cc", "*addsi3_alc", "*subsi3_slb_cc", "*subsi3_slb"):
+ New insns.
+
+2003-10-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Clean up some feedback echoes.
+ * configure: Regenerate.
+
+ * aclocal.m4: Properly quote names of macros being defined.
+
+ * config.gcc (am33_2.0-*-linux*): Use t-slibgcc-elf-ver.
+
+2003-10-14 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.c (ia64_expand_call): Force function address
+ to DImode.
+ * config/ia64/ia64.md (call_gp): Put DImode on operand 0.
+
+2003-10-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("muldf3", "*muldf3", "*muldf3_ibm",
+ "mulsf3", "*mulsf3", "*mulsf3_ibm"): Do not clobber CC.
+ ("divdf3", "*divdf3", "*divdf3_ibm", "divsf3", "*divsf3",
+ "*divsf3_ibm"): Likewise.
+
+2003-10-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc, config/m68hc11/t-m68hc11-gas: Replace uses of
+ target_alias with target_noncanonical.
+
+2003-10-14 Geoffrey Keating <geoffk@apple.com>
+
+ * expr.c (block_move_libcall_safe_for_call_parm): Clean up,
+ and add case for machines where outgoing register parameters
+ get stack space.
+
+ * config/darwin.c (machopic_indirect_data_reference): Use a scratch
+ register when generating indirect address.
+
+2003-10-14 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_addimm_operand): MODE arguemnt is unused.
+ * arm.md (cbranchne_decr1): Fix bootstrap warning.
+
+2003-10-14 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * fixinc/inclhack.def (alpha_pthread_gcc): New fix.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/pthread.h [ALPHA_PTHREAD_GCC_CHECK]: New
+ testcase.
+ Fixes PR bootstrap/9330.
+
+2003-10-13 Eric Christopher <echristo@redhat.com>
+
+ * config/frv/frv.c (frv_adjust_field_align): Redo check for
+ too wide bitfields.
+ (frv_hard_regno_mode_ok): Add SPR_P and AP_FIRST.
+ * config/frv/frv.h (FUNCTION_PROFILER): Remove abort call.
+ (SBSS_SECTION_ASM_OP): Remove.
+ (EXTRA_SECTIONS): Remove in_sbss.
+ (EXTRA_SECTION_FUNCTIONS): Remove SBSS_SECTION_FUNCTION.
+ (SBSS_SECTION_FUNCTION, sbss_section): Remove.
+ (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Change sbss_section to
+ named_section.
+
+2003-10-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in, configure.in, config.host, mkheaders.in: Replace
+ uses of ${target_alias} for directory names (and other places which
+ won't like the empty string) with ${target_noncanonical}. Introduce
+ call early in configure.in to _GCC_TOPLEV_NONCANONICAL_TARGET so it's
+ available.
+ * configure: Regenerate.
+
+2003-10-13 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * config/arm/iwmmxt.md (cond_iwmmxt_movsi_insn): New pattern.
+ * config/arm/arm.md: For splits which rely on conditional moves,
+ remove ! TARGET_IWMMXT condition.
+
+2003-10-13 David S. Miller <davem@redhat.com>
+
+ * ifcvt.c (num_removed_blocks): Rename to num_true_changes.
+ (find_cond_trap): Always increment if we emit a conditional
+ trap insn.
+
+2003-10-13 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (BUILD_RTL): Replace $(BUILD_PREFIX)insn-modes.o
+ with min-insn-modes.o.
+ (STAGESTUFF): Add min-insn-modes.c.
+ (genobjs): Add genmodes.o.
+ (print-rtl.o, print-rtl1.o): Depend on $(TM_P_H).
+ (insn-modes.o): Depend on $(TM_H) not $(GTM_H); also real.h.
+ (min-insn-modes.c, min-insn-modes.o): New rules.
+ (s-modes): Also generate min-insn-modes.c.
+ ($(BUILD_PREFIX_1)insn-modes.o): Kill.
+ * genmodes.c (struct mode_data): Add format field.
+ (blank_mode, validate_mode, complete_mode): Update to match.
+ (make_scalar_mode): Separate into make_int_mode and make_float_mode.
+ (_SCALAR_MODE): Kill.
+ (FLOAT_MODE, FRACTIONAL_FLOAT_MODE): Add format argument.
+ (emit_insn_modes_c_header): Adjust.
+ (emit_min_insn_modes_c_header, emit_real_format_for_mode)
+ (emit_min_insn_modes_c): New functions.
+ (emit_insn_modes_c): Call emit_real_format_for_mode.
+ (main): Add -m option to generate min-insn-modes.c.
+ * machmode.h: Update documentation. Add format argument to
+ all uses of FLOAT_MODE.
+ * real.c: Don't define real_format_for_mode here.
+
+ * dwarfout.c: Move default definition of PRINT_REG...
+ * defaults.h: ...here.
+ * print-rtl.c: Include tm_p.h.
+ (DEBUG_PRINT_REG, DEBUG_REGISTER_NAMES, debug_reg_names, reg_names):
+ Kill.
+ (print_rtx): Use PRINT_REG, not DEBUG_PRINT_REG. But surround
+ this entire block with #ifndef GENERATOR_FILE.
+ * regclass.c: Unconditionally define reg_names.
+ * config/mips/mips.h, config/rs6000/rs6000.h, config/sh/sh.h
+ Don't define DEBUG_REGISTER_NAMES.
+ * config/rs6000/darwin.h: Don't use DEBUG_REGISTER_NAMES in
+ redefinition of REGISTER_NAMES.
+ * config/i386/i386.h: Don't define DEBUG_PRINT_REG.
+
+ * combine.c: Change all preprocessor conditionals on
+ EXTRA_CC_MODES to use SELECT_CC_MODE instead; rearrange a bit
+ for clarity.
+ * genopinit.c: Remove mention of EXTRA_CC_MODES in comment.
+ * configure.in: Don't define EXTRA_CC_MODES.
+ * configure, config.in: Regenerate.
+ * doc/tm.texi: Remove documentation of EXTRA_CC_MODES.
+
+ * config/arc/arc.c, config/m32r/m32r.c, config/sparc/sparc.c:
+ May assume that GET_MODE_CLASS is accurate for extra CC modes
+ at all times.
+
+ * config/i860/i860.h (INIT_CUMULATIVE_ARGS): Pass correct
+ number of arguments to aggregate_value_p.
+
+ * genmodes.c (RESET_FLOAT_FORMAT, reset_float_format): New.
+ * machmode.def: Explain ARCH-modes.def. Document
+ RESET_FLOAT_FORMAT. Improve commentary on various mode
+ clusters. Do not define OI, PQI, PHI, PSI, PDI, QF, HF, TQF,
+ XF, or TF modes here. Remove backward-compatibility
+ definition of CC.
+
+ * config/alpha/alpha-modes.def: New file; define TF mode.
+ * config/arc/arm-modes.def: Define XF mode.
+ * config/c4x/c4x-modes.def: Define QF and HF modes. Unset
+ float format for SF and DF modes.
+ * config/dsp16xx/dsp16xx-modes.def: New file; define HF mode.
+ * config/i386/i386-modes.def: Define XF and TF modes.
+ * config/i960/i960-modes.def: Define TF mode.
+ * config/ia64/ia64-modes.def: Define TF and OI modes.
+ * config/m68k/m68k-modes.def: New file; define XF mode.
+ * config/mips/mips-modes.def: New file; define TF mode, reset
+ formats for SF and DF modes.
+ * config/pa/pa-modes.def: Define TF mode.
+ * config/rs6000/rs6000.c: Define TF and PSI modes.
+ * config/s390/s390-modes.def: Define OI mode.
+ * config/sh/sh-modes.def: New file; define PSI mode.
+ * config/sparc/sparc-modes.def: Define TF mode.
+ * config/vax/vax-modes.def: New file; reset formats for SF and
+ DF modes.
+
+ * config/c4x/c4x.c (c4x_override_options): No need to mess
+ with real_format_for_mode or set REAL_MODE_FORMATs.
+ (c4x_immed_int_constant): Don't apply GET_MODE_CLASS to rtx
+ variable.
+ * config/i386/i386.c (override_options): No need to set
+ REAL_MODE_FORMATs here.
+ * config/i960/i960.c (i960_initialize): Likewise.
+ * config/m68k/m68k.c (m68k_override_options): Likewise.
+ * config/ia64/ia64.c (ia64_override_options): Set REAL_MODE_FORMAT
+ for TFmode only if not the default.
+ * config/mips/mips.c (override_options): Likewise.
+ * config/vax/vax.c (override_optionms): Set REAL_MODE_FORMAT for
+ DFmode only if not the default.
+
+ * config/i370/i370.h (RET_REG): Don't consider TFmode.
+ * config/m68hc11/m68hc11.c (print_operand): Don't consider XFmode.
+ * config/dsp16xx/dsp16xx.c (hard_regno_mode_ok): #if 0 out use
+ of modes that don't appear anywhere in the machine description.
+
+ * config/arc/arc-modes.def, config/arm/arm-modes.def
+ * config/c4x/c4x-modes.def, config/frv/frv-modes.def
+ * config/i386/i386-modes.def, config/i960/i960-modes.def
+ * config/ia64/ia64-modes.def, config/mmix/mmix-modes.def
+ * config/pa/pa-modes.def, config/pdp11/pdp11-modes.def
+ * config/rs6000/rs6000-modes.def, config/s390/s390-modes.def
+ * config/sparc/sparc-modes.def: Convert to new style for
+ declaring extra CC modes.
+
+2003-10-13 Zack Weinberg <zack@codesourcery.com>
+
+ * cpplex.c (_cpp_clean_line): In the common case of a line
+ with no trigraphs and no \-newline, avoid writing to memory.
+ (_cpp_skip_block_comment): Use a local 'cur' pointer instead
+ of the buffer member. Make c an uchar to avoid unnecessary
+ sign extensions.
+
+2003-10-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Remove unnecessary test.
+ * configure: Regenerate.
+
+ * configure.in: Fix grammatical error. Move UWIN host error to...
+ * config.host: Here.
+ * configure: Regenerate.
+
+2003-10-13 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.md ("*fmadddf4", "*fmsubdf4", "*fmaddsf4",
+ "*fmsubsf4"): Insns are now dependent on TARGET_FUSED_MADD instead
+ of flag_unsafe_math_optimizations.
+ * config/s390/s390.h ("MASK_NO_FUSED_MADD", "TARGET_NO_FUSED_MADD",
+ "TARGET_FUSED_MADD", "TARGET_SWITCHES"): Introduced new target flags
+ fused-madd and no-fused-madd.
+ * doc/invoke.texi: Documented the new options fused-madd and
+ no-fused-madd for S/390.
+
+2003-10-14 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/linux64.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Choose
+ MASK_ALIGN_NATURAL if rs6000_alignment_string not given. Don't
+ assign DEFAULT_ABI.
+ (ADJUST_FIELD_ALIGN, ROUND_TYPE_ALIGN): Update comment.
+ * config/rs6000/rs6000.c: Formatting.
+ (rs6000_parse_alignment_option): Only set rs6000_alignment_flags
+ when rs6000_alignment_string given.
+
+2003-10-13 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/12538
+ * config/sparc/sparc.c (MUST_SAVE_REGISTER): Delete.
+ (sparc_flat_must_save_register_p): New function to decide whether
+ a register must be saved/restored in the function prologue/epilogue.
+ (sparc_flat_compute_frame_size): Use it instead of MUST_SAVE_REGISTER.
+
+2003-10-12 Steven Bosscher <steven@gcc.gnu.org>
+
+ * config/avr/avr.c, config/avr/avr-protos.h: Convert to
+ ISO C90 function declarations and definitions.
+ * config/sh/sh.c, config/sh/sh-protos.h: Likewise.
+
+2003-10-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (*-*-freebsd*): Use tm_defines instead of tiny
+ config files which do the same thing.
+ * config/freebsd3.h, config/freebsd4.h, config/freebsd5.h,
+ config/freebsd6.h: Remove now unnecessary files.
+
+2003-10-12 Steven Bosscher <steven@gcc.gnu.org>
+
+ * c-common.c (c_common_truthvalue_conversion): Warn if the
+ address of a non-weak function is used as a truth value.
+
+2003-10-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (WORD_REG_USED): Use SP_REG instead of
+ a literal.
+ * config/h8300/h8300.h (REGNO_OK_FOR_BASE_P): Use MAC_REG
+ instead of a literal.
+
+2003-10-12 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * doc/extend.texi (Function Attributes): Mention the exceptional
+ path for noreturn-marked functions.
+
+2003-10-12 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_decide_inlining): Fix uninitialized variable
+ warning.
+
+2003-10-12 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/i386.c (x86_this_parameter): Fix typo.
+
+203-10-11 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (web.o): New.
+ * web.c: New file.
+ * rtl.h (web_main): Declare.
+ * timervar.def (TV_WEB): New.
+ * toplev.c (dump_file_index, dump_file_info): Add DFI_web.
+ (rest_of_hanle_web): New.
+ (flag_web): New static variable.
+ (lang_independent_options): Add "web".
+ (rest_of_compilation): Call rest_of_handle_web.
+ * invoke.texi (-fweb): Document.
+ * common.opt (fweb): New.
+ * flags.h (flag_web): New.
+ * opts.c (decode_options): Set flag_web at -O3.
+
+ * passes.texi (web construction): Document.
+ * invoke.texi (-O3): Document that -fweb is enabled.
+
+ * regrename.c (regrename_optimize): Deal better with situation when
+ replacement failed.
+
+ * sched-ebb.c: Include params.h and profile.h
+ (schedule_ebbs): Use tracer parameters to discover superblocks
+ * Makefile.in (sched-ebb.o): Add dependencies.
+
+2003-10-11 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (negate_mathfn_p): New function to determine whether
+ a built-in mathematical function is sign preserving, f(-x) == -f(x).
+ Add support for BUILT_IN_ASIN, BUILT_IN_ASINF and BUILT_IN_ASINL.
+ (tree_swap_operands_p): Change API to take an additional argument
+ indicating that the swapped operands evaluate in reverse order.
+ Canonicalize VAR_DECLs and PARM_DECLs last if we can, i.e. neither
+ operand side-effects or we don't care about flag_evaluation_order.
+ (reorder_operands_p): New function to check whether its safe to
+ evaluate the given operands in reverse order.
+ (negate_expr_p): We can always negate integer constants unless
+ we honor -ftrapv and the signed type would overflow. Only allow
+ -(A-B) into B-A if reorder_operands_p says that its OK. Allow
+ negation of COMPLEX_CST if both real and imaginary parts can be
+ negated. Allow negation through floating point extensions and
+ sign-preserving built-in functions.
+ (negate_expr): Move the code to negate integers from "fold" to
+ here. Always negate integer constants unless we honor -ftrapv
+ and the signed type would overflow. Always negate real constants
+ unless we honor -ftrapping-math. Only convert -(A-B) into B-A
+ if allowed by reorder_operands_p. Add support for COMPLEX_CST.
+ Optimize negation through floating point extensions and
+ sign-preserving built-in functions (as defined by negate_mathfn_p).
+ (fold): Adjust calls to tree_swap_operands_p.
+ (fold <NEGATE_EXPR>): Move the remaining negation optimizations
+ to negate_expr_p/negate_expr.
+ (fold <MINUS_EXPR>): Use reorder_operands_p to check whether we're
+ allowed to convert (-A) - B into (-B) - A.
+
+2003-10-11 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_strcmp): Defend against the possibility
+ that gen_cmpstrsi may fail: Stabilize the argument list against
+ re-evaluation and expand the library call directly using this saved
+ argument list if a cmpstrsi sequence can't be generated.
+ (expand_builtin_strncmp): Likewise.
+
+ * config/i386/i386.md (cmpstrsi, movstrsi): Disable with -Os.
+
+2003-10-11 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/12260
+ * simplify-rtx.c (simplify_unary_operation): Simplify all unary
+ operations through CONST nodes. Optimize (neg (plus X C)) as
+ (minus -C X) for constant values C.
+ (simplify_binary_operation): Optimize (minus (neg X) C) as
+ (minus -C X) for constant values C.
+ (simplify_plus_minus): Avoid creating (neg (const (plus X C)),
+ instead create (minus -C X).
+
+2003-10-11 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_expr <PLUS_EXPR>): Let expand_operands call
+ safe_from_p for us, once it chooses an evaluation order.
+ (expand_expr <MULT_EXPR>): Likewise.
+ (expand_expr <MIN_EXPR> <MAX_EXPR>): Likewise. If expand_operands
+ places the second operand in "target", swap the operands.
+ (do_store_flag): Let expand_operands call safe_from_p for us.
+
+2003-10-11 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/12544
+ * function.c (put_var_into_stack): Don't generate ADDRESSOFs
+ for DECL_NONLOCAL decls.
+
+2003-10-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * expr.c: Follow spelling conventions.
+ * final.c: Likewise.
+ * optabs.c: Likewise.
+ * sched-deps.c: Likewise.
+ * sdbout.c: Likewise.
+
+Sat Oct 11 12:24:23 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * varasm.c (notice_global_symbol): Fix handling of variables; avoid
+ re-computing of variable.
+
+2003-10-11 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_return_in_memory): Rename from
+ return_in_memory, make static, change signature to match target hook.
+ (alpha_setup_incoming_varargs): Make static, change signature to
+ match target hook, add code for vms and unicos.
+ (TARGET_PROMOTE_FUNCTION_ARGS, TARGET_PROMOTE_FUNCTION_RETURN,
+ TARGET_PROMOTE_PROTOTYPES, TARGET_STRUCT_VALUE_RTX,
+ TARGET_RETURN_IN_MEMORY, TARGET_SETUP_INCOMING_VARARGS,
+ TARGET_STRICT_ARGUMENT_NAMING,
+ TARGET_PRETEND_OUTGOING_VARARGS_NAMED): New.
+ * config/alpha/alpha-protos.h: Update.
+ * config/alpha/alpha.h (PROMOTE_FUNCTION_ARGS,
+ PROMOTE_FUNCTION_RETURN, RETURN_IN_MEMORY,
+ SETUP_INCOMING_VARARGS): Remove.
+ * config/alpha/unicosmk.h (SETUP_INCOMING_VARARGS): Remove.
+ * config/alpha/vms.h (SETUP_INCOMING_VARARGS): Remove.
+
+2003-10-11 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * config/arm/arm.c (arm_regno_class): Handle IWMMXT_GR_REGS.
+
+2003-10-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m68k/lb1sf68.asm: Follow spelling conventions.
+ * config/m68k/m68k.c: Likewise.
+ * config/m68k/m68k.h: Likewise.
+ * config/m68k/m68k.md: Likewise.
+
+2003-10-11 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_memcpy): Optimize case when the two
+ pointer arguments are the equal, non-volatile and side-effect free.
+ (expand_builtin_mempcpy): Likewise.
+ (expand_builtin_memmove): Likewise.
+ (expand_builtin_strcpy): Likewise.
+ (expand_builtin_memcmp): Likewise.
+ (expand_builtin_strcmp): Likewise.
+ (expand_builtin_strncmp): Likewise.
+
+2003-10-11 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (apply_distributive_law): Enable "distributive" floating
+ point optimizations with -funsafe-math-optimizations.
+
+2003-10-11 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * genmodes.c (emit_mode_mask) Change MASK to MODE_MASK.
+
+2003-10-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m68k/m68k-protos.h: Remove the prototype for
+ finalize_pic.
+
+2003-10-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m68k/m68k.c: Fix comment typos.
+
+2003-10-11 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k-protos.h (use_return_insn): Change return type from
+ int to bool.
+ * config/m68k/m68k.c (struct m68k_frame): Add funcdef_no member.
+ (current_frame): New global var.
+ (m68k_compute_frame_layout): Cache computations in current_frame.
+ (m68k_initial_elimination_offset): Use values from current_frame
+ instead of recomputing them.
+ (use_return_insn): Likewise.
+ (m68k_output_function_prologue): Likewise.
+ (m68k_output_function_epilogue): Likewise.
+ * config/m68k/m68k.h (TARGET_CPU_CPP_PREDEFINES): Fold __PIC__ handling
+ inside the block for __pic__.
+
+2003-10-11 Peter Barada <peter@baradas.org>
+ Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c (m68k_frame): Move before protos referencing it.
+ (m68k_save_reg): Add boolean parameter `interrupt_handler'.
+ (m68k_interrupt_function_p): New function.
+ (m68k_handle_fndecl_attribute): Ditto.
+ (m68k_compute_frame_layout): Ditto.
+ (m68k_attribute_table): Define back-end specific attributes.
+ (m68k_output_function_epilogue): Emit RTE instruction for interrupt
+ functions.
+
+2003-10-11 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/t-uclinux: New target Makefile fragment.
+ * config/m68k/uclinux.h: New target macro file.
+ * config.gcc (m68k-*-uclinux): New target definition.
+
+2003-10-10 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (builtin_mathfn_code): Generalize to check whether
+ the call is to any built-in function by comparing the call's
+ argument list against the builtin decl's function type.
+
+2003-10-10 Roger Sayle <roger@eyesopen.com>
+
+ * cse.c (constant_pool_entries_regcost): New global variable to
+ hold the register cost component of constant_pool_entries_cost.
+ (fold_rtx): Calculate constant_pool_entries_regcost at the same
+ time as constant_pool_entries_cost.
+ (cse_insn): Set both src_folded_cost and src_folded_regcost from
+ constant_pool_entries_cost and constant_pool_entries_regcost.
+ (cse_main): Initialize constant_pool_entries_regcost to zero.
+
+ * optabs.c (expand_unop): Attach a REG_EQUAL note describing
+ the semantics of the sequence of bit operations used to negate
+ a floating-point value.
+ (expand_abs_nojump): Likewise attach a REG_EQUAL note describing
+ the semantics of the bit operations used to abs a floating point
+ value.
+
+2003-10-11 Bernardo Innocenti <bernie@develer.com>
+ Paul Dale <pauli@snapgear.com>
+
+ * config/m68k/lb1sf68.asm: Add __PIC__ and __ID_SHARED_LIBRARY__
+ support.
+ * config/m68k/m68k-none.h (ASM_SPEC): Pass --pcrel to assembler on
+ -fpic, -fPIC, -msep-data and -mid-shared-library.
+ * config/m68k/m68k.c (m68k_library_id_string): New global variable.
+ (override_options): Add -msep-data and -mshared-library-id support.
+ (m68k_output_function_prologue): Generate code to load A5 for
+ TARGET_ID_SHARED_LIBRARY and TARGET_SEP_DATA.
+ (m68k_output_mi_thunk): Emit indirect jump on TARGET_ID_SHARED_LIBRARY.
+ (m68k_output_pic_call): New function.
+ * gcc/config/m68k/m68k.h (TARGET_SEP_DATA): New target flag.
+ (TARGET_ID_SHARED_LIBRARY): Ditto.
+ (TARGET_SWITCHES): Add switches for -mid-shared-library and -msep-data.
+ * gcc/config/m68k/m68k.md (call): Call m68k_output_pic_call().
+ (call_value): Likewise.
+
+2003-10-10 Zack Weinberg <zack@codesourcery.com>
+
+ * gengenrtl.c (find_formats, genheader): Make i an unsigned
+ int, remove cast of NUM_RTX_CODE.
+ * machmode.h: Make the HAVE_MACHINE_MODES #ifdef encompass the
+ entire file. Remove the #ifs on GET_MODE_MASK etc and
+ GET_MODE_WIDER_MODE etc.
+
+2003-10-10 Eric Christopher <echristo@redhat.com>
+
+ * lcm.c (optimize_mode_switching): Change NORMAL_MODE
+ to MODE_ENTRY and MODE_EXIT. Add MODE_AFTER for insns
+ that set mode.
+ * config/sh/sh.h (MODE_ENTRY): New macro.
+ (MODE_EXIT): Ditto.
+ (MODE_AFTER): Ditto.
+ * config/sh/sh.md: Change for MODE_AFTER. Add
+ fp_set attribute.
+ * doc/tm.texi: Document MODE_AFTER, MODE_ENTRY, and MODE_EXIT.
+
+2003-10-10 Zack Weinberg <zack@codesourcery.com>
+
+ * genmodes.c, mode-classes.def: New files.
+ * machmode.def: Rewritten to genmodes.c interface.
+ * Makefile.in (extra_modes_file): New substitution variable.
+ (MACHMODE_H): No longer includes machmode.def or
+ @extra_modes_file@; instead, mode-classes.def and insn-modes.h.
+ (BUILD_RTL): Add $(BUILD_PREFIX)insn-modes.o.
+ (OBJS-common): Add insn-modes.o.
+ (STAGESTUFF): Add insn-modes.c, insn-modes.h, s-modes, and
+ genmodes$(build_exeext).
+ (insn-modes.o, insn-modes.c, insn-modes.h, s-modes, genmodes.o,
+ genmodes$(build_exeext), $(BUILD_PREFIX_1)insn-modes.o): New targets.
+ (s-genrtl): Don't depend on $(RTL_BASE_H).
+ (gengenrtl.o): Don't depend on coretypes.h, $(GTM_H), real.h,
+ or $(RTL_BASE_H); just rtl.def.
+ * gengenrtl.c: Don't include coretypes.h, tm.h, rtl.h, or
+ real.h. Give fake definition of CONST_DOUBLE_FORMAT and
+ substitute definition of NUM_RTX_CODE. Add casts to avoid
+ warnings.
+ * machmode.h: Include insn-modes.h, not machmode.def. Include
+ mode-classes.def to define enum mode_class. Tweak definitions
+ of GET_MODE_CLASS, GET_MODE_SIZE, GET_MODE_BITSIZE, GET_MODE_MASK,
+ GET_MODE_INNER, GET_MODE_WIDER_MODE, GET_CLASS_NARROWEST_MODE.
+ (inner_mode_array): Renamed mode_inner.
+ (mode_base_align): New.
+ * rtl.c (mode_name, mode_class, mode_bitsize, mode_size,
+ mode_unit_size, mode_wider_mode, mode_mask_array,
+ inner_mode_array, class_narrowest_mode): Delete definitions.
+ * stor-layout.c (get_mode_alignment): Use mode_base_align.
+ * real.h: Use MIN_MODE_FLOAT and MAX_MODE_FLOAT, not QFmode
+ and TFmode, in real_format_for_mode and REAL_MODE_FORMAT.
+
+ * config/ip2k/ip2k.h, config/iq2000/iq2000.h:
+ No need to define BITS_PER_UNIT.
+
+2003-10-10 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * config/ia64/ia64.c (ia64_vms_init_libfuncs): New function.
+ (ia64_output_function_prologue): Only write .prologue if --with-gnu-as.
+ (ia64_initialize_trampoline): If not using GAS, declare trampoline
+ as global.
+ * config/ia64/ia64.h (ASM_APP_ON, ASM_APP_OFF): Add vers for not GAS.
+ (ASM_OUTPUT_DEBUG_LABEL): Likewise.
+
+ * stor-layout.c (compute_record_mode): Don't force BLKmode if
+ field is zero-length BLKmode.
+ * expr.c (expand_expr, case COMPONENT_REF): Handle case of BLKmode
+ zero-size references.
+
+ * combine.c (distribute_links): Properly test for REG being set.
+
+ * config/alpha/alpha.c (alpha_expand_block_mode): Don't use
+ gen_lowpart and company except for REG.
+
+2003-10-10 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa64-hpux.h (LINK_SPEC): Use `-z' option with HP ld.
+
+2003-10-10 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (mips*-*-netbsd*): Remove content-free line.
+
+2003-10-10 Herman A.J. ten Brugge <hermantenbrugge@home.nl>
+
+ * gcov-io.h: Check BITS_PER_UNIT when defining gcov_unsigned_t,
+ gcov_position_t and gcov_type.
+
+2003-10-09 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * configure.in (HAVE_AS_TLS): Add sh-*-* and sh[34]*-*-* cases.
+ * configure: Regenerate.
+
+2003-10-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (define_asm_attributes): Specify
+ the length of an asm insn more precisely.
+
+2003-10-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/iris6.h (SUBTARGET_CPP_SPEC): Define.
+
+2003-10-09 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (xtensa_dbx_register_number): Change first
+ FP register number to 48 and MAC16 accumulator to 0x210.
+
+2003-10-09 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Remove redundant thread_file setting clauses for
+ various *-*-linux* targets.
+
+2003-10-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (define_asm_attributes): New.
+
+2003-10-09 Roger Sayle <roger@eyesopen.com>
+
+ * optabs.c (prepare_float_lib_cmp): Always attach a REG_EQUAL note
+ to the comparison, as emit_libcall_block calls copy_rtx on equiv.
+
+2003-10-09 Dorit Naishlos <dorit@il.ibm.com>
+
+ * haifa-sched.c (ok_for_early_schedule): New function.
+ (early_queue_to_ready): New function.
+ (schedule_block): Allow early removal of insns from Q.
+ (schedule_insn): Update INSN_TICK in case of premature
+ issue.
+ * common.opt (sched_stalled_insns): New flag.
+ (sched_stalled_insns_dep): New flag.
+ * flags.h: Same above flags.
+ * opts.c: Same as above.
+ * toplev.c: Same as above.
+ * target.h (targetm.sched.is_costly_dependence): New
+ hook.
+ * target-def.h: Same as above.
+ * config/rs6000/rs6000.h: (rs6000_sched_costly_dep):
+ Support new flag -msched-costly-dep.
+ (DEFAULT_SCHED_COSTLY_DEP): Define.
+ * config/rs6000/rs6000.c:
+ (rs6000_is_costly_dependence): New function.
+ (is_load_insn, is_store_insn): New functions.
+ (is_load_insn1, is_store_insn1, is_mem_ref): New
+ functions.
+ * doc/invoke.texi (-fsched-stalled-insns-dep)
+ (-fsched-stalled-insns, -msched-costly-dep): Document
+ options.
+ * doc/tm.texi (is_costly_dependence): Define new
+ scheduler target hook.
+
+2003-10-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/6392
+ * c-common.c (c_build_qualified_type): Look through arrays first.
+ (c_apply_type_quals_to_decl): Look through arrays.
+
+ * c-common.c (c_apply_type_quals_to_decl): Unset TREE_READONLY for
+ types with constructors.
+
+ * coverage.c (build_ctr_info_value): Use build_decl to make a
+ VAR_DECL.
+ (create_coverage): Likewise.
+
+ * stmt.c (resolve_asm_operand_names): Call check_unique_operand_names
+ here.
+ (expand_asm_operands): Not here.
+ (parse_input_constraint): No longer static.
+ * tree.h: Declare it.
+
+2003-10-08 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/t-linux (SHLIB_LINK): Override to use a linker script
+ libgcc_s.so.
+ (SHLIB_INSTALL): Likewise.
+
+2003-10-08 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * doc/install.texi: Remove reference to removed 'pthreads' thread
+ option.
+
+2003-10-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.md ("abssi2_isel"): Add early clobber to
+ operand 2.
+
+2003-10-08 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Don't accept --enable-threads=pthreads. Clean
+ up related case statements.
+ * configure.in: Don't accept --enable-threads=pthreads,
+ decosf1, mach, or os2 (none of which work anyway). Alphabetize
+ supported thread files in case clause.
+ * configure: Regenerate.
+
+2003-10-08 Geoffrey Keating <geoffk@apple.com>
+
+ * function.c (pad_to_arg_alignment): Move 'boundary_in_bytes'
+ definition to above SPARC_STACK_BOUNDARY_HACK.
+
+2003-10-08 Jason Merrill <jason@redhat.com>
+
+ * c-pretty-print.c (pp_c_postfix_expression)
+ <COMPOUND_LITERAL_EXPR>: Fix thinko.
+
+2003-10-08 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * mklibgcc.in: Don't hide undefined or typeless symbols.
+
+2003-10-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR optimization/12142
+ * cse.c (count_reg_usage): In a SET with a REG SET_DEST, count the
+ uses of the register in the SET_SRC. Remove unnecessary argument.
+ * pa.c (legitimize_pic_address): Before reload, use a scratch register
+ for the intermediate result in loading the address of a SYMBOL_REF.
+ Set the MEM_NOTRAP_P flag for the MEM. Add a REG_EQUAL to the insn
+ which loads the SYMBOL_REF address.
+
+2003-10-08 Timo Kokkonen <tjko@iki.fi>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR bootstrap/12490
+ * scan-decls.c (MAX_EXTERN_C_BRACES): New preprocessor constant
+ to define the size of the extern_C_braces array. Set it to 200.
+ (scan_decls): Abort when extern_C_braces_length is out-of-bounds.
+
+2003-10-08 Carlo Wood <carlo@alinoe.com>
+
+ * Makefile.in (gengtype-lex.c): flex 2.5.4[a] doesn't understand
+ a space after the -o option. flex 2.5.31 understands both, with
+ and without the space. Removed that space.
+
+2003-10-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_frame_info): Add cprestore_size field.
+ (compute_frame_size): Initialize it. Remove the .cprestore slot
+ from args_size.
+ (mips_output_function_prologue): Simplify accordingly.
+ (mips_debugger_offset): Change the mips16 frame pointer offset from
+ current_function_outgoing_args to cfun->machine->frame.args_size.
+ (mips_initial_elimination_offset): Likewise.
+ (mips_expand_prologue): Likewise.
+ (mips_expand_epilogue): Likewise.
+
+2003-10-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (EXTRA_CONSTRAINT): Add 'W' constraint.
+ (EXTRA_MEMORY_CONSTRAINT): Define.
+ (CAN_ELIMINATE): Remove lwu workaround.
+ * config/mips/mips.md (*zero_extendsidi2_mem): Enable for mips16 too.
+ Use a 'W' constraint for the source operand.
+
+2003-10-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genopinit.c (main): Output code to declare undefined
+ variables.
+
+2003-10-07 Kelley Cook <kcook@gcc.gnu.org>
+
+ * gengtype-lex.l: Remove -Wtraditional cruft.
+ * Makefile.in (gengtype-lex.c): Likewise.
+
+2003-10-07 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopmanip.c (fix_irreducible_loops): Initialize e correctly.
+
+2003-10-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/12519
+ * c-semantics.c (genrtl_cleanup_stmt): Ignore the CLEANUP_DECL if
+ it isn't a decl.
+
+2003-10-07 Alexandre Oliva <aoliva@redhat.com>
+
+ * gcc.c (cpp_options): Only pass -fworking-directory for -g* if
+ not overridden.
+ Fixes PR bootstrap/12173.
+
+2003-10-07 Zack Weinberg <zack@codesourcery.com>
+
+ * errors.c: Don't include coretypes.h or tm.h.
+ (trim_filename): Use IS_DIR_SEPARATOR.
+ * Makefile.in: Update dependencies of errors.o and
+ $(BUILD_PREFIX_1)errors.o.
+
+2003-10-07 Geoffrey Keating <geoffk@apple.com>
+
+ * function.c (pad_to_arg_alignment): Take STACK_POINTER_OFFSET into
+ account when aligning arguments.
+ * calls.c (STACK_POINTER_OFFSET): Move default from here ...
+ * defaults.h (STACK_POINTER_OFFSET): ... to here.
+ * config/sparc/sparc.h (STACK_BOUNDARY): Add comment about how
+ it's wrong when TARGET_ARCH64 && TARGET_STACK_BIAS.
+ (SPARC_STACK_BOUNDARY_HACK): Define.
+ * config/rs6000/rs6000.c (function_arg): On non-SVR4 systems,
+ arrange for vector parameters to varargs functions to be passed
+ in both memory and GPRs when appropriate.
+ (rs6000_va_arg): Vector arguments passed in memory are 16-byte
+ aligned.
+
+ * hooks.c (hook_bool_tree_true): New.
+ (hook_rtx_tree_int_null): New.
+ (hook_rtx_rtx_null): Use NULL, not 0.
+ * hooks.h: Add 'extern' to everything.
+ (hook_bool_tree_true): New.
+ (hook_rtx_tree_int_null): New.
+ * targhooks.c (hook_bool_CUMULATIVE_ARGS_true): New.
+ * targhooks.h (hook_bool_CUMULATIVE_ARGS_true): New.
+ * config/rs6000/rs6000-protos.h (setup_incoming_varargs): Remove
+ prototype.
+ * config/rs6000/rs6000.c (rs6000_return_in_memory): New.
+ (setup_incoming_varargs): Prototype.
+ (TARGET_PROMOTE_FUNCTION_ARGS): Define.
+ (TARGET_PROMOTE_FUNCTION_RETURN): Define.
+ (TARGET_STRUCT_VALUE_RTX): Define.
+ (TARGET_RETURN_IN_MEMORY): Define.
+ (TARGET_SETUP_INCOMING_VARARGS): Define.
+ (TARGET_STRICT_ARGUMENT_NAMING): Define.
+ (TARGET_PRETEND_OUTGOING_VARARGS_NAMED): Define.
+ (init_cumulative_args): Use rs6000_return_in_memory.
+ (setup_incoming_varargs): Make 'static'.
+ * config/rs6000/rs6000.h (PROMOTE_FUNCTION_ARGS): Delete.
+ (PROMOTE_FUNCTION_RETURN): Delete.
+ (STRUCT_VALUE): Delete.
+ (RETURN_IN_MEMORY): Delete.
+ (SETUP_INCOMING_VARARGS): Delete.
+
+2003-10-07 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/invoke.texi (Warning Options): Simplify and clarify the
+ descriptions of -Wnonnull and -Winit-self.
+
+2003-10-07 Richard Earnshaw <rearnsha@arm.com>
+
+ * optabs.c (init_intraclass_conv_libfuncs): Fix order of array
+ indicees for floating-point conversersion libcalls.
+
+2003-10-07 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in: Add more comments separating large conceptually
+ separate sections.
+
+ * configure.in: Clean up thread file logic.
+ * configure: Regenerate.
+
+2003-10-07 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/cygming.h (READONLY_DATA_SECTION_ASM_OP): Define.
+ (switch_to_section): Handle in_readonly_data.
+ * config/i386/winnt.c (i386_pe_asm_named_section): Handle
+ readonly data.
+
+2003-10-07 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (cmpsi2_addneg): New ARM pattern. Add peephole2 to generate
+ it.
+ (cbranchne_decr1): New Thumb pattern.
+ * arm.c (arm_addimm_operand): New insn predicate.
+ * arm-protos.h: Add a prototype for it.
+ * arm.h (PREDICATE_CODES): Add it.
+
+2003-10-07 Dorit Naishlos <dorit@il.ibm.com>
+
+ * sched-int.h (sched_info): New field
+ sched_max_insns_priority.
+ * sched-rgn.c (init_ready_list): Add invocations to
+ targetm.sched.adjust_priority.
+ (sched_max_insns_priority): Init new field.
+ * sched-ebb.c (sched_max_insns_priority): Init new field.
+ * haifa-sched.c (set_priorities): Set
+ sched_info->sched_max_insns_priority.
+ * config/rs6000/rs6000.h:
+ (rs6000_sched_restricted_insns_priority_str): Support new
+ flag -mprioritize-restricted-insns.
+ (DEFAULT_RESTRICTED_INSNS_PRIORITY): Define.
+ * config/rs6000/rs6000.c (is_dispatch_slot_restricted): New
+ function.
+ (rs6000_adjust_priority): Change priority of restricted
+ insns, using above new function and new flag.
+ * doc/invoke.texi (-mprioritize-restricted-insns): Document
+ new option.
+
+2003-10-07 Zack Weinberg <zack@codesourcery.com>
+
+ * expr.c (cmpstr_optab, cmpmem_optab): New.
+ * genopinit.c: Initialize them.
+ * optabs.h: Declare them.
+ * optabs.c (init_optabs): Clear them.
+ (prepare_cmp_insn): Use cmpstr_optab and cmpmem_optab to find
+ block memory compare insns, not conditional chains. Restructure
+ the fallback generation of a call to memcmp/bcmp for better
+ readability.
+
+2003-10-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (MIPS_MAX_FIRST_STACK_STEP): New macro.
+ (mips_save_restore_fn): New typedef.
+ (mips_add_large_offset_to_sp, mips_emit_frame_related_store): Remove.
+ (mips_set_frame_expr, mips_frame_set): Move above prologue code.
+ (save_restore_insns): Remove, replacing with...
+ (mips_save_restore_reg, mips_for_each_saved_reg): ...these new fns.
+ (mips_save_reg, mips_restore_reg): New function.
+ (mips_expand_prologue, mips_expand_epilogue): Rework.
+ * config/mips/mips.h (MIPS_TEMP1_REGNUM, MIPS_TEMP2_REGNUM): Remove.
+ (MIPS_PROLOGUE_TEMP_REGNUM, MIPS_EPILOGUE_TEMP_REGNUM): New macros.
+ (MIPS_PROLOGUE_TEMP, MIPS_EPILOGUE_TEMP): New macros.
+
+2003-10-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_expand_prologue): Remove unused
+ traversal of function arguments.
+
+2003-10-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/invoke.texi: Remove documentation of -mentry.
+ * config/mips/mips.c (mips_entry_string, mips_entry): Remove.
+ (override_options, mips_save_reg_p): Remove handling.
+ (compute_frame_size, mips_output_function_prologue): Likewise.
+ (mips_expand_prologue, mips_expand_epilogue): Likewise.
+ * config/mips/mips.h (mips_entry_string): Remove declaration.
+ (TARGET_OPTIONS): Remove -mentry.
+ * config/mips/mips16.S: Remove mention of -mentry.
+
+2003-10-06 Zack Weinberg <zack@codesourcery.com>
+
+ * libfuncs.h (LTI_extendsfdf2, LTI_extendsfxf2, LTI_extendsftf2)
+ (LTI_extenddfxf2, LTI_extenddftf2, LTI_truncdfsf2, LTI_truncxfsf2)
+ (LTI_trunctfsf2, LTI_truncxfdf2, LTI_trunctfdf2, LTI_floatsisf)
+ (LTI_floatdisf, LTI_floattisf, LTI_floatsidf, LTI_floatdidf)
+ (LTI_floattidf, LTI_floatsixf, LTI_floatdixf, LTI_floattixf)
+ (LTI_floatsitf, LTI_floatditf, LTI_floattitf, LTI_fixsfsi, LTI_fixsfdi)
+ (LTI_fixsfti, LTI_fixdfsi, LTI_fixdfdi, LTI_fixdfti, LTI_fixxfsi)
+ (LTI_fixxfdi, LTI_fixxfti, LTI_fixtfsi, LTI_fixtfdi, LTI_fixtfti)
+ (LTI_fixunssfsi, LTI_fixunssfdi, LTI_fixunssfti, LTI_fixunsdfsi)
+ (LTI_fixunsdfdi, LTI_fixunsdfti, LTI_fixunsxfsi, LTI_fixunsxfdi)
+ (LTI_fixunsxfti, LTI_fixunstfsi, LTI_fixunstfdi, LTI_fixunstfti)
+ (extendsfdf2_libfunc, extendsfxf2_libfunc, extendsftf2_libfunc)
+ (extenddfxf2_libfunc, extenddftf2_libfunc, truncdfsf2_libfunc)
+ (truncxfsf2_libfunc, trunctfsf2_libfunc, truncxfdf2_libfunc)
+ (trunctfdf2_libfunc, floatsisf_libfunc, floatdisf_libfunc)
+ (floattisf_libfunc, floatsidf_libfunc, floatdidf_libfunc)
+ (floattidf_libfunc, floatsixf_libfunc, floatdixf_libfunc)
+ (floattixf_libfunc, floatsitf_libfunc, floatditf_libfunc)
+ (floattitf_libfunc, fixsfsi_libfunc, fixsfdi_libfunc, fixsfti_libfunc)
+ (fixdfsi_libfunc, fixdfdi_libfunc, fixdfti_libfunc, fixxfsi_libfunc)
+ (fixxfdi_libfunc, fixxfti_libfunc, fixtfsi_libfunc, fixtfdi_libfunc)
+ (fixtfti_libfunc, fixunssfsi_libfunc, fixunssfdi_libfunc)
+ (fixunssfti_libfunc, fixunsdfsi_libfunc, fixunsdfdi_libfunc)
+ (fixunsdfti_libfunc, fixunsxfsi_libfunc, fixunsxfdi_libfunc)
+ (fixunsxfti_libfunc, fixunstfsi_libfunc, fixunstfdi_libfunc)
+ (fixunstfti_libfunc): Delete.
+ * optabs.h (struct optab_handlers): Break out of struct optab.
+ (struct convert_optab, convert_optab, enum convert_optab_index,
+ convert_optab_table, sext_optab, zext_optab, trunc_optab,
+ sfix_optab, ufix_optab, sfixtrunc_optab, ufixtrunc_optab,
+ sfloat_optab, ufloat_optab): New.
+ (set_conv_libfunc): Prototype.
+ (GEN_FCN): Use C90 indirect call syntax, remove unnecessary cast.
+ (trunc_optab): Renamed btrunc_optab.
+ * builtins.c (expand_builtin_mathfn): Update to match.
+ * optabs.c (extendtab, fixtab, fixtrunctab, floattab): Delete.
+ (convert_optab_table, new_convert_optab, init_convert_optab)
+ (init_interclass_conv_libfuncs, init_intraclass_conv_libfuncs)
+ (set_conv_libfunc): New.
+ (can_extend_p, gen_extend_insn, can_fix_p, can_float_p)
+ (expand_float, expand_fix): Use new conversion optabs,
+ not old insn code tables or long chains of ifs.
+ (init_optabs): No need to clear old insn code tables.
+ Initialize the new optabs, not the old libfunc array entries.
+ Don't handle FIXUNS_TRUNC_LIKE_FIX_TRUNC here.
+ * genopinit.c: Initialize conversion optabs, not the
+ former insn code tables. Remove unnecessary casts.
+ Handle FIXUNS_TRUNC_LIKE_FIX_TRUNC here.
+ * expr.c (convert_move): Remove redundant check that
+ to_real==from_real. Use the conversion optabs instead
+ of long chains of tests of modes. Move partial-integer-mode
+ interconversion above all integer conversion. Do not recurse
+ on a value forced into a register in the original mode.
+
+ * config/gofast.h, config/frv/frv.c, config/ia64/ia64.c
+ * config/mips/mips.c, config/pa/pa.c, config/rs6000/rs6000.c
+ * config/sparc/sparc.c: Use set_conv_libfunc to adjust entries
+ in new conversion optabs; do not reference the old libfunc
+ array entries. No need to include libfuncs.h.
+
+2003-10-06 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.c (ix86_expand_setcc): Annotate the floating
+ point comparison sequence with a REG_EQUAL note that describes
+ the comparison's semantics.
+
+2003-10-06 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_expr <COND_EXPR>): Handle the void type semantics
+ of COND_EXPR when expanding the "A op 0 ? FOO : A" optimizations.
+
+2003-10-06 Roger Sayle <roger@eyesopen.com>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * optabs.c (prepare_float_lib_cmp): Avoid searching for REG_RETVAL
+ instruction by using LCT_CONST and then calling emit_libcall_block
+ ourselves.
+
+2003-10-06 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ PR optimization/11974
+ * optabs.c (expand_unop): Promote libcall outmode according to
+ hard_libcall_value.
+
+2003-10-06 Zack Weinberg <zack@codesourcery.com>
+
+ * real.h (REAL_MODE_FORMAT): New macro.
+ * c-cppbuiltin.c, optabs.c, real.c, config/alpha/alpha.c
+ * config/c4x/c4x.c, config/i370/i370.c, config/i386/freebsd.h
+ * config/i386/i386.c, config/i960/i960.c, config/ia64/ia64.c
+ * config/m68k/m68k.c, config/mips/mips.c, config/rs6000/rs6000.c
+ * config/vax/vax.c: Use REAL_MODE_FORMAT instead of referring
+ directly to real_format_for_mode array, wherever possible.
+
+2003-10-06 Devang Patel <dpatel@apple.com>
+
+ * dwarf2out.c (is_main_source): Remove variable.
+ (dwarf2out_start_source_file): Do not check is_main_source.
+ Do not reset is_main_source.
+ (dwarf2out_init): Do not initialize is_main_source.
+
+2003-10-06 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * fixinc/inclhack.def (stdio_va_list): Removed _ap fix.
+ (irix_stdio_va_list): Don't require leading printf, IRIX 6.5.21
+ introduced some multi-line prototypes.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-10-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (PREDICATE_CODES): Add stack_operand.
+ * config/mips/mips.c (stack_operand): New predicate.
+ * config/mips/mips.md: Use it for the destination of mips16 insns
+ that store $31.
+
+2003-10-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (*lowsi): Renamed from lowsi.
+ (*lowdi): Likewise lowdi.
+ (*lowsi_mips16, *lowdi_mips16): New patterns.
+ * config/mips/mips.c (mips_const_insns, mips_output_move): Remove
+ mips16 CONSTANT_RELOC handling.
+ (mips_delegitimize_address): Adjust for new sdata representation.
+
+2003-10-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_arg_info): If MUST_PASS_IN_STACK,
+ skip any remaining register arguments.
+
+2003-10-06 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * reload.c (find_reloads_subreg_address): Use correct offset for
+ paradoxical MEM subregs on big-endian targets.
+
+2003-10-06 Andrew Haley <aph@redhat.com>
+
+ * tree.c (get_callee_fndecl): Call
+ lang_hooks.lang_get_callee_fndecl.
+ * langhooks-def.h (LANG_HOOKS_GET_CALLEE_FNDECL): New.
+ (lhd_get_callee_fndecl): New.
+
+2003-10-06 Andrew Pinski <apinski@apple.com>
+
+ * config/darwin.c (machopic_non_lazy_ptr_name): Fix off by one
+ error in calculating the length of the string.
+ (machopic_stub_name): Likewise.
+
+2003-10-06 Roger Sayle <roger@eyesopen.com>
+
+ * optabs.c (prepare_float_lib_cmp): Attach a REG_EQUAL note
+ describing the return value of the comparison libcall to the
+ REG_RETVAL instruction of the emitted sequence.
+
+2003-10-06 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/12215
+ * cse.c (cse_set_around_loop): Emit the move at the beginning
+ of the next basic block for trapping sets.
+
+2003-10-06 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11637
+ * combine.c (adjust_for_new_dest): New function to adjust the
+ notes and LOG_LINKS when the dest of an insn has changed.
+ (try_combine): Use it when deleting the first insn of a two-insn
+ parallel or splitting a two-load parallel.
+
+2003-10-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_classify_constant): Only allow UNSPECs
+ if TARGET_EXPLICIT_RELOCS.
+
+2003-10-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR bootstrap/12512
+ * Makefile.in (info): Use double-colon rules.
+ (dvi): Likewise.
+ (generated-manpages): Likewise.
+ * configure.in: Do not create lang.info, lang.dvi, or
+ lang.generated-manpages hooks.
+ * configure: Regenerated.
+ * objc/Make-lang.in (objc.info): Remove.
+ (objc.dvi): Remove.
+ (objc.generated-manpages): Remove.
+ * doc/sourcebuild.texi: Update description of info, dvi, and
+ generated-manpages hooks.
+
+2003-10-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md: Merge mips16 lw/srl pattern with its splitter.
+
+2003-10-05 Andrew Pinski <apinski@apple.com>
+
+ * config/darwin.c (machopic_non_lazy_ptr_name): Fix off by one
+ errors in memcpy destinations.
+ (machopic_stub_name): Likewise.
+
+2003-10-05 Andrew Pinski <apinski@apple.com>
+
+ * config/darwin.c (machopic_non_lazy_ptr_name):
+ Change strcat to memcpy and add length together.
+ (machopic_stub_name): Likewise.
+
+2003-10-05 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Handle new
+ signal trampoline codes.
+
+2003-10-05 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.md (*divsf3): Move description of
+ SB-1 F2 erratum from here to...
+ (divsf3): Here. Disable if TARGET_FIX_SB1 is set and
+ flag_unsafe_math_optimizations is not.
+
+2003-10-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/linuxspe.h: Define TARGET_SPE_ABI, TARGET_SPE,
+ TARGET_E500, TARGET_ISEL, and TARGET_FPRS.
+
+2003-10-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-pretty-print.c: Fix comment typos.
+ * c-pretty-print.h: Likewise.
+ * calls.c: Likewise.
+ * cfgloopmanip.c: Likewise.
+ * cgraphunit.c: Likewise.
+ * cppfiles.c: Likewise.
+ * final.c: Likewise.
+ * function.c: Likewise.
+ * gcov-io.h: Likewise.
+ * gcse.c: Likewise.
+ * genoutput.c: Likewise.
+ * loop.c: Likewise.
+ * postreload.c: Likewise.
+ * reg-stack.c: Likewise.
+ * regmove.c: Likewise.
+ * sched-int.h: Likewise.
+ * sched-rgn.c: Likewise.
+ * simplify-rtx.c: Likewise.
+ * tree-inline.c: Likewise.
+ * config/m68hc11/m68hc11.h: Likewise.
+ * config/mmix/mmix.c: Likewise.
+ * config/mn10300/mn10300.md: Likewise.
+ * config/sh/sh.h: Likewise.
+
+2003-10-05 Richard Henderson <rth@redhat.com>
+
+ * tree-inline.c (remap_type): New.
+ (remap_decl): Use it. Remap DECL_SIZE*.
+ (copy_body_r): Use it.
+ (walk_tree): Walk TREE_TYPE too.
+ (copy_tree_r): Don't walk subtrees of types.
+ * tree.c (variably_modified_type_p): Restructure. Consider integer
+ types with non-const bounds variably modified.
+
+2003-10-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Fix typos.
+
+2003-10-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c: Follow spelling conventions.
+ * function.c: Likewise.
+ * config/c4x/c4x.h: Likewise.
+ * config/c4x/c4x.md: Likewise.
+ * config/frv/frv.md: Likewise.
+ * config/rs6000/aix.h: Likewise.
+ * config/rs6000/linux64.h: Likewise.
+ * config/xtensa/xtensa.c: Likewise.
+
+2003-10-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-pretty-print.c: Fix comment formatting.
+ * cfglayout.c: Likewise.
+ * cfgloopanal.c: Likewise.
+ * cppcharset.c: Likewise.
+ * dbxout.c: Likewise.
+ * ggc-page.c: Likewise.
+ * ggc.h: Likewise.
+ * target.h: Likewise.
+
+2003-10-04 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * gengtype-lex.l: Recognize typedef of functions without PARAMS macro.
+
+2003-10-04 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/v850/v850-c.c, config/v850/v850-protos.h, config/v850/v850.c:
+ Convert to ISO C90 function declarations and definitions.
+
+2003-10-04 Zack Weinberg <zack@codesourcery.com>
+
+ * libfuncs.h
+ (LTI_eqhf2, LTI_nehf2, LTI_gthf2, LTI_gehf2, LTI_lthf2)
+ (LTI_lehf2, LTI_unordhf2, LTI_eqsf2, LTI_nesf2, LTI_gtsf2)
+ (LTI_gesf2, LTI_ltsf2, LTI_lesf2, LTI_unordsf2, LTI_eqdf2)
+ (LTI_nedf2, LTI_gtdf2, LTI_gedf2, LTI_ltdf2, LTI_ledf2)
+ (LTI_unorddf2, LTI_eqxf2, LTI_nexf2, LTI_gtxf2, LTI_gexf2)
+ (LTI_ltxf2, LTI_lexf2, LTI_unordxf2, LTI_eqtf2, LTI_netf2)
+ (LTI_gttf2, LTI_getf2, LTI_lttf2, LTI_letf2, LTI_unordtf2)
+ (eqhf2_libfunc, nehf2_libfunc, gthf2_libfunc, gehf2_libfunc)
+ (lthf2_libfunc, lehf2_libfunc, unordhf2_libfunc, eqsf2_libfunc)
+ (nesf2_libfunc, gtsf2_libfunc, gesf2_libfunc, ltsf2_libfunc)
+ (lesf2_libfunc, unordsf2_libfunc eqdf2_libfunc, nedf2_libfunc)
+ (gtdf2_libfunc, gedf2_libfunc, ltdf2_libfunc, ledf2_libfunc)
+ (unorddf2_libfunc eqxf2_libfunc, nexf2_libfunc, gtxf2_libfunc)
+ (gexf2_libfunc, ltxf2_libfunc, lexf2_libfunc, unordxf2_libfunc
+ (eqtf2_libfunc, netf2_libfunc, gttf2_libfunc, getf2_libfunc)
+ (lttf2_libfunc, letf2_libfunc, unordtf2_libfunc):
+ Delete.
+ * optabs.h (OTI_eq, OTI_ne, OTI_gt, OTI_ge, OTI_lt, OTI_le)
+ (OTI_unord, eq_optab, ne_optab, gt_optab, ge_optab, lt_optab)
+ (le_optab, unord_optab): New.
+
+ * optabs.c (prepare_float_lib_cmp): Rewrite. Get the libfuncs
+ from the code_to_optab table, not a giant switch; use
+ swap_condition; do widening only if a comparison function that
+ we can call exists in a wider mode, not if a cmp_optab insn or
+ libfunc exists in a wider mode; call protect_from_queue
+ exactly once on each operand.
+ (init_optabs): Initialize the new optabs, not the deleted libfuncs.
+
+ * config/gofast.h, config/ia64/ia64.c, config/mips/mips.c
+ * config/pa/pa.c, config/rs6000/rs6000.c, config/sparc/sparc.c:
+ Set floating point comparison libfuncs using set_optab_libfunc
+ on the appropriate optab.
+
+ * config/ia64/ia64.c (ia64_hpux_init_libfuncs): Fix typo.
+ * config/rs6000/rs6000.c (rs6000_init_libfuncs): Correct ABI
+ selector conditionals.
+
+2003-10-04 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/t-m68hc11-gas (MULTILIB_MATCHES): m68hcs12 is
+ identical to m68hc12 as far as libraries are concerned.
+
+2003-10-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/12446
+ * c-typeck.c (convert_for_assignment): Issue an error for
+ array to pointer assignment after default conversion.
+ (digest_init): Likewise.
+
+2003-10-04 Fariborz Jahanian <fjahanian@apple.com>
+
+ * c-decl.c (duplicate_decls): retain DECL_COMMON of old declaration
+
+2003-10-03 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/extend.texi (Function Attributes): Fix title of GNU C
+ Preprocessor manual.
+ (C++ Extensions): Fix reference to "Predefined Macros" in the
+ GNU C Preprocessor manual.
+
+2003-10-04 Richard Earnshaw <reanrsha@arm.com>
+
+ * doc/extend.texi: Document how GCC estimates and relies on the size
+ of an asm.
+
+2003-10-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_pad_arg_upward): Pad floating-point
+ arguments downward for big-endian o64.
+
+2003-10-03 Robert Bowdidge <bowdidge@apple.com>
+
+ * ggc-page.c (ggc_pch_write_object): Replace fseek() with fwrite() in
+ PCH generation, avoiding too-frequent flushes when writing to NFS
+ file system.
+
+2003-10-03 Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (lookup_category): Mark as 'inline'.
+
+2003-10-03 Alexander Malmberg <alexander@malmberg.org>
+ Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (add_method_to_hash_list, lookup_category):
+ New functions.
+ (lookup_method_in_hash_lists): New parameter indicating whether
+ we are messaging 'Class' or 'id'.
+ (check_duplicates): Likewise; do not assume all methods will
+ be either class or instance methods.
+ (generate_category, finish_class): Use lookup_category().
+ (add_method): Use add_method_to_hash_list(); insert instance
+ methods of root classes into the global class method hash table.
+ (add_category): Use lookup_category(); avoid constructing
+ duplicate categories.
+ (really_start_method): Add method to corresponding @interface,
+ if not already there (and if the @interface exists).
+ (finish_message_expr, finish_objc): Adjust calls to
+ check_duplicates().
+
+2003-10-03 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/9325, PR java/6391
+ * fold-const.c (fold_convert): For floating point to integer
+ conversions, return the maximum/minimum representable integer
+ value if the real constant overflows the destination type.
+ * tree.c (real_value_from_int_cst): Allow the type to be NULL,
+ meaning don't truncate the result to a floating point mode.
+ Simplify the logic by calling real_from_integer directly.
+ * simplify-rtx.c (simplify_unary_operation): Implement the
+ same semantics for folding floating point to integer conversions
+ in RTL.
+
+2003-10-03 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.c (mips_emit_prefetch): Restructure
+ to avoid use of arrays, handle indexed prefetch.
+ * config/mips/mips.h (ISA_HAS_FP4, ISA_HAS_PREFETCH): Update comments.
+ (ISA_HAS_PREFETCHX): New deffine.
+ * config/mips/mips.md ("type" attr): Add new "prefetchx" value,
+ update comments.
+ (prefetch_indexed_di, prefetch_indexed_si): New insns.
+
+2003-10-03 Jeff Sturm <jsturm@one-point.com>
+ Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/12289
+ * calls.c (emit_call_1): Pretend to have popped the arguments
+ to noreturn and longjmp functions instead of ignoring them.
+ (expand_call): Don't adjust stack_pointer_dela while
+ inhibit_defer_pop is set.
+
+2003-10-03 Andreas Schwab <schwab@suse.de>
+
+ PR bootstrap/12276
+ * configure.in: Check for libunwind on the host only if building
+ a native compiler.
+ * configure: Regenerated.
+
+2003-10-03 Paolo Carlini <pcarlini@unitus.it>
+
+ * unwind-pe.h (read_encoded_value_with_base): Constify u and
+ its inizialization cast.
+
+2003-10-03 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/12485
+ * config/mips/mips.c (mips_load_got): GOT accesses can't trap.
+
+2003-10-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR optimization/12180
+ * tree-inline.c (inline_forbidden_p_1): Do not permit inlining of
+ functions containing calls to __builtin_next_arg.
+
+2003-10-02 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.c (mips_emit_prefetch): Use operand 3
+ in instructions being output.
+ * config/mips/mips.md (prefetch_si_address): Change third
+ operand's constraint letter to 'I'.
+ (prefetch_di_address): Likewise.
+ (prefetch_si, prefetch_di): Set third operand to const0_rtx.
+
+2003-10-02 Zack Weinberg <zack@codesourcery.com>
+
+ * system.h: Poison macros obsoleted by earlier patch.
+ * config/cris/cris.c: C90-ify a function definition.
+
+2003-10-02 Josef Zlomek <zlomekj@suse.cz>
+
+ PR/12292
+ * combine.c (make_field_assignment): Check whether rtx's code
+ is CONST_INT before using INTVAL.
+
+2003-10-02 Josef Zlomek <zlomekj@suse.cz>
+
+ * cgraph.c (cgraph_node): Use INSERT instead of 1 in
+ htab_find_slot_with_hash.
+ (cgraph_node_for_identifier): Use NO_INSERT.
+ (cgraph_remove_node): Use NO_INSERT.
+ (cgraph_varpool_node): Use INSERT.
+ (cgraph_varpool_node_for_identifier): Use NO_INSERT.
+
+2003-10-02 Josef Zlomek <zlomekj@suse.cz>
+
+ Waldek Hebisch <hebisch@math.uni.wroc.pl>
+ PR/12072
+ * varasm.c (compare_constant): Fix thinko.
+
+2003-10-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/frv/frv.c (frv_issue_rate): New function.
+ (frv_pack_insns): Use it.
+ (TARGET_SCHED_ISSUE_RATE): Define.
+
+2003-10-02 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * config/mcore/mcore.c: Convert to ISO C90 function declarations
+ and definitions.
+ * config/mcore/mcore.h: Likewise.
+ * config/mcore/mcore-protos.h: Likewise.
+
+2003-10-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/frv/frv.c (frv_use_dfa_pipeline_interface): New function.
+ (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE): Define.
+
+2003-10-01 Per Bothner <pbothner@apple.com>
+
+ * c-lex.c (src_line): Remove unneeded static variable.
+ (cb_line_change): Set input_line directly, instead of src_line.
+ (get_non_padding_token): We no longer need to compensate for the
+ "horrible things" the C++ front-end does with the current line number,
+
+ * cpplib.c (_cpp_pop_buffer): Do generate a _cpp_do_file_change
+ callback even when popping the main file.
+ * c-lex.c (fe_file_change): Handle a NULL new_map.
+ * fix-header.c (cb_file_change): Likewise.
+ * c-ppoutput.c (pp_file_change): Likewise.
+
+ * cppinit.c (cpp_read_main_file): Split into two functions:
+ Distribute _cpp_stack_file call over the two functions.
+ (cpp_find_main_file): New function.
+ Don't call _cpp_do_file_change even if working_directory flag set.
+ (cpp_push_main_file): New function.
+ * cppfiles.c (_cpp_find_failed): New helper function.
+ (find_file): Made non-static and renamed to _cpp_find_file.
+ (_cpp_stack_file): No longer needed. But note the following.
+ (stack_file): Made non-static and renamed to _cpp_stack_file.
+ * fix-header.c (cpp_read_main_file): Replace cpp_read_main_file
+ call with calls to cpp_find_main_file and cpp_push_main_file.
+ (search_path_head): If there is no current buffer, use main_file.
+ * cpphash.h: Update function declarations.
+ * cpplib.h: Update function declarations.
+
+ * c-opts.c (c_common_post_options): Don't call cpp_find_main_file yet.
+ (c_common_parse_file): No longer need to call cpp_read_main_file
+ when file_index > 0 (as in multi-file or server compiation).
+ (finish_options): Change to <built-in> is an LC_ENTER, not LC_RENAME
+ as this now happens before cpp_push_main_file.
+ (push_command_line_include): When done with options, pass LC_LEAVE
+ instead of LC_RENAME to cpp_change_file and finally cpp_push_main_file.
+ (fe_file_change): Handle NULL new_map, and simplify.
+ * cpplex.c (_cpp_get_fresh_line): Revert my no-longer-needed
+ 08-28 change, since we're never called with a NULL buffer.
+ (_cpp_lex_direct): Likewise.
+ * cpptrad.c (_cpp_read_logical_line_trad): Likewise.
+ Return false if buffer is NULL at end.
+
+ * cpplex.c (_cpp_get_fresh_line): Return value now just depends on
+ whether pfile->buffer is NULL after pop, ignoring return_at_eof.
+ * cpphash.h (struct cpp_buffer): Remove unused return_at_eof field.
+ * cpplib.c (cpp_push_buffer): Since we no longer set return_at_eof,
+ remove the unused return_at_eof parameter.
+ * cppfiles.c, cpplib.c, cppmacro.c, cpppch.c, fix-header.c:
+ Update callers of cpp_push_buffer.
+
+2003-10-01 Zack Weinberg <zack@codesourcery.com>
+
+ * target.h (init_libfuncs): New hook.
+ * target-def.h: Default TARGET_INIT_BUILTINS and
+ TARGET_INIT_LIBFUNCS to hook_void_void. Add
+ TARGET_INIT_LIBFUNCS to TARGET_INITIALIZER.
+ * builtins.c (default_init_builtins): Delete.
+ * expr.h (default_init_builtins): Delete prototype.
+ * doc/tm.texi: Document TARGET_INIT_LIBFUNCS and US_SOFTWARE_GOFAST.
+ Tweak documentation of TARGET_FLOAT_LIB_COMPARE_RETURNS_BOOL.
+ Remove documentation of INIT_TARGET_OPTABS, MULSI3_LIBCALL,
+ DIVSI3_LIBCALL, UDIVSI3_LIBCALL, MODSI3_LIBCALL, UMODSI3_LIBCALL,
+ MULDI3_LIBCALL, DIVDI3_LIBCALL, UDIVDI3_LIBCALL, MODDI3_LIBCALL,
+ and UMODDI3_LIBCALL,
+
+ * Makefile.in (optabs.o): Depends on target.h.
+ * defaults.h: Provide default for FLOAT_LIB_COMPARE_RETURNS_BOOL.
+ * optabs.c: Include target.h.
+ (prepare_float_lib_cmp): No need for #ifdef around use of
+ FLOAT_LIB_COMPARE_RETURNS_BOOL.
+ (set_optab_libfunc): New function.
+ (init_optabs): Delete use of all *_LIBCALL defines.
+ Call targetm.init_libfuncs not INIT_TARGET_OPTABS.
+ * optabs.h: Prototype set_optab_libfunc.
+
+ * config.gcc: Remove all references to pa/long_double.h,
+ ia64/hpux_longdouble.h, and gofast.h.
+ (mips-*-*): When --enable-gofast, just add US_SOFTWARE_GOFAST
+ to tm_defines; don't set INIT_SUBTARGET_OPTABS or change tm_file.
+
+ * config/alpha/alpha.c, config/c4x/c4x.c, config/cris/cris.c
+ * config/frv/frv.c, config/h8300/h8300.c, config/i860/i860.c
+ * config/ia64/ia64.c, config/ip2k/ip2k.c, config/m68hc11/m68hc11.c
+ * config/mips/mips.c, config/pa/pa.c, config/rs6000/rs6000.c
+ * config/sparc/sparc.c, config/vax/vax.c:
+ Provide a definition for TARGET_INIT_LIBFUNCS. Where
+ necessary, include optabs.h, libfuncs.h, and/or config/gofast.h.
+
+ * config/alpha/unicosmk.h, config/alpha/vms.h, config/c4x/c4x.h
+ * config/avr/avr.h, config/cris/cris.h, config/frv/frv.h
+ * config/h8300/h8300.h, config/i860/i860.h, config/ip2k/ip2k.h
+ * config/iq2000/iq2000.h, config/m68hc11/m68hc11.h, config/mips/mips.h
+ * config/rs6000/aix.h, config/rs6000/sysv4.h, config/sparc/elf.h
+ * config/sparc/lite.h, config/sparc/netbsd-elf.h, config/sparc/sol2.h
+ * config/sparc/sparc.h, config/v850/v850.h, config/vax/vax.h
+ * config/vax/elf.h: Don't define or use INIT_TARGET_OPTABS,
+ INIT_SUBTARGET_OPTABS, or any *_LIBCALL macros.
+
+ * config/ia64/hpux.h: Redefine INTEL_EXTENDED_IEEE_FORMAT to 0.
+ Set TARGET_INIT_LIBFUNCS and FLOAT_LIB_COMPARE_RETURNS_BOOL here.
+ * config/pa/pa-hpux.h: Define LONG_DOUBLE_TYPE_SIZE,
+ HPUX_LONG_DOUBLE_LIBRARY, and FLOAT_LIB_COMPARE_RETURNS_BOOL here.
+ * config/ia64/hpux_longdouble.h, config/pa/long_double.h: Delete.
+
+ * config/rs6000/xcoff.h: Don't define RS6000_ITRUNC nor RS6000_UITRUNC.
+ * config/sparc/sparc.h: Default SUN_CONVERSION_LIBFUNCS and
+ SUN_INTEGER_MULTIPLY_64 to 0.
+ * config/sparc/sol2.h: Redefine SUN_CONVERSION_LIBFUNCS and
+ SUN_INTEGER_MULTIPLY_64 to 1.
+ * config/sparc/elf.h: Redefine SUN_CONVERSION_LIBFUNCS and
+ SUN_INTEGER_MULTIPLY_64 to 0.
+ * config/sparc/lite.h, config/sparc/liteelf.h, config/sparc/sp86x-elf.h:
+ Define US_SOFTWARE_GOFAST.
+ * config/vax/vax.h: Default TARGET_ELF to 0.
+ * config/vax/elf.h: Redefine TARGET_ELF to 1.
+
+ * config/gofast.h: Don't define any macros here. Provide one
+ static function, gofast_maybe_init_libfuncs, which does what
+ INIT_GOFAST_LIBFUNCS used to do but only if US_SOFTWARE_GOFAST
+ is already defined. Do not clear negation libfuncs. Do
+ not mess with HFmode, XFmode, or TFmode libfuncs.
+
+ * config/avr/avr.c (avr_init_once): #if 0 out; mark FIXME.
+
+2003-10-01 Kelley Cook <kelleycook@wideopenwest.com>
+
+ PR C/12466
+ * c-parse.in (parmlist_2): Mark declaration with an ellipsis as ISO C.
+
+2003-10-01 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/xm-iris5.h: Remove, unnecessary.
+ * config.build (mips-sgi-irix5*): Remove.
+ (mips-sgi-irix6*o32): Likewise.
+ * config.gcc (mips-sgi-irix6*o32): Remove xm_file.
+ (mips-sgi-irix5cross64): Likewise.
+ (mips-sgi-irix5*): Likewise.
+ * config.host (mips-sgi-irix5*): Remove.
+ (mips-sgi-irix6*o32): Likewise.
+
+2003-10-01 Zack Weinberg <zack@codesourcery.com>
+
+ * dbxout.c (dbxout_fptype_value): Delete.
+ (dbxout_type): Emit R3 for all COMPLEX_TYPEs.
+
+2003-10-01 Alexandre Oliva <aoliva@redhat.com>
+
+ * output.h (compute_reloc_for_constant): Declare.
+ * varasm.c (compute_reloc_for_constant): Extract from...
+ (output_addressed_constants): ... here. Adjust all callers.
+
+2003-10-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * aclocal.m4: Add hpux10* and hpux11.00 to /dev/zero blacklist.
+ * configure: Rebuilt.
+
+2003-10-01 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * fold-const.c (make_range): When handling unsigned, don't reverse
+ range if high bound is zero.
+
+2003-09-30 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/frv/frv.h (PREDICATE_CODES): Added
+ condexec_si_media_operator, condexec_sf_add_operator and
+ condexec_sf_conv_operator. Removed condexec_sf_binary_operator
+ and condexec_sf_unary_operator.
+
+2003-10-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * aclocal.m4: Add ultrix* to /dev/zero blacklist.
+ * configure: Rebuilt.
+
+2003-10-01 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * except.h (MUST_USE_SJLJ_EXCEPTIONS): Revert 2003-09-23 change.
+ Allow override.
+ * doc/tm.texi (MUST_USE_SJLJ_EXCEPTIONS): Document.
+
+2003-09-23 David S. Miller <davem@redhat.com>
+
+ * config/sparc/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Undefine
+ before redefining.
+ * config/sparc/linux64.h (LINK_GCC_C_SEQUENCE_SPEC): Likewise.
+
+2003-10-01 Steven Bosscher <steven@gcc.gnu.org>
+
+ * config/cris/cris-protos.h, config/cris/cris.c: Convert to ISO
+ C90 function declarations and definitions.
+
+2003-10-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (cris-*-linux*): Revert mistaken commit.
+
+2003-10-01 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11753
+ * config/sparc/sparc.md (length attribute) [fcc branch]: Add 1 to
+ the length in the non-V9 case.
+
+2003-09-30 Richard Henderson <rth@redhat.com>
+
+ * dwarf2out.c (expand_builtin_init_dwarf_reg_sizes): Honor
+ DWARF_ALT_FRAME_RETURN_COLUMN.
+ * unwind-dw2.c (dwarf_reg_size_table): Expand by one.
+ (_Unwind_GetGR, _Unwind_SetGR): Validate lookup column.
+ (uw_frame_state_for): Return end-of-stack for null return address.
+ * doc/tm.texi (DWARF_ALT_FRAME_RETURN_COLUMN): Add.
+
+ * config/alpha/alpha.c (alpha_sa_mask): Add r31 for eh_return.
+ (alpha_expand_prologue): Store a zero for it.
+ (alpha_expand_epilogue): Don't reload it.
+ * config/alpha/alpha.h (DWARF_ALT_FRAME_RETURN_COLUMN): New.
+ * config/alpha/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Use column 64
+ for the sigframe return address.
+
+2003-09-30 Kelley Cook <kelleycoook@wideopenwest.com>
+
+ * sdbout.c: Convert to ISO C90 prototypes.
+ * objc/objc-act.c: Likewise.
+
+2003-09-30 Kelley Cook <kelleycoook@wideopenwest.com>
+
+ * config/i386/cygwin1.c: Convert to ISO C90 prototypes.
+ * config/i386/winnt.c: Likewise.
+ * config/i386/cygming.h: Likewise.
+
+2003-09-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold): Fold (A & ~B) - (A & B) into
+ (A ^ B) - B for any B.
+
+2003-09-30 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (arm*-*-kaos*, i[34567]86-*-kaos*, powerpc-*-kaos*,
+ powerpcle-*-kaos*, strongarm-*-kaos*): Disable fixproto.
+
+2003-09-30 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm/ieee754-sf.S: Tidy formatting.
+
+2003-09-30 Nicolas Pitre <nico@cam.org>
+
+ * arm/lib1funcs.asm (ARM_DIV_MOD_BODY): Split into ARM_DIV_BODY
+ and ARM_MOD_BODY.
+ (ARM_MOD_BODY): Rewritten. added clz insns for __ARM_ARCH__ >= 5.
+ (ARM_DIV_BODY): Added clz insns for __ARM_ARCH__ >= 5,
+ added better divisor alignment in the other case.
+ (ARM_DIV2_ORDER): Added, finds the order of a single bit divisor.
+ (__divsi3, __udivsi3, __modsi3, __umodsi3): rewritten using the
+ macros above, add fast exits for divisor >= dividend, etc.
+
+2003-09-30 Nicolas Pitre <nico@cam.org>
+
+ * arm/ieee754-df.S: Split compilation of fixunsdfsi from
+ L_fixdfsi target.
+ * arm/t-arm-elf (LIB1ASMFUNCS): Add _fixunsdfsi.
+
+2003-09-30 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Default use_fixproto to 'no'.
+
+2003-09-30 Richard Sandiford <rsandifo@redhat.com>
+
+ PR optimization/12345
+ * config/mips/mips-protos.h (mips_restore_gp): Remove.
+ (mips_gp_save_slot): Declare.
+ * config/mips/mips.c (mips_restore_gp): Remove in favor of...
+ (mips_gp_save_slot): ...this new function.
+ * config/mips/mips.md (exception_receiver): Use mips_gp_save_slot
+ and mips_output_move to generate the output template.
+ (call_internal): Force splitting if TARGET_SPLIT_CALLS. Don't emit
+ a gp load after a noreturn call. Load the gp using a move rather
+ than an exception_receiver pattern.
+ (call_value_internal, call_value_multiple_internal): Likewise.
+ (call_split, call_value_split, call_value_multiple_split): Clobber $28.
+
+2003-09-30 Carlo Wood <carlo@alinoe.com>
+
+ PR debug/12319
+ * cfglayout.c (insn_scope): Use prologue_locator and
+ epilogue_locator; return the outer function scope for
+ pro- and epilogue insns.
+
+2003-09-29 Zack Weinberg <zack@codesourcery.com>
+
+ * objc/objc-act.c (encode_type): Encode INTEGER_TYPEs and
+ REAL_TYPEs based on the bitsize of the type's mode, not the
+ mode directly.
+
+2003-09-29 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * dwarf2out.c (default_eh_frame_section): Split into ...
+ (named_section_eh_frame_section, collect2_eh_frame_section): ... new
+ functions.
+ * output.h (named_section_eh_frame_section): Declare.
+ (collect2_eh_frame_section): Likewise.
+
+2003-09-29 Zack Weinberg <zack@codesourcery.com>
+
+ * real.c (real_sqrt): Use get_canonical_qnan directly.
+
+ * dwarf2out.c (add_const_value_attribute): Use real_to_target.
+
+ * varasm.c (assemble_real): Use real_to_target directly,
+ calculate the number of significant elements of the result
+ array and write them out in a loop, instead of using a giant
+ switch statement to pick the correct REAL_VALUE_TO_TARGET_*
+ macro.
+
+2003-09-29 Jan Hubicka <jh@suse.cz>
+
+ PR c++/12175
+ * varasm.c (notice_global_symbol): Discard external symbols.
+
+ PR optimization/12286
+ * gcov-io.c (gcov_read_words): Fix memmove call.
+ * profile.c (compute_branch_probabilities): Add extra sanity checks.
+
+2003-09-29 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config.gcc (sparc-*-solaris2*): Handle Solaris 10 and up like
+ Solaris 7-9.
+
+ * fixinc/inclhack.def (solaris_widec): Replace solaris2.[0-5]* by
+ wildcards which explicitly match micro versions.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-09-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold): Fold (A & ~B) - (A & B) into
+ (A ^ B) - B, where B is any power of 2 minus 1.
+
+2003-09-29 Jan Hubicka <jh@suse.cz>
+
+ * libgcov.c (gcov_exit): Fix two pastos.
+
+2003-09-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*tst_extzv_1_n): Combine with the
+ define_split immediately below to form define_insn_and_split.
+
+2003-09-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*tstsi_variable_bit): New.
+ (*tstsi_variable_bit_qi): Likewise.
+
+2003-09-28 Phil Edwards <phil@codesourcery.com>
+
+ * doc/cppopts.texi: Use 'dashMP' instead of '-MP' as a cross-
+ reference name.
+
+2003-09-28 Richard Henderson <rth@redhat.com>
+
+ * c-decl.c (duplicate_decls): Copy DECL_SOURCE_LOCATION, not
+ file and line separately.
+
+2003-09-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*adddi3_carry1_cc", "*adddi3_carry1_cconly",
+ "*adddi3_carry2_cc", "*adddi3_carry2_cconly", "*subdi3_borrow_cc",
+ "*subdi3_borrow_cconly"): New insns.
+ ("*addsi3_sub", "*subsi3_sub"): Remove.
+ ("*subdi3_cc", *subdi3_cconly"): Use only if TARGET_64BIT.
+ ("*subsi3_cc"): Fix op_type attribute.
+
+2003-09-28 Richard Henderson <rth@redhat.com>
+
+ * stmt.c (expand_asm_operands): Take a location_t, instead of
+ individual file and line.
+ * c-typeck.c (c_expand_asm_operands): Likewise.
+ * tree.h (expand_asm_operands): Update decl.
+ * c-common.h (c_expand_asm_operands): Likewise.
+ * c-semantics (genrtl_asm_stmt): Update call.
+
+2003-09-28 Philip Blundell <philb@gnu.org>
+
+ * config/arm/arm.c (legitimize_pic_address): Check
+ SYMBOL_REF_LOCAL_P, not ENCODED_SHORT_CALL_ATTR_P.
+ (arm_assemble_integer): Likewise.
+
+2003-09-28 Steven Bosscher <steven@gcc.gnu.org>
+
+ * config/pdp11/pdp11-protos.h, config/pdp11/pdp11.c,
+ config/c4x/c4x-c.c, config/c4x/c4x-protos.h, config/c4x/c4x.c,
+ config/c4x/c4x.h:
+ Convert to ISO C90 function declarations and definitions.
+
+2003-09-28 Steven Bosscher <steven@gcc.gnu.org>
+
+ * config/stormy16/stormy16.c, config/stormy16/stormy16-protos.h:
+ Convert to ISO C90 function declarations and definitions.
+
+2003-09-28 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_constant_info): Add reloc field.
+ (mips_classify_constant): Initialize it. Always set SYMBOL to the
+ underlying symbol, not to an unspec.
+ (mips_delegitimize_address, print_operand): Clean up accordingly.
+
+2003-09-28 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips16_gp_pseudo_reg): Remove.
+ * config/mips/mips.h (LEGITIMATE_CONSTANT_P): Remove orphaned comment.
+ * config/mips/mips.c (mips_reloc_offset_ok_p): New function.
+ (mips_classify_constant): Use it.
+ (mips_splittable_symbol_p): Add an offset argument.
+ (mips_classify_address): Adjust call accordingly.
+ (mips_legitimize_symbol): Handle sdata references with LO_SUM rather
+ than a relocation unspec. Update call to mips_splittable_symbol_p.
+ Generalize the code that copes with symbols + invalid offsets.
+ (print_operand): Allow '%R' to be applied to small data addresses.
+ (mips_reloc_string): Remove RELOC_GPREL16.
+ (mips_sdata_pointer): Renamed from mips16_gp_pseudo_reg. Return $gp
+ for TARGET_EXPLICIT_RELOCS. Return null if we can't use gp-relative
+ relocation operators.
+ * config/mips/mips.md (RELOC_GPREL16): Remove. Shuffle other reloc
+ constants accordingly.
+
+2003-09-27 Roger Sayle <roger@eyesopen.com>
+
+ * toplev.c (flag_evaluation_order): New global variable.
+ * flags.h (flag_evaluation_order): Prototype here.
+ * expr.c (expand_operands): If we need to preserve observable
+ evaluation order, protect exp1 from clobbering exp0's result.
+
+2003-09-28 Andreas Jaeger <aj@suse.de>
+
+ * c-decl.c (finish_function): Convert definition to ISO C90.
+ * ifcvt.c (mark_loop_exit_edges): Likewise.
+ * ra-rewrite.c (emit_colors): Likewise.
+
+2003-09-27 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (alpha*-dec-osf[45]*): Disable fixproto.
+ * config.gcc (arm*-*-uclinux*): Disable fixproto.
+ * config.gcc (powerpc-*-eabispe*, powerpc-*-eabisimaltivec*,
+ powerpc-*-eabialtivec*): Disable fixproto.
+
+2003-09-27 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/12340
+ * loop.h (struct induction): Document the new semantics
+ of the 'same' field for bivs.
+ * unroll.c (biv_total_increment): Don't count the same
+ biv increment several times.
+ (loop_iterations) [GENERAL_INDUCT]: Likewise.
+
+2003-09-27 Graham Stott <graham.stott@btinternet.com>
+
+ * unroll.c (loop_interations)[GT]: Add missing break.
+
+2003-09-27 Kelley Cook <kcook@gcc.gnu.org>
+
+ * config/chorus.h, config/darwin-c.c, config/darwin-protos.h,
+ config/darwin.c, config/darwin.h, config/dbx.h, config/dbxcoff.h,
+ config/dbxelf.h, config/elfos.h, config/fp-bit.h,
+ config/freebsd-nthr.h, config/freebsd-spec.h, config/freebsd.h,
+ config/freebsd3.h, config/freebsd4.h, config/freebsd5.h,
+ config/freebsd6.h, config/netbsd-aout.h, config/netbsd-elf.h,
+ config/netbsd.h, config/netware.h, config/openbsd-oldgas.h,
+ config/openbsd.h, config/ptx4.h, config/alpha/alpha-protos.h,
+ config/alpha/alpha.c, config/alpha/alpha.h, config/alpha/alpha.md,
+ config/alpha/elf.h, config/alpha/ev4.md, config/alpha/ev5.md,
+ config/alpha/ev6.md, config/alpha/freebsd.h, config/alpha/linux-elf.h,
+ config/alpha/linux.h, config/alpha/netbsd.h, config/alpha/openbsd.h,
+ config/alpha/osf.h, config/alpha/osf5.h, config/alpha/unicosmk.h,
+ config/alpha/vms-cc.c, config/alpha/vms-crt0-64.c,
+ config/alpha/vms-crt0.c, config/alpha/vms-dwarf2.asm,
+ config/alpha/vms-dwarf2eh.asm, config/alpha/vms-ld.c,
+ config/alpha/vms-psxcrt0-64.c, config/alpha/vms-psxcrt0.c,
+ config/alpha/vms.h, config/alpha/vms64.h, config/alpha/vms_tramp.asm,
+ config/alpha/xm-vms.h, config/arc/arc-modes.def,
+ config/arc/arc-protos.h, config/arc/arc.c, config/arc/arc.h,
+ config/arc/arc.md, config/arc/initfini.c, config/arc/lib1funcs.asm,
+ config/avr/avr-protos.h, config/avr/avr.c, config/avr/avr.h,
+ config/avr/avr.md, config/d30v/d30v-protos.h, config/d30v/d30v.h,
+ config/d30v/d30v.md, config/fr30/fr30-protos.h, config/fr30/fr30.c,
+ config/fr30/fr30.h, config/fr30/fr30.md, config/fr30/lib1funcs.asm,
+ config/frv/cmovd.c, config/frv/cmovh.c, config/frv/cmovw.c,
+ config/frv/frv-abi.h, config/frv/frv-asm.h, config/frv/frv-modes.def,
+ config/frv/frv-protos.h, config/frv/frv.c, config/frv/frv.h,
+ config/frv/frv.md, config/frv/frvbegin.c, config/frv/frvend.c,
+ config/frv/lib1funcs.asm, config/h8300/clzhi2.c, config/h8300/ctzhi2.c,
+ config/h8300/parityhi2.c, config/h8300/popcounthi2.c,
+ config/i370/i370-c.c, config/i370/i370-protos.h, config/i370/i370.c,
+ config/i370/i370.h, config/i370/i370.md, config/i370/linux.h,
+ config/i370/mvs.h, config/i370/oe.h, config/i386/darwin.h,
+ config/i960/i960-c.c, config/i960/i960-coff.h,
+ config/i960/i960-modes.def, config/i960/i960-protos.h,
+ config/i960/i960.c, config/i960/i960.h, config/i960/i960.md,
+ config/i960/rtems.h, config/ia64/elf.h, config/ia64/ia64.h,
+ config/m32r/initfini.c, config/m32r/m32r-protos.h, config/m32r/m32r.c,
+ config/m32r/m32r.h, config/m32r/m32r.md, config/m68hc11/larith.asm,
+ config/m68hc11/m68hc11-protos.h, config/m68hc11/m68hc11.c,
+ config/m68hc11/m68hc11.h, config/m68hc11/m68hc11.md,
+ config/m68hc11/m68hc12.h, config/m68k/coff.h, config/m68k/crti.s,
+ config/m68k/crtn.s, config/m68k/hp320.h, config/m68k/hp320base.h,
+ config/m68k/lb1sf68.asm, config/m68k/linux.h, config/m68k/m68020-elf.h,
+ config/m68k/m68k-aout.h, config/m68k/m68k-none.h,
+ config/m68k/m68k-protos.h, config/m68k/m68k.c, config/m68k/m68k.h,
+ config/m68k/m68k.md, config/m68k/m68kelf.h, config/m68k/m68kv4.h,
+ config/m68k/netbsd-elf.h, config/m68k/openbsd.h,
+ config/m68k/rtemself.h, config/m68k/sgs.h, config/mcore/lib1.asm,
+ config/mcore/mcore-elf.h, config/mcore/mcore-pe.h,
+ config/mcore/mcore-protos.h, config/mcore/mcore.c,
+ config/mcore/mcore.md, config/mips/elf.h, config/mips/elf64.h,
+ config/mips/elforion.h, config/mips/iris5.h, config/mips/iris6.h,
+ config/mips/iris6gld.h, config/mips/irix6-libc-compat.c,
+ config/mips/linux.h, config/mips/mips-protos.h, config/mips/mips.c,
+ config/mips/mips.h, config/mips/mips.md, config/mips/netbsd.h,
+ config/mips/openbsd.h, config/mips/r3900.h, config/mips/rtems.h,
+ config/mips/vr.h, config/mn10300/linux.h,
+ config/mn10300/mn10300-protos.h, config/mn10300/mn10300.c,
+ config/mn10300/mn10300.h, config/mn10300/mn10300.md,
+ config/ns32k/__unorddf2.c, config/ns32k/__unordsf2.c,
+ config/ns32k/netbsd.h, config/ns32k/ns32k-protos.h,
+ config/ns32k/ns32k.c, config/ns32k/ns32k.h, config/ns32k/ns32k.md,
+ config/pdp11/2bsd.h, config/pdp11/pdp11-modes.def,
+ config/pdp11/pdp11-protos.h, config/pdp11/pdp11.c,
+ config/pdp11/pdp11.h, config/pdp11/pdp11.md, config/rs6000/biarch64.h,
+ config/rs6000/default64.h, config/sh/coff.h, config/sh/crt1.asm,
+ config/sh/crti.asm, config/sh/crtn.asm, config/sh/elf.h,
+ config/sh/embed-elf.h, config/sh/linux.h, config/sh/little.h,
+ config/sh/netbsd-elf.h, config/sh/rtems.h, config/sh/rtemself.h,
+ config/sh/sh-protos.h, config/sh/sh.c, config/sh/sh.h,
+ config/sh/sh.md, config/sh/sh64.h, config/sh/shmedia.h,
+ config/sh/sshmedia.h, config/sh/ushmedia.h, config/sparc/pbd.h,
+ config/sparc/sparc.h, doc/install-old.texi, fixinc/fixinc.ptx,
+ fixinc/fixinc.svr4: GNU CC -> GCC.
+
+2003-09-26 Loren James Rittle <ljrittle@acm.org>
+
+ * objc/objc-act.c (tm_p.h): Tweak order.
+ * objc/Make-lang.in (objc/objc-act.o): Add $(TM_P_H).
+
+2003-09-26 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (hppa*64*-*-linux* | parisc*64*-*-linux*):
+ Include t-slibgcc-elf-ver and t-linux in tmake_file.
+ * config.gcc (hppa*64*-*-linux* | parisc*64-*-linux*):
+ Disable fixproto.
+ * config.gcc (i960-*-coff*, m68k-*-aout*, sparclite-*-coff*):
+ Disable fixproto.
+ * config.gcc (i[34567]86-*-solaris2*, sparc64-*-solaris2*,
+ sparcv9-*-solaris2*, sparc-*-solaris2*): Disable fixproto.
+
+ * config/i386/unix.h: Remove (unused) DEFAULT_ASSEMBLER_DIALECT.
+
+2003-09-26 Loren James Rittle <ljrittle@acm.org>
+
+ * config/i386/i386.h (ix86_return_in_memory): Revert my last patch.
+ * objc/objc-act.c (tm_p.h): Include.
+
+2003-09-26 Per Bothner <pbothner@apple.com>
+
+ * dbxout.c (dbxout_typedefs): Output typedefs in forward order.
+ No longer any need to reverse by recursion.
+
+2003-09-26 Roger Sayle <roger@eyesopen.com>
+ Richard Henderson <rth@redhat.com>
+
+ PR optimization/11741
+ * gcse.c (pre_insert_copy_insn): Tweak the logic for finding the
+ appropriate set to match that in hash_scan_insn. Fall back to
+ the original copy method, if we can't validate changing insn.
+ (pre_delete): Only delete instructions that have a single_set,
+ instead of aborting when we encounter an PARALLEL insn with more
+ then one SET.
+
+2003-09-26 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.md ("builtin_setjmp_setup"): Insn deleted.
+ ("builtin_longjmp"): Insn deleted.
+ ("save_stack_nonlocal"): Save literal pool base pointer behind
+ backchain and stack pointer.
+ ("restore_stack_nonlocal"): Restore literal pool base pointer.
+ * config/s390/s390.h (STACK_SAVEAREA_MODE): Double size of
+ the stack save area for the nonlocal goto case.
+
+2003-09-26 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR bootstrap/12358
+ * pa.c (output_bvb): Fix typo.
+
+2003-09-26 Richard Sandiford <rsandifo@redhat.com>
+
+ * expmed.c (store_bit_field): Don't search for an integer mode
+ unless we need the result.
+
+2003-09-26 Richard Sandiford <rsandifo@redhat.com>
+
+ * expr.c (emit_move_insn_1): If there is no move pattern for the
+ original mode, try using a pattern for the corresponding integer mode.
+
+2003-09-26 Richard Sandiford <rsandifo@redhat.com>
+
+ PR middle-end/9200
+ * combine.c (if_then_else_cond): Tighten mode check.
+
+2003-09-25 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cppcharset.c, cpphash.h: Rename 'struct strbuf' to
+ 'struct _cpp_strbuf'.
+
+ * config/i386/netbsd-elf.h, config/i386/netbsd64.h,
+ config/i386/netware.h, config/i386/nto.h, config/i386/openbsd.h,
+ config/i386/pentium.md, config/i386/pmmintrin.h, config/i386/ppro.md,
+ config/i386/ptx4-i.h, config/i386/rtemself.h, config/i386/sco5.h,
+ config/i386/sol2.h, config/i386/svr3gas.h, config/i386/sysv3.h,
+ config/i386/sysv4-cpp.h, config/i386/sysv4.h, config/i386/sysv5.h,
+ config/i386/unix.h, config/i386/uwin.h, config/i386/vsta.h,
+ config/i386/xm-cygwin.h, config/i386/xm-djgpp.h,
+ config/i386/xm-mingw32.h, config/i386/xmmintrin.h: Replace
+ "GNU CC", "GNU compiler", and "GNU C-compiler" with "GCC".
+ * config/i386/i386-aout.h, config/i386/i386-coff.h,
+ config/i386/i386-interix.h, config/i386/i386-interix3.h,
+ config/i386/i386-modes.def, config/i386/i386-protos.h,
+ config/i386/i386.c, config/i386/i386.h, config/i386/i386.md,
+ config/i386/i386elf.h, config/i386/k6.md, config/i386/kaos-i386.h,
+ config/i386/linux-aout.h, config/i386/linux.h, config/i386/linux64.h,
+ config/i386/lynx-ng.h, config/i386/lynx.h, config/i386/mingw32.h,
+ config/i386/mmintrin.h, config/i386/moss.h: GNU CC -> GCC.
+ "GNU compiler" -> GCC.
+ * config/i386/att.h, config/i386/beos-elf.h, config/i386/biarch64.h,
+ config/i386/bsd.h, config/i386/crtdll.h, config/i386/cygming.h,
+ config/i386/cygwin.h, config/i386/cygwin1.c, config/i386/cygwin2.c,
+ config/i386/darwin.h, config/i386/djgpp.h, config/i386/emmintrin.h,
+ config/i386/freebsd-aout.h, config/i386/freebsd.h,
+ config/i386/freebsd64.h, config/i386/gas.h: GNU CC -> GCC.
+
+2003-09-25 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * cgraph.c (dump_cgraph): Don't output newline before dump. Add in
+ "local" to the callgraph dump. Output "after inlining" earlier.
+ * cgraphunit.c: Fix dumpfile whitespace and commonize headers of the
+ callgraph dumps. Correct misspellings.
+ (cgraph_decide_inlining): Output number of insns before inlining.
+ Output the calling function into which a function is inlined.
+ (cgraph_decide_small_functions): Format dump file like always_inline.
+
+2003-09-25 Loren James Rittle <ljrittle@acm.org>
+
+ * config/i386/i386.h (ix86_return_in_memory): Add prototype.
+
+2003-09-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_emit_prologue): Simplify accesses to
+ FPR slots in the save area.
+ (s390_emit_epilogue): Likewise.
+
+2003-09-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * cgraph.h (cgraph_remove_edge): Declare.
+ * cgraph.c (cgraph_remove_edge): Make extern.
+ * cgraphunit.c (cgraph_finalize_function): Call cgraph_remove_edge
+ instead of cgraph_remove_call.
+
+2003-09-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * objc/objc-act.c (gen_declaration_1): Fix printf format.
+
+2003-09-25 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (all_cores): arm710t, arm720t and arm740t are all based on the
+ arm7tdmi core.
+
+2003-09-25 Ziemowit Laski <zlaski@apple.com>
+
+ * config/darwin-protos.h (objc_image_info_section):
+ New prototype.
+
+2003-09-25 Ziemowit Laski <zlaski@apple.com>
+
+ * Makefile.in (stub-objc.o): Depend on $(GGC_H).
+
+2003-09-25 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Get rid of more gratuitious 'x'es. Actually allow
+ tsc701 as a --with-cpu, --with-tune setting for sparc.
+
+2003-09-25 Ziemowit Laski <zlaski@apple.com>
+
+ * c-parse.in (objc_try_stmt): Do not specify a %type.
+
+2003-09-25 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: New 'widely ported system' clause for rtems.
+ Set thread file there, not in individual clauses.
+
+2003-09-25 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/6222
+ * config/mips/mips.c (mips_va_arg): Handle arguments that must be
+ passed on the stack.
+
+2003-09-25 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (widely ported systems section): Mostly alphabetize
+ by system. Comment the case where we can't.
+ * config.gcc (widely ported systems section): Reindent and clean up.
+
+ * config.gcc: Remove some unnecessary uses of 'x' in case statements.
+ Actually allow ep9312 as an arm --with-arch setting.
+
+ * config.gcc (*-hpux11): Disable fixproto.
+
+2003-09-24 Phil Edwards <phil@codesourcery.com>
+
+ PR pch/12112
+ * gcc/cppfiles.c (pch_open_file): Return based on combined
+ result of all files.
+ (validate_pch): Return validate flag for current file.
+
+2003-09-24 Roger Sayle <roger@eyesopen.com>
+
+ PR bootstrap/12358
+ * fold-const.c (tree_swap_operands_p): Only reorder operands when
+ one of the operands is constant.
+
+2003-09-24 Ziemowit Laski <zlaski@apple.com>
+
+ MERGE OF objc-improvements-branch into MAINLINE:
+ * Makefile.in (C_OBJS): Add in stub-objc.o.
+ (c-parse.y): Change sed demarcations to begin with '@@'.
+ (stub-objc.o): New rule.
+ * c-common.c (flag_nil_receivers, flag_objc_exceptions, flag_zero_link,
+ flag_replace_objc_classes): New flags.
+ * c-common.h (RID_AT_THROW, RID_AT_TRY, RID_AT_CATCH, RID_AT_FINALLY,
+ RID_AT_SYNCHRONIZED): New keywords.
+ (flag_nil_receivers, flag_objc_exceptions, flag_zero_link,
+ flag_replace_objc_classes): New flags.
+ (lookup_interface, is_class_name, objc_is_object_ptr, objc_check_decl,
+ objc_comptypes, objc_message_selector, lookup_objc_ivar,
+ get_current_scope, objc_mark_locals_volatile): New prototypes,
+ some moved from c-tree.h.
+ * c-decl.c (get_current_scope, objc_mark_locals_volatile): New functions.
+ (finish_decl): Adjust where objc_check_decl() gets called.
+ * c-lang.c (lookup_interface, is_class_name, objc_is_id, objc_check_decl,
+ objc_comptypes, objc_message_selector, lookup_objc_ivar): Remove stubs.
+ * c-opts.c (c_common_handle_option): Add handling for flag_nil_receivers,
+ flag_objc_exceptions, flag_replace_objc_classes and flag_zero_link.
+ * c-parse.in: Replace 'ifc' and 'end ifc' sed markers with '@@ifc' and
+ '@@end_ifc', respectively.
+ (AT_THROW, AT_TRY, AT_CATCH, AT_FINALLY, AT_SYNCHRONIZED): New %tokens.
+ (objc_try_stmt, superclass, class_ivars, objc_try_catch-stmt,
+ objc_finally_block): New rules.
+ (component_decl_list2): Clean up semantic action for @defs construct.
+ (component_decl, c99_block_start): Remove call to add_objc_decls().
+ (poplevel): Add call to objc_clear_super_receiver().
+ (stmt): Add rules for @throw, @try..@catch..@finally and @synchronized
+ constructs.
+ (classdef, methodprotolist): Clean up/simplify.
+ (methodprotolist2): Eliminate.
+ (methodproto): Call add_method() instead of add_class_method() and
+ add_instance_method().
+ (receiver): Add TYPENAME production.
+ (reswords): Add "throw", "try", "catch", "finally" and "synchronized".
+ (rid_to_yy): Add AT_THROW, AT_TRY, AT_CATCH, AT_FINALLY and
+ AT_SYNCHRONIZED.
+ * c-tree.h (lookup_interface, is_class_name, objc_is_id, objc_check_decl,
+ objc_comptypes, objc_message_selector)
+ * c-typeck.c (comptypes): In ObjC mode, call objc_comptypes() for
+ struct and pointer types.
+ (build_c_cast): Do not discard ObjC protocol qualifiers.
+ (convert_for_assignment): Cache result of comp_target_types() instead
+ of calling it more than once.
+ * c.opt (fnext-runtime): Update description string.
+ (fnil-receivers, fobjc-exceptions, freplace-objc-classes, fzero-link):
+ New ObjC/ObjC++-specific flags.
+ * function.h (GCC_FUNCTION_H): Header guard.
+ * gengtype-lex.l: Teach lexer about new @@... sed demarcations.
+ * stub-objc.c: New file, to be used to satisfy references to ObjC
+ functions by the C and C++ front-ends.
+ * config/darwin.c (_OBJC_IMAGE_INFO): New global metadata.
+ * config/darwin.h (FUNCTION): Add in_objc_image_info.
+ (SECTION_FUNCTION): Add objc_image_info_section.
+ * doc/invoke.texi: Link to GCC web site for Objective-C information.
+ (-fconstant-string-class): Update documentation.
+ (-fno-nil-receivers, -fobjc-exceptions, -freplace-objc-classes,
+ -fzero-link): New documentation.
+ * objc/Make-lang.in (objc-parse.y): Change sed demarcations to begin
+ with '@@'.
+ * objc/lang-specs.h (@objective-c-header): Fix -E spec.
+ * objc/objc/objc-act.c: Replace TYPE_NAME with OBJC_TYPE_NAME
+ throughout; provide casts for return values from memory allocation
+ functions (xmalloc, alloca, ggc_alloc, etc.).
+ (OBJC_VOID_AT_END): New macro.
+ (rtl.h): Do not #include any more.
+ (STRING_OBJECT_GLOBAL_NAME): Replaced with STRING_OBJECT_GLOBAL_FORMAT.
+ (TAG_MSGSEND_STRET, TAG_MSGSENDSUPER_STRET, TAG_MSGSEND_NONNIL,
+ TAG_MSGSEND_NONNIL_STRET, TAG_EXCEPTIONEXTRACT, TAG_EXCEPTIONTRYENTER,
+ TAG_EXCEPTIONTRYEXIT, TAG_EXCEPTIONMATCH, TAG_EXCEPTIONTHROW,
+ TAG_SYNCENTER, TAG_SYNCEXIT): New NeXT runtime entry points.
+ (struct val_stack, catch_count_stack, exc_binding_stack, val_stack_push,
+ val_stack_pop): New.
+ (objc_check_decl): Fix precondition for error message, along with
+ the message itself.
+ (lookup_and_install_protocols): Remove nonexistent protocols from
+ protocol list instead of returning error_mark_node.
+ (create_builtin_decl): Use DECL_ARTIFICIAL only for VAR_DECLs.
+ (setup_string_decl): Generalize to use STRING_OBJECT_GLOBAL_FORMAT.
+ (synth_module_prologue): General clean-up; construct NeXT-specific
+ runtime API prototypes if needed.
+ (build_string_class_template): Remove.
+ (check_string_class_template, string_layout_checked): New.
+ (build_objc_string_object): Generalize to work with
+ -fconstant-string-class.
+ (build_objc_symtab_template): Fix layout for the NeXT runtime.
+ (build_metadata_decl): New.
+ (forward_declare_categories): Call build_metadata_decl() instead of
+ create_builtin_decl() et al.
+ (build_module_descriptor): Use OBJC_VOID_AT_END instead of
+ void_list_node_1.
+ (build_selector_reference_decl, build_class_reference_decl,
+ build_objc_string_decl): Do not set TREE_READONLY.
+ (get_proto_encoding): Do not call hack_method_prototype().
+ (get_class_reference): Add failure mode for invalid class names;
+ support -fzero-link; defer if in an ObjC++ template declaration.
+ (objc_declare_alias, objc_declare_class): Fix up duplicate name
+ lookup; check for global scope if in ObjC++.
+ (is_class_name): Generalize to work with various tree nodes (TYPE_DECL,
+ RECORD_TYPE, IDENTIFIER_NODE, etc.)
+ (objc_is_id): Removed.
+ (objc_is_object_ptr): New function.
+ (get_class_ivars_from_name): New function, used for @defs construct.
+ (get_class_ivars): Add option to return raw ivars; create a
+ ClASS_OWN_IVARS list for each class as needed.
+ (objc_enter_block, objc_exit_block, objc_declare_variable,
+ objc_build_throw_stmt, val_stack_push, val_stack_pop,
+ objc_build_try_enter_fragment, objc_build_extract_expr,
+ objc_build_try_exit_fragment, objc_build_extract_fragment,
+ objc_build_try_prologue, objc_build_try_epilogue,
+ objc_build_catch_stmt, objc_build_catch_epilogue,
+ objc_build_finally_prologue, objc_build_finally_epilogue,
+ objc_build_try_catch_finally_stmt, objc_build_synchronized_prologue,
+ objc_build_synchronized_epilogue, build_objc_exception_stuff):
+ New functions.
+ (_JBLEN): _setjmp jmpbuf size (needs to be made a target hook in
+ the future).
+ (build_private_template): Fix up calls to get_class_ivars().
+ (offset_is_register, forwarding_offset): Remove.
+ (objc_method_parm_type, objc_encoded_type_size): New functions.
+ (encode_method_prototype): Simplify to no longer depend on
+ back-end information.
+ (build_tmp_function_decl_xxx, build_tmp_function_decl,
+ hack_method_prototype): Removed.
+ (generate_protocol_references): Remove calls to
+ build_tmp_function_decl().
+ (generate_protocols): Adjust calls to encode_method_prototype().
+ (build_class_template): Generate sel_id' and 'gc_object_type' fields
+ for the NeXT runtime.
+ (synth_forward_declarations): Call build_metadata_decl().
+ (check_ivars): Check that the number of ivars matches also.
+ (build_super_template): Modify super_type directly; disable debugging
+ output while generating decl.
+ (build_ivar_list_initializer): Skip list elements that are not
+ FIELD_DECLs.
+ (ivar_list_length): New function.
+ (generate_ivar_lists): Call ivar_list_length() instead of list_length()
+ and encode_method_prototype() instead of encode_method_def().
+ (build_shared_structure_initializer): Generate 'sel_id' field for
+ the NeXT runtime.
+ (generate_category): Do not set TREE_USED.
+ (build_keyword_selector): Ditto; transform into a function argument
+ chain.
+ (get_arg_type_list): If there are no user-specified arguments, use
+ '...'; use OBJC_VOID_AT_END.
+ (check_duplicates): Add a parameter indicating whether methods or
+ selectors are being checked.
+ (receiver_is_class_object): Add parameters indicating whether
+ receiver is 'self' or 'super'; robustify.
+ (build_message_expr): Defer call to finish_message_expr() if
+ inside an ObjC++ template.
+ (lookup_method_in_hash_lists): New function.
+ (finish_message_expr): Complete rewrite/fix.
+ (build_objc_method_call): Ditto; factor out commonalities between
+ the GNU and NeXT runtimes; acccommodate ..._stret and ...NonNil
+ messenger variants on the NeXT.
+ (lookup_instance_method_static, lookup_class_method_static):
+ Fold into a single lookup_method_static() function with an
+ additional parameter.
+ (add_class_method, add_instance_method): Fold into a single
+ add_method() function with an additional parameter.
+ (add_category): Make duplicate categories a hard error in ObjC++.
+ (add_instance_variable): Properly handle unnamed ivars, arrays of
+ zero or no size and bitfields. In ObjC++, check for nontrivial
+ C++ class instances.
+ (is_public): Allow C functions to access non-@public ivars, with
+ a warning.
+ (start_class): Move common initializations to
+ synth_module_prologue(); check for global scope if in ObjC++.
+ (continue_class): Fix calls to finish_struct().
+ (objc_declare_protocols, start_protocol): Check for global scope
+ if in ObjC++.
+ (encode_pointer): Encode 'BOOL *' specially on the NeXT.
+ (encode_aggregate_within): Rewrite to properly distinguish
+ struct tags from typedefs in both ObjC and ObjC++.
+ (encode_bitfield, encode_complete_bitfield): Remove.
+ (encode_next_bitfield, encode_gnu_bitfield): New functions.
+ (encode_field_decl): Call encode_next_bitfield() or
+ encode_gnu_bitfield() as needed.
+ (synth_self_and_ucmd_args): New function.
+ (start_method_def): Use it.
+ (objc_types_are_equivalent): New function.
+ (comp_proto_with_proto): Use it instead of comptypes(), since
+ we need symmetry.
+ (really_start_method): Use lookup_method_static() instead of
+ lookup_class_method_static() and lookup_instance_method_static();
+ Emit 'extern "C"' if in ObjC++ mode.
+ (add_objc_decls): Removed.
+ (UOBJC_SUPER_scope): New variable.
+ (get_super_receiver): Move construction of 'super' from
+ add_objc_decls(); remove dependency on struct objc_class.
+ (encode_method_def): Removed; encode_method_prototype() is
+ used instead.
+ (objc_clear_super_receiver): New function.
+ (objc_expand_function_end): Do not do anything for ordinary
+ C functions.
+ (finish_method_def): Mark ObjC methods as un-inlinable.
+ (gen_declaration_1): Emit widths of bitfields.
+ (finish_objc): Call generate_objc_image_info() if needed;
+ use check_duplicates() when checking for selector duplicates.
+ (generate_objc_image_info): New function.
+ * objc/objc-act.h (add_instance_method, add_class_method,
+ get_class_ivars): Remove prototypes.
+ (objc_build_throw_stmt, objc_build_try_catch_finally_stmt,
+ objc_build_synchronized_prologue, objc_build_synchronized_epilogue,
+ objc_build_catch_stmt, objc_build_catch_epilogue,
+ objc_build_finally_prologue, objc_build_finally_epilogue,
+ add_method, get_class_ivars_from_name): New prototypes.
+ (CLASS_BINFO_ELTS, PROTOCOL_BINFO_ELTS): New.
+ (TYPE_PROTOCOL_LIST): Robustify to distinguish from
+ TRANSLATION_UNIT_DECLs.
+ (OBJC_TYPE_NAME): New.
+ (objc_tree_code): Ensure that either <c-tree.h> or <cp/cp-tree.h>
+ got included.
+ (IS_SUPER): Robustify.
+ (umsg_stret_decl, umsg_super_stret_decl, umsg_nonnil_decl,
+ umsg_nonnil_stret_decl, objc_storage_class, objc_exception_extract_decl,
+ objc_exception_try_enter_decl, objc_exception_try_exit_decl,
+ objc_exception_match_decl, objc_exception_throw_decl,
+ objc_sync_enter_decl, objc_sync_exit_decl, objc_exception_data_template,
+ objc_setjmp_decl, objc_stack_exception_data, objc_caught_exception,
+ objc_rethrow_exception, objc_eval_once, objc_exception_block_stack,
+ objc_catch_type): New ObjC/ObjC++ roots.
+ * objc/objc-tree.def (MESSAGE_SEND_EXPR, CLASS_REFERENCE_EXPR): New
+ ObjC/ObjC++ tree node codes.
+
+2003-09-24 Alexandre Oliva <aoliva@redhat.com>
+
+ * cpplib.c (do_pragma): Reintroduce cb_line_change call in the
+ code path that calls a handler.
+
+2003-09-24 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (c4x-*, tic4x-*, d30v-*, mmix-knuth-mmixware):
+ Disable fixproto.
+
+ * config.gcc: Clean up and reindent $with_cpu=yes|no clause and
+ the section giving $with_cpu defaults by target.
+
+ * config.gcc (arm-*-coff*, armel-*-coff*, arm*-*-ecos-elf,
+ arm*-*-elf, ep9312-*-elf, arm*-wince-pe*, arm*-*-pe*, arm*-*-pe*,
+ rs6000-ibm-aix4.[3456789]*, powerpc-ibm-aix4.[3456789]*,
+ rs6000-ibm-aix5.1.*, powerpc-ibm-aix5.1.*,
+ rs6000-ibm-aix[56789].*, powerpc-ibm-aix[56789].*,
+ i[34567]86-pc-msdosdjgpp*): Disable fixproto.
+
+2003-09-24 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (movti_power): Collapse case 1 and 2
+ together. Protect load string instruction with TARGET_STRING.
+ (movti_string): Collapse case 1 and 2 together.
+
+2003-09-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-common.c (c_common_type_for_mode): Check for VOIDmode.
+
+2003-09-24 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.h (ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Wrap in
+ do...while(0)
+
+2003-09-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Move use_fixproto=no from generic vxworks clause to
+ specific one.
+
+ * config.gcc (powerpc-*-gnu-gnualtivec*): Disable fixproto
+ (accidentally missed in last pass).
+
+2003-09-23 Andrew Pinski <apinski@apple.com>
+
+ PR bootstrap/12383
+ * configure: Regenerate.
+
+2003-09-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (x86_64-*-freebsd*): Disable fixproto (accidentally
+ missed in last pass).
+
+2003-09-23 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mn10300/mn10300.md (andsi3): Fix cut&pasto in 0xfffffffe
+ constant.
+
+2003-09-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Move vax-*-vms* unsupported notice up with the rest.
+
+ * config.gcc (alpha64*-dec-*vms*, alpha*-dec-*vms*,
+ powerpc-*-eabisim*, powerpc-*-eabi*, powerpcle-*-eabisim*,
+ powerpcle-*-eabi*): Disable fixproto.
+
+ * config.gcc: Move use_fixproto=no from generic FreeBSD clause to
+ specific FreeBSD clauses.
+ * config.gcc: Move use_fixproto=no from generic NetBSD clause to
+ specific NetBSD clauses.
+ * config.gcc: Move use_fixproto=no from generic OpenBSD clause
+ to specific OpenBSD clauses.
+
+2003-09-23 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (hppa_expand_prologue): Do pic register save in frame marker
+ without adding a frame note.
+ * pa.md (allocate_stack): Save pic register in new frame marker when
+ generating pic code.
+
+2003-09-23 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * cgraphunit.c (cgraph_expand_all_functions): Renamed from
+ cgraph_expand_functions.
+
+2003-09-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (gnucompare*): Merge into ...
+ (slowcompare*): ... here.
+ (fastcompare*): New targets.
+ * aclocal.m4 (gcc_AC_PROG_CMP_IGNORE_INITIAL): Add checks for
+ other "fast" cmp programs.
+ * configure: Regenerate.
+
+2003-09-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * targhooks.c: Include output.h.
+ * Makefile.in (targhooks.o): Add output.h to dependency list.
+
+2003-09-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config.host: Removed superfluous newline.
+
+2003-09-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Use ${target}, not $machine.
+ * configure.in: Don't set $machine.
+ * configure: Regenerate.
+
+2003-09-23 Geoffrey Keating <geoffk@apple.com>
+
+ * config/t-darwin (crt2.o): Add stmp-int-hdrs to dependencies.
+
+ * config/rs6000/rs6000.c (function_arg_pass_by_reference): Don't
+ pass zero-size arrays by reference.
+ (rs6000_va_arg): Likewise.
+
+2003-09-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Set use_fixproto=no in each specific *-gnu*
+ configuration, rather than the generic one.
+
+2003-09-23 Richard Henderson <rth@redhat.com>
+
+ * tree-inline.c (remap_save_expr): Map new save_expr to identity
+ rather than to error_mark_node.
+
+2003-09-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (HAVE_GAS_SHF_MERGE): Always define to test result.
+ Update description.
+ * configure: Regenerate.
+ * config.in: Likewise.
+ * dwarf2out.c (DEBUG_STR_SECTION_FLAGS): Test for
+ HAVE_GAS_SHF_MERGE value.
+ * varasm.c (mergeable_string_section): Likewise.
+ (mergeable_constant_section): Likewise.
+
+2003-09-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * except.h (MUST_USE_SJLJ_EXCEPTIONS): Test for DWARF2_UNWIND_INFO
+ value.
+
+2003-09-23 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * target.h (struct gcc_target): New member external_libcall.
+ * target-def.h (TARGET_ASM_EXTERNAL_LIBCALL): Provide default.
+ (TARGET_ASM_OUT): Use it.
+ * doc/tm.texi (TARGET_ASM_EXTERNAL_LIBCALL): Document.
+ * targhooks.c: Convert to ISO C 90.
+ (default_external_libcall): New function.
+ * targhooks.h (default_external_libcall): Declare.
+ * varasm.c (assemble_external_libcall): Use
+ targetm.asm_out.external_libcall instead of
+ ASM_OUTPUT_EXTERNAL_LIBCALL.
+ * config/mips/mips-protos.h [TARGET_IRIX5 || TARGET_IRIX 6]
+ (mips_output_external_libcall): Declare.
+ * config/mips/mips.c (mips_output_external_libcall): Change
+ definition guard.
+ Change to match TARGET_ASM_EXTERNAL_LIBCALL.
+ Only operate for O32 ABI.
+ * config/mips/iris5.h (TARGET_ASM_EXTERNAL_LIBCALL): Define
+ instead of ASM_OUTPUT_EXTERNAL_LIBCALL.
+ * config/mips/iris6.h (ASM_OUTPUT_EXTERNAL_LIBCALL): Don't undef,
+ superceded by TARGET_ASM_EXTERNAL_LIBCALL.
+
+2003-09-22 Nathnael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Do per-target disabling of fixproto here in clauses,
+ not in t- fragments.
+ * configure.in: Adjust to set STMP_FIXPROTO correctly.
+ * configure: Regenerate.
+ * config/arm/t-semi, config/cris/t-cris, config/i386/t-beos,
+ config/i386/t-cygming, config/i386/t-nto, config/ia64/t-hpux,
+ t-freebsd, t-linux, t-netbsd, t-openbsd, t-rtems, t-vxworks,
+ xtensa/t-xtensa: Remove setting of STMP_FIXPROTO.
+ * config/i370/t-oe, config/i386/t-netware, config/pa/t-bsd,
+ t-interix, t-linux-aout: Delete files consisting only of
+ setting of STMP_FIXPROTO.
+
+ * config.host: Allow unknown hosts (not targets). Allow
+ ns32k-*-netbsdelf* as a host (not a target). Remove redundant
+ empty clauses. Remove useless obsolete-configuration clause.
+ Prune unsupported configuration list. Collapse identical
+ clauses for closely related systems. Rewrite comment for
+ unsupported hosts list. Reorganize a little.
+
+2003-09-22 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (c_common_signed_or_unsigned_type): Examine mode,
+ not precision.
+
+2003-09-22 David Edelsohn <edelsohn@gnu.org>
+ Hartmut Penner <hpenner@de.ibm.com>
+ Segher Boessenkool <boessen@de.ibm.com>
+
+ * config/rs6000/rs6000.c (altivec_in_gprs_p): Rename to ...
+ (gpr_or_gpr_p): Test INT_REGNO_P and convert to boolean.
+ (rs6000_split_altivec_in_gprs): Rename to ...
+ (rs6000_split_multireg_move): Add support for update addressing.
+ * config/rs6000/rs6000-protos.h: Same.
+ * config/rs6000/altivec.md: Same.
+ * config/rs6000/rs6000.md (movdi_internal32): Use new splitter for
+ multiple GPRs.
+ (movti): Remove TARGET_STRING || TARGET_POWERPC64 final condition.
+ (movti_power): Use new splitter for multiple GPRs.
+ (movti_string): Same.
+ (movti_ppc64): Same.
+
+2003-09-22 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa-protos.h: Convert to ISO C90.
+ * config/xtensa/xtensa.c: Convert to ISO C90. Minor formatting fixes.
+
+2003-09-22 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mn10300/mn10300.md: Revert 2003-09-17's patch.
+ (andsi3): Set attr cc to set_zn when using shifts or adds.
+
+2003-09-22 Bernardo Innocenti <bernie@develer.com>
+
+ * doc/contrib.texi: Add Peter Barada, Paul Dale and myself.
+
+2003-09-22 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.h (MASK_RTD, TARGET_RTD, RETURN_POPS_ARGS):
+ Resurrect -mrtd option.
+
+2003-09-21 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/12281
+ * config/darwin.c (machopic_validate_stub_or_non_lazy_ptr): Call
+ mark_referenced instead of setting TREE_SYMBOL_REFERENCED.
+
+2003-09-22 Olivier Hainque <hainque@act-europe.fr>
+
+ PR target/9786
+ * reg-stack.c (convert_regs_1): Purge possible dead eh edges
+ after potential deletion of trapping insn. Avoids later ICE
+ from call to fixup_abnormal_edges.
+ (convert_regs_2): Stack the current block successors before
+ processing this block, that is, before the potential deletion of
+ dead edges by convert_regs_1, because these edges have been used
+ to initialize the predecessors count.
+
+2003-09-22 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * real.c: Fix several nits in the head comment.
+
+2003-09-21 Richard Henderson <rth@redhat.com>
+
+ * tree.h c-aux-info.c, c-decl.c, c-parse.in, coverage.c, dbxout.c,
+ diagnostic.c, dwarf2out.c, dwarfout.c, function.c, integrate.c,
+ print-tree.c, stmt.c, toplev.c, tree-dump.c, tree-inline.c,
+ tree-optimize.c, tree.c, tree.def, xcoffout.c, config/alpha/alpha.c,
+ config/mips/mips.c, doc/c-tree.texi, objc/objc-act.c: Revert.
+
+2003-09-21 Richard Henderson <rth@redhat.com>
+
+ * tree.h (TREE_LOCUS): Rename from DECL_SOURCE_LOCATION; make const.
+ (TREE_FILENAME, TREE_LINENO): Likewise.
+ (set_tree_locus, copy_tree_locus, set_tree_file_line): New.
+ (TREE_LOCUS_SET_P): New.
+ * c-aux-info.c, c-decl.c, c-parse.in, coverage.c, dbxout.c,
+ diagnostic.c, dwarf2out.c, dwarfout.c, function.c, integrate.c,
+ print-tree.c, stmt.c, toplev.c, tree-dump.c, tree-inline.c,
+ tree-optimize.c, tree.c, tree.def, xcoffout.c, config/alpha/alpha.c,
+ config/mips/mips.c, doc/c-tree.texi, objc/objc-act.c: Update to match.
+
+2003-09-21 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/vax/vax-protos.h: Convert to ISO C90.
+ * config/vax/vax.c: Convert to ISO C90.
+
+2003-09-21 Graham Stott <grahams@btinternet.com>
+
+ PR target/12353
+ * config/i386/i386.md(ffs_no_cmove): Fix operand 2 constraint.
+
+2003-09-21 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/12301
+ * reorg.c (stop_search_p): Return 1 for insns that can
+ throw internally.
+
+2003-09-20 Richard Henderson <rth@redhat.com>
+
+ * c-format.c (gcc_diag_char_table): Add %J.
+ (gcc_cdiag_char_table, gcc_cxxdiag_char_table): Likewise.
+ (check_format_types): Fix wanted_type name lookup.
+ (init_dynamic_diag_info): Setup %J.
+ * diagnostic.c (text_specifies_location): Implement %J.
+ * c-common.c, c-decl.c, c-objc-common.c, c-pragma.c, calls.c,
+ dwarfout.c, expr.c, function.c, stmt.c, stor-layout.c, toplev.c,
+ tree-inline.c, tree-optimize.c, varasm.c, config/arm/pe.c,
+ config/i386/winnt.c, config/ia64/ia64.c, config/mcore/mcore.c,
+ config/v850/v850.c, objc/objc-act.c: Use %J in diagnostics.
+
+ * tree-inline.c: Include intl.h
+ (inline_forbidden_p_1): Fix i18n of inline_forbidden_reason.
+ * Makefile.in (tree-inline.o): Update.
+
+2003-09-20 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.c (ix86_expand_carry_flag_compare): Fix
+ transformation of a>=0 into (unsigned)a<0x80000000.
+
+2003-09-20 Andrew Pinski <apinski@apple.com>
+
+ * config/darwin.c (machopic_select_rtx_section): Fix check for PIC code.
+
+2003-09-20 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in: Don't set (unused) DLLTOOL.
+
+ * config/arm/t-linux, config/arm/t-netbsd, config/arm-t-semi:
+ Remove obsolete references to ENQUIRE.
+
+2003-09-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Remove --with-elf, which doesn't work.
+ * configure: Regenerate.
+ * config.gcc: Remove references to $elf, which does nothing.
+
+ * config/i386/xm-vsta.h: Remove xm-file believed useless.
+ * config.build (i386-vsta): Remove reference to it.
+ * config.host (i386-vsta): Remove reference to it.
+
+2003-09-19 Phil Edwards <phil@codesourcery.com>
+
+ * doc/install.texi: Document the multiple testsuite options.
+
+2003-09-19 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/install.texi (Specific): Add the specific versions of GCC
+ where support for FreeBSD 1, HP-UX version 9 and older, and AIX
+ version 3 and older was discontinued.
+
+2003-09-19 Joel Sherrill <joel@oarcorp.com>
+
+ * config/m68k/t-m68kbare, config/m68k/t-rtems: Change 68681 to
+ 68881.
+
+2003-09-19 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.h (TARGET_CPU_CPP_PREDEFINES): Add predefines
+ for -m68030, -m68020-60 and -m68020-40.
+ * config/m68k/m68k.h (TARGET_68030): New target flag.
+ * config/m68k/m68k.h (MASK_RTD, TARGET_RTD, MASK_REGPARM,
+ TARGET_REGPARM): Remove.
+ * config/m68k/m68k.h: Regroup and renumber target flags.
+ * config/m68k/m68k.h (TARGET_SWITCHES): Fix some tabulations.
+ * config/m68k/m68k.h (RETURN_POPS_ARGS): Always evaluate to 0.
+ * config/m68k/m68k.h (FUNCTION_ARG): Likewise.
+ * config/m68k/m68k.h (FUNCTION_ARG_PARTIAL_NREGS): Likewise.
+ * config/m68k/m68k-none.h: Use MASK_xxx values in M68K_CPU_xxx macros.
+
+2003-09-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * config/m68k/t-rtems (m68k-*-rtems*): New.
+ * config.gcc: Use config/m68k/t-rtems.
+
+2003-09-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ * config/mips/t-rtems: New.
+ * config.gcc (mips*-*-rtems*): Use config/mips/t-rtems.
+
+2003-09-19 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * cgraph.c: Fix typo in debugging output.
+
+2003-09-19 T. Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/12166
+ * config/sparc/sol2-c1.asm (start): Set __Argv if GCRT1.
+
+2003-09-18 Mike Stump <mrs@apple.com>
+
+ * c-ppoutput.c (print): Use fileline typedef for field 'line'.
+ (print_line, maybe_print_line, cb_define, cb_undef, cb_include,
+ cb_ident, cb_def_pragma): Use fileline typedef.
+ * cpphash.h (struct cpp_reader): Likewise for field out.first_line.
+
+2003-09-18 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/winnt.c (gen_stdcall_suffix): Quit summation of
+ total parm size if a parm has incomplete type.
+ (gen_fastcall_suffix): Likewise.
+
+2003-09-18 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * except.c (output_function_exception_table): Adjust last change
+ to handle TYPE of INTEGER_CST.
+
+2003-09-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR target/11184
+ * builtins.c (expand_builtin_apply): Use convert_memory_address
+ before returning the value.
+
+ * alias.c (find_base_value): Simplify use of
+ convert_memory_address.
+ (find_base_term): Likewise.
+ * builtins.c (expand_builtin_stejmp_setup): Likewise.
+ (expand_builtin_longjmp): Likewise.
+ (expand_builtin_prefetch): Likewise.
+ (get_memory_rtx): Likewise.
+ (expand_builtin_return): Likewise.
+ (expand_builtin_memcpy): Likewise.
+ (expand_builtin_strncpy): Likewise.
+ (expand_builtin_memset): Likewise.
+ (expand_builtin_va_arg): Likewise.
+ (expand_builtin_va_copy): Likewise.
+ (expand_builtin_alloca): Likewise.
+ * calls.c (expand_call): Likewise.
+ * except.c (expand_builtin_extract_return_addr): Likewise.
+ (expand_builtin_eh_return): Likewise.
+ * explow.c (convert_memory_address): Define even when
+ POINTER_EXTEND_UNSIGNED is not defined. Do nothing if the address
+ is already in the right mode.
+ * explow.c (memory_address): Simplify use of convert_memory_address.
+ (probe_stack_range): Likewise.
+ * expmed.c (make_tree): Likewise.
+ * expr.c (emit_block_move_in_libcall): Likewise.
+ (expand_assignment): Likewise.
+ (expand_expr): Likewise.
+ * function.c (assign_parms): Likewise.
+ (expand_function_end): Likewise.
+ * integrate.c (copy_rtx_and_substitute): Likewise.
+ * stmt.c (expand_computed_goto): Likewise.
+
+2003-09-18 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_unary_operation): Only transform
+ (not (eq X Y)) into (ne X Y) when mode is BImode or STORE_FLAG_VALUE
+ is -1. RTL "not" is a bit-wise not, "~", not a logical not "!".
+
+2003-09-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR target/11674
+ * config/i386/i386.c (x86_emit_floatuns): Also handle SImode operand.
+
+2003-09-18 Roger Sayle <roger@eyesopen.com>
+
+ * tree.def (FFS_EXPR, CLZ_EXPR, CTZ_EXPR, POPCOUNT_EXPR,
+ PARITY_EXPR): Delete unused tree codes.
+ * c-common.c (c_common_truthvalue_conversion): Delete references
+ to FFS_EXPR and POPCOUNT_EXPR.
+ * c-pretty-print.c (pp_c_postfix_expression): Remove FFS_EXPR.
+ (pp_c_expression): Likewise.
+ * expr.c (expand_expr): Delete RTL expansion of FFS_EXPR, CLZ_EXPR,
+ CTZ_EXPR, POPCOUNT_EXPR and PARITY_EXPR.
+ * fold-const.c (tree_expr_nonnegative_p): Remove FFS_EXPR, CLZ_EXPR,
+ CTZ_EXPR, POPCOUNT_EXPR and PARITY_EXPR. Add support for calls to
+ BUILT_IN_FFS, BUILT_IN_PARITY and BUILT_IN_POPCOUNT and their long
+ and long long variants.
+
+2003-09-18 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.h (pp_type_specifier_seq): Fix thinko.
+ * c-pretty-print.c: Fix formatting.
+ (pp_c_integer_constant): Append type annotation to literals. Tidy.
+ (pp_c_type_specifier): Tidy.
+ (pp_c_compound_literal): New function.
+ (pp_c_initializer): Simplify..
+ (pp_c_initializer_list): Likewise.
+ (pp_c_brace_enclosed_initializer_list): New function.
+ (pp_c_postfix_expression): Simplify.
+
+2003-09-17 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mn10300/mn10300.md (andsi3, iorsi3, xorsi3,
+ one_complsi2, bit-clear, bit-set, iorqi3): Make them set_zn.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * tree-optimize.c (tree_rest_of_compilation): Save and restore
+ input_location.
+
+2003-09-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/rs6000/sysv4.h (LIB_LINUX_SPEC): Give -lpthread before -lc.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * cfg.c (dump_flow_info): Skip register dump if reg_n_info null.
+
+2003-09-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (gcc_cv_ld_hidden): Don't test gnu_ld_flag.
+ * configure: Regenerate.
+
+2003-09-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR debug/12066
+ * dbxout.c (dbxout_init): Use a langhook to find builtin types.
+ * langhooks-def.h (lhd_return_null_tree_v): New function.
+ (LANG_HOOKS_BUILTIN_TYPE_DECLS): New macro.
+ (LANG_HOOKS_DECLS): Add it to the intializer.
+ * langhooks.c (lhd_return_null_tree_v): New function.
+ * langhooks.h (lang_hooks_for_decls): Add builtin_type_decls.
+
+2003-09-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in: Quote gcc_config_arguments for configargs.h.
+ * configure: Regenerated.
+ * gccbug.in: Don't shell-expand gcc_config_arguments.
+
+2003-09-17 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/11357
+ * c-pretty-print.c (pp_c_floating_constant): Append
+ type-annotation to floating constants.
+
+2003-09-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/iris5.h (TARGET_OS_CPP_BUILTINS): Define _LONGLONG.
+ Define _ABIO32.
+ Use it for _MIPS_SIM.
+ * config/mips/iris6-o32.h (TARGET_OS_CPP_BUILTINS): Removed.
+
+ * config/mips/iris6-o32-as.h (SUBTARGET_ASM_OPTIMIZING_SPEC):
+ Moved ...
+ * config/mips/iris5.h (SUBTARGET_ASM_OPTIMIZING_SPEC): ... here,
+ updating comment.
+ Fixes PR target/10190.
+
+2003-09-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/rs6000/sysv4.h (LIB_LINUX_SPEC): Make -pthread apply
+ to shared libraries.
+
+2003-09-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11646
+ * cfgrtl.c (purge_dead_edges) [JUMP_INSN]: Rematerialize the
+ EDGE_ABNORMAL flag for EH edges.
+ * toplev.c (rest_of_handle_cse): Delete unreachable blocks
+ if dead edges were purged.
+
+2003-09-16 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.h (TARGET_CPU_CPP_BUILTINS): Add target predefines.
+ * config/m68k/m68k-none.h (CPP_CPU_DEFAULT_SPEC): Kill all definitions.
+ * config/m68k/m68k-none.h (CPP_FPU_SPEC): Remove.
+ * config/m68k/m68k-none.h (CPP_SPEC): Likewise.
+
+2003-09-16 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * cfgcleanup.c (label_is_jump_target_p): Correct use of table
+ returned by tablejump_p.
+
+2003-09-16 Joel Brobecker <brobecker@gnat.com>
+
+ * dwarf2asm.c (dw2_asm_output_nstring): Add comment.
+
+2003-09-16 Roger Sayle <roger@eyesopen.com>
+
+ PR bootstrap/12269
+ * simplify-rtx.c (simplify_gen_relational): Allow the cmp_mode
+ argument to be VOIDmode, taking the mode of the comparison from
+ the operands. Only call simplify_relational_operation if we
+ know the mode of the comparison. Honor FLOAT_STORE_FLAG_VALUE
+ if comparison has a floating point result. Ensure that the
+ result is always of the specified mode.
+ (simplify_replace_rtx): Simplify call to simplify_gen_relational.
+ (simplify_unary_operation): Ensure the correct mode and cmp_mode
+ are always passed to simplify_gen_relational. Simplify NOT of
+ comparison operator in any mode, not just BImode.
+ (simplify_ternary_operation): Correct tests on the return value
+ of simplify_relational_operation to use const_true_rtx, not
+ const1_rtx. Abort if it ever returns a non-constant result.
+
+ * cfgloopanal.c (count_strange_loop_iterations): Use the function
+ simplify_relational_operation, not simplify_gen_relational, if
+ we're only interested in constant comparisons and will ignore
+ non-constant results.
+
+2003-09-16 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (tree_swap_operands_p): New function to determine
+ the prefered ordering of operands.
+ (fold): Numerous clean-ups. Use tree_swap_operands_p when swapping
+ operands to commutative, comparison or ternary operators. Replace
+ uses of TREE_SET_CODE with recursive call to fold. Remove duplicate
+ transformation of A ? B : C into !A ? C : B.
+
+2003-09-16 Jakub Jelinek <jakub@redhat.com>
+
+ * config/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/alpha/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/arm/linux-elf.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/rs6000/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/rs6000/linux64.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/sh/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/sparc/linux.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+ * config/sparc/linux64.h (LINK_GCC_C_SEQUENCE_SPEC): Define.
+
+2003-09-16 Jason Merrill <jason@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * c-common.c (handle_warn_unused_result_attribute): New function.
+ (c_common_attribute_table): Add warn_unused_result.
+ (c_expand_expr): Issue warning when result of inlined function
+ with warn_unused_result attribute is ignored.
+ * calls.c (expand_call): Issue warning when result of function
+ with warn_unused_result attribute is ignored.
+ * c-common.h (STMT_EXPR_WARN_UNUSED_RESULT): Define.
+ * expr.c (expr_wfl_stack): Define.
+ (expand_expr) <case EXPR_WITH_FILE_LOCATION>: If ignore,
+ pass const0_rtx as target. Chain locations into expr_wfl_stack.
+ * tree-inline.c (expand_call_inline): Set STMT_EXPR_WARN_UNUSED_RESULT
+ bit if inlined function has warn_unused_result attribute.
+ * input.h (expr_wfl_stack): Declare.
+ * doc/extend.texi: Document warn_unused_result attribute.
+
+2003-09-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * cpplib.c (do_pragma): Remove unnecessary cb_line_change.
+
+2003-09-15 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (xtensa_multibss_section_type_flags): Add
+ ATTRIBUTE_UNUSED.
+ (call_insn_operand): For PIC, don't allow a direct call to a
+ function in a different section than the current one.
+
+2003-09-16 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * doc/invoke.texi (Warning Options): Add missing hyphen before
+ "Wimport". Change "-Wno-endif-labels" to "-Wendif-labels".
+ Move "-Wold-style-definition" to the C-only section.
+ Fix the ordering of the warning options.
+
+2003-09-15 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+ Jeff Law <law@redhat.com>
+
+ * gcse.c (remove_reachable_equiv_notes): New.
+ replace_store_insn): Call it. Update antic list.
+ (store_killed_in_insn): Take REG_EQUAL notes into account.
+ (build_store_vectors, delete_store): Add parameter to
+ replace_store_insn call.
+
+2003-09-15 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.h (LEGITIMATE_PIC_OPERAND_P): Use
+ SYMBOL_REF_LOCAL_P.
+
+2003-09-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * expr.h (DEFAULT_FUNCTION_ARG_PADDING): New.
+ (FUNCTION_ARG_PADDING): Use DEFAULT_FUNCTION_ARG_PADDING.
+ * config/ia64/ia64.c (ia64_hpux_function_arg_padding):
+ Likewise.
+ * config/m68hc11/m68hc11.c (m68hc11_function_arg_padding):
+ Likewise.
+ * config/rs6000/rs6000.c (function_arg_padding): Likewise.
+ * config/sparc/sparc.c (function_arg_padding): Likewise.
+
+2003-09-15 Vladimir Makarov <vmakarov@redhat.com>
+
+ * haifa-sched.c (schedule_block): Use ready_remove_first instead
+ of choose_ready for non-dfa insn scheduling.
+
+2003-09-15 Andreas Jaeger <aj@suse.de>
+ Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * doc/invoke.texi (Warning Options): Describe -Wold-style-definition.
+ * c-opts.c (c_common_handle_option): Handle OPT_Wold_style_definition.
+ * c-parse.in: Warn about old-style parameter definition.
+ * c-common.c: Define warn_old_style_defintion.
+ * c-common.h: Declare it.
+ * c.opt: Add Wold-style-defintion.
+
+2003-09-15 Andreas Jaeger <aj@suse.de>
+
+ * config/rs6000/altivec.h: Convert () prototypes to ISO C90.
+ * config/rs6000/rs6000.c: Likewise.
+
+2003-09-12 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR optimization/10914
+ * expr.h (get_condition, canonicalize_condition): Declaration changed.
+ * cfgloopanal.c (simple_loop_exit_p): Add parameter to a get_condition
+ and canonicalize_condition calls.
+ * gcse.c (fis_get_condition, delete_null_pointer_checks_1,
+ delete_null_pointer_checks): Ditto.
+ * ifcvt.c (noce_get_alt_condition, noce_get_condition): Ditto.
+ * predict.c (estimate_probability, expected_value_to_br_prob): Ditto.
+ * loop.c (check_dbra_loop, get_condition_for_loop): Ditto.
+ (canonicalize_condition, get_condition): Allow to return comparisons
+ of cc mode registers.
+ * loop-unswitch.c (may_unswitch_on_p, unswitch_single_loop): Allow
+ cc mode registers comparison in condition.
+
+2003-09-12 Mark Mitchell <mark@codesourcery.com>
+
+ * coverage.c (create_coverage): Do not call pushlevel/poplevel.
+ * langhooks-def.h (lhd_do_nothing_iii_return_null_tree): New
+ function.
+ * langhooks.c (lhd_do_nothing_iii_return_null_tree): Define it.
+
+2003-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (simplify_comparison): Convert
+ (ne (and (lshiftrt (xor X CST) Y) 1) 0) into
+ (eq (and (lshiftrt X Y) 1) 0).
+
+2003-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alias.c: Follow spelling conventions.
+ * cpphash.h: Likewise.
+ * fold-const.c: Likewise.
+
+2003-09-14 Alexandre Oliva <aoliva@redhat.com>
+
+ * c-ppoutput.c (cb_line_change): Revert 2003-08-04's change.
+ * c-lex.c (cb_line_change): Skip line changing whenever
+ c-ppoutput.c would.
+
+2003-09-14 Steven Bosscher <steven@gcc.gnu.org>
+
+ * ra.c: Convert to ISO C90 prototypes.
+ * ra-build.c: Likewise.
+ * ra-colorize.c: Likewise.
+ * ra-debug.c: Likewise.
+ * ra-rewrite.c: Likewise.
+
+2003-09-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * Makefile.in (%.dvi): Remove excess $(docdir).
+
+2003-09-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * function.c (STACK_BYTES): Move definition to head of file.
+ (assign_parms): Don't pass current_function_pretend_args_size
+ directly to SETUP_INCOMING_VARARGS. For partial register arguments,
+ round current_function_pretend_args_size up to STACK_BYTES. Skip any
+ excess before laying out the argument.
+
+2003-09-14 Andreas Jaeger <aj@suse.de>
+
+ * objc/objc-act.c: Convert to ISO C90 prototypes.
+ * objc/objc-act.h: Likewise.
+
+2003-09-14 Olaf Hering <olh@suse.de>
+
+ * config/rs6000/rs6000.c: Fix typo: Remove extra ')'.
+
+2003-09-13 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/12021
+ * config/m68k/netbsd-elf.h (TARGET_OS_CPP_BUILTINS): Remove the asserts
+ as they already are done in config/m68k/m68k.h.
+ * config/m68k/netbsd.h (TARGET_OS_CPP_BUILTINS): Likewise
+
+ * config/rs6000/rs6000.c (GEN_LOCAL_LABEL_FOR_SYMBOL): Remove.
+ (machopic_output_stub): Only generate pic base symbols when using pic
+ and generate them in the form L00000000$spb.
+
+2003-09-13 Richard Henderson <rth@redhat.com>
+
+ * cgraphunit.c (cgraph_assemble_pending_functions): Export.
+ (cgraph_finalize_function): Revert TREE_ASM_WRITTEN check.
+ * cgraph.h: Update.
+
+2003-09-12 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.c: Fix typos in previous.
+
+2003-09-12 Ziemowit Laski <zlaski@apple.com>
+
+ * pretty-print.c (pp_construct): Use xcalloc instead of xmalloc
+ when allocating pp->buffer.
+
+2003-09-12 Geoffrey Keating <geoffk@apple.com>
+
+ * config/darwin.c (machopic_select_rtx_section): Use
+ const_data_section for things that might require relocation.
+
+2003-09-12 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR bootstrap/12264
+ * tree-inline.c (inline_forbidden_p_1): Cast the 3rd arg to tree.
+
+2003-09-12 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/elf.h (ASM_SPEC): Remove no-density option. Reformat.
+ * config/xtensa/linux.h (ASM_SPEC): Likewise.
+ * config/xtensa/xtensa.h (TARGET_SWITCHES): Remove -mbig-endian,
+ -mlittle-endian, -m[no-]density, -m[no-]abs, -m[no-]addx, -m[no-]mac16,
+ -m[no-]mul16, -m[no-]mul32, -m[no-]nsa, -m[no-]minmax, -m[no-]sext,
+ -m[no-]booleans, -mhard-float, -msoft-float, -m[no-]hard-float-div,
+ -m[no-]hard-float-recip, -m[no-]hard-float-sqrt, and
+ -m[no-]hard-float-rsqrt options. Delete corresponding MASK_* macros
+ and redefine corresponding TARGET_* macros with constants from the
+ xtensa-config.h header.
+ * doc/invoke.texi (Option Summary, Xtensa Options): Remove documention
+ for the options listed above.
+
+2003-09-12 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000-protos.h: Use C90 prototypes.
+ * config/rs6000/rs6000-c.c: Ditto.
+ * config/rs6000/rs6000.c: Ditto.
+ * config/rs6000/ sysv4.h: Ditto.
+
+2003-09-12 Chris Lattner <sabre@nondot.org>
+
+ * loop.c: Move comments describing BIV's and GIV's to top of file
+
+2003-09-12 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/8967
+ * alias.c (write_dependence_p): Modify to take an additional constp
+ argument that controls whether the UNCHANGING_RTX_P flags are used.
+ (anti_dependence, output_dependence): Adjust write_dependence_p
+ callers to pass this additional argument, to return the same result.
+ (unchanging_anti_dependence): New variant of anti_dependence that
+ ignores the UNCHANGING_RTX_P property on memory references.
+ * rtl.h (unchaning_anti_dependence): Prototype here.
+ * flow.c (init_propagate_block): Place fake constant mem writes on
+ the mem_set_list so that dead writes to const variables are deleted.
+ (insn_dead_p): Change anti_dependence to unchanging_anti_dependence.
+ (mark_used_regs): Likewise.
+
+2003-09-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mcore/mcore-protos.h (mcore_r15_operand_p): Declare.
+ (mcore_secondary_reload_class): Declare.
+ (mcore_output_inline_const_forced): Remove.
+ * config/mcore/mcore.md (movsi): Remove the code that forced
+ non-inlineable constants into a register if the target was r15
+ or the stack pointer. Remove constant restrictions from the main
+ define_insn. Remove r <- I, r <- M and r <- N alternatives in favor
+ of an r <- P alternative. Remove fallback define_insn for reload.
+ (movhi, movqi): Use gen_lowpart rather than gen_SUBREG. Remove reload
+ define_insn. Use mcore_output_move in the remaining define_insn.
+ Adjust condition and constraints in the way as for movsi.
+ (movdi): Always split unacceptable constants into two. Use
+ simplify_gen_subreg instead of operand_subword{,_force}.
+ * config/mcore/mcore.c (mcore_output_inline_const_forced): Remove.
+ (mcore_output_move): Support HImode and QImode moves as well.
+ (mcore_m15_operand_p): New function.
+ (mcore_reload_class): Use it to detect cases where LRW_REGS are better.
+ (mcore_secondary_reload_class): New function.
+ * config/mcore/mcore.h (SECONDARY_RELOAD_CLASS): Redefine in
+ terms of mcore_secondary_reload_class.
+
+2003-09-11 Mike Stump <mrs@apple.com>
+
+ * c-lex.c (fe_file_change): Don't transform to_line with SOURCE_LINE.
+
+2003-09-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (fold_builtin_logarithm): if N can't be truncated to
+ MODE exactly, then only convert logN(N) -> 1.0 if
+ flag_unsafe_math_optimizations is set.
+
+ * builtins.c (builtin_dconsts_init, dconstpi, dconste,
+ init_builtin_dconsts): Delete.
+ * emit-rtl.c (dconstpi, dconste): Define.
+ (init_emit_once): Initialize dconstpi & dconste.
+ * real.h (dconstpi, dconste): Declare.
+
+2003-09-11 Alexandre Oliva <aoliva@redhat.com>
+
+ PR fortran/11522
+ * dwarf2out.c (gen_inlined_subroutine_die): Emit abstract function
+ for ultimate origin even if block is abstract.
+
+2003-09-11 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (combine_simplify_rtx): Move several NOT and NEG
+ optimizations from here...
+ * simplify-rtx.c (simplify_unary_operation): to here. Recursively
+ simplify expressions using simplify_gen_*ary instead of gen_rtx_*.
+
+2003-09-11 Richard Henderson <rth@redhat.com>
+
+ * cgraphunit.c (cgraph_finalize_function): Add nested arg.
+ Tweek tests for function already generated.
+ (cgraph_expand_function): Don't double announce in !unit-at-a-time.
+ * cgraph.h (cgraph_finalize_function): Update for extra arg.
+ * c-decl.c (finish_function): Likewise.
+
+2003-09-10 Joe Buck <jbuck@welsh-buck.org>
+
+ * c-decl.c (poplevel): Eliminate use of |= in function_body assignment.
+
+2003-09-10 Jerry Quinn <jlquinn@optonline.net>
+
+ * real.c: Update URL to VAX floating point docs.
+ (decode_vax_d): Extract 8 exponent bits instead of 7.
+
+2003-09-10 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * combine.c (force_to_mode): Set fuller_mask based only on mask,
+ not op_mode.
+
+2003-09-11 Jan Hubicka <jh@suse.cz>
+
+ * c-objc-common.c (c_cannot_inline_tree_fn): Warn
+ on why function is not inlinable; do not check
+ the body.
+ (inline_forbidden_p): Move to...
+ * tree-inline.c (inline_forbidden_p_1): ... here; Add warnings;
+ deal with alloca, longjmp.
+ (inline_forbidden_p): New static function.
+ (find_alloca_call_1, find_alloca_call, find_builtin_longjmp_call_1,
+ find_builtin_longjmp_call): Kill.
+
+2003-09-10 Richard Henderson <rth@redhat.com>
+
+ * cgraph.h (struct cgraph_node): Rename lowered to analyzed.
+ * cgraphunit.c: Update to match.
+ (record_call_1): Rearrange. Call lang hook for language nodes.
+ (cgraph_analyze_function): Don't call lower_function.
+ * langhooks.h (struct lang_hooks_for_callgraph): Replace
+ lower_function with analyze_expr.
+ * langhooks-def.h: Update to match.
+ * langhooks.c (lhd_callgraph_analyze_expr): New.
+
+2003-09-10 Martin Husemann <martin@duskware.de>
+
+ PR target/11965
+ * config/sparc/sparc.c (sparc_v8plus_shift): Protect against
+ constants greater than 63.
+ * config/sparc/sparc.md (ashlsi3, ashrsi3, lshrsi3): Protect
+ against constants greater than 31.
+ (*ashldi3_sp64, *ashrdi3_sp64, *lshrdi3_sp64): Protect against
+ constants greater than 63.
+
+2003-09-09 Richard Henderson <rth@redhat.com>
+
+ * cgraphunit.c (cgraph_finalize_function): Remove unused argument.
+ * cgraph.h (cgraph_finalize_function): Update.
+ * c-decl.c (finish_function): Update.
+
+2003-09-09 Devang Patel <dpatel@apple.com>
+
+ * config/darwin.h (LINK_SPEC): Pass -nofixprebinding to linker.
+ * doc/invoke.texi: Document new Darwin linker option -nofixprebinding.
+
+2003-09-09 Eric Christopher <echristo@redhat.com>
+
+ * configure.in: Change usage of 'head' to 'sed 1q'.
+ * configure: Regenerate.
+
+2003-09-09 Richard Henderson <rth@redhat.com>
+
+ * except.c: Include cgraph.h.
+ (output_function_exception_table): Invoke
+ cgraph_varpool_mark_needed_node.
+ * Makefile.in (except.o): Update.
+
+2003-09-07 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * Makefile.in: Define REMAKEFLAGS for LANGUAGES & BOOT_CFLAGS
+ and use it throughout.
+
+2003-09-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (real_dconstp, fold_builtin_logarithm,
+ fold_builtin_exponent): New, split out from fold_builtin. Also
+ generalize to add log2, log10, exp2 and exp10/pow10 equivalents.
+ * emit-rtl.c (dconst3, dconst10, dconstthird): New.
+ (init_emit_once): Initialize new dconsts, use ARRAY_SIZE in lieu
+ of hardcoded array size.
+ * fold-const.c (fold): Add cases for exp2, exp10 and pow10.
+ (tree_expr_nonnegative_p): Likewise.
+ * real.h (dconst3, dconst10, dconstthird): New.
+
+2003-09-09 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_finalize_function): Fix handling of extern
+ inline functions.
+ (cgraph_finalize_compilation_unit): Fix crash when dealing with lost
+ DECL_SAVED_TREE.
+
+2003-09-09 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (fold_builtin_cabs): Protect the complex argument
+ against multiple evaluation when optimizing cabs* into sqrt*.
+
+2003-09-09 Jan Hubicka <jh@suse.cz>
+
+ * varasm.c (notice_global_symbol): Properly deal with weak symbols.
+
+2003-09-08 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * Makefile.in: Revert yesterday's change.
+
+2003-09-08 Bernardo Innocenti <bernie@develer.com>
+ Peter Barada <peter@baradas.org>
+
+ * config/m68k/coff.h (REGISTER_NAMES): Add fake register `argptr'
+ * config/m68k/hp320.h (REGISTER_NAMES): Likewise.
+ * config/m68k/linux.h (REGISTER_NAMES): Likewise.
+ * config/m68k/m68kelf.h (REGISTER_NAMES): Likewise.
+ * gcc/config/m68k/sgs.h (REGISTER_NAMES): Likewise.
+ * config/m68k/m68k-protos.h (m68k_initial_elimination_offset): Add prototype.
+ * config/m68k/m68k.c (m68k_frame): New struct, simular to ix86 back-end.
+ (m68k_compute_frame_layout): New function.
+ (m68k_initial_elimination_offset): New function.
+ (m68k_output_function_prologue): ColdFire-specific movem handling.
+ (m68k_output_function_epilogue): Likewise.
+ * config/m68k/m68k.h (FIRST_PSEOUDO_REGISTER): Make room for argptr reg.
+ (ARG_POINTER_REGNUM): Add new definition.
+ (INITIAL_FRAME_POINTER_OFFSET): Remove macro.
+ (ELIMINABLE_REGS): Define new macro, like in ix86 back-end.
+ (CAN_ELIMINATE): Likewise.
+ (INITIAL_ELIMINATION_OFFSET): Likewise.
+
+2003-09-08 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c (m68k_output_function_prologue): Simplify
+ by removing redundant variable cfa_store_offset.
+
+2003-09-08 Mark Mitchell <mark@codesourcery.com>
+
+ * langhooks-def.h (lhd_register_builtin_type): New function.
+ (LANG_HOOKS_REGISTER_BUILTIN_TYPE): New macro.
+ (LANG_HOOKS_FOR_TYPES_INITIALIZER): Update.
+ * langhooks.h (lang_hooks_for_types): Add register_builtin_type.
+ * langhooks.c (lhd_register_builtin_type): New function.
+ * c-common.h (c_register_builtin_type): Declare.
+ * c-common.c (c_register_builtin_type): New function.
+ * c-lang.c (LANG_HOOKS_REGISTER_BUILTIN_TYPE): Define to
+ c_register_builtin_type.
+ * config/ia64/hpux.h (TARGET_OS_CPP_BUILTINS): Remove __fpreg,
+ __float80, and __float128 macros.
+ * config/ia64/ia64.c (ia64_init_builtins): Create __fpreg,
+ __float80, and __float128 types.
+
+2003-09-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-types.def
+ (BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE,
+ BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
+ BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT): New.
+ * builtins.def (BUILT_IN_CACOS, BUILT_IN_CACOSF, BUILT_IN_CACOSH,
+ BUILT_IN_CACOSHF, BUILT_IN_CACOSHL, BUILT_IN_CACOSL,
+ BUILT_IN_CARG, BUILT_IN_CARGF, BUILT_IN_CARGL, BUILT_IN_CASIN,
+ BUILT_IN_CASINF, BUILT_IN_CASINH, BUILT_IN_CASINHF,
+ BUILT_IN_CASINHL, BUILT_IN_CASINL, BUILT_IN_CATAN,
+ BUILT_IN_CATANF, BUILT_IN_CATANH, BUILT_IN_CATANHF,
+ BUILT_IN_CATANHL, BUILT_IN_CATANL, BUILT_IN_CCOS, BUILT_IN_CCOSF,
+ BUILT_IN_CCOSH, BUILT_IN_CCOSHF, BUILT_IN_CCOSHL, BUILT_IN_CCOSL,
+ BUILT_IN_CEXP, BUILT_IN_CEXPF, BUILT_IN_CEXPL, BUILT_IN_CPOW,
+ BUILT_IN_CPOWF, BUILT_IN_CPOWL, BUILT_IN_CPROJ, BUILT_IN_CPROJF,
+ BUILT_IN_CPROJL, BUILT_IN_CSIN, BUILT_IN_CSINF, BUILT_IN_CSINH,
+ BUILT_IN_CSINHF, BUILT_IN_CSINHL, BUILT_IN_CSINL, BUILT_IN_CSQRT,
+ BUILT_IN_CSQRTF, BUILT_IN_CSQRTL, BUILT_IN_CTAN, BUILT_IN_CTANF,
+ BUILT_IN_CTANH, BUILT_IN_CTANHF, BUILT_IN_CTANHL, BUILT_IN_CTANL):
+ New.
+ * doc/extend.texi: Document new builtins.
+
+2003-09-09 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_varpool_finalize_decl): Sanity check duplicated
+ finalization.
+ * cgraphunit.c (decide_is_fnction_needed): Avoid special case of nested
+ functions, check for COMDAT.
+ (cgraph_assemble_pending_functions): Break out from...
+ (cgraph_finalize_function): ... here; allow redefinig of extern inline
+ functions.
+ (record_call_1): Record function references only in non-unit-at-a-time
+ mode.
+ (cgraph_analyze_function): Reset current_function_decl.
+ (cgraph_finalize_compilation_unit): Assemble pending functions.
+
+2003-09-08 Mark Mitchell <mark@codesourcery.com>
+
+ * mklibgcc.in (libcc.a): Depend on stmp-dirs.
+ (libgov.a): Likewise.
+ (libgcc_eh.a): Likewise.
+
+2003-09-08 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (operand_equal_p): Clarify documentation.
+
+2003-09-08 Richard Henderson <rth@redhat.com>
+
+ * c-decl.c (c_expand_body_1): Push and pop function context here.
+ * tree-optimize.c (tree_rest_of_compilation): ... not here. Take
+ nested argument instead of computing nesting ourselves.
+
+2003-09-08 Jakub Jelinek <jakub@redhat.com>
+
+ * toplev.c (rest_of_handle_stack_regs): Call split_all_insns before
+ regstack if optimizing but not scheduling after reload.
+
+2003-09-08 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/sparc.c (struct machine_function): New type.
+ (TARGET_HAVE_TLS, TARGET_CANNOT_FORCE_CONST_MEM): Define.
+ (sparc_override_options): Initialize init_machine_status.
+ (tls_symbolic_operand, tgd_symbolic_operand, tld_symbolic_operand,
+ tie_symbolic_operand, tle_symbolic_operand): New functions.
+ (symbolic_operand): Disallow tls_symbolic_operand.
+ (symbolic_memory_operand): Likewise.
+ (tls_call_delay, sparc_cannot_force_const_mem, legitimate_constant_p,
+ constant_address_p, legitimate_pic_operand_p, legitimate_address_p):
+ New functions.
+ (sparc_tls_symbol): New variable.
+ (sparc_tls_get_addr, sparc_tls_got, legitimize_tls_address,
+ legitimize_address): New functions.
+ (print_operand): Handle %&.
+ (sparc_init_machine_status, get_some_local_dynamic_name,
+ get_some_local_dynamic_name_1): New functions.
+ (sparc_output_dwarf_dtprel): New function.
+ * config/sparc/sparc.h (CONSTANT_ADDRESS_P): Moved into
+ constant_address_p.
+ (LEGITIMATE_PIC_OPERAND_P): Moved into legitimate_pic_operand_p.
+ (LEGITIMATE_CONSTANT_P): Moved into legitimate_constant_p.
+ (GO_IF_LEGITIMATE_ADDRESS): Moved into legitimate_address_p.
+ (LEGITIMIZE_ADDRESS): Moved into legitimize_address.
+ (PRINT_OPERAND_PUNCT_VALID_P): Add '&'.
+ (TARGET_TLS, TARGET_SUN_TLS, TARGET_GNU_TLS): Define.
+ (ASM_OUTPUT_DWARF_DTPREL): Define.
+ (PREDICATE_CODES): Add tgd_symbolic_operand, tld_symbolic_operand,
+ tie_symbolic_operand, tle_symbolic_operand.
+ * config/sparc/sparc.md (UNSPEC_TLSGD, UNSPEC_TLSLDM, UNSPEC_TLSLDO,
+ UNSPEC_TLSIE, UNSPEC_TLSLE, UNSPEC_TLSLD_BASE): New constants.
+ (tls_call_delay): New attribute.
+ (in_call_delay): Use it.
+ (movqi, movhi, movsi, movdi): Call legitimize_tls_address if needed.
+ (tgd_hi22, tgd_lo10, tgd_add32, tgd_add64, tgd_call32, tgd_call64,
+ tldm_hi22, tldm_lo10, tldm_add32, tldm_add64, tldm_call32, tldm_call64,
+ tldo_hix22, tldo_lox10, tldo_add32, tldo_add64, tie_hi22, tie_lo10,
+ tie_ld32, tie_ld64, tie_add32, tie_add64, tle_hix22_sp32,
+ tle_lox10_sp32, tle_hix22_sp64, tle_lox10_sp64): New insns.
+ (tldo_ldub_sp32, tldo_ldub1_sp32, tldo_ldub2_sp32, tldo_ldsb1_sp32,
+ tldo_ldsb2_sp32, tldo_ldub_sp64, tldo_ldub1_sp64, tldo_ldub2_sp64,
+ tldo_ldub3_sp64, tldo_ldsb1_sp64, tldo_ldsb2_sp64, tldo_ldsb3_sp64,
+ tldo_lduh_sp32, tldo_lduh1_sp32, tldo_ldsh1_sp32, tldo_lduh_sp64,
+ tldo_lduh1_sp64, tldo_lduh2_sp64, tldo_ldsh1_sp64, tldo_ldsh2_sp64,
+ tldo_lduw_sp32, tldo_lduw_sp64, tldo_lduw1_sp64, tldo_ldsw1_sp64,
+ tldo_ldx_sp64, tldo_stb_sp32, tldo_stb_sp64, tldo_sth_sp32,
+ tldo_sth_sp64, tldo_stw_sp32, tldo_stw_sp64, tldo_stx_sp64): New
+ insns.
+ * config/sparc/sparc-protos.h (legitimate_constant_p,
+ constant_address_p, legitimate_pic_operand_p, legitimate_address_p,
+ legitimize_tls_address, legitimize_address, tls_symbolic_operand,
+ tls_call_delay, sparc_output_dwarf_dtprel): New prototypes.
+ * config/sparc/linux.h (TARGET_GNU_TLS, TARGET_SUN_TLS): Define.
+ * config/sparc/linux64.h (TARGET_GNU_TLS, TARGET_SUN_TLS): Likewise.
+ * configure.in (sparc*-*-*): Add TLS check.
+ * configure: Rebuilt.
+
+2003-09-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/11689
+ * config/i386/i386.c (memory_address_length): Fix computation when
+ the base is esp or ebp.
+
+2003-09-07 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11852
+ * varasm.c (initializer_constant_valid_p): Correct logic for
+ CONSTRUCTORs.
+
+2003-09-07 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_operands): New function to expand an operand pair.
+ (expand_expr): Call expand_operands whenever we need to expand both
+ operands of a binary operator.
+ (do_store_flag): Likewise for operands of comparison operations.
+
+2003-09-07 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (combine_simplify_rtx): Don't convert -(A*B) into
+ (-A)*B if we care about sign-dependent rounding.
+
+2003-09-07 Gabriel Dos Reis <gcc@integrable-solutions.net>
+
+ * c-pretty-print.h (pp_c_left_brace): Declare.
+ (pp_c_right_brace): Likewise.
+ * c-pretty-print.c (pp_c_left_brace): Now a function
+ (pp_c_right_brace): Likewise.
+
+2003-09-07 Jan Hubicka <jh@suse.cz>
+
+ * cfgcleanup.c (try_simplify_condjump): Fix again the preivous patch.
+
+2003-09-07 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * diagnostic.c (warn_deprecated_use): Move to toplev.c
+
+2003-09-07 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * langhooks.c (lhd_print_error_function): Move from diagnostic.c.
+ * Makefile.in (langhooks.o): Depend on diagnostic.h
+
+2003-09-06 James E Wilson <wilson@tuliptree.org>
+
+ * loop.c (loop_regs_update): Delete else clause for PATTERN rtx and
+ simplify.
+
+2003-09-07 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * Makefile.in: Define $REMAKE to be $MAKE with LANGUAGES & BOOT_CFLAGS
+ and use it throughout.
+
+2003-09-07 Jan Hubicka <jh@suse.cz>
+
+ * cfgcleanup.c (try_simplify_condjump): Fix my previous patch.
+
+ * toplev.c (rest_of_decl_compilation): Do not finalize external
+ virables.
+
+ * cgraph.c (cgraph_mark_reachable_node): Only enqueue finalized
+ functions.
+ (cgraph_varpool_finalize_decl): Notice global symbol when needed.
+
+2003-09-06 Jan Hubicka <jh@suse.cz>
+
+ PR target/12070
+ * calls.c (emit_library_call_value_1): Fix saving of BLKmode arguments.
+
+ PR opt/12082
+ * cfgcleanup.c (try_simplify_condjump): Avoid unreachable code warning.
+
+2003-09-06 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * diagnostic.c (announce_function): Move to toplev.c.
+
+2003-09-06 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcse.c (expr_equiv_p): Don't consider anything to be equal to
+ volatile mem.
+
+2003-09-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ggc-common.c (init_ggc_heuristics): Don't use the heuristics
+ when gc checking is enabled.
+
+2003-09-06 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR c/9862
+ * c-decl.c (c_expand_body_1): Move return warning from here...
+ (finish_function): ...to here.
+
+2003-09-05 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/darwin.h (PREFERRED_RELOAD_CLASS): Always return
+ a subset of the input class.
+
+2003-09-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i860/i860.c: Follow spelling conventions.
+ * config/i860/i860.h: Likewise.
+ * config/sh/sh.h: Likewise.
+
+2003-09-05 Nitin Yewale <NitinY@KPITCummins.com>
+
+ * config/h8300/h8300-protos.h: Declare h8300_hard_regno_rename_ok
+ * config/h8300/h8300.h (HARD_REGNO_RENAME_OK): New.
+ * config/h8300/h8300.c (h8300_hard_regno_rename_ok): New.
+
+2003-09-05 Roger Sayle <roger@eyesopen.com>
+ Richard Henderson <rth@redhat.com>
+
+ PR optimization/1823
+ * expmed.c (expand_divmod <EXACT_DIV_EXPR>): Use an unsigned
+ multiplication to implement division by constant integer.
+
+2003-09-05 Jan Hubicka <jh@suse.cz>
+
+ * opts.c (decode_options): Enable unit-at-a-time at -O2.
+ * params.def (max-inline-insns-single): Set to 500
+ (max-inline-insns-auto): Set to 150
+ * invoke.texi (max-inline-insns-single, max-inline-insns-auto): Update.
+
+2003-09-04 Richard Henderson <rth@redhat.com>
+
+ * cgraph.c (cgraph_mark_reachable_node): Split out from ...
+ (cgraph_mark_needed_node): Remove needed argument.
+ * cgraph.h: Update to match.
+ * cgraphunit.c (decide_is_function_needed): Split out from ...
+ (cgraph_finalize_function): Reorg. Avoid deferred_inline_function
+ if we generated the function.
+ (record_call_1): Update for cgraph_mark_reachable_node.
+ * varasm.c (mark_referenced): Likewise.
+ * objc/objc-act.c (mark_referenced_methods): Likewise.
+
+2003-09-04 DJ Delorie <dj@redhat.com>
+
+ * targhooks.c: Add comment explaining the migration process.
+
+2003-09-04 Eric Christopher <echristo@redhat.com>
+
+ * config/frv/t-frv: Fix path for frv-abi.h.
+ * config/frv/frv-asm.h: Fix string concatenation.
+
+2003-09-04 DJ Delorie <dj@redhat.com>
+
+ * builtins.c (apply_args_size): Guard against a NULL cfun.
+ (expand_builtin_apply_args_1): Likewise.
+ (expand_builtin_apply): Likewise.
+ Fixes PR bootstrap/12172.
+
+2003-09-04 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (gcc_cv_as_ix86_cmov_sun_syntax): Check if
+ assembler supports Sun syntax for cmov.
+ * configure: Regenerate.
+ * config.in: Likewise.
+ * config/i386/i386.c: Rename CMOV_SUN_AS_SYNTAX to
+ HAVE_AS_IX86_CMOV_SUN_SYNTAX.
+ * config/i386/sol2.h (CMOV_SUN_AS_SYNTAX): Remove.
+ Fixes PR target/12101.
+
+2003-09-04 Matt Austern <austern@apple.com>
+
+ * c-common.c (fname_as_string): Use lang_hooks.decl_printable_name
+ with verbosity 0, instead of DECL_NAME, for human-readable string.
+
+2003-09-04 Eric Christopher <echristo@redhat.com>
+
+ * targhooks.c (default_return_in_memory): Allow
+ unconverted ports.
+
+2003-09-04 Eric Christopher <echristo@redhat.com>
+
+ * targhooks.c (default_return_in_memory): Fix typo
+ in last checkin.
+
+2003-09-04 Eric Christopher <echristo@redhat.com>
+
+ * targhooks.c (default_return_in_memory): Fix default
+ definition.
+
+2003-09-04 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c (m68k_coff_asm_named_section): Restore
+ deleted function.
+ * config/m68k/coff.h (M68K_TARGET_COFF): Add flag used to
+ enable coff-only code in m68k.c.
+
+2003-09-04 Nick Clifton <nickc@redhat.com>
+
+ * config.gcc: Add v850e1 target. Allow --with-cpu to accept
+ v850e1.
+ * config/v850/v850.h: Accept v850e1 as a default CPU.
+ Accept -mv850e1 as a command line option.
+ * doc/invoke.texi: Document new -mv850e1 command line switch.
+ * config/v850/t-v850: Treat -mv850e1 as a multilib alias for
+ -mv850e.
+
+2003-09-04 Nick Clifton <nickc@redhat.com>
+
+ * config.gcc (v850e-*-*): Use t-v850e makefile fragment.
+ * config/v850/t-v850: Only produce one extra multilib - for
+ the v850e.
+ * config/v850/t-v850e: New file: Only produce one extra
+ multilib - for the v850.
+
+2003-09-04 Jakub Jelinek <jakub@redhat.com>
+
+ * config/ia64/libgcc-ia64.ver: Export _Unwind_GetBSP@@GCC_3.3.2.
+ * config/ia64/unwind-ia64.c (_Unwind_GetBSP): New function.
+ * unwind.h (_Unwind_GetBSP): New prototype.
+ * libgcc-std.ver: Add empty GCC_3.3.2 version.
+ * mkmap-symver.awk: For symbol versions with no exported symbols,
+ don't put anything into version script, just change all symbol
+ versions which inherit from it to inherit from its ancestor.
+
+2003-09-04 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.c (mips_expand_prologue): Convert to
+ calls.struct_value_rtx hook.
+ (reg_or_const_float_1_operand): New.
+ * config/mips/mips.h: Update Comments.
+ (mips_arg): Add reg_or_const_float_1_operand.
+ * config/mips/mips.md (divdf3); Convert to expander.
+ (divsf3): Ditto.
+ (*divdf3): New pattern.
+ (*divsf3): Ditto.
+
+2003-09-04 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (wrapup_global_declarations): Fix final pass in
+ unit-at-atime mode.
+
+2003-09-04 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/extend.texi: Document removal of cast-as-lvalue extension in
+ C++.
+
+2003-09-04 Nicolas Roche <roche@act-europe.fr>
+
+ * gcc.c (process_command): Fix typo.
+
+2003-09-03 David O'Brien <obrien@FreeBSD.org>
+
+ optimization/11980
+ * config/i386/freebsd.h (SIZE_TYPE): Support TARGET_64BIT.
+ (PTRDIFF_TYPE): Likewise.
+ (WCHAR_TYPE_SIZE): Likewise.
+
+2003-09-03 DJ Delorie <dj@redhat.com>
+
+ * targhooks.c: New file.
+ * targhooks.h: New file.
+ * Makefile.in: Add targhooks.o support.
+ (function.o): Depend on$(TARGET_H).
+ (stmt.o): Likewise.
+ (combine.o): Depend on $(TREE_H) and $(TARGET_H).
+ * builtins.c (apply_args_size, expand_builtin_apply_args_1,
+ expand_builtin_apply): Convert to calls.struct_value_rtx hook.
+ (expand_builtin_saveregs): Convert to
+ calls.expand_builtin_saveregs hook.
+ * c-decl.c (start_decl): Handle new calls.promote_prototypes hook
+ here, instead of ...
+ (get_parm_info) ... here.
+ (store_parm_decls_oldstyle): Convert to calls.promote_prototypes
+ hook.
+ (finish_function): Handle calls.promote_prototypes hook here too.
+ * c-typeck.c (convert_arguments): Convert to
+ calls.promote_prototypes hook.
+ (c_convert_parm_for_inlining): Likewise.
+ * calls.c (initialize_argument_information): Convert to
+ calls.promote_function_args hook.
+ (expand_call): Convert to calls.struct_value_rtx,
+ calls.strict_argument_naming,
+ calls.pretend_outgoing_varargs_named, and
+ calls.promote_function_return hooks. Pass fndecl to
+ aggregate_value_p. Initialize CUMULATIVE_ARGS before calling
+ hooks, so they can use that.
+ (emit_library_call_value_1): Likewise.
+ * combine.c (setup_incoming_promotions): Convert to
+ calls.promote_function_args hook.
+ * emit-rtl.c: Convert to calls.struct_value_rtx hook.
+ * expr.c (expand_assignment): Pass call to aggregate_value_p.
+ (expand_expr): Likewise.
+ * expr.h: Remove support for SETUP_INCOMING_VARARGS,
+ STRICT_ARGUMENT_NAMING, PRETEND_OUTGOING_VARARGS_NAMED,
+ RETURN_IN_MEMORY macro defaults.
+ * final.c (profile_function): Convert to calls.struct_value_rtx
+ hook.
+ * function.c (aggregate_value_p): Accept function type tree as
+ second parameter; try to deduce fntype from it. Convert to
+ calls.return_in_memory hook.
+ (assign_parms): Convert to calls.setup_incoming_varargs,
+ calls.strict_argument_naming, calls.promote_function_args,
+ calls.pretend_outgoing_varargs_named hooks. Pass fndecl to
+ aggregate_value_p.
+ (expand_function_start): Likewise. Convert to
+ calls.struct_value_rtx hook.
+ (expand_function_end): Convert to calls.promote_function_return hook.
+ (allocate_struct_function): Pass fndecl to aggregate_value_p.
+ * hard-reg-set.h: Update comments to new hook names.
+ * integrate.c (expand_inline_function): Pass fndecl to aggregate_value_p.
+ * reg-stack.c (stack_result): Likewise.
+ * rtl.h (struct_value_rtx, struct_value_incoming_rtx): Delete.
+ * stmt.c (expand_value_return): Convert to
+ calls.promote_function_return hook.
+ * target-def.h: Add TARGET_PROMOTE_FUNCTION_ARGS,
+ TARGET_PROMOTE_FUNCTION_RETURN, TARGET_PROMOTE_PROTOTYPES,
+ TARGET_STRUCT_VALUE_RTX, TARGET_RETURN_IN_MEMORY,
+ TARGET_EXPAND_BUILTIN_SAVEREGS, TARGET_SETUP_INCOMING_VARARGS,
+ TARGET_STRICT_ARGUMENT_NAMING,
+ TARGET_PRETEND_OUTGOING_VARARGS_NAMED, and TARGET_CALLS.
+ * target.h: Likewise.
+ * tree.h (aggregate_value_p): Also takes a tree to deduce function
+ attributes from (for target hooks).
+ * doc/tm.texi (PROMOTE_FUNCTION_ARGS, PROMOTE_FUNCTION_RETURN,
+ PROMOTE_PROTOTYPES, RETURN_IN_MEMORY, STRUCT_VALUE_REGNUM,
+ STRUCT_VALUE, STRUCT_VALUE_INCOMING_REGNUM, STRUCT_VALUE_INCOMING,
+ EXPAND_BUILTIN_SAVEREGS, SETUP_INCOMING_VARARGS,
+ STRICT_ARGUMENT_NAMING, PRETEND_OUTGOING_VARARGS_NAMED): Convert
+ to hooks.
+
+ * config/alpha/alpha.c (alpha_output_mi_thunk_osf): Pass function
+ to aggregate_value_p.
+ * config/arm/arm.c (arm_init_cumulative_args,
+ arm_output_mi_thunk): Likewise.
+ * config/i386/i386.c (ix86_return_pops_args, x86_this_parameter):
+ Likewise.
+ * config/mips/mips.c (mips_save_reg_p, mips_expand_prologue,
+ mips_can_use_return_insn): Likewise.
+ * config/rs6000/rs6000.c (rs6000_output_mi_thunk): Likewise.
+ * config/s390/s390.c (s390_output_mi_thunk): Likewise.
+ * config/sparc/sparc.c (sparc_output_mi_thunk): Pass function to
+ aggregate_value_p.
+ * config/story16/stormy16.c (xstormy16_asm_output_mi_thunk): Pass
+ function to aggregate_value_p.
+ * objc/objc-act.c (generate_struct_by_value_array): Pass NULL to
+ aggregate_value_p.
+
+ * config/sh/sh-protos.h (sh_builtin_saveregs): Remove.
+ (sh_attr_renesas_p, sh_cfun_attr_renesas_p, sh_function_arg,
+ sh_function_arg_advance, sh_pass_in_reg_p): New. * config/sh/sh.c
+ (sh_handle_renesas_attribute, sh_promote_prototypes,
+ sh_struct_value_rtx, sh_return_in_memory, sh_builtin_saveregs,
+ sh_setup_incoming_varargs, sh_strict_argument_naming,
+ sh_pretend_outgoing_varargs_named): New decls.
+ (targetm): Add new hooks.
+ (calc_live_regs): Save MACL and MACH if the function has the
+ renesas attribute.
+ (sh_expand_prologue): Support renesas attribute.
+ (sh_builtin_saveregs): Make static.
+ (sh_build_va_list): Support renesas attribute.
+ (sh_va_start): Likewise.
+ (sh_va_arg): Likewise.
+ (sh_promote_prototypes): New.
+ (sh_function_arg): New, moved from sh.h. Support renesas
+ attribute.
+ (sh_function_arg_advance): Likewise.
+ (sh_return_in_memory): Likewise.
+ (sh_strict_argument_naming): Likewise.
+ (sh_pretend_outgoing_varargs_named): Likewise.
+ (sh_struct_value_rtx): New.
+ (sh_attribute): Add renesas attribute.
+ (sh_handle_renesas_attribute): New.
+ (sh_attr_renesas_p, sh_cfun_attr_renesas_p): New.
+ (sh_ms_bitfield_layout_p): Support renesas attribute also.
+ (sh_output_mi_thunk): Pass function to aggregate_value_p. *
+ config/sh/sh.h (TARGET_SWITCHES): Add -mrenesas as an alias for
+ -mhitachi.
+ (STRUCT_VALUE_REGNUM, STRUCT_VALUE, RETURN_IN_MEMORY): Moved to
+ target hooks.
+ (sh_args): Add renesas_abi flag.
+ (INIT_CUMULATIVE_ARGS): Set it. Pass fndecl to aggregate_value_p.
+ (FUNCTION_ARG_ADVANCE, FUNCTION_ARG): Move to sh.c.
+ (PASS_IN_REG_P): Support renesas attribute. Pass DF and TF on the
+ stack for the renesas abi.
+ (STRICT_ARGUMENT_NAMING, PRETEND_OUTGOING_VARARGS_NAMED,
+ SETUP_INCOMING_VARARGS, EXPAND_BUILTIN_SAVEREGS,
+ PROMOTE_PROTOTYPES): Moved to sh.c. * config/sh/sh.md (call): Set
+ call cookie to indicate renesas calls.
+
+2003-09-03 Mostafa Hagog <mustafa@il.ibm.com>
+
+ * gcse.c (replace_one_set): New function.
+ (pre_insert_copy_insn): Change the order of copying
+ to make copy propagation discover additional PRE opportunities.
+
+2003-09-03 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/11700.
+ * simplify-rtx.c (simplify_subreg): Check that the subreg offset
+ of a hard register is representable before trying to simplify it
+ using subreg_hard_regno.
+
+2003-09-04 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (gcc_cv_ld_hidden): Disable unless using GNU ld.
+ * configure: Regenerate.
+
+2003-09-04 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * intl.h (N_): Remove parentheses.
+
+2003-09-03 Bernardo Innocenti <bernie@develer.com>
+
+ * config.gcc (m68k-*-linux*): Remove definition of LINUX_DEFAULT_ELF.
+ * config/i370/linux.h (LINUX_DEFAULT_ELF): Remove unconditional
+ definition and code blocks compiled when not defined.
+ * config/i386/linux.h (LINUX_DEFAULT_ELF): Likewise.
+ * config/i386/linux64.h (LINUX_DEFAULT_ELF): Likewise.
+ * config/sparc/linux.h: (LINUX_DEFAULT_ELF): Likewise.
+ * config/sparc/linux64.h: (LINUX_DEFAULT_ELF): Likewise.
+
+2003-09-03 Jeff Sturm <jsturm@one-point.com>
+
+ * cgraphunit.c (visited_nodes): New static variable.
+ (record_call_1): Use walk_tree with visited_nodes.
+ (cgraph_create_edges): Use walk_tree with visited_nodes.
+ Setup/teardown visited_nodes hashtable.
+
+2003-09-03 Roger Sayle <roger@eyesopen.com>
+
+ * toplev.c (flag_rounding_math): New global variable.
+ (f_options): Add to the list of language independent options.
+ * flags.h (flag_rounding_math): Prototype here.
+ (HONOR_SIGN_DEPENDENT_ROUNDING): Use flag_rounding_math instead.
+ * common.opt (frounding-math): New common command line option.
+ * opts.c (common_handle_option): Handle OPT_frounding_math.
+ (set_fast_math_flags): -ffast-math clears flag_rounding_math.
+
+ * doc/invoke.texi: Document this new command line option.
+
+2003-09-03 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/sol2.h (NO_IMPLICIT_EXTERN_C): Update comment.
+
+2003-09-03 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (c-objc-common.o): Kill gt-c-objc-common.h dependency.
+ * c-decl.c (finish_function): Kill arguments, always use cgraph path.
+ * c-objc-common.c: Kill include of gt-c-objc-common.h
+ (expand_deferred_fns, deffer_fn): Kill function.
+ (deferred_fns): Kill variable.
+ (finish_cdtor): Update finish_function call.
+ (c_objc_common_finish_file): Always call cgraph code.
+ * c-parse.c: Regenerate.
+ * c-parse.y: Regenerate.
+ * c-tree.h (finish_function): Update prototype.
+ * objc-acct.c (build_module_descriptor, finish_method_def):
+ Update call of finish_function.
+ * cgraphunit.c (cgraph_default_inline_p, cgraph_analyze_function): Add
+ forward prototype.
+ (cgraph_finalize_function): In non-unit-at-a-time mode analyze the
+ function and assemble it if needed.
+ (cgraph_finalize_compilation_unit): Do nothing in non-unit-at-a-time
+ mode.
+ (cgraph_optimize): Likewise.
+ (cgraph_expand_function): In non-unit-at-a-time mode keep function body
+ even when it has no inline callees.
+ * c-parse.in: Update calls to finish_function.
+
+2003-09-03 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.h: Handle TARGET_CPU_iwmmxt.
+ Use #error to generate the message if TARGET_DEFAULT is not
+ recognised.
+
+2003-09-03 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (MASK_UNUSED1): Remove.
+ (MASK_XGOT, TARGET_XGOT): Define.
+ (TARGET_SWITCHES): Add an entry for -mxgot.
+ (ASM_SPEC): Map -mxgot to -xgot.
+ * config/mips/mips.c (mips_symbol_insns): Use TARGET_XGOT to decide
+ whether we're using a big-GOT sequences.
+ (mips_legitimize_const_move, mips_expand_call): Likewise.
+ (override_options): Revert 2003-01-09 change.
+ * doc/invoke.texi: Document -mxgot.
+
+2003-09-02 Jason Merrill <jason@redhat.com>
+
+ * config/sol2.h (NO_IMPLICIT_EXTERN_C): Define here.
+ * config/sparc/sol2.h: Not here.
+
+2003-09-02 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_expr): The code following both_summands performs
+ the same task as simplify_gen_binary. Replace all gotos to
+ both_summands with a call to simplify_gen_binary and delete the
+ now unused label.
+
+2003-09-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/7327
+ * config/sparc/sol2.h (NO_IMPLICIT_EXTERN_C): Define.
+
+2003-09-02 Jeff Sturm <jsturm@one-point.com>
+
+ * cgraphunit.c (record_call_1): Use walk_tree_without_duplicates.
+ (cgraph_optimize_function): Set current_function_decl to the
+ fndecl we're integrating from.
+
+2003-09-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def: Break out _Complex math functions into their
+ own category.
+
+2003-09-02 Andreas Jaeger <aj@suse.de>
+
+ * langhooks-def.h (LANG_HOOKS_RTL_EXPAND_STMT): Cast properly.
+
+2003-09-02 Josef Zlomek <zlomekj@suse.cz>
+
+ * cfgbuild.c (compute_outgoing_frequencies): Use NOTE instead of
+ finding the note again.
+
+2003-09-02 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Remove host-specific rewrites of target_alias.
+
+2003-09-01 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (genprogs): Fix typo.
+
+ * Makefile.in (gencheck.o): Remove build commands.
+ (dummy-conditions.o): Likewise.
+ (read-rtl.o): Likewise.
+ (gensupport.o): Likewise.
+ (genconfig$(build_exeext)): Remove rule.
+ (genconfig.o): Remove build commands.
+ (genflags$(build_exeext)): Remove rule.
+ (genflags.o): Remove build commands.
+ (gencodes$(build_exeext)): Remove rule.
+ (gencodes.o): Remove build commands.
+ (genconstants.o): Remove build commands.
+ (genemit$(build_exeext)): Remove rule.
+ (genemit.o): Remove build commands.
+ (genrecog$(build_exeext)): Remove rule.
+ (genrecog.o): Remove build commands.
+ (genextract$(build_exeext)): Remove rule.
+ (genextract.o): Remove build commands.
+ (genpeep$(build_exeext)): Remove rule.
+ (genpeep.o): Remove build commands.
+ (genattr$(build_exeext)): Remove rule.
+ (genattr.o): Remove build commands.
+ (genprognames): New variable.
+ (genprogs): Likewise.
+ (genobjs): Likewise.
+ (genprogs): New rule.
+ (genobjs): Likewise.
+ (genattrtab.o): Remove build commands.
+ (genautomata.o): Likewise.
+ (genoutput$(build_exeext)): Remove rule.
+ (genoutput.o): Remove build commands.
+ (gengenrtl.o): Likewise.
+ (genpreds.o): Likewise.
+ (gengtype.o): Likewise.
+ (genconditions.o): Likewise.
+ (gen-protos.o): Likewise.
+ (scan.o): Likewise.
+ (fix-header.o): Likewise.
+ (scan-decls.o): Likewise.
+ (check-g++): Combine with other check targets.
+ (check-gcc): Likewise.
+ (check-g77): Likewise.
+ (check-objc): Likewise.
+
+2003-09-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Remove host-specific stuff which is unused here
+ since the introduction of config.host.
+
+ * doc/fragments.texi: Mention config.host.
+ * doc/sourcebuild.texi: Mention config.host. Give brief descriptions
+ of config.build, config.host, and config.gcc.
+
+2003-09-01 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (pushdecl): Don't put variables on
+ C_TYPE_INCOMPLETE_VARS of a type unless that type is itself
+ incomplete.
+
+2003-09-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.host: New file.
+ * config.gcc: Remove some host-specific stuff and some
+ logic needed only for repeated invocation.
+ * configure.in: Use config.host.
+ * configure: Regenerate.
+
+2003-09-01 Josef Zlomek <zlomekj@suse.cz>
+
+ * c-typeck.c (build_binary_op): Kill BIT_ANDTC_EXPR.
+ * convert.c (convert_to_integer): Kill BIT_ANDTC_EXPR.
+ * fold-const.c (int_const_binop): Kill BIT_ANDTC_EXPR.
+ (fold): Kill BIT_ANDTC_EXPR and label bit_and.
+ * tree.def (BIT_ANDTC_EXPR): Kill.
+
+2003-08-31 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Remove uses of "for x in .. ${foo}" idiom.
+ * configure: Regenerate.
+
+ * config.gcc: Remove references to install_headers_dir, now unused
+ since introduction of config.build.
+ * config.gcc (i860-*-sysv4*): Don't set unused USG, SVR3 defines.
+
+ * doc/fragments.texi, doc/sourcebuild.texi: Mention new file
+ config.build.
+
+ * config.build: New file.
+ * config.gcc: Remove some build-specific stuff.
+ * configure.in: Use config.build.
+ * configure: Regnerate.
+
+2003-08-31 Steven Bosscher <steven@gcc.gnu.org>
+ Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11823
+ * stmt.c (expand_end_case_type): Only use jump tables for dense
+ switch statements when optimizing for size.
+
+2003-08-31 Olivier Hainque <hainque@act-europe.fr>
+
+ * builtins.c (expand_builtin_setjmp): Use emit_jump to jump around
+ the != 0 case, which ensures pending stack adjustments are flushed.
+
+2003-08-30 Zack Weinberg <zack@codesourcery.com>
+
+ * configure.frag: Delete file.
+ * configure.in: Rename the substitution variables
+ dep_host_xmake_file and dep_tmake_file to xmake_file and
+ tmake_file respectively. Do not expand $srcdir in the
+ value of these; leave that for Make. Introduce a new
+ substitution varaible, all_lang_makefrags, which lists
+ subdirectory Make-lang.in files; exclude these from
+ all_lang_makefiles, which is now only for subdirectory
+ outputs. Do not invoke configure.frag. Do not set nor
+ AC_SUBST_FILE target_overrides, host_overrides, or
+ language_fragments. Create build subdirectories in
+ config.status extra commands.
+ * configure: Regenerate.
+ * Makefile.in: Update substitutions to match changes to
+ configure. Use include directives instead of @-insertions
+ to read in host, target, and language fragments.
+ (Makefile rule): Do not invoke configure.frag. Do not copy
+ config.status to config.run before executing it. Set
+ CONFIG_HEADERS and CONFIG_FILES so that only Makefile gets
+ regenerated.
+ (cstamp-h rule): Set CONFIG_FILES as well as CONFIG_HEADERS.
+
+2003-08-30 Zack Weinberg <zack@codesourcery.com>
+
+ * c-tree.h: Delete COMPARE_DIFFERENT_TU from enumeration.
+ * c-typeck.c (same_translation_unit_p): New function.
+ (comptypes): Use it instead of flags parameter to identify
+ structure types from different translation units.
+ * c-decl.c (duplicate_decls): Always call comptypes with
+ COMPTYPE_STRICT flags argument.
+ (c_reset_state): Set BLOCK_SUPERCONTEXT of the block formed
+ to file_scope_decl.
+
+2003-08-30 Zack Weinberg <zack@codesourcery.com>
+
+ * c-tree.h (C_TYPE_INCOMPLETE_VARS): New macro.
+ * c-decl.c (struct c_scope): Remove "incomplete" field.
+ (pushdecl): Attach variables with incomplete types to
+ the TYPE_MAIN_VARIANT of the incomplete type in question.
+ (finish_struct): Look at C_TYPE_INCOMPLETE_VARS for variables
+ to complete, not at current_scope->incomplete. All such
+ variables do need completion.
+
+2003-08-30 Richard Earnshaw <rearnsha@arm.com>
+ Nicolas Pitre <nico@cam.org>
+
+ * arm/lib1funcs.asm (RETCOND): Delete.
+ (RETLDM): New assembler macro. Use it for returning with ldm/ldr.
+ (ARM_LDIV0, THUMB_LDIV0): Collapse multiple definitions.
+ (__ARM_ARCH__): Move here from ieee754-?f.S.
+ (RET, RETc): Clean up definitions.
+ (DIV_FUNC_END): Renamed from FUNC_END. All uses changed.
+ (FUNC_END): New macro that marks the end of any function.
+ (ARM_FUNC_START): New macro that allows an assembler routine to be
+ implemented in ARM code even if a Thumb-only build.
+ Unconditionally include ieee754-?f.S.
+ * arm/ieee754-df.S: Delete macros moved to lib1funcs.asm.
+ Mark ends of functions.
+ Split into separate conditionally-compiled units.
+ Use RETLDM to return from routines.
+ * arm/ieee754-sf.S: Similarly.
+ * t-arm-elf (LIB1ASMFUNCS): Remove _ieee754_dp and _ieee754_sp.
+ Add _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi
+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2
+ _fixsfsi and _fixunssfsi.
+
+ * arm/ieee754-df.S (__muldf3): Fix bug when result of a
+ multiplication underflows to zero.
+ (__adddf3): Fix bug when using VFP ordering on little-endian
+ processors.
+ (__fixdfsi): Use rrx to extract the carry into a register instead of
+ MRS instruction. Optimize later use of result.
+ * arm/ieee754-sf.S (__fixsfsi): Likewise.
+ (__fixunssfsi): Use a better sequence for handling negative-or-zero.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+
+ * tree-optimize.c: New file.
+ * Makefile.in (OBJS-archive): Add tree-optimize.o.
+ (tree-optimize.o): New.
+ * c-decl.c (store_parm_decls): Use allocate_struct_function.
+ (finish_function): Don't free_after_parsing or free_after_compilation.
+ (set_save_expr_context): Move to tree-optimize.c.
+ (c_expand_body_1): Use tree_rest_of_compilation.
+ * c-lang.c (LANG_HOOKS_RTL_EXPAND_STMT): New.
+ * objc/objc-lang.c (LANG_HOOKS_RTL_EXPAND_STMT): New.
+ * c-objc-common.c (expand_deferred_fns): Don't emit unused inlines;
+ iterate until closure.
+ * langhooks-def.h (LANG_HOOKS_RTL_EXPAND_START,
+ LANG_HOOKS_RTL_EXPAND_STMT, LANG_HOOKS_RTL_EXPAND_END): New.
+ (LANG_HOOKS_RTL_EXPAND_INITIALIZER): New.
+ * langhooks.h (struct lang_hooks_for_rtl_expansion): New.
+ * toplev.h (tree_rest_of_compilation): Declare it.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+
+ * function.h (struct function): Add rtl_inline_init, saved_for_inline.
+ * integrate.c (save_for_inline): Set saved_for_inline.
+ * c-semantics.c (genrtl_scope_stmt): Check it.
+ * toplev.c (wrapup_global_declarations): Check it.
+ (rest_of_handle_inlining): Set and check rtl_inline_init.
+ (rest_of_compilation): Remove out of date comment.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+
+ * function.c (allocate_struct_function): New, split out of ...
+ (prepare_function_start, init_function_start): ... here.
+ * expr.c (init_expr): Use ggc_alloc_cleared.
+ * stmt.c (init_stmt_for_function): Likewise.
+ * tree.h (allocate_struct_function): Declare.
+
+2003-08-29 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Don't use negated character class in shell case
+ clause.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+
+ * function.h (struct function): Move function_frequency and
+ max_jumptable_ents before start of bit field members.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (expand_builtin_constant_p): Check cse_not_expected here,
+ (fold_builtin_constant_p) ... not here.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+
+ * c-tree.h (C_DECL_FILE_SCOPE): Move ...
+ * tree.h (DECL_FILE_SCOPE_P): ... here, and rename.
+ * c-decl.c, c-objc-common.c, c-typeck.c: Update to match.
+
+2003-08-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def: Fix typos.
+ (ATTR_MATHFN_FPROUNDING_STORE): New macro.
+ (BUILT_IN_FREXP, BUILT_IN_FREXPF, BUILT_IN_FREXPL, BUILT_IN_MODF,
+ BUILT_IN_MODFF, BUILT_IN_MODFL, BUILT_IN_REMQUO, BUILT_IN_REMQUOF,
+ BUILT_IN_REMQUOL, BUILT_IN_SINCOS, BUILT_IN_SINCOSF,
+ BUILT_IN_SINCOSL): Use ATTR_MATHFN_FPROUNDING_STORE.
+
+ * builtins.def (BUILT_IN_ERFC, BUILT_IN_ERFCF, BUILT_IN_ERFCL):
+ Use ATTR_MATHFN_FPROUNDING_ERRNO.
+
+2003-08-29 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc (i386-*-vsta): Fix obvious bogosity.
+
+ * fixinc/inclhack.def: Remove special cases for unsupported
+ PTX 1 and PTX 2 (including i[34567]86-sequent-sysv3).
+ * fixinc/fixincl.x: Regenerate.
+
+2003-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (cpp.info): Just state dependencies.
+ (gcc.info): Likewise.
+ (gccint.info): Likewise.
+ (gccinstall.info): Likewise.
+ (cppinternals.info): Likewise.
+ (cpp.dvi): Likewise.
+ (gcc.dvi): Likewise.
+ (gccint.dvi): Likewise.
+ (gccinstall.dvi): Likewise.
+ (cppinternals.dvi): Likewise.
+ (gcov.1): Likewise.
+ (cpp.1): Likewise.
+ (gcc.1): Likewise.
+ (gfdl.7): Likewise.
+ (gpl.7): Likewise.
+ (fsf-funding.7): Likewise.
+ ($(objdir)/%.info): New pattern rule.
+ (%.dvi): Likewise.
+
+2003-08-29 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * Makefile.in (restage1): Pass BOOT_CFLAGS to recursive make.
+ (restage2): Likewise.
+ (restage3): Likewise.
+ (restage4): Likewise.
+ (restageprofile): Likewise.
+ (restagefeedback): Likewise.
+ (bubblestrap): Likewise.
+
+2003-08-29 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Narrow unsupported target match to avoid clobbering
+ i?86-sequent-sysv4*.
+
+2003-08-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (mathfn_built_in): Handle new math builtins.
+
+2003-08-28 Per Bothner <per@bothner.com>
+
+ Fix (hopefully temporary) for breakage caused by my 08-21 patch.
+ * cpplex.c (_cpp_get_fresh_line): Check for null buffer.
+ (_cpp_lex_buffer): Likewise.
+ * cpptrad.c (_cpp_read_logical_line_trad): Likewise.
+
+2003-08-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*mulsi3_sign"): New insn.
+ ("mulsidi3" expander, "mulsi_6432" insn): Remove, replace by ...
+ ("mulsidi3"): ... this new insn.
+ ("umulsidi3"): New insn.
+ ("divmoddi3", "divmodtidi3", "divmodtisi3"): Simplify by using
+ mixed-mode matching constraints.
+ ("udivmodsi4", "udivmoddisi3"): New insns.
+ ("udivsi3", "umodsi3"): Use only in ESA/390 mode.
+
+2003-08-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-types.def (BT_INT_PTR, BT_FLOAT_PTR, BT_DOUBLE_PTR,
+ BT_LONGDOUBLE_PTR, BT_FN_FLOAT_FLOAT_FLOATPTR,
+ BT_FN_DOUBLE_DOUBLE_DOUBLEPTR,
+ BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLEPTR,
+ BT_FN_FLOAT_FLOAT_INTPTR, BT_FN_DOUBLE_DOUBLE_INTPTR,
+ BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR,
+ BT_FN_FLOAT_FLOAT_FLOAT_INTPTR, BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR,
+ BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_INTPTR,
+ BT_FN_VOID_FLOAT_FLOATPTR_FLOATPTR,
+ BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR,
+ BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR): New.
+ * builtins.def (BUILT_IN_FREXP, BUILT_IN_FREXPF, BUILT_IN_FREXPL,
+ BUILT_IN_MODF, BUILT_IN_MODFF, BUILT_IN_MODFL, BUILT_IN_REMQUO,
+ BUILT_IN_REMQUOF, BUILT_IN_REMQUOL, BUILT_IN_SINCOS,
+ BUILT_IN_SINCOSF, BUILT_IN_SINCOSL): New.
+ * tree.c: Assign new type_nodes.
+ * tree.h (tree_index): Add TI_FLOAT_PTR_TYPE, TI_DOUBLE_PTR_TYPE,
+ TI_LONG_DOUBLE_PTR_TYPE, TI_INTEGER_PTR_TYPE.
+ (float_ptr_type_node, double_ptr_type_node,
+ long_double_ptr_type_node, integer_ptr_type_node): New type_nodes.
+
+ * doc/extend.texi: Document new builtins.
+
+2003-08-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-types.def (BT_FN_FLOAT_INT_FLOAT,
+ BT_FN_DOUBLE_INT_DOUBLE, BT_FN_LONGDOUBLE_INT_LONGDOUBLE): New.
+
+ * builtins.def (BUILT_IN_ERF, BUILT_IN_ERFC, BUILT_IN_ERFCF,
+ BUILT_IN_ERFCL, BUILT_IN_ERFF, BUILT_IN_ERFL, BUILT_IN_GAMMA,
+ BUILT_IN_GAMMAF, BUILT_IN_GAMMAL, BUILT_IN_J0, BUILT_IN_J0F,
+ BUILT_IN_J0L, BUILT_IN_J1, BUILT_IN_J1F, BUILT_IN_J1L,
+ BUILT_IN_JN, BUILT_IN_JNF, BUILT_IN_JNL, BUILT_IN_LGAMMA,
+ BUILT_IN_LGAMMAF, BUILT_IN_LGAMMAL, BUILT_IN_SIGNIFICAND,
+ BUILT_IN_SIGNIFICANDF, BUILT_IN_SIGNIFICANDL, BUILT_IN_TGAMMA,
+ BUILT_IN_TGAMMAF, BUILT_IN_TGAMMAL, BUILT_IN_Y0, BUILT_IN_Y0F,
+ BUILT_IN_Y0L, BUILT_IN_Y1, BUILT_IN_Y1F, BUILT_IN_Y1L,
+ BUILT_IN_YN, BUILT_IN_YNF, BUILT_IN_YNL): New.
+
+ * doc/extend.texi: Document new builtins.
+
+2003-08-28 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/mkfixinc.sh: Remove special case code for unsupported
+ variants of i?86, powerpcle, and thumb.
+ * fixinc/mkfixinc.sh: Remove special case code for unsupported
+ arm and hppa variants.
+
+2003-08-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-types.def (BT_FN_INT_FLOAT, BT_FN_INT_DOUBLE,
+ BT_FN_INT_LONGDOUBLE, BT_FN_LONG_FLOAT, BT_FN_LONG_DOUBLE,
+ BT_FN_LONG_LONGDOUBLE, BT_FN_LONGLONG_FLOAT,
+ BT_FN_LONGLONG_DOUBLE, BT_FN_LONGLONG_LONGDOUBLE,
+ BT_FN_FLOAT_FLOAT_LONGDOUBLE, BT_FN_DOUBLE_DOUBLE_LONGDOUBLE,
+ BT_FN_FLOAT_FLOAT_INT, BT_FN_DOUBLE_DOUBLE_INT,
+ BT_FN_LONGDOUBLE_LONGDOUBLE_INT, BT_FN_FLOAT_FLOAT_LONG,
+ BT_FN_DOUBLE_DOUBLE_LONG, BT_FN_LONGDOUBLE_LONGDOUBLE_LONG,
+ BT_FN_FLOAT_FLOAT_FLOAT_FLOAT, BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE,
+ BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE): New.
+
+ * builtins.def (BUILT_IN_ACOS, BUILT_IN_ACOSF, BUILT_IN_ACOSH,
+ BUILT_IN_ACOSHF, BUILT_IN_ACOSHL, BUILT_IN_ACOSL, BUILT_IN_ASIN,
+ BUILT_IN_ASINF, BUILT_IN_ASINH, BUILT_IN_ASINHF, BUILT_IN_ASINHL,
+ BUILT_IN_ASINL, BUILT_IN_ATANH, BUILT_IN_ATANHF, BUILT_IN_ATANHL,
+ BUILT_IN_CBRT, BUILT_IN_CBRTF, BUILT_IN_CBRTL, BUILT_IN_COPYSIGN,
+ BUILT_IN_COPYSIGNF, BUILT_IN_COPYSIGNL, BUILT_IN_COSH,
+ BUILT_IN_COSHF, BUILT_IN_COSHL, BUILT_IN_DREM, BUILT_IN_DREMF,
+ BUILT_IN_DREML, BUILT_IN_EXP10, BUILT_IN_EXP10F, BUILT_IN_EXP10L,
+ BUILT_IN_EXP2, BUILT_IN_EXP2F, BUILT_IN_EXP2L, BUILT_IN_EXPM1,
+ BUILT_IN_EXPM1F, BUILT_IN_EXPM1L, BUILT_IN_FDIM, BUILT_IN_FDIMF,
+ BUILT_IN_FDIML, BUILT_IN_FMA, BUILT_IN_FMAF, BUILT_IN_FMAL,
+ BUILT_IN_FMAX, BUILT_IN_FMAXF, BUILT_IN_FMAXL, BUILT_IN_FMIN,
+ BUILT_IN_FMINF, BUILT_IN_FMINL, BUILT_IN_HYPOT, BUILT_IN_HYPOTF,
+ BUILT_IN_HYPOTL, BUILT_IN_ILOGB, BUILT_IN_ILOGBF, BUILT_IN_ILOGBL,
+ BUILT_IN_LDEXP, BUILT_IN_LDEXPF, BUILT_IN_LDEXPL, BUILT_IN_LLRINT,
+ BUILT_IN_LLRINTF, BUILT_IN_LLRINTL, BUILT_IN_LLROUND,
+ BUILT_IN_LLROUNDF, BUILT_IN_LLROUNDL, BUILT_IN_LOG10,
+ BUILT_IN_LOG10F, BUILT_IN_LOG10L, BUILT_IN_LOG1P, BUILT_IN_LOG1PF,
+ BUILT_IN_LOG1PL, BUILT_IN_LOG2, BUILT_IN_LOG2F, BUILT_IN_LOG2L,
+ BUILT_IN_LOGB, BUILT_IN_LOGBF, BUILT_IN_LOGBL, BUILT_IN_LRINT,
+ BUILT_IN_LRINTF, BUILT_IN_LRINTL, BUILT_IN_LROUND,
+ BUILT_IN_LROUNDF, BUILT_IN_LROUNDL, BUILT_IN_NEXTAFTER,
+ BUILT_IN_NEXTAFTERF, BUILT_IN_NEXTAFTERL, BUILT_IN_NEXTTOWARD,
+ BUILT_IN_NEXTTOWARDF, BUILT_IN_NEXTTOWARDL, BUILT_IN_POW10,
+ BUILT_IN_POW10F, BUILT_IN_POW10L, BUILT_IN_REMAINDER,
+ BUILT_IN_REMAINDERF, BUILT_IN_REMAINDERL, BUILT_IN_RINT,
+ BUILT_IN_RINTF, BUILT_IN_RINTL, BUILT_IN_SCALB, BUILT_IN_SCALBF,
+ BUILT_IN_SCALBL, BUILT_IN_SCALBLN, BUILT_IN_SCALBLNF,
+ BUILT_IN_SCALBLNL, BUILT_IN_SCALBN, BUILT_IN_SCALBNF,
+ BUILT_IN_SCALBNL, BUILT_IN_SINH, BUILT_IN_SINHF, BUILT_IN_SINHL,
+ BUILT_IN_TANH, BUILT_IN_TANHF, BUILT_IN_TANHL): New.
+
+ * doc/extend.texi: Document new builtins.
+
+2003-08-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (legitmate_constant_p): Use LARL on
+ zSeries machines even in 31-bit addressing mode.
+ (legitimate_reload_constant_p): Likewise.
+ (legitimize_pic_address): Likewise.
+ (legitimize_tls_address): Likewise.
+ (s390_split_branches): Likewise.
+ (s390_dump_pool): Likewise.
+ (s390_mainpool_finish): Likewise.
+ (s390_chunkify_start): Likewise.
+ (s390_select_rtx_section): Likewise.
+ * config/s390/s390.md ("doloop_si"): Likewise.
+ ("pool_start_31", "pool_end_31"): Likewise.
+ ("pool_start_64", "pool_end_64"): Likewise.
+ ("main_base_31_small", "main_base_31_large"): Likewise.
+ ("main_base_64"): Likewise.
+ ("reload_base_31", "reload_base_64"): Likewise.
+ ("*movsi_larl"): New insn.
+ ("cjump", "icjump"): Use long branches on zSeries machines.
+ ("jump"): Likewise.
+ ("call"): Use BRASL on zSeries machines.
+ ("call_value", "call_value_tls"): Likewise.
+ ("brasl", "bras", "basr_64", "basr_31", "bas_64", "bas_31"): Remove
+ and replace by ...
+ ("*bras", "*brasl", "*basr") ... these new insns.
+ ("brasl_r", "bras_r", "basr_64_r", "basr_31_r", "bas_64_r",
+ "bas_31_r"): Remove and replace by ...
+ ("*bras_r", "*brasl_r", "*basr_r") ... these new insns.
+ ("brasl_tls", "bras_tls", "basr_64_tls", "basr_31_tls",
+ "bas_64_tls", "bas_31_tls"): Remove and replace by ...
+ ("*bras_tls", "*brasl_tls", "*basr_tls") ... these new insns.
+ ("*return_si", "*return_di"): Remove and replace by ...
+ ("*return"): ... this new insn.
+ ("rotlsi3"): Allow on zSeries machines.
+
+ * config/s390/s390.c (legitimize_reload_constant_p): Use
+ LL/LH type instructions in z/Architecture mode.
+ * config/s390/s390.md ("*movsi_lli"): Likewise.
+ ("*andsi3_ni", "*andhi3_ni", "*andqi3_ni"): Likewise.
+ ("*iorsi3_ni", "*iorhi3_ni", "*iorqi3_ni"): Likewise.
+ ("*extendqisi2"): Use LB in z/Architecture mode.
+ ("*zero_extendqisi2_64", "*zero_extendqisi2_31"): Use LLGC in
+ z/Architecture mode.
+ ("zero_extendqihi2", "*zero_extendqihi2_64", "*zero_extendqihi2_31"):
+ Likewise.
+
+ * config/s390/s390.md ("*tmdi_ext"): Allow in both 64-bit
+ and 31-bit mode.
+ ("ptr_extend"): Allow only in 64-bit mode.
+
+2003-08-27 Daniel Jacobowitz <drow@mvista.com>
+
+ * gcc.c (STANDARD_EXEC_PREFIX, STANDARD_STARTFILE_PREFIX)
+ (TOOLDIR_BASE_PREFIX, STANDARD_BINDIR_PREFIX): Remove unnecessary
+ definitions.
+ (main): Only use standard_startfile_prefix if native.
+ * doc/tm.texi (STANDARD_STARTFILE_PREFIX): Update.
+
+2003-08-27 Per Bothner <pbothner@apple.com>
+
+ * cpperror.c (print_location): Don't check for !pfile->buffer. That
+ test fails following my 08-21 change, and it seems unnecessary anyway.
+ (cpp_error): Likewise.
+
+2003-08-27 Jason Merrill <jason@redhat.com>
+
+ * real.c (do_multiply): Initialize with memset.
+
+2003-08-27 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcov.c (typedef struct arc_info): New field cs_count.
+ (accumulate_line_counts): Find cycles correctly.
+
+2003-08-27 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (struct machine_function): Remove member
+ literal_pool_label.
+ (s390_optimize_prolog): Replace TEMP_REG argument with
+ TEMP_USED and BASE_USED. Do not check get_pool_size ().
+ (general_s_operand): Accept all immediates before reload if
+ ALLOW_IMMEDIATE. If not ALLOW_IMMEDIATE, reject literal pool
+ references.
+ (s390_output_symbolic_const): Remove UNSPEC_LTREL_OFFSET handling.
+ (find_constant_pool_ref): Ignore UNSPECV_POOL_ENTRY insns.
+ (s390_alloc_pool): New function.
+ (s390_new_pool): Call it.
+ (s390_dump_pool): Add REMOTE_LABEL argument.
+ (s390_chunkify_start): Add BASE_REG argument. Do not check
+ get_pool_size ().
+ (s390_chunkify_finish): Add BASE_REG argument. Adapt
+ s390_dump_pool call.
+ (s390_pool_count, s390_nr_constants): Remove.
+ (s390_output_constant_pool): Remove.
+ (s390_mainpool_start): New function.
+ (s390_mainpool_finish): New function.
+ (s390_mainpool_cancel): New function.
+ (s390_reorg): Implement main literal pool handling.
+ (s390_emit_prologue): Emit main_pool placeholder instead of
+ literal_pool_31 / literal_pool_64 insns.
+ * config/s390/s390.h (s390_pool_count, s390_nr_constants): Remove.
+ (ASM_OUTPUT_POOL_PROLOGUE, ASM_OUTPUT_SPECIAL_POOL_ENTRY): Remove.
+ * config/s390/s390.md (UNSPEC_MAIN_BASE): New symbolic constant.
+ ("main_base_31_small", "main_base_31_large"): New insns.
+ ("main_base_64", "main_pool"): New insns.
+ ("literal_pool_31", "literal_pool_64"): Remove.
+
+2003-08-27 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (ptx_netswap): New disabled fix, ported from
+ fixinc.ptx.
+ * fixinc/inclhack.def (undefine_null): Don't generate \r characters.
+ Prettify a little.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-08-27 Richard Earnshaw <rearnsha@arm.com>
+
+ * lib1funcs.asm (L_ieee754_sp): New. Include ieee754-sf.S.
+ (L_ieee754_dp): New. Include ieee754-df.S.
+ * arm/ieee754-sf.S: Rework to allow interworking, calling from Thumb,
+ and compilation in apcs-26 mode.
+ * arm/ieee754-df.S: Likewise.
+ * t-arm-elf (DPBIT, FPBIT, fp-bit.c dp-bit.c): Delete rules
+ (LIB1ASMFUNCS): Add _ieee754_sp and _ieee754_dp targets.
+
+2003-08-27 Nicolas Pitre <nico@cam.org>
+
+ * arm/ieee754-sf.S: New.
+ * arm/ieee754-df.S: New.
+
+2003-08-27 Jakub Jelinek <jakub@redhat.com>
+
+ * builtins.c (expand_builtin_expect_jump): Save pending_stack_adjust
+ and restore it if returning NULL.
+
+2003-08-27 Richard Sandiford <rsandifo@redhat.com>
+
+ * calls.c (initialize_argument_information): If an argument has no
+ stack space associated with it, and BLOCK_REG_PADDING is defined,
+ use it to decide at which end the argument should be padded.
+ * function.c (assign_parms): Allocate BLKmode stack slots.
+ * config/mips/mips-protos.h (mips_pad_arg_upward): Declare.
+ (mips_pad_reg_upward): Declare.
+ * config/mips/mips.h (PAD_VARARGS_DOWN): Use FUNCTION_ARG_PADDING.
+ (CUMULATIVE_ARGS): Remove num_adjusts and adjusts.
+ (FUNCTION_ARG_PADDING): Use mips_pad_arg_upward.
+ (BLOCK_REG_PADDING): Use mips_pad_reg_upward.
+ * config/mips/mips.c (struct mips_arg_info): Remove struct_p.
+ (mips_expand_call): Remove code for generating structure shifts.
+ (mips_arg_info): Don't set struct_p. Don't set fpr_p for non-float
+ types unless using the EABI.
+ (function_arg_advance): Don't generate shift instructions.
+ (function_arg): Don't return them. Don't short-circuit the
+ check for double structure chunks for DFmode arguments.
+ (mips_pad_arg_upward, mips_pad_reg_upward): New functions.
+ (mips_expand_prologue): Remove code to emit structure shifts.
+ * config/mips/irix6-libc-compat.c: Remove workarounds for buggy
+ structure passing (inet_ntoa, inet_lnaof, inet_netof). Update
+ comments to say that only structure returns are a problem.
+
+2003-08-26 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/tests/base/string.h, fixinc/tests/base/sys/regset.h:
+ Fix to match produced versions.
+ * fixinc/inclhack.def (longlong_t): New disabled test, ported
+ from fixinc.svr4.
+ * fixinc/inclhack.def (ptx_pwd_h): New disabled fix, ported
+ from fixinc.ptx.
+ * fixinc/inclhack.def (ptx_sys_mc_param_h): New disabled fix,
+ ported from fixinc.ptx.
+
+2003-08-26 Per Bothner <pbothner@apple.com>
+
+ * cpplib.h (struct cpp_token): Change type of field line to fileline.
+ (cpp_error_with_line): Use fileline for appropriate parameter.
+ * cpphash.h (struct cpp_macro): Change type of field line to fileline.
+ (struct cpp_reader): Likewise for fields line and directive_line.
+ (_cpp_begin_message): Use fileline for appropriate parameter.
+ * cpperror.c (print_location, _cpp_begin_message, cpp_error_with_line,
+ cpp_error): Use fileline for appropriate parameters and variables.
+ (print_location): New local lin, since it is not a fileline.
+
+2003-08-26 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/12002
+ * tree.h (SCALAR_FLOAT_TYPE_P, COMPLEX_FLOAT_TYPE_P): New macros.
+ (FLOAT_TYPE_P): Define in terms of these two new macros.
+ * fold-const.c (fold <PLUS_EXPR>): Don't convert x+x into x*2.0
+ for complex floating point types.
+
+2003-08-26 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (emit_prologue): Don't check literal pool size.
+ * config/s390/s390.h (ASM_OUTPUT_SPECIAL_POOL_ENTRY): Call
+ s390_output_pool_entry.
+
+2003-08-26 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (svr4_preproc_lint_on,
+ svr4_preproc_lint_off, svr4_preproc_machine): New disabled
+ fixes, ported from fixinc.svr4.
+
+2003-08-26 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/install.texi (Prerequisites): Mention GNU make requirement.
+
+ * Makefile.in (AR_FOR_TARGET): Export it.
+ (AR_CREATE_FOR_TARGET): Likewise.
+ (AR_FLAGS_FOR_TARGET): Likewise.
+ (AR_EXTRACT_FOR_TARGET): Likewise.
+ (AWK): Likewise.
+ (BUILD_PREFIX): Likewise.
+ (BUILD_PREFIX_1): Likewise.
+ (DESTDIR): Likewise.
+ (GCC_FOR_TARGET): Likewise.
+ (INCLUDES): Likewise.
+ (INSTALL_DATA): Likewise.
+ (LIB1ASMSRC): Likewise.
+ (LIBGCC2_CFLAGS): Likewise.
+ (MACHMODE_H): Likewise.
+ (NM_FOR_TARGET): Likewise.
+ (RANLIB_FOR_TARGET): Likewise.
+ (libsubdir): Likewise.
+ (slibdir): Likewise.
+ (ORDINARY_FLAGS_TO_PASS): Remove stuff that we're
+ exporting.
+ (libgcc.a): Don't pass them here.
+ (stmp-multilib): Or here.
+ (install-libgcc): Or here.
+ (install-multilib): Or here.
+ (POSTSTAGE1_FLAGS_TO_PASS): Or here.
+ (stage1_build): Or here.
+
+2003-08-26 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.md ("*llgt_sisi", "*llgt_sisi_split", "*llgt_didi",
+ "*llgt_didi_split", "*llgt_sidi", "*llgt_sidi_split"): New insns.
+
+2003-08-26 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.md ("*fmadddf", "*fmsubdf",
+ "*fmaddsf", "*fmsubsf"): New insns.
+
+2003-08-26 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold <MULT_EXPR>): Optimize (C1/X)*C2 into
+ (C1*C2)/X when unsafe math optimizations are allowed.
+ (fold <RDIV_EXPR>): Optimize C1/(X*C2) into (C1/C2)/X with unsafe
+ math optimizations. Minor code clean-ups. Recursively call
+ fold when constructing sub-expressions.
+
+2003-08-26 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (fold_builtin_bitop): New function to perform constant
+ folding of ffs, clz, ctz, popcount and parity builtin functions
+ and their long and long long variants (such as ffsl and ffsll).
+ (fold_builtin): fold_builtin_bitop when appropriate.
+ * simplify-rtx.c (simplify_unary_operation): Honor both
+ CLZ_DEFINED_VALUE_AT_ZERO and CTZ_DEFINED_VALUE_AT_ZERO when
+ evaluating clz and ctz at compile-time, for operands wider
+ than HOST_WIDE_INT.
+
+2003-08-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * builtins.c (build_function_call_expr): Don't set
+ TREE_SIDE_EFFECTS here.
+ * expr.c (emit_block_move_via_libcall): Likewise.
+ (clear_storage_via_libcall): Likewise.
+ * tree.c (build): Set TREE_SIDE_EFFECTS for non-const, non-pure
+ CALL_EXPRs.
+
+ * gcse.c (is_too_expensive): New function.
+ (gcse_main, delete_null_pointer_checks, bypass_jumps): Use it.
+
+2003-08-25 Zack Weinberg <zack@codesourcery.com>
+
+ * config.gcc (hppa*-*-hpux11*, ia64*-*-hpux*): Remove
+ commented-out logic to use DCE threads (if present), add
+ support for POSIX threads.
+ * config/ia64/hpux.h: Define CPP_SPEC to set appropriate
+ #defines for -pthread. Add -lpthread to LIB_SPEC when
+ -pthread. In both cases take -mt as a synonym for -pthread
+ for acc compatibility.
+ Define GTHREAD_USE_WEAK to 0.
+ * config/pa/pa-hpux11.h: Likewise for CPP_SPEC and LIB_SPEC.
+ Remove old logic for DCE threads from LIB_SPEC.
+ * config/pa/pa64-hpux.h: Define GTHREAD_USE_WEAK to 0.
+
+2003-08-25 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_mathfn): Rearrange so that we only
+ return 0 for invalid argument types. Instead drop through to a
+ call of expand_call at the bottom of function. If op is SQRT,
+ try attaching a SQRT rtx as the REQ_EQUAL note of the libcall.
+
+2003-08-25 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.c (ia64_expand_tls_address): Properly truncate
+ result when op0 is SImode.
+
+2003-08-25 Nathanael Nerode <neroden@twcny.rr.com>
+
+ * fixinc/inclhack.def (svr4_sighandler_type): New fix, ported
+ from fixinc.svr4.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/sys/signal.h: Regenerate.
+
+2003-08-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * combine.c (simplify_comparison): Re-enable widening of comparisons
+ with non-paradoxical subregs of non-REG expressions.
+
+2003-08-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * combine.c (distribute_notes): Handle REG_ALWAYS_RETURN.
+
+2003-08-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * combine.c (combine_simplify_rtx): Fix RTL sharing bug.
+
+2003-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.h (pp_maybe_newline_and_indent): New macro.
+ * c-pretty-print.h (c_pretty_printer): Now typedef to the
+ structure. Be consistent with pretty-print.h abd cxx-pretty-print.h
+ (struct c_pretty_print_info): Document. Add new fields.
+ (pp_type_specifier_seq): Rename from pp_c_type_specifier.
+ (pp_direct_abstract_declarator): New macro.
+ (pp_ptr_operator): Likewise.
+ (pp_simple_type_specifier): Likewise.
+ (pp_expression): Likewise.
+ (pp_parameter_list): Rename from pp_parameter_declaration.
+ * c-pretty-print.c (pp_c_whitespace): Now a function.
+ (pp_c_left_paren): Likewise.
+ (pp_c_right_paren): Likewise.
+ (pp_c_dot): Likewise.
+ (pp_c_ampersand): Likewise.
+ (pp_c_arrow): Likewise.
+ (pp_c_semicolon): Likewise.
+ (pp_c_type_cast): New function.
+ (pp_c_space_for_pointer_operator): Likewise.
+ (pp_c_call_argument_list): Likewise.
+ (pp_c_cv_qualifier): Adjust prototype.
+ (pp_c_type_qualifier_list): Likewise.
+ (pp_c_pointer): Likewise. Handle REFERENCE_TYPE here.
+ (pp_c_type_specifier): Rename from pp_c_simple_type_specifier.
+ Adjust to follow standard grammar.
+ (pp_c_specifier_qualifier_list): Adjusr prototype. Handle
+ REFERENCE_TYPE. Tidy.
+ (pp_c_parameter_type_list): Adjust prototype. Tidy.
+ (pp_c_parameter_declaration): Remove.
+ (pp_c_abstract_declarator): Adjust prototype.
+ (pp_c_direct_abstract_declarator): Likewise.
+ (pp_c_type_id): Likewise.
+ (pp_c_storage_class_specifier): Likewise.
+ (pp_c_function_specifier): Likewise.
+ (pp_c_declaration_specifiers): Likewise.
+ (pp_c_direct_declarator): Likewise.
+ (pp_c_declarator): Likewise.
+ (pp_c_declarator): Likewise.
+ (pp_c_declaration): Likewise.
+ (pp_c_attributes): Likewise. Tidy.
+ (pp_c_function_definition): Adjust prototype.
+ (pp_c_char): Likewise.
+ (pp_c_string_literal): Likewise.
+ (pp_c_integer_constant): Likewise.
+ (pp_c_character_constant): Likewise.
+ (pp_c_bool_constant): Likewise.
+ (pp_c_enumeration_constant): Likewise.
+ (pp_c_floating_constant): Likewise.
+ (pp_c_constant): Likewise.
+ (pp_c_identifier): Likewise.
+ (pp_c_primary_expression): Likewise. Remove TARGET_EXPR case. Tidy.
+ (pp_c_initializer): Adjust prototype.
+ (pp_c_init_declarator): Likewise.
+ (pp_c_initializer_list): Likewise.
+ (pp_c_id_expression): Likewise.
+ (pp_c_postfix_expression): Likewise.
+ (pp_c_expression_list): Likewise.
+ (pp_c_unary_expression): Likewise.
+ (pp_c_cast_expression): Likewise.
+ (pp_c_multiplicative_expression): Likewise.
+ (pp_c_additive_expression): Likewise.
+ (pp_c_shift_expression): Likewise.
+ (pp_c_relational_expression): Likewise.
+ (pp_c_equality_expression): Likewise.
+ (pp_c_and_expression): Likewise.
+ (pp_c_exclusive_or_expression): Likewise.
+ (pp_c_inclusive_or_expression): Likewise.
+ (pp_c_logical_and_expression): Likewise.
+ (pp_c_logical_or_expression): Likewise.
+ (pp_c_conditional_expression): Likewise.
+ (pp_c_assignment_expression): Likewise.
+ (pp_c_expression): Likewise. Tidy.
+ (pp_c_statement): Likewise. Document.
+ (pp_c_pretty_printer_init): Adjust prototype. Tidy.
+
+ * c-lang.c (c_initialize_diagnostics): Update.
+ * c-common.h (strip_pointer_operator): Declare.
+ * c-common.c (strip_pointer_operator): Define.
+
+2003-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8795
+ * tree.h (build_method_type_directly): Declare.
+ * c-common.c (handle_vector_size_attributes): Handle METHOD_TYPEs.
+ (vector_size_helper): Likewise.
+ * tree.c (build_method_type_directly): New function.
+ (build_method_type): Use it.
+
+2003-08-24 Richard Henderson <rth@redhat.com>
+
+ * config/i386.i386.c (ix86_return_in_memory): Reformat. Return true
+ for 16-byte vector modes if sse not enabled; warn for abi change.
+ (ix86_value_regno): Only return xmm0 for 16-byte vector types.
+
+2003-08-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * rtlanal.c (may_trap_p): Simplify an integer comparison.
+
+2003-08-24 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (AAB_svr4_replace_byteorder): Enhance
+ comment. Enable for DYNIX/ptx systems (when they switch to
+ regular fixincludes).
+ * fixinc/fixincl.x: Regenerate.
+
+2003-08-23 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/t-i860: New.
+ * config.gcc (i860-*-sysv4*): Add t-i860 to tmake_file.
+
+2003-08-23 Jakub Jelinek <jakub@redhat.com>
+
+ * c-decl.c (pushdecl): Only put decls which finish_struct will do
+ something about onto incomplete chain.
+ (finish_struct): If not removing type from incomplete
+ list, update prev.
+
+2003-08-20 Jan Hubicka <jh@suse.cz>
+
+ PR target/11369
+ * i386.c (ix86_expand_carry_flag_compare): Validate operand.
+
+ PR target/11031
+ * i386.c (const_0_to_3_operand, const_0_to_7_operand,
+ const_0_to_15_operand, const_0_to_255_operand): New predicates.
+ * i386.h (PREDICATE_CODES): Add these.
+ * i386.c (pinsrw and pextrw patterns): Use them.
+
+ PR target/10984
+ * i386.c (ix86_expand_binop_builtin): Behave sanely for VOIDmodes.
+
+ PR target/8869
+ * expr.c (convert_modes): Deal properly with integer to vector
+ constant conversion.
+
+ PR target/8871
+ * i386.md (zero_extendsidi2*): Add MMX and SSE alternatives.
+
+2003-08-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h (LOAD_EXTEND_OP): Remove.
+ * config/s390/s390.md ("movhi"): New expander; old insn renamed to ...
+ ("*movhi"): ... this.
+ ("movqi", "*movqi"): Likewise.
+ ("movqi_64"): Remove.
+ ("*zero_extendhisi2_31"): Change predicate to s_operand.
+
+2003-08-23 Dale Johannesen <dalej@apple.com>
+ * calls.c (emit_library_call_value_1): Fix obvious errors in
+ arguments to emit_group_store.
+
+2003-08-23 Jason Eckhardt <jle@rice.edu>
+
+ * calls.c (emit_library_call_value_1): Remove code related
+ to LIBGCC_NEEDS_DOUBLE.
+ * config/stormy16/stormy16.h: Remove mention of LIBGCC_NEEDS_DOUBLE.
+ * doc/tm.texi: Likewise.
+ * system.h: Poison the LIBGCC_NEEDS_DOUBLE macro.
+
+2003-08-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/linux64.h (STARTFILE_PREFIX_SPEC): Remove.
+
+2003-08-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_setup_incoming_varargs): Handle o32 and o64
+ as well. Put memory references in the varargs alias set.
+ (mips_expand_prologue): Remove varargs handling from here.
+
+2003-08-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_expand_movstr, s390_expand_clrstr,
+ s390_expand_cmpmem, s390_output_constant_pool, s390_build_va_list,
+ s390_function_profiler, s390_output_mi_thunk): Use ISO C syntax
+ for function pointer calls.
+ * config/s390/s390.md ("*negdi2_31"): Likewise.
+
+2003-08-23 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (apply_distributive_law): Correct comment.
+
+2003-08-23 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/i860.h: Remove comment mentioning LIBGCC_NEEDS_DOUBLE.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/i860.c (i860_build_va_list): Create the va_decl
+ declaration. Document the va_list structure.
+ (i860_va_start): Initialize the va_list structure.
+ (i860_va_arg): Rewrite completely.
+ * config/i860/i860.h (LIBGCC_NEEDS_DOUBLE): Don't define.
+ * config/i860/varargs.asm: Do not allocate or initialize
+ a va_list. Return the address of the register save area.
+
+2003-08-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/iq2000/iq2000.c: Fix comment typos.
+ * config/iq2000/iq2000.md: Likewise.
+
+2003-08-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/iq2000/iq2000.c: Follow spelling conventions.
+ * config/iq2000/iq2000.h: Likewise.
+ * config/mn10300/mn10300.c: Likewise.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/i860.c (output_move_double): Don't set latehalf
+ to zero for CONST_INT (since it could be, e.g., -1).
+
+ * config/i860/i860.h (REMSI3_LIBCALL): Replace this macro...
+ (MODSI3_LIBCALL): ...with this one.
+ (UREMSI3_LIBCALL): Replace this macro...
+ (UMODSI3_LIBCALL): ...with this one.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/i860-protos.h (output_delay_insn): Remove prototype.
+ (output_delayed_branch): Remove prototype.
+ (single_insn_src_p): Remove prototype.
+ * config/i860/i860.c (single_insn_src_p): Remove function.
+ (output_delayed_branch): Remove function.
+ (output_delay_insn): Remove function.
+ (va_start): Remove unconditional test and dead code, re-format.
+ Fix coding style and spelling problems in various comments.
+ * config/i860/i860.md (UNSPECV_BLOCKAGE): Define constant...
+ (blockage pattern): ...and use it here.
+ (all define_peephole patterns related to delayed branches): Remove.
+ Fix coding style and spelling problems in various comments.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/i860.c: Replace all occurrences of 'GNU CC' with 'GCC'.
+ Remove all uses of the PARAMS macro. Remove superflous prototypes.
+ Convert all function definitions from traditional to ISO C90 syntax.
+ * config/i860/i860-protos.h: Replace all occurrences of 'GNU CC'
+ with 'GCC'. Remove all uses of the PARAMS macro.
+ * config/i860/i860.h: Replace all occurrences of 'GNU CC' with 'GCC'.
+ * config/i860/i860.md: Likewise.
+ * config/i860/sysv4.h: Likewise.
+ * config/i860/varargs.asm: Likewise.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * config/i860/i860-protos.h (i860_va_start): Remove 'stdarg_p'
+ argument.
+ (tdesc_section): Add prototype.
+ Update copyright dates.
+ * config/i860/i860.c: Include coretypes.h, tm.h, and toplev.h.
+ (TARGET_ASM_FUNCTION_PROLOGUE): Move definition to end of file.
+ (TARGET_ASM_FUNCTION_EPILOGUE): Likewise.
+ (targetm): Likewise.
+ (i860_output_function_prologue): Substitute HOST_WIDE_INT_PRINT_DEC
+ for '%d' where necessary.
+ (i860_va_start): Remove 'stdarg_p' argument. Make conditional checks
+ on 'stdarg_p' unconditional. Divide current_function_args_info.ints
+ by UNITS_PER_WORD when referencing (likewise for .floats).
+ (I860_SVR4_VARARGS): Rename...
+ (I860_SVR4_VA_LIST): ...to this.
+ Call build() with 't' rather than 'field'.
+ (i860_rtx_costs): New function.
+ (TARGET_RTX_COSTS): Define.
+ (i860_internal_label): New function.
+ (TARGET_ASM_INTERNAL_LABEL): Define.
+ (i860_file_start): New function.
+ Update copyright dates.
+ * config/i860/i860.h (CPP_PREDEFINES): Remove.
+ (TARGET_CPU_CPP_BUILTINS): Define.
+ (EXPAND_BUILTIN_VA_START): Remove 'stdarg' argument.
+ (CONST_COSTS): Remove (and move code to i860_rtx_costs).
+ (ASM_FILE_START): Remove.
+ (ASM_FILE_START_1): Remove.
+ (ASM_GLOBALIZE_LABEL): Remove.
+ (ASM_OUTPUT_INTERNAL_LABEL): Remove.
+ (ASM_OUTPUT_CASE_LABEL): Replace call of ASM_OUTPUT_INTERNAL_LABEL
+ with targetm.asm_out.internal_label.
+ Update copyright dates.
+ * config/i860/sysv4.h (USER_LABEL_PREFIX): Define.
+ (CPP_PREDEFINES): Remove.
+ (TARGET_OS_CPP_BUILTINS): Define.
+ (GLOBAL_ASM_OP): Define.
+ (ASM_FILE_START): Remove.
+ (TARGET_ASM_FILE_START_FILE_DIRECTIVE): Define.
+ (TARGET_ASM_FILE_START): Define.
+ Update copyright dates.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * gcc/config.gcc (i860-*-sysv4*): Add target.
+ * config/i860/i860-protos.h: New.
+ * config/i860/i860.c: New.
+ * config/i860/i860.h: New.
+ * config/i860/i860.md: New.
+ * config/i860/sysv4.h: New.
+ * config/i860/varargs.asm: New.
+ * config/i860/x-sysv4: New.
+
+2003-08-22 Jason Eckhardt <jle@rice.edu>
+
+ * config/pa/pa.c: Replace 'GNU CC' with 'GCC'.
+ Remove all uses of PARAMS macro.
+ Convert all function definitions to ISO C90 syntax.
+ * config/pa/elf.h: Replace 'GNU CC' with 'GCC'.
+ * config/pa/fptr.c: Likewise.
+ * config/pa/lib2funcs.asm: Likewise.
+ * config/pa/long_double.h: Likewise.
+ * config/pa/milli64.S: Likewise.
+ * config/pa/pa-64.h: Likewise.
+ * config/pa/pa-hpux.h: Likewise.
+ * config/pa/pa-hpux10.h: Likewise.
+ * config/pa/pa-hpux11.h: Likewise.
+ * config/pa/pa-linux.h: Likewise.
+ * config/pa/pa-modes.def: Likewise.
+ * config/pa/pa-osf.h: Likewise.
+ * config/pa/pa-pro-end.h: Likewise.
+ * config/pa/pa.md: Likewise.
+ * config/pa/pa32-linux.h: Likewise.
+ * config/pa/pa64-linux.h: Likewise.
+ * config/pa/pa64-hpux.h: Likewise.
+ * config/pa/pa64-regs.h: Likewise.
+ * config/pa/quadlib.c: Likewise.
+ * config/pa/rtems.h: Likewise.
+ * config/pa/pa-protos.h: Replace 'GNU CC' with 'GCC' and remove
+ all uses of the PARAMS macro.
+ * config/pa/pa.h: Likewise.
+ * config/pa/som.h: Likewise.
+
+ * config/iq2000/iq2000.c: Replace 'GNU CC' with 'GCC'.
+ Remove all uses of PARAMS macro.
+ Convert all function definitions to ISO C90 syntax.
+ * config/iq2000-protos.h: Replace 'GNU CC' with 'GCC'.
+ Remove all uses of PARAMS macro.
+ * config/iq2000.h: Remove all uses of PARAMS macro.
+ * config/iq2000/iq2000.md: Replace 'GNU CC' with 'GCC'.
+
+2003-08-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_output_pool_entry): Declare.
+ * config/s390/s390.c (gen_consttable): Remove.
+ (s390_dump_pool): Use UNSPECV_POOL_ENTRY for pool entry insns.
+ (s390_output_pool_entry): New function.
+ * config/s390/s390.md (UNSPECV_POOL_QI, UNSPECV_POOL_HI,
+ UNSPECV_POOL_SI, UNSPECV_POOL_DI, UNSPECV_POOL_TI,
+ UNSPECV_POOL_SF, UNSPECV_POOL_DF): Remove, replace by ...
+ (UNSPECV_POOL_ENTRY): ... this new constant.
+ ("consttable_qi", "consttable_hi", "consttable_si", "consttable_di",
+ "consttable_ti", "consttable_sf", "consttable_df"): Remove ...
+ ("*pool_entry"): ... and replace by this new insn.
+ ("literal_pool_31"): Do not emit anchor label if pool empty.
+
+ * config/s390/s390.c (struct machine_function): Add save_return_addr_p.
+ (s390_optimize_prolog): Save RETURN_REGNUM if save_return_addr_p.
+ (s390_fixup_clobbered_return_reg): Remove.
+ (s390_reorg): Don't call s390_fixup_clobbered_return_reg.
+ (s390_return_addr_rtx): Always retrieve return address from save area
+ slot. Use save_return_addr_p to force slot to be filled.
+ (s390_emit_prologue): Remove has_hard_reg_initial_val test.
+
+2003-08-22 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.h (MASK_FIX_SB1, TARGET_FIX_SB1): New defines.
+ (TARGET_SWITCHES): Add -mfix-sb1 and -mno-fix-sb1.
+ * config/mips/mips.md (divdf3, divsf3, sqrtdf2, sqrtsf2): Work
+ around SB-1 errata if TARGET_FIX_SB1 is set.
+ (recip.d insn, recip.s insn, rsqrt.d insn, rsqrt.s insn): Likewise.
+ * doc/invoke.texi: Document MIPS -mfix-sb1 and -mno-fix-sb1.
+
+2003-08-22 Roger Sayle <roger@eyesopen.com>
+
+ * hashtable.c (ht_expand): Avoid calculating rehash for the common
+ case that the first probe hits an empty hash table slot.
+
+2003-08-22 Mark Mitchell <mark@codesourcery.com>
+
+ * config/ia64/hpux.h (SUPPORTS_INIT_PRIORITY): Define to 0.
+
+2003-08-22 Mark Mitchell <mark@codesourcery.com>
+
+ * config/ia64/ia64.md (*ptr_extend_plus_1): Rename to ...
+ (ptr_extend_plus_imm): ... this.
+ * config/ia64/ia64.c (addp4_optimize_ok): Do not disable addp4
+ optimization in C++.
+ (ia64_output_mi_thunk): Support ILP32 mode.
+
+2003-08-22 Bernardo Innocenti <bernie@develer.com>
+
+ * gcc/config/m68k/m68k.c (m68k_coff_asm_named_section): remove unused
+ function.
+ * gcc/config/m68k/m68k.c (-m68k_svr3_asm_out_constructor): likewise.
+
+2003-08-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386.c (const_int_1_operand): Simplify an
+ integer comparison.
+
+2003-08-22 Alan Modra <amodra@bigpond.net.au>
+
+ * config/fp-bit.c: Specify config/ dir for include of fp-bit.h.
+ * config/rs6000/ppc64-fp.c: Likewise.
+
+2003-08-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cfgcleanup.c: Fix comment typos.
+ * emit-rtl.c: Likewise.
+ * optabs.c: Likewise.
+ * ra-build.c: Likewise.
+ * rtlanal.c: Likewise.
+ * tree.h: Likewise.
+
+2003-08-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-decl.c: Fix comment formatting.
+ * cfgrtl.c: Likewise.
+ * combine.c: Likewise.
+ * convert.c: Likewise.
+ * dominance.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * dwarfout.c: Likewise.
+ * expmed.c: Likewise.
+ * fold-const.c: Likewise.
+ * gcov.c: Likewise.
+ * genattrtab.c: Likewise.
+ * ggc-common.c: Likewise.
+ * mips-tfile.c: Likewise.
+ * regmove.c: Likewise.
+
+2003-08-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtin-attrs.def: Fix comment formatting.
+ * c-pretty-print.c: Likewise.
+ * diagnostic.h: Likewise.
+ * langhooks.h: Likewise.
+ * recog.c: Likewise.
+ * simplify-rtx.c: Likewise.
+ * tree.def: Likewise.
+
+2003-08-22 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k-protos.h: Convert to ISO C90.
+ * config/m68k/m68k.c: Likewise.
+
+2003-08-21 Bernardo Innocenti <bernie@develer.com>
+ Paul Dale <pauli@snapgear.com>
+ Peter Barada <peter@baradas.org>
+
+ * config/m68k/m68k.c (m68k_rtx_costs): Adjust mul/div costs for
+ ColdFire cores.
+
+2003-08-21 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (INCLUDES): Remove -I$(srcdir)/config.
+ * config.gcc (*-*-openbsd): Don't set tm_file.
+ (alpha*-*-openbsd, arm*-*-coff*, arm*-wince-pe*,
+ arm-*-pe*, avr-*-*, h8300-*-rtems*, h8300-*-elf*,
+ h8300-*-*, hppa*-*-osf*, hppa*-*-bsd*, hppa*-*-hpux*,
+ i370-*-opened*, i370-*-mvs*, i370-*-linux*, i?86-*-openbsd*,
+ i?86-*-lynxos, i?86-*-nto-qnx*, iq2000*-*-elf*, m68000-hp-hpux*,
+ m68k-hp-hpux*, m68k-*-aout*, m68k-*-coff*, m68020-*-elf*,
+ m68k-*-elf*, m68k*-*-netbsd*, m68k*-*-openbsd*, m68k-*-sysv4*,
+ m68k-*-linux*, m68k-*-rtems*, mcore-*-pe*, mips*-*-netbsd*,
+ mips*-*-openbsd*, rs6000-*-lynxos*, sh*-*-elf*, sh*-*-ka,
+ sh-*-rtemself, sparc-*-openbsd*, strongarm-*-pe, vax-*-openbsd*,
+ xscale-*-coff): Use explicit and complete lists of target headers
+ to include. Move definitions to tm_defines where appropriate.
+ (hppa*-*-openbsd*, powerpc-*-openbsd*): Comment out stanza for
+ not-yet-contributed configuration.
+
+ * config/lynx.h, config/alpha/openbsd.h, config/arm/coff.h
+ * config/avr/avr.h, config/frv/frv.h, config/h8300/elf.h
+ * config/i370/linux.h, config/i370/mvs.h, config/i370/oe.h
+ * config/i386/nto.h, config/iq2000/iq2000.h,
+ * config/m68k/coff.h, config/m68k/hp310.h, config/m68k/hp320.h
+ * config/m68k/linux.h, config/m68k/m68k-aout.h
+ * config/m68k/m68k-none.h, config/m68k/m68kv4.h
+ * config/m68k/netbsd.h, config/m68k/openbsd.h
+ * config/m68k/sgs.h, config/mcore/mcore-pe.h,
+ * config/mips/netbsd.h, config/mips/openbsd.h, config/pa/pa.h,
+ * config/rs6000/lynx.h, config/sh/embed-elf.h, config/sparc/openbsd.h:
+ Remove includes of other target config headers, and
+ definitions of macros moved to tm_defines lists. Add #undefs
+ where now necessary to prevent redefinition warnings.
+
+ * config/h8300/coff.h: New file split out of...
+ * config/h8300/elf.h: ...here.
+ * config/m68k/hp320base.h: New file split out of...
+ * config/m68k/hp320.h: ...here.
+ * config/rs6000/lynxbase.h: New file split out of...
+ * config/rs6000/lynx.h: ...here.
+
+ * config/m68k/hp310g.h, config/m68k/hp320g.h, config/m68k/hpux7.h
+ * config/m68k/m68k-coff.h, config/mips/openbsd-be.h: Delete file.
+
+ * config/sol2.h: Remove #if 0-ed #include of sys/mman.h.
+ * config/m68k/m68kelf.h: Remove commented out #include of m68k/sgs.h.
+ * config/mcore/mcore.h: Don't include hwint.h nor machmode.h.
+ Remove unnecessary #ifndef.
+ * config/s390/s390.h: Prefix #include of s390/fixdfdi.h
+ [under IN_LIBGCC2] with config/.
+
+2003-08-21 Per Bothner <pbothner@apple.com>
+
+ * cppfiles.c (stack_file): Correctly pass return_at_eof parameter
+ to cpp_push_buffer.
+ * cpplex.c (_cpp_get_fresh_line): Don't buffer->prev - handled
+ by return_at_eof check. Always call _cpp_pop_buffer at end.
+
+2003-08-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/11805
+ * config/h8300/h8300.md (two anonymous patterns): Remove.
+
+2003-08-21 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (MUST_PASS_IN_STACK): Remove BLKmode clause.
+ * config/mips/mips.c (function_arg_pass_by_reference): Never return
+ true for n32 & n64.
+
+2003-08-21 Josef Zlomek <zlomekj@suse.cz>
+
+ * fold-const.c (fold): Fix bug in (A & C) == D where D & ~C != 0
+ and similarly in (A | C) == D where C & ~D != 0.
+
+2003-08-20 Geoffrey Keating <geoffk@apple.com>
+
+ PR 8180
+ * configure.in: When testing with_libs and with_headers, treat
+ 'no' as unset. Based on a patch by Dan Kegel <dank@kegel.com>.
+ * configure: Regenerate.
+
+2003-08-20 Peter Barada <peter@baradas.org>
+
+ * longlong.h (umul_ppmm): Add ColdFire support.
+
+2003-08-20 Peter Barada <peter@baradas.org>
+ Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k-none.h: Introduce new ColdFire archs.
+ * config/m68k/m68k.h: Likewise.
+ * config/m68k/lb1sf68.asm: Rename __mcf5200__ to __mcoldfire__.
+ * config/m68k/coff.h: Rename TARGET_5200 to TARGET_COLDFIRE.
+ * config/m68k/linux.h: Likewise.
+ * config/m68k/m68k.c: Likewise.
+ * config/m68k/m68k.md: Likewise.
+ * config/m68k/m68kelf.h: Likewise.
+ * config/m68k/netbsd-elf.h: Likewise.
+ * config/m68k/t-m68kelf: Add multilib targets for new ColdFire archs.
+
+2003-08-20 Bernardo Innocenti <bernie@develer.com>
+
+ * config/m68k/m68k.c: Strip away code depending on NO_ADDSUB_Q definition.
+ * config/m68k/m68k.md: Likewise.
+
+2003-08-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR java/11996
+ Revert this change:
+ 2003-08-19 Mark Mitchell <mark@codesourcery.com>
+ * c-common.c (c_common_signed_or_unsigned_type): Correctly handle
+ types with precisions other than those given by native machine
+ modes.
+
+2003-08-20 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.md (anonymous define_insn): remove obsolete code
+ selected by FSGLMUL_USE_S and FSGLDIV_USE_S
+ * config/m68k/m68k.c (output_move_himode): remove SGS_NO_LI check
+ * config/m68k/m68k.md (anonymous define_insn): Likewise
+ * config/m68k/m68k.md (anonymous define_insn): remove ISI_OV check
+ * config/m68k/m68k.c (standard_68881_constant_p): remove obsolete
+ code selected by NO_ASM_FMOVECR
+
+2003-08-20 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (output_move_const_into_data_reg,
+ output_move_himode): unify MOTOROLA/MIT handling of moveq
+ * config/m68k/m68k.md (movsi_const0, anonymous define_insn):
+ Likewise
+
+2003-08-20 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_output_function_prologue): use %U in
+ label name
+ * config/m68k/m68k.c (m68k_output_function_epilogue): replace
+ HOST_WIDE_INT_PRINT_DEC with %wd
+
+2003-08-20 Loren James Rittle <ljrittle@acm.org>
+
+ * config/i386/freebsd.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Handle
+ redefine warning.
+
+2003-08-20 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11984
+ * fold-const.c (fold <PLUS_EXPR>): Check for integer constant
+ operands before calling tree_int_cst_lt when performing associative
+ transformations.
+
+2003-08-20 Jason Merrill <jason@redhat.com>
+
+ * tree.h (IS_EXPR_CODE_CLASS): Also include 'r' and 's'.
+ (EXPR_CHECK): Don't check for 'r' or 's' if we're
+ checking IS_EXPR_CODE_CLASS.
+ * calls.c (calls_function_1): Likewise.
+ * fold-const.c (fold): Likewise.
+ * tree.c (iterative_hash_expr): Likewise.
+ * tree-inline.c (walk_tree, copy_tree_r): Likewise.
+
+2003-08-20 Gunther Nikl <gni@gecko.de>
+
+ * config/m68k/m68k.c (m68k_output_mi_thunk): delete obsolete code
+ depending on MOTOROLA_BSR
+ * config/m68k/m68k.md (anonymous define_insn): Likewise
+
+2003-08-20 Jason Merrill <jason@redhat.com>
+
+ * builtins.c (expand_builtin_mathfn): Use get_callee_fndecl.
+ (expand_builtin_mathfn2, expand_builtin, builtin_mathfn_code,
+ fold_trunc_transparent_mathfn, fold_builtin): Likewise.
+ * dojump.c (do_jump): Likewise.
+ * fold-const.c (operand_equal_p, fold): Likewise.
+ (tree_expr_nonnegative_p): Likewise.
+
+ * stor-layout.c (do_type_align): Only copy DECL_USER_ALIGN from
+ TYPE_USER_ALIGN for FIELD_DECLs.
+
+ * attribs.c (decl_attributes): Rebuild the function pointer type after
+ changing the target type.
+ * tree.c (get_qualified_type): Also check that the attributes match.
+
+2003-08-19 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * Makefile.in (STAGESTUFF): Move cc1obj$(exeext) from here ...
+ * objc/config-lang.in (stagestuff): ... to here.
+
+2003-08-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11946
+ * convert.c (convert_to_integer): Use CONVERT_EXPR (instead of
+ NOP_EXPR) when necessary.
+ * c-common.c (c_common_signed_or_unsigned_type): Correctly handle
+ types with precisions other than those given by native machine
+ modes.
+
+2003-08-19 Geoffrey Keating <geoffk@apple.com>
+
+ * cpppch.c (cpp_valid_state): Re-add warning about PCH not used
+ because some macro is defined.
+
+ * config/darwin.h (LINK_COMMAND_SPEC): Add -arch and -arch_only
+ options.
+ * config/i386/darwin.h (ASM_SPEC): New.
+ (SUBTARGET_EXTRA_SPECS): New.
+ * config/rs6000/darwin.h (ASM_SPEC): New.
+ (SUBTARGET_EXTRA_SPECS): New.
+ * configure.in: Don't set CROSS or SYSTEM_HEADER_DIR when building
+ a cross-compiler between two different processors on Darwin.
+ * configure: Regenerate.
+
+2003-08-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtins.c: Fix comment typos.
+ * c-common.c: Likewise.
+ * c-decl.c: Likewise.
+ * c-pretty-print.c: Likewise.
+ * cfgbuild.c: Likewise.
+ * cfglayout.c: Likewise.
+ * cfgloopanal.c: Likewise.
+ * cgraphunit.c: Likewise.
+ * cppfiles.c: Likewise.
+ * dwarfout.c: Likewise.
+ * expr.c: Likewise.
+ * fold-const.c: Likewise.
+ * gcse.c: Likewise.
+ * ggc-page.c: Likewise.
+ * haifa-sched.c: Likewise.
+ * pretty-print.c: Likewise.
+ * tree.c: Likewise.
+ * tree.h: Likewise.
+ * value-prof.c: Likewise.
+
+2003-08-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-decl.c: Follow spelling conventions.
+ * cppfiles.c: Likewise.
+
+2003-08-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-common.c: Fix comment formatting.
+ * c-common.h: Likewise.
+ * c-decl.c: Likewise.
+ * cppinit.c: Likewise.
+ * cpplib.h: Likewise.
+ * emit-rtl.c: Likewise.
+ * input.h: Likewise.
+ * line-map.h: Likewise.
+ * opts.c: Likewise.
+ * opts.h: Likewise.
+ * simplify-rtx.c: Likewise.
+
+2003-08-19 Daniel Jacobowitz <drow@mvista.com>
+
+ * unwind-c.c: Add libgcc-style exception.
+ * unwind-dw2.c: Likewise.
+ * unwind-pe.h: Likewise.
+ * unwind-sjlj.c: Likewise.
+ * unwind.inc: Likewise.
+
+2003-08-19 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/5582 PR c++/10538
+ * langhooks-def.h (lhd_decl_uninit): Declare.
+ (LANG_HOOKS_DECL_UNINIT): New macro.
+ (LANG_HOOKS_INITIALIZER): Adjust.
+ * langhooks.h (struct lang_hooks): Add new field
+ decl_uninit.
+ * langhooks.c (lhd_decl_uninit): Define.
+ * c-common.c (c_decl_uninit_1): New function.
+ (c_decl_uninit): New function.
+ (warn_init_self): Define.
+ * c-common.h (c_decl_uninit): Declare.
+ (warn_init_self): Declare.
+ * c.opt: Introduce -Winit-self.
+ * c-opts.c (c_common_handle_options): Set warn_init_self.
+ * c-lang.c (LANG_HOOKS_DECL_UNINIT): Define.
+ * objc/objc-lang.c (LANG_HOOKS_DECL_UNINIT): Define.
+ * function.c (uninitialized_vars_warning): Call the language hook.
+ * doc/invoke.texi: Document -Winit-self.
+
+2003-08-19 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.md: Adjust SI-mode "trap_if" instruction
+ to use better predicates and constraints. Define new
+ instruction to handle "trap_if" with DI-mode arguments.
+ (conditional_trap): FAIL if trap code is not 0.
+
+2003-08-19 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/i386/i386.c (legitimate_pic_address_disp_p): Change the
+ strstr with $pb to a strcompare with "<pic base>"
+ (ix86_output_addr_diff_elt): Output the real pic base.
+
+2003-08-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * langhooks-def.h (LANG_HOOKS_INITIALIZE_DIAGNOSTICS): Fix spelling.
+ (LANG_HOOKS_INITIALIZER): Correct.
+ * c-lang.c: Likewise.
+
+2003-08-19 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_mark_needed_node): Call notice_global_symbol.
+ (cgraph_varpool_mark_needed_node): Likewise.
+ * cgraph.h (notice_global_symbol): Declare
+ * varasm.c (notice_global_symbol): Break out from ...
+ (assemble_start_function): ... here; update for variables.
+ (assemble_variable): Use notice_global_symbol.
+
+2003-08-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_va_arg): If EABI_FLOAT_VARARGS_P,
+ expect SFmode and DFmode arguments to be passed in FPRs,
+ regardless of the underlying type.
+
+2003-08-19 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/11924
+ * config/mips/mips.c (INTERNAL_SYMBOL_P): New macro.
+ (mips_classify_symbol, m16_usym8_4, m16_usym5_4): Use it.
+
+2003-08-18 Matt Kraai <kraai@alumni.cmu.edu>
+
+ PR c/11207
+ * c-typeck.c (set_init_index): Check for negative index.
+
+2003-08-18 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/crti.asm (_init, _fini): Add alternate code for new
+ call0 ABI.
+ * config/xtensa/crtn.asm (_init, _fini): Likewise.
+ * config/xtensa/lib1funcs.asm (__mulsi3, __udivsi3, __divsi3,
+ __umodsi3, __modsi3): Likewise.
+ * config/xtensa/t-xtensa (crti.o, crtn.o): Add $(GCC_CFLAGS) and
+ $(INCLUDES).
+
+2003-08-18 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md ("*nabssf2_gpr"): New.
+
+2003-08-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md: Quote C code in braces. Remove use of
+ fake const0_rtx operands. Remove double backslashes. Use \;.
+ Remove workarounds for bogus warnings.
+
+2003-08-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (muldf3, mulsf3): Don't call a gen_* function.
+ (muldf3_internal, muldf3_r4300): Select based on TARGET_4300_MUL_FIX
+ rather than TARGET_MIPS4300.
+ (mulsf3_internal, mulsf3_r4300): Likewise.
+
+2003-08-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md: Renumber unspecs. Clean up comments.
+
+2003-08-17 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (associative_constant_p): New function to test
+ whether an RTX expression is an immediate constant.
+ (simplify_associative_operation): New function to perform some
+ reassociation optimizations of associative binary expressions.
+ (simplify_binary_operation): Use simplify_associative_operation
+ to simplify PLUS, MULT, AND, IOR, XOR, SMIN, SMAX, UMIN and UMAX.
+ Floating point expressions are only reassociated when unsafe
+ math optimizations are permitted.
+
+2003-08-17 Andreas Jaeger <aj@suse.de>
+
+ * config/alpha/alpha.md: Remove usage of PARAMS.
+
+ * config/i386/cygwin.h: Convert K&R prototypes to ISO C90.
+ * config/i386/i386-interix.h: Likewise.
+ * config/i386/winnt.c: Likewise.
+ * config/i386/cygming.h: Likewise.
+ * config/i386/cygwin2.c: Likewise.
+ * config/darwin.c: Likewise.
+ * config/darwin-c.c: Likewise.
+ * config/darwin-protos.h: Likewise.
+ * config/darwin.h: Likewise.
+ * config/s390/s390-protos.h: Likewise.
+ * config/s390/s390.c: Likewise.
+ * config/ia64/ia64.c: Likewse
+ * config/ia64/ia64-protos.h: Likewise.
+ * config/ia64/ia64-c.c: Likewise.
+
+2003-08-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/sparc/sparc.c: Convert to ISO C.
+
+ * config/sparc/sparc-protos.h: Don't use the PARAMS macro.
+ * config/sparc/sparc.c: Likewise.
+
+2003-08-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11512
+ * stmt.c (expand_expr_stmt_value): Don't warn about any void
+ typed expression.
+
+2003-08-16 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_fntype_regparm): Rename from ...
+ (ix86_function_regparm): ... this one; add fastcall and local
+ functions.
+ (ix86_function_ok_for_sibcall): Update.
+ (ix86_return_pops_args): Likewise.
+ (init_cumulative_args): Likewise.
+ (x86_can_output_mi_thunk): Likewise.
+ (function_arg): Fix formating.
+ (x86_this_parameter): Fix fastcall.
+ (x86_output_mi_thunk): Likewise.
+
+ * cgraph.c (cgraph_mark_needed_node): Do not mark functions without
+ body as reachable; mark nested functions as needed too.
+ (dump_cgraph): Do not output global.calls.
+ * cgraph.h (cgraph_global_info): Kill.
+ * cgraphunit.c (cgraph_finalize_function): Enqueue needed functions.
+ (record_call_1): Speedup.
+ (cgraph_analyze_function): Break out from ...; compute inlining
+ parameters.
+ (cgraph_finalize_compilation_unit): ... here.
+ (cgraph_mark_inline): Kill computation of calls.
+ (cgraph_decide_inlining): Do not compute most of initial values.
+
+2003-08-14 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (negate_expr_p): MULT_EXPRs and RDIV_EXPRs are easy
+ to negate if either operand is easy to negate, if we don't care
+ about sign-dependent rounding.
+ (negate_expr): Make the logic to negate a REAL_CST explicit.
+ Attempt to negate a MULT_EXPR or RDIV_EXPR by negating an operand
+ that's easy to negate, if we don't honor sign-dependent rounding.
+ (fold <MULT_EXPR>): Optimize -A * B as A * -B if B is easy to
+ negate, and the symmetric A * -B as -A * B if A is easy to negate.
+ (fold <RDIV_EXPR>): Likewise, optimize -A/B and C/-D as A/-B and
+ -C/D if B and C are cheap to negate. Add an explicit rule to
+ optimize X/-1.0 as -X when we don't care about signaling NaNs.
+
+2003-08-14 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (tm_file): Rename tm_include_list.
+ (tm_p_file): Rename tm_p_include_list.
+ (build_xm_file): Rename build_xm_include_list.
+ (host_xm_file): Rename host_xm_include_list.
+ (xm_file): Rename xm_include_list.
+ (xm_file_list): Add to be substituted.
+ (cs-config.h, cs-bconfig.h, cs-tconfig.h, cs-tm.h, cs-tm_p.h):
+ Update to match.
+ (bt-load.o): Add missing dependency on $(TM_H).
+ * configure.in: Prefix value of EXTRA_MODES_FILE with config/.
+ For each of tm_file, tm_p_file, xm_file, host_xm_file, and
+ build_xm_file, generate both *_file_list and *_include_list
+ values from it. (xm_file_list was formerly not being generated.)
+ In *_include_list, prefix the names of all headers found in
+ $(srcdir)/config with config/. In each loop, consider only
+ the special case files that can actually appear in that list.
+ AC_SUBST all *_file_list and all *_include_list variables; do
+ not AC_SUBST the plain *_file variables.
+ * configure: Regenerate.
+
+2003-08-14 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfg.c (dump_edge_info): Add name of loop_exit edge flag.
+
+2003-08-14 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (pa_adjust_insn_length): Delete adjustment for delay slot in
+ direct calls.
+ (attr_length_call): Include it here. Improve length estimate for
+ local calls.
+ (output_call): Use targetm.binds_local_p.
+
+2003-08-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (CASE_MATHFN): New helper macro.
+ (mathfn_built_in): Simplify and sort.
+
+ * protoize.c (substr): Delete, callers changed to `strstr'.
+
+2003-08-13 Zack Weinberg <zack@codesourcery.com>
+
+ * config.gcc (iq2000*-*-elf*): Don't set xm_file.
+ * config/iq2000/xm-iq2000.h: Delete file.
+
+2003-08-13 Geoffrey Keating <geoffk@apple.com>
+
+ * gengtype.c (walk_type): Process a subobject before processing
+ the pointer that points to the subobject.
+
+2003-08-13 Per Bothner <pbothner@apple.com>
+
+ * regclass.c (init_reg_modes): Make non-static.
+ Rename to init_reg_modes_once per new naming convention.
+ (init_regs): Don't call init_reg_modes here.
+ * emit-rtl.c (init_emit_once): Call init_reg_modes_once here instead.
+ * rtl.h (init_reg_modes_once): New declaration.
+ * toplev.c (backend_init): Call init_regs after init_emit_once.
+
+2003-08-13 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/linux.h (DBX_REGISTER_NUMBER): Define so to map a
+ special index for MD_FALLBACK_FRAME_STATE_FOR to itself.
+
+2003-08-13 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (sh_get_pr_initial_val): Always wrap in unspec for TARGET_SH1.
+ * sh.md (load_ra): Change insn predicate to TARGET_SH1.
+
+2003-08-13 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.md (ctrsi, ctrdi): Reenable
+ handling of decrement-and-branch farther than 32 bits.
+
+2003-08-12 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * configure.in (make_compare_target): Move test to ...
+ * aclocal.m4 (gcc_AC_PROG_CMP_IGNORE_INITIAL): here.
+ * configure: Regenerate.
+
+2003-08-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/iris6.h: Convert to C90 prototypes.
+ * config/mips/irix6-libc-compat.c: Likewise.
+ * config/mips/mips-protos.h: Likewise.
+ * config/mips/mips.c: Likewise.
+
+2003-08-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ fixinc/inclhack.def (svr4_krnl): Rename from svr4_kernel. Enable
+ for selected machines. Comment heavily.
+ fixinc/fixincl.x: Rebuild.
+ fixinc/tests/base/fs/rfs/rf_cache.h: New file.
+
+2003-08-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h: Tweak various comments.
+ * config/mips/mips.c: Likewise.
+
+2003-08-11 James E Wilson <wilson@tuliptree.org>
+
+ PR optimization/11319
+ PR target/10021
+ * alias.c (find_base_value, case REG): Return 0 not src if no base
+ found.
+
+2003-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcse.c (gmalloc): Fix last change.
+
+2003-08-11 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_binary_operation): Replace calls to
+ gen_rtx_NEG and gen_rtx_NOT with calls to simplify_gen_unary,
+ and calls to gen_rtx_PLUS, gen_rtx_MULT, gen_rtx_LSHIFTRT,
+ gen_rtx_ASHIFT and gen_rtx_AND with calls to simplify_gen_binary.
+
+2003-08-11 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_expr): If an ABS_EXPR has a complex type, abort.
+ * c-typeck.c (build_unary_op): COMPLEX_TYPE is not a valid
+ typecode for an ABS_EXPR.
+
+ * doc/c-tree.texi: Document ABS_EXPR.
+
+2003-08-11 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold): Optimize any associative floating point
+ operator with -funsafe-math-optimizations, not just MULT_EXPR.
+
+2003-08-11 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/lib1funcs.asm (__udivdi3): Add .type and .size
+ information in SHmedia case too.
+ (__divdi3, __umoddi3, __moddi3, __init_trampoline, __ic_invalidate):
+ Likewise.
+ (__set_fpscr): Use an access via GOT for PIC case.
+
+2003-08-11 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * configure.in (intermodule): Make switch test more portable.
+ * configure: Regenerate.
+
+2003-08-11 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * Makefile.in (cleanstrap): Pass BOOT_CFLAGS to bootstrap.
+ (restrap): Likewise.
+
+2003-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcse.c (gmalloc): Argument is a size_t. Add ATTRIBUTE_MALLOC.
+ (grealloc): Size argument is a size_t.
+ (gcalloc): New function. Use throughout in lieu of
+ gmalloc/memset.
+
+ * config/avr/avr.c (avr_init_once): Use xcalloc in lieu of
+ xmalloc/memset.
+ * config/ia64/ia64.c (ia64_reorg): Likewise.
+ * conflict.c (conflict_graph_new): Likewise.
+ * fixinc/fixincl.c (run_compiles): Likewise.
+ * genattrtab.c (optimize_attrs): Likewise.
+ * genrecog.c (new_decision): Likewise.
+ * haifa-sched.c (schedule_block): Likewise.
+ * hashtable.c (ht_create): Likewise.
+
+2003-08-11 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/lib2funcs.S: Fix whitespace.
+ * config/xtensa/xtensa.md (all insns and expanders): Use brace block
+ syntax where appropriate. Remove unnecessary backslash escapes.
+ Reformat comments and fix some code formatting.
+ (extendqisi2): Rearrange conditional.
+ (*btrue, *bfalse, *ubtrue, *ubfalse, *bittrue, *bitfalse, *masktrue,
+ *maskfalse, movsicc_internal0, movsfcc_internal0): Call abort instead
+ of fatal_insn.
+
+2003-08-11 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c: Various formatting fixes.
+ (override_options): Resync -mtune handling with gas.
+ (mips_issue_rate): Rearrange like mips_use_dfa_pipeline_interface.
+ * config/mips/mips.h: More formatting fixes.
+ (mips_abi): Move declaration.
+ * config/mips/mips.md (exception_receiver): Add mode to
+ unspec_volatile.
+
+2003-08-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (spe_init_builtins): Handle evsplati and
+ evsplatfi here.
+ (bdesc_1arg): Remove evsplati and evsplatfi.
+
+2003-08-11 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * dwarf2asm.c (dw2_output_indirect_constant_1): Take user_label_prefix
+ into account.
+
+2003-08-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (expand_builtin_strcat): Optimize constant strings.
+
+2003-08-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.c (pp_base_indent): Rename from pp_indent.
+ * c-pretty-print.h (pp_c_pretty_print_flag)s: New datatype.
+ (struct c_pretty_print_info): Add more fields.
+ (pp_c_left_paren): Move to c-pretty-print.c.
+ (pp_c_right_paren): Likewise.
+ (pp_c_left_brace): Likewise.
+ (pp_c_right_brace): Likewise.
+ (pp_c_left_bracket): Likewise.
+ (pp_c_right_bracket): Likewise.
+ (pp_c_declarator): Declare.
+ (pp_c_direct_declarator): Likewise.
+ (pp_c_specifier_qualifier_list): Likewise.
+ (pp_c_type_id): Likewise.
+ * c-pretty-print.c (pp_c_cv_qualifier): Change prootype. Rework..
+ (pp_c_type_qualifier_list): New.
+ (pp_c_pointer): Likewise.
+ (pp_c_parameter_type_list): Likewise.
+ (pp_c_function_definition): Likewise.
+ (pp_c_id_expression): Likewise.
+ (pp_c_simple_type_specifier): Tidy.
+ (pp_c_unary_expression): Likewise.
+ (pp_c_expression): Likewise.
+ (pp_c_pretty_printer_init): Likewise.
+ (pp_c_specifier_qualifier_list): Rework..
+ (pp_c_abstract_declarator): Likewise.
+ (pp_c_postfix_expression): Likewise.
+ (pp_c_primary_expression): Likewise.
+ (pp_c_cast_expression): Likewise.
+ (pp_c_direct_abstract_declarator): Likewise.
+ (pp_c_storage_class_specifier): Likewise.
+ (pp_c_function_specifier): Likewise.
+ (pp_c_declaration_specifiers): Likewise.
+ (pp_c_direct_declarator): Likewise.
+ (pp_c_declarator): Likewise.
+ (pp_c_declaration): Likewise.
+ (pp_c_statement): Likewise.
+ (pp_c_integer_constant): Rename from pp_c_integer_literal.
+ (pp_c_character_constant): Rename from pp_c_character_literal.
+ (pp_c_bool_constant): Rename from pp_c_bool_literal.
+ (pp_c_enumeration_constant): Rename from pp_c_enumerator.
+ (pp_c_floating_constant): Rename from pp_c_real_literal.
+ (pp_c_constant): Rename from pp_c_literal.
+ * c-lang.c: Include diagnostic.h and c-pretty-print.h
+ (LANG_HOOKS_INITIALIZE_DIAGNOSTITCS): Define.
+ (c_initialize_diagnostics): New.
+ * Makefile.in (c-lang.o): Update dependency.
+
+2003-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-typeck.c (digest_init): Add conversion for VECTOR_TYPEs.
+
+2003-08-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_no_mips16_string): Remove.
+ (override_options): Don't handle -mips16 as part of -mipsN.
+ * config/mips/mips.h (mips_no_mips16_string): Remove declaration.
+ (TARGET_SWITCHES): Add -mips16 and -mno-mips16 entries.
+ (TARGET_OPTIONS): Remove -mno-mips16.
+
+2003-08-10 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (coprocessor_operand): Remove declaration.
+ (coprocessor2_operand): Likewise.
+ * config/mips/mips.c (STAB_CODE_TYPE): Remove.
+ (lookup_name): Remove declaration.
+ (abort_with_insn): Remove. Replace all uses with fatal_insn.
+ (mips16, mips_abicalls): Remove.
+ (mips_char_to_class): Remove initialiser: all entries are NO_REGS.
+ (arith32_operand, large_int, true_reg_or_0_operand): Remove.
+ (coprocessor_operand, coprocessor2_operand): Remove.
+ (override_options): Don't set mips16 or mips_abicalls.
+ (print_operand): Don't expect SIGN_EXTEND operands.
+ (mips_secondary_reload_class): Likewise.
+ (mips_output_conditional_branch): Remove disabled long-branch code.
+ * config/mips/mips.h (call_used_regs): Remove declaration.
+ (may_call_alloca): Likewise.
+ (mips_cpu_attr, mips_abicalls_type, mips_abicalls_attr): Remove.
+ (mips_abicalls, mips16): Remove declarations.
+ (ASM_FINAL_SPEC, LIB_SPEC): Remove.
+ (CC1_SPEC): Remove outdated comment.
+ (MIPS_VERSION, MACHINE_TYPE): Remove.
+ (TARGET_VERSION_INTERNAL, TARGET_VERSION): Remove.
+ (PC_REGNUM, STACK_POINTER_OFFSET): Remove disabled definitions.
+ (STRUCT_VALUE_RETURN_REGNUM, STACK_DYNAMIC_OFFSET): Likewise.
+ (PUSH_ROUNDING): Likewise.
+ (ASSEMBLER_SCRATCH_REGNUM): Remove.
+ * config/mips/mips.md: Replace mips_cpu_attr with mips_tune
+ and mips16 with TARGET_MIPS16.
+
+2003-08-09 Per Bothner <pbothner@apple.com>
+
+ * cppinit.c (cpp_read_main_file): Split out source-independent
+ initialization to separate function ...
+ (cpp_post_options): New function.
+ * cppfiles.c (cpp_stack_file): Rename public name to ...
+ (_cpp_stack_file): New internal function name.
+ * cpplib.h: Update accordingly.
+ * cppinit.c: (cpp_create_reader): Initialize cpp_readers line here.
+ (cpp_read_main_file): Don't initialize line here.
+ * c-opts.c (c_common_post_options): Call cpp_post_options.
+ (c_common_parse_file): Call cpp_read_main_file, not cpp_stack_file.
+ * fix-header.c (read_scan_file): Call cpp_post_options.
+
+2003-08-09 Per Bothner <per@bothner.com>
+
+ * c-decl.c (SCOPE_LIST_APPEND): Remove bogus line continuation.
+
+2003-08-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (pa_asm_output_mi_thunk): Fix typo.
+
+2003-08-09 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/11839
+ * cppfiles.c (open_file): Handle ENOTDIR.
+
+2003-08-09 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/11699
+ * config/mips/mips.c (override_options): Reject -mabi=eabi -mabicalls.
+
+2003-08-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.md (extzv, extv, insv): Fix operand limit checks. Fail if
+ source/destination is not a register operand.
+
+2003-08-08 Richard Henderson <rth@redhat.com>
+
+ PR target/11535
+ * config/ia64/ia64.c (ia64_initial_elimination_offset): Remove
+ RETURN_ADDRESS_POINTER_REGNUM.
+ (ia64_expand_prologue): Don't frob it.
+ (ia64_output_function_epilogue): Likewise.
+ (ia64_return_addr_rtx): New.
+ (ia64_split_return_addr_rtx): New.
+ * config/ia64/ia64-protos.h: Update.
+ * config/ia64/ia64.h (FIRST_PSEUDO_REGISTER): Decrement.
+ (RETURN_ADDRESS_POINTER_REGNUM): Remove.
+ (GENERAL_REGNO_P): Don't check it.
+ (AR_*_REGNUM): Renumber.
+ (FIXED_REGISTERS): Remove RETURN_ADDRESS_POINTER_REGNUM.
+ (CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS): Likewise.
+ (REG_ALLOC_ORDER, REG_CLASS_CONTENTS): Likewise.
+ (ELIMINABLE_REGS, REGISTER_NAMES): Likewise.
+ (RETURN_ADDR_RTX): Use ia64_return_addr_rtx.
+ * config/ia64/ia64.md (UNSPEC_RET_ADDR): New.
+ (movdi_ret_addr): New.
+
+2003-08-08 Geoffrey Keating <geoffk@apple.com>
+
+ * config.gcc (powerpc-*-darwin*): Don't build a soft-float multilib.
+
+2003-08-08 Roger Sayle <roger@eyesopen.com>
+
+ * tree.h (get_identifier) Define a macro form of get_identifier
+ that calls get_identifier_with_length when the string is constant.
+ (get_identifier_with_length): Change type of second argument to
+ size_t in prototype.
+ * stringpool.c (get_identifier): Undefine the macro before giving
+ the function definition.
+ (get_identifier_with_length): Change type of second argument to
+ size_t in function definition.
+ * hashtable.c (calc_hash): Change type of second argument to size_t.
+ (ht_lookup): Change type of third argument to size_t. Reorganize
+ to speed-up the cases where the hash table slot is empty, or the
+ first probe matches (i.e. there isn't a collision).
+ * hashtable.h (ht_lookup): Adjust function prototype.
+
+2003-08-08 Bernardo Innocenti <bernie@develer.com>
+
+ PR target/9697
+ PR target/11777
+ * longlong.h (count_leading_zeros): Exclude on __mcpu32__.
+
+2003-08-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * common.opt: Add debug switches.
+ * flags.h (use_gnu_debug_info_extensions): Boolify.
+ * opts.c (write_symbols, debug_info_level,
+ use_gnu_debug_info_extensions): Move from toplev.c.
+ (set_debug_level): New.
+ (common_handle_options): Handle debug switches.
+ (print_help): Display target options directly.
+ * toplev.c (debug_hooks): Don't initialize.
+ (write_symbols, debug_info_level,
+ use_gnu_debug_info_extensions): Move to opts.c.
+ (debug_args, display_help, decode_g_option): Remove.
+ (process_options): Set no debug if level zero here,
+ and no-debug-hooks. Error here if impossible debug format selected.
+ * toplev.h (display_help, decode_g_option): Remove.
+
+2003-08-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * tree.c (get_file_function_name_long): Fix size of alloca() area.
+
+2003-08-08 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * configure.in (gcc_cv_prog_cmp_skip): Flipflop make_compare_target
+ and gcc_cv_prog_cmp_skip.
+ * configure: Regenerate.
+
+2003-08-08 Stan Cox <scox@redhat.com>
+
+ * config/iq2000: New port.
+ * config.gcc (iq2000-*-elf): Added.
+ * doc/install.texi (Specific): Add iq2000 description.
+
+2003-08-08 Andreas Schwab <schwab@suse.de>
+
+ * configure.in (gcc_cv_as_ia64_ltoffx_ldxmov_relocs): Fix quoting
+ and insert missing empty argument.
+ * configure: Regenerate.
+
+2003-08-07 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (update_total_code_bytes): Use new macro IN_NAMED_SECTION_P.
+ (attr_length_millicode_call): Likewise.
+ (attr_length_call): Likewise. Revise some maximum insn lengths.
+ (attr_length_indirect_call): Likewise.
+ (output_call): Fix thinko that added extra nop.
+ * pa.h (IN_NAMED_SECTION_P): Define.
+
+ PR c++/11712
+ * pa-hpux.h, pa-hpux10.h, pa-hpux11.h (TARGET_OS_CPP_BUILTINS): Define
+ __STDC_EXT__ when using C++ dialect.
+
+2003-08-07 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (calc_live_regs): If the return address pointer is live,
+ force pr live.
+ (sh5_schedule_saves): Exclude PR_MEDIA_REG from being a temp register
+ for saves / restores.
+ (sh_expand_epilogue): If sh_media_register_for_return returns a
+ register number, flag the instructions that restores PR_MEDIA_REG
+ as possibly dead.
+ Remove dead update of offset.
+ (sh_get_pr_initial_val): Use UNSPEC_RA if we don't know yet if
+ we can use the result of get_hard_reg_initial_val.
+ * sh.md (UNSPEC_RA): New constant.
+ (movsi_i_lowpart+1): Changed into a define_insn_and_split, named:
+ (load_ra). Handle UNSPEC_RA.
+ (sibcall_media): Use PR_MEDIA_REG.
+
+ * sh.h (CALL_USED_REGISTERS): Include PR_REG and PR_MEDIA_REG.
+ * sh.c (calc_live_regs): Use sh_pr_n_sets to determine if pr
+ needs saving on SHmedia.
+
+2003-08-07 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md: Replace all occurrences of \\t with \t.
+
+2003-08-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * local-alloc.c (combine_regs): Fix comment typo.
+
+2003-08-06 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (builtin_decls): Replace with first_builtin_decl
+ and last_builtin_decl.
+ (c_init_decl_processing): Initialize both.
+ (c_reset_state): Iterate from first_builtin_decl to
+ last_builtin_decl inclusive to reintroduce builtins.
+
+2003-08-06 David Mosberger <davidm@hpl.hp.com>
+
+ * doc/extend.texi (Function Attributes): Document the IA-64 version
+ of the "model" attribute.
+
+ * config/ia64/ia64.h (SYMBOL_FLAG_SMALL_ADDR): New macro.
+ (SYMBOL_REF_SMALL_ADDR_P): Ditto.
+ (PREDICATE_CODES): Mention "small_addr_symbolic_operand".
+
+ * config/ia64/ia64.c (ia64_handle_model_attribute): New function.
+ (ia64_encode_section_info): Likewise.
+ (ia64_attribute_table): Add "model" attribute.
+ (TARGET_ENCODE_SECTION_INFO): Define.
+ (small_addr_symbolic_operand): New function.
+ (got_symbolic_operand): Return 0 for a symbolref to an object
+ in the small address area.
+ (enum ia64_addr_area): New type.
+ (small_ident1): New variable.
+ (small_ident2): Likewise.
+ (init_idents): New function.
+ (ia64_get_addr_area): Likewise.
+ (ia64_encode_addr_area): Likewise.
+ (ia64_encode_section_info): Likewise.
+ (ia64_expand_load_address): For symbolic references to objects in
+ the small-address-area, load the address via gen_rtx_SET() (which,
+ eventually, will expand into "addl").
+
+2003-08-06 Per Bothner <pbothner@apple.com>
+
+ * line-map.h (fileline): New typedef.
+ (struct line_map, linemap_add, linemap_lookup): Use it.
+ * input.h (struct location_s): Comment notes that long-term we want
+ to replace it by fileline.
+
+2003-08-06 J"orn Rennecke <joern.rennecke@superh.com>
+
+ Fix SHcompact exception handling:
+ * sh.c (sh_get_pr_initial_val): If PR is or miight be clobbered
+ by the prologue, return a MEM with return_address_pointer_rtx
+ as address.
+ * sh.h (HARD_REGNO_MODE_OK): PR is OK for SImode.
+ (RETURN_ADDR_OFFSET): Don't define.
+ (SH_DBX_REGISTER_NUMBER): Use SHmedia numbers for SHmedia
+ registers that are visible in compact mode. Show that SHmedia
+ registers still exist in compact mode, even if there are not
+ readily accessible.
+ (ASM_PREFERRED_EH_DATA_FORMAT): Supply DW_EH_PE_indirect
+ if GLOBAL. Use DW_EH_PE_textrel (nominally) for CODE,
+ and DW_EH_PE_pcrel for pic data.
+ (ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX): If DW_EH_PE_textrel,
+ set SYMBOL_FLAG_FUNCTION in symbol, and actually use
+ DW_EH_PE_pcrel / DW_EH_PE_absptr encoding.
+ (ALLOCATE_INITIAL_VALUE): Put PR on stack if prologue clobbers it.
+ * sh.md (movsi_media-1): New splitter.
+
+2003-08-06 Graeme Peterson <gp@qnx.com>
+
+ * config/i386/nto.h: New.
+ * config/i386/t-nto: New.
+ * config.gcc (i[34567]86-*-nto-qnx*): New.
+
+2003-08-06 Phil Edwards <pme@gcc.gnu.org>
+
+ * doc/install.texi (*-*-solaris2*): Refine configure instructions.
+
+2003-08-06 Alan Modra <amodra@bigpond.net.au>
+
+ * calls.c (load_register_parameters): Arrange for call_fusage to
+ report the whole register as used when shifting to the msb.
+
+2003-08-05 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin): When not optimizing, call the library
+ function for all builtins that have library functions (except alloca).
+
+2003-08-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * c.opt: Introduce -fworking-directory.
+ * doc/cpp.texi, doc/invoke.texi, doc/cppopts.texi: Document it.
+ * c-common.h (flag_working_directory): Declare.
+ * c-common.c (flag_working_directory): Define.
+ * c-opts.c (c_common_handle_options): Set it.
+ (sanitize_cpp_opts): Set...
+ * cpplib.h (struct cpp_options): ... working_directory option.
+ (struct cpp_callbacks): Add dir_change.
+ * cppinit.c (read_original_filename): Call...
+ (read_original_directory): New. Look for # 1 "directory//"
+ and process it.
+ (cpp_read_main_file): Call dir_change callback if working_directory
+ option is set.
+ * gcc.c (cpp_unique_options): Pass -g*.
+ * c-lex.c (cb_dir_change): New.
+ (init_c_lex): Set dir_change callback.
+ * toplev.c (src_pwd): New static variable.
+ (set_src_pwd, get_src_pwd): New functions.
+ * toplev.h (get_src_pwd, set_src_pwd): Declare.
+ * dbxout.c (dbxout_init): Call get_src_pwd() instead of getpwd().
+ * dwarf2out.c (gen_compile_unit_die): Likewise.
+ * dwarfout.c (output_compile_unit_die, dwarfout_init): Likewise.
+
+2003-08-05 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.h (pp_set_line_maximum_length): Make macro.
+ (pp_set_prefix): Likewise.
+ (pp_destroy_prefix): Likewise.
+ (pp_remaining_character_count_for_line): Likewise.
+ (pp_clear_output_area): Likewise.
+ (pp_formatted_text): Likewise.
+ (pp_last_position_in_text): Likewise.
+ (pp_emit_prefix): Likewise.
+ (pp_append_text): Likewise.
+ (pp_flush): Likewise.
+ (pp_format_text): Likewise.
+ (pp_format_verbatim): Likewise.
+ (pp_tree_identifier): Tidy.
+ * pretty-print.c (pp_base_format_text): Rename from pp_format_text.
+ (pp_base_format_verbatim): Rename from pp_format_verbatim.
+ (pp_base_flush): Rename from pp_flush.
+ (pp_base_set_line_maximum_length): Rename from
+ pp_set_line_maximum_length.
+ (pp_base_clear_output_area): Rename from pp_clear_output_area.
+ (pp_base_set_prefix): Rename from pp_set_prefix.
+ (pp_base_destroy_prefix): Rename from pp_destroy_prefix.
+ (pp_base_emit_prefix): Rename from pp_emit_prefix.
+ (pp_base_append_text): Rename from pp_append_text.
+ (pp_base_formatted_text): Rename from pp_formatted_text.
+ (pp_base_last_position_in_text): Rename from pp_last_position_in_text.
+ (pp_base_remaining_character_count_for_line): Rename from
+ pp_remaining_character_count_for_line.
+ * diagnostic.h (diagnostic_format_decoder): Tidy.
+ (diagnostic_flush_buffer): Likewise.
+ * c-pretty-print.h: (pp_c_string_literal): Declare.
+ (pp_c_real_literal): Likewise.
+ (pp_c_integer_literal): Likewise.
+ * c-pretty-print.c (pp_c_char): Use pp_string in lieu of
+ pp_identifier.
+ (pp_c_character_literal): Tidy.
+ (pp_c_string_literal): Make public.
+ (pp_c_bool_literal): Likewise.
+ (pp_c_integer_literal): Likewise.
+ (pp_c_real_literal): Likewise.
+
+ * Makefile.in (C_PRETTY_PRINT_H): New variable.
+ (c-pretty-print.o): Update dependence.
+
+2003-08-05 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.md (fix_truncdfsi2_macro): Properly restore
+ ".set nomacro" state.
+ (fix_truncsfsi2_macro): Likewise.
+
+2003-08-05 Steven Bosscher <steven@gcc.gnu.org>
+
+ * tree.h (DID_INLINE_FUNC): Remove macro.
+ (DECL_DECLARED_INLINE_P): Move from c-tree.h and cp/cp-tree.h,
+ add tree check for FUNCTION_DECL.
+ (DECL_ESTIMATED_INSNS): Move from c-common.h and java/java-tree.h.
+ (struct tree_decl): Rename inlined_function_flag to
+ declared_inline_flag.
+ * c-common.h (c_lang_decl): Remove.
+ (DECL_ESTIMATED_INSNS): Remove.
+ * c-tree.h (struct lang_decl): Don't include c_lang_decl.
+ (DECL_DECLARED_INLINE_P): Remove.
+ * c-decl.c (grokdeclarator): Update comment. With -finline-functions,
+ do not reset DECL_DECLARED_INLINE_P. Don't use DID_INLINE_FUNC.
+ (finish_function): Make uninlinable a bool. Fixup call to
+ tree_inlinable_function_p() and fix some code style issues.
+ * cgraph.h (disgread_inline_limits): Fix spelling: `disregard'.
+ * cgraph.c (dump_cgraph): Likewise.
+ * cgraphunit.c (cgraph_decide_inlining): Likewise
+ (cgraph_finalize_compilation_unit): Likewise.
+ Also update call to tree_inlinable_function_p().
+ (cgraph_default_inline_p): Don't use DID_INLINE_FUNC. Instead
+ look at DECL_DECLARED_INLINE and reverse logic.
+ * print-tree.c (print_node): Likewise.
+ * toplev.c (rest_of_handle_inlining): Don't use DID_INLINE_FUNC.
+ * tree-inline.h (tree_inlinable_function_p): Make a bool. Update
+ prototype.
+ * tree-inline.c (inlinable_function_p): Split up in this function to
+ check for basic inlining inhibiting conditions, and new
+ limits_allow_inlining() function. Warn if inlining is impossible
+ because the inline candidate calls alloca or uses sjlj exceptions.
+ (limits_allow_inlining): this new function to check if the inlining
+ limits are satisfied. Throttle from currfn_max_inline_insns, not from
+ MAX_INLINE_INSNS_SINGLE. The latter only makes sense if
+ MAX_INLINE_INSNS_AUTO and MAX_INLINE_INSNS_SINGLE are equal.
+ Update prototypes.
+ (tree_inlinable_function_p): Make a bool. Update call to
+ inlinable_function_p
+ (expand_call_inline): Use limits_allow_inlining() when not in
+ unit-at-a-time mode to decide on inlining. Don't use DID_INLINE_FUNC,
+ instead see if the function was declared `inline'.
+
+2003-08-05 Josef Zlomek <zlomekj@suse.cz>
+
+ * gcse.c (try_replace_reg): Fix updating of note.
+
+2003-08-04 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/11771
+ * fold-const.c (negate_expr_p <MINUS_EXPR>): Change to match the
+ logic in negate_expr, i.e. we don't invert (A-B) for floating
+ point types unless flag_unsafe_math_optimizations.
+
+2003-08-04 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold <PLUS_EXPR>): Transform x+x into x*2.0.
+ Optimize x*c+x and x+x*c into x*(c+1) and x*c1+x*c2 into x*(c1+c2)
+ for floating point expressions with -ffast-math.
+ (fold <MULT_EXPR>): Don't transform x*2.0 into x+x.
+ * expmed.c (expand_mult): Wrap long line. Expand x*2.0 as x+x.
+
+2003-08-04 Roger Sayle <roger@eyesopen.com>
+
+ * c-common.c (flag_noniso_default_format_attributes): Delete.
+ (built_in_attribute): Don't define/undefine DEF_FN_ATTR.
+ (c_attrs_initialized): Delete.
+ (c_common_nodes_and_builtins): Don't test c_attrs_initialized,
+ always call c_init_attributes.
+ (c_init_attributes): Don't define/undefine DEF_FN_ATTR. Don't
+ set c_attrs_initialized when done.
+ (c_common_insert_default_attributes): Delete.
+ * c-common.h (flag_noniso_default_format_attributes): Delete.
+ (c_coomon_insert_default_attributes): Delete prototype.
+ * c-opts.c (set_std_c89, set_std_c99, set_std_cxx98): Dont set
+ flag_noniso_default_format_attributes.
+
+ * c-decl.c (c_insert_default_attributes): Delete.
+ * c-tree.h (c_insert_default_attributes): Delete prototype.
+
+ * attribs.c (decl_attributes): Don't call insert_default_attributes
+ langhook. Update function description comment.
+ * langhooks.h (lang_hooks): Remove insert_default_attributes field.
+ * langhooks-def.h (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Delete.
+ * c-lang.c (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Don't define.
+ * system.h: Poison LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES macro.
+
+ * objc/objc-lang.c (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Don't
+ define.
+
+2003-08-04 Richard Sandiford <rsandif@redhat.com>
+
+ * config/mips/mips.c (override_options): Disable -G on targets that
+ have no .section support.
+ (mips_select_section): Use default_select_section for such targets.
+
+2003-08-04 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (svr4_undeclared_getrnge): Introduce and enable.
+ * fixinc/inclhack.def (static_getrnge): Remove disabled hack.
+ * fixinc/fixincl.x: Rebuild.
+ * fixinc/tests/base/regexp.h: New test.
+
+2003-08-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * c-ppoutput.c (cb_line_change): Don't skip line changing while
+ parsing macro arguments in the top-level context.
+
+2003-08-04 Neil Booth <neil@daikokuya.co.uk>
+
+ * config.in: Remove HAVE_LSTAT.
+ * configure, configure.in: Don't test for lstat.
+
+2003-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * opts.c (decode_options): Do language-specific initialization for
+ the global diagnostic context.
+ * langhooks-def.h (lhd_initialize_diagnostics): Declare.
+ (LANG_HOOKS_INITIALIZE_DIAGNOSTITCS): New macro.
+ (LANG_HOOKS_INITIALIZER): Adjust.
+ * langhooks.h (struct lang_hooks): Add new field
+ initialize_diagnostics.
+ * langhooks.c (lhd_initialize_diagnostics): Define.
+
+2003-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.h: Adjust macro definitions.
+ * pretty-print.c (pp_newline): Rename to pp_base_newline.
+ (pp_character): Rename to pp_base_character.
+ (pp_string): Rename to pp_base_string.
+ * c-pretty-print.c (pp_buffer): Move to pretty-print.h
+ (pp_newline): Likewise. Adjust.
+ (pp_c_char): Adjust.
+
+2003-08-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def (BUILT_IN_ABS, BUILT_IN_IMAXABS, BUILT_IN_LABS,
+ BUILT_IN_LLABS): Move to miscellaneous section.
+
+2003-08-03 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/11534
+ * cppexp.c (parse_defined): Warn only if -pedantic.
+
+2003-08-03 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (stack_file): Use file path.
+
+2003-08-02 Roger Sayle <roger@eyesopen.com>
+
+ * builtin-types.def (BT_SSIZE): New primitive type.
+ (BT_FN_INT_PTR_CONST_STRING_VALIST_ARG,
+ BT_FN_STRING_CONST_STRING_CONST_STRING_INT,
+ BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR,
+ BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR): New function types.
+ * builtins.def (BUILT_IN_DCGETTEXT, BUILT_IN_DGETTEXT,
+ BUILT_IN_FSCANF, BUILT_IN_GETTEXT, BUILT_IN_STRFMON,
+ BUILT_IN_STRFTIME, BUILT_IN_VFPRINTF, BUILT_IN_VFSCANF): New builtins.
+ * builtin-attrs.def: Remove DEF_FN_ATTR construct and the last
+ few functions that define default attributes using it.
+ * c-common.c (c_common_insert_default_attributes): Do nothing.
+
+ * doc/extend.texi: Document these "new" builtins.
+
+2003-08-02 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/linux.h (SUBTARGET_LINK_SPEC): Don't set rpath.
+ (LIB_SPEC): Set -lpthread always when -pthread set. Set -lieee
+ when -mieee-fp set and -shared not set.
+ (SH_FALLBACK_FRAME_FLOAT_STATE): Don't define for SH5.
+
+2003-08-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (struct _cpp_file): Rename once_only_next to
+ next_file. Remove import and pragma_once, add once_only.
+ (find_file): Add new file structures to the all_files list.
+ (should_stack_file): Mark #import-ed files once-only, and
+ don't stack them if the file has already been stacked.
+ (_cp_mark_file_once_only): Simplify.
+ * cpphash.h (struct cpp_reader): Rename once_only_files
+ to all_files. Rename saw_pragma_once to seen_once_only.
+ (_cpp_mark_file_once_only): Update prototype.
+ * cpplib.c (do_pragma_once): Update.
+
+2003-08-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (ENOTDIR): Remove.
+ (open_file_in_dir): Rename find_file_in_dir. Handle errors
+ other than ENOENT here.
+ (once_only_file_p): Rename should_stack_file.
+ (find_file, open_file_failed, read_file_guts): Report errors
+ with full path name.
+ (read_file): Move pch handling to should_stack_file.
+ (should_stack_file): Handle PCH and once-only issues, and
+ reading the file.
+ (stack_file): Don't do file reads.
+
+2003-08-02 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * libgcov.c (gcov_exit): Cleanup and fix.
+ * profile.c (compute_value_histograms): Don't try to read profiles
+ that are not present.
+
+2003-08-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def: Categorize.
+
+ * builtins.def (BUILT_IN_CABS, BUILT_IN_CABSF, BUILT_IN_CABSL):
+ Mind fp rounding.
+ (BUILT_IN_FFSL): Use DEF_EXT_LIB_BUILTIN.
+
+2003-08-02 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * config.gcc: Enable posix threads by default on darwin.
+
+2003-08-01 Jakub Jelinek <jakub@redhat.com>
+
+ * cfgcleanup.c (outgoing_edges_match): Check REG_EH_REGION notes
+ even if nehedges1 is 0.
+
+2003-08-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/fixfixes.c, fixinc/fixlib.c, fixinc/fixlib.h,
+ fixinc/fixtests.c, fixinc/procopen.c, fixinc/server.c,
+ fixinc/server.h, fixinc/fixincl.c: ANSIfy function prototypes
+ and defintions.
+
+ * fixinc/inclhack.def (broken_cabs): Make matching more generous.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/math.h: Regenerate to match test_text change.
+
+2003-08-01 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * ggc-common.c (gt_pch_restore): Case MAP_FAILED to void *.
+
+2003-08-01 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * except.c (sjlj_emit_dispatch_table): Use ptr_mode, not Pmode,
+ for accesses to exc_ptr.
+
+2003-08-01 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/sourcebuild.texi (Front End Directory): Don't make references
+ to libsubdir, it's not part of the interface to frontends.
+ * doc/install.texi (Configuration): Help users read faster by saying
+ that GCC's configure options are the standard autoconf ones.
+ Mention --libdir. Update the default rules for finding the
+ assembler. Don't use libsubdir since we haven't said what it means.
+ (Specific): In the Solaris 7 notes, update the place to put the
+ assembler.
+ * doc/invoke.texi: Update lib/gcc-lib to lib/gcc.
+ * doc/cpp.texi (Search Path): Actually, the search path
+ depends on libdir, which can relocate with cpp.
+ * doc/tm.texi (Driver): Don't document STANDARD_EXEC_PREFIX, it's
+ now a private interface between the Makefile and the driver.
+
+2003-08-01 Richard Henderson <rth@redhat.com>
+
+ * system.h: Poison ASM_SIMPLIFY_DWARF_ADDR.
+
+ * varasm.c (lookup_constant_def): New function.
+ * rtl.h (lookup_constant_def): Declare it.
+ * dwarf2out.c (loc_descriptor_from_tree): Use it.
+ Use targetm.delegitimize_address, not ASM_SIMPLIFY_DWARF_ADDR.
+
+2003-08-01 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (gettags, pushdecl_function_level): Delete.
+ (last_function_parm_vars): Rename last_function_parm_others.
+ (current_function_parm_vars): Rename current_function_parm_others.
+ (struct c_scope): Rewrite comment explaining this data structure.
+ Add names_last, blocks_last, parms_last fields. Rename
+ incomplete_list to incomplete.
+ (SCOPE_LIST_APPEND, SCOPE_LIST_CONCAT): New macros.
+ (poplevel): Ignore second argument. No need to nreverse
+ anything. Restructure such that each list is processed
+ exactly once. Use 'const location_t *locus' syntactic sugar
+ variable where useful. Issue unused variable warnings
+ ourselves, do not rely on function.c.
+ (insert_block, pushdecl, bind_label): Use SCOPE_LIST_APPEND.
+ (pushdecl_top_level): Likewise. Don't call duplicate_decls.
+ (implicitly_declare): decl cannot be error_mark_node.
+ (undeclared_variable): Manipulate scope structure directly.
+ (c_make_fname_decl): Likewise.
+ (getdecls, c_init_decl_processing): Fix comment.
+ (mark_forward_parm_decls): Use SCOPE_LIST_CONCAT. No need
+ for 'last' variable.
+ (grokparms): No need to nreverse parms list.
+ (store_parm_decls_newstyle): Set up the parms_last and
+ names_last fields of the new scope too.
+ (store_parm_decls_oldstyle): Can assume DECL_WEAK is not set
+ on parms to begin with; check this under ENABLE_CHECKING. Set
+ up parms_last.
+ (check_for_loop_decls): Refer directly to current_scope->tags.
+ Use consistent quote style in diagnostics.
+ (c_write_global_declarations): The names list is not backward.
+
+ * c-common.h: Don't prototype gettags.
+ * c-parse.in: Call poplevel with second argument 0 always.
+
+2003-08-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def: Resort builtins.
+
+2003-08-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def (DEF_GCC_BUILTIN, DEF_LIB_BUILTIN,
+ DEF_EXT_LIB_BUILTIN, DEF_C99_BUILTIN, DEF_C99_C90RES_BUILTIN):
+ Prepend "__builtin_" onto NAME with string concatenation. Remove
+ explicit "__builtin_" from each macro call.
+
+ Reformat entire file.
+
+2003-08-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.def (ATTR_MATHFN_ERRNO, ATTR_MATHFN_FPROUNDING,
+ ATTR_MATHFN_FPROUNDING_ERRNO): New macros. Use throughout.
+
+2003-08-01 Andreas Krebbel <krebbel1@de.ibm.com>
+
+ * config/s390/s390.c (s390_select_ccmode): Do not attempt to use CCL,
+ CCL1, or CCL2 modes with floating point operations.
+
+ * config/s390/s390.md ("*addsf3_cc", "*addsf3_cconly", "*adddf3_cc",
+ "*adddf3_cconly", "*subsf3_cc", "*subsf3_cconly", "*subdf3_cc",
+ "*subdf3_cconly"): New insns.
+ ("*negabssi2", "*negabsdi2", "*negabsdf2", "*negabssf2"): Likewise.
+
+2003-08-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Refine dependencies.
+ * c-opts.c (c_common_handle_option): Do nothing for -Wimport.
+ * c.opt: Update help for -Wimport.
+ * cppfiles.c: Include hashtab.h. Update comments.
+ (stack_file): Read the file before updating dependencies.
+ (once_only_file_p): Be smarter about marking once-only files.
+ (_cpp_mark_file_once_only): Correct the check for existence on
+ the list.
+ (open_file_failed): Use name not path, which is NULL.
+ * cpphash.h: Don't include hashtab.h.
+ (struct _cpp_file): Remove.
+ (struct cpp_reader): Update.
+ * cppinit.c (cpp_create_reader): Don't initialize warn_import.
+ * cpplib.h (struct cpp_options): Remove warn_import.
+ (cpp_simplify_path): Remove.
+
+2003-08-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11295
+ * doc/extend.texi (Statement Expressions): Document C++ semantics.
+
+2003-07-31 SUGIOKA Toshinobu <sugioka@itonet.co.jp>
+
+ * config.gcc (sh-*-linux*): Do not override sh/t-linux with sh/t-le.
+
+2003-07-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-types.def: Use `LONGDOUBLE' instead of `LONG_DOUBLE'
+ throughout.
+ * builtins.def: Likewise.
+
+2003-07-31 Jason Merrill <jason@redhat.com>
+
+ * Makefile.in (bubblestrap): Don't require a previous full
+ bootstrap.
+
+ * expr.c (mostly_zeros_p): No longer static.
+ * tree.h: Declare it.
+ * stmt.c (resolve_asm_operand_names): Don't copy the pattern
+ unless we need to do substitutions.
+
+2003-07-31 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold <MULT_EXPR>): Optimize both x*pow(x,c) and
+ pow(x,c)*x as pow(x,c+1) for constant values c. Optimize x*x
+ as pow(x,2.0) when the latter will be expanded back into x*x.
+ (fold <RDIV_EXPR>): Optimize pow(x,c)/x as pow(x,c-1).
+ * builtins.c (expand_builtin_pow): Ignore flag_errno_math as
+ pow can never set errno when used with an integer exponent.
+ Always use expand_powi when exponent is -1, 0, 1 or 2.
+ (fold_builtin): Don't rewrite pow(x,2.0) as x*x nor pow(x,-2.0)
+ as 1.0/(x*x). This avoids unbounded recursion as we now prefer
+ the pow forms of these expressions.
+
+2003-07-31 Geoffrey Keating <geoffk@apple.com>
+
+ * Makefile.in (libexecdir): New.
+ (libsubdir): Use gcc instead of gcc-lib.
+ (libexecsubdir): New.
+ (ORDINARY_FLAGS_TO_PASS): Add libexecsubdir.
+ (DRIVER_DEFINES): Add STANDARD_LIBEXEC_PREFIX, use gcc instead of
+ gcc-lib.
+ (installdirs): Make libexecsubdir.
+ (install-common): Put executables in libexecsubdir.
+ (itoolsdir): Use libexecsubdir.
+ (itoolsdatadir): New.
+ (install-mkheaders): Separate data files and executables.
+ (install-collect2): Put executables in libexecsubdir.
+ (uninstall): Remove libexecsubdir.
+ * mkheaders.in: Update for new arrangement of files.
+ (libexecdir): New.
+ (libexecsubdir): New.
+ (itoolsdir): Use libexecsubdir.
+ (itoolsdatadir): New.
+ * gcc.c (gcc_libexec_prefix): New.
+ (STANDARD_LIBEXEC_PREFIX): Use gcc instead of gcc-lib.
+ (standard_exec_prefix_1): Use libexec.
+ (standard_exec_prefix_2): New.
+ (standard_libexec_prefix): New.
+ (process_command): Update for new arrangement of files. Compute
+ gcc_libexec_prefix. Update for change from gcc-lib to gcc.
+
+2003-07-31 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * inclhack.def (stdio_va_list): Avoid bogus replacement which
+ triggers on Interix.
+ * fixincl.x: Regenerate.
+
+2003-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (legitimate_pic_address_disp_p): Disallow TLS
+ SYMBOL_REFs not inside UNSPEC even in PLUS rtx.
+
+2003-07-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * dwarf2out.c (loc_descriptor_from_tree, case CONSTRUCTOR): New case.
+
+2003-07-31 Per Bothner <pbothner@apple.com>
+
+ * opts.c (in_fnames, num_in_fnames): Moved here from c-opts.
+ (add_input_filename): New function.
+ (handle_options): Call add_input_filename directly instead of
+ with a lang hook.
+ * opts.h (in_fnames, num_in_fnames): Moved here.
+ (add_input_filename): Declare.
+ * c-decl.c: Need to #include opts.h.
+ * Makefile.in (c-decl.o): Also depends on opts.h.
+ * c-opts.c (in_fnames, num_in_fnames): Moved to opts.c.
+ (c_common_handle_filename): Replaced by add_input_filename.
+ * c-common.h (in_fnames, num_in_fnames, c_common_handle_filename):
+ Remove.
+ * langhooks.h (struct lang_hooks): Remove handle_filename hook.
+ * langhooks-def.h (LANG_HOOKS_HANDLE_FILENAME): Remove macro.
+ (LANG_HOOKS_INITIALIZER): Remove use of LANG_HOOKS_HANDLE_FILENAME.
+ * c-lang.c (LANG_HOOKS_HANDLE_FILENAME): Remove macro.
+
+2003-07-31 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * combine.c (try_combine): Set JUMP_LABEL for newly created
+ unconditional jump.
+
+2003-07-31 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * fold-const.c (fold): Fold some comparisons of bit operations.
+
+2003-07-31 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (create_edge): Fix typo.
+ * i386.c (pic_symbolic_operand): Reorder tests.
+
+2003-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * doc/gcov.texi (Invoking Gcov): Describe output name mangling
+ more fully.
+ (Gcov Data Files): Update.
+
+2003-07-31 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config.gcc (alpha*-dec-osf[45]*): Enable POSIX thread support by
+ default.
+
+ * gthr-posix.c: New file.
+ * gthr-posix.h: Define _REENTRANT if missing.
+ Make _LIBOBJC #pragma weak visible with _LIBOBJC_WEAK.
+
+ * config/alpha/t-osf4 (SHLIB_LINK): Hide dummy functions provided
+ by gthr-posix.o.
+ * config/alpha/t-osf-pthread: New file.
+
+ * fixinc/inclhack.def (alpha_pthread): New fix.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/pthread.h [ALPHA_PTHREAD_CHECK]: New testcase.
+
+ * doc/install.texi (alpha*-dec-osf*): Remove --enable-threads
+ warning.
+ Fixes PR bootstrap/9330.
+
+2003-07-31 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (gcc_cv_ld_hidden): Also disable on mips-sgi-irix5*
+ without GNU ld.
+ Update comment.
+ * configure: Regenerate.
+
+2003-07-31 Vladimir Makarov <vmakarov@redhat.com>
+
+ * sched-deps.c (sched_analyze_2): Prevent interblock move of CC0
+ setter.
+
+2003-07-30 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def: Alphabetize.
+
+2003-07-30 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * doc/c-tree.texi: Normalize spellings of "lowercase" and
+ "uppercase".
+ * doc/cpp.texi: Likewise.
+ * doc/md.texi: Likewise.
+ * doc/rtl.texi: Likewise.
+ * doc/tm.texi: Likewise.
+
+2003-07-30 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * objc/Make-lang.in (objc.stage1, objc.stage2, objc.stage3)
+ (objc.stage4, objc.stageprofile, objc.stagefeedback): Remove moves
+ of cc1obj.
+
+2003-07-30 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.h (SIZE_TYPE, PTRDIFF_TYPE): Undef these
+ macros before defining them.
+
+2003-07-31 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md (UNSPEC_ROUND, UNSPEC_SETHIGH,
+ UNSPECV_BLOCKAGE): New constants.
+ ("*sethighqisi", "*sethighhisi", "*sethiqidi_64", "*sethiqidi_31",
+ "*extractqi", "*extracthi", "*extendqidi2" splitter, "*extendqisi2"
+ splitter, "fix_truncdfdi2_ieee", "fix_truncdfsi2_ieee",
+ "fix_truncsfdi2", "fix_truncsfsi2", "blockage"): Use them.
+
+ (all insns and expanders): Write output control string as brace block
+ where appropriate. Remove \-escapes for doublequote characters.
+
+2003-07-31 Jan Hubicka <jh@suse.cz>
+
+ * gcse.c (insert_store): Fix typo in previous patch.
+
+2003-07-30 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (stack_file, open_file_failed): Use path for deps.
+
+2003-07-30 Andi Kleen <ak@muc.de>
+
+ * loop.c (check_dbra_loop): Allow LTU in the loop condition.
+
+2003-07-30 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * combine.c (distribute_notes): Cancel REG_VALUE_PROFILE notes.
+ * gcov-io.h (GCOV_FIRST_VALUE_COUNTER, GCOV_LAST_VALUE_COUNTER,
+ GCOV_N_VALUE_COUNTERS): New.
+ * profile.c (compute_value_histograms): New static function.
+ (branch_prob): Read back the value histograms.
+ * rtl.c (reg_note_name): Add name for REG_VALUE_PROFILE note.
+ * rtl.h (enum reg_note): Add REG_VALUE_PROFILE note.
+ * value-prof.c: Add comment on reading the profile.
+ * value-prof.h (COUNTER_FOR_HIST_TYPE, HIST_TYPE_FOR_COUNTER): New.
+ * doc/invoke.texi (-fprofile-values): Document behavior with
+ -fbranch-probabilities.
+
+2003-07-30 David Edelsohn <edelsohn@gnu.org>
+
+ * longlong.h (PowerPC umul_ppmm): Do not test __vxworks__.
+
+2003-07-30 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h (EH_RETURN_HANDLER_RTX): Compute offset
+ symbolically.
+
+2003-07-30 Jan Hubicka <jh@suse.cz>
+
+ * gcse.c (insert_store): Ignore fake edges.
+
+ * c-common.c (flag_vtable_gc): Kill.
+ * c-common.g (flag_vtable_gc): Kill.
+ * c-opts (c_common_handle_option): Kill.
+ * c.opt (fvtable-gc): Kill.
+ * final.c (final_scan_insn): Do not call assemble_vtable_entry.
+ * output.h (assemble_vtable_entry, assemble_vtable_inherit): Kill.
+ * varasm.c (assemble_vtable_entry, assemble_vtable_inherit): Kill.
+
+ * invoke.texi (-ftable-gc): Kill documentation.
+
+ * tree-inline.c (inlinable_function_p): Don't set DECL_UNINLINABLE
+ just because function body is missing.
+
+ * i386.c (pic_symbolic_operand): Properly detect RIP relative unspecs.
+
+2003-07-30 Ranjit Mathew <rmathew@hotmail.com>
+
+ * unwind-sjlj.c: Fix typo in file description.
+
+2003-07-30 Alan Modra <amodra@bigpond.net.au>
+
+ * calls.c (load_register_parameters): When shifting reg sized values
+ to the msb, move the value to a reg first.
+
+2003-07-29 Geoffrey Keating <geoffk@apple.com>
+
+ * cppfiles.c (stack_file): Leave filename as "" rather than "<stdin>".
+ * line-map.h (linemap_add): Update comments.
+ * line-map.c (linemap_add): Update comments, interpret zero-length
+ filename as "<stdin>".
+
+2003-07-29 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * mkinstalldirs: Import autoconf 2.57 / automake 1.7 version.
+
+2003-07-29 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (last_function_parm_vars, current_function_parm_vars):
+ New static variables.
+ (struct c_scope): Add parms and warned_forward_parm_decls
+ fields; remove parm_order.
+ (storedecls, storetags): Delete.
+ (poplevel): Also clear bindings on the parms chain.
+ (pushdecl): Handle forward declarations of parameters, and
+ chain PARM_DECLs on the parms list, not the names list.
+ (lookup_name_current_level): Check for PARM_DECLs on the parms
+ list too.
+ (push_parm_decl): Don't update parm_order.
+ (clear_parm_order): Rename mark_forward_parm_decls. Issue the
+ warning, only once per parameter list, and set TREE_ASM_WRITTEN
+ on the decls here. Then move the forward decls to the names list.
+ (grokparms): Set last_function_parm_vars.
+ (get_parm_info): Don't use gettags or getdecls. No need to
+ extract non-parms from the parms list, or reorganize the parms
+ list. Feed nonparms back in the TREE_TYPE of the list node
+ returned. Issue only one error per parameter list for "void"
+ appearing more than once in said parameter list. Collapse
+ parmlist_tags_warning into this function to avoid double scan
+ of tags list.
+ (start_function): Set current_function_parm_vars.
+ (store_parm_decls_newstyle): Bypass pushdecl, manipulate scope
+ directly. Get non-parms from current_function_parm_vars; no
+ need to extract them from the parms chain. Properly bind tags
+ in the new scope.
+ (store_parm_decls_oldstyle): No need to extract non-parameters
+ from the parms chain, nor to store them back afterward. Move
+ declaration to top of function, restructure code reordering
+ DECL_ARGUMENTS.
+ (store_parm_decls): No need to save and restore warn_shadow.
+ * c-parse.in: Don't call parmlist_tags_warning nor
+ clear_parm_order. Call mark_forward_parm_decls when forward
+ parm decls are encountered.
+ * c-tree.h: Prototype mark_forward_parm_decls; not
+ clear_parm_order or parmlist_tags_warning.
+
+2003-07-29 Geoffrey Keating <geoffk@apple.com>
+
+ * c-common.c (allow_pch): Remove.
+ * c-common.h (allow_pch): Remove.
+ (c_common_no_more_pch): Declare.
+ * c-lex.c (c_lex): Call c_common_no_more_pch when appropriate.
+ * c-pch.c: Include hosthooks.h.
+ (c_common_valid_pch): Don't check allow_pch.
+ (c_common_read_pch): Clear valid_pch to prevent reading PCH files.
+ (c_common_no_more_pch): New.
+ * ggc-common.c: Include hosthooks.h.
+ (gt_pch_save): Call gt_pch_get_address.
+ (gt_pch_restore): Call gt_pch_use_address.
+ * hooks.c (hook_voidp_size_t_null): New.
+ (hook_bool_voidp_size_t_false): New.
+ * hooks.h (hook_voidp_size_t_null): New.
+ (hook_bool_voidp_size_t_false): New.
+ * hosthooks-def.h (HOST_HOOKS_GT_PCH_GET_ADDRESS): New.
+ (HOST_HOOKS_GT_PCH_USE_ADDRESS): New.
+ (HOST_HOOKS_INITIALIZER): Add HOST_HOOKS_GT_PCH_GET_ADDRESS,
+ HOST_HOOKS_GT_PCH_USE_ADDRESS.
+ * hosthooks.h (struct host_hooks): Add gt_pch_get_address,
+ gt_pch_use_address.
+ * doc/hostconfig.texi (Host Common): Document
+ HOST_HOOKS_GT_PCH_GET_ADDRESS, HOST_HOOKS_GT_PCH_USE_ADDRESS.
+ * Makefile.in (c-pch.o): Depend on hosthooks.h.
+ (ggc-common.o): Likewise.
+
+ * config/rs6000/host-darwin.c (HOST_HOOKS_GT_PCH_GET_ADDRESS): Define.
+ (HOST_HOOKS_GT_PCH_USE_ADDRESS): Define.
+ (pch_address_space): New.
+ (darwin_rs6000_gt_pch_get_address): New.
+ (darwin_rs6000_gt_pch_use_address): New.
+
+2003-07-29 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/11569
+ PR preprocessor/11649
+ * Makefile.in (LIBCPP_DEPS): Add HASHTAB_H.
+ * cppfiles.c: Completely rewritten.
+ * c-incpath.c (free_path, remove_duplicates, heads, tails, add_path):
+ struct cpp_path is now struct cpp_dir.
+ (remove_duplicates): Don't simplify path names.
+ * c-opts.c (c_common_parse_file): cpp_read_next_file renamed
+ cpp_stack_file.
+ * cpphash.h: Include hashtab.h.
+ (_cpp_file): Declare.
+ (struct cpp_buffer): struct include_file is now struct _cpp_file,
+ and struct cpp_path is now struct cpp_dir. Rename members.
+ (struct cpp_reader): Similarly. New members once_only_files,
+ file_hash, file_hash_entries, quote_ignores_source_dir,
+ no_search_path, saw_pragma_once. Remove all_include_files and
+ max_include_len. Make some members bool.
+ (_cpp_mark_only_only): Renamed from _cpp_never_reread.
+ (_cpp_stack_file): Renamed from _cpp_read_file.
+ (_cpp_stack_include): Renamed from _cpp_execute_include.
+ (_cpp_init_files): Renamed from _cpp_init_includes.
+ (_cpp_cleanup_files): Renamed from _cpp_cleanup_includes.
+ * cppinit.c (cpp_create_reader): Initialize no_search_path. Update.
+ (cpp_read_next_file): Rename and move to cppfiles.c.
+ (cpp_read_main_file): Update.
+ * cpplib.c (run_directive): Update for renamed members.
+ (do_include_common, _cpp_pop_buffer): Update.
+ (do_import): Undeprecate #import.
+ (do_pragma_once): Undeprecate. Use _cpp_mark_file_once_only.
+ * cpplib.h: Remove file_name_map_list.
+ (cpp_options): Remove map_list.
+ (cpp_dir): Rename from cpp_path. New datatype for name_map.
+ (cpp_set_include_chains, cpp_stack_file, cpp_included): Update.
+
+2003-07-29 Phil Edwards <pme@gcc.gnu.org>
+
+ * Makefile.in: Make stamp-objdir safe for parallel builds.
+
+2003-07-29 Phil Edwards <pme@gcc.gnu.org>
+
+ * Makefile.in (stmp-docobjdir): New target; ensure $docobjdir exists.
+ (info): Depend on stmp-docobjdir.
+
+2003-07-29 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure: Regenerate.
+
+2003-07-29 Jan Hubicka <jh@suse.cz>
+
+ PR C++/11131
+ * tree-inline.c (expand_call_inline): Always call inlinable_function_p
+ in !unit-at-a-time mode.
+
+2003-07-28 Geoffrey Keating <geoffk@apple.com>
+
+ * c-decl.c (c_expand_body_1): Use C_DECL_FILE_SCOPE to detect
+ main function.
+
+2003-07-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11667
+ * c-common.c (shorten_compare): Take into account differences
+ between C and C++ representation for enumeration types.
+ * tree.h (set_min_and_max_values_for_integral_type): Declare.
+ * stor-layout.c (set_min_and_max_values_for_integral_type): New
+ function, broken out from ...
+ (fixup_signed_type): ... here and ...
+ (fixup_unsigned_type): ... here.
+
+2003-07-28 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c: Update commentary, adjust blank lines throughout.
+ (struct c_scope): Fix indentation. Reorder members so
+ outer-context pointers come first, booleans last.
+ (duplicate_decls, define_label): Use a 'locus' variable for
+ diagnostic locations in a few more places.
+ (warn_if_shadowing): Un-split a conditional that fits on one line.
+ (c_init_decl_processing): No need to clear current_scope and
+ current_function_scope.
+ (start_decl): Merge if/else if statements with same action.
+ (push_parm_decl): Rename old_immediate_size_expand to use
+ save_foo convention; save/restore around entire function.
+ (grokdeclarator): Remove unnecessary braces.
+
+2003-07-28 Hans-Peter Nilsson <hp@bitrange.com>
+ Michael Culbertson <Michael.J.Culbertson@wheaton.edu>
+
+ * c-parse.in (lineno_stmt_decl_or_labels_ending_decl): Also warn
+ when warn_declaration_after_statement. Call pedwarn_c90, not
+ pedwarn. Correct message: it's "ISO C90", not "ISO C89".
+ * c-common.c (warn_declaration_after_statement): Define.
+ * c-common.h (warn_declaration_after_statement): Declare.
+ * c.opt (Wdeclaration-after-statement): New.
+ * c-errors.c (pedwarn_c90): New function.
+ * c-opts.c (c_common_handle_option) <case
+ OPT_Wdeclaration_after_statement>: New.
+ * c-tree.h (pedwarn_c90): Declare.
+ * doc/invoke.texi (Option Summary): Document
+ -Wdeclaration-after-statement.
+ (Warning Options): Ditto.
+
+2003-07-28 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (memory attribute) Avoid accessing uninitialized memory
+ for ishift1 type instructions.
+
+2003-07-28 Jakub Jelinek <jakub@redhat.com>
+
+ * configure.in (--enable-checking): Add fold category.
+ (ENABLE_FOLD_CHECKING): Define if requested.
+ * configure: Rebuilt.
+ * config.in: Rebuilt.
+ * doc/install.texi: Document it.
+ * fold-const.c: Include md5.h.
+ [ENABLE_FOLD_CHECKING] (fold): Define to fold_1.
+ [ENABLE_FOLD_CHECKING] (fold, fold_checksum_tree, fold_check_failed,
+ print_fold_checksum): New functions.
+
+ * fold-const.c (fold): Never modify argument passed to fold, instead
+ change a copy and return it.
+ * convert.c (convert_to_integer): Likewise.
+
+2003-07-27 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/fixinc.svr4: Remove dead code. Remove now-unnecessary
+ cleanup of junk after #else and #endif directives. Collapse repeated
+ clauses into for statment.
+
+ * fixinc/fixincl.sh: GNU C -> GCC. Add usage comment.
+
+2003-07-27 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (struct c_scope): Remove keep_if_subblocks field.
+ (keep_next_if_subblocks): Rename next_is_function_body.
+ (pushlevel): Adjust commentary. Always set ->keep on the
+ outermost level of a function. Don't set ->keep_if_subblocks.
+ (poplevel): Adjust commentary. Don't look at ->keep_if_subblocks.
+ (store_parm_decls): Adjust to match.
+ (finish_function): Adjust to match.
+ Call poplevel with all three arguments zero.
+
+ * c-decl.c (store_parm_decls_newstyle, store_parm_decls_oldstyle):
+ New functions split out of store_parm_decls.
+ Avoid unnecessary work. Use local variables consistently.
+ (store_parm_decls): Likewise.
+
+ (finish_function): No need to set functionbody flag on call to
+ poplevel.
+ (struct language_function): Remove scope field.
+ (c_push_function_context, c_pop_function_context): No need to
+ save and restore current_scope.
+
+2003-07-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * doc/extend.texi (Deprecated Features): Implicit typename is
+ gone. Default args on types is going.
+
+2003-07-26 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * Makefile.in (ifcvt.o): Depend on target.h
+ * ifcvt.c (target.h): Include.
+ (if_convert): Don't call mark_loop_exit_edges if we can't
+ modify jumps.
+
+2003-07-26 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/install.texi (Testing): Adjust required versions of DejaGnu.
+
+2003-07-26 Richard Henderson <rth@redhat.com>
+
+ PR inline-asm/11676
+ * cse.c (count_reg_usage): Handle asm_operands properly.
+
+2003-07-26 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def (DEF_FALLBACK_BUILTIN): Delete.
+ (DEF_EXT_FALLBACK_BUILTIN): Delete.
+ (BUILT_IN_BZERO, BUILT_IN_BCOPY, BUILT_IN_BCMP): Declare using
+ the regular DEF_EXT_LIB_BUILTIN macro.
+ (BUILT_IN_FPUTC, BUILT_IN_FPUTS, BUILT_IN_FWRITE): Declare using
+ the regular DEF_LIB_BUILTIN macro.
+ (BUILT_IN_PUTCHAR_UNLOCKED, BUILT_IN_PUTS_UNLOCKED,
+ BUILT_IN_FPUTC_UNLOCKED, BUILT_IN_FPUTS_UNLOCKED,
+ BUILT_IN_FWRITE_UNLOCKED): Declare using the regular
+ DEF_EXT_LIB_BUILTIN macro.
+
+ * c-decl.c (duplicate_decls): Remove code to handle builtin
+ functions prototyped without an argument list.
+
+2003-07-26 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/winnt.c: Revert 2003-07-08 change.
+ (i386_pe_section_type_flags): Remove error_with_decl here too.
+
+2003-07-26 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * config/arm/pe.c (arm_mark_dllimport): Don't use xxx_with_decl.
+ * config/mcore/mcore.c (mcore_mark_dllimport): Likewise.
+ * config/v850/v850.c (v850_handle_data_area_attribute): Likewise.
+ (v850_handle_data_area_attribute): Likewise.
+
+2003-07-26 Geoffrey Keating <geoffk@apple.com>
+
+ * varasm.c (output_constant_def_contents): Use
+ ASM_DECLARE_CONSTANT_NAME if defined.
+ * doc/tm.texi (Label Output): Document ASM_DECLARE_CONSTANT_NAME.
+ * config/darwin.h (ASM_DECLARE_OBJECT_NAME): Ensure zero-sized
+ objects get at least one byte to prevent assembler problems.
+ (ASM_DECLARE_CONSTANT_NAME): New.
+
+ * Makefile.in (libbackend.o): Remove options_.h.
+ (mostlyclean): Likewise.
+
+ * config/rs6000/rs6000.c (rs6000_output_function_epilogue): Don't
+ insert a label at the end of an function under Mach-O.
+
+ * c-decl.c (c_static_assembler_name): Remove TREE_STATIC test.
+
+2003-07-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (is_ev64_opaque_type): Only check pointer
+ equality.
+ (spe_init_builtins): Declare __ev64_opaque__ as a builtin type.
+
+ * config/rs6000/spe.h: Remove __ev64_opaque__ definition.
+
+2003-07-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * doc/passes.texi (Passes): Mention pretty-printing and
+ diagnostic files.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * doc/extend.texi (Function Attributes): GNU C++ does now allow
+ unused parameter decls.
+ (Attribute Syntax): GNU C++ does not allow label attributes to be
+ after the ':'.
+
+2003-07-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * objc/objc-act.c (objc_check_decl): Don't use xxx_with_decl.
+ (objc_declare_class): Likewise.
+ (error_with_ivar): Likewise.
+ (start_class): Likewise.
+ (warn_with_method): Likewise.
+
+2003-07-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove pedwarn_with_decl, warning_with_decl and error_with_decl
+ from GCC.
+ * calls.c (try_to_integrate): Don't use xxx_with_decl.
+ (expand_call): Likewise.
+ * dwarfout.c (output_reg_number): Likewise.
+ * expr.c (expand_expr): Likewise.
+ * function.c (assign_temp): Likewise.
+ (uninitialized_vars_warning): Likewise.
+ (setjmp_args_warning): Likewise.
+ (expand_function_end): Likewise.
+ * stmt.c (fixup_gotos): Likewise.
+ (warn_about_unused_variables): Likewise.
+ (expand_end_bindings): Likewise.
+ * stor-layout.c (layout_decl): Likewise.
+ (place_field): Likewise.
+ * toplev.c (check_global_declarations): Likewise.
+ (rest_of_handle_inlining): Likewise.
+ (default_tree_printer): New function.
+ (general_init): Initialize diagnostic machinery before routing
+ signals to the ICE machinery. Set default tree printer.
+ * toplev.h (pedwarn_with_decl): Remove declaration.
+ (warning_with_decl): Likewise.
+ (error_with_decl): Likewise.
+ (pedwarn): Remove attribute for the time being.
+ * tree-inline.c (expand_call_inline): Don't use xxx_with_decl.
+ * varasm.c (named_section): Likewise.
+ (make_decl_rtl): Likewise.
+ (assemble_variable): Likewise.
+ (merge_weak): Likewise.
+ (declare_weak): Likewise.
+
+ * diagnostic.h: Move non-diagnostic stuff into pretty-print.h.
+ * diagnostic.c: Move non-diagnostic stuff into pretty-print.c.
+ (format_with_decl): Remove.
+ (diagnostic_for_decl): Likewise.
+ (pedwarn_with_decl): Likewise.
+ (warning_with_decl): Likewise.
+ (error_with_decl): Likewise.
+ (diagnostic_initialize): Adjust.
+ (diagnostic_count_diagnostic): Likewise.
+ (announce_function): Likewise.
+ (lhd_print_error_function): Likewise.
+ (diagnostic_report_current_module): Likewise.
+ (default_diagnostic_starter): Likewise.
+ (diagnostic_report_diagnostic): Likewise.
+ (default_diagnostic_finalizer): Likewise.
+ (verbatim): Likewise.
+ (error): Likewise.
+ (warning): Likewise.
+ * opts.c (common_handle_option): Likewise.
+ * pretty-print.c: New file.
+ * c-pretty-print.h (pp_base): Override.
+ * c-pretty-print.c: Adjust use of macros throughout.
+ (pp_buffer): New macro.
+ (pp_newline): Likewise.
+ * c-objc-common.c (c_tree_printer): Adjust prototype. Tidy.
+ * Makefile.in (DIAGNOSTIC_H): New variable.
+ (c-errors.o): Use it.
+ (c-objc-common.o): Likewise.
+ (c-common.o): Likewise.
+ (c-opts.o): Likewise.
+ (c-format.o): Likewise.
+ (diagnostic.o): Likewise.
+ (opts.o): Likewise.
+ (toplev.o): Likewise.
+ (rtl-error.o): Likewise.
+ (dwarf2out.o): Likewise.
+ (jump.o): Likewise.
+ (pretty-print.o): New rule.
+
+2003-07-24 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def (BUILT_IN_PRINTF, BUILT_IN_FPRINTF): Changed from
+ front-end builtins to normal builtins, using DEF_LIB_BUILTIN.
+ (BUILT_IN_PRINTF_UNLOCKED, BUILT_IN_FPRINTF_UNLOCKED): Changed
+ from front-end to normal builtins, using DEF_EXT_LIB_BUILTIN.
+ (DEF_FRONT_END_LIB_BUILTIN): Delete.
+ (DEF_EXT_FRONT_END_LIB_BUILTIN): Delete.
+ (BUILT_IN_FWRITE_UNLOCKED): Wrap long line.
+
+ * builtins.c (build_string_literal): New function to construct
+ a char* pointer to a string literal.
+ (expand_builtin_fputs): Change 2nd argument from "int ignore" to
+ "rtx target" to be consistent with other expand_builtin_* functions.
+ Change 3rd argument from "int unlocked" to "bool unlocked".
+ (expand_builtin_printf): Rewrite of c_expand_builtin_printf from
+ c-common.c to avoid front-end dependencies. Optimize printf("")
+ as a no-op when the result isn't required. Handle embedded NULs
+ in format string.
+ (expand_builtin_fprintf): A rewrite of c_expand_builtin_fprintf
+ from c-common.c to avoid front-end dependencies. Likewise, optimize
+ fprintf(fp,"") as a no-op when the result isn't required, evaluating
+ fp for side-effects. Handle embedded NULs in format string.
+ (expand_builtin_sprintf): Fix typo.
+ (expand_builtin): Don't expand BUILT_IN_FPRINT{,_UNLOCKED} when not
+ optimizing. Adjust calls of expand_builtin_fputs to match the API
+ change. Expand BUILT_IN_PRINTF and BUILT_IN_PRINTF_UNLOCKED using
+ expand_builtin_printf. Likewise, expand BUILT_IN_FPRINTF_UNLOCKED
+ and BUILT_IN_FPRINTF using expand_builtin_fprintf.
+
+ * c-common.c (is_valid_printf_arglist): Delete.
+ (c_expand_builtin): Delete.
+ (c_expand_builtin_printf): Moved to builtins.c. Delete.
+ (c_expand_builtin_fprintf): Moved to builtins.c. Delete.
+ (c_expand_expr): No longer treat CALL_EXPRs specially.
+ (CALLED_AS_BUILT_IN): Delete.
+
+2003-07-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR optimization/11631
+ * gcse.c (store_motion): Connect infinite loops to exit.
+
+2003-07-24 Jason Merrill <jason@redhat.com>
+
+ * tree.h (boolean_type_node): Move from C/C++/Java frontends.
+ (boolean_true_node, boolean_false_node): Likewise.
+ (enum tree_index): Add TI_BOOLEAN_{TYPE,FALSE,TRUE}.
+ * tree.c (build_common_tree_nodes): Init boolean_type_node.
+ (build_common_tree_nodes_2): Init boolean_{true,false}_node.
+ * stor-layout.c (set_sizetype): Handle an early BOOLEAN_TYPE.
+ * c-common.h (truthvalue_type_node): Renamed from boolean_type_node.
+ (truthvalue_true_node): Renamed from boolean_true_node.
+ (truthvalue_false_node): Renamed from boolean_false_node.
+ * c-decl.c: Just set truthvalue_* to integer_*.
+ * c-*.[ch]: s/boolean/truthvalue/. s/c_bool/boolean/.
+
+2003-07-24 Roger Sayle <roger@eyesopen.com>
+
+ * c-decl.c (match_builtin_function_types): New subroutine of
+ duplicate_decls to test whether a redeclaration of a builtin
+ function is suitably close, i.e. the return type and all of
+ the argument types have the same modes as the builtin expects.
+ (duplicate_decls): Fuzzy type matching for builtin functions
+ moved to match_builtin_function_types.
+
+2003-07-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopmanip.c (duplicate_loop_to_header_edge): Update irreducible
+ flag correctly.
+
+2003-07-24 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c: Search-and-replace change 'binding level' to
+ 'scope' in commentary.
+ (struct binding_level): Now struct c_scope.
+ (current_binding_level): Now current_scope.
+ (free_binding_level): Now scope_freelist.
+ (current_function_level): Now current_function_scope.
+ (global_binding_level): Now global_scope.
+ (make_binding_level): Now make_scope.
+ (pop_binding_level): Now pop_scope.
+
+2003-07-24 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (libgcc_visibility): Add missing whitespace.
+
+2003-07-24 Richard Henderson <rth@redhat.com>
+
+ * libgcc-std.ver (GCC_3.3.1): Export __gcc_personality_sj0,
+ __gcc_personality_v0.
+
+2003-07-24 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * Makefile.in: Replace pwd by ${PWD_COMMAND}.
+
+2003-07-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * doc/invoke.texi (-fprofile-arcs, -ftest-coverage): Update
+ documentation missed from my 2003-07-09 patch.
+
+2003-07-24 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * aclocal.m4 (_gcc_COMPUTE_GAS_VERSION): Set patch level to 0 if
+ it's not provided.
+ * configure: Rebuild.
+
+2003-07-24 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR c/10602
+ * c-typeck.c (type_lists_compatible_p): Do not compare
+ arguments if one of them is an error_mark_node
+
+2003-07-24 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_emit_prologue): Save fp regs inline
+ if current_function_calls_eh_return.
+
+2003-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/c-tree.texi (OFFSET_TYPE): Update description.
+
+2003-07-23 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/crti.asm (_init, _fini): Increase frame size to 64.
+ * config/xtensa/lib1funcs.asm (__mulsi3, __udivsi3, __divsi3,
+ __umodsi3, __modsi3): Increase frame size to 32.
+
+2003-07-23 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/host-darwin.c: ANSIfy, update comment for sigaltstack
+ prototype.
+
+2003-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/c-tree.texi (Types): Update documentation for OFFSET_TYPE.
+
+ PR optimization/10679
+ * tree-inline.c (inlinable_function_p): Honor MIN_INLINE_INSNS.
+
+2003-07-23 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR target/11607 and PR target/11516
+ * pa.md (extzv, extv, insv): Revert latter half of last patch.
+
+2003-07-22 Mark Mitchell <mark@codesourcery.com>
+
+ * fold-const.c (force_fit_type): Handle OFFSET_TYPE.
+ * varasam.c (output_constant): Likewise.
+
+2003-07-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alias.c: Fix comment formatting.
+ * c-common.c: Likewise.
+ * c-decl.c: Likewise.
+ * c-opts.c: Likewise.
+ * combine.c: Likewise.
+ * cpplib.c: Likewise.
+ * diagnostic.c: Likewise.
+ * dojump.c: Likewise.
+ * final.c: Likewise.
+ * fold-const.c: Likewise.
+ * gcc.c: Likewise.
+ * gcse.c: Likewise.
+ * ggc-page.c: Likewise.
+ * jump.c: Likewise.
+ * loop.c: Likewise.
+ * mips-tfile.c: Likewise.
+ * recog.c: Likewise.
+ * regclass.c: Likewise.
+ * regmove.c: Likewise.
+ * tree.c: Likewise.
+ * tree.h: Likewise.
+
+2003-07-22 Per Bothner <pbothner@apple.com>
+
+ * line-map.c (add_line_map): Handle invalid LEAVE request.
+ Fixes PR preprocessor/11361.
+
+2003-07-22 Per Bothner <pbothner@apple.com>
+
+ * diagnostic.c.(diagnostic_report_current_module): Update to match
+ 2003-06-05 changes to push_srcloc and pop_srcloc.
+
+2003-07-22 Wolfgang Bangerth <bangerth@dealii.org>
+
+ * doc/trouble.texi: Better document two-stage name lookup.
+
+2003-07-22 Eric Christopher <echristo@redhat.com>
+
+ * config/s390.c (s390_valid_pointer_mode): New.
+ (TARGET_VALID_POINTER_MODE): Use.
+ (s390_emit_prologue): Add tpf profiling hooks.
+ (s390_emit_epilogue): Ditto.
+ * config/s390.h (MASK_TPF): New.
+ (TARGET_TPF): Use.
+ (POINTERS_EXTEND_UNSIGNED): Define.
+ * config/s390.md (ptr_extend): New pattern.
+
+2003-07-22 Zack Weinberg <zack@codesourcery.com>
+
+ * hashtable.c (approx_sqrt): Make static.
+ * hashtable.h: Don't prototype approx_sqrt.
+ * line-map.c (init_line_maps): Rename linemap_init.
+ (free_line_maps): Rename linemap_free.
+ (add_line_map): Rename linemap_add.
+ (lookup_line): Rename linemap_lookup.
+ (print_containing_files): Rename linemap_print_containing_files.
+ * linemap.h: Update to match.
+
+ * cpperror.c, cppinit.c, cpplib.c, cppmacro.c: Update calls to
+ linemap routines to use new names.
+
+2003-07-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-common.c (handle_packed_attribute): Don't pack a struct via a
+ typedef. Propagate packedness from a main variant.
+
+2003-07-22 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in (install-common): Add dependency on installdirs.
+
+2003-07-21 Alexandre Oliva <aoliva@redhat.com>
+
+ * c-common.c (c_common_type_for_mode): Return integer types for
+ pointer modes.
+
+2003-07-22 Geoffrey Keating <geoffk@apple.com>
+
+ * c-decl.c (start_decl): Don't call maybe_apply_pragma_weak here.
+ (finish_decl): Call maybe_apply_pragma_weak here.
+ (grokdeclarator): Check that DECL_ASSEMBLER_NAME isn't set before
+ TREE_PUBLIC and TREE_STATIC are decided.
+ (start_function): Move call to maybe_apply_pragma_weak. Check that
+ DECL_ASSEMBLER_NAME isn't set too early.
+
+ * cpplex.c (_cpp_process_line_notes): Mention option name in
+ trigraphs warning.
+
+2003-07-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (if_then_else_cond): Simplify the comparison of
+ rtx against -1, 0, and 1.
+ * loop.c (check_dbra_loop): Likewise.
+ * optabs.c (emit_conditional_move): Likewise.
+ (emit_conditional_add): Likewise.
+ * config/i386/i386.md (*movsi_or): Likewise.
+ (*movdi_or_rex6): Likewise.
+
+2003-07-22 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_finalize_compilation_unit): Remove redundant if.
+
+2003-07-21 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (open_file_pch): Don't put unused entries in the
+ splay tree. Remove dead code.
+
+2003-07-21 Geoffrey Keating <geoffk@apple.com>
+
+ * c-common.h (num_in_fnames): Declare.
+ (c_static_assembler_name): Move from here...
+ * c-tree.h (c_static_assembler_name): ... to here.
+ * c-opts.c: Don't include langhooks-def.h.
+ (c_static_assembler_name): Move to c-decl.c.
+ (num_in_fnames): Make externally visible.
+ * c-decl.c: Include langhooks-def.h.
+ (c_static_assembler_name): Move from c-opts.c.
+ * Makefile.in (c-decl.o): Add $(LANGHOOKS_DEF_H).
+ (c-opts.o): Remove $(LANGHOOKS_DEF_H).
+
+ * c-pragma.c (maybe_apply_pragma_weak): Don't get DECL_ASSEMBLER_NAME
+ when it's not needed.
+
+2003-07-21 Jakub Jelinek <jakub@redhat.com>
+
+ * config/rs6000/rs6000.h (machine_function): Add ra_need_lr.
+ * config/rs6000/rs6000.c (rs6000_return_addr): Set it.
+ (rs6000_emit_prologue): Save FPRs inline if set.
+
+2003-07-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/ia64/ia64.md (prefetch): Support predicate.
+
+2003-07-21 Josef Zlomek <zlomekj@suse.cz>
+
+ * cfgcleanup.c (merge_blocks_move_successor_nojumps): Use tablejump_p.
+ * rtlanal.c (tablejump_p): Use next_active_insn for finding the jump
+ table.
+
+2003-07-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11536
+ * unroll.c (loop_iterations): Do not replace a register holding
+ the final value by its equivalent before the loop if it is not
+ invariant.
+
+2003-07-21 Dave Fluri <dave.fluri@onlink.net>
+
+ * doc/extend.texi: Fixes to spelling, grammar, and diction.
+
+2003-07-21 Ben Elliston <bje@wasabisystems.com>
+
+ * doc/invoke.texi (Optimize Options): Replace "it's" with "its".
+ (V850 Options): Spelling fixes.
+
+2003-07-20 Lisa M. Goldstein <opus@gnu.org>
+
+ * doc/invoke.texi: Fixes to style, grammar and diction.
+
+2003-07-20 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def (BUILT_IN_ALLOCA): Remove "#if SMALL_STACK" form.
+ * system.h (SMALL_STACK): Poison obsolete target macro.
+ * doc/tm.texi (SMALL_STACK): Remove target macro documentation.
+
+2003-07-20 Phil Edwards <pme@gcc.gnu.org>
+
+ * configure.in: Cache the results of testing for cmp's capabilities.
+ * configure: Regenerate.
+
+2003-07-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR debug/11279
+ * dwarf2out.c (gen_enumeration_type_die): Remember that
+ enumerators can be unsigned.
+
+2003-07-19 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (named_labels, shadowed_labels, label_level_chain)
+ (push_label_level, pop_label_level): Kill.
+ (struct binding_level): Rename level_chain to outer.
+ Add outer_function field. Change parm_flag, function_body,
+ keep, keep_if_subblocks to 1-bit bitfields of type bool.
+ (current_function_level): New variable.
+ (keep_next_level_flag, keep_next_if_subblocks): Change type to bool.
+ (keep_next_level, declare_parm_level, warn_if_shadowing):
+ Update to match.
+ (struct language_function): Kill named_labels, shadowed_labels fields.
+ (c_init_decl_processing, start_function, c_push__function_context)
+ (c_pop_function_context): No need to muck with named_labels nor
+ shadowed_labels.
+
+ (make_binding_level): No need to clear the structure here.
+ (pop_binding_level): Always operate on current_binding_level.
+ Update current_function_level if necessary.
+ (pushlevel): Don't clear named_labels. Update current_function_level
+ if necessary. Use "true" and "false" where appropriate.
+ (poplevel): Diagnose labels defined but not used, or vice
+ versa, and clear out label-meanings leaving scope, while
+ walking down the decls list, for all binding levels.
+ Handle LABEL_DECLs appearing in the shadowed list.
+ pop_binding_level takes no arguments.
+ (pushdecl_function_level): Use current_function_level.
+
+ (make_label, bind_label): New static functions.
+ (declare_label): New exported function.
+ (lookup_label, define_label): Rewritten for new data structure.
+ (shadow_label): Kill.
+
+ * c-tree.h: Prototype declare_label; don't prototype
+ push_label_level, pop_label_level, nor shadow_label.
+ * c-parse.in: Remove all calls to push_label_level and
+ pop_label_level. Use declare_label for __label__ decls.
+
+ * doc/extend.texi: Clarify that __label__ can be used to
+ declare labels with local scope in any nested block, not
+ just statement expressions. Cross-reference nested functions
+ section from local labels section.
+
+2003-07-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * sched-rgn.c (find_rgns): Initialize current_edge correctly.
+
+2003-07-19 Phil Edwards <pme@gcc.gnu.org>
+
+ * doc/makefile.texi (restrap, profiledbootstrap): Document targets.
+
+2003-07-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fixinc/fixfixes.c fixinc/fixincl.c fixinc/fixlib.c
+ fixinc/server.c objc/objc-act.c: Remove unnecessary casts.
+
+2003-07-19 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (legitimize_pic_address): Access local symbols
+ relative to the GOT instead of relative to the literal pool base.
+ (s390_output_symbolic_const): Handle new GOT-relative accesses.
+ * config/s390/s390.md ("call"): Access local functions and PLT stubs
+ relative to the GOT instead of relative to the literal pool base.
+ ("call_value"): Likewise.
+ ("call_value_tls"): Likewise.
+
+ * config/s390/s390.c (s390_chunkify_start): Remove pool anchor
+ reloading. Support LTREL_BASE / LTREL_OFFSET construct.
+ (s390_chunkify_finish): Likewise.
+ (s390_chunkify_cancel): Likewise.
+ (s390_reorg): Adapt caller.
+ (find_base_register_in_addr,
+ find_base_register_ref, replace_base_register_ref): Delete.
+ (find_ltrel_base, replace_ltrel_base): New functions.
+ (find_constant_pool_ref): Handle LTREL_BASE unspecs.
+ (s390_decompose_address): Handle LTREL_BASE unspecs. Optimize
+ base vs. index register usage.
+ (struct constant_pool): Remove 'anchor'.
+ (s390_add_anchor): Delete.
+ (s390_dump_pool): Remove anchor handling.
+ * config/s390/s390.md ("reload_anchor"): Remove.
+
+ * config/s390/s390.c (s390_split_branches): Use LTREL_BASE/OFFSET.
+ (s390_load_got): New function. Use LTREL_BASE/OFFSET.
+ (s390_emit_prologue): Use it.
+ * config/s390/s390.md ("builtin_longjmp", "builtin_setjmp_setup",
+ "builtin_setjmp_receiver"): Cleanup. Use s390_load_got. Do not
+ hard-code register 14.
+ * config/s390/s390-protos.h (s390_load_got): Declare.
+
+ * config/s390/s390.c (NR_C_MODES, constant_modes, gen_consttable):
+ Support TImode constants.
+ * config/s390/s390.md ("consttable_ti"): New.
+ ("consttable_si", "consttable_di"): Handle TLS symbols correctly.
+
+ * config/s390/s390.md (UNSPEC_LTREL_OFFSET, UNSPEC_LTREL_BASE,
+ UNSPEC_GOTENT, UNSPEC_GOT, UNSPEC_GOTOFF, UNSPEC_PLT, UNSPEC_PLTOFF,
+ UNSPEC_RELOAD_BASE, UNSPECV_POOL, UNSPECV_POOL_START, UNSPECV_POOL_END,
+ UNSPECV_POOL_QI, UNSPECV_POOL_HI, UNSPECV_POOL_SI, UNSPECV_POOL_DI,
+ UNSPECV_POOL_TI, UNSPECV_POOL_SF, UNSPECV_POOL_DF, UNSPECV_MAIN_POOL):
+ New symbolic constants.
+ ("consttable_qi", "consttable_hi", "consttable_si", "consttable_di",
+ "consttable_sf", "consttable_df", "pool_start_31", "pool_end_31",
+ "pool_start_64", "pool_end_64", "reload_base_31", "reload_base_64",
+ "pool", "literal_pool_31", "literal_pool_64"): Cleanup. Use
+ symbolic UNSPEC values.
+ * config/s390/s390.c (larl_operand, s390_short_displacement,
+ bras_sym_operand, s390_cannot_force_const_mem,
+ s390_delegitimize_address, s390_decompose_address,
+ legitimize_pic_address, s390_output_symbolic_const,
+ s390_function_profiler): Use symbolic UNSPEC values.
+
+2003-07-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alias.c alloc-pool.c bitmap.c bitmap.h bt-load.c builtins.c
+ c-common.c c-decl.c c-incpath.c c-lex.c c-opts.c c-parse.in
+ c-pragma.c c-typeck.c calls.c cfg.c cfganal.c cfgloop.c cfgrtl.c
+ collect2.c combine.c conflict.c coverage.c cppexp.c cppfiles.c
+ cpphash.c cppinit.c cpplex.c cpplib.c cppmacro.c cppspec.c
+ cpptrad.c cse.c cselib.c dbxout.c defaults.h df.c dominance.c
+ dwarf2out.c dwarfout.c emit-rtl.c except.c expmed.c expr.c final.c
+ fix-header.c flow.c fold-const.c function.c gcc.c gccspec.c gcov.c
+ gcse.c genattr.c genattrtab.c genautomata.c genconditions.c
+ genemit.c genextract.c genoutput.c genrecog.c gensupport.c
+ ggc-page.c ggc-simple.c global.c graph.c haifa-sched.c hashtable.c
+ integrate.c jump.c langhooks.c lcm.c line-map.c local-alloc.c
+ loop.c mips-tdump.c mips-tfile.c mkdeps.c optabs.c params.c
+ postreload.c prefix.c print-tree.c protoize.c ra-build.c
+ ra-colorize.c ra-rewrite.c ra.c recog.c reg-stack.c regclass.c
+ regmove.c regrename.c reload.c reload1.c reorg.c resource.c
+ sbitmap.c sched-deps.c sched-rgn.c sched-vis.c sdbout.c
+ simplify-rtx.c ssa-ccp.c ssa.c stmt.c stor-layout.c timevar.c
+ tlink.c toplev.c tree-dump.c tree.c unroll.c unwind-dw2-fde.c
+ varasm.c varray.c vmsdbgout.c xcoffout.c: Remove unnecessary
+ casts.
+
+2003-07-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pragma.c (apply_pragma_weak): Don't use warning_with_decl.
+ * toplev.h (warning): Remove attribute.
+
+2003-07-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-decl.c (c_finish_incomplete_decl): Don't use xxx_with_decl.
+ (pop_label_level): Likewise.
+ (duplicate_decls): Likewise.
+ (implicitly_declare): Likewise.
+ (shadow_label): Likewise.
+ (start_decl): Likewise.
+ (finish_decl): Likewise.
+ (grokdeclarator): Likewise.
+ (get_parm_info): Likewise.
+ (detect_field_duplicates): Likewise.
+ (finish_struct): Likewise.
+ (start_function): Likewise.
+ (store_parm_decls): Likewise.
+ (finish_function): Likewise.
+ (c_expand_body_1): Likewise.
+ (check_for_loop_decls): Likewise.
+ (merge_translation_unit_decls): Likewise.
+
+2003-07-19 Neil Booth <neil@daikokuya.co.uk>
+
+ * common.opt: Document --param.
+ * opts.c (columns, undocumented_msg): New.
+ (print_help): Get number of columns from environment. Print
+ --param help. Tweak newline handling.
+ (print_param_help): New.
+ (print_filtered_help): Better handling of duplicates. Complain
+ about undocumented switches.
+ (print_switch): New.
+ (wrap_help): Improve wrapping, use COLUMNS.
+ * opts.sh: Ignore comments in records.
+ * params.def: Fix typos and remove trailing periods.
+ * toplev.c (display_help): Don't dump --param help.
+ * doc/sourcebuild.texi: Update.
+
+2003-07-18 Richard Henderson <rth@redhat.com>
+
+ PR target/11556
+ * optabs.c (prepare_operand): Fail gracefully instead of abort
+ if the predicate doesn't satisfy.
+ (gen_cond_trap): Allow prepare_operand to fail.
+
+2003-07-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-common.c: Don't undefine GCC_DIAG_STYLE.
+ (fname_decl): Don't use xxx_with_decl.
+ (c_add_case_label): Likewise.
+ (handle_section_attribute): Likewise.
+ (handle_alias_attribute): Likewise.
+ (handle_no_instrument_function_attribute): Likewise.
+ (handle_no_limit_stack_attribute): Likewise.
+ * c-objc-common.c (c_tree_printer): Print IDENTIFIER_NODEs.
+ * c-format.c (gcc_cdiag_char_table): Add '%E' format-specifier.
+
+2003-07-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (ifcvt.o): Add cfgloop.h.
+ * basic-block.h (EDGE_LOOP_EXIT): New flag.
+ * cfgrtl.c (rtl_verify_flow_info_1): Handle it correctly.
+ * ifcvt.c: Include cfgloop.h.
+ (mark_loop_exit_edges): New static function.
+ (if_convert): Call it.
+ (find_if_header): Ignore branches out of loops.
+
+2003-07-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (simplify_comparison): Don't share rtx when converting
+ (ne (and (not X) 1) 0) to (eq (and X 1) 0).
+
+2003-07-18 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/aix.h (AGGREGATE_PADDING_FIXED): Define.
+ (AGGREGATES_PAD_UPWARD_ALWAYS): Define.
+ (MUST_PASS_IN_STACK): Define.
+ (BLOCK_REG_PADDING): Define.
+
+2003-07-18 Richard Henderson <rth@redhat.com>
+
+ * cfgrtl.c (force_nonfallthru_and_redirect): Use tablejump_p
+ to skip the addr_vec.
+
+2003-07-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * combine.c (combinable_i3pat): Don't forbid occurrences of
+ i2dest or i1dest in inner_dest if inner_dest is a mem.
+
+2003-07-18 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_remove_node): Clear the hash table slot.
+
+2003-07-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/11087
+ * loop.c (basic_induction_var): Check if convert_modes emitted any
+ instructions. Remove them and return 0 if so.
+
+2003-07-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11083
+ * toplev.c (rest_of_handle_addresof): Rename into
+ rest_of_handle_addressof. Delete unreachable blocks
+ if dead edges were purged after the addressof pass.
+
+2003-07-18 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in, configure, configure.in: Remove handling of
+ lang-options.h and options_.h.
+ * toplev.c (struct lang_opt, documented_lang_options): Remove.
+ (display_help): Don't use documented_lang_options.
+
+2003-07-17 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (pushdecl_function_level): Make static, return nothing.
+ (kept_level_p): Fold into poplevel.
+ (undeclared_variable): Moved here from c-typeck.c. Export.
+ * c-tree.h (KEEP_YES, KEEP_NO, KEEP_MAYBE): New #defines.
+ (undeclared_variable): Prototype here. Don't prototype
+ kept_level_p nor pushdecl_function_level.
+ * c-parse.in: Change first argument to poplevel from
+ "kept_level_p()" to "KEEP_MAYBE".
+ * c-typeck.c (undeclared_variable): Moved to c-decl.c.
+
+2003-07-17 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_rtx): Use simplify_gen_binary to swap
+ commutative operands instead of modifying the RTL in-place.
+
+2003-07-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR optimization/11557
+ * calls.c (flags_from_decl_or_type): Do not set ECF_LIBCALL_BLOCK
+ unless we know which function is being called.
+
+2003-07-17 Roger Sayle <roger@eyesopen.com>
+
+ * cse.c (fold_rtx): Use swap_commutative_operands_p to determine
+ whether to reorder the operands of a commutative binary operator.
+
+2003-07-17 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (const_binop): Avoid performing the FP operation at
+ compile-time, if either operand is NaN and we honor signaling NaNs,
+ or if we're dividing by zero and either flag_trapping_math is set
+ or the desired mode doesn't support infinities.
+ (fold_initializer): New function to fold an expression ignoring any
+ potential run-time exceptions or traps.
+ * tree.h (fold_initializer): Prototype here.
+ * c-typeck.c (build_binary_op): Move to the end of the file so
+ that intializer_stack is in scope. If constructing an initializer,
+ i.e. when initializer_stack is not NULL, use fold_initializer to
+ fold expressions.
+ * simplify-rtx.c (simplify_binary_operation): Likewise, avoid
+ performing FP operations at compile-time, if they would raise an
+ exception at run-time.
+
+2003-07-17 Geoffrey Keating <geoffk@apple.com>
+
+ PR 11498
+ * Makefile.in (c-opts.o): Add $(LANGHOOKS_DEF_H).
+ (langhooks.o): Add $(GGC_H), gt-langhooks.h.
+ (GTFILES): Add langhooks.c.
+ (gt-langhooks.h): New.
+ * c-common.h (c_static_assembler_name): Prototype.
+ * c-lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): Define.
+ * objc/objc-lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): Define.
+ * c-opts.c: Include langhooks-def.h.
+ (c_static_assembler_name): New.
+ * langhooks.c: Include ggc.h. Include gt-langhooks.h.
+ (var_labelno): New.
+ (lhd_set_decl_assembler_name): Give static objects with context
+ unique names.
+ * varasm.c (var_labelno): Delete.
+ (make_decl_rtl): Don't change the assembler name once it's set.
+
+ * c-opts.c (this_input_filename): New.
+ (finish_options): Take new parameter, name of file being compiled.
+ Update callers. Set this_input_filename.
+ (push_command_line_include): Use this_input_filename not
+ main_input_filename.
+
+2003-07-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Depend .pot generation on options.c.
+ * po/exgettext: Add an extra_files variable containing additional
+ files to scan.
+
+2003-07-17 Zack Weinberg <zack@codesourcery.com>
+
+ * objc/objc-lang.c: Override LANG_HOOKS_WRITE_GLOBALS to
+ c_write_global_declarations.
+
+ * c-decl.c: Fix typos in several comments. Remove all
+ #if 0 blocks; reindent as needed. Remove unused argument
+ to declare_parm_level; all callers changed.
+ * c-parse.in: Update calls to declare_parm_level. Avoid
+ issuing a double warning in some circumstances.
+ * c-typeck.c: Update calls to declare_parm_level.
+ * c-tree.h: Update prototype of declare_parm_level.
+
+ * c-pragma.c (apply_pragma_weak): Don't complain about a
+ redundant #pragma weak.
+
+ * objc/objc-act.c (forward_declare_categories,
+ build_selector_reference_decl, build_class_reference_decl,
+ build_objc_string_decl, synth_forward_declarations,
+ build_protocol_reference): Set TREE_PUBLIC on synthetic
+ forward decl to 0, consistent with eventual definition.
+ Correct comments to match.
+
+ * fixinc/inclhack.def (solaris_mutex_init_2): Escape braces
+ in regexp that don't form a range expression.
+ * fixinc/fixincl.def: Regenerate.
+
+2003-07-17 Richard Henderson <rth@redhat.com>
+
+ PR target/10907
+ * config/ia64/ia64.c (ia64_epilogue_uses): GP is live at end
+ even with !TARGET_CONST_GP.
+ (ia64_function_ok_for_sibcall): Reject non-local functions.
+
+2003-07-17 Steven Bosscher <steven@gcc.gnu.org>
+
+ * c-common.c (c_estimate_num_insns_1): Don't handle
+ METHOD_CALL_EXPR.
+ * expr.c (safe_from_p): Likewise.
+ * gengtype.c (adjust_field_tree_exp): Likewise.
+ * stmt.c (warn_if_unused_value): Likewise
+ * tree.c (first_rtl_op): Likewise.
+ * tree.def: Don't define METHOD_CALL_EXPR.
+ * java/lang.c (java_estimate_num_insns_1): Don't handle
+ METHOD_CALL_EXPR.
+
+2003-07-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR other/11466
+ * doc/invoke.texi (SPARC Options): Document "-mlittle-endian"
+ and its restrictions for the SPARC64 port.
+ Move the entry of "-mimpure-text" before that of "-mv8".
+
+2003-07-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Phil Edwards <phil@jaj.com>
+
+ * doc/install.texi (*-*-solaris2*): Document the step-by-step
+ procedure to bootstrap and install.
+ Document the preference for the legacy Sun tools in /usr/bin
+ over the POSIX tools in /usr/xpg4/bin for the build process.
+
+2003-07-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * c.opt: Document Uncodumented; use it. Document ObjC options.
+ * opts.c (print_filtered_help): Skip undocumented switches.
+ * opts.h (CL_UNDOCUMENTED): New.
+ * opts.sh: Handle Undocumented.
+ * toplev.c (documented_lang_options): Prevent its becoming empty.
+objc:
+ * lang-options.h: Remove.
+
+2003-07-16 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * loop.c (check_ext_dependent_givs): Pass const struct loop *
+ instead of struct loop_info * as argument. Accept BIVs with
+ increment +/- 1 provided there is a friendly exit test against
+ a loop-invariant value.
+ (strength_reduce): Adapt call to check_ext_dependent_givs.
+
+2003-07-16 J"orn Rennecke <joern.rennecke@superh.com>
+ Con Bradley <con.bradley@superh.com>
+
+ * sh-protos.h (sh_get_pr_initial_val): Declare.
+ * sh.c (regno_reg_class): Make its elements type enum reg_class.
+ (output_stack_adjust): Remove emit_fn argument. Add epilogue_p
+ and live_regs_mask arguments. Changed all callers.
+ (save_schedule_s): New structure.
+ (save_schedule): New typedef.
+ (scavenge_reg, sh5_schedule_saves, sh5_schedule_saves): New functions.
+ (calc_live_regs): For TARGET_SHMEDIA, use leaf_function_p.
+ In interrupts handlers, also save registers that are usually
+ partially saved, and make sure there is at least one general purpose
+ register saved if a target register needs saving.
+ Add casts in comparisons to avoid warnings.
+ (sh_media_register_for_return): return -1 for interrupt handlers.
+ (MAX_SAVED_REGS, MAX_TEMPS): New defines.
+ (sh_expand_prologue): Use sh5_schedule_saves. Check that any temp
+ registers used are available.
+ Set RTX_FRAME_RELATED_P where appropriate.
+ Add an REG_FRAME_RELATED_EXPR for r0 + offset addressing.
+ (sh_expand_epilogue, sh_set_return_address): Use sh5_schedule_saves.
+ (initial_elimination_offset): Likewise.
+ * sh.h (DWARF_CIE_DATA_ALIGNMENT): Set to -4.
+ (LOCAL_ALIGNMENT, GENERAL_REGISTER_P): Add casts to avoid warnings.
+ (FP_REGISTER_P): Add casts to fix broken handling of unsigned REGNO.
+ (XD_REGISTER_P, TARGET_REGISTER_P): Likewise.
+ (HARD_REGNO_CALL_PART_CLOBBERED): Also yield nonzero for r15,
+ and for target registers.
+ (RETURN_IN_MEMORY): Add parentheses to avoid warnings.
+ (regno_reg_class): Make its elements type enum reg_class.
+ (CONSTRAINT_LEN): Don't use isdigit.
+ (FUNCTION_ARG_REGNO_P): Add casts to avoid warnings.
+ (FUNCTION_ARG): Add parentheses to avoid warnings.
+ (RETURN_ADDR_RTX): Use sh_get_pr_initial_val.
+ (RETURN_ADDR_OFFSET): Define to -1 for TARGET_SH5.
+ (SH_DBX_REGISTER_NUMBER): Add casts to avoid warnings.
+ (EH_RETURN_DATA_REGNO): Use unsigned constants to avoid warnings.
+ * sh.md (xordi3+1): Remove unused variable regno.
+ (return_media): Check that tr0 is available before using it.
+
+2003-07-16 Neil Booth <neil@daikokuya.co.uk>
+
+ * c.opt: Document more options.
+
+2003-07-16 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (subst): Also handle (subreg (const_double ...)) case
+ if created by a substitution, by using the original inner mode.
+
+2003-07-16 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_replace_rtx): Convert constant comparisons
+ to MODE_FLOAT constants if FLOAT_STORE_FLAG_VALUE is defined.
+ (simplify_rtx): Likewise. Simplify (lo_sum (high X) X) as X.
+
+2003-07-16 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * doc/install.texi (--without-headers): New.
+
+ Partial Fix PR/10129
+ * config/darwin.c (machopic_function_base_name): Only Return "<pic base>".
+ (machopic_output_function_base_name): New; print the true pic label.
+ (machopic_classify_ident): Pic Base is always a defined data.
+ * config/darwin.h (ASM_OUTPUT_LABELREF): Support the pic base label.
+ * config/darwin-proto.h (machopic_output_function_base_name): Prototype.
+
+ * gcse.c (gcse_constant_p): COMPARE of the same registers is a constant
+ if they are not floating point registers.
+
+ PR c/10962
+ * ggc.h: Add header guards.
+ * c-decl.c (finish_struct): Sort fields if
+ number greater than 15 and there are no
+ anonymous structs/unions.
+ * c-common.h: Include ggc.h.
+ (sorted_fields_type): New struct.
+ (field_decl_cmp): New prototype.
+ (resort_sorted_fields): New prototype.
+ (DECL_DECLARES_TYPE_NON_TEMPLATE_P): New macro.
+ * c-tree.h: (lang_type): Use pointer to sorted_fields_type
+ as s, removing other fields.
+ * c-typeck.c (lookup_field): Use s in lang_type.
+ These were mostly moved from cp/class.c:
+ * c-common.c (field_decl_cmp): New static function.
+ (field_decl_cmp): New function.
+ (resort_sorted_fields): New function.
+
+2003-07-16 Geoffrey Keating <geoffk@apple.com>
+
+ * config/darwin.c (machopic_select_section): Use decl_readonly_section
+ to do most of the work.
+
+2003-07-16 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/mmix/mmix-protos.h: Convert prototypes to ISO C90.
+ * config/mmix/mmix.c: Convert functions to ISO C90.
+ (mmix_eh_return_handler_rtx, mmix_output_shifted_value): Tweak
+ formatting.
+ (mmix_get_hard_reg_initial_val): Tweak section head comment.
+
+2003-07-16 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * c-pragma.h (HANDLE_PRAGMA_WEAK): Always define to SUPPORTS_WEAK.
+
+2003-07-16 Jakub Jelinek <jakub@redhat.com>
+
+ * unwind-dw2.c (MD_FROB_UPDATE_CONTEXT): Define.
+ (uw_update_context_1): Use it.
+ * config/rs6000/rs6000.c (insn_after_throw): Remove.
+ (rs6000_aix_emit_builtin_unwind_init): Save $r2 to its location
+ in parent frame if _Unwind_* called directly instead of through
+ .plt.
+ (rs6000_emit_eh_toc_restore): Remove.
+ (rs6000_emit_prologue): Update stack pointer before doing any saving
+ if current_function_calls_eh_return. Generate unwind info for $r2.
+ (rs6000_emit_epilogue): Restore stack pointer after doing all
+ restoring if current_function_calls_eh_return. Restore $r2.
+ * config/rs6000/rs6000-protos.h (rs6000_emit_eh_toc_restore): Remove.
+ * config/rs6000/rs6000.md (eh_return): Remove call to
+ rs6000_emit_eh_toc_restore.
+ * config/rs6000/linux64.h (MD_FROB_UPDATE_CONTEXT): Define.
+ * config/rs6000/aix.h (MD_FROB_UPDATE_CONTEXT): Define.
+
+2003-07-15 Jakub Jelinek <jakub@redhat.com>
+
+ * expr.c (emit_block_move): Don't move anything if size is const 0.
+ (clear_storage): Test against const0_rtx instead of comparing INTVAL
+ against 0.
+
+2003-07-15 David S. Miller <davem@redhat.com>
+
+ * config/sparc/sparc.c (sparc_nonflat_function_epilogue): Only
+ emit nop if the last real insn is CALL_INSN.
+
+2003-07-16 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/xm-mingw32.h (HOST_BIT_BUCKET): Define
+ as "nul".
+ * config/i386/xm-mingw32.h: Change GNU CC to GCC.
+
+2003-07-16 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/winnt.c (associated_type): Artificial methods are not
+ affected by the import/export status of their class unless they are
+ COMDAT.
+ (i386_pe_dllimport_p): Do not mark artificial methods as dllimport.
+
+ * config/i386/winnt.c: Fix GCC copyright comment.
+
+2003-07-16 Gabriel Dos Reis <gcc@integrable-solutions.net>
+
+ PR c++/11531
+ * diagnostic.c (diagnostic_report_diagnostic): Don't ICE if we're
+ not recursing on hard error.
+ (diagnostic_for_decl): Likewise.
+ * diagnostic.def: Rearrange.
+
+2003-07-15 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * dwarf2out.c (expand_builtin_init_dwarf_reg_sizes):
+ If DWARF_FRAME_RETURN_COLUMN doesn't have a register mode, use Pmode.
+
+2003-07-15 J"orn Rennecke <joern.rennecke@superh.com>
+ Richard Henderson <rth@redhat.com>
+
+ * unwind-dw2.c (_Unwind_GetGR): Use dwarf_reg_size_table
+ to decide if to access a _Unwind_Ptr or a _Unwind_Word.
+ (_Unwind_SetGR): Likewise.
+ (_Unwind_GetPtr, _Unwind_SetSpColumn): New functions.
+ (Unwind_SpTmp): New typedef.
+ (uw_update_context_1): Use _Unwind_SetSpColumn and _Unwind_GetPtr.
+ (uw_update_context): Use _Unwind_GetPtr.
+ (init_dwarf_reg_size_table): Move above uw_init_context_1.
+ (uw_init_context_1): Initialize dwarf_reg_size_table if necessary.
+ Use _Unwind_SetSpColumn.
+ (uw_install_context_1): Don't initialize dwarf_reg_size_table.
+ Use _Unwind_GetPtr.
+
+2003-07-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * c.opt: Document more options.
+ * toplev.c (documented_lang_options): Remove all local help strings.
+
+2003-07-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR debug/11473
+ * dbxout.c (dbxout_type): Use TYPE_SIZE to determine the sizes of
+ base classes.
+
+2003-07-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR target/10795
+ * config/i386/i386.c (ix86_expand_carry_flag_compare): Don't
+ swap comparison operands if doing so would generate an
+ unrecognizable insn.
+
+2003-07-15 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11320
+ * sched-int.h (struct deps) [reg_conditional_sets]: New field.
+ (struct sched_info) [compute_jump_reg_dependencies]: New prototype.
+ * sched-deps.c (sched_analyze_insn) [JUMP_INSN]: Update call to
+ current_sched_info->compute_jump_reg_dependencies. Record which
+ registers are used and which registers are set by the jump.
+ Clear deps->reg_conditional_sets after a barrier.
+ Set deps->reg_conditional_sets if the insn is a COND_EXEC.
+ Clear deps->reg_conditional_sets if the insn is not a COND_EXEC.
+ (init_deps): Initialize reg_conditional_sets.
+ (free_deps): Clear reg_conditional_sets.
+ * sched-ebb.c (compute_jump_reg_dependencies): New prototype.
+ Mark registers live on entry of the fallthrough block and conditionally
+ set as set by the jump. Mark registers live on entry of non-fallthrough
+ blocks as used by the jump.
+ * sched-rgn.c (compute_jump_reg_dependencies): New prototype.
+ Mark new parameters as unused.
+
+2003-07-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/invoke.texi: Resync MIPS -march documentation.
+
+2003-07-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (PROCESSOR_R9000): New processor_type.
+ (TARGET_MIPS9000, TUNE_MIPS9000): New macros.
+ (GENERATE_MULT3_SI): True for TARGET_MIPS9000.
+ * config/mips/mips.c (mips_cpu_info_table): Add rm9000 entry.
+ (mips_rtx_costs): Adjust integer multiplication costs for the rm9000.
+ (mips_issue_rate): Handle PROCESSOR_R9000.
+ (mips_use_dfa_pipeline_interface): Likewise.
+ * config/mips/9000.md: New file.
+ * config/mips/mips.md: Include it.
+ (define_attr cpu): Add r9000.
+ (mulsi3_mult3): Use "mul" for rm9000 code.
+
+2003-07-15 Stan Cox <scox@redhat.com>
+
+ * config/mips/mips.h (PROCESSOR_R7000): New processor_type.
+ (TARGET_MIPS7000, TUNE_MIPS7000): New macros.
+ (GENERATE_MULT3_SI): True for TARGET_MIPS7000.
+ * config/mips/mips.c (mips_cpu_info_table): Add rm7000 entry.
+ (mips_rtx_costs): Adjust integer multiplication costs for the rm7000.
+ (mips_issue_rate): Handle PROCESSOR_R7000.
+ (mips_use_dfa_pipeline_interface): Likewise.
+ * config/mips/7000.md: New file.
+ * config/mips/mips.md: Include it.
+ (define_attr cpu): Add r7000.
+ (mulsi3_mult3): Use "mul" for rm7000 code.
+
+2003-07-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (define_attr type): Add condmove. Use it for
+ the conditional move patterns.
+ * config/mips/5400.md (ir_vr54_move): Rename to ir_vr54_condmove.
+ Check for condmove type.
+ (ir_vr54_arith): Add move type.
+ * config/mips/5500.md (ir_vr55_move, ir_vr55_arith): Likewise.
+ * config/mips/sr71k.md (ir_sr70_move, ir_sr70_arith): Likewise.
+
+2003-07-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (print_help): Remove.
+ (c_common_handle_option): Don't handle --help.
+ * c.opt: Document some options.
+ (--help): Remove.
+ * opts.c (print_filtered_help): New.
+ (print_help): Use it.
+
+2003-07-14 Geoffrey Keating <geoffk@apple.com>
+
+ * c-common.c (c_common_type_for_mode): Handle V4DFmode.
+ * tree.c: (build_common_tree_nodes_2): Likewise.
+ * tree.h (enum tree_index): Add TI_V4DF_TYPE.
+ (V4DF_type_node): New.
+
+ * c-opts.c (push_command_line_include): Don't free deferred_opts,
+ we'll need it.
+ (finish_options): Reset init_cursor.
+
+2003-07-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * expr.c (expand_assignment): Remove an unused argument
+ SUGGEST_REG.
+ * expr.h: Update the prototype.
+ * function.c: Update the callers.
+ * stmt.c: Likewise.
+
+2003-07-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR debug/11098
+ * integrate.c (copy_decl_for_inlining): Do not mark copied decls
+ as DECL_ABSTRACT.
+
+2003-07-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (avoid_bool_define, avoid_bool_type): Bypass
+ with __cplusplus, not "we must use the C++ compiler's type"
+ * fixinc/inclhack.def (void_null): Note that Interix needs this.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-07-14 Geoffrey Keating <geoffk@apple.com>
+
+ * unwind-dw2-fde-darwin.c (live_image_destructor): Get seen_objects
+ and unseen_objects from the global data before calling
+ __deregister_frame_info_bases.
+ (examine_objects): Insert objects into the seen_objects list,
+ not unseen_objects.
+ (_Unwind_Find_FDE): Always unlock the global object lists, even if
+ we couldn't allocate a data structure to put in it.
+
+ * objc/objc-act.h (CLASS_SUPER_NAME): Add a little typechecking.
+ (TYPE_PROTOCOL_LIST): Share use of type.context with C frontend.
+ (SET_TYPE_PROTOCOL_LIST): New.
+ * objc/objc-act.c (get_static_reference): Use SET_TYPE_PROTOCOL_LIST.
+ (get_object_reference): Likewise.
+
+2003-07-14 Jan Hubicka <jh@suse.cz>
+
+ * cfglayout.c (locator_file): Break out from ....
+ (insn_file): ... here.
+ (locator_line): Break out from ....
+ (insn_line): ... here.
+ * rtl.h (locator_file, locator_line): Declare.
+ (final_start_function): Set proper line/file info.
+
+2003-07-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.c (pp_c_unary_expression): A CONVERT_EXPR is
+ handled by pp_c_cast_expression.
+
+2003-07-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_expand_prologue): Use a single insn to
+ allocate 32768 bytes of stack. Use addition rather than subtraction
+ when a single insn is enough.
+ * config/mips/mips.md: Remove insns and splitters for subtracting
+ constants.
+ (subsi3): Only accept register operands.
+ (subsi3_internal): Likewise. Use for TARGET_MIPS16 as well.
+ (subdi3_internal_3, subsi3_internal_2): Likewise.
+ (casesi): Use expand_binop to subtract the lower bound.
+
+2003-07-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_in_small_data_p): Don't handle
+ TARGET_MIPS16 specially.
+
+2003-07-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/elf.h (ASM_OUTPUT_ALIGNED_BSS): Use
+ mips_output_aligned_bss.
+ * config/mips/linux.h: Likewise.
+ * config/mips/mips-protos.h (mips_output_aligned_bss): Declare.
+ * config/mips/mips.c (mips_output_aligned_bss): New function.
+
+ * config/mips/elf.h (DBX_DEBUGGING_INFO): Delete.
+ * config/mips/elf64.h: Likewise.
+
+ * config/mips/elf.h (ASM_DECLARE_OBJECT_NAME): Use
+ mips_declare_object_name.
+ (ASM_FINISH_DECLARE_OBJECT): Likewise mips_finish_declare_object.
+ * config/mips/elf64.h: As for elf.h.
+ * config/mips/iris6.h: Likewise.
+ * config/mips/linux.h (ASM_DECLARE_OBJECT_NAME): As for elf.h.
+ * config/mips/mips.h (ASM_DECLARE_OBJECT_NAME): Remove unnecessary
+ do...while (0) block.
+ * config/mips/mips-protos.h (mips_declare_object_name): Declare.
+ (mips_finish_declare_object): Declare.
+ * config/mips/mips.c (mips_declare_object_name): New function.
+ (mips_finish_declare_object): New function.
+
+ * config/mips/elf.h (SBSS_SECTION_ASM_OP): Delete.
+ * config/mips/linux.h: Likewise.
+
+ * config/mips/mips.c (inside_function): Delete.
+ (file_in_function_warning, ignore_line_number): Delete.
+ (mips_output_filename): Don't warn about changing filenames within
+ a function.
+ (mips_output_lineno): Update accordingly.
+ (mips_output_function_prologue): Don't reset the deleted variables.
+ * config/mips/mips.h (inside_function): Delete.
+ (file_in_function_warning, ignore_line_number): Delete.
+
+ * config/mips/elf.h (OBJECT_FORMAT_COFF, EXTENDED_COFF): Remove undefs.
+ * config/mips/elf64.h: Likewise.
+ * config/mips/openbsd.h: Likewise.
+ * config/mips/iris5.h (OBJECT_FORMAT_COFF): Remove undefs.
+ * config/mips/linux.h: Likewise.
+ * config/mips/mips.h (OBJECT_FORMAT_COFF, EXTENDED_COFF): Delete.
+ (CODE_MASK, MIPS_IS_STAB, MIPS_MARK_STAB, MIPS_UNMARK_STAB): Delete.
+
+ * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix5*): Add mips/sdb.h
+ to the list of include files when using gas.
+ (mips*el-*-openbsd*, mips*-*-openbsd*): Add mips/sdb.h unconditionally.
+ * config/mips/elf.h: Remove #undef SDB_DEBUGGING_INFO.
+ * config/mips/elf64.h: Likewise.
+ * config/mips/iris5.h: Likewise.
+ * config/mips/linux.h: Likewise.
+ * config/mips/iris5gas.h (SDB_DEBUGGING_INFO): Remove definition.
+ * config/mips/mips.h (PREFERRED_DEBUGGING_TYPE): Likewise.
+ (SDB_DEBUGGING_INFO, sdb*, SDB_ALLOW_*, PUT_SDB*): Move to...
+ * config/mips/sdb.h: ...this new file.
+
+2003-07-14 Douglas Rupp <rupp@gnat.com>
+
+ * fixinc/server.c (server_setup): Don't use non-POSIX NULL first
+ argument to getcwd; use fixed buffer instead.
+
+2003-07-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/mkfixinc.sh: Treat OpenBSD normally.
+ * fixinc/fixinc.wrap: Delete.
+
+2003-07-14 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * ggc-page.c (extra_order_size_table): Insns have 9 slots. Regs
+ don't have 2.
+
+2003-07-14 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * ggc-page.c (struct globals): Add new fields to keep track of the
+ total allocated memory and overhead.
+ (ggc_print_statistics): Print them.
+ (ggc_alloc): Keep track of the total allocated memory and the
+ overhead.
+
+ * tree.c (dump_tree_statistics): Increase spacing.
+ (enum tree_node_kind): Move to ...
+ * tree.h (enum tree_node_kind): ... here.
+ (tree_node_counts, tree_node_sizes): Declare.
+
+2003-07-14 James A. Morrison <ja2morri@student.math.uwaterloo.ca>
+
+ * doc/include/texinfo.tex: Upgrade to texinfo 4.6.
+
+2003-07-14 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR optimization/11440
+ * gcse.c (try_replace_reg): Don't attach notes to ZERO_EXTRACT or
+ SIGN_EXTRACT SETs.
+
+2003-07-14 Alan Modra <amodra@bigpond.net.au>
+
+ * doc/tm.texi (BLOCK_REG_PADDING): Describe.
+ * expr.h (struct locate_and_pad_arg_data): Add where_pad.
+ (emit_group_load, emit_group_store): Adjust declarations.
+ Remove most occurrences of #ifdef TREE_CODE.
+ * expr.c (emit_group_load): Add "type" param, and use
+ BLOCK_REG_PADDING to determine need for a shift. Optimize non-
+ aligned accesses if !SLOW_UNALIGNED_ACCESS.
+ (emit_group_store): Likewise.
+ (emit_push_insn, expand_assignment, store_expr, expand_expr): Adjust
+ emit_group_load and emit_group_store calls.
+ * calls.c (store_unaligned_arguments_into_pseudos): Tidy. Use
+ BLOCK_REG_PADDING to determine whether we need endian_correction.
+ (load_register_parameters): Localize vars. Handle shifting of
+ small values to the correct end of regs. Adjust emit_group_load
+ call.
+ (expand_call, emit_library_call_value_1): Adjust emit_group_load
+ and emit_group_store calls.
+ * function.c (assign_parms): Set mem alignment for stack slots.
+ Adjust emit_group_store call. Store values at the "wrong" end
+ of regs to the stack. Use BLOCK_REG_PADDING.
+ (locate_and_pad_parm): Save where_pad.
+ (expand_function_end): Adjust emit_group_load call.
+ * stmt.c (expand_value_return): Adjust emit_group_load call.
+ * Makefile.in (calls.o): Depend on $(OPTABS_H).
+ * config/rs6000/linux64.h (TARGET_LITTLE_ENDIAN): Redefine as 0.
+ (AGGREGATE_PADDING_FIXED, AGGREGATES_PAD_UPWARD_ALWAYS): Define.
+ (MUST_PASS_IN_STACK): Define.
+ (BLOCK_REG_PADDING): Define.
+ * config/rs6000/rs6000.h (struct rs6000_args): Remove orig_nargs.
+ (PAD_VARARGS_DOWN): Define in terms of FUNCTION_ARG_PADDING.
+ * config/rs6000/rs6000.c (init_cumulative_args): Don't set orig_nargs.
+ (function_arg_padding): !AGGREGATE_PADDING_FIXED compatibility code.
+ Act on AGGREGATES_PAD_UPWARD_ALWAYS.
+
+2003-07-13 Aaron W. LaFramboise <awlaframboise@aol.com>
+
+ * config/i386/gthr-win32.c (__GTHREAD_HIDE_WIN32API): Define to 1.
+
+2003-07-13 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (expand_expr, case COMPONENT_REF): If reg, copy OP0 to MEM
+ both if OFFSET specified and if result BLKmode for ARRAY_RANGE_REF.
+
+2003-07-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR other/11123
+ * toplev.c: Don't cut off option names.
+
+2003-07-13 Andreas Jaeger <aj@suse.de>
+
+ * c-decl.c (link_hash_hash): Avoid warning about casting pointer
+ to integer of different size.
+
+2003-07-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (simplify_comparison): Convert (ne (and (not X) 1) 0)
+ to (eq (and X 1) 0).
+
+2003-07-13 Andreas Jaeger <aj@suse.de>
+
+ * config.gcc: Add pmmintrin.h for x86_64-*-*.
+
+2003-07-13 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (LIBCPP_DEPS): Remove coretypes.h and $(TM_H).
+ (hashtable.o, line-map.o, mkdeps.o): Likewise, from dependency
+ list. Move these all together down by cpplib.
+
+ * cpplib.h: Don't refer to MAX_WCHAR_TYPE_SIZE when determining
+ definition of CPPCHAR_SIGNED_T.
+
+ * cppcharset.c, cpperror.c, cppexp.c, cppfiles.c, cpphash.c, cppinit.c
+ * cpplex.c, cpplib.c, cppmacro.c, cpppch.c, cpptrad.c, hashtable.c
+ * line-map.c, mkdeps.c: Don't include coretypes.h or tm.h.
+
+ * cpphash.c (_cpp_init_hashtable): Don't use gcc_obstack_init.
+ * cppinit.c (cpp_create_reader): Likewise.
+
+ * cpphash.h (scan_out_logical_line): Rename _cpp_scan_out_logical_line.
+ * cpptrad.c: Likewise. All callers changed.
+ * cpplib.c: All callers changed.
+ * c-ppoutput.c: Replace 'uchar' with 'unsigned char' throughout.
+ * hashtable.h: Define GTY(x) to nothing here too.
+
+2003-07-13 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * stor-layout.c (compute_record_mode): Remove very obsolete test
+ that forces BLKmode for records with fields crossing word boundary.
+
+2003-07-13 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in: Remove orphan reference to acconfig.h.
+
+2003-07-13 Andreas Jaeger <aj@suse.de>
+
+ * cgraphunit.c: Convert prototypes to ISO C90.
+
+2003-07-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (avoid_wchar_t_type): Use __cplusplus bypass
+ (for OpenBSD).
+ * fixinc/fixincl.x: Rebuild.
+
+2003-07-12 Zack Weinberg <zack@codesourcery.com>
+
+ * configure.in: Always define HAVE_AS_GOTOFF_IN_DATA for
+ i?86-*-*. Use correct name of cache variable.
+ * configure: Regenerate.
+
+2003-07-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.c: Fix comment typos.
+ * config/alpha/alpha.md: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/arm/arm.md: Likewise.
+ * config/arm/lib1funcs.asm: Likewise.
+ * config/avr/avr.md: Likewise.
+ * config/arm/README-interworking: Fix typos.
+
+2003-07-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-format.c: Fix comment formatting.
+ * c-typeck.c: Likewise.
+ * coverage.c: Likewise.
+ * cppcharset.c: Likewise.
+ * cpplib.c: Likewise.
+ * dbxout.c: Likewise.
+ * gcov-io.h: Likewise.
+ * toplev.c: Likewise.
+
+2003-07-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (alpha_sbrk): Note that OpenBSD needs this
+ fix.
+
+2003-07-12 Zack Weinberg <zack@codesourcery.com>
+
+ * aclocal.m4 (gcc_AC_CHECK_TYPE): Clone of AC_CHECK_TYPE,
+ uses three-argument AC_DEFINE so no acconfig.h entries are
+ needed.
+ (_gcc_COMPUTE_GAS_VERSION): Also provide gcc_cv_gas_vers
+ which contains the GAS version number as a scaled integer.
+ (gcc_GAS_VERSION_GTE_IFELSE): Use gcc_cv_gas_vers. Add
+ ability to check for ELF assembler.
+ (gcc_GAS_CHECK_FEATURE): New macro.
+ * configure.in: Use gcc_AC_CHECK_TYPE. Rewrite all
+ assembler feature checks using gcc_GAS_CHECK_FEATURE.
+ Use three-argument AC_DEFINE everywhere.
+ * acconfig.h: Deleted.
+ * config.in, configure: Regenerate.
+
+2003-07-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/inclhack.def (struct_sockaddr): Avoid "fixing" sockaddr_in
+ (on OpenBSD).
+ * fixinc/fixincl.x: Regenerate.
+
+ * fixinc/inclhack.def (gnu_types): Improve comment.
+
+2003-07-12 Andreas Jaeger <aj@suse.de>
+
+ * fp-test.c (main): Use ISO C90 prototype.
+
+ * version.c: Remove unneded include of ansidecl.h.
+
+ * cgraph.h: Convert prototypes to ISO C90.
+ * cgraph.c: Likewise.
+ * fix-header.c: Likewise.
+ * ra.h: Likewise.
+ * protoize.c: Likewise.
+
+2003-07-12 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_inlined_into, cgraph_inlined_calees): Fix
+ warning.
+
+2003-07-12 Jan Hubicka <jh@suse.cz>
+ Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * cgraph.c (cgraph_max_uid): New global variable.
+ (cgraph_node): Set uid field.
+ (create_edge): Keep inline flags consistent.
+ (dump_cgraph): Dump more info.
+ * cgraph.h (struct cgraph_local_info): Remove inline_many and
+ can_inline_once; add inlinable, disgread_inline_limits, and self_insn
+ (struct cgraph_global_info): Add insns, calls, cloned_times,
+ will_be_output.
+ (struct cgraph_node): Add uid.
+ (struct cgraph_edge): Add inline_call.
+ (cgraph_max_uid, cgraph_inline_p): Declare.
+ * cgraph.c: Include params.h and fibheap.h
+ (cgraph_mark_functions_to_inline_once): Kill.
+ (INSNS_PER_CALL): New constant.
+ (ncalls_inlined, nfunctions_inlined, initial_insns, overall_insns): New
+ static variables.
+ (cgraph_finalize_function): Do not analyze inlining.
+ (cgraph_finalize_compilation_unit): Set inlining attributes.
+ (cgraph_mark_functions_to_output): More consistency checks.
+ (cgraph_optimize_function): Set current_function_decl to NULL.
+ (cgraph_expand_function): Use new inline flags.
+ (cgraph_postorder): Expand from cgraph_expand_functions.
+ (INLINED_TIMES, SET_INLINED_TIMES): New macros.
+ (cgraph_inlined_into, cgraph_inlined_callees,
+ cgraph_estimate_size_after_inlining, cgraph_estimate_growth,
+ cgraph_mark_inline, cgraph_check_inline_limits,
+ cgraph_default_inline_p, cgraph_decide_inling_of_small_functions,
+ cgraph_decide_inlining, cgraph_inline_p): New functions.
+ * params.def (PARAM_LARGE_FUNCTION_INSNS, PARAM_LARGE_FUNCTION_GROWTH,
+ PARAM_INLINE_UNIT_GROWTH): New parameters.
+ * tree-inline.c (struct inline_data): New field current_decl.
+ (expand_call_inline): Avoid forward declarations; use
+ inlinable_function_p.
+ (optimize_inline_calls): Set id.current_decl.
+
+2003-07-11 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * configure.in: Remove wrongly added definition of
+ local_prefix.
+ * configure: Regenerate.
+
+2003-07-11 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * rtl.def (NOTE): Do not use padding.
+
+2003-07-11 Dara Hazeghi <dhazeghi@yahoo.com>
+
+ * doc/install.tex: Update required binutils for i?86-*-linux*
+
+2003-07-11 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (stage1_build): Force OBJS-onestep=OBJS.
+
+2003-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ * varasm.c (make_decl_rtl): Treat decls with a DECL_CONTEXT of
+ TRANSLATION_UNIT_DECL as top_level.
+
+2003-07-11 Jakub Jelinek <jakub@redhat.com>
+
+ * optabs.c (prepare_cmp_insn): Try cmpmemM first if it exists,
+ then fall back to cmpstrM.
+ * builtins.c (expand_builtin_memcmp): Likewise.
+ * config/s390/s390-protos.h (s390_expand_cmpstr): Rename to...
+ (s390_expand_cmpmem): ... this.
+ * config/s390/s390.md (cmpmemdi, cmpmemsi, cmpmem_short_64,
+ cmpmem_short_31, cmpmem_long_64, cmpmem_long_31): Renamed
+ from cmpstr* patterns. Rename call to s390_expand_cmpstr
+ to s390_expand_cmpmem.
+ * config/s390/s390.c (s390_expand_cmpstr): Rename to...
+ (s390_expand_cmpstr): ... this. Rename cmpstr* instructions
+ to cmpmem*.
+ * config/i370/i370.md (cmpmemsi, cmpmemsi_1): Renamed from
+ cmpstr* patterns.
+ * doc/md.texi (cmpstrM): Describe as String compare insn, not
+ Block compare insn.
+ (cmpmemM): Add.
+
+2003-07-11 Loren James Rittle <ljrittle@acm.org>
+
+ * config/i386/freebsd.h (SET_ASM_OP): Remove.
+ (SUBTARGET_OVERRIDE_OPTIONS): Handle TARGET_64BIT case.
+ (ASM_COMMENT_START, ASM_APP_ON, ASM_APP_OFF, DBX_REGISTER_NUMBER
+ MCOUNT_NAME, SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE_SIZE): Whitespace.
+
+2003-07-11 Richard Henderson <rth@redhat.com>
+
+ * function.c (assign_parms): Don't recombine complex args if
+ fnargs is unchanged from orig_fnargs.
+ (split_complex_args): Return args without complex before copying.
+ Re-layout the modified parameters.
+
+2003-07-11 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * regclass.c (choose_hard_reg_mode): Add third argument.
+ Changed all callers.
+ * rtl.h (choose_hard_reg_mode): Update declaration.
+ * dwarf2out.c (expand_builtin_init_dwarf_reg_sizes):
+ Take HARD_REGNO_CALL_PART_CLOBBERED into account.
+
+2003-07-11 Geoffrey Keating <geoffk@apple.com>
+
+ * c-decl.c (finish_decl): Handle 'used' here...
+ * cgraphunit.c (cgraph_finalize_function): ... and here ...
+ * c-common.c: (handle_used_attribute): ... not here.
+
+ * configure.in (onstep): Support --enable-intermodule.
+ * Makefile.in (OBJS-common): New.
+ (OBJS-md): New.
+ (OBJS-archive): New.
+ (OBJS): Build from OBJS-common, OBJS-md, OBJS-archive.
+ (OBJS-onestep): New.
+ (libbackend.a): Support @onestep@.
+ (libbackend.o): New.
+ * configure: Regenerate.
+
+ * c-common.h (c_reset_state): New prototype.
+ (c_parse_file): New prototype.
+ (finish_file): Move prototype from c-tree.h.
+ * c-decl.c: Include <hashtab.h>.
+ (builtin_decls): New.
+ (current_file_decl): New.
+ (duplicate_decls): Add extra parameter. Change all callers. Don't
+ output duplicate common symbols.
+ (link_hash_hash): New.
+ (link_hash_eq): New.
+ (poplevel): Handle popping of the top level.
+ (warn_if_shadowing): Handle TRANSLATION_UNIT_DECL.
+ (pushdecl): Set DECL_CONTEXT to TRANSLATION_UNIT_DECL if appropriate.
+ (pushdecl_top_level): Likewise.
+ (redeclaration_error_message): Handle TRANSLATION_UNIT_DECL.
+ (c_init_decl_processing): Create TRANSLATION_UNIT_DECL.
+ (finish_decl): Handle TRANSLATION_UNIT_DECL.
+ (merge_translation_unit_decls): New.
+ (c_write_global_declarations): New.
+ (c_reset_state): New.
+ (implicitly_declare): Handle TRANSLATION_UNIT_DECL.
+ * c-lang.c (LANG_HOOKS_WRITE_GLOBALS): New.
+ * c-objc-common.c (c_cannot_inline_tree_fn): Handle
+ TRANSLATION_UNIT_DECL.
+ (c_objc_common_finish_file): Call merge_translation_unit_decls.
+ * c-opts.c (in_fnames): Rename from in_fname.
+ (c_common_decode_option): Handle multiple input filenames.
+ (c_common_post_options): Likewise.
+ (c_common_parse_file): Likewise; also, call c_parse_file rather than
+ yyparse.
+ * c-parse.in: Move cleanup code to c_parse_file.
+ (free_parser_stacks): Move contents to c_parse_file.
+ (c_parse_file): New.
+ * c-tree.h (union lang_tree_node): Chain along TYPE_NEXT_VARIANT
+ for integer types.
+ (C_DECL_FILE_SCOPE): New.
+ (finish_file): Move prototype to c-common.h.
+ (merge_translation_unit_decls): New prototype.
+ (comptypes): Add extra parameter to prototype.
+ (c_write_global_declarations): New prototype.
+ * c-typeck.c (tagged_types_tu_compatible_p): New.
+ (function_types_compatible_p): Add extra parameter, change all callers.
+ (type_lists_compatible_p): Likewise.
+ (comptypes): Likewise.
+ (struct tagged_tu_seen): New.
+ (tagged_tu_seen_base): New.
+ (build_unary_op): Handle TRANSLATION_UNIT_DECL.
+ (c_mark_addressable): Remove #if 0 code.
+ * calls.c (special_function_p): Handle TRANSLATION_UNIT_DECL, add
+ comment explaining why it shouldn't have to.
+ * cgraph.h (struct cgraph_node): Add chain_next and chain_prev GTY
+ options.
+ * cppinit.c (cpp_read_next_file): New.
+ (cpp_read_main_file): Use it.
+ * cpplib.c (undefine_macros): New.
+ (cpp_undef_all): New.
+ * cpplib.h (cpp_read_next_file): Prototype.
+ (cpp_undef_all): Prototype.
+ * langhooks-def.h (write_global_declarations): Remove prototype.
+ * toplev.h (write_global_declarations): Add prototype.
+ * tree.c (decl_type_context): Use switch statement, handle
+ TRANSLATION_UNIT_DECL.
+ * tree.def: Update documentation for TRANSLATION_UNIT_DECL.
+ (TRANSLATION_UNIT_DECL): New kind of tree.
+ * tree.h: Update documentation for TRANSLATION_UNIT_DECL.
+ * Makefile.in (c-decl.o): Add $(HASHTAB_H) to dependencies.
+ * doc/invoke.texi: Make attempt to document new functionality.
+
+ 2003-05-19 Per Bothner <bothner@apple.com>
+
+ * gcc.c (combine_inputs): New.
+ (process_command): Set combine_inputs.
+ (do_spec_1): Handle combine_inputs.
+ (main): Likewise.
+
+2003-07-10 James E Wilson <wilson@tuliptree.org>
+
+ PR optimization/9745
+ * loop.c (loop_iv_add_mult_emit_before): Call loop_regs_update before
+ loop_insn_emit_before.
+ (loop_iv_add_mult_sink, loop_iv_add_mult_hoist): Likewise.
+
+2003-07-10 Zack Weinberg <zack@codesourcery.com>
+
+ * cppcharset.c: Fix comment.
+ (iconv_close [!HAVE_ICONV]): #define to (void)0 to prevent warning.
+ (EILSEQ): #define to EINVAL if not already defined.
+ (convert_using_iconv): #if out when !HAVE_ICONV.
+ (init_iconv_desc): Handle !HAVE_ICONV here...
+ (cpp_init_iconv): ...not here.
+
+2003-07-11 Neil Booth <neil@daikokuya.co.uk>
+
+ * common.opt: More --help messages.
+ * opts.c (print_help): Use puts().
+ * toplev.c (f_options): Remove help text.
+ (display_help): Don't dump f_options.
+
+2003-07-11 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/mkfixinc.sh: Drop reference to unsupported alpha-*-interix*.
+ Move i?86-*-interix* to the don't-fix list.
+ * fixinc/fixinc.interix: Delete with extreme prejudice.
+
+2003-07-10 Dara Hazeghi <dhazeghi@yahoo.com>
+
+ PR bootstrap/10758
+ * doc/install.texi: Document requirements for ia64-*-hpux* target.
+
+2003-07-10 Roger Sayle <roger@eyesopen.com>
+
+ * config/ia64/hpux.h (TARGET_C99_FUNCTIONS): Define.
+
+2003-07-10 Zack Weinberg <zack@codesourcery.com>
+
+ * cppcharset.c (one_utf8_to_cppchar, one_cppchar_to_utf8,
+ one_utf8_to_utf32, one_utf32_to_utf8, one_utf8_to_utf16,
+ one_utf16_to_utf8, conversion_loop, convert_utf8_utf16,
+ convert_utf8_utf32, convert_utf16_utf8, convert_utf32_utf8,
+ convert_no_conversion, convert_using_iconv): New functions.
+ (APPLY_CONVERSION): New macro.
+ (struct conversion, conversion_tab): New data structure.
+ (init_iconv_desc): Check conversion_tab for a custom conversion
+ primitive before trying to use iconv.
+ (convert_cset): Deleted.
+ (cpp_init_iconv): Use UTF- terminology, not UCS-.
+ (_cpp_destroy_iconv): Update to match.
+ (_cpp_valid_ucn): We don't need iconv to implement UCNs.
+ (convert_ucn): Use one_cppchar_to_utf8 and APPLY_CONVERSION.
+ (convert_escape, cpp_interpret_string): Use APPLY_CONVERSION.
+ (_cpp_interpret_string_notranslate): New function, moved here
+ from cpplib.c.
+
+ * cpphash.h (convert_f, struct cset_converter): New types.
+ (struct cpp_reader): narrow_cset_desc and wide_cset_desc
+ are now struct cset_converter, not bare iconv_t.
+ Update prototypes.
+ * cpplib.c (interpret_string_notranslate): Moved to cppcharset.c;
+ all callers changed.
+
+2003-07-10 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * Makefile.in (options.h): Depend on Makefile. Add move-if-change
+ to opts.sh command line.
+ * opts.sh: Write to temporary files with a move-if-change at the end.
+
+2003-07-10 Denis Chertykov <denisc@overta.ru>
+ Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * combine.c (gen_binary): Handle the CLOBBER rtx and
+ don't build a binary operation with it.
+
+2003-07-10 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcse.c (load_kills_store, find_loads, store_killed_in_insn,
+ store_killed_after, store_killed_before): Keep track of the correct
+ dependency function to use.
+
+2003-07-10 Steven Bosscher <steven@gcc.gnu.org>
+ * toplev.c (do_compile): Don't try to open dump files before
+ lang_dependent_init initializes dump_base_name.
+
+2003-07-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/arm/arm.c (arm_init_iwmmxt_builtins, arm_expand_builtin):
+ Use ARRAY_SIZE.
+ * config/frv/frv.c (frv_expand_builtin): Likewise.
+ * config/sh/sh.c (sh_media_init_builtins): Likewise.
+
+2003-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10032
+ * doc/invoke.texi (C++ Dialect Options): Change documentation of
+ -fpermissive.
+
+2003-07-10 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * tm.texi (RETURN_ADDR_OFFSET): Document.
+
+2003-07-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov-io.h: Update documentation.
+ (GCOV_UNSIGNED2STRING): New.
+ (GCOV_TAG_FUNCTION_LENGTH, GCOV_TAG_BLOCKS_LENGTH,
+ GCOV_TAG_ARCS_LENGTH, GCOV_TAG_COUNTER_LENGTH,
+ GCOV_TAG_SUMMARY_LENGTH): Adjust.
+ (GCOV_TAG_BLOCKS_NUM, GCOV_TAG_ARCS_NUM,
+ GCOV_TAG_COUNTER_NUM): New.
+ (GCOV_BLOCK_SIZE): Number of words.
+ (gcov_var): Adjust buffer type.
+ * gcov-io.c (gcov_write_bytes, gcov_read_bytes): Rename to ...
+ (gcov_write_words, gcov_read_words): ... here. Take a 4-byte word
+ count, not byte count.
+ (gcov_open): Adjust overread init.
+ (gcov_allocate, gcov_write_unsigned, gcov_write_counter,
+ gcov_write_string, gcov_write_tag, gcov_write_length,
+ gcov_write_tag_length): Adjust.
+ (gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust.
+ (gcov_sync, gcov_seek): Adjust.
+ * gcov-dump.c (print_usage): Show gcc version only.
+ (dump_file): Use GCOV_UNSIGNED2STRING.
+ (tag_blocks, tag_arcs, tag_counters): Use GCOV_TAG_*_NUM macros.
+ * gcov.c (print_version): Show gcc version only.
+ (read_graph_file): Use GCOV_UNSIGNED2STRING. Use
+ GCOV_TAG_*_NUM macros.
+ (read_count_file): Use GCOV_UNSIGNED2STRING. Use
+ GCOV_TAG_COUNTER_LENGTH.
+ * coverage.c (read_counts_file): Use GCOV_UNSIGNED2STRING.
+ Use GCOV_TAG_COUNTER_NUM.
+ * libgcov.c (gcov_version): Use GCOV_UNSIGNED2STRING.
+ (__gcov_merge_single, __gcov_merge_delta): Use GCOV_CHECK.
+
+2003-07-10 Andreas Schwab <schwab@suse.de>
+
+ * gcov-dump.c (dump_file): Fix missing address operator.
+
+2003-07-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR c/11449
+ * fold-const.c (sign_bit_p): Return EXP if VAL is the sign bit
+ of HOST_WIDE_INT.
+ (fold_single_bit_test): If sign_bit_p() fails, assume that the
+ bit being tested is not a sign bit.
+
+2003-07-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): New.
+
+2003-07-10 Alexandre Oliva <aoliva@redhat.com>
+
+ 2001-12-13 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/linux.h (LINK_SPEC): Rename the dynamic linker
+ from ld-linux.so.2 to ld.so.1.
+ 2001-11-18 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/linux.h (LINK_SPEC): -lpthread, not -lthread.
+ * config/mn10300/linux.h (LINK_SPEC): Don't handle -Wl,-rpath
+ nor -Wl,-rpath-link.
+ (LIB_SPEC): Add -rpath-link if !static.
+ 2001-08-22 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.c (mn10300_protect_label): New
+ variable.
+ * config/mn10300/linux.h (PRINT_OPERAND,
+ PRINT_OPERAND_ADDRESS): Set it during their execution.
+ (ASM_OUTPUT_LABELREF): Output `+' before symbol name if
+ mn10300_protect_label is set.
+ * config/mn10300/linux.h (LINK_SPEC): Recognize -Wl,-rpath and
+ -Wl,-rpath-link.
+ (LIB_SPEC, STARTFILE_SPEC): Define.
+ 2001-05-11 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/t-linux (dp-bit.c, fp-bit.c): Don't define
+ FLOAT_BIT_ORDER_MISMATCH.
+ 2001-05-09 Alexandre Oliva <aoliva@redhat.com>
+ * config.gcc (am33_2.0-*-linux*): Added.
+ * config/mn10300/linux.h: New.
+ * config/mn10300/t-linux: New.
+
+2003-07-10 Andreas Jaeger <aj@suse.de>
+
+ * fold-const.c: Properly wrap prototypes.
+
+2003-07-09 Alexandre Oliva <aoliva@redhat.com>
+
+ 2003-06-16 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.c (mn10300_unspec_int_label_counter):
+ Moved from...
+ * config/mn10300/mn10300.md (GOTaddr2picreg): ... here.
+ * config/mn10300/mn10300.h: GTY-declare it.
+ 2003-06-11 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.c (mn10300_encode_section_info): Fix
+ prototype. Use incoming RTL argument.
+ 2002-12-12 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.md (int_label): Move C statements...
+ (GOTaddr2picreg): ... here.
+ 2002-08-15 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.h (ENCODE_SECTION_INFO): Move...
+ * config/mn10300/mn10300.c (mn10300_encode_section_info):
+ ... here. New function.
+ (TARGET_ENCODE_SECTION_INFO): Define to it.
+ 2001-11-04 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.md (builtin_setjmp_receiver): Fix typo in
+ pattern name.
+ (mn10300_loadPC): Define as insn splittable after reload.
+ 2001-05-13 Alexandre Oliva <aoliva@redhat.com>
+ * config/sh/mn10300.h (JUMP_TABLES_IN_TEXT_SECTION): Let them
+ be defined in .rodata even in PIC, now that the assembler
+ supports that.
+ 2001-05-09 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.h (GOT_SYMBOL_NAME): Don't let the
+ symbol take an underscore prefix.
+ 2001-04-14 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300-protos.h (legitimate_pic_operand_p,
+ legitimize_pic_address): Declare.
+ * config/mn10300/mn10300.h (CONDITIONAL_REGISTER_USAGE): Mark
+ the PIC register as fixed.
+ (EXTRA_CONSTRAINT): Match UNSPEC_PLT and UNSPEC_PIC for 'S'.
+ (GO_IF_LEGITIMATE_ADDRESS): Require legitimate_pic_operand for
+ PIC.
+ (LEGITIMATE_PIC_OPERAND_P): Define.
+ (PIC_OFFSET_TABLE_REGNUM): Define.
+ (GOT_SYMBOL_NAME): Define.
+ (SYMBOLIC_CONST_P): Define.
+ (ENCODE_SECTION_INFO): Use SYMBOL_REF_FLAG to mark local
+ symbols.
+ (MN10300_GLOBAL_P): Test it.
+ (OUTPUT_ADDR_CONST_EXTRA): Handle PIC-related unspecs.
+ (JUMP_TABLES_IN_TEXT_SECTION): Enable for PIC.
+ * config/mn10300/mn10300.c (print_operand): Handle unspec.
+ (expand_prologue): Set PIC register.
+ (call_address_operand): Don't match SYMBOL_REFs in PIC.
+ (legitimize_address): Call legitimize_pic_address.
+ (legitimize_pic_address): New fn.
+ (legitimate_pic_operand_p): New fn.
+ * config/mn10300/mn10300.md (PIC_REG, SP_REG): New constants.
+ (UNSPEC_INT_LABEL, UNSPEC_PIC, UNSPEC_GOT, UNSPEC_GOTOFF,
+ UNSPEC_PLT): New constants.
+ (pop_pic_reg): New insn.
+ (movsi): Adjust non-PIC addresses.
+ (builtin_setjmp_receiver): Restore the PIC register.
+ (casesi): New insn.
+ (call): Adjust non-PIC addresses.
+ (int_label, GOTaddr2picreg): New expands.
+ (am33_loadPC): New insn.
+ (mn10300_loadPC): New expand.
+ (call_next_insn): New insn.
+ (add_GOT_to_pic_reg): New expand.
+ (symGOT2reg, symGOT2reg_i): New expands.
+ (symGOTOFF2reg, symGOTOFF2reg_i): New expands.
+ (sym2PIC, sym2PLT): New expands.
+
+2003-07-09 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mn10300/mn10300.h (PREDICATE_CODES): Define.
+ 2001-05-01 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.md (sqrtsf2): flag_fast_math was renamed
+ to flag_unsafe_math_optimizations.
+ 2001-04-14 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.c (expand_prologue): Mark
+ FP-register-saving insns as frame-related.
+ 2001-02-13 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.c
+ (mn10300_get_live_callee_saved_regs): Don't search past
+ LAST_EXTENDED_REGNUM.
+ (mn10300_gen_multiple_store, store_multiple_operation): Likewise.
+ * config/mn10300/mn10300.md: Remove excessive line breaks from
+ `@' output patterns that were accounted as additional
+ alternatives.
+ * config/mn10300/mn10300.md, config/mn10300/mn10300.c:
+ Re-introduce changes accidentally removed in Richard Sandiford's
+ 2000-12-05's patch.
+ * config/mn10300/t-mn10300 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
+ Re-instate am33-2 lost in merge from net GCC.
+ 2000-08-26 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.h (DBX_REGISTER_NUMBER): Added
+ floating-point registers.
+ 2000-08-07 Alexandre Oliva <aoliva@redhat.com>
+ * config/mn10300/mn10300.md (movdf): Revert some am33-specific
+ pessimizations that had gone in on 2000-05-08.
+ 2000-06-28 Graham Stott <grahams@cygnus.co.uk>
+ * config/mn10300/mn10300.h (REG_CLASS_CONTENTS): Fix typo.
+ 2000-06-22 Graham Stott <grahams@cygnus.co.uk>
+ * config/mn10300/mn10300.md (movqi): Use nonimmediate_operand for
+ operand 0.
+ * (movhi): Likewise.
+ * (movsi): Likewise.
+ * (movsf): Likewise.
+ * (movdi): Likewise.
+ * (movdf): Likewise.
+ 2000-05-24 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.c (fp_regs_to_save): New function.
+ (can_use_return_insn, initial_offset): Add fp_regs_to_save.
+ (expand_prologue, expand_epilogue): Save and restore FP regs.
+ 2000-05-20 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.md (movdi, movdf): 64-bit clean-up.
+ 2000-05-13 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.md (abssf2, negsf2, rsqrtsf2, addsf3,
+ subsf3, mulsf3, divsf3, fmaddsf4, fmsubsf4, fnmaddsf4, fnmsubsf4):
+ Do not clobber cc0.
+ 2000-05-12 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.md (abssf2, negsf2, rsqrtsf2):
+ Discourage the two-argument, longer opcodes.
+ (addsf3, subsf3, mulsf3, divsf3): Likewise for three-argument
+ ones.
+ * config/mn10300/mn10300.h (struct mn10300_cc_status_mdep): New.
+ (CC_STATUS_MDEP, CC_STATUS_MDEP_INIT): Define.
+ * config/mn10300/mn10300.md (cmpsf): New pattern.
+ (branch): Test mdep.fpCC and output fbCC.
+ * config/mn10300/mn10300.c (print_operand): Output conditions.
+ (notice_cc_update): Recognize fcmp and set mdep.fpCC.
+ 2000-05-10 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.md (movsf, movdf, addsf3, subsf3,
+ mulsf3, divsf3): Use the `F' constraint for FP values.
+ * config/mn10300/mn10300.c (const_1f_operand): New function.
+ * config/mn10300/mn10300-protos.h (const_1f_operand): Declare.
+ * config/mn10300/mn10300.md (sqrtsf2): New expand.
+ (rsqrtsf2): New insn.
+ 2000-05-09 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.md (movdf): Oops, I missed it in my
+ previous check-in.
+ 2000-05-08 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.md (abssf2, negdf2): On
+ TARGET_AM33_2, expand to...
+ (abssf2_am33_2, negdf2_am33_2): New insns.
+ (addsf3, subsf3, mulsf3, divsf3): Likewise.
+ (fmaddsf4, fmsubsf4, fnmaddsf4, fnmsubsf4): Likewise.
+ * config/mn10300/mn10300.md (movqi, movhi, movsi, movsf,
+ movdi, movdf): Added FP regs.
+ * invoke.texi (-mam33-2, -mno-am33-2): Document.
+ 2000-04-29 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.h (FIRST_FP_REGNUM, LAST_FP_REGNUM):
+ New macros.
+ (REGNO_AM33_2_FP_P): Renamed to...
+ (REGNO_FP_P): Redefine in terms of FIRST_* and LAST_*.
+ (CONDITIONAL_REGISTER_USAGE, REGNO_REG_CLASS): Likewise.
+ 2000-04-27 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.h (REG_CLASS_CONTENTS): Remove FP
+ regs from GENERAL_REGS.
+ 2000-04-27 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.h (REGNO_AM33_2_FP_P): New macro.
+ * config/mn10300/mn10300.c (mn10300_address_cost): Added FP_REGS.
+ * config/mn10300/mn10300.h (REGISTER_MOVE_COST): Added FP_REGS.
+ 2000-04-23 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.h (CLASS_CANNOT_CHANGE_SIZE): Defined
+ as FP_REGS.
+ 2000-04-21 Alexandre Oliva <aoliva@cygnus.com>
+ * config/mn10300/mn10300.h (OK_FOR_Q): New macro.
+ (EXTRA_CONSTRAINT): Added OK_FOR_Q.
+ * config/mn10300/mn10300.c (secondary_reload_class): Adjust.
+ * config/mn10300/mn10300.c (print_operand): Support `D' for doubles.
+ * config/mn10300/mn10300.h (FIRST_PSEUDO_REGISTER): Adjust.
+ (FIXED_REGISTERS, CALL_USED_REGISTERS, REG_ALLOC_ORDER): Added
+ AM33/2.0 floating-point registers.
+ (CONDITIONAL_REGISTER_USAGE): Adjust.
+ (enum reg_class, REG_CLASS_NAMES): Added FP_REGS and FP_ACC_REGS.
+ (REG_CLASS_CONTENTS, REGNO_REG_CLASS): Adjust.
+ (REG_CLASS_FROM_LETTER): Added `f' and `A'.
+ (REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Adjust.
+ * config/mn10300/t-mn10300 (MULTILIB_OPTIONS): Added am33-2.
+ (MULTILIB_DIRNAMES): Likewise.
+ * config/mn10300/mn10300.h (CPP_SPEC): Define `__AM33__=2' and
+ `__AM33_2__' when `-mam33-2' is given.
+ (TARGET_AM33_2): Define.
+ (TARGET_SWITCHES): Adjust.
+ * config/mn10300/mn10300.c (asm_file_start): Print `.am33_2'
+ when appropriate.
+
+2003-07-09 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * doc/install.texi: Add missing @.
+
+2003-07-09 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.h (CRT_CALL_STATIC_FUNCTION): Define.
+
+2003-07-09 Aldy Hernandez <aldyh@redhat.com>
+
+ PR/11144
+ * config/i386/i386.c (ix86_function_arg_boundary): Remove abort.
+
+2003-07-09 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR bootstrap/11043
+ * config/arc/t-arc: Replace bogus references to "x-crtinit.o",
+ "x-crtfini.o" with "crtinit.o", "crtfini.o".
+
+ * fixinc/inclhack.def (limits_ifndefs): Add select test.
+ * fixinc/fixincl.x: Rebuild.
+
+ * fixinc/inclhack.def (math_exception): Improve bypass and comment.
+ * fixinc/fixincl.x: Rebuild.
+
+2003-07-09 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * doc/install.texi (Configuration): Document the valgrind option
+ to --enable-checking.
+
+2003-07-09 Jan Hubicka <jh@suse.cz>
+
+ * objc-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): New.
+
+2003-07-09 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * c-lex.c (cb_ident): Cast cstr.text to const char *.
+
+2003-07-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov-io.h: Update documentation.
+ (GCOV_GRAPH_SUFFIX, GCOV_GRAPH_MAGIC): Rename to GCOV_NOTE_SUFFIX,
+ GCOV_NOTE_MAGIC.
+ (GCOV_DATA_SUFFIX, GCOV_NOTE_SUFFIX): Update.
+ (GCOV_DATA_MAGIC, GCOV_NOTE_MAGIC): Make non-palindromic.
+ (struct gcov_var): Change buffer's type. Add endian flag.
+ (gcov_open): Remove mode in libgcov.
+ (gcov_magic): Prototype.
+ * gcov-io.c (from_file): New.
+ (gcov_open): Clear endian flag.
+ (gcov_magic): New.
+ (gcov_write_bytes, gcov_read_bytes): Return gcov_unsigned_t
+ pointers.
+ (gcov_write_unsigned, gcov_write_counter, gcov_write_string,
+ gcov_write_tag, gcov_write_length, gcov_write_tag_length): Update.
+ (gcov_read_unsigned, gcov_read_counter, gcov_read_string): Update.
+ * gcov-iov.c (main): Correct cast.
+ * coverage.c (read_counts_file): Use gcov_magic. Remove endianness
+ conversion.
+ (gcov_begin_output): Use GCOV_NOTE_MAGIC.
+ (coverage_init): Use GCOV_NOTE_SUFFIX.
+ * libgcov.c (gcov_version_mismatch): Remove endianness conversion.
+ Rename to gcov_version, and return flag.
+ (gcov_exit): Use gcov_version.
+ (__gcov_init): Use gcov_version.
+ * Makefile.in (coverageexts): Update.
+ * gcov.c (print_version): Remove endianness conversion.
+ (create_file_names): Use GCOV_NOTE_SUFFIX.
+ (read_graph_file): Use gcov_magic.
+ (read_count_file): Likewise.
+ * gcov-dump.c (dump_file): Remove endianness conversion, use
+ gcov_magic.
+
+2003-07-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * configure.in (BUILD_PREFIX, BUILD_PREFIX_1): Set if enable
+ coverage is on.
+ * configure: Regenerated.
+ * Makefile.in (ALL_CFLAGS): Correct its comment.
+
+2003-07-08 Mark Mitchell <mark@codesourcery.com>
+
+ * fold-const.c (make_range): Do not access operand 1 for a
+ zero-operand operator.
+
+2003-07-09 Neil Booth <neil@daikokuya.co.uk>
+
+ * toplev.c (warn_dummy, W_options): Die.
+ (display_help): Don't print W_options.
+ * common.opt: Add W_options help from toplev.c.
+
+2003-07-09 Andreas Jaeger <aj@suse.de>
+
+ * opts.c (wrap_help): Only pass int arguments as arguments to
+ printf's '*' modifier. Change argument of function.
+
+2003-07-08 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * doc/invoke.texi: Fix misspelling of "@item".
+
+2003-07-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386.md: Remove an old comment about
+ NOTICE_UPDATE_CC.
+
+2003-07-09 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_node_name): New function.
+ (dump_cgraph): Use it.
+ * cgraph.h (cgraph_dump_file): Declare.
+ (cgraph_node_name): Declare.
+ * cgraphunit.c: Include timevar.h
+ (cgraph_finalize_compilation_unit): Use timevar; reorganize dumps.
+ (cgraph_optimize_function): Use TV_INTEGRATION.
+ (cgraph_mark_local_functions): reorganize dumps.
+ (cgraph_mark_functions_to_inline_once): Likewise.
+ (cgraph_optimize): Likewise; use timevar.
+ * timevar.def (TV_CGRAPH, TV_CGRAPHOPT): New.
+ * toplev.c (dump_file_index): Add DFI_cgraph.
+ (dump_file_info): Likewise.
+ (cgraph_dump_file): New global variable.
+ (do_compile): Open and close cgraph dump.
+ * invoke.texi (-d): Document new flag; renumber.
+
+2003-07-08 Roger Sayle <roger@eyesopen.com>
+
+ PR c/11370
+ * calls.c (emit_call_1): Don't bother popping the arguments off of
+ the stack after a noreturn function call; The adjustment is dead.
+ (expand_call): Likewise.
+
+2003-07-08 Geoffrey Keating <geoffk@apple.com>
+
+ * expr.c (MOVE_MAX_PIECES): Move from here...
+ * defaults.h (MOVE_MAX_PIECES): ... to here.
+
+2003-07-08 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * Makefile.in (stage1-start): Handle an empty SUBDIRS.
+
+2003-07-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * genattr.c (internal_dfa_insn_code): Don't prototype.
+ * genattrtab.c (attr_desc): Add `static_p' field.
+ (expand_units): Make blockage range and ready cost functions
+ static.
+ (write_attr_get): Don't add extern prototypes in C file. Mark
+ static functions as appropriate.
+ (find_attr, make_internal_attr): Initialize static_p.
+ * genattrtab.h (ATTR_STATIC): New macro.
+ * genautomata.c (output_internal_reset_func): Mark output function
+ as inline.
+ (make_internal_dfa_insn_code_attr): Mark output function as static.
+
+2003-07-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * genattrtab.h: Add new macros for attr `special' flags.
+ * genattrtab.c (attr_desc): Reorder/resize fields better.
+ Use attr `special' macros in all calls to make_internal_attr.
+ * genautomata.c: Likewise.
+
+2003-07-09 Jan Hubicka <jh@suse.cz>
+
+ * c-common.c (c_estimate_num_insns_1): New static function.
+ (c_estimate_num_insns): New global function.
+ * c-common.h (DECL_NUM_STMTS): Rename to...
+ (DECL_ESTIMATED_INSNS): ... this.
+ (c_estimate_num_insns): Declare.
+ * c-decl.c (duplicate_decls): Use DECL_ESTIMATED_INSNS.
+ * c-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): New.
+ * c-semantics.c (add_stmt): Do not account statements.
+ * langhooks-def.h (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS):
+ New.
+ * langhooks.h (lang_hooks_for_tree_inlining): Add
+ estimate_num_insns
+ * params.def (max-inline-insns-auto, max-inline-insns-auto): set
+ to 100.
+ (max-inline-insns): set to 300.
+ (min-inline-insns): set to 10.
+ * tree-inline.c (struct inline_data): Rename inlined_stmts to
+ inlined-insns.
+ (INSNS_PER_STMT): Kill.
+ (inlinable_function_p): Compute and store body size.
+ (expand_call_inline): Likewise.
+ (optimize_inline_calls): Likewise.
+
+2003-07-08 James E Wilson <wilson@tuliptree.org>
+
+ PR target/10021
+ * emit-rtl.c (set_mem_attribute_minus_bitpos): When handle ARRAY_REF,
+ loop over new variable t2 instead of t.
+
+2003-07-08 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR bootstrap/11455
+ * config/i386/winnt.c: Replace use of error(), warning() with
+ error_with_decl(), warning_with_decl(), throughout.
+
+2003-07-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * opts.c (wrap_help): Use unsigned int, not size_t.
+
+2003-07-08 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.h (HAVE_AS_DWARF2_DEBUG_LINE): Don't define
+ as .file/.loc directives are incompatible with linker relaxation.
+
+2003-07-08 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (fixinc.sh): Remove gnu-regex.[ch] from dependencies.
+ * fixinc/Makefile.in: Remove all references to gnu-regex.[och].
+ * fixinc/fixfixes.c, fixinc/fixincl.c, fixinc/fixlib.c
+ * fixinc/fixtests.c: Use xregexec not regexec, xregcomp not regcomp.
+ * fixinc/fixlib.h: Include xregex.h not gnu-regex.h.
+ * fixinc/inclhack.def (hpux10_cpp_pow_inline, hpux11_cpp_pow_inline):
+ Escape { and } characters which are not part of range expressions.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/gnu-regex.c, fixinc/gnu-regex.h: Delete file.
+
+2003-07-08 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR c/1687
+ * tree-inline.c (find_alloca_call): Use
+ walk_tree_without_duplicates, instead of walk_tree.
+ (find_builtin_longjmp_call): Likewise.
+ * c-objc-common.c (c_cannot_inline_fn): Likewise.
+ * c-semantics.c (find_reachable_label): Likewise.
+
+2003-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/11420
+ * config/i386/i386.c (ix86_check_movabs): New function.
+ * config/i386/i386-protos.h (ix86_check_movabs): New prototype.
+ * config/i386/i386.md (movabs[shqd]i_1_rex64): Kill broken alternative.
+ (movabs[shqd]i_[12]_rex64): Add ix86_check_movabs check to conditions.
+
+2003-07-08 Chris Demetriou <cgd@broadcom.com>
+
+ * Makefile.in (install-po): Cope with empty CATALOGS.
+
+2003-07-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/elf64.h (TARGET_ASM_UNIQUE_SECTION): Delete.
+ (EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Delete.
+ (SECTION_FUNCTION_TEMPLATE): Delete.
+ * config/mips/elf.h: As for elf64.h.
+ (ASM_OUTPUT_ALIGNED_BSS): Use named_section rather than sbss_section.
+ * config/mips/linux.h: As for elf.h
+ * config/mips/iris6gld.h (TARGET_ASM_UNIQUE_SECTION): Delete.
+ * config/mips/iris6.h (EXTRA_SECTIONS): Delete.
+ (EXTRA_SECTION_FUNCTIONS): Remove sdata_section. Remove the handling
+ of in_sdata from current_section_name and current_section_flags.
+ * config/mips/iris6gld.h (TARGET_ASM_UNIQUE_SECTION): Delete.
+ * config/mips/mips.h (sdata_section, sbss_section): Remove prototypes.
+ (MASK_GP_OPT, TARGET_GP_OPT): Delete.
+ (MASK_NO_FUSED_MADD): Use MASK_GP_OPT's old value.
+ (TARGET_SWITCHES): Neuter gpOPT, gpopt, no-gpOPT and no-gpopt.
+ (SMALL_DATA_SECTION, EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Remove.
+ * config/mips/mips.c (TARGET_IN_SMALL_DATA_P): Override.
+ (TARGET_SECTION_TYPE_FLAGS): Override if TARGET_IRIX6.
+ (mips_classify_symbol): Use SYMBOL_REF_SMALL_P.
+ (override_options): Remove setting of MASK_GPOPT.
+ (mips_output_external): Use mips_in_small_data_p to check whether a
+ symbol needs an .extern directive. Don't emit such directives for
+ TARGET_EXPLICIT_RELOCS.
+ (mips_declare_object): Update accordingly.
+ (mips_select_rtx_section): Call named_section rather than
+ SMALL_DATA_SECTION.
+ (mips_select_section): Use default_elf_section_section for everything
+ except .text string constants.
+ (mips_in_small_data_p): New function.
+ (mips_encode_section_info): Remove small data handling.
+ (mips_unique_section): Delete.
+ (iris6_section_type_flags): New function.
+ * doc/tm.texi: Remove documentation of -mgpopt and -mhalf-pic.
+
+2003-07-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR Target/11453
+ * pa.md: Disparage all mtsar constraints.
+ (extzv, extv, insv): Don't fail on length of {32|64}.
+
+2003-07-08 Zack Weinberg <zack@codesourcery.com>
+
+ * system.h: Poison MAP_CHARACTER.
+ * config/i370/i370-protos.h (mvs_map_char): Delete.
+ * config/i370/i370.c (ascebc, ebcasc, mvs_map_char): Delete.
+ * config/i370/i370.h (MAP_CHARACTER): Delete definition.
+ (ASM_OUTPUT_ASCII): Don't use MAP_CHARACTER.
+
+2003-07-08 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * toplev.c (randomize): Correct call to time().
+
+2003-07-08 Jakub Jelinek <jakub@redhat.com>
+
+ * unroll.c (reg_dead_after_loop): Check for reg in REG_EQUAL and
+ REG_EQUIV notes as well.
+
+2003-07-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/md.texi: Fix the description of addmodecc.
+
+2003-07-07 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (top_builddir): Set to "..", not ".".
+ (INTLLIBS, INTLDEPS): Delete.
+ (LIBINTL, LIBINTL_DEP, LIBICONV_DEP): New variables to be substituted.
+ (LIBDEPS): Add $(LIBICONV_DEP).
+ (LIBS): Take out $(INTLLIBS), add $(LIBINTL) and $(LIBICONV).
+ (INCLUDES): Replace -I../intl with @INCINTL@.
+ ($(top_builddir)/intl/libintl.a): Delete rule.
+ (stage2-start, stage3-start, stage4-start, stageprofile-start,
+ stagefeedback-start): Use $$ for variable to be evaluated by
+ shell, not make.
+ * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT,
+ HAVE_LC_MESSAGES, HAVE_STPCPY): Delete.
+ * aclocal.m4: sinclude ../config/progtest.m4. Add
+ contents of lcmessage.m4 from gettext distro.
+ * configure.in: Check for wchar.h and setlocale. Set
+ LIBICONV_DEP to the empty string and substitute it.
+ Call AM_LC_MESSAGES. Delete AC_ARG_ENABLE for --enable-nls;
+ this is handled elsewhere. Use ZW_GNU_GETTEXT_SISTER_DIR,
+ not CY_GNU_GETTEXT. Clear $LIBICONV if its text is included
+ in $LIBINTL, to avoid linking it twice.
+ * configure, config.in: Regenerate.
+
+2003-07-08 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/mkfixinc.sh: Remove winnt support.
+ * fixinc/fixinc.winnt: Delete with extreme prejudice.
+
+2003-07-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Update.
+ * c-opts.c (c_common_handle_option): opt_text now contains the '-'.
+ * c.opt: Update documentation.
+ * common.opt: Add some help text.
+ * opts.c: Include intl.h.
+ (wrap_help, print_help): New.
+ (find_opt, handle_option, common_handle_option): opt_text now
+ contains the '-'. Use print_help to output help.
+ * opts.h (struct cl_option): New member "help".
+ * opts.sh: Update to handle help text output and to prepend
+ options with '-'.
+ * toplev.c (display_help): Remove some help text.
+
+2003-07-07 David Edelsohn <edelsohn@gnu.org>
+ Fariborz Jahanian <fjahanian@apple.com>
+
+ * configure.in: Test for PowerPC mfcr field support in assembler.
+ * config.in, configure: Regenderated.
+
+ * config/rs6000/power4.md: Add mfcrf reservation.
+ * config/rs6000/rs6000-protos.h (mfcr_operation): Declare.
+ * config/rs6000/rs6000.c (mfcr_operation): Define.
+ (print_operand): Add 'Q' case for mfcrf.
+ * config/rs6000/rs6000.h (TARGET_MFCRF): New.
+ * config/rs6000/rs6000.md (attribute "type"): Add mfcrf.
+ (movcc_internal1): Emit optional field operand for mfcr and set
+ "type" attribute appropriately.
+ (mfcr SCC): Likewise.
+ (movesi_from_cr_one): New.
+
+2003-07-07 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.md: Correct check-in of incorrect version.
+
+2003-07-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bitmap.c (debug_bitmap_file): Merge uses of HOST_PTR_PRINTF with
+ adjacent stdio calls.
+ * c-decl.c (c_print_identifier): Likewise.
+ * mips-tfile.c (write_varray, write_object, allocate_cluster): Likewise.
+ * print-rtl.c (print_rtx): Likewise.
+ * print-tree.c (print_node_brief, print_node): Likewise.
+ * system.h (HOST_PTR_PRINTF): Ensure we have a literal string.
+
+ * configure.in (AC_COMPILE_CHECK_SIZEOF): Check for `void *'.
+ * config.in, configure: Regenerated.
+
+2003-07-07 Roger Sayle <roger@eyesopen.com>
+
+ PR target/10979
+ * config/i386/i386.md (atan2df3, atan2sf3, atan2xf3, atan2tf3):
+ Changed to define_expand patterns that copy operand[1] to prevent
+ it from being clobbered before emitting an atan2?f3_1 insn.
+ (atan2df3_1, atan2sf3_1, atan2xf_1, atan2tf3_1): New define_insn
+ patterns that actually specify the behaviour of x87's FPATAN.
+
+2003-07-07 Jakub Jelinek <jakub@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_output_mi_thunk): Remove bogus
+ clearing of SYMBOL_FLAG_LOCAL bit.
+ If vcall_offset fits into signed 16-bit immediate, use
+ one instruction for both addition and load.
+
+2003-07-07 Neil Booth <neil@daikokuya.co.uk>
+
+ * opts.c (common_handle_option): Correct handling of the
+ -falign- switches that do and don't take an argument.
+
+2003-07-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (pushqi1_h8300hs): Revert my patch
+ today.
+ (pushhi1_h8300hs): Likewise.
+
+2003-07-07 Andreas Jaeger <aj@suse.de>
+
+ * genextract.c: Convert remaining prototypes to ISO C90.
+
+ * cpplex.c (_cpp_free_buff): Convert prototype to ISO C90.
+ * fold-const.c (fold_single_bit_test): Likewise.
+ * diagnostic.c (default_diagnostic_finalizer): Likewise.
+ * cfgrtl.c (rtl_redirect_edge_and_branch): Likewise.
+
+ * gengtype.c (write_array): Generate ISO C90 prototypes.
+
+ * genflags.c (gen_proto): Generate ISO C90 prototypes.
+
+2003-07-07 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/11059
+ * expr.c (can_store_by_pieces): Return true if length is zero.
+ (store_by_pieces): If length is zero and endp is two, abort,
+ othwerise, if length is zero and endp is not two, return "to".
+ (clear_by_pieces): Do nothing if length is zero.
+ (clear_storage): Do nothing if length is zero.
+ (store_constructor): Simplify code when size is zero, or the
+ target has already been cleared. This avoids emitting a
+ blockage instruction when initializing empty structures.
+
+2003-07-07 Andreas Jaeger <aj@suse.de>
+
+ * mips-tfile.c: Convert prototypes to ISO C90.
+ * mips-tdump.c: Convert prototypes to ISO C90.
+
+2003-07-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtl.h (emit_line_note): Take a location_t.
+ (emit_line_note_force): Remove.
+ (set_file_and_line_for_statement): Take a location_t.
+ * tree.g (emit_line_note): Take a location_t.
+ * emit-rtl.c (emit_line_note): Take a location_t.
+ (emit_line_note_force): Remove.
+ * function.c (init_function_start): Adjust emit_line_note call.
+ (expand_function_end): Use force_next_line_note, not
+ emit_line_note_force.
+ * c-parse.in (maybe_type_qual): Adjust emit_line_note calls.
+ * c-semantics.c (genrtl_do_pushlevel, genrtl_goto_stmt,
+ genrtl_expr_stmt_value, genrtl_decl_stmt, genrtl_if_stmt,
+ genrtl_while_stmt, genrtl_do_stmt_1, genrtl_return_stmt,
+ genrtl_for_stmt, genrtl_break_stmt, genrtl_continue_stmt,
+ genrtl_continue_stmt, genrtl_switch_stmt,
+ genrtl_asm_stmt): Likewise.
+ * expr.c (expand_expr): Likewise.
+ * integrate.c (expand_inline_function): Likewise.
+ * stmt.c (set_file_and_line_for_stmt): Take a location_t.
+ (expand_decl_init): Adjust emit_line_note call.
+
+2003-07-07 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/darwin-tramp.asm: Fix trampolines. PR 10900.
+
+2003-07-07 Andreas Jaeger <aj@suse.de>
+
+ * config/i386/i386-protos.h: Convert prototypes to ISO C90.
+ * config/i386/i386.c: Likewise.
+
+2003-07-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Use gen_int_mode instead of
+ GEN_INT (trunc_int_for_mode (...)).
+
+2003-07-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (pushqi1_h8300hs): Optimize by pushing
+ 2 bytes and then subtract 2 from the stack pointer.
+ (pushhi1_h8300hs): Likewise.
+
+2003-07-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * configure.in (enable_coverage): Remove -DSELF_COVERAGE, add
+ -frandom-seed.
+ * configure: Regenerated.
+ * Makefile.in: Remove extraneous comment.
+ * toplev.c (randomize): Protect against potential multiple calls.
+ * doc/invoke.texi (-frandom-seed): Document use for in coverage
+ files.
+
+2003-07-07 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11198
+ * alias.c (objects_must_conflict_p): Return 1 if the types have
+ the same alias set, not if the alias sets only conflict.
+
+2003-07-07 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * cppcharset.c (ICONV_CONST): Define iff !HAVE_ICONV.
+ (convert_cset): Change inbuf to type ICONV_CONST char.
+ * Makefile.in (LIBS): Add LIBICONV.
+
+ * doc/invoke.texi (-falign-functions): Document that
+ when n is zero then a machine-dependent default is used.
+ (-falign-labels): Document that when n is zero then a
+ machine-dependent default is used and that -falign-labels =1
+ is equivalent to -fno-align-labels.
+ (-falign-loops): Likewise.
+ (-falign-jumps): Likewise.
+
+2003-07-06 Art Haas <ahaas@airmail.net>
+
+ * f/global.c (ffeglobal_type_string_): Fix obsolete GCC array
+ initializer syntax.
+
+2003-07-06 James E Wilson <wilson@tuliptree.org>
+
+ PR optimization/9812
+ * rtl.h (mem_for_const_double): Delete prototype.
+ * varasm.c (mem_for_const_double): Delete function.
+ * config/m68k/hp320.h, config/m68k/linux.h, config/m68k/m68kelf.h,
+ config/m68k/m68kv4.h, config/m68k/netbsd-elf.h
+ (LEGITIMATE_PIC_OPERAND_P): Delete duplicate definitions.
+ * config/m68k/m68k.h (LEGITIMATE_CONSTANT_P): Disallow XFmode.
+ (LEGITIMATE_PIC_OPERAND_P): Delete CONST_DOUBLE tests.
+ * config/m68k/m68k.md (movxf): Add reload_in_progress guard. Add
+ comment about confused support for XFmode constants.
+
+2003-07-07 Jan Hubicka <jh@suse.cz>
+
+ * cfglayout.c (fixup_reorder_chain): Call delete_dead_jumptables.
+
+2003-07-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c: Fix comment typos.
+ * config/h8300/h8300.md: Likewise.
+ * config/i386/athlon.md: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/i386/pentium.md: Likewise.
+ * config/ia64/ia64.c: Likewise.
+ * config/ia64/itanium1.md: Likewise.
+ * config/ia64/itanium2.md: Likewise.
+ * config/m32r/m32r.md: Likewise.
+ * config/m68hc11/m68hc11.c: Likewise.
+ * config/mcore/mcore.c: Likewise.
+ * config/mips/sr71k.md: Likewise.
+ * config/mips/t-iris5-as: Likewise.
+ * config/mmix/mmix.h: Likewise.
+ * config/ns32k/ns32k.h: Likewise.
+ * config/ns32k/NOTES: Fix a typo.
+
+2003-07-06 Andreas Jaeger <aj@suse.de>
+
+ * stmt.c: Convert remaining prototypes to ISO C90.
+ * cfglayout.c: Likewise.
+ * dbxout.c: Likewise.
+ * gcc.c: Likewise.
+ * genemit.c: Likewise.
+
+ * basic-block.h: Convert prototypes to ISO C90.
+ * c-parse.in: Likewise.
+ * c-pragma.h: Likewise.
+ * c-typeck.c: Likewise.
+ * cfghooks.h: Likewise.
+ * cfgloopanal.c: Likewise.
+ * dbxout.h: Likewise.
+ * debug.h: Likewise.
+ * dwarf2asm.h: Likewise.
+ * gcov.c: Likewise.
+ * gengtype-lex.l: Likewise.
+ * sched-int.h: Likewise.
+ * timevar.c: Likewise.
+
+2003-07-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.h (c_comon_handle_filename,
+ c_common_missing_arguement): New.
+ * c-lang.c (LANG_HOOKS_HANDLE_FILENAME,
+ LANG_HOOKS_MISSING_ARGUMENT): New.
+ * c-opts.c (missing_arg): Rename c_common_missing_argument,
+ update to be an appropriate langhook.
+ (c_common_handle_option): Don't handle filenames.
+ (c_common_handle_filename): New.
+ * hooks.c (hook_void_constcharptr,
+ hook_bool_constcharptr_size_t_false): New.
+ * hooks.h (hook_void_constcharptr,
+ hook_bool_constcharptr_size_t_false): New.
+ * langhooks-def.h (LANG_HOOKS_HANDLE_FILENAME,
+ LANG_HOOKS_MISSING_ARGUMENT): New.
+ (LANG_HOOKS_INITIALIZER): Update.
+ * langhooks.h (struct lang_hooks): Add handle_filename and
+ missing_argument.
+ * opts.c (handle_option): Don't handle filenames here, but ...
+ (handle_options): ... here.
+ (common_handle_option): Don't handle missing arguments here.
+ * objc/objc-lang.c (LANG_HOOKS_HANDLE_FILENAME,
+ LANG_HOOKS_MISSING_ARGUMENT): New.
+
+2003-07-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makfile.in: Remove traces of mbchar.
+ * c-parse.in (MULTIBYTE_CHARS): Remove.
+ * config.in (MULTIBYTE_CHARS): Remove.
+ * configure: Remove --enable-mbchar.
+ * configure.in: Remove --enable-mbchar.
+ * mbchar.c, mbchar.h: Remove.
+ * system.h: Poison MULTIBYTE_CHARS.
+ * config/linux-aout.h (MULTIBYTE_CHARS): Remove.
+ * config/linux.h (MULTIBYTE_CHARS): Remove.
+ * config/svr4.h (MULTIBYTE_CHARS): Remove.
+ * config/sparc/linux.h (MULTIBYTE_CHARS): Remove.
+
+2003-07-06 Andreas Jaeger <aj@suse.de>
+
+ * varray.c (varray_check_failed): Fix typo.
+
+ * unroll.c: Convert prototypes to ISO C90.
+ * varasm.c: Likewise.
+ * varray.c: Likewise.
+ * varray.h: Likewise.
+ * vmsdbgout.c: Likewise.
+ * xcoffout.c: Likewise.
+ * xcoffout.h: Likewise.
+
+2003-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov-io.h: Add a local time stamp.
+ (struct gcov_info): Add stamp field.
+ (gcov_truncate): New.
+ * coverage.c (read_counts_file): Skip the stamp.
+ (coverage_begin_output): Write the stamp.
+ (build_gcov_info): Declare and init the stamp.
+ (coverage_finish): Only unlink data file, if stamp is zero.
+ * gcov-dump.c (dump_file): Dump the stamp.
+ * gcov.c (bbg_stamp): New.
+ (release_structures): Clear bbg_stamp.
+ (read_graph_file): Read stamp.
+ (read_count_file): Check stamp.
+ * libgcov.c (gcov_exit): Check stamp and truncate if needed.
+
+2003-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.h (default_flag_random_seed): Remove.
+ * toplev.h (local_tick): Declare.
+ * tree.c (flag_random_seed, default_flag_random_seed): Move to
+ toplev.c.
+ (append_random_chars): Don't call default_flag_random_seed.
+ * toplev.c (flag_random_seed): Define here. Set local_tick.
+ (local_tick): Define.
+ (randomize): New, moved from tree.c.
+ (print_switch_values): Adjust.
+ (toplev_main): Call randomize.
+
+2003-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.h (crc32_string): Declare.
+ * tree.c (append_random_chars): Remove.
+ (crc32_string): New.
+ (get_file_function_name_long): Use crc32_string here.
+
+2003-07-06 Andreas Jaeger <aj@suse.de>
+
+ * gcc.c: Convert prototypes to ISO C90.
+ * gcc.h: Likewise.
+ * gcov-dump.c: Likewise.
+ * gcov-iov.c: Likewise.
+ * gcse.c: Likewise.
+ * genattrtab.h: Likewise.
+ * ggc.h: Likewise.
+ * global.c: Likewise.
+ * graph.c: Likewise.
+ * graph.h: Likewise.
+ * hosthooks.h: Likewise.
+ * hooks.h: Likewise.
+ * hooks.c: Likewise.
+ * hashtable.h: Likewise.
+ * hashtable.c: Likewise.
+ * haifa-sched.c: Likewise.
+ * integrate.h: Likewise.
+ * integrate.c: Likewise.
+ * input.h: Likewise.
+ * ifcvt.c: Likewise.
+ * jump.c: Likewise.
+ * langhooks-def.h: Likewise. Add extern to prototypes.
+ * langhooks.c: Likewise.
+ * langhooks.h: Likewise.
+ * lcm.c: Likewise.
+ * local-alloc.c: Likewise.
+ * loop-init.c: Likewise.
+ * loop-unroll.c: Likewise.
+ * loop-unswitch.c: Likewise.
+ * loop.c: Likewise.
+ * loop.h: Likewise. Add extern to prototypes.
+ * machmode.h: Likewise.
+ * main.c: Likewise.
+ * mbchar.c: Likewise.
+ * mbchar.h: Likewise.
+ * mkdeps.c: Likewise.
+ * mkdeps.h: Likewise.
+ * optabs.c: Likewise.
+ * optabs.h: Likewise.
+ * output.h: Likewise.
+ * gccspec.c: Likwise.
+ * postreload.c: Likewise.
+ * prefix.c: Likewise.
+ * prefix.h: Likewise.
+ * print-rtl.c: Likewise.
+ * print-tree.c: Likewise.
+ * profile.c: Likewise.
+ * read-rtl.c: Likewise.
+ * real.c: Likewise.
+ * real.h: Likewise.
+ * recog.c: Likewise.
+ * recog.h: Likewise.
+ * reg-stack.c: Likewise.
+ * regclass.c: Likewise.
+ * regmove.c: Likewise.
+ * regrename.c: Likewise.
+ * regs.h: Likewise.
+ * reload.c: Likewise.
+ * reload.h: Likewise.
+ * reload1.c: Likewise.
+ * reorg.c: Likewise.
+ * resource.c: Likewise.
+ * resource.h: Likewise.
+ * rtl-error.c: Likewise.
+ * rtl.c: Likewise.
+ * rtl.h: Likewise.
+ * rtlanal.c: Likewise.
+ * sbitmap.c: Likewise.
+ * sbitmap.h: Likewise.
+ * scan-decls.c: Likewise.
+ * scan.c: Likewise.
+ * sched-deps.c: Likewise.
+ * sched-ebb.c: Likewise.
+ * sched-int.h: Likewise.
+ * sched-rgn.c: Likewise.
+ * sched-vis.c: Likewise.
+ * sibcall.c: Likewise.
+ * simplify-rtx.c: Likewise.
+ * sreal.c: Likewise.
+ * sreal.h: Likewise.
+ * ssa-ccp.c: Likewise.
+ * ssa-dce.c: Likewise.
+ * ssa.c: Likewise.
+ * ssa.h: Likewise.
+ * stack.h: Likewise.
+ * stmt.c: Likewise.
+ * stor-layout.c: Likewise.
+ * stringpool.c: Likewise.
+ * target.h: Likewise.
+ * timevar.c: Likewise.
+ * timevar.h: Likewise.
+ * tlink.c: Likewise.
+ * tracer.c: Likewise.
+ * tree-inline.c: Likewise.
+ * tree-inline.h: Likewise.
+ * tree.c: Likewise.
+ * tree.h: Likewise.
+
+2003-07-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (nonzero_bits1): Fix a warning.
+
+2003-07-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (compute_mov_length): Correct the
+ length of loading CONST0_RTX (SFmode).
+
+2003-07-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * toplev.c (output_clean_symbol_name): Remove.
+ * toplev.h (output_clean_symbol_name): Remove.
+ * config/alpha/alpha.c (unicosmk_output_module_name): Use
+ lbasename & clean_symbol_name.
+
+2003-07-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ggc.h: Follow spelling conventions.
+ * config/i386/i386.c: Likewise.
+ * config/i386/winnt.c: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+
+2003-07-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * bt-load.c: Fix comment typos.
+ * c-incpath.c: Likewise.
+ * cfg.c: Likewise.
+ * cfgcleanup.c: Likewise.
+ * cfgloop.h: Likewise.
+ * cfgloopmanip.c: Likewise.
+ * cfgrtl.c: Likewise.
+ * diagnostic.h: Likewise.
+ * dwarfout.c: Likewise.
+ * emit-rtl.c: Likewise.
+ * et-forest.c: Likewise.
+ * et-forest.h: Likewise.
+ * expr.c: Likewise.
+ * gcse.c: Likewise.
+ * genattr.c: Likewise.
+ * jump.c: Likewise.
+ * langhooks.h: Likewise.
+ * local-alloc.c: Likewise.
+ * loop-unroll.c: Likewise.
+ * loop-unswitch.c: Likewise.
+ * ra-build.c: Likewise.
+ * regclass.c: Likewise.
+ * regmove.c: Likewise.
+ * rtl.def: Likewise.
+ * rtlanal.c: Likewise.
+ * sched-ebb.c: Likewise.
+ * sched-rgn.c: Likewise.
+ * simplify-rtx.c: Likewise.
+ * ssa.c: Likewise.
+ * tracer.c: Likewise.
+ * tree.c: Likewise.
+
+2003-07-05 Zack Weinberg <zack@codesourcery.com>
+
+ * cppcharset.c: Use the correct return type for the fallback iconv
+ macro.
+
+2003-07-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ Blame to Jan Hubicka <jh@suse.cz>
+ * cfglayout.c (record_effective_endpoints): Split insns before
+ first basic block correctly.
+
+2003-07-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (expand_expr, case COMPONENT_REF): When seeing if should use
+ bitfield operations, use STRICT_ALIGNMENT, not SLOW_UNALIGNED_ACCESS
+ if EXPAND_CONST_ADDRESS or EXPAND_INITIALIZER.
+
+2003-07-05 Andreas Jaeger <aj@suse.de>
+
+ * genattrtab.c (write_attr_get): Revert part of last patch to
+ always write out a prototype.
+
+ * genemit.c (gen_split): Readd lost unused attributes in last
+ patch.
+
+2003-07-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopmanip.c (force_single_succ_latches): Force latch to be
+ different from header.
+
+2003-07-05 Andreas Schwab <schwab@suse.de>
+
+ * config/m68k/m68k.c: Remove code protected by CRDS.
+ * config/m68k/m68k.md: Likewise.
+
+2003-07-05 Neil Booth <neil@daikokuya.co.uk>
+
+ PR driver/11417
+ * c-opts.c (permit_fortran_options): New.
+ (c_common_init_options): Accept fortran front end options if
+ it looks like we might be preprocessing Fortran.
+ (c_common_handle_option): Don't reject switch if permit_fotran_options.
+
+2003-07-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * genattr.c (internal_dfa_insn_code): Output prototype.
+ * genattrtab.c: Don't output unnecessary decls, output in ISO C.
+ * genautomata.c: Likewise.
+ * genconditions.c: Likewise.
+ * genemit.c: Likewise.
+ * genextract.c: Likewise.
+ * gengenrtl.c: Likewise.
+ * gengtype.c: Likewise.
+ * genopinit.c: Likewise.
+ * genoutput.c: Likewise.
+ * genpeep.c: Likewise.
+ * genrecog.c: Likewise.
+
+2003-07-04 Zack Weinberg <zack@codesourcery.com>
+
+ * cpplib.h (CPP_AT_NAME, CPP_OBJC_STRING): New token types.
+ (struct cpp_options): Add narrow_charset, wide_charset,
+ bytes_big_endian fields. Remove EBCDIC field.
+ (cpp_init_iconv, cpp_interpret_string): New external interfaces.
+
+ * cpphash.h: Include <iconv.h> if we have it, otherwise
+ provide a dummy definition of iconv_t.
+ (struct cpp_reader): Add narrow_cset_desc and wide_cset_desc fields.
+ (_cpp_valid_ucn): Update prototype.
+ (_cpp_destroy_iconv): New prototype.
+
+ * doc/cpp.texi: Document character set handling.
+ * doc/cppopts.texi: Document -fexec-charset= and -fexec-wide-charset=.
+ * doc/extend.texi: Delete entire section on multiline strings.
+ Rewrite section on __FUNCTION__ etc now that these are
+ variables in C.
+
+ * cppucnid.tab, cppucnid.pl: New files.
+ * cppucnid.h: New generated file.
+ * cppcharset.c: Include cppucnid.h. Lots of commentary added.
+ (iconv_open, iconv, iconv_close): Provide dummy definitions
+ if !HAVE_ICONV.
+ (SOURCE_CHARSET, struct strbuf, init_iconv_desc, cpp_init_iconv,
+ _cpp_destroy_iconv, convert_cset, width_to_mask, convert_ucn,
+ emit_numeric_escape, convert_hex, convert_oct, convert_escape,
+ cpp_interpret_string, narrow_str_to_charconst,
+ wide_str_to_charconst): New.
+ (ucn_valid_in_identifier): Use a binary search through the
+ ucnranges table defined in cppucnid.h, not a long chain of if
+ statements.
+ (_cpp_valid_ucn): Add a limit pointer. Downgrade "universal
+ character names are only valid in C++ and C99" to a warning.
+ Issue the "meaning of \[uU] is different in traditional C"
+ warning here. Take care not to let iconv see an invalid UCS
+ value if we get a malformed UCN. Issue an error if we don't
+ have iconv.
+ (cpp_interpret_charconst): Moved here from cpplex.c. Use
+ cpp_interpret_string to do the heavy lifting.
+
+ * cppinit.c (cpp_create_reader): Initialize bytes_big_endian,
+ narrow_charset, wide_charset fields of options structure.
+ (cpp_destroy): Call _cpp_destroy_iconv.
+ * cpplex.c (forms_identifier_p): Adjust call to _cpp_valid_ucn.
+ (maybe_read_ucn, hex_digit_value, cpp_parse_escape): Delete.
+ (cpp_interpret_charconst): Moved to cppcharset.c.
+ * cpplib.c (dequote_string): Delete.
+ (interpret_string_notranslate): New.
+ (do_line, do_linemarker): Use interpret_string_notranslate.
+
+ * Makefile.in (cppcharset.o): Depend on cppucnid.h.
+
+ * c-common.c (fname_string, combine_strings): Delete.
+ * c-common.h (fname_string, combine_strings): Delete prototypes.
+ * c-lex.c (ignore_escape_flag): Delete.
+ (cb_ident): Use cpp_interpret_string, not lex_string.
+ (get_nonpadding_token): New function.
+ (c_lex): Handle Objective-C @-prefixed identifiers and strings here.
+ Adjust calls to lex_string. Don't write *value twice.
+ (lex_string): Now handles string constant concatenation.
+ Most of the work handed off to cpp_interpret_string.
+ Call fix_string_type here.
+ * c-parse.in (STRING_FUNC_NAME, VAR_FUNC_NAME): Replace with
+ FUNC_NAME, throughout.
+ (OBJC_STRING): New token type.
+ (primary:STRING): No need to call fix_string_type here.
+ (primary:objc_string): Make that OBJC_STRING.
+ (objc_string nonterminal): Delete.
+ (yylexname): Delete code to handle fake string constants.
+ (yylexstring): Delete entirely.
+ (_yylex): Handle CPP_AT_NAME and CPP_OBJC_STRING. No need
+ to handle CPP_ATSIGN.
+
+ * c.opt (-fexec-charset=, -fwide-exec-charset=): New options.
+ * c-opts.c (missing_arg, c_common_handle_option): Handle
+ OPT_fexec_charset_ and OPT_fwide_exec_charset_.
+ (c_common_init): Set cpp_opts->bytes_big_endian, not
+ cpp_opts->EBCDIC. Call cpp_init_iconv.
+ (print_help): Document -fexec-charset= and -fexec-wide-charset=.
+ (TARGET_EBCDIC): Delete default definition.
+
+ * objc/objc-act.c (build_objc_string_object): No need to
+ handle string constant concatenation.
+
+2003-07-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/install.texi: Fix typos.
+ * doc/invoke.texi: Likewise.
+ * doc/tm.texi: Likewise.
+
+2003-07-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/pa/fptr.c: Fix comment typos.
+ * config/pa/pa-64.h: Likewise.
+ * config/pa/pa.c: Likewise.
+ * config/pa/pa.h: Likewise.
+ * config/rs6000/603.md: Likewise.
+ * config/rs6000/7xx.md: Likewise.
+ * config/rs6000/darwin.h: Likewise.
+ * config/rs6000/freebsd.h: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/rs6000/rs6000.md: Likewise.
+ * config/rs6000/spe.h: Likewise.
+
+2003-07-04 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/2064.md: Change GNU CC to GCC.
+ * config/s390/2084.md: Likewise.
+ * config/s390/fixdfdi.h: Likewise.
+ * config/s390/linux.h: 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/s390x.h: Likewise.
+
+2003-07-04 Jeff Law <law@redhat.com>
+
+ PR c/11428
+ * expr.c (do_store_flag): Pass in the correct result type
+ when calling fold_single_bit_test.
+ * fold-const.c (fold_single_bit_test): Use result_type for the
+ result when folding a sign bit test.
+
+2003-07-04 Neil Booth <neil@daikokuya.co.uk>
+
+ * opts.c (common_handle_options): Negate sense of -falign- switches.
+
+2003-07-04 H.J. Lu <hongjiu.lu@intel.com>
+
+ * Makefile.in: Replace PWD with PWD_COMMAND.
+
+2003-07-04 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopanal.c (count_strange_loop_iterations): New static function.
+ (constant_iterations, count_loop_iterations, simple_loop_exit_p):
+ Handle strange loops.
+
+2003-07-04 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * install.texi: Even the g77 manpage is derived from
+ the full g77 manual.
+
+2003-07-04 Zack Weinberg <zack@codesourcery.com>
+
+ * ABOUT-NLS: Delete.
+ * intl: Delete entire directory.
+ * aclocal.m4: Include ../config/gettext.m4. Delete
+ AC_ISC_POSIX, AM_LANGINFO_CODESET, jm_GLIBC21, AM_LC_MESSAGES,
+ AM_PATH_PROG_WITH_TEST, AM_WITH_NLS, and AM_GNU_GETTEXT.
+ * configure.in: Use CY_GNU_GETTEXT, not AM_GNU_GETTEXT.
+ Remove intl/Makefile from all_outputs.
+ * configure, config.in: Regenerate.
+ * Makefile.in: Expunge all references to intl subdirectory.
+ Add -I../intl to INCLUDES.
+ * intl.h: Include libintl.h if and only if ENABLE_NLS is defined.
+
+2003-07-04 Roger Sayle <roger@eyesopen.com>
+
+ * config/rs6000/aix51.h (TARGET_C99_FUNCTIONS): Define.
+ * config/rs6000/aix52.h (TARGET_C99_FUNCTIONS): Likewise.
+
+2003-07-04 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c++/5287, PR c++/7910, PR c++/11021
+ * config/i386/winnt.c (ix86_handle_dll_attribute): Don't add
+ dllimport attribute if function is defined at declaration, but
+ report error instead. Likewise for dllimport'd variable
+ definitions. Set implicit TREE_PUBLIC for dllimport'd variables
+ declared within functions, Report error if dllimport or dllexport
+ symbol is not global.
+ (i386_pe_dllimport_p): Ignore dllimport attribute of functions
+ if defined after declaration or if inlined. Don't allow definition
+ of static data members of C++ classes. Don't dllimport virtual
+ methods.
+ (i386_pe_mark_dllexport): Warn about inconsistent dll attributes.
+ (i386_pe_mark_dllimport): Remove unnecessary checks.
+ (i386_pe_encode_section_info): Warn if the dllimport attribute
+ and symbol prefix have been instantiated and then overridden.
+
+ * doc/extend.texi: Document dllimport and dllexport attributes.
+
+ * config/i386/winnt.c (i386_pe_output_labelref): Fix indents.
+
+2003-07-03 Uwe Stieber <uwe@kaos-group.de>
+
+ * config/kaos.h (CPP_PREDEFINES): Delete.
+ (TARGET_OS_CPP_BUILTINS): New.
+
+2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-aux-info.c: Include toplev.h after c-tree.h.
+ * c-common.c: Likewise.
+ (GCC_DIAG_STYLE): Undef.
+ * c-semantics.c (GCC_DIAG_STYLE): Define.
+ * c-tree.h (GCC_DIAG_STYLE): Likewise.
+ * diagnostic.h (inform): Move prototype to toplev.h.
+ * jump.c: Include diagnostic.h before toplev.h.
+ * toplev.h (GCC_DIAG_STYLE, ATTRIBUTE_GCC_DIAG): Define.
+ (warning, error, fatal_error, pedwarn, sorry, inform,
+ error_for_asm, warning_for_asm): Mark with ATTRIBUTE_GCC_CXXDIAG.
+
+2003-07-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfglayout.c (cfg_layout_duplicate_bb): Do not update frequencies
+ at all if edge is not specified.
+ (can_copy_bbs_p, copy_bbs): New.
+ * cfglayout.h (can_copy_bbs_p, copy_bbs): Declare.
+ * cfgloop.c (get_loop_body): Comment more precisely.
+ * cfgloopmanip.c (copy_bbs, record_exit_edges): Removed.
+ (scale_bbs_frequencies): Fix comment typo.
+ (can_duplicate_loop_p): Use can_copy_bbs_p.
+ (duplicate_loop_to_header_edge): Simplify by using copy_bbs.
+
+2003-07-03 Devang Patel <dpatel@apple.com>
+
+ * c-opts.c (c_common_parse_file): Remove extra
+ debug_hooks->start_source_file call.
+
+2003-07-03 Roger Sayle <roger@eyesopen.com>
+
+ * real.c (real_trunc, real_floor, real_ceil): New functions
+ to implement trunc, floor and ceil respectively.
+ * real.h (real_trunc, real_floor, real_ceil): Prototype here.
+ * builtins.c (integer_valued_real_p): New function to test if
+ a floating point expression has an integer valued result.
+ (fold_trunc_transparent_mathfn): Optimize foo(foo(x)) as
+ foo(x) where foo is an integer rounding function. Similarly,
+ optimize foo(bar(x)) as bar(x), and foo((double)(int)x) as
+ (double)(int)x when both foo and bar are integer rounding
+ functions and we don't need to honor errno.
+ (fold_builtin_trunc, fold_builtin_floor, fold_builtin_ceil):
+ New functions to fold trunc, floor and ceil.
+ (fold_builtin): Use fold_builtin_trunc to fold BUILT_IN_TRUNC*,
+ fold_builtin_floor to fold BUILT_IN_FLOOR* and fold_builtin_ceil
+ to fold BUILT_IN_CEIL*.
+ * fold-const.c (tree_expr_nonnegative_p): Handle FLOAT_EXPR and
+ the remaining integer rounding functions.
+
+2003-07-03 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (function_arg_partial_nregs): Use
+ SPARC_INT_ARG_MAX to determine where to split unnamed
+ complex FP arguments.
+
+2003-07-03 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h (create_basic_block, merge_blocks_nomove): Kill.
+ * cfgcleanup.c (merge_blocks): Rename to merge_blocks_move.
+ (merge_blocks_move_predecessor_nojumps,
+ merge_blocks_move_successor_nojumps): Use merge_blocks.
+ (try_optimize_cfg): Use merge_blocks_move.
+ * cfgrtl.c (create_basic_block): Rename to rtl_create_basic_block.
+ (merge_blocks_nomove): Rename to rtl_merge_blocks.
+ (cfg_layout_create_basic_block): New.
+ (rtl_can_merge_blocks): New.
+ (cfg_layout_split_block): Do not alloc aux by hand.
+ * cfghooks.h (cfg_hooks): Add create_basic_block, can_merge_blocks_p,
+ merge_blocks.
+ (create_basic_block, can_merge_blocks_p, merge_blocks): New macros.
+ * cfglayout.c (cfg_layout_duplicate_bb): Do not allocate aux by hand.
+ * cfgloopmanip.c (loop_split_edge_with): Likewise.
+ * ifcvt.c (merge_if_block): Use merge_blocks_nomove.
+
+ * basic-block.h (basic_block_def): Add field 'rbi'.
+ * bb-reorder.c (find_traces, rotate_loop, mark_bb_visited,
+ find_traces_1_round, copy_bb, connect_traces): Update use of rbi.
+ * cfg.c (entry_exit_blocks): Add new field.
+ * cfglayout.c: Include alloc-pool.h;
+ (cfg_layout_pool): New.
+ (record_effective_endpoints, fixup_reorder_chain,
+ fixup_fallthru_exit_predecessor, cfg_layout_duplicate_bb): Update use
+ of rbi.
+ (cfg_layout_initialize_rbi): New function.
+ (cfg_layout_initialize): Use it.
+ (cfg_layout_finalize): Clear rbi fields.
+ * cfglayout.h (RBI): Kill.
+ (cfg_layout_initialize_rbi): Declare.
+ * cfgloopmanip.c (copy_bbs): Use rbi.
+ (record_exit_edges): Likewise.
+ (duplicate_loop_to_header_edge): Likewise.
+ * cfgrtl.c (cfg_layout_create_basic_block): Use
+ cfg_layout_initialize_rbi.
+ (cfg_layout_split_block): Use rbi.
+ (cfg_layout_delete_block): Likewise.
+ * loop-init.c (loop_optimizer_finalize): Likewise.
+ * loop-unswitch.c (unswitch_loop): Likewise.
+ * tracer.c (seen, tail_duplicate, layout_superblocks): Likewise.
+
+ * cfgrtl.c: Update comments.
+ (try_redirect_by_replacing_jump): New argument.
+ (redirect_branch_edge): Break out from ...
+ (rtl_redirect_edge_and_branch): ... this one.
+ (update_cfg_after_block_merging): Break out from ...
+ (rtl_merge_blocks): ... this one.
+ (cfg_layout_split_edge): New.
+ (cfg_layout_merge_blocks): New.
+ (cfg_layout_can_merge_blocks_p): New.
+ (cfg_layout_redirect_edge_and_branch): Reorganize.
+ (cfg_layout_rtl_cfg_hooks): Fill in.
+ (cfg_layout_delete_block): Kill barriers.
+ * cfganal.c (can_fallthru): Deal with exit blocks
+ * cfglayout.c (cfg_layout_function_header): New function
+ (record_effective_endpoints): Record function header.
+ (fixup_reorder_chain): Fixup dead jumptables; place header
+
+ * basic-block.h (CLEANUP_CFGLAYOUT): New flag.
+ * bb-reorder.c (cfg_layout_initialize): Update call.
+ * cfgcleanup.c (try_optimize_cfg): Supress optimizations of fallthru
+ edges in cfglayout mode.
+ * cfglayout.c (cleanup_unconditional_jumps): Kill.
+ (cfg_layout_initialize): Kill agrument loops; use cfgcleanup.
+ * cfglayout.h (cfg_layout_initialize): Update prototype.
+ * cfgloop.h (CP_INSIDE_CFGLAYOUT): Kill.
+ * cfgloopmanip.c (loop_split_edge_with): Use split_edge.
+ * flow.c (propagate_block): Do not crash when basic block ends
+ by first insn in the chain.
+ * loop-init.c (loop_optimizer_init): First enter cfglayout mode; later
+ do loop discovery.
+ * tracer.c (tracer): Update call of cfg_layout_initialize.
+
+2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in: Use dependency variables in lieu of explicit
+ files throughout.
+
+2003-07-03 Steven Bosscher <steven@gcc.gnu.org>
+
+ * rtl.h (ECF_*, flags_from_decl_or_type): Move from here...
+ * tree.h: ...to here.
+
+2003-07-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/s390/2064.md: Fix comment typos.
+ * config/s390/2084.md: Likewise.
+ * config/s390/s390.c: Likewise.
+ * config/s390/s390.md: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/sh/sh.h: Likewise.
+ * config/sh/sh.md: Likewise.
+ * config/sparc/sparc.c: Likewise.
+ * config/sparc/sparc.h: Likewise.
+ * config/sparc/sparc.md: Likewise.
+ * config/stormy16/stormy16.c: Likewise.
+ * config/stormy16/stormy16.h: Likewise.
+ * config/stormy16/stormy-abi: Fix a typo.
+
+2003-07-03 Kelley Cook <kelleycook@wideopenwest.org>
+
+ * Makefile.in (ifcvt.o): Depend on OPTABS_H.
+
+2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/mips/mips.h (save_argv): Delete.
+
+2003-07-03 Roger Sayle <roger@eyesopen.com>
+
+ PR target/10700
+ * fold-const.c (extract_muldiv_1): There's nothing that can be done
+ if the expression is a SAVE_EXPR.
+
+2003-07-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.c: Fix comment typos.
+ * config/m68hc11/m68hc11.c: Likewise.
+ * config/m68hc11/m68hc11.h: Likewise.
+ * config/m68k/m68k.c: Likewise.
+ * config/mcore/mcore.c: Likewise.
+ * config/mcore/mcore.h: Likewise.
+ * config/mcore/mcore.md: Likewise.
+ * config/mips/mips.c: Likewise.
+ * config/mips/mips.h: Likewise.
+ * config/mips/mips.md: Likewise.
+ * config/mips/netbsd.h: Likewise.
+ * config/mn10300/mn10300.c: Likewise.
+
+2003-07-03 Andreas Schwab <schwab@suse.de>
+
+ * dbxout.c (pending_bincls): Move decl down inside
+ DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO section.
+
+2003-07-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtl.h (NOTE_DATA): Refer to whole union.
+ * emit-rtl.c (emit_note): Use memset to clear NOTE_DATA.
+
+2003-07-03 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11381
+ * simplify-rtx.c (simplify_relational_operation): Check that
+ two equal operands have no side-effects before simplifying
+ the comparison.
+
+2003-07-02 Jeff Law <law@redhat.com>
+
+ * expr.c (do_store_flag): Remove special case folding for
+ single bit tests. Instead call back into the commonized folder
+ routine.
+ * fold-const.c (fold_single_bit_test): New function, mostly
+ extracted from do_store_flag, with an additional case extracted
+ from fold.
+ (fold): Call fold_single_bit_test appropriately.
+ * tree.h (fold_single_bit_test): Prototype.
+
+2003-07-02 Zack Weinberg <zack@codesourcery.com>
+
+ * system.h: Include filenames.h.
+ (IS_DIR_SEPARATOR, IS_ABSOLUTE_PATHNAME): Don't define.
+ (DIR_SEPARATOR, DIR_SEPARATOR_2): If not already defined,
+ define based on HAVE_DOS_BASED_FILE_SYSTEM.
+ * config/i386/xm-cygwin.h, config/i386/xm-djgpp.h
+ * config/i386/xm-mingw32.h: Don't define
+ HAVE_DOS_BASED_FILE_SYSTEM,
+ DIR_SEPARATOR, or DIR_SEPARATOR_2.
+ * doc/hostconfig.texi: Update to match.
+
+ * cppfiles.c, gcc.c, gensupport.c, protoize.c,
+ config/i386/cygwin.h:
+ Use IS_ABSOLUTE_PATH throughout.
+ * gcc.c (DIR_UP): Delete, unused.
+ * protoize.c (IS_SAME_PATH): Define in terms of
+ FILENAME_CMP.
+ (is_abspath): Delete.
+
+2003-07-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/emmintrin.h: Fix comment typos.
+ * config/i386/i386.c: Likewise.
+ * config/i386/i386.h: Likewise.
+ * config/i386/sco5.h: Likewise.
+ * config/ia64/ia64.c: Likewise.
+ * config/ia64/itanium2.md: Likewise.
+
+2003-07-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * dbxout.c (pending_bincls): Replace DBX_USE_BINCLS with
+ DBX_USE_BINCL.
+ (emit_bincl_stab): Same.
+ (emit_pending_bincls): Same.
+
+2003-07-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (compute_mov_length): Fix the length of
+ loading CONST0_RTX (SFmode).
+ * config/h8300/h8300.h (CONST_DOUBLE_OK_FOR_LETTER_P): Change
+ 'G' to CONST0_RTX (SFmode).
+ * config/h8300/h8300.md (movsf_h8300): Change the first
+ constraint to 'G'.
+ (movsf_h8300h): Likewise.
+
+2003-07-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.h (c_common_init_options): New prototype.
+ * c-opts.c (deferred_size): Remove.
+ (defer_opt): Array is now pre-allocated.
+ (c_common_init_options): Pre-allocate deferred_opts. Make
+ lang_flags unsigned.
+ (push_command_line_options): Free deferred_opts.
+ * hooks.c (hook_uint_uint_constcharptrptr_0): New.
+ * hooks.h (hook_uint_uint_constcharptrptr_0): New.
+ * langhooks-def.h (LANG_HOOKS_INIT_OPTIONS): Update.
+ * langhooks.h (struct lang_hooks): New prototype for init_options.
+ * main.c (main): Cast argv.
+ * opts.c (handle_option, handle_options): Update prototypes.
+ (decode_options): save_argc, save_argv are not global. Constify.
+ * opts.h (decode_options): New prototype.
+ * toplev.c (general_init): New protoype.
+ (save_argv): Make static.
+ (save_argc): Remove.
+ (print_switch_values, general_init): Constify.
+ (toplev_main): Save argv.
+ * toplev.h (toplev_main): Update prototype.
+ (save_argc, save_argv): Remove.
+
+2003-07-02 David Edelsohn <edelsohn@gnu.org>
+
+ * dbxout.c (pending_bincls): Guard with DBX_USE_BINCLS.
+ (emit_bincl_stab): Same.
+ (emit_pending_bincls): Same.
+
+2003-07-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11072
+ * ginclude/stddef.h (offsetof): Remove cast to 'char &'. Explain why.
+
+2003-07-02 Andreas Schwab <schwab@suse.de>
+
+ * dbxout.c (pending_bincls): Only define if DBX_DEBUGGING_INFO.
+
+2003-07-02 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11210
+ * expr.c (handled_component_p) [NOP_EXPR]: Add ??? note
+ about the behaviour with regard to bitfields.
+ * fold-const (decode_field_reference): Record outermost type in
+ case the expression is a NOP. Strip all NOPs. Set the signedness
+ to that of the outermost type (if any) when the bitsize is equal
+ to the size of the type.
+
+2003-07-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (addsi3): Remove workaround for adds of -32768.
+ (addsi3_internal, adddi3, adddi3_internal_2): Likewise.
+ (adddi3_internal_3, addsi3_internal_2): Likewise.
+
+2003-07-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (machine_function): Add new fields:
+ ignore_hazard_length_p and all_noreorder_p.
+ (mips_flag_delayed_branch): New variable.
+ (override_options): Treat '/' as an operand punctuation character.
+ Set up mips_flag_delayed_branch.
+ (print_operand): Handle '/'.
+ (mips_output_function_prologue): Put the whole function in
+ .set noreorder and .set nomacro if all_noreorder_p is true.
+ (mips_output_function_epilogue): End the noreorder/nomacro sequence.
+ (mips16_optimize_gp): Remove "first insn" parameter.
+ (mips16_lay_out_constants): New function, split out from mips_reorg.
+ (mips_avoid_hazard, mips_avoid_hazards): New functions.
+ (mips_reorg): For mips16 code, call mips16_lay_out_constant
+ and (optionally) mips16_optimize. If TARGET_EXPLICIT_RELOCS,
+ do delayed-branch scheduling followed by hazard detection.
+ (mips_adjust_insn_length): Only account for hazards if
+ !ignore_hazard_length_p.
+ (mips_output_load_label): Add a nop to the o32 sequence if
+ the target suffers from load delays.
+ (mips_output_conditional_branch): Add %/ to the end of branches.
+ (mips_output_division): Fill the branch delay slot with %#.
+ * config/mips/mips.md: Remove redundant '%*' from mips16 branch
+ instructions. End all other %* branches with %/.
+ (ffssi2, ffsdi2): Fix lengths.
+ (truncdisi2, truncdihi2, truncdiqi2): Add store attributes.
+ (fix_truncdfsi2_macro): Turn off .set nomacro if appropriate.
+ (fix_truncsfsi2_macro): Likewise.
+ (mov_lwl): Set hazard to "none".
+ (ashldi3_internal): Fill the branch delay slot with %#.
+ (ashrdi3_internal, lshrdi3_internal): Likewise.
+ (exception_receiver): Explicitly set $28.
+ (hazard_nop): New pattern.
+
+2003-07-02 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_finalize_unit): Set current_function_decl
+ before calling tree_inlinable_function_p.
+
+2003-07-02 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * fixinc/inclhack.def (irix_stdio_va_list): Apply to IRIX 6.5
+ <internal/stdio_core.h> too.
+ (stdio_va_list): Apply to IRIX 6.5 <internal/stdio_core.h> and
+ <internal/wchar_core.h> too.
+ Substitute va_list uses in inline definition.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-07-02 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/iris5.h (SET_FILE_NUMBER): Moved here from iris3.h.
+ Undef before redefinition.
+ (LABEL_AFTER_LOC): Likewise.
+ (DEFAULT_SIGNED_CHAR): Likewise.
+ (ASM_OUTPUT_ASCII): Moved here from iris4.h.
+ Fix IRIX spelling.
+
+ * config/mips/iris3.h: Remove, unused.
+ * config/mips/iris4.h: Likewise.
+
+ * config/mips/mips.h (STACK_ARGS_ADJUST): Remove, unused.
+
+ * config/mips/iris5.h (TARGET_DEFAULT): Move ...
+ * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix5*): ... here to
+ target_cpu_default.
+
+ * config/mips/iris5.h: Move explicit includes ...
+ * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix5*): ... here.
+
+ * config/mips/iris6.h (MIPS_ISA_DEFAULT, MIPS_ABI_DEFAULT): Move ...
+ * config.gcc (mips-sgi-irix6*, mips-sgi-irix5cross64): ... here to
+ tm_defines.
+
+ * config/mips/iris6.h (TARGET_DEFAULT): Move ...
+ * config.gcc (mips-sgi-irix6*, mips-sgi-irix5cross64): ... here to
+ target_cpu_default.
+
+ * config/mips/iris6.h: Fix IRIX spelling.
+ (MULTILIB_DEFAULTS): Undef before redefinition.
+
+ * config/mips/iris6.h: Move explicit includes ...
+ * config.gcc (mips-sgi-irix6*, mips-sgi-irix5cross64): ... here.
+
+2003-07-02 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_mark_needed_node, cgraph_varpool_mark_needed_node,
+ cgraph_varpool_finalize_decl, cgraph_varpool_assemble_pending_decls):
+ Use next_needed field instead of aux to maintain the queue.
+ * cgraph.h (cgraph_node): Add next_needed.
+ (cgraph_varpool_node): Add next_needed; remove aux.
+ * cgraphunit.c (cgraph_finalize_compilation_unit): Use next_needed.
+
+2003-07-02 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_finalize_function): Set finalized.
+ (cgraph_finalize_function): Do not examine inlinablility.
+ (cgraph_finalize_compilation_unit): Do it here.
+ * cgraph.h (cgraph_local_info): Add finalized field.
+
+2003-07-02 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * ggc-common.c (gt_pch_save): Cast MAP_FAILED to void *.
+ (gt_pch_restore): Likewise.
+
+2003-07-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.c: Fix comment typos.
+ * config/alpha/elf.h: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/arm/arm.h: Likewise.
+ * config/arm/arm.md: Likewise.
+ * config/arm/t-arm-coff: Likewise.
+ * config/arm/t-strongarm-pe: Likewise.
+ * config/arm/xscale-elf.h: Likewise.
+ * config/avr/avr.h: Likewise.
+
+2003-07-01 Jeff Law <law@redhat.com>
+
+ * stmt.c (any_pending_cleanups): Remove another redundant test.
+
+2003-07-01 David Edelsohn <edelsohn@gnu.org>
+ J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/rs6000/rs6000.md (ctr{s,d}i_internal?): Add earlyclobber
+ for MEM case.
+
+2003-07-01 Devang Patel <dpatel@apple.com>
+
+ * dbxout.c (DBXOUT_DECR_NESTING): Emit pending bincls, if required.
+ (binclstatus): New.
+ (struct dbx_file): New members - bincl_status, pending_bincl_name and
+ prev.
+ (pending_bincls): New.
+ (dbxout_init): Initialize new dbx_file members.
+ (dbxout_start_source_file): Same.
+ (emit_bincl_stab): New function.
+ (emit_pending_bincls): Same.
+ (emit_pending_bincls_if_required): Same.
+ (dbxout_end_source_file): Emit EINCL stab only if BINCL is already
+ processed.
+ (dbxout_begin_block): Emit pending BINCL stabs.
+ (dbxout_end_block): Same.
+ (dbxout_function_decl): Same.
+ (dbxout_continue): Same.
+ (dbxout_type): Same.
+ (dbxout_class_name_qualifiers): Same.
+ (dbxout_symbol): Same.
+ (dbxout_symbol_location): Same.
+ (dbxout_parms): Same.
+
+2003-07-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-semantics.c (genrtl_case_label): Fix format specifier bug.
+ * cfgrtl.c (rtl_verify_flow_info_1): Likewise.
+
+2003-07-01 Andreas Jaeger <aj@suse.de>
+
+ * fold-const.c: Convert prototypes to ISO C90.
+ * function.c: Likewise.
+ * function.h: Likewise.
+
+2003-07-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/contrib.texi: Fix typos.
+ * doc/invoke.texi: Likewise.
+ * doc/passes.texi: Likewise.
+ * doc/sourcebuild.texi: Likewise.
+ * doc/tm.texi: Likewise.
+
+2003-07-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * basic-block.h: Fix comment typos.
+ * bb-reorder.c: Likewise.
+ * c-format.c: Likewise.
+ * cfgcleanup.c: Likewise.
+ * cfghooks.h: Likewise.
+ * cfgloop.c: Likewise.
+ * cfgloopmanip.c: Likewise.
+ * cfgrtl.c: Likewise.
+ * cgraph.h: Likewise.
+ * cgraphunit.c: Likewise.
+ * combine.c: Likewise.
+ * convert.c: Likewise.
+ * dbxout.c: Likewise.
+ * df.c: Likewise.
+ * df.h: Likewise.
+ * diagnostic.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * et-forest.h: Likewise.
+ * flow.c: Likewise.
+ * fold-const.c: Likewise.
+ * function.h: Likewise.
+ * gcov-io.h: Likewise.
+ * gcov.c: Likewise.
+ * gcse.c: Likewise.
+ * genautomata.c: Likewise.
+ * ggc-common.c: Likewise.
+ * ggc-page.c: Likewise.
+ * loop-unroll.c: Likewise.
+ * loop-unswitch.c: Likewise.
+ * loop.c: Likewise.
+ * mips-tfile.c: Likewise.
+ * optabs.c: Likewise.
+ * ra-build.c: Likewise.
+ * ra-colorize.c: Likewise.
+ * ra-rewrite.c: Likewise.
+ * ra.h: Likewise.
+ * regmove.c: Likewise.
+ * reload.c: Likewise.
+ * rtlanal.c: Likewise.
+ * sched-ebb.c: Likewise.
+ * sched-int.h: Likewise.
+ * sched-vis.c: Likewise.
+ * sreal.c: Likewise.
+ * ssa-ccp.c: Likewise.
+ * ssa.c: Likewise.
+ * toplev.c: Likewise.
+ * tree-inline.c: Likewise.
+ * value-prof.c: Likewise.
+ * value-prof.h: Likewise.
+
+2003-07-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtl.h (emit_line_note_after): Remove.
+ (emit_note_copy_after, emit_note_copy): New.
+ * emit-rtl.c (reorder_insns_with_line_notes): Replace
+ emit_line_note_after with emit_note_copy_after.
+ (emit_insn_after_with_line_notes): Likewise.
+ (emit_line_note_after): Kill.
+ (emit_note_copy_after): New.
+ (emit_note_copy): New.
+ * function.c (emit_return_into_block): Use emit_note_copy_after.
+ (thread_prologue_and_epilogue_insns): Likewise.
+ * integrate.c (expand_inline_function): Use emit_note_copy.
+ (copy_insn_list): Likewise.
+ * unroll.c (copy_loop_body): Likewise.
+ * cfglayout.c (duplicate_insn_chain): Likewise.
+
+2003-07-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-tree.h (define_label): Replace filename and lineno arguments
+ with a location_t.
+ * c-decl.c (poplevel): Adjust define_label call.
+ (pop_label_level): Likewise.
+ (define_label): Replace filename and lineno arguments with a
+ location_t.
+ (store_parm_decls): Use DECL_SOURCE_LOCATION.
+ * c-parse.in (label): Adjust define_label call.
+
+2003-07-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/sol2.h, config/alpha/alpha.h, config/alpha/linux.h,
+ config/i386/i386-interix.h, config/ia64/hpux.h, config/mips/iris6.h,
+ config/mips/linux.h, config/mips/mips.h, config/pa/pa-hpux.h,
+ config/pa/pa-hpux10.h, config/pa/pa-hpux11.h, config/pa/pa-pro-end.h,
+ config/pa/pa.h, config/pa/rtems.h: Use c_dialect_ macros.
+
+2003-07-01 Andreas Jaeger <aj@suse.de>
+
+ * final.c: Convert prototypes to ISO C90.
+ * flow.c: Likewise.
+ * flags.h: Likewise.
+ * gcov-io.c: Likewise.
+ * gcov-io.h: Likewise.
+
+See ChangeLog.9 for earlier changes.
diff --git a/contrib/gcc/ChangeLog.2 b/contrib/gcc/ChangeLog.2
index a7cff363cd6c..39b4f3a0d613 100644
--- a/contrib/gcc/ChangeLog.2
+++ b/contrib/gcc/ChangeLog.2
@@ -4782,7 +4782,7 @@ Tue Oct 19 15:26:11 1999 Richard Earnshaw (rearnsha@arm.com)
Tue Oct 19 14:01:34 1999 Nick Clifton <nickc@cygnus.com>
* toplev.c (main): Do not generate an error message if an
- unrecognized command line switch is recognisable by another
+ unrecognized command line switch is recognizable by another
language. If extra_warnings are enabled, then generate a
warning message instead.
@@ -10733,7 +10733,7 @@ Thu Aug 19 11:51:22 EDT 1999 John Wehle (john@feith.com)
Thu Aug 19 15:02:01 1999 Nick Clifton <nickc@cygnus.com>
* config/rs6000/rs6000.c (rs6000_override_options): Fix test for
- unrecognisable switches.
+ unrecognizable switches.
Wed Aug 18 23:31:57 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
@@ -10855,7 +10855,7 @@ Fri Aug 13 15:20:43 1999 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
Fri Aug 13 10:21:28 1999 Nick Clifton <nickc@cygnus.com>
* toplev.c (rest_of_compilation): Allow machine dependent
- reorganisation pass to place information into the RTL dump
+ reorganization pass to place information into the RTL dump
file if it so wishes.
Sun Aug 15 12:41:21 1999 Jim Wilson <wilson@cygnus.com>
diff --git a/contrib/gcc/ChangeLog.3 b/contrib/gcc/ChangeLog.3
index 067d9adb68f8..52df96025fbf 100644
--- a/contrib/gcc/ChangeLog.3
+++ b/contrib/gcc/ChangeLog.3
@@ -6424,7 +6424,7 @@ Mon Apr 17 14:59:36 MET DST 2000 Jan Hubicka <jh@suse.cz>
* i370.c (mvs_add_label): Change spacing for coding conventions.
* i370.h (ASM_OUTPUT_CASE_LABEL): Change to the data CSECT for the
- outputing case vectors.
+ outputting case vectors.
(ASM_OUTPUT_CASE_END): New, put assembler back into code CSECT.
(ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT): Remove page check,
since vector in in the data CSECT.
@@ -14863,9 +14863,9 @@ Mon Jan 24 16:56:10 2000 Jim Wilson <wilson@cygnus.com>
2000-01-24 Richard Henderson <rth@cygnus.com>
- * rtl.def: Add unordered fp comparisions.
+ * rtl.def: Add unordered fp comparisons.
* tree.def: Likewise.
- * tree.h: Add ISO C 9x unordered fp comparision builtins.
+ * tree.h: Add ISO C 9x unordered fp comparison builtins.
* builtins.c (expand_tree_builtin): New function.
* c-typeck.c (build_function_call): Use it.
diff --git a/contrib/gcc/ChangeLog.4 b/contrib/gcc/ChangeLog.4
index ac0f7e0ffd09..25546c471dcc 100644
--- a/contrib/gcc/ChangeLog.4
+++ b/contrib/gcc/ChangeLog.4
@@ -14230,7 +14230,7 @@ Fri Jul 14 10:25:53 2000 Clinton Popetz <cpopetz@cygnus.com>
(cpp_pop_buffer): Use _cpp_pop_file_buffer.
* cpplex.c: Move all prototypes and structure declarations to the
- top of the file. Properly parenthesise some macro arguments.
+ top of the file. Properly parenthesize some macro arguments.
(cpp_scan_line): New function.
(special_symbol [case T_INCLUDE_DEPTH]): Use pfile->include_depth,
don't need to walk up the stack counting.
diff --git a/contrib/gcc/ChangeLog.5 b/contrib/gcc/ChangeLog.5
index 9bd21c1a544f..e5c26cc1cd20 100644
--- a/contrib/gcc/ChangeLog.5
+++ b/contrib/gcc/ChangeLog.5
@@ -3283,7 +3283,7 @@ Sat May 19 18:23:04 2001 Richard Henderson <rth@redhat.com>
* c-parse.in (parm_declarator): Split into
parm_declarator_starttypename and parm_declarator_nostarttypename.
(parm_declarator_starttypename, parm_declarator_nostarttypename):
- New. Allow parenthesised sub-declarators which don't begin with a
+ New. Allow parenthesized sub-declarators which don't begin with a
TYPENAME. Fixes PR c/166.
2001-05-19 Mark Mitchell <mark@codesourcery.com>
diff --git a/contrib/gcc/ChangeLog.6 b/contrib/gcc/ChangeLog.6
index 5618eaa29e2d..8e1510d00937 100644
--- a/contrib/gcc/ChangeLog.6
+++ b/contrib/gcc/ChangeLog.6
@@ -10043,7 +10043,7 @@ Tue Sep 25 17:13:56 CEST 2001 Jan Hubicka <jh@suse.cz>
* config/i386/i386.c (ix86_init_builtins): Correct return type
building v4hi_ftype_v4hi_int_int tree node.
(ix86_expand_sse_comi): Fix typo swapping operands.
- Don't swap comparision condition, it is already swapped.
+ Don't swap comparison condition, it is already swapped.
(ix86_expand_sse_compare): Before swapping operands
move operand 1 into new rtx and not the target rtx.
Don't swap comparison condition, it is already swapped.
@@ -15034,12 +15034,12 @@ Tue Aug 7 14:56:16 CEST 2001 Jan Hubicka <jh@suse.cz>
2001-08-05 Jan Hubicka <jh@suse.cz>
- * Makefile.in (reload1.o): Add dedendancy on except.h
+ * Makefile.in (reload1.o): Add dependency on except.h
* basic-block.h (purge_all_dead_edges, purge_dead_edges): Update
prototypes.
* flow.c (purge_dead_edges, purge_all_dead_edges): Return bool
- indicating wehther edges has been cleaned up.
- * reload1.c: Inlucde except.h
+ indicating whether edges has been cleaned up.
+ * reload1.c: Include except.h.
(fixup_abnormal_edges): Accept deleted insns.
* toplev.c (rest_of_compilation): Purge dead edges unconditionally
after combine.
diff --git a/contrib/gcc/ChangeLog.7 b/contrib/gcc/ChangeLog.7
index dc7282b839c9..f9c6a7dbcb0f 100644
--- a/contrib/gcc/ChangeLog.7
+++ b/contrib/gcc/ChangeLog.7
@@ -8244,7 +8244,7 @@ Wed May 8 11:10:31 CEST 2002 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
Jan Hubicka <jh@suse.cz>
* basic-block.h (note_prediction_to_br_prob): declare.
- * c-semantics.c: Inlucde predit.h
+ * c-semantics.c: Include predit.h
(expand_stmt): predict GOTO_STMT as not taken.
* cfgcleanup.c: (delete_unreachable_blocks): Make global.
(cleanup_cfg): Do not free tail_recursion_list.
@@ -12648,7 +12648,7 @@ Thu Mar 28 16:35:31 2002 Jeffrey A Law (law@redhat.com)
Thu Mar 28 19:13:36 CET 2002 Jan Hubicka <jh@suse.cz>
- * ifcvt.c (if_convert): Clear aux_for_blocks early enought.
+ * ifcvt.c (if_convert): Clear aux_for_blocks early enough.
Thu Mar 28 13:21:53 CET 2002 Jan Hubicka <jh@suse.cz>
diff --git a/contrib/gcc/ChangeLog.8 b/contrib/gcc/ChangeLog.8
new file mode 100644
index 000000000000..37774eebf508
--- /dev/null
+++ b/contrib/gcc/ChangeLog.8
@@ -0,0 +1,14448 @@
+2002-12-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Update the prototypes.
+ * config/h8300/h8300.c (const_le_2_operand): Change to
+ const_int_le_2_operand.
+ (const_int_le_6_operand): Change to const_int_le_6_operand.
+ * config/h8300/h8300.md (two peepholes): Update the function
+ names.
+
+2002-12-31 Tom Tromey <tromey@redhat.com>
+
+ * doc/install.texi (Testing): Fixed typo.
+
+2002-12-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (TRAMPOLINE_TEMPLATE): Remove.
+ (TRAMPOLINE_SIZE): Support the normal mode.
+ (INITIALIZE_TRAMPOLINE): Emit the entire trampoline.
+
+2002-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ * c-common.h (pending_lang_change): Declare.
+
+2002-12-31 Jerry Quinn <jlquinn@optonline.net>
+
+ * gcc/doc/invoke.texi (Optimization Options): Clean up -O flag
+ descriptions.
+
+2002-12-31 Jerry Quinn <jlquinn@optonline.net>
+
+ * gcc/doc/invoke.texi (Optimization Options): List the options
+ enabled by each -O flag.
+
+2002-12-31 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/install.texi (Configuration): Explicitly refer
+ gcc/config.gcc for a list of cpu models.
+
+2002-12-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h: Fix comment typos.
+
+2002-12-30 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.h (WIDEST_HARDWARE_FP_SIZE): Define.
+
+2002-12-30 Tom Tromey <tromey@redhat.com>
+
+ * doc/install.texi (Testing): Mention Jacks.
+
+2002-12-30 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/gcc.texi, doc/gccint.texi: Update last modification dates.
+
+2002-12-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (output_logical_op): Use extu.w in more
+ cases.
+ (compute_logical_op_length): Update to reflect the change in
+ output_logical_op.
+ (compute_logical_op_cc): Likewise.
+
+2002-12-30 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/service.texi: Uncomment and update FAQ link.
+
+2002-12-30 Andreas Jaeger <aj@suse.de>
+
+ * unwind-dw2-fde.h (last_fde): Add unused attribute for obj.
+
+2002-12-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*addsi3_lshiftrt_16_zexthi): New.
+
+2002-12-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (output_logical_op): Use extu.w if we
+ are clearing the most significant byte.
+ (compute_logical_op_length): Update to reflect the change in
+ output_logical_op.
+ (compute_logical_op_cc): Likewise.
+
+2002-12-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Give internal names to anonymous
+ insns.
+
+2002-12-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Reorder some insns.
+
+2002-12-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add prototypes for
+ const_int_qi_operand and const_int_hi_operand.
+ * config/h8300/h8300.c (const_int_qi_operand): New.
+ (const_int_hi_operand): Likewise.
+ * config/h8300/h8300.md (three peepholes): New.
+
+2002-12-28 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/cpp.texi, doc/gcc.texi, doc/gccint.texi, doc/install.texi:
+ Use @copying.
+
+2002-12-28 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * configure.in: Increase makeinfo version requirement to 4.[2-9].
+ * configure: Regenerate.
+ * doc/install.texi: Update Texinfo version requirement.
+
+2002-12-28 Andreas Jaeger <aj@suse.de>
+
+ * config/i386/i386.c (x86_function_profiler): Mark labelno as
+ possibly unused.
+
+ * c-parse.in (yyprint): Use HOST_WIDE_INT_PRINT_DOUBLE_HEX for
+ correct format.
+
+2002-12-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*iorhi_shift_8): Change the name to
+ *iorhi_ashift_8.
+ (*iorhi_lshiftrt_8): New.
+
+2002-12-27 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/include/texinfo.tex: Update to version 2002-12-26.16.
+
+2002-12-27 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/contrib.texi (Contributors): Add Abramo and Roberto Bagnara.
+
+2002-12-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Fix comment typos.
+ Update copyright.
+ * config/h8300/h8300.c: Fix comment typos.
+
+2002-12-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (IDENT_ASM_OP): End with a tab.
+
+2002-12-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/athlon.md: Fix comment typos.
+ * config/i386/crtdll.h: Likewise.
+ * config/i386/djgpp.h: Likewise.
+ * config/i386/i386-interix.h: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/i386/i386.h: Likewise.
+ * config/i386/i386.md: Likewise.
+ * config/i386/k6.md: Likewise.
+ * config/i386/mingw32.h: Likewise.
+ * config/i386/pentium.md: Likewise.
+ * config/i386/sco5.h: Likewise.
+ * config/i386/winnt.c: Likewise.
+ * config/i386/xmmintrin.h: Likewise.
+
+2002-12-26 Jose Renau <renau@cs.uiuc.edu>
+
+ * ssa-dce.c (EXECUTE_IF_UNNECESSARY): Verify INSN is an
+ INSN_P before checking to see if it is dead.
+ (mark_all_insn_unnecessary): Similarly.
+ (ssa_eliminate_dead_code): Similarly.
+ * rtl.h (struct rtx_def): Update comments for in_struct usage
+ in dead code elimination pass.
+ (INSN_DEAD_CODE_P): Allow JUMP_INSN and CALL_INSN as well.
+
+2002-12-26 Andreas Schwab <schwab@suse.de>
+
+ * config.gcc (powerpc*-*-*, rs6000-*-*): Fix assignment syntax.
+
+2002-12-25 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Convert to
+ tartet_flags_explicit.
+ * config/rs6000/rs6000.h (MASK_MULTIPLE_SET, MASK_STRING_SET): Delete.
+ Compact target_flags bits.
+ (TARGET_MULTIPLE_SET, TARGET_STRING_SET): Delete.
+ (TARGET_SWITCHES): Delete references to *_SET flags.
+
+Wed Dec 25 20:30:53 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (memory attribute): Fix setcc attribute.
+
+2002-12-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * output.h: Fix comment typos.
+ * predict.c: Likewise.
+ * print-tree.c: Likewise.
+ * profile.c: Likewise.
+ * ra-build.c: Likewise.
+ * ra-colorize.c: Likewise.
+ * ra-debug.c: Likewise.
+ * ra-rewrite.c: Likewise.
+ * ra.c: Likewise.
+ * ra.h: Likewise.
+ * real.c: Likewise.
+ * recog.c: Likewise.
+ * reg-stack.c: Likewise.
+ * regclass.c: Likewise.
+
+2002-12-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (print_operand_address): Do not negate
+ a negative number when printing one.
+
+2002-12-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add prototypes for
+ output_plussi, compute_plussi_length, and compute_plussi_cc.
+ * config/h8300/h8300.c (output_plussi): New.
+ (compute_plussi_length): Likewise.
+ (compute_plussi_cc): Likewise.
+ * config/h8300/h8300.md (addsi_h8300h): Call
+ output_plussi, compute_plussi_length, and compute_plussi_cc.
+
+2002-12-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (two peepholes): Use match_dup instead
+ of match_operand in the new patterns.
+
+2002-12-24 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/include/texinfo.tex: Update to version 2002-11-25.11.
+
+2002-12-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * configure.in (enable-coverage): Add SELF_COVERAGE.
+ * profile.c (end_branch_prob): Use SELF_COVERAGE.
+
+2002-12-24 Jim Wilson <wilson@redhat.com>
+
+ * alias.c (record_set): Handle multi-reg hard registers.
+
+2002-12-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * regmove.c: Fix comment typos.
+ * reload.c: Likewise.
+ * reload1.c: Likewise.
+ * resource.c: Likewise.
+ * rtl.def: Likewise.
+ * rtl.h: Likewise.
+ * rtlanal.c: Likewise.
+ * sched-deps.c: Likewise.
+ * sched-rgn.c: Likewise.
+ * sibcall.c: Likewise.
+ * simplify-rtx.c: Likewise.
+ * ssa-ccp.c: Likewise.
+ * ssa.c: Likewise.
+ * stmt.c: Likewise.
+ * stor-layout.c: Likewise.
+ * system.h: Likewise.
+ * tlink.c: Likewise.
+ * toplev.c: Likewise.
+ * tracer.c: Likewise.
+ * tree-inline.c: Likewise.
+ * tree.c: Likewise.
+ * tree.h: Likewise.
+ * unroll.c: Likewise.
+ * varasm.c: Likewise.
+
+2002-12-23 Larin Hennessy <larin@science.oregonstate.edu>
+
+ * doc/install.texi: Remove i386-*-isc, i860-*-bsd,
+ m68k-altos-sysv, m68k-isi-bsd, m68k-sony-bsd entries.
+ * doc/invoke.texi: Remove AMD 29K, ARM RISC/iX, Clipper, Convex,
+ DG/UX entries.
+ * doc/md.texi: Remove AMD 29K entries.
+ * doc/trouble.texi: Remove Alliant, DG/UX, Iris 4.0.5F, GAS
+ 1.38.1, NewsOS, RT PC, WE32K entries.
+
+2002-12-23 Aldy Hernandez <aldyh@redhat.com>
+
+ PR/8763
+ * config/rs6000/altivec.md (mulv4sf3): Rewrite to add -0.0 vector.
+ (altivec_vspltisw_v4sf): Name pattern.
+ (altivec_vslw_v4sf): New pattern.
+
+2002-12-23 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/include/gcc-common.texi: Define DEVELOPMENT.
+
+2002-12-23 Mark Mitchell <mark@codesourcery.com>
+
+ * stor-layout.c (update_alignment_for_field): Correct handling of
+ unnamed bitfields on PCC_BITFIELD_TYPE_MATTERS machines.
+ * doc/tm.texi (PCC_BITFIELD_TYPE_MATTERS): Note that an unnamed
+ bitfield does not affect alignment.
+
+2002-12-23 David Edelsohn <edelsohn@gnu.org>
+
+ * expr.c (expand_assignment): Apply special treatment to
+ ARRAY_TYPE.
+
+2002-12-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Update the prototype of
+ expand_a_shift.
+ * config/h8300/h8300.c (expand_a_shift): Change the return
+ type to void.
+ * config/h8300/h8300.md: Update all the uses of
+ expand_a_shift.
+
+2002-12-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (save_expr): Allow either side of a dyadic operand to be
+ constant.
+
+ * doc/portability.texi (portability): Update portability goals.
+
+2002-12-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (output_a_shift): Remove unused code.
+
+2002-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ * stor-layout.c (update_alignment_for_field): Guard use of
+ ADJUST_FIELD_ALIGN with #ifdef.
+
+ * stor-layout.c (update_alignment_for_field): Use
+ ADJUST_FIELD_ALIGN when computing the alignment for a zero-width
+ bitfield when PCC_BITFIELD_TYPE_MATTERS.
+
+2002-12-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genautomata.c: Fix comment typos.
+
+Sun Dec 22 18:23:44 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * params.def (tracer-min-branch-probability-feedback): Fix default.
+ * final.c (compute_alignments): Use profile to avoid code bloat.
+
+2002-12-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (get_shift_alg): Make shift insn
+ sequences end with a valid cc0 whenever possible.
+
+2002-12-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (negsf2): New.
+ (*negsf2_h8300): Likewise.
+ (*negsf2_h8300hs): Likewise.
+
+2002-12-21 Geoffrey Keating <geoffk@apple.com>
+
+ * integrate.c (output_inline_function): Don't hold private
+ pointers to 'struct function' over GC calls.
+
+2002-12-21 Kaz kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/lib1funcs.asm (__fpscr_values): Conditionalize with
+ NO_FPSCR_VALUES.
+ * config/sh/t-linux (TARGET_LIBGCC2_CFLAGS): Add -DNO_FPSCR_VALUES.
+
+2002-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (zero_extendqisi2): Correct the
+ length.
+
+2002-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*zero_extendqihi2_h8300): Make the
+ second alternative "#".
+ (*zero_extendqihi2_h8300hs): Likewise.
+ (a define_split): New.
+
+2002-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Update the prototype for
+ split_adds_subs.
+ Add prototypes for const_le_2_operand and const_le_6_operand.
+ * config/h8300/h8300.c (split_adds_subs): Add an argument to
+ specify whether inc/dec should be used when possible.
+ (const_le_2_operand): New.
+ (const_le_6_operand): Likewise.
+ * config/h8300/h8300.md (two peepholes): New.
+
+2002-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/fr30/fr30.md: Fix a comment typo.
+ * config/i386/i386.c: Likewise.
+ * config/ip2k/ip2k.h: Likewise.
+
+2002-12-20 Jim Wilson <wilson@redhat.com>
+
+ * config/rs6000/spe.h (__ev_subifw): Reverse arguments.
+ (__ev_subw, __ev_subiw): New.
+ (ev_mwlssf, ev_mwlsmf, ev_mwlssfa, ev_mwlsmfa, ev_mwlssfaaw,
+ ev_mwlsmfaaw, ev_mwlssfanw, ev_mwlsmfanw): Delete.
+
+2002-12-20 John David Anglin <dave.anglin@nrc.gc.ca>
+
+ * pa-linux.h (TARGET_HAS_STUBS_AND_ELF_SECTIONS): Delete define.
+ * pa32-linux.h (FUNCTION_OK_FOR_SIBCALL): Delete define.
+ * pa.c (pa_function_ok_for_sibcall): Allow non indirect sibcalls on
+ TARGET_ELF32. Add comment on sibcall issues for TARGET_64BIT.
+
+2002-12-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add prototypes for
+ incdec_operand and eqne_operator.
+ * config/h8300/h8300.c (incdec_operand): New.
+ (eqne_operator): Likewise.
+ * config/h8300/h8300.h (CONST_OK_FOR_M): Likewise.
+ (CONST_OK_FOR_O): Likewise.
+ (CONST_OK_FOR_LETTER_P): Use CONST_OK_FOR_M and
+ CONST_OK_FOR_O.
+ * config/h8300/h8300.md (UNSPEC_INCDEC): New.
+ (addhi3_incdec): New.
+ (addsi3_incdec): Likewise.
+ (two peepholes): Likewise.
+
+2002-12-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (dosize): Remove warnings.
+ (print_operand): Likewise.
+
+2002-12-20 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (decl_has_samegp): New.
+ (samegp_function_operand): Use it. Rename from
+ current_file_function_operand.
+ (direct_call_operand): Handle -msmall-text via symbol->jump.
+ (tls_symbolic_operand_1): Use T for tprel64, t for smaller tprel.
+ (tls_symbolic_operand_type): Likewise.
+ (alpha_encode_section_info): Likewise. Handle -msmall-text.
+ (alpha_function_ok_for_sibcall): Use decl_has_samegp.
+ (alpha_end_function): Set symbol->jump for functions defined in
+ the text section.
+ * config/alpha/alpha-protos.h: Update.
+ * config/alpha/alpha.h (MASK_SMALL_TEXT, TARGET_SMALL_TEXT): New.
+ (TARGET_SWITCHES): Add -msmall-text and -mlarge-text.
+ (PREDICATE_CODES): Update.
+ * config/alpha/alpha.md (call patterns): Update for
+ samegp_function_operand rename; use !samegp reloc if
+ TARGET_EXPLICIT_RELOCS.
+ * doc/invoke.text: Document -msmall-text and -mlarge-text.
+
+2002-12-20 Ian Dall <ian@sibyl.beware.dropbear.id.au>
+
+ * config/ns32k/ns32k.md (movdi): Use "l" instead of "f" to match
+ all registers capable of holding a double float.
+ (*rcond): change name of "reverse branch" insns to
+ something more meaningful.
+ (*rbgt, *rblt, *rbge, *rble): Reverse branches to handle IEEE
+ comparisons properly.
+ (*ffs): Change operand 0 from write to read-modify-write.
+ (*ffsssi2): Drop constraints from define_expand.
+
+ * config/ns32k/ns32k.h (STORE_RATIO, STORE_BY_PIECES): Avoid using
+ MOVE_RATIO as default for store operations.
+
+ * config/ns32k/ns32k.h (enum reg_class, REG_CLASS_NAMES): Add
+ LONG_REGS class.
+ (CANNOT_CHANGE_MODE_CLASS): Can't subreg LONG_REGS.
+ (GO_IF_LEGITIMATE_ADDRESS): Remove spurious abort().
+ * config/ns32k/ns32k.c (regclass_map): Add LONG_REGS class.
+
+ * config/ns32k/STATUS: New File
+ * config/ns32k/NOTES: New file.
+
+2002-12-20 Hartmut Penner <hpenner@de.ibm.com>
+
+ * doc/invoke.texi: Document -mzarch, -mesa, -mcpu= and -march=
+ option for S/390 and zSeries.
+ * config/s390/s390.c (s390_cpu, s390_cpu_string, s390_arch,
+ s390_arch_string): New variables.
+ (override_options): Checking for options and setting of
+ appropriate target_flags, cpu and arch flags.
+ * config/s390/s390.h: (processor_type): New enum.
+ (TARGET_SWITCHES): New switches -mesa/zarch.
+ * config/s390/s390.md: New attribute 'cpu'.
+
+2002-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-pretty-print.h: Fix comment typos.
+ * integrate.c: Likewise.
+ * varasm.c: Likewise.
+ * config/c4x/c4x.h: Likewise.
+ * config/c4x/c4x.md: Likewise.
+ * config/fr30/fr30.md: Likewise.
+ * config/frv/frv.c: Likewise.
+ * config/h8300/h8300.c: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/i386/i386.h: Likewise.
+ * config/ia64/ia64.c: Likewise.
+ * config/ia64/ia64.h: Likewise.
+ * config/ip2k/ip2k.md: Likewise.
+ * config/m68hc11/m68hc11-crt0.S: Likewise.
+ * config/m68hc11/m68hc11.h: Likewise.
+ * config/m68hc11/m68hc11.md: Likewise.
+ * config/m68hc11/m68hc12.h: Likewise.
+ * config/mcore/mcore.md: Likewise.
+ * config/mips/mips.c: Likewise.
+ * config/mips/mips.md: Likewise.
+ * config/mmix/mmix-modes.def: Likewise.
+ * config/pa/pa.c: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/rs6000/rs6000.h: Likewise.
+ * config/rs6000/rs6000.md: Likewise.
+
+2002-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (output_a_shift): Clean up the code to
+ output shifts using rotation.
+
+2002-12-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * flow.c (allocate_reg_life_data): Reset REG_FREQ.
+
+2002-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (pushqi_h8300): Don't push the stack
+ pointer.
+ (pushqi_h8300hs): Likewise.
+ (pushhi_h8300): Likewise.
+ (pushhi_h8300hs): Likewise.
+
+Thu Dec 19 23:44:09 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sched-rgn.c (init_regions): Update comment.
+
+2002-12-19 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (define_attr type): Remove altivec.
+ * config/rs6000/altivec.md (movv4si_internal): Set correct instruction
+ attributes.
+ (movv8hi_internal,movv16qi_internal,movv4sf_internal): Same.
+ (get_vrsave_internal,set_vrsave_internal): Same.
+ (altivec_vspltisb,altivec_vspltish,altivec_vspltisw): Same.
+ (absv16qi2,absv8hi2,absv4si2,absv4sf2): Same
+ (altivec_abss_v16qi,altivec_abss_v8hi,altivec_abss_v4si): Same.
+
+2002-12-19 Casper S. Hornstrup <chorns@users.sourceforge.net>
+ Danny Smith <dannysmith@users.sourceforge.net>
+ Eric Kohl <ekohl@rz-online.de>
+
+ * config/i386/i386.c (ix86_handle_cdecl_attribute): Check for
+ attributes incompatible with fastcall attribute.
+ (ix86_handle_regparm_attribute): Likewise.
+
+ * config/i386/i386.c (ix86_comp_type_attributes): Check for mismatched
+ fastcall types.
+
+ * config/i386/cygwin.h (TARGET_OS_CPP_BUILTINS): Add fastcall
+ attributes.
+ (ASM_OUTPUT_LABELREF): Define as i386_pe_output_labelref.
+ * config/i386/i386-protos.h (i386_pe_output_labelref): Declare.
+ * config/i386/winnt.c (i386_pe_mark_dllimport). Add __imp_ prefix in
+ i386_pe_output_labelref rather than here.
+ (gen_fastcall_suffix): New function. Decorates a label name with the
+ fastcall prefix (@) and the stdcall suffix.
+ (i386_pe_encode_section_info): Call gen_fastcall_suffix() if a symbol
+ has a fastcall attribute.
+ (i386_pe_output_labelref): New function. Outputs a label reference.
+ * config/i386/i386.c (ix86_attribute_table): Accept 'fastcall' as a
+ valid attribute.
+ (ix86_return_pops_args): Fastcall functions pop the stack.
+ (init_cumulative_args): Reserve registers ECX and EDX if function has
+ fastcall attribute.
+ (function_arg): Use registers ECX and EDX if function has fastcall
+ attribute.
+ * config/i386/i386.h (CUMULATIVE_ARGS): Add fastcall attribute flag.
+ (DLL_IMPORT_EXPORT_PREFIX): Redefine as '#'.
+ (FASTCALL_PREFIX): Define as '@'.
+ * config/i386/mingw32.h (TARGET_OS_CPP_BUILTINS): Add fastcall
+ attributes.
+ * doc/extend.texi: Add documentation of fastcall attribute.
+
+2002-12-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: FORBUILD when build!=host changed from
+ ../$build-alias to ../build-$build_alias to match change made
+ in top directory.
+ * configure: Regenerated.
+
+2002-12-19 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/8988
+ * loop.c (maybe_eliminate_biv): Kill REG_EQUAL notes mentioning
+ the biv when eliminating.
+
+2002-12-19 Devang Patel <dpatel@apple.com>
+ * gcc.c (struct default_compiler): Recognizes input file name with
+ .CPP extension as C++ source files
+ * cp/lang-spec.h: Same
+ * doc/invoke.texi: Add documentation for .CPP support.
+
+2002-12-19 Aldy Hernandez <aldyh@redhat.com>
+
+ PR 8553
+ * config/rs6000/altivec.md ("absv8hi2"): Add & to clobbered
+ registers.
+ ("absv16qi2"): Same.
+ ("absv4si2"): Same.
+ ("absv4sf2"): Same.
+ ("altivec_abss_v16qi"): Same.
+ ("altivec_abss_v8hi"): Same.
+ ("altivec_abss_v4si"): Same.
+
+2002-12-19 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*tsthiCCT", "*tsthiCCT_cconly",
+ "*tstqiCCT", "*tstqiCCT_cconly"): New insns.
+
+2002-12-19 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/8340
+ * stmt.c (expand_asm_operands): Produce an error when
+ the PIC register is clobbered.
+
+2002-12-18 Daniel Berlin <dberlin@dberlin.org>
+
+ * Makefile.in (OBJS): Add alloc-pool.o
+ (alloc-pool.o): New object.
+
+ * alloc-pool.c: New file.
+ * alloc-pool.h: New file.
+
+2002-12-18 Loren James Rittle <ljrittle@acm.org>
+
+ * gcc.c (validate_switches): Robustify against skipping past '\0'.
+
+2002-12-18 Geoffrey Keating <geoffk@apple.com>
+
+ * config.gcc: Set extra_objs in the generic Darwin rule,
+ not in the machine-specific rules.
+
+2002-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.2: Likewise.
+ * ChangeLog.4: Likewise.
+ * ChangeLog.5: Likewise.
+ * cppexp.c: Likewise.
+ * df.c: Likewise.
+ * gcov.c: Likewise.
+ * gengtype.c: Likewise.
+ * reload1.c: Likewise.
+ * sched-rgn.c: Likewise.
+ * stmt.c: Likewise.
+ * stor-layout.c: Likewise.
+ * timevar.c: Likewise.
+ * toplev.c: Likewise.
+ * tree.h: Likewise.
+ * varasm.c: Likewise.
+ * config/fr30/fr30.md: Likewise.
+ * config/i386/i386.c: Likewise.
+ * config/ia64/ia64.c: Likewise.
+ * config/pa/pa.c: Likewise.
+
+2002-12-18 Roger Sayle <roger@eyesopen.com>
+
+ * basic-block.h (flow_bb_inside_loop_p): Correct prototype.
+
+2002-12-18 Aldy Hernandez <aldyh@redhat.com>
+
+ PR 8551
+ * config/rs6000/altivec.h (vec_cmplt macro): Reverse arguments in
+ macro.
+ (vec_cmplt C++ functions): Reverse arguments.
+
+2002-12-18 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/t-rs6000: Move contents to t-fprules,
+ add rules for dependencies of rs6000.o and to build rs6000-c.o
+ * config/rs6000/t-fprules: New file from t-rs6000.
+ * config/rs6000/t-beos: Remove soft-fp rules.
+ * config/rs6000/t-ppccomm: Likewise.
+ * config/rs6000/t-newas: Likewise.
+ * config/rs6000/t-rs6000-c-rule: Delete.
+ * config.gcc: Use t-fprules for rs6000/ ports when appropriate.
+ Use t-rs6000 for all rs6000/ ports instead of t-rs6000-c-rule.
+ Create generic Darwin rules.
+
+ * gengenrtl.c (gencode): Delete unnecessary rtl_obstack declaration.
+
+2002-12-18 Doug Evans <dje@sebabeach.org>
+
+ * m32r/m32r.c (addr24_operand): Fix arg to CONSTANT_POOL_ADDRESS_P
+ and LIT_NAME_P.
+ (move_src_operand): Remove compile-time warning.
+ * m32r/m32r.h (ROUND_ADVANCE_ARG): Ditto.
+
+2002-12-18 Jason Merrill <jason@redhat.com>
+
+ * unwind-dw2-fde.c (frame_downheap): Split out from...
+ (frame_heapsort): Here.
+
+2002-12-17 Jason Merrill <jason@redhat.com>
+
+ * tree.c (make_node): Don't set TREE_TYPE on 's' class nodes.
+ (build1): Always set TREE_SIDE_EFFECTS on 's' class nodes.
+
+ * gcc.c (do_spec_1) ['W']: End any pending argument from the braces.
+
+ * calls.c (expand_call): Don't try to be clever about expanding
+ the return slot address.
+
+2002-12-18 Kaz kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/linux.h (NO_IMPLICIT_EXTERN_C, CPLUSPLUS_CPP_SPEC):
+ Define.
+
+2002-12-17 Jason Merrill <jason@redhat.com>
+
+ * genmultilib: Use 'cd ./foo'.
+
+2002-12-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/c-tree.texi: Restore deliberate spelling mistakes.
+
+2002-12-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/c-tree.texi: Fix typos and follow spelling conventions.
+ * doc/cpp.texi: Likewise.
+ * doc/extend.texi: Likewise.
+ * doc/gty.texi: Likewise.
+ * doc/install.texi: Likewise.
+ * doc/invoke.texi: Likewise.
+ * doc/md.texi: Likewise.
+ * doc/passes.texi: Likewise.
+ * doc/rtl.texi: Likewise.
+ * doc/sourcebuild.texi: Likewise.
+ * doc/tm.texi: Likewise.
+
+2002-12-17 Jerry Quinn <jlquinn@optonline.net>
+
+ * doc/invoke.texi: Minor spelling and grammar fixes.
+
+2002-12-17 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_output_constant_pool): Replace
+ ASM_OUTPUT_INTERNAL_LABEL by (*targetm.asm_out.internal_label).
+
+Tue Dec 17 09:47:57 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * convert.c (convert_to_real): Disable function transformation for
+ now.
+
+2002-12-16 Geoffrey Keating <geoffk@apple.com>
+
+ * gcc.c (handle_braces): Allow '@' as a switch name.
+
+2002-12-16 Jason Merrill <jason@redhat.com>
+
+ * calls.c (expand_call): Handle CALL_EXPR_HAS_RETURN_SLOT_ADDR
+ with special struct-return ABIs.
+
+ * c-semantics.c (add_scope_stmt): Abort if the end SCOPE_STMT
+ doesn't match the begin SCOPE_STMT in partialness.
+
+2002-12-16 Geoffrey Keating <geoffk@apple.com>
+
+ * genmultilib: Create temporary files in unique subdirectory.
+
+ * gcc.c (validate_switches): Allow '@' as a switch name.
+
+2002-12-16 Loren J. Rittle <ljrittle@acm.org>
+
+ * Makefile.in (gcov-iov.h): Improve portability.
+
+Mon Dec 16 23:39:19 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * mips.h (ASM_OUTPUT_ADDR_DIFF_ELT): Do not use qpword on API_N32/not
+ gas
+ * mips.md (tablejump insn): Likewise.
+
+2002-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/include/gcc-common.texi: Change version number to 3.4.
+
+2002-12-16 Bruce Korb <bkorb@gnu.org>
+
+ * fixinc/fixlib.h: add: #include <signal.h>
+ * fixinc/fixincl.c: remove: #include <signal.h>
+
+Mon Dec 16 17:20:04 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (EXTRA_CONSTRAINT_Z): New macro.
+ (EXTRA_CONSTRAINT): Use it.
+ * sh.md (anddi3): Use 'Z' constraint for alternative 2.
+
+2002-12-15 Zack Weinberg <zack@codesourcery.com>
+
+ * config.gcc (need_64bit_hwint): New variable.
+ (alpha*-*-*, x86_64-*-*, ia64-*-*, mips*-*-*, powerpc*-*-*,
+ mmix-knuth-mmixware, rs6000*-*-*, sparc64*-*-*, s390*-*-*,
+ sh*-*-*, hppa*64*-*-linux, parisc*64*-*-linux, hppa*64*-*-hpux11*,
+ sparcv9-*-solaris2*, sparc*-*-solaris2.[789], ultrasparc-*-freebsd*):
+ Set it.
+ (powerpc*-*-darwin*): Unset it.
+ (alpha-*-interix, alpha64-dec-*vms*, i?86-*-interix3*,
+ i?86-*-interix*, sparc64-*-openbsd*): Remove references to
+ deleted/nonexistent xm-*.h headers.
+ * configure.in: AC_DEFINE NEED_64BIT_HOST_WIDE_INT if the
+ target set need_64bit_hwint in config.gcc.
+ * configure, config.in: Regenerate.
+
+ * hwint.h: Overhaul. Don't bother trying int for
+ HOST_WIDE_INT. Do try __int64 if long is not enough. Base
+ decision to force 64-bit HOST_WIDE_INT on
+ NEED_64BIT_HOST_WIDE_INT, not (MAX_)LONG_TYPE_SIZE which is
+ not visible at this point. Don't allow prior definition of
+ any macro defined by this file.
+
+ * config/alpha/xm-vms.h: Don't define HOST_WIDE_INT or
+ HOST_BITS_PER_WIDE_INT.
+ * config/c4x/c4x.h: Adjust redefinition of
+ HOST_WIDE_INT_PRINT_HEX to match changes to hwint.h.
+ * config/alpha/xm-alpha-interix.h, config/alpha/xm-vms64.h,
+ config/i386/xm-i386-interix.h: Delete file.
+
+2002-12-14 Rodney Brown <rbrown64@csc.com.au>
+ John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.c (output_millicode_call): Convert ASM_OUTPUT_INTERNAL_LABEL.
+ * pa64-hpux.h (ASM_OUTPUT_INTERNAL_LABEL): Delete define.
+
+2002-12-14 Zack Weinberg <zack@codesourcery.com>
+
+ * mkconfig.sh: Correct comment. Add copyright boilerplate.
+
+2002-12-14 Zack Weinberg <zack@codesourcery.com>
+
+ * config/t-darwin, config/arm/t-pe, config/arm/t-strongarm-pe,
+ config/c4x/t-c4x, config/i370/t-i370, config/i386/t-cygwin,
+ config/i386/t-interix, config/i960/t-960bare, config/ia64/t-ia64,
+ config/rs6000/t-rs6000-c-rule, config/sparc/t-sol2,
+ config/v850/t-v850: Correct dependencies and normalize
+ compilation commands for files that include coretypes.h and tm.h.
+
+ * config/sparc/gmon-sol2.c: Include tconfig.h and tsystem.h,
+ not config.h and system.h.
+
+Sat Dec 14 20:43:41 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (flags_reg_operand): New function.
+ * i386.h (PREDICATE_CODES): Add flags_reg_operand.
+ * i386.md (cmov splitter, movqicc): Use new predicate.
+
+Sat Dec 14 17:03:17 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (movqicc splitter): Fix template.
+
+2002-12-13 Jason Merrill <jason@redhat.com>
+
+ * tree.h (CALL_EXPR_HAS_RETURN_SLOT_ADDR): New macro.
+ * calls.c (expand_call): Handle it.
+ * tree-inline.c (struct inline_data): Remove target_exprs field.
+ (optimize_inline_calls): Don't initialize it.
+ (expand_call_inline): Don't modify it. Handle
+ CALL_EXPR_HAS_RETURN_SLOT_ADDR.
+ (declare_return_variable): Take return slot addr.
+ * langhooks.h (copy_res_decl_for_inlining): Change target_exprs parm
+ to return_slot_addr.
+ * langhooks-def.h, langhooks.c: Adjust.
+ * explow.c (maybe_set_unchanging): Don't set RTX_UNCHANGING_P for
+ a decl with no DECL_INITIAL.
+
+ * expr.c (expand_expr): Don't discard the target of a call which
+ returns in memory.
+
+2002-12-13 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppinit.c (path_include): Take an environment variable name.
+ Tidy up.
+ (init_standard_includes): Simplify environment handling, and
+ move to ...
+ (cpp_read_main_file): ...here as -nostdinc should not affect
+ environment variable paths.
+
+2002-12-13 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.c (output_millicode_call): Correct typo.
+ (output_call): Likewise.
+
+Fri Dec 13 21:07:18 2002 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mn10300/mn10300.c (print_operand) <case N>: Check
+ operand's range. Print value directly, without aid from
+ output_address.
+ <case U>: New.
+ <case S>: Make sure argument to fprintf has the right type.
+ * config/mn10300/mn10300.h (OK_FOR_T): New macro.
+ (EXTRA_CONSTRAINT): Adjust.
+ * config/mn10300/mn10300.md: Add new all-QImode pattern for
+ bclr. Use %U for immediate operands of bset and bclr.
+ (iorqi3): New expand, with insns for AM33 and mn10300.
+
+Fri Dec 13 16:02:27 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (sh_register_operand): New function.
+ (prepare_move_operands): Use it.
+ * sh.h (PREDICATE_CODES): Add entry for sh_register_operand.
+ * sh.md (movsi_media, movsi_media_nofpu): Allow stores of 0.
+ (movqi_media, movhi_media, movdi_media, movdi_media_nofpu): Likewise.
+ (movdf_media, movdf_media_nofpu, movv4sf_i, movsf_media): Likewise.
+ (movsf_media_nofpu, movv2hi_i, movv4hi_i, movv8qi_i): Likewise.
+ (movv2si_i): Likewise.
+
+2002-12-13 Jim Wilson <wilson@redhat.com>
+
+ * doc/extend.texi (Complex Numbers): Update info on debug info.
+
+2002-12-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (addhi3_h8300): Remove the last
+ alternative.
+
+2002-12-12 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * hooks.h (hook_tree_tree_bool_false): Declare
+ hook_bool_tree_tree_false instead.
+
+2002-12-12 Devang Patel <dpatel@apple.com>
+
+ * doc/invoke.texi: Document Darwin linker options, -bundle
+ -bind_at_load, -all_load and -arch_errors_fatal
+
+2002-12-12 Jim Wilson <wilson@redhat.com>
+
+ * dbxout.c (dbxout_fptype_value): New.
+ (dbxout_type, case COMPLEX_TYPE): Call it. Use 'R' instead of 'r'.
+
+2002-12-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-decl.c: Fix a comment typo.
+ * cfg.c: Likewise.
+ * cfgcleanup.c: Likewise.
+ * cfglayout.c: Likewise.
+ * cfgrtl.c: Likewise.
+ * c-typeck.c: Likewise.
+ * dominance.c: Likewise.
+ * dwarf2asm.c: Likewise.
+ * dwarfout.c: Likewise.
+ * expmed.c: Likewise.
+ * expr.c: Likewise.
+ * final.c: Likewise.
+ * flow.c: Likewise.
+ * function.c: Likewise.
+ * gcc.c: Likewise.
+ * genautomata.c: Likewise.
+ * integrate.c: Likewise.
+ * loop.c: Likewise.
+ * loop.h: Likewise.
+ * output.h: Likewise.
+ * profile.c: Likewise.
+ * ra.h: Likewise.
+ * reload1.c: Likewise.
+ * reload.c: Likewise.
+ * sched-rgn.c: Likewise.
+ * stmt.c: Likewise.
+ * tree.h: Likewise.
+ * vmsdbgout.c: Likewise.
+
+2002-12-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Add a new peephole2.
+
+2002-12-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): Accept a constant
+ that's accepted by CONST_OK_FOR_J.
+
+2002-12-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (CONST_OK_FOR_J): New.
+ (CONST_OK_FOR_LETTER_P): Use CONST_OK_FOR_J.
+ * config/h8300/h8300.md (*addhi_h8300): Add a new alternative.
+ (*addhi_h8300hs): Likewise.
+
+Thu Dec 12 16:24:59 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (reg_class_from_letter): No longer const. Add 'e' entry.
+ (sh_register_move_cost): Add clause for SImode fp-fp moves.
+ Increase cost for moves involving multiple general purpose registers.
+ * sh.h (OVERRIDE_OPTIONS): Set reg_class_from_letter['e'] according to
+ TARGET_FMOVD.
+ (HARD_REGNO_MODE_OK): Allow V2SFmode and V4SFmode in general purpose
+ registers, and SImode in fp registers, for ! TARGET_SHMEDIA.
+ (enum reg_class reg_class_from_letter): No longer const.
+ (SECONDARY_OUTPUT_RELOAD_CLASS): Use REGCLASS_HAS_FP_REG /
+ REGCLASS_HAS_GENERAL_REG.
+ Handle SImode moves from/to fp registers.
+ ! TARGET_SHMEDIA && TARGET_FMOVD.
+ (SECONDARY_INPUT_RELOAD_CLASS): Use REGCLASS_HAS_FP_REG.
+ * sh.md (movsi_ie): Add alternatives to move from / to fp regisyters.
+
+2002-12-12 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/ia64.c (ia64_hpux_asm_file_end): Fix typo in last
+ change and some warnings.
+
+2002-12-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/md.texi (pushm): Fix a typo.
+
+2002-12-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mips/mips.c (mips_output_conditional_branch): Support
+ PIC-safe out-of-range branch and branch-likely.
+ * config/mips/mips.md (attr length): PIC-safe out-of-range
+ branches are longer.
+ ("jump"): Support PIC-safe out-of-range-for-branch jumps. Remove
+ unused code to support indirect jumps.
+
+2002-12-11 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (GTFILES): Add $(host_xm_file_list) and
+ $(tm_file_list).
+
+2002-12-11 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/t-rs6000-c-rule: Add coretypes.h $(TM_H) dependencies.
+
+Wed Dec 11 15:20:45 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (cmove splitters): Avoid creation of unnecesary subregs.
+
+2002-12-11 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.h (BIGGEST_ALIGNMENT): Change 32-bit value to 64 bits.
+ (MAX_PARM_BOUNDARY, STACK_BOUNDARY): Express in terms of
+ BIGGEST_ALIGNMENT.
+ (PREFERRED_STACK_BOUNDARY): Express in terms of STACK_BOUNDARY.
+ (FUNCTION_BOUNDARY): Express in terms of BITS_PER_WORD.
+
+2002-12-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Correct dump file names.
+
+2002-12-09 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.c (ia64_hpux_asm_file_end): Don't send stripped
+ name to globalize_label or assemble_name.
+
+Wed Dec 11 20:15:19 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (REG_CLASS_HAS_GENERAL_REG): Only true for SIBCALL_REGS
+ if not TARGET_SHMEDIA.
+
+Wed Dec 11 19:05:05 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (REG_CLASS_HAS_FP_REG): New.
+ (REGISTER_MOVE_COST) Use it. Put body into a function and
+ move it into:
+ * sh.c (sh_register_move_cost).
+ * sh-protos.h (sh_register_move_cost): Declare.
+
+ * sh.c (sh_expand_builtin): Abort for unexpected nop values.
+ (sh_adjust_cost): Always return a value.
+
+Wed Dec 11 18:39:52 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (REG_CLASS_HAS_GENERAL_REG): New.
+ (REGISTER_MOVE_COST): Use it.
+
+2002-12-11 Richard Henderson <rth@redhat.com>
+
+ * tree.h (MODULE_LOCAL_P): Kill.
+ * varasm.c (default_binds_local_p_1): Use decl_visibility instead.
+
+2002-12-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (two define_peephole2): New.
+
+2002-12-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (CONST_OK_FOR_J): Remove.
+ (CONST_OK_FOR_K): Likewise.
+ (CONST_OK_FOR_M): Likewise.
+ (CONST_OK_FOR_LETTER_P): Do not use the above macros.
+
+2002-12-11 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.c (builtin_define_type_max): Handle unsigned
+ types too.
+
+2002-12-10 David Edelsohn <edelsohn@gnu.org>
+
+ * haifa-sched.c (rank_for_schedule): Correct style.
+
+2002-12-10 Per Bothner <pbothner@apple.com>
+
+ * cpplib.h (struct cpp_hashnode): Split a non-portably-signed field
+ directive_index into an unsigned field and a new is_directive field.
+ * cppinit.c (mark_named_operators): Update to set new fields.
+ * cpplex.c (_cpp_lex_direct): Now directive_field is unsigned.
+ * cpplib.c [_cpp_handle_directive]: Test is_directive field.
+ No longer need to subtract 1 from directive_index.
+ (_cpp_init_directives): No longer need to add 1 to directive_index.
+ * cpptrad.c (scan_out_logical_line): Use is_directive field.
+
+2002-12-10 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (fold_builtin): Remove -funsafe-math-optimizations
+ check for evaluating sqrt of a constant at compile time.
+ * simplify-rtx.c (simplify_unary_operation): Likewise.
+
+2002-12-10 Janis Johnson <janis187@us.ibm.com>
+
+ PR other/8882
+ * doc/tm.texi (PUSH_ARGS): Remove misplaced line.
+
+2002-12-10 Devang Patel <dpatel@appple.com>
+
+ * config/darwin.h(LINK_SPEC): Add darwin specific linker options.
+ * doc/invoke.texi: Add new "Darwin Options" section.
+
+2002-12-10 Jim Wilson <wilson@redhat.com>
+
+ * rs6000.h (RETURN_IN_MEMORY): If ABI_V4, then TFmode is returned in
+ memory.
+
+2002-12-10 Andrew Haley <aph@redhat.com>
+
+ * cse.c (cse_insn): Don't cse past a basic block boundary.
+
+2002-12-10 Jakub Jelinek <jakub@redhat.com>
+
+ * config/linux.h (LIB_SPEC): If -pthread, add -lpthread even if
+ -shared.
+ * config/alpha/linux-elf.h (LIB_SPEC): Likewise.
+ * config/alpha/linux.h (LIB_SPEC): Likewise.
+ * config/arm/linux-elf.h (LIB_SPEC): Likewise.
+ * config/pa/pa-linux.h (LIB_SPEC): Likewise.
+ * config/sparc/linux.h (LIB_SPEC): Likewise.
+ * config/sparc/linux64.h (LIB_SPEC): Likewise.
+
+2002-12-09 Larin Hennessy <larin@science.oregonstate.edu>
+
+ * doc/invoke.texi: Document UltraSparc III option.
+
+2002-12-09 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.h (TARGET_CPU_CPP_BUILTINS): Define
+ __tune_pentium2__ and __tune_pentium3__ as necessary.
+
+2002-12-09 Richard Henderson <rth@redhat.com>
+
+ * target.h (gcc_target): Add cannot_force_const_mem.
+ * target-def.h (TARGET_CANNOT_FORCE_CONST_MEM): New.
+ (TARGET_INITIALIZER): Add it.
+ * varasm.c (force_const_mem): Fail if cannot_force_const_mem.
+ * expr.c (emit_move_insn): Be prepared for force_const_mem to fail.
+ * reload1.c (reload): Likewise.
+ * hooks.c (hook_bool_rtx_false): New.
+ * hooks.h: Declare it.
+
+ * config/i386/i386.c (ix86_cannot_force_const_mem): New.
+ (TARGET_CANNOT_FORCE_CONST_MEM): New.
+ (ix86_expand_move): Remove de-const-pooling hack.
+
+Mon Dec 9 21:33:38 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (dump_file): Fix order to match reality.
+
+2002-12-08 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.md (load_multiple): Use adjust_address_nv.
+ (store_multiple): Likewise.
+
+2002-12-09 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa/fptr.c (__canonicalize_funcptr_for_compare): Don't canonicalize
+ function pointers in page 0.
+
+2002-12-09 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/hpux.h (TARGET_STRUCT_ARG_REG_LITTLE_ENDIAN): Remove
+ definition
+ (MEMBER_TYPE_FORCES_BLK): Move.
+ * config/ia64/ia64.c (ia64_function_arg): Use PARALLEL to pass
+ aggregate arguments.
+ (ia64_function_value): Use PARALLEL to return aggregate values.
+
+2002-12-09 Steve Ellcey <sje@cup.hp.com>
+
+ * doc/tm.texi (FUNCTION_ARG_REG_LITTLE_ENDIAN): Remove definition.
+ * defaults.h (FUNCTION_ARG_REG_LITTLE_ENDIAN): Remove definition.
+ * calls.c (store_unaligned_arguments_into_pseudos) Remove
+ FUNCTION_ARG_REG_LITTLE_ENDIAN.
+ * stmt.c (expand_return): Ditto.
+ * expr.c (move_block_from_reg): Ditto.
+ (copy_blkmode_from_reg): Ditto.
+ * expmed.c (store_bit_field): Ditto.
+
+2002-12-09 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config.gcc: Added tic4x-* target as an alias to c4x-*
+
+Sun Dec 8 14:57:39 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_int_movcc): Use force_operand instead of
+ constructing insn directly.
+
+2002-12-06 Per Bothner <pbothner@apple.com>
+
+ * cpplib.h (struct cpp_hashnode): Change field directive_index from
+ char to an int bit-field, for hosts where char is unsigned.
+
+2002-12-07 Roger Sayle <roger@eyesopen.com>
+ Richard Henderson <rth@redhat.com>
+
+ * real.c (ieee_extended_motorola_format,
+ ieee_extended_intel_96_format, ieee_extended_intel_128_format,
+ ieee_quad_format, vax_d_format, vax_g_format, i370_double_format):
+ Provide appropriate values for new signbit field.
+
+2002-12-07 Roger Sayle <roger@eyesopen.com>
+
+ * real.h (real_format): Add signbit field.
+ * real.c (ieee_single_format, ieee_double_format,
+ ieee_extended_motorola_format, ieee_extended_intel_96_format,
+ ieee_extended_intel_128_format, ibm_extended_format,
+ ieee_quad_format, vax_f_format, vax_d_format,
+ vax_g_format, i370_single_format, i370_double_format,
+ c4x_single_format, c4x_extended_format, real_internal_format):
+ Provide suitable signbit value, or -1 to avoid bit twiddling.
+
+ * optabs.c (expand_unop): Try implementing negation of
+ floating point modes by flipping the sign bit.
+ (expand_abs): Try implementing abs of floating point modes
+ by clearing the sign bit.
+
+Sat Dec 7 22:29:47 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_int_movcc): Use force_operand instead
+ of constructing insn directly.
+
+2002-12-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*iorhi_shift_8): New.
+
+2002-12-06 Bernd Schmidt <bernds@redhat.com>
+
+ * doc/invoke.texi: Document FRV port options.
+ * doc/md.texi: Document FRV register classes.
+
+2002-12-07 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/install.texi (Configuration): Improve description of cases
+ where `make distclean` may fail; clarify --with-gnu-as; fix grammar.
+
+2002-12-06 Per Bothner <pbothner@apple.com>
+
+ * cpplib.h (NODE_MACRO_ARG): New flag.
+ (struct cpp_hashnode): Give _cpp_hashnode_value tag to value union.
+ Remove value.operator field. Move arg_index field to value union.
+ (directive_index): Make signed, since also used for C++ operators.
+ * cppmacro.c (_cpp_save_parameter): Use NODE_MACRO_ARG flag to
+ check for duplicate parameter. Set NODE_MACRO_ARG flag.
+ Save node->value, and set node->value.arg_index.
+ (_cpp_create_definition): For each paramater, restore node->value.
+ (lex_expansion_token): Use NODE_MACRO_ARG flag, and moved arg_index.
+ * cpptrad.c (scan_out_logical_line): Likewise.
+ (scan_out_logical_line): Check for directive > 0.
+ * cpplib.c (cpp_handle_directive): Likewise.
+ * cpplex.c (_cpp_lex_direct): Update as value.operator is replaced
+ by negative of directive_index.
+ * cppinit.c (mark_named_operators): Likewise.
+
+ * hashtable.h (struct ht_identifier): Swap fields, for better packing.
+
+2002-12-06 Dhananjay Deshpande <dhananjayd@kpit.com>
+
+ * gcc/config/sh/sh.c (calc_live_regs): Save fpscr only if target has
+ FPU.
+ (push): Generate push_fpscr.
+ (pop): Generate pop_fpscr.
+ * gcc/config/sh/sh.md : Add define_expand "push_fpscr", "pop_fpscr".
+ (fpu_switch): Add alternative to push fpscr. Enable for TARGET_SH3E.
+
+Fri Dec 6 19:36:24 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (dump_table): DImode pool constants need only 32 bit alignment.
+ DFmode alignment depends on TARGET_FMOVD && TARGET_ALIGN_DOUBLE.
+
+Fri Dec 6 19:17:49 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (movdi_i): Name. Remove inappropriate comment.
+
+Fri Dec 6 15:44:46 2002 J"orn Rennecke <joern.rennecke@superh.com>
+ Merged from basic improvements branch (excerpt):
+
+ 2002-11-19 Kaz Kojima <kkojima@gcc.gnu.org>
+ * config/sh/sh.h (SH_DBX_REGISTER_NUMBER): Handle PR_MEDIA_REG.
+
+2002-12-06 Jakub Jelinek <jakub@redhat.com>
+
+ * expr.c (expand_expr) <case COND_EXPR>: Never modify exp in place.
+
+Thu Dec 5 16:58:25 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (dimode peep2s): Re-add "&& 1".
+
+Thu Dec 5 14:10:15 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_prologue): Add comment, do not use
+ fast prologues for cold and normal functions.
+
+Thu Dec 5 00:52:37 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (x86_rep_movl_optimal): New variable.
+ (ix86_expand_movstr, ix86_expand_clrstr): Use TARGET_REP_MOVL_OPTIMAL
+ * i386.h (TARGET_REP_MOVL_OPTIMAL): New macro.
+
+ * i386.md (negsf2_ifs, negdf2_ifs, negdf2_ifs_rex64, abssf2_ifs,
+ absdf2_ifs, absdf2_ifs_rex64): Fix constraints.
+ neg?f2_ifs, abs?f2_ifs splitters): Refuse memory operand; do not
+ generate unnecesary subregs.
+
+2002-12-05 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa32-linux.h (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL): Move define.
+ * pa.h (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL): To here.
+
+2002-12-05 Dale Johannesen <dalej@apple.com>
+
+ * tree.c (unsafe_for_reeval): Consider callee child of CALL_EXPR.
+
+2002-12-05 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/cygwin.h (SUBTARGET_PROLOGUE): Replace with
+ PROFILE_HOOK.
+ * config/i386/mingw32.h (SUBTARGET_PROLOGUE): Don't undef.
+
+2002-12-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.h (__ev_mwlufi): Remove.
+ (__ev_mwlufia): Remove.
+ (__ev_mwlumfaaw): Remove.
+ (__ev_mwlusfaaw): Remove.
+ (__ev_mwlumfanw): Remove.
+ (__ev_mwlusfanw): Remove.
+
+2002-12-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*andorsi3_shift_8): New.
+
+2002-12-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (shift_alg_si): Optimize ashift:HI and
+ lshiftrt:SI by 28, 29, and 30 bits when !TARGET_H8300.
+ (get_shift_alg): Return optimal assembly instructions for the
+ shifts mentioned above.
+
+Wed Dec 4 11:53:07 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_int_movcc): Force operand into register for QImode
+ condtiional moves.
+
+2002-12-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_init_once): Do not use loop to
+ implement ashiftrt:HI by 13 bits on H8S.
+
+2002-12-04 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa/fptr.c (__canonicalize_funcptr_for_compare): New file and function.
+ * pa.md (canonicalize_funcptr_for_compare): Output library call to
+ canonicalize_funcptr_for_compare_libfunc on TARGET_ELF32.
+ * pa32-linux.h (CANONICALIZE_FUNCPTR_FOR_COMPARE_LIBCALL,
+ CTOR_LIST_BEGIN): New defines.
+ * pa/t-linux (LIB2FUNCS_EXTRA): New define.
+ (fptr.c): Add make rules.
+
+2002-12-04 Geoffrey Keating <geoffk@apple.com>
+
+ * combine.c (combine_simplify_rtx): Add new canonicalizations.
+ * doc/md.texi (Insn Canonicalizations): Document new
+ canonicalizations for multiply/add combinations.
+ * config/rs6000/rs6000.md: Add and modify floating add/multiply
+ patterns to ensure they're used whenever they can be.
+
+2002-12-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c: Update the comments related to shifts.
+
+2002-12-04 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.md (get_fnaddr): Correct length attribute.
+
+2002-12-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*extzv_8_8): New.
+ (*extzv_8_16): Likewise.
+
+2002-12-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/8461, c++/8625
+ * integrate.c (copy_decl_for_inlining): Handle explicit invisible
+ references.
+ * tree-inline.c (initialize_inlined_parameters): Likewise.
+
+ * tree.c (variably_modified_type_p): Just return an error_mark_node.
+
+2002-12-04 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.md (get_fnaddr): Avoid placing an "la"
+ macro instruction in a branch delay slot, to avoid assembler
+ warnings.
+
+2002-12-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/7622
+ * c-semantics (genrtl_scope_stmt): Do not output inlined
+ nested functions that contain no code.
+
+Wed Dec 4 15:20:54 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * cfgrtl.c (force_nonfallthru_and_redirect): Allow abnormal edge
+ to be forced into nonfallthru.
+
+2002-12-03 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/t-netbsd (USER_H): Set to $(EXTRA_HEADERS).
+
+2002-12-03 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md (*movv1di_const0): New pattern.
+
+2002-12-03 Richard Henderson <rth@redhat.com>
+
+ * libgcc-std.ver: Inherit GCC_3.3 from GCC_3.0.
+
+2002-12-03 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * bitmap.c (bitmap_ior_and_compl, bitmap_union_of_diff):
+ Initialize tmp.using_obstack to 0.
+
+2002-12-03 Andreas Schwab <schwab@suse.de>
+
+ * config/m68k/m68k.h (EH_RETURN_DATA_REGNO): Define.
+ (EH_RETURN_STACKADJ_RTX): Define.
+ (EH_RETURN_HANDLER_RTX): Define.
+ (ASM_PREFERRED_EH_DATA_FORMAT): Define.
+ * config/m68k/m68k.c (m68k_save_reg): New function. Handle eh
+ registers and don't save fixed registers.
+ (m68k_output_function_prologue): Use it.
+ (use_return_insn): Likewise.
+ (m68k_output_function_epilogue): Likewise.
+
+2002-12-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (single_one_operand): Fix a warning.
+ (single_zero_operand): Likewise.
+
+2002-12-02 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in configure configure.in dummy-conditions.c fix-header.c
+ gcov-iov.c gen-protos.c genattr.c genattrtab.c genautomata.c
+ gencheck.c gencodes.c genconditions.c genconfig.c genconstants.c
+ genemit.c genextract.c genflags.c gengenrtl.c gengtype-lex.l
+ gengtype-yacc.y gengtype.c genopinit.c genoutput.c genpeep.c
+ genpreds.c genrecog.c gensupport.c mkconfig.sh read-rtl.c
+ scan-decls.c scan.c config/sh/sh.h doc/configfiles.texi
+ doc/install-old.texi: Replace hconfig.h with bconfig.h.
+ * Makefile.in: Replace HCONFIG_H with BCONFIG_H.
+
+2002-12-02 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/rs6000.md (ffssi): Convert to expander.
+ (ffsdi): Likewise.
+ (cntlzw2, cntlzd2): New patterns.
+
+2002-12-02 H.J. Lu <hjl@gnu.org>
+
+ * config.gcc (mips*-*-netbsd*): Remove mips/t-netbsd.
+ (mips*-*-linux*): Remove mips/t-linux.
+
+Mon Dec 2 19:26:30 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_int_movcc): Avoid overflow.
+
+2002-12-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (dosize): Replace argument op with
+ sign.
+ (h8300_output_function_prologue): Update the call to dosize.
+ (h8300_output_function_epilogue): Likewise.
+
+2002-12-02 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.h: Delete ifndefs with nothing inside them.
+
+2002-12-02 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ * configure.in: Use "missing" script to generate warning if
+ flex or bison programs not found, instead of invoking "false".
+ * configure: Rebuilt.
+
+Mon Dec 2 20:28:48 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * unroll.c (copy_loop_body): Copy CONST_OR_PURE_CALL_P.
+
+Mon Dec 2 19:42:52 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_int_movcc): Avoid overflow.
+
+2002-12-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (dosize): Output r7/er7 instead of sp.
+ (push): Likewise.
+ (pop): Likewise.
+ (h8300_output_function_prologue): Likewise.
+ (h8300_output_function_epilogue): Likewise.
+
+Mon Dec 2 14:43:22 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * expmed.c (store_bit_field): Use int_mode_for_mode to find
+ corresponding mode of non-integer mode, unless it is VOIDmode.
+
+2002-12-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (stm_h8300s_2): New.
+ (stm_h8300s_3): Likewise.
+ (stm_h8300s_4): Likewise.
+ (five define_peephole2): Likewise.
+
+2002-12-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ra-build.c: Fix a comment typo.
+
+Sun Dec 1 16:50:47 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_int_movcc): fix
+ reversed BRANCH_COST test; be curefull about infinite recursion.
+
+2002-12-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_output_function_prologue):
+ Remove variable idx.
+ (h8300_output_function_epilogue): Likewise.
+
+2002-12-01 Zack Weinberg <zack@codesourcery.com>
+
+ * config/frv/xm-frv.h: Delete, unnecessary.
+
+2002-12-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Add comments for define_peephole2.
+
+2002-12-01 Mark Mitchell <mark@codesourcery.com>
+
+ * builtin-types.def (BT_SIZE): Use size_type_node.
+ * builtins.c (fold_builtin): Make the builtin strlen returns a
+ size_t, not a sizetype.
+ * c-common.c (c_sizeof_or_alignof_type): Use size_type_node, not
+ c_size_type_node.
+ (c_alignof_expr): Likewise.
+ (c_common_nodes_and_builtins): Likewise.
+ * c-common.h (CTI_C_SIZE_TYPE): Remove.
+ (c_size_type_node): Likewise.
+ * c-format.c (T_ST): Use size_type_node, not c_size_type_node.
+ * tree.h (TI_SIZE_TYPE): New enumeral.
+ (size_type_node): Likewise.
+
+2002-11-30 Zack Weinberg <zack@codesourcery.com>
+
+ * configure.in: Don't put ${tm_file} into host_xm_file,
+ build_xm_file, or xm_file. Do put tm-preds.h into tm_p_file.
+ Take location of tm-preds.h into account when calculating
+ tm_p_file_list.
+ * configure: Regenerate.
+ * mkconfig.sh: No need for separate TM_DEFINES and XM_DEFINES
+ arguments. Do not provide rtx, rtvec, tree, or GTY here.
+ Remove special case code for tm_p.h and *config.h; add new
+ special case code for tm.h and tconfig.h. Clean up a bit.
+
+ * Makefile.in (tm_file, tm_file_list): New variables set from
+ @-substitutions.
+ (GCONFIG_H): Deleted.
+ (GTM_H, TM_H): New.
+ (CONFIG_H): Is now just config.h $(host_xm_file_list).
+ (TM_P_H): Move up with the other mkconfig.sh-generated
+ headers; don't mention tm-preds.h explicitly.
+ (tm.h, cs-tm.h): New rule.
+ (cs-config.h, cs-hconfig.h, cs-tconfig.h, cs-tm_p.h): Adjust
+ invocations of mkconfig.sh for changes to that program.
+ (mostlyclean): Delete print-rtl1.c.
+ (clean): Delete tm.h.
+ Update dependencies for the files listed below.
+
+ * mklibgcc.in: Add 'coretypes.h $(TM_H)' to libgcc2_c_dep.
+
+ * coretypes.h: New file.
+ * system.h: #define malloc to xmalloc and realloc to xrealloc
+ when FLEX_SCANNER or YYBISON is defined, independent of the
+ value of GCC_VERSION.
+ * alias.c, attribs.c, bb-reorder.c, bitmap.c, builtins.c,
+ c-aux-info.c, c-common.c, c-convert.c, c-decl.c, c-dump.c,
+ c-errors.c, c-format.c, c-lang.c, c-lex.c, c-objc-common.c,
+ c-opts.c, c-parse.in, c-pragma.c, c-pretty-print.c,
+ c-semantics.c, c-typeck.c, caller-save.c, calls.c, cfg.c,
+ cfganal.c, cfgbuild.c, cfgcleanup.c, cfglayout.c, cfgloop.c,
+ cfgrtl.c, collect2.c, combine.c, conflict.c, convert.c,
+ cppdefault.c, cpperror.c, cppexp.c, cppfiles.c, cpphash.c,
+ cppinit.c, cpplex.c, cpplib.c, cppmacro.c, cppmain.c,
+ cppspec.c, cpptrad.c, crtstuff.c, cse.c, cselib.c, dbxout.c,
+ debug.c, df.c, diagnostic.c, doloop.c, dominance.c,
+ dummy-conditions.c, dwarf2asm.c, dwarf2out.c, dwarfout.c,
+ emit-rtl.c, errors.c, et-forest.c, except.c, explow.c,
+ expmed.c, expr.c, final.c, fix-header.c, flow.c, fold-const.c,
+ function.c, gcc.c, gccspec.c, gcov-dump.c, gcov-iov.c, gcov.c,
+ gcse.c, gen-protos.c, genattr.c, genattrtab.c, genautomata.c,
+ gencheck.c, gencodes.c, genconditions.c, genconfig.c,
+ genconstants.c, genemit.c, genextract.c, genflags.c,
+ gengenrtl.c, gengtype-lex.l, gengtype-yacc.y, gengtype.c,
+ genopinit.c, genoutput.c, genpeep.c, genpreds.c, genrecog.c,
+ gensupport.c, ggc-common.c, ggc-none.c, ggc-page.c,
+ ggc-simple.c, global.c, graph.c, haifa-sched.c, hashtable.c,
+ hooks.c, ifcvt.c, integrate.c, intl.c, jump.c, langhooks.c,
+ lcm.c, libgcc2.c, line-map.c, lists.c, local-alloc.c, loop.c,
+ main.c, mbchar.c, mips-tdump.c, mips-tfile.c, mkdeps.c,
+ optabs.c, params.c, predict.c, prefix.c, print-rtl.c,
+ print-tree.c, profile.c, protoize.c, ra-build.c,
+ ra-colorize.c, ra-debug.c, ra-rewrite.c, ra.c, read-rtl.c,
+ real.c, recog.c, reg-stack.c, regclass.c, regmove.c,
+ regrename.c, reload.c, reload1.c, reorg.c, resource.c,
+ rtl-error.c, rtl.c, rtlanal.c, sbitmap.c, scan-decls.c,
+ scan.c, sched-deps.c, sched-ebb.c, sched-rgn.c, sched-vis.c,
+ sdbout.c, sibcall.c, simplify-rtx.c, ssa-ccp.c, ssa-dce.c,
+ ssa.c, stmt.c, stor-layout.c, stringpool.c, timevar.c,
+ tlink.c, toplev.c, tracer.c, tree-dump.c, tree-inline.c,
+ tree.c, unroll.c, varasm.c, varray.c, varray.h, vmsdbgout.c,
+ xcoffout.c, config/darwin-c.c, config/darwin.c,
+ config/fp-bit.c, config/alpha/alpha.c, config/alpha/vms-cc.c,
+ config/alpha/vms-ld.c, config/arc/arc.c, config/arm/arm.c,
+ config/arm/pe.c, config/avr/avr.c, config/c4x/c4x-c.c,
+ config/c4x/c4x.c, config/cris/cris.c, config/d30v/d30v.c,
+ config/dsp16xx/dsp16xx.c, config/fr30/fr30.c,
+ config/frv/frv.c, config/h8300/h8300.c, config/i370/i370-c.c,
+ config/i370/i370.c, config/i386/i386.c, config/i386/winnt.c,
+ config/i960/i960-c.c, config/i960/i960.c,
+ config/ia64/ia64-c.c, config/ia64/ia64.c, config/ip2k/ip2k.c,
+ config/m32r/m32r.c, config/m68hc11/m68hc11.c,
+ config/m68k/m68k.c, config/m88k/m88k.c, config/mcore/mcore.c,
+ config/mips/irix6-libc-compat.c, config/mips/mips.c,
+ config/mmix/mmix.c, config/mn10200/mn10200.c,
+ config/mn10300/mn10300.c, config/ns32k/ns32k.c,
+ config/pa/pa.c, config/pdp11/pdp11.c, config/romp/romp.c,
+ config/rs6000/rs6000-c.c, config/rs6000/rs6000.c,
+ config/s390/s390.c, config/sh/sh.c, config/sparc/gmon-sol2.c,
+ config/sparc/sparc.c, config/stormy16/stormy16.c,
+ config/v850/v850-c.c, config/v850/v850.c, config/vax/vax.c,
+ config/xtensa/xtensa.c, objc/objc-act.c, objc/objc-lang.c:
+ Include coretypes.h and tm.h.
+
+ * genattrtab.c, genconditions.c, genemit.c, genextract.c,
+ gengenrtl.c, gengtype.c, genopinit.c, genoutput.c, genpeep.c,
+ genrecog.c: Include coretypes.h and tm.h from the file
+ generated by this program.
+
+ * unwind-dw2-fde-darwin.c, unwind-dw2-fde-glibc.c,
+ unwind-dw2-fde.c, unwind-dw2.c, unwind-sjlj.c: Include
+ coretypes.h and tm.h, and tsystem.h when not already included.
+ No need to include stddef.h nor stdlib.h.
+
+ * fixinc/fixlib.h: Include coretypes.h and tm.h. Do not
+ include auto-host.h or ansidecl.h/
+ * fixinc/server.h: Do not include stdio.h, unistd.h, or fixlib.h.
+ * fixinc/procopen.c: Include server.h after fixlib.h. Do not
+ include auto-host.h, ansidecl.h, or system.h.
+ * fixinc/server.c: Likewise. Also, do not include signal.h,
+ and do not redefine volatile.
+
+Sat Nov 30 17:16:46 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (movdf_integer): Always enable in 64bit.
+ (movdf_nointeger): Always disable in 64bit.
+
+2002-11-30 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * cfg.c (dump_flow_info): Use max_reg_num () to determine the largest
+ pseudo register number plus 1.
+
+Fri Nov 29 20:10:56 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * expmed.c (store_bit_field): Use int_mode_for_mode to find
+ corresponding mode of non-integer mode, unless it is VOIDmode.
+
+2002-11-29 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * cpplib.c (_cpp_test_assertion): Default *value to 0.
+
+ * cppexp.c (num_part_mul): Initialize result.unsignedp, to 1.
+
+2002-11-29 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/t-crtstuff: New target makefile fragment.
+ * config.gcc [s390-*-linux, s390x-*-linux]: Use it.
+
+2002-11-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (movsi_h8300hs): Change the order of
+ alternatives to correct the length when the memory operand is
+ either pre_dec or post_inc.
+
+2002-11-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (an anonymous pattern): Give an
+ internal name *tst_extzv_bitqi_1_n.
+ Accept bit_operand instead of bit_memory_operand.
+ Do not accept bit tests with the MSB.
+ (*tst_extzv_memqi_1_n): New.
+
+Thu Nov 28 23:56:24 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_int_movcc): Add copy_rtx to avoid invalid RTX
+ sharing when operand is SUBREG.
+
+Thu Nov 28 08:57:26 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * athlon.md (athlon-decodev): New reservation unit.
+ (athlon-direct0): New reservation.
+ (athlon-vector): New use athlon-decodev.
+ (athlon-double, athlon-direct): Better model.
+ (athlon_imul_k8): Use athlon-direct0.
+ (athlon_movlpd_load): New insn reservation.
+
+2002-11-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_eightbit_constant_address_p):
+ Fix a comment typo.
+ (h8300_tiny_constant_address_p): Likewise.
+
+2002-11-28 Michael Matz <matz@suse.de>
+
+ * doc/passes.texi: Mention the other register allocator.
+
+2002-11-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (6 new peephole2 patterns): New.
+
+2002-11-28 Jakub Jelinek <jakub@redhat.com>
+
+ * config.gcc (x86_64-*-linux*) [tmake_file]: Remove i386/t-crtstuff.
+ * config/t-linux (CRTSTUFF_T_CFLAGS_S): Add $(CRTSTUFF_T_CFLAGS).
+ * config/i386/t-linux64 (CRTSTUFF_T_CFLAGS): Define.
+
+2002-11-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_and_costs): New.
+ * config/h8300/h8300.h (RTX_COSTS): Use h8300_and_costs.
+ * config/h8300/h8300-protos.h: Add a prototype for
+ h8300_and_costs.
+
+Wed Nov 27 20:34:13 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (x86_sse_partial_regs_for_cvtsd2ss): New.
+ * i386.h (x86_sse_partial_regs_for_cvtsd2ss): Declare.
+ (TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS): New macro.
+ * i386.md (truncdfsf patterns and splitters): Use
+ TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
+
+2002-11-27 Zack Weinberg <zack@codesourcery.com>
+
+ * config/rs6000/rs6000.c (altivec_init_builtins): Make the
+ pointer argument in the prototypes of the following builtins
+ be (const TYPE *) rather than (TYPE *):
+ + __builtin_altivec_ld_internal_4sf
+ + __builtin_altivec_ld_internal_4si
+ + __builtin_altivec_ld_internal_8hi
+ + __builtin_altivec_ld_internal_16qi
+ + __builtin_altivec_lvsl
+ + __builtin_altivec_lvsr
+ + __builtin_altivec_lvebx
+ + __builtin_altivec_lvehx
+ + __builtin_altivec_lvewx
+ + __builtin_altivec_lvxl
+ + __builtin_altivec_lvx
+ + __builtin_altivec_dst
+ + __builtin_altivec_dstt
+ + __builtin_altivec_dstst
+ + __builtin_altivec_dststt
+
+2002-11-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * except.c (default_exception_section): Move variable into the
+ scope where it is used.
+
+2002-11-27 Krister Walfridsson <cato@df.lth.se>
+
+ * config.gcc (*-*-netbsd[2-9]*, *-*-netbsdelf[2-9]*): Test for
+ correct version.
+
+2002-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (OK_FOR_U): Remove extra parentheses.
+
+2002-11-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_shift_costs): New.
+ * config/h8300/h8300.h (RTX_COSTS): Use h8300_shift_costs.
+ * config/h8300/h8300-protos.h: Add a prototype for
+ h8300_shift_costs.
+
+2002-11-27 Jim Wilson <wilson@redhat.com>
+
+ * config/rs6000/spe.md (spu_evsplatfi, spu_evsplati): Swap operands
+ in output template.
+
+2002-11-27 Casper S. Hornstrup <chorns@users.sourceforge.net>
+
+ * config/i386/i386.h (DLL_IMPORT_EXPORT_PREFIX): Define.
+ * config/i386/winnt.c (i386_pe_dllexport_name_p): Use
+ DLL_IMPORT_EXPORT_PREFIX, not '@'.
+ (i386_pe_dllimport_name_p): Likewise.
+ (i386_pe_mark_dllexport): Likewise.
+ (i386_pe_mark_dllimport): Likewise.
+ (i386_pe_encode_section_info): Likewise.
+ (i386_pe_strip_name_encoding): Likewise.
+
+2002-11-27 Richard Henderson <rth@redhat.com>
+
+ * mkmap-symver.awk (BEGIN): Set sawsymbol false.
+ (nm && NF == 3): Set sawsymbol true.
+ (END): Exit if no symbols seen.
+ (output): Fix map syntax error if no globals for the version.
+
+Wed Nov 27 14:45:46 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * builtins.def (DEF_C99_BUILTIN): Fix.
+
+2002-11-26 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/lib1funcs.asm (FUNC, ENDFUNC0, ENDFUNC): New macros.
+ (all): Add .size and .type information.
+
+Tue Nov 26 22:43:50 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_int_movcc): Do not emit lea for short mode on
+ partial_reg_stall target.
+
+Tue Nov 26 22:27:47 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (movhicc): Allow general operand.
+ (movqicc): New expander.
+ (movqicc_noc): New pattern.
+ * i386.c (ix86_expand_carry_flag_compare): New function.
+ (ix86_expand_int_movcc): Optimize harder using sbb; support more
+ HImode conversion; support QImode conditional moves
+
+Tue Nov 26 16:30:59 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (FAST_PROLOGUE_INSN_COUNT): Set to 20.
+ (ix86_expand_prologue): Multiply the count by amount of registers to be
+ pushed.
+
+Tue Nov 26 15:55:27 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (override_options): Error about wrong -mcpu on x86-64
+ compilation.
+
+2002-11-26 NIIBE Yutaka <gniibe@m17n.org>
+
+ * config/sh/linux.h (FUNCTION_PROFILER): Implemented.
+
+Tue Nov 26 00:14:20 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386-protos.h (x86_extended_QIreg_mentioned_p,
+ x86_extended_reg_mentioned_p): Declare.
+ * i386.c (extended_reg_mentioned_1): New static function.
+ (x86_extended_QIreg_mentioned_p,
+ x86_extended_reg_mentioned_p): New global functions.
+ * i386.h (REX_SSE_REGNO_P): New macro.
+ * i386.md (prefix_rex): New attribute.
+ (length attribute): Add rex.
+
+2002-11-26 Andrew Haley <aph@redhat.com>
+
+ * unwind-sjlj.c (_Unwind_FindEnclosingFunction): Rename
+ from_Unwind_Find_Enclosing_Function.
+ * unwind-dw2.c (_Unwind_FindEnclosingFunction): Likewise.
+ * config/ia64/unwind-ia64.c (_Unwind_FindEnclosingFunction): Likewise.
+ * libgcc-std.ver (_Unwind_FindEnclosingFunction): Rename from
+ _Unwind_Find_Enclosing_Function, export @@GCC_3.3.
+ * unwind.h (_Unwind_FindEnclosingFunction): Add.
+
+2002-11-26 Hartmut Penner <hpenner@de.ibm.com>
+
+ * config/s390/s390.c (390_output_constant_pool): Set alignment
+ before label in 64 bit mode, behind otherwise.
+
+2002-11-26 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (handle_visibility_attribute): Accept "default".
+ * tree.h (enum symbol_visibility): New.
+ (decl_visibility): Declare.
+ * target.h (gcc_target.visibility): Take visibility arg as integer.
+ * varasm.c (default_assemble_visibility): Likewise.
+ (decl_visibility): New.
+ (maybe_assemble_visibility): Use it.
+ * output.h (default_assemble_visibility): Update prototype.
+ * config/rs6000/rs6000.c (rs6000_assemble_visibility): Take
+ visibility arg as integer.
+ * doc/extend.texi: Document default visibility.
+
+2002-11-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c: Adjust spacing.
+ * config/h8300/h8300.h: Likewise.
+
+2002-11-26 Richard Henderson <rth@redhat.com>
+
+ * hooks.c (hook_bool_void_false, hook_void_tree_int,
+ hook_void_FILEptr_constcharptr): Rename so that the return
+ type is first.
+ (hook_int_tree_tree_1, hook_void_tree, hook_void_tree_treeptr,
+ hook_bool_tree_false): New.
+ * hooks.h: Update.
+ * langhooks-def.h: Update for renames.
+ * target-def.h: Likewise.
+ * tree.c (default_comp_type_attributes,
+ default_set_default_type_attributes, default_insert_attributes,
+ default_function_attribute_inlinable_p,
+ default_ms_bitfield_layout_p): Remove.
+ * tree.h: Update.
+
+2002-11-26 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa-protos.h (function_value): New prototype.
+ * pa.c (function_value): Use a PARALLEL to return small aggregates on
+ TARGET_64BIT.
+ * pa.h (FUNCTION_VALUE): Use function_value.
+ * pa.md (call_value_internal_symref, call_value_internal_reg_64bit,
+ call_value_internal_reg, sibcall_value_internal_symref,
+ sibcall_value_internal_symref_64bit): Remove =rf constraint on return
+ value.
+
+2002-11-26 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * expr.c (gen_group_rtx, emit_group_move): New functions.
+ * expr.h (gen_group_rtx, emit_group_move): Prototype.
+ * function.c (expand_function_start): Use gen_group_rtx to create a
+ PARALLEL rtx to hold the return value when the real return rtx is a
+ PARALLEL.
+ (expand_function_end): Use emit_group_move to move the return value
+ from a PARALLEL to the real return registers.
+ * rtl.h (REG_FUNCTION_VALUE_P): Allow function values to be returned
+ in PARALLELs.
+
+2002-11-26 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/t-libc-ok: Fix typo.
+
+2002-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ * configure.in: Move AC_CANONICAL_SYSTEM and AC_ARG_PROGRAM back
+ before AC_PROG_CC.
+ * configure: Rebuilt.
+
+2002-11-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-decl.c: (start_struct): Commonize flag setting.
+
+2002-11-26 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/rs6000/rs6000.h (RS6000_CPU_CPP_ENDIAN_BUILTINS): New.
+ * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Use
+ RS6000_CPU_CPP_ENDIAN_BUILTINS.
+ * config/rs6000/netbsd.h (RS6000_CPU_CPP_ENDIAN_BUILTINS): Redefine.
+
+2002-11-26 Hartmut Penner <hpenner@de.ibm.com>
+
+ * config/s390/s390.md (literal_pool_64, literal_pool_31 ): New
+ insns.
+ * config/s390/s390.c (struct machine_function): Introduction of
+ struct machine_function.
+ (s390_output_symbolic_const): Use of cfun.
+ (s390_optimize_prolog): Likewise.
+ (s390_fixup_clobbered_return_reg): Likewise.
+ (s390_frame_info): Likewise.
+ (s390_emit_prologue, s390_emit_epilogue): Likewise.
+ (s390_init_machine_status): New function.
+ (override_options): call s390_init_machine_status.
+ * config/s390/s390-protos.h (s390_output_constant_pool): Changed
+ prototype.
+
+2002-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ * varasm.c (output_constant_pool): For pool constants in mergeable
+ section ensure each constant is padded to multiple of entity size.
+
+2002-11-26 Jakub Jelinek <jakub@redhat.com>
+
+ * varasm.c (default_exception_section): Move to...
+ * except.c (default_exception_section): ... here. Make
+ .gcc_except_table read-only if it is not expected to have any
+ dynamic relocations and linker handles it.
+ * dwarf2out.c (default_eh_frame_section): Make .eh_frame read-only
+ if it is not expected to have any dynamic relocations and linker
+ handles it.
+ * configure.in (HAVE_LD_RO_RW_SECTION_MIXING): Check what ld does
+ when linking read-only and read-write sections together.
+ * configure, config.in: Rebuilt.
+ * crtstuff.c (EH_FRAME_SECTION_CONST): Define.
+ (__EH_FRAME_BEGIN__, __FRAME_END__): Add it.
+
+Mon Nov 25 18:32:37 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (pushsf_rex64): Fix typo.
+
+2002-11-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.h (__ev_create_sfix32_fs): Change macro into
+ new function.
+ (__ev_create_ufix32_fs): Same.
+ (__ev_get_sfix32_fs_internal): New.
+ (__ev_get_sfix32_fs): Define to use function.
+ (__ev_get_ufix32_fs_internal): New.
+ (__ev_get_ufix32_fs): Define to use function.
+ (__ev_get_upper_ufix32_fs): Call __ev_get_ufix32_fs.
+ (__ev_get_lower_ufix32_fs): Same.
+ (__ev_get_upper_sfix32_fs): Call __ev_get_sfix32_fs.
+ (__ev_get_lower_sfix32_fs): Same.
+ (__ev_set_sfix32_fs_internal): New.
+ (__ev_set_ufix32_fs_internal): New.
+ (__ev_set_sfix32_fs): Call __ev_set_sfix32_fs_internal.
+ (__ev_set_ufix32_fs): Call __ev_set_ufix32_fs_internal.
+ (__ev_set_upper_sfix32_fs): Call function.
+ (__ev_set_lower_sfix32_fs): Same.
+ (__ev_set_upper_ufix32_fs): Same.
+ (__ev_set_lower_ufix32_fs): Same.
+
+2002-11-25 Douglas B Rupp <rupp@gnat.com>
+
+ * gcc.c (do_spec_1): Reset delete_this_arg to zero.
+
+2002-11-25 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/elfos.h (HANDLE_SYSV_PRAGMA): Define as 1.
+ * config/interix.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/linux-aout.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/lynx-ng.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/lynx.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/netbsd.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/openbsd.h (HANDLE_SYSV_PRAGMA: Likewise.
+ * config/alpha/elf.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/arm/netbsd.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/cris/aout.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/d30v/d30v.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/frv/frv.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/i386/djgpp.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/i386/i386-interix.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/i386/vxi386.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/ia64/ia64.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/m88k/m88k.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/mmix/mmix.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/rs6000/aix.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/rs6000/darwin.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/sparc/linux-aout.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/sparc/vxsparc64.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/stormy16/stormy16.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/alpha/osf.h (HANDLE_SYSV_PRAGMA): Don't undef before
+ defining.
+ * config/i386/sco5.h (HANDLE_SYSV_PRAGMA): Likewise.
+ * config/mips/iris5.h (HANDLE_SYSV_PRAGMA): Likewise.
+
+2002-11-25 Dave Pitts <dpitts@cozx.com>
+
+ * gcc/fixinc/mkfixinc.sh: add i370-*-openedition to bypass fixinc list
+
+2002-11-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (an anonymous pattern): New.
+
+2002-11-25 Richard Henderson <rth@redhat.com>
+
+ * alias.c (find_base_value): Use new_reg_base_value if it's live.
+ (copying_arguments): Make boolean.
+
+2002-11-25 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * gcc.c (static_spec_functions): Add if-exists-else spec
+ function.
+ (if_exists_else_spec_function): New function.
+ * doc/invoke.texi: Document the if-exists-else spec function.
+
+ * config/netbsd-elf.h (NETBSD_STARTFILE_SPEC): For -static, use
+ "%:if-exists-else(crtbeginT%O%s crtbegin%O%s)".
+
+2002-11-25 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.gcc (powerpc-*-netbsd*): Replace "svr4.h" with
+ "netbsd.h netbsd-elf.h" in tm_file. Set tmake_file to
+ "${tmake_file} rs6000/t-netbsd".
+ * config/rs6000/netbsd.h: Rewrite.
+ * config/rs6000/t-netbsd: New file.
+
+2002-11-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (an anonymous pattern): Relax the
+ condition for the pattern.
+
+2002-11-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.h (enum rs6000_builtins): Remove evmwlssf,
+ evmwlsmf, evmwlssfa, evmwlsmfa, evmwlssfaaw, evmwlsmfaaw,
+ evmwlssfanw, evmwlsmfanw.
+
+ * config/rs6000/rs6000.c (bdesc_2arg): Same.
+
+ * config/rs6000/spe.md: Same for patterns.
+
+2002-11-25 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
+
+ PR c/8639
+ * fold-const.c (extract_muldiv): Don't propagate division unless
+ both arguments are multiples of C.
+
+2002-11-25 Andrew Haley <aph@redhat.com>
+
+ * libgcc-std.ver (_Unwind_Find_Enclosing_Function): Add.
+ * config/ia64/unwind-ia64.c (_Unwind_Find_Enclosing_Function): New.
+ * unwind-sjlj.c (_Unwind_Find_Enclosing_Function): Likewise.
+ * unwind-dw2.c (_Unwind_Find_Enclosing_Function): Likewise.
+
+Sun Nov 24 10:38:04 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (x86_use_ffreep): New global variable.
+ * i386.h (x86_use_frfeep): Declare
+ (TARGET_USE_FFREEP): New macro
+ * i386.md (movs?f*): Use freep when asked for.
+ (push?f): Remove dead code.
+
+2002-11-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_init_once): Fix a typo in the
+ target help message.
+
+2002-11-24 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.gcc (*-*-netbsd*1.[7-9]*, *-*-netbsd*[2-9]*): Set
+ extra_parts to "crtbegin.o crtend.o crtbeginS.o crtendS.o
+ crtbeginT.o".
+ (arm*-*-netbsd*, i[34567]86-*-netbsd*, m68k*-*-netbsd*)
+ (ns32k-*-netbsd*, sparc-*-netbsd*, vax-*-netbsd*): Set extra_parts
+ to "" for a.out configurations.
+ * config/t-netbsd (CRTSTUFF_T_CFLAGS): Set to "-fPIC".
+
+2002-11-24 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/alpha/netbsd.h (CPP_SUBTARGET_SPEC): Just use
+ NETBSD_CPP_SPEC directly.
+ (SUBTARGET_EXTRA_SPECS): Remove netbsd_cpp_spec. Add
+ netbsd_endfile_spec.
+ (ENDFILE_SPEC): Use %(netbsd_endfile_spec).
+
+2002-11-24 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/netbsd-elf.h (STARTFILE_SPEC): Rename to
+ NETBSD_STARTFILE_SPEC.
+ (STARTFILE_SPEC): Redefine in terms of NETBSD_STARTFILE_SPEC.
+ (ENDFILE_SPEC): Likewise.
+ * config/netbsd.h (LIB_SPEC, LIBGCC_SPEC): Likewise.
+
+2002-11-24 Andreas Schwab <schwab@suse.de>
+
+ * Makefile.in (install-driver): Remove versioned link before
+ trying to create it.
+
+ * config/m68k/m68k.c: Fix typo in last change defining
+ TARGET_ASM_CAN_OUTPUT_MI_THUNK.
+
+2002-11-23 H.J. Lu <hjl@gnu.org>
+
+ * aclocal.m4: Include ../config/accross.m4.
+ (gcc_AC_COMPILE_CHECK_SIZEOF): Removed.
+ (gcc_AC_C_COMPILE_ENDIAN): Removed.
+ (gcc_AC_C_FLOAT_FORMAT): Check $ac_cv_c_bigendian
+ instead of $ac_cv_c_compile_endian.
+
+ * configure.in: Replace gcc_AC_COMPILE_CHECK_SIZEOF with
+ AC_COMPILE_CHECK_SIZEOF.
+ Replace gcc_AC_C_COMPILE_ENDIAN with AC_C_BIGENDIAN_CROSS.
+ * configure: Rebuild.
+
+2002-11-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (print_operand): Update the use of
+ h8300_tiny_constant_address_p.
+ (h8300_adjust_insn_length): Likewise.
+ (h8300_tiny_constant_address_p): Check if the given rtx is a
+ variable declared with __attribute__ ((tiny_data)).
+
+2002-11-22 Dale Johannesen <dalej@apple.com>
+
+ * toplev.c (rest_of_compilation): Fix comments.
+
+2002-11-22 Geoffrey Keating <geoffk@apple.com>
+
+ * aclocal.m4 (ac_cv_func_mmap_dev_zero): Darwin does not
+ allow mmap from /dev/zero. Don't make decisions for the host
+ based on presence or absence of /dev/zero on the build machine.
+ (ac_cv_func_mmap_anon): Darwin does have working MMAP_ANON.
+ (AC_FUNC_MMAP_FILE): Darwin does have mmap of a file.
+ * configure: Regenerate.
+
+2002-11-22 Daniel Jacobowitz <drow@mvista.com>
+
+ * gcc.c (make_relative_prefix, split_directories)
+ (free_split_directories): Removed.
+
+2002-11-22 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in: Set insn=nop for DWARF-2 tests on ARM.
+ * configure: Regenerated.
+
+2002-11-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (compute_a_shift_length): Fix the insn
+ length computation when xor.l is output.
+
+2002-11-21 Douglas B Rupp <rupp@gnat.com>
+
+ * alpha.md (movstrdi, clrstrdi): New VMS patterns.
+ (call_vms_1, call_value_vms_1): Cleanup syntax.
+
+Thu Nov 21 19:20:27 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * athlon.md (define_atuomaton): Add athlon_load.
+ (athlon-double): New reservation.
+ (athlon-ieu0): New CPU unit.
+ (athlon-load?): Use athlon_load automaton.
+ (*_k8 reservations): New.
+ (other insn revervations): Activate for K8.
+
+Thu Nov 21 15:07:42 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * cfgrtl.c (verify_flow_info): Accept EDGE_CAN_FALLTHRU flag.
+
+2002-11-21 Jim Wilson <wilson@redhat.com>
+
+ * config/rs6000/rs6000.c (function_arg): Set inner mode of SPE
+ vectors to SI.
+
+2002-11-21 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa-protos.h (xtensa_copy_incoming_a7): Declare.
+ * config/xtensa/xtensa.c (struct machine_function): Add
+ incoming_a7_copied flag.
+ (xtensa_copy_incoming_a7): Define.
+ (xtensa_emit_move_sequence): Use xtensa_copy_incoming_a7.
+ * config/xtensa/xtensa.md (movdi, movsf, movdf): Ditto.
+
+Thu Nov 21 23:52:04 CET 2002 Jan Hubicka <jH@suse.cz>
+
+ * i386-protos.h (x86_64_sign_extended_value): Fix prototype.
+ * i386.c (x86_64_general_operand, x86_64_szext_general_operand,
+ x86_64_nonmemory_operand, x86_64_movabs_operand,
+ x86_64_szext_nonmemory_operand, x86_64_immediate_operand,
+ ix86_expand_int_movcc): Update call of x86_64_sign_extended_value.
+ (local_symbolic_operand): Do not care the 64bit limits.
+ (x86_64_sign_extended_value): Remove allow_rip support.
+ (legitimate_pic_address_disp_p): Handle all cases allowed
+ with RIP addressing.
+ (legitimate_address_p): Use legitimate_pic_address_disp_p for PIC.
+ (legitimize_pic_address): Reorganize.
+ * i386.h (EXTRA_CONSTRAINT): Update call of x86_64_sign_extended_value.
+
+2002-11-21 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.gcc (arm*-*-netbsdelf*): Enable configuration.
+ * config/arm/netbsd-elf.h: New file.
+
+2002-11-21 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/arm/elf.h (SUBTARGET_EXTRA_SPECS): Add
+ subtarget_asm_float_spec.
+ (SUBTARGET_ASM_FLOAT_SPEC): Define, moving the
+ defaults from...
+ (ASM_SPEC): ...here. Use subtarget_asm_float_spec.
+
+2002-11-21 Nick Clifton <nickc@redhat.com>
+
+ * config/fr30/fr30.md (movsf_constant_store): Move code to
+ detect 0.0 into fr30.c.
+ * config/fr30/fr30-protos.h (fr30_const_double_is_zero):
+ Prototype.
+ * config/fr30/fr30.c (fr30_const_double_is_zero): New
+ function. Return true if the rtx is 0.0.
+
+2002-11-21 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/arm/elf.h (ASM_SPEC, LINK_SPEC): Pass -EL
+ if -mlittle-endian is specified.
+
+2002-11-21 Richard Earnshaw <rearnsha@arm.com>
+
+ PR optimization/2903
+ * arm.md (anddi_notzesidi_di): Operand 2 is inverted not operand 1.
+ (anddi_notsesidi_di): Likewise.
+
+2002-11-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (print_operand): Use
+ h8300_eightbit_constant_address_p and
+ h8300_tiny_constant_address_p.
+ (h8300_adjust_insn_length): Likewise.
+ * config/h8300/h8300.h (EIGHTBIT_CONSTANT_ADDRESS_P): Remove.
+ (TINY_CONSTANT_ADDRESS_P): Likewise.
+ (OK_FOR_U): Use eightbit_constant_address_p.
+
+2002-11-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/libgcc-libc.ver: Add multilib support.
+ * config/s390/linux.h (MULTILIB_DEFAULT): Define.
+ * config/s390/t-linux64 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES,
+ MULTILIB_OSDIRNAMES, LIBGCC, INSTALL_LIBGCC,
+ EXTRA_MULTILIB_PARTS): Define.
+
+2002-11-21 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_get_frame_size): A leaf function does not need its
+ stack padding to an aligned boundary if it has no frame.
+ (thumb_get_frame_size): Likewise.
+
+Wed Nov 20 22:25:53 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * x86-64.h (MCOUNT_NAME): Fix typo in my previous patch.
+ (override_options): Likewise.
+
+Wed Nov 20 19:07:17 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * config.gcc: Add k8 target alias support
+ * i386.c (_cost): Declare costs for various variants of divides and
+ multiplies.
+ (k8_cost): New.
+ (m_K8, m_ATHLON_K8): New macros.
+ (x86_use_leave, x86_push_memory, x86_movx, x86_unroll_strlen,
+ x86_cmove, x86_3dnow_a, x86_deep_branch, x86_use_fiop,
+ x86_promote_QImode, x86_sub_esp_?, x86_add_esp_?,
+ x86_integer_DFmode_moves, x86_partial_reg_dependency,
+ x86_memory_mismatch_stall, x86_accumulate_outgoing_args,
+ x86_prologue_using_move, x86_epilogue_using_move,
+ x86_arch_always_fancy_math_387, x86_sse_partial_regs,
+ x86_sse_typeless_stores): Set for K8
+ (override_options): Add k8 support; fix athlon alignment;
+ complain about non-x86-64 capable CPU being used in x86-64 compilation.
+ (ix86_issue_rate): Set for K8.
+ (ix86_adjust_cost, ia32_use_dfa_pipeline_interface,
+ x86_machine_dependent_reorg): Handle K8 like
+ * i386.h
+ (x86_costs): Change mult_init and divide into array.
+ (TARGET_K8, TARGET_ATHLON): New macros.
+ (MODE_INDEX): New macro.
+ (RTX_COST): Use new costs.
+ (TARGET_CPU_CPP_BUILTINS): Define __k8__ and __tune_k8__.
+ (TARGET_CPU_DEFAULT_NAMES): Add k8
+ (TARGET_CPU_DEFAULT_k8): New constant
+ (enum processor_type): Add PROCESSOR_K8.
+ * i386.md (cpu attribute): Add k8.
+
+ * invoke.texi: Document -march=k8.
+
+ * i386.md (type attribute): Add leave
+ (mode attribute): Remove unknownfp.
+ (length_immediate, modrm, memory attributes): Handle leave correctly.
+ (fp comparison patterns): Determine FP mode.
+ (leave, leave_rex64): Remove special cases.
+ * ppro.md (ppro_uops, ppro_p2): Add leave
+ * pentiun.md (pent_pop): Handle leave too.
+ * k6.md (k6_load): Handle leave.
+ * athlon.md (athlon_leave, athlon_pop): Fix.
+ (athlon_decode): Handle leave.
+
+2002-11-20 Steve Ellcey <sje@cup.hp.com>
+
+ * emit-rtl.c (gen_reg_rtx): Simplify mapping of Complex type
+ to component type using GET_MODE_INNER.
+ * expr.c (emit_move_insn_1): Ditto.
+ * optabs.c (expand_binop): Ditto.
+ (expand_unop): Ditto.
+ (expand_complex_abs): Ditto.
+
+2002-11-20 Douglas B Rupp <rupp@gnat.com>
+
+ * hwint.h (HAVE___INT64): Fix typo (was HAVE__INT64).
+
+2002-11-20 DJ Delorie <dj@redhat.com>
+
+ * config/stormy16/stormy16.c (s16builtins,
+ xstormy16_init_builtins, xstormy16_expand_builtin): New.
+ * config/stormy16/stormy16.md (divmodhi4, sdivlh, udivlh): New.
+
+2002-11-20 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * Makefile.in (RUN_GEN, VALGRIND_DRIVER_DEFINES): New variables.
+ (DRIVER_DEFINES): Add $(VALGRIND_DRIVER_DEFINES).
+ (executing gencheck, genconfigs, genconditions, genflags,
+ gencodes, genconstants, genemit, genrecog, genopinit, genextract,
+ genpeep, genattr, genattrtab, genoutput, gengenrtl, genpreds,
+ gengtype, genprotos): Prepend $(RUN_GEN).
+ * configure.in: Move host compiler tests before --enable-checking
+ tests.
+ (--enable-checking=valgrind): New.
+ * config.in, configure: Regenerate.
+ * cppfiles.c [!ENABLE_VALGRIND_CHECKING] (VALGRIND_DISCARD):
+ Define as empty.
+ (read_include_file): When doing the mmap+1 trick,
+ valgrind-annotate the byte after the mmap:ed area as readable.
+ (purge_cache): Remove above annotation.
+ * gcc.c (execute) [ENABLE_VALGRIND_CHECKING]: Arrange to prepend
+ VALGRIND_PATH -q to each command.
+
+ * ggc-common.c [!ENABLE_VALGRIND_CHECKING] (VALGRIND_DISCARD):
+ Define as empty.
+ (ggc_realloc): Update valgrind annotations.
+ * ggc-page.c [!ENABLE_VALGRIND_CHECKING] (VALGRIND_DISCARD):
+ Define as empty.
+ (alloc_anon, free_page, ggc_alloc, poison_pages): Add machinery to
+ valgrind-annotate memory.
+
+2002-11-20 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * recog.c (constrain_operands): Prefer exact match over reloadable
+ EXTRA_MEMORY_CONSTRAINT or EXTRA_ADDRESS_CONSTRAINT.
+
+ * reload.c (find_reloads): Always reload EXTRA_ADDRESS_CONSTRAINT
+ operands in Pmode.
+
+2002-11-20 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/8518
+ * c-decl.c (duplicate_decls): Outline the second definition
+ of an extern inline function in all cases.
+
+2002-11-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * stor-layout.c (place_field): Update rli->offset as well as
+ rli->bitpos.
+
+2002-11-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * sched-deps.c (sched_analyze): Check HARD_REGNO_CALL_PART_CLOBBERED.
+
+2002-11-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/sh/sh.md (udivsi3): Don't put udivsi3_i4_media instructions
+ into a libcall block.
+ (divsi3): Likewise divsi3_i4_media.
+
+2002-11-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * global.c (find_reg): Check HARD_REGNO_NREGS before kicking
+ out another register.
+
+2002-11-20 Jakub Jelinek <jakub@redhat.com>
+
+ * combine.c (force_to_mode): Only replace with (not Y) if all bits in fuller_mask
+ (not just mask) are set in C.
+
+2002-11-19 Steven Bosscher <steven.bosscher@usafa.af.mil>
+
+ * config/mips/vr.h (DRIVER_SELF_SPECS): Change %{<mgp32} to %<mgp32.
+
+2002-11-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * profile.c (index_counts_file): Fix obvious mistake.
+
+2002-11-19 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (profile.o): Add hashtab.h dependency.
+ * gcov-io.h (GCOV_SUMMARY_LENGTH): New.
+ * profile.c: Include hashtab.h.
+ (htab_counts_index_hash, htab_counts_index_eq, htab_counts_index_del,
+ cleanup_counts_index, index_counts_file, struct section_reference,
+ struct da_index_entry, counts_file_name, counts_file_index): New.
+ (get_exec_counts, init_branch_prob): Modified.
+
+2002-11-19 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config.gcc (sh*-*-linux*): Add t-slibgcc-elf-ver and t-linux
+ to tmake_file. Remove setting gas and gnu_ld here.
+ * config/sh/libgcc-glibc.ver: New file.
+ * config/sh/t-linux (EXTRA_MULTILIB_PARTS): Add crtbeginT.o.
+ (SHLIB_MAPFILES): New.
+ * config/sh/linux.h (MD_EXEC_PREFIX): Undefine.
+ (MD_STARTFILE_PREFIX): Likewise.
+ (HANDLE_PRAGMA_PACK_PACK_PUSH_POP): Define.
+ (DWARF2_UNWIND_INFO): Redefine.
+ (ASM_PREFERRED_EH_DATA_FORMAT): Define.
+ (LINK_EH_SPEC): Redefine.
+ (MD_FALLBACK_FRAME_STATE_FOR): Define except for SH-media.
+ (SH_FALLBACK_FRAME_FLOAT_STATE): Define.
+ (SH_DWARF_FRAME_GP0, SH_DWARF_FRAME_FP0, SH_DWARF_FRAME_XD0,
+ SH_DWARF_FRAME_BT0, SH_DWARF_FRAME_PR, SH_DWARF_FRAME_PR_MEDIA,
+ SH_DWARF_FRAME_GBR, SH_DWARF_FRAME_MACH, SH_DWARF_FRAME_MACL,
+ SH_DWARF_FRAME_PC, SH_DWARF_FRAME_SR, SH_DWARF_FRAME_FPUL,
+ SH_DWARF_FRAME_FPSCR): Likewise.
+ * config/sh/sh-protos.h (sh_set_return_address): Declare.
+ * config/sh/sh.c (calc_live_regs): Count EH_RETURN_DATA_REGNO
+ registers if the current function calls EH return.
+ (sh_expand_epilogue): Handle EH stack adjustments.
+ (sh_set_return_address): New function.
+ * config/sh/sh.h (SH_DBX_REGISTER_NUMBER): Handle PR_MEDIA_REG.
+ Don't abort even if the number is mapped to -1.
+ (EH_RETURN_DATA_REGNO): Define.
+ (EH_RETURN_STACKADJ_RTX): Define.
+ * config/sh/sh.md (UNSPEC_EH_RETURN): New.
+ (eh_return): New pattern.
+ (eh_set_ra_di, eh_set_ra_si): Likewise.
+ Add splitter to perform EH return after reload.
+
+Tue Nov 19 12:52:07 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * stor-layout.c (excess_unit_span): New function.
+ (place_field): Use it.
+
+2002-11-19 Andreas Schwab <schwab@suse.de>
+
+ * unwind.h (_Unwind_GetTextRelBase): Revert last change, this is
+ not valid in C++.
+
+2002-11-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in, Makefile.in: Correct BUILD/HOST confusion.
+ * configure: Regenerate.
+
+Tue Nov 19 00:11:44 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * convert.c (strip_float_extensions): New function.
+ (convert_to_real): Optimize some cases.
+
+2002-11-19 Andreas Jaeger <aj@suse.de>
+
+ * loop.c (record_giv): Initialize not_replaceable.
+ (check_final_value): Likewise.
+
+2002-11-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_init_once): Replace 1 with
+ MASK_H8300S.
+
+2002-11-19 Vijay L. Khuspe <vijayk1@kpit.com>
+
+ * config/h8300/h8300.c (h8300_init_once): Allow -mn switch
+ only if -mh or -ms present.
+ (h8300_eightbit_constant_address_p): Support the normal mode.
+ (h8300_tiny_constant_address_p): Likewise.
+ * config/h8300/h8300.h (TARGET_NORMAL_MODE): New.
+ (POINTER_SIZE): Add 16 bit pointer for the normal mode.
+ (Pmode): Evaluate to HImode for the normal mode.
+ (SIZE_TYPE): Evaluate to unsigned int for normal mode.
+ (PTRDIFF_TYPE): Evaluate to int for the normal mode.
+ (ASM_WORD_OP): Evaluate to word for the normal mode.
+ * config/h8300/h8300.md (tablejump_normal_mode): New.
+ (indirect_jump_normal_mode): New.
+ * config/h8300/t-h8300 (MULTILIB_OPTIONS): Pass -mn option to
+ directory.
+ (MULTILIB_DIRNAMES): Create target dependent directory
+ 'normal'.
+ (MULTILIB_EXCEPTIONS): Don't turn on -mn on H8/300.
+ * doc/invoke.texi (gccoptlist): Describe the new switch -mn.
+
+Tue Nov 19 23:50:56 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (length_immediate): Do not refer to insn address.
+ (jcc*, jmp patterns): Compute length explicitly.
+
+2002-11-19 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/8588
+ * optabs.c (expand_binop): Convert CONST_INTs in shift
+ operations too.
+
+2002-11-19 Roger Sayle <roger@eyesopen.com>
+
+ * gcse.c (gcse_emit_move_after): Correct typo in REG_EQUAL note.
+
+2002-11-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (an anonymous pattern): Relax the
+ condition to accept the same operands and/or subregs.
+
+2002-11-19 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/sh/sh.c (gen_shl_and): Revert previous patch.
+ * config/sh/sh.md (ashrdi3+1, ashrdi3+2): Predicate on
+ reload_completed.
+
+2002-11-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (print_operand): Update the use of
+ EIGHTBIT_CONSTANT_ADDRESS_P.
+ (h8300_adjust_insn_length): Likewise.
+ (h8300_eightbit_constant_address_p): Check if the given rtx is
+ a variable with __attribute__((eightbit_data)).
+ * config/h8300/h8300.h (OK_FOR_U): Update the use of
+ EIGHTBIT_CONSTANT_ADDRESS_P.
+
+2002-11-19 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/contrib.texi (Contributors): Add self as second contact in
+ addition to Jeff Law.
+
+2002-11-19 Andreas Jaeger <aj@suse.de>
+
+ * tree-inline.c: Move prototpyes of find_alloca_call_1 and
+ find_alloca_call to right place.
+
+2002-11-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cppfiles.c: Fix formatting.
+
+2002-11-19 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * gcc.c (The Specs Language): Document spec functions.
+ (static_spec_functions, lookup_spec_function)
+ (eval_spec_function, handle_spec_function)
+ (if_exists_spec_function, alloc_args): New.
+ (execute): Abort if processing_spec_function is true.
+ (do_spec_1): Hand off spec to handle_spec_function if %:
+ is encountered. If processing_spec_function is true,
+ end any pending argument when the end of the string is reached.
+ (main): Use alloc_args to allocate the initial argument vector.
+ * gcc.h (struct spec_function): New.
+ (lang_specific_spec_functions): New extern.
+
+ * config/netbsd-elf.h (STARTFILE_SPEC): Add if-exists(crti%O%s).
+ (ENDFILE_SPEC): Add if-exists(crtn%O%s).
+ * config/alpha/netbsd.h (ENDFILE_SPEC): Likewise.
+
+ * doc/invoke.texi: Document spec functions.
+
+ * cppspec.c (lang_specific_spec_functions): New.
+ * gccspec.c: Likewise.
+
+2002-11-18 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/hpux_longdouble.h (FIXUNS_TRUNCTFSI2_LIBCALL): New.
+ (FIXUNS_TRUNCTFDI2_LIBCALL): New.
+ (fixunstfsi_libfunc): Change.
+ (fixunstfdi_libfunc): Change.
+ (sdiv_optab): Don't zero out SImode handler.
+ (udiv_optab): Don't zero out SImode handler.
+ (smod_optab): Don't zero out SImode handler.
+ (umod_optab): Don't zero out SImode handler.
+
+2002-11-18 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/8524
+ * cpplib.c (run_directive): Remove previous kludge to _Pragma.
+ Add a new one in its place, which hopefully works.
+ (skip_rest_of_line): Change test for bottom-of-context-stack.
+
+Mon Nov 18 21:29:03 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (addqi_1_slp): Fix output template.
+ (subqi_1_slp): Fix type.
+
+Sun Nov 17 00:01:28 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * calls.c (alloca_call_p): New global function.
+ * tree.h (alloca_call_p): New.
+ * tree-inline.c (inlinable_function_p): Do not inline when
+ function calls alloca.
+ (find_alloca_call, find_alloca_call_1): New functions.
+
+2002-11-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*andorqi3): Use bor between bld and
+ bst. Update the insn length.
+ (*andorhi3): Likewise.
+ (*andorsi3): Likewise.
+
+2002-11-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/sh/sh-protos.h (sh_mark_label): Declare.
+ * config/sh/sh.c (sh_mark_label): New function, taken from
+ movdi_const, but fixing the case when the address has an addend.
+ * config/sh/sh.md (movdi_const, movdi_const_32bit): Use it.
+
+2002-11-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/sh/sh.c (pool_node): New field: part_of_sequence_p.
+ (add_constant): Set it.
+ (dump_table): Don't reorder a constant if part_of_sequence_p.
+ (machine_dependent_reorg): Assume that float constants will
+ stay in their original order if used as a sequence.
+
+2002-11-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/sh/sh.c (calc_live_regs): Update check for PIC liveness
+ in compact code.
+
+2002-11-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/sh/sh.md (initialize_trampoline): Do not force the
+ trampoline address into R0_REGS here.
+
+Sun Nov 17 14:01:09 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (negsf2_ifs, negdf2_ifs, negdf2_ifs_rex64, abssf2_ifs,
+ absdf2_ifs, absdf2_ifs_rex64): Fix constraints.
+ (neg?f2_ifs, abs?f2_ifs splitters): Refuse memory operand; do not
+ generate unnecesary subregs.
+
+2002-11-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * df.c: Fix formatting.
+
+2002-11-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (two anonymous patterns): Fix insn
+ lengths.
+
+2002-11-17 Daniel Jacobowitz <drow@mvista.com>
+
+ * sh.c (gen_shl_and): Don't create a zero_extend if the operand
+ is not an arith_reg_operand.
+
+2002-11-17 Graham Stott <graham.stott@btinternet.com>
+
+ * real.c (real_to_decimal): Fix buffer overrun when buffer size
+ is smaller than representation.
+
+2002-11-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtins.c: Fix formatting.
+
+Sat Nov 16 16:49:58 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (truncdfsf2_1_sse, truncdfsf2_1_sse_nooverlap, truncdfsf2_2,
+ floats?dff2_i387):
+ Work around regclass stupidity.
+ (truncdfsf_2_1_sse splitter): Accept !TARGET_PARTIAL_SSE_REGS
+
+Sat Nov 16 02:17:48 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (fop_df_6): New pattern.
+ (fop_xf_4, fop_xf_5): Handle both SF and DFmode extensions.
+ (fop_xf_6): Rewrite
+ (fop_xf_7): Delete.
+ (fop_tf_4, fop_tf_5): Handle both SF and DFmode extensions.
+ (fop_tf_6): Rewrite
+ (fop_tf_7): Delete.
+
+2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (two anonymous patterns): Fix typos.
+
+2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Fix formatting.
+
+2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Replace spaces with tabs.
+ * config/h8300/t-h8300: Remove a trailing empty line.
+
+2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tlink.c: Fix formatting.
+
+2002-11-16 David Edelsohn <edelsohn@gnu.org>
+
+ PR 8362
+ * config/rs6000/rs6000.c (rs6000_outout_load_multiple): New function.
+ * config/rs6000/rs6000.md (movti_string): Remove output modifier
+ when scratch register never needed.
+ (ldmsi[3-8]): New patterns.
+
+2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * hard-reg-set.h: Follow spelling conventions.
+ * real.c: Likewise.
+ * target.h: Likewise.
+
+2002-11-16 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/x86-64.h (MCOUNT_NAME): Change into string literal.
+
+2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * optabs.c: Fix formatting.
+
+Sat Nov 16 02:06:02 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * athlon.md, k6.md, pentium.md, ppro.md: Handle shift1, rotate1
+ * i386.md (attribute type): Add type shift1 and rotate1.
+ (*_slp): Rewrite to have just two operands to avoid reload problems.
+
+2002-11-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (4 anonymous patterns): New.
+
+2002-11-15 Geoffrey Keating <geoffk@apple.com>
+
+ * params.def (GGC_MIN_HEAPSIZE): Fix GGC_ALWAYS_COLLECT problem.
+ * doc/invoke.texi: Correct description of what needs to be done to
+ force collection at every ggc_collect call.
+
+2002-11-15 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (optimization_options): Set
+ flag_asynchronous_unwind_tables to 1 by default.
+
+2002-11-15 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h (ASM_PREFERRED_EH_DATA_FORMAT): Define.
+
+Fri Nov 15 14:54:19 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386-protos.h (x86_function_profiler): New function
+ * i386.h (MCOUNT_NAME): New.
+ (PROFILE_COUNT_REGISTER): New.
+ (FUNCTION_PROFILER): Move offline to ...
+ * i386.c (x86_function_profiler) ... here; fix 64bit support
+ * beos-elf.h (FUNCTION_PROFILER): Kill.
+ (MCOUNT_NAME): New.
+ * freebsd-aout.h (FUNCTION_PROFILER): Kill.
+ (MCOUNT_NAME): New.
+ (PROFILE_COUNT_REGISTER): New.
+ * linux.h (FUNCTION_PROFILER): Kill.
+ (MCOUNT_NAME): New.
+ * x86-64.h (FUNCTION_PROFILER): Kill.
+ (MCOUNT_NAME): New.
+ * freebsd.h (FUNCTION_PROFILER): Kill.
+ (MCOUNT_NAME): New.
+
+2002-11-14 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
+
+ * config/arm/arm.h (EXPAND_BUILTIN_VA_ARG,
+ FUNCTION_ARG_PASS_BY_REFERENCE): Define.
+ * config/arm/arm.c (arm_va_arg,
+ arm_function_arg_pass_by_reference): New.
+ * config/arm/arm-protos.h: Add prototypes.
+
+2002-11-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gthr-single.h: Fix formatting.
+
+2002-11-14 Zack Weinberg <zack@codesourcery.com>
+
+ * tree.c (tree_vec_elt_check_failed): New function.
+ * tree.h (TREE_VEC_ELT_CHECK): New checking macro.
+ (TREE_VEC_ELT): Use it.
+
+ * tree-inline.c (optimize_inline_calls): Don't copy a
+ zero-length vector.
+
+2002-11-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * diagnostic.c (sorry): Don't repeat "sorry, unimplemented" text.
+
+2002-11-14 Jakub Jelinek <jakub@redhat.com>
+
+ * varasm.c (output_addressed_constants) [MINUS_EXPR]: Clear reloc if
+ both operands contain local relocations.
+ (categorize_decl_for_section): Don't use mergeable sections if
+ initializer has any relocations.
+
+2002-11-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gthr-vxworks.h: Fix formatting.
+
+2002-11-13 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/install.texi (Testing): Document extra Java testing.
+ * doc/sourcebuild.texi (Test Suites): Document libgcj testing.
+
+2002-11-13 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa64-hpux.h (LINK_SPEC): Move "+Accept TypeMismatch" switch to the
+ beginning of the spec.
+ (LDD_SUFFIX, PARSE_LDD_OUTPUT): Delete.
+ (LD_INIT_SWITCH, LD_FINI_SWITCH): Define but don't enable. Add comment
+ regarding problems with global constructors when using GNU ld.
+
+2002-11-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gthr-solaris.h: Fix formatting.
+
+2002-11-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gthr-posix.h: Fix formatting.
+
+2002-11-12 Devang Patel <dpatel@apple.com>
+ * gcc.c (display_help): Two new options -Xpreprocessor and -Xassembler.
+ (process_command): Same.
+ * doc/invoke.texi: Info about these two new options.
+
+2002-11-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*andorsi3): New.
+
+2002-11-12 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * doc/install.texi (powerpc-*-linux-gnu*): Update binutils requirement.
+
+2002-11-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (tiny_constant_address_p): Parenthesize
+ expressions appropriately.
+
+2002-11-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gthr-win32.h: Fix formatting.
+
+2002-11-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (single_one_operand): Correctly compute
+ mask when mode is SImode.
+ (single_zero_operand): Likewise.
+ * config/h8300/h8300.md (two new anonymous insns): New.
+
+2002-11-12 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/contrib.texi (Contributors): Use GCJ instead of gcj to refer
+ to that entire project.
+
+2002-11-12 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/t-iris6 (MULTILIB_OSDIRNAMES): Restore old
+ directories.
+
+2002-11-11 Zack Weinberg <zack@codesourcery.com>
+
+ * params.def (ggc-min-expand, ggc-min-heapsize): New parameters.
+ * doc/invoke.texi: Document them.
+
+ * ggc-page.c: Include params.h. Remove definitions of
+ GGC_MIN_EXPAND_FOR_GC, GGC_MIN_LAST_ALLOCATED. Replace
+ GGC_POISON with ENABLE_GC_CHECKING in ifdefs, delete #define.
+ (init_gcc): Don't set G.allocated_last_gc here.
+ (ggc_collect): Use PARAM_VALUE (GGC_MIN_HEAPSIZE) and
+ PARAM_VALUE (GGC_MIN_EXPAND) to decide whether or not to
+ perform collection.
+ * ggc-simple.c: Similarly.
+ * Makefile.in (ggc-common.o, ggc-simple.o): Add $(PARAMS_H) to
+ dependencies.
+
+2002-11-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gthr-dce.h: Fix formatting.
+
+2002-11-11 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR c/8467
+ * stmt.c (tail_recursion_args): Handle DECL_MODE differing from the
+ mode of DECL_RTL case.
+
+2002-11-11 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/contrib.texi: Merge in the list from the libstdc++ web pages.
+
+Mon Nov 11 12:06:08 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (construct_container): Fix handling of SSE_CLASS.
+
+2002-11-10 Joel Sherrill <joel@gcc.gnu.org>
+
+ * config/m68k/t-crtstuff (crti.o): Use this...
+ ($(T)crti.o): ... instead.
+ (crtn.o): Use this...
+ ($(T)crtn.o): ... instead.
+
+2002-11-10 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/8439
+ * recog.c (validate_replace_rtx_1) [PLUS]: Simplify only
+ if there is something new to be simplified.
+
+2002-11-10 H.J. Lu <hjl@gnu.org>
+
+ * calls.c (PUSH_ARGS_REVERSED): Define only if not defined.
+ * expr.c (PUSH_ARGS_REVERSED): Likewise.
+
+ * config/i386/i386.h (PUSH_ARGS_REVERSED): Set to 1.
+
+2002-11-10 Zack Weinberg <zack@codesourcery.com>
+
+ * config/rs6000/sysv4.h: Define NO_IMPLICIT_EXTERN_C here...
+ * config/rs6000/linux.h, config/rs6000/linux64.h,
+ config/rs6000/windiss.h: ... not here.
+
+2002-11-10 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/mips/netbsd.h (TARGET_OS_CPP_BUILTINS): Define
+ __ABICALLS__ if TARGET_ABICALLS.
+
+Sun Nov 10 18:49:21 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.h (MIN_UNITS_PER_WORD): Define to 8 for x86-64 libgcc.
+
+2002-11-10 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-decl.c (grokdeclarator): Make error for duplicate type
+ qualifiers into a pedwarn, disabled for C99.
+
+2002-11-10 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/mmix/mmix.h (FUNCTION_ARG_CALLEE_COPIES): Define the same
+ as FUNCTION_ARG_PASS_BY_REFERENCE.
+
+2002-11-09 Zack Weinberg <zack@codesourcery.com>
+
+ * doc/install.texi: Add *-*-vxworks* specific installation
+ instructions.
+
+ * config/vxlib.c: Rewrite using generation numbers to identify
+ valid TSD keys.
+
+Sat Nov 9 00:10:54 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (x86_machine_dependent_reorg): Fix even more side cases.
+
+2002-11-09 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.h (STARTING_FRAME_OFFSET): Change offset for TARGET_64BIT to 16.
+
+ * config.gcc (hppa*64*-*-linux*): Shorten lines in tm_file define.
+ (hppa*64*-*-hpux11*): Likewise. Use elfos.h with gas.
+ * pa.c (output_millicode_call): Use symbol difference rather than
+ $PIC_pcrel$0 when using HP assembler.
+ * pa64-hpux.h (TARGET_GAS): Define to 1 or 0 depending on whether or
+ not elfos.h (i.e., gas) is being used.
+ (ASM_FILE_START, STRING_ASM_OP, TEXT_SECTION_ASM_OP,
+ DATA_SECTION_ASM_OP, BSS_SECTION_ASM_OP, ASM_OUTPUT_ALIGNED_COMMON,
+ ASM_OUTPUT_ALIGNED_LOCAL, GLOBAL_ASM_OP, ASM_DECLARE_FUNCTION_NAME,
+ ASM_OUTPUT_EXTERNAL, ASM_OUTPUT_EXTERNAL_LIBCALL,
+ ASM_OUTPUT_INTERNAL_LABEL, ASM_GENERATE_INTERNAL_LABEL): Define when
+ using elfos.h.
+ (TARGET_ASM_GLOBALIZE_LABEL): Undefine when using elfos.h.
+ (DWARF2_ASM_LINE_DEBUG_INFO): Delete.
+ (ASM_FILE_START): Add standard .SPACE and .SUBSPA defines when not
+ using elfos.h.
+ (TEXT_SECTION_ASM_OP, READONLY_DATA_SECTION_ASM_OP, DATA_SECTION_ASM_OP,
+ BSS_SECTION_ASM_OP): New HP style defines when not using elfos.h.
+ (TARGET_ASM_NAMED_SECTION, MAKE_DECL_ONE_ONLY, ASM_WEAKEN_LABEL):
+ Don't define when not using elfos.h.
+ (ASM_DECLARE_RESULT): Don't define.
+ * doc/install.texi (hppa*-hp-hpux*): Remove statement that HP assembler
+ doesn't work on hppa64-hp-hpux11.
+ (hppa*-hp-hpux11): Update.
+
+2002-11-09 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/mips/netbsd.h (SUBTARGET_ASM_SPEC): Don't pass -KPIC
+ to the assembler if -mno-abicalls was specified.
+
+2002-11-09 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa-linux.h (PREFERRED_DEBUGGING_TYPE, DWARF2_ASM_LINE_DEBUG_INFO,
+ ASM_OUTPUT_DEF): Delete.
+
+2002-11-09 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (COMMAND_LINE_OPTIONS): Fix -Wimplicit.
+
+2002-11-08 Roger Sayle <roger@eyesopen.com>
+
+ * real.c (real_sqrt): Update comment with bibliographic reference.
+
+Fri Nov 8 13:33:58 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (sse_loadss, sse2_loadsd): Fix expander.
+
+Fri Nov 8 13:25:41 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (x86_machine_dependent_reorg): Fix handling of empty functions.
+
+Fri Nov 8 13:01:42 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * builtins.c (expand_builtin_mathfn): Handle floor/ceil/trunc/round/nearbyint
+ (expand_builtin): Likewise.
+ * builtins.def: Add
+ __builtin_floor, __builtin_floorf, __builtin_floorl
+ __builtin_ceil, __builtin_ceilf, __builtin_ceill
+ __builtin_round, __builtin_roundf, __builtin_roundl
+ __builtin_trunc, __builtin_truncf, __builtin_truncl
+ __builtin_nearbyint, __builtin_nearbyintf, __builtin_nearbyintl.
+ * genopinit.c (optabs): Initialize the new optabs.
+ * optab.c (init_optabs): Likewise.
+ * optabs.h (optab_index): Add OTI_floor, OTI_ceil, OTI_trunc,
+ OTI_round, OTI_nearbyint.
+ (floor_optab, ceil_optab, trunc_optab, round_optab, nearbyint_optab): New.
+ * doc/md.texi: Document new named patterns.
+ * doc/extend.texi (builtin functions) Document
+ floor, floorf, floorl, ceil, ceilf,
+ ceill, round, roundf, roundl, trunc,
+ truncf, truncl, nearbyint, nearbyintf, nearbyintl.
+
+Fri Nov 8 11:36:11 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (sse_movdfcc, sse_movsfcc): Fix typo in previous patch.
+
+2002-11-08 Dale Johannesen <dalej@apple.com>
+
+ * dbxout.c (dbxout_type): Fix stabs info for vector types.
+
+2002-11-08 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/8497
+ PR preprocessor/8501
+ * cpptrad.c (scan_out_logical_line): A '#' from a macro doesn't
+ start a directive. In assembler, #NUM is not a line directive.
+
+2002-11-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppmain.c (cpp_preprocess_file): Loop to pop any -included
+ buffers.
+
+2002-11-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (two anonymous test insns): New.
+
+Fri Nov 8 11:20:19 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * jump.c (mark_jump_label): Handle subregs of label_refs.
+
+Thu Nov 7 21:54:22 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (sse_movdfcc, sse_movsfcc): Avoid overactive matching.
+ * i386.c (ix86_expand_fp_movcc): Match the reversed cases.
+
+2002-11-07 David Mosberger <davidm@hpl.hp.com>
+
+ * config/ia64/crtend.asm: Include "auto-host.h".
+ [HAVE_INITFINI_ARRAY]: Invoke __do_global_ctors_aux via .init_array.
+ * config/ia64/crtbegin.asm: Similarly.
+ * config/ia64/t-ia64 (crtbegin.o): Include from current directory.
+ (crtend.o, crtbeginS.o, crtendS.o): Likewise.
+
+ * aclocal.m4 (gcc_AC_INITFINI_ARRAY): New.
+ * configure.in: Use it if --enable-initfini-array not specified.
+ * doc/install.texi (Configuration): Document --enable-initfini-array.
+ * configure, config.in: Rebuild.
+
+2002-11-07 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/arm/arm-protos.h (arm_get_frame_size)
+ (thumb_get_frame_size): New prototypes.
+ * config/arm/arm.c (arm_get_frame_size)
+ (thumb_get_frame_size): New functions.
+ (use_return_insn, arm_output_epilogue, arm_output_function_epilogue)
+ (arm_compute_initial_elimination_offset, arm_expand_prologue): Use
+ arm_get_frame_size.
+ (thumb_expand_prologue, thumb_expand_epilogue): Use
+ thumb_get_frame_size.
+ * config/arm/arm.h (PREFERRED_STACK_BOUNDARY): Define.
+ (machine_function): Add frame_size member.
+ (THUMB_INITIAL_ELIMINATION_OFFSET): Use thumb_get_frame_size.
+
+2002-11-07 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (bit_count): Make argument unsigned long. Return unsigned.
+ Adjust code to use portable unsigned bit manipulation.
+ (insn_flags, tune_flags): Change type to unsigned.
+ (struct processors): Make flags unsigned long.
+ (arm_override_options): Change type of count and current_bit_count
+ to unsigned.
+
+2002-11-07 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm/elf.h (TYPE_OPERAND_FMT): Prefix type with %.
+
+Thu Nov 7 15:50:18 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (DWARF_FRAME_RETURN_COLUMN): Use DWARF_FRAME_REGNUM.
+
+Thu Nov 7 11:18:01 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * reg-stack.c (compensate_edge): Fix sanity check.
+
+2002-11-05 Geoffrey Keating <geoffk@apple.com>
+
+ * config.gcc: Don't create crtbegin, crtend on Darwin; do create
+ crt2.o. Rearrange t-darwin makefiles.
+ * crtstuff.c [OBJECT_FORMAT_MACHO]: Delete.
+ * unwind-dw2-fde-darwin.c: New.
+ * unwind-dw2-fde-glibc.c: Correct comment.
+ * unwind-dw2-fde.c (__register_frame_info_bases)
+ [DWARF2_OBJECT_END_PTR_EXTENSION]: Clear fde_end.
+ (classify_object_over_fdes): Use last_fde.
+ (add_fdes): Likewise.
+ (linear_search_fdes): Likewise.
+ * unwind-dw2-fde.h (struct object)
+ [DWARF2_OBJECT_END_PTR_EXTENSION]: Add fde_end field.
+ (last_fde): New.
+ * config/darwin.h (STARTFILE_SPEC): Include crt2.o not crtbegin.o.
+ (ENDFILE_SPEC): No crtend.o.
+ * config/t-darwin: New.
+ * config/i386/t-darwin: Delete.
+ * config/darwin-crt2.c: New.
+ * config/rs6000/t-darwin: Delete contents duplicated in t-rs6000
+ or config/t-darwin.
+
+2002-11-06 Douglas B Rupp <rupp@gnat.com>
+
+ * config/i386/i386-interix.h (TARGET_SUBTARGET_DEFAULT): Or
+ MASK_MS_BITFIELD_LAYOUT
+ (SUBTARGET_OVERRIDE_OPTIONS): Warn about and turn off
+ MS bitfields for Objective-C.
+ (PCC_BIT_FIELD_TYPE_TEST, GROUP_BITFIELDS_BY_ALIGN): Remove
+ defines.
+
+ * config/i386/i386.c (ix86_ms_bitfield_layout): New function.
+ (TARGET_MS_BITFIELD_LAYOUT_P): Define to above function.
+ (TARGET_USE_MS_BITFIELD_LAYOUT): Define.
+
+ * config/i386/i386.h (MASK_MS_BITFIELD_LAYOUT: New mask.
+ TARGET_USE_MS_BITFIELD_LAYOUT): New macro.
+ (TARGET_SWITCHES): Add above mask.
+
+ * testsuite/gcc.dg/bf-ms-layout.c: New test case.
+ * testsuite/gcc.dg/bf-no-ms-layout.c: New test case.
+ * testsuite/gcc.dg/i386-bitfield1.c (dg-options): Add appropriate
+ flags for interix.
+
+Wed Nov 6 18:54:47 2002 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mips/mips.h (ASM_OUTPUT_ADDR_DIFF_ELT): Output
+ .gpword/.gpdword for ABI_N32 and ABI_64 too, if using the GNU
+ assembler.
+ * config/mips/mips.md (tablejump_internal3): Output .cpadd
+ before jump on ABI_N32 too.
+ (tablejump_internal4): Ditto on ABI_64. Increase maximum
+ length to match.
+
+Wed Nov 6 17:16:48 CET 2002 Jan Hubicka <jh@.suse.cz>
+
+ * i386.md (negsf splitter): Accept memory operand in second register.
+ (abssf/absdf splitters): Simplify
+ (sse_loadss, sse_loadsd): Turn into expander.
+
+2002-11-06 David Edelsohn <edelsohn@gnu.org>
+
+ PR target/8480
+ * config/rs6000/rs6000.md (movdi_internal64): Discourage
+ FPR to FPR moves.
+
+2002-11-06 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/contrib.texi: Merge in the list from the Java web pages.
+
+2002-11-06 David O'Brien <obrien@FreeBSD.org>
+
+ * config/sparc/freebsd: Fix typo.
+
+2002-11-06 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa64-hpux.h (LDD_SUFFIX, PARSE_LDD_OUTPUT): Define.
+
+2002-11-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mips/mips.md (call_value_multiple_internal2): Use dla for
+ non-SImode addresses.
+
+Tue Nov 5 14:34:36 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (float_truncate SSE splitter): Ensure that operand is not
+ stack register.
+ (float SSE splitters): Reorder conditional.
+
+2002-11-05 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/elf.h (LIB_SPEC): Add "-lhal".
+
+2002-11-05 John David Anglin <dave2hiauly1.hia.nrc.ca>
+
+ * pa64-hpux.h (LIB_SPEC): Fix p and pg options.
+ (STARTFILE_SPEC): Remove p and pg options.
+
+2002-11-05 Andrew Haley <aph@redhat.com>
+
+ * fold-const.c (fold): Don't transform (a0 op compound(a1,a2))
+ to (compound(a1,a0 op a2)) if a0 or a1 have side effects.
+
+2002-11-05 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (CANNOT_CHANGE_MODE_CLASS): Move comment to...
+ * config/mips/mips.c (mips_cannot_change_mode_class): ...here.
+
+2002-11-04 Zack Weinberg <zack@codesourcery.com>
+
+ * gthr-vxworks.h: Rewritten from scratch.
+ * config/vxlib.c: New file.
+ * config/t-vxworks: Add config/vxlib.c to LIB2FUNCS_EXTRA.
+ * config/rs6000/t-vxworks: Add config/vxlib.c to
+ LIB2FUNCS_EXTRA here too, because of clash with
+ config/rs6000/t-ppccomm.
+
+2002-11-04 Dale Johannesen <dalej@apple.com>
+
+ * doloop.c (doloop_modify_runtime): Fix loop count computation
+ for unrolled loops.
+ * loop.c (loop_invariant_p): Support calling from unroller.
+
+2002-11-04 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_decompose_address): Use arg_pointer_rtx
+ for comparison.
+
+2002-11-04 Aldy Hernandez <aldyh@redhat.com>
+
+ * hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): New.
+
+ * config/rs6000/rs6000.h (CLASS_CANNOT_CHANGE_MODE_P): Remove.
+ (CLASS_CANNOT_CHANGE_MODE): Remove.
+ (CANNOT_CHANGE_MODE_CLASS): New.
+
+ * config/alpha/alpha.h: Same.
+
+ * config/ia64/ia64.h: Same.
+
+ * config/mips/mips.h: Same.
+
+ * config/s390/s390.h: Same.
+
+ * config/sh/sh.h: Same.
+
+ * config/pa/pa64-regs.h: Same.
+
+ * config/sh/sh-protos.h (sh_cannot_change_mode_class): Add prototype.
+
+ * config/sh/sh.c (sh_cannot_change_mode_class): New.
+
+ * config/mips/mips-protos.h (mips_cannot_change_mode_class): Add
+ prototype.
+
+ * config/mips/mips.c (mips_cannot_change_mode_class): New.
+
+ * doc/tm.texi (Register Classes): Remove
+ CLASS_CANNOT_CHANGE_MODE and CLASS_CANNOT_CHANGE_MODE_P.
+ Document CANNOT_CHANGE_MODE_CLASS.
+
+ * reload.c (push_reload): Use CANNOT_CHANGE_MODE_CLASS.
+ (push_reload): Same.
+
+ * simplify-rtx.c (simplify_subreg): Same.
+
+ * reload1.c (choose_reload_regs): Same.
+
+ * recog.c (register_operand): Same.
+
+ * regrename.c (mode_change_ok): Change to use new
+ CANNOT_CHANGE_MODE_CLASS infrastructure.
+
+ * regclass.c (cannot_change_mode_set_regs): New.
+ Declare subregs_of_mode.
+ (regclass): Use subregs_of_mode.
+ Remove references to reg_changes_mode.
+ (init_reg_sets_1): Remove class_can_change_mode and
+ reg_changes_mode code.
+ (invalid_mode_change_p): New.
+ (dump_regclass): Use invalid_mode_change_p instead of
+ class_can_change_mode.
+ (regclass): Same.
+ (record_operand_costs): Do not set reg_changes_mode.
+
+ * local-alloc.c (struct qty): Remove changes_mode field.
+ (alloc_qty): Remove changes_mode initialization.
+ (update_qty_class): Remove set of changes_mode.
+ (find_free_reg): Use subregs_of_mode.
+
+ * global.c (find_reg): Use subregs_of_mode info.
+
+ * rtl.h (cannot_change_mode_set_regs): New prototype.
+ (invalid_mode_change_p): Same.
+ (REG_CANNOT_CHANGE_MODE_P): New macro.
+
+ * flow.c (mark_used_regs): Calculate subregs_of_mode. Remove
+ REG_CHANGES_MODE.
+ (life_analysis): Clear subregs_of_mode.
+
+ * combine.c (subst): Pass class to CLASS_CANNOT_CHANGE_MODE_P.
+ Remove use of CLASS_CANNOT_CHANGE_MODE.
+ (simplify_set): Same.
+ (gen_lowpart_for_combine): Calculate subregs_of_mode. Remove
+ REG_CHANGES_MODE.
+
+ * regs.h: Add extern for subregs_of_mode;
+ Include hard-reg-set and basic-block.
+ (REG_CHANGES_MODE): Delete.
+
+2002-11-03 Roger Sayle <roger@eyesopen.com>
+
+ * real.c (real_sqrt): New function to calculate square roots.
+ * real.h (real_sqrt): Add function prototype.
+ * builtins.c (fold_builtin): Fold sqrt of constant argument.
+ * simplify-rtx.c (simplify_unary_operation): Simplify sqrt
+ of constant argument.
+
+2002-11-03 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * jump.c (never_reached_warning): Don't set contains_insn until the
+ first line note is seen.
+
+2002-11-03 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (movti_string): Use string instructions.
+
+2002-11-03 Roger Sayle <roger@eyesopen.com>
+
+ PR c/7128
+ * c-typeck.c (c_expand_asm_operands): Defend against
+ error_mark_nodes in the output argument to avoid ICE.
+
+2002-11-03 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR middle-end/8408
+ * genrecog.c (preds): Handle ADDRESSOF.
+ (validate_pattern): Mark it as an lvalue.
+
+2002-11-02 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Use string
+ instructions when optimizing for size.
+
+2002-11-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h: Fix comment typos.
+ * config/h8300/h8300.md: Likewise.
+ * config/h8300/lib1funcs.asm: Likewise.
+
+2002-11-02 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ Revert this change:
+
+ *doc/install.texi (Installing GCC: Configuration): Clarify
+ the only supported ways to configure gcc.
+
+2002-11-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (anonymous and:QI pattern): Use 'n'
+ instead of 'O' for the constraint for the second operand.
+
+2002-11-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8391
+ * toplev.c (rest_of_compilation): Do not refuse to output code for
+ an inline function in a local class.
+
+2002-11-01 David O'Brien <obrien@FreeBSD.org>
+
+ * config/sparc/freebsd.h (CPP_CPU64_DEFAULT_SPEC): Define __arch64__.
+ (TRANSFER_FROM_TRAMPOLINE): Reformat.
+ Add comment.
+
+2002-11-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (CAN_ELIMINATE): Simplify.
+
+2002-11-01 Toshiyasu Morita <toshiyasu.morita@hsa.hitachi.com>
+
+ * config/h8300/h8300.h (OPTIMIZATION_OPTIONS): New.
+
+2002-11-01 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.h (MASK_INLINE_DIV_LAT): Remove.
+ (MASK_INLINE_DIV_THR): Remove.
+ (TARGET_INLINE_DIV_LAT): Remove.
+ (TARGET_INLINE_DIV_THR): Remove.
+ (TARGET_INLINE_DIV): Remove.
+ (MASK_INLINE_FLOAT_DIV_LAT): New macro.
+ (MASK_INLINE_FLOAT_DIV_THR): New macro.
+ (MASK_INLINE_INT_DIV_LAT): New macro.
+ (MASK_INLINE_INT_DIV_THR): New macro.
+ (TARGET_INLINE_FLOAT_DIV_LAT): New macro.
+ (TARGET_INLINE_FLOAT_DIV_THR): New macro.
+ (TARGET_INLINE_INT_DIV_LAT): New macro.
+ (TARGET_INLINE_INT_DIV_THR): New macro.
+ (TARGET_INLINE_FLOAT_DIV): New macro.
+ (TARGET_INLINE_INT_DIV): New macro.
+ * config/ia64/ia64.md (divsi3): Change to use new macros.
+ (modsi3): Ditto.
+ (udivsi3): Ditto.
+ (umodsi3): Ditto.
+ (divsi3_internal): Ditto.
+ (divdi3): Ditto.
+ (moddi3): Ditto.
+ (udivdi3): Ditto.
+ (umoddi3): Ditto.
+ (divdi3_internal_lat): Ditto.
+ (divdi3_internal_thr): Ditto.
+ (divsf3): Ditto.
+ (divsf3_internal_lat): Ditto.
+ (divsf3_internal_thr): Ditto.
+ (divdf3): Ditto.
+ (divdf3_internal_lat): Ditto.
+ (divdf3_internal_thr): Ditto.
+ (divtf3): Ditto.
+ (divtf3_internal_lat): Ditto.
+ (divtf3_internal_thr): Ditto.
+ * config/ia64/ia64.c (ia64_override_options): Change
+ to check new macros for conflicts in settings.
+ * doc/invoke.texi (-minline-divide-min-latency): Remove.
+ (-minline-divide-max-throughput): Remove.
+ (-minline-float-divide-min-latency): New.
+ (-minline-float-divide-max-throughput): New.
+ (-minline-int-divide-min-latency): New.
+ (-minline-int-divide-max-throughput): New.
+
+2002-11-01 Richard Earnshaw (rearnsha@arm.com)
+
+ PR target/7856
+ * arm.c (use_return_insn): Don't use a return insn if there are
+ saved integer regs, but LR is not one of them.
+
+Fri Nov 1 10:33:15 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * expr.c (emit_move_insn): Use SCALAR_FLOAT_MODE_P
+ * machmode.h (SCALAR_FLOAT_MODE_P): New macro.
+
+Thu Oct 31 18:20:50 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (sse_loadss, sse_loadsd): Canonicalize; add expander
+ (movps, movpd splitters): Use canonical form.
+ (movv2di): Fix merge problem.
+
+Thu Oct 31 16:22:31 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (negdf2_ifs_rex64): Don't allow GPR operand.
+
+2002-10-31 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR optimization/6162
+ * doc/md.texi: Document restriction on commutative operand
+ specification.
+
+2002-10-31 Eric Christopher <echristo@redhat.com>
+
+ * explow.c (convert_memory_address): Use shallow_copy_rtx.
+
+2002-10-31 Steve Ellcey <sje@cup.hp.com>
+
+ * expmed.c (store_bit_field): Check FUNCTION_ARG_REG_LITTLE_ENDIAN.
+
+2002-10-31 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/hpux.h (MEMBER_TYPE_FORCES_BLK): Set for non-floats.
+
+Thu Oct 31 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/darwin.h: Correct formatting in previous.
+
+Thu Oct 31 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/darwin.h: Enable -falign-xxx options.
+
+Thu Oct 31 18:08:00 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (override_options): Set defaults for flag_omit_frame_pointer,
+ flag_asynchronous_unwind_tables, flag_pcc_struct_return.
+ * i386.c (optimization_options): Set flag_omit_frame_pointer,
+ flag_asynchronous_unwind_tables, flag_pcc_struct_return to 2.
+ Do not clear -momit-leaf-frame-pointer when profiling.
+ (ix86_frame_pointer_required): Frame pointer is always required when
+ profiling.
+
+Thu Oct 31 16:09:44 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (negdf2_ifs_rex64): Don't allow GPR operand.
+
+Thu Oct 31 12:45:55 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (binary_logical_operator): Declare.
+ * sh.c (binary_logical_operator): New function.
+ * sh.md (xordi3+1): New combiner splitter pattern.
+
+2002-10-31 David O'Brien <obrien@FreeBSD.org>
+
+ * config/sparc/freebsd.h (TRANSFER_FROM_TRAMPOLINE): Define
+ __enable_execute_stack function.
+
+2002-10-30 Zack Weinberg <zack@codesourcery.com>
+
+ * gthr.h, gthr-dce.h, gthr-posix.h, gthr-rtems.h,
+ gthr-solaris.h, gthr-win32.h: Remove __gthread_key_dtor.
+ * unwind-sjlj.c (fc_key_dtor): Delete.
+ (fc_key_init): Adjust __gthread_key_create call to match.
+
+2002-10-30 Aldy Hernandez <aldyh@redhat.com>
+
+ * c-common.c: Add GTY to vector_type_node_list.
+
+2002-10-30 John David Anglin <dave@hiauly.hia.nrc.ca>
+
+ * pa-linux.h (ASM_OUTPUT_EXTERNAL_LIBCALL): Define.
+ * pa-protos.h (attr_length_millicode_call, attr_length_call,
+ pa_init_machine_status): Declare new global functions.
+ * pa.c (void copy_fp_args, length_fp_args, get_plabel): Declare and
+ implement new functions.
+ (attr_length_millicode_call, attr_length_call): Implement.
+ (total_code_bytes): Change type to long.
+ (pa_output_function_prologue): Compute total_code_bytes on TARGET_64BIT.
+ Reset counter if flag_function_sections.
+ (output_deferred_plabels): Set output alignment to 3 for TARGET_64BIT.
+ (output_cbranch): Move call to gen_label_rtx.
+ (output_millicode_call): Rewrite adding long TARGET_64BIT call, expose
+ delay slot in all variants, shorten pc-relative calls.
+ (output_call): Rewrite adding long TARGET_64BIT call, improved delay
+ slot usage and exposure, various new call variants, and shortened
+ sequences for some variants on TARGET_PA_20.
+ Miscellaneous format changes.
+ * pa.h (total_code_bytes): Change type to long.
+ (MASK_LONG_CALLS, TARGET_LONG_CALLS, TARGET_LONG_ABS_CALL,
+ TARGET_LONG_PIC_SDIFF_CALL, TARGET_LONG_PIC_PCREL_CALL): Define.
+ (TARGET_SWITCHES): Add "-mlong-calls" and "-mno-long-calls" options.
+ (EXTRA_CONSTRAINT, GO_IF_LEGITIMATE_ADDRESS,
+ LEGITIMIZE_RELOAD_ADDRESS): Don't use long floating point loads and
+ stores on TARGET_ELF32.
+ *pa.md (define_delay): Allow insns in delay on TARGET_PORTABLE_RUNTIME.
+ (unnamed patterns for mulsi3, divsi3, udivsi3, modsi3, umodsi3 and
+ canonicalize_funcptr_for_compare expanders): Calculate attribute length
+ attr_length_millicode_call().
+ (call_internal_symref, call_value_internal_symref): Clobber register 1.
+ Calculate attribute length using attr_length_call().
+ (call_internal_reg_64bit, call_value_internal_reg_64bit): Move gp load
+ to delay slot.
+ (sibcall, sibcall_value): Rewrite.
+ (sibcall_internal_symref, sibcall_value_internal_symref): Clobber
+ register 1. Use attr_length_call().
+ (sibcall_internal_symref_64bit, sibcall_value_internal_symref_64bit):
+ New patterns.
+ (unamed pattern for canonicalize_funcptr_for_compare): Rewrite.
+ * som.h (MEMBER_TYPE_FORCES_BLK): Define.
+ * t-pa64 (TARGET_LIBGCC2_CFLAGS): Add "-mlong-calls".
+ * doc/invoke.texi (mlong-calls): Document.
+
+2002-10-30 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold_binary_op_with_conditional_arg): Improve
+ handling of cases where one or both branches of the conditional
+ have void type, i.e. throw an exception or don't return.
+ (fold): Only apply (and undo) type conversion to the non-void
+ branches of a COND_EXPR.
+
+2002-10-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8333
+ * varasm.c (asm_output_aligned_bss): Do not call
+ ASM_GLOBALIZE_LABEL.
+
+2002-10-30 David Edelsohn <edelsohn@gnu.org>
+ Torbjorn Granlund <tege@swox.com>
+
+ * config/rs6000/rs6000.md (load_toc_v4_PIC_1): Use preferred form
+ for addressibility.
+ (load_toc_v4_PIC_1b): Same.
+
+2002-10-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_eightbit_constant_address_p):
+ Truncate the addresses for H8/300 using HImode.
+
+Tue Oct 29 23:28:10 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (negdf splitter): Fix construction of the constant.
+
+Tue Oct 29 20:47:06 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (negsf, negdf): Reorganize to use vector modes
+ for SSE variants.
+ (abssf, absdf): Use force_reg.
+ (movv4sf, movv2df): New splitters.
+ * i386.h (PREDICATE_CODES): add zero_extended_scalar_load_operand
+ * i386.c (zero_extended_scalar_load_operand
+
+ * i386-protos.h (ix86_expand_call): Update prototype.
+ * i386.c (ix86_function_ok_for_sibcall): Handle 64bit
+ (ix86_expand_call): Use r11 for indirect sibcalls.
+ * i386.md (call, call_value, untyped_call, call_value_pop):
+ update x86_expand_call call.
+ (sibcall, sibcall_value): new patterns
+ (call_rex64, call_value_rex64): Do not accept sibcalls.
+ (sibcall_rex64, sibcall_value_rex64,
+ sibcall_rex64_v, sibcall_value_rex64_v): New.
+
+Tue Oct 29 15:37:39 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (rest_of_compilation): Reorganize way reg_scan is called
+ before final pass.
+
+2002-10-29 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * toplev.c (rest_of_type_compilation): Return early in case of
+ errors.
+ (check_global_declarations): Don't call debug_hooks->global_decl
+ in case of errors.
+
+2002-10-28 Andreas Bauer <baueran@in.tum.de>
+
+ * doc/c-tree.texi (Tree overview): Fix typos.
+
+2002-10-29 Phil Edwards <pme@gcc.gnu.org>
+
+ * Makefile.in (gnucompare*): Only record bad comparisons
+ if there really was a bad comparison.
+
+Tue Oct 29 19:32:16 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.h (CONST_DOUBLE_OK_FOR_LETTER_P): Remove 'H'
+ * i386.md (movsf*, movdf*): Use 'C' instead of 'H'
+ * md.texi (machine dependent constraints): Document 'C'
+
+ * simplify-rtx.c (simplify_subreg): Fix const_int->vector subregging.
+
+ * i386.c (ix86_expand_vector_move): Fix.
+
+ * i386.c (ix86_expand_builtin): Use sse2_maskmovdqu_rex64.
+ * i386.md (sse2_maskmovdqu_rex64): New pattern
+
+ PR target/8322
+ * xmmintrin.h (_mm_stream_pi, _mm_stream_pd): Fix cast.
+ (ix86_init_mmx_sse_builtins): Fix type.
+
+2002-10-29 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * gthr-posix.h: Include <unistd.h> for feature tests.
+ (sched_get_priority_max, sched_get_priority_min)
+ (pthread_getschedparam, pthread_setschedparam): Only use
+ if _POSIX_THREAD_PRIORITY_SCHEDULING is defined.
+ (__gthread_objc_thread_set_priority): Don't treat all nonzero
+ returns from sched_get_priority_max and sched_get_priority_min
+ as an error.
+
+2002-10-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (TARGET_DEFAULT): Make it
+ MASK_QUICKCALL.
+
+2002-10-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_eightbit_constant_address_p): New.
+ (h8300_tiny_constant_address_p): Likewise.
+ * config/h8300/h8300.h (EIGHTBIT_CONSTANT_ADDRESS_P): Use
+ h8300_eightbit_constant_address_p.
+ (TINY_CONSTANT_ADDRESS_P): Use h8300_tiny_constant_address_p.
+ * config/h8300/h8300-protos.h: Add the prototypes for the two
+ new functions.
+
+2002-10-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * reload1.c (update_eliminables): Unconditionally check if
+ frame_pointer_needed has changed.
+
+Tue Oct 29 15:37:39 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (rest_of_compilation): Reorganize way reg_scan is called
+ before final pass.
+
+2002-10-29 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/8334
+ * expr.c (expand_expr) [PLUS]: Don't use simplify_binary_operation;
+ check for zero operands explicitly.
+
+2002-10-29 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (extv, extzv, insv): Set size of referenced
+ memory after adjusting to BLKmode.
+
+2002-10-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (MASK_*): New.
+ (TARGET_*): Use MASK_*.
+
+2002-10-28 Zack Weinberg <zack@codesourcery.com>
+
+ * config.gcc (*-*-vxworks, powerpc-wrs-vxworks*): New stanzas.
+ * config/t-vxworks, config/vxworks.h, config/rs6000/t-vxworks,
+ config/rs6000/vxworks.h: New files.
+ * config/rs6000/sysv4.h: Rip out -mvxworks and all related code.
+
+ * config.gcc (alpha*-*-vxworks*, arm-*-vxworks*,
+ i?86-wrs-vxworks*, i960-wrs-vxworks* [all],
+ m68k-wrs-vxworks*, mips-wrs-vxworks, powerpc-wrs-vxworks*,
+ powerpcle-wrs-vxworks*, sparc*-wrs-vxworks* [all],
+ sparc-*-vxsim*): Delete stanzas.
+ * gthr-vxworks.h: Rip out all substantive code and just
+ include gthr-single.h.
+
+ * config/alpha/vxworks.h, config/arm/vxarm.h,
+ config/i386/vxi386.h, config/i960/t-vxworks960,
+ config/i960/vx960-coff.h, config/i960/vx960.h,
+ config/m68k/t-vxworks68, config/m68k/vxm68k.h,
+ config/mips/vxworks.h, config/rs6000/vxppc.h,
+ config/sparc/t-vxsparc, config/sparc/t-vxsparc64,
+ config/sparc/vxsim.h, config/sparc/vxsparc.h,
+ config/sparc/vxsparc64.h: Delete files.
+
+2002-10-28 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.gcc (*-*-netbsd*): Add NETBSD_ENABLE_PTHREADS to
+ tm_defines if pthreads are enabled.
+ * config/netbsd.h (LIB_SPEC): Only support the -pthread option
+ if NETBSD_ENABLE_PTHREADS is defined.
+
+2002-10-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog.1: Fix typos.
+ * cse.c: Fix a comment typo.
+ * reload1.c: Likewise.
+
+2002-10-27 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * fixinc/inclhack.def (libc1_G_va_list): Correct test_text.
+ * fixinc/tests/base/_G_config.h: New file.
+
+2002-10-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c: Fix comment formatting.
+ * loop.c: Likewise.
+ * real.c: Likewise.
+ * regclass.c: Likewise.
+ * regmove.c: Likewise.
+ * regrename.c: Likewise.
+ * reg-stack.c: Likewise.
+ * reload1.c: Likewise.
+ * reload.c: Likewise.
+ * reload.h: Likewise.
+ * unroll.c: Likewise.
+
+2002-10-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * reload1.c (reload): Fix a comment typo.
+
+Sun Oct 27 10:15:24 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * linux64.h (DEFAULT_PCC_STRUCT_RETURN): Define.
+
+2002-10-27 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (dwarf2out.o): Add dependendcy on hashtab.h.
+ * dwarf2out.c: Include hashtab.h.
+ (is_main_source): New static variable.
+ (attr_checksum, die_checksum): Modified to handle die references.
+ (same_loc_p, same_dw_val_p, same_attr_p, same_die_p, same_die_p_wrap,
+ unmark_all_dies, htab_cu_hash, htab_cu_eq, htab_cu_del, check_duplicate_cu,
+ record_comdat_symbol_number): New static functions.
+ (output_comp_unit, compute_section_prefix, is_type_die, break_out_includes,
+ mark_dies, unmark_dies, dwarf2out_start_source_file): Modified.
+ * toplev.c (rest_of_decl_compilation): Call of dwarf2out_decl for type
+ declarations added.
+
+2002-10-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (initial_offset): Change to
+ h8300_initial_elimination_offset.
+ * config/h8300/h8300.h (INITIAL_ELIMINATION_OFFSET): Use
+ h8300_initial_elimination_offset.
+ * config/h8300/h8300-protos.h: Update the prototype.
+
+2002-10-26 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/mmix/mmix.h (LIBCALL_VALUE): Use
+ MMIX_RETURN_VALUE_REGNUM, not MMIX_OUTGOING_RETURN_VALUE_REGNUM.
+ (FUNCTION_VALUE_REGNO_P): Similar, but move code to...
+ * config/mmix/mmix.c (mmix_function_value_regno_p): New.
+ * config/mmix/mmix-protos.h: Remove needless ifdefs on TREE_CODE
+ and RTX_CODE.
+ (mmix_function_value_regno_p): Declare.
+
+ * config/mmix/mmix.md ("fixuns_truncdfdi2"): Replace unsigned_fix,
+ invalid for floating point mode result, with fix.
+
+Fri Oct 25 00:04:21 2002 Alexandre Oliva <aoliva@redhat.com>
+
+ * Makefile.in (GCC_FOR_TARGET): Add -L$(objdir)/../ld.
+ (STAGE2_FLAGS_TO_PASS): Pass GCC_FOR_TARGET.
+ (stage1_build): Likewise.
+
+2002-10-25 Mike Stump <mrs@apple.com>
+
+ Fixes gcc.dg/warn-1.c.
+ * c-typeck.c (warn_for_assignment): Don't print argument number,
+ if zero.
+
+Sat Oct 26 01:44:46 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (dump_file_index): Add DFI_ce3.
+ (dump_file_info): Likewise.
+ (rest_of_compilation): Run first ifcvt pass before tracer.
+
+2002-10-25 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/hpux.h (BITS_BIG_ENDIAN): Remove.
+
+2002-10-25 Richard Henderson <rth@redhat.com>
+
+ * real.c (real_to_decimal): If the >1 tens reduction loop results
+ in a negative exponent, fall into the <1 pten computation.
+
+2002-10-25 Zack Weinberg <zack@codesourcery.com>
+
+ PR middle-end/6994
+ * c-objc-common.c (inline_forbidden_p): Can not inline
+ functions containing structures or unions containing VLAs.
+ * tree-inline.c (walk_tree): For all class 't' nodes, walk
+ TYPE_SIZE and TYPE_SIZE_UNIT.
+ (copy_tree_r): Copy types if they are variably modified.
+
+2002-10-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md: Remove old-style peepholes.
+
+2002-10-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_decompose_address): Do not range check the
+ displacement if base or index is the argument pointer register.
+
+2002-10-24 Hans-Peter Nilsson <hp@bitrange.com>
+
+ PR other/3337
+ PR bootstrap/6763
+ PR bootstrap/8122
+ * fixinc/inclhack.def (libc1_G_va_list): New fix.
+ * fixinc/fixincl.x: Regenerate.
+ * config/i386/linux.h: Move MD_FALLBACK_FRAME_STATE_FOR inside
+ ifndef IN_LIBGCC2. Wrap it together with signal.h and
+ sys/ucontext.h inclusion in ifndef USE_GNULIBC_1.
+ * configure.in (gcc_AC_CHECK_DECLS): Check vasprintf too.
+ * config.in, configure: Regenerate.
+
+2002-10-24 Igor Shevlyakov <igor@microunity.com>
+
+ * varasm.c (struct rtx_const): Array size 16 for V16QImode.
+
+2002-10-24 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (x86_output_mi_thunk): Fix x86_64 pic jump.
+
+2002-10-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (initial_offset): Simplify by using
+ round_frame_size.
+
+2002-10-24 Marek Michalkiewicz <marekm@amelek.gda.pl>
+
+ * doc/install.texi (avr): Update required binutils version.
+
+2002-10-24 Theodore A. Roth <troth@openavr.org>
+
+ * doc/install.texi: Point avr users at more up-to-date information.
+
+2002-10-24 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md (movdi, movsi, movhi, movqi): Add peepholes2
+ to pull operands out of the literal pool where possible.
+
+2002-10-24 Denis Chertykov <denisc@overta.ru>
+
+ * config/avr/avr.c (init_cumulative_args): Test fntype for zero.
+
+2002-10-24 Steve Ellcey <sje@cup.hp.com>
+
+ * expr.c (convert_move): If unsignedp is less then zero there
+ is no equivalent code.
+
+2002-10-24 Zack Weinberg <zack@codesourcery.com>
+
+ * tree.def: Delete mention of nonexistent ARRAY_TYPE fields.
+
+2002-10-24 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h: Rework comments; re-sort target macro definitions
+ according to the sequence they are defined in the manual.
+ (POINTER_BOUNDARY): Remove.
+
+2002-10-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (round_frame_size): Replace 8 with
+ BITS_PER_UNIT.
+
+2002-10-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (EIGHTBIT_CONSTANT_ADDRESS_P): Make it
+ 64-bit safe.
+ (TINY_CONSTANT_ADDRESS_P): Likewise.
+
+2002-10-24 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): True.
+ (ia64_output_mi_thunk): Rewrite to use rtl, and to handle the
+ vcall offset.
+
+2002-10-24 Richard Henderson <rth@redhat.com>
+
+ PR opt/7944
+ * reload.c (find_reloads_toplev): Mode of X is not important
+ when simplifying subregs of constants.
+
+2002-10-24 Richard Sandiford <rsandifo@redhat.com>
+
+ * config.gcc (mips64vr-*-elf*, mips64vrel-*-elf*): Add
+ MIPS_MARCH_CONTROLS_SOFT_FLOAT=1 to $tm_defines.
+ * config/mips/mips.c (MIPS_MARCH_CONTROLS_SOFT_FLOAT): Default to 0.
+ (override_options): Base default setting of MASK_SOFT_FLOAT on -march
+ if MIPS_MARCH_CONTROLS_SOFT_FLOAT.
+
+2002-10-24 Richard Sandiford <rsandifo@redhat.com>
+
+ * optabs.c (expand_binop): Don't reuse the shift target in the
+ middle of shift sequences.
+
+Wed Oct 23 22:48:44 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (abs splitters): Do not produce nested subregs.
+
+Wed Oct 23 12:42:32 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (movti_rex64): Fix constraints.
+
+Wed Oct 23 12:01:21 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (abssf,absdf): Use vector operands for SSE
+ (abssf2_ifs, absdf2_ifs, absdf2_ifs_rex64 and splitters): Update for
+ vector operand.
+
+2002-10-23 Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (get_static_reference): Remove unneeded
+ TYPE_BINFO initialization.
+ (get_object-reference): Likewise.
+ (build_constructor): Tighten precondition check.
+ (finish_message_expr): Likewise.
+
+2002-10-23 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (local_symbolic_operand): Move LABEL_REF test
+ after CONST test.
+
+2002-10-23 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.c (hfa_element_mode): Don't allow 128 bit floats
+ in HFAs.
+
+2002-10-23 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): True.
+ (alpha_output_mi_thunk_osf): Handle vcall_offset.
+
+2002-10-23 Zack Weinberg <zack@codesourcery.com>
+
+ * langhooks.h (struct lang_hooks_for_tree_inlining): Add
+ var_mod_type_p.
+ * langhooks-def.h: Default for tree_inlining.var_mod_type_p is
+ hook_tree_bool_false.
+
+ * tree.c (variably_modified_type_p): Moved here from
+ cp/tree.c. Use lang_hooks.tree_inlining.var_mod_type_p for
+ language-specific cases. Due to this, must weaken some 'if
+ and only if' checks to merely 'if'.
+ * tree.h: Prototype variably_modified_type_p.
+
+ * tree-inline.c (walk_tree): #undef WALK_SUBTREE_TAIL at end.
+
+2002-10-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/linux.h (CC1_SPEC, CC1PLUS_SPEC): Remove.
+ * config/s390/s390.c (optimization_options): Disable -fcaller-saves.
+
+ * config/s390/s390-protos.h (fp_operand): Remove.
+ * config/s390/s390.c (fp_operand): Remove.
+ * config/s390/s390.md ("movdi"): Replace fp_operand by FP_REG_P.
+ ("*movdi_lhi", "*movdi_lli", "*movdi_larl"): Likewise.
+ ("movsi", "*movsi_lhi", "*movsi_lli"): Likewise.
+ (movdi_31, movdf_31 splitters): Likewise.
+
+ * config/s390/s390.h (IEEE_FLOAT): Remove.
+ (TARGET_FLOAT_FORMAT): Define in terms of TARGET_IEEE_FLOAT.
+ (INT_REGNO_P): Rename to ...
+ (GENERAL_REGNO_P): ... this.
+ (FLOAT_REGNO_P): Rename to ...
+ (FP_REGNO_P): ... this.
+ (ADDR_REGNO_P): New macro.
+ (GENERAL_REG_P, ADDR_REG_P, FP_REG_P, CC_REG_P): New macros.
+ (REGNO_OK_FOR_DATA_P, REGNO_OK_FOR_FP_P): Remove.
+ (DATA_REG_P, FP_REG_P, ADDRESS_REG_P): Likewise.
+ (HARD_REGNO_NREGS): Adapt to macro renaming.
+ (HARD_REGNO_MODE_OK): Likewise.
+
+2002-10-23 David Edelsohn <edelsohn@gnu.org>
+ Geoff Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_register_move_cost): New function.
+ (rs6000_memory_move_cost): New function.
+ * config/rs6000/rs6000-protos.h: Declare them.
+ * config/rs6000/rs6000.h: Use them.
+
+2002-10-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * libgcc2.c (__udiv_w_sdiv): Use attribute ((always_inline)) when
+ inlining it into other libgcc2 routines.
+ (__udivmoddi4): Likewise.
+
+2002-10-22 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * doc/sourcebuild.texi (Test Suites): Improve.
+
+2002-10-22 Stan Shebs <shebs@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_output_mi_thunk): Add missing
+ case for Darwin.
+
+2002-10-22 Jim Wilson <wilson@redhat.com>
+
+ * config/i386/i386.md (subdi3_1): Add call to ix86_binary_operator_ok.
+
+Wed Oct 23 01:52:36 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ PR other/8289
+ * xmmintrin.h: Add const to the argument of loads.
+
+ * i386.md (pushv2di): New pattern.
+ PR target/6890
+ * xmmintrin.h (_MM_TRANSPOSE4_PS): New.
+
+2002-10-22 Richard Henderson <rth@redhat.com>
+
+ * target.h (gcc_target.asm_out): Merge output_mi_thunk and
+ output_mi_vcall_thunk into a single hook. Add can_output_mi_thunk.
+ * target-def.h (TARGET_ASM_OUTPUT_MI_THUNK): Don't conditionalize.
+ (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Remove.
+ (TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
+ (TARGET_ASM_OUT): Update.
+ * hooks.c (hook_bool_tree_hwi_hwi_tree_false): New.
+ (hook_bool_tree_hwi_hwi_tree_true): New.
+ (default_can_output_mi_thunk_no_vcall): New.
+ * hooks.h: Declare them.
+ * system.h (ASM_OUTPUT_MI_THUNK): Poison.
+
+ * config/alpha/alpha.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
+ (alpha_output_mi_thunk_osf): Add VCALL_OFFSET parameter.
+ * config/arm/arm.c, config/cris/cris.c, config/frv/frv.c,
+ config/i960/i960.c, config/ia64/ia64.c, config/m68k/m68k.c,
+ config/mmix/mmix.c, config/pa/pa.c, config/sparc/sparc.c,
+ config/stormy16/stormy16.c: Similarly.
+
+ * config/i386/i386.c (x86_output_mi_thunk): Merge vcall_offset code.
+ Handle 64-bit properly. Streamline.
+ (x86_output_mi_vcall_thunk): Remove.
+ (x86_this_parameter): Rename from ia32_this_parameter; handle 64-bit.
+ (x86_can_output_mi_thunk): New.
+ (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Remove.
+ (TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
+ (override_options): Don't zap targetm.asm_out.output_mi_vcall_thunk.
+
+ * config/rs6000/rs6000.c (rs6000_output_mi_thunk): Rename from
+ output_mi_thunk; make static; always use function_section.
+ (TARGET_ASM_OUTPUT_MI_THUNK): New.
+ (TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
+ (rs6000_ra_ever_killed): Test no_new_pseudos not
+ targetm.asm_out.output_mi_thunk in conjunction with thunks.
+ * config/rs6000/rs6000-protos.h: Update.
+ * config/rs6000/sysv4.h (TARGET_ASM_OUTPUT_MI_THUNK): Remove.
+ * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Don't call
+ xcoffout_declare_function when using rs6000_output_mi_thunk.
+
+ * config/s390/s390.c (s390_output_mi_thunk): Rename from
+ s390_output_mi_vcall_thunk.
+ (TARGET_ASM_OUTPUT_MI_THUNK): Remove.
+ (TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
+
+ * config/vax/vax.c (vax_output_mi_thunk): Static; add vcall_offset.
+ (TARGET_ASM_OUTPUT_MI_THUNK, TARGET_ASM_CAN_OUTPUT_MI_THUNK): New.
+ * config/vax/vax-protos.h: Update.
+ * config/vax/vax.h (ASM_OUTPUT_MI_THUNK): Remove.
+
+Wed Oct 23 00:33:11 CEST 2002 Jan Hubicka <jh@suse,cz>
+
+ * i386.c (standard_sse_constant_p): Accept vector and integer zeros too.
+ * i386.h (EXTRA_CONSTRAINT): Recognize 'C'
+ * i386.md (movti_internal): Use 'C'
+
+ * xmmintrin.h (_mm_cmplt_epi*): New.
+
+2002-10-22 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*movdi_64"): Fix op_type attribute.
+ ("*movdf_64"): Likewise.
+ ("*lshrdi3_64"): Likewise.
+ ("blockage"): Add length attribute.
+ ("lit"): Likewise.
+
+Tue Oct 22 23:51:34 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md: FIx typo.
+ (sse2_cvtsi2sd, sse2_pslrdq): Fix template.
+ (sse2_umulv2siv2di3): Fix predicate.
+ (sse2_psadbw, ashrv8hi3, ashrv4si3, lshrv8hi3 lshrv4si3,
+ lshrv2di3, ashlv8hi3, ashlv4si3, ashlv2di3): Likewise.
+ * xmmintrin.h (_mm_mul_epu16): Rename to...
+ (_mm_mul_epu32): This one.
+ (_mm_cvtsi32_si128, _mm_cvtsi128_si32): New.
+
+ (contains_128bit_aligned_vector_p): Undo accidental checkin.
+
+2002-10-22 Eric Christopher <echristo@redhat.com>
+
+ * config/sparc/sparc.h: Add #error.
+
+2002-10-22 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config.gcc [s390-*-linux]: Remove s390/t-linux from tmake_file.
+ [s390x-*-linux*]: Likewise.
+ * config/s390/t-linux: Remove.
+ * config/s390/s390.h: Include fixdfdi.h when building libgcc2.
+
+Tue Oct 22 19:07:03 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (builtin_description): Add IX86_BUILTIN_PUNPCKHQDQ128.
+ (ix86_expand_builtin): Fix MASKMOVDQU expasion.
+ * i386.h (ix86_builtins): Add IX86_BUILTIN_PUNPCKHQDQ128.
+ * i386.md (mmx_punpck?dq): Simplify.
+ (sse2_pubpcklqdq): Fix.
+ (sse2_pubpckhqdq): New.
+ * xmmintrin.h (_mm_unpackhi_epi32): New.
+
+ * xmmintrin.h (_mm_cvt*, _mm_stream_pd): Fix prototypes.
+ (_mm_shufflehi_epi16, _mm_shufflelo_epi16): Fix typo.
+
+2002-10-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7209
+ * fold_const.c (fold_binary_op_with_conditional_arg): Always
+ build compound_expr if we used save_expr.
+
+2002-10-22 Alan Modra <amodra@bigpond.net.au>
+
+ * output.h (SECTION_NOTYPE): Define.
+ * varasm.c (default_section_type_flags_1): Set SECTION_NOTYPE for
+ init array sections.
+ (default_elf_asm_named_section): Mind SECTION_NOTYPE.
+ * config/arm/arm.c (arm_elf_asm_named_section): Likewise. Also
+ merge TLS support.
+
+2002-10-21 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (ix86_function_ok_for_sibcall): Look at
+ the function type, not the return type.
+
+2002-10-21 Richard Henderson <rth@redhat.com>
+
+ * real.c (sticky_rshift_significand): Return inexact, don't
+ or it in immediately.
+ (sub_significands): Accept incomming carry.
+ (div_significands, rtd_divmod): Update for sub_significands change.
+ (round_for_format): Update for sticky_rshift_significand change.
+ (do_add): Don't involve the inexact bit in addition, do give the
+ inexact bit as the subtraction carry-in.
+ (encode_internal, decode_internal, real_internal_format): New.
+ * real.h (real_internal_format): Declare.
+
+2002-10-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * libgcc2.c: Fix __udiv_w_sdiv breakage on platforms that
+ don't define sdiv_qrnnd.
+
+2002-10-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (EIGHTBIT_CONSTANT_ADDRESS_P): Simplify
+ using IN_RANGE.
+ (TINY_CONSTANT_ADDRESS_P): Likewise.
+
+Tue Oct 22 00:04:20 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (builtin_description): Add punpcklqdq and movdq2q
+ (ix86_init_mmx_sse_builtins): Add v2di_ftype_void, di_ftype_v2di,
+ v16qi_ftype_pchar, void_ftype_pchar_v16qi, v4si_ftype_pchar,
+ void_ftype_pchar_v4si; Initialize __builtin_ia32_movdq2q,
+ __builtin_ia32_loaddqa, __builtin_ia32_loaddqu, __builtin_ia32_loadd
+ __builtin_ia32_storedqa, __builtin_ia32_storedqu, __builtin_ia32_stored
+ __builtin_ia32_setzero128.
+ (ix86_expand_builtin): Handle IX86_BUILTIN_CLRTI, IX86_BUILTIN_LOADDQA,
+ IX86_BUILTIN_LOADDQU, IX86_BUILTIN_LOADD, IX86_BUILTIN_STOREDQA,
+ IX86_BUILTIN_STOREDQU, IX86_BUILTIN_STORED, Ix86_BUILTIN_MOVQ.
+ * i386.h (ix86_builtins): Add IX86_BUILTIN_LOADDQA, IX86_BUILTIN_LOADDQU,
+ IX86_BUILTIN_STOREDQA, IX86_BUILTIN_STOREDQU, IX86_BUILTIN_LOADD,
+ IX86_BUILTIN_STORED, IX86_BUILTIN_CLRTI, IX86_BUILTIN_MOVDQ2Q,
+ IX86_BUILTIN_PUNPCKLQDQ128, Ix86_BUILTIN_MOVQ.
+ * i386.md (sse2_punpcklqdq, sse2_movqsse2_loadd, sse2_stored,
+ sse2_movq): New patterns.
+ (sse2_movdqa, sse2_movdqu, sse2_movdq2q): Fix.
+ * xmmintrin.h (_mm_load_si128, _mm_loadu_si128, _mm_loadl_epi64,
+ _mm_store_si128, _mm_storeu_si128, _mm_storel_epi64,
+ _mm_setzero_si128, _mm_set_epi64, _mm_set_epi32, _mm_set_epi16,
+ _mm_set_epi8, _mm_set1_epi64, _mm_set1_epi32, _mm_set1_epi16,
+ _mm_set1_epi8, _mm_setr_epi64, _mm_setr_epi32, _mm_setr_epi16,
+ _mm_setr_epi8, _mm_unpacklo_epi64,_mm_set_moveq): New functions.
+ (_mm_insert_epi16): Fix.
+
+2002-10-21 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_reverse_condition): Handle
+ unsafe math reversals correctly for RTL generation.
+ (output_cbranch): Replace rs6000_reverse_condition call
+ by its former definition.
+
+2002-10-21 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (x86_64_sign_extended_value): Add allow_rip
+ argument. In CM_SMALL_PIC model consider SYMBOL_REFs binding locally or
+ from constant pool or LABEL_REFs as sign extended if allow_rip.
+ Change all +-1GB limits to +-16MB.
+ (x86_64_general_operand, x86_64_szext_general_operand,
+ x86_64_nonmemory_operand, x86_64_movabs_operand,
+ x86_64_szext_nonmemory_operand, x86_64_immediate_operand,
+ legitimate_address_p, ix86_expand_int_movcc): Update callers.
+ (local_symbolic_operand): Don't allow offsets bigger than +-16MB
+ in CM_SMALL_PIC model.
+ (legitimate_pic_address_disp_p): Don't check offsets before
+ calling local_symbolic_operand.
+ (legitimize_pic_address): Force offsets bigger than +-16MB into
+ register.
+ * config/i386/i386.h (EXTRA_CONSTRAINT, CONST_COSTS): Likewise.
+ * config/i386/i386-protos.h (x86_64_sign_extended_value): Update
+ prototype.
+
+ * configure.in: Test for @GOTNTPOFF and @INDNTPOFF on IA-32 too.
+ Add x86-64 test. Set tls_first_minor to 14 on IA-32 and x86-64.
+ * configure: Rebuilt.
+ * config/i386/i386.c (x86_64_sign_extended_value): Don't allow TLS
+ SYMBOL_REFs unless enclosed in UNSPEC. Handle UNSPEC_DTPOFF,
+ UNSPEC_GOTNTPOFF and UNSPEC_NTPOFF.
+ (legitimate_address_p): Allow foo@dtpoff(base) even on TARGET_64BIT
+ -fpic.
+ (ix86_encode_section_info): Don't ever generate TLSGD or TLSLD for
+ non-pic code if TARGET_64BIT.
+ (legitimize_address): Generate 64-bit TLS sequences.
+ (output_pic_addr_const): Support x86-64 TLS operators.
+ (i386_output_dwarf_dtprel): Output 64-bit DTPOFF as .long f@DTPOFF, 0.
+ (print_operand_address): Use %fs instead of %gs on TARGET_64BIT.
+ Don't append (%rip) in 64-bit TLSGD and TLSLD sequences.
+ (output_addr_const_extra): Support x86-64 TLS operators.
+ (maybe_get_pool_constant): Handle TARGET_64BIT -fpic.
+ (ix86_tls_get_addr): Use __tls_get_addr on TARGET_64BIT
+ unconditionally.
+ * config/i386/i386.md (*tls_global_dynamic_gnu): Renamed to...
+ (*tls_global_dynamic_32_gnu): ..., add !TARGET_64BIT.
+ (*tls_global_dynamic_sun): Renamed to...
+ (*tls_global_dynamic_32_sun): ..., add !TARGET_64BIT.
+ (tls_global_dynamic): Renamed to...
+ (tls_global_dynamic_32): ... this.
+ (tls_global_dynamic_64, *tls_global_dynamic_64): New.
+ (*tls_local_dynamic_base_dynamic_gnu): Renamed to...
+ (*tls_local_dynamic_base_dynamic_32_gnu): ..., add !TARGET_64BIT.
+ (*tls_local_dynamic_base_dynamic_sun): Renamed to...
+ (*tls_local_dynamic_base_dynamic_32_sun): ..., add !TARGET_64BIT.
+ (tls_local_dynamic_base_dynamic): Renamed to...
+ (tls_local_dynamic_base_dynamic_32): ... this.
+ (tls_local_dynamic_base_dynamic_64,
+ *tls_local_dynamic_base_dynamic_64): New.
+ (*tls_local_dynamic_once): Renamed to...
+ (*tls_local_dynamic_32_once): ... this.
+
+2002-10-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * libgcc2.c: Inline __udiv_w_sdiv when compiling __udivdi3,
+ __divdi3, __umoddi3, or __moddi3.
+
+2002-10-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * c-opts.c (missing_arg): Use cl_options[opt_index].opt_code
+ instead of just opt_index as switch expression.
+
+ * calls.c (store_one_arg): Change type of 'excess_align'
+ to unsigned int.
+
+ * profile.c (output_gcov_string): Change type of 'temp'
+ to size_t.
+
+2002-10-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/fixdfdi.h (__fixunsdfdi, __fixdfdi): Add prototypes.
+ (__fixunssfdi, __fixsfdi): Likewise.
+ * config/s390/s390.c (s390_single_hi): Initialize 'value'.
+ (s390_single_qi): Likewise.
+ (s390_emit_epilogue): Initialize 'offset'. Remove signed vs.
+ unsigned comparison warning.
+ (s390_return_addr_rtx): New function.
+ * config/s390/s390-protos.h (s390_return_addr_rtx): Declare it.
+ * config/s390/s390.h (RETURN_ADDR_RTX): Use it.
+ (HARD_REGNO_MODE_OK): Rewrite condition to silence warnings.
+
+2002-10-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_output_mi_vcall_thunk): New function.
+ (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Define target hook.
+ (s390_output_mi_thunk): Remove.
+ (TARGET_ASM_OUTPUT_MI_THUNK): Remove.
+
+2002-10-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (N_REG_CLASSES): Parenthesize.
+
+2002-10-20 Zack Weinberg <zack@codesourcery.com>
+
+ * config/i386/i386.c (ix86_function_ok_for_sibcall): Fix an
+ inverted test in the conditional determining the possibility
+ of sibcalls in PIC mode.
+
+2002-10-20 Richard Henderson <rth@redhat.com>
+
+ * target.h (struct gcc_target): Line wrap.
+
+ * config/alpha/alpha.c (alpha_output_mi_thunk_osf): Static.
+ (TARGET_ASM_OUTPUT_MI_THUNK): Define here...
+ * config/alpha/alpha.h: ... not here.
+ * config/alpha/alpha-protos.h: Update.
+
+ * config/arm/arm.c, config/arm/arm.h, config/arm/arm-protos.h
+ config/cris/cris-protos.h, config/cris/cris.c, config/cris/cris.h,
+ config/frv/frv-protos.h, config/frv/frv.c, config/frv/frv.h,
+ config/i386/i386-protos.h, config/i386/i386.c, config/i386/openbsd.h,
+ config/i386/unix.h, config/i960/i960-protos.h, config/i960/i960.c,
+ config/i960/i960.h, config/ia64/ia64-protos.h, config/ia64/ia64.c,
+ config/ia64/ia64.h, config/m68k/linux.h, config/m68k/m68k-protos.h,
+ config/m68k/m68k.c, config/m68k/netbsd-elf.h, config/m68k/openbsd.h,
+ config/mmix/mmix-protos.h, config/mmix/mmix.c, config/mmix/mmix.h,
+ config/pa/pa-protos.h, config/pa/pa.c, config/pa/pa.h,
+ config/s390/s390-protos.h, config/s390/s390.c, config/s390/s390.h,
+ config/sparc/openbsd.h, config/sparc/sparc-protos.h,
+ config/sparc/sparc.c, config/sparc/sparc.h,
+ config/stormy16/stormy16-protos.h, config/stormy16/stormy16.c,
+ config/stormy16/stormy16.h: Similarly.
+
+ * config/m68k/m68k.c (m68k_output_mi_thunk): Replicate mnemonic
+ selection logic from call patterns.
+
+2002-10-20 Mark Mitchell <mark@codesourcery.com>
+
+ * config/m68k/m68k.c (m68k_output_mi_thunk): Fix typo.
+
+2002-10-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ PR other/8202
+ * i386.c (ix86_init_mmx_sse_builtins, ix86_expand_builtin): Define and
+ expand __builtin_ia32_pslldqi128 and __builtin_ia32_psrldqi128.
+ * i386.h (IX86_BUILTIN_PSLLDQI128, IX86_BUILTIN_PSRLDQI128): New.
+ * xmmintrin.h (_mm_srli_si128, _mm_slli_si128): New.
+
+2002-10-20 Roger Sayle <roger@eyesopen.com>
+
+ PR c/761
+ * toplev.c (flag_unsafe_profile_arcs): Remove.
+ (flag_bounded_pointers): Remove.
+ (flag_bounds_check): Correct comments.
+ (lang_independent_options): Remove -funsafe-profile-arcs and
+ -fbounded-pointers. Correct -fbounds-check comments.
+
+ * flags.h: Correct flag_schedule_interblock comments.
+ (flag_bounded_pointers): Remove prototype.
+ (flag_bounds_check): Correct comments.
+
+ * c-opts.c (c_common_init_options): No need to mark
+ flag_bounds_check as unspecified.
+ (c_common_post_options): And no need to set it from
+ flag_bounded_pointers if its still unspecified.
+
+ * doc/invoke.texi: Fix some overfull hboxes in "make dvi".
+ Document --version, -feliminate-dwarf-2-dups, -fno-sched-interblock,
+ -fno-sched-spec, -fsched-spec-load, -fsched-spec-load-dangerous,
+ -fsched-verbose=n, -fno-branch-count-reg and -fbounds-check.
+
+Sat Oct 19 22:02:28 2002 Alexandre Oliva <aoliva@redhat.com>
+ Angela Marie Thomas <angela@releasedominatrix.com>
+ Brendan Kehoe <brendan@zen.org>
+ Nick Clifton <nickc@redhat.com>
+ Andrew Haley <aph@redhat.com>
+
+ * configure.in (--with-sysroot): New. Don't inhibit libc if
+ given. AC_SUBST TARGET_SYSTEM_ROOT, TARGET_SYSTEM_ROOT_DEFINE
+ and CROSS_SYSTEM_HEADER_DIR.
+ * configure: Rebuilt.
+ * Makefile.in (CROSS_SYSTEM_HEADER_DIR): Set in configure.
+ (TARGET_SYSTEM_ROOT): New.
+ (DRIVER_DEFINES): Define CROSS_INCLUDE_DIR from
+ CROSS_SYSTEM_HEADER_DIR.
+ (install-gcc-tooldir): New target.
+ (stmp-fixinc): Do not create $(libsubdir), but rather bail out
+ if SYSTEM_HEADER_DIR does not exist and it's not the default
+ sys-include directory.
+ (deduced.h, stmp-fixproto): Quote SYSTEM_HEADER_DIR properly.
+ (install-mkheaders): Likewise.
+ * gcc.c (target_system_root): New variable.
+ (add_sysrooted_prefix): New function.
+ (process_command): Recompute run-time target_system_root from
+ gcc_exec_prefix, keeping it unchanged if the relocated sysroot
+ does not exist.
+ (do_spec_1): Process 'R' spec.
+ (main): Add md_exec_prefix to exec_prefixes regardless of
+ startfile_prefix_spec. Use add_sysrooted_prefix for
+ startfile_prefixes, and don't skip the default ones when cross
+ compiling with sysroot enabled. Removed unused case of
+ non-absolute standard_startfile_prefix.
+ * config/interix.h: Remove the only potential, yet disabled,
+ occurrence of non-absolute (empty) standard_startfile_prefix.
+ * config/sh/linux.h (LIB_SPEC): Add -rpath-link in non-static
+ linking.
+ * config/mips/linux.h (LIB_SPEC): Define as in sh/linux.h.
+ * doc/install.texi (--with-sysroot): Document.
+ (--with-headers, --with-libs): Deprecate.
+
+2002-10-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * alpha-protos.h (alpha_output_mi_thunk_osf): Update signature to
+ match target.h.
+ * arm-protos.h, arm.c (arm_output_mi_thunk): Likewise.
+ * cris-protos.h, cris.c (cris_asm_output_mi_thunk): Likewise.
+ * frv-protos.h, frv.c (frv_asm_output_mi_thunk): Likewise.
+ * i386-protos.h, i386.c (x86_output_mi_vcall_thunk,
+ x86_output_mi_thunk): Likewise.
+ * i960-protos.h, i960.c (i960_output_mi_thunk): Likewise.
+ * ia64-protos.h, ia64.c (ia64_output_mi_thunk): Likewise.
+ * m68k-protos.h, m68k.c (m68k_output_mi_thunk): Likewise.
+ * mmix-protos.h, mmix.c (mmix_asm_output_mi_thunk): Likewise.
+ * rs6000-protos.h, rs6000.c (output_mi_thunk): Likewise.
+ * s390-protos.h, s390.c (s390_output_mi_thunk): Likewise.
+ * stormy16-protos.h, stormy16.c (xstormy16_asm_output_mi_thunk):
+ Likewise.
+ * vax-protos.h, vax.c (vax_output_mi_thunk): Likewise.
+
+ * target.h (gcc_target): Update output_mi_thunk and
+ output_mi_vcall_thunk to take a HOST_WIDE_INT delta and
+ vcall_index.
+
+ * config/alpha/alpha.c: Replace ASM_OUTPUT_MI_THUNK with
+ TARGET_ASM_OUTPUT_MI_THUNK in comments.
+ * config/alpha/vms.h (ASM_OUTPUT_MI_THUNK): Don't #undef it.
+ (TARGET_ASM_OUTPUT_MI_THUNK): #undef it.
+ * config/frv/frv.h (DEFAULT_VTABLE_THUNKS): Remove definition.
+ * config/i386/i386-protos.h (x86_output_mi_vcall_thunk): Update
+ signature.
+ * config/i386/i386.c (x86_output_mi_vcall_thunk): Likewise.
+ * config/i386/openbsd.h: Replace ASM_OUTPUT_MI_THUNK with
+ TARGET_ASM_OUTPUT_MI_THUNK in comments.
+ * config/i960/i960.h (ASM_OUTPUT_MI_THUNK): Don't define.
+ (TARGET_ASM_OUTPUT_MI_THUNK): Do define.
+ * config/m68k/openbsd.h: Replace ASM_OUTPUT_MI_THUNK with
+ TARGET_ASM_OUTPUT_MI_THUNK in comments.
+ * config/rs6000/rs6000.c (rs6000_ra_ever_killed): Remove #ifdef
+ ASM_OUTPUT_MI_THUNK and replace with check of targetm.
+
+ * doc/tm.texi (TARGET_ASM_OUTPUT_MI_THUNK): Update signature.
+ (TARGET_ASM_OUTPU_MI_VCALL_THUNK): Likewise.
+
+2002-10-19 Brad Lucier <lucier@math.purdue.edu>
+
+ * real.c (do_add): Fix 0+0 sign corner case.
+ (do_divide): Fix Inf/0 corner case.
+
+Sun Oct 20 00:31:31 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (classify_argument): Pass MMX arguments in memory
+ (ix86_expand_builtin): Expand proper address mode for cflush.
+ * i386.md (movdqa): Fix typo.
+ (sse2_cflush): Accept DImode addresses.
+
+ * xmmintrin.h (_mm_sqrt_sd): Accept two arguments.
+ (_mm_max_sd): Fix pasto.
+ (_mm_storeh_pd, _mm_storel_pd): Fix.
+
+ * i386.c (bdesc_comi): Fix to match specification.
+ (ix86_expand_sse_comi): Emit the comparison properly.
+ * i386.md (sse_comi, sse2_comi, sse_ucomi, sse2_ucomi):
+ Do not use comparison operator.
+ (vnmaskcmp): Fix template.
+
+ * xmmintrin.h (_mm_cvtps_pi16): Fix.
+
+2002-10-19 Sebastian Pop <s.pop@laposte.net>
+
+ * dependence.c : Removed.
+ * Makefile.in : Remove dependence.o.
+
+Sat Oct 19 10:46:52 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * mmintrin.h (__m64): typedef it to v2si.
+ (_mm_cvtsi32_si64, _mm_cvtsi32_si64_mm_sll_pi16,
+ _mm_sll_pi32, _mm_sll_pi64, _mm_slli_pi64, _mm_sra_pi16,
+ _mm_sra_pi32, _mm_srl_pi16, _mm_srl_pi32, _mm_srl_pi64,
+ _mm_srli_pi64, _mm_and_si64, _mm_andnot_si64,
+ _mm_or_si64, _mm_xor_si64): Add neccesary casts.
+ * xmmintrin.h (_mm_setzero_si64): Likewise.
+
+ * i386.h (ALIGN_MODE_128): Update comment; add missing modes
+ (SSE_REG_MODE_P, MMX_REG_MODE_P): New macros.
+
+ PR target/7693
+ Patch by Shawn Wagner
+ * mmintrin.h: Replace pi64 by si64.
+
+2002-10-18 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.md (movdf_hardfloat32): Order alternatives consistently.
+ Use length of 4 not *.
+ (movdf_hardfloat64): Same. Support DFmode moves to/from CTR/LR.
+ (movdf_softfloat64): Likewise.
+ (movdi_internal32): Use length of 4 not *.
+ (movti_power): Same.
+ (ctrsi, ctrdi): Same.
+
+2002-10-18 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (start_decl): Point users of the old initialized-
+ typedef extension at __typeof__.
+
+2002-10-18 Richard Henderson <rth@redhat.com>
+
+ * real.c (cmp_significand_0, rtd_divmod, ten_to_mptwo): New.
+ (real_to_decimal): Re-implement using the logic from the
+ gcc 3.2 etoasc. Comment heavily.
+ (div_significands): Simplify loop startup and comparison logic.
+
+2002-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * target-def.h (TARGET_ASM_OUTPUT_MI_THUNK): Default to NULL.
+ (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Likewise.
+ (TARGET_ASM_OUT): Add them.
+ * target.h (asm_out): Add output_mi_thunk and
+ output_mi_vcall_thunk.
+ * config/alpha/alpha.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/arm/arm-protos.h (arm_output_mi_thunk): Declare.
+ * config/arm/arm.c (arm_output_mi_thunk): Define.
+ * config/arm/arm.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/cris/cris.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/frv/frv.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/i386/i386-protos.h (x86_output_mi_thunk): Adjust
+ prototype.
+ (x86_output_mi_vcall_thunk): Declare.
+ * config/i386/i386.c (override_options): Clear
+ output_mi_vcall_thunk in 64-bit mode.
+ (ix86_fntype_regparm): New function.
+ (ix86_return_pops_args): Use it.
+ (ia32_this_parameter): New function.
+ (x86_output_mi_vcall_thunk): New function.
+ (x86_output_mi_thunk): Use it
+ * config/i386/unix.h (TARGET_ASM_OUTPUT_MI_THUNK): Adjust.
+ (TARGET_ASM_OUTPUT_MI_VCALL_THUNK): Define.
+ * config/i960/i960-protos.h (i960_output_mi_thunk): Declare.
+ * config/i960/i960.c (i960_output_mi_thunk): New function.
+ * config/i960/i960.h (ASM_OUTPUT_MI_THUNK): Adjust.
+ * config/ia64/ia64-protos.h (ia64_output_mi_thunk): Declare.
+ * config/ia64/ia64.c (ia64_output_mi_thunk): Define.
+ * config/ia64/ia64.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/m68k/m68k-protos.h (m68k_output_mi_thunk): New function.
+ * config/m68k/linux.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/m68k/netbsd-elf.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/mmix/mmix.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/pa/pa.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/rs6000/sysv4.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/s390/s390-protos.h (s390_output_mi_thunk): Declare.
+ * config/s390/s390.c (s390_output_mi_thunk): Define.
+ * config/s390/s390.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/sparc/sparc.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/stormy16/stormy16.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * config/vax/vax-protos.h (vax_output_mi_thunk): Declare.
+ * config/vax/vax.c (vax_output_mi_thunk): Define.
+ * config/vax/vax.h (ASM_OUTPUT_MI_THUNK): Rename to ...
+ (TARGET_ASM_OUTPUT_MI_THUNK): ... this.
+ * doc/tm.texi: Adjust documentation.
+
+2002-10-18 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/netbsd.h (NETBSD_ENABLE_EXECUTE_STACK): Define
+ __enable_execute_stack function.
+ * config/alpha/netbsd.h (TRANSFER_FROM_TRAMPOLINE): Define
+ as NETBSD_ENABLE_EXECUTE_STACK.
+ * config/i386/netbsd-elf.h (TRANSFER_FROM_TRAMPOLINE): Ditto.
+ * config/i386/netbsd.h (TRANSFER_FROM_TRAMPOLINE): Ditto.
+ * config/i386/netbsd64.h (TRANSFER_FROM_TRAMPOLINE): Ditto.
+ * config/sparc/netbsd-elf.h (TRANSFER_FROM_TRAMPOLINE): Ditto.
+ * config/sparc/netbsd.h (TRANSFER_FROM_TRAMPOLINE): Ditto.
+
+2002-10-18 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/i386/i386.c (x86_initialize_trampoline): Emit a call
+ to __enable_execute_stack with the address of the trampoline
+ if TRANSFER_FROM_TRAMPOLINE is defined.
+ * config/i386/i386.h (TARGET_64BIT): Expand to a compile-time
+ constant if building libgcc2.
+
+Thu Oct 17 17:40:05 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (pentium4_cost): Fix according to Intel recommendations.
+ (ix86_memory_move_cost): Fix for 64bit compilation.
+
+2002-10-17 Roger Sayle <roger@eyesopen.com>
+
+ * doc/c-tree.texi: Update description of COND_EXPR tree nodes.
+
+2002-10-17 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.h (HARD_REGNO_MODE_OK): Allow arbitrary modes
+ in CTR/LR/MQ.
+ * config/rs6000/rs6000.md (movcc_internal1): Support CCmode moves
+ to/from CTR/LR/MQ.
+ (movsf_hardfloat): Support SFmode moves to/from CTR/LR/MQ.
+ (movsf_softfloat): Likewise.
+
+2002-10-17 Janis Johnson <janis187@us.ibm.com>
+
+ * Makefile.in (site.exp): Add ALT_CXX_UNDER_TEST and COMPAT_OPTIONS.
+
+2002-10-17 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/alpha/alpha.c (alpha_initialize_trampoline): Use
+ tramp, not addr, to pass the trampoline address to
+ __enable_execute_stack.
+
+Thu Oct 17 18:40:47 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * mmintrin.h: Guard by __MMX__
+ * xmmintrin.h: Guard by __SSE__
+
+ PR other/8062
+ * xmmintrin.h (_MM_SHUFFLE2): New macro.
+ (_mm_load*_?d): New functions.
+ (_mm_set*_?d): New functions.
+ (_mm_store*_?d): New functions.
+
+Wed Oct 16 15:01:29 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ Really commit patch announced at Oct 14
+ PR c/7344
+ * predict.c (can_predict_insn_p): New function.
+ (estimate_probability): Avoid unnecesary work.
+ (process_note_prediction): Likewise.
+ * toplev.c (rest_of_compilation): Account early branch prediction pass
+ as TV_BRANCH_PROB.
+
+ PR other/8048
+ Found by Ian Ollmann
+ * xmmintrin.h (_mm_shuffle_pd): Fix typo.
+ (_mm_load?_pd): Likewise.
+ (_mm_store?_pd): Likewise.
+
+ PR target/7386
+ * i386.c (builtin_description):Drop cmpg[te]s[sd].
+ * xmmintrin.h (__mm_cmpg[te]_s[sd]): Rewrite using
+ swapped alternative.
+
+ PR opt/7630
+ * reload1.c (reload_inner_reg_of_subreg): New argument output;
+ (push_reload): Update call.
+
+2002-10-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * config.gcc (mips*-*-*): Add OBJECT_FORMAT_ELF to $tm_defines
+ if using mips/elf.h or mips/elf64.h.
+ * config/mips/elf.h (OBJECT_FORMAT_ELF): Remove.
+ * config/mips/elf64.h (OBJECT_FORMAT_ELF): Remove.
+
+2002-10-16 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (function_arg): Set inner mode of V1DI to
+ SI.
+
+2002-10-16 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/linux.h (ASM_DOUBLE, _ASM_OUTPUT_LONG): Remove.
+ (LPREFIX): Likewise.
+ (ASM_COMMENT_START, LOCAL_LABEL_PREFIX, ASM_FORMAT_PRIVATE_NAME,
+ ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT,
+ ASM_OUTPUT_ALIGN, ASM_OUTPUT_SKIP, ASM_OUTPUT_ALIGNED_BSS,
+ TEXT_SECTION_ASM_OP, DATA_SECTION_ASM_OP, BSS_SECTION_ASM_OP,
+ GLOBAL_ASM_OP, ASM_OUTPUT_MI_THUNK): Move to s390.h.
+
+ * config/s390/s390.h (ASM_COMMENT_START, LOCAL_LABEL_PREFIX,
+ ASM_FORMAT_PRIVATE_NAME, ASM_OUTPUT_ALIGN, ASM_OUTPUT_SKIP,
+ ASM_OUTPUT_ALIGNED_BSS, TEXT_SECTION_ASM_OP, DATA_SECTION_ASM_OP,
+ BSS_SECTION_ASM_OP): Move from linux.h.
+ (ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT): Likewise.
+ Also, use ASM_GENERATE_INTERNAL_LABEL instead of LPREFIX.
+
+ * config/s390/s390.c (s390_function_profiler): Use
+ ASM_GENERATE_INTERNAL_LABEL instead of LPREFIX.
+
+2002-10-15 Eric Christopher <echristo@redhat.com>
+
+ * stor-layout.c (layout_type): Call GET_MODE_BITSIZE once.
+ * java/parse.y (obtain_incomplete_type): Make pointer
+ ptr_mode.
+
+2002-10-15 Richard Henderson <rth@redhat.com>
+
+ * real.c (real_to_decimal): Accept BUF_SIZE and CROP_TRAILING_ZEROS
+ as arguments. Bound DIGITS by the available buffer size.
+ (real_to_hexadecimal): Likewise.
+ * real.h (real_to_decimal, real_to_hexadecimal): Update prototypes.
+ (REAL_VALUE_TO_DECIMAL): Remove.
+ * c-common.c, c-pretty-print.c, print-rtl.c, print-tree.c,
+ sched-vis.c, config/arc/arc.c, config/c4x/c4x.c, config/fr30/fr30.c,
+ config/i370/i370.h, config/i386/i386.c, config/i960/i960.c,
+ config/ip2k/ip2k.c, config/m32r/m32r.c, config/m68hc11/m68hc11.c,
+ config/m68k/hp320.h, config/m68k/m68k.h, config/m68k/sun2o4.h,
+ config/m68k/sun3.h, config/mips/mips.c, config/ns32k/ns32k.c,
+ config/pdp11/pdp11.h, config/vax/vax.h: Update all callers to
+ use real_to_decimal directly, and with the proper arguments.
+ * doc/tm.texi (REAL_VALUE_TO_DECIMAL): Remove.
+
+2002-10-15 Jim Wilson <wilson@redhat.com>
+
+ * reload1.c (merge_assigned_reloads): After converting overlapping
+ reloads to RELOAD_OTHER, abort if there are now conflicting reloads.
+
+ * config/i386/i386.md (adddi3_1): Add call to ix86_binary_operator_ok.
+
+Tue Oct 15 22:08:35 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * expr.c (do_tablejump): Fix typo in my previous commit.
+
+2002-10-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/vr.h (DRIVER_SELF_SPECS): Change %<mgp32 to %{<mgp32}.
+
+2002-10-15 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_split_branches): Add return
+ value. Add parameters TEMP_REG and TEMP_USED. Use unspec 104.
+
+ (find_base_register_in_addr): New function.
+ (find_base_register_ref): New function.
+ (replace_base_register_ref): New function.
+
+ (struct constant_pool): Add members pool_insn, insns, and anchor.
+ Remove member last_insn.
+ (s390_start_pool): Initialize them.
+ (s390_end_pool): Emit pool placeholder insn.
+ (s390_add_pool_insn): New function.
+ (s390_find_pool): Use insns bitmap instead of addresses.
+ (s390_dump_pool): Replace placeholder insn. Emit anchor.
+ Replace unspec 104 by local-pool-relative references.
+ (s390_output_constant_pool): Output anchor label if required.
+ (s390_output_symbolic_const): Handle unspec 104 and 105.
+ (s390_add_pool): Remove, replace by ...
+ (s390_add_constant, s390_find_constant): ... these new functions.
+ (s390_add_anchor): New function.
+
+ (s390_chunkify_pool): Delete, replace by ...
+ (s390_chunkify_start, s390_chunkify_finish,
+ s390_chunkify_cancel): ... these new functions.
+ (s390_optimize_prolog): Add parameter TEMP_REGNO.
+ Recompute register live data for special registers.
+ (s390_fixup_clobbered_return_reg): New function.
+ (s390_machine_dependent_reorg): Rewrite to use new
+ s390_chunkify_... routines.
+
+ config/s390/s390.md ("reload_base"): Rename to ...
+ ("reload_base_31"): ... this.
+ ("reload_base_64"): New insn.
+ ("reload_base2"): Remove.
+ ("reload_anchor"): New insn.
+ ("pool"): New insn.
+
+ s390.c (s390_pool_overflow): Remove.
+ s390.h (s390_pool_overflow): Likewise.
+ s390.md ("cjump", "icjump", "doloop_si"): Remove s390_pool_overflow.
+
+Tue Oct 15 16:51:04 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (movv8qi_i+2): Don't split if source is -1.
+
+2002-10-15 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/install.texi: Formatting changes for conformance to HTML 4.01.
+
+2002-10-15 Ulrich Weigand <uweigand@de.ibm.com>
+
+ PR opt/7409
+ * loop.c (loop_regs_scan): Mark registers used for function
+ argument passing as MAY_NOT_OPTIMIZE.
+
+Mon Oct 14 19:22:19 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * gcov-io.h (gcov_info): Fix type.
+ * profile.c (create_profiler): Fix type mismatch.
+
+Mon Oct 14 20:33:12 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (movv2di_internal): New pattern.
+ (movv2df_internal, movv8hi_internal, movv16qi_internal): Fix predicate.
+ (movv2di): New expander.
+ * i386.c (ix86_preferred_reload_class): Return NO_REGS for vector operands.
+
+ * i386.c (ix86_expand_timode_binop_builtin): Delete.
+ (builtin_description): Add SSE1 logicals; rename SSE2 logicals.
+ (ix86_init_mmx_sse_builtins): Kill SSE1 logicals.
+ (ix86_expand_builtin): Likewise.
+ * i386.h (sse_andti4_df_1, sse_andti3_df_2, sse_andti3_sf_1, sse_andti3_sf_2,
+ sse_andti3,
+ sse_andnti4_df_1, sse_andti3_df_2, sse_andti3_sf_1, sse_andti3_sf_2,
+ sse_andnti3,
+ sse_orti4_df_1, sse_orti3_df_2, sse_orti3_sf_1, sse_orti3_sf_2,
+ sse_orti3,
+ sse_xorti4_df_1, sse_xorti3_df_2, sse_xorti3_sf_1, sse_xorti3_sf_2,
+ sse_xorti3): Kill.
+ (sse_andv4sf3, sse_andnv4sf3, sse_orv2df3, sse_xorv2df3, sse_andv2df3,
+ sse_andnv2df3, sse_orv2df3, sse_xorv2df3): New expanders.
+ (*sse_andv4sf3, *sse_andnv2df3, *sse_orv4sf3, *sse_xorv4sf3, *sse_andv2df3,
+ *sse_andnv2df3, *sse_orv2df3, *sse_xorv2df3): New patterns.
+ (*sse_andsf3, *sse_andndf3, *sse_ordf3, *sse_xordf3, *sse_anddf3,
+ *sse_andndf3, *sse_orv2df3, *sse_xorv2df3): New patterns.
+
+ * xmmintrin.h (__m128i): Define as __v2di.
+
+ PR c++/6419
+ (expand_expr): Use DECL_RTL_SET_P.
+
+2002-10-14 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (simplify_set): Treat MODE_CC registers like cc0.
+
+2002-10-14 Roger Sayle <roger@eyesopen.com>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * config/i386/i386.c (k6_cost): Correct typo.
+
+2002-10-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR optimization/6631
+ * alias.c (objects_must_conflict_p): Check honor_readonly when
+ examining TYPE_READONLY.
+ * function.c (assign_stack_temp_for_type): Likewise.
+
+2002-10-14 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ * config/alpha/alpha.md (extendsidi2_nofix, extendsidi2_fix):
+ Swap zero extension arguments.
+ (umaxhi3): Fix instruction class.
+ PR target/7211
+ (prefetch): Fix prefetch instructions.
+ PR target/7238
+ (pkwb): Fix output constraint.
+
+2002-10-14 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mips/mips.c (print_operand): Increase buffer size for
+ real numbers.
+
+2002-10-14 Richard Henderson <rth@redhat.com>
+
+ PR opt/8165
+ * gcse.c (adjust_libcall_notes): Revert last change.
+ * simplify-rtx.c (simplify_replace_rtx): Handle LO_SUM.
+
+2002-10-14 Andrew Haley <aph@redhat.com>
+
+ * tree-inline.c (remap_block): All local class initialization
+ flags go in the outermost scope.
+ (expand_call_inline): Call java_inlining_map_static_initializers.
+ (expand_call_inline): Call java_inlining_merge_static_initializers.
+ * java/lang.c (merge_init_test_initialization): New.
+ (java_inlining_merge_static_initializers): New.
+ (inline_init_test_initialization): New.
+ (java_inlining_map_static_initializers): New.
+
+ * tree-inline.c (expand_call_inline): Convert retvar to expected
+ type.
+
+2002-10-14 Graham Stott <graham.stott@btinternet.com>
+
+ * stmt.c (decl_conflicts_with_clobbers_p): Add REG_P check.
+
+2002-10-14 Aldy Hernandez <aldyh@redhat.com>
+
+ * stmt.c: Fix typo in comment.
+
+Mon Oct 14 11:35:49 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * c-common.c (c_common_type_for_mode): Add V2HImode case.
+ * tree.c (build_common_tree_nodes_2): Initialize
+ unsigned_V2HI_type_node and V2HI_type_node.
+ * tree.h (enum tree_index): Add TI_UV2HI_TYPE and TI_V2HI_TYPE.
+ (unsigned_V2HI_type_node, V2HI_type_node): Define.
+
+2002-10-14 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.h (ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP):
+ Handle TARGET_64BIT.
+
+2002-10-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/vr.h (DRIVER_SELF_SPECS): Define.
+ * config/mips/t-vr (MULTILIB_OPTIONS): Remove mlong32.
+ (MULTILIB_DIRNAMES): Remove long32.
+ (MULTILIB_EXCEPTIONS): Don't build -mabi=32 -mgp32 multilibs.
+ (MULTILIB_REDUNDANT_DIRS): Remove.
+
+2002-10-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/tm.texi (DRIVER_SELF_SPECS): Document.
+ * gcc.c (driver_self_specs): New variable.
+ (do_self_spec): New function.
+ (main): Use it to process driver_self_specs.
+
+2002-10-13 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (ix86_function_ok_for_sibcall): Reject
+ indirect sibcalls when regparm >= 3.
+
+ * config/i386/i386.c (sibcall_insn_operand): New.
+ * config/i386/i386.h (PREDICATE_CODES): Update.
+ * config/i386/i386-protos.h: Update.
+ * config/i386/i386.md (sibcall_1, sibcall_value_1): Use it.
+
+ * rtl.c (shallow_copy_rtx): Use memcpy for the entire node.
+
+2002-10-12 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_binary_operation) [ASHIFTRT]: Optimize
+ arithmetic right shifts of ~0 during RTL simplifications.
+
+2002-10-12 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/7862
+ PR preprocessor/8190
+ * gcc.c (cpp_unique_options): Don't delete .d files.
+ Remove stray whitespace.
+
+2002-10-12 Naohiko Shimizu <pshimizu@fa2.so-net.ne.jp>
+
+ * pdp11.h (ASM_OUTPUT_SKIP): Add preceding 0 for octal constant.
+ (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL): Likewise.
+ * pdp11.c (pdp11_output_function_prologue): 0%o -> %#o.
+ (pdp11_output_function_epilogue, output_ascii): Likewise.
+ (output_addr_const_pdp11): Likewise.
+ * pdp11.md (movdi): Use offsetable memory for floating store.
+ (lshrsi3, negsi2): Delete irrelevant comment.
+
+2002-10-11 Andreas Bauer <baueran@in.tum.de>
+
+ * config/i386/i386.c (ix86_function_ok_for_sibcall): Allow
+ indirect calls to be sibcall optimized.
+ * config/i386/i386.md (sibcall_1): New.
+ (call_1): Add no-sibcalls condition.
+ (sibcall_value_1): New.
+ (call_value_1): Add no-sibcalls condition.
+
+2002-10-11 Eric Christopher <echristo@redhat.com>
+
+ * output.h (default_valid_pointer_mode): Declare.
+ * varasm.c (default_valid_pointer_mode): Define.
+ * target-def.h (TARGET_VALID_POINTER_MODE): Use.
+ * target.h: Ditto.
+ * tree.c (build_pointer_type_for_mode): New function.
+ (build_pointer_type): Use.
+ (build_reference_type_for_mode): New function.
+ (build_reference_type): Use.
+ * tree.h: Declare new functions.
+ * c-common.c (handle_mode_attribute): Use new functions, check
+ for type.
+ * stor-layout.c (layout_type): Depend on machine mode for
+ REFERENCE_TYPE and POINTER_TYPE.
+ * dwarf2out.c (simple_type_size_in_bits): Move upward in file.
+ (modified_type_die): Use instead of PTR_SIZE for POINTER_TYPE
+ and REFERENCE_TYPE.
+ * config/mips/mips.c (mips_valid_pointer_mode): New function.
+ (TARGET_VALID_POINTER_MODE): Use and define.
+ * config/mips/mips-protos.h (mips_valid_pointer_mode): Declare.
+
+2002-10-11 Geoffrey Keating <geoffk@apple.com>
+
+ * cse.c (mention_regs): Set SUBREG_TICKED to the register number,
+ not the address of the REG.
+ (struct cse_reg_info): Make subreg_ticked unsigned.
+
+2002-10-11 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/compat.texi: Add info about C++ libraries.
+
+2002-10-11 Richard Henderson <rth@redhat.com>
+
+ PR opt/8165
+ * gcse.c (adjust_libcall_notes): Also adjust notes for INSN.
+
+2002-10-11 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * cfganal.c (dfs_enumerate_from): Use PARAMS.
+ * genautomata.c (output_insn_code_cases): Likewise.
+ * real.c (real_format): Likewise.
+ * tree.c (tree_size): Revise expressions using TREE_CODE_LENGTH to
+ ensure value is promoted before doing subtraction.
+
+Fri Oct 11 22:22:38 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * calls.c (expand_call): Simplify noreturn call.
+
+ PR c/7344
+ * cfgbuild.c (make_edges): Create edge cache when we do have
+ large jumptable.
+ * expr.c (do_tablejump): Note size of maximal jumptable.
+ * function.c (prepare_function_start): Zero out size.
+ * function.h (function): Add max_jumptable_ents.
+
+ * cfgcleanup.c (insn_match_p): Verify sibcall flag for calls to.
+
+Fri Oct 11 12:34:33 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (movv8qi_i+2): For V8QI destinations, generate V4HI
+ register for mperm_w operation.
+
+Fri Oct 11 10:56:17 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * emit-rtl.c (gen_lowpart_common): When asked to make a vector from
+ an integer, use simplify_gen_subreg.
+
+2002-10-10 Diego Novillo <dnovillo@redhat.com>
+
+ * calls.c (flags_from_decl_or_type): Make extern.
+ (ECF_*): Move ...
+ * rtl.h (ECF_*): ... here.
+ (flags_from_decl_or_type): Declare.
+
+2002-10-10 Roger Sayle <roger@eyesopen.com>
+ Nathan Sidwell <nathan@codesourcery.com>
+
+ * fold-const.c (fold) [RSHIFT_EXPR]: Optimize arithmetic right
+ shifts of the form -1 >> x.
+
+Thu Oct 10 16:52:55 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * cfgcleanup.c (insn_match_p): Verify sibcall flag for calls to.
+
+2002-10-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * extend.texi (Vector Extensions): Remove comment about single
+ element vectors.
+
+2002-10-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fold-const.c (size_htab_hash): Use htab_hash_pointer.
+ * function.c (insns_for_mem_hash): Likewise.
+ * varasm.c (STRHASH): Likewise.
+
+2002-10-10 Stuart Hastings <stuart@apple.com>
+
+ * cse.c (struct cse_reg_info): Add subreg_ticked.
+ (SUBREG_TICKED): New.
+ (get_cse_reg_info): Initialize SUBREG_TICKED.
+ (mention_regs): Use it.
+ (invalidate): Set SUBREG_TICKED.
+ (invalidate_for_call): Likewise.
+ (addr_affects_sp_p): Likewise.
+
+2002-10-10 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.md (tls_local_dynamic_base): Put pic reg
+ into proper operand.
+
+2002-10-10 Denis Chertykov <denisc@overta.ru>
+
+ * config/ip2k/ip2k.c (function_epilogue): Optimize stack
+ deallocation.
+ * config/ip2k/libgcc.S: Combine routines used by function
+ epilogue.
+
+2002-10-10 Jim Wilson <wilson@redhat.com>
+
+ * cse.c (fold_rtx): Don't perform associative optimization for DIV and
+ UDIV.
+
+2002-10-10 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/aix52.h: New file.
+ * config/rs6000/t-aix52: New File.
+ * config.gcc (rs6000-ibm-aix5.1.*): New entry.
+ (rs6000-ibm-aix[56789].*): Default to AIX 5.2.
+
+Thu Oct 10 19:37:54 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ PR target/5610
+ * invoke.texi (-msse-math): Kill
+ (-msse): Add note to mfpmath=sse.
+
+Thu Oct 10 17:08:30 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ PR target/7723
+ * i386.c (ix86_expand_vector_move): Do not generate const0->mem moves.
+
+2002-10-10 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/8179
+ * gcc.c (cpp_options): Add {ansi}, move %{m*} to same location
+ as cc1_options.
+ (default_compilers): Pass debug options when preprocessing
+ stdin.
+
+2002-10-06 Richard Henderson <rth@redhat.com>
+
+ * toplev.c (rest_of_compilation): Revert opt/2960 change.
+
+Wed Oct 9 21:18:43 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (*_cost): Add branch costs.
+ (override_options): set ix86_branch_cost.
+ (ix86_expand_int_movcc): Use BRANCH_COST.
+ * i386.h (costs): Add branch_cost.
+
+2002-10-09 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/7353
+ * c-decl.c (start_decl): Unconditionally issue error for
+ 'typedef foo = bar'.
+ (finish_decl): Remove special case for TYPE_DECL with initializer.
+
+ * doc/extend.texi: Delete "Naming Types" section. Change all
+ cross-references to that section to refer to "Typeof" instead.
+ Add the useful safe-max()-macro example from "Naming Types" to
+ "Typeof", rewritten using that extension. Add some compatibility
+ notes to "Typeof."
+
+2002-10-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * loop.c: Revert 2002-08-15 change.
+ (LOOP_REGNO_NREGS): Ensure type is int.
+
+2002-10-09 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (extenddftf2): Change to define_insn
+ which copies first FPR and clears second.
+ (extendsftf2): Same.
+ (floatditf2): Fix typo.
+ (floatsitf2): Same.
+ (fix_trunctfdi2): Same.
+ (fix_trunctfsi2): Same.
+
+2002-10-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * conflict.c (arc_hash): Change return type to hashval_t.
+ * cselib.c (get_value_hash): Likewise.
+ * genautomata.c (automaton_decl_hash, insn_decl_hash, decl_hash,
+ state_hash, automata_list_hash): Likewise.
+ * read-rtl.c (def_hash): Likewise.
+ * tree.c (type_hash_hash): Likewise.
+
+2002-10-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_ra_ever_killed): Call
+ prologue_epilogue_contains instead of using REG_MAYBE_DEAD notes.
+
+Wed Oct 9 15:54:49 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (ffssi2): Fix emitted code.
+
+2002-10-09 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * cse.c (insn_live_p): Pass insn pattern, not full insn
+ to may_trap_p.
+
+2002-10-09 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppmacro.c (paste_tokens): Only allow / to paste with =.
+
+2002-10-09 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (movdf splitter): Use gen_int_mode on
+ 64-bit hosts.
+ (movtf_internal): Reference correct displacement for second value
+ in memory.
+ (movtf splitter): Correct generation of constants in 64-bit mode.
+
+2002-10-09 Alan Modra <amodra@bigpond.net.au>
+
+ * libgcc2.c (__floatdisf): Properly cure double rounding.
+
+2002-10-09 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-common.c (cb_register_builtins): Define __WCHAR_MAX__.
+ * doc/cpp.texi (Common Predefined Macros): Document.
+
+2002-10-09 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR doc/7484
+ * doc/invoke.texi (Option Summary): List
+ -Wmissing-declarations as a C only option.
+
+2002-10-08 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold) [LROTATE_EXPR, RROTATE_EXPR]: Optimize
+ left and right rotates of ~0, i.e. integer_all_onesp (arg0).
+ [LSHIFT_EXPR, RSHIFT_EXPR]: Optimize shifts and rotates of zero.
+
+Tue Oct 8 01:24:19 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (x86_sse_partial_reg_dependency, x86_sse_partial_regs,
+ x86_sse_typeless_stores, x86_sse_load0_by_pxor): New global
+ variables.
+ (safe_vector_operand): Update sse_clrv4sf call.
+ (ix86_expand_buildin): Likewise
+ * i386.h (x86_sse_partial_reg_dependency, x86_sse_partial_regs,
+ x86_sse_typeless_stores, x86_sse_load0_by_pxor): Declare.
+ (TARGET_SSE_PARTIAL_REG_DEPENDENCY, TARGET_SSE_PARTIAL_REGS,
+ TARGET_SSE_TYPELESS_STORES, TARGET_SSE_TYPELESS_LOAD0): New
+ macros.
+ * i386.md (movsf*, movdf*, movti, movv4sf, movv2df, movv16qi, movv8hi,
+ movv4si): Obey the new flags.
+ (floatsi2sf, floatdi2sf, truncatedf2sf): Emit extra load of 0 to avoid
+ reformating penalty.
+ (anddf, cmov patterns): Avoid reformating by first converting.
+ (sse_cvtsd2ss): Fix predicate.
+ (sse2_clrti): Fix mode,
+ (sse_clrv4sf): Avoid unspec.
+
+2002-10-08 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/t-linux64 (MULTILIB_OPTIONS): Remove
+ mno-app-regs|mcmodel=medany.
+ (MULTILIB_DIRNAMES, MULTILIB_OSDIRNAMES): Remove alt.
+ (MULTILIB_EXCEPTIONS, MULTILIB_EXCLUSIONS, MULTILIB_MATCHES): Remove.
+ (CRTSTUFF_T_CFLAGS): Define.
+
+2002-10-08 Roger Sayle <roger@eyesopen.com>
+
+ PR target/8087
+ * simplify-rtx.c (avoid_constant_pool_reference): Allow constant
+ pool references that are constructed using LO_SUM.
+
+2002-10-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-opts.c (c_common_decode_option): Add warn_strict_aliasing to
+ -Wall.
+ * c-typeck.c (build_c_cast): Use warn_strict_aliasing, tweak
+ message.
+ * flags.h (warn_strict_aliasing): Declare.
+ * toplev.c (warn_strict_aliasing): Define.
+ (lang_independent_options): Add it.
+ * doc/invoke.texi (-Wstrict-aliasing): Document it.
+
+2002-10-08 Zack Weinberg <zack@codesourcery.com>
+
+ * system.h (GCCBUGURL): Delete.
+ * version.c (bug_report_url): New. Add commentary about
+ modifying both these strings in modified distributions.
+ * version.h: Declare bug_report_url.
+
+ * diagnostic.c, gcc.c, gcov.c: Globally replace GCCBUGURL with
+ bug_report_url.
+
+2002-10-08 Nick Clifton <nickc@redhat.com>
+
+ * config/rs6000/spe.h (__ev_set_acc_u64): Use __ev_create_u64 to
+ convert uint64_t into __ev64_opaque__.
+ (__ev_set_acc_s64): Likewise, but using signed types.
+
+2002-10-08 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*doloop_si_long"): Add missing operand.
+ ("*doloop_di_long"): Likewise.
+
+Tue Oct 8 16:50:10 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * print-rtl.c (print_rtx): Increase buffer size for real numbers.
+
+2002-10-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (define_attr cpu): Add r4111.
+
+2002-10-08 Anthony Green <green@redhat.com>
+
+ * bitmap.c (bitmap_equal_p): Clear all bitmap_head fields.
+
+2002-10-08 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_print_operand): Enlarge buffer
+ for REAL_VALUE_TO_DECIMAL output.
+
+2002-10-07 Richard Henderson <rth@redhat.com>
+
+ * cse.c (fixed_base_plus_p): Turn FIXED_BASE_PLUS_P into a
+ function; cleanup PLUS case by using recursion. Update all users.
+ (NONZERO_BASE_PLUS_P): Remove.
+ (find_comparison_args): Use rtx_addr_can_trap_p instead.
+ (fold_rtx): Use nonzero_address_p.
+ * rtl.h (nonzero_address_p): Declare.
+ * rtlanal.c (rtx_varies_p): Handle ADDRESSOF.
+ (rtx_addr_can_trap_p): Likewise.
+ (nonzero_address_p): New.
+ * simplify-rtx.c (NONZERO_BASE_PLUS_P): Remove.
+ (simplify_relational_operation): Use nonzero_address_p.
+
+2002-10-07 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Set
+ real_format_for_mode for IBM extended format, if enabled.
+ (easy_fp_constant): Add TFmode.
+ (rs6000_legitimize_address): Add TFmode.
+ (rs6000_legitimate_address): Same.
+ (function_arg_advance): TFmode uses two FPRs.
+ (rs6000_emit_prologue): Fix warning.
+ (rs6000_output_function_epilogue): Add TFmode.
+ (output_toc): Add TFmode.
+ * rs6000.h (SLOW_UNALIGNED_ACCESS): Add TFmode.
+ (LEGITIMATE_OFFSET_ADDRESS_P): Add TFmode.
+ * rs6000.md (movtf splitter): Load TFmode constant.
+
+2002-10-07 Dale Johannesen <dalej@apple.com>
+
+ * rtl.h: Add NOTE_PRECONDITIONED.
+ * unroll.c: Set it.
+ * loop.c: Set loop_info->preconditioned from it.
+ * doloop.c: Permit doloop treatment when loop_info->preconditoned.
+
+2002-10-07 Richard Henderson <rth@redhat.com>
+
+ * config/i960/i960.c (i960_setup_incoming_varargs): Create a
+ new rtx for comparing the argument pointer against zero.
+ (i960_va_start): Similarly.
+
+2002-10-07 Richard Henderson <rth@redhat.com>
+
+ * config/i960/i960.md (*): Use TFmode, not XFmode.
+ * config/i960/i960.c (*): Likewise.
+ (i960_arg_size_and_align): Remove XFmode alignment hack.
+ (i960_round_align): Merge code from ROUND_TYPE_ALIGN.
+ * config/i960/i960.h (LONG_DOUBLE_TYPE_SIZE): Use 128, not 96.
+ (MAX_LONG_DOUBLE_TYPE_SIZE): Likewise.
+ (DATA_ALIGNMENT, ROUND_TYPE_SIZE): Remove.
+
+2002-10-07 Richard Henderson <rth@redhat.com>
+
+ * config/fp-bit.c (EXTENDED_FLOAT_STUBS): Flush out all XF/TFmode
+ entry points; use void return value and argument list.
+
+2002-10-06 Andreas Bauer <baueran@in.tum.de>
+
+ * calls.c (expand_call): Fix function-is-volatile check.
+
+2002-10-05 Naohiko Shimizu <nshimizu@keyaki.cc.u-tokai.ac.jp>
+
+ * t-pdp11: Add MULTILIB support for msoft-float.
+ * pdp11.h (LEGITIMATE_CONSTANT_P): Fix soft-float case.
+
+ * t-pdp11: Add LIB2FUNCS_EXTRA.
+ * pdp11.c (pdp11_output_function_prologue): Restrict offset to 16bit,
+ add preceding 0 to the octal constant, rename 'fp' to 'r5', rename
+ 'fldd' to 'ldd', rename 'fstd' to 'std'.
+ (pdp11_output_function_epilogue): Likewise.
+ (output_move_quad): Make the comment gas compatible.
+ (output_ascii): Add preceding 0 to the octal constant.
+ (print_operand_address): Add pre_modify, post_modify.
+ (output_addr_const_pdp11): Add preceding 0 to the octal constant.
+ * pdp11.h (GO_IF_LEGITIMATE_ADDRESS) : Add 'movb' pre_modify case
+ with the indication of Paul Koning.
+ (PRINT_OPERAND): Fix floating constant.
+ * pdp11.md (movdi): Restrict matching pattern.
+ (movqi): Generalize the matching pattern.
+ (movdf): Restrict matching pattern.
+ (zero_extendqihi2): Change constant representation.
+ (floatsidf2): Fix wrong operands.
+ (addqi3): Fix wrong instruction name.
+ (subqi3): Fix wrong instruction name.
+ (andsi3, andhi3, andqi3): Simplify and fix to use 'bic'.
+ (xorsi3): Fix wrong insn.
+ (one_cmplqi2): Add two operand pattern.
+ (lsrsi3): New.
+ (negsi2): New.
+ (call): Add register indirect case.
+ (mod): Fix wrong subreg.
+
+2002-10-06 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c/7411
+ * expr.c (expand_expr) [PLUS]: Simplify after the operands
+ have been expanded in EXPAND_NORMAL mode.
+
+2002-10-06 Richard Henderson <rth@redhat.com>
+
+ * config/rs6000/rs6000.md (load_toc_v4_PIC_2): Fix base constraint.
+
+2002-10-06 Richard Henderson <rth@redhat.com>
+
+ PR optimization/2960
+ * toplev.c (rest_of_compilation): Don't copy_loop_headers if
+ optimize_size.
+
+2002-10-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mips/mips.h (SIZE_TYPE, PTRDIFF_TYPE): Override
+ previously definitions.
+
+2002-10-06 Frank Ch. Eigler <fche@redhat.com>
+
+ * cppinit.c (init_standard_includes, parse_option): Use strncmp.
+ * c-opts.c (find_opt): Similarly.
+
+Sat Oct 5 22:48:06 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * athlon.md: rewrite to DFA.
+ * i386 (ix86_adjust_cost): Drop memory latency code.
+ (ia32_use_dfa_pipeline_interface): Return true for Athlon.
+
+2002-10-05 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.c (set_multilib_dir): Don't access *end.
+ Use memcpy instead of strncpy. Don't write beyond malloced buffer.
+ (print_multilib_info): Don't show paths starting with ".:".
+ * genmultilib: Add new option, "yes" if multilibs are enabled.
+ Update comments. If multilibs not enabled, print .:${osdirout}
+ for each directory. If multilibs are enabled, always print
+ ${dirout}:${osdirout}, even if the two are the same.
+ * Makefile.in (s-mlib): Pass @enable_multilib@ to genmultilib.
+ Pass all MULTILIB_* variables to genmultilib even if
+ --disable-multilib but MULTILIB_OSDIRNAMES is not empty.
+
+2002-10-04 Zack Weinberg <zack@codesourcery.com>
+
+ * gcc.c (process_command): Set .validated for -pipe. Correct
+ grammar in comment.
+
+2002-10-04 Bruce Korb <bkorb@gnu.org>
+
+ * fixinc/inclhack.def(hpux11_abs): use format fix
+ * fixinc/fixincl.x: regenerate
+ * fixinc/tests/base/stdlib.h: accommodate new fix test
+
+Sat Oct 5 19:42:45 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * c-common.c (cb_register_builtins): Use really_no_inline.
+
+2002-10-04 David Edelsohn <edelsohn@gnu.org>
+
+ * unroll.c (copy_loop_body): Remove REG_EQUAL note attached to
+ copied instruction if the note is not loop invariant.
+
+2002-10-04 Loren J. Rittle <ljrittle@acm.org>
+
+ * gcc/ginclude/stddef.h: Support the FreeBSD 5 typedef system.
+
+2002-10-04 Steve Ellcey <sje@cup.hp.com>
+
+ * doc/invoke.texi (HPPA): Add -mlinker-opt, -mgnu-ld,
+ and -mhp-ld options to list of options. Add -mgnu-ld
+ and -mhp-ld option descriptions.
+
+2002-10-04 Steve Ellcey <sje@cup.hp.com>
+
+ * fixinc/inclhack.def (hpux11_abs): New.
+ (stdio_va_list): change __va_list__ to __gnuc_va_list.
+ * fixinc/fixincl.x: Rebuild.
+
+2002-10-04 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.h (processor_costs): Add new fields fadd,
+ fmul, fdiv, fabs, fchs and fsqrt to costs structure.
+ (RTX_COSTS): Use these fields to determine the RTX costs
+ of floating point addition/subtraction, multiplication,
+ division, fabs, negation and square root respectively.
+ * config/i386/i386.c (size_cost): Provide instruction sizes
+ for these new fields.
+ (i386_cost, i486_cost, pentium_cost, pentiumpro_cost,
+ k6_cost, athlon_cost, pentium4_cost): Provide typical cycle
+ counts for these new fields for all x86 processor variants.
+
+2002-10-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mips.c (mips_const_double_ok): Delete unused variable.
+
+ * gengtype.c (rtx_next): Change type to int.
+
+2002-10-04 Andreas Jaeger <aj@suse.de>
+
+ * config/i386/t-linux64 (MULTILIB_OSDIRNAMES): Fix value.
+
+2002-10-04 Richard Henderson <rth@redhat.com>
+
+ * real.h (SIGNIFICAND_BITS): Add one more word.
+ (CONST_DOUBLE_FORMAT): Accomodate 6 words.
+ * real.c (times_pten): New.
+ (real_to_decimal, real_from_string): Use it.
+ (sticky_rshift_significand): Use & to find modulus.
+ (rshift_significand, lshift_significand): Likewise.
+ (do_divide): Apply sticky bit after normalization.
+ (real_to_decimal, real_to_hexadecimal): Fix sign of Inf and NaN.
+
+2002-10-03 Andreas Bauer <baueran@in.tum.de>
+
+ * doc/tm.texi (FUNCTION_OK_FOR_SIBCALL): Remove.
+ (TARGET_FUNCTION_OK_FOR_SIBCALL): New.
+
+2002-10-03 Andreas Jaeger <aj@suse.de>
+
+ * gengtype.c (adjust_field_rtx_def): Cast variables of type size_t
+ to unsigned long, adjust printf format string.
+ (output_mangled_typename): Likewise.
+
+2002-10-03 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/vax/vax.c (vax_output_function_prologue): Use asm_fprintf.
+ * config/vax/vax.h (VAX_FUNCTION_PROFILER_NAME): New.
+ (FUNCTION_PROFILER): Rewrite to use ASM_GENERATE_INTERNAL_LABEL,
+ assemble_name, asm_fprintf, and VAX_FUNCTION_PROFILER_NAME.
+ (ASM_OUTPUT_MI_THUNK): Use asm_fprintf instead of REGISTER_PREFIX.
+ (PRINT_OPERAND_PUNCT_VALID_P): Fix comment.
+ * config/vax/elf.h (FUNCTION_PROFILER): Remove.
+ (VAX_FUNCTION_PROFILER_NAME): Redefine as "__mcount".
+
+2002-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/invoke.texi (-Wabi): Document mangling bug.
+
+2002-10-04 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_output_function_epilogue): Use a
+ name for the tbtab label that depends on the function asm name.
+ Don't output tbtab label unless optional_tbtab.
+ (output_mi_thunk): Formatting.
+
+2002-10-03 Richard Henderson <rth@redhat.com>
+
+ * config/m68k/m68k.h (OVERRIDE_OPTIONS): Move additional code ...
+ * config/m68k/m68k.c (override_options): ... here.
+ * config/m68k/m68kelf.h (OVERRIDE_OPTIONS): Remove.
+ * config/m68k/m68kv4.h (OVERRIDE_OPTIONS): Remove.
+ * config/m68k/linux.h (SUBTARGET_OVERRIDE_OPTIONS): Remove.
+ * config/m68k/netbsd-elf.h (SUBTARGET_OVERRIDE_OPTIONS): Remove.
+
+2002-10-03 Richard Henderson <rth@redhat.com>
+
+ * real.h (struct real_value): Use ENUM_BITFIELD.
+
+2002-10-03 Richard Henderson <rth@redhat.com>
+
+ * config/i960/i960.md (call, call_value): Use emit_call_insn.
+
+2002-10-03 Steve Ellcey <sje@cup.hp.com>
+
+ * config/pa/pa64-hpux.h (INIT_ENVIRONMENT): New.
+
+2002-10-03 Steve Ellcey <sje@cup.hp.com>
+
+ * config.gcc (hppa*64*-*-hpux11*): Check gnu_ld.
+ * config/pa/pa.h (MASK_GNU_LD): New.
+ (TARGET_GNU_LD): New.
+ * config/pa/pa64-hpux.h (LINK_SPEC): Set based
+ on gnu-ld and MASK_GNU_LD.
+ (SUBTARGET_SWITCHES): New gnu-ld & hp-ld flags.
+
+Thu Oct 3 23:35:51 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (athlon_cost): Fix the move costs.
+
+Thu Oct 3 23:20:58 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * final.c (final): Use symbol name as function name for profiling.
+ * profile.c (get_exec_counts): Likewise.
+ (branch_prob): Likewise.
+
+2002-10-03 Jakub Jelinek <jakub@redhat.com>
+
+ * longlong.h (__udiv_qrnnd): Remove PARAMS from prototype.
+
+2002-10-03 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.c (print_multi_os_directory): New variable.
+ (option_map): Support --print-multi-os-directory.
+ (struct prefix_list): Add os_multilib field.
+ (multilib_os_dir): New variable.
+ (static_specs): Add multilib_options.
+ (find_a_file): Add multilib argument. Search in GCC or OS multilib
+ subdirs if nonzero.
+ (read_specs, execute): Update callers.
+ (find_file): Likewise. Don't prefix name with multilib_dir, instead
+ pass 1 as multilib option.
+ (display_help): Include --print-multi-os-directory.
+ (add_prefix): Add os_multilib argument. Initialize pl->os_multilib.
+ (process_command): Update callers. Handle --print-multi-os-directory.
+ (do_spec_1) ['D']: Use multilib_os_directory if pl->os_multilib is
+ set.
+ (main): Update find_a_file and add_prefix callers.
+ Handle print_multi_os_directory.
+ (struct mdswitchstr): New.
+ (mdswitches, n_mdswitches): New variables.
+ (used_arg): Add MULTILIB_DEFAULT switches too if they are not
+ present on the command line nor their mutually incompatible
+ switches.
+ (default_arg): Optimize.
+ (set_multilib_dir): Compute multilib_os_dir. Initialize mdswitches
+ array.
+ (print_multilib_info): Only print GCC multilib dir name, not OS
+ multilib dirname.
+ * genmultilib: Add osdirnames parameter. Output multilib_options
+ variable. If osdirnames is specified, output dirnames as
+ dirname:osdirname.
+ * mklibgcc.in: Use MULTILIB_OSDIRNAMES, --print-multi-directory
+ and --print-multi-os-directory instead of SHLIB_SLIBDIR_SUFFIXES
+ to compute libgcc_s soname and install path.
+ * Makefile.in (libgcc.mk): Pass MULTILIB_OSDIRNAMES instead of
+ SHLIB_SLIBDIR_SUFFIXES to mklibgcc.
+ (s_mlib): Pass MULTILIB_OSDIRNAMES or nothing as last genmultilib
+ argument.
+
+ * config/sparc/t-linux64 (MULTILIB_OSDIRNAMES): Set.
+ (SHLIB_SLIBDIR_SUFFIXES): Remove.
+ * config/sparc/linux64.h (STARTFILE_SPEC32, STARTFILE_SPEC64,
+ ENDFILE_SPEC32, ENDFILE_SPEC64, ENDFILE_COMMON): Remove.
+ (STARTFILE_SPEC, ENDFILE_SPEC): Don't distinguish between -m32
+ and -m64.
+ * config/sparc/t-sol2-64 (MULTILIB_OSDIRNAMES): Set.
+ (SHLIB_SLIBDIR_SUFFIXES): Remove.
+ * config/sparc/sol2-bi.h (STARTFILE_ARCH64_SPEC): Remove.
+ (STARTFILE_ARCH_SPEC): Remove.
+ * config/i386/t-linux64 (MULTILIB_OSDIRNAMES): Set.
+ (SHLIB_SLIBDIR_SUFFIXES): Remove.
+ * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): Remove.
+ * config/mips/t-iris6 (MULTILIB_OSDIRNAMES): Set.
+ (SHLIB_SLIBDIR_SUFFIXES): Remove.
+
+Thu Oct 3 21:42:20 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * predict.c (choose_function_section): Avoid choice for linkonce functions.
+
+Thu Oct 3 15:15:00 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (lea to mul peep2): Fix condition.
+
+2002-10-02 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa-linux.h (FUNCTION_OK_FOR_SIBCALL): Delete macro.
+ * pa32-linux.h (FUNCTION_OK_FOR_SIBCALL): Define.
+
+2002-10-02 David Mosberger-Tang <David.Mosberger@acm.org>
+
+ * unwind.h (_Unwind_GetTextRelBase): Mark _C argument with
+ attribute "unused".
+
+ * config/t-libunwind: Mention unwind-sjlj.c.
+ * unwind-libunwind.c: Change #ifdef __USING_LIBUNWIND_EXCEPTIONS__
+ to #ifndef __USING_SJLJ_EXCEPTIONS__.
+
+ * configure.in: Move sjlj-exceptions and --enable-libunwind-exceptions
+ before inclusion of config.gcc, but after configuring the compiler etc.
+ Determine default value for --enable-libunwind-exceptions based on
+ whether the host has a libunwind library (not guaranteed to be correct,
+ but it's a reasonable first guess and can always be overridden with an
+ explicit --enable/disable-libunwind-exceptions.
+ * config.gcc: For target ia64*-*-linux*, mention t-libunwind as a
+ tmake_file when $use_libunwind_exceptions is enabled.
+ * Makefile.in: Update comment: LIB2ADDEH is updated not just by
+ ia64 (e.g., config/t-linux also updates it).
+ * gcc.c (init_spec) [USE_LIBUNWIND_EXCEPTIONS]: Mention -lunwind
+ along with the shared version of libgcc since the latter requires
+ the former.
+ * unwind-libunwind.c: New file.
+ * config/t-libunwind: Ditto.
+
+2002-10-02 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Remove support for vax-*-vms*.
+ * config/vax/vms.h: Remove.
+ * config/vax/xm-vms.h: Remove.
+ * config/vax/vax-protos.h: Remove VMS-specific code.
+ * config/vax/vax.c: Remove VMS-specific code.
+
+2002-10-02 Richard Henderson <rth@redhat.com>
+
+ PR opt/7124
+ * config/i386/i386.c (ix86_register_move_cost): Increase cost
+ for secondary_memory_needed pairs.
+
+2002-10-02 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * doc/vms.texi: Blow away false include file section.
+
+2002-10-02 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/6627
+ * toplev.c (force_align_functions_log): New global variable.
+ * flags.h (force_align_functions_log): Add extern prototype.
+ * varasm.c (assemble_start_function): Use it to force minimum
+ function alignment.
+ * config/i386/i386.h (FUNCTION_BOUNDARY): Set the correct
+ minimum function alignment to one byte.
+ (TARGET_PTRMEMFUNC_VBIT_LOCATION): Store the virtual bit in
+ the least significant bit of vtable member function pointers.
+ * tree.h (enum ptrmemfunc_vbit_where_t): Move definition to
+ here from cp/cp-tree.h.
+
+Wed Oct 2 17:01:36 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (print_operand_address): Use RIP addressing for offsetted
+ label refs too.
+
+2002-09-30 David S. Miller <davem@redhat.com>
+
+ PR middle-end/7151
+ * config/sparc/sparc.md (movdi_insn_sp32_v9): Accept 'e' regs.
+ (movdi reg/reg split): Match only on sparc32, and v9 when int regs.
+
+2002-10-01 Andreas Bauer <baueran@in.tum.de>
+
+ * calls.c (expand_call): Remove the `no indirect check'
+ for sibcall optimization; use function_ok_for_sibcall
+ target hook; refine check for `function is volatile'.
+ (FUNCTION_OK_FOR_SIBCALL): Remove the redefinition.
+ * hooks.c (hook_tree_tree_bool_false): New.
+ * hooks.h (hook_tree_tree_bool_false): Declare.
+ * target-def.h (TARGET_FUNCTION_OK_FOR_SIBCALL): New.
+ (TARGET_INITIALIZER): Add it.
+ * target.h (struct gcc_target): Add function_ok_for_sibcall.
+ * config/alpha/alpha.c: (alpha_function_ok_for_sibcall): New.
+ (TARGET_FUNCTION_OK_FOR_SIBCALL): Redefine accordingly.
+ * config/alpha/alpha.h: (FUNCTION_OK_FOR_SIBCALL): Remove.
+ * config/arm/arm-protos.h: (arm_function_ok_for_sibcall):
+ Remove function declaration.
+ * config/arm/arm.c: (arm_function_ok_for_sibcall): Make
+ function static and accept another argument of type `tree'.
+ (TARGET_FUNCTION_OK_FOR_SIBCALL): Redefine accordingly.
+ * config/arm/arm.h: (FUNCTION_OK_FOR_SIBCALL): Remove.
+ * config/frv/frv.h: (FUNCTION_OK_FOR_SIBCALL): Remove.
+ * config/i386/i386.c: (ix86_function_ok_for_sibcall): New.
+ (TARGET_FUNCTION_OK_FOR_SIBCALL): Redefine accordingly.
+ * config/i386/i386.h: (FUNCTION_OK_FOR_SIBCALL): Remove.
+ * config/pa/pa-linux.h: (FUNCTION_OK_FOR_SIBCALL): Remove.
+ (TARGET_HAS_STUBS_AND_ELF_SECTIONS): New definition.
+ * config/pa/pa.c: (pa_function_ok_for_sibcall): New.
+ (TARGET_FUNCTION_OK_FOR_SIBCALL): Redefine accordingly.
+ * config/pa/pa.h: (FUNCTION_OK_FOR_SIBCALL): Remove.
+ * config/rs6000/rs6000-protos.h: (function_ok_for_sibcall):
+ Remove function declaration.
+ * config/rs6000/rs6000.c: (rs6000_function_ok_for_sibcall):
+ Rename function_ok_for_sibcall to rs6000_function_ok_for_sibcall;
+ rename first argument to `decl'; accept another argument
+ of type `tree'; make static.
+ (TARGET_FUNCTION_OK_FOR_SIBCALL): Redefine accordingly.
+ * config/rs6000/rs6000.h: (FUNCTION_OK_FOR_SIBCALL): Remove.
+ * config/sh/sh.c: (sh_function_ok_for_sibcall): New.
+ (TARGET_FUNCTION_OK_FOR_SIBCALL): Redefine accordingly.
+ * config/sh/sh.h: (FUNCTION_OK_FOR_SIBCALL): Remove.
+ * config/sparc/sparc.c: (sparc_function_ok_for_sibcall): New.
+ (TARGET_FUNCTION_OK_FOR_SIBCALL): Redefine accordingly.
+ * config/sparc/sparc.h: (FUNCTION_OK_FOR_SIBCALL): Remove.
+ * config/xtensa/xtensa.h: (FUNCTION_OK_FOR_SIBCALL): Remove.
+
+2002-10-01 Roger Sayle <roger@eyesopen.com>
+
+ * unroll.c (loop_iterations): Revert 2002-09-08 change.
+
+2002-10-01 Richard Henderson <rth@redhat.com>
+
+ * real.c (real_to_decimal): Crop trailing zeros for DIGITS < 0.
+ (real_to_hexadecimal): Likewise.
+ * print-rtl.c (print_rtx): If we are linked with real.c, don't
+ dump the XWINT fields of a floating point CONST_DOUBLE.
+
+2002-10-01 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/vax/elf.h (FUNCTION_PROFILER): Fix __mcount call.
+
+2002-10-01 Richard Henderson <rth@redhat.com>
+
+ * calls.c (precompute_register_parameters): Force non-legitimate
+ constants into pseudos.
+
+2002-10-01 Nick Clifton <nickc@redhat.com>
+
+ * config/rs6000/spe.md (spe_evrlwi): Add missing third operand
+ to assembler template.
+
+2002-10-01 Richard Henderson <rth@redhat.com>
+
+ * dwarf2out.c (loc_descriptor_from_tree): Relax requirement
+ for TLS debug info to !DECL_EXTERNAL.
+
+2002-10-01 Matt Thomas <matt@3am-software.com>
+ Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.gcc (vax-*-netbsdelf*): Enable configuration.
+ * config/elfos.h (PCC_BITFIELD_TYPE_MATTERS): Define only
+ if not already defined.
+ * config/vax/elf.h: New file.
+ * config/vax/netbsd-elf.h: New file.
+ * config/vax/vax.c: Include "debug.h".
+ (vax_output_function_prologue): Add dwarf2 support. Use
+ MAIN_NAME_P when checking for VMS_TARGET stack adjust.
+ * config/vax/vax.h (CONST_OK_FOR_LETTER_P): Add cases for
+ 'J' [0..63], 'K' [-128..127], 'L' [-32768..32767],
+ 'M' [0..255], 'N' [0..65535], and, 'O' [-63..-1].
+ (VAX_ISTREAM_SYNC): Remove.
+ (INITIALIZE_TRAMPOLINE): Use gen_sync_istream.
+ (JUMP_TABLES_IN_TEXT_SECTION): Define.
+ (ASM_OUTPUT_REG_POP): Use reg_names for the stack pointer.
+ (ASM_OUTPUT_ADDR_VEC_ELT): Use ASM_GENERATE_INTERNAL_LABEL
+ and assemble_name.
+ (ASM_OUTPUT_ADDR_DIFF_ELT): Likewise.
+ (PRINT_OPERAND_PUNCT_VALID_P): Accept '|'.
+ (PRINT_OPERAND): Output REGISTER_PREFIX for '|'.
+ (INCOMING_RETURN_ADDR_RTX): Define.
+ * config/vax/vax.md (VUNSPEC_BLOCKAGE)
+ (VUNSPEC_SYNC_ISTREAM): Define.
+ (blockage): Use VUNSPEC_BLOCKAGE.
+ (sync_istream): New insn.
+
+2002-10-01 Richard Henderson <rth@redhat.com>
+
+ * config/vax/vax.md (call_pop, *call_pop, call_value_pop)
+ (*call_value_pop, call, call_value): Add dwarf2 EH support.
+ (*call): New insn.
+
+2002-10-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c/8083
+ * c-typeck.c (build_c_cast): Warn about type punning which breaks
+ type based aliasing.
+
+2002-10-01 Mark Mitchell <mark@codesourcery.com>
+
+ * stor-layout.c (update_alignment_for_field): New function.
+ (place_union_field): Use it.
+ (place_field): Likewise.
+
+2002-10-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR other/8077
+ * gcc.c (cc1_options): Add space on -auxbase-strip.
+
+2002-10-01 Jim Wilson <wilson@redhat.com>
+
+ * config/v850/v850.h (EPILOGUE_USES): Define.
+
+2002-09-30 Andrew Haley <aph@redhat.com>
+
+ * flow.c (insn_dead_p): When using non-call-exceptions, don't
+ eliminate insns that may trap.
+ * cse.c (insn_live_p): Likewise.
+
+2002-10-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (PROCESSOR_R4121): Rename to PROCESSOR_R4120.
+ (TARGET_MIPS4121): Rename to TARGET_MIPS4120.
+ * config/mips/mips.c (mips_cpu_info): Rename vr4121 to vr4120.
+ * config/mips/mips.md: Apply same renaming here.
+
+2002-10-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (PROCESSOR_R4320, TARGET_MIPS4320): Remove.
+ (GENERATE_MULT3_SI): Remove use of TARGET_MIPS4320.
+ * config/mips/mips.c (mips_cpu_info): Remove vr4320 entry.
+ * config/mips/mips.md (define_attr cpu): Remove r4320.
+ Remove vr4320 scheduler and uses of TARGET_MIPS4320.
+
+2002-10-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips16_strings): New variable.
+ (mips_output_function_epilogue): Clear the SYMBOL_REF_FLAG of every
+ symbol in mips16_strings. Free the list.
+ (mips_encode_section_info): Keep track of local strings.
+
+2002-10-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (bunge, bltgt, bungt): New define_expands.
+ (sordered_df, sordered_sf): Remove.
+ * config/mips/mips.c (get_float_compare_codes): New fn.
+ (gen_int_relational, gen_conditional_move): Use it.
+
+2002-10-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_emit_fcc_reload): Declare.
+ * config/mips/mips.h (PREDICATE_CODES): Add fcc_register_operand.
+ * config/mips/mips.c (fcc_register_operand): New function.
+ (mips_emit_fcc_reload): New function, extracted from reload_incc.
+ (override_options): Allow TFmode values in float registers
+ if ISA_HAS_8CC.
+ * cnfig/mips/mips.md (reload_incc): Change destination prediate
+ to fcc_register_operand. Remove misleading source constraint.
+ Use mips_emit_fcc_reload.
+ (reload_outcc): Duplicate reload_incc.
+
+2002-09-30 Zack Weinberg <zack@codesourcery.com>
+
+ * gcc.c (validate_switches): Handle all new forms of spec
+ syntax introduced recently. Now returns a char *.
+ (validate_all_switches): Repetitive logic broken out to...
+ (validate_switches_from_spec): ...here.
+ * mklibgcc.in: Don't @-flag commands to generate .oS files.
+
+2002-09-30 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * longlong.h: Partially synchronize with GMP-4.1 version:
+ Use i370 definitions also for s390.
+ Add generic definition of umul_ppmm in terms of smul_ppmm.
+ [s390] (umul_ppmm): Remove.
+ [s390] (smul_ppmm): Fix incorrect assembler constraints.
+ [s390] (smul_ppmm, sdiv_qrnnd): Rename __xx to __x.
+
+2002-09-30 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.h (REG_CLASS_NAMES, REG_CLASS_CONTENTS):
+ Add new RL_REGS register class.
+ (PREFERRED_RELOAD_CLASS, PREFERRED_OUTPUT_RELOAD_CLASS):
+ Call xtensa_preferred_reload_class for both input and output reloads.
+ * config/xtensa/xtensa.c (xtensa_regno_to_class): Use new RL_REGS class.
+ (xtensa_preferred_reload_class): Handle output reloads; use RL_REGS
+ instead of either AR_REGS or GR_REGS classes.
+ (xtensa_secondary_reload_class): Use new RL_REGS class.
+ * config/xtensa/xtensa-protos.h (xtensa_preferred_reload_class): Update.
+
+2002-09-30 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.c (hppa_encode_label): Don't drop '*' from function labels.
+ (pa_strip_name_encoding): Strip '@' and '*', in that order.
+ * pa.h (ASM_OUTPUT_LABELREF): Output user_label_prefix except when
+ there is a '*' prefix in NAME.
+
+Mon Sep 30 21:33:23 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * reload.c (push_reload): Handle subregs and secondary memory.
+ * reload1.c (gen_reload): Likewise.
+
+ * jump.c (reg_or_subregno): New function.
+ * rtl.h (reg_or_subregno): Declare
+ * unroll.c (find_splittable_givs): Handle subregs.
+
+2002-09-30 Mark Mitchell <mark@codesourcery.com>
+
+ * store-layout.c (finish_record_layout): Add free_p parameter.
+ (layout_type): Pass it.
+ * tree.h (finish_record_layout): Update prototype.
+
+Mon Sep 30 14:57:18 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.h (TARGET_CPP_CPU_BUILTINS): Define __SSE_MATH__.
+
+ * gcse.c (cprop_jump): Check that the register has not
+ been modified
+ (cprop_jump): Likewise.
+
+2002-09-30 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.h (BASE_REG_CLASS): Always return LO_REGS for Thumb.
+ (MODE_BASE_REG_CLASS, case Thumb): Only return BASE_REGS if we know
+ that we have a SImode access, and only then if reload hasn't completed;
+ for all other cases, use LO_REGS.
+
+2002-09-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * openbsd.h: Fix typo in last change.
+
+2002-09-29 Richard Henderson <rth@redhat.com>
+
+ * real.c (real_from_string): Apply sign last. Tidy exponent handling.
+
+2002-09-29 Richard Henderson <rth@redhat.com>
+
+ PR c/8002
+ * combine.c (force_to_mode): Handle FLOAT_MODE destinations
+ for CONST_INT.
+
+2002-09-29 David Edelsohn <edelsohn@gnu.org>
+
+ * real.h (ibm_extended_format): Declare.
+ * real.c (encode_ibm_extended, decode_ibm_extended): New
+ functions.
+
+2002-09-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * darwin-protos.h (darwin_asm_output_dwarf_delta): Prototype.
+
+ * ia64.c (ia64_hpux_asm_file_end): Const-ify.
+
+2002-09-29 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * expmed.c (extract_bit_field): Fix bit-field extraction from SUBREGs.
+
+2002-09-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtins.def: Fix comment formatting.
+ * c-common.def: Likewise.
+ * cfgcleanup.c: Likewise.
+ * combine.c: Likewise.
+ * gengtype.c: Likewise.
+ * params.def: Likewise.
+ * predict.def: Likewise.
+ * rtl.def: Likewise.
+ * stab.def: Likewise.
+ * stor-layout.c: Likewise.
+ * tree.def: Likewise.
+ * config/darwin.c: Likewise.
+ * config/darwin.h: Likewise.
+ * config/dbxcoff.h: Likewise.
+ * config/elfos.h: Likewise.
+ * config/fp-bit.c: Likewise.
+ * config/freebsd-spec.h: Likewise.
+ * config/interix.h: Likewise.
+ * config/libgloss.h: Likewise.
+ * config/linux-aout.h: Likewise.
+ * config/linux.h: Likewise.
+ * config/lynx-ng.h: Likewise.
+ * config/lynx.h: Likewise.
+ * config/netbsd-aout.h: Likewise.
+ * config/netbsd.h: Likewise.
+ * config/netware.h: Likewise.
+ * config/psos.h: Likewise.
+ * config/ptx4.h: Likewise.
+
+2002-09-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog.4: Fix typos.
+ * ChangeLog.6: Likewise.
+ * FSFChangeLog.10: Likewise.
+ * genattrtab.c: Fix comment typos.
+ * haifa-sched.c: Likewise.
+ * real.c: Likewise.
+ * tree.h: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/arm/crti.asm: Likewise.
+ * config/arm/crtn.asm: Likewise.
+ * config/frv/frv.c: Likewise.
+ * config/frv/frv.md: Likewise.
+ * config/h8300/h8300.md: Likewise.
+ * config/i386/rtemself.h: Likewise.
+ * config/ia64/unwind-ia64.c: Likewise.
+ * config/ip2k/ip2k.h: Likewise.
+ * config/m88k/m88k.c: Likewise.
+ * config/m88k/m88k.md: Likewise.
+ * config/mips/sr71k.md: Likewise.
+ * config/mmix/mmix.c: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/sh/sh.md: Likewise.
+
+2002-09-26 Theodore A. Roth <troth@verinet.com>
+
+ * config/avr/avr.c: Eliminate use of _PC_ in pc relative insns.
+ * config/avr/avr.md: Ditto.
+
+2002-09-27 Alexander N. Kabaev <ak03@gte.com>
+
+ PR preprocessor/8055
+ * cppmacro.c (stringify_arg): Do not overflow the buffer
+ with the terminating NUL when the argument to be stringified
+ has no tokens.
+
+2002-09-27 Richard Henderson <rth@redhat.com>
+
+ * unroll.c (simplify_cmp_and_jump_insns): New.
+ (unroll_loop): Use it. Use simplify_gen_foo+force_operand
+ instead of expand_simple_foo.
+
+2002-09-27 Richard Henderson <rth@redhat.com>
+
+ PR optimization/7520
+ * cfganal.c (flow_active_insn_p): New.
+ (forwarder_block_p): Use it.
+
+2002-09-27 Richard Henderson <rth@redhat.com>
+
+ * emit-rtl.c (active_insn_p): Revert last change.
+
+2002-09-27 Jakub Jelinek <jakub@redhat.com>
+
+ * doc/extend.texi (tls_model): Document.
+ * varasm.c (decl_tls_model): New.
+ * c-common.c (handle_tls_model_attribute): New.
+ (c_common_attribute_table): Add tls_model.
+ * config/alpha/alpha.c (alpha_encode_section_info): Use
+ decl_tls_model.
+ * flags.h (enum tls_model, flag_tls_default): Move...
+ * tree.h (enum tls_model, flag_tls_default): ...here.
+ (decl_tls_model): New prototype.
+ * config/ia64/ia64.c (ia64_encode_section_info): Likewise.
+ * config/i386/i386.c (ix86_encode_section_info): Likewise.
+ * config/i386/i386.md (tls_global_dynamic, tls_local_dynamic_base):
+ Allow !flag_pic.
+
+2002-09-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * LANGUAGES: Follow spelling conventions.
+ * rtl.def: Likewise.
+ * sbitmap.c: Likewise.
+ * sched-int.h: Likewise.
+ * sched-rgn.c: Likewise.
+ * sibcall.c: Likewise.
+ * simplify-rtx.c: Likewise.
+ * ssa.c: Likewise.
+ * stab.def: Likewise.
+ * stmt.c: Likewise.
+ * stor-layout.c: Likewise.
+ * target.h: Likewise.
+ * timevar.c: Likewise.
+ * toplev.c: Likewise.
+ * tree-dump.c: Likewise.
+ * tree-inline.c: Likewise.
+ * tree.c: Likewise.
+ * tree.def: Likewise.
+ * tree.h: Likewise.
+ * unroll.c: Likewise.
+ * varasm.c: Likewise.
+ * vmsdbgout.c: Likewise.
+ * treelang/treelang.texi: Likewise.
+ * treelang/treetree.c: Likewise.
+
+2002-09-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (compute_saved_regs): Use a macro
+ instead of a hard register number.
+ (get_shift_alg): Use an enumerated type instead of numbers.
+ (h8300_shift_needs_scratch_p): Likewise.
+
+2002-09-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * varasm.c (force_data_section): Remove.
+ (assemble_constant_align): Likewise.
+ * output.h: Remove corresponding prototypes.
+
+2002-09-26 Roger Sayle <roger@eyesopen.com>
+
+ * stmt.c (expand_exit_loop_if_false): Expand a simple conditional
+ jump, if the loop to exit is the top of the current nesting stack.
+
+2002-09-26 Torbjorn Granlund <tege@swox.com>
+
+ * libgcc2.c (fixunsdfdi, fixunssfdi): Rewrite, avoiding `long long'
+ arithmetic.
+
+2002-09-26 David S. Miller <davem@redhat.com>
+
+ PR optimization/7335
+ * calls.c (emit_library_call_value_1): Passing args by reference
+ converts a CONST function into a PURE one.
+
+2002-09-26 David Edelsohn <edelsohn@gnu.org>
+
+ * dbxout.c (FORCE_TEXT): Switch to current_function_decl, not
+ text_section.
+ * xcoffout.h (DBX_STATIC_BLOCK_START): Remove explicit change to
+ text section.
+ * config/rs6000/rs6000.c (rs6000_override_options): Allow
+ function-sections and data-sections functionality on AIX.
+
+2002-09-26 David Edelsohn <edelsohn@gnu.org>
+ Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_move): Insert zero-extend
+ in RTL for sub-word loads from memory.
+
+2002-09-26 Richard Henderson <rth@redhat.com>
+
+ PR c/7160
+ * sched-deps.c (sched_analyze_insn): Make clobber insns depend
+ on call insns.
+
+2002-09-26 Richard Henderson <rth@redhat.com>
+
+ * emit-rtl.c (const_double_htab_eq): Remove unused variable.
+
+2002-09-26 Chris Lattner <sabre@nondot.org>
+
+ * ssa.c (rename_insn_1): Handle RENAME_NO_RTX correctly when
+ handling undefined values.
+
+2002-09-26 Richard Henderson <rth@redhat.com>
+
+ PR opt/7520
+ * emit-rtl.c (active_insn_p): Consider a clobber of the
+ function return value to be active even after reload.
+
+2002-09-27 Alan Modra <amodra@bigpond.net.au>
+
+ * doloop.c (doloop_modify_runtime <biv skips initial incr>): Adjust
+ by absolute loop increment, not loop increment.
+
+2002-09-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-common.h: Follow spelling conventions.
+ * cpplex.c: Likewise.
+ * cpplib.h: Likewise.
+ * gthr-dce.h: Likewise.
+ * gthr-posix.h: Likewise.
+ * optabs.c: Likewise.
+ * output.h: Likewise.
+ * profile.c: Likewise.
+ * protoize.c: Likewise.
+ * ra-rewrite.c: Likewise.
+ * real.c: Likewise.
+ * recog.c: Likewise.
+ * reg-stack.c: Likewise.
+ * regclass.c: Likewise.
+ * regmove.c: Likewise.
+ * reload.c: Likewise.
+ * reload.h: Likewise.
+ * reload1.c: Likewise.
+ * reorg.c: Likewise.
+ * resource.c: Likewise.
+ * rtl.h: Likewise.
+ * rtlanal.c: Likewise.
+
+2002-09-26 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.c (ia64_expand_load_address): Ensure correct mode
+ for symbol address.
+
+2002-09-24 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/elf.h: Add HANDLE_SYSV_PRAGMA.
+ * config/mips/elf64.h: Ditto.
+
+2002-09-24 Eric Christopher <echristo@redhat.com>
+
+ * except.c (expand_builtin_extract_return_address): Handle case
+ where Pmode != ptr_mode.
+
+2002-09-26 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/hpux.h (ASM_OUTPUT_EXTERNAL_LIBCALL): New
+
+2002-09-26 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/hpux.h (TARGET_DEFAULT): Include TARGET_ILP32.
+
+2002-09-26 Igor Shevlyakov <igor@microunity.com>
+
+ * combine.c (simplify_set): Don't call to force_to_mode if size
+ of integer type is larger than HOST_BITS_PER_WIDE_INT.
+
+2002-09-26 Janis Johnson <janis187@us.ibm.com>
+
+ * Makefile.in (qmtest-g++): Fix file path.
+
+2002-09-26 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * expr.c (expand_expr) [MINUS_EXPR]: Convert A - const to
+ A + (-const) on RTX level, even for unsigned types.
+
+2002-09-26 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * reload.c (dup_replacements): New function.
+ (find_reloads): Use it to duplicate replacements at the top level
+ of match_dup operands.
+
+2002-09-26 Miles Bader <miles@gnu.org>
+
+ * v850.md ("length"): Change default value to 4.
+
+2002-09-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog.1: Follow spelling conventions.
+ * ChangeLog.4: Likewise.
+ * ChangeLog.6: Likewise.
+ * FSFChangeLog.11: Likewise.
+ * doc/cpp.texi: Likewise.
+ * doc/invoke.texi: Likewise.
+ * doc/tm.texi: Likewise.
+
+2002-09-26 Nick Clifton <nickc@redhat.com>
+
+ * config.gcc: Add x prefix to v850e case for handling
+ --with-cpu=v850e.
+
+2002-09-25 Zack Weinberg <zack@codesourcery.com>
+
+ * gcc.c (input_suffix_matches, switch_matches,
+ mark_matching_switches, process_marked_switches,
+ process_brace_body): New functions - split from handle_braces.
+ (handle_braces): Rewrite; handle %{S:X;T:Y;:D} syntax; accept
+ and ignore whitespace in more places.
+ (specs documentation comment): Document %{S:X;T:Y;:D}.
+ Clarify other %{...} docs.
+ * doc/invoke.texi: Document %{S:X;T:Y;:D}. Clarify other
+ %{...} docs.
+
+ * config/arm/aof.h (LINK_SPEC): Change %{ov*,*} to %{ov*}.
+ * config/rs6000/sysv4.h: Use N-way choice spec syntax.
+
+2002-09-25 David S. Miller <davem@redhat.com>
+
+ PR target/7842
+ * config/sparc/sparc.c (set_extends): SImode ASHIFT does not
+ extend.
+
+2002-09-25 Richard Henderson <rth@redhat.com>
+
+ * emit-rtl.c (const_double_htab_eq): Distinguish integer and
+ fp CONST_DOUBLE; use real_identical.
+
+2002-09-25 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/invoke.texi: Add more -Wabi examples.
+
+2002-09-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (TARGET_MIPS4100): Add missing bracket.
+
+2002-09-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * profile.c (end_branch_prob): Only look for __gcov_init on
+ weak-enabled native compilers.
+
+2002-09-24 Denis Chertykov <denisc@overta.ru>
+
+ * config/ip2k/ip2k.c (function_epilogue): Fix wrong numbers in
+ cases of optimizing "add sp,w" to "inc sp".
+
+2002-09-24 Adam Nemet <anemet@lnxw.com>
+
+ * config/arm/arm.c (thumb_unexpanded_epilogue): Don't generate
+ epilogue for naked functions.
+
+2002-09-24 Adam Nemet <anemet@lnxw.com>
+ Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.h (THUMB_FUNCTION_PROFILER): Remove.
+ (FUNCTION_PROFILER): Only invoke THUMB_FUNCTION_PROFILER if it
+ is defined.
+
+2002-09-24 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (preferred_la_operand_p): New function.
+ * config/s390/s390-protos.h (preferred_la_operand_p): Declare it.
+ * config/s390/s390.md ("addaddr_esame", "*la_ccclobber"): Replace by ...
+ ("*la_64_cc", "*la_31_cc", splitters): ... these.
+ ("*la_31"): Deactivate for TARGET_64BIT.
+ ("*la_31_and", "*la_31_and_cc"): New.
+
+2002-09-24 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * real.h (real_value): Make `exp' explicitly signed.
+
+2002-09-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/elfos.h: Follow spelling conventions.
+ * config/alpha/alpha.h: Likewise.
+ * config/arc/arc.h: Likewise.
+ * config/arm/arm.md: Likewise.
+ * config/avr/avr.h: Likewise.
+ * config/cris/cris.md: Likewise.
+ * config/d30v/d30v.h: Likewise.
+ * config/frv/frv.c: Likewise.
+ * config/frv/frv.h: Likewise.
+ * config/h8300/h8300.c: Likewise.
+ * config/h8300/h8300.h: Likewise.
+ * config/h8300/h8300.md: Likewise.
+ * config/i386/cygwin.h: Likewise.
+ * config/i386/i386.h: Likewise.
+ * config/i386/sysv3.h: Likewise.
+ * config/i960/i960.h: Likewise.
+ * config/ia64/ia64.h: Likewise.
+ * config/ia64/ia64.md: Likewise.
+ * config/ip2k/ip2k.h: Likewise.
+ * config/m32r/m32r.h: Likewise.
+ * config/m68k/m68k.h: Likewise.
+ * config/m88k/m88k.h: Likewise.
+ * config/mcore/mcore.c: Likewise.
+ * config/mcore/mcore.h: Likewise.
+ * config/mcore/mcore.md: Likewise.
+ * config/mips/mips.h: Likewise.
+ * config/mmix/mmix.h: Likewise.
+ * config/mmix/mmix.md: Likewise.
+ * config/ns32k/netbsd.h: Likewise.
+ * config/ns32k/ns32k.h: Likewise.
+ * config/ns32k/ns32k.md: Likewise.
+ * config/pa/pa.h: Likewise.
+ * config/romp/romp.h: Likewise.
+ * config/rs6000/rs6000.h: Likewise.
+ * config/rs6000/rs6000.md: Likewise.
+ * config/sparc/sparc.h: Likewise.
+ * config/stormy16/stormy-abi: Likewise.
+ * config/stormy16/stormy16.h: Likewise.
+ * config/vax/vax.h: Likewise.
+
+2002-09-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.h: Remove commented-out macro
+ definitions of HAVE_{POST|PRE}_{INC|DEC}REMENT.
+ * config/avr/avr.h: Likewise.
+ * config/d30v/d30v.h: Likewise.
+ * config/dsp16xx/dsp16xx.h: Likewise.
+ * config/i370/i370.h: Likewise.
+ * config/i386/i386.h: Likewise.
+ * config/i960/i960.h: Likewise.
+ * config/m68k/m68k.h: Likewise.
+ * config/m88k/m88k.h: Likewise.
+ * config/mips/mips.h: Likewise.
+ * config/ns32k/ns32k.h: Likewise.
+ * config/pdp11/pdp11.h: Likewise.
+ * config/romp/romp.h: Likewise.
+ * config/rs6000/rs6000.h: Likewise.
+ * config/s390/s390.h: Likewise.
+ * config/sh/sh.h: Likewise.
+ * config/sparc/sparc.h: Likewise.
+ * config/stormy16/stormy16.h: Likewise.
+ * config/vax/vax.h: Likewise.
+
+2002-09-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * function.c (push_temp_slots_for_block): Remove.
+ (push_temp_slots_for_target): Likewise.
+ (get_target_temp_slot_level): Likewise.
+ (set_target_temp_slot_level): Likewise.
+ (get_first_block_beg): Likewise.
+ * function.h: Remove corresponding prototypes.
+
+2002-09-23 Zack Weinberg <zack@codesourcery.com>
+
+ * version.c (version_string): Now const char[].
+ * version.h: Update to match.
+
+2002-09-23 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.h (MASK_ACCUMULATE_OUTGOING_ARGS_SET, MASK_MMX_SET,
+ MASK_SSE_SET, MASK_SSE2_SET, MASK_3DNOW_SET, MASK_3DNOW_A_SET): Kill.
+ (TARGET_SWITCHES): Don't reference them.
+ * config/i386/i386.c (override_options): Use target_flags_explicit
+ to examine bits set by the user.
+
+2002-09-23 Dale Johannesen <dalej@apple.com>
+
+ * dbxout.c (dbxout_parms): Set current_sym_code for params
+ passed on stack by invisible reference.
+
+2002-09-23 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm/unknown-elf.h (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Always allocate
+ at least one byte of space.
+
+2002-09-23 Mark Mitchell <mark@codesourcery.com>
+
+ * c-common.h (flag_abi_version): Fix typo in comment.
+ * doc/invoke.texi (flag_abi_version): Document default value.
+
+2002-09-23 Hans-Peter Nilsson <hp@axis.com>
+
+ * doc/extend.texi (Extended Asm): Clarify that overlap between
+ asm-declared register variables used in an asm and the asm clobber
+ list is not allowed.
+ * stmt.c (decl_conflicts_with_clobbers_p): New function.
+ (expand_asm_operands): Keep track of clobbered registers. Call
+ decl_conflicts_with_clobbers_p for each input and output operand.
+ If no conflicts found before, also do conflict sanity check when
+ emitting clobbers.
+
+2002-09-23 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (cpp_define_data_format): Remove.
+ (cb_register_builtins): Don't define __WCHAR_BIT__, __SHRT_BIT__,
+ __INT_BIT__, __LONG_BIT__, __LONG_LONG_BIT__, __FLOAT_BIT__,
+ __DOUBLE_BIT__, __LONG_DOUBLE_BIT__.
+ * doc/cpp.texi: Don't document them either.
+ (__SCHAR_MAX__, __SHRT_MAX__, __INT_MAX__, __LONG_MAX__,
+ __LONG_LONG_MAX__): Document.
+ (__TARGET_FLOAT_FORMAT__): Remove.
+
+2002-09-23 Richard Henderson <rth@redhat.com>
+
+ * real.c (do_multiply): Normalize U before addition.
+
+2002-09-23 Mark Mitchell <mark@codesourcery.com>
+
+ * c-common.c (flag_abi_version): New variable.
+ * c-common.h (flag_abi_version): Declare it.
+ * c-opts.c (missing_arg): Add -fabi-version.
+ (c_common_decode_option): Process -fabi-version.
+ * doc/invoke.texi (-fabi-version): Document it.
+ (-Wabi): Add information about bit-fields in unions.
+
+2002-09-22 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (STORE_BY_PIECES_P): New target macro.
+ (can_store_by_pieces, store_by_pieces): Use STORE_BY_PIECES_P
+ instead of MOVE_BY_PIECES_P.
+ * doc/tm.texi: Document this new macro.
+
+2002-09-22 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/mips/netbsd.h (SUBTARGET_ASM_SPEC): Always pass -KPIC
+ unless -fno-pic or -fno-PIC is specified.
+
+2002-09-22 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * c-common.c (preprocessing_trad_p): Define.
+ * pa-hiux.h, pa-hpux.h, pa-hpux7.h (CPP_PREDEFINES): Delete.
+ (TARGET_OS_CPP_BUILTINS, SUBTARGET_SWITCHES): Define.
+ * pa-hpux10.h (TARGET_OS_CPP_BUILTINS, CPP_SPEC): Define.
+ * pa-hpux11.h (TARGET_OS_CPP_BUILTINS): Define.
+ * pa-linux.h (CPP_PREDEFINES): Delete.
+ (TARGET_OS_CPP_BUILTINS, CPP_SPEC): Define.
+ * pa32-linux.h, pa64-linux.h (CPP_SPEC): Delete.
+ * pa-osf.h, pa-pro-end.h, rtems.h (CPP_PREDEFINES): Delete.
+ (TARGET_OS_CPP_BUILTINS): Define.
+ * pa.h (MASK_SIO, TARGET_SIO, TARGET_PA_10): Define.
+ (TARGET_SWITCHES): Reformat. Use N_() macro. Add SUBTARGET_SWITCHES.
+ (SUBTARGET_SWITCHES): Provide default definition.
+ (TARGET_OPTIONS): Reformat. Use N_() macro.
+ (CPP_PA10_SPEC, CPP_PA11_SPEC, CPP_PA20_SPEC, CPP_64BIT_SPEC,
+ CPP_CPU_DEFAULT_SPEC, CPP_64BIT_DEFAULT_SPEC, SUBTARGET_EXTRA_SPECS,
+ EXTRA_SPECS, CPP_SPEC, CPLUSPLUS_CPP_SPEC, CPP_PREDEFINES): Delete.
+ (TARGET_CPU_CPP_BUILTINS): Define.
+ (TARGET_OS_CPP_BUILTINS): Define for BSD-like systems.
+ * doc/invoke.texi (msio, mwsio): Document new hppa options.
+ * doc/tm.texi (TARGET_CPU_CPP_BUILTINS): Document macro
+ preprocessing_trad_p().
+
+2002-09-22 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * doc/install.texi: Document behavior of --with-headers and
+ --with-libs when arguments are omitted.
+
+2002-09-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * dbxout.c: Follow spelling conventions.
+ * defaults.h: Likewise.
+ * df.c: Likewise.
+ * diagnostic.h: Likewise.
+ * doloop.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * dwarfout.c: Likewise.
+ * emit-rtl.c: Likewise.
+ * except.c: Likewise.
+ * explow.c: Likewise.
+ * expmed.c: Likewise.
+ * expr.c: Likewise.
+ * expr.h: Likewise.
+ * flags.h: Likewise.
+ * flow.c: Likewise.
+ * fold-const.c: Likewise.
+ * function.c: Likewise.
+ * function.h: Likewise.
+ * gcc.c: Likewise.
+ * gcov-io.h: Likewise.
+ * gcov.c: Likewise.
+ * gcse.c: Likewise.
+ * genattrtab.c: Likewise.
+ * genconfig.c: Likewise.
+ * genrecog.c: Likewise.
+ * ggc-page.c: Likewise.
+ * ggc.h: Likewise.
+ * global.c: Likewise.
+ * gthr-win32.h: Likewise.
+ * integrate.c: Likewise.
+ * jump.c: Likewise.
+ * langhooks.c: Likewise.
+ * langhooks.h: Likewise.
+ * line-map.h: Likewise.
+ * local-alloc.c: Likewise.
+ * longlong.h: Likewise.
+ * loop.c: Likewise.
+ * loop.h: Likewise.
+
+Tue Aug 27 22:26:35 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.h (BIGGEST_FIELD_ALIGNMENT): Set proper default for x86_64.
+
+Tue Aug 27 20:07:01 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (overwrite_options): Set -mpreferred-stack-boundary to 128
+ for -Os/TARGET_64BIT too.
+
+2002-09-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.0: Likewise.
+ * ChangeLog.1: Likewise.
+ * ChangeLog.2: Likewise.
+ * ChangeLog.3: Likewise.
+ * ChangeLog.4: Likewise.
+ * ChangeLog.5: Likewise.
+ * ChangeLog.6: Likewise.
+ * FSFChangeLog.10: Likewise.
+ * FSFChangeLog.11: Likewise.
+ * alias.c: Likewise.
+ * basic-block.h: Likewise.
+ * c-aux-info.c: Likewise.
+ * c-common.c: Likewise.
+ * c-common.h: Likewise.
+ * c-decl.c: Likewise.
+ * c-format.c: Likewise.
+ * c-semantics.c: Likewise.
+ * c-typeck.c: Likewise.
+ * calls.c: Likewise.
+ * cfganal.c: Likewise.
+ * cfgloop.c: Likewise.
+ * collect2.c: Likewise.
+ * combine.c: Likewise.
+ * conflict.c: Likewise.
+ * cppexp.c: Likewise.
+ * cppfiles.c: Likewise.
+ * cpphash.h: Likewise.
+ * cppinit.c: Likewise.
+ * cpplex.c: Likewise.
+ * cpplib.c: Likewise.
+ * cpplib.h: Likewise.
+ * cppmacro.c: Likewise.
+ * cse.c: Likewise.
+
+2002-09-21 Richard Earnshaw <rearnsha@arm.com>
+
+ * netbsd-aout.h (NETBSD_LINK_SPEC_AOUT): New, takes old definition of
+ LINK_SPEC.
+ (LINK_SPEC): Define to NETBSD_LINK_SPEC_AOUT.
+ * arm/netbsd.h (SUBTARGET_EXTRA_SEPCS): Add NETBSD_LINK_SPEC_AOUT.
+ (LINK_SPEC): Rework to use NETBSD_LINK_SPEC_AOUT).
+
+2002-09-21 Richard Earnshaw <rearnsha@arm.com>
+
+ PR opt/7930
+ * cse.c (fold_rtx): Calculate old_cost before we fold each
+ operand.
+
+2002-09-21 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (cpp_define_data_format): Remove __GCC_LITTLE_ENDIAN__,
+ __GCC_BIG_ENDIAN__, __TARGET_BITS_ORDER__, __TARGET_BYTES_ORDER__,
+ __TARGET_INT_WORDS_ORDER__, __TARGET_FLOAT_WORDS_ORDER__,
+ __TARGET_USES_VAX_F_FLOAT__, __TARGET_USES_VAX_D_FLOAT__,
+ __TARGET_USES_VAX_G_FLOAT__, __TARGET_USES_VAX_H_FLOAT__.
+ * doc/cpp.texi: Don't document them.
+
+2002-09-21 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (builtin_define_float_constants): Use real_format
+ to get the floating-point parameters.
+
+2002-09-21 Richard Henderson <rth@redhat.com>
+
+ * real.c (struct real_format): Move to real.h.
+ (real_format_for_mode): Rename from fmt_for_mode; update all users;
+ initialize with ieee defaults.
+ (real_to_target_fmt, real_from_target_fmt): New.
+ (ieee_single_format, ieee_double_format, ieee_extended_motorola_format,
+ ieee_extended_intel_96_format, ieee_extended_intel_128_format,
+ ieee_quad_format, i370_single_format, i370_double_format,
+ c4x_single_format, c4x_extended_format): Rename from s/_format//.
+ (ieee_quad_format): Fix emin.
+ (format_for_size, init_real_once): Remove.
+ * real.h (struct real_format): Move from real.c.
+ (real_format_for_mode): Declare.
+ (real_to_target_fmt, real_from_target_fmt): Declare.
+ (ieee_single_format, ieee_double_format, ieee_extended_motorola_format,
+ ieee_extended_intel_96_format, ieee_extended_intel_128_format,
+ ieee_quad_format, vax_f_format, vax_d_format, vax_g_format,
+ i370_single_format, i370_double_format, c4x_single_format,
+ c4x_extended_format): Declare.
+ * toplev.c (do_compile): Don't call init_real_once.
+
+ * defaults.h (INTEL_EXTENDED_IEEE_FORMAT): Remove.
+ * doc/tm.texi (INTEL_EXTENDED_IEEE_FORMAT): Remove.
+
+ * config/alpha/alpha.h (TARGET_FLOAT_FORMAT): Define.
+ * config/alpha/osf5.h (LONG_DOUBLE_TYPE_SIZE): 64, if vax mode.
+ * config/alpha/alpha.c (override_options): Set real_format_for_mode
+ for VAX, if enabled.
+
+ * config/c4x/c4x.c (c4x_override_options): Set real_format_for_mode
+ for C4X.
+
+ * config/i370/i370.h (OVERRIDE_OPTIONS): New.
+ * config/i370/i370.c (override_options): New.
+ * config/i370/i370-protos.h: Update.
+
+ * config/i386/i386.c (override_options): Set real_format_for_mode
+ for Intel 80-bit extended.
+ * config/i386/i386.h (INTEL_EXTENDED_IEEE_FORMAT): Remove.
+
+ * config/i960/i960.h (LONG_DOUBLE_TYPE_SIZE): Mind -mlong-double-64.
+ (OVERRIDE_OPTIONS): Move code...
+ * config/i960/i960.c (i960_initialize): ... here. Set
+ real_format_for_mode for Intel 80-bit extended.
+
+ * config/ia64/ia64.c (ia64_override_options): Set real_format_for_mode
+ for Intel 80-bit extended, if enabled.
+
+ * config/m68k/m68k.c (override_options): Set real_format_for_mode
+ for Motorola 96-bit extended.
+
+ * config/vax/vax.h (OVERRIDE_OPTIONS): New.
+ * config/vax/vax.c (override_options): New.
+ * config/vax/vax-protos.h: Update.
+
+2002-09-21 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.md (builtin_setjmp_receiver): Add
+ #if TARGET_MACHO.
+
+ * config/rs6000/rs6000.md (floatdisf2_internal2): Combine
+ insns. Supply missing clobber of scratch reg.
+
+2002-09-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.c: Follow spelling conventions.
+ * config/m32r/m32r.h: Likewise.
+ * config/m32r/m32r.md: Likewise.
+ * config/m68k/m68k.c: Likewise.
+ * config/m88k/m88k.c: Likewise.
+ * config/mcore/mcore.c: Likewise.
+ * config/mips/mips.c: Likewise.
+ * config/mips/mips.h: Likewise.
+ * config/mmix/mmix.c: Likewise.
+ * config/mn10200/mn10200.c: Likewise.
+ * config/ns32k/ns32k.h: Likewise.
+ * config/pa/pa.c: Likewise.
+ * config/pa/pa64-linux.h: Likewise.
+ * config/pdp11/pdp11.h: Likewise.
+ * config/romp/romp.c: Likewise.
+ * config/romp/romp.h: Likewise.
+ * config/rs6000/eabi.asm: Likewise.
+ * config/rs6000/linux64.h: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/rs6000/rs6000.h: Likewise.
+ * config/rs6000/rs6000.md: Likewise.
+ * config/rs6000/sysv4.h: Likewise.
+ * config/rs6000/xcoff.h: Likewise.
+
+2002-09-20 Jim Wilson <wilson@redhat.com>
+
+ * config/v850/v850/lib1funcs.asm (__muldi3): Change r5 to r28.
+
+2002-09-20 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.md (UNSPEC_GOTNTPOFF, UNSPEC_INDNTPOFF): New.
+ * config/i386/i386.c (legitimate_pic_address_disp_p): Handle
+ UNSPEC_GOTNTPOFF and UNSPEC_INDNTPOFF like UNSPEC_GOTTPOFF.
+ (legitimate_address_p): Likewise.
+ (legitimize_address): Use @gotntpoff and @indntpoff.
+ (output_pic_addr_const): Handle UNSPEC_GOTNTPOFF and UNSPEC_INDNTPOFF.
+ (output_addr_const_extra): Likewise.
+
+2002-09-20 Jim Wilson <wilson@redhat.com>
+
+ * combine.c (try_combine): When split an instruction pair, where the
+ first has a sign_extend src, verify that the src and dest modes match.
+
+2002-09-20 Richard Henderson <rth@redhat.com>
+
+ * config/mips/mips.c (dfhigh, dflow, sfhigh, sflow): Remove.
+ (override_options): Do not initialize them.
+ (mips_const_double_ok): Allow no fp constants except zero,
+ and not even that for mips16.
+ (const_float_1_operand): Use dconst1.
+ * config/mips/mips.md (movsf, movsf_internal1, movsf_internal2,
+ movdf, movdf_internal1, movdf_internal1a, movdf_internal2):
+ Don't allow arbitrary constants; fix predicates and C constraint.
+
+2002-09-20 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppmacro.c: Don't warn about function-like macros without
+ '(' during pre-expansion.
+
+2002-09-20 Jim Wilson <wilson@redhat.com>
+
+ * config/v850/v850.c (current_function_anonymous_args): Delete.
+ (expand_prologue): Use current_function_args_info.anonymous_args.
+ (expand_epilogue): Delete use of current_function_anonymous_args.
+ * config/v850/v850.h (struct cum_arg): Add anonymous_args field.
+ (INIT_CUMULATIVE_ARGS): Clear anonymous_args field.
+ (current_function_anonymous_args): Delete extern declaration.
+ (SETUP_INCOMING_VARARGS): Set anonymous_args field.
+
+2002-09-20 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_prologue): Update for change
+ to load_macho_picbase.
+ * config/rs6000/rs6000.md: Document Darwin-specific unspec IDs.
+ (load_macho_picbase): Take the symbol to use as a parameter.
+ (macho_correct_pic): New insn.
+ (builtin_setjmp_reciever): On Darwin, restore the PIC register.
+
+ * config/rs6000/rs6000.h (ELIMINABLE_REGS): Use
+ RS6000_PIC_OFFSET_TABLE_REGNUM rather than hardcoding 30.
+ (CAN_ELIMINATE): Likewise.
+ (INITIAL_ELIMINATION_OFFSET): Likewise.
+ (TOC_REGISTER): Likewise.
+
+2002-09-20 Richard Henderson <rth@redhat.com>
+
+ * real.c (real_hash): New.
+ * real.h: Declare it.
+ * cse.c (canon_hash): Use it.
+ * cselib.c (hash_rtx): Likewise.
+ * emit-rtl.c (const_double_htab_hash): Likewise.
+ * rtl.h (CONST_DOUBLE_REAL_VALUE): New.
+ * varasm.c (struct rtx_const): Reduce vector size; separate
+ integer and fp vectors.
+ (HASHBITS): Remove.
+ (const_hash_1): Rename from const_hash. Use real_hash. Do not
+ take modulus MAX_HASH_TABLE.
+ (const_hash): New. Do take modulus MAX_HASH_TABLE.
+ (output_constant_def): Do not take modulus MAX_HASH_TABLE.
+ (SYMHASH): Don't use HASHBITS.
+ (decode_rtx_const): Copy only active bits from REAL_VALUE_TYPE.
+ Fix CONST_VECTOR thinko wrt fp vectors. Fix kind comparison.
+ (simplify_subtraction): Fix kind comparison.
+ (const_hash_rtx): Return unsigned int. Don't use HASHBITS.
+ Use a union to pun integer array.
+ * config/rs6000/rs6000.c (rs6000_hash_constant): Use real_hash;
+ only hash two words of integral CONST_DOUBLE.
+
+2002-09-20 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/hpux.h (STARTFILE_SPEC): Modify.
+ (STARTFILE_PREFIX_SPEC): New.
+ (LINK_SPEC): Modify.
+ (LIB_SPEC): Modify.
+ (LIBGCC_SPEC): New.
+
+2002-09-20 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (legitimate_pic_address_disp_p): Allow
+ UNSPEC_NTPOFF and UNSPEC_DTPOFF to be offsetted by constant.
+
+2002-09-20 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
+
+ * config/arm/arm.md (sign_extract_onebit, not_signextract_onebit):
+ Add clobber of the condition code register.
+
+2002-09-20 Richard Henderson <rth@redhat.com>
+
+ * real.c (do_fix_trunc): Static.
+ (encode_ieee_single, encode_ieee_double, encode_ieee_extended,
+ encode_ieee_quad, encode_vax_f, encode_vax_d, encode_vax_g,
+ encode_i370_single, encode_i370_double, encode_c4x_single,
+ encode_c4x_extended): Add default abort case.
+
+2002-09-20 Richard Henderson <rth@redhat.com>
+
+ * real.h (enum real_value_class, SIGNIFICAND_BITS, EXP_BITS,
+ MAX_EXP, SIGSZ, SIG_MSB, struct real_value): Move from real.c.
+ (struct realvaluetype): Remove.
+ (REAL_VALUE_TYPE): Use struct real_value.
+ (REAL_VALUE_TYPE_SIZE): Use SIGNIFICAND_BITS.
+ (test_real_width): New.
+ * real.c: Global replace struct real_value with REAL_VALUE_TYPE.
+ (real_arithmetic): Avoid hoops for REAL_VALUE_TYPE parameters.
+ (real_compare, real_exponent, real_ldexp, real_isinf, real_isnan,
+ real_isneg, real_isnegzero, real_identical, exact_real_inverse,
+ real_to_integer, real_to_integer2, real_to_decimal,
+ real_to_hexadecimal, real_from_string, real_from_integer,
+ real_inf, real_nan, real_2expN, real_convert, real_to_target,
+ real_from_target): Likewise.
+ * tree.h (struct tree_real_cst): Use real_value not realvaluetype.
+ * gengtype-yacc.y (bitfieldopt): Accept an ID as well.
+
+2002-09-20 Richard Henderson <rth@redhat.com>
+
+ * real.h (UNKNOWN_FLOAT_FORMAT, IEEE_FLOAT_FORMAT, VAX_FLOAT_FORMAT,
+ IBM_FLOAT_FORMAT, C4X_FLOAT_FORMAT, TARGET_FLOAT_FORMAT): Move ...
+ * defaults.h: ... here.
+ * config/arm/arm.h, config/avr/avr.h, config/d30v/d30v.h,
+ config/fr30/fr30.h, config/frv/frv.h, config/ia64/ia64.h,
+ config/ip2k/ip2k.h, config/mips/mips.h, config/stormy16/stormy16.h,
+ config/xtensa/xtensa.h (TARGET_FLOAT_FORMAT): Remove.
+
+2002-09-20 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/mmix/mmix.md ("negdf2"): Rewrite.
+ ("*expanded_negdf2"): New.
+
+2002-09-19 Jim Wilson <wilson@redhat.com>
+
+ * combine.c (simplify_set): When optimizing a subreg src with a
+ cc0 dest, use GET_MODE (src) for mask instead of inner_mode.
+
+2002-09-19 Dale Johannesen <dalej@apple.com>
+ * combine.c (make_extraction): Don't create
+ invalid subreg.
+
+2002-09-19 Roger Sayle <roger@eyesopen.com>
+
+ * tree.c (integer_nonzerop): New predicate for nonzero integers.
+ * tree.h (integer_nonzerop): Add function prototype.
+ * stmt.c (expand_end_loop): Don't rotate the loop when there
+ are no instructions in the test, i.e. the loop is unconditional.
+ (expand_exit_loop_if_false): Optimize RTL generation of loop
+ tests when the condition is always true or always false.
+ * c-semantics.c (genrtl_do_stmt): Optimize RTL generation of
+ do-loops when the condition is always true.
+ (genrtl_for_stmt): Optimize RTL generation of for-loops when
+ the for-expression is empty.
+
+2002-09-19 Zack Weinberg <zack@codesourcery.com>
+
+ * gcc.c (use_pipes): New flag.
+ (process_command): Set it. Adjust check for -pipe conflicting
+ with -time or -save-temps.
+ (do_spec_1): Use it. Handle %|SUFFIX, %mSUFFIX, and
+ %<SWITCH. Drop %| (without a SUFFIX).
+ (handle_braces): Drop %{<SWITCH}, %{^SWITCH}, %{|...}.
+ (give_switch): Third argument eliminated.
+ (invoke_as, @assembler_with_cpp spec): Use %|.s or %m.s
+ depending on AS_NEEDS_DASH_FOR_PIPED_INPUT.
+ (specs documentation comment): Update.
+
+ * config/netbsd-aout.h, config/openbsd.h, config/ptx4.h,
+ config/svr4.h, config/i386/freebsd-aout.h,
+ config/m68k/netbsd-elf.h, config/m68k/netbsd.h,
+ config/m68k/openbsd.h, config/mips/openbsd.h,
+ config/sparc/sparc.h: Define AS_NEEDS_DASH_FOR_PIPED_INPUT
+ instead of putting %| into ASM_SPEC and/or ASM_FINAL_SPEC.
+ * config/avr/avr.h: Delete do-nothing ASM_FINAL_SPEC.
+ * config/cris/cris.h: Update comment.
+
+ * ada/lang-specs.h: Use %(invoke_as). Straighten out
+ error messages. Don't use %{^SWITCH}.
+ * ada/misc.c (gnat_decode_option): Handle -I with a
+ separate argument.
+
+ * f/lang-specs.h: Use %| and %m.
+ * java/jvspec.c: Use %m and %(invoke_as). Change all
+ uses of %{<SWITCH} to %<SWITCH.
+
+ * doc/invoke.texi: Update documentation of specs.
+ * doc/tm.texi: Document AS_NEEDS_DASH_FOR_PIPED_INPUT.
+
+2002-09-19 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (addr_generation_dependency_p): Handle SUBREG
+ and STRICT_LOW_PART within SET_DEST.
+ * config/s390/s390.md ("*extractqi", "*extracthi"): New insns with
+ splitters, replacing pre-reload splitters.
+ ("*zero_extendhisi2_31", "*zero_extendqisi2_31",
+ "*zero_extendqihi2_31"): New insns.
+ ("*zero_extendqihi2_64"): Do not clobber CC.
+
+2002-09-18 Devang Patel <dpatel@apple.com>
+
+ * cp/cp-tree.h: New prototype for walk_vtables().
+ * cp/decl.c (walk_vtables_r): New function.
+ (struct cp_binding_level): Add new members, namespaces,
+ names_size and vtables.
+ (add_decl_to_level): Add decl in namespaces or vtables
+ chain, if conditions match.
+ (walk_vtables): New function.
+ (walk_namespaces_r): Travers separate namespace chain
+ for namespace decls.
+ (wrapup_globals_for_namespace): Use names_size instead
+ of list_length().
+ * cp/decl2.c (finish_file): Use walk_vtables() instead of
+ walk_globals() to walk vtable decls.
+
+2002-09-19 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/hpux.h (CTORS_SECTION_ASM_OP): New.
+ (DTORS_SECTION_ASM_OP): Ditto.
+ (READONLY_DATA_SECTION_ASM_OP): Moved.
+ (DATA_SECTION_ASM_OP): New.
+ (SDATA_SECTION_ASM_OP): New.
+ (BSS_SECTION_ASM_OP): New.
+ (SBSS_SECTION_ASM_OP): New.
+ (TEXT_SECTION_ASM_OP): New.
+
+2002-09-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/fp-bit.c: Follow spelling conventions.
+ * config/d30v/d30v.c: Likewise.
+ * config/d30v/d30v.h: Likewise.
+ * config/fr30/fr30.c: Likewise.
+ * config/fr30/fr30.h: Likewise.
+ * config/fr30/fr30.md: Likewise.
+ * config/frv/frv.c: Likewise.
+ * config/frv/frv.h: Likewise.
+ * config/h8300/h8300.c: Likewise.
+ * config/h8300/lib1funcs.asm: Likewise.
+ * config/i370/i370.c: Likewise.
+ * config/i386/i386.h: Likewise.
+ * config/i386/i386.md: Likewise.
+ * config/i386/pentium.md: Likewise.
+ * config/i386/winnt.c: Likewise.
+ * config/i960/i960.c: Likewise.
+ * config/ia64/ia64.h: Likewise.
+ * config/ip2k/ip2k.c: Likewise.
+ * config/ip2k/ip2k.h: Likewise.
+ * config/ip2k/ip2k.md: Likewise.
+ * config/ip2k/libgcc.S: Likewise.
+
+2002-09-19 Stephen Clarke <stephen.clarke@superh.com>
+
+ * config/sh/sh.h (UNSPEC_GOTOFF_P): Define.
+ (GOTOFF_P): Extend to allow gotoff plus constant.
+
+2002-09-18 Richard Henderson <rth@redhat.com>
+
+ * ifcvt.c (noce_process_if_block): Correctly detect X modified
+ with INSN_B before COND_EARLIEST. Don't check A and B for
+ modification in condition range. Reorder INSN_B for A==B properly.
+ (if_convert): Iterate until no matches for a block.
+
+2002-09-18 Richard Henderson <rth@redhat.com>
+
+ * calls.c (store_one_arg): Rename default_align to parm_align;
+ always adjust parm_align for downward padding.
+
+2002-09-18 Richard Henderson <rth@redhat.com>
+
+ * toplev.c (backend_init): Move init_real_once invocation ...
+ (do_compile): ... here.
+
+2002-09-18 Richard Henderson <rth@redhat.com>
+
+ * sibcall.c (optimize_sibling_and_tail_recursive_call): Also remove
+ RTX_UNCHANGING_P markers for successful tail-recursive replacement.
+
+2002-09-18 Richard Henderson <rth@redhat.com>
+
+ * real.c (round_for_format): Collect sticky as unsigned long, not bool.
+
+2002-09-19 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.md: (floatdisf2): Rename to
+ floatdisf2_internal1.
+ (floatdisf2): New define_expand.
+ (floatdisf2_internal2): Likewise.
+
+2002-09-18 Richard Henderson <rth@redhat.com>
+
+ * real.c (sticky_rshift_significand): Collect sticky as
+ unsigned long, not bool.
+
+2002-09-18 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_address_cost): New function.
+ config/s390/s390-protos.h (s390_address_cost): Add prototype.
+ config/s390/s390.h (ADDRESS_COST): Call s390_address_cost.
+ (RTX_COST): Use COSTS_N_INSNS.
+
+2002-09-18 Douglas Rupp <rupp@gnat.com>
+ Donn Terry <donnte@microsoft.com>
+
+ * stor-layout.c (place_field): Handle alignment of whole
+ structures when MSVC compatible bitfields are involved.
+ Change method of computing location of MS bitfields to
+ be compatible with #pragma pack(n).
+
+ * tree.h (record_layout_info): Add new field
+ remaining_in_alignment.
+
+ * doc/tm.texi: (TARGET_MS_BITFIELD_LAYOUT_P): Update.
+ (pragma pack): Add paragraph on MSVC bitfield packing.
+
+2002-09-18 Richard Earnshaw (reanrsha@arm.com)
+
+ PR optimization/7967
+ * arm.md (ne_zeroextractsi): Add clobber of the condition code
+ register.
+
+2002-09-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/s390/s390.c: Follow spelling conventions.
+ * config/sh/lib1funcs.asm: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/sh/sh.h: Likewise.
+ * config/sparc/sparc.c: Likewise.
+ * config/sparc/sparc.h: Likewise.
+ * config/sparc/sparc.md: Likewise.
+ * config/stormy16/stormy16.c: Likewise.
+ * config/stormy16/stormy16.h: Likewise.
+ * config/v850/v850.c: Likewise.
+ * config/v850/v850.h: Likewise.
+ * config/vax/vax.c: Likewise.
+ * config/vax/vax.h: Likewise.
+
+2002-09-18 Nick Clifton <nickc@redhat.com>
+
+ * config/rs60000/rs6000.c (rs6000_emit_move): Handle V1DImode moves.
+ * config/rs60000/rs6000.c (SPE_VECTOR_MODE): Include V1DImode.
+ * config/rs6000/spe.md (movv1di, movv1di_internal): New patterns.
+
+2002-09-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * function.c (max_parm_reg_num): Remove.
+ * stmt.c (in_control_zone_p, stmt_loop_nest_empty,
+ drop_through_at_end_p, move_cleanups_up,
+ expand_end_case_dummy, case_index_expr_type): Likewise.
+ * stor-layout.c (pos_from_byte): Likewise.
+ * tree.c (chain_member_value, chain_member_purpose, listify,
+ tree_int_cst_msb, index_type_equal): Likewise.
+ * tree.h: Remove prototypes for unused functions.
+
+2002-09-17 Zack Weinberg <zack@codesourcery.com>
+
+ * ABOUT-GCC-NLS: Remove reference to enquire, and out-of-date
+ statement that the only translation is to en_UK.
+
+2002-09-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.c: Follow spelling conventions.
+ * config/alpha/alpha.h: Likewise.
+ * config/alpha/alpha.md: Likewise.
+ * config/arc/arc.h: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/arm/arm.h: Likewise.
+ * config/arm/arm.md: Likewise.
+ * config/arm/pe.c: Likewise.
+ * config/arm/unknown-elf.h: Likewise.
+ * config/avr/avr.c: Likewise.
+ * config/avr/avr.h: Likewise.
+ * config/c4x/c4x.c: Likewise.
+ * config/cris/cris.c: Likewise.
+ * config/cris/cris.h: Likewise.
+
+2002-09-17 Samuel Figueroa <figueroa@apple.com>
+
+ * final.c (final_scan_insn): Use new macro ASM_OUTPUT_ALIGN_WITH_NOP.
+ * config/sparc/sparc.h (ASM_OUTPUT_ALIGN_WITH_NOP) New macro.
+ * doc/tm.texi (ASM_OUTPUT_ALIGN_WITH_NOP) New description.
+
+2002-09-17 Dale Johannesen <dalej@apple.com>
+
+ * cfgcleanup.c (try_forward_edges): Do not forward a
+ branch to just after a loop exit before loop optimization;
+ this interfered with doloop detection.
+
+2002-09-17 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.c (output_return_instruction): Do not
+ writeback the stack pointer when it is being loaded.
+ (arm_output_epilogue): Likewise.
+
+2002-09-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * optabs.c (prepare_cmp_insn): Let emit_library_call_value
+ generate a pseudo reg that receives the result of a libcall.
+ (prepare_float_lib_cmp): Likewise.
+
+2002-09-17 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/elf.h: Remove CPP_PREDEFINES.
+
+Tue Sep 17 13:58:04 2002 Nicola Pero <n.pero@mi.flashnet.it>
+
+ Fix PR/7014 and related objc bugs:
+ * c-typeck.c (comp_target_types): Added a reflexive argument.
+ Pass it to ObjC when/if calling objc_comptypes(). Updated all
+ callers to provide the appropriate reflexive argument.
+ * objc/objc-act.c (objc_comptypes): Carefully checked and fixed
+ typechecking for all cases of comparisons and assignments,
+ particularly the obscure and less common ones involving protocols.
+
+2002-09-17 Nick Clifton <nickc@redhat.com>
+
+ * machmode.def (V1DImode): New mode. A single element vector.
+ * tree.h (TI_UV1DI_TYPE, TI_V1DI_TYPE): New tree_index enums.
+ (unsigned_V1DI_type_node, V1D1_type_node): New type nodes.
+ * tree.c (build_common_tree_nodes_2): Build
+ unsigned_V1DI_type_node and V1D1_type_node.
+ * c-common.c (c_common_type_for_mode): Return
+ unsigned_V1DI_type_node or V1D1_type_node for V1DImode.
+ * rtl.c (class_narrowest_): Start integer vector nodes with V1DImode.
+
+Tue Sep 17 13:40:13 2002 Nicola Pero <n.pero@mi.flashnet.it>
+
+ * doc/objc.texi (Constant string objects): Extended documentation
+ to make clear that the constant string class ivar layout is
+ completely fixed.
+
+2002-09-17 Roger Sayle <roger@eyesopen.com>
+
+ * cfgrtl.c (flow_delete_block_noexpunge): Delete orphaned
+ NOTE_INSN_LOOP_CONT notes when deleting basic blocks.
+
+2002-09-16 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * config/mips/mips.c (save_restore_insns): Remove unused variable.
+ * gcc.c (make_relative_prefix): Likewise.
+ * loop.c (check_final_value): Likewise.
+ * jump.c (init_label_info): Remove return value.
+ * cse.c (prev_insn): Move variable between #ifdef HAVE_cc0 ... #endif.
+
+2002-09-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * dsp16xx.h (ASM_FORMAT_PRIVATE_NAME): Delete.
+ (ASM_PN_FORMAT): Define.
+
+2002-09-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alpha.h, alpha/vms.h, arc.h, arm/aof.h, arm/aout.h, avr.h,
+ c4x.h, cris.h, d30v.h, fr30.h, frv.h, h8300.h, i370.h, i386.h,
+ i960.h, ia64.h, ip2k.h, m32r.h, m68hc11.h, m68k/3b1.h,
+ m68k/hp320.h, m68k.h, m68k/mot3300.h, m68k/sgs.h, m68k/tower-as.h,
+ m88k.h, mcore.h, mips.h, mmix.h, mn10200.h, mn10300.h, ns32k.h,
+ pa.h, pdp11.h, romp.h, rs6000.h, s390/linux.h, sh.h, sparc.h,
+ stormy16.h, v850.h, vax.h, xtensa.h (ASM_FORMAT_PRIVATE_NAME):
+ Delete.
+ * alpha/vms.h, h8300.h, i370.h, ia64.h, m68k/3b1.h, m68k/hp320.h,
+ m68k/mot3300.h, m68k/sgs.h, m68k/tower-as.h, mmix.h, mn10200.h,
+ mn10300.h, pa.h, v850.h (ASM_PN_FORMAT): Define.
+
+ * defaults.h (ASM_PN_FORMAT, ASM_FORMAT_PRIVATE_NAME): Define.
+ * doc/tm.texi (ASM_FORMAT_PRIVATE_NAME): Update documentation.
+
+2002-09-16 Richard Henderson <rth@redhat.com>
+
+ * expr.c (emit_block_move): Set memory block size as appropriate
+ for the copy.
+
+2002-09-16 Richard Henderson <rth@redhat.com>
+
+ PR fortran/3924
+ * sdbout.c (sdbout_symbol): Don't handle offsets from a symbol.
+
+2002-09-16 Richard Henderson <rth@redhat.com>
+
+ * emit-rtl.c (set_mem_attributes_minus_bitpos): Adjust SIZE
+ as well as OFFSET for BITPOS.
+
+2002-09-16 Jeff Garzik <jgarzik@mandrakesoft.com>
+
+ * config.gcc: Treat winchip_c6-*|winchip2-*|c3-* as pentium-mmx.
+ * config/i386/i386.c (processor_alias_table): Add winchip-c6,
+ winchip2 and c3.
+ * doc/invoke.texi: Mention new aliases.
+
+2002-09-16 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * calls.c (store_one_arg): Set default alignment for BLKmode arguments
+ to BITS_PER_UNIT when ARGS_GROW_DOWNWARD and the padding direction is
+ downward.
+ * function.c (pad_below): Always compile.
+ (locate_and_pad_parm): If defined ARGS_GROW_DOWNWARD, pad argument to
+ alignment when it is not in a register or REG_PARM_STACK_SPACE is true.
+ Pad below when the argument is not in a register and the padding
+ direction is downward.
+
+ * pa-64.h (MUST_PASS_IN_STACK): Move define to pa.h.
+ (PAD_VARARGS_DOWN): Define.
+ * pa.c (function_arg_padding): Revise padding directions to make them
+ compatible with the 32 and 64-bit runtime architecture documentation.
+ (hppa_va_arg): Add code to handle variable and size zero arguments
+ passed by reference on TARGET_64BIT. Reformat.
+ (function_arg): Use a PARALLEL for BLKmode and aggregates args on
+ TARGET_64BIT. Use a DImode PARALLEL for BLKmode args 5 to 8 bytes
+ wide when !TARGET_64BIT. Move forward check for mode==VOIDmode.
+ Add comments.
+ * pa.h (MAX_PARM_BOUNDARY): Correct define for TARGET_64BIT.
+ (RETURN_IN_MEMORY): Return size zero types in memory.
+ (FUNCTION_VALUE): Return TFmode in general registers.
+ (MUST_PASS_IN_STACK): Define.
+ (FUNCTION_ARG_BOUNDARY): Simplify.
+ (FUNCTION_ARG_PASS_BY_REFERENCE): Pass variable and zero sized types
+ by reference.
+ (FUNCTION_ARG_CALLEE_COPIES): Define to FUNCTION_ARG_PASS_BY_REFERENCE.
+
+2002-09-16 Richard Henderson <rth@redhat.com>
+
+ * real.c (do_fix_trunc): New.
+ (real_arithmetic): Call it.
+ * simplify-rtx.c (simplify_unary_operation): Handle FIX
+ with a floating-point result mode.
+
+2002-09-16 Richard Henderson <rth@redhat.com>
+
+ * builtin-types.def (BT_FN_FLOAT_CONST_STRING): New.
+ (BT_FN_DOUBLE_CONST_STRING, BT_FN_LONG_DOUBLE_CONST_STRING): New.
+ * builtins.def (__builtin_nan, __builtin_nanf, __builtin_nanl): New.
+ (__builtin_nans, __builtin_nansf, __builtin_nansl): New.
+ * builtins.c (fold_builtin_nan): New.
+ (fold_builtin): Call it.
+ * real.c (real_nan): Parse a non-empty string.
+ (round_for_format): Fix NaN significand truncation.
+ * real.h (real_nan): Return bool.
+ * doc/extend.texi: Document new builtins.
+
+2002-09-16 Jason Merrill <jason@redhat.com>
+ Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/winnt.c (ix86_handle_dll_attribute): Set
+ DECL_EXTERN and TREE_PUBLIC for dllimported variables here...
+ (i386_pe_mark_dllimport): Not here.
+
+2002-09-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-semantics.c (genrtl_do_stmt): Cope with NULL cond.
+
+2002-09-16 Geoffrey Keating <geoffk@redhat.com>
+
+ * config/rs6000/rs6000.c (build_mask64_2_operands): Suppress
+ warnings about unused operands when HOST_BITS_PER_WIDE_INT is
+ < 64.
+ (rs6000_emit_cmove): Use real_isinf not target_isinf.
+
+2002-09-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * calls.c (emit_library_call_value_1): Don't refer to
+ hard_libcall_value.
+ * optabs.c (prepare_float_lib_cmp): Likewise.
+
+2002-09-16 Geoffrey Keating <geoffk@apple.com>
+
+ * ggc-common.c (ggc_mark_rtx_children_1): Update for changed name
+ mangling.
+
+ The following changes are merged from pch-branch:
+
+ * doc/gty.texi (GTY Options): Document %a.
+ * gengtype.c (do_scalar_typedef): New function.
+ (process_gc_options): Handle `length' option.
+ (set_gc_used_type): A pointer to an array of structures doesn't
+ qualify as a pointer to a structure.
+ (output_escaped_param): Add `%a' escape.
+ (write_gc_structure_fields): Allow 'desc' on array of unions.
+ (main): Define `uint8', `jword' and `JCF_u2' as scalars; use
+ do_scalar_typedef.
+
+ * gengtype.c (enum rtx_code): Make global.
+ (rtx_format): Make global.
+ (rtx_next): New.
+ (gen_rtx_next): New.
+ (write_rtx_next): New.
+ (adjust_field_rtx_def): Skip fields marked by chain_next.
+ (open_base_files): Delete redundant prototype.
+ (write_enum_defn): New.
+ (output_mangled_typename): Correct abort call.
+ (write_gc_marker_routine_for_structure): Handle chain_next and
+ chain_prev options.
+ (finish_root_table): Don't output redundant \n.
+ (main): Call gen_rtx_next, write_rtx_next, write_enum_defn.
+ * c-tree.h (union lang_tree_node): Add chain_next option.
+
+ * gengtype.h (NUM_PARAM): New definition.
+ (struct type): For TYPE_PARAM_STRUCT, allow multiple parameters.
+ * gengtype.c (find_param_structure): New.
+ (adjust_field_type): Handle param<n>_is option.
+ (process_gc_options): Detect use_params option. Update callers.
+ (set_gc_used_type): Add 'param' parameter, update callers. Handle
+ 'use_params' option.
+ (open_base_files): Add splay-tree.h to list of files included.
+ (output_mangled_typename): New.
+ (write_gc_structure_fields): Update 'param' parameter to support
+ multiple parameters. Change name mangling. Allow parameterized
+ fields to have an apparent scalar type. Handle param<n>_is options,
+ use_param option.
+ (write_gc_marker_routine_for_structure): Update for change to name
+ mangling. Better guess the output file for parameterized types.
+ (write_gc_types): Update for change to name mangling.
+ (write_gc_root): Update for change to name mangling. Handle (ignore)
+ param<n>_is options.
+ * doc/gty.texi (GTY Options): Add description of param<n>_is
+ options, use_params option.
+ * ggc.h (ggc_mark_rtx): Update for changed name mangling.
+ * gengtype-lex.l: Produce token for param<n>_is.
+ * gengtype-yacc.y: Parse param<n>_is.
+
+ * gengtype.c (adjust_field_tree_exp): Don't name a variable 'rindex'.
+
+ * rtl.c: Update comment describing rtx_format.
+ * rtl.h (union rtunion): Separate definition and typedef.
+ (struct rtx_def): Use gengtype to mark.
+ * Makefile.in (gengtype.o): Also depend on rtl.def.
+ * ggc.h (ggc_mark_rtx_children): Delete prototype.
+ (ggc_mark_rtx): Change to alias of gengtype-generated routine.
+ * ggc-common.c (ggc_mark_rtx_children): Delete.
+ (ggc_mark_rtx_children_1): Delete.
+ (gt_ggc_m_rtx_def): Delete.
+ * gengtype.c (adjust_field_rtx_def): New.
+ (adjust_field_type): Call adjust_field_rtx_def.
+ (write_gc_structure_fields): Add 'default' case to switch if none
+ is specified; remove unused code.
+
+ * tree.h (struct tree_exp): Update for change to meaning
+ of special.
+ * gengtype.c (adjust_field_tree_exp): New function.
+ (adjust_field_type): Handle `tree_exp' special here.
+ (write_gc_structure_fields): Don't handle `tree_exp' special here.
+ Handle new `dot' option.
+
+ * gengtype.h: Make `info' a pointer-to-const.
+ * gengtype-yacc.y (yacc_ids): Use xasprintf.
+
+ * gengtype.c (write_gc_structure_fields): Remove implementation
+ of `always' option, add `default' option.
+ * doc/gty.texi (GTY Options): Remove documentation of `always',
+ add `default'.
+
+2002-09-16 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * output.h: Remove #ifdef RTX_CODE and #ifdef TREE_CODE.
+
+2002-09-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * m68hc11.md (addhi_sp): Fix uninitialized variable bug.
+
+ * c4x-c.c, c4x.c, darwin.c, i370-c.c, m32r.c: Include tm_p.h
+ instead of the *-protos.h file directly.
+ * t-c4x, t-i370, t-v850: Depend on $(TM_P_H).
+ * darwin.c (machopic_output_stub): Move prototype ...
+ * darwin-protos.h (machopic_output_stub): ... here.
+ * rs6000-protos.h (machopic_output_stub): Don't declare.
+
+2002-09-16 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (builtin_define_float_constants): Emit __FOO_DENORM_MIN__.
+
+2002-09-16 Richard Henderson <rth@redhat.com>
+
+ * real.c, real.h: Rewrite from scratch.
+
+ * Makefile.in (simplify-rtx.o): Depend on TREE_H.
+ (paranoia): New target.
+ * builtins.c (fold_builtin_inf): Use new real.h interface.
+ * c-common.c (builtin_define_with_hex_fp_value): Likewise.
+ * c-lex.c (interpret_float): Likewise.
+ * emit-rtl.c (gen_lowpart_common): Likewise.
+ * optabs.c (expand_float): Use real_2expN.
+ * config/ia64/ia64.md (divsi3, udivsi3): Likewise.
+ * defaults.h (INTEL_EXTENDED_IEEE_FORMAT): New.
+ (FLOAT_WORDS_BIG_ENDIAN): New.
+ * cse.c (find_comparison_args): Don't pass FLOAT_STORE_FLAG_VALUE
+ directly to REAL_VALUE_NEGATIVE.
+ * loop.c (canonicalize_condition): Likewise.
+ * simplify-rtx.c: Include tree.h.
+ (simplify_unary_operation): Don't handle FIX and UNSIGNED_FIX
+ with floating-point result modes.
+ * toplev.c (backend_init): Call init_real_once.
+
+ * fold-const.c (force_fit_type): Don't call CHECK_FLOAT_VALUE.
+ * tree.c (build_real): Likewise.
+ * config/alpha/alpha.c, config/vax/vax.c (float_strings,
+ float_values, inited_float_values, check_float_value): Remove.
+ * config/alpha/alpha.h, config/m68hc11/m68hc11.h,
+ config/m88k/m88k.h, config/vax/vax.h (CHECK_FLOAT_VALUE): Remove.
+ * doc/tm.texi (CHECK_FLOAT_VALUE): Remove.
+ (VAX_HALFWORD_ORDER): Remove.
+
+2002-09-16 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c: (legitimize_la_operand): Remove, replace by ...
+ (s390_load_address): ... this new function.
+ (s390_decompose_address): Allow the argument pointer and all
+ virtual registers as 'pointer' registers.
+ (s390_expand_plus_operand): Use s390_load_address.
+ config/s390/s390.md (movti, movdi, movdf splitters): Likewise.
+ ("force_la_31"): New insn pattern.
+ config/s390/s390-protos.h (legitimize_la_operand): Remove.
+ (s390_load_address): Add prototype.
+
+ * config/s390/s390.c: Include "optabs.h".
+ (s390_expand_movstr, s390_expand_clrstr, s390_expand_cmpstr): New.
+ config/s390/s390-protos.h (s390_expand_movstr, s390_expand_clrstr,
+ s390_expand_cmpstr): Add prototypes.
+ config/s390/s390.md ("movstrdi", "movstrsi"): Call s390_expand_movstr.
+ ("movstrdi_short"): Rename to "movstr_short_64". Change predicates
+ for operands 0 and 1 to "memory_operand". Add type attribute.
+ ("movstrsi_short"): Rename to "movstr_short_31". Change predicates
+ for operands 0 and 1 to "memory_operand". Add type attribute.
+ ("movstrdi_long", "movstrsi_long"): Remove.
+ ("movstrdi_64"): Rename to "movstr_long_64". Add type attribute.
+ ("movstrsi_31"): Rename to "movstr_long_31". Add type attribute.
+ ("clrstrdi", "clrstrsi"): Call s390_expand_clrstr.
+ ("clrstrsico"): Remove, replace by ...
+ ("clrstr_short_64", "clrstr_short_31"): ... these new patterns.
+ ("clrstrsi_64"): Rename to "clrstr_long_64".
+ ("clrstrsi_31"): Rename to "clrstr_long_31".
+ ("cmpstrdi", "cmpstrsi"): Call s390_expand_cmpstr.
+ ("cmpstr_const"): Remove, replace by ...
+ ("cmpstr_short_64", "cmpstr_short_31"): ... these new patterns.
+ ("cmpstr_64"): Rename to "cmpstr_long_64".
+ ("cmpstr_31"): Rename to "cmpstr_long_31".
+
+2002-09-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ABOUT-NLS: Follow spelling conventions.
+ * ChangeLog: Likewise.
+ * ChangeLog.1: Likewise.
+ * ChangeLog.2: Likewise.
+ * ChangeLog.3: Likewise.
+ * ChangeLog.4: Likewise.
+ * ChangeLog.5: Likewise.
+ * ChangeLog.6: Likewise.
+ * FSFChangeLog.10: Likewise.
+ * FSFChangeLog.11: Likewise.
+ * c-common.c: Likewise.
+ * c-lex.c: Likewise.
+ * c-objc-common.c: Likewise.
+ * cppexp.c: Likewise.
+ * cppinit.c: Likewise.
+ * cpplex.c: Likewise.
+ * doloop.c: Likewise.
+ * flow.c: Likewise.
+ * function.c: Likewise.
+ * integrate.c: Likewise.
+ * loop.c: Likewise.
+ * reg-stack.c: Likewise.
+ * reload.h: Likewise.
+ * ssa.c: Likewise.
+
+2002-09-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (vmsdbgout.o): Depend on $(TARGET_H)
+ * vmsdbgout.c: Include "target.h".
+
+2002-09-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.0: Likewise.
+ * ChangeLog.1: Likewise.
+ * ChangeLog.2: Likewise.
+ * ChangeLog.4: Likewise.
+ * ChangeLog.6: Likewise.
+ * config.gcc: Likewise.
+ * dwarfout.c: Likewise.
+ * reload1.c: Likewise.
+ * simplify-rtx.c: Likewise.
+ * unwind-sjlj.c: Likewise.
+ * config/avr/avr.h: Likewise.
+ * config/d30v/d30v.h: Likewise.
+ * config/frv/frv.c: Likewise.
+ * config/frv/frv.h: Likewise.
+ * config/ip2k/ip2k.h: Likewise.
+ * config/m88k/m88k-move.sh: Likewise.
+ * config/stormy16/stormy16.c: Likewise.
+ * config/stormy16/stormy16.h: Likewise.
+ * doc/extend.texi: Likewise.
+ * doc/interface.texi: Likewise.
+ * doc/invoke.texi: Likewise.
+ * doc/md.texi: Likewise.
+ * doc/rtl.texi: Likewise.
+ * doc/tm.texi: Likewise.
+ * doc/trouble.texi: Likewise.
+ * ginclude/float.h: Likewise.
+ * treelang/treelang.texi: Likewise.
+
+2002-09-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * i386-protos.h (i386_pe_dllexport_name_p,
+ i386_pe_dllimport_name_p, i386_pe_unique_section,
+ i386_pe_declare_function_type, i386_pe_record_external_function,
+ i386_pe_record_exported_symbol, i386_pe_asm_file_end): Add
+ prototype.
+ * i386/t-cygwin (winnt.o): Depend on $(TM_P_H).
+ * i386/t-interix (winnt.o): Likewise.
+
+ * v850-protos.h (v850_output_addr_const_extra): Prototype.
+
+2002-09-15 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/mips/netbsd.h (TARGET_OS_CPP_BUILTINS): Add
+ MIPS ABI CPP macros.
+ (TARGET_CPU_CPP_BUILTINS): Redefine.
+ (SUBTARGET_EXTRA_SPECS): Remove subtarget_endian_default.
+ (SUBTARGET_ENDIAN_DEFAULT_SPEC): Remove.
+
+2002-09-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ia64/aix.h (TARGET_OS_CPP_BUILTINS): Fix typo.
+
+2002-09-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.0: Likewise.
+ * ChangeLog.1: Likewise.
+ * ChangeLog.2: Likewise.
+ * ChangeLog.3: Likewise.
+ * ChangeLog.4: Likewise.
+ * ChangeLog.5: Likewise.
+ * ChangeLog.6: Likewise.
+ * FSFChangeLog.10: Likewise.
+ * FSFChangeLog.11: Likewise.
+ * c-common.c: Likewise.
+ * c-common.h: Likewise.
+ * c-format.c: Likewise.
+ * c-opts.c: Likewise.
+ * cpplib.c: Likewise.
+ * langhooks.h: Likewise.
+ * real.c: Likewise.
+ * reg-stack.c: Likewise.
+ * toplev.c: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/arm/arm.md: Likewise.
+ * config/arm/linux-gas.h: Likewise.
+ * config/arm/netbsd.h: Likewise.
+ * config/c4x/c4x.c: Likewise.
+ * config/c4x/c4x.h: Likewise.
+ * config/c4x/c4x.md: Likewise.
+ * config/c4x/libgcc.S: Likewise.
+ * config/fr30/fr30.md: Likewise.
+ * config/frv/frv.md: Likewise.
+ * config/ia64/ia64.md: Likewise.
+ * config/mips/mips.h: Likewise.
+ * config/mn10300/mn10300.c: Likewise.
+ * config/stormy16/stormy16.c: Likewise.
+ * config/v850/v850.md: Likewise.
+ * doc/extend.texi: Likewise.
+ * doc/invoke.texi: Likewise.
+ * doc/md.texi: Likewise.
+
+2002-09-15 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/netbsd.h (LIB_SPEC): Include the appropriate pthread
+ library if -pthread is specified.
+
+2002-09-15 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.gcc (*-*-netbsd*): Set thread_file to 'posix'
+ for --enable-threads=yes and --enable-threads=posix.
+
+2002-09-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/sparc/cypress.md: Replace Sparc with SPARC.
+ * config/sparc/freebsd.h: Likewise.
+ * config/sparc/gmon-sol2.c: Likewise.
+ * config/sparc/hypersparc.md: Likewise.
+ * config/sparc/lb1spc.asm: Likewise.
+ * config/sparc/lb1spl.asm: Likewise.
+ * config/sparc/linux.h: Likewise.
+ * config/sparc/linux64.h: Likewise.
+ * config/sparc/lynx.h: Likewise.
+ * config/sparc/sol2.h: Likewise.
+ * config/sparc/sparc-modes.def: Likewise.
+ * config/sparc/sparc.c: Likewise.
+ * config/sparc/sparc.h: Likewise.
+ * config/sparc/sparc.md: Likewise.
+ * config/sparc/sparclet.md: Likewise.
+ * config/sparc/supersparc.md: Likewise.
+ * config/sparc/sysv4.h: Likewise.
+ * config/sparc/vxsim.h: Likewise.
+ * config/sparc/vxsparc64.h: Likewise.
+
+2002-09-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-lex.c (cb_ident): Mark variable with ATTRIBUTE_UNUSED.
+ * collect2.c (ignore_library, aix_std_libs): Move into the context
+ where it is used.
+ * m68hc11.c (m68hc11_autoinc_compatible_p): Delete prototype.
+ (autoinc_mode, m68hc11_make_autoinc_notes): Add prototypes.
+ * m88k.c (output_call): Wrap variables with macro controlling use.
+ * rs6000.md: Likewise. Const-ify variable.
+ * sh.h (ASM_OUTPUT_LABELREF): Likewise.
+ * final.c (only_leaf_regs_used): Likewise.
+ * regrename.c (maybe_mode_change): Mark parameter with
+ ATTRIBUTE_UNUSED.
+ * reload.c (find_valid_class): Likewise. Likewise for variable.
+ (find_reloads_address_1): Likewise.
+ * varasm.c (weak_finish): Wrap variable with macro controlling use.
+
+2002-09-14 Marek Michalkiewicz <marekm@amelek.gda.pl>
+
+ * config/avr/avr.c (output.h): Move after inclusion of tree.h.
+
+2002-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.0: Likewise.
+ * ChangeLog.2: Likewise.
+ * ChangeLog.3: Likewise.
+ * ChangeLog.4: Likewise.
+ * ChangeLog.5: Likewise.
+ * ChangeLog.6: Likewise.
+ * cppfiles.c: Likewise.
+ * cppinit.c: Likewise.
+ * cpplib.h: Likewise.
+ * cse.c: Likewise.
+ * debug.h: Likewise.
+ * df.c: Likewise.
+ * dominance.c: Likewise.
+ * hashtable.c: Likewise.
+ * hashtable.h: Likewise.
+ * loop.c: Likewise.
+ * config/arm/README-interworking: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/arm/arm.h: Likewise.
+ * config/arm/arm.md: Likewise.
+ * config/dsp16xx/dsp16xx.h: Likewise.
+ * config/frv/frv.c: Likewise.
+ * config/frv/frv.h: Likewise.
+ * config/ip2k/ip2k.h: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/stormy16/stormy-abi: Likewise.
+ * config/stormy16/stormy16.h: Likewise.
+ * config/v850/v850.c: Likewise.
+
+2002-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * loop.c: Fix a comment typo.
+
+2002-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/fr30/fr30.h: Fix comment typos.
+ * config/frv/frv.c: Likewise.
+ * config/i386/xmmintrin.h: Likewise.
+ * config/mips/mips.c: Likewise.
+ * config/sh/sh.c: Likewise.
+
+2002-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * haifa-sched.c: Follow spelling conventions.
+ * regclass.c: Likewise.
+ * regrename.c: Likewise.
+ * config/fp-bit.c: Likewise.
+ * config/frv/frv.h: Likewise.
+ * config/m88k/m88k.c: Likewise.
+ * config/mcore/mcore.c: Likewise.
+ * config/rs6000/darwin.h: Likewise.
+ * config/rs6000/gnu.h: Likewise.
+ * config/rs6000/linux.h: Likewise.
+ * config/rs6000/linux64.h: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/rs6000/rs6000.h: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/sparc/sparc.c: Likewise.
+ * config/sparc/ultra1_2.md: Likewise.
+
+2002-09-14 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("movdi_internal"): Allow any offsetable
+ memory operand when source is 0 (K constraint).
+ ("movsi_internal"): Likewise.
+ ("movdf_internal"): Likewise.
+ ("movsf_internal"): Likewise.
+
+2002-09-14 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_elf_encode_section_info): Use
+ targetm.binds_local_p to set SYMBOL_REF_FLAG.
+ (rs6000_xcoff_encode_section_info): Likewise.
+ * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Likewise.
+
+2002-09-10 Theodore A. Roth <troth@verinet.com>
+
+ * gcc/config/avr/avr.h: Set default options for C++ for avr.
+
+2002-09-13 Roger Sayle <roger@eyesopen.com>
+
+ * stmt.c (struct nexting): Remove unused alt_end_label field.
+ (expand_start_loop): Delete initialization of alt_end_label.
+ (expand_start_null_loop): Likewise.
+ (expand_exit_loop_if_false): Delete updating of alt_end_label.
+
+2002-09-13 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (toplev.o): Depend on real.h.
+ (print-rtl.o, varasm.o, ifcvt.o): Likewise.
+
+2002-09-14 Alan Modra <amodra@bigpond.net.au>
+
+ * doc/tm.texi (DBX_OUTPUT_NFUN): Describe.
+ * dbxout.c (dbxout_function_end): Use DBX_OUTPUT_NFUN.
+ * config/rs6000/linux64.h (DBX_OUTPUT_NFUN): Define.
+
+2002-09-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ * ggc-common.c (ggc_mark_roots): Don't iterate NULL hash tables.
+
+2002-09-13 Steve Ellcey <sje@cup.hp.com>
+
+ * config.gcc (ia64*-*-aix*, ia64*-*-elf*, ia64*-*-freebsd*,
+ ia64*-*-linux*): Set extra_parts.
+ * config/ia64/t-aix (EXTRA_PARTS): Remove.
+ * config/ia64/t-ia64 (EXTRA_PARTS): Remove.
+
+2002-09-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/fixunssfsi.c: Replace H8/S with H8S.
+ * config/h8300/h8300.c: Likewise.
+ * config/h8300/h8300.h: Likewise.
+ * config/h8300/h8300.md: Likewise.
+ * doc/invoke.texi: Likewise.
+
+2002-09-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_init_once): Fix formatting.
+
+2002-09-13 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.md (attr type): Add callpal.
+ (imb, trap, load_tp, set_tp): Use it.
+ * config/alpha/ev4.md (ev4_callpal): New.
+ * config/alpha/ev5.md (ev5_callpal): New.
+ * config/alpha/ev6.md (ev6_ibr): Handle callpal.
+ * config/alpha/alpha.c (alphaev4_insn_pipe): Handle TYPE_CALLPAL.
+ (alphaev5_insn_pipe): Likewise.
+
+2002-09-13 Andreas Jaeger <aj@suse.de>
+
+ * Makefile.in (print-rtl.o): Depend on CONFIG_H.
+
+2002-09-13 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/t-hpux (LIBGCC1_TEST, STMP_FIXPROTO,
+ LIB2ADDEH): New, set to NULL.
+ (SHLIB_EXT, SHLIB_LINK, SHLIB_INSTALL, SHLIB_MKMAP): New.
+
+2002-09-13 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/quadlib.c (_U_Qfcmp): Make extern.
+ (_U_Qfcnvfxt_quad_to_sgl): Remove declaration.
+ (_U_Qfeq, _U_Qfne, _U_Qfgt, _U_Qfge, U_Qflt, U_Qfle, _U_Qfcomp):
+ Add declarations.
+ (_U_Qfneg): Remove.
+
+2002-09-13 Dhananjay Deshpande <dhananjayd@kpit.com>
+
+ * config/h8300/h8300.h (EIGHTBIT_CONSTANT_ADDRESS_P): Add support
+ for H8/300, H8S aa:8 mode.
+ (TINY_CONSTANT_ADDRESS_P): Add support for H8S aa:16 mode.
+ * config/h8300/h8300.c (h8300_adjust_insn_length): Adjust length
+ for H8/300 aa:8 mode.
+
+2002-09-13 Hartmut Penner <hpenner@de.ibm.com>
+
+ * config/s390/s390.md ("trap", "conditional_trap", "*trap"): New
+ insns.
+
+2002-09-12 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (HOST_PRINT): Use print-rtl1.o
+ (print-rtl.o): Don't define GENERATOR_FILE.
+ (print-rtl1.o): Rename from $(BUILD_PREFIX_1)print-rtl.o.
+ * print-rtl.c (print_rtx): Include CONST_DOUBLE fp decimal output
+ unless GENERATOR_FILE.
+
+2002-09-12 Stan Shebs <shebs@apple.com>
+
+ * config/darwin.h (USER_LABEL_PREFIX): Define here...
+ * config/i386/darwin.h: ... instead of here.
+
+ * target.h (struct gcc_target): New field
+ terminate_dw2_eh_frame_info.
+ * target-def.h (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Define.
+ (TARGET_INITIALIZER): Add it.
+ * dwarf2out.c (output_call_frame_info): Use target hook.
+ * dwarf2asm.c (dw2_asm_output_delta): Use macro
+ ASM_OUTPUT_DWARF_DELTA if defined.
+ * doc/tm.texi (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Document.
+ (ASM_OUTPUT_DWARF_DELTA): Ditto.
+ (ASM_OUTPUT_DWARF_OFFSET): Ditto.
+ (ASM_OUTPUT_DWARF_PCREL): Ditto.
+ * config.gcc (i[34567]86-*-darwin*): Define extra_parts.
+ (powerpc-*-darwin*): Ditto.
+ * crtstuff.c [OBJECT_FORMAT_MACHO]: Update the Mach-O bits
+ to work correctly for Darwin.
+ * config/darwin.h (OBJECT_FORMAT_MACHO): Define.
+ (STARTFILE_SPEC): Add crtbegin.o.
+ (ENDFILE_SPEC): Define.
+ (EXTRA_SECTION_FUNCTIONS): Put gcc_except_tab in data segment.
+ (ASM_PREFERRED_EH_DATA_FORMAT): Handle more cases.
+ (ASM_OUTPUT_DWARF_DELTA): Define.
+ (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Define.
+ * config/darwin.c (darwin_asm_output_dwarf_delta): New function.
+
+2002-09-13 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_emit_load_toc_table): Remove "if"
+ nesting. Correct test for non-PowerPC64 ELF ABI_AIX.
+ * config/rs6000/rs6000.md (load_toc_v4_PIC*): Disable when ABI_AIX.
+
+2002-09-12 Zack Weinberg <zack@codesourcery.com>
+
+ * toplev.c: Move default definition of USER_LABEL_PREFIX...
+ * defaults.h: ... here.
+
+2002-09-12 Richard Henderson <rth@redhat.com>
+
+ * vax.c: Include tree.h earlier.
+
+2002-09-12 Stan Shebs <shebs@apple.com>
+
+ * config/darwin.c (machopic_finish): Remove #if 0 chunks.
+ (machopic_operand_p): Ditto.
+
+2002-09-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arm/arm.c (arm_compute_initial_elimination_offset):
+ Fix a comment typo.
+
+2002-09-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * toplev.c (do_abort): Fix a comment typo.
+
+2002-09-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cselib.c: Fix comment formatting.
+ * gengtype.c: Likewise.
+
+2002-09-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (udivmodqi4): Do not use an expander.
+ (udivmodhi4): Likewise.
+
+2002-09-12 Graham Stott <graham.stott@btinternet.com>
+ Roger Sayle <roger@eyesopen.com>
+
+ * i386.c (any_fp_register_operand, fp_register_operand,
+ register_and_not_any_fp_reg_operand, register_and_not_fp_reg_operand):
+ New predicate functions.
+ * i386-protos.h: Add their prototypes.
+ * i386.h: Add them to PREDICATE_CODES.
+ * i386.md ("*pushsf_rex64"+2, "*pushsf_rex64"+3, "*pushdf_integer"+1,
+ "*pushdf_integer"+2, "*pushtf_integer"+1, "*pushtf_integer"+2,
+ "*pushtf_integer"+3, "*pushtf_integer"+4, "*dummy_extendsfdf2"+1,
+ "*dummy_extendsfdf2"+2, "*dummy_extendsfxf2"+1,
+ "*dummy_extendsftf2"+1, "*dummy_extendsftf2"+2,
+ "*dummy_extenddfxf2"+1, "*dummy_extenddftf2"+1,
+ "*dummy_extenddftf2"+2, "*negsf2_if"+1, "*negsf2_if"+2,
+ "*negdf2_if_rex64"+1, "*negdf2_if_rex64"+2, "*negxf2_if"+1,
+ "*negxf2_if"+2, "*negtf2_if"+1, "*negtf2_if"+2, "*abssf2_if"+1,
+ "*abssf2_if"+2, "*absdf2_if_rex64"+1, "*absdf2_if_rex64"+2,
+ "*absxf2_if"+1, "*absxf2_if"+2, "*abstf2_if"+1, "*abstf2_if"+2):
+ Use these new predicates to simplify and correct the use of
+ FP_REG_P, ANY_FP_REG_P, FP_REGNO_P and any ANY_FP_REGNO_P.
+
+2002-09-12 Jason Merrill <jason@redhat.com>
+
+ * diagnostic.c (output_add_identifier): New fn.
+ * diagnostic.h: Declare it.
+
+ * calls.c (store_one_arg): Use size_in_bytes to determine the
+ amount of space to push.
+
+2002-09-12 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/linux64.h (STARTFILE_SPEC32): Fix a typo.
+
+2002-09-12 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-modes.def (CCAPmode, CCANmode): New CC modes.
+ * config/s390/s390.c (s390_match_ccmode_set): Support new CC modes.
+ (s390_select_ccmode): Likewise.
+ (s390_branch_condition_mask): Likewise.
+ (optimization_options): Do not set flag_branch_on_count.
+ (s390_split_branches): Handle doloop branches.
+ (s390_chunkify_pool): Likewise.
+ * config/s390/s390.md ("*adddi3_imm_cc", "*addsi3_imm_cc"): New insns.
+ ("doloop_end"): New expander.
+ ("doolop_si", "*doloop_si_long", "doloop_di", "*doloop_di_long",
+ associated splitters): New.
+
+2002-09-11 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * genattrtab.c (simplify_cond): Remove unused variable(s).
+ * global.c (record_conflicts): Likewise.
+ * jump.c (rebuild_jump_labels): Likewise.
+ * loop.c (scan_loop, check_final_value): Likewise.
+ * ra-colorize.c (colorize_one_web, assign_colors): Likewise.
+ * reload1.c (eliminate_regs_in_insn, do_input_reload): Likewise.
+ * rtlanal.c (reg_set_p): Likewise.
+ * stmt.c (expand_asm_operands, expand_decl): Likewise.
+ * genautomata.c (empty_reserv): Remove.
+ * loop.c (max_luid): Likewise.
+ * sched-rgn.c (bitlst_table_size): Likewise.
+
+2002-09-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ Reimplement gcov format.
+ * gcov-io.h: Replace.
+ * gcov.c: Reimplement.
+ * gcov-iov.c: New file.
+ * gcov-dump.c: New file.
+ * libgcc2.c (L_bb): Replace with ...
+ (L_gcov): ... this.
+ (struct bb_function_info, struct bb): Remove.
+ (inhibit_libc): Never inhibit.
+ (gcov_list, gcov_crc): New static variables.
+ (gcov_version_mismatch): New static function.
+ (__bb_exit_func): Renamed to ...
+ (__gcov_exit): ... here. Made static. Reimplement.
+ (__gcov_init_func): Rename to ...
+ (__gcov_init): ... here. Check version, update crc.
+ (__bb_fork_func): Rename to ...
+ (__gcov_flush): ... here.
+ * libgcc2.h (struct bb, __bb_exit_func, __bb_init_func,
+ __bb_fork_func, gcov_type, __bb_find_arc_counters): Remove.
+ * calls.c (expand_call): Call __gcov_flush.
+ * profile.c (bb_file, last_bb_file_name): Remove.
+ (bbg_file_name): New global variable.
+ (output_gcov_string): Remove.
+ (get_exec_counts): Reimplement.
+ (branch_prob): Reimplement gcov file writing.
+ (init_branch_prob): Create bbg_file_name, don't create
+ bb_file_name.
+ (end_branch_prob): Adjust. Don't remove counter file when
+ instrumenting ourselves.
+ (create_profiler): Adjust.
+ * doc/gcov.texi (Gcov Data Files): Remove detailed specification,
+ point to gcov-io.h.
+ * Makefile.in (LANGUAGES): Add gcov-dump.
+ (coverageexts): Remove .bb.
+ (STAGESTUFF): Add gcov-dump.
+ (LIB2FUNCS_ST): Replace _bb with _gcov.
+ (profile.o): Depend on gcov-iov.h.
+ (final.o): Don't depend on profile.h, gcov.h.
+ (gcov.o): Depend on gcov-iov.h.
+ (gcov-iov.o): New target.
+ (gcov-iov): New target.
+ (gcov-iov.h): New target.
+ (gcov-dump.o): New target.
+ (GCOV_DUMP_OBJS): New variable.
+ (gcov-dump): New target.
+ (distclean): Remove coverageexts.
+ (stage1): Remove coverageexts.
+
+2002-09-11 Hartmut Penner <hpenner@de.ibm.com>
+
+ * fold-const.c (make_range): Only narrow to signed range if
+ the signed range is smaller than the unsigned range.
+
+2002-09-12 Alan Modra <amodra@bigpond.net.au>
+
+ * emit-rtl.c (set_mem_size): New function.
+ * expr.h (set_mem_size): Declare.
+ * config/rs6000/rs6000.c (expand_block_move_mem): Exterminate.
+ (expand_block_move): Instead, use adjust_address and
+ replace_equiv_address to generate proper aliasing info.
+ Move common code out of conditionals. Localize vars.
+
+2002-09-11 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * optabs.c (expand_binop): Minor cleanup.
+ (expand_twoval_binop): Convert CONST_INTs like in expand_binop.
+
+2002-09-11 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * print-tree.c (print_node): Print the restrict qualifier.
+
+2002-09-11 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/install.texi: Fix typos.
+
+2002-09-11 Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in: Remove all references to s-under and underscore.c.
+ * collect2.c, tlink.c: Change all uses of prepends_underscore
+ to look directly at USER_LABEL_PREFIX.
+
+2002-09-11 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_xcoff_asm_named_section): Append
+ alignment to csect.
+ (rs6000_xcoff_unique_section): Only set section name for public
+ data.
+ (rs6000_xcoff_section_type_flags): Store log2 alignment in flags.
+ * config/rs6000/xcoff.h (TARGET_ASM_SELECT_SECTION): Remove
+ duplicate definition.
+
+2002-09-10 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.md (extzv): Check predicates before emitting extzv_32.
+ (insv): Likewise.
+
+2002-09-10 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h (MOVE_MAX): Define to correct value.
+ (MAX_MOVE_MAX): Define.
+ (MOVE_BY_PIECES_P): Define.
+ (CLEAR_BY_PIECES_P): Define.
+
+2002-09-10 Denis Chertykov <denisc@overta.ru>
+
+ * config/avr/avr.md (movstrhi): Use right operands for conversion.
+
+2002-09-10 Richard Earnshaw <rearnsha@arm.com>
+
+ PR c/7873
+ * arm.md (insv): Use reg_or_int_operand for operand[3].
+
+2002-09-10 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.c (rs6000_assemble_visibility): Protect declaration
+ inside macro. Correct function definition typo.
+ (rs6000_xcoff_section_type_flags): New function.
+ (TARGET_SECTION_TYPE_FLAGS): Remove definition.
+ (rs6000_elf_section_type_flags): Call default_section_type_flags_1
+ with appropriate PIC test.
+ (rs6000_xcoff_select_section): Use decl_readonly_section_1 to
+ determine readonly.
+ (rs6000_binds_local_p): Combine PIC flags.
+ * sysv4.h (TARGET_SECTION_TYPE_FLAGS): Define.
+ * xcoff.h (TARGET_SECTION_TYPE_FLAGS): Define.
+
+2002-09-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * h8300.md: Fix signed/unsigned warnings.
+ * mcore.md: Likewise.
+ * mn10300.c (mask_ok_for_mem_btst): Likewise.
+
+2002-09-09 Per Bothner <per@bothner.com>
+
+ * print-tree.c (print_node): In a STRING_CST, escape non-ascii
+ characters, and only print TREE_STRING_LENGTH chars.
+
+2002-09-09 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/hpux.h (TARGET_HPUX_LD): New, define true.
+ (ASM_FILE_END) New.
+ * config/ia64/ia64.h (TARGET_HPUX_LD): New, define false.
+ * config/ia64/ia64-protos.h (ia64_hpux_asm_file_end): New.
+ * config/ia64/ia64.c (ia64_asm_output_external): Create list
+ of external functions if TARGET_HPUX_LD is true.
+ (ia64_hpux_add_extern_decl): New, routine to put names on
+ list of external functions.
+ (ia64_hpux_asm_file_end): Put out declarations for external
+ functions if and only if they are used.
+
+2002-09-09 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.md (exception_receiver, builtin_setjmp_receiver): Add blockage
+ on TARGET_64BIT before pic register restore.
+
+2002-09-09 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/tm.texi (TARGET_HAVE_SRODATA_SECTION): New description.
+ (TARGET_HAVE_TLS): New description.
+
+2002-09-09 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/extend.texi (Statement Exprs): Fix broken link.
+
+2002-09-09 Denis Chertykov <denisc@overta.ru>
+
+ * config/avr/avr.md (movstrhi, clrstrhi): Use gen_int_mode for
+ right conversion of operands[1].
+
+2002-09-09 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*tmdi_reg", "*tmsi_reg"): Do not mark as
+ commutative. Use "nonimmediate_operand" instead of "register_operand"
+ as predicate for operand 0. Move to after the "*tmXX_mem" insns.
+
+ ("*tmdi_mem", "*tmsi_mem", "*tmhi_mem", "*tmqi_mem"): Do not mark
+ as commutative.
+
+ ("*anddi3_ni", "*andsi3_ni", "*iordi3_ni", "*iorsi3_ni"): Do not
+ mark as commutative. Use "nonimmediate_operand" instead of
+ "register_operand" as predicate for operand 1.
+
+ ("movstrictsi"): Fix typo in insn name.
+
+2002-09-09 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (index_register_operand): New.
+ * i386.h (predicate_codes): Add new predicate.
+ * i386.md (lea_general_*): Use index_register_operand
+ (ashift to lea splitter): Do not produce invalid leas
+ (ashift to mov+ashift split): New.
+
+2002-09-09 Nick Clifton <nickc@redhat.com>
+
+ * config/fr30/fr30.c (output.h): Move after inclusion of tree.h.
+ Fix folding marks.
+
+2002-09-09 Toshiyasu Morita <toshiyasu.morita@hsa.hitachi.com>
+ J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh/sh.h (OVERRIDE_OPTIONS): align_functions is in bytes, not bits.
+
+2002-09-09 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_binds_local_p): Return bool.
+ (function_ok_for_sibcall): Use binds_local_p. Respect longcall
+ attributes.
+
+2002-09-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * basic_block.h (gcov_type): Explain why it is signed.
+ * final.c: Don't include profile.h.
+ (struct function_list, functions_head, functions_tail,
+ end_final): Moved to profile.c
+ (final): Move arc chaining code to profile.c.
+ * function.c (prepare_function_start): Remove duplicate line.
+ * output.h (end_final): Remove prototype.
+ * predict.c (estimate_loops_at_level): Use gcov_type.
+ * profile.c (struct function_list, functions_head,
+ functions_tail): Moved from final.c
+ (need_func_profiler): Remove.
+ (instrument_edges): Don't set need_func_profiler.
+ (get_exec_counts): Avoid signed/unsigned warning.
+ (compute_checksum): Use crc32.
+ (branch_prob): Adjust. Chain onto functions_head.
+ (init_branch_prob): Absorb init_edge_profiler.
+ (init_edge_profiler): Remove.
+ (create_profiler): Moved and renamed from final.c:end_final.
+ Emit data and constructor.
+ (output_func_start_profiler): Remove.
+ * profile.h (struct profile_info): checksum is unsigned.
+ * rtl.h (output_func_start_profiler): Remove prototype.
+ (create_profiler): Declare.
+ * toplev.c (compile_file): Call create_profiler, if instrumenting
+ arcs. Don't call end_final.
+
+2002-09-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fr30.c (fr30_print_operand): Fix bug in output of CONST_DOUBLE.
+
+2002-09-08 Richard Henderson <rth@redhat.com>
+
+ * dwarf2.h (DW_OP_call_ref): Rename from DW_OP_calli.
+ (DW_OP_GNU_push_tls_address): New.
+ (DW_OP_lo_user): Fix.
+ * dwarf2out.c (INTERNAL_DW_OP_tls_addr): New.
+ (dwarf_stack_op_name): Handle it, plus other dwarf3 opcodes.
+ (size_of_loc_descr): Likewise.
+ (output_loc_operands): Handle INTERNAL_DW_OP_tls_addr.
+ (add_AT_location_description): Take a dw_loc_descr_ref not an rtx.
+ (loc_descriptor_from_tree): Handle TLS variables.
+ (rtl_for_decl_location): Do avoid_constant_pool_reference here ...
+ (add_location_or_const_value_attribute): ... not here. Defer
+ to loc_descriptor_from_tree for TLS variables.
+
+ * config/i386/i386.h (ASM_OUTPUT_DWARF_DTPREL): New.
+ * config/i386/i386.c (i386_output_dwarf_dtprel): New.
+ * config/i386/i386-protos.h: Update.
+
+2002-09-08 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/6405
+ * unroll.c (loop_iterations): last_loop_insn should be the previous
+ non-note instruction before loop->end.
+ * loop.c (strength_reduce): The conditional jump is the last
+ non-note instruction before loop->end (as above).
+
+2002-09-08 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (try_combine): Handle the case that undobuf.other_insn
+ has been turned into a return or unconditional jump, by inserting
+ a BARRIER if necessary.
+ (simplify_set): Test if a condition code setter has a constant
+ comparison at compile time, if so convert this insn to a no-op move
+ and update/simplify the condition code user (undobuf.other_insn).
+
+2002-09-08 Krister Walfridsson <cato@df.lth.se>
+
+ * config/arm/netbsd.h (INITIALIZE_TRAMPOLINE): Redefine.
+ (CLEAR_INSN_CACHE): Define.
+
+2002-09-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * basic-block.h: Fix comment formatting.
+ * c-common.c: Likewise.
+ * c-common.h: Likewise.
+ * c-lex.c: Likewise.
+ * c-pretty-print.c: Likewise.
+ * cfglayout.c: Likewise.
+ * cfgloop.c: Likewise.
+ * defaults.h: Likewise.
+ * et-forest.c: Likewise.
+ * explow.c: Likewise.
+ * function.h: Likewise.
+ * gcov.c: Likewise.
+ * genattrtab.c: Likewise.
+ * gengtype.c: Likewise.
+ * ifcvt.c: Likewise.
+ * libgcc2.c: Likewise.
+ * loop.c: Likewise.
+ * profile.c: Likewise.
+ * ra-build.c: Likewise.
+ * real.c: Likewise.
+ * rtl.h: Likewise.
+ * tracer.c: Likewise.
+ * tree-inline.c: Likewise.
+ * varasm.c: Likewise.
+
+2002-09-08 Jan Hubicka <jh@suse.cz>
+
+ * emit-rtl.c (set_mem_attributes_minus_bitpos): Fix array_ref
+ handling.
+
+ * loop.c (loop_givs_reduce): Emit addition after.
+
+2002-09-08 Alan Modra <amodra@bigpond.net.au>
+
+ * varasm.c (default_assemble_visibility): Rename from
+ assemble_visibility.
+ * output.h: Here too.
+ * target-def.h (TARGET_ASM_ASSEMBLE_VISIBILITY): And here.
+ * config/rs6000/rs6000.c (rs6000_assemble_visibility): And here.
+
+2002-09-08 Alan Modra <amodra@bigpond.net.au>
+
+ * reload.c (find_reloads <p constraint>): Pass operand_mode to
+ find_reloads_address.
+
+2002-09-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (udivmodqi4): Enable on H8/300.
+ (anonymous pattern): Likewise.
+
+2002-09-07 Igor Shevlyakov <igor@microunity.com>
+
+ * machmode.def: Add modes for half-float vectors.
+
+2002-09-07 Scott Snyder <snyder@fnal.gov>
+
+ PR target/7374
+ * config/alpha/alpha.md (abstf2): Fix typo: 'neg' for 'abs'.
+
+2002-09-07 Roger Sayle <roger@eyesopen.com>
+
+ * basic-block.h (struct loop): Remove unused cont_dominator field.
+
+2002-09-07 Igor Shevlyakov <igor@microunity.com>
+
+ * varasm.c (decode_rtx_const): Don't check undefined field for
+ CONST_VECTOR.
+
+2002-09-07 Glen Nakamura <glen@imodulo.com>
+
+ PR opt/7814
+ * sched-deps.c (sched_analyze_insn): Make sure to add insn
+ to reg_last->sets after flushing the dependency lists to guarantee
+ that subsequent clobbers will be dependent on it.
+
+2002-09-07 Igor Shevlyakov <igor@microunity.com>
+
+ * combine.c (simplify_shift_const): Calculate rotate count
+ correctly for vector operands.
+
+2002-09-07 Ansgar Esztermann <ansgar@thphy.uni-duesseldorf.de>
+
+ * c-typeck.c (c_tree_expr_nonnegative_p): New function.
+ (build_binary_op): Call c_tree_expr_nonnegative_p rather than
+ tree_expr_nonnegative_p.
+ (build_conditional_expr): Likewise.
+ * c-tree.h (c_tree_expr_nonnegative_p): Declare.
+
+2002-09-07 Richard Henderson <rth@redhat.com>
+
+ * builtins.def (inf, inff, infl): Mark const.
+ (huge_val, huge_valf, huge_vall): Likewise.
+ (BUILT_IN_GETEXP, BUILT_IN_GETMAN): Remove.
+
+ * real.c (ereal_inf): Clear E before use.
+
+2002-09-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (udivmodqi4): Split the pattern into
+ an expander and an anonymous pattern. Zero out the upper half
+ of the dividend in the expander.
+ (udivmodqi4): Likewise.
+
+2002-09-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c: Fix formatting.
+ * config/h8300/h8300.h: Likewise.
+ * config/h8300/h8300.md: Likewise.
+
+2002-09-07 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgcleanup.c (try_crossjump_to_edge): Fix updating of liveness
+ information.
+
+2002-09-07 Graham Stott <graham.stott@btinternet.com>
+
+ * rtlanal.c (dead_or_set_regno_p): Fix typo.
+
+2002-09-07 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/linux64.h (ASM_PREFERRED_EH_DATA_FORMAT): Define.
+
+ * doc/tm.texi (TARGET_ASM_ASSEMBLE_VISIBILITY): Describe.
+ * target-def.h (TARGET_ASM_ASSEMBLE_VISIBILITY): Define.
+ (TARGET_ASM_OUT): Add the above here.
+ * target.h (struct gcc_target): Add "visibility" field.
+ * varasm.c (maybe_assemble_visibility): Call targetm visibility func.
+ * config/rs6000/rs6000.c (rs6000_assemble_visibility): New function.
+ (TARGET_ASM_ASSEMBLE_VISIBILITY): Define.
+ (rs6000_legitimize_reload_address, first_reg_to_save): Formatting.
+
+2002-09-06 Ziemowit Laski <zlaski@apple.com>
+
+ * c-lang.c (objc_is_id): New stub.
+ * c-tree.h (objc_is_id): New forward declaration.
+ * c-typeck.c (build_c_cast): Do not strip protocol
+ qualifiers from 'id' type.
+ * objc/objc-act.c (objc_comptypes): Correct handling
+ of protocol qualifiers.
+ (objc_is_id): New.
+
+Fri Sep 6 13:10:08 2002 Jeffrey A Law (law@redhat.com)
+
+ * pentium.md (pentium-firstvboth): Fix typo.
+
+2002-09-06 Dhananjay Deshpande <dhananjayd@kpit.com>
+
+ * h8300.c (enum shift_alg): Move to earlier in h8300.c.
+ (enum shift_type, enum h8_cpu): Likewise.
+ (INL, ROT, LOP, SPC macros): Likewise.
+ (shift_alg_qi, shift_alg_hi, shift_alg_si): Likewise. Lose
+ const designator.
+ (h8300_init_once): Update shift_alg_{qi,hi,si} to use more
+ space efficient algorithms when optimize for codesize.
+
+Fri Sep 6 16:35:32 2002 Nicola Pero <n.pero@mi.flashnet.it>
+
+ Fix PR/1727 and long-standing failing testcase
+ objc/formal-protocol-6.m.
+ * objc-act.c (build_protocol_expr): If compiling for the GNU
+ runtime, create a list of Protocol statically allocated instances
+ if it doesn't exist, then add the Protocol object to this same
+ list.
+ (get_objc_string_decl): Fixed typo/bug - TREE_VALUE had been used
+ instead of TREE_CHAIN.
+
+Fri Sep 6 16:17:33 2002 Nicola Pero <n.pero@mi.flashnet.it>
+
+ * objc/objc-act.c (dump_interface): Enlarged the char * buffer to
+ 10k. Fixed category dumping - print out category names with the
+ proper syntax. Print '@end\n' and not '\n@end' at the end of the
+ interface.
+ (finish_objc): Fixed the -gen-decls option. It was printing out
+ only the last class. Dump an interface declaration of all classes
+ being compiled instead.
+
+2002-09-06 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/arm/arm-protos.h (arm_gen_return_addr_mask): New
+ prototype.
+ * config/arm/arm.c (arm_gen_return_addr_mask): New function.
+ * config/arm/arm.h (MASK_RETURN_ADDR): Use arm_gen_return_addr_mask
+ if not APCS26 and not Thumb or ARMv4-or-higher. Use gen_int_mode
+ rather than GEN_INT.
+ * config/arm/arm.md (UNSPEC_CHECK_ARCH): Define.
+ (return_addr_mask, *check_arch2): New.
+
+2002-09-06 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*adddi3_cc", "*adddi3_cconly",
+ "*adddi3_cconly2", "*adddi3_64", "*adddi3_31", "adddi3",
+ "*addsi3_carry1_cc", "*addsi3_carry1_cconly",
+ "*addsi3_carry2_cc", "*addsi3_carry2_cconly",
+ "*addsi3_cc", "*addsi3_cconly", "*addsi3_cconly2", "addsi3",
+ "adddf3", "*adddf3", "*adddf3_ibm",
+ "addsf3", "*addsf3", "*addsf3_ibm",
+ "muldi3", "mulsi3", "mulsidi3",
+ "muldf3", "*muldf3", "*muldf3_ibm",
+ "mulsf3", "*mulsf3", "*mulsf3_ibm",
+ "*anddi3_cc", "*anddi3_cconly", "anddi3",
+ "*andsi3_cc", "*andsi3_cconly", "andsi3",
+ "*iordi3_cc", "*iordi3_cconly", "iordi3",
+ "*iorsi3_cc", "*iorsi3_cconly", "iorsi3",
+ "*xordi3_cc", "*xordi3_cconly", "xordi3",
+ "*xorsi3_cc", "*xorsi3_cconly", "xorsi3"): Use "nonimmediate_operand"
+ instead of "register_operand" as predicate for "%0" operand.
+
+2002-09-06 Jakub Jelinek <jakub@redhat.com>
+
+ * configure.in (HAVE_AS_OFFSETABLE_LO10): Use -xarch=v9
+ unconditionally when gcc_cv_as_flags64 checks are gone.
+ * configure: Rebuilt.
+
+2002-09-06 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.md (extzvsi_internal2): Revert most of
+ 2002-07-26 change. Comment.
+
+2002-09-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * frv.c (frv_unique_section, frv_select_section,
+ frv_select_rtx_section): Delete.
+ (frv_in_small_data_p): New.
+ (TARGET_ASM_UNIQUE_SECTION, TARGET_ASM_SELECT_SECTION,
+ TARGET_ASM_SELECT_RTX_SECTION): Delete.
+ (TARGET_IN_SMALL_DATA_P): Define.
+
+2002-09-05 Dale Johannesen <dalej@apple.com>
+
+ * reload1.c (reload): Retain only those memory clobbers
+ added for variable-array handling.
+
+2002-09-05 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/arm/arm.c (arm_return_in_memory): Implement ATPCS
+ return-in-memory rules.
+ * config/arm/arm.h (ARM_FLAG_ATPCS, TARGET_ATPCS): Define.
+
+2002-09-05 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/xcoff.h (HOT_TEXT_SECTION_NAME): Delete.
+ (UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Delete.
+
+2002-09-05 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * real.c: Avoid parse error if FLOAT_WORDS_BIG_ENDIAN is
+ not a compile-time constant for the non-IBM case.
+ * config/arm/arm-protos.h (arm_float_words_big_endian): New
+ prototype.
+ * config/arm/arm.c (arm_float_words_big_endian): New function.
+ * config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define __VFP_FP__
+ if TARGET_VFP and not TARGET_HARD_FLOAT.
+ (ARM_FLAG_VFP, TARGET_VFP): Define.
+ (FLOAT_WORDS_BIG_ENDIAN): Use arm_float_words_big_endian.
+
+2002-09-05 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/install.texi: Correct text of s390-*-linux* and s390x-*-linux*
+ URLs. Fix AIX wording.
+
+2002-09-05 Stan Shebs <shebs@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Make -fpic and
+ -fPIC equivalent on Darwin.
+
+Thu Sep 5 16:27:47 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (sh_expand_builtin): Return early if encountering an
+ error_mark for a type.
+
+2002-09-05 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_expand_plus_operand): Do not require
+ double-word scratch register.
+ config/s390/s390.md ("reload_indi", "reload_insi"): Adapt.
+
+ ("*tmqi_ext", "*tmdi_mem", "*tmsi_mem", "*tmhi_mem", "*tmqi_mem",
+ "*cli"): Replace s_operand by memory_operand.
+ ("cmpstrdi", "cmpstrsi"): Replace s_operand by general_operand.
+
+2002-09-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (asm_file_start): Add a missing
+ semicolon.
+
+2002-09-04 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * c-typeck.c (build_function_call): Remove unused variable(s).
+ (build_c_cast): Likewise.
+ * calls.c (rtx_for_function_call): Likewise.
+ * cfglayout.c (duplicate_insn_chain): Likewise.
+ * cfgloop.c (flow_loop_nodes_find): Likewise.
+ * cfgrtl.c (split_edge): Likewise.
+ * df.c (df_ref_create): Likewise.
+ * except.c (expand_end_catch): Likewise.
+ * expr.c (emit_push_insn, store_constructor, expand_expr): Likewise.
+ * function.c (emit_return_into_block): Likewise.
+ (reposition_prologue_and_epilogue_notes): Likewise.
+ * gengtype.c (get_file_basename, write_gc_structure_fields): Likewise.
+ * combine.c (subst_prev_insn, need_refresh): Remove.
+ * dwarf2out.c (primary_filename): Remove.
+ * final.c (new_block): Remove.
+ * gcse.c (orig_bb_count): Remove.
+
+2002-09-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * dsp16xx-protos.h (dsp16xx_compare_gen): Change to bool.
+ * dsp16xx.c (dsp16xx_compare_gen): Likewise.
+ * dsp16xx.md: Treat dsp16xx_compare_gen as a bool. Call functions
+ directly instead of using a function pointer.
+
+2002-09-04 Krister Walfridsson <cato@df.lth.se>
+
+ * config/i386/i386.h (GOT_SYMBOL_NAME): Define.
+ * config/i386/i386.c (output_set_got): Use GOT_SYMBOL_NAME.
+ (ix86_output_addr_diff_elt) Likewise.
+ (x86_output_mi_thunk) Likewise.
+ * config/i386/netbsd.h (GOT_SYMBOL_NAME): Redefine.
+
+2002-09-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * frv.c (frv_encode_section_info): Fix error in last change.
+
+2002-09-04 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_flag_pic): New variable.
+ (rs6000_elf_encode_section_info): ATTRIBUTE_UNUSED.
+ (TARGET_BINDS_LOCAL_P): Define.
+ (rs6000_override_options): Save original flag_pic value.
+ (rs6000_elf_select_section): Call default_elf_select_section_1.
+ (rs6000_elf_unique_section): Call default_unique_section_1.
+ (rs6000_elf_in_small_data_p): New function.
+ (rs6000_xcoff_asm_named_section): Determine storage mapping class.
+ (rs6000_xcoff_select_section): Update based on defaults.
+ (rs6000_xcoff_unique_section): Set to basic name if not common.
+ (rs6000_binds_local_p): New function.
+ * config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Set
+ targetm.have_srodata_section if SDATA_EABI.
+ (TARGET_IN_SMALL_DATA_P): Define.
+
+2002-09-04 Dale Johannesen <dalej@apple.com>
+
+ * varasm.c (struct rtx_const, decode_rtx_const):
+ Make veclo and vechi fields not share storage.
+
+Thu Sep 5 00:34:33 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * loop.c (scan_loop): Don't mark separate insns out of a libcall
+ for moving.
+ (move_movables): Abort if we see the first insn of a libcall.
+
+2002-09-04 Richard Henderson <rth@redhat.com>
+
+ * builtin-types.def (BT_FN_FLOAT): New.
+ (BT_FN_DOUBLE, BT_FN_LONG_DOUBLE): New.
+ * builtins.def (BUILT_IN_INF, BUILT_IN_INFF, BUILT_IN_INFL,
+ BUILT_IN_HUGE_VAL, BUILT_IN_HUGE_VALF, BUILT_IN_HUGE_VALL): New.
+ * builtins.c (fold_builtin_inf): New.
+ (fold_builtin): Call it.
+ * real.c (ereal_inf): New.
+ * real.h: Declare it.
+ * doc/extend.texi: Document new builtins.
+
+2002-09-04 Richard Henderson <rth@redhat.com>
+
+ * cse.c (cse_insn): Avoid subreg games if the equivalence
+ is already in the proper mode.
+
+2002-09-04 Eric Botcazou <ebotcazou@multimania.com>
+
+ PR c/7102
+ * optabs.c (expand_binop): Convert CONST_INTs in all cases.
+
+2002-09-04 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.md (setccfp0, setccfp1): New patterns.
+
+2002-09-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * frv-protos.h (frv_init_builtins, frv_expand_builtin,
+ frv_select_section, frv_select_rtx_section,
+ frv_encode_section_info, frv_unique_section): Delete.
+ * frv.c: Update for target hooks.
+ * frv.h (STRIP_NAME_ENCODING, SLOW_ZERO_EXTEND, SELECT_SECTION,
+ SELECT_RTX_SECTION, ENCODE_SECTION_INFO, UNIQUE_SECTION,
+ EASY_DIV_EXPR, MD_INIT_BUILTINS, MD_EXPAND_BUILTIN): Delete.
+
+2002-09-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ip2k-protos.h (function_prologue, function_epilogue,
+ encode_section_info): Update to match target hook specification.
+ * ip2k.c: Wrap `MDR' code in IP2K_MD_REORG_PASS.
+ (function_prologue, function_epilogue, encode_section_info):
+ Update to match target hook specification.
+ * ip2k.h (SELECT_SECTION, SELECT_RTX_SECTION, ASM_OPEN_PAREN,
+ ASM_CLOSE_PAREN, EASY_DIV_EXPR): Delete.
+ (NOTICE_UPDATE_CC): Cast to void.
+ * ip2k.md: Add defaults in switch statements.
+
+2002-09-04 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/trouble.texi (Interoperation): Update information about C++ ABI
+ issues.
+
+2002-09-04 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/sparc/t-netbsd64: Disable multilib for now.
+
+2002-09-04 David Edelsohn <edelsohn@gnu.org>
+
+ * target-def.h (TARGET_HAVE_SRODATA_SECTION): New macro.
+ * target.h (gcc_target): Add have_srodata_section member.
+ * varasm.c (section_category): Add SECCAT_SRODATA.
+ (categorize_decl_for_section): Return SECCAT_SRODATA for sdata if
+ READONLY_SDATA_SECTION defined.
+ (decl_readonly_section_1): True for SECCAT_SRODATA also.
+ (default_elf_select_section_1): Map SECCAT_SRODATA to .sdata2.
+ (default_unique_section_1): Likewise.
+
+2002-09-04 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * expr.c (emit_group_load): Revise to allow splitting TCmode source
+ into DImode pieces.
+
+ * pa-64.h (LONG_DOUBLE_TYPE_SIZE): Define to 128.
+ * pa64-regs.h (CLASS_CANNOT_CHANGE_MODE_P): Inhibit changes from SImode
+ for floating-point register class.
+ * pa.c (function_arg): Fix handling of modes wider than one word for
+ TARGET_64BIT.
+
+Wed Sep 4 18:48:10 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * combine.c (make_compound_operation): Don't generate zero / sign
+ extensions in floating point modes.
+
+2002-09-04 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/c-tree.texi: Fix overfull hboxes.
+ * doc/cppopts.texi: Ditto.
+ * doc/extend.texi: Ditto.
+ * doc/gty.texi: Ditto.
+ * doc/invoke.texi: Ditto.
+ * doc/makefile.texi: Ditto.
+ * doc/rtl.texi: Ditto.
+ * doc/standards.texi: Ditto.
+ * doc/tm.texi: Ditto.
+
+2002-09-04 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (builtin_define_with_hex_fp_value): New.
+ (builtin_define_float_constants): Use it. Fix H_FLOAT mant_dig.
+
+2002-09-04 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/invoke.texi (-fshort-wchar): Move to Code Generation Options.
+ (-fpcc-struct-return, -freg-struct-return, -fshort-enums,
+ -fshort-double, -fshort-wchar, -fpack-struct, -fleading-underscore):
+ Warn that these options can break ABI compatibility.
+
+2002-09-04 Richard Henderson <rth@redhat.com>
+
+ * real.c (ereal_to_decimal): Add digits parameter.
+ * real.h (REAL_VALUE_TO_DECIMAL): Remove format; add digits parameter.
+ * c-pretty-print.c (pp_c_real_literal): Update call.
+ * print-rtl.c (print_rtx): Likewise.
+ * print-tree.c (print_node_brief, print_node): Likewise.
+ * sched-vis.c (print_value): Likewise.
+ * config/arc/arc.c (arc_print_operand): Likewise.
+ * config/c4x/c4x.c (c4x_print_operand): Likewise.
+ * config/i370/i370.h (PRINT_OPERAND): Likewise.
+ * config/i386/i386.c (print_operand): Likewise.
+ * config/i960/i960.c (i960_print_operand): Likewise.
+ * config/ip2k/ip2k.c (asm_output_float): Likewise.
+ * config/m32r/m32r.c (m32r_print_operand): Likewise.
+ * config/m68hc11/m68hc11.c (print_operand): Likewise.
+ * config/m68k/hp320.h (PRINT_OPERAND, ASM_OUTPUT_FLOAT_OPERAND,
+ ASM_OUTPUT_DOUBLE_OPERAND, ASM_OUTPUT_LONG_DOUBLE_OPERAND): Likewise.
+ * config/m68k/m68k.h (ASM_OUTPUT_FLOAT_OPERAND,
+ ASM_OUTPUT_DOUBLE_OPERAND, ASM_OUTPUT_LONG_DOUBLE_OPERAND): Likewise.
+ * config/m68k/sun2o4.h (ASM_OUTPUT_FLOAT_OPERAND,
+ ASM_OUTPUT_DOUBLE_OPERAND): Likewise.
+ * config/m68k/sun3.h (ASM_OUTPUT_FLOAT_OPERAND,
+ ASM_OUTPUT_DOUBLE_OPERAND): Likewise.
+ * config/mips/mips.c (print_operand): Likewise.
+ * config/ns32k/ns32k.c (print_operand): Likewise.
+ * config/pdp11/pdp11.h (PRINT_OPERAND): Likewise.
+ * config/vax/vax.h (PRINT_OPERAND): Likewise.
+ * doc/tm.texi (REAL_VALUE_TO_DECIMAL): Update docs.
+
+2002-09-04 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/elf.h (TARGET_SECTION_TYPE_FLAGS): Define to
+ xtensa_multibss_section_type_flags.
+ * config/xtensa/xtensa.c (xtensa_multibss_section_type_flags): Define.
+
+2002-09-04 Richard Henderson <rth@redhat.com>
+
+ * doc/install-old.texi: Don't mention enquire.
+ * doc/sourcebuild.texi: Update float.h description.
+
+Wed Sep 4 11:22:14 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (mperm_w_little, mperm_w_big): Supply mode for zero_extract.
+
+2002-09-03 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (build_function_call_expr): Remove prototype, export
+ as non-static and add a comment above function definition.
+ (builtin_mathfn_code): New function to check for math builtins.
+ (fold_builtin): Optimize sqrt(0.0) as 0.0, sqrt(1.0) as 1.0,
+ exp(0.0) as 1.0, and log(1.0) as 0.0. Optimize exp(log(x)) and
+ log(exp(x)) as x. Optimize sqrt(exp(x)) as exp(x/2.0) and
+ log(sqrt(x)) as log(x)/2.0.
+
+ * tree.h: Prototype build_function_call_expr and builtin_mathfn_code
+ in new "builtins.c" section. Place the build_range_type prototype
+ with the other prototypes from "tree.c".
+
+ * fold-const.c (fold) [ABS_EXPR]: Fold fabs(sqrt(x)) as sqrt(x)
+ and fabs(exp(x)) as exp(x). [MULT_EXPR]: Fold sqrt(x)*sqrt(y)
+ as sqrt(x*y) and exp(x)*exp(y) as exp(x+y). [RDIV_EXPR]: Fold
+ x/exp(y) as x*exp(-y).
+
+2002-09-03 David Edelsohn <edelsohn@gnu.org>
+
+ * varasm.c (default_section_type_flags): Append _1 to name with
+ shlib parameter. Use original name to call new function with
+ implicit flag_pic.
+ (decl_readonly_section): Likewise.
+ (default_elf_select_section): Likewise.
+ (default_unique_section): Likewise.
+ (default_bind_local_p): Likewise.
+ (categorize_decl_for_section): Add shlib parameter to use in place
+ of implicit flag_pic.
+ * output.h: Declare new functions with _1 and shlib argument.
+
+2002-09-03 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/install.texi: Fix typos, formatting problems, and obvious
+ overfull/underfull boxes.
+
+ * Makefile.in (TEXI_GCC_FILES): Add compat.texi.
+ * doc/gcc.texi (Top): Add new chapter, Binary Compatibility, and
+ include its file, compat.texi.
+ * doc/compat.texi: New file with new chapter, Binary Compatibility.
+
+2002-09-03 Neil Booth <neil@daikokuya.co.uk>
+
+ Debian BTS Bug #157416
+ * cpphash.h (FIRST, LAST, CUR, RLIMIT): Fix definitions.
+ * cpplib.c (destringize_and_run): Kludge around getting
+ tokens from in-progress macros.
+ (_cpp_do__Pragma): Simplify.
+
+2002-09-03 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.h (EXTRA_SPECS): Remove cpp_cpu.
+ (CPP_CPU_SPEC): Remove.
+ (TARGET_CPU_CPP_BUILTINS): New.
+ * config/ia64/hpux.h (CPP_PREDEFINES): Remove.
+ (CPP_SPEC): Remove.
+ (TARGET_OS_CPP_BUILTINS): New.
+ * config/ia64/linux.h (CPP_PREDEFINES): Remove.
+ (TARGET_OS_CPP_BUILTINS): New.
+ * config/ia64/aix.h (CPP_SPEC): Move some stuff to
+ TARGET_OS_CPP_BUILTINS.
+ (CPP_PREDEFINES): Remove.
+ (CPLUSPLUS_CPP_SPEC): Remove.
+ (TARGET_OS_CPP_BUILTINS): New.
+
+2002-09-03 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (USER_H): Add ginclude/float.h.
+ (FLOAT_H): Remove.
+ (stmp-int-hdrs, install-mkheaders): Don't handle FLOAT_H.
+ (mostlyclean): Don't remove float.h intermediate files.
+ (distclean): Don't remove float.h.
+ * config.gcc: Remove all float_format references.
+ * configure.in (float_format, float_h_file): Remove.
+
+ * c-common.c: Include tree-inline.h.
+ (builtin_define_with_int_value): New.
+ (builtin_define_type_precision): Use it.
+ (builtin_define_float_constants): New.
+ (cb_register_builtins): Use it. Define __FLT_RADIX__ and
+ __FLT_EVAL_METHOD__.
+ * defaults.h (TARGET_FLT_EVAL_METHOD): New.
+ * config/i386/i386.h (TARGET_FLT_EVAL_METHOD): New.
+ * config/m68k/m68k.h (TARGET_FLT_EVAL_METHOD): New.
+ * doc/tm.texi (INTEL_EXTENDED_IEEE_FORMAT): Mention moto 96-bit format.
+ (TARGET_FLT_EVAL_METHOD): New.
+
+ * config/float-c4x.h, config/float-i128.h, config/float-i32.h,
+ config/float-i386.h, config/float-i64.h, config/float-m68k.h,
+ config/float-sh.h, config/float-sparc.h, config/float-vax.h: Remove.
+ * ginclude/float.h: New.
+
+2002-09-03 Stan Shebs <shebs@apple.com>
+
+ * config/darwin.h (WARN_FOUR_CHAR_CONSTANTS): Remove, never used.
+ (DWARF2_DEBUGGING_INFO): Remove until assembler accepts Dwarf-2.
+ (PREFERRED_DEBUGGING_TYPE): Ditto.
+ (ASM_OUTPUT_IDENT): Remove empty definition.
+
+2002-09-03 Steve Ellcey <sje@cup.hp.com>
+
+ * config.gcc (ia64*-*-hpux*): Add ia64-c.o to c_target and
+ cxx_target.
+ * config/ia64/hpux.h (REGISTER_TARGET_PRAGMAS): Register pragma
+ handling routine for builtin pragma.
+ * config/ia64/ia64-protos.h (ia64_hpux_handle_builtin_pragma):
+ Registered pragma handling routine.
+ * ia64-c.c (ia64_hpux_handle_builtin_pragma): Ditto.
+ (ia64_hpux_add_pragma_builtin) New subroutine used by above.
+ If builtin pragma seen for math routine and C89 conformance is
+ requested use different math function in order to set errno.
+ * t-ia64 (ia64-c.o): Add new rule for new file.
+
+2002-09-03 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("movti"): Add Q->Q alternative.
+ ("*movdi_64", "*movdi_31", "*movsi", "movhi", "movqi_64",
+ "movqi", "*movdf_64", "*movdf_31", "*movsf"): Likewise.
+
+ ("*movti_ss", "*movdi_ss", "*movsi_ss", "*movdf_ss",
+ "*movsf_ss"): Remove.
+
+2002-09-03 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa32-regs.h (CLASS_CANNOT_CHANGE_MODE, CLASS_CANNOT_CHANGE_MODE_P):
+ Delete macros.
+
+2002-09-03 Arati Dikey <aratid@kpit.com>
+
+ * h8300.c (asm_file_start): Corrected optimization comment.
+
+2002-09-03 Stan Shebs <shebs@apple.com>
+
+ * c-lang.c (recognize_objc_keyword): Remove, no longer used.
+ * c-tree.h (recognize_objc_keyword): Remove decl.
+ * c-typeck.c (comp_target_types): Update a comment.
+
+2002-09-03 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_decompose_address): Remove STRICT parameter
+ and register validity checks.
+ (general_s_operand): Adapt to s390_decompose_address interface change.
+ (q_constraint): Likewise.
+ (s390_expand_plus_operand): Likewise.
+ (legitimiate_address_p): Likewise.
+ (legitimate_la_operand_p): Likewise.
+ (legitimize_la_operand): Likewise.
+ (print_operand_address): Likewise.
+ (print_operand): Likewise.
+
+Tue Sep 3 11:32:14 2002 Nicola Pero <n.pero@mi.flashnet.it>
+
+ PR objc/5956:
+ * objc/objc-act.c (build_typed_selector_reference): Fix typo which
+ was causing the new selector never to match the existing ones
+ (Patch by Alexander Malmberg <alexander@malmberg.org>).
+
+2002-09-03 Graham Stott <graham.stott@btinternet.com>
+
+ * config/i386/i386.md ("femms"): Add "memory" attr "none".
+
+2002-09-03 Graham Stott <graham.stott@btinternet.com>
+
+ * expr.c (expand_expr): Remove extraneous comment and code.
+
+2002-09-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * stor-layout (finish_builtin_struct): Renamed and moved from c++
+ frontend. Take chain of fields. Allow NULL alignment type.
+ * tree.h (finish_builtin_struct): Declare.
+
+2002-09-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/alpha/alpha.c config/alpha/alpha.h config/alpha/alpha.md
+ config/alpha/elf.h config/alpha/unicosmk.h config/alpha/vms.h
+ config/arc/arc.c config/arc/arc.h config/arm/aout.h
+ config/arm/arm.c config/arm/arm.h config/arm/arm.md
+ config/avr/avr.h config/d30v/d30v.h config/dbxcoff.h
+ config/dbxelf.h config/elfos.h config/fr30/fr30.h config/frv/frv.h
+ config/i386/i386.c config/i386/i386.md config/i386/sco5.h
+ config/ia64/ia64.h config/ip2k/ip2k.h config/m68hc11/m68hc11.md
+ config/m68k/hp320.h config/m68k/m68k.c config/m68k/m68k.md
+ config/m68k/mot3300.h config/m68k/sgs.h config/m68k/tower-as.h
+ config/m88k/m88k.c config/m88k/m88k.h config/mcore/mcore-pe.h
+ config/mcore/mcore.c config/mips/mips.c config/mips/mips.h
+ config/ns32k/ns32k.md config/pa/pa-linux.h config/pa/pa.c
+ config/pa/pa.h config/pa/pa.md config/romp/romp.h
+ config/rs6000/linux64.h config/rs6000/lynx.h
+ config/rs6000/rs6000.c config/rs6000/sysv4.h config/rs6000/xcoff.h
+ config/s390/s390.c config/s390/s390.md config/sh/sh.c
+ config/sparc/sparc.c config/sparc/sysv4.h
+ config/stormy16/stormy16.h dbxout.c defaults.h dwarf2out.c
+ dwarfout.c except.c final.c varasm.c vmsdbgout.c: Replace
+ ASM_OUTPUT_INTERNAL_LABEL macro with a call to the target hook.
+
+ * doc/tm.texi: Update docs.
+ * default.h (ASM_OUTPUT_INTERNAL_LABEL): Don't define.
+ * system.h (ASM_OUTPUT_INTERNAL_LABEL): Poison.
+
+2002-08-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (sdbout.o, insn-output.o): Depend on $(TARGET_H).
+ * arc.c (arc_internal_label): New function.
+ (TARGET_ASM_INTERNAL_LABEL): Set.
+ * arc.h (ASM_OUTPUT_INTERNAL_LABEL): Delete.
+ * arm.c (arm_internal_label): New function.
+ (TARGET_ASM_INTERNAL_LABEL): Set.
+ * arm.h (ASM_OUTPUT_INTERNAL_LABEL): Delete.
+ * arm/elf.h (ASM_OUTPUT_INTERNAL_LABEL): Delete.
+ * i370.c (i370_internal_label): New function.
+ (TARGET_ASM_INTERNAL_LABEL): Set.
+ * i370.h (ASM_OUTPUT_INTERNAL_LABEL): Delete.
+ * m68k/hp320.h (ASM_OUTPUT_INTERNAL_LABEL): Delete.
+ * m68k.c (m68k_hp320_internal_label): New function.
+ (TARGET_ASM_INTERNAL_LABEL): Set.
+ * m88k.c (m88k_internal_label): New function.
+ (TARGET_ASM_INTERNAL_LABEL): Set.
+ * m88k.h (ASM_OUTPUT_INTERNAL_LABEL): Delete.
+ * defaults.h (ASM_OUTPUT_INTERNAL_LABEL): Set to target hook.
+ * genoutput.c (output_prologue): Include target.h in output file.
+ * output.h (default_internal_label): Declare.
+ * sdbout.c: Include target.h.
+ * target-def.h (TARGET_ASM_INTERNAL_LABEL): Set and add to
+ TARGET_ASM_OUT.
+ * target.h (internal_label): Add to struct gcc_target.
+ * varasm.c (default_internal_label): New function.
+
+2002-08-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alpha.h (ASM_OUTPUT_INTERNAL_LABEL): Delete.
+ * avr.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * c4x.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * cris.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * d30v.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * darwin.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * dsp16xx.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * elfos.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * h8300.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * i386/att.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * i386/bsd.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * i386/i386-coff.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * i386/lynx-ng.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * i386/lynx.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * i386/sco5.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * i960/i960.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * m68k/3b1.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * m68k/amix.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * m68k/atari.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * m68k.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * m68k/mot3300.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * m68k/tower-as.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * m88k.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * mcore.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * mips.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * mmix-protos.h (mmix_asm_output_internal_label): Likewise.
+ * mmix.c (mmix_asm_output_internal_label): Likewise.
+ * mmix.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * ns32k.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * pa.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * pdp11.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * romp.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * rs6000/xcoff.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * sh/coff.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * sh/elf.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * sparc/freebsd.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * sparc/linux.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * sparc/linux64.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * sparc/netbsd-elf.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * sparc/pbd.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * sparc/sol2.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * sparc.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * sparc/vxsim.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * stormy16.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * svr3.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * vax.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+
+ * defaults.h (ASM_OUTPUT_INTERNAL_LABEL): Define.
+
+2002-08-31 Richard Henderson <rth@redhat.com>
+
+ * expr.c (block_move_libcall_safe_for_call_parm): Fix thinko.
+
+2002-08-31 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.c (pa_globalize_label): Add ATTRIBUTE_UNUSED to prototype.
+
+2002-08-30 Richard Henderson <rth@redhat.com>
+
+ PR opt/7515
+ * c-objc-common.c: Include target.h.
+ (c_cannot_inline_tree_fn): Don't auto-inline functions that
+ don't bind locally. Factor setting DECL_UNINLINABLE.
+ * Makefile.in (c-objc-common.o): Update.
+
+2002-08-30 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/install.texi (Configuration, Building): Fix a typo and
+ some formatting directives.
+
+2002-08-30 Paul Koning <pkoning@equallogic.com>
+
+ * doc/c-tree.texi (RDIV_EXPR): Fix typo.
+ * doc/rtl.texi (post_modify): Remove misplaced text, remove "not
+ implemented" note.
+ * doc/md.texi (IP2K): Move machine-specific constraints before MIPS
+ for alphabetic order.
+ * doc/tm.texi (TARGET_FLOAT_FORMAT): Update description for
+ VAX_FLOAT_FORMAT. Remove reference to HOST_FLOAT_FORMAT.
+ (VAX_HALFWORD_ORDER): Document.
+ (LARGEST_EXPONENT_IS_NORMAL): Remove note about being only for
+ IEEE float format.
+ (TARGET_SCHED_ISSUE_RATE): Reword reference to MAX_DFA_ISSUE_RATE.
+ (ASM_OUTPUT_LABEL_REF): Fix font.
+ (CASE_VECTOR_SHORTEN_MODE): Ditto.
+
+2002-08-30 Denis Chertykov <denisc@overta.ru>
+
+ * config/ip2k/ip2k.c (ip2k_set_compare): Remove all const_double
+ stuff.
+ (ip2k_gen_unsigned_comp_branch): Handle CONST_INT and
+ CONST_DOUBLE constants.
+
+2002-08-30 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/alpha/alpha.h (TARGET_CPU_CPP_BUILTINS): Move language-
+ related defines to...
+ (SUBTARGET_LANGUAGE_CPP_BUILTINS): ...here.
+ * config/alpha/netbsd.h (SUBTARGET_LANGUAGE_CPP_BUILTINS): Redefine
+ as a no-op.
+
+2002-08-30 Krister Walfridsson <cato@df.lth.se>
+
+ * config/arm/arm.c (arm_asm_output_labelref): New function.
+ * config/arm/arm.h (ASM_OUTPUT_LABELREF): Call arm_asm_output_labelref.
+ * config/arm/arm-protos.h: Add prototype for arm_asm_output_labelref.
+
+2002-08-29 Rodney Brown <rbrown64@csc.com.au>
+
+ * doc/install.texi (Specific, alpha*-dec-osf*): Add "virtual
+ memory exhausted" workarounds.
+
+2002-08-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * diagnostic.c (fancy_abort): Don't repeat "internal error".
+ * toplev.c (crash_signal): Likewise.
+
+Fri Aug 30 00:33:37 2002 Nicola Pero <n.pero@mi.flashnet.it>
+
+ * doc/cpp.texi (__NEXT_RUNTIME__): Extended documentation.
+ * doc/invoke.texi (-fnext-runtime, -Wno-protocol, -Wselector):
+ Extended, updated documentation.
+ (-Wundeclared-selector): Documented.
+
+2002-08-29 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/chorus.h: Consistently define *_DEBUGGING_INFO with
+ the value 1. Do not undef before defining.
+ * config/darwin.h: Likewise.
+ * config/dbx.h: Likewise.
+ * config/dbxcoff.h: Likewise.
+ * config/dbxelf.h: Likewise.
+ * config/elfos.h: Likewise.
+ * config/interix.h: Likewise.
+ * config/lynx-ng.h: Likewise.
+ * config/lynx.h: Likewise.
+ * config/netware.h: Likewise.
+ * config/psos.h: Likewise.
+ * config/svr3.h: Likewise.
+ * config/alpha/alpha.h: Likewise.
+ * config/alpha/elf.h: Likewise.
+ * config/alpha/vms.h: Likewise.
+ * config/arc/arc.h: Likewise.
+ * config/arm/aout.h: Likewise.
+ * config/arm/coff.h: Likewise.
+ * config/c4x/c4x.h: Likewise.
+ * config/h8300/h8300.h: Likewise.
+ * config/i386/cygwin.h: Likewise.
+ * config/i386/djgpp.h: Likewise.
+ * config/i386/gas.h: Likewise.
+ * config/i386/gstabs.h: Likewise.
+ * config/i386/i386-coff.h: Likewise.
+ * config/i386/i386-interix.h: Likewise.
+ * config/i386/sco5.h: Likewise.
+ * config/i386/svr3dbx.h: Likewise.
+ * config/i386/sysv3.h: Likewise.
+ * config/i386/win32.h: Likewise.
+ * config/i386/x86-64.h: Likewise.
+ * config/i960/i960.h: Likewise.
+ * config/ia64/ia64.h: Likewise.
+ * config/ip2k/ip2k.h: Likewise.
+ * config/m32r/m32r.h: Likewise.
+ * config/m68k/3b1.h: Likewise.
+ * config/m68k/3b1g.h: Likewise.
+ * config/m68k/ccur-GAS.h: Likewise.
+ * config/m68k/coff.h: Likewise.
+ * config/m68k/hp2bsd.h: Likewise.
+ * config/m68k/hp310g.h: Likewise.
+ * config/m68k/hp320g.h: Likewise.
+ * config/m68k/hp3bsd.h: Likewise.
+ * config/m68k/hp3bsd44.h: Likewise.
+ * config/m68k/linux-aout.h: Likewise.
+ * config/m68k/m68k-aout.h: Likewise.
+ * config/m68k/mot3300.h: Likewise.
+ * config/m68k/netbsd.h: Likewise.
+ * config/m68k/openbsd.h: Likewise.
+ * config/m68k/pbb.h: Likewise.
+ * config/m68k/plexus.h: Likewise.
+ * config/m68k/sun2.h: Likewise.
+ * config/m68k/sun3.h: Likewise.
+ * config/m68k/tower-as.h: Likewise.
+ * config/m68k/vxm68k.h: Likewise.
+ * config/m88k/aout-dbx.h: Likewise.
+ * config/m88k/m88k-aout.h: Likewise.
+ * config/mcore/mcore-elf.h: Likewise.
+ * config/mcore/mcore-pe.h: Likewise.
+ * config/mips/elf.h: Likewise.
+ * config/mips/elf64.h: Likewise.
+ * config/mips/iris5gas.h: Likewise.
+ * config/mips/iris6.h: Likewise.
+ * config/mips/mips.h: Likewise.
+ * config/mips/sni-gas.h: Likewise.
+ * config/mmix/mmix.h: Likewise.
+ * config/ns32k/netbsd.h: Likewise.
+ * config/pa/pa64-hpux.h: Likewise.
+ * config/romp/romp.h: Likewise.
+ * config/rs6000/sysv4.h: Likewise.
+ * config/rs6000/xcoff.h: Likewise.
+ * config/sh/coff.h: Likewise.
+ * config/sh/elf.h: Likewise.
+ * config/sparc/linux64.h: Likewise.
+ * config/sparc/liteelf.h: Likewise.
+ * config/sparc/netbsd.h: Likewise.
+ * config/sparc/openbsd.h: Likewise.
+ * config/sparc/pbd.h: Likewise.
+ * config/sparc/sp64-elf.h: Likewise.
+ * config/sparc/sp86x-elf.h: Likewise.
+ * config/sparc/sparc.h: Likewise.
+ * config/vax/vax.h: Likewise.
+ * config/vax/vaxv.h: Likewise.
+
+2002-08-29 "Dhananjay R. Deshpande" <dhananjayd@kpit.com>
+
+ * h8300.c (shift_alg_hi): Various tweaks to improve performance
+ of HImode shifts.
+ (get_shift_alg): Corresponding changes.
+
+2002-08-29 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * som.h (ALWAYS_STRIP_DOTDOT): Define to 1.
+
+2002-08-29 Richard Henderson <rth@redhat.com>
+
+ * expr.h (enum block_op_methods): New.
+ (emit_block_move): Update prototype.
+ * expr.c (block_move_libcall_safe_for_call_parm): New.
+ (emit_block_move_via_loop): New.
+ (emit_block_move): Use them. New argument METHOD.
+ (emit_push_insn): Always respect the given alignment.
+ (expand_assignment): Update call to emit_block_move.
+ (store_expr, store_field, expand_expr): Likewise.
+ * builtins.c (expand_builtin_apply): Likewise.
+ (expand_builtin_memcpy, expand_builtin_va_copy): Likewise.
+ * function.c (expand_function_end): Likewise.
+ * config/sh/sh.c (sh_initialize_trampoline): Likewise.
+ * config/sparc/sparc.c (sparc_va_arg): Likewise.
+ * calls.c (expand_call, emit_library_call_value_1): Likewise.
+ (save_fixed_argument_area): Use emit_block_move with
+ BLOCK_OP_CALL_PARM instead of move_by_pieces.
+ (restore_fixed_argument_area): Likewise.
+ (store_one_arg): Fix alignment parameter to emit_push_insn.
+
+2002-08-29 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * install.texi (hppa64-hp-hpux11*): Document installation procedure.
+
+2002-08-29 Catherine Moore <clm@redhat.com>
+
+ * config/v850/v850.h (MULDI3_LIBCALL, UCMPDI2_LIBCALL, CMPDI2_LIBCALL,
+ NEGDI2_LIBCALL, INIT_TARGET_OPTABS, MASK_STRICT_ALIGN): Define.
+ (PREDICATE_CODES): Include new predicates.
+ (RTX_COSTS): Handle UMOD and UDIV. Tune MULT for v850e.
+ (TARGET_SWITCHES): Add strict-align.
+ (TARGET_STRICT_ALIGN): New.
+ (MASK_DEFAULT, STRICT_ALIGNMENT): Redefine.
+ * config/v850/t-v850 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES):
+ Define.
+ (LIB1ASMFUNCS): Add v850_negdi2, v850_cmpdi2, v850_ucmpdi2,
+ v850_muldi3.
+ * config/v850/lib1funcs.asm (L_callt_save_r2_r29, L_return_r2_r29,
+ L_callt_save_r2_r31, L_return_r2_r31,
+ L_save_all_interrupt): Change addi to add.
+ (L_save_interrupt, L_return_interrupt): Rework.
+ (__return_r31): Correct .size directive.
+ (mulsi3, divsi3, udivsi3, umodsi3, modsi3): Tune for v850e.
+ (v850_negdi2, v850_cmpdi2, v850_ucmpdi2, v850_muldi3):
+ New routines.
+ * config/v850/v850.c (expand_prologue): Call
+ gen_callt_save_interrupt, gen_callt_restore_all_interrupt,
+ gen_callt_return_interrupt and gen_callt_save_all_interrupt.
+ (reg_or_int9_operand): New predicate.
+ (reg_or_const_operand): New routine.
+ * config/v850/v850.md (return_interrupt): Changed from
+ restore_interrupt.
+ (callt_save_all_interrupt): Changed from save_all_interrupt_v850e.
+ (callt_save_interrupt): Change save sequence.
+ (callt_return_interrupt): New.
+ (save_interrupt): Don't use runtime function for LONG_CALLS
+ and TARGET_PROLOG_FUNCTION.
+ (save_all_interrupt): Likewise.
+ (mulsi3): Use new predicate.
+ (moviscc): Disallow some combination of constants.
+ Fix define_split for sasf insns, so that it will not generate bad
+ code if operand0 and operand5 are the same.
+ * config/v850/v850-protos.h: Prototype new predicates.
+
+2002-08-29 Zack Weinberg <zack@codesourcery.com>
+
+ * config/rs6000/rs6000.c (processor_target_table): Add 405f.
+ * config/rs6000/rs6000.h (ASM_CPU_SPEC): Likewise.
+
+2002-08-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-common.c (builtin_define_type_precision): New function.
+ (cb_register_builtins): Use it. Define __WCHAR_UNSIGNED__ is
+ wchar_t is unsigned in C++.
+ * doc/cpp.texi (Common Predefined Macros): Document
+ __WCHAR_UNSIGNED__, __CHAR_BIT__, __WCHAR_BIT__, __SHRT_BIT__,
+ __INT_BIT__, __LONG_BIT__, __LONG_LONG_BIT__, __FLOAT_BIT__,
+ __DOUBLE_BIT__, __LONG_DOUBLE_BIT__.
+
+2002-08-28 Sylvain Pion <pion@cs.nyu.edu>
+
+ * doc/invoke.texi (-Wreorder): Remove remaining pieces from the generic
+ section. Mention that it is enabled by -Wall.
+ (-Wall): Mention that there can be language-specific warnings as well.
+ (-Wctor-dtor-privacy): Mention that it is enabled by default.
+ (-Wnon-virtual-dtor): Mention that it is enabled by -Wall.
+
+Wed Aug 28 15:35:17 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (calc_live_regs): Save FPSCR_REG in an interrupt handler
+ if it is ever live.
+
+ * sh.c (sh_handle_interrupt_handler_attribute): Reject interrupt_handler
+ attribute for SHCOMPACT.
+
+ * sh.h (OVERRIDE_OPTIONS): If align_function isn't set, set it
+ appropriately.
+ (FUNCTION_BOUNDARY): Specify only the minimum alignment required
+ by the ABI.
+
+ * sh.h (SH5_WOULD_BE_PARTIAL_NREGS): Also handle TImode case.
+
+2002-08-28 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.gcc (mips*-*-netbsd*): Set target_cpu_default to
+ "MASK_GAS|MASK_ABICALLS".
+ * config/mips/netbsd.h (TARGET_ENDIAN_DEFAULT)
+ (TARGET_DEFAULT): Remove.
+ (MACHINE_TYPE): Undefine before defining.
+ (DBX_DEBUGGING_INFO, PREFERRED_DEBUGGING_TYPE): Remove.
+
+2002-08-27 Mark Mitchell <mark@codesourcery.com>
+
+ * c-common.c (warn_abi): New variable.
+ * c-common.h (warn_abi): Likewise.
+ * c-opts.c (COMMAND_LINE_OPTIONS): Add -Wabi.
+ (c_common_decode_option): Handle it.
+ * doc/invoke.texi: Document -Wabi.
+
+Tue Aug 27 23:03:52 2002 Nicola Pero <n.pero@mi.flashnet.it>
+
+ * c-common.c (warn_undeclared_selector): New variable.
+ * c-common.h (warn_undeclared_selector): Idem.
+ * c-opts.c (c_common_decode_option): Set warn_undeclared_selector
+ to on when -Wundeclared-selector is found.
+ (COMMAND_LINE_OPTIONS): Added -Wundeclared-selector.
+ * objc/objc-act.c (build_selector_expr): If
+ warn_undeclared_selector is set, check that the selector has
+ already been defined, and emit a warning if not.
+
+2002-08-27 Nick Clifton <nickc@redhat.com>
+ Catherine Moore <clm@redhat.com>
+ Jim Wilson <wilson@cygnus.com>
+
+ * config.gcc: Add v850e-*-* target.
+ Add --with-cpu= support for v850.
+ * config/v850/lib1funcs.asm: Add v850e callt functions.
+ * config/v850/v850.h: Add support for v850e target.
+ * config/v850/v850.c: Add functions to support v850e target.
+ * config/v850/v850-protos.h: Add prototypes for new functions in v850.c.
+ * config/v850/v850.md: Add patterns for v850e instructions.
+ * doc/invoke.texi: Document new v850e command line switches.
+
+Tue Aug 27 18:30:47 2002 J"orn Rennecke <joern.rennecke@superh.com>
+ Aldy Hernandez <aldyh at redhat dot com>
+
+ * doc/tm.texi: Applied numerous fixes to the automaton based
+ scheduler descrition.
+
+Tue Aug 27 19:51:05 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (classify_argument): Handle variable sized objects.
+
+Tue Aug 27 19:18:16 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_int_movcc): Fix RTL sharing problem
+
+Tue Aug 27 18:01:45 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * libgcc2.c (__bb_exit_func): Properly write the summarized statistics.
+
+Tue Aug 27 18:00:11 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (classify_argument): Properly compute word size of the analyzed object.
+
+Tue Aug 27 14:39:09 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (attribute type): Add types mt_group, fload, pcfload, fpul_gp,
+ mac_gp ftrc_s and cwb. Add / Adjust definitions in individual insn
+ accordingly.
+ (attribute insn_class): Provide default definitions based on type.
+ Remove all insn-specific settings.
+ (various function units): Remove old SH4 scheduling.
+ (branch_zero, dfp_comp, late_fp_use, any_fp_comp, any_int_load):
+ New attributes. Set them where appropriate.
+ (cpu unit FS): Don't define / use.
+ (F3, load_store): New cpu units.
+ (F01): New reservation.
+ (all insn_reservations): Make dependent on sh4 pipeline model.
+ Fix latencies.
+ (nil, reg_mov, freg_mov, sh4_fpul_gp, sh4_call): New insn_reservations.
+ (sh4_mac_gp, fp_arith_ftrc, arith3, arith3b): Likewise.
+ (mt insn_reservation): Use type mt_group.
+ (insn_reservation load_store): Split into sh4_load, sh4_load_si,
+ sh4_fload and sh4_store.
+ (insn_reservation branch_zero and branch): Replace with sh4_branch.
+ (insn_reservation branch_far): Replace with sh4_return.
+ (insn_reservation return_from_exp): Rename to:
+ (sh4_return_from_exp). Change to be just d_lock*5.
+ (insn_reservation lds_to_pr): Rename to:
+ (sh4_lds_to_pr). Change to be just d_lock*2.
+ (insn_reservation ldsmem_to_pr, sts_from_pr): Change to be just
+ d_lock*2.
+ (insn_reservation prload_mem): Rename to:
+ (sh4_prstore_mem). Change to d_lock*2,nothing,memory.
+ (insn_reservation fpscr_store): Rename to:
+ (fpscr_load). Change to d_lock,nothing,F1*3.
+ (insn_reservation fpscr_store_mem): Rename to:
+ (fpscr_load_mem). Change to d_lock,nothing,(F1+memory),F1*2.
+ (insn_reservation multi): Change to
+ d_lock,(d_lock+f1_1),(f1_1|f1_2)*3,F2.
+ (insn_reservation fp_arith): Change to issue,F01,F2.
+ (insn_reservation fp_div: Change to issue,F01+F3,F2+F3,F3*7,F1+F3,F2.
+ (insn_reservation dp_float): Change to issue,F01,F1+F2,F2.
+ (insn_reservation fp_double_arith): Change to issue,F01,F1+F2,fpu*4,F2.
+ (insn_reservation fp_double_cmp): Change to
+ d_lock,(d_lock+F01),F1+F2,F2.
+ (insn_reservation dp_div): Change to
+ issue,F01+F3,F1+F2+F3,F2+F3,F3*16,F1+F3,(fpu+F3)*2,F2.
+ * sh.c (flow_dependent_p, flow_dependent_p_1): New functions.
+ (sh_adjust_cost, SHcompact): Differentiate between different
+ kinds of dependencies. Drop factor of ten for superscalar.
+ Use new instruction types. Add new exception rules.
+
+ * sh.md (mulhisi3, umulhisi3: Add a REG_EQUAL note.
+
+ * sh.md (mperm_w): Add DONE.
+
+2002-08-27 David Edelsohn <edelsohn@gnu.org>
+
+ * longlong.h: Import current PowerPC defintion from GMP-4.1.
+
+ * config/rs6000/rs6000.h (MIN_UNITS_PER_WORD): Add IN_LIBGCC2 case.
+
+ * config/rs6000/linux64.h (ADJUST_FIELD_ALIGN): Undef before define.
+
+Tue Aug 27 13:53:57 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (MAX_FIXED_MODE_SIZE): Define.
+
+2002-08-27 Gabriel Dos Reis <gdr@soliton.integrable-solutions.net>
+
+ * doc/cpp.texi (Common Predefined Macros): Don't mess with table
+ delimiter.
+
+2002-08-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-common.c (cpp_define_data_format): New function.
+ (cb_register_builtins): Call it.
+
+ * doc/cpp.texi (Common Predefined Macros): Document
+ __TARGET_BITS_ORDER__, __TARGET_BYTES_ORDER__,
+ __TARGET_INT_WORDS_ORDER__, __TARGET_FLOAT_WORDS_ORDER__,
+ __TARGET_FLOAT_FORMAT__, __TARGET_USES_VAX_F_FLOAT__,
+ __TARGET_USES_VAX_D_FLOAT__, __TARGET_USES_VAX_G_FLOAT__,
+ __TARGET_USES_VAX_H_FLOAT__.
+
+2002-08-26 Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (get_super_receiver): If inside a class method
+ of a category, cast the receiver to 'id' before accessing the 'isa'
+ field so that <objc/objc-class.h> is not needed. For NeXT runtime.
+
+2002-08-26 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (s390_function_prologue,
+ s390_function_epilogue): Remove.
+ config/s390/s390.c (s390_function_prologue, s390_function_epilogue,
+ TARGET_ASM_FUNCTION_PROLOGUE, TARGET_ASM_FUNCTION_EPILOGUE): Remove.
+
+ config/s390/s390.c (s390_machine_dependent_recorg): New function.
+ config/s390/s390-protos.h (s390_machine_dependent_reorg): Declare it.
+ config/s390/s390.h (MACHINE_DEPENDENT_REORG): Call it.
+ config/s390/s390.c (s390_split_branches, s390_chunkify_pool): Adapt
+ to being called from MACHINE_DEPENDENT_REORG. Update regs_ever_live.
+
+ config/s390/s390.c (s390_frame_info): Inline save_fprs_p. Always
+ assume BASE_REGISTER and RETURN_REGNUM need to be saved.
+ (s390_emit_prologue): Assume RETURN_REGNUM to be saved iff
+ function is not a leaf function. Use save_gprs and restore_gprs.
+ (s390_emit_epilogue): Likewise.
+ (save_gprs, restore_gprs): New functions.
+ (struct s390_frame): Remove return_reg_saved_p member.
+ (save_fprs_p): Remove.
+ (s390_optimize_prolog): New function.
+ (s390_legitimate_reload_constant): Remove now unnecessary check.
+
+ (s390_function_count): Remove.
+ (s390_output_symbolic_const): Replace s390_function_count by
+ current_function_funcdef_no.
+ (s390_output_constant_pool): Likewise.
+
+ (legitimize_pic_address): Use regs_ever_live to track PIC register
+ instead of current_function_uses_pic_offset_table.
+ (s390_emit_prologue): Likewise.
+ config/s390/s390.md ("call", "call_value"): Likewise.
+
+2002-08-26 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (find_opt): Don't complain about wrong languages
+ here. Return exact matches even for wrong language.
+ (c_common_decode_option): Complain about wrong languages
+ here.
+
+2002-08-24 Stuart Hastings <stuart@apple.com>
+
+ * function.h (struct function): Add flag
+ all_throwers_are_sibcalls.
+ * except.c (set_nothrow_function_flags): Replaces
+ nothrow_function_p. Set new flag.
+ * except.h (set_nothrow_function_flags): Replaces
+ nothrow_function_p.
+ * dwarf2out.c (struct dw_fde_struct): Add flag
+ all_throwers_are_sibcalls.
+ (output_call_frame_info): Test it.
+ (dwarf2out_begin_prologue) Propagate it from cfun to
+ dw_fde_struct.
+ * toplev.c (rest_of_compilation): Update calls to
+ nothrow_function_p.
+
+2002-08-23 Zack Weinberg <zack@codesourcery.com>
+
+ * ggc-page.c (compute_inverse): Short circuit calculation for
+ object sizes larger than half a page.
+
+2002-08-23 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_elf_select_section): Treat
+ DEFAULT_ABI == ABI_AIX like PIC. Test PIC & reloc for readonly
+ default.
+ (rs6000_elf_unique_section): Likewise.
+
+2002-08-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ns32k.c (ns32k_globalize_label): Delete.
+ * ns32k.h (ASM_OUTPUT_LABEL, TARGET_ASM_GLOBALIZE_LABEL): Delete.
+
+2002-08-23 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (output_mi_thunk): Don't determine insns
+ for loading delta with num_insns_constant_wide. Calculate
+ delta_low, delta_high without using a conditional.
+
+2002-08-22 Jason Merrill <jason@redhat.com>
+
+ * c-common.h (RETURN_STMT_EXPR): Rename from RETURN_EXPR.
+ * c-common.def: Adjust.
+ * c-dump.c (c_dump_tree): Adjust.
+ * c-semantics.c (genrtl_return_stmt): Adjust.
+ * c-pretty-print.c (pp_c_statement): Adjust.
+ * tree-inline.c (copy_body_r): Adjust.
+
+2002-08-22 Zack Weinberg <zack@codesourcery.com>
+
+ * ggc-page.c: Avoid division in ggc_set_mark.
+ (DIV_MULT, DIV_SHIFT, OFFSET_TO_BIT, inverse_table,
+ compute_inverse): New.
+ (ggc_set_mark, ggc_marked_p): Use OFFSET_TO_BIT.
+ (init_ggc): Initialize inverse_table.
+
+2002-08-22 Tom Tromey <tromey@redhat.com>
+
+ * doc/install.texi (Configuration): Document --datadir.
+
+2002-08-22 Alexandre Oliva <aoliva@redhat.com>
+
+ * Makefile.in ($(BUILD_PREFIX_1)varray.o): Depend on $(GGC_H).
+
+2002-08-22 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * gengtype-lex.l (ID): Allow underscore as first character.
+
+2002-08-21 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_xcoff_asm_globalize_label): New
+ function.
+ (rs6000_xcoff_asm_named_section): Rename.
+ * config/rs6000/xcoff.h (TARGET_ASM_GLOBALIZE_LABEL): Define.
+
+2002-08-21 Tom Tromey <tromey@redhat.com>
+
+ For PR java/6005 and PR java/7611:
+ * fold-const.c (fold_truthop): Use can_use_bit_fields_p.
+ (fold): Likewise.
+ * langhooks.c (lhd_can_use_bit_fields_p): New function.
+ * langhooks-def.h (lhd_can_use_bit_fields_p): Declare.
+ (LANG_HOOKS_CAN_USE_BIT_FIELDS_P): New define.
+ (LANG_HOOKS_INITIALIZER): Use it.
+ * langhooks.h (struct lang_hooks) [can_use_bit_fields_p]: New
+ field.
+
+2002-08-21 Stan Shebs <shebs@apple.com>
+
+ * tree.c (finish_vector_type): Fix a typo in a comment.
+ * Makefile.in: Fix "the the" stutters in comments.
+ * genautomata.c: Ditto.
+ * ifcvt.c: Ditto.
+ * regrename.c: Ditto.
+ * config/alpha/alpha.c: Ditto.
+ * config/alpha/vms-crt0-64.c: Ditto.
+ * config/alpha/vms-crt0.c: Ditto.
+ * config/alpha/vms-psxcrt0-64.c: Ditto.
+ * config/alpha/vms-psxcrt0.c: Ditto.
+ * config/d30v/d30v.h: Ditto.
+ * config/fr30/fr30.h: Ditto.
+ * config/rs6000/rs6000.c: Ditto.
+ * config/stormy16/stormy16.h: Ditto.
+ * doc/md.texi: Ditto.
+
+2002-08-21 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * cppinit.c (remove_dup_nonsys_dirs): Fix warning and return value.
+
+2002-08-21 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-decl.c (grokdeclarator): Make invalid combinations with long,
+ short, signed or unsigned into hard errors. Fixes PR c/4319.
+ Also make duplicate modifiers such as "short short" into hard
+ errors.
+
+2002-08-21 Andrew Pinski <pinskia@physics.uc.edu>
+ Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * doc/tm.texi (TARGET_ASM_GLOBALIZE_LABEL): Move '@end deftypefn'
+ to the actual end. Add '@end table' and '@table @code'.
+
+2002-08-20 Geoffrey Keating <geoffk@redhat.com>
+
+ * doc/tm.texi (Label Output): Add missing '@end deftypefn'.
+
+ * unroll.c (biv_total_increment): Don't try to compute the total
+ increment for FP BIVs.
+
+2002-08-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alpha.c (TARGET_ASM_GLOBALIZE_LABEL): Define for unicosmk.
+ * alpha/elf.h (ASM_OUTPUT_EXTERNAL_LIBCALL,
+ ASM_OUTPUT_ALIGNED_BSS): Use target hook.
+ * alpha/osf.h (ASM_OUTPUT_WEAK_ALIAS): Likewise.
+ * alpha/unicosmk.h (ASM_GLOBALIZE_LABEL): Delete.
+ * arm/aof.h (ASM_GLOBALIZE_LABEL): Likewise.
+ (GLOBAL_ASM_OP): Define.
+ * arm.c (aof_globalize_label): New function.
+ (TARGET_ASM_GLOBALIZE_LABEL): Define for AOF.
+ * arm/unknown-elf.h (ASM_OUTPUT_ALIGNED_BSS): Use target hook.
+ * c4x.c (c4x_globalize_label): New function.
+ (TARGET_ASM_GLOBALIZE_LABEL): Define for c4x.
+ * c4x.h (ASM_GLOBALIZE_LABEL): Delete.
+ (GLOBAL_ASM_OP): Define.
+ * cris/aout.h (ASM_OUTPUT_EXTERNAL_LIBCALL): Use target hook.
+ * darwin-protos.h (darwin_globalize_label): Declare.
+ * darwin.c (darwin_globalize_label): New function.
+ * darwin.h (ASM_DECLARE_CLASS_REFERENCE): Use target hook.
+ (ASM_GLOBALIZE_LABEL): Delete.
+ (GLOBAL_ASM_OP, TARGET_ASM_GLOBALIZE_LABEL): Define.
+ * dsp16xx.c (asm_output_common): Use target hook.
+ * elfos.h (ASM_OUTPUT_EXTERNAL_LIBCALL): Likewise.
+ * frv.h (ASM_GLOBALIZE_LABEL): Delete.
+ (GLOBAL_ASM_OP): Define.
+ * i370.c (i370_globalize_label): New function.
+ (TARGET_ASM_GLOBALIZE_LABEL): Define for i370.
+ * i370.h (ASM_GLOBALIZE_LABEL): Delete.
+ * i386.c (ix86_asm_file_end): Use target hook.
+ * i386/sco5.h (ASM_GLOBALIZE_LABEL): Don't undef.
+ (ASM_OUTPUT_EXTERNAL_LIBCALL): Use target hook.
+ * ia64.c (ia64_asm_output_external): Likewise.
+ * ia64/sysv4.h: Update comment.
+ * m32r.h (ASM_OUTPUT_ALIGNED_BSS): Use target hook.
+ * mips/elf.h (ASM_OUTPUT_ALIGNED_BSS): Likewise.
+ * mips/iris5.h (ASM_OUTPUT_WEAK_ALIAS): Use target hook.
+ * mips/linux.h (ASM_OUTPUT_ALIGNED_BSS): Likewise.
+ * mips.h (ASM_OUTPUT_ALIGNED_DECL_COMMON): Use target hook.
+ * mmix-protos.h (mmix_asm_globalize_label): Delete.
+ * mmix.c (mmix_asm_globalize_label): Likewise.
+ * mmix.h (ASM_GLOBALIZE_LABEL): Likewise.
+ (GLOBAL_ASM_OP): Define.
+ * ns32k.c (ns32k_globalize_label): New function.
+ * ns32k.h (TARGET_ASM_GLOBALIZE_LABEL): Define for ns32k.
+ (ASM_GLOBALIZE_LABEL): Delete.
+ * pa/pa-linux.h (ASM_GLOBALIZE_LABEL): Don't undef.
+ (TARGET_ASM_GLOBALIZE_LABEL): Undefine.
+ * pa.c (pa_globalize_label): New function.
+ * pa.h (ASM_GLOBALIZE_LABEL): Delete.
+ (TARGET_ASM_GLOBALIZE_LABEL): Define for pa.
+ * rs6000/darwin.h (ASM_GLOBALIZE_LABEL): Delete.
+ (GLOBAL_ASM_OP): Define.
+ (TARGET_ASM_GLOBALIZE_LABEL): Undef.
+ * rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_BSS): Use target hook.
+ * rs6000/xcoff.h (ASM_GLOBALIZE_LABEL): Delete.
+ (GLOBAL_ASM_OP): Define.
+ * v850.c (v850_output_aligned_bss): Use target hook.
+ * vax.c (vms_globalize_label): New function.
+ (TARGET_ASM_GLOBALIZE_LABEL): Define for vms.
+ * vax/vms.h (ASM_GLOBALIZE_LABEL): Delete.
+ (GLOBAL_ASM_OP): Define.
+ * defaults.h (ASM_GLOBALIZE_LABEL): Delete.
+ * doc/tm.texi: Update docs.
+ * dwarf2out.c (default_eh_frame_section, output_die_symbol): Use
+ target hook.
+ * final.c (output_alternate_entry_point): Likewise.
+ * hooks.c (hook_FILEptr_constcharptr_void): New function.
+ * hooks.h (hook_FILEptr_constcharptr_void): Declare.
+ * output.h (assemble_global): Delete.
+ (default_globalize_label): Declare.
+ * system.h (ASM_GLOBALIZE_LABEL): Poison.
+ * target-def.h (TARGET_ASM_GLOBALIZE_LABEL): Define.
+ (TARGET_ASM_OUT): Add TARGET_ASM_GLOBALIZE_LABEL.
+ * target.h (gcc_target): Add globalize_label member.
+ * varasm.c (asm_output_bss, asm_output_aligned_bss,
+ globalize_decl): Use target hook.
+ (assemble_global): Delete.
+ (default_globalize_label): New function.
+
+2002-08-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * dsp16xx.h (dsp16xx_umulhi3_libcall): Delete.
+
+2002-08-20 Devang Patel <dpatel@apple.com>
+ * tree.c (get_qualified_type): Add TYPE_CONTEXT check.
+
+2002-08-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * arc.c (output_shift): Use stdio instead of asm_fprintf.
+ * arm.c (thumb_output_function_prologue): Likewise.
+ * avr.c (print_operand): Likewise.
+ * c4x.c (c4x_print_operand): Likewise.
+ * c4x.h (ASM_OUTPUT_INTERNAL_LABEL, TRAMPOLINE_TEMPLATE,
+ ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Likewise.
+ * cris.c (cris_target_asm_function_prologue,
+ cris_asm_output_mi_thunk): Likewise.
+ * h8300.c (print_operand): Likewise.
+ * h8300.h (ASM_OUTPUT_ADDR_VEC_ELT): Likewise.
+ * ip2k.c (print_operand): Likewise. Fix format specifier.
+ * m68hc11.c (asm_print_register, print_operand,
+ print_operand_address): Use stdio instead of asm_fprintf.
+ (print_operand_address): Fix format specifier.
+ * m68hc11.h (FUNCTION_PROFILER, ASM_OUTPUT_ADDR_DIFF_ELT,
+ ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ALIGN): Use stdio instead of
+ asm_fprintf.
+ * m68k/amix.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * m68k/atari.h (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ * m68k.c (m68k_output_function_prologue,
+ m68k_output_function_epilogue, print_operand): Likewise.
+ * mmix.c (mmix_asm_output_mi_thunk, mmix_asm_weaken_label):
+ Likewise. Fix format specifier.
+ * mn10200.h (ASM_OUTPUT_ADDR_VEC_ELT): Likewise.
+ * mn10300.h (ASM_OUTPUT_ADDR_VEC_ELT): Likewise.
+ * v850.h (ASM_OUTPUT_ADDR_VEC_ELT): Likewise.
+
+2002-08-15 Eric Christopher <echristo@redhat.com>
+ Jeff Knaggs <jknaggs@redhat.com>
+
+ * config.gcc (mipsisa64sr71k-elf): New target.
+ * config/mips/sr71k.md: New file.
+ * config/mips/mips.md: Use it.
+ (rot*): Add sr71k specifics.
+ * config/mips/t-sr71k: New file.
+ * config/mips/mips.h (sr71k): New cpu.
+ (TARGET_SR71K): Use it.
+ (TUNE_SR71K): Ditto.
+ (GENERATE_BRANCHLIKELY): Ditto.
+ (ISA_HAS_MULHI, ISA_HAS_MULS, ISA_HAS_MSAC, ISA_HAS_MACC,
+ ISA_HAS_ROTR_SIISA_HAS_ROTR_DI): Ditto.
+ * config/mips/mips.c (sr71k): New cpu.
+ (mips_use_dfa_pipeline_interface): Use.
+
+2002-08-15 Eric Christopher <echristo@redhat.com>
+ Richard Sandiford <rsandifo@redhat.com>
+ Aldy Hernandez <aldyh@redhat.com>
+ Graham Stott <grahams@redhat.com>
+ Michael Meissner <meissner@redhat.com>
+ Gavin Romig-Koch <gavin@redhat.com>
+ Ken Raeburn <raeburn@cygnus.com>
+ Alexandre Oliva <aoliva@redhat.com>
+
+ * config.gcc (mips64vr-elf): New target.
+ * config/mips/5400.md: New file.
+ * config/mips/5500.md: Ditto.
+ * config/mips/mips.md: Use them.
+ (frsqrt): New.
+ * config/mips/mips.c (vr4111, vr4121, vr4320, vr5400, vr5500): New
+ cpus.
+ (mips_issue_rate): Use them.
+ (mips_use_dfa_pipeline_interface): New function. Use for 5400 and 5500.
+ (TARGET_SCHEDUSE_DFA_PIPELINE_INTERFACE): Define. Use above.
+ * config/mips/mips.h (vr4111, vr4121, vr4320, vr5400, vr5500): New
+ cpus.
+ (TARGET_MIPSx): Use them.
+ (TUNE_MIPSx): Ditto.
+ (GETNATE_MULT3_SI): Ditto.
+ (ISA_HAS_BRANCHLIKELY): Ditto.
+ (ISA_HAS_CONDMOVE): Ditto.
+ (ISA_HAS_NMADD_NMSUB): Ditto.
+ (ISA_HAS_MULHI): New. Ditto.
+ (ISA_HAS_MULS): Ditto.
+ (ISA_HAS_MSAC): Ditto.
+ (ISA_HAS_MACC): Ditto.
+ (ISA_HAS_ROTR_SI): Ditto.
+ (ISA_HAS_ROTR_DI): Ditto.
+ (RTX_COSTS): Use.
+
+2002-08-20 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * cppinit.c (remove_dup_dir): Add head_ptr argument to handle removal
+ at head.
+ (remove_dup_nonsys_dirs): New function.
+ (remove_dup_dirs): Change argument head to head_ptr. Remove warnings.
+ (merge_include_chains): Remove non-system include directories from
+ quote and bracket include chains when they duplicate equivalent system
+ directories.
+ * doc/cpp.texi (-I): Update.
+ * doc/cppopts.texi (-I): Update.
+ * doc/install.texi (--with-local-prefix): Further document usage of
+ this option.
+ * doc/invoke.texi (-I): Update.
+
+2002-08-20 Richard Henderson <rth@redhat.com>
+
+ * expr.c (TARGET_MEM_FUNCTIONS): Transform to boolean.
+ (emit_block_move): Split out subroutines.
+ (emit_block_move_via_movstr): New.
+ (emit_block_move_via_libcall): New. Emit bcopy via normal call also.
+ (emit_block_move_libcall_fn): New. Construct function prototype for
+ bcopy as well.
+ (clear_storage): Split out subroutines.
+ (clear_storage_via_clrstr): New.
+ (clear_storage_via_libcall): New. Emit bzero as a normal call also.
+ (clear_storage_libcall_fn): New. Construct function prototype for
+ bzero as well.
+ (emit_push_insn): Use emit_block_move.
+ (expand_assignment): Booleanize TARGET_MEM_FUNCTIONS.
+ (store_constructor): Likewise.
+
+2002-08-19 Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (building_objc_message_expr): Rename to
+ current_objc_message_selector.
+
+2002-08-19 Ziemowit Laski <zlaski@apple.com>
+
+ * objc/objc-act.c (build_ivar_chain): Remove.
+ (objc_copy_list): Likewise.
+ (get_class_ivars): Inline call to removed build_ivar_chain
+ function. Save off a clean copy of ivars in the CLASS_OWN_IVARS
+ slot; use that slot (rather than CLASS_IVARS) when accessing
+ ivars for base classes. Call copy_list and chainon instead of
+ objc_copy_list.
+ (build_private_template): Call get_class_ivars instead of
+ build_ivar_chain.
+ (start_class): Allocate room for the CLASS_OWN_IVARS slot.
+ (continue_class): Call get_class_ivars instead of
+ build_ivar_chain.
+ (encode_field_decl): Check for DECL_BIT_FIELD_TYPE instead
+ of DECL_BIT_FIELD (which may have been cleared).
+ * objc/objc-act.h (CLASS_OWN_IVARS): New accessor macro.
+
+2002-08-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * genautomata.c (output_translate_vect, output_state_ainsn_table,
+ output_min_issue_delay_table): Mark variable with ATTRIBUTE_UNUSED
+ in output file.
+ (output_internal_min_issue_delay_func): Initialize variable in
+ output file.
+
+2002-08-19 Alexandre Oliva <aoliva@redhat.com>
+
+ * Makefile.in (GCC_FOR_TARGET): Prepend STAGE_CC_WRAPPER.
+ (stage2_build, stage3_build, stage4_build): Likewise, to CC.
+
+2002-08-19 Geoffrey Keating <geoffk@redhat.com>
+ Steve Ellcey <sje@cup.hp.com>
+
+ * machmode.h (SCALAR_INT_MODE_P): New macro to test for
+ scaler integer mode (MODE_INT or MODE_PARTIAL_INT).
+ * explow.c (trunc_int_for_mode): Abort when the mode is not
+ a scaler integer mode.
+ * combine.c (expand_compound_operation): Don't expand Vector
+ or Complex modes into shifts.
+ (expand_field_assignment): Don't do bitwise arithmatic and
+ shifts on Vector or Complex modes.
+ (simplify_comparison): Don't call trunc_int_for_mode
+ for VOIDmode.
+ * recog.c (general_operand): Likewise.
+ (immediate_operand): Likewise.
+ (nonmemory_operand): Likewise.
+
+2002-08-19 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_emit_set_const): Inline
+ multi-instruction SImode constant. Add REG_EQUAL note.
+ * config/rs6000/rs6000.md (movsi splitter): Use
+ rs6000_emit_set_const.
+
+2002-08-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * tree-inline.c (initialize_inlined_parameters): Wrap variable in
+ the macro test controlling its use.
+
+2002-08-18 H.J. Lu (hjl@gnu.org)
+
+ * config.gcc (*-*-linux*): Set extra_parts="crtbegin.o
+ crtbeginS.o crtbeginT.o crtend.o crtendS.o", gas=yes and
+ gnu_ld=yes.
+ (alpha*-*-linux*, cris-*-linux*, i370-*-linux*,
+ i[34567]86-*-linux*, x86_64-*-linux*, mips*-*-linux*,
+ s390-*-linux*, s390x-*-linux*, sparc-*-linux*, sparc64-*-linux*,
+ xtensa-*-linux*): Remove setting extra_parts, gas, and gnu_ld
+ here.
+ (cris-*-linux*): Remove setting thread_file here.
+
+2002-08-18 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/7602
+ * cppinit.c (path_include): Treat the system environment
+ variables as being cxx_aware.
+
+2002-08-17 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * c-decl.c (flexible_array_type_p): New function.
+ (grokdeclarator, finish_struct): Use it.
+ * doc/extend.texi: Document constraints on use of structures with
+ flexible array members.
+
+2002-08-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/t-coff, config/mips/t-elf, config/mips/t-isa3264,
+ config/mips/t-r3900 (MULTILIB_MATCHES): Define.
+ * config/mips/mips.h (ASM_SPEC): Use %(endian_spec).
+
+2002-08-16 Stan Shebs <shebs@apple.com>
+
+ * c-common.c (cb_register_builds): Define __NEXT_RUNTIME__
+ for ObjC with -fnext-runtime.
+ * doc/cpp.texi: Document it.
+
+2002-08-16 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/install.texi (Final installation): Replace links to individual
+ build status pages with a link to a common page that lists them all.
+
+2002-08-16 Sylvain Pion <pion@cs.nyu.edu>
+
+ * doc/invoke.texi: Fix typo.
+
+2002-08-16 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/install.texi (*-ibm-aix*): Explain AIX shared object versioning.
+
+2002-08-16 Andrew Haley <aph@redhat.com>
+
+ * tree-inline.c: Add includes for Java inliner.
+ (remap_decl): Don't handle anonymous types for Java.
+ (remap_block): Add handling for Java trees.
+ (copy_scope_stmt): Conditionalize for non-Java use only.
+ (copy_body_r): Handle Java trees. Add handling for
+ LABELED_BLOCK_EXPR, EXIT_BLOCK_EXPR, Java blocks.
+ (initialize_inlined_parameters): Handle Java trees.
+ (declare_return_variable): Likewise.
+ (expand_call_inline): Handle Java trees.
+ (walk_tree): Likewise.
+ (copy_tree_r): Don't handle SCOPE_STMTs for Java.
+ (add_stmt_to_compound): New function.
+
+2002-08-15 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (LOOSE_WARN): Remove -fno-common.
+ (NOCOMMON_FLAG): New substitution point.
+ (GCC_WARN_CFLAGS): Include it.
+ * configure.in (ac_checking): Set nocommon_flag.
+ (nocommon_flag): New substitution point.
+
+2002-08-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * c-tree.h (skip_evaluation): Move declaration...
+ * c-common.h: ... here.
+ * c-typeck.c (build_external_ref): Don't assemble_external nor
+ mark a tree as used if skip_evaluation is set.
+ * c-parse.in (typeof): New non-terminal to set skip_evaluation
+ around TYPEOF.
+ (typespec_nonreserved_nonattr): Use it.
+
+2002-08-15 Douglas B Rupp <rupp@gnat.com>
+
+ * dbxout.c (dbx_debug_hooks): Update end_prologue, end_epilogue.
+ (xcoff_debug_hooks): Update end_prologue.
+ * debug.c (do_nothing_debug_hooks): Update end_prologue, end_epilogue.
+ * debug.h (end_prologue): Add file arg.
+ (end_epilogue): Add line and file args.
+ (dwarf2out_end_epilogue): Add line and file args.
+ (vmsdbgout_after_prologue): Remove.
+ * dwarf2out.c (dwarf2out_end_epilogue): Add line and file args.
+ (dwarf2_debug_hooks): Update end_prologue.
+ * dwarfout.c (dwarfout_end_epilogue): Add line and file args.
+ (dwarfout_end_prologue): Add file arg.
+ * final.c (vmsdbgout_after_prologue): Remove
+ (final_end_function): Update end_epilogue call.
+ (final_scan_insn): Update end_prologue call.
+ * sdbout.c (sdbout_end_epilogue): Add line and file args.
+ (sdbout_end_prologue): Add file arg.
+ (sdb_debug_hooks): Update end_prologue.
+ (sdb_begin_prologue): Update sdbout_end_prologue call.
+ * vmsdbgout.c (vmsdbg_debug_hooks): Add vmsdbgout_end_prologue,
+ vmsdbgout_end_function.
+ (vmsdbgout_end_prologue): New function renamed from
+ vmsdbgout_after_prologue. Call vmsdbgout_source_line.
+ (vmsdbgout_end_function): New function.
+ (vmsdbgout_end_epilogue): Add line and file args. Call
+ vmsdbgout_source_line.
+ (write_pclines): Write only valid line numbers.
+ (write_srccorr): Don't write source correlation records if 0 lines.
+ * xcoffout.c (xcoffout_end_epilogue): Add line and file args.
+
+2002-08-15 Steve Ellcey <sje@cup.hp.com>
+
+ * gcc/unwind.h (_Unwind_Ptr): Make 64 bits on IA64 HP-UX.
+ (_Unwind_Internal_Ptr): 32 bit version for use in
+ read_encoded_value_with_base.
+ * gcc/unwind-pe.h (read_encoded_value_with_base): Use
+ _Unwind_Internal_Ptr instead of _Unwind_Ptr in order to get the
+ right size.
+
+2002-08-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * loop.c (scan_loop, move_movables, count_one_set): Cast to avoid
+ signed/unsigned warnings.
+
+ * regclass.c (init_reg_sets_1, choose_hard_reg_mode,
+ record_reg_classes): Likewise.
+
+ * reload.c (reload_inner_reg_of_subreg, push_reload,
+ find_reloads_address_1): Likewise.
+
+2002-08-15 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.c (output_mi_thunk): Return to function section on
+ TARGET_ELF.
+
+ * rs6000-c.c (rs6000_cpu_cpp_builtins): Define __PPC405__ if PPC405.
+
+2002-08-15 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (legitimize_address): Optimize loading
+ of large displacements.
+
+2002-08-14 Douglas B Rupp <rupp@gnat.com>
+
+ * config/alpha/alpha-protos.h: Update.
+
+ * config/alpha/alpha.c: (LINKAGE_SYMBOL_REF_P): New macro.
+ (alpha_legitimate_address_p): Test LINKAGE_SYMBOL_REF_P.
+ (alpha_linkage_symbol_p): New static function.
+ (print_operand_address): Print linkage operand.
+
+ (alpha_funcs_num, alpha_funcs_tree, alpha_links_tree): New static
+ variables.
+ (reloc_kind): New enum.
+ (struct alpha_funcs): New struct.
+ (struct alpha_links): Add reloc_kind field. Rename links_kind field.
+
+ (alpha_need_linkage): Rewrite.
+ (alpha_use_linkage): New global function.
+ (alpha_write_linkage): Rewrite and make static.
+ (alpha_write_one_linkage): Rewrite
+
+ (alpha_start_function): Remove procedure descriptor output.
+ (alpha_end_function): Write linkages at end of each function.
+
+ * config/alpha/alpha.md (call_vms, call_value_vms): Rewrite.
+ (call_vms_1, call_value_vms_1): Rewrite.
+
+ * config/alpha/vms.h (ASM_FILE_END): Remove.
+
+2002-08-14 Richard Henderson <rth@redhat.com>
+
+ * ggc-page.c (RTL_SIZE): New.
+ (extra_order_size_table): Add specializations for 2 and 10 rtl slots.
+ * rtl.def (BARRIER, NOTE): Pad to 9 slots.
+
+2002-08-14 Richard Henderson <rth@redhat.com>
+
+ * calls.c: Include target.h.
+ * Makefile.in (calls.o): Update.
+
+ * config/alpha/alpha.c (alpha_end_function): Use targetm.binds_local_p.
+ * config/alpha/alpha.h (FUNCTION_OK_FOR_SIBCALL): Likewise.
+
+2002-08-14 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (LOOSE_WARN): Add -fno-common.
+ * c-common.h (constant_string_class_name): Add missing extern.
+
+2002-08-15 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/7358
+ * c-opts.c (check_deps_environment_vars): Ignore main file
+ for SUNPRO_DEPENDENCIES.
+ * cppfiles.c (stack_include_file): Ignore main file if
+ appropriate.
+ * cpplib.h (struct cpp_options): New member in deps.
+ * doc/cppenv.texi: Update.
+
+2002-08-14 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/7526
+ * cpplib.c (run_directive): Kludge so _Pragma dependency works.
+
+2002-08-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * doc/invoke.texi (-a): Remove documentation.
+ (-fprofile-arcs): Remove reference to -a, -ax options.
+ * doc/gcov.texi (Gcov Data Files): Data might be merged.
+
+2002-08-14 Gabriel Dos Reis <gdr@nerim.net>
+
+ Fix PR/7566
+ * c-semantics.c (genrtl_case_label): Don't (mis)use
+ warning_with_decl.
+
+2002-08-14 Dale Johannesen <dalej@apple.com>
+
+ * explow.c (emit_stack_restore): Emit memory clobbers
+ preceding the stack pop, to prevent the scheduler from
+ moving refs to variable arrays below this pop.
+ * reload1.c (reload): Preserve these clobbers for sched2.
+ * doc/rtl.texi: Document clobber (mem:BLK (scratch)).
+
+2002-08-14 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (c_common_post_options): Correct test.
+
+2002-08-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * m88k.h (ASM_OUTPUT_SOURCE_FILENAME): Fix incorrect argument
+ order in call to fprintf.
+
+2002-08-14 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/sparc/sol2.h (SUBTARGET_EXTRA_SPECS): Define.
+
+2002-08-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * reload.c (find_reloads): Handle constraint letters marked by
+ EXTRA_ADDRESS_CONSTRAINT and EXTRA_MEMORY_CONSTRAINT.
+ (alternative_allows_memconst): Likewise.
+ * reload1.c (maybe_fix_stack_asms): Likewise.
+ * recog.c (asm_operand_ok, preprocess_constraints,
+ constrain_operands): Likewise.
+ * regclass.c (record_operand_costs, record_reg_classes): Likewise.
+ * local-alloc.c (block_alloc, requires_inout): Likewise.
+ * stmt.c (parse_output_constraint, parse_input_constraint): Likewise.
+
+ * defaults.h (EXTRA_MEMORY_CONSTRAINT): Provide a default.
+ (EXTRA_ADDRESS_CONSTRAINT): Likewise.
+ * doc/tm.texi: Document these two new target macros.
+
+ * config/s390/s390.c (s390_expand_plus_operand): Accept already
+ valid operands.
+ (q_constraint): New function.
+ config/s390/s390-protos.h (q_constraint): Declare it.
+ config/s390/s390.h (EXTRA_CONSTRAINT): Use it.
+ (EXTRA_MEMORY_CONSTRAINT): New macro.
+
+ * config/s390/s390.md: Throughout the machine description,
+ replace all instances of the constraint combinations 'Qo'
+ or 'oQ' with simply 'Q'.
+
+2002-08-14 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.h (LINK_SPEC): Support -mrelax.
+ * config/m68hc11/t-m68hc11-gas (LIBGCC2_DEBUG_CFLAGS): Can use -g now.
+ (LIBGCC2_CFLAGS): Compile with -mrelax.
+
+2002-08-14 Stephane Carrez <stcarrez@nerim.fr>
+
+ * doc/invoke.texi: Document -minmax for 68HC12.
+
+ * config/m68hc11/m68hc11.md ("umaxqi3"): Use TARGET_MIN_MAX.
+ ("uminqi3"): Likewise.
+ ("uminhi3", "umaxhi3"): Likewise.
+
+ * config/m68hc11/m68hc11.h (MASK_MIN_MAX): Define.
+ (TARGET_MIN_MAX): Define.
+ (TARGET_SWITCHES): New option -minmax/-mnominmax.
+
+2002-08-14 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/t-m68hc11-gas (LIB1ASMFUNCS): Build __far_trampoline.
+ (MULTILIB_OPTIONS): Must also generate for -mlong-calls.
+
+ * config/m68hc11/larith.asm: Put a mode for ELF ABI flags.
+ (ret, declare, farsym): New gas macros.
+ (__premain, exit, abort, _cleanup, memcpy, memset, ___adddi3,
+ ___subdi3, ___notdi2, __mulhi32, __mulsi3): Use them to use 'rtc'
+ and declare the symbol far when compiled with -mlong-calls.
+ (__far_trampoline): New for 68HC12 trampoline code to invoke a
+ far handler using jsr/bsr.
+
+ * config/m68hc11/m68hc11-crt0.S: Put a mode for ELF ABI flags.
+ (jsr): New macro to transform a 'jsr' into a 'call'.
+
+2002-08-14 Stephane Carrez <stcarrez@nerim.fr>
+
+ * doc/invoke.texi: Document -mlong-calls for 68HC12.
+
+ * config/m68hc11/m68hc11.h (CPP_SPEC): Pass -D__USE_RTC__ when
+ -mlong-calls is specified.
+ (ASM_DECLARE_FUNCTION_NAME): Define to generate .far and .interrupt
+ assembler directives.
+ (TARGET_LONG_CALL, MASK_LONG_CALL): Declare.
+ (TARGET_SWITCHES): Add -mlong-calls options.
+ (current_function_far): Declare.
+
+ * config/m68hc11/m68hc11.c (m68hc11_initial_elimination_offset): Take
+ into account the page register saved on the stack.
+ (m68hc11_override_options): Take into account -mlong-calls option.
+ (m68hc11_asm_file_start): Put a mode for the ELF flags ABI.
+
+ * config/m68hc11/m68hc11.md ("*return_32bit"): Return rtc
+ if the function is going to be in 68HC12 banked memory (-mlong-calls).
+ ("*return_16bit"): Likewise.
+ ("*return_void"): Likewise.
+ ("call", "call_value"): Use call for a far function call.
+
+2002-08-14 Neil Booth <neil@daikokuya.co.uk>
+
+ * toplev.c (parse_options_and_default_flags): Don't call
+ post_options here.
+ (general_init): Initialize GC, pools and tree hash here,
+ instead of lang_independent_init.
+ (lang_independent_init): Rename backend_init.
+ (do_compile): Call post_options hook; exit early if there
+ have been errors after switch processing.
+ (toplev_main): Update.
+
+2002-08-14 Gabriel Dos Reis <gdr@nerim.net>
+
+ * c-pretty-print.h: Guard against multiple inclusion.
+ Robustify macros.
+ (pp_c_attributes): Declare.
+ * c-pretty-print.c (pp_c_attributes): New function.
+
+2002-08-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * m68k.c (m68k_output_function_prologue,
+ m68k_output_function_epilogue): Delete versions for DPX2/MOTOROLA
+ and NEWS/MOTOROLA.
+ * genattrtab.c: Remove dpx2 comment.
+ * libgcc2.c (__enable_execute_stack): Delete versions for
+ NeXT/__MACH__, __convex__, __sysV88__, __pyr__ and
+ sony_news/SYSTYPE_BSD.
+ * longlong.h: Delete code for __a29k__, _AM29K, __clipper__,
+ __gmicro__, __i860__, __NeXT__ and __pyr__.
+ * rtl.h: Remove convex comment.
+ * varasm.c: Likewise.
+
+2002-08-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-opts.c (lang_flags): Const-ify.
+ * ra-build.c (undef_table): Likewise.
+ * ra.c (eliminables): Likewise.
+
+2002-08-14 Gabriel Dos Reis <gdr@nerim.net>
+
+ * tree.h: Guard against multiple inclusion.
+
+2002-08-14 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * reload1.c (reload_cse_simplify): Before checking
+ REG_FUNCTION_VALUE_P, check REG_P.
+
+2002-08-13 Geoffrey Keating <geoffk@redhat.com>
+
+ * Makefile.in (attribs.o): Remove $(OBSTACK_H) dependency.
+
+2002-08-13 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (c_common_init_options): Extra braces needed.
+
+Tue Aug 13 17:40:25 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (sh_init_builtins): Add PARAMS to declaration.
+ (sh_media_init_builtins, sh_expand_builtin): Likewise.
+ (sh_expand_unop_v2sf): Use PARAMS for variable declaration.
+ (sh_expand_binop_v2sf): Likewise.
+ * sh-protos.h (sh_expand_unop_v2sf): Add PARAMS to declaration.
+ (sh_expand_binop_v2sf, sh_cfun_interrupt_handler_p): Likewise.
+ (sh_initialize_trampoline): Likewise.
+
+2002-08-13 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * s390-modes.def [CCL1, CCL2, CCT1, CCT2, CCT3, CCUR, CCSR]: Declare
+ new condition code modes.
+ s390.c (s390_match_ccmode_set): Handle those new CC modes.
+ (s390_select_ccmode): Likewise.
+ (s390_branch_condition_mask): Likewise.
+
+ * s390-protos.h (s390_tm_ccmode): Declare.
+ s390.c (s390_tm_ccmode): New function.
+ (s390_match_ccmode): Allow VOIDmode as REQ_MODE.
+
+ * s390.md ("*cmpdi_tm2"): Rename to "*tmdi_ext".
+ ("*cmpsi_tm2"): Rename to "*tmsi_ext".
+ ("*cmpqi_tm2"): Rename to "*tmqi_ext".
+
+ ("*cmpdi_tm_reg", "*cmpdi_tm_mem", "*cmpsi_tm_reg", "*cmpsi_tm_mem",
+ "*cmphi_tm_sub","*cmphi_cct_0", "*cmpqi_tm", "*cmpqi_tm_sub",
+ "*cmpqi_cct_0", "*tm_0"): Remove, replace by ...
+ ("*tmdi_reg", "*tmsi_reg", "*tmdi_mem", "*tmsi_mem", "*tmhi_mem",
+ "*tmqi_mem", "*tmhi_full", "*tmqi_full"): ... these new patterns.
+
+ ("*ltgr", "*cmpdi_ccs_0_64", "*cmpdi_ccs_0_31", "*ltr", "*icm15",
+ "*icm15_cconly", "*cmpsi_ccs_0", "*icm3", "*cmphi_ccs_0", "*icm1",
+ "*cmpqi_ccs_0"): Remove, replace by ...
+ ("*tstdi_sign", "*tstdi", "*tstdi_cconly", "*tstdi_cconly_31",
+ "*tstsi", "*tstsi_cconly", "*tstsi_cconly2", "*tsthi", "*tsthi_cconly",
+ "*tstqi", "*tstqi_cconly"): ... these new patterns.
+
+ ("*cmpsidi_ccs"): Remove, replace by ...
+ ("*cmpsi_ccs_sign"): ... this new pattern.
+ ("*cmpdi_ccs_sign", "*cmpdi_ccu_zero"): New patterns.
+
+ ("*cmpqi_ccu_0", "*cmpqi_ccu_immed"): Remove, replace by ...
+ ("*cli"): ... this new pattern.
+
+ ("*adddi3_sign", "*adddi3_zero_cc", "*adddi3_zero_cconly",
+ "*adddi3_zero", "*adddi3_cc", "*adddi3_cconly", "*adddi3_cconly2"):
+ New patterns.
+ ("adddi3_64"): Rename to "*adddi3_64".
+ ("adddi3_31"): Replace by insn and splitter "*adddi3_31".
+ ("adddi3"): Adapt expander.
+
+ ("*addsi3_cc"): Allow "general_operand" for operand 2.
+ ("*addsi3_carry1_cc", "*addsi3_carry1_cconly",
+ "*addsi3_carry2_cc", "*addsi3_carry2_cconly"): New patterns.
+
+ ("addhi3", "addqi3"): Remove, replace by ...
+ ("*addsi3_sign", "*addsi3_sub"): ... these new patterns.
+
+ ("*subdi3_sign", "*subdi3_zero_cc", "*subdi3_zero_cconly",
+ "*subdi3_zero", "*subdi3_cc", "*subdi3_cconly"): New patterns.
+ ("subdi3"): Replace by insn and splitter "*subdi3_31".
+ ("subdi3"): New expander.
+
+ ("*subsi3_borrow_cc", "*subsi3_borrow_cconly"): New patterns.
+
+ ("subhi3", "subqi3"): Remove, replace by ...
+ ("*subsi3_sign", "*subsi3_sub"): ... these new patterns.
+
+ ("*muldi3_sign"): New pattern.
+ ("muldi3"): Do not clobber CC.
+ ("mulsi3"): Likewise.
+ ("mulsi_6432"): Likewise.
+
+2002-08-13 Denis Chertykov <denisc@overta.ru>
+
+ * config/avr/avr.md: Call CC_STATUS_INIT in all peepnoles
+ which can change CC0.
+
+Tue Aug 13 14:49:20 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * gcse.c (adjust_libcall_notes): New function.
+ (do_local_cprop): Use it. Add fourth parameter. Changed caller.
+
+2002-08-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ * libgcc2.c (L_bb): Remove unneeded #includes.
+ (__global_counters, __gthreads_active): Remove unused globals.
+ (__bb_exit_func): Merge counts into files rather than appending.
+ * Makefile.in (INTERNAL_CFLAGS): Move COVERAGE_FLAGS from here ...
+ (ALL_CFLAGS): ... to here.
+
+2002-08-13 Denis Chertykov <denisc@overta.ru>
+
+ * config/ip2k/ip2k.c (commands_in_file): Variable removed.
+ (function_epilogue): Don't calculate function size.
+ (ip2k_set_compare): Don't use lookup_const_double.
+ (asm_file_start): Initialization of commands_in_file removed.
+ (asm_file_end): Output of commands_in_file removed.
+
+ * config/ip2k/ip2k.c (CPP_PREDEFINES): Remove definition of
+ __INT_MAX__.
+
+2002-08-13 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (c_common_init_options): Check option array is
+ sorted if checking enabled.
+
+2002-08-13 Gabriel Dos Reis <gdr@nerim.net>
+
+ * c-pretty-print.c: #include "c-tree.h".
+ (pp_c_simple_type_specifier): Tweak.
+ (pp_c_storage_class_specifier): New.
+ (pp_c_function_specifier): Likewise.
+ (pp_c_declaration_specifiers): Likewise.
+ (pp_c_init_declarator): Likewise.
+ (pp_c_declaration): Likewise.
+ (pp_c_direct_declarator): Stub.
+ (pp_c_declarator): Likewise.
+ (pp_c_parameter_declaration): Likewise.
+
+2002-08-13 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (deps_seen, deps_file, deferred_count, deferred_size,
+ handle_deferred_opts, sanitize_cpp_opts, defer_opt,
+ struct deferred_opt): New.
+ (COMMAND_LINE_OPTIONS): Add -M*.
+ (missing_arg): Update.
+ (c_common_decode_option): Handle -M*.
+ (c_common_post_options): Handle -M*. Use sanitize_cpp_opts;
+ don't call cpp_post_options.
+ (c_common_finish, check_deps_environment_vars): Update.
+ * cppfiles.c (stack_include_file, handle_missing_header): Update.
+ * cpphash.h (CPP_PRINT_DEPS): Remove.
+ * cppinit.c: Don't include version.h.
+ (cpp_create_reader): Don't call deps_init. Initialize
+ warn_long_long.
+ (cpp_read_main_file): Init deps if necessary.
+ (cpp_destroy): Conditionally free deps.
+ (cpp_finish): Update.
+ (no_tgt): Remove.
+ (COMMAND_LINE_OPTIONS, cpp_handle_option): Remove -M*.
+ (cpp_post_options): Rename post_options.
+ * cpplib.h (struct cpp_options): Remove some dependency options;
+ move others to a new structure.
+ (cpp_post_options): Remove.
+ (cpp_finish): Comment.
+ * fix-header.c (read_scan_file): Don't call cpp_post_options.
+
+2002-08-12 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/mmix/mmix.md (define_constants): Add MMIX_rR_REGNUM.
+ ("divdi3", "*divdi3_nonknuth", "moddi3", "*moddi3_nonknuth"): Mark
+ MMIX_rR_REGNUM as clobbered.
+ * config/mmix/mmix.h (MMIX_REMAINDER_REGNUM): Use MMIX_rR_REGNUM.
+
+2002-08-12 Gabriel Dos Reis <gdr@nerim.net>
+
+ * diagnostic.h (output_formatted_scalar): Rename from
+ output_formatted_integer.
+ * diagnostic.def: Add DK_DEBUG.
+ * diagnostic.c (output_decimal): Adjust.
+ (output_long_decimal): Likewise.
+ (output_unsigned_decimal): Likewise.
+ (output_octal): Likewise.
+ (output_long_octal): Likewise.
+ (output_hexadecimal): Likewise.
+ (output_long_hexadecimal): Likewise.
+ * c-pretty-print.c (pp_c_type_specifier): New function.
+ (pp_c_specifier_qualifier_list): Likewise.
+ (pp_c_abstract_declarator): Likewise.
+ (pp_c_char): Replace pp_format_integer with pp_format_scalar.
+
+2002-08-12 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/trouble.texi (Disappointments): Add static constructor and
+ destructor dependency information for AIX.
+
+2002-08-12 Neil Booth <neil@daikokuya.co.uk>
+
+ * cpphash.h (struct printer): New from cppmain.c.
+ (cpp_reader): New member.
+ * cppmain.c (struct printer): Move to cpphash.h.
+ (options, print): Remove.
+ (account_for_newlines, print_line, maybe_print_line,
+ cpp_preprocess_file, setup_callbacks, scan_translation_unit,
+ scan_translation_unit_trad, cb_line_change, cb_ident,
+ cb_define, cb_undef, cb_include, cb_file_change, dump_macro,
+ cb_def_pragma): Make reentrant.
+
+2002-08-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * real.c (ieee_64): Always define.
+ (ieee_113): Guard with INTEL_EXTENDED_IEEE_FORMAT == 0.
+ (dec_h): Not used yet, hide it.
+ (emdnorm): Mark parameter in ATTRIBUTE_UNUSED. Guard label with
+ macro controlling use.
+ (TFbignan, TFlittlenan): Guard with INTEL_EXTENDED_IEEE_FORMAT == 0.
+
+Mon Aug 12 12:48:20 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (tablejump): Sign extend the operand.
+ * i386.c (classify_argument): Fix missed case from previous patch.
+
+2002-08-12 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.c (STDC_0_IN_SYSTEM_HEADERS, c_common_init): Move
+ to c-copts.c.
+ (warn_multichar): Die.
+ (cb_register_builtins): Export.
+ * c-common.h (warn_multichar, preprocess_file): Remove.
+ (cb_register_builtins): New.
+ * c-lang.c (c_init): Remove.
+ (LANG_HOOKS_INIT): Use c_objc_common_init.
+ * c-lex.c (init_c_lex): Don't canonicalize filename.
+ * c-opts.c (in_fname, STDC_0_IN_SYSTEM_HEADERS): New.
+ (preprocess_file): Make static. Update for cpplib.
+ (c_common_decode_option): Remove warn_multichar. Use in_fname.
+ (c_common_post_options): Set some cpp options here.
+ (c_common_init): Move from c-common.c.
+ * cppinit.c (cpp_post_options): Don't canonicalize in_fname.
+ * cpplib.h (struct cpp_options): Remove in_fname.
+ (cpp_preprocess_file): Update.
+ * cppmain.c (cpp_preprocess_file): Update for new prototypes.
+
+2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config.gcc (mips*-*-netbsd*): Include ${tm_file}.
+
+2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * i370.h (TARGET_CPU_CPP_BUILTINS): Remove spurious trailing
+ backslash in comment preceeding macro definition.
+ * i370/linux.h (TARGET_OS_CPP_BUILTINS): Likewise.
+ * i370/mvs.h (TARGET_OS_CPP_BUILTINS): Likewise.
+ * i370/oe.h (TARGET_OS_CPP_BUILTINS): Likewise.
+
+2002-08-12 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * expr.c (store_expr): In condition for checking if value is
+ generated in TARGET, move call to expr_size last.
+
+2002-08-11 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.c (c_common_init): Call preprocess_file instead.
+ (c_common_finish): Move to c-opts.c.
+ * c-common.h (preprocess_file): new.
+ * c-opts.c (out_fname, out_stream, deps_append, preprocess_file,
+ check_deps_environment_vars, c_common_finish): New.
+ (c_common_decode_option): Update for out_fname and dependencies.
+ * cppinit.c (init_dependency_output, output_deps): Remove.
+ (cpp_destroy): Update prototype.
+ (cpp_add_dependency_target): New.
+ (cpp_read_main_file): Don't overlay a buffer.
+ (cpp_finish): Take a deps output stream and write deps to it.
+ Return the error count.
+ (cpp_post_options): Don't canonicalize out_fname, or do anything
+ with dependencies.
+ * cpplib.h (struct cpp_options): Remove out_fname and
+ preprocess_only.
+ (cpp_add_dependency_target): New.
+ (cpp_destroy, cpp_finish, cpp_preprocess_file): Update.
+ * cppmain.c (cpp_preprocess_file): Update prototype. Don't
+ set preprocess_only. Don't handle the output stream directly.
+
+2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * dsp16xx.c (print_operand): Fix format specifier.
+ * dsp16xx.md: Avoid automatic aggregate initialization.
+ * frv.h (REG_CLASS_FROM_LETTER): Avoid char as array index.
+ * h8300.c (emit_a_rotate, h8300_adjust_insn_length): Avoid U
+ integer constant modifier.
+ * ip2k.c (ip2k_set_compare): Avoid signed/unsigned warning.
+ * mmix-protos.h (mmix_use_simple_return): Move outside TREE_CODE
+ guards.
+ * sh/netbsd-elf.h (FUNCTION_PROFILER): Fix format specifier.
+ * v850.c (v850_select_section): Mark parameter with
+ ATTRIBUTE_UNUSED.
+ * global.c (global_alloc): Const-ify.
+ * ra-colorize.c (hardregset_to_string): Fix format specifier.
+
+2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * darwin-c.c (darwin_pragma_options): Const-ify.
+ * darwin.c (machopic_non_lazy_ptr_name,
+ machopic_validate_stub_or_non_lazy_ptr): Likewise.
+ (machopic_indirect_data_reference): Wrap variables in macros
+ controlling their use.
+ (machopic_finish, update_non_lazy_ptrs, update_stubs): Const-ify.
+ (machopic_select_section): Use parentheses around && within ||.
+ * i386/darwin.h (ASM_OUTPUT_ALIGN): Avoid ambiguous-else.
+
+2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ip2k.c (mdr_resequence_xy_yx, mdr_propagate_reg_equivs,
+ mdr_try_move_dp_reload, ip2k_check_can_adjust_stack_ref,
+ ip2k_adjust_stack_ref, mdr_try_move_pushes, mdr_try_propagate_clr,
+ ip2k_xexp_not_uses_reg_for_mem, mdr_try_propagate_move,
+ mdr_try_remove_redundant_insns, track_w_reload,
+ mdr_try_wreg_elim): Make function static to match prototype.
+ * mmix.c (mmix_target_asm_function_epilogue): Likewise. Mark
+ parameter with ATTRIBUTE_UNUSED.
+
+2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * arc.c (arc_init): Don't use ISO C style function definitions.
+ * arm.c (count_insns_for_constant, thumb_far_jump_used_p,
+ arm_get_strip_length, arm_strip_name_encoding): Likewise.
+ * avr.h (progmem_section): Likewise.
+ * h8300.c h8300_asm_insn_count): Likewise.
+ * m32r.c (init_idents): Likewise.
+ * s390.c (s390_split_branches, s390_chunkify_pool): Likewise.
+ * sh.c (sh_cfun_interrupt_handler_p): Likewise.
+ * xtensa.c (xtensa_build_va_list): Likewise.
+
+2002-08-11 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.h (enum c_language_kind): Emphasize that clk_c is 0.
+ * c-opts.c (parse_option): Rename find_opt.
+ (set_std_c99): New function.
+ (COMMAND_LINE_OPTIONS): Handle -remap and -o. Remove OPT_std_bad.
+ (missing_arg): Remove OPT_std_bad. Handle -o.
+ (c_common_decode_option): Handle input and output file names,
+ -o and -remap. Clean up -std= handling.
+ * cppinit.c (COMMAND_LINE_OPTIONS): Remove OPT_o and OPT_remap.
+ (cpp_handle_option): Similarly. Don't handle filenames.
+
+Sun Aug 11 14:43:17 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (classify_argument): Fix computing of field's offsets.
+
+2002-08-11 Andreas Jaeger <aj@suse.de>
+
+ PR target/7531:
+ * doc/invoke.texi (i386 and x86-64 Options): Document -mcmodel.
+
+2002-08-10 Ziemowit Laski <zlaski@apple.com>
+
+ * config/alpha/alpha.h (TARGET_CPU_CPP_BUILTINS): Replace
+ reference to clk_objective_c with flag_objc.
+ * config/i386/i386-interix.h (TARGET_OS_CPP_BUILTINS):
+ Likewise.
+ * config/mips/mips.h (TARGET_CPU_CPP_BUILTINS): Likewise.
+
+2002-08-10 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (set_std_cxx98, set_std_c89): New.
+ (COMMAND_LINE_OPTIONS): Move more from cppinit.c.
+ (c_common_decode_option): Handle new switches from cppinit.c.
+ Add -std=gnu++98.
+ * cppinit.c (set_lang): Rename cpp_set_lang. Export.
+ (no_arg, no_num): Remove.
+ (COMMAND_LINE_OPTIONS): Move more to c-opts.c. Drop all lang-
+ switches apart from -lang-objc and lang-asm.
+ (cpp_handle_option): Similarly.
+ * cpplib.h (cpp_set_lang): New.
+ * doc/cppopts.texi, doc/invoke.texi: Document -std=c++98,
+ -std=gnu++98.
+ * objc/lang-specs.h: Remove -ansi.
+
+Sat Aug 10 19:59:43 CEST 2002 Jan Hubicka <jh@suse.cz>
+ Graham Stott
+
+ * cfg.c (redirect_edge_succ_nodup): Avoid overflows due to roundoff
+ errors.
+
+2002-08-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * emit-rtl.c (emit_jump_insn_before, emit_call_insn_before,
+ emit_jump_insn): Fix uninitialized variable.
+ * gcov.c (init_line_info): Likewise.
+ * genautomata.c (transform_3): Add braces around ambiguous
+ else.
+ * ifcvt.c (cond_exec_process_insns): Mark parameter with
+ ATTRIBUTE_UNUSED.
+ * ra-build.c (parts_to_webs_1): Fix uninitialized variable.
+ * regrename.c (copyprop_hardreg_forward): Fix uninitialized
+ variable.
+
+ * gengtype.c (write_gc_structure_fields): Avoid signed/unsigned
+ warnings in output files.
+
+2002-08-09 Ziemowit Laski <zlaski@apple.com>
+
+ * c-common.c (flag_objc): New.
+ * c-common.h (c_language_kind): Get rid of clk_objective_c
+ enum value.
+ (flag_objc): New extern declaration.
+ * c-decl.c (implicitly_declare): Call objc_check_decl
+ instead of maybe_objc_check_decl.
+ (finish_decl): Likewise.
+ (grokfield): Likewise.
+ (finish_struct): Likewise.
+ * c-lang.c (maybe_objc_check_decl): Rename to objc_check_decl.
+ (maybe_objc_comptypes): Rename to objc_comptypes.
+ (maybe_building_objc_message_expr): Rename to
+ objc_message_selector.
+ * c-lex.c (lex_charconst): Remove uses of clk_objective_c,
+ replace with flag_objc as needed.
+ * c-opts.c (c_common_init_options): Likewise.
+ (c_common_decode_option): Likewise.
+ * c-parse.in (init_reswords): Likewise.
+ * c-tree.h (maybe_objc_check_decl): Rename to objc_check_decl.
+ (maybe_objc_comptypes): Rename to objc_comptypes.
+ (maybe_building_objc_message_expr): Rename to
+ objc_message_selector.
+ * c-typeck.c (comptypes): Call objc_comptypes instead of
+ maybe_objc_comptypes, and/or objc_message_selector instead of
+ maybe_building_objc_message_expr.
+ (comp_target_types): Likewise.
+ (convert_for_assignment): Likewise.
+ (warn_for_assignment): Likewise.
+ * cppinit.c (init_builtins): Set __OBJC__ manifest constant
+ independently of those for other languages.
+ * objc/objc-act.c (maybe_objc_comptypes): Delete.
+ (maybe_objc_check_decl): Delete.
+ (maybe_building_objc_message_expr): Rename to
+ objc_message_selector.
+ * objc/objc-lang.c (objc_init_options): Use clk_c instead of
+ clk_objective_c; set flag_objc flag.
+
+2002-08-09 Toshiyasu Morita <toshiyasu.morita@hsa.hitachi.com>
+
+ * ifcvt.c (find_if_case_2): Test correct basic block for size.
+
+2002-08-09 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.md: Add sibcall patterns.
+ * config/rs6000/rs6000.h (FUNCTION_OK_FOR_SIBCALL): Define.
+ * config/rs6000/rs6000.c (rs6000_ra_ever_killed):
+ Rewritten to handle sibcalls.
+ * config/rs6000/rs6000.c (function_ok_for_sibcall): New.
+ * config/rs6000/rs6000-protos.h (function_ok_for_sibcall): New.
+
+2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * profile.c (da_file_name): New static var.
+ (init_branch_prob): Initialize it.
+ (end_branch_prob): Remove da file.
+
+ * Makefile.in (stage1_build): Pass empty COVERAGE_FLAGS.
+ * configure.in (coverage_flags): Default to nothing.
+ * configure: Rebuilt.
+
+2002-08-09 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in (c-opts.o): Update
+ * c-opts.c: Include intl.h.
+ (print_help): Move from cppinit.c. Remove unused options.
+ (COMMAND_LINE_OPTIONS): Move more from cppinit.c.
+ (missing_arg): Complain for switches without an argument.
+ (c_common_decode_option): Reject missing joined arguments.
+ Handle new switches from cppinit.c.
+ * cppinit.c (COMMAND_LINE_OPTIONS): Move some switches to c-opts.c.
+ (cpp_handle_option): Similarly.
+ (print_help): Moved to c-opts.c.
+ * cpplib.h (struct cpp_options): Remove help_only.
+ * gcc.c (cpp_unique_options): Remove -$.
+ * doc/cppopts.texi: Undocument -h.
+
+2002-08-08 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (legitimate_constant_p): UNSPEC_TP is not
+ legitimate constant.
+ (legitimate_pic_operand_p): Neither pic operand.
+ (legitimate_address_p): But legitimate address.
+ (get_thread_pointer): Generate MEM/u instead of CONST around
+ UNSPEC_TP.
+ (print_operand): Remove printing of UNSPEC_TP.
+ (print_operand_address): And print it here.
+
+2002-08-08 Devang Patel <dpatel@apple.com>
+
+ * objc/objc-act.c (build_selector_translation_table): Issue warning,
+ when -Wselector is used,if method for which selector is being
+ created does not exist.
+
+2002-08-08 Stephen Clarke <stephen.clarke@superh.com>
+
+ * config/sh/sh.c (prepare_move_operands): Only call
+ target_reg_operand if TARGET_SHMEDIA.
+
+2002-08-08 Jakub Jelinek <jakub@redhat.com>
+
+ * config/rs6000/rs6000.h, config/rs6000/aix.h,
+ config/rs6000/darwin.h, config/rs6000/linux64.h: Revert last
+ two patches.
+ * config/rs6000/sysv4.h: Likewise, remove #undef ADJUST_FIELD_ALIGN.
+
+2002-08-08 Lars Brinkhoff <lars@nocrew.org>
+ Richard Henderson <rth@redhat.com>
+
+ * emit-rtl.c (gen_rtx_REG): After reload, only return
+ frame_pointer_rtx or hard_frame_pointer_rtx if frame_pointer_needed.
+
+2002-08-08 Jakub Jelinek <jakub@redhat.com>
+
+ * config/rs6000/rs6000-protos.h (rs6000_field_alignment): Remove.
+ * config/rs6000/rs6000.c (rs6000_field_alignment): Move...
+ * config/rs6000/rs6000.h (ADJUST_FIELD_ALIGN): ...inline into the
+ macro.
+
+2002-08-08 Adam Nemet <anemet@lnxw.com>
+
+ * config/arm/arm.c (thumb_unexpanded_epilogue): Stack the PIC
+ register.
+ (thumb_expand_prologue): Likewise.
+ (thumb_output_function_prologue): Likewise.
+ * config/arm/arm.h (THUMB_INITIAL_ELIMINATION_OFFSET): Account for
+ the additional push of the PIC register.
+
+2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * configure.in (enable_coverage): New enable switch.
+ * configure: Rebuilt.
+ * Makefile.in (COVERAGE_FLAGS, coverageexts): New variables.
+ (INTERNAL_CFLAGS): Append COVERAGE_FLAGS.
+ (ALL_FLAGS): Reorder so INTERNAL_CFLAGS comes after CFLAGS.
+ (mostlyclean): Remove coverage files.
+ * doc/install.texi: Document enable_coverage.
+
+ * cp/Make-lang.in (c++.mostlyclean): Remove coverage files.
+ * ada/Make-lang.in (ada.mostlyclean): Remove coverage files.
+ * f/Make-lang.in (f.mostlyclean): Remove coverage files.
+ * java/Make-lang.in (java.mostlyclean): Remove coverage files.
+ * objc/Make-lang.in (objc.mostlyclean): Remove coverage files.
+ * treelang/Make-lang.in (treelang.mostlyclean): Remove coverage
+ files.
+
+2002-08-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (cpp_opts): New.
+ (COMMAND_LINE_OPTIONS): Add switches from cppinit.c.
+ (c_common_decode_options): Handle cpplib switches.
+ (c_common_init_options): Set cpp_opts.
+ * cppinit.c (COMMAND_LINE_OPTIONS): Move some switches to c-opts.c.
+ (cpp_handle_option): Similarly.
+
+2002-08-08 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/aix.h (TARGET_ALTIVEC): Define to 0.
+ (TARGET_ALTIVEC_ABI): Same.
+ (TARGET_ALTIVEC_VRSAVE): Same.
+
+ * config/rs6000/rs6000.c (rs6000_expand_ternop_builtin): Check
+ icode not CODE_FOR_nothing. Change switch to if.
+
+2002-08-08 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.h (ASM_CPU_SPEC): Pass -mpower4 when cpu=power4.
+
+2002-08-08 Jakub Jelinek <jakub@redhat.com>
+
+ * stor-layout.c (place_union_field): For bitfields if
+ PCC_BITFIELD_TYPE_MATTERS and TYPE_USER_ALIGN, set record's
+ TYPE_USER_ALIGN.
+
+2002-08-07 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.c (struct deferred_plabel): Constify name field.
+
+2002-08-07 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppmacro.c (_cpp_builtin_macro_text): Remove unused variable.
+
+2002-08-07 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * configure.in (PREFIX_INCLUDE_DIR): Don't define if prefix and
+ local_prefix are the same.
+ * configure: Rebuilt.
+
+2002-08-07 Jakub Jelinek <jakub@redhat.com>
+ Richard Henderson <rth@redhat.com>
+
+ * stor-layout.c (place_union_field): Apply ADJUST_FIELD_ALIGN
+ to type_align when PCC_BITFIELD_TYPE_MATTERS. Only apply
+ ADJUST_FIELD_ALIGN if not DECL_USER_ALIGN resp. TYPE_USER_ALIGN.
+ (place_field): Likewise.
+ * config/i386/i386.c (x86_field_alignment): Don't check
+ DECL_USER_ALIGN here.
+ * config/rs6000/rs6000.c (rs6000_field_alignment): New.
+ * config/rs6000/rs6000-protos.h (rs6000_field_alignment): New
+ prototype.
+ * config/rs6000/rs6000.h (ADJUST_FIELD_ALIGN): Define.
+ * config/rs6000/aix.h (ADJUST_FIELD_ALIGN): Remove.
+ * config/rs6000/darwin.h (ADJUST_FIELD_ALIGN): Remove.
+ * config/rs6000/linux64.h (ADJUST_FIELD_ALIGN): Remove.
+ * config/rs6000/sysv4.h (ADJUST_FIELD_ALIGN): Remove.
+ * doc/tm.texi (ADJUST_FIELD_ALIGN): Update description.
+
+2002-08-07 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in (c-opts.o, c-common.o, C_AND_OBJC_OBJS): Update.
+ * c-common.c: Don't include tree-inline.h.
+ (c_common_init_options, c_common_post_options): Move to c-opts.c.
+ * c-common.h (c_common_decode_option): New.
+ * c-decl.c (c_decode_option): Remove.
+ * c-lang.c (LANG_HOOKS_DECODE_OPTION): Use c_common_decode_option.
+ * c-opts.c: New file.
+ * c-tree.h (c_decode_option): Remove.
+ * doc/passes.texi: Update.
+ * objc/objc-act.c (objc_decode_option): Remove.
+ * objc/objc-act.h (objc_decode_option): Remove.
+ * objc/ojbc-lang.c (LANG_HOOKS_DECODE_OPTION): Use
+ c_common_decode_option.
+
+2002-08-07 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.md (sunlt_sf, suneq_sf, sunle_sf): Remove
+ dependency on TARGET_DOUBLE_FLOAT.
+
+2002-08-07 Stephen Clarke <stephen.clarke@superh.com>
+
+ * config/sh/lib1funcs.asm (GCC_shcompact_incoming_args): Don't
+ overwrite callee-save registers. Fix comment.
+
+2002-08-06 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.c (override_options): Set MASK_BRANCHLIKELY
+ in target_flags based on ISA, if it was not set on the command
+ line. Warn if MASK_BRANCHLIKLEY is set but the ISA does not
+ support Branch Likely instructions.
+ * config/mips/mips.h (MASK_BRANCHLIKLEY): New macro.
+ (TARGET_BRANCHLIKELY): Likewise.
+ (TARGET_SWITCHES): Add -mbranch-likely and -mno-branch-likely.
+ (GENERATE_BRANCHLIKELY): Use TARGET_BRANCHLIKELY rather than
+ ISA_HAS_BRANCHLIKELY.
+ (ISA_HAS_BRANCHLIKELY): Do not include MIPS16 check.
+ * doc/invoke.texi: Document new MIPS -mbranch-likely and
+ -mno-branch-likely options.
+
+2002-08-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ip2k.c (ip2k_set_compare): Add missing iteration variable.
+
+ * Makefile.in (dummy-conditions.o): Depend on $(HCONFIG_H) not
+ $(GCONFIG_H).
+
+2002-08-06 Aldy Hernandez <aldyh@redhat.com>
+
+ * c-decl.c (duplicate_decls): Error out for incompatible TLS
+ declarations.
+
+ * testsuite/gcc.dg/tls/diag-3.c: New.
+
+2002-08-06 Dale Johannesen <dalej@apple.com>
+
+ * c-common.c (fname_decl): Use line number 0 for
+ __func__, to avoid confusing debuggers.
+
+2002-08-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov.c: Tidy.
+ (struct line_info, struct coverage): New structures.
+ (gcov_file_name, gcov_file): Remove globals.
+ (output_data): Take source file parameter. Fix memory leak. Break
+ up into ...
+ (init_line_info, output_line_info, make_gcov_file_name,
+ accumulate_branch_counts): ... here.
+ (calculate_branch_probs, function_summary): Adjust.
+ (main): Adjust.
+ (function_*): Remove global variables.
+
+2002-08-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * dwarf2out.c: Remove unused macros.
+
+2002-08-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * function.c (TRAMPOLINE_ALIGNMENT): Always defined.
+
+2002-08-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppinit.c (struct lang_flags): Rename trigraphs std.
+ (set_lang): Update.
+ * cpplib.h (struct cpp_options): New member std.
+ * cppmacro.c (_cpp_builtin_macro_text): Use std.
+ (collect_args): Flag whether to swallow a possible future
+ comma pasted with varargs.
+ (replace_args): Use this flag.
+ * doc/cpp.texi: Update varargs extension documentation.
+
+2002-08-06 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/mmintrin.h (__m64): Make the type 64-bit aligned.
+
+2002-08-06 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (x86_field_alignment): Apply min for all MODE_INT
+ and MODE_CLASS_INT modes.
+
+2002-08-06 Jakub Jelinek <jakub@redhat.com>
+
+ * config.gcc (*-*-linux*): Default to --enable-threads=posix if no
+ --{enable,disable}-threads is given to configure.
+ (alpha*-*-linux*, hppa*-*-linux*, i[34567]86-*-linux*,
+ x86_64-*-linux*, ia64*-*-linux*, m68k-*-linux*, mips*-*-linux*,
+ powerpc-*-linux-gnualtivec*, powerpc-*-linux*, s390-*-linux*,
+ s390x-*-linux*, sh-*-linux*, sparc-*-linux*, sparc64-*-linux*):
+ Remove thread_file setting here.
+
+2002-08-06 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/install.texi (Binaries): Update Bull Freeware URL.
+
+2002-08-06 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/gcc.texi (Top): Rename Index to Keyword Index.
+
+2002-08-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov.c (output_data): Round to % to nearest, tweak formatting.
+
+2002-08-05 Jakub Jelinek <jakub@redhat.com>
+
+ * fold-const.c (associate_trees): Only optimize NEGATE_EXPR in one
+ of the operands into MINUS_EXPR if code is PLUS_EXPR.
+
+2002-08-05 Douglas B Rupp <rupp@gnat.com>
+
+ * config.gcc (i[34567]86-*-interix*): Replace interix.o with winnt.o
+ * config/i386/i386-interix.h (TARGET_NOP_FUN_DLLIMPORT,
+ drectve_section): Define.
+ * config/i386/t-interix: Replace interix.o rule with winnt.o.
+ * config/i386/interix.c: Remove.
+
+2002-08-05 Geoffrey Keating <geoffk@redhat.com>
+
+ * attribs.c: Don't include obstack.h.
+ * builtins.c: Likewise.
+ * cfganal.c: Likewise.
+ * cfgbuild.c: Likewise.
+ * cfgcleanup.c: Likewise.
+ * emit-rtl.c: Likewise.
+ * loop.c: Likewise.
+ * stmt.c: Likewise.
+
+ * Makefile.in (s-gtype): Re-add dependency on $(GTFILES).
+
+2002-08-05 Gabriel Dos Reis <gdr@nerim.net>
+
+ * doc/c-tree.texi (Expression trees): Document VA_ARG_EXPR
+
+2002-08-04 Chris Demetriou <cgd@broadcom.com>
+
+ * doc/invoke.texi: Remove duplicated paragraph describing
+ TARGET_SWITCHES.
+
+2002-08-04 Geoffrey Keating <geoffk@redhat.com>
+
+ * Makefile.in (sdbout.o): Doesn't need $(OBSTACK_H).
+ * collect2.h (permanent_obstack): Delete declaration.
+ * collect2.c (permanent_obstack): Delete definition.
+ (main): Don't initialize permanent_obstack. Use xstrdup instead.
+ * expr.c: Don't include obstack.h.
+ (permanent_obstack): Delete declaration.
+ * function.c: Don't include obstack.h.
+ (permanent_obstack): Delete declaration.
+ * integrate.c: Don't include obstack.h.
+ (function_maybepermanent_obstack): Delete declaration.
+ * print-tree.c (debug_tree): Use x*alloc not permalloc.
+ * sdbout.c (gen_fake_label): Use x*alloc not permalloc.
+ * tlink.c (pfgets): Use xstrdup not permanent_obstack.
+ * toplev.c (lang_independent_init): Rename init_obstacks to init_ttree.
+ * tree.h: Rename init_obstacks to init_ttree. Remove declarations
+ of permalloc, expralloc, perm_calloc.
+ * tree.c (permanent_obstack): Delete definition.
+ (init_ttree): Rename from init_obstacks.
+ (permalloc): Delete.
+ (perm_calloc): Delete.
+ (dump_tree_statistics): Don't print information about
+ permanent_obstack.
+ * varasm.c (assemble_start_function): Use xstrdup instead of
+ permalloc/strcpy.
+ (assemble_variable): Likewise.
+ * config/alpha/alpha.c (unicosmk_need_dex): Use xmalloc instead of
+ permalloc.
+ (unicosmk_add_extern): Likewise.
+ * config/c4x/c4x.c (c4x_external_ref): Likewise.
+ (c4x_global_label): Likewise.
+ * config/frv/frv.c (frv_encode_section_info): Likewise.
+ * config/i386/winnt.c (i386_pe_record_external_function): Likewise.
+ (i386_pe_record_exported_symbol): Likewise.
+ * config/mips/mips.c (mips_output_external): Likewise.
+ (mips_output_external_libcall): Likewise.
+ * config/pa/pa.c: (permanent_obstack): Delete declaration.
+ (output_call): Use ggc_strdup instead of allocating on
+ permanent_obstack.
+ * config/romp/romp.c: Include ggc.h.
+ (get_symref): Don't declare permanent_obstack, use ggc_strdup
+ intead of permanent_obstack.
+ * config/rs6000/aix31.h (ASM_OUTPUT_EXTERNAL): Use concat
+ instead of permalloc.
+ * config/rs6000/rs6000.c (rs6000_gen_section_name): Use xmalloc
+ instead of permalloc
+ * config/rs6000/xcoff.h (ASM_OUTPUT_EXTERNAL): Use concat
+ instead of permalloc.
+ * config/vax/vax.c (vms_check_external): Use xmalloc instead of
+ permalloc.
+
+2002-08-04 Bernd Schmidt <bernds@redhat.com>
+
+ Contribute a port developed primarily by Michael Meissner,
+ Catherine Moore, and Richard Sandiford <rsandifo@redhat.com>.
+ * config.gcc: Add frv-elf target.
+ * config/frv/cmovd.c: New file.
+ * config/frv/cmovh.c: New file.
+ * config/frv/cmovw.c: New file.
+ * config/frv/frv-abi.h: New file.
+ * config/frv/frv-asm.h: New file.
+ * config/frv/frv-modes.def: New file.
+ * config/frv/frv-protos.h: New file.
+ * config/frv/frv.c: New file.
+ * config/frv/frv.h: New file.
+ * config/frv/frv.md: New file.
+ * config/frv/frvbegin.c: New file.
+ * config/frv/frvend.c: New file.
+ * config/frv/lib1funcs.asm: New file.
+ * config/frv/media.h: New file.
+ * config/frv/modi.c: New file.
+ * config/frv/t-frv: New file.
+ * config/frv/uitod.c: New file.
+ * config/frv/uitof.c: New file.
+ * config/frv/ulltod.c: New file.
+ * config/frv/ulltof.c: New file.
+ * config/frv/umodi.c: New file.
+ * config/frv/xm-frv.h: New file.
+
+ * config/frv/media.h: Removed again.
+
+2002-08-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov.c (bb_file_time): New static variable.
+ (object_directory): May also be object file.
+ (preserve_paths): New static variable.
+ (print_usage): Adjust.
+ (options): Adjust.
+ (process_args): Adjust.
+ (open_files): Simplify. Cope when OBJECT_DIRECTORY is an object
+ file. Find modification date on bb file.
+ (read_profile): Don't rewind a NULL file.
+ (format_hwint): New static function.
+ (function_summary): Use format_hwint.
+ (output_data): SOURCE_FILE_NAME is never relative to
+ OBJECT_DIRECTORY. Use format_hwint. Adjust gcov file name
+ mangling. Adjust output format to make it more machine readable.
+ * doc/gcov.texi: Document & clarify semantics.
+
+2002-08-04 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/include/gcc-common.texi (version-GCC): Increase to 3.3.
+
+2002-08-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcc.c (cc1_options): Pass output file as auxbase when
+ appropriate.
+ * profile.c (init_branch_prob): FILENAME has already had ending
+ stripped.
+ * final.c (end_final): Likewise.
+ * toplev.c (aux_base_name): New global.
+ (compile_file): Pass aux_base_name to init init_branch_prob and
+ end_final.
+ (independent_decode_option, case 'a'): New auxinfo options.
+ (case 'd'): Protect against mising basename.
+ (do_compile): Initialize aux_base_name.
+ * toplev.h (aux_base_name): New global.
+ * doc/invoke.texi: Adjust documentation.
+
+2002-08-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * config/i386/i386.c (x86_field_alignment): Remove duplicate test
+ of TARGET_ALIGN_DOUBLE.
+
+2002-08-04 Gabriel Dos Reis <gdr@nerim.net>
+
+ * diagnostic.c (inform): New function.
+ * diagnostic.h (inform): Declare.
+
+2002-08-03 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (movsi_internal1): Add nop mnemonic.
+ (movhi_internal): Same.
+ (movqi_internal): Same.
+ (movdi_internal64): Same.
+
+ * config/rs6000/t-ppccomm (MULTILIB_MATCHES_FLOAT): Add mcpu=405.
+
+ * config/rs6000/xcoff.h (SKIP_ASM_OP): Define.
+ (ASM_OUTPUT_SKIP): Use it. SIZE unsigned.
+ (COMMON_ASM_OP): Define.
+ (ASM_OUTPUT_ALIGNED_COMMON): Use it. SIZE unsigned.
+ Use ALIGN parameter.
+ (LOCAL_COMMON_ASM_OP): Define.
+ (ASM_OUTPUT_LOCAL): Use it. SIZE unsigned.
+
+2002-08-03 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def: Define new builtin functions exp, expf, expl,
+ log, logf and logl (and their __builtin_* variants).
+ * optabs.h (enum optab_index): Add new OTI_exp and OTI_log.
+ Define exp_optab and log_optab.
+ * optabs.c (init_optans): Initialize exp_optab and log_optab.
+ * genopinit.c (optabs): Implement exp_optab and log_optab
+ using exp?f2 and log?f2 patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_EXP*
+ and BUILT_IN_LOG* using exp_optab and log_optab respectively.
+ (expand_builtin): Ignore the new builtins (and all cos and
+ sin variants) when not optimizing. Expand new builtins via
+ expand_builtin_mathfn when flag_unsafe_math_optimizations.
+
+ * doc/extend.texi: Document new exp and log builtins.
+ * doc/md.texi: Document new exp?f2 and log?f2 patterns
+ (and previously undocumented cos?f2 and sin?f2 patterns).
+
+2002-08-03 Jason Merrill <jason@redhat.com>
+
+ * explow.c (int_expr_size): New fn.
+ * expr.c (expand_expr) [CONSTRUCTOR]: Use it.
+ * expr.h: Declare it.
+
+2002-08-02 Krister Walfridsson <cato@df.lth.se>
+
+ * Makefile.in (gengtype-lex.o, gengtype-yacc.o): Add path to
+ gengtype-* dependencies.
+
+2002-08-02 Eric Christopher <echristo@redhat.com>
+
+ * config.gcc (mips*-*-linux*): Fix ordering of tm_file.
+ * config/mips/mips.h (READONLY_DATA_SECTION_ASM_OP): Change
+ #ifndef to #undef.
+ (TARGET_MEM_FUNCTIONS): Define instead of define to 1.
+
+2002-08-02 David Edelsohn <edelsohn@gnu.org>
+
+ PR optimize/7067
+ * config/rs6000/rs6000.h (RTX_COSTS): Artificially make MULT
+ small if optimizing for size.
+
+2002-08-02 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in (FORBUILD): Use $build_alias.
+ * configure: Regenerated.
+
+2002-08-02 Richard Sandiford <rsandifo@redhat.com>
+
+ * config.gcc: Don't include mips/abi64.h in $tm_file.
+ * hard-reg-set.h (call_really_used_regs): Declare.
+ * config/mips/abi64.h: Remove file.
+ * config/mips/linux.h,
+ * config/mips/iris6.h: Don't include it.
+ * config/mips/mips-protos.h (mips_conditional_register_usage): Declare.
+ * config/mips/mips.h (CONDITIONAL_REGISTER_USAGE): Use it.
+ (REG_PARM_STACK_SPACE, STACK_BOUNDARY, STRICT_ARGUMENT_NAMING,
+ FUNCTION_ARG_PASS_BY_REFERENCE, FUNCTION_ARG_PADDING,
+ FUNCTION_ARG_CALLEE_COPIES, MUST_PASS_IN_STACK, MIPS_STACK_ALIGN):
+ Bring across definitions from abi64.h.
+ (GP_ARG_LAST, FP_ARG_LAST): Use MAX_ARGS_IN_REGISTERS.
+ (BIGGEST_MAX_ARGS_IN_REGISTERS): New.
+ (struct mips_args): Use it.
+ * config/mips/mips.c (mips_conditional_register_usage): Define.
+
+2002-08-02 Jason Merrill <jason@redhat.com>
+
+ * langhooks-def.h (LANG_HOOKS_EXPR_SIZE): New macro.
+ * langhooks.c (lhd_expr_size): Define default.
+ * langhooks.h (struct lang_hooks): Add expr_size.
+ * explow.c (expr_size): Call it.
+ * expr.c (store_expr): Don't copy an expression of size zero.
+ (expand_expr) [CONSTRUCTOR]: Use expr_size to calculate how much
+ to store.
+ * Makefile.in (builtins.o): Depend on langhooks.h.
+
+2002-08-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (ra-debug.o): Depend on $(TM_P_H).
+ * ra-debug.c: Include "tm_p.h".
+ * ra-rewrite.c (is_partly_live_1): Change return type to bool.
+
+2002-08-02 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * simplify-rtx.c (simplify_binary_operation): x * 1 is allowed
+ when not honoring signalling NaNs.
+ (simplify_ternary_operation): a == b has a definite value
+ when not honoring NaNs.
+
+2002-08-02 Jason Merrill <jason@redhat.com>
+
+ * gdbinit.in (pct): New macro.
+
+2002-08-01 Stan Shebs <shebs@apple.com>
+ Andreas Tobler <toa@pop.agri.ch>
+
+ * ginclude/stddef.h (_BSD_SIZE_T_DEFINED_): Define if not defined,
+ plays nice with Darwin headers.
+ (_BSD_RUNE_T_DEFINED_): Likewise.
+
+2002-08-01 Zack Weinberg <zack@codesourcery.com>
+
+ * c-common.c (c_common_init): -Wtraditional also implies -Wlong-long.
+ * cppinit.c (cpp_post_options): Likewise.
+
+ * cppexp.c (cpp_classify_number): Suppress -Wtraditional
+ warning about 'LL' suffix (but not 'ULL' etc) when
+ -Wno-long-long is in effect.
+
+ * cppmacro.c (_cpp_builtin_macro_text) [BT_TIME, BT_DATE]:
+ Check for failing time()/localtime(), issue a warning, and
+ make __TIME__ and __DATE__ expand to fallback strings.
+
+ * doc/cpp.texi, doc/extend.texi: Document behavior of __DATE__
+ and __TIME__ when the date and time cannot be determined.
+
+2002-08-02 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (output_cbranch): Hint differently for power4.
+
+2002-08-01 Daniel Jacobowitz <drow@mvista.com>
+
+ * Makefile.in ($(BUILD_PREFIX_1)ggc-none.o): Use $(GGC_H).
+
+2002-08-01 Chris Demetriou <cgd@broadcom.com>
+
+ * config.gcc (mipsisa64sb1-*-elf*): New configuration.
+ (mipsisa64sb1el-*-elf*): Likewise.
+ * config/mips/mips.c (mips_cpu_info_table): Add sb1.
+ * config/mips/mips.h (processor_type): Add PROCESSOR_SB1.
+ (TARGET_SB1, TUNE_SB1): New macros.
+ * doc/invoke.texi: Add sb1 to documentation for MIPS -march and
+ -mtune flags.
+
+2002-08-01 David Edelsohn <edelsohn@gnu.org>
+
+ * varasm.c (asm_emit_uninitialized): Return false if global BSS
+ and ASM_EMIT_BSS not supported by target.
+ (assemble_variable): Do not duplicate uninitialized logic.
+ Fall through if asm_emit_uninitialized failed.
+
+2002-08-01 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.h (BRANCH_LIKELY_P): Remove unused macro.
+
+2002-08-02 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/linux64.h (DBX_OUTPUT_BRAC): Define.
+ (DBX_OUTPUT_LBRAC, DBX_OUTPUT_RBRAC): Define.
+
+ * config/rs6000/rs6000.c (output_toc): Don't use lshift_double when
+ HOST_BITS_PER_WIDE_INT == 64.
+
+2002-08-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * df.c (df_insn_table_realloc): Change parameter to unsigned.
+ * optabs.c (expand_binop): Make variable unsigned.
+ * simplify-rtx.c (simplify_subreg): Likewise.
+ * unroll.c (unroll_loop): Cast to avoid signed/unsigned warnings.
+
+2002-08-01 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * c-common.c (cb_register_builtins): Always define __GXX_ABI_VERSION.
+
+2002-08-01 Richard Henderson <rth@redhat.com>
+
+ * toplev.c (parse_options_and_default_flags): Don't set
+ flag_reorder_blocks for -Os.
+
+ * config/avr/avr.c (avr_optimization_options): Remove.
+ * config/avr/avr.h (OPTIMIZATION_OPTIONS): Remove.
+ * config/m68hc11/m68hc11.c (m68hc11_optimization_options): Remove.
+ * config/m68hc11/m68hc11.h (OPTIMIZATION_OPTIONS): Remove.
+
+2002-08-01 H.J. Lu <hjl@gnu.org>
+ Richard Henderson <rth@redhat.com>
+
+ * output.h (DECL_READONLY_SECTION): Remove.
+ (decl_readonly_section): Declare.
+ * varasm.c (decl_readonly_section): New.
+ (default_section_type_flags, default_select_section): Use it.
+ * config/arm/pe.c (arm_pe_unique_section): Likewise.
+ * config/i386/interix.c (i386_pe_unique_section): Likewise.
+ * config/i386/winnt.c (i386_pe_unique_section): Likewise.
+ * config/mcore/mcore.c (mcore_unique_section): Likewise.
+ * config/mips/mips.c (mips_unique_section): Likewise.
+
+2002-08-01 Richard Henderson <rth@redhat.com>
+
+ * integrate.c (copy_rtx_and_substitute): Squash MEM_EXPR when it
+ refers to a subroutine parameter.
+
+2002-08-01 Jakub Jelinek <jakub@redhat.com>
+
+ * varasm.c (assemble_visibility): Strip name encoding.
+
+2002-08-01 Ian Dall <ian@sibyl.beware.dropbear.id.au>
+
+ * config/ns32k/ns32k.h (TARGET_IEEE_COMPARE): Correct earlier patch.
+ (RETURN_ADDR_RTX): Cannot determine return address for FRAME > 0
+ when there is no frame pointer.
+ (INITIAL_FRAME_POINTER_OFFSET): Count stack space for saved fp
+ registers properly.
+ * config/ns32k/__unorddf2.c: New file.
+ * config/ns32k/__unordsf2.c: New file.
+ * config/ns32k/t-ns32k: New file.
+ * config.gcc (ns32k-*-netbsd*): Use it.
+
+2002-08-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.h (SPU_CONST_OFFSET_OK): Change to 0xff.
+
+2002-08-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.c (__GXX_ABI_VERSION): Correct spelling.
+
+2002-08-01 Benjamin Kosnik <bkoz@redhat.com>
+
+ * c-common.c (cb_register_builtins): Set __GXX_ABI_VERSION__ to 102.
+
+2002-08-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md: Add [!]TARGET_MIPS16 to sgtu conditions.
+
+2002-08-01 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcse.c (expr_hash_table_size, n_exprs, set_hash_table_size,
+ n_sets): Removed.
+ (expr_hash_table, set_hash_table): Type changed to ...
+ (struct hash_table): New type.
+ (hash_scan_insn, hash_scan_set, hash_scan_clobber, hash_scan_call,
+ insert_expr_in_table, insert_set_in_table, compute_hash_table,
+ dump_hash_table, lookup_expr, lookup_set, compute_local_properties,
+ compute_ae_gen, compute_ae_kill): Modified to pass the table explicitly.
+ (alloc_set_hash_table, alloc_expr_hash_table): Merged to ...
+ (alloc_hash_table): New.
+ (free_set_hash_table, free_expr_hash_table): Merged to ...
+ (free_hash_table): New.
+ (compute_set_hash_table, compute_expr_hash_table): Merged to ...
+ (compute_hash_table_work): New.
+ (classic_gcse, one_classic_gcse_pass, compute_cprop_data,
+ find_avail_set, one_cprop_pass, find_bypass_set, compute_pre_data,
+ pre_edge_insert, pre_insert_copies, pre_delete, pre_gcse,
+ one_pre_gcse_pass, compute_transpout, compute_code_hoist_vbeinout,
+ hoist_code, one_code_hoisting_pass,
+ trim_ld_motion_mems): Altered due to changed type of hash tables.
+
+2002-08-01 Zack Weinberg <zack@codesourcery.com>
+
+ * final.c (output_alternate_entry_point):
+ If ASM_OUTPUT_TYPE_DIRECTIVE is defined, use it.
+
+2002-08-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * objc/objc-act.c (encode_complete_bitfield): Add prototype and
+ avoid ISO C style function definition.
+
+ * expr.c (expand_assignment): Delete unused variable.
+
+2002-08-01 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * c-common.c (cb_register_builtins): Set
+ __FINITE_MATH_ONLY__ to 1 if -ffinite-math-only
+ is given, and to 0 otherwise.
+ * combine.c (simplify_if_then_else): HONOR_NANS
+ implies FLOAT_MODE_P.
+
+2002-08-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppinit.c (COMMAND_LINE_OPTIONS): Remove OPT_dollar.
+ (cpp_handle_option): Don't handle it.
+ (print_help): Update.
+ * doc/cppopts.texi: Update.
+
+2002-08-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.c (cb_register_builtins): If C++, define
+ __EXCEPTIONS, __DEPRECATED and __GXX_ABI_VERSION as appropriate.
+ * gcc.c (cpp_unique_options): Remove __GXX_ABI_VERSION.
+cp:
+ * lang-specs.h: Simplify in accordance with new code in
+ c-common.c.
+
+2002-08-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.c: Define all C/ObjC/C++ warning and flag variables.
+ * c-common.h: Declare all C/ObjC/C++ warning and flag variables.
+ * c-decl.c: Move all warning and flag variables to c-common.c.
+ * c-format.c: Move all warning variables to c-common.c.
+ * c-tree.h: Move all warning and flag declarations to c-common.h.
+ * objc/objc-act.c: Move all warning variables to c-common.c.
+ (flag_warn_protocol): Rename warn_protocol.
+
+2002-07-31 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa-linux.h (GLOBAL_ASM_OP): Fix typo.
+
+2002-07-31 Graham Stott <graham.stott@btinternet.com>
+
+ * config/stormy16/stormy16.h (BSS_SECTION_ASM_OP): Add missing
+ .section prefix.
+
+2002-07-31 Stan Shebs <shebs@apple.com>
+
+ * config.gcc (i[34567]86-*-darwin*): New configuration.
+ * config/darwin.h (TARGET_ENCODE_SECTION_INFO): Undefine before
+ defining.
+ (TARGET_ENCODE_SECTION_INFO): Ditto.
+ (ASM_PREFERRED_EH_DATA_FORMAT): Ditto.
+ * config/darwin.c (machopic_indirect_data_reference): Remove
+ setting of RTX_UNCHANGING_P.
+ (machopic_legitimize_pic_address): Move RTX_UNCHANGING_P up so as
+ not to be applied to sums.
+ * config/i386/t-darwin: New file.
+ * config/i386/darwin.h: New file.
+ * config/i386/i386.h (TARGET_MACHO): Add default definition.
+ * config/i386/i386.md (tablejump): Add TARGET_MACHO case.
+ * config/i386/i386.c (output_set_got): For Mach-O, output Mach-O
+ label and not the GOT add.
+ (constant_address_p): For Mach-O, seeing a CONST is enough.
+ (legitimate_pic_address_disp_p): Add a Mach-O case.
+ (legitimate_address_p): Also test machopic_operand_p if Mach-O.
+ (legitimize_pic_address): Use generic Mach-O code to legitimize.
+ (output_pic_addr_const): Suppress @PLT if Mach-O, and parens
+ if outputting a difference.
+ (ix86_output_addr_diff_elt): Add Mach-O case.
+ (ix86_expand_move): Similarly.
+ (ix86_expand_call): Similarly.
+ (current_machopic_label_num): New global.
+ (machopic_output_stub): New function.
+ (ix86_value_regno): New function.
+ (ix86_function_value): Use it instead of VALUE_REGNO.
+ (ix86_libcall_value): Ditto.
+ * config/i386/unix.h (VALUE_REGNO): Remove.
+
+2002-07-31 Graham Stott <grahas@btinternet.com>
+
+ * config/rs6000/rs6000.c(rs6000_hash_constant): Fix
+ hash for LABEL_REF's.
+
+2002-07-31 Graham Stott <grahams@btinternet.com>
+
+ * config/rs6000/rs6000.c (spe_init_builtins,
+ altivec_init_builtins, rs6000_common_init_builtins):
+ Replace ANSI with K&R function def.
+
+2002-07-31 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.c (validate_condition_mode): Test flag_finite_math_only
+ for CCFPmode.
+
+2002-07-31 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/crtn.asm: Don't use __mips16 to determine the
+ return-address offset. Define RA to a suitable temporary
+ register for the return address.
+
+2002-07-31 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (eh_set_lr_si, eh_set_lr_di): Change
+ constraints to 'd'.
+
+2002-07-30 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/elf.h (STARTFILE_SPEC): Define differently if
+ default ABI is MEABI. (Undoes incorrect change in Eric Christopher's
+ patch on 2002-07-29.)
+ * config/mips/elf64.h (STARTFILE_SPEC): Likewise.
+
+2002-07-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alpha.h, arc.h, arm/aout.h, avr.h, cris.h, d30v.h, dsp16xx.h,
+ fr30.h, h8300.h, i370.h, i386/sco5.h, i386/unix.h, i960.h, ia64.h,
+ ip2k.h, m32r.h, mcore.h, mips.h, mn10200.h, mn10300.h, ns32k.h,
+ openbsd.h, pa/pa-linux.h, pdp11.h, romp.h, rs6000/sysv4.h,
+ s390/linux.h, sh.h, sparc.h, stormy16.h, v850.h, vax.h, xtensa.h:
+ (ASM_GLOBALIZE_LABEL): Delete.
+ (GLOBAL_ASM_OP): Define.
+
+ * m68hc11.h, m68k.h, m88k.h (ASM_GLOBALIZE_LABEL): Delete.
+
+ * defaults.h (ASM_GLOBALIZE_LABEL): Provide a default.
+ * doc/tm.texi (ASM_GLOBALIZE_LABEL): Update docs.
+
+2002-07-30 Geoffrey Keating <geoffk@redhat.com>
+
+ * doc/extend.texi (Hints implementation): Document that GCC
+ mostly ignores `register'.
+
+2002-07-30 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * flags.h: Declare flag_finite_math_only.
+ Use it in definition of HONOR_NANS and
+ HONOR_INFINITIES.
+ * c-common.c (cb_register_builtins): Emit
+ __FINITE_MATH_ONLY__ when flag_finite_math_only
+ is set.
+ * combine.c (simplify_if_then_else): If
+ flag_finite_math_only is set, a == b has a
+ definite value.
+ * toplev.c: Initialize flag_finite_math_only.
+ (set_flags_fast_math): Set it on -ffast-math.
+ (flag_fast_math_set_p): Test it.
+ * doc/invoke.texi: Document -ffinite-math-only.
+
+2002-07-30 Richard Henderson <rth@redhat.com>
+
+ * ifcvt.c (noce_get_alt_condition): Use reg_overlap_mentioned_p.
+ (noce_process_if_block): Likewise.
+
+2002-07-30 Bernd Schmidt <bernds@redhat.com>
+
+ * ifcvt.c (cond_exec_process_if_block): Fix a merging error.
+ Bail out early if false_expr is NULL and we'd crash due to this.
+ * genemit.c (gen_expand): Recognize return insns even if the return
+ appears in a parallel.
+ * libgcc2.c: Expand macro DECLARE_LIBRARY_RENAMES if it is defined.
+ * config/fp-bit.c: Likewise.
+ * doc/tm.texi: Document it.
+
+2002-07-30 David Edelsohn <edelsohn@gnu.org>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * rs6000.c (rs6000_expand_unop_builtin): Check icode not
+ CODE_FOR_nothing. Change switch to if.
+ (rs6000_expand_binop_builtin): Same.
+ (rs6000_expand_builtin): Expand builtin if target support enabled.
+ (rs6000_init_builtins): Init builtin if target support enabled.
+ (rs6000_common_init_builtins): Check icode not CODE_FOR_nothing.
+
+2002-07-30 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * gcc.c (cpp_unique_options): Define __GXX_ABI_VERSION, bump it to 101.
+
+2002-07-30 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (SUBTARGET_ASM_DEBUGGING_SPEC): Fix typo.
+
+Tue Jul 30 18:31:31 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (cond_delay_slot): New attribute.
+ (cbranch delay): Use it for anulled-true case.
+ (stuff_delay_slot): New pattern.
+ * sh.c (print_operand, case '.'): Don't print .s / /s fore zero-length
+ delay slot insn.
+ (gen_far_branch): Emit stuff_delay_slot pattern.
+
+Tue Jul 30 11:21:44 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * unroll.c (copy_loop_body): Don't copy NOTE_INSN_LOOP_CONT.
+
+2002-07-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c: Fix comment typos.
+ * gcse.c: Likewise.
+ * reload1.c: Likewise.
+
+2002-07-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.md: Disallow CCEQ compare with crnor/crnot
+ for TARGET_SPE.
+
+2002-07-30 Gabriel Dos Reis <gdr@nerim.net>
+
+ * c-pretty-print.h (pp_c_statement): Declare.
+ * c-pretty-print.c (pp_c_postfix_expression): #if 0 support for SRCLOC.
+ (pp_c_statement): Define.
+
+2002-07-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alpha.h, arc.h, arm/aout.h, avr.h, c4x.h, cris.h, d30v.h,
+ darwin.h, dsp16xx.h, fr30.h, h8300.h, i370.h, i386.h, i960.h,
+ ip2k.h, m32r.h, m68hc11.h, m68k.h, m88k.h, mcore.h, mips.h,
+ mn10200.h, mn10300.h, ns32k.h, pa/pa-linux.h, pdp11.h, romp.h,
+ rs6000/sysv4.h, s390/linux.h, sh.h, sparc.h, stormy16.h,
+ v850.h, vax.h, xtensa.h (ASM_OUTPUT_LABEL): Delete definition.
+
+ * defaults.h (ASM_OUTPUT_LABEL): Provide a default.
+ * doc/tm.texi (ASM_OUTPUT_LABEL): Update docs.
+
+2002-07-30 Gabriel Dos Reis <gdr@nerim.net>
+
+ * c-pretty-print.c (pp_c_primary_expression): Handle STMT_EXPR.
+ (pp_c_postfix_expression): Handle ARROW_EXPR, FFS_EXPR,
+ COMPOUND_LITERAL_EXPR, VA_ARG_EXPR.
+ (pp_c_expression): Update.
+
+2002-07-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alpha/vms-cc.c (preprocess_args, main): Use xstrdup and/or
+ concat in lieu of xmalloc/strcpy/memcpy/sprintf.
+ * alpha/vms-ld.c (main): Likewise.
+ * dsp16xx.c (double_reg_to_memory): Likewise.
+ * mcore.c (mcore_expand_prolog): Likewise.
+ * cppfiles.c (read_name_map): Likewise.
+ * gensupport.c (process_rtx, identify_predicable_attribute,
+ alter_test_for_insn): Likewise.
+ * vmsdbgout.c (write_rtnbeg, vmsdbgout_init): Likewise.
+
+2002-07-29 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin): Change the default behavior to
+ only issue an error if the builtin function doesn't have a
+ fallback library call. Remove several cases handled by the
+ new default.
+
+2002-07-29 John David Anglin <dave@hiauly1.hia.nrc>
+
+ * real.c (ieee_24, ieee_53, ieee_64, ieee_113): Define only if the
+ floating point format of the target is IEEE.
+ * (dec_f, dec_d, dec_g, dec_h): Define only if the floating point
+ format of the target is DEC.
+
+2002-07-29 Richard Henderson <rth@redhat.com>
+
+ * unroll.c (verify_addresses): Remove.
+ (find_splittable_givs): Never split DEST_ADDR givs.
+
+2002-07-29 Geoffrey Keating <geoffk@redhat.com>
+
+ * doc/gty.texi (GGC Roots): Clarify that the list of syntaxes
+ is exhaustive.
+ (Files): Improve documentation on generated source files.
+
+ * doc/extend.texi (Translation implementation): Document what
+ diagnostics look like.
+ (Identifiers implementation): Document that there's normally no
+ limit on identifier names.
+ (Integers implementation): Document two's complement.
+ (Hints implementation): Document that GCC honors 'inline', mostly.
+ (Preprocessing directives implementation): Document that GCC
+ requires the current time.
+
+2002-07-30 Gabriel Dos Reis <gdr@nerim.net>
+
+ * c-pretty-print.h (struct c_pretty_print_info): Add new member.
+ (pp_initializer): New macro.
+ (pp_c_initializer): Declare.
+ * c-pretty-print.c (pp_c_primary_expression): HAndle TARGET_EXPR.
+ (pp_c_initializer): Define.
+ (pp_c_initializer_list): New function.
+ (pp_c_postfix_expression): Handle ABS_EXPR, COMPLEX_CST,
+ VECTOR_CST, CONSTRUCTOR.
+ (pp_c_unary_expression): Handle CONJ_EXPR, REALPART_EXPR,
+ IMAGPART_EXPR.
+ (pp_c_cast_expression): Handle FLOAT_EXPR.
+ (pp_c_assignment_expression): Handle INIT_EXPR.
+ (pp_c_expression): Update.
+
+2002-07-30 Neil Booth <neil@daikokuya.co.uk>
+
+ * objc/objc-act.c (objc_init): Return immediately if filename
+ is NULL.
+
+2002-07-29 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/elf.h: Remove ecoff.h and gofast includes.
+ (DWARF2_DEBUGGING_INFO, DBX_DEBUGGING_INFO): Define unconditionally.
+ (SDB_DEBUGGING_INFO): Undefine.
+ (PREFERRED_DEBUGGING_TYPE): Set to DWARF2_DEBUG.
+ (PUT_SDB_SIZE): Remove.
+ (SUBTARGET_ASM_DEBUGGING_SPEC): Redefine.
+ (STARTFILE_SPEC): Add isa3264 define.
+ * config/mips/elf64.h: Ditto. Move TARGET_MEM_FUNCTIONS from here...
+ * config/mips/ecoff.h: Remove. and here...
+ * config/mips/iris3.h: and here...
+ * config/mips/sni-svr4.h: and here...
+ * config/mips/mips.h: To here. Remove OBJECT_FORMAT_ROSE ifdefs.
+ Add assembler -mmdebug options for non-dwarf debugging.
+ * config/mips/r3900.h: Remove debug info defines.
+ * config/mips/isa32-linux.h: Remove, move functionality to config.gcc.
+ * config/mips/isa3264.h: Ditto.
+ * config/mips/t-isa3264: Fix up for file removal and gofast configure
+ change.
+ * config/mips/t-elf: Ditto.
+ * config/mips/t-ecoff: Ditto.
+ * config/mips/t-r3900: Ditto.
+ * config/mips/t-iris5-6: Ditto.
+ * config/mips/t-isa3264: Ditto.
+ * config/mips/t-linux: Remove.
+ * config/mips/t-netbsd: Remove.
+ * config/mips/t-mips: New file.
+ * config/mips/t-gofast: Ditto.
+ * config/mips/netbsd.h: Remove unnecessary undefines.
+ * config/mips/linux.h: Remove #include of mips.h.
+ * config.gcc: Add mips.h include for elf targets. Remove tm_file
+ for ecoff. Add gofast configure option for mips.
+
+2002-07-29 Chris Demetriou <cgd@broadcom.com>
+
+ * configure.in (mips*-*-*): Add a test to see if MIPS libgloss
+ linker scripts use STARTUP directives consistently.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * config/mips/elf.h (STARTFILE_SPEC): Define conditionally, based
+ on whether HAVE_MIPS_LIBGLOSS_STARTUP_DIRECTIVES is defined.
+ * config/mips/elf64.h (STARTFILE_SPEC): Likewise.
+ * config/mips/isa3264.h (STARTFILE_SPEC): Do not redefine if
+ HAVE_MIPS_LIBGLOSS_STARTUP_DIRECTIVES is set; the result
+ will be the same.
+
+2002-07-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.md ("cpu"): Add ppc8540 to attribute.
+
+2002-07-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.h (RTX_COSTS): Add MULT case for 8540.
+
+2002-07-29 Aldy Hernandez <aldy@quesejoda.com>
+
+ * config/rs6000/rs6000.md: Move altivec patterns from here...
+
+ * config/rs6000/altivec.md: ...to here.
+
+2002-07-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md ("spe_evmra"): Change to unspec.
+
+2002-07-29 Richard Henderson <rth@redhat.com>
+
+ * emit-rtl.c (set_mem_attributes_minus_bitpos): Rename from
+ set_mem_attributes and add BITPOS argument. Subtract it from
+ OFFSET when same is adjusted.
+ (set_mem_attributes): New wrapper function.
+ * expr.c (expand_assignment): Use set_mem_attributes_minus_bitpos;
+ remove offset adjustment hack.
+ * expr.h (set_mem_attributes_minus_bitpos): Declare.
+
+2002-07-29 Gabriel Dos Reis <gdr@nerim.net>
+
+ * Makefile.in (C_OBJS): Include c-pretty-print.o
+ (c-pretty-print.o): Add depency rule.
+ * pretty-print.h: Add more macros.
+ * c-pretty-print.c: New file.
+ * c-pretty-print.h: Likewise.
+
+2002-07-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.h (__internal_ev_mwhgumian): Cast vector
+ constants to __ev64_s32__.
+ (__internal_ev_mwhgsmian): Same.
+ (__internal_ev_mwhgsmfan): Same.
+ (__internal_ev_mwhgssfan): Same.
+ (__internal_ev_mwhgumiaa): Same.
+ (__internal_ev_mwhgsmiaa): Same.
+ (__internal_ev_mwhgsmfaa): Same.
+ (__internal_ev_mwhgssfaa): Same.
+
+2002-07-29 David Edelsohn <edelsohn@gnu.org>
+
+ * varasm.c (assemble_variable): Narrow test for uninitialized
+ without BSS target support.
+
+2002-07-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * profile.c: Add file comment describing the overall algorithm and
+ structures.
+ (struct edge_info): Add comments.
+ (struct bb_info): Add comments.
+ * basic-block.h (EDGE_*): Add comments.
+ * doc/gcov.texi (Gcov Data Files): Document bit flags.
+
+2002-07-29 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/elf.h, config/xtensa/linux.h
+ (TARGET_OS_CPP_BUILTINS): Define.
+ (CPP_PREDEFINES): Remove.
+ * config/xtensa/xtensa.h (TARGET_CPU_CPP_BUILTINS): Define.
+ (CPP_SPEC): Remove.
+
+2002-07-29 Zack Weinberg <zack@codesourcery.com>
+
+ * gensupport.c: Include hashtab.h.
+ (insn_elision, condition_table, hash_c_test, cmp_c_test,
+ maybe_eval_c_test): New routines and data structures to
+ support insn elision.
+ (init_md_reader): Read and initialize the condition_table.
+ (read_md_rtx): Discard insn patterns whose C test is provably
+ always false.
+ * gensupport.h: Declare new functions and data structures.
+
+ * genconditions.c, dummy-conditions.c: New files.
+ * Makefile.in: Build genconditions; run it to construct
+ insn-conditions.c; build that and link it into most gen*
+ programs.
+ (HOST_SUPPORT, HOST_EARLY_SUPPORT): New variables.
+ (GEN): Delete, unused.
+ (STAGESTUFF): Update.
+
+ * gencodes.c: (gen_insn): #define CODE_FOR_xxx equal to
+ CODE_FOR_nothing for all elided patterns.
+ (main): Tweaked to support this.
+ * genflags.c (gen_proto): Emit a static inline generator
+ function here for all elided patterns, which simply returns
+ NULL_RTX.
+ (gen_insn): Do not define HAVE_xxx for elided patterns.
+ (main): Tweaked to support this. No need to forward-declare
+ struct rtx_def.
+ * genrecog.c: Do not bother emitting the C test if it's known
+ to be true at compile time.
+
+2002-07-29 Mike Stump <mrs@apple.com>
+
+ * config.gcc (target_gtfiles): Initialize, as otherwise cross
+ compilers hosted on powerpc-apple-darwin6.0 won't even build.
+
+2002-07-29 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (sibcall, sibcall_value): Add RETURN as part of the pattern,
+ remove clobber of LR.
+ (sibcall_insn, sibcall_value_insn): Update accordingly.
+ (sibcall_epilogue): Remove debugging comment from assembler stream.
+
+2002-07-29 Gabriel Dos Reis <gdr@nerim.net>
+
+ * pretty-print.h: Define more macros.
+ * diagnostic.h (output_formatted_integer): Moved from...
+ * diagnostic.c: ... here.
+
+2002-07-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * stormy16.h (ASM_OUTPUT_SYMBOL_REF): Use ASM_OUTPUT_LABEL_REF.
+
+2002-07-28 Zack Weinberg <zack@codesourcery.com>
+
+ * defaults.h (ASM_OUTPUT_MEASURED_SIZE): Take only two
+ arguments. Always use ".-symbol" as expression argument.
+ * doc/tm.texi: Update to match. Document requirement for
+ ".size symbol, .-symbol" to be acceptable to assembler.
+
+ * config/elfos.h, config/netbsd-aout.h, config/openbsd.h,
+ config/arm/elf.h, config/avr/avr.h, config/cris/aout.h,
+ config/i386/freebsd-aout.h, config/i386/sco5.h,
+ config/ip2k/ip2k.h, config/m88k/m88k.h, config/xtensa/elf.h,
+ config/xtensa/linux.h: Update uses of ASM_OUTPUT_MEASURED_SIZE.
+
+2002-07-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (gengtype-lex.c): Fix error in last change.
+
+ * alpha/freebsd.h (TARGET_OS_CPP_BUILTINS): Add missing
+ backslash.
+
+ * Makefile.in (vmsdbgout.o): Depend on function.h.
+
+ * vmsdbgout.c: Include function.h.
+
+2002-07-28 Alan Modra <amodra@bigpond.net.au>
+
+ * prefix.c (update_path): Don't strip single `.' path components
+ unless stripping a later `..' component. Exit loop as soon as
+ a valid path is found.
+
+2002-07-27 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def [DEF_GCC_BUILTIN]: Require an explicit ATTRS
+ argument. Mark BUILT_IN_RETURN, BUILT_IN_EH_RETURN,
+ BUILT_IN_LONGJMP and BUILT_IN_TRAP as noreturn, the ISO C99
+ floating point unordered comparisons (e.g. __builtin_isgreater)
+ as const, and leave the remaining GCC_BUILTINs unchanged.
+
+ * c-decl.c (builtin_function): No need to explicitly mark
+ BUILT_IN_RETURN and BUILT_IN_EH_RETURN as noreturn.
+
+2002-07-27 Roger Sayle <roger@eyesopen.com>
+
+ * Makefile.in: rtlanal.o now depends upon real.h.
+
+ * flags.h [flag_signaling_nans]: New flag.
+ [HONOR_SNANS]: New macro.
+
+ * toplev.c [flag_signaling_nans]: Initialize to false.
+ (f_options): Add processing for "-fsignaling-nans".
+ (set_fast_math_flags): Clear flag_signaling_nans with -ffast-math.
+ (process_options): flag_signaling_nans implies flag_trapping_math.
+
+ * c-common.c (cb_register_builtins): Define __SUPPORT_SNAN__
+ when -fsignaling-nans. First step to implementing WG14's N965.
+
+ * fold-const.c (fold) [MULT_EXPR]: Conditionalize transforming
+ 1.0 * x into x, and -1.0 * x into -x on !HONOR_SNANS.
+ [RDIV_EXPR]: Conditionalize x/1.0 into x on !HONOR_SNANS.
+
+ * simplify-rtx.c (simplify_relational_operation): Conditionalize
+ transforming abs(x) < 0.0 into false on !HONOR_SNANS.
+
+ * rtlanal.c: #include real.c for TARGET_FLOAT_FORMAT definitions
+ required by HONOR_SNANS. (may_trap_p): Floating point DIV, MOD,
+ UDIV, UMOD, GE, GT, LE, LT and COMPARE may always trap with
+ -fsignaling_nans. EQ and NE only trap for flag_signaling_nans
+ not flag_trapping_math (i.e. HONOR_SNANS but not HONOR_NANS).
+
+ * doc/invoke.texi: Document new -fsignaling-nans compiler option.
+
+2002-07-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (gengtype-lex.c): Work around a bug in flex.
+ * gengtype-lex.l (YY_USE_PROTOS): Undef.
+ (YY_DECL): Define.
+
+2002-07-27 Roger Sayle <roger@eyesopen.com>
+
+ * doc/invoke.texi: Document that both -fno-builtin-foo and
+ -fno-builtin are supported by the g++ front-end.
+
+2002-07-27 Stan Shebs <shebs@apple.com>
+
+ * configure.in: Rename config_gtfiles to target_gtfiles.
+ * configure: Regenerate.
+ * doc/gty.texi: Update reference.
+ * config.gcc (powerpc-*-darwin*): Set target_gtfiles
+ instead of appending to it.
+
+2002-07-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (function_arg_advance): SPE vararg
+ vectors are split into two registers.
+ (function_arg): Same.
+
+Thu Jul 26 23:00:13 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * pa.md (extv): Check predicates before emitting extv_32.
+
+2002-07-27 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_traceback_name): New var.
+ (rs6000_traceback): New var.
+ (rs6000_override_options): Set rs6000_traceback.
+ (rs6000_output_function_epilogue): Implement traceback options.
+ * config/rs6000/rs6000.h (TARGET_OPTIONS): Add "traceback=".
+ (rs6000_traceback_name): Declare.
+
+ * config/rs6000/rs6000.c (output_profile_hook): Don't generate profile
+ label reference when NO_PROFILE_COUNTERS.
+
+2002-07-26 Jason Merrill <jason@redhat.com>
+
+ * function.c (assign_parms): Handle frontend-directed pass by
+ invisible reference.
+
+2002-07-26 Neil Booth <neil@daikokuya.co.uk>
+
+ * doc/cppopts.texi: Update.
+
+2002-07-26 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppmacro.c (_cpp_create_definition): Don't attempt redefinition
+ warnings on assertions.
+
+2002-07-26 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.h (RID_AND, RID_AND_EQ, RID_NOT, RID_NOT_EQ,
+ RID_OR, RID_OR_EQ, RID_XOR, RID_XOR_EQ, RID_BITAND, RID_BITOR,
+ RID_COMPL): Remove.
+ * c-parse.in (rid_to_yy): Similarly.
+
+2002-07-26 Jason Merrill <jason@redhat.com>
+
+ * c-dump.c: Resurrect.
+ * tree-dump.c: Move C-specific stuff to c-dump.c.
+ * c-common.h: Declare c_dump_tree.
+ * c-lang.c (LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN): Define.
+ * Makefile.in (C_AND_OBJC_OBJS): Add c-dump.o.
+ (c-dump.o): New rule.
+
+2002-07-26 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.md: Enable patterns using rlwinm for
+ PowerPC64. Replace "T" and "S" constraints with "n" when the
+ predicate will do. Formatting fixes.
+ (extzvsi_internal2): Use "andi.", "andis." and attr type of "compare"
+ as for extzvsi_internal1.
+
+2002-07-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * dwarfout.c (VERSION_ASM_OP, DERIV_BEGIN_LABEL_FMT,
+ DERIV_END_LABEL_FMT): Remove.
+ (SL_BEGIN_LABEL_FMT, SL_END_LABEL_FMT): Move.
+
+2002-07-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * objc/objc-act.c (UTAG_STATICS, UTAG_PROTOCOL_LIST, USERTYPE):
+ Remove.
+
+2002-07-25 Stan Shebs <shebs@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_prologue): Remove unused
+ local var dwarfp.
+ (output_compiler_stub): Remove unused locals.
+ (output_call): Always initialize line number.
+
+Thu Jul 25 20:34:50 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (LOAD_EXTEND_OP): QImode zero-extends on SHmedia.
+ * sh.md (truncdiqi2, movqi_media): Likewise.
+
+2002-07-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * gcse.c (obstack_chunk_alloc): Remove.
+ (gcse_alloc): Fix to count allocated bytes.
+ * collect2.c (SYMBOL__MAIN): Remove.
+
+2002-07-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * gcc.c (TARGET_EXECUTABLE_SUFFIX): Only used if
+ HAVE_TARGET_EXECUTABLE_SUFFIX.
+
+Thu Jul 25 18:57:50 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * rtl.h (mem_attrs): Spell out more clearly the roles of ALIGN,
+ SIZE, EXPR and OFFSET.
+
+2002-07-25 Richard Henderson <rth@redhat.com>
+
+ * emit-rtl.c (set_mem_attributes): Fix size and alignment thinkos
+ in ARRAY_REF of DECL_P case.
+
+2002-07-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/invoke.texi: Document -mabi=meabi, and expand on the EABI
+ description. Document -mips32, -mips64, and the associated -march
+ values. Describe the "mipsN" arguments to -march. Say that the
+ -mipsN options are equivalent to -march. Reword the description
+ of default type sizes.
+ * toplev.h (target_flags_explicit): Declare.
+ * toplev.c (target_flags_explicit): New var.
+ (set_target_switch): Update target_flags_explicit.
+ * config/mips/abi64.h (SUBTARGET_TARGET_OPTIONS): Undefine.
+ * config/mips/elf64.h (MIPS_ISA_DEFAULT): Undefine.
+ * config/mips/iris6.h (SUBTARGET_ASM_SPEC): -mabi=64 implies -mips3.
+ * config/mips/isa3264.h (MIPS_ENABLE_EMBEDDED_O32): Undefine.
+ * config/mips/mips.h (mips_cpu_info): New struct.
+ (mips_cpu_string, mips_explicit_type_size_string): Remove.
+ (mips_cpu_info_table, mips_arch_info, mips_tune_info): Declare.
+ (MIPS_CPP_SET_PROCESSOR): New macro.
+ (TARGET_CPP_BUILTINS): Declare a macro for each supported processor.
+ Define _MIPS_ARCH and _MIPS_TUNE.
+ (MIPS_ISA_DEFAULT): Don't provide a default value. Instead...
+ (MIPS_CPU_STRING_DEFAULT): Set to "from-abi" if neither it nor
+ MIPS_ISA_DEFAULT were already defined.
+ (MULTILIB_DEFAULTS): Add MULTILIB_ABI_DEFAULT.
+ (TARGET_OPTIONS): Remove -mcpu and -mexplicit-type-size.
+ (ABI_NEEDS_32BIT_REGS, ABI_NEEDS_64BIT_REGS): New.
+ (GAS_ASM_SPEC): Remove -march, -mcpu, -mgp* and -mabi rules.
+ (ABI_GAS_ASM_SPEC): Remove.
+ (MULTILIB_ABI_DEFAULT, ASM_ABI_DEFAULT_SPEC): New macros.
+ (ASM_SPEC): Add -mgp32, -mgp64, -march, -mabi=eabi and -mabi=o64.
+ Invoke %(asm_abi_default_spec) if no ABI was specified.
+ (CC1_SPEC): Remove ISA -> register-size rules.
+ (EXTRA_SPECS): Remove abi_gas_asm_spec. Add asm_abi_default_spec.
+ * config/mips/mips.c (mips_arch_info, mips_tune_info): New vars.
+ (mips_cpu_string, mips_explicit_type_size_string): Remove.
+ (mips_cpu_info_table): New array.
+ (mips_set_architecture, mips_set_tune): New fns.
+ (override_options): Rework to make -mipsN equivalent to -march.
+ Detect more erroneous cases, including those removed from CC1_SPEC.
+ Don't change the ABI based on architecture, or vice versa.
+ Unify logic with GAS.
+ (mips_asm_file_start): Get architecture name from mips_arch_info.
+ (mips_strict_matching_cpu_name_p, mips_matching_cpu_name_p): New fns.
+ (mips_parse_cpu): Take the name of the option as argument. Handle
+ 'from-abi'. Raise an error if the option is wrong.
+ (mips_cpu_info_from_isa): New fn.
+
+2002-07-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (tablejump_mips161): Use gen_rtx_LABEL_REF.
+ (tablejump_mips162): Likewise.
+
+Thu Jul 25 10:23:41 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * simpify-rtx.c (simplify_subreg): Don't pass MODE_CC mode to
+ int_mode_for_mode.
+
+2002-07-25 Gabriel Dos Reis <gdr@nerim.net>
+
+ * c-common.c (c_sizeof_or_alignof_type): Take a third argument for
+ complaining.
+ * c-common.h (c_sizeof): Adjust definition.
+ (c_alignof): Likewise.
+ * c-tree.h (c_sizeof_nowarn): Now macro.
+ * c-typeck.c (c_sizeof_nowarn): Remove definition.
+
+2002-07-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-decl.c (c_decode_option): No need to handle switches
+ cpplib handles.
+
+2002-07-24 Zack Weinberg <zack@codesourcery.com>
+
+ * defaults.h (ASM_OUTPUT_TYPE_DIRECTIVE, ASM_OUTPUT_SIZE_DIRECTIVE,
+ ASM_OUTPUT_MEASURED_SIZE): New default definitions of new macros.
+ * doc/tm.texi: Document them. Also document SIZE_ASM_OP,
+ TYPE_ASM_OP, and TYPE_OPERAND_FMT.
+
+ * config/elfos.h, config/netbsd-aout.h, config/openbsd.h,
+ config/alpha/elf.h, config/arm/elf.h, config/avr/avr.h,
+ config/cris/aout.h, config/i386/freebsd-aout.h,
+ config/i386/sco5.h, config/ia64/ia64.c, config/ip2k/ip2k.h,
+ config/m68k/m68kelf.h, config/m68k/m68kv4.h, config/m88k/m88k.h,
+ config/mcore/mcore-elf.h, config/mips/elf.h, config/mips/elf64.h,
+ config/mips/iris6.h, config/mips/linux.h, config/pa/pa-linux.h,
+ config/pa/pa64-hpux.h, config/rs6000/sysv4.h,
+ config/xtensa/elf.h, config/xtensa/linux.h:
+ Use the new macros.
+ Where possible, remove redundant definitions of SIZE_ASM_OP,
+ TYPE_ASM_OP, and TYPE_OPERAND_FMT.
+
+2002-07-24 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/eabi.h: Define TARGET_SPE_ABI, TARGET_SPE,
+ TARGET_ISEL, and TARGET_FPRS.
+
+ * doc/invoke.texi (RS/6000 and PowerPC Options): Document
+ -mabi=spe, -mabi=no-spe, and -misel=.
+
+ * config/rs6000/rs6000-protos.h: Add output_isel.
+ Move vrsave_operation prototype here.
+
+ * config/rs6000/rs6000.md (sminsi3): Allow pattern for TARGET_ISEL.
+ (smaxsi3): Same.
+ (uminsi3): Same.
+ (umaxsi3): Same.
+ (abssi2_nopower): Disallow when TARGET_ISEL.
+ (*ne0): Same.
+ (negsf2): Change to expand and rename old pattern to *negsf2.
+ (abssf2): Change to expand and rename old pattern to *abssf2.
+
+ New expanders: fix_truncsfsi2, floatunssisf2, floatsisf2,
+ fixunssfsi2.
+
+ Change patterns that check for TARGET_HARD_FLOAT or
+ TARGET_SOFT_FLOAT to also check TARGET_FPRS.
+
+ * config/rs6000/rs6000.c: New globals: rs6000_spe_abi,
+ rs6000_isel, rs6000_fprs, rs6000_isel_string.
+ (rs6000_override_options): Add 8540 case to
+ processor_target_table.
+ Set rs6000_isel for the 8540.
+ Call rs6000_parse_isel_option.
+ (enable_mask_for_builtins): New.
+ (rs6000_parse_isel_option): New.
+ (rs6000_parse_abi_options): Add spe and no-spe.
+ (easy_fp_constant): Treat !TARGET_FPRS as soft-float.
+ (rs6000_legitimize_address): Check for TARGET_FPRS when checking
+ for TARGET_HARD_FLOAT.
+ Add case for SPE_VECTOR_MODE.
+ (rs6000_legitimize_reload_address): Handle SPE vector modes.
+ (rs6000_legitimate_address): Disallow PRE_INC/PRE_DEC for SPE
+ vector modes.
+ Check for TARGET_FPRS when checking for TARGET_HARD_FLOAT.
+ (rs6000_emit_move): Check for TARGET_FPRS.
+ Add cases for SPE vector modes.
+ (function_arg_boundary): Return 64 for SPE vector modes.
+ (function_arg_advance): Check for TARGET_FPRS and
+ Handle SPE vectors.
+ (function_arg): Same.
+ (setup_incoming_varargs): Check for TARGET_FPRS.
+ (rs6000_va_arg): Same.
+ (struct builtin_description): Un-constify mask field. Move up in
+ file.
+ (bdesc_2arg): Un-constify and add SPE builtins.
+ (bdesc_1arg): Same.
+ (bdesc_spe_predicates): New.
+ (bdesc_spe_evsel): New.
+ (rs6000_expand_unop_builtin): Add SPE 5-bit literal builtins.
+ (rs6000_expand_binop_builtin): Same.
+ (bdesc_2arg_spe): New.
+ (spe_expand_builtin): New.
+ (spe_expand_predicate_builtin): New.
+ (spe_expand_evsel_builtin): New.
+ (rs6000_expand_builtin): Call spe_expand_builtin for SPE.
+ (rs6000_init_builtins): Initialize SPE builtins. Call
+ rs6000_common_init_builtins.
+ (altivec_init_builtins): Move all non-altivec builtin code to...
+ (rs6000_common_init_builtins): ...here. New function.
+ (branch_positive_comparison_operator): Allow NE code for SPE.
+ (ccr_bit): Return correct ccr bit for SPE fp.
+ (print_operand): Emit crnor in 'D' case for SPE.
+ New case 't'.
+ Add SPE code for 'y' case.
+ (rs6000_generate_compare): Generate rtl for SPE fp.
+ (output_cbranch): Handle SPE hard floats.
+ (rs6000_emit_cmove): Handle isel.
+ (rs6000_emit_int_cmove): New.
+ (output_isel): New.
+ (rs6000_stack_info): Adjust stack frame so GPRs are saved in
+ 64-bits for SPE.
+ (debug_stack_info): Add SPE info.
+ (gen_frame_mem_offset): New.
+ (rs6000_emit_prologue): Save GPRs in 64-bits for SPE abi.
+ Change mode of frame pointer, when saving it, to Pmode.
+ (rs6000_emit_epilogue): Restore GPRs in 64-bits for SPE abi.
+ Misc cleanups and use gen_frame_mem_offset when appropriate.
+
+ * config/rs6000/rs6000.h (processor_type): Add PROCESSOR_PPC8540.
+ (TARGET_SPE_ABI): New.
+ (TARGET_SPE): New.
+ (TARGET_ISEL): New.
+ (TARGET_FPRS): New.
+ (FIXED_SCRATCH): New.
+ (RTX_COSTS): Add PROCESSOR_PPC8540.
+ (ASM_CPU_SPEC): Add case for 8540.
+ (TARGET_OPTIONS): Add isel= case.
+ (rs6000_spe_abi): New.
+ (rs6000_isel): New.
+ (rs6000_fprs): New.
+ (rs6000_isel_string): New.
+ (UNITS_PER_SPE_WORD): New.
+ (LOCAL_ALIGNMENT): Adjust for SPE.
+ (HARD_REGNO_MODE_OK): Same.
+ (DATA_ALIGNMENT): Same.
+ (MEMBER_TYPE_FORCES_BLK): New.
+ (FIRST_PSEUDO_REGISTER): Set to 113.
+ (FIXED_REGISTERS): Add SPE registers.
+ (reg_class): Same.
+ (REG_CLASS_NAMES): Same.
+ (REG_CLASS_CONTENTS): Same.
+ (REGNO_REG_CLASS): Same.
+ (REGISTER_NAMES): Same.
+ (DEBUG_REGISTER_NAMES): Same.
+ (ADDITIONAL_REGISTER_NAMES): Same.
+ (CALL_USED_REGISTERS): Same.
+ (CALL_REALLY_USED_REGISTERS): Same.
+ (SPE_ACC_REGNO): New.
+ (SPEFSCR_REGNO): New.
+ (SPE_SIMD_REGNO_P): New.
+ (HARD_REGNO_NREGS): Adjust for SPE.
+ (VECTOR_MODE_SUPPORTED_P): Same.
+ (REGNO_REG_CLASS): Same.
+ (FUNCTION_VALUE): Same.
+ (LIBCALL_VALUE): Same.
+ (LEGITIMATE_OFFSET_ADDRESS_P): Same.
+ (SPE_VECTOR_MODE): New.
+ (CONDITIONAL_REGISTER_USAGE): Disable FPRs when target does FP on
+ the GPRs. Set FIXED_SCRATCH fixed in SPE case.
+ (rs6000_stack): Add spe_gp_size, spe_padding_size,
+ spe_gp_save_offset.
+ (USE_FP_FOR_ARG_P): Check for TARGET_FPRS.
+ (LEGITIMATE_LO_SUM_ADDRESS_P): Same.
+ (SPE_CONST_OFFSET_OK): New.
+ (rs6000_builtins): Add SPE builtins.
+
+ * testsuite/gcc.dg/ppc-spe.c: New.
+
+ * config/rs6000/eabispe.h: New.
+
+ * config/rs6000/spe.h: New.
+
+ * config/rs600/spe.md: New.
+
+ * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Define
+ __SIMD__ for TARGET_SPE.
+
+ * config.gcc: Add powerpc-*-eabispe* case.
+ Add spe.h to user headers for powerpc.
+
+2002-07-24 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/elf.h (STARTFILE_SPEC): Undo previous change.
+ * config/mips/elf64.h (STARTFILE_SPEC): Likewise.
+ * config/mips/isa3264.h (STARTFILE_SPEC): Likewise.
+
+2002-07-24 Richard Henderson <rth@redhat.com>
+
+ * expr.c (expand_expr) [TRY_FINALLY_EXPR]: Use GOTO_SUBROUTINE_EXPR
+ form when not optimizing.
+
+2002-07-24 David Mosberger <davidm@hpl.hp.com>
+
+ * config/ia64/ia64.c (gen_thread_pointer): Fix typo in marking
+ thread_pointer_rtx as unchanging.
+
+2002-07-24 Michael Matz <matz@suse.de>
+
+ * ra-colorize.c (INV_REG_ALLOC_ORDER): New macro.
+ (free_reg): Use it.
+
+2002-07-24 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (arm_buneq, arm_bltgt): put '\' before ';' in output
+ pattern.
+ (arm_buneq_reversed, arm_bltgt_reversed): Likewise.
+ (movsicc, movsfcc, movdfcc): FAIL if UNEQ or LTGT.
+
+2002-07-24 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/elf.h (STARTFILE_SPEC): Never include crt0.o.
+ * config/mips/elf64.h (STARTFILE_SPEC): Likewise.
+ * config/mips/isa3264.h (STARTFILE_SPEC): Do not redefine.
+
+Wed Jul 24 17:59:12 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (rest_of_compilation): Dump loops before clobbering
+ the structure.
+
+Wed Jul 24 17:23:16 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * rtlanal.c (keep_with_call_p): Avoid overflow in fixed_regs.
+
+2002-07-24 Frank van der Linden <fvdl@wasabisystems.com>
+
+ PR optimization/7291
+ * config/i386/i386.c (ix86_expand_clrstr): Fix bzero alignment
+ problem on x86_64.
+
+2002-07-24 Gabriel Dos Reis <gdr@nerim.net>
+
+ * pretty-print.h: Add macros from cp/error.c
+
+2002-07-24 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000-protos.h (mask_operand_wrap): Declare.
+ (mask64_2_operand): Declare.
+ (build_mask64_2_operands): Declare.
+ (and64_2_operand): Declare.
+ (extract_MB): Declare.
+ (extract_ME): Declare.
+ * config/rs6000/rs6000.c (mask64_operand): Allow all ones. Remove
+ CONST_DOUBLE code.
+ (mask_operand_wrap): New insn predicate.
+ (mask64_2_operand): Likewise.
+ (and64_2_operand): Likewise.
+ (build_mask64_2_operands): New function.
+ (extract_MB): New function.
+ (extract_ME): New function.
+ (print_operand <case m,M>): Use extract_MB and extract_ME.
+ (print_operand <case S>): Allow all ones. Remove CONST_DOUBLE support.
+ * config/rs6000/rs6000.h (EXTRA_CONSTRAINT): Add 't'.
+ (PREDICATE_CODES): Add and64_2_operand, mask_operand_wrap and
+ mask64_2_operand. Remove CONST_DOUBLE from mask64_operand.
+ * config/rs6000/rs6000.md (andsi3_internal3): New
+ (andsi3_internal3+1): Enable split for powerpc64.
+ (andsi3_internal3+2): New split.
+ (andsi3_internal4): Renamed old andsi3_internal3.
+ (andsi3_internal5): New.
+ (andsi3_internal5+1): Enable split for powerpc64.
+ (andsi3_internal5+2): New split.
+ (andsi3_internal6, andsi3_internal7, andsi3_internal8): New.
+ (anddi3): Handle 't' constraint.
+ (anddi3+1): New split.
+ (anddi3_internal2): Handle 't' constraint.
+ (anddi3_internal2+1): New split.
+ (anddi3_internal3): Handle 't' constraint.
+ (anddi3_internal3+1): New split.
+
+2002-07-24 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.md: Remove scratch reg on insns using
+ addze and similar (plus (comparison r1 r2) r3) insns. Add
+ missing scratch reg in one case. Formatting fixes.
+
+2002-07-24 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppexp.c (parse_defined): Mark macro used.
+ * cpphash.h (struct cpp_macro): New member "used".
+ (_cpp_mark_macro_used, _cpp_warn_if_unused_macro): New.
+ (struct cpp_reader): New member.
+ * cppinit.c (cpp_finish_options): Set first_unused_line.
+ (cpp_finish): Warn of unused macros if requested.
+ (OPT_TABLE): New switches.
+ (cpp_handle_option): Handle them.
+ * cpplib.c (do_undef): Warn if macro unused.
+ (do_ifdef, do_ifndef): Mark macro used.
+ * cpplib.h (struct cpp_options): New member.
+ * cppmacro.c (_cpp_warn_if_unused_macro): New.
+ (enter_macro_context): Mark macro used.
+ (_cpp_create_definition): Mark macro unused; warn if unused
+ when redefined.
+ * cpptrad.c (scan_out_logcial_line, push_replacement_text):
+ Mark macros used.
+ * doc/cppopts.texi: Update.
+
+2002-07-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * dwarf2out.c (SECTION_ASM_OP,
+ ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL): Remove.
+ * system.h (SECTION_ASM_OP): Poison.
+ * tree.c (FILE_FUNCTION_PREFIX_LEN): Remove.
+ * config/alpha/alpha-interix.h, config/mips/linux.h
+ (ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL): Remove.
+ * config/mmix/mmix-protos.h, config/mmix/mmix.c
+ (mmix_asm_output_define_label_difference_symbol): Remove.
+ * config/mmix/mmix.h
+ (ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL): Remove.
+ * doc/tm.texi: Remove documentation.
+
+Tue Jul 23 21:49:24 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * recog.c (asm_operand_ok): Allow float CONST_VECTORs for 'F'.
+ (constrain_operands): Likewise.
+ * regclass.c (record_reg_classes): Likewise.
+ * reload.c (find_reloads): Likewise.
+ * doc/md.texi: Likewise.
+
+ * reload.c (find_reloads_toplev): Use simplify_gen_subreg.
+ * simplify-rtx.c (simplify_subreg): When converting to a non-int
+ mode, try to convert to an integer mode of matching size first.
+
+ * simplify-rtx.x (simplify_subreg): When constructing a CONST_VECTOR
+ from individual subregs, check that each subreg has been generated
+ sucessfully.
+
+2002-07-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * genautomata.c (VLA_HWINT_SHORTEN, VLA_HWINT_LAST): Remove.
+ * df.c (HANDLE_SUBREG, FOR_EACH_BB_IN_BITMAP_REV,
+ FOR_EACH_BB_IN_SBITMAP): Remove.
+ * gcse.c (NEVER_SET, FOLLOW_BACK_EDGES): Remove.
+ * haifa-sched.c (DONE_PRIORITY, MAX_PRIORITY, TAIL_PRIORITY,
+ LAUNCH_PRIORITY, DONE_PRIORITY_P, LOW_PRIORITY_P): Remove.
+ * loop.c (PREFETCH_BLOACK_IN_LOOP_MIN,
+ PREFETCH_LIMIT_TO_SIMULTANEOUS): Remove.
+ * regrename.c (REGNO_MODE_OK_FOR_BASE_P): Remove.
+
+2002-07-23 Gabriel Dos Reis <gdr@nerim.net>
+
+ * pretty-print.h: New file.
+
+2002-07-23 Paul Koning <pkoning@equallogic.com>
+
+ * real.c (REAL_WORDS_BIG_ENDIAN): Make 1 for DEC.
+ (LARGEST_EXPONENT_IS_NORMAL): Ditto.
+ (VAX_HALFWORD_ORDER): Define (1 for DEC VAX, 0 otherwise).
+ (TARGET_G_FLOAT): Default to 0 if not defined.
+ (ieeetoe): New, common routine to convert target format floats
+ to internal form.
+ (e24toe, e53toe): Change to use ieeetoe, distinguish DEC
+ vs. others.
+ (e113toe): Change to use ieeetoe.
+
+2002-07-23 Roman Lechtchinsky <rl@cs.tu-berlin.de>
+
+ * real.c (REAL_WORDS_BIG_ENDIAN): Make sure it is 0 for DEC and 1 for
+ IBM.
+ (e53toe): Assume IEEE if non of DEC, IBM and C4X is defined.
+ (e64toe): Remove special cases for DEC and IBM. Remove support for
+ ARM_EXTENDED_IEEE_FORMAT.
+ (e24toe): Remove special cases for DEC.
+ (significand_size): Simplify. Indent.
+ (ieee_format, ieee_24, ieee_53, ieee_64, ieee_113): New.
+ (etoieee, toieee): New.
+ (etoe113, toe113, etoe64, toe64, etoe53, toe53, etoe24, toe24): Use
+ etoieee and toieee for IEEE arithmetic.
+
+2002-07-23 Gabriel Dos Reis <gdr@nerim.net>
+
+ * doc/extend.texi: Say ISO C90, not ISO C89.
+ * doc/invoke.texi: Likewise.
+ * doc/standards.texi: Likewise.
+
+2002-07-23 Steve Ellcey <sje@cup.hp.com>
+
+ * gcc/explow.c (convert_memory_address): Fix conversion of CONSTs.
+ Fix permutation of conversion and plus/mult.
+ * gcc/builtins.c (expand_builtin_memcpy) Ensure return pointer is
+ ptr_mode and not Pmode when POINTERS_EXTEND_UNSIGNED is defined.
+ (expand_builtin_strncpy) Ditto.
+ (expand_builtin_memset) Ditto.
+
+2002-07-23 Gabriel Dos Reis <gdr@nerim.net>
+
+ Fix PR/7363:
+ * c-common.c (c_sizeof_or_alignof_type): New function.
+ (c_alignof): Remove definition.
+ * c-common.h (c_sizeof, c_alignof): Define as macros.
+ (c_sizeof_or_alignof_type): Declare.
+ (my_friendly_assert): Moved from cp/cp-tree.h
+ * c-typeck.c (c_sizeof): Remove definition.
+
+2002-07-23 Jan Hubicka <jh@suse.cz>
+
+ * gcse.c (try_replace_reg): Use num_changes_pending.
+ * recog.c (num_changes_pending): New function.
+ (validate_replace_src): Use validate_repalce_src_group.
+ (validate_replace_src_group): New.
+ * recog.h (validate_repalce_src_group): New.
+ (num_changes_pending): Likewise.
+
+Tue Jul 23 12:16:58 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * calls.c (emit_library_call_value_1): If
+ FUNCTION_ARG_PASS_BY_REFERENCE is true, pretend this is neither
+ libcall, const call nor pure call.
+
+2002-07-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/m88k/m88k.h (SECTION_ASM_OP): Remove.
+
+2002-07-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * vmsdbgout.c (SECTION_ASM_OP): Remove.
+
+2002-07-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/i386/i386.c (AT_BP): Remove.
+
+2002-07-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * defaults.h (obstack_chunk_alloc, obstack_chunk_free):
+ Default definition.
+ * gcse.c: Don't define obstack_chunk_free.
+ * collect2.c, conflict.c, df.c, diagnostic.c, fix-header.c,
+ flow.c, gcc.c, genattrtab.c, genautomata.c, genflags.c, gensupport.c,
+ integrate.c, loop.c, ra.c, read-rtl.c, regrename.c, reload1.c,
+ reorg.c, tlink.c, tree.c, config/arm/arm.c, objc/objc-act.c:
+ Don't define obstack macros.
+
+2002-07-22 Stephane Carrez <stcarrez@nerim.fr>
+
+ PR target/6744
+ * config/m68hc11/m68hc11.c (m68hc11_z_replacement): Also replace
+ ASM_OPERANDS instructions.
+
+2002-07-22 Stephane Carrez <stcarrez@nerim.fr>
+
+ PR target/7361
+ * config/m68hc11/m68hc11.c (go_if_legitimate_address_internal): Accept
+ constant addresses only on 68HC12.
+
+2002-07-22 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (stack_include_file): Correct test of whether
+ a dependency should be output.
+
+2002-07-22 David Edelsohn <edelsohn@gnu.org>
+
+ * collect2.c (is_ctor_dtor): Add other possible JOINER values.
+
+2002-07-22 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (movqi): If optimizing and we can create pseudos, use
+ a ZERO_EXTEND to load from memory, then copy the result into the
+ target.
+ (movhi): Likewise, but only for ARMv4.
+
+2002-07-22 Neil Booth <neil@daikokuya.co.uk>
+
+ * ssa-ccp.c (PHI_PARMS): Remove.
+
+2002-07-22 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (CLASS_CANNOT_CHANGE_MODE): Include FP_REGS
+ on big-endian targets.
+
+2002-07-22 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * hwint.h (HOST_WIDE_INT_PRINT_DEC_SPACE,
+ HOST_WIDE_INT_PRINT_UNSIGNED_SPACE,
+ HOST_WIDEST_INT_PRINT_DEC_SPACE, HOST_WIDEST_INT_PRINT_DEC_SPACE):
+ New formatting macros.
+
+ * ra-debug.c (dump_static_insn_cost): Avoid string concatenation.
+
+Mon Jul 22 15:27:25 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * rtlanal.c (subreg_regno_offset): Return correct offset for
+ big endian paradoxical subregs.
+
+ * optabs.c (expand_vector_unop): Don't expand using sub_optab
+ if we got the wrong mode.
+
+ * hwint.c (define HOST_WIDE_INT_PRINT_DEC_C): New define.
+ * genrecog.c (write_switch, write_cond): Use it.
+ * genemit.c (gen_exp): Likewise.
+
+2002-07-22 Jakub Jelinek <jakub@redhat.com>
+
+ * c-decl.c (build_compound_literal): Set decl TREE_READONLY from TYPE.
+
+2002-07-22 Jakub Jelinek <jakub@redhat.com>
+
+ * c-decl.c (build_compound_literal): Defer compound literal decls
+ until until file end to emit them only if they are actually used.
+
+2002-07-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ra-build.c (check_conflict_numbers): Hide unused function.
+ (livethrough_conflicts_bb): Avoid automatic aggregate
+ initialization.
+ (parts_to_webs_1): Avoid `U' integer constant modifier.
+ (conflicts_between_webs): Wrap a variable in the macro controlling
+ its usage.
+ * ra-debug.c (ra_debug_msg): Use VA_OPEN/VA_CLOSE.
+ (dump_igraph, dump_graph_cost): Avoid string concatenation
+ (dump_static_insn_cost): Avoid automatic aggregate
+ initialization.
+ * ra-rewrite.c (insert_stores): Avoid automatic aggregate
+ initialization.
+ (dump_cost): Avoid string concatenation
+
+2002-07-21 Richard Henderson <rth@redhat.com>
+
+ * expr.c (expand_expr) [TRY_FINALLY_EXPR]: Don't use
+ GOTO_SUBROUTINE_EXPR when finally_block can be re-expanded.
+
+2002-07-21 Richard Henderson <rth@redhat.com>
+
+ * unroll.c (find_splittable_givs): Do not split DEST_ADDR givs
+ that are not unrolled completely.
+
+2002-07-21 Richard Henderson <rth@redhat.com>
+
+ * loop.h (LOOP_AUTO_UNROLL): Rename from LOOP_FIRST_PASS.
+ * loop.c (strength_reduce): Update.
+ * toplev.c (rest_of_compilation): Do unrolling in the first
+ loop pass, not the second.
+
+2002-07-21 Richard Henderson <rth@redhat.com>
+
+ * emit-rtl.c (set_mem_attributes): Preserve indirection of PARM_DECL
+ when flag_argument_noalias == 2.
+ * alias.c (nonoverlapping_memrefs_p): Handle that.
+ * print-rtl.c (print_mem_expr): Likewise.
+
+2002-07-21 Hartmut Schirmer <hartmut.schirmer@arcor.de>
+
+ * libgcc2.c (__divdi3, __moddi3): Use unary minus operator
+ instead of __negdi2 directly.
+
+2002-07-21 Neil Booth <neil@daikokuya.co.uk>
+
+ * gengenrtl.c (gencode): Don't define obstack_alloc_rtx.
+ * function.c (SYMBOL__MAIN): Remove definition.
+ * global.c (SET_CONFLICT, REGBITP, ALLOCNO_LIVE_P): Remove.
+ * predict.c (PROB_NEVER, PROB_LIKELY, PROB_UNLIKELY): Remove.
+ * profile.c (GCOV_INDEX_TO_BB): Remove.
+ * sched-rgn.c (ABS_VALUE, MIN_DIFF_PRIORITY, MIN_PROB_DIFF): Remove.
+ * simplify-rtx.c (FIXED_BASE_PLUS_P): Remove.
+
+2002-07-21 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-lex.c (GET_ENVIRONMENT): Remove.
+ * collect2.c (GET_ENV_PATH_LIST): Remove.
+ (prefix_from_env): Use GET_ENVIRONMENT.
+ * cppinit.c (GET_ENV_PATH_LIST): Remove.
+ (init_standard_includes): Use GET_ENVIRONMENT.
+ * defaults.h (GET_ENVIRONMENT): Define here if not already.
+ * gcc.c (GET_ENV_PATH_LIST): Remove.
+ (make_relative_prefix, process_command): Update.
+ * protoize.c (GET_ENV_PATH_LIST): Remove.
+ (do_processing): Update.
+
+2002-07-21 Gabriel Dos Reis <gdr@nerim.net>
+
+ * c-decl.c (build_array_declarator): Say 'ISO C90', not 'ISO C89'.
+ (grokdeclarator): Likewise.
+ * c-format.c (C_STD_NAME): Likewise.
+ * c-lex.c (interpret_integer): Likewise.
+ * c-typeck.c (build_array_ref): Likewise.
+ * cpplex.c (_cpp_lex_direct): Likewise.
+ * toplev.c (documented_lang_options): Likewise.
+
+2002-07-21 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-format.c (T99_I, T99_UI): Remove.
+
+2002-07-21 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-typeck.c (SAVE_SPELLING_DEPTH): Remove.
+
+Sun Jul 21 21:36:41 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * gcse.c (do_local_cprop): Do not extend lifetimes of registers set by
+ do_local_cprop.
+
+2002-07-21 Andreas Jaeger <aj@suse.de>
+
+ * reload1.c (fixup_abnormal_edges): Remove unused variable.
+
+2002-07-21 Bernd Schmidt <bernds@redhat.com>
+
+ Improvements for the ifcvt pass from Michael Meissner, with patches
+ by Richard Sandiford <rsandifo@redhat.com>
+ * basic-block.h (struct ce_if_block, ce_if_block_t): New types.
+ * ifcvt.c (cond_exec_changed_p): New static variable.
+ (last_active_insn): New function, renamed from last_active_insn_p
+ and changed to return the last active insn in a basic block. All
+ callers updated.
+ (block_fallthru): New function.
+ (cond_exec_process_insns): New argument CE_INFO. Pass it to
+ IFCVT_MODIFY_INSN. All callers updated.
+ Return false if START or END are NULL.
+ Handle case where we're processing an insn that is already
+ conditional.
+
+ (noce_process_if_block): CE_INFO argument rather than
+ multiple args containing the involved basic blocks. All callers
+ changed.
+ (process_if_block, merge_if_block, find_if_block,
+ cond_exec_process_if_block): Likewise.
+
+ (cond_exec_process_if_block): New arg DO_MULTIPLE_P. All callers
+ changed.
+ Use new function last_active_insn to simplify some code.
+ New code to handle multiple tests.
+ Call IFCVT_MODIFY_CANCEL in all failure cases, otherwise set
+ cond_exec_changed_p to TRUE.
+
+ (process_if_block): New code to handle multiple tests.
+ (merge_if_block): Likewise.
+ (find_if_header): New arg PASS. Changed to return the currently
+ processed basic block or NULL instead of true/false. All callers
+ changed.
+ Call IFCVT_INIT_EXTRA_FIELDS.
+ (block_jumps_and_fallthru_p): New function.
+ (find_if_block): Discover opportunities to convert multiple tests.
+ Add additional debugging output.
+ Update the ce_info structure before returning.
+
+ (if_convert): Run multiple passes of if-conversion.
+ * doc/tm.texi (IFCVT_MODIFY_TESTS, IFCVT_MODIFY_INSN,
+ IFCVT_MODIFY_FINAL, IFCVT_MODIFY_CANCEL, IFCVT_MODIFY_MULTIPLE_TESTS,
+ IFCVT_INIT_EXTRA_FIELDS, IFCVT_EXTRA_FIELDS): Update documentation for
+ these macros.
+
+Sun Jul 21 00:54:54 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * gcse.c: Include cselib.h
+ (constptop_register): Break out from ...
+ (cprop_insn): ... here; kill basic_block argument.
+ (do_local_cprop, local_cprop_pass): New functions.
+ (one_cprop_pass): Call local_cprop_pass.
+
+2002-07-20 Roger Sayle <roger@eyesopen.com>
+
+ * simplify-rtx.c (simplify_relational_operation): Optimize
+ abs(x) < 0.0 (and abs(x) >= 0.0 when using -ffast-math).
+
+2002-07-20 Michae Matz <matz@suse.de>
+
+ * ra-build.c: (remember_web_was_spilled): Use GENERAL_REGS.
+
+2002-07-20 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppexp.c (struct op): Add token pointer.
+ (check_promotion, CHECK_PROMOTION): New.
+ (optab): Update.
+ (_cpp_parse_expr): Update, use token pointer of struct op.
+ (reduce): Warn about change of sign owing to promotion.
+ * cppinit.c (cpp_handle_option): New warning if -Wall.
+ * cpplib.h (struct cpp_options): New member.
+
+2002-07-19 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md: Remove ppc630 fpcompare from single
+ fpu list. Separate Power4 compare and delayed_compare. Correct
+ Power4 fpcompare.
+ (fix_truncdfsi2_internal): Restore FPR preference.
+ * config/rs6000/t-aix43 (MULTILIB_MATCHES): Add mcpu?power3,
+ mcpu?power4, mcpu?604e. Remove mpower, mpower2, mpowerpc.
+
+2002-07-19 Momchil Velikov <velco@fadata.bg>
+
+ * reload1.c (reload_as_needed): Duplicate oldpat.
+
+2002-07-20 Alan Modra <amodra@bigpond.net.au>
+
+ PR optimization/7130
+ * loop.h (struct loop_info): Add "preconditioned".
+ * unroll.c (unroll_loop): Set it.
+ * doloop.c (doloop_modify_runtime): Correct count for unrolled loops.
+
+2002-07-19 Zack Weinberg <zack@codesourcery.com>
+
+ * rtl.def (CODE_LABEL): Remove slot 8.
+ * rtl.h (struct rtx_def): Document new uses of jump and call fields.
+ (LABEL_ALTERNATE_NAME): Delete.
+ (LABEL_KIND, SET_LABEL_KIND, LABEL_ALT_ENTRY_P): New.
+ * defaults.h: Remove default for ASM_OUTPUT_ALTERNATE_LABEL_NAME.
+
+ * final.c (output_alternate_entry_point): New.
+ (final_scan_insn): Use it instead of
+ ASM_OUTPUT_ALTERNATE_LABEL_NAME. Do not consider possibility
+ of a case label being an alternate entry point.
+
+ * cfgbuild.c (make_edges, find_bb_boundaries): Use LABEL_ALT_ENTRY_P.
+ * emit-rtl.c (gen_label_rtx): Adjust call to gen_rtx_CODE_LABEL.
+ Do not clear LABEL_NUSES (unnecessary) or LABEL_ALTERNATE_NAME
+ (field deleted).
+ * print-rtl.c, ra-debug.c: Update code to output CODE_LABELs.
+
+ * doc/rtl.texi: Document LABEL_KIND, SET_LABEL_KIND, and
+ LABEL_ALT_ENTRY_P; not LABEL_ALTERNATE_NAME.
+ * doc/tm.texi: Delete documentation of
+ ASM_OUTPUT_ALTERNATE_LABEL_NAME.
+
+2002-07-19 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/iris5gas.h (DWARF2_DEBUGGING_INFO): Define.
+ (PREFERRED_DEBUGGING_TYPE): Use DWARF2_DEBUG.
+ (LINK_SPEC): Define.
+ (STARTFILE_SPEC): Define.
+ (ENDFILE_SPEC): Define.
+
+ * config/mips/iris6-o32.h (LINK_SPEC): Move ...
+ * config/mips/iris6-o32-as.h (LINK_SPEC): ... here.
+
+ * config/mips/iris6-o32-gas.h: New file.
+ * config.gcc (mips-sgi-irix6*o32): Use it.
+
+ * config/mips/t-iris5-gas: New file.
+ * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix5*): Use it.
+
+2002-07-19 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppexp.c (ALWAYS_EVAL): Remove.
+ (optab, reduce): Always evaluate.
+ (num_unary_op, num_binary_op, num_div_op): Issue diagnostics
+ only if not skipping evaluation.
+
+2002-07-19 Marek Michalkiewicz <marekm@amelek.gda.pl>
+
+ * config/avr/avr.c (debug_hard_reg_set): Remove.
+
+2002-07-19 Chris Demetriou <cgd@broadcom.com>
+
+ * gcc.c (cpp_options): Include "%1" (cc1_spec).
+
+2002-07-19 Richard Henderson <rth@redhat.com>
+
+ * loop.c (loop_givs_rescan): Delete the REG_EQUAL note, not the insn.
+
+2002-07-19 Alan Modra <amodra@bigpond.net.au>
+
+ * prefix.c (update_path): Don't zap single `.' path components
+ unless followed by another `.' and fix typo last patch.
+
+2002-07-18 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppexp.c (cpp_num_mul): Remove unused parameter.
+ (UNARY, BINARY, OTHER, binary_handler): Remove.
+ (ALWAYS_EVAL): New.
+ (optab): Update.
+ (reduce): Refactor to a large switch, don't use a function
+ pointer.
+
+2002-07-18 Bo Thorsen <bo@berlioz.suse.de>
+
+ * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): Define this always.
+
+Thu Jul 18 19:39:18 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh-protos.h (sh_expand_unop_v2sf): Move inside #ifdef RTX_CODE guard.
+ (sh_expand_binop_v2sf): Likewise.
+ * sh.c (machine_dependent_reorg): Add move for UNSPEC_MOVA.
+ (int_gpr_dest, trunc_hi_operand): New functions.
+ * sh.h (PREDICATE_CODES): Add any_register_operand, int_gpr_dest and
+ trunc_hi_operand.
+ (SPECIAL_MODE_PREDICATES, any_register_operand): Define.
+ * sh.md (cmpeqdi_t+1): Remove comments that genrecog warns about.
+ (adddi3_compact+1, subdi3_compact+1, ashlsi3_n+1, ashlhi3+1): Likewise.
+ (ashrsi2_16+1, ashrsi2_31+1, lshrsi3_n+1, ashrdi3+[12]): Likewise.
+ (and_shl_scratch+[12], zero_extendhidi2+1): Likewise.
+ (zero_extendhisi2_media+1, extendhidi2+1, extendqidi2+1): Likewise.
+ (extendhisi2_media+1, extendqisi2_media+1): Likewise.
+ (movsi_media_nofpu+[12], movhi_media+1, movdi_media_nofpu+1): Likewise.
+ (movdi_const_16bit+[12], movdf_i4+[123], reload_outdf+[2-5]): Likewise.
+ (movsf_ie+1): Likewise.
+ (loaddi_trunc): Use int_gpr_dest predicate.
+ (use_sfunc_addr, indirect_jump_scratch, sibcall_compact): Add mode(s).
+ (mova, mova_const, GOTaddr2picreg, ptrel, casesi_worker_0): Likewise.
+ (casesi_worker_0+[12], casesi_worker): Likewise.
+ (shcompact_preserve_incoming_args): Likewise.
+ (mov_nop): Use any_register_operand predicate.
+ (mperm_w0): Use trunc_hi_operand predicate.
+
+2002-07-18 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa-linux.h (DWARF2_UNWIND_INFO): Delete define.
+ * pa.h (EH_RETURN_DATA_REGNO): Revise TARGET_64BIT and correct
+ numbering.
+
+2002-07-18 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.c (output_deferred_plabels): Remove unused millicode enum mulU.
+
+2002-07-18 Richard Henderson <rth@redhat.com>
+
+ PR optimization/7147
+ * ifcvt.c (noce_get_condition): Make certain that the condition
+ is valid at JUMP.
+
+Thu Jul 18 13:44:51 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (barrier_align, push): Shut up compiler warnings.
+ (initial_elimination_offset,sh_media_init_builtins): Likewise.
+ (reg_no_subreg_operand): Delete.
+
+2002-07-17 Bo Thorsen <bo@suse.de>
+
+ * config/i386/linux64.h (LINK_SPEC): Remove bogus -Y option.
+ (STARTFILE_PREFIX_SPEC): Define for NATIVE_CROSS compilations.
+ (STARTFILE_SPEC): Remove hardcoded library paths.
+ (ENDFILE_SPEC): Likewise.
+
+Thu Jul 18 09:38:59 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * gcse.c (hoist_expr_reaches_here_p): Stop once expr_bb is reached.
+
+ * gcse.c (try_replace_reg): Do not return false positives.
+
+2002-07-18 Alan Modra <amodra@bigpond.net.au>
+
+ * prefix.c: (update_path): Strip ".." components when prior dir
+ doesn't exist. Pass correct var to UPDATE_PATH_HOST_CANONICALIZE.
+
+ * config/rs6000/sysv4.h (ASM_OUTPUT_REG_PUSH): Remove 64-bit support.
+ (ASM_OUTPUT_REG_POP): Likewise.
+
+2002-07-18 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (first_reg_to_save): Remove bogus
+ adjustments to first_reg for profiling case.
+ (output_function_profiler): Correct lr save slot for ABI_AIX_NODESC.
+ Disable profiling for 64 bit code on both ABI_V4 and ABI_AIX_NODESC.
+ Save static chain reg to sp + 12 on ABI_AIX_NODESC.
+ * config/rs6000/sysv4.h (ASM_OUTPUT_REG_PUSH): Define.
+ (ASM_OUTPUT_REG_POP): Define.
+ * config/rs6000/linux64.h (ASM_OUTPUT_REG_PUSH): Undef.
+ (ASM_OUTPUT_REG_POP): Undef.
+
+2002-07-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * cpplib.c (do_sccs): Handle #sccs on all systems.
+ * system.h (SCCS_DIRECTIVE): Poison.
+ * config/darwin.h, config/freebsd.h, config/netbsd.h,
+ config/ptx4.h, config/svr3.h, config/svr4.h, config/alpha/elf.h,
+ config/arm/linux-elf.h, config/c4x/c4x.h, config/d30v/d30v.h,
+ config/i370/i370.h, config/i386/gas.h, config/i386/sco5.h,
+ config/i960/i960.h, config/m68hc11/m68hc11.h, config/m68k/3b1.h,
+ config/m68k/3b1g.h, config/m68k/crds.h, config/m68k/mot3300.h,
+ config/m68k/pbb.h, config/m88k/m88k.h, config/mips/mips.h,
+ config/sparc/pbd.h, config/stormy16/stormy16.h, config/vax/vaxv.h:
+ Remove all references to SCCS_DIRECTIVE.
+ * doc/cpp.texi, doc/tm.texi: Update.
+
+Wed Jul 17 19:23:32 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * regrename.c (maybe_mode_change): New function.
+ (find_oldest_value_reg, copyprop_hardreg_forward_1): Use it.
+
+2002-07-17 Rodney Brown <rbrown64@csc.com.au>
+
+ * config/i386/i386.c (ix86_expand_int_movcc): In the general case
+ suppress addition when either ct or cf are zero.
+
+2002-07-17 Eric Botcazou <ebotcazou@multimania.com>
+ Glen Nakamura <glen@imodulo.com>
+
+ PR optimization/6713
+ * loop.c (loop_givs_rescan): Explicitly delete the insn that
+ sets a non-replaceable giv after issuing the new one.
+
+2002-07-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppexp.c (cpp_interpret_integer, append_digit, parse_defined,
+ eval_token): Clarify and correct use of "bool" variables.
+ * cpplib.h (struct cpp_options): Similarly.
+ * cppmacro.c (parse_params, _cpp_save_parameter): Ditto.
+ * cpptrad.c (recursive_macro): Similarly.
+
+Wed Jul 17 17:08:06 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/sh/lib1funcs.asm (udivsi3_i4): Implement SHcompact version in
+ SHmedia code.
+
+ * sh.md (cmpgtudi_media): Remove spurious @.
+
+ * config/sh/lib1funcs.asm (FMOVD_WORKS): Don't define for little endian.
+ * sh.h (OVERRIDE_OPTIONS): Don't set FMOVD_BIT for little endian.
+
+ * config/sh/lib1funcs.asm (init_trampoline): New entry point.
+ * sh-protos.h (sh_initialize_trampoline): Declare.
+ * sh.c (sh_initialize_trampoline): New function.
+ * sh.h (TRAMPOLINE_SIZE): Only 24 for TARGET_SHMEDIA32.
+ (TRAMPOLINE_ALIGNMENT): Need cache-line alignment for TARGET_SHMEDIA.
+ (INITIALIZE_TRAMPOLINE): Call sh_initialize_trampoline.
+ (TRAMPOLINE_ADJUST_ADDRESS): Not needed for SHcompact.
+ * sh.md (initialize_trampoline, double_shori): New patterns.
+ (initialize_trampoline_compact): Likewise.
+ (shmedia32_initialize_trampoline_big): Remove.
+ (shmedia32_initialize_trampoline_little): Likewise.
+
+ * sh-protos.h (binary_float_operator): Remove declaration.
+ (sh_expand_unop_v2sf, sh_expand_binop_v2sf): Declare.
+ * sh.c (print_operand, case 'N'): Check against CONST0_RTX.
+ (unary_float_operator, sh_expand_unop_v2sf): New functions.
+ (sh_expand_binop_v2sf): Likewise.
+ (zero_vec_operand): Delete.
+ (SH_BLTIN_UDI): New builtin shared signature define. Renumbered
+ all non-shared ones.
+ (bdesc): Change all the mextr builtins to use SH_BLTIN_UDI.
+ Enable nsb and byterev.
+ * sh.h (CONDITIONAL_REGISTER_USAGE): Initialize DF_HI_REGS.
+ (HARD_REGNO_MODE_OK): Allow TImode in fp regs. Allow V2SFmode
+ in general regs.
+ (enum reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add DF_HI_REGS.
+ (SECONDARY_OUTPUT_RELOAD_CLASS): Likewise. Remove clause for
+ immediate operands.
+ (SECONDARY_INPUT_RELOAD_CLASS): Add clause for immediate operands.
+ Add DF_HI_REGS.
+ (CLASS_CANNOT_CHANGE_MODE, CLASS_CANNOT_CHANGE_MODE_P): Allow
+ lowpart fp regs - only for big endian for now.
+ (LEGITIMATE_CONSTANT_P): Don't allow nonzero float vectors
+ when FPU is in use.
+ (EXTRA_CONTRAINT_U): Check against CONST0_RTX.
+ (LOAD_EXTEND_OP): NIL for SImode.
+ (REGISTER_MOVE_COST): Add DF_HI_REGS. Const for moves between
+ general and fp registers is 4.
+ PREDICATE_CODES: Amend binary_float_operator entry.
+ Remove zero_vec_operand. Add unary_float_operator.
+ * sh.md (udivsi3_i4_media): Use truncate instead of paradoxical
+ subreg SET_DEST.
+ (truncdisi2, truncdihi2, movv2sf): Allow memory destinations.
+ (truncdiqi2): Do sign extension.
+ (movsi_media, movdi_media): Allow to use r63 to an fp register.
+ (movdf_media, movsf_media): Likewise.
+ (movv2sf_i, movv2sf_i+1): Don't use f{ld,st}.p or SUBREGS.
+ Collapse to one define_insn_and_split. Allow immediate sources.
+ (addv2sf3, subv2sf3, mulv2sf3, divv2sf3): New patterns.
+ (movv4sf_i): Allow immediate sources. Use simplify_gen_subreg.
+ (movv4sf): Allow immediate sources.
+ (movsf_media_nofpu+1): Don't split moves to FP registers.
+ (unary_sf_op, binary_sf_op, mshflo_w_x, concat_v2sf): New patterns.
+ (movv8qi_i+3): Check against CONST0_RTX.
+ (mextr1, mextr2. mextr3. mextr4, mextr5, mextr6, mextr7): Use DImode
+ for input and output operands. Fix argument 3 to gen_mextr_rl.
+ (mmul23_wl, mmul01_wl, mmulsum_wq_i): s/const_vector/parallel/
+ (msad_ubq_i, mshf4_b, mshf0_b, mshf4_l, mshf0_l, mshf4_w): Likewise.
+ (mshf0_w, fipr, ftrv): Likewise.
+ (mshfhi_l_di): Now insn_and_split. Can handle FP regs.
+
+2002-07-17 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
+
+ * arm.h (ARM_NUM_INTS, ARM_NUM_REGS, ARM_NUM_REGS2): Renamed from
+ NUM_INTS, NUM_REGS and ARM_NUM_REGS2 respectively. All uses changed.
+ * arm.c: Similarly.
+
+2002-07-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_sign_extend): Declare.
+ * config/mips/mips.h (MASK_DEBUG_H, TARGET_DEBUG_H_MODE): Remove.
+ (TARGET_SWITCHES): Remove debugh.
+ (ISA_HAS_TRUNC_W): New macro.
+ (CLASS_CANNOT_CHANGE_MODE): Include FP_REGS if TARGET_FLOAT64.
+ (PREDICATE_CODES): Remove se_nonimmediate_operand.
+ * config/mips/mips.c (movdi_operand): Allow sign-extensions of
+ any SImode move_operand.
+ (se_nonimmediate_operand): Remove.
+ (mips_sign_extend): New.
+ (mips_move_2words): Use it for sign-extended source operands.
+ (override_options): Allow integers to be put into single FPRs.
+ (mips_secondary_reload_class): Handle integers in float registers.
+ * config/mips/mips.md (extendsidi2): Turn into a define_expand.
+ (fix_truncsfsi2, fix_truncdfsi2): Likewise.
+ (fix_truncdfsi2_insn, fix_truncdfsi2_macro): New.
+ (fix_truncsfsi2_insn, fix_truncsfsi2_macro): New.
+ (fix_truncdfdi2): Provide only a single alternative, in which the
+ integer is in a float register. Depend on TARGET_FLOAT64 rather
+ than TARGET_64BIT.
+ (fix_truncsfdi2, floatdidf2, floatdisf2): Likewise.
+ (floatsidf2, floatsisf2): Likewise, but no TARGET_FLOAT64 dependency.
+ (movdi_internal2): Don't allow the source operand to be sign-extended.
+ Add alternatives for float registers.
+ (*movdi_internal2_extend): New. Version of movdi_internal2 that
+ allows sign-extension.
+ (*movdi_internal2_mips16): Name the existing mips16 movdi pattern.
+ (movsi_internal2): Rename to movsi_internal. Add alternatives for
+ float registers. Remove TARGET_DEBUG_H_MODE test.
+ (movhi_internal1): Rename to movhi_internal. Don't check
+ TARGET_DEBUG_H_MODE. Fix transposed *d and *f source constraints.
+ (movqi_internal1): Rename to movqi_internal and remove
+ TARGET_DEBUG_H_MODE dependency.
+ (movsi_internal1, movhi_internal2, movqi_internal2): Remove.
+
+2002-07-16 Jim Wilson <wilson@redhat.com>
+
+ * toplev.c (lang_dependent_init): Create function context for
+ init_expr_once.
+
+2002-07-16 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/cris/linux.h (CRIS_LINK_SUBTARGET_SPEC): Don't
+ --gc-sections if -r.
+ * config/cris/cris.h: Ditto.
+
+2002-07-16 Rodney Brown <rbrown64@csc.com.au>
+
+ * config/i386/i386.c (ix86_expand_int_movcc): In the case where
+ the comparison directly gives a mask suppress addition when cf is
+ zero by complementing the mask.
+
+2002-07-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in: Delete references to enquire.
+ * enquire.c: Move to contrib.
+
+2002-07-16 Stan Shebs <shebs@apple.com>
+
+ * config/darwin.h (ASM_OUTPUT_LABEL): Move to here from
+ config/rs6000/darwin.h.
+ (ASM_OUTPUT_SKIP): Ditto.
+ (TEXT_SECTION_ASM_OP): Ditto.
+ (DATA_SECTION_ASM_OP): Ditto.
+ (ASM_APP_ON): Define.
+ (ASM_APP_OFF): Define.
+ * config/rs6000/darwin.h (ASM_OUTPUT_LABEL, ASM_OUTPUT_SKIP,
+ TEXT_SECTION_ASM_OP, DATA_SECTION_ASM_OP): Remove.
+
+ * config/darwin.c (func_name_maybe_scoped): Remove unused decl.
+ (machopic_function_base_name): Declare result to be const.
+ (machopic_non_lazy_ptr_name): Ditto.
+ (machopic_stub_name): Ditto.
+ * config/darwin-protos.h: Ditto for the prototypes.
+
+Wed Jul 17 00:22:39 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * m68hc11.c (m68hc11_reorg): Do not rebuild CFG.
+
+Wed Jul 17 00:20:48 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (prefetch): Fix for 64bit mode.
+ (prefetch_sse_rex, prefetch_3dnow_rex): New patterns.
+
+Wed Jul 17 00:19:20 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.h (MACHINE_DEPENDENT_REORG): New macro.
+ * i386.c (x86_machine_dependent_reorg): New function.
+ * i386-protos.h (x86_machine_dependent_reorg): Declare.
+
+2002-07-16 Zack Weinberg <zack@codesourcery.com>
+
+ * builtins.c (std_expand_builtin_va_start): Remove unused
+ first argument.
+ (expand_builtin_va_start): Call EXPAND_BUILTIN_VA_START and
+ std_expand_builtin_va_start with just two arguments.
+ * expr.h: Update prototypes.
+
+ * alpha-protos.h, alpha.h, alpha.c, arc-protos.h, arc.h,
+ arc.c, d30v-protos.h, d30v.h, d30v.c, i386-protos.h, i386.h,
+ i386.c, i960-protos.h, i960.h, i960.c, m88k-protos.h, m88k.h,
+ m88k.c, mips-protos.h, mips.h, mips.c, mn10300-protos.h,
+ mn10300.h, mn10300.c, pa-protos.h, pa.h, pa.c,
+ rs6000-protos.h, rs6000.h, rs6000.c, s390-protos.h, s390.h,
+ s390.c, sh-protos.h, sh.h, sh.c, sparc-protos.h, sparc.h,
+ sparc.c, stormy16-protos.h, stormy16.h, stormy16.c,
+ xtensa-protos.h, xtensa.h, xtensa.c: Remove unused first
+ argument from all implementations of EXPAND_BUILTIN_VA_START
+ and all uses of std_expand_builtin_va_start.
+
+Tue Jul 16 19:32:58 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * regrename.c (copy_value): Don't record high part copies.
+
+2002-07-16 Steve Ellcey <sje@cup.hp.com>
+
+ * gcc/config/pa/long_double.h (FIXUNS_TRUNCTFDI2_LIBCALL): New define.
+ (fixunstfdi_libfunc): Change to use FIXUNS_TRUNCTFDI2_LIBCALL.
+ * gcc/config/pa/quadlib.c (_U_Qfcnvfxt_quad_to_udbl): New function.
+
+2002-07-16 Ian Dall <ian@sibyl.beware.dropbear.id.au>
+
+ * doc/invoke.texi (NS32K Options): Document -mieee-compare option
+
+ * config/ns32k/ns32k.md (addsi3, *frame_addr, *stack_addr): merge
+ into addsi3 using register class "x" and "y".
+
+ * config/ns32k/ns32k.md (*madddf, *maddsf, *msubdf, *msubsf):
+ "earlyclobber" constraint modifier for some alternative.
+
+ * config/ns32k/ns32k.md (tstdf, tstsf, cmpdf, cmpsf, blt, ble)
+ (*ble, *blt): Flag to indicate bCOND and sCOND should check for
+ unordered.
+ config/ns32k/ns32k.h (CC_UNORD): define corresponding mask.
+
+ * config/ns32k/ns32k.h (TARGET_IEEE_COMPARE, MASK_IEEE_COMPARE)
+ (TARGET_SWITCHES): Add -mieee-compare option.
+ (OVERRIDE_OPTIONS): 32332 is a subset of
+ 32532. Don't use IEEE_COMPARE -funsafe-math-optimizations.
+ (TARGET_SWITCHES): Fix description of bitfield option.
+ * config/ns32k/netbsd.h (TARGET_DEFAULT): Add
+ -mieee-compare option. Remove 32332 flag.
+
+2002-07-16 Steve Ellcey <sje@cup.hp.com>
+
+ * explow.c (convert_memory_address): Remove special handling
+ when POINTERS_EXTEND_UNSIGNED < 0.
+ * config/ia64.md (movsi_symbolic): New instruction for ILP32 mode.
+ (movedi_symbolic): Fix typo.
+ (load_fptr): Remove mode restriction so it works for SI and DI.
+ (load_fptr_internal1): Ditto.
+ (load_gprel): Ditto.
+ (load_symptr_internal1): Ditto.
+ (call_pic): Ditto.
+ * config/ia64.c (call_operand): Modify mode check.
+ (ia64_expand_load_address): Handle DI and SI addresses and symbols.
+ (ia64_expand_move): Ditto.
+ (ia64_assemble_integer): Handle SImode function pointers.
+ (ia64_expand_fetch_and_op): Handle SImode mem addresses.
+ (ia64_expand_op_and_fetch): Ditto.
+ (ia64_expand_compare_and_swap): Ditto.
+ (ia64_expand_lock_test_and_set): Ditto.
+ (ia64_expand_lock_release): Ditto.
+
+2002-07-16 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
+
+ * arm.c (emit_sfm): Don't set RTX_FRAME_RELATED_P on DWARF.
+
+2002-07-16 Jeroen Dobbelaere <jeroen.dobbelaere@acunia.com>
+ Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.h (LEGITIMATE_PIC_OPERAND_P): Only test
+ CONSTANT_POOL_ADDRESS_P if a SYMBOL_REF. Simplify logic.
+
+2002-07-16 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (stack_tie): New insn. Use an idiom that the alias code
+ understands to be a memory clobber.
+ * arm.c (arm_expand_prologue): Use it.
+
+2002-07-16 Daniel Berlin <dberlin@dberlin.org>
+
+ * ra-rewrite.c: #include reload.h, insn-config.h
+ * ra-build.c: #include reload.h
+ * Makefile.in: Update ra-rewrite.o, ra-build.o dependencies to
+ depend on reload.h, insn-config.h.
+
+Tue Jul 16 11:57:45 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * expr.c (emit_move_insn_1): Handle arbitrary moves that are
+ the same size as a word.
+
+ * regrename.c (find_oldest_value_reg): Take WORDS_BIG_ENDIAN /
+ BYTES_BIG_ENDIAN into account.
+
+Tue Jul 16 12:22:44 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (prefetch): Fix for 64bit mode.
+ (prefetch_sse_rex, prefetch_3dnow_rex): New patterns.
+
+ * i386.md (movss, movsd): Use xorps/xorpd for Athlon.
+
+2002-07-16 Marek Michalkiewicz <marekm@amelek.gda.pl>
+
+ * hard-reg-set.h (TEST_HARD_REG_BIT): Return 1 if the bit is set.
+
+2002-07-15 Zack Weinberg <zack@codesourcery.com>
+
+ * ginclude/varargs.h: Replace with stub which issues #error.
+ * ginclude/stdarg.h: __builtin_stdarg_start is renamed
+ __builtin_va_start.
+
+ * builtins.def (BUILT_IN_VARARGS_START): Delete.
+ (BUILT_IN_VA_START): New.
+ * builtins.c (expand_builtin_va_start): Eliminate first
+ argument and code to implement pre-ISO varargs.
+ (std_expand_builtin_va_start): Ignore first argument; it is
+ always 1.
+ (expand_builtin): Handle BUILT_IN_VA_START and
+ BUILT_IN_STDARG_START identically. Delete
+ BUILT_IN_VARARGS_START case.
+
+ * function.c (assign_parms): Delete hide_last_arg and all
+ its uses.
+ (mark_varargs): Delete function.
+ * function.h (struct function): Delete 'varargs' bit.
+ (current_function_varargs): Delete macro.
+ * tree.h: Don't declare mark_varargs.
+
+ * c-decl.c (c_function_varargs, c_mark_varargs): Delete.
+ (c_expand_body): Don't call mark_varargs.
+ * c-objc-common.c: Handle BUILT_IN_VA_START and
+ BUILT_IN_STDARG_START identically. Delete
+ BUILT_IN_VARARGS_START case.
+ * c-tree.h: Don't declare c_mark_varargs.
+ * c-parse.in: Remove grammar rules for '&...' (which has been
+ commented out since before 2.7.2) and for '...' in K+R
+ argument declarations.
+
+ * builtins.c, function.c, integrate.c, sibcall.c,
+ config/alpha/unicosmk.h, config/arc/arc.c, config/arc/arc.h,
+ config/avr/avr.c, config/cris/cris.c, config/fr30/fr30.c,
+ config/i960/i960.c, config/i960/i960.md, config/m32r/m32r.c,
+ config/m32r/m32r.h, config/m88k/m88k.c, config/m88k/m88k.h,
+ config/mips/mips.c, config/mmix/mmix.c, config/mmix/mmix.h,
+ config/mn10300/mn10300.c, config/pa/som.h, config/s390/s390.c,
+ config/sh/sh.c, config/sh/sh.h, config/sparc/sparc.h,
+ config/stormy16/stormy16.c: Delete all references to
+ current_function_varargs, and code predicated on that flag.
+
+ * config/alpha/alpha.c (alpha_va_start),
+ config/arc/arc.c (arc_va_start),
+ config/i386/i386.c (ix86_va_start),
+ config/mips/mips.c (mips_va_start),
+ config/mn10300/mn10300.c (mn10300_va_start),
+ config/rs6000/rs6000.c (rs6000_va_start),
+ config/s390/s390.c (s390_va_start),
+ config/sh/sh.c (sh_va_start),
+ Ignore first argument; it is always 1.
+
+ * config/c4x/c4x-protos.h, config/c4x/c4x.c: Delete c4x_va_start.
+ * config/ia64/ia64-protos.h, config/ia64/ia64.c: Delete ia64_va_start.
+ * config/m68hc11/m68hc11-protos.h, config/m68hc11/m68hc11.c:
+ Delete m68hc11_va_start.
+ * config/c4x/c4x.h, config/ia64/ia64.h, config/m68hc11/m68hc11.h:
+ No need to define EXPAND_BUILTIN_VA_START.
+
+ * doc/invoke.texi, doc/sourcebuild.texi, doc/tm.texi,
+ doc/trouble.texi: Remove references to GCC-provided <varargs.h>.
+
+2002-07-15 Eric Botcazou <ebotcazou@multimania.com>
+
+ PR optimization/7153
+ * regmove.c (optimize_reg_copy_3): Don't optimize if the register
+ dies in more than one insn.
+
+2002-07-15 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/sparc/netbsd-elf.h (TRANSFER_FROM_TRAMPOLINE): Remove.
+
+2002-07-15 Michael Matz <matz@suse.de>,
+ Daniel Berlin <dberlin@dberlin.org>,
+ Denis Chertykov <denisc@overta.ru>
+
+ Add a new register allocator.
+
+ * ra.c: New file.
+ * ra.h: New file.
+ * ra-build.c: New file.
+ * ra-colorize.c: New file.
+ * ra-debug.c: New file.
+ * ra-rewrite.c: New file.
+
+ * Makefile.in (ra.o, ra-build.o, ra-colorize.o, ra-debug.o,
+ (ra-rewrite.o): New .o files for libbackend.a.
+ (GTFILES): Add basic-block.h.
+
+ * toplev.c (flag_new_regalloc): New.
+ (f_options): New option "new-ra".
+ (rest_of_compilation): Call initialize_uninitialized_subregs()
+ only for the old allocator. If flag_new_regalloc is set, call
+ new allocator, instead of local_alloc(), global_alloc() and
+ friends.
+
+ * doc/invoke.texi: Document -fnew-ra.
+ * basic-block.h (FOR_ALL_BB): New.
+ * config/rs6000/rs6000.c (print_operand): Write small constants
+ as @l+80.
+
+ * df.c (read_modify_subreg_p): Narrow down cases for a rmw subreg.
+ (df_reg_table_realloc): Make size at least as large as max_reg_num().
+ (df_insn_table_realloc): Size argument now is absolute, not relative.
+ Changed all callers.
+
+ * gengtype.c (main): Add the pseudo-type "HARD_REG_SET".
+ * regclass.c (reg_scan_mark_refs): Ignore NULL rtx's.
+
+ 2002-06-20 Michael Matz <matz@suse.de>
+
+ * df.h (struct ref.id): Make unsigned.
+ * df.c (df_bb_reg_def_chain_create): Remove unsigned cast.
+
+ 2002-06-13 Michael Matz <matz@suse.de>
+
+ * df.h (DF_REF_MODE_CHANGE): New flag.
+ * df.c (df_def_record_1, df_uses_record): Set this flag for refs
+ involving subregs with invalid mode changes, when
+ CLASS_CANNOT_CHANGE_MODE is defined.
+
+ 2002-05-07 Michael Matz <matz@suse.de>
+
+ * reload1.c (fixup_abnormal_edges): Don't insert on NULL edge.
+
+ 2002-05-03 Michael Matz <matz@suse.de>
+
+ * sbitmap.c (sbitmap_difference): Accept sbitmaps of different size.
+
+ Sat Feb 2 18:58:07 2002 Denis Chertykov <denisc@overta.ru>
+
+ * regclass.c (regclass): Work with all regs which have sets or
+ refs.
+ (reg_scan_mark_refs): Count regs inside (clobber ...).
+
+ 2002-01-04 Michael Matz <matzmich@cs.tu-berlin.de>
+
+ * df.c (df_ref_record): Correctly calculate SUBREGs of hardregs.
+ (df_bb_reg_def_chain_create, df_bb_reg_use_chain_create): Only
+ add new refs.
+ (df_bb_refs_update): Don't clear insns_modified here, ...
+ (df_analyse): ... but here.
+
+ * sbitmap.c (dump_sbitmap_file): New.
+ (debug_sbitmap): Use it.
+
+ * sbitmap.h (dump_sbitmap_file): Add prototype.
+
+ 2001-08-07 Daniel Berlin <dan@cgsoftware.com>
+
+ * df.c (df_insn_modify): Grow the UID table if necessary, rather
+ than assume all emits go through df_insns_modify.
+
+ 2001-07-26 Daniel Berlin <dan@cgsoftware.com>
+
+ * regclass.c (reg_scan_mark_refs): When we increase REG_N_SETS,
+ increase REG_N_REFS (like flow does), so that regclass doesn't
+ think a reg is useless, and thus, not calculate a class, when it
+ really should have.
+
+ 2001-01-28 Daniel Berlin <dberlin@redhat.com>
+
+ * sbitmap.h (EXECUTE_IF_SET_IN_SBITMAP_REV): New macro, needed for
+ dataflow analysis.
+
+2002-07-15 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/7245
+ * config/i386/i386.c (const_int_1_31_operand): New.
+ * config/i386/i386.h (PREDICATE_CODES): Add it.
+ * config/i386/i386.md (ashlsi3_cmp, ashlsi3_cmp_zext, ashlhi3_cmp,
+ ashlqi3_cmp, ashrsi3_cmp, ashrsi3_cmp_zext, ashrhi3_cmp, ashrqi3_cmp,
+ lshrsi3_cmp, lshrsi3_cmp_zext, lshrhi3_cmp, lshrqi3_cmp): Use it.
+
+2002-07-14 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/7282
+ * config/rs6000/rs6000.md (floatsidf2): Enable for POWERPC64.
+ (floatunssidf2): Likewise.
+ (floatsidf_ppc64): New insn_and_split.
+ (floatunssidf_ppc64): Likewise.
+
+2002-07-14 Andreas Jaeger <aj@suse.de>
+
+ * config.gcc (sh64): Remove unused
+ target_requires_64bit_host_wide_int.
+
+2002-07-12 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c [CLEAR_RATIO]: New macro defining the maximum number
+ of move instructions to use when clearing memory, c.f. MOVE_RATIO.
+ [CLEAR_BY_PIECES]: New macro, using CLEAR_RATIO, to determine
+ whether clear_by_pieces should be used to clear storage.
+ (clear_storage): Use CLEAR_BY_PIECES instead of MOVE_BY_PIECES.
+
+ * doc/tm.texi: Document these two new target macros.
+
+2002-07-12 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("zero_extendsidi2"): Use D_REG only for
+ the scratch register.
+ ("*movhi2_push"): Accept Z_REG because a split pattern can make use
+ of it, forbid reload to use it.
+
+2002-07-12 Marek Michalkiewicz <marekm@amelek.gda.pl>
+
+ * config/avr/avr.c (test_hard_reg_class): Fix TEST_HARD_REG_BIT
+ usage on 64-bit hosts, return value was truncated to 32 bits.
+
+Fri Jul 12 00:49:36 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * simplify-rtx.c (simplify_subreg): Handle floating point
+ CONST_DOUBLEs. When an integer subreg of a smaller mode than
+ the element mode is requested, compute a subreg with an
+ integer mode of the same size as the element mode first.
+
+Thu Jul 11 22:02:57 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * combine.c (try_combine): When converting a paradoxical subreg
+ to an extension, take LOAD_EXTEND_OP into account.
+
+2002-07-11 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config.gcc (mips-sgi-irix6*o32): New configuration.
+
+ * configure.in (libgcc_visibility): Disable for mips-sgi-irix6*o32
+ configurations.
+ * configure: Regenerate.
+
+ * config/mips/iris6-o32-as.h: New file.
+ * config/mips/iris6-o32.h: New file.
+
+ * config/mips/iris5gas.h (TARGET_ASM_NAMED_SECTION): Define.
+ (NM_FLAGS): Define.
+ (HAVE_AS_SHF_MERGE): Undefine.
+
+ * config/mips/t-iris5-as: New file.
+ * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix5*): Use it.
+
+ * config/mips/t-iris6 (SHLIB_EXT, SHLIB_SOLINK, SHLIB_SONAME,
+ SHLIB_NAME, SHLIB_MAP, SHLIB_OBJS, SHLIB_SLIBDIR_QUAL, SHLIB_LINK,
+ SHLIB_INSTALL, SHLIB_MKMAP, SHLIB_MAPFILES, FPBIT, DPBIT,
+ dp-bit.c, fp-bit.c): Move ...
+ * config/mips/t-iris5-6: ... here.
+ New file, shared by IRIX 5 and IRIX 6.
+ * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix6*,
+ mips-sgi-irix5*): Use it.
+
+ * config/mips/iris6.h: Remove duplicate comment.
+
+ * config/mips/mips.c (TARGET_ASM_UNALIGNED_DI_OP) [TARGET_IRIX5 &&
+ !TARGET_IRIX6]: Define.
+ (mips_asm_file_start): Don't emit mdebug.<ABI> sections on IRIX 5/6.
+
+ * config/mips/mips.h (ASM_DECLARE_FUNCTION_NAME): Fix comment.
+
+2002-07-11 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.md (adddi3): Change predicate of operand 2 to adddi3_operand
+ and delete code to force constant to register.
+ * pa-protos.h (adddi3_operand): Add prototype.
+ * pa.c (adddi3_operand): New function.
+
+2002-07-11 Roger Sayle <roger@eyesopen.com>
+
+ * c-decl.c (duplicate_decls): Preserve the noreturn attribute on
+ non-ANSI builtin functions.
+
+Thu Jul 11 11:31:12 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * rtl.h (gen_rtx_CONST_VECTOR): Declare.
+ * gengenrtl.c (special_rtx): Check for CONST_VECTOR.
+ * emit-rtl.c (gen_rtx_CONST_VECTOR): New function.
+ (gen_const_vector_0): Use it.
+
+2002-07-11 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa.md (adddi3): For 32-bit targets, force constants to a register
+ if they don't fit in an 11-bit immediate. Change insn predicate to
+ arith11_operand. Remove comment.
+ * pa.c (cint_ok_for_move): Fix comment.
+ (emit_move_sequence): Don't directly split DImode constants on 32-bit
+ targets.
+
+2002-07-11 Tim Josling <tej@melbpc.org.au>
+
+ Remove front end hard coding from gengtype.c.
+
+ * Makefile.in
+ (STAGESTUFF): add gtyp-gen.h
+ (GTFILES): Remove front end specific files.
+ (GTFILES_FILES_LANGS): New, from configure..
+ (GTFILES_FILES_FILES): Likewise.
+ (GTFILES_LANG_DIR_NAMES): Likewise.
+ (GTFILES_SRCDIR): Likewise.
+ (gtyp-gen.h): Build from configure information.
+ (s-gtype): Remove command line parameters from gengtype.
+ (gengtype.o): Remove dependency on GTFILES. Depend on gtyp-gen.h.
+ (mostlyclean): Delete files generated by and for gengtype.
+
+ * c-config-lang.in: New file.
+
+ * configure.in (all_gtfiles_files_langs): New. Accumulate files
+ for each language.
+ (all_gtfiles_files_files): New. Accumulate language for each file
+ accumulated.
+ (gtfiles): Pick up value for C.
+ (srcdir): AC-SUBST this variable.
+ (all_gtfiles_files_langs): AC-SUBST this variable.
+ (all_gtfiles_files_files): AC-SUBST this variable.
+
+ * configure: Regenerate.
+
+ * gengtype-lex.l (parse_file): Make parameter const.
+
+ * gengtype.c (toplevel): include gtyp-gen.h.
+ (BASE_FILE_<language> unnamed enum): Delete.
+ (lang_names): Delete (replaced by gtyp-gen.h)
+ (lang_dir_names): From gtyp-gen.h, replaces lang_names; changed
+ all references.
+ (NUM_GT_FILES): New.
+ (NUM_LANG_FILES): New.
+ (srcdir_len): New.
+ (NUM_BASE_FILES): Change calculation.
+ (open_base_files): Change prototype to avoid warning.
+ (startswith): Delete.
+ (get_file_basename): Iterate through generated language list not
+ hard coded list.
+ (get_base_file_bitmap): Use generated list of files and languages.
+ (close_output_files): Add prototype to rmove warning.
+ (main): Iterate through list of generated files from gtyp-gen.h
+ rather than command line paramaters. Ignore duplicated file
+ names.
+
+ * gengtype.h (parse_file): Amend prototype for const parameter.
+
+ * doc/sourcebuild.texi: Document gtfiles variable.
+
+ * doc/gty.texi: Document changes to gtfiles variable for front
+ ends.
+
+ * objc/config-lang.in (gtfiles): Add files needed for objc front
+ end.
+
+2002-07-10 Roger Sayle <roger@eyesopen.com>
+
+ PR c/2454
+ * combine.c (nonzero_bits): LOAD_EXTEND_OP should only apply
+ to SUBREGs of MEMs. (num_sign_bit_copies): Likewise.
+
+2002-07-10 Roger Sayle <roger@eyesopen.com>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * builtins.def: Make the argument types of abort and exit
+ independent of the front-end.
+
+2002-07-11 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/linux64.h (ASM_SPEC): Define.
+
+2002-07-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (emit_frame_save): New.
+ (rs6000_frame_related): Replace reg2 before reg.
+ (rs6000_emit_prologue): Use emit_frame_save for saving gprs, fprs,
+ and eh_return registers.
+
+2002-07-10 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ Revert all patches for optimization of Complex .op. Real.
+ * complex_part_zero_p: Remove
+ * expand_cmplxdiv_straight: Replace complex_part_zero_p(x)
+ with x.
+ * expand_cmplxdiv_wide: Ditto.
+ * expand_binop: Ditto.
+
+2002-07-10 Marek Michalkiewicz <marekm@amelek.gda.pl>
+
+ * config/avr/avr.md: Fix two 0x80000000 constants to make them
+ negative also on 64-bit hosts.
+
+ Default to -fno-reorder-blocks when optimizing for size.
+ * config/avr/avr-protos.h (avr_optimization_options): Declare.
+ * config/avr/avr.c (avr_optimization_options): New function.
+ * config/avr/avr.h (OPTIMIZATION_OPTIONS): New.
+
+ Optimize returning from simple functions.
+ * config/avr/avr-protos.h (avr_simple_epilogue): Declare.
+ * config/avr/avr.c (avr_simple_epilogue): New function.
+ * config/avr/avr.md (return): New insn.
+
+2002-07-10 Douglas B Rupp <rupp@gnat.com>
+
+ * config/i386/i386.c (ix86_svr3_asm_out_constructor): Add
+ HAS_INIT_SECTION to protection.
+
+2002-07-10 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/invoke.texi (Debugging Options): Mention that -gdwarf is
+ deprecated.
+
+Wed Jul 10 19:50:03 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * combine.c (gen_lowpart_for_combine): Handle vector modes.
+ Supply non-VOID mode to simplify_gen_subreg.
+
+Wed Jul 10 18:48:55 CEST 2002 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_init_mmx_sse_builtins): Fix thinko.
+
+2002-07-10 Jeffrey A Law <law@redhat.com>
+
+ * mn10200.c (expand_prologue): Create REG_MAYBE_DEAD notes
+ as appropriate.
+
+ * mn10200.c (expand_epilogue): Fix test to determine which scratch
+ register to use.
+
+Wed Jul 10 16:06:00 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * cse.c (cse_insn): Supply proper SUBREG_BYTE to simplify_gen_subreg.
+ Get mode from dest.
+ If simplify_gen_subreg fails, try next equivalent.
+
+2002-07-09 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * diagnostic.h: #include location.h
+ (location_t): Move definition to..
+ * location.h: ... here. New file.
+ * tree.h: #include location.h
+ (DECL_SOURCE_LOCATION): New macro.
+ (DECL_SOURCE_FILE): Use.
+ (DECL_SOURCE_LINE): Likewise.
+ (struct tree_decl): REplace filename and linenum with locus.
+ * Makefile.in (TREE_H): add location.h
+ (diagnostic.o): Depends on gt-location.h
+ (gt-location.h): Depends on s-gtype
+
+2002-07-09 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * config/rs6000/aix.h: Convert CPP_PREDEFINES to
+ TARGET_OS_CPP_BUILTINS.
+ * config/rs6000/aix31.h: Likewise.
+ * config/rs6000/aix41.h: Likewise.
+ * config/rs6000/aix43.h: Likewise.
+ * config/rs6000/aix51.h: Likewise.
+ * config/rs6000/beos.h: Likewise.
+ * config/rs6000/darwin.h: Likewise.
+ * config/rs6000/eabi.h: Likewise.
+ * config/rs6000/eabisim.h: Likewise.
+ * config/rs6000/linux.h: Likewise.
+ * config/rs6000/linux64.h: Likewise.
+ * config/rs6000/lynx.h: Likewise.
+ * config/rs6000/mach.h: Likewise.
+ * config/rs6000/rtems.h: Likewise.
+ * config/rs6000/sysv4.h: Likewise.
+ * config/rs6000/vxppc.h: Likewise.
+
+2002-07-09 Devang Patel <dpatel@apple.com>
+ * objc/objc-act.c (adjust_type_for_id_default): Fix my previous patch.
+ Do not allow ObjC objects as a parameter type for Objective-C methods.
+ My previous patch restricted 'struct' also.
+
+2002-07-09 Neil Booth <neil@daikokuya.co.uk>
+
+ * cpperror.c (cpp_error): Default to directive_line within
+ directives here.
+ * cppexp.c (cpp_interpret_integer): Only use traditional
+ number semantics in directives.
+ * cpplib.c (prepare_directive_trad): Don't reset pfile->line.
+ (do_include_common): Similarly.
+ * cpptrad.c (scan_out_logical_line): Implement accurate
+ quoting of <> in #include.
+ * doc/cpp.texi: Update.
+
+Tue Jul 9 22:37:44 2002 Stephen Clarke <stephen.clarke@superh.com>
+ J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (sh_adjust_cost): Special handling of SHMEDIA code.
+ * sh.md (attribute issues): Replace with:
+ (attribute pipe_model). All users changed.
+ (attribute type): Change pt / ptabs to pt_media / ptabs_media.
+ All users changed.
+ (function units sh5issue, sh5fds): New.
+ (attribute is_mac_media): New.
+ (adddi3_media, subdi3_media, divsi3_i1_media, anddi3): Add type.
+ (andcdi3, iordi3, xordi3, ashldi3_media, lshrdi3_media): Likewise.
+ (ashrdi3_media, negdi_media, extendsidi2, movqi_media): Likewise.
+ (movhi_media, shori_media, movv2sf_i, jump_media): Likewise.
+ (call_media, call_value_media, sibcall_media): Likewise.
+ (casesi_jump_media, casesi_shift_media, casesi_load_media): Likewise.
+ (return_media_i, addsf3_media, subsf3_media, mulsf3_media): Likewise.
+ (mac_media, divsf3_media, floatdisf2, floatsisf2_media): Likewise.
+ (fix_truncsfdi2, fix_truncsfsi2_media, cmpeqsf_media): Likewise.
+ (cmpgtsf_media, cmpgesf_media, cmpunsf_media, negsf2_media): Likewise.
+ (sqrtsf2_media, abssf2_media, adddf3_media, subdf3_media): Likewise.
+ (muldf3_media, divdf3_media, floatdidf2, floatsidf2_media): Likewise.
+ (fix_truncdfdi2, fix_truncdfsi2_media, cmpeqdf_media): Likewise.
+ (cmpgtdf_media, cmpgedf_media,cmpundf_media, negdf2_media): Likewise.
+ (sqrtdf2_media, absdf2_media, extendsfdf2_media): Likewise.
+ (truncdfsf2_media): Likewise.
+ (movsi_media, movsi_media_nofpu, movdi_media): Use new types.
+ (movdi_media_nofpui, movdf_media, movdf_media_nofpu): Likewise.
+
+Tue Jul 9 21:39:50 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (PREDICATE_CODES): Add general_extend_operand and inqhi_operand.
+ * sh.c (general_extend_operand, inqhi_operand): New functions.
+ * sh.md (cmpeqdi_media, cmpgtdi_media, cmpgtudi_media): Collapse
+ alternatives using 'N' modifier. Add type.
+ (adddi3z_media): Likewise. Enable generator function generation.
+ (movdicc_false, movdicc_true, addsi3_media, subsi3_media): Use more
+ exact predicates / constraints. Add type.
+ (subsi3): Allow 0 for SHMEDIA.
+ (udivsi3_i4_media): Use match_operand for input values
+ rather than hard registers.
+ (udivsi3 - TARGET_SHMEDIA_FPU case): Don't ferry values
+ unnecessarily through hard registers. Keep copies of pseudo
+ registers outside of the libcall sequence.
+ (mulsidi3_media, umulsidi3_media): Use more exact predicates. Add type.
+ (ashlsi3_media, ashrsi3_media, lshrsi3_media): Likewise.
+ (zero_extendsidi2, zero_extendhidi2, zero_extendqidi2): Likewise.
+ (extendhidi2, extendqidi2): Likewise.
+ (andsi3_compact): Name.
+ (andcdi3): Enable generator function generation.
+ (zero_extendhisi2, zero_extendqisi2): Rename to
+ (zero_extendhisi2_compact, zero_extendqisi2_compact).
+ (extendhisi2, extendqisi2): Rename to
+ (extendhisi2_compact, extendqisi2_compact).
+ (rotldi3, rotldi3_mextr, rotrdi3, rotrdi3_mextr): New patterns.
+ (loaddi_trunc, zero_extendhisi2, zero_extendhisi2_media): Likewise.
+ (zero_extendhisi2_media+1, zero_extendqisi2): Likewise.
+ (zero_extendqisi2_media, extendhisi2, extendhisi2_media): Likewise.
+ (extendhisi2_media, extendhisi2_media+1, extendqisi2): Likewise.
+ (extendqisi2_media, extendqisi2_media+1, truncdisi2): Likewise.
+ (truncdihi2, truncdiqi2, reload_inqi, reload_inhi): Likewise.
+ (shmedia32_initialize_trampoline_big): Likewise.
+ (shmedia32_initialize_trampoline_little): Likewise.
+ (nsb, nsbsi, nsbdi, ffsdi2, ffssi2, byterev): Likewise.
+ (negdi2): Remove spurious T clobber.
+ (zero_extendhidi2+1, extendhidi2+1, extendqidi2+1): Handle TRUNCATE.
+ (movsi_media, movsi_media_nofpu): Remove spurious *k after b.
+ (movdi_media, movdi_media_nofpu, pt, ptb): Likewise.
+ (movsi_media_nofpu+2, movhi_media+1): Only do split after reload.
+ (ic_invalidate_line_media): Write back data cache before invalidating
+ instruction cache. Add type.
+ (movsf_media): Sign-extend when the destination is a general
+ purpose register. Add type.
+ (bgt_media, bge_media, bgtu_media, bgeu_media, blt_media_i): Allow 0.
+ (casesi_worker_0+1): Only increment ref count for proper label.
+ (casesi_worker_0+2): Likewise.
+
+2002-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * dwarfout.c (dwarfout_init): Warn that DWARF1 is deprecated.
+
+2002-07-09 Steve Ellcey <sje@cup.hp.com>
+
+ * gcc/except.c (expand_eh_region_end_cleanup): Change exception pointer
+ from Pmode to ptr_mode.
+ (get_exception_pointer): Ditto.
+ (connect_post_landing_pads): Ditto.
+ (dw2_build_landing_pads): Ditto.
+
+2002-07-08 Steve Ellcey <sje@cup.hp.com>
+ * gcc/c-pragma.h (add_to_renaming_pragma_list): New function.
+ * gcc/c-pragma.c (add_to_renaming_pragma_list): New function.
+ (handle_pragma_redefine_extname): Change to use new function.
+
+2002-07-08 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (combine_simplify_rtx): Add an explicit cast
+ to avoid signed/unsigned comparison warning.
+ (simplify_if_then_else): Likewise.
+ (extended_count): Likewise.
+ (simplify_shift_const): Likewise.
+ (simplify_comparison): Likewise.
+
+2002-07-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md: Add imadd type. Update scheduler description
+ to use imadd as well as imul.
+ (*mul_acc_si, *madsi): Change imul alternatives to imadd.
+ (*mul_acc_di, *mul_acc_64bit_di): Likewise.
+ (*mul_sub_si): Likewise for first alternative. Change second
+ alternative from imul to multi.
+
+2002-07-07 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.c (c_common_post_options): Update prototype;
+ don't init backends if preprocessing only.
+ * langhooks-def.h (LANG_HOOKS_POST_OPTIONS): Update.
+ * langhooks.h (struct lang_hooks): Update post_options to
+ return a boolean.
+ * toplev.c (parse_options_and_default_flags, do_compile,
+ lang_independent_init): Update prototypes. Allow the
+ front end to specify that there is no need to initialize
+ the back end.
+ (general_init): Move call to hex_init here...
+ (toplev_main): ...from here. Pass flag for back end init
+ suppression.
+
+Sun Jul 7 20:38:38 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (PRINT_OPERAND_PUNCT_VALID_P): Allow '\''.
+ (PREDICATE_CODES): Add entries for equality_comparison_operator,
+ greater_comparison_operator and less_comparison_operator.
+ * sh.c (print_operand): Add '\'' code. Make 'o' handle
+ more operators.
+ (equality_comparison_operator): New function.
+ (greater_comparison_operator, less_comparison_operator): Likewise.
+ * sh.md (beq_media_i): Disable generator function generation.
+ Use match_operator to handle a whole class of comparisons. Add
+ modifier in output template to provide branch prediction. Add type.
+ (bgt_media_i, ble_media_i): Likewise. Allow zero operands.
+ (bne_media_i, bge_media_i, bgtu_media_i, bgeu_media_i): Delete.
+ (blt_media_i, bleu_media_i, bltu_media_i): Likewise.
+ (bgt, blt, ble, bge, bgtu, bltu, bgeu, bleu): Allow zero operands.
+
+2002-07-07 Hans-Peter Nilsson <hp@bitrange.com>
+
+ Emit MMIX function prologue and epilogue as rtl.
+ * config/mmix/mmix.md ("call"): Use mmix_get_hard_reg_initial_val,
+ not unprototyped get_hard_reg_initial_val.
+ ("call_value", "nonlocal_goto_receiver"): Ditto.
+ ("return"): Make define_expand. Move real insn to...
+ ("*expanded_return"): New pattern.
+ ("prologue", "epilogue"): New define_expands.
+ * config/mmix/mmix.h (MMIX_rO_REGNUM): New macro.
+ (struct machine_function): New member in_prologue.
+ (FIRST_PSEUDO_REGISTER): Adjust for including rO as register.
+ (FIXED_REGISTERS, CALL_USED_REGISTERS): Ditto.
+ (MMIX_MMIXWARE_ABI_REG_ALLOC_ORDER): Ditto.
+ (MMIX_GNU_ABI_REG_ALLOC_ORDER, REG_CLASS_CONTENTS): Ditto.
+ (REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES): Ditto.
+ (LOCAL_REGNO): Define. Adjust comment.
+ * config/mmix/mmix.c (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS):
+ Consider regs_ever_live[MMIX_rJ_REGNUM], not just
+ leaf_function_p.
+ (MMIX_OUTPUT_REGNO): Don't translate registers while outputting
+ the prologue.
+ (mmix_target_asm_function_prologue): Make static. Just mark that
+ the prologue is being emitted. Move guts to...
+ (mmix_expand_prologue): New function. Adjust for emitting
+ prologue as rtl. For sizes, use HOST_WIDE_INT only.
+ (mmix_target_asm_function_epilogue): Make static. Simply emit a
+ \n. Move guts to...
+ (mmix_expand_epilogue): New function. Adjust for emitting
+ epilogue as rtl. For sizes, use HOST_WIDE_INT only.
+ (mmix_target_asm_function_end_prologue): Mark that the prologue
+ has ended.
+ (TARGET_ASM_FUNCTION_END_PROLOGUE): Define.
+ (mmix_conditional_register_usage): Improve comments.
+ (mmix_local_regno): New function.
+ (mmix_emit_sp_add, mmix_get_hard_reg_initial_val): Ditto.
+ * config/mmix/mmix-protos.h (mmix_local_regno): Prototype.
+ (mmix_expand_prologue, mmix_expand_epilogue): Ditto.
+ (mmix_get_hard_reg_initial_val): Ditto.
+
+2002-07-06 Andreas Jaeger <aj@suse.de>
+
+ * toplev.c (set_fast_math_flags): Don't use ISO C style function
+ definitions.
+ * gengtype.c (open_base_files): Likewise.
+ (close_output_files): Likewise.
+ * tracer.c (find_best_predecessor): Likewise.
+ (find_best_successor): Likewise.
+ (ignore_bb_p): Likewise.
+
+2002-07-05 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/7099
+ * builtin-attrs.def: Define new attribute lists for use in
+ builtins.def.
+ * builtins.def [DEF_BUILTIN]: Modify to take an additional
+ ATTRS argument, an enumerated value defined in builtin-attrs.def
+ that represents the attribute list for the builtins. Modify
+ all builtin functions to pass an appropriate attribute list.
+ Specify "abort", "exit", "_exit" and "_Exit" builtins here with
+ their required noreturn attributes.
+ * tree.h (enum_builtin_function): Ignore the additional parameter
+ to DEF_BUILTIN.
+ * builtins.c (built_in_names): Likewise.
+ * c-common.c: (builtin_function_2): Replace the "int noreturn_p"
+ argument with a tree representing the functions attribute list.
+ Pass this "attrs" argument to builtin_function. No longer handle
+ the noreturn_p processing manually.
+ (built_in_attributes): Move the definitions from builtin-attrs.def
+ before c_common_nodes_and_builtins.
+ (c_common_nodes_and_builtins): Handle the new ATTRS parameter in
+ DEF_BUILTIN, passing it to both builtin_function and the changed
+ builtin_function_2.
+
+ * doc/extend.texi: Document __builtin_abort, __builtin_exit,
+ __builtin__exit and __builtin__Exit.
+
+2002-07-05 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("*movqi_68hc12"): Avoid allocating
+ QI mode registers in soft registers.
+ ("zero_extendqihi2"): Do not take into account soft registers
+ for register allocation (use '*' constraint).
+
+2002-07-05 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("*ashlsi3"): Avoid saving y if we know
+ it is dead.
+ ("*ashrsi3"): Likewise.
+ ("*lshrsi3"): Likewise.
+
+2002-07-05 Vladimir Makarov <vmakarov@redhat.com>
+
+ * genautomata.c (output_max_insn_queue_index_def): Take latencies
+ into account.
+
+2002-07-05 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md (peephole2): New peephole2 to optimize
+ address computation and memory moves.
+
+2002-07-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6706
+ * dwarfout.c (output_reg_number): Fix warning message.
+ (output_bound_representation): Check SAVE_EXPR_RTL is not NULL
+ before using it.
+
+2002-07-05 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * gcc/gcc.c (asm_debug): Move initialization ...
+ (init_spec): ... here.
+
+2002-07-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-parse.in (extdef): Append ';'.
+ (old_style_parm_decls): Append ';'.
+
+2002-07-04 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in: Correct typos: gcc_cv_as_gdwarf2_debug_flag to
+ gcc_cv_as_gdwarf2_flag and gcc_cv_as_gstabs_debug_flag
+ to gcc_cv_as_gstabs_flag.
+ * configure: Rebuilt.
+
+2002-07-04 Geoffrey Keating <geoffk@redhat.com>
+
+ * ggc.h (ggc_add_root): Document as obsolete.
+
+Thu Jul 4 07:58:01 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (mshfhi_b, mshflo_b, mshfhi_l, mshflo_l, mshfhi_w): Add DONE.
+ (mshflo_w): Likewise.
+
+Thu Jul 4 07:36:29 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * simplify-rtx.c (simplify_subreg): Reduce problem of finding
+ vector mode subregs of constants to finding integer mode
+ subregs of constants.
+ * cse.c (cse_insn): Use simplify_gen_subreg.
+ * convert.c (convert_to_integer): Don't strip a NOP_EXPR
+ From a vector mode expression of different size than the
+ target mode.
+
+2002-07-03 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/linux.h: Add #undef for SUBTARGET_CPP_SPEC.
+ * config/mips/mips.h: Remove deprecated -m<processor> options
+ and cc1_cpu_spec associated.
+ (CONSTANT_ADDRESS_P): Fix last patch.
+ (ASM_DECLARE_FUNCTION_NAME): Declare. Fix comment.
+ * config/mips/mips.md (bungt, bunge, sungt_df, sungt_sf, sunge_df,
+ sunge_sf): Remove.
+
+2002-07-03 Stan Shebs <shebs@apple.com>
+
+ * config/darwin.h (APPLE_CC): Remove, not meaningful in FSF GCC.
+ (STRINGIFY_THIS, REALLY_STRINGIFY): Remove.
+ (CPP_SPEC): Remove insertion of APPLE_CC definition.
+
+2002-07-03 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (struct_undo): Change types of recorded substitutions
+ to be either "int" or "rtx", instead of "unsigned int" and "rtx".
+ (do_SUBST_INT): Change types of the substitution from unsigned int
+ to int, to avoid compilation warning from SUBST_INT's only caller.
+
+ (make_extraction): Add cast to avoid compilation warning.
+ (force_to_mode): Remove cast to avoid compilation warning.
+
+2002-07-03 Eric Botcazou <ebotcazou@multimania.com>
+ Jeff Law <law@redhat.com>
+
+ * i386.md (length_immediate attribute): Fix typo.
+ (length_address attribute): Likewise.
+ (modrm attribute): Set it to 0 for immediate call instructions.
+ (jcc_1 pattern): Set modrm attribute to 0.
+ (jcc_2 pattern ): Likewise.
+ (jump pattern): Likewise.
+ (doloop_end_internal pattern): Explicitly set length.
+ (leave pattern): Fix typo.
+ (leave_rex64 pattern): Likewise.
+
+2002-07-03 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (fix_truncdfsi2_internal): Ignore DImode
+ in FPR as preference.
+ (fctiwz): Same.
+ (floatdidf2, fix_truncdfdi2): Same.
+ (floatdisf2, floatditf2, fix_trunctfdi2): Same.
+ (floatditf2): Same.
+ (floatsitf2, fix_trunctfsi2): SImode in GPR.
+ (ctrdi): Remove FPR alternative and splitter.
+
+2002-07-03 Will Cohen <wcohen@redhat.com>
+
+ * config/i386/i386.c (x86_integer_DFmode_moves): Disable for PPro.
+
+Wed Jul 3 10:24:16 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * optabs.c (expand_vector_binop): Don't store using a SUBREG smaller
+ than UNITS_PER_WORD, unless this is little endian and the first unit
+ in this word. Let extract_bit_field decide how to load an element.
+ Force arguments to matching mode.
+ (expand_vector_unop): Likewise.
+
+ * simplify-rtx.c (simplify_subreg): Don't assume that all vectors
+ consist of word_mode elements.
+ * c-typeck.c (build_binary_op): Allow vector types for BIT_AND_EXPR,
+ BIT_ANDTC_EXPR, BIT_IOR_EXPR and BIT_XOR_EXPR.
+ (build_unary_op): Allow vector types for BIT_NOT_EPR.
+ * emit-rtl.c (gen_lowpart_common): Use simplify_gen_subreg for
+ CONST_VECTOR.
+ * optabs.c (expand_vector_binop): Try to perform operation in
+ smaller vector modes with same inner size. Add handling of AND, IOR
+ and XOR. Reject expansion to inner-mode sized scalars when using
+ OPTAB_DIRECT. Use simplify_gen_subreg on constants.
+ (expand_vector_unop): Try to perform operation in smaller vector
+ modes with same inner size. Add handling of one's complement.
+ When there is no vector negate operation, try a vector subtract
+ operation. Use simplify_gen_subreg on constants.
+ * simplify-rtx.c (simplify_subreg): Add capability to convert vector
+ constants into smaller vectors with same inner mode, and to
+ integer CONST_DOUBLEs.
+
+2002-07-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-parse.in (parsing_iso_function_signature): New variable.
+ (extdef_1): New, copied from...
+ (extdef): ... here. Reset parsing_iso_function_signature.
+ (old_style_parm_decls): Reset parsing_iso_function_signature.
+ (old_style_parm_decls_1): New, copied from old_style_parm_decls.
+ Warn about ISO C style function definitions.
+ (nested_function, notype_nested_function): Reset
+ parsing_iso_function_signature.
+ (parmlist_2): Set parsing_iso_function_signature.
+
+ * doc/invoke.texi (-Wtraditional): Document new behavior.
+
+2002-07-02 Chris Demetriou <cgd@broadcom.com>
+
+ * config.gcc (mips*el-*-*): Use tm_defines to set
+ TARGET_ENDIAN_DEFAULT, rather than including mips/little.h.
+ * config/mips/little.h: Remove.
+
+2002-07-02 Devang Patel <dpatel@apple.com>
+
+ * objc/objc-act.c (adjust_type_for_id_default): Do not allow an
+ object as parameter. Prevent something like 'NSObject' to be
+ used as the type for a method argument.
+
+2002-07-03 Neil Booth <neil@daikokuya.co.uk>
+
+ * cpptrad.c: Update comment.
+
+2002-07-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * doc/cpp.texi: Update for traditional preprocessing changes.
+ * goc/cppopts.texi: Similarly.
+
+2002-07-02 Ziemowit Laski <zlaski@apple.com>
+
+ * c-parse.in (designator): Enable designated initializers if ObjC.
+ (objcmessageexpr): Remove references to objc_receiver_context.
+ * objc/objc-act.h (objc_receiver_context): Remove decl.
+ * objc/objc-act.c (objc_receiver_context): Remove.
+ (lookup_objc_ivar): Test objc_method_context instead of
+ objc_receiver_context.
+
+Tue Jul 2 18:45:45 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (print_operand, case 'N'): Allow zero vector.
+ (arith_reg_or_0_operand): Likewise.
+ (zero_vec_operand): Check for CONST_VECTOR, not PARALLEL.
+ * sh.h (CONST_COSTS): 0 has 0 cost. Check OUTER_CODE for
+ IOR, XOR, PLUS and SET and take their respective constant
+ ranges into account.
+ (PREDICATE_CODES, arith_reg_or_0_operand): Can be CONST_VECTOR.
+ * sh.md (subdi3, subdi3_media): Allow zero operand.
+ (movv8qi_i+3): Only vector that is not split is the zero vector.
+ Fix operand 3 to simplify_subreg.
+ (movv2si_i): Split alternative 1.
+ (mshfhi_l_di_rev+1): New splitter.
+
+2002-07-02 Neil Booth <neil@daikokuya.co.uk>
+
+ PR preprocessor/7029
+ * cppinit.c (cpp_handle_option): Suppress warnings with an
+ implicit "-w" for "-M" and "-MM".
+ * doc/cppopts.texi: Update.
+
+2002-07-01 Roger Sayle <roger@eyesopen.com>
+
+ * config/sh/sh.c (sh_media_init_builtins): Change use of poisoned
+ identifier "bzero" to "memset". Pass extra NULL_TREE argument to
+ builtin_function.
+
+2002-07-02 Alan Modra <amodra@bigpond.net.au>
+
+ * README.Portability: Fix typos.
+
+2002-07-01 Hans-Peter Nilsson <hp@axis.com>
+
+ PR target/7177
+ * config/cris/cris.h (LEGITIMIZE_RELOAD_ADDRESS): Correct number
+ of indirections for register inside sign-extended mem part.
+
+2002-07-01 Roger Sayle <roger@eyesopen.com>
+
+ * tree.h: Modify builtin_function interface to take an extra
+ argument ATTRS, which is a tree representing an attribute list.
+
+ * c-decl.c (builtin_function): Accept additional parameter.
+ * objc/objc-act.c (builtin_function): Likewise.
+ * f/com.c (builtin_function): Likewise.
+ * java/decl.c (builtin_function): Likewise.
+ * ada/utils.c (builtin_function): Likewise.
+ * cp/decl.c (builtin_function): Likewise.
+ (builtin_function_1): Likewise.
+
+ * c-common.c (c_common_nodes_and_builtins): Pass an additional
+ NULL_TREE argument to builtin_function. (builtin_function_2):
+ Likewise.
+ * cp/call.c (build_java_interface_fn_ref): Likewise.
+ * objc/objc-act.c (synth_module_prologue): Likewise.
+ * java/decl.c (java_init_decl_processing): Likewise.
+ * f/com.c (ffe_com_init_0): Likewise.
+
+ * config/alpha/alpha.c (alpha_init_builtins): Pass an additional
+ NULL_TREE argument to builtin_function.
+ * config/arm/arm.c (def_builtin): Likewise.
+ * config/c4x/c4x.c (c4x_init_builtins): Likewise.
+ * config/i386/i386.c (def_builtin): Likewise.
+ * config/ia64/ia64.c (def_builtin): Likewise.
+ * config/rs6000/rs6000.c (def_builtin): Likewise.
+
+2002-07-01 Zack Weinberg <zack@codesourcery.com>
+
+ * config/ip2k/t-ip2k: Remove LIBGCC1, CROSS_LIBGCC1, and LIBGCC1_TEST.
+ * config/mips/t-isa3264: Likewise.
+ * config/mmix/t-mmix: Likewise.
+
+2002-07-01 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * emit-rtl.c (init_emit_once): Add missing cast to HOST_WIDE_INT.
+
+2002-07-01 Roger Sayle <roger@eyesopen.com>
+
+ PR opt/4046
+ * fold-const.c (fold) [COND_EXPR]: Simplify A ? 0 : 1 to !A,
+ A ? B : 0 to A && B and A ? B : 1 into !A || B if both A and
+ B are truth values.
+
+2002-07-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/mmix/t-mmix: Eliminate last reference to LIBGCC1_TEST.
+
+2002-07-01 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * README.Portability (Function prototypes): Give an example of
+ declaring and defining a function with no arguments.
+
+ * README.Portability (Function prototypes): Document new
+ variable-argument function macros.
+
+Mon Jul 1 19:55:17 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (langhooks.h): Include.
+ (sh_init_builtins, sh_media_init_builtins): New functions.
+ (sh_expand_builtin, arith_reg_dest,and_operand): Likewise.
+ (mextr_bit_offset, extend_reg_operand, zero_vec_operand): Likewise.
+ (sh_rep_vec, sh_1el_vec, sh_const_vec): Likewise.
+ (builtin_description): New struct tag.
+ (signature_args, bdesc): New arrays.
+ (TARGET_INIT_BUILTINS, TARGET_EXPAND_BUILTIN): Undef / define.
+ (print_operand): Add 'N' modifier.
+ * sh.h (VECTOR_MODE_SUPPORTED_P): Add SHmedia vector modes.
+ (EXTRA_CONSTRAINT_U, EXTRA_CONSTRAINT_W): New macros.
+ (EXTRA_CONSTRAINT): Add 'U' and 'W' cases.
+ (CONST_COSTS): Add special case for SHmedia AND.
+ (PREDICATE_CODES): Add and_operand, arith_reg_dest,
+ extend_reg_operand, extend_reg_or_0_operand, mextr_bit_offset,
+ sh_const_vec, sh_1el_vec, sh_rep_vec, zero_vec_operand.
+ target_operand can also be const or unspec.
+ * sh.md (UNSPEC_INIT_TRAMP, UNSPEC_FCOSA UNSPEC_FSRRA): New constants.
+ (UNSPEC_FSINA, UNSPEC_NSB, UNSPEC_ALLOCO): Likewise.
+ (attribute type): Add new types.
+ (anddi3): Add splitter.
+ (movdi_const_16bit+1): Add code to handle vector constants and
+ bitmasks efficiently.
+ (shori_media): Have generator function made.
+ (movv8qi, movv8qi_i, movv8qi_i+1, movv8qi_i+2): New patterns.
+ (movv8qi_i+3, movv2hi, movv2hi_i, movv4hi, movv4hi_i): Likewise.
+ (movv2si, movv2si_i, absv2si2, absv4hi2, addv2si3, addv4hi3): Likewise.
+ (ssaddv2si3, usaddv8qi3, ssaddv4hi3, negcmpeqv8qi): Likewise.
+ (negcmpeqv2si, negcmpeqv4hi, negcmpgtuv8qi, negcmpgtv2si): Likewise.
+ (negcmpgtv4hi, mcmv, mcnvs_lw, mcnvs_wb, mcnvs_wub): Likewise.
+ (mextr_rl, mextr_lr, mextr1, mextr2, mextr3, mextr4, mextr5): Likewise.
+ (mextr6, mextr7, mmacfx_wl, mmacfx_wl_i, mmacnfx_wl): Likewise.
+ (mmacnfx_wl_i, mulv2si3, mulv4hi3, mmulfx_l, mmulfx_w): Likewise.
+ (mmulfxrp_w, mmulhi_wl, mmullo_wl, mmul23_wl, mmul01_wl): Likewise.
+ (mmulsum_wq, mmulsum_wq_i, mperm_w, mperm_w_little): LIkewise.
+ (mperm_w_big, mperm_w0, msad_ubq, msad_ubq_i, mshalds_l): Likewise.
+ (mshalds_w, ashrv2si3, ashrv4hi3, mshards_q, mshfhi_b): Likewise.
+ (mshflo_b, mshf4_b, mshf0_b, mshfhi_l, mshflo_l, mshf4_l): Likewsie.
+ (mshf0_l, mshfhi_w, mshflo_w, mshf4_w, mshf0_w, mshfhi_l_di): Likewise.
+ (mshfhi_l_di_rev, mshflo_l_di, mshflo_l_di_rev): Likewise.
+ (mshflo_l_di_x, mshflo_l_di_x_rev, ashlv2si3, ashlv4hi3): Likewise.
+ (lshrv2si3, lshrv4hi3, subv2si3, subv4hi3, sssubv2si3): Likewise.
+ (ussubv8qi3, sssubv4hi3, fcosa_s, fsina_s, fipr, fsrra_s): Likewise.
+ (ftrv): Likewise.
+
+ (fpu_switch+1, fpu_switch+2): Remove constraint.
+
+2002-07-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree.c (build_function_type_list): Update function comment.
+ Rename first argument to return_type.
+
+2002-07-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Remove all trace of tradcpp.c, tradcpp.h,
+ tradcif.y and related files.
+
+2002-07-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * cpptrad.c (skip_whitespace): Pass pointer to prior char.
+
+2002-07-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mips.h (FUNCTION_ARG_REGNO_P): Fix parentheses.
+
+See ChangeLog.7 for earlier changes.
diff --git a/contrib/gcc/ChangeLog.9 b/contrib/gcc/ChangeLog.9
new file mode 100644
index 000000000000..8eed245136d1
--- /dev/null
+++ b/contrib/gcc/ChangeLog.9
@@ -0,0 +1,21488 @@
+2003-06-30 Bruno Haible <bruno@clisp.org>
+
+ PR middle-end/6578
+ * libgcc2.c (__subvsi3): Remove simplification that would not work
+ when subtracting -0x80000000.
+ (__subvdi3): Remove simplification that would return a wrong result.
+ (__mulvsi3): Fix overflow check.
+ (__absvdi2): Fix simplification that would return a wrong result.
+ (__mulvdi3): Fix overflow check.
+
+2003-06-30 Jeff Law <law@redhat.com>
+
+ * stmt.c (any_pending_cleanups): Lose argument THIS_CONTOUR, it
+ was always passed in the value '1'. Simplify body appropriately.
+ * tree.h (any_pending_cleanups): Corresponding changes.
+ * calls.c: (expand_call): Corresponding changes.
+
+2003-06-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (distribute_notes): Don't bother REG_WAS_0.
+ * cse.c (cse_insn): Likewise.
+ * final.c (final_scan_insn): Likewise.
+ * jump.c (duplicate_loop_exit_test): Likewise.
+ * rtl.c (reg_note_name): Remove REG_WAS_0.
+ * rtl.h (REG_WAS_0): Remove.
+ * unroll.c (final_reg_note_copy): Don't bother REG_WAS_0.
+ * config/avr/avr.c (output_movqi): Don't use reg_was_0.
+ (output_movhi): Likewise.
+ (output_movsisf): Likewise.
+ (reg_was_0): Remove.
+ * config/m68hc11/m68hc11.c (m68hc11_gen_movhi): Don't use
+ REG_WAS_0.
+ (m68hc11_gen_movqi): Likewise.
+ * config/vax/vax-protos.h: Remove the prototype for
+ reg_was_0_p.
+ * config/vax/vax.c (follows_p): Remove.
+ (reg_was_0_p): Likewise.
+ * config/vax/vax.md (movsi): Don't use reg_was_0_p.
+ (movhi): Likewise.
+ (movqi): Likewise.
+ * doc/rtl.texi (REG_WAS_0): Remove.
+
+2003-06-30 Mark Mitchell <mark@codesourcery.com>
+
+ * config/rs6000/spe.h (__ev_set_spefscr_frmc): Set the flag.
+
+2003-06-30 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/lib1funcs.asm: Use "xtensa-config.h" from
+ top-level include directory.
+ * config/xtensa/lib2funcs.S: Likewise.
+ * config/xtensa/xtensa.h: Likewise.
+ * config/xtensa/xtensa-config.h: Remove.
+ * doc/install.texi: Update location of "xtensa-config.h" header.
+
+2003-06-30 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_extra_constraint): New function.
+ * config/s390/s390-protos.h (s390_extra_constraint): Declare it.
+ * config/s390/s390.h (EXTRA_CONSTRAINT): Use it.
+ * config/s390/s390.c (q_constraint): Remove.
+ * config/s390/s390-protos.h (q_constraint): Likewise.
+ * config/s390/s390.h (EXTRA_MEMORY_CONSTRAINT): Add 'R', 'S', 'T'.
+ (EXTRA_ADDRESS_CONSTRAINT): Define.
+
+ * config/s390/s390.c (larl_operand): Refuse out-of-range operands.
+ (DISP_IN_RANGE, s390_short_displacement): New.
+ (legitimate_reload_operand_p): Support long displacements.
+ (s390_decompose_address): Likewise.
+ (legitimize_pic_address): Likewise.
+ (legitimize_address): Likewise.
+ (s390_fixup_clobbered_return_reg): Likewise.
+ (s390_emit_prologue, s390_emit_epilogue): Likewise.
+ (s390_output_mi_thunk): Likewise.
+
+ * config/s390/s390.md (attr "op_type"): Add "RXY", "RSY", "SIY".
+ (attr "atype", attr "length"): Add defaults for new op_types.
+ (all insns): Change op_type attribute where appropriate.
+
+ ("*movdi_lay", "*movsi_lay", "*extendqidi2", "*extendqisi2"): New insns.
+ ("*tmqi_ext", "*tmdi_mem", "*tmsi_mem", "*tmhi_mem", *tmqi_mem",
+ "*tstsi", "*tstsi_cconly", "*tsthiCCT", "*tsthiCCT_cconly",
+ "*tsthi", "*tsthi_cconly", "*tstqiCCT", "*tstqiCCT_cconly",
+ "*tstqi", "*tstqi_cconly", "*cmpsi_ccs_sign", "*cmpsi_ccs",
+ "*cmpsi_ccu", "*cmphi_ccu", "*cmpqi_ccu", "*cli",
+ "movti", "*movdi_64", "*movdi_31", "*movsi", "movhi", "movqi_64",
+ "movqi", "*movstrictqi", "*movstricthi", "movstrictsi",
+ "*movdf_64", "*movdf_31", "*movsf",
+ "*load_multiple_si", "*store_multiple_di",
+ "*sethighqisi", "*sethighhisi", "*sethighqidi_31", "*extendhisi2",
+ "*la_64", "*la_31", "*la_31_and", "force_la_31",
+ "*addsi3_carry1_cc", *addsi3_carry1_cconly",
+ "*addsi3_carry2_cc", *addsi3_carry2_cconly",
+ "*addsi3_cc", "*addsi3_cconly", "*addsi3_cconly2",
+ "*addsi3_sign", "*addsi3_sub", "addsi3",
+ "*subsi3_borrow_cc", "*subsi3_borrow_cconly", "*subsi3_cc",
+ "*subsi3_cconly", "*subsi3_sign", "*subsi3_sub", "subsi3",
+ "mulsi3"
+ "*andsi3_cc", "*andsi3_cconly", "andsi3",
+ "*andqi3_ss", "*andqi3_ss_inv",
+ "*iorsi3_cc", "*iorsi3_cconly", "iorsi3",
+ "*iorqi3_ss", "*iorqi3_ss_inv",
+ "*xorsi3_cc", "*xorsi3_cconly", "xorsi3",
+ "*xorqi3_ss", "*xorqi3_ss_inv",
+ "*tls_load_31"): Add alternatives for long-displacement instructions.
+
+ ("*cmpdf_ccs", "*cmpdf_ccs_ibm", "*cmpsf_ccs", "*cmpsf_ccs_ibm",
+ "*load_multiple_di", "*store_multiple_di",
+ "*sethighqidi_64", "*zero_extendhisi2_31",
+ "truncdfsf2_ibm", "extendsfdf2_ieee", "extendsfdf2_ibm",
+ "adddf3", "*adddf3", "*adddf3_ibm",
+ "addsf3", "*addsf3", "*addsf3_ibm",
+ "subdf3", "*subdf3", "*subdf3_ibm",
+ "subsf3", "*subsf3", "*subsf3_ibm",
+ "mulsi_6432", "divmoddisi3",
+ "muldf3", "*muldf3", "*muldf3_ibm",
+ "mulsf3", "*mulsf3", "*mulsf3_ibm",
+ "divdf3", "*divdf3", "*divdf3_ibm",
+ "divsf3", "div*sf3", "*divsf3_ibm",
+ "sqrtdf2", "sqrtsf2",
+ "*cjump_long", "*icjump_long", "indirect_jump", "casesi_jump",
+ "*doloop_si_long", "*doloop_di_long", "bas_64", "bas_31",
+ "bas_r_64", "bas_r_31", "bas_tls_31", "bas_tls_64"): Adapt memory
+ and address constraints for instructions that do not accept long
+ displacements.
+
+2003-06-30 Hartmut Penner <hpenner@de.ibm.com>
+ Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/2084.md: New file.
+ * config/s390/s390.md: Include it.
+ * config/s390/s390.c (s390_adjust_priority): New function.
+ (TARGET_SCHED_ADJUST_PRIORITY): Define.
+ (s390_first_cycle_multipass_dfa_lookahead): New function.
+ (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD): Define.
+ (s390_sched_reorder2): New function.
+ (TARGET_SCHED_REORDER2): Define.
+ (s390_adjust_cost): Support PROCESSOR_2084_Z990 cpu type.
+ (s390_issue_rate): Likewise.
+
+Mon Jun 30 23:47:33 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (GTFILES): Add cgraph.h.
+ * cgraph.c (known_decls): Remove.
+ (cgraph_hash, cgraph_nodes, cgraph_nodes_queue,
+ cgraph_varpool_hash, cgraph_varpool_nodes_queue): GTYize.
+ (cgraph_node): Do not allocate known_decls; use polutate hashtable.
+ (cgraph_varpool_node): Likewise; add next pointer.
+ (cgraph_varpool_nodes): New static variable.
+ * cgraph.h (cgraph_local_info, cgraph_global_info, cgraph_rtl_info,
+ cgraph_node, cgraph_edge, cgraph_varpool_node, cgraph_nodes, cgraph_n_nodes,
+ cgraph_varpool_n_nodes, cgraph_varpool_nodes_queue): GTYize.
+ * gengtype.c (open_base_files): Include cgraph.h
+
+2003-06-30 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * Changelog: Remove ">>>>>>>" from previous change.
+
+2003-06-30 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * config/cris/cris.c: Fix spelling for "testcase".
+ * config/cris/cris.h: Likewise.
+ * config/cris/cris.md: Likewise.
+ * config/mmix/crti.asm: Likewise.
+ * config/mmix/mmix.h: Likewise.
+ * config/mmix/mmix.md: Likewise.
+
+2003-06-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (LEGITIMATE_CONSTANT_P): Make it always
+ 1.
+
+2003-06-30 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config.gcc [s390*-*-*]: Support --with-arch, --with-tune, and
+ --with-mode configure options.
+ * config/s390/s390.h (OPTION_DEFAULT_SPECS): Define.
+ (DRIVER_SELF_SPECS): Define.
+ * config/s390/linux.h (ASM_SPEC): Pass architecture mode and cpu
+ architecture to assembler.
+ (LINK_SPEC): Merge 31-bit and 64-bit variants.
+ (LINK_ARCH31_SPEC, LINK_ARCH64_SPEC, EXTRA_SPECS): Remove.
+ * config/s390/s390.c (override_options): New default rules for
+ architecture mode and cpu architecture selection.
+ * doc/invoke.texi (-mesa, -mzarch, -march, -mtune): Document
+ new default rules.
+
+ * config/s390/s390.h (enum processor_type): Add PROCESSOR_2084_Z990.
+ * config/s390/s390.md (attr "cpu"): Add "z990" processor type.
+ * config/s390/s390.c (override_options): Add "z990" to
+ processor_alias_table.
+ * doc/invoke.texi (-march): Document "z990" processor type.
+
+ * config/s390/s390.c (s390_tune_flags, s390_arch_flags): New variables.
+ * config/s390/s390.h (s390_tune_flags, s390_arch_flags): Declare.
+ (enum processor_flags, TARGET_CPU_IEEE_FLOAT, TARGET_CPU_ZARCH,
+ TARGET_CPU_LONG_DISPLACEMENT, TARGET_LONG_DISPLACEMENT): New.
+ * config/s390/s390.c (override_options): Replace enum pta_flags by
+ enum processor_flags. Fill in s390_tune_flags and s390_arch_flags.
+
+ * config/s390/s390.c (s390_cpu): Rename to ...
+ (s390_tune): ... this.
+ * config/s390/s390.h (s390_cpu, s390_tune): Likewise.
+ * config/s390/s390.c (s390_issue_rate, override_options): Likewise.
+ * config/s390/s390.md (attr "cpu"): Likewise.
+
+2003-06-30 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.c (enum c_language_kind, flag_objc): Remove.
+ (fix_string_type, check_case_value, c_common_nodes_and_builtins,
+ c_add_case_label, finish_label_addr_expr, boolean_increment):
+ Use c_dialect_ macros.
+ * c-common.h (enum c_language_kind): Extend.
+ (c_dialect_cxx, c_dialect_objc): New.
+ (flag_objc): Remove.
+ (c_common_init_options): Update prototype.
+ * c-cppbuiltin.c (define__GNUC__, c_cpp_builtins): Use c_dialect_
+ macros.
+ * c-decl.c (finsih_decl, grokfield, finish_struct): Use c_dialect_
+ macros.
+ * c-format.c (C_STD_VER, C_STD_NAME): Similarly.
+ * c-lang.c (c_init_options): Remove.
+ (c_language): Define.
+ (LANG_HOOKS_INIT_OPTIONS): Use common hook.
+ * c-lex.c (lex_charconst): Use c_dialect_ macros.
+ * c-opts.c (lang_flags): Make function-local.
+ (c_common_init_options): Use c_dialect_ macros. Handle
+ C++ diagnostic requirements.
+ (c_common_handle_option, c_common_post_options): Use flag_cxx.
+ * c-parse.in (init_reswords): Use c_dialect_objc ().
+ * c-pch.c (get_ident): Use c_language.
+ * c-pretty-print.c (pp_c_bool_literal): Use c_dialect_ macros.
+ * c-typeck.c (comptypes, build_c_cast): Similarly.
+ * objc/objc-lang.c (c_language): Define.
+ (LANG_HOOKS_INIT_OPTIONS): Use common hook.
+ (objc_init_options): Remove.
+
+2003-06-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.h (FUNCTION_ARG_PADDING): Remove.
+ * config/alpha/unicosmk.h: Don't #undef FUNCTION_ARG_PADDING.
+
+2003-06-30 Wolfgang Bangerth <bangerth@dealii.org>
+
+ * doc/sourcebuild.texi: Don't reference gnats.html any more.
+
+2003-06-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (compute_mov_length): Fix length of
+ mov:SF on H8/300.
+
+2003-06-30 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.h (BIGGEST_FIELD_ALIGNMENT): Make defintion
+ constant.
+
+Mon Jun 30 15:36:29 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ (fyl2x_sfxf3, fyl2x_dfxf3, fscale_sfxf3, fscale_dfxf3): Fix condition.
+
+2003-06-30 Hartmut Penner <hpenner@de.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_split_altivec_in_gprs): New function.
+ (altivec_in_gprs_p): New function.
+
+ * config/rs6000/rs6000-protos (rs6000_split_altivec_in_gprs): New
+ prototype.
+ (altivec_in_gprs_p): New prototype.
+
+ * config/rs6000/altivec.md (*movv4si_internal): Change
+ multi-assembler alternative to '#'. Add postreload splitter to
+ handle this cases.
+ (*movv4hi_internal): Likewise.
+ (*movv4qi_internal): Likewise.
+ (*movv4sf_internal): Likewise.
+
+2003-06-30 Jason Merrill <jason@redhat.com>
+
+ * defaults.h (PUSH_ARGS_REVERSED): Define default here.
+ * calls.c: Not here.
+
+2003-06-30 Ben Elliston <bje@wasabisystems.com>
+
+ * config/arm/arm.c (arm_rtx_costs): Remove #if 0 block.
+ (bad_signed_byte_operand): Likewise.
+ (arm_output_epilogue): Likewise.
+ (arm_final_prescan_insn): Likewise.
+
+2003-06-30 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * cfgrtl.c (mark_killed_regs): Cast HARD_REGNO_NREGS to int.
+
+2003-06-30 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * c-pch.c (c_common_write_pch): Flush asm_out_file to allow for
+ subsequent writes.
+
+Mon Jun 30 10:03:02 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * cfgrtl.c (verify_flow_info): Accept degenerated condjumps
+ in cfglayout mode.
+
+Mon Jun 30 09:52:39 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (standard_80387_constant_p): Accept TFmode constants too.
+ (init_ext_80387_constants): Likewise.
+ (standard_80387_constant_rtx): Likewise.
+ * i386.md (atanxf): Disable for TARGET_128BIT_LONG_LONG
+ (atantf): Disable for !TARGET_128BIT_LONG_LONG
+ (fyl2x_sfxf3, fyl2x_dfxf3): Accept TFmode operands.
+ (fyl2x_xfxf3, fyl2x_tfxf3): Enable/disable as needed.
+ (fscale_sfxf3, fscale_dfxf3): Accept TFmode operands.
+ (fscale_xfxf3, fscale_tfxf3): Enable/disable as needed.
+ (frndinttf2): New.
+ (f2xm1tf2): New.
+ (exp?f2): Use expsf2_tf when needed.
+ (exp?f2_tf): New.
+ (exptf): New.
+
+2003-06-29 Uwe Stieber <uwe@kaos-group.de>
+
+ * config.gcc (sh*-*-kaos*): Put tm_file setting in separate case
+ statement from tmake_file set.
+
+2003-06-29 James E Wilson <wilson@tuliptree.org>
+
+ * reload.c (find_reloads): Change push_reloads to push_reload in
+ comment.
+ * reload1.c (eliminate_regs): Likewise.
+ (dump_needs): Delete prototype for deleted function.
+
+2003-06-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-attrs.def (gcc_diag, gcc_cdiag, gcc_cxxdiag): New
+ format attributes.
+ * c-format.c (enum format_type): Add gcc_diag_format_type,
+ gcc_cdiag_format_type, and gcc_cxxdiag_format_type.
+ (gcc_diag_length_specs, gcc_cdiag_length_specs,
+ gcc_cxxdiag_length_specs, gcc_diag_flag_pairs,
+ gcc_cdiag_flag_pairs, gcc_cxxdiag_flag_pairs, gcc_diag_flag_specs,
+ gcc_cdiag_flag_specs, gcc_cxxdiag_flag_specs, gcc_diag_char_table,
+ gcc_cdiag_char_table, gcc_cxxdiag_char_table): New.
+ (format_types_orig): Add new data.
+ (find_char_info_specifier_index, init_dynamic_diag_info): New
+ functions.
+ (handle_format_attribute): Update to handle new format attributes.
+
+2003-06-29 Dara Hazeghi <dhazeghi@yahoo.com>
+
+ * doc/install.texi: Remove install documentation for obsoleted targets
+ i?86-*-sco, i?86-*-sco3.2v4, powerpcle-*-pe, powerpcle-*-winnt,
+ arm-*-aof.
+ Update information about IA64 toolchain, AIX make requirements,
+ and binutils for m68k-*-hpux and *-*-linuxaout targets.
+
+Mon Jun 30 00:50:43 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * regmove.c (regmove_optimize): Don't try to make src and dst match
+ when they are in different modes.
+
+Sun Jun 29 23:06:32 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * builtins.c (expand_builtin_mathfn, expand_builtin_mathfn_2): Avoid
+ busy work when builtin is not supported by the backend.
+
+2003-06-29 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * loop.c (count_one_set): Fix detection of registers set in more
+ than one basic block.
+
+2003-06-29 Andreas Jaeger <aj@suse.de>
+
+ * target-def.h: Remove usage of OBJECT_FORMAT_ROSE.
+ * system.h: Poison OBJ_FORMAT_ROSE.
+ * doc/tm.texi (Macros for Initialization): Remove documentatin of
+ OBJECT_FORMAT_ROSE.
+ * config/rs6000/lynx.h: Remove undef of OBJECT_FORMAT_ROSE.
+ * collect2.c: Remove usage of OBJECT_FORMAT_ROSE.
+
+2003-06-29 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (update_total_code_bytes): New function.
+ (last_address): Number of bytes output for a function and its
+ associated thunks.
+ (compute_frame_size): Use BITS_PER_UNIT.
+ (pa_output_function_epilogue): Compute last_address. Use
+ update_total_code_bytes.
+ (output_lbranch): Handle long branch on portable runtime.
+ (attr_length_millicode_call, attr_length_call,
+ attr_length_indirect_call): Only use total_code_bytes for calls in
+ the text section.
+ (output_call): Only use an indirect call sequence when the target is
+ not local.
+ (pa_asm_output_mi_thunk): Handle updating of total_code_bytes. Improve
+ test to determine when an IA-relative branch can be used. Add various
+ long branch sequences. Avoid using an indirect branch on all ports
+ except SOM.
+
+2003-06-29 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * expr.c (clear_by_pieces): Fix prototype.
+
+2003-06-29 Andreas Jaeger <aj@suse.de>
+
+ * cse.c: Convert prototypes to ISO C90.
+ * cselib.c: Likewise.
+ * cselib.h: Likewise.
+ * dbxout.c: Likewise.
+ * debug.c: Likewise.
+ * df.c: Likewise.
+ * df.h: Likewise.
+ * dojump.c: Likewise.
+ * doloop.c: Likewise.
+ * dominance.c: Likewise.
+ * dwarf2asm.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * dwarf2out.h: Likewise.
+ * dwarfout.c: Likewise.
+ * except.c: Likewise.
+ * except.h: Likewise.
+ * emit-rtl.c: Likewise.
+ * et-forest.c: Likewise.
+ * et-forest.h: Likewise.
+ * except.c: Likewise.
+ * explow.c: Likewise.
+ * expmed.c: Likewise.
+ * expr.c: Likewise.
+ * expr.h: Likewise.
+
+2003-06-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alloc-pool.c: Fix comment formatting.
+ * bitmap.c: Likewise.
+ * bitmap.h: Likewise.
+ * bt-load.c: Likewise.
+ * builtins.c: Likewise.
+ * caller-save.c: Likewise.
+ * cfganal.c: Likewise.
+ * cfgrtl.c: Likewise.
+ * collect2.c: Likewise.
+ * cse.c: Likewise.
+ * df.c: Likewise.
+ * diagnostic.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * dwarfout.c: Likewise.
+ * expmed.c: Likewise.
+ * final.c: Likewise.
+ * flags.h: Likewise.
+ * fold-const.c: Likewise.
+ * gcc.c: Likewise.
+ * gcov-io.h: Likewise.
+ * gcov.c: Likewise.
+ * genattrtab.c: Likewise.
+ * genautomata.c: Likewise.
+ * libgcov.c: Likewise.
+ * mips-tfile.c: Likewise.
+ * optabs.c: Likewise.
+ * prefix.c: Likewise.
+ * rtlanal.c: Likewise.
+ * stmt.c: Likewise.
+ * stor-layout.c: Likewise.
+ * toplev.c: Likewise.
+ * varasm.c: Likewise.
+ * vmsdbgout.c: Likewise.
+
+2003-06-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * expr.c (emit_single_push_insn): If padding is needed
+ downward, adjust the stack pointer first, and then store the
+ data into the stack location using an offset.
+
+2003-06-29 Andreas Jaeger <aj@suse.de>
+
+ * collect2.h: Convert prototypes to ISO C90.
+ * collect2.c: Likewise.
+ * conflict.c: Likewise.
+ * coverage.c: Likewise.
+ * convert.h: Likewise.
+ * convert.c: Likewise.
+
+2003-06-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-decl.c (c_init_decl_processing): Use a location_t. Set input
+ filename to <internal>.
+ * tree.c (make_node): Just copy the current location.
+
+2003-06-29 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11210
+ * fold-const (decode_field_reference): Revert 2003-06-26 patch.
+
+2003-06-29 Neil Booth <neil@daikokuya.co.uk>
+
+ * toplev.c (flag_dummy): Remove.
+ (f_options): Restore flag pointers.
+
+2003-06-29 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (processor_target_table): Add 970.
+ * config.gcc: Add 970.
+
+2003-06-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * dwarf2out.c (add_AT_string): Replace ggc_alloc_string (X,
+ -1) with ggc_strdup.
+ * stmt.c (expand_asm_operands): Likewise.
+ * config/rs6000/rs6000.md (builtin_setjmp_receiver): Likewise.
+
+2003-06-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/ip2k/ip2k.c (ip2k_reorg): Use INSN_P instead of its
+ definition.
+
+2003-06-29 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * opts.c: Include insn-attr.h.
+ * Makefile.in (opts.o): Depend on INSN_ATTR_H.
+
+2003-06-27 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * flow.c (propagate_one_insn): Use proper test for a register
+ being part of the return value.
+
+2003-06-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/avr/avr.c: Fix a comment typo.
+
+2003-06-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/avr/avr-protos.h: Replace avr_simplify_comparision_p
+ with avr_simplify_comparison_p.
+ * config/avr/avr.c: Likewise.
+
+2003-06-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtins.c: Follow spelling conventions.
+ * cgraph.c: Likewise.
+ * cpplex.c: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/arm/iwmmxt.md: Likewise.
+ * config/c4x/c4x-modes.def: Likewise.
+ * config/c4x/c4x.c: Likewise.
+ * config/c4x/c4x.h: Likewise.
+ * config/c4x/c4x.md: Likewise.
+ * config/i386/i386-interix.h: Likewise.
+ * config/mips/mips.h: Likewise.
+
+2003-06-28 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/m68k/m68k.h (TARGET_CPU_CPP_BUILTINS): Predicate
+ __mc68020__ on TARGET_68020.
+
+2003-06-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c: Fix a comment typo.
+
+2003-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-parse.in (yylexstring): Use a location_t.
+
+ * diagnostic.h (diagnostic_set_info): Replace file and lineno
+ parameters with a location_t.
+ * diagnostic.c (diagnostic_set_info): Replace file and lineno
+ parameters with a location_t.
+ (inform, warning, pedwarn, error, sorry, fatal_error,
+ internal_error, warning_with_decl, pedwarn_with_decl,
+ error_with_decl): Adjust.
+ * c-error.c (pedwarn_c99): Adjust.
+ * c-format.c (status_warning): Adjust.
+ * rtl-error.c (file_and_line_for_asm): Rename to ...
+ (location_for_asm): Return a location_t.
+ (diagnostic_for_asm): Adjust.
+
+2003-06-28 Neil Booth <neil@daikokuya.co.uk>
+
+ * cpptrad.c (skip_macro_block_comment): New.
+ (copy_comment): Use it if appropriate.
+
+2003-06-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gcse.c (compute_ld_motion_mems): Use INSN_P instead of its
+ definition.
+ (store_killed_in_insn): Likewise.
+ * print-rtl.c (print_rtx): Likewise.
+ * config/frv/frv.c (frv_final_prescan_insn): Likewise.
+ * config/m68hc11/m68hc11.c (dead_register_here): Likewise.
+ (m68hc11_reassign_regs): Likewise.
+ (m68hc11_reorg): Likewise.
+
+2003-06-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * diagnostic.c (output_integer_with_precision): New macro.
+ (output_format): Use it. Handle more format specifiers.
+ (output_long_decimal): Remove.
+ (output_unsigned_decimal): Likewise.
+ (output_long_unsigned_decimal): Likewise.
+ (output_octal): Likewise.
+ (output_long_octal): Likewise.
+ (output_hexadecimal): Likewise.
+ (output_long_hexadecimal): Likewise.
+ (output_long_long_decimal): Likewise.
+
+2003-06-28 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/ia64.md: Follow recent emit_note API change.
+
+2003-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-parse.in (%union): Replace filename & lineno with location.
+ (save_filename, save_lineno): Remove.
+ (save_location): New.
+ (fndef, old_style_parm_decls_1, lineno_datadecl, lineno_decl,
+ nested_function, notype_nested_function, if_prefix, lineno_stmt,
+ lineno_label, label): Adjust.
+
+2003-06-28 Jakub Jelinek <jakub@redhat.com>
+
+ * builtins.c (c_strlen): Add only_value argument.
+ Handle COND_EXPR and COMPOUND_EXPR.
+ (expand_builtin_strlen): Optimize also strlen (i++ ? "foo" : "bar").
+ Adjust c_strlen callers.
+ (expand_builtin_strcpy, expand_builtin_strncpy,
+ expand_builtin_strcmp, expand_builtin_strncmp,
+ expand_builtin_fputs, expand_builtin_sprintf,
+ fold_builtin): Adjust c_strlen callers.
+
+2003-06-28 Josef Zlomek <zlomekj@suse.cz>
+
+ * bb-reorder.c (find_traces_1_round): Do not send basic block
+ to next round when we are in the last round.
+
+2003-06-28 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Update.
+ * opts.c: Include tm_p.h.
+ (handle_options): Make static.
+ (decode_options): Copied from toplev.c.
+ * opts.h (decode_options): New.
+ * toplev.c (parse_options_and_default_flags): Move most to opts.c,
+ some to...
+ (general_init): ...here.
+ (toplev_main): Use decode_options instead.
+ * toplev.h (save_argc, save_argv): New.
+
+2003-06-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * explow.c (find_next_ref): Remove.
+ * rtl.h: Remove the prototype for find_next_ref.
+
+2003-06-27 Roger Sayle <roger@eyesopen.com>
+
+ * config/alpha/alpha.md (anonymous define_split): Adjust emit_note
+ call to match recent API change.
+
+2003-06-27 Zack Weinberg <zack@codesourcery.com>
+
+ * dbxout.c (flag_debug_only_used_symbols): Delete redundant
+ declaration.
+
+ * c-format.c (check_format_string, get_constant)
+ * cfgrtl.c (rtl_split_edge):
+ Mark the definition static, matching the forward declaration.
+
+2003-06-27 Gunther Nikl <gni@gecko.de>
+
+ * unwind-c.c (PERSONALITY_FUNCTION): Delete duplicate define.
+
+ PR target/11014
+ * config/m68k/m68k.c (m68k_output_mi_thunk): Use correct assembly
+ syntax for MIT / MOTOROLA.
+
+ PR other/10240
+ * configure.in: Removed $(XCFLAGS) from BUILD_CFLAGS for build != host.
+ * configure: Rebuilt.
+
+2003-06-27 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.c (mips_build_va_list): Make padding in
+ va_list structure explicit to avoid -Wpadded warnings.
+
+2003-06-27 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h (SECONDARY_OUTPUT_RELOAD_CLASS): Define.
+ * config/s390/s390.c (s390_secondary_output_reload_class): New function.
+ * config/s390/s390-protos.h (s390_secondary_output_reload_class):
+ Declare it.
+ * config/s390/s390.md ("reload_outti", "reload_outdi",
+ "reload_outdf"): New expanders.
+
+ * config/s390/s390.md ("movti" + splitters): Handle non-offsettable
+ memory operands as source.
+ ("movdi" + splitters): Likewise.
+ ("movdf" + splitters): Likewise.
+ * config/s390/s390.c (s390_split_ok_p): New function.
+ * config/s390/s390-protos.h (s390_split_ok_p): Declare it.
+
+2003-06-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (force_to_mode): Replace the equality comparison
+ of INTVALs with a pointer equality comparison.
+ (simplify_comparison): Likewise.
+
+2003-06-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * jump.c (rtx_renumbered_equal_p): Replace an expression that
+ is known to be 0 with 0.
+
+2003-06-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gcse.c (expr_equiv_p): Replace expressions that are known to
+ be 0 with 0.
+
+2003-06-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cse.c (fold_rtx): Replace the equality comparison of INTVALs
+ with a pointer equality comparison.
+
+2003-06-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * rtlanal.c (reg_mentioned_p): Return 0 earlier if REG and IN
+ are known to be not equivalent.
+
+2003-06-27 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (function_arg): Don't pass small aggregates
+ in floating point registers. Validate that we don't receive complex
+ values here. Use #elif.
+ (return_in_memory, function_value): New.
+ (alpha_va_arg): Handle complex values as two arguments.
+ * config/alpha/alpha.h (RETURN_IN_MEMORY): Use return_in_memory.
+ (FUNCTION_VALUE, LIBCALL_VALUE): Use function_value.
+ (SPLIT_COMPLEX_ARGS): New.
+ * config/alpha/alpha-protos.h: Update.
+
+2003-06-27 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * ggc-page.c (inverse_table): Change type of mult to size_t.
+ (compute_inverse): Compute inverse using size_t, not unsigned int.
+ Compute inverse also for sizes larger than half a machine page.
+
+Fri Jun 27 18:36:12 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (rest_of_decl_compilation): Only varpoolize argument
+ when called before cgraph_optimize.
+
+2003-06-27 Zack Weinberg <zack@codesourcery.com>
+
+ * config/darwin.h, config/elfos.h, config/i960/i960-coff.h
+ * config/m68k/coff.h: ASM_FILE_START_FILE_DIRECTIVE should
+ be TARGET_ASM_FILE_START_FILE_DIRECTIVE.
+
+Fri Jun 27 17:41:16 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_node, cgraph_varpool_node): Avoid re-initializing
+ of known_decls.
+
+2003-06-27 Hans-Peter Nilsson <hp@axis.com>
+
+ * defaults.h (REGISTER_MOVE_COST): Define default here.
+ * regclass.c: Don't define default REGISTER_MOVE_COST here.
+ * reload.c, reload1.c: Ditto.
+
+2003-06-27 Richard Earnshaw <rearnsha@arm.com>
+
+ * flags.h: Really install previous change.
+
+2003-06-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtl.h (emit_note): Remove FILE parameter.
+ * emit-rtl.c (emit_line_note): Adjust emit_note call.
+ (emit_note): Remove FILE parameter. Adjust.
+ * builtins.c (expand_builtin_expect): Adjust emit_note call.
+ * c-semantics.c (genrtl_scope_stmt): Likewise.
+ (expand_stmt): Likewise.
+ * cfglayout.c (reemit_insn_block_notes): Likewise.
+ (duplicate_insn_chain): Likewise.
+ * except.c (expand_eh_region_start, expand_eh_region_end,
+ sjlj_emit_function_enter): Likewise.
+ * explow.c (probe_stack_range): Likewise.
+ * expr.c (emit_block_move_via_loop): Likewise.
+ * function.c (init_function_start, expand_function_start,
+ expand_function_end, thread_prologue_and_epilogue_insns): Likewise.
+ * integrate.c (expand_inline_function, copy_insn_list): Likewise.
+ * reg-stack.c (compensate_edge): Likewise.
+ * reload1.c (reload): Likewise.
+ * rtlanal.c (hoist_insn_to_edge): Likewise.
+ * stmt.c (expand_fixup, expand_start_loop, expand_start_null_loop,
+ expand_loop_continue_here, expand_end_loop, expand_continue_loop,
+ expand_exit_loop_top_cond, expand_value_return,
+ expand_start_bindings_and_block, expand_end_bindings,
+ expand_decl_cleanup, expand_start_case): Likewise.
+ * unroll.c (copy_loop_body
+ * config/alpha/alpha.c (alpha_output_mi_thunk_osf): Likewise.
+ * config/ia64/ia64.c (ia64_output_mi_thunk): Likewise.
+ * config/rs6000/rs6000.c (rs6000_emit_eh_toc_restore,
+ rs6000_emit_allocate_stack, rs6000_output_function_prologue,
+ rs6000_output_function_epilogue, rs6000_output_mi_thunk): Likewise.
+ * config/sh/sh.c (sh_output_mi_thunk): Likewise.
+ * config/sparc/sparc.c (sparc_output_mi_thunk): Likewise.
+
+2003-06-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-tree.h (grokfield): Remove unused filename and line parameters.
+ * c-decl.c (grokfield): Remove unused filename and line parameters.
+ * c-parse.in (component_decl): Adjust field grokking rules, adjust
+ grokfield calls.
+ (component_declarator): Likewise.
+ (component_notype_declarator): Likewise.
+ * objc/objc-act.c (build_module_descriptor): Adjust grokfield
+ calls.
+ (build_protocol_template, build_method_prototype_list_template,
+ build_method_prototype_template, build_category_template,
+ build_selector_template, build_class_template,
+ build_super_template, build_ivar_template,
+ build_ivar_list_template, build_method_list_template,
+ build_method_template, add_instance_variable): Likewise.
+
+2003-06-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * stmt.c (do_jump_if_equal): Return 0 earlier if OP1 and
+ OP2 are known to be not equivalent.
+
+2003-06-26 Devang Patel <dpatel@apple.com>
+
+ * final.c (debug_flush_symbol_queue): New function.
+ (debug_queue_symbol): New function.
+ (debug_free_queue): New function.
+ (debug_nesting): New variable.
+ (symbol_queue): New variable.
+ (symbol_queue_index): Same.
+ (symbol_queue_size): Same.
+ * debug.h (debug_flush_symbol_queue): New.
+ (debug_queue_symbol): New.
+ (debug_free_queue): New.
+ (debug_nesting): New.
+ (symbol_queue_index): New.
+ * dbxout.c (DBXOUT_DECR_NESTING): New macro.
+ (DBXOUT_DECR_NESTING_AND_RETURN): New macro.
+ (dbxout_init): Delay symbol output.
+ (dbxout_global_decl): Save, set and reset TREE_USED bit around
+ dbxout_symbol() call.
+ (dbxout_begin_function): Same.
+ (dbxout_finish): Free symbol queue.
+ (dbxout_type): Put appropriate symbols in queue.
+ (dbxout_symbol): Put info for symbol's type in queue.
+ Decrement/Increment nesting counts flush symbol queue appropriately.
+ (dbxout_parms): Increment dbxout nesting.
+ (dbxout_reg_parms): Same.
+ * flags.h (flag_debug_only_used_symbols): New.
+ * toplev.c (flag_debug_only_used_symbols): New variable.
+ (lang_independent_options): Add entries for new option
+ -feliminate-unused-debug-symbols.
+ * common.opt: Add entry for -feliminate-unused-debug-symbols.
+ * opts.c (common_handle_options): Same.
+ * config/rs6000/darwin.h (CC1_SPEC): Interpret -gused as
+ -feliminate-unused-debug-symbols.
+ * doc/invoke.texi (Debugging Options): Document
+ -feliminate-unused-debug-symbols.
+
+2003-06-26 Roger Sayle <roger@eyesopen.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * builtins.c (expand_builtin_sprintf): Use c_getstr and strlen to
+ obtain the format string instead of using TREE_STRING_POINTER and
+ TREE_STRING_LENGTH. Only optimize sprintf(dst,"%s",src) when the
+ return value is unused or the length of src is a known constant.
+
+2003-06-26 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.h (REGISTER_NAMES): R0 is really AP.
+
+2003-06-26 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.c (ia64_expand_call): Don't add ar.pfs for sibcalls.
+ (ia64_split_call): Only load descriptor for GP register inputs.
+ (ia64_expand_epilogue): Check current_frame_info.mask not
+ current_function_is_leaf to restore ar.pfs.
+
+2003-06-26 Richard Henderson <rth@redhat.com>
+
+ * emit-rtl.c (try_split): Append to new CALL_INSN_FUNCTION_USAGE
+ instead of replacing it.
+
+2003-06-26 Richard Henderson <rth@redhat.com>
+
+ * flow.c (propagate_one_insn): Kill function return value
+ registers across tail calls.
+
+ * flow.c (propagate_one_insn): Preserve live-at-end registers
+ across tail calls.
+
+2003-06-26 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * reload.c (can_reload_into): New function.
+ (push_reload): Use it.
+
+2003-06-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (compute_a_rotate_length): Fix the
+ references to the amount of a rotation.
+
+2003-06-26 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/sh/coff.h: Don't include dbxcoff.h.
+ * config.gcc: List it here.
+
+2003-06-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * postreload.c (reload_cse_simplify_set): Call cselib_lookup
+ earlier. Don't check if SRC is a constant.
+
+2003-06-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * Makefile.in (OBJS): Add postreload.o.
+ Remove cselib.h from the dependency list for reload1.o.
+ Add a dependency list for postreload.o.
+ * reload.h: Change the comment for the prototype of
+ reload_cse_regs.
+ * reload1.c: Don't include cselib.h.
+ (reload_cse_regs): Move to postreload.c
+ (reload_cse_regs_1): Likewise.
+ (reload_cse_noop_set_p): Likewise.
+ (reload_cse_simplify_set): Likewise.
+ (reload_cse_simplify_operands): Likewise.
+ (RELOAD_COMBINE_MAX_USES): Likewise.
+ (reload_combine_ruid): Likewise.
+ (LABEL_LIVE): Likewise.
+ (reload_combine): Likewise.
+ (reload_combine_note_use): Likewise.
+ (reload_combine_note_store): Likewise.
+ (reg_set_luid): Likewise.
+ (reg_offset): Likewise.
+ (reg_base_reg): Likewise.
+ (reg_mode): Likewise.
+ (move2add_luid): Likewise.
+ (move2add_last_label_luid): Likewise.
+ (MODES_OK_FOR_MOVE2ADD): Likewise.
+ (reload_cse_move2add): Likewise.
+ (move2add_note_store): Likewise.
+ (reload_cse_simplify): Likewise.
+ * postreload.c: New.
+
+2003-06-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/avr/avr.c (final_prescan_insn): Remove support for
+ -mrtl.
+ * config/avr/avr.h (MASK_RTL_DUMP): Remove.
+ (TARGET_RTL_DUMP): Likewise.
+ (TARGET_SWITCHES): Remove -mrtl.
+
+2003-06-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Change emit_a_rotate to
+ output_a_rotate. Add a prototype for compute_a_rotate_length.
+ * config/h8300/h8300.c (emit_a_rotate): Change to
+ output_a_rotate.
+ (compute_a_rotate_length): New.
+ (h8300_adjust_insn_length): Remove.
+ * config/h8300/h8300.h (ADJUST_INSN_LENGTH): Remove.
+ * config/h8300/h8300.md (adjust_length): Remove.
+ (*rotlqi3_1): Use output_a_rotate and compute_a_rotate_length.
+ (*rotlhi3_1): Likewise.
+ (*rotlsi3_1): Likewise.
+
+2003-06-26 Roger Sayle <roger@eyesopen.com>
+ Richard Henderson <rth@redhat.com>
+
+ * builtins.c (expand_builtin_mathfn): Always stabilize the argument
+ list against re-evaluation. If expand_unop fails, call expand_call
+ with the stabilized argument list rather than return NULL_RTX.
+ (expand_builtin_mathfn2): Likewise, always stabilize the argument
+ list, and call expand_call ourselves if expand_binop fails.
+
+2003-06-26 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11210
+ * fold-const (decode_field_reference): Strip only NOPs that
+ don't affect the sign.
+
+2003-06-26 Dhananjay Deshpande <dhananjayd@kpitcummins.com>
+
+ * gcc/config/sh/sh.md (push_fpscr): Enable for TARGET_SH2E.
+ (pop_fpscr, fpu_switch): Likewise.
+
+2003-06-26 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * value-prof.c: New.
+ * value-prof.h: New.
+ * Makefile.in (value-prof.o): New.
+ (LIBGCOV): Add _gcov_merge_single and _gcov_merge_delta
+ (profile.o): Add value-prof.h and tree.h dependency.
+ * flags.h (flag_profile_values): Declare.
+ * gcov-io.h (GCOV_COUNTERS, GCOV_COUNTER_NAMES, GCOV_MERGE_FUNCTIONS):
+ Add new counters.
+ (GCOV_COUNTER_V_INTERVAL, GCOV_COUNTER_V_POW2, GCOV_COUNTER_V_SINGLE,
+ GCOV_COUNTER_V_DELTA): New counter sections.
+ (__gcov_merge_single, __gcov_merge_delta): Declare.
+ * flow.c (mark_used_regs): Set subregs_of_mode only when the
+ structure is initialized.
+ * libgcov.c (__gcov_merge_single, __gcov_merge_delta): New functions.
+ * profile.c: Include value-prof.h and tree.h.
+ (gen_interval_profiler, gen_pow2_profiler, gen_one_value_profiler,
+ gen_const_delta_profiler, instrument_values): New static functions.
+ (get_exec_counts): Fix comment.
+ (branch_prob): Invoke instrument_values.
+ * toplev.c (flag_profile_values): New flag.
+ * doc/invoke.texi (-fprofile-values): Document.
+
+2003-06-26 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (cfgrtl.o): Add expr.h dependency.
+ * cfgrtl.c: Include expr.h.
+ (mark_killed_regs, safe_insert_insn_on_edge): New
+ functions.
+ * config/i386/i386.h (AVOID_CCMODE_COPIES): Define.
+ * basic-block.h (safe_insert_insn_on_edge): Declare.
+
+2003-06-26 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (missing_arg): Make non-static.
+ (c_common_handle_option): Don't check for missing arguments.
+ * opts.c (handle_option): Check for missing arguments.
+
+2003-06-26 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/power4.md (power4-veccomplex): Correct latency.
+
+2003-06-25 Loren James Rittle <ljrittle@acm.org>
+
+ * configure.in (ld_vers): Portability [sed].
+ * configure: Regenerate with autoconf213.
+
+2003-06-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * doc/extend.texi: Document new builtin functions for Intel
+ Prescott New Intrunctions.
+
+ * doc/invoke.texi: Document new command-line options, -mpni and
+ -mno-pni, for Intel Prescott New Intrunctions.
+
+ * config.gcc (extra_headers): Add pmmintrin.h for i[34567]86-*-*.
+
+ * config/i386/i386.c (override_options): Turn on MASK_SSE2
+ for -mpni. Turn on MASK_SSE for -msse2.
+ (bdesc_2arg): Add PNI builtins with 2 args.
+ (bdesc_1arg): Add PNI builtins with 1 arg.
+ (ix86_init_mmx_sse_builtins): Handle PNI builtins.
+ (ix86_expand_builtin): Likewise.
+
+ * config/i386/i386.h (MASK_3DNOW, MASK_3DNOW_A,
+ MASK_128BIT_LONG_DOUBLE, MASK_64BIT, MASK_MS_BITFIELD_LAYOUT,
+ MASK_TLS_DIRECT_SEG_REFS): Renumbered.
+ (TARGET_PNI): New.
+ (TARGET_SWITCHES): Don't enable MASK_SSE for -msse2 here. Add
+ -mpni and -mno-pni.
+ (TARGET_CPU_CPP_BUILTINS): Defined __PNI__ for PNI.
+ (ix86_builtins): Add PNI builtins.
+ (config/i386/i386.md): Add PNI patterns.
+
+ * config/i386/pmmintrin.h: New file.
+
+2003-06-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (call): Fix the insn lengths.
+ (call_value): Likewise.
+
+Thu Jun 26 00:13:35 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * c-common.c (handle_used_attribute): Use mark_referenced.
+ * varasm.c (mark_referenced): Break out from ...
+ (assemble_name): ... here.
+ * tree.h (mark_referenced): Declare.
+
+2003-06-25 Wolfgang Bangerth <bangerth@dealii.org>
+
+ * gccbug.in: Add PCH to list of categories.
+
+2003-06-25 Martin Schaffner <schaffner@gmx.li>
+
+ * cppfiles.c: Clarify comments.
+ * cpphash.h: Likewise.
+ * cpplib.h: Likewise.
+ * cppmacro.c: Likewise.
+ * mkdeps.h: Likewise.
+
+2003-06-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (complain_wrong_lang, write_langs): Remove.
+ (c_common_handle_option): Complaints about wrong language are
+ handled in opts.c now.
+ * opts.c (complain_wrong_lang, write_langs, handle_options): New.
+ (find_opt): Fix thinko.
+ (handle_option): Update prototype. Complain about switches for
+ a different front end.
+ * opts.h (lang_names, handle_options): New.
+ (handle_option): Remove.
+ * opts.sh: Write out language names array.
+ * toplev.c (parse_options_and_default_flags): Use handle_options.
+
+2003-06-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/i386.c (MASK_SSE1): Removed.
+ (MASK_SSE164): Removed.
+ (MASK_SSE264): Removed.
+ (bdesc_2arg): Replace MASK_SSE1 with MASK_SSE. Replace
+ MASK_SSE164 with MASK_SSE | MASK_64BIT. Replace MASK_SSE264
+ with MASK_SSE2 | MASK_64BIT.
+ (bdesc_1arg): Likewise.
+ (ix86_init_mmx_sse_builtins): Likewise.
+
+ * config/i386/i386.h (TARGET_SSE): Remove MASK_SSE2.
+ (TARGET_SWITCHES): Enable both MASK_SSE and MASK_SSE2 for
+ -msse2.
+
+2003-06-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * hwint.h (HOST_WIDE_INT_PRINT, HOST_WIDE_INT_PRINT_C): New macros.
+ (HOST_WIDE_INT_PRINT_DEC_SPACE,
+ HOST_WIDE_INT_PRINT_UNSIGNED_SPACE,
+ HOST_WIDEST_INT_PRINT_DEC_SPACE,
+ HOST_WIDEST_INT_PRINT_UNSIGNED_SPACE): Delete.
+ (HOST_WIDE_INT_PRINT_DEC, HOST_WIDE_INT_PRINT_DEC_C,
+ HOST_WIDE_INT_PRINT_UNSIGNED, HOST_WIDE_INT_PRINT_HEX): Define in
+ terms of HOST_WIDE_INT_PRINT and possibly HOST_WIDE_INT_PRINT_C.
+
+ * final.c (asm_fprintf): Use HOST_WIDE_INT_PRINT.
+ * ra-debug.c (dump_static_insn_cost): Likewise.
+
+2003-06-26 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.h (BIGGEST_FIELD_ALIGNMENT): Define instead
+ of ADJUST_FIELD_ALIGN if IN_TARGET_LIBS.
+ Replace occurances of '???' with 'XXX' incase they are
+ mistaken for trigraphs.
+ (THUMB_PRINT_OPERAND_ADDRESS): abort if a compound address
+ does not have a register for the first operand.
+
+2003-06-25 Dhananjay Deshpande <dhananjayd@kpitcummins.com>
+
+ * config/sh/sh.c (sh_register_move_cost):
+ Add case for moving between MAC_REGS.
+
+2003-06-25 Zack Weinberg <zack@codesourcery.com>
+
+ PR 10178
+ * langhooks.h (struct lang_hooks): Add no_body_blocks bool.
+ * langhooks-def.h (LANG_HOOKS_NO_BODY_BLOCKS): New; default false.
+ * c-lang.c, objc/objc-lang.c: Override LANG_HOOKS_NO_BODY_BLOCKS
+ to true.
+ * stmt.c (is_body_block): If lang_hooks.no_body_blocks, always
+ return 0.
+
+2003-06-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (bt-load.o): Depend on $(TM_P_H).
+ * bt-load.c: Include "tm_p.h".
+
+2003-06-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (compute_mov_length): Adjust for the
+ new optimization.
+ * config/h8300/h8300.md (*movsi_h8300): Optimize the load of
+ an SImode constant whose upper and lower are the same.
+
+Wed Jun 25 11:31:59 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * varasm.c (assemble_name): Mark needed variables even when
+ global info is ready.
+
+2003-06-24 Jerry Quinn <jlquinn@optonline.net>
+
+ PR other/11280
+ * gcc/doc/invoke.texi (Optimization Options): Remove -Os from
+ -freorder-functions description.
+
+2003-06-25 Josef Zlomek <zlomekj@suse.cz>
+
+ * dwarf2out.c (gen_field_die): Return if type of decl is error mark.
+
+2003-06-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * opts.c (common_handle_option): Add missing break;s.
+
+2003-06-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add a prototype for
+ compute_mov_length.
+ * config/h8300/h8300.c (compute_mov_length): New.
+ * config/h8300/h8300.md (*movqi_h8300): Use it.
+ (*movqi_h8300hs): Likewise.
+ (movstrictqi): Likewise.
+ (*movhi_h8300): Likewise.
+ (*movhi_h8300hs): Likewise.
+ (movstricthi): Likewise.
+ (*movsi_h8300): Likewise.
+ (*movsf_h8300): Likewise.
+ (*movsi_h8300hs): Likewise.
+ (*movsf_h8300hs): Likewise.
+
+2003-06-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * jump.c (next_nondeleted_insn): Remove.
+ * rtl.h: Remove the prototype for next_nondeleted_insn.
+
+2003-06-24 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/11311
+ * builtins.c (powi_cost): Fix typo. The number of multiplications
+ required is the number to reduce the argument, result, plus the
+ cost of calculating the residual, val [not n, the original value].
+
+2003-06-24 Roger Sayle <roger@eyesopen.com>
+
+ * config/alpha/osf5.h (TARGET_C99_FUNCTIONS): Define.
+
+2003-06-24 Richard Henderson <rth@redhat.com>
+ (blame to: Loren James Rittle <ljrittle@acm.org>)
+
+ * real.h (ieee_extended_intel_96_round_53_format): New.
+ * real.c (ieee_extended_intel_96_round_53_format): New.
+ * config/i386/freebsd.h (SUBTARGET_OVERRIDE_OPTIONS): Use it
+ for XFmode and TFmode.
+
+2003-06-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (4 anonymous patterns): Give internal
+ names.
+ (movsi_h8300): Change the name to *movsi_h8300.
+ (movsi_h8300hs): Change the name to *movsi_h8300hs.
+ (movsf_h8300): Change the name to *movsf_h8300.
+ (movsf_h8300hs): Change the name to *movsf_h8300hs.
+
+2003-06-24 Jakub Jelinek <jakub@redhat.com>
+
+ * builtins.c (expand_builtin_strcpy): Don't evaluate side-effects in
+ src twice.
+
+2003-06-24 J"orn Rennecke <joern.rennecke@superh.com>
+
+ Back out these patches:
+ 2003-06-02 J"orn Rennecke <joern.rennecke@superh.com>
+ * sh.h (OLD_ARG_MODE): New macro.
+ (FUNCTION_ARG_ADVANCE, FUNCTION_ARG_PASS_BY_REFERENCE): Use it.
+ (FUNCTION_ARG_1): Break out of:
+ (FUNCTION_ARG). Use OLD_ARG_MODE.
+ 2003-06-06 J"orn Rennecke <joern.rennecke@superh.com>
+ * sh.h (FUNCTION_ARG_1): Consistently use NEW_MODE for the mode
+ of the generated register.
+
+ * sh.h (FUNCTION_ARG_SCmode_WART): Define.
+ (FUNCTION_ARG): Unless FUNCTION_ARG_SCmode_WART is defined and
+ an even number of floating point regs are in use, use the same
+ sequence of argument passing registers for SCmode as would be
+ used for two SFmode values.
+ * sh.c (sh_va_arg): If FUNCTION_ARG_SCmode_WART is defined,
+ swap real / imaginary parts in incoming SCmode values passed
+ in registers.
+
+2003-06-24 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ PR target/11260
+ * config/alpha/alpha.md (sqrtdf2): Fix operand substitution.
+
+Tue Jun 24 18:49:33 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (cgraph.o): Depend on output.h, not depend on
+ tree-inline.h
+ * cgraph.c: Do not include tree-inline.h; include output.h
+ (known_fns): Rename to ...
+ (known_decls): ... this one; update all uses.
+ (cgraph_varpool_hash): New static variable.
+ (cgraph_varpool_n_nodes, cgraph_varpool_nodes_queue): New global
+ variables.
+ (cgraph_varpool_hash_node, eq_cgraph_varpool_node, cgraph_varpool_node,
+ cgraph_varpool_node_for_identifier, cgraph_varpool_mark_needed_node,
+ cgraph_varpool_finalize_decl, cgraph_varpool_assemble_pending_decls):
+ New functions.
+ * cgraph.h (cgraph_varpool_node): New structure.
+ (cgraph_varpool_n_nodes, cgraph_varpool_nodes_queue): Declare.
+ (cgraph_varpool_node, cgraph_varpool_node_for_identifier,
+ cgraph_varpool_finalize_decl, cgraph_varpool_mark_needed_node,
+ cgraph_varpool_asemble_pending_decls): Declare.
+ * cgraphunit.c (record_call_1): Notice variable references.
+ (cgraph_finalize_compilation_unit): Assemble pending variables.
+ * toplev.c (wrapup_global_declarations): Use varpool.
+ (compile_file): Assemble pending declarations.
+ (rest_of_decl_compilation): Use varpool in unit-at-a-time mode.
+ * varasm.c (assemble_name): Notice varpool references.
+
+Tue Jun 24 13:52:11 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * langhooks-def.h (LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE): New macro.
+ * langhooks.h (lang_hooks_for_decls): Add prepare_assemble_variable.
+ * varasm.c (assemble_variable): Call prepare_assemble_variable.
+
+2003-06-23 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin): Use expand_builtin_pow to expand
+ calls for pow, powf, powl and their __builtin_ variants.
+ (expand_builtin_pow): If the second argument is a constant
+ integer and compiling with -ffast-math, use expand_powi to
+ generate RTL if powi_cost is less than POWI_MAX_MULTS.
+ (powi_cost): New function to return the number of multiplications
+ necessary to evaluate an Nth power, for integer constant N.
+ (expand_powi): New function to expand the RTL for evaluating
+ the Nth power of a floating point value, for integer constant N.
+
+ * doc/tm.texi (POWI_MAX_MULTS): Document new target macro.
+
+Mon Jun 23 23:07:35 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_nodes_queue): Declare.
+ (eq_node): Take identifier as p2.
+ (cgraph_node): Update htab_find_slot_with_hash call.
+ (cgraph_node_for_identifier): New.
+ (cgraph_mark_needed_node): Move here from cgraphunit.c.
+ * cgraph.h (cgraph_nodes_queue): Declare.
+ (cgraph_node_for_identifier): Declare.
+ * cgraphunit.c (cgraph_finalize_function): Collect entry points here
+ instead of in cgraph_finalize_compilation_unit; constructors and
+ destructors are entry points.
+ (cgraph_finalize_compilation_unit): Reorganize debug outout;
+ examine nested functions after lowerng; call collect_functions hook.
+ (cgraph_mark_local_functions): DECL_COMDAT functions are not local.
+ (cgraph_finalize_compilation_unit): Do not collect entry points.
+ * varasm.c: Include cgraph.h
+ (assemble_name): Mark referenced identifier as needed.
+
+ * cgraphunit.c (record_call_1): Use get_callee_fndecl.
+
+2003-06-23 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.c (x86_output_mi_thunk): Don't pass MEM to %P0,
+ just SYMBOL_REF.
+ * config/s390/s390.c (s390_output_mi_thunk): Avoid .plt in -m31
+ mode, as it requires pic register loaded.
+
+ * varasm.c (resolve_unique_section): Remove prototype. No longer
+ static.
+ * tree.h (resolve_unique_section): New prototype.
+
+2003-06-23 Andreas Schwab <schwab@suse.de>
+
+ PR debug/9905
+ * dwarf2out.c (loc_descriptor_from_tree): Handle MODIFY_EXPR by
+ recursing through first argument.
+
+2003-06-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog.1: Fix a typo.
+ * cfgrtl.c: Fix comment typos.
+ * dwarf2out.c: Likewise.
+ * expmed.c: Likewise.
+ * genrecog.c: Likewise.
+ * jump.c: Likewise.
+ * rtlanal.c: Likewise.
+ * ssa-dce.c: Likewise.
+ * toplev.c: Likewise.
+
+2003-06-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/extend.texi: Fix typos.
+ * doc/md.texi: Likewise.
+ * doc/tm.texi: Likewise.
+
+2003-06-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * basic-block.h: Fix comment formatting.
+ * bt-load.c: Likewise.
+ * builtins.c: Likewise.
+ * c-common.c: Likewise.
+ * c-common.h: Likewise.
+ * c-format.c: Likewise.
+ * coverage.c: Likewise.
+ * cpplib.h: Likewise.
+ * cpppch.c: Likewise.
+ * dbxout.c: Likewise.
+ * diagnostic.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * expr.c: Likewise.
+ * fold-const.c: Likewise.
+ * function.c: Likewise.
+ * gcc.c: Likewise.
+ * gcov-io.c: Likewise.
+ * gcov-io.h: Likewise.
+ * gcov.c: Likewise.
+ * profile.c: Likewise.
+ * real.h: Likewise.
+ * sched-deps.c: Likewise.
+
+2003-06-23 Roger Sayle <roger@eyesopen.com>
+ Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/contrib.texi (Contributors): Add a note on testing and
+ remove duplicates from testers list.
+
+2003-06-23 Nick Clifton <nickc@redhat.com>
+
+ * read-rtl.c (read_braced_string): Check for EOF. If
+ encountered issue an error message.
+
+2003-06-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Document dump options, dT and dW.
+
+2003-06-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genrecog.c (pred_table): Remove the entry for
+ mode_independent_operand.
+ * recog.c (next_insns_test_no_inequality): Remove.
+ (mode_independent_operand): Likewise.
+ * recog.h: Remove the prototype for mode_independent_operand.
+
+2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (output_simode_bld): Use rotxl.l to
+ store into bit 0.
+ * config/h8300/h8300.md (*extzv_1_r_h8300hs): Change cc of the
+ second alternative to set_znv.
+ (*extzv_1_r_inv_h8300hs): Likewise.
+
+2003-06-23 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * configure.in (in_tree_gas): Find out here whether GAS is ELF,
+ set in_tree_gas_is_elf accordingly.
+ (in_tree_ld): Find out whether LD emulation is ELF, set
+ in_tree_ld_is_elf accordingly.
+ (gcc_cv_as_subsections, gcc_cv_as_hidden, gcc_cv_as_leb128)
+ (gcc_cv_as_eh_frame, gcc_cv_as_shf_merge)
+ (gcc_cv_as_dwarf2_debug_line, gcc_cv_as_gdwarf2_flag)
+ (gcc_cv_as_gstabs_flag): Use $in_tree_gas_is_elf instead of
+ grepping gas/Makefile.
+ (gcc_cv_ld_ro_rw_mix, gcc_cv_ld_eh_frame_hdr, gcc_cv_ld_pie): Use
+ $in_tree_ld_is_elf instead of grepping ld/Makefile.
+ * configure: Regenerate.
+
+2003-06-22 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_mathfn_2): Use tree_cons to build
+ up the stabilized argument list, not build_tree_list.
+ (expand_builtin_strcpy): Construct new argument list manually
+ instead of using chainon to modify the original argument list.
+ (expand_builtin_stpcpy): Construct new argument list manually
+ instead of using copy_list and chainon.
+ (expand_builtin_sprintf): New function. Optimize calls to
+ sprintf when the format is "%s" or doesn't contain a '%'.
+ (expand_builtin): Expand BUILT_IN_SPRINTF using the new function
+ expand_builtin_sprintf.
+
+2003-06-22 Andreas Schwab <schwab@suse.de>
+
+ * function.c (set_insn_locators): Mark as unused.
+
+2003-06-22 Neil Booth <neil@daikokuya.co.uk>
+
+ * common.opt: Add -finline-limit.
+ * opts.c (common_handle_options): Handle it.
+ * opts.sh: Temporary kludge for -finline-limit.
+ * toplev.c (decode_f_option, independent_decode_option): Die.
+ (parse_options_and_default_flags): No independent_decode_option.
+
+2003-06-22 Andreas Jaeger <aj@suse.de>
+
+ * calls.c (emit_call_1): Readd lost ATTRIBUTE_UNUSED.
+
+2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Document dumps, .btl, .cfg, and .bypass.
+
+2003-06-22 Andreas Schwab <schwab@suse.de>
+
+ * doc/invoke.texi: Remove leading `-' from options in index.
+
+2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * bt-load.c: Follow spelling conventions.
+
+2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * expr.c (emit_move_insn_1): Fix a comment typo.
+
+2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Alphabetize dump options.
+
+2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Remove a duplicate -dk.
+
+2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Update dump file names.
+
+2003-06-22 Zack Weinberg <zack@codesourcery.com>
+
+ * config/i370/i370.c, config/i370/i370.h: Use HOST_CHARSET_ASCII
+ and HOST_CHARSET_EBCDIC, not HC_ASCII and HC_EBCDIC.
+
+2003-06-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/rtl.texi: Fix the @findex for pre_modify.
+
+2003-06-22 Andreas Jaeger <aj@suse.de>
+
+ * caller-save.c: Convert to ISO C90.
+ * calls.c: Likewise.
+ * cfg.c: Likewise.
+ * cfganal.c: Likewise.
+ * cfgbuild.c: Likewise.
+ * cfgcleanup.c: Likewise.
+ * cfghooks.c: Likewise.
+ * cfglayout.c: Likewise.
+ * cfglayout.h: Likewise.
+ * cfgloop.c: Likewise.
+ * cfgloop.h: Likewise.
+ * cfgloopanal.c: Likewise.
+ * cfgloopmainip.c: Likewise.
+ * cfgrtl.c: Likewise.
+
+2003-06-22 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.h (BIGGEST_ALIGNMENT): Use TARGET_REALLY_IWMMXT for selecting
+ 64-bit alignment.
+
+2003-06-22 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (all call_value patterns): Remove register constraints on
+ value operand.
+
+2003-06-22 Neil Booth <neil@daikokuya.co.uk>
+
+ * common.opt: More -f switches.
+ * opts.c (common_handle_options): Handle them.
+ * toplev.c (time_report): Make extern.
+ (f_options): USe flag_dummy.
+ (decode_f_option): No need to use f_options now.
+ * toplev.h (flag_cprop_registers, flag_ssa, flag_ssa_ccp,
+ flag_ssa_dce, time_report, flag_new_regalloc): Make extern.
+
+2003-06-22 Andreas Jaeger <aj@suse.de>
+
+ * c-lex.c: Convert to ISO C90.
+ * c-objc-common.c: Likewise.
+ * c-opts.c: Likewise.
+ * c-pch.c: Likewise.
+ * c-ppoutput.c: Likewise.
+ * c-pragma.h: Likewise.
+ * c-pretty-print.c: Likewise.
+ * c-pretty-print.h: Likewise.
+ * c-semantics.c: Likewise.
+ * c-tree.h: Likewise.
+ * c-typeck.c: Likewise.
+
+ * c-lang.c: Convert to ISO C90.
+
+2003-06-22 Neil Booth <neil@daikokuya.co.uk>
+
+ * opts.c (find_opt): Fix to always guarantee a find of a
+ switch with joined parameter.
+ * opts.h (struct cl_option): New member back_chain.
+ * opts.sh: Update to calculate and add back_chain member.
+
+2003-06-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * diagnostic.h (output_host_wide_integer): Declare.
+ * diagnostic.c (output_long_long_decicaml): New function.
+ (output_host_wide_integer): Likewise.
+ (output_format): Use them. Handle "%ll" and "%w".
+
+2003-06-21 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.gcc (*-*-netbsd*): Add t-libgcc-pic to tmake_file.
+
+2003-06-21 Zack Weinberg <zack@codesourcery.com>
+
+ * aclocal.m4 (gcc_AC_C_CHARSET): Delete.
+ * configure.in: Don't use gcc_AC_C_CHARSET.
+ * configure, config.in: Regenerate.
+ * config/i370/i370.c, config/i370/i370.h: Use
+ (HOST_CHARSET == HC_EBCDIC) or (HOST_CHARSET == HC_ASCII)
+ instead of HOST_EBCDIC or !HOST_EBCDIC. Clarify comments a tad.
+
+2003-06-21 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Update.
+ * common.opt: New switches.
+ * opts.c: Include diagnostic.h.
+ (common_handle_option): Handle new switches.
+ * toplev.c (flag_loop_optimize, flag_crossjumping, flag_if_conversion,
+ flag_if_conversion2, flag_delete_null_pointer_checks,
+ flag_rerun_cse_after_loop): Make extern.
+ (flag_dummy): New.
+ (f_options): Update to use flag_dummy for moved options.
+ (decode_f_option): Some switches moved to opts.c.
+ * toplev.h (flag_loop_optimize, flag_crossjumping, flag_if_conversion,
+ flag_if_conversion2, flag_delete_null_pointer_checks,
+ flag_rerun_cse_after_loop, flag_keep_static_consts, flag_peel_loops,
+ flag_tracer, flag_thread_jumps, flag_unroll_loops,
+ flag_unroll_all_loops, flag_unswitch_loops): New.
+
+Sat Jun 21 13:41:00 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_va_arg): Fix allocation of temporary slot.
+
+2003-06-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add a prototype for
+ same_cmp_preceding_p.
+ * config/h8300/h8300.c (same_cmp_preceding): New.
+ * config/h8300/h8300.md: Extend peephole2's that transform
+ compare:SI into shorter sequences so that they can deal with
+ signed comparisons.
+
+2003-06-21 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/contrib.texi (Contributors): Use Windows instead of Win32.
+
+ Update Andreas Jaeger's entry.
+
+ Merge the two entries of Kaveh Ghazi, David Edelsohn, and
+ Loren J. Rittle.
+
+2003-06-21 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * mkconfig.sh: Add multiple inclusion guards to generated headers.
+
+2003-06-20 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-decl.c (store_parm_decls): Make saved_warn_shadow boolean.
+ * common.opt: Add remaining -W options and -g.
+ * diagnostic.c (warnings_are_errors): Remove.
+ * flags.h: Make most warning flags boolean.
+ * opts.c (common_handle_option): Handle remaining -W options, and -g.
+ Move many warning flags from toplev.c, making them boolean.
+ * toplev.c: Remove many warning flags.
+ (decode_W_option): Remove.
+ (decode_g_option): Make extern. Error on unknown switch.
+ (lang_independent_W_options): Use warn_dummy.
+ (independent_decode_option): Just handle -f switches now.
+ * toplev.h (decode_g_option): New.
+
+2003-06-20 Aldy Hernandez <aldyh@redhat.com>
+
+ PR/11092
+ * config/rs6000/rs6000.h (LEGITIMATE_CONSTANT_P): Adjust for
+ vectors.
+
+2003-06-20 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * opts.sh: Tweak awk script for portability.
+
+2003-06-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10888
+ * tree-inline.c (expand_call_inline): Do not warn about failing to
+ inline functions declared in system headers.
+ * doc/invoke.texi (-Winline): Expand on documentation.
+
+2003-06-20 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_file_start): Disable
+ file_start_file_directive for ELF and not MDEBUG.
+
+2003-06-20 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (ROUND_TYPE_ALIGN): Remove.
+
+2003-06-20 Richard Henderson <rth@redhat.com>
+
+ * hooks.c (hook_int_void_no_regs): Rename from
+ hook_reg_class_void_no_regs; change return type.
+ * hooks.h: Update.
+ * target-def.h (TARGET_BRANCH_TARGET_REGISTER_CLASS): Update.
+ * target.h (branch_target_register_class): Change return type to int.
+ Add documentation.
+ * config/sh/sh.c (sh_target_reg_class): Change return type.
+ * doc/tm.texi (TARGET_BRANCH_TARGET_REGISTER_CLASS): Likewise.
+
+2003-06-20 Andreas Tobler <toa@pop.agri.ch>
+
+ * c-format.c: Change _Bool to bool reverting part of the last
+ patch.
+
+2003-06-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * som.h (ASM_OUTPUT_SOURCE_LINE): Use targetm.strip_name_encoding to
+ strip name encoding.
+
+2003-06-20 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (gcc_cv_as_gstabs_flag): Disable if assembler warns.
+ * configure: Regenerate.
+ Fixes PR driver/9362.
+
+2003-06-20 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * config/alpha/alpha.c (alpha_file_start): Fix typo.
+
+2003-06-20 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/mips.h (PUT_SDB_FUNCTION_END): Pass 0 as third arg
+ to ASM_OUTPUT_SOURCE_LINE.
+
+2003-06-20 Daniel Egger <degger@fhm.edu>
+ Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/install.texi (Building): Correct and improve statement
+ about parallel builds.
+
+2003-06-20 Andreas Jaeger <aj@suse.de>
+
+ * c-common.c: Change _Bool to bool reverting part of the last
+ patch.
+
+2003-06-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.h (expand_function_end): Remove all parameters.
+ * function.c (expand_function_end): Remove all parameters.
+ Use input_location. Never expand_end_bindings.
+ * c-decl.c (c_expand_body_1): Adjust expand_function_end call.
+ * coverage.c (create_coverage): Likewise.
+
+2003-06-20 Nick Clifton <nickc@redhat.com>
+
+ * doc/extend.texi (ARM Built-in Functions): New node. Document
+ ARM builtin functions for iWMMXt support.
+
+2003-06-20 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/install.texi (--with-gnu-as): Mention SPARC/Solaris and
+ SPARC64/Solaris as platforms where --with-gnu-as makes a difference.
+ (--with-as): Add @anchor.
+ (--with-gnu-ld): Fix typo.
+ (--with-ld): Add @uref to --with-as.
+
+2003-06-19 Zack Weinberg <zack@codesourcery.com>
+
+ * doc/tm.texi: Uniformly use @defmac for macros, rather than
+ @table items. Minor formatting and editorial corrections.
+
+2003-06-20 Neil Booth <neil@daikokuya.co.uk>
+
+ * line-map.c, line-map.h: Convert to ISO prototypes.
+
+2003-06-20 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcse.c (store_killed_in_insn): Fix.
+
+2003-06-19 Zack Weinberg <zack@codesourcery.com>
+
+ * target.h (asm_out.file_start, file_start_app_off,
+ file_start_file_directive): New hooks.
+ * target-def.h (TARGET_ASM_FILE_START_FILE_DIRECTIVE,
+ TARGET_ASM_FILE_START_APP_OFF, TARGET_ASM_FILE_START):
+ New hook-definition macros.
+ * doc/tm.texi: Document new hooks; remove docs of ASM_FILE_START.
+ * varasm.c (default_file_start): New.
+ * output.h: Prototype it.
+ * toplev.c (init_asm_output): Use targetm.asm_out.file_start.
+ * system.h: Poison ASM_FILE_START.
+
+ * config/alpha/alpha.c (alpha_write_verstamp): Delete.
+ (alpha_file_start): New, define if !TARGET_ABI_UNICOSMK.
+ (unicosmk_asm_file_start): Rename unicosmk_file_start,
+ make static, take no arguments.
+ (TARGET_ASM_FILE_START, TARGET_ASM_FILE_END,
+ TARGET_ASM_FILE_START_FILE_DIRECTIVE): Set as appropriate.
+ * config/alpha/unicosmk.h: Don't define ASM_FILE_START nor
+ TARGET_ASM_FILE_END. Remove reference to ASM_FILE_START in
+ comment.
+ * config/arc/arc.c (arc_asm_file_start): Rename
+ arc_file_start, take no arguments, make static.
+ (TARGET_ASM_FILE_START): Set it.
+ * config/arm/arm.c (aof_file_start): New static function.
+ (TARGET_ASM_FILE_START): Set it, when appropriate.
+ * config/arm/coff.h, config/arm/elf.h:
+ Set TARGET_ASM_FILE_START_APP_OFF to true.
+ * config/avr/avr.c (asm_file_start): Rename avr_file_start,
+ take no arguments, make static.
+ (TARGET_ASM_FILE_START, TARGET_ASM_FILE_START_FILE_DIRECTIVE):
+ Set them.
+ * config/c4x/c4x.c (c4x_file_start): New static function.
+ (TARGET_ASM_FILE_START, TARGET_ASM_FILE_START_FILE_DIRECTIVE):
+ Set them.
+ * config/cris/cris.c (cris_file_start): New static function.
+ (TARGET_ASM_FILE_START): Set it.
+ * config/dsp16xx/dsp16xx.c (coff_dsp16xx_file_start): Rename
+ dsp16xx_file_start, make static.
+ (luxworks_dsp16xx_file_start): Delete.
+ (TARGET_ASM_FILE_START): Set it.
+ * config/h8300/h8300.c (asm_file_start): Rename
+ h8300_file_start, make static, take no arguments.
+ (TARGET_ASM_FILE_START): Set it.
+ * config/i370/i370.c (i370_file_start): New static function.
+ (TARGET_ASM_FILE_START): Set it.
+ * config/i386/i386.c (x86_file_start): New static function.
+ (TARGET_ASM_FILE_START): Set it.
+ * config/i386/i386.h (X86_FILE_START_VERSION_DIRECTIVE,
+ X86_FILE_START_FLTUSED): New macros, default to false.
+ * config/i386/i386-interix.h: Override X86_FILE_START_FLTUSED to 1.
+ * config/i386/sysv4.h, config/i386/sco5.h: Override
+ X86_FILE_START_VERSION_DIRECTIVE to true.
+ * config/ia64/ia64.c (ia64_file_start): New static function.
+ (TARGET_ASM_FILE_START): Set it.
+ (emit_safe_across_calls): Take no arguments.
+ * config/ia64/ia64.md: Update to match.
+ * config/m32r/m32r.c (m32r_asm_file_start): Rename
+ m32r_file_start, make static, take no arguments.
+ (TARGET_ASM_FILE_START): Set it.
+ * config/m68hc11/m68hc11.c (m68hc11_asm_file_start): Rename
+ m68hc11_file_start, make static, take no arguments.
+ (TARGET_ASM_FILE_START, TARGET_ASM_FILE_START_FILE_DIRECTIVE): Set.
+ (print_options): Delete.
+ * config/m68k/m68k.c (m68k_hp320_file_start): New static function.
+ (TARGET_ASM_FILE_START_APP_OFF): Set.
+ * config/m68k/hp320.h: Set TARGET_ASM_FILE_START to
+ m68k_hp320_file_start.
+ * config/mips/mips.c (iris6_asm_file_start, mips_asm_file_start):
+ Make static, take no arguments.
+ (TARGET_ASM_FILE_START, TARGET_ASM_FILE_START_FILE_DIRECTIVE): Set.
+ * config/mmix/mmix.c (mmix_asm_file_start): Rename
+ mmix_file_start, make static, take no arguments.
+ (TARGET_ASM_FILE_START, TARGET_ASM_FILE_START_FILE_DIRECTIVE): Set.
+ * config/mn10300/mn10300.c (asm_file_start): Rename
+ mn10300_file_start, make static, take no arguments.
+ (TARGET_ASM_FILE_START, TARGET_ASM_FILE_START_FILE_DIRECTIVE): Set.
+ * config/ns32k/ns32k.c (TARGET_ASM_FILE_START_APP_OFF): Set.
+ * config/pa/pa.c (pa_file_start_level, pa_file_start_space,
+ pa_file_start_file, pa_file_start_mcount, pa_elf_file_start,
+ pa_som_file_start, pa_linux_file_start, pa_hpux64_gas_file_start,
+ pa_hpux64_hpas_file_start): New static functions.
+ * config/pa/elf.h: Set TARGET_ASM_FILE_START to pa_elf_file_start.
+ * config/pa/pa-linux.h: Set TARGET_ASM_FILE_START to
+ pa_linux_file_start.
+ * config/pa/pa64-hpux.h: Set TARGET_ASM_FILE_START to
+ pa_hpux64_gas_file_start or pa_hpux64_hpas_file_start, as
+ appropriate.
+ * config/pa/som.h: Set TARGET_ASM_FILE_START to pa_som_file_start.
+ * config/rs6000/rs6000.c: Include xcoffout.h when TARGET_XCOFF.
+ (rs6000_file_start): Make static, take no arguments. Reset
+ default_cpu under certain conditions.
+ (rs6000_xcoff_file_start): New function.
+ * config/rs6000/rs6000.h (TARGET_ASM_FILE_START): Set.
+ * config/rs6000/xcoff.h (TARGET_ASM_FILE_START,
+ TARGET_ASM_FILE_START_FILE_DIRECTIVE): Override.
+ * config/sh/sh.c (output_file_start): Rename
+ sh_file_start, make static, take no arguments. Merge in old
+ code from sh/elf.h's ASM_FILE_START, conditioned on TARGET_ELF.
+ (TARGET_ASM_FILE_START, TARGET_ASM_FILE_START_FILE_DIRECTIVE): Set.
+ * config/sh/sh.c (TARGET_ELF): Define to 0.
+ * config/sh/elf.h (TARGET_ELF): Redefine to 1.
+ * config/v850/v850.c (asm_file_start): Delete.
+ (TARGET_ASM_FILE_START_FILE_DIRECTIVE): Set.
+ * config/vax/vax.c (vax_file_start): New static function.
+ (TARGET_ASM_FILE_START, TARGET_ASM_FILE_START_APP_OFF): Set.
+
+ * config/darwin.h: Override ASM_FILE_START_FILE_DIRECTIVE to false.
+ * config/elfos.h, config/svr3.h, config/arm/elf.h, config/arm/pe.h
+ * config/i386/att.h, config/i386/gas.h, config/i386/linux.h
+ * config/i386/sysv4.h, config/i386/sco5.h, config/i960/i960-coff.h
+ * config/m68k/coff.h, config/m68k/hp320.h, config/mcore/mcore-pe.h
+ * config/vax/vaxv.h: Set ASM_FILE_START_FILE_DIRECTIVE to true.
+
+ * config/darwin.h, config/elfos.h, config/alpha/elf.h
+ * config/alpha/openbsd.h, config/alpha/osf.h, config/alpha/vms.h
+ * config/arc/arc.h, config/arm/aof.h, config/arm/aout.h
+ * config/arm/coff.h, config/arm/elf.h, config/arm/pe.h
+ * config/avr/avr.h, config/c4x/c4x.h, config/cris/cris.h
+ * config/dsp16xx/dsp16xx.h, config/h8300/elf.h, config/h8300/h8300.h
+ * config/i370/i370.h, config/i386/att.h, config/i386/gas.h
+ * config/i386/i386-interix.h, config/i386/linux.h, config/i386/sysv4.h
+ * config/i386/sco5.h, config/i960/i960-coff.h, config/i960/i960.h
+ * config/ia64/ia64.h, config/ia64/sysv4.h, config/m32r/m32r.h
+ * config/m68hc11/m68hc11.h, config/m68k/coff.h, config/m68k/m68k.h
+ * config/mcore/mcore-pe.h, config/mips/iris6.h, config/mips/mips.h
+ * config/mmix/mmix.h, config/mn10300/mn10300.h, config/ns32k/ns32k.h
+ * config/pa/elf.h, config/pa/pa-linux.h, config/pa/pa64-hpux.h
+ * config/pa/som.h, config/pdp11/pdp11.h, config/rs6000/linux64.h
+ * config/rs6000/lynx.h, config/rs6000/xcoff.h, config/sh/elf.h
+ * config/sh/sh.h, config/sparc/sparc.h, config/v850/v850.h
+ * config/vax/vax.h, config/vax/vaxv.h: Don't (re)define ASM_FILE_START.
+
+ * config/alpha/alpha-protos.h, config/arc/arc-protos.h
+ * config/avr/avr-protos.h, config/dsp16xx/dsp16xx-protos.h
+ * config/h8300/h8300-protos.h, config/ia64/ia64-protos.h
+ * config/m32r/m32r-protos.h, config/m68hc11/m68hc11-protos.h
+ * config/mips/mips-protos.h, config/mmix/mmix-protos.h
+ * config/mn10300/mn10300-protos.h, config/rs6000/rs6000-protos.h
+ * config/sh/sh-protos.h, config/v850/v850-protos.h: Update.
+
+ * xcoffout.h, config/rs6000/aix.h, config/rs6000/xcoff.h:
+ Remove reference to ASM_FILE_START in comment.
+ * config/arm/aof.h, config/arm/aout.h, config/arm/freebsd.h
+ * config/arm/linux-gas.h, config/arm/netbsd-elf.h
+ * config/arm/netbsd.h: Delete definition of ARM_OS_NAME.
+
+2003-06-19 Graeme Peterson <gp@qnx.com>
+
+ * gcc.c (target_sysroot_suffix, target_sysroot_hdrs_suffix,
+ SYSROOT_SUFFIX_SPEC, SYSROOT_HEADERS_SUFFIX_SPEC, sysroot_suffix_spec,
+ sysroot_hdrs_suffix_spec): New.
+ (static_specs): Initialize new variables.
+ (add_sysroot_suffix_prefix, do_spec_1, main): Use new variables.
+ * doc/tm.texi (SYSROOT_SUFFIX_SPEC, SYSROOT_HEADERS_SUFFIX_SPEC):
+ New macros.
+
+2003-06-19 Andreas Jaeger <aj@suse.de>
+
+ * c-aux-info.c: Convert to ISO C90.
+ * c-pragma.c: Likewise.
+ * c-common.c: Likewise.
+ * c-common.h: Likewise.
+ * c-convert.c: Likewise.
+ * c-cppbuiltin.c: Likewise.
+ * c-dump.c: Likewise.
+ * c-decl.c: Likewise
+ * c-format.c: Likewise.
+ * c-incpath.c: Likewise.
+ * c-incpath.h: Likewise.
+
+2003-06-19 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_errno_check): Assume that flag_errno_math
+ and HONOR_NANS have been tested before calling here. Only try
+ to set errno ourselves if the decl can't throw an exception.
+ (expand_builtin_mathfn): Move the code to stabilize the arg
+ after the main switch, so that that its only done when needed.
+ BUILT_IN_SQRT{,F,L} doesn't set errno if its arg is nonnegative.
+ Don't modify the original expr when stabilizing the argument.
+ (expand_builtin_mathfn_2): Likewise, move the code to stabilize
+ the args after the main switch, and don't modify the orginal exp.
+
+2003-06-19 Aldy Hernandez <aldyh@redhat.com>
+
+ * expr.c (const_vector_from_tree): Initialize remaining elements
+ to 0.
+
+2003-06-19 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md ("spe_evfscfsi"): Change operand types.
+ Change "fix" to "float".
+
+2003-06-19 Andreas Jaeger <aj@suse.de>
+
+ * c-tree.h: Remove declaration of poplevel.
+
+ * tree.h: Remove declaration of approx_sqrt.
+
+ * c-lex.c: Remove redundant declaration of asm_out_file.
+
+ * flags.h: Remove declaration of warn_unknown_pragma and
+ main_input_filename.
+
+ * rtl.h: Remove functions from fold-const.c since they're already
+ declared in tree.h.
+
+ * regs.h: Remove redundant declaration of reg_names.
+
+ * bt-load.c (migrate_btr_defs): Correct printf arguments.
+
+ * protoize.c: Fix breakage from last patch.
+
+2003-06-19 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * hooks.h (hook_reg_class_void_no_regs): Only declare if tm.h
+ has been included.
+
+2003-06-18 James A Morrison <ja2morri@student.math.uwaterloo.ca>
+
+ * config/sparc/sparc.c: Update copyright year.
+
+2003-06-19 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (init_cumulative_args): Limit CALL_LIBCALL
+ to ABI_V4.
+
+2003-06-18 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ PR bootstrap/4068
+ * config/i386/liunx.h: Don't include sys/ucontext.h for glibc 2.0.
+
+2003-06-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (TARGET_INITIALIZER and friends): Move
+ to the end of the file. Remove unnecessary prototypes.
+
+2003-06-19 Hans-Peter Nilsson <hp@axis.com>
+
+ * bt-load.c (migrate_btr_def) [INSN_SCHEDULING]: Conditionalize
+ calls to insn_default_latency and result_ready_cost. Initialize
+ def_latency to 1.
+
+2003-06-18 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/unwind-ia64.c (_Unwind_GetCFA): New.
+ (_Unwind_FindEnclosingFunction): Implement.
+
+2003-06-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * toplev.c (rest_of_handle_sched): Hide the entire function if
+ INSN_SCHEDULING is not defined.
+ (rest_of_compilation): Call rest_of_handle_sched() only when
+ INSN_SCHEDULING is defined.
+
+2003-06-18 Stephen Clarke <stephen.clarke@superh.com>
+ J"orn Rennecke <joern.rennecke@superh.com>
+
+ * bt-load.c: New file.
+ * Makefile.in (OBJS): Include bt-load.o
+ (bt-load.o): Add dependencies.
+ * flags.h (flag_branch_target_load_optimize): Declare.
+ (flag_branch_target_load_optimize2): Likewise.
+ * hooks.c (hook_reg_class_void_no_regs): New function.
+ (hook_bool_bool_false): Likewise.
+ * hooks.h (hook_reg_class_void_no_regs, hook_bool_bool_false): Declare.
+ * rtl.h (branch_target_load_optimize): Declare.
+ * target-def.h (TARGET_BRANCH_TARGET_REGISTER_CLASS): Define.
+ (TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED): Likewise.
+ (TARGET_INITIALIZER): Include these.
+ * target.h (struct gcc_target): Add branch_target_register_class
+ and branch_target_register_callee_saved members.
+ * toplev.c (enum dump_file_index): Add DFI_branch_target_load
+ (dump_file) Add "tars" entry.
+ (flag_branch_target_load_optimize): New variable.
+ (flag_branch_target_load_optimize2): Likewise.
+ (lang_independent_options): Add entries for new options.
+ (rest_of_compilation): Call branch_target_load_optimize.
+ * doc/tm.texi (TARGET_BRANCH_TARGET_REGISTER_CLASS): Document.
+ (TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED): Likewise.
+ * doc/invoke.texi: Document -fbranch-target-load-optimize and
+ -fbranch-target-load-optimize2.
+ * rtl.h (epilogue_completed): Declare.
+ * recog.c (epilogue_completed): New variable.
+ * toplev.c (rest_of_compilation): Set it.
+ * flow.c (mark_regs_live_at_end): Use it.
+ * config/ia64/ia64.c (ia64_output_mi_thunk): Set it.
+ * config/rs6000/rs6000.c (rs6000_output_mi_thunk): Likewise.
+ * config/sh/sh.c (sh_output_mi_thunk): Likewise.
+ * config/sparc/sparc.c (sparc_output_mi_thunk): Likewise.
+
+ * sh.c (shmedia_space_reserved_for_target_registers): New variable.
+ (sh_target_reg_class): New function.
+ (sh_optimize_target_register_callee_saved): Likwise.
+ (shmedia_target_regs_stack_space): Likewise.
+ (shmedia_reserve_space_for_target_registers_p): Likewise.
+ (shmedia_target_regs_stack_adjust): Likewise.
+ (TARGET_BRANCH_TARGET_REGISTER_CLASS): Override.
+ (TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED): Likewise.
+ (calc_live_regs): If flag_branch_target_load_optimize2 and
+ TARGET_SAVE_ALL_TARGET_REGS is enabled, and we have space reserved
+ for target registers, make sure that we save all target registers.
+ (sh_expand_prologue, sh_expand_epilogue): Take target register
+ optimizations into account. Collapse stack adjustments if that
+ is beneficial.
+ (initial_elimination_offset): Reserve space for target registers
+ if necessary.
+ * sh.h (SAVE_ALL_TR_BIT, TARGET_SAVE_ALL_TARGET_REGS): Define.
+ (OPTIMIZATION_OPTIONS): Enable flag_branch_target_load_optimize.
+
+2003-06-18 Nick Clifton <nickc@redhat.com>
+
+ * config.gcc: Add an extra_header for ARM targets.
+ Support configuring with --with-cpu=iwmmxt.
+ * doc/invoke.texi: Document new value for -mcpu= ARM switch.
+ * config/arm/aof.h (REGISTER_NAMES): Add iwmmxt register
+ names. Fix formatting.
+ * config/arm/aout.h (REGISTER_NAMES): Add iwmmxt register
+ names.
+ * config/arm/arm-protos.h (arm_emit_vector_const): New
+ prototype.
+ (arm_output_load_gr): New prototype.
+ * config/arm/arm.c (extra_reg_names1): Delete.
+ (TARGET_INIT_BUILTINS, TARGET_EXPAND_BUILTIN, FL_IWMMXT,
+ * arch_is_iwmmxt): Define.
+ (all_cores, all_architecture): Add entry for iwmmxt.
+ (arm_override_options): Add support for iwmmxt.
+ (use_return_insn, arm_function_arg, arm_legitimate_index_p,
+ arm_print_value, arm_rtx_costs_1, output_move_double,
+ arm_compute_save_reg_mask, arm_output_epilogue,
+ arm_get_frame_size, arm_expand_prologue, arm_print_operand,
+ arm_assemble_integer, arm_hard_regno_ok, arm_regno_class):
+ Likewise.
+ (arm_init_cumulative_args): Count iwmmxt registers.
+ (arm_function_ok_for_sibcall): Return false of sibcall_blocked
+ has been set.
+ (struct minipool_node): Add fix_size field.
+ (add_minipool_forward_ref): Add support for 8-byte aligning of
+ the pool.
+ (add_minipool_backward_ref, add_minipool_offsets,
+ dump_minipool, push_minipool_fix): Likewise.
+ (struct builtin_description): New struct.
+ (builtin_description): New array of iwmmxt builtin functions.
+ (arm_init_iwmmxt_builtins): New function.
+ (arm_init_builtins): New function.
+ (safe_vector_operand): New function.
+ (arm_expand_binop_builtin): New function.
+ (arm_expand_unop_builtin): New function.
+ (arm_expand_builtin): New function.
+ (arm_emit_vector_const): New function.
+ (arm_output_load_gr): New function.
+ * config/arm/arm.h (TARGET_CPU_iwmmxt, TARGET_IWMMXT,
+ TARGET_REALLY_IWMMXT, arm_arch_iwmmxt, IWMMXT_ALIGNMENT,
+ TYPE_NEEDS_IWMMXT_ALIGNMENT, ADJUST_FIELD_ALIGN,
+ DATA_ALIGNMENT, LOCAL_ALIGNMENT, VECTOR_MODE_SUPPORTED_P): Define.
+ (BIGGEST_ALIGNMENT): Set to 64 if ATPCS support is enabled.
+ (CPP_CPU_ARCH_SPEC): Add entries for iwmmxt.
+ (FIXED_REGISTERS, CALL_USED_REGISTERS, REG_ALLOC_ORDER,
+ reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS,
+ REG_CLASS_FOR_LETTER): Add iwmmxt registers.
+ (SUBTARGET_CONDITIONAL_REGISTER_USAGE): Disable iwmmxt
+ registers unless the iwmmxt target is selected.
+ (FIRST_IWMMXT_GR_REGNUM, LAST_IWMMXT_GR_REGNUM,
+ FIRST_IWMMXT_REGNUM, LAST_IWMMXT_REGNUM, IS_IWMMXT_REGNUM,
+ IS_IWMMXT_GR_REGNUM): Define.
+ (FIRST_PSEUDO_REGISTER): Bump to 63.
+ (struct machine_function): Add sibcall_blocked field.
+ (Struct CUMULATIVE_ARGS): Add iwmmxt_nregs, named_count and
+ nargs fields.
+ (enum arm_builtins): New enum list.
+ * config/arm/arm.md (UNSPEC_WSHUFH, UNSPEC_WACC,
+ UNSPEC_TMOVMSK, UNSPEC_WSAD, UNSPEC_WSADZ, UNSPEC_WMACS,
+ UNSPEC_WMACU, UNSPEC_WMACSZ, UNSPEC_WMACUZ, UNSPEC_CLRDI,
+ UNSPEC_WMADDS, UNSPEC_WMADDU): New unspecs.
+ (VUNSPEC_TMRC, VUNSPEC_TMCR, VUNSPEC_ALIGN8, VUNSPEC_WCMP_EQ,
+ VUNSPEC_WCMP_GTU, VUNSPEC_WCMP_GT): New vunspecs.
+ (movv2si, movv4hi, movv8qi): New expands for vector moves.
+ Include iwmmxt.md.
+ * config/arm/t-xscale-elf (MULTILIB_OPITONS): Add iwmmxt
+ multilib.
+ (MULTILIB_DIRNAMES, MULTILIB_REDUNDANT_DIRS): Likewise.
+ * config/arm/mmintrin.h: New ARM specific header file.
+ * config/arm/iwmmx.md: New iWMMXt specific machine patterns.
+
+2003-06-18 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * toplev.c (Remaining -d letters summary): Update.
+
+2003-06-18 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * config/rs6000/rs6000.c (init_cumulative_args): Add and handle LIBCALL
+ argument.
+ (function_arg): Handle CALL_LIBCALL flag.
+ * config/rs6000/rs6000-protos.h (init_cumulative_args): Update
+ prototype.
+ * config/rs6000/rs6000.h (CALL_LIBCALL): New macro.
+ (INIT_CUMULATIVE_LIBCALL_ARGS): New macro.
+ (INIT_CUMULATIVE_ARGS): Add LIBCALL argument.
+ (INIT_CUMULATIVE_INCOMING_ARGS): Likewise.
+
+2003-06-18 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Update.
+ * common.opt: New options.
+ * opts.c (maybe_warn_unused_parameter, set_Wextra, handle_param,
+ set_Wunused): New.
+ (common_handle_option): Handle new options.
+ * toplev.c (set_target_switch): Export.
+ (set_Wextra, set_Wunused, maybe_warn_unused_parameter): Move to opts.c.
+ (decode_W_option): -Wunused and -Wextra handled in opts.c now.
+ (independent_decode_option): More options handled in opts.c now.
+ Change prototype.
+ * toplev.h (set_target_switch): New.
+
+2003-06-17 Robert Abeles <rabeles@archaelogic.com>
+
+ PR debug/4252
+ * c-opts.c (c_common_handle_option): Pass -fdump argument suffix
+ to dump_switch_p().
+ * tree-dump.c (dump_switch_p): Remove redundant 'dump-' prefix
+ from static strings in dump_files.
+
+2003-06-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * system.h (ANSI_PROTOTYPES, PTR_CONST, LONG_DOUBLE, VPARAMS,
+ VA_OPEN, VA_FIXEDARG, VA_CLOSE, VA_START): undef and poison these
+ libiberty macros.
+
+2003-06-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/10929
+ * tree-inline.c (expand_call_inline): Don't warn about failing to
+ inline a function which was made inline by -finline-functions.
+
+2003-06-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Update to ISO C.
+ * config/h8300/h8300.c: Likewise.
+ * config/h8300/h8300.h: Likewise.
+ * config/h8300/h8300.md: Likewise.
+
+2003-06-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Replace BUILD_CC references with CC_FOR_BUILD.
+ * configure: Regenerate.
+ * Makefile.in: Replace BUILD_CC references with CC_FOR_BUILD.
+
+2003-06-17 Ranjit Mathew <rmathew@hotmail.com>
+
+ * install.texi (Testing): Add information on how to run Java
+ runtime tests separately.
+
+2003-06-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/mips.md (trap): Use break 0 when !TARGET_GAS.
+
+ * config/mips/iris6-o32.h (MIPS_ISA_DEFAULT): Remove.
+ (MIPS_CPU_STRING_DEFAULT): Redefine to mips2.
+
+2003-06-17 Christopher Faylor <cgf@redhat.com>
+
+ * doc/install.texi: Add msvc rebuild caveat.
+
+2003-06-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/sh/coff.h: Replace Hitachi with Renesas.
+ * config/sh/elf.h: Likewise.
+ * config/sh/embed-elf.h: Likewise.
+ * config/sh/lib1funcs.asm: Likewise.
+ * config/sh/sh-protos.h: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/sh/sh.h: Likewise.
+ * config/sh/sh.md: Likewise.
+
+2003-06-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog.3: Fix comment typos.
+ * ChangeLog.6: Likewise.
+ * config/d30v/d30v.c: Likewise.
+ * config/h8300/h8300.md: Likewise.
+ * config/m32r/m32r.md: Likewise.
+ * config/mips/mips.c: Likewise.
+ * config/mips/mips.md: Likewise.
+ * config/ns32k/NOTES: Likewise.
+
+2003-06-17 Ranjit Mathew <rmathew@hotmail.com>
+ Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/sourcebuild.texi (libgcj Tests): Simplify instructions on how
+ to run Java runtime tests separately.
+
+2003-06-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Update a comment.
+
+2003-06-17 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (ROUND_TYPE_ALIGN, LOCAL_ALIGNMENT): Complex modes
+ are aligned like integral modes.
+ (SH5_WOULD_BE_PARTIAL_NREGS): Also test for CDImode and DCmode.
+
+ * sh.h (EXTRA_CONSTRAINT_Csy): Allow PIC_DIRECT_ADDR_P.
+ (LEGITIMATE_PIC_OPERAND_P): Allow LABEL_REF.
+ * sh.md (*pt): Remove.
+
+ * sh.h (REG_ALLOC_ORDER): Avoid squandering call-saved registers.
+
+ * sh.md (return_media_rte): New pattern.
+ (return_media): Use it.
+
+2003-06-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/contrib.texi: Replace Hitachi with Renesas.
+ * doc/install.texi: Likewise.
+ * doc/invoke.texi: Likewise.
+
+2003-06-17 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (CONST_OK_FOR_J16): Fix HOST_BITS_PER_WIDE_INT >= 64
+ behaviour.
+
+2003-06-17 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * doc/tm.texi (MD_FALLBACK_FRAME_STATE_FOR): Mention MAKE_THROW_FRAME.
+
+ * config/rs6000/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Partly revert
+ 2003-01-23 patch. Corrected to handle kernels with changed ucontext.
+
+ * config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Error on invalid
+ -msdata=eabi usages.
+
+ * gcc/config/rs6000/sysv4.h (USE_LIBC_1): Delete all uses.
+
+2003-06-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alloc-pool.c: Don't check HAVE_LONG_DOUBLE.
+ * fixinc/gnu-regex.c: Don't define `volatile'.
+ * ggc-page.c: Don't check HAVE_LONG_DOUBLE.
+ * ggc-simple.c: Likewise.
+ * system.h: Don't define `volatile'.
+
+ * aclocal.m4 (gcc_AC_C_VOLATILE, gcc_AC_C_LONG_DOUBLE): Delete.
+ * configure.in (gcc_AC_C_VOLATILE, gcc_AC_C_LONG_DOUBLE): Don't
+ call these macros.
+ * config.in, configure: Regenerated.
+
+2003-06-17 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * config/ia64/ia64.c (ia64_expand_builtin, case IA64_BUILTIN_BSP):
+ Handle POINTERS_EXTEND_UNSIGNED.
+
+2003-06-17 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/mips.c (TARGET_ASM_UNALIGNED_DI_OP) [TARGET_IRIX5 &&
+ !TARGET_IRIX6]: Define as NULL.
+
+2003-06-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (sparc_va_arg): Don't align 16-byte+ structures.
+
+2003-06-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * dbxout.c (dbxout_source_line_counter): New global variable.
+ Mark it with GTY(()).
+ (dbxout_source_line): Increment dbxout_source_line_counter
+ and pass it to ASM_OUTPUT_SOURCE_LINE.
+ * sdbout.c (sdbout_source_line_counter): New global variable.
+ Mark it with GTY(()).
+ (unnamed_struct_number): Mark it with GTY(()).
+ (sdbout_source_line): Increment sdbout_source_line_counter
+ and pass it to ASM_OUTPUT_SOURCE_LINE.
+ * xcoffout.c (ASM_OUTPUT_SOURCE_LINE): Add third parameter
+ (xcoffout_source_line): Pass 0 as third argument to
+ ASM_OUTPUT_SOURCE_LINE.
+ (xcoffout_begin_prologue): Likewise.
+ * config/dbxout.h (ASM_OUTPUT_SOURCE_LINE): Add third parameter.
+ Use it instead of 'sym_lineno' but without incrementing it.
+ * config/dbxelf.h (ASM_OUTPUT_SOURCE_LINE): Likewise.
+ * config/lynx.h (ASM_OUTPUT_SOURCE_LINE): Likewise.
+ * config/ptx4.h (ASM_OUTPUT_SOURCE_LINE): Likewise.
+ * config/alpha/alpha.c (alpha_start_function): Pass 0 as third
+ argument to ASM_OUTPUT_SOURCE_LINE.
+ * config/alpha/alpha.h (ASM_OUTPUT_SOURCE_LINE): Add third parameter.
+ * config/arm/aout.h: Remove useless comment.
+ * config/avr/avr.h (ASM_OUTPUT_SOURCE_LINE): Add third parameter.
+ * config/i960/i960.h (ASM_OUTPUT_SOURCE_LINE): Likewise.
+ * config/m32r/m32r.h (ASM_OUTPUT_SOURCE_LINE): Add third parameter.
+ Use it instead of 'sym_lineno' but without incrementing it.
+ * config/m68k/hp320.h (ASM_OUTPUT_SOURCE_LINE): Add third parameter.
+ * config/mcore/mcore-pe.h (ASM_OUTPUT_SOURCE_LINE): Add third
+ parameter. Use it instead of 'sym_lineno' but without incrementing it.
+ * config/mips/mips.c (mips_output_function_prologue): Pass 0 as third
+ argument to ASM_OUTPUT_SOURCE_LINE.
+ * config/mips/mips.h (ASM_OUTPUT_SOURCE_LINE): Add third parameter.
+ * config/mmix/mmix.h (ASM_OUTPUT_SOURCE_LINE): Likewise.
+ * config/pa/som.h (ASM_OUTPUT_SOURCE_LINE): Add third parameter.
+ Use it instead of 'sym_lineno' but without incrementing it.
+ * config/rs6000/linux64.h (ASM_OUTPUT_SOURCE_LINE): Likewise.
+ * config/sh/elf.h (ASM_OUTPUT_SOURCE_LINE): Likewise.
+ * config/sparc/aout.h (ASM_OUTPUT_SOURCE_LINE): Likewise.
+ * config/sparc/pbd.h (ASM_OUTPUT_SOURCE_LINE): Likewise.
+ * doc/tm.texi (ASM_OUTPUT_SOURCE_LINE): Document third parameter.
+
+2003-06-17 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_expand_block_move): Declare.
+ (expand_block_move, output_block_move): Remove.
+ * config/mips/mips.h (enum block_move_type): Remove.
+ * config/mips/mips.c (block_move_call, output_block_move): Remove.
+ (mips_block_move_straight, mips_adjust_block_mem): New function.
+ (mips_block_move_loop): Renamed and reworked from block_move_loop.
+ (mips_expand_block_move): Likewise expand_block_move. Return false
+ to fall back on the target-independent code.
+ * config/mips/mips.md (movstrsi): Use mips_expand_block_move.
+ (movstrsi_internal*): Remove.
+
+2003-06-16 Zack Weinberg <zack@codesourcery.com>
+
+ * cpplib.h, cpphash.h, cppcharset.c, cpperror.c, cppexp.c
+ * cppfiles.c, cpphash.c, cppinit.c, cpplex.c, cpplib.c
+ * cppmacro.c, cpppch.c, cpptrad.c, cppspec.c: Convert to
+ ISO C: new-style function declarations, no need for PARAMS,
+ no special punctuation on indirect function calls, use string
+ constant concatenation where convenient.
+
+2003-06-17 Andreas Jaeger <aj@suse.de>
+
+ * rtl.h: Remove declarations from coverage.h.
+ * toplev.c: Include coverage.h.
+ * Makefile.in (toplev.o): Depend on coverage.h.
+
+ * toplev.h: Remove extra declaration of print_time.
+
+ * gengtype.c (close_output_files): Remove duplicated declaration.
+
+2003-06-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/sparc/sysv4.h: Remove target-independent comment;
+ replace "GNU CC" with "GCC".
+ * config/vxworks.h: Replace "GNU compiler" with "GCC".
+ * config/sparc/aout.h, config/sparc/biarch64.h, config/sparc/elf.h,
+ config/sparc/freebsd.h, config/sparc/linux.h, config/sparc/linux64.h,
+ config/sparc/lite.h, config/sparc/litecoff.h, config/sparc/liteelf.h,
+ config/sparc/netbsd-elf.h, config/sparc/openbsd.h,
+ config/sparc/rtemself.h, config/sparc/sol2-64.h,
+ config/sparc/sol2-bi.h, config/sparc/sol2-gas-bi.h,
+ config/sparc/sol2-gld-bi.h, config/sparc/sol2-gld.h,
+ config/sparc/sol2.h, config/sparc/sp64-aout.h,
+ config/sparc/sp64-elf.h, config/sparc/sp86x-elf.h,
+ config/sparc/sparc-protos.h, config/sparc/sysv4-only.h: Replace
+ "GNU compiler", "GNU CC" with "GCC".
+ * config/sparc/cypress.md, config/sparc/hypersparc.md,
+ config/sparc/sparc-modes.def, config/sparc/sparc.c,
+ config/sparc/sparc.md, config/sparc/sparclet.md,
+ config/sparc/supersparc.md, config/sparc/ultra1_2.md,
+ config/sparc/ultra3.md: Replace "GNU CC", "GNU Compiler", and
+ "GNU C Compiler" with "GCC".
+ * config/ip2k/ip2k.h: Replace "GNU CC" and "GNU compiler" with "GCC".
+
+2003-06-16 Aldy Hernandez <aldyh@redhat.com>
+
+ * simplify-rtx.c (simplify_subreg): Do not over-extend vector
+ constants.
+
+ * testsuite/gcc.c-torture/execute/simd-4.c: New.
+
+2003-06-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/ip2k/ip2k.h: Remove target-independent comments.
+
+ * config.gcc: Explicitly mention elfos.h in ip2k entry.
+ * config/ip2k/ip2k.h: Don't #include it here.
+
+2003-06-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bitmap.c, builtins.c, c-incpath.c, cgraph.c, config/frv/frv.c,
+ config/mips/mips.c, cppfiles.c, cpphash.c, cppinit.c, cpplib.c,
+ dwarf2out.c, dwarfout.c, except.c, expr.c, expr.h, fold-const.c,
+ function.c, gcc.c, genoutput.c, gensupport.c, global.c,
+ haifa-sched.c, hashtable.c, ifcvt.c, integrate.c, local-alloc.c,
+ loop.c, mips-tdump.c, mips-tfile.c, mkdeps.c, protoize.c,
+ read-rtl.c, recog.h, reload1.c, sbitmap.c, ssa-dce.c,
+ stringpool.c, tlink.c, tree.c, varasm.c, varray.c: Don't use
+ the PTR macro.
+
+ * gengtype.c: Don't use UNION_INIT_ZERO.
+ * system.h (UNION_INIT_ZERO): Delete.
+
+2003-06-16 Richard Henderson <rth@redhat.com>
+
+ * simplify-rtx.c (simplify_subreg): Use GET_MODE_SIZE instead of
+ GET_MODE_UNIT_SIZE when simplifying constant vectors.
+
+2003-06-16 Andreas Jaeger <aj@suse.de>
+
+ * timevar.c (get_run_time): Remove function provided also by
+ libiberty.
+ * timevar.h: Remove get_run_time declaration.
+
+2003-06-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m68hc11/m68hc11.c (m68hc11_rtx_costs): Remove
+ unreachable code.
+
+2003-06-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-attrs.def, builtin-attrs.def, builtins.c, cpplex.c,
+ cpplib.c, gencheck.c, gengenrtl.c, machmode.def, protoize.c: Don't
+ use macros from "symcat.h", instead rely on ISO C.
+
+ * system.h: Don't include "symcat.h".
+ * configure.in (AC_C_STRINGIZE): Delete.
+ * config.in, configure: Regenerate.
+
+2003-06-16 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Makefile.in (install-mkheaders): Use INSTALL_SCRIPT for scripts.
+
+ * tree.h (STMT_CHECK): New macro.
+ Also upper-case argument names on all checking macros and
+ fix some whitespace problems; assume CODE argument does not
+ have side-effects.
+
+2003-06-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * scan.h: Convert to ISO C.
+ * system.h: Likewise.
+
+ * c-format.c (dynamic_format_types): New pointer for dynamic data.
+ (find_length_info_modifier_index, init_dynamic_asm_fprintf_info):
+ New functions split out of...
+ (handle_format_attribute): ...here.
+
+2003-06-16 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (REG_CLASS_FROM_LETTER): Change to:
+ (REG_CLASS_FROM_CONSTRAINT).
+ (CONST_OK_FOR_I): Rename to:
+ (CONST_OK_FOR_I08). Changed all users.
+ (CONST_OK_FOR_J): Rename to:
+ (CONST_OK_FOR_I16). Changed all users.
+ (CONST_OK_FOR_K): Rename to:
+ (CONST_OK_FOR_P27). Changed all users.
+ (CONST_OK_FOR_L): Rename to:
+ (CONST_OK_FOR_K08). Changed all users.
+ (CONST_OK_FOR_O): Rename to:
+ (CONST_OK_FOR_I06). Changed all users.
+ (CONST_OK_FOR_P): Rename to:
+ (CONST_OK_FOR_I10). Changed all users.
+ (CONSTRAINT_LEN, CONST_OK_FOR_I, CONST_OK_FOR_J16): Define.
+ (CONST_OK_FOR_J, CONST_OK_FOR_K, CONST_OK_FOR_P): Likewise.
+ (EXTRA_CONSTRAINT_A, EXTRA_CONSTRAINT_Bsc): Likewise.
+ (EXTRA_CONSTRAINT_B, PIC_OFFSET_P, PIC_DIRECT_ADDR_P): Likewise.
+ (EXTRA_CONSTRAINT_Cpg, EXTRA_CONSTRAINT_C): Likewise.
+ (EXTRA_MEMORY_CONSTRAINT,(EXTRA_CONSTRAINT_Sr0): Likewise.
+ (CONST_OK_FOR_LETTER_P): Replace with
+ (CONST_OK_FOR_CONSTRAINT_P).
+ (EXTRA_CONSTRAINT_S): Rename to:
+ (EXTRA_CONSTRAINT_C16). Changed all users.
+ (MOVI_SHORI_BASE_OPERAND_P): Don't allow direct addresses.
+ (EXTRA_CONSTRAINT_T): Rename to:
+ (EXTRA_CONSTRAINT_Csy). Changed all users.
+ (EXTRA_CONSTRAINT_Z): Remove.
+ (EXTRA_CONSTRAINT): Replace with:
+ (EXTRA_CONSTRAINT_STR).
+ (EXTRA_CONSTRAINT_U): Rename to:
+ (EXTRA_CONSTRAINT_Z). Changed all users.
+ * sh.c (and_operand): Use CONST_OK_FOR_J16.
+ * sh.md (cmpeqsi_t-1, cmpeqsi_t, adddi3_media): Use new constraints.
+ (addsi3_media, addsi3_compact, andsi3_compact, anddi3): Likewise.
+ (iorsi3, iordi3, xorsi3, xordi3, ashlsi3_std, ashlhi3_k): Likewise.
+ (lshrsi3_k, movsi_i, movsi_ie, movsi_i_lowpart, movsi_media): Likewise.
+ (movsi_media_nofpu, movqi_media, movhi_i, movhi_media): Likewise.
+ (*movdi_i, movdi_media, movdi_media_nofpu, shori_media): Likewise.
+ (movdf_media, movdf_media_nofpu, movv2sf_i, movv4sf_i): Likewise.
+ (movsf_media, movsf_media_nofpu, movsi_y, beq_media): Likewise.
+ (beq_media_i, bne_media, pt, ptb, movv8qi_i, movv2hi_i): Likewise.
+ (movv4hi_i, movv2si_i, negcmpeqv8qi, negcmpeqv2si): Likewise.
+ (negcmpeqv4hi, negcmpgtuv8qi, negcmpgtv2si, negcmpgtv4hi): Likewise.
+ (mcmv, mcnvs_lw, mcnvs_wb, mcnvs_wub, mextr_rl, mextr_lr): Likewise.
+ (mextr1, mextr2, mextr3, mextr4, mextr5, mextr6, mextr7): Likewise.
+ (mperm_w, mperm_w_little, mperm_w_big, msad_ubq_i): Likewise.
+ (mshards_q, mshfhi_b, mshflo_b, mshf4_b, mshf0_b, mshfhi_l): Likewise.
+ (mshflo_l, mshf4_l, mshf0_l, mshfhi_w, mshflo_w, mshf4_w): Likewise.
+ (mshf0_w, mshflo_w_x, mshfhi_l_di, mshfhi_l_di_rev): Likewise.
+ (mshflo_l_di_rev, mshflo_l_di_x, concat_v2sf): Likewise.
+ (mshflo_l_di_x_rev, subv2si3, subv4hi3, sssubv2si3): Likewise.
+ (sssubv4hi3): Likewise.
+ (movsf_i): Change I[08]/r to G/r.
+ (movsf_ie): Change f/{G,H}/c/X to f/{G,H}/c/Bsc.
+
+ * sh.c (sh_output_mi_thunk): Use CONST_OK_FOR_ADD.
+
+2003-06-16 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/i386/i386.c (ix86_memory_move_cost): Fix typo.
+
+2003-06-16 Andreas Jaeger <aj@suse.de>
+
+ * basic-block.h: Remove duplicate prototype of
+ note_prediction_to_br_prob.
+
+ * tree.h: Remove duplicate prototype of strip_float_extensions.
+
+2003-06-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/c4x/c4x.c: Don't include "c-tree.h".
+ * config/pa/pa.c: Likewise.
+ * langhooks.c: Likewise.
+ * tree.h (poplevel): Declare.
+
+2003-06-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (const_costs): Move this to ...
+ (h8300_rtx_costs): ... here.
+
+2003-06-16 Roger Sayle <roger@eyesopen.com>
+
+ * optabs.h (enum optab_index): Add new OTI_tan and OTI_atan.
+ (tan_optab, atan_optab): Define corresponding macros.
+ * optabs.c (init_optabs): Initialize tan_optab and atan_optab.
+ * genopinit.c (optabs): Implement tan_optab and atan_optab
+ using tan?f2 and atan?f2 patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_TAN{,F,L}
+ using tan_optab, and BUILT_IN_ATAN{,F,L} using atan_optab.
+ Change the default value of errno_set to false.
+ (expand_builtin): Expand BUILT_IN_TAN{,F,L} and BUILT_IN_ATAN{,F,L}
+ using expand_builtin_mathfn.
+
+ * config/i386/i386.md (atansf2, atandf2, atanxf2, atantf2): New
+ expander patterns implemented using existing atan2?f3 patterns.
+
+2003-06-16 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_expr <PLUS_EXPR>): If operand_equal_p considers
+ both operands of the addition equal, reuse the expanded RTL.
+ (expand_expr <MULT_EXPR>): Likewise for multiplication.
+
+2003-06-16 Roger Sayle <roger@eyesopen.com>
+ Jeff Law <law@redhat.com>
+
+ * fold-const.c (operand_equal_p): Consider two calls to "const"
+ functions with identical non-volatile arguments to be equal.
+ Consider the FUNCTION_DECL for the "__builtin_foo" form of a
+ built-in function to be equal to the "foo" form.
+
+2003-06-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/rs6000/sysv4le.h: Remove target-independent comment.
+ Replace "GNU compiler" with "GCC" in comment.
+
+2003-06-16 Andreas Jaeger <aj@suse.de>
+
+ * tracer.c: Remove duplicate declaration.
+
+ * toplev.c: Remove extra declaration of decode_d_option.
+
+ * ssa.c: Remove duplicate declaration.
+
+ * sreal.c: Remove extra declaration of dump_sreal.
+
+ * reload1.c: Remove duplicate declarations.
+
+ * integrate.c: Remove extra declaration of
+ set_decl_abstract_flags.
+
+ * flow.c: Remove extra declaration of dump_flow_info.
+
+ * alias.c: Remove extra declaration of get_addr.
+
+2003-06-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/rtems.h, config/sol2.h, config/svr4.h, config/usegas.h,
+ config/vxworks.h: GNU CC -> GCC.
+
+ * convert.c, dwarf2out.c, dwarfout.c, emit-rtl.c, function.c,
+ lists.c, print-rtl.c, print-tree.c, read-rtl.c, rtl-error.c,
+ stmt.c, toplev.c, integrate.h, loop.h, machmode.h, rtl.h,
+ ssa.h, tree.def: Replace overly specific references to "GNU C"
+ and "GNU C Compiler" with references to "GCC".
+
+2003-06-16 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (prepare_move_operand): Check if operand 0 is an invalid
+ memory reference. Fix test that checks if operand 1 is using r0.
+ * sh.md (movhi_i): Don't allow st.w r0,@(rX,rY) .
+
+ * defaults.h (REG_CLASS_FROM_CONSTRAINT): Only define if not already
+ defined.
+
+2003-06-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * function.h (struct emit_status): Remove x_last_linenum,
+ x_last_filename. Add x_last_location.
+ * rtl.h: #include "input.h".
+ (NOTE_DATA): New.
+ * cfglayout.c (duplicate_insn_chain): Use emit_line_note for line
+ number notes.
+ * emit-rtl.c (last_linenum, last_filename): Remove.
+ (last_location): New.
+ (emit_line_note_after): LINE must always be >= 0.
+ (emit_line_note): Likewise. Check not duplicate here...
+ (emit_note): ... rather than here.
+ (emit_line_note_force, force_next_line_note, init_emit): Adjust.
+ * integrate.c (expand_inline_function): Use emit_line_note for
+ line number notes.
+ (copy_insn_list): Likewise.
+ * unroll.c (copy_loop_body): Likewise.
+ * Makefile.in (RTL_H): Add input.h.
+
+2003-06-16 Richard Sandiford <rsandifo@redhat.com>
+
+ * optabs.c (emit_libcall_block): Don't hoist insns past a label.
+
+2003-06-16 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha-protos.h, config/alpha/elf.h,
+ config/alpha/osf.h, config/alpha/unicosmk.h, config/alpha/vms.h,
+ config/alpha/vms-cc.c, config/alpha/vms-ld.c: Update to ISO C.
+ * config/alpha/alpha.c: Likewise. Move targetm init to end of file.
+ Remove unneeded static function decls.
+
+2003-06-16 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (c_common_handle_option): s/on/value/.
+ (OPT_fabi_version_, OPT_ftabstop_, OPT_ftemplate_depth_): Use value
+ directly rather than converting the argument.
+ * c.opt: Update docs. Use UInteger where appropriate.
+ * common.opt: Use UInteger where appropriate.
+ * opts.c (integral_argument): New.
+ (handle_argument): Handle integral arguments, and optional
+ joined arguments.
+ (common_handle_option): Update.
+ * opts.h (CL_MISSING_OK, CL_UINTEGER): New.
+ * opts.sh: Handle JoinedOrMissing and UInteger flags.
+
+2003-06-16 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_LOCAL): Remove
+ unnecessary extern declaration.
+
+2003-06-15 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/gofast.h, config/interix.h, config/interix3.h,
+ config/libgloss.h, config/linux-aout.h, config/linux.h,
+ config/lynx-ng.h, config/lynx.h: GNU CC -> GCC.
+ * config/kaos.h: "GNU compiler" -> GCC.
+ * config/linux-aout.h, config/lynx.h: Clarify comment describing file.
+
+ * config/ip2k/crt0.S, config/ip2k/ip2k-protos.h,
+ config/ip2k/ip2k.c, config/ip2k/ip2k.md, config/ip2k/libgcc.S:
+ GNU CC -> GCC.
+
+ * config/svr3.h: Remove #if 0 code, misleading comments.
+ GNU CC -> GCC.
+
+2003-06-15 Zack Weinberg <zack@codesourcery.com>
+
+ * vmsdbgout.c (vmsdbgout_finish): Rename parameter to
+ main_input_filename to avoid conflict with input_filename macro.
+
+2003-06-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/mips/mips.h (asm_file_name, g_switch_set,
+ g_switch_value): Remove.
+ * config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Remove
+ unnecessary extern declarations.
+
+2003-06-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/frv/frv.h: Remove declaration of g_switch_value.
+ * config/m32r/m32r.h: Remove declaration of g_switch_value.
+ * config/m68hc11/m68hc11.c: Remove declaration of asm_file_name.
+
+2003-06-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * opts.sh: Quote '+' in regex.
+
+2003-06-15 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/t-rs6000: Add dependence of cfglayout.h to rs6000.o.
+ * config/rs6000/rs6000.c: Include cfglayout.h.
+ * config/alpha/alpha.c: Likewise.
+ * config/ia64/ia64.c: Likewise.
+ * config/sparc/sparc.c: Likewise.
+ * config/sh/sh.c: Likewise.
+
+2003-06-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * opts.sh: Quote '+' in regex.
+
+2003-06-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (lang_flags): Update for new spelling of flags.
+ (write_langs): Similarly.
+ * c.opt: Specify languages.
+ * opts.h: Remove languages.
+ * opts.sh: Recognise front-end defined languages.
+ * doc/sourcebuild.texi: Update.
+
+2003-06-15 Andreas Jaeger <aj@suse.de>
+
+ * alloc-pool.c: Convert to ISO C90 prototypes.
+ * alloc-pool.h: Likewise.
+ * alias.c: Likewise.
+ * attribs.c: Likewise.
+ * bb-reorder.c: Likewise.
+ * bitmap.h: Likewise.
+ * bitmap.c: Likewise.
+ * builtins.c: Likewise.
+
+ * tree.h: Convert prototypes of attribs.c to ISO C90.
+ * basic-block.h: Convert prototypes of bb-reorder.c to ISO C90.
+ * rtl.h: Convert prototypes of alias.c and builtins.c to ISO C90.
+ * expr.h: Convert prototypes of builtins.c to ISO C90.
+
+2003-06-15 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.md (expsf2, expdf2, expxf2): New patterns to
+ implement exp, expf and expl built-ins as inline x87 intrinsics.
+ (UNSPEC_FSCALE, UNSPEC_FRNDINT, UNSPEC_F2XM1): New unspecs to
+ represent x87's fscale, frndint and f2xm1 insns respectively.
+ (*fscale_sfxf3, *fscale_dfxf3, *fscale_xf3): New insn patterns
+ to encode x87's "fscale" instruction followed by a pop.
+ (*frndintxf2): New insn pattern for "frndint".
+ (*f2xm1xf2): New insn pattern for "f2xm1".
+
+ * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_FRNDINT and
+ UNSPEC_F2XM1 like UNSPEC_{SIN,COS} and handle UNSPEC_FSCALE like
+ UNSPEC_FPATAN.
+
+2003-06-15 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * gencheck.c (main): Avoid generating duplicate macros.
+
+ * Makefile.in (stagefeedback-start): Use $(SUBDIRS) instead of
+ knowing names of language subdirectories.
+
+2003-06-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-pch.c (asm_file_name): Remove.
+ * common.opt: Add more switches.
+ * flags.h (g_switch_set): Boolify.
+ * opts.c (g_switch_value, g_switch_set, exit_after_options,
+ version_flag): Move from toplev.c.
+ (common_handle_option): Handle more switches from toplev.c.
+ * toplev.c (display_help, display_target_options, decode_d_option,
+ print_version): Make non-static, remove prototypes.
+ (aux_base_name, asm_file_name, aux_info_file_name): Constify.
+ (version_flag, g_switch_value, g_switch_set, exit_after_options):
+ Remove.
+ (independent_decode_option): Move some handlers to opts.c.
+ * toplev.h (aux_info_file_name, aux_base_name, asm_file_name,
+ exit_after_options, version_flag, display_help, display_target_options,
+ print_version, decode_d_option): New.
+
+2003-06-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/alpha/alpha.md: Follow spelling conventions.
+ * config/arm/arm.c: Likewise.
+ * config/arm/arm.h: Likewise.
+ * config/arm/arm.md: Likewise.
+ * config/arm/crtn.asm: Likewise.
+ * config/m32r/m32r.c: Likewise.
+ * config/m32r/m32r.md: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+
+2003-06-15 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_output_mi_thunk_osf): Call
+ insn_locators_initialize.
+ * config/ia64/ia64.c (ia64_output_mi_thunk): Likewise.
+ * config/rs6000/rs6000.c (rs6000_output_mi_thunk): Likewise.
+ * config/sparc/sparc.c (sparc_output_mi_thunk): Likewise.
+ * config/sh/sh.c (sh_output_mi_thunk): Do it later.
+
+2003-06-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtins.c (expand_builtin_expect_jump): Remove redundant
+ tests that are also in any_condjump_p().
+
+2003-06-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * libgcc2.c: Delete sysV68 L_trampoline section.
+ * config/m68k/mot3300-crt0.S: Delete file.
+ * config/m68k/mot3300Mcrt0.S: Likewise.
+
+2003-06-15 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/aoutos.h: Remove.
+ * config.gcc: Remove reference to aoutos.h.
+ * config/m68k/m68k-aout.h: Remove reference to aoutos.h.
+
+2003-06-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/install.texi: Follow spelling conventions.
+ * doc/tm.texi: Likewise.
+ * config/fp-bit.c: Likewise.
+ * config/arm/arm.c: Likewise.
+ * config/frv/frv.c: Likewise.
+ * config/ns32k/NOTES: Likewise.
+ * config/ns32k/STATUS: Likewise.
+
+2003-06-14 Roger Sayle <roger@eyesopen.com>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * rtl.h (STORE_FLAG_VALUE): Remove default definition from here.
+ * defaults.h (STORE_FLAG_VALUE): Move default definition to here.
+ * doc/tm.texi (STORE_FLAG_VALUE): Document the default value.
+
+ * config/alpha/alpha.h (STORE_FLAG_VALUE): Remove definition.
+ * config/arc/arc.h (STORE_FLAG_VALUE): Likewise.
+ * config/arm/arm.h (STORE_FLAG_VALUE): Likewise.
+ * config/cris/cris.h (STORE_FLAG_VALUE): Likewise.
+ * config/i370/i370.h (STORE_FLAG_VALUE): Likewise.
+ * config/i386/i386.h (STORE_FLAG_VALUE): Likewise.
+ * config/i960/i960.h (STORE_FLAG_VALUE): Likewise.
+ * config/ia64/ia64.h (STORE_FLAG_VALUE): Likewise.
+ * config/ip2k/ip2k.h (STORE_FLAG_VALUE): Likewise.
+ * config/m32r/m32r.h (STORE_FLAG_VALUE): Likewise.
+ * config/mcore/mcore.h (STORE_FLAG_VALUE): Likewise.
+ * config/mips/mips.h (STORE_FLAG_VALUE): Likewise.
+ * config/mmix/mmix.h (STORE_FLAG_VALUE): Likewise.
+ * config/ns32k/ns32k.h (STORE_FLAG_VALUE): Likewise.
+ * config/pa/pa.h (STORE_FLAG_VALUE): Likewise.
+ * config/pdp11/pdp11.h (STORE_FLAG_VALUE): Likewise.
+ * config/sh/sh.h (STORE_FLAG_VALUE): Likewise.
+ * config/sparc/sparc.h (STORE_FLAG_VALUE): Likewise.
+ * config/v850/v850.h (STORE_FLAG_VALUE): Likewise.
+ * config/xtensa/xtensa.h (STORE_FLAG_VALUE): Likewise.
+
+2003-06-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * opts.sh (POSIXLY_CORRECT): Unset it.
+
+ * tree.h (init_function_start): Remove filename and line paramters.
+ * function.c (init_function_start): Remove filename and line
+ parameters. Use DECL_SOURCE_LOCATION.
+ * c-decl.c (store_parm_decls): Adjust init_function_start call.
+ (c_expand_body_1): Likewise.
+ * coverage.c (create_coverage): Likewise.
+ * objc/objc-act.c (build_tmp_function_decl): Set line number to
+ zero.
+ (hack_method_prototype): Adjust init_function_start call.
+
+2003-06-14 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/3724
+ * arm/linux-elf.h (PROFILE_HOOK): Define.
+
+2003-06-14 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/11183
+ * arm.h (CANNOT_CHANGE_MODE_CLASS): Define.
+
+2003-06-14 Roger Sayle <roger@eyesopen.com>
+
+ * opts.sh: Work around a mysterious feature in cygwin's gawk
+ where specifying the input files explicitly has a different
+ behavior to piping them via stdin.
+
+2003-06-14 Neil Booth <neil@daikokuya.co.uk>
+
+ * doc/sourcebuild.texi: Update.
+
+2003-06-14 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/11183
+ * arm.c (output_move_double): Pass SImode to adjust_address.
+
+2003-06-14 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Update to use common.opt and lang_opt_files.
+ (c-options.c, c-options.h): Remove.
+ (options.c, options.h): Add.
+ * c-opts.c: Include options.h not c-options.h.
+ * common.opt: New file.
+ * configure, configure.in: Add lang_opt_files.
+ * opts.c: Include flags.h and diagnostic.h.
+ (common_handle_option): New.
+ (handle_option): Update to recognize common options and all
+ language-dependent options.
+ * opts.h (CL_F77, CL_JAVA, CL_ADA, CL_COMMON, CL_TREELANG): New.
+ (struct cl_option): Make flags of type int.
+ * opts.h: Flag option with front ends to which it applies.
+ Handle duplicate options.
+ * toplev.c (filename): Remove.
+ (independent_decode_option): Don't handle filenames and -quiet.
+ (process_options, do_compile): Update.
+
+2003-06-14 Nick Clifton <nickc@redhat.com>
+
+ * doc/install.texi (Specific): Add description of different
+ ARM supported file format targets.
+
+Sat Jun 14 11:12:04 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * reorg.c (emit_delay_sequence, dbr_schedule): Clear insn locators
+ inside delay slots.
+
+2003-06-13 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * unwind-c.c: Define NO_SIZE_OF_ENCODED_VALUE.
+ * unwind-pe.h (size_of_encoded_value): Do not define if
+ NO_SIZE_OF_ENCODED_VALUE is defined.
+
+2003-06-13 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (expand_expr <COMPLEX_CST>): Handle the case of
+ expanding a complex constant into a CONCAT target.
+
+2003-06-13 Zack Weinberg <zack@codesourcery.com>
+
+ * config/svr3.h (ASM_FILE_START): Don't use ASM_FILE_START_1.
+ (ASM_FILE_START_1): Delete.
+ * config/i386/att.h, config/i386/sco5.h,
+ config/i386/sysv3.h
+ (ASM_FILE_START_1): Delete.
+
+2003-06-13 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * config/i386/bsd.h: Remove ASM_FILE_START.
+ * config/i386/djgpp.h: Likewise.
+ * config/i386/gas.h (ASM_FILE_START): Output .file before .intel_syntax.
+
+ * config/i386/djgpp.h: Move included unix.h, bsd.h, gas.h to ...
+ * config.gcc (i[34567]86-pc-msdosdjgpp): ... here.
+
+2003-06-13 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR bootstrap/10835
+ * haifa-sched.c (max_lookahead_tries,
+ cached_first_cycle_multipass_dfa_lookahead,
+ cached_issue_rate): New variables.
+ (max_issue): Check the number of tries.
+ (choose_ready): Calculate max_lookahead_tries.
+ (sched_init): Check cached_issue_rate.
+
+2003-06-13 Richard Henderson <rth@redhat.com>
+
+ * cfgbuild.c (make_edges): Set ABNORMAL with SIBCALL.
+ * cfgrtl.c (purge_dead_edges): Expect it too.
+
+2003-06-13 Jim Wilson <wilson@tuliptree.org>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR bootstrap/10983
+ * combine.c (make_extraction): Use gen_lowpart_for_combine
+ when extracting from a REG and not in the destination of a SET.
+
+2003-06-13 Doug Evans <dje@sebabeach.org>
+
+ * tsystem.h (abort): Declare in inhibit_libc case to remove build
+ warnings for addvsi3, et.al.
+
+2003-06-13 Aldy Hernandez <aldyh@redhat.com>
+
+ * c-common.c (handle_mode_attribute): Use VECTOR_MODE_P macro.
+
+ * simplify-rtx.c (simplify_subreg): Same.
+
+ * emit-rtl.c (gen_lowpart_common): Same.
+
+2003-06-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * builtins.c: Fix comment typos.
+ * fold-const.c: Likewise.
+
+2003-06-13 Doug Evans <dje@sebabeach.org>
+ Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/m32r/m32r-protos.h (m32r_pass_by_reference): Declare.
+ * config/m32r/m32r.c (m32r_pass_by_reference): New fn.
+ (m32r_va_arg): Use it.
+ * config/m32r/m32r.h (FUNCTION_ARG_PASS_BY_REFERENCE): Ditto.
+ (RETURN_IN_MEMORY): Ditto.
+
+2003-06-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * c-typeck.c: Remove #if 0 clauses.
+
+ PR other/1494
+ * config/alpha/openbsd.h, config/i386/openbsd.h,
+ config/m68k/openbsd.h, config/sparc/openbsd.h: Remove
+ residual reference to EGCS.
+
+2003-06-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (output_call_mem): If the address references the link-register
+ use an instruction sequence that avoids early-clobbering IP.
+ (eliminate_lr2ip): Delete.
+
+2003-06-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-format.c (format_types_orig): Disallow '*' width/precision in
+ asm_fprintf format checks.
+
+2003-06-13 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_va_arg): Fix alignment when retrieving
+ non-integral types from integer register save area slots.
+
+2003-06-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/i386/svr3dbx.h: GNU CC -> GCC; Intel 385 -> Intel 386.
+
+2003-06-13 Florian Weimer <fw@deneb.enyo.de>
+
+ * doc/invoke.texi (SPARC Options): Document ``-mimpure-text''.
+
+2003-06-13 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/linux.h (TARGET_ASM_FILE_END): Set TARGET_ASM_FILE_END
+ to file_end_indicate_exec_stack.
+
+2003-06-12 Richard Henderson <rth@redhat.com>
+
+ PR target/11089
+ * config/i386/i386.md (sse_movaps): Use an expander to force
+ one operand to be a register.
+ (sse_movups): Likewise.
+
+2003-06-13 Doug Evans <dje@sebabeach.org>
+
+ Remove some build warnings.
+ * config/m32r/initfini.c (__CTOR_LIST__,__DTOR_LIST__): Attribute used.
+ (__do_global_ctors,__do_global_dtors): Ditto.
+
+2003-06-12 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/10557
+ * rtlanal.c (subreg_offset_representable_p): Relax subreg check.
+
+2003-06-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m32r/m32r.md: Fix a comment typo.
+
+2003-06-13 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
+
+ PR target/10142
+ * config/sparc/sparc.c (function_arg_record_value_parms): Add
+ new 'stack' field.
+ (function_arg_record_value_1): Set 'stack' to 1 if we run out of
+ integer slots for an integer field.
+ (function_arg_record_value_3): Shift vector index.
+ (function_arg_record_value_2): Likewise.
+ (function_arg_record_value): Initialize 'stack' to 0.
+ Set 'stack' to 1 if we run out of integer slots for an integer field.
+ Generate (parallel [(expr_list (nil) ...) ...]) if 'stack' is set to 1.
+
+2003-06-13 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/10955
+ * unroll.c (unroll_loop): Fix off-by-one bug.
+
+2003-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (function_arg): Remove typo.
+
+2003-06-12 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (legitimate_constant_p): Handle UNSPEC_NTPOFF
+ and UNSPEC_DTPOFF.
+
+2003-06-12 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/10475
+ * expmed.c (emit_store_flag): Use simplify_gen_subreg directly
+ for extracting sub-words.
+
+2003-06-12 Richard Henderson <rth@redhat.com>
+
+ PR target/7594
+ * config/m68k/m68k.md (zero_extendhisi2): Use gen_lowpart_SUBREG.
+ (zero_extendqihi2, zero_extendqisi2): Likewise.
+
+2003-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (function_arg): Always split vectors for
+ e500 if it's a stdarg function.
+ (function_arg_advance): Advance 2 registers for vectors in a
+ stdarg function.
+ (init_cumulative_args): Initialize stdarg.
+ (rs6000_spe_function_arg): New.
+
+ * config/rs6000/rs6000.h (rs6000_args): Add stdarg.
+
+2003-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.h (MODES_TIEABLE_P): Add SPE vectors.
+
+2003-06-12 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/168
+ * fold-const.c (tree_expr_nonnegative_p): Handle addition
+ and multiplication of zero extensions, floating point division,
+ and integer<->fp, fp<->fp and zero extension conversions.
+ The built-in ceil and floor functions preserve signedness.
+
+2003-06-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.2: Likewise.
+ * c-decl.c: Likewise.
+ * cfgloop.h: Likewise.
+ * cgraph.c: Likewise.
+ * coverage.c: Likewise.
+ * cppcharset.c: Likewise.
+ * cpphash.h: Likewise.
+ * cpplex.c: Likewise.
+ * cpplib.c: Likewise.
+ * dbxout.c: Likewise.
+ * df.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * dwarfout.c: Likewise.
+ * emit-rtl.c: Likewise.
+ * explow.c: Likewise.
+ * gcov-io.c: Likewise.
+ * gcov-io.h: Likewise.
+ * gcov.c: Likewise.
+ * gengtype.c: Likewise.
+ * ggc.h: Likewise.
+ * opts.c: Likewise.
+ * real.c: Likewise.
+ * reload.c: Likewise.
+ * stmt.c: Likewise.
+
+2003-06-12 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/install.texi (m32r-*-elf): Change company to Renesas.
+
+Thu Jun 12 20:00:55 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h (flow_delete_block_noexpunge): Kill.
+ * cfgrtl.c (flow_delete_block_noexpunge): Merge to
+ rtl_delete_block.
+
+2003-06-10 Richard Henderson <rth@redhat.com>
+
+ PR inline-asm/4823
+ * reg-stack.c (any_malformed_asm): New.
+ (check_asm_stack_operands): Set it.
+ (convert_regs_1): Check it before aborting.
+
+2003-06-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md: Change all clobbers of the accumulator to sets.
+
+2003-06-12 Jakub Jelinek <jakub@redhat.com>
+
+ * c-opts.c (complain_wrong_lang): Add on argument.
+ Print no- switch if on is false.
+ (c_common_decode_option): Adjust caller.
+
+2003-06-12 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_emit_prologue): Use LA instead of AR
+ to initialize GOT register.
+
+2003-06-12 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (tree_expr_nonnegative_p): Add support for
+ floating point constants, addition and multiplication.
+
+2003-06-12 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (adddi3_compact, subdi3_compact): Add earlyclobber
+ constraint modifier for operand 0.
+
+2003-06-12 Hans-Peter Nilsson <hp@axis.com>
+
+ Don't warn on dollars in builtin macro definitions,
+ e.g. __REGISTER_PREFIX__.
+ * cpphash.h (struct cpp_reader): Move member warn_dollars...
+ * cpplib.h (struct cpp_options): ...to here. Change type to
+ unsigned char.
+ * cppinit.c (cpp_create_reader): Set it to 1 here.
+ (post_options): Don't set it here.
+ * c-opts.c (c_common_init_options): Reset it to 0 here.
+ (finish_options): Set it here.
+ * cpplex.c (forms_identifier_p): Tweak for new location of
+ warn_dollars.
+
+ * configure.in (assembler dwarf2 debug_line support): Define insn
+ for cris-*-* and mmix-*-*.
+ * configure: Regenerate.
+
+2003-06-11 Uwe Stieber <uwe@kaos-group.de>
+
+ * config.gcc (arm*-*-kaos*, i[34567]86-*-kaos*, powerpc-*-kaos*,
+ powerpcle-*-kaos*, strongarm-*-kaos*): New targets.
+ (sh-*-elf*): Add sh*-*-kaos* support.
+ * config/kaos.h, config/arm/kaos-strongarm.h, config/arm/kaos-arm.h,
+ config/i386/kaos-i386.h, config/rs6000/kaos-ppc.h,
+ config/sh/kaos-sh.h: New files.
+
+2003-06-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gcse.c (fis_get_condition): Make it a global function.
+ * reload1.c (reload_cse_move2add): Detect implicit sets.
+ * rtl.h: Add a prototype for fis_get_condition.
+
+2003-06-11 Richard Henderson <rth@redhat.com>
+
+ * stmt.c (expand_asm_operands): Don't warn for memories with
+ queued addresses.
+
+2003-06-11 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.h (SUBTARGET_ASM_RELAX_SPEC): Rewrite without
+ brackets.
+
+2003-06-11 Neil Booth <neil@daikokuya.co.uk>
+
+ * hooks.c (hook_int_size_t_constcharptr_int_0): New.
+ * hooks.h (hook_int_size_t_constcharptr_int_0): New.
+ * langhooks-def.h (lhd_decode_option, LANG_HOOKS_DECODE_OPTION): Die.
+ (LANG_HOOKS_HANDLE_OPTION, LANG_HOOKS_INITIALIZER): Update.
+ * langhooks.c (lhd_decode_option): Remove.
+ * langhooks.h (struct lang_hooks): Remove decode_option.
+ * opts.c (handle_option): No longer use decode_option.
+
+2003-06-11 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopanal.c (variable_initial_value): Update the set of altered
+ registers correctly.
+
+2003-06-11 Roger Sayle <roger@eyesopen.com>
+ Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/d30v/d30v.h: Delete reference to ASM_FINAL_SPEC.
+ * config/i386/netbsd-elf.h: Likewise.
+ * config/m32r/m32r.h: Likewise.
+ * config/mn10300/mn10300.h: Likewise.
+ * config/stormy16/stormy16.h: Likewise.
+ * config/v850/v850.h: Likewise.
+ * config/vax/netbsd-elf.h: Likewise.
+ * config/xtensa/elf.h: Likewise.
+ * config/xtensa/linux.h: Likewise.
+
+2003-06-11 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/iris5gas.h (MDEBUG_ASM_SPEC): Override to match
+ DWARF 2 default.
+
+ * config/mips/dbxmdebug.h: New file.
+ * config.gcc (mips-sgi-irix6*o32, mips-sgi-irix5*): Use it with
+ gas and --with-stabs.
+
+2003-06-11 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * expr.c (can_move_by_pieces): align argument may be unused.
+
+2003-06-11 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * expr.c (convert_move): Handle moves between two CONCATs.
+
+2003-06-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (RETURN_IN_MEMORY): Accept DImode if
+ !TARGET_H8300.
+
+2003-06-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (final_prescan_insn): Don't dump rtl.
+ * config/h8300/h8300.h (MASK_RTL_DUMP): Remove.
+ (TARGET_RTL_DUMP): Likewise.
+ (TARGET_SWITHCES): Remove -mrtl-dump.
+
+2003-06-10 Richard Henderson <rth@redhat.com>
+
+ * optabs.c (gen_cond_trap): Fix prepare_operand typo.
+
+2003-06-10 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.md (call_gp): Fix memory mode.
+
+2003-06-10 James E Wilson <wilson@tuliptree.org>
+
+ PR target/8812
+ * reload1.c (choose_reload_regs): For equiv reg, add loop over all
+ hard regs for reload_reg_used_at_all and reg_class_contents checks.
+
+2003-06-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (print_operand): Remove support for
+ operand character 'b'.
+ Add the AND case to operand character 'c'.
+ * config/h8300/h8300.md (two anonymous patterns): Replace
+ operand character 'b' with 'c'.
+
+2003-06-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (print_operand): Remove support for
+ operand character 'u'.
+
+2003-06-10 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Fix typo.
+ * configure: Regenerate.
+
+2003-06-10 Loren James Rittle <ljrittle@acm.org>
+
+ * config/alpha/alpha.c (unicosmk_file_end): Add conditional
+ compilation guard.
+
+2003-06-10 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh-protos.h (function_symbol): Declare.
+ * sh.c (expand_block_move, expand_ashiftrt): Use it.
+ (sh_expand_prologue, sh_expand_epilogue): Likewise.
+ (sh_initialize_trampoline): Likewise.
+ (function_symbol): New function.
+ * sh.md (udivsi3, divsi3, mulsi3, ic_invalidate_line): Use it.
+ (initialize_trampoline, call, call_pop, call_value, sibcall): Likewise.
+ (call_value_pop, shcompact_return_tramp): Likewise.
+
+ * sh.h (OVERRIDE_OPTIONS): Don't suppress --profile-arc-flag.
+
+ * sh.md (GOTaddr2picreg): Use gen_lowpart to get lowpart of
+ target register.
+
+2003-06-10 DJ Delorie <dj@redhat.com>
+
+ * doc/md.texi (Machine Constraints): Document stormy's Z
+ constraint.
+
+2003-06-10 Geoffrey Keating <geoffk@apple.com>
+
+ * except.c (call_site_base): Mark with GTY.
+
+2003-06-10 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm-proto.h: Convert to ISO C90 prototypes.
+ * arm.c: Likewise.
+
+2003-06-10 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (sh_output_mi_thunk): Call insn_locators_initialize.
+
+2003-06-10 Steve Ellcey <sje@cup.hp.com>
+
+ * calls.c (expand_call): Convert structure_value_addr to Pmode if
+ necessary.
+
+2003-06-10 Andrew Haley <aph@redhat.com>
+
+ * langhooks-def.h (LANG_HOOKS_DECL_OK_FOR_SIBCALL): New.
+ (LANG_HOOKS_DECLS): Add LANG_HOOKS_DECL_OK_FOR_SIBCALL.
+ (lhd_decl_ok_for_sibcall): New.
+ * langhooks.c (lhd_decl_ok_for_sibcall): New.
+ * langhooks.h (lang_hooks_for_decls.ok_for_sibcall): New field.
+ * calls.c (expand_call): Check lang_hook before generating a
+ sibcall.
+
+2003-06-10 DJ Delorie <dj@redhat.com>
+
+ * config/stormy16/stormy16.c (xstormy16_extra_constraint_p): Add Z,
+ which matches (const_int 0) for addhi3.
+ * config/stormy16/stormy16.md: Document known constraints.
+ (addhi3): Handle adding zero.
+
+2003-06-10 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * config/m32r/m32r.h (HARD_REGNO_RENAME_OK): New.
+ * config/m32r/m32r.c (m32r_hard_regno_rename_ok): New.
+ * config/m32r/m32r-protos.h: Prototype it.
+
+2003-06-10 Janis Johnson <janis187@us.ibm.com>
+
+ * config/rs6000/eabi.h (TARGET_OS_CPP_BUILTINS): Define builtins
+ common to rs6000 sysv targets.
+ * config/rs6000/eabisim.h (TARGET_OS_CPP_BUILTINS): Ditto.
+ * config/rs6000/rtems.h (TARGET_OS_CPP_BUILTINS): Ditto.
+
+2003-06-10 Nick Clifton <nickc@redhat.com>
+
+ * config.gcc: Add arm-wince-pe target.
+ * config/arm/pe.h (MULTILIB_DEFAULTS): Define.
+ Add comment about default apcs26 support.
+ * config/arm/t-pe (MULTILIB_OPTIONS): Add an -mapcs-32
+ multilib.
+ (MULTILIB_DIRNAMES): Add 'apcs32'.
+ * config/arm/t-wince-pe: New makefile fragment.
+ * config/arm/wince-pe.h: New file. Overrides a few definitions
+ in arm/pe.h
+
+2003-06-10 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (fold_builtin): Optimize cos(-x) as cos(x).
+ * fold-const.c (fold <NEGATE_EXPR>): Convert -f(x) into f(-x)
+ when x is easily negated and f is sin, tan or atan.
+ (fold <MULT_EXPR>): Optimize tan(x)*cos(x) and cos(x)*tan(x) as
+ sin(x) with flag_unsafe_math_optimizations.
+ (fold <RDIV_EXPR>): With flag_unsafe_math_optimizations fold
+ sin(x)/cos(x) as tan(x) and cos(x)/sin(x) as 1.0/tan(x).
+
+2003-06-10 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold <EQ_EXPR>): Don't fold x == x only if x
+ is a floating point type *and* we currently honor NaNs.
+ (fold <NE_EXPR>): Likewise.
+
+2003-06-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11131
+ * tree-inline.c (inlinable_function_p): Call the language-specific
+ hook early.
+
+2003-06-09 David Taylor <dtaylor@emc.com>
+
+ * config/rs6000/rs6000.c (rs6000_va_start, rs6000_va_arg): Skip over
+ the f_res field.
+
+2003-06-09 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Remove references to host_truncate_target.
+ * configure: Regenerate.
+ * config.gcc: Remove references to truncate_target,
+ host_truncate_target.
+
+ * Makefile.in, configure.in, config/m68hc11/t-m68hc11-gas:
+ Replace "build_canonical" with build, "host_canonical" with host.
+ * configure.in: Use GCC_TOPLEV_SUBDIRS.
+ * aclocal.m4: Include ../config/acx.m4.
+ * configure: Regenerate.
+
+2003-06-09 David Taylor <dtaylor@emc.com>
+
+ * config/rs6000/rs6000.c (rs6000_build_va_list): Give the two
+ bytes of padding in the __va_list_tag structure a name (reserved).
+
+2003-06-09 Jason Merrill <jason@redhat.com>
+
+ * fold-const.c (operand_equal_p): Handle ADDR_EXPR and TRUTH_NOT_EXPR.
+
+2003-06-09 Osku Salerma <osku@iki.fi>
+
+ * c-format.c (check_format_string, get_constant): New.
+ (handle_format_attribute, handle_format_arg_attribute,
+ decode_format_attr): Change to use above functions.
+
+2003-06-09 Richard Henderson <rth@redhat.com>
+
+ * stmt.c (expand_asm_operands): Re-word warning.
+
+2003-06-08 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR target/8787
+ * config/i386/djgpp.h (ASM_FILE_START): emit `.intel_syntax'
+ if -masm=intel.
+
+2003-06-09 James E Wilson <wilson@tuliptree.org>
+
+ * config/frv/cmovc.c, config/frv/cmovh.c, config/frv/cmovw.c,
+ config/frv/frvbegin.c, config/frv/frvend.c, config/frv/lib1funcs.asm:
+ Add libgcc exception.
+
+2003-06-09 David Edelsohn <edelsohn@gnu.org>
+ Ayal Zaks <gcchaifa@us.ibm.com>
+
+ * config/rs6000/rs6000.md (define_attr "type"): Add insert_word.
+ (insvsi*): Add insert_word attribute.
+ * config/rs6000/rs6000.c (rs6000_variable_issue): Add TYPE_INSERT_WORD.
+ * config/rs6000/{40x.md,603.md,6xx.md,7450.md,7xx.md,mpc.md,
+ power4.md,rios1.md,rios2.md,rs64.md}: Add insert_word.
+
+2003-06-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * fold-const.c (fold): Fix a comment typo.
+
+2003-06-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree-inline.c (expand_call_inline): DECL_SOURCE_LINE_FIRST is
+ removed.
+
+2003-06-09 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (gen_block_redirect): Use locators.
+
+2003-06-09 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.h (THUMB_PRINT_OPERAND_ADDRESS): Use %wd in format and remove
+ cast to int.
+
+2003-06-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * configure.in: Assume gas 2.14 and above can handle MIPS relocation
+ operators.
+ * configure: Regenerated.
+
+2003-06-09 Richard Sandiford <rsandifo@redhat.com>
+ Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mips/mips.h (GLOBAL_POINTER_REGNUM): New macro.
+ (PIC_OFFSET_TABLE_REGNUM): Look at pic_offset_table_rtx after reload.
+ (STARTING_FRAME_OFFSET): Don't allocate a cprestore slot for
+ n32/64 PIC.
+ (MUST_SAVE_REGISTERS): Delete.
+ * config/mips/mips.c (mips_frame_info): Remove extra_size field.
+ (machine_function): Add global_pointer field.
+ (mips_classify_constant): Check for (const $gp) using pointer equality
+ with pic_offset_table_rtx.
+ (mips_classify_constant): Handle RELOC_LOADGP_HI and RELOC_LOADGP_LO.
+ (mips_restore_gp): Use current_function_outgoing_args_size.
+ (print_operand): Use PIC_OFFSET_TABLE_REGNUM instead of
+ GP_REG_FIRST + 28. Handle relocation strings that have
+ more than one '('.
+ (mips_reloc_string): Handle RELOC_LOADGP_HI and RELOC_LOADGP_LO.
+ (mips_global_pointer): New function.
+ (mips_save_reg_p): New function, mostly split out from...
+ (compute_frame_size): ...here. Remove handling of extra_size.
+ Reclaim args_size if no variables depend on it. Don't treat gp
+ as a special case: handle it in the main GPR loop.
+ (mips_initial_elimination_offset): Fix comment.
+ (save_restore_insns): Save every register in the GPR mask,
+ removing distinction between mask and real_mask.
+ (mips_output_function_prologue): Update .frame psuedo-op after
+ the removal of extra_size. Move the SVR4 PIC stack allocation
+ and cprestore instructions to mips_expand_prologue.
+ (mips_gp_insn): New function.
+ (mips_expand_prologue): Set REGNO (pic_offset_table_rtx) to
+ the chosen global pointer. Handle SVR4 PIC stack allocation
+ in the same way as other ABIs. Adjust varargs code accordingly.
+ Emit a cprestore insn after allocating the stack. Use mips_gp_insn
+ to emit the loadgp sequence. Follow it with a loadgp_blockage
+ if not using explicit relocs.
+ (mips_output_function_epilogue): Reinstate the default gp register.
+ (mips16_gp_pseudo_reg): Use pic_offset_table_rtx.
+ (mips16_optimize_gp): Likewise.
+ * config/mips/mips.md (UNSPEC_LOADGP): Remove.
+ (UNSPEC_SETJMP, UNSPEC_LONGJMP): Remove.
+ (UNSPEC_CPRESTORE, RELOC_LOADGP_HI, RELOC_LOADGP_LO): New.
+ (loadgp): Remove.
+ (loadgp_blockage, cprestore): New instructions.
+ (builtin_setjmp_setup): Implement using emit_move_insn. Use
+ pic_offset_table_rtx.
+ (builtin_setjmp_setup_32, builtin_setjmp_setup_64): Remove.
+ (builtin_longjmp): Use gen_raw_REG to force use of $28.
+
+2003-06-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_output_division): Declare.
+ * config/mips/mips.h (MASK_CHECK_RANGE_DIV): Remove.
+ (MASK_BRANCHLIKELY): Use MASK_CHECK_RANGE_DIV's old number.
+ (TARGET_NO_CHECK_ZERO_DIV, TARGET_CHECK_RANGE_DIV): Remove.
+ (TARGET_CHECK_ZERO_DIV): New macro.
+ (TARGET_SWITCHES): Remove -mcheck-range-div & -mno-check-range-div.
+ * config/mips/mips.c (mips_output_division): New function.
+ * config/mips/mips.md (length): Take TARGET_CHECK_ZERO_DIV into
+ account when calculating the default length of a division.
+ (divmodsi4, divmoddi4, udivmodsi4, udivmoddi4): Turn into define_insns.
+ Enable regardless of optimization level. Use mips_output_division.
+ (divmodsi4_internal, divmoddi4_internal, udivmodsi4_internal,
+ udivmoddi4_internal, div_trap, div_trap_normal, div_trap_mips16,
+ divsi3, divsi3_internal, divdi3, divdi3_internal, modsi3,
+ modsi3_internal, moddi3, moddi3_internal, udivsi3, udivsi3_internal,
+ udivdi3, udivdi3_internal, umodsi3, umodsi3_internal, umoddi3,
+ umoddi3_internal): Remove.
+
+2003-06-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_reg_names): Change hilo entry to "".
+ (mips_sw_reg_names): Likewise.
+ (mips_regno_to_class): Change hilo entry to NO_REGS.
+ (hilo_operand): Use MD_REG_P.
+ (extend_operator): New predicate.
+ (override_options): Remove 'a' constraint.
+ (mips_secondary_reload_class): Remove hilo handling. Also remove
+ handling of (plus sp reg) reloads for mips16.
+ (mips_register_move_cost): Remove hilo handling.
+ * config/mips/mips.h (FIXED_REGISTERS): Make hilo entry fixed.
+ (MD_REG_LAST): Remove hilo from range.
+ (HILO_REGNUM): Delete.
+ (reg_class): Remove HILO_REG and HILO_AND_GR_REGS.
+ (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update accordingly.
+ (PREDICATE_CODES): Add entry for extend_operator.
+ (DEBUG_REGISTER_NAMES): Change hilo entry to "".
+ * config/mips/mips.md: Remove hilo clobbers wherever they occur.
+ Remove constraints from multiplication define_expands. Remove
+ clobbers from "decorative" define_expand patterns.
+ (UNSPEC_HILO_DELAY): Delete.
+ (*mul_acc_si, *mul_sub_si): Add early-clobber to operand 6.
+ (mulsidi3, umulsidi3): Change pattern to match the TARGET_64BIT case.
+ Adjust C code to just emit insns for !TARGET_64BIT.
+ (mulsidi3_internal): Rename to mulsidi3_32bit.
+ (mulsidi3_64bit): Use a "d" constraint for the destination.
+ Use extend_operator so that the pattern can handle umulsidi3 as well.
+ Split the instruction after reload.
+ (*mulsidi3_64bit_parts): New pattern, generated by mulsidi3_64bit.
+ (umulsidi3_internal): Rename to umulsidi3_32bit.
+ (umulsidi3_64bit): Remove.
+ (*smsac_di, *umsac_di): Line-wrap fixes.
+ (udivsi3_internal): Don't allow operand 2 to be constant.
+ (udivdi3_internal, umodsi3_internal, umoddi3_internal): Likewise.
+ (movdi_internal2, movsi_internal): Remove hilo alternatives.
+ (reload_in[sd]i, reload_out[sd]i, hilo_delay): Remove.
+
+2003-06-09 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/10913
+ * config/mips/mips.h (TARGET_FILE_SWITCHING, NO_DBX_FUNCTION_END,
+ PUT_SDB_SCL, PUT_SDB_INT_VAL, PUT_SDB_VAL, PUT_SDB_ENDEF,
+ PUT_SDB_TYPE, PUT_SDB_SIZE, PUT_SDB_DIM, PUT_SDB_START_DIM,
+ PUT_SDB_NEXT_DIM, PUT_SDB_LAST_DIM, PUT_SDB_TAG, PUT_SDB_SRC_FILE,
+ SDB_GENERATE_FAKE, TEXT_SECTION): Delete.
+ (PUT_SDB_DEF, PUT_SDB_PLAIN_DEF, PUT_SDB_BLOCK_START,
+ PUT_SDB_BLOCK_END, PUT_SDB_FUNCTION_END): Replace use of
+ asm_out_text_file with asm_out_file.
+ * config/mips/iris5gas.h (PUT_SDB_SIZE, PUT_SDB_TYPE): Likewise.
+ * config/mips/elf.h (TEXT_SECTION): Undefine.
+ * config/mips/elf64.h (TEXT_SECION): Undefine.
+ * config/mips/openbsd.h (TEXT_SECION): Undefine.
+ * config/mips/mips.c (asm_out_text_file, asm_out_data_file): Delete.
+ (override_options): Disable small-data optimizations unless using
+ gas or explicit relocations.
+ (mips_asm_file_start, mips_asm_file_end, mips_output_function_epilogue,
+ iris6_asm_named_section, iris6_asm_file_start): Remove code for
+ handling TARGET_FILE_SWITCHING.
+ (copy_file_data): Move into TARGET_IRIX6 block.
+
+2003-06-08 Richard Henderson <rth@redhat.com>
+
+ * expr.h (EXPAND_MEMORY): New.
+ * expr.c (expand_expr): Check it.
+ * stmt.c (expand_asm_operands): Provide it when the constraint
+ requires a memory. Warn for memory input constraints without
+ a memory operand.
+
+2003-06-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * varasm.c: Don't include c-tree.h.
+
+2003-06-08 Andreas Jaeger <aj@suse.de>
+
+ * predict.h: Convert to ISO C90 prototypes.
+ * predict.c: Likewise.
+ * tree-dump.h: Likewise.
+ * tree-dump.c: Likewise.
+ * diagnostic.h: Likewise.
+ * diagnostic.c: Likewise.
+ * combine.c: Likewise.
+
+ * rtl.h: Convert prototypes of combine.c to ISO C90.
+
+Sun Jun 8 21:27:41 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * cfglayout.c (insn_scope): New static function
+ (block_locators_*, line_locators*, file_locators*): New static varrays.
+ (scope_to_insns_initialize): Use them.
+ (insn_line, insn_file): New functions.
+ (scope_to_insns_finalize): Use insn_scope.
+ (prologue_locator, epilogue_locator): New global variables.
+ * emit-rt.c (try_split, make_insn_raw, make_jump_insn_raw,
+ make_call_insn_raw, emit_copy_of_insn_after): Use locators.
+ (emit_insn_after_scope, emit_insn_before_scope
+ emit_jump_insn_after_scope, emit_jump_insn_before_scope
+ emit_call_insn_after_scope, emit_call_insn_before_scope): Rename to...
+ (emit_insn_after_setloc, emit_insn_before_setloc
+ emit_jump_insn_after_setloc, emit_jump_insn_before_setloc
+ emit_call_insn_after_setloc, emit_call_insn_before_setloc): ... these;
+ use locators.
+ * final.c (notice_source_line): Use locators.
+ (final_start_function): Set initial source file and line.
+ (final_scan_insn): Use locators.
+ * ifcvt.c (noce_try_store_flag, noce_try_store_flag_constants,
+ noce_try_addcc, noce_try_store_flag_mask, noce_try_cmove,
+ noce_try_cmove_arith, noce_try_minmax, noce_try_abs,
+ noce_process_if_block, find_cond_trap): Likewise.
+ * integrate.c (copy_insn_list): Likewise.
+ * jump.c (duplicate_loop_exit_test): LIkewise.
+ * print-rtl.c (print_rtx): Print locators.
+ * recog.c (peephole2_optimize): Likewise.
+ * rtl.h (INSN_SCOPE): Remove.
+ (emit_insn_after_scope, emit_insn_before_scope
+ emit_jump_insn_after_scope, emit_jump_insn_before_scope
+ emit_call_insn_after_scope, emit_call_insn_before_scope): Rename to...
+ (emit_insn_after_setloc, emit_insn_before_setloc
+ emit_jump_insn_after_setloc, emit_jump_insn_before_setloc
+ emit_call_insn_after_setloc, emit_call_insn_before_setloc): ... these;
+ (insn_file, insn_line, prologue_locator, epilogue_locator): Declare.
+ * unroll.c (copy_loop_body): Use locators.
+ * function.c (set_insn_locators): New function.
+ (thread_prologue_and_epilogue_insns): Set the locators accordingly.
+
+2003-06-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (LONG_LONG_TYPE_SIZE): Set to 64.
+ * config/h8300/t-h8300 (LIB1ASMFUNCS): Remove _floatdisf
+ _fixsfdi _fixunssfdi.
+ (LIB2FUNCS_EXTRA): Add entries for clzhi2, ctzhi2, parityhi2,
+ popcounthi2.
+ (TARGET_LIBGCC2_CFLAGS): Remove -DDI=SI.
+ * config/h8300/clzhi2.c: New.
+ * config/h8300/ctzhi2.c: Likewise.
+ * config/h8300/parityhi2.c: Likewise.
+ * config/h8300/popcounthi2.c: Likewise.
+
+Sun Jun 8 15:52:17 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (subsi_3_zext, sse2_nandv2di3): Fix predicates.
+ * i386.c (k8_avoid_jump_misspredicts): Fix debug output.
+
+ * cfg.c (verify_flow_info): Move IL independent checks from cfgrtl here.
+ (dump_bb): New based on old dump_bb in cfgrtl.c
+ (debug_bb, debug_bb_n): Move the functions from cfgrtl.c here.
+ * cfghooks.h (cfgh_verify_flow_info): Return status.
+ * cfglayout.c (cfg_layout_finalize): Verify CFG correctness.
+ * cfgrtl.c (debug_bb, debug_bb_n): Move to cfg.c
+ (dump_bb): Remove generic parts.
+ (rtl_verify_flow_info_1): Break out from rtl_verify_flow_info.
+ (rtl_verify_flow_info): Only check things dependeing on linearized RTL.
+
+2003-06-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Rename options.c and options.h to c-options.c and
+ c-options.h.
+ (OBJS): Remove options.o.
+ * c-opts.c: Don'tInclude c-options.h instead of options.h.
+ * opts.c: Don't include options.h.
+ (find_opt): Can't use enum opt_code or N_OPTS.
+ * opts.h (struct cl_option, cl_options, cl_options_count): Move from...
+ * opts.sh: ... here.
+
+2003-06-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
+
+ PR pch/9830
+ * ggc-common.c (HAVE_MMAP_FILE): Include sys/types.h
+ if HAVE_MINCORE is defined.
+ (MAP_FAILED): Define if not defined.
+ (gt_pch_save): Test against MAP_FAILED.
+ (gt_pch_restore): If HAVE_MINCORE, use MAP_FIXED to force
+ the mapping address to the preferred base after checking it
+ is possible to do so. Test against MAP_FAILED.
+ * configure.in: Test for the presence of mincore in libc.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+
+2003-06-07 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_setup_incoming_varargs): Fix
+ conditional compilation guard.
+
+2003-06-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * optabs.c (expand_abs): Set result_unsignedp to 1 if
+ flag_trav is zero.
+
+2003-06-07 Richard Henderson <rth@redhat.com>
+
+ * c-cppbuiltin.c (c_cpp_builtins): Define __EXCEPTIONS for C also.
+
+2003-06-07 Richard Henderson <rth@redhat.com>
+
+ * basic-block.h (EDGE_SIBCALL): New.
+ (EDGE_ALL_FLAGS): Update.
+ * cfg.c (dump_edge_info): Add sibcall name.
+ * cfgbuild.c (make_edges): Use EDGE_SIBCALL.
+ * cfgrtl.c (purge_dead_edges): Handle sibcalls.
+
+2003-06-07 Andreas Jaeger <aj@suse.de>
+
+ * mklibgcc.in (lib2funcs): Remove _exit.
+ * libgcc2.c: Remove L_exit.
+ * gbl-ctors.h: Remove declarations dependend on NEED_ATEXIT.
+
+ * system.h: Poison NEED_ATEXIT, ON_EXIT, EXIT_BODY.
+
+ * doc/tm.texi (Misc): Remove NEED_ATEXIT, ON_EXIT, EXIT_BODY.
+
+ * ggc.h: Convert to ISO C90 prototypes.
+ * ggc-none.c: Likewise.
+ * ggc-common.c: Likewise.
+ * ggc-page.c: Likewise.
+ * ggc-simple.c: Likewise.
+
+ * crtstuff.c: Remove undefined usage of INIT_SECTION_PREAMBLE.
+
+ * system.h: Poison INIT_SECTION_PREAMBLE.
+
+2003-06-07 Zack Weinberg <zack@codesourcery.com>
+
+ * config.gcc (with_cpu handling): Translate sparc64 in
+ $machine to --with-cpu=v9.
+ * config/alpha/alpha.c
+ (TARGET_ASM_GLOBALIZE_LABEL [TARGET_ABI_UNICOSMK]): Correct definition.
+ (alpha_setup_incoming_varargs): #ifdef out when TARGET_ABI_UNICOSMK.
+
+ * target.h: New hook asm_out.file_end.
+ * target.h: Update to match. New hook macro TARGET_ASM_FILE_END.
+ * toplev.c (compile_file): Use targetm.asm_out.file_end.
+ * system.h: Poison ASM_FILE_END.
+ * varasm.c (file_end_indicate_exec_stack): New.
+ * output.h: Prototype it.
+ * doc/tm.texi: Document TARGET_ASM_FILE_END and
+ file_end_indicate_exec_stack. Delete references to attasm.h.
+
+ * config/darwin.h (TARGET_ASM_FILE_END): Reset to darwin_file_end.
+ (ASM_FILE_END): Delete; move code...
+ * config/darwin.c (darwin_file_end): Here; new function.
+ * config/darwin-protos.h: Prototype it.
+ * config/alpha/alpha.c (unicosmk_asm_file_end): Make static,
+ rename unicosmk_file_end.
+ * config/arm/aof.h (ASM_FILE_END): Delete; move code...
+ * config/arm/arm.c (aof_file_end): ... here; new static function.
+ Set TARGET_ASM_FILE_END to aof_file_end if AOF_ASSEMBLER.
+ Make aof_dump_imports and aof_dump_pic_table static.
+ * config/avr/avr.c (asm_file_end): Rename avr_file_end, make static.
+ Set TARGET_ASM_FILE_END to avr_file_end.
+ * config/c4x/c4x.c (c4x_file_end): Make static. Take no arguments.
+ Set TARGET_ASM_FILE_END to c4x_file_end.
+ * config/h8300/h8300.c (asm_file_end): Rename h8300_file_end,
+ make static. Take no arguments. Set TARGET_ASM_FILE_END to
+ h8300_file_end.
+ * config/i370/i370.h (ASM_FILE_END): Delete; move code...
+ * config/i370/i370.c (i370_file_end): ... here; new static function.
+ Set TARGET_ASM_FILE_END to i370_file_end.
+ * config/i386/i386.c (ix86_asm_file_end): Rename ix86_file_end.
+ Take no arguments. Call file_end_indicate_exec_stack if
+ NEED_INDICATE_EXEC_STACK; don't use SUBTARGET_FILE_END.
+ * config/i386/i386.h: Set TARGET_ASM_FILE_END, not ASM_FILE_END.
+ Define NEED_INDICATE_EXEC_STACK to 0.
+ * config/i386/linux.h, config/i386/linux64.h: Redefine
+ NEED_INDICATE_EXEC_STACK to 1 instead of setting SUBTARGET_FILE_END.
+ * config/i386/winnt.c (i386_pe_asm_file_end): Rename to
+ i386_pe_file_end. Take no arguments. Use ix86_file_end.
+ * config/ia64/ia64.c (ia64_hpux_asm_file_end): Rename to
+ ia64_hpux_file_end, make static. Take no arguments.
+ * config/ip2k/ip2k.c (asm_file_start, asm_file_end,
+ commands_in_prologues, commands_in_epilogues): Delete.
+ (function_epilogue): Update to match.
+ * config/mips/mips.c (mips_asm_file_end): Rename mips_file_end,
+ make static. Take no arguments.
+ (iris6_asm_file_end): Rename iris6_file_end, make static, use
+ mips_file_end, take no arguments.
+ Set TARGET_ASM_FILE_END to iris6_file_end or mips_file_end as
+ appropriate.
+ * config/mmix/mmix.c (mmix_asm_file_end): Rename mmix_file_end,
+ make static, take no arguments. Set TARGET_ASM_FILE_END to
+ mmix_file_end.
+ * config/pa/pa.c (output_deferred_plabels): Make static, take
+ no arguments. Set TARGET_ASM_FILE_END to output_deferred_plabels.
+ * config/rs6000/xcoff.h (TARGET_ASM_FILE_END): Set it.
+ (ASM_FILE_END): Delete; move code...
+ * config/rs6000/rs6000.c (rs6000_xcoff_file_end): ... here;
+ new static function.
+
+ * config/avr/avr.h, config/cris/cris.h, config/h8300/h8300.h
+ * config/mmix/mmix.h, config/mips/iris6.h, config/mips/mips.h:
+ Don't set ASM_FILE_END.
+ * config/alpha/linux-elf.h, config/m68k/linux.h, config/rs6000/linux.h
+ * config/rs6000/linux64.h, config/s390/linux.h, config/sparc/linux.h
+ * config/sparc/linux64.h: Set TARGET_ASM_FILE_END to
+ file_end_indicate_exec_stack; don't set ASM_FILE_END.
+ * config/alpha/unicosmk.h, config/i386/cygming.h
+ * config/ia64/hpux.h: Set TARGET_ASM_FILE_END, not ASM_FILE_END.
+ * config/arm/arm-protos.h, config/alpha/alpha-protos.h
+ * config/avr/avr-protos.h, config/c4x/c4x-protos.h
+ * config/h8300/h8300-protos.h, config/ia64/ia64-protos.h
+ * config/ip2k/ip2k-protos.h, config/mips/mips-protos.h
+ * config/mmix/mmix-protos.h, config/pa/pa-protos.h: Update.
+
+Sat Jun 7 18:32:13 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.h (OPTION_DEFAULT_SPECS): Avoid -mcpu default when -march is
+ specified.
+
+Sat Jun 7 15:20:01 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (stageprofile_build): Kill redundant target.
+ * i386.c (mdep_reorg): Don't pad jumps for Athlon.
+
+2003-06-07 Andreas Jaeger <aj@suse.de>
+
+ * doc/tm.texi (Costs): Remove DONT_REDUCE_ADDR documentation.
+
+ * config/avr/avr.h: Remove comment regarding DONT_REDUCE_ADDR.
+ * config/dsp16xx/dsp16xx.h: Likewise.
+ * config/i386/i386.h: Likewise.
+ * config/ip2k/ip2k.h: Likewise.
+
+2003-06-07 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in (OJBS, c-opts.o): Update.
+ (c-options.c, c-options.h): Rename options.h and options.c.
+ (options.h): Rename options_.h.
+ (opts.o): New.
+ * c-common.h (c_common_handle_option): Replace c_common_decode_option.
+ (c_common_init_options): Update prototype.
+ * c-lang.c (c_init_options): Update prototype.
+ (LANG_HOOKS_HANDLE_OPTION): Override.
+ (LANG_HOOKS_DECODE_OPTION): Drop.
+ * c-opts.c: Include opts.h and options.h instead of c-options.h
+ and c-options.c.
+ (lang_flags): Move to file scope.
+ (find_opt, c_common_decode_option): Remove.
+ (CL_C, CL_OBJC, CL_CXX, CL_OBJCXX, CL_JOINED, CL_SEPARATE,
+ CL_REJECT_NEGATIVE): Move to opts.h.
+ (missing_arg): Update prototype.
+ (c_common_init_options): Update for new prototype.
+ (c_common_handle_options): Filenames are passed as N_OPTS.
+ * hooks.c (hook_int_void_0): New.
+ * hooks.h (hook_int_void_0): New.
+ * langhooks-def.h (LANG_HOOKS_INIT_OPTIONS): New default.
+ (LANG_HOOKS_HANDLE_OPTION): Default to NULL for now.
+ (LANG_HOOKS_INITIALIZER): Update.
+ * langhooks.h (init_options): Update.
+ (handle_option): New.
+ * opts.c, opts.h: New files.
+ * opts.sh: Update c file to include opts.h and options.h.
+ * toplev.c: Include opts.h; change options.h to options_.h.
+ (parse_options_and_default_flags): Get lang_mask, use
+ handle_option for language-specific handling.
+ * objc/objc-lang.c (LANG_HOOKS_DECODE_OPTON): Drop.
+ (LANG_HOOKS_HANDLE_OPTION): Override.
+ (objc_init_options): Update.
+
+2003-06-07 Magnus Kreth <magnus.kreth@gmx.de>
+ Thibaud Gaillard <thibaud.gaillard@nto.atmel.com>
+
+ PR other/7031
+ * Makefile.in (install-common): Remove GCOV_INSTALL_NAME instead of
+ gcov.
+
+2003-06-07 Kelley Cook <kelleycook@wideopenwest.com>
+
+ * configure.in (HAVE_LD_RO_RW_SECTION_MIXING): Remove quotes in
+ section names.
+ * configure: Regenerate.
+
+2003-06-07 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/linux64.h (CRT_CALL_STATIC_FUNCTION): Define.
+
+2003-06-06 James E Wilson <wilson@tuliptree.org>
+
+ PR inline-asm/10890
+ * reload1.c (merge_assigned_reloads): Abort only if two reloads have
+ different in fields.
+
+2003-06-06 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Make $(target_subdir) correspond with top level usage.
+ * Makefile.in: Likewise.
+ * configure: Regenerate.
+
+2003-06-06 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_ALIGNED_COMMON,
+ ASM_OUTPUT_ALIGNED_LOCAL): Cast `SIZE' and `ALIGNED' parameters to
+ unsigned HOST_WIDE_INT.
+ * pa-pro-end.h (ASM_OUTPUT_ALIGNED_COMMOM, ASM_OUTPUT_ALIGNED_LOCAL):
+ Likewise.
+ * pa64-hpux.h (ASM_OUTPUT_ALIGNED_COMMON, ASM_OUTPUT_ALIGNED_LOCAL):
+ Likewise.
+
+2003-06-06 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * doc/install.texi (Prerequisites): New section documenting
+ tools and packages necessary prior to building and/or
+ modifying GCC.
+ * doc/install.texi2html: Also generate prerequisites.html.
+
+2003-06-06 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/11052
+ * ifcvt.c (noce_process_if_block): Fail if the destination has
+ side-effects.
+
+2003-06-06 Jason Merrill <jason@redhat.com>
+
+ * stmt.c (resolve_asm_operand_names): Rename from
+ resolve_operand_names. No longer static. Avoid needless copying.
+ Don't build array of constraints.
+ (expand_asm_operands): Build it here.
+ * tree.h: Declare resolve_asm_operand_names.
+
+ * stmt.c (expand_decl): Put artificial vars into registers even
+ when not optimizing, and don't mark the regs as user vars.
+
+2003-06-06 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (FUNCTION_ARG_1): Consistently use NEW_MODE for the mode
+ of the generated register.
+
+2003-06-06 Daniel Jacobowitz <drow@mvista.com>
+
+ * config.gcc: Add a missing sparc64 case.
+
+2003-06-06 Jakub Jelinek <jakub@redhat.com>
+
+ * mklibgcc.in: Propagate .note.GNU-stack section if needed into
+ the .hidden assembly stubs.
+
+2003-06-06 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config.gcc (extra_headers): Add emmintrin.h for i[34567]86-*-*
+ and x86_64-*-*.
+
+ * config/i386/mmintrin.h: Update version and add alternate
+ intrinsic names.
+ * config/i386/xmmintrin.h: Likewise.
+
+ * config/i386/xmmintrin.h: Include <emmintrin.h>. Move SSE2
+ intrinsics to ...
+ * config/i386/emmintrin.h: Here. New file.
+
+2003-06-06 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold <ABS_EXPR>): Re-fold the result of folding
+ fabs(-x) into fabs(x). Use tree_expr_nonnegative_p to determine
+ when the ABS_EXPR (fabs or abs) is not required.
+ (tree_expr_nonnegative_p): Move the logic that sqrt and exp are
+ always nonnegative from fold to here. Additionally, cabs and fabs
+ are always non-negative, and pow and atan are non-negative if
+ their first argument is non-negative.
+
+ * builtins.c (fold_builtin_cabs): New function to fold cabs{,f,l}.
+ Evaluate cabs of a constant at compile-time. Convert cabs of a
+ non-complex argument into fabs. Convert cabs(z) into
+ sqrt(z.r*z.r + z.i*z.i) at the tree-level with -ffast-math or
+ -funsafe-math-optimizations or -ffast-math.
+ (fold_builtin): Convert BUILT_IN_FABS{,F,L} into an ABS_EXPR.
+ Fold BUILT_IN_CABS{,F,L} using fold_builtin_cabs.
+
+Thu Jun 5 20:51:09 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * sourcebuild.texi (Front End Directory): Document new hooks.
+
+Fri Jun 6 11:02:35 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * function.c (FLOOR_ROUND, CEIL_ROUND): Fix.
+ * i386.md (gen_pro_epilogue_adjust_stack): Deal with gigantic
+ stack frames.
+ (pro_epilogue_adjust_stack_rex64_2): New pattern
+
+Fri Jun 6 11:03:14 CEST 2003 Jan Hubicka <jh@suse.cz>
+ Pop Sebastian
+ Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfghooks.h, cfghooks.c: New files.
+ * Makefile.in (BASIC_BLOCK_H): Depends on cfghooks.h.
+ (OBJS): Add cfghooks.o.
+ (cfghooks.o): New rule.
+ * basic-block.h (split_edge): Rename to rtl_split_edge.
+ (verify_flow_info): Rename to rtl_verify_flow_info.
+ (cfghooks.h): Included here.
+ * cfgrtl.c (split_edge): Renamed rtl_split_edge.
+ (verify_flow_info): Renamed rtl_verify_flow_info.
+ * toplev.c (rest_of_compilation): Call rtl_register_cfg_hooks.
+
+ * basic-block.h (split_block, split_edge, flow_delete_block,
+ redirect_edge_and_branch, redirect_edge_and_branch_force): Delete.
+ (flow_delete_block_noexpunge): Return void.
+ * cfg.c (verify_flow_info): New function.
+ * cfgcleanup.c (try_simplify_condjump, outgoing_edges_match,
+ try_crossjump_to_edge, try_optimize_cfg, delete_unreachable_blocks):
+ Use delete_block.
+ * cfglayout.c (function_footer): Rename to...
+ (cfg_layout_function_footer): ... this variable
+ (unlink_insn_chain): Make global.
+ (fixup_reorder_chain, record_effective_endpoints): Update.
+ (cleanup_unconditional_jumps): Use delete_block.
+ (cfg_layout_redirect_edge, cfg_layout_split_block): Move to cfgrtl.c
+ (cfg_layout_duplicate_bb): Use redirect_edge_and_branch_force.
+ (cfg_layout_initialize, cfg_layout_finalize): Update hooks.
+ * cfglayout.h (cfg_layout_redirect_edge, cfg_layout_split_block): Delete.
+ (cfg_layout_function_footer): Declare.
+ * cfgloopmanip (split_loop_bb): Do not update RBI.
+ (remove_bbs): Use delete_block.
+ (loop_reidrect_edge, loop_delete_branch_edge): Use
+ redirect_edge_and_branch.
+ (create_preheader): Use split_block and redirect_edge_and_branch_force.
+ (split_edge_with): Likewise.
+ * cfgrtl.c: Include cfglayout.h
+ (split_edge): Rename to ...
+ (rtl_split_edge) ... this one; make local.
+ (redirect_edge_and_branch): Rename to ...
+ (rtl_redirect_edge_and_branch) ... this one; make local.
+ (redirect_edge_and_branch_force): Rename to ...
+ (rtl_redirect_edge_and_branch_force) ... this one; make local.
+ (cfg_layout_delete_block, cfg_layout_delete_edge_and_branch_force): New.
+ (cfg_layout_redirect_edge_and_branch, cfg_layout_split_block): Move here from
+ cfglayout.c; update to directly call RTL counterparts.
+ (rtl_cfg_hooks, cfg_layout_rtl_cfg_hooks): New functions.
+ * ifcvt.c (find_cond_trap): Use delete_block.
+ (find_if_case_1): Use delete_block.
+ (find_if_case_2): Use delete_block.
+ * rtl.h (unlink_insn_chain): Declare.
+ * toplev.c (rtl_reigster_cfg_hooks): New.
+
+2003-06-05 Richard Henderson <rth@redhat.com>
+
+ * recog.c (peephole2_optimize): Revert last change.
+
+2003-06-05 Richard Henderson <rth@redhat.com>
+
+ * recog.c (peephole2_optimize): Don't split block unless
+ can_throw_internal.
+
+2003-06-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (get_shift_alg): Correct the syntax of rotxl.
+ * config/h8300/h8300.md (*addsi3_lshiftrt_16_zexthi): Likewise.
+
+2003-06-05 Kelley Cook <kelleycook@wideopenwest.com>
+
+ PR optimization/4490
+ * config/i386/i386.md: Don't use XFMode if TARGET_128BIT_LONG_DOUBLE.
+ * doc/invoke.texi (m96bit-long-double, m128bit-long-double): Reword
+ documentation to accurately reflect what these options do.
+
+2003-06-06 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/linux.h (STARTFILE_SPEC): Handle -pie. Simplify.
+ (ENDFILE_SPEC): Redefine to handle -pie.
+
+2003-06-05 Phil Edwards <phil@jaj.com>
+
+ * Makefile.in (qmtest-g++): Use target_alias, not target.
+
+2003-06-05 Per Bothner <pbothner@apple.com>
+
+ * toplev.c (push_srcloc): Simplify behavior to save current location
+ and set current location to parameters.
+ (pop_srcloc): Simplify semantics.
+ (lang_dependent_init): Remove now-useless initial push_srcloc.
+
+2003-05-06 Richard Henderson <rth@redhat.com>
+
+ * dwarf2out.c (loc_descriptor_from_tree): Return 0 for
+ language-specific tree codes.
+
+2003-06-05 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR middle-end/9986
+ * pa.c (pa_init_builtins): Also set implicit_built_in_decls for
+ BUILT_IN_FPUTC_UNLOCKED to NULL_TREE.
+
+Thu Jun 5 18:32:46 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * install.tex: Document profiledbootstrap.
+
+ * configure.in: Add support for lang.stageprofile and
+ lang.stagefeedback
+ * Makefile.in (clean, distclean): Kill new stages
+ (POSTSTAGE1_FLAGS_TO_PASS): Break from ...
+ (STAGE2_FLAGS_TO_PASS): ... this one.
+ (STAGEPROFILE_FLAGS_TO_PASS, STAGEFEEDBACK_FLAGS_TO_PASS): New.
+ (stage[2-4]_build): Add POSTSTAGE1_FLAGS_TO_PASS.
+ (stageprofile_build, stageprofile_copy, stagefeedback_build,
+ stagefeedback_copy): New.
+ (restageprofile, restagefeedback, stageprofile-start,
+ stageprofile, stagefeedback-start): Likewise.
+
+2003-06-05 David Miller <davem@redhat.com>
+ Richard Henderson <rth@redhat.com>
+
+ * optabs.c (HAVE_conditional_trap): Provide default.
+ (gen_conditional_trap): Likewise.
+ (init_optabs): Merge init_traps.
+ (gen_cond_trap): Use prepare_operand. Restructure and avoid ifdef.
+
+Thu Jun 5 14:59:44 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * combine.c (simplify_if_then_else): (IF_THEN_ELSE (NE REG 0) (0) (8))
+ is REG for nonzero_bits (REG) == 8.
+
+Thu Jun 5 13:23:51 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (align): Fix warning; clarify what to do when no p2align
+ is available.
+
+2003-06-05 Nick Clifton <nickc@redhat.com>
+
+ * config.gcc (m32r-elf): Revert previous delta.
+ * config/m32r/t-m32r (crtinit.o): Fix rule to work with
+ multilibs. Remove m32rx specific version.
+ (crtfini.o): Likewise.
+ (EXTRA_MULTILIB_PARTS): Define.
+
+2003-06-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/md.texi (Machine Constraints): Correct the meaning of
+ constraints related to floating-point registers on SPARC.
+
+2003-06-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Paolo Bonzini <bonzini@gnu.org>
+
+ PR target/10663
+ * configure.in (HAVE_LD_RO_RW_SECTION_MIXING): Redirect
+ assembler and linker output to /dev/null.
+ Use a 'sed' construct instead of 'grep -A1'.
+ * configure: Regenerate.
+
+2003-06-04 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (struct ix86_address): Add seg.
+ (no_seg_address_operand): New.
+ (ix86_decompose_address): Restructure PLUS loop. Accept one
+ UNSPEC_TP if TARGET_TLS_DIRECT_SEG_REFS. Adjust ESP swap test
+ to test for a regnum, not stack_pointer_rtx.
+ (ix86_address_cost): Reduce cost if non-default segment.
+ (legitimate_address_p): Remove UNSPEC_TP check.
+ (get_thread_pointer): Add to_reg argument. Don't represent
+ the thread pointer as a memory load.
+ (legitimize_tls_address): Split out of ...
+ (legitimize_address): ... here.
+ (print_operand_address): Handle parts.seg.
+ (ix86_expand_move): Use legitimize_tls_address.
+ (ix86_rtx_costs): Handle UNSPEC_TP.
+ * config/i386/i386.h (MASK_TLS_DIRECT_SEG_REFS): New.
+ (TARGET_TLS_DIRECT_SEG_REFS): New.
+ (TARGET_SWITCHES): Add tls-direct-seg-refs.
+ (TARGET_TLS_DIRECT_SEG_REFS_DEFAULT): Default.
+ (PREDICATE_CODES): Add no_seg_address_operand.
+ * config/i386/i386.md (lea_1): Use it.
+ (lea_1_rex64, lea_1_zext, lea_2_rex64): Likewise.
+ (load_tp_si, add_tp_si, load_tp_di, add_tp_di): New.
+ * config/i386/linux.h (TARGET_TLS_DIRECT_SEG_REFS_DEFAULT): New.
+ * config/i386/linux64.h (TARGET_TLS_DIRECT_SEG_REFS_DEFAULT): New.
+ * doc/invoke.texi: Add -mtls-direct-seg-refs.
+
+2003-06-04 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (QMTESTRUNFLAGS): Set for DejaGNU emulation.
+ (QMTEST_GPP_TESTS): Use "g++" by default.
+ (stamp-qmtest): Tweak database creation.
+ (QMTEST_DIR/context): Update context file format.
+ (qmtest-g++): Tweak command-line.
+
+2003-06-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (varasm.o): Don't set -Wno-error.
+ * rs6000/t-rs6000 (varasm.o, out_object_file): Don't clear.
+
+2003-06-04 Zack Weinberg <zack@codesourcery.com>
+
+ PR bootstrap/3163
+ * aclocal.m4 (AC_FUNC_MMAP_ANYWHERE, AC_FUNC_MMAP_FILE): Delete.
+ (gcc_AC_FUNC_MMAP_BLACKLIST): New.
+ * configure.in: Check for sys/mman.h and mmap in AC_CHECK_HEADERS
+ and AC_CHECK_FUNCS lists, respectively. Use
+ gcc_AC_FUNC_MMAP_BLACKLIST, not AC_FUNC_MMAP_ANYWHERE nor
+ AC_FUNC_MMAP_FILE.
+ * configure, config.in: Regenerate.
+
+2003-06-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * arm/aout.h (ASM_OUTPUT_SKIP): Fix cast for format specifier warning.
+ * arm.c (arm_output_function_prologue): Fix format specifiers.
+ * arm.h (ARM_PRINT_OPERAND_ADDRESS): Likewise.
+ * m68k.c (m68k_output_mi_thunk): Use more readable %wd instead of
+ HOST_WIDE_INT_PRINT_DEC.
+ * vax.c (vax_output_function_prologue): Fix format specifiers.
+
+2003-06-04 Richard Henderson <rth@redhat.com>
+
+ * cse.c (find_best_addr): Consider binary operators even if second
+ argument is not CONST_INT.
+
+2003-06-04 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * doc/invoke.texi (max-cse-path-length): Document.
+
+2003-06-04 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.md (align): Use ASM_OUTPUT_*ALIGN macros.
+
+2003-06-04 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config/rs6000/darwin.h (RS6000_OUTPUT_BASENAME):
+ Remove semi-colon at the end of the expression.
+
+2003-06-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * i370.c (mvs_function_name_length): Fix signed/unsigned warnings.
+ * i370.h (mvs_function_name_length): Likewise.
+ * i960.h (CONSTANT_ALIGNMENT): Likewise.
+ * mips/linux.h (ASM_OUTPUT_ALIGNED_BSS): Likewise.
+ * pa/pa-pro-end.h (ASM_OUTPUT_ALIGNED_COMMON): Likewise.
+ * pa.h (ASM_OUTPUT_ALIGNED_COMMON): Likewise.
+ * rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Delete unused
+ variable.
+
+2003-06-04 Daniel Jacobowitz <drow@mvista.com>
+
+ * config.gcc: Reorganize --with-cpu logic. Set
+ configure_default_options according to the default CPU, --with-cpu,
+ --with-arch, --with-tune, --with-schedule, --with-abi, and
+ --with-float. Check for legal values of various options.
+ * configure.in: Define configure_default_options in configargs.h.
+ * configure: Regenerated.
+ * config/mips/mips.h (TARGET_DEFAULT_ARCH_P)
+ (TARGET_DEFAULT_FLOAT_P): New macros.
+ * gcc.c (do_option_spec): New function.
+ (struct default_spec, option_default_specs): New.
+ (main): Call do_option_spec.
+ * config/alpha/alpha.h, config/arm/arm.h, config/i386/i386.h,
+ config/mips/mips.h, config/pa/pa.h, config/rs6000/rs6000.h,
+ config/sparc/sparc.h (OPTION_DEFAULT_SPECS): Define.
+
+ * doc/install.texi: Update --with-cpu documentation. Mention
+ --with-arch, --with-schedule, --with-tune, --with-abi, and
+ --with-float.
+ * doc/tm.texi (Driver): Document OPTION_DEFAULT_SPECS.
+
+2003-06-04 Daniel Jacobowitz <drow@mvista.com>
+
+ * config.gcc: Only process --with-cpu logic in the third pass.
+
+2003-06-04 Daniel Jacobowitz <drow@mvista.com>
+
+ * config.gcc: Reorganize --with-cpu section. Remove an
+ obsolete comment about the default CPU for x86-64. Fix
+ a typo for the ep9312. Update the list of supported PowerPC
+ CPUs. Support a limited set of new --with-cpu options
+ for i386.
+
+2003-06-04 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_complex_function_value): Unpack
+ complex numbers <= 32 bits into two registers.
+
+2003-06-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alpha.c (print_operand_address): Fix format specifier warnings.
+ * alpha/elf.h (ASM_OUTPUT_ALIGNED_COMMON): Likewise.
+ * alpha/vms.h (ASM_OUTPUT_ALIGNED_COMMON): Likewise.
+ * arm/aof.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL): Likewise.
+ * arm/pe.h (ASM_OUTPUT_COMMON): Likewise.
+ * avr.h (ASM_OUTPUT_COMMON, ASM_GENERATE_INTERNAL_LABEL,
+ ASM_OUTPUT_SKIP): Likewise.
+ * c4x.h (ASM_GENERATE_INTERNAL_LABEL): Likewise.
+ * dsp16xx.h (ASM_GENERATE_INTERNAL_LABEL): Likewise.
+ * h8300.h (ASM_GENERATE_INTERNAL_LABEL, ASM_OUTPUT_COMMON):
+ Likewise.
+ * i370.h (ASM_GENERATE_INTERNAL_LABEL): Likewise.
+ * i386/cygming.h (ASM_OUTPUT_COMMON): Likewise.
+ * i386/darwin.h (ASM_OUTPUT_COMMON): Likewise.
+ * i960.h (ASM_GENERATE_INTERNAL_LABEL): Likewise.
+ * m68k/hp320.h (PRINT_OPERAND_ADDRESS): Likewise.
+ * mcore.h (ASM_OUTPUT_ALIGNED_COMMON): Likewise.
+ * pdp11.h (ASM_GENERATE_INTERNAL_LABEL): Likewise.
+ * ptx4.h (ASM_OUTPUT_ALIGNED_COMMON): Likewise.
+ * sparc/freebsd.h (ASM_GENERATE_INTERNAL_LABEL): Likewise.
+ * svr3.h (ASM_OUTPUT_COMMON): Likewise.
+
+2003-06-04 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * c-decl.c (c_init_decl_processing): Clear input_file_name
+ while building common nodes.
+ * dwarf2out.c (gen_compile_unit_die, dwarf2out_finish):
+ Don't add working directory for strings like <built-in> .
+
+2003-06-04 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/install.texi (*-ibm-aix*): Native as and ld required
+ to bootstrap on AIX 5L.
+
+2003-06-04 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (handle_cleanup_attribute): New.
+ (c_common_attributes): Add it.
+ * c-decl.c (finish_decl): Honor the cleanup attribute.
+ * doc/extend.texi (Variable Attributes): Document it.
+
+ * unwind-c.c: New file.
+ * Makefile.in (LIB2ADDEH): Add it.
+ * config/t-darwin, config/t-linux, config/t-linux-gnulibc1,
+ config/ia64/t-ia64: Likewise.
+
+2003-06-04 Jakub Jelinek <jakub@redhat.com>
+
+ * function.c (trampolines_created): New variable.
+ (expand_function_end): Set it when doing INITIALIZE_TRAMPOLINE.
+ * function.h (trampolines_created): Add.
+ * config/s390/linux.h (ASM_FILE_END): Define.
+ * config/alpha/linux-elf.h (ASM_FILE_END): Define.
+ * config/m68k/linux.h (ASM_FILE_END): Define.
+ * config/rs6000/linux.h (ASM_FILE_END): Define.
+ * config/rs6000/linux64.h (ASM_FILE_END): Define.
+ * config/rs6000/ppc-asm.h: Add .note.GNU-stack on powerpc-linux.
+ * config/sparc/linux.h (ASM_FILE_END): Define.
+ * config/sparc/linux64.h (ASM_FILE_END): Define.
+ * config/i386/i386.c (ix86_asm_file_end): Use SUBTARGET_FILE_END.
+ * config/i386/linux.h (SUBTARGET_FILE_END): Define.
+ * config/i386/linux64.h (SUBTARGET_FILE_END): Define.
+
+Wed Jun 4 18:39:33 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (min_insn_size, k8_avoid_jump_misspredicts): New functions
+ (ix86_reorg): Use it.
+ * i386.md (align): New insn pattern.
+
+2003-06-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * toplev.c (rest_of_type_compilation): Fix typo.
+
+2003-06-04 Jakub Jelinek <jakub@redhat.com>
+ Alan Modra <amodra@bigpond.net.au>
+
+ * config/i386/linux.h (NO_PROFILE_COUNTERS): Define to 1.
+ * config/i386/freebsd.h (NO_PROFILE_COUNTERS): Likewise.
+ * config/i386/netbsd-elf.h (NO_PROFILE_COUNTERS): Likewise.
+ * config/xtensa/xtensa.h (NO_PROFILE_COUTNERS): Likewise.
+ * config/darwin.h (NO_PROFILE_COUNTERS): Likewise.
+ * final.c (NO_PROFILE_COUNTERS): Define to 0 if not defined.
+ (profile_function): Allow NO_PROFILE_COUNTERS to be non-constant.
+ * config/rs6000/rs6000.c (output_profile_hook): Likewise.
+
+ * configure.in (powerpc*-*, s390*-*): Set tls_as_opt.
+ Pass it to $gcc_cv_as.
+ * configure: Rebuilt.
+
+ * config/rs6000/rs6000.c (rs6000_abi_name): Remove initializer.
+ (print_operand): Allow TARGET_AIX to be non-constant.
+ (rs6000_aix_emit_builtin_unwind_init, rs6000_emit_eh_toc_restore):
+ Define unconditionally.
+ (rs6000_elf_declare_function_name): New function.
+ * config/rs6000/rs6000.md (eh_return): Allow TARGET_AIX to be
+ non-constant.
+ * config/rs6000/linux64.h [!RS6000_BI_ARCH] (TARGET_64BIT): Define
+ to 1.
+ (DEFAULT_ARCH64_P, RS6000_BI_ARCH_P): Define.
+ [IN_LIBGCC2] (TARGET_64BIT): Define based on whether __powerpc64__
+ is defined.
+ (TARGET_AIX): Define to 1 if TARGET_64BIT.
+ (PROCESSOR_DEFAULT): Remove.
+ (TARGET_RELOCATABLE, RS6000_ABI_NAME, INVALID_64BIT,
+ INVALID_32BIT, SUBSUBTARGET_OVERRIDE_OPTIONS): Define.
+ [RS6000_BI_ARCH] (OVERRIDE_OPTIONS, ASM_FILE_START): Define.
+ (ASM_DEFAULT_SPEC, ASM_SPEC, LINK_OS_LINUX_SPEC): Define for both
+ -m32 and -m64.
+ (MULTILIB_DEFAULTS): Define.
+ (SUBSUBTARGET_EXTRA_SPECS): Define.
+ (ASM_SPEC32, ASM_SPEC64, ASM_SPEC_COMMON): Define.
+ (TARGET_TOC): Define only if !RS6000_BI_ARCH.
+ (TARGET_NO_TOC): Remove.
+ [!RS6000_BI_ARCH] (TARGET_RELOCATABLE, TARGET_EABI,
+ TARGET_PROTOTYPE): Define to 0.
+ (NO_PROFILE_COUNTERS): Define to TARGET_64BIT.
+ (PROFILE_HOOK): Only call output_profile_hook if TARGET_64BIT.
+ (ADJUST_FIELD_ALIGN, ROUND_TYPE_ALIGN): Adjust to work properly
+ if !TARGET_64BIT.
+ (USER_LABEL_PREFIX): Remove.
+ (JUMP_TABLES_IN_TEXT_SECTION): Define to TARGET_64BIT.
+ (SETUP_FRAME_ADDRESSES): Only call rs6000_aix_emit_builtin_unwind_init
+ if TARGET_64BIT.
+ (TARGET_OS_CPP_BUILTINS): Handle both -m32 and -m64.
+ (LINK_OS_LINUX_SPEC32, LINK_OS_LINUX_SPEC64): Define.
+ (STARTFILE_LINUX_SPEC, ENDFILE_LINUX_SPEC): Remove.
+ (TOC_SECTION_ASM_OP): Define depending on TARGET_64BIT.
+ (MINIMAL_TOC_SECTION_ASM_OP): Likewise.
+ (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Define depending on
+ TARGET_64BIT.
+ (RS6000_CALL_GLUE): Likewise.
+ (SAVE_FP_PREFIX, SAVE_FP_SUFFIX, RESTORE_FP_PREFIX,
+ RESTORE_FP_SUFFIX): Likewise.
+ (ASM_DECLARE_FUNCTION_NAME): Remove.
+ (ASM_DECLARE_FUNCTION_SIZE, ASM_OUTPUT_SOURCE_LINE,
+ DBX_OUTPUT_BRAC, DBX_OUTPUT_NFUN): Only output dot before function
+ name if TARGET_64BIT.
+ (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P): Handle both TARGET_64BIT and
+ !TARGET_64BIT.
+ (ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Remove undefs.
+ (ASM_PREFERRED_EH_DATA_FORMAT): Take TARGET_64BIT into account.
+ (DRAFT_V4_STRUCT_RET): Define.
+ (SIGNAL_FRAMESIZE): New enum value.
+ (MD_FALLBACK_FRAME_STATE_FOR): Define.
+ * config/rs6000/default64.h: New file.
+ * config/rs6000/sysv4.h (SUBTARGET_SWITCHES): Add -m32 and -m64
+ options.
+ (SUBTARGET_OVERRIDE_OPTIONS): If rs6000_abi_name is NULL, set it
+ to RS6000_ABI_NAME. Only disallow mixing of -fPIC with -mcall-aixdesc
+ if !TARGET_64BIT.
+ [!RS6000_BI_ARCH] (SUBSUBTARGET_OVERRIDE_OPTIONS): Define.
+ (ASM_DECLARE_FUNCTION_NAME): Use rs6000_elf_declare_function_name
+ function.
+ (TARGET_OS_SYSV_CPP_BUILTINS): Define.
+ (TARGET_OS_CPP_BUILTINS): Use it.
+ (CPP_SYSV_SPEC): Remove.
+ (CPP_SPEC): Remove cpp_sysv.
+ (SUBTARGET_EXTRA_SPECS): Remove cpp_sysv.
+ Add SUBSUBTARGET_EXTRA_SPECS.
+ (SUBSUBTARGET_EXTRA_SPECS): Define.
+ * config/rs6000/biarch64.h: New file.
+ * config/rs6000/rs6000-protos.h (rs6000_elf_declare_function_name):
+ New prototype.
+ * config/rs6000/x-linux64: New file.
+ * config/rs6000/t-linux64: Build -m64, -m32 and -m32 -msoft-float
+ multilibs.
+ * config/rs6000/eabi-ci.asm: Protect with #ifndef __powerpc64__.
+ * config/rs6000/eabi-cn.asm: Likewise.
+ * config/rs6000/tramp.asm: Likewise.
+ * config/rs6000/sol-ci.asm: Likewise.
+ * config/rs6000/sol-cn.asm: Likewise.
+ * config/rs6000/linux.h (TARGET_64BIT): Define to 0.
+ (TARGET_OS_CPP_BUILTINS): Use TARGET_OS_SYSV_CPP_BUILTINS.
+ * config/rs6000/ppc-asm.h: Move __powerpc64__ section before
+ _CALL_AIXDESC section.
+ * config.gcc (powerpc64-*-linux*): Configure a bi-arch compiler,
+ defaulting to -m64 unless --with-cpu= is one of the 32-bit CPUs
+ or default32.
+
+2003-06-04 Daniel Jacobowitz <drow@mvista.com>
+
+ * config.gcc: Revert accidentally committed ARM changes.
+
+2003-06-04 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (dconstpi, dconste): New mathematical constants.
+ (init_builtin_dconsts): New function to initialize dconstpi
+ and dconste.
+ (fold_builtin): Optimize exp(1.0) = e. Evaluate exp(x) at
+ compile time with -ffast-math when x is an integer constant.
+ Optimize tan(0.0) = 0.0. Optimize atan(0.0) = 0.0,
+ atan(1.0) = pi/4 and tan(atan(x)) = x with -ffast-math.
+
+2003-06-04 Roger Sayle <roger@eyesopen.com>
+
+ * calls.c (expand_call): Avoid calling pure or const functions
+ when the result is ignored (or void) and none of the arguments
+ are volatile. Move warning diagnostic earlier in function.
+
+2003-06-04 Andreas Jaeger <aj@suse.de>
+
+ * system.h: Do not poison TDESC_SECTION_ASM_OP,
+ RDATA_SECTION_ASM_OP and SUBTARGET_PROLOGUE.
+
+2003-06-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * final.c (asm_fprintf): Update comments, accept "-+ #0" flags,
+ optimize '%' case, handle %c, don't accept %p, %e, %f or %g,
+ handle %ll, optimize regular character case.
+
+2003-06-04 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (cse.o): Add params.h dependency.
+ * cse.c: Include params.h.
+ (PATHLENGTH): Removed.
+ (struct cse_basic_block_data): Make path array dynamic.
+ (cse_end_of_basic_block): Use PARAM_MAX_CSE_PATH_LENGTH instead
+ of PATHLENGTH.
+ (cse_main, cse_basic_block): Allocate path array.
+ * params.def (PARAM_MAX_CSE_PATH_LENGTH): New.
+
+Wed Jun 4 09:49:21 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_reorg): Replace the jump instead of adding nop.
+ * i386.md (UNSPEC_REP): New constant.
+ (return_internal_long): New pattern.
+
+2003-06-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/11018
+ * config/sparc/sparc.c (sparc_v8plus_shift): Use which_alternative
+ consistently to decide whether the scratch register is really
+ required.
+
+2003-06-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/10876
+ * config/sparc/sparc.h (CONST_OK_FOR_LETTER): Add
+ new 'O' constraint for constant 4096.
+ (CONST_DOUBLE_OK_FOR_LETTER_P): Likewise.
+ * config/sparc/sparc.md (adddi3 expander): Canonicalize pattern.
+ Do not transform into MINUS insn for constant 4096.
+ (*adddi3_sp64 insn): Canonicalize pattern. Add new alternative
+ for constant 4096 as third operand.
+ (addsi3 expander): Remove.
+ (*addsi3 insn): Rename into 'addsi3'. Canonicalize pattern. Add
+ new alternative for constant 4096 as third operand.
+ (subdi3 expander): Do not transform into PLUS insn for constant 4096.
+ (*subdi3_sp64 insn): Add new alternative for constant 4096 as third
+ operand.
+ (subsi3 expander): Remove.
+ (*subsi3 insn): Rename into 'subsi3'. Add new alternative for
+ constant 4096 as third operand.
+ * doc/md.texi (Machine Constraints): Document new 'O' constraint for
+ the SPARC port.
+
+2003-06-03 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/t-linux64 (CRTSTUFF_T_CFLAGS_S): Define.
+
+2003-06-04 Andreas Jaeger <aj@suse.de>
+
+ * config/i386/uwin.h: Remove SUBTARGET_PROLOGUE.
+
+ * config/i386/i386.c (ix86_expand_prologue): Do not use
+ SUBTARGET_PROLOGUE.
+
+ * system.h: Poision SUBTARGET_PROLOGUE.
+
+ * config/arm/arm-protos.h: Remove unused rdate_section prototype.
+
+ * output.h: Remove TDESC_SECTION_ASM_OP and RDATA_SECTION_ASM_OP
+ dependend code.
+
+ * system.h: Poison TDESC_SECTION_ASM_OP and RDATA_SECTION_ASM_OP.
+
+ * system.h: Poison INSN_CACHE_DEPTH, INSN_CACHE_SIZE and
+ INSN_CACHE_LINE_WIDTH.
+
+ * libgcc2.c (INSN_CACHE_PLANE_SIZE): Removed.
+ (__clear_cache): Remove code dependend on INSN_CACHE_DEPTH,
+ INSN_CACHE_SIZE and INSN_CACHE_LINE_WIDTH.
+
+ * doc/tm.texi (Trampolines): Remove INSN_CACHE_DEPTH,
+ INSN_CACHE_SIZE and INSN_CACHE_LINE_WIDTH.
+
+ * dbxout.c (dbxout_type): Remove usage of DBX_OUTPUT_ENUM.
+ (dbxout_symbol): Remove usage of DBX_OUTPUT_CONSTANT_SYMBOL.
+ (dbxout_block): Remove usage of DBX_OUTPUT_CATCH.
+ (dbxout_block): Remove usage of DBX_LBRAC_FIRST.
+ (dbxout_source_file): Remove usage of DBX_OUTPUT_SOURCE_FILENAME.
+ (dbxout_init): Remove test for DBX_WORKING_DIRECTORY.
+
+ * doc/tm.texi (DBX Options): Do not document DBX_LBRAC_FIRST,
+ DBX_OUTPUT_SOURCE_FILENAME and DBX_OUTPUT_ENUM and
+ DBX_WORKING_DIRECTORY.
+
+ * system.h: Poison DBX_LBRAC_FIRST, DBX_OUTPUT_ENUM,
+ DBX_OUTPUT_SOURCE_FILENAME and DBX_WORKING_DIRECTORY.
+
+ * config/frv/frv-protos.h: Remove unused const_section
+ declaration.
+ * config/vax/vax-protos.h: Likewise.
+
+ * output.h: Remove CONST_SECTION_ASM_OP usage.
+
+ * system.h: Poison CONST_SECTION_ASM_OP.
+
+ * crtstuff.c (__do_global_dtors_aux): Remove usage of
+ CRT_GET_RFIB_TEXT.
+ (frame_dummy): Likewise.
+ * unwind-dw2-fde-glibc.c (_Unwind_IteratePhdrCallback): Likewise.
+ * system.h: Poison CRT_GET_RFIB_TEXT.
+
+ * collect2.c (is_ctor_dtor): Remove CFRONT_LOSSAGE dependend code.
+
+ * fix-header.c: Remove ADD_MISSING_EXTERN_C dependend variables.
+ (write_lbrac): Remove ADD_MISSING_EXTERN_C dependend code.
+ (recognized_function): Likewise.
+ (read_scan_file): Likewise.
+
+2003-06-03 Roger Sayle <roger@eyesopen.com>
+
+ * optabs.c (expand_binop): Optimize complex multiplication for
+ the case of squaring a complex argument.
+
+2003-06-03 Roger Sayle <roger@eyesopen.com>
+
+ * optabs.c (expand_binop): Attempt to reuse pseudos for duplicate
+ non-volatile operands of binary operations.
+ (prepare_cmp_insn): Likewise.
+
+2003-06-03 Roger Sayle <roger@eyesopen.com>
+
+ * varasm.c (force_const_mem): Handle alignment of constants not
+ representable as a type in the front-end language.
+
+2003-06-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * flow.c (initialize_uninitialized_subregs): Use
+ emit_move_insn instead of emitting a hardcoded move.
+
+2003-06-03 Richard Henderson <rth@redhat.com>
+
+ * optabs.c (expand_abs_nojump): Split out from ...
+ (expand_abs): ... here.
+ * optabs.h (expand_abs_nojump): Declare.
+ * ifcvt.c: (noce_try_abs): Use expand_abs_nojump.
+ * Makefile.in (ifcvt.o): Depend on optabs.h.
+
+2003-06-03 Alan Modra <amodra@bigpond.net.au>
+
+ * dwarf2out.c (DEBUG_STR_SECTION_FLAGS): Heed flag_merge_constants.
+
+2003-06-03 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.gcc (default_use_cxa_atexit): New variable, defaults to no.
+ (*-*-netbsd[2-9]* | *-*-netbsdelf[2-9]*): Set default_use_cxa_atexit
+ to yes.
+ * configure.in: Allow default_use_cxa_atexit to determine the
+ value of DEFAULT_USE_CXA_ATEXIT if not explicitly enabled or
+ disabled.
+ * configure: Regenerate.
+
+2003-06-03 Douglas B Rupp <rupp@gnat.com>
+
+ * Makefile.in (TEXI_GCC_FILES): Remove vms.texi entry.
+ * doc/gcc.texi: Remove vms.texi section.
+ * doc/vms.texi: Remove obsolete file.
+
+2003-05-23 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * configure.in (inhibit_libc): Don't define when configuring
+ with --with-newlib --with-headers.
+ * configure: Regenerate.
+
+ * t-sh: Remove LIB2FUNCS_EXTRA and embed-bb.c rules.
+
+2003-06-03 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in (gcc_cv_as_hidden): Disable .hidden completely on
+ IRIX 6 without GNU ld.
+ * configure: Regenerate.
+
+2003-06-03 Roger Sayle <roger@eyesopen.com>
+
+ * expr.c (emit_move_insn_1): Use emit_move_insn to move the parts
+ of a complex number rather than invoke mov_optab directly.
+
+2003-06-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (simplify_set): Don't move a subreg in SET_SRC to
+ SET_DEST if WORD_REGISTER_OPERATIONS is not defined.
+
+2003-06-03 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/i386/x86-64.h: Remove two target-independent comments;
+ replace "GNU CC" with "GCC".
+
+2003-06-03 Anthony Green <green@redhat.com>
+
+ * config/frv/t-frv (EXTRA_HEADERS): Remove media.h
+
+2003-06-03 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def (BUILT_IN_CABS, BUILT_IN_CABSF, BUILT_IN_CABSL):
+ New builtins representing ISO C99's cabs, cabsf and cabsl.
+ * builtins.c (expand_builtin_fabs): New function.
+ (expand_builtin_cabs): New function.
+ (expand_builtin): Expand BUILT_IN_FABS{,F,L} and BUILT_IN_CABS{,F,L}
+ using expand_builtin_fabs and expand_builtin_cabs respectively.
+
+ * doc/extend.texi: Document new cabs, cabsf and cabsl builtins.
+
+2003-06-03 Aldy Hernandez <aldyh@redhat.com>
+
+ * function.c (assign_parms): Split complex arguments.
+
+ * doc/tm.texi (SPLIT_COMPLEX_ARGS): Document.
+
+ * expr.h (SPLIT_COMPLEX_ARGS): Define.
+ (split_complex_types): Protoize.
+ (split_complex_values): Protoize.
+
+ * calls.c (expand_call): Split complex arguments on architectures
+ that require it.
+ (split_complex_values): New.
+ (split_complex_types): New.
+
+ * config/rs6000/rs6000.c (rs6000_libcall_value): New.
+ (rs6000_function_value): Handle complex values on AIX.
+ (rs6000_complex_function_value): New.
+
+ * config/rs6000/rs6000-protos.h (rs6000_libcall_value): Protoize.
+
+ * config/rs6000/rs6000.h (LIBCALL_VALUE): Call function.
+ (SPLIT_COMPLEX_ARGS): New.
+
+2003-06-03 Jakub Jelinek <jakub@redhat.com>
+
+ * configure.in (HAVE_LD_PIE): Check for ld -pie.
+ * config.in: Rebuilt.
+ * configure: Rebuilt.
+ * toplev.c (flag_pie, flag_shlib): New variables.
+ (f_options): Add -fpie and -fPIE.
+ (parse_options_and_default_flags): Set flag_pic if -fpie/-fPIE.
+ Set flag_shlib if flag_pic and not -fpie/-fPIE.
+ * flags.h (flag_pic, flag_shlib): Add.
+ * varasm.c (default_binds_local_p): Use flag_shlib instead of
+ flag_pic.
+ * gcc.c (LINK_PIE_SPEC): Define.
+ (LINK_COMMAND_SPEC): Use LINK_PIE_SPEC.
+ (option_map): Add --pie -> -pie mapping.
+ * config/sol2.h (ASM_SPEC): Handle -fpie the same way as -fpic
+ and -fPIE the same way as -fPIC.
+ * config/openbsd.h (ASM_SPEC): Likewise.
+ * config/frv/frv.h (ASM_SPEC): Likewise.
+ * config/arm/linux-gas.h (SUBTARGET_CPP_SPEC): Likewise.
+ * config/arm/semi.h (ASM_SPEC): Likewise.
+ * config/arm/netbsd-elf.h (SUBTARGET_EXTRA_ASM_SPEC): Likewise.
+ * config/freebsd-spec.h (FBSD_CPP_SPEC): Likewise.
+ * config/i386/beos-elf.h (CC1_SPEC): Likewise.
+ * config/i386/freebsd-aout.h (ASM_SPEC): Likewise.
+ * config/m68k/linux.h (CPP_SPEC): Likewise.
+ * config/m68k/netbsd.h (ASM_SPEC): Likewise.
+ * config/m68k/openbsd.h (ASM_SPEC): Likewise.
+ * config/m68k/netbsd-elf.h (ASM_SPEC): Likewise.
+ * config/mips/linux.h (SUBTARGET_CPP_SPEC): Likewise.
+ * config/mips/openbsd.h (SUBTARGET_ASM_SPEC): Likewise.
+ * config/pa/pa-linux.h (CPP_SPEC): Likewise.
+ * config/netbsd-aout.h (ASM_SPEC): Likewise.
+ * config/rs6000/sysv4.h (ASM_SPEC, CPP_SYSV_SPEC): Likewise.
+ * config/rs6000/vxworks.h (CPP_SPEC): Likewise.
+ * config/sparc/linux.h (CPP_SUBTARGET_SPEC, ASM_SPEC): Likewise.
+ * config/sparc/linux64.h (CPP_SUBTARGET_SPEC, ASM_SPEC): Likewise.
+ * config/sparc/sparc.h (ASM_SPEC): Likewise.
+ * config/sparc/sp64-elf.h (ASM_SPEC): Likewise.
+ * config/sparc/sysv4.h (ASM_SPEC): Likewise.
+ * config/sparc/netbsd-elf.h (ASM_SPEC): Likewise.
+ * config/sparc/openbsd64.h (ASM_SPEC): Likewise.
+ * config/cris/linux.h (CRIS_ASM_SUBTARGET_SPEC): Likewise.
+ * config/linux.h (STARTFILE_SPEC, ENDFILE_SPEC): Handle -pie.
+ Simplify.
+ * config/alpha/elf.h (STARTFILE_SPEC, ENDFILE_SPEC): Likewise.
+ * config/i386/linux64.h (STARTFILE_SPEC, ENDFILE_SPEC): Likewise.
+ * config/ia64/linux.h (STARTFILE_SPEC, ENDFILE_SPEC): Likewise.
+ * config/rs6000/sysv4.h (STARTFILE_SPEC, ENDFILE_SPEC): Likewise.
+ * config/rs6000/linux64.h (STARTFILE_SPEC, ENDFILE_SPEC): Likewise.
+ * config/sparc/linux.h (STARTFILE_SPEC, ENDFILE_SPEC): Likewise.
+ * config/sparc/linux64.h (STARTFILE_SPEC, ENDFILE_SPEC): Likewise.
+ * doc/invoke.texi: Document -pie, -fpie and -fPIE options.
+
+2003-06-03 Jakub Jelinek <jakub@redhat.com>
+
+ * builtins.c (expand_builtin_memcpy): Remove endp argument and endp
+ != 0 handling. Pass 0 to store_by_pieces.
+ (expand_builtin_mempcpy): Add endp argument. Don't call
+ expand_builtin_memcpy, call store_by_pieces resp. move_by_pieces
+ directly. If ignoring result, only do expand_call.
+ (expand_builtin_stpcpy): Likewise. Call expand_builtin_mempcpy
+ otherwise.
+ (expand_builtin_strncpy, expand_builtin_memset): Adjust
+ store_by_pices callers.
+ (expand_builtin): Adjust expand_builtin_memcpy and
+ expand_builtin_mempcpy callers.
+ * expr.c (can_move_by_pieces): New function.
+ (move_by_pieces): Add endp argument, return to resp. memory at end
+ or one byte earlier depending on endp.
+ (store_by_pieces): Likewise.
+ (emit_block_move): Adjust call to move_by_pieces.
+ (emit_push_insn): Adjust move_by_pieces caller.
+ * expr.h (can_move_by_pieces): New prototype.
+ (store_by_pieces): Adjust prototypes.
+ * rtl.h (move_by_pieces): Adjust prototype.
+ * config/mips/mips.c (expand_block_move): Adjust move_by_pieces
+ caller.
+
+2003-06-03 Ben Elliston <bje@wasabisystems.com>
+
+ * doc/md.texi (Processor pipeline description): Improve wording.
+
+2003-06-03 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (c_common_handle_option): New, pulled out of
+ c_common_decode_option. Substitute uses of argv.
+ (c_common_decode_option): Broken into two.
+
+2003-06-02 Roger Sayle <roger@eyesopen.com>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * emit-rtl.c (gen_complex_constant_part): Remove unnecessary
+ test of TREE_CONSTANT_POOL_ADDRESS_P.
+
+2003-06-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mips.c: Don't include output.h twice.
+ * stormy16.c: Likewise.
+ * xtensa.c: Likewise.
+ * output.h: Protect against multiple inclusion.
+
+2003-06-02 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (OLD_ARG_MODE): New macro.
+ (FUNCTION_ARG_ADVANCE, FUNCTION_ARG_PASS_BY_REFERENCE): Use it.
+ (FUNCTION_ARG_1): Break out of:
+ (FUNCTION_ARG). Use OLD_ARG_MODE.
+
+2003-06-02 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
+
+ * gcc/config.gcc Add support multilib parts for m32rx processor.
+
+2003-06-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (c-options.c): Pass in $(AWK) to opts.sh.
+ (mostlyclean): Delete c-options.c and c-options.h.
+
+2003-06-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (CL_REJECT_NEGATIVE): New.
+ (c_common_decode_option): Update to use it.
+ * c.opt: Update documentation; use RejectNegative.
+ * opts.sh: Handle RejectNegative.
+
+2003-06-01 Zack Weinberg <zack@codesourcery.com>
+
+ * ggc-page.c (init_ggc): Give better diagnostics on failure to
+ open /dev/zero.
+ * toplev.c (crash_signal): Reset handling for received signal
+ to SIG_DFL.
+
+2003-06-02 Ben Elliston <bje@wasabisystems.com>
+
+ * config/arm/arm.c (arm_use_dfa_pipeline_interface): Declare.
+ (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE): Define if not already.
+ (arm_use_dfa_pipeline_interface): Implement.
+ * config/arm/arm.md (arm): New automaton.
+ (write_buf): Remove function units; new cpu unit.
+ (write_blockage): Remove function units; new cpu unit.
+ (core): Remove function units; new cpu unit.
+ (r_mem_f_wbuf): New instruction reservation.
+ (store1_wbuf, store2_wbuf, store3_wbuf, store4_wbuf): Likewise.
+ (store1_ldsched, store2, store3, store4): Likewise.
+ (load_ldsched, load_ldsched_xscale, load_or_store): Likewise.
+ (mult, mult_ldsched, mult_ldsched_strongarm): Likewise.
+ (multi_cycle, single_cycle): Likewise.
+ * config/arm/fpa.md (armfp): New automaton.
+ (fpa): Remove function units; new cpu unit.
+ (fpa_mem): Remove function unit; new cpu unit.
+ (fdivx, fdivd, fdivs, fmul, ffmul, farith, ffarith): New reservations.
+ (r_2_f, f_2_r, f_load, f_store, r_mem_f, f_mem_r): Likewise.
+
+2003-06-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-attrs.def (ATTR_ASM_FPRINTF): New.
+ * c-format.c (enum format_type): Add asm_fprintf_format_type.
+ (NOARGUMENTS, asm_fprintf_length_specs, asm_fprintf_flag_specs,
+ asm_fprintf_flag_pairs, asm_fprintf_char_table): New.
+ (format_types_orig): Renamed from format_types. Add new data.
+ (format_types): Declare as pointer.
+ (handle_format_attribute): Move later in file so we have all
+ necessary declarations. Add section to capture HOST_WIDE_INT.
+ * output.h (ATTRIBUTE_ASM_FPRINTF, __gcc_host_wide_int__): New.
+ (asm_fprintf): Mark with ATTRIBUTE_ASM_FPRINTF.
+
+2003-06-01 Andreas Jaeger <aj@suse.de>
+
+ * doc/tm.texi (Storage Layout): Remove ROUND_TYPE_SIZE and
+ ROUND_TYPE_SIZE_UNIT.
+
+ * stor-layout.c (finalize_record_size): Remove usages of
+ ROUND_TYPE_SIZE and ROUND_TYPE_SIZE_UNIT.
+ (finalize_type_size): Likewise.
+ (layout_type): Likewise.
+
+ * system.h: Poison ROUND_TYPE_SIZE and ROUND_TYPE_SIZE_UNIT.
+
+ * loop.c (check_insn_for_givs): Remove DONT_REDUCE_ADDR macro.
+
+ * config/d30v/d30v.h: Remove text copied from the manual.
+
+2003-06-01 Roger Sayle <roger@eyesopen.com>
+ John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+ Geoffrey Keating <geoffk@apple.com>
+
+ * emit-rtl.c (gen_lowpart_common): Handle interpreting integer
+ constants as condition code values.
+
+2003-06-01 DJ Delorie <dj@redhat.com>
+
+ * cppmacro.c (warn_of_redefinition): Handle cases where the two
+ definitions have different numbers of tokens.
+
+2003-06-01 Andreas Jaeger <aj@suse.de>
+
+ * gen-protos.c (main): Readd unused attribute for argc.
+
+2003-06-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in (c-options.c, c-options.h): Parallel make safe.
+ * c.opt: End in blank line.
+ * opts.sh: Take AWK from environment if available; use C locale.
+
+2003-06-01 Andreas Schwab <schwab@suse.de>
+
+ * config/m68k/linux.h: Remove code protected by USE_GNULIBC_1.
+
+2003-06-01 Andreas Jaeger <aj@suse.de>
+
+ * gen-protos.c (main): Revert patch to check for argument.
+
+2003-06-01 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/11044
+ * config/i386/i386.md (length attribute): Set length to 4
+ for instructions of type "fcmp".
+
+2003-06-01 Andreas Jaeger <aj@suse.de>
+
+ * toplev.c: Use ISO C90 prototypes.
+
+ * toplev.h: Use ISO C90 prototypes.
+
+ * genrecog.c: Use ISO C90 prototypes.
+ (nodes_identical): Correct declaration to match prototype.
+ (maybe_both_true): Likewise.
+ (merge_trees): Likewise.
+
+ * genpeep.c (gen_peephole): Remove #if 0 code.
+ Use ISO C90 prototypes.
+
+ * genattrtab.c (copy_rtx_unchanging): Remove #if 0'ed code.
+ Remove #if 0'ed function simplify_by_alternatives.
+ (optimize_attrs): Remove #if 0'ed code.
+ Remove ^L.
+ Use ISO C90 prototypes.
+ (make_canonical): Remove #if 0'ed code.
+ (convert_const_symbol_ref): Remove #if 0'ed function.
+
+ * gen-protos.c (main): Check for argument.
+
+ * rtl.h: Use ISO C90 prototypes for functions from lists.c.
+
+ * params.h: Use ISO C90 prototypes.
+ * params.c: Likewise.
+ * intl.c: Likewise.
+ * intl.h: Likewise.
+ * lists.c: Likewise.
+ * errors.c: Likewise.
+ * errors.h: Likewise.
+ * gencodes.c: Likewise.
+ * genpreds.c: Likewise.
+ * genattr.c: Likewise.
+ * gen-protos.c: Likewise.
+ * genflags.c: Likewise
+ * genconditions.c: Likewise.
+ * genautomata.c: Likewise.
+ * gencheck.c: Likewise.
+ * genconfig.c: Likewise.
+ * genconstants.c: Likewise.
+ * genemit.c: Likewise.
+ * genextract.c: Likewise.
+ * gengenrtl.c: Likewise.
+ * gengtype.c: Likewise.
+ * gengtype.h: Likewise.
+ * genopinit.c: Likewise.
+ * genoutput.c: Likewise.
+ * gensupport.c: Likewise.
+ * gensupport.h: Likewise.
+
+ * sdbout.h: Use ISO C90 prototypes.
+
+ * sdbout.c (CONTIN): Removed empty macro.
+ (sdbout_one_type): Remove CONTIN usages.
+ Remove ^Ls.
+ (tag_of_ru_type): Remove #if 0'ed function.
+ (sdbout_symbol): Remove #if 0'ed code.
+ (sdbout_one_type): Remove a #if 1.
+ (sdbout_one_type): Remove #if 0'ed code.
+ (sdbout_init): Remove RMS_QUICK_HACK_1 code.
+ Remove PARAMS, use ISO C90 prototypes for all functions.
+
+2003-06-01 Josef Zlomek <zlomekj@suse.cz>
+
+ * rtl.def (CONST_DOUBLE): Update comment.
+
+2003-06-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * opts.sh: Remove path from sort.
+
+2003-06-01 Aldy Hernandez <aldyh@redhat.com>
+
+ PR/9680
+ * config/rs6000/rs6000.h (CANNOT_CHANGE_MODE_CLASS): Require
+ TARGET_SPE for SPE_VECTOR_MODE.
+
+2003-05-31 Aldy Hernandez <aldyh@redhat.com>
+
+ * toplev.c (botch): Remove.
+ (do_abort): Remove.
+ (set_Wunused): Comment.
+ (set_Wextra): Comment.
+ Remove ^L's.
+ (rest_of_compilation): Factor out common code into functions.
+ (rest_of_handle_inlining): New.
+ (rest_of_handle_ssa): New.
+ (rest_of_handle_cse): New.
+ (rest_of_handle_gcse): New.
+ (rest_of_handle_loop_optimize): New.
+ (rest_of_handle_jump_bypass): New.
+ (rest_of_handle_sibling_calls): New.
+ (rest_of_handle_null_pointer): New.
+ (rest_of_handle_addresof): New.
+ (rest_of_handle_flow): New.
+ (rest_of_handle_branch_prob): New.
+ (rest_of_handle_if_conversion): New.
+ (rest_of_handle_tracer): New.
+ (rest_of_handle_loop2): New.
+ (rest_of_handle_cse2): New.
+ (rest_of_handle_life): New.
+ (rest_of_handle_combine): New.
+ (rest_of_handle_if_after_combine): New.
+ (rest_of_handle_regmove): New.
+ (rest_of_handle_sched): New.
+ (rest_of_handle_old_regalloc): New.
+ (rest_of_handle_new_regalloc): New.
+ (rest_of_handle_regrename): New.
+ (rest_of_handle_reorder_blocks): New.
+ (rest_of_handle_sched2): New.
+ (rest_of_handle_new_regalloc): New.
+ (rest_of_handle_old_regalloc): New.
+ (rest_of_handle_regrename): New.
+ (rest_of_handle_reorder_blocks): New.
+ (rest_of_handle_stack_regs): New.
+ (rest_of_handle_machine_reorg): New.
+ (rest_of_handle_delay_slots): New.
+ (rest_of_handle_final): New.
+
+ * toplev.h (botch): Remove prototype.
+ (do_abort): Same.
+
+2003-05-31 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in (c-opts.o, c-options.h): Update dependencies.
+ * c-opts.c: Include c-options.h and c-options.c.
+ (CL_C_ONLY, CL_OBJC_ONLY, CL_CXX_ONLY, CL_OBJCXX_ONLY):
+ Rename CL_C, CL_OBJC, CL_CXX, CL_OBJCXX.
+ (CL_ARG, CL_ALL, COMMAND_LINE_OPTIONS, struct cl_option,
+ OPT, opt_comp): Remove.
+ (missing_arg, c_common_init_options, c_common_decode_option,
+ write_langs): Update for macro redefinitions and enumeration
+ name changes.
+ * c.opt, opts.sh: New files.
+ * doc/passes.texi: Update.
+
+2003-05-31 Andreas Jaeger <aj@suse.de>
+
+ * function.c (trampoline_address): Remove ALLOCATE_TRAMPOLINE
+ usage.
+
+ * doc/tm.texi (Trampolines): Remove ALLOCATE_TRAMPOLINE.
+
+ * config/d30v/d30v.h: Remove traces of ALLOCATE_TRAMPOLINE.
+
+ * system.h: Poison ALLOCATE_TRAMPOLINE.
+
+ * doc/tm.texi (Misc): Remove HANDLE_PRAGMA.
+ * system.h: Poison HANDLE_PRAGMA.
+
+2003-05-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Update dump file names.
+
+2003-05-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-format.c (format_length_info, format_char_info,
+ format_flag_spec, format_flag_pair, format_kind_info):
+ De-const-ify structure members.
+
+2003-05-31 Roger Sayle <roger@eyesopen.com>
+
+ * flags.h (flag_wrapv): New flag controlling overflow semantics.
+ * toplev.c (flag_wrapv): Declare the variable with default false.
+ (lang_independent_options): New option "-fwrapv" to set the above.
+
+ * fold-const.c (extract_muldiv_1): Disable optimization of (2*x)/2
+ as x, when signed arithmetic overflow wraps around.
+ (fold): Optimize "-A - B" as "-B - A" if overflow wraps around.
+ * loop.c (basic_induction_var): Ignore BIVs that rely on undefined
+ overflow when flag_wrapv is true.
+
+ * doc/invoke.texi: Document new -fwrapv command line option.
+ * doc/c-tree.texi: Mention that the overflow semantics of
+ NEGATE_EXPR, PLUS_EXPR, MINUS_EXPR and MULT_EXPR is dependent
+ upon both flag_wrapv and flag_trapv.
+
+2003-05-31 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/install.texi (mips-sgi-irix5): Add missing
+ HTML <hr> marker.
+
+2003-05-31 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/md.texi (Machine Constraints): Document
+ missing SPARC constraints.
+
+2003-05-31 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/md.texi (Automaton pipeline description): Use
+ "type" instead of "cpu" as the attribute in the examples.
+
+2003-05-30 Stan Shebs <shebs@apple.com>
+
+ * system.h: Poison OBJC_PROLOGUE.
+
+2003-05-30 Roger Sayle <roger@eyesopen.com>
+
+ * emit-rtl.c (gen_complex_constant_part): New function for getting
+ the constant real or imaginary part of a complex constant.
+ (gen_realpart): Use it.
+ (gen_imagpart): Likewise.
+
+2003-05-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Fix typos.
+ * doc/rtl.texi: Likewise.
+
+2003-05-30 Dhananjay Deshpande <dhananjayd@kpitcummins.com>
+
+ * config/h8300/crti.asm: Use .h8300hn and .h8300sn for normal
+ mode.
+ * config/h8300/crtn.asm: Likewise.
+ * config/h8300/lib1funcs.asm: Likewise.
+ * config/h8300/h8300.c (asm_file_start): Likewise.
+ * config/h8300/elf.h (LINK_SPEC): Use h8300hnelf and
+ h8300snelf emulations for normal mode.
+ * config/h8300/h8300.h (LINK_SPEC): Use h8300hn and h8300sn
+ emulations for normal mode.
+
+2003-05-30 Dhananjay Deshpande <dhananjayd@kpitcummins.com>
+
+ * config/h8300/h8300.c (h8300_tiny_constant_address_p): Return
+ true if TARGET_NORMAL_MODE.
+
+2003-05-30 Roger Sayle <roger@eyesopen.com>
+
+ * cse.c (cse_insn): Simplify REG_EQUAL note on libcalls when
+ making a substitution.
+ (dead_libcall_p): If directly replacing a libcall with a
+ constant value produces an invalid instruction, also try forcing
+ the constant into the constant pool.
+ * expr.c (emit_move_insn): Add a REG_EQUAL note when it is not
+ obvious that the source is a constant.
+ (compress_float_constant): Use set_unique_reg_note to place
+ REG_EQUAL notes on instructions.
+
+2003-05-30 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.c (extern_list): Add GTY marker.
+ (extern_head): Separate out definition. Add marker.
+ (mips_output_external): Use ggc_alloc for extern_list
+ allocation.
+ (mips_output_external_libcall): Ditto.
+
+2003-05-30 Florian Weimer <fw@deneb.enyo.de>
+
+ * doc/install.texi: Ada-enabled bootstrap requires GNAT 3.14 or
+ later.
+
+2003-05-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * vax.h (ASM_GENERATE_INTERNAL_LABEL): Fix format specifier
+ warnings.
+ (PRINT_OPERAND): Likewise.
+
+2003-05-30 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/mips.h (SUBTARGET_ASM_DEBUGGING_SPEC): Move
+ -mdebug/-no-mdebug switches ...
+ (MDEBUG_ASM_SPEC): ... here.
+ Use only with gas.
+ (EXTRA_SPECS): Initialize mdebug_asm_spec.
+
+2003-05-29 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * gthr-gnat.c: Remove #undef UNUSED.
+ (__gnat_default_lock, __gnat_default_unlock): Prototype.
+ (__gnat_task_lock, __gnat_task_unlock): Make declarations
+ prototypes.
+ (__gnat_install_locks): Convert declaration to ISO C90, make
+ parameter declarations prototypes, and remove blank line.
+ * gthr-gnat.h (__gnat_install_locks): Make parameter
+ declarations prototypes.
+
+2003-05-29 Jason Merrill <jason@redhat.com>
+
+ * Makefile.in (unstrap): Remove stage_last after make unstage1.
+
+2003-05-29 Roger Sayle <roger@eyesopen.com>
+
+ * mips-tfile.c (PAGE_SIZE): Increase page size to 32K.
+
+2003-05-29 Roger Sayle <roger@eyesopen.com>
+ Kaveh Ghazi <ghazi@caip.rutgers.edu>
+
+ PR bootstrap/10169
+ * mips-tfile.c (main): Use getopt_long instead of getopt.
+ Add new command line option --version to display version.
+ Treat --verbose like -v to report a single line version.
+ (options): New global variable for getopt_long.
+ * mips-tdump.c (main): Use getopt_long instead of getopt.
+ New command line options -v, --version and -verbose to display
+ the program version number (to match mips-tfile's behavior).
+ (options): New global variable for getopt_long.
+
+ * gcov.c (options): Zero-terminate getopt_long array.
+ * gcov-dump.c (options): Likewise.
+
+ * Makefile.in (mips-tdump.o): Add dependency on version.h.
+
+2003-05-29 Stan Shebs <shebs@apple.com>
+
+ Remove OBJC_PROLOGUE everywhere.
+ * objc/objc-act.c (finish_objc): Remove use of OBJC_PROLOGUE.
+ * config/avr/avr.h: Remove no-op ref to OBJC_PROLOGUE.
+ * config/d30v/d30v.h: Similarly.
+ * config/ip2k/ip2k.h: Similarly.
+ * doc/tm.texi: Remove doc of OBJC_PROLOGUE.
+
+2003-05-29 Roger Sayle <roger@eyesopen.com>
+
+ * c-semantics.c (genrtl_do_stmt_1): New function split out from...
+ (gen_rtl_do_stmt): ... here. Call genrtl_do_stmt_1.
+ (expand_unreachable_stmt): Expand unreachable while statements
+ using genrtl_do_stmt_1.
+
+2003-05-29 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_output_load_label): Declare.
+ * config/mips/mips.c (mips_output_load_label): New function.
+ (mips_output_conditional_branch): Use it.
+ * config/mips/mips.md (jump): And here.
+
+2003-05-28 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa-protos.h (smalloffset_double_mem_p): Delete.
+ (xtensa_split_operand_pair): New proto.
+ * config/xtensa/xtensa.c (move_operand): Handle DFmode and DImode.
+ (smalloffset_double_mem_p): Delete.
+ (gen_float_relational, printx, print_operand, xtensa_va_arg):
+ Fix whitespace.
+ (xtensa_split_operand_pair): New.
+ (xtensa_dbx_register_number): Fix formatting.
+ * config/xtensa/xtensa.h (EXTRA_CONSTRAINT): Remove 'S' constraint.
+ * config/xtensa/xtensa.md (movdi, movdf): Force constants to memory
+ instead of splitting them into single-word moves. Remove unnecessary
+ checks for reload_in_progress and reload_completed.
+ (movdi_internal, movdf_internal): Change to post-reload split patterns.
+ Add constraints to allow constant operands.
+ (movsf_internal): Allow CONST_INT operands.
+
+2003-05-27 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config.gcc (i[34567]86-*-mingw32*): Add host makefile
+ fragment i386/x-mingw32.
+ * config/i386/x-mingw32: New file. Make local_includedir
+ relative to EXEC_PREFIX.
+
+2003-05-27 Aaron W. LaFramboise <awlaframboise@aol.com>
+
+ * config/i386/mingw32.h (STANDARD_INCLUDE_DIR): Update.
+ (MD_STARTFILE_PREFIX): Define.
+
+2003-05-27 Denis Chertykov <denisc@overta.ru>
+
+ * cselib.c (cselib_invalidate_regno): Abort if hardreg have a
+ VOIDmode.
+ * cselib.c (cselib_process_insn): Pass reg_raw_mode for hardreg in
+ call of cselib_invalidate_regno.
+
+2003-05-28 Daniel Jacobowitz <drow@mvista.com>
+
+ * config/mips/linux.h (LIB_SPEC): Add missing -lc and correct
+ -lthread to -lpthread.
+
+2003-05-28 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Bruce Korb <bkorb@gnu.org>
+ Arno Klaassen <arno@heho.snv.jussieu.fr>
+
+ * fixinc/inclhack.def: Add missing declaration of getpagesize()
+ to unistd.h on Solaris 2.5.1.
+ Fix prototype of recv() and send() in sys/socket.h on
+ Solaris 2.5.1 and 2.6.
+ * fixinc/tests/base/unistd.h: Add solaris_unistd fix test.
+ * fixinc/tests/base/sys/socket.h: Add solaris_socket test.
+ * fixinc/check.tpl: Use 'diff -c', not 'diff -u'.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-05-27 Jason Merrill <jason@redhat.com>
+
+ * tree.c (expr_first, expr_length): New fns.
+ * tree.h: Declare them.
+
+ * tree.c (iterative_hash_expr): Hash commutative expressions
+ consistently.
+
+2003-05-27 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * tree.h (contains_placeholder_p): Now returns bool.
+ (CONTAINS_PLACEHOLDER_P): New macro.
+ (type_contains_placeholder_p): New function.
+ * tree.c (save_expr): Remove code avoiding folding COMPONENT_REF.
+ (contains_placeholder_p): Now returns bool.
+ Rework to use CONTAINS_PLACEHOLDER_P macro.
+ (type_contains_placeholder_p): New function.
+ * fold-const.c (fold, case COMPONENT_REF): Don't fold if
+ type_contains_placeholder_p.
+ (fold_range_test, fold_mathfn_compare, fold_inf_compare, fold):
+ Use CONTAINS_PLACEHOLDER_P macro.
+ * builtins.c (fold_builtin): Likewise.
+ * calls.c (initialize_argument_information): Likewise.
+ * emit-rtl.c (set_mem_attributes_minus_bitpos): Likewise.
+ * explow.c (expr_size): Likewise.
+ * expr.c (store_constructor, get_inner_reference): Likewise.
+ * function.c (assign_parms): Likewise.
+ * stor-layout.c (variable_size): Likewise.
+
+2003-05-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * diagnostic.h (output_verbatim, verbatim): Remove printf
+ attribute.
+
+2003-05-25 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/contrib.texi (Contributors): Update Kean Johnston.
+
+2003-05-24 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (save_fpregs_{si,di}): Add length attribute.
+
+2003-05-24 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/rs6000/440.md, config/stormy16/stormy16protos.h,
+ config/stormy16/stormy16.c, config/stormy16/stormy16.md:
+ Replace "GNU CC" with "GCC".
+
+2003-05-24 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * builtins.c (expand_builtin_memcpy): Use mode of dest_addr for
+ intermediate computation.
+
+2003-05-23 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.md (clzsi, clzdi): New patterns.
+
+2003-05-23 Geoffrey Keating <geoffk@apple.com>
+
+ * gcc.c (default_compilers): Use -o to specify preprocessor's output
+ file. Make -no-integrated-cpp work when building PCH files.
+ * objc/lang-specs.h: Likewise.
+
+2003-05-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/Makefile.in: Correct description.
+ * fixinc/Makefile.in, fixinc/fixfixes.c, fixinc/fixincl.c,
+ fixinc/fixlib.c, fixinc/fixlib.h, fixinc/fixtests.c,
+ fixinc/genfixes: Replace "GNU CC" with "GCC".
+
+2003-05-23 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def: Define atan, atanf, atanl, tan, tanf and tanl
+ builtin functions (and their __builtin_* variants).
+ * builtins.c (mathfn_built_in): Handle tan{,f,l} and atan{,f,l}.
+ (expand_builtin): Don't expand tan{,f,l} or atan{,f,l} when not
+ optimizing.
+
+ * doc/extend.texi: Document new tan and atan builtins, and
+ their float and long double variants.
+
+2003-05-23 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/sparc/netbsd-elf.h (TARGET_OS_CPP_BUILTINS): Define
+ __sparcv9 in the TARGET_ARCH64 case.
+
+Fri May 23 22:17:32 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_reorg): Calls are also jumps.
+
+2003-05-23 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * cse.c (count_reg_usage): When processing an INSNs REG_EQUAL
+ note containing an EXPR_LIST, process all the arguments.
+
+Fri May 23 21:19:31 CEST 2003 Jan Hubicka <jh@suse.cz>
+ Andreas Jaeger <aj@suse.de>
+
+ * i386.h (TARGET_CPU_CPP_BUILTINS): Define __amd64 and __amd64__;
+ do not use assertion.
+
+2003-05-23 Mike Stump <mrs@apple.com>
+
+ * tlink.c (scan_linker_output): Add support for darwin linker, as it
+ emits unresolved symbols one per line, consuming the entire line.
+
+2003-05-23 Larin Hennessy <larin@science.oregonstate.edu>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * explow.c (allocate_dynamic_stack_space): Remove call to gen_probe.
+ * config/m68k/m68k.c (m68k_output_function_prologue):
+ Remove code under #if NEED_PROBE.
+ * config/m68k/m68k.h: Don't define NEED_PROBE.
+ * config/m68k/m68k.md: Remove "probe" insn.
+ * doc/md.texi: Remove documentation of "probe" pattern.
+
+2003-05-23 Dorit Naishlos <gcchaifa@il.ibm.com>
+
+ * config/rs6000/rs6000.md (save_fpregs_{si,di}): Add branch attribute.
+
+2003-05-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/install.texi: Remove sparc64-*-*. Add sparc64-*-solaris2*.
+ Document sparcv9-*-solaris2* as a synonym for sparc64-*-solaris2*.
+
+2003-05-22 Roger Sayle <roger@eyesopen.com>
+
+ * real.c (real_maxval): New function to return the largest finite
+ value representable in a given mode (i.e. FLT_MAX and DBL_MAX).
+ * real.h (real_maxval): Prototype here.
+ * fold-const.c (fold_inf_compare): Transform comparisons against
+ +-Infinity into comparisons against DBL_MAX (or equivalent).
+
+2003-05-22 Mike Stump <mrs@apple.com>
+
+ * config.gcc (*-*-darwin*): Remove use_collect2=no, as it is the
+ default.
+
+2003-05-22 DJ Delorie <dj@redhat.com>
+
+ * calls.c (expand_call): If the arg block is going to grow
+ downward, we need argblock to point to the top of the block,
+ not the bottom.
+
+2003-05-22 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * c-decl.c (duplicate_decls): Test DECL for ERROR_MARK.
+
+ * expr.c (expand_expr, case CONSTRUCTOR): Put into memory if
+ constant and EXPAND_CONST_ADDRESS, not just EXPAND_INITIALIZER.
+
+2003-05-22 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * m68hc11.c: Don't use the `0' flag for asm_fprintf specifiers.
+ * m68k.c: Likewise.
+ * m68k.h: Likewise.
+
+2003-05-22 Zack Weinberg <zack@codesourcery.com>
+
+ PR other/2873
+ * fixinc/inclhack.def (avoid_wchar_t_type): Add bypass
+ expressions to prevent triggering on recent curses.h,
+ linux/nls.h, or X11/Xlib.h.
+ (stdio_va_list): Add _G_va_list to bypass pattern.
+ (strict_ansi_not): Add bypass pattern for __SCO_VERSION__.
+ * fixinc/fixincl.x: Regenerate.
+
+2003-05-22 Rekha Bhintade <rekhad@kpitcummins.com>
+
+ * gcc/config/sh/sh.h (TARGET_SWITCHES): Display all the target
+ switches when --target-help option is specified.
+
+2003-05-22 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR bootstrap/10805
+ * doc/install.texi (sparc-sun-solaris2.7): Document bootstrap
+ failure with Sun assembler 5.0 Alpha 03/27/98.
+
+2003-05-21 Loren James Rittle <ljrittle@acm.org>
+
+ * config/sparc/freebsd.h (CPP_CPU64_DEFAULT_SPEC): Add -D__sparcv9
+ to match system compiler convention.
+
+2003-05-21 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * gthr-win32.h (__GTHREAD_HIDE_WIN32API): Test for nonzero
+ value, not just if defined.
+ Update copyright year.
+
+2003-05-21 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR target/6428
+ * pa-hpux10.h (LINK_SPEC, LIB_SPEC): Move -L options for profiling
+ directories from LIB_SPEC to LINK_SPEC. Emit warning if `-p' or `-pg'
+ option is used without `-static'.
+ * pa-hpux11.h (LINK_SPEC, LIB_SPEC): Likewise.
+ * pa64-hpux.h (LINK_SPEC, LIB_SPEC): Likewise.
+
+2003-05-21 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.h (MASK_SERIALIZE_VOLATILE,
+ TARGET_SERIALIZE_VOLATILE): Delete.
+ (MASK_CONST16, MASK_ABS, MASK_ADDX): Renumber flag bits.
+ (TARGET_DEFAULT): Remove MASK_SERIALIZE_VOLATILE.
+ (TARGET_SWITCHES): Remove "-mserialize-volatile" and
+ "-mno-serialize-volatile".
+ * config/xtensa/xtensa.c (print_operand): Remove checks of
+ TARGET_SERIALIZE_VOLATILE.
+ * config/xtensa/xtensa.md (*lsiu, *ssiu): Likewise.
+ * doc/invoke.texi (Option Summary, Xtensa Options): Remove
+ "-mserialize-volatile" and "-mno-serialize-volatile" options.
+
+2003-05-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-parse.in (fndef): Set DECL_SOURCE_LINE and FILE earlier.
+ (nested_function): Likewise.
+ (notype_nested_function): Likewise.
+
+2003-05-21 Nick Clifton <nickc@redhat.com>
+
+ * config/stormy16/stormy-abi: Update overflow type for
+ R_XSTORMY16_16 reloc.
+
+2003-05-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-common.h (enum rid): Remove RID_BOUNDED, RID_UNBOUNDED.
+ * c-parse.in (reswords): Remove __bounded__ and __unbounded__.
+ (rid_to_yy): Remove RID_BOUNDED, RID_UNBOUNDED slots.
+ * print-tree.c (print_node): Remove ambient-boundedness.
+ * tree.h (tree_common): Remove bounded_flag.
+ (BOUNDED_INDIRECT_YPE_P, BOUNDED_POINTER_TYPE_P,
+ BOUNDED_REFERENCE_TYPE_P, MAYBE_BOUNDED_INDIRECT_TYPE_P,
+ MAYBE_BOUNDED_POINTER_TYPE_P, MAYBE_BOUNDED_REFERENCE_TYPE_P,
+ TREE_BOUNDED, TYPE_MAIN_VARIANTS_PHYSICALLY_EQUAL_P,
+ TYPE_MAIN_PHYSICAL_VARIANT, TYPE_BOUNDED, TYPE_QUAL_BOUNDED):
+ Remove.
+ (TYPE_QUALS): Remove BOUNDED.
+ (TREE_EXPR_QUALS, TREE_FUNC_QUALS): Remove.
+ (TYPE_BOUNDED_VALUE, TYPE_BOUNDED_BASE, TYPE_BOUNDED_EXTENT,
+ TYPE_BOUNDED_SUBTYPE, TYPE_UNBOUNDED_VARIANT, TYPE_POINTER_DEPTH,
+ TYPE_AMBIENT_BOUNDEDNESS, MAX_POINTER_DEPT,
+ VA_LIST_POINTER_DEPTH): Remove.
+ (struct tree_type): Remove pointer_depth.
+
+2003-05-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-pretty-print.c (pp_c_integer_literal): Use
+ HOST_WIDE_INT_PRINT_DOUBLE_HEX.
+
+2003-05-20 Roger Sayle <roger@eyesopen.com>
+ Kazu Hirata <kazu@cs.umass.edu>
+ Joern Rennecke <joern.rennecke@superh.com>
+
+ * gcse.c (cprop_jump): Make use of REG_EQUAL notes on both
+ setcc and jump, if they exist. If substituted instruction
+ fails to validate, store current effort in a REG_EQUAL note.
+ (cprop_insn): Don't attempt further substitutions if the
+ current instruction has been deleted.
+ (local_cprop_pass): Likewise.
+
+ * jump.c (redirect_jump): Also update REG_EQUAL note, if
+ one is attached to the jump instruction.
+ (invert_jump): Delete REG_EQUAL note on jump, if one exists.
+
+2003-05-21 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c++/9738
+ * config/i386/winnt.c (i386_pe_encode_section_info): Enable
+ even if not first.
+
+2003-05-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * genautomata.c (output_description, output_automaton_units,
+ output_state_arcs): Add missing specifiers.
+
+2003-05-20 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/lib1funcs.asm: Avoid use of .Lfe* in .size directives.
+ (do_abs, do_addx2, do_addx4, do_addx8): New assembler macros.
+ (__mulsi3): Use do_addx* instead of ADDX* instructions. Formatting.
+ (nsau): Rename to do_nsau. Provide alternate version for use when
+ the NSAU instruction is available.
+ (__udivsi3, __divsi3, __umodsi3, __modsi3): Use do_nsau macro.
+ (__divsi3, __modsi3): Use do_abs macro instead of ABS instruction.
+ * config/xtensa/xtensa-config.h: Update comments to match binutils.
+ (XCHAL_HAVE_ABS, XCHAL_HAVE_ADDX): Define.
+ * config/xtensa/xtensa.h (MASK_ABS, MASK_ADDX): Define.
+ (TARGET_ABS, TARGET_ADDX): Define.
+ (TARGET_DEFAULT): Conditionally add MASK_ABS and MASK_ADDX.
+ (TARGET_SWITCHES): Add "abs", "no-abs", "addx", and "no-addx".
+ * config/xtensa/xtensa.md (*addx2, *addx4, *addx8, *subx2, *subx4,
+ *subx8): Set predicate condition to TARGET_ADDX.
+ (abssi2): Set predicate condition to TARGET_ABS.
+ * doc/invoke.texi (Option Summary): Document new "-mabs", "-mno-abs",
+ "-maddx", and "-mno-addx" options.
+ (Xtensa Options): Likewise. Also tag some opcode names with @code.
+
+2003-05-20 Kevin Ryde <user42@zip.com.au>
+ Wolfgang Bangerth <bangerth@dealii.org>
+
+ PR/10355
+ * doc/extend.texi: Put a warning into the documentation
+ of attribute regparm.
+
+2003-05-20 Jason Merrill <jason@redhat.com>
+
+ * tree.c (expr_last): New fn.
+ * tree.h: Declare it.
+ * objc/objc-act (expr_last): Rename to objc_expr_last.
+
+2003-05-20 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (sh_register_move_cost): Add clase for moving between
+ FP registers and MAC registers.
+
+2003-05-19 John David Anglin <dave.anglin@nrc-gnrc.gc.ca>
+
+ * pa/milli64.S ($$mulI): Fix typo.
+
+2003-05-19 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * alias.c (nonlocal_mentioned_p, nonlocal_referenced_p)
+ (nonlocal_set_p): Remove initial blank line.
+ * dwarf2out.c (simple_type_size_in_bits): Likewise.
+ * et-forest.c (et_forest_create): Likewise.
+ * explow.c (stabilize): Likewise.
+ * fix-header.c (write_lbrac): Likewise.
+ * graph.c (start_fct, node_data): Likewise.
+ * jump.c (only_sets_cc0_p, sets_cc0_p): Likewise.
+ * rtlanal.c (global_reg_mentioned_p): Likewise.
+ * tree.c (bit_position): Likewise.
+
+2003-05-19 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mips/linux64.h (LIB_SPEC): Add missing -lc and correct
+ -lthread to -lpthread.
+
+2003-05-19 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (c_common_decode_option): Don't accept dollars
+ as identifier characters in assembly.
+ * doc/cpp.texi: Document this.
+
+2003-05-19 Seth Arnold <sarnold@wirex.com>
+ Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_stack_info): Do not add
+ vrsave_size twice.
+
+2003-05-19 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/tm.texi (function_arg): Fix typo.
+
+2003-05-19 Matt Austern <austern@apple.com>
+
+ * c-opts.c (COMMAND_LINE_OPTIONS): Add -Winvalid-offsetof option.
+ * c-common.h (warn_invalid_offsetof): Declare.
+ * c-common.c (warn_invalid_offsetof): Define.
+ * doc/invoke.texi: Document -Winvalid-offsetof.
+ * testsuite/g++.dg/other/offsetof3.C: New.
+ * testsuite/g++.dg/other/offsetof4.C: New.
+
+2003-05-19 Kevin B. Hendricks <kevin.hendricks@sympatico.ca>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_alignment_string,
+ rs6000_alignment_flags): New variables.
+ (rs6000_parse_alignment_option): New function.
+ (rs6000_override_options): Call it.
+ * config/rs6000/rs6000.h (TARGET_OPTIONS): Add -malign-XXX option.
+ (MASK_ALIGN_POWER, MASK_ALIGN_NATURAL, TARGET_ALIGN_NATURAL): New
+ macros.
+ * config/rs6000/aix.h (ADJUST_FIELD_ALIGN): Always use COMPUTED
+ natural alignment if TARGET_NATURAL_ALIGNMENT
+ (ROUND_TYPE_ALIGN): Always use default record alignment if
+ TAGET_NATURAL_ALIGNMENT.
+ * config/rs6000/darwin.h (ADJUST_FIELD_ALIGN): Same
+ (ROUND_TYPE_ALIGN): Same.
+ * config/rs6000/linux64.h (ADJUST_FIELD_ALIGN): Same
+ (ROUND_TYPE_ALIGN): Same.
+ * doc/invoke.texi (Option Summary, PowerPC Options): Document
+ new options.
+
+2003-05-19 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * c-decl.c (finish_decl): When setting the DECL_ASSEMBLER_NAME
+ of a function using ASMSPEC, prepend a star.
+
+2003-05-19 Jason Merrill <jason@redhat.com>
+
+ * tree-inline.c (copy_body_r): Avoid generating &* during inline
+ substitution.
+
+2003-05-19 Andrew Macleod <amacleod@redhat.com>
+
+ * config/stormy16/stormy16.c (xstormy16_expand_prologue): Do
+ not mark assignments to the hard frame pointer as being stack
+ frame related.
+ (xstormy16_expand_epilogue): Mark adjustments to the stack
+ pointer as being stack frame related.
+
+2003-05-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (ISA_HAS_LOAD_DELAY, ISA_HAS_XFER_DELAY,
+ ISA_HAS_FCMP_DELAY, ISA_HAS_HILO_INTERLOCKS): New macros.
+ (PREDICATE_CODES): Add hilo_operand.
+ * config/mips/mips.c (hilo_operand): New predicate.
+ (mips_adjust_insn_length): Account for the number nops that might
+ be needed to avoid hardware hazards.
+ * config/mips/mips.md (dslot): Remove attribute.
+ (hazard): New attribute.
+ (can_delay): Use it. Check for calls, branches & jumps.
+ (muldi3): Use the standard dmult pattern for mips16 code.
+ (muldi3_internal, muldi3_internal2): Adjust conditions accordingly.
+
+2003-05-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (final_prescan_insn,
+ mips_count_memory_refs, mips_fill_delay_slot): Remove.
+ * config/mips/mips.h (delay_type, dslots_load_total,
+ dslots_load_filled, dslots_jump_total, dslots_jump_filled,
+ dslots_number_nops, num_refs, mips_load_reg, mips_load_reg2,
+ mips_load_reg3, mips_load_reg4): Remove.
+ (MASK_STATS): Remove.
+ (MASK_EXPLICIT_RELOCS): Reuse its value.
+ (TARGET_STATS): Remove.
+ (TARGET_SWITCHES): Turn -mstats and -mno-stats into no-ops.
+ Warn that -mstats is now ignored.
+ (FINAL_PRESCAN_INSN): Undefine.
+ (DBR_OUTPUT_SEQEND): Remove handling of dslot statistics.
+ (ASM_OUTPUT_REG_POP): Likewise.
+ * config/mips/mips.c (dslots_load_total, dslots_load_filled,
+ dslots_jump_total, dslots_jump_filled, dslots_number_nops, num_refs,
+ mips_load_reg, mips_load_reg2, mips_load_reg3, mips_load_reg4,
+ mips_fill_delay_slot, mips_count_memory_refs,
+ final_prescan_insn): Remove.
+ (output_block_move): Remove calls to mips_count_memory_refs.
+ (print_operand): Remove printing of #nop for TARGET_STATS.
+ (mips_output_function_epilogue): Remove TARGET_STATS code.
+ Reorganize setting of fnnmae.
+ * config/mips/mips.md: Remove handling of dslot statistics
+ throughout file. Change all fcmp patterns into normal asm
+ templates, removing calls to mips_fill_delay_slot.
+ * doc/invoke.texi: Remove documentation of -mstats.
+
+2003-05-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_class_max_nregs): Return the number of
+ words in the mode.
+
+2003-05-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (override_options): Disable explicit
+ relocs for old ABIs unless using gas.
+
+2003-05-18 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.h: Remove definition of g_switch_value.
+
+2003-05-18 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * flags.h (g_switch_value): Change to an unsigned
+ HOST_WIDE_INT.
+ * toplev.c (g_switch_value): Likewise.
+
+ * config/alpha/alpha.c (small_symbolic_operand): Remove
+ g_switch_value cast.
+ (alpha_in_small_data_p): Cast size to an unsigned
+ HOST_WIDE_INT.
+
+ * config/frv/frv.c (frv_in_small_data_p): Cast size to an
+ unsigned HOST_WIDE_INT.
+ * config/frv/frv.h (g_switch_value, g_switch_set): Remove.
+ (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Declare g_switch_set.
+
+ * config/m32r/m32r.c (m32r_in_small_data_p): Cast size to an
+ unsigned HOST_WIDE_INT.
+ (m32r_asm_file_start): Use HOST_WIDE_INT_PRINT_UNSIGNED.
+ * config/m32r/m32r.h (g_switch_value, g_switch_set): Remove.
+ (ASM_OUTPUT_ALIGNED_COMMON): Declare g_switch_value.
+
+ * config/rs6000/rs6000.c (rs6000_file_start): Use
+ HOST_WIDE_INT_PRINT_UNSIGNED.
+ (small_data_operand): Cast summand to unsigned HOST_WIDE_INT.
+ (rs6000_elf_in_small_data_p): Cast size to unsigned
+ HOST_WIDE_INT.
+ * config/rs6000/sysv4.h (g_switch_value, g_switch_set):
+ Remove.
+ (SUBTARGET_OVERRIDE_OPTIONS): Declare g_switch_value and
+ g_switch_set.
+ (ASM_OUTPUT_ALIGNED_LOCAL): Declare g_switch_value and remove
+ g_switch_value cast.
+
+2003-05-18 Roger Sayle <roger@eyesopen.com>
+ Zack Weinberg <zack@codesourcery.com>
+
+ PR middle-end/10472
+ * builtins.c (expand_builtin_memcpy): Call force_operand on
+ expressions and use simplify_gen_binary to create the addition.
+
+2003-05-18 Andreas Schwab <schwab@suse.de>
+
+ * config/m68k/m68k.md: Use define_constants for unspec numbers.
+
+2003-05-18 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/sparc/sparc.h: Define sparc for now.
+
+2003-05-18 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Clear xm_file, md_file at the beginning of each pass.
+
+ * config/stormy16/stormy16.h: Remove about 3000 lines of
+ target-independent comments. Update copyright notice.
+
+ * doc/collect2.texi: GNU CC -> GCC.
+ * doc/headerdirs.texi: GNU CC -> GCC.
+
+2003-05-18 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * hashtable.h (struct ht_identifier): Add data member "hash_value".
+ * hashtable.c (ht_lookup): Use it when searching, remember.
+ (ht_expand): Do not recompute.
+ * tree.h (IDENTIFIER_HASH_VALUE): New macro.
+
+2003-05-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov-io.c (gcov_read_bytes): Fix fread thinko.
+
+2003-05-18 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-cppbuiltin.c (TARGET_OS_CPP_BUILTINS, TARGET_OBJFMT_CPP_BUILTINS):
+ Default here.
+ (c_cpp_builtins): Invoke TARGET_OBJFMT_CPP_BUILTINS().
+ * defaults.h: Don't default TARGET_OS_CPP_BUILTINS here.
+ * config/elfos.h (TARGET_OBJFMT_CPP_BUILTINS): Define __ELF__.
+ * config/freebsd-spec.h, config/netbsd-elf.h, config/alpha/gnu.h,
+ config/arm/linux-elf.h, config/arm/rtems-elf.h,
+ config/arm/unknown-elf.h, config/cris/cris.h, config/cris/linux.h,
+ config/h8300/elf.h, config/i370/linux.h, config/i386/beos-elf.h,
+ config/i386/gnu.h, config/i386/linux.h, config/i386/linux64.h,
+ config/i386/moss.h, config/i386/rtemself.h, config/ia64/ia64.h,
+ config/m68k/rtemself.h, config/mcore/mcore-elf.h, config/mips/linux.h,
+ config/pa/pa-linux.h, config/rs6000/linux.h, config/rs6000/linux64.h,
+ config/rs6000/sysv4.h, config/rs6000/vxworks.h, config/s390/linux.h,
+ config/sh/coff.h, config/sh/elf.h, config/sh/rtemself.h,
+ config/sh/sh.h, config/sparc/linux.h, config/sparc/linux64.h,
+ config/sparc/openbsd64.h, config/sparc/sp64-elf.h,
+ config/sparc/sp86x-elf.h, config/xtensa/elf.h, config/xtensa/linux.h:
+ Don't define __ELF__.
+ * config/alpha.h, config/m68k/linux.h (TARGET_OBJFMT_CPP_BUILTINS):
+ Define __ELF__.
+ * doc/cpp.texi: Document __ELF__.
+ * doc/tm.texi: Document TARGET_OBJFMT_CPP_BUILTINS. *
+
+2003-05-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (validate_arglist): Eliminate libiberty VA_ macros,
+ always use stdarg.
+ * c-errors.c (pedwarn_c99): Likewise.
+ * c-format.c (status_warning): Likewise.
+ * c-semantics.c (build_stmt): Likewise.
+ * calls.c (emit_library_call, emit_library_call_value): Likewise.
+ * collect2.c (notice, fatal_perror, fatal, error): Likewise.
+ * cpperror.c (cpp_error, cpp_error_with_line): Likewise.
+ * diagnostic.c (build_message_string, output_printf,
+ output_verbatim, verbatim, inform, warning, pedwarn, error, sorry,
+ fatal_error, internal_error, warning_with_decl, pedwarn_with_decl,
+ error_with_decl, fnotice): Likewise.
+ * dwarf2asm.c (dw2_asm_output_data, dw2_asm_output_delta,
+ dw2_asm_output_offset, dw2_asm_output_pcrel, dw2_asm_output_addr,
+ dw2_asm_output_addr_rtx, dw2_asm_output_nstring,
+ dw2_asm_output_data_uleb128, dw2_asm_output_data_sleb128,
+ dw2_asm_output_delta_uleb128, dw2_asm_output_delta_sleb128,
+ dw2_asm_output_encoded_addr_rtx): Likewise.
+ * emit-rtl.c (gen_rtx, gen_rtvec): Likewise.
+ * errors.c (warning, error, fatal, internal_error): Likewise.
+ * final.c (output_operand_lossage, asm_fprintf): Likewise.
+ * fix-header.c (fatal): Likewise.
+ * gcc.c (fatal, error, notice): Likewise.
+ * gcov.c (fnotice): Likewise.
+ * genattrtab.c (attr_rtx, attr_printf): Likewise.
+ * gengtype.c (error_at_line, xasprintf, oprintf): Likewise.
+ * gensupport.c (message_with_line): Likewise.
+ * mips-tfile.c (fatal, error): Likewise.
+ * protoize.c (notice): Likewise.
+ * ra-debug.c (ra_debug_msg): Likewise.
+ * read-rtl.c (fatal_with_file_and_line): Likewise.
+ * rtl-error.c (error_for_asm, warning_for_asm): Likewise.
+ * tree.c (build, build_nt, build_function_type_list): Likewise.
+
+2003-05-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * defaults.h (TARGET_CPU_CPP_BUILTINS, CPP_PREDEFINES): Remove.
+ * gcc.c (cpp_predefines): Remove.
+ (cpp_unique_options, do_spec_1): Remove handling of CPP_PREDEFINES.
+ (static_specs): Remove predefines.
+ * system.h: Poison CPP_PREDEFINES.
+ * config/freebsd.h, config/openbsd.h, config/ptx4.h, config/svr3.h,
+ config/svr4.h, doc/tm.texi: Remove references to CPP_PREDEFINES.
+
+2003-05-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/m68k/hp320.h, config/m68k/linux.h, config/m68k/m68k-none.h,
+ config/m68k/m68k.h, config/m68k/m68kemb.h, config/m68k/m68kv4.h,
+ config/m68k/openbsd.h, config/m68k/rtemself.h: Remove CPP_PREDEFINES,
+ use TARGET_OS_CPP_BUILTINS and TARGET_CPU_CPP_BUILTINS instead.
+
+2003-05-17 Neil Booth <neil@daikokuya.co.uk>
+
+ PR c/9209
+ * c-common.c, c-common.h (dollars_in_ident): Remove.
+ * c-opts.c (DOLLARS_IN_IDENTIFIERS): Default to true.
+ (c_common_init_options, c_common_decode_option): Set dollars_in_ident.
+ * cpphash.h (warned_dollar): Rename warn_dollars.
+ * cppinit.c (struct lang_flags, lang_defaults, cpp_set_lang)
+ Permit dollars regardless of -std=.
+ (post_options): Set warn_dollars.
+ * cpplex.c (forms_identifier_p): Use warn_dollars.
+ * config/darwin.h, config/alpha/vms.h, config/m68hc11/m68hc11.h:
+ Remove redundant definitions of DOLLARS_IN_IDENTIFIERS.
+ * doc/cpp.texi, doc/cppopts.texi, doc/invoke.texi, doc/tm.texi:
+ Update documentation.
+
+2003-05-17 Andreas Schwab <schwab@suse.de>
+
+ * config/m68k/m68k.c (m68k_output_function_prologue): Use
+ HOST_WIDE_INT_PRINT_DEC for fprintf and %wd for asm_fprintf when
+ formatting a HOST_WIDE_INT.
+ (m68k_output_function_epilogue): Likewise.
+
+2003-05-17 Zack Weinberg <zack@codesourcery.com>
+
+ * doc/install.texi: Remove information about desupported targets.
+
+2003-05-17 Andreas Schwab <schwab@suse.de>
+
+ * config/m68k/coff.h: Remove support for Sun FPA and Sun SKY board.
+ * config/m68k/linux.h: Likewise.
+ * config/m68k/m68k-none.h: Likewise.
+ * config/m68k/netbsd-elf.h: Likewise.
+ * config/m68k/sgs.h: Likewise.
+ * config/m68k/m68k.h: Likewise.
+ * config/m68k/m68k.md: Likewise.
+ * config/m68k/m68k.c: Likewise.
+ * doc/md.texi (Machine Constraints): Remove Sun FPA specific
+ constraints.
+ * doc/invoke.texi (Option Summary): Remove -mfpa.
+ (M680x0 Options): Likewise.
+
+2003-05-17 David Edelsohn <edelsohn@gnu.org>
+
+ * rs6000.c (rs6000_function_value): Simplify REAL_TYPE logic.
+
+2003-05-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/sol2.h: Add TARGET_SUB_OS_CPP_BUILTINS.
+ * config/sparc/liteelf.h, config/sparc/openbsd64.h,
+ config/sparc/rtemself.h, config/sparc/sol2-64.h,
+ config/sparc/sp64-elf.h, config/sparc/sp86x-elf.h:
+ Update for use of TARGET_SUB_OS_CPP_BUILTINS.
+
+2003-05-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * i960/i960.h, i960/rtems.h: Use TARGET_OS_CPP_BUILTINS and
+ TARGET_CPU_CPP_BUILTINS in preference to CPP_PREDEFINES.
+
+2003-05-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * config.gcc (sparc-*-sysv4*): Add sparc/sysv4-only.h.
+ * sparc/aout.h, sparc/elf.h, sparc/freebsd.h, sparc/linux.h,
+ sparc/linux64.h, sparc/lite.h, sparc/litecoff.h, sparc/liteelf.h,
+ sparc/netbsd-elf.h, sparc/openbsd.h, sparc/openbsd64.h,
+ sparc/pbd.h, sparc/rtemself.h, sparc/sol2-64.h, sparc/sol2-bi.h,
+ sparc/sol2.h, sparc/sp64-elf.h, sparc/sp86-elf.h, sparc/sparc.h,
+ sparc/sysv4.h,
+ * sparc/sysv4-only.h: New.
+
+2003-05-17 Alan Modra <amodra@bigpond.net.au>
+
+ * function.c (assign_parms): Check for zero size args.
+
+2003-05-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cfgloopanal.c (test_for_iteration): Use string concatentation on
+ HOST_WIDE_INT_PRINT_* format specifier to collapse multiple
+ function calls into one.
+ * dbxout.c (dbxout_symbol): Likewise.
+ * defaults.h (ASM_OUTPUT_SIZE_DIRECTIVE): Likewise.
+ * dwarf2asm.c (dw2_asm_output_data_uleb128,
+ dw2_asm_output_data_sleb128): Likewise.
+ * genrecog.c (debug_decision_2): Likewise.
+ * loop.c (emit_prefetch_instructions): Likewise.
+ * print-rtl.c (print_rtx): Likewise.
+ * print-tree.c (print_node_brief, print_node): Likewise.
+ * ra-debug.c (dump_igraph, dump_graph_cost,
+ dump_static_insn_cost): Likewise.
+ * ra-rewrite.c (dump_cost): Likewise.
+ * sdbout.c (PUT_SDB_INT_VAL, PUT_SDB_SIZE): Likewise.
+ * sreal.c (dump_sreal): Likewise.
+ * unroll.c (unroll_loop, precondition_loop_p): Likewise.
+ * varasm.c (assemble_vtable_entry): Likewise.
+
+ * avr.c (avr_output_function_prologue,
+ avr_output_function_epilogue, print_operand): Fix format specifier
+ warnings.
+ (init_cumulative_args): Mark parameter with ATTRIBUTE_UNUSED.
+ * avr.h (FUNCTION_VALUE_REGNO_P): Fix signed/unsigned warnings.
+
+2003-05-16 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.c (expand_block_move): Unify the TARGET_STRING
+ and ! TARGET_STRING cases.
+
+ * doc/cppopts.texi (-undef): Fix texinfo warning.
+
+ * doc/cppopts.texi (-H): Document that -H works for PCH files too.
+ * cppfiles.c (validate_pch): When -H is used, print some information
+ about PCH files found.
+
+2003-05-16 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * config/mips/t-elf: Remove obsolete rules adding dependencies on tm.h.
+ * config/mips/t-isa3264, config/mips/t-r3900: Likewise.
+ * config/mips/t-sr71k: Likewise.
+
+2003-05-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * arc.c (arc_output_function_prologue,
+ arc_output_function_epilogue): Fix format specifier warnings.
+ * arc.h (LARGE_INT): Fix signed/unsigned warnings.
+
+ * v850.c (print_operand): Fix format specifier warnings.
+
+ * ns32k.c (ADJSP, ns32k_output_function_prologue): Fix format
+ specifier warnings.
+
+ * mcore.c (mcore_print_operand_address, mcore_print_operand): Fix
+ format specifier warnings.
+
+ * ip2k.c (function_prologue, function_epilogue, print_operand):
+ Fix format specifier warnings.
+ * ip2k.md: Likewise.
+
+ * i960.c (i960_output_function_prologue, i960_print_operand,
+ i960_print_operand_addr): Fix format specifier warnings.
+
+ * i370.c (ascebc, ebcasc): Wrap in macros controlling usage.
+ (i370_output_function_prologue): Fix format specifier warnings.
+ * i370.h (PRINT_OPERAND): Likewise.
+
+ * fr30.c (fr30_print_operand): Fix format specifier warnings.
+
+ * dsp16xx.c (print_operand_address): Fix format specifier warning.
+ * dsp16xx.h (INCLUDE_DEFAULTS): Add missing initializers.
+
+ * c4x.c (c4x_print_operand, c4x_print_operand_address): Fix format
+ specifier warnings.
+
+ * alpha.c (print_operand_address, alpha_start_function,
+ unicosmk_output_ssib): Use string concatentation on
+ HOST_WIDE_INT_PRINT_* format specifier to collapse multiple
+ function calls into one.
+ * arm.c (arm_print_operand): Likewise.
+ * cris.c (cris_asm_output_mi_thunk): Likewise.
+ * frv.c (frv_asm_output_mi_thunk): Likewise.
+ * ia64.c (ia64_print_operand, process_set): Likewise.
+ * m68k.c (m68k_output_function_epilogue, m68k_output_mi_thunk):
+ Likewise.
+ * mips/iris5gas.h (PUT_SDB_SIZE): Likewise.
+ * mips.h (PUT_SDB_INT_VAL, PUT_SDB_SIZE): Likewise.
+ * pa.c (output_div_insn, pa_asm_output_mi_thunk): Likewise.
+ * pa.h (PRINT_OPERAND_ADDRESS): Likewise.
+ * rs6000.c (rs6000_va_start, print_operand_address): Likewise.
+ * s390.c (s390_assemble_integer): Likewise.
+ * sparc.c (sparc_flat_function_prologue,
+ sparc_flat_function_epilogue): Likewise.
+ * stormy16.c (xstormy16_print_operand_address, xstormy16_print_operand): Likewise.
+ * vax.c (vax_output_mi_thunk): Likewise.
+
+ * frv.c (frv_print_operand_memory_reference): Fix format specifier
+ warning.
+ (frv_rtx_costs): Mark parameter with ATTRIBUTE_UNUSED.
+
+ * m68k.c (m68k_output_function_epilogue): Fix format specifier
+ warnings.
+
+ * stormy16-protos.h (xs_hi_general_operand,
+ xs_hi_nonmemory_operand): Prototype.
+ * stormy16.c (xstormy16_output_shift): Fix format specifier
+ warnings.
+
+ * cris.c: Fix format specifier warnings.
+
+2003-05-16 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/lib1funcs.asm: Fix typo: LSM instead of LSYM.
+
+2003-05-16 Wolfgang Bangerth <bangerth@dealii.org>
+
+ * doc/bugreport.texi: Remove most of the of the preface of the
+ bugs section.
+
+2003-05-16 Jakub Jelinek <jakub@redhat.com>
+
+ * config/ia64/unwind-ia64.c (uw_update_reg_address): Handle
+ .save XX, r0.
+
+2003-05-15 Roger Sayle <roger@eyesopen.com>
+
+ * config/alpha/alpha.h (ASM_OUTPUT_SKIP): Fix typo.
+
+2003-05-15 Eric Christopher <echristo@redhat.com>
+
+ * cfgcleanup.c (merge_blocks): Fix return value.
+
+2003-05-15 Eric Christopher <echristo@redhat.com>
+
+ * combine.c (expand_compound_operation): Make sure
+ that zero_extend operation is profitable.
+
+2003-05-15 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/linux.h, config/alpha/linux-elf.h: Remove
+ code protected by USE_GNULIBC_1.
+
+2003-05-15 Zack Weinberg <zack@codesourcery.com>
+
+ * config.gcc: Purge all targets obsoleted in GCC 3.3. Also
+ remove hppa*-*-mpeix* which could not be built, and prune
+ files from tmake_file= or tm_file= lists that don't exist.
+
+ * config/alpha/alpha-interix.h, config/alpha/alpha32.h
+ * config/alpha/t-interix, config/arm/conix-elf.h
+ * config/arm/t-arm-aout, config/arm/t-strongarm-coff
+ * config/arm/unknown-elf-oabi.h, config/i386/win32.h
+ * config/m68k/3b1.h, config/m68k/3b1g.h, config/m68k/amix.h
+ * config/m68k/atari.h, config/m68k/ccur-GAS.h, config/m68k/crds.h
+ * config/m68k/hp2bsd.h, config/m68k/hp3bsd.h
+ * config/m68k/hp3bsd44.h, config/m68k/linux-aout.h
+ * config/m68k/m68k-psos.h, config/m68k/mot3300.h
+ * config/m68k/pbb.h, config/m68k/plexus.h, config/m68k/sun2.h
+ * config/m68k/sun2o4.h, config/m68k/sun3.h, config/m68k/sun3mach.h
+ * config/m68k/sun3n.h, config/m68k/sun3n3.h, config/m68k/sun3o3.h
+ * config/m68k/t-mot3300, config/m68k/t-mot3300-gald
+ * config/m68k/t-mot3300-gas, config/m68k/t-mot3300-gld
+ * config/m68k/tower-as.h, config/m68k/tower.h
+ * config/m88k/aout-dbx.h, config/m88k/m88k-aout.h
+ * config/m88k/m88k-modes.def, config/m88k/m88k-move.sh
+ * config/m88k/m88k-protos.h, config/m88k/m88k.c
+ * config/m88k/m88k.h, config/m88k/m88k.md, config/m88k/openbsd.h
+ * config/m88k/sysv4.h, config/m88k/t-luna, config/m88k/t-luna-gas
+ * config/m88k/t-m88k, config/m88k/t-sysv4, config/mcore/gfloat.h
+ * config/mips/rtems64.h, config/mips/sni-gas.h
+ * config/mips/sni-svr4.h, config/mips/t-ecoff
+ * config/mn10200/lib1funcs.asm, config/mn10200/mn10200-protos.h
+ * config/mn10200/mn10200.c, config/mn10200/mn10200.h
+ * config/mn10200/mn10200.md, config/mn10200/t-mn10200
+ * config/pa/pa-hiux.h, config/pa/pa-hpux7.h, config/pa/pa-hpux9.h
+ * config/pa/pa-oldas.h, config/pa/t-mpeix, config/psos.h
+ * config/romp/romp-protos.h, config/romp/romp.c
+ * config/romp/romp.h, config/romp/romp.md, config/rs6000/aix31.h
+ * config/rs6000/aix3newas.h, config/rs6000/mach.h
+ * config/sparc/bsd.h, config/sparc/hal.h
+ * config/sparc/linux-aout.h, config/sparc/lynx-ng.h
+ * config/sparc/lynx.h, config/sparc/netbsd.h
+ * config/sparc/sp86x-aout.h, config/sparc/splet.h
+ * config/sparc/sun4gas.h, config/sparc/sun4o3.h
+ * config/sparc/sunos4.h, config/sparc/t-chorus-elf
+ * config/sparc/t-halos, config/sparc/t-sparcbare
+ * config/sparc/t-splet, config/sparc/t-sunos41
+ * config/v850/rtems.h: Delete file.
+
+2003-05-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000-protos.h (function_value): Protoize.
+
+ * config/rs6000/rs6000.h (FUNCTION_VALUE): Call function.
+
+ * config/rs6000/rs6000.c (rs6000_function_value): New.
+
+2003-05-15 Philip Blundell <philb@gnu.org>
+
+ * config/arm/arm.c (arm_is_xscale): Rename to arm_arch_xscale.
+ All uses updated.
+ (arm_tune_xscale): New variable.
+ (arm_override_options): Set it.
+ (arm_adjust_cost): Use it in place of arm_arch_xscale.
+ (arm_gen_load_multiple): Likewise.
+ (arm_gen_store_multiple): Likewise.
+ * config/arm/arm.md (is_xscale): Likewise.
+ * config/arm/arm.h (arm_tune_xscale): Declare.
+
+2003-05-15 Philip Blundell <philb@gnu.org>
+
+ PR target/10730
+ * config/arm/arm.c (adjacent_mem_locations): Reject offsets
+ involving invalid constants.
+
+2003-05-15 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (hppa_expand_prologue): Remove blockage.
+
+2003-05-15 Wolfgang Bangerth <bangerth@dealii.org>
+
+ * doc/bugreport.texi: Remove most of the bug reporting
+ instructions and merge them into bugs.html.
+
+2003-05-14 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * config/rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_LOCAL): Cast
+ g_switch_value to unsigned HOST_WIDE_INT.
+
+2003-05-14 Eric Christopher <echristo@redhat.com>
+
+ * combine.c: Fix header comments.
+ (distribute_notes): Remove usage of elim_i1, elim_i2. Propagate
+ to all calls and prototype.
+
+2003-05-14 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/10764
+ * config/i386/i386.md (atan2df3, atan2sf3, atan2xf3, atan2tf3):
+ Add an explicit clobber to show that UNSPEC_FPATAN clobbers st(1).
+ (*fyl2x_sfxf3, *fyl2x_dfxf3, *fyl2x_xf3, *fyl2x_tfxf3): Likewise,
+ add an explicit clobber to show that UNSPEC_FYL2X clobbers st(1).
+ (logsf2, logdf2, logxf2, logtf2): Update expander patterns to match
+ the corresponding *fyl2x_?fxf3 instructions.
+
+2003-05-14 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/lib2funcs.S (TRAMPOLINE_SIZE): Change from 49 to 59.
+ * config/xtensa/xtensa-config.h (XCHAL_HAVE_CONST16,
+ XCHAL_HAVE_L32R): New.
+ * config/xtensa/xtensa-protos.h (non_const_move_operand,
+ xtensa_load_constant, xtensa_function_prologue,
+ xtensa_function_epilogue): Delete prototypes.
+ (xtensa_expand_prologue): New.
+ * config/xtensa/xtensa.c (frame_size_const,
+ TARGET_ASM_FUNCTION_PROLOGUE, TARGET_MACHINE_DEPENDENT_REORG,
+ non_const_move_operand, xtensa_load_constant, xtensa_reorg,
+ xtensa_function_prologue): Delete.
+ (add_operand, xtensa_mem_offset): Formatting.
+ (move_operand): If the const16 option is available, allow any SFmode
+ and SImode constants.
+ (xtensa_emit_move_sequence): Inline the former contents of
+ xtensa_load_constant with modifications to handle the const16 option.
+ (override_options): Add xtensa_char_to_class['W'] and set it to
+ the general register class only if the const16 option is enabled.
+ Fix formatting. Disallow PIC when using the const16 option.
+ (print_operand): Reorganize to switch on "letter" instead of the
+ RTL code. Add output_operand_lossage calls for invalid cases.
+ Add support for 't' and 'b' letters.
+ (xtensa_expand_prologue): New function to replace
+ xtensa_function_prologue and xtensa_reorg.
+ (xtensa_function_epilogue): Declare this as static. Delete code
+ to print the retw.n or retw instruction.
+ (xtensa_return_addr): Use A0_REG instead of 0.
+ (xtensa_rtx_costs): Add costs for using the const16 option.
+ * config/xtensa/xtensa.h (MASK_CONST16, TARGET_CONST16): New.
+ (TARGET_DEFAULT): Add CONST16 if L32R instructions not available.
+ (TARGET_SWITCHES): Add "const16" and "no-const16".
+ (REG_CLASS_FROM_LETTER): Add comment about new 'W' letter.
+ (EXTRA_CONSTRAINT): Change 'T' constraint to only apply when not
+ using the const16 option.
+ (TRAMPOLINE_TEMPLATE): Rewrite to avoid hardwired use of l32r insn.
+ (TRAMPOLINE_SIZE): Change from 49 to 59.
+ (INITIALIZE_TRAMPOLINE): Adjust offsets to match new trampoline.
+ (GO_IF_LEGITIMATE_ADDRESS): Do not allow constant pool addresses
+ when using the const16 option.
+ (PREDICATE_CODES): Delete non_const_move_operand.
+ * config/xtensa/xtensa.md (define_constants): Add A1_REG, A8_REG, and
+ UNSPECV_ENTRY.
+ (movdi, movdf): If the source is a constant, always expand to a
+ sequence of movsi insns.
+ (movdi_internal, movdf_internal): Remove alternative using l32r insns.
+ (movsi_internal, movsf_internal): Add alternative using const16 insns.
+ (movsf): Add const16 support.
+ (entry, prologue, epilogue): New.
+ (set_frame_ptr): Add missing mode for unspec_volatile operation.
+ Likewise for subsequent split pattern.
+ * doc/invoke.texi (Option Summary, Xtensa Options): Document new
+ "-mconst16" and "-mno-const16" options.
+
+2003-05-14 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.c (ia64_expand_load_address): Force destination
+ to be DImode register. Merge load_symptr.
+ * config/ia64/ia64.md (load_symptr): Remove.
+
+2003-05-14 Richard Henderson <rth@redhat.com>
+
+ * rtl.h (TREE_CONSTANT_POOL_ADDRESS_P): Rename from
+ DEFERRED_CONSTANT_P.
+ * integrate.c (copy_rtx_and_substitute): Update use.
+ * varasm.c (build_constant_desc): Set SYMBOL_REF_DECL
+ to the copy generated.
+ (maybe_output_constant_def_contents): Examine TREE_ASM_WRITTEN
+ of the constant to see if we should emit.
+ (mark_constant): Similarly.
+ (output_constant_def_contents): Set TREE_ASM_WRITTEN.
+
+2003-05-14 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (movsi_internal2): Use compare for self
+ move record condition.
+ (movdi_internal2): Same.
+
+2003-05-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov-io.h (gcov_write_bytes, gcov_read_bytes): Remove here.
+ (GCOV_TAG_*) Force type to gcov_unsigned_t.
+ (GCOV_CHECK, GCOV_CHECK_READING, GCOV_CHECK_WRITING): New.
+ (struct gcov_var): Remove modified. Add start, length, offset,
+ overread. Have buffer array for libgcov.
+ (gcov_sync, gcov_seek): Definitions moved to gcov-io.c.
+ (gcov_position, gcov_rewrite, gcov_is_eof): Adjust.
+ * gcov-io.c (gcov_open): Set mode, do not read anything.
+ (gcov_close): Write final block.
+ (gcov_write_block, gcov_allocate): New.
+ (gcov_write_bytes): Make static. Write or allocate buffer.
+ (gcov_write_unsigned, gcov_write_counter): Buffer can never be
+ null.
+ (gcov_write_string): Adjust.
+ (gcov_write_tag)
+ (gcov_write_length): Adjust. Flush the block.
+ (gcov_write_tag_length): Buffer can never be null.
+ (gcov_read_bytes): Make static. Read in block.
+ (gcov_sync): Moved here. Adjust.
+ (gcov_seek): Moved here. Adjust.
+ * coverage.c (read_counts_file): Adjust.
+ * gcov-dump.c (print_prefix): Add position parameter.
+ (flag_dump_positions): New flag.
+ (options, main, print_usage): Add it.
+ (dump_file, tag_blocks, tag_arcs, tag_lines, tag_counters,
+ tag_summary): Adjust.
+ * gcov.c (read_graph_file, read_count_file): Adjust.
+ * libgcov.c (gcov_exit): Adjust.
+
+ * Makefile.in (LIBGCC_DEPS): Use $(srcdir) on gcov files
+ (libgcov.a): Depend on libgcc.a.
+ (gcov.o, gcov-dump.o): Add gcov-io.c.
+ * mklibgcc.in (libgcov_c_dep): Use $(srcdir).
+
+ * loop.c (check_dbra_loop): Factor common test.
+
+2003-05-14 Ben Elliston <bje@wasabisystems.com>
+
+ * doc/md.texi (Automaton pipeline description): Grammar fixes.
+
+2003-05-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * target-def.h (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (TARGET_INITIALIZER): Include it.
+ * target.h (struct gcc_target): Add machine_dependent_reorg field.
+ * toplev.c (rest_of_compilation): Use targetm.machine_dependent_reorg.
+ * system.h: Poison MACHINE_DEPENDENT_REORG.
+
+ * config/alpha/alpha-protos.h (alpha_reorg): Remove declaration.
+ * config/alpha/alpha.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/alpha/alpha.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (alpha_handle_trap_shadows): Remove "first insn" parameter.
+ (alpha_align_insns): Likewise.
+ (alpha_reorg): Likewise. Make static. Update calls to above
+ functions.
+
+ * config/arm/arm-protos.h (arm_reorg): Remove declaration.
+ * config/arm/arm.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/arm/arm.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (arm_reorg): Remove parameter. Make static.
+
+ * config/avr/avr-protos.h (machine_dependent_reorg): Remove.
+ * config/avr/avr.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/avr/avr.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (avr_reorg): Renamed from machine_dependent_reorg. Make static.
+ Remove parameter.
+
+ * config/c4x/c4x-protos.h (c4x_process_after_reload): Remove.
+ * config/c4x/c4x.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/c4x/c4x.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (c4x_reorg): Renamed from c4x_process_after_reload. Make static.
+ Remove parameter.
+
+ * config/d30v/d30v-protos.h (d30v_machine_dependent_reorg): Remove.
+ * config/d30v/d30v.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/d30v/d30v.c (d30v_machine_dependent_reorg): Remove.
+
+ * config/frv/frv-protos.h (frv_machine_dependent_reorg): Remove.
+ * config/frv/frv.c: Remove orphaned comment.
+
+ * config/i386/i386-protos.h (x86_machine_dependent_reorg): Remove.
+ * config/i386/i386.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/i386/i386.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (ix86_reorg): Renamed from x86_machine_dependent_reorg. Make static.
+ Remove parameter.
+
+ * config/ia64/ia64-protos.h (ia64_reorg): Remove declaration.
+ * config/ia64/ia64.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/ia64/ia64.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (emit_insn_group_barriers): Remove "first insn" parameter.
+ (emit_all_insn_group_barriers): Likewise.
+ (ia64_reorg): Likewise. Make static. Update calls to above functions.
+ (ia64_output_mi_thunk): Update call to emit_all_insn_group_barriers.
+
+ * config/ip2k/ip2k-protos.h (machine_dependent_reorg): Remove.
+ * config/ip2k/ip2k.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/ip2k/ip2k.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (ip2k_reorg): Renamed from machine_dependent_reorg. Make static.
+ Remove parameter.
+
+ * config/m68hc11/m68hc11-protos.h (m68hc11_reorg): Remove declaration.
+ * config/m68hc11/m68hc11.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/m68hc11/m68hc11.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (m68hc11_reorg): Make static. Remove parameter.
+
+ * config/mcore/mcore-protos.h (mcore_dependent_reorg): Remove.
+ * config/mcore/mcore.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/mcore/mcore.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (conditionalize_optimization): Remove parameter.
+ (mcore_reorg): Renamed from mcore_dependent_reorg. Remove parameter.
+ Make static. Update call to conditionalize_optimization.
+
+ * config/mips/mips-protos.h (machine_dependent_reorg): Remove.
+ * config/mips/mips.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/mips/mips.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (mips_reorg): Renamed from machine_dependent_reorg. Remove parameter.
+ Make static.
+
+ * config/mmix/mmix-protos.h (mmix_machine_dependent_reorg): Remove.
+ * config/mmix/mmix.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/mmix/mmix.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (mmix_reorg): Renamed from mmix_machine_dependent_reorg. Make static.
+ Remove parameter.
+
+ * config/pa/pa-protos.h (pa_reorg): Remove declaration.
+ * config/pa/pa.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/pa/pa.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (pa_combine_instructions): Remove "first insn" parameter.
+ (remove_useless_addtr_insns): Likewise.
+ (pa_reorg): Likewise. Make static. Update calls to above functions.
+
+ * config/rs6000/rs6000.h (MACHINE_DEPENDENT_REORG): Remove
+ commented-out definition.
+
+ * config/s390/s390-protos.h (s390_machine_dependent_reorg): Remove.
+ * config/s390/s390.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/s390/s390.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (s390_reorg): Renamed from s390_machine_dependent_reorg. Make static.
+ Remove parameter.
+
+ * config/sh/sh-protos.h (machine_dependent_reorg): Remove.
+ * config/sh/sh.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/sh/sh.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (sh_reorg): Renamed from machine_dependent_reorg. Make static.
+ Remove parameter.
+ (sh_output_mi_thunk): Call sh_reorg directly.
+ * config/sh/sh.md: Update comment.
+
+ * config/stormy16/stormy16.h (MACHINE_DEPENDENT_REORG): Remove
+ commented-out definition.
+
+ * config/v850/v850-protos.h (v850_reorg): Remove declaration.
+ * config/v850/v850.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/v850/v850.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (v850_reorg): Make static. Remove parameter.
+
+ * config/xtensa/xtensa-protos.h (xtensa_reorg): Remove declaration.
+ * config/xtensa/xtensa.h (MACHINE_DEPENDENT_REORG): Remove.
+ * config/xtensa/xtensa.c (TARGET_MACHINE_DEPENDENT_REORG): Define.
+ (xtensa_reorg): Make static. Remove parameter.
+
+ * doc/tm.texi (MACHINE_DEPENDENT_REORG): Remove.
+ (TARGET_MACHINE_DEPENDENT_REORG): Document.
+
+2003-05-13 Richard Henderson <rth@redhat.com>
+
+ * c-decl.c (duplicate_decls): Re-invoke make_decl_rtl if
+ the old decl had instantiated DECL_RTL.
+
+2003-05-13 Mike Stump <mrs@apple.com>
+
+ * doc/invoke.texi (Option Summary): Kill off documentation for -$.
+
+2003-05-13 Janis Johnson <janis187@us.ibm.com>
+
+ * config/rs6000/sysv4.h (OUTPUT_ASM_ALIGNED_LOCAL): Expect
+ HOST_WIDE_INT argument.
+
+2003-05-13 Jason Merrill <jason@redhat.com>
+
+ * tree.h (STRIP_MAIN_TYPE_NOPS): New macro.
+
+ * tree.c (iterative_hash_expr): New fn.
+
+ * c-semantics.c (emit_local_var): Don't mess with temp slots if
+ there's no initializer.
+
+2003-05-13 Richard Sandiford <rsandifo@redhat.com>
+
+ * final.c (final_scan_insn): Apply the effects of frame-related
+ delay slot insns before emitting a delayed branch.
+
+2003-05-13 Nick Clifton <nickc@redhat.com>
+
+ * config/mcore/mcore.md (jump): Use emit_jump_insn.
+
+2003-05-13 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h (ASM_OUTPUT_SPECIAL_POOL_ENTRY): Second
+ parameter of ASM_OUTPUT_SKIP must have type unsigned HOST_WIDE_INT.
+
+2003-05-12 DJ Delorie <dj@redhat.com>
+
+ * expr.c (move_by_pieces): Honor the alignment of TO and FROM.
+ (emit_push_insn): Don't use push when the source alignment is less
+ than the stack's push rounding.
+
+2003-05-13 Zack Weinberg <zack@codesourcery.com>
+
+ * diagnostic.c (output_format): Add support for %m.
+ (output_printf, output_verbatim, diagnostic_set_info,
+ verbatim): Set err_no field of the text_info structure being
+ initialized.
+ (fatal_io_error): Delete function.
+ * diagnostic.h (text_info): Add err_no field.
+ * toplev.h (fatal_io_error): Delete prototype.
+
+ * c-opts.c, c-pch.c, dwarfout.c, ggc-common.c, ggc-page.c, graph.c
+ * toplev.c, config/mips/mips.c, config/rs6000/host-darwin.c
+ * objc/objc-act.c: Replace all calls to fatal_io_error with
+ calls to fatal_error; add ": %m" to the end of all the affected
+ error messages.
+
+2003-05-13 Zack Weinberg <zack@codesourcery.com>
+
+ * varasm.c (notice_rtl_inlining_of_deferred_constant): New function.
+ * rtl.h: Prototype it.
+ * integrate.c (copy_rtx_and_substitute <SYMBOL_REF>): Call it
+ when appropriate.
+
+2003-05-13 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("*iordi3_oi"): Do not mark commutative.
+ ("*iorsi3_oi"): Likewise.
+
+2003-05-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (compare_scc): Use shorter sequence for EQ case.
+ (ior_scc_scc_cmp, and_scc_scc_cmp): New insn-and-split patterns.
+ (and_scc_scc): Ensure split only applies when there is a dominance
+ of the comparisons.
+ (and_scc_scc_nodom): New insn-and-split pattern.
+
+2003-05-13 Richard Sandiford <rsandifo@redhat.com>
+
+ * unwind-dw2.c (uw_init_context_1): Don't pass &outer_cfa directly
+ to _Unwind_SetGRPtr().
+
+2003-05-13 Michael Eager <eager@mvista.com>
+
+ * Makefile.in: Initialize program_transform_cross_name from
+ @program_transform_name@ instead of target_alias.
+
+2003-05-12 Janis Johnson <janis187@us.ibm.com>
+ Alan Modra <amodra@bigpond.net.au>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * configure.in (HAVE_AS_TLS): Add powerpc and powerpc64 tests.
+ * configure: Rebuild.
+ * config/rs6000/rs6000-protos.h: Update.
+ * config/rs6000/rs6000.c (rs6000_tls_size): New.
+ (rs6000_tls_size_string): New.
+ (rs6000_parse_tls_size_option): New.
+ (rs6000_legitimize_tls_address): New.
+ (rs6000_tls_get_addr): New.
+ (rs6000_got_sym): New.
+ (rs6000_tls_symbol_ref): New.
+ (rs6000_tls_symbol_ref_1): New.
+ (rs6000_get_some_local_dynamic_name): New.
+ (rs6000_get_some_local_dynamic_name_1): New.
+ (TARGET_HAVE_TLS): New.
+ (TARGET_CANNOT_FORCE_CONST_MEM): New.
+ (rs6000_override_options): Handle -mtls-size option.
+ (constant_pool_expr_1): Handle TLS symbols.
+ (rs6000_legitimize_address): Handle TLS symbols.
+ (rs6000_tls_referenced_p): New.
+ (rs6000_legitimate_address): Handle TLS symbols.
+ (rs6000_emit_move): Handle TLS symbols.
+ (print_operand): Handle TLS symbols.
+ (uses_TOC): Handle TLS symbols.
+ (rs6000_emit_prologue): Use symbol for unspec constant.
+ * config/rs6000/rs6000.h (HAVE_AS_TLS): New.
+ (some_ld_name): New.
+ (LEGITIMATE_CONSTANT_P): Handle TLS symbols.
+ (PRINT_OPERAND_PUNCT_VALID_P): Handle TLS symbols.
+ (PREDICATE_CODES): Add rs6000_tls_symbol_ref.
+ * config/rs6000/rs6000.md (load_toc_v4_PIC_1, load_toc_v4_PIC_1b):
+ Support TLS.
+ (tls_gd_32, tls_gd_64, tls_ld_32, tls_ld_64, tls_dtprel_32,
+ tls_dtprel_64, tls_dtprel_ha_32, tls_dtprel_ha_64, tls_dtprel_lo_32,
+ tls_dtprel_lo_64, tls_got_dtprel_32, tls_got_dtprel_64, tls_tprel_32,
+ tls_tprel_64, tls_tprel_ha_32, tls_tprel_ha_64, tls_tprel_lo_32,
+ tls_tprel_lo_64, tls_got_tprel_32, tls_got_tprel_64, tls_tls_32,
+ tls_tls_64): New.
+ * config/rs6000/sysv4.h (SUBTARGET_OPTIONS): Add tls_size.
+
+2003-05-12 Neil Booth <neil@cat.daikokuya.co.uk>
+
+ * Makefile.in (stage2_build, stage3_build, stage4_build):
+ Set BUILD_CC to the same as CC.
+
+2003-05-12 Neil Booth <neil@daikokuya.co.uk>
+
+ * alloc-pool.c (last_id): Put in ENABLE_CHECKING guards.
+
+2003-05-12 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/ia64.c (ia64_function_ok_for_sibcall): Mark 'exp'
+ as unused.
+ (bundling): Initialize 'pos'.
+ (ia64_expand_builtin): Initialize 'rmode'.
+
+2003-05-12 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/xcoff.h (ASM_OUTPUT_SKIP): Accept HOST_WIDE_INT.
+ (ASM_OUTPUT_ALIGNED_COMMON): Same.
+ (ASM_OUTPUT_LOCAL): Same.
+
+Mon May 12 21:53:29 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * varasm.c (output_constant): Fix underflow.
+
+2003-05-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR other/10745
+ * configure.in: Correct detection of GNU ld version number.
+ * configure: Regenerated.
+
+2003-05-12 Zack Weinberg <zack@codesourcery.com>
+
+ * diagnostic.c (diagnostic_for_decl): Take a
+ diagnostic_context argument. Restructure to be consistent
+ with diagnostic_report_diagnostic.
+ (diagnostic_count_diagnostic): Now static. Take a
+ diagnostic_info argument, not just a diagnostic_t. Some code
+ moved here from internal_error. Move a case label for
+ clarity.
+ (diagnostic_action_after_output): New function. Code moved
+ here from internal_error and fatal_error.
+ (bug_report_request): New #define so that this text appears in
+ only one place.
+ (diagnostic_report_diagnostic): Update to match changes to
+ diagnostic_count_diagnostic. Call diagnostic_action_after_output.
+ (diagnostic_set_info): Call gettext here.
+
+ (pedwarn): Update comment. Don't call gettext here.
+ (sorry): Use report_diagnostic. Don't call gettext here.
+ (fatal_error): Remove final fnotice and exit, but call
+ real_abort to prevent warnings about noreturn function returning.
+ (internal_error): Likewise. Don't do ICE suppression here nor
+ call context->internal_error.
+ (warning_with_decl): Suppress for decls in system headers.
+ Adjust call to diagnostic_for_decl.
+ (pedwarn_with_decl): Likewise.
+ (error_with_decl): Adjust call to diagnostic_for_decl.
+ (error_recursion): Use bug_report_request.
+
+ * diagnostic.h: Remove prototype of diagnostic_count_diagnostic.
+ * objc/objc-act.c (error_with_ivar, warn_with_method): Don't call
+ diagnostic_count_diagnostic.
+
+2003-05-12 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa64-hpux.h (ASM_OUTPUT_ALIGNED_COMMON): Correct last patch.
+
+Mon May 12 15:57:54 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * rs6000/darwin.h (ASM_OUTPUT_COMMON): Accept HOST_WIDE_INT
+ * mips/elf.h (ASM_OUTPUT_ALIGNED_BSS): Fix warning.
+ * mips/mips.h (ASM_OUTPUT_SKIP): Fix typo in the previous patch.
+
+2003-05-12 Roger Sayle <roger@eyesopen.com>
+
+ * doc/rtl.texi: Document zero_extract as a valid destination
+ of a set insn.
+
+2003-05-12 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm/lib1funcs.asm (LSYM): Define -- on ELF prefix a local symbol with
+ '.'. Change all local symbol definitions and references to use LSYM.
+
+Mon May 12 11:32:53 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * expr.h (assemble_static_space): Update prototype.
+ * output.h (assemble_zeros, output_constant): Likewise.
+ * elfos.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_COMMON): Make it 64bit clean
+ * alpha.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_COMMON, ASK_OUTPUT_LOCAL): Make
+ it 64bit clean.
+ * elf.h (ASM_OTUPUT_SKIP): Likewise.
+ * unicosmk.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_COMM): Likewise.
+ * arm.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL, ASM_OUTPUT_SKIP):
+ Expect HOST_WIDE_INT operand.
+ * aout.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL, ASM_OUTPUT_SKIP):
+ Expect HOST_WIDE_INT operand.
+ * unknown-elf.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL, ASM_OUTPUT_SKIP):
+ Expect HOST_WIDE_INT operand.
+ * avr.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_SKIP): Expect
+ HOST_WIDE_INT operand.
+ * c4x.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL, ASM_OUTPUT_SKIP,
+ ASM_OUTPUT_BSS): Expect HOST_WIDE_INT operand.
+ * aout.h (ASM_OTUPUT_SKIP): Likewise.
+ * cris.h (ASM_OTUPUT_SKIP, ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL): Likewise.
+ * darwin.h (ASM_OTUPUT_SKIP, ASM_OUTPUT_COMMON): Likewise.
+ * dsp16xx.h (ASM_OTUPUT_SKIP): Likewise.
+ * frv.h (ASM_OTUPUT_SKIP): Likewise.
+ * h8300.h (ASM_OTUPUT_SKIP, ASM_OUTPUT_LOCAL): Likewise.
+ * 370.h (ASM_OTUPUT_SKIP, ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL):
+ Make it 64bit
+ clean.
+ * att.h (ASM_OUTPUT_SKIP): Expect HOST_WIDE_INT operand.
+ * bsd.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL):
+ Make it 64bit clean.
+ * darwin.h (ASM_OUTPUT_SKIP): Make it 64bit clean..
+ * sco5.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL): Expect
+ HOST_WIDE_INT operand
+ * svr3gas.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL):
+ Expect HOST_WIDE_INT operand
+ * sysv3.h (ASM_OUTPUT_SKIP): Expect HOST_WIDE_INT operand
+ * i960.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_COMMON,
+ ASM_OUTPUT_ALIGNED_LOCAL): Expect HOST_WIDE_INT operand
+ * ip2k.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL, ASM_OUTPUT_SKIP):
+ Likewise.
+ * m32r.h (ASM_OUTPUT_COMMON): Likewise.
+ * 3b1.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL, ASM_OUTPUT_SKIP):
+ Likewise.
+ * amix.h (ASM_OUTPUT_ALIGNED_LOCAL): Likewise.
+ * crds.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_ALIGNED_LOCAL): Likewise.
+ * hp320.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL,
+ ASM_OUTPUT_SKIP): Likewise.
+ * m68k.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL, ASM_OUTPUT_SKIP):
+ Likewise.
+ * m68kelf.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL,
+ ASM_OUTPUT_SKIP): Likewise.
+ * m68kv4.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL,
+ ASM_OUTPUT_SKIP): Likewise.
+ * mot3300.h (ASM_OUTPUT_LOCAL, ASM_OUTPUT_SKIP): Likewise.
+ * netbsd-elf.h (ASM_OUTPUT_LOCAL, ASM_OUTPUT_COMMON,
+ ASM_OUTPUT_SKIP): Likewise.
+ * sgs.h (ASM_OUTPUT_SKIP): Likewise.
+ * tower-as.h (ASM_OUTPUT_LOCAL, ASM_OUTPUT_COMMON,
+ ASM_OUTPUT_SKIP): Likewise.
+ * m88k.h (ASM_OUTPUT_LOCAL, ASM_OUTPUT_COMMON, ASM_OUTPUT_SKIP):
+ Likewise.
+ * mcore.h (ASM_OUTPUT_LOCAL, ASM_OUTPUT_BSS, ASM_OUTPUT_SKIP): Likewise.
+ * iris.h (ASM_OUTPUT_LOCAL): Likewise.
+ * mips.h (ASM_OUTPUT_LOCAL, ASM_OUTPUT_SKIP): Likewise.
+ * ns32k.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL,
+ ASM_OUTPUT_SKIP): Make it 64bit clean.
+ * pa-pro-end.h (ASM_OUTPUT_LOCAL, ASM_OUTPUT_ALIGNED_LOCAL):
+ Make it 64bit clean.
+ * pa.h (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL, ASM_OUTPUT_ALIGNED_LOCAL,
+ ASM_OUTPUT_SKIP): Make it 64bit clean.
+ * hpux.h (ASM_OUTPUT_LOCAL, ASM_OUTPUT_ALIGNED_LOCAL): Make it
+ 64bit clean.
+ * romp.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_LOCAL, ASM_OUTPUT_COMMON): Expect
+ HOST_WIDE_INT argument
+ * s390.h (ASM_OUTPUT_SKIP): Expect HOST_WIDE_INT argument.
+ * sh.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_LOCAL, ASM_OUTPUT_COMMON): Expect
+ HOST_WIDE_INT argument
+ * sol2.h (ASM_OUTPUT_SKIP): HOST_WIDE_INT argument
+ * sparc.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_COMMON): HOST_WIDE_INT argument
+ * svr3.h (ASM_OUTPUT_SKIP): HOST_WIDE_INT argument
+ * vax.h (ASM_OUTPUT_SKIP, ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL):
+ HOST_WIDE_INT argument
+ * vaxv.h (ASM_OUTPUT_LOCAL): HOST_WIDE_INT argument
+ * xtensa.h (ASM_OUTPUT_LOCAL): HOST_WIDE_INT argument
+ * varasm.c (asm_output_bss, asm_output_aligned_bss,
+ asm_emit_uninitialized, assemble_zeros, assemble_static_space):
+ HOST_WIDE_INT argument
+
+2003-05-10 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cgraphunit.c (cgraph_create_edges): Drop walk_tree in
+ favor of walk_tree_without_duplicates. Add comments.
+
+2003-05-12 Josef Zlomek <zlomekj@suse.cz>
+
+ * alloc-pool.h (ALLOC_POOL_ID_TYPE): New type.
+ (struct alloc_pool_def): New element 'id'.
+ * alloc-pool.c (fancy_abort): Extern function prototype.
+ (abort): Macro which uses fancy_abort.
+ (struct allocation_object_def): New structure.
+ (ALLOCATION_OBJECT_PTR_FROM_USER_PTR): New macro.
+ (USER_PTR_FROM_ALLOCATION_OBJECT_PTR): New macro.
+ (last_id): New variable.
+ (create_alloc_pool): Add the offset of u.data to size of element,
+ increase and use last_id.
+ (free_alloc_pool): Do the checking only when ENABLE_CHECKING.
+ (pool_alloc): Likewise. Set ID for elements.
+ (pool_free): Check whether the PTR was allocated from POOL.
+
+2003-05-11 Richard Henderson <rth@redhat.com>
+
+ PR c/10675
+ * c-decl.c: Include hashtab.h.
+ (detect_field_duplicates): New.
+ (finish_struct): Use it.
+ * Makefile.in (c-decl.o): Update.
+ * c-parse.in (structsp_attr): Nreverse component_decl_list results.
+ (component_decl_list, component_decl_list2,
+ components, components_notype): Build list in reverse order.
+ (enumlist): Clarify docs. Use TREE_CHAIN not chainon.
+
+ * tree.c (chainon): Special case op2 null as well.
+ Reorg for clarity.
+
+2003-05-11 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.md (logsf2, logdf2, logxf2, logdf2): New patterns
+ to implement log, logf and logl built-ins as inline x87 intrinsics.
+ (UNSPEC_FYL2X): New unspec to represent x87's "fyl2x" instruction.
+ (*fyl2x_sfxf3, *fyl2x_dfxf3, *fyl2x_xf3, *fyl2x_tfxf3): New insn
+ patterns for x87's "fyl2x" instruction, used by log?f2 patterns.
+
+ * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_FYL2X like
+ UNSPEC_FPATAN, i.e. replaces two stack operands with single result.
+
+2003-05-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (out_object_file): Don't set -Wno-error for ${cpu}.o.
+
+ * sparc.c (print_operand): Fix uninitialized warning.
+
+2003-05-12 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopanal.c (num_loop_insns, average_num_loop_insns): Count only
+ real insns.
+ * loop-unroll.c (unroll_loop_runtime_iterations): Remove superfluous
+ condition.
+
+2003-05-11 Neil Booth <neil@cat.daikokuya.co.uk>
+
+ * doc/cpp.texi: Fix typos.
+
+2003-05-11 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_function_arg_float): New function.
+ (s390_function_arg_pass_by_reference): Use it.
+ (s390_function_arg_advance): Likewise.
+ (s390_function_arg): Likewise.
+ (s390_va_arg): Likewise
+
+2003-05-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * coverage.h (coverage_counter_alloc): New function.
+ * function.h (struct function): Remove arc_profile flag.
+ * coverage.c (fn_ident): Remove.
+ (fn_b_ctrs, no_coverage): New.
+ (get_coverage_counts): Use current_function_funcdef_no.
+ (coverage_counter_alloc): New.
+ (coverage_counter_ref): Adjust.
+ (coverage_begin_output): Check no_coverage. Use
+ current_function_funcdef_no.
+ (coverage_end_function): Likewise.
+ (create_coverage): Set no_coverage. Set DECL_UNINLINEABLE rather
+ than clearing flag_inline_functions. Do not clear arc_profile
+ flag.
+ * function.c (prepare_function_start): Do not set arc_profile
+ flag.
+ * profile.c (instrument_edges): Return number of instrumented
+ edges. Use a for loop.
+ (branch_prob): Call coverage_counter_alloc. Make BB_TO_GCOV_INDEX
+ local to here and simplify. Use profile_arc_flag not arc_profile
+ flag.
+ (find_spanning_tree): Reformat.
+ * toplev.c (rest_of_compilation): Use profile_arc_flags and
+ flag_test_coverage rather than arc_profile flag.
+
+2003-05-11 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * doc/invoke.texi (Wctor-dtor-privacy): Update documentation.
+
+2003-05-11 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * varasm.c (copy_constant, case VIEW_CONVERT_EXPR): New case.
+
+2003-05-11 Bruno Haible <bruno@clisp.org>
+
+ * cppfiles.c (find_or_create_entry): Preserve errno.
+
+2003-05-11 Neil Booth <neil@cat.daikokuya.co.uk>
+
+ * c-cppbuiltin.c (c_cpp_builtins): Move __STDC_HOSTED__ into
+ cpplib as it's a Standard Predefined Macro.
+ * c-opts.c (finish_options): Pass flag_hosted to cpp_init_builtins.
+ * cppinit.c (_cpp_init_builtins): Take HOSTED. Define
+ __STDC_HOSTED__ appropriately.
+ * cpplib.h (_cpp_init_builtins): Update.
+ * fix-header.c (read_scan_file): Update.
+ * doc/cpp.texi, doc/cppopts.texi: Update documentation.
+
+2003-05-11 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR C++/689
+ PR C++/9257
+ * c-opts.c (c_common_decode_option): Don't set
+ warn_ctor_dtor_privacy wen -Wall.
+ * c-common.c (warn_ctor_dtor_privacy): Don't turn on by default.
+
+2003-05-10 Alexandre Oliva <aoliva@redhat.com>
+
+ * reload1.c (reload_cse_move2add): Revert part of my 2003-05-09's
+ patch.
+
+2003-05-10 Zack Weinberg <zack@codesourcery.com>
+
+ * diagnostic.c: Reorder functions for clarity, putting all the
+ functions in the "error" family next to each other, and
+ likewise all the functions in the "error_with_decl" family.
+ Some other routines were moved too. Add comments.
+ (vbuild_message_string): Fold into sole caller.
+
+
+2003-05-11 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * except.c (EH_RETURN_STACKADJ_RTX): Do not define.
+ (EH_RETURN_HANDLER_RTX): Likewise.
+ (expand_builtin_eh_return): Do not copy stack adjustment
+ if EH_RETURN_STACKADJ_RTX is not defined.
+ (expand_eh_return): Likewise. Also, do not pass stack
+ adjustment as argument to the eh_return pattern.
+ * except.h (MUST_USE_SJLJ_EXCEPTIONS): Do not define just
+ because EH_RETURN_STACKADJ_RTX is not defined.
+ * unwind-dw.c (uw_update_context_1): If EH_RETURN_STACKADJ_RTX
+ is not defined, treat stack pointer like a regular register.
+ (uw_init_context_1): Set up fake initial stack pointer register.
+ (uw_install_context_1): Do not compute stack adjustment if
+ EH_RETURN_STACKADJ_RTX is not defined.
+
+ * config/i386/i386.md ("eh_return"): Remove first argument.
+ * config/mips/mips.md ("eh_return"): Likewise.
+ * config/rs6000/rs6000.md ("eh_return"): Likewise.
+ * config/sh/sh.md ("eh_return"): Likewise.
+
+ * config/s390/s390.h (EH_RETURN_STACKADJ_RTX): Remove.
+
+2003-05-10 Alexander Aganichev <aaganichev@yandex.ru>
+
+ * config/i386/i386.h (MODES_TIEABLE_P): Fix typo.
+
+2003-05-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * defaults.h (GCOV_TYPE_SIZE): Remove.
+ * gcov-io.h (gcov_type): Set to specific mode int on target.
+ (gcov_unsigned_t, gcov_position_t): New.
+ (GCOV_TYPE_NODE): New.
+ (GCOV_TAG_SUMMARY_LENGTH): Adjust.
+ (GCOV_COUNTERS_SUMMABLE): New.
+ (gcov_ctr_summary, gcov_sumary, gcov_fn_info, gcov_merge_fn,
+ gcov_ctr_info, gcov_info): Adjust types.
+ (gcov_var): Adjust types.
+ (gcov_write_unsigned, gcov_write_tag,
+ gcov_write_length, gcov_write_tag_length, gcov_write_summary,
+ gcov_read_unsigned, gcov_read_summary): Adjust gcov types.
+ (gcov_position, gcov_sync, gcov_seek): Adjust gcov types.
+ * gcov-io.c (gcov_write_unsigned, gcov_write_tag,
+ gcov_write_length, gcov_write_tag_length, gcov_write_summary,
+ gcov_read_unsigned, gcov_read_summary): Adjust gcov types.
+ * libgcov.c (gcov_crc32, gcov_version_mismatch, gcov_exit,
+ __gcov_init, __gcov_merge_add): Adjust gcov types.
+ * coverage.c (ctr_merge_functions): Constify.
+ (ctr_names): New.
+ (read_counts_file): Adjust gcov types. Only summarize & merge
+ summable counters.
+ (coverage_counter_ref): Use GCOV_TYPE_NODE.
+ (build_fn_info_type, build_fn_info_value, build_ctr_info_type,
+ build_ctr_info_value, build_gcov_info): Adjust types.
+ * profile.c (branch_prob): Adjust gcov types.
+ * gcov_dump (dump_file): Adjust gcov types.
+
+2003-05-10 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (DOM_CC_X_AND_Y, DOM_CC_NX_OR_Y, DOM_CC_X_OR_Y): New
+ constants.
+ (ior_scc_scc, and_scc_scc): New insn_and_split patterns.
+ * arm.c (arm_select_dominance_cc_mode): Renamed from
+ select_dominance_cc_mode, no-longer static. Use DOM_CC... constants.
+ Callers updated.
+ * arm-protos.h (arm_select_dominance_cc_mode): Add prototype.
+
+2003-05-09 Roger Sayle <roger@eyesopen.com>
+
+ * config/alpha/alpha.c (alpha_start_function): Declare frame_size
+ as unsigned to avoid signed/unsigned comparison warnings.
+
+2003-05-09 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (xtensa_emit_loop_end): Only use "nop.n"
+ instruction if the Xtensa density option is enabled.
+
+2003-05-09 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * mklibgcc.in: Remove extra quotes.
+
+2003-05-09 Mark Mitchell <mark@codesourcery.com>
+
+ * config/rs6000/rs6000.c (spe_init_builtins): Fix typo in creation
+ of int_ftype_void.
+
+2003-05-09 Alexandre Oliva <aoliva@redhat.com>
+
+ * reload1.c (reload_cse_move2add): Don't turn an implicit
+ truncation into a self-set in the narrow mode.
+
+2003-05-09 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (clzsi2): The CLZ instruction is predicable.
+
+2003-05-09 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c: Formatting.
+
+2003-05-09 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dump.c (dequeue_and_dump): Use CONSTRUCTOR_ELTS,
+ instead of TREE_OPERAND to access the operand of a
+ CONSTRUCTOR node.
+
+2003-05-09 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-dump.c (dequeue_and_dump): CONSTRUCTOR nodes contain only
+ one operand.
+
+2003-05-09 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * toplev.h (warning_with_file_and_line): Don't declare.
+ (error_with_file_and_line): Likewise.
+ * diagnostic.c (error_with_file_and_line): Remove.
+ (warning_with_file_and_line): Likewise.
+
+2003-05-09 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-parse.in (if_stmt_locus): New object.
+ (if_prefix rule): Use it. Don't use warning_with_file_and_line.
+ (select_or_iter_stmt rule): Likewise.
+ (if_stmt_file): Remove.
+ (if_stmt_line): Likewise.
+ * jump.c: include "diagnostic.h"
+ (never_reached_warning): Don't use warning_with_file_and_line.
+ * Makefile.in (jump.o): Add dependce on diagnostic.h
+
+2003-05-09 Alan Modra <amodra@bigpond.net.au>
+
+ * expr.c (move_block_from_reg): Remove "size" parm. Localize vars.
+ Move code handling pieces not larger than a word to..
+ * function.c (assign_parms): ..here, but use change_address instead
+ of adjust_address and operand_subword, and expand_binop instead of
+ expand_shift. Adjust calls to move_block_from_reg.
+ * expr.h (move_block_from_reg): Update declaration.
+ (copy_blkmode_from_reg): Formatting.
+ * Makefile.in (function.o): Add $(OPTABS_H) to deps.
+ * config/alpha/alpha.c (alpha_setup_incoming_varargs): Adjust
+ move_block_from_reg calls.
+ * config/arc/arc.c (arc_setup_incoming_varargs): Likewise.
+ * config/i960/i960.c (i960_setup_incoming_varargs): Likewise.
+ * config/m32r/m32r.c (m32r_setup_incoming_varargs): Likewise.
+ * config/m88k/m88k.c (m88k_builtin_saveregsk): Likewise.
+ * config/mips/mips.c (mips_setup_incoming_varargs): Likewise.
+ * config/pa/pa.c (hppa_builtin_saveregs): Likewise.
+ * config/romp/romp.h (SETUP_INCOMING_VARARGS): Likewise.
+ * config/rs6000/rs6000.c (setup_incoming_varargs): Likewise.
+ * config/sh/sh.c (sh_builtin_saveregs): Likewise.
+
+2003-05-08 DJ Delorie <dj@redhat.com>
+
+ * config/stormy16/stormy16.c (xstormy16_expand_builtin_va_arg): Fix
+ to handle arguments for which MUST_PASS_IN_STACK is true (e.g.,
+ variable-sized types).
+ (xstormy16_function_arg): New. Pass them that way too.
+ * config/stormy16/stormy16-protos.h (xstormy16_function_arg): New.
+ * config/stormy16/stormy16.h (FUNCTION_ARG): Call it.
+
+2003-05-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * mklibgcc.in: Use mkinstalldirs when installing multilib
+ directories.
+
+2003-05-08 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (gen_block_redirect, split_branches): Use CODE_FOR_jump_compact
+ instead of CODE_FOR_jump
+
+2003-05-08 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * objc/objc-act.c (error_with_ivar): Don't use
+ error_with_file_and_line.
+ (warn_with_method): Don't use warning_with_file_and_line.
+
+2003-05-08 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * stmt.c (emit_locus): New macro.
+ (emit_filename): Remove.
+ (emit_lineno): Likewise.
+ (struct stmt_status): Replace members x_emit_filename and
+ x_emit_lineno with x_emit_locus.
+ (set_file_and_line_for_stmt): Adjust.
+ (expand_expr_stmt_value): Don't use warning_with_file_and_line.
+ (warn_if_unused_value): Likewise.
+ (check_seenlabel): Likewise.
+
+2003-05-08 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-decl.c (define_label): Tidy. Don't use any of
+ error_with_file_and_line or warning_with_file_and_file.
+ (pending_xref_error): Likewise.
+ (store_parm_decls): Likewise.
+ (current_function_prototype_locus): New object. Package from
+ current_function_prototype_file and current_function_prototype_line.
+ (start_function): Use it.
+ (current_function_prototype_file): Remove.
+ (current_function_prototype_line): Remove;
+
+2003-05-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (readonly_data_expr): New function.
+ (expand_builtin_memmove): Optimize any rodata source, not just
+ strings.
+
+2003-05-07 David Mosberger <davidm@hpl.hp.com>
+
+ * unwind-libunwind.c (_Unwind_FindEnclosingFunction): New.
+
+2003-05-07 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (ix86_split_long_move): Fix base register
+ mode for XFmode splits for TARGET_64BIT.
+
+2003-05-07 Richard Henderson <rth@redhat.com>
+
+ * sched-ebb.c (schedule_ebb): Supply the correct starting
+ block number to save_line_notes.
+
+2003-05-07 Richard Henderson <rth@redhat.com>
+
+ * toplev.c (enum dump_file_index): Swap DFI_ce3, DFI_bbro.
+ (dump_file): Likewise.
+
+2003-05-07 David Mosberger <davidm@hpl.hp.com>
+
+ * config/ia64/crtbegin.asm (__do_jv_register_classes): Don't
+ forget to preserve gp.
+ * config/ia64/crtend.asm (__do_global_ctors_au): Ditto.
+
+ * config/ia64/crtbegin.asm (__do_jv_register_classes): Add missing
+ .prologue directive.
+ Use .skip instead of data8 for .bss section to make Intel
+ Assembler (ias) happy. Minor whitespace fixups. Make "nop 0"
+ explicit in the .mib bundles and remove the unnecessary stop
+ bits. Replace local labels with normal labels, to make ias
+ happy. Don't register __do_global_ctors_aux here, do it in
+ crtend.asm instead.
+
+ * config/ia64/crtend.asm [HAVE_INIT_FINI_ARRAY]: Register
+ __do_global_ctors_aux in .init_array section instead of
+ declaring it as a hidden global. Replace local labels with
+ ordinary labels to make ias happy.
+
+2003-05-07 Richard Henderson <rth@redhat.com>
+
+ PR c++/10570
+ * except.c: Revert 04-01 and 04-02 forced-unwind changes.
+ * flags.h, toplev.c, doc/invoke.texi: Likewise.
+
+ * unwind-dw2.c (_Unwind_GetCFA): Fix ptr->int conversion warning.
+ * unwind.inc (_Unwind_DeleteException): Check for null
+ exception_cleanup.
+
+ * unwind-sjlj.c (_Unwind_SjLj_Resume_or_Rethrow): New.
+ * unwind.inc (_Unwind_Resume_or_Rethrow): New.
+ * unwind.h: Declare them.
+ * libgcc-std.ver (GCC_3.3): Export them.
+
+2003-05-07 Richard Henderson <rth@redhat.com>
+
+ * unwind-dw2.c (_Unwind_GetCFA): Cast pointer to _Unwind_Ptr,
+ not _Unwind_Word.
+
+2003-05-07 Zack Weinberg <zack@codesourcery.com>
+
+ * stmt.c (force_label_rtx): New function, based on logic
+ formerly found in expand_expr.
+ * expr.h: Prototype it.
+ * expr.c (expand_expr <LABEL_DECL>): Use force_label_rtx if
+ appropriate.
+ * varasm.c (decode_addr_const <LABEL_DECL>): Use force_label_rtx.
+
+ * print-tree.c (debug_tree): Free the table after we're done
+ with it. Use putc.
+
+2003-05-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.h: Reverse arguments for __ev_subfw.
+ Unreverse arguments for __ev_subw.
+
+ * config/rs6000/spe.md (evsubfw): Reverse arguments of assembly.
+
+2003-05-07 Nick Clifton <nickc@redhat.com>
+
+ * config/stormy16/stormy-abi: Update to include
+ R_XSTORMY16_FPTR16, R_XSTORMY16_LO16, R_XSTORMY16_HI16 and
+ R_XSTORMY16_12 relocs.
+
+2003-05-07 Alan Modra <amodra@bigpond.net.au>
+
+ * function.c (assign_parms): Correct reversed reg_parm_stack_space
+ test. Add partial in-regs size to stack_args_size.
+
+2003-05-07 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/invoke.texi (Warning Options): Mark -Wmissing-declarations
+ as a C only option.
+
+2003-05-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov-io.h (GCOV_LOCKED): New #define.
+ (GCOV_LINKAGE): Make sure it is #defined.
+ (gcov_write_string, gcov_write_tag, gcov_write_length,
+ gcov_read_string, gcov_time): Poison in libgcov.
+ (gcov_seek_end): Remove.
+ (gcov_write_tag_length, gcov_sync, gcov_rewrite): New.
+ (GCOV_TAG_FUNCTION_LENGTH, GCOV_TAG_BLOCKS_LENGTH,
+ GCOV_TAG_ARCS_LENGTH, GCOV_TAG_COUNTER_LENGTH,
+ GCOV_TAG_SUMMARY_LENGTH): New #defines.
+ (gcov_write_tag, gcov_write_length): Not in libgcov.
+ * gcov-io.c (gcov_open): Use GCOV_LOCKED.
+ (gcov_write_tag, gcov_write_length): Not in libgcov.
+ (gcov_write_tag_length): New.
+ (gcov_write_summary): Use gcov_write_tag_length.
+ * libgcov.c: Always #include gcov-io.h.
+ (IN_LIBGCOV): -1 for inhibit_libc, +1 otherwise.
+ (GCOV_LINKAGE): Define to nothing for L_gcov.
+ (gcov_exit): Replace gcov_write_tag, gcov_write_length with
+ gcov_write_tag_length. Use gcov_rewrite & gcov_seek.
+ * gcov.c (read_graph_file): Replace gcov_seek by gcov_sync.
+ (read_count_file): Likewise.
+ * gcov-dump.c (dump_file): Likewise.
+ * coverag.c (read_counts_file): Likewise.
+
+2003-05-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR other/10658
+ * gcc.c (process_command): Update copyright date.
+
+2003-05-06 Phil Edwards <pme@gcc.gnu.org>
+
+ * doc/install.texi (mips-*-*): Add note about libstdc++.
+
+2003-05-06 DJ Delorie <dj@redhat.com>
+
+ * config/stormy16/stormy16.c (xstormy16_function_profiler): New.
+ * config/stormy16/stormy16.h (FUNCTION_PROFILER): Call it.
+ * config/stormy16/stormy16-protos.h (xstormy16_function_profiler): New.
+
+2003-05-06 <neil@cat.daikokuya.co.uk>
+
+ * c-opts.c (COMMAND_LINE_OPTIONS): Reject -Wmissing-prototypes
+ and -Wstrict-prototypes if C++.
+
+2003-05-06 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/linuxspe.h: New file.
+
+ * config.gcc: Add powerpc-*-linux-gnuspe* target.
+
+2003-05-06 Richard Henderson <rth@redhat.com>
+
+ * unwind-dw2.c (uw_update_context_1): Only set cfa as sp if
+ previous frame didn't save sp. Clear sp for next frame.
+ (uw_install_context_1): Honor saved sp from frame.
+
+2003-05-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_subword, mips_output_move): Declare.
+ (mips_move_1word, mips_move_2words): Remove declaration.
+ (mips_split_64bit_move_p, mips_split_64bit_move): Declare.
+ (mips_restore_gp): Remove insn argument.
+ * config/mips/mips.h (FP_REG_RTX_P): New macro.
+ * config/mips/mips.c (volatile_buffer): Remove.
+ (mips_subword, mips_split_64bit_move_p, mips_split_64bit_move): New.
+ (mips_move_1word, mips_move_2words): Remove, replacing with...
+ (mips_output_move): ...this new function.
+ (mips_restore_gp): Remove insn argument. Adjust for above changes.
+ (print_operand): Make '%h' print %hi(op) for HIGH operands. Remove
+ handling of floating-point constants. Handle zero CONST_DOUBLE
+ arguments.
+ (mips_annotate_frame_insn): Replace with...
+ (mips_set_frame_expr): ...this, which just takes one argument.
+ (mips_frame_set): Change the register argument to an rtx.
+ (mips_emit_frame_related_store): Use mips_split_64bit_move_p to
+ check whether moves should be split. Use mips_split_64bit_move
+ to split them. Use mips_subword to generate the high and low
+ parts of a paired FPR. Adjust calls to frame_set and
+ mips_set_frame_expr.
+ (mips_expand_prologue): Simplify due to above changes.
+ * config/mips/mips.md: Add splitters for 64-bit moves on 32-bit
+ targets, replacing xisting register-only versions.
+ (UNSPEC_STORE_DF_HIGH): New unspec.
+ (UNSPEC_LOAD_DF_LOW, UNSPEC_LOAD_DF_HIGH): New unspecs.
+ (mulsi3_r4000, muldi3_internal2): Avoid use of mips_move_1word.
+ (*paradoxical_extendhidi2): Remove.
+ (movdi_internal, movdi_internal2): Use mips_output_move.
+ (*movdi_internal2_mips16, movsi_internal, movcc): Likewise.
+ (movsf_internal1, movsf_internal2): Likewise.
+ (movdf_internal1a): Likewise. Fix length and type of f <- G case.
+ (movdf_internal1b): Use mips_output_move. Fix type of f <- G case.
+ (movdf_internal2): Use mips_output_move. Fix lengths of FPR moves.
+ Add m <- G alternative.
+ (load_df_low, load_df_high, store_df_low): New patterns.
+ (movhi_internal): Use @ template instead of calling a function.
+ Remove unnecessary 'z' alternatives.
+ (movqi_internal): Likewise.
+ (exception_receiver): Update call to mips_restore_gp.
+
+2003-05-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_simplify_dwarf_addr): Remove.
+ (mips_delegitimize_address): Declare.
+ * config/mips/mips.h (ASM_SIMPLIFY_DWARF_ADDR): Undefine.
+ (FIND_BASE_TERM): Define.
+ * config/mips/mips.c (TARGET_DELEGITIMIZE_ADDRESS): Defi~e.
+ (mips_delegitimize_address): Renamed from mips_simplify_dwarf_addr.
+ Handle small-data addresses.
+
+2003-05-05 Roger Sayle <roger@eyesopen.com>
+
+ * real.c (real_powi): New function to calculate the value of
+ a real raised to an integer power, i.e. pow(x,n) for int n.
+ (real_sqrt): Convert to using the faster do_add, do_multiply
+ and do_divide API for consistency with the rest of real.c.
+ * real.h (real_powi): Prototype here.
+ * builtins.c (fold_builtin): Avoid local variable mode when
+ evaluating sqrt at compile time. Attempt to evaluate pow at
+ compile-time, by checking for an integral exponent.
+
+2003-05-05 Richard Henderson <rth@redhat.com>
+
+ * doc/extend.texi (Variable Attributes): Re-sort table and tidy.
+
+2003-05-05 David O'Brien <obrien@FreeBSD.org>
+
+ * config/rs6000/sysv4.h (CPP_OS_FREEBSD_SPEC): Add __ELF__ to mirror
+ other FreeBSD ports.
+ (LINK_OS_FREEBSD_SPEC): Mirror conventions on other FreeBSD ports.
+ (_LITTLE_ENDIAN): Use __LITTLE_ENDIAN__ instead.
+
+2003-05-05 Janis Johnson <janis187@us.ibm.com>
+
+ * Makefile.in: (site.exp): Add ALT_CC_UNDER_TEST, add quotes around
+ expanded variables.
+ * doc/sourcebuild.texi (C tests): Describe gcc.dg/compat tests.
+
+2003-05-05 Zack Weinberg <zack@codesourcery.com>
+
+ * rtl.h (STRING_POOL_ADDRESS_P): Rename to DEFERRED_CONSTANT_P.
+ * varasm.c (struct varasm_status): Add deferred_constants field.
+ (n_deferred_strings): Delete variable.
+ (n_deferred_constants): New #define.
+ (struct constant_descriptor_tree): Kill next and label fields.
+ (const_hash_table, MAX_HASH_TABLE): Delete.
+ (const_desc_htab): New static variable.
+ (const_hash): Rename const_desc_hash, and make it fit the
+ hashtab.h interface.
+ (const_desc_eq): New.
+ (const_hash_1, compare_constant): Const-ify arguments.
+ (build_constant_desc): Set DEFERRED_CONSTANT_P on all new
+ SYMBOL_REFs. Clarify comments. Don't set desc->label.
+ (output_constant_def): Do the lookup/insert using the
+ hashtab.h interface. Don't muck with n_deferred_constants or
+ DEFERRED_CONSTANT_P here.
+ Always call maybe_output_constant_def_contents.
+ (maybe_output_constant_def_contents): Take a pointer to the
+ descriptor, not the EXP and RTL separately. Return
+ immediately if this constant is not deferred. Defer output of
+ everything, except writable string constants. Update
+ n_deferred_constants here.
+ (output_constant_def_contents): Now takes just one argument,
+ an rtx. Clear DEFERRED_CONSTANT_P here.
+ (mark_constant_pool): Update for rename of n_deferred_strings.
+ (mark_constant): Don't clear DEFERRED_CONSTANT_P here.
+
+ (init_varasm_status): Clear p->deferred_constants.
+ (init_varasm_once): Call htab_create_ggc for const_desc_htab.
+
+2003-05-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (expand_builtin_stpcpy): Only expand when the length
+ of the source string can be evaluated at compile-time.
+
+2003-05-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * testsuite/gcc.c-torture/compile/simd-6.c: New.
+
+ * c-typeck.c (digest_init): Handle arrays of vector constants.
+
+2003-05-05 Jakub Jelinek <jakub@redhat.com>
+
+ * builtins.c (expand_builtin_mempcpy): New function.
+ (expand_builtin_stpcpy): Optimize stpcpy whose return value is
+ ignored into strcpy no matter what arguments it has.
+ (expand_builtin) <case BUILT_IN_MEMPCPY>: Call
+ expand_builtin_mempcpy.
+
+2003-05-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * testsuite/gcc.dg/20030505.c: New.
+
+ * c-typeck.c (convert_for_assignment): Opaque pointers can
+ interconvert.
+
+ * config/rs6000/rs6000.c: New global opaque_p_V2SI_type_node.
+ (rs6000_init_builtins): Initialize opaque_p_V2SI_type_node.
+ (spe_init_builtins): Rename all pv2si_type_node to
+ opaque_p_V2SI_type_node.
+ Remove declaration of pv2si_type_node.
+ (is_ev64_opaque_type): Accept opaque pointers.
+
+2003-05-05 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.c (validate_condition_mode): Use
+ flag_finite_math_only.
+ (rs6000_reverse_condition): Never return UNKNOWN; use
+ flag_finite_math_only.
+ (rs6000_generate_compare): Use flag_finite_math_only.
+ (rs6000_emit_cmove): Handle UNLE. Support UNEQ under -ffast-math.
+ Use HONOR_* rather than flag_unsafe_math_optimizations. Correct
+ UNGE and GT cases. Handle UNEQ and LTGT when ! HONOR_NANS.
+
+ * toplev.c (check_global_declarations): Suppress not-used warning
+ for volatile variables.
+
+2003-05-05 Olivier Hainque <hainque@act-europe.fr>
+
+ * expr.c (expand_expr, case BIT_FIELD_REF): Refine the test forcing
+ usage of bitfield instructions for mode1 != BLKmode, only ignoring
+ SLOW_UNALIGNED_ACCESS if the field is not byte aligned.
+ (store_field): Likewise.
+
+2003-05-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_expand_binop_builtin): Add
+ evsubifw to builtins accepting 5-bit unsigned constants.
+ (easy_vector_constant): Return if V1DImode. Fix typo.
+
+2003-05-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.h: Revert licensing change from last patch.
+
+2003-05-05 DJ Delorie <dj@redhat.com>
+
+ * config/stormy16/stormy16.md (negsi2): Allocate the pseudos
+ before reload, but defer the split until after.
+ * config/stormy16/stormy16.c (xstormy16_expand_arith): Modify
+ to match.
+
+2003-05-05 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.h (ASM_CPU_SPEC): Add 440 support.
+ * config/rs6000/vxworks.h (CC1_SPEC): Use -mcpu=440 for t440.
+
+2003-05-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * libgcov.c (__gcov_merge_add): Do not use gcov_type when inhibit_libc
+ is defined.
+
+2003-05-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtin-attrs.def (ATTR_NOTHROW_NONNULL_1,
+ ATTR_NOTHROW_NONNULL_2, ATTR_NOTHROW_NONNULL_3): Renamed from
+ ATTR_NONNULL_1, ATTR_NONNULL_2 and ATTR_NONNULL_3.
+
+ (ATTR_NOTHROW_NONNULL_1_2, ATTR_NOTHROW_NONNULL_1_4,
+ ATTR_CONST_NOTHROW_NONNULL_1, ATTR_PURE_NOTHROW_NONNULL_1,
+ ATTR_PURE_NOTHROW_NONNULL_1_2, ATTR_MALLOC_NOTHROW_NONNULL_1):
+ New.
+
+ * builtins.def (DEF_EXT_FALLBACK_BUILTIN): Accept ATTRS argument.
+ (BUILT_IN_BZERO, BUILT_IN_BCOPY, BUILT_IN_BCMP): Update comment
+
+ (BUILT_IN_INDEX, BUILT_IN_RINDEX, BUILT_IN_MEMCPY,
+ BUILT_IN_MEMMOVE, BUILT_IN_MEMCMP, BUILT_IN_MEMSET,
+ BUILT_IN_MEMPCPY, BUILT_IN_STRCAT, BUILT_IN_STRNCAT,
+ BUILT_IN_STPCPY, BUILT_IN_STRCPY, BUILT_IN_STRNCPY,
+ BUILT_IN_STRCMP, BUILT_IN_STRNCMP, BUILT_IN_STRLEN,
+ BUILT_IN_STRSTR, BUILT_IN_STRPBRK, BUILT_IN_STRSPN,
+ BUILT_IN_STRCSPN, BUILT_IN_STRCHR, BUILT_IN_STRRCHR, BUILT_IN_NAN,
+ BUILT_IN_NANF, BUILT_IN_NANL, BUILT_IN_NANS, BUILT_IN_NANSF,
+ BUILT_IN_NANSL, BUILT_IN_PUTS, BUILT_IN_FPUTC, BUILT_IN_FPUTS,
+ BUILT_IN_FWRITE, BUILT_IN_PUTS_UNLOCKED, BUILT_IN_FPUTC_UNLOCKED,
+ BUILT_IN_FPUTS_UNLOCKED, BUILT_IN_FWRITE_UNLOCKED,
+ BUILT_IN_STRDUP): Add "nonnull" attribute.
+
+2003-05-04 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (store_field): Don't clobber TEMP in shift: it might be
+ a variable.
+ (get_inner_reference): Don't go through a VIEW_CONVERT_EXPR
+ whose purpose is to step up the alignment.
+ (expand_expr, case ADDR_EXPR): Force LO_SUM into memory, just like REG.
+
+ * stor-layout.c (compute_record_mode): Relax restriction
+ on fields crossing word boundaries forcing BLKmode.
+
+2003-05-04 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppinit.c (cpp_create_reader, post_options): Warn about
+ trigraphs unless explicity set or -trigraphs.
+ * cpplex.c (warn_in_comment): New.
+ (_cpp_process_line_notes): Better handling of -Wtrigraphs.
+ (_cpp_skip_block_comment): Add call to _cpp_process_line_notes.
+ * doc/cppopts.texi, doc/cpp.texi: Update.
+
+2003-05-04 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (LIBGCOV): Add _gcov_merge_add.
+ * gcov-io.h: Make GCOV_LINKAGE extern in libgcov and prevent resulting
+ namespace clash.
+ (GCOV_MERGE_FUNCTIONS): New.
+ (gcov_merge_fn): Declare.
+ (struct gcov_ctr_info): New field "merge".
+ (__gcov_merge_add): Declare.
+ * coverage.c (ctr_merge_functions): New.
+ (build_ctr_info_type, build_ctr_info_value): Initialize merge field
+ of gcov_ctr_info type.
+ * libgcov.c (__gcov_merge_add): New.
+ (gcov_exit): Call a hook to merge values of counters.
+
+2003-05-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * toplev.h (pedwarn_with_file_and_line): Don't declare.
+ * diagnostic.c (pedwarn_with_file_and_line): Remove.
+
+2003-05-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * varasm.c (assemble_variable): Don't use error_with_file_and_line.
+
+2003-05-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (expand_builtin_constant_p, expand_builtin_strlen,
+ expand_builtin_frame_address): Update prototypes.
+ (expand_builtin_constant_p, expand_builtin_strlen,
+ expand_builtin_strcpy, expand_builtin_memset,
+ expand_builtin_bzero, expand_builtin_args_info,
+ expand_builtin_frame_address): Pass in just the argument(s)
+ needed, not the entire expression `exp'.
+ (expand_builtin): Update all calls to these functions.
+
+2003-05-03 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (expand_builtin) <BUILT_IN_DWARF_FP_REGNUM>: Remove.
+ <BUILT_IN_DWARF_SP_COLUMN>: New.
+ * builtins.def (BUILT_IN_DWARF_FP_REGNUM): Remove.
+ (BUILT_IN_DWARF_SP_COLUMN): New.
+ * dwarf2out.c (expand_builtin_dwarf_fp_regnum): Remove.
+ (expand_builtin_dwarf_sp_column): New.
+ * except.h: Update to match.
+ * unwind-dw2.c (execute_stack_op): Correct stack push typo.
+ (execute_cfa_program): Record location expression address
+ before extracting length.
+ (uw_update_context_1): Install old CFA into stack pointer column.
+ (uw_init_context_1): Set cfa_reg to stack pointer column.
+
+2003-05-03 Richard Henderson <rth@redhat.com>
+
+ * config/rs6000/rs6000.c (constant_pool_expr_p): Make static and
+ return bool.
+ (toc_relative_expr_p): Likewise.
+ (SPE_CONST_OFFSET_OK): Move from rs6000.h.
+ (legitimate_constant_pool_address_p): Move from rs6000.h, change
+ into a function, downcase all users.
+ (legitimate_small_data_p): Likewise.
+ (legitimate_offset_address_p): Likewise.
+ (legitimate_indexed_address_p): Likewise.
+ (legitimate_indirect_address_p): Likewise.
+ (legitimate_lo_sum_address_p): Likewise.
+ (rs6000_mode_dependent_address): Likewise.
+ * rs6000.h (CONSTANT_POOL_EXPR_P, TOC_RELATIVE_EXPR_P): Remove.
+ (SPE_CONST_OFFSET_OK, LEGITIMATE_CONSTANT_POOL_ADDRESS_P,
+ LEGITIMATE_SMALL_DATA_P, LEGITIMATE_OFFSET_ADDRESS_P,
+ LEGITIMATE_INDEXED_ADDRESS_P, LEGITIMATE_INDIRECT_ADDRESS_P,
+ LEGITIMATE_LO_SUM_ADDRESS_P): Move into rs6000.c.
+ (LEGITIMATE_ADDRESS_INTEGER_P): Remove.
+ (GO_IF_MODE_DEPENDENT_ADDRESS): Use rs6000_mode_dependent_address.
+ * config/rs6000/rs6000-protos.h: Update.
+
+2003-05-03 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.h (REVERSIBLE_CC_MODE): Define.
+ (REVERSE_CONDITION): Define.
+
+ * config/rs6000/rs6000.c (scc_comparison_operator): Make equivalent
+ to branch_positive_comparison_operator.
+ (ccr_bit): Check that sCOND conditions are actually a positive bit.
+ (print_operand): Remove %D substitution.
+ (rs6000_emit_sCOND): Generate complement operation to ensure that
+ sCOND input is a positive bit.
+ * config/rs6000/rs6000.md: Rearrange sCOND templates to be in the
+ same order as bCOND, and add the missing ones. Remove the %D
+ substitutions from the scc patterns.
+
+ * simplify-rtx.c (simplify_relational_operation): Add case for
+ ! (fabs(x) < 0.0).
+
+2003-05-03 Bruce Korb <bkorb@gnu.org>
+
+ * gcc/fixinc/fixincl.tpl(dne): restore this to force merge conflicts
+ in fixincl.x
+ * gcc/fixinc/inclhack.def(bsd_stdio_attrs_conflict): fix placement
+
+2003-05-03 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.h: Remove unecessary casts. Misc cleanups.
+
+2003-05-03 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/10604
+ * c-common.c (warn_sign_compare): Initialize to -1.
+ * c-opts.c (c_common_init_options): Don't set warn_sign_compare here.
+ (c_common_decode_option <OPT_Wall>): Set warn_sign_compare
+ for C++ only.
+ (c_common_post_options): Set warn_sign_compare from extra_warnings
+ if it's still -1 at this point.
+
+ * toplev.c (maybe_warn_unused_parameter): New static variable.
+ (set_Wextra): New static function.
+ (W_options): Remove "extra".
+ (decode_W_option): Call set_Wextra.
+ (independent_decode_option): Likewise.
+ (set_Wunused): Cooperate with set_Wextra in setting
+ warn_unused_parameter.
+ (rest_of_compilation): No need to check extra_warnings as
+ well as warn_uninitialized.
+
+ * c-typeck.c (build_binary_op, build_conditional_expr):
+ No need to check extra_warnings as well as warn_sign_compare.
+ (internal_build_compound_expr): No need to check extra_warnings
+ as well as warn_unused_value.
+ * function.c (expand_function_end): No need to check extra_warnings
+ as well as warn_unused_parameter.
+ * stmt.c (expand_expr_stmt_value): No need to check extra_warnings
+ as well as warn_unused_value.
+
+ * doc/invoke.texi: Clarify documentation of -Wsign-compare.
+
+ * Makefile.in: Disable -Werror for gengtype-lex.o.
+
+2003-05-03 Olivier Hainque <hainque@act-europe.fr>
+
+ * emit-rtl.c (last_call_insn, add_function_usage_to): New functions.
+ * rtl.h (last_call_insn, add_function_usage_to): New prototypes.
+ * builtins.c (expand_builtin_apply): Use the new emit-rtl functions.
+ * calls.c (emit_call_1): Likewise.
+ (expand_call): For calls initializing constant memory, replace
+ emission of standalone mem /u clobber with function usage entry.
+ * expr.c (emit_block_move_via_libcall): Likewise.
+ * cse.c (count_reg_usage, case EXPR_LIST): New case.
+ * flow.c (propagate_one_insn): Pass entire operand of
+ CALL_INSN_FUNCTION_USAGE to mark_used_regs.
+ * integrate.c (try_constants): For CALL_INSNs, substitute constants
+ within the FUNCTION_USAGE also.
+ * loop.c (prescan_loop): Note clobbers of const mem mentioned in
+ FUNCTION_USAGE lists.
+ * reload1.c (replace_pseudos_in): Renamed.
+ (reload): Use it for clobbers surviving until the end of the reload.
+
+2003-05-03 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (expand_expr, case VIEW_CONVERT_EXPR): Don't use
+ gen_lowpart on non-integer modes.
+
+ * stor-layout.c (place_field): When adjusting offset_align, use
+ desired_align, not DECL_ALIGN.
+
+2003-05-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * c-decl.c (pending_invalid_xref_file): Remove.
+ (pending_invalid_xref_line): Remove.
+ (pending_invalid_xref_location): New.
+ (lookup_label): Use location_t and input_location directly.
+ (lookup_tag): Likewise.
+ (pending_xref_error): Likewise.
+ (c_expand_body_1): Likewise.
+ * c-common.c (x_expand_start_cond): Likewise.
+ * c-semantics.c (genrtl_for_stmt): Likewise.
+ (find_reachable_label): Likewise.
+ * expr.c (expand_expr): Likewise.
+ * integrate.c (output_inline_function): Likewise.
+ * tree-inline.c (find_alloca_call): Likewise.
+ (find_builtin_longjmp_call): Likewise.
+ * gcc.c (input_filename): Make static.
+
+2003-05-03 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md: Fix comment typo.
+
+ * config/mips/mips.c (mips_integer_op): New structure.
+ (MIPS_MAX_INTEGER_OPS): Define.
+ (mips_const_insns): Use mips_build_integer to determine the number
+ of instructions needed to load a CONST_INT.
+ (move_operand): Reject compound CONST_INTs.
+ (mips_build_shift, mips_build_lower, mips_build_integer): New fns.
+ (mips_move_integer): New fn.
+ (mips_legitimize_const_move): Pass CONST_INTs to mips_move_integer.
+ (mips_legitimize_move): Only legitimize constants when moving
+ word or subword values.
+
+2003-05-02 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * Makefile.in (gcov-iov.h): Use move-if-change and a stamp.
+
+2003-05-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (expand_builtin_stpcpy): Copy `arglist' before
+ modifying it.
+
+2003-05-03 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+ Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/contrib.texi (Contributors): Add Zdenek Dvorak, Aldy
+ Hernandez, and Kazu Hirata. Update Richard Henderson.
+
+2003-05-02 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_attribute_table): Add 'extern'
+ to tentative declaration.
+
+ * config/rs6000/sysv4.h (SYMBOL_FLAG_SMALL_V4): Delete.
+ (SYMBOL_FLAG_SMALL_V4): Delete.
+ * config/rs6000/rs6000.c (small_data_operand): Use SYMBOL_REF_SMALL_P.
+ (rs6000_elf_encode_section_info): Don't set SYMBOL_FLAG_SMALL_V4.
+ (rs6000_elf_in_small_data_p): Add extra section names. Add
+ comment about TREE_PUBLIC test.
+
+ * c-semantics.c (genrtl_switch_stmt, genrtl_if_stmt): Call
+ expand_stmt on result of expand_unreachable_stmt.
+
+2003-05-02 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/contrib.texi (Contributors): Add Daniel Berlin.
+
+2003-05-02 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/{603.md,6xx.md,7450.md,7xx.md,rs64.md}: Decrease
+ number of automata.
+
+ * config/rs6000/rs6000.c (symbol_ref_operand): Check
+ SYMBOL_REF_FUNCTION_P on AIX.
+ (current_file_function_operand): Same.
+ * config/rs6000/rs6000.md (call,call_value): Force non-function
+ symbol_ref into register on AIX.
+
+2003-05-02 Alan Modra <amodra@bigpond.net.au>
+
+ * calls.c (struct arg_data): Move offset, slot_offset, size and
+ alignment_pad to struct locate_and_pad_arg_data. Update all refs.
+ (initialize_argument_information): Adjust call to locate_and_pad_parm.
+ Delete alignment_pad var. Don't calculate slot_offset here.
+ (emit_library_call_value_1): Delete alignment_pad, offset and size
+ vars. Use struct locate_and_pad_arg_data instead. Adjust refs.
+ Adjust call to locate_and_pad_parm. Don't tweak arg size for
+ partial in-regs here. Formatting fixes.
+ * expr.h (struct locate_and_pad_arg_data): New struct.
+ (locate_and_pad_parm): Adjust declaration.
+ * function.c (assign_parms): Localize vars. Use "locate" instead of
+ other arg location vars. Don't invoke FUNCTION_ARG or
+ FUNCTION_INCOMING_ARG unless pretend_named is different from
+ named_arg. Heed MUST_PASS_IN_STACK and set up "partial" before
+ calling locate_and_pad_parm. Adjust locate_and_pad_parm call.
+ Use slot_offset for stack home of reg parms. Correct test for
+ parm passed in memory. Formatting fixes.
+ (locate_and_pad_parm): Add "partial" to params. Replace offset_ptr
+ arg_size_ptr and alignment pad with "locate". Set slot_offset here.
+ Correct initial_offset_ptr handling. Localize vars. Always pad
+ locate->offset even when in_regs.
+
+2003-05-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * Makefile.in (TREE_H): Replace location.h with input.h.
+ (GTFILES) Remove location.h
+ (gt-lists.h): Replace gt-location.h with gt-input.h
+ * input.h (input_filename, input_line): Remove variables.
+ (location_s, location_t): Move from location.h.
+ (input_location): New.
+ (input_filename, input_line): New #defines.
+ * location.h: Remove.
+ * tree.h: Replace location.h with input.h.
+ (input_filename, input_line): Remove.
+ * diagnostic.h: Replace location.h with input.h.
+ * gcc.h (input_filename, input_filename_length): Remove declarations.
+ * toplev.c (input_filename, input_line): Remove.
+ (input_location): Define.
+ (push_srcloc, pop_srcloc): Adjust.
+ * diagnostic.c (diagnostic_report_current_module): Adjust.
+
+2003-05-02 Nick Clifton <nickc@redhat.com>
+
+ * configure.in: Add xstormy16 to list of targets that has a nop
+ instruction and hence which can be tested to see if the
+ assembler supports the --gdwarf2 switch.
+ * configure: Regenerate.
+
+2003-05-01 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ PR target/8257
+ * config/alpha/alpha.c (alpha_sa_mask, alpha_expand_prologue,
+ alpha_start_function, alpha_expand_epilogue, unicosmk_gen_dsib):
+ Avoid undefined shifts by making the shift operand unsigned.
+
+2003-05-01 DJ Delorie <dj@redhat.com>
+
+ * reload.c (find_reloads): Also check that all of a multi-reg
+ value is in the class.
+
+2003-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * scan.h (lineno): Revert the rename here.
+
+2003-05-01 Stan Shebs <shebs@apple.com>
+
+ * config/darwin.c (darwin_encode_section_info): Call
+ default_encode_section_info.
+
+2003-05-01 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (define_attr "type"): Add mfjmpr.
+ (movsi_internal1): Use new mfjmpr attribute.
+ (movhi_internal): Same.
+ (movqi_internal): Same.
+ (movcc_internal1): Same.
+ (movdi_internal64): Same.
+ * config/rs6000/{40x.md,603.md,6xx.md,7450.md,7xx.md,mpc.md,
+ power4.md,rios1.md,rios2.md,rs64.md}: Add mfjmpr.
+ * config/rs6000/40x.md: Add fpu_405.
+ * config/rs6000/power4.md: Merge power4lsu and power4disp automata
+ into power4misc automata. Remove extraneous parentheses.
+ * config/rs6000/440.md: New file.
+ * config/rs6000/rs6000.c (processor_target_table): Add 440,
+ 440fp. Rename 405f to 405fp.
+ (function_arg_padding): Correct formatting.
+ (rs6000_rtx_costs): Add PROCESSOR_PPC440 cases.
+
+2003-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * input.h (lineno): Rename to ...
+ (input_line): ... here.
+ * tree.h (lineno): Rename to ...
+ (input_line): ... here.
+ * scan.h (lineno): Rename to ...
+ (input_line): ... here.
+ * toplev.c (lineno): Rename to ...
+ (input_line): ... here.
+ (push_srcloc, pop_srcloc): Rename lineno to input_line.
+ * c-common.c (c_expand_start_cond, fname_decl): Likewise.
+ * c-decl.c (poplevel, pop_label_level, lookup_label, lookup_tag,
+ store_parm_decls, c_expand_body_1): Likewise.
+ * c-errors.c (pedwarn_c99): Likewise.
+ * c-format.c (status_warning): Likewise.
+ * c-lex.c (fe_file_change, cb_def_pragma, c_lex): Likewise.
+ * c-opts.c (c_common_post_options, c_common_parse_file): Likewise.
+ * c-parse.in (save_filename, maybe_type_qual, ifc): Likwise.
+ * c-semantics.c (finish_stmt_tree, build_stmt, emit_local_var,
+ gentrtl_goto_stmt, genrtl_expr_stmt_value, genrtl_decl_stmt,
+ genrtl_if_stmt, genrtl_while_stmt, genrtl_do_stmt,
+ genrtl_return_stmt, genrtl_for_stmt, build_break_stmt,
+ build_continue_stmt, genrtl_switch_stmt, genrtl_asm_stmt,
+ prep_stmt, find_reachable_label, expand_unreachable_stmt): Likewise.
+ * coverage.c (create_coverage): Likewise.
+ * diagnostic.c (pedwarn, sorry, error, fatal_error,
+ internal_error, warning, diagnostic_report_current_module,
+ inform): Likewise.
+ * expr.c (expand_expr): Likewise.
+ * integrate.c (expand_inline_function,
+ output_inline_function): Likewise.
+ * rtl-error.c (file_and_line_for_asm): Likewise.
+ * tree-inline.c (find_alloca_call, find_builtin_longjmp_call,
+ walk_tree): Likewise.
+ * tree.c (make_node): Likewise.
+ * ada, cp, f, java, objc, treelang: Likewise.
+ * objc/objc-act.c (objc_init): Rename lineno to input_line.
+ (build_module_descriptor, build_selector_translation_table,
+ build_protocol_template, build_method_prototype_list_template,
+ build_category_template, build_selector_table,
+ build_class_template, build_super_template, build_ivar_template,
+ build_ivar_list_template, build_method_list_template,
+ build_method_template, add_instance_variable): Likewise.
+
+ * dwarf2out.c (dwarf2out_init, dwarf2out_finish): Change parameter
+ name from input_filename.
+
+2003-04-30 Eric Christopher <echristo@redhat.com>
+ Richard Sandiford <rsandifo@redhat.com>
+
+ * configure: Regenerate from patches below.
+ * combine.c (gen_lowpart_for_combine): Fix comment and add tests
+ for all symbolic operands.
+ * config/mips/mips.c: Migrate RTX_COSTS and CONST_COSTS
+ to function.
+ * config/mips/linux.h: Fix typo.
+ * Merge from mips-3_4-rewrite branch:
+
+ 2003-04-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_classify_symbol): Add catch-all case for
+ handling local labels when TARGET_ABICALLS.
+
+ 2003-04-04 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_expand_epilogue): Add an
+ integer argument.
+ (mips_expand_call): Likewise.
+ * config/mips/mips.h (TARGET_SIBCALLS): New macro.
+ (FIXED_REGISTERS): Clear $31 entry.
+ (CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTER): Likewise.
+ (EPILOGUE_USES): Define.
+ * config/mips/mips.c (mips_function_ok_for_sibcall): New function.
+ (TARGET_FUNCTION_OK_FOR_SIBCALL): Use it.
+ (override_options): Add a 'j' register class.
+ (mips_expand_call): Handle sibcalls
+ (mips_expand_epilogue): Handle epilogues for sibcalls.
+ * config/mips/mips.md (epilogue): Adjust call to mips_expand_epilogue.
+ (sibcall_epilogue): New pattern.
+ (call, call_value): Adjust calls to mips_expand_call.
+ (sibcall, sibcall_value): New expanders.
+ (sibcall_internal, sibcall_value_internal): New patterns.
+ (sibcall_value_multiple_internal): New pattern.
+
+ 2003-03-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (extended_mips16): New attribute.
+ (define_attr length): Default to 8 if extended_mips16 == yes.
+ (truncdisi2): Set extended_mips16 to yes for the sll alternative.
+ (truncdihi2, truncdiqi2, *extendsidi2): Likewise.
+ (call_internal): Set extended_mips16 to yes for direct jumps.
+ Remove redundant mode attribute.
+ (call_value_internal, call_value_multiple_internal): Likewise.
+ (call_split): Remove redundant mode attribute.
+ (call_value_split, call_value_multiple_split): Likewise.
+
+ * config/mips/mips.c (mips_symbol_insns): Rework. Fix handling
+ of unaligned offsets.
+
+ * config/mips/mips.c (mips_splittable_symbol_p): Fix handling
+ of SYMBOL_GENERAL.
+
+ 2003-03-22 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (TARGET_EXPLICIT_RELOCS): Add commentary.
+ * config/mips/mips.c (override_options): Disable -mexplicit-relocs
+ for mips16 code.
+
+ 2003-03-22 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (ADDRESS_COST): Define.
+
+ 2003-03-20 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (EXTRA_CONSTRAINT): Give existing meaning of
+ 'R' to 'U'. Make 'R' mean a single-instruction memory reference.
+ * config/mips/mips.md: Replace 'R' constraints with 'U'.
+
+ 2003-03-18 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (truncdisi2): Add commentary. Use sll instead
+ of a two-instruction sequence. Add register->memory alternative.
+ (truncdihi2, truncdiqi2): Likewise.
+ Rework shift/truncate instructions so that they only handle right
+ shifts of 32 (or more, in the case of arithmetic shifts).
+ Add patterns for truncate/sign-extend.
+
+ 2003-03-13 Richard Sandiford <rsandifo@redhat.com>
+
+ * configure.in (mips*-*-*): Check for explicit relocation support.
+ * configure: Regenerate.
+
+ 2003-03-13 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (TARGET_SWITCHES): Add -mexplicit-relocs
+ and -mno-explicit-relocs.
+ (MASK_EXPLICIT_RELOCS): Define.
+ (TARGET_EXPLICIT_RELOCS): Use it.
+ (mips_split_addresses): Remove declaration.
+ * config/mips/mips.c (override_options): Update comment for
+ mips_split_addresses. Clear MASK_EXPLICIT_RELOCS for non-PIC n64.
+
+ 2003-03-13 Richard Sandiford <rsandifo@redhat.com>
+
+ * combine.c (gen_lowpart_for_combine): Treat the lowpart Pmode of
+ a CONST as identity. Check the return value of gen_lowpart_common.
+
+ 2003-03-13 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_legitimize_symbol): Handle small data
+ references for TARGET_EXPLICIT_RELOCS.
+ (mips_reloc_string): Return "%gp_rel(" for RELOC_GPREL16 if
+ !TARGET_MIPS16.
+
+ 2003-03-13 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md: Replace 'IQ' mips16 constraints with just 'Q'.
+ (addsi3): Remove redundant constraints.
+ (addsi3_internal): Use separate register & constant alternatives.
+ Use a 'Q' constraint and "addiu" insn for the latter.
+ (adddi3_internal_3, addsi3_internal_2): Likewise.
+
+ 2003-03-13 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_expand_unaligned_load): Declare.
+ (mips_expand_unaligned_store): Declare.
+ * config/mips/mips.c (mips_get_unaligned_mem): New fn.
+ (mips_expand_unaligned_load, mips_expand_unaligned_store): New fns.
+ * config/mips/mips.md (UNSPEC_ULW, UNSPEC_USW): Remove.
+ (UNSPEC_ULD, UNSPEC_USD): Remove.
+ (UNSPEC_LWL, UNSPEC_LWR, UNSPEC_SWL, UNSPEC_SWR): New.
+ (UNSPEC_LDL, UNSPEC_LDR, UNSPEC_SDL, UNSPEC_SDR): New.
+ (extv, extzv): Use mips_expand_unaligned_load.
+ (insv): Use mips_expand_unaligned_store. Use a reg_or_0_operand
+ predicate for operand 3.
+ (movsi_ulw, movsi_usw): Replace with...
+ (mov_lwl, mov_lwr, mov_swl, move_swr): ...these new insns.
+ (movdi_uld, movdi_usd): Likewise replace with...
+ (mov_ldl, mov_ldr, mov_sdl, move_sdr): ...these insns.
+
+ 2003-02-26 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_global_pic_constant_p): Declare.
+ * config/mips/mips.h (LEA_REGS): New register class.
+ (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add entries for it.
+ (GR_REG_CLASS_P): Include LEA_REGS.
+ (DANGEROUS_FOR_LA25_P): New macro.
+ (EXTRA_CONSTRAINT): Add !DANGEROUS_FOR_LA25_P to R's condition.
+ Add a T constraint for the DANGEROUS_FOR_LA25_P case.
+ * config/mips/mips.c (mips_regno_to_class): Change GR_REGS
+ entries to LEA_REGS.
+ (mips_global_pic_constant_p): New function.
+ (override_options): Add 'e' register constraint.
+ (mips_secondary_reload_class): Return LEA_REGS when reloading
+ a dangerous constant into a class containing $25.
+ * config/mips/mips.md (movdi_internal2): Add an e <- T alternative.
+ (movsi_internal): Likewise.
+
+ 2003-02-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (TARGET_SPLIT_CALLS): New macro.
+ * config/mips/mips.md (call_split): New insn.
+ (call_value_split, call_value_multiple_split): New insns.
+ (call_internal): Turn into a define_insn_and_split. Split the
+ instruction into a call and $gp load if TARGET_SPLIT_CALLS.
+ (call_value_internal, call_value_multiple_internal): Likewise.
+
+ 2003-02-23 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_reloc_string): Return "%got(" for
+ RELOC_GOT_PAGE and RELOC_GOT_DISP if !TARGET_NEWABI.
+ (mips_encode_section_info): Don't take symbol visibility into
+ account if TARGET_ABICALLS. Add more commentary.
+ * config/mips/mips.md: Add commentary above reloc constants.
+
+ 2003-02-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_legitimize_const_move): New, extracted
+ from mips_legitimize_move. Legitimize constant pool references.
+ (mips_legitimize_move): Call mips_legitimize_const_move. Attach
+ a REG_EQUAL note to the last instruction.
+
+ 2003-02-11 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_simplify_dwarf_addr): Declare.
+ * config/mips/mips.h (TARGET_EXPLICIT_RELOCS, TARGET_NEWABI): New.
+ (ASM_SIMPLIFY_DWARF_ADDR): Define to mips_simplify_dwarf_addr.
+ (EXTRA_CONSTRAINT): Allow symbolic call addresses for TARGET_ABICALLS.
+ * config/mips/mips.md (UNSPEC_HIGH): New constant.
+ (UNSPEC_RELOC_GPREL16): Rename to...
+ (RELOC_GPREL16): ...this.
+ (RELOC_GOT_HI, RELOC_GOT_LO, RELOC_GOT_PAGE, RELOC_GOT_DISP): New.
+ (RELOC_CALL16, RELOC_CALL_HI, RELOC_CALL_LO): New.
+ (macro_calls): New attribute.
+ (length): Use it to set the default length of calls. Don't allow
+ calls to have delay slots if macro_calls is "yes".
+ (luisi, luidi): New patterns.
+ (lowsi, lowdi): Use '%R' to print the relocation.
+ (lowdi_extend): Remove.
+ (loadgp): Remove mode from operand 0. Use '%0' instead of '%a0'.
+ (call_internal): Merge alternatives. Always use "jal".
+ (call_value_internal, call_value_multiple_internal): Likewise.
+ (reloc_gprel16): Remove.
+ * config/mips/mips.c (mips_got_alias_set): New variable.
+ (mips_classify_constant): Handle the new relocation constants.
+ (mips_classify_symbol): Reverse the sense of SYMBOL_REF_FLAG for PIC.
+ (mips_symbolic_address_p): Return false if generating explicit relocs.
+ Otherwise allow local PIC symbols to have an offset.
+ (mips_splittable_symbol_p): New function.
+ (mips_classify_address): Use it to check whether a LO_SUM is valid.
+ (mips_const_insns): Always accept HIGH.
+ (call_insn_operand): Don't accept global symbols if using explicit
+ relocs.
+ (move_operand): Don't accept HIGH when generating PIC.
+ (mips_reloc, mips_lui_reloc): New functions.
+ (mips_force_temporary): Remove MODE argument. Expect VALUE to
+ be a valid right-hand-side for a SET pattern.
+ (mips_load_got, mips_load_got16, mips_load_got32): New functions.
+ (mips_emit_high): New function.
+ (mips_legitimize_symbol): Use mips_reloc for the mips16 gp-relative
+ case. Use mips_splittable_symbol_p to check whether a LO_SUM
+ address should be used. Use mips_emit_high to generate the
+ high part of such an address. Adjust the global symbol + offset
+ case to match the change to mips_force_temprorary.
+ (mips_legitimize_move): Shuffle call to mips_legitimize_symbol.
+ If generating explicit-reloc PIC, load the address of global
+ symbols from the GOT. Use mips_emit_high to emit the high part
+ of an address.
+ (mips_simplify_dwarf_addr): New function.
+ (mips_move_1word): Use lwc1 instead of l.s and swc1 instead of s.s.
+ (mips_move_2words): Likewise ldc1/l.d and sdc1/s.d if TARGET_64BIT.
+ (mips_expand_call): Load the addresses of global functions using
+ %call* relocs if generating explicit-reloc PIC. Don't generate
+ an exception_receiver pattern.
+ (override_options): Initialize mips_got_alias_set.
+ (print_relocation): Remove in favor of...
+ (mips_reloc_string): ...this new function.
+ (print_operand): Handle '%R'. Use mips_reloc_string.
+ (print_operand_address): Use print_operand to print the symbolic
+ part of a LO_SUM address.
+ (mips_output_function_prologue): Use .cprestore, reverting last patch.
+ (mips_encode_section_info): Factor out DECL_RTL accesses. Reverse
+ sense of SYMBOL_REF_FLAG for PIC, using binds_local_p to check
+ for local symbols.
+
+ 2003-02-02 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.c (mips_sign_extend): Remove.
+ * config/mips/mips-protos.h: Ditto.
+ * config/mips/mips.md (movdi_internal2_extend): Remove.
+ (extendsidi2): Fix mode of convert_memory_address.
+
+ 2003-01-24 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.md: Rewrite zero_extend* and extend*
+ patterns. Use explicit instructions and split after reload
+ for register extensions.
+ (ashlsi3_internal1_extend): New combiner pattern for
+ shift and extend combinations.
+ * config/mips/mips.h: Change Pmode back to ptr_mode
+ for performance enhancement.
+ * combine.c (expand_compound_operation): Make sure
+ that zero_extend operation is profitable.
+
+ 2003-01-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (TRAMPOLINE_TEMPLATE): Make size of stored
+ addresses depend on ptr_mode rather than Pmode.
+ (TRAMPOLINE_SIZE, TRAMPOLINE_ALIGNMENT): Update acoordingly.
+ (INITIALIZE_TRAMPOLINE): Rework to handle Pmode != ptr_mode.
+ (CASE_VECTOR_MODE): Use ptr_mode for !TARGET_MIPS16.
+ (ASM_OUTPUT_ADDR_VEC_ELT): Update accordingly.
+ * config/mips/mips.md (tablejump): Likewise. Remove Pmode
+ condition for selecting cpaddsi or cpadddi: use cpadd instead.
+ (tablejump_internal1): Remove condition.
+ (tablejump_internal2): Change condition to TARGET_64BIT.
+ (cpaddsi): Rename to...
+ (cpadd): ...this.
+ (cpadddi): Remove.
+
+ 2003-01-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips16_constant_after_function_p,
+ mips_address_cost, mips_check_split, double_memory_operand,
+ mips16_gp_offset, mips16_gp_offset_p, mips16_constant,
+ pic_address_needs_scratch, symbolic_operand): Remove declarations.
+ (mips_legitimate_address_p): Return bool.
+ (mips_address_insns, mips_fetch_insns, mips_const_insns,
+ mips_legitimize_address, mips_legitimize_move,
+ mips_expand_call): Declare.
+ (mips_return_addr): Move outside #ifdef RTX_CODE.
+
+ * config/mips/mips.h (ABI_HAS_64BIT_SYMBOLS): New macro.
+ (PIC_FN_ADDR_REG): New reg_class.
+ (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add corresponding entries.
+ (GR_REG_CLASS_P): True for PIC_FN_ADDR_REG.
+ (SMALL_OPERAND, SMALL_OPERAND_UNSIGNED, LUI_OPERAND,
+ CONST_HIGH_PART, CONST_LOW_PART, LUI_INT): New macros.
+ (SMALL_INT, SMALL_INT_UNSIGNED, CONST_OK_FOR_LETTER_P): Use new macros.
+ (EXTRA_CONSTRAINTS): Give new meanings to Q, R and S.
+ (CONSTANT_ADDRESS_P): Use mips_legitimate_address_p.
+ (LEGITIMATE_PIC_OPERAND): Undefine.
+ (LEGITIMATE_CONSTANT_P): Use mips_const_insns.
+ (LEGITIMIZE_ADDRESS): Use mips_legitimize_address.
+ (CONSTANT_AFTER_FUNCTION_P): Remove definition in #if 0 block.
+ (FUNCTION_MODE): Change to SImode.
+ (CONST_COSTS): Use mips_const_insns to calculate the cost of
+ most constants. Treat const_artih_operands specially if they
+ occur in a PLUS or MINUS.
+ (CONSTANT_POOL_COST): New macro.
+ (RTX_COSTS): Use mips_address_insns for MEMs, with a base cost of 2.
+ Add LO_SUM handling.
+ (ADDRESS_COST): Undefine.
+ (PREDICATE_CODES): Add symbolic_operand and const_arith_operand.
+ Add CONST to the list of codes for arith_operand. Add LABEL_REF
+ to call_insn_operand and remove CONST_INT.
+
+ * config/mips/mips.c: Include integrate.h.
+ (SINGLE_WORD_MODE_P): New macro.
+ (mips_constant_type, mips_symbol_type, mips_address_type): New enums.
+ (mips_constant_info, mips_address_info): New structs.
+ (mips_regno_to_class): Map $25 to PIC_FN_ADDR_REG.
+ (mips_classify_constant, mips_classify_symbol,
+ mips_valid_base_register_p, mips_symbolic_address_p,
+ mips_classify_address, mips_symbol_insns,
+ mips16_unextended_reference_p, mips_address_insns, mips_const_insns,
+ mips_fetch_insns, mips_force_temporary, mips_add_offset,
+ mips_legitimize_symbol, mips_legitimize_address, mips_legitimize_move,
+ mips_print_relocation): New functions.
+ (const_arith_operand): New operand predicate.
+ (arith_operand): Use it.
+ (mips_const_double_ok, mips16_simple_memory_operand,
+ simple_memory_operand, double_memory_operand, mips_check_split,
+ mips_address_cost, pic_address_needs_scratch, mips16_gp_offset,
+ mips16_gp_offset_p, mips16_output_gp_offset,
+ mips16_constant_after_function_p, mips16_constant): Remove.
+ (call_insn_operand): Be more fussy about symbolic constants.
+ Use register_operand.
+ (move_operand): Use mips_symbolic_address_p to check symbolic
+ operands and general_operand to check the rest.
+ (symbolic_operand): Use mips_classify_constant.
+ (mips_legitimate_address_p): Use mips_classify_address.
+ (mips_move_1word): Combine handling of symbolic addresses.
+ Remove special treatment of gp-relative loads for TARGET_MIPS16.
+ (move_move_2words): Likewise. Assume addresses are offsettable
+ if they need to refer to more than one word. Add HIGH handling.
+ (mips_restore_gp): Use ptr_mode for the GP save slot.
+ (mips_expand_call): New function, combining the old mips.md
+ call and call_internal define_expands. If the address isn't
+ a call_insn_operand, force it into a register. For SVR4 PIC,
+ emit an exception_receiver instruction after the call.
+ (override_options): Only override flag_pic for TARGET_ABICALLS
+ if it is currently zero. Allow mips_split_addresses when
+ Pmode == DImode too, except when ABI_HAS_64BIT_SYMBOLS.
+ Add new register class letter, 'c'.
+ (print_operand): Use mips_classify_constant for constant operands.
+ (print_operand_address): Use mips_classify_address.
+ (mips_output_function_prologue): Don't use .cprestore.
+ (mips_expand_epilogue): For TARGET_MIPS16, only adjust the stack
+ via the frame pointer if current_function_calls_eh_return.
+ (mips_encode_section_info): For TARGET_ABICALLS, use SYMBOL_REF_FLAG
+ to mark whether a symbol is local or global.
+ (build_mips16_call_stub): Expect the address of the function rather
+ than a MEM reference to it. Update call generation sequences.
+ (mips16_optimize_gp): Remove Pmode checks. Temporarily disable
+ small-data adjustments.
+
+ * config/mips/mips.md: Remove 'R'/'m' memory distinction. Use default
+ length for loads and stores.
+ (UNSPEC_CPADD, UNSPEC_RELOC_GPREL16): New constants.
+ (define_attr type): Add const and prefetch.
+ (define_attr length): Use mips_const_insns for const instructions.
+ Use mips_fetch_insns for load and store instructions.
+ (define_attr single_insn): New.
+ (define_attr can_delay): Use it.
+ (define_attr abicalls): Remove.
+ (define_delay): Use can_delay. Always allow calls to have delay slots.
+ (addsi3_internal_2): Add 'Q' constraint.
+ (movsi_ulw, movsi_usw, movdi_uld, movdi_usd): Set length to 8.
+ (high): Remove.
+ (lowsi): Renamed from low.
+ (lowdi): New pattern.
+ (movdi, movsi): Use mips_legitimize_move. Remove define_split.
+ (lwxc1, ldxc1, swxc1, sdxc1): Set length to 4.
+ (loadgp): Change operand 0 to an immediate_operand.
+ (tablejump): Use the same patterns for SVR4 PIC but emit a cpadd
+ beforehand.
+ (cpaddsi, cpadddi): New patterns.
+ (tablejump_internal3, tablejump_internal4): Remove define_expands
+ and associated define_splits.
+ (call, call_value): Use mips_expand_call.
+ (call_internal): New, replacing all existing call_internal* insns.
+ (call_value_internal): Likewise call_value_internal*.
+ (call_value_multiple_internal): Likewise call_value_multiple_internal*.
+ (untyped_call): Remove if (operands[0]) magic.
+ (prefetch_si_address, prefetch_si): Change type to "prefetch".
+ (prefetch_di_address, prefetch_di): Likewise.
+ (leasi, leadi): Remove.
+ (reloc_gprel16): New.
+
+ * config/mips/5400.md (ir_vr54_hilo): Include const type.
+ * config/mips/5500.md (ir_vr55_hilo): Likewise.
+ * config/mips/sr71k.md (ir_sr70_hilo): Likewise.
+
+ 2003-01-08 Eric Christopher <echristo@redhat.com>
+
+ * config.gcc (mipsisa32*): Change ABI_MEABI to ABI_EABI.
+ * config/mips/elf.h (STARTFILE_SPEC): Remove ABI_MEABI references and
+ configure check for libgloss.
+ * config/mips/elf64.h: Ditto.
+ * config/mips/mips.c: Remove ABI_MEABI.
+ * config/mips/mips.h: Ditto.
+
+ 2002-11-05 Richard Sandiford <rsandifo@redhat.com>
+
+ Fix merge fallout.
+ * config/mips/mips.md (mul_acc_si): Reapply 2002-10-16 change.
+ (muldi3_internal): Remove outdated comment.
+ (*muls_di, *umuls_di): Fix comment and 64-bitness.
+ (*smsac_di, *umsac_di): Likewise. Reformat.
+ (umulsi3_highpart): Minor formatting tweaks.
+ (umulsi3_highpart_internal): Use only if !ISA_HAS_MULHI. Remove
+ redundant scratch operand. Minor formatting tweak.
+ (umulsi3_highpart_mulhi_internal): Use for !TARGET_64BIT as well.
+ (umulsi3_highpart_neg_mulhi_internal): Likewise. Fix asm template.
+ (smulsi3_highpart): As for the unsigned version.
+ (smulsi3_highpart_internal): Likewise.
+ (smulsi3_highpart_mulhi_internal): Likewise.
+ (smulsi3_highpart_neg_mulhi_internal): Likewise.
+ (smuldi3_highpart, umuldi3_highpart): Minor formatting tweaks.
+ (*smul_acc_di): Remove duplicated pattern.
+ (*umul_acc_di, *smul_acc_di): Reapply 2002-10-16 change.
+ (anddi3) [unnamed mips16 pattern]: Remove reintroduced length.
+ (zero_extendsidi2_internal2): Remove new, but commented-out pattern.
+
+ 2002-10-22 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_return_addr): New.
+ * config/mips/mips.c (mips_return_addr): New.
+ (movdi_operand): Remove.
+ (se_register_operand): Ditto.
+ (se_reg_or_0_operand): Ditto.
+ (se_uns_arith_operand): Ditto.
+ (se_arith_operand): Ditto.
+ (se_nonmemory_operand): Ditto.
+ (extend_operator): Ditto.
+ (highpart_shift_operator): Ditto.
+ (mips_initial_elimination_offset): Remove return address pointer
+ elimination.
+ (mips_reg_names): Remove $ra.
+ (mips_regno_to_class): Ditto.
+ * config/mips/mips.h (POINTER_SIZE): Define based on TARGET_LONG64
+ and TARGET_64BIT.
+ (POINTER_BOUNDARY): Remove.
+ (POINTERS_EXTEND_UNSIGNED): Define to 0.
+ (PROMOTE_MODE): Promote to Pmode.
+ (SHORT_IMMEDIATES_SIGN_EXTEND): Define.
+ (Pmode): Define to TARGET_64BIT.
+ (FUNCTION_MODE): Define as Pmode.
+ (mips_args): Remove deleted functions.
+ (SIZE_TYPE): Depend on POINTER_SIZE.
+ (PTRDIFF_TYPE): Ditto.
+ (FIXED_REGISTERS): Fix extra registers.
+ (CALL_USED_REGISTERS): Ditto.
+ (CALL_REALLY_USED_REGISTERS): Ditto.
+ (RAP_REG_NUM): Remove.
+ (RETURN_ADDRESS_POINTER_REGNUM): Ditto.
+ (RETURN_ADDR_RTX): Define to mips_return_addr.
+ (ELIMINABLE_REGS): Remove RETURN_ADDRESS_POINTER_REGNUM.
+ (CAN_ELIMINATE): Ditto.
+ * config/mips/mips.md: For DImode patterns, take into account
+ deletions above. Split mulsidi patterns into sign_extend and
+ zero_extend.
+
+ 2002-10-16 Richard Sandiford <rsandifo@redhat.com>
+ Michael Meissner <meissner@redhat.com>
+
+ * config/mips/mips.h (ISA_HAS_MACC): True for normal-mode vr4120 code.
+ * config/mips/mips.md (mulsi3_mult3): Add a define_peephole2 to
+ mop up unnecessarly moves through LO.
+ (*mul_acc_si): Remove vr5400 and vr5500 handling from here.
+ (*macc): New pattern for ISA_HAS_MACC. Add define_peephole2s to
+ change mtlo/macc sequences into mul/add sequences when a three-
+ address mul is available.
+ (*macc2): New pattern. Add a define_peephole2 to generate it.
+ (*mul_sub_si): Fix contraint for operand 5.
+ (*muls): Use in 32-bit code as well.
+ (*msac): Likewise. Use msub instead of msac in vr5500 code
+ if the destination is LO. Remove duplicate define_split.
+ (*muls_di): Use only in 32-bit code. Adjust rtl accordingly.
+ (*msac_di): Likewise. Fix formatting.
+ (smulsi3_highpart, umulsi3_highpart): Use mulhi in 32-bit code too.
+ (*xmulsi3_highpart_internal): Use only if !ISA_HAS_MULHI.
+ (*xmulsi3_highpart_mulhi): Use even if !TARGET_64BIT.
+ (*xmulsi3_neg_highpart_mulhi): Likewise.
+ (*mul_acc_64bit_di): Remove.
+ (*mul_acc_di): Use only in 32-bit code. Handle ISA_HAS_MACC as well.
+
+ 2002-10-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/vr.h (DRIVER_SELF_SPECS): Define.
+ * config/mips/t-vr (MULTILIB_OPTIONS): Remove mlong32.
+ (MULTILIB_DIRNAMES): Remove long32.
+ (MULTILIB_EXCEPTIONS): Don't build -mabi=32 -mgp32 multilibs.
+ (MULTILIB_REDUNDANT_DIRS): Remove.
+
+ 2002-10-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/tm.texi (DRIVER_SELF_SPECS): Document.
+ * gcc.c (driver_self_specs): New variable.
+ (do_self_spec): New function.
+ (main): Use it to process driver_self_specs.
+
+ 2002-10-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (one_cmpldi2): Use only if TARGET_64BIT.
+ Remove DImode define_split for !TARGET_64BIT.
+ (anddi3): Remove !TARGET_64BIT support from here as well.
+ Change operand 2's predicate to se_uns_arith_operand.
+ Add constant alternatives to define_insn.
+ (iordi3, xordi3, *nordi3): Likewise.
+ (anddi3_internal1, xordi3_immed): Remove.
+
+ 2002-10-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (PROCESSOR_R4121): Rename to PROCESSOR_R4120.
+ (TARGET_MIPS4121): Rename to TARGET_MIPS4120.
+ * config/mips/mips.c (mips_cpu_info): Rename vr4121 to vr4120.
+ * config/mips/mips.md: Apply same renaming here.
+
+ 2002-10-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (PROCESSOR_R4320, TARGET_MIPS4320): Remove.
+ (GENERATE_MULT3_SI): Remove use of TARGET_MIPS4320.
+ * config/mips/mips.c (mips_cpu_info): Remove vr4320 entry.
+ * config/mips/mips.md (define_attr cpu): Remove r4320.
+ Remove vr4320 scheduler and uses of TARGET_MIPS4320.
+
+ 2002-10-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips16_strings): New variable.
+ (mips_output_function_epilogue): Clear the SYMBOL_REF_FLAG of every
+ symbol in mips16_strings. Free the list.
+ (mips_encode_section_info): Keep track of local strings.
+
+ 2002-10-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (bunge, bltgt, bungt): New define_expands.
+ (sordered_df, sordered_sf): Remove.
+ * config/mips/mips.c (get_float_compare_codes): New fn.
+ (gen_int_relational, gen_conditional_move): Use it.
+
+ 2002-10-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_emit_fcc_reload): Declare.
+ * config/mips/mips.h (PREDICATE_CODES): Add fcc_register_operand.
+ * config/mips/mips.c (fcc_register_operand): New function.
+ (mips_emit_fcc_reload): New function, extracted from reload_incc.
+ (override_options): Allow TFmode values in float registers
+ if ISA_HAS_8CC.
+ * cnfig/mips/mips.md (reload_incc): Change destination prediate
+ to fcc_register_operand. Remove misleading source constraint.
+ Use mips_emit_fcc_reload.
+ (reload_outcc): Duplicate reload_incc.
+
+
+2003-04-30 Diego Novillo <dnovillo@redhat.com>
+
+ * builtins.def (BUILTIN_CONSTANT_P): Mark as constant.
+
+2003-04-30 Geoffrey Keating <geoffk@apple.com>
+
+ * tree-inline.c (inlinable_function_p): Back out last change, it's
+ unnecessary.
+
+2003-04-30 Steven Bosscher <steven@gcc.gnu.org>
+
+ * ggc-page.c (TREE_EXP_SIZE): Define.
+ (extra_order_size_table): New entry for expr trees with
+ two operands.
+
+2003-04-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-common.c (if_elt): Use location_t in lieu of "file, line" pair.
+ (c_expand_start_cond): Adjust.
+ (c_expand_end_cond): Don't use warning_with_file_and_file.
+ (shadow_warning): Likewise.
+
+2003-04-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.h (DECL_POINTER_DEPTH): Remove.
+ (struct tree_decl): Remove pointer_depth.
+
+2003-04-30 Janis Johnson <janis187@us.ibm.com>
+
+ * config/rs6000/linux64.h (ASM_OUTPUT_LABELREF): Remove.
+ * config/rs6000/rs6000.c (rs6000_elf_strip_name_encoding): Remove.
+ (rs6000_xcoff_encode_section_info): Remove.
+ (current_file_function_operand): Use SYMBOL_REF_FLAGS; fix latent bug.
+ (rs6000_output_mi_thunk): Remove dead code; use SYMBOL_REF_FLAGS.
+ (small_data_operand, rs6000_emit_move, rs6000_elf_in_small_data_p,):
+ Use SYMBOL_REF_FLAGS.
+ (rs6000_elf_encode_section_info): Call default_encode_section_info for
+ generic flags, use SYMBOL_REF_FLAGS; code cleanups.
+ * sysv4.h (TARGET_STRIP_NAME_ENCODING, ASM_OUTPUT_LABELREF): Remove.
+ (SYMBOL_FLAG_SMALL_V4, SYMBOL_REF_SMALL_V4_P): New.
+ * xcoff.h (TARGET_ENCODE_SECTION_INFO): Remove.
+ (ASM_DECLARE_FUNCTION_NAME): Remove setting of SYMBOL_REF_FLAG.
+
+2003-04-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * diagnostic.c (output_pointer): Use HOST_PTR_PRINTF.
+
+2003-04-30 Andreas Schwab <schwab@suse.de>
+
+ * doc/extend.texi (Other Builtins): Enclose multiple word data
+ type in braces for @deftypefn.
+
+2003-04-30 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * stor-layout.c (mode_for_size_tree): Use BLKmode if SIZE overflows.
+
+ * doc/install.texi (--enable-threads): Document "gnat" option.
+
+2003-04-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * diagnostic.h (output_formatted_scalar): Tweak.
+ * diagnostic.c (output_long_decimal): Likewise.
+ (output_unsigned_decimal): Likewise.
+ (output_long_unsigned_decimal): Likewise.
+ (output_octal): Likewise.
+ (output_long_octal): Likewise.
+ (output_hexadecimal): Likewise.
+ (output_long_hexadecimal): Likewise.
+ (output_pointer): New function.
+ (output_format): Use it. Recognize "%p" format specifier.
+
+2003-04-30 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * function.c (purge_addressof_1): Postpone insn in fewer cases.
+
+2003-04-29 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/host-darwin.c (segv_handler): When -dH is used,
+ call abort() after running out of stack space.
+
+ * c-typeck.c (function_types_compatible_p): Ignore incompatible
+ 'volatile' qualifiers on a function's return type in GNU mode.
+
+2003-04-29 Aldy Hernandez <aldyh@redhat.com>
+
+ * expr.c (emit_group_load): Dump parallels of simd types to
+ memory.
+
+2003-04-29 Vladimir Makarov <vmakarov@redhat.com>
+
+ * genautomata.c (add_vect): Check undefined value for range type
+ too.
+
+2003-04-29 Phil Edwards <pme@gcc.gnu.org>
+
+ * configure.in: More general test for cmp --ignore-initial.
+ * configure: Regenerate.
+
+2003-04-29 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * stor-layout.c (mode_for_size_tree): Use tree_low_cst.
+ (layout_decl, place_field): Likewise.
+ Also make minor type and whitespace changes.
+
+ * tree.c (save_expr): Don't fold a COMPONENT_REF.
+
+2003-04-29 Olivier Hainque <hainque@act-europe.fr>
+
+ * calls.c (expand_call): When modes of target and valreg match, force
+ sibcall failure when target is a MEM.
+
+2003-04-29 Geoffrey Keating <geoffk@apple.com>
+
+ * tree-inline.c (inlinable_function_p): Don't support inlining
+ functions using varargs.
+
+ * doc/invoke.texi (Overall Options): Mention -x objective-c-header.
+
+ * dwarf2out.c (output_call_frame_info): No need to output EH
+ unwind information if all_throwers_are_sibcalls.
+
+ * c-semantics.c (expand_unreachable_stmt): Return a tree.
+ (expand_stmt): Update for change to expand_unreachable_stmt.
+ (expand_unreachable_if_stmt): Likewise.
+
+ * Makefile.in (quickstrap): Pass BOOT_CFLAGS to submake.
+
+2003-04-29 Jason Merrill <jason@redhat.com>
+
+ PR middle-end/10336
+ * jump.c (never_reached_warning): Really stop looking if we reach
+ the beginning of the function.
+
+2003-04-29 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/elf.h (SIZE_TYPE, PTRDIFF_TYPE, USER_LABEL_PREFIX):
+ Remove redundant macros.
+ (WCHAR_TYPE, WCHAR_TYPE_SIZE): Change to "short unsigned int".
+ (LOCAL_LABEL_PREFIX): Define unconditionally.
+ (NO_DOT_IN_LABEL): Clarify comment.
+ * config/xtensa/linux.h (WCHAR_TYPE, WCHAR_TYPE_SIZE): Add explicit
+ definition to "long int".
+
+2003-04-29 Alexander Kabaev <kan@FreeBSD.ORG>
+
+ bootstrap/10452
+ * gengtype-yacc.y: Improve portability.
+
+2003-04-29 Zack Weinberg <zack@codesourcery.com>
+
+ * config.gcc: Install obsolete target list for GCC 3.3.
+ * doc/install.texi: Mention in specific-target instructions
+ that certain configurations are deprecated.
+
+2003-04-29 Zack Weinberg <zack@codesourcery.com>
+
+ * tree.h: Delete no-checking definition of CST_OR_CONSTRUCTOR_CHECK.
+
+2003-04-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * c-pragma.c (maybe_apply_renaming_pragma): Fix typo.
+ * gcc.c (display_help): Likewise.
+ * toplev.c (f_options): Likewise.
+ * params.def (PARAM_MAX_INLINE_SCOPE): Likewise.
+ * config/c4x/c4x.h (TARGET_SWITCHES): Likewise.
+ * config/mcore/mcore.h (TARGET_SWITCHES): Likewise.
+ * config/s390/s390.h (TARGET_SWITCHES): Likewise.
+ * config/v850/v850.h (TARGET_SWITCHES): Likewise.
+
+2003-04-29 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * varasm.c (default_assemble_visibility): Use assemble_name.
+
+2003-04-29 David O'Brien <obrien@FreeBSD.org>
+
+ * config/i386/freebsd64.h (LINK_SPEC): Mirror FreeBSD linker.
+ * config/rs6000/freebsd.h (LINK_SHLIB_SPEC): New macro.
+ (SIZE_TYPE): New macro.
+ * config/i386/freebsd-aout.h (NO_PROFILE_COUNTERS): New macro.
+ (SET_ASM_OP): New macro.
+ (HANDLE_SYSV_PRAGMA): New macro.
+ (ASM_WEAKEN_LABEL): New macro.
+
+2003-04-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10180
+ * tree-inline.c (expand_call_inline): Call push_srcloc when
+ encountering EXPR_WITH_FILE_LOCATION. Honor warn_inline.
+
+2003-04-28 Mike Stump <mrs@apple.com>
+
+ * gdbinit.in: Update to reflect new identifier structure.
+
+2003-04-28 Zack Weinberg <zack@codesourcery.com>
+
+ * tree.h (TREE_CST_RTL, CST_OR_CONSTRUCTOR_CHECK): Delete.
+ (struct tree_int_cst, struct tree_real_cst, struct tree_string,
+ struct tree_complex, struct tree_vector): Remove RTL field.
+ (CONSTRUCTOR_ELTS): Use elt 0.
+ * tree.def (CONSTRUCTOR): Delete first of its two operands.
+ * varasm.c (output_constant_def): Remove early exit if
+ TREE_CST_RTL is set. Don't set TREE_CST_RTL.
+ (decode_addr_const): Don't mention TREE_CST_RTL in comment.
+ * target.h (select_section): Don't mention TREE_CST_RTL in comment.
+ * doc/tm.texi (encode_section_info): Don't talk about TREE_CST_RTL.
+
+2003-04-28 Jakub Jelinek <jakub@redhat.com>
+
+ * c-decl.c (finish_decl): When prototype with asmspec is found
+ for built-in, adjust built_in_decls as well as expr.c decls.
+ * expr.c (init_block_move_fn, init_block_clear_fn): New functions.
+ (emit_block_move_libcall_fn, clear_storage_libcall_fn): Use it.
+ * expr.c (init_block_move_fn, init_block_clear_fn): New prototypes.
+
+2003-04-28 Richard Henderson <rth@redhat.com>
+
+ * config/sparc/sparc.c (print_operand): Add 's' to sign-extend.
+ * config/sparc/sparc.md (const_mulsidi3_v8plus): Fix mode of
+ integral constant mult operand.
+ (const_mulsidi3_sp32, const_mulsidi3_sp64): Likewise.
+ (const_smulsi3_highpart_v8plus): Likewise.
+ (const_smulsi3_highpart): Likewise.
+ (const_umulsidi3_sp32): Likewise; sign-extend it in the output.
+ (const_umulsidi3_sp64, const_umulsidi3_v8plus): Likewise.
+ (const_umulsi3_highpart_v8plus): Likewise.
+ (const_umulsi3_highpart): Likewise.
+
+2003-04-28 David O'Brien <obrien@FreeBSD.org>
+
+ * config/i386/x86-64.h (NO_PROFILE_COUNTERS, HAVE_AS_DWARF2_DEBUG_LINE):
+ Define as 1.
+
+2003-04-28 David O'Brien <obrien@FreeBSD.org>
+
+ * config/i386/i386.h (builtin_define): Add __amd64 and __amd64__.
+
+2003-04-28 Jakub Jelinek <jakub@redhat.com>
+
+ * builtins.def (BUILT_IN_BCOPY, BUILT_IN_MEMMOVE): New.
+ * builtin-types.def (BT_FN_VOID_CONST_PTR_PTR_SIZE): New.
+ * builtins.c (expand_builtin_memmove, expand_builtin_bcopy): New
+ functions.
+ (expand_builtin): Handle BUILT_IN_BCOPY and BUILT_IN_MEMMOVE.
+
+2003-04-28 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/elf.h (ASM_OUTPUT_ALIGNED_COMMON): Remove definition.
+
+2003-04-27 Zack Weinberg <zack@codesourcery.com>
+
+ * expr.c (expand_expr <COMPLEX_CST, STRING_CST>): Always call
+ output_constant_def, use its result instead of TREE_CST_RTL (exp).
+ Can assume it has the form (mem (symbol_ref ".LCxxx")).
+ (expand_expr <COMPONENT_REF>): Can always just extract the
+ relevant field of a CONSTRUCTOR.
+ (expand_expr <ARRAY_REF, COMPONENT_REF, BIT_FIELD_REF,
+ ARRAY_RANGE_REF>): Make control flow explicit.
+ * varasm.c (output_constant_def): Can look at TREE_CST_RTL of
+ an INTEGER_CST.
+
+2003-04-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * reload1.c (reg_set_luid): Fix a comment typo.
+
+2003-04-27 Zack Weinberg <zack@codesourcery.com>
+
+ * varasm.c (const_str_htab_hash, const_str_htab_eq, STRHASH,
+ struct deferred_string, const_str_htab): Kill.
+ (n_deferred_strings): New static variable.
+ (build_constant_desc): Set SYMBOL_REF_DECL of the new
+ symbol_ref to point to the constant.
+ (output_constant_def): When a deferred string is forced out,
+ just clear STRING_POOL_ADDRESS_P and decrement n_deferred_strings.
+ (mark_constant): Likewise.
+ (maybe_output_constant_def_contents): When deferring a string
+ constant, just set STRING_POOL_ADDRESS_P and increment
+ n_deferred_strings.
+ (mark_constant_pool): Check n_deferred_strings, not the size
+ of const_str_htab.
+ (init_varasm_once): No need to create const_str_htab.
+
+ * rtl.def, rtl.h, doc/rtl.texi: Document possibility that
+ SYMBOL_REF_DECL points to a constant.
+
+2003-04-26 Zack Weinberg <zack@codesourcery.com>
+
+ * varasm.c (output_constant_def): Split out two new static
+ functions, build_constant_desc and maybe_output_constant_def_contents.
+ Restructure for comprehensibility. Don't call
+ output_addressed_constants. Treat defstr being non-NULL for
+ STRING_POOL_ADDRESS_P constants as an invariant.
+ (struct deferred_string): Remove labelno field.
+ (output_constant_def_contents): Kill labelno argument. Call
+ output_addressed_constants here. Use ASM_OUTPUT_LABEL, not
+ asm_out.internal_label.
+ (mark_constant): Update call to output_constant_def_contents.
+ Treat defstr being non-NULL for STRING_POOL_ADDRESS_P
+ constants as an invariant.
+
+2003-04-26 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (output_pic_addr_const): Use SYMBOL_REF_LOCAL_P.
+ (ix86_expand_call, ix86_rtx_consts): Likewise.
+
+2003-04-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * doc/md.texi (cmpstr): Document additional restrictions.
+
+2003-04-26 Neil Booth <neil@daikokuya.co.uk>
+
+ * flags.h (time_report): Remove.
+ * timevar.c (timevar_enable): New.
+ (TIMEVAR_ENABLE): Remove, use timevar_enable.
+ (timevar_init): Rename from init_timevar.
+ * timevar.h (timevar_init): Rename from init_timevar.
+ * toplev.c (time_report): Make static.
+ (do_compile): Conditionally call init_timevar first.
+ (preprocess_options): Move some code to do_compile.
+
+2003-04-26 Stephane Carrez <stcarrez@nerim.fr>
+
+ * doc/install.texi (Binaries): Mention binaries for HC11/HC12.
+
+2003-04-26 Neil Booth <neil@daikokuya.co.uk>
+
+ * _cpp_lex_direct: Remove pointless code.
+
+2003-04-26 Stephane Carrez <stcarrez@nerim.fr>
+
+ * doc/extend.texi (Function Attributes): Document "near" and "far"
+ for 68HC11 and 68HC12.
+
+2003-04-25 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (store_field): When making temporary for store, don't
+ make it TYPE_QUAL_CONST.
+
+2003-04-25 Phil Edwards <pme@gcc.gnu.org>
+
+ * toplev.c (read_integral_parameter): Use "argument" in error
+ message to distinguish it from actual invalid options.
+
+2003-04-25 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/linux.h (TARGET_OS_CPP_BUILTINS): Back out previous
+ addition of __PIC__ and __pic__ macros.
+ * config/xtensa/xtensa.h: Clean up indentation.
+
+2003-04-25 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/linux.h (TARGET_OS_CPP_BUILTINS): Remove definition of
+ _GNU_SOURCE. Add definitions of __PIC__ and __pic__.
+ (SUBTARGET_CPP_SPEC): Define.
+ (LIB_SPEC): Delete.
+ * config/xtensa/xtensa-protos.h (xtensa_declare_object): Delete.
+ * config/xtensa/xtensa.c (xtensa_declare_object): Delete.
+ * config/xtensa/xtensa.h (CPP_SPEC, SUBTARGET_CPP_SPEC, EXTRA_SPECS):
+ Define.
+ (ASM_OUTPUT_COMMON, ASM_OUTPUT_LOCAL): Delete.
+ (ASM_OUTPUT_ALIGNED_BSS, BSS_SECTION_ASM_OP): Define.
+
+2003-04-25 H.J. Lu <hjl@gnu.org>
+
+ * config/ia64/ia64.c (ia64_expand_compare_and_swap): Add rmode
+ for return mode.
+ (ia64_expand_builtin): Set rmode to SImode for
+ IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_SI,
+ IA64_BUILTIN_VAL_COMPARE_AND_SWAP_SI and
+ IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_DI. Set remode to DImode
+ for IA64_BUILTIN_VAL_COMPARE_AND_SWAP_DI.
+
+2003-04-25 Phil Edwards <pme@gcc.gnu.org>
+
+ * configure.in (make_compare_target): Test for GNU cmp and set this
+ variable appropriately.
+ * Makefile.in (compare, compare3, compare4, compare-lean, compare3-lean,
+ compare4-lean): Rename actual targets to slowcompare*. New compare*
+ targets depend on names based on make_compare_target.
+ * configure: Regenerated.
+
+2003-04-25 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.c (ia64_compute_frame_size): Allow inline asm
+ to clobber ar.pfs and ar.unat.
+ (ia64_expand_prologue): Force alloc instruction if ar.pfs saved;
+ fix test for spilling ar.pfs to the stack.
+
+2003-04-25 Richard Henderson <rth@redhat.com>
+
+ PR opt/10315
+ * config/rs6000/rs6000.c (rs6000_emit_move): Only elide proper
+ checks during reload; use validize_mem instead of adjust_address.
+
+2003-04-26 Ben Elliston <bje@wasabisystems.com>
+
+ * config/arm/arm.c (arm_adjust_cost): Correct logic that tests the
+ return values from recog_memoized().
+
+2003-04-24 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR opt/8705
+ * gcse.c (try_replace_reg): On a successful substitution of a constant
+ into a single set, try to simplify the source of the set.
+ * loop.c (scan_loop): Don't try to optimize a MODE_CC set with a
+ constant source.
+
+2003-04-24 Neil Booth <neil@daikokuya.co.uk>
+
+ * cpplex.c (cpp_token_len): Tighten up.
+ (cpp_token_as_text): Need extra byte now.
+ * cpplib.c (glue_header_name): Need extra 2 bytes.
+ * cppmacro.c (cpp_macro_definition): Need extra byte.
+
+2003-04-24 Alexander Kabaev <kan@FreeBSD.ORG>
+
+ * config/sparc/sparc.md (umulsidi3, mulsidi3): Avoid using
+ const_umulsidi3_sp32 and const_mulsidi3_sp32 on 64bit targets
+ where they might be not present. Use their _sp64 equivalent
+ instead.
+
+Thu Apr 24 20:42:12 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (cvtsi2sdq): Fix typo in previous patch.
+
+2003-04-24 Krister Walfridsson <cato@df.lth.se>
+
+ * configure.in: Check whether mbstowcs works.
+ * configure, config.in: Regenerate.
+ * intl.c: Use HAVE_WORKING_MBSTOWCS.
+
+2003-04-24 H.J. Lu <hjl@gnu.org>
+
+ * config/ia64/ia64.c (ia64_init_builtins): Add si_ftype_pdi_di_di
+ for __sync_bool_compare_and_swap_di for int return type.
+
+ * config/ia64/ia64intrin.h (__sync_bool_compare_and_swap_di):
+ Change return type to int.
+ (__sync_bool_compare_and_swap): Likewise.
+
+Thu Apr 24 16:55:26 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * cfgbuild.c (make_edges): Do not use next_nonnote_insn when
+ looking for fallthru edge.
+
+ * athlon.md (athlon-agu, athlon-store, athlon-fany, athlon-faddmul):
+ Fix.
+ (athlon-load2, athlon-store2, athlon-fpsched, athlon-fpload,
+ athlon-fvector): New.
+ (athlon_*): Revisit to match new optimization guide.
+ * i386.c (ix86_adjust_cost): Fix memory operand costs on Athlon/k8
+ * i386.md (cvt??2?? patterns): Fix modes.
+ (fistp patterns): Set modes.
+
+ Accidentaly commited with my earlier reload patch:
+ PR c/10308
+ * reload.c (find_reloads_address_1): Reload plus at the place of
+ index register.
+
+2003-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ New GCOV_TAG_FUNCTION layout
+ * coverage.c (struct function_list): Replace name with ident.
+ (struct counts_entry): Likewise.
+ (fn_ident): New.
+ (htab_counts_entry_hash, htab_counts_entry_eq,
+ htab_counts_entry_del): Adjust.
+ (reads_count_file, get_coverage_counts,
+ coverage_begin_output, coverage_end_function): Adjust.
+ (build_fn_info_type, build_fn_info_value): Likewise.
+ * gcov-dump.c (tag_function): Adjust.
+ * gcov-io.c (gcov_write_string, gcov_read_string): Not in LIBGCOV.
+ * gcov-io.h (gcov_write_string, gcov_read_string): Not in LIBGCOV.
+ * gcov.c (struct function_info): Add ident.
+ (read_graph_file, read_count_file): Adjust.
+ * libgcov.c (gcov_exit): Adjust.
+
+2003-04-23 Richard Henderson <rth@redhat.com>
+
+ PR opt/8300
+ * toplev.c (rest_of_compilation): Delay no_new_pseudos until
+ after initialize_uninitialized_subregs; update reg info assuming
+ new pseudos were created.
+
+2003-04-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in (c-lex.o, LIBCPP_OBJS, cpplex.o): Update.
+ * c-lex.c (MULTIBYTE_CHARS): Remove conditionals.
+ (lex_string): Take cpp_string with full spelling.
+ (cb_ident): Update.
+ (c_lex): Update diagnostics.
+ * cpplex.c (SPELL_NUMBER, SPELL_STRING): Combine into SPELL_LITERAL.
+ (create_literal): New.
+ (lex_string): Unterminated literals have type CPP_OTHER.
+ (_cpp_lex_direct): Update calls to lex_string. Use create_literal
+ for CPP_OTHER.
+ (cpp_token_len, cpp_spell_token, cpp_output_token): Simplify.
+ (_cpp_equiv_tokens, cpp_interpret_charconst): Update.
+ * cpplib.c (parse_include, do_line, do_linemarker,
+ destringize_and_run): Update for token storing full spelling.
+ * cpplib.h: Update token spelling types.
+ * cppmacro.c (stringify_arg, check_trad_stringification):
+ Update for token storing full spelling.
+
+2003-04-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_expand_cmpstr): Disable CLC loop.
+
+2003-04-23 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.h (TARGET_OPTIONS): Add value field.
+
+2003-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/extend.texi: Remove duplicate 2003 copyright date.
+
+2003-04-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * Makefile.in (LIBGCC_DEPS): Add gcov headers.
+ (libgcov.a): Depends on LIBGCC_DEPS.
+ * basic-block.h (profile_info): Moved here from coverage.h. Made
+ a pointer.
+ * coverage.c (struct function_list): Fixed array of counter types.
+ (struct counts_entry): Keyed by counter type, contains summary.
+ (profile_info): Moved to profile.c.
+ (prg_ctr_mask, prg_n_ctrs, fn_ctr_mask, fn_n_ctrs): New global
+ vars.
+ (profiler_label): Remove.
+ (ctr_labels): New.
+ (set_purpose, label_for_tag, build_counter_section_fields,
+ build_counter_section_value, build_counter_section_data_fields,
+ build_counter_section_data_values, build_function_info_fields,
+ build_function_info_value, gcov_info_fields, gcov_info_value): Remove.
+ (build_fn_info_type, build_fn_info_value, build_ctr_info_type,
+ build_ctr_info_value, build_gcov_info): New.
+ (htab_counts_entry_hash, htab_counts_entry_eq): Adjust.
+ (reads_counts_file): Adjust.
+ (get_coverage_counts): Takes counter number. Add summary
+ parameter. Adjust.
+ (coverage_counter_ref): Tkaes counter number. Adjust. Lazily
+ create counter array labels.
+ (coverage_end_function): Adjust.
+ (create_coverage): Adjust.
+ (find_counters_section): Remove.
+ * coverage.h (MAX_COUNTER_SECTIONS): Remove.
+ (struct section_info, struct profile_info): Remove.
+ (profile_info): Moved to basic-block.h.
+ (coverage_counter_ref): Takes a counter number.
+ (get_coverage_counts): Takes a counter number. Added summary
+ parameter.
+ (find_counters_section): Remove.
+ * gcov-dump.c (tag_arc_counts): Rename to ...
+ (tag_counters): ... here. Adjust.
+ (tag_table): Move tag_counters to 3rd entry. Remove
+ PROGRAM_PLACEHOLDER and PROGRAM_INCORRECT entries.
+ (dump_file): Check for counter tag values here.
+ (tag_summary): Adjust.
+ * gcov-io.c (gcov_write_summary, gcov_read_summary): Adjust.
+ * gcov-io.h (GCOV_LOCKED): New.
+ (GCOV_TAG_ARC_COUNTS): Rename to ...
+ (GCOV_TAG_COUNTS_BASE): ... here.
+ (GCOV_TAG_PLACEHOLDER_SUMMARY, GCOV_TAG_INCORRECT_SUMMARY):
+ Remove.
+ (GCOV_COUNTER_ARCS, GCOV_COUNTERS, GCOV_NAMES): New.
+ (GCOV_TAG_FOR_COUNTER, GCOV_COUNTER_FOR_TAG,
+ GCOV_TAG_IS_COUNTER): New.
+ (struct gcov_ctr_summary): New.
+ (struct gcov_summary): Adjust.
+ (struct gcov_counter_section): Remove.
+ struct gcov_counter_section_data): Remove.
+ (struct gcov_function_info): Rename to ...
+ (struct gcov_fn_info): ... here. Adjust.
+ (struct gcov_ctr_info): New.
+ (struct gcov_info): Adjust.
+ * gcov.c (read_count_file): Adjust.
+ (output_lines): Adjust.
+ * libgcov.c (gcov_exit): Adjust.
+ (__gcov_flush): Adjust.
+ * mklibgcc.in (libgcc2_c_dep): Add gcov headers.
+ * predict.c (maybe_hot_bb_p, probably_cold_bb_p,
+ probably_never_executed_bb_p, compute_frequency_function): Adjust
+ profile_info use.
+ * profile.c (struct counts_entry): Remove.
+ (profile_info): Define here.
+ (get_exec_counts): Adjust get_coverage_counts call.
+ (compute_branch_probablilities): Remove find_counters_section
+ call.
+ (gen_edge_profiler): Adjust coverage_counter_ref call.
+ * tracer.c (tail_duplicate): Adjust profile_info use.
+
+2003-04-23 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/10339
+ * builtins.c (expand_builtin_strcmp): Try to emit cmpstrsi insn
+ directly instead of unsafely transforming call into a memcmp.
+ (expand_builtin_strncmp): Likewise.
+
+2003-04-22 Roger Sayle <roger@eyesopen.com>
+
+ * alias.c (mark_constant_function): Check for constancy and
+ purity even of void functions. Update both the function decl
+ and the cgraph RTL info with the results.
+
+2003-04-22 Roger Sayle <roger@eyesopen.com>
+
+ * real.c (do_add): Change to return a bool indicating that the
+ result of the operation may be inexact due to loss of precision.
+ (do_multiply): Likewise.
+ (do_divide): Likewise.
+
+2003-04-22 Geoffrey Keating <geoffk@apple.com>
+ Loren James Rittle <ljrittle@acm.org>
+
+ * dwarf2out.c (fde_table_allocated): Mark with GTY.
+ (decl_die_table_allocated): Likewise.
+ (abbrev_die_table_allocated): Likewise.
+ (line_info_table_allocated): Likewise.
+ (separate_line_info_table_allocated): Likewise.
+ (pubname_table_allocated): Likewise.
+ (arange_table_allocated): Likewise.
+ (ranges_table_allocated): Likewise.
+ (decl_die_table_in_use): Unconditionalize; mark with GTY.
+ (abbrev_die_table_in_use): Likewise.
+ (line_info_table_in_use): Likewise.
+ (separate_line_info_table_in_use): Likewise.
+ (pubname_table_in_use): Likewise.
+ (arange_table_in_use): Likewise.
+ (ranges_table_in_use): Likewise.
+ (have_location_lists): Likewise.
+ (emitcount): New GTY-marked static, moved...
+ (maybe_emit_file): ...from here.
+ (label_num): New GTY-marked static, moved...
+ (gen_internal_sym): ...from here.
+
+2003-04-22 Richard Henderson <rth@redhat.com>
+
+ PR 8866
+ * rtl.h (MEM_NOTRAP_P): New.
+ (MEM_COPY_ATTRIBUTES): Copy it.
+ * rtlanal.c (may_trap_p): Check it.
+ * expr.c (do_tablejump): Set it.
+ * doc/rtl.texi (Flags): Document it.
+
+ * cfgrtl.c (try_redirect_by_replacing_jump): Revert last three changes.
+
+2003-04-22 Olivier Hainque <hainque@act-europe.fr>
+
+ * config/alpha/alpha.c (alpha_expand_prologue [OPEN_VMS_ABI]): Don't
+ set FRP on stack adjustment for outgoing args if frame_pointer_needed.
+
+2003-04-22 Vincent Celier <celier@gnat.com>
+
+ * gthr-gnat.h, gthr-gnat.c: new sources for implementation of
+ --enable-threads=gnat.
+ * Makefile.in: Add gthr-gnat.c to LIB2ADDEH.
+ * configure.in: Add gnat to the list of thread packages
+ * configure: Rebuild.
+ * config/t-linux: Add gthr-gnat.c to LIB2ADDEH and LIB2ADDEHDEP
+
+2003-04-22 Neil Booth <neil@daikokuya.co.uk>
+
+ * cpplex.c (_cpp_get_fresh_line): Pop the buffer if return_at_eof.
+
+2003-04-22 Devang Patel <dpatel@apple.com>
+
+ * cpptrad.c (_cpp_replacement_text_len): Add check for macro
+ parameter count.
+ (_cpp_copy_replacement_text): Same.
+
+2003-04-22 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-lex.c (c_lex): Handle CPP_OTHER differently.
+ * cppexp.c (_cpp_parse_expr): Similarly.
+ * cpplex.c (SPELL_CHAR): Remove.
+ (_cpp_lex_direct): Stray chars are saved as byte strings.
+ (cpp_spell_token, cpp_output_token, _cpp_equiv_token): Don't
+ handle SPELL_CHAR.
+ (cpp_avoid_paste): Update handling of CPP_OTHER.
+ * cpplib.h: Spell CPP_OTHER like a number.
+ (struct cpp_token): Remove member c.
+ * cppmacro.c (stringify_arg): Update handling of CPP_OTHER.
+
+2003-04-22 David Turner <novalis@gnu.org>
+
+ * gbl-ctors.h: Add special license exception.
+ * libgcc2.h: Likewise.
+ * tsystem.h: Likewise.
+ * gcov-io.h: Likewise.
+
+2003-04-22 David Edelsohn <edelsohn@gnu.org>
+
+ * fold-const.c (fold_range_test): Use RANGE_TEST_NON_SHORT_CIRCUIT
+ macro defaulting to original BRANCH_COST heuristic.
+ * doc/tm.texi (RANGE_TEST_NON_SHORT_CIRCUIT): Document.
+
+ * config/rs6000/rs6000.h (RANGE_TEST_NON_SHORT_CIRCUIT): Define.
+
+2003-04-22 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/t-spe: Merge in t-fprules into file.
+
+ * config.gcc: Add t-spe to powerpc-eabispe.
+
+2003-04-22 Kean Johnston <jkj@sco.com>
+
+ * tlink.c (recompile_files): Add missing '=' to putenv calls
+
+2003-04-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * ginclude/stddef.h: Provide C++ safe offsetof.
+
+2003-04-22 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * function.c (purge_addressof_1): In (mem (addressof (reg))) case
+ for reg notes, if there are no substitutions, just use a SUBREG.
+
+2003-04-21 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (calls.o): Depend on except.h.
+ * calls.c: Include except.h.
+ (emit_call_1): Call note_eh_region_may_contain_throw if
+ appropriate.
+ * except.c (eh_region): Add may_contain_throw.
+ (expand_eh_region_end_cleanup): Do not include handler code when
+ it cannot be reached.
+ (note_eh_region_may_contain_throw): New function.
+ * except.h (note_eh_region_may_contain_throw): New function.
+
+2003-04-21 Mark Mitchell <mark@codesourcery.com>
+
+ * config/i386/winnt.c (i386_pe_mark_dllimport): Revert previous
+ changes.
+
+2003-04-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_override_options): No SPE means
+ 64-bit long doubles.
+
+2003-04-21 Olivier Hainque <hainque@act-europe.fr>
+
+ * fold-const.c (fold, case PLUS_EXPR and case MULT_EXPR): Restore
+ a number of conversions required for type consistency and previously
+ stripped off by STRIP_NOPS.
+
+ * calls.c (expand_call): Prevent sibcall optimization for calls to
+ nested subprograms.
+
+ * expmed.c (extract_bit_field): Reverse operands of && condition to
+ prevent a potential division by zero in the previously first branch.
+ * config/pa/pa.md (extv, extzv): FAIL if the bitfield length is zero.
+
+2003-04-21 Joel Brobecker <brobecker@gnat.com>
+
+ * dwarf2out.c (is_ada, is_ada_subrange_type): New functions.
+ (subrange_type_die): Likewise.
+ (modified_type_die): Emit a subrange_type DIE for Ada subrange types.
+ (is_c_family, is_cxx, is_java, is_fortran): Return bool and clean up.
+
+2003-04-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ Break out coverage routines to new file.
+ * Makefile.in (COVERAGE_H): New variable
+ (C_OBJS): Add coverage.o
+ (coverage.o): New target.
+ (profile.o, loop-init.o, sched-ebb.o, predict.o, tracer.o): Adjust
+ dependencies.
+ (GTFILES): Adjust.
+ (gt-coverage.h): New target.
+ (gt-profile.h): Remove.
+ * profile.h: Remove. Move to ...
+ * coverage.h: ... here. New. #include gcov-io.h.
+ * gcov-io.h: Move function definitions to ...
+ * gcov-io.c: ... here. New.
+ * profile.c: Move coverage routines to coverage.c.
+ (instrument_edges, get_exec_counts, branch_prob, init_branch_prob,
+ end_branch_prob): Adjust.
+ * coverage.c: New. Coverage routines from profile.c
+ (coverage_counter_ref, coverage_init, coverage_finish,
+ coverage_end_function, coverage_begin_output,
+ coverage_counter_ref, get_coverage_counts): Define.
+ * gcov-dump.c, gcov.c: #include gcov-io.c.
+ * libgcov.c: Likewise. Adjust.
+ * loop-init.c: Don't #include profile.h
+ * tracer.c, predict.c, sched-ebb.c: Adjust #includes.
+ * rtl.h: Add coverage prototypes.
+ * toplev.c (compile_file): Init coverage, not branch_prob.
+ Always call coverage_finish.
+ (rest_of_compilation): Call coverage_end_function.
+
+2003-04-21 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * config/rs6000/rs6000.md (*movsf_softfloat): Add "h" <- "0" case.
+
+2003-04-21 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-ppoutput.c (cb_include): Don't take a cpp_token.
+ * cppfiles.c: Don't undef strcmp.
+ (find_include_file): Don't take a cpp_token. Check for empty
+ file names.
+ (_cpp_execute_include, _cpp_compare_file_date): Don't take a cpp_token.
+ (cpp_push_include): Simplify.
+ * cpphash.h (_cpp_execute_include, _cpp_compare_file_date): Update.
+ * cpplib.c (glue_header_name): Return the file name, not a cpp_token.
+ (parse_include): Similary. Don't check for zero-length filenames.
+ (do_include_common, do_pragma_dependency): Update accordingly.
+ * cpplib.h (struct cpp_callbacks): Change prototype of include.
+
+2003-04-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * doc/rtl.texi (RTX_UNCHANGING_P): Point to true_dependence for
+ details of conflict handling.
+
+ * fold-const.c (extract_muldiv, case CONVERT_EXPR): Detect case
+ when conversion overflows.
+
+ * stor-layout.c (layout_decl): Don't set DECL_SIZE_UNIT if already set.
+
+ * expr.c (store_constructor): Set RTX_UNCHANGING_P if readonly_field_p
+ before clearing.
+
+2003-04-21 Mark Mitchell <mark@codesourcery.com>
+
+ * config/i386/winnt.c (i386_pe_mark_dllimport): Make the new RTL
+ have the same form as the old RTL.
+
+2003-04-21 Andreas Jaeger <aj@suse.de>
+
+ * cppcharset.c (_cpp_valid_ucn): Cast field precision to int.
+
+2003-04-20 Chris Lattner <sabre@nondot.org>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * c-common.h, c-semantics.c: Rename genrtl_decl_cleanup to
+ genrtl_cleanup_stmt. Correct comment at head of
+ genrtl_cleanup_stmt (no such thing as a DECL_CLEANUP).
+
+ * stmt.c (struct nesting): Kill n_function_calls.
+ (expand_start_bindings): Don't set
+ thisblock->data.block.n_function_calls.
+ (expand_end_bindings): Compare function_call_count against 0.
+ (expand_cleanups): Kill DONT_DO argument; all callers passed
+ NULL_TREE. All callers updated to match.
+
+2003-04-20 Zack Weinberg <zack@codesourcery.com>
+
+ * varasm.c (struct deferred_constant, defer_addressed_constants_flag)
+ (defer_addressed_constants, output_deferred_addressed_constants): Kill.
+ (output_constant_def): Remove code predicated on
+ defer_addressed_constants_flag.
+
+ * output.h: Remove prototypes of deleted functions.
+ * c-typeck.c (constructor_subconstants_deferred): Kill.
+ (struct initializer_stack): Remove 'deferred' field.
+ (start_init): Remove all references to the above.
+ (finish_init): Likewise. Also remove never-executed call to
+ output_deferred_addressed_constants. Pull assignment to
+ defstr out of if expression.
+
+2003-04-20 Neil Booth <neil@daikokuya.co.uk>
+
+ * cpphash.h (NOTE_ESC_NL, NOTE_ESC_SPACE_NL, NOTE_TRIGRAPH,
+ NOTE_NEWLINE): Remove.
+ * cpplex.c (_cpp_clean_line, _cpp_process_line_notes): Update
+ to handle new form of line note type.
+
+2003-04-20 Zack Weinberg <zack@codesourcery.com>
+
+ * target.h (encode_section_info): Add new argument carrying
+ the RTL to be modified by the hook.
+
+ * varasm.c (make_decl_rtl, output_constant_def): Update calls
+ to encode_section_info.
+ (default_encode_section_info): Take and use RTL argument,
+ don't use TREE_CST_RTL or DECL_RTL.
+ * output.h: Update prototype of default_encode_section_info.
+ * config/darwin.h (ASM_DECLARE_OBJECT_NAME)
+ (ASM_DECLARE_FUNCTION_NAME, ASM_OUTPUT_ALIGNED_DECL_LOCAL):
+ Update calls to encode_section_info.
+
+ * config/darwin.c, config/arm/arm.c, config/arm/pe.c
+ * config/h8300/h8300.c, config/i386/winnt.c, config/m32r/m32r.c
+ * config/m68hc11/m68hc11.c, config/m88k/m88k.c, config/mcore/mcore.c
+ * config/mips/mips.c, config/mmix/mmix.c, config/pa/pa.c
+ * config/romp/romp.c, config/rs6000/rs6000.c, config/s390/s390.c
+ * config/v850/v850.c (TARGET_ENCODE_SECTION_INFO definitions):
+ Take and use RTL argument, don't use TREE_CST_RTL or DECL_RTL,
+ except for PE dllimport/dllexport. Update calls to
+ default_encode_section_info.
+
+ * config/darwin-protos.h, config/arm/arm-protos.h, config/i386-protos.h:
+ Update prototypes.
+
+ * doc/tm.texi (TARGET_ENCODE_SECTION_INFO): Update.
+
+2003-04-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR/8705
+ * pa.md (movccfp): New expander.
+ (setccfp0, setccfp1): Rename to movccfp0 and movccfp1, respectively.
+ Reverse fcmp conditions.
+
+2003-04-20 Marek Michalkiewicz <marekm@amelek.gda.pl>
+
+ * config/avr/avr.md (*cmpqi_sign_extend): Handle negative values
+ of operand 1 correctly.
+
+2003-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cpplex.c (_cpp_lex_direct): Set BOL for CPP_EOF tokens.
+ * gcov.c (output_lines): Don't be so fussy about going past EOF.
+
+2003-04-20 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in (LIBCPP_OBJS): Add cppcharset.o.
+ (cppcharset.o): New target.
+ * c-lex.c (is_extended_char): Move to cppcharset.c.
+ (utf8_extend_token): Delete.
+ * cppcharset.c: New file.
+ * cpphash.h (_cpp_valid_ucn): New.
+ * cpplex.c (lex_identifier): Update prototype.
+ (continues_identifier_p): Rename forms_identifier_p. Handle UCN
+ escapes.
+ (maybe_read_ucs): Rename maybe_read_ucn. Update to use code
+ in cppcharset.c.
+ (lex_number, lex_identifier, cpp_parse_escape): Update.
+ (_cpp_lex_direct): Update to handle UCNs.
+ (cpp_avoid_paste): Don't paste to form a UCN.
+
+2003-04-19 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin): Don't expand a pure or const
+ built-in function if the result will be ignored and none of
+ its arguments are volatile.
+
+2003-04-19 Kean Johnston <jkj@sco.com>
+
+ * unwind-dw2.c (_Unwind_GetCFA): cast return to avoid warning
+ * config.gcc: make SCO use dbxelf.h and elfos.h; only use one
+ target fragment now: t-sco5; dont compile crti.o.
+ * config/i386/sco5.h: major overhaul to remove all COFF remnants
+ and to use elfos.h for most definitions.
+ (BSS_SECTION_ASM_OP): set correct segment attributes.
+ (PREFERED_DEBUGGING_TYPE): set to DWARF-2.
+ (DWARF2_UNWIND_INFO): Always set to 1.
+ (MD_STARTFILE_PREFIX): Make /usr/gnu/lib the default.
+ (MD_STARTFILE_PREFIX_1): Define.
+ (MD_EXEC_PREFIX): Adjust to /usr/gnu/bin if using GAS.
+ (DEFAULT_LINKER): Define if not specified to configure.
+ (CTORS_SECTION_ASM_OP): Remove COFF crud.
+ (DTORS_SECTION_ASM_OP): Remove COFF crud.
+ (WINT_TYPE): Define.
+ (SDB_DEBUGGING_INFO): Remove.
+ (EXTRA_SECTIONS): Likewise.
+ (EXTRA_SECTION_FUNCTIONS): Likewise.
+ (CTOR_LIST_BEGIN): Likewise.
+ (CTOR_LIST_END): Likewise.
+ (INIT_SECTION_FUNCTION): Likewise.
+ (FINI_SECTION_FUNCTION): Likewise.
+ (SUBTARGET_FRAME_POINTER_REQUIRED): Likewise.
+ (LOCAL_LABEL_PREFIX): Likewise.
+ (NON_SAVING_SETJMP): Likewise.
+ (RETURN_POPS_ARGS): Likewise.
+ (ASM_OUTPUT_SKIP): Likewise.
+ (TARGET_ASM_NAMED_SECTION): Likewise.
+ (ASM_OUTPUT_INTERNAL_LABEL): Likewise.
+ (ASM_OUTPUT_EXTERNAL_LIBCALL): Likewise.
+ (ASM_OUTPUT_IDENT): Likewise.
+ (ASM_OUTPUT_CASE_LABEL): Likewise.
+ (ASM_OUTPUT_ASCII): Likewise.
+ (ASM_OUTPUT_LIMITED_STRING): Likewise.
+ (ASM_OUTPUT_ALIGNED_LOCAL): Likewise.
+ (ASM_OUTPUT_ALIGNED_COMMON): Likewise.
+ (ASM_GENERATE_INTERNAL_LABEL): Likewise.
+ (ASM_FINISH_DECLARE_OBJECT): Likewise.
+ (ASM_DECLARE_OBJECT_NAME): Likewise.
+ (ASM_DECLARE_FUNCTION_SIZE): Likewise.
+ (ASM_DECLARE_FUNCTION_NAME): Likewise.
+ (ASM_DECLARE_RESULT): Likewise.
+ (ASM_WEAKEN_LABEL): Likewise.
+ (SUPPORTS_WEAK): Likewise.
+ (APPLY_RESULT_SIZE): Likewise.
+ (LPREFIX): Likewise.
+ (ALIGN_ASM_OP): Likewise.
+ (ASCII_DATA_ASM_OP): Likewise.
+ (IDENT_ASM_OP): Likewise.
+ (ASM_SHORT): Likewise.
+ (ASM_LONG): Likewise.
+ (TYPE_ASM_OP): Likewise.
+ (SIZE_ASM_OP): Likewise.
+ (STRING_ASM_OP): Likewise.
+ (SKIP_ASM_OP): Likewise.
+ (EH_FRAME_SECTION_ASM_OP): Likewise.
+ (READONLY_DATA_SECTION_ASM_OP): Likewise.
+ (INIT_SECTION_ASM_OP): Likewise.
+ (FINI_SECTION_ASM_OP): Likewise.
+ (TEXT_SECTION_ASM_OP): Likewise.
+ (DATA_SECTION_ASM_OP): Likewise.
+ (TYPE_OPERANT_FORMAT): Likewise.
+ (ASM_SPEC): Remove COFF code.
+ (STARTFILE_SPEC): Likewise. Always use crti.o; add -p and -pp support;
+ cause -pg to emit an error; use pcrt1elf.o with -pp
+ (ENDFILE_SPEC): Likewise.
+ (TARGET_OS_CPP_BUILTINS): Add _SCO_DS_LL.
+ (CPP_SPEC): Remove COFF crud; always look in /usr/gnu/include first.
+ (LINK_SPEC): Remove COFF crud; use -E for environment switch not -R;
+ add -z alt_resolve to support weak symbols the way GCC wants them.
+ (LIB_SPEC): Use the profiler libraries in -p or -pp mode.
+ (LIBGCC_SPEC): Dont use -lgcc in -G mode.
+ (ASM_PREFERED_EH_DATA_FORMAT): Remove.
+ * config/i386/t-sco5 (TARGET_LIBGCC2_CFLAGS): Remove.
+ (CRTSTUFF_T_CFLAGS_S): Define.
+ (MULTILIB_OPTIONS): Likewise.
+ (MULTILIB_DIRNAMES): Likewise.
+ (MULTILIB_MATCHES): Likewise.
+ (MULTILIB_EXTRA_OPTS): Likewise.
+ (LIBGCC): Likewise.
+ (INSTALL_LIBGCC): Likewise.
+ (crti.o): Remove.
+ * config/i386/t-sco5gas: Remove.
+ * doc/install.texi: Updated for new OpenServer instructions.
+ * testsuite/gcc.dg/nest.c: Allow failure on SCO (-pg not supported)
+
+2003-04-19 Kean Johnston <jkj@sco.com>
+
+ * fixinc/check.tpl: Allow user to over-ride diff program.
+ * fixinc/inclhack.def: Removed extraneous #ifndef SVR5.
+ (sco_math): Added test for SCO math header files.
+ (sco_regset): Added check for conflicts with ieeefp.h.
+ (svr4_disable_opt): Removed extraneous #ifdef SVR4.
+ * fixinc/fixincl.x: Regenerated
+ * fixinc/tests/base/math.h: Added sco_math tests.
+ * fixinc/tests/base/string.h: New file.
+ * fixinc/tests/base/sys/regset.h: New file.
+
+2003-04-19 Neil Booth <neil@daikokuya.co.uk>
+
+ * cpphash.h (struct cpp_buffer): Remove backup_to.
+ * cpplex.c (BACKUP, get_effective_char): Die.
+ (_cpp_skip_block_comment): Assume '*' is location on entry.
+ (continues_identifier_p): Respect -fno-dollars-in-identifiers.
+ (IF_NEXT_IS): Update.
+ (_cpp_lex_direct): Don't use backup_to; look ahead directly.
+
+2003-04-19 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * README.Portability: Move to a new section and obsolete K+R
+ portability issues.
+
+Sat Apr 19 14:56:17 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * rtlanal.c (subreg_offset_representable_p): Fix call of
+ subreg_lowpart.
+
+2003-04-19 Neil Booth <neil@daikokuya.co.uk>
+
+ * cpphash.h (struct cpp_reader): New member warned_dollar.
+ * cpplex.c (continues_identifier_p): New function.
+ (parse_identifier, parse_number, parse_string): Rename lex_identifer,
+ lex_number and lex_string, and simplify.
+ (parse_slow, unescaped_terminator_p): Die.
+ (_cpp_lex_direct): Update.
+
+2003-04-19 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * calls.c (expand_call): Provide init for old_stack_pointer_delta.
+
+2003-04-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * doc/invoke.texi (-fprofile-arcs): Mention -lgcov, locking and
+ fork behavior.
+
+2003-04-19 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppexp.c (eval_token): Permit true and false even if pedantic.
+
+2003-04-19 Neil Booth <neil@daikokuya.co.uk>
+
+ * cpplex.c (skip_whitespace): Rearrange to avoid stage1 ICE.
+
+2003-04-19 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (ENABLE_VALGRIND_CHECKING, VALGRIND_DISCARD,
+ MMAP_THRESHOLD, TEST_THRESHOLD, SHOULD_MMAP): Remove.
+ (struct include_file): Remove fefcnt, mapped members.
+ (open_file, stack_include_file, _cpp_pop_file_buffer): Disable caching.
+ (read_include_file): Don't use mmap, terminate buffers in '\r'.
+ (purge_cache): Don't use munmap.
+ * cpphash.h (CPP_BUF_COLUMN): Update.
+ (lexer_state): Remove lexing_comment.
+ (struct _cpp_line_note): New.
+ (struct cpp_buffer): New members cur_note, notes_used, notes_cap,
+ next_line and need_line. Remove col_adjust and saved_flags.
+ (_cpp_process_line_notes, _cpp_clean_line, _cpp_get_fresh_line,
+ _cpp_skip_block_comment, scan_out_logical_line): New.
+ (_cpp_init_mbchar): Remove.
+ * cppinit.c (init_library): Remove call to _cpp_init_mbchar.
+ (cpp_read_main_file): Set line to 1 earlier.
+ (post_options): -traditional-cpp doesn't want trigraphs.
+ * cpplex.c (MULTIBYTE_CHARS): Remove code predicated on this.
+ (add_line_note, _cpp_clean_line, _cpp_process_line_notes,
+ _cpp_get_fresh_line): New.
+ (handle_newline, skip_escaped_newlines, trigraph_p,
+ continue_after_nul, _cpp_init_mbchar): Remove.
+ (get_effective_char): Update.
+ (_cpp_skip_block_comment): Rename from skip_block_comment, simplify.
+ (skip_line_comment): Simplify.
+ (skip_whitespace, parse_identifier, parse_slow, parse_number,
+ parse_string): Update.
+ (cpp_lex_direct): Use clean lines and process line notes. Update.
+ (cpp_interpret_charconst): No MULTIBYTE_CHARS.
+ * cpplib.c (prepare_directive_trad): Call scan_out_logical_line
+ directly.
+ (_cpp_handle_directive): Don't set saved_flags.
+ (run_directive, destringize_and_run, cpp_define, cpp_define_builtin,
+ cpp_undef, handle_assertion, cpp_push_buffer): Update.
+ (_cpp_pop_buffer): Free notes.
+ * cppmacro.c (builtin_macro, paste_tokens): \n terminate buffer.
+ * cpppch.c (cpp_read_state): \n terminate buffer.
+ * cpptrad.c (skip_escaped_newlines, handle_newline): Remove.
+ (copy_comment): Use _cpp_skip_block_comment.
+ (skip_whitespace, lex_identifier, _cpp_read_logical_line_trad):
+ Simplify.
+ (_cpp_overlay_buffer, _cpp_remove_overlay, push_replacement_text,
+ save_replacement_text): Update.
+ (scan_out_logical_line): Update to use clean lines and process
+ line notes.
+ * fix-header.c (read_scan_file): Update.
+
+2003-04-18 Douglas B Rupp <rupp@gnat.com>
+
+ * unwind-dw2-fde.c (__register_frame_info_bases): Check for
+ null begin parameter (as well as pointer to null).
+ (__deregister_frame_info_bases): Likewise.
+
+2003-04-18 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * function.c (purge_addressof_1): For ADDRESSOF, see if SUB is a
+ hard or virtual register and copy into pseudo if replacement fails.
+
+ * cfgcleanup.c (flow_find_cross_jump): Use INSN_P, not active_insn_p.
+
+ * expmed.c (mask_rtx): Avoid undefined shifts for BITSIZE of 0.
+
+2003-04-18 Olivier Hainque <hainque@act-europe.fr>
+
+ * calls.c (expand_call): Move special case for constructor calls
+ to right place. Ensures constructor calls used to initialize
+ arguments get a clean outgoing argument block for themselves.
+ Move check for stack deallocation completeness until after last
+ deallocation. Add stack_pointer_delta to set of state
+ variables saved and restored along with current stack_level.
+
+ * integrate.c (expand_inline_function): Ensure non-const actuals
+ don't end up const in the caller's flow after conversion to possibly
+ const formal type.
+
+2003-04-18 Vincent Celier <celier@gnat.com>
+
+ * dwarf2out.c (loc_descriptor_from_tree): Treat all *_MOD_EXPR
+ and *_DIV_EXPR as TRUNC_*_EXPR.
+
+2003-04-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cfgrtl.c (try_redirect_by_replacing_jump): Create a basic block
+ for orphaned jump tables.
+
+2003-04-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * reload1.c: Revert my previous patch on 2002-04-17.
+
+2003-04-18 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/contrib.texi (Contributors): Prefer "bug fix" over "bugfix".
+ Add Segher Boessenkool.
+
+2003-04-18 Alexander Sotirov <sluncho@mirizma.org>
+
+ PR c/9177
+ * c-decl.c (c_expand_body): Don't garbage collect the function
+ body if we are going to dump it later.
+
+2003-04-18 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (SYMBOL_FLAG_NEAR, SYMBOL_FLAG_SAMEGP): Remove.
+ (alpha_end_function): Don't set them.
+ (decl_in_text_section): Remove.
+ (alpha_encode_section_info): Remove.
+ (samegp_function_operand): Use SYMBOL_REF LOCAL_P and EXTERNAL_P.
+ (direct_call_operand): Use SYMBOL_REF_DECL and compare actual
+ sections, rather than decl_in_text_section results.
+
+2003-04-18 Roger Sayle <roger@eyesopen.com>
+
+ * rtlanal.c (reg_overlap_mentioned_p): Handle ZERO_EXTRACT
+ and SIGN_EXTRACT.
+
+2003-04-18 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/7675
+ * c-typeck.c (build_external_ref): Set the DECL_NONLOCAL flag
+ on VAR_DECL, PARM_DECL and FUNCTION_DECL from within
+ nested functions if they refer to declarations from parent functions.
+ * stmt.c (expand_decl): Don't put automatic variables in registers
+ if the DECL_NONLOCAL flag is set.
+
+2003-04-18 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * gcse.c (compute_ld_motion_mems): For MEM destinations, only
+ consider those to be movable where the source matches
+ want_to_gcse_p.
+ (update_ld_motion_stores): In comment, refer to
+ compute_ld_motion_mems for validity of replacement.
+
+Fri Apr 18 01:28:51 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * gcov-dump.c (tag_summary): Remove max_sum
+ * gcov-io.h (gcov_summary, gcov_write_summary,
+ gcov_read_summary): Kill max_sum.
+ * libgcov.c (gcov_exit): Do one pass over the data. Make error
+ message more verbose.
+
+ * emit-rtl.c (subreg_hard_regno): Check that register is
+ representable.
+
+ * reload.c (reload_inner_reg_of_subreg): When register is not
+ representable, reload the whole thing.
+ (find_reloads): Likewsie.
+ * rtlanal.c (subreg_representable_p): New function.
+
+ * profile.c (compute_branch_probabilities): Cleanup sanity checking;
+ allow negative probabilities for edges from the call to exit.
+ (branch_prob): Do not add fake edges for functions that may return
+ twice.
+
+2003-04-17 DJ Delorie <dj@redhat.com>
+
+ * toplev.c (target_options): Add value field.
+ (set_target_switch): Handle target options with values.
+ * doc/tm.texi: Document how fixed vs variable target
+ options work.
+ * config/alpha/alpha.h, config/arc/arc.h, config/avr/avr.h,
+ config/c4x/c4x.h, config/cris/aout.h, config/cris/cris.h,
+ config/d30v/d30v.h, config/dsp16xx/dsp16xx.h,
+ config/frv/frv.h, config/i386/i386.h, config/ia64/ia64.h,
+ config/m32r/m32r.h, config/m68hc11/m68hc11.h,
+ config/m68k/m68k.h, config/m88k/m88k.h, config/mcore/mcore.h,
+ config/mips/mips.h, config/mmix/mmix.h, config/pa/pa.h,
+ config/rs6000/rs6000.h, config/rs6000/sysv4.h,
+ config/s390/s390.h, config/sparc/sparc.h, config/v850/v850.h:
+ Add value initializer to target options.
+
+2003-04-07 Loren James Rittle <ljrittle@acm.org>
+
+ * cpppch.c (cpp_valid_state): Unconditionally initialize nl.
+
+2003-04-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * reload1.c (move2add_last_cc0): New.
+ (reload_cse_move2add): Detect implicit sets.
+ (move2add_note_store): Notice a store into cc0.
+
+2003-04-17 Roger Sayle <roger@eyesopen.com>
+
+ PR c/10375
+ * c-decl.c (duplicate_decls): Preserve "const" and "noreturn"
+ function attributes.
+
+2003-04-17 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/sourcebuild.texi (Test Suites): Document support for testing
+ binary compatibility (moved from testsuite/README.compat).
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.c (ia64_in_small_data_p): Disallow strings.
+
+2003-04-17 Simon Law <sfllaw@engmail.uwaterloo.ca>
+
+ * doc/include/gpl.texi: Fix double-spacing after "MA" to match
+ the one provided by the FSF.
+
+2003-04-17 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/install.texi (Binaries): Update URL and list of platforms
+ provided by ftp.thewrittenword.com.
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * config/xtensa/xtensa.c (xtensa_encode_section_info): Remove.
+ (call_insn_operand): Use SYMBOL_REF_LOCAL_P.
+ * config/xtensa/xtensa.md (call, call_value): Likewise.
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * config/v850/v850.c (print_operand): Use SYMBOL_REF_[ZST]DA.
+ (print_operand_address): Likewise.
+ (ep_memory_operand): Likewise.
+ (special_symbolref_operand): Likewise.
+ (v850_encode_data_area): Use SYMBOL_REF_FLAGS.
+ (v850_encode_section_info): Call default_encode_section_info.
+ (v850_strip_name_encoding): Remove.
+ * config/v850/v850.h (EXTRA_CONSTRAINT): Use SYMBOL_REF_[ZST]DA.
+ (ASM_OUTPUT_LABELREF): Remove.
+ (ZDA_NAME_FLAG_CHAR, ZDA_NAME_P): Remove.
+ (SDA_NAME_FLAG_CHAR, SDA_NAME_P): Remove.
+ (TDA_NAME_FLAG_CHAR, TDA_NAME_P): Remove.
+ (ENCODED_NAME_P): Remove.
+ (SYMBOL_FLAG_ZDA, SYMBOL_REF_ZDA_P): New.
+ (SYMBOL_FLAG_SDA, SYMBOL_REF_SDA_P): New.
+ (SYMBOL_FLAG_TDA, SYMBOL_REF_TDA_P): New.
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * config/stormy16/stormy16.c (xstormy16_encode_section_info): Kill.
+ * config/stormy16/stormy16.h (ASM_OUTPUT_SYMBOL_REF): Use
+ SYMBOL_REF_FUNCTION_P.
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * config/sparc/sparc.c (sparc_encode_section_info): Remove.
+ (data_segment_operand): Use SYMBOL_REF_FUNCTION_P.
+ (text_segment_operand): Likewise.
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * config/sh/sh.c (gen_datalabel_ref): Don't add SH_DATALABEL_ENCODING.
+ (tls_symbolic_operand): Use SYMBOL_REF_TLS_MODEL.
+ (legitimize_pic_address): Use SYMBOL_REF_LOCAL_P.
+ (sh_encode_section_info): Remove.
+ (sh_strip_name_encoding): Remove.
+ * config/sh/sh.h (SH_DATALABEL_ENCODING): Remove.
+ (DATALABEL_SYMNAME_P, STRIP_DATALABEL_ENCODING): Remove.
+ (SH_TLS_ENCODING, TLS_SYMNAME_P, STRIP_TLS_ENCODING): Remove.
+ (ASM_OUTPUT_LABELREF): Remove.
+ (ASM_OUTPUT_SYMBOL_REF): Use SYMBOL_REF_FUNCTION_P.
+ * config/sh/sh.md (*): Use SYMBOL_REF_LOCAL_P.
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * config/s390/s390.c (SYMBOL_FLAG_ALIGN1): New.
+ (tls_model_chars): Remove.
+ (larl_operand): Use SYMBOL_REF_FLAGS.
+ (tls_symbolic_operand): Use SYMBOL_REF_TLS_MODEL.
+ (legitimize_pic_address): Use SYMBOL_REF_LOCAL_P.
+ (s390_output_mi_thunk): Likewise.
+ (s390_emit_prologue): Set SYMBOL_FLAG_LOCAL as needed.
+ (s390_function_profiler): Likewise.
+ (s390_encode_section_info): Use default_encode_section_info
+ and SYMBOL_FLAG_ALIGN1.
+ (s390_strip_name_encoding): Remove.
+ * config/s390/s390.h (ASM_OUTPUT_LABELREF): Remove.
+ * config/s390/s390.md (call, call_value): Use SYMBOL_REF_LOCAL_P.
+ (builtin_setjmp_receiver): Set SYMBOL_FLAG_LOCAL as needed.
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * config/ns32k/ns32k.c (ns32k_encode_section_info): Remove.
+ (global_symbolic_reference_mentioned_p): Use SYMBOL_REF_LOCAL_P.
+ (print_operand_address): Likewise.
+
+ * config/ns32k/ns32k.h (CANNOT_CHANGE_MODE_CLASS): Add CLASS argument.
+ * config/ns32k/ns32k.c (expand_block_move): Don't check
+ flag_unroll_loops.
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * config/mcore/mcore.c (mcore_encode_section_info): Don't set
+ SYMBOL_REF_FLAG.
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * rtl.h (SYMBOL_FLAG_MACH_DEP_SHIFT): New.
+
+ * config/m32r/m32r.c (SYMBOL_FLAG_MODEL_SHIFT): New.
+ (SYMBOL_REF_MODEL): New.
+ (LIT_NAME_P): Move from m32r.h.
+ (m32r_select_section): Remove.
+ (m32r_encode_section_info): Use SYMBOL_REF_FLAGS.
+ (m32r_strip_name_encoding): Remove.
+ (m32r_in_small_data_p): New.
+ (small_data_operand): Use SYMBOL_REF_SMALL_P.
+ (addr24_operand): Use SYMBOL_REF_MODEL.
+ (call26_operand): Likewise.
+ (addr32_operand): Tidy.
+ (m32r_print_operand): Use HOST_WIDE_INT_PRINT_HEX.
+ * config/m32r/m32r.h (RODATA_SECTION_ASM_OP): Remove.
+ (SDATA_SECTION_ASM_OP, SBSS_SECTION_ASM_OP): Remove.
+ (READONLY_DATA_SECTION_ASM_OP): Remove.
+ (EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS): Remove.
+ (SDATA_SECTION_FUNCTION, SBSS_SECTION_FUNCTION): Remove.
+ (TARGET_ASM_SELECT_SECTION): Remove.
+ (SDATA_FLAG_CHAR, MEDIUM_FLAG_CHAR, LARGE_FLAG_CHAR): Remove.
+ (SDATA_NAME_P, SMALL_NAME_P, MEDIUM_NAME_P): Remove.
+ (LARGE_NAME_P, ENCODED_NAME_P): Remove.
+ (ASM_OUTPUT_LABELREF): Remove.
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * config/ip2k/ip2k.c (is_regfile_address): Use SYMBOL_REF_FUNCTION_P.
+ (encode_section_info): Remove.
+ * config/ip2k/ip2k-protos.h: Update.
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * varasm.c (default_encode_section_info): Don't set
+ SYMBOL_FLAG_EXTERNAL if not TREE_PUBLIC.
+ * config/i370/i370.c (i370_encode_section_info): Remove.
+ * config/i370/i370.h (CONSTANT_ADDRESS_P): Use SYMBOL_REF_EXTERNAL_P.
+ (PRINT_OPERAND, PRINT_OPERAND_ADDRESS): Likewise.
+ * config/i370/i370.md (movsi): Likewise.
+
+ * config/i370/t-i370: Add missing backslash.
+
+2003-04-17 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/invoke.texi (inline-limit): Fix pasto.
+
+2003-04-17 Richard Henderson <rth@redhat.com>
+
+ * config/h8300/h8300.c (SYMBOL_FLAG_FUNCVEC_FUNCTION): New.
+ (small_call_insn_operand): Use it.
+ (SYMBOL_FLAG_EIGHTBIT_DATA): New.
+ (h8300_eightbit_constant_address_p): Use it.
+ (SYMBOL_FLAG_TINY_DATA): New.
+ (h8300_tiny_constant_address_p): Use it.
+ (h8300_encode_label, h8300_strip_name_encoding): Remove.
+ (h8300_encode_section_info): Set SYMBOL_REF_FLAGS.
+ * config/h8300/h8300.h (TINY_DATA_NAME_P): Remove.
+ (ASM_OUTPUT_LABELREF): Remove.
+
+2003-04-16 Richard Henderson <rth@redhat.com>
+
+ * config/frv/frv.c (symbol_ref_small_data_p): Remove. Replace
+ all users with SYMBOL_REF_SMALL_P.
+ (const_small_data_p): Use SYMBOL_REF_SMALL_P.
+ (frv_encode_section_info): Remove.
+ (frv_strip_name_encoding): Remove.
+ (frv_in_small_data_p): Merge tests from encode_section_info.
+ (frv_print_operand): Use '@' not SDATA_FLAG_CHAR.
+ * config/frv/frv.h (SDATA_FLAG_CHAR): Remove.
+ (SDATA_NAME_P): Remove.
+ (ASM_OUTPUT_ALIGNED_DECL_LOCAL): Use SIZE not SDATA_NAME_P.
+ (ASM_OUTPUT_LABELREF): Remove.
+ (PRINT_OPERAND_PUNCT_VALID_P): Use '@' not SDATA_FLAG_CHAR.
+
+ * config/frv/frv.c (frv_asm_out_constructor): New.
+ (frv_asm_out_destructor): New.
+ * config/frv/frv.h (CTORS_SECTION_ASM_OP): New.
+ (DTORS_SECTION_ASM_OP): New.
+ (ASM_OUTPUT_CONSTRUCTOR): Remove.
+ (ASM_OUTPUT_DESTRUCTOR): Remove.
+
+2003-04-16 Richard Henderson <rth@redhat.com>
+
+ * config/cris/cris.c (cris_gotless_symbol, cris_got_symbol): Use
+ SYMBOL_REF_LOCAL_P; abort if not pic.
+ (cris_encode_section_info): Remove.
+
+2003-04-16 Richard Henderson <rth@redhat.com>
+
+ * config/c4x/c4x.c (c4x_encode_section_info): Remove.
+ (c4x_T_constraint): Use SYMBOL_REF_FUNCTION_P.
+
+ * config/c4x/c4x.h (TARGET_CPU_CPP_BUILTINS): Declare
+ flag_inline_trees.
+
+2003-04-16 Richard Henderson <rth@redhat.com>
+
+ * config/avr/avr.c (avr_encode_section_info): Remove.
+ (avr_insert_attributes): New.
+ (print_operand_address): Use SYMBOL_REF_FUNCTION_P.
+ (avr_assemble_integer): Likewise.
+
+2003-04-16 Richard Henderson <rth@redhat.com>
+
+ * arc.c (arc_encode_section_info): Remove.
+ (arc_assemble_integer): Use SYMBOL_REF_FUNCTION_P.
+ (arc_print_operand, arc_print_operand_address): Likewise.
+ * arc.h (EXTRA_CONSTRAINT): Likewise.
+
+2003-04-16 Roger Sayle <roger@eyesopen.com>
+
+ * c-semantics.c (find_reachable_label): New function to find a
+ potentially reachable label in an expression.
+ (expand_unreachable_if_stmt): Similar to expand_if_stmt but
+ assumes the start of the IF_STMT is unreachable (dead) code.
+ (expand_unreachable_stmt): Similar to expand_stmt but assumes
+ the start of the statement list is unreachable (dead) code.
+ (genrtl_if_stmt): If the controlling expression of the IF
+ is constant, use expand_unreachable_stmt for the THEN or ELSE
+ clause as appropriate.
+ (genrtl_switch_stmt): Use expand_unreachable_stmt to expand
+ the body of a SWITCH statement.
+ (expand_stmt): The code immediately following a "return",
+ "break", "continue" or "goto" is unreachable.
+ * Makefile.in (c-semantics.o): Depend upon tree-inline.h.
+
+2003-04-16 Richard Henderson <rth@redhat.com>
+
+ * rtl.h (MEM_ALIAS_SET): Update documentation.
+ * doc/rtl.texi (Special Accessors): New node.
+ (SYMBOL_REF_FLAG): Note relationship with SYMBOL_REF_FLAGS.
+
+2003-04-16 Alexandre Oliva <aoliva@redhat.com>
+
+ * reload1.c (reload_cse_noop_set_p): Return false if mode of
+ SET_DEST is not the same as that returned by...
+ * cselib.h (cselib_reg_set_mode): ... new function.
+ * cselib.c (cselib_reg_set_mode): Define it.
+ (REG_VALUES): Document semantics of first element as set mode.
+ (cselib_subst_to_values): Skip first element if ELT is NULL.
+ (cselib_lookup): Likewise. Insert past the first element.
+ (cselib_invalidate_regno): NULLify first element.
+ (cselib_record_set): Set first element.
+
+2003-04-16 Olivier Hainque <hainque@act-europe.fr>
+
+ * tree.c (skip_simple_arithmetics_at, saved_expr_p): New functions.
+ (save_expr): Replace loop by call to skip_simple_arithmetics_at.
+ * tree.h: Add prototypes for the two new functions.
+ * fold-const.c (fold_binary_op_with_conditional_arg): Replace test
+ updates introduced in the previous revision by call to saved_expr_p.
+ * stor-layout.c (put_pending_size): Use skip_simple_arithmetics_at.
+
+ * expr.c (store_field): Force usage of bitfield instructions when
+ the field position requires it, whatever SLOW_UNALIGNED_ACCESS.
+ (expand_expr, case BIT_FIELD_REF): likewise.
+
+2003-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR middle-end/8866
+ * cfgtrl.c (try_redirect_by_replacing_jump): Do not delete
+ jumptables.
+
+2003-04-16 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.c (sdata_symbolic_operand): Use
+ SYMBOL_REF_SMALL_P and SYMBOL_REF_LOCAL_P.
+ (tls_symbolic_operand): Use SYMBOL_REF_TLS_MODEL.
+ (function_operand): Use SYMBOL_REF_FUNCTION_P.
+ (ia64_expand_load_address): Likewise.
+ (ia64_assemble_integer): Likewise.
+ (ia64_encode_section_info): Remove.
+ (ia64_strip_name_encoding): Remove.
+ * config/ia64/ia64.h (ENCODE_SECTION_INFO_CHAR): Remove.
+ * config/ia64/sysv4.h (ASM_OUTPUT_LABELREF): Don't strip it.
+
+2003-04-16 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (SYMBOL_FLAG_NEAR, SYMBOL_FLAG_SAMEGP): New.
+ (samegp_function_operand): Use SYMBOL_FLAG_SAMEGP.
+ (direct_call_operand): Use SYMBOL_FLAG_NEAR.
+ (local_symbolic_operand): Use SYMBOL_REF_LOCAL_P.
+ (small_symbolic_operand): Use SYMBOL_REF_SMALL_P.
+ (global_symbolic_operand): Similarly.
+ (tls_symbolic_operand_1): Use SYMBOL_REF_TLS_MODEL.
+ (tls_symbolic_operand_type): Likewise.
+ (alpha_encode_section_info): Use default_encode_section_info.
+ (alpha_strip_name_encoding): Remove.
+ (get_tls_get_addr): Split out from ...
+ (alpha_legitimize_address): ... here.
+ (alpha_emit_xfloating_libcall): Use init_one_libfunc.
+ (get_some_local_dynamic_name_1): Use SYMBOL_REF_TLS_MODEL.
+ (alpha_initialize_trampoline): Use init_one_libfunc.
+ (alpha_setup_incoming_varargs): Mark unused parameters.
+ (alpha_initial_elimination_offset): Likewise.
+ (alpha_end_function): Use SYMBOL_FLAG_NEAR, SYMBOL_FLAG_SAMEGP.
+ (unicosmk_unique_section): Use default_strip_name_encoding.
+ (unicosmk_ssib_name, unicosmk_output_externs): Likewise.
+
+2003-04-16 Aldy Hernandez <aldyh@redhat.com>
+
+ * config.gcc: Add t-spe for eabispe.
+
+ * config/rs6000/t-spe: New.
+
+2003-04-16 J"orn Rennecke <joern.rennecke@superh.com>
+
+ Re-apply this patch:
+
+ 2002-05-16 Dale Johannesen <dalej@apple.com>
+ * combine.c (cant_combine_insn_p): Reenable combinations
+ involving hard regs unless CLASS_LIKELY_SPILLED_P.
+
+2003-04-16 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR/10271
+ * pa-protos.h (function_arg): Remove last argument.
+ * pa.c (function_arg): Likewise. Use CUMULATIVE_ARGS struct instead.
+ * pa.h (struct hppa_args): Add member incoming.
+ (INIT_CUMULATIVE_ARGS, INIT_CUMULATIVE_INCOMING_ARGS): Initialize
+ member incoming.
+ (FUNCTION_ARG): Revise call to function_arg.
+ (FUNCTION_INCOMING_ARG): Delete.
+
+2003-04-15 Zack Weinberg <zack@codesourcery.com>
+
+ * configure.in: Unify the code which creates symlinks to a
+ just-built as, ld, objdump, and nm with the code that detects
+ their presence for purposes of feature tests.
+ * configure: Regenerate.
+
+2003-04-15 Zack Weinberg <zack@codesourcery.com>
+
+ * varasm.c (output_constant_def): Do not consult
+ CONSTANT_AFTER_FUNCTION_P. Remove all code predicated on it.
+ (after_function_constants, output_after_function_constants): Delete.
+ * doc/tm.texi: Delete documentation of CONSTANT_AFTER_FUNCTION_P.
+ * config/mips/mips-protos.h, config/mips/mips.c
+ (mips16_constant_after_function_p): Delete.
+ * config/mips/mips.h: Delete #if-0-ed definition of
+ CONSTANT_AFTER_FUNCTION_P.
+ * config/d30v/d30v.h, config/stormy16/stormy16.h: Remove
+ mention of CONSTANT_AFTER_FUNCTION_P in comment.
+
+2003-04-15 Geoffrey Keating <geoffk@apple.com>
+
+ * tree.c (next_decl_uid): Mark with GTY.
+ (next_type_uid): Likewise.
+
+2003-04-15 J"orn Rennecke <joern.rennecke@superh.com>
+
+ PR target/9594:
+ * sh.c (barrier_align): Also recognize stuff_delay_slot as
+ an indicator that a barrier was created by branch splitting.
+
+2003-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * c-decl.c (implicitly_declare): Copy declarations that are going
+ to be placed in a local scope.
+
+2003-04-15 James A. Morrison <ja2morri@uwaterloo.ca>
+
+ * invoke.texi (Spec Files): Wrap if-exists-else example.
+ (MCore): Remove duplicate @itemx entries and @opindex entries.
+
+2003-04-15 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * unwind.inc (_Unwind_Backtrace): New function.
+ * unwind.h (_Unwind_Backtrace): Declare it.
+ * libgcc-std.ver (_Unwind_Backtrace): Export it.
+
+2003-04-14 Jason Merrill <jason@redhat.com>
+
+ PR middle-end/10336, c++/10401
+ * jump.c (never_reached_warning): Also stop looking if we reach the
+ beginning of the function.
+
+2003-04-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ PR target/10338
+ PR bootstrap/10198
+ PR bootstrap/10140
+ * fixinc/gnu-regex.c (regerror): Use mempcpy not __mempcpy.
+
+2003-04-15 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * i386.md (abssf2_if+1): Make condition agree with abssf2_1 .
+
+2003-04-15 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * optabs.c (expand_binop): In multi-word add cases, ensure
+ XTARGET is copied to TARGET if they are different.
+
+2003-04-15 Olivier Hainque <hainque@act-europe.fr>
+
+ * except.c (resolve_fixup_regions): Avoid dereferencing null pointer
+ to region, possible after integration of function with unreachable
+ regions that were optimized away.
+
+2003-04-15 Jakub Jelinek <jakub@redhat.com>
+
+ * config/rs6000/rs6000.h (EPILOGUE_USES): Use register 2,
+ instead of TOC_REGISTER in epilogue in
+ current_function_calls_eh_return functions.
+
+2003-04-14 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/extend.texi (Empty Structures): Correct description of G++'s
+ handling of these structures.
+
+ * c-decl.c (grokdeclarator): Reject extern redeclarations of
+ static variables.
+
+2003-04-14 Janis Johnson <janis287@us.ibm.com>
+
+ * config/rs6000/rs6000.md (define_constants): Define constants for
+ all UNSPEC usage, including new values for TLS support.
+ (aux_truncdfsf2, fctiwz, movsi_got, movsi_got_internal,
+ load_toc_aix_si, load_toc_aix_di, load_toc_v4_pic_si,
+ load_toc_v4_PIC_1, load_toc_v4_PIC_1b, load_macho_picbase,
+ macho_correct_pic, blockage, move_from_CR_ov_bit, movesi_from_cr,
+ stack_tie, movsi_to_cr_one, movsi_to_cr, mtcrfsi, eh_set_lr_si,
+ eh_set_lr_di): Use them.
+ * rs6000.c: (mtcrf_operation, uses_TOC, rs6000_emit_prologue,
+ rs6000_emit_epilogue) Use them.
+
+ * rtl.h (SYMBOL_REF_TLS_MODEL): Fix mask value.
+
+2003-04-14 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in (c-opts.o): Use custom action.
+
+2003-04-14 Douglas B Rupp <rupp@gnat.com>
+
+ * ifcvt.c (noce_process_if_block): Fail on BLKmode move.
+
+2003-04-14 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * stor-layout.c (layout_type, case ARRAY_TYPE): Add missing code to
+ handle "superflat arrays" in Ada.
+
+ * integrate.c (expand_inline_function): Don't inline if would
+ lose /u on a BLKmode TARGET.
+
+2003-04-14 Joel Brobecker <brobecker@gnat.com>
+
+ * dbxout.c (print_int_cst_bounds_in_octal_p): New function,
+ extracted from dbxout_type.
+ (dbxout_range_type): print large bounds in octal format.
+ (dbxout_type): Replace extracted code by call to
+ print_int_cst_bounds_in_octal_p.
+
+ * dwarf2out.c (gen_compile_unit_die): Emit DW_LANG_Ada95 instead
+ of DW_LANG_Ada83 for Ada units.
+
+2003-04-14 Olivier Hainque <hainque@act-europe.fr>
+
+ * explow.c (round_push): Use HOST_WIDE_INT instead of int for the
+ temporary used to round CONST_INT sizes.
+
+ * tree.c (int_fits_type_p): Extract generic checks from the case
+ of constant type bounds. Refine the checks against constant type
+ bounds to allow for possible decisions against each of these bounds
+ without requiring both bounds to be constant.
+ (tree_int_cst_msb): Put back.
+ * tree.h (tree_int_cst_msb): Likewise.
+
+ * global.c (global_conflicts): Prevent allocation of call clobbered
+ hard regs to pseudos live across abnormal edges, as later passes are
+ not ready to handle them.
+
+ * fold-const.c (fold): Reorder tests for conditional expressions.
+
+ * expr.c (highest_pow2_factor): Return unsigned.
+ * expr.h (offset_address): Likewise.
+ * emit-rtl.c (offset_address): POW2 argument now unsigned.
+
+2003-04-14 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (expand_builtin_strlen): Evaluate the lengths of
+ string literals at compile-time.
+
+2003-04-14 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold): Transform (c1 - x) cmp c2, where cmp is a
+ comparison operation and c1/c2 are floating point constants into
+ x swap(cmp) (c1 - c2).
+
+2003-04-14 Vladimir Makarov <vmakarov@redhat.com>
+
+ * genautomata.c (output_translate_vect): Fix a typo in loop
+ condition.
+
+2003-04-14 Hans-Peter Nilsson <hp@axis.com>
+
+ PR target/10377
+ * config/cris/cris.md ("*mov_sideqi", "*mov_sidehi")
+ ("*mov_sidesi", "*mov_sideqi_mem", "*mov_sidehi_mem")
+ ("*mov_sidesi_mem", "*clear_sidesi", "*clear_sidehi")
+ ("*clear_sideqi", "*ext_sideqihi", "*ext_sideqisi")
+ ("*ext_sidehisi", "*op_sideqi", "*op_sidehi", "*op_sidesi")
+ ("*op_swap_sideqi", "*op_swap_sidehi", "*op_swap_sidesi")
+ ("*extopqihi_side", "*extopqisi_side", "*extophisi_side")
+ ("*extopqihi_swap_side", "*extopqisi_swap_side")
+ ("*extophisi_swap_side", 8th, 9th, 10th, 11th, 14th peepholes):
+ When next to constraint R, replace constraint i with n.
+
+Mon Apr 14 16:18:37 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ PR opt/10024
+ * cfgrtl.c (force_nonfallthru_and_redirect): Use unchecked_make_edge.
+
+2003-04-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * doc/contrib.texi (Contributors): Correct my entry.
+
+2003-04-13 Roger Sayle <roger@eyesopen.com>
+
+ * tree.h (DECL_BUILT_IN_NONANSI): Remove.
+ * c-common.c (builtin_function_2): Don't set DECL_BUILT_IN_NONANSI.
+ * c-decl.c (duplicate_decls): Use invariant DECL_BUILT_IN_NONANSI
+ implies DECL_BUILT_IN to simplify logic.
+ * print-tree.c (print_node): Don't dump DECL_BUILT_IN_NONANSI.
+
+2003-04-13 Roger Sayle <roger@eyesopen.com>
+
+ * builtin-types.def (BT_FN_STRING_CONST_STRING): New builtin type.
+ (BT_FN_PTR_SIZE_SIZE): Likewise.
+ * builtins.def (BUILT_IN_MALLOC, BUILT_IN_CALLOC, BUILT_IN_STRDUP):
+ New built-in functions for malloc, calloc and strdup respectively.
+ * calls.c (special_function_p): No need to handle malloc-like
+ functions any longer. ECF_MALLOC is set via built-in attributes.
+
+ * c-decl.c (duplicate_decls): Preserve pure and malloc attributes.
+
+ * doc/extend.texi: Document these new built-in functions.
+
+2003-04-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (expand_builtin_memcpy): Add `endp' argument, use it.
+ (expand_builtin_stpcpy): New.
+ (expand_builtin): Add BUILT_IN_MEMPCPY & BUILT_IN_STPCPY.
+ * builtins.def: Add mempcpy & stpcpy support.
+ * doc/extend.texi (mempcpy, stpcpy): Document new builtins.
+
+2003-04-13 Nick Clifton <nickc@redhat.com>
+
+ * config/rs6000/rs6000.c: Replace occurrences of "GNU CC" with
+ "GCC".
+ * config/rs6000/40x.md, config/rs6000/603.md,
+ config/rs6000/6xx.md, config/rs6000/7450.md, config/rs6000/7xx.md,
+ config/rs6000/8540.md, config/rs6000/aix.h, config/rs6000/aix31.h,
+ config/rs6000/aix3newas.h, config/rs6000/aix41.h,
+ config/rs6000/aix43.h, config/rs6000/aix51.h,
+ config/rs6000/aix52.h, config/rs6000/altivec-defs.h,
+ config/rs6000/altivec.h, config/rs6000/altivec.md,
+ config/rs6000/beos.h, config/rs6000/darwin.h,
+ config/rs6000/eabi.h, config/rs6000/eabialtivec.h,
+ config/rs6000/eabisim.h, config/rs6000/eabispe.h,
+ config/rs6000/freebsd.h, config/rs6000/gnu.h,
+ config/rs6000/host-darwin.c, config/rs6000/linux.h,
+ config/rs6000/linux64.h, config/rs6000/linuxaltivec.h,
+ config/rs6000/lynx.h, config/rs6000/mach.h, config/rs6000/mpc.md,
+ config/rs6000/netbsd.h, config/rs6000/power4.md,
+ config/rs6000/rios1.md, config/rs6000/rios2.md,
+ config/rs6000/rs6000-c.c, config/rs6000/rs6000-modes.def,
+ config/rs6000/rs6000-protos.h, config/rs6000/rs6000.c,
+ config/rs6000/rs6000.h, config/rs6000/rs6000.md,
+ config/rs6000/rs64.md, config/rs6000/rtems.h, config/rs6000/spe.h,
+ config/rs6000/spe.md, config/rs6000/sysv4.h,
+ config/rs6000/sysv4le.h, config/rs6000/vxworks.h,
+ config/rs6000/windiss.h, config/rs6000/xcoff.h: Likewise.
+
+2003-04-13 Nick Clifton <nickc@redhat.com>
+
+ * config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Delete
+ support for -mcall-aix switch.
+ * config/rs6000/eabiaix.h: Delete.
+ * config/rs6000/rs6000.h (rs6000_abi): Remove ABI_AIX_NODESC.
+ (RS6000_REG_SAVE, RS6000_SAVE_AREA, FP_ARGS_MAX_REG,
+ RETURN_ADDRESS_OFFSET): Remove use of ABI_AIX_NODESC.
+ * config/rs6000/rs6000-c.c (rs6000_cpu_cpp_builtins): Likewise.
+ * config/rs6000/rs6000.c (print_operand, rs6000_stack_info,
+ debug_stack_info, output_function_profiler,
+ rs6000_trampoline_size, rs6000_initialise_trampoline): Likewise.
+ * config/rs6000/rs6000.md (call, call_value, call_nonlocal_sysv,
+ call_indirect_nonlocal_sysv, call_value_indirect_nonlocal_sysv,
+ call_value_nonlocal_sysv, sibcall_value_nonlocal_sysv,
+ sibcall_nonlocal_sysv, sibcall_value_local64): Likewise.
+ * config/rs6000/t-ppcgas (MULTILIB_OPTIONS): Remove mcall-aix
+ multilibs.
+ (MULTILIB_DIRNAMES): Remove mcall-aix directories.
+ (MULTILIB_EXCEPTIONS): Delete.
+ (MULTILIB_MATCHES): Remove mcall-aix matches.
+
+ * doc/fragments.texi: Replace -mcall-aix example with an ARM
+ one.
+ * doc/install.texi: Delete powerpc-*-eabiaix target.
+ * doc/invoke.texi: Remove documentation of mcall-aix switch.
+ * doc/tm.texi: Remove mcall-aix from example CPP_SPEC.
+ * config.gcc: Delete powerpc-*-eabiaix target.
+
+2003-04-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/invoke.texi: Fix typos.
+ * doc/tm.texi: Likewise.
+
+2003-04-12 Zack Weinberg <zack@codesourcery.com>
+
+ * c-typeck.c (digest_init, push_init_level): Use CONSTRUCTOR_ELTS.
+
+2003-04-12 Zack Weinberg <zack@codesourcery.com>
+
+ * tree.c (build_constructor): New function.
+ * tree.h: Prototype it.
+
+ * c-typeck.c (build_c_cast, pop_init_level)
+ * profile.c (build_function_info_value, build_gcov_info_value)
+ (create_profiler):
+ Use build_constructor.
+
+ * builtins.c (expand_builtin_args_info): Remove #if 0 blocks.
+
+ * objc/objc-act.c (build_constructor):
+ Rename objc_build_constructor. Use build_constructor.
+ (build_objc_string_object, objc_add_static_instance)
+ (init_def_list, init_objc_symtab, init_module_descriptor)
+ (generate_static_references, build_selector_translation_table)
+ (build_descriptor_table_initializer, generate_descriptor_table)
+ (build_protocol_initializer, build_ivar_list_initializer)
+ (generate_ivars_list, build_dispatch_table_initializer)
+ (generate_dispatch_table, generate_protocol_list)
+ (build_category_initializer, build_shared_structure_initializer):
+ Update to match.
+
+2003-04-12 Zack Weinberg <zack@codesourcery.com>
+
+ * intl.h: #define gcc_gettext_width to strlen when !ENABLE_NLS.
+
+2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11-protos.h
+ (m68hc11_eq_compare_operator): Declare
+ * config/m68hc11/m68hc11.h (PREDICATE_CODES): Register new predicate.
+ * config/m68hc11/m68hc11.c (m68hc11_eq_compare_operator): New predicate
+ (d_register_operand): Check the operand mode.
+ (hard_addr_reg_operand): Likewise.
+
+2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("decrement_and_branch_until_zero"): New
+ pattern for dbcc/ibcc generation for 68HC12.
+ ("doloop_end"): New pattern.
+ ("m68hc12_dbcc_dec_hi"): New pattern for dbeq/dbne.
+ ("m68hc12_dbcc_inc_hi"): New pattern for ibeq/ibne.
+ ("m68hc12_dbcc_dec_qi"): New pattern.
+ ("m68hc12_dbcc_inc_qi"): New pattern.
+ (split): Add split for the above when we can't use dbcc/ibcc due to
+ reloading.
+ (peephole2): Add peephole2 to generate the above when possible.
+
+2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("bitcmpqi" split): No need to test the
+ mode of operand 0.
+ (peephole2 optimize const load): Likewise for operand 2.
+ ("*rotlhi3_with_carry"): Change pattern to a const 1 rotate which
+ clobbers CC_REGNUM.
+ ("*rotrhi3_with_carry"): Likewise.
+ (ashift:DI 1 split): Update pattern to create the above rotate.
+ (lshiftrt:DI 1 split): Likewise.
+
+2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md (SOFT_Z_REGNUM): New constant.
+ ("tstqi_z_used" split): Use it.
+ ("cmphi_z_used"): Likewise.
+ ("bitcmpqi_z_used"): Likewise; also use SP_REGNUM constant.
+ ("cmpqi_z_used"): Likewise.
+
+2003-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7910
+ * config/i386/winnt.c (i386_pe_mark_dllimport): Fix thinko.
+
+2003-04-12 Zack Weinberg <zack@codesourcery.com>
+
+ * configure.in: Check for wchar.h, mbstowcs, and wcswidth.
+ * configure, config.in: Regenerate.
+ * intl.c (gcc_gettext_width): New function.
+ * intl.h: Prototype it.
+
+2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.h (TARGET_SWITCHES): Fix -mnominmax option;
+ recognize -mnorelax.
+ (reg_class): Add Z_OR_S_REGS to represent soft registers with Z
+ (REG_CLASS_NAMES): Add its name.
+ (REG_CLASS_CONTENTS): Define its content.
+
+2003-04-12 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/larith.asm (memcpy): Use ARG macro to access stack
+ parameters so that offsets are valid for far definition.
+ (__mulsi3): Likewise and use ret to return.
+ (___adddi3, ___subdi3, ___notdi2, ): Don't use it to save the result.
+
+2003-04-12 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_hash_constant): Skip '0' fields.
+
+2003-04-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * mklibgcc.in (libgcc-stage-start): For every multilib directory
+ containing a libgcc.a, move lib* to the corresponding stage dir.
+
+ * Makefile.in (stage1-start, stage2-start, stage3-start,
+ stage4-start): Move $(SPECS) to specs in stage dir.
+ (unstage1 unstage2 unstage3 unstage4): Move specs in stage dir
+ back as $(SPECS).
+
+ * mklibgcc.in (libgcc-stage-start): Move into the stage directory
+ object files from the non-libgcc/ multilib directories as well.
+
+2003-04-11 Geoffrey Keating <geoffk@apple.com>
+
+ * profile.c (read_counts_file): Initialise 'checksum'.
+
+ * emit-rtl.c (gen_rtx): Really correct typo.
+
+ PR c++/9393
+ * doc/invoke.texi (Debugging Options): Document -frandom-seed.
+ * configure.in: Check for gettimeofday.
+ * tree.c (flag_random_seed): Define.
+ (default_flag_random_seed): New.
+ (append_random_chars): Use flag_random_seed rather than trying
+ to acquire randomness here.
+ * tree.h (default_flag_random_seed): Declare.
+ * toplev.c (display_help): Add -frandom-seed and -fstack-limit-*
+ descriptions.
+ (decode_f_option): Handle -frandom-seed.
+ (print_switch_values): Call default_flag_random_seed.
+ * flags.h (flag_random_seed): Declare.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * config/alpha/t-crtfm: Use -frandom-seed.
+
+ * doc/extend.texi (Empty Structures): New.
+
+ * c-pch.c: Include flags.h. Add comments to routines.
+ (struct c_pch_validity): New.
+ (get_ident): Update PCH file version number.
+ (pch_init): Output current debugging type.
+ (c_common_valid_pch): Check debugging type.
+ * Makefile.in (c-pch.o): Update dependencies.
+ * flags.h (debug_type_names): Declare.
+ * toplev.c (debug_type_names): Move out of decode_g_option.
+
+2003-04-11 Eric Christopher <echristo@redhat.com>
+
+ * emit-rtl.c (gen_rtx): Fix typos.
+
+2003-04-11 Richard Henderson <rth@redhat.com>
+
+ * emit-rtl.c (gen_rtx): Zero '0' fields.
+
+2003-04-11 Richard Henderson <rth@redhat.com>
+
+ PR c++/10202
+ * expr.c (expand_expr): Use COMPLETE_OR_UNBOUND_ARRAY_TYPE_P
+ not COMPLETE_TYPE_P for re-invoking layout_decl.
+
+2003-04-11 Simon Law <sfllaw@engmail.uwaterloo.ca>
+
+ * doc/bugreport.texi: Fix paragraph breaking between sections
+ in preparation for TeXinfo's paragraph indentation fixes.
+ * doc/extend.texi: Ditto.
+ * doc/invoke.texi: Ditto.
+ * doc/objc.texi: Ditto.
+ * doc/gcov.texi: Wrap 'gcov' in @command{}.
+ * doc/invoke.texi (Darwin Options): Add a preamble.
+
+2003-04-11 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (tls_model_chars): Remove.
+ (ix86_encode_section_info, ix86_strip_name_encoding): Remove.
+ (local_symbolic_operand): Use SYMBOL_REF_LOCAL_P.
+ (tls_symbolic_operand): Use SYMBOL_REF_TLS_MODEL.
+ (tls_symbolic_operand_1): Likewise.
+ (legitimate_pic_address_disp_p): Use SYMBOL_REF_LOCAL_P.
+ * config/i386/i386.h (TARGET_ENCODE_SECTION_INFO): Remove.
+ (TARGET_STRIP_NAME_ENCODING, ASM_OUTPUT_LABELREF): Remove.
+ * config/i386/winnt.c (i386_pe_encode_section_info): Replace
+ bits "copied from i386.h" with default_encode_section_info.
+
+2003-04-11 Richard Henderson <rth@redhat.com>
+
+ * rtl.def (SYMBOL_REF): Add two 0 fields.
+ * gengtype.c (adjust_field_rtx_def): Handle them.
+ * print-rtl.c (print_rtx): Print them.
+ * rtl.h (SYMBOL_REF_DECL, SYMBOL_REF_FLAGS): New.
+ (SYMBOL_FLAG_FUNCTION, SYMBOL_REF_FUNCTION_P): New.
+ (SYMBOL_FLAG_LOCAL, SYMBOL_REF_LOCAL_P): New.
+ (SYMBOL_FLAG_SMALL, SYMBOL_REF_SMALL_P): New.
+ (SYMBOL_FLAG_TLS_SHIFT, SYMBOL_REF_TLS_MODEL): New.
+ (SYMBOL_FLAG_EXTERNAL, SYMBOL_REF_EXTERNAL_P): New.
+ (SYMBOL_FLAG_MACH_DEP): New.
+ * optabs.c (init_one_libfunc): Zap fake SYMBOL_REF_DECL.
+ * varasm.c (make_decl_rtl): Set SYMBOL_REF_DECL.
+ (assemble_static_space): Set SYMBOL_REF_FLAGS.
+ (assemble_trampoline_template): Likewise.
+ (output_constant_def, force_const_mem): Likewise.
+ (default_encode_section_info): New.
+ * output.h: Declare it.
+ * target-def.h (TARGET_ENCODE_SECTION_INFO): Use it.
+
+2003-04-11 Richard Henderson <rth@redhat.com>
+
+ * libfuncs.h (LTI_setbits, LTI_gcov_flush, LTI_gcov_init): New.
+ (setbits_libfunc, gcov_flush_libfunc, gcov_init_libfunc): New.
+ * optabs.c (init_optabs): Initialize them.
+ (init_libfuncs): Use init_one_libfunc.
+ * calls.c (expand_call): Use gcov_flush_libfunc.
+ * expr.c (store_constructor): Use setbits_libfunc.
+ * function.c (expand_main_function): Use init_one_libfunc.
+ * profile.c (create_profiler): Use gcov_init_libfunc and DECL_RTL.
+
+2003-04-11 Mark Mitchell <mark@codesourcery.com>
+
+ * doc/c-tree.texi (Functions): Remove DECL_REAL_CONTEXT
+ documentation; add DECL_FRIEND_CONTEXT.
+
+2003-04-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * doc/install.texi (hppa): Update links for HP-UX patches. Revise
+ notes on linker selection and configuration for 64-bit HP-UX port.
+ * doc/invoke.texi (hppa): Remove hppa text from description for
+ -ffunction-sections and -fdata-sections. Document -static, -nolibdld
+ and -threads options.
+
+ * pa-hpux10.h (LIB_SPEC): Add link options to resolve dependency of
+ libc.a on libdld.sl when -static is specified and -nolibdld is not
+ specified.
+ * pa64-hpux.h (LIB_SPEC): Likewise.
+ * pa-hpux11.h (LIB_SPEC): Likewise.
+ (LINK_SPEC): Add __gcc_plt_call as an undefined symbol when -shared
+ is not specified.
+
+2003-04-11 Zack Weinberg <zack@codesourcery.com>
+
+ * config/darwin-c.c (darwin_pragma_unused): Use lookup_name,
+ not IDENTIFIER_LOCAL_VALUE.
+
+2003-04-11 Richard Henderson <rth@redhat.com>
+
+ PR c/10201
+ * expr.c (expand_expr): Move DECL_RTL frobbing ...
+ * stor-layout.c (layout_decl): ... here.
+
+2003-04-11 James A. Morrison <ja2morri@uwaterloo.ca>
+
+ * doc/invoke.texi: Eliminate extra white-space caused by
+ @gccoptlist{ on its own line.
+ * doc/invoke.texi: Ensured there are two spaces between each option.
+ * doc/invoke.texi: Re-wrapped option lines that were too wide.
+ Added @gol to options that didn't have them.
+
+2003-04-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * Makefile.in (loop-init.o): Do not depend on gcov-io.h,
+ gcov-iov.h.
+
+ Simplify interface to gcov reading and writing.
+ * gcov-io.h (gcov_file, gcov_position, gcov_length, gcov_buffer,
+ gcov_alloc, gcov_modified, gcov_errored): Move into ...
+ (struct gcov_var gcov_var): ... this static structure.
+ (gcov_write_unsigned, gcov_write_counter, gcov_write_string):
+ Return void.
+ (gcov_read_unsigned, gcov_read_couter, gcov_read_string): Return
+ read object.
+ (gcov_read_bytes, gcov_write_bytes): Set error flag on error.
+ (gcov_reserve_length): Remove.
+ (gcov_write_tag): New.
+ (gcov_write_length): Adjust.
+ (gcov_read_summary, gcov_write_summary): Adjust.
+ (gcov_eof, gcov_ok): Rename to ...
+ (gcov_is_eof, gcov_is_error): ... here. Return error code.
+ (gcov_save_position, gcov_resync): Rename to ...
+ (gcov_position, gcov_seek): ... here.
+ (gcov_skip, gcov_skip_string): Remove.
+ (gcov_error): Remove.
+ (gcov_open, gcov_close): Adjust.
+ * gcov.c (find_source): Take const char *, copy it on allocation.
+ (read_graph_file): Adjust.
+ (read_count_file): Adjust.
+ * libgcov.c (gcov_exit): Adjust.
+ * gcov-dump.c (tag_function, tag_blocks, tag_arcs, tag_lines,
+ tag_arc_counts, tag_summary): Return void. Adjust.
+ (struct tag_format): Adjust proc member.
+ (dump_file): Adjust gcov calls.
+
+2003-04-11 Alexandre Oliva <aoliva@redhat.com>
+
+ * Makefile.in (fixinc.sh): Pass BUILD_LIBERTY as LIBERTY to
+ mkfixinc.sh.
+ * fixinc/mkfixinc.sh (defs): Add LIBERTY.
+ * configure.in (STMP_FIXINC, STMP_FIXPROTO): Don't disable on
+ build != host sysrooted builds.
+ * configure.in (SYSTEM_HEADER_DIR): Make sure it contains
+ TARGET_SYSTEM_ROOT even on sysrooted natives.
+ * configure: Rebuilt.
+
+2003-04-10 Zack Weinberg <zack@codesourcery.com>
+
+ * c-decl.c (struct binding_level): Add shadowed_tags and
+ function_body; remove this_block, tag_transparent, and
+ subblocks_tag_transparent; update comments.
+ (clear_binding_level, lookup_tag_reverse): Kill.
+ (make_binding_level): Use ggc_alloc_cleared or memset.
+ (lookup_tag): Remove struct binding_level* parameter. All
+ callers changed. Just look at IDENTIFIER_TAG_VALUE, and
+ current_binding_level->tags if asked for thislevel_only or if
+ we might have to diagnose "struct foo; union foo;"
+ (pushlevel): Ignore argument. Do not push another binding
+ level on the transition from the parameters to the top level
+ of the function body; just tweak the flags and proceed.
+ (poplevel): Overhaul. Clear IDENTIFIER_TAG_VALUEs; on exiting
+ a function body, separate the parameter list from the
+ top-level local variables.
+ (set_block): Do nothing.
+ (pushtag): Set IDENTIFIER_TAG_VALUE and add an entry to
+ shadowed_tags if necessary.
+ (warn_if_shadowing): Nuke the special case for local shadowing
+ parameter.
+ (pushdecl): Do not create a shadow entry if we are replacing
+ an older decl in the same binding level.
+ (pushdecl_function_level): Tweak for new way of indicating
+ function scope.
+ (shadow_tag_warned): Use TYPE_NAME, not lookup_tag_reverse.
+ (start_function): Don't set subblocks_tag_transparent.
+ (finish_function): Fix up the binding_level stack for totally
+ empty functions. Otherwise, don't call poplevel.
+
+ * c-common.c (shadow_warning): MANDATORY argument is no longer
+ necessary. Always use plain warning.
+ * c-common.h: Update to match.
+
+ * cfglayout.c (scope_to_insns_initialize): Clear block when we
+ hit the FUNCTION_DECL.
+ * function.c: Do not create cyclic tree structure.
+
+2003-04-10 Zack Weinberg <zack@codesourcery.com>
+
+ * c-tree.h (struct lang_identifier): Replace global_value,
+ local_value members with symbol_value, tag_value. Kill
+ implicit_decl and limbo_value.
+ (IDENTIFIER_GLOBAL_VALUE, IDENTIFIER_LOCAL_VALUE,
+ IDENTIFIER_LIMBO_VALUE, IDENTIFIER_IMPLICIT_DECL,
+ C_MISSING_PROTOTYPE_WARNED): Kill.
+ (IDENTIFIER_SYMBOL_VALUE, IDENTIFIER_TAG_VALUE,
+ C_DECL_IMPLICIT, C_DECL_ISNT_PROTOTYPE): New.
+ (C_DECL_ANTICIPATED): Rename to C_DECL_INVISIBLE.
+ (implicit_decl_warning, lookup_name_current_level,
+ record_function_scope_shadow): Don't prototype.
+ (pushdecl_function_level): Prototype.
+
+ * c-decl.c (truly_local_externals): New variable.
+ (struct binding_level): Adjust commentary.
+ (get_function_binding_level, clear_limbo_values,
+ record_function_scope_shadow): Kill.
+ (lookup_name_current_level, implicit_decl_warning): Are now static.
+ (any_external_decl, record_external_decl): New static functions.
+ (clone_underlying type): Split out of pushdecl.
+ (c_print_identifier): Update to match changes to struct
+ lang_identifier.
+ (poplevel): Delete #if 0 block. Make externals invisible
+ instead of clearing their IDENTIFIER_SYMBOL_VALUEs. Don't
+ call clear_limbo_values. Refer to IDENTIFIER_SYMBOL_VALUE not
+ IDENTIFIER_GLOBAL_VALUE or IDENTIFIER_LOCAL_VALUE.
+ (duplicate-decls): For real parm decl after a forward decl,
+ set TREE_ASM_WRITTEN here. Allow void foo(...) followed by
+ foo(...) { } with only a warning. Say whether a previous
+ declaration was implicit.
+ (warn_if_shadowing): Now handles all shadowing, not just
+ local-over-local. Clarify comments.
+ (pushdecl): Rewritten. There is no longer a distinction
+ between global and local symbol values; they're all
+ IDENTIFIER_SYMBOL_VALUE. Call record_external_decl on all
+ DECL_EXTERNAL decls, and use any_external_decl to check
+ against previous externals. Kill #if 0 blocks. Don't
+ tolerate error_mark_node being NULL.
+ (pushdecl_top_level): Handle only those cases which
+ Objective C (the only user) needs.
+ (pushdecl_function_level): New function.
+ (implicitly_declare): Create ordinary decls with
+ C_DECL_IMPLICIT set. Recycle old decls, however they got
+ created.
+ (lookup_name): It's always IDENTIFIER_SYMBOL_VALUE. Return 0
+ for C_DECL_INVISIBLE symbols.
+ (lookup_name_current_level): Likewise. Use chain_member.
+ (c_make_fname_decl): Don't muck with DECL_CONTEXT.
+ Use pushdecl_function_level.
+ (builtin_function): Use C_DECL_INVISIBLE.
+ (start_function): Don't muck with IDENTIFIER_IMPLICIT_DECL.
+ Use C_DECL_ISNT_PROTOTYPE and C_DECL_IMPLICIT.
+ (store_parm_decls): It's IDENTIFIER_SYMBOL_VALUE now.
+ (identifier_global_value): Same. Must scan
+ global_binding_level in extremis.
+
+ * c-typeck.c (undeclared_variable): New static function, split
+ from build_external_ref.
+ (build_external_ref): Use DECL_CONTEXT, not
+ IDENTIFIER_LOCAL_VALUE, to decide whether a local hides
+ an instance variable. Restructure for clarity.
+ * objc/objc-act.c: Use identifier_global_value, not
+ IDENTIFIER_GLOBAL_VALUE.
+
+2003-04-08 Jonathan Wakely <redi@gcc.gnu.org>
+
+ * doc/extend.texi (Template Instantiation): Refer to ISO standard,
+ not Working Paper.
+ * doc/invoke.texi (C++ Dialect Options): Same.
+
+2003-04-10 Zack Weinberg <zack@codesourcery.com>
+
+ * tree.c (tree_operand_check_failed): New function.
+ * tree.h (TREE_OPERAND_CHECK, TREE_OPERAND_CHECK_CODE,
+ TREE_RTL_OPERAND_CHECK): New checking macros.
+ (TREE_OPERAND, SAVE_EXPR_CONTEXT, SAVE_EXPR_RTL,
+ RTL_EXPR_SEQUENCE, RTL_EXPR_RTL, WITH_CLEANUP_EXPR_RTL,
+ CONSTRUCTOR_ELTS, LABELED_BLOCK_LABEL, LABELED_BLOCK_BODY,
+ EXIT_BLOCK_RETURN, LOOP_EXPR_BODY, EXPR_WFL_NODE,
+ EXPR_WFL_FILENAME_NODE, EXPR_WFL_FILENAME, TARGET_EXPR_SLOT,
+ TARGET_EXPR_INITIAL, TARGET_EXPR_CLEANUP): Use the new
+ checking macros.
+
+Thu Apr 10 23:52:30 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ PR inline-asm/8803
+ * function.c (instantate_virtual_regs): Verify that all ASM statements
+ match after the virutal regs instantiation.
+
+2003-04-10 Steve Ellcey <sje@cup.hp.com>
+
+ * ia64-protos.h (addp4_optimize_ok): New.
+ * ia64.c (addp4_optimize_ok): New.
+ * ia64.md (*ptr_extend_plus_1): Use addp4_optimize_ok.
+ (*ptr_extend_plus_2): Ditto.
+
+2003-04-10 Steve Ellcey <sje@cup.hp.com>
+
+ * expr.c (expand_assignment): Extend offset_rtx with convert_to_mode
+ not with convert_memory_address.
+ (store_constructor): Ditto, and same for copy_size_rtx.
+ (expand_expr): Ditto.
+
+2003-04-10 Douglas B Rupp <rupp@gnat.com>
+
+ * config/i386/i386.c (ix86_ms_bitfield_layout_p): Fix formatting.
+
+2003-04-10 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/lib2funcs.S (__xtensa_sync_caches): Flush data cache
+ even if it is configured to be write-through.
+
+2003-04-10 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (larl_operand): Do not allow symbols
+ marked with '@'.
+ (s390_encode_section_info): Mark symbols with forced 1-byte
+ alignment with '@'.
+ (s390_strip_name_encoding): Strip '@'.
+ (legitimize_pic_address): Handle symbols that are not valid
+ LARL operands in 64-bit mode.
+
+2003-04-10 Andrew Haley <aph@redhat.com>
+
+ * tree-inline.c (inlinable_function_p): Disable inlining for
+ synchronized methods.
+
+2003-04-09 Steven Bosscher <steven@gcc.gnu.org>
+
+ * c-common.h (lang_statement_code_p): Remove declaration.
+ (statement_code_p): Ditto.
+ (c_common_stmt_codes): Define; list of c-common statement codes.
+ (statement_code_p): New extern declaration.
+ (STATEMENT_CODE_P): Define.
+ (INIT_STATEMENT_CODES): Define.
+ * c-common.c (statement_code_p): Kill the function, declare
+ as an array of bools instead.
+ (lang_statement_code_p): Remove.
+ (walk_stmt_tree): Use STATEMENT_CODE_P not statement_code_p.
+ (c_safe_from_p): Ditto.
+ * c-objc-common.c (c_objc_common_init): Use INIT_STATEMENT_CODES
+ to initialize the statement_code_p array.
+ * tree-inline.c (walk_tree): Use STATEMENT_CODE_P instead of
+ statement_code_p.
+ (copy_tree_r): Ditto.
+ * cp/cp-tree.h (cp_stmt_codes): Define; list of C++ specific
+ statement tree codes.
+ * cp/lex.c (cxx_init): Add missing print line break. Use
+ INIT_STATEMENT_CODES to initialize the statement_code_p array.
+ * cp/parser.c (cp_parser_statement): Use STATEMENT_CODE_P
+ instead of statement_code_p.
+ * cp/pt.c (tsubst_expr): Ditto.
+ * cp/tree.c (verify_stmt_tree_r): Ditto.
+ (cp_statement_code_p): Remove.
+ (init_tree): Don't set lang_statement_code_p, it's gone.
+
+2003-04-09 Dan Nicolaescu <dann@ics.uci.edu>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * regrename.c (struct du_chain): Use a bitfield for reg_class.
+ * cse.c (struct qty_table_elem, struct table_elt, struct set):
+ Use bitfields for fields holding enum rtx_code or
+ enum machine_mode values. Add comments explaining size choices.
+
+2003-04-09 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/fp-bit.c (unpack_d): Handle pair of doubles with
+ different signs correctly.
+
+2003-04-09 Vladimir Makarov <vmakarov@redhat.com>
+
+ * sched-deps.c (reg_pending_barrier_mode): New enumeration.
+ (reg_pending_barrier): Make it of the enumeration type.
+ (sched_analyze_2): Define the barrier as MOVE_BARRIER or
+ TRUE_BARRIER.
+ (sched_analyze): Ditto.
+ (sched_analyze_insn): Ditto. Use anti-dependencies for
+ MOVE_BARRIER and true-dependencies as TRUE_BARRIER.
+ (init_deps_global): Initialize the barrier as NO_BARRIER.
+
+2003-04-09 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/ia64/ia64.c (issue_nops_and_insn): Add new parameter.
+ Check that asm insn starts on a new cycle. Add nops after asm
+ insn to end bundle.
+ (bundling): Move insn type evaluation from the loop. Call
+ issue_nops_and_insn with the new parameter. Ignore changing
+ position for nops after asm insn.
+
+2003-04-09 Alexandre Oliva <aoliva@redhat.com>
+
+ * optabs.c: Comment that gen_add2_insn and others may actually
+ return emitted insns, if the gen functions turn out to return
+ emitted insns.
+ * reload1.c (reload_cse_move2add): Cope with emitted insns from
+ gen_add2_insn.
+
+2003-04-09 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.c (move_operand): Allow symbolic_operand,
+ but not tls_symbolic_operand.
+ (ia64_expand_load_address): Remove scratch operand.
+ (ia64_expand_tls_address): Split out from ia64_expand_move.
+ (ia64_expand_move): Split symbolics only after reload.
+ (ia64_emit_cond_move): New.
+ * config/ia64/ia64-protos.h: Update.
+ * config/ia64/ia64.md (movsi_symbolic, movdi_symbolic): Remove.
+ (symbolic splitter): Accept SImode operands too.
+ (cmove splitter): Use ia64_emit_cond_move.
+
+2003-04-09 Nick Clifton <nickc@redhat.com>
+
+ * doc/install.texi: Note that ARM toolchains need binutils 2.13 or
+ newer.
+ * config/arm/elf.h (SUBTARGET_ASM_FLOAT_SPEC): Pass -mfpu=softfpa
+ instead of -mno-fpu.
+ * config/arm/semi.h (ASM_SPEC): Likewise.
+ * config/arm/xscale-elf.h (SUBTARGET_EXTRA_ASM_SPEC): Likewise,
+ but only if -msoft-float is specified pass. Otherwise pass
+ -mfpu=softvfp.
+
+2003-04-09 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * function.c (purge_addressof): Use free_INSN_LIST_node instead of
+ free_EXPR_LIST_node.
+
+2003-04-08 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold): Use "fold" following build in more places.
+ Optimize sqrt(x)*sqrt(x) as x, pow(x,y)*pow(z,y) as pow(x*z,y),
+ pow(x,y)*pow(x,z) as pow(x,y+z) and x/pow(y,z) as x*pow(y,-z).
+
+2003-04-08 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (fold_builtin): Constant fold expressions as x*0.5
+ instead of x/2.0. Optimize sqrt(pow(x,y)) as pow(x,y*0.5),
+ log(pow(x,y)) as y*log(x), pow(exp(x),y) as exp(x*y),
+ pow(sqrt(x),y) as pow(x,y*0.5) and pow(pow(x,y),z) as pow(x,y*z).
+ Delete function scope "fcode" variable to avoid shadowing.
+
+2003-04-08 Kevin Buettner <kevinb@redhat.com>
+
+ * dwarf2out.c (DWARF_ARANGES_HEADER_SIZE, DWARF_ARANGES_PAD_SIZE):
+ Take into account DWARF_INITIAL_LENGTH_SIZE.
+
+2003-04-08 Hans-Peter Nilsson <hp@axis.com>
+
+ * reorg.c (fill_slots_from_thread): When considering changing the
+ insn following a reg-to-reg copy insn to use the source reg of the
+ copy, bail out if there's overlap between the registers.
+
+2003-04-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * function.c (postponed_insns): New.
+ (purge_addressof_1): Postpone processing of insns if addressofs
+ are not put into stack.
+ (purge_addressof): Process postponed insns.
+
+2003-04-08 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (NORMAL_MODE): If interrupt handler and TARGET_FMOVD,
+ this is FP_MODE_DOUBLE .
+ * sh.c (ra.h): #include.
+ (push_regs): Add second parameter. Changed all callers.
+ If necessary, set fpscr before saving floating point registers.
+ (calc_live_regs): If interrupt handler and TARGET_FMOVD, always
+ do saves / restores with SZ == 1.
+ (sh_expand_prologue): If interrupt handler, don't use gen_toggle_sz.
+ (sh_expand_epilogue): Likewise. For TARGET_FMOVD, if floating point
+ registers are being restored, restore FPSCR only after restoring them.
+
+2003-04-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_init_builtins): Set opaque types
+ regardless of architecture.
+ (spe_init_builtins): Change V2SI and V2SF types to opaque types.
+
+2003-04-08 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (push_regs, calc_live_regs): Return int. Take single
+ HARD_REG_SET * parameter. Changed all callers.
+
+Tue Apr 8 11:12:07 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (legitimate_pic_address_disp_p): Do not accept PLUS in the
+ GOTOFF operand.
+ (legitimize_pic_address): Move plus outside the unspec.
+ * i386.c (legitimate_constant_p): Check (CONST (PLUS (UNSPEC ...
+ for validity.
+
+2003-04-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov-io.h (gcov_save_position): Remove __inline__ from
+ declaration.
+
+2003-04-07 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * doc/install.texi: Use @command and @samp for single- and
+ multi-word commands respectively.
+ * doc/makefile.texi: Likewise.
+ * doc/sourcebuild.texi: Likewise.
+
+2003-04-07 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
+ Richard Henderson <rth@redhat.com>
+
+ PR c/9516
+ * expr.c (safe_from_p): Rearrange to avoid deep recursion in
+ favor of looping and tail recursion for TREE_LIST and binops.
+
+2003-04-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * loop.h (REGNO_FIRST_LUID, REGNO_LAST_LUID): Provide defaults
+ for insns without luid.
+
+2003-04-07 Glen Nakamura <glen@imodulo.com>
+
+ PR opt/8634
+ * explow.c (maybe_set_unchanging): Don't flag non-static const
+ aggregate type initializers with RTX_UNCHANGING_P.
+
+2003-04-07 Richard Henderson <rth@redhat.com>
+
+ PR opt/8634
+ * function.c (purge_addressof_1): Don't try arithmetics for
+ unchanging memories.
+
+2003-04-07 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/sourcebuild.texi (Test Suites): Document testing support for
+ gcov and profile-directed optimizations; describe gcc.misc-tests.
+
+Mon Apr 7 22:19:59 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ PR target/10077
+ * i386.md (movsi_1, movsi_nointerunit_1): Fix SSEMOV alternative.
+
+2003-04-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/rtl.texi (Comparison operations): Update to
+ record the allowed comparison modes.
+
+2003-04-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_common_init_builtins): Rename all
+ V2SI_type_node to opaque_V2SI_type_node. Rename all
+ V2SF_type_node to opaque_V2SF_type_node.
+ (rs6000_init_builtins): Define opaque_V2SI_type_node and
+ opaque_V2SF_type_node.
+ (is_ev64_opaque_type): The types opaque_V2SI_type_node and
+ opaque_V2SF_type_node are opaque types.
+
+2003-04-07 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * gcse.c (replace_store_insn): Use single_set.
+
+2003-04-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ Change gcov file interface to single file at a time.
+ * gcov-io.h: Replace IN_LIBGCC1 with IN_LIBGCOV. Use IN_GCOV.
+ Convert to C89 prototypes.
+ (gcov_file, gcov_length, gcov_position, gcov_buffer, gcov_alloc,
+ gcov_error, gcov_modified): New static variables.
+ (gcov_open, gcov_close, gcov_read_bytes, gcov_write_bytes): New
+ functions.
+ (gcov_write_unsigned, gcov_write_counter, gcov_write_string,
+ gcov_read_unsigned, gcov_read_counter, gcov_read_string): Adjust.
+ (gcov_read_summary, gcov_write_summary): Adjust.
+ (gcov_save_position, gcov_reserve_length, gcov_write_length):
+ Adjust.
+ (gcov_resync, gcov_skip, gcov_skip_string): Adjust.
+ (da_file_open, da_file_close, da_file_eof, da_file_error): Remove.
+ (da_file_position, da_file_seek, da_file_write, da_file_read):
+ Remove.
+ (gcov_error, gcov_eof, gcov_ok, gcov_time): New functions.
+ * gcov.c (gcov_type): Don't typedef here.
+ (IN_GCOV): #define
+ (read_graph_file, read_count_file): Adjust.
+ * gcov-dump.c (gcov_type): Don't typedef here.
+ (IN_GCOV): #define.
+ (tag_function, tag_blocks, tag_arcs, tag_lines, tag_arc_counts):
+ Remove FILE parameter, adjust.
+ (struct tag_format): Adjust proc member.
+ (dump_file): Adjust.
+ * libgcov.c (IN_LIBGCOV): #define.
+ (gcov_exit): Adjust.
+ * loop-init.c: Don't #include gcov-io.h
+ * profile.c (struct counts_entry): New structure to hold counter
+ values.
+ (struct section_reference, struct da_index_entry): Remove.
+ (bbg_file, da_file): Remove.
+ (htab_counts_index_hash, htab_counts_index_eq,
+ htab_counts_index_del): Replace with ...
+ (htab_counts_entry_hash, htab_counts_entry_eq,
+ htab_counts_entry_del): ... these.
+ (cleanup_counts_index, index_counts_file): Remove.
+ (read_counts_file): New function.
+ (get_exec_counts): Adjust.
+ (compute_branch_probabilities): Don't free the exec counts here.
+ (branch_prob): Adjust.
+ (init_branch_prob): Adjust.
+ (end_branch_prob): Adjust.
+
+2003-04-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/invoke.texi (RS/6000 and PowerPC Options): Document
+ -mfloat-gprs.
+
+ * config/rs6000/rs6000.c: Delete rs6000_fprs.
+ Declare rs6000_float_gprs.
+ Declare rs6000_float_gprs_string.
+ (rs6000_parse_float_gprs_option): New.
+ (rs6000_override_options): Genericize rs6000_parse_* calls to use
+ rs6000_parse_yes_no_option.
+ Change check for cpu=8540, to use TARGET_E500.
+ (rs6000_parse_isel_option): Delete.
+ (rs6000_parse_spe_option): Delete.
+ (rs6000_parse_vrsave_option): Delete.
+
+ * config/rs6000/rs6000.h: Rename rs6000_fprs to rs6000_float_gprs.
+ Define rs6000_float_gprs_string.
+ (TARGET_OPTIONS): Add rs6000_float_gprs option.
+
+ * config/rs6000/eabi.h (TARGET_FPRS): Change to use rs6000_float_gprs.
+
+ * config/rs6000/eabispe.h: Set rs6000_float_gprs.
+
+Mon Apr 7 14:36:24 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ PR opt/10024
+ * cfglayout.c (cfg_layout_redirect_edge):
+ Redirect any branch edges unified with the fallthru one.
+ * cfgrtl.c (force_nonfallthru_and_redirect): Do not special
+ case fallthru edges when called via cfglayout.c
+
+2003-04-07 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * c-typeck.c (output_init_element): Check for type == error_mark_node.
+
+2003-04-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*zero_extendqisi2_h8300hs): Always
+ split.
+ (a splitter): Do zero-extension via HImode.
+
+2003-04-07 James A. Morrison <ja2morri@uwaterloo.ca>
+
+ * doc/invoke.texi: Eliminate extra white-space caused by
+ @gccoptlist{ on its own line.
+ * doc/invoke.texi: Ensured there are two spaces between each option.
+ * doc/invoke.texi: Re-wrapped option lines that were too wide.
+ Added @gol to options that didn't have them.
+
+2003-04-07 James A Morrison <ja2morri@student.math.uwaterloo.ca>
+
+ * doc/extend.texi (Darwin Pragmas): Fix spelling of Mac OS.
+
+2003-04-06 Zack Weinberg <zack@codesourcery.com>
+
+ * tree.c (tree_size): For all 'c' and 'x' nodes, look directly
+ at the sizes of the relevant structures, rather than relying
+ on TREE_CODE_LENGTH. Call lang_hooks.tree_size to get the
+ sizes of any such we don't know about. Use
+ lang_hooks.identifier_size for IDENTIFIER_NODE.
+
+ (initializer_zerop): Use CONSTRUCTOR_ELTS.
+ * tree.def: Update commentary. Make fourth element of
+ the definition for all 'c' and 'x' nodes zero.
+
+ * langhooks.h: New hook, tree_size / LANG_HOOKS_TREE_SIZE.
+ * langhooks-def.h: Update to match.
+ * langhooks.c: New default, lhd_tree_size.
+
+ * c-common.def (SRCLOC): Kill.
+ * c-pretty-print.c (pp_c_postfix_expression [case SRCLOC]):
+ Remove entirely - was already #if-ed out.
+
+
+2003-04-06 Zack Weinberg <zack@codesourcery.com>
+
+ * mklibgcc.in: Use a here document to avoid running afoul of
+ shells that generate control-A from "echo \1".
+
+2003-04-06 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/invoke.texi (RS/6000 and PowerPC Options): Document -mspe
+ option.
+
+ * config/rs6000/eabispe.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Set
+ rs6000_spe.
+
+ * config/rs6000/eabi.h (TARGET_E500): Define.
+
+ * config/rs6000/rs6000.h (TARGET_E500): Define.
+ (TARGET_OPTIONS): Add spe= option.
+ Declare rs6000_spe and rs6000_spe_string extern.
+
+ * config/rs6000/rs6000.c (branch_positive_comparison_operator):
+ Change TARGET_SPE to TARGET_E500.
+ (ccr_bit): Change TARGET_SPE to TARGET_E500. Check for
+ !TARGET_FPRS.
+ (print_operand): Same.
+ (rs6000_generate_compare): Same.
+ (output_cbranch): Same.
+ (rs6000_spe): Declare.
+ (rs6000_spe_string): Declare.
+ (rs6000_override_options): Call rs6000_parse_spe_option.
+ (rs6000_parse_spe_option): New.
+
+2003-04-06 Steven Bosscher <steven@gcc.gnu.org>
+
+ * hashtable.c (gcc_obstack_init): Delete this function
+ and everything related to it.
+ * hashtable.h: Remove prototype.
+ * bitmap.c (bitmap_element_allocate): Cleanup redundant
+ defines. Cleanup some unnecessary whitespace.
+ * defaults.h (obstack_chunk_alloc): Redefine with
+ appropriate casts for libiberty obstacks.
+ (obstack_chunk_free): Ditto.
+ (OBSTACK_CHUNK_SIZE): Define, default to 0.
+ (gcc_obstack_init): Define as a call to _obstack_begin.
+ * tree.c (print_obstack_statistics): Delete this unused
+ function.
+ * tree.h (obstack): Don't forward-declare.
+ (print_obstack_statistics): Delete prototype.
+ (print_obstack_name): Ditto.
+ (gcc_obstack_init): Ditto.
+ * rtl.h (gcc_obstack_init): Ditto.
+ * java/jv-scan.c (gcc_obstack_init): Delete this
+ function, its prototype and related defines.
+ * java/jvgenmain.c (gcc_obstack_init): Delete this
+ function, and related defines.
+ * java/parse-scan.y (obstack_chunk_alloc): Don't define.
+ (obstack_chunk_free): Ditto
+
+2003-04-06 Geoffrey Keating <geoffk@apple.com>
+
+ * dbxout.c (dbxout_handle_pch): Move prototype out from
+ #if defined DBX_DEBUGGING_INFO.
+
+2003-04-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov.c (struct arc_info): Replace local_span with cycle.
+ (struct block_info): Replace u.span with u.cycle. Add is_call_return.
+ (solve_flow_graph): Set is_call_return.
+ (add_line_counts): Adjust. In block mode, blocks attach to last line.
+ (accumulate_line_counts): Find graph cycles, not spanning tree.
+ (output_branch_count): Adjust.
+ (output_lines): Adjust.
+ * doc/gcov.texi: Update.
+
+2003-04-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*zero_extendqisi2_h8300hs): Change
+ the second alternative to "#".
+
+2003-04-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (single_one_operand): Use GET_MODE_MASK.
+ (single_zero_operand): Likewise.
+
+2003-04-05 Daniel Berlin <dberlin@dberlin.org>
+
+ * Makefile.in (df.o): Depend on alloc-pool.h, not obstack.h.
+ * df.c: Include alloc-pool.h, not obstack.h.
+ (df_ref_obstack): Remove.
+ (df_ref_pool, df_link_pool): Add pools.
+ (df_alloc): Init the new pools.
+ (df_free): And free them.
+ (df_link_create): Use the pools.
+ (df_ref_create): Ditto.
+
+2003-04-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * simplify-rtx.c: Fix formatting.
+
+2003-04-05 Andrew Pinski <apinski@apple.com>
+
+ * config/rs6000/rs6000.c (addrs_ok_for_quad_peep): Allow addr2
+ reg with reg1 == reg2 and offset1 = -8.
+
+2003-04-05 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_rtx_costs): Halve Power4
+ multiply costs. Correct Power4 divide costs.
+ * config/rs6000/power4.md: Restore multiply and FP latency.
+
+2003-04-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * alias.c (find_base_term): Export.
+ * rtl.h (find_base_term): Declare.
+ * gcse.c (find_moveable_store): Test for flag_non_call_exceptions
+ instead of flag_exceptions. Move test for parameter passing ...
+ (store_killed_in_insn): ... here.
+
+2003-04-05 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ PR bootstrap/10267
+ * doc/install.texi (*-*-solaris2): /bin/ksh is not just recommended
+ for configuring.
+
+2003-04-04 Geoffrey Keating <geoffk@apple.com>
+
+ * dbxout.c (scope_labelno): Add GTY.
+ (have_used_extensions): Add GTY.
+ (source_label_number): Add GTY.
+ (lastfile): Add GTY.
+ (lastfile_is_base): New.
+ (base_input_file): New.
+ (dbxout_handle_pch): New.
+ (dbx_debug_hooks): Add handle_pch.
+ (xcoff_debug_hooks): Likewise.
+ (dbxout_function_end): Remove scope_labelno.
+ (dbxout_init): Set base_input_file.
+ (dbxout_handle_pch): New.
+ (dbxout_source_file): Honour lastfile_is_base.
+ * dwarfout.c (dwarf_debug_hooks): Add dummy handle_pch.
+ * sdbout.c (sdb_debug_hooks): Add dummy handle_pch.
+ * vmsdbgout.c (vmsdbg_debug_hooks): Add dummy handle_pch.
+ * dwarf2out.c (dwarf2_debug_hooks): Add dummy handle_pch.
+ * debug.c (do_nothing_debug_hooks): Add dummy handle_pch.
+ * debug.h (struct gcc_debug_hooks): Add handle_pch.
+ * c-pch.c (pch_init): Don't call start_source_file, but do call
+ handle_pch.
+ (c_common_write_pch): Call handle_pch.
+ (c_common_read_pch): Don't call start_source_file,
+ or end_source_file.
+
+Fri Apr 4 17:43:52 2003 Olivier Hainque <hainque@act-europe.fr>
+
+ * emit-rtl.c (get_mem_attrs): Adjust alignment tests determining
+ use of default attributes to agree MEM_ALIGN macro.
+
+Fri Apr 4 17:33:24 2003 Joel Brobecker <brobecker@gnat.com>
+
+ * dbxout.c (dbxout_type): When printing type index of range type
+ whose bounds are printed in octal format, print type of parent type if
+ it exists so enumerated type descriptions are not transformed
+ into unsigned types.
+
+2003-04-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add a prototype for
+ compute_a_shift_cc.
+ * config/h8300/h8300.c (shift_one): Update the CC status.
+ (shift_two): Likewise.
+ (output_a_shift_cc): Set cc_inline and cc_special.
+ (compute_a_shift_cc): New.
+ * config/h8300/h8300.md (shift insns): Use compute_a_shift_cc.
+
+2003-04-04 Richard Henderson <rth@redhat.com>
+
+ * cse.c (fold_rtx): Fix 03-30 change; do check insn non-null.
+
+2003-04-04 Loren James Rittle <ljrittle@acm.org>
+
+ * fixinc/inclhack.def (bsd_stdio_attrs_conflict): New.
+ * fixinc/fixincl.x: Rebuilt.
+ * fixinc/tests/base/stdio.h: Regenerated.
+
+2003-04-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov.c (accumulate_line_counts): Fix span tree merge bug.
+
+Fri Apr 4 15:58:52 2003 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (ACTUAL_NORMAL_MODE): New macro, broken out of
+ (NORMAL_MODE).
+ * sh.c (fpscr_set_from_mem): Use ACTUAL_NORMAL_MODE.
+
+2003-04-04 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/contrib.texi (Contributors): Add entries for Wolfgang
+ Bangerth, DJ Delorie, Christian Ehrhardt, Christopher Faylor,
+ Nathanael Nerode, Diego Novillo, Hartmut Penner, Volker Reichelt,
+ Danny Smith, and Ulrich Weigand.
+ Update Kriang Lerdsuwanakij and fix a typo in Janis Johnson's
+ entry.
+
+2003-04-04 Nick Clifton <nickc@redhat.com>
+
+ * config/sparc/sol2-bi.h: Revert previous delta.
+ * config/sparc/sol2-gas-bi.h (AS_SPARC64_FLAG): Prepend -TSO
+
+2003-04-04 Nick Clifton <nickc@redhat.com>
+
+ * config/v850/v850.c (expand_prologue): Only use register save
+ helper functions if long calls are not being used.
+ Add a clobber of r11 id using long calls.
+ (pattern_is_ok_for_prologue): Account for the extra clobber.
+ (construct_save_jarl): Likewise.
+ * config/v850/v850.md (prolog pattern): Do not use this pattern
+ for v850e's.
+
+2003-04-04 Andreas Schwab <schwab@suse.de>
+
+ * stor-layout.c (layout_decl): Avoid syntax error in last change
+ when PCC_BITFIELD_TYPE_MATTERS is defined but not
+ EMPTY_FIELD_BOUNDARY.
+
+2003-04-03 Jason Merrill <jason@redhat.com>
+
+ PR c/10175
+ * jump.c (never_reached_warning): Revert patch of 2002-11-02.
+ Look backwards for a line note.
+
+2003-04-03 Neil Booth <neil@daikokuya.co.uk>
+
+ * fix-header.c (read_scan_file): Defer switch processing.
+
+2003-04-03 Matt Austern <austern@apple.com>
+
+ * cpppch.c (reset_ht): Remove.
+ (cpp_read_state): Remove loop to reset hashtable identifiers.
+ * ggc-common.c (gt_pch_save): Add call to gt_pch_fixup_stringpool
+ after pch file is written.
+ * ggc.h (gt_pch_fixup_stringpool): Declare.
+ * stringpool.c (ht_copy_and_clear): Define. Callback. Copy
+ hashnode's value to another hashtable, then clear the original.
+ (saved_ident_hash): Define.
+ (gt_pch_save_stringpool): Create saved_ident_hash, use it to
+ store definitions in ident_hash, and clear ident_hash.
+ (gt_pch_fixup_stringpool): Define. Restore definitions from
+ saved_ident_hash to ident_hash, then destroy saved_ident_hash.
+
+Thu Apr 3 22:27:40 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * cfgrtl.c (update_bb_for_insn): Do not set block for barriers.
+
+2003-04-03 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/10157
+ * gcse.c (can_copy_p): Rename it to can_copy.
+ (can_copy_init_p): Remove.
+ (compute_can_copy): Use can_copy instead of can_copy_p.
+ (can_copy_p): New exported function. Call compute_can_copy.
+ (hash_scan_set): Use it.
+ (gcse_main): Don't call compute_can_copy.
+ (bypass_jumps): Don't call compute_can_copy.
+ * rtl.h (can_copy_p): Declare.
+ * loop.c (scan_loop): Don't move the source and add a reg-to-reg
+ copy if the mode doesn't support copy operations.
+
+2003-04-03 Jason Merrill <jason@redhat.com>
+
+ * Makefile.in (unstrap): Also remove stage_last.
+
+ * dwarf2out.c (lookup_filename): Don't check for "<internal>".
+ (dwarf2out_source_line): Don't do anything if line==0.
+
+ * stor-layout.c (do_type_align): New fn, split out from...
+ (layout_decl): ...here. Do all alignment calculations for
+ FIELD_DECLs here.
+ (update_alignment_for_field): Not here.
+ (start_record_layout, debug_rli): Remove unpadded_align.
+ * tree.h (struct record_layout_info_s): Remove unpadded_align.
+ * c-decl.c (finish_enum): Don't set DECL_SIZE, DECL_ALIGN
+ or DECL_MODE on the CONST_DECLs.
+ (finish_struct): Don't mess with DECL_ALIGN.
+
+Thu Apr 3 18:57:19 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (print_operand): Do not bypass output_addr_const at flag_pic.
+
+Thu Apr 3 17:08:09 2003 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (sh_function_ok_for_sibcall): Return 0 if the current
+ function is an interrupt handler.
+
+ * sh.c (sh_expand_epilogue): Avoid clash of temp register for
+ restoring target registers with EH_RETURN_STACKADJ_RTX; use
+ multiple registers in round-robin fashion.
+
+2003-04-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gengtype-lex.l (IWORD): Add CHAR_BITFIELD.
+ * system.h (CHAR_BITFIELD): New.
+
+2003-04-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): Generalize to accept GT
+ and LE.
+ (another peephole2): Likewise.
+
+2003-04-03 Nick Clifton <nickc@redhat.com>
+
+ * config/sparc/sol2-bi.h (ASM_CPU64_DEFAULT_SPEC): Add -TSO.
+ (DEF_ARCH64_SPEC): Likewise.
+
+Thu Apr 3 09:53:40 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (constant_address_p): Use legitimate_constant_p.
+ (legitimate_address_p): Do not use CONSTANT_ADDRESS_P.
+
+2003-04-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add a prototype for
+ gtle_operator.
+ * config/h8300/h8300.c (gtle_operator): New.
+ * config/h8300/h8300.h (PREDICATE_CODES): Add an entry for
+ gtle_operator.
+ * config/h8300/h8300.md (a peephole2): Generalize to accept GT
+ and LE.
+
+2003-04-02 Richard Henderson <rth@redhat.com>
+
+ * libgcc-std.ver (_Unwind_GetCFA): New.
+ * unwind-dw2.c (_Unwind_GetCFA): New.
+ * unwind-libunwind.c (_Unwind_GetCFA): New.
+ * unwind-sjlj.c (_Unwind_GetCFA): New.
+ * unwind.h: Declare it.
+
+Thu Apr 3 00:31:21 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ PR inline-asm/8088
+ * i386.c (ix86_hard_regno_mode_ok): Return 0 for MMX/SSE registers
+ when MMX/SSE is not available.
+
+2003-04-02 Mike Stump <mrs@apple.com>
+
+ * doc/install.texi (Specific): Update pointers to apple.com.
+
+Thu Apr 3 00:18:49 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (override_options): Disable red zone by default on i386.
+ (compute_frame_layout, ix86_force_to_memory, ix86_free_from_memory):
+ Do not test TARGET_64BIT together with TARGET_RED_ZONE
+
+2003-04-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): Tighten the condition.
+
+2003-04-02 Richard Henderson <rth@redhat.com>
+
+ * longlong.h (umul_ppmm) [alpha]: Use __builtin_alpha_umulh.
+
+2003-04-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): New.
+
+2003-04-02 Richard Henderson <rth@redhat.com>
+
+ * except.c (sjlj_find_directly_reachable_regions): Recognize when
+ must-not-throw region has been deleted.
+
+2003-04-02 Richard Henderson <rth@redhat.com>
+
+ * dwarf2out.c (output_call_frame_info): Ignore fde->nothrow as an
+ optimization when flag_exceptions not enabled.
+
+2003-04-02 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/rs6000/rs6000.c
+ (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD): Redefine the
+ macros.
+ (rs6000_issue_rate): Add case for 8540.
+ (rs6000_use_sched_lookahead): New function.
+
+ * config/rs6000/8540.md: Rename SIU units into SU ones and MIU
+ units into MU ones.
+ (ppc8540_branch, ppc8540_cr_logical): Add one cycle in the
+ reservation before retirement.
+ (ppc8540_multiply, ppc8540_load, ppc8540_store,
+ ppc8540_simple_float, ppc8540_vector_load, ppc8540_vector_store):
+ Remove additional cycle in the reservation before retirement.
+ (ppc8540_mfcr, ppc8540_mtcrf, ppc8540_mtjmpr): Add missed
+ reservation of ppc8540_issue.
+
+2003-04-02 Andreas Schwab <schwab@suse.de>
+
+ * real.c (decode_ieee_single): Fix decoding of SNaN bit.
+
+2003-04-01 Richard Henderson <rth@redhat.com>
+
+ * except.c (convert_from_eh_region_ranges_1): Smash REG_EH_REGION
+ notes for nothrow calls if flag_forced_unwind_exceptions.
+ (build_post_landing_pads): Mind flag_forced_unwind_exceptions.
+ (sjlj_find_directly_reachable_regions): Likewise.
+ (reachable_handlers): Likewise.
+ (can_throw_external): Likewise.
+ (collect_one_action_chain): Record cleanups after catch-all and
+ must-not-throw if flag_forced_unwind_exceptions.
+ * flags.h (flag_forced_unwind_exceptions): Declare.
+ * toplev.c (flag_forced_unwind_exceptions): New.
+ (lang_independent_options): Add it.
+ * doc/invoke.text: Add it.
+
+2003-04-01 David Mosberger <davidm@hpl.hp.com>
+
+ * config/ia64/crti.asm: Clean up trailing whitespace.
+ Remove trailing hashes (#) from identifiers.
+
+ * config/ia64/crtn.asm: Ditto.
+
+ * config/ia64/crtend.asm: Remove trailing hashes (#) from
+ identifiers.
+ (__do_global_ctors_aux): Align to 32-byte boundary. Add unwind
+ directives. Drop explicit bundling---it just makes the code
+ harder to read. Don't save/restore gp needlessly.
+
+ * config/ia64/crtbegin.asm: Remove trailing hashes (#) from
+ identifiers (they're only needed if the identifier would clash
+ with a register name otherwise).
+ (__do_global_dtors_aux): Align to 32-byte boundary. Add unwind
+ directives. Drop explicit bundling---it just makes the code
+ harder to read.
+ (__do_jv_register_classes): Ditto.
+ (.fini_array): Remove "progbits" (newer
+ assemblers don't like wrong section-types).
+ (.init_array): Ditto.
+
+2003-04-01 Roger Sayle <roger@eyesopen.com>
+
+ PR fortran/9974
+ * gcse.c (reg_killed_on_edge): New function to test whether the
+ given reg is overwritten by any instruction queued on an edge.
+ (bypass_block): Ignore substitutions killed on incoming edges.
+ Don't bypass outgoing edges that have queued instructions.
+
+2003-04-01 Alexandre Oliva <aoliva@redhat.com>
+
+ * real.h (EXP_BITS): Make room for...
+ (struct real_value): ... added canonical bit.
+ (struct real_format): Added pnan.
+ (mips_single_format, mips_double_format, mips_extended_format,
+ mips_quad_format): New.
+ * real.c: Copy p to pnan in all formats.
+ (get_canonical_qnan, get_canonical_snan): Set canonical bit.
+ (real_nan): Use pnan to compute significand's shift.
+ (real_identical): Disregard significand in canonical
+ NaNs.
+ (real_hash): Likewise. Take signalling into account.
+ (encode_ieee_single, encode_ieee_double, encode_ieee_quad):
+ Disregard significand bits in canonical NaNs. Set all bits of
+ canonical NaN if !qnan_msb_set.
+ (encode_ibm_extended, decode_ibm_extended): Likewise. Use
+ qnan_msb_set to tell the base double format.
+ (ibm_extended_format): Use 53 as pnan.
+ (mips_single_format, mips_double_format, mips_extended_format,
+ mips_quad_format): Copied from the corresponding ieee/ibm
+ formats, with qnan_msb_set false.
+ * config/mips/iris6.h (MIPS_TFMODE_FORMAT): Use mips_extended_format.
+ * config/mips/linux64.h (MIPS_TFMODE_FORMAT): Use mips_quad_format.
+ * config/mips/mips.c (override_options): Use mips_single_format
+ and mips_double_format. Default TFmode to mips_quad_format.
+ * config/mips/t-linux64 (tp-bit.c): Define QUIET_NAN_NEGATED.
+ * config/mips/t-irix6: Likewise.
+ * config/mips/t-mips (fp-bit.c, dp-bit.c): Likewise.
+ * config/fp-bit.c (pack_d, unpack_d): Obey it.
+
+2003-04-01 Geoffrey Keating <geoffk@apple.com>
+
+ * unwind-dw2-fde-darwin.c (DESTRUCTOR_MAY_BE_CALLED_LIVE): New.
+ (live_image_destructor): Reset image to initial state.
+ (examine_objects): Set DESTRUCTOR_MAY_BE_CALLED_LIVE.
+
+2003-04-01 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * config/sparc/sparc.c (input_operand): Accept bare
+ CONSTANT_P_RTX operands.
+
+2003-04-01 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcse.c (struct ls_expr): Added pattern_regs field.
+ (ldst_entry): Initialize it.
+ (extract_mentioned_regs, extract_mentioned_regs_helper): New.
+ (store_ops_ok): Use regs precomputed by them.
+ (find_loads, store_killed_in_insn, load_kills_store): Change return
+ type to bool.
+ (store_killed_before, store_killed_after): Take position of register
+ set in account.
+ (reg_set_info): Store position of the setter.
+ (gcse_main): Enable store motion.
+ (mems_conflict_for_gcse_p): Enable load motion of non-symbol mems.
+ (pre_insert_copy_insn, update_ld_motion_stores, insert_store): Prevent rtl
+ sharing.
+ (simple_mem): Enable store motion of non-symbol mems.
+ (regvec): Type changed.
+ (LAST_AVAIL_CHECK_FAILURE): New.
+ (compute_store_table_current_insn): New.
+ (build_store_vectors): Computation of availability and anticipatability
+ moved ...
+ (compute_store_table, find_moveable_store): ... here.
+ (delete_store): Remove senseless comment.
+ (store_motion): Reorganize.
+
+2003-04-01 Kevin Buettner <kevinb@redhat.com>
+
+ * config/mips/mips.c (override_options): Provide mappings for
+ HI_REGNUM and LO_REGNUM.
+ * config/mips/mips.h (MD_DBX_FIRST): Define.
+
+2003-04-01 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * combine.c (merge_outer_ops): Fix typo.
+
+ * varasm.c (make_decl_one_only): Revert 2003-03-09 patch.
+
+2003-04-01 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/{40x.md,603.md,6xx.md,7450.md,7xx.md,mpc.md,
+ power4.md,rios1.md,rios2.md,rs64.md}: Change mult_compare to
+ imul_compare. Add lmul_compare.
+ * config/rs6000/power4.md: Bump some latencies. Model extra cycle
+ in second pair of dispatch slots. Model stores more accurately.
+ Tweak multiply model. Add bypasses for CR instructions dependent
+ on complicated compares.
+ * config/rs6000/rs6000.md (mulsi3): Name imul_compare patterns.
+ (muldi3): Add lmul_compare patterns.
+ * config/rs6000/rs6000.c (rs6000_variable_issue): Move FPLOAD_UX
+ and FPSTORE_UX to split instructions and add COMPARE,
+ DELAYED_COMPARE, IMUL_COMPARE, LMUL_COMPARE, IDIV, LDIV.
+ (rs6000_adjust_cost): Add IMUL_COMPARE and LMUL_COMPARE.
+ (rs6000_rtx_costs): Separate POWER4 multiply case.
+
+2003-04-01 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_fixup_clobbered_return_reg):
+ Do nothing if __builtin_return_address was not used.
+
+Tue Apr 1 18:18:23 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (test patterns): Allow memory operand in operand1.
+
+2003-04-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * testsuite/gcc.c-torture/execute/simd-3.c: New.
+
+ * expr.c (expand_expr): Handle VECTOR_CST.
+ (const_vector_from_tree): New.
+
+ * varasm.c (output_constant): Handle VECTOR_CST.
+
+ * c-typeck.c (digest_init): Build a vector constant from a
+ VECTOR_TYPE.
+
+ * config/rs6000/rs6000.c: Remove prototype for
+ easy_vector_constant.
+ (easy_vector_constant): Add mode parameter. Rewrite to handle
+ more easy constants.
+ (rs6000_emit_move): Pass mode to easy_vector_constant.
+ Call emit_easy_vector_insn for SPE V2SI vector constant moves.
+ (emit_easy_vector_insn): New.
+ (easy_vector_same): New.
+ (EASY_VECTOR_15): New macro.
+ (EASY_VECTOR_15_ADD_SELF): New macro.
+ (bdesc_2arg): Rename to xorv2si3.
+ (easy_vector_constant_add_self): New.
+ (input_operand): Allow vector constants.
+
+ * config/rs6000/rs6000.h (PREDICATE_CODES): Add
+ easy_vector_constant, easy_vector_constant_add_self.
+ (EXTRA_CONSTRAINT): Add 'W'.
+
+ * config/rs6000/rs6000-protos.h: Add prototype for
+ easy_vector_constant, emit_easy_vector_insn.
+
+ * config/rs6000/altivec.md (xorv8hi3): New.
+ (xorv16qi3): New.
+ Remove all _const0 patterns.
+ (movv4si_internal): Rewrite to use code. Add vector constant to
+ vector alternative. Add splitter.
+ (movv8hi_internal): Same.
+ (movv16qi_internal): Same.
+ (movv4sf_internal): Same.
+ Change the unspecs for vspltis* to use constants.
+
+ * config/rs6000/spe.md ("xorv4hi3"): New.
+ ("spe_evxor"): Rename to xorv2si3.
+ ("xorv1di3"): New.
+ Remove all _const0 patterns.
+ (movv2si_internal): Rewrite to use code. Add vector constant to
+ alternatives. Add splitter.
+ (movv4hi_internal): Add vector constant to alternatives.
+ (movv1di_internal): Same.
+ (movv2sf_internal): Same.
+
+2003-03-31 Mark Mitchell <mark@codesourcery.com>
+
+ PR c/9936
+ * c-decl.c (grokdeclarator): Clear SAVE_EXPR_CONTEXT for
+ variably-sized arrays in parameters.
+ (set_save_expr_context): New function.
+ (c_expand_body): Use it, via walk_tree.
+
+2003-03-31 Eric Christopher <echristo@redhat.com>
+
+ * combine.c (can_combine_p): Allow ZERO_EXTRACT and STRICT_LOW_PART.
+ (combinable_i3pat): Remove call to expand_field_assignment and
+ #if 0'd code.
+
+2003-03-31 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10278
+ * c-common.c (finish_label_address_expr): Handle the
+ error_mark_node.
+
+2003-03-31 Richard Henderson <rth@redhat.com>
+
+ * real.c (real_identical): Reorg so as to not compare
+ signalling for normals.
+
+2003-03-31 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (hard_reg_operand): Check the mode.
+
+2003-03-31 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (m68hc11_gen_movhi): Don't rely on REG_WAS_0
+ notes as they are boggus.
+ (m68hc11_gen_movqi): Likewise.
+
+2003-03-31 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (expand_prologue): For an interrupt handler
+ save the soft registers after the frame pointer so that gdb can unwind
+ the frame more easily.
+ (expand_epilogue): Likewise in opposite order; allow to use X register
+ as scratch if the return value is by reference.
+
+2003-03-31 Jason Merrill <jason@redhat.com>
+
+ PR java/10145
+ * stor-layout.c (update_alignment_for_field): Respect
+ DECL_USER_ALIGN for zero-length bitfields, too.
+ * c-decl.c (finish_struct): Don't set DECL_ALIGN for normal
+ fields.
+
+2003-03-31 Matt Austern <austern@apple.com>
+
+ * cpppch.c (struct cpp_savedstate): Add defs and n_defs members.
+ (count_defs): Keep track of number of defs as well as total size.
+ (write_defs): Put every definition in cpp_savedstate's defs array.
+ (comp_hashnode): Define. Comparison function for qsort.
+ (cpp_write_pch_deps): Sort definitions before writing them.
+ (struct ht_node_list): Define. Like cpp_savedstate but simpler.
+ (collect_ht_nodes): Define.
+ (cpp_valid_state): When verifying that undefined identifiers in
+ the pch file are still undefined, read a sorted list of undefined
+ identifiers, collect all defined identifiers into a sorted list,
+ and walk through both lists to make sure there's no match.
+
+2003-03-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): New.
+
+2003-03-31 Michael Matz <matz@suse.de>
+
+ * config/i386/i386.h (TARGET_FLT_EVAL_METHOD): Change 1 into 0.
+
+2003-03-31 Segher Boessenkool <segher@koffie.nl>
+
+ PR target/10177
+ * config/rs6000/rs6000.h (HARD_REGNO_RENAME_OK): New.
+ * config/rs6000/rs6000.c (compute_vrsave_mask): Don't mark
+ all call-clobbered registers as used.
+
+2003-03-31 Michael Matz <matz@suse.de>
+
+ * cppexp.c (cpp_classify_number): Accept '.' after "0x".
+ * testsuite/gcc.dg/cpp/c99-hexfloat-3.c: New file.
+
+2003-03-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov.c: Add -a & -u options.
+ (struct arc_info): Add local_span, is_call_non_return,
+ is_nonlocal_return, is_unconditional flags, remove is_call flag.
+ (struct block_info): Add flags, is_call_site, is_nonlocal_return
+ members. Make encodings a union with span member.
+ (struct function_info): Add blocks_executed, line, src, line_next
+ members.
+ (struct coverage_info): Make branches a union with blocks member.
+ (struct source_info): Add functions member.
+ (object_summary, program_count): New global variables.
+ (flag_all_blocks, flag_unconditional): New flags.
+ (find_source, output_branch_count): New functions.
+ (print_usage): Adjust.
+ (options): Adjust.
+ (process_args): Adjust.
+ (read_graph_file) <GCOV_TAG_FUNCTION>: Adjust.
+ <GCOV_TAG_BLOCKS>: Read flags.
+ <GCOV_TAG_LINES>: Adjust.
+ (read_count_file): Process SUMMARY tags.
+ (solve_flow_graph): Set is_unconditional and clear is_call_site
+ appropriately.
+ (add_branch_counts): Adjust. Don't count unconditional branches.
+ (add_line_counts): Deal with all-blocks mode, accumulate block
+ coverage.
+ (accumulate_line_counts): Adjust, generate local spanning tree for
+ all-blocks mode.
+ (output_lines): Adjust.
+ * profile.c (branch_prob): Alter GCOV_FUNCTION_TAG record.
+ * doc/gcov.texi: Document.
+
+2003-03-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Organize peephole2's that transform
+ (compare (reg:HI) (const_int)).
+
+2003-03-31 Roger Sayle <roger@eyesopen.com>
+
+ * emit-rtl.c (dconstm2, dconsthalf): New real constants.
+ (init_emit_once): Initialize dconstm2 and dconsthalf here.
+ * real.h (dconstm2, dconsthalf): Add prototypes here.
+ * real.c (real_sqrt): Use dconsthalf rather than local copy.
+ * builtins.c (fold_builtin): When optimizing sqrt(exp(x)) as
+ exp(x/2.0) remember to fold the division if possible.
+ Fold sin(0.0) as 0.0, cos(0.0) as 1.0, pow(x,1.0) as x,
+ pow(x,-1.0) as 1.0/x, pow(x,2.0) as x*x, pow(x,-2.0) as
+ 1.0/(x*x) and pow(x,0.5) as sqrt(x).
+
+2003-03-31 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a new peephole2): New.
+
+2003-03-31 Richard Sandiford <rsandifo@redhat.com>
+
+ * gcse.c (simple_mem): Return false for floating-point accesses
+ if flag_float_store is true.
+
+2003-03-30 Roger Sayle <roger@eyesopen.com>
+
+ * gcse.c (gcse_constant_p): New function to identify constants
+ suitable for constant propagation, including COMPARE with two
+ integer constant arguments.
+ (hash_scan_set): Use gcse_constant_p.
+ (find_avail_set): Likewise.
+ (cprop_insn): Likewise.
+ (do_local_cprop): Likewise.
+ (find_implicit_sets): Likewise.
+ (find_bypass_set): Likewise.
+
+2003-03-30 Matt Kraai <kraai@alumni.cmu.edu>
+
+ * except.h: Remove definition of varray_type.
+
+2003-03-30 Richard Henderson <rth@redhat.com>
+
+ PR opt/10011, opt/10252:
+ * toplev.c (rest_of_compilation): Run purge_builtin_constant_p
+ before post-gcse cse pass.
+
+2003-03-30 Roger Sayle <roger@eyesopen.com>
+
+ * dojump.c (do_jump): Copy SUBREGs into a pseudo for comparison.
+
+2003-03-30 DJ Delorie <dj@redhat.com>
+
+ * profile.c (instrument_edges): Make sure any newly created
+ jump insns have correct jump label info.
+
+2003-03-30 Richard Henderson <rth@redhat.com>
+
+ * cfgbuild.c (make_edges): Use tablejump_p.
+ * cfgcleanup.c (label_is_jump_target_p): Likewise.
+ * cfglayout.c (cfg_layout_can_duplicate_bb_p): Likewise.
+ * cfgrtl.c (flow_delete_block_noexpunge): Likewise.
+ (try_redirect_by_replacing_jump): Likewise.
+ (redirect_edge_and_branch): Likewise.
+ * cse.c (fold_rtx): Likewise.
+ * jump.c (delete_related_insns): Likewise.
+ * rtlanal.c (get_jump_table_offset): Likewise.
+ * ssa-ccp.c (ssa_ccp_df_delete_unreachable_insns): Likewise.
+
+2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * Makefile.in (STRICT_WARN): Don't warn for ISO C constructs.
+ (STRICT2_WARN): Likewise.
+
+2003-03-30 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ PR other/6955
+ * collect2.c (collect_wait): Use WCOREDUMP and fix output message.
+ * system.h (WCOREDUMP, WCOREFLG): Define if necessary.
+
+2003-03-30 Richard Henderson <rth@redhat.com>
+
+ PR c/10083
+ * config/alpha/alpha.md (umuldi3_highpart): Change to expander;
+ don't zero_extend const inputs.
+
+2003-03-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * reload1.c (reload_cse_move2add): Fix a comment typo.
+
+2003-03-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): Remove useless code.
+
+2003-03-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*iorsi3_and_ashift): New.
+ (*iorsi3_and_lshiftrt): Likewise.
+ (*iorsi3_zero_extract): Likewise.
+
+2003-03-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*insv_si_8_8): New.
+ (*insv_si_8_8_lshiftrt_8): Likewise.
+ (a peephole2): Likewise.
+
+2003-03-29 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/contrib.texi: Add Eric Botcazou and Roger Sayle.
+ Uniformly use bugfix instead of bug fix.
+
+2003-03-29 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ PR doc/895
+ * ONEWS: Remove those items that already appear in the EGCS
+ release notes on our web pages.
+
+2003-03-29 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.h (FUNCTION_VALUE_REGNO_P): Respect
+ TARGET_HARD_FLOAT. Reformat.
+ (FUNCTION_ARG_REGNO_P): Likewise, and remove unneeded casts.
+
+2003-03-28 Albert Chin-A-Young <china@thewrittenword.com>
+
+ * gcc/fixinc/inclhack.def: Update solaris_mutex_init_1 to
+ work on Solaris 2.5.1.
+
+2003-03-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*addsi3_and_r_1): Put under plus:SI
+ section of h8300.md
+ (*addsi3_and_nor_r_1): Likewise.
+
+2003-03-29 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_emit_prologoue): Make sure backchain is
+ set up before any trapping memory access if flag_non_call_exceptions.
+
+2003-03-29 Alan Modra <amodra@bigpond.net.au>
+
+ * reload1.c (reload_as_needed): Allow a USE in asm reloads.
+
+ * loop.c: (find_mem_in_note_1, find_mem_in_note): Comment.
+
+2003-03-28 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Clarify comments.
+ * configure: Regenerate.
+
+2003-03-28 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("literal_pool_31"): Output pool anchor
+ label even if pool empty when generating PIC.
+ ("literal_pool_31", "literal_pool_64"): Coding style cleanup.
+
+2003-03-28 Kazu Hirata <kazu@cs.umass.edu>,
+ Dhananjay Deshpande <dhananjayd@kpit.com>
+
+ PR target/10205
+ * config/h8300/h8300.c (h8300_initial_elimination_offset):
+ Correct the offset computation when TARGET_NORMAL.
+
+2003-03-28 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/10067
+ * config/sparc/sparc.md (jump pattern): Correct order
+ when issuing the annuling marker.
+
+2003-03-28 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/8281
+ * config/sparc/sparc.md (movdi_insn_sp32_v9): Remove 'f-f' alternative.
+ (movdi reg/reg split): Match only on sparc32, and v9 when int regs.
+
+2003-03-28 Alan Modra <amodra@bigpond.net.au>
+
+ * config/alpha/elf.h (ASM_OUTPUT_ALIGNED_BSS): Remove unnecessary
+ globalize_label.
+ * config/arm/unknown-elf.h (ASM_OUTPUT_ALIGNED_BSS): Likewise.
+ * config/i960/i960.h (ASM_OUTPUT_ALIGNED_BSS): Likewise.
+ * config/m32r/m32r.h (ASM_OUTPUT_ALIGNED_BSS): Likewise.
+ * config/mips/elf.h (ASM_OUTPUT_ALIGNED_BSS): Likewise.
+ * config/mips/linux.h (ASM_OUTPUT_ALIGNED_BSS): Likewise.
+ * config/sparc/sparc.h (ASM_OUTPUT_ALIGNED_BSS): Likewise.
+ * config/v850/v850.c (v850_output_aligned_bss): Likewise.
+
+2003-03-28 Alan Modra <amodra@bigpond.net.au>
+
+ * loop.c: (find_mem_in_note_1, find_mem_in_note): New functions.
+ (replace_loop_mems): Add "written" param. Remove invalid REG_EQUAL
+ notes after hoisting.
+ (load_mems): Adjust replace_loop_mems call.
+
+2003-03-28 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Richard Henderson <rth@redhat.com>
+
+ PR target/10114 and PR target/10084
+ * dwarf2out.c (mem_loc_descriptor): Handle LO_SUM.
+
+2003-03-27 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.md (adddi_er_high_l): Valid only after reload.
+
+2003-03-27 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold_inf_compare): New function to simplify FP
+ comparisons against +Infinity or -Infinity.
+ (fold): Optimize floating point comparisons against Infs and NaNs.
+
+2003-03-27 Janis Johnson <janis187@us.ibm.com>
+
+ * libgcov.c: Provide only dummy functions if libc is not available.
+
+2003-03-27 Richard Henderson <rth@redhat.com>
+
+ * real.h (struct real_value): Add signalling.
+ (EXP_BITS): Decrement.
+ * real.c (get_canonical_qnan): Don't set MSB-1.
+ (get_canonical_snan): Likewise. Set signalling.
+ (real_identical): Compare signalling.
+ (round_for_format): Remove force-one-bit on code.
+ (real_nan): Likewise. Set signalling.
+ (encode_ieee_single): Add force-one-bit code; honor signalling.
+ (encode_ieee_double, encode_ieee_extended, encode_ieee_quad): Likewise.
+ (decode_ieee_single): Set signalling.
+ (decode_ieee_double, decode_ieee_extended, decode_ieee_quad): Likewise.
+
+2003-03-27 Olivier Hainque <hainque@act-europe.fr>
+
+ PR ada/9953
+ * ada/Makefile.in (gnatlib configuration for HPUX): Split
+ the general section for HPUX into specific sections for
+ HPUX 10 and HPUX 11. Fix the setting of TGT_LIB in the HPUX
+ 11 case.
+
+2003-03-27 Glen Nakamura <glen@imodulo.com>
+
+ PR opt/10087
+ * loop.c (loop_givs_reduce): Skip bivs with duplicate locations
+ while incrementing giv.
+ (record_biv): Check for duplicate biv locations and
+ set (struct induction *) v->same if found.
+
+2003-03-27 David Mosberger <davidm@hpl.hp.com>
+
+ * unwind-libunwind.c (uw_frame_state_for): Adjust for libunwind
+ v0.9 API change: replace read of UNW_REG_HANDLER with
+ unw_get_proc_info().
+ (_Unwind_GetLanguageSpecificData): Replace read of UNW_REG_LSDA
+ with unw_get_proc_info().
+ (_Unwind_GetRegionStart): Replace UNW_REG_PROC_START with
+ unw_get_proc_info().
+
+2003-03-27 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/rs6000/8540.md: Use presence_set instead of absence_set.
+
+2003-03-26 Richard Henderson <rth@redhat.com>
+
+ * c-decl.c (finish_function): Always defer if DECL_DECLARED_INLINE_P.
+
+2003-03-26 Roger Sayle <roger@eyesopen.com>
+
+ PR bootstrap/10051, PR bootstrap/10169.
+ * mips-tfile.c (init_file): Don't provide a static initializer.
+ (initialize_init_file): Initialize the contents of init_file.
+ (add_file): Call initialize_init_file if not already initialized.
+
+2003-03-26 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_optimize_prolog): Do not save/restore
+ registers used for global asm variables.
+ (s390_frame_info, s390_arg_frame_offset): Likewise.
+ (s390_emit_prologue, s390_emit_epilogue): Likewise.
+
+2003-03-26 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/rs6000/8540.md: New file.
+
+ * config/rs6000/{40x.md, 603.md, 6xx.md, 7450.md, 7xx.md, mpc.md,
+ power4.md, rios1.md, rios2.md, rs64.md}: Add mult_compare to
+ reservations for imul.
+
+ * config/rs6000/rs6000.md: Include 8540.md. Change
+ delayed_compare onto mult_compare for insns generating
+ multiplication.
+ (mult_compare, fpsimple, brinc, vecdiv, veccmpsimple, vecfdiv):
+ New type attribute values.
+
+ * config/rs6000/spe.md (*negsf2_gp, *abssf2_gpr): Use type
+ fpsimple instead of fp.
+ (*divsf3_gpr): Use type vecfdiv instead of fp.
+ (spe_evfsabs, spe_evfsnabs, spe_evfsneg): Use type vecsimple
+ instead of vecfloat.
+ (spe_evfsdive): Use type vecfdiv instead of vecfloat.
+ (spe_brinc): Use type brinc instead of veccomplex.
+ (spe_evaddw, spe_evaddiw): Use type vecsimple instead of
+ veccomplex.
+ (spe_evdivws, spe_evdivwu): Use type vecdiv instead of veccomplex.
+ (*movv2si_internal, *movv1di_internal, *movv4hi_internal,
+ *movv2sf_internal): Define type attribute values for all
+ alternatives.
+ (cmpsfeq_gpr, cmpsfgt_gpr, cmpsflt_gpr): Use type veccmp instead
+ of fpcompare.
+ (tstsfeq_gpr, tstsfgt_gpr, tstsflt_gpr): Use type veccmpsimple
+ instead of fpcompare.
+
+2003-03-26 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/power4.md: Allow delay between dispatch and
+ function units for simple instructions. Correct store units.
+ Allow branch to occupy as many dispatch slots as necessary.
+
+2003-03-26 Jakub Jelinek <jakub@redhat.com>
+
+ * config/ia64/ia64.c (ia64_expand_op_and_fetch): Fix comment.
+ (ia64_expand_compare_and_swap): Use always DImode ar.ccv,
+ zero extend old to it.
+ * config/ia64/ia64.md (cmpxchg_acq_si): Remove mode from ccv
+ operand.
+
+2003-03-26 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/7784
+ * reload.c (find_reloads_address): Handle
+ (PLUS (PLUS (REG) (REG)) (CONST_INT)) form for
+ all base registers.
+
+2003-03-25 Marcelo Abreu <mmabreu@inf.ufrgs.br>
+
+ PR other/10203
+ * version.c: Reference the GCC web site in the URL.
+
+2003-03-26 Alan Modra <amodra@bigpond.net.au>
+
+ * c-incpath.c (add_standard_paths): Add both "translated" and
+ non-translated header paths.
+
+2003-03-25 Loren James Rittle <ljrittle@acm.org>
+
+ * doc/install.texi (*-*-freebsd*): Update with known status.
+
+2003-03-21 Jason Merrill <jason@redhat.com>
+
+ PR optimization/10171
+ * unroll.c (unroll_loop): Don't delete the jump at the end unless
+ we also delete a jump at the beginning.
+
+2003-03-25 Stephane Carrez <stcarrez@nerim.fr>
+
+ * doc/contrib.texi (Contributors): Mention self as 68HC11/68HC12
+ contributor.
+
+Tue Mar 25 20:35:51 CET 2003 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_rtx_costs): For -fpic and x86-64 local symbolic
+ constants are not expensive.
+
+Mon Mar 24 20:03:03 CET 2003 Jan Hubicka <jh@suse.cz>
+
+ PR opt/10056
+ * cfglayout.c (fixup_reorder_chain): Fix dealing with the conditional
+ jump jumping to the next instruction.
+ * cfgrtl.c (force_nonfallthru_and_redirect): Likewise.
+
+2003-03-25 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/passes.texi (Passes): Properly document that we do not
+ perform jump2 any longer; remove command-line option -dJ.
+
+2003-03-25 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/8746
+ * config/i386/i386.md (and promoting splitters): Disable HImode to
+ SImode promoting when the sign bit matters and is not preserved, or
+ when TARGET_FAST_PREFIX is true. Disable promoting when optimizing
+ for size.
+
+2003-03-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): Extend to support loads
+ in QImode and HImode.
+
+2003-03-24 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/t-m68hc11-gas (LIB1ASMFUNCS): Add _call_far and
+ _return_far
+ (MULTILIB_OPTIONS): Don't multilib on -mlong-calls.
+ (MULTILIB_EXCEPTIONS): Likewise.
+ * config/m68hc11/m68hc11.md ("call"): Support far calls for 68HC11
+ by calling some board support routine.
+ ("call_value"): Likewise.
+ ("*return_void"): Likewise for return.
+ ("*return_16bit"): Likewise.
+ ("*return_32bit"): Likewise.
+ * config/m68hc11/m68hc11.h (ASM_DECLARE_FUNCTION_NAME): Generate .far
+ for 68HC11 too.
+ (DWARF2_ADDR_SIZE): Use 4 so that addresses can
+ * config/m68hc11/m68hc11.c (m68hc11_override_options): Accept
+ -mlong-calls for 68HC11.
+ * config/m68hc11/larith.asm (declare_near): New macro.
+ (__premain, ___negsi2, ___one_cmplsi2, ___ashlsi3): Use it.
+ (___ashrsi3, ___lshrsi3, ___lshrhi3, ___lshlhi3): Likewise.
+ (___rotrhi3, ___rotlhi3, ___ashrhi3, ___ashrqi3): Likewise.
+ (___lshlqi3, __divmodhi4, ___mulqi3, ___mulhi3): Likewise.
+ (__mulhi32): Likewise.
+ (ret): Update macro for 68HC11.
+ (__far_trampoline): Implement for 68HC11.
+ (__call_a16, __call_a32, __return_void, __return_16): New support
+ routines for 68HC11 memory bank switching calling support.
+ (__return_32): Likewise.
+
+2003-03-24 Neil Booth <neil@daikokuya.co.uk>
+
+ * toplev.c (independent_decode_option): Don't skip a 'Y' prefix.
+
+2003-03-24 Janis Johnson <janis187@us.ibm.com>
+
+ * doc/install.texi (Testing): Mention test result links from build
+ status pages.
+
+2003-03-24 Mark Mitchell <mark@codesourcery.com>
+
+ * function.c (put_var_into_stack): Change bool parameter to int.
+ (gen_mem_addressof): Likewise.
+ * rtl.h (gen_mem_addressof): Likewise.
+ * tree.h (put_var_into_stack): Likewise.
+ * config/alpha/alpha.c (alpha_gp_save_rtx): Adjust call to
+ gen_mem_addressof or put_var_into_stack.
+ * config/c4x/c4x.c (c4x_expand_builtin): Likewise.
+ * config/ia64/ia64.c (spill_tfmode_operand): Likewise.
+
+2003-03-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): New.
+
+2003-03-24 Jakub Jelinek <jakub@redhat.com>
+
+ * dojump.c (do_jump): Handle UNSAVE_EXPR specially.
+
+2003-03-24 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/contrib.texi (Contributors): Update Janis Johnson.
+
+2003-03-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/10072
+ * combine.c (simplify_if_then_else): Check that the mode
+ has MODE_INT class before applying the (OP Z (mult COND C2))
+ transformation.
+
+2003-03-23 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/9414
+ * config/sparc/sparc.md (widening peepholes): Use
+ widen_memory_access instead of change_address.
+
+2003-03-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7086
+ * c-typeck.c (c_mark_addressable): Adjust calls to
+ put_var_into_stack.
+ * expr.c (expand_expr): Likewise.
+ * function.c (put_var_into_stack): Add rescan parameter. Do not
+ call fixup_var_refs when rescan is false.
+ (gen_mem_addressof): Likewise.
+ (assign_parms): Adjust calls to put_var_into_stack.
+ (setjmp_protect): Likewise.
+ (setjmp_protect_args): Likewise.
+ * rtl.h (gen_mem_addressof): Change prototype.
+ * stmt.c (expand_decl): Adjust calls to put_var_into_stack.
+ * tree.h (put_var_into_stack): Change prototype.
+
+2003-03-23 Arpad Beszedes <beszedes@cc.u-szeged.hu>
+
+ PR middle-end/9967
+ * builtins.c (expand_builtin_fputs): When optimizing for size,
+ don't transform fputs into fwrite.
+
+2003-03-23 Glen Nakamura <glen@imodulo.com>
+
+ PR c/8224
+ * fold-const.c (extract_muldiv_1): Don't pass through type conversions
+ when signedness changes for division or modulus.
+
+2003-03-24 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_BSS): Remove unnecessary
+ globalize_label.
+
+2003-03-23 Roger Sayle <roger@eyesopen.com>
+
+ PR c/10178
+ * stmt.c (expand_end_case_type): Check for overflow in range when
+ determining whether to use a bit-test implementation.
+
+2003-03-23 Richard Henderson <rth@redhat.com>
+
+ * cfgcleanup.c (try_optimize_cfg): Allow merging of tablejumps
+ before flow2.
+ * cfgrtl.c (try_redirect_by_replacing_jump): Similarly.
+
+2003-03-23 Richard Henderson <rth@redhat.com>
+
+ PR opt/10116
+ * ifcvt.c (find_if_block): Disallow tablejump insns outgoing
+ from then_bb or else_bb after flow2.
+
+2003-03-23 Zack Weinberg <zack@codesourcery.com>
+
+ * configure.in: Check whether it is necessary to link against
+ libm to use ldexp.
+ * configure: Regenerate.
+ * Makefile.in: Add LDEXP_LIB substitution variable.
+
+2003-03-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Fix comment typos.
+
+2003-03-22 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (output_cbranch): Fix typo in comment.
+
+2003-03-22 Richard Henderson <rth@redhat.com>
+
+ * cfgcleanup.c (insns_match_p): Do not do EQUIV substitution
+ after reload.
+
+2003-03-22 DJ Delorie <dj at redhat dot com>,
+ Bruce Korb <bkorb at gnu dot org>
+
+ * fixinc/inclhack.def (solaris_mutex_init_1): New; Fix
+ buggy Solaris 2.6 mutex/cond initializers.
+ (solaris_mutex_init): Rename to solaris_mutex_init_2.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/pthread.h: Update.
+ * fixinc/fixincl.c(initialize): be explicit about the default case
+ and indicate verbose level when being very, very verbose.
+ * fixinc/check.tpl(VERBOSE): provide a means for passing the value in
+
+2003-03-22 Andreas Jaeger <aj@suse.de>
+
+ * config/i386/i386.c (ix86_init_machine_status): Return value.
+
+2003-03-22 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (output_cbranch, output_bb, output_bvb): Output nop for
+ conditional branch to the following instruction. Use next_real_insn
+ instead of next_active_insn.
+ (output_dbra, output_movb, jump_in_call_delay): Use next_real_insn
+ instead of next_active_insn.
+
+2003-03-22 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("movti", "*movdi_31", "*movdf_31"): Use 'o'
+ instead of 'm' constraint in forced-split alternatives.
+ ("*adddi3_31", "*subdi3_31"): Likewise. Also, pass 0 instead of 1 as
+ VALIDATE_ADDRESS parameter to operand_subword.
+
+2003-03-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (notice_update_cc): Correctly handle
+ the case where the set destination is STRICT_LOW_PART.
+
+2003-03-22 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config/c4x/t-c4x (INSTALL_LIBGCC): Make gcc recognize a c33 as a
+ c30 instead of a c40 processor.
+
+2003-03-22 Alan Modra <amodra@bigpond.net.au>
+
+ * combine.c (simplify_comparison <AND>): Use gen_int_mode. Tidy.
+
+2003-03-21 Zack Weinberg <zack@codesourcery.com>
+
+ * c-common.c: Include intl.h.
+ (shadow_warning): Rewrite to allow better diagnostic translations.
+ * c-common.h: Update prototype of shadow_warning. Declare sw_kind enum.
+ * c-decl.c (warn_if_shadowing): Update calls to shadow_warning;
+ use it throughout.
+ * Makefile.in (c-common.o): Add intl.h.
+
+2003-03-21 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config.gcc: Remove 'float_format'.
+
+ * fixproto: Define NULL and size_t in generated stdlib.h and
+ unistd.h. Kill unused required_stdlib_h, required_unistd_h.
+ Rearrange file generation loop for readability. Generate time.h,
+ string.h if missing.
+ * tsystem.h: Include <string.h>, <time.h> unconditionally.
+ * config.gcc: Blow away POSIX defines.
+
+2003-03-22 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("call_value"): Fix trap check.
+
+2003-03-22 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.h (ASM_DECLARE_FUNCTION_NAME): Fix typo in
+ writing .interrupt command.
+ * config/m68hc11/m68hc11.md ("call"): Look at the symbol to see
+ if it's a far or near function.
+ ("call_value"): Likewise.
+ * config/m68hc11/m68hc11.c (m68hc11_attribute_table): Add far and
+ near attributes.
+ (m68hc11_handle_fntype_attribute): Accept attributes on methods.
+ (m68hc11_override_options): Ignore -mlong-calls for 68HC11.
+ (m68hc11_initial_elimination_offset): Set current_function_far
+ according to attributes.
+ (expand_prologue): Likewise.
+ (trap_handler_symbol): New global to keep track of trap handlers.
+ (m68hc11_encode_section_info): Mark symbol as far if needed; set
+ trap symbol.
+ (m68hc11_is_far_symbol): New function.
+ (m68hc11_is_trap_symbol): New function.
+ * config/m68hc11/m68hc11-protos.h (m68hc11_is_far_symbol): Declare.
+ (m68hc11_is_trap_symbol): Declare.
+
+2003-03-21 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_compute_frame_layout): Recompute fast prologues
+ only when amount of saved regs changed.
+ (ix86_init_machine_status): Initialize use_fast_prologue_epilgoue_nregs.
+ * i386.h (machine_function): New fields use_fast_prologue_epilgoue_nregs.
+
+2003-03-21 Jan Hubicka <jh@suse.cz>
+
+ PR inline-asm/7916
+ * function.c (instantiate_virtual_regs_lossage): New function.
+ (instantiate_virtual_regs_1): Use it.
+ (instantiate_virtual_regs): Do not continue in substition when insn has
+ been deleted.
+
+2003-03-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (make_field_assignment): Fix a warning.
+
+2003-03-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*insv_si_1_n_lshiftrt_16): New.
+
+2003-03-21 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.h (REG_ALLOC_ORDER): Increase
+ priority for R2 on Darwin.
+ (HARD_REGNO_MODE_OK): Don't accept R31 for DFmode.
+
+2003-03-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (make_field_assignment): Remove unnecessary AND
+ when storing into zero_extract.
+
+2003-03-21 Zack Weinberg <zack@codesourcery.com>
+
+ * aclocal.m4 (gcc_AC_EXAMINE_OBJECT, gcc_AC_C_FLOAT_FORMAT): Delete.
+ * configure.in: Don't call gcc_AC_C_FLOAT_FORMAT.
+ * defaults.h: Remove reference to HOST_FLOAT_WORDS_BIG_ENDIAN
+ in comment.
+
+2003-03-21 DJ Delorie <dj@redhat.com>
+
+ * optabs.c (init_integral_libfuncs): Make sure we init at least up
+ to "long long" size words.
+
+2003-03-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h: Do not include fixdfdi.h on s390x.
+ (TARGET_64BIT): Define as compile-time constant when IN_LIBGCC2.
+ (MIN_UNITS_PER_WORD): Do not define when IN_LIBGCC2.
+
+2003-03-21 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR doc-bug/9813
+ * doc/extend.texi: Move misplaced paragraph about underscores in
+ variables in macros.
+
+2003-03-21 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Richard Henderson <rth@redhat.com>
+
+ PR optimization/8366
+ * config/sparc/sparc.h: (SYMBOLIC_CONST): New macro.
+ (GO_IF_LEGITIMATE_ADDRESS): Use it. Reject the form
+ PIC+SYMBOLIC_CONST in other modes than Pmode.
+ (GO_IF_MODE_DEPENDENT_ADDRESS): Use it. Mark
+ the form PIC+SYMBOLIC_CONST as mode dependent.
+
+2003-03-21 DJ Delorie <dj@redhat.com>
+
+ * config/stormy16/stormy16.c (xstormy16_expand_arith): Make
+ sure we always emit at least one insn.
+
+2003-03-21 Christopher Faylor <cgf@redhat.com>
+
+ * config.gcc (i[34567]86-*-cygwin*): Use new common makefile
+ stub t-cygming. Use common target header cygming.h. Add extra
+ c_target_obj and cxx_target_obj file. Default cygwin to posix
+ threading. Enforce i386 as float format.
+ (i[34567]86-*-mingw*): Use new common makefile stub t-cygming.
+ Remove cygwin.h as target header. Use common target header
+ cygming.h Enforce i386 as float format. Correct typo.
+ * config/i386/cygming.h: New file, containing definitions
+ common to mingw32 and cygwin.
+ * config/i386/cygwin.h: Remove definitions common to cygwin and
+ mingw. Simplify special spec logic. Define "wrappers" around
+ certain include path defines to accommodate -mno-cygwin.
+ Remove some #if 0'ed code.
+ (STANDARD_INCLUDE_DIR) Always define when not cross-compiling.
+ (LINK_SPEC): Don't use cyg search prefix when -mno-cygwin.
+ (GCC_DRIVER_HOST_INITIALIZATION): Define as call to mingw_scan.
+ * config/i386/mingw32.h: Remove definitions common to cygwin and
+ mingw.
+ (EXTRA_OS_CPP_BUILTINS): Adjust.
+ (TARGET_VERSION): Define.
+ * config/i386/crtdll.h (EXTRA_OS_CPP_BUILTINS): Override
+ mingw32.h definitions.
+ (LIBGCC_SPEC): Add libmingwex.a as in mingw32.h.
+ * config/i386/t-cygwin (EXTRA_GCC_OBJS): Define as cygwin1.o.
+ Add compilation rules for cygwin1.o cygwin2.o.
+ * config/i386/cygwin1.c: New file.
+ * config/i386/cygwin2.c: New file.
+ * config/i386/t-cygming: New makefile stub.
+
+2003-03-20 Richard Henderson <rth@redhat.com>
+
+ * fold-const.c (extract_muldiv_1): Revert changing order of
+ operands in case MULT_EXPR of 2003-02-16 patch.
+
+2003-03-20 Daniel Berlin <dberlin@dberlin.org>
+ Merge changes from new-regalloc-branch
+
+ From Michael Matz <matz@suse.de>
+ * df.c (df_ref_record_1): Move init of loc to safe point.
+ Only recurse on interesting things in parallels.
+ Handle CLASS_CANNOT_CHANGE_MODE smarter.
+ (df_uses_record): Ditto.
+
+ * df.h (DF_REF_MEM_OK): New enum member, used to mark ref's which
+ it's already okay to use memory operands in (IE doesn't require
+ adding another insn or anything).
+
+2003-03-20 Richard Henderson <rth@redhat.com>
+
+ PR middle-end/6348
+ * explow.c (allocate_dynamic_stack_space): Handle STACK_SIZE_MODE
+ different from word_mode.
+
+2003-03-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*insv_si_1_n_lshiftrt): Restrict the
+ source operand to those that can be extracted with bld.
+
+2003-03-20 Richard Earnshaw <rearnsha@arm.com>
+
+ PR 10066
+ * arm.md (UNSPEC_PIC_BASE): New constant.
+ (pic_add_dot_plus_four): Wrap with unspec.
+ (pic_add_dot_plus_eight): Likewise.
+
+2003-03-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*insv_si_1_n): New.
+ (*insv_si_1_n_lshiftrt): Likewise.
+
+2003-03-20 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold_mathfn_compare): New function to simplify
+ comparisons against built-in math functions. Fold comparisons
+ of sqrt against constants.
+ (fold): Call fold_mathfn_compare when appropriate.
+
+2003-03-20 Richard Earnshaw <rearnsha@arm.com>
+
+ * ifcvt.c (find_if_case_1): If we add a new bb, update the dominance
+ information.
+
+2003-03-20 Per Bothner <pbothner@apple.com>
+
+ Various cleanups to help compile server.
+
+ * cppinit.c (cpp_create_reader): Take extra hash_table* argument,
+ and pass that to _cpp_init_hashtable.
+ (cpp_read_main_file): Drop hash_table* argument; don't call
+ _cpp_init_hashtable.
+ * cpplib.h: Update declarations to match.
+ * c-opts.c (c_common_init_options): Pass ident_hash to
+ cpp_create_reader.
+ (c_common_post_options): Don't pass ident_hash to cpp_read_main_file.
+ * fix-header.c (read_scan_file): Likewise pass NULL table to
+ cpp_create_reader rather than cpp_read_main_file.
+
+ * cppfiles.c (cpp_rename_file): Generalized and renamed
+ to cpp_change_file.
+ * cpplib.h: Update declaration to match.
+ * c-opts.c (push_command_line_line, finish_options): Change
+ cpp_rename_file calls to cpp_change_file.
+
+ * line-map.c (add_line_map): Allow leaving the outermost file.
+ Allowing entering an outermost-file after the initial time.
+
+ * toplev.c (pop_srcloc): Allow popping from initial file.
+
+2003-03-20 Kazu Hirata <kazu at cs dot umass dot edu>
+
+ * fold-const.c (fold): Fold A - (A & B) into ~B & A.
+
+2003-03-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): New.
+
+2003-03-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*addsi3_and_r_1): New.
+ (*addsi3_and_not_r_1): Likewise.
+
+2003-03-19 Loren James Rittle <ljrittle@acm.org>
+
+ * Makefile.in (STRICT2_WARN): Add @WERROR@.
+ (GCC_WARN_CFLAGS): Remove $(WERROR).
+ (fixinc.sh-warn): New.
+ * ada/Make-lang.in (ada-warn): Add $(WERROR).
+ * cp/Make-lang.in (cp-warn): Add $(WERROR).
+ * f/Make-lang.in (f-warn): Add $(WERROR).
+ * java/Make-lang.in (java-warn): Add $(WERROR).
+ * treelang/Make-lang.in (treelang-warn): Add $(WERROR).
+
+2003-03-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * c-common.h (c_dump_tree), c-dump.c (c_dump_tree),
+ langhooks-def.h (lhd_tree_dump_dump_tree),
+ langhooks.c (lhd_tree_dump_dump_tree), langhooks.h (*dump_tree):
+ Change return type from 'int' to 'bool'. Replace 0 and 1 with
+ true and false in return statements.
+
+2003-03-19 Kevin Buettner <kevinb@redhat.com>
+
+ * dwarf2out.c (DWARF_INITIAL_LENGTH_SIZE): Define.
+ (DWARF_COMPILE_UNIT_HEADER_SIZE): Take into account
+ DWARF_INITIAL_LENGTH_SIZE.
+ (output_compilation_unit_header, output_pubnames, output_aranges)
+ (output_line_info): Output 0xffffffff escape value for 64-bit
+ DWARF extension.
+ * config/mips/iris6.h (DWARF_INITIAL_LENGTH_SIZE): Define.
+
+2003-03-19 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_preferred_reload_class): Do not
+ force constants to the pool unless necessary.
+ (s390_decompose_address): Prefer to use pointer as base,
+ not index register.
+ * config/s390/s390.md ("*tsthiCCT_only"): Remove '?' from
+ Q alternative.
+ ("*movdi_64", "*movsi", "movhi", "movqi_64", "movqi",
+ "*movdf_64", "*movsf"): Add '?' to Q->Q alternatives.
+ ("*extractqi", "*extracthi", "*zero_extendhisi2_31",
+ "*zero_extendqisi2_31", "*zero_extendqihi2_31",
+ "*adddi3_31", "*subdi3_31"): Do not set "type" attribute.
+
+2003-03-19 Jan Hubicka <jh@suse.cz>
+
+ * i386.h (machine_function): New fields use_fast_prologue_epilogue.
+ * i386.c (use_fast_prologue_epilogue): Remove.
+ (ix86_frame): New field save_regs-using_mov;
+ (ix86_compute_frame_layout): Decide on fast prologues;
+ allocate saved registers in red zone.
+ (ix86_expand_epilogue, ix86_expand_prolgoues): Obey new parameters.
+
+2003-03-19 Nick Clifton <nickc@redhat.com>
+
+ * config/mcore/mcore.h (CPP_SPEC): Remove trailing semi-colon.
+
+2003-03-18 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR 10062
+ * config/pa/pa-hpux.h (TARGET_HPUX_UNWIND_LIBRARY): Redefine.
+ * pa-protos.h (output_lbranch): New prototype.
+ * pa.c (compute_frame_size): Change size of the frame marker on the
+ 64-bit ports to 48 bytes.
+ (pa_output_function_prologue): Document why SAVE_SP is set.
+ (hppa_expand_prologue): Save previous stack pointer into frame marker
+ on targets which use the hpux unwind library.
+ (output_cbranch): Use output_lbranch.
+ (output_lbranch): New function to output long unconditional branches.
+ * pa.h (TARGET_HPUX_UNWIND_LIBRARY): Define.
+ (STACK_POINTER_OFFSET): Update offset for 48-byte frame marker on
+ 64-bit ports.
+ * pa.md (jump): Use output_lbranch.
+ (allocate_stack): New expander for dynamic stack allocation.
+
+2003-03-19 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_stack_info): Only require a frame
+ when debugging on XCOFF targets. Delete "abi" temp.
+
+ PR target/10073
+ * combine.c (force_to_mode <NOT>): Use gen_int_mode.
+
+2003-03-18 Jakub Jelinek <jakub@redhat.com>
+
+ * config/s390/s390.c (s390_output_dwarf_dtprel): New.
+ * config/s390/s390-protos.h (s390_output_dwarf_dtprel): New proto.
+ * config/s390/s390.h (ASM_OUTPUT_DWARF_DTPREL): Define.
+
+ * config/ia64/ia64.c (ia64_output_dwarf_dtprel): New.
+ * config/ia64/ia64-protos.h (ia64_output_dwarf_dtprel): New proto.
+ * config/ia64/ia64.h (ASM_OUTPUT_DWARF_DTPREL): Define.
+
+2003-03-18 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_prologue): Don't clone
+ the result of machopic_function_base_name.
+ * config/darwin.c (machopic_function_base_name): Use a gc-allocated
+ string rather than a static array.
+
+ * Makefile.in (emit-rtl.o): Add gt-emit-rtl.h to dependencies.
+
+ * gengtype.c: Include rtl.h.
+ (enum rtx_code): Don't define.
+ (rtx_format): Make declaration match rtl.h.
+ (rtx_next_new): Rename from rtx_next to avoid conflict. Change all
+ users.
+ (adjust_field_rtx_def): Describe strings in NOTE_LINE_NUMBER notes.
+ * Makefile.in (gengtype.o): Update dependencies.
+
+2003-03-18 Andreas Schwab <schwab@suse.de>
+
+ * config/m68k/m68k.md (iordi3): Fix setting low half to -1. From
+ martin@blom.org.
+
+2003-03-18 Geoffrey Keating <geoffk@apple.com>
+
+ * function.c (next_block_index): Mark with GTY.
+
+ * config/rs6000/rs6000.md (macho_correct_pic): Correct pattern.
+
+2003-03-18 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.md (UNSPECV_SETJMP_RECEIVER): New.
+ (builtin_setjmp_receiver): Delay call to ia64_reload_gp
+ until after reload.
+
+2003-03-18 Richard Henderson <rth@redhat.com>
+
+ * builtins.c (expand_builtin_unop): New target_mode operand;
+ use it to convert the result to the correct mode.
+ (expand_builtin): Update all callers.
+
+2003-03-18 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.md ("movti", "movhi", "movqi"): Add "type" attribute.
+
+2003-03-18 Jan Hubicka <jh@suse.cz>
+
+ * i386.md: Fix previous commit that mistakely applied the patch
+ twice.
+
+ * alias.c (rtx_equal_for_memref_p): Assume that X and Y has been
+ canonicalized.
+ (memrefs_conflict_p): Likewise.
+ (addr_side_effect_eval): Canonicalize the constructed address.
+
+2003-03-18 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (cvtts?2si peep2): New.
+
+2003-03-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*iorsi3_two_qi_zext): New.
+
+2003-03-18 Andreas Schwab <schwab@suse.de>
+
+ * dwarf2out.c (output_file_names): Cast size_t to unsigned long
+ for format.
+
+2003-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/10091
+ * expr.c (expand_expr) [ADDR_EXPR]: Disallow taking the address of
+ an unaligned member of TREE_ADDRESSABLE type.
+
+2003-03-18 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/linux64.h (MASK_PROFILE_KERNEL): Define.
+ (TARGET_PROFILE_KERNEL): Define.
+ (SUBTARGET_SWITCHES): Handle -mprofile-kernel.
+ (PROFILE_BEFORE_PROLOGUE): Don't define.
+ (PROFILE_KERNEL): Remove hacks.
+ * config/rs6000/rs6000.c (TARGET_PROFILE_KERNEL): Define default.
+ (rs6000_stack_info): No need to save lr if just for profiling when
+ TARGET_PROFILE_KERNEL.
+ (output_profile_hook): Output nothing when TARGET_PROFILE_KERNEL.
+ (output_function_profiler): Localize label generation. Emit code
+ for kernel profiling.
+
+2003-03-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add a prototype for
+ byte_accesses_mergeable_p.
+ * config/h8300/h8300.c (byte_accesses_mergeable_p): New.
+ * config/h8300/h8300.md (*iorhi3_two_qi_mem): Likewise.
+ (a splitter): Likewise.
+ (*iorsi3_ashift_16_ashift_24): Likewise.
+ (*iorsi3_ashift_16_ashift_24_mem): Likewise.
+
+2003-03-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * dwarf2asm.h: Delete obsolete comment.
+ (dw2_asm_output_data, dw2_asm_output_delta, dw2_asm_output_offset,
+ dw2_asm_output_pcrel, dw2_asm_output_addr,
+ dw2_asm_output_addr_rtx, dw2_asm_output_encoded_addr_rtx,
+ dw2_asm_output_nstring, dw2_asm_output_data_uleb128,
+ dw2_asm_output_data_sleb128, dw2_asm_output_delta_uleb128,
+ dw2_asm_output_delta_sleb128): Add ATTRIBUTE_NULL_PRINTF.
+
+2003-03-17 Zack Weinberg <zack@codesourcery.com>
+
+ * c-tree.h (struct lang_identifier): Remove error_locus field.
+ (IDENTIFIER_ERROR_LOCUS): Kill.
+ (record_function_scope_shadow): New prototype.
+ * c-typeck.c (build_external_ref): Don't complain if
+ decl is error_mark_node. When not at file scope, bind the
+ decl's local value to error_mark_node to suppress further
+ warnings, instead of setting IDENTIFIER_ERROR_LOCUS.
+
+ * c-decl.c (get_function_binding_level): New static function.
+ (record_function_scope_shadow): New exported function.
+ (c_make_fname_decl): Use get_function_binding_level.
+
+2003-03-17 Steve Ellcey <sje@cup.hp.com>
+
+ * stmt.c (tail_recursion_args): Call promote_mode to set
+ unsignedp flag correctly before calling convert_move.
+
+2003-03-17 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * loop-unroll.c (decide_peel_completely,
+ decide_unroll_constant_iterations, decide_unroll_stupid,
+ decide_unroll_runtime_iterations, decide_peel_simple): Set
+ loop->has_desc.
+
+2003-03-17 Jan Hubicka <jh@suse.cz>
+
+ * ggc-common.c (ggc_mark_roots): Use htab_traverse_noresize.
+
+2003-03-17 Olivier Hainque <hainque@act-europe.fr>
+
+ * function.c (assign_parms): For a struct value address passed as
+ first argument, delay the function's result RTL setup code until
+ after the emission of parameter conversions.
+
+2003-03-17 Dave Love <fx@gnu.org>
+ Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/alpha/osf.h (TARGET_OS_CPP_BUILTINS): Define __digital__,
+ __arch64__ to match Compaq cc.
+
+2003-03-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c: Default TARGET_EBCDIC to 0 if not defined.
+ (c_common_init): Set EBCDIC in cpp options.
+ * cpplex.c (maybe_read_ucs, cpp_parse_escape): Use EBCDIC option,
+ not conditional compilation.
+ * cpplib.h (struct cpp_options): New entry EBCDIC.
+
+2003-03-17 Neil Booth <neil@daikokuya.co.uk>
+
+ * fix-header.c (read_scan_file): Need to malloc arguments to add_path.
+
+2003-03-17 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * function.c (thread_prologue_and_epilogue_insns): Set delete_unused
+ argument to 0 for redirect_jump.
+
+2003-03-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8805
+ * except.c (eh_region_u_cleanup): Add prev_try.
+ (expand_eh_region_end_cleanup): Set it.
+ (reachable_handlers): Use it to skip over cleanup blocks.
+
+2003-03-17 Andreas Jaeger <aj@suse.de>
+
+ * Makefile.in (TAGS): Remove obsolete handling of =*.[chy].
+
+2003-03-17 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/linux64.h (TARGET_64BIT): Redefine.
+ (TARGET_RELOCATABLE, TARGET_EABI, TARGET_PROTOTYPE): Likewise.
+ (SUBTARGET_SWITCHES, SUBTARGET_OPTIONS): Likewise.
+ (SUBTARGET_OVERRIDE_OPTIONS, CPP_SYSV_SPEC): Likewise.
+
+2003-03-16 Richard Henderson <rth@redhat.com>
+
+ * simplify-rtx (simplify_binary_operation): Don't abort for
+ SS_PLUS, US_PLUS, SS_MINUS, US_MINUS.
+
+2003-03-16 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.md (movstrictqi, movstrictqi_1): Check
+ optimize_size as well.
+
+2003-03-16 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (print_operand): Handle 'b' modifier
+ for D register to specify the low part of it, aka B.
+ (m68hc11_gen_movhi): Use REG_WAS_0 note and increment or decrement
+ the register if we are loading 1 or -1 to it; avoid using temp
+ register when moving X/Y to Y/X.
+ (m68hc11_gen_movqi): Likewise.
+ (m68hc11_check_z_replacement): Fix last insn setting for compare case.
+
+2003-03-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR optimization/9016
+ * config/i386/i386.c (ix86_expand_move): Force more CONST_DOUBLEs
+ into the constant pool.
+
+2003-03-16 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ PR target/9164
+ * tree.c (get_narrower): For extensions with unchanged bit number,
+ return the unsignedness of the outer mode.
+
+2003-03-16 Roger Sayle <roger@eyesopen.com>
+
+ * c-typeck.c (build_component_ref): Turn "for" into "do .. while"
+ to avoid "may be used uninitialized" warning on ia64-hpux.
+ * config/ia64/ia64-c.c: Include "tm_p.h" for function prototypes.
+
+2003-03-16 Andreas Jaeger <aj@suse.de>
+
+ * configure.in: Improve check for memcheck.h.
+ * configure: Regenerated.
+
+2003-03-16 Neil Booth <neil@daikokuya.co.uk>
+
+ * doc/cppopts.texi: Remove documentation of -A-.
+
+2003-03-15 Zack Weinberg <zack@codesourcery.com>
+
+ * doc/libgcc.texi: Remove @tie.
+
+2003-03-15 Josef Zlomek <zlomekj@suse.cz>
+
+ * rtl.h (subrtx_p): Renamed to rtx_referenced_p.
+ (rtx_pair): Added new element update_label_nuses, renamed to
+ replace_label_data.
+ * cfgcleanup.c (outgoing_edges_match, try_crossjump_to_edge): Use
+ replace_label_data instead of rtx_pair.
+ * loop.c (load_mems): Likewise.
+ * rtlanal.c (replace_label): Replace label in pool constants and in
+ INSN_LIST (in REG_LABEL note).
+ (subrtx_p): Renamed to rtx_referenced_p.
+ (subrtx_p_1): Renamed to rtx_referenced_p_1, compare the interior of
+ LABEL_REF with CODE_LABEL, traverse constants from pool.
+
+2003-03-15 Aldy Hernandez <aldyh@redhat.com>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * Makefile.in (TEXI_GCCINT_FILES): Add libgcc.texi.
+ * doc/libgcc.texi: New file.
+ * doc/interface.texi: Delete paragraph about libgcc interface.
+ * doc/gccint.texi: Add libgcc menu entry and @include libgcc.texi.
+
+2003-03-15 Jason Merrill <jason@redhat.com>
+
+ PR debug/9039
+ * dwarf2out.c (gen_decl_die): Ignore frontend tree codes.
+
+ PR debug/6387
+ * dwarf2out.c (dwarf2out_decl): If we're at -g1, just stick nested
+ function DIEs at toplevel.
+ (decls_for_scope): At -g1, don't descend into subblocks.
+
+2003-03-15 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * varasm.c (struct rtx_const): Change type of un.addr member
+ to struct holding an additional 'symbol' member.
+ (decode_rtx_const): Re-enable optimization to count SYMBOL_REFs
+ with equal string addresses as equal.
+ (simplify_subtraction): Adapt to struct rtx_const change.
+
+2003-03-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * fix-header.c (read_scan_file): Read main file before handling -D.
+
+2003-03-15 Roger Sayle <roger@eyesopen.com>
+
+ * c-cppbuiltin.c (builtin_define_with_value_n): Fix whitespace.
+ * c-typeck.c (c_tree_expr_nonnegative_p): Likewise.
+ * cfgbuild.c (find_many_sub_basic_blocks): Likewise.
+ (find_sub_basic_blocks): Likewise.
+ * cgraphunit.c (cgraph_expand_functions): Likewise.
+ * dwarf2out.c (prune_unused_types): Likewise.
+ * expr.c (store_field): Likewise.
+ * genextract.c (print_path): Likewise.
+ * haifa-sched.c (schedule_insn): Likewise.
+ * lcm.c (compute_antinout_edge): Likewise.
+ * loop-unroll.c (decide_peel_once_rolling): Likewise.
+ * ra-colorize.c (ra_colorize_free_all): Likewise.
+ * ra-debug.c (dump_igraph): Likewise.
+ (debug_hard_reg_set): Likewise.
+ * reg-stack.c (reg_to_stack): Likewise.
+ * rtlanal.c (refers_to_regno_p): Likewise.
+ * tracer.c (layout_superblocks): Likewise.
+
+2003-03-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * fix-header.c (read_scan_file): Fix thinko.
+
+2003-03-15 Glen Nakamura <glen@imodulo.com>
+
+ * reload1.c (choose_reload_regs): Use && instead of ||
+ with REG_CANNOT_CHANGE_MODE_P condition.
+
+2003-03-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Update.
+ * c-common.h (cb_register_builtins): Rename c_cpp_builtins.
+ * c-lex.c (init_c_lex): Register builtins hook is dead.
+ * c-opts.c (COMMAND_LINE_OPTIONS, missing_arg): Handle -A, -D and -U.
+ (c_common_decode_option): Don't call cpp_handle_option.
+ Handle -A, -D and -U.
+ (handle_deferred_opts): Simplify.
+ (finish_options): Define builtins and command line macros.
+ * c-ppoutput.c (init_pp_output): Register builtins hook is dead.
+ * cppinit.c: Don't include intl.h.
+ (init_builtins): Rename cpp_init_builtins. No hook to call.
+ (init_library): Don't need to sort options.
+ (cpp_create_reader): Don't set pending.
+ (cpp_destroy): Don't free pending.
+ (struct pending_option, cl_directive_handler, struct cpp_pending,
+ APPEND, free_chain, new_pending_directive, parse_option, opt_comp,
+ cpp_finish_options, COMMAND_LINE_OPTIONS, DEF_OPT, struct cl_option,
+ cl_options, cpp_handle_option): Remove.
+ * cpplib.h (struct cpp_pending, register_builtins, cpp_handle_option,
+ cpp_finish_options): Remove.
+ (cpp_init_builtins): New.
+ * fix-header.c (read_scan_file): Update to handle -D. Fix
+ handling of -I. Replace call to cpp_finish_options.
+
+2003-03-15 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ PR optimization/9387
+ * function.c (thread_prologue_and_epilogue_insns): Use redirect_jump
+ for conditional returns.
+
+2003-03-14 Jason Merrill <jason@redhat.com>
+
+ PR optimization/6871
+ * varasm.c (assemble_variable): Leave constant zeroes in .rodata.
+
+2003-03-14 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-opts.c (finish_options): New.
+ (COMMAND_LINE_OPTIONS, c_common_decode_option): Add -imacros.
+ (missing_arg): Handle OPT_include and OPT_imacros.
+ (c_common_init, c_common_parse_file): Use finish_options.
+ (handle_deferred_opts): Update.
+ * cppinit.c (struct cpp_pending): Remove imacros_head and imacros_tail.
+ (cpp_finish_options): Don't handle -imacros here.
+ (no_fil): Remove.
+ (COMMAND_LINE_OPTIONS, cpp_handle_option): Don't handle -imacros.
+
+2003-03-14 Jakub Jelinek <jakub@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_load_toc_table): Don't call
+ rs6000_maybe_dead if !fromprolog.
+
+2003-03-14 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Update.
+ * c-common.h (fe_file_change, pp_file_change): New.
+ * c-lex.c (init_c_lex): Don't set cb_file_change.
+ (c_common_parse_file): Move to c-opts.c.
+ (cb_file_change): Rename fe_file_change.
+ * c-opts.c: Include debug.h.
+ (warn_unused_macros, include_cursor): New.
+ (push_command_line_include, cb_file_change): New.
+ (COMMAND_LINE_OPTIONS): Handle -include.
+ (c_common_decode_option): Use local warn_unused_macros.
+ Handle OPT_include.
+ (c_common_post_options): Set file change callback.
+ (handle_deferred_opts): Skip -include. Don't free the array.
+ (c_common_init): Call cpp_finish_options here, and push an
+ initial -include file.
+ * c-ppoutput.c (cb_file_change): Rename pp_file_change.
+ (preprocess_file): Don't call cpp_finish_options.
+ (init_pp_output): Don't set the file change callback.
+ (pp_file_change): Return if no line commands or no output.
+ * cpphash.h (next_include_file, first_unused_line): Remove.
+ * cppinit.c (include_head, include_tail): Remove.
+ (cpp_destroy): Don't free -include chain.
+ (cpp_finish_options): Don't handle -include, or worry about
+ -Wunused-macros.
+ (_cpp_maybe_push_include_file): Remove.
+ (COMMAND_LINE_OPTIONS, cpp_handle_option): Don't handle -include.
+ * cpplib.c (_cpp_pop_buffer): Don't handle -include.
+ * cppmacro.c (_cpp_warn_if_unused_macro, _cpp_create_definition):
+ Used flag is set based upon the state of the warn_unused_macros
+ flag, and so use of first_unused_line is unnecessary.
+
+2003-03-13 Jan Hubicka <jh@suse.cz>
+
+ * cselib.c (clear_table): Do not take argument; always clear just
+ used slots.
+ (cselib_process_insn): Update call of clear_table
+ (cselib_init): Do not call clear_table.
+ (cselib_finish): Clear table.
+
+ * cse.c (count_reg_usage): Do not check side_effects_p.
+ * rtlanal.c (set_noop_p): Check side_effects_p only when set looks
+ like noop.
+ (find_reg_equal_equiv_note): Do not use find_reg_note.
+
+2003-03-14 Richard Henderson <rth@redhat.com>
+
+ PR target/9700
+ * config/alpha/alpha.c (alpha_va_start): Account for
+ current_function_pretend_args_size in the AP offset.
+
+ * config/alpha/alpha.h (SETUP_INCOMING_VARARGS): Move out of line.
+ (INITIAL_ELIMINATION_OFFSET): Move out of line.
+ * config/alpha/alpha.c (alpha_setup_incoming_varargs): New.
+ (alpha_initial_elimination_offset) New.
+ * config/alpha/alpha-protos.h: Update.
+
+2003-03-14 Jakub Jelinek <jakub@redhat.com>
+
+ * stmt.c (expand_start_case): Call emit_queue ().
+
+2003-03-14 Chris Demetriou <cgd@broadcom.com>
+ Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mips/mips.h (FUNCTION_PROFILER): _mcount() doesn't pop 2
+ words in new abis.
+
+2003-03-14 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/8396
+ * tree-inline.c (initialize_inlined_parameters): Make sure the value
+ of read-only constant arguments is passed with the right type.
+
+2003-03-14 Steven Bosscher <steven@gcc.gnu.org>
+
+ * doc/extend.texi (Function Names): Make the example compilable.
+
+2003-03-13 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (processor_target_table): Really allow
+ GP optional instructions on Power4.
+
+2003-03-13 Roger Sayle <roger@eyesopen.com>
+
+ * calls.c (flags_from_decl_or_type): Factor and remove redundant
+ conditional tests.
+
+2003-03-13 Mike Stump <mrs@apple.com>
+
+ * ggc-page.c (struct page_entry): Remove varray.h header.
+ Add index_by_depth field.
+ Remove save_in_use_p field.
+ (struct globals): Add depth_in_use, depth_max, by_depth_in_use,
+ by_depth_max, by_depth, and save_in_use fields.
+ (INITIAL_PTE_COUNT): Add.
+ (save_in_use_p_i): Add.
+ (save_in_use_p): Add.
+ (adjust_depth): Add.
+ (move_ptes_to_front): Add.
+ (push_depth): Add.
+ (push_by_depth): Add.
+ (prefetch): Add.
+ (free_page): Add support for and use faster data structures.
+ (ggc_alloc): Likewise.
+ (init_ggc): Likewise.
+ (ggc_recalculate_in_use_p): Likewise.
+ (ggc_pop_context): Likewise.
+ (clear_marks): Likewise.
+ (ggc_pch_read): Likewise.
+ * Makefile.in (ggc-page.o): Remove varray.h.
+
+2003-03-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * ChangeLog: Rotated last year's entries to...
+ * ChangeLog.8: New.
+
+ * config/ia64/fde-glibc.c, config/ia64/freebsd.h,
+ config/ia64/hpux.h, config/ia64/hpux_longdouble.h,
+ config/ia64/ia64-c.c, config/ia64/ia64-modes.def,
+ config/ia64/ia64-protos.h, config/ia64/ia64.c,
+ config/ia64/ia64.h, config/ia64/ia64.md,
+ config/ia64/itanium1.md, config/ia64/itanium2.md,
+ config/ia64/quadlib.c, config/ia64/unwind-ia64.c,
+ config/ia64/unwind-ia64.h: It's GCC, not GNU CC.
+
+2003-03-13 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_dwarf_register_span):
+ Differentiate endianness.
+ (s6000_override_options): Use cpu type instead of TARGET_SPE.
+
+2003-03-13 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.c (print_multi_reg): Do not generate a type 2
+ LDM instructions with writeback enabled.
+ (output_return_instruction): Likewise.
+
+ * config/arm/pe.h (FIXED_REGISTERS): Remove definition.
+ (CALL_USED_REGISTERS): Remove definition.
+ (SUBTARGET_CONDITIONAL_REGISTER_USAGE): Define.
+
+2003-03-13 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.c (rs6000_flag_pic): Delete.
+ (rs6000_xcoff_encode_section_info): #ifdef TARGET_XCOFF.
+ (rs6000_binds_local_p, TARGET_BINDS_LOCAL_P): #if TARGET_MACHO.
+ (rs6000_override_options): Don't clear flag_pic for ABI_AIX.
+ (rs6000_legitimize_address): Formatting.
+ (rs6000_emit_move): Likewise.
+ (rs6000_return_addr): Test ABI_AIX as well as flag_pic.
+ (rs6000_emit_prologue <save_LR_around_toc_setup>): Likewise.
+ (rs6000_elf_select_section): Comment reason for shlib being
+ set for ABI_AIX.
+ (rs6000_elf_unique_section): Likewise.
+ (rs6000_elf_encode_section_info): Test !TARGET_AIX as well as ABI_AIX.
+ * config/rs6000/rs6000.h (LEGITIMATE_LO_SUM_ADDRESS_P): Test ABI_AIX
+ as well as flag_pic.
+ * config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Likewise.
+ (MINIMAL_TOC_SECTION_ASM_OP): Likewise.
+ * config/rs6000/linux64.h (TARGET_ENCODE_SECTION_INFO): Don't define.
+
+2003-03-13 Richard Henderson <rth@redhat.com>
+
+ * emit-rtl.c (try_split): Handle 1-1 splits of call insns properly.
+
+ * config/ia64/ia64.c (TARGET_FUNCTION_OK_FOR_SIBCALL): New.
+ (ia64_gp_save_reg): Remove.
+ (struct ia64_frame_info): Move to the beginning of the file;
+ add reg_save_gp.
+ (ia64_expand_call): Rearrange for new call patterns.
+ (ia64_reload_gp): New.
+ (ia64_split_call): New.
+ (ia64_compute_frame_size): Allocate reg_save_gp.
+ (ia64_expand_prologue): Save reg_save_gp.
+ (ia64_expand_epilogue): Don't restore gp.
+ (ia64_hard_regno_rename_ok): Remove R4 hack.
+ (ia64_function_ok_for_sibcall): New.
+ (ia64_output_mi_thunk): Set reload_completed, no_new_pseudos;
+ call try_split on sibcall pattern.
+ * config/ia64/ia64-protos.h: Update.
+ * config/ia64/ia64.md (call_nogp, call_value_nogp, sibcall_nogp):
+ Rename from nopic versions. Confiscate 2nd argument to call as
+ a marker.
+ (call_pic, call_value_pic, sibcall_pic): Remove.
+ (call_gp, call_value_gp, sibcall_gp): New.
+ (builtin_setjmp_setup): Remove.
+ (builtin_setjmp_receiver): Call ia64_reload_gp.
+
+2003-03-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config/dsp16xx/dsp16xx-protos.h, config/dsp16xx/dsp16xx.c,
+ config/dsp16xx/dsp16xx.h, config/dsp16xx/dsp16xx.md: Replace
+ "GNU CC" with "GCC".
+
+ * config/c4x/c4x-c.c, config/c4x/c4x-modes.def,
+ config/c4x/c4x-protos.h, config/c4x/c4x.c, config/c4x/c4x.h,
+ config/c4x/c4x.md, config/c4x/libgcc.S, config/c4x/rtems.h:
+ GCC, not GNU CC.
+
+ * genattrtab.h, hosthooks-def.h, hosthooks.h, langhooks-def.h,
+ langhooks.h, tree-inline.h: Replace "GNU CC" with "GCC".
+
+ * c-pch.c, dummy-conditions.c, genautomata.c, genconditions.c,
+ langhooks.c, tree-inline.c, unwind-dw2-fde-darwin.c,
+ unwind-dw2-fde-glibc.c, unwind-libunwind.c, vmsdbgout.c: Replace
+ "GNU CC" with "GCC".
+
+ * config/v850/lib1funcs.asm, config/v850/rtems.h,
+ config/v850/v850-c.c, config/v850/v850-protos.h,
+ config/v850/v850.c, config/v850/v850.h, config/v850/v850.md:
+ GCC, not GNU CC.
+
+ * config/vax/bsd.h, config/vax/elf.h, config/vax/netbsd-elf.h,
+ config/vax/netbsd.h, config/vax/openbsd.h, config/vax/openbsd1.h,
+ config/vax/ultrix.h, config/vax/vax-protos.h, config/vax/vax.c,
+ config/vax/vax.h, config/vax/vax.md, config/vax/vaxv.h: GCC, not
+ GNU CC.
+
+2003-03-12 Benjamin Kosnik <bkoz@redhat.com>
+
+ * cpppch.c (cpp_valid_state): Use DL_WARNING_SYSHDR, not DL_WARNING.
+
+2003-03-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * fixinc/fixinc.interix: Remove dead code (most of it).
+ * fixinc/fixinc.dgux: Remove.
+
+ * ginclude/float.h, ginclude/iso646.h, ginclude/stdarg.h,
+ ginclude/stdbool.h, ginclude/stddef.h: GCC, not GNU CC.
+
+2003-03-12 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (pa_init_builtins): Fix warning.
+
+2003-03-12 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/ia64.h (ASM_OUTPUT_XDATA_CHAR): Remove.
+ (ASM_OUTPUT_XDATA_SHORT): Remove.
+ (ASM_OUTPUT_XDATA_INT): Remove.
+ (ASM_OUTPUT_XDATA_DOUBLE_INT): Remove.
+ (ASM_OUTPUT_ADDR_DIFF_ELT): Handled 32 bit address diffs.
+ (ASM_PREFERRED_EH_DATA_FORMAT): Handle 32 bit EH pointers.
+ (CASE_VECTOR_MODE): Handle 32 bit pointers in case statement.
+
+2003-03-12 Andrew Lewycky <andrew@mxc.ca>
+
+ PR c++/7050
+ * expr.c (store_expr): Don't attempt to store void-typed trees,
+ just evaluate them for side effects.
+
+2003-03-12 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppfiles.c (cpp_rename_file, cpp_push_include): New.
+ * cppinit.c (push_include): Move with changes to cppfiles.c.
+ (cpp_read_main_file): Mark named operators here...
+ (cpp_finish_options): ...not here. Update.
+ (_cpp_maybe_push_include_file): Update.
+ * cpplib.h (cpp_push_include, cpp_rename_file): New.
+
+2003-03-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * aclocal.m4: Introduce gcc_GAS_VERSION_GTE_IFELSE,
+ _gcc_COMPUTE_GAS_VERSION.
+ * configure.in: Use them.
+ * configure: Regenerate.
+
+2003-03-12 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.md (adddi3): Don't clobber source operand used
+ to detect carry.
+ (subdi3): Reorder emitted instructions.
+
+2003-03-12 Andreas Jaeger <aj@suse.de>
+
+ * config/i386/netbsd64.h (TARGET_OS_CPP_BUILTINS): Remove call to
+ NETBSD_OS_CPP_BUILTINS_LP64.
+
+2003-03-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in: Eliminate all.indirect. Update and clean up comments.
+ Rearrange. Reorganize.
+ * configure.in: Rearrange.
+ * configure: Regenerate.
+
+2003-03-12 Andreas Jaeger <aj@suse.de>
+
+ * c-cppbuiltin.c (cb_register_builtins): Define LP64 builtins for
+ LP64 targets.
+
+ * doc/cpp.texi (Common Predefined Macros): Document __LP64__ and
+ _LP64.
+
+ * config/ia64/ia64.h (TARGET_CPU_CPP_BUILTINS): Do not define
+ _LP64 macros here.
+ * config/pa/pa.h (TARGET_CPU_CPP_BUILTINS): Likewise.
+
+ * config/alpha/netbsd.h (TARGET_OS_CPP_BUILTINS): Remove call to
+ NETBSD_OS_CPP_BUILTINS_LP64.
+ * config/sh/netbsd-elf.h (TARGET_OS_CPP_BUILTINS): Likewise.
+ * config/sparc/netbsd-elf.h (TARGET_OS_CPP_BUILTINS): Likewise.
+
+ * config/netbsd.h (NETBSD_OS_CPP_BUILTINS_LP64): Remove.
+
+2003-03-12 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_setup_incoming_varargs): Set stack_alignment_needed to 128.
+
+2003-03-12 Daniel Jacobowitz <drow@mvista.com>
+
+ Fix PR target/9797 and PR c/9853.
+ * stmt.c (expand_decl_init): Call push_temp_slots () and
+ pop_temp_slots ().
+
+2003-03-12 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c: Include basic-block.h.
+ (sh_output_mi_thunk, emit_load_ptr): New functions.
+ (TARGET_ASM_OUTPUT_MI_THUNK, TARGET_ASM_CAN_OUTPUT_MI_THUNK): Redefine.
+
+2003-03-12 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/pe.h (FIXED_REGISTERS): Add Maverick registers.
+ (CALL_USED_REGISTERS): Likewise.
+ * config/arm/arm.h (FIRST_PSEUDO_REGISTER): Update comment
+ describing how this value is calculated.
+
+2003-03-12 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * configure.in (rlim_t): Define to long if no valid definition
+ found in sys/resource.h.
+ * config.in, configure: Regenerate.
+
+2003-03-12 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/mcore/mcore-elf.h (CPP_PREDEFINES): Replace with
+ TARGET_OS_CPP_BUILTINS.
+ * config/mcore/mcore-pe.h: Similarly.
+ * config/mcore/mcore.h: Replace CPP_PREDEFINES and part of
+ CPP_SPEC with TARGET_CPU_CPP_BUILTINS.
+
+2003-03-12 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/9928
+ * c-decl.c (duplicate_decls): Discard the initializer of the new decl
+ only if it is a VAR_DECL.
+
+2003-03-12 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/9888
+ * config/i386/i386.md (jcc_1): Fix range.
+ (jcc_2): Likewise.
+ (jump): LIkewise.
+ (doloop_end_internal): Likewise.
+
+2003-03-12 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/winnt.c (DLL_IMPORT_PREFIX): New define.
+ Use throughout instead of DLL_IMPORT_EXPORT_PREFIX and "e."
+ (DLL_EXPORT_PREFIX): New define. Use throughout instead of
+ DLL_IMPORT_EXPORT_PREFIX and "i."
+ (i386_pe_dllexport_name_p): Here.
+ (i386_pe_dllimport_name_p): Here.
+ (i386_pe_mark_dllexport): Here. Remove DLL_IMPORT_PREFIX,
+ not 9 chars when getting identifier name.
+ (i386_pe_mark_dllimport): Here.
+ (i386_pe_encode_section_info): Here. Remove DLL_IMPORT_PREFIX,
+ not 9 chars when getting identifier name. Correct comment.
+ (i386_pe_strip_name_encoding): Here. Add comments for different
+ cases.
+ (gen_fastcall_suffix): Break down xmalloc() argument to
+ components.
+ (gen_stdcall_suffix): Likewise.
+ Update copyright year.
+
+2003-03-12 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR optimization/9888
+ * config/i386/i386.md (movsi_1): Remove special alternatives
+ for %eax register.
+ (movsi_1_nointernunit): Likewise.
+ (movhi_1): Likewise.
+ * config/i386/i386.c (memory_address_length): Do not use
+ short displacement when there is no base.
+ (ix86_attr_length_address_default): Handle LEA instructions.
+
+2003-03-12 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-cppbuiltin.c (builtin_define_std): Make non-static.
+
+2003-03-11 Loren James Rittle <ljrittle@acm.org>
+
+ * config/freebsd-spec.h (FBSD_CPP_PREDEFINES): Remove.
+ (FBSD_TARGET_OS_CPP_BUILTINS): New port-specific macro.
+ (FBSD_TARGET_CPU_CPP_BUILTINS): New port-specific macro.
+ * config/freebsd.h (CPP_PREDEFINES): Remove.
+ (TARGET_OS_CPP_BUILTINS): New.
+ * config/alpha/freebsd.h: Use overridden FBSD_TARGET_CPU_CPP_BUILTINS
+ instead of TARGET_OS_CPP_BUILTINS.
+ * config/sparc/freebsd.h (CPP_PREDEFINES): Remove.
+
+2003-03-11 Geoffrey Keating <geoffk@apple.com>
+
+ * c-cppbuiltin.c (builtin_define_std): Add ATTRIBUTE_UNUSED.
+
+2003-03-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_stack_info): Remove
+ insn_chain_scanned. Use insn_chain_scanned_p in machine_function.
+
+ * config/rs6000/rs6000.h (machine_function): Add insn_chain_scanned_p.
+
+2003-03-11 Alexandre Oliva <aoliva@redhat.com>
+
+ * toplev.c (independent_decode_option): Return success for --help,
+ --target-help and --version.
+
+2003-03-11 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mips/linux64.h (DRIVER_SELF_SPECS): Add endian_spec.
+ Default to -mips3 on -mabi=64. Don't add -mips* flag if -march is
+ specified.
+ (SUBTARGET_ASM_SPEC): Remove -mips*-adding code obviated by
+ DRIVER_SELF_SPECS.
+ (LINK_SPEC): Let endian options affect the linker emulation name.
+
+2003-03-11 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.md (reload_inqi): Fix mode for source in second set.
+
+2003-03-11 Jan Hubicka <jh@suse.cz>
+
+ * cselib.c (cselib_invalidate_mem_1): Move too ...
+ (cselib_invalidate_mem): ... here; use new list
+ (dummy_val, first_containing_mem): New static variables.
+ (clear_table): Initialize first_containing_mem.
+ (discard_useless_values): Compact the containing_mem list.
+ (add_mem_for_addr): Add to the list.
+ * cselib.h (cselib_val): Add next_containing_mem.
+
+2003-03-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Disable string
+ instructions for e500.
+
+2003-03-11 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Update.
+ * c-cppbuiltin.c: Include tm_p.h.
+
+2003-03-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/tm.texi (Frame Registers): Document DWARF_REG_TO_UNWIND_COLUMN.
+
+ * unwind-dw2.c (DWARF_REG_TO_UNWIND_COLUMN): Define.
+ (_Unwind_GetGR): Use DWARF_REG_TO_UNWIND_COLUMN.
+ (_Unwind_SetGR): Same.
+ (_Unwind_GetGRPtr): New.
+ (_Unwind_SetGRPtr): New.
+ (uw_update_context_1): Use accesor functions instead of accessing
+ context->reg[] directly.
+ (uw_install_context_1): Same.
+ (execute_cfa_program): Same.
+ (__frame_state_for): Same.
+
+ * config/rs6000/rs6000.c (spe_synthesize_frame_save): Use 1200 as
+ the synthetic register offset.
+
+ * config/rs6000/rs6000.h (DWARF_REG_TO_UNWIND_COLUMN): New.
+
+2003-03-11 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/cris/cris.md: Remove lingering EGCS reference.
+ ("*extopqihi_side_biap"): For HI operation, match
+ cris_additive_operand_extend_operator, not
+ cris_operand_extend_operator. Adjust condition.
+ ("*extopqihi_side", "*extopqihi"): Ditto.
+ ("*extopqisi_side_biap"): Correct operand numbers in condition.
+ ("*extophisi_side_biap", "*extopqisi_swap_side_biap"): Ditto.
+ ("*extophisi_swap_side_biap", "*extopqisi_swap"): Ditto.
+ ("*extophisi_swap"): Ditto.
+ ("*extopqihi_swap_side_biap"): For HI operation, match a simple
+ PLUS, not cris_operand_extend_operator. Adjust condition and
+ output template.
+ ("*extopqihi_swap_side", "*extopqihi_swap"): Ditto.
+ * config/cris/cris.h (PREDICATE_CODES): Add
+ cris_additive_operand_extend_operator.
+ * config/cris/cris.c (cris_additive_operand_extend_operator):
+ New predicate.
+
+2003-03-11 Hartmut Penner <hpenner@de.ibm.com>
+
+ * df.c (read_modify_subreg_p): Change from static to global.
+ * df.h (read_modify_subreg_p): Add prototype.
+ * sched-deps.c (sched_analyze_1): Generate true dependency for
+ strict_low_part, certain subregs and zero/sign_extract.
+
+2003-03-11 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Update.
+ * c-common.c: Don't include real.h or except.h.
+ (REGISTER_PREFIX): Remove.
+ (builtin_define_std, builtin_define_with_value,
+ builtin_define_with_int_value, builtin_define_with_hex_fp_value,
+ builtin_define_type_max, builtin_define_type_precision,
+ builtin_define_float_constants): Move to c-cppbuiltin.c.
+ (c_stddef_cpp_builtins): New.
+ * c-common.h (builtin_define_with_value, c_stddef_cpp_builtins): New.
+ * c-cppbuiltin.c: New, extracted from c-common.c.
+ (define__GNUC__): New.
+ * cppspec.c (lang_specific_driver): Remove support of -no-gcc.
+ * gcc.c: Remove support of %v1, %v2 and %v3 specs.
+ (cpp_unique_options): Don't support no-gcc.
+ (do_spec_1): Remove support of version specs.
+ * doc/invoke.texi: Remove documentation of %v1, %v2 and %v3.
+ * doc/passes.texi: Update.
+ * doc/tm.texi: Update.
+
+2003-03-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * dwarf2out.c (multiple_reg_loc_descriptor): Fix thinko.
+
+2003-03-10 Andrew Pinski <apinski@apple.com>
+
+ * config/darwin.c (machopic_function_base_name): If dynamic-no-pic
+ is on should not get here.
+ (machopic_indirect_data_reference): If dynamic-no-pic is on just
+ generate high/low parts of the address.
+ (machopic_legitimize_pic_address): Change MACHOPIC_PURE to
+ MACHOPIC_INDIRECT. Dynamic-no-pic uses 0 as the pic base. Generate
+ symbol and labels with a new reg. Dynamic-no-pic does not have a
+ pic_offset_table_rtx.
+ (machopic_select_section): Change references of flag_pic to
+ MACHOPIC_INDIRECT.
+ (machopic_asm_out_destructor): Likewise.
+ * config/darwin.h (ASM_DECLARE_UNRESOLVED_REFERENCE): Change
+ reference of flag_pic to MACHOPIC_INDIRECT.
+ (MACHO_DYNAMIC_NO_PIC_P): Define as TARGET_DYNAMIC_NO_PIC.
+ (MACHOPIC_INDIRECT): Is also true when dynamic-no-pic is on.
+ (MACHOPIC_JUST_INDIRECT): Is also true when dynamic-no-pic is on.
+ (MACHOPIC_PURE): Is not pure when dynamic-no-pic is on.
+ * config/i386/darwin.h (MASK_MACHO_DYNAMIC_NO_PIC): Define as
+ 0 for right now as dynamic-no-pic is not implemented on Darwin/ia32.
+ * config/rs6000/darwin.h (MASK_MACHO_DYNAMIC_NO_PIC): Define.
+ (TARGET_DYNAMIC_NO_PIC): Define.
+ (SUBTARGET_SWITCHES): Define, have sub-target switches for
+ dynamic-no-pic.
+ (SUBTARGET_OVERRIDE_OPTIONS): Move check for -fpic from
+ rs6000_override_options to here. Dynamic-no-pic overrides
+ pic.
+ (CC1_SPEC): Change from not static then pic to not static and not
+ dynamic-no-pic then pic.
+ * config/rs6000/rs6000.c (rs6000_override_options): Move the
+ check for -fpic and DARWIN_ABI to config/rs6000/darwin.h
+ (rs6000_legitimize_reload_address): Add case for loading floating in
+ dynamic-no-pic.
+ (rs6000_emit_move): Add case for dynamic-no-pic. Change reference
+ of flag_pic to MACHOPIC_INDIRECT.
+ (secondary_reload_class): Conditional change the reference of
+ flag_pic to MACHOPIC_INDIRECT.
+ (rs6000_output_mi_thunk): Change reference of flag_pic to
+ MACHOPIC_INDIRECT.
+ (output_profile_hook): Likewise.
+ (machopic_output_stub): Non-pure (dynamic-no-pic) is now supported.
+ * config/rs6000/rs6000.md (movdf_low): Add the case for
+ MACHO_DYNAMIC_NO_PIC_P.
+ (call): Change references for flag_pic in TARGET_MACHO to
+ MACHOPIC_INDIRECT.
+ (SUBTARGET_OVERRIDE_OPTIONS): Add case where -fpic is on and
+ -mdynamic-no-pic is on. Also move case for -fpic from rs6000.c.
+ * doc/invoke.texi (-mdynamic-no-pic): Document.
+
+2003-03-10 Devang Patel <dpatel@apple.com>
+
+ PR c++/9394
+ * gcc.c (DEFAULT_SWITCH_TAKES_ARG): Remove.
+ (DEFAULT_WORD_SWITCH_TAKES_ARG): Remove.
+ * gcc.h (DEFAULT_SWITCH_TAKES_ARG): Add.
+ (DEFAULT_WORD_SWITCH_TAKES_ARG): Add.
+ * cppspec.c (DEFAULT_SWITCH_TAKES_ARG): Remove.
+ (DEFAULT_WORD_SWITCH_TAKES_ARG): Remove.
+
+2003-03-10 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ PR optimization/7189
+ * toplev.c (rest_of_compilation): Move
+ check_function_return_warnings up to just after
+ delete_unreachable_blocks.
+
+2003-03-10 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.h (HARD_REGNO_RENAME_OK): Define.
+ * config/m68hc11/m68hc11-protos.h (m68hc11_hard_regno_rename_ok):
+ Declare.
+ * config/m68hc11/m68hc11.c (m68hc11_hard_regno_rename_ok): New function
+ for reg rename optimization to avoid using Z and Y registers.
+
+2003-03-10 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("*addhi3_68hc12"): Accept any constant
+ when adding to X and Y since leax/leay are fast.
+ ("*addhi3"): Accept 'I' constraint when adding to address register.
+ ("rotlhi3"): Operand 1 must be a register_operand.
+ (peephole2): New peephole to optimize some adds.
+ * config/m68hc11/m68hc11.h (CONST_OK_FOR_LETTER_P): Use 'I' constraint
+ to represent -2 .. 2 small integer range.
+
+2003-03-10 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (m68hc11_gen_rotate): Set carry before
+ each 16-bit rotation.
+
+2003-03-10 Zack Weinberg <zack@codesourcery.com>
+
+ * c-opts.c (add_prefixed_path): Don't use concat. When
+ prefixing with cpp_GCC_INCLUDE_DIR, copy only the first
+ cpp_GCC_INCLUDE_DIR_len characters.
+
+2003-03-10 Segher Boessenkool <segher@koffie.nl>
+
+ * testsuite/gcc.dg/altivec-9.c: New file.
+
+ * config/rs6000/rs6000.c (altivec_frame_fixup): Remove.
+ (rs6000_emit_prologue): Use rs6000_frame_related instead.
+
+2003-03-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.h: Define __ev64_*64__ to use single element
+ vectors.
+ (__ev_convert_u64): Remove macro. Define as inline.
+ (__ev_convert_s64): Same.
+
+2003-03-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.h (DWARF_FRAME_REGISTERS): Define.
+ (rs6000_stack_t): Add spe_64bit_regs_used.
+
+ * config/rs6000/rs6000.c (rs6000_stack_info): Calculate
+ spe_64bit_regs_used, and use it to determine the size of the
+ frame.
+ (spe_func_has_64bit_regs_p): New.
+ (spe_synthesize_frame_save): New.
+ (rs6000_frame_related): Handle SPE synthetic registers.
+ (rs6000_emit_prologue): Only save in 64-bits if the function used
+ any registers in 64-bit mode.
+ (rs6000_emit_epilogue): Same, but for restore.
+
+2003-03-10 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.h (enum floating_point_type): Delete. Replace with...
+ (enum fputype): ... new.
+ (FPUTYPE_DEFAULT): Renamed from FP_DEFAULT. Values reworked.
+ * linux-elf.h (FPUTYPE_DEFAULT): Likewise.
+ * arm.md (attr fpu): Reworked for new underlying enum values.
+ * arm.c (arm_fpu_arch): Now enum fputype.
+ (arm_fpu_tune): Renamed from arm_fpu. Now enum fputype.
+ (arm_override_options, arm_output_epilogue, arm_expand_prologue):
+ Update uses of arm_fpu_arch and arm_fpu_tune.
+
+2003-03-10 Josef Zlomek <zlomekj@suse.cz>
+
+ * cfgcleanup.c (outgoing_edges_match): Compare the jump tables.
+ (try_crossjump_to_edge): Replace refereces to one jump table by
+ references to identical jump table.
+ * loop.c (load_mems): Moved setting the JUMP_LABEL to replace_label.
+ (replace_label): Moved to rtlanal.c.
+ (struct rtx_pair): Moved to rtl.h.
+ * rtl.h (struct rtx_pair): Moved from loop.c.
+ (replace_label): New extern function.
+ (subrtx_p): New extern function.
+ (tablejump_p): New extern function.
+ * rtlanal.c (replace_label): Moved from loop.c.
+ (subrtx_p_1): New static function.
+ (subrtx_p): New function.
+ (tablejump_p): New function.
+
+2003-03-10 Jan Hubicka <jh@suse.cz>
+
+ * cfgcleanup.c (try_optimize_cfg): Fix thinko in previous patch.
+
+ * cfgcleanup.c (merge_blocks): Return where to iterate next.
+ (try_optimize_cfg): Use return value of merge_blocks
+
+2003-03-10 Michael Matz <matz@suse.de>
+
+ * cfg.c (unchecked_make_edge): New.
+ (cached_make_edge): Use it.
+ * basic-block.h (unchecked_make_edge): Declare.
+ * cfglayout.c (cfg_layout_duplicate_bb): Use it.
+
+2003-03-10 Richard Earnshaw <rearnsha@arm.com>
+
+ * fpa.md: New file. Move all patterns relating to FPA co-processor
+ to here...
+ * arm.md: ... from here.
+ (cirrus.md, fpa.md): Include at end of description.
+ (divsf3, divdf3, modsf3, movdf3, sqrtsf2, sqrtdf2): New expands.
+ (pic_load_addr_based): Remove register constraint from expander.
+ (seq, sne, sgt, sle, slt, sge, sgeu, sleu, sgtu, sltu, sunordered)
+ (sordered, sungt, sunle, sunge, sunlt): Likewise.
+ (eh_epilogue, tablejump): Likewise.
+
+2003-03-09 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * tree.c (substitute_in_expr, case 'e'): Only make recursive call
+ on operands if it has a PLACEHOLDER_EXPR.
+
+2003-03-09 David Edelsohn <edelsohn@gnu.org>
+ Mostafa Hagog
+
+ * config/rs6000/rs6000.md (movsi_update1): Add TARGET_UPDATE final
+ condition.
+
+2003-03-09 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/frv/frv.h: Use TARGET_CPU_CPP_BUILTINS, not CPP_PREDEFINES.
+ * config/ip2k/ip2k.h: Similarly.
+ * config/m32r/m32r.h: Similarly.
+ * config/m68hc11/m68hc11.h: Similarly.
+ * config/mn10200/mn10200.h: Similarly.
+ * config/mn10300/mn10300.h: Similarly.
+ * config/pdp11/pdp11.h: Similarly.
+ * config/v850/v850.h: Similarly.
+ * config/rs6000/vxworks.h: Similarly for TARGET_OS_CPP_BUILTINS.
+ * config/v850/retms.h: Similarly for TARGET_OS_CPP_BUILTINS.
+ * config/mips/iris3.h: Remove #if 0 block.
+
+2003-03-09 Roger Sayle <roger@eyesopen.com>
+ Joern Rennecke <joern.rennecke@superh.com>
+
+ * gcc.c (do_spec_1) ['{']: Revert 2003-02-24 patch. Don't handle
+ pending argument upon return from handle_braces here.
+ (do_spec_2): Instead handle it upon return from do_spec_1 here.
+
+2003-03-09 Roger Sayle <roger@eyesopen.com>
+ Joern Rennecke <joern.rennecke@superh.com>
+
+ * gcc.c (do_spec_1) ['{']: Revert 2003-02-24 patch. Don't handle
+ pending argument upon return from handle_braces here.
+ (do_spec_2): Instead handle it upon return from do_spec_1 here.
+
+2003-03-09 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * varasm.c (make_decl_one_only): Use declare_weak().
+
+2003-03-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR middle-end/9986
+ * c-common.c (c_common_nodes_and_builtins): Initialize target builtins
+ after the common builtins.
+ * pa-hpux.h (DONT_HAVE_FPUTC_UNLOCKED): Define.
+ * pa.c (TARGET_INIT_BUILTINS): Define.
+ (pa_init_builtins): New function.
+
+ * pa.md (call, call_value, sibcall, sibcall_value): When sufficient
+ space has been allocated for the outgoing arguments, set the arg
+ pointer for a call emitted after virtuals have been instantiated
+ using the stack pointer offset, otherwise abort.
+
+2003-03-09 DJ Delorie <dj@redhat.com>
+
+ * config/stormy16/stormy16.h (DWARF_LINE_MIN_INSTR_LENGTH): Revert.
+
+2003-03-09 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (fix_truncsfsi2, fix_truncdfsi2, arm_fix_truncsfsi2)
+ (arm_fix_truncdfsi2): Add missing fix in floating point mode before
+ conversion to integer.
+ * cirrus.md (cirrus_truncsfsi2, cirrus_truncdfsi2): Likewise.
+
+2003-03-09 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def: Fix typo and improve grammar.
+ * loop-unroll.c (decide_peel_completely): Tidy log message.
+
+2003-03-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*tstsi_upper_bit): New.
+ (*iorsi3_e2f): Likewise.
+
+2003-03-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_and_costs): Return the number of
+ assembly instructions needed.
+ (h8300_shift_costs): Likewise.
+
+2003-03-09 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/cris/aout.h (ENDFILE_SPEC): Undef.
+
+ * optabs.c (gen_move_insn): Move logic for synthesizing MODE_CC
+ moves from here ...
+ * expr.c (emit_move_insn_1): ... to here.
+
+ * config/cris/aout.h (CRIS_CPP_SUBTARGET_SPEC): Move -D__AOUT__ to...
+ (TARGET_OS_CPP_BUILTINS): New macro.
+ * config/cris/cris.h (CRIS_CPP_SUBTARGET_SPEC): Move -D__ELF__ to...
+ (TARGET_OS_CPP_BUILTINS): New macro.
+ (CPP_PREDEFINES): Don't define. Move old definitions and...
+ (CPP_SPEC): ...move -D__CRIS_ABI_version=2 to...
+ (TARGET_CPU_CPP_BUILTINS): New macro.
+ * config/cris/linux.h (CRIS_CPP_SUBTARGET_SPEC): Move constant
+ definitions and the optional __PIC__, __pic__ and
+ __NO_UNDERSCORES__ definitions to...
+ (TARGET_OS_CPP_BUILTINS): New macro.
+
+ * flags.h (flag_leading_underscore): Declare.
+
+ * c-opts.c (c_common_post_options): On fopen failure, return
+ false, not NULL.
+
+2003-03-08 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/cris/cris_abi_symbol.c: #include tconfig.h and tm.h, not
+ config.h.
+ * config/cris/cris.h (HAVE_GAS_HIDDEN): Don't define here.
+ * config/cris/aout.h (HAVE_GAS_HIDDEN): Undef.
+
+2003-03-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/sh/rtemself.h (TARGET_OS_CPP_BUILTINS): Use instead of
+ CPP_PREDEFINES.
+ * config/sh/rtems.h (TARGET_OS_CPP_BUILTINS): Use instead of
+ CPP_PREDEFINES.
+
+2003-03-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-common.h (c_common_init, c_common_post_options): Update.
+ * c-objc-common.c (c_objc_common_init): Update for new prototype.
+ * c-opts.c (saved_lineno): New.
+ (c_common_post_options, c_common_init): Update prototypes,
+ move call to cpp_read_main_file from latter to former.
+ * c-tree.h (c_ojbc_common_init): Update.
+ * langhooks-def.h (lhd_post_options): New.
+ (LANG_HOOKS_INIT, LANG_HOOKS_POST_OPTIONS): Update.
+ * langhooks.c (lhd_post_options): New.
+ * langhooks.h (struct lang_hooks): Update post_options and init hooks.
+ * toplev.c (no_backend): New.
+ (process_options): Call post_options hook and set main_input_filename
+ and input_filename here.
+ (lang_dependent_init, do_compile): post_options hook moved to
+ process_options.
+ * objc/objc-act.c (objc_init): Update prototype.
+ * objc/objc-act.h (objc_init): Update prototype.
+
+2003-03-08 Roger Sayle <roger@eyesopen.com>
+
+ * emit-rtl.c (gen_lowpart): Don't attempt to load a part of
+ a complex or vector type, using a load in the original mode.
+
+2003-03-08 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (cgraph.o): Depend on gt-cgraph.h and varray.h.
+ * gt-cgraph.h: New GC file.
+ * cgraph.c (known_fns): New static variable.
+ (cgraph_node): Add the decl into varray.
+
+2003-03-08 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/mmix/mmix.md ("*movcc_expanded"): Add missing alternatives.
+
+2003-03-08 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (fpa_rhs_operand, fpa_add_operand, const_double_rtx_ok_for_fpa)
+ (neg_const_double_ok_for_fpa, output_mov_long_double_fpa_from_arm)
+ (output_mov_long_double_arm_from_fpa, output_mov_double_fpa_from_arm)
+ (output_mov_double_arm_from_fpa): Renamed to use fpa instead of fpu.
+ All callers changed.
+ * arm.md, arm.h, arm-protos.h: Updated.
+
+ * arm.h (enum reg_class FPA_REGS): Renamed from FPU_REGS.
+ (CLASS_MAX_NREGS, REGISTER_MOVE_COST, REG_CLASS_FROM_LETTER): Updated.
+ * arm.c (arm_regno_class, f_register_operand): Updated.
+
+2003-03-08 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/cris/cris.h: Remove EGCS references.
+ (CPP_SPEC): Remove "-$".
+ (INIT_CUMULATIVE_ARGS): Adjust parameter name to FNDECL.
+
+2003-03-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/stormy16/stormy16.h (TARGET_CPU_CPP_BUILTINS): Use in
+ preference to CPP_PREDEFINES.
+
+2003-03-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * cppinit.c (cpp_finish_options): Set first_unused_line to -1.
+
+2003-03-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*extzv_16_8): New.
+
+2003-03-08 Jan Hubicka <jh@suse.cz>
+
+ * c-decl.c: (finish_function): Update call of tree_inlinable_function_p.
+ * cgraph.h: (cgraph_local_info): Add can_inline_once
+ (cgraph_global_info): Add inline_once.
+ (cgraph_node): Add previous.
+ (cgraph_remove_node): New.
+ * cgraphunit.c (cgraph_mark_functions_to_inline_once): New static
+ function.
+ (cgraph_optimize): Call it.
+ (cgraph_finalize_function): Set inlinable flags.
+ (cgraph_finalize_compilation_unit): Actually remove the reclaimed nodes.
+ (cgraph_mark_functions_to_output): Use new inlining heuristics flags.
+ (cgraph_expand_function): Likewise.
+ * cgraph.c
+ (cgraph_node): Put nodes into doubly linked chain.
+ (cgraph_remove_node): New function.
+ * flags.h (flag_inline_functions_called_once): Declare.
+ * tree-inline.c: Include cgraph.h
+ (inlinable_functions_p): Add extra argument to bypass limits.
+ (expand_call_inline): Obey cgraph flag.
+ * tree-inline.h (tree_inlinable_function_p): Update prototype.
+
+2003-03-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcse.c (bypass_block, bypass_conditional_jumps): Do not create
+ irreducible loops.
+
+ * loop-unroll.c (unroll_loop_runtime_iterations): Update irreducible
+ loops info correctly.
+
+2003-03-08 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR middle-end/7796
+ * unroll.c (calculate_giv_inc): Handle constants being
+ loaded with LSHIFTRT.
+
+2003-03-07 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (processor_target_table): Do not disable
+ GP optional instructions on Power3, Power4, 620, and 630.
+
+2003-03-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * calls.c: Fix comment formatting.
+ * cfgloopanal.c: Likewise.
+ * cfgloopmanip.c: Likewise.
+ * combine.c: Likewise.
+ * dwarf2out.c: Likewise.
+ * ggc-common.c: Likewise.
+ * langhooks.c: Likewise.
+ * loop-unroll.c: Likewise.
+ * loop.c: Likewise.
+ * ra-build.c: Likewise.
+ * sbitmap.c: Likewise.
+ * toplev.c: Likewise.
+
+2003-03-07 James E Wilson <wilson@tuliptree.org>
+
+ * config/sh/sh.h (HARD_REGNO_NREGS): Round up the XD register count.
+
+2003-03-07 Geoffrey Keating <geoffk@apple.com>
+
+ * objc/lang-specs.h (objective-c-header): Use .gch not .pch;
+ support -no-integrated-cpp.
+
+ * c-pch.c (get_ident): Use c_language_kind and flag_objc rather
+ than langhooks.name.
+
+2003-03-07 Michael Matz <matz@suse.de>
+
+ * df.h (enum df_ref_flags.DF_REF_STRIPPED): New.
+ (DF_FOR_REGALLOC): New.
+ * df.c (df_ref_record): Set DF_REF_STRIPPED.
+ (read_modify_subreg_p): Simplify.
+ (df_def_record_1, df_uses_record): Set DF_REF_MODE_CHANGE more often.
+ Use DF_FOR_REGALLOC.
+ * ra.h (struct web): New member subreg_stripped.
+ (invalid_mode_change_regs): Declare.
+ * ra.c (invalid_mode_change_regs): New.
+ (init_ra): Initialize it.
+ * ra-build.c (init_one_web_common, remember_web_was_spilled): Use it.
+ Use CANNOT_CHANGE_MODE_CLASS as ifdef guard.
+ (reinit_one_web, parts_to_web_1): Deal with subreg_stripped.
+ * ra-colorize.c (colorize_one_web): Use invalid_mode_change_regs.
+ Use CANNOT_CHANGE_MODE_CLASS as ifdef guard.
+
+2003-03-07 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (addsf3, adddf3, subsf3, subdf3, mulsf3, muldf3, negsf2)
+ (negdf2, abssi2, abssf2, absdf2, floatsisf2, floatsidf2)
+ (fix_truncsfsi2, fix_truncdfsi2, truncdfsf2): Moved back into main
+ machine description file from ...
+ * cirrus.md: ... here.
+
+2003-03-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): Don't use
+ reg_overlap_mentioned_p.
+
+2003-03-06 Geoffrey Keating <geoffk@apple.com>
+
+ * c-pch.c: Include langhooks.h.
+ (IDENT_LENGTH): New.
+ (get_ident): New.
+ (pch_ident): Delete.
+ (pch_init): Use get_ident, IDENT_LENGTH.
+ (c_common_valid_pch): Likewise. Also, use actual language
+ in warning message.
+ * Makefile.in (c-pch.o): Add langhooks.h to dependencies.
+
+ * objc/config-lang.in (gtfiles): Add objc-act.c. Remove duplicate
+ c-parse.in.
+ * objc/Make-lang.in (objc/objc-act.o): Add dependency on
+ gt-objc-objc-act.h.
+ (gt-objc-objc-act.h): New rule.
+ * objc/lang-specs.h: Support PCH.
+ * objc/objc-act.c: Include gt-objc-objc-act.h.
+ (objc_add_static_instance): Move num_static_inst out, mark for PCH.
+ (build_selector_reference_decl): Move idx out, mark for PCH.
+ (build_class_reference_decl): Likewise.
+ (build_objc_string_decl): Move *_idx out, mark for PCH.
+ (build_tmp_function_decl): Move xxx out, mark for PCH.
+
+2003-03-06 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.c (rs6000_binds_local_p): Consider
+ global functions for inlining on Darwin.
+
+2003-03-06 Vladimir Makarov <vmakarov@redhat.com>
+
+ * haifa-sched.c (schedule_block): Don't call reorder when sorting
+ is prohibited.
+
+2003-03-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in (c-ppoutput.o): Update.
+ * c-common.h (init_pp_output): New.
+ (preprocess_file): Update.
+ * c-lex.c (init_c_lex): Move mbchar initialization to cpplib.
+ Register builtins.
+ * c-opts.c (c_common_init): Call init_pp_output if preprocessing.
+ Make call to cpp_read_main_file common to whether preprocessing
+ or not. Don't register builtins.
+ * c-ppoutput.c: Include c-pragma.h.
+ (setup_callbacks): Rename init_pp_output.
+ (preprocess_file): No longer setup callbacks or call
+ cpp_read_main_file.
+ * cpphash.h (_cpp_init_mbchar): New.
+ * cppinit.c (init_library): Call _cpp_init_mbchar.
+ * cpplex.c (_cpp_init_mbchar): New.
+
+2003-03-06 Roger Sayle <roger@eyesopen.com>
+
+ * emit-rtl.c (gen_lowpart): When requesting the low-part of a
+ MEM, try loading the MEM into a register and taking the low-part
+ of that, to help CSE see the use of the MEM in its true mode.
+
+2003-03-05 Tom Tromey <tromey@redhat.com>
+
+ * config/stormy16/stormy16.h (DWARF_LINE_MIN_INSTR_LENGTH):
+ Define.
+
+2003-03-05 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * config/stormy16/stormy16.md ("*eqbranchsi"): Remove '+' on
+ operand 2.
+ ("*ineqbranchsi"): Likewise.
+
+2003-03-05 Andrew Haley <aph@cambridge.redhat.com>
+
+ * config/stormy16/stormy16.c (xstormy16_expand_prologue): Delete
+ mem_fake_push_rtx. Instead construct a SEQUENCE to show the
+ register store followed by a stack increment.
+
+2003-03-05 Chris Moller <cmoller@redhat.com>
+
+ * config/stormy16/stormy16.c (REG_NEEDS_SAVE): added a term
+ to inhibit saving CARRY_REGS.
+
+ * config/stormy16/stormy16.c (xs_hi_general_operand):
+ added predicate to detect and error-out on out-of-range
+ const_ints for movhi.
+ * config/stormy16/stormy16.md (movhi): use
+ xs_hi_general_operand.
+
+ * config/stormy16/stormy16.c (xstormy16_expand_prologue):
+ added a check for local vbl size overflow.
+ * config/stormy16/stormy16.c (xs_hi_nonmemory_operand):
+ added predicate to detect and error-out on out-of-range
+ const_ints for addhi and subhi.
+ * config/stormy16/stormy16.md (addhi3, addchi4, addchi5,
+ subhi3, subchi4, subchi5): used xs_hi_nonmemory_operand.
+
+ * config/stormy16/stormy16.c (xstormy16_legitimate_address_p):
+ add a term to accept PRE_MODIFY addresses.
+ * config/stormy16/stormy16.c (xstormy16_expand_move):
+ add code to expand PRE_MODIFY addresses to an add followed
+ by a move.
+
+2003-03-06 Jason Merrill <jason@redhat.com>
+
+ * tree-inline.c (inlinable_function_p): Revert earlier change
+ pending investigation.
+
+2003-03-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a new peephole2): New.
+
+2003-03-06 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_node): Do not confuse nested functions and methods.
+
+2003-03-06 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * dwarf2out.c (size_of_die): Compute size of external reference to
+ die correctly.
+
+2003-03-06 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/mmix/mmix.md ("*movcc_expanded"): New pattern.
+ ("movcc", "movcc_uns", "movcc_fp", "movcc_fpeq", "movcc_fun"): New
+ expanders.
+
+2003-03-05 Roger Sayle <roger@eyesopen.com>
+
+ * expr.h (lang_expand_expr): Delete obsolete prototype.
+
+2003-03-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * emit-rtl.c (gen_highpart_mode): Fix a comment typo.
+
+2003-03-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): Generalize to
+ accept a memory operand.
+
+2003-03-05 Olivier Hainque <hainque@act-europe.fr>
+
+ * config/alpha/alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Add '+'.
+ * config/alpha/alpha.c (print_operand, case '+'): New.
+ * config/alpha/alpha.md (call_osf_1_noreturn): Document and use.
+ (call_value_osf_1_noreturn): Likewise.
+
+2003-03-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * stmt.c (fixup_gotos): Change meaning of DONT_JUMP_IN.
+ (expand_end_bindings): Likewise.
+
+2003-03-05 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.md (return_external_pic): Add !TARGET_PA_20 to constraint.
+ (epilogue): Don't generate return_external_pic when emitting PA 2.0
+ code.
+
+2003-03-05 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/tm.texi: Document TARGET_DWARF_REGISTER_SPAN.
+
+ * config/rs6000/rs6000.c (rs6000_dwarf_register_span): New.
+
+ * hooks.c (hook_rtx_rtx_null): New.
+
+ * hooks.h (hook_rtx_rtx_null): Protoize.
+
+ * target-def.h (TARGET_DWARF_REGISTER_SPAN): New macro.
+ (TARGET_INITIALIZER): Add TARGET_DWARF_REGISTER_SPAN.
+
+ * target.h (struct gcc_target): Add dwarf_register_span.
+
+ * dwarf2out.c (multiple_reg_loc_descriptor): New.
+ (one_reg_loc_descriptor): New.
+ (reg_loc_descriptor): Add support for values that span more than
+ one register.
+
+2003-03-05 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (calls.o, toplev.o alias.o): Depend on cgraph.h
+ * alias.c: Include cgraph.h
+ (mark_constant_function): Use cgraph_rtl_info.
+ * calls.c: Include cgraph.h
+ (flags_from_decl_or_type): Use cgraph_rtl_info to find pure and const
+ calls.
+ (expand_call): Use cgraph_rtl_info to set preferred stack boundary.
+ * cgraph.c (cgraph_rtl_info): New function.
+ * cgraph.h (cgraph_rtl_info): Declare
+ (cgraph_rtl_info): Likewise.
+ * function.h (struct function): Add recursive_call_emit.
+ * toplev.c: Include cgraph.h.
+ (rest_of_compilation): Set preferred_incoming_stack_boundary.
+
+2003-03-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (output_simode_bld): Clear the
+ destination first if possible.
+ * config/h8300/h8300.md (extzv_1_r_h8300hs): Add an
+ alternative.
+ (extzv_1_r_inv_h8300hs): Likewise.
+
+2003-03-05 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * basic-block.h (EDGE_IRREDUCIBLE_LOOP, EDGE_ALL_FLAGS): New.
+ * cfg.c (dump_edge_info): Add EDGE_IRREDUCIBLE_LOOP flag dump.
+ * cfgloop.c (flow_loop_free): Made global.
+ (establish_preds): New static function.
+ (flow_loop_tree_node_add): Handle subloops of added loop correctly.
+ (get_loop_exit_edges): New.
+ (verify_loop_structure): Verify EDGE_IRREDUCIBLE_LOOP flags.
+ * cfgloop.h (flow_loop_free, get_loop_exit_edges, unloop): Declare.
+ * cfgloopanal.c (mark_irreducible_loops): Mark edges in irreducible
+ loops.
+ * cfgloopmanip.c (loop_delete_branch_edge): Allow to test for
+ removability of an edge.
+ (fix_irreducible_loops): New static function.
+ (find_path, remove_path): Add ability to remove enclosing loops.
+ (unloop): New.
+ (copy_bbs, duplicate_loop_to_header_edge): Use EDGE_IRREDUCIBLE_LOOP
+ flags.
+ * cfgrtl.c (verify_flow_info): Handle EDGE_IRREDUCIBLE_LOOP flag.
+ * loop-unroll.c (peel_loops_completely): Do not duplicate loop if
+ not neccessary.
+ (decide_peel_completely, peel_loops_completely): Allow complete peeling
+ of non-duplicable once rolling loops.
+ * loop-unswitch.c (unswitch_loop): Update EDGE_IRREDUCIBLE_LOOP flags.
+
+2003-03-05 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (OVERRIDE_OPTIONS): For TARGET_SHMEDIA, the minimum value
+ for align_jumps is 4.
+
+ (SECONDARY_INPUT_RELOAD_CLASS): If reloading a PLUS into FPUL,
+ use GENERAL_REGS.
+
+2003-03-05 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.h (PAD_VARARGS_DOWN): Define and return
+ according to va_arg type.
+ (EXPAND_BUILTIN_VA_ARG): Remove.
+ * config/m68hc11/m68hc11.c (m68hc11_va_arg): Remove.
+ * config/m68hc11/m68hc11-protos.h (m68hc11_va_arg): Remove.
+
+2003-03-05 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_variable_issue): Remove unnecessary
+ else clauses.
+
+2003-03-05 Michael Matz <matz@suse.de>
+
+ * i386/i386.c (ix86_save_reg): Also test
+ current_function_uses_const_pool.
+
+2003-03-05 Michael Matz <matz@suse.de>
+
+ * unwind.h: Add the GPL exception.
+ * Makefile.in (USER_H): Add unwind.h.
+
+2003-03-05 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/9799
+ * c-typeck.c (push_init_level): Add sanity check.
+
+2003-03-05 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (rest_of_compilation): Defer RTL compilation only when
+ RTL inlining is done.
+
+ * cgraphunit.c (cgraph_mark_local_functions): New local function.
+ (cgraph_optimize): Mark local functions.
+ * i386-protos.h (init_cumulative_args): Update prototype.
+ * i386.c (init_cumulative_args): Use register passing convention for
+ local functions.
+
+ * cgraph.c (cgraph_global_info_ready): New global variable
+ (cgraph_local_info, cgraph_global_info): New functions.
+ * cgraph.h (struct cgraph_local_info, cgraph_global_info): New
+ structures.
+ (cgraph_local_info, cgraph_global_info, cgraph_global_info_ready):
+ Declare.
+ * cgraphunit.c (cgraph_finalize_function): Set inline_many.
+ (cgraph_mark_functions_to_output): Use inline_many.
+ (cgraph_expand_function): Free DECL_SAVED_TREE uncondtionally.
+ (cgraph_expand_functions): Expand inline functions last.
+ (cgraph_optimize): Do not emit uneeded functions.
+
+2003-03-04 Steve Ellcey <sje@cup.hp.com>
+
+ * expr.c (convert_modes): Check for legal hard register.
+
+2003-03-04 Tom Tromey <tromey@redhat.com>
+
+ * doc/sourcebuild.texi (Front End Directory): Document tags.
+ * configure: Rebuilt.
+ * configure.in (target_list): Added tags.
+ * Makefile.in (TAGS): Depend on lang.clean. Include subdirectory
+ TAGS files by reference.
+ * objc/Make-lang.in (objc.tags): New target.
+
+2003-03-04 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcov-io.h (gcov_save_position, gcov_reserve_length, gcov_resync,
+ gcov_skip, gcov_skip_string, gcov_write_unsigned, gcov_write_counter,
+ gcov_write_string, gcov_read_unsigned, gcov_read_counter,
+ gcov_read_string, gcov_write_length): Modified to enable reading/
+ writing of whole .da file just once.
+ (da_file_open, da_file_close, da_file_eof, da_file_error,
+ da_file_position, da_file_seek, da_file_write, da_file_read): New
+ functions.
+ (actual_da_file, actual_da_file_position, actual_da_file_length,
+ actual_da_file_buffer, actual_da_file_buffer_size): New static
+ functions.
+ * libgcov.c (gcov_exit): Modified to read/write the whole .da file at
+ just once.
+
+
+2003-03-04 Andreas Schwab <schwab@suse.de>
+
+ * config/m68k/m68k.c (m68k_output_function_prologue): Fix CFA
+ offset without frame pointer.
+
+2003-03-04 Steve Ellcey <sje@cup.hp.com>
+
+ * expr.c (expand_expr): Call promote_mode to set unsignedp.
+
+2003-03-04 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in: Don't always define TARGET_SYSTEM_ROOT.
+ * configure: Regenerated.
+ * gcc.c: Check whether TARGET_SYSTEM_ROOT is defined.
+
+2003-03-04 Andreas Jaeger <aj@suse.de>
+
+ * configure.in: Check for <memcheck.h>.
+ * configure: Regenerated.
+
+ * config.in: Define HAVE_MEMCHECK_H.
+
+ * ggc-common.c: Use <memcheck.h> if available instead of
+ <valgrind.h>.
+ * ggc-page.c: Likewise.
+ * cppfiles.c: Likewise.
+
+2003-03-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*extzv_8_8): Fix cc and lengths.
+
+2003-03-04 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/9262
+ * c-typeck.c (do_case): Attach the first case label to the SWITCH_BODY.
+ (c_finish_case): Rechain the next statements to the SWITCH_STMT.
+
+2003-03-04 Jan Hubicka <jh@suse.cz>
+
+ * doc/invoke.texi: Document that unit-at-a-time is enabled for -O3
+ * toplev.c (parse_options_and_default_flags): Enable flag_unit_at_a_time
+ for -O3.
+
+2003-03-04 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * configure.in: Delete three unused variables. Move a variable
+ definition closer to its use. Simplify use_collect2 logic. Start to
+ organize. Simplify tests for in-tree gas and ld.
+ * configure: Regenerate.
+
+2003-03-04 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in: Update.
+ * c-common.c (flag_no_line_commands, flag_no_output,
+ flag_dump_macros, flag_dump_includes): New.
+ * c-common.h (flag_no_line_commands, flag_no_output,
+ flag_dump_macros, flag_dump_includes, preprocess_file): New.
+ (init_c_lex): Update prototype.
+ * c-lex.c (init_c_lex): Update prototype; move some code to
+ c_common_init.
+ * c-opts.c (preprocess_file): Subsume into c_common_init.
+ (c_common_decode_option): Update flags.
+ (c_common_init): Move code from preprocess_file and init_c_lex.
+ (sanitize_cpp_opts): Update.
+ * c-ppoutput.c: New, cppmain.c almost verbatim.
+ * cpphash.h (struct printer): Remove.
+ (struct cpp_reader): Remove print.
+ * cpplib.h (dump_none, dump_only, dump_names, dump_definitions,
+ cpp_preprocess_file): Remove.
+ (struct cpp_options): Remove no_output, no_line_commands, dump_macros
+ and dump_includes.
+ * cppmain.c: Remove.
+ * doc/passes.texi: Update.
+
+2003-03-04 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * function.c (STACK_ALIGNMENT_NEEDED): New macro. Default to 1.
+ (assign_stack_local_1): Perform overall stack alignment only when
+ STACK_ALIGNMENT_NEEDED is nonzero.
+ * doc/tm.texi (STACK_ALIGNMENT_NEEDED): Document.
+
+ * pa.c (compute_frame_size): Rename fsize to size. Account for
+ alignment to a word boundary before general register save block. Only
+ account for double-word alignment before floating point register save
+ block if one or more are saved. Don't allocate space for %r3 when
+ frame pointer is needed.
+ (hppa_expand_prologue): Include alignment to word boundary in local
+ frame size.
+ * pa.h (STARTING_FRAME_OFFSET): Define to 8 on both 32 and 64-bit ports.
+ (STACK_ALIGNMENT_NEEDED): Define.
+
+2003-03-04 Kevin Buettner <kevinb@redhat.com>
+
+ * dwarf2out.c (rtl_for_decl_location): Don't return NULL_RTX for
+ global register variables.
+
+2003-03-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * reload.c (reload_adjust_reg_for_mode): New function.
+ (subst_reloads): Call it.
+ (operands_match_p): Adjust registers using HARD_REGNO_NREGS.
+ * reload.h (reload_adjust_reg_for_mode): Declare.
+ * reload1.c (emit_input_reload_insns, emit_output_reload_insns):
+ Call it.
+
+2003-03-03 James E Wilson <wilson@tuliptree.org>
+
+ * optabs.c (add_equal_note): Delete SUBREG_REG use.
+ Fixes PR c/7872.
+
+2003-03-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*ixorsi3_ashift_16): New.
+ (*ixorsi3_lshiftrt_16): New.
+ (*iorsi3_ashift_16): Remove.
+
+2003-03-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*extzv_8_8): Use '?' to simplify the
+ pattern.
+
+2003-03-03 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/install.texi (Specific): Update entry for powerpc-darwin.
+
+2003-03-03 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.h (HAVE_AS_LTOFFX_LDXMOV_RELOCS): Default to 0.
+
+2003-03-03 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_multipass_dfa_lookahead): Delete.
+ (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD): Delete.
+ (rs6000_variable_issue): Do not return negative value.
+ (rs6000_issue_rate): Uniformly set issue rate to 1 for first
+ scheduling pass.
+
+2003-03-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * dwarf2out.c (dwarf2out_finish): Swap order of break_out_includes and
+ prune_unused_types calls.
+
+2003-03-03 Jason Merrill <jason@redhat.com>
+
+ * tree-inline.c (find_builtin_longjmp_call): Save and restore
+ lineno and input_filename.
+ (find_alloca_call): Likewise.
+ (inlinable_function_p): Run the langhook earlier.
+
+ * calls.c (compute_argument_addresses): Give the new MEMs a
+ minimum alignment of PARM_BOUNDARY.
+
+2003-03-03 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * config/sh/sh.h (EXTRA_SPECS): Add subtarget_asm_relax_spec and
+ subtarget_asm_isa_spec.
+ (SUBTARGET_ASM_RELAX_SPEC, SUBTARGET_ASM_ISA_SPEC): Define.
+ (ASM_SPEC): Define as SH_ASM_SPEC.
+ (SH_ASM_SPEC): New; take the role of ASM_SPEC, but safe from svr4.h.
+ Use subtarget_asm_relax_spec and subtarget_asm_isa_spec.
+ * config/sh/elf.h (ASM_SPEC): Use SH_ASM_SPEC.
+ (SUBTARGET_ASM_ISA_SPEC): Undef / define.
+
+ * sh.h (OVERRIDE_OPTIONS): Set default values for align_loops
+ and align_jumps if not set.
+ Force align_jumps to be at least 2.
+ When relaxing, force align_functions to be at least the maximum of
+ align_loops, align_jumps and 4.
+ * sh.c (find_barrier, barrier_align): Honour align_jumps_log.
+ (sh_loop_align): Honour align_loops_log.
+
+ * sh.md (length attribute): Use prev_nonnote_insn instead of PREV_INSN
+ to check for indirect_jump_scratch.
+ (indirect_jump_scratch): Add second set.
+ * sh.c (output_far_jump): Use prev_nonnote_insn instead of PREV_INSN
+ when looking for indirect_jump_scratch.
+ Extract scratch register taking new structure of indirect_jump_scratch
+ into account.
+ (gen_block_redirect): Set INSN_SCOPE for indirect_jump_scratch.
+
+2003-03-03 Jan Hubicka <jh@suse.cz>
+
+ * calls.c (rtx_for_function_call): Take the address as an argument
+ (expand_call): Do not modify the expression.
+
+ * toplev.c (rest_of_compilation): Avoid cfg_cleanup calls when not
+ optimizing.
+
+2003-03-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*ixorsi3_zext_hi): Restrict to
+ TARGET_H8300H and TARGET_H8300S.
+
+2003-03-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): New.
+
+2003-03-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*extzv_8_8): Use shorter code when
+ operands[0] and operands[1] are different.
+
+2003-03-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * reload1.c (reload_cse_move2add): Remove variable success.
+
+2003-03-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ggc-common.c (ggc_rlimit_bound): Cast RLIM_INFINITY to avoid
+ warnings.
+
+2003-03-02 Richard Henderson <rth@redhat.com>
+
+ * configure.in (HAVE_AS_LTOFFX_LDXMOV_RELOCS): New ia64 test.
+ * config.in, configure: Rebuild.
+ * config/ia64/ia64.c (ia64_ld_address_bypass_p): Accept lo_sum.
+ * config/ia64/ia64.md (load_symptr): Use high/lo_sum for the
+ paired ldtoffx and ldxmov annotations.
+ (load_symptr_internal1): Remove.
+ (load_symptr_high, load_symptr_low): New.
+
+2003-03-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-incpath.c (add_path): Fix sysp assignment.
+
+2003-03-02 Kurt Garloff <garloff@suse.de>
+
+ * params.def: Introduce parameter max-inline-insns-rtl for
+ a separate limit for the RTL inliner.
+ * params.h: Likewise.
+ * integrate.c (function_cannot_inline_p): Use it.
+ * toplev.c (decode_f_option): Set multiple parameters
+ controlling inlining with -finline-limit.
+ * params.def: Fix orthographic and typographic errors.
+ * doc/invoke.texi: Document parameters controlling inlining
+ and the way -finline-limit sets multiple of them.
+
+ * tree.h (struct tree_decl): Introduce inlined_function_flag,
+ recording whether the function became eligible for inlining
+ by a compiler flag rather than the declaration.
+ Provide DID_INLINE_FUNC macro to access it.
+ * c-decl.c (grokdeclarator): Set DID_INLINE_FUNC.
+ * cp/decl.c (grokfndecl): Likewise.
+ * toplev.c (rest_of_compilation): Likewise.
+ * cp/optimize (maybe_clone_body): Copy DID_INLINE_FUNC.
+ * print-tree.c (print_node): Report it.
+ * params.def: Introduce new max-inline-insns-auto limit.
+ * params.h: Likewise.
+ * tree-inline.c (inlinable_function_p): Apply it to functions
+ with DID_INLINE_FUNC set.
+ * toplev.c (decode_f_option): Initialize it from -finline-limit
+ value.
+ * doc/invoke.texi: Document new parameter.
+
+2003-03-02 Geoffrey Keating <geoffk@apple.com>
+
+ * fix-header.c (read_scan_file): Don't reference simplify_path.
+
+2003-03-02 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (m68hc11_override_options): Don't enable
+ min/max instructions by default as may result in reload errors.
+
+2003-03-02 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("mulqi3"): Allow address register to
+ avoid reload problems; define split for it.
+
+2003-03-02 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (m68hc11_shift_operator): New function.
+ * config/m68hc11/m68hc11-protos.h (m68hc11_shift_operator): Declare.
+ * config/m68hc11/m68hc11.h (PREDICATE_CODES): Register.
+ * config/m68hc11/m68hc11.md ("rotrhi3", "rotlhi3"): New patterns for
+ rotatert and rotate.
+ ("rotrhi3_const", "rotlhi3_const"): Rename of old 'rotrhi3' insns.
+ ("*rotrhi3", "*rotlhi3"): New insn pattern for non-const rotatert.
+ ("*rotrhi3_addr"): New split for shift insns on address register.
+ ("*lshrhi3", "*ashrhi3", "*ashlhi3_2"): Use new split.
+ * config/m68hc11/larith.asm (___rotlhi3): New asm function.
+ (___rotrhi3): Likewise.
+ * config/m68hc11/t-m68hc11-gas (LIB1ASMFUNCS): Build them.
+
+2003-03-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * toplev.c (aux_base_name): Moved from toplev.h.
+ (filename): Constify.
+ (lang_dependent_init): Don't duplicate name.
+ (process_options): Set aux_base_name here, not...
+ (do_compile): ...here. Change protoype.
+ (toplev_main): Move some code from do_compile.
+ * toplev.h: Remove aux_base_name.
+
+2003-03-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add a prototype for
+ iorxor_operator.
+ * config/h8300/h8300.c (print_operand): Handle 'c'.
+ (iorxor_operator): New.
+ * config/h8300/h8300.h (PREDICATE_CODES): Add iorxor_operator.
+ * config/h8300/h8300.md (*iorhi3_zext): Remove.
+ (*iorsi3_zexthi): Likewise.
+ (*iorsi3_zextsi): Likewise.
+ (*xorhi3_zextqi): Likewise.
+ (*xorsi3_zexthi): Likewise.
+ (*xorsi3_zextsi): Likewise.
+ (*ixorhi3_zext): New.
+ (*ixorsi3_zext_qi): Likewise.
+ (*ixorsi3_zext_hi): Likewise.
+
+2003-03-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-incpath.c (remove_component_p, simplify_path): Move back to
+ cppfiles.c.
+ (remove_duplicates): Use cpp_simplify_path.
+ * c-incpath.h (simplify_path): Remove.
+ * c-lex.c: Don't include c-incpath.h.
+ (init_c_lex): Remove simplify_path.
+ * cppfiles.c (remove_component_p, cpp_simplify_path): Restore.
+ (find_or_create_entry, validate_pch): Revert.
+
+2003-03-02 Ashif Harji <asharji@uwaterloo.ca>
+
+ * gcc.c (default_compilers): Add -no-integrated-cpp flag to invoke
+ an external cpp during compilation.
+ (option_map): Likewise.
+ * objc/lang-specs.h (default_compilers): Similarly.
+ * doc/invoke.texi: Document -no-integrated-cpp flag.
+
+2003-03-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (zero_extendqisi2): Change to an
+ expander.
+ (*zero_extendqisi2_h8300): New.
+ (*zero_extendqisi2_h8300hs): New.
+ (two splitters): New.
+
+2003-03-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fp-bit.h (float_to_usi): Fix condition wrapping prototype.
+
+2003-03-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): Remove dead code.
+
+2003-03-01 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/9367
+ * builtin-types.def (DEF_FUNCTION_TYPE_VAR_3): New macro.
+ (BT_FN_INT_CONST_STRING_VALIST_ARG,
+ BT_FN_INT_STRING_CONST_STRING_VALIST_ARG,
+ BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG,
+ BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG,
+ BT_FN_INT_STRING_CONST_STRING_VAR,
+ BT_FN_INT_CONST_STRING_CONST_STRING_VAR,
+ BT_FN_INT_STRING_SIZE_CONST_STRING_VAR): New built-in types.
+ * builtin-attrs.def (ATTR_NONNULL_1, ATTR_NONNULL_2,
+ ATTR_NONNULL_3): Also include the nothrow attribute.
+ (sprintf, scanf, sscanf, vprintf, vsprintf, snprintf,
+ vsnprintf, vscanf, vsscanf): Don't define attributes here.
+ * builtins.def (putchar, puts): Make full C89 built-ins.
+ (snprintf, sprintf, scanf, sscanf, vprintf, vscanf,
+ vsscanf, vsnprintf, vsprintf): New built-ins.
+ * c-common.c (c_common_nodes_and_builtins): Handle new macro
+ DEF_FUNCTION_TYPE_VAR_3.
+
+ * doc/extend.texi: Document these new built-in functions.
+
+2003-03-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): New.
+
+2003-03-01 Richard Earnshaw <rearnsha@arm.com>
+
+ * predict.c (estimate_bb_frequencies): Correctly set
+ real_values_initialized after initialization.
+
+2003-03-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * Makefile.in (C_AND_OBJC_OBJS, c-incpath.o, c-lex.o, LIBCPP_OBJS,
+ cppinit.o, cppdefault.o, fix-header): Update.
+ * c-incpath.c: New file.
+ * c-incpath.h: New file.
+ * c-lex.c: Include c-incpath.h.
+ (init_c_lex): Register path simplifier.
+ * c-opts.c: Include cppdefault.h and c-incpath.h.
+ (TARGET_SYSTEM_ROOT, verbose, iprefix, sysroot, std_inc,
+ std_cxx_inc, quote_chain_split, add_prefixed_path): New.
+ (COMMAND_LINE_OPTIONS): Add more options from cpplib.
+ (missing_arg, c_common_decode_option): Handle them.
+ (c_common_post_options): Register include chains.
+ (print_help): Update.
+ * cppdefault.h (struct default include): Update.
+ Move some macros to ...
+ * cppdefault.c: ... here.
+ (cpp_include_defaults): Add extra field add_sysroot.
+ * cppfiles.c (include_file, search_from, find_or_create_entry,
+ cpp_included, find_include_file, remap_filename): Update for
+ renaming of search_path to cpp_path, and of the chain headers.
+ (remove_component_p, _cpp_simplify_pathname): Move to c-incpath.c.
+ * cpphash.h (struct search_path): Move to cpplib.h.
+ (struct cpp_buffer, struct cpp_reader): Update.
+ (_cpp_simplify_pathname): Remove.
+ * cppinit.c: Don't include prefix.h and cppdefault.h.
+ (INO_T_EQ, INO_T_COPY, path_include, append_include_chain,
+ remove_dup_dir, remove_dup_nonsys_dirs, remove_dup_dirs,
+ init_standard_includes, BRACKET, SYSTEM, AFTER, no_dir,
+ no_pth, cpp_handle_options): Remove.
+ (struct pending_option): Remove chain members.
+ (cpp_destroy, cpp_read_main_file, COMMAND_LINE_OPTIONS,
+ cpp_handle_option): Update.
+ * cpplib.h (struct cpp_path, cpp_set_include_chains): New.
+ (struct cpp_options): Remove quote_include, bracket_include,
+ include_prefix, include_prefix_len, verbose, ignore_srcdir,
+ no_standard_includes, no_standard_cplusplus_includes.
+ (struct cpp_callbacks): Add simplify_path.
+ (cpp_handle_options): Remove.
+ * fix-header.c: Include c-incpath.h.
+ (read_scan_file): Update to use c-incpath functionality.
+ * doc/passes.texi: Update.
+
+2003-03-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (bit_operand): Accept MEM only if it
+ satisfies EXTRA_CONSTRAINT 'U'.
+
+2003-03-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*tst_extzv_bitqi_1_n): Take a scratch
+ register.
+ (*tst_extzv_memqi_1_n): Change to a splitter.
+ (a peephole2): Update.
+
+2003-03-01 Richard Earnshaw <rearnsha@arm.com>
+
+ * predict.c (estimate_bb_frequencies): Initialize the sreal
+ constants once per compilation.
+
+2003-02-28 Richard Henderson <rth@redhat.com>
+
+ * toplev.c (flag_eliminate_unused_debug_types): Enable by default.
+
+2003-02-28 scott snyder <snyder@fnal.gov>
+
+ * flags.h: Add flag_eliminate_unused_debug_types.
+ * toplev.c: Add flag_eliminate_unused_debug_types.
+ (f_options): Add -feliminate-unused-debug-types.
+ * dwarf2out.c (struct file_table): Add emitted member.
+ (splice_child_die): Fix the parent pointer for the child being
+ spliced.
+ (lookup_filename): Maintain file_table.emitted array. Don't
+ output .file directive here.
+ (maybe_emit_file): (new)
+ (init_file_table): Set up file_table.emitted.
+ (dwarf2out_source_line): Use maybe_emit_file.
+ (dwarf2out_start_source_file): Use maybe_emit_file.
+ (dwarf2out_init): Use maybe_emit_file.
+ (prune_unused_types_walk_attribs): (new)
+ (prune_unused_types_mark): (new)
+ (prune_unused_types_walk): (new)
+ (prune_unused_types_prune): (new)
+ (prune_unused_types): (new)
+ (dwarf2out_finish): Call prune_unused_types if
+ flag_eliminate_unused_debug_types is set.
+ * doc/invoke.texi (Option Summary): Add
+ -feliminate-unused-debug-types.
+ (Debugging Options): Likewise.
+
+2003-02-28 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/invoke.texi: Change .pch to .gch.
+ * cppfiles.c (open_file_pch): Likewise.
+ * gcc.c (default_compilers): Likewise.
+
+2003-02-28 Aldy Hernandez <aldyh@redhat.com>
+
+ * floatlib.c: Remove.
+
+2003-02-28 Jason Merrill <jason@redhat.com>
+
+ * stor-layout.c (variable_size): Leave a "minus 1" outside the
+ SAVE_EXPR.
+
+2003-02-28 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/power4.md: Add compare bypass.
+
+2003-02-28 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/netbsd.h: Update copyright years.
+ (NETBSD_CPP_SPEC): Define _REENTRANT and _PTHREADS if
+ -pthread is specified on the command line.
+
+2003-02-28 Dale Johannesen <dalej@apple.com>
+
+ * loop.c (struct movable): Add insert_temp, shrink savemode.
+ (scan_loop): Accept invariants that require copying; mark as
+ insert_temp.
+ (combine_movables): Don't combine insert_temp movables.
+ (move_movables): Insert copies for insert_temp movables.
+ Don't record the info based on regno for insert_temp's.
+
+2003-02-28 Joel Sherrill <joel@OARcorp.com>
+
+ PR 9638/other
+ * config/i386/i386.c (DEFAULT_PCC_STRUCT_RETURN): Ensure the
+ this constant defaults to 1.
+
+2003-02-28 Bob Wilson <bob.wilson@acm.org>
+
+ * config.gcc (xtensa-*-linux*): Add t-slibgcc-elf-ver to tmake_file.
+
+2003-02-28 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (mulhisi3, mulhisi3addsi, mulhidi3adddi): Enable for any
+ ARMv5e processor, not just for XScale. Instructions are predicable.
+ (mulhisi3tb, mulhisi3bt, mulhisi3tt): New patterns for ARMv5e.
+
+2003-02-28 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.c (note_invalid_constants): Change parameter type
+ from bool to int.
+
+2003-02-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*tst_extzv_bitqi_1_n): Accept the
+ test of bit 7.
+ (*tst_extzv_memqi_1_n): Likewise.
+ (a peephole2): New.
+
+2003-02-28 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (CRT_CALL_STATIC_FUNCTION): Wrap in
+ #ifndef __mips16.
+
+2003-02-28 Jan Hubicka <jh@suse.cz>
+
+ * combine.c (gen_lowpart_for_combine): Update handling of
+ subregs_of_mode
+ * flow.c (life_analysis, mark_used_regs): Likewise.
+ * regclass.c (subregs_of_mode): Turn into single bitmap.
+ (cannot_change-mode_set_regs, invalid_mode_change_p): Update
+ dealing with subregs_of_mode
+ * regs.h (subregs_of_mode): Update prototype.
+
+2003-02-28 Josef Zlomek <zlomekj@suse.cz>
+
+ * emit-rtl.c (set_reg_attrs_for_parm): New function.
+ * rtl.h (set_reg_attrs_for_parm): New exported function.
+ * function.c (assign_parms): Use set_reg_attrs_for_parm instead of
+ set_reg_attrs_from_mem.
+
+2003-02-27 Roger Sayle <roger@eyesopen.com>
+ Zack Weinberg <zack@codesourcery.com>
+
+ * gcc.c (do_spec_1): Treat %U like %u for unique associations.
+
+2003-02-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * reload1.c (sext_for_mode): Remove.
+ (reload_cse_move2add): Use trunc_int_for_mode instead of
+ sext_for_mode.
+ (move2add_note_store): Likewise.
+ Reset register information if we see a set in non-integer
+ mode.
+
+2003-02-27 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/aix43.h (ASM_SPEC): Only emit -mppc64 if no -mcpu
+ option.
+ (ASM_CPU_SPEC): Use -m620 for Power3, Power4, 620, 630.
+ * config/rs6000/aix51.h: Same.
+ * config/rs6000/aix52.h: Same.
+ * config/rs6000/power4.md: Additional VMX bypasses.
+
+2003-02-27 Geert Bosch <bosch@gnat.com>
+
+ * toplev.c (print_version): Add indentation for GGC heuristics and
+ output after printing version information.
+
+2003-02-27 James E Wilson <wilson@tuliptree.org>
+
+ * combine.c (simplify_comparison): Require integral mode when
+ permuting SUBREG with AND.
+
+2003-02-27 Steve Ellcey <sje@cup.hp.com>
+
+ * config/ia64/hpux.h (STARTFILE_PREFIX_SPEC): Remove.
+
+2003-02-27 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.md (extendsfdf2): Add pattern accidentally
+ deleted when cirrus instructions were added.
+
+2003-02-27 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config.gcc (*-*-netbsd[2-9]*, *-*-netbsdelf[2-9]*): Enable
+ POSIX thread support by default.
+
+2003-02-27 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/cygwin.h: Don't include any other files directly.
+ * config/i386/mingw32.h: Don't include cygwin.h directly.
+ * config.gcc (cygwin, mingw32, uwin): Instead make these files
+ explicit in the tm_files variable.
+
+2003-02-27 Alan Modra <amodra@bigpond.net.au>
+
+ * config/rs6000/rs6000.md: Add TI constant splitter.
+
+2003-02-26 Alexandre Oliva <aoliva@redhat.com>
+
+ * builtins.c (purge_builtin_constant_p): Handle subreg of
+ constant_p_rtx too.
+
+ * function.c (assign_stack_local_1): Truncate constant added to
+ frame_pointer_rtx or virtual_stack_vars_rtx for Pmode.
+
+2003-02-26 David Edelsohn <edelsohn@gnu.org>
+
+ * config.gcc: Add power4 to PowerPC with_cpu list.
+
+2003-02-26 Jan Hubicka <jh@suse.cz>
+
+ * objc-act.c: (mark_referenced_methods): Fix compilation problem.
+
+2003-02-26 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * gcov-dump.c (print_prefix): Fix signedness warning.
+ * gcov-io.h (struct counter_section, struct counter_section_data): New.
+ (struct function_info): n_arc_counts field removed, n_counter_sections,
+ counter_sections fields added.
+ (struct gcov_info): arc_counts, n_arc_counts fields removed,
+ n_counter_sections, counter_sections fields added.
+ * libgcov.c (gcov_exit, __gcov_flush): Add support for multiple
+ profile sections.
+ * profile.h (MAX_COUNTER_SECTIONS): New.
+ (struct section_info): New.
+ (struct profile_info): count_instrumented_edges,
+ count_edges_instrumented_now fields removed, n_sections, section_info
+ fields added.
+ (find_counters_section): Declare.
+ * profile.c (struct function_list): count_edges field removed,
+ n_counter_sections, counter_sections fields added.
+ (set_purpose, label_for_tag, build_counter_section_fields,
+ build_counter_section_value, build_counter_section_data_fields,
+ build_counter_section_data_value, build_function_info_fields,
+ build_function_info_value, build_gcov_info_fields,
+ build_gcov_info_value): New static functions.
+ (find_counters_section): New function.
+ (instrument_edges, get_exec_counts, compute_branch_probabilities,
+ branch_prob, create_profiler): Modified to support multiple profile
+ sections.
+
+2003-02-26 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (compute_frame_size): Don't assume PREFERRED_STACK_BOUNDARY
+ is 8 * STACK_BOUNDARY.
+ * pa.h (PREFERRED_STACK_BOUNDARY): Change to 128 on 64-bit port.
+
+2003-02-26 Michael Matz <matz@suse.de>
+
+ * ra-colorize.c (merge_moves): Fix list handling.
+
+2003-02-26 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.c (is_load_address): Rename to...
+ (arm_memory_load_p) ... this and make it check for SUBREGs and
+ constant loads that will be converted into loads from the
+ minipool.
+ (is_cirrus_insn): Rename to ...
+ (arm_cirrus_insn_p): ... this, for consistency. Replace test
+ of CIRRUS_NO with CIRRUS_NOT.
+ (cirrus_reorg): Use renamed functions.
+ (note_invalid_constants): Change from a void function to bool.
+ Add an extra parameter, saying whether the fixups should be
+ pushed. Return true if fixups are needed.
+ (arm_reorg): Use renamed functions. Use INSN_P. Replace test
+ of CIRRUS_NO with CIRRUS_NOT.
+ * config/arm/arm.h (FLOAT_WORDS_BIG_ENDIAN): Mention that
+ other floating point co-processors can also affect this.
+ * config/arm/arm.md ("type" attribute): Add mav_farith and
+ mav_dmult. Replace references to "cirrus_type" attribute with
+ "type".
+ * config/arm/cirrus.md ("cirrus_fpu" attribute): Delete.
+ ("cirrus_type" attribute): Delete - use "type" instead.
+ ("cirrus" attribute): Replace 'no' with 'not' and 'yes' with
+ 'normal'.
+
+2003-02-25 Jan Hubicka <jh@suse.cz>
+
+ * objc-act.c: Include cgraph.h
+ (mark_referenced_methods): New function.
+ (objc_init): Call it.
+ * objc-lang.c (LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION): Set.
+
+ * c-decl.c (finish_function): Honor can_defer_p even in unit-at-a-time
+ mode.
+
+ * optabs.c (expand_fix): Do not widen the input operand.
+
+ * expr.c (emit_group_store): Fix crash when converting single
+ register into complex register.
+
+ * Makefile.in (jump.o, regclass.o, alias.o): Add dependency on timevar.h
+ * alias.c: Include timevar.h
+ (init_alias_analysis): Set timevar
+ * jump.c: Include timevar.h
+ (rebuild_jump_labels): Set timevar
+ * regcalss.c: Include timevar.h
+ (reg_scan): Set timevar
+ * timevar.def (TV_ALIAS_ANALYSIS, TV_REG_SCAN, TV_REBUILD_JUMP): New
+
+2003-02-26 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cse.c (count_reg_usage): Fix handling of REG_EQUAL notes.
+
+ * Makefile.in (loop-unroll.o): New.
+ * cfgloop.h (UAP_PEEL, UAP_UNROLL, UAP_UNROLL_ALL): New.
+ (unroll_and_peel_loops): Declare.
+ * alias.c (init_alias_analysis): Flag_unroll_loops renamed to
+ flag_old_unroll_loops.
+ * loop.c (loop_invariant_p): Ditto.
+ * unroll.c (unroll_loop): Flag_unroll_all_loops renamed to
+ flag_old_unroll_all_loops.
+ * flags.h (flag_unroll_loops): Renamed to flag_old_unroll_loops.
+ (flag_unroll_all_loops): Renamed to flag_old_unroll_all_loops.
+ * params.def (PARAM_MAX_UNROLLED_INSNS): Default value changed.
+ (PARAM_MAX_AVERAGE_UNROLLED_INSNS, PARAM_MAX_UNROLL_TIMES,
+ PARAM_MAX_PEELED_INSNS, PARAM_MAX_PEEL_TIMES,
+ PARAM_MAX_COMPLETELY_PEELED_INSNS, PARAM_MAX_COMPLETELY_PEEL_TIMES,
+ PARAM_MAX_ONCE_PEELED_INSNS): New.
+ * toplev.h (flag_old_unroll_loops, flag_old_unroll_all_loops): New.
+ (flag_unroll_loops, flag_unroll_all_loops): Used for new unroller
+ instead of old one.
+ (flag_peel_loops): New.
+ (lang_independent_options): The new flags added.
+ (rest_of_compilation): Call new unroller.
+ (process_options): Setup flags for coexistence of old and new unroller.
+ * doc/invoke.texi: Document new options.
+ * doc/passes.texi: Document new unroller pass.
+
+2003-02-26 David Billinghurst <David.Billinghurst@riotinto.com>
+
+ * fixinc/fixincl.x: Regenerate
+
+2003-02-26 Josef Zlomek <zlomekj@suse.cz>
+
+ * function.c (assign_parms): Set reg_attrs for parameters passed in
+ registers.
+
+2003-02-26 Alan Modra <amodra@bigpond.net.au>
+
+ PR target/9681
+ * tlink.c (scan_linker_output): Drop leading '.' from symbol names.
+
+2003-02-25 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/xcoff.h (ASM_FILE_START): Do not emit machine
+ pseudo-op.
+
+2003-02-25 Roger Sayle <roger@eyesopen.com>
+
+ * combine.c (combine_simplify_rtx, simplfy_comparison): Use CC0_P.
+ * cse.c (invalidate_skipped_set): Likewise.
+ * integrate.c (subst_constants): Likewise.
+ * jump.c (reversed_comparison_code_parts): Likewise.
+ * loop.c (canonicalize_condition): Likewise.
+ * simplify-rtx.c (simplify_relational_operation): Likewise.
+
+2003-02-25 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def (DEF_LIB_ALWAYS_BUILTIN, DEF_UNUSED_BUILTIN): Delete.
+ (abs, labs, fabs, fabsf, fabsl, abort, exit, _exit, _Exit): Use
+ the appropriate macro to define built-in function.
+ (fmod,fmodf,fmodl): New built-in functions.
+
+ * doc/extend.texi (fmod,fmodf,fmodl): Document new built-ins.
+
+2003-02-25 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (function_arg): Pass variable sized
+ structures correctly on the stack.
+
+2003-02-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * reload1.c (reload_cse_move2add): Use STRICT_LOW_PART if PLUS
+ does not reduce the cost of SET.
+
+2003-02-25 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR target/9732
+ * config/rs6000/rs6000.c (first_reg_to_save): Handle
+ PIC_OFFSET_TABLE_REGNUM for -fPIC too.
+ (rs6000_emit_prologue): Likewise.
+ (rs6000_emit_epilogue): Likewise.
+ * config/rs6000/rs6000.h (CONDITIONAL_REGISTER_USAGE): Make
+ PIC_OFFSET_TABLE_REGNUM a fixed register for -fPIC.
+
+2003-02-25 Richard Henderson <rth@redhat.com>
+
+ * real.c (real_to_integer2): Force overflow result only for
+ unsigned overflow.
+
+2003-02-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gcse.c (cprop_jump): Revert the 2003-02-23 change.
+
+2003-02-25 Vladimir Makarov <vmakarov@toke.toronto.redhat.com>
+ Richard Henderson <rth@redhat.com>
+
+ * sched-ebb.c (add_deps_for_risky_insns): Add the dependence when
+ there is no similar load.
+
+2003-02-25 Vladimir Makarov <vmakarov@redhat.com>
+ Richard Henderson <rth@redhat.com>
+
+ * sched-int.h (INSN_TRAP_CLASS, WORST_CLASS): Move them from
+ sched-rgn.c.
+ (add_forward_dependence): New function prototype.
+
+ * sched-rgn.c (INSN_TRAP_CLASS, WORST_CLASS): Move them to
+ sched-init.h.
+ (CONST_BASED_ADDRESS_P, may_trap_exp, haifa_classify_insn): Move
+ them to haifa-sched.c.
+
+ * haifa-sched.c (CONST_BASED_ADDRESS_P, may_trap_exp,
+ haifa_classify_insn): Move them from sched-rgn.c.
+
+ * sched-deps.c (add_dependence): Return flag of creating a new
+ entry.
+ (add_forward_dependence): New function.
+ (compute_forward_dependences): Use the function.
+
+ * sched-ebb.c (earliest_block_with_similiar_load): New function.
+ (add_deps_for_risky_insns): New function.
+ (schedule_ebb): Call the function.
+
+2003-02-20 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/tm.texi: Document Rename TARGET_VECTOR_TYPES_COMPATIBLE to
+ TARGET_VECTOR_OPAQUE_P. Document accordingly.
+
+ * testsuite/gcc.dg/20030218-1.c: Check that initialization of
+ opaque types fail.
+
+ * c-typeck.c (comptypes): Change call to vector_types_compatible
+ to vector_opaque_p.
+ (convert_for_assignment): Call vector_opaque_p instead of
+ vector_types_compatible.
+ (really_start_incremental_init): Disallow initialization of opaque
+ types.
+
+ * target-def.h: Remove TARGET_VECTOR_TYPES_COMPATIBLE.
+ Define TARGET_VECTOR_OPAQUE_P.
+ (TARGET_INITIALIZER): Same.
+
+ * target.h (struct gcc_target): Remove vector_types_compatible.
+ Add vector_opaque_p.
+
+ * config/rs6000/rs6000.c (rs6000_spe_vector_types_compatible):
+ Remove.
+ (is_ev64_opaque_type): Check for TARGET_SPE and make sure type is
+ a vector type. Change return type to bool.
+ (TARGET_VECTOR_TYPES_COMPATIBLE): Remove.
+ (TARGET_VECTOR_OPAQUE_P): Define.
+
+ * cp/parser.c (cp_parser_init_declarator): Call vector_opaque_p
+ target hook.
+ Include target.h.
+ (cp_parser_init_declarator): Fix typo in function comments.
+
+2003-02-25 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (lcm.o): Add dependency on function.h
+ * lcm.c (function.h): Include.
+ * i386.c (machine_function, ix86_stack_locals,
+ * ix86_save_varrargs_registers) : Move to
+ ...
+ * i386.h (machine_function, ix86_stack_locals,
+ ix86_save_varrargs_registers): ... here; add optimize_mode_switching
+ (ix86_optimize_mode_switching): New.
+ * i386.md (fix patterns): Set ix86_optimize_mode_switching
+
+2003-02-25 Nick Clifton <nickc@redhat.com>
+
+ * config/d30v/d30v.c (d30v_init_cumulative_args): Fix typo. Name
+ of fourth arg is 'fndecl' not 'indirect'. Update comment
+ describing the function's parameters.
+
+2003-02-24 Jan Hubicka <jh@suse.cz>
+
+ * combine.c (simplify_shift_const): Fix previous patch.
+
+2003-02-24 Jeff Law <law@redhat.com>
+
+ * i386.md (testdi_1_rex64): Discourage reload from using the %eax
+ alternative.
+ (testsi_1, testhi_1, testqi_1): Likewise.
+
+2003-02-24 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/alpha/osf.h (TARGET_OS_CPP_BUILTINS): Rename
+ __EXTERN_PREFIX to __PRAGMA_EXTERN_PREFIX.
+ * doc/extend.texi (Tru64 Pragmas): Reflect this.
+
+ * fixinc/inclhack.def (alpha___extern_prefix): Indicate #pragma
+ extern_prefix support for Tru64 UNIX V5 <sys/stat.h>.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/sys/stat.h [ALPHA___EXTERN_PREFIX_CHECK]: New
+ testcase.
+ Fixes PR c/5059, c/6126, other/9671.
+
+2003-02-24 Roger Sayle <roger@eyesopen.com>
+
+ * gcc.c (do_spec_1) ['{']: Handle pending argument upon return
+ from handle_braces in "%{...}".
+
+2003-02-24 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (TARGET_HAVE_TLS): Conditionally define.
+ (prepare_move_operands): Handle TLS operands.
+ (tls_symbolic_operand): New.
+ (nonpic_symbol_mentioned_p): Handle TLS UNSPECs.
+ (legitimize_pic_address): Do nothing for the TLS symbol.
+ (sh_encode_section_info): Handle TLS case.
+ (sh_strip_name_encoding): Drop TLS encoding.
+ * config/sh/sh-protos.h (tls_symbolic_operand): Add prototype.
+ * config/sh/sh.h (SH_TLS_ENCODING): Define.
+ (TLS_SYMNAME_P, STRIP_TLS_ENCODING): Likewise.
+ (ASM_OUTPUT_LABELREF): Drop TLS encoding.
+ (OUTPUT_ADDR_CONST_EXTRA): Handle TLS UNSPECs.
+ * config/sh/sh.md: Define TLS UNSPEC constants.
+ (type): Add tls_load.
+ ("tls_global_dynamic", "tls_local_dynamic"): New insns.
+ ("sym2DTPOFF", "symDTPOFF2reg", "sym2GOTTPOFF"): New expanders.
+ ("tls_initial_exec"): New insn.
+ ("sym2TPOFF", "symTPOFF2reg"): New expanders.
+ ("load_gbr"): New insn.
+
+ * configure.in (HAVE_AS_TLS): Add sh-*-* and sh[34]*-*-* cases.
+ * configure: Regenerate.
+
+2003-02-24 Alan Modra <amodra@bigpond.net.au>
+
+ PR 9297, PR 9722
+ * calls.c (store_one_arg): Revert 1999-02-16 change. Revert
+ 2000-12-17 change. Pass EXPAND_STACK_PARM to expand_expr.
+ * expr.h (enum expand_modifier): Define EXPAND_STACK_PARM.
+ (enum block_op_methods): Reorder for better store_expr optimization.
+ * expr.c (store_expr): Test bit 1 of "want_value" for call param
+ stores, test bit 0 for original want_value meaning. Pass
+ BLOCK_OP_CALL_PARM to emit_block_move when bit 1 set. Adjust
+ recursive calls, and calls to expand_param.
+ (expand_expr): Handle EXPAND_STACK_PARM modifier. When cse
+ expected, set target to 0 rather than to subtarget. Formatting.
+
+2003-02-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gcse.c (cprop_jump): Use the REG_EQUAL note if available.
+
+2003-02-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * doc/invoke.texi (ggc-min-expand, ggc-min-heapsize): Document
+ new default behavior.
+ * ggc-common.c: Include sys/resource.h.
+ (ggc_rlimit_bound): New function.
+ (ggc_min_expand_heuristic, ggc_min_heapsize_heuristic): Update
+ defaults to account for rlimits.
+
+2003-02-22 Richard Henderson <rth@redhat.com>
+
+ * i386.c, i386.h (TUNEMASK): Rename from CPUMASK.
+
+2003-02-22 Kelley Cook <kelley@dwhoops.info>
+
+ * i386.h, i386.c, i386.md (ix86_tune): Rename from ix86_cpu.
+ (ix86_tune_string): Rename from ix86_cpu_string.
+
+2003-02-22 Kelley Cook <kelleycook@comcast.net>
+
+ * config/i386/i386.c: Replace "mcpu" with "mtune".
+ * config/i386/i386.h (TARGET_OPTIONS): Likewise.
+ (CC1_CPU_SPEC): Likewise. New warning for "-mcpu".
+ * doc/invoke.texi (i386 and x86-64 Options): Replace "mcpu"
+ with "mtune". Note that "mcpu" is a deprecated synonym for "mtune".
+
+2003-02-23 Andreas Schwab <schwab@suse.de>
+
+ * config.gcc: Delete references to m68k/t-linux and
+ m68k/t-linux-aout.
+ * config/m68k/t-linux, config/m68k/t-linux-aout: Removed.
+
+2003-02-22 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (rest_of_compilation): Apply fotgotten hunk
+ of track scheduling patch.
+
+2003-02-22 Jan Hubicka <jh@suse.cz>
+
+ * config/linux.h (TARGET_HAS_F_SETLKW): Define.
+ * config/alpha/linux.h (TARGET_HAS_F_SETLKW): Likewise
+
+2003-02-22 Jan Hubicka <jh@suse.cz>
+
+ * c-decl.c (c_expand_body_1): Fix.
+
+2003-02-22 Jan Hubicka <jh@suse.cz>
+
+ * expmed.c (expand_divmod): Undo sign extensions for unsigned operands
+
+ * cfgcleanup.c (try_forward_edges): Don't check loop structures
+ when not optimizing.
+ (cleanup_cfg): Do not iterate trought delete_trivially_dead_insns
+ when not expensive.
+ * toplev.c (rest_of_compilation): Duplicate loop headers only when
+ optimizing; Delete trivially dead insns early; fix optimize check.
+
+ * Makefile.in (c-decl.o, c-objc-common.o, cgraph.o, tree-inline.o): Add
+ dependency on cgraph.h
+ * c-decl.c: Include cgraph.h
+ (finish_function): Update call of tree_inlinable_function_p.
+ * c-objc-common.c: Include cgraph.h
+ * cgraph.h: New file.
+ * cgraphunit.c: New file.
+ * cgraph.c (cgraph_node, cgraph_edge): Move into cgraph.h
+ (cgraph_nodes, cgraph_n_nodes): Globalize.
+ (cgraph_finalize_function, cgraph_finalize_compilation_unit
+ cgraph_create_edges, cgraph_optimize, cgraph_mark_needed_node):
+ Move into cgraphunit.c
+ * tree-inline.c: Include cgraph.h
+ * tree-inline.c: Include cgraph.h
+
+2003-02-22 Josef Zlomek <zlomekj@suse.cz>
+
+ * config/i386/i386.md: Use gen_lowpart instead of gen_rtx_REG
+ for copying a register.
+
+2003-02-22 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ PR other/3782
+ * toplev.c (process_options): If flag_detailed_statistics is set,
+ then set time_report as well.
+
+ PR c/8828
+ * jump.c (never_reached_warning): Don't fall through BARRRIER
+ insns. Update comments to reflect what the function really does.
+
+2003-02-21 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (omit_one_operand): No longer static.
+ * tree.h (omit_one_operand): Prototype here.
+ (div_and_round_double): Keep fold-const.c prototypes together.
+ * builtins.c (builtin_mathfn_code): Handle binary built-in
+ funtions, such as "pow" and "atan2".
+ (fold_builtin): Optimize both pow(x,0.0) and pow(1.0,y) to 1.0.
+ Simplify optimizations using "type" the builtin's return type.
+
+2003-02-22 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/cris/cris.c (cris_rtx_costs): Blockify dangling else.
+ Fix functionalization typo.
+
+ * regmove.c (optimize_reg_copy_1): Do not replace a hard register
+ in an asm.
+
+2003-02-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (ggc-common.o): Depend on $(PARAMS_H)
+ * doc/invoke.texi (ggc-min-expand, ggc-min-heapsize): Update
+ documentation.
+ * ggc-common.c: Include params.h
+ (ggc_min_expand_heuristic, ggc_min_heapsize_heuristic,
+ init_ggc_heuristics): New functions.
+ * ggc.h (ggc_min_expand_heuristic, ggc_min_heapsize_heuristic,
+ init_ggc_heuristics): Prototype.
+ * toplev.c (print_version): Output GGC heuristics.
+ (parse_options_and_default_flags): Call init_ggc_heuristics.
+
+2003-02-22 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (def_builtin): Special case 64bit builtins.
+ (MASK_SSE164, MASK_SSE264): New constants.
+ (builtin_description): Add 64bit builtins.
+ (ix86_init_mmx_sse_builtins): Likewise.
+ * i386.h (enum ix86_builtins): Likewise.
+ * i386.md (cvtss2siq, cvttss2siq, cvtsd2siq, cvttsd2siq, cvtsi2sdq,
+ sse2_movq2dq_rex64, sse2_movsq2q_rex64): New.
+ (sse2_movq2dq, sse2_movsq2q): Disable for 64bit.
+ * mmintrin.h (_mm_cvtsi64x_si64, _mm_set_pi64x, _mm_cvtsi64_si64x): New.
+ * xmmintrin.h (_mm_cvtss_si64x, _mm_cvttss_si64x, _mm_cvtsi64x_ss,
+ _mm_set_epi64x, _mm_set1_epi64x, _mm_cvtsd_si64x, _mm_cvttsd_si64x,
+ _mm_cvtsi64x_sd, _mm_cvtsi64x_si128, _mm_cvtsi128_si64x): New.
+
+2003-02-22 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (builtin_description): Add __builtin_ia32_paddq and
+ __builtin_ia32_psubq. Fix __builtin_ia32_paddq128
+ and __builtin_ia32_psubq128.
+ * i386.h (IX86_BUILTIN_PADDQ, IX86_BUILTIN_PSUBQ): New.
+ * i386.md (addv*, mmx_ior*, mmx_xoe*, mmx_and*): Add missing '%'.
+ (mmx_adddi3, mmx_subdi3): New.
+ * mmintrin.h (_mm_add_si64, _mm_sub_si64): New.
+ * xmmintrin.h (_mm_movepi64_pi64): New.
+ (_mm_add_epi64, _mm_sub_epi64): fix.
+ (_mm_mul_pu16): Rename to...
+ (_mm_mul_su32): ... this one.
+
+ * builtins.c (expand_builtin_expect): Do not predict
+ flag_guess_branch_prob is not set.
+ * c-semantics.c (expand_stmt): Likewise.
+ * predict.c (predict_insn): Likewise.
+ * stmt.c (expand_continue_loop): Likewise.
+ * toplev.c (rest_of_compilation): Do not call
+ note_prediction_to_br_prob and note_prediction_to_br_prob
+ when not optimizing.
+
+2003-02-21 Jan Hubicka <jh@suse.cz>
+
+ * cfgrtl.c (commit_edge_insertions): Call
+ find_many_sub_basic_block only when some code has been emitted.
+ (commit_edge_insertions_watch_calls): Bring into sync with
+ commit_edge_insertions
+
+2003-02-21 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.h (OVERRIDE_OPTIONS): Fix code that clears 'e' register class.
+
+ * sh.md (binary_sf_op): Use extra constant operand instead of
+ negating constant operand 4.
+ * sh.c (sh_expand_binop_v2sf): Supply it.
+
+2003-02-21 Zack Weinberg <zack@codesourcery.com>
+
+ * cpphash.h (struct lexer_state): Add directive_wants_padding.
+ * cpplib.c (_cpp_handle_directive): Set directive_wants_padding
+ for directives of type INCL.
+ (glue_header_name, parse_include): Use get_token_no_padding.
+ * cppmacro.c (replace_args): If directive_wants_padding,
+ provide padding tokens.
+
+2003-02-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): New.
+
+2003-02-21 Jan Hubicka <jh@suse.cz>
+
+ * cfgrtl.c (commit_one_edge_insertion): Only mark BB for splitting.
+ (commit_edge_insertions): Call find_many_sub_basic_blocks
+
+ * reg-stack.c (convert_regs): Cleax aux for blocks.
+
+2003-02-21 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (parse_options_and_default_flags): Undo accidental commit.
+
+2003-02-21 Glen Nakamura <glen@imodulo.com>
+
+ PR optimization/8613
+ * builtins.c (expand_builtin): Emit postincrements before expanding
+ builtin functions.
+
+2003-02-21 Ben Elliston <bje@redhat.com>
+
+ PR other/5634
+ * doc/install.texi (Configuration): Explain using $HOME instead of
+ the ~ metacharacter when referring to home directories.
+
+2003-02-20 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure.in (TARGET_SYSTEM_ROOT): Set default to
+ ${exec_prefix}/${target_alias}/sys-root. Match explicit
+ '${exec_prefix}' (in addition to the expansion thereof) as
+ relocatable.
+ * configure: Rebuilt.
+
+2003-02-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (addhi3_incdec): Change the name to
+ *addhi3_incdec.
+ (addsi3_incdec): Change the name to *addsi3_incdec.
+
+2003-02-20 Roger Sayle <roger@eyesopen.com>
+
+ * explow.c (force_reg): Avoid useless REG_EQUAL notes.
+
+2003-02-20 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ PR fortran/9038
+ * c-opts.c (sanitize_cpp_opts): Add Fortran front end
+ options to be ignored.
+ (c_common_decode_option): Ignore them when preprocessing.
+
+2003-02-20 Jan Hubicka <jh@suse.cz>
+
+ * toplev.c (flag_sched2_use_superblocks, flag_sched2_use_traces): New
+ global variables.
+ (lang_independent_options): Add -fsched2-use-superblocks
+ -fsced2-use-traces.
+ (rest_of_compilation): Deal with it.
+ * invoke.texi (-fsched2-use-traces, fsched2-use-superblocks): Declare.
+ * flags.h (flag_sched2_use_superblocks, flag_sched2_use_traces):
+ Declare.
+ * rtl.h (reg_to_stack): Update prototype.
+ * reg-stack.c (reg_to_stack): Return when something has changed;
+ update liveness when executing after superblock scheduling.
+
+ * combine.c (simplify_shift_const): Simplify few special cases
+ into constants.
+
+2003-02-20 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md: (attr "type"): Add fast_compare.
+ (add.,subf.,neg.): Change attribute to fast_compare.
+ All DFA descriptions updated.
+
+2003-02-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ Change base class access representation.
+ * tree.h (TREE_VIA_PUBLIC, TREE_VIA_PROTECTED,
+ TREE_VIA_PRIVATE): Remove.
+ (BINFO_BASEACCESSES): New binfo elt.
+ (BINFO_BASEACCESS): New accessor.
+ (BINFO_ELTS): Increase.
+ (TI_ACCESS_PUBLIC, TI_ACCESS_PROTECTED, TI_ACCESS_PRIVATE): New.
+ (access_public_node, access_protected_node,
+ access_private_node): New global nodes.
+ * tree.c (build_common_tree_nodes_2): Initialize access nodes.
+ * dbxout.c (dbxout_type): Adjust.
+ * dwarf2out.c (gen_inheritance_die): Add access parameter.
+ (gen_member_die): Adjust.
+ * dwarfout.c (output_inheritance_die): ARG is array of two trees.
+ (output_type): Adjust.
+ * tree-dump.c (dequeue_and_dump): Adjust binfo dumping.
+
+ Change base class access representation. Share virtual base
+ binfos.
+ * cp/call.c (build_special_member_call): Remove binfo_for_vbase
+ call.
+ * cp/class.c (build_base_path): Likewise.
+ (build_primary_vtable): Adjust BINFO_NEW_VTABLE_MARKED use.
+ (build_secondary_vtable): Remove FOR_TYPE arg. Adjust.
+ (make_new_vtable): Adjust.
+ (force_canonical_binfo_r): Delete.
+ (force_canonical_binfo): Delete.
+ (mark_primary_virtual_base): Delete.
+ (dfs_unshared_virtual_bases): Delete.
+ (mark_primary_bases): Adjust.
+ (maybe_warn_about_overly_private_class): Adjust.
+ (dfs_base_derived_from): Delete.
+ (base_derived_from): Follow the inheritance chain.
+ (struct find_final_overrider_data): Add vpath member.
+ (dfs_find_final_overrider): Adjust.
+ (dfs_find_final_overrider_q, dfs_find_final_overrider_post): New.
+ (find_final_overrider): Adjust.
+ (update_vtable_entry_for_fn): Adjust.
+ (modify_all_vtables): Adjust.
+ (walk_subobject_offsets): Adjust.
+ (layout_nonempty_base_or_field): Adjust.
+ (layout_empty_base): Remove last parameter. Adjust.
+ (build_base_field): Adjust.
+ (build_base_fields): Adjust.
+ (propagate_binfo_offsets): Remove last parameter. Adjust.
+ (dfs_set_offset_for_unshared_vbases): Delete.
+ (layout_virtual_bases): Adjust.
+ (finish_struct_1): Adjust.
+ (init_class_processing): Don't init access nodes.
+ (dfs_get_primary_binfo): Delete.
+ (get_primary_binfo): Adjust.
+ (dump_class_hierarchy_r): Remove most derived arg, add IGO
+ parameter. Adjust.
+ (dump_class_hierarchy): Adjust.
+ (finish_vtbls): Adjust.
+ (get_original_base): Delete.
+ (build_vtt_inits): Adjust.
+ (dfs_build_secondary_vptr_vtt_inits): Adjust.
+ (dfs_ctor_vtable_bases_queue_p): Adjust.
+ (build_ctor_vtbl_group): Adjust.
+ (dfs_accumulate_vtbl_inits): Adjust.
+ (build_vtbl_initializer): Adjust.
+ (build_vbase_offset_vtbl_entries): Adjust.
+ (add_vcall_offset_vtbl_entries_1): Adjust.
+ * cp/cp-tree.h (CPTI_ACCESS_*): Remove.
+ (access_*_node): Remove.
+ (CANONICAL_BINFO): Delete.
+ (BINFO_UNSHARED_MARKED): Remove.
+ (BINFO_MARKED): Set LANG_FLAG_0 directly.
+ (SET_BINFO_MARKED, CLEAR_BINFO_MARKED): Delete.
+ (BINFO_VTABLE_PATH_MARKED): Set LANG_FLAG_3 directly.
+ (SET_BINFO_VTABLE_PATH_MARKED, CLEAR_BINFO_VTABLE_PATH_MARKED):
+ Delete.
+ (BINFO_NEW_VTABLE_MARKED): Set LANG_FLAG_4 directly.
+ (SET_BINFO_NEW_VTABLE_MARKED): Adjust.
+ (SET_BINFO_PUSHDECLS_MARKED, CLEAR_BINFO_PUSHDECLS_MARKED):
+ Delete.
+ (BINFO_DEPENDENT_BASE_P): New.
+ (dfs_walk, dfs_walk_real): Queue function takes derived binfo and
+ index.
+ (markedp, unmarkedp): Adjust.
+ (dfs_unmarked_real_bases_queue_p, dfs_marked_real_bases_queue_p,
+ dfs_skip_vbases, marked_vtable_pathp, unmarked_vtable_pathp,
+ find_vbase_instance, binfo_for_vbase): Delete.
+ (copied_binfo, original_binfo): Declare.
+ (finish_base_specifier): Add virtual_p arg.
+ (unshare_base_binfos): Delete.
+ (copy_base_binfos): Declare.
+ (reverse_path): Delete.
+ * cp/decl.c (xref_basetypes): Access and virtuality passed
+ differently. Don't copy direct base binfos here. Call
+ copy_base_binfos.
+ * cp/init.c (dfs_initialize_vtbl_ptrs): Adjust.
+ (initialize_vtbl_ptrs): Adjust.
+ (expand_member_init): Adjust.
+ * cp/parser.c (cp_parser_base_specifier): Adjust.
+ * cp/pt.c (instantiate_class_template): Adjust.
+ (get_template_base_recursive): Adjust.
+ * cp/rtti.c (get_pseudo_ti_init): Adjust.
+ (get_pseudo_ti_desc): Adjust.
+ * cp/tree.c (unshare_base_binfos): Rename to ...
+ (copy_base_binfos): ... here, reimplement.
+ (make_binfo): Set BINFO_DEPENDENT_BASE_P.
+ (reverse_path): Remove.
+ * cp/typeck.c (get_delta_difference): Adjust error messages.
+ * cp/semantics.c (finish_base_specifier): Add virtual arg, adjust.
+ * cp/search.c (lookup_base_r): Adjust.
+ (dynamic_cast_base_recurse): Adjust.
+ (canonical_binfo): Remove.
+ (dfs_canonical_queue): Remove.
+ (dfs_assert_unmarked_p): Remove.
+ (assert_canonical_unmarked): Remove.
+ (shared_marked_p, shared_unmarked_p): Remove.
+ (BINFO_ACCESS, SET_BINFO_ACCESS): Use TREE_PUBLIC & TREE_PRIVATE.
+ (dfs_access_in_type): Adjust.
+ (access_in_type): Adjust.
+ (dfs_accessible_queue_p): Adjust.
+ (dfs_accessible_p): Adjust.
+ (is_subobject_of_p_1, is_subobject_of_p): Remove.
+ (struct lookup_field_info): Remove from_dep_base_p field.
+ (lookup_field_queue_p): Adjust, test BINFO_DEPENDENT_BASE_P.
+ (lookup_field_r): Remove dependent base code.
+ (lookup_member): Likewise.
+ (dfs_walk, dfs_walk_real): Add access arg to queue fn.
+ (dfs_unmarked_real_bases_queue_p): Remove.
+ (dfs_marked_real_bases_queue_p): Remove.
+ (dfs_skip_vbases): Remove.
+ (dfs_get_pure_virtuals): Adjust.
+ (markedp, unmarkedp): Adjust.
+ (marked_vtable_pathp, unmarked_vtable_pathp): Remove.
+ (marked_pushdecls_p, unmarked_pushdecls_p): Adjust.
+ (dfs_unmark): Adjust.
+ (dfs_get_vbase_types):Remove.
+ (dfs_build_inheritance_graph_order): Remove.
+ (get_vbase_types): Remove
+ (dfs_find_vbase_instance): Remove.
+ (find_vbase_instance): Remove.
+ (dfs_debug_unmarkedp): Adjust.
+ (dependent_base_p): Remove.
+ (dfs_push_type_decls): Adjust.
+ (dfs_push_decls): Adjust.
+ (dfs_no_overlap_yet): Adjust.
+ (copied_binfo): New function.
+ (original_binfo): New function.
+ (binfo_for_vbase): Remove.
+
+ Change base class access representation.
+ * java/class.c (set_super_info): Don't set TREE_VIA_PUBLIC.
+ (add_interface_do): Likewise.
+
+2003-02-20 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/sysv4.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Define.
+ * config/rs6000/power4.md (power4-store,power4-vecstore): New
+ insn reservations.
+ (power4-fpstore): Compact.
+
+2003-02-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*iorsi3_w): New.
+
+2003-02-20 Josef Zlomek <zlomekj@suse.cz>
+
+ * combine.c (distribute_notes): Kill REG_EXEC_COUNT.
+ * rtl.c (reg_note_name): Likewise.
+ * rtl.h (enum reg_note): Likewise.
+ * doc/invoke.texi: Likewise.
+ * doc/rtl.texi: Likewise.
+
+2003-02-20 Josef Zlomek <zlomekj@suse.cz>
+
+ * bb-reorder.c (find_traces_1_round): Fix comment typo.
+
+2003-02-19 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (fold_real_zero_addition_p): Don't fold a zero
+ addition in the presence of signaling NaNs.
+
+2003-02-19 Krister Walfridsson <cato@df.lth.se>
+
+ * tm.texi (INIT_CUMULATIVE_ARGS): Fix typo.
+
+2003-02-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (output_logical_op): Optimize or.l when
+ ORing with 0xffff??00 with the highest bit of the ?? part set.
+ (compute_logical_op_length): Update.
+ (compute_logical_op_cc): Likewise.
+
+2003-02-19 Josef Zlomek <zlomekj@suse.cz>
+
+ * bb-reorder.c (find_traces_1_round): Fixed condition for small
+ destination block with multiple predecessors.
+ (connect_traces): Check whether the block is a start of trace.
+
+2003-02-19 Jan Hubicka <jh@suse.cz>
+
+ * calls.c (expand_call): Update call of INIT_CUMULATIVE_ARGS
+ * function.c (assign_params): Likewise.
+ * arm-protos.h (arm_init_cumulative_args): Update prototype.
+ * arm.c (arm_init_cumulative_args): Update function.
+ * arm.h (INIT_CUMULATIVE_ARGS): Update.
+ * avr-protos.h (init_cumulative_args): Update prototype.
+ * avr.c (init_cumulative_args): Update function.
+ * avr.h (INIT_CUMULATIVE_ARGS): Update.
+ * d30v-protos.h (d30v_init_cumulative_args): Update prototype.
+ * d30v.c (d30v_init_cumulative_args): Update function.
+ * d30v.h (INIT_CUMULATIVE_ARGS): Update.
+ * frv-protos.h (frv_init_cumulative_args): Update prototype.
+ * frv.c (frv_init_cumulative_args): Update function.
+ * frv.h (INIT_CUMULATIVE_ARGS): Update.
+ * mips.c (mips_expand_prolgue): Update call of INIT_CUMULATIVE_ARGS.
+ * pa.h (INIT_CUMULATIVE_ARGS): Update.
+ * sparc-protos.h (init_cumulative_args): Update prototype.
+ * sparc.c (init_cumulative_args): Update function.
+ * sparc.h (INIT_CUMULATIVE_ARGS): Update.
+ * tm.texi (INIT_CUMULATIVE_ARGS): Update documentation.
+
+2003-02-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*iorsi3_two_qi_sext): New.
+ (*ashiftsi_sextqi_7): Likewise.
+
+2003-02-19 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * config/mips/iris6.h (TARGET_OS_CPP_BUILTINS): Define __c99 for
+ ISO C99 and C++.
+
+ * fixinc/inclhack.def (irix___restrict): Don't change __restrict
+ for C++ on IRIX 6.5.1[89].
+ * fixinc/tests/base/internal/sgimacros.h: New file.
+
+ * fixinc/inclhack.def (irix_wcsftime): Use XPG5 variant for C99.
+ * fixinc/tests/base/internal/wchar_core.h: New file.
+
+ * fixinc/inclhack.def (irix_socklen_t): Fix broken IRIX 6.5.1[78]
+ socklen_t definition.
+ * fixinc/fixincl.x: Regenerate.
+ * fixinc/tests/base/sys/socket.h: New file.
+ Fixes PR libgcj/9652.
+
+2003-02-19 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (movsfcc_1, movdfcc_1): Fix constrains.
+
+2003-02-19 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_override_options): Initialize
+ align_jumps_max_skip and align_loops_max_skip.
+
+2003-02-19 Thierry Moreau <thierry.moreau@connotech.com>
+
+ * config/rs6000/rs6000.c (rs6000_encode_section_info): Do not
+ test size if named section.
+
+2003-02-19 Daniel Jacobowitz <drow@mvista.com>
+
+ * expr.c (expand_expr): Use gen_int_mode for the argument
+ to gen_rtx_MULT.
+
+2003-02-19 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (cosxf2): Fix conditional.
+
+2003-02-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (extendqisi2): Change to an expander.
+ (*extendqisi2_h8300): New.
+ (*extendqisi2_h8300hs): Likewise.
+
+2003-02-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Update the prototype for
+ split_adds_subs. Remove the prototypes for
+ const_int_le_2_operand and const_int_le_6_operand.
+ * config/h8300/h8300.c (split_adds_sub): Don't output inc/dec.
+ (const_int_le_2_operand): Remove.
+ (const_int_le_6_operand): Likewise.
+ * config/h8300/h8300.h (PREDICATE_CODES): Remove the entries
+ for const_int_le_2_operand and const_int_le_6_operand.
+ * config/h8300/h8300.md: Update all uses of split_adds_subs.
+ (a peephole2): New.
+
+2003-02-18 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (NPREDECESORC, SET_NPREDECESORS): Kill.
+ (cgraph_expand_function): Rewrite.
+
+2003-02-18 Matt Austern <austern@apple.com>
+
+ * toplev.c, langhooks.c, langhooks-def.h: Move
+ write_global_declarations from toplev.c to langhooks.c.
+
+2003-02-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (general_operand_src): Always check
+ MODE.
+ (general_operand_dst): Likewise.
+
+2003-02-18 Roger Sayle <roger@eyesopen.com>
+
+ * convert.c (convert_to_real): Also optimize (float)log(x) into
+ logf(x) where x is a float, i.e. also handle BUILT_IN_LOG{,L}.
+
+2003-02-18 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (unspec_caller_rtx_p): New.
+ (sh_cannot_copy_insn_p): New.
+ (TARGET_CANNOT_COPY_INSN_P): New.
+
+2003-02-18 Richard Henderson <rth@redhat.com>
+
+ * c-common.c (handle_used_attribute): Accept static data too.
+
+2003-02-18 Nick Clifton <nickc@redhat.com>
+ Aldy Hernandez <aldyh@redhat.com>
+
+ * testsuite/gcc.dg/20030218-1.c: New.
+
+ * doc/tm.texi: Document TARGET_VECTOR_TYPES_COMPATIBLE.
+
+ * target-def.h (TARGET_INITIALIZER): Add
+ TARGET_VECTOR_TYPES_COMPATIBLE.
+ (TARGET_VECTOR_TYPES_COMPATIBLE): New macro.
+
+ * target.h (struct gcc_target): Add field vector_types_compatible.
+
+ * c-typeck.c (comptypes): Take into account
+ TARGET_VECTOR_TYPES_COMPATIBLE.
+ (convert_for_assignment): Same.
+
+ * config/rs6000/rs6000.c (is_ev64_opaque_type): New.
+ (rs6000_spe_vector_types_compatible): New.
+ (TARGET_VECTOR_TYPES_COMPATIBLE): Define.
+
+2003-02-19 Andreas Schwab <schwab@suse.de>
+
+ * Makefile.in (toplev.o): Depend on $(LANGHOOKS_DEF_H).
+ * toplev.c: Include langhooks-def.h.
+
+2003-02-18 Chris Demetriou <cgd@broadcom.com>
+
+ * config/mips/mips.h (enum processor_type): Sort entries
+ alphabetically.
+ * config/mips/mips.md (define_attr cpu): Sync with processor_type
+ enum values, including adding entries that were missing.
+
+2003-02-18 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * sh.c (calc_live_regs): Also check GET_CODE when checking if
+ initial value for PR_REG is still the PR_REG register.
+
+2003-02-18 Jim Wilson <wilson@redhat.com>
+
+ * config/ia64/ia64.md (floatdidf2, floatdisf2): Add %, before second
+ instruction in output template.
+ (bsp_value): Change output template from string to C code, add %,
+ before actual instruction.
+ (flushrs): Mark as not predicable.
+
+2003-02-18 Krister Walfridsson <cato@df.lth.se>
+
+ * inclhack.def (netbsd_bogus_semicolon): New fix.
+ * fixincl.x: Rebuilt.
+ * tests/base/ctype.h: Update.
+
+2003-02-18 Roger Sayle <roger@eyesopen.com>
+
+ * fold-const.c (negate_expr_p): New function to determine whether
+ an expression can be negated cheaply.
+ (fold) [MINUS_EXPR]: Use it to determine whether to transform
+ -A - B into -B - A for floating point types.
+
+2003-02-18 Roger Sayle <roger@eyesopen.com>
+
+ * sbitmap.c (sbitmap_resize): New function.
+ * sbitmap.h (sbitmap_resize): Prototype here.
+ * recog.c (split_all_insns): Use sbitmap_resize.
+
+2003-02-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*zero_extendhisi2_h8300): Fix the
+ insn length.
+ (extendqisi2): Likewise.
+ (*extendhisi2_h8300): Likewise.
+
+2003-02-18 Matt Austern <austern@apple.com>
+
+ * langhooks.h, langhooks-def.h: introduce new langhook,
+ final_write_globals, with write_global_declarations as default.
+ * toplev.c: Move invocation of wrapup_global_declarations from
+ compile_file to new function, write_global_declarations. Change
+ compile_file to use final_write_globals hook. Change
+ wrapup_global_declarations so writing to DECL_DEFER_OUTPUT is
+ conditional.
+
+2003-02-18 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.md: Correct and enhance comment.
+
+2003-02-18 Geoffrey Keating <geoffk@apple.com>
+
+ * gcc.c (validate_switches): Don't scan past closing '}'.
+
+2003-02-18 Ben Elliston <bje@redhat.com>
+
+ PR c++/1607
+ * doc/extend.texi (Function Attributes): Document the effect of
+ the C++ "this" parameter on the counting of arguments for the
+ "format" and "format_arg" attributes.
+
+2003-02-17 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.h (__ev_stdd): Cast 2nd arg.
+ (__ev_stdw): Same.
+ (__ev_stdh): Same.
+
+2003-02-17 Jan Hubicka <jh@suse.cz>
+
+ * recog.c (split_all_insns): Fix memory overflow.
+
+2003-02-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (cmpqi): Remove mode from compare.
+ (cmphi): Likewise.
+ (*cmphi_h8300): Likewise.
+ (*cmphi_h8300hs): Likewise.
+ (cmpsi): Likewise.
+ (7 peephole2): Likewise.
+
+2003-02-16 Jan Hubicka <jh@suse.cz>
+
+ * c-typeck.c (build_c_cast): Fold constant variables into
+ initial values.
+
+2003-02-16 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/install.texi (Specific): Fix link for m68k-att-sysv.
+ (Binaries): Ditto for Sinix/Reliant Unix.
+
+2003-02-16 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_reload_in_hi): Ensure that the scratch register does
+ not overlap the final result register.
+
+2003-02-16 Arend Bayer <arend.bayer@web.de>
+ Richard Henderson <rth@redhat.com>
+
+ PR c/8068
+ * fold-const.c (extract_muldiv_1): Rename from extract_muldiv;
+ rearrange mult arguments for less recursion.
+ (extract_muldiv): New. Prevent runaway recursion.
+
+2003-02-16 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/cygwin.h (TARGET_SUBTARGET_DEFAULT): Set
+ MASK_ALIGN_DOUBLE.
+
+2003-02-15 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.c (x86_ext_80387_constants): Use 80387 insns
+ to load mathematical constants on K6, Athlon, Pentium 4 and PPro.
+ (ext_80387_constants_table): Global table of 80387 special constants
+ guarded by ext_80387_constants_init flag when not initialized.
+ (init_ext_80387_constants): New function to initialize this table.
+ (standard_80387_constant_p): Extend to recognize extra 80387
+ constants, in XFmode, on processors where this is a win.
+ (standard_80387_constant_opcode): New function to return the
+ opcode associated with standard_80387_constant_p.
+ (standard_80387_constant_rtx): New function to return the XFmode
+ CONST_DOUBLE associated with standard_80387_constant_p.
+ (ix86_rtx_costs): Give the new constants the same cost as 1.0.
+
+ * config/i386/i386-protos.h (standard_80387_constant_opcode):
+ Prototype here.
+ (standard_80387_constant_rtx): Likewise.
+
+ * config/i386/i386.md (*movsf1, *movsf1_nointerunit, *movdf_nointeger,
+ *movdf_integer, *movxf_nointeger, *movtf_nointeger, *movxf_integer,
+ *movtf_integer): Simplify using new standard_80387_constant_opcode.
+
+2003-02-15 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/invoke.texi (Optimize Options): Correct @option syntax.
+
+2003-02-15 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (cfglayout.o): Depend on TARGET_H.
+ * cfglayout.c: Include target.h.
+ (cfg_layout_can_duplicate_bb_p): Check targetm.cannot_copy_insn_p.
+ * target-def.h (TARGET_CANNOT_COPY_INSN_P): New.
+ * target.h (struct gcc_target): Add cannot_copy_insn_p.
+
+ * config/alpha/alpha.c (alpha_cannot_copy_insn_p): New.
+ (TARGET_CANNOT_COPY_INSN_P): New.
+ (override_options): Revert 2003-02-08 hack.
+
+2003-02-15 Richard Henderson <rth@redhat.com>
+
+ * gcse.c (bypass_block): Use BLOCK_FOR_INSN for resolving LABEL_REFs.
+ (bypass_conditional_jumps): Accept computed_jump_p insns as well.
+
+2003-02-15 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.h (processor_type): Add PPC440.
+ * config/rs6000/rs6000.c (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE,
+ TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD,
+ TARGET_SCHED_VARIABLE_ISSUE): Define.
+ (rs6000_use_dfa_pipeline_interface): New function.
+ (rs6000_multipass_dfa_lookahead): New Function.
+ (rs6000_variable_issue): New function.
+ (rs6000_adjust_cost): Add CMP and DELAYED_CR types.
+ (rs6000_issue_rate): Add PPC440.
+ * config/rs6000/rs6000.md (unspec list): Correct typo.
+ (attr "type"): Add load_ext, load_ext_u, load_ext_ux, load_u,
+ store_ux, store_u, fpload_ux, fpload_u, fpstore_ux, fpstore_u,
+ cmp, delayed_cr, mfcr, mtcr.
+ (automata_option): Set "ndfa".
+ (extendMMNN2): Update attributes.
+ (movcc_internal1): Discourage move to non-cr0. Update
+ attributes.
+ (movMM_update): Update attributes.
+ (cmpMM_internal): Update attributes.
+ (sCC CR materialization): Update attributes.
+ (branch patterns): Do not discourage non-cr0.
+ (cr logical patterns): Prefer destructive register allocation.
+ Update attributes.
+ (movesi_from_cr): Update attribute.
+ (mtcrf_operation): Update attribute.
+ (mtcrfsi): Update attribute.
+ * config/rs6000/40x.md: New file.
+ * config/rs6000/603.md: New file.
+ * config/rs6000/6xx.md: New file.
+ * config/rs6000/7450.md: New file.
+ * config/rs6000/7xx.md: New file.
+ * config/rs6000/mpc.md: New file.
+ * config/rs6000/power4.md: New file.
+ * config/rs6000/rios1.md: New file.
+ * config/rs6000/rios2.md: New file.
+ * config/rs6000/rs64.md: New file.
+ [Some DFA descriptions based on work by Michael Hayes]
+
+2003-02-15 Richard Henderson <rth@redhat.com>
+
+ * bb-reorder.c (find_traces_1_round): Don't connect easy to copy
+ successors with multiple predecessors.
+ (connect_traces): Try harder to copy traces of length 1.
+
+ * function.h (struct function): Add computed_goto_common_label,
+ computed_goto_common_reg.
+ * function.c (free_after_compilation): Zap them.
+ * stmt.c (expand_computed_goto): Use them to produce one
+ indirect branch per function.
+
+2003-02-15 Richard Henderson <rth@redhat.com>
+
+ * cfgcleanup.c: Include params.h.
+ (try_crossjump_bb): Use PARAM_MAX_CROSSJUMP_EDGES. Fix test for
+ too many outgoing edges from a block.
+ * Makefile.in (cfgcleanup.o): Depend on PARAMS_H.
+ * params.def (max-crossjump-edges): New.
+ * doc/invoke.texi: Document it.
+
+2003-02-15 Richard Henderson <rth@redhat.com>
+
+ * recog.c (split_all_insns): Include new blocks in life update;
+ do a global life update.
+
+2003-02-15 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/mingw32.h (LIBGCC_SPEC): Add libmingwex.a.
+ Update copyright.
+ * config/i386/cygwin.h (LIBGCC_SPEC): Add libmingwex.a for
+ -mno-cygwin case.
+
+2003-02-14 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ PR optimization/7702
+ * reload1.c (reload_cse_simplify_set): Honor
+ CANNOT_CHANGE_MODE_CLASS.
+
+2003-02-14 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mn10300/mn10300.c (mn10300_wide_const_load_uses_clr): New
+ function.
+ * config/mn10300/mn10300-protos.h: Declare it.
+ * config/mn10300/mn10300.md (movdi, movdf): Use it to compute
+ attribute cc of instructions that may use clr.
+
+2003-02-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * simplify-rtx.c (simplify_binary_operation): Simplify ~y when
+ (x - (x & y)) is found.
+
+2003-02-14 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * configure.in: Fix typo.
+ * configure: Regenerate.
+
+2003-02-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*iorsi2_and_1_lshiftrt_1): New.
+
+2003-02-13 Adam Nemet <anemet@lnxw.com>
+
+ PR opt/2391
+ * combine.c: Fix spelling in comment.
+ (cached_nonzero_bits): New function.
+ (cached_num_sign_bit_copies): New function.
+ (nonzero_bits_with_known): New macro.
+ (num_sign_bit_copies_with_known): New macro.
+ (nonzero_bits1): Rename from nonzero_bits. Add three new
+ arguments. Change calls from nonzero_bits to
+ nonzero_bits_with_known.
+ (num_sign_bit_copies1): Rename from num_sign_bit_copies. Add
+ three new arguments. Change calls from num_sign_bit_copies to
+ num_sign_bit_copies_with_known.
+ (nonzero_bits): New macro.
+ (num_sign_bit_copies): New macro.
+ (update_table_tick): Don't traverse identical subexpression more
+ than once.
+ (get_last_value_validate): Likewise.
+
+2003-02-13 Zack Weinberg <zack@codesourcery.com>
+
+ * emit-rtl.c (init_emit): Use ggc_alloc for regno_reg_rtx.
+ * function.h (struct emit_status): Length of regno_pointer_align
+ and x_regno_reg_rtx as seen by gengtype is only x_reg_rtx_no,
+ not regno_pointer_align_length (i.e. length actually used, not
+ length as allocated)
+
+ * config/i386/i386.c (struct stack_local_entry): New.
+ (struct machine_function): Replace huge array with alist.
+ (assign_386_stack_local): Change to match.
+
+2003-02-13 John David Anglin <dave.anglin@nrc-crnc.gc.ca>
+
+ * inclhack.def (hpux_long_double): Tighten select and add bypass
+ regexp.
+ * fixincl.x: Rebuilt.
+
+2003-02-13 Josef Zlomek <zlomekj@suse.cz>
+
+ * cfgcleanup.c (outgoing_edges_match): When there is single outgoing
+ edge and block ends with a jump insn it must be simple jump.
+
+2003-02-13 Daniel Jacobowitz <drow@mvista.com>
+
+ * Makefile.in (PREPROCESSOR_DEFINES): Add
+ @TARGET_SYSTEM_ROOT_DEFINE@.
+ * configure.in (PREFIX_INCLUDE_DIR): Don't define if $with_sysroot
+ is specified or if building a cross compiler.
+ (TARGET_SYSTEM_ROOT_DEFINE): Add TARGET_SYSTEM_ROOT_RELOCATABLE
+ if the sysroot is under $exec_prefix.
+ * configure: Regenerated.
+ * cppdefault.h: Use native include paths if TARGET_SYSTEM_ROOT is
+ defined.
+ (struct default_include): Add add_sysroot field.
+ (cpp_SYSROOT): Declare.
+ * cppdefault.c (cpp_include_defaults): Fill in add_sysroot
+ field.
+ (cpp_SYSROOT): New variable.
+ * cppinit.c (cpp_create_reader): Initialize
+ CPP_OPTION (pfile, sysroot).
+ (init_standard_includes): Handle add_sysroot. Do not
+ add unrelocated copies of relocated directories.
+ (COMMAND_LINE_OPTIONS): Add -isysroot.
+ (cpp_handle_option): Handle -isysroot.
+ * cpplib.h (struct cpp_options): Add sysroot member.
+ * gcc.c (The Specs Language): Update description of %I.
+ (target_system_root_changed): New variable.
+ (process_command): Conditionalize make_relative_prefix call
+ on !VMS and TARGET_SYSTEM_ROOT_RELOCATABLE. Set
+ target_system_root_changed.
+ (do_spec_1): Add -isysroot to %I.
+ * doc/invoke.texi (Spec Files): Update description of %I.
+ * doc/install.texi (--with-sysroot): Update comment about
+ relocation.
+
+2003-02-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): New.
+
+2003-02-13 Robert Lipe <robertlipe@usa.net>
+ Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/install.texi (Specific): Update three SCO-related URLs.
+
+2003-02-13 Andreas Schwab <schwab@suse.de>
+
+ * cgraph.c (SET_NPREDECESORS): Add intermediate cast to size_t.
+ Parenthesize properly.
+ (NPREDECESORS): Parenthesize properly.
+
+2003-02-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * timevar.h (POP_TIMEVAR_AND_RETURN): New macro.
+
+2003-02-12 Roger Sayle <roger@eyesopen.com>
+
+ * config/i386/i386.md (UNSPEC_FPATAN): New UNSPEC constant.
+ (atan2sf3, atan2df3, atan2xf3, atan2tf3): New patterns.
+
+ * reg-stack.c (subst_stack_regs_pat): Add support for binary
+ UNSPEC instructions (e.g. "fpatan").
+
+2003-02-12 Mike Stump <mrs@apple.com>
+
+ * varray.c (element_size): Remove.
+ (uses_ggc): Remove.
+ (element): Add.
+ (varray_init): Use new interface.
+ (varray_grow): Use new interface.
+ (varray_clear): Use new interface.
+
+2003-02-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.h: Add casts to the arguments of the following
+ macros: evfsabs, evfsnabs, evfsneg, evfsadd, evfssub, evfsmul,
+ evfsdiv, evfscfui, evfscfsi evfscfuf evfscfsf, evfsctui, evfsctsi,
+ evfsctuf, evfsctsf, evfsctuiz, evfsctsiz, __ev_get_upper*,
+ __ev_get_lower*, __ev_get_u32, __ev_get_s32, __ev_get_fs,
+ __ev_get_u16, __ev_get_s16.
+
+2003-02-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): New.
+
+2003-02-12 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (CRTSTUFF_CFLAGS): Add -fno-unit-at-a-time
+ (OBJS): Add cgraph.o
+ (cgraph.o): New.
+ * c-decl.c (expand_body_1): Break out from ...
+ (expand_body): This one; change calling convention
+ (finish_function): Move some of expand_body logic here.
+ (c_expand_deferred_function): Update call of expand_body
+ (c_expand_stmt): Use c_expand_body_1.
+ * c-lang.c (LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION): Define.
+ * c-objc-commin.c (c_objc_common_finish_file): Use callgraph code.
+ * c-tree.h (c_expand_body): Declare.
+ * cgraph.c: New file.
+ * flags.h (flag_unit_at_a_time): Declare.
+ * langhooks.h (LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION,
+ LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION,
+ LANG_HOOKS_CALLGRAPH_INITIALIZER): New macros.
+ * langhooks.h (struct lang_hooks_for_callgraph): New.
+ (struct lang_hooks): Add callgraph field.
+ * toplev.c (flag_unit_at_a_time): New.
+ (lang_independent_options): Add flag_unit_at_a_time.
+ (process_options): Disable unit-at-a-time mode for frontends not
+ supporting callgraph.
+ * tree-inline.c (typedef struct inline_data): Add "decl"
+ (expand_call_inline): Update callgraph.
+ (optimize_inline_calls): Set id.decl.
+ * tree.h (cgraph_finalize_function, cgraph_finalize_compilation_unit,
+ cgraph_create_edges, dump_cgraph, cgraph_optimize, cgraph_remove_call
+ cgraph_calls_p): Declare.
+ * invoke.texi (-funit-at-a-time): Document.
+
+2003-02-12 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.h: Fix misc formatting.
+ (__ev_create_ufix32_fs): Cast ev argument.
+ (__ev_create_sfix32_fs): Same.
+ (__ev_get_sfix32_fs_internal): Cast arguments to builtins.
+ (__ev_get_ufix32_fs_internal): Same.
+
+2003-02-12 Ranjit Mathew <rmathew@hotmail.com>
+
+ * doc/tm.texi (MODIFY_JNI_METHOD_CALL): Document.
+ * config/i386/cygwin.h (MODIFY_JNI_METHOD_CALL): New macro.
+
+2003-02-12 Zack Weinberg <zack@codesourcery.com>
+
+ * cpplib.c (do_include_common): Move warnings for
+ #include_next and #import out to callers. Use early-return
+ instead of nested ifs. Don't do check_eol here.
+ (parse_include): Do check_eol here with the rest of the
+ parsing stuff.
+ (do_include_next, do_import): Now handle warnings.
+
+2003-02-11 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/install.texi (Specific): Update AVR- and Darwin-related URLs.
+
+2003-02-12 Jan Hubicka <jh@suse.cz>
+
+ * predict.c (estimate_probability): Fix roundoff error.
+
+2003-02-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): Don't handle 65535.
+ (two peephole2): New.
+
+2003-02-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (several peephole2): Replace
+ find_regno_note with peep2_reg_dead_p.
+
+2003-02-11 Richard Henderson <rth@redhat.com>
+
+ * gcse.c (lookup_set): Remove unused argument PAT. Update
+ both callers.
+
+2003-02-11 Geoffrey Keating <geoffk@apple.com>
+
+ * diagnostic.c (real_abort): New.
+ (diagnostic_report_diagnostic): Call real_abort on error.
+ * diagnostic.h (diagnostic_abort_on_error): New.
+ (struct diagnostic_context): Add abort_on_error field.
+ * toplev.c (setup_core_dumping): New.
+ (decode_d_option): Handle 'H' case.
+ * doc/invoke.texi (Debugging Options): Document -dH.
+
+2003-02-11 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Makefile.in: Remove pointless setting of CXXFLAGS for dejagnu
+ which refers to obsolete directories.
+
+2003-02-11 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/linux.h (TARGET_C99_FUNCTIONS): New.
+
+2002-10-21 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (contains_128bit_aligned_vector_p): New function.
+ (ix86_function_arg_boundary): Properly align vector modes.
+
+2003-02-11 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.md (set_frame_ptr): Change rtl to set reg a7.
+ * config/xtensa/xtensa.c (xtensa_reorg): Search for UNSPECV_SET_FP
+ as a SET pattern.
+
+2003-02-11 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c: Fix failure caused by commiting wrong patch.
+
+2003-02-11 Dale Johannesen <dalej@apple.com>
+ * ra-build.c (compare_and_free_webs): Relax checking.
+ * config/rs6000/darwin.h (HOT_TEXT_SECTION_NAME): Define.
+ (UNLIKELY_EXECUTED_TEXT_SECTION_NAME): Define.
+
+2003-02-11 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ PR optimization/9651
+ * rtlanal.c (may_trap_p): Handle FIX.
+
+2003-02-11 Dave Jones <davej@codemonkey.org.uk>
+
+ * config/i386/i386.c (override_options): Define c3-2 as a 686 with SSE.
+ * doc/invoke.texi: Extra alias.
+
+2003-02-11 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/host-darwin.c: Fix comment.
+
+2003-02-11 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (divmodsi4): Use register_operand
+ predicate for mod result.
+
+2003-02-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * inclhack.def (hpux_long_double, hpux10_ctype_declarations1,
+ hpux10_ctype_declarations2, hpux_ctype_macros): New hacks.
+ * fixincl.x: Rebuilt.
+ * tests/base/stdlib.h: Update.
+ * tests/base/ctype.h: New file.
+
+2003-02-11 Jan Hubicka <jh@suse.cz>
+
+ * emit-rtl.c (emit_copy_of_insn_after): Copy insn recog cache too.
+
+2003-02-11 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (ix86_expand_movstr): Fail if esi or edi
+ appropriated as globals.
+ (ix86_expand_clrstr): Similarly.
+ * config/i386/i386.md (cmpstrsi): Similarly.
+
+2003-02-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): Add a case of 255.
+
+2003-02-11 Roger Sayle <roger@eyesopen.com>
+
+ * optabs.h (enum optab_index): Add new OTI_pow and OTI_atan2.
+ (pow_optab, atan2_optab): Define corresponding macros.
+ * optabs.c (init_optabs): Initialize pow_optab and atan2_optab.
+ * genopinit.c (optabs): Implement pow_optab and atan2_optab
+ using pow?f3 and atan2?f3 patterns.
+ * builtins.c (expand_errno_check): New function to update errno
+ if necessary, split out from expand_builtin_mathfn.
+ (expand_builtin_mathfn): Use expand_errno_check.
+ (expand_builtin_mathfn_2): New function to handle expanding binary
+ math functions, reusing the code in expand_errno_check.
+ (expand_builtin): Handle the pow and atan2 math built-ins,
+ BUILT_IN_{POW,POWF,POWL,ATAN2,ATAN2F,ATAN2L} via the new function
+ expand_builtin_mathfn_2.
+
+ * doc/md.texi: Document new pow?f3 and atan2?f3 patterns.
+
+2003-02-11 Jan Hubicka <jh@suse.cz>
+
+ * combine.c (combine_simplify_rtx): Fix folding of
+ nested float_truncates.
+
+2003-02-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (a peephole2): Fix a typo.
+
+2003-02-11 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.mc (return_address_mask): Use CC_REGNUM for the condition code
+ register number.
+
+2003-02-11 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add a prototype for
+ gtuleu_operator.
+ * config/h8300/h8300.c (gtuleu_operator): New.
+ * config/h8300/h8300.h (PREDICATE_CODES): Add gtuleu_operator.
+ * config/h8300/h8300.md (a peephole2): New.
+
+2003-02-11 Jan Hubicka <jh@suse.cz>
+
+ * sched-ebb.c (schedule_ebbs): Do not verify_flow_info.
+
+2003-02-11 Jan Hubicka <jh@suse.cz>
+
+ * predict.c (choose_function_section): Choose sections correctly.
+
+2003-02-10 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * reload1.c (first_label_num): New.
+ (reload): Index offsets_known_at and offsets_at using difference of
+ label number and first label number. Don't use offset pointers.
+ (set_label_offsets, set_initial_label_offsets): Likewise.
+
+2003-02-10 Roger Sayle <roger@eyesopen.com>
+
+ * mips-tfile.c (init_file): Add missing initializers in the
+ "#ifdef __alpha" case.
+ (file_offset, max_file_offset): Declare as unsigned long.
+ (write_varray): Cast to "unsigned long" in comparisons against
+ either file_offset or max_file_offset.
+ (write_object): Likewise.
+ (read_seek): Likewise.
+ (copy_object): Likewise. Declare "ifd" as int to match its use
+ in add_ext_symbol, and avoid signed/unsigned conditional warning.
+
+2003-02-10 Nick Clifton <nickc@redhat.com>
+ Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/eabispe.h (SUBSUBTARGET_OVERRIDE_OPTIONS): Do not
+ override options which have been specified on the command line.
+
+2003-02-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (abssf2): New.
+ (*abssf2_h8300): Likewise.
+ (*abssf2_h8300hs): Likewise.
+
+2003-02-10 Phil Edwards <pme@gcc.gnu.org>
+
+ * tree.c (build_tree_list): Fix parameter names in comment.
+
+2003-02-10 Janis Johnson <janis187@us.ibm.com>
+
+ * config/rs6000/ppc64-fp.c: New file.
+ * config/rs6000/t-linux64 (LIB2FUNCS_EXTRA): Add ppc64-fp.c.
+
+2003-02-10 Josef Zlomek <zlomekj@suse.cz>
+
+ * Makefile.in (bb-reorder.o): Add dependency on $(FIBHEAP_H).
+ * bb-reorder.c (make_reorder_chain): Deleted.
+ (make_reorder_chain_1): Deleted.
+ (find_traces): New function.
+ (rotate_loop): New function.
+ (mark_bb_visited): New function.
+ (find_traces_1_round): New function.
+ (copy_bb): New function.
+ (bb_to_key): New function.
+ (better_edge_p): New function.
+ (connect_traces): New function.
+ (copy_bb_p): New function.
+ (get_uncond_jump_length): New function.
+ (reorder_basic_blocks): Use new functions (Software Trace Cache).
+ * cfgcleanup.c (outgoing_edges_match): Enable crossjumping across loop
+ boundaries.
+
+2003-02-10 Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/rs6000.c (bdesc_2arg): Change spe_evxor to xorv2si3.
+
+2003-02-09 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * tree.h (struct tree_decl): Remove unused live_range_rtl field.
+ (DECL_LIVE_RANGE_RTL): Remove.
+
+2003-02-10 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/aof.h, config/arm/aout.h, config/arm/arm-modes.def,
+ config/arm/arm-protos.h, config/arm/arm.c, config/arm/arm.h,
+ config/arm/arm.md, config/arm/cirrus.md, config/arm/coff.h,
+ config/arm/conix-elf.h, config/arm/ecos-elf.h, config/arm/elf.h,
+ config/arm/freebsd.h, config/arm/linux-elf.h,
+ config/arm/linux-gas.h, config/arm/netbsd-elf.h,
+ config/arm/netbsd.h, config/arm/pe.c, config/arm/pe.h,
+ config/arm/rtems-elf.h, config/arm/semi.h, config/arm/semiaof.h,
+ config/arm/strongarm-coff.h, config/arm/strongarm-elf.h,
+ config/arm/strongarm-pe.h, config/arm/uclinux-elf.h,
+ config/arm/unknown-elf-oabi.h, config/arm/unknown-elf.h,
+ config/arm/xscale-elf.h: Replace occurances of "GNU CC" with "GCC"
+ and reformat as appropriate.
+
+2003-02-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/clzsi2.c: Remove.
+ * config/h8300/ctzsi2.c: Likewise.
+ * config/h8300/paritysi2.c: Likewise.
+ * config/h8300/popcountsi2.c: Likewise.
+ * config/h8300/t-h8300 (LIB2FUNCS_EXTRA): Remove clzsi2,
+ ctzsi2, paritysi2, and popcountsi2.
+
+2003-02-10 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
+
+ PR c/7741
+ * c-decl.c (duplicate_decls): Discard the initializer of the
+ new decl when the types are conflicting.
+
+2003-02-10 Josef Zlomek <zlomekj@suse.cz>
+
+ * Makefile.in (sreal.o): Added.
+ (predict.o): Depends on sreal.h instead of real.h.
+ * sreal.c: New file.
+ * sreal.h: New file.
+ * predict.c: Use sreal.c instead of real.c.
+
+2003-02-10 Nick Clifton <nickc@redhat.com>
+
+ * Contributed support for the Cirrus EP9312 "Maverick"
+ floating point co-processor. Written by Aldy Hernandez
+ <aldyh@redhat.com>.
+ (config/arm/arm.c): Add Cirrus support.
+ (config/arm/arm.h): Likewise.
+ (config/arm/aout.h): Likewise.
+ (config/arm/arm.md): Likewise.
+ (config/arm/arm-protos.h): Likewise.
+ (config.gcc): Likewise.
+ (doc/invoke.texi): Describe new -mcpu value and new
+ -mcirrus-fix-invalid-insns switch,
+ (cirrus.md): New file.
+
+2003-02-10 Jan Hubicka <jh@suse.cz>
+
+ * combine.c (combine_simplify_rtx): Simplify using
+ (float_truncate (float x)) is (float x)
+ (float_extend (float_extend x)) is (float_extend x).
+
+2003-02-10 Alan Modra <amodra@bigpond.net.au>
+
+ * calls.c (try_to_integrate): Tidy stack_usage_map access.
+ (emit_library_call_value_1): Likewise. Formatting.
+ (store_one_arg): Likewise.
+
+2003-02-09 Nick Clifton <nickc@redhat.com>
+ Aldy Hernandez <aldyh@redhat.com>
+
+ * config/rs6000/spe.md: spe_evlhhesplat, spe_evlhhossplat,
+ spe_evlhhousplat, spe_evlwhsplat, spe_evlwwsplat, spe_evldd,
+ spe_evldh, spe_evldw, spe_evlwhe, spe_evlwhos, spe_evlwhou,
+ spe_evstdd, spe_evstdh, spe_evstdw, spe_evstdwx, spe_evstwhe,
+ spe_evstwho, spe_evstwwe, spe_evstwwo: Fix syntax to match newest
+ docs. Add range test for immediate value.
+
+2003-02-09 Aldy Hernandez <aldyh@redhat.com>
+
+ Rename spe_evxor to xorv2si3.
+ (xorv4hi3): New.
+ (xorv1di3): New.
+
+2003-02-10 Glen Nakamura <glen@imodulo.com>
+
+ * doc/extend.texi (C++98 Thread-Local Edits): Add missing @item
+ tag.
+
+2003-02-10 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (vector_move_operand): New predicate.
+ (ix86_expand_vector_move): Be happy about 0.
+ * i386.h (PREDICATE_CODES): Add sse-move_operand.
+ * i386.md (mov*_internal): Add 'C' alternative.
+
+2003-02-09 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (floathi*): Deal with SSE.
+
+2003-02-09 Jan Hubicka <jh@suse.cz>
+
+ * simplify-rtx.c (simplify_unary_operation,
+ simplify_binary_operation): Deal with vector modes
+ (simplify_ternary_operation): Deal with no-op VEC_MERGE.
+
+2003-02-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * toplev.c (rest_of_compilation): Recompute register usage after
+ split_all_insns.
+
+2003-02-09 Richard Henderson <rth@redhat.com>
+
+ * libgcc-std.ver (__clztf2): New.
+ (__ctztf2, __popcounttf2, __paritytf2): New.
+ * libgcc2.c (__clzSI2, __clzDI2, __ctzSI2, __ctzDI2, __popcountSI2,
+ __popcountDI2, __paritySI2, __parityDI2): Use UWmode and UDWmode;
+ adjust code to match the different type sizes.
+ * libgcc2.h (__clzSI2, __ctzSI2, __popcountSI2, __paritySI2,
+ __clzDI2, __ctzDI2, __popcountDI2, __parityDI2): New macros.
+
+ * optabs.c (init_integral_libfuncs): Don't hard-code SImode and
+ TImode; select word_mode and twice that.
+ (init_floating_libfuncs): Don't hard-code SFmode and TFmode;
+ select the modes from float, double, and long double.
+ (init_optabs): Remove duplicate initializations.
+
+2003-02-09 Wolfgang Bangerth <bangerth@ticam.utexas.edu>
+
+ * doc/install.texi: Squeeze and streamline section on
+ testing and regression checking.
+
+2003-02-09 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (ahi?v*3): Set third operand type to TImode.
+ * i386.c (ix86_expand_binop_builtin): Extend operand when needed.
+
+ * simplify-rtx.c (simplify_subreg): Fix conversion from vector into
+ integer mode.
+
+ * rtl.def (VEC_MERGE, VEC_SELECT, VEC_CONCAT, VEC_DUPLICATE):
+ Change code so they are arithmetic expressions now.
+ * simplify-rtx.c (simplify_unary_operation, simplify_binary_operation,
+ simplify_ternary_operation): Deal with VEC_* expressions.
+
+ * i386.md (vmaskcmp, pinsrw, movd patterns): Fix RTL representation.
+
+2003-02-08 Jan Hubicka <jh@suse.cz>
+
+ * cfgrtl.c (verify_flow_info): Use control_flow_insn_p.
+ * reload1.c (fixup_abnormal_edges): Split basic blocks when EH edges
+ possibly got duplicated.
+
+2003-02-08 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (override_options): Turn off explicit
+ relocs until post-peep2 code duplication resolved.
+
+2003-02-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * optabs.c (expand_unop): Widen clz properly when clz is done
+ via libcall.
+
+2003-02-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/clzsi2.c: Replace "GNU CC" with "GCC".
+ * config/h8300/crti.asm: Likewise.
+ * config/h8300/crtn.asm: Likewise.
+ * config/h8300/ctzsi2.c: Likewise.
+ * config/h8300/fixunssfsi.c: Likewise.
+ * config/h8300/h8300-protos.h: Likewise.
+ * config/h8300/h8300.c: Likewise.
+ * config/h8300/h8300.h: Likewise.
+ * config/h8300/h8300.md: Likewise.
+ * config/h8300/paritysi2.c: Likewise.
+ * config/h8300/popcountsi2.c: Likewise.
+ * config/h8300/rtems.h: Likewise.
+
+2003-02-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * doc/invoke.texi: Documentation for my previous commit.
+ * doc/passes.texi: Ditto.
+
+2003-02-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloop.h (fix_loop_placement, can_duplicate_loop_p,
+ duplicate_loop_to_header_edge, loopify, remove_path, split_loop_bb):
+ Declare.
+ (DLTHE_FLAG_UPDATE_FREQ): New.
+ * cfgloopmanip.c (duplicate_loop, duplicate_subloops, copy_loops_to,
+ loop_redirect_edge, loop_delete_branch_edge, copy_bbs, remove_bbs,
+ rpe_enum_p, find_branch, alp_enum_p, add_loop, fix_loop_placements,
+ fix_bb_placement, fix_bb_placements, place_new_loop,
+ scale_loop_frequencies, scale_bbs_frequencies, record_exit_edges):
+ New static functions.
+ (fix_loop_placement, can_duplicate_loop_p,
+ duplicate_loop_to_header_edge, loopify, remove_path, split_loop_bb):
+ New functions.
+
+ * cfgloop.h (loop_optimizer_init, loop_optimizer_finalize,
+ unswitch_loops): Declare.
+ * loop-init.c: New file.
+ * loop-unswitch.c: New file.
+ * Makefile.in (loop-init.o, loop-unswitch.o): New.
+ * params.def (PARAM_MAX_UNSWITCH_INSNS, PARAM_MAX_UNSWITCH_LEVEL): New.
+ * toplev.c (DFI_loop2): New dump.
+ (flag_unswitch_loops): New.
+ (lang_independent_options): Add it.
+ (rest_of_compilation): Call new loop optimizer.
+ (parse_options_and_default_flags): Turn flag_unswitch_loops on with -O3.
+
+2003-02-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/clzsi2.c: New.
+ * config/h8300/ctzsi2.c: Likewise.
+ * config/h8300/paritysi2.c: Likewise.
+ * config/h8300/popcountsi2.c: Likewise.
+ * config/h8300/t-h8300 (LIB2FUNCS_EXTRA): Add above files.
+
+2003-02-07 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.h (CLZ_DEFINED_VALUE_AT_ZERO): Define.
+ * config/rs6000/rs6000.md (clzsi2): Rename from cntlzw2.
+ (ctzsi2): New pattern.
+ (ffssi2): Use clz instead of unspec.
+ (clzdi2): Rename from cntlzd2.
+ (ctzdi2): New pattern.
+ (ffsdi2): Use clz instead of unspec.
+
+2003-02-07 Loren James Rittle <ljrittle@acm.org>
+
+ * config/alpha/freebsd.h (LINK_SPEC): Weaken error to notice.
+ * config/ia64/freebsd.h (LINK_SPEC): Likewise.
+ * config/sparc/freebsd.h (LINK_SPEC): Likewise.
+ * config/i386/freebsd.h (LINK_SPEC): Add clause to mirror other arches.
+
+2003-02-07 Wolfgang Bangerth <bangerth@ticam.utexas.edu>
+
+ * doc/trouble.texi: Document pitfalls of two-stage name lookup.
+
+2003-02-07 Richard Henderson <rth@redhat.com>
+
+ PR 9226
+ * gcse.c (local_cprop_find_used_regs): New.
+ (local_cprop_pass): Use it.
+
+2003-02-07 Fred Fish <fnf@intrinsity.com>
+
+ * mips-tfile.c (parse_def): Parenthesize assignments to fix
+ precedence bugs.
+
+2003-02-07 Segher Boessenkool <segher@koffie.nl>
+
+ * genoutput.c (output_get_insn_name): Handle NOOP_MOVE_INSN_CODE.
+
+2003-02-07 Roger Sayle <roger@eyesopen.com>
+
+ * builtin-types.def (BT_FN_FLOAT_FLOAT_FLOAT): New built-in type.
+ (BT_FN_LONG_DOUBLE_LONG_DOUBLE_LONG_DOUBLE): Likewise.
+ (BT_FN_DOUBLE_DOUBLE_DOUBLE): Likewise.
+ * builtins.def: Define pow, powf, powl, atan2, atan2f and atan2l
+ builtin functions (and their __builtin_* variants).
+ * builtins.c (mathfn_built_in): Handle missing log{,f,l} cases.
+ (expand_builtin): Don't expand log{,f,l}, pow{,f,l} or atan2{,f,l}
+ when not optimizing.
+
+ * doc/extend.texi: Document new pow and atan2 builtins, and
+ their float and long double variants. Realphabetize builtins.
+
+2003-02-07 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (sse2_nandv2di3): Fix.
+
+2003-03-07 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/i386.h (MS_AGGREGATE_RETURN): New define.
+ * config/i386/cygwin.h (MS_AGGREGATE_RETURN): Override default
+ definition.
+ * config/i386/i386.h (ix86_return_in_memory): Return aggregate
+ types of up to 8 bytes via registers if MS_AGGREGATE_RETURN.
+
+2003-02-07 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (movdi_rex64_1): Fix mmx<->int move opcode.
+
+2003-02-07 Daniel Berlin <dberlin@dberlin.org>
+
+ * cfg.c (dump_flow_info): Add back accidently deleted line.
+
+2003-02-07 Andrey Petrov <petrov@netbsd.org>
+
+ * optabs.c (expand_float): Search wider integer modes first.
+
+2003-02-07 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.h (LIBGCC2_WORDS_BIG_ENDIAN): Set this
+ based on preprocessor flag.
+
+2003-02-07 Roger Sayle <roger@eyesopen.com>
+ Richard Henderson <rth@redhat.com>
+
+ * gcse.c (implicit_sets): New.
+ (compute_hash_table_work): Include them in hash table.
+ (find_implicit_sets, fis_get_condition): New.
+ (one_cprop_pass): Allocate and free implicit_sets; call
+ find_implicit_sets before building hash table.
+
+2003-02-07 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * config/t-netbsd (USER_H): Revert previous change.
+
+2003-02-07 Gabor Greif <ggreif@lucent.com>
+
+ * doc/c-tree.texi (Namespaces): Fix typo.
+
+2003-02-07 Jan Hubicka <jh@suse.cz>
+
+ * regrename.c (do_replace, find_oldest_value_reg,
+ copyprop_hardreg_forward_1): Update register attributes.
+
+2003-02-06 Vladimir Makarov <vmakarov@redhat.com>
+
+ * genautomata.c (VLA_PTR_CREATE, VLA_PTR_EXPAND, VLA_PTR_ADD,
+ VLA_HWINT_CREATE, VLA_HWINT_EXPAND, VLA_HWINT_ADD): Use temporay
+ variables starting with underscore.
+ (struct unit_usage): New structure.
+ (unit_usages, cycle_alt_unit_usages): New global variables.
+ (check_unit_distribution_in_reserv): Remove it.
+ (store_alt_unit_usage): New function.
+ (check_regexp_units_distribution): Rewrite it.
+
+2003-02-06 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * config.gcc (hppa*-*-linux*): Set MASK_NO_SPACE_REGS in
+ target_cpu_default.
+ * pa.c (attr_length_call): Add 8 to call length (long indirect PA 1.X)
+ if not MASK_NO_SPACE_REGS.
+ (output_call): Adjust return pointer, don't load new space register
+ into %sr0, and use %sr4 for call if TARGET_NO_SPACE_REGS is true.
+ (pa_asm_output_mi_thunk): Don't load new space register into %sr0 if
+ TARGET_NO_SPACE_REGS is true.
+ * pa.md (return_external_pic): Add TARGET_NO_SPACE_REGS to insn
+ conditions.
+ (epilogue): Always use return_internal if TARGET_NO_SPACE_REGS is true.
+ (interspace_jump): Add new pattern for when TARGET_NO_SPACE_REGS is
+ true. Use bve when TARGET_64BIT is true.
+
+2003-02-06 Richard Henderson <rth@redhat.com>
+
+ * combine.c (nonzero_bits): Fix double break.
+
+2003-02-06 Eric Botcazou <ebotcazou@libertysurf.fr>
+ Richard Henderson <rth@redhat.com>
+
+ PR c/9530
+ * config/i386/i386.c (ix86_function_ok_for_sibcall): Forbid sibcalls
+ from functions that return a float to functions that don't.
+
+2003-02-06 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (x86_inter_unit_moves): New variable.
+ (ix86_secondary_memory_needed): Fix 64bit case, honor
+ TARGET_INTER_UNIT_MOVES
+ * i386.h (x86_inter_unit_moves): Declare.
+ (TARGET_INTER_UNIT_MOVES): New macro.
+ * i386.md (movsi_1): Cleanup constraints; disable
+ when not doing inter-unit moves.
+ (movsi_1_nointernunit): New.
+ (movdi_1_rex64): Fix constraints; deal with SSE->GPR moves.
+ (movdi_1_rex64_nointerunit): New.
+ (mivsf_1): disable when not doing inter-unit moves.
+ (movsf_1_nointerunit): New.
+
+ * basic-block.h (inside_basic_block_p): Declare.
+ * cfgbuild.c (inside_basic_block_p): Make global.
+ * haifa-sched.c (unlink_other_notes): Deal with NOT_INSN_BASIC_BLOCK.
+ * scheudle-ebb.c (schedule_ebb): Return last basic block of trace;
+ update CFG.
+ (fix_basic_block_boundaries, add_missing_bbs): New.
+ (rank): Use profile.
+ (scheudle_ebbs): Rely on CFG; update coments.
+
+2003-02-05 Geoffrey Keating <geoffk@apple.com>
+
+ * Makefile.in (host_hook_obj): New.
+ (OBJS): Add $(host_hook_obj).
+ (host_default.o): New rule.
+ * config.gcc (host_hook_obj): New, default to host-default.o.
+ (powerpc-*-darwin*): Use host-darwin.o.
+ (out_host_hook_obj): New.
+ * configure: Regenerate.
+ * configure.in: Print information about out_host_hook_obj, substitute
+ into output files.
+ * host-default.c: New file.
+ * hosthooks.h: New file.
+ * toplev.c (general_init): Call host_hooks.extra_signals.
+ * config/rs6000/host-darwin.c: New file.
+ * config/rs6000/x-darwin: New file.
+ * doc/hostconfig.texi: Add documentation for new host hook.
+ Rearrange existing documentation.
+
+2003-02-05 Roger Sayle <roger@eyesopen.com>
+
+ * dwarf2out.c (mem_loc_descriptor): Replace ASM_SIMPLIFY_DWARF_ADDR
+ with *targetm.delegitimize_address.
+ (rtl_for_decl_location): Likewise.
+ * dwarfout.c (output_mem_loc_descriptor): Likewise. Include target.h.
+ * Makefile.in (dwarf2out.c, dwarfout.c): Depend upon $(TARGET_H)
+
+ * config/i386/i386.h (ASM_SIMPLIFY_DWARF_ADDR): Remove definition.
+ * config/i386/i386-protos.h (i386_simplify_dwarf_addr): Remove
+ prototype.
+ * config/i386/i386.c (ix86_delegitimize_address): Renamed from
+ i386_simplify_dwarf_addr. Made static. Prototyped.
+ (TARGET_DELEGITIMIZE_ADDRESS): Update definition from
+ i386_simplify_dwarf_addr to ix86_delegitimize_address.
+ (ix86_find_base_term): Likewise.
+ (maybe_get_pool_constant): Likewise.
+
+ * config/s390/s390.h (ASM_SIMPLIFY_DWARF_ADDR): Remove definition.
+ * config/s390/s390-protos.h (s390_simplify_dwarf_addr): Remove
+ prototype.
+ * config/s390/s390.c (s390_delegitimize_address): Renamed from
+ s390_simplify_dwarf_addr. Made static. Prototyped.
+ (TARGET_DELEGITIMIZE_ADDRESS): Define as s390_delegitimize_address.
+
+2003-02-05 Richard Henderson <rth@redhat.com>
+
+ PR c/8602
+ * integrate.c (output_inline_function): Reset input_filename
+ and lineno from the decl before rest_of_compilation.
+
+2003-02-05 Richard Henderson <rth@redhat.com>
+
+ * defaults.h (CLZ_DEFINED_VALUE_AT_ZERO): New.
+ (CTZ_DEFINED_VALUE_AT_ZERO): New.
+ * doc/rtl.texi, doc/tm.texi: Document them.
+
+ * combine.c (nonzero_bits) [CLZ, CTZ]: Handle the definedness
+ of the value at zero properly.
+ * fold-const.c (tree_expr_nonnegative_p): Likewise.
+ * simplify-rtx.c (simplify_unary_operation): Likewise.
+
+ * config/alpha/alpha.h (CLZ_DEFINED_VALUE_AT_ZERO): New.
+ (CTZ_DEFINED_VALUE_AT_ZERO): New.
+
+ * config/arm/arm.c (TARGET_INIT_BUILTINS): Remove.
+ (TARGET_EXPAND_BUILTIN): Remove.
+ (def_builtin, arm_init_builtins, arm_expand_builtin): Remove.
+ * config/arm/arm.h (CLZ_DEFINED_VALUE_AT_ZERO): New.
+ (enum arm_builtins): Remove.
+ * config/arm/arm.md (UNSPEC_CLZ): Remove.
+ (clzsi2): Rename from clz; use clz instead of unspec.
+ (ctzsi2): New.
+ * config/arm/arm-protos.h: Update.
+
+2003-02-05 Jan Hubicka <jh@suse.cz>
+
+ * i386-protos.h (x86_emit_floatuns): Declare.
+ * i386.c (x86_emit_floatuns): New global function.
+ * i386.md (floatunssisf2, floatunsdisf2,
+ floatunsdidf2): New patterns.
+
+2003-01-25 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopmanip.c (force_single_succ_latches): Fix missindentation.
+
+2003-02-05 Hans Boehm <Hans.Boehm@hp.com>
+
+ * config/ia64/unwind-ia64.c: include coretypes.h, tm.h to get
+ config/ia64/linux.h
+
+2003-02-05 Roger Sayle <roger@eyesopen.com>
+
+ * cfgloop.h (flow_bb_inside_loop_p): Correct prototype again.
+
+2003-02-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR optimization/8555
+ * config/i386/i386.md (sse_mov?fcc split): Handle op2 == op3 case
+ instead of aborting.
+
+2003-02-04 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.md (UNSPEC_BSF): Remove.
+ (ffssi2): Split into cmove and no_cmove insns and splitters;
+ lose pentium float trick for now.
+ (ffssi_1): Add * to name; use CTZ instead of UNSPEC.
+ (ctzsi2, clzsi2, bsr): New.
+
+2003-02-04 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.c (rtx_needs_barrier): Handle POPCOUNT,
+ UNSPEC_GETF_EXP; remove UNSPEC_POPCNT.
+ * config/ia64/ia64.md (UNSPEC_POPCNT): Remove.
+ (ffsdi2): Use popcount instead of unspec.
+ (popcountdi2): Rename from *popcnt.
+ (ctzdi2, clzdi2, getf_exp_tf): New.
+
+2003-02-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * genconfig.c (main): Generate CC0_P.
+ * rtl.h (CC0_P): Remove.
+
+2003-02-04 Richard Henderson <rth@redhat.com>
+
+ * libgcc2.h, libgcc2.c (__ffsSI2): New.
+ (__ffsDI2): Rename from __ffsdi2.
+ * mklibgcc.in (lib2funcs): Add _ffssi2.
+
+2003-02-04 Richard Henderson <rth@redhat.com>
+
+ * libgcc2.c (__paritysi2, __paritydi2): Replace last two reduction
+ rounds with a "bit table" lookup.
+
+2003-02-04 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * reload.c (find_reloads): Do not use the mode specified in the insn
+ pattern as reload mode for address operands. Do not generate optional
+ reloads for operands where a mandatory reload was already pushed.
+
+2003-02-04 Richard Henderson <rth@redhat.com>
+
+ * longlong.h [alpha] (count_leading_zeros, count_trailing_zeros): Use
+ builtins instead of inline assembly.
+
+2003-02-04 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ PR c/9376
+ * libgcc2.c (__subvdi3): Fix typo.
+
+2003-02-04 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (movti_rex64): Fix constraint.
+
+2003-02-04 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (vector push splitters): Fix typo in resolving conflict.
+
+2003-02-04 Rodney Brown <rbrown64@csc.com.au>
+
+ * config/i386/i386.c (x86_function_profiler): Fix typo in format.
+
+2003-02-04 Phil Edwards <pme@gcc.gnu.org>
+
+ * doc/install.texi (*-*-linux-gnu): Mention glibc requirements
+ for recent libstdc++. Remove formatting cruft.
+
+2003-02-04 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2out.c (dwarf2out_finish): Add AT_comp_dir
+ attribute even if input file name is absolute, but one of the
+ includes is relative.
+
+2003-02-04 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * doc/gcc.texi, doc/gccint.texi, doc/gcov.texi,
+ doc/include/fdl.texi, doc/invoke.texi: Update to GFDL 1.2.
+ * doc/install.texi: Update copyright dates. Update to GFDL 1.2.
+
+2003-02-03 Richard Henderson <rth@redhat.com>
+
+ * libgcc2.c (__ffsdi2, __clzsi2, __clzdi2, __ctzsi2, __ctzdi2,
+ __popcountsi2, __popcountdi2, __paritysi2, __paritydi2): Change
+ return type to "int". Shuffle declarations and undef int trap.
+ * libgcc2.h: Remove their declarations.
+ * optabs.c (expand_unop): Force outmode to int for bitops.
+
+2003-02-03 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c (order_regs_for_local_alloc): Order the
+ coprocessor registers before floating-point registers.
+ * config/xtensa/xtensa.h (REG_ALLOC_ORDER): Adjust register numbers
+ to account for a previously removed register.
+ (SPEC_REG_FIRST, SPEC_REG_LAST, SPEC_REG_NUM, COUNT_REGISTER_REGNUM):
+ Delete unused macros.
+
+2003-02-03 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_store_builtin): Always force op1 to register.
+ (mov*_internal): Fix predicates; require one of operands to not be
+ memory.
+ (SSE?MMX move expanders): Fix predicates; force one of operands to
+ register.
+ (SSE/MMX push patterns): Reorganize; fix x86-64 code generation.
+ (movups/movupd/movdqu patterns): Force one of operands to not be
+ memory.
+
+2003-02-03 Roger Sayle <roger@eyesopen.com>
+
+ * hooks.c (hook_rtx_rtx_identity): Generic hook function that
+ takes a single rtx and returns it unmodified.
+ * hooks.h (hook_rtx_rtx_identity): Prototype here.
+ * target.h (struct gcc_target): Add "delegitimize_address"
+ field to target structure.
+ * target-def.h (TARGET_DELEGITIMIZE_ADDRESS): Provide default
+ for delegitimize_address target using hook_rtx_rtx_identity.
+ (TARGET_INITIALIZER): Initialize delegitimize_address field
+ using TARGET_DELEGITIMIZE_ADDRESS macro.
+ * simplify-rtx.c (avoid_constant_pool_reference): Handle float
+ extensions of constant pool references. Use delegitimize_address
+ to undo the obfuscation of "-fpic".
+ * Makefile.in (simplify-rtx.o): Add dependency on target.h.
+
+ * config/i386/i386.c (TARGET_DELEGITIMIZE_ADDRESS): Define as
+ i386_simplify_dwarf_addr.
+ (ix86_find_base_term): Simplify using i386_simplify_dwarf_addr.
+ (maybe_get_pool_constant): Likewise.
+
+2003-02-03 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_int_movcc): Fix setcc sign bit case.
+
+2003-02-03 Jan Hubicka <jh@suse.cz>
+
+ * regclass.c (cannot_change_mode_set_regs): Correct argument order.
+
+2003-02-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mips/_tilib.c: Don't include tsystem.h or defaults.h. Don't
+ define LIBGCC2_WORDS_BIG_ENDIAN. Include coretypes.h and tm.h.
+
+2003-02-02 Andreas Schwab <schwab@suse.de>
+
+ * varasm.c (asm_output_aligned_bss): Declare as possibly unused.
+
+2003-02-02 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (sibcall_epilogue): Set the "conds" to "clob".
+ (epilogue_insns): Likewise.
+
+2003-02-02 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * doc/install.texi (hppa*-hp-hpux11*): Update installation notes.
+
+2003-02-02 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa-protos.h (attr_length_millicode_call): Remove second argument.
+ (attr_length_indirect_call, attr_length_indirect_call,
+ attr_length_save_restore_dltp): New prototypes.
+ * pa.c (attr_length_millicode_call): Remove second argument. Check
+ INSN_ADDRESSES_SET_P in distance calculation.
+ (output_millicode_call): Check INSN_ADDRESSES_SET_P before using
+ INSN_ADDRESSES.
+ (attr_length_call): Check INSN_ADDRESSES_SET_P in distance calculation.
+ (output_call): Check INSN_ADDRESSES_SET_P before using INSN_ADDRESSES.
+ Call attr_length_call directly.
+ (attr_length_indirect_call, output_indirect_call,
+ attr_length_save_restore_dltp): New functions.
+ * pa.md (attr_length_millicode_call): Drop second argument from all
+ patterns.
+ (return_internal_pic): Delete.
+ (return_external_pic): Remove use of PIC register and pic operand and
+ flag checks.
+ (epilogue): Use return_internal for both normal and pic code.
+ (call, call_value): Emit new 32-bit pic patterns for symref and
+ indirect calls. Remove uses for arg pointer and pic register.
+ (call_symref_pic, call_symref_pic_post_reload, call_reg_pic,
+ call_reg_pic_post_reload, call_val_symref_pic,
+ call_val_symref_pic_post_reload, call_val_reg_pic,
+ call_val_reg_pic_post_reload): New pre and post reload insn patterns.
+ Implement define_split and define_peephole2 patterns for pre reload
+ patterns.
+ (call_symref_64bit, call_internal_reg_64bit, call_value_symref_64bit,
+ call_value_internal_reg_64bit): Shorten names.
+ (all call patterns): Explicitly indicate registers used and clobbered.
+ Use attr_length_indirect_call and attr_length_save_restore_dltp for
+ attribute length calculation. Move code generation for indirect calls
+ to output_indirect_call.
+ (sibcall, sibcall_value): Don't restore PIC register.
+ (exception_receiver, builtin_setjmp_receiver): Add blockage after PIC
+ register retore.
+
+2003-02-02 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/install.texi (Testing): Simplify and compress instructions
+ concerning Dejagnu.
+
+2003-02-01 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * collect2.c (pexecute_pid): Rename to pid.
+ (collect_wait, collect_execute, scan_prog_file, scan_libraries): Use
+ pid.
+
+2003-02-01 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/extend.texi (Function Attributes): Remove documentation
+ for PowerPC Windows NT function attributes..
+
+2003-02-01 Daniel Jacobowitz <drow@mvista.com>
+
+ * dwarf2out.c (gen_type_die): Check for typedefs before calling
+ for TYPE_MAIN_VARIANT.
+
+2003-02-01 Richard Henderson <rth@redhat.com>
+
+ * libgcc2.c: Include auto-host.h.
+ (ATTRIBUTE_HIDDEN): New.
+ (__clz_tab): Don't declare here for clz and ctz.
+ (__clzsi2, __clzdi2): Use count_leading_zeros.
+ (__ctzsi2, __ctzdi2): Use count_trailing_zeros.
+ (__popcount_tab): Mark ATTRIBUTE_HIDDEN.
+ (__paritysi2, __paritydi2): Use shifts instead of __popcount_tab.
+ * longlong.h (__clz_tab): Mark ATTRIBUTE_HIDDEN.
+
+2003-02-01 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.md (addsi_1_zext splitter): Add TARGET_64BIT
+ to the conditional.
+ (ashlsi3_1_zext splitter): Likewise.
+
+2003-02-01 Richard Henderson <rth@redhat.com>
+
+ * optabs.c (expand_unop): Use word_mode for outmode of bit scaners.
+ * libgcc2.c (__ffsdi2, __clzsi2, __clzdi2, __ctzsi2, __ctzdi2,
+ __popcountsi2, __popcountdi2, __paritysi2 __paritydi2): Change
+ return type to Wtype.
+
+ * libgcc-std.ver (GCC_3.4): Fix inheritance.
+
+ * config/i386/i386.md (ffssi2): Use nonimmediate_operand for
+ expander input constraint.
+
+2003-02-01 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ * optabs.h (optab_index): Add OTI_clz, OTI_ctz, OTI_popcount and
+ OTI_parity.
+ (clz_optab, ctz_optab, popcount_optab, parity_optab): New.
+ * optabs.c (widen_clz, expand_parity): New.
+ (expand_unop): Handle clz and parity. Hardcode SImode as outmode
+ for libcalls to clz, ctz, popcount, and parity.
+ (init_optabs): Init clz_optab, ctz_optab, popcount_optab and
+ parity_optab, and set up libfunc handlers.
+ * libgcc2.c (__clzsi2, __clzdi2, __ctzsi2, __ctzdi2,
+ __popcountsi2, __popcountdi2, __paritysi2 __paritydi2,
+ __popcount_tab): New.
+ * libgcc2.h: Declare them.
+ * libgcc-std.ver (GCC_3.4): Add new functions from libgcc2.c.
+ * genopinit.c (optabs): Add clz_optab, ctz_optab, popcount_optab
+ and parity_optab.
+ * builtin-types.def (BT_FN_INT_LONG, BT_FN_INT_LONGLONG): New.
+ * builtins.def (BUILT_IN_CLZ, BUILT_IN_CTZ, BUILT_IN_POPCOUNT,
+ BUILT_IN_PARITY, BUILT_IN_FFSL, BUILT_IN_CLZL, BUILT_IN_CTZL,
+ BUILT_IN_POPCOUNTL, BUILT_IN_PARITYL, BUILT_IN_FFSLL,
+ BUILT_IN_CLZLL, BUILT_IN_CTZLL, BUILT_IN_POPCOUNTLL,
+ BUILT_IN_PARITYLL): New.
+ * builtins.c (expand_builtin_unop): Rename from expand_builtin_ffs
+ and add optab argument.
+ (expand_builtin): Expand BUILT_IN_{FFS,CLZ,POPCOUNT,PARITY}*.
+ * tree.def (CLZ_EXPR, CTZ_EXPR, POPCOUNT_EXPR, PARITY_EXPR): New.
+ * expr.c (expand_expr): Handle them.
+ * fold-const.c (tree_expr_nonnegative_p): Likewise.
+ * rtl.def (CLZ, CTZ, POPCOUNT, PARITY): New.
+ * reload1.c (eliminate_regs): Handle them.
+ (elimination_effects): Likewise.
+ * function.c (instantiate_virtual_regs_1): Likewise
+ * genattrtab.c (check_attr_value): Likewise.
+ * simplify-rtx.c (simplify_unary_operation): Likewise.
+ * c-common.c (c_common_truthvalue_conversion): Handle POPCOUNT_EXPR.
+ * combine.c (combine_simplify_rtx): Handle POPCOUNT and PARITY.
+ (nonzero_bits): Handle CLZ, CTZ, POPCOUNT and PARITY.
+ * config/alpha/alpha.md (clzdi2, ctzdi2, popcountdi2): New.
+ * config/arm/arm.c (arm_init_builtins): Rename __builtin_clz to
+ __builtin_arm_clz.
+ * Makefile.in (LIB2FUNCS_1, LIB2FUNCS_2): Move...
+ * mklibgcc.in (lib2funcs): ...here and merge. Add new members.
+ * doc/extend.texi (Other Builtins): Add new builtins.
+ * doc/md.texi (Standard Names): Add new patterns.
+
+2003-02-01 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * reload.c: Revert 2003-01-31 change.
+
+2003-02-01 Jan Hubicka <jh@suse.cz>
+
+ * combine.c (combine_simplify_rtx): Use reversed_comparison_code_parts.
+
+2003-02-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * flags.h (flag_volatile): Remove declaration.
+ (flag_volatile_global, flag_volatile_static): Likewise.
+ * c-typeck.c (build_indirect_ref): Don't check flag_volatile.
+ * toplev.c (flag_volatile): Remove definition.
+ (flag_volatile_global, flag_volatile_static): Likewise.
+ (f_options): Remove corresponding entries here.
+ * varasm.c (make_decl_rtl): Don't check flag_volatile_global
+ or flag_volatile_static.
+ * doc/invoke.texi: Remove documentation of -fvolatile,
+ -fvolatile-global and -fvolatile-static.
+
+2003-01-31 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa.c (pa_output_function_prologue, pa_output_function_epilogue): Move
+ updating of total_code_bytes from prologue to epilogue.
+
+2003-01-31 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * reload.c (find_reloads): Do not use the mode specified in the insn
+ pattern as reload mode for address operands. Do not generate optional
+ reloads for operands where a mandatory reload was already pushed.
+ Generate optional reloads only in the final pass though find_reloads.
+ (have_replacement_p): New function.
+
+2003-01-31 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/install.texi (Testing): Remove a reference to our obsolete
+ /testresults web pages and strip redundant information concerning
+ test results.
+ (Binaries): Refer to Microsoft Windows instead of listing all
+ possible variants.
+
+2003-02-01 Jan Hubicka <jh@suse.cz>
+
+ * loop.c (emit_prefetch_instructions): Do conversion at right place in
+ RTL chain.
+
+ * combine.c (simplify_set): Reverse order of ragumetns to
+ REG_CANNOT_CHANGE_MODE_P
+ * df.c (df_def_record_1): Likewise.
+ * recog.c (register_operand): Likewise.
+ * simplify-rtx.c (simplify_subreg): Likewise.
+ * hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): Update use of
+ CANNOT_CHANGE_MODE_CLASS.
+ * regclass.c (cannot_change_mode_set_regs, invalid_mode_change_p):
+ Likewise.
+ * reload.c (push_reload): Likewise.
+ * alpha.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * ia64.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * mips.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * mips-protos.h (mips_cannot_change_mode_class): Update prototype.
+ * mips.c (mips_cannot_change_mode_class): Update.
+ * pa64-regs.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * rs6000.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * s390.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * sh.h (CANNOT_CHANGE_MODE_CLASS): Update definition.
+ * sh-protos.h (sh_cannot_change_mode_class): Update prototype.
+ * sh.c (sh_cannot_change_mode_class): Update.
+ * i386.h (CANNOT_CHANGE_MODE_CLASS): New.
+ * tm.texi (CANNOT_CHANGE_MODE_CLASS): Update documentation.
+
+2003-01-31 Geoffrey Keating <geoffk@apple.com>
+
+ * config/darwin.h (LINK_COMMAND_SPEC): Update for Nathan's recent
+ change to LINK_COMMAND_SPEC in gcc.c.
+
+2003-01-31 Jan Hubicka <jh@suse.cz>
+
+ PR c/9506
+ * i386.c (override_options): Use DEFAULT_PCC_STRUCT_RETURN.
+
+2003-01-31 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * pa32-regs.h (REGNO_REG_CLASS, REG_CLASS_FROM_LETTER): Delete
+ duplicated code.
+
+2003-01-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.h (TYPE_BINFO_SIZE, TYPE_BINFO_SIZE_UNIT): Remove.
+ (BINFO_ELTS): New #define.
+ * stor-layout.c (finalize_record_size): Don't set them.
+ * cp/cp-tree.h (BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX,
+ BINFO_PRIMARY_BASE_OF): Use BINFO_ELTS.
+ (BINFO_LANG_ELTS): New #define.
+ * cp/tree.c (make_binfo): Use BINFO_LANG_ELTS.
+ * java/class.c (make_class): Use BINFO_ELTS.
+ (set_super_info): Likewse.
+ (add_interface_do): Likewise.
+ * objc/objc-act.c (start_class): Use BINFO_ELTS.
+
+2003-01-31 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * timevar.c (getrusage): Don't ever declare if not HAVE_GETRUSAGE.
+ (times): Don't ever declare if not HAVE_TIMES.
+ (clock): Don't ever declare if not HAVE_CLOCK.
+
+2003-01-30 Richard Henderson <rth@redhat.com>
+
+ * flow.c (update_life_info): Zap life info after cleanup_cfg.
+ (regno_uninitialized): Use correct live at function entry set.
+ (regno_clobbered_at_setjmp): Likewise.
+
+ * expr.c (store_expr): Promote all MEM intermediates to regs.
+
+2003-01-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arm/arm.c: Fix comment typos.
+ * config/arm/arm.h: Likewise.
+ * config/arm/netbsd-elf.h: Likewise.
+ * config/arm/netbsd.h: Likewise.
+
+2003-01-30 Geoffrey Keating <geoffk@apple.com>
+
+ * gengtype.c (struct walk_type_data): Add needs_cast_p.
+ (walk_type): Set needs_cast_p in walk_type_data.
+ (write_types_process_field): Supply casts when required to suppress
+ warnings.
+ (write_root): Cast gt_pch_n_S to suppress warning.
+ * Makefile.in: Remove -Wno-error from gtype-desc.o and c-decl.o.
+ * config/rs6000/rs6000.c (print_operand): Mask off high bits only
+ when they might exist.
+ * config/rs6000/t-rs6000: Remove -Wno-error from varasm.o,
+ insn-conditions.o, and rs6000.o.
+
+2003-01-30 Richard Henderson <rth@redhat.com>
+
+ * ggc-page.c (G.context_depth_allocations): New.
+ (G.context_depth_collections): New.
+ (alloc_page): Set G.context_depth_allocations.
+ (ggc_collect): Set G.context_depth_collections.
+ (ggc_push_context): Limit to HOST_BITS_PER_LONG contexts.
+ (ggc_pop_context): Early exit for no allocations or collections.
+
+2003-01-30 Richard Henderson <rth@redhat.com>
+
+ * tree-inline.c (walk_tree): Streamline duplicate hash table lookup.
+
+2003-01-30 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_compute_initial_elimination_offset): If optimizing for
+ size, the link register is always saved if any other register is
+ saved.
+
+2003-01-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Update the prototype for
+ compute_plussi_cc.
+ (cpp_reader): Declare before it is used.
+ * config/h8300/h8300.c (compute_plussi_cc): Change the return
+ type to int.
+ * config/h8300/h8300.md (monitor_prologue): Call abort() if we
+ see an unknown H8 variant.
+
+2003-01-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
+
+ PR target/9316
+ * config/rs6000/rtems.h: Add CPP_OS_DEFAULT_SPEC.
+ * config/rs6000/sysv4.h: Add CPP_OS_RTEMS_SPEC.
+ * config/rs6000/t-rtems: New file. multilib variants to match OS.
+ * config.gcc (powerpc-*-rtems*): Use rs6000/t-rtems instead of
+ rs6000/t-ppcgas so we get the desired multilibs.
+
+2003-01-30 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.c (arm_output_epilogue): Update stack pointer
+ when popping saved IP register off the stack.
+
+2003-01-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/rs6000/aix43.h: Fix comment typos.
+ * config/rs6000/aix51.h: Likewise.
+ * config/rs6000/aix52.h: Likewise.
+ * config/rs6000/altivec.h: Likewise.
+ * config/rs6000/rs6000.c: Likewise.
+ * config/rs6000/rs6000.h: Likewise.
+ * config/rs6000/rs6000.md: Likewise.
+ * config/rs6000/spe.md: Likewise.
+
+2003-01-29 Mark Mitchell <mark@codesourcery.com>
+
+ * c-common.c (builtin_define_float_constants): Define
+ __<TYPE>_HAS_INFINITY__ and __<TYPE>_HAS_QUIET_NAN__.
+
+2003-01-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/sh/lib1funcs.asm: Fix comment typos.
+ * config/sh/linux.h: Likewise.
+ * config/sh/sh.c: Likewise.
+ * config/sh/sh.md: Likewise.
+
+2003-01-30 Loren James Rittle <ljrittle@acm.org>
+
+ * objc/Make-lang.in (objc-parse.y): Find c-parse.in in $(srcdir).
+
+2003-01-30 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/fp-bit.h (__make_dp): Declare if TMODES.
+
+2003-01-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (PREDICATE_CODES): Add entries for
+ general_operand_src and general_operand_dst.
+
+2003-01-29 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (function_arg_pass_by_reference):
+ Return true for variable sized types.
+ (rs6000_va_arg): Handle variable sized types passed by reference
+ on non-SVR4 ABI.
+
+2003-01-29 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_legtimize_address): New function.
+ * arm-protos.h (arm_legtimize_address): Add prototype.
+ * arm.h (ARM_LEGITIMIZE_ADDRESS): Use arm_legitimize_address.
+ (LEGITIMIZE_ADDRESS, THUMB_LEGITIMIZE_ADDRESS): Wrap with
+ do ... while (0)
+
+2003-01-29 Joel Sherrill <joel@OARcorp.com>
+
+ PR bootstrap/9296
+ * gthr-rtems.h: Define __GTHREAD_MUTEX_INIT. Apparently no code
+ depended on it being defined until now.
+
+2003-01-29 Joel Sherrill <joel@OARcorp.com>
+
+ PR target/9295
+ * config/mips/rtems.h: Predefine __USE_INIT_FINI__ so generic
+ RTEMS code knows which C++ initialization style the toolset
+ configuration is using.
+
+2003-01-29 Joel Sherrill <joel@OARcorp.com>
+
+ PR bootstrap/9293
+ * config/m68k/t-crtstuff: Replace spaces with tabs, add
+ $(MULTILIB_CFLAGS) as compiler option and multilib crtbegin/end.o.
+
+2003-01-29 Joel Sherrill <joel@OARcorp.com>
+
+ PR bootstrap/9292
+ * config.gcc (hppa1.1-rtems): Did not include t-rtems nor enable
+ RTEMS threads.
+ * config/pa/rtems.h (LIB_SPEC): Use -N when linking.
+
+2003-01-29 Nick Clifton <nickc@redhat.com>
+
+ * Makefile.in (c-parse.o): Locate source file in $(parsedir)
+ not $(srcdir).
+
+2003-01-29 Andrew Haley <aph@redhat.com>
+
+ * tree-inline.c (walk_tree): Add CHAR_TYPE.
+
+2003-01-29 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (subdi3_carry_rex64): Fix typo.
+
+2003-01-28 Stan Shebs <shebs@apple.com>
+
+ * coretypes.h (cpp_reader): Forward declare struct.
+ * c-pragma.h (cpp_reader): Remove forward declaration.
+ * hashtable.h (cpp_reader): Likewise.
+ * scan.h (cpp_reader): Likewise.
+ * tree.h (cpp_reader): Likewise.
+ * config/darwin-protos.h (cpp_reader): Likewise.
+ * config/arm/arm-protos.h (cpp_reader): Likewise.
+ * config/rs6000/rs6000-protos.h: Remove GCC_CPPLIB_H ifdef, use
+ struct cpp_reader in prototypes.
+
+2003-01-28 Christian Cornelssen <ccorn@cs.tu-berlin.de>
+
+ * doc/install.texi: Add documentation for installation into
+ tooldirs and with DESTDIR.
+
+2003-01-28 Richard Henderson <rth@redhat.com>
+
+ * config.gcc (ia64*-*-aix*): Remove.
+ * config/ia64/aix.h, config/ia64/t-aix: Remove file.
+ * config/ia64/unwind-aix.c: Remove file.
+
+2003-01-28 Andreas Schwab <schwab@suse.de>
+
+ * config/m68k/m68k.md (tablejump+2): Don't sign extend an address
+ register.
+ * config/m68k/apollo68.h (ASM_RETURN_CASE_JUMP): Likewise.
+ * config/m68k/coff.h (ASM_RETURN_CASE_JUMP): Likewise.
+ * config/m68k/linux.h (ASM_RETURN_CASE_JUMP): Likewise.
+ * config/m68k/m68kelf.h (ASM_RETURN_CASE_JUMP): Likewise.
+ * config/m68k/mot3300.h (ASM_RETURN_CASE_JUMP): Likewise.
+ * config/m68k/netbsd-elf.h (ASM_RETURN_CASE_JUMP): Likewise.
+ * config/m68k/pbb.h (ASM_RETURN_CASE_JUMP): Likewise.
+
+2003-01-28 Richard Sandiford <rsandifo@redhat.com>
+
+ * combine.c (nonzero_bits): Fix check for negative divide operands.
+
+2003-01-28 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.c (ia64_rwreloc_section_type_flags): New.
+ * config/ia64/hpux.h (TARGET_SECTION_TYPE_FLAGS): New.
+
+2003-01-28 Richard Henderson <rth@redhat.com>
+
+ * cse.c (find_best_addr): Kill !ADDRESS_COST code.
+
+ * config/cris/cris.c (cris_address_cost): Make static.
+ (TARGET_RTX_COSTS, TARGET_ADDRESS_COST): New.
+ * config/cris/cris.h (ADDRESS_COST): Remove.
+ * config/cris/cris-protos.h: Update.
+
+2003-01-23 Mike Stump <mrs@apple.com>
+
+ * regclass.c (init_reg_autoinc): New function.
+ (regclass): Move initialization of forbidden_inc_dec_class from
+ here...
+ (init_regs): to here. Avoids reinitialization for each function,
+ saving compilation time.
+
+2003-01-28 Jason Merrill <jason@redhat.com>
+
+ * cpplib.h (struct cpp_options): Add warn_deprecated field.
+ * cppinit.c (cpp_create_reader): Turn it on by default.
+ * c-opts.c (c_common_decode_option): Set it.
+ * cpplib.c (do_pragma_once): Only complain about #pragma once
+ if warn_deprecated is set.
+
+2003-01-28 Dale Johannesen <dalej@apple.com>
+
+ * emit-rtl.c (const_double_htab_hash): Use mode in the hash.
+ * loop.c (scan_loop): Move movables on -Os rich-register targets.
+ * config/rs6000/rs6000.md (sibcall*): Use match_operand for LR.
+
+2003-01-28 Richard Henderson <rth@redhat.com>
+
+ * target.h (targetm.address_cost): New.
+ * target-def.h (TARGET_ADDRESS_COST): New.
+ (TARGET_RTX_COSTS): Uncomment. Oops.
+ * cse.c (address_cost): Use new target hook.
+ (default_address_cost): New.
+ * output.h (default_address_cost): Declare.
+ * hooks.c (hook_int_rtx_0): New.
+ * hooks.h (hook_int_rtx_0): Declare.
+ * loop.c (combine_givs_p): Remove if 0 code.
+ * system.h (ADDRESS_COST): Poison.
+
+ * config/alpha/alpha.c, config/alpha/alpha.h, config/d30v/d30v.c,
+ config/d30v/d30v.h, config/ia64/ia64.c, config/ia64/ia64.h,
+ config/m32r/m32r.c, config/m32r/m32r.h, config/mcore/mcore.c,
+ config/mcore/mcore.h, config/mmix/mmix.c, config/mmix/mmix.h,
+ config/rs6000/rs6000.c, config/rs6000/rs6000.h, config/sparc/sparc.c,
+ config/sparc/sparc.h, config/v850/v850.c, config/v850/v850.h,
+ config/xtensa/xtensa.c, config/xtensa/xtensa.h
+ (TARGET_ADDRESS_COST): Define as hook_int_rtx_0.
+ (ADDRESS_COST): Remove.
+
+ * config/arc/arc-protos.h, config/arc/arc.c, config/arc/arc.h,
+ config/avr/avr-protos.h, config/avr/avr.c, config/avr/avr.h,
+ config/c4x/c4x-protos.h, config/c4x/c4x.c, config/c4x/c4x.h,
+ config/dsp16xx/dsp16xx-protos.h, config/dsp16xx/dsp16xx.c,
+ config/dsp16xx/dsp16xx.h, config/i386/i386-protos.h,
+ config/i386/i386.c, config/i386/i386.h, config/i960/i960-protos.h,
+ config/i960/i960.c, config/i960/i960.h, config/ip2k/ip2k-protos.h,
+ config/ip2k/ip2k.c, config/ip2k/ip2k.h, config/mips/mips-protos.h,
+ config/mips/mips.c, config/mips/mips.h,
+ config/m68hc11/m68hc11-protos.h, config/m68hc11/m68hc11.c,
+ config/m68hc11/m68hc11.h, config/ns32k/ns32k-protos.h,
+ config/ns32k/ns32k.c, config/ns32k/ns32k.h, config/pa/pa-protos.h,
+ config/pa/pa.c, config/pa/pa.h, config/s390/s390-protos.h,
+ config/s390/s390.c, config/s390/s390.h, config/vax/vax-protos.h,
+ config/vax/vax.c, config/vax/vax.h
+ (foo_address_cost): Make static.
+ (TARGET_ADDRESS_COST): New.
+ (ADDRESS_COST): Remove.
+
+ * config/arm/arm.h, config/arm/arm.c, config/m88k/m88k.h,
+ config/m88k/m88k.c, config/romp/romp.h, config/romp/romp.c,
+ config/sh/sh.c, config/sh/sh.h, config/stormy16/stormy16.c,
+ config/stormy16/stormy16.h
+ (ADDRESS_COST): Move code ...
+ (foo_address_cost): ... here.
+ (TARGET_ADDRESS_COST): New.
+
+ * config/m32r/m32r.c (m32r_address_cost): Remove.
+ * config/m32r/m32r-protos.h: Update.
+
+ * config/mmix/mmix.c (mmix_address_cost): Remove.
+ * config/mmix/mmix-protos.h: Update.
+
+ * config/mn10300/mn10300.c (mn10300_address_cost_1): Rename from
+ mn10300_address_cost; move unsig allocation ...
+ (mn10300_address_cost): ... here.
+ (TARGET_ADDRESS_COST): New.
+ * config/mn10300/mn10300-protos.h: Update.
+ * config/mn10300/mn10300.h (ADDRESS_COST): Remove.
+
+ * doc/tm.texi: Update.
+
+2003-01-28 Vladimir Makarov <vmakarov@redhat.com>
+
+ * haifa-sched.c (schedule_insn): Return necessary cycle advance
+ after issuing the insn.
+ (rank_for_schedule): Make a insn with /S the highest priority
+ insn.
+ (move_insn): Ignore schedule groups. Clear SCHED_GROUP_P.
+ (choose_ready): Check SCHED_GROUP_P.
+ (schedule_block): Advance cycle after issuing insn if it is
+ necessary. Don't reorder insns if there is an insn with /S.
+ (set_priorities): Ignore schedule groups.
+
+ * sched-deps.c (remove_dependence, group_leader): Remove the
+ functions.
+ (add_dependence): Ignore schedule groups.
+ (set_sched_group_p): Don't make copy of dependencies from previous
+ insn of the schedule group. Add anti-dependency to the previous
+ insn of the schedule group.
+ (compute_forward_dependences): Ignore schedule groups.
+
+ * sched-ebb.c (init_ready_list): Ignore schedule groups.
+
+ * sched-rgn.c (init_ready_list): Ditto.
+ (can_schedule_ready_p): Ditto.
+
+2003-01-28 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/i386/i386.md (*movsi_1): Use movdqa to move one xmm
+ register to another one.
+
+2003-01-28 Richard Henderson <rth@redhat.com>
+
+ * calls.c (default_must_pass_in_stack): Fix typo in !type case.
+
+2003-01-28 Roger Sayle <roger@eyesopen.com>
+
+ * cse.c (cse_insn): Avoid redundant REG_EQUAL notes.
+
+2003-01-28 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/sh/sh.h (CLASS_MAX_NREGS): If TARGET_SHMEDIA, and the given
+ class contains a floating-point register, return the size of the
+ mode in half words.
+
+2003-01-28 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_carry_flag_operator): New predicate.
+ (fcmov_operator): Fix whitespace.
+ (ix86_expand_carry_flag_compare): Deal with floating point.
+ (ix86_expand_int_movcc): Deal with fp; update insn expansion
+ (ix86_expand_int_addcc): Likewise.
+ (ix86_expand_strlensi_unroll_1): likewsie.
+ * i386.h (PREDICATE_CODES): Add ix86_carry_flag_operator.
+ * i386.md (add?i_carry_rex64): Use new predicate.
+ (sub?i3_carry_rex64): Likewise.
+ (x86_mov?icc_0_m1*): Likewise.
+
+2003-01-28 Andreas Schwab <schwab@suse.de>
+
+ * cfgloopmanip.c (create_preheader): Initialize src to avoid
+ warning.
+
+ * expmed.c (emit_store_flag): Fix cast to avoid sign
+ comparison warning.
+
+ * combine.c (force_to_mode): Add cast to fix warning when
+ STORE_FLAG_VALUE is negative.
+
+2003-01-27 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (cse.o): Depend on TARGET_H.
+ * cse.c (rtx_cost): Use targetm.rtx_costs.
+ * system.h (CONST_COSTS RTX_COSTS DEFAULT_RTX_COSTS): Poison.
+ * doc/tm.texi: Update.
+
+ * target.h (targetm.rtx_costs): New.
+ * target-def.h (TARGET_RTX_COSTS): New.
+ * hooks.c (hook_bool_rtx_int_int_intp_false): New.
+ * hooks.h: Update.
+
+ * config/alpha/alpha.c (alpha_rtx_cost_data): New.
+ (alpha_rtx_costs, TARGET_RTX_COSTS): New.
+ * config/alpha/alpha.h (PROCESSOR_MAX): New.
+ (CONST_COSTS, RTX_COSTS): Remove.
+
+ * config/arc/arc.c, config/arc/arc.h, config/c4x/c4x.c,
+ config/c4x/c4x.h, config/cris/cris.c, config/cris/cris.h,
+ config/d30v/d30v.c, config/d30v/d30v.h, config/dsp16xx/dsp16xx.c,
+ config/dsp16xx/dsp16xx.h, config/frv/frv.c, config/frv/frv.h,
+ config/h8300/h8300.c, config/h8300/h8300.h, config/i370/i370.c,
+ config/i370/i370.h, config/i386/i386.c, config/i386/i386.h,
+ config/i960/i960.c, config/i960/i960.h, config/ia64/ia64.c,
+ config/ia64/ia64.h, config/m32r/m32r.c, config/m32r/m32r.h,
+ config/m68k/m68k.c, config/m68k/m68k.h, config/m88k/m88k.c,
+ config/m88k/m88k.h, config/mcore/mcore.c, config/mcore/mcore.h,
+ config/mips/mips.c, config/mips/mips.h, config/mn10200/mn10200.c,
+ config/mn10200/mn10200.h, config/mn10300/mn10300.c,
+ config/mn10300/mn10300.h, config/ns32k/ns32k.c, config/ns32k/ns32k.h,
+ config/pa/pa.c, config/pa/pa.h, config/pdp11/pdp11.c,
+ config/pdp11/pdp11.h, config/romp/romp.c, config/romp/romp.h,
+ config/rs6000/rs6000.c, config/rs6000/rs6000.h, config/s390/s390.c,
+ config/s390/s390.h, config/sh/sh.c, config/sh/sh.h,
+ config/stormy16/stormy16.c, config/stormy16/stormy16.h,
+ config/v850/v850.c, config/v850/v850.h,
+ config/xtensa/xtensa.c, config/xtensa/xtensa.h
+ (CONST_COSTS, RTX_COSTS): Move code ...
+ (foo_rtx_costs, TARGET_RTX_COSTS): ... here.
+
+ * config/arm/arm.c (arm_rtx_costs_1): Rename from arm_rtx_costs.
+ (arm_rtx_costs, TARGET_RTX_COSTS): New.
+ * config/arm/arm-protos.h: Update.
+ * config/arm/arm.h (DEFAULT_RTX_COSTS): Remove.
+
+ * config/avr/avr.h (CONST_COSTS): Move code ...
+ * config/avr/avr.c (avr_rtx_costs): ... here.
+ (default_rtx_costs): Make static.
+ * config/avr/avr-protos.h: Update.
+
+ * config/h8300/h8300.c (const_costs): Make static.
+ (h8300_and_costs, h8300_shift_costs): Likewise.
+ * config/h8300/h8300-protos.h: Update.
+
+ * config/ip2k/ip2k.h (DEFAULT_RTX_COSTS): Remove.
+ (CONST_COSTS): Move code ...
+ * config/ip2k/ip2k.c (ip2k_rtx_costs): ... here. Rename from
+ default_rtx_costs; update for signature change.
+ * config/ip2k/ip2k-protos.h: Update.
+
+ * config/m68hc11/m68hc11.h (RTX_COSTS): Remove.
+ (CONST_COSTS): Move code ...
+ * config/m68hc11/m68hc11.c (m68hc11_rtx_costs): ... here.
+ (TARGET_RTX_COSTS): New.
+ (m68hc11_rtx_costs_1): Rename from m68hc11_rtx_costs; make static.
+ * config/m68hc11/m68hc11-protos.h: Update.
+
+ * config/m68k/m68k.c (const_int_cost): Make static.
+ * config/m68k/m68k-protos.h: Update.
+
+ * config/mcore/mcore.c (mcore_const_costs): Make static.
+ (mcore_and_cost, mcore_ior_cost): Likewise.
+ * config/mcore/mcore-protos.h: Update.
+
+ * config/mmix/mmix.c (mmix_rtx_costs, TARGET_RTX_COSTS): New.
+ (mmix_rtx_cost_recalculated): Remove.
+ * config/mmix/mmix.h (DEFAULT_RTX_COSTS): Remove.
+ * config/mmix/mmix-protos.h: Update.
+
+ * config/sh/sh.c (shiftcosts): Make static.
+ (addsubcosts, andcosts, multcosts): Likewise.
+ * config/sh/sh-protos.h: Update.
+
+ * config/sparc/sparc.c (TARGET_RTX_COSTS): New.
+ (sparc_rtx_costs): Make static; update for change in signature.
+ * config/sparc/sparc.h (RTX_COSTS_CASES, RTX_COSTS): Remove.
+ * config/sparc/sparc-protos.h: Update.
+
+ * config/v850/v850.c (const_costs): Make static.
+ * config/v850/v850-protos.h: Update.
+
+ * config/vax/vax.h (RTX_COSTS): Remove.
+ (CONST_COSTS): Move code ...
+ * config/vax/vax.c (vax_rtx_costs_1): ... here; rename
+ from vax_rtx_cost.
+ (vax_rtx_costs, TARGET_RTX_COSTS): New.
+
+2003-01-27 Richard Henderson <rth@redhat.com>
+
+ * config/vax/vax.h (ASM_OUTPUT_MI_THUNK): Remove. Really.
+ * config/vax/vax-protos.h: Update. Really.
+
+2003-01-28 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mips/mips.h (UNITS_PER_HWFPVALUE): Renamed from...
+ (UNITS_PER_FPVALUE): Defined as the width of a long double, or
+ zero if no hardware floating point.
+ (LONG_DUBLE_TYPE_SIZE): Set to 128 on N32 and N64.
+ (MAX_FIXED_MODE_SIZE): Define to LONG_DOUBLE_TYPE_SIZE.
+ (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define.
+ (BIGGEST_ALIGNMENT): Same as LONG_DOUBLE_TYPE_SIZE.
+ (FUNCTION_VALUE_REGNO_P): Set for FP_RETURN+2 on N32 and N64.
+ * config/mips/mips.c (mips_arg_info): Pass TFmode values in
+ even FP registers on N32 and N64.
+ (mips_setup_incoming_varargs): Use UNITS_PER_HWFPVALUE.
+ (mips_va_start): Adjust alignment of ARG_POINTER_REGNUM.
+ (mips_va_arg): Use UNITS_PER_HWFPVALUE. Impose additional
+ even-register-like alignment to 128-bit arguments.
+ (save_restore_insns): Use UNITS_PER_HWFPVALUE.
+ (mips_function_value): Likewise. Return TFmode in $f0 and $f2
+ on N32 or N64.
+ * config/mips/_tilib.c (__negti2, __ashlti3, __lshrti3): New.
+ * config/mips/t-iris6 (LIB2FUNCS_EXTRA): Add _tilib.c.
+ (TPBIT): Set to tp-bit.c.
+ (tp-bit.c): Create out of fp-bit.c.
+
+2003-01-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-parse.in: Remove '%expect 32' directive in objc mode.
+
+2003-01-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * Makefile.in (LIB2FUNCS_ST): Remove _gcov.
+ (LIBGCOV): New variable.
+ (libgcc.mk): Add LIBGCOV.
+ (LIBGCC_DEPS): Add libgcov.c.
+ (libgcov.a): New target.
+ (clean): Remove libgcov.a.
+ (install-libgcc): Do libgcov too.
+ (stage1-start, stage2-start, stage3-start, stage4-start): Deal
+ with libgcov.a.
+ * libgcc2.c (L_gcov): Move into ...
+ * libgcov.c: ... here. New file.
+ * mklibgcc.in: Add libgcov rules.
+ * gcc.c (LINK_COMMAND_SPEC): Add -lgcov when profiling.
+
+ * doc/invoke.texi (profile-arcs, test-coverage): Update and
+ clarify.
+
+ * profile.c (index_counts_file): Remove duplicate check for open file.
+
+2003-01-27 Jerry Quinn <jlquinn@optonline.net>
+
+ * gcc/doc/invoke.texi (Optimization Options): Group together
+ optional and experimental flags. Move trapv and bounds-check
+ out of this section. Group floating point flags together.
+ (Code Gen Options): Move trapv and bounds-check to here.
+
+2003-01-27 Josef Zlomek <zlomekj@suse.cz>
+
+ * gcse.c (constprop_register): Check NEXT_INSN (insn) != NULL.
+
+2003-01-27 Richard Earnshaw <rearnsha@arm.com>
+
+ PR optimization/9090
+ * function.c (purge_addressof_1): After pushing an addressed register
+ onto the stack, simplify the result.
+
+2003-01-27 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * doc/extend.texi: Fix typo.
+
+2003-01-27 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * doc/cppopts.texi: Fix typo.
+ * doc/objc.texi: Likewise.
+ * doc/passes.texi: Likewise.
+
+2003-01-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * real.c (ibm_extended_format): Add 53 to minimum exponent.
+ (encode_ibm_extended): Adjust.
+
+2003-01-26 Gabriel Dos Reis <gdr@soliton.integrable-solutions.net>
+
+ * timevar.def (TV_OVERLOAD, TV_TEMPLATE_INSTANTIATION): New
+ timevar_id enumerations.
+
+2003-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c: Fix formatting.
+
+2003-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/gccint.texi: Update the copyright.
+
+2003-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * doc/cpp.texi: Fix typos.
+ * doc/extend.texi: Likewise.
+ * doc/gty.texi: Likewise.
+ * doc/install.texi: Likewise.
+ * doc/passes.texi: Likewise.
+ * doc/rtl.texi: Likewise.
+ * doc/tm.texi: Likewise.
+
+2003-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/ia64/fde-glibc.c: Fix comment typos.
+ * config/ia64/hpux.h: Likewise.
+ * config/ia64/ia64.c: Likewise.
+ * config/ia64/ia64.h: Likewise.
+ * config/ia64/unwind-ia64.c: Likewise.
+
+2003-01-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/i386/i386-modes.def: Fix comment typos.
+ * config/i386/i386.c: Likewise.
+ * config/i386/i386.md: Likewise.
+
+2003-01-26 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * config/avr/avr.h, config/cris/aout.h, config/elfos.h,
+ config/i386/freebsd-aout.h, config/mips/iris6.h: Undefine
+ ASM_FINISH_DECLARE_OBJECT before defining it.
+ * toplev.c (rest_of_decl_compilation): Don't define
+ ASM_FINISH_DECLARE_OBJECT. Only use it if it is defined.
+ (rest_of_type_compilation): Don't ATTRIBUTE_UNUSED function
+ parameters for DWARF2 targets because they _are_ used.
+
+2003-01-26 Alexandre Oliva <aoliva@redhat.com>
+
+ * fp-bit.h: Define macros for TFmode floating-point constants
+ in IBM-extended TFmode types.
+ (TMODES): Define if __LDBL_MANT_DIG__ has the newly-supported
+ widths.
+ * config/fp-bit.c (pack_d, unpack_d): Support IBM-extended
+ TFmode type.
+
+ * config/fp-bit.h: Define macros for TFmode floating-point
+ constants in IEEE quad TFmode type. Declare functions according
+ to L_ macros.
+ (TMODES): Define if __LDBL_MANT_DIG__ is 113.
+ (TFtype, TItype, UTItype): Define if TMODES is defined.
+ (MAX_UDI_INT, MAX_DI_INT, BITS_PER_DI): Likewise.
+ (F_T_BITOFF, D_T_BITOFF): Define.
+ (IMPLICIT_1, IMPLICIT_2): Cast constants to types that are
+ guaranteed to be wide enough.
+ * config/fp-bit.c: Check for L_ macros for tf functions.
+ (__thenan_tf): New.
+ (nan): Adjust.
+ (pack_d, unpack_d): Support IEEE 854 quad type.
+ (_fpmul_parts): Support TFmode. Compute exponent adjustment
+ from FRAC_NBITS, FRAC_BITS and NGARDS.
+ (usi_to_float): Cast constants to be shifted to fractype
+ instead of assuming long long is wide enough.
+ (sf_to_tf, df_to_tf, __make_tp, tf_to_df, tf_to_sf): New.
+
+2003-01-26 Andreas Jaeger <aj@suse.de>
+
+ * df.c: Remove prototype of unused function df_regno_rtl_debug.
+
+2003-01-26 Alexandre Oliva <aoliva@redhat.com>
+
+ * Makefile.in (FPBIT_FUNCS): Added _sf_to_tf.
+ (DBBIT_FUNCS): Added _df_to_tf.
+ (TPBIT_FUNCS): New.
+ (libgcc.mk): Pass TPBIT and TPBIT_FUNCS down.
+ (LIBGCC_DEPS): Added TPBIT.
+ * mklibgcc.in: Support TPBIT and TPBIT_FUNCS.
+
+ * optabs.c (expand_binop) <add, sub>: Return xtarget if we haven't
+ been able to move the result to target.
+
+ * expr.c (emit_group_store): Initialize dst with CONST0_RTX
+ for the appropriate mode.
+
+ * calls.c (emit_library_call_value_1): Handle return values
+ in a PARALLEL.
+
+ * rtl.c (get_mode_alignment): Moved to...
+ * stor-layout.c: ... here.
+
+ * print-rtl.c (print_rtx): Don't print MEM details in
+ GENERATOR_FILEs.
+
+2003-01-26 Michael Hayes <mph@paradise.net.nz>
+
+ * df.h: Update comments, tidy formatting.
+ (DF_FORWARD, DF_REVERSE, DF_UNION, DF_INTERSECTION): Rename from FORWARD,
+ REVERSE, UNION, INTERSECTION. All uses updated.
+ (OLD_DF_INTERFACE): Remove.
+ (struct insn_info): Remove commented out insn field.
+ * df.c: Update comments, tidy formatting.
+ (df_def_table_realloc): Remove.
+
+
+2003-01-26 Alan Modra <amodra@bigpond.net.au>
+
+ * calls.c (save_fixed_argument_area): Tidy.
+ (restore_fixed_argument_area): Tidy. Set alignment of stack_area.
+ (expand_call): Comment typo fixes. Don't init low_to_save. Start
+ call chain loop at 1 if !try_tail_call. Formatting.
+ (emit_library_call_value_1): Don't init low_to_save or high_to_save.
+ Use save_fixed_argument_area and restore_fixed_argument_area.
+
+2003-01-26 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * df.c (df_uses_record): Handle CC0.
+
+2003-01-25 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * reload.c (maybe_memory_address_p): New function.
+ (find_reloads_address): Use it instead of memory_address_p.
+
+2003-01-25 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * final.c (shorten_branches): Align the address of code label
+ when computing initial lengths and addresses.
+
+2003-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/m68hc11/m68hc11.md: Fix a comment typo.
+
+2003-01-25 Andreas Jaeger <aj@suse.de>
+
+ * config/i386/i386.c (x86_output_mi_thunk): Correct test for
+ TARGET_MACHO.
+
+2003-01-25 Roger Sayle <roger@eyesopen.com>
+
+ * gcse.c (bypass_last_basic_block): New global variable.
+ (bypass_block): Use redirect_edge_and_branch_force to redirect
+ fall-through edges. Use bypass_last_basic_block to determine
+ which blocks have valid PRE information.
+ (bypass_conditional_jumps): Initialize bypass_last_basic_block.
+
+2003-01-25 Jan Hubicka <jh@suse.cz>
+
+ * gcse.c (local_cprop_pass): Update reg_sets table when needed.
+
+2003-01-25 Jan Hubicka <jh@suse.cz>
+ Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR opt/8492
+ * gcse.c (one_cprop_pass): Delete unreachable blocks.
+
+2003-01-25 Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.c (ia64_rwreloc_select_rtx_section): Rename
+ from ia64_aix_select_rtx_section.
+ (ia64_rwreloc_select_section): Simlarly; use default*_1 function
+ instead of saving and restoring flag_pic.
+ (ia64_rwreloc_unique_section): Similarly.
+ * config/ia64/aix.h (TARGET_ASM_SELECT_SECTION,
+ TARGET_ASM_UNIQUE_SECTION, TARGET_ASM_SELECT_RTX_SECTION): Update.
+ * config/ia64/hpux.h (TARGET_ASM_SELECT_SECTION,
+ TARGET_ASM_UNIQUE_SECTION, TARGET_ASM_SELECT_RTX_SECTION): New.
+
+2003-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_shift_needs_scratch_p): Update a
+ comment.
+
+2003-01-25 Richard Henderson <rth@redhat.com>
+
+ * config/m68k/m68k-none.h (ASM_SPEC): Adjust inter-option spacing.
+
+2003-01-25 Kelley Cook <kelleycook@comcast.net>
+
+ * ggc-simple.c (debug_ggc_tree): Add PTR cast.
+
+2003-01-25 Segher Boessenkool <segher@koffie.nl>
+
+ * bitmap.h (BITMAP_WORD): New typedef: fundamental storage
+ type for bitmaps. Use unsigned long.
+ (nBITMAP_WORD_BITS): New macro.
+ (BITMAP_WORD_BITS): New macro.
+ (rest of file): Use it.
+ * bitmap.c: Use it.
+
+2003-01-25 Richard Henderson <rth@redhat.com>
+
+ 2002-02-19 Robert Lipe <robertlipe@usa.net>
+ * config/i386/t-sco5gas: (CRTSTUFF_T_CFLAGS_S): Delete -mcoff.
+
+2003-01-25 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.c (purge_builtin_constant_p): Scan insn stream
+ sequentially rather than by basic block.
+ * function.c (purge_addressof): Simplify test with INSN_P.
+
+2003-01-25 Kazu Hirata <kazu@cs.umass.edu>
+
+ * combine.c (simplify_comparison, case AND): Remove a redundant test.
+
+2003-01-25 Roger Sayle <roger@eyesopen.com>
+
+ * function.h (struct function): New field calls_constant_p.
+ (current_function_calls_constant_p): New macro for above.
+ * function.c (prepare_function_start): Initialize calls_eh_return
+ and calls_constant_p.
+ * builtins.c (expand_builtin_constant_p): Set calls_constant_p.
+ * toplev.c (rest_of_compilation): Only call purge_builtin_constant_p
+ when the current_function_calls_constant_p.
+ * integrate.c (expand_inline_function): Set calls_constant_p if
+ the function being inlined has calls_constant_p set.
+
+2003-01-25 Roger Sayle <roger@eyesopen.com>
+
+ * cse.c (fold_rtx): Instantiate CONSTANT_P_RTX to 0 when not
+ optimizing, even if flag_gcse is true.
+ * toplev.c (rest_of_compilation): purge_builtin_constant_p
+ only needs to be called when "optimize > 0 && flag_gcse".
+
+2003-01-25 Roger Sayle <roger@eyesopen.com>
+
+ * stmt.c (emit_case_bit_tests): New routine to implement suitable
+ switch statements using the equivalent of "if ((1<<x) & cst) ... ".
+ (case_bit_test_cmp): New comparison function for "qsort" to order
+ case_bit_tests by decreasing number of destination nodes.
+ (lshift_cheap_p): New function to determine if "1 << x" is cheap.
+ (expand_end_case_type): Use emit_case_bit_tests to implement
+ suitable switch statments.
+ (CASE_USE_BIT_TESTS): New target macro to disable the above.
+ * Makefile.in (stmt.o): Add dependency on optab.h.
+ * doc/tm.texi (CASE_USE_BIT_TESTS): Document new target macro.
+
+2003-01-23 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/crtend.asm [HAVE_INITFINI_ARRAY]: Make
+ __do_global_ctors_aux hidden global and don't put it in
+ .init_array.
+ * config/ia64/crtbegin.asm [HAVE_INITFINI_ARRAY]: Put it here
+ instead so that it comes first.
+
+2003-01-25 Jan Hubicka <jh@suse.cz>
+
+ * df.c (read_modify_subreg_p): When osize == UNITS_PER_WORD,
+ subreg is read/modify.
+
+2003-01-25 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_movstr, ix86_expand_clrstr): Consistently
+ do libcall for large blocks.
+ * i386.md (comi patterns): Set type to ssecomi.
+ (sse2_unpck?pd): Fix mode of vec_select.
+
+ * cse.c: Include except.h
+ (cse_set_around_loop): Do not create new basic blocks.
+ * Makefile.in (cse.o): Add dependnecy on except.h
+
+2003-01-25 Jan Hubicka <jh@suse.cz>
+
+ * builtins.c (fold_trunc_transparent_mathfn): New function.
+ (fold_builtin): Use it.
+ * convert.c (convert_to_real): Re-enable code to convert
+ math functions; add support for floor familly functions.
+
+2003-01-25 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * Makefile.in (cfgloop.o, cfgloopanal.o, cfgloopmanip.o): Add
+ dependencies on coretypes.h and $(TM_H).
+
+2003-01-25 Jan Hubicka <jh@suse.cz>
+
+ * builtins.c (fold_trunc_transparent_mathfn): Undo accidental commit.
+
+2003-01-24 Stuart Hastings <stuart@apple.com>
+
+ * config/i386/i386.c (x86_output_mi_thunk): Add Darwin/x86 support.
+
+2003-01-25 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.md (UNSPEC_BU): New constants.
+ (UNSPEC_RPTS, UNSPEC_LSH, UNSPEC_CMPHI, UNSPEC_RCPF): Likewise.
+ (UNSPEC_RND, UNSPEC_RPTB_FILL, UNSPEC_LOADHF_INT): Likewise.
+ (UNSPEC_STOREHF_INT, UNSPEC_RSQRF, UNSPEC_LOADQF_INT): Likewise.
+ (UNSPEC_STOREQF_INT, UNSPEC_LDIV, UNSPEC_PUSH_ST): Likewise.
+ (UNSPEC_POP_ST, UNSPEC_PUSH_DP, UNSPEC_POP_DP): Likewise.
+ (UNSPEC_POPQI, UNSPEC_POPQF, UNSPEC_ANDN_ST): Likewise.
+ (UNSPEC_RPTB_INIT, UNSPEC_TOIEEE, UNSPEC_FRIEEE): Likewise.
+
+2003-01-24 Jan Hubicka <jh@suse.cz>
+
+ * emit-rtl.c (reg_attrs_htab): New static variable.
+ (reg_attrs_htab_hash, reg_attrs_htab_eq, get_reg_attrs): New static
+ functions.
+ (reg_rtx): Do not maintain regno_decl.
+ (gen_rtx_REG_offset, set_reg_attrs_from_mem, set_delc_rtx,
+ set_mem_attrs_from_reg): New global function.
+ (init_emit): Do not initialize regno_decl.
+ (init_emit_once): initialize reg_attrs_htab.
+ * final.c (alter_subreg): Do not replace REG by SUBREG.
+ (gen_mem_expr_from_op): Improve output.
+ (output_asm_operands): Likewise.
+ * function.c (assign_params): Do not set REGNO_DECL.
+ * function.h (struct function): Kill regno_decl.
+ (REGNO_DECL): Kill.
+ * gengtype.c (adjust_field_rtx_def): Handle new field of reg.
+ * print_rtl.c (print_rtx): Output REG information.
+ * regclass.c (reg_scan_mark_refs): Update attrs.
+ * reload1.c (alter_reg): Likewise.
+ * simplify_rtx.c (simplify_subreg): Likewise.
+ * stmt.c (expand_decl): Likewise.
+ * rtl.def (REG): Add new field.
+ * rtl.h (struct reg_attrs): New.
+ (rtunion_def): At rtreg.
+ (X0MEMATTR): Add checking.
+ (X0REGATTR, REG_ATTRS, REG_EXPR, REG_OFFSET): New macro.
+ (set_reg_attrs_from_mem, set_mem_attrs_from_reg, gen_rtx_REG_offset):
+ Declare.
+ * tree.h (SET_DECL_RTL): Call set_decl_rtl.
+
+2003-01-24 Bob Wilson <bob.wilson@acm.org>
+
+ * config/xtensa/xtensa.c: Remove unused include of machmode.h.
+ (xtensa_emit_call, print_operand): Fix printf format strings
+ to avoid compile warnings.
+ (xtensa_function_prologue, xtensa_function_epilogue): Change type
+ of "size" argument to HOST_WIDE_INT to fix compile warnings.
+ * config/xtensa/xtensa-protos.h
+ (xtensa_function_prologue, xtensa_function_epilogue): Ditto.
+
+2003-01-24 Jan Hubicka <jh@suse.cz>
+
+ * builtins.c (DEF_BUILTIN): Accept 10 arguments.
+ (implicit_built_in_decls): New global array.
+ (mathfn_built_in): New global function.
+ (fold_trunc_transparent_mathfn): New static function
+ (expand_builtin_strstr, expand_bultin_strchr,
+ expand_builtin_strpbrk, expand_builtin_strcpy,
+ expand_builtin_strncpy, expand_bultin_strcmp,
+ expand_bultin_strncat, expand_builtin_fputs): Use
+ implicint_built_in_decls.
+ (fold_builtin): Fold floor/trunc/round/ceil/nearbyint.
+ * builtins.def: Fix comments.
+ (DEF_GCC_BUILTIN, DEF_FALLBACK_BUILTIN, DEF_EXT_FALLBACK_BUILTIN,
+ DEF_LIB_BUILTIN, DEF_LIB_ALWAYS_BUILTIN, DEF_EXT_LIB_BUILTIN,
+ DEF_C99_BULTIN, DEF_FRONT_END_LIB_BUILTIN,
+ DEF_EXT_FRONT_END_LIB_BUILTIN): Pass implicit as needed.
+ (DEF_C99_C90RES_BULTIN): New.
+ (*f, *l builtins): Update.
+ * c-common.c (DEF_BUILTIN): Initialize implicit array.
+ (c_expand_builtin_printf, c_expand_builtin_fprintf): Update.
+ * convert.c (strip_float_extensions): New global function.
+ * tree.h (DEF_BUILTIN): Accept 10 arguments.
+ (implicit_built_in_decls, mathfn_built_in, strip_float_extension):
+ Declare.
+ * java/builtins.c (define_builtin): Handle implicit.
+ (DEF_BUILTIN): Update.
+ * tm.texi (TARGET_C99_FUNCTIONS): Document.
+ * defaults.h (TARGET_C99_FUNCTIONS): Default to 0.
+ * config/linux.h (TARGET_C99_FUNCTIONS): Default to 1
+ when using glibc2.
+
+2003-01-24 Bob Wilson <bob.wilson@acm.org>
+
+ * config.gcc (xtensa-*-elf*): Removed assignments to with_newlib,
+ extra_parts, and fixincludes. Add xtensa/t-elf tmake_file.
+ (xtensa-*-linux*): Add xtensa/t-linux tmake_file.
+ * config/xtensa/crti.asm: New file.
+ * config/xtensa/crtn.asm: New file.
+ * config/xtensa/t-elf: New file.
+ * config/xtensa/t-linux: New file.
+ * config/xtensa/t-xtensa: Add rules for crti.o and crtn.o.
+ Move various CFLAGS settings to new t-elf file.
+
+2003-01-24 Richard Henderson <rth@redhat.com>
+
+ PR optimization/4382
+ * tree-inline.c (find_builtin_longjmp_call_1): New.
+ (find_builtin_longjmp_call): New.
+ (inlinable_function_p): Use it.
+
+2003-01-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * config/i386/i386-protos.h (function_arg_pass_by_reference): Declare.
+ * config/i386/i386.h (FUNCTION_ARG_PASS_BY_REFERENCE): Use it.
+ * config/i386/i386.c (function_arg_pass_by_reference): New.
+ (ix86_va_arg): Support arguments passed by reference.
+
+2003-01-24 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloopanal.c: New file.
+ * cfgloopmanip.c: New file.
+ * Makefile.in (cfgloopanal.o, cfgloopmanip.o): New.
+ (toplev.o, loop.o, doloop.o, unroll.o, cfgloop.o, predict.o,
+ cfglayout.o): Add dependency on cfgloop.h.
+ (cfgloop.o): Add flags.h dependency.
+ * basic-block.h (BB_IRREDUCIBLE_LOOP, BB_SUPERBLOCK): New flags.
+ (VLS_EXPECT_PREHEADERS, VLS_EXPECT_SIMPLE_LATCHES): Removed.
+ (struct loop, struct loops, flow_loops_find, flow_loops_update,
+ flow_loops_free, flow_loops_dump, flow_loop_dump,
+ flow_loop_scan, flow_loop_tree_node_add, flow_loop_tree_node_remove,
+ LOOP_TREE,,LOOP_PRE_HEADER, LOOP_ENTRY_EDGES, LOOP_EXIT_EDGES,
+ LOOP_ALL, flow_loop_outside_edge_p, flow_loop_nested_p,
+ flow_bb_inside_loop_p, get_loop_body, loop_preheader_edge,
+ loop_latch_edge, add_bb_to_loop, remove_bb_from_loops,
+ find_common_loop, verify_loop_structure): Declarations moved to ...
+ * cfgloop.h: New file.
+ * bb-reorder.c (reorder_basic_blocks): Modified.
+ * cfglayout.c: Include cfgloop.h.
+ (cleanup_unconditional_jumps, cfg_layout_redirect_edge,
+ cfg_layout_duplicate_bb, cfg_layout_initialize): Update loop structure.
+ (break_superblocks): New static function.
+ (cfg_layout_finalize): Use it.
+ (cfg_layout_split_block): New function.
+ * cfglayout.h (struct reorder_block_def): Add copy and duplicated
+ fields.
+ (cfg_layout_initialize, cfg_layout_redirect_edge): Declaration
+ changed.
+ (cfg_layout_split_block): Declare.
+ * cfgloop.c: Include cfgloop.h and flags.h.
+ (flow_loop_dump, flow_loops_free, flow_loop_exit_edges_find,
+ get_loop_body): Avoid signed versus unsigned comparison warnings.
+ (make_forwarder_block, flow_loops_find, loop_preheader_edge,
+ loop_latch_edge): Modified.
+ (verify_loop_structure): Modified to use flags stored in loop structure;
+ check irreducible loops.
+ (cancel_loop, cancel_loop_tree): New functions.
+ (estimate_probability): Use loop analysis code for predictions.
+ (estimate_loops_at_level): Avoid signed versus unsigned comparison
+ warnings.
+ * doloop.c: Include cfgloop.h.
+ * loop.c: Include cfgloop.h.
+ * predict.c: Include cfgloop.h.
+ * toplev.c: Include cfgloop.h.
+ * unroll.c: Include cfgloop.h.
+ * tracer.c (tracer): Modified.
+
+2003-01-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (get_shift_alg): Fix a typo.
+
+2003-01-24 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * configure.in (HAVE_AS_TLS): Add s390-*-* and s390x-*-* cases.
+ * configure: Regenerate.
+
+ * config/s390/s390-protos.h (tls_symbolic_operand): Add prototype.
+ (tls_symbolic_reference_mentioned_p): Add prototype.
+ (s390_tls_get_offset): Add prototype.
+ (emit_pic_move): Remove prototype, replace by ...
+ (emit_symbolic_move): .. this new prototype.
+
+ * config/s390/s390.c (TARGET_HAVE_TLS): Conditionally define.
+ (tls_model_chars): New global variable.
+ (s390_encode_section_info): Encode TLS model.
+ Use targetm.binds_local_p to check for local symbols.
+ (s390_strip_name_encoding): New function.
+ (TARGET_STRIP_NAME_ENCODING): Define.
+
+ (get_thread_pointer): New function.
+ (legitimize_tls_address): New function.
+ (legitimize_address): Call it.
+ (emit_pic_move): Remove, replace by ...
+ (emit_symbolic_move): ... this new function.
+
+ (larl_operand): Handle TLS operands.
+ (legitimate_constant_p): Likewise.
+ (s390_decompose_address): Likewise.
+ (s390_cannot_force_const_mem): New function.
+ (TARGET_CANNOT_FORCE_CONST_MEM): Define.
+
+ (s390_output_symbolic_const): Handle TLS unspecs.
+ (print_operand): New code 'J'.
+ (machine_function): Add struct member 'some_ld_name'.
+ (get_some_local_dynamic_name, get_some_local_dynamic_name_1): New.
+
+ (enum s390_builtin): New type.
+ (code_for_builtin_64, code_for_builtin_31): New global variables.
+ (s390_init_builtins, s390_expand_builtin): New functions.
+ (TARGET_INIT_BUILTINS, TARGET_EXPAND_BUILTIN): Define.
+
+ * config/s390/s390.h (TLS_SYMBOLIC_CONST): New macro.
+ (ASM_OUTPUT_LABELREF): Define.
+ (ASM_OUTPUT_SPECIAL_POOL_ENTRY): Handle TLS constants.
+
+ * config/s390/s390.md: Define TLS UNSPEC constants.
+ ("movdi", "movsi"): Handle TLS operands.
+ ("get_tp_64", "get_tp_31", "set_tp_64", "set_tp_31"): New insns.
+ ("*tls_load_64", "*tls_load_31"): New insns.
+ ("call_value_tls", "call_value_tls_exp"): New expanders.
+ ("brasl_tls", "bras_tls", "basr_tls_64", "basr_tls_31",
+ "bas_tls_64", "bas_tls_31"): New insns.
+
+2003-01-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * config/rs6000/rs6000.c (rs6000_parse_abi_options): Make sure
+ spe ABI is configured, if requested.
+
+2003-01-24 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * doc/passes.texi: Fix typo.
+
+2003-01-24 Andreas Schwab <schwab@suse.de>
+
+ * stor-layout.c (excess_unit_span): Only define if used.
+
+2003-01-24 Jerry Quinn <jlquinn@optonline.net>
+
+ * gcc/doc/invoke.texi (Optimization Options): List -O levels
+ for each optimization flag.
+
+2003-01-24 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*andsi3_ashift_n_lower): New.
+
+2003-01-24 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * doc/bugreport.texi: Use @command instead of @code for commands.
+ * doc/collect2.texi: Likewise.
+ * doc/headerdirs.texi: Likewise.
+ * doc/invoke.texi: Likewise.
+ * doc/standards.texi: Likewise.
+ * doc/tm.texi: Likewise.
+ * doc/trouble.texi: Likewise.
+
+2003-01-24 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.c (use_return_insn): Do not use a single return
+ instruction for interrupt handelrs which have to create a stack
+ frame.
+ (arm_expand_prologue): Do not pre-bias the return address of
+ interrupt handlers which create a stack frame.
+
+2003-01-24 Nick Clifton <nickc@redhat.com>
+
+ * Add sh2e support:
+
+ 2002-08-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/sh/sh.c (output_branch) [TARGET_SH2E]: Handle
+ med_cbranches. Fix logic in short_cbranches.
+
+ 2002-04-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/sh/sh.md (delay for cbranch): Don't annul delay
+ slots on SH2e.
+ * config/sh/sh.c (sh_insn_length_adjustment): Add 2 for
+ cbranch with unfilled delay slot on SH2e.
+ (output_branch): Fill with a nop the delay slot of a
+ branch that required a delay slot but didn't get one.
+
+ 2002-04-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * doc/invoke.texi (SH options): Document -m2e.
+ * config/sh/crt1.asm: Add __SH2E__ Next to __SH3E__.
+ * config/sh/lib1funcs.asm: Likewise.
+ * config/sh/sh.c: Replace all uses of TARGET_SH3E with SH2E.
+ * config/sh/sh.h (CPP_SPEC): Define __SH2E__ for -m2e, and
+ not __sh1__.
+ (CONDITIONAL_REGISTER_USAGE): Don't disable FP regs from
+ SH2E up.
+ (SH3E_BIT): Renamed to...
+ (SH_E_BIT): ... this. Replace all uses.
+ (TARGET_SH2E): Define from SH_E_BIT and TARGET_SH2.
+ Replace all uses of TARGET_SH3E with TARGET_SH2E.
+ (TARGET_SWITCHES): Added 2e.
+ (OVERRIDE_OPTIONS): Set sh_cpu for SH2E.
+ (processor_type): Added PROCESSOR_SH2E.
+ * config/sh/sh.md: Replace all uses of TARGET_SH3E with
+ TARGET_SH2E, except in sqrtsf2_i.
+ (attribute cpu): Added sh2e.
+ * config/sh/t-sh (MULTILIB_OPTIONS): Replace m3e with m2e.
+ (MULTILIB_MATCHES): Use m2e multilib for m3e.
+ * config.gcc: Add sh2e target support.
+
+2003-01-24 Phil Edwards <pme@gcc.gnu.org>
+
+ Rename -W to -Wextra.
+ * c-decl.c: Update comments.
+ * c-typeck.c: Likewise.
+ * flags.h: Likewise.
+ * function.c: Likewise.
+ * stmt.c: Likewise.
+ * toplev.c: Update comments.
+ (W_options): Add 'extra'.
+ (display_help): Remove '-W'.
+ (decode_W_option): Special warn_uninitialized treatment in the case
+ of -Wextra.
+ * doc/invoke.texi: Update with new entries.
+
+2003-01-23 Richard Henderson <rth@redhat.com>
+
+ * ifcvt.c (noce_process_if_block): Re-add check vs X being changed
+ in no-else-block case. Add commentary.
+
+2003-01-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * configure.in: Revert last change.
+
+2003-01-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * configure.in: Don't include ansidecl.h in tconfig.h.
+ * gcov-io.h (PARAMS, ATTRIBUTE_UNUSED): Define if IN_LIBGCC2.
+ * unwind-dw2-fde.h (last_fde): Use __attribute__, not
+ ATTRIBUTE_UNUSED.
+
+ * configure: Regenerate.
+
+2003-01-23 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR java/6748
+ * config/rs6000/linux.h (MD_FALLBACK_FRAME_STATE_FOR): Don't destroy
+ regs->nip. Fix rt_sigreturn frame layout. Add support for newer
+ kernels.
+
+2003-01-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cpplex.c (cpp_interpret_charconst): Squelch warning with cast.
+
+2003-01-23 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * genattrtab.c (write_attr_get): Mark 'insn' paramter
+ as ATTRIBUTE_UNUSED.
+
+2003-01-23 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (thumb_base_register_rtx_p): New function.
+ (thumb_index_register_rtx_p): New function.
+ (thumb_legitimate_address_p): New function.
+ (thumb_legitimate_offset_p): New function.
+ * arm.h (REG_STRICT_P): Define according to setting of REG_OK_STRICT.
+ (ARM_GO_IF_LEGITIMATE_ADDRESS): Use REG_STRICT_P to avoid duplicate
+ definitions.
+ (THUMB_GO_IF_LEGITIMATE_ADDRESS): Use thumb_legitimate_address_p.
+ (THUMB_LEGITIMATE_OFFSET): Delte.
+ (THUMB_LEGITIMIZE_RELOAD_ADDRESS): Use thumb_legitimate_offset.
+ * arm-protos.h (thumb_legitimate_address_p): Add prototype.
+ (thumb_legitimate_offset_p): Likewise.
+
+2003-01-23 Andreas Schwab <schwab@suse.de>
+
+ * unwind.h (_Unwind_GetTextRelBase): Mark parameter as unused.
+
+2003-01-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fixinc/Makefile.in (FL_LIST): Revert last change.
+
+2003-01-23 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR other/7341
+ * invoke.texi (ftest-coverage): Fix broken cross-reference.
+ Change @code to @command for gcov command.
+
+ * gcc.texi: Adjust title of gcov section.
+ Adjust copyright.
+ * gcov.texi: Likewise.
+
+2003-01-22 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/8423
+ * cse.c (fold_rtx): Only eliminate a CONSTANT_P_RTX to 1 when
+ its argument is constant, or 0 if !flag_gcse.
+ * simplify-rtx.c (simplify_rtx): Convert CONSTANT_P_RTX to 1
+ if it's argument is constant.
+ * gcse.c (want_to_gcse_p): Ignore CONSTANT_P_RTX nodes.
+ (hash_scan_set): Don't record CONSTANT_P_RTX expressions.
+ (do_local_cprop): Don't propagate CONSTANT_P_RTX constants.
+ * builtins.c (purge_builtin_constant_p): New function to force
+ instantiation of any remaining CONSTANT_P_RTX nodes.
+ * rtl.h (purge_builtin_constant_p): Prototype here.
+ * toplev.c (rest_of_compilation): Invoke purge_builtin_constant_p
+ pass after GCSE and before loop.
+ (flag_gcse): No longer static.
+ * flags.h (flag_gcse): Prototype here.
+
+2003-01-22 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.h (HARD_REGNO_MODE_OK): Fix warning regression
+ introduced by last change.
+
+2003-01-22 Andreas Schwab <schwab@suse.de>
+
+ * ra-rewrite.c (rewrite_program2): Initialize bb to avoid warning.
+
+2003-01-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_shift_needs_scratch_p): Don't
+ request a scratch reg on H8S when the shift count is 8.
+
+2003-01-22 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390-protos.h (preferred_la_operand_p):
+ Remove second parameter.
+ * config/s390/s390.c (preferred_la_operand_p): Likewise.
+ * config/s390/s390.h (FRAME_REGNO_P, FRAME_REG_P): New macros.
+ (HARD_REGNO_MODE_OK): Use FRAME_REGNO_P.
+ * config/s390/s390.md ("*la_cc_64", "*la_cc_31", splitters): Remove.
+ Add peepholes to transform ADD to LOAD ADDRESS.
+
+2003-01-22 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_address_register_rtx_p): New function.
+ (arm_legitimate_address_p): New function.
+ (arm_legitimate_index_p): New function.
+ (legitimize_pic_address): Use arm_legitimate_index_p.
+ * arm-protos.h (arm_legtimate_address_p): Add prototype.
+ * arm.h (ARM_GO_IF_LEGITIMATE_INDEX): Delete.
+ (ARM_GO_IF_LEGITIMATE_ADDRESS): Call arm_legitimate_address_p.
+
+2003-01-22 Hartmut Penner <hpenner@de.ibm.com>
+
+ * config/s390/s390.md (floatdfdi2): Insn has type 'itof'.
+ * config/s390/2064.md (define_bypass): Correct 'Load' and
+ 'Load-address' bypass values.
+
+2003-01-22 Andreas Schwab <schwab@suse.de>
+
+ * config/ia64/t-ia64 (insn-attrtab.o-warn): Define as -Wno-error.
+
+2003-01-21 Zack Weinberg <zack@codesourcery.com>
+
+ * genautomata.c (output_internal_insn_latency_func,
+ output_print_reservation_func): Short circuit when there is no
+ automaton to generate code for.
+
+2003-01-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (ssa-ccp.o): Depend on coretypes.h $(TM_H).
+ (df.o): Delete duplicate dependency on coretypes.h $(TM_H).
+
+2003-01-21 Geoffrey Keating <geoffk@apple.com>
+
+ * config/rs6000/rs6000.md: Remove warning.
+ (builtin_setjmp_receiver): Likewise.
+ * config/darwin.c (update_stubs): Slightly improve terrible hack
+ with identifiers. Add comment pointing out problems with it.
+ (update_non_lazy_ptrs): Likewise.
+
+2003-01-21 Richard Henderson <rth@redhat.com>
+
+ * dwarf2out.c (lookup_filename): Fix printf format warning.
+ * system.h (fread_unlocked, fwrite_unlocked): Undef.
+
+ * fixinc/Makefile.in (FL_LIST): Add $($@-warn) hook.
+ (fixincl.o-warn, gnu-regex.o-warn): New.
+ * fixinc/fixfixes.c (FIX_PROC_HEAD): Mark parameters unused.
+ * fixinc/fixtests.c (TEST_FOR_FIX_PROC_HEAD): Likewise.
+ * fixinc/fixincl.c (process): Fix printf format warning.
+
+2003-01-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * dwarf2out (output_file_names): Don't crash if called
+ with empty file_table.
+
+2003-01-21 Zack Weinberg <zack@codesourcery.com>
+
+ * genautomata.c (output_internal_insn_latency_func): Add
+ missing break statement to generated code.
+
+2003-01-21 Roger Sayle <roger@eyesopen.com>
+
+ * stmt.c (same_case_target_p): New function to determine whether
+ two case labels branch to the same target. Split out from...
+ (group_case_nodes): ... here. Use same_case_target_p instead.
+ (strip_default_case_nodes): Remove explicit case nodes
+ that branch to the default destination.
+ (expand_end_case_type): Call strip_default_case_nodes after
+ group_case_nodes, to simplify the case-list before we count it.
+ Only generate table_label RTX when actually needed. Try to share
+ thiscase->exit_label and thiscase->data.case_stmt.default_label
+ when a switch has no explicit default case. Simplify test for
+ constant index.
+
+2003-01-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*negsf2_h8300): Use \\t instead of
+ \t.
+ (*negsf2_h8300hs): Likewise.
+ (*addsi3_lshiftrt_16_zexthi): Likewise.
+ (*iorhi3_lshiftrt_8): Likewise.
+
+2003-01-21 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * dwarf2out.c (fde_table_in_use): Mark GTY.
+ (dwarf2out_cfi_label_num): New variable, marked GTY.
+ (dwarf2out_cfi_label): Use it instead of static label_num.
+ * emit-rtl.c (label_num): Mark GTY.
+
+2003-01-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (output_plussi): Support H8/300.
+ (compute_plussi_length): Likewise.
+ (compute_plussi_cc): Likewise.
+ * config/h8300/h8300.md (addsi_h8300): Use output_plussi to
+ output assembly instructions.
+
+2003-01-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * calls.c (fix_unsafe_tree): Prototype.
+
+ * Makefile.in (GCC_WARN_CFLAGS): Add $(WERROR) $($@-warn)
+ (gtype-desc.o-warn, c-decl.o-warn, varasm.o-warn, gcc.o-warn,
+ insn-conditions.o-warn, out_object_file, gengtype-yacc.o-warn,
+ c-parse.o-warn): Add -Wno-error.
+ (STAGE2_FLAGS_TO_PASS): Add WERROR="@WERROR@".
+
+ * configure.in (--enable-werror): Add new flag.
+ * doc/install.texi (--enable-werror): Document.
+ * configure: Regenerate.
+
+ * objc/Make-lang.in (objc/objc-parse.o-warn): Add -Wno-error.
+
+2003-01-21 Andreas Schwab <schwab@suse.de>
+
+ * genautomata.c (output_internal_insn_latency_func): Fix missing
+ close paren in output.
+
+2003-01-21 Zack Weinberg <zack@codesourcery.com>
+
+ * genautomata.c: Space savings in generated code:
+ (output_dfa_insn_code_func): Split out the table-enlargement
+ path to an out-of-line static function, dfa_insn_code_enlarge.
+ (output_internal_insn_latency_func): Use a lookup table for the
+ default latencies.
+ (output_print_reservation_func): Use a lookup table for the
+ strings.
+
+2003-01-21 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
+
+ PR opt/7507
+ * calls.c (fix_unsafe_tree): Split out from ...
+ (expand_call): ... here. Use it on the function address too.
+
+2003-01-20 Richard Henderson <rth@redhat.com>
+
+ * expr.h (default_must_pass_in_stack): Move decl outside ifdef.
+
+2003-01-20 Richard Henderson <rth@redhat.com>
+
+ PR opt/7154
+ * stmt.c (expand_asm_operands): Validize memory operands.
+
+2003-01-20 Richard Henderson <rth@redhat.com>
+
+ PR opt/8848
+ * ifcvt.c (noce_process_if_block): Correct arguments to
+ modified_between_p for no-else-block case.
+
+2003-01-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (const_costs): Remove a warning.
+ (output_plussi): Likewise.
+ (compute_plussi_length): Likewise.
+ (compute_plussi_cc): Likewise.
+
+2003-01-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (addsi_h8300): Remove the last
+ alternative.
+
+2003-01-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (get_shift_alg): Remove redundant code.
+
+2003-01-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * system.h (__NO_STRING_INLINES): Define.
+
+2003-01-20 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * ifcvt.c (noce_emit_store_flag): Don't emit store flag if mode of x
+ is not a scalar int mode.
+
+2003-01-20 Roger Sayle <roger@eyesopen.com>
+
+ * cse.c (cse_insn): Avoid RTL sharing when updating the RETVAL
+ insn's notes following a substitution inside a libcall.
+
+2003-01-20 Zack Weinberg <zack@codesourcery.com>
+
+ * configure.in: Check for system-provided 'uchar' type.
+ * configure, config.in: Regenerate.
+ * cpphash.h: Only typedef 'uchar' if the system doesn't.
+
+2003-01-20 Richard Henderson <rth@redhat.com>
+
+ * expr.h (MUST_PASS_IN_STACK): Move implementation...
+ * calls.c (default_must_pass_in_stack): ... here.
+
+2003-01-20 Vladimir Makarov <vmakarov@redhat.com>
+
+ * genattrtab.h (INSN_ALTS_FUNC_NAME): Move it from genautomata.c.
+
+ * genautomata.c (INSN_ALTS_FUNC_NAME): Move it into genattrtab.h.
+
+ * genattr.c (main): Output default definition of AUTOMATON_ALTS.
+ Wrap up definition of `insn_alts'.
+
+ * genattrtab.c (main): Wrap up `insn_alts'.
+
+2003-01-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * collect2.c (ldgetname): Check HAVE_DECL_LDGETNAME before
+ prototyping.
+ * configure.in: Check for <ldfcn.h> and ldgetname() prototype.
+
+ * config.in, configure: Regenerate.
+
+2003-01-20 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/arm.md (sibcall_epilogue): Add an
+ UNSPEC_PROLOGUE_USE to prevent the link register from being
+ considered dead.
+
+2003-01-20 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (SSE cmov splitter): Handle memory operand in operand 5.
+
+2003-01-20 Andreas Schwab <schwab@suse.de>
+
+ * system.h: Don't declare strsignal if the decl test hasn't been
+ run yet.
+
+2003-01-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (notice_update_cc): Don't assume that
+ recog_data.operands[0] is always associated with cc0.
+
+2003-01-19 David Edelsohn <edelsohn@gnu.org>
+
+ * collect2.c (ldgetname): Expand declaration to prototype.
+ * read-rtl.c (atoll): Add prototype.
+ * system.h (strsignal): Also declare if no declaration found.
+
+2003-01-19 Alexandre Oliva <aoliva@redhat.com>
+
+ * config.gcc (mips64*-*-linux*): Added.
+ * config/mips/linux64.h, config/mips/t-linux64: New file.
+ * config/mips/iris6.h (MIPS_TFMODE_FORMAT): Define.
+ * config/mips/mips.c (override_options): Use it.
+ * config/mips/mips.h (TARGET_SWITCHES): Added...
+ (SUBTARGET_TARGET_SWITCHES): New, empty by default.
+ * Makefile.in (SPECS): New.
+ (STAGESTUFF, specs, mostlyclean, install-common): Use it.
+ * gcc.c (process_command): Move self-spec processing past spec
+ file loading.
+ * doc/tm.texi (DRIVER_SELF_SPECS): Document the change.
+ * doc/fragments.texi (MULTILIB_EXTRA_OPTS): Document need for
+ CRTSTUFF_T_CFLAGS.
+ (SPECS): Document.
+ * doc/invoke.texi (-mabi-fake-default): Document.
+
+2003-01-19 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (stack_push_word, stack_pop_word,
+ z_reg, z_reg_qi): Declare static and GTY().
+ (da_reg): Remove.
+ (create_regs_rtx): Don't create da_reg.
+ ("gt-m68hc11.h"): Include for GTY roots.
+ * config/m68hc11/m68hc11.h (ix_reg, iy_reg, d_reg): Declare extern
+ and GTY() here.
+ (m68hc11_compare_op0, m68hc11_compare_op1): Likewise.
+ (m68hc11_soft_tmp_reg): Likewise.
+ * config/m68hc11/m68hc11-protos.h: Remove above declarations.
+
+2003-01-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * basic-block.h: Fix comment formatting.
+ * calls.c: Likewise.
+ * combine.c: Likewise.
+ * convert.c: Likewise.
+ * gcov.c: Likewise.
+ * haifa-sched.c: Likewise.
+ * libgcc2.c: Likewise.
+ * loop.c: Likewise.
+ * profile.c: Likewise.
+ * system.h: Likewise.
+
+2003-01-18 Roger Sayle <roger@eyesopen.com>
+
+ * config/pa/pa.md (muldi3): Avoid invalid sharing of SUBREG RTXs.
+
+2003-01-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ra-build.c (undef_to_size_word): Avoid `switch' warning.
+
+2003-01-17 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.md (*floatsidf2_internal): Add earlyclobbers.
+ (*floatunssidf2_internal): Ditto.
+
+2003-01-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * alias.c: Fix comment typos.
+ * basic-block.h: Likewise.
+ * c-common.c: Likewise.
+ * c-common.h: Likewise.
+ * c-decl.c: Likewise.
+ * c-opts.c: Likewise.
+ * c-pragma.c: Likewise.
+ * c-pretty-print.h: Likewise.
+ * cfg.c: Likewise.
+ * cfganal.c: Likewise.
+ * cfgbuild.c: Likewise.
+ * cfgcleanup.c: Likewise.
+ * cfglayout.c: Likewise.
+ * cfgrtl.c: Likewise.
+ * convert.c: Likewise.
+ * cpphash.h: Likewise.
+ * cpplex.c: Likewise.
+ * cpplib.h: Likewise.
+ * df.h: Likewise.
+ * diagnostic.c: Likewise.
+ * diagnostic.h: Likewise.
+ * dwarf2.h: Likewise.
+
+2003-01-17 Stan Shebs <shebs@apple.com>
+
+ * config/darwin-protos.h: Forward-declare struct cpp_reader.
+
+2003-01-17 Douglas B Rupp <rupp@gnat.com>
+
+ * config/alpha/alpha.c (alpha_need_linkage): Fix obvious
+ mistake in last checkin.
+
+2003-01-17 Kazu Hirata <kazu@cs.umass.edu>
+
+ * et-forest.c: Fix comment typos.
+ * et-forest.h: Likewise.
+ * except.c: Likewise.
+ * expr.c: Likewise.
+ * flags.h: Likewise.
+ * flow.c: Likewise.
+ * gcc.c: Likewise.
+ * gcse.c: Likewise.
+ * genattrtab.c: Likewise.
+ * genautomata.c: Likewise.
+ * gengtype.c: Likewise.
+ * genrecog.c: Likewise.
+ * global.c: Likewise.
+ * gthr-rtems.h: Likewise.
+
+2003-01-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * i386.c (x86_function_profiler): Fix format specifier.
+
+2003-01-17 Richard Henderson <rth@redhat.com>
+
+ * gengtype.c (walk_type): Allow paramN_is.
+
+2003-01-17 Nick Clifton <nickc@redhat.com>
+
+ * config/i960/t-960bare (i960-c.o): Add missing newline escape.
+
+2003-01-16 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/linux-elf.h (LIB_SPEC): Adjust inter-option spacing.
+
+2003-01-16 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_sr_alias_set): Mark GTY.
+ (alpha_next_sequence_number): Likewise.
+ (alpha_this_literal_sequence_number): Likewise.
+ (alpha_this_gpdisp_sequence_number): Likewise.
+ (struct alpha_funcs, alpha_funcs_num): Likewise.
+ (struct alpha_links): Fix branch merge error.
+ (alpha_need_linkage, alpha_use_linkage): Use GC for alpha_funcs.
+
+2003-01-17 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/mips/mips.h: Don't use #elif. Reported by Kaveh
+ R. Ghazi.
+
+2003-01-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ifcvt.c: Fix comment typos.
+ * lcm.c: Likewise.
+ * libgcc2.c: Likewise.
+ * local-alloc.c: Likewise.
+ * loop.c: Likewise.
+ * predict.c: Likewise.
+ * ra-build.c: Likewise.
+ * ra.c: Likewise.
+ * ra-colorize.c: Likewise.
+ * ra.h: Likewise.
+ * ra-rewrite.c: Likewise.
+ * regmove.c: Likewise.
+ * reload.h: Likewise.
+ * rtlanal.c: Likewise.
+ * toplev.c: Likewise.
+ * tree.h: Likewise.
+ * unwind-dw2-fde-glibc.c: Likewise.
+ * vmsdbgout.c: Likewise.
+
+2003-01-16 Richard Henderson <rth@redhat.com>
+
+ * dwarf2out.c (struct file_table): Remove.
+ (FILE_TABLE_INCREMENT): Remove.
+ (file_table): Make a varray; mark for GC. Update all users.
+ (file_table_last_lookup_index): Extract from struct file_table.
+ (output_file_names): Fix unsigned compare warnings.
+ (add_name_attribute): Remove inline marker.
+ (add_comp_dir_attribute): Split out from gen_compile_unit_die.
+ (lookup_filename): Don't manage size of file_table.
+ (init_file_table): Allocate file_table with GC.
+ (dwarf2out_init): Don't record main_input_filename here.
+ (dwarf2out_finish): Do it here instead.
+
+2003-01-16 Bruce Korb <bkorb@gnu.org>
+
+ * gcc/fixinc/inclhack.def(limits_ifndef): QNX needs a bypass, too.
+
+2003-01-16 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (sh_initialize_trampoline): Emit rotrdi3_mextr
+ instead of rotldi3_mextr.
+
+2003-01-16 Vladimir Makarov <vmakarov@redhat.com>
+
+ * haifa-sched.c (move_insn): Restore moving all schedule group.
+ (set_priorities): Restore taking SCHED_GROUP_P into account.
+
+ * sched-deps.c (add_dependence): Restore processing the last group
+ insn.
+ (remove_dependence, group_leader): Restore the functions.
+ (set_sched_group_p): Restore adding dependencies from previous insn
+ in the group.
+ (compute_forward_dependences): Restore usage of group_leader.
+
+ * sched-ebb.c (init_ready_list): Restore taking SCHED_GROUP_P into
+ account.
+
+ * sched-rgn.c (init_ready_list): Restore taking SCHED_GROUP_P into
+ account.
+ (can_schedule_ready_p): Ditto.
+ (add_branch_dependences): Restore skipping over the group insns.
+
+2003-01-16 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (m68hc11_check_z_replacement): Fix handling
+ 68HC12 pre/post inc/dec side effects.
+
+2003-01-16 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.h (MASK_M6812): Define.
+
+2003-01-16 J"orn Rennecke <amylaar@onetel.net.uk>
+
+ * sh.md (mshflo_w_x): Fix description of operation.
+
+2003-01-16 Zack Weinberg <zack@codesourcery.com>
+
+ * config/rs6000/rs6000.h: Mention Altivec registers in
+ commentary. Fix typo.
+
+2003-01-16 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (movti_string): Remove clobber.
+ * config/rs6000/rs6000.c (rs6000_emit_move, TImode): Explicitly
+ generate PARALLEL with clobber for TARGET_POWER.
+
+2003-01-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ra-colorize.c (colorize_one_web): Initialize variable.
+ * regmove.c (fixup_match_1): Likewise.
+ * reload1.c (reload_as_needed): Likewise.
+ * sdbout.c (SET_KNOWN_TYPE_TAG): Add cast.
+
+2003-01-16 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * cfgloop.c (flow_loops_find): Fix handling of abnormal edges.
+
+2003-01-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * dbxout.c (lastfile, cwd): Fix `unused' warning.
+ * dwarf2out.c (fde_table_in_use, current_funcdef_fde,
+ dw_cfi_oprnd1_desc, dw_cfi_oprnd2_desc, next_die_offset,
+ is_main_source, file_table, decl_die_table_in_use,
+ abbrev_die_table_in_use, line_info_table_in_use,
+ separate_line_info_table_in_use, pubname_table_in_use,
+ arange_table_in_use, ranges_table_in_use,
+ current_function_has_inlines): Likewise.
+ * flow.c (life_analysis): Likewise.
+ * genemit.c (gen_insn): Likewise.
+ * protoize.c (cplus_suffix): Likewise.
+
+ * arm.c (ROUND_UP_WORD): Renamed from ROUND_UP.
+ * arm.h (ROUND_UP_WORD): Likewise.
+
+ * arm.h (CONDITIONAL_REGISTER_USAGE): Avoid signed/unsigned
+ warning.
+ * emit-rtl.c (gen_rtx_REG, set_mem_attributes_minus_bitpos,
+ init_emit_once): Likewise.
+ * flow.c (mark_regs_live_at_end, calculate_global_regs_live):
+ Likewise.
+ * function.c (assign_stack_temp_for_type): Likewise.
+ * loop.c (loop_invariant_p): Likewise.
+ * recog.c (push_operand): Likewise.
+ * regclass.c (init_reg_sets_1): Likewise.
+ * reload.c (update_auto_inc_notes): Likewise.
+ * reload1.c (reload_as_needed, emit_input_reload_insns): Likewise.
+ * stmt.c (expand_asm_operands): Likewise.
+ * stor-layout.c (start_record_layout): Likewise.
+
+2003-01-16 Herman A.J. ten Brugge <hermantenbrugge@home.nl>
+
+ * config/c4x/c4x.md (epilogue): Correct last patch.
+
+2003-01-15 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (find_lo_sum_using_gp): Rename from find_lo_sum;
+ also check that GP is being used.
+ (alpha_find_lo_sum_using_gp): New.
+ (alpha_does_function_need_gp): Use get_attr_usegp.
+ * config/alpha/alpha-protos.h: Update.
+ * config/alpha/alpha.md (attr usegp): New. Annotate patterns
+ as needed.
+
+2003-01-15 Roger Sayle <roger@eyesopen.com>
+
+ * gcse.c (one_cprop_pass): Change function arguments to take both
+ cprop_jumps and bypass_jumps flags instead of just alter_jumps.
+ (gcse_main): Update calls to one_cprop_pass, disabling bypassing.
+ (bypass_jumps): New function to perform separate jump bypassing pass.
+ * rtl.h (bypass_jumps): Add function prototype.
+ * timevar.def (TV_BYPASS): New timing variable.
+ * toplev.c (enum dump_file_index): Add new entry DFI_bypass.
+ (dump_file): New entry for the bypass RTL dump file.
+ (rest_of_compilation): Insert new jump bypassing optimization
+ pass after loop.
+ * doc/passes.texi: Document new pass.
+
+2003-01-15 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * som.h (SUPPORTS_WEAK, SUPPORTS_ONE_ONLY, MAKE_DECL_ONE_ONLY,
+ ASM_WEAKEN_LABEL, GTHREAD_USE_WEAK): Define.
+ * pa.h (TARGET_SOM_SDEF): Define.
+ * pa-hpux11.h (TARGET_SOM_SDEF): Define.
+
+2003-01-16 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.c (expand_prologue): Use push/pop to
+ allocate 4-bytes of locals on 68HC11.
+ (expand_epilogue): Likewise.
+ (m68hc11_memory_move_cost): Increase cost of HI/QI soft registers.
+
+2003-01-15 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.h (ASM_SPEC): Handle -m68hcs12; Pass -mshort
+ and -mshort-double to the assembler to specify the ABI.
+ (LINK_SPEC): Likewise.
+ (CPP_SPEC): Pass HCS12 specific define.
+ (MASK_M68S12): New define.
+ (TARGET_M68S12): Likewise.
+ (TARGET_SWITCHES): New options -m68hcs12 and -m68S12.
+ (TARGET_VERSION): Update.
+ * config/m68hc11/m68hc12.h (CPP_SPEC): Pass HCS12 specific define.
+ (LINK_SPEC): Update.
+ (ASM_SPEC): Update.
+ * config/m68hc11/m68hc11.c (m68hc11_asm_file_start): Update.
+ * doc/invoke.texi (M68hc1x Options): Document -m68hcs12.
+
+2003-01-15 Stephane Carrez <stcarrez@nerim.fr>
+
+ * config/m68hc11/m68hc11.md ("return"): Use emit_jump_insn to emit
+ the return code.
+
+2003-01-15 Josef Zlomek <zlomekj@suse.cz>
+
+ * cfganal.c (set_edge_can_fallthru_flag): Clear the EDGE_CAN_FALLTHRU
+ flag before setting it.
+
+2003-01-15 Roger Sayle <roger@eyesopen.com>
+
+ * c-semantics.c (genrtl_while_stmt): Improve initial RTL generation
+ when loop condition is known true, i.e. "while (1) { ... }".
+ (genrtl_for_stmt): Similarly for "for" statements.
+
+2003-01-15 Roger Sayle <roger@eyesopen.com>
+
+ * real.c (real_sqrt): Return a bool result indicating whether
+ a floating point exception or trap should be raised.
+ * real.h (real_sqrt): Update function prototype.
+ * builtins.c (fold_builtin): Only fold non-trapping square
+ roots unless we're ignoring errno and trapping math.
+
+2003-01-15 John David Anglin <dave.anglin@nrc.gc.ca>
+
+ * expr.h (emit_conditional_add): Add PARAMS to declaration.
+ * gengtype-lex.l (malloc, realloc): Move defines after include of
+ system.h. Remove duplicate include of system.h.
+
+2003-01-15 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/9009
+ * optabs.c (expand_unop): When manipulating the FP sign bit
+ using integer operations, account for targets with different
+ integer and FP word orders.
+ (expand_abs): Likewise.
+
+2003-01-15 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_gen_section_name): Do not include
+ file extension in section name.
+
+2003-01-15 Richard Earnshaw <rearnsha@arm.com>
+
+ * flow.c (find_auto_inc): Also try to generate a PRE_MODIFY with
+ constant offset.
+
+2003-01-15 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.h (HAVE_PRE_MODIFY_DISP, HAVE_PRE_MODIFY_REG): Define.
+ (HAVE_POST_MODIFY_DISP, HAVE_POST_MODIFY_REG): Define.
+ (ARM_GO_IF_LEGITIMATE_ADDRESS): Handle pre/post-modify addresses.
+ (ARM_PRINT_OPERAND_ADDRESS): Likewise.
+
+2003-01-15 Jan Hubicka <jh@suse.cz>
+
+ PR f/9258
+ * global.c (struct allocno): Add no_stack_reg.
+ (global_conflicts): Set no_stack_reg.
+ (find_reg): Use it.
+
+ * convert.c (convert_to_real): Fold - and abs only when profitable.
+ * fold-const.c (fold): Fold truncates in - and abs.
+
+2003-01-15 Josef Zlomek <zlomekj@suse.cz>
+
+ Segher Boessenkool <segher@koffie.nl>
+
+ * predict.c (real_inv_br_prob_base): New variable.
+ (propagate_freq): Use multiply by reciprocal instead of
+ division. Don't divide by 1.0 at all.
+ (estimate_bb_frequencies): Similar.
+
+2003-01-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure.in (libgcc_visibility): Force disabled on IRIX 6 too.
+ * configure: Rebuilt.
+
+2003-01-15 Hartmut Penner <hpenner@de.ibm.com>
+
+ * config/s390/s390.c (s390_safe_attr_type): New function.
+ (s390_use_dfa_pipeline_interface): New function, return true for z900.
+ (s390_issue_rate): New function.
+ (s390_agen_dep_p): New function.
+ (addr_generation_dependency_p): Use 's390_safe_attr_type'.
+ (s390_adjust_cost): Return 'cost' if new DFA is used.
+ (s390_adjust_priority): Delete function.
+ * config/s390/s390-protos.h: (s390_agen_dep_p): New prototype.
+ * config/s390/s390.md (atype attribute): Attribute 'atype' default
+ determined by 'op_type'.
+ (type attribute): Added more type attributes.
+ * config/s390/2064.md: New DFA description for z900 pipeline.
+
+2003-01-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/i386/i386.c (ix86_expand_vector_move): Validize constant
+ forced to memory. Fixes PR bootstrap/9036.
+
+ * config/mips/mips.h (CRT_CALL_STATIC_FUNCTION): Define so as
+ to set $gp before the call.
+
+2003-01-14 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_expand_mov): Use correct mode
+ for force_const_mem.
+
+2003-01-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * genattr.c (main): Rearrange output to avoid prototype warning.
+ * genautomata.c (transform_3): Fix ambiguous-else warning.
+ * local-alloc.c (requires_inout): Add parentheses around
+ assignment used as truth-value.
+ * timevar.c: Move system includes above local includes. Include
+ toplev.h
+ * Makefile.in (timevar.o): Depend on toplev.h.
+
+2003-01-14 Denis Chertykov <denisc@overta.ru>
+
+ * config/ip2k/ip2k.h (VALID_MACHINE_DECL_ATTRIBUTE): Remove.
+ (VALID_MACHINE_TYPE_ATTRIBUTE): Remove.
+
+ * config/ip2k/ip2k.c (ip2k_attribute_table): New table of
+ attributes.
+ (TARGET_ATTRIBUTE_TABLE): New macro.
+ (valid_machine_type_attribute): Remove.
+ (valid_machine_decl_attribute): Remove.
+ (ip2k_handle_progmem_attribute): New function.
+ (ip2k_handle_fndecl_attribute): New function.
+
+2003-01-10 Andrew Haley <aph@redhat.com>
+
+ * config/i386/linux64.h (MD_FALLBACK_FRAME_STATE_FOR): Rename
+ registers to be in correct order. Add rip.
+
+2003-01-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*andsi3_lshiftrt_9_sb): New.
+ (*iorsi3_and_lshiftrt_9_sb): Likewise.
+
+2003-01-14 Jan Hubicka <jh@suse.cz>
+
+ * convert.c (strip_float_extensions): Look for narrowest type handling
+ FP constants.
+
+ * fold-const.c (fold): Fold (double)float1 CMP (double)float2 into
+ float1 CMP float2.
+ * convert.c (strip_float_extensions): Make global.
+ * tree.h (strip_float_extensions): Declare.
+
+2003-01-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * timevar.def: define TV_NAME_LOOKUP.
+ * timevar.c (timevar_pop): Be verbose when aborting.
+
+2003-01-13 Andreas Schwab <schwab@suse.de>
+
+ * Makefile.in ($(parsedir)/gengtype-lex.c): Don't change to
+ $(parsedir), just move the temporary file at the end.
+ ($(parsedir)/gengtype-yacc.c): Likewise.
+
+2003-01-13 Alexandre Oliva <aoliva@redhat.com>
+
+ * aclocal.m4 (gcc_AC_PROG_GNAT): Don't try to prepend
+ ${ac_tool_prefix} to ADAC or CC. Protect them from word
+ splitting.
+ * configure: Rebuilt.
+
+2003-01-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/sparc/gmon-sol2.c (moncontrol, monstartup, _mcleanup,
+ internal_mcount): Don't use PARAMS.
+ (monstartup, _mcleanup, internal_mcount, moncontrol): Convert to
+ ISO C style.
+ (internal_mcount): Use __attribute__, not ATTRIBUTE_UNUSED.
+
+2003-01-13 Andreas Schwab <schwab@suse.de>
+
+ * config/rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_LOCAL): Output type
+ directive.
+
+2003-01-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*andsi3_lshift_n_sb): New.
+ (*iorsi3_and_lshiftrt_n_sb): Likewise.
+
+2003-01-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9264
+ * c-lex.c (c_lex): Set the token value to error_mark_node for
+ invalid numeric constants.
+
+2003-01-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-pch.c (asm_file_startpos): Change to `long'.
+ (pch_init): Use ftell, not ftello.
+ (c_common_write_pch): Use ftell/fseek, not ftello/fseeko.
+ Use `long' instead of `off_t'.
+ (c_common_read_pch): Likewise.
+ * ggc-common.c (gt_pch_save): Use long/ftell instead of
+ off_t/ftello.
+
+2003-01-12 Alan Modra <amodra@bigpond.net.au>
+
+ * expr.c (expand_expr <RDIV_EXPR>): Correct recursive call args.
+
+2003-01-11 Richard Earnshaw (rearnsha@arm.com)
+
+ * arm-protos.h (struct cpp_reader): Add declaration.
+
+2003-01-11 Jan Hubicka <jh@suse.cz>
+
+ PR target/9068
+ * i386.c (output_fp_compare): Fix typo.
+
+2003-01-10 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (common_mode_defined): Mark for PCH.
+
+2003-01-10 Geoffrey Keating <geoffk@apple.com>
+
+ * Makefile.in (parsedir): New variable.
+ (docobjdir): New variable.
+ (c-parse.o, c-parse.c, c-parse.y, gengtype-lex.o, gengtype-yacc.o,
+ gengtype-lex.c, gengtype-yacc.c): Use parsedir.
+ (info, cpp.info, gcc.info, gccint.info, gccinstall.info,
+ cppinternals.info, generated-manpages, gcov.1, cpp.1, gcc.1, gfdl.7,
+ gpl.7, fsf-funding.7, maintainer-clean, install-info, install-man):
+ Use docobjdir.
+ * objc/Make-lang.in (objc/objc-parse.c, objc/objc-parse.y,
+ objc.maintainer-clean): Use parsedir.
+
+ * varasm.c (struct constant_descriptor_rtx): Remove unused
+ `label' field.
+
+ * toplev.c (documented_lang_options): Document -Winvalid-pch.
+
+2003-01-10 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.h (NO_PROFILE_COUNTERS): Set.
+ (ASM_OUTPUT_REG_PUSH, ASM_OUTPUT_REG_POP): Kill.
+
+2003-01-10 Richard Henderson <rth@redhat.com>
+
+ * combine.c (make_compound_operation): Use SCALAR_INT_MODE_P,
+ not INTEGRAL_MODE_P when widening extensions.
+
+2003-01-10 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (decl_has_samegp): True for !TREE_PUBLIC.
+
+2003-01-10 Geoffrey Keating <geoffk@apple.com>
+
+ * ggc-page.c (ggc_collect): Avoid overflow computing
+ min_expand.
+
+ * Makefile.in (RANLIB_FOR_TARGET): Use RANLIB when native.
+ (RANLIB_TEST_FOR_TARGET): Delete. Don't pass down to sub-makes.
+ Remove calls.
+ * mklibgcc.in: Remove uses of RANLIB_TEST_FOR_TARGET.
+
+2003-01-10 Jan Hubicka <jh@suse.cz>
+
+ * ifcvt.c (noce_try_addcc): Do not call emit_conditional_add
+ with weird operands.
+
+2003-01-10 Dale Johannesen <dalej@apple.com>
+
+ * calls.c (load_register_parameters): Add is_sibcall, sibcall_failure
+ parameters. Call check_sibcall_argument_overlap if indicated.
+ (check_sibcall_argument_overlap): Add mark_stored_args_map
+ parameter. Don't mark parameter area as clobbered if not set.
+ (expand_call): Adjust calls to above.
+
+2003-01-10 Kelley Cook <kelleycook@comcast.net>
+
+ * configure.in (linker read-only and read-write section mixing):
+ Squelch some assembler warnings.
+ * configure: Likewise.
+
+2003-01-10 Hartmut Penner <hpenner@de.ibm.com>
+
+ * doc/invoke.texi: Document -mtune, delete -mcpu
+ option for S/390 and zSeries.
+ * config/s390/s390.c (s390_tune_string) New variable.
+ (s390_cpu_string) Delete variable.
+ (override_options): Use s390_tune_string instead of
+ s390_cpu_string.
+ * config/s390/s390.h: (TARGET_OPTIONS) '-mtune' instead of '-mcpu'.
+
+2003-01-10 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*iorsi3_ashift_31): New.
+
+2003-01-10 Josef Zlomek <zlomekj@suse.cz>
+
+ * jump.c (next_nonnote_insn_in_loop): New function.
+ (copy_loop_headers): Use next_nonnote_insn_in_loop instead of
+ next_nonnote_insn.
+ (duplicate_loop_exit_test). Likewise.
+
+2003-01-09 Geoffrey Keating <geoffk@apple.com>
+
+ Merge from pch-branch:
+
+ 2003-01-06 Geoffrey Keating <geoffk@apple.com>
+
+ * ggc-page.c (ggc_pch_read): Update the statistics after a PCH
+ load.
+
+ 2002-12-24 Geoffrey Keating <geoffk@apple.com>
+
+ * cpplib.c (count_registered_pragmas): New function.
+ (save_registered_pragmas): New function.
+ (_cpp_save_pragma_names): New function.
+ (restore_registered_pragmas): New function.
+ (_cpp_restore_pragma_names): New function.
+ * cpphash.h (_cpp_save_pragma_names): Prototype.
+ (_cpp_restore_pragma_names): Likewise.
+ * cpppch.c (struct save_macro_item): Split from save_macro_data.
+ (struct save_macro_data): New field 'saved_pragmas'.
+ (save_macros): Update for changes to struct save_macro_data.
+ (cpp_prepare_state): Call _cpp_save_pragma_names, update
+ for changes to struct save_macro_data.
+ (cpp_read_state): Call _cpp_restore_pragma_names, update
+ for changes to struct save_macro_data.
+
+ * cpppch.c (cpp_read_state): Restore the hashtable references
+ in the cpp_reader.
+
+ * tree.h (built_in_decls): Mark for PCH.
+
+ * dbxout.c (lastfile): Don't mark for PCH.
+
+ * ggc.h: Document PCH calls into memory managers.
+
+ 2002-12-18 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/invoke.texi (Precompiled Headers): Document the
+ directory form of PCH.
+ * cppfiles.c (validate_pch): New function.
+ (open_file_pch): Search suitably-named directories for PCH files.
+
+ 2002-12-14 Geoffrey Keating <geoffk@apple.com>
+
+ * doc/gty.texi (GTY Options): Document chain_next, chain_prev,
+ reorder options.
+ (Type Information): Mention that the information is also
+ used to implement PCH.
+ * doc/passes.texi (Passes): Improve documentation of
+ language-specific files.
+
+ 2002-12-11 Geoffrey Keating <geoffk@apple.com>
+
+ * gengtype.c (struct write_types_data): Add reorder_note_routine field.
+ (struct walk_type_data): Add reorder_fn field.
+ (walk_type): Process 'reorder' option.
+ (write_types_process_field): Reorder parameters to gt_pch_note_object,
+ call reorder_note_routine.
+ (write_func_for_structure): Reorder parameters to gt_pch_note_object.
+ (ggc_wtd): Update for change to struct write_types_data.
+ (pch_wtd): Likewise.
+ * ggc.h (gt_pch_note_object): Reorder parameters.
+ (gt_handle_reorder): New definition.
+ (gt_pch_note_reorder): New prototype.
+ * ggc-common.c (struct ptr_data): Add reorder_fn.
+ (gt_pch_note_object): Reorder parameters.
+ (gt_pch_note_reorder): New.
+ (gt_pch_save): Call reorder_fn.
+ * stringpool.c (gt_pch_n_S): Update for change to gt_pch_note_object.
+
+ * dbxout.c (cwd): Don't mark for PCH.
+
+ 2002-12-09 Geoffrey Keating <geoffk@apple.com>
+
+ * gengtype.c (finish_root_table): Fix some warnings.
+ (write_root): Handle TYPE_STRING.
+ * ggc.h (gt_ggc_m_S): Add prototype.
+ * stringpool.c (gt_ggc_m_S): New function.
+
+ 2002-11-30 Geoffrey Keating <geoffk@apple.com>
+
+ * dwarf2out.c (dw2_string_counter): New.
+ (AT_string_form): Use it.
+ (same_dw_val_p): Update for removal of hashtable.h hash tables.
+
+ 2002-11-22 Geoffrey Keating <geoffk@apple.com>
+
+ * dbxout.c: Include gt-dbxout.h.
+ (lastfile): Mark for PCH/GGC.
+ (cwd): Likewise.
+ (struct typeinfo): Likewise.
+ (typevec): Likewise.
+ (typevec_len): Likewise.
+ (next_type_number): Likewise.
+ (struct dbx_file): Likewise.
+ (current_file): Likewise.
+ (next_file_number): Likewise.
+ (dbxout_init): Allocate typevec, struct dbx_file with GGC.
+ (dbxout_start_source_file): Allocate struct dbx_file with GGC.
+ (dbxout_end_source_file): Don't free struct dbx_file.
+ (dbxout_type): Use GGC to allocate typevec.
+ * Makefile.in (dbxout.o): Depend on gt-dbxout.h, $(GGC_H).
+ (GTFILES): Add dbxout.c.
+ (gt-dbxout.h): New rule.
+
+ * Makefile.in (c-pch.o): Add debug.h as dependency.
+ * c-pch.c: Include debug.h.
+ (pch_init): Call start_source_file to keep nesting right.
+ (c_common_read_pch): Add orig_name parameter. Call
+ start_source_file debug hook. Call end_source_file debug hook.
+ * c-common.h (c_common_read_pch): Update prototype.
+ * cpplib.h (struct cpp_callbacks): Add fourth field to read_pch
+ callback.
+ * cppfiles.c (struct include_file): Add new field `header_name'.
+ (find_or_create_entry): Default it to `name'.
+ (open_file_pch): Set it to the original header file searched for.
+ (stack_include_file): Don't stack an empty buffer, just handle
+ PCH files immediately. Pass header_name field to read_pch callback.
+
+ 2002-11-19 Geoffrey Keating <geoffk@apple.com>
+
+ * function.c (funcdef_no): Mark to be saved in a PCH.
+
+ 2002-11-15 Geoffrey Keating <geoffk@apple.com>
+
+ * ggc-page.c (ggc_pch_read): Remove unused 'bmap_size'.
+
+ * cpppch.c (cpp_read_state): Correct size reallocated for 'defn'.
+
+ 2002-11-14 Geoffrey Keating <geoffk@apple.com>
+
+ * optabs.h (code_to_optab): Add GTY marker.
+
+ 2002-11-13 Geoffrey Keating <geoffk@apple.com>
+
+ * Makefile.in (GTFILES): Add cpplib.h.
+ * c-common.h (struct c_common_identifier): Don't skip 'node' field.
+ * c-decl.c (build_compound_literal): Don't use var_labelno.
+ * cpplib.h (struct cpp_hashnode): Use gengtype to mark.
+ * dwarf2asm.c (dw2_force_const_mem): Don't use const_labelno.
+ * varasm.c (const_labelno): Use gengtype to mark.
+ (var_labelno): Likewise.
+ (in_section): Likewise.
+ (in_named_name): Likewise.
+ (struct in_named_entry): Likewise.
+ (in_named_htab): Likewise.
+ (set_named_section_flags): Use GGC to allocate struct in_named_entry.
+ (init_varasm_once): Use GGC to allocate in_named_htab.
+ * config/darwin.c (current_pic_label_num): Mark for PCH.
+
+ 2002-11-11 Geoffrey Keating <geoffk@apple.com>
+
+ * ggc-simple.c (init_ggc_pch): New stub procedure.
+ (ggc_pch_count_object): Likewise.
+ (ggc_pch_total_size): Likewise.
+ (ggc_pch_this_base): Likewise.
+ (ggc_pch_alloc_object): Likewise.
+ (ggc_pch_prepare_write): Likewise.
+ (ggc_pch_write_object): Likewise
+ (ggc_pch_finish): Likewise.
+ (ggc_pch_read): Likewise.
+
+ 2002-11-08 Geoffrey Keating <geoffk@apple.com>
+
+ * c-pch.c (c_common_write_pch): Write the macro definitions after
+ the GCed data.
+ (c_common_read_pch): Call cpp_prepare_state. Restore the macro
+ definitions after the GCed data.
+ * cpplib.c (save_macros): New.
+ (reset_ht): New.
+ (cpp_write_pch_deps): Split out of cpp_write_pch.
+ (cpp_write_pch_state): Split out of cpp_write_pch.
+ (cpp_write_pch): Delete.
+ (struct save_macro_data): Delete.
+ (cpp_prepare_state): New.
+ (cpp_read_state): Erase and restore initial macro definitions.
+ * cpplib.h (struct save_macro_data): Forward-declare.
+ (cpp_write_pch_deps): Prototype.
+ (cpp_write_pch_state): Prototype.
+ (cpp_write_pch): Delete prototype.
+ (cpp_prepare_state): Prototype.
+ (cpp_read_state): Add fourth argument.
+
+ 2002-11-04 Geoffrey Keating <geoffk@apple.com>
+
+ * gengtype.c (adjust_field_rtx_def): Don't use skip on valid fields.
+ (write_array): Remove warning.
+
+ * gengtype.c (contains_scalar_p): New.
+ (finish_root_table): Add the table to all languages, even if it's
+ empty.
+ (write_roots): Output gt_pch_scalar_rtab.
+ * ggc-common.c (gt_pch_save): Write out scalars.
+ (gt_pch_restore): Read scalars back.
+
+ * ggc-page.c (OBJECTS_IN_PAGE): New macro.
+ (struct page_entry): Delete pch_page field.
+ (ggc_recalculate_in_use_p): Use OBJECTS_IN_PAGE.
+ (clear_marks): Likewise.
+ (sweep_pages): Likewise.
+ (poison_pages): Likewise.
+ (ggc_print_statistics): Likewise.
+ (ggc_pch_read): Don't free objects read from a PCH.
+ Properly set up in_use_p and page_tails.
+
+ 2002-10-25 Geoffrey Keating <geoffk@apple.com>
+
+ * gengtype.c (struct write_types_data): New.
+ (struct walk_type_data): Make `cookie' const; add extra
+ prev_val item; add `orig_s' field.
+ (walk_type): Update prev_val[3].
+ (write_types_process_field): New.
+ (write_func_for_structure): Take write_types_data structure.
+ (write_types): New.
+ (ggc_wtd): New.
+ (pch_wtd): New.
+ (write_types_local_process_field): New.
+ (gc_mark_process_field): Delete.
+ (write_local_func_for_structure): New.
+ (gc_mark_func_name): Delete.
+ (write_gc_types): Delete.
+ (write_local): New.
+ (finish_root_table): Don't include 'ggc_' in PFX.
+ (write_root): Rename from write_root. Fill pchw field of structures.
+ (write_array): New.
+ (write_roots): Rename from write_gc_roots. Split out to write_array.
+ Update to changes to other routines. Write gt_pch_cache_rtab table.
+ (main): Write PCH walking routines.
+ * ggc-common.c: Include toplev.h, sys/mman.h.
+ (ggc_mark_roots): For cache hashtables, also mark the hash table
+ and the array of entries.
+ (saving_htab): New.
+ (struct ptr_data): New.
+ (POINTER_HASH): New.
+ (gt_pch_note_object): New.
+ (saving_htab_hash): New.
+ (saving_htab_eq): New.
+ (struct traversal_state): New.
+ (call_count): New.
+ (call_alloc): New.
+ (compare_ptr_data): New.
+ (relocate_ptrs): New.
+ (write_pch_globals): New.
+ (struct mmap_info): New.
+ (gt_pch_save): New.
+ (gt_pch_restore): New.
+ * ggc-page.c (ROUND_UP_VALUE): New.
+ (ROUND_UP): New.
+ (struct page_entry): Add field `pch_page'.
+ (init_ggc): Use ROUND_UP.
+ (struct ggc_pch_data): Declare.
+ (init_ggc_pch): New.
+ (ggc_pch_count_object): New.
+ (ggc_pch_total_size): New.
+ (ggc_pch_this_base): New.
+ (ggc_pch_alloc_object): New.
+ (ggc_pch_prepare_write): New.
+ (ggc_pch_write_object): New.
+ (ggc_pch_finish): New.
+ (ggc_pch_read): New.
+ * ggc.h (gt_pointer_operator): New.
+ (gt_note_pointers): New.
+ (gt_pch_note_object): New prototype.
+ (gt_pointer_walker): New.
+ (struct ggc_root_tab): Use gt_pointer_walker, add `pchw' field.
+ (LAST_GGC_ROOT_TAB): Update.
+ (gt_pch_cache_rtab): Declare.
+ (gt_pch_scalar_rtab): Declare.
+ (struct ggc_cache_tab): Use gt_pointer_walker, add `pchw' field.
+ (LAST_GGC_CACHE_TAB): Update.
+ (gt_pch_save_stringpool): Declare.
+ (gt_pch_restore_stringpool): Declare.
+ (gt_pch_p_S): Declare.
+ (gt_pch_n_S): Declare.
+ (struct ggc_pch_data): Forward-declare.
+ (init_ggc_pch): Declare.
+ (ggc_pch_count_object): Declare.
+ (ggc_pch_total_size): Declare.
+ (ggc_pch_this_base): Declare.
+ (ggc_pch_alloc_object): Declare.
+ (ggc_pch_prepare_write): Declare.
+ (ggc_pch_write_object): Declare.
+ (ggc_pch_finish): Declare.
+ (ggc_pch_read): Declare.
+ (gt_pch_save): Declare.
+ (gt_pch_restore): Declare.
+ * fold-const.c (size_int_type_wide): Allocate size_htab using GGC.
+ * emit-rtl.c (init_emit_once): Allocate const_int_htab,
+ const_double_htab, mem_attrs_htab using GGC.
+ * c-pch.c: Include ggc.h.
+ (pch_init): Allow reading PCH file back.
+ (c_common_write_pch): Call gt_pch_save.
+ (c_common_read_pch): Call gt_pch_restore.
+ * c-parse.in (init_reswords): Delete now-untrue comment.
+ Allocate ridpointers using GGC.
+ * c-objc-common.c (c_objc_common_finish_file): Write PCH before
+ calling expand_deferred_fns.
+ * c-common.h (ridpointers): Mark for GTY machinery.
+ * Makefile.in (stringpool.o): Update dependencies.
+ (c-pch.o): Update dependencies.
+ (ggc-common.o): Update dependencies.
+ * stringpool.c: Include gt-stringpool.h.
+ (gt_pch_p_S): New.
+ (gt_pch_n_S): New.
+ (struct string_pool_data): New.
+ (spd): New.
+ (gt_pch_save_stringpool): New.
+ (gt_pch_restore_stringpool): New.
+ * tree.c (init_ttree): Make type_hash_table allocated using GC.
+
+ 2002-10-04 Geoffrey Keating <geoffk@apple.com>
+
+ * gengtype.c (adjust_field_rtx_def): Don't pass size_t to printf.
+ (output_mangled_typename): Don't pass size_t to printf.
+
+ * tree.h (union tree_type_symtab): Add tag to `address' field.
+ (union tree_decl_u2): Add tag to 'i' field.
+ * varasm.c (union rtx_const_un): Add tags to all fields.
+ * gengtype.c (struct walk_type_data): New.
+ (output_escaped_param): Take struct walk_type_data parameter.
+ (write_gc_structure_fields): Delete.
+ (walk_type): New.
+ (write_gc_marker_routine_for_structure): Delete.
+ (write_func_for_structure): New.
+ (gc_mark_process_field): New.
+ (gc_mark_func_name): New.
+ (gc_counter): Delete.
+ (write_gc_types): Use write_func_for_structure.
+ (write_gc_roots): Use walk_type.
+
+ 2002-10-02 Geoffrey Keating <geoffk@apple.com>
+
+ * ggc-common.c (ggc_mark_roots): Delete 'x'.
+ (ggc_splay_dont_free): Fix warning about unused 'x'.
+ (ggc_print_common_statistics): Remove warnings.
+
+ 2002-10-01 Mike Stump <mrs@apple.com>
+
+ * ggc-common.c (ggc_splay_alloc): Actually return the allocated area.
+ * gengtype.c (write_gc_structure_fields): Handle param[digit]_is.
+
+ 2002-09-01 Geoffrey Keating <geoffk@redhat.com>
+ Catherine Moore <clm@redhat.com>
+
+ * Makefile (c-pch.o): Update dependencies.
+ (LIBCPP_OBJS): Add cpppch.o.
+ (cpppch.o): New.
+ * c-common.c (c_common_init): Don't call pch_init here.
+ * c-common.h (c_common_read_pch): Update prototype.
+ * c-lex.c (c_common_parse_file): Call pch_init here.
+ * c-opts.c (COMMAND_LINE_OPTIONS): Add -Winvalid-pch, -fpch-deps.
+ (c_common_decode_option): Handle them.
+ * c-pch.c: Include c-pragma.h.
+ (save_asm_offset): Delete.
+ (pch_init): Move contents of save_asm_offset into here, call
+ cpp_save_state.
+ (c_common_write_pch): Call cpp_write_pch.
+ (c_common_valid_pch): Warn only when -Winvalid-pch. Call
+ cpp_valid_state.
+ (c_common_read_pch): Add NAME parameter. Call cpp_read_state.
+ * cppfiles.c (stack_include_file): Update for change to
+ parameters of cb.read_pch.
+ * cpphash.h (struct cpp_reader): Add `savedstate' field.
+ * cpplib.h (struct cpp_options): Add `warn_invalid_pch' and
+ `restore_pch_deps' fields.
+ (struct cpp_callbacks): Add NAME parameter to `read_pch'.
+ (cpp_save_state): Prototype.
+ (cpp_write_pch): Prototype.
+ (cpp_valid_state): Prototype.
+ (cpp_read_state): Prototype.
+ * cpppch.c: New file.
+ * flags.h (version_flag): Remove prototype.
+ * mkdeps.c (deps_save): New.
+ (deps_restore): New.
+ * mkdeps.h (deps_save): Prototype.
+ (deps_restore): Prototype.
+ * toplev.c (late_init_hook): Delete.
+ (version_flag): Make static again.
+ (compile_file): Don't call late_init_hook.
+ * toplev.h (late_init_hook): Delete.
+ * doc/cppopts.texi: Document -fpch-deps.
+ * doc/invoke.texi (Warning Options): Document -Winvalid-pch.
+
+ 2002-08-27 Geoffrey Keating <geoffk@redhat.com>
+
+ * c-pch.c (c_common_write_pch): Rename from c_write_pch, change
+ callers.
+ (c_common_valid_pch): Rename from c_valid_pch, change callers.
+ (c_common_read_pch): Rename from c_read_pch, change callers.
+
+ * c-opts.c (COMMAND_LINE_OPTIONS): Allow -output-pch= to have
+ a space between it and its argument.
+
+ 2002-08-24 Geoffrey Keating <geoffk@redhat.com>
+
+ * c-pch.c: New file.
+ * toplev.h (late_init_hook): Declare.
+ * toplev.c (late_init_hook): Define.
+ (version_flag): Make globally visible.
+ (compile_file): Call late_init_hook.
+ (init_asm_output): Make output file seekable.
+ * gcc.c (default_compilers): Update c-header rule.
+ * flags.h (version_flag): Declare.
+ * cpplib.h (struct cpp_callbacks): Add 'valid_pch' and 'read_pch'
+ fields.
+ * cppfiles.c (struct include_file): Add 'pch' field.
+ (INCLUDE_PCH_P): New.
+ (open_file_pch): New.
+ (stack_include_file): Handle PCH files specially.
+ (find_include_file): Call open_file_pch instead of open_file.
+ (_cpp_read_file): Explain why open_file is used instead of
+ open_file_pch.
+ * c-opts.c (c_common_decode_option): Correct OPT__output_pch case.
+ * c-objc-common.c (c_objc_common_finish_file): Call c_write_pch.
+ * c-lex.c (init_c_lex): Set valid_pch and read_pch fields
+ in cpplib callbacks.
+ * c-common.c (pch_file): Correct comment.
+ (allow_pch): Define.
+ (c_common_init): Call pch_init.
+ * c-common.h (allow_pch): Declare.
+ (pch_init): Declare.
+ (c_valid_pch): Declare.
+ (c_read_pch): Declare.
+ (c_write_pch): Declare.
+ * Makefile.in (c-pch.o): New.
+ (C_AND_OBJC_OBJS): Add c-pch.o.
+ * doc/invoke.texi (Precompiled Headers): Add index entries,
+ complete truncated paragraph.
+
+ 2002-08-17 Geoffrey Keating <geoffk@redhat.com>
+
+ * c-common.c: (pch_file): Define.
+ * c-common.h (pch_file): Declare.
+ * c-opts.c (COMMAND_LINE_OPTIONS): Add --output-pch=.
+ (missing_arg): Require --output-pch= to have an argument.
+ (c_common_decode_option): Handle --output-pch=.
+ * gcc.c: Document new %V.
+ (default_compilers): Handle compiling C header files.
+ (do_spec_1): Implement %V.
+ (main): Handle "gcc foo.h" without trying to run linker.
+ * doc/invoke.texi (Invoking GCC): Add new menu item for PCH.
+ (Overall Options): Document what the driver does with header files,
+ document new -x option possibilities.
+ (Invoking G++): More documentation for PCH.
+ (Precompiled Headers): New.
+
+ 2002-08-09 Geoffrey Keating <geoffk@redhat.com>
+
+ * ggc.h: Don't include varray.h. Rearrange functions to be more
+ organized.
+ (ggc_add_root): Delete.
+ (ggc_mark_rtx): Delete.
+ (ggc_mark_tree): Delete.
+ (struct ggc_statistics): Remove contents.
+ * ggc-common.c: Remove unneeded includes.
+ (struct ggc_root): Delete.
+ (roots): Delete.
+ (ggc_add_root): Delete.
+ (ggc_mark_roots): Don't mark `roots'. Call ggc_mark_stringpool.
+ (ggc_print_common_statistics): Remove most of the contents.
+ * Makefile.in (GGC_H): No longer uses varray.h.
+ (ggc-common.o): Update dependencies.
+ (c-parse.o): Add varray.h to dependencies.
+ (c-common.o): Add varray.h.
+ * stringpool.c (mark_ident): Use mangled name for tree marker routine.
+ (mark_ident_hash): Rename to ggc_mark_stringpool.
+ (init_stringpool): Don't use ggc_add_root.
+ * c-parse.in: Include varray.h.
+ * c-common.c: Include varray.h.
+ * objc/Make-lang.in (objc-act.o): Add varray.h.
+ * objc/objc-act.c: Include varray.h.
+
+ 2002-07-25 Geoffrey Keating <geoffk@redhat.com>
+
+ * dwarf2out.c (dw_cfi_oprnd2_desc): Fix ISO-only function definition.
+ (dw_cfi_oprnd1_desc): Likewise.
+
+ 2002-07-17 Geoffrey Keating <geoffk@redhat.com>
+
+ * config/alpha/alpha.c (struct alpha_links): Use gengtype to mark;
+ move out of ifdef.
+ (alpha_links): Use gengtype to mark; move out of ifdef.
+ (mark_alpha_links_node): Delete.
+ (mark_alpha_links): Delete.
+ (alpha_need_linkage): Use GGC to allocate splay tree, struct
+ alpha_links, strings. Don't use ggc_add_root.
+ * ggc-common.c (ggc_splay_alloc): New.
+ (ggc_splay_dont_free): New.
+ * ggc.h (ggc_mark_rtx): Update for changed name mangling.
+ (ggc_mark_tree): Likewise.
+ (splay_tree_new_ggc): New.
+ (ggc_splay_alloc): Declare.
+ (ggc_splay_dont_free): Declare.
+ * dwarf2asm.c: Include gt-dwarf2asm.h.
+ (mark_indirect_pool_entry): Delete.
+ (mark_indirect_pool): Delete.
+ (indirect_pool): Use gengtype to mark.
+ (dw2_force_const_mem): Don't use ggc_add_root.
+ * Makefile.in (dwarf2asm.o): Depend on gt-dwarf2asm.h.
+ (GTFILES): Add SPLAY_TREE_H, dwarf2asm.c.
+ (gt-dwarf2asm.h): Depend on s-gtype.
+
+ 2002-07-08 Geoffrey Keating <geoffk@redhat.com>
+
+ * tree.h (union tree_type_symtab): Mark `die' field.
+ * Makefile.in (dwarf2out.o): Update dependencies.
+ * dwarf2out.c: Use GGC to allocate all structures. Convert to htab_t
+ hash tables.
+ (dw_cfi_oprnd1_desc): New function.
+ (dw_cfi_oprnd2_desc): New function.
+ (indirect_string_alloc): Delete.
+ (debug_str_do_hash): New function.
+ (debug_str_eq): New function.
+ (mark_limbo_die_list): Delete.
+ (dwarf2out_init): Don't call ggc_add_root.
+
+2003-01-09 Vladimir Makarov <vmakarov@redhat.com>
+
+ The following changes are merged from itanium-sched-branch:
+
+ 2003-01-08 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/md.texi: Clarify assignment of units to automata description.
+
+ 2003-01-08 Vladimir Makarov <vmakarov@redhat.com>
+
+ * genautomata.c (unit_decl): Remove members
+ `the_same_automaton_unit' and
+ `the_same_automaton_message_reported_p'.
+ (process_unit_to_form_the_same_automaton_unit_lists,
+ form_the_same_automaton_unit_lists_from_regexp,
+ form_the_same_automaton_unit_lists, the_same_automaton_lists):
+ Remove them.
+ (annotation_message_reported_p): New global variable.
+ (check_unit_distribution_in_reserv,
+ check_regexp_units_distribution): New functions.
+ (check_unit_distributions_to_automata): Rewrite it.
+
+ 2003-01-04 Vladimir Makarov <vmakarov@redhat.com>
+
+ * genautomata.c (form_the_same_automaton_unit_lists_from_regexp):
+ Use continue instead of break if cycle is too big.
+
+ 2002-12-20 Vladimir Makarov <vmakarov@redhat.com>
+
+ * genautomata.c (check_unit_distributions_to_automata): Output at
+ most one message for a unit.
+ (process_unit_to_form_the_same_automaton_unit_lists): Check
+ automaton of units instead of units themself.
+
+ * doc/md.texi: Describe the constraint about assigning unit to
+ automata.
+
+ 2002-12-20 Jan Hubicka <jH@suse.cz>
+ Vladimir Makarov <vmakarov@redhat.com>
+
+ * genautomata.c (unit_decl): Add new members `min_occ_cycle_num'
+ and `in_set_p'.
+ (gen_cpu_unit): Initialize the new members.
+ (process_regexp_cycles): Calculate minimal finish cycle too. Set
+ up `min_occ_cycle_num'.
+ (evaluate_max_reserv_cycles): Change the function call.
+ (CLEAR_BIT): New macro.
+ (states_union, state_shift): Use the mask.
+ (initiate_excl_sets, form_reserv_sets_list): Set up `in_set_p'.
+ (form_reservs_matter): New function.
+ (make_automaton): Call the function and use the mask.
+ (estimate_one_automaton_bound): Take `min_occ_cycle_num' into
+ account.
+
+ 2002-12-17 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/ia64/itanium2.md (lfetch): Change the insn reservation.
+
+ 2002-12-17 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/ia64/ia64.c (bundling): Try to insert 2 nops for M insn
+ for Itanium.
+
+ 2002-12-17 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/ia64/ia64.c (ia64_override_options): Make itanium2 as
+ default cpu.
+
+ 2002-12-17 Vladimir Makarov <vmakarov@redhat.com>
+ 2002-10-31 Dale Johannesen <dalej@apple.com>
+
+ * haifa-sched.c (find_set_reg_weight): New function.
+ (find_insn_reg_weight): Use the new function.
+ (schedule_block): Do sorting ready queue always
+ after insn issue.
+
+ 2002-11-27 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/ia64/ia64.c (bundling): Use MFI template instead of MLX.
+
+ 2002-11-19 Vladimir Makarov <vmakarov@redhat.com>
+
+ * haifa-sched.c (choice_entry): New structure.
+ (choice_stack, cycle_issued_insns): New variables.
+ (max_issue): Rewrite it.
+ (choose_ready): Set up ready_try for unknown insns too.
+ (schedule_block): Allocate and free choice_stack. Set up
+ and modify cycle_issued_insns.
+
+ * config/ia64/ia64.c (issue_nops_and_insn): Combine insn issue
+ with and without filling the bundle.
+ (bundling): Combine calls of issue_nops_and_insn.
+
+ 2002-10-17 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/ia64/itanium1.md: New file.
+
+ * config/ia64/itanium2.md: New file.
+
+ * config/ia64/ia64.md: Move DFA descriptions into the new files.
+ Remove the old pipeline description.
+
+ * config/ia64/ia64.c (ia64_override_options): Add aliases of
+ itanium processor names.
+
+ 2002-10-16 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/ia64/ia64.c (bundling): Print states for Itanium2 too.
+ (ia64_reorg): Set up queried unit codes for Itanium2 too.
+
+ * config/ia64/ia64.md: Add descriptions for Itanium2.
+
+ 2002-10-08 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/ia64/ia64.h (processor_type): New enumeration.
+ (ia64_tune, ia64_tune_string): New external declarations.
+ (TARGET_OPTIONS): Add option `tune='.
+
+ * config/ia64/ia64.c (ia64_tune, ia64_tune_string): New global
+ variables.
+ (ia64_override_options): Set up `ia64_tune'.
+ (ia64_sched_reorder2): Set up `clocks' only for Itanium.
+ (ia64_dfa_new_cycle): Set up `add_cycles' only for Itanium.
+ (bundling): Add nops for MM-insns only for Itanium.
+ (ia64_reorg): Allocate and free `clocks' and `add_cycles' only for
+ Itanium.
+
+ * config/ia64/ia64.md (cpu): New attribute.
+ (DFA description): Enable it only for Itanium.
+
+ 2002-10-08 Vladimir Makarov <vmakarov@redhat.com>
+ Richard Henderson <rth@redhat.com>
+
+ * config/ia64/ia64.h (MASK_TUNE_STOP_BITS): Rename it to
+ MASK_EARLY_STOP_BITS.
+ (TARGET_TUNE_STOP_BITS): Rename it to TARGET_EARLY_STOP_BITS.
+ (TARGET_SWITCHES): Rename option `tune-stop-bits' to
+ `early-stop-bits'.
+
+ * config/ia64/ia64.c (ia64_dfa_new_cycle,
+ final_emit_insn_group_barriers): Use TARGET_EARLY_STOP_BITS
+ instead of TARGET_TUNE_STOP_BITS.
+
+ * doc/invoke.texi: Rename option `-mtune-stop-bits' to
+ `-mearly-stop-bits'.
+
+ * config/ia64/ia64.c (automata_option "v"): Comment it.
+
+ 2002-10-07 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/ia64/ia64.h (MASK_TUNE_STOP_BITS, TARGET_TUNE_STOP_BITS):
+ New macros.
+ (TARGET_SWITCHES): Add entries for the new option.
+
+ * config/ia64/ia64.c (dfa_stop_insn, last_scheduled_insn, rtx
+ dfa_pre_cycle_insn, ia64_nop): Don't make them as roots for GC.
+ (stops_p, stop_before_p, clocks_length, clocks, add_cycles): New
+ global variables.
+ (ia64_sched_reorder2): Set up `clocks'.
+ (ia64_variable_issue): Set up `stops_p' and reset `stop_before_p'.
+ (ia64_dfa_new_cycle): Set up add_cycle. Permit sorting ready
+ queue when TARGET_TUNE_STOP_BITS.
+ (bundling): Insert additional nops for MM-insns.
+ (final_emit_insn_group_barriers): Add insertion of stop bits
+ according `stops_p'.
+ (ia64_reorg): Initiate the new varibales.
+
+ * doc/invoke.texi: Add description of option `-mtune-stop-bits'.
+
+ 2002-10-02 Vladimir Makarov <vmakarov@redhat.com>
+
+ * haifa-sched.c (schedule_block): Modify INSN_TICK of depended
+ insns at the end of block insn scheduling.
+
+ 2002-09-30 Vladimir Makarov <vmakarov@redhat.com>
+
+ * sched-deps.c (remove_dependence, group_leader): Remove it.
+ (add_dependence): Add dependence to group leader to.
+ (set_sched_group_p): Add dependence to the first insn of the
+ schedule group too.
+ (sched_analyze_insn): Make dependence to jump as anti-dependence.
+ Change true dependence by anti-dependence when
+ `reg_pending_barrier'.
+
+ * sched-rgn.c (init_ready_list, can_schedule_ready_p,
+ add_branch_dependences): Ignore schedule groups.
+
+ * sched-ebb.c (init_ready_list): Ditto.
+
+ * (move_insn, set_priorities): Ditto.
+
+ * config/ia64/ia64.c (ia64_sched_init): Check that schedule group
+ flag is clear after reload.
+ (adjust_cost): Change cost only for output dependencies.
+
+ * config/ia64/ia64.md: Add more insns into bypass for MM-insns.
+
+ 2002-09-26 Vladimir Makarov <vmakarov@redhat.com>
+
+ * Makefile.in (sched-ebb.o): Add `$(TARGET_H)' to the entry.
+
+ * target.h (gcc_target): Add member
+ `dependencies_evaluation_hook'.
+
+ * target-def.h (TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK): New
+ macro.
+ (TARGET_SCHED): Add initiatialization of the new member.
+
+ * sched-ebb.c: Include `target.h'.
+ (schedule_ebb): Call `dependencies_evaluation_hook'.
+
+ * sched-rgn.c (schedule_region): Call
+ `dependencies_evaluation_hook'.
+
+ * config/ia64/ia64.c (TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK):
+ New macro.
+ (ia64_dependencies_evaluation_hook): New function.
+
+ * doc/tm.texi (TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK):
+ Describe the new hook.
+
+ 2002-09-25 Vladimir Makarov <vmakarov@redhat.com>
+
+ * target.h (gcc_target): Add members
+ `first_cycle_multipass_dfa_lookahead_guard' and `dfa_new_cycle'.
+
+ * target-def.h (TARGET_SCHED_DFA_NEW_CYCLE,
+ TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD): New
+ macros.
+ (TARGET_SCHED): Add initiatialization of the new members.
+
+ * haifa-sched.c (schedule_insn): Update last_clock_var for the 1st
+ insn scheduling too.
+ (choose_ready): Use `first_cycle_multipass_dfa_lookahead_guard' to
+ initialize `ready_try'.
+ (schedule_block): Use `dfa_new_cycle'. Sort `ready' only unless
+ `dfa_new_cycle' says not to do it.
+
+ * config/ia64/ia64.md: Add DFA Itanium 1 description for insn
+ bundling.
+
+ * config/ia64/ia64.h (CPU_UNITS_QUERY): New macro.
+
+ * config/ia64/ia64.c: Include `hashtab.h'.
+ (ia64_first_cycle_multipass_dfa_lookahead_guard,
+ ia64_dfa_new_cycle, final_emit_insn_group_barriers,
+ ia64_dfa_sched_reorder, get_free_bundle_state, free_bundle_state,
+ initiate_bundle_states, finish_bundle_states, bundle_state_hash,
+ bundle_state_eq_p, insert_bundle_state,
+ initiate_bundle_state_table, finish_bundle_state_table,
+ try_issue_nops, try_issue_insn, issue_nops_and_insn, get_max_pos,
+ get_template, get_next_important_insn, bundling): New functions.
+ (ia64_internal_sched_reorder): Remove it.
+ (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD,
+ TARGET_SCHED_DFA_NEW_CYCLE): New macros.
+ (ia64_safe_itanium_requires_unit0): Remove it.
+ (group_barrier_needed_p): Place group barrier right before a real
+ insn.
+ (bundle, ia64_packet, NR_PACKETS, type_names, packets, packets):
+ Remove them.
+ (bundle_name): New variable.
+ (_0mii_, _0mmi_, _0mfi_, _0mmf_, _0bbb_, _0mbb_, _0mib_, _0mmb_,
+ _0mfb_, _0mlx_, _1mii_, _1mmi_, _1mfi_, _1mmf_, _1bbb_, _1mbb_,
+ _1mib_, _1mmb_, _1mfb_, _1mlx_, pos_1, pos_2, pos_3, pos_4, pos_5,
+ pos_6, dfa_stop_insn, last_scheduled_insn, dfa_state_size,
+ temp_dfa_state, prev_cycle_state): New global variables.
+ (insn_matches_slot, maybe_rotate, finish_last_head,
+ rotate_one_bundle, rotate_one_bundles, nop_cycles_until,
+ cycle_end_fill_slots, packet_matches_p, get_split, find_best_insn,
+ find_best_packet, itanium_reorder, dump_current_packet,
+ schedule_stop, gen_nop_type, ia64_emit_nops): Remove them.
+ (sched_data, sched_ready, sched_types): Remove them.
+ (ia64_sched_init): Initiate only `last_scheduled_insn' and call
+ `init_insn_group_barriers'.
+ (ia64_sched_reorder, ia64_sched_reorder2): Call
+ ia64_dfa_sched_reorder.
+ (ia64_variable_issue): Rewrite it.
+ (bundle_state): New structure.
+ (index_to_bundle_states, bundle_states_num,
+ allocated_bundle_states_chain, free_bundle_state_chain): New
+ global variables.
+ (ia64_sched_finish): Add stop bits and call `bundling' after the
+ 2nd insn scheduling.
+ (ia64_use_dfa_pipeline_interface): Return zero always.
+ (ia64_first_cycle_multipass_dfa_lookahead): Return 6 for the 2nd
+ insn scheduling.
+ (ia64_init_dfa_pre_cycle_insn): Initialize `dfa_state_size',
+ `temp_dfa_state', `prev_cycle_state', and `dfa_stop_insn'.
+ (ia64_reorg): Add bundling insns.
+
+ * doc/tm.texi
+ (TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD,
+ TARGET_SCHED_DFA_NEW_CYCLE): Describe the new hooks.
+
+ 2002-09-23 Vladimir Makarov <vmakarov@redhat.com>
+
+ * config/ia64/ia64.md: Add Itanium1 DFA description.
+ (itanium_class): Add `nop' and `pre_cycle'. Add
+ define_function_unit for `nop'.
+ (nop): Change attribute `itanium_class'.
+ (pre_cycle): New define_insn.
+
+ * config/ia64/ia64-protos.h (bundling_p): New external variable.
+ (ia64_st_address_bypass_p, ia64_ld_address_bypass_p,
+ ia64_produce_address_p): New function prototypes.
+
+ * config/ia64/ia64.c (bundling_p): New global variable.
+ (ia64_use_dfa_pipeline_interface,
+ ia64_first_cycle_multipass_dfa_lookahead,
+ ia64_init_dfa_pre_cycle_insn, ia64_dfa_pre_cycle_insn): New
+ functions.
+ (TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE,
+ TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD,
+ TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN,
+ TARGET_SCHED_DFA_PRE_CYCLE_INSN): New macros.
+ (ia64_sched_init, ia64_sched_reorder, ia64_sched_reorder2,
+ ia64_variable_issue, ia64_sched_finish): Do nothing before reload.
+ (dfa_pre_cycle_insn): New variable.
+
+ 2002-09-20 Vladimir Makarov <vmakarov@redhat.com>
+
+ * rtl.def (FINAL_PRESENCE_SET, FINAL_ABSENCE_SET): New
+ constructions.
+
+ * genattrtab.h (gen_final_presence_set, gen_final_absence_set):
+ New function prototypes.
+
+ * genattrtab.c (main): Process the new constructions.
+
+ * genautomata.c (gen_presence_absence_set,
+ process_presence_absence_names, process_presence_absence_patterns,
+ add_presence_absence, check_absence_pattern_sets): Add parameter
+ `final_p'.
+ (unit_decl): Add new members `final_presence_list' and
+ `final_absence_list'.
+ (unit_pattern_rel_decl): Add new member `final_p'.
+ (gen_final_presence_set, gen_final_absence_set): New functions.
+ (process_decls): Use member `final_p'.
+ (temp_reserv): New global variable.
+ (reserv_sets_are_intersected): Add processing `final_presence_set'
+ and `final_absence_set'.
+ (initiate_states): Allocate `temp_reserv'.
+ (unit_final_presence_set_table, unit_final_absence_set_table): New
+ gloabal variables.
+ (initiate_presence_absence_pattern_sets): Initiate them.
+ (NDFA_to_DFA): Fix typo.
+ (output_description): Output `final_presence_set' and
+ `final_absence_set'.
+
+ * doc/md.texi (final_presence_set, final_absence_set): Describe
+ them.
+
+ 2002-09-20 Vladimir Makarov <vmakarov@redhat.com>
+
+ * genautomata.c (transform_3): Process a missing case (nothing on
+ unit place).
+
+ 2002-09-20 Vladimir Makarov <vmakarov@redhat.com>
+
+ * rtl.def (DEFINE_QUERY_CPU_UNIT, AUTOMATA_OPTION): Change
+ comments about queried units and the minimization.
+
+ * doc/md.texi: Ditto.
+
+ * genautomata.c (create_composed_state): Return nonzero if the new
+ state has been created.
+ (first_cycle_unit_presence): New function.
+ (state_is_differed): Add new parameter. Use the new function.
+ Take queried units into account.
+ (partition_equiv_class): Pass additional parameter to
+ `state_is_differed'.
+ (merge_states): Process composed states too.
+ (build_automaton, create_automata, output_min_issue_delay_table,
+ output_tables, output_statistics): Output more information.
+ (output_reserved_units_table): Use function
+ `first_cycle_unit_presence'.
+ (output_tables): Output table of queried units even if the
+ minimization is switched on.
+ (write_automata): Output code for querying units even if the
+ minimization is switched on.
+
+ 2002-09-19 Vladimir Makarov <vmakarov@redhat.com>
+
+ * rtl.def (PRESENCE_SET, ABSENCE_SET): Add comments about extended
+ syntax of the constructions.
+
+ * doc/md.texi (PRESENCE_SET, ABSENCE_SET): Add description of
+ extended syntax of the constructions.
+
+ * genautomata.c (unit_rel_decl): Rename it to
+ `unit_pattern_rel_decl'.
+ (pattern_set_el, pattern_reserv): New structures.
+ (pattern_set_el_t, pattern_reserv_t): New types.
+ (gen_presence_absence_set): New function.
+ (process_presence_absence): Remove it.
+ (process_presence_absence_names,
+ process_presence_absence_patterns): New functions.
+ (get_presence_absence_set): Remove it.
+ (initiate_presence_absence_sets): Rename it on
+ `initiate_presence_absence_pattern_sets'. Use new function
+ `form_reserv_sets_list'.
+ (form_reserv_sets_list, check_presence_pattern_sets,
+ check_absence_pattern_sets, output_pattern_set_el_list): New
+ functions.
+ (unit_decl): Change types of members `presence_list' and
+ `absence_list'.
+ (unit_rel_decl): Rename member `names_num' to `all_names_num'.
+ (decl): Change types of members `excl', `presence', and `absence'.
+ (get_str_vect): Rename `par_flag' to `paren_p'. Add null element
+ at the end of the vector.
+ (gen_cpu_unit, gen_query_cpu_unit, gen_bypass, gen_excl_set,
+ gen_automaton, gen_regexp_repeat, gen_regexp_allof,
+ gen_regexp_oneof, gen_regexp_sequence): Use boolean values.
+ (gen_presence_set, gen_absence_set): Use new function
+ `gen_presence_absence_set'.
+ (add_presence_absence): Process `pattern_list' instead of
+ `source_list'.
+ (process_decls): USe new functions
+ `process_presence_absence_names' and
+ `process_presence_absence_patterns'.
+ (reserv_sets_are_intersected): Use new function
+ `check_presence_pattern_sets'.
+ (presence_set, absence_set): Remove them.
+ (unit_presence_set_table, unit_absence_set_table): New global
+ variables.
+ (output_description): Use new function
+ `output_pattern_set_el_list'.
+ (generate): Use `initiate_presence_absence_pattern_sets'.
+
+ 2002-09-18 Vladimir Makarov <vmakarov@redhat.com>
+
+ * genattr.c (main): Add output of prototype of new interface
+ function `dfa_clean_insn_cache'.
+
+ * genautomata.c (output_dfa_clean_insn_cache_func): New function.
+ (DFA_CLEAN_INSN_CACHE_FUNC_NAME): New macro.
+ (output_dfa_start_func): Use function `dfa_clean_insn_cache' in
+ the generated code.
+ (write_automata): Call the new function.
+
+2003-01-09 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (unit, prefix_0f, memory attributes): Hanlde sseicvt
+ correctly.
+
+2003-01-09 Paolo Carlini <pcarlini@unitus.it>
+
+ * doc/tm.texi (EXTRA_ADDRESS_CONSTRAINT): Fix typo.
+
+2003-01-09 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * defaults.h (EXTRA_MEMORY_CONSTRAINT): Add STR argument.
+ (EXTRA_ADDRESS_CONSTRAINT): Likewise.
+ (CONSTRAINT_LEN): Provide default definition.
+ (CONST_OK_FOR_CONSTRAINT_P): Likewise.
+ (CONST_DOUBLE_OK_FOR_CONSTRAINT_P): Likewise.
+ (EXTRA_CONSTRAINT_STR): Likewise.
+ (REG_CLASS_FROM_CONSTRAINT): Define.
+ * genoutput.c (check_constraint_len, constraint_len): New functions.
+ (validate_insn_alternatives): Check CONSTRAINT_LEN for each
+ constraint / modifier.
+ (gen_insn): Call check_constraint_len.
+ * local-alloc.c (block_alloc): Update to use new macros / pass
+ second argument to EXTRA_{MEMORY,ADDRESS}_CONSTRAINT.
+ * ra-build.c (handle_asm_insn): Likewise.
+ * recog.c (asm_operand_ok, preprocess_constraints): Likewise.
+ (constrain_operands, peep2_find_free_register): Likewise.
+ * regclass.c (record_operand_costs, record_reg_classes): Likewise.
+ * regmove.c (find_matches): Likewise.
+ * reload.c (push_secondary_reload, find_reloads): Likewise.
+ (alternative_allows_memconst): Likewise.
+ * reload1.c (maybe_fix_stack_asms): Likewise.
+ (reload_cse_simplify_operands): Likewise.
+ * stmt.c (parse_output_constraint, parse_input_constraint): Likewise.
+ * doc/tm.texi (CONSTRAINT_LEN, REG_CLASS_FROM_CONSTRAINT): Document.
+ (CONST_OK_FOR_CONSTRAINT_P): Likewise.
+ (CONST_DOUBLE_OK_FOR_CONSTRAINT_P, EXTRA_CONSTRAINT_STR): Likewise.
+ (EXTRA_MEMORY_CONSTRAINT, EXTRA_ADDRESS_CONSTRAINT): Add STR argument.
+ * config/s390/s390.h (EXTRA_MEMORY_CONSTRAINT): Likewise.
+
+ * sh.h (OVERRIDE_OPTIONS): Allow first scheduling pass for SH5.
+
+2003-01-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*extzv_1_r_h8300): Correct the insn
+ length.
+ (*extzv_1_r_h8300hs): Likewise.
+ (*extzv_1_r_inv_h8300): Likewise.
+ (*extzv_1_r_inv_h8300hs): Likewise.
+
+2003-01-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (PREDICATE_CODES): New.
+
+2003-01-09 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*addsi3_upper): New.
+ (*iorsi3_shift): Likewise.
+ (two splitters): Likewise.
+ (*addsi3_shift): Likewise.
+ (two splitters): Likewise.
+
+2003-01-09 Josef Zlomek <zlomj9am@artax.karlin.mff.cuni.cz>
+
+ * Makefile.in (optabs.o): Add dependency on basic-block.h.
+ * basic-block.h (control_flow_insn_p): Fuction was exported.
+ * cfgbuild.c (control_flow_insn_p): Fuction was made non-static.
+ * optabs.c (emit_libcall_block): Emit REG_LIBCALL and REG_RETVAL
+ notes only when the region is contained in a single basic block.
+
+2003-01-09 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR inline-asm/8832
+ * tree.h (expand_asm): New prototype.
+ * stmt.c (expand_asm): Set the MEM_VOLATILE_P flag if instructed
+ to do so.
+ * c-semantics (genrtl_asm_stmt): Pass the RID_VOLATILE qualifier
+ down to expand_asm.
+ * c-typeck.c (simple_asm_stmt): Set the RID_VOLATILE qualifier.
+ * rtlanal.c (volatile_insn_p) [ASM_INPUT]: Test the MEM_VOLATILE_P flag.
+ (volatile_refs_p) [ASM_INPUT]: Likewise.
+ (side_effects_p) [ASM_INPUT]: Likewise.
+
+2003-01-09 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (*mul*): FIx constraints; remove confused comment; fix
+ athlon_decode attributes
+ (imul/k8 optimization peep2s): New.
+
+ * athlon.md (athlon_ssecmp*): Handle ssecomi as well.
+ * i386.md (type attribute): Add ssecomi.
+ (unit, memory, prefix attributes): Handle ssecomi.
+ (cvt?2? patterns): Fix athlon_decode attribute
+ (comi patterns): Set attribute to ssecomi.
+
+ PR target/8343
+ * m68k.md (umulsidi, mulsidi expanders): Use register operand.
+
+2003-01-09 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.h (PREDICATE_CODES): Add ADDRESSOF for predicates
+ that match register_operands.
+ * config/mips/mips.c (reg_or_0_operand, true_reg_or_0_operand): Make
+ register_operand the default case.
+
+2003-01-09 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR c/8032
+ * c-typeck.c (process_init_element) [RECORD_TYPE]: For
+ an empty element, do not advance the pointer to unfilled
+ fields if there are pending initializers.
+
+2003-01-09 Christian Cornelssen <ccorn@cs.tu-berlin.de>
+
+ * Makefile.in (ORDINARY_FLAGS_TO_PASS): Also pass DESTDIR.
+ (install-gcc-tooldir, install-cpp, installdirs,
+ install-common, install-driver, install-info, install-man,
+ install-headers, install-include-dir, install-headers-tar,
+ install-headers-cpio, install-headers-cp, install-mkheaders,
+ install-collect2, uninstall): Prepend $(DESTDIR) to
+ destination paths in all (un)installation commands.
+ (install-driver): Rewrite $(LN) commands to support DESTDIR
+ with "ln" as well as with "ln -s".
+ (installdirs): Simply use mkinstalldirs.
+ (install-libgcc, install-multilib): Also pass DESTDIR.
+ * mklibgcc.in: Prepend $(DESTDIR) to $(libsubdir) in the
+ installation destination variable ldir.
+ * config/alpha/t-osf4, config/arm/t-netbsd,
+ config/ia64/t-hpux, config/mips/t-iris5-6,
+ config/pa/t-hpux-shlib, config/rs6000/t-aix43,
+ config/rs6000/t-aix52, config/t-slibgcc-elf-ver,
+ config/t-slibgcc-sld: Prepend $$(DESTDIR) to $$(slibdir)
+ in the definition of SHLIB_INSTALL.
+ * config/arc/t-arc (install-multilib-arc): Prepend $(DESTDIR) to
+ $(libsubdir) in the installation commands.
+
+2003-01-08 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.h (CASE_VECTOR_MODE): Use SImode for a
+ non-optimizing compile.
+ (ASM_OUTPUT_ADDR_VEC_ELT): Use .long for a non-optimizing
+ compile.
+
+2003-01-08 Douglas B Rupp <rupp@gnat.com>
+
+ * config/i386/i386.c (ix86_attribute_table): Add new attributes
+ ms_struct and gcc_struct.
+ (ix86_handle_struct_attribute): New function.
+ (ix86_ms_bitfield_layout_p): Update to take new attributes
+ into account.
+ * doc/extend.texi: Document new attributes.
+ * testsuite/gcc.dg/bf-ms-attrib.c: New test.
+
+2003-01-08 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR optimization/8750
+ * config/i386/i386.c (ix86_expand_prologue): Don't allow
+ scheduling pass to move insns across __alloca call.
+
+2003-01-08 Dale Johannesen <dalej@apple.com>
+
+ * config/rs6000/rs6000.md: Replace *store_multiple_string
+ with *stmsi[3-8].
+
+2003-01-08 Jeff Sturm <jsturm@one-point.com>
+
+ PR target/9210
+ * config/rs6000/rs6000.c (rs6000_elf_encode_section_info):
+ Set SYMBOL_REF_FLAG on local data sym_ref.
+
+2003-01-08 Dale Johannesen <dalej@apple.com>
+
+ * function.c (assign_parms): Don't set pretend_args_size if
+ REG_PARM_STACK_SPACE.
+ config/rs6000/rs6000.c (setup_incoming_varargs): Don't set
+ pretend_args_size.
+
+2003-01-08 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * gcc.hlp: Delete.
+
+2003-01-09 Jan Hubicka <jh@suse.cz>
+
+ * i386.c (ix86_expand_int_addcc): Fix thinko.
+
+2003-01-08 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.h (FUNCTION_MODE): Always use SImode.
+ * config/rs6000/rs6000.c (TARGET_ASM_CAN_OUTPUT_MI_THUNK): Redefine
+ as hook_bool_tree_hwi_hwi_tree_true.
+ (rs6000_emit_allocate_stack): Use TARGET_32BIT.
+ (rs6000_emit_epilogue): Same.
+ (rs6000_output_mi_thunk): Re-implement as RTL.
+ * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Call
+ xcoffout_declare_function if any debugging enabled.
+
+2003-01-08 Chris Demetriou <cgd@broadcom.com>
+
+ * config.gcc (mipsisa32r2-*-elf*, mipsisa32r2el-*-elf*): New
+ targets, to support MIPS32 Release 2 (MIPS32R2) configurations.
+ * config/mips/mips.h (enum processor_type): Rename
+ PROCESSOR_R4KC to PROCESSOR_4KC, PROCESSOR_R5KC to
+ PROCESSOR_5KC, and PROCESSOR_R20KC to PROCESSOR_20KC.
+ Add PROCESSOR_M4K.
+ (TARGET_MIPS4KC, TARGET_MIPS5KC): Update for the renaming.
+ (ISA_MIPS32R2): New define.
+ (GENERATE_MULT3_SI, ISA_HAS_CONDMOVE, ISA_HAS_8CC)
+ (ISA_HAS_MADD_MSUB, ISA_HAS_CLZ_CLO)
+ (ISA_HAS_PREFETCH): Add support for MIPS32R2.
+ (MIPS_ISA_DEFAULT): Likewise. Also, fix indentation.
+ (TARGET_CPU_CPP_BUILTINS): Add support for MIPS32R2. Add new
+ predefine __mips_isa_rev for MIPS32, MIPS32R2, and MIPS64.
+ (ISA_HAS_ROTR_SI): Add support for MIPS32R2, and avoid if
+ compiling MIPS16 code.
+ (ISA_HAS_ROTR_DI): Do not use if compiling MIPS16 code, and fix
+ comment.
+ (ISA_HAS_SEB_SEH): New define.
+ (ASM_SPEC, LINK_SPEC): Pass -mips32r2 to assembler and linker.
+ * config/mips/mips.c (mips_cpu_info_table): Adjust for enum
+ processor_type value renaming. Add support for MIPS32R2.
+ Clean up comments, and move "sb1" entry with other MIPS64 CPU
+ entries.
+ (override_options): Reimplement -mipsN option handling so that
+ it will work correctly for -mips32r2. Avoid branch-likely
+ instructions on MIPS32R2.
+ * config/mips/mips.md (mulsi3_mult3): Add support for MIPS32R2.
+ (extendhisi2): Use extendhisi2_hw if ISA_HAS_SEB_SEH.
+ (extendqisi2): Use extendqisi2_hw if ISA_HAS_SEB_SEH.
+ (extendhisi2_hw, extendqisi2_hw): New.
+ * config/mips/netbsd.h (TARGET_CPU_CPP_BUILTINS): Add support
+ for MIPS32R2. Add new predefine __mips_isa_rev for MIPS32,
+ MIPS32R2, and MIPS64.
+ (LINK_SPEC): Pass -mips32r2 to linker.
+ * config/mips/t-isa3264: Built -mips32r2 multilibs.
+ * doc/invoke.texi (MIPS Options): Add -mips32r2, add support
+ for mips32r2 in the -march description. Alphabetically sort
+ CPU names in the -march description. Add long-missed -mips32
+ and -mips64 to MIPS option summary.
+
+ * config.gcc: Update copyright years to include 2003.
+ * config/mips/mips.c: Likewise.
+ * config/mips/mips.h: Likewise.
+ * config/mips/mips.md: Likewise.
+ * config/mips/netbsd.h: Likewise.
+ * doc/invoke.texi: Likewise.
+
+2003-01-08 Andreas Schwab <schwab@suse.de>
+
+ * aclocal.m4 (gcc_AC_INITFINI_ARRAY): Fix spelling of cache
+ variable.
+ * configure: Regenerated.
+
+2003-01-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (output_logical_op): Replace byte/word
+ extraction of det with b0, b1, w0, w2, etc.
+ (compute_logical_op_length): Likewise.
+ (compute_logical_op_cc): Likewise.
+
+2003-01-08 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.h (CONSTANT_ADDRESS_P): Allow CONST and
+ HIGH on all variants.
+
+2003-01-08 Josef Zlomek <zlomj9am@artax.karlin.mff.cuni.cz>
+
+ * Makefile.in (PARTITION_H): New.
+ (BASIC_BLOCK_H): Added hard-reg-set.h and $(PARTITION_H).
+ * basic-block.h: Include hard-reg-set.h.
+
+2003-01-08 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.h (ENABLE_XF_PATTERNS): Delete.
+ * arm.md (addxf3, subxf3, mulxf3, divxf3, modxf3, negxf2, absxf2)
+ (sqrtxf2, floatsixf2, fix_truncxfsi2, truncxfsf2, truncxfdf2)
+ (extendsfxf2, extenddfxf2, movxf, cmpxf, cmpxf_insn)
+ (cmpxf_trap): Delete.
+ (movxf_hard_insn): Remove test of ENABLE_XF_PATTERNS.
+
+2003-01-08 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (adddi3_carry_rex64, subdi3_carry_rex64): Name pattern.
+ (addhi3_carry, addqi3_carry, subhi3_carry, subqi3_carry): New patterns.
+ (add??cc): New expanders.
+ * i386.c (expand_int_addcc): New function.
+ * i386-protos.h (expand_int_addcc): Declare.
+
+ * alias.c (memory_modified_1): New static function.
+ (memory_modified): New static varaible.
+ (memory_modified_in_insn_p): New global function.
+ * rtl.h (memory_modified_in_insn_p): Declare.
+ * rtlanal.c (modified_between_p, modified_in_p): Be smart about memory
+ references.
+
+ * expr.h (emit_conditional_add): Declare.
+
+2003-01-07 Janis Johnson <janis187@us.ibm.com>
+
+ PR other/8947
+ * doc/invoke.texi (-malign-double): Explain that the option breaks
+ binary compatibility.
+
+2003-01-08 Andreas Schwab <schwab@suse.de>
+
+ * config.gcc (m68k-*-linux*): Don't set extra_parts and gnu_ld,
+ should come from the generic *-*-linux* entry.
+
+2003-01-07 Jan Hubicka <jh@suse.cz>
+
+ * cselib.c (cselib_current_insn_in_libcall): New static variable.
+ (new_elt_loc_list, cselib_process_insn, cselib_init): Keep track on whether
+ we are inside libcall.
+ * cselib.h (elt_loc_list): Add in_libcall.
+ * gcse.c (do_local_cprop): Do not copy propagate using insns
+ in libcalls.
+
+2003-01-07 David Edelsohn <edelsohn@gnu.org>
+
+ * doc/tm.texi (TARGET_SCHED_VARIABLE_ISSUE): CLOBBER and USE do
+ not normally affect to issue rate.
+
+2003-01-07 Jan Hubicka <jh@suse.cz>
+
+ * genopinit.c (optabs): Add addc_optab.
+ * ifcvt.c (noce_try_store_flag): Rename to ...
+ (noce_try_addcc): ... this one; handle generic conditional increment.
+ (noce_process_if_block): Update noce_try_addcc call.
+ * optabs.c (emit_conditional_add): New.
+ (init_obtabs): Initialize addc_optab.
+ * optabs.h (optab_index): Add OTI_addcc.
+ (addcc_optab): New macro.
+ * md.texi: Document addMcc
+
+ PR target/8322
+ * i386.c (ix86_init_mmx_sse_builtins): Constify arguments of loads.
+ * xmmintrin.h (_mm_load*_si128. _mm_store*_si128): Add casts.
+ * xmmintrin.h (_mm_load*_si128. _mm_store*_si128): Add casts.
+
+ * reload1.c (delete_output_reload): Avoid repeated attempts
+ to delete insn.
+
+2003-01-07 Andreas Schwab <schwab@suse.de>
+
+ * configure.in: Restore CFLAGS before gcc_AC_INITFINI_ARRAY.
+ Move --enable-initfini-array check ...
+ * aclocal.m4 (gcc_AC_INITFINI_ARRAY): ... here. Define
+ HAVE_INITFINI_ARRAY also when --enable-initfini-array is given.
+ Don't AC_SUBST gcc_cv_initfinit_array. Use AC_TRY_RUN.
+ * configure: Rebuild.
+
+2003-01-07 Richard Henderson <rth@redhat.com>
+
+ * alias.c (find_base_value): Only use new_reg_base_value shortcut
+ if the register is set once.
+
+2003-01-07 Sylvain Pion <Sylvain.Pion@mpi-sb.mpg.de>
+
+ * config/i386/i386.c (ix86_init_mmx_sse_builtins):
+ __builtin_ia32_ldmxcsr and __builtin_ia32_stmxcsr are SSE, not MXX.
+ * config/i386/i386.md (ldmxcsr, stmxcsr): SSE, not MMX.
+
+2003-01-07 Benjamin Kosnik <bkoz@redhat.com>
+ Sunil Davasam <sunil.k.davasam@intel.com>
+
+ PR libstdc++/9076
+ * unwind-dw2.c (execute_cfa_program): DW_CFA_undefined,
+ DW_CFA_same_value, read next and ignore.
+
+2003-01-07 Richard Henderson <rth@redhat.com>
+
+ * cfganal.c (flow_call_edges_add): Don't crash on noreturn call.
+
+2003-01-07 Daniel Berlin <dberlin@dberlin.org>
+
+ * cfg.c: Include alloc-pool.h
+ (edge_pool): New pool.
+ (bb_pool): New pool.
+ (first_deleted_edge): Remove.
+ (first_deleted_block): Remove.
+ (init_flow): Alloc/free the pools.
+ (free_edge): Use pools.
+ (alloc_block): Ditto.
+ (expunge_block): Ditto.
+ (cached_make_edge): Ditto.
+
+ * Makefile.in (cfg.o): Add alloc-pool.h dependency.
+
+2003-01-07 Daniel Berlin <dberlin@dberlin.org>
+
+ * et-forest.c: Include alloc-pool.h.
+ (struct et_forest): Add node_pool and occur_pool.
+ (et_forest_create): Create the new pools.
+ (et_forest_delete): Delete them.
+ (et_forest_add_node): Allocate and free using pools.
+ (et_forest_add_edge): Ditto.
+ (et_forest_remove_node): Ditto.
+ (et_forest_remove_edge): Ditto.
+
+ * Makefile.in (et-forest.o): Add alloc-pool.h dependency.
+
+2003-01-07 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (output_logical_op): Simplify and
+ optimize the handling of SImode.
+ * config/h8300/h8300.c (compute_logical_op_length): Update
+ accordingly.
+ * config/h8300/h8300.c (compute_logical_op_cc): Likewise.
+
+2003-01-07 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.c (mips_va_arg): In the EABI code, apply the
+ big-endian correction to indirect arguments too.
+
+2003-01-06 Aldy Hernandez <aldyh@redhat.com>
+
+ Segher Boessenkool <segher@koffie.nl>
+
+ * config/rs6000/rs6000.c (rs6000_reg_names): Add missing registers.
+ (alt_reg_names): Ditto, fix formatting.
+ * config/rs6000/rs6000.h (DEBUG_REGISTER_NAMES): Fix formatting.
+
+2003-01-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (final_prescan_insn): Constify uid.
+ (output_logical_op): Constify intval and det.
+ (compute_logical_length): Likewise.
+ (compute_logical_cc): Likewise.
+ (output_a_shift): Constify mask.
+ (h8300_encode_label): Constify len.
+
+2003-01-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (h8300_expand_prologue): Remove fsize.
+ (h8300_expand_epilogue): Likewise.
+
+2003-01-06 Aldy Hernandez <aldyh@redhat.com>
+
+ Segher Boessenkool <segher@koffie.nl>
+
+ * config/rs6000/altivec.md: Remove spaces from assembler
+ instruction argument lists.
+
+2003-01-07 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_naked_function_p): Rename from
+ c4x_assembler_function_p.
+ (c4x_null_epilogue_p): Complement return value, all uses updated.
+ (c4x_insert_attributes): Add naked.
+ * config/c4x/c4x.md (c4x_null_epilogue_p): Changes uses.
+ * doc/extend.texi: Update C4x function attributes.
+
+2003-01-06 Richard Henderson <rth@redhat.com>
+
+ * config/alpha/alpha.c (alpha_encode_section_info): Adjust symbol_str
+ properly when changing "local-ness".
+ * config/alpha/alpha.md (movdi_er_high_g): Allow all symbols.
+
+2003-01-06 Dale Johannesen <dalej@apple.com>
+
+ * config/darwin-protos.h: Add prototypes for new section functions.
+
+2003-01-06 Chris Demetriou <cgd@broadcom.com>
+
+ * config.gcc (mipsisa32-*-elf*, mipsisa32el-*-elf*): Default ABI
+ to EABI.
+
+2003-01-06 Zack Weinberg <zack@codesourcery.com>
+
+ * hwint.h: If the current compiler has no 64-bit type at all,
+ make HOST_WIDEST_INT 32 bits.
+
+2003-01-06 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.md (movdf_internal2): Fix constraints.
+
+2003-01-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*twoshifts_l16_r1): New.
+
+2003-01-06 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md (leadi): Use dla rather than la.
+
+2003-01-06 Svein E. Seldal <Svein.Seldal@solidas.com>
+
+ * config/c4x/c4x.h: Updated specs for new gas format. Fixed bug
+ in C33_FLAG. Added proper C33 support in ASM_FILE_START macro.
+
+2003-01-06 Herman A.J. ten Brugge <hermantenbrugge@home.nl>
+
+ * config/c4x/c4x.h: Remove hwint.h include and HOST_WIDE_INT_PRINT_HEX
+ redefinition.
+
+2003-01-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*extzv_8_23): New.
+
+2003-01-05 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * pa64-hpux.h (JCR_SECTION_NAME): Define.
+ (PA_INIT_FRAME_DUMMY_ASM_OP): Check EH_FRAME_SECTION_NAME instead of
+ USE_EH_FRAME_REGISTRY when defining.
+
+2003-01-05 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (output_a_shift): Do not output a
+ variable shift.
+ * config/h8300/h8300.md (two splitters): New.
+
+2003-01-05 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips.md: Disable the movstrsi define_split.
+
+2003-01-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * alloc-pool.c: Don't include "libiberty.h".
+ * config/sparc/gmon-sol2.c: Include <fcntl.h>.
+ * convert.c (convert_to_real): Hide unused variable.
+
+2003-01-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (gtyp-gen.h): Const-ify.
+ * gcov-dump.c (tag_table): Likewise.
+
+2003-01-04 Bruce Korb <bkorb@gnu.org>
+
+ * fixinc/fixfixes.c(wrap_fix): the wrapper guard must be a function
+ of *both* the file name and the fix name.
+
+2003-01-04 John David Anglin <dave.anglin@nrc.ca>
+
+ * config.gcc (hppa*64*-*-hpux11*): Define extra_parts. Don't use
+ collect2.
+ * pa-hpux11.h (LDD_SUFFIX, PARSE_LDD_OUTPUT): Undefine.
+ (HAS_INIT_SECTION, LD_INIT_SWITCH, LD_FINI_SWITCH): Define.
+ * pa64-hpux.h (HP_INIT_ARRAY_SECTION_ASM_OP,
+ GNU_INIT_ARRAY_SECTION_ASM_OP, HP_FINI_ARRAY_SECTION_ASM_OP,
+ GNU_FINI_ARRAY_SECTION_ASM_OP): Define.
+ (CTORS_SECTION_ASM_OP, DTORS_SECTION_ASM_OP): Define when not using
+ elfos.h.
+ (EH_FRAME_IN_DATA_SECTION): Delete define.
+ (HAS_INIT_SECTION, LD_INIT_SWITCH, LD_FINI_SWITCH): Undefine.
+ (STARTFILE_SPEC): Use crtbegin.o.
+ (ENDFILE_SPEC): Use crtend.o.
+ (INIT_SECTION_ASM_OP, FINI_SECTION_ASM_OP, CRT_CALL_STATIC_FUNCTION,
+ SUPPORTS_INIT_PRIORITY, PA_CXA_FINALIZE_STUB, PA_INIT_FINI_HACK,
+ PA_INIT_FRAME_DUMMY_ASM_OP, PA_JV_REGISTERCLASSES_STUB,
+ DTOR_LIST_BEGIN): Define.
+ * pa.c (TARGET_ASM_CONSTRUCTOR): Define.
+ (pa_asm_out_constructor, pa_asm_out_destructor): New functions.
+ * som.h (SUPPORTS_INIT_PRIORITY): Delete define.
+
+2002-12-31 Larin Hennessy <larin@science.oregonstate.edu>
+
+ * fixinc/fixinc.svr4: Remove references to i860, Sony NewsOS, and spur.
+ * fixinc/inclhack.def: Remove tests for Apple A/UX, ARM/RISCiX, DG/UX,
+ m88k-*-sysv3*, Sony NewsOS. Remove references to i860.
+ Cleanup handling of replacement text.
+ * fixinc/mkfixinc.sh: Remove reference to i?86-*-osf1*
+
+2003-01-04 Bruce Korb <bkorb@gnu.org>
+
+ * fixinc/tests/base/math.h: removed obsolete results
+ * fixinc/tests/base/stdlib.h: ditto
+ * fixinc/tests/base/sys/param.h: ditto
+ * fixinc/tests/base/sys/stat.h: ditto
+ * fixinc/tests/base/time.h: ditto
+ * fixinc/tests/base/X11/Intrinsic.h: removed obsolete file
+ * fixinc/tests/base/sys/byteorder.h: ditto
+ * fixinc/inclhack.def: Remove superfluous backslashes
+
+2003-01-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add prototypes for
+ the new functions defined below.
+ * config/h8300/h8300.c (TARGET_ASM_FUNCTION_PROLOGUE): Do not
+ define.
+ (dosize): Emit RTL instead of assembly code.
+ (push): Likewise.
+ (pop): Likewise.
+ (h8300_output_function_prologue): Remove.
+ (h8300_expand_prologue): New.
+ (h8300_expand_epilogue): New.
+ (h8300_output_function_epilogue): Do only the reset of
+ pragma_saveall.
+ * config/h8300/h8300.md (push_h8300): New.
+ (push_h8300hs): Likewise.
+ (pop_h8300): Likewise.
+ (pop_h8300hs): Likewise.
+ (*stm_h8300s_2): Change the name to stm_h8300s_2.
+ (*stm_h8300s_3): Change the name to stm_h8300s_3.
+ (*stm_h8300s_4): Change the name to stm_h8300s_4.
+ (*ldm_h8300s_2): New.
+ (*ldm_h8300s_3): Likewise.
+ (*ldm_h8300s_4): Likewise.
+ (return): Likewise.
+ (*return_1): Likewise.
+ (prologue): Likewise.
+ (epilogue): Likewise.
+ (monitor_prologue): Likewise.
+
+2003-01-03 Dale Johannesen <dalej@apple.com>
+
+ * config/darwin.h: (EXTRA_SECTIONS): Add machopic_symbol_stub1,
+ machopic_picsymbol_stub1.
+ (EXTRA_SECTION_FUNCTIONS): Ditto.
+ * rs6000/rs6000.c: Update copyright.
+ (machopic_output_stub): Use them. Remove an insn from stub code.
+
+2003-01-02 Jason Merrill <jason@redhat.com>
+
+ * fold-const.c (fold) [COND_EXPR]: Avoid NOP_EXPRs better.
+
+ * integrate.c (copy_decl_for_inlining): Don't clear the rtl for
+ static/external decls.
+
+ * c-common.c (finish_fname_decls): Put the DECL_STMTs inside the
+ outermost scope.
+ * c-decl.c (c_make_fname_decl): Push the decls there, too.
+
+2003-01-03 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300-protos.h: Add a prototype for
+ h8300_current_function_interrupt_function_p.
+ * config/h8300/h8300.c (interrupt_handler): Remove.
+ (os_task): Likewise.
+ (monitor): Likewise.
+ (pragma_interrupt): New.
+ (WORD_REG_USED): Use
+ h8300_current_function_interrupt_function_p.
+ (dosize): Likewise.
+ (h8300_output_function_prologue): Likewise.
+ Do not set interrupt_handler, os_task, monitor.
+ (h8300_output_function_prologue): Use
+ h8300_current_function_interrupt_function_p.
+ Do not set interrupt_handler, os_task, monitor.
+ (h8300_current_function_interrupt_function_p): New.
+ (h8300_pr_interrupt): Set pragma_interrupt.
+ (h8300_insert_attributes): Reset pragma_interrupt.
+
+2003-01-03 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * doc/install.texi (Configuration): Fix markup for reference to
+ gcc/config.gcc.
+
+2003-01-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md (*iorhi3_zext): Relax the condition.
+ (*iorhi3_two_qi): Likewise.
+ (*iorsi3_zexthi): Likewise.
+ (*xorhi3_zextqi): Likewise.
+ (*xorsi3_zexthi): Likewise.
+ (*xorsi3_zextqi): Likewise.
+
+2003-01-02 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (stack_pointer_operand): New.
+ (const_int_gt_2_operand): Likewise.
+ (const_int_ge_8_operand): Likewise.
+ * config/h8300/h8300.md (a splitter): Likewise.
+ (a peephole2): Likewise.
+ * config/h8300/h8300-protos.h: Add prototypes for the new
+ functions above.
+
+2003-01-02 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * objc/Make-lang.in, objc/config-lang.in, objc/lang-specs.h,
+ objc/objc-act.h: Fix copyright years.
+
+2003-01-02 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * doc/passes.texi: Fix documentation for -fssa-ccp
+
+2003-01-02 Neil Booth <neil@daikokuya.co.uk>
+
+ * gccbug.in: Update for new categories.
+
+2003-01-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.md: Reorder some patterns.
+
+2003-01-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c (output_logical_op): Fix a warning.
+
+2003-01-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/darwin-protos.h, config/c4x/c4x-protos.h,
+ config/cris/cris-protos.h, config/i370/i370-protos.h,
+ config/i960/i960-protos.h, config/ia64/ia64-protos.h,
+ config/v850/v850-protos.h: Use struct, and don't conditionally
+ compile on GCC_C_PRAGMA_H.
+
+2003-01-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arm/arm-protos.h: Remove #ifdef GCC_C_PRAGMA_H.
+ * config/h8300/h8300-protos.h: Likewise.
+ * config/sh/sh-protos.h: Likewise.
+
+2003-01-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/arm/arm-protos.h: Use struct cpp_reader instead of
+ cpp_reader.
+ * config/h8300/h8300-protos.h: Likewise.
+ * config/sh/sh-protos.h: Likewise.
+
+2003-01-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * config/arm/arm.c (arm_pr_long_calls, arm_pr_no_long_calls,
+ arm_pr_long_calls_off): Use struct.
+ * config/h8300/h8300.c (h8300_pr-interrupt, h8300_pr_saveall)
+ : Similarly.
+ Don't include cpplib.h.
+ * config/sh/sh.c (sh_pr_interrupt, sh_pr_trapa,
+ sh_pr_nosave_low_regs): Similarly.
+
+2003-01-01 Kazu Hirata <kazu@cs.umass.edu>
+
+ * config/h8300/h8300.c: Include cpplib.h.
+
+2003-01-01 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * objc/Make-lang.in, objc/config-lang.in, objc/lang-options.h,
+ objc/lang-specs.h, objc/objc-act.c, objc/objc-act.h,
+ objc/objc-lang.c, objc/objc-tree.def: Replace "GNU CC" with
+ "GCC" in the copyright header.
+
+2003-01-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * c-pragma.c (c_register_pragma): New.
+ (init_pragma): Use it.
+ * c-pragma.h (cpp_register_pragma): Don't declare.
+ (c_register_pragma): New.
+ * cpplib.h: Remove #ifdef GCC_C_PRAGMA_H.
+ * config/darwin.h (REGISTER_TARGET_PRAGMAS): Update.
+ * config/arm/arm.h (REGISTER_TARGET_PRAGMAS): Update.
+ * config/c4x/c4x.h (REGISTER_TARGET_PRAGMAS): Update.
+ * config/h8300/h8300.h (REGISTER_TARGET_PRAGMAS): Update.
+ * config/i370/i370.h (REGISTER_TARGET_PRAGMAS): Update.
+ * config/i960/i960.h (REGISTER_TARGET_PRAGMAS): Update.
+ * config/ia64/hpux.h (REGISTER_TARGET_PRAGMAS): Update.
+ * config/rs6000/rs6000.h (REGISTER_TARGET_PRAGMAS): Update.
+ * config/sh/sh.h (REGISTER_TARGET_PRAGMAS): Update.
+ * config/v850/v850.h (REGISTER_TARGET_PRAGMAS): Update.
+ * doc/tm.texi (REGISTER_TARGET_PRAGMAS): Update
+
+See ChangeLog.8 for earlier changes.
diff --git a/contrib/gcc/Makefile.in b/contrib/gcc/Makefile.in
index 67076d30c76a..d0ec7688e672 100644
--- a/contrib/gcc/Makefile.in
+++ b/contrib/gcc/Makefile.in
@@ -1,6 +1,8 @@
-# Makefile for GNU C compiler.
-# Copyright (C) 1987, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
-# 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+# Makefile for GNU Compiler Collection
+# Run 'configure' to generate Makefile from Makefile.in
+
+# Copyright (C) 1987, 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+# 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
#This file is part of GCC.
@@ -25,32 +27,103 @@
# stage1, stage2, stage3, stage4.
# This is the default target.
-all:
+# Set by autoconf to "all.internal" for a native build, or
+# "all.cross" to build a cross compiler.
+all: @ALL@
-# Suppress smart makes who think they know how to automake Yacc files
+# Depend on this to specify a phony target portably.
+force:
+
+# This tells GNU make version 3 not to export the variables
+# defined in this file into the environment (and thus recursive makes).
+.NOEXPORT:
+# And this tells it not to automatically pass command-line variables
+# to recursive makes.
+MAKEOVERRIDES =
+
+# Suppress smart makes who think they know how to automake yacc and flex file
.y.c:
+.l.c:
+
+# The only suffixes we want for implicit rules are .c and .o, so clear
+# the list and add them. This speeds up GNU Make, and allows -r to work.
+# For i18n support, we also need .gmo, .po, .pox.
+# This must come before the language makefile fragments to allow them to
+# add suffixes and rules of their own.
+.SUFFIXES:
+.SUFFIXES: .c .o .po .pox .gmo
+
+# -------------------------------
+# Standard autoconf-set variables
+# -------------------------------
+
+build=@build@
+host=@host@
+target=@target@
+target_noncanonical:=@target_noncanonical@
+
+# Sed command to transform gcc to installed name.
+program_transform_name := @program_transform_name@
+
+# -----------------------------
+# Directories used during build
+# -----------------------------
# Directory where sources are, from where we are.
srcdir = @srcdir@
+docdir = @srcdir@/doc
+
+# Directory where sources are, absolute.
+abs_srcdir = @abs_srcdir@
+abs_docdir = @abs_srcdir@/doc
+
+# Top build directory, relative to here.
+top_builddir = ..
+# objdir is set by configure.
+# It's normally the absolute path to the current directory.
+objdir = @objdir@
+
+# --------
+# Defined vpaths
+# --------
+
+# Directory where sources are, from where we are.
VPATH = @srcdir@
-# Pointer to the GCC Project website
-website=http://gcc.gnu.org
+# We define a vpath for the sources of the .texi files here because they
+# are split between multiple directories and we would rather use one implicit
+# pattern rule for everything.
+# This vpath could be extended within the Make-lang fragments.
+
+vpath %.texi $(docdir):$(docdir)/include
+
+# ----
+# Default values for variables overridden in Makefile fragments.
+# These need to be quite early in the Makefile so as to avoid
+# trouble induced by changes in fragment ordering.
+# ----
+
+# For ada/Make-lang.in; overridden in, for example, config/pa/x-ada.
+X_ADA_CFLAGS =
+T_ADA_CFLAGS =
+X_ADAFLAGS =
+T_ADAFLAGS =
+
+# --------
+# UNSORTED
+# --------
# Variables that exist for you to override.
# See below for how to change them for certain systems.
# List of language subdirectories.
-# This is overridden by configure.
SUBDIRS =@subdirs@
# Selection of languages to be made.
-# This is overridden by configure.
CONFIG_LANGUAGES = @all_languages@
-LANGUAGES = c gcov$(exeext) $(CONFIG_LANGUAGES)
+LANGUAGES = c gcov$(exeext) gcov-dump$(exeext) $(CONFIG_LANGUAGES)
# Selection of languages to be made during stage1 build.
-# This is overridden by configure.
BOOT_LANGUAGES = c @all_boot_languages@
# Various ways of specifying flags for compilations:
@@ -71,10 +144,9 @@ BOOT_CFLAGS = -g -O2
# Flags to determine code coverage. When coverage is disabled, this will
# contain the optimization flags, as you normally want code coverage
-# without optimization. The -dumpbase $@ makes sure that the auxilary
-# files end up near the object files.
+# without optimization.
COVERAGE_FLAGS = @coverage_flags@
-coverageexts = .{da,bb,bbg}
+coverageexts = .{gcda,gcno}
# The warning flags are separate from BOOT_CFLAGS because people tend to
# override optimization flags and we'd like them to still have warnings
@@ -89,26 +161,43 @@ coverageexts = .{da,bb,bbg}
# with other compilers. This is partially controlled by configure in
# stage1, as not all versions of gcc understand -Wno-long-long.
LOOSE_WARN = -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes
-STRICT_WARN = -Wtraditional @strict1_warn@
-STRICT2_WARN = -Wtraditional -pedantic -Wno-long-long
+STRICT_WARN = @strict1_warn@
+STRICT2_WARN = -pedantic -Wno-long-long -Wold-style-definition @WERROR@
# This is set by --enable-checking. The idea is to catch forgotten
# "extern" tags in header files.
NOCOMMON_FLAG = @nocommon_flag@
+# This is set by --disable-maintainer-mode (default) to "#"
+MAINT := @MAINT@
+
# These are set by --enable-checking=valgrind.
RUN_GEN = @valgrind_command@
VALGRIND_DRIVER_DEFINES = @valgrind_path_defines@
# This is how we control whether or not the additional warnings are applied.
.-warn = $(STRICT_WARN)
-GCC_WARN_CFLAGS = $(LOOSE_WARN) $($(@D)-warn) $(NOCOMMON_FLAG)
+GCC_WARN_CFLAGS = $(LOOSE_WARN) $($(@D)-warn) $(NOCOMMON_FLAG) $($@-warn)
+
+# These files are to have -Werror bypassed in stage2:
+# These are very hard to completely clean due to target complexities.
+gcc.o-warn = -Wno-error
+insn-conditions.o-warn = -Wno-error
+# Bison-1.75 output often yields (harmless) -Wtraditional warnings
+gengtype-yacc.o-warn = -Wno-error
+c-parse.o-warn = -Wno-error
+# flex output may yield harmless "no previous prototype" warnings
+gengtype-lex.o-warn = -Wno-error
+# SYSCALLS.c misses prototypes
+SYSCALLS.c.X-warn = -Wno-strict-prototypes -Wno-error
# All warnings have to be shut off in stage1 if the compiler used then
# isn't gcc; configure determines that. WARN_CFLAGS will be either
# $(GCC_WARN_CFLAGS), or nothing.
WARN_CFLAGS = @warn_cflags@
+CPPFLAGS = @CPPFLAGS@
+
# These exists to be overridden by the x-* and t-* files, respectively.
X_CFLAGS =
T_CFLAGS =
@@ -116,7 +205,6 @@ T_CFLAGS =
X_CPPFLAGS =
T_CPPFLAGS =
-ADAC = @ADAC@
AWK = @AWK@
CC = @CC@
BISON = @BISON@
@@ -125,8 +213,12 @@ FLEX = @FLEX@
FLEXFLAGS =
AR = ar
AR_FLAGS = rc
-DLLTOOL = dlltool
RANLIB = @RANLIB@
+
+# -------------------------------------------
+# Programs which operate on the build machine
+# -------------------------------------------
+
SHELL = @SHELL@
# pwd command to use. Allow user to override default by setting PWDCMD in
# the environment to account for automounters. The make variable must not
@@ -146,22 +238,27 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL@
MAKEINFO = @MAKEINFO@
-MAKEINFOFLAGS =
+MAKEINFOFLAGS = --no-split
TEXI2DVI = texi2dvi
TEXI2POD = perl $(srcdir)/../contrib/texi2pod.pl
POD2MAN = pod2man --center="GNU" --release="gcc-$(version)"
-# For GNUmake: let us decide what gets passed to recursive makes.
-MAKEOVERRIDES =
-@SET_MAKE@
-# Some compilers can't handle cc -c blah.c -o foo/blah.o.
-# In stage2 and beyond, we force this to "-o $@" since we know we're using gcc.
-OUTPUT_OPTION = @OUTPUT_OPTION@
-
# Some versions of `touch' (such as the version on Solaris 2.8)
# do not correctly set the timestamp due to buggy versions of `utime'
# in the kernel. So, we use `echo' instead.
STAMP = echo timestamp >
+# Make sure the $(MAKE) variable is defined.
+@SET_MAKE@
+REMAKEFLAGS=LANGUAGES="$(LANGUAGES)" BOOT_CFLAGS="$(BOOT_CFLAGS)"
+
+# --------
+# UNSORTED
+# --------
+
+# Some compilers can't handle cc -c blah.c -o foo/blah.o.
+# In stage2 and beyond, we force this to "-o $@" since we know we're using gcc.
+OUTPUT_OPTION = @OUTPUT_OPTION@
+
# This is where we get zlib from. zlibdir is -L../zlib and zlibinc is
# -I../zlib, unless we were configured with --with-system-zlib, in which
# case both are empty.
@@ -189,37 +286,25 @@ USER_H = $(srcdir)/ginclude/float.h \
# The GCC to use for compiling libgcc.a and crt*.o.
# Usually the one we just built.
# Don't use this as a dependency--use $(GCC_PASSES) or $(GCC_PARTS).
-GCC_FOR_TARGET = $(STAGE_CC_WRAPPER) ./xgcc -B./ -B$(build_tooldir)/bin/ -isystem $(build_tooldir)/include -isystem $(build_tooldir)/sys-include
+GCC_FOR_TARGET = $(STAGE_CC_WRAPPER) ./xgcc -B./ -B$(build_tooldir)/bin/ -isystem $(build_tooldir)/include -isystem $(build_tooldir)/sys-include -L$(objdir)/../ld
# This is used instead of ALL_CFLAGS when compiling with GCC_FOR_TARGET.
# It omits XCFLAGS, and specifies -B./.
# It also specifies -isystem ./include to find, e.g., stddef.h.
-GCC_CFLAGS=$(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(LOOSE_WARN) -isystem ./include $(TCFLAGS)
+GCC_CFLAGS=$(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(LOOSE_WARN) -Wold-style-definition $($@-warn) -isystem ./include $(TCFLAGS)
-# Sed command to transform gcc to installed name. Overwritten by configure.
-program_transform_name = @program_transform_name@
-program_transform_cross_name = s,^,$(target_alias)-,
-
-build_canonical = @build_canonical@
-host_canonical = @host_canonical@
-
-# Tools to use when building a cross-compiler.
-# These are used because `configure' appends `cross-make'
-# to the makefile when making a cross-compiler.
-
-# Use the tools from the build tree, if they are available.
-
-# objdir is set by configure.
-objdir = @objdir@
+# ---------------------------------------------------
+# Programs which produce files for the target machine
+# ---------------------------------------------------
AR_FOR_TARGET = ` \
if [ -f $(objdir)/../binutils/ar ] ; then \
echo $(objdir)/../binutils/ar ; \
else \
- if [ "$(host_canonical)" = "$(target)" ] ; then \
+ if [ "$(host)" = "$(target)" ] ; then \
echo ar; \
else \
- t='$(program_transform_cross_name)'; echo ar | sed -e $$t ; \
+ t='$(program_transform_name)'; echo ar | sed -e $$t ; \
fi; \
fi`
AR_FLAGS_FOR_TARGET =
@@ -229,29 +314,29 @@ RANLIB_FOR_TARGET = ` \
if [ -f $(objdir)/../binutils/ranlib ] ; then \
echo $(objdir)/../binutils/ranlib ; \
else \
- if [ "$(host_canonical)" = "$(target)" ] ; then \
- echo ranlib; \
+ if [ "$(host)" = "$(target)" ] ; then \
+ echo $(RANLIB); \
else \
- t='$(program_transform_cross_name)'; echo ranlib | sed -e $$t ; \
+ t='$(program_transform_name)'; echo ranlib | sed -e $$t ; \
fi; \
fi`
-RANLIB_TEST_FOR_TARGET = \
- [ -f $(RANLIB_FOR_TARGET) ] \
- || ( [ "$(host_canonical)" = "$(target)" ] \
- && [ -f /usr/bin/ranlib -o -f /bin/ranlib ] )
NM_FOR_TARGET = ` \
if [ -f ./nm ] ; then \
echo ./nm ; \
elif [ -f $(objdir)/../binutils/nm-new ] ; then \
echo $(objdir)/../binutils/nm-new ; \
else \
- if [ "$(host_canonical)" = "$(target)" ] ; then \
+ if [ "$(host)" = "$(target)" ] ; then \
echo nm; \
else \
- t='$(program_transform_cross_name)'; echo nm | sed -e $$t ; \
+ t='$(program_transform_name)'; echo nm | sed -e $$t ; \
fi; \
fi`
+# --------
+# UNSORTED
+# --------
+
# Where to find some libiberty headers.
HASHTAB_H = $(srcdir)/../include/hashtab.h
OBSTACK_H = $(srcdir)/../include/obstack.h
@@ -262,7 +347,7 @@ PARTITION_H = $(srcdir)/../include/partition.h
# Default native SYSTEM_HEADER_DIR, to be overridden by targets.
NATIVE_SYSTEM_HEADER_DIR = /usr/include
# Default cross SYSTEM_HEADER_DIR, to be overridden by targets.
-CROSS_SYSTEM_HEADER_DIR = $(build_tooldir)/sys-include
+CROSS_SYSTEM_HEADER_DIR = @CROSS_SYSTEM_HEADER_DIR@
# autoconf sets SYSTEM_HEADER_DIR to one of the above.
SYSTEM_HEADER_DIR = @SYSTEM_HEADER_DIR@
@@ -274,37 +359,49 @@ STMP_FIXINC = @STMP_FIXINC@
# Test to see whether <limits.h> exists in the system header files.
LIMITS_H_TEST = [ -f $(SYSTEM_HEADER_DIR)/limits.h ]
-target=@target@
-target_alias=@target_alias@
-xmake_file=@dep_host_xmake_file@
-tmake_file=@dep_tmake_file@
+# Directory for prefix to system directories, for
+# each of $(system_prefix)/usr/include, $(system_prefix)/usr/lib, etc.
+TARGET_SYSTEM_ROOT = @TARGET_SYSTEM_ROOT@
+
+xmake_file=@xmake_file@
+tmake_file=@tmake_file@
out_file=$(srcdir)/config/@out_file@
out_object_file=@out_object_file@
md_file=$(srcdir)/config/@md_file@
+tm_file_list=@tm_file_list@
+tm_include_list=@tm_include_list@
tm_defines=@tm_defines@
tm_p_file_list=@tm_p_file_list@
-tm_p_file=@tm_p_file@
+tm_p_include_list=@tm_p_include_list@
build_xm_file_list=@build_xm_file_list@
-build_xm_file=@build_xm_file@
+build_xm_include_list=@build_xm_include_list@
build_xm_defines=@build_xm_defines@
host_xm_file_list=@host_xm_file_list@
-host_xm_file=@host_xm_file@
+host_xm_include_list=@host_xm_include_list@
host_xm_defines=@host_xm_defines@
-xm_file=@xm_file@
+xm_file_list=@xm_file_list@
+xm_include_list=@xm_include_list@
xm_defines=@xm_defines@
+lang_checks=check-gcc
+lang_opt_files=@lang_opt_files@ $(srcdir)/c.opt $(srcdir)/common.opt
lang_specs_files=@lang_specs_files@
-lang_options_files=@lang_options_files@
lang_tree_files=@lang_tree_files@
target_cpu_default=@target_cpu_default@
GCC_THREAD_FILE=@thread_file@
OBJC_BOEHM_GC=@objc_boehm_gc@
GTHREAD_FLAGS=@gthread_flags@
+extra_modes_file=@extra_modes_file@
+host_hook_obj=@out_host_hook_obj@
# Be prepared for gcc2 merges.
gcc_version=@gcc_version@
gcc_version_trigger=@gcc_version_trigger@
version=$(gcc_version)
mainversion=`grep version_string $(srcdir)/version.c | sed -e 's/.*\"\([0-9]*\.[0-9]*\).*/\1/'`
+# ------------------------
+# Installation directories
+# ------------------------
+
# Common prefix for installation directories.
# NOTE: This directory must exist when you start installation.
prefix = @prefix@
@@ -319,8 +416,17 @@ exec_prefix = @exec_prefix@
bindir = @bindir@
# Directory in which to put the directories used by the compiler.
libdir = @libdir@
-# Directory in which the compiler finds executables, libraries, etc.
-libsubdir = $(libdir)/gcc-lib/$(target_alias)/$(version)
+# Directory in which GCC puts its executables.
+libexecdir = @libexecdir@
+
+# --------
+# UNSORTED
+# --------
+
+# Directory in which the compiler finds libraries etc.
+libsubdir = $(libdir)/gcc/$(target_noncanonical)/$(version)
+# Directory in which the compiler finds executables
+libexecsubdir = $(libexecdir)/gcc/$(target_noncanonical)/$(version)
# Used to produce a relative $(gcc_tooldir) in gcc.o
unlibsubdir = ../../..
# Directory in which to find other cross-compilation tools and headers.
@@ -330,7 +436,7 @@ gcc_tooldir = @gcc_tooldir@
# Used to install the shared libgcc.
slibdir = @slibdir@
# Since gcc_tooldir does not exist at build-time, use -B$(build_tooldir)/bin/
-build_tooldir = $(exec_prefix)/$(target_alias)
+build_tooldir = $(exec_prefix)/$(target_noncanonical)
# Directory in which the compiler finds target-independent g++ includes.
gcc_gxx_include_dir = @gcc_gxx_include_dir@
# Directory to search for site-specific includes.
@@ -357,21 +463,16 @@ man7dir = $(mandir)/man7
# Dir for temp files.
tmpdir = /tmp
-# Top build directory, relative to here.
-top_builddir = .
-
# Whether we were configured with NLS.
USE_NLS = @USE_NLS@
# Internationalization library.
-INTLLIBS = @INTLLIBS@
-INTLDEPS = @INTLDEPS@
+LIBINTL = @LIBINTL@
+LIBINTL_DEP = @LIBINTL_DEP@
# Character encoding conversion library.
LIBICONV = @LIBICONV@
-
-# List of internationalization subdirectories.
-INTL_SUBDIRS = intl
+LIBICONV_DEP = @LIBICONV_DEP@
# The GC method to be used on this system.
GGC=@GGC@.o
@@ -399,11 +500,11 @@ 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 \
- -fno-zero-initialized-in-bss
+ -fno-zero-initialized-in-bss -fno-unit-at-a-time
# Additional sources to handle exceptions; overridden by targets as needed.
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \
- $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
+ $(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c
LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h
# nm flags to list global symbols in libgcc object files.
@@ -427,10 +528,9 @@ EXTRA_OBJS = @extra_objs@
# List of extra object files that should be compiled and linked with
# the gcc driver.
-EXTRA_GCC_OBJS =@host_extra_gcc_objs@
+EXTRA_GCC_OBJS =@extra_gcc_objs@
# List of additional header files to install.
-# Often this is edited directly by `configure'.
EXTRA_HEADERS =@extra_headers_list@
# It is convenient for configure to add the assignment at the beginning,
@@ -466,7 +566,6 @@ GENERATED_MANPAGES = @GENERATED_MANPAGES@
OTHER_FIXINCLUDES_DIRS=
# A list of all the language-specific executables.
-# This is overridden by configure.
COMPILERS = cc1$(exeext) @all_compilers@
# List of things which should already be built whenever we try to use xgcc
@@ -490,31 +589,21 @@ BUILD_PREFIX = @BUILD_PREFIX@
# out of the way of the other rules for compiling the same source files.
BUILD_PREFIX_1 = @BUILD_PREFIX_1@
# Native compiler for the build machine and its switches.
-HOST_CC = @HOST_CC@
-HOST_CFLAGS= @HOST_CFLAGS@ -DGENERATOR_FILE
+CC_FOR_BUILD = @CC_FOR_BUILD@
+BUILD_CFLAGS= @BUILD_CFLAGS@ -DGENERATOR_FILE
# Native linker and preprocessor flags. For x-fragment overrides.
-HOST_LDFLAGS=$(LDFLAGS)
-HOST_CPPFLAGS=$(ALL_CPPFLAGS)
+BUILD_LDFLAGS=$(LDFLAGS)
+BUILD_CPPFLAGS=$(ALL_CPPFLAGS)
# Actual name to use when installing a native compiler.
-GCC_INSTALL_NAME = `echo gcc|sed '$(program_transform_name)'`
-GCC_TARGET_INSTALL_NAME = $(target_alias)-`echo gcc|sed '$(program_transform_name)'`
-CPP_INSTALL_NAME = `echo cpp|sed '$(program_transform_name)'`
-PROTOIZE_INSTALL_NAME = `echo protoize|sed '$(program_transform_name)'`
-UNPROTOIZE_INSTALL_NAME = `echo unprotoize|sed '$(program_transform_name)'`
-GCOV_INSTALL_NAME = `echo gcov|sed '$(program_transform_name)'`
-GCCBUG_INSTALL_NAME = `echo gccbug|sed '$(program_transform_name)'`
-
-# Actual name to use when installing a cross-compiler.
-GCC_CROSS_NAME = `echo gcc|sed '$(program_transform_cross_name)'`
-CPP_CROSS_NAME = `echo cpp|sed '$(program_transform_cross_name)'`
-PROTOIZE_CROSS_NAME = `echo protoize|sed '$(program_transform_cross_name)'`
-UNPROTOIZE_CROSS_NAME = `echo unprotoize|sed '$(program_transform_cross_name)'`
-
-# Set by autoconf to "all.internal" for a native build, or
-# "all.cross" to build a cross compiler.
-ALL = @ALL@
+GCC_INSTALL_NAME := $(shell echo gcc|sed '$(program_transform_name)')
+GCC_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gcc|sed '$(program_transform_name)')
+CPP_INSTALL_NAME := $(shell echo cpp|sed '$(program_transform_name)')
+PROTOIZE_INSTALL_NAME := $(shell echo protoize|sed '$(program_transform_name)')
+UNPROTOIZE_INSTALL_NAME := $(shell echo unprotoize|sed '$(program_transform_name)')
+GCOV_INSTALL_NAME := $(shell echo gcov|sed '$(program_transform_name)')
+GCCBUG_INSTALL_NAME := $(shell echo gccbug|sed '$(program_transform_name)')
# Setup the testing framework, if you have one
EXPECT = `if [ -f $${rootme}/../expect/expect ] ; then \
@@ -543,38 +632,38 @@ T =
T_TARGET =
T_TARGET : $(T_TARGET)
-# End of variables for you to override.
-
-# Definition of `all' is here so that new rules inserted by sed
-# do not specify the default target.
-# The real definition is under `all.internal' (for native compilers)
-# or `all.cross' (for cross compilers).
-all: all.indirect
+# This should name the specs file that we're going to install. Target
+# Makefiles may override it and name another file to be generated from
+# the built-in specs and installed as the default spec, as long as
+# they also introduce a rule to generate a file name specs, to be used
+# at build time.
+SPECS = specs
-# This tells GNU Make version 3 not to put all variables in the environment.
-.NOEXPORT:
+# End of variables for you to override.
-# GCONFIG_H lists the config files that the generator files depend on, while
-# CONFIG_H lists the ones ordinary gcc files depend on, which includes
-# several files generated by those generators.
-GCONFIG_H = config.h $(host_xm_file_list)
-HCONFIG_H = hconfig.h $(build_xm_file_list)
-CONFIG_H = $(GCONFIG_H) insn-constants.h insn-flags.h
+# GTM_H lists the config files that the generator files depend on,
+# while TM_H lists the ones ordinary gcc files depend on, which
+# includes several files generated by those generators.
+BCONFIG_H = bconfig.h $(build_xm_file_list)
+CONFIG_H = config.h $(host_xm_file_list)
TCONFIG_H = tconfig.h $(xm_file_list)
-TARGET_H = target.h
+TM_P_H = tm_p.h $(tm_p_file_list)
+GTM_H = tm.h $(tm_file_list)
+TM_H = $(GTM_H) insn-constants.h insn-flags.h
+
+TARGET_H = $(TM_H) target.h
HOOKS_H = hooks.h
LANGHOOKS_DEF_H = langhooks-def.h $(HOOKS_H)
TARGET_DEF_H = target-def.h $(HOOKS_H)
-TM_P_H = tm_p.h $(tm_p_file_list) tm-preds.h
-
-MACHMODE_H = machmode.h machmode.def @extra_modes_file@
+MACHMODE_H = machmode.h mode-classes.def insn-modes.h
RTL_BASE_H = rtl.h rtl.def $(MACHMODE_H)
-RTL_H = $(RTL_BASE_H) genrtl.h
+RTL_H = $(RTL_BASE_H) genrtl.h input.h
PARAMS_H = params.h params.def
TREE_H = tree.h tree.def $(MACHMODE_H) tree-check.h version.h builtins.def \
- location.h
+ input.h
BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h varray.h $(PARTITION_H) \
- hard-reg-set.h
+ hard-reg-set.h cfghooks.h
+COVERAGE_H = coverage.h gcov-io.h gcov-iov.h
DEMANGLE_H = $(srcdir)/../include/demangle.h
RECOG_H = recog.h
EXPR_H = expr.h
@@ -583,7 +672,7 @@ REGS_H = regs.h varray.h $(MACHMODE_H)
INTEGRATE_H = integrate.h varray.h
LOOP_H = loop.h varray.h bitmap.h
GCC_H = gcc.h version.h
-GGC_H = ggc.h varray.h gtype-desc.h
+GGC_H = ggc.h gtype-desc.h
TIMEVAR_H = timevar.h timevar.def
INSN_ATTR_H = insn-attr.h $(srcdir)/insn-addr.h $(srcdir)/varray.h
C_COMMON_H = c-common.h $(SPLAY_TREE_H) $(CPPLIB_H)
@@ -591,26 +680,20 @@ C_TREE_H = c-tree.h $(C_COMMON_H)
SYSTEM_H = system.h hwint.h $(srcdir)/../include/libiberty.h
PREDICT_H = predict.h predict.def
CPPLIB_H = cpplib.h line-map.h
+PRETTY_PRINT_H = pretty-print.h input.h $(OBSTACK_H)
+DIAGNOSTIC_H = diagnostic.h diagnostic.def $(PRETTY_PRINT_H)
+C_PRETTY_PRINT_H = $(PRETTY_PRINT_H) $(C_COMMON_H) $(TREE_H)
-# sed inserts variable overrides after the following line.
-####target overrides
-@target_overrides@
-
-####host overrides
-@host_overrides@
#
# Now figure out from those variables how to compile and link.
-all.indirect: $(ALL)
-
# IN_GCC distinguishes between code compiled into GCC itself and other
# programs built during a bootstrap.
# autoconf inserts -DCROSS_COMPILE if we are building a cross compiler.
INTERNAL_CFLAGS = -DIN_GCC @CROSS@
-# This is the variable actually used when we compile.
-# If you change this line, you probably also need to change the definition
-# of HOST_CFLAGS in build-make to match.
+# This is the variable actually used when we compile. If you change this,
+# you probably want to update BUILD_CFLAGS in configure.ac
ALL_CFLAGS = $(X_CFLAGS) $(T_CFLAGS) \
$(CFLAGS) $(INTERNAL_CFLAGS) $(COVERAGE_FLAGS) $(WARN_CFLAGS) $(XCFLAGS) @DEFS@
@@ -623,15 +706,15 @@ LIBIBERTY = ../libiberty/libiberty.a
BUILD_LIBIBERTY = @FORBUILD@/libiberty/libiberty.a
# Dependencies on the intl and portability libraries.
-LIBDEPS= $(INTLDEPS) $(LIBIBERTY)
+LIBDEPS= $(LIBIBERTY) $(LIBINTL_DEP) $(LIBICONV_DEP)
# Likewise, for use in the tools that must run on this machine
# even if we are cross-building GCC.
-HOST_LIBDEPS= $(BUILD_LIBIBERTY)
+BUILD_LIBDEPS= $(BUILD_LIBIBERTY)
# How to link with both our special library facilities
# and the system's installed libraries.
-LIBS = $(INTLLIBS) @LIBS@ $(LIBIBERTY)
+LIBS = @LIBS@ $(LIBIBERTY) $(LIBINTL) $(LIBICONV)
# Any system libraries needed just for GNAT.
SYSLIBS = @GNAT_LIBEXC@
@@ -641,16 +724,16 @@ LDEXP_LIB = @LDEXP_LIB@
# Likewise, for use in the tools that must run on this machine
# even if we are cross-building GCC.
-HOST_LIBS = $(BUILD_LIBIBERTY)
+BUILD_LIBS = $(BUILD_LIBIBERTY)
-HOST_RTL = $(BUILD_PREFIX)rtl.o read-rtl.o $(BUILD_PREFIX)bitmap.o \
- $(BUILD_PREFIX)ggc-none.o
-HOST_SUPPORT = gensupport.o insn-conditions.o
-HOST_EARLY_SUPPORT = gensupport.o dummy-conditions.o
+BUILD_RTL = $(BUILD_PREFIX)rtl.o read-rtl.o $(BUILD_PREFIX)bitmap.o \
+ $(BUILD_PREFIX)ggc-none.o min-insn-modes.o
+BUILD_SUPPORT = gensupport.o insn-conditions.o
+BUILD_EARLY_SUPPORT = gensupport.o dummy-conditions.o
-HOST_PRINT = print-rtl1.o
-HOST_ERRORS = $(BUILD_PREFIX)errors.o
-HOST_VARRAY = $(BUILD_PREFIX)varray.o
+BUILD_PRINT = print-rtl1.o
+BUILD_ERRORS = $(BUILD_PREFIX)errors.o
+BUILD_VARRAY = $(BUILD_PREFIX)varray.o
# Specify the directories to be searched for header files.
# Both . and srcdir are used, in that order,
@@ -658,21 +741,18 @@ HOST_VARRAY = $(BUILD_PREFIX)varray.o
# subdirectory rather than in the source directory.
# -I$(@D) and -I$(srcdir)/$(@D) cause the subdirectory of the file
# currently being compiled, in both source trees, to be examined as well.
+# libintl.h will be found in ../intl if we are using the included libintl.
INCLUDES = -I. -I$(@D) -I$(srcdir) -I$(srcdir)/$(@D) \
- -I$(srcdir)/config -I$(srcdir)/../include
+ -I$(srcdir)/../include @INCINTL@
-# Always use -I$(srcdir)/config when compiling.
.c.o:
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-# This tells GNU make version 3 not to export all the variables
-# defined in this file into the environment.
-.NOEXPORT:
#
-# Support for additional languages (other than c and objc).
-# ??? objc can be supported this way too (leave for later).
+# Support for additional languages (other than C).
+# C can be supported this way too (leave for later).
-# These next lines are overridden by configure.
+LANG_MAKEFRAGS = @all_lang_makefrags@
LANG_MAKEFILES = @all_lang_makefiles@
LANG_STAGESTUFF = @all_stagestuff@
@@ -681,17 +761,30 @@ LANG_STAGESTUFF = @all_stagestuff@
# because we need CC="stage1/xgcc -Bstage1/" to work in the language
# subdirectories.
# ??? The choices here will need some experimenting with.
+
+export AR_FOR_TARGET
+export AR_CREATE_FOR_TARGET
+export AR_FLAGS_FOR_TARGET
+export AR_EXTRACT_FOR_TARGET
+export AWK
+export BUILD_PREFIX
+export BUILD_PREFIX_1
+export DESTDIR
+export GCC_FOR_TARGET
+export INCLUDES
+export INSTALL_DATA
+export LIB1ASMSRC
+export LIBGCC2_CFLAGS
+export MACHMODE_H
+export NM_FOR_TARGET
+export RANLIB_FOR_TARGET
+export libsubdir
+export slibdir
+
ORDINARY_FLAGS_TO_PASS = \
- "AR=$(AR)" \
- "AR_FLAGS_FOR_TARGET=$(AR_FLAGS_FOR_TARGET)" \
- "AR_CREATE_FOR_TARGET=$(AR_CREATE_FOR_TARGET)" \
- "AR_EXTRACT_FOR_TARGET=$(AR_EXTRACT_FOR_TARGET)" \
- "AR_FOR_TARGET=$(AR_FOR_TARGET)" \
"BISON=$(BISON)" \
"BISONFLAGS=$(BISONFLAGS)" \
"CFLAGS=$(CFLAGS) $(WARN_CFLAGS)" \
- "DESTDIR=$(DESTDIR)" \
- "GCC_FOR_TARGET=$(GCC_FOR_TARGET)" \
"LDFLAGS=$(LDFLAGS)" \
"FLEX=$(FLEX)" \
"FLEXFLAGS=$(FLEXFLAGS)" \
@@ -700,8 +793,6 @@ ORDINARY_FLAGS_TO_PASS = \
"MAKEINFO=$(MAKEINFO)" \
"MAKEINFOFLAGS=$(MAKEINFOFLAGS)" \
"MAKEOVERRIDES=" \
- "RANLIB_FOR_TARGET=$(RANLIB_FOR_TARGET)" \
- "RANLIB_TEST_FOR_TARGET=$(RANLIB_TEST_FOR_TARGET)" \
"SHELL=$(SHELL)" \
"exeext=$(exeext)" \
"build_exeext=$(build_exeext)" \
@@ -713,7 +804,7 @@ ORDINARY_FLAGS_TO_PASS = \
"build_tooldir=$(build_tooldir)" \
"gcc_tooldir=$(gcc_tooldir)" \
"bindir=$(bindir)" \
- "libsubdir=$(libsubdir)" \
+ "libexecsubdir=$(libsubdir)" \
"datadir=$(datadir)" \
"localedir=$(localedir)"
FLAGS_TO_PASS = $(ORDINARY_FLAGS_TO_PASS) "CC=@cc_set_by_configure@" \
@@ -739,32 +830,44 @@ CXX_TARGET_OBJS=@cxx_target_objs@
# Language-specific object files for C and Objective C.
C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
- c-objc-common.o c-dump.o libcpp.a $(C_TARGET_OBJS)
+ c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
+ c-objc-common.o c-dump.o c-pch.o libcpp.a $(C_TARGET_OBJS)
# Language-specific object files for C.
-C_OBJS = c-parse.o c-lang.o c-pretty-print.o $(C_AND_OBJC_OBJS)
+C_OBJS = c-parse.o c-lang.o c-pretty-print.o stub-objc.o $(C_AND_OBJC_OBJS)
# Language-independent object files.
-OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o \
+OBJS-common = \
+ alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o \
cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o \
- cfgrtl.o combine.o conflict.o convert.o cse.o cselib.o dbxout.o \
- debug.o df.o diagnostic.o doloop.o dominance.o \
- dwarf2asm.o dwarf2out.o dwarfout.o emit-rtl.o except.o explow.o \
+ cfgloopanal.o cfgloopmanip.o loop-init.o loop-unswitch.o loop-unroll.o \
+ cfgrtl.o combine.o conflict.o convert.o coverage.o cse.o cselib.o \
+ dbxout.o debug.o df.o diagnostic.o dojump.o doloop.o dominance.o \
+ dwarf2asm.o dwarf2out.o emit-rtl.o except.o explow.o \
expmed.o expr.o final.o flow.o fold-const.o function.o gcse.o \
genrtl.o ggc-common.o global.o graph.o gtype-desc.o \
- haifa-sched.o hashtable.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o \
+ haifa-sched.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o insn-modes.o \
insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o \
- integrate.o intl.o jump.o langhooks.o lcm.o lists.o local-alloc.o \
- loop.o mbchar.o optabs.o params.o predict.o print-rtl.o print-tree.o \
+ integrate.o intl.o jump.o langhooks.o lcm.o lists.o local-alloc.o \
+ loop.o optabs.o options.o opts.o params.o postreload.o predict.o \
+ print-rtl.o print-tree.o value-prof.o \
profile.o ra.o ra-build.o ra-colorize.o ra-debug.o ra-rewrite.o \
real.o recog.o reg-stack.o regclass.o regmove.o regrename.o \
reload.o reload1.o reorg.o resource.o rtl.o rtlanal.o rtl-error.o \
sbitmap.o sched-deps.o sched-ebb.o sched-rgn.o sched-vis.o sdbout.o \
- sibcall.o simplify-rtx.o ssa.o ssa-ccp.o ssa-dce.o stmt.o \
- stor-layout.o stringpool.o timevar.o toplev.o tracer.o tree.o tree-dump.o \
- tree-inline.o unroll.o varasm.o varray.o version.o vmsdbgout.o xcoffout.o \
- et-forest.o $(GGC) $(out_object_file) $(EXTRA_OBJS)
+ sibcall.o simplify-rtx.o sreal.o stmt.o stor-layout.o stringpool.o \
+ targhooks.o timevar.o toplev.o tracer.o tree.o tree-dump.o unroll.o \
+ varasm.o varray.o version.o vmsdbgout.o xcoffout.o alloc-pool.o \
+ et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) web.o
+
+OBJS-md = $(out_object_file)
+OBJS-archive = $(EXTRA_OBJS) $(host_hook_obj) hashtable.o tree-inline.o \
+ tree-optimize.o cgraph.o cgraphunit.o
+
+OBJS = $(OBJS-common) $(out_object_file) $(OBJS-archive)
+
+OBJS-onestep = libbackend.o $(OBJS-archive)
BACKEND = main.o libbackend.a
@@ -772,8 +875,8 @@ BACKEND = main.o libbackend.a
STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
insn-attr.h insn-attrtab.c insn-opinit.c insn-constants.h tm-preds.h \
- tree-check.h insn-conditions.c \
- s-flags s-config s-codes s-mlib s-genrtl s-gtype gtyp-gen.h \
+ tree-check.h insn-conditions.c min-insn-modes.c insn-modes.c insn-modes.h \
+ s-flags s-config s-codes s-mlib s-genrtl s-modes s-gtype gtyp-gen.h \
s-output s-recog s-emit s-extract s-peep s-check s-conditions \
s-attr s-attrtab s-opinit s-preds s-constants s-crt0 \
genemit$(build_exeext) genoutput$(build_exeext) genrecog$(build_exeext) \
@@ -781,27 +884,21 @@ STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
genconfig$(build_exeext) genpeep$(build_exeext) genattrtab$(build_exeext) \
genattr$(build_exeext) genopinit$(build_exeext) gengenrtl$(build_exeext) \
gencheck$(build_exeext) genpreds$(build_exeext) genconstants$(build_exeext) \
- gengtype$(build_exeext) genconditions$(build_exeext) \
+ gengtype$(build_exeext) genconditions$(build_exeext) genmodes$(build_exeext) \
genrtl.c genrtl.h gt-*.h gtype-*.h gtype-desc.c \
xgcc$(exeext) cpp$(exeext) cc1$(exeext) $(EXTRA_PASSES) \
- $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) cc1obj$(exeext) \
+ $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) \
protoize$(exeext) unprotoize$(exeext) \
- specs collect2$(exeext) $(USE_COLLECT2) \
- gcov$(exeext) *.[0-9][0-9].* *.[si] libcpp.a libbackend.a libgcc.mk \
+ $(SPECS) collect2$(exeext) $(USE_COLLECT2) \
+ gcov-iov$(build_exeext) gcov$(exeext) gcov-dump$(exeext) \
+ *.[0-9][0-9].* *.[si] libcpp.a libbackend.a libgcc.mk \
$(LANG_STAGESTUFF)
-# Library members defined in libgcc2.c.
-# Variable length limited to 255 charactes when passed to a shell script.
-LIB2FUNCS_1 = _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 _ffsdi2 _clz \
- _cmpdi2 _ucmpdi2 _floatdidf _floatdisf _fixunsdfsi _fixunssfsi \
- _fixunsdfdi _fixdfdi _fixunssfdi _fixsfdi _fixxfdi _fixunsxfdi
-
-LIB2FUNCS_2 = _floatdixf _fixunsxfsi _fixtfdi _fixunstfdi _floatditf \
- _clear_cache _trampoline __main _exit _absvsi2 _absvdi2 _addvsi3 \
- _addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 _negvsi2 _negvdi2 _ctors
-
# Defined in libgcc2.c, included only in the static library.
-LIB2FUNCS_ST = _eprintf _bb __gcc_bcmp
+LIB2FUNCS_ST = _eprintf __gcc_bcmp
+
+# Defined in libgcov.c, included only in gcov library
+LIBGCOV = _gcov _gcov_merge_add _gcov_merge_single _gcov_merge_delta
FPBIT_FUNCS = _pack_sf _unpack_sf _addsub_sf _mul_sf _div_sf \
_fpcmp_parts_sf _compare_sf _eq_sf _ne_sf _gt_sf _ge_sf \
@@ -822,82 +919,92 @@ TPBIT_FUNCS = _pack_tf _unpack_tf _addsub_tf _mul_tf _div_tf \
# unwinder info.
LIB2_DIVMOD_FUNCS = _divdi3 _moddi3 _udivdi3 _umoddi3 _udiv_w_sdiv _udivmoddi4
-# The only suffixes we want for implicit rules are .c and .o, so clear
-# the list and add them. This speeds up GNU Make, and allows -r to work.
-# For i18n support, we also need .gmo, .po, .pox.
-# This must come before the language makefile fragments to allow them to
-# add suffixes and rules of their own.
-.SUFFIXES:
-.SUFFIXES: .c .o .po .pox .gmo
-
#
# Language makefile fragments.
# The following targets define the interface between us and the languages.
#
# all.cross, start.encap, rest.encap,
-# info, dvi,
# install-normal, install-common, install-info, install-man,
# uninstall,
-# mostlyclean, clean, distclean, extraclean, maintainer-clean,
+# mostlyclean, clean, distclean, maintainer-clean,
# stage1, stage2, stage3, stage4
#
-# Each language is linked in with a series of hooks (since we can't use `::'
-# targets). The name of each hooked is "lang.${target_name}" (eg: lang.info).
-# Configure computes and adds these here.
+# Each language is linked in with a series of hooks. The name of each
+# hooked is "lang.${target_name}" (eg: lang.info). Configure computes
+# and adds these here. We use double-colon rules for some of the hooks;
+# double-colon rules should be preferred for any new hooks.
-####language hooks
+# language hooks, generated by configure
@language_hooks@
-# sed inserts language fragments after the following line.
-####language fragments
-@language_fragments@
+# per-language makefile fragments
+ifneq ($(LANG_MAKEFRAGS),)
+include $(LANG_MAKEFRAGS)
+endif
+
+# target and host overrides must follow the per-language makefile fragments
+# so they can override or augment language-specific variables
+
+# target overrides
+ifneq ($(tmake_file),)
+include $(tmake_file)
+endif
+
+# host overrides
+ifneq ($(xmake_file),)
+include $(xmake_file)
+endif
-# End of language makefile fragments.
#
-Makefile: $(srcdir)/Makefile.in config.status $(srcdir)/version.c \
- $(xmake_file) $(tmake_file) $(LANG_MAKEFILES)
- $(SHELL) $(srcdir)/configure.frag $(srcdir) "$(SUBDIRS)" \
- "$(xmake_file)" "$(tmake_file)"
- cp config.status config.run
- LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.run
- rm -f config.run
+# -----------------------------
+# Rebuilding this configuration
+# -----------------------------
+
+Makefile: config.status $(srcdir)/Makefile.in $(srcdir)/version.c $(LANG_MAKEFRAGS)
+ LANGUAGES="$(CONFIG_LANGUAGES)" \
+ CONFIG_HEADERS= \
+ CONFIG_SHELL="$(SHELL)" \
+ CONFIG_FILES=$@ $(SHELL) config.status
config.h: cs-config.h ; @true
-hconfig.h: cs-hconfig.h ; @true
+bconfig.h: cs-bconfig.h ; @true
tconfig.h: cs-tconfig.h ; @true
+tm.h: cs-tm.h ; @true
tm_p.h: cs-tm_p.h ; @true
cs-config.h: Makefile
- TM_DEFINES="$(tm_defines)" \
- HEADERS="$(host_xm_file)" XM_DEFINES="$(host_xm_defines)" \
- TARGET_CPU_DEFAULT="$(target_cpu_default)" \
+ TARGET_CPU_DEFAULT="" \
+ HEADERS="$(host_xm_include_list)" DEFINES="$(host_xm_defines)" \
$(SHELL) $(srcdir)/mkconfig.sh config.h
-cs-hconfig.h: Makefile
- TM_DEFINES="$(tm_defines)" \
- HEADERS="$(build_xm_file)" XM_DEFINES="$(build_xm_defines)" \
- TARGET_CPU_DEFAULT="$(target_cpu_default)" \
- $(SHELL) $(srcdir)/mkconfig.sh hconfig.h
+cs-bconfig.h: Makefile
+ TARGET_CPU_DEFAULT="" \
+ HEADERS="$(build_xm_include_list)" DEFINES="$(build_xm_defines)" \
+ $(SHELL) $(srcdir)/mkconfig.sh bconfig.h
cs-tconfig.h: Makefile
- TM_DEFINES="$(tm_defines)" \
- HEADERS="$(xm_file)" XM_DEFINES="$(xm_defines)" \
TARGET_CPU_DEFAULT="" \
+ HEADERS="$(xm_include_list)" DEFINES="$(xm_defines)" \
$(SHELL) $(srcdir)/mkconfig.sh tconfig.h
+cs-tm.h: Makefile
+ TARGET_CPU_DEFAULT="$(target_cpu_default)" \
+ HEADERS="$(tm_include_list)" DEFINES="$(tm_defines)" \
+ $(SHELL) $(srcdir)/mkconfig.sh tm.h
+
cs-tm_p.h: Makefile
- TM_DEFINES="" \
- HEADERS="$(tm_p_file)" XM_DEFINES="" TARGET_CPU_DEFAULT="" \
+ TARGET_CPU_DEFAULT="" \
+ HEADERS="$(tm_p_include_list)" DEFINES="" \
$(SHELL) $(srcdir)/mkconfig.sh tm_p.h
-# Don't automatically run autoconf, since configure.in might be accidentally
+# Don't automatically run autoconf, since configure.ac might be accidentally
# newer than configure. Also, this writes into the source directory which
# might be on a read-only file system. If configured for maintainer mode
# then do allow autoconf to be run.
-$(srcdir)/configure: @MAINT@ $(srcdir)/configure.in
+$(srcdir)/configure: @MAINT@ $(srcdir)/configure.ac
(cd $(srcdir) && autoconf)
gccbug: $(srcdir)/gccbug.in
@@ -922,13 +1029,15 @@ mkheaders: $(srcdir)/mkheaders.in
# Don't run autoheader automatically either.
# Only run it if maintainer mode is enabled.
@MAINT@ $(srcdir)/config.in: $(srcdir)/cstamp-h.in
-@MAINT@ $(srcdir)/cstamp-h.in: $(srcdir)/configure.in $(srcdir)/acconfig.h
+@MAINT@ $(srcdir)/cstamp-h.in: $(srcdir)/configure.ac
@MAINT@ (cd $(srcdir) && autoheader)
@MAINT@ @rm -f $(srcdir)/cstamp-h.in
@MAINT@ echo timestamp > $(srcdir)/cstamp-h.in
auto-host.h: cstamp-h ; @true
cstamp-h: config.in config.status
- CONFIG_HEADERS=auto-host.h:config.in LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status
+ CONFIG_HEADERS=auto-host.h:config.in \
+ CONFIG_FILES= \
+ LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status
# Really, really stupid make features, such as SUN's KEEP_STATE, may force
# a target to build even if it is up-to-date. So we must verify that
@@ -941,18 +1050,22 @@ config.status: $(srcdir)/configure $(srcdir)/config.gcc version.c
LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status --recheck; \
fi
+# --------
+# UNSORTED
+# --------
+
all.internal: start.encap rest.encap doc
# This is what to compile if making a cross-compiler.
all.cross: native gcc-cross cpp$(exeext) specs \
$(LIBGCC) $(EXTRA_PARTS) lang.all.cross doc
# This is what must be made before installing GCC and converting libraries.
start.encap: native xgcc$(exeext) cpp$(exeext) specs \
- xlimits.h lang.start.encap
+ xlimits.h lang.start.encap @GENINSRC@ srcextra
# These can't be made until after GCC can run.
rest.encap: $(STMP_FIXPROTO) $(LIBGCC) $(EXTRA_PARTS) lang.rest.encap
# This is what is made with the host's compiler
# whether making a cross compiler or not.
-native: config.status auto-host.h intl.all build-@POSUB@ $(LANGUAGES) \
+native: config.status auto-host.h build-@POSUB@ $(LANGUAGES) \
$(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(USE_COLLECT2)
# Define the names for selecting languages in LANGUAGES.
@@ -971,9 +1084,9 @@ rest.cross: $(LIBGCC) specs
compilations: $(BACKEND)
# Like libcpp.a, this archive is strictly for the host.
-libbackend.a: $(OBJS)
+libbackend.a: $(OBJS@onestep@)
-rm -rf libbackend.a
- $(AR) $(AR_FLAGS) libbackend.a $(OBJS)
+ $(AR) $(AR_FLAGS) libbackend.a $(OBJS@onestep@)
-$(RANLIB) libbackend.a
# We call this executable `xgcc' rather than `gcc'
@@ -993,9 +1106,9 @@ cpp$(exeext): gcc.o cppspec.o version.o intl.o prefix.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)
+$(SPECS): xgcc$(exeext)
$(GCC_FOR_TARGET) -dumpspecs > tmp-specs
- mv tmp-specs specs
+ mv tmp-specs $(SPECS)
# We do want to create an executable named `xgcc', so we can use it to
# compile libgcc2.a.
@@ -1024,9 +1137,8 @@ LIB2ADD_ST = $(LIB2FUNCS_STATIC_EXTRA)
libgcc.mk: config.status Makefile mklibgcc $(LIB2ADD) $(LIB2ADD_ST) xgcc$(exeext) specs
objext='$(objext)' \
LIB1ASMFUNCS='$(LIB1ASMFUNCS)' \
- LIB2FUNCS_1='$(LIB2FUNCS_1)' \
- LIB2FUNCS_2='$(LIB2FUNCS_2)' \
LIB2FUNCS_ST='$(LIB2FUNCS_ST)' \
+ LIBGCOV='$(LIBGCOV)' \
LIB2ADD='$(LIB2ADD)' \
LIB2ADD_ST='$(LIB2ADD_ST)' \
LIB2ADDEH='$(LIB2ADDEH)' \
@@ -1055,26 +1167,20 @@ libgcc.mk: config.status Makefile mklibgcc $(LIB2ADD) $(LIB2ADD_ST) xgcc$(exeext
# All the things that might cause us to want to recompile bits of libgcc.
LIBGCC_DEPS = $(GCC_PASSES) $(LANGUAGES) stmp-int-hdrs $(STMP_FIXPROTO) \
- libgcc.mk $(srcdir)/libgcc2.c $(TCONFIG_H) \
+ libgcc.mk $(srcdir)/libgcc2.c $(srcdir)/libgcov.c $(TCONFIG_H) \
$(MACHMODE_H) longlong.h gbl-ctors.h config.status stmp-int-hdrs \
tsystem.h $(FPBIT) $(DPBIT) $(TPBIT) $(LIB2ADD) \
$(LIB2ADD_ST) $(LIB2ADDEH) $(LIB2ADDEHDEP) $(EXTRA_PARTS) \
- $(srcdir)/config/$(LIB1ASMSRC)
+ $(srcdir)/config/$(LIB1ASMSRC) \
+ $(srcdir)/gcov-io.h $(srcdir)/gcov-io.c gcov-iov.h
+
+libgcov.a: libgcc.a; @true
libgcc.a: $(LIBGCC_DEPS)
- $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
- BUILD_PREFIX="$(BUILD_PREFIX)" BUILD_PREFIX_1="$(BUILD_PREFIX_1)" \
- AR_FOR_TARGET="$(AR_FOR_TARGET)" \
- AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
- AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
+ $(MAKE) \
CFLAGS="$(CFLAGS) $(WARN_CFLAGS)" \
- RANLIB_FOR_TARGET="$(RANLIB_FOR_TARGET)" \
- RANLIB_TEST_FOR_TARGET="$(RANLIB_TEST_FOR_TARGET)" \
- NM_FOR_TARGET="$(NM_FOR_TARGET)" AWK="$(AWK)" \
- LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" \
+ CONFIG_H="$(TCONFIG_H)" TM_H="$(TM_H)" \
INCLUDES="$(INCLUDES)" \
- CONFIG_H="$(TCONFIG_H)" MACHMODE_H="$(MACHMODE_H)" \
- LIB1ASMSRC='$(LIB1ASMSRC)' \
MAKEOVERRIDES= \
-f libgcc.mk all
@@ -1104,19 +1210,9 @@ s-mlib: $(srcdir)/genmultilib Makefile
# Build multiple copies of libgcc.a, one for each target switch.
stmp-multilib: $(LIBGCC_DEPS)
- $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
- BUILD_PREFIX="$(BUILD_PREFIX)" BUILD_PREFIX_1="$(BUILD_PREFIX_1)" \
- AR_FOR_TARGET="$(AR_FOR_TARGET)" \
- AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
- AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
+ $(MAKE) \
CFLAGS="$(CFLAGS) $(WARN_CFLAGS)" \
- RANLIB_FOR_TARGET="$(RANLIB_FOR_TARGET)" \
- RANLIB_TEST_FOR_TARGET="$(RANLIB_TEST_FOR_TARGET)" \
- NM_FOR_TARGET="$(NM_FOR_TARGET)" AWK="$(AWK)" \
- LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" \
- INCLUDES="$(INCLUDES)" \
- CONFIG_H="$(CONFIG_H)" MACHMODE_H="$(MACHMODE_H)" \
- LIB1ASMSRC='$(LIB1ASMSRC)' \
+ CONFIG_H="$(CONFIG_H)" \
MAKEOVERRIDES= \
-f libgcc.mk all
$(STAMP) stmp-multilib
@@ -1125,33 +1221,33 @@ stmp-multilib: $(LIBGCC_DEPS)
# linked using GCC on systems using COFF or ELF, for the sake of C++
# constructors.
$(T)crtbegin.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
- gbl-ctors.h stmp-int-hdrs tsystem.h
+ gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H)
$(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \
@inhibit_libc@ -c $(srcdir)/crtstuff.c -DCRT_BEGIN \
-o $(T)crtbegin$(objext)
$(T)crtend.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
- gbl-ctors.h stmp-int-hdrs tsystem.h
+ gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H)
$(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \
@inhibit_libc@ -c $(srcdir)/crtstuff.c -DCRT_END \
-o $(T)crtend$(objext)
# These are versions of crtbegin and crtend for shared libraries.
$(T)crtbeginS.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
- gbl-ctors.h stmp-int-hdrs tsystem.h
+ gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H)
$(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS_S) \
@inhibit_libc@ -c $(srcdir)/crtstuff.c -DCRT_BEGIN -DCRTSTUFFS_O \
-o $(T)crtbeginS$(objext)
$(T)crtendS.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
- gbl-ctors.h stmp-int-hdrs tsystem.h
+ gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H)
$(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS_S) \
@inhibit_libc@ -c $(srcdir)/crtstuff.c -DCRT_END -DCRTSTUFFS_O \
-o $(T)crtendS$(objext)
# This is a version of crtbegin for -static links.
$(T)crtbeginT.o: crtstuff.c $(GCC_PASSES) $(TCONFIG_H) auto-host.h \
- gbl-ctors.h stmp-int-hdrs tsystem.h
+ gbl-ctors.h stmp-int-hdrs tsystem.h coretypes.h $(TM_H)
$(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) \
@inhibit_libc@ -c $(srcdir)/crtstuff.c -DCRT_BEGIN -DCRTSTUFFT_O \
-o $(T)crtbeginT$(objext)
@@ -1175,58 +1271,61 @@ s-crt0: $(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H)
# C language specific files.
-c-errors.o: c-errors.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) flags.h \
- diagnostic.h $(TM_P_H)
-c-parse.o : $(srcdir)/c-parse.c $(CONFIG_H) $(TREE_H) $(GGC_H) intl.h \
- $(C_TREE_H) input.h flags.h $(SYSTEM_H) toplev.h output.h $(CPPLIB_H) \
- gt-c-parse.h
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
- -c $(srcdir)/c-parse.c $(OUTPUT_OPTION)
+c-errors.o: c-errors.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(C_TREE_H) flags.h $(DIAGNOSTIC_H) $(TM_P_H)
+c-parse.o : c-parse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(GGC_H) intl.h $(C_TREE_H) input.h flags.h toplev.h output.h $(CPPLIB_H) \
+ varray.h gt-c-parse.h
-$(srcdir)/c-parse.c: $(srcdir)/c-parse.y
- cd $(srcdir) && \
- if $(BISON) $(BISONFLAGS) -o c-p$$$$.c c-parse.y; then \
- test -f c-p$$$$.output && mv -f c-p$$$$.output c-parse.output ; \
- mv -f c-p$$$$.c c-parse.c ; \
- else \
- rm -f c-p$$$$.* ; \
- false ; \
- fi
+srcextra: gcc.srcextra lang.srcextra
+
+gcc.srcextra: c-parse.y c-parse.c gengtype-lex.c gengtype-yacc.c gengtype-yacc.h
+ -cp -p $^ $(srcdir)
+
+c-parse.c: c-parse.y
+ -$(BISON) $(BISONFLAGS) -o $@ $<
-$(srcdir)/c-parse.y: c-parse.in
+c-parse.y: c-parse.in
echo '/*WARNING: This file is automatically generated!*/' >tmp-c-parse.y
- sed -e "/^ifobjc$$/,/^end ifobjc$$/d" \
- -e "/^ifc$$/d" -e "/^end ifc$$/d" \
- $(srcdir)/c-parse.in >>tmp-c-parse.y
- $(SHELL) $(srcdir)/move-if-change tmp-c-parse.y $(srcdir)/c-parse.y
-
-c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) $(C_TREE_H) \
- $(GGC_H) $(TARGET_H) flags.h function.h output.h $(EXPR_H) \
- debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H) c-pragma.h \
- gt-c-decl.h libfuncs.h except.h
-c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
+ sed -e "/^@@ifobjc.*/,/^@@end_ifobjc.*/d" \
+ -e "/^@@ifc.*/d" -e "/^@@end_ifc.*/d" $< >>tmp-c-parse.y
+ $(SHELL) $(srcdir)/move-if-change tmp-c-parse.y $@
+
+c-incpath.o: c-incpath.c c-incpath.h $(CONFIG_H) $(SYSTEM_H) $(CPPLIB_H) \
+ intl.h prefix.h coretypes.h $(TM_H) cppdefault.h
+
+c-decl.o : c-decl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(RTL_H) $(C_TREE_H) $(GGC_H) $(TARGET_H) flags.h function.h output.h \
+ $(EXPR_H) debug.h toplev.h intl.h $(TM_P_H) tree-inline.h $(TIMEVAR_H) \
+ opts.h c-pragma.h gt-c-decl.h cgraph.h $(HASHTAB_H) libfuncs.h except.h \
+ $(LANGHOOKS_DEF_H)
+c-typeck.o : c-typeck.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(C_TREE_H) \
$(TARGET_H) flags.h intl.h output.h $(EXPR_H) $(RTL_H) toplev.h $(TM_P_H)
-c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
- $(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) c-common.h gtype-c.h
-c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \
- debug.h $(C_TREE_H) c-common.h real.h \
+c-lang.o : c-lang.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(C_TREE_H) $(C_PRETTY_PRINT_H) $(DIAGNOSTIC_H) \
+ $(GGC_H) langhooks.h $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-c.h
+stub-objc.o : stub-objc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
+ $(GGC_H) $(C_COMMON_H)
+c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(RTL_H) debug.h $(C_TREE_H) $(C_COMMON_H) real.h c-incpath.h cppdefault.h \
c-pragma.h input.h intl.h flags.h toplev.h output.h \
- mbchar.h $(CPPLIB_H) $(EXPR_H) $(TM_P_H)
-c-objc-common.o : c-objc-common.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
- $(C_TREE_H) $(RTL_H) insn-config.h integrate.h $(EXPR_H) $(C_TREE_H) \
- flags.h toplev.h tree-inline.h diagnostic.h integrate.h $(VARRAY_H) \
- langhooks.h $(GGC_H) gt-c-objc-common.h $(TARGET_H)
-c-aux-info.o : c-aux-info.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
- flags.h toplev.h
-c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h toplev.h \
- $(C_COMMON_H)
-c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) function.h \
- c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) $(C_COMMON_H) gt-c-pragma.h
-mbchar.o: mbchar.c $(CONFIG_H) $(SYSTEM_H) mbchar.h
-graph.o: graph.c $(CONFIG_H) $(SYSTEM_H) toplev.h flags.h output.h $(RTL_H) \
- function.h hard-reg-set.h $(BASIC_BLOCK_H) graph.h
-sbitmap.o: sbitmap.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h hard-reg-set.h \
- $(BASIC_BLOCK_H)
+ $(CPPLIB_H) $(EXPR_H) $(TM_P_H)
+c-ppoutput.o : c-ppoutput.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(C_COMMON_H) $(TREE_H) $(CPPLIB_H) cpphash.h $(TM_P_H) c-pragma.h
+c-objc-common.o : c-objc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(C_TREE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) $(EXPR_H) $(C_TREE_H) \
+ flags.h toplev.h tree-inline.h $(DIAGNOSTIC_H) $(VARRAY_H) \
+ langhooks.h $(GGC_H) $(TARGET_H) cgraph.h
+c-aux-info.o : c-aux-info.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(C_TREE_H) flags.h toplev.h
+c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ flags.h toplev.h $(C_COMMON_H) real.h
+c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ function.h c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) $(C_COMMON_H) gt-c-pragma.h
+graph.o: graph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h flags.h output.h \
+ $(RTL_H) function.h hard-reg-set.h $(BASIC_BLOCK_H) graph.h
+sbitmap.o: sbitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
+ hard-reg-set.h $(BASIC_BLOCK_H)
COLLECT2_OBJS = collect2.o tlink.o intl.o version.o
COLLECT2_LIBS = @COLLECT2_LIBS@
@@ -1236,57 +1335,74 @@ collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
$(COLLECT2_OBJS) $(LIBS) $(COLLECT2_LIBS)
mv -f T$@ $@
-collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) gstab.h intl.h \
+collect2.o : collect2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) gstab.h intl.h \
$(OBSTACK_H) $(DEMANGLE_H) collect2.h version.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
- -DTARGET_MACHINE=\"$(target_alias)\" \
+ -DTARGET_MACHINE=\"$(target_noncanonical)\" \
-c $(srcdir)/collect2.c $(OUTPUT_OPTION)
-tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) \
+tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(OBSTACK_H) collect2.h intl.h
# A file used by all variants of C.
-c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(OBSTACK_H) \
- $(C_COMMON_H) flags.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
- $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def $(TARGET_H) \
- diagnostic.h except.h gt-c-common.h real.h langhooks.h c-tree.h
-c-pretty-print.o : c-pretty-print.c c-pretty-print.h pretty-print.h \
- $(C_COMMON_H) $(CONFIG_H) $(SYSTEM_H) real.h
+c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(OBSTACK_H) $(C_COMMON_H) flags.h toplev.h output.h c-pragma.h intl.h \
+ $(GGC_H) $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def \
+ $(DIAGNOSTIC_H) gt-c-common.h langhooks.h varray.h $(RTL_H) \
+ $(TARGET_H) $(C_TREE_H)
+c-pretty-print.o : c-pretty-print.c $(C_PRETTY_PRINT_H) \
+ $(C_COMMON_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) real.h
+
+c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ c-pragma.h flags.h toplev.h langhooks.h tree-inline.h $(DIAGNOSTIC_H) \
+ intl.h debug.h $(C_COMMON_H) opts.h options.h $(PARAMS_H)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $< $(OUTPUT_OPTION) @TARGET_SYSTEM_ROOT_DEFINE@
-c-opts.o : c-opts.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_COMMON_H) \
- c-pragma.h flags.h toplev.h langhooks.h tree-inline.h diagnostic.h \
- intl.h
+c-cppbuiltin.o : c-cppbuiltin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(TREE_H) $(C_COMMON_H) c-pragma.h flags.h toplev.h langhooks.h \
+ output.h except.h real.h $(TM_P_H)
# A file used by all variants of C and some other languages.
-attribs.o : attribs.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h \
+attribs.o : attribs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) flags.h \
toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) $(EXPR_H) $(TM_P_H) \
builtin-types.def $(TARGET_H) langhooks.h
-c-format.o : c-format.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) langhooks.h \
- $(C_COMMON_H) flags.h toplev.h intl.h diagnostic.h
+c-format.o : c-format.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) langhooks.h \
+ $(C_COMMON_H) flags.h toplev.h intl.h $(DIAGNOSTIC_H)
+
+c-semantics.o : c-semantics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(C_TREE_H) flags.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
+ $(EXPR_H) $(PREDICT_H) tree-inline.h
-c-semantics.o : c-semantics.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
- flags.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
- $(EXPR_H) $(PREDICT_H)
+c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(C_TREE_H) tree-dump.h
-c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) tree-dump.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)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ -DHOST_MACHINE=\"$(host)\" -DTARGET_MACHINE=\"$(target)\" \
+ $< $(OUTPUT_OPTION)
# Language-independent files.
DRIVER_DEFINES = \
-DSTANDARD_STARTFILE_PREFIX=\"$(unlibsubdir)/\" \
- -DSTANDARD_EXEC_PREFIX=\"$(libdir)/gcc-lib/\" \
+ -DSTANDARD_EXEC_PREFIX=\"$(libdir)/gcc/\" \
+ -DSTANDARD_LIBEXEC_PREFIX=\"$(libexecdir)/gcc/\" \
-DDEFAULT_TARGET_VERSION=\"$(version)\" \
- -DDEFAULT_TARGET_MACHINE=\"$(target_alias)\" \
+ -DDEFAULT_TARGET_MACHINE=\"$(target_noncanonical)\" \
-DSTANDARD_BINDIR_PREFIX=\"$(bindir)/\" \
-DTOOLDIR_BASE_PREFIX=\"$(unlibsubdir)/../\" \
+ @TARGET_SYSTEM_ROOT_DEFINE@ \
$(VALGRIND_DRIVER_DEFINES) \
`test "X$${SHLIB_LINK}" = "X" || test "@enable_shared@" != "yes" || echo "-DENABLE_SHARED_LIBGCC"` \
`test "X$${SHLIB_MULTILIB}" = "X" || echo "-DNO_SHARED_LIBGCC_MULTILIB"`
-gcc.o: gcc.c $(CONFIG_H) $(SYSTEM_H) intl.h multilib.h \
+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)
(SHLIB_LINK='$(SHLIB_LINK)' \
SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
@@ -1294,14 +1410,14 @@ gcc.o: gcc.c $(CONFIG_H) $(SYSTEM_H) intl.h multilib.h \
$(DRIVER_DEFINES) \
-c $(srcdir)/gcc.c $(OUTPUT_OPTION))
-gccspec.o: gccspec.c $(CONFIG_H) $(SYSTEM_H) $(GCC_H)
+gccspec.o: gccspec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H)
(SHLIB_LINK='$(SHLIB_LINK)' \
SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(DRIVER_DEFINES) \
-c $(srcdir)/gccspec.c $(OUTPUT_OPTION))
-cppspec.o: cppspec.c $(CONFIG_H) $(SYSTEM_H) $(GCC_H)
+cppspec.o: cppspec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H)
tree-check.h: s-check ; @true
s-check : gencheck$(build_exeext) $(srcdir)/move-if-change
@@ -1309,14 +1425,12 @@ s-check : gencheck$(build_exeext) $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-check.h tree-check.h
$(STAMP) s-check
-gencheck$(build_exeext) : gencheck.o $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- gencheck.o $(HOST_LIBS)
+gencheck$(build_exeext) : gencheck.o $(BUILD_LIBDEPS)
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
+ gencheck.o $(BUILD_LIBS)
-gencheck.o : gencheck.c gencheck.h tree.def $(HCONFIG_H) $(SYSTEM_H) \
- $(lang_tree_files)
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
- $(srcdir)/gencheck.c $(OUTPUT_OPTION)
+gencheck.o : gencheck.c gencheck.h tree.def $(BCONFIG_H) $(SYSTEM_H) \
+ coretypes.h $(GTM_H) $(lang_tree_files)
gencheck.h : s-gencheck ; @true
s-gencheck : Makefile
@@ -1326,14 +1440,6 @@ s-gencheck : Makefile
$(SHELL) $(srcdir)/move-if-change tmp-gencheck.h gencheck.h
$(STAMP) s-gencheck
-options.h : s-options ; @true
-s-options : Makefile
- lof="$(lang_options_files)"; for f in $$lof; do \
- echo "#include \"$$f\""; \
- done | sed 's|$(srcdir)/||' > tmp-options.h
- $(SHELL) $(srcdir)/move-if-change tmp-options.h options.h
- $(STAMP) s-options
-
specs.h : s-specs ; @true
s-specs : Makefile
lsf="$(lang_specs_files)"; for f in $$lsf; do \
@@ -1342,331 +1448,395 @@ s-specs : Makefile
$(SHELL) $(srcdir)/move-if-change tmp-specs.h specs.h
$(STAMP) s-specs
+options.c: $(lang_opt_files) $(srcdir)/opts.sh options.h intl.h
+
+options.h: $(lang_opt_files) $(srcdir)/opts.sh Makefile
+ AWK=$(AWK) $(SHELL) $(srcdir)/opts.sh \
+ '$(SHELL) $(srcdir)/move-if-change' \
+ options.c options.h $(lang_opt_files)
+
dumpvers: dumpvers.c
version.o: version.c version.h
-gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) varray.h $(HASHTAB_H) \
- $(TREE_H) $(RTL_H) function.h insn-config.h $(EXPR_H) $(OPTABS_H) \
+gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) varray.h \
+ $(HASHTAB_H) $(TREE_H) $(RTL_H) function.h insn-config.h $(EXPR_H) $(OPTABS_H) \
libfuncs.h debug.h $(GGC_H) bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h \
- ssa.h cselib.h insn-addr.h
+ cselib.h insn-addr.h
-ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
- flags.h $(GGC_H) varray.h $(HASHTAB_H) $(TM_P_H) langhooks.h \
- $(PARAMS_H)
+ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \
+ $(HASHTAB_H) toplev.h $(PARAMS_H) hosthooks.h
-ggc-simple.o: ggc-simple.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- $(GGC_H) varray.h $(TIMEVAR_H) $(TM_P_H) $(PARAMS_H)
+ggc-simple.o: ggc-simple.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ flags.h $(GGC_H) varray.h $(TIMEVAR_H) $(TM_P_H) $(PARAMS_H)
-ggc-page.o: ggc-page.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- toplev.h $(GGC_H) $(TIMEVAR_H) $(TM_P_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)
-stringpool.o: stringpool.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(OBSTACK_H) \
- flags.h toplev.h $(GGC_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)
-hashtable.o: hashtable.c hashtable.h $(CONFIG_H) $(SYSTEM_H) $(OBSTACK_H)
+stringpool.o: stringpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(TREE_H) $(GGC_H) gt-stringpool.h
-line-map.o: line-map.c line-map.h intl.h $(CONFIG_H) $(SYSTEM_H)
-
-ggc-none.o: ggc-none.c $(GCONFIG_H) $(SYSTEM_H) $(GGC_H)
+ggc-none.o: ggc-none.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) $(GGC_H)
$(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) Makefile prefix.h
+prefix.o: prefix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) Makefile prefix.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DPREFIX=\"$(prefix)\" \
-c $(srcdir)/prefix.c $(OUTPUT_OPTION)
-convert.o: convert.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h convert.h \
- toplev.h langhooks.h
+convert.o: convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) flags.h \
+ convert.h toplev.h langhooks.h
-langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) toplev.h \
- tree-inline.h $(RTL_H) insn-config.h integrate.h langhooks.h \
- $(LANGHOOKS_DEF_H) flags.h
-tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h function.h toplev.h \
- $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
+langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) toplev.h \
+ tree-inline.h $(RTL_H) insn-config.h $(INTEGRATE_H) langhooks.h \
+ $(LANGHOOKS_DEF_H) flags.h $(GGC_H) gt-langhooks.h diagnostic.h
+tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) flags.h function.h \
+ toplev.h $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
real.h gt-tree.h
-tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(C_TREE_H) \
- flags.h langhooks.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
+tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(C_TREE_H) flags.h langhooks.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
$(EXPR_H) $(SPLAY_TREE_H) tree-dump.h
-tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \
- expr.h flags.h params.h input.h insn-config.h $(INTEGRATE_H) \
- $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h langhooks.h \
- $(C_COMMON_H) tree-inline.h
-print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GGC_H) \
- langhooks.h real.h
-stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h \
- function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H) $(TM_P_H) $(TARGET_H) \
+tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(TREE_H) $(RTL_H) $(EXPR_H) flags.h $(PARAMS_H) input.h insn-config.h \
+ $(INTEGRATE_H) $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
+ langhooks.h $(C_COMMON_H) tree-inline.h cgraph.h intl.h
+tree-optimize.o : tree-optimize.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(TREE_H) toplev.h langhooks.h cgraph.h $(TIMEVAR_H) function.h $(GGC_H)
+
+print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(GGC_H) langhooks.h real.h
+stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ flags.h function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H) $(TM_P_H) $(TARGET_H) \
langhooks.h
-fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h real.h \
- toplev.h $(HASHTAB_H) $(EXPR_H) $(RTL_H) $(GGC_H) $(TM_P_H) langhooks.h
-diagnostic.o : diagnostic.c diagnostic.h real.h diagnostic.def \
- $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TM_P_H) flags.h $(GGC_H) \
+fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ flags.h real.h toplev.h $(HASHTAB_H) $(EXPR_H) $(RTL_H) $(GGC_H) $(TM_P_H) langhooks.h
+diagnostic.o : diagnostic.c $(DIAGNOSTIC_H) real.h \
+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(TM_P_H) flags.h $(GGC_H) \
input.h toplev.h intl.h langhooks.h $(LANGHOOKS_DEF_H)
-toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) function.h \
- flags.h xcoffout.h input.h $(INSN_ATTR_H) output.h diagnostic.h \
+opts.o : opts.c opts.h options.h toplev.h $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(RTL_H) \
+ output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h
+targhooks.o : targhooks.c targhooks.h $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h $(TREE_H) $(TM_H) $(RTL_H) $(TM_P_H) function.h \
+ output.h toplev.h
+
+toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_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 $(RECOG_H) Makefile toplev.h \
dwarf2out.h sdbout.h dbxout.h $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) \
- graph.h $(LOOP_H) except.h $(REGS_H) $(TIMEVAR_H) $(lang_options_files) \
- ssa.h $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
- langhooks.h insn-flags.h options.h cfglayout.h real.h
+ graph.h $(LOOP_H) except.h $(REGS_H) $(TIMEVAR_H) value-prof.h \
+ $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
+ langhooks.h insn-flags.h cfglayout.h real.h cfgloop.h \
+ hosthooks.h $(LANGHOOKS_DEF_H) cgraph.h $(COVERAGE_H) alloc-pool.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
- -DTARGET_NAME=\"$(target_alias)\" \
+ -DTARGET_NAME=\"$(target_noncanonical)\" \
-c $(srcdir)/toplev.c $(OUTPUT_OPTION)
-main.o : main.c $(CONFIG_H) $(SYSTEM_H) toplev.h
+main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h
+
+host-default.o : host-default.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ hosthooks.h hosthooks-def.h
-rtl-error.o: rtl-error.c system.h $(RTL_H) $(INSN_ATTR_H) insn-config.h \
- input.h toplev.h intl.h diagnostic.h $(CONFIG_H)
+rtl-error.o: rtl-error.c $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(INSN_ATTR_H) \
+ insn-config.h input.h toplev.h intl.h $(DIAGNOSTIC_H) $(CONFIG_H)
-rtl.o : rtl.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) real.h $(GGC_H) errors.h
+rtl.o : rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) $(RTL_H) real.h \
+ $(GGC_H) errors.h
$(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
- hard-reg-set.h $(BASIC_BLOCK_H) real.h
-rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) toplev.h $(RTL_H) \
- hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) real.h flags.h
+print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) real.h $(TM_P_H)
+rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \
+ $(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) real.h flags.h \
+ $(BASIC_BLOCK_H)
-errors.o : errors.c $(GCONFIG_H) $(SYSTEM_H) errors.h
+errors.o : errors.c $(CONFIG_H) $(SYSTEM_H) errors.h
$(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
- function.h $(EXPR_H) hard-reg-set.h $(REGS_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) \
$(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h real.h
-function.o : function.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- function.h $(EXPR_H) libfuncs.h $(REGS_H) hard-reg-set.h \
+function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ flags.h function.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h \
insn-config.h $(RECOG_H) output.h toplev.h except.h $(HASHTAB_H) $(GGC_H) \
- $(TM_P_H) langhooks.h gt-function.h
-stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h \
- insn-config.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \
+ $(TM_P_H) langhooks.h gt-function.h $(TARGET_H)
+stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) flags.h \
+ function.h insn-config.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \
$(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H) \
- langhooks.h $(PREDICT_H) gt-stmt.h
-except.o : except.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- except.h function.h $(EXPR_H) libfuncs.h integrate.h langhooks.h \
- insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \
+ langhooks.h $(PREDICT_H) gt-stmt.h $(OPTABS_H) $(TARGET_H)
+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 $(INTEGRATE_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
-expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h \
- $(REGS_H) $(EXPR_H) $(OPTABS_H) libfuncs.h insn-attr.h insn-config.h \
+ gt-except.h cgraph.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) libfuncs.h $(INSN_ATTR_H) insn-config.h \
$(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
- except.h reload.h $(GGC_H) langhooks.h intl.h $(TM_P_H) real.h
-builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- $(TARGET_H) function.h $(REGS_H) $(EXPR_H) $(OPTABS_H) insn-config.h \
+ except.h reload.h $(GGC_H) langhooks.h intl.h $(TM_P_H) real.h $(TARGET_H)
+dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ flags.h function.h $(EXPR_H) $(OPTABS_H) $(INSN_ATTR_H) insn-config.h \
+ langhooks.h
+builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H)\
+ flags.h $(TARGET_H) function.h $(REGS_H) $(EXPR_H) $(OPTABS_H) insn-config.h \
$(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
except.h $(TM_P_H) $(PREDICT_H) libfuncs.h real.h langhooks.h
-calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- $(EXPR_H) langhooks.h $(TARGET_H) \
- libfuncs.h $(REGS_H) toplev.h output.h function.h $(TIMEVAR_H) $(TM_P_H) \
- except.h
-expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) real.h \
+calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) flags.h \
+ $(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \
+ libfuncs.h $(REGS_H) toplev.h output.h function.h $(TIMEVAR_H) $(TM_P_H) cgraph.h except.h
+expmed.o : expmed.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ flags.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) real.h \
toplev.h $(TM_P_H) langhooks.h
-explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \
- toplev.h function.h ggc.h $(TM_P_H) gt-explow.h
-optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(RECOG_H) reload.h \
- toplev.h $(GGC_H) real.h $(TM_P_H) except.h gt-optabs.h $(BASIC_BLOCK_H)
-dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
- $(REGS_H) debug.h $(TM_P_H) $(TARGET_H) function.h langhooks.h \
- insn-config.h reload.h gstab.h xcoffout.h output.h dbxout.h toplev.h
-debug.o : debug.c debug.h $(CONFIG_H) $(SYSTEM_H)
-sdbout.o : sdbout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
- function.h $(EXPR_H) output.h hard-reg-set.h $(REGS_H) real.h \
- insn-config.h xcoffout.h c-pragma.h ggc.h \
+explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ flags.h hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \
+ toplev.h function.h $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h
+optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ flags.h insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(RECOG_H) reload.h \
+ toplev.h $(GGC_H) real.h $(TM_P_H) except.h gt-optabs.h $(BASIC_BLOCK_H) \
+ $(TARGET_H)
+dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
+ flags.h $(REGS_H) debug.h $(TM_P_H) $(TARGET_H) function.h langhooks.h \
+ insn-config.h reload.h gstab.h xcoffout.h output.h dbxout.h toplev.h \
+ $(GGC_H) gt-dbxout.h
+debug.o : debug.c debug.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
+sdbout.o : sdbout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
+ flags.h function.h $(EXPR_H) output.h hard-reg-set.h $(REGS_H) real.h \
+ insn-config.h xcoffout.h c-pragma.h $(GGC_H) $(TARGET_H) \
sdbout.h toplev.h $(TM_P_H) except.h debug.h langhooks.h gt-sdbout.h
-dwarfout.o : dwarfout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) dwarf.h \
- flags.h insn-config.h reload.h output.h toplev.h $(TM_P_H) \
- debug.h langhooks.h
-dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) dwarf2.h \
- debug.h flags.h insn-config.h reload.h output.h diagnostic.h real.h \
+dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(RTL_H) dwarf2.h debug.h flags.h insn-config.h reload.h output.h $(DIAGNOSTIC_H) real.h \
hard-reg-set.h $(REGS_H) $(EXPR_H) libfuncs.h toplev.h dwarf2out.h varray.h \
- $(GGC_H) except.h dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) gt-dwarf2out.h
-dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) flags.h $(RTL_H) $(TREE_H) \
- output.h dwarf2asm.h $(TM_P_H) $(GGC_H)
-vmsdbgout.o : vmsdbgout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \
- output.h vmsdbg.h debug.h langhooks.h function.h
-xcoffout.o : xcoffout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) xcoffout.h \
- flags.h toplev.h output.h dbxout.h $(GGC_H) $(TARGET_H)
-emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- function.h $(REGS_H) insn-config.h $(RECOG_H) real.h $(GGC_H) \
- $(EXPR_H) $(srcdir)/../include/obstack.h hard-reg-set.h bitmap.h toplev.h \
- $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h
-real.o : real.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) toplev.h $(TM_P_H)
-integrate.o : integrate.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- debug.h $(INTEGRATE_H) insn-config.h $(EXPR_H) real.h $(REGS_H) \
+ $(GGC_H) except.h dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) \
+ gt-dwarf2out.h $(TARGET_H) cgraph.h
+dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) flags.h $(RTL_H) \
+ $(TREE_H) output.h dwarf2asm.h $(TM_P_H) $(GGC_H) gt-dwarf2asm.h
+vmsdbgout.o : vmsdbgout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ $(RTL_H) flags.h output.h vmsdbg.h debug.h langhooks.h function.h $(TARGET_H)
+xcoffout.o : xcoffout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
+ xcoffout.h flags.h toplev.h output.h dbxout.h $(GGC_H) $(TARGET_H)
+emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ flags.h function.h $(REGS_H) insn-config.h $(RECOG_H) real.h $(GGC_H) \
+ $(EXPR_H) $(OBSTACK_H) hard-reg-set.h bitmap.h toplev.h \
+ $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h gt-emit-rtl.h
+real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) toplev.h $(TM_P_H)
+integrate.o : integrate.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ flags.h debug.h $(INTEGRATE_H) insn-config.h $(EXPR_H) real.h $(REGS_H) \
intl.h function.h output.h $(RECOG_H) except.h toplev.h $(LOOP_H) \
$(PARAMS_H) $(TM_P_H) $(TARGET_H) langhooks.h gt-integrate.h
-jump.o : jump.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h hard-reg-set.h $(REGS_H) \
- insn-config.h $(RECOG_H) $(EXPR_H) real.h except.h function.h \
- toplev.h $(INSN_ATTR_H) $(TM_P_H) reload.h $(PREDICT_H)
-
-simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) \
+jump.o : jump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
+ hard-reg-set.h $(REGS_H) insn-config.h $(RECOG_H) $(EXPR_H) real.h except.h function.h \
+ toplev.h $(INSN_ATTR_H) $(TM_P_H) reload.h $(PREDICT_H) $(TIMEVAR_H) \
+ $(DIAGNOSTIC_H)
+
+simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ $(REGS_H) hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
+ output.h function.h $(GGC_H) $(OBSTACK_H) $(TM_P_H) $(TREE_H) $(TARGET_H)
+cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ langhooks.h toplev.h flags.h $(GGC_H) $(TARGET_H) cgraph.h gt-cgraph.h \
+ output.h intl.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 \
+ function.h
+coverage.o : coverage.c gcov-io.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(RTL_H) $(TREE_H) flags.h output.h $(REGS_H) $(EXPR_H) function.h \
+ toplev.h $(GGC_H) $(TARGET_H) langhooks.h $(COVERAGE_H) libfuncs.h \
+ gt-coverage.h $(HASHTAB_H)
+cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
- output.h function.h $(GGC_H) $(OBSTACK_H) $(TM_P_H) $(TREE_H)
-cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) \
+ output.h function.h cselib.h $(GGC_H) $(TM_P_H) gt-cselib.h $(PARAMS_H)
+cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
- output.h function.h cselib.h $(GGC_H) $(TM_P_H) gt-cselib.h
-cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
- real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h function.h \
- $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H)
-gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_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
-sibcall.o : sibcall.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) function.h \
- hard-reg-set.h flags.h insn-config.h $(RECOG_H) $(BASIC_BLOCK_H)
-resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) \
- $(BASIC_BLOCK_H) $(REGS_H) flags.h output.h resource.h function.h toplev.h \
+ output.h function.h $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H) \
+ except.h $(TARGET_H) $(PARAMS_H)
+web.o : web.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
+ hard-reg-set.h flags.h $(BASIC_BLOCK_H) function.h output.h toplev.h df.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 gt-gcse.h $(TREE_H) cselib.h
+sibcall.o : sibcall.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
+ function.h hard-reg-set.h flags.h insn-config.h $(RECOG_H) $(BASIC_BLOCK_H)
+resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(BASIC_BLOCK_H) $(REGS_H) flags.h output.h resource.h function.h toplev.h \
$(INSN_ATTR_H) except.h $(PARAMS_H) $(TM_P_H)
-lcm.o : lcm.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
- real.h insn-config.h $(INSN_ATTR_H) $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) \
- $(TM_P_H) df.h
-ssa.o : ssa.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) varray.h $(EXPR_H) \
- hard-reg-set.h flags.h function.h real.h insn-config.h $(RECOG_H) \
- $(BASIC_BLOCK_H) output.h ssa.h
-ssa-dce.o : ssa-dce.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h \
- $(BASIC_BLOCK_H) ssa.h insn-config.h $(RECOG_H) output.h
-ssa-ccp.o : ssa-ccp.c $(CONFIG_H) system.h $(RTL_H) hard-reg-set.h \
- $(BASIC_BLOCK_H) ssa.h insn-config.h $(RECOG_H) output.h \
- errors.h $(GGC_H) df.h function.h
-df.o : df.c $(CONFIG_H) system.h $(RTL_H) insn-config.h $(RECOG_H) \
- function.h $(REGS_H) $(OBSTACK_H) hard-reg-set.h $(BASIC_BLOCK_H) df.h \
- $(FIBHEAP_H)
-conflict.o : conflict.c $(CONFIG_H) $(SYSTEM_H) $(OBSTACK_H) $(HASHTAB_H) \
- $(RTL_H) hard-reg-set.h $(BASIC_BLOCK_H)
-profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- insn-config.h output.h $(REGS_H) $(EXPR_H) function.h \
- gcov-io.h toplev.h $(GGC_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TARGET_H) \
- langhooks.h profile.h libfuncs.h gt-profile.h
-loop.o : loop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h $(LOOP_H) \
+lcm.o : lcm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
+ hard-reg-set.h flags.h real.h insn-config.h $(INSN_ATTR_H) $(RECOG_H) $(EXPR_H) \
+ $(BASIC_BLOCK_H) $(TM_P_H) df.h function.h
+df.o : df.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ insn-config.h $(RECOG_H) function.h $(REGS_H) alloc-pool.h hard-reg-set.h \
+ $(BASIC_BLOCK_H) df.h $(FIBHEAP_H)
+conflict.o : conflict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(OBSTACK_H) \
+ $(HASHTAB_H) $(RTL_H) hard-reg-set.h $(BASIC_BLOCK_H)
+profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ $(TREE_H) flags.h output.h $(REGS_H) $(EXPR_H) function.h \
+ toplev.h $(BASIC_BLOCK_H) $(COVERAGE_H) $(TREE_H) value-prof.h
+value-prof.o : value-prof.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ $(BASIC_BLOCK_H) hard-reg-set.h value-prof.h $(EXPR_H) output.h flags.h \
+ $(RECOG_H) insn-config.h $(OPTABS_H) $(REGS_H)
+loop.o : loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h $(LOOP_H) \
insn-config.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) \
- real.h $(PREDICT_H) $(BASIC_BLOCK_H) function.h \
- toplev.h varray.h except.h cselib.h $(OPTABS_H) $(TM_P_H)
-doloop.o : doloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h $(LOOP_H) \
- $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) toplev.h
-unroll.o : unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h function.h \
- $(INTEGRATE_H) $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) $(LOOP_H) toplev.h \
- hard-reg-set.h varray.h $(BASIC_BLOCK_H) $(TM_P_H) $(PREDICT_H) $(PARAMS_H)
-flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h insn-config.h \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
- function.h except.h $(EXPR_H) ssa.h $(GGC_H) $(TM_P_H)
-cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h insn-config.h \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
- function.h except.h $(GGC_H) $(TM_P_H)
-cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h insn-config.h \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
- function.h except.h $(GGC_H) $(TM_P_H) insn-config.h
-cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(BASIC_BLOCK_H) \
- hard-reg-set.h insn-config.h $(RECOG_H) $(GGC_H) $(TM_P_H)
-cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h insn-config.h \
+ real.h $(PREDICT_H) $(BASIC_BLOCK_H) function.h cfgloop.h \
+ toplev.h varray.h except.h cselib.h $(OPTABS_H) $(TM_P_H) $(GGC_H)
+doloop.o : doloop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
+ $(LOOP_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) toplev.h \
+ cfgloop.h
+unroll.o : unroll.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) insn-config.h \
+ function.h $(INTEGRATE_H) $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) $(LOOP_H) toplev.h \
+ hard-reg-set.h varray.h $(BASIC_BLOCK_H) $(TM_P_H) $(PREDICT_H) $(PARAMS_H) \
+ cfgloop.h
+alloc-pool.o : alloc-pool.c $(CONFIG_H) $(SYSTEM_H) alloc-pool.h $(HASHTAB_H)
+flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ flags.h insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
+ $(RECOG_H) function.h except.h $(EXPR_H) $(GGC_H) $(TM_P_H)
+cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h insn-config.h \
$(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
+ function.h except.h $(GGC_H) $(TM_P_H) alloc-pool.h
+cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ $(BASIC_BLOCK_H) cfglayout.h
+cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
+ insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
+ function.h except.h $(GGC_H) $(TM_P_H) insn-config.h $(EXPR_H)
+cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ $(BASIC_BLOCK_H) hard-reg-set.h insn-config.h $(RECOG_H) $(GGC_H) $(TM_P_H)
+cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
+ insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
function.h except.h $(GGC_H)
-cfgcleanup.o : cfgcleanup.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TIMEVAR_H)\
- $(BASIC_BLOCK_H) hard-reg-set.h output.h flags.h $(RECOG_H) toplev.h \
- $(GGC_H) insn-config.h cselib.h $(TARGET_H) $(TM_P_H) $(PARAMS_H)
-cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
- $(BASIC_BLOCK_H) hard-reg-set.h
-dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h \
- $(BASIC_BLOCK_H) et-forest.h
-et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) et-forest.h
-combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h function.h \
- insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \
- $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h $(TM_P_H)
-regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) hard-reg-set.h flags.h \
- $(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(RECOG_H) reload.h real.h \
- toplev.h function.h output.h $(GGC_H) $(TM_P_H) $(EXPR_H)
-local-alloc.o : local-alloc.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
+cfgcleanup.o : cfgcleanup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(TIMEVAR_H) $(BASIC_BLOCK_H) hard-reg-set.h output.h flags.h \
+ $(RECOG_H) toplev.h $(GGC_H) insn-config.h cselib.h $(TARGET_H) $(TM_P_H) \
+ $(PARAMS_H)
+cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) coretypes.h $(TM_H) \
+ $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h flags.h
+cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
+ $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h $(EXPR_H) coretypes.h $(TM_H)
+cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
+ $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h output.h coretypes.h $(TM_H)
+loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
+ $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h \
+ coretypes.h $(TM_H)
+loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
+ $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h $(PARAMS_H) \
+ output.h $(EXPR_H) coretypes.h $(TM_H)
+loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
+ $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h $(PARAMS_H) \
+ output.h $(EXPR_H) coretypes.h $(TM_H)
+dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h
+et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) et-forest.h alloc-pool.h
+combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
+ function.h insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \
+ $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h $(TM_P_H) $(TREE_H) $(TARGET_H)
+regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ hard-reg-set.h flags.h $(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(RECOG_H) reload.h \
+ real.h toplev.h function.h output.h $(GGC_H) $(TM_P_H) $(EXPR_H) $(TIMEVAR_H)
+local-alloc.o : local-alloc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ flags.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
output.h function.h $(INSN_ATTR_H) toplev.h except.h $(TM_P_H)
-bitmap.o : bitmap.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h \
+bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) $(RTL_H) flags.h \
$(BASIC_BLOCK_H) $(REGS_H) $(GGC_H)
$(CC) -c $(ALL_CFLAGS) -DGENERATOR_FILE $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-global.o : global.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h reload.h function.h \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h output.h toplev.h \
- $(TM_P_H)
-varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) varray.h $(GGC_H) errors.h
-ra.o : ra.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_P_H) insn-config.h \
- $(RECOG_H) integrate.h function.h $(REGS_H) $(OBSTACK_H) hard-reg-set.h \
- $(BASIC_BLOCK_H) df.h expr.h output.h toplev.h flags.h reload.h ra.h
-ra-build.o : ra-build.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_P_H) \
+global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
+ reload.h function.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h output.h \
+ toplev.h $(TM_P_H)
+varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) varray.h $(GGC_H) errors.h
+ra.o : ra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TM_P_H) insn-config.h \
+ $(RECOG_H) $(INTEGRATE_H) function.h $(REGS_H) $(OBSTACK_H) hard-reg-set.h \
+ $(BASIC_BLOCK_H) df.h $(EXPR_H) output.h toplev.h flags.h reload.h ra.h
+ra-build.o : ra-build.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TM_P_H) \
insn-config.h $(RECOG_H) function.h $(REGS_H) hard-reg-set.h \
- $(BASIC_BLOCK_H) df.h output.h ggc.h ra.h gt-ra-build.h reload.h
-ra-colorize.o : ra-colorize.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_P_H) \
- function.h $(REGS_H) hard-reg-set.h $(BASIC_BLOCK_H) df.h output.h ra.h
-ra-debug.o : ra-debug.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h \
- $(RECOG_H) function.h hard-reg-set.h $(BASIC_BLOCK_H) df.h output.h ra.h \
- $(TM_P_H)
-ra-rewrite.o : ra-rewrite.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_P_H) \
- function.h $(REGS_H) hard-reg-set.h $(BASIC_BLOCK_H) df.h expr.h \
+ $(BASIC_BLOCK_H) df.h output.h $(GGC_H) ra.h gt-ra-build.h reload.h
+ra-colorize.o : ra-colorize.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ $(TM_P_H) function.h $(REGS_H) hard-reg-set.h $(BASIC_BLOCK_H) df.h output.h ra.h
+ra-debug.o : ra-debug.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ insn-config.h $(RECOG_H) function.h hard-reg-set.h $(BASIC_BLOCK_H) df.h output.h \
+ ra.h $(TM_P_H)
+ra-rewrite.o : ra-rewrite.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ $(TM_P_H) function.h $(REGS_H) hard-reg-set.h $(BASIC_BLOCK_H) df.h $(EXPR_H) \
output.h except.h ra.h reload.h insn-config.h
-reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h output.h \
+reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h output.h \
$(EXPR_H) $(OPTABS_H) reload.h $(RECOG_H) hard-reg-set.h insn-config.h \
- $(REGS_H) function.h real.h toplev.h $(TM_P_H)
-reload1.o : reload1.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) real.h flags.h \
+ $(REGS_H) function.h real.h toplev.h $(TM_P_H) $(PARAMS_H)
+reload1.o : reload1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) real.h flags.h \
+ $(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) hard-reg-set.h insn-config.h \
+ $(BASIC_BLOCK_H) $(RECOG_H) output.h function.h toplev.h $(TM_P_H) \
+ except.h $(TREE_H)
+postreload.o : postreload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) real.h flags.h \
$(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) hard-reg-set.h insn-config.h \
$(BASIC_BLOCK_H) $(RECOG_H) output.h function.h toplev.h cselib.h $(TM_P_H) \
except.h $(TREE_H)
-caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h \
- $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) function.h \
+caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ flags.h $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) function.h \
$(RECOG_H) reload.h $(EXPR_H) toplev.h $(TM_P_H)
-reorg.o : reorg.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) conditions.h hard-reg-set.h \
- $(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(INSN_ATTR_H) except.h \
+bt-load.o : bt-load.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(BASIC_BLOCK_H) $(RTL_H) hard-reg-set.h $(REGS_H) $(OBSTACK_H) $(TM_P_H) \
+ $(FIBHEAP_H) output.h $(TARGET_H) $(EXPR_H) flags.h $(INSN_ATTR_H)
+reorg.o : reorg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) conditions.h \
+ hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(INSN_ATTR_H) except.h \
$(RECOG_H) function.h flags.h output.h $(EXPR_H) toplev.h $(PARAMS_H) $(TM_P_H)
-alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) flags.h hard-reg-set.h \
- $(BASIC_BLOCK_H) $(REGS_H) toplev.h output.h $(EXPR_H) \
+alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
+ hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) toplev.h output.h $(EXPR_H) \
$(GGC_H) function.h cselib.h $(TREE_H) $(TM_P_H) langhooks.h $(TARGET_H) \
- gt-alias.h
-regmove.o : regmove.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h \
+ gt-alias.h $(TIMEVAR_H) cgraph.h
+regmove.o : regmove.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) insn-config.h \
$(RECOG_H) output.h $(REGS_H) hard-reg-set.h flags.h function.h \
$(EXPR_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) except.h reload.h
-haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
+haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ sched-int.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
$(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(TARGET_H)
-sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
+sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ sched-int.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
$(INSN_ATTR_H) toplev.h $(RECOG_H) except.h cselib.h $(PARAMS_H) $(TM_P_H)
-sched-rgn.o : sched-rgn.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
+sched-rgn.o : sched-rgn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ sched-int.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
$(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(TARGET_H)
-sched-ebb.o : sched-ebb.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
- $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H)
-sched-vis.o : sched-vis.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) sched-int.h \
- hard-reg-set.h $(BASIC_BLOCK_H) $(INSN_ATTR_H) $(REGS_H) $(TM_P_H) \
+sched-ebb.o : sched-ebb.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ sched-int.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h function.h \
+ $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(PARAMS_H)
+sched-vis.o : sched-vis.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ sched-int.h hard-reg-set.h $(BASIC_BLOCK_H) $(INSN_ATTR_H) $(REGS_H) $(TM_P_H) \
$(TARGET_H) real.h
-final.o : final.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h intl.h \
- $(REGS_H) $(RECOG_H) conditions.h insn-config.h $(INSN_ATTR_H) function.h \
- real.h output.h hard-reg-set.h except.h debug.h xcoffout.h profile.h \
- toplev.h reload.h dwarf2out.h $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) $(EXPR_H)
-recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) function.h $(BASIC_BLOCK_H) \
- $(REGS_H) $(RECOG_H) $(EXPR_H) hard-reg-set.h flags.h insn-config.h \
+final.o : final.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ flags.h intl.h $(REGS_H) $(RECOG_H) conditions.h insn-config.h $(INSN_ATTR_H) \
+ function.h real.h output.h hard-reg-set.h except.h debug.h xcoffout.h \
+ toplev.h reload.h dwarf2out.h $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) \
+ $(EXPR_H)
+recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) function.h \
+ $(BASIC_BLOCK_H) $(REGS_H) $(RECOG_H) $(EXPR_H) hard-reg-set.h flags.h insn-config.h \
$(INSN_ATTR_H) real.h toplev.h output.h reload.h $(TM_P_H)
-reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) $(RECOG_H) \
- $(REGS_H) hard-reg-set.h flags.h insn-config.h toplev.h reload.h \
+reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ $(RECOG_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h toplev.h reload.h \
varray.h function.h $(TM_P_H) $(GGC_H) gt-reg-stack.h
-predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \
- insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
- $(RECOG_H) function.h except.h $(EXPR_H) $(TM_P_H) $(PREDICT_H) real.h \
- $(PARAMS_H) $(TARGET_H)
-lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) toplev.h $(RTL_H) $(GGC_H)
-bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
- flags.h $(BASIC_BLOCK_H) hard-reg-set.h output.h cfglayout.h $(TARGET_H)
-tracer.o : tracer.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
- $(BASIC_BLOCK_H) hard-reg-set.h output.h cfglayout.h flags.h \
- $(PARAMS_H) profile.h
-cfglayout.o : cfglayout.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
- insn-config.h $(BASIC_BLOCK_H) hard-reg-set.h output.h function.h \
- cfglayout.h
-timevar.o : timevar.c $(CONFIG_H) $(SYSTEM_H) $(TIMEVAR_H) flags.h intl.h
-regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h \
- $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h $(RECOG_H) function.h \
+sreal.o: sreal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) sreal.h
+predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ flags.h insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
+ $(RECOG_H) function.h except.h $(EXPR_H) $(TM_P_H) $(PREDICT_H) sreal.h \
+ $(PARAMS_H) $(TARGET_H) cfgloop.h $(COVERAGE_H)
+lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h $(RTL_H) $(GGC_H)
+bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(BASIC_BLOCK_H) flags.h timevar.h output.h cfglayout.h $(FIBHEAP_H) \
+ $(TARGET_H)
+tracer.o : tracer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
+ $(BASIC_BLOCK_H) hard-reg-set.h output.h cfglayout.h flags.h timevar.h \
+ $(PARAMS_H) $(COVERAGE_H)
+cfglayout.o : cfglayout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(TREE_H) insn-config.h $(BASIC_BLOCK_H) hard-reg-set.h output.h \
+ function.h cfglayout.h cfgloop.h $(TARGET_H) gt-cfglayout.h $(GGC_H)
+timevar.o : timevar.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TIMEVAR_H) flags.h \
+ intl.h toplev.h
+regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h $(RECOG_H) function.h \
resource.h $(OBSTACK_H) flags.h $(TM_P_H)
-ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) toplev.h \
- flags.h insn-config.h function.h $(RECOG_H) $(BASIC_BLOCK_H) $(EXPR_H) \
- output.h except.h $(TM_P_H) real.h
-params.o : params.c $(CONFIG_H) $(SYSTEM_H) $(PARAMS_H) toplev.h
-hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) $(HOOKS_H)
-
-$(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) $(GGC_H) \
+ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ $(REGS_H) toplev.h flags.h insn-config.h function.h $(RECOG_H) $(TARGET_H) \
+ $(BASIC_BLOCK_H) $(EXPR_H) output.h except.h $(TM_P_H) real.h $(OPTABS_H) \
+ cfgloop.h
+params.o : params.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(PARAMS_H) toplev.h
+hooks.o: hooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(HOOKS_H)
+pretty-print.o: $(CONFIG_H) $(SYSTEM_H) pretty-print.c $(PRETTY_PRINT_H)
+
+$(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) $(GGC_H) \
$(RTL_H) $(REGS_H) hard-reg-set.h real.h insn-config.h conditions.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) $(OPTABS_H) \
@@ -1678,12 +1848,21 @@ $(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) $(GGC_H) \
mips-tfile: mips-tfile.o version.o $(LIBDEPS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tfile.o version.o $(LIBS)
-mips-tfile.o : mips-tfile.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) version.h
+mips-tfile.o : mips-tfile.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) coretypes.h $(TM_H) version.h
mips-tdump: mips-tdump.o version.o $(LIBDEPS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ mips-tdump.o version.o $(LIBS)
-mips-tdump.o : mips-tdump.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H)
+mips-tdump.o : mips-tdump.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) coretypes.h $(TM_H) version.h
+
+# FIXME: writing proper dependencies for this is a *LOT* of work.
+libbackend.o : $(OBJS-common:.o=.c) $(out_file) \
+ insn-config.h insn-flags.h insn-codes.h insn-constants.h \
+ insn-attr.h
+ $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ -DTARGET_NAME=\"$(target_noncanonical)\" \
+ -DLOCALEDIR=\"$(localedir)\" \
+ -c $(filter %.c,$^) -o $@
#
# Generate header and source files from the machine description,
@@ -1724,14 +1903,14 @@ s-conditions : $(md_file) genconditions$(build_exeext) $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-conditions.c insn-conditions.c
$(STAMP) s-conditions
-insn-conditions.o : insn-conditions.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) \
- $(TM_P_H) $(REGS_H) function.h $(RECOG_H) real.h output.h flags.h \
- hard-reg-set.h resource.h toplev.h reload.h gensupport.h insn-constants.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) insn-conditions.c
+insn-conditions.o : insn-conditions.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(GTM_H) $(RTL_H) $(TM_P_H) $(REGS_H) function.h $(RECOG_H) real.h output.h \
+ flags.h hard-reg-set.h resource.h toplev.h reload.h gensupport.h \
+ insn-constants.h
+ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) insn-conditions.c
-dummy-conditions.o : dummy-conditions.c $(HCONFIG_H) $(SYSTEM_H) gensupport.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
- $(srcdir)/dummy-conditions.c $(OUTPUT_OPTION)
+dummy-conditions.o : dummy-conditions.c $(BCONFIG_H) $(SYSTEM_H) \
+ coretypes.h $(GTM_H) gensupport.h
insn-flags.h: s-flags ; @true
s-flags : $(md_file) genflags$(build_exeext) $(srcdir)/move-if-change
@@ -1751,9 +1930,9 @@ s-constants : $(md_file) genconstants$(build_exeext) $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-constants.h insn-constants.h
$(STAMP) s-constants
-insn-emit.o : insn-emit.c $(CONFIG_H) $(RTL_H) $(EXPR_H) real.h output.h \
- insn-config.h $(OPTABS_H) $(SYSTEM_H) reload.h $(RECOG_H) toplev.h \
- function.h flags.h hard-reg-set.h resource.h $(TM_P_H)
+insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(EXPR_H) real.h output.h insn-config.h $(OPTABS_H) reload.h \
+ $(RECOG_H) toplev.h function.h flags.h hard-reg-set.h resource.h $(TM_P_H)
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-emit.c \
$(OUTPUT_OPTION)
@@ -1763,9 +1942,9 @@ s-emit : $(md_file) genemit$(build_exeext) $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-emit.c insn-emit.c
$(STAMP) s-emit
-insn-recog.o : insn-recog.c $(CONFIG_H) $(RTL_H) insn-config.h $(RECOG_H) \
- real.h output.h flags.h $(SYSTEM_H) function.h hard-reg-set.h resource.h \
- $(TM_P_H) toplev.h reload.h
+insn-recog.o : insn-recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) insn-config.h $(RECOG_H) real.h output.h flags.h function.h \
+ hard-reg-set.h resource.h $(TM_P_H) toplev.h reload.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-recog.c \
$(OUTPUT_OPTION)
@@ -1775,8 +1954,8 @@ s-recog : $(md_file) genrecog$(build_exeext) $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-recog.c insn-recog.c
$(STAMP) s-recog
-insn-opinit.o : insn-opinit.c $(CONFIG_H) $(RTL_H) \
- insn-config.h flags.h $(RECOG_H) $(EXPR_H) $(OPTABS_H) reload.h $(SYSTEM_H)
+insn-opinit.o : insn-opinit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) insn-config.h flags.h $(RECOG_H) $(EXPR_H) $(OPTABS_H) reload.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-opinit.c \
$(OUTPUT_OPTION)
@@ -1786,8 +1965,8 @@ s-opinit : $(md_file) genopinit$(build_exeext) $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-opinit.c insn-opinit.c
$(STAMP) s-opinit
-insn-extract.o : insn-extract.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) toplev.h \
- insn-config.h $(RECOG_H)
+insn-extract.o : insn-extract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) toplev.h insn-config.h $(RECOG_H)
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-extract.c \
$(OUTPUT_OPTION)
@@ -1797,8 +1976,9 @@ s-extract : $(md_file) genextract$(build_exeext) $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-extract.c insn-extract.c
$(STAMP) s-extract
-insn-peep.o : insn-peep.c $(CONFIG_H) $(RTL_H) $(REGS_H) output.h real.h \
- $(SYSTEM_H) insn-config.h $(RECOG_H) except.h function.h $(TM_P_H)
+insn-peep.o : insn-peep.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(REGS_H) output.h real.h insn-config.h $(RECOG_H) except.h \
+ function.h $(TM_P_H)
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-peep.c \
$(OUTPUT_OPTION)
@@ -1808,9 +1988,9 @@ s-peep : $(md_file) genpeep$(build_exeext) $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-peep.c insn-peep.c
$(STAMP) s-peep
-insn-attrtab.o : insn-attrtab.c $(CONFIG_H) $(RTL_H) $(REGS_H) real.h \
- output.h $(INSN_ATTR_H) insn-config.h $(SYSTEM_H) toplev.h $(RECOG_H) \
- $(TM_P_H) flags.h
+insn-attrtab.o : insn-attrtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(REGS_H) real.h output.h $(INSN_ATTR_H) insn-config.h toplev.h \
+ $(RECOG_H) $(TM_P_H) flags.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-attrtab.c \
$(OUTPUT_OPTION)
@@ -1826,10 +2006,10 @@ s-attrtab : $(md_file) genattrtab$(build_exeext) $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-attrtab.c insn-attrtab.c
$(STAMP) s-attrtab
-insn-output.o : insn-output.c $(CONFIG_H) $(RTL_H) $(GGC_H) $(REGS_H) real.h \
- conditions.h hard-reg-set.h insn-config.h $(INSN_ATTR_H) $(EXPR_H) \
- output.h $(RECOG_H) function.h $(SYSTEM_H) toplev.h flags.h \
- insn-codes.h $(TM_P_H)
+insn-output.o : insn-output.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(GGC_H) $(REGS_H) real.h conditions.h hard-reg-set.h \
+ insn-config.h $(INSN_ATTR_H) $(EXPR_H) output.h $(RECOG_H) function.h \
+ toplev.h flags.h insn-codes.h $(TM_P_H) $(TARGET_H)
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-output.c \
$(OUTPUT_OPTION)
@@ -1839,17 +2019,31 @@ s-output : $(md_file) genoutput$(build_exeext) $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-output.c insn-output.c
$(STAMP) s-output
-genrtl.o : genrtl.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) $(GGC_H)
+genrtl.o : genrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
+ $(GGC_H)
genrtl.c genrtl.h : s-genrtl
@true # force gnu make to recheck modification times.
-s-genrtl: gengenrtl$(build_exeext) $(srcdir)/move-if-change $(RTL_BASE_H)
+s-genrtl: gengenrtl$(build_exeext) $(srcdir)/move-if-change
$(RUN_GEN) ./gengenrtl$(build_exeext) -h > tmp-genrtl.h
$(SHELL) $(srcdir)/move-if-change tmp-genrtl.h genrtl.h
$(RUN_GEN) ./gengenrtl$(build_exeext) > tmp-genrtl.c
$(SHELL) $(srcdir)/move-if-change tmp-genrtl.c genrtl.c
$(STAMP) s-genrtl
+insn-modes.o : insn-modes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(MACHMODE_H) real.h
+min-insn-modes.c insn-modes.c insn-modes.h : s-modes ; @true
+
+s-modes: genmodes$(build_exeext) $(srcdir)/move-if-change
+ $(RUN_GEN) ./genmodes$(build_exeext) -h > tmp-modes.h
+ $(SHELL) $(srcdir)/move-if-change tmp-modes.h insn-modes.h
+ $(RUN_GEN) ./genmodes$(build_exeext) -m > tmp-min-modes.c
+ $(SHELL) $(srcdir)/move-if-change tmp-min-modes.c min-insn-modes.c
+ $(RUN_GEN) ./genmodes$(build_exeext) > tmp-modes.c
+ $(SHELL) $(srcdir)/move-if-change tmp-modes.c insn-modes.c
+ $(STAMP) s-modes
+
tm-preds.h: s-preds; @true
s-preds: genpreds$(build_exeext) $(srcdir)/move-if-change
@@ -1857,22 +2051,22 @@ s-preds: genpreds$(build_exeext) $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-preds.h tm-preds.h
$(STAMP) s-preds
-GTFILES = $(GCONFIG_H) $(srcdir)/location.h \
- $(HASHTAB_H) \
- $(srcdir)/bitmap.h $(srcdir)/function.h $(srcdir)/rtl.h $(srcdir)/optabs.h \
- $(srcdir)/tree.h $(srcdir)/libfuncs.h $(srcdir)/hashtable.h $(srcdir)/real.h \
- $(srcdir)/varray.h $(srcdir)/ssa.h $(srcdir)/insn-addr.h $(srcdir)/cselib.h \
+GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h $(srcdir)/cpplib.h \
+ $(host_xm_file_list) $(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) \
+ $(srcdir)/bitmap.h $(srcdir)/coverage.c $(srcdir)/function.h $(srcdir)/rtl.h \
+ $(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/libfuncs.h $(srcdir)/hashtable.h \
+ $(srcdir)/real.h $(srcdir)/varray.h $(srcdir)/insn-addr.h \
+ $(srcdir)/cselib.h $(srcdir)/basic-block.h $(srcdir)/cgraph.h \
$(srcdir)/c-common.h $(srcdir)/c-tree.h \
- $(srcdir)/basic-block.h \
- $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c \
- $(srcdir)/dwarf2out.c $(srcdir)/emit-rtl.c \
- $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \
+ $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
+ $(srcdir)/dbxout.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \
+ $(srcdir)/emit-rtl.c $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \
$(srcdir)/fold-const.c $(srcdir)/function.c \
$(srcdir)/gcse.c $(srcdir)/integrate.c $(srcdir)/lists.c $(srcdir)/optabs.c \
$(srcdir)/profile.c $(srcdir)/ra-build.c $(srcdir)/regclass.c \
- $(srcdir)/reg-stack.c \
+ $(srcdir)/reg-stack.c $(srcdir)/cfglayout.c $(srcdir)/langhooks.c \
$(srcdir)/sdbout.c $(srcdir)/stmt.c $(srcdir)/stor-layout.c \
- $(srcdir)/tree.c $(srcdir)/varasm.c \
+ $(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
$(out_file) \
@all_gtfiles@
@@ -1881,36 +2075,37 @@ GTFILES_FILES_FILES = @all_gtfiles_files_files@
GTFILES_LANG_DIR_NAMES = @subdirs@
GTFILES_SRCDIR = @srcdir@
-gtype-desc.h gtype-desc.c gt-except.h gt-function.h : s-gtype; @true
-gt-integrate.h gt-stmt.h gt-tree.h gt-varasm.h gt-emit-rtl.h : s-gtype; @true
-gt-explow.h gt-stor-layout.h gt-regclass.h gt-lists.h : s-gtype; @true
-gt-alias.h gt-cselib.h gt-fold-const.h gt-gcse.h gt-profile.h : s-gtype; @true
-gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h gt-dwarf2out.h : s-gtype ; @true
-gt-ra-build.h gt-reg-stack.h : s-gtype ; @true
-gt-c-common.h gt-c-decl.h gt-c-parse.h gt-c-pragma.h : s-gtype; @true
-gt-c-objc-common.h gtype-c.h gt-location.h : s-gtype ; @true
+gt-cgraph.h gt-coverage.h gtype-desc.h gtype-desc.c gt-except.h \
+gt-function.h gt-integrate.h gt-stmt.h gt-tree.h gt-varasm.h \
+gt-emit-rtl.h gt-explow.h gt-stor-layout.h gt-regclass.h \
+gt-lists.h gt-alias.h gt-cselib.h gt-fold-const.h gt-gcse.h \
+gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h \
+gt-dwarf2out.h gt-ra-build.h gt-reg-stack.h gt-dwarf2asm.h \
+gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parse.h \
+gt-c-pragma.h gtype-c.h gt-input.h gt-cfglayout.h \
+gt-stringpool.h gt-langhooks.h : s-gtype ; @true
gtyp-gen.h: Makefile
echo "/* This file is machine generated. Do not edit. */" > tmp-gtyp.h
- echo "static const char *srcdir = " >> tmp-gtyp.h
+ echo "static const char *const srcdir = " >> tmp-gtyp.h
echo "\"$(GTFILES_SRCDIR)\"" >> tmp-gtyp.h
echo ";" >> tmp-gtyp.h
- echo "static const char *lang_files[] = {" >> tmp-gtyp.h
+ echo "static const char *const lang_files[] = {" >> tmp-gtyp.h
ll="$(GTFILES_FILES_FILES)"; \
for f in $$ll; do \
echo "\"$$f\", "; done >> tmp-gtyp.h
echo "NULL};" >> tmp-gtyp.h
- echo "static const char *langs_for_lang_files[] = {" >> tmp-gtyp.h
+ echo "static const char *const langs_for_lang_files[] = {" >> tmp-gtyp.h
ff="$(GTFILES_FILES_LANGS)"; \
for f in $$ff; do \
echo "\"$$f\", " ; done >> tmp-gtyp.h
echo "NULL};" >> tmp-gtyp.h
- echo "static const char *all_files[] = {" >> tmp-gtyp.h
+ echo "static const char *const all_files[] = {" >> tmp-gtyp.h
gf="$(GTFILES)"; \
for f in $$gf; do \
echo "\"$$f\", "; done >> tmp-gtyp.h
echo " NULL};" >> tmp-gtyp.h
- echo "static const char *lang_dir_names[] = { \"c\", " >> tmp-gtyp.h
+ echo "static const char *const lang_dir_names[] = { \"c\", " >> tmp-gtyp.h
gf="$(GTFILES_LANG_DIR_NAMES)"; \
for l in $$gf; do \
echo "\"$$l\", "; done >> tmp-gtyp.h
@@ -1923,7 +2118,7 @@ s-gtype: gengtype$(build_exeext) $(GTFILES)
#
# Compile the programs that generate insn-* from the machine description.
-# They are compiled with $(HOST_CC), and associated libraries,
+# They are compiled with $(CC_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.
@@ -1932,280 +2127,211 @@ s-gtype: gengtype$(build_exeext) $(GTFILES)
# about the target machine. They do depend on config.h itself,
# since that describes the host machine.
-read-rtl.o: read-rtl.c $(HCONFIG_H) $(SYSTEM_H) $(RTL_H) \
+# The names of programs that run on the "build" machine.
+genprognames=genconfig genflags gencodes genemit genopinit genrecog \
+ genextract genpeep genattr genoutput
+
+# The names of the executable files for those programs.
+genprogs=$(genprognames:%=%$(build_exeext))
+
+# Object files used in those programs.
+genobjs=$(genprognames:%=%.o) read-rtl.o gensupport.o genattrtab.o \
+ genautomata.o gengenrtl.o genmodes.o genpreds.o gengtype.o \
+ genconstants.o gen-protos.o scan.o fix-header.o scan-decls.o \
+ gencheck.o dummy-conditions.o genconditions.o
+
+$(genprogs): %$(build_exeext): %.o $(BUILD_RTL) $(BUILD_SUPPORT) \
+ $(BUILD_PRINT) $(BUILD_ERRORS) \
+ $(BUILD_LIBDEPS)
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
+ $< $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) \
+ $(BUILD_ERRORS) $(BUILD_LIBS)
+
+$(genobjs): %.o : %.c
+ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+
+read-rtl.o: read-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) $(RTL_H) \
$(OBSTACK_H) $(HASHTAB_H)
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/read-rtl.c $(OUTPUT_OPTION)
-
-gensupport.o: gensupport.c $(RTL_H) $(OBSTACK_H) $(SYSTEM_H) errors.h gensupport.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gensupport.c $(OUTPUT_OPTION)
-
-genconfig$(build_exeext) : genconfig.o $(HOST_RTL) $(HOST_SUPPORT) \
- $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- genconfig.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
- $(HOST_ERRORS) $(HOST_LIBS)
-
-genconfig.o : genconfig.c $(RTL_H) $(HCONFIG_H) \
- $(SYSTEM_H) errors.h gensupport.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genconfig.c $(OUTPUT_OPTION)
-
-genflags$(build_exeext) : genflags.o $(HOST_RTL) $(HOST_SUPPORT) \
- $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- genflags.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
- $(HOST_ERRORS) $(HOST_LIBS)
-
-genflags.o : genflags.c $(RTL_H) $(OBSTACK_H) $(HCONFIG_H) \
- $(SYSTEM_H) errors.h gensupport.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genflags.c $(OUTPUT_OPTION)
-
-gencodes$(build_exeext) : gencodes.o $(HOST_RTL) $(HOST_SUPPORT) \
- $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- gencodes.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
- $(HOST_ERRORS) $(HOST_LIBS)
-
-gencodes.o : gencodes.c $(RTL_H) $(HCONFIG_H) \
- $(SYSTEM_H) errors.h gensupport.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gencodes.c $(OUTPUT_OPTION)
-
-genconstants$(build_exeext) : genconstants.o $(HOST_RTL) $(HOST_EARLY_SUPPORT) \
- $(HOST_ERRORS) $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- genconstants.o $(HOST_EARLY_SUPPORT) $(HOST_RTL) \
- $(HOST_ERRORS) $(HOST_LIBS)
-
-genconstants.o : genconstants.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genconstants.c $(OUTPUT_OPTION)
-
-genemit$(build_exeext) : genemit.o $(HOST_RTL) $(HOST_SUPPORT) \
- $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- genemit.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
- $(HOST_ERRORS) $(HOST_LIBS)
-
-genemit.o : genemit.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h gensupport.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genemit.c $(OUTPUT_OPTION)
-
-genopinit$(build_exeext) : genopinit.o $(HOST_RTL) $(HOST_SUPPORT) \
- $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- genopinit.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
- $(HOST_ERRORS) $(HOST_LIBS)
-
-genopinit.o : genopinit.c $(RTL_H) $(HCONFIG_H) \
- $(SYSTEM_H) errors.h gensupport.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genopinit.c $(OUTPUT_OPTION)
-
-genrecog$(build_exeext) : genrecog.o $(HOST_RTL) $(HOST_SUPPORT) \
- $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- genrecog.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
- $(HOST_ERRORS) $(HOST_LIBS)
-
-genrecog.o : genrecog.c $(RTL_H) $(HCONFIG_H) \
- $(SYSTEM_H) errors.h gensupport.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genrecog.c $(OUTPUT_OPTION)
-
-genextract$(build_exeext) : genextract.o $(HOST_RTL) $(HOST_SUPPORT) \
- $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- genextract.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
- $(HOST_ERRORS) $(HOST_LIBS)
-
-genextract.o : genextract.c $(RTL_H) $(HCONFIG_H) \
- $(SYSTEM_H) insn-config.h errors.h gensupport.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genextract.c $(OUTPUT_OPTION)
-
-genpeep$(build_exeext) : genpeep.o $(HOST_RTL) $(HOST_SUPPORT) \
- $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- genpeep.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
- $(HOST_ERRORS) $(HOST_LIBS)
-
-genpeep.o : genpeep.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h gensupport.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genpeep.c $(OUTPUT_OPTION)
-
-genattr$(build_exeext) : genattr.o $(HOST_RTL) $(HOST_SUPPORT) \
- $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- genattr.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
- $(HOST_ERRORS) $(HOST_LIBS)
-
-genattr.o : genattr.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h gensupport.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genattr.c $(OUTPUT_OPTION)
+
+gensupport.o: gensupport.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) $(RTL_H) \
+ $(OBSTACK_H) errors.h $(HASHTAB_H) gensupport.h
+
+genconfig.o : genconfig.c $(RTL_H) $(BCONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
+
+genflags.o : genflags.c $(RTL_H) $(OBSTACK_H) $(BCONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
+
+gencodes.o : gencodes.c $(RTL_H) $(BCONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
+
+genconstants$(build_exeext) : genconstants.o $(BUILD_RTL) $(BUILD_EARLY_SUPPORT) \
+ $(BUILD_ERRORS) $(BUILD_LIBDEPS)
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
+ genconstants.o $(BUILD_EARLY_SUPPORT) $(BUILD_RTL) \
+ $(BUILD_ERRORS) $(BUILD_LIBS)
+
+genconstants.o : genconstants.c $(RTL_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) \
+ errors.h
+
+genemit.o : genemit.c $(RTL_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) \
+ errors.h gensupport.h
+
+genopinit.o : genopinit.c $(RTL_H) $(BCONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
+
+genrecog.o : genrecog.c $(RTL_H) $(BCONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
+
+genextract.o : genextract.c $(RTL_H) $(BCONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(GTM_H) insn-config.h errors.h gensupport.h
+
+genpeep.o : genpeep.c $(RTL_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) \
+ errors.h gensupport.h
+
+genattr.o : genattr.c $(RTL_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) errors.h \
+ gensupport.h
genattrtab$(build_exeext) : genattrtab.o genautomata.o \
- $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_VARRAY) \
- $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
+ $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) $(BUILD_ERRORS) $(BUILD_VARRAY) \
+ $(BUILD_LIBDEPS)
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
genattrtab.o genautomata.o \
- $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) $(HOST_ERRORS) \
- $(HOST_VARRAY) $(HOST_LIBS) -lm
+ $(BUILD_RTL) $(BUILD_SUPPORT) $(BUILD_PRINT) $(BUILD_ERRORS) \
+ $(BUILD_VARRAY) $(BUILD_LIBS) -lm
+
+genattrtab.o : genattrtab.c $(RTL_H) $(OBSTACK_H) $(BCONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(GTM_H) errors.h $(GGC_H) gensupport.h genattrtab.h
-genattrtab.o : genattrtab.c $(RTL_H) $(OBSTACK_H) $(HCONFIG_H) \
- $(SYSTEM_H) errors.h $(GGC_H) gensupport.h genattrtab.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genattrtab.c $(OUTPUT_OPTION)
+genautomata.o : genautomata.c $(RTL_H) $(OBSTACK_H) $(BCONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(GTM_H) errors.h varray.h genattrtab.h $(HASHTAB_H)
-genautomata.o : genautomata.c $(RTL_H) $(OBSTACK_H) $(HCONFIG_H) \
- $(SYSTEM_H) errors.h varray.h genattrtab.h $(HASHTAB_H)
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genautomata.c $(OUTPUT_OPTION)
+genoutput.o : genoutput.c $(RTL_H) $(BCONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
-genoutput$(build_exeext) : genoutput.o $(HOST_RTL) $(HOST_SUPPORT) \
- $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- genoutput.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
- $(HOST_ERRORS) $(HOST_LIBS)
+gengenrtl$(build_exeext) : gengenrtl.o $(BUILD_LIBDEPS)
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
+ gengenrtl.o $(BUILD_LIBS)
-genoutput.o : genoutput.c $(RTL_H) $(HCONFIG_H) \
- $(SYSTEM_H) errors.h gensupport.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genoutput.c $(OUTPUT_OPTION)
+gengenrtl.o : gengenrtl.c $(BCONFIG_H) $(SYSTEM_H) rtl.def
-gengenrtl$(build_exeext) : gengenrtl.o $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- gengenrtl.o $(HOST_LIBS)
+genmodes$(build_exeext) : genmodes.o $(BUILD_ERRORS) $(BUILD_LIBDEPS)
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
+ genmodes.o $(BUILD_ERRORS) $(BUILD_LIBS)
-gengenrtl.o : gengenrtl.c $(RTL_BASE_H) $(HCONFIG_H) $(SYSTEM_H) real.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gengenrtl.c $(OUTPUT_OPTION)
+genmodes.o : genmodes.c $(BCONFIG_H) $(SYSTEM_H) errors.h $(HASHTAB_H) \
+ machmode.def $(extra_modes_file)
-genpreds$(build_exeext) : genpreds.o $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- genpreds.o $(HOST_LIBS)
+genpreds$(build_exeext) : genpreds.o $(BUILD_LIBDEPS)
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
+ genpreds.o $(BUILD_LIBS)
-genpreds.o : genpreds.c $(RTL_BASE_H) $(HCONFIG_H) $(SYSTEM_H)
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genpreds.c $(OUTPUT_OPTION)
+genpreds.o : genpreds.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H)
gengtype$(build_exeext) : gengtype.o gengtype-lex.o gengtype-yacc.o \
- $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- gengtype.o gengtype-lex.o gengtype-yacc.o $(HOST_LIBS)
-
-gengtype.o : gengtype.c gengtype.h $(HCONFIG_H) $(SYSTEM_H) real.h rtl.def \
- gtyp-gen.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
- $(srcdir)/gengtype.c $(OUTPUT_OPTION)
-
-gengtype-lex.o : $(srcdir)/gengtype-lex.c gengtype.h $(srcdir)/gengtype-yacc.c \
- $(HCONFIG_H) $(SYSTEM_H)
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
- $(srcdir)/gengtype-lex.c $(OUTPUT_OPTION)
-
-gengtype-yacc.o : $(srcdir)/gengtype-yacc.c gengtype.h $(HCONFIG_H) $(SYSTEM_H)
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
- $(srcdir)/gengtype-yacc.c $(OUTPUT_OPTION)
-
-# The sed command works around a bug in flex-2.5.4.
-$(srcdir)/gengtype-lex.c : $(srcdir)/gengtype-lex.l
- cd $(srcdir) && \
- $(FLEX) $(FLEXFLAGS) -t -o$@ gengtype-lex.l | \
- sed 's/^\(char msg\[\];\)/yyconst \1/' > g-$$$$ ; \
- if test $$? -eq 0 ; then \
- mv -f g-$$$$ gengtype-lex.c ; \
- else \
- rm -f g-$$$$.* ; \
- false ; \
- fi
+ $(BUILD_LIBDEPS)
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
+ gengtype.o gengtype-lex.o gengtype-yacc.o $(BUILD_LIBS)
+
+gengtype.o : gengtype.c gengtype.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) \
+ real.h $(RTL_BASE_H) gtyp-gen.h
+
+gengtype-lex.o : gengtype-lex.c gengtype.h gengtype-yacc.h \
+ $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H)
+ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \
+ $< $(OUTPUT_OPTION)
-$(srcdir)/gengtype-yacc.c: $(srcdir)/gengtype-yacc.y
- (cd $(srcdir) && \
- $(BISON) $(BISONFLAGS) -d -o gengtype-yacc.c gengtype-yacc.y || \
- ( rm -f $@ && false ) )
+gengtype-yacc.o : gengtype-yacc.c gengtype.h $(BCONFIG_H) $(SYSTEM_H) \
+ coretypes.h $(GTM_H)
+ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \
+ $< $(OUTPUT_OPTION)
-genconditions$(build_exeext) : genconditions.o $(HOST_EARLY_SUPPORT) \
- $(HOST_RTL) $(HOST_ERRORS) $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- genconditions.o $(HOST_EARLY_SUPPORT) $(HOST_RTL) \
- $(HOST_ERRORS) $(HOST_LIBS)
+gengtype-lex.c : gengtype-lex.l
+ -$(FLEX) $(FLEXFLAGS) -o$@ $<
-genconditions.o : genconditions.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
- $(srcdir)/genconditions.c $(OUTPUT_OPTION)
+gengtype-yacc.c gengtype-yacc.h: gengtype-yacc.y
+ -$(BISON) $(BISONFLAGS) -d -o gengtype-yacc.c $<
+
+genconditions$(build_exeext) : genconditions.o $(BUILD_EARLY_SUPPORT) \
+ $(BUILD_RTL) $(BUILD_ERRORS) $(BUILD_LIBDEPS)
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
+ genconditions.o $(BUILD_EARLY_SUPPORT) $(BUILD_RTL) \
+ $(BUILD_ERRORS) $(BUILD_LIBS)
+
+genconditions.o : genconditions.c $(RTL_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(GTM_H) errors.h
#
# Compile the libraries to be used by gen*.
# If we are not cross-building, gen* use the same .o's that cc1 will use,
# and BUILD_PREFIX_1 is `loser-', just to ensure these rules don't conflict
# with the rules for rtl.o, etc.
-$(BUILD_PREFIX_1)rtl.o: $(srcdir)/rtl.c $(HCONFIG_H) $(SYSTEM_H) $(RTL_H) \
+$(BUILD_PREFIX_1)rtl.o: $(srcdir)/rtl.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) $(RTL_H) \
real.h $(GGC_H) errors.h
rm -f $(BUILD_PREFIX)rtl.c
- sed -e 's/config[.]h/hconfig.h/' $(srcdir)/rtl.c > $(BUILD_PREFIX)rtl.c
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)rtl.c $(OUTPUT_OPTION)
+ sed -e 's/config[.]h/bconfig.h/' $(srcdir)/rtl.c > $(BUILD_PREFIX)rtl.c
+ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)rtl.c $(OUTPUT_OPTION)
-print-rtl1.o: $(srcdir)/print-rtl.c $(HCONFIG_H) \
- $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H)
+print-rtl1.o: $(srcdir)/print-rtl.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(GTM_H) $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H)
rm -f print-rtl1.c
- sed -e 's/config[.]h/hconfig.h/' $(srcdir)/print-rtl.c > print-rtl1.c
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) print-rtl1.c $(OUTPUT_OPTION)
+ sed -e 's/config[.]h/bconfig.h/' $(srcdir)/print-rtl.c > print-rtl1.c
+ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) print-rtl1.c $(OUTPUT_OPTION)
-$(BUILD_PREFIX_1)bitmap.o: $(srcdir)/bitmap.c $(HCONFIG_H) $(SYSTEM_H) \
+$(BUILD_PREFIX_1)bitmap.o: $(srcdir)/bitmap.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) \
$(RTL_H) flags.h $(BASIC_BLOCK_H) $(REGS_H) $(GGC_H)
rm -f $(BUILD_PREFIX)bitmap.c
- sed -e 's/config[.]h/hconfig.h/' $(srcdir)/bitmap.c > $(BUILD_PREFIX)bitmap.c
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)bitmap.c $(OUTPUT_OPTION)
+ sed -e 's/config[.]h/bconfig.h/' $(srcdir)/bitmap.c > $(BUILD_PREFIX)bitmap.c
+ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)bitmap.c $(OUTPUT_OPTION)
-$(BUILD_PREFIX_1)errors.o: errors.c $(HCONFIG_H) $(SYSTEM_H) errors.h
+$(BUILD_PREFIX_1)errors.o: errors.c $(BCONFIG_H) $(SYSTEM_H) errors.h
rm -f $(BUILD_PREFIX)errors.c
- sed -e 's/config[.]h/hconfig.h/' $(srcdir)/errors.c > $(BUILD_PREFIX)errors.c
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)errors.c $(OUTPUT_OPTION)
+ sed -e 's/config[.]h/bconfig.h/' $(srcdir)/errors.c > $(BUILD_PREFIX)errors.c
+ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)errors.c $(OUTPUT_OPTION)
-$(BUILD_PREFIX_1)varray.o: varray.c $(HCONFIG_H) $(SYSTEM_H) varray.h \
+$(BUILD_PREFIX_1)varray.o: varray.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) varray.h \
$(RTL_H) $(GGC_H) $(TREE_H) bitmap.h errors.h
rm -f $(BUILD_PREFIX)varray.c
- sed -e 's/config[.]h/hconfig.h/' $(srcdir)/varray.c > \
+ sed -e 's/config[.]h/bconfig.h/' $(srcdir)/varray.c > \
$(BUILD_PREFIX)varray.c
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
+ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \
$(BUILD_PREFIX)varray.c $(OUTPUT_OPTION)
-$(BUILD_PREFIX_1)ggc-none.o: ggc-none.c $(HCONFIG_H) $(SYSTEM_H) $(GGC_H)
+$(BUILD_PREFIX_1)ggc-none.o: ggc-none.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) $(GGC_H)
rm -f $(BUILD_PREFIX)ggc-none.c
- sed -e 's/config[.]h/hconfig.h/' $(srcdir)/ggc-none.c > $(BUILD_PREFIX)ggc-none.c
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)ggc-none.c $(OUTPUT_OPTION)
+ sed -e 's/config[.]h/bconfig.h/' $(srcdir)/ggc-none.c > $(BUILD_PREFIX)ggc-none.c
+ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(BUILD_PREFIX)ggc-none.c $(OUTPUT_OPTION)
+
+min-insn-modes.o: min-insn-modes.c $(BCONFIG_H) $(SYSTEM_H) $(MACHMODE_H)
+ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \
+ min-insn-modes.c $(OUTPUT_OPTION)
#
# Remake internationalization support.
-intl.o: intl.c $(CONFIG_H) system.h intl.h Makefile
+intl.o: intl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h Makefile
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DLOCALEDIR=\"$(localedir)\" \
-c $(srcdir)/intl.c $(OUTPUT_OPTION)
-$(top_builddir)/intl/libintl.a: intl.all
-
-intl.all intl.install intl.uninstall \
- intl.mostlyclean intl.clean intl.distclean intl.maintainer-clean:
- @for d in $(INTL_SUBDIRS); do \
- target=`expr $@ : 'intl.\(.*\)'` && \
- echo "(cd $$d && $(MAKE) $$target)" && \
- (cd $$d && AWK='$(AWK)' $(MAKE) $(SUBDIR_FLAGS_TO_PASS) $$target); \
- if [ $$? -eq 0 ] ; then true ; else exit 1 ; fi ; \
- done
-
-# intl.all and intl.install need config.h to exist, and the files it includes.
-# (FIXME: intl/*.c shouldn't need to see insn-foo.h!)
-intl.all intl.install: config.h insn-flags.h insn-constants.h
-
-# Make-lang.in should add dependencies of po-generated on any generated
-# files which need to be scanned by gettext (usually Yacc-generated parsers).
-po-generated: c-parse.c
-
#
# Remake cpp and protoize.
PREPROCESSOR_DEFINES = \
-DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \
-DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \
- -DGPLUSPLUS_TOOL_INCLUDE_DIR=\"$(gcc_gxx_include_dir)/$(target_alias)\" \
+ -DGPLUSPLUS_TOOL_INCLUDE_DIR=\"$(gcc_gxx_include_dir)/$(target_noncanonical)\" \
-DGPLUSPLUS_BACKWARD_INCLUDE_DIR=\"$(gcc_gxx_include_dir)/backward\" \
-DLOCAL_INCLUDE_DIR=\"$(local_includedir)\" \
- -DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \
- -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\"
+ -DCROSS_INCLUDE_DIR=\"$(CROSS_SYSTEM_HEADER_DIR)\" \
+ -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" \
+ @TARGET_SYSTEM_ROOT_DEFINE@
LIBCPP_OBJS = cpplib.o cpplex.o cppmacro.o cppexp.o cppfiles.o cpptrad.o \
- cpphash.o cpperror.o cppinit.o cppdefault.o cppmain.o \
- hashtable.o line-map.o mkdeps.o prefix.o mbchar.o
+ cpphash.o cpperror.o cppinit.o cppcharset.o \
+ hashtable.o line-map.o mkdeps.o cpppch.o
LIBCPP_DEPS = $(CPPLIB_H) cpphash.h line-map.h hashtable.h intl.h \
- $(OBSTACK_H) $(SYSTEM_H)
+ $(OBSTACK_H) $(CONFIG_H) $(SYSTEM_H)
# Most of the other archives built/used by this makefile are for
# targets. This one is strictly for the host.
@@ -2214,25 +2340,27 @@ libcpp.a: $(LIBCPP_OBJS)
$(AR) $(AR_FLAGS) libcpp.a $(LIBCPP_OBJS)
-$(RANLIB) libcpp.a
-cppmain.o: cppmain.c $(CONFIG_H) $(LIBCPP_DEPS)
-
-cpperror.o: cpperror.c $(CONFIG_H) $(LIBCPP_DEPS)
-cppexp.o: cppexp.c $(CONFIG_H) $(LIBCPP_DEPS)
-cpplex.o: cpplex.c $(CONFIG_H) $(LIBCPP_DEPS) mbchar.h
-cppmacro.o: cppmacro.c $(CONFIG_H) $(LIBCPP_DEPS)
-cpplib.o: cpplib.c $(CONFIG_H) $(LIBCPP_DEPS)
-cpphash.o: cpphash.c $(CONFIG_H) $(LIBCPP_DEPS)
-cpptrad.o: cpptrad.c $(CONFIG_H) $(LIBCPP_DEPS)
-cppfiles.o: cppfiles.c $(CONFIG_H) $(LIBCPP_DEPS) $(SPLAY_TREE_H) mkdeps.h
-cppinit.o: cppinit.c $(CONFIG_H) $(LIBCPP_DEPS) cppdefault.h \
- mkdeps.h prefix.h
-
-cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) cppdefault.h Makefile
+cppcharset.o: cppcharset.c $(LIBCPP_DEPS) cppucnid.h
+cpperror.o: cpperror.c $(LIBCPP_DEPS)
+cppexp.o: cppexp.c $(LIBCPP_DEPS)
+cpplex.o: cpplex.c $(LIBCPP_DEPS)
+cppmacro.o: cppmacro.c $(LIBCPP_DEPS)
+cpplib.o: cpplib.c $(LIBCPP_DEPS)
+cpphash.o: cpphash.c $(LIBCPP_DEPS)
+cpptrad.o: cpptrad.c $(LIBCPP_DEPS)
+cppfiles.o: cppfiles.c $(LIBCPP_DEPS) $(HASHTAB_H) mkdeps.h
+cppinit.o: cppinit.c $(LIBCPP_DEPS) mkdeps.h
+cpppch.o: cpppch.c $(LIBCPP_DEPS) mkdeps.h
+
+cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ cppdefault.h Makefile
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(PREPROCESSOR_DEFINES) \
-c $(srcdir)/cppdefault.c $(OUTPUT_OPTION)
mkdeps.o: mkdeps.c $(CONFIG_H) $(SYSTEM_H) mkdeps.h
+hashtable.o: hashtable.c hashtable.h $(CONFIG_H) $(SYSTEM_H) $(OBSTACK_H)
+line-map.o: line-map.c line-map.h intl.h $(CONFIG_H) $(SYSTEM_H)
# Note for the stamp targets, we run the program `true' instead of
# having an empty command (nothing following the semicolon).
@@ -2248,7 +2376,7 @@ unprotoize$(exeext): unprotoize.o $(PROTO_OBJS) $(LIBDEPS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ unprotoize.o $(PROTO_OBJS) $(LIBS)
protoize.o: protoize.c $(srcdir)/../include/getopt.h $(CONFIG_H) $(SYSTEM_H) \
- Makefile version.h
+ coretypes.h $(TM_H) Makefile version.h
(SHLIB_LINK='$(SHLIB_LINK)' \
SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
@@ -2303,13 +2431,28 @@ test-protoize-simple: ./protoize ./unprotoize $(GCC_PASSES)
diff $(srcdir)/protoize.c tmp-proto.c | cat
-rm -f tmp-proto.[cs] tmp-proto$(objext)
-gcov.o: gcov.c gcov-io.h intl.h $(SYSTEM_H) $(CONFIG_H)
+# gcov-iov.c is run on the build machine to generate gcov-iov.h from version.c
+gcov-iov.o: gcov-iov.c version.c $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) coretypes.h $(TM_H)
+ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) $(srcdir)/gcov-iov.c $(OUTPUT_OPTION)
+gcov-iov$(build_exeext): gcov-iov.o
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) gcov-iov.o -o $@
+gcov-iov.h: s-iov
+s-iov: gcov-iov$(build_exeext) $(srcdir)/move-if-change
+ ./gcov-iov$(build_exeext) > tmp-gcov-iov.h
+ $(SHELL) $(srcdir)/move-if-change tmp-gcov-iov.h gcov-iov.h
+ $(STAMP) s-iov
+
+gcov.o: gcov.c gcov-io.h gcov-io.c gcov-iov.h intl.h $(SYSTEM_H) coretypes.h $(TM_H) $(CONFIG_H)
+gcov-dump.o: gcov-dump.c gcov-io.h gcov-io.c gcov-iov.h $(SYSTEM_H) coretypes.h $(TM_H) $(CONFIG_H)
# Only one of 'gcov' or 'gcov.exe' is actually built, depending
# upon whether $(exeext) is empty or not.
GCOV_OBJS = gcov.o intl.o version.o
gcov$(exeext): $(GCOV_OBJS) $(LIBDEPS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) $(GCOV_OBJS) $(LIBS) -o $@
+GCOV_DUMP_OBJS = gcov-dump.o version.o
+gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) $(GCOV_DUMP_OBJS) $(LIBS) -o $@
#
# Build the include directory. The stamp files are stmp-* rather than
# s-* so that mostlyclean does not force the include directory to
@@ -2351,19 +2494,34 @@ specs.ready: specs
$(STAMP) specs.ready; \
fi
+# Until someone fixes this recursive make nightmare (please note where
+# BUILD_CFLAGS and WARN_CFLAGS are first expanded below versus which
+# later make invocation has the fine-grain -warn markings for fixinc):
+fixinc.sh-warn = -Wno-error
+
FIXINCSRCDIR=$(srcdir)/fixinc
fixinc.sh: $(FIXINCSRCDIR)/mkfixinc.sh $(FIXINCSRCDIR)/fixincl.c \
- $(FIXINCSRCDIR)/procopen.c $(FIXINCSRCDIR)/gnu-regex.c \
- $(FIXINCSRCDIR)/server.c $(FIXINCSRCDIR)/gnu-regex.h \
+ $(FIXINCSRCDIR)/procopen.c $(FIXINCSRCDIR)/server.c \
$(FIXINCSRCDIR)/server.h $(FIXINCSRCDIR)/inclhack.def specs.ready
(MAKE="$(MAKE)"; srcdir=`cd $(srcdir)/fixinc && ${PWD_COMMAND}` ; \
- CC="$(HOST_CC)"; CFLAGS="$(HOST_CFLAGS)"; LDFLAGS="$(HOST_LDFLAGS)"; \
- WARN_CFLAGS="$(WARN_CFLAGS)"; \
- export MAKE srcdir CC CFLAGS LDFLAGS WARN_CFLAGS; cd ./fixinc && \
- $(SHELL) $${srcdir}/mkfixinc.sh $(build_canonical) $(target))
+ CC="$(CC_FOR_BUILD)"; CFLAGS="$(BUILD_CFLAGS)"; LDFLAGS="$(BUILD_LDFLAGS)"; \
+ WARN_CFLAGS="$(WARN_CFLAGS)"; LIBERTY=`${PWD_COMMAND}`/"$(BUILD_LIBIBERTY)"; \
+ export MAKE srcdir CC CFLAGS LDFLAGS WARN_CFLAGS LIBERTY; \
+ cd ./fixinc && \
+ $(SHELL) $${srcdir}/mkfixinc.sh $(build) $(target))
+
+.PHONY: install-gcc-tooldir
+install-gcc-tooldir:
+ $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(gcc_tooldir)
# Build fixed copies of system files.
stmp-fixinc: fixinc.sh gsyslimits.h
+ @if test ! -d ${SYSTEM_HEADER_DIR}; then \
+ echo The directory that should contain system headers does not exist: >&2 ; \
+ echo " ${SYSTEM_HEADER_DIR}" >&2 ; \
+ if test "x${SYSTEM_HEADER_DIR}" = "x${gcc_tooldir}/sys-include"; \
+ then sleep 1; else exit 1; fi; \
+ fi
rm -rf include; mkdir include
-chmod a+rx include
(TARGET_MACHINE='$(target)'; srcdir=`cd $(srcdir); ${PWD_COMMAND}`; \
@@ -2377,29 +2535,15 @@ stmp-fixinc: fixinc.sh gsyslimits.h
cp $(srcdir)/gsyslimits.h include/syslimits.h; \
fi; \
chmod a+r include/syslimits.h)
-# If $(SYSTEM_HEADER_DIR) is $(build_tooldir)/sys-include, and
-# that directory exists, then make sure that $(libsubdir) exists.
-# This is because cpp is compiled to find $(gcc_tooldir)/include via
-# $(libsubdir)/$(unlibsubdir), which will only work if $(libsubdir)
-# exists.
-# ??? Better would be to use -isystem $(build_tooldir)/sys-include,
-# but fixincludes does not take such arguments.
- if [ "$(SYSTEM_HEADER_DIR)" = "$(build_tooldir)/sys-include" ] \
- && [ -d $(build_tooldir)/sys-include ]; then \
- if [ -d $(libdir) ] ; then true ; else mkdir $(libdir) ; fi; \
- if [ -d $(libdir)/gcc-lib ] ; then true ; else mkdir $(libdir)/gcc-lib; fi; \
- if [ -d $(libdir)/gcc-lib/$(target_alias) ] ; then true ; else mkdir $(libdir)/gcc-lib/$(target_alias) ; fi; \
- if [ -d $(libdir)/gcc-lib/$(target_alias)/$(version) ] ; then true ; else mkdir $(libdir)/gcc-lib/$(target_alias)/$(version) ; fi; \
- else true; fi
$(STAMP) stmp-fixinc
# Files related to the fixproto script.
-# gen-protos and fix-header are compiled with HOST_CC, but they are only
+# gen-protos and fix-header are compiled with CC_FOR_BUILD, but they are only
# used in native and host-x-target builds, so it's safe to link them with
# libiberty.a.
deduced.h: $(GCC_PASSES) $(srcdir)/scan-types.sh stmp-int-hdrs
- if [ -d $(SYSTEM_HEADER_DIR) ]; \
+ if [ -d "$(SYSTEM_HEADER_DIR)" ]; \
then \
CC="$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(ALL_CPPFLAGS) -I. -I$(srcdir) -isystem include -isystem ${SYSTEM_HEADER_DIR}"; \
export CC; \
@@ -2411,14 +2555,12 @@ deduced.h: $(GCC_PASSES) $(srcdir)/scan-types.sh stmp-int-hdrs
GEN_PROTOS_OBJS = gen-protos.o scan.o
gen-protos$(build_exeext): $(GEN_PROTOS_OBJS)
- ${HOST_CC} $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
- $(GEN_PROTOS_OBJS) $(HOST_LIBS)
+ ${CC_FOR_BUILD} $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ \
+ $(GEN_PROTOS_OBJS) $(BUILD_LIBS)
-gen-protos.o: gen-protos.c scan.h $(HCONFIG_H) $(SYSTEM_H)
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gen-protos.c $(OUTPUT_OPTION)
+gen-protos.o: gen-protos.c scan.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H)
-scan.o: scan.c scan.h $(HCONFIG_H) $(SYSTEM_H)
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/scan.c $(OUTPUT_OPTION)
+scan.o: scan.c scan.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H)
xsys-protos.h: $(GCC_PASSES) $(srcdir)/sys-protos.h deduced.h gen-protos$(build_exeext) Makefile
sed -e s/TARGET_GETGROUPS_T/$(TARGET_GETGROUPS_T)/ \
@@ -2433,16 +2575,14 @@ xsys-protos.h: $(GCC_PASSES) $(srcdir)/sys-protos.h deduced.h gen-protos$(build_
# This is nominally a 'build' program, but it's run only when host==build,
# so we can (indeed, must) use $(LIBDEPS) and $(LIBS).
fix-header$(build_exeext): fix-header.o scan-decls.o scan.o xsys-protos.h \
- $(LIBDEPS) libcpp.a
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ fix-header.o \
- scan-decls.o scan.o libcpp.a $(LIBS)
+ c-incpath.o cppdefault.o prefix.o $(LIBDEPS) libcpp.a
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o $@ fix-header.o \
+ c-incpath.o cppdefault.o scan-decls.o prefix.o scan.o libcpp.a $(LIBS)
fix-header.o: fix-header.c $(OBSTACK_H) scan.h \
- xsys-protos.h $(HCONFIG_H) $(SYSTEM_H) $(CPPLIB_H)
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/fix-header.c $(OUTPUT_OPTION)
+ xsys-protos.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) $(CPPLIB_H)
-scan-decls.o: scan-decls.c scan.h $(CPPLIB_H) $(HCONFIG_H) $(SYSTEM_H)
- $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/scan-decls.c $(OUTPUT_OPTION)
+scan-decls.o: scan-decls.c scan.h $(CPPLIB_H) $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H)
# stmp-fixproto depends on this, not on fix-header directly.
# The idea is to make sure fix-header gets built,
@@ -2465,7 +2605,7 @@ stmp-fixproto: fixhdr.ready fixproto stmp-int-hdrs
FIXPROTO_DEFINES="$(FIXPROTO_DEFINES)"; export FIXPROTO_DEFINES; \
mkinstalldirs="$(SHELL) $(srcdir)/mkinstalldirs"; \
export mkinstalldirs; \
- if [ -d $(SYSTEM_HEADER_DIR) ] ; then \
+ if [ -d "$(SYSTEM_HEADER_DIR)" ]; then \
$(SHELL) ${srcdir}/fixproto include include $(SYSTEM_HEADER_DIR); \
if [ $$? -eq 0 ] ; then true ; else exit 1 ; fi ; \
else true; fi; \
@@ -2475,132 +2615,111 @@ stmp-fixproto: fixhdr.ready fixproto stmp-int-hdrs
#
# Remake the info files.
-docdir = $(srcdir)/doc
-
doc: $(BUILD_INFO) $(GENERATED_MANPAGES) gccbug
-info: $(docdir)/cpp.info $(docdir)/gcc.info $(docdir)/gccint.info $(docdir)/gccinstall.info lang.info $(docdir)/cppinternals.info
-
-TEXI_CPP_FILES = $(docdir)/cpp.texi $(docdir)/include/fdl.texi \
- $(docdir)/cppenv.texi $(docdir)/cppopts.texi
-
-TEXI_GCC_FILES = $(docdir)/gcc.texi $(docdir)/include/gcc-common.texi \
- $(docdir)/frontends.texi $(docdir)/standards.texi \
- $(docdir)/invoke.texi $(docdir)/extend.texi $(docdir)/md.texi \
- $(docdir)/objc.texi $(docdir)/gcov.texi $(docdir)/trouble.texi \
- $(docdir)/bugreport.texi $(docdir)/service.texi \
- $(docdir)/contribute.texi $(docdir)/compat.texi \
- $(docdir)/include/funding.texi $(docdir)/gnu.texi \
- $(docdir)/include/gpl.texi $(docdir)/include/fdl.texi \
- $(docdir)/contrib.texi $(docdir)/cppenv.texi $(docdir)/cppopts.texi
-
-TEXI_GCCINT_FILES = $(docdir)/gccint.texi \
- $(docdir)/include/gcc-common.texi $(docdir)/contribute.texi \
- $(docdir)/makefile.texi $(docdir)/configterms.texi \
- $(docdir)/portability.texi $(docdir)/interface.texi \
- $(docdir)/passes.texi $(docdir)/c-tree.texi \
- $(docdir)/rtl.texi $(docdir)/md.texi $(docdir)/tm.texi \
- $(docdir)/hostconfig.texi $(docdir)/fragments.texi \
- $(docdir)/configfiles.texi $(docdir)/collect2.texi \
- $(docdir)/headerdirs.texi $(docdir)/include/funding.texi \
- $(docdir)/gnu.texi $(docdir)/include/gpl.texi \
- $(docdir)/include/fdl.texi $(docdir)/contrib.texi \
- $(docdir)/languages.texi $(docdir)/sourcebuild.texi \
- $(docdir)/gty.texi
-
-TEXI_GCCINSTALL_FILES = $(docdir)/install.texi $(docdir)/install-old.texi \
- $(docdir)/include/fdl.texi
-
-TEXI_CPPINT_FILES = $(docdir)/cppinternals.texi
-
-$(docdir)/cpp.info: $(TEXI_CPP_FILES)
- cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/cpp.info doc/cpp.texi
-
-$(docdir)/gcc.info: $(TEXI_GCC_FILES)
- cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/gcc.info doc/gcc.texi
-
-$(docdir)/gccint.info: $(TEXI_GCCINT_FILES)
- cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/gccint.info doc/gccint.texi
-
-$(docdir)/gccinstall.info: $(TEXI_GCCINSTALL_FILES)
- cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/gccinstall.info doc/install.texi
-
-$(docdir)/cppinternals.info: $(TEXI_CPPINT_FILES)
- cd $(srcdir) && $(MAKEINFO) $(MAKEINFOFLAGS) -I doc -I doc/include -o doc/cppinternals.info \
- doc/cppinternals.texi
-
-dvi: gcc.dvi gccint.dvi gccinstall.dvi cpp.dvi lang.dvi cppinternals.dvi
-
-# This works with GNU Make's default rule.
-cpp.dvi: $(TEXI_CPP_FILES)
- $(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/cpp.texi
-
-gcc.dvi: $(TEXI_GCC_FILES)
- $(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/gcc.texi
-
-gccint.dvi: $(TEXI_GCCINT_FILES)
- $(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/gccint.texi
-
-gccinstall.dvi: $(TEXI_GCCINSTALL_FILES)
- s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
- $(TEXI2DVI) -I $$s/doc -I $$s/doc/include -o $@ $$s/doc/install.texi
-
-cppinternals.dvi: $(TEXI_CPPINT_FILES)
- $(TEXI2DVI) -I $(docdir) -I $(docdir)/include $(docdir)/cppinternals.texi
-
-generated-manpages: $(docdir)/gcov.1 $(docdir)/cpp.1 $(docdir)/gcc.1 \
- $(docdir)/gfdl.7 $(docdir)/gpl.7 $(docdir)/fsf-funding.7 \
- lang.generated-manpages
-
-$(docdir)/gcov.1: $(docdir)/gcov.texi
- $(STAMP) $(docdir)/gcov.1
- -$(TEXI2POD) $(docdir)/gcov.texi > gcov.pod
- -($(POD2MAN) --section=1 gcov.pod > $(docdir)/gcov.1.T$$$$ && \
- mv -f $(docdir)/gcov.1.T$$$$ $(docdir)/gcov.1) || \
- (rm -f $(docdir)/gcov.1.T$$$$ && exit 1)
- -rm -f gcov.pod
-$(docdir)/cpp.1: $(docdir)/cpp.texi $(docdir)/cppenv.texi \
- $(docdir)/cppopts.texi
- $(STAMP) $(docdir)/cpp.1
- -$(TEXI2POD) $(docdir)/cpp.texi > cpp.pod
- -($(POD2MAN) --section=1 cpp.pod > $(docdir)/cpp.1.T$$$$ && \
- mv -f $(docdir)/cpp.1.T$$$$ $(docdir)/cpp.1) || \
- (rm -f $(docdir)/cpp.1.T$$$$ && exit 1)
- -rm -f cpp.pod
-
-$(docdir)/gcc.1: $(docdir)/invoke.texi $(docdir)/cppenv.texi \
- $(docdir)/cppopts.texi
- $(STAMP) $(docdir)/gcc.1
- -$(TEXI2POD) $(docdir)/invoke.texi > gcc.pod
- -($(POD2MAN) --section=1 gcc.pod > $(docdir)/gcc.1.T$$$$ && \
- mv -f $(docdir)/gcc.1.T$$$$ $(docdir)/gcc.1) || \
- (rm -f $(docdir)/gcc.1.T$$$$ && exit 1)
- -rm -f gcc.pod
-
-$(docdir)/gfdl.7: $(docdir)/include/fdl.texi
- $(STAMP) $(docdir)/gfdl.7
- -$(TEXI2POD) $(docdir)/include/fdl.texi > gfdl.pod
- -($(POD2MAN) --section=7 gfdl.pod > $(docdir)/gfdl.7.T$$$$ && \
- mv -f $(docdir)/gfdl.7.T$$$$ $(docdir)/gfdl.7) || \
- (rm -f $(docdir)/gfdl.7.T$$$$ && exit 1)
- -rm -f gfdl.pod
-
-$(docdir)/gpl.7: $(docdir)/include/gpl.texi
- $(STAMP) $(docdir)/gpl.7
- -$(TEXI2POD) $(docdir)/include/gpl.texi > gpl.pod
- -($(POD2MAN) --section=7 gpl.pod > $(docdir)/gpl.7.T$$$$ && \
- mv -f $(docdir)/gpl.7.T$$$$ $(docdir)/gpl.7) || \
- (rm -f $(docdir)/gpl.7.T$$$$ && exit 1)
- -rm -f gpl.pod
-
-$(docdir)/fsf-funding.7: $(docdir)/include/funding.texi
- $(STAMP) $(docdir)/fsf-funding.7
- -$(TEXI2POD) $(docdir)/include/funding.texi > fsf-funding.pod
- -($(POD2MAN) --section=7 fsf-funding.pod \
- > $(docdir)/fsf-funding.7.T$$$$ && \
- mv -f $(docdir)/fsf-funding.7.T$$$$ $(docdir)/fsf-funding.7) || \
- (rm -f $(docdir)/fsf-funding.7.T$$$$ && exit 1)
- -rm -f fsf-funding.pod
+INFOFILES = doc/cpp.info doc/gcc.info doc/gccint.info \
+ doc/gccinstall.info doc/cppinternals.info
+
+info: $(INFOFILES) lang.info @GENINSRC@ srcinfo lang.srcinfo
+
+srcinfo: $(INFOFILES)
+ -cp -p $^ $(srcdir)/doc
+
+TEXI_CPP_FILES = cpp.texi fdl.texi cppenv.texi cppopts.texi
+
+TEXI_GCC_FILES = gcc.texi gcc-common.texi frontends.texi standards.texi \
+ invoke.texi extend.texi md.texi objc.texi gcov.texi trouble.texi \
+ bugreport.texi service.texi contribute.texi compat.texi funding.texi \
+ gnu.texi gpl.texi fdl.texi contrib.texi cppenv.texi cppopts.texi
+
+TEXI_GCCINT_FILES = gccint.texi gcc-common.texi contribute.texi makefile.texi \
+ configterms.texi portability.texi interface.texi passes.texi \
+ c-tree.texi rtl.texi md.texi tm.texi hostconfig.texi fragments.texi \
+ configfiles.texi collect2.texi headerdirs.texi funding.texi gnu.texi \
+ gpl.texi fdl.texi contrib.texi languages.texi sourcebuild.texi \
+ gty.texi libgcc.texi
+
+TEXI_GCCINSTALL_FILES = install.texi install-old.texi fdl.texi
+
+TEXI_CPPINT_FILES = cppinternals.texi
+
+# The *.1, *.7, *.info, and *.dvi files are being generated from implicit
+# patterns. To use them, put each of the specific target with with their
+# specific dependencies but no build commands.
+
+doc/cpp.info: $(TEXI_CPP_FILES)
+doc/gcc.info: $(TEXI_GCC_FILES)
+doc/gccint.info: $(TEXI_GCCINT_FILES)
+doc/cppinternals.info: $(TEXI_CPPINT_FILES)
+
+doc/%.info: %.texi
+ if [ x$(BUILD_INFO) = xinfo ]; then \
+ $(MAKEINFO) $(MAKEINFOFLAGS) -I $(docdir) \
+ -I $(docdir)/include -o $@ $<; \
+ fi
+
+# Duplicate entry to handle renaming of gccinstall.info
+doc/gccinstall.info: $(TEXI_GCCINSTALL_FILES)
+ if [ x$(BUILD_INFO) = xinfo ]; then \
+ $(MAKEINFO) $(MAKEINFOFLAGS) -I $(docdir) \
+ -I $(docdir)/include -o $@ $<; \
+ fi
+
+doc/cpp.dvi: $(TEXI_CPP_FILES)
+doc/gcc.dvi: $(TEXI_GCC_FILES)
+doc/gccint.dvi: $(TEXI_GCCINT_FILES)
+doc/cppinternals.dvi: $(TEXI_CPPINT_FILES)
+
+dvi:: doc/gcc.dvi doc/gccint.dvi doc/gccinstall.dvi doc/cpp.dvi \
+ doc/cppinternals.dvi
+
+doc/%.dvi: %.texi
+ $(TEXI2DVI) -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $<
+
+# Duplicate entry to handle renaming of gccinstall.dvi
+doc/gccinstall.dvi: $(TEXI_GCCINSTALL_FILES)
+ $(TEXI2DVI) -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $<
+
+MANFILES = doc/gcov.1 doc/cpp.1 doc/gcc.1 doc/gfdl.7 doc/gpl.7 doc/fsf-funding.7
+
+generated-manpages: man
+
+man: $(MANFILES) lang.man @GENINSRC@ srcman lang.srcman
+
+srcman: $(MANFILES)
+ -cp -p $^ $(srcdir)/doc
+
+doc/%.1: %.pod
+ $(STAMP) $@
+ -($(POD2MAN) --section=1 $< > $(@).T$$$$ && \
+ mv -f $(@).T$$$$ $@) || \
+ (rm -f $(@).T$$$$ && exit 1)
+
+doc/%.7: %.pod
+ $(STAMP) $@
+ -($(POD2MAN) --section=7 $< > $(@).T$$$$ && \
+ mv -f $(@).T$$$$ $@) || \
+ (rm -f $(@).T$$$$ && exit 1)
+
+%.pod: %.texi
+ $(STAMP) $@
+ -$(TEXI2POD) $< > $@
+
+.INTERMEDIATE: cpp.pod gcc.pod gfdl.pod fsf-funding.pod
+cpp.pod: cpp.texi cppenv.texi cppopts.texi
+
+# These next rules exist because the output name is not the same as
+# the input name, so our implict %.pod rule will not work.
+
+gcc.pod: invoke.texi cppenv.texi cppopts.texi
+ $(STAMP) $@
+ -$(TEXI2POD) $< > $@
+gfdl.pod: fdl.texi
+ $(STAMP) $@
+ -$(TEXI2POD) $< > $@
+fsf-funding.pod: funding.texi
+ $(STAMP) $@
+ -$(TEXI2POD) $< > $@
#
# Deletion of files made during compilation.
@@ -2616,27 +2735,26 @@ $(docdir)/fsf-funding.7: $(docdir)/include/funding.texi
# We remove as much from the language subdirectories as we can
# (less duplicated code).
-INTL_MOSTLYCLEAN = intl.mostlyclean
-mostlyclean: $(INTL_MOSTLYCLEAN) lang.mostlyclean
+mostlyclean: lang.mostlyclean
-rm -f $(STAGESTUFF)
-rm -f *$(coverageexts)
-rm -rf libgcc
# Delete the temporary source copies for cross compilation.
-rm -f $(BUILD_PREFIX_1)rtl.c $(BUILD_PREFIX_1)print-rtl.c
-rm -f $(BUILD_PREFIX_1)bitmap.c $(BUILD_PREFIX_1)errors.c
- -rm -f $(BUILD_PREFIX_1)ggc-none.c
+ -rm -f $(BUILD_PREFIX_1)ggc-none.c print-rtl1.c
# Delete the temp files made in the course of building libgcc.a.
-rm -f xlimits.h
# Delete other built files.
-rm -f xsys-protos.hT
- -rm -f specs.h options.h gencheck.h
+ -rm -f specs.h gencheck.h options.c options.h
# Delete the stamp and temporary files.
-rm -f s-* tmp-* stamp-* stmp-*
-rm -f */stamp-* */tmp-*
# Delete debugging dump files.
-rm -f *.[0-9][0-9].* */*.[0-9][0-9].*
# Delete some files made during installation.
- -rm -f specs SYSCALLS.c.X SYSCALLS.c
+ -rm -f specs $(SPECS) SYSCALLS.c.X SYSCALLS.c
-rm -f collect collect2 mips-tfile mips-tdump
# Delete files generated for fixproto
-rm -rf fix-header$(build_exeext) xsys-protos.h deduced.h tmp-deduced.h \
@@ -2659,14 +2777,13 @@ mostlyclean: $(INTL_MOSTLYCLEAN) lang.mostlyclean
# Delete all files made by compilation
# that don't exist in the distribution.
-INTL_CLEAN = intl.clean
-clean: mostlyclean $(INTL_CLEAN) lang.clean
- -rm -f libgcc.a libgcc_eh.a libgcc_s$(SHLIB_EXT) libgcc_s$(SHLIB_EXT).1
- -rm -f config.h tconfig.h hconfig.h tm_p.h
+clean: mostlyclean lang.clean
+ -rm -f libgcc.a libgcc_eh.a libgcov.a
+ -rm -f libgcc_s$(SHLIB_EXT) libgcc_s$(SHLIB_EXT).1
+ -rm -f config.h tconfig.h bconfig.h tm_p.h tm.h
-rm -f cs-*
-rm -rf libgcc
- -rm -f *.dvi
- -rm -f */*.dvi
+ -rm -f doc/*.dvi
# Delete the include directory.
-rm -rf include
# Delete files used by the "multilib" facility (including libgcc subdirs).
@@ -2676,7 +2793,7 @@ clean: mostlyclean $(INTL_CLEAN) lang.clean
else if [ "x$(MULTILIB_OPTIONS)" != x ] ; then \
rm -rf `echo $(MULTILIB_OPTIONS) | sed -e 's/\// /g'`; \
fi ; fi
- -rm -fr stage1 stage2 stage3 stage4
+ -rm -fr stage1 stage2 stage3 stage4 stageprofile stagefeedback
# Delete stamps of bootstrap stages
-rm -f stage?_*
-rm -f clean?_*
@@ -2684,23 +2801,21 @@ clean: mostlyclean $(INTL_CLEAN) lang.clean
# Delete all files that users would normally create
# while building and installing GCC.
-INTL_DISTCLEAN = intl.distclean
-distclean: clean $(INTL_DISTCLEAN) lang.distclean
+distclean: clean lang.distclean
-rm -f auto-host.h auto-build.h
-rm -f cstamp-h
-rm -f config.status config.run config.cache config.bak
-rm -f Make-lang Make-hooks Make-host Make-target
-rm -f Makefile *.oaux
-rm -f gthr-default.h
- -rm -f */stage1 */stage2 */stage3 */stage4 */include
- -rm -f c-parse.output
+ -rm -f */stage1 */stage2 */stage3 */stage4 */include */stageprofile */stagefeedback
+ -rm -f c-parse.y c-parse.c c-parse.output TAGS */TAGS
-rm -f *.asm
-rm -f site.exp site.bak testsuite/site.exp testsuite/site.bak
-rm -f testsuite/*.log testsuite/*.sum
-cd testsuite && rm -f x *.x *.x? *.exe *.rpo *.o *.s *.S *.c
- -cd testsuite && rm -f *.out *.gcov *.bb *.bbg
+ -cd testsuite && rm -f *.out *.gcov *$(coverageexts)
-rm -rf ${QMTEST_DIR} stamp-qmtest
- -rm -f intl/libintl.h libintl.h
-rm -f cxxmain.c
-rm -f mklibgcc mkheaders gccbug .gdbinit configargs.h
-rm -f gcov.pod
@@ -2709,41 +2824,16 @@ distclean: clean $(INTL_DISTCLEAN) lang.distclean
-if [ ! -f po/exgettext ]; then rm -f po/*.gmo; fi
-rmdir ada cp f java objc fixinc intl po testsuite 2>/dev/null
-# Delete anything likely to be found in the source directory
-# that shouldn't be in the distribution.
-extraclean: distclean lang.extraclean
- -rm -rf =* ./"#"* *~* config/=* config/"#"* config/*~*
- -rm -f patch* *.orig *.rej config/patch* config/*.orig config/*.rej
- -rm -f config/*/=* config/*/"#"* config/*/*~*
- -rm -f config/*/*.orig config/*/*.rej
- -rm -f *.dvi *.ps *.oaux *.d *.[zZ] *.gz
- -rm -f *.tar *.xtar *diff *.diff.* *.tar.* *.xtar.* *diffs
- -rm -f *lose config/*lose config/*/*lose
- -rm -f *.s *.s[0-9] *.i config/ChangeLog
- -rm -f y.tab.c yacc.*
- -rm -f */=* */"#"* */*~*
- -rm -f */patch* */*.orig */*.rej
- -rm -f */*.dvi */*.oaux */*.d */*.[zZ] */*.gz
- -rm -f */*.tar */*.xtar */*diff */*.diff.* */*.tar.* */*.xtar.* */*diffs
- -rm -f */*lose */*.s */*.s[0-9] */*.i
-
# Get rid of every file that's generated from some other file, except for `configure'.
# Most of these files ARE PRESENT in the GCC distribution.
-# We define INTL_DISTCLEAN, INTL_CLEAN & INTL_MOSTLYCLEAN to be empty in the
-# submake, so that we don't descend into intl after its makefile has been
-# removed.
maintainer-clean:
@echo 'This command is intended for maintainers to use; it'
@echo 'deletes files that may need special tools to rebuild.'
- $(MAKE) INTL_DISTCLEAN= INTL_CLEAN= INTL_MOSTLYCLEAN= \
- intl.maintainer-clean lang.maintainer-clean distclean
- -rm -f c-parse.y c-parse.c c-parse.output TAGS
+ $(MAKE) lang.maintainer-clean distclean
+ -rm -f $(srcdir)/c-parse.y $(srcdir)/c-parse.c
-rm -f cpp.??s cpp.*aux
-rm -f gcc.??s gcc.*aux
- -rm -f $(docdir)/cpp.info* $(docdir)/gcc.info* $(docdir)/gccint.info*
- -rm -f $(docdir)/cppinternals.info*
- -rm -f $(docdir)/gcov.1 $(docdir)/cpp.1 $(docdir)/gcc.1
- -rm -f $(docdir)/fsf-funding.7 $(docdir)/gfdl.7 $(docdir)/gpl.7
+ -rm -f $(docdir)/*.info $(docdir)/*.1 $(docdir)/*.7 $(docdir)/*.dvi
#
# Entry points `install' and `uninstall'.
# Also use `install-collect2' to install collect2 when the config files don't.
@@ -2752,31 +2842,23 @@ maintainer-clean:
# Install the driver last so that the window when things are
# broken is small.
install: install-common $(INSTALL_HEADERS) $(INSTALL_LIBGCC) \
- install-cpp install-man install-info intl.install install-@POSUB@ \
+ install-cpp install-man install-info install-@POSUB@ \
lang.install-normal install-driver
# Handle cpp installation.
install-cpp: cpp$(exeext)
- -if [ -f gcc-cross$(exeext) ] ; then \
- rm -f $(DESTDIR)$(bindir)/$(CPP_CROSS_NAME)$(exeext); \
- $(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(bindir)/$(CPP_CROSS_NAME)$(exeext); \
- if [ x$(cpp_install_dir) != x ]; then \
- rm -f $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_CROSS_NAME)$(exeext); \
- $(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_CROSS_NAME)$(exeext); \
- else true; fi; \
- else \
- rm -f $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext); \
- $(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext); \
- if [ x$(cpp_install_dir) != x ]; then \
- rm -f $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \
- $(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \
- else true; fi; \
- fi
+ -rm -f $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext)
+ -$(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext)
+ -if [ x$(cpp_install_dir) != x ]; then \
+ rm -f $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \
+ $(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \
+ else true; fi
# Create the installation directories.
-# $(libdir)/gcc-lib/include isn't currently searched by cpp.
+# $(libdir)/gcc/include isn't currently searched by cpp.
installdirs:
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(libsubdir)
+ $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(libexecsubdir)
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir)
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(includedir)
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(infodir)
@@ -2785,18 +2867,18 @@ installdirs:
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(man7dir)
# Install the compiler executables built during cross compilation.
-install-common: native $(EXTRA_PARTS) lang.install-common
+install-common: native $(EXTRA_PARTS) lang.install-common installdirs
for file in $(COMPILERS); do \
if [ -f $$file ] ; then \
- rm -f $(DESTDIR)$(libsubdir)/$$file; \
- $(INSTALL_PROGRAM) $$file $(DESTDIR)$(libsubdir)/$$file; \
+ rm -f $(DESTDIR)$(libexecsubdir)/$$file; \
+ $(INSTALL_PROGRAM) $$file $(DESTDIR)$(libexecsubdir)/$$file; \
else true; \
fi; \
done
for file in $(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(USE_COLLECT2) ..; do \
if [ x"$$file" != x.. ]; then \
- rm -f $(DESTDIR)$(libsubdir)/$$file; \
- $(INSTALL_PROGRAM) $$file $(DESTDIR)$(libsubdir)/$$file; \
+ rm -f $(DESTDIR)$(libexecsubdir)/$$file; \
+ $(INSTALL_PROGRAM) $$file $(DESTDIR)$(libexecsubdir)/$$file; \
else true; fi; \
done
for file in $(EXTRA_PARTS) ..; do \
@@ -2809,165 +2891,116 @@ install-common: native $(EXTRA_PARTS) lang.install-common
# Don't mess with specs if it doesn't exist yet.
-if [ -f specs ] ; then \
rm -f $(DESTDIR)$(libsubdir)/specs; \
- $(INSTALL_DATA) specs $(DESTDIR)$(libsubdir)/specs; \
+ $(INSTALL_DATA) $(SPECS) $(DESTDIR)$(libsubdir)/specs; \
chmod a-x $(DESTDIR)$(libsubdir)/specs; \
fi
# Install protoize if it was compiled.
- -if [ -f protoize$(exeext) ]; \
- then \
- if [ -f gcc-cross$(exeext) ] ; then \
- rm -f $(DESTDIR)$(bindir)/$(PROTOIZE_CROSS_NAME)$(exeext); \
- $(INSTALL_PROGRAM) protoize$(exeext) $(DESTDIR)$(bindir)/$(PROTOIZE_CROSS_NAME)$(exeext); \
- rm -f $(DESTDIR)$(bindir)/$(UNPROTOIZE_CROSS_NAME)$(exeext); \
- $(INSTALL_PROGRAM) unprotoize$(exeext) $(DESTDIR)$(bindir)/$(UNPROTOIZE_CROSS_NAME)$(exeext); \
- else \
- rm -f $(DESTDIR)$(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext); \
- $(INSTALL_PROGRAM) protoize$(exeext) $(DESTDIR)$(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext); \
- rm -f $(DESTDIR)$(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext); \
- $(INSTALL_PROGRAM) unprotoize$(exeext) $(DESTDIR)$(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext); \
- fi ; \
- rm -f $(DESTDIR)$(libsubdir)/SYSCALLS.c.X; \
- $(INSTALL_DATA) SYSCALLS.c.X $(DESTDIR)$(libsubdir)/SYSCALLS.c.X; \
- chmod a-x $(DESTDIR)$(libsubdir)/SYSCALLS.c.X; \
+ -if [ -f protoize$(exeext) ]; then \
+ rm -f $(DESTDIR)$(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext); \
+ $(INSTALL_PROGRAM) protoize$(exeext) $(DESTDIR)$(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext); \
+ rm -f $(DESTDIR)$(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext); \
+ $(INSTALL_PROGRAM) unprotoize$(exeext) $(DESTDIR)$(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext); \
+ rm -f $(DESTDIR)$(libsubdir)/SYSCALLS.c.X; \
+ $(INSTALL_DATA) SYSCALLS.c.X $(DESTDIR)$(libsubdir)/SYSCALLS.c.X; \
+ chmod a-x $(DESTDIR)$(libsubdir)/SYSCALLS.c.X; \
fi
# Install gcov if it was compiled.
-if [ -f gcov$(exeext) ]; \
then \
- rm -f $(DESTDIR)$(bindir)/gcov$(exeext); \
+ rm -f $(DESTDIR)$(bindir)/$(GCOV_INSTALL_NAME)$(exeext); \
$(INSTALL_PROGRAM) gcov$(exeext) $(DESTDIR)$(bindir)/$(GCOV_INSTALL_NAME)$(exeext); \
fi
$(INSTALL_SCRIPT) gccbug $(DESTDIR)$(bindir)/$(GCCBUG_INSTALL_NAME)
-# Install the driver program as $(target_alias)-gcc,
-# $(target-alias)-gcc-$(version)
+# Install the driver program as $(target_noncanonical)-gcc,
+# $(target_noncanonical)-gcc-$(version)
# and also as either gcc (if native) or $(gcc_tooldir)/bin/gcc.
install-driver: installdirs xgcc$(exeext)
+ -rm -f $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext)
+ -$(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext)
+ -rm -f $(DESTDIR)$(bindir)/$(target_noncanonical)-gcc-$(version)
+ -( cd $(DESTDIR)$(bindir) && \
+ $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_noncanonical)-gcc-$(version) )
-if [ -f gcc-cross$(exeext) ] ; then \
- rm -f $(DESTDIR)$(bindir)/$(GCC_CROSS_NAME)$(exeext); \
- $(INSTALL_PROGRAM) gcc-cross$(exeext) $(DESTDIR)$(bindir)/$(GCC_CROSS_NAME)$(exeext); \
- rm -f $(DESTDIR)$(bindir)/$(target_alias)-gcc-$(version); \
- ( cd $(DESTDIR)$(bindir) && \
- $(LN) $(GCC_CROSS_NAME)$(exeext) $(target_alias)-gcc-$(version) ); \
if [ -d $(DESTDIR)$(gcc_tooldir)/bin/. ] ; then \
rm -f $(DESTDIR)$(gcc_tooldir)/bin/gcc$(exeext); \
$(INSTALL_PROGRAM) gcc-cross$(exeext) $(DESTDIR)$(gcc_tooldir)/bin/gcc$(exeext); \
else true; fi; \
else \
- rm -f $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext); \
- $(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext); \
- rm -f $(DESTDIR)$(bindir)/$(target_alias)-gcc-$(version); \
- ( cd $(DESTDIR)$(bindir) && \
- $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_alias)-gcc-$(version) ); \
- rm -f $(DESTDIR)$(bindir)/$(target_alias)-gcc-tmp$(exeext); \
+ rm -f $(DESTDIR)$(bindir)/$(target_noncanonical)-gcc-tmp$(exeext); \
( cd $(DESTDIR)$(bindir) && \
- $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_alias)-gcc-tmp$(exeext) && \
- mv -f $(target_alias)-gcc-tmp$(exeext) $(GCC_TARGET_INSTALL_NAME)$(exeext) ); \
+ $(LN) $(GCC_INSTALL_NAME)$(exeext) $(target_noncanonical)-gcc-tmp$(exeext) && \
+ mv -f $(target_noncanonical)-gcc-tmp$(exeext) $(GCC_TARGET_INSTALL_NAME)$(exeext) ); \
fi
# Install the info files.
# $(INSTALL_DATA) might be a relative pathname, so we can't cd into srcdir
# to do the install.
-install-info: doc installdirs lang.install-info
- -rm -f $(DESTDIR)$(infodir)/cpp.info* $(DESTDIR)$(infodir)/gcc.info*
- -rm -f $(DESTDIR)$(infodir)/cppinternals.info* $(DESTDIR)$(infodir)/gccint.info*
- if [ -f $(docdir)/gcc.info ]; then \
- for f in $(docdir)/cpp.info* $(docdir)/gcc.info* \
- $(docdir)/cppinternals.info* $(docdir)/gccint.info*; do \
+install-info:: doc installdirs \
+ $(DESTDIR)$(infodir)/cpp.info \
+ $(DESTDIR)$(infodir)/gcc.info \
+ $(DESTDIR)$(infodir)/cppinternals.info \
+ $(DESTDIR)$(infodir)/gccinstall.info \
+ $(DESTDIR)$(infodir)/gccint.info
+
+$(DESTDIR)$(infodir)/%.info: doc/%.info installdirs
+ rm -f $@
+ if [ -f $< ]; then \
+ for f in $(<)*; do \
realfile=`echo $$f | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
$(INSTALL_DATA) $$f $(DESTDIR)$(infodir)/$$realfile; \
+ chmod a-x $(DESTDIR)$(infodir)/$$realfile; \
done; \
else true; fi
-if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
- if [ -f $(DESTDIR)$(infodir)/dir ] ; then \
- for f in cpp.info gcc.info gccint.info cppinternals.info; do \
- if [ -f $(DESTDIR)$(infodir)/$$f ]; then \
- install-info --dir-file=$(DESTDIR)$(infodir)/dir $(DESTDIR)$(infodir)/$$f; \
- else true; fi; \
- done; \
+ if [ -f $@ ]; then \
+ install-info --dir-file=$(DESTDIR)$(infodir)/dir $@; \
else true; fi; \
else true; fi;
- -chmod a-x $(DESTDIR)$(infodir)/cpp.info* $(DESTDIR)$(infodir)/gcc.info*
- -chmod a-x $(DESTDIR)$(infodir)/cppinternals.info* $(DESTDIR)$(infodir)/gccint.info*
# Install the man pages.
-install-man: installdirs $(GENERATED_MANPAGES) lang.install-man
- -if [ -f gcc-cross$(exeext) ] ; then \
- rm -f $(DESTDIR)$(man1dir)/$(GCC_CROSS_NAME)$(man1ext); \
- $(INSTALL_DATA) $(docdir)/gcc.1 $(DESTDIR)$(man1dir)/$(GCC_CROSS_NAME)$(man1ext); \
- chmod a-x $(DESTDIR)$(man1dir)/$(GCC_CROSS_NAME)$(man1ext); \
- else \
- rm -f $(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext); \
- $(INSTALL_DATA) $(docdir)/gcc.1 $(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext); \
- chmod a-x $(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext); \
- fi
- -rm -f $(DESTDIR)$(man1dir)/cpp$(man1ext)
- -$(INSTALL_DATA) $(docdir)/cpp.1 $(DESTDIR)$(man1dir)/cpp$(man1ext)
- -chmod a-x $(DESTDIR)$(man1dir)/cpp$(man1ext)
- -rm -f $(DESTDIR)$(man1dir)/gcov$(man1ext)
- -$(INSTALL_DATA) $(docdir)/gcov.1 $(DESTDIR)$(man1dir)/gcov$(man1ext)
- -chmod a-x $(DESTDIR)$(man1dir)/gcov$(man1ext)
- -rm -f $(DESTDIR)$(man7dir)/fsf-funding$(man7ext)
- -$(INSTALL_DATA) $(docdir)/fsf-funding.7 $(DESTDIR)$(man7dir)/fsf-funding$(man7ext)
- -chmod a-x $(DESTDIR)$(man7dir)/fsf-funding$(man7ext)
- -rm -f $(DESTDIR)$(man7dir)/gfdl$(man7ext)
- -$(INSTALL_DATA) $(docdir)/gfdl.7 $(DESTDIR)$(man7dir)/gfdl$(man7ext)
- -chmod a-x $(DESTDIR)$(man7dir)/gfdl$(man7ext)
- -rm -f $(DESTDIR)$(man7dir)/gpl$(man7ext)
- -$(INSTALL_DATA) $(docdir)/gpl.7 $(DESTDIR)$(man7dir)/gpl$(man7ext)
- -chmod a-x $(DESTDIR)$(man7dir)/gpl$(man7ext)
+install-man: installdirs lang.install-man \
+ $(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext) \
+ $(DESTDIR)$(man1dir)/$(CPP_INSTALL_NAME)$(man1ext) \
+ $(DESTDIR)$(man1dir)/$(GCOV_INSTALL_NAME)$(man1ext) \
+ $(DESTDIR)$(man7dir)/fsf-funding$(man7ext) \
+ $(DESTDIR)$(man7dir)/gfdl$(man7ext) \
+ $(DESTDIR)$(man7dir)/gpl$(man7ext)
+
+$(DESTDIR)$(man7dir)/%$(man7ext): doc/%.7
+ -rm -f $@
+ -$(INSTALL_DATA) $< $@
+ -chmod a-x $@
+
+$(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext): doc/gcc.1
+ -rm -f $@
+ -$(INSTALL_DATA) $< $@
+ -chmod a-x $@
+
+$(DESTDIR)$(man1dir)/$(CPP_INSTALL_NAME)$(man1ext): doc/cpp.1
+ -rm -f $@
+ -$(INSTALL_DATA) $< $@
+ -chmod a-x $@
+
+$(DESTDIR)$(man1dir)/$(GCOV_INSTALL_NAME)$(man1ext): doc/gcov.1
+ -rm -f $@
+ -$(INSTALL_DATA) $< $@
+ -chmod a-x $@
# Install the library.
-install-libgcc: libgcc.mk libgcc.a installdirs
- if $(RANLIB_TEST_FOR_TARGET); then \
- r_f_t=$(RANLIB_FOR_TARGET); \
- else \
- r_f_t=: ; \
- fi; \
- $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
- BUILD_PREFIX="$(BUILD_PREFIX)" BUILD_PREFIX_1="$(BUILD_PREFIX_1)" \
- AR_FOR_TARGET="$(AR_FOR_TARGET)" \
- AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
- AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
+install-libgcc: libgcc.mk libgcc.a libgcov.a installdirs
+ $(MAKE) \
CFLAGS="$(CFLAGS) $(WARN_CFLAGS)" \
- RANLIB_TEST_FOR_TARGET="$(RANLIB_TEST_FOR_TARGET)" \
- NM_FOR_TARGET="$(NM_FOR_TARGET)" AWK="$(AWK)" \
- LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" \
- INCLUDES="$(INCLUDES)" \
- CONFIG_H="$(TCONFIG_H)" MACHMODE_H="$(MACHMODE_H)" \
- LIB1ASMSRC='$(LIB1ASMSRC)' \
+ CONFIG_H="$(TCONFIG_H)" \
MAKEOVERRIDES= \
- INSTALL_DATA="$(INSTALL_DATA)" \
- RANLIB_FOR_TARGET="$$r_f_t" \
- DESTDIR="$(DESTDIR)" \
- libsubdir="$(libsubdir)" \
- slibdir="$(slibdir)" \
-f libgcc.mk install
-# Install multiple versions of libgcc.a.
+# Install multiple versions of libgcc.a, libgcov.a.
install-multilib: stmp-multilib installdirs
- if $(RANLIB_TEST_FOR_TARGET); then \
- r_f_t=$(RANLIB_FOR_TARGET); \
- else \
- r_f_t=: ; \
- fi; \
- $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
- BUILD_PREFIX="$(BUILD_PREFIX)" BUILD_PREFIX_1="$(BUILD_PREFIX_1)" \
- AR_FOR_TARGET="$(AR_FOR_TARGET)" \
- AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
- AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
+ $(MAKE) \
CFLAGS="$(CFLAGS) $(WARN_CFLAGS)" \
- RANLIB_TEST_FOR_TARGET="$(RANLIB_TEST_FOR_TARGET)" \
- NM_FOR_TARGET="$(NM_FOR_TARGET)" AWK="$(AWK)" \
- LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" \
- INCLUDES="$(INCLUDES)" \
- CONFIG_H="$(CONFIG_H)" MACHMODE_H="$(MACHMODE_H)" \
- LIB1ASMSRC='$(LIB1ASMSRC)' \
+ CONFIG_H="$(CONFIG_H)" \
MAKEOVERRIDES= \
- INSTALL_DATA="$(INSTALL_DATA)" \
- RANLIB_FOR_TARGET="$$r_f_t" \
- DESTDIR="$(DESTDIR)" \
- libsubdir="$(libsubdir)" \
- slibdir="$(slibdir)" \
-f libgcc.mk install
# Install all the header files built in the include subdirectory.
@@ -3015,67 +3048,67 @@ install-headers-cpio: stmp-int-hdrs $(STMP_FIXPROTO) install-include-dir
install-headers-cp: stmp-int-hdrs $(STMP_FIXPROTO) install-include-dir
cp -p -r include $(DESTDIR)$(libsubdir)
-itoolsdir = $(libsubdir)/install-tools
+itoolsdir = $(libexecsubdir)/install-tools
+itoolsdatadir = $(libsubdir)/install-tools
# Don't install the headers. Instead, install appropriate scripts
# and supporting files for fixincludes to be run later.
install-mkheaders: stmp-int-hdrs $(STMP_FIXPROTO) install-include-dir \
mkheaders xlimits.h
- -rm -rf $(DESTDIR)$(itoolsdir)
- $(SHELL) $(srcdir)/mkinstalldirs $(DESTDIR)$(itoolsdir)/include
+ -rm -rf $(DESTDIR)$(itoolsdir) $(DESTDIR)$(itoolsdatadir)
+ $(SHELL) $(srcdir)/mkinstalldirs $(DESTDIR)$(itoolsdatadir)/include
+ $(SHELL) $(srcdir)/mkinstalldirs $(DESTDIR)$(itoolsdir)
for file in $(USER_H); do \
realfile=`echo $$file | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
$(INSTALL_DATA) $$file \
- $(DESTDIR)$(itoolsdir)/include/$$realfile ; \
+ $(DESTDIR)$(itoolsdatadir)/include/$$realfile ; \
done
- $(INSTALL_DATA) xlimits.h $(DESTDIR)$(itoolsdir)/include/limits.h
+ $(INSTALL_DATA) xlimits.h $(DESTDIR)$(itoolsdatadir)/include/limits.h
if [ x$(STMP_FIXINC) != x ] ; then \
$(INSTALL_DATA) $(srcdir)/README-fixinc \
- $(DESTDIR)$(itoolsdir)/include/README ; \
- $(INSTALL_PROGRAM) fixinc.sh $(DESTDIR)$(itoolsdir)/fixinc.sh ; \
+ $(DESTDIR)$(itoolsdatadir)/include/README ; \
+ $(INSTALL_SCRIPT) fixinc.sh $(DESTDIR)$(itoolsdir)/fixinc.sh ; \
$(INSTALL_PROGRAM) fixinc/fixincl $(DESTDIR)$(itoolsdir)/fixincl ; \
- $(INSTALL_DATA) $(srcdir)/gsyslimits.h $(DESTDIR)$(itoolsdir)/gsyslimits.h ; \
+ $(INSTALL_DATA) $(srcdir)/gsyslimits.h \
+ $(DESTDIR)$(itoolsdatadir)/gsyslimits.h ; \
else :; fi
if [ x$(STMP_FIXPROTO) != x ] ; then \
- $(INSTALL_PROGRAM) $(srcdir)/mkinstalldirs \
+ $(INSTALL_SCRIPT) $(srcdir)/mkinstalldirs \
$(DESTDIR)$(itoolsdir)/mkinstalldirs ; \
- $(INSTALL_PROGRAM) $(srcdir)/fixproto $(DESTDIR)$(itoolsdir)/fixproto ; \
+ $(INSTALL_SCRIPT) $(srcdir)/fixproto $(DESTDIR)$(itoolsdir)/fixproto ; \
$(INSTALL_PROGRAM) fix-header$(build_exeext) \
$(DESTDIR)$(itoolsdir)/fix-header$(build_exeext) ; \
else :; fi
- $(INSTALL_PROGRAM) mkheaders $(DESTDIR)$(itoolsdir)/mkheaders
- echo 'SYSTEM_HEADER_DIR="$(SYSTEM_HEADER_DIR)"' \
- > $(DESTDIR)$(itoolsdir)/mkheaders.conf
+ $(INSTALL_SCRIPT) mkheaders $(DESTDIR)$(itoolsdir)/mkheaders
+ echo 'SYSTEM_HEADER_DIR="'"$(SYSTEM_HEADER_DIR)"'"' \
+ > $(DESTDIR)$(itoolsdatadir)/mkheaders.conf
echo 'OTHER_FIXINCLUDES_DIRS="$(OTHER_FIXINCLUDES_DIRS)"' \
- >> $(DESTDIR)$(itoolsdir)/mkheaders.conf
+ >> $(DESTDIR)$(itoolsdatadir)/mkheaders.conf
echo 'FIXPROTO_DEFINES="$(FIXPROTO_DEFINES)"' \
- >> $(DESTDIR)$(itoolsdir)/mkheaders.conf
- echo 'STMP_FIXPROTO="$(STMP_FIXPROTO)"' >> $(DESTDIR)$(itoolsdir)/mkheaders.conf
- echo 'STMP_FIXINC="$(STMP_FIXINC)"' >> $(DESTDIR)$(itoolsdir)/mkheaders.conf
+ >> $(DESTDIR)$(itoolsdatadir)/mkheaders.conf
+ echo 'STMP_FIXPROTO="$(STMP_FIXPROTO)"' \
+ >> $(DESTDIR)$(itoolsdatadir)/mkheaders.conf
+ echo 'STMP_FIXINC="$(STMP_FIXINC)"' \
+ >> $(DESTDIR)$(itoolsdatadir)/mkheaders.conf
# Use this target to install the program `collect2' under the name `collect2'.
install-collect2: collect2 installdirs
- $(INSTALL_PROGRAM) collect2$(exeext) $(DESTDIR)$(libsubdir)/collect2$(exeext)
+ $(INSTALL_PROGRAM) collect2$(exeext) $(DESTDIR)$(libexecsubdir)/collect2$(exeext)
# Install the driver program as $(libsubdir)/gcc for collect2.
- $(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(libsubdir)/gcc$(exeext)
+ $(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(libexecsubdir)/gcc$(exeext)
# Cancel installation by deleting the installed files.
-uninstall: intl.uninstall lang.uninstall
+uninstall: lang.uninstall
-rm -rf $(DESTDIR)$(libsubdir)
+ -rm -rf $(DESTDIR)$(libexecsubdir)
-rm -rf $(DESTDIR)$(bindir)/$(GCC_INSTALL_NAME)$(exeext)
- -rm -rf $(DESTDIR)$(bindir)/$(GCC_CROSS_NAME)$(exeext)
-rm -f $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext)
- -rm -f $(DESTDIR)$(bindir)/$(CPP_CROSS_NAME)$(exeext)
-if [ x$(cpp_install_dir) != x ]; then \
rm -f $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \
- rm -f $(DESTDIR)$(prefix)/$(cpp_install_dir)/$(CPP_CROSS_NAME)$(exeext); \
else true; fi
-rm -rf $(DESTDIR)$(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext)
- -rm -rf $(DESTDIR)$(bindir)/$(PROTOIZE_CROSS_NAME)$(exeext)
-rm -rf $(DESTDIR)$(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext)
- -rm -rf $(DESTDIR)$(bindir)/$(UNPROTOIZE_CROSS_NAME)$(exeext)
-rm -rf $(DESTDIR)$(bindir)/$(GCOV_INSTALL_NAME)$(exeext)
-rm -rf $(DESTDIR)$(man1dir)/$(GCC_INSTALL_NAME)$(man1ext)
- -rm -rf $(DESTDIR)$(man1dir)/$(GCC_CROSS_NAME)$(man1ext)
-rm -rf $(DESTDIR)$(man1dir)/cpp$(man1ext)
-rm -rf $(DESTDIR)$(man1dir)/protoize$(man1ext)
-rm -rf $(DESTDIR)$(man1dir)/unprotoize$(man1ext)
@@ -3085,7 +3118,6 @@ uninstall: intl.uninstall lang.uninstall
# These targets are for the dejagnu testsuites. The file site.exp
# contains global variables that all the testsuites will use.
-# Set to $(target_alias)/ for cross.
target_subdir = @target_subdir@
site.exp: ./config.status Makefile
@@ -3098,13 +3130,13 @@ site.exp: ./config.status Makefile
@echo "# add them to the last section" >> ./tmp0
@echo "set rootme \"`${PWD_COMMAND}`\"" >> ./tmp0
@echo "set srcdir \"`cd ${srcdir}; ${PWD_COMMAND}`\"" >> ./tmp0
- @echo "set host_triplet $(host_canonical)" >> ./tmp0
- @echo "set build_triplet $(build_canonical)" >> ./tmp0
+ @echo "set host_triplet $(host)" >> ./tmp0
+ @echo "set build_triplet $(build)" >> ./tmp0
@echo "set target_triplet $(target)" >> ./tmp0
- @echo "set target_alias $(target_alias)" >> ./tmp0
+ @echo "set target_alias $(target_noncanonical)" >> ./tmp0
# CFLAGS is set even though it's empty to show we reserve the right to set it.
@echo "set CFLAGS \"\"" >> ./tmp0
- @echo "set CXXFLAGS \"-I$(objdir)/../$(target_subdir)libio -I\$$srcdir/../libg++/src -I\$$srcdir/../libio -I\$$srcdir/../libstdc++ -I\$$srcdir/../libstdc++/stl -L$(objdir)/../$(target_subdir)libg++ -L$(objdir)/../$(target_subdir)libstdc++\"" >> ./tmp0
+ @echo "set CXXFLAGS \"\"" >> ./tmp0
@echo "set TESTING_IN_BUILD_TREE 1" >> ./tmp0
@echo "set HAVE_LIBSTDCXX_V3 1" >> ./tmp0
# If newlib has been configured, we need to pass -B to gcc so it can find
@@ -3116,9 +3148,10 @@ site.exp: ./config.status Makefile
# ??? Another way to solve this might be to rely on linker scripts. Then
# theoretically the -B won't be needed.
# We also need to pass -L ../ld so that the linker can find ldscripts.
- @if [ -d $(objdir)/../$(target_subdir)newlib ] ; then \
- echo "set newlib_cflags \"-I$(objdir)/../$(target_subdir)newlib/targ-include -I\$$srcdir/../newlib/libc/include\"" >> ./tmp0; \
- echo "set newlib_ldflags \"-B$(objdir)/../$(target_subdir)newlib/\"" >> ./tmp0; \
+ @if [ -d $(objdir)/../$(target_subdir)/newlib ] \
+ && [ "${host}" != "${target}" ]; then \
+ echo "set newlib_cflags \"-I$(objdir)/../$(target_subdir)/newlib/targ-include -I\$$srcdir/../newlib/libc/include\"" >> ./tmp0; \
+ echo "set newlib_ldflags \"-B$(objdir)/../$(target_subdir)/newlib/\"" >> ./tmp0; \
echo "append CFLAGS \" \$$newlib_cflags\"" >> ./tmp0; \
echo "append CXXFLAGS \" \$$newlib_cflags\"" >> ./tmp0; \
echo "append LDFLAGS \" \$$newlib_ldflags\"" >> ./tmp0; \
@@ -3130,12 +3163,16 @@ site.exp: ./config.status Makefile
fi
echo "set tmpdir $(objdir)/testsuite" >> ./tmp0
@echo "set srcdir \"\$${srcdir}/testsuite\"" >> ./tmp0
+ @if [ "X$(ALT_CC_UNDER_TEST)" != "X" ] ; then \
+ echo "set ALT_CC_UNDER_TEST \"$(ALT_CC_UNDER_TEST)\"" >> ./tmp0; \
+ else true; \
+ fi
@if [ "X$(ALT_CXX_UNDER_TEST)" != "X" ] ; then \
- echo "set ALT_CXX_UNDER_TEST $(ALT_CXX_UNDER_TEST)" >> ./tmp0; \
+ echo "set ALT_CXX_UNDER_TEST \"$(ALT_CXX_UNDER_TEST)\"" >> ./tmp0; \
else true; \
fi
@if [ "X$(COMPAT_OPTIONS)" != "X" ] ; then \
- echo "set COMPAT_OPTIONS $(COMPAT_OPTIONS)" >> ./tmp0; \
+ echo "set COMPAT_OPTIONS \"$(COMPAT_OPTIONS)\"" >> ./tmp0; \
else true; \
fi
@echo "## All variables above are generated by configure. Do Not Edit ##" >> ./tmp0
@@ -3146,10 +3183,6 @@ site.exp: ./config.status Makefile
CHECK_TARGETS = check-gcc @check_languages@
-check-c++ : check-g++
-check-f77 : check-g77
-check-java :
-
check: $(CHECK_TARGETS)
# The idea is to parallelize testing of multilibs, for example:
@@ -3157,7 +3190,8 @@ check: $(CHECK_TARGETS)
# will run 3 concurrent sessions of check-gcc, eventually testing
# all 10 combinations. GNU make is required, as is a shell that expands
# alternations within braces.
-check-gcc//% check-g++//% check-g77//% check-objc//%: site.exp
+lang_checks_parallel = $(lang_checks:=//%)
+$(lang_checks_parallel): site.exp
target=`echo "$@" | sed 's,//.*,,'`; \
variant=`echo "$@" | sed 's,^[^/]*//,,'`; \
vardots=`echo "$$variant" | sed 's,/,.,g'`; \
@@ -3172,7 +3206,7 @@ $(TESTSUITEDIR)/site.exp: site.exp
-rm -f $@
sed '/set tmpdir/ s|testsuite|$(TESTSUITEDIR)|' < site.exp > $@
-check-g++: $(TESTSUITEDIR)/site.exp
+$(lang_checks): check-% : $(TESTSUITEDIR)/site.exp
-(rootme=`${PWD_COMMAND}`; export rootme; \
srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
cd $(TESTSUITEDIR); \
@@ -3180,37 +3214,7 @@ check-g++: $(TESTSUITEDIR)/site.exp
if [ -f $${rootme}/../expect/expect ] ; then \
TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
export TCL_LIBRARY ; fi ; \
- $(RUNTEST) --tool g++ $(RUNTESTFLAGS))
-
-check-gcc: $(TESTSUITEDIR)/site.exp
- -(rootme=`${PWD_COMMAND}`; export rootme; \
- srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
- cd $(TESTSUITEDIR); \
- EXPECT=${EXPECT} ; export EXPECT ; \
- if [ -f $${rootme}/../expect/expect ] ; then \
- TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
- export TCL_LIBRARY ; fi ; \
- $(RUNTEST) --tool gcc $(RUNTESTFLAGS))
-
-check-g77: $(TESTSUITEDIR)/site.exp
- -(rootme=`${PWD_COMMAND}`; export rootme; \
- srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
- cd $(TESTSUITEDIR); \
- EXPECT=${EXPECT} ; export EXPECT ; \
- if [ -f $${rootme}/../expect/expect ] ; then \
- TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
- export TCL_LIBRARY ; fi ; \
- $(RUNTEST) --tool g77 $(RUNTESTFLAGS))
-
-check-objc: $(TESTSUITEDIR)/site.exp
- -(rootme=`${PWD_COMMAND}`; export rootme; \
- srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
- cd $(TESTSUITEDIR); \
- EXPECT=${EXPECT} ; export EXPECT ; \
- if [ -f $${rootme}/../expect/expect ] ; then \
- TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
- export TCL_LIBRARY ; fi ; \
- $(RUNTEST) --tool objc $(RUNTESTFLAGS))
+ $(RUNTEST) --tool $* $(RUNTESTFLAGS))
check-consistency: testsuite/site.exp
-rootme=`${PWD_COMMAND}`; export rootme; \
@@ -3231,13 +3235,13 @@ QMTEST_PATH=qmtest
QMTESTFLAGS=
# The flags to pass to "qmtest run".
-QMTESTRUNFLAGS=
+QMTESTRUNFLAGS=-f none --result-stream dejagnu_stream.DejaGNUStream
# The command to use to invoke qmtest.
QMTEST=${QMTEST_PATH} ${QMTESTFLAGS}
# The tests (or suites) to run.
-QMTEST_GPP_TESTS=gpp
+QMTEST_GPP_TESTS=g++
# The subdirectory of the OBJDIR that will be used to store the QMTest
# test database configuration and that will be used for temporary
@@ -3246,48 +3250,32 @@ QMTEST_DIR=qmtestsuite
# Create the QMTest database configuration.
${QMTEST_DIR} stamp-qmtest:
- debug_options=""; \
- ${STAMP} empty.C; \
- for option in \
- -gdwarf-2 -gstabs -gstabs+ -gxcoff -gxcoff+ -gcoff; do \
- (./cc1plus -q $${option} empty.C 2>&1 | \
- grep "unknown or unsupported -g option" > /dev/null) || \
- debug_options="$${debug_options}$${option} "; done; \
- ${QMTEST} -D ${QMTEST_DIR} create-tdb \
- -c gcc_database.GCCDatabase \
- -a GCCDatabase.testsuite_root=`cd ${srcdir}/testsuite && pwd` \
- -a GCCDatabase.debug_options="$${debug_options}"
- rm -f empty.C empty.s
- $(STAMP) stamp-qmtest
+ ${QMTEST} -D ${QMTEST_DIR} create-tdb \
+ -c gcc_database.GCCDatabase \
+ -a srcdir=`cd ${srcdir}/testsuite && ${PWD_COMMAND}` && \
+ $(STAMP) stamp-qmtest
# Create the QMTest context file.
${QMTEST_DIR}/context: stamp-qmtest
- echo "GCCTest.flags=-B${objdir}" >> $@
- echo "GCCTest.objdir=${objdir}/.." >> $@
- echo "GCCTest.host=${host_canonical}" >> $@
- echo "GCCTest.target=${target}" >> $@
- echo "GCCTest.gcov=${objdir}/gcov" >> $@
- echo "GPPTest.gpp=${objdir}/g++" >> $@
- echo "DGTest.demangler=${objdir}/c++filt" >> $@
+ rm -f $@
+ echo "CompilerTable.languages=c cplusplus" >> $@
+ echo "CompilerTable.c_kind=GCC" >> $@
+ echo "CompilerTable.c_path=${objdir}/xgcc" >> $@
+ echo "CompilerTable.c_options=-B${objdir}/" >> $@
+ echo "CompilerTable.cplusplus_kind=GCC" >> $@
+ echo "CompilerTable.cplusplus_path=${objdir}/g++" >> $@
+ echo "CompilerTable.cplusplus_options=-B${objdir}/" >> $@
+ echo "DejaGNUTest.target=${target_noncanonical}" >> $@
# Run the G++ testsuite using QMTest.
-qmtest-g++: ${QMTEST_DIR}/context ${QMTEST_DIR}/gpp-expected.qmr
+qmtest-g++: ${QMTEST_DIR}/context
cd ${QMTEST_DIR} && ${QMTEST} run ${QMTESTRUNFLAGS} -C context \
- -o gpp.qmr -O gpp-expected.qmr \
- ${QMTEST_GPP_TESTS}
+ -o g++.qmr ${QMTEST_GPP_TESTS}
# Use the QMTest GUI.
qmtest-gui: ${QMTEST_DIR}/context
cd ${QMTEST_DIR} && ${QMTEST} gui -C context
-# Build the set of expected G++ failures.
-${QMTEST_DIR}/gpp-expected.qmr: ${QMTEST_DIR}/context
- echo "Determining expected results..."
- cd ${QMTEST_DIR} && ${QMTEST} run ${QMTESTRUNFLAGS} -C context \
- -c "GCCTest.generate_xfails=1" -o gpp-expected.qmr \
- ${QMTEST_GPP_TESTS} \
- > /dev/null
-
.PHONY: qmtest-g++
# Run Paranoia on real.c.
@@ -3302,13 +3290,24 @@ paranoia: paranoia.o real.o $(LIBIBERTY)
# These exist for maintenance purposes.
# Update the tags table.
-TAGS: force
- (cd $(srcdir); \
- mkdir tmp-tags; \
- mv -f c-parse.[ch] =*.[chy] tmp-tags; \
- etags *.y *.h *.c; \
- mv tmp-tags/* .; \
- rmdir tmp-tags)
+TAGS: lang.tags
+ (cd $(srcdir); \
+ incs= ; \
+ list='$(SUBDIRS)'; for dir in $$list; do \
+ if test -f $$dir/TAGS; then \
+ incs="$$incs --include $$dir/TAGS.sub"; \
+ fi; \
+ done; \
+ mkdir tmp-tags; \
+ mv -f c-parse.[ch] tmp-tags; \
+ etags -o TAGS.sub *.y *.h *.c; \
+ mv tmp-tags/* .; \
+ rmdir tmp-tags; \
+ etags --include TAGS.sub $$incs)
+
+# ------------------------------------------------------
+# Bootstrap-related targets (not used during 'make all')
+# ------------------------------------------------------
# A list of files to be destroyed during "lean" builds.
VOL_FILES=`echo $(BACKEND) $(OBJS) $(C_OBJS) $(LIBCPP_OBJS) *.c *.h gen*`
@@ -3316,30 +3315,42 @@ VOL_FILES=`echo $(BACKEND) $(OBJS) $(C_OBJS) $(LIBCPP_OBJS) *.c *.h gen*`
# Flags to pass to stage2 and later recursive makes. Note that the
# WARN_CFLAGS setting can't be to the expansion of GCC_WARN_CFLAGS in
# the context of the stage_x rule.
-STAGE2_FLAGS_TO_PASS = \
- ADAC="\$$(CC)" \
- AR_FOR_TARGET="$(AR_FOR_TARGET)" \
- RANLIB_FOR_TARGET="$(RANLIB_FOR_TARGET)" \
+
+POSTSTAGE1_FLAGS_TO_PASS = \
+ ADAFLAGS="$(BOOT_ADAFLAGS)" \
CFLAGS="$(BOOT_CFLAGS)" \
LDFLAGS="$(BOOT_LDFLAGS)" \
WARN_CFLAGS="\$$(GCC_WARN_CFLAGS)" \
STRICT_WARN="$(STRICT2_WARN)" \
libdir=$(libdir) \
LANGUAGES="$(LANGUAGES)" \
+ MAKEINFO="$(MAKEINFO)" \
+ MAKEINFOFLAGS="$(MAKEINFOFLAGS)" \
MAKEOVERRIDES= \
OUTPUT_OPTION="-o \$$@"
+STAGE2_FLAGS_TO_PASS = \
+ CFLAGS="$(BOOT_CFLAGS)" \
+ WERROR="@WERROR@" \
+
+STAGEPROFILE_FLAGS_TO_PASS = \
+ CFLAGS="$(BOOT_CFLAGS) -fprofile-generate"
+
+# Files never linked into the final executable produces warnings about missing
+# profile.
+STAGEFEEDBACK_FLAGS_TO_PASS = \
+ CFLAGS="$(BOOT_CFLAGS) -fprofile-use"
+
# Only build the C compiler for stage1, because that is the only one that
# we can guarantee will build with the native compiler, and also it is the
# only thing useful for building stage2. STAGE1_CFLAGS (via CFLAGS),
# MAKEINFO and MAKEINFOFLAGS are explicitly passed here to make them
# overrideable (for a bootstrap build stage1 also builds gcc.info).
stage1_build:
- $(MAKE) AR_FOR_TARGET="$(AR_FOR_TARGET)" \
- RANLIB_FOR_TARGET="$(RANLIB_FOR_TARGET)" \
- CC="$(CC)" libdir=$(libdir) LANGUAGES="$(BOOT_LANGUAGES)" \
+ $(MAKE) CC="$(CC)" libdir=$(libdir) LANGUAGES="$(BOOT_LANGUAGES)" \
CFLAGS="$(STAGE1_CFLAGS)" MAKEINFO="$(MAKEINFO)" \
- MAKEINFOFLAGS="$(MAKEINFOFLAGS)" COVERAGE_FLAGS=
+ MAKEINFOFLAGS="$(MAKEINFOFLAGS)" COVERAGE_FLAGS= \
+ OBJS-onestep="$(OBJS)"
$(STAMP) stage1_build
echo stage1_build > stage_last
@@ -3349,8 +3360,9 @@ stage1_copy: stage1_build
echo stage2_build > stage_last
stage2_build: stage1_copy
- $(MAKE) CC="$(STAGE_CC_WRAPPER) stage1/xgcc$(exeext) -Bstage1/ -B$(build_tooldir)/bin/" \
+ $(MAKE) CC="$(STAGE_CC_WRAPPER) stage1/xgcc$(exeext) -Bstage1/ -B$(build_tooldir)/bin/" CC_FOR_BUILD="$(STAGE_CC_WRAPPER) stage1/xgcc$(exeext) -Bstage1/ -B$(build_tooldir)/bin/" \
STAGE_PREFIX=stage1/ \
+ $(POSTSTAGE1_FLAGS_TO_PASS) \
$(STAGE2_FLAGS_TO_PASS)
$(STAMP) stage2_build
echo stage2_build > stage_last
@@ -3360,13 +3372,40 @@ stage2_copy: stage2_build
$(STAMP) stage2_copy
echo stage3_build > stage_last
+stageprofile_build: stage1_copy
+ $(MAKE) CC="$(STAGE_CC_WRAPPER) stage1/xgcc$(exeext) -Bstage1/ -B$(build_tooldir)/bin/" CC_FOR_BUILD="$(STAGE_CC_WRAPPER) stage1/xgcc$(exeext) -Bstage1/ -B$(build_tooldir)/bin/" \
+ STAGE_PREFIX=stage1/ \
+ $(POSTSTAGE1_FLAGS_TO_PASS) \
+ $(STAGEPROFILE_FLAGS_TO_PASS)
+ $(STAMP) stageprofile_build
+ echo stageprofile_build > stage_last
+
+stageprofile_copy: stageprofile_build
+ $(MAKE) stageprofile
+ $(STAMP) stageprofile_copy
+ echo stagefeedback_build > stage_last
+
stage3_build: stage2_copy
- $(MAKE) CC="$(STAGE_CC_WRAPPER) stage2/xgcc$(exeext) -Bstage2/ -B$(build_tooldir)/bin/" \
+ $(MAKE) CC="$(STAGE_CC_WRAPPER) stage2/xgcc$(exeext) -Bstage2/ -B$(build_tooldir)/bin/" CC_FOR_BUILD="$(STAGE_CC_WRAPPER) stage2/xgcc$(exeext) -Bstage2/ -B$(build_tooldir)/bin/" \
STAGE_PREFIX=stage2/ \
+ $(POSTSTAGE1_FLAGS_TO_PASS) \
$(STAGE2_FLAGS_TO_PASS)
$(STAMP) stage3_build
echo stage3_build > stage_last
+stagefeedback_build: stageprofile_copy stage1_copy
+ $(MAKE) CC="$(STAGE_CC_WRAPPER) stage1/xgcc$(exeext) -Bstage1/ -B$(build_tooldir)/bin/" CC_FOR_BUILD="$(STAGE_CC_WRAPPER) stage1/xgcc$(exeext) -Bstage1/ -B$(build_tooldir)/bin/" \
+ STAGE_PREFIX=stage1/ \
+ $(POSTSTAGE1_FLAGS_TO_PASS) \
+ $(STAGEFEEDBACK_FLAGS_TO_PASS)
+ $(STAMP) stagefeedback_build
+ echo stagefeedback_build > stage_last
+
+stagefeedback_copy: stagefeedback_build
+ $(MAKE) stagefeedback
+ $(STAMP) stagefeedback_copy
+ echo stagefeedback2_build > stage_last
+
# For bootstrap4:
stage3_copy: stage3_build
$(MAKE) stage3
@@ -3374,8 +3413,9 @@ stage3_copy: stage3_build
echo stage4_build > stage_last
stage4_build: stage3_copy
- $(MAKE) CC="$(STAGE_CC_WRAPPER) stage3/xgcc$(exeext) -Bstage3/ -B$(build_tooldir)/bin/" \
+ $(MAKE) CC="$(STAGE_CC_WRAPPER) stage3/xgcc$(exeext) -Bstage3/ -B$(build_tooldir)/bin/" CC_FOR_BUILD="$(STAGE_CC_WRAPPER) stage3/xgcc$(exeext) -Bstage3/ -B$(build_tooldir)/bin/" \
STAGE_PREFIX=stage3/ \
+ $(POSTSTAGE1_FLAGS_TO_PASS) \
$(STAGE2_FLAGS_TO_PASS)
$(STAMP) stage4_build
echo stage4_build > stage_last
@@ -3411,12 +3451,13 @@ bootstrap3 bootstrap3-lean: bootstrap
bootstrap4 bootstrap4-lean: stage4_build
-unstage1 unstage2 unstage3 unstage4:
+unstage1 unstage2 unstage3 unstage4 unstageprofile unstagefeedback:
-set -vx; stage=`echo $@ | sed -e 's/un//'`; \
rm -f $$stage/as$(exeext); \
rm -f $$stage/ld$(exeext); \
rm -f $$stage/collect-ld$(exeext); \
if test -d $$stage; then \
+ mv $$stage/specs $(SPECS) 2>/dev/null || :; \
mv $$stage/* . 2>/dev/null; \
for i in `cd $$stage; echo *` ; do \
if test -d $$stage/$$i; then \
@@ -3430,75 +3471,104 @@ unstage1 unstage2 unstage3 unstage4:
echo $${stage}_build > stage_last
restage1: unstage1
- $(MAKE) stage1_build
+ $(MAKE) $(REMAKEFLAGS) stage1_build
restage2: unstage2
- $(MAKE) LANGUAGES="$(LANGUAGES)" stage2_build
+ $(MAKE) $(REMAKEFLAGS) stage2_build
restage3: unstage3
- $(MAKE) LANGUAGES="$(LANGUAGES)" stage3_build
+ $(MAKE) $(REMAKEFLAGS) stage3_build
restage4: unstage4
- $(MAKE) LANGUAGES="$(LANGUAGES)" stage4_build
+ $(MAKE) $(REMAKEFLAGS) stage4_build
+
+restageprofile: unstageprofile
+ $(MAKE) $(REMAKEFLAGS) stageprofile_build
+restagefeedback: unstagefeedback
+ $(MAKE) $(REMAKEFLAGS) stagefeedback_build
+
+# Bubble up a bugfix through all the stages. Primarily useful for fixing
+# bugs that cause the compiler to crash while building stage 2.
bubblestrap:
- if test -f stage3_build; then true; else \
- echo; echo You must \"make bootstrap\" first.; \
- exit 1; \
+ if test -f stage_last; then \
+ LAST=`sed -e 's/_build//' < stage_last`; \
+ if test "$$LAST" != "stage1"; then \
+ $(MAKE) $(REMAKEFLAGS) $$LAST; \
+ $(STAMP) $${LAST}_copy; \
+ fi; \
+ fi
+ if test -f stage1_copy; then $(MAKE) unstage1; fi
+ $(MAKE) $(REMAKEFLAGS) stage1_copy
+ if test -f stage2_copy; then $(MAKE) unstage2; fi
+ $(MAKE) $(REMAKEFLAGS) stage2_copy
+ if test -f stage3_copy; then $(MAKE) unstage3; fi
+ $(MAKE) $(REMAKEFLAGS) stage3_build
+ if test -f stage4_copy; then \
+ $(MAKE) $(REMAKEFLAGS) stage3_copy; $(MAKE) unstage4; \
+ $(MAKE) $(REMAKEFLAGS) stage4_build || exit 1; \
fi
- for i in stage3 \
- unstage1 stage1_build stage1_copy \
- unstage2 stage2_build stage2_copy \
- unstage3 stage3_build ; \
- do \
- $(MAKE) LANGUAGES="$(LANGUAGES)" $$i || exit 1 ; \
- done
quickstrap:
if test -f stage_last ; then \
- LAST=`cat stage_last`; rm $$LAST; $(MAKE) LANGUAGES="$(LANGUAGES)" $$LAST; \
+ LAST=`cat stage_last`; rm $$LAST; $(MAKE) $(REMAKEFLAGS) $$LAST; \
else \
- $(MAKE) stage1_build; \
+ $(MAKE) $(REMAKEFLAGS) stage1_build; \
fi
cleanstrap:
-$(MAKE) clean
- $(MAKE) LANGUAGES="$(LANGUAGES)" bootstrap
+ $(MAKE) $(REMAKEFLAGS) bootstrap
unstrap:
-rm -rf stage[234]*
$(MAKE) unstage1
+ -rm -f stage_last
# Differs from cleanstrap in that it starts from the earlier stage1 build,
# not from scratch.
restrap:
$(MAKE) unstrap
- $(MAKE) LANGUAGES="$(LANGUAGES)" bootstrap
-
-# Compare the object files in the current directory with those in the
-# stage2 directory.
-
-# ./ avoids bug in some versions of tail.
-compare compare3 compare4 compare-lean compare3-lean compare4-lean: force
+ $(MAKE) $(REMAKEFLAGS) bootstrap
+
+# These targets compare the object files in the current directory with
+# those in a stage directory. We need to skip the first N bytes of
+# each object file. The "slow" mechanism assumes nothing special
+# about cmp and uses the tail command to skip. ./ avoids a bug in
+# some versions of tail. The "gnu" targets use gnu cmp (diffutils
+# v2.4 or later), to avoid running tail and the overhead of twice
+# copying each object file. Likewise, the "fast" targets use the skip
+# parameter of cmp available on some systems to accomplish the same
+# thing. An exit status of 1 is precisely the result we're looking
+# for (other values mean other problems).
+slowcompare slowcompare3 slowcompare4 slowcompare-lean slowcompare3-lean slowcompare4-lean \
+fastcompare fastcompare3 fastcompare4 fastcompare-lean fastcompare3-lean fastcompare4-lean \
+ gnucompare gnucompare3 gnucompare4 gnucompare-lean gnucompare3-lean gnucompare4-lean: force
-rm -f .bad_compare
- case "$@" in compare | compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
- for file in *$(objext); do \
- tail +16c ./$$file > tmp-foo1; \
- tail +16c stage$$stage/$$file > tmp-foo2 \
- && (cmp tmp-foo1 tmp-foo2 > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \
- done
- case "$@" in compare | compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
- for dir in tmp-foo intl $(SUBDIRS); do \
+ case "$@" in *compare | *compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^[a-z]*compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
+ for dir in . $(SUBDIRS); do \
if [ "`echo $$dir/*$(objext)`" != "$$dir/*$(objext)" ] ; then \
for file in $$dir/*$(objext); do \
- tail +16c ./$$file > tmp-foo1; \
- tail +16c stage$$stage/$$file > tmp-foo2 \
- && (cmp tmp-foo1 tmp-foo2 > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \
+ case "$@" in \
+ slowcompare* ) \
+ tail +16c ./$$file > tmp-foo1; \
+ tail +16c stage$$stage/$$file > tmp-foo2 \
+ && (cmp tmp-foo1 tmp-foo2 > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \
+ ;; \
+ fastcompare* ) \
+ cmp $$file stage$$stage/$$file 16 16 > /dev/null 2>&1; \
+ test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
+ ;; \
+ gnucompare* ) \
+ cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1; \
+ test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
+ ;; \
+ esac ; \
done; \
else true; fi; \
done
-rm -f tmp-foo*
- case "$@" in compare | compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
+ case "$@" in *compare | *compare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^[a-z]*compare\([0-9][0-9]*\).*,\1,'` ;; esac; \
if [ -f .bad_compare ]; then \
echo "Bootstrap comparison failure!"; \
cat .bad_compare; \
@@ -3510,91 +3580,75 @@ compare compare3 compare4 compare-lean compare3-lean compare4-lean: force
esac; true; \
fi
-# Compare the object files in the current directory with those in the
-# stage2 directory. Use gnu cmp (diffutils v2.4 or later) to avoid
-# running tail and the overhead of twice copying each object file.
-# An exit status of 1 is precisely the result we're looking for (other
-# values mean other problems).
-gnucompare gnucompare3 gnucompare4 gnucompare-lean gnucompare3-lean gnucompare4-lean: force
- -rm -f .bad_compare
- case "$@" in gnucompare | gnucompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^gnucompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
- for file in *$(objext); do \
- cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1; \
- test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
- done
- case "$@" in gnucompare | gnucompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^gnucompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
- for dir in tmp-foo intl $(SUBDIRS); do \
- if [ "`echo $$dir/*$(objext)`" != "$$dir/*$(objext)" ] ; then \
- for file in $$dir/*$(objext); do \
- cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1; \
- test $$? -eq 1 && echo $$file differs >> .bad_compare || true; \
- done; \
- else true; fi; \
- done
- case "$@" in gnucompare | gnucompare-lean ) stage=2 ;; * ) stage=`echo $@ | sed -e 's,^gnucompare\([0-9][0-9]*\).*,\1,'` ;; esac; \
- if [ -f .bad_compare ]; then \
- echo "Bootstrap comparison failure!"; \
- cat .bad_compare; \
- exit 1; \
- else \
- case "$@" in \
- *-lean ) rm -rf stage$$stage ;; \
- esac; true; \
- fi
+# Forwarding wrappers to the most appropriate version.
+compare: @make_compare_target@
+compare3: @make_compare_target@3
+compare4: @make_compare_target@4
+compare-lean: @make_compare_target@-lean
+compare3-lean: @make_compare_target@3-lean
+compare4-lean: @make_compare_target@4-lean
# Copy the object files from a particular stage into a subdirectory.
stage1-start:
-if [ -d stage1 ] ; then true ; else mkdir stage1 ; fi
$(MAKE) -f libgcc.mk libgcc-stage-start stage=stage1
- -for dir in intl $(SUBDIRS) ; \
+ -subdirs="$(SUBDIRS)"; for dir in $$subdirs; \
do \
if [ -d stage1/$$dir ] ; then true ; else mkdir stage1/$$dir ; fi ; \
done
+# If SPECS is overridden, make sure it is `installed' as specs.
+ -mv $(SPECS) stage1/specs
-mv $(STAGESTUFF) stage1
- -mv intl/*$(objext) stage1/intl
# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
# dir will work properly.
-if [ -f as$(exeext) ] ; then (cd stage1 && $(LN_S) ../as$(exeext) .) ; else true ; fi
-if [ -f ld$(exeext) ] ; then (cd stage1 && $(LN_S) ../ld$(exeext) .) ; else true ; fi
-if [ -f collect-ld$(exeext) ] ; then (cd stage1 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
- -rm -f stage1/libgcc.a stage1/libgcc_eh.a
+ -rm -f stage1/libgcc.a stage1/libgcc_eh.a stage1/libgcov.a
+ -rm -f stage1/libgcc_s*$(SHLIB_EXT)
-cp libgcc.a stage1
- -if $(RANLIB_TEST_FOR_TARGET) ; then \
- $(RANLIB_FOR_TARGET) stage1/libgcc.a; \
- else true; fi
+ -$(RANLIB_FOR_TARGET) stage1/libgcc.a
+ -cp libgcov.a stage1
+ -$(RANLIB_FOR_TARGET) stage1/libgcov.a
-if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage1; \
- if $(RANLIB_TEST_FOR_TARGET) ; then \
$(RANLIB_FOR_TARGET) stage1/libgcc_eh.a; \
- else true; fi; fi
+ fi
+ -cp libgcc_s*$(SHLIB_EXT) stage1
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
cp stage1/$${f} . ; \
else true; \
fi; done
stage1: force stage1-start lang.stage1
+ -for dir in . $(SUBDIRS) ; \
+ do \
+ rm -f $$dir/*$(coverageexts) ; \
+ done
stage2-start:
-if [ -d stage2 ] ; then true ; else mkdir stage2 ; fi
$(MAKE) -f libgcc.mk libgcc-stage-start stage=stage2
- -for dir in intl $(SUBDIRS) ; \
+ -subdirs="$(SUBDIRS)"; for dir in $$subdirs; \
do \
if [ -d stage2/$$dir ] ; then true ; else mkdir stage2/$$dir ; fi ; \
done
+# If SPECS is overridden, make sure it is `installed' as specs.
+ -mv $(SPECS) stage2/specs
-mv $(STAGESTUFF) stage2
- -mv intl/*$(objext) stage2/intl
# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
# dir will work properly.
-if [ -f as$(exeext) ] ; then (cd stage2 && $(LN_S) ../as$(exeext) .) ; else true ; fi
-if [ -f ld$(exeext) ] ; then (cd stage2 && $(LN_S) ../ld$(exeext) .) ; else true ; fi
-if [ -f collect-ld$(exeext) ] ; then (cd stage2 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
- -rm -f stage2/libgcc.a stage2/libgcc_eh.a
+ -rm -f stage2/libgcc.a stage2/libgcov.a stage2/libgcc_eh.a
+ -rm -f stage2/libgcc_s*$(SHLIB_EXT)
-cp libgcc.a stage2
- -if $(RANLIB_TEST_FOR_TARGET) ; then \
- $(RANLIB_FOR_TARGET) stage2/libgcc.a; \
- else true; fi
+ -$(RANLIB_FOR_TARGET) stage2/libgcc.a
+ -cp libgcov.a stage2
+ -$(RANLIB_FOR_TARGET) stage2/libgcov.a
-if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage2; \
- if $(RANLIB_TEST_FOR_TARGET) ; then \
$(RANLIB_FOR_TARGET) stage2/libgcc_eh.a; \
- else true; fi; fi
+ fi
+ -cp libgcc_s*$(SHLIB_EXT) stage2
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
cp stage2/$${f} . ; \
else true; \
@@ -3604,26 +3658,28 @@ stage2: force stage2-start lang.stage2
stage3-start:
-if [ -d stage3 ] ; then true ; else mkdir stage3 ; fi
$(MAKE) -f libgcc.mk libgcc-stage-start stage=stage3
- -for dir in intl $(SUBDIRS) ; \
+ -subdirs="$(SUBDIRS)"; for dir in $$subdirs; \
do \
if [ -d stage3/$$dir ] ; then true ; else mkdir stage3/$$dir ; fi ; \
done
+# If SPECS is overridden, make sure it is `installed' as specs.
+ -mv $(SPECS) stage3/specs
-mv $(STAGESTUFF) stage3
- -mv intl/*$(objext) stage3/intl
# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
# dir will work properly.
-if [ -f as$(exeext) ] ; then (cd stage3 && $(LN_S) ../as$(exeext) .) ; else true ; fi
-if [ -f ld$(exeext) ] ; then (cd stage3 && $(LN_S) ../ld$(exeext) .) ; else true ; fi
-if [ -f collect-ld$(exeext) ] ; then (cd stage3 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
- -rm -f stage3/libgcc.a stage3/libgcc_eh.a
+ -rm -f stage3/libgcc.a stage3/libgcov.a stage3/libgcc_eh.a
+ -rm -f stage3/libgcc_s*$(SHLIB_EXT)
-cp libgcc.a stage3
- -if $(RANLIB_TEST_FOR_TARGET) ; then \
- $(RANLIB_FOR_TARGET) stage3/libgcc.a; \
- else true; fi
+ -$(RANLIB_FOR_TARGET) stage3/libgcc.a
+ -cp libgcov.a stage3
+ -$(RANLIB_FOR_TARGET) stage3/libgcov.a
-if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage3; \
- if $(RANLIB_TEST_FOR_TARGET) ; then \
$(RANLIB_FOR_TARGET) stage3/libgcc_eh.a; \
- else true; fi; fi
+ fi
+ -cp libgcc_s*$(SHLIB_EXT) stage3
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
cp stage3/$${f} . ; \
else true; \
@@ -3633,32 +3689,97 @@ stage3: force stage3-start lang.stage3
stage4-start:
-if [ -d stage4 ] ; then true ; else mkdir stage4 ; fi
$(MAKE) -f libgcc.mk libgcc-stage-start stage=stage4
- -for dir in intl $(SUBDIRS) ; \
+ -subdirs="$(SUBDIRS)"; for dir in $$subdirs; \
do \
if [ -d stage4/$$dir ] ; then true ; else mkdir stage4/$$dir ; fi ; \
done
+# If SPECS is overridden, make sure it is `installed' as specs.
+ -mv $(SPECS) stage4/specs
-mv $(STAGESTUFF) stage4
- -mv intl/*$(objext) stage4/intl
# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
# dir will work properly.
-if [ -f as$(exeext) ] ; then (cd stage4 && $(LN_S) ../as$(exeext) .) ; else true ; fi
-if [ -f ld$(exeext) ] ; then (cd stage4 && $(LN_S) ../ld$(exeext) .) ; else true ; fi
-if [ -f collect-ld$(exeext) ] ; then (cd stage4 && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
- -rm -f stage4/libgcc.a stage4/libgcc_eh.a
+ -rm -f stage4/libgcc.a stage4/libgcov.a stage4/libgcc_eh.a
+ -rm -f stage4/libgcc_s*$(SHLIB_EXT)
-cp libgcc.a stage4
- -if $(RANLIB_TEST_FOR_TARGET) ; then \
- $(RANLIB_FOR_TARGET) stage4/libgcc.a; \
- else true; fi
+ -$(RANLIB_FOR_TARGET) stage4/libgcc.a
+ -cp libgcov.a stage4
+ -$(RANLIB_FOR_TARGET) stage4/libgcov.a
-if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stage4; \
- if $(RANLIB_TEST_FOR_TARGET) ; then \
$(RANLIB_FOR_TARGET) stage4/libgcc_eh.a; \
- else true; fi; fi
+ fi
+ -cp libgcc_s*$(SHLIB_EXT) stage4
-for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
cp stage4/$${f} . ; \
else true; \
fi; done
stage4: force stage4-start lang.stage4
+stageprofile-start:
+ -if [ -d stageprofile ] ; then true ; else mkdir stageprofile ; fi
+ $(MAKE) -f libgcc.mk libgcc-stage-start stage=stageprofile
+ -subdirs="$(SUBDIRS)"; for dir in $$subdirs; \
+ do \
+ if [ -d stageprofile/$$dir ] ; then true ; else mkdir stageprofile/$$dir ; fi ; \
+ done
+ -mv $(STAGESTUFF) stageprofile
+# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
+# dir will work properly.
+ -if [ -f as$(exeext) ] ; then (cd stageprofile && $(LN_S) ../as$(exeext) .) ; else true ; fi
+ -if [ -f ld$(exeext) ] ; then (cd stageprofile && $(LN_S) ../ld$(exeext) .) ; else true ; fi
+ -if [ -f collect-ld$(exeext) ] ; then (cd stageprofile && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
+ -rm -f stageprofile/libgcc.a stageprofile/libgcov.a stageprofile/libgcc_eh.a
+ -rm -f stageprofile/libgcc_s*$(SHLIB_EXT)
+ -cp libgcc.a stageprofile
+ -$(RANLIB_FOR_TARGET) stageprofile/libgcc.a
+ -cp libgcov.a stageprofile
+ -$(RANLIB_FOR_TARGET) stageprofile/libgcov.a
+ -if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stageprofile; \
+ $(RANLIB_FOR_TARGET) stageprofile/libgcc_eh.a; \
+ fi
+ -cp libgcc_s*$(SHLIB_EXT) stageprofile
+ -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
+ cp stageprofile/$${f} . ; \
+ else true; \
+ fi; done
+stageprofile: force stageprofile-start lang.stageprofile
+
+stagefeedback-start:
+ -if [ -d stagefeedback ] ; then true ; else mkdir stagefeedback ; fi
+ $(MAKE) -f libgcc.mk libgcc-stage-start stage=stagefeedback
+ -subdirs="$(SUBDIRS)"; for dir in $$subdirs; \
+ do \
+ if [ -d stagefeedback/$$dir ] ; then true ; else mkdir stagefeedback/$$dir ; fi ; \
+ done
+ -mv $(STAGESTUFF) stagefeedback
+# Copy as/ld if they exist to stage dir, so that running xgcc from the stage
+# dir will work properly.
+ -if [ -f as$(exeext) ] ; then (cd stagefeedback && $(LN_S) ../as$(exeext) .) ; else true ; fi
+ -if [ -f ld$(exeext) ] ; then (cd stagefeedback && $(LN_S) ../ld$(exeext) .) ; else true ; fi
+ -if [ -f collect-ld$(exeext) ] ; then (cd stagefeedback && $(LN_S) ../collect-ld$(exeext) .) ; else true ; fi
+ -rm -f stagefeedback/libgcc.a stagefeedback/libgcov.a stagefeedback/libgcc_eh.a
+ -rm -f stagefeedback/libgcc_s*$(SHLIB_EXT)
+ -rm -f *.da
+ -for dir in fixinc po testsuite $(SUBDIRS); \
+ do \
+ rm -f $$dir/*.da ; \
+ done
+ -cp libgcc.a stagefeedback
+ -$(RANLIB_FOR_TARGET) stagefeedback/libgcc.a
+ -cp libgcov.a stagefeedback
+ -$(RANLIB_FOR_TARGET) stagefeedback/libgcov.a
+ -if [ -f libgcc_eh.a ] ; then cp libgcc_eh.a stagefeedback; \
+ $(RANLIB_FOR_TARGET) stagefeedback/libgcc_eh.a; \
+ fi
+ -cp libgcc_s*$(SHLIB_EXT) stagefeedback
+ -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
+ cp stagefeedback/$${f} . ; \
+ else true; \
+ fi; done
+stagefeedback: force stagefeedback-start lang.stagefeedback
+
# Copy just the executable files from a particular stage into a subdirectory,
# and delete the object files. Use this if you're just verifying a version
# that is pretty sure to work, and you are short of disk space.
@@ -3677,11 +3798,12 @@ risky-stage4: stage4
#In GNU Make, ignore whether `stage*' exists.
.PHONY: stage1 stage2 stage3 stage4 clean maintainer-clean TAGS bootstrap
.PHONY: risky-stage1 risky-stage2 risky-stage3 risky-stage4
+.PHONY: stagefeedback stageprofile
-force:
-
+# -----------------------------------------------------
# Rules for generating translated message descriptions.
# Disabled by autoconf if the tools are not available.
+# -----------------------------------------------------
XGETTEXT = @XGETTEXT@
GMSGFMT = @GMSGFMT@
@@ -3725,7 +3847,7 @@ update-po: $(CATALOGS:.gmo=.pox)
# with the distribution.
install-po:
$(SHELL) $(srcdir)/mkinstalldirs $(DESTDIR)$(datadir)
- for cat in $(CATALOGS); do \
+ cats="$(CATALOGS)"; for cat in $$cats; do \
lang=`basename $$cat | sed 's/\.gmo$$//'`; \
if [ -f $$cat ]; then :; \
elif [ -f $(srcdir)/$$cat ]; then cat=$(srcdir)/$$cat; \
@@ -3746,8 +3868,8 @@ install-po:
# fairly modern (POSIX-compliant) awk.
# The .pot file is left in the build directory.
$(PACKAGE).pot: po/$(PACKAGE).pot
-po/$(PACKAGE).pot: force
+po/$(PACKAGE).pot: force options.c
-test -d po || mkdir po
- $(MAKE) po-generated
+ $(MAKE) srcextra
AWK=$(AWK) $(SHELL) $(srcdir)/po/exgettext \
$(XGETTEXT) $(PACKAGE) $(srcdir)
diff --git a/contrib/gcc/README.Portability b/contrib/gcc/README.Portability
index 04638b2a00cd..32a33e27bec8 100644
--- a/contrib/gcc/README.Portability
+++ b/contrib/gcc/README.Portability
@@ -1,4 +1,4 @@
-Copyright (C) 2000 Free Software Foundation, Inc.
+Copyright (C) 2000, 2003 Free Software Foundation, Inc.
This file is intended to contain a few notes about writing C code
within GCC so that it compiles without error on the full range of
@@ -10,65 +10,28 @@ This knowledge until know has been sparsely spread around, so I
thought I'd collect it in one useful place. Please add and correct
any problems as you come across them.
-I'm going to start from a base of the ISO C89 standard, since that is
+I'm going to start from a base of the ISO C90 standard, since that is
probably what most people code to naturally. Obviously using
constructs introduced after that is not a good idea.
-The first section of this file deals strictly with portability issues,
-the second with common coding pitfalls.
-
-
- Portability Issues
- ==================
-
-Unary +
--------
-
-K+R C compilers and preprocessors have no notion of unary '+'. Thus
-the following code snippet contains 2 portability problems.
-
-int x = +2; /* int x = 2; */
-#if +1 /* #if 1 */
-#endif
-
-
-Pointers to void
-----------------
-
-K+R C compilers did not have a void pointer, and used char * as the
-pointer to anything. The macro PTR is defined as either void * or
-char * depending on whether you have a standards compliant compiler or
-a K+R one. Thus
-
- free ((void *) h->value.expansion);
-
-should be written
-
- free ((PTR) h->value.expansion);
-
-Further, an initial investigation indicates that pointers to functions
-returning void are okay. Thus the example given by "Calling functions
-through pointers to functions" below appears not to cause a problem.
+For the complete coding style conventions used in GCC, please read
+http://gcc.gnu.org/codingconventions.html
String literals
---------------
-Some SGI compilers choke on the parentheses in:-
+Irix6 "cc -n32" and OSF4 "cc" have problems with constant string
+initializers with parens around it, e.g.
const char string[] = ("A string");
This is unfortunate since this is what the GNU gettext macro N_
produces. You need to find a different way to code it.
-K+R C did not allow concatenation of string literals like
-
- "This is a " "single string literal".
-
-Moreover, some compilers like MSVC++ have fairly low limits on the
-maximum length of a string literal; 509 is the lowest we've come
-across. You may need to break up a long printf statement into many
-smaller ones.
+Some compilers like MSVC++ have fairly low limits on the maximum
+length of a string literal; 509 is the lowest we've come across. You
+may need to break up a long printf statement into many smaller ones.
Empty macro arguments
@@ -88,140 +51,6 @@ foo (bar, )
needs to be coded in some other way.
-signed keyword
---------------
-
-The signed keyword did not exist in K+R compilers; it was introduced
-in ISO C89, so you cannot use it. In both K+R and standard C,
-unqualified char and bitfields may be signed or unsigned. There is no
-way to portably declare signed chars or signed bitfields.
-
-All other arithmetic types are signed unless you use the 'unsigned'
-qualifier. For instance, it is safe to write
-
- short paramc;
-
-instead of
-
- signed short paramc;
-
-If you have an algorithm that depends on signed char or signed
-bitfields, you must find another way to write it before it can be
-integrated into GCC.
-
-
-Function prototypes
--------------------
-
-You need to provide a function prototype for every function before you
-use it, and functions must be defined K+R style. The function
-prototype should use the PARAMS macro, which takes a single argument.
-Therefore the parameter list must be enclosed in parentheses. For
-example,
-
-int myfunc PARAMS ((double, int *));
-
-int
-myfunc (var1, var2)
- double var1;
- int *var2;
-{
- ...
-}
-
-This implies that if the function takes no arguments, it should be
-declared and defined as follows:
-
-int myfunc PARAMS ((void));
-
-int
-myfunc ()
-{
- ...
-}
-
-You also need to use PARAMS when referring to function protypes in
-other circumstances, for example see "Calling functions through
-pointers to functions" below.
-
-Variable-argument functions are best described by example:-
-
-void cpp_ice PARAMS ((cpp_reader *, const char *msgid, ...));
-
-void
-cpp_ice VPARAMS ((cpp_reader *pfile, const char *msgid, ...))
-{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, cpp_reader *, pfile);
- VA_FIXEDARG (ap, const char *, msgid);
-
- ...
- VA_CLOSE (ap);
-}
-
-See ansidecl.h for the definitions of the above macros and more.
-
-One aspect of using K+R style function declarations, is you cannot
-have arguments whose types are char, short, or float, since without
-prototypes (ie, K+R rules), these types are promoted to int, int, and
-double respectively.
-
-Calling functions through pointers to functions
------------------------------------------------
-
-K+R C compilers require parentheses around the dereferenced function
-pointer expression in the call, whereas ISO C relaxes the syntax. For
-example
-
-typedef void (* cl_directive_handler) PARAMS ((cpp_reader *, const char *));
- *p->handler (pfile, p->arg);
-
-needs to become
-
- (*p->handler) (pfile, p->arg);
-
-
-Macros
-------
-
-The rules under K+R C and ISO C for achieving stringification and
-token pasting are quite different. Therefore some macros have been
-defined which will get it right depending upon the compiler.
-
- CONCAT2(a,b) CONCAT3(a,b,c) and CONCAT4(a,b,c,d)
-
-will paste the tokens passed as arguments. You must not leave any
-space around the commas. Also,
-
- STRINGX(x)
-
-will stringify an argument; to get the same result on K+R and ISO
-compilers x should not have spaces around it.
-
-
-Passing structures by value
----------------------------
-
-Avoid passing structures by value, either to or from functions. It
-seems some K+R compilers handle this differently or not at all.
-
-
-Enums
------
-
-In K+R C, you have to cast enum types to use them as integers, and
-some compilers in particular give lots of warnings for using an enum
-as an array index.
-
-
-Bitfields
----------
-
-See also "signed keyword" above. In K+R C only unsigned int bitfields
-were defined (i.e. unsigned char, unsigned short, unsigned long.
-Using plain int/short/long was not allowed).
-
-
free and realloc
----------------
@@ -232,37 +61,16 @@ pointer. Thus if mem might be null, you need to write
free (mem);
-Reserved Keywords
------------------
-
-K+R C has "entry" as a reserved keyword, so you should not use it for
-your variable names.
-
-
-Type promotions
----------------
-
-K+R used unsigned-preserving rules for arithmetic expresssions, while
-ISO uses value-preserving. This means an unsigned char compared to an
-int is done as an unsigned comparison in K+R (since unsigned char
-promotes to unsigned) while it is signed in ISO (since all of the
-values in unsigned char fit in an int, it promotes to int).
-
Trigraphs
---------
-You weren't going to use them anyway, but trigraphs were not defined
-in K+R C, and some otherwise ISO C compliant compilers do not accept
-them.
+You weren't going to use them anyway, but some otherwise ISO C
+compliant compilers do not accept trigraphs.
Suffixes on Integer Constants
-----------------------------
-K+R C did not accept a 'u' suffix on integer constants. If you want
-to declare a constant to be be unsigned, you must use an explicit
-cast.
-
You should never use a 'l' suffix on integer constants ('L' is fine),
since it can easily be confused with the number '1'.
@@ -300,22 +108,19 @@ long and int are not the same size.
Second, if you write a function definition with no return type at
all:
- operate (a, b)
- int a, b;
+ operate (int a, int b)
{
...
}
that function is expected to return int, *not* void. GCC will warn
-about this. K+R C has no problem with 'void' as a return type, so you
-need not worry about that.
+about this.
Implicit function declarations always have return type int. So if you
correct the above definition to
void
- operate (a, b)
- int a, b;
+ operate (int a, int b)
...
but operate() is called above its definition, you will get an error
@@ -368,7 +173,7 @@ WITH UMLAUT.
Other common pitfalls
---------------------
-o Expecting 'plain' char to be either sign or unsigned extending
+o Expecting 'plain' char to be either sign or unsigned extending.
o Shifting an item by a negative amount or by greater than or equal to
the number of bits in a type (expecting shifts by 32 to be sensible
@@ -389,3 +194,4 @@ o Passing incorrect types to fprintf and friends.
o Adding a function declaration for a module declared in another file to
a .c file instead of to a .h file.
+
diff --git a/contrib/gcc/aclocal.m4 b/contrib/gcc/aclocal.m4
index 93eed5c2495e..939fb640e45b 100644
--- a/contrib/gcc/aclocal.m4
+++ b/contrib/gcc/aclocal.m4
@@ -1,5 +1,10 @@
+sinclude(../config/acx.m4)
+sinclude(../config/accross.m4)
+sinclude(../config/gettext.m4)
+sinclude(../config/progtest.m4)
+
dnl See if stdbool.h properly defines bool and true/false.
-AC_DEFUN(gcc_AC_HEADER_STDBOOL,
+AC_DEFUN([gcc_AC_HEADER_STDBOOL],
[AC_CACHE_CHECK([for working stdbool.h],
ac_cv_header_stdbool_h,
[AC_TRY_COMPILE([#include <stdbool.h>],
@@ -12,7 +17,7 @@ fi
])
dnl See whether we can include both string.h and strings.h.
-AC_DEFUN(gcc_AC_HEADER_STRING,
+AC_DEFUN([gcc_AC_HEADER_STRING],
[AC_CACHE_CHECK([whether string.h and strings.h may both be included],
gcc_cv_header_string,
[AC_TRY_COMPILE([#include <string.h>
@@ -28,7 +33,7 @@ dnl to use a different cache variable name in this macro if it is invoked
dnl in a different context somewhere else.
dnl gcc_AC_CHECK_DECL(SYMBOL,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
-AC_DEFUN(gcc_AC_CHECK_DECL,
+AC_DEFUN([gcc_AC_CHECK_DECL],
[AC_MSG_CHECKING([whether $1 is declared])
AC_CACHE_VAL(gcc_cv_have_decl_$1,
[AC_TRY_COMPILE([$4],
@@ -46,7 +51,7 @@ dnl Check multiple functions to see whether each needs a declaration.
dnl Arrange to define HAVE_DECL_<FUNCTION> to 0 or 1 as appropriate.
dnl gcc_AC_CHECK_DECLS(SYMBOLS,
dnl [ACTION-IF-NEEDED [, ACTION-IF-NOT-NEEDED [, INCLUDES]]])
-AC_DEFUN(gcc_AC_CHECK_DECLS,
+AC_DEFUN([gcc_AC_CHECK_DECLS],
[for ac_func in $1
do
changequote(, )dnl
@@ -75,8 +80,41 @@ if test x = y ; then
fi
])
+dnl 'make compare' can be significantly faster, if cmp itself can
+dnl skip bytes instead of using tail. The test being performed is
+dnl "if cmp --ignore-initial=2 t1 t2 && ! cmp --ignore-initial=1 t1 t2"
+dnl but we need to sink errors and handle broken shells. We also test
+dnl for the parameter format "cmp file1 file2 skip1 skip2" which is
+dnl accepted by cmp on some systems.
+AC_DEFUN([gcc_AC_PROG_CMP_IGNORE_INITIAL],
+[AC_CACHE_CHECK([for cmp's capabilities], gcc_cv_prog_cmp_skip,
+[ echo abfoo >t1
+ echo cdfoo >t2
+ gcc_cv_prog_cmp_skip=slowcompare
+ if cmp --ignore-initial=2 t1 t2 > /dev/null 2>&1; then
+ if cmp --ignore-initial=1 t1 t2 > /dev/null 2>&1; then
+ :
+ else
+ gcc_cv_prog_cmp_skip=gnucompare
+ fi
+ fi
+ if test $gcc_cv_prog_cmp_skip = slowcompare ; then
+ if cmp t1 t2 2 2 > /dev/null 2>&1; then
+ if cmp t1 t2 1 1 > /dev/null 2>&1; then
+ :
+ else
+ gcc_cv_prog_cmp_skip=fastcompare
+ fi
+ fi
+ fi
+ rm t1 t2
+])
+make_compare_target=$gcc_cv_prog_cmp_skip
+AC_SUBST(make_compare_target)
+])
+
dnl See if the printf functions in libc support %p in format strings.
-AC_DEFUN(gcc_AC_FUNC_PRINTF_PTR,
+AC_DEFUN([gcc_AC_FUNC_PRINTF_PTR],
[AC_CACHE_CHECK(whether the printf functions support %p,
gcc_cv_func_printf_ptr,
[AC_TRY_RUN([#include <stdio.h>
@@ -97,7 +135,7 @@ fi
])
dnl See if symbolic links work and if not, try to substitute either hard links or simple copy.
-AC_DEFUN(gcc_AC_PROG_LN_S,
+AC_DEFUN([gcc_AC_PROG_LN_S],
[AC_MSG_CHECKING(whether ln -s works)
AC_CACHE_VAL(gcc_cv_prog_LN_S,
[rm -f conftestdata_t
@@ -129,7 +167,7 @@ AC_SUBST(LN_S)dnl
])
dnl See if hard links work and if not, try to substitute either symbolic links or simple copy.
-AC_DEFUN(gcc_AC_PROG_LN,
+AC_DEFUN([gcc_AC_PROG_LN],
[AC_MSG_CHECKING(whether ln works)
AC_CACHE_VAL(gcc_cv_prog_LN,
[rm -f conftestdata_t
@@ -160,38 +198,8 @@ fi
AC_SUBST(LN)dnl
])
-dnl See whether the stage1 host compiler accepts the volatile keyword.
-AC_DEFUN(gcc_AC_C_VOLATILE,
-[AC_CACHE_CHECK([for volatile], gcc_cv_c_volatile,
-[AC_TRY_COMPILE(, [volatile int foo;],
- gcc_cv_c_volatile=yes, gcc_cv_c_volatile=no)])
-if test $gcc_cv_c_volatile = yes ; then
- AC_DEFINE(HAVE_VOLATILE, 1, [Define if your compiler understands volatile.])
-fi
-])
-
-dnl Check whether long double is supported. This differs from the
-dnl built-in autoconf test in that it works for cross compiles.
-AC_DEFUN(gcc_AC_C_LONG_DOUBLE,
-[AC_CACHE_CHECK(for long double, gcc_cv_c_long_double,
-[if test "$GCC" = yes; then
- gcc_cv_c_long_double=yes
-else
-AC_TRY_COMPILE(,
-[/* The Stardent Vistra knows sizeof(long double), but does not support it. */
-long double foo = 0.0;
-/* On Ultrix 4.3 cc, long double is 4 and double is 8. */
-switch (0) case 0: case (sizeof(long double) >= sizeof(double)):;],
-gcc_cv_c_long_double=yes, gcc_cv_c_long_double=no)
-fi])
-if test $gcc_cv_c_long_double = yes; then
- AC_DEFINE(HAVE_LONG_DOUBLE, 1,
- [Define if your compiler supports the \`long double' type.])
-fi
-])
-
dnl Check whether _Bool is built-in.
-AC_DEFUN(gcc_AC_C__BOOL,
+AC_DEFUN([gcc_AC_C__BOOL],
[AC_CACHE_CHECK(for built-in _Bool, gcc_cv_c__bool,
[AC_TRY_COMPILE(,
[_Bool foo;],
@@ -204,7 +212,7 @@ fi
dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead
dnl of the usual 2.
-AC_DEFUN(gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG,
+AC_DEFUN([gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG],
[AC_CACHE_CHECK([if mkdir takes one argument], gcc_cv_mkdir_takes_one_arg,
[AC_TRY_COMPILE([
#include <sys/types.h>
@@ -223,7 +231,7 @@ if test $gcc_cv_mkdir_takes_one_arg = yes ; then
fi
])
-AC_DEFUN(gcc_AC_PROG_INSTALL,
+AC_DEFUN([gcc_AC_PROG_INSTALL],
[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -289,73 +297,45 @@ AC_SUBST(INSTALL_DATA)dnl
dnl Test for GNAT.
dnl We require the gnatbind program, and a compiler driver that
-dnl understands Ada. The user may set the driver name explicitly
-dnl with ADAC; also, the user's CC setting is tried. Failing that,
-dnl we try gcc and cc, then a sampling of names known to be used for
-dnl the Ada driver on various systems.
+dnl understands Ada. We use the user's CC setting, already found.
dnl
dnl Sets the shell variable have_gnat to yes or no as appropriate, and
-dnl substitutes GNATBIND and ADAC.
+dnl substitutes GNATBIND.
AC_DEFUN([gcc_AC_PROG_GNAT],
[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])
+AC_REQUIRE([AC_PROG_CC])
AC_CHECK_TOOL(GNATBIND, gnatbind, no)
-AC_CACHE_CHECK([for compiler driver that understands Ada],
- gcc_cv_prog_adac,
+AC_CACHE_CHECK([whether compiler driver understands Ada],
+ gcc_cv_cc_supports_ada,
[cat >conftest.adb <<EOF
procedure conftest is begin null; end conftest;
EOF
-gcc_cv_prog_adac=no
-# Have to do ac_tool_prefix and user overrides by hand.
-for cand in ${ADAC+"$ADAC"} ${CC+"$CC"} \
- ${ac_tool_prefix}gcc gcc \
- ${ac_tool_prefix}cc cc \
- ${ac_tool_prefix}gnatgcc gnatgcc \
- ${ac_tool_prefix}gnatcc gnatcc \
- ${ac_tool_prefix}adagcc adagcc \
- ${ac_tool_prefix}adacc adacc ; do
- # There is a bug in all released versions of GCC which causes the
- # driver to exit successfully when the appropriate language module
- # has not been installed. This is fixed in 2.95.4, 3.0.2, and 3.1.
- # Therefore we must check for the error message as well as an
- # unsuccessful exit.
- errors=`($cand -c conftest.adb) 2>&1 || echo failure`
- if test x"$errors" = x; then
- gcc_cv_prog_adac=$cand
- break
- fi
-done
+gcc_cv_cc_supports_ada=no
+# There is a bug in old released versions of GCC which causes the
+# driver to exit successfully when the appropriate language module
+# has not been installed. This is fixed in 2.95.4, 3.0.2, and 3.1.
+# Therefore we must check for the error message as well as an
+# unsuccessful exit.
+# Other compilers, like HP Tru64 UNIX cc, exit successfully when
+# given a .adb file, but produce no object file. So we must check
+# if an object file was really produced to guard against this.
+errors=`(${CC} -c conftest.adb) 2>&1 || echo failure`
+if test x"$errors" = x && test -f conftest.$ac_objext; then
+ gcc_cv_cc_supports_ada=yes
+ break
+fi
rm -f conftest.*])
-ADAC=$gcc_cv_prog_adac
-AC_SUBST(ADAC)
-if test x$GNATBIND != xno && test x$ADAC != xno; then
+if test x$GNATBIND != xno && test x$gcc_cv_cc_supports_ada != xno; then
have_gnat=yes
else
have_gnat=no
fi
])
-#serial 1
-dnl This test replaces the one in autoconf.
-dnl Currently this macro should have the same name as the autoconf macro
-dnl because gettext's gettext.m4 (distributed in the automake package)
-dnl still uses it. Otherwise, the use in gettext.m4 makes autoheader
-dnl give these diagnostics:
-dnl configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX
-dnl configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX
-
-undefine([AC_ISC_POSIX])
-AC_DEFUN(AC_ISC_POSIX,
- [
- dnl This test replaces the obsolescent AC_ISC_POSIX kludge.
- AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"])
- ]
-)
-
-
dnl GCC_PATH_PROG(VARIABLE, PROG-TO-CHECK-FOR [, VALUE-IF-NOT-FOUND [, PATH]])
dnl like AC_PATH_PROG but use other cache variables
-AC_DEFUN(GCC_PATH_PROG,
+AC_DEFUN([GCC_PATH_PROG],
[# Extract the first word of "$2", so it can be a program name with args.
set dummy $2; ac_word=[$]2
AC_MSG_CHECKING([for $ac_word])
@@ -413,7 +393,7 @@ else
# read() to the same fd. The only system known to have a problem here
# is VMS, where text files have record structure.
case "$host_os" in
- vms*)
+ vms* | ultrix*)
gcc_cv_func_mmap_file=no ;;
*)
gcc_cv_func_mmap_file=yes;;
@@ -488,7 +468,7 @@ fi
dnl Locate a program and check that its version is acceptable.
dnl AC_PROG_CHECK_VER(var, name, version-switch,
dnl version-extract-regexp, version-glob)
-AC_DEFUN(gcc_AC_CHECK_PROG_VER,
+AC_DEFUN([gcc_AC_CHECK_PROG_VER],
[AC_CHECK_PROG([$1], [$2], [$2])
if test -n "[$]$1"; then
# Found it, now check the version.
@@ -515,7 +495,7 @@ fi
dnl Determine if enumerated bitfields are unsigned. ISO C says they can
dnl be either signed or unsigned.
dnl
-AC_DEFUN(gcc_AC_C_ENUM_BF_UNSIGNED,
+AC_DEFUN([gcc_AC_C_ENUM_BF_UNSIGNED],
[AC_CACHE_CHECK(for unsigned enumerated bitfields, gcc_cv_enum_bf_unsigned,
[AC_TRY_RUN(#include <stdlib.h>
enum t { BLAH = 128 } ;
@@ -532,39 +512,10 @@ if test $gcc_cv_enum_bf_unsigned = yes; then
[Define if enumerated bitfields are treated as unsigned values.])
fi])
-dnl Host type sizes probe.
-dnl By Kaveh R. Ghazi. One typo fixed since.
-dnl
-AC_DEFUN([gcc_AC_COMPILE_CHECK_SIZEOF],
-[changequote(<<, >>)dnl
-dnl The name to #define.
-define(<<AC_TYPE_NAME>>, translit(sizeof_$1, [a-z *], [A-Z_P]))dnl
-dnl The cache variable name.
-define(<<AC_CV_NAME>>, translit(ac_cv_sizeof_$1, [ *], [_p]))dnl
-changequote([, ])dnl
-AC_MSG_CHECKING(size of $1)
-AC_CACHE_VAL(AC_CV_NAME,
-[for ac_size in 4 8 1 2 16 $3 ; do # List sizes in rough order of prevalence.
- AC_TRY_COMPILE([#include "confdefs.h"
-#include <sys/types.h>
-$2
-], [switch (0) case 0: case (sizeof ($1) == $ac_size):;], AC_CV_NAME=$ac_size)
- if test x$AC_CV_NAME != x ; then break; fi
-done
-])
-if test x$AC_CV_NAME = x ; then
- AC_MSG_ERROR([cannot determine a size for $1])
-fi
-AC_MSG_RESULT($AC_CV_NAME)
-AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME, [The number of bytes in type $1])
-undefine([AC_TYPE_NAME])dnl
-undefine([AC_CV_NAME])dnl
-])
-
dnl Probe number of bits in a byte.
dnl Note C89 requires CHAR_BIT >= 8.
dnl
-AC_DEFUN(gcc_AC_C_CHAR_BIT,
+AC_DEFUN([gcc_AC_C_CHAR_BIT],
[AC_CACHE_CHECK(for CHAR_BIT, gcc_cv_decl_char_bit,
[AC_EGREP_CPP(found,
[#ifdef HAVE_LIMITS_H
@@ -620,216 +571,6 @@ AC_CACHE_CHECK(for __int64, ac_cv_c___int64,
fi
])
-dnl Host character set probe.
-dnl The EBCDIC values match the table in config/i370/i370.c;
-dnl there are other versions of EBCDIC but GCC won't work with them.
-dnl
-AC_DEFUN([gcc_AC_C_CHARSET],
-[AC_CACHE_CHECK(execution character set, ac_cv_c_charset,
- [AC_EGREP_CPP(ASCII,
-[#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \
- && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21
-ASCII
-#endif], ac_cv_c_charset=ASCII)
- if test x${ac_cv_c_charset+set} != xset; then
- AC_EGREP_CPP(EBCDIC,
-[#if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \
- && 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A
-EBCDIC
-#endif], ac_cv_c_charset=EBCDIC)
- fi
- if test x${ac_cv_c_charset+set} != xset; then
- ac_cv_c_charset=unknown
- fi])
-if test $ac_cv_c_charset = unknown; then
- AC_MSG_ERROR([*** Cannot determine host character set.])
-elif test $ac_cv_c_charset = EBCDIC; then
- AC_DEFINE(HOST_EBCDIC, 1,
- [Define if the host execution character set is EBCDIC.])
-fi])
-
-dnl Utility macro used by next two tests.
-dnl AC_EXAMINE_OBJECT(C source code,
-dnl commands examining object file,
-dnl [commands to run if compile failed]):
-dnl
-dnl Compile the source code to an object file; then convert it into a
-dnl printable representation. All unprintable characters and
-dnl asterisks (*) are replaced by dots (.). All white space is
-dnl deleted. Newlines (ASCII 0x10) in the input are preserved in the
-dnl output, but runs of newlines are compressed to a single newline.
-dnl Finally, line breaks are forcibly inserted so that no line is
-dnl longer than 80 columns and the file ends with a newline. The
-dnl result of all this processing is in the file conftest.dmp, which
-dnl may be examined by the commands in the second argument.
-dnl
-AC_DEFUN([gcc_AC_EXAMINE_OBJECT],
-[AC_LANG_SAVE
-AC_LANG_C
-dnl Next bit cribbed from AC_TRY_COMPILE.
-cat > conftest.$ac_ext <<EOF
-[#line __oline__ "configure"
-#include "confdefs.h"
-$1
-]EOF
-if AC_TRY_EVAL(ac_compile); then
- od -c conftest.o |
- sed ['s/^[0-7]*[ ]*/ /
- s/\*/./g
- s/ \\n/*/g
- s/ [0-9][0-9][0-9]/./g
- s/ \\[^ ]/./g'] |
- tr -d '
- ' | tr -s '*' '
-' | fold | sed '$a\
-' > conftest.dmp
- $2
-ifelse($3, , , else
- $3
-)dnl
-fi
-rm -rf conftest*
-AC_LANG_RESTORE])
-
-dnl Host endianness probe.
-dnl This tests byte-within-word endianness. GCC actually needs
-dnl to know word-within-larger-object endianness. They are the
-dnl same on all presently supported hosts.
-dnl Differs from AC_C_BIGENDIAN in that it does not require
-dnl running a program on the host, and it defines the macro we
-dnl want to see.
-dnl
-AC_DEFUN([gcc_AC_C_COMPILE_ENDIAN],
-[AC_CACHE_CHECK(byte ordering, ac_cv_c_compile_endian,
-[ac_cv_c_compile_endian=unknown
-gcc_AC_EXAMINE_OBJECT([
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-/* This structure must have no internal padding. */
- struct {
- char prefix[sizeof "\nendian:" - 1];
- short word;
- char postfix[2];
- } tester = {
- "\nendian:",
-#if SIZEOF_SHORT == 4
- ('A' << (CHAR_BIT * 3)) | ('B' << (CHAR_BIT * 2)) |
-#endif
- ('A' << CHAR_BIT) | 'B',
- 'X', '\n'
-};],
- [if grep 'endian:AB' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_compile_endian=big-endian
- elif grep 'endian:BA' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_compile_endian=little-endian
- fi])
-])
-if test $ac_cv_c_compile_endian = unknown; then
- AC_MSG_ERROR([*** unable to determine endianness])
-elif test $ac_cv_c_compile_endian = big-endian; then
- AC_DEFINE(HOST_WORDS_BIG_ENDIAN, 1,
- [Define if the host machine stores words of multi-word integers in
- big-endian order.])
-fi
-])
-
-dnl Floating point format probe.
-dnl The basic concept is the same as the above: grep the object
-dnl file for an interesting string. We have to watch out for
-dnl rounding changing the values in the object, however; this is
-dnl handled by ignoring the least significant byte of the float.
-dnl
-dnl Does not know about VAX G-float or C4x idiosyncratic format.
-dnl It does know about PDP-10 idiosyncratic format, but this is
-dnl not presently supported by GCC. S/390 "binary floating point"
-dnl is in fact IEEE (but maybe we should have that in EBCDIC as well
-dnl as ASCII?)
-dnl
-AC_DEFUN([gcc_AC_C_FLOAT_FORMAT],
-[AC_CACHE_CHECK(floating point format, ac_cv_c_float_format,
-[gcc_AC_EXAMINE_OBJECT(
-[/* This will not work unless sizeof(double) == 8. */
-extern char sizeof_double_must_be_8 [sizeof(double) == 8 ? 1 : -1];
-
-/* This structure must have no internal padding. */
-struct possibility {
- char prefix[8];
- double candidate;
- char postfix[8];
-};
-
-#define C(cand) { "\nformat:", cand, ":tamrof\n" }
-struct possibility table [] =
-{
- C( 3.25724264705901305206e+01), /* @@IEEEFP - IEEE 754 */
- C( 3.53802595280598432000e+18), /* D__float - VAX */
- C( 5.32201830133125317057e-19), /* D.PDP-10 - PDP-10 - the dot is 0x13a */
- C( 1.77977764695171661377e+10), /* IBMHEXFP - s/390 format, ascii */
- C(-5.22995989424860458374e+10) /* IBMHEXFP - s/390 format, EBCDIC */
-};],
- [if grep 'format:.@IEEEF.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='IEEE (big-endian)'
- elif grep 'format:.I@@PFE.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='IEEE (big-endian)'
- elif grep 'format:.FEEEI@.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='IEEE (little-endian)'
- elif grep 'format:.EFP@@I.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='IEEE (little-endian)'
- elif grep 'format:.__floa.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='VAX D-float'
- elif grep 'format:..PDP-1.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='PDP-10'
- elif grep 'format:.BMHEXF.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='IBM 370 hex'
- else
- AC_MSG_ERROR(Unknown floating point format)
- fi],
- [AC_MSG_ERROR(compile failed)])
-])
-# IEEE is the default format. If the float endianness isn't the same
-# as the integer endianness, we have to set FLOAT_WORDS_BIG_ENDIAN
-# (which is a tristate: yes, no, default). This is only an issue with
-# IEEE; the other formats are only supported by a few machines each,
-# all with the same endianness.
-format=
-fbigend=
-case $ac_cv_c_float_format in
- 'IEEE (big-endian)' )
- if test $ac_cv_c_compile_endian = little-endian; then
- fbigend=1
- fi
- ;;
- 'IEEE (little-endian)' )
- if test $ac_cv_c_compile_endian = big-endian; then
- fbigend=0
- fi
- ;;
- 'VAX D-float' )
- format=VAX_FLOAT_FORMAT
- ;;
- 'PDP-10' )
- format=PDP10_FLOAT_FORMAT
- ;;
- 'IBM 370 hex' )
- format=IBM_FLOAT_FORMAT
- ;;
-esac
-if test -n "$format"; then
- AC_DEFINE_UNQUOTED(HOST_FLOAT_FORMAT, $format,
- [Define to the floating point format of the host machine, if not IEEE.])
-fi
-if test -n "$fbigend"; then
- AC_DEFINE_UNQUOTED(HOST_FLOAT_WORDS_BIG_ENDIAN, $fbigend,
- [Define to 1 if the host machine stores floating point numbers in
- memory with the word containing the sign bit at the lowest address,
- or to 0 if it does it the other way around.
-
- This macro should not be defined if the ordering is the same as for
- multi-word integers.])
-fi
-])
-
#serial AM2
dnl From Bruno Haible.
@@ -848,6 +589,8 @@ AC_DEFUN([AM_ICONV],
done
])
+ AC_CHECK_HEADERS([iconv.h])
+
AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [
am_cv_func_iconv="no, consider installing GNU libiconv"
am_cv_lib_iconv=no
@@ -901,556 +644,141 @@ size_t iconv();
AC_SUBST(LIBICONV)
])
-### Gettext macros begin here.
-### Changes for GCC marked by 'dnl GCC LOCAL'.
-### Note iconv.m4 appears above, as it's used for other reasons.
-
-#serial AM1
-
-dnl From Bruno Haible.
-
-AC_DEFUN([AM_LANGINFO_CODESET],
-[
- AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset,
- [AC_TRY_LINK([#include <langinfo.h>],
- [char* cs = nl_langinfo(CODESET);],
- am_cv_langinfo_codeset=yes,
- am_cv_langinfo_codeset=no)
- ])
- if test $am_cv_langinfo_codeset = yes; then
- AC_DEFINE(HAVE_LANGINFO_CODESET, 1,
- [Define if you have <langinfo.h> and nl_langinfo(CODESET).])
- fi
-])
-
-#serial 1
-# This test replaces the one in autoconf.
-# Currently this macro should have the same name as the autoconf macro
-# because gettext's gettext.m4 (distributed in the automake package)
-# still uses it. Otherwise, the use in gettext.m4 makes autoheader
-# give these diagnostics:
-# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX
-# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX
-
-undefine([AC_ISC_POSIX])
-
-AC_DEFUN([AC_ISC_POSIX],
- [
- dnl This test replaces the obsolescent AC_ISC_POSIX kludge.
- dnl GCC LOCAL: Use AC_SEARCH_LIBS.
- AC_SEARCH_LIBS(strerror, cposix)
- ]
-)
-
-#serial 2
-
-# Test for the GNU C Library, version 2.1 or newer.
-# From Bruno Haible.
-
-AC_DEFUN([jm_GLIBC21],
- [
- AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer,
- ac_cv_gnu_library_2_1,
- [AC_EGREP_CPP([Lucky GNU user],
- [
-#include <features.h>
-#ifdef __GNU_LIBRARY__
- #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)
- Lucky GNU user
- #endif
-#endif
- ],
- ac_cv_gnu_library_2_1=yes,
- ac_cv_gnu_library_2_1=no)
- ]
- )
- AC_SUBST(GLIBC21)
- GLIBC21="$ac_cv_gnu_library_2_1"
- ]
-)
-
-# Check whether LC_MESSAGES is available in <locale.h>.
-# Ulrich Drepper <drepper@cygnus.com>, 1995.
-#
-# This file can be copied and used freely without restrictions. It can
-# be used in projects which are not available under the GNU General Public
-# License or the GNU Library General Public License but which still want
-# to provide support for the GNU gettext functionality.
-# Please note that the actual code of the GNU gettext library is covered
-# by the GNU Library General Public License, and the rest of the GNU
-# gettext package package is covered by the GNU General Public License.
-# They are *not* in the public domain.
-
-# serial 2
-
-AC_DEFUN([AM_LC_MESSAGES],
- [if test $ac_cv_header_locale_h = yes; then
- AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
- [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
- am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
- if test $am_cv_val_LC_MESSAGES = yes; then
- AC_DEFINE(HAVE_LC_MESSAGES, 1,
- [Define if your <locale.h> file defines LC_MESSAGES.])
- fi
- fi])
-
-# Search path for a program which passes the given test.
-# Ulrich Drepper <drepper@cygnus.com>, 1996.
-#
-# This file can be copied and used freely without restrictions. It can
-# be used in projects which are not available under the GNU General Public
-# License or the GNU Library General Public License but which still want
-# to provide support for the GNU gettext functionality.
-# Please note that the actual code of the GNU gettext library is covered
-# by the GNU Library General Public License, and the rest of the GNU
-# gettext package package is covered by the GNU General Public License.
-# They are *not* in the public domain.
-
-# serial 2
-
-dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
-dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
-AC_DEFUN([AM_PATH_PROG_WITH_TEST],
-[# Extract the first word of "$2", so it can be a program name with args.
-set dummy $2; ac_word=[$]2
-AC_MSG_CHECKING([for $ac_word])
-AC_CACHE_VAL(ac_cv_path_$1,
-[case "[$]$1" in
- /*)
- ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
- ;;
- *)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in ifelse([$5], , $PATH, [$5]); do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if [$3]; then
- ac_cv_path_$1="$ac_dir/$ac_word"
- break
- fi
- fi
- done
- IFS="$ac_save_ifs"
-dnl If no 4th arg is given, leave the cache variable unset,
-dnl so AC_PATH_PROGS will keep looking.
-ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
-])dnl
- ;;
-esac])dnl
-$1="$ac_cv_path_$1"
-if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
- AC_MSG_RESULT([$]$1)
-else
- AC_MSG_RESULT(no)
-fi
-AC_SUBST($1)dnl
+AC_DEFUN([gcc_AC_INITFINI_ARRAY],
+[AC_ARG_ENABLE(initfini-array,
+ [ --enable-initfini-array use .init_array/.fini_array sections],
+ [], [
+AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support,
+ gcc_cv_initfini_array, [dnl
+ AC_TRY_RUN([
+static int x = -1;
+int main (void) { return x; }
+int foo (void) { x = 0; }
+int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;],
+ [gcc_cv_initfini_array=yes], [gcc_cv_initfini_array=no],
+ [gcc_cv_initfini_array=no])])
+ enable_initfini_array=$gcc_cv_initfini_array
])
+if test $enable_initfini_array = yes; then
+ AC_DEFINE(HAVE_INITFINI_ARRAY, 1,
+ [Define .init_array/.fini_array sections are available and working.])
+fi])
-# Macro to add for using GNU gettext.
-# Ulrich Drepper <drepper@cygnus.com>, 1995.
-#
-# This file can be copied and used freely without restrictions. It can
-# be used in projects which are not available under the GNU General Public
-# License or the GNU Library General Public License but which still want
-# to provide support for the GNU gettext functionality.
-# Please note that the actual code of the GNU gettext library is covered
-# by the GNU Library General Public License, and the rest of the GNU
-# gettext package package is covered by the GNU General Public License.
-# They are *not* in the public domain.
+dnl # _gcc_COMPUTE_GAS_VERSION
+dnl # Used by gcc_GAS_VERSION_GTE_IFELSE
+dnl #
+dnl # WARNING:
+dnl # gcc_cv_as_gas_srcdir must be defined before this.
+dnl # This gross requirement will go away eventually.
+AC_DEFUN([_gcc_COMPUTE_GAS_VERSION],
+[gcc_cv_as_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
+for f in $gcc_cv_as_bfd_srcdir/configure \
+ $gcc_cv_as_gas_srcdir/configure \
+ $gcc_cv_as_gas_srcdir/configure.in \
+ $gcc_cv_as_gas_srcdir/Makefile.in ; do
+ gcc_cv_gas_version=`grep '^VERSION=[[0-9]]*\.[[0-9]]*' $f`
+ if test x$gcc_cv_gas_version != x; then
+ break
+ fi
+done
+gcc_cv_gas_major_version=`expr "$gcc_cv_gas_version" : "VERSION=\([[0-9]]*\)"`
+gcc_cv_gas_minor_version=`expr "$gcc_cv_gas_version" : "VERSION=[[0-9]]*\.\([[0-9]]*\)"`
+gcc_cv_gas_patch_version=`expr "$gcc_cv_gas_version" : "VERSION=[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)"`
+case $gcc_cv_gas_patch_version in
+ "") gcc_cv_gas_patch_version="0" ;;
+esac
+gcc_cv_gas_vers=`expr \( \( $gcc_cv_gas_major_version \* 1000 \) \
+ + $gcc_cv_gas_minor_version \) \* 1000 \
+ + $gcc_cv_gas_patch_version`
+]) []dnl # _gcc_COMPUTE_GAS_VERSION
+
+dnl # gcc_GAS_VERSION_GTE_IFELSE([elf,] major, minor, patchlevel,
+dnl # [command_if_true = :], [command_if_false = :])
+dnl # Check to see if the version of GAS is greater than or
+dnl # equal to the specified version.
+dnl #
+dnl # The first ifelse() shortens the shell code if the patchlevel
+dnl # is unimportant (the usual case). The others handle missing
+dnl # commands. Note that the tests are structured so that the most
+dnl # common version number cases are tested first.
+AC_DEFUN([_gcc_GAS_VERSION_GTE_IFELSE],
+[ifelse([$1], elf,
+ [if test $in_tree_gas_is_elf = yes \
+ &&],
+ [if]) test $gcc_cv_gas_vers -ge `expr \( \( $2 \* 1000 \) + $3 \) \* 1000 + $4`
+ then dnl
+ifelse([$5],,:,[$5])[]dnl
+ifelse([$6],,,[
+ else $6])
+fi])
-# serial 10
+AC_DEFUN([gcc_GAS_VERSION_GTE_IFELSE],
+[AC_REQUIRE([_gcc_COMPUTE_GAS_VERSION])dnl
+ifelse([$1], elf, [_gcc_GAS_VERSION_GTE_IFELSE($@)],
+ [_gcc_GAS_VERSION_GTE_IFELSE(,$@)])])
-dnl Usage: AM_WITH_NLS([TOOLSYMBOL], [NEEDSYMBOL], [LIBDIR]).
-dnl If TOOLSYMBOL is specified and is 'use-libtool', then a libtool library
-dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static,
-dnl depending on --{enable,disable}-{shared,static} and on the presence of
-dnl AM-DISABLE-SHARED). Otherwise, a static library
-dnl $(top_builddir)/intl/libintl.a will be created.
-dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
-dnl implementations (in libc or libintl) without the ngettext() function
-dnl will be ignored.
-dnl LIBDIR is used to find the intl libraries. If empty,
-dnl the value `$(top_builddir)/intl/' is used.
-dnl
-dnl The result of the configuration is one of three cases:
-dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
-dnl and used.
-dnl Catalog format: GNU --> install in $(datadir)
-dnl Catalog extension: .mo after installation, .gmo in source tree
-dnl 2) GNU gettext has been found in the system's C library.
-dnl Catalog format: GNU --> install in $(datadir)
-dnl Catalog extension: .mo after installation, .gmo in source tree
-dnl 3) No internationalization, always use English msgid.
-dnl Catalog format: none
-dnl Catalog extension: none
-dnl The use of .gmo is historical (it was needed to avoid overwriting the
-dnl GNU format catalogs when building on a platform with an X/Open gettext),
-dnl but we keep it in order not to force irrelevant filename changes on the
-dnl maintainers.
+dnl gcc_GAS_CHECK_FEATURE(description, cv, [[elf,]major,minor,patchlevel],
+dnl [extra switches to as], [assembler input],
+dnl [extra testing logic], [command if feature available])
dnl
-AC_DEFUN([AM_WITH_NLS],
- [AC_MSG_CHECKING([whether NLS is requested])
- dnl Default is enabled NLS
- AC_ARG_ENABLE(nls,
- [ --disable-nls do not use Native Language Support],
- USE_NLS=$enableval, USE_NLS=yes)
- AC_MSG_RESULT($USE_NLS)
- AC_SUBST(USE_NLS)
-
- BUILD_INCLUDED_LIBINTL=no
- USE_INCLUDED_LIBINTL=no
-dnl GCC LOCAL: Separate concept of link command line from dependencies.
- INTLLIBS=
- INTLDEPS=
-
- dnl If we use NLS figure out what method
- if test "$USE_NLS" = "yes"; then
- AC_DEFINE(ENABLE_NLS, 1,
- [Define to 1 if translation of program messages to the user's native language
- is requested.])
- AC_MSG_CHECKING([whether included gettext is requested])
- AC_ARG_WITH(included-gettext,
- [ --with-included-gettext use the GNU gettext library included here],
- nls_cv_force_use_gnu_gettext=$withval,
- nls_cv_force_use_gnu_gettext=no)
- AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
-
- nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
- if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
- dnl User does not insist on using GNU NLS library. Figure out what
- dnl to use. If GNU gettext is available we use this. Else we have
- dnl to fall back to GNU NLS library.
- CATOBJEXT=NONE
-
- dnl Add a version number to the cache macros.
- define(gt_cv_func_gnugettext_libc, [gt_cv_func_gnugettext]ifelse([$2], need-ngettext, 2, 1)[_libc])
- define(gt_cv_func_gnugettext_libintl, [gt_cv_func_gnugettext]ifelse([$2], need-ngettext, 2, 1)[_libintl])
-
-dnl GCC LOCAL: Expose presence of libintl.h to C code.
- AC_CHECK_HEADER(libintl.h,
- [AC_DEFINE([HAVE_LIBINTL_H], 1,
- [Define if you have the <libintl.h> header file.])
- AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc,
- [AC_TRY_LINK([#include <libintl.h>
-extern int _nl_msg_cat_cntr;],
- [bindtextdomain ("", "");
-return (int) gettext ("")]ifelse([$2], need-ngettext, [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr],
- gt_cv_func_gnugettext_libc=yes,
- gt_cv_func_gnugettext_libc=no)])
-
- if test "$gt_cv_func_gnugettext_libc" != "yes"; then
- AC_CACHE_CHECK([for GNU gettext in libintl],
- gt_cv_func_gnugettext_libintl,
- [gt_save_LIBS="$LIBS"
- LIBS="$LIBS -lintl $LIBICONV"
- AC_TRY_LINK([#include <libintl.h>
-extern int _nl_msg_cat_cntr;],
- [bindtextdomain ("", "");
-return (int) gettext ("")]ifelse([$2], need-ngettext, [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr],
- gt_cv_func_gnugettext_libintl=yes,
- gt_cv_func_gnugettext_libintl=no)
- LIBS="$gt_save_LIBS"])
- fi
-
- dnl If an already present or preinstalled GNU gettext() is found,
- dnl use it. But if this macro is used in GNU gettext, and GNU
- dnl gettext is already preinstalled in libintl, we update this
- dnl libintl. (Cf. the install rule in intl/Makefile.in.)
- if test "$gt_cv_func_gnugettext_libc" = "yes" \
- || { test "$gt_cv_func_gnugettext_libintl" = "yes" \
- && test "$PACKAGE" != gettext; }; then
- AC_DEFINE(HAVE_GETTEXT, 1,
- [Define if the GNU gettext() function is already present or preinstalled.])
-
- if test "$gt_cv_func_gnugettext_libintl" = "yes"; then
- dnl If iconv() is in a separate libiconv library, then anyone
- dnl linking with libintl{.a,.so} also needs to link with
- dnl libiconv.
- INTLLIBS="-lintl $LIBICONV"
- fi
-
- gt_save_LIBS="$LIBS"
- LIBS="$LIBS $INTLLIBS"
- AC_CHECK_FUNCS(dcgettext)
- LIBS="$gt_save_LIBS"
-
- dnl Search for GNU msgfmt in the PATH.
- AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
- [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1], :)
- AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
-
- dnl Search for GNU xgettext in the PATH.
- AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
- [$ac_dir/$ac_word --omit-header /dev/null >/dev/null 2>&1], :)
-
- CATOBJEXT=.gmo
- fi
- ])
-
- if test "$CATOBJEXT" = "NONE"; then
- dnl GNU gettext is not found in the C library.
- dnl Fall back on GNU gettext library.
- nls_cv_use_gnu_gettext=yes
- fi
- fi
-
- if test "$nls_cv_use_gnu_gettext" = "yes"; then
- dnl Mark actions used to generate GNU NLS library.
- INTLOBJS="\$(GETTOBJS)"
- AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
- [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1], :)
- AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
- AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
- [$ac_dir/$ac_word --omit-header /dev/null >/dev/null 2>&1], :)
- AC_SUBST(MSGFMT)
- BUILD_INCLUDED_LIBINTL=yes
- USE_INCLUDED_LIBINTL=yes
- CATOBJEXT=.gmo
- INTLLIBS="ifelse([$3],[],\$(top_builddir)/intl,[$3])/libintl.ifelse([$1], use-libtool, [l], [])a $LIBICONV"
- INTLDEPS="ifelse([$3],[],\$(top_builddir)/intl,[$3])/libintl.ifelse([$1], use-libtool, [l], [])a"
- LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
- fi
-
- dnl This could go away some day; the PATH_PROG_WITH_TEST already does it.
- dnl Test whether we really found GNU msgfmt.
- if test "$GMSGFMT" != ":"; then
- dnl If it is no GNU msgfmt we define it as : so that the
- dnl Makefiles still can work.
- if $GMSGFMT --statistics /dev/null >/dev/null 2>&1; then
- : ;
- else
- AC_MSG_RESULT(
- [found msgfmt program is not GNU msgfmt; ignore it])
- GMSGFMT=":"
- fi
- fi
-
- dnl This could go away some day; the PATH_PROG_WITH_TEST already does it.
- dnl Test whether we really found GNU xgettext.
- if test "$XGETTEXT" != ":"; then
- dnl If it is no GNU xgettext we define it as : so that the
- dnl Makefiles still can work.
- if $XGETTEXT --omit-header /dev/null >/dev/null 2>&1; then
- : ;
- else
- AC_MSG_RESULT(
- [found xgettext program is not GNU xgettext; ignore it])
- XGETTEXT=":"
- fi
- fi
-
- dnl We need to process the po/ directory.
- POSUB=po
- fi
- AC_OUTPUT_COMMANDS(
- [for ac_file in $CONFIG_FILES; do
- # Support "outfile[:infile[:infile...]]"
- case "$ac_file" in
- *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- esac
- # PO directories have a Makefile.in generated from Makefile.in.in.
- case "$ac_file" in */Makefile.in)
- # Adjust a relative srcdir.
- ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
- ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
- ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
- # In autoconf-2.13 it is called $ac_given_srcdir.
- # In autoconf-2.50 it is called $srcdir.
- test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
- case "$ac_given_srcdir" in
- .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
- /*) top_srcdir="$ac_given_srcdir" ;;
- *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
- if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
- rm -f "$ac_dir/POTFILES"
- test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
- sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," -e "\$s/\(.*\) \\\\/\1/" < "$ac_given_srcdir/$ac_dir/POTFILES.in" > "$ac_dir/POTFILES"
- test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
- sed -e "/POTFILES =/r $ac_dir/POTFILES" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
- fi
- ;;
- esac
- done])
-
-
- dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
- dnl to 'yes' because some of the testsuite requires it.
- if test "$PACKAGE" = gettext; then
- BUILD_INCLUDED_LIBINTL=yes
- fi
-
- dnl intl/plural.c is generated from intl/plural.y. It requires bison,
- dnl because plural.y uses bison specific features. It requires at least
- dnl bison-1.26 because earlier versions generate a plural.c that doesn't
- dnl compile.
- dnl bison is only needed for the maintainer (who touches plural.y). But in
- dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put
- dnl the rule in general Makefile. Now, some people carelessly touch the
- dnl files or have a broken "make" program, hence the plural.c rule will
- dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not
- dnl present or too old.
- AC_CHECK_PROGS([INTLBISON], [bison])
- if test -z "$INTLBISON"; then
- ac_verc_fail=yes
+dnl Checks for an assembler feature. If we are building an in-tree
+dnl gas, the feature is available if the associated assembler version
+dnl is greater than or equal to major.minor.patchlevel. If not, then
+dnl ASSEMBLER INPUT is fed to the assembler and the feature is available
+dnl if assembly succeeds. If EXTRA TESTING LOGIC is not the empty string,
+dnl then it is run instead of simply setting CV to "yes" - it is responsible
+dnl for doing so, if appropriate.
+AC_DEFUN([gcc_GAS_CHECK_FEATURE],
+[AC_CACHE_CHECK([assembler for $1], [$2],
+ [[$2]=no
+ ifelse([$3],,,[dnl
+ if test $in_tree_gas = yes; then
+ gcc_GAS_VERSION_GTE_IFELSE($3, [[$2]=yes])
+ el])if test x$gcc_cv_as != x; then
+ echo ifelse(m4_substr([$5],0,1),[$], "[$5]", '[$5]') > conftest.s
+ if AC_TRY_COMMAND([$gcc_cv_as $4 -o conftest.o conftest.s >&AC_FD_CC])
+ then
+ ifelse([$6],, [$2]=yes, [$6])
else
- dnl Found it, now check the version.
- AC_MSG_CHECKING([version of bison])
-changequote(<<,>>)dnl
- ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'`
- case $ac_prog_version in
- '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
- 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*)
-changequote([,])dnl
- ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
- *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
- esac
- AC_MSG_RESULT([$ac_prog_version])
+ echo "configure: failed program was" >&AC_FD_CC
+ cat conftest.s >&AC_FD_CC
fi
- if test $ac_verc_fail = yes; then
- INTLBISON=:
- fi
-
- dnl GCC LOCAL: GMOFILES/POFILES removed as unnecessary.
-
- dnl Make all variables we use known to autoconf.
- AC_SUBST(BUILD_INCLUDED_LIBINTL)
- AC_SUBST(USE_INCLUDED_LIBINTL)
- AC_SUBST(CATALOGS)
- AC_SUBST(CATOBJEXT)
- AC_SUBST(INTLLIBS)
- AC_SUBST(INTLDEPS)
- AC_SUBST(INTLOBJS)
- AC_SUBST(POSUB)
-dnl GCC LOCAL: Make USE_INCLUDED_LIBINTL visible to C code.
- if test $USE_INCLUDED_LIBINTL = yes; then
- AC_DEFINE([USE_INCLUDED_LIBINTL], 1,
- [Define to use the libintl included with this package instead of any
- version in the system libraries.])
- fi
-
- dnl For backward compatibility. Some configure.ins may be using this.
- nls_cv_header_intl=
- nls_cv_header_libgt=
-
- dnl For backward compatibility. Some Makefiles may be using this.
- DATADIRNAME=share
- AC_SUBST(DATADIRNAME)
-
- dnl For backward compatibility. Some Makefiles may be using this.
- INSTOBJEXT=.mo
- AC_SUBST(INSTOBJEXT)
-
- dnl For backward compatibility. Some Makefiles may be using this.
- GENCAT=gencat
- AC_SUBST(GENCAT)
- ])
-
-dnl Usage: Just like AM_WITH_NLS, which see.
-AC_DEFUN([AM_GNU_GETTEXT],
- [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
- AC_REQUIRE([AC_PROG_CC])dnl
- AC_REQUIRE([AC_CANONICAL_HOST])dnl
- AC_REQUIRE([AC_PROG_RANLIB])dnl
- AC_REQUIRE([AC_ISC_POSIX])dnl
- AC_REQUIRE([AC_HEADER_STDC])dnl
- AC_REQUIRE([AC_C_CONST])dnl
- AC_REQUIRE([AC_C_INLINE])dnl
- AC_REQUIRE([AC_TYPE_OFF_T])dnl
- AC_REQUIRE([AC_TYPE_SIZE_T])dnl
- AC_REQUIRE([AC_FUNC_ALLOCA])dnl
-dnl GCC LOCAL: Do not refer to AC_FUNC_MMAP, we have special needs.
-dnl AC_REQUIRE([AC_FUNC_MMAP])dnl
- AC_REQUIRE([jm_GLIBC21])dnl
-
- AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \
-stdlib.h string.h unistd.h sys/param.h])
- AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getcwd getegid geteuid \
-getgid getuid mempcpy munmap putenv setenv setlocale stpcpy strchr strcasecmp \
-strdup strtoul tsearch __argz_count __argz_stringify __argz_next])
-
- AM_ICONV
- AM_LANGINFO_CODESET
- AM_LC_MESSAGES
- AM_WITH_NLS([$1],[$2],[$3])
-
- dnl GCC LOCAL: The LINGUAS/ALL_LINGUAS/CATALOGS mess that was here
- dnl has been torn out and replaced with this more sensible scheme.
- if test "x$CATOBJEXT" != x; then
- AC_MSG_CHECKING(for catalogs to be installed)
- # Look for .po and .gmo files in the source directory.
- CATALOGS=
- XLINGUAS=
- for cat in $srcdir/po/*$CATOBJEXT $srcdir/po/*.po; do
- # If there aren't any .gmo files the shell will give us the
- # literal string "../path/to/srcdir/po/*.gmo" which has to be
- # weeded out.
- case "$cat" in *\**)
- continue;;
- esac
- # The quadruple backslash is collapsed to a double backslash
- # by the backticks, then collapsed again by the double quotes,
- # leaving us with one backslash in the sed expression (right
- # before the dot that mustn't act as a wildcard). The dot to
- # be escaped in the second expression is hiding inside CATOBJEXT.
- cat=`echo $cat | sed -e "s!$srcdir/!!" -e "s!\\\\.po!$CATOBJEXT!"`
- lang=`echo $cat | sed -e 's!po/!!' -e "s!\\\\$CATOBJEXT!!"`
- # The user is allowed to set LINGUAS to a list of languages to
- # install catalogs for. If it's empty that means "all of them."
- if test "x$LINGUAS" = x; then
- CATALOGS="$CATALOGS $cat"
- XLINGUAS="$XLINGUAS $lang"
- else
- case "$LINGUAS" in *$lang*)
- CATALOGS="$CATALOGS $cat"
- XLINGUAS="$XLINGUAS $lang"
- ;;
- esac
- fi
- done
- LINGUAS="$XLINGUAS"
- AC_MSG_RESULT($LINGUAS)
- fi
-
- dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
- dnl find the mkinstalldirs script in another subdir but $(top_srcdir).
- dnl Try to locate is.
- MKINSTALLDIRS=
- if test -n "$ac_aux_dir"; then
- MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
- fi
- if test -z "$MKINSTALLDIRS"; then
- MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
- fi
- AC_SUBST(MKINSTALLDIRS)
+ rm -f conftest.o conftest.s
+ fi])
+ifelse([$7],,,[dnl
+if test $[$2] = yes; then
+ $7
+fi])])
+
+# lcmessage.m4 serial 3 (gettext-0.11.3)
+dnl Copyright (C) 1995-2002 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License. As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper@cygnus.com>, 1995.
- dnl Enable libtool support if the surrounding package wishes it.
- INTL_LIBTOOL_SUFFIX_PREFIX=ifelse([$1], use-libtool, [l], [])
- AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX)
- ])
+# Check whether LC_MESSAGES is available in <locale.h>.
-AC_DEFUN(gcc_AC_INITFINI_ARRAY,
-[AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support,
- gcc_cv_initfinit_array, [dnl
- cat > conftest.c <<EOF
-static int x = -1;
-int main (void) { return x; }
-int foo (void) { x = 0; }
-int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;
-EOF
- if AC_TRY_COMMAND([${CC-cc} -o conftest conftest.c 1>&AS_MESSAGE_LOG_FD])
- then
- if ./conftest; then
- gcc_cv_initfinit_array=yes
- else
- gcc_cv_initfinit_array=no
- fi
- else
- gcc_cv_initfinit_array=no
+AC_DEFUN([AM_LC_MESSAGES],
+[
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES, 1,
+ [Define if your <locale.h> file defines LC_MESSAGES.])
fi
- rm -f conftest*])
- AC_SUBST(gcc_cv_initfinit_array)
- if test $gcc_cv_initfinit_array = yes; then
- AC_DEFINE(HAVE_INITFINI_ARRAY, 1,
- [Define .init_array/.fini_array sections are available and working.])
- fi])
+])
diff --git a/contrib/gcc/alias.c b/contrib/gcc/alias.c
index dd8426964026..5cce5e4d16f7 100644
--- a/contrib/gcc/alias.c
+++ b/contrib/gcc/alias.c
@@ -1,5 +1,5 @@
/* Alias analysis for GNU C
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by John Carr (jfc@mit.edu).
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
@@ -37,14 +39,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "splay-tree.h"
#include "ggc.h"
#include "langhooks.h"
+#include "timevar.h"
#include "target.h"
+#include "cgraph.h"
+#include "varray.h"
/* The alias sets assigned to MEMs assist the back-end in determining
which MEMs can alias which other MEMs. In general, two MEMs in
different alias sets cannot alias each other, with one important
exception. Consider something like:
- struct S {int i; double d; };
+ struct S { int i; double d; };
a store to an `S' can alias something of either type `int' or type
`double'. (However, a store to an `int' cannot alias a `double'
@@ -62,61 +67,60 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
To see whether two alias sets can point to the same memory, we must
see if either alias set is a subset of the other. We need not trace
- past immediate descendents, however, since we propagate all
+ past immediate descendants, however, since we propagate all
grandchildren up one level.
Alias set zero is implicitly a superset of all other alias sets.
However, this is no actual entry for alias set zero. It is an
error to attempt to explicitly construct a subset of zero. */
-typedef struct alias_set_entry
+struct alias_set_entry GTY(())
{
/* The alias set number, as stored in MEM_ALIAS_SET. */
HOST_WIDE_INT alias_set;
/* The children of the alias set. These are not just the immediate
- children, but, in fact, all descendents. So, if we have:
+ children, but, in fact, all descendants. So, if we have:
struct T { struct S s; float f; }
continuing our example above, the children here will be all of
`int', `double', `float', and `struct S'. */
- splay_tree children;
+ splay_tree GTY((param1_is (int), param2_is (int))) children;
/* Nonzero if would have a child of zero: this effectively makes this
alias set the same as alias set zero. */
int has_zero_child;
-} *alias_set_entry;
-
-static int rtx_equal_for_memref_p PARAMS ((rtx, rtx));
-static rtx find_symbolic_term PARAMS ((rtx));
-rtx get_addr PARAMS ((rtx));
-static int memrefs_conflict_p PARAMS ((int, rtx, int, rtx,
- HOST_WIDE_INT));
-static void record_set PARAMS ((rtx, rtx, void *));
-static rtx find_base_term PARAMS ((rtx));
-static int base_alias_check PARAMS ((rtx, rtx, enum machine_mode,
- enum machine_mode));
-static rtx find_base_value PARAMS ((rtx));
-static int mems_in_disjoint_alias_sets_p PARAMS ((rtx, rtx));
-static int insert_subset_children PARAMS ((splay_tree_node, void*));
-static tree find_base_decl PARAMS ((tree));
-static alias_set_entry get_alias_set_entry PARAMS ((HOST_WIDE_INT));
-static rtx fixed_scalar_and_varying_struct_p PARAMS ((rtx, rtx, rtx, rtx,
- int (*) (rtx, int)));
-static int aliases_everything_p PARAMS ((rtx));
-static bool nonoverlapping_component_refs_p PARAMS ((tree, tree));
-static tree decl_for_component_ref PARAMS ((tree));
-static rtx adjust_offset_for_component_ref PARAMS ((tree, rtx));
-static int nonoverlapping_memrefs_p PARAMS ((rtx, rtx));
-static int write_dependence_p PARAMS ((rtx, rtx, int));
-
-static int nonlocal_mentioned_p_1 PARAMS ((rtx *, void *));
-static int nonlocal_mentioned_p PARAMS ((rtx));
-static int nonlocal_referenced_p_1 PARAMS ((rtx *, void *));
-static int nonlocal_referenced_p PARAMS ((rtx));
-static int nonlocal_set_p_1 PARAMS ((rtx *, void *));
-static int nonlocal_set_p PARAMS ((rtx));
+};
+typedef struct alias_set_entry *alias_set_entry;
+
+static int rtx_equal_for_memref_p (rtx, rtx);
+static rtx find_symbolic_term (rtx);
+static int memrefs_conflict_p (int, rtx, int, rtx, HOST_WIDE_INT);
+static void record_set (rtx, rtx, void *);
+static int base_alias_check (rtx, rtx, enum machine_mode,
+ enum machine_mode);
+static rtx find_base_value (rtx);
+static int mems_in_disjoint_alias_sets_p (rtx, rtx);
+static int insert_subset_children (splay_tree_node, void*);
+static tree find_base_decl (tree);
+static alias_set_entry get_alias_set_entry (HOST_WIDE_INT);
+static rtx fixed_scalar_and_varying_struct_p (rtx, rtx, rtx, rtx,
+ int (*) (rtx, int));
+static int aliases_everything_p (rtx);
+static bool nonoverlapping_component_refs_p (tree, tree);
+static tree decl_for_component_ref (tree);
+static rtx adjust_offset_for_component_ref (tree, rtx);
+static int nonoverlapping_memrefs_p (rtx, rtx);
+static int write_dependence_p (rtx, rtx, int, int);
+
+static int nonlocal_mentioned_p_1 (rtx *, void *);
+static int nonlocal_mentioned_p (rtx);
+static int nonlocal_referenced_p_1 (rtx *, void *);
+static int nonlocal_referenced_p (rtx);
+static int nonlocal_set_p_1 (rtx *, void *);
+static int nonlocal_set_p (rtx);
+static void memory_modified_1 (rtx, rtx, void *);
/* Set up all info needed to perform alias analysis on memory references. */
@@ -153,17 +157,21 @@ static int nonlocal_set_p PARAMS ((rtx));
current function performs nonlocal memory memory references for the
purposes of marking the function as a constant function. */
-static GTY((length ("reg_base_value_size"))) rtx *reg_base_value;
+static GTY(()) varray_type reg_base_value;
static rtx *new_reg_base_value;
-static unsigned int reg_base_value_size; /* size of reg_base_value array */
+
+/* We preserve the copy of old array around to avoid amount of garbage
+ produced. About 8% of garbage produced were attributed to this
+ array. */
+static GTY((deletable (""))) varray_type old_reg_base_value;
/* Static hunks of RTL used by the aliasing code; these are initialized
once per function to avoid unnecessary RTL allocations. */
static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];
#define REG_BASE_VALUE(X) \
- (REGNO (X) < reg_base_value_size \
- ? reg_base_value[REGNO (X)] : 0)
+ (reg_base_value && REGNO (X) < VARRAY_SIZE (reg_base_value) \
+ ? VARRAY_RTX (reg_base_value, REGNO (X)) : 0)
/* Vector of known invariant relationships between registers. Set in
loop unrolling. Indexed by register number, if nonzero the value
@@ -173,16 +181,16 @@ static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];
Because this array contains only pseudo registers it has no effect
after reload. */
-static rtx *alias_invariant;
+static GTY((length("alias_invariant_size"))) rtx *alias_invariant;
+unsigned GTY(()) int alias_invariant_size;
/* Vector indexed by N giving the initial (unchanging) value known for
- pseudo-register N. This array is initialized in
- init_alias_analysis, and does not change until end_alias_analysis
- is called. */
-rtx *reg_known_value;
+ pseudo-register N. This array is initialized in init_alias_analysis,
+ and does not change until end_alias_analysis is called. */
+static GTY((length("reg_known_value_size"))) rtx *reg_known_value;
/* Indicates number of valid entries in reg_known_value. */
-static unsigned int reg_known_value_size;
+static GTY(()) unsigned int reg_known_value_size;
/* Vector recording for each reg_known_value whether it is due to a
REG_EQUIV note. Future passes (viz., reload) may replace the
@@ -196,35 +204,29 @@ static unsigned int reg_known_value_size;
REG_EQUIV notes. One could argue that the REG_EQUIV notes are
wrong, but solving the problem in the scheduler will likely give
better code, so we do it here. */
-char *reg_known_equiv_p;
+static bool *reg_known_equiv_p;
/* True when scanning insns from the start of the rtl to the
NOTE_INSN_FUNCTION_BEG note. */
static bool copying_arguments;
/* The splay-tree used to store the various alias set entries. */
-static splay_tree alias_sets;
+static GTY ((param_is (struct alias_set_entry))) varray_type alias_sets;
/* Returns a pointer to the alias set entry for ALIAS_SET, if there is
such an entry, or NULL otherwise. */
-static alias_set_entry
-get_alias_set_entry (alias_set)
- HOST_WIDE_INT alias_set;
+static inline alias_set_entry
+get_alias_set_entry (HOST_WIDE_INT alias_set)
{
- splay_tree_node sn
- = splay_tree_lookup (alias_sets, (splay_tree_key) alias_set);
-
- return sn != 0 ? ((alias_set_entry) sn->value) : 0;
+ return (alias_set_entry)VARRAY_GENERIC_PTR (alias_sets, alias_set);
}
/* Returns nonzero if the alias sets for MEM1 and MEM2 are such that
the two MEMs cannot alias each other. */
-static int
-mems_in_disjoint_alias_sets_p (mem1, mem2)
- rtx mem1;
- rtx mem2;
+static inline int
+mems_in_disjoint_alias_sets_p (rtx mem1, rtx mem2)
{
#ifdef ENABLE_CHECKING
/* Perform a basic sanity check. Namely, that there are no alias sets
@@ -246,9 +248,7 @@ mems_in_disjoint_alias_sets_p (mem1, mem2)
record_alias_subset via splay_tree_foreach. */
static int
-insert_subset_children (node, data)
- splay_tree_node node;
- void *data;
+insert_subset_children (splay_tree_node node, void *data)
{
splay_tree_insert ((splay_tree) data, node->key, node->value);
@@ -258,8 +258,7 @@ insert_subset_children (node, data)
/* Return 1 if the two specified alias sets may conflict. */
int
-alias_sets_conflict_p (set1, set2)
- HOST_WIDE_INT set1, set2;
+alias_sets_conflict_p (HOST_WIDE_INT set1, HOST_WIDE_INT set2)
{
alias_set_entry ase;
@@ -296,8 +295,7 @@ alias_sets_conflict_p (set1, set2)
contain readonly fields, return true as well. */
int
-readonly_fields_p (type)
- tree type;
+readonly_fields_p (tree type)
{
tree field;
@@ -320,8 +318,7 @@ readonly_fields_p (type)
NULL_TREE, it means we know nothing about the storage. */
int
-objects_must_conflict_p (t1, t2)
- tree t1, t2;
+objects_must_conflict_p (tree t1, tree t2)
{
HOST_WIDE_INT set1, set2;
@@ -362,8 +359,7 @@ objects_must_conflict_p (t1, t2)
NULL_TREE is returned. */
static tree
-find_base_decl (t)
- tree t;
+find_base_decl (tree t)
{
tree d0, d1, d2;
@@ -419,8 +415,7 @@ find_base_decl (t)
get_inner_reference in T are such that we can address the object in T. */
int
-can_address_p (t)
- tree t;
+can_address_p (tree t)
{
/* If we're at the end, it is vacuously addressable. */
if (! handled_component_p (t))
@@ -452,8 +447,7 @@ can_address_p (t)
expression. Call language-specific routine for help, if needed. */
HOST_WIDE_INT
-get_alias_set (t)
- tree t;
+get_alias_set (tree t)
{
HOST_WIDE_INT set;
@@ -506,6 +500,8 @@ get_alias_set (t)
/* If we haven't computed the actual alias set, do it now. */
if (DECL_POINTER_ALIAS_SET (decl) == -2)
{
+ tree pointed_to_type = TREE_TYPE (TREE_TYPE (decl));
+
/* No two restricted pointers can point at the same thing.
However, a restricted pointer can point at the same thing
as an unrestricted pointer, if that unrestricted pointer
@@ -514,11 +510,22 @@ get_alias_set (t)
alias set for the type pointed to by the type of the
decl. */
HOST_WIDE_INT pointed_to_alias_set
- = get_alias_set (TREE_TYPE (TREE_TYPE (decl)));
+ = get_alias_set (pointed_to_type);
if (pointed_to_alias_set == 0)
/* It's not legal to make a subset of alias set zero. */
- ;
+ DECL_POINTER_ALIAS_SET (decl) = 0;
+ else if (AGGREGATE_TYPE_P (pointed_to_type))
+ /* For an aggregate, we must treat the restricted
+ pointer the same as an ordinary pointer. If we
+ were to make the type pointed to by the
+ restricted pointer a subset of the pointed-to
+ type, then we would believe that other subsets
+ of the pointed-to type (such as fields of that
+ type) do not conflict with the type pointed to
+ by the restricted pointer. */
+ DECL_POINTER_ALIAS_SET (decl)
+ = pointed_to_alias_set;
else
{
DECL_POINTER_ALIAS_SET (decl) = new_alias_set ();
@@ -602,30 +609,38 @@ get_alias_set (t)
/* Return a brand-new alias set. */
+static GTY(()) HOST_WIDE_INT last_alias_set;
+
HOST_WIDE_INT
-new_alias_set ()
+new_alias_set (void)
{
- static HOST_WIDE_INT last_alias_set;
-
if (flag_strict_aliasing)
- return ++last_alias_set;
+ {
+ if (!alias_sets)
+ VARRAY_GENERIC_PTR_INIT (alias_sets, 10, "alias sets");
+ else
+ VARRAY_GROW (alias_sets, last_alias_set + 2);
+ return ++last_alias_set;
+ }
else
return 0;
}
-/* Indicate that things in SUBSET can alias things in SUPERSET, but
- not vice versa. For example, in C, a store to an `int' can alias a
- structure containing an `int', but not vice versa. Here, the
- structure would be the SUPERSET and `int' the SUBSET. This
- function should be called only once per SUPERSET/SUBSET pair.
+/* Indicate that things in SUBSET can alias things in SUPERSET, but that
+ not everything that aliases SUPERSET also aliases SUBSET. For example,
+ in C, a store to an `int' can alias a load of a structure containing an
+ `int', and vice versa. But it can't alias a load of a 'double' member
+ of the same structure. Here, the structure would be the SUPERSET and
+ `int' the SUBSET. This relationship is also described in the comment at
+ the beginning of this file.
+
+ This function should be called only once per SUPERSET/SUBSET pair.
It is illegal for SUPERSET to be zero; everything is implicitly a
subset of alias set zero. */
void
-record_alias_subset (superset, subset)
- HOST_WIDE_INT superset;
- HOST_WIDE_INT subset;
+record_alias_subset (HOST_WIDE_INT superset, HOST_WIDE_INT subset)
{
alias_set_entry superset_entry;
alias_set_entry subset_entry;
@@ -643,14 +658,12 @@ record_alias_subset (superset, subset)
{
/* Create an entry for the SUPERSET, so that we have a place to
attach the SUBSET. */
- superset_entry
- = (alias_set_entry) xmalloc (sizeof (struct alias_set_entry));
+ superset_entry = ggc_alloc (sizeof (struct alias_set_entry));
superset_entry->alias_set = superset;
superset_entry->children
- = splay_tree_new (splay_tree_compare_ints, 0, 0);
+ = splay_tree_new_ggc (splay_tree_compare_ints);
superset_entry->has_zero_child = 0;
- splay_tree_insert (alias_sets, (splay_tree_key) superset,
- (splay_tree_value) superset_entry);
+ VARRAY_GENERIC_PTR (alias_sets, superset) = superset_entry;
}
if (subset == 0)
@@ -682,8 +695,7 @@ record_alias_subset (superset, subset)
function if the individual component aren't addressable. */
void
-record_component_aliases (type)
- tree type;
+record_component_aliases (tree type)
{
HOST_WIDE_INT superset = get_alias_set (type);
tree field;
@@ -701,7 +713,7 @@ record_component_aliases (type)
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
- /* Recursively record aliases for the base classes, if there are any */
+ /* Recursively record aliases for the base classes, if there are any. */
if (TYPE_BINFO (type) != NULL && TYPE_BINFO_BASETYPES (type) != NULL)
{
int i;
@@ -729,36 +741,35 @@ record_component_aliases (type)
/* Allocate an alias set for use in storing and reading from the varargs
spill area. */
+static GTY(()) HOST_WIDE_INT varargs_set = -1;
+
HOST_WIDE_INT
-get_varargs_alias_set ()
+get_varargs_alias_set (void)
{
- static HOST_WIDE_INT set = -1;
+ if (varargs_set == -1)
+ varargs_set = new_alias_set ();
- if (set == -1)
- set = new_alias_set ();
-
- return set;
+ return varargs_set;
}
/* Likewise, but used for the fixed portions of the frame, e.g., register
save areas. */
+static GTY(()) HOST_WIDE_INT frame_set = -1;
+
HOST_WIDE_INT
-get_frame_alias_set ()
+get_frame_alias_set (void)
{
- static HOST_WIDE_INT set = -1;
-
- if (set == -1)
- set = new_alias_set ();
+ if (frame_set == -1)
+ frame_set = new_alias_set ();
- return set;
+ return frame_set;
}
/* Inside SRC, the source of a SET, find a base address. */
static rtx
-find_base_value (src)
- rtx src;
+find_base_value (rtx src)
{
unsigned int regno;
@@ -784,7 +795,7 @@ find_base_value (src)
The test above is not sufficient because the scheduler may move
a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN. */
if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno])
- && regno < reg_base_value_size)
+ && regno < VARRAY_SIZE (reg_base_value))
{
/* If we're inside init_alias_analysis, use new_reg_base_value
to reduce the number of relaxation iterations. */
@@ -792,8 +803,8 @@ find_base_value (src)
&& REG_N_SETS (regno) == 1)
return new_reg_base_value[regno];
- if (reg_base_value[regno])
- return reg_base_value[regno];
+ if (VARRAY_RTX (reg_base_value, regno))
+ return VARRAY_RTX (reg_base_value, regno);
}
return 0;
@@ -902,10 +913,8 @@ find_base_value (src)
{
rtx temp = find_base_value (XEXP (src, 0));
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (temp != 0 && CONSTANT_P (temp) && GET_MODE (temp) != Pmode)
+ if (temp != 0 && CONSTANT_P (temp))
temp = convert_memory_address (Pmode, temp);
-#endif
return temp;
}
@@ -928,21 +937,36 @@ static char *reg_seen;
static int unique_id;
static void
-record_set (dest, set, data)
- rtx dest, set;
- void *data ATTRIBUTE_UNUSED;
+record_set (rtx dest, rtx set, void *data ATTRIBUTE_UNUSED)
{
unsigned regno;
rtx src;
+ int n;
if (GET_CODE (dest) != REG)
return;
regno = REGNO (dest);
- if (regno >= reg_base_value_size)
+ if (regno >= VARRAY_SIZE (reg_base_value))
abort ();
+ /* If this spans multiple hard registers, then we must indicate that every
+ register has an unusable value. */
+ if (regno < FIRST_PSEUDO_REGISTER)
+ n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
+ else
+ n = 1;
+ if (n != 1)
+ {
+ while (--n >= 0)
+ {
+ reg_seen[regno + n] = 1;
+ new_reg_base_value[regno + n] = 0;
+ }
+ return;
+ }
+
if (set)
{
/* A CLOBBER wipes out any old value but does not prevent a previously
@@ -1021,26 +1045,22 @@ record_set (dest, set, data)
are different. */
void
-record_base_value (regno, val, invariant)
- unsigned int regno;
- rtx val;
- int invariant;
+record_base_value (unsigned int regno, rtx val, int invariant)
{
- if (regno >= reg_base_value_size)
- return;
-
- if (invariant && alias_invariant)
+ if (invariant && alias_invariant && regno < alias_invariant_size)
alias_invariant[regno] = val;
+ if (regno >= VARRAY_SIZE (reg_base_value))
+ VARRAY_GROW (reg_base_value, max_reg_num ());
+
if (GET_CODE (val) == REG)
{
- if (REGNO (val) < reg_base_value_size)
- reg_base_value[regno] = reg_base_value[REGNO (val)];
-
+ VARRAY_RTX (reg_base_value, regno)
+ = REG_BASE_VALUE (val);
return;
}
-
- reg_base_value[regno] = find_base_value (val);
+ VARRAY_RTX (reg_base_value, regno)
+ = find_base_value (val);
}
/* Clear alias info for a register. This is used if an RTL transformation
@@ -1049,30 +1069,93 @@ record_base_value (regno, val, invariant)
changes the offset. */
void
-clear_reg_alias_info (reg)
- rtx reg;
+clear_reg_alias_info (rtx reg)
{
unsigned int regno = REGNO (reg);
- if (regno < reg_known_value_size && regno >= FIRST_PSEUDO_REGISTER)
- reg_known_value[regno] = reg;
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ {
+ regno -= FIRST_PSEUDO_REGISTER;
+ if (regno < reg_known_value_size)
+ {
+ reg_known_value[regno] = reg;
+ reg_known_equiv_p[regno] = false;
+ }
+ }
+}
+
+/* If a value is known for REGNO, return it. */
+
+rtx
+get_reg_known_value (unsigned int regno)
+{
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ {
+ regno -= FIRST_PSEUDO_REGISTER;
+ if (regno < reg_known_value_size)
+ return reg_known_value[regno];
+ }
+ return NULL;
+}
+
+/* Set it. */
+
+static void
+set_reg_known_value (unsigned int regno, rtx val)
+{
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ {
+ regno -= FIRST_PSEUDO_REGISTER;
+ if (regno < reg_known_value_size)
+ reg_known_value[regno] = val;
+ }
+}
+
+/* Similarly for reg_known_equiv_p. */
+
+bool
+get_reg_known_equiv_p (unsigned int regno)
+{
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ {
+ regno -= FIRST_PSEUDO_REGISTER;
+ if (regno < reg_known_value_size)
+ return reg_known_equiv_p[regno];
+ }
+ return false;
+}
+
+static void
+set_reg_known_equiv_p (unsigned int regno, bool val)
+{
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ {
+ regno -= FIRST_PSEUDO_REGISTER;
+ if (regno < reg_known_value_size)
+ reg_known_equiv_p[regno] = val;
+ }
}
+
/* Returns a canonical version of X, from the point of view alias
analysis. (For example, if X is a MEM whose address is a register,
and the register has a known value (say a SYMBOL_REF), then a MEM
whose address is the SYMBOL_REF is returned.) */
rtx
-canon_rtx (x)
- rtx x;
+canon_rtx (rtx x)
{
/* Recursively look for equivalences. */
- if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER
- && REGNO (x) < reg_known_value_size)
- return reg_known_value[REGNO (x)] == x
- ? x : canon_rtx (reg_known_value[REGNO (x)]);
- else if (GET_CODE (x) == PLUS)
+ if (GET_CODE (x) == REG && REGNO (x) >= FIRST_PSEUDO_REGISTER)
+ {
+ rtx t = get_reg_known_value (REGNO (x));
+ if (t == x)
+ return x;
+ if (t)
+ return canon_rtx (t);
+ }
+
+ if (GET_CODE (x) == PLUS)
{
rtx x0 = canon_rtx (XEXP (x, 0));
rtx x1 = canon_rtx (XEXP (x, 1));
@@ -1098,13 +1181,13 @@ canon_rtx (x)
}
/* Return 1 if X and Y are identical-looking rtx's.
+ Expect that X and Y has been already canonicalized.
We use the data in reg_known_value above to see if two registers with
different numbers are, in fact, equivalent. */
static int
-rtx_equal_for_memref_p (x, y)
- rtx x, y;
+rtx_equal_for_memref_p (rtx x, rtx y)
{
int i;
int j;
@@ -1116,9 +1199,6 @@ rtx_equal_for_memref_p (x, y)
if (x == 0 || y == 0)
return 0;
- x = canon_rtx (x);
- y = canon_rtx (y);
-
if (x == y)
return 1;
@@ -1136,9 +1216,6 @@ rtx_equal_for_memref_p (x, y)
/* Some RTL can be compared without a recursive examination. */
switch (code)
{
- case VALUE:
- return CSELIB_VAL_PTR (x) == CSELIB_VAL_PTR (y);
-
case REG:
return REGNO (x) == REGNO (y);
@@ -1148,6 +1225,7 @@ rtx_equal_for_memref_p (x, y)
case SYMBOL_REF:
return XSTR (x, 0) == XSTR (y, 0);
+ case VALUE:
case CONST_INT:
case CONST_DOUBLE:
/* There's no need to compare the contents of CONST_DOUBLEs or
@@ -1157,24 +1235,42 @@ rtx_equal_for_memref_p (x, y)
case ADDRESSOF:
return (XINT (x, 1) == XINT (y, 1)
- && rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0)));
+ && rtx_equal_for_memref_p (XEXP (x, 0),
+ XEXP (y, 0)));
default:
break;
}
- /* For commutative operations, the RTX match if the operand match in any
- order. Also handle the simple binary and unary cases without a loop. */
- if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
+ /* canon_rtx knows how to handle plus. No need to canonicalize. */
+ if (code == PLUS)
return ((rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0))
&& rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1)))
|| (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 1))
&& rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 0))));
+ /* For commutative operations, the RTX match if the operand match in any
+ order. Also handle the simple binary and unary cases without a loop. */
+ if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
+ {
+ rtx xop0 = canon_rtx (XEXP (x, 0));
+ rtx yop0 = canon_rtx (XEXP (y, 0));
+ rtx yop1 = canon_rtx (XEXP (y, 1));
+
+ return ((rtx_equal_for_memref_p (xop0, yop0)
+ && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), yop1))
+ || (rtx_equal_for_memref_p (xop0, yop1)
+ && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)), yop0)));
+ }
else if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == '2')
- return (rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0))
- && rtx_equal_for_memref_p (XEXP (x, 1), XEXP (y, 1)));
+ {
+ return (rtx_equal_for_memref_p (canon_rtx (XEXP (x, 0)),
+ canon_rtx (XEXP (y, 0)))
+ && rtx_equal_for_memref_p (canon_rtx (XEXP (x, 1)),
+ canon_rtx (XEXP (y, 1))));
+ }
else if (GET_RTX_CLASS (code) == '1')
- return rtx_equal_for_memref_p (XEXP (x, 0), XEXP (y, 0));
+ return rtx_equal_for_memref_p (canon_rtx (XEXP (x, 0)),
+ canon_rtx (XEXP (y, 0)));
/* Compare the elements. If any pair of corresponding elements
fail to match, return 0 for the whole things.
@@ -1198,13 +1294,14 @@ rtx_equal_for_memref_p (x, y)
/* And the corresponding elements must match. */
for (j = 0; j < XVECLEN (x, i); j++)
- if (rtx_equal_for_memref_p (XVECEXP (x, i, j),
- XVECEXP (y, i, j)) == 0)
+ if (rtx_equal_for_memref_p (canon_rtx (XVECEXP (x, i, j)),
+ canon_rtx (XVECEXP (y, i, j))) == 0)
return 0;
break;
case 'e':
- if (rtx_equal_for_memref_p (XEXP (x, i), XEXP (y, i)) == 0)
+ if (rtx_equal_for_memref_p (canon_rtx (XEXP (x, i)),
+ canon_rtx (XEXP (y, i))) == 0)
return 0;
break;
@@ -1232,8 +1329,7 @@ rtx_equal_for_memref_p (x, y)
X and return it, or return 0 if none found. */
static rtx
-find_symbolic_term (x)
- rtx x;
+find_symbolic_term (rtx x)
{
int i;
enum rtx_code code;
@@ -1262,9 +1358,8 @@ find_symbolic_term (x)
return 0;
}
-static rtx
-find_base_term (x)
- rtx x;
+rtx
+find_base_term (rtx x)
{
cselib_val *val;
struct elt_loc_list *l;
@@ -1297,16 +1392,16 @@ find_base_term (x)
{
rtx temp = find_base_term (XEXP (x, 0));
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (temp != 0 && CONSTANT_P (temp) && GET_MODE (temp) != Pmode)
+ if (temp != 0 && CONSTANT_P (temp))
temp = convert_memory_address (Pmode, temp);
-#endif
return temp;
}
case VALUE:
val = CSELIB_VAL_PTR (x);
+ if (!val)
+ return 0;
for (l = val->locs; l; l = l->next)
if ((x = find_base_term (l->loc)) != 0)
return x;
@@ -1316,7 +1411,7 @@ find_base_term (x)
x = XEXP (x, 0);
if (GET_CODE (x) != PLUS && GET_CODE (x) != MINUS)
return 0;
- /* fall through */
+ /* Fall through. */
case LO_SUM:
case PLUS:
case MINUS:
@@ -1396,9 +1491,8 @@ find_base_term (x)
objects, 1 if they might be pointers to the same object. */
static int
-base_alias_check (x, y, x_mode, y_mode)
- rtx x, y;
- enum machine_mode x_mode, y_mode;
+base_alias_check (rtx x, rtx y, enum machine_mode x_mode,
+ enum machine_mode y_mode)
{
rtx x_base = find_base_term (x);
rtx y_base = find_base_term (y);
@@ -1477,8 +1571,7 @@ base_alias_check (x, y, x_mode, y_mode)
a more useful rtx. */
rtx
-get_addr (x)
- rtx x;
+get_addr (rtx x)
{
cselib_val *v;
struct elt_loc_list *l;
@@ -1486,14 +1579,17 @@ get_addr (x)
if (GET_CODE (x) != VALUE)
return x;
v = CSELIB_VAL_PTR (x);
- for (l = v->locs; l; l = l->next)
- if (CONSTANT_P (l->loc))
- return l->loc;
- for (l = v->locs; l; l = l->next)
- if (GET_CODE (l->loc) != REG && GET_CODE (l->loc) != MEM)
- return l->loc;
- if (v->locs)
- return v->locs->loc;
+ if (v)
+ {
+ for (l = v->locs; l; l = l->next)
+ if (CONSTANT_P (l->loc))
+ return l->loc;
+ for (l = v->locs; l; l = l->next)
+ if (GET_CODE (l->loc) != REG && GET_CODE (l->loc) != MEM)
+ return l->loc;
+ if (v->locs)
+ return v->locs->loc;
+ }
return x;
}
@@ -1502,10 +1598,7 @@ get_addr (x)
is not modified by the memory reference then ADDR is returned. */
rtx
-addr_side_effect_eval (addr, size, n_refs)
- rtx addr;
- int size;
- int n_refs;
+addr_side_effect_eval (rtx addr, int size, int n_refs)
{
int offset = 0;
@@ -1529,9 +1622,11 @@ addr_side_effect_eval (addr, size, n_refs)
}
if (offset)
- addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0), GEN_INT (offset));
+ addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0),
+ GEN_INT (offset));
else
addr = XEXP (addr, 0);
+ addr = canon_rtx (addr);
return addr;
}
@@ -1541,6 +1636,7 @@ addr_side_effect_eval (addr, size, n_refs)
C is nonzero, we are testing aliases between X and Y + C.
XSIZE is the size in bytes of the X reference,
similarly YSIZE is the size in bytes for Y.
+ Expect that canon_rtx has been already called for X and Y.
If XSIZE or YSIZE is zero, we do not know the amount of memory being
referenced (the reference was BLKmode), so make the most pessimistic
@@ -1554,10 +1650,7 @@ addr_side_effect_eval (addr, size, n_refs)
local variables had their addresses taken, but that's too hard now. */
static int
-memrefs_conflict_p (xsize, x, ysize, y, c)
- rtx x, y;
- int xsize, ysize;
- HOST_WIDE_INT c;
+memrefs_conflict_p (int xsize, rtx x, int ysize, rtx y, HOST_WIDE_INT c)
{
if (GET_CODE (x) == VALUE)
x = get_addr (x);
@@ -1568,13 +1661,13 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
else if (GET_CODE (x) == LO_SUM)
x = XEXP (x, 1);
else
- x = canon_rtx (addr_side_effect_eval (x, xsize, 0));
+ x = addr_side_effect_eval (x, xsize, 0);
if (GET_CODE (y) == HIGH)
y = XEXP (y, 0);
else if (GET_CODE (y) == LO_SUM)
y = XEXP (y, 1);
else
- y = canon_rtx (addr_side_effect_eval (y, ysize, 0));
+ y = addr_side_effect_eval (y, ysize, 0);
if (rtx_equal_for_memref_p (x, y))
{
@@ -1673,8 +1766,8 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
unsigned int r_x = REGNO (x), r_y = REGNO (y);
rtx i_x, i_y; /* invariant relationships of X and Y */
- i_x = r_x >= reg_base_value_size ? 0 : alias_invariant[r_x];
- i_y = r_y >= reg_base_value_size ? 0 : alias_invariant[r_y];
+ i_x = r_x >= alias_invariant_size ? 0 : alias_invariant[r_x];
+ i_y = r_y >= alias_invariant_size ? 0 : alias_invariant[r_y];
if (i_x == 0 && i_y == 0)
break;
@@ -1697,7 +1790,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
{
if (GET_CODE (y) == AND || ysize < -INTVAL (XEXP (x, 1)))
xsize = -1;
- return memrefs_conflict_p (xsize, XEXP (x, 0), ysize, y, c);
+ return memrefs_conflict_p (xsize, canon_rtx (XEXP (x, 0)), ysize, y, c);
}
if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT)
{
@@ -1707,7 +1800,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
a following reference, so we do nothing with that for now. */
if (GET_CODE (x) == AND || xsize < -INTVAL (XEXP (y, 1)))
ysize = -1;
- return memrefs_conflict_p (xsize, x, ysize, XEXP (y, 0), c);
+ return memrefs_conflict_p (xsize, x, ysize, canon_rtx (XEXP (y, 0)), c);
}
if (GET_CODE (x) == ADDRESSOF)
@@ -1777,9 +1870,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c)
only be a dependence here if both reads are volatile. */
int
-read_dependence (mem, x)
- rtx mem;
- rtx x;
+read_dependence (rtx mem, rtx x)
{
return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem);
}
@@ -1793,10 +1884,9 @@ read_dependence (mem, x)
MEM1_ADDR and MEM2_ADDR are the addresses of MEM1 and MEM2. */
static rtx
-fixed_scalar_and_varying_struct_p (mem1, mem2, mem1_addr, mem2_addr, varies_p)
- rtx mem1, mem2;
- rtx mem1_addr, mem2_addr;
- int (*varies_p) PARAMS ((rtx, int));
+fixed_scalar_and_varying_struct_p (rtx mem1, rtx mem2, rtx mem1_addr,
+ rtx mem2_addr,
+ int (*varies_p) (rtx, int))
{
if (! flag_strict_aliasing)
return NULL_RTX;
@@ -1820,8 +1910,7 @@ fixed_scalar_and_varying_struct_p (mem1, mem2, mem1_addr, mem2_addr, varies_p)
indicates that it might well alias *anything*. */
static int
-aliases_everything_p (mem)
- rtx mem;
+aliases_everything_p (rtx mem)
{
if (GET_CODE (XEXP (mem, 0)) == AND)
/* If the address is an AND, its very hard to know at what it is
@@ -1835,8 +1924,7 @@ aliases_everything_p (mem)
overlap for any pair of objects. */
static bool
-nonoverlapping_component_refs_p (x, y)
- tree x, y;
+nonoverlapping_component_refs_p (tree x, tree y)
{
tree fieldx, fieldy, typex, typey, orig_y;
@@ -1892,8 +1980,7 @@ nonoverlapping_component_refs_p (x, y)
/* Look at the bottom of the COMPONENT_REF list for a DECL, and return it. */
static tree
-decl_for_component_ref (x)
- tree x;
+decl_for_component_ref (tree x)
{
do
{
@@ -1908,9 +1995,7 @@ decl_for_component_ref (x)
offset of the field reference. */
static rtx
-adjust_offset_for_component_ref (x, offset)
- tree x;
- rtx offset;
+adjust_offset_for_component_ref (tree x, rtx offset)
{
HOST_WIDE_INT ioffset;
@@ -1935,12 +2020,11 @@ adjust_offset_for_component_ref (x, offset)
return GEN_INT (ioffset);
}
-/* Return nonzero if we can deterimine the exprs corresponding to memrefs
+/* Return nonzero if we can determine the exprs corresponding to memrefs
X and Y and they do not overlap. */
static int
-nonoverlapping_memrefs_p (x, y)
- rtx x, y;
+nonoverlapping_memrefs_p (rtx x, rtx y)
{
tree exprx = MEM_EXPR (x), expry = MEM_EXPR (y);
rtx rtlx, rtly;
@@ -2066,11 +2150,8 @@ nonoverlapping_memrefs_p (x, y)
/* True dependence: X is read after store in MEM takes place. */
int
-true_dependence (mem, mem_mode, x, varies)
- rtx mem;
- enum machine_mode mem_mode;
- rtx x;
- int (*varies) PARAMS ((rtx, int));
+true_dependence (rtx mem, enum machine_mode mem_mode, rtx x,
+ int (*varies) (rtx, int))
{
rtx x_addr, mem_addr;
rtx base;
@@ -2150,10 +2231,8 @@ true_dependence (mem, mem_mode, x, varies)
this value prior to canonicalizing. */
int
-canon_true_dependence (mem, mem_mode, mem_addr, x, varies)
- rtx mem, mem_addr, x;
- enum machine_mode mem_mode;
- int (*varies) PARAMS ((rtx, int));
+canon_true_dependence (rtx mem, enum machine_mode mem_mode, rtx mem_addr,
+ rtx x, int (*varies) (rtx, int))
{
rtx x_addr;
@@ -2211,13 +2290,11 @@ canon_true_dependence (mem, mem_mode, mem_addr, x, varies)
}
/* Returns nonzero if a write to X might alias a previous read from
- (or, if WRITEP is nonzero, a write to) MEM. */
+ (or, if WRITEP is nonzero, a write to) MEM. If CONSTP is nonzero,
+ honor the RTX_UNCHANGING_P flags on X and MEM. */
static int
-write_dependence_p (mem, x, writep)
- rtx mem;
- rtx x;
- int writep;
+write_dependence_p (rtx mem, rtx x, int writep, int constp)
{
rtx x_addr, mem_addr;
rtx fixed_scalar;
@@ -2236,15 +2313,18 @@ write_dependence_p (mem, x, writep)
if (DIFFERENT_ALIAS_SETS_P (x, mem))
return 0;
- /* Unchanging memory can't conflict with non-unchanging memory. */
- if (RTX_UNCHANGING_P (x) != RTX_UNCHANGING_P (mem))
- return 0;
+ if (constp)
+ {
+ /* Unchanging memory can't conflict with non-unchanging memory. */
+ if (RTX_UNCHANGING_P (x) != RTX_UNCHANGING_P (mem))
+ return 0;
- /* If MEM is an unchanging read, then it can't possibly conflict with
- the store to X, because there is at most one store to MEM, and it must
- have occurred somewhere before MEM. */
- if (! writep && RTX_UNCHANGING_P (mem))
- return 0;
+ /* If MEM is an unchanging read, then it can't possibly conflict with
+ the store to X, because there is at most one store to MEM, and it
+ must have occurred somewhere before MEM. */
+ if (! writep && RTX_UNCHANGING_P (mem))
+ return 0;
+ }
if (nonoverlapping_memrefs_p (x, mem))
return 0;
@@ -2283,30 +2363,33 @@ write_dependence_p (mem, x, writep)
/* Anti dependence: X is written after read in MEM takes place. */
int
-anti_dependence (mem, x)
- rtx mem;
- rtx x;
+anti_dependence (rtx mem, rtx x)
{
- return write_dependence_p (mem, x, /*writep=*/0);
+ return write_dependence_p (mem, x, /*writep=*/0, /*constp*/1);
}
/* Output dependence: X is written after store in MEM takes place. */
int
-output_dependence (mem, x)
- rtx mem;
- rtx x;
+output_dependence (rtx mem, rtx x)
{
- return write_dependence_p (mem, x, /*writep=*/1);
+ return write_dependence_p (mem, x, /*writep=*/1, /*constp*/1);
+}
+
+/* Unchanging anti dependence: Like anti_dependence but ignores
+ the UNCHANGING_RTX_P property on const variable references. */
+
+int
+unchanging_anti_dependence (rtx mem, rtx x)
+{
+ return write_dependence_p (mem, x, /*writep=*/0, /*constp*/0);
}
/* A subroutine of nonlocal_mentioned_p, returns 1 if *LOC mentions
something which is not local to the function and is not constant. */
static int
-nonlocal_mentioned_p_1 (loc, data)
- rtx *loc;
- void *data ATTRIBUTE_UNUSED;
+nonlocal_mentioned_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
rtx x = *loc;
rtx base;
@@ -2391,7 +2474,7 @@ nonlocal_mentioned_p_1 (loc, data)
if (MEM_VOLATILE_P (x))
return 1;
- /* FALLTHROUGH */
+ /* Fall through. */
default:
break;
@@ -2404,10 +2487,8 @@ nonlocal_mentioned_p_1 (loc, data)
local to the function and is not constant. */
static int
-nonlocal_mentioned_p (x)
- rtx x;
+nonlocal_mentioned_p (rtx x)
{
-
if (INSN_P (x))
{
if (GET_CODE (x) == CALL_INSN)
@@ -2429,9 +2510,7 @@ nonlocal_mentioned_p (x)
something which is not local to the function and is not constant. */
static int
-nonlocal_referenced_p_1 (loc, data)
- rtx *loc;
- void *data ATTRIBUTE_UNUSED;
+nonlocal_referenced_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
rtx x = *loc;
@@ -2489,7 +2568,7 @@ nonlocal_referenced_p_1 (loc, data)
if (MEM_VOLATILE_P (x))
return 1;
- /* FALLTHROUGH */
+ /* Fall through. */
default:
break;
@@ -2502,10 +2581,8 @@ nonlocal_referenced_p_1 (loc, data)
local to the function and is not constant. */
static int
-nonlocal_referenced_p (x)
- rtx x;
+nonlocal_referenced_p (rtx x)
{
-
if (INSN_P (x))
{
if (GET_CODE (x) == CALL_INSN)
@@ -2527,9 +2604,7 @@ nonlocal_referenced_p (x)
something which is not local to the function and is not constant. */
static int
-nonlocal_set_p_1 (loc, data)
- rtx *loc;
- void *data ATTRIBUTE_UNUSED;
+nonlocal_set_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
rtx x = *loc;
@@ -2569,7 +2644,7 @@ nonlocal_set_p_1 (loc, data)
if (MEM_VOLATILE_P (x))
return 1;
- /* FALLTHROUGH */
+ /* Fall through. */
default:
break;
@@ -2582,10 +2657,8 @@ nonlocal_set_p_1 (loc, data)
local to the function and is not constant. */
static int
-nonlocal_set_p (x)
- rtx x;
+nonlocal_set_p (rtx x)
{
-
if (INSN_P (x))
{
if (GET_CODE (x) == CALL_INSN)
@@ -2603,10 +2676,10 @@ nonlocal_set_p (x)
return for_each_rtx (&x, nonlocal_set_p_1, NULL);
}
-/* Mark the function if it is constant. */
+/* Mark the function if it is pure or constant. */
void
-mark_constant_function ()
+mark_constant_function (void)
{
rtx insn;
int nonlocal_memory_referenced;
@@ -2614,7 +2687,6 @@ mark_constant_function ()
if (TREE_READONLY (current_function_decl)
|| DECL_IS_PURE (current_function_decl)
|| TREE_THIS_VOLATILE (current_function_decl)
- || TYPE_MODE (TREE_TYPE (current_function_decl)) == VOIDmode
|| current_function_has_nonlocal_goto
|| !(*targetm.binds_local_p) (current_function_decl))
return;
@@ -2649,14 +2721,20 @@ mark_constant_function ()
if (insn)
;
else if (nonlocal_memory_referenced)
- DECL_IS_PURE (current_function_decl) = 1;
+ {
+ cgraph_rtl_info (current_function_decl)->pure_function = 1;
+ DECL_IS_PURE (current_function_decl) = 1;
+ }
else
- TREE_READONLY (current_function_decl) = 1;
+ {
+ cgraph_rtl_info (current_function_decl)->const_function = 1;
+ TREE_READONLY (current_function_decl) = 1;
+ }
}
void
-init_alias_once ()
+init_alias_once (void)
{
int i;
@@ -2682,46 +2760,77 @@ init_alias_once ()
static_reg_base_value[HARD_FRAME_POINTER_REGNUM]
= gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
#endif
+}
- alias_sets = splay_tree_new (splay_tree_compare_ints, 0, 0);
+/* Set MEMORY_MODIFIED when X modifies DATA (that is assumed
+ to be memory reference. */
+static bool memory_modified;
+static void
+memory_modified_1 (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
+{
+ if (GET_CODE (x) == MEM)
+ {
+ if (anti_dependence (x, (rtx)data) || output_dependence (x, (rtx)data))
+ memory_modified = true;
+ }
+}
+
+
+/* Return true when INSN possibly modify memory contents of MEM
+ (ie address can be modified). */
+bool
+memory_modified_in_insn_p (rtx mem, rtx insn)
+{
+ if (!INSN_P (insn))
+ return false;
+ memory_modified = false;
+ note_stores (PATTERN (insn), memory_modified_1, mem);
+ return memory_modified;
}
/* Initialize the aliasing machinery. Initialize the REG_KNOWN_VALUE
array. */
void
-init_alias_analysis ()
+init_alias_analysis (void)
{
- int maxreg = max_reg_num ();
+ unsigned int maxreg = max_reg_num ();
int changed, pass;
int i;
unsigned int ui;
rtx insn;
- reg_known_value_size = maxreg;
+ timevar_push (TV_ALIAS_ANALYSIS);
- reg_known_value
- = (rtx *) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (rtx))
- - FIRST_PSEUDO_REGISTER;
- reg_known_equiv_p
- = (char*) xcalloc ((maxreg - FIRST_PSEUDO_REGISTER), sizeof (char))
- - FIRST_PSEUDO_REGISTER;
+ reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER;
+ reg_known_value = ggc_calloc (reg_known_value_size, sizeof (rtx));
+ reg_known_equiv_p = xcalloc (reg_known_value_size, sizeof (bool));
/* Overallocate reg_base_value to allow some growth during loop
optimization. Loop unrolling can create a large number of
registers. */
- reg_base_value_size = maxreg * 2;
- reg_base_value = (rtx *) ggc_alloc_cleared (reg_base_value_size
- * sizeof (rtx));
+ if (old_reg_base_value)
+ {
+ reg_base_value = old_reg_base_value;
+ /* If varray gets large zeroing cost may get important. */
+ if (VARRAY_SIZE (reg_base_value) > 256
+ && VARRAY_SIZE (reg_base_value) > 4 * maxreg)
+ VARRAY_GROW (reg_base_value, maxreg);
+ VARRAY_CLEAR (reg_base_value);
+ if (VARRAY_SIZE (reg_base_value) < maxreg)
+ VARRAY_GROW (reg_base_value, maxreg);
+ }
+ else
+ {
+ VARRAY_RTX_INIT (reg_base_value, maxreg, "reg_base_value");
+ }
- new_reg_base_value = (rtx *) xmalloc (reg_base_value_size * sizeof (rtx));
- reg_seen = (char *) xmalloc (reg_base_value_size);
- if (! reload_completed && flag_unroll_loops)
+ new_reg_base_value = xmalloc (maxreg * sizeof (rtx));
+ reg_seen = xmalloc (maxreg);
+ if (! reload_completed && flag_old_unroll_loops)
{
- /* ??? Why are we realloc'ing if we're just going to zero it? */
- alias_invariant = (rtx *)xrealloc (alias_invariant,
- reg_base_value_size * sizeof (rtx));
- memset ((char *)alias_invariant, 0, reg_base_value_size * sizeof (rtx));
+ alias_invariant = ggc_calloc (maxreg, sizeof (rtx));
+ alias_invariant_size = maxreg;
}
/* The basic idea is that each pass through this loop will use the
@@ -2758,10 +2867,10 @@ init_alias_analysis ()
copying_arguments = true;
/* Wipe the potential alias information clean for this pass. */
- memset ((char *) new_reg_base_value, 0, reg_base_value_size * sizeof (rtx));
+ memset (new_reg_base_value, 0, maxreg * sizeof (rtx));
/* Wipe the reg_seen array clean. */
- memset ((char *) reg_seen, 0, reg_base_value_size);
+ memset (reg_seen, 0, maxreg);
/* Mark all hard registers which may contain an address.
The stack, frame and argument pointers may contain an address.
@@ -2810,6 +2919,7 @@ init_alias_analysis ()
{
unsigned int regno = REGNO (SET_DEST (set));
rtx src = SET_SRC (set);
+ rtx t;
if (REG_NOTES (insn) != 0
&& (((note = find_reg_note (insn, REG_EQUAL, 0)) != 0
@@ -2817,29 +2927,28 @@ init_alias_analysis ()
|| (note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
&& GET_CODE (XEXP (note, 0)) != EXPR_LIST
&& ! rtx_varies_p (XEXP (note, 0), 1)
- && ! reg_overlap_mentioned_p (SET_DEST (set), XEXP (note, 0)))
+ && ! reg_overlap_mentioned_p (SET_DEST (set),
+ XEXP (note, 0)))
{
- reg_known_value[regno] = XEXP (note, 0);
- reg_known_equiv_p[regno] = REG_NOTE_KIND (note) == REG_EQUIV;
+ set_reg_known_value (regno, XEXP (note, 0));
+ set_reg_known_equiv_p (regno,
+ REG_NOTE_KIND (note) == REG_EQUIV);
}
else if (REG_N_SETS (regno) == 1
&& GET_CODE (src) == PLUS
&& GET_CODE (XEXP (src, 0)) == REG
- && REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER
- && (reg_known_value[REGNO (XEXP (src, 0))])
+ && (t = get_reg_known_value (REGNO (XEXP (src, 0))))
&& GET_CODE (XEXP (src, 1)) == CONST_INT)
{
- rtx op0 = XEXP (src, 0);
- op0 = reg_known_value[REGNO (op0)];
- reg_known_value[regno]
- = plus_constant (op0, INTVAL (XEXP (src, 1)));
- reg_known_equiv_p[regno] = 0;
+ t = plus_constant (t, INTVAL (XEXP (src, 1)));
+ set_reg_known_value (regno, t);
+ set_reg_known_equiv_p (regno, 0);
}
else if (REG_N_SETS (regno) == 1
&& ! rtx_varies_p (src, 1))
{
- reg_known_value[regno] = src;
- reg_known_equiv_p[regno] = 0;
+ set_reg_known_value (regno, src);
+ set_reg_known_equiv_p (regno, 0);
}
}
}
@@ -2849,13 +2958,16 @@ init_alias_analysis ()
}
/* Now propagate values from new_reg_base_value to reg_base_value. */
- for (ui = 0; ui < reg_base_value_size; ui++)
+ if (maxreg != (unsigned int) max_reg_num())
+ abort ();
+ for (ui = 0; ui < maxreg; ui++)
{
if (new_reg_base_value[ui]
- && new_reg_base_value[ui] != reg_base_value[ui]
- && ! rtx_equal_p (new_reg_base_value[ui], reg_base_value[ui]))
+ && new_reg_base_value[ui] != VARRAY_RTX (reg_base_value, ui)
+ && ! rtx_equal_p (new_reg_base_value[ui],
+ VARRAY_RTX (reg_base_value, ui)))
{
- reg_base_value[ui] = new_reg_base_value[ui];
+ VARRAY_RTX (reg_base_value, ui) = new_reg_base_value[ui];
changed = 1;
}
}
@@ -2863,9 +2975,9 @@ init_alias_analysis ()
while (changed && ++pass < MAX_ALIAS_LOOP_PASSES);
/* Fill in the remaining entries. */
- for (i = FIRST_PSEUDO_REGISTER; i < maxreg; i++)
+ for (i = 0; i < (int)reg_known_value_size; i++)
if (reg_known_value[i] == 0)
- reg_known_value[i] = regno_reg_rtx[i];
+ reg_known_value[i] = regno_reg_rtx[i + FIRST_PSEUDO_REGISTER];
/* Simplify the reg_base_value array so that no register refers to
another register, except to special registers indirectly through
@@ -2882,16 +2994,17 @@ init_alias_analysis ()
{
changed = 0;
pass++;
- for (ui = 0; ui < reg_base_value_size; ui++)
+ for (ui = 0; ui < maxreg; ui++)
{
- rtx base = reg_base_value[ui];
+ rtx base = VARRAY_RTX (reg_base_value, ui);
if (base && GET_CODE (base) == REG)
{
unsigned int base_regno = REGNO (base);
if (base_regno == ui) /* register set from itself */
- reg_base_value[ui] = 0;
+ VARRAY_RTX (reg_base_value, ui) = 0;
else
- reg_base_value[ui] = reg_base_value[base_regno];
+ VARRAY_RTX (reg_base_value, ui)
+ = VARRAY_RTX (reg_base_value, base_regno);
changed = 1;
}
}
@@ -2903,22 +3016,21 @@ init_alias_analysis ()
new_reg_base_value = 0;
free (reg_seen);
reg_seen = 0;
+ timevar_pop (TV_ALIAS_ANALYSIS);
}
void
-end_alias_analysis ()
+end_alias_analysis (void)
{
- free (reg_known_value + FIRST_PSEUDO_REGISTER);
+ old_reg_base_value = reg_base_value;
reg_known_value = 0;
reg_known_value_size = 0;
- free (reg_known_equiv_p + FIRST_PSEUDO_REGISTER);
+ free (reg_known_equiv_p);
reg_known_equiv_p = 0;
- reg_base_value = 0;
- reg_base_value_size = 0;
if (alias_invariant)
{
- free (alias_invariant);
alias_invariant = 0;
+ alias_invariant_size = 0;
}
}
diff --git a/contrib/gcc/alloc-pool.c b/contrib/gcc/alloc-pool.c
new file mode 100644
index 000000000000..9f1583df72bf
--- /dev/null
+++ b/contrib/gcc/alloc-pool.c
@@ -0,0 +1,367 @@
+/* Functions to support a pool of allocatable objects.
+ Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2003, 2004
+ Free Software Foundation, Inc.
+ Contributed by Daniel Berlin <dan@cgsoftware.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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "alloc-pool.h"
+#include "hashtab.h"
+
+/* Redefine abort to report an internal error w/o coredump, and
+ reporting the location of the error in the source file. This logic
+ is duplicated in rtl.h and tree.h because every file that needs the
+ special abort includes one or both. toplev.h gets too few files,
+ system.h gets too many. */
+
+extern void fancy_abort (const char *, int, const char *)
+ ATTRIBUTE_NORETURN;
+#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
+
+#define align_eight(x) (((x+7) >> 3) << 3)
+
+/* The internal allocation object. */
+typedef struct allocation_object_def
+{
+#ifdef ENABLE_CHECKING
+ /* The ID of alloc pool which the object was allocated from. */
+ ALLOC_POOL_ID_TYPE id;
+#endif
+
+ union
+ {
+ /* The data of the object. */
+ char data[1];
+
+ /* Because we want any type of data to be well aligned after the ID,
+ the following elements are here. They are never accessed so
+ the allocated object may be even smaller than this structure. */
+ char *align_p;
+ HOST_WIDEST_INT align_i;
+ long double align_ld;
+ } u;
+} allocation_object;
+
+/* Convert a pointer to allocation_object from a pointer to user data. */
+#define ALLOCATION_OBJECT_PTR_FROM_USER_PTR(X) \
+ ((allocation_object *) (((char *) (X)) \
+ - offsetof (allocation_object, u.data)))
+
+/* Convert a pointer to user data from a pointer to allocation_object. */
+#define USER_PTR_FROM_ALLOCATION_OBJECT_PTR(X) \
+ ((void *) (((allocation_object *) (X))->u.data))
+
+#ifdef ENABLE_CHECKING
+/* Last used ID. */
+static ALLOC_POOL_ID_TYPE last_id;
+#endif
+
+#ifdef GATHER_STATISTICS
+
+/* Store infromation about each particular alloc_pool. */
+struct alloc_pool_descriptor
+{
+ const char *name;
+ int allocated;
+ int created;
+ int peak;
+ int current;
+};
+
+/* Hashtable mapping alloc_pool names to descriptors. */
+static htab_t alloc_pool_hash;
+
+/* Hashtable helpers. */
+static hashval_t
+hash_descriptor (const void *p)
+{
+ const struct alloc_pool_descriptor *d = p;
+ return htab_hash_pointer (d->name);
+}
+static int
+eq_descriptor (const void *p1, const void *p2)
+{
+ const struct alloc_pool_descriptor *d = p1;
+ return d->name == p2;
+}
+
+/* For given name, return descriptor, create new if needed. */
+static struct alloc_pool_descriptor *
+alloc_pool_descriptor (const char *name)
+{
+ struct alloc_pool_descriptor **slot;
+
+ if (!alloc_pool_hash)
+ alloc_pool_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
+
+ slot = (struct alloc_pool_descriptor **)
+ htab_find_slot_with_hash (alloc_pool_hash, name,
+ htab_hash_pointer (name),
+ 1);
+ if (*slot)
+ return *slot;
+ *slot = xcalloc (sizeof (**slot), 1);
+ (*slot)->name = name;
+ return *slot;
+}
+#endif
+
+/* Create a pool of things of size SIZE, with NUM in each block we
+ allocate. */
+
+alloc_pool
+create_alloc_pool (const char *name, size_t size, size_t num)
+{
+ alloc_pool pool;
+ size_t pool_size, header_size;
+#ifdef GATHER_STATISTICS
+ struct alloc_pool_descriptor *desc;
+#endif
+
+ if (!name)
+ abort ();
+
+ /* Make size large enough to store the list header. */
+ if (size < sizeof (alloc_pool_list))
+ size = sizeof (alloc_pool_list);
+
+ /* Now align the size to a multiple of 4. */
+ size = align_eight (size);
+
+#ifdef ENABLE_CHECKING
+ /* Add the aligned size of ID. */
+ size += offsetof (allocation_object, u.data);
+#endif
+
+ /* Um, we can't really allocate 0 elements per block. */
+ if (num == 0)
+ abort ();
+
+ /* Find the size of the pool structure, and the name. */
+ pool_size = sizeof (struct alloc_pool_def);
+
+ /* and allocate that much memory. */
+ pool = xmalloc (pool_size);
+
+ /* Now init the various pieces of our pool structure. */
+ pool->name = /*xstrdup (name)*/name;
+#ifdef GATHER_STATISTICS
+ desc = alloc_pool_descriptor (name);
+ desc->created++;
+#endif
+ pool->elt_size = size;
+ pool->elts_per_block = num;
+
+ /* List header size should be a multiple of 8. */
+ header_size = align_eight (sizeof (struct alloc_pool_list_def));
+
+ pool->block_size = (size * num) + header_size;
+ pool->free_list = NULL;
+ pool->elts_allocated = 0;
+ pool->elts_free = 0;
+ pool->blocks_allocated = 0;
+ pool->block_list = NULL;
+
+#ifdef ENABLE_CHECKING
+ /* Increase the last used ID and use it for this pool.
+ ID == 0 is used for free elements of pool so skip it. */
+ last_id++;
+ if (last_id == 0)
+ last_id++;
+
+ pool->id = last_id;
+#endif
+
+ return (pool);
+}
+
+/* Free all memory allocated for the given memory pool. */
+void
+free_alloc_pool (alloc_pool pool)
+{
+ alloc_pool_list block, next_block;
+#ifdef GATHER_STATISTICS
+ struct alloc_pool_descriptor *desc = alloc_pool_descriptor (pool->name);
+#endif
+
+#ifdef ENABLE_CHECKING
+ if (!pool)
+ abort ();
+#endif
+
+ /* Free each block allocated to the pool. */
+ for (block = pool->block_list; block != NULL; block = next_block)
+ {
+ next_block = block->next;
+ free (block);
+#ifdef GATHER_STATISTICS
+ desc->current -= pool->block_size;
+#endif
+ }
+ /* Lastly, free the pool. */
+#ifdef ENABLE_CHECKING
+ memset (pool, 0xaf, sizeof (*pool));
+#endif
+ free (pool);
+}
+
+/* Allocates one element from the pool specified. */
+void *
+pool_alloc (alloc_pool pool)
+{
+ alloc_pool_list header;
+ char *block;
+#ifdef GATHER_STATISTICS
+ struct alloc_pool_descriptor *desc = alloc_pool_descriptor (pool->name);
+
+ desc->allocated+=pool->elt_size;
+#endif
+
+#ifdef ENABLE_CHECKING
+ if (!pool)
+ abort ();
+#endif
+
+ /* If there are no more free elements, make some more!. */
+ if (!pool->free_list)
+ {
+ size_t i;
+ alloc_pool_list block_header;
+
+ /* Make the block. */
+ block = xmalloc (pool->block_size);
+ block_header = (alloc_pool_list) block;
+ block += align_eight (sizeof (struct alloc_pool_list_def));
+#ifdef GATHER_STATISTICS
+ desc->current += pool->block_size;
+ if (desc->peak < desc->current)
+ desc->peak = desc->current;
+#endif
+
+ /* Throw it on the block list. */
+ block_header->next = pool->block_list;
+ pool->block_list = block_header;
+
+ /* Now put the actual block pieces onto the free list. */
+ for (i = 0; i < pool->elts_per_block; i++, block += pool->elt_size)
+ {
+#ifdef ENABLE_CHECKING
+ /* Mark the element to be free. */
+ ((allocation_object *) block)->id = 0;
+#endif
+ header = (alloc_pool_list) USER_PTR_FROM_ALLOCATION_OBJECT_PTR (block);
+ header->next = pool->free_list;
+ pool->free_list = header;
+ }
+ /* Also update the number of elements we have free/allocated, and
+ increment the allocated block count. */
+ pool->elts_allocated += pool->elts_per_block;
+ pool->elts_free += pool->elts_per_block;
+ pool->blocks_allocated += 1;
+ }
+
+ /* Pull the first free element from the free list, and return it. */
+ header = pool->free_list;
+ pool->free_list = header->next;
+ pool->elts_free--;
+
+#ifdef ENABLE_CHECKING
+ /* Set the ID for element. */
+ ALLOCATION_OBJECT_PTR_FROM_USER_PTR (header)->id = pool->id;
+#endif
+
+ return ((void *) header);
+}
+
+/* Puts PTR back on POOL's free list. */
+void
+pool_free (alloc_pool pool, void *ptr)
+{
+ alloc_pool_list header;
+
+#ifdef ENABLE_CHECKING
+ if (!ptr)
+ abort ();
+
+ memset (ptr, 0xaf, pool->elt_size - offsetof (allocation_object, u.data));
+
+ /* Check whether the PTR was allocated from POOL. */
+ if (pool->id != ALLOCATION_OBJECT_PTR_FROM_USER_PTR (ptr)->id)
+ abort ();
+
+ /* Mark the element to be free. */
+ ALLOCATION_OBJECT_PTR_FROM_USER_PTR (ptr)->id = 0;
+#else
+ /* Check if we free more than we allocated, which is Bad (TM). */
+ if (pool->elts_free + 1 > pool->elts_allocated)
+ abort ();
+#endif
+
+ header = (alloc_pool_list) ptr;
+ header->next = pool->free_list;
+ pool->free_list = header;
+ pool->elts_free++;
+}
+/* Output per-alloc_pool statistics. */
+#ifdef GATHER_STATISTICS
+
+/* Used to accumulate statistics about alloc_pool sizes. */
+struct output_info
+{
+ int count;
+ int size;
+};
+
+/* Called via htab_traverse. Output alloc_pool descriptor pointed out by SLOT
+ and update statistics. */
+static int
+print_statistics (void **slot, void *b)
+{
+ struct alloc_pool_descriptor *d = (struct alloc_pool_descriptor *) *slot;
+ struct output_info *i = (struct output_info *) b;
+
+ if (d->allocated)
+ {
+ fprintf (stderr, "%-21s %6d %10d %10d %10d\n", d->name,
+ d->created, d->allocated, d->peak, d->current);
+ i->size += d->allocated;
+ i->count += d->created;
+ }
+ return 1;
+}
+#endif
+
+/* Output per-alloc_pool memory usage statistics. */
+void dump_alloc_pool_statistics (void)
+{
+#ifdef GATHER_STATISTICS
+ struct output_info info;
+
+ fprintf (stderr, "\nAlloc-pool Kind Pools Allocated Peak Leak\n");
+ fprintf (stderr, "-------------------------------------------------------------\n");
+ info.count = 0;
+ info.size = 0;
+ htab_traverse (alloc_pool_hash, print_statistics, &info);
+ fprintf (stderr, "-------------------------------------------------------------\n");
+ fprintf (stderr, "%-20s %7d %10d\n",
+ "Total", info.count, info.size);
+ fprintf (stderr, "-------------------------------------------------------------\n");
+#endif
+}
diff --git a/contrib/gcc/alloc-pool.h b/contrib/gcc/alloc-pool.h
new file mode 100644
index 000000000000..0eb2c9685b8b
--- /dev/null
+++ b/contrib/gcc/alloc-pool.h
@@ -0,0 +1,55 @@
+/* Functions to support a pool of allocatable objects
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004
+ Free Software Foundation, Inc.
+ Contributed by Daniel Berlin <dan@cgsoftware.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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+#ifndef ALLOC_POOL_H
+#define ALLOC_POOL_H
+
+typedef unsigned long ALLOC_POOL_ID_TYPE;
+
+typedef struct alloc_pool_list_def
+{
+ struct alloc_pool_list_def *next;
+}
+ *alloc_pool_list;
+
+typedef struct alloc_pool_def
+{
+ const char *name;
+#ifdef ENABLE_CHECKING
+ ALLOC_POOL_ID_TYPE id;
+#endif
+ size_t elts_per_block;
+ alloc_pool_list free_list;
+ size_t elts_allocated;
+ size_t elts_free;
+ size_t blocks_allocated;
+ alloc_pool_list block_list;
+ size_t block_size;
+ size_t elt_size;
+}
+ *alloc_pool;
+
+extern alloc_pool create_alloc_pool (const char *, size_t, size_t);
+extern void free_alloc_pool (alloc_pool);
+extern void *pool_alloc (alloc_pool);
+extern void pool_free (alloc_pool, void *);
+extern void dump_alloc_pool_statistics (void);
+#endif
diff --git a/contrib/gcc/ansidecl.h b/contrib/gcc/ansidecl.h
index f8f2d737bf0a..d2c87768ce2e 100644
--- a/contrib/gcc/ansidecl.h
+++ b/contrib/gcc/ansidecl.h
@@ -312,15 +312,4 @@ So instead we use the macro below and test it against specific values. */
#define __extension__
#endif
-/* Bootstrap support: Adjust certain macros defined by Autoconf,
- which are only valid for the stage1 compiler. If we detect
- a modern version of GCC, we are probably in stage2 or beyond,
- so unconditionally reset the values. Note that const, inline,
- etc. have been dealt with above. */
-#if (GCC_VERSION >= 2007)
-# ifndef HAVE_LONG_DOUBLE
-# define HAVE_LONG_DOUBLE 1
-# endif
-#endif /* GCC >= 2.7 */
-
#endif /* ansidecl.h */
diff --git a/contrib/gcc/attribs.c b/contrib/gcc/attribs.c
index c5a8a73026b7..a40fea7e7610 100644
--- a/contrib/gcc/attribs.c
+++ b/contrib/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 Free Software Foundation, Inc.
+ 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "toplev.h"
@@ -33,7 +35,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "target.h"
#include "langhooks.h"
-static void init_attributes PARAMS ((void));
+static void init_attributes (void);
/* Table of the tables of attributes (common, language, format, machine)
searched. */
@@ -51,7 +53,7 @@ static const struct attribute_spec empty_attribute_table[] =
if --enable-checking. */
static void
-init_attributes ()
+init_attributes (void)
{
size_t i;
@@ -132,16 +134,10 @@ init_attributes ()
information, in the form of a bitwise OR of flags in enum attribute_flags
from tree.h. Depending on these flags, some attributes may be
returned to be applied at a later stage (for example, to apply
- a decl attribute to the declaration rather than to its type). If
- ATTR_FLAG_BUILT_IN is not set and *NODE is a DECL, then also consider
- whether there might be some default attributes to apply to this DECL;
- if so, decl_attributes will be called recursively with those attributes
- and ATTR_FLAG_BUILT_IN set. */
+ a decl attribute to the declaration rather than to its type). */
tree
-decl_attributes (node, attributes, flags)
- tree *node, attributes;
- int flags;
+decl_attributes (tree *node, tree attributes, int flags)
{
tree a;
tree returned_attrs = NULL_TREE;
@@ -151,10 +147,6 @@ decl_attributes (node, attributes, flags)
(*targetm.insert_attributes) (*node, &attributes);
- if (DECL_P (*node) && TREE_CODE (*node) == FUNCTION_DECL
- && !(flags & (int) ATTR_FLAG_BUILT_IN))
- (*lang_hooks.insert_default_attributes) (*node);
-
for (a = attributes; a; a = TREE_CHAIN (a))
{
tree name = TREE_PURPOSE (a);
@@ -162,6 +154,7 @@ decl_attributes (node, attributes, flags)
tree *anode = node;
const struct attribute_spec *spec = NULL;
bool no_add_attrs = 0;
+ tree fn_ptr_tmp = NULL_TREE;
size_t i;
for (i = 0; i < ARRAY_SIZE (attribute_tables); i++)
@@ -230,9 +223,18 @@ decl_attributes (node, attributes, flags)
&& (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE))
{
- if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
- *anode = build_type_copy (*anode);
- anode = &TREE_TYPE (*anode);
+ /* OK, this is a bit convoluted. We can't just make a copy
+ of the pointer type and modify its TREE_TYPE, because if
+ we change the attributes of the target type the pointer
+ type needs to have a different TYPE_MAIN_VARIANT. So we
+ pull out the target type now, frob it as appropriate, and
+ rebuild the pointer type later.
+
+ This would all be simpler if attributes were part of the
+ declarator, grumble grumble. */
+ fn_ptr_tmp = TREE_TYPE (*anode);
+ anode = &fn_ptr_tmp;
+ flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE;
}
else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT)
{
@@ -299,6 +301,19 @@ decl_attributes (node, attributes, flags)
old_attrs));
}
}
+
+ if (fn_ptr_tmp)
+ {
+ /* Rebuild the function pointer type and put it in the
+ appropriate place. */
+ fn_ptr_tmp = build_pointer_type (fn_ptr_tmp);
+ if (DECL_P (*node))
+ TREE_TYPE (*node) = fn_ptr_tmp;
+ else if (TREE_CODE (*node) == POINTER_TYPE)
+ *node = fn_ptr_tmp;
+ else
+ abort ();
+ }
}
return returned_attrs;
@@ -315,9 +330,7 @@ decl_attributes (node, attributes, flags)
resulting attributes together the way decl_attributes expects them. */
void
-split_specs_attrs (specs_attrs, declspecs, prefix_attributes)
- tree specs_attrs;
- tree *declspecs, *prefix_attributes;
+split_specs_attrs (tree specs_attrs, tree *declspecs, tree *prefix_attributes)
{
tree t, s, a, next, specs, attrs;
@@ -392,8 +405,7 @@ split_specs_attrs (specs_attrs, declspecs, prefix_attributes)
A warning is issued for every ignored attribute. */
tree
-strip_attrs (specs_attrs)
- tree specs_attrs;
+strip_attrs (tree specs_attrs)
{
tree specs, attrs;
@@ -408,4 +420,3 @@ strip_attrs (specs_attrs)
return specs;
}
-
diff --git a/contrib/gcc/basic-block.h b/contrib/gcc/basic-block.h
index 1829fdebed24..5c6dd5c5e6dd 100644
--- a/contrib/gcc/basic-block.h
+++ b/contrib/gcc/basic-block.h
@@ -1,5 +1,5 @@
/* Define control and data flow tables, and regsets.
- Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@@ -72,7 +72,7 @@ typedef bitmap regset;
#define REGNO_REG_SET_P(TO, REG) bitmap_bit_p (TO, REG)
/* Copy the hard registers in a register set to the hard register set. */
-extern void reg_set_to_hard_reg_set PARAMS ((HARD_REG_SET *, bitmap));
+extern void reg_set_to_hard_reg_set (HARD_REG_SET *, bitmap);
#define REG_SET_TO_HARD_REG_SET(TO, FROM) \
do { \
CLEAR_HARD_REG_SET (TO); \
@@ -113,7 +113,11 @@ do { \
be done, other than zero the statistics on the first allocation. */
#define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P)
-/* Type we use to hold basic block counters. Should be at least 64bit. */
+/* Type we use to hold basic block counters. Should be at least
+ 64bit. Although a counter cannot be negative, we use a signed
+ type, because erroneous negative counts can be generated when the
+ flow graph is manipulated by various optimizations. A signed type
+ makes those easy to detect. */
typedef HOST_WIDEST_INT gcov_type;
/* Control flow edge information. */
@@ -146,9 +150,20 @@ typedef struct edge_def {
#define EDGE_DFS_BACK 32 /* A backwards edge */
#define EDGE_CAN_FALLTHRU 64 /* Candidate for straight line
flow. */
+#define EDGE_IRREDUCIBLE_LOOP 128 /* Part of irreducible loop. */
+#define EDGE_SIBCALL 256 /* Edge from sibcall to exit. */
+#define EDGE_LOOP_EXIT 512 /* Exit of a loop. */
+#define EDGE_ALL_FLAGS 1023
#define EDGE_COMPLEX (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH)
+/* Counter summary from the last set of coverage counts read by
+ profile.c. */
+extern const struct gcov_ctr_summary *profile_info;
+
+/* Declared in cfgloop.h. */
+struct loop;
+struct loops;
/* A basic block is a sequence of instructions with only entry and
only one exit. If any one of the instructions are executed, they
@@ -178,7 +193,7 @@ typedef struct edge_def {
/* Basic block information indexed by block number. */
typedef struct basic_block_def {
/* The first and last insns of the block. */
- rtx head, end;
+ rtx head_, end_;
/* The first and last trees of the block. */
tree head_tree;
@@ -219,6 +234,9 @@ typedef struct basic_block_def {
/* Outermost loop containing the block. */
struct loop *loop_father;
+ /* The dominance and postdominance information node. */
+ struct et_node *dom[2];
+
/* Expected number of executions: calculated in profile.c. */
gcov_type count;
@@ -227,6 +245,9 @@ typedef struct basic_block_def {
/* Various flags. See BB_* below. */
int flags;
+
+ /* Additional data maintained by cfg_layout routines. */
+ struct reorder_block_def *rbi;
} *basic_block;
#define BB_FREQ_MAX 10000
@@ -236,6 +257,8 @@ typedef struct basic_block_def {
#define BB_NEW 2
#define BB_REACHABLE 4
#define BB_VISITED 8
+#define BB_IRREDUCIBLE_LOOP 16
+#define BB_SUPERBLOCK 32
/* Number of basic blocks in the current function. */
@@ -296,11 +319,8 @@ extern struct obstack flow_obstack;
/* Stuff for recording basic block info. */
-#define BLOCK_HEAD(B) (BASIC_BLOCK (B)->head)
-#define BLOCK_END(B) (BASIC_BLOCK (B)->end)
-
-#define BLOCK_HEAD_TREE(B) (BASIC_BLOCK (B)->head_tree)
-#define BLOCK_END_TREE(B) (BASIC_BLOCK (B)->end_tree)
+#define BB_HEAD(B) (B)->head_
+#define BB_END(B) (B)->end_
/* Special block numbers [markers] for entry and exit. */
#define ENTRY_BLOCK (-1)
@@ -317,214 +337,44 @@ extern struct basic_block_def entry_exit_blocks[2];
#define BLOCK_NUM(INSN) (BLOCK_FOR_INSN (INSN)->index + 0)
#define set_block_for_insn(INSN, BB) (BLOCK_FOR_INSN (INSN) = BB)
-extern void compute_bb_for_insn PARAMS ((void));
-extern void free_bb_for_insn PARAMS ((void));
-extern void update_bb_for_insn PARAMS ((basic_block));
-
-extern void free_basic_block_vars PARAMS ((int));
-
-extern edge split_block PARAMS ((basic_block, rtx));
-extern basic_block split_edge PARAMS ((edge));
-extern void insert_insn_on_edge PARAMS ((rtx, edge));
-
-extern void commit_edge_insertions PARAMS ((void));
-extern void commit_edge_insertions_watch_calls PARAMS ((void));
-
-extern void remove_fake_edges PARAMS ((void));
-extern void add_noreturn_fake_exit_edges PARAMS ((void));
-extern void connect_infinite_loops_to_exit PARAMS ((void));
-extern int flow_call_edges_add PARAMS ((sbitmap));
-extern edge cached_make_edge PARAMS ((sbitmap *, basic_block,
- basic_block, int));
-extern edge unchecked_make_edge PARAMS ((basic_block,
- basic_block, int));
-extern edge make_edge PARAMS ((basic_block,
- basic_block, int));
-extern edge make_single_succ_edge PARAMS ((basic_block,
- basic_block, int));
-extern void remove_edge PARAMS ((edge));
-extern void redirect_edge_succ PARAMS ((edge, basic_block));
-extern edge redirect_edge_succ_nodup PARAMS ((edge, basic_block));
-extern void redirect_edge_pred PARAMS ((edge, basic_block));
-extern basic_block create_basic_block_structure PARAMS ((rtx, rtx, rtx, basic_block));
-extern basic_block create_basic_block PARAMS ((rtx, rtx, basic_block));
-extern int flow_delete_block PARAMS ((basic_block));
-extern int flow_delete_block_noexpunge PARAMS ((basic_block));
-extern void clear_bb_flags PARAMS ((void));
-extern void merge_blocks_nomove PARAMS ((basic_block, basic_block));
-extern void tidy_fallthru_edge PARAMS ((edge, basic_block,
- basic_block));
-extern void tidy_fallthru_edges PARAMS ((void));
-extern void flow_reverse_top_sort_order_compute PARAMS ((int *));
-extern int flow_depth_first_order_compute PARAMS ((int *, int *));
-extern void flow_preorder_transversal_compute PARAMS ((int *));
-extern void dump_edge_info PARAMS ((FILE *, edge, int));
-extern void clear_edges PARAMS ((void));
-extern void mark_critical_edges PARAMS ((void));
-extern rtx first_insn_after_basic_block_note PARAMS ((basic_block));
-
-/* Dominator information for basic blocks. */
-
-typedef struct dominance_info *dominance_info;
-
-/* Structure to hold information for each natural loop. */
-struct loop
-{
- /* Index into loops array. */
- int num;
-
- /* Basic block of loop header. */
- basic_block header;
-
- /* Basic block of loop latch. */
- basic_block latch;
-
- /* Basic block of loop pre-header or NULL if it does not exist. */
- basic_block pre_header;
-
- /* Array of edges along the pre-header extended basic block trace.
- The source of the first edge is the root node of pre-header
- extended basic block, if it exists. */
- edge *pre_header_edges;
-
- /* Number of edges along the pre_header extended basic block trace. */
- int num_pre_header_edges;
-
- /* The first block in the loop. This is not necessarily the same as
- the loop header. */
- basic_block first;
-
- /* The last block in the loop. This is not necessarily the same as
- the loop latch. */
- basic_block last;
-
- /* Bitmap of blocks contained within the loop. */
- sbitmap nodes;
-
- /* Number of blocks contained within the loop. */
- int num_nodes;
-
- /* Array of edges that enter the loop. */
- edge *entry_edges;
-
- /* Number of edges that enter the loop. */
- int num_entries;
-
- /* Array of edges that exit the loop. */
- edge *exit_edges;
-
- /* Number of edges that exit the loop. */
- int num_exits;
-
- /* Bitmap of blocks that dominate all exits of the loop. */
- sbitmap exits_doms;
-
- /* The loop nesting depth. */
- int depth;
-
- /* Superloops of the loop. */
- struct loop **pred;
-
- /* The height of the loop (enclosed loop levels) within the loop
- hierarchy tree. */
- int level;
-
- /* The outer (parent) loop or NULL if outermost loop. */
- struct loop *outer;
-
- /* The first inner (child) loop or NULL if innermost loop. */
- struct loop *inner;
-
- /* Link to the next (sibling) loop. */
- struct loop *next;
-
- /* Nonzero if the loop is invalid (e.g., contains setjmp.). */
- int invalid;
-
- /* Auxiliary info specific to a pass. */
- void *aux;
-
- /* The following are currently used by loop.c but they are likely to
- disappear as loop.c is converted to use the CFG. */
-
- /* Nonzero if the loop has a NOTE_INSN_LOOP_VTOP. */
- rtx vtop;
-
- /* Nonzero if the loop has a NOTE_INSN_LOOP_CONT.
- A continue statement will generate a branch to NEXT_INSN (cont). */
- rtx cont;
-
- /* The NOTE_INSN_LOOP_BEG. */
- rtx start;
-
- /* The NOTE_INSN_LOOP_END. */
- rtx end;
-
- /* For a rotated loop that is entered near the bottom,
- this is the label at the top. Otherwise it is zero. */
- rtx top;
-
- /* Place in the loop where control enters. */
- rtx scan_start;
-
- /* The position where to sink insns out of the loop. */
- rtx sink;
-
- /* List of all LABEL_REFs which refer to code labels outside the
- loop. Used by routines that need to know all loop exits, such as
- final_biv_value and final_giv_value.
-
- This does not include loop exits due to return instructions.
- This is because all bivs and givs are pseudos, and hence must be
- dead after a return, so the presense of a return does not affect
- any of the optimizations that use this info. It is simpler to
- just not include return instructions on this list. */
- rtx exit_labels;
-
- /* The number of LABEL_REFs on exit_labels for this loop and all
- loops nested inside it. */
- int exit_count;
-};
-
-
-/* Structure to hold CFG information about natural loops within a function. */
-struct loops
-{
- /* Number of natural loops in the function. */
- int num;
-
- /* Maxium nested loop level in the function. */
- int levels;
-
- /* Array of natural loop descriptors (scanning this array in reverse order
- will find the inner loops before their enclosing outer loops). */
- struct loop *array;
-
- /* The above array is unused in new loop infrastructure and is kept only for
- purposes of the old loop optimizer. Instead we store just pointers to
- loops here. */
- struct loop **parray;
-
- /* Pointer to root of loop heirachy tree. */
- struct loop *tree_root;
-
- /* Information derived from the CFG. */
- struct cfg
- {
- /* The bitmap vector of dominators or NULL if not computed. */
- dominance_info dom;
-
- /* The ordering of the basic blocks in a depth first search. */
- int *dfs_order;
-
- /* The reverse completion ordering of the basic blocks found in a
- depth first search. */
- int *rc_order;
- } cfg;
-
- /* Headers shared by multiple loops that should be merged. */
- sbitmap shared_headers;
-};
+extern void compute_bb_for_insn (void);
+extern void free_bb_for_insn (void);
+extern void update_bb_for_insn (basic_block);
+
+extern void free_basic_block_vars (int);
+
+extern void insert_insn_on_edge (rtx, edge);
+bool safe_insert_insn_on_edge (rtx, edge);
+
+extern void commit_edge_insertions (void);
+extern void commit_edge_insertions_watch_calls (void);
+
+extern void remove_fake_edges (void);
+extern void add_noreturn_fake_exit_edges (void);
+extern void connect_infinite_loops_to_exit (void);
+extern int flow_call_edges_add (sbitmap);
+extern edge unchecked_make_edge (basic_block, basic_block, int);
+extern edge cached_make_edge (sbitmap *, basic_block, basic_block, int);
+extern edge make_edge (basic_block, basic_block, int);
+extern edge make_single_succ_edge (basic_block, basic_block, int);
+extern void remove_edge (edge);
+extern void redirect_edge_succ (edge, basic_block);
+extern edge redirect_edge_succ_nodup (edge, basic_block);
+extern void redirect_edge_pred (edge, basic_block);
+extern basic_block create_basic_block_structure (rtx, rtx, rtx, basic_block);
+extern void clear_bb_flags (void);
+extern void tidy_fallthru_edge (edge, basic_block, basic_block);
+extern void tidy_fallthru_edges (void);
+extern void flow_reverse_top_sort_order_compute (int *);
+extern int flow_depth_first_order_compute (int *, int *);
+extern void flow_preorder_transversal_compute (int *);
+extern int dfs_enumerate_from (basic_block, int,
+ bool (*)(basic_block, void *),
+ basic_block *, int, void *);
+extern void dump_edge_info (FILE *, edge, int);
+extern void clear_edges (void);
+extern void mark_critical_edges (void);
+extern rtx first_insn_after_basic_block_note (basic_block);
/* Structure to group all of the information to process IF-THEN and
IF-THEN-ELSE blocks for the conditional execution support. This
@@ -553,19 +403,6 @@ typedef struct ce_if_block
} ce_if_block_t;
-extern int flow_loops_find PARAMS ((struct loops *, int flags));
-extern int flow_loops_update PARAMS ((struct loops *, int flags));
-extern void flow_loops_free PARAMS ((struct loops *));
-extern void flow_loops_dump PARAMS ((const struct loops *, FILE *,
- void (*)(const struct loop *,
- FILE *, int), int));
-extern void flow_loop_dump PARAMS ((const struct loop *, FILE *,
- void (*)(const struct loop *,
- FILE *, int), int));
-extern int flow_loop_scan PARAMS ((struct loops *, struct loop *, int));
-extern void flow_loop_tree_node_add PARAMS ((struct loop *, struct loop *));
-extern void flow_loop_tree_node_remove PARAMS ((struct loop *));
-
/* This structure maintains an edge list vector. */
struct edge_list
{
@@ -610,12 +447,11 @@ struct edge_list
#define EDGE_CRITICAL_P(e) ((e)->src->succ->succ_next \
&& (e)->dest->pred->pred_next)
-struct edge_list * create_edge_list PARAMS ((void));
-void free_edge_list PARAMS ((struct edge_list *));
-void print_edge_list PARAMS ((FILE *, struct edge_list *));
-void verify_edge_list PARAMS ((FILE *, struct edge_list *));
-int find_edge_index PARAMS ((struct edge_list *,
- basic_block, basic_block));
+struct edge_list * create_edge_list (void);
+void free_edge_list (struct edge_list *);
+void print_edge_list (FILE *, struct edge_list *);
+void verify_edge_list (FILE *, struct edge_list *);
+int find_edge_index (struct edge_list *, basic_block, basic_block);
enum update_life_extent
@@ -637,13 +473,19 @@ enum update_life_extent
#define PROP_AUTOINC 64 /* Create autoinc mem references. */
#define PROP_EQUAL_NOTES 128 /* Take into account REG_EQUAL notes. */
#define PROP_SCAN_DEAD_STORES 256 /* Scan for dead code. */
+#define PROP_ASM_SCAN 512 /* Internal flag used within flow.c
+ to flag analysis of asms. */
#define PROP_FINAL (PROP_DEATH_NOTES | PROP_LOG_LINKS \
| PROP_REG_INFO | PROP_KILL_DEAD_CODE \
| PROP_SCAN_DEAD_CODE | PROP_AUTOINC \
| PROP_ALLOW_CFG_CHANGES \
| PROP_SCAN_DEAD_STORES)
+#define PROP_POSTRELOAD (PROP_DEATH_NOTES \
+ | PROP_KILL_DEAD_CODE \
+ | PROP_SCAN_DEAD_CODE | PROP_AUTOINC \
+ | PROP_SCAN_DEAD_STORES)
-#define CLEANUP_EXPENSIVE 1 /* Do relativly expensive optimizations
+#define CLEANUP_EXPENSIVE 1 /* Do relatively expensive optimizations
except for edge forwarding */
#define CLEANUP_CROSSJUMP 2 /* Do crossjumping. */
#define CLEANUP_POST_REGSTACK 4 /* We run after reg-stack and need
@@ -656,155 +498,115 @@ enum update_life_extent
#define CLEANUP_THREADING 64 /* Do jump threading. */
#define CLEANUP_NO_INSN_DEL 128 /* Do not try to delete trivially dead
insns. */
-/* Flags for loop discovery. */
-
-#define LOOP_TREE 1 /* Build loop hierarchy tree. */
-#define LOOP_PRE_HEADER 2 /* Analyse loop pre-header. */
-#define LOOP_ENTRY_EDGES 4 /* Find entry edges. */
-#define LOOP_EXIT_EDGES 8 /* Find exit edges. */
-#define LOOP_EDGES (LOOP_ENTRY_EDGES | LOOP_EXIT_EDGES)
-#define LOOP_ALL 15 /* All of the above */
-
-extern void life_analysis PARAMS ((rtx, FILE *, int));
-extern int update_life_info PARAMS ((sbitmap, enum update_life_extent,
- int));
-extern int update_life_info_in_dirty_blocks PARAMS ((enum update_life_extent,
- int));
-extern int count_or_remove_death_notes PARAMS ((sbitmap, int));
-extern int propagate_block PARAMS ((basic_block, regset, regset, regset,
- int));
+#define CLEANUP_CFGLAYOUT 256 /* Do cleanup in cfglayout mode. */
+#define CLEANUP_LOG_LINKS 512 /* Update log links. */
+extern void life_analysis (rtx, FILE *, int);
+extern int update_life_info (sbitmap, enum update_life_extent, int);
+extern int update_life_info_in_dirty_blocks (enum update_life_extent, int);
+extern int count_or_remove_death_notes (sbitmap, int);
+extern int propagate_block (basic_block, regset, regset, regset, int);
struct propagate_block_info;
-extern rtx propagate_one_insn PARAMS ((struct propagate_block_info *, rtx));
+extern rtx propagate_one_insn (struct propagate_block_info *, rtx);
extern struct propagate_block_info *init_propagate_block_info
- PARAMS ((basic_block, regset, regset, regset, int));
-extern void free_propagate_block_info PARAMS ((struct propagate_block_info *));
+ (basic_block, regset, regset, regset, int);
+extern void free_propagate_block_info (struct propagate_block_info *);
/* In lcm.c */
-extern struct edge_list *pre_edge_lcm PARAMS ((FILE *, int, sbitmap *,
- sbitmap *, sbitmap *,
- sbitmap *, sbitmap **,
- sbitmap **));
-extern struct edge_list *pre_edge_rev_lcm PARAMS ((FILE *, int, sbitmap *,
- sbitmap *, sbitmap *,
- sbitmap *, sbitmap **,
- sbitmap **));
-extern void compute_available PARAMS ((sbitmap *, sbitmap *,
- sbitmap *, sbitmap *));
-extern int optimize_mode_switching PARAMS ((FILE *));
+extern struct edge_list *pre_edge_lcm (FILE *, int, sbitmap *, sbitmap *,
+ sbitmap *, sbitmap *, sbitmap **,
+ sbitmap **);
+extern struct edge_list *pre_edge_rev_lcm (FILE *, int, sbitmap *,
+ sbitmap *, sbitmap *,
+ sbitmap *, sbitmap **,
+ sbitmap **);
+extern void compute_available (sbitmap *, sbitmap *, sbitmap *, sbitmap *);
+extern int optimize_mode_switching (FILE *);
/* In emit-rtl.c. */
-extern rtx emit_block_insn_after PARAMS ((rtx, rtx, basic_block));
-extern rtx emit_block_insn_before PARAMS ((rtx, rtx, basic_block));
+extern rtx emit_block_insn_after (rtx, rtx, basic_block);
+extern rtx emit_block_insn_before (rtx, rtx, basic_block);
/* In predict.c */
-extern void estimate_probability PARAMS ((struct loops *));
-extern void note_prediction_to_br_prob PARAMS ((void));
-extern void expected_value_to_br_prob PARAMS ((void));
-extern void note_prediction_to_br_prob PARAMS ((void));
-extern bool maybe_hot_bb_p PARAMS ((basic_block));
-extern bool probably_cold_bb_p PARAMS ((basic_block));
-extern bool probably_never_executed_bb_p PARAMS ((basic_block));
+extern void estimate_probability (struct loops *);
+extern void note_prediction_to_br_prob (void);
+extern void expected_value_to_br_prob (void);
+extern bool maybe_hot_bb_p (basic_block);
+extern bool probably_cold_bb_p (basic_block);
+extern bool probably_never_executed_bb_p (basic_block);
/* In flow.c */
-extern void init_flow PARAMS ((void));
-extern void reorder_basic_blocks PARAMS ((void));
-extern void dump_bb PARAMS ((basic_block, FILE *));
-extern void debug_bb PARAMS ((basic_block));
-extern void debug_bb_n PARAMS ((int));
-extern void dump_regset PARAMS ((regset, FILE *));
-extern void debug_regset PARAMS ((regset));
-extern void allocate_reg_life_data PARAMS ((void));
-extern void allocate_bb_life_data PARAMS ((void));
-extern void expunge_block PARAMS ((basic_block));
-extern void link_block PARAMS ((basic_block, basic_block));
-extern void unlink_block PARAMS ((basic_block));
-extern void compact_blocks PARAMS ((void));
-extern basic_block alloc_block PARAMS ((void));
-extern void find_unreachable_blocks PARAMS ((void));
-extern int delete_noop_moves PARAMS ((rtx));
-extern basic_block redirect_edge_and_branch_force PARAMS ((edge, basic_block));
-extern basic_block force_nonfallthru PARAMS ((edge));
-extern bool redirect_edge_and_branch PARAMS ((edge, basic_block));
-extern rtx block_label PARAMS ((basic_block));
-extern bool forwarder_block_p PARAMS ((basic_block));
-extern bool purge_all_dead_edges PARAMS ((int));
-extern bool purge_dead_edges PARAMS ((basic_block));
-extern void find_sub_basic_blocks PARAMS ((basic_block));
-extern void find_many_sub_basic_blocks PARAMS ((sbitmap));
-extern bool can_fallthru PARAMS ((basic_block, basic_block));
-extern void flow_nodes_print PARAMS ((const char *, const sbitmap,
- FILE *));
-extern void flow_edge_list_print PARAMS ((const char *, const edge *,
- int, FILE *));
-extern void alloc_aux_for_block PARAMS ((basic_block, int));
-extern void alloc_aux_for_blocks PARAMS ((int));
-extern void clear_aux_for_blocks PARAMS ((void));
-extern void free_aux_for_blocks PARAMS ((void));
-extern void alloc_aux_for_edge PARAMS ((edge, int));
-extern void alloc_aux_for_edges PARAMS ((int));
-extern void clear_aux_for_edges PARAMS ((void));
-extern void free_aux_for_edges PARAMS ((void));
+extern void init_flow (void);
+extern void dump_bb (basic_block, FILE *);
+extern void debug_bb (basic_block);
+extern basic_block debug_bb_n (int);
+extern void dump_regset (regset, FILE *);
+extern void debug_regset (regset);
+extern void allocate_reg_life_data (void);
+extern void allocate_bb_life_data (void);
+extern void expunge_block (basic_block);
+extern void link_block (basic_block, basic_block);
+extern void unlink_block (basic_block);
+extern void compact_blocks (void);
+extern basic_block alloc_block (void);
+extern void find_unreachable_blocks (void);
+extern int delete_noop_moves (rtx);
+extern basic_block force_nonfallthru (edge);
+extern rtx block_label (basic_block);
+extern bool forwarder_block_p (basic_block);
+extern bool purge_all_dead_edges (int);
+extern bool purge_dead_edges (basic_block);
+extern void find_sub_basic_blocks (basic_block);
+extern void find_many_sub_basic_blocks (sbitmap);
+extern bool can_fallthru (basic_block, basic_block);
+extern void flow_nodes_print (const char *, const sbitmap, FILE *);
+extern void flow_edge_list_print (const char *, const edge *, int, FILE *);
+extern void alloc_aux_for_block (basic_block, int);
+extern void alloc_aux_for_blocks (int);
+extern void clear_aux_for_blocks (void);
+extern void free_aux_for_blocks (void);
+extern void alloc_aux_for_edge (edge, int);
+extern void alloc_aux_for_edges (int);
+extern void clear_aux_for_edges (void);
+extern void free_aux_for_edges (void);
/* This function is always defined so it can be called from the
debugger, and it is declared extern so we don't get warnings about
it being unused. */
-extern void verify_flow_info PARAMS ((void));
-extern bool flow_loop_outside_edge_p PARAMS ((const struct loop *, edge));
-extern bool flow_loop_nested_p PARAMS ((const struct loop *,
- const struct loop *));
-extern bool flow_bb_inside_loop_p PARAMS ((const struct loop *,
- const basic_block));
-extern basic_block *get_loop_body PARAMS ((const struct loop *));
-extern int dfs_enumerate_from PARAMS ((basic_block, int,
- bool (*)(basic_block, void *),
- basic_block *, int, void *));
-
-extern edge loop_preheader_edge PARAMS ((struct loop *));
-extern edge loop_latch_edge PARAMS ((struct loop *));
-
-extern void add_bb_to_loop PARAMS ((basic_block, struct loop *));
-extern void remove_bb_from_loops PARAMS ((basic_block));
-extern struct loop * find_common_loop PARAMS ((struct loop *, struct loop *));
-
-extern void verify_loop_structure PARAMS ((struct loops *, int));
-#define VLS_EXPECT_PREHEADERS 1
-#define VLS_EXPECT_SIMPLE_LATCHES 2
+extern void verify_flow_info (void);
typedef struct conflict_graph_def *conflict_graph;
/* Callback function when enumerating conflicts. The arguments are
the smaller and larger regno in the conflict. Returns zero if
enumeration is to continue, nonzero to halt enumeration. */
-typedef int (*conflict_graph_enum_fn) PARAMS ((int, int, void *));
+typedef int (*conflict_graph_enum_fn) (int, int, void *);
/* Prototypes of operations on conflict graphs. */
extern conflict_graph conflict_graph_new
- PARAMS ((int));
-extern void conflict_graph_delete PARAMS ((conflict_graph));
-extern int conflict_graph_add PARAMS ((conflict_graph,
- int, int));
-extern int conflict_graph_conflict_p PARAMS ((conflict_graph,
- int, int));
-extern void conflict_graph_enum PARAMS ((conflict_graph, int,
- conflict_graph_enum_fn,
- void *));
-extern void conflict_graph_merge_regs PARAMS ((conflict_graph, int,
- int));
-extern void conflict_graph_print PARAMS ((conflict_graph, FILE*));
-extern conflict_graph conflict_graph_compute
- PARAMS ((regset,
- partition));
-extern bool mark_dfs_back_edges PARAMS ((void));
-extern void set_edge_can_fallthru_flag PARAMS ((void));
-extern void update_br_prob_note PARAMS ((basic_block));
-extern void fixup_abnormal_edges PARAMS ((void));
-extern bool can_hoist_insn_p PARAMS ((rtx, rtx, regset));
-extern rtx hoist_insn_after PARAMS ((rtx, rtx, rtx, rtx));
-extern rtx hoist_insn_to_edge PARAMS ((rtx, edge, rtx, rtx));
-extern bool control_flow_insn_p PARAMS ((rtx));
+ (int);
+extern void conflict_graph_delete (conflict_graph);
+extern int conflict_graph_add (conflict_graph, int, int);
+extern int conflict_graph_conflict_p (conflict_graph, int, int);
+extern void conflict_graph_enum (conflict_graph, int, conflict_graph_enum_fn,
+ void *);
+extern void conflict_graph_merge_regs (conflict_graph, int, int);
+extern void conflict_graph_print (conflict_graph, FILE*);
+extern conflict_graph conflict_graph_compute (regset, partition);
+extern bool mark_dfs_back_edges (void);
+extern void set_edge_can_fallthru_flag (void);
+extern void update_br_prob_note (basic_block);
+extern void fixup_abnormal_edges (void);
+extern bool can_hoist_insn_p (rtx, rtx, regset);
+extern rtx hoist_insn_after (rtx, rtx, rtx, rtx);
+extern rtx hoist_insn_to_edge (rtx, edge, rtx, rtx);
+extern bool inside_basic_block_p (rtx);
+extern bool control_flow_insn_p (rtx);
+
+/* In bb-reorder.c */
+extern void reorder_basic_blocks (unsigned int);
/* In dominance.c */
@@ -814,21 +616,37 @@ enum cdi_direction
CDI_POST_DOMINATORS
};
-extern dominance_info calculate_dominance_info PARAMS ((enum cdi_direction));
-extern void free_dominance_info PARAMS ((dominance_info));
-extern basic_block nearest_common_dominator PARAMS ((dominance_info,
- basic_block, basic_block));
-extern void set_immediate_dominator PARAMS ((dominance_info,
- basic_block, basic_block));
-extern basic_block get_immediate_dominator PARAMS ((dominance_info,
- basic_block));
-extern bool dominated_by_p PARAMS ((dominance_info, basic_block, basic_block));
-extern int get_dominated_by PARAMS ((dominance_info, basic_block, basic_block **));
-extern void add_to_dominance_info PARAMS ((dominance_info, basic_block));
-extern void delete_from_dominance_info PARAMS ((dominance_info, basic_block));
-basic_block recount_dominator PARAMS ((dominance_info, basic_block));
-extern void redirect_immediate_dominators PARAMS ((dominance_info, basic_block,
- basic_block));
-void iterate_fix_dominators PARAMS ((dominance_info, basic_block *, int));
-extern void verify_dominators PARAMS ((dominance_info));
+enum dom_state
+{
+ DOM_NONE, /* Not computed at all. */
+ DOM_CONS_OK, /* The data is conservatively OK, i.e. if it says you that A dominates B,
+ it indeed does. */
+ DOM_NO_FAST_QUERY, /* The data is OK, but the fast query data are not usable. */
+ DOM_OK /* Everything is ok. */
+};
+
+extern enum dom_state dom_computed[2];
+
+extern void calculate_dominance_info (enum cdi_direction);
+extern void free_dominance_info (enum cdi_direction);
+extern basic_block nearest_common_dominator (enum cdi_direction,
+ basic_block, basic_block);
+extern void set_immediate_dominator (enum cdi_direction, basic_block,
+ basic_block);
+extern basic_block get_immediate_dominator (enum cdi_direction, basic_block);
+extern bool dominated_by_p (enum cdi_direction, basic_block, basic_block);
+extern int get_dominated_by (enum cdi_direction, basic_block, basic_block **);
+extern void add_to_dominance_info (enum cdi_direction, basic_block);
+extern void delete_from_dominance_info (enum cdi_direction, basic_block);
+basic_block recount_dominator (enum cdi_direction, basic_block);
+extern void redirect_immediate_dominators (enum cdi_direction, basic_block,
+ basic_block);
+extern void iterate_fix_dominators (enum cdi_direction, basic_block *, int);
+extern void verify_dominators (enum cdi_direction);
+extern basic_block first_dom_son (enum cdi_direction, basic_block);
+extern basic_block next_dom_son (enum cdi_direction, basic_block);
+extern bool try_redirect_by_replacing_jump (edge, basic_block, bool);
+
+#include "cfghooks.h"
+
#endif /* GCC_BASIC_BLOCK_H */
diff --git a/contrib/gcc/bb-reorder.c b/contrib/gcc/bb-reorder.c
index 857e0fbc6ec3..a8b3280d8cea 100644
--- a/contrib/gcc/bb-reorder.c
+++ b/contrib/gcc/bb-reorder.c
@@ -1,5 +1,5 @@
/* Basic block reordering routines for the GNU compiler.
- Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -18,305 +18,1101 @@
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-/* References:
-
- "Profile Guided Code Positioning"
- Pettis and Hanson; PLDI '90.
-
- TODO:
-
- (1) Consider:
-
- if (p) goto A; // predict taken
- foo ();
- A:
- if (q) goto B; // predict taken
- bar ();
- B:
- baz ();
- return;
-
- We'll currently reorder this as
-
- if (!p) goto C;
- A:
- if (!q) goto D;
- B:
- baz ();
- return;
- D:
- bar ();
- goto B;
- C:
- foo ();
- goto A;
-
- A better ordering is
-
- if (!p) goto C;
- if (!q) goto D;
- B:
- baz ();
- return;
- C:
- foo ();
- if (q) goto B;
- D:
- bar ();
- goto B;
-
- This requires that we be able to duplicate the jump at A, and
- adjust the graph traversal such that greedy placement doesn't
- fix D before C is considered.
-
- (2) Coordinate with shorten_branches to minimize the number of
- long branches.
-
- (3) Invent a method by which sufficiently non-predicted code can
- be moved to either the end of the section or another section
- entirely. Some sort of NOTE_INSN note would work fine.
-
- This completely scroggs all debugging formats, so the user
- would have to explicitly ask for it.
+/* This (greedy) algorithm constructs traces in several rounds.
+ The construction starts from "seeds". The seed for the first round
+ is the entry point of function. When there are more than one seed
+ that one is selected first that has the lowest key in the heap
+ (see function bb_to_key). Then the algorithm repeatedly adds the most
+ probable successor to the end of a trace. Finally it connects the traces.
+
+ There are two parameters: Branch Threshold and Exec Threshold.
+ If the edge to a successor of the actual basic block is lower than
+ Branch Threshold or the frequency of the successor is lower than
+ Exec Threshold the successor will be the seed in one of the next rounds.
+ Each round has these parameters lower than the previous one.
+ The last round has to have these parameters set to zero
+ so that the remaining blocks are picked up.
+
+ The algorithm selects the most probable successor from all unvisited
+ successors and successors that have been added to this trace.
+ The other successors (that has not been "sent" to the next round) will be
+ other seeds for this round and the secondary traces will start in them.
+ If the successor has not been visited in this trace it is added to the trace
+ (however, there is some heuristic for simple branches).
+ If the successor has been visited in this trace the loop has been found.
+ If the loop has many iterations the loop is rotated so that the
+ source block of the most probable edge going out from the loop
+ is the last block of the trace.
+ If the loop has few iterations and there is no edge from the last block of
+ the loop going out from loop the loop header is duplicated.
+ Finally, the construction of the trace is terminated.
+
+ When connecting traces it first checks whether there is an edge from the
+ last block of one trace to the first block of another trace.
+ When there are still some unconnected traces it checks whether there exists
+ a basic block BB such that BB is a successor of the last bb of one trace
+ and BB is a predecessor of the first block of another trace. In this case,
+ BB is duplicated and the traces are connected through this duplicate.
+ The rest of traces are simply connected so there will be a jump to the
+ beginning of the rest of trace.
+
+
+ References:
+
+ "Software Trace Cache"
+ A. Ramirez, J. Larriba-Pey, C. Navarro, J. Torrellas and M. Valero; 1999
+ http://citeseer.nj.nec.com/15361.html
+
*/
#include "config.h"
#include "system.h"
-#include "tree.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
-#include "hard-reg-set.h"
#include "basic-block.h"
#include "flags.h"
+#include "timevar.h"
#include "output.h"
#include "cfglayout.h"
-#include "function.h"
+#include "fibheap.h"
#include "target.h"
+/* The number of rounds. */
+#define N_ROUNDS 4
+
+/* Branch thresholds in thousandths (per mille) of the REG_BR_PROB_BASE. */
+static int branch_threshold[N_ROUNDS] = {400, 200, 100, 0};
+
+/* Exec thresholds in thousandths (per mille) of the frequency of bb 0. */
+static int exec_threshold[N_ROUNDS] = {500, 200, 50, 0};
+
+/* If edge frequency is lower than DUPLICATION_THRESHOLD per mille of entry
+ block the edge destination is not duplicated while connecting traces. */
+#define DUPLICATION_THRESHOLD 100
+
+/* Length of unconditional jump instruction. */
+static int uncond_jump_length;
+
+/* Structure to hold needed information for each basic block. */
+typedef struct bbro_basic_block_data_def
+{
+ /* Which trace is the bb start of (-1 means it is not a start of a trace). */
+ int start_of_trace;
+
+ /* Which trace is the bb end of (-1 means it is not an end of a trace). */
+ int end_of_trace;
+
+ /* Which heap is BB in (if any)? */
+ fibheap_t heap;
+
+ /* Which heap node is BB in (if any)? */
+ fibnode_t node;
+} bbro_basic_block_data;
+
+/* The current size of the following dynamic array. */
+static int array_size;
+
+/* The array which holds needed information for basic blocks. */
+static bbro_basic_block_data *bbd;
+
+/* To avoid frequent reallocation the size of arrays is greater than needed,
+ the number of elements is (not less than) 1.25 * size_wanted. */
+#define GET_ARRAY_SIZE(X) ((((X) / 4) + 1) * 5)
+
+/* Free the memory and set the pointer to NULL. */
+#define FREE(P) \
+ do { if (P) { free (P); P = 0; } else { abort (); } } while (0)
+
+/* Structure for holding information about a trace. */
+struct trace
+{
+ /* First and last basic block of the trace. */
+ basic_block first, last;
+
+ /* The round of the STC creation which this trace was found in. */
+ int round;
+
+ /* The length (i.e. the number of basic blocks) of the trace. */
+ int length;
+};
+
+/* Maximum frequency and count of one of the entry blocks. */
+int max_entry_frequency;
+gcov_type max_entry_count;
+
/* Local function prototypes. */
-static void make_reorder_chain PARAMS ((void));
-static basic_block make_reorder_chain_1 PARAMS ((basic_block, basic_block));
-static basic_block maybe_duplicate_computed_goto_succ PARAMS ((basic_block));
+static void find_traces (int *, struct trace *);
+static basic_block rotate_loop (edge, struct trace *, int);
+static void mark_bb_visited (basic_block, int);
+static void find_traces_1_round (int, int, gcov_type, struct trace *, int *,
+ int, fibheap_t *);
+static basic_block copy_bb (basic_block, edge, basic_block, int);
+static fibheapkey_t bb_to_key (basic_block);
+static bool better_edge_p (basic_block, edge, int, int, int, int);
+static void connect_traces (int, struct trace *);
+static bool copy_bb_p (basic_block, int);
+static int get_uncond_jump_length (void);
-/* Compute an ordering for a subgraph beginning with block BB. Record the
- ordering in RBI()->index and chained through RBI()->next. */
+/* Find the traces for Software Trace Cache. Chain each trace through
+ RBI()->next. Store the number of traces to N_TRACES and description of
+ traces to TRACES. */
static void
-make_reorder_chain ()
+find_traces (int *n_traces, struct trace *traces)
{
- basic_block prev = NULL;
- basic_block next, bb;
+ int i;
+ edge e;
+ fibheap_t heap;
+
+ /* Insert entry points of function into heap. */
+ heap = fibheap_new ();
+ max_entry_frequency = 0;
+ max_entry_count = 0;
+ for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
+ {
+ bbd[e->dest->index].heap = heap;
+ bbd[e->dest->index].node = fibheap_insert (heap, bb_to_key (e->dest),
+ e->dest);
+ if (e->dest->frequency > max_entry_frequency)
+ max_entry_frequency = e->dest->frequency;
+ if (e->dest->count > max_entry_count)
+ max_entry_count = e->dest->count;
+ }
- /* Loop until we've placed every block. */
+ /* Find the traces. */
+ for (i = 0; i < N_ROUNDS; i++)
+ {
+ gcov_type count_threshold;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "STC - round %d\n", i + 1);
+
+ if (max_entry_count < INT_MAX / 1000)
+ count_threshold = max_entry_count * exec_threshold[i] / 1000;
+ else
+ count_threshold = max_entry_count / 1000 * exec_threshold[i];
+
+ find_traces_1_round (REG_BR_PROB_BASE * branch_threshold[i] / 1000,
+ max_entry_frequency * exec_threshold[i] / 1000,
+ count_threshold, traces, n_traces, i, &heap);
+ }
+ fibheap_delete (heap);
+
+ if (rtl_dump_file)
+ {
+ for (i = 0; i < *n_traces; i++)
+ {
+ basic_block bb;
+ fprintf (rtl_dump_file, "Trace %d (round %d): ", i + 1,
+ traces[i].round + 1);
+ for (bb = traces[i].first; bb != traces[i].last; bb = bb->rbi->next)
+ fprintf (rtl_dump_file, "%d [%d] ", bb->index, bb->frequency);
+ fprintf (rtl_dump_file, "%d [%d]\n", bb->index, bb->frequency);
+ }
+ fflush (rtl_dump_file);
+ }
+}
+
+/* Rotate loop whose back edge is BACK_EDGE in the tail of trace TRACE
+ (with sequential number TRACE_N). */
+
+static basic_block
+rotate_loop (edge back_edge, struct trace *trace, int trace_n)
+{
+ basic_block bb;
+
+ /* Information about the best end (end after rotation) of the loop. */
+ basic_block best_bb = NULL;
+ edge best_edge = NULL;
+ int best_freq = -1;
+ gcov_type best_count = -1;
+ /* The best edge is preferred when its destination is not visited yet
+ or is a start block of some trace. */
+ bool is_preferred = false;
+
+ /* Find the most frequent edge that goes out from current trace. */
+ bb = back_edge->dest;
do
{
- next = NULL;
-
- /* Find the next unplaced block. */
- /* ??? Get rid of this loop, and track which blocks are not yet
- placed more directly, so as to avoid the O(N^2) worst case.
- Perhaps keep a doubly-linked list of all to-be-placed blocks;
- remove from the list as we place. The head of that list is
- what we're looking for here. */
-
- FOR_EACH_BB (bb)
- if (! RBI (bb)->visited)
- {
- next = bb;
- break;
- }
+ edge e;
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->dest != EXIT_BLOCK_PTR
+ && e->dest->rbi->visited != trace_n
+ && (e->flags & EDGE_CAN_FALLTHRU)
+ && !(e->flags & EDGE_COMPLEX))
+ {
+ if (is_preferred)
+ {
+ /* The best edge is preferred. */
+ if (!e->dest->rbi->visited
+ || bbd[e->dest->index].start_of_trace >= 0)
+ {
+ /* The current edge E is also preferred. */
+ int freq = EDGE_FREQUENCY (e);
+ if (freq > best_freq || e->count > best_count)
+ {
+ best_freq = freq;
+ best_count = e->count;
+ best_edge = e;
+ best_bb = bb;
+ }
+ }
+ }
+ else
+ {
+ if (!e->dest->rbi->visited
+ || bbd[e->dest->index].start_of_trace >= 0)
+ {
+ /* The current edge E is preferred. */
+ is_preferred = true;
+ best_freq = EDGE_FREQUENCY (e);
+ best_count = e->count;
+ best_edge = e;
+ best_bb = bb;
+ }
+ else
+ {
+ int freq = EDGE_FREQUENCY (e);
+ if (!best_edge || freq > best_freq || e->count > best_count)
+ {
+ best_freq = freq;
+ best_count = e->count;
+ best_edge = e;
+ best_bb = bb;
+ }
+ }
+ }
+ }
+ bb = bb->rbi->next;
+ }
+ while (bb != back_edge->dest);
+
+ if (best_bb)
+ {
+ /* Rotate the loop so that the BEST_EDGE goes out from the last block of
+ the trace. */
+ if (back_edge->dest == trace->first)
+ {
+ trace->first = best_bb->rbi->next;
+ }
+ else
+ {
+ basic_block prev_bb;
+
+ for (prev_bb = trace->first;
+ prev_bb->rbi->next != back_edge->dest;
+ prev_bb = prev_bb->rbi->next)
+ ;
+ prev_bb->rbi->next = best_bb->rbi->next;
+
+ /* Try to get rid of uncond jump to cond jump. */
+ if (prev_bb->succ && !prev_bb->succ->succ_next)
+ {
+ basic_block header = prev_bb->succ->dest;
+
+ /* Duplicate HEADER if it is a small block containing cond jump
+ in the end. */
+ if (any_condjump_p (BB_END (header)) && copy_bb_p (header, 0))
+ {
+ copy_bb (header, prev_bb->succ, prev_bb, trace_n);
+ }
+ }
+ }
+ }
+ else
+ {
+ /* We have not found suitable loop tail so do no rotation. */
+ best_bb = back_edge->src;
+ }
+ best_bb->rbi->next = NULL;
+ return best_bb;
+}
+
+/* This function marks BB that it was visited in trace number TRACE. */
- if (next)
- prev = make_reorder_chain_1 (next, prev);
+static void
+mark_bb_visited (basic_block bb, int trace)
+{
+ bb->rbi->visited = trace;
+ if (bbd[bb->index].heap)
+ {
+ fibheap_delete_node (bbd[bb->index].heap, bbd[bb->index].node);
+ bbd[bb->index].heap = NULL;
+ bbd[bb->index].node = NULL;
}
- while (next);
- RBI (prev)->next = NULL;
}
-/* If the successor is our artificial computed_jump block, duplicate it. */
+/* One round of finding traces. Find traces for BRANCH_TH and EXEC_TH i.e. do
+ not include basic blocks their probability is lower than BRANCH_TH or their
+ frequency is lower than EXEC_TH into traces (or count is lower than
+ COUNT_TH). It stores the new traces into TRACES and modifies the number of
+ traces *N_TRACES. Sets the round (which the trace belongs to) to ROUND. It
+ expects that starting basic blocks are in *HEAP and at the end it deletes
+ *HEAP and stores starting points for the next round into new *HEAP. */
-static inline basic_block
-maybe_duplicate_computed_goto_succ (bb)
- basic_block bb;
+static void
+find_traces_1_round (int branch_th, int exec_th, gcov_type count_th,
+ struct trace *traces, int *n_traces, int round,
+ fibheap_t *heap)
{
- edge e;
- basic_block next;
-
- /* Note that we can't rely on computed_goto_common_label still being in
- the instruction stream -- cfgloop.c likes to munge things about. But
- we can still use it's non-null-ness to avoid a fruitless search. */
- if (!cfun->computed_goto_common_label)
- return NULL;
-
- /* Only want to duplicate when coming from a simple branch. */
- e = bb->succ;
- if (!e || e->succ_next)
- return NULL;
-
- /* Only duplicate if we've already layed out this block once. */
- next = e->dest;
- if (!RBI (next)->visited)
- return NULL;
-
- /* See if the block contains only a computed branch. */
- if ((next->head == next->end
- || next_active_insn (next->head) == next->end)
- && computed_jump_p (next->end))
+ /* Heap for discarded basic blocks which are possible starting points for
+ the next round. */
+ fibheap_t new_heap = fibheap_new ();
+
+ while (!fibheap_empty (*heap))
{
+ basic_block bb;
+ struct trace *trace;
+ edge best_edge, e;
+ fibheapkey_t key;
+
+ bb = fibheap_extract_min (*heap);
+ bbd[bb->index].heap = NULL;
+ bbd[bb->index].node = NULL;
+
if (rtl_dump_file)
- fprintf (rtl_dump_file, "Duplicating block %d after %d\n",
- next->index, bb->index);
- return cfg_layout_duplicate_bb (next, e);
+ fprintf (rtl_dump_file, "Getting bb %d\n", bb->index);
+
+ /* If the BB's frequency is too low send BB to the next round. */
+ if (round < N_ROUNDS - 1
+ && (bb->frequency < exec_th || bb->count < count_th
+ || probably_never_executed_bb_p (bb)))
+ {
+ int key = bb_to_key (bb);
+ bbd[bb->index].heap = new_heap;
+ bbd[bb->index].node = fibheap_insert (new_heap, key, bb);
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ " Possible start point of next round: %d (key: %d)\n",
+ bb->index, key);
+ continue;
+ }
+
+ trace = traces + *n_traces;
+ trace->first = bb;
+ trace->round = round;
+ trace->length = 0;
+ (*n_traces)++;
+
+ do
+ {
+ int prob, freq;
+
+ /* The probability and frequency of the best edge. */
+ int best_prob = INT_MIN / 2;
+ int best_freq = INT_MIN / 2;
+
+ best_edge = NULL;
+ mark_bb_visited (bb, *n_traces);
+ trace->length++;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Basic block %d was visited in trace %d\n",
+ bb->index, *n_traces - 1);
+
+ /* Select the successor that will be placed after BB. */
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+#ifdef ENABLE_CHECKING
+ if (e->flags & EDGE_FAKE)
+ abort ();
+#endif
+
+ if (e->dest == EXIT_BLOCK_PTR)
+ continue;
+
+ if (e->dest->rbi->visited
+ && e->dest->rbi->visited != *n_traces)
+ continue;
+
+ prob = e->probability;
+ freq = EDGE_FREQUENCY (e);
+
+ /* Edge that cannot be fallthru or improbable or infrequent
+ successor (ie. it is unsuitable successor). */
+ if (!(e->flags & EDGE_CAN_FALLTHRU) || (e->flags & EDGE_COMPLEX)
+ || prob < branch_th || freq < exec_th || e->count < count_th)
+ continue;
+
+ if (better_edge_p (bb, e, prob, freq, best_prob, best_freq))
+ {
+ best_edge = e;
+ best_prob = prob;
+ best_freq = freq;
+ }
+ }
+
+ /* If the best destination has multiple predecessors, and can be
+ duplicated cheaper than a jump, don't allow it to be added
+ to a trace. We'll duplicate it when connecting traces. */
+ if (best_edge && best_edge->dest->pred->pred_next
+ && copy_bb_p (best_edge->dest, 0))
+ best_edge = NULL;
+
+ /* Add all non-selected successors to the heaps. */
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if (e == best_edge
+ || e->dest == EXIT_BLOCK_PTR
+ || e->dest->rbi->visited)
+ continue;
+
+ key = bb_to_key (e->dest);
+
+ if (bbd[e->dest->index].heap)
+ {
+ /* E->DEST is already in some heap. */
+ if (key != bbd[e->dest->index].node->key)
+ {
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file,
+ "Changing key for bb %d from %ld to %ld.\n",
+ e->dest->index,
+ (long) bbd[e->dest->index].node->key,
+ key);
+ }
+ fibheap_replace_key (bbd[e->dest->index].heap,
+ bbd[e->dest->index].node, key);
+ }
+ }
+ else
+ {
+ fibheap_t which_heap = *heap;
+
+ prob = e->probability;
+ freq = EDGE_FREQUENCY (e);
+
+ if (!(e->flags & EDGE_CAN_FALLTHRU)
+ || (e->flags & EDGE_COMPLEX)
+ || prob < branch_th || freq < exec_th
+ || e->count < count_th)
+ {
+ if (round < N_ROUNDS - 1)
+ which_heap = new_heap;
+ }
+
+ bbd[e->dest->index].heap = which_heap;
+ bbd[e->dest->index].node = fibheap_insert (which_heap,
+ key, e->dest);
+
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file,
+ " Possible start of %s round: %d (key: %ld)\n",
+ (which_heap == new_heap) ? "next" : "this",
+ e->dest->index, (long) key);
+ }
+
+ }
+ }
+
+ if (best_edge) /* Suitable successor was found. */
+ {
+ if (best_edge->dest->rbi->visited == *n_traces)
+ {
+ /* We do nothing with one basic block loops. */
+ if (best_edge->dest != bb)
+ {
+ if (EDGE_FREQUENCY (best_edge)
+ > 4 * best_edge->dest->frequency / 5)
+ {
+ /* The loop has at least 4 iterations. If the loop
+ header is not the first block of the function
+ we can rotate the loop. */
+
+ if (best_edge->dest != ENTRY_BLOCK_PTR->next_bb)
+ {
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file,
+ "Rotating loop %d - %d\n",
+ best_edge->dest->index, bb->index);
+ }
+ bb->rbi->next = best_edge->dest;
+ bb = rotate_loop (best_edge, trace, *n_traces);
+ }
+ }
+ else
+ {
+ /* The loop has less than 4 iterations. */
+
+ /* Check whether there is another edge from BB. */
+ edge another_edge;
+ for (another_edge = bb->succ;
+ another_edge;
+ another_edge = another_edge->succ_next)
+ if (another_edge != best_edge)
+ break;
+
+ if (!another_edge && copy_bb_p (best_edge->dest,
+ !optimize_size))
+ {
+ bb = copy_bb (best_edge->dest, best_edge, bb,
+ *n_traces);
+ }
+ }
+ }
+
+ /* Terminate the trace. */
+ break;
+ }
+ else
+ {
+ /* Check for a situation
+
+ A
+ /|
+ B |
+ \|
+ C
+
+ where
+ EDGE_FREQUENCY (AB) + EDGE_FREQUENCY (BC)
+ >= EDGE_FREQUENCY (AC).
+ (i.e. 2 * B->frequency >= EDGE_FREQUENCY (AC) )
+ Best ordering is then A B C.
+
+ This situation is created for example by:
+
+ if (A) B;
+ C;
+
+ */
+
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e != best_edge
+ && (e->flags & EDGE_CAN_FALLTHRU)
+ && !(e->flags & EDGE_COMPLEX)
+ && !e->dest->rbi->visited
+ && !e->dest->pred->pred_next
+ && e->dest->succ
+ && (e->dest->succ->flags & EDGE_CAN_FALLTHRU)
+ && !(e->dest->succ->flags & EDGE_COMPLEX)
+ && !e->dest->succ->succ_next
+ && e->dest->succ->dest == best_edge->dest
+ && 2 * e->dest->frequency >= EDGE_FREQUENCY (best_edge))
+ {
+ best_edge = e;
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Selecting BB %d\n",
+ best_edge->dest->index);
+ break;
+ }
+
+ bb->rbi->next = best_edge->dest;
+ bb = best_edge->dest;
+ }
+ }
+ }
+ while (best_edge);
+ trace->last = bb;
+ bbd[trace->first->index].start_of_trace = *n_traces - 1;
+ bbd[trace->last->index].end_of_trace = *n_traces - 1;
+
+ /* The trace is terminated so we have to recount the keys in heap
+ (some block can have a lower key because now one of its predecessors
+ is an end of the trace). */
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if (e->dest == EXIT_BLOCK_PTR
+ || e->dest->rbi->visited)
+ continue;
+
+ if (bbd[e->dest->index].heap)
+ {
+ key = bb_to_key (e->dest);
+ if (key != bbd[e->dest->index].node->key)
+ {
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file,
+ "Changing key for bb %d from %ld to %ld.\n",
+ e->dest->index,
+ (long) bbd[e->dest->index].node->key, key);
+ }
+ fibheap_replace_key (bbd[e->dest->index].heap,
+ bbd[e->dest->index].node,
+ key);
+ }
+ }
+ }
}
- return NULL;
+ fibheap_delete (*heap);
+
+ /* "Return" the new heap. */
+ *heap = new_heap;
}
-/* A helper function for make_reorder_chain.
+/* Create a duplicate of the basic block OLD_BB and redirect edge E to it, add
+ it to trace after BB, mark OLD_BB visited and update pass' data structures
+ (TRACE is a number of trace which OLD_BB is duplicated to). */
- We do not follow EH edges, or non-fallthru edges to noreturn blocks.
- These are assumed to be the error condition and we wish to cluster
- all of them at the very end of the function for the benefit of cache
- locality for the rest of the function.
+static basic_block
+copy_bb (basic_block old_bb, edge e, basic_block bb, int trace)
+{
+ basic_block new_bb;
- ??? We could do slightly better by noticing earlier that some subgraph
- has all paths leading to noreturn functions, but for there to be more
- than one block in such a subgraph is rare. */
+ new_bb = cfg_layout_duplicate_bb (old_bb, e);
+ if (e->dest != new_bb)
+ abort ();
+ if (e->dest->rbi->visited)
+ abort ();
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "Duplicated bb %d (created bb %d)\n",
+ old_bb->index, new_bb->index);
+ new_bb->rbi->visited = trace;
+ new_bb->rbi->next = bb->rbi->next;
+ bb->rbi->next = new_bb;
-static basic_block
-make_reorder_chain_1 (bb, prev)
- basic_block bb;
- basic_block prev;
+ if (new_bb->index >= array_size || last_basic_block > array_size)
+ {
+ int i;
+ int new_size;
+
+ new_size = MAX (last_basic_block, new_bb->index + 1);
+ new_size = GET_ARRAY_SIZE (new_size);
+ bbd = xrealloc (bbd, new_size * sizeof (bbro_basic_block_data));
+ for (i = array_size; i < new_size; i++)
+ {
+ bbd[i].start_of_trace = -1;
+ bbd[i].end_of_trace = -1;
+ bbd[i].heap = NULL;
+ bbd[i].node = NULL;
+ }
+ array_size = new_size;
+
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file,
+ "Growing the dynamic array to %d elements.\n",
+ array_size);
+ }
+ }
+
+ return new_bb;
+}
+
+/* Compute and return the key (for the heap) of the basic block BB. */
+
+static fibheapkey_t
+bb_to_key (basic_block bb)
{
edge e;
- basic_block next;
- rtx note;
- /* Mark this block visited. */
- if (prev)
+ int priority = 0;
+
+ /* Do not start in probably never executed blocks. */
+ if (probably_never_executed_bb_p (bb))
+ return BB_FREQ_MAX;
+
+ /* Prefer blocks whose predecessor is an end of some trace
+ or whose predecessor edge is EDGE_DFS_BACK. */
+ for (e = bb->pred; e; e = e->pred_next)
{
- restart:
- RBI (prev)->next = bb;
+ if ((e->src != ENTRY_BLOCK_PTR && bbd[e->src->index].end_of_trace >= 0)
+ || (e->flags & EDGE_DFS_BACK))
+ {
+ int edge_freq = EDGE_FREQUENCY (e);
- if (rtl_dump_file && prev->next_bb != bb)
- fprintf (rtl_dump_file, "Reordering block %d after %d\n",
- bb->index, prev->index);
+ if (edge_freq > priority)
+ priority = edge_freq;
+ }
}
+
+ if (priority)
+ /* The block with priority should have significantly lower key. */
+ return -(100 * BB_FREQ_MAX + 100 * priority + bb->frequency);
+ return -bb->frequency;
+}
+
+/* Return true when the edge E from basic block BB is better than the temporary
+ best edge (details are in function). The probability of edge E is PROB. The
+ frequency of the successor is FREQ. The current best probability is
+ BEST_PROB, the best frequency is BEST_FREQ.
+ The edge is considered to be equivalent when PROB does not differ much from
+ BEST_PROB; similarly for frequency. */
+
+static bool
+better_edge_p (basic_block bb, edge e, int prob, int freq, int best_prob,
+ int best_freq)
+{
+ bool is_better_edge;
+
+ /* The BEST_* values do not have to be best, but can be a bit smaller than
+ maximum values. */
+ int diff_prob = best_prob / 10;
+ int diff_freq = best_freq / 10;
+
+ if (prob > best_prob + diff_prob)
+ /* The edge has higher probability than the temporary best edge. */
+ is_better_edge = true;
+ else if (prob < best_prob - diff_prob)
+ /* The edge has lower probability than the temporary best edge. */
+ is_better_edge = false;
+ else if (freq < best_freq - diff_freq)
+ /* The edge and the temporary best edge have almost equivalent
+ probabilities. The higher frequency of a successor now means
+ that there is another edge going into that successor.
+ This successor has lower frequency so it is better. */
+ is_better_edge = true;
+ else if (freq > best_freq + diff_freq)
+ /* This successor has higher frequency so it is worse. */
+ is_better_edge = false;
+ else if (e->dest->prev_bb == bb)
+ /* The edges have equivalent probabilities and the successors
+ have equivalent frequencies. Select the previous successor. */
+ is_better_edge = true;
else
- {
- if (bb->prev_bb != ENTRY_BLOCK_PTR)
- abort ();
- }
- RBI (bb)->visited = 1;
- prev = bb;
+ is_better_edge = false;
- if (bb->succ == NULL)
- return prev;
+ return is_better_edge;
+}
- /* Find the most probable block. */
+/* Connect traces in array TRACES, N_TRACES is the count of traces. */
- next = NULL;
- if (any_condjump_p (bb->end)
- && (note = find_reg_note (bb->end, REG_BR_PROB, 0)) != NULL)
- {
- int taken, probability;
- edge e_taken, e_fall;
+static void
+connect_traces (int n_traces, struct trace *traces)
+{
+ int i;
+ bool *connected;
+ int last_trace;
+ int freq_threshold;
+ gcov_type count_threshold;
- probability = INTVAL (XEXP (note, 0));
- taken = probability > REG_BR_PROB_BASE / 2;
+ freq_threshold = max_entry_frequency * DUPLICATION_THRESHOLD / 1000;
+ if (max_entry_count < INT_MAX / 1000)
+ count_threshold = max_entry_count * DUPLICATION_THRESHOLD / 1000;
+ else
+ count_threshold = max_entry_count / 1000 * DUPLICATION_THRESHOLD;
- /* Find the normal taken edge and the normal fallthru edge.
+ connected = xcalloc (n_traces, sizeof (bool));
+ last_trace = -1;
+ for (i = 0; i < n_traces; i++)
+ {
+ int t = i;
+ int t2;
+ edge e, best;
+ int best_len;
- Note, conditional jumps with other side effects may not
- be fully optimized. In this case it is possible for
- the conditional jump to branch to the same location as
- the fallthru path.
+ if (connected[t])
+ continue;
- We should probably work to improve optimization of that
- case; however, it seems silly not to also deal with such
- problems here if they happen to occur. */
+ connected[t] = true;
- e_taken = e_fall = NULL;
- for (e = bb->succ; e ; e = e->succ_next)
+ /* Find the predecessor traces. */
+ for (t2 = t; t2 > 0;)
{
- if (e->flags & EDGE_FALLTHRU)
- e_fall = e;
- else if (! (e->flags & EDGE_EH))
- e_taken = e;
+ best = NULL;
+ best_len = 0;
+ for (e = traces[t2].first->pred; e; e = e->pred_next)
+ {
+ int si = e->src->index;
+
+ if (e->src != ENTRY_BLOCK_PTR
+ && (e->flags & EDGE_CAN_FALLTHRU)
+ && !(e->flags & EDGE_COMPLEX)
+ && bbd[si].end_of_trace >= 0
+ && !connected[bbd[si].end_of_trace]
+ && (!best
+ || e->probability > best->probability
+ || (e->probability == best->probability
+ && traces[bbd[si].end_of_trace].length > best_len)))
+ {
+ best = e;
+ best_len = traces[bbd[si].end_of_trace].length;
+ }
+ }
+ if (best)
+ {
+ best->src->rbi->next = best->dest;
+ t2 = bbd[best->src->index].end_of_trace;
+ connected[t2] = true;
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, "Connection: %d %d\n",
+ best->src->index, best->dest->index);
+ }
+ }
+ else
+ break;
}
- next = ((taken && e_taken) ? e_taken : e_fall)->dest;
+ if (last_trace >= 0)
+ traces[last_trace].last->rbi->next = traces[t2].first;
+ last_trace = t;
+
+ /* Find the successor traces. */
+ while (1)
+ {
+ /* Find the continuation of the chain. */
+ best = NULL;
+ best_len = 0;
+ for (e = traces[t].last->succ; e; e = e->succ_next)
+ {
+ int di = e->dest->index;
+
+ if (e->dest != EXIT_BLOCK_PTR
+ && (e->flags & EDGE_CAN_FALLTHRU)
+ && !(e->flags & EDGE_COMPLEX)
+ && bbd[di].start_of_trace >= 0
+ && !connected[bbd[di].start_of_trace]
+ && (!best
+ || e->probability > best->probability
+ || (e->probability == best->probability
+ && traces[bbd[di].start_of_trace].length > best_len)))
+ {
+ best = e;
+ best_len = traces[bbd[di].start_of_trace].length;
+ }
+ }
+
+ if (best)
+ {
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, "Connection: %d %d\n",
+ best->src->index, best->dest->index);
+ }
+ t = bbd[best->dest->index].start_of_trace;
+ traces[last_trace].last->rbi->next = traces[t].first;
+ connected[t] = true;
+ last_trace = t;
+ }
+ else
+ {
+ /* Try to connect the traces by duplication of 1 block. */
+ edge e2;
+ basic_block next_bb = NULL;
+ bool try_copy = false;
+
+ for (e = traces[t].last->succ; e; e = e->succ_next)
+ if (e->dest != EXIT_BLOCK_PTR
+ && (e->flags & EDGE_CAN_FALLTHRU)
+ && !(e->flags & EDGE_COMPLEX)
+ && (!best || e->probability > best->probability))
+ {
+ edge best2 = NULL;
+ int best2_len = 0;
+
+ /* If the destination is a start of a trace which is only
+ one block long, then no need to search the successor
+ blocks of the trace. Accept it. */
+ if (bbd[e->dest->index].start_of_trace >= 0
+ && traces[bbd[e->dest->index].start_of_trace].length
+ == 1)
+ {
+ best = e;
+ try_copy = true;
+ continue;
+ }
+
+ for (e2 = e->dest->succ; e2; e2 = e2->succ_next)
+ {
+ int di = e2->dest->index;
+
+ if (e2->dest == EXIT_BLOCK_PTR
+ || ((e2->flags & EDGE_CAN_FALLTHRU)
+ && !(e2->flags & EDGE_COMPLEX)
+ && bbd[di].start_of_trace >= 0
+ && !connected[bbd[di].start_of_trace]
+ && (EDGE_FREQUENCY (e2) >= freq_threshold)
+ && (e2->count >= count_threshold)
+ && (!best2
+ || e2->probability > best2->probability
+ || (e2->probability == best2->probability
+ && traces[bbd[di].start_of_trace].length
+ > best2_len))))
+ {
+ best = e;
+ best2 = e2;
+ if (e2->dest != EXIT_BLOCK_PTR)
+ best2_len = traces[bbd[di].start_of_trace].length;
+ else
+ best2_len = INT_MAX;
+ next_bb = e2->dest;
+ try_copy = true;
+ }
+ }
+ }
+
+ /* Copy tiny blocks always; copy larger blocks only when the
+ edge is traversed frequently enough. */
+ if (try_copy
+ && copy_bb_p (best->dest,
+ !optimize_size
+ && EDGE_FREQUENCY (best) >= freq_threshold
+ && best->count >= count_threshold))
+ {
+ basic_block new_bb;
+
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, "Connection: %d %d ",
+ traces[t].last->index, best->dest->index);
+ if (!next_bb)
+ fputc ('\n', rtl_dump_file);
+ else if (next_bb == EXIT_BLOCK_PTR)
+ fprintf (rtl_dump_file, "exit\n");
+ else
+ fprintf (rtl_dump_file, "%d\n", next_bb->index);
+ }
+
+ new_bb = copy_bb (best->dest, best, traces[t].last, t);
+ traces[t].last = new_bb;
+ if (next_bb && next_bb != EXIT_BLOCK_PTR)
+ {
+ t = bbd[next_bb->index].start_of_trace;
+ traces[last_trace].last->rbi->next = traces[t].first;
+ connected[t] = true;
+ last_trace = t;
+ }
+ else
+ break; /* Stop finding the successor traces. */
+ }
+ else
+ break; /* Stop finding the successor traces. */
+ }
+ }
}
- /* If the successor is our artificial computed_jump block, duplicate it. */
- else
- next = maybe_duplicate_computed_goto_succ (bb);
-
- /* In the absence of a prediction, disturb things as little as possible
- by selecting the old "next" block from the list of successors. If
- there had been a fallthru edge, that will be the one. */
- /* Note that the fallthru block may not be next any time we eliminate
- forwarder blocks. */
- if (! next)
+ if (rtl_dump_file)
{
- for (e = bb->succ; e ; e = e->succ_next)
- if (e->flags & EDGE_FALLTHRU)
- {
- next = e->dest;
- break;
- }
- else if (e->dest == bb->next_bb)
- {
- if (! (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH)))
- next = e->dest;
- }
+ basic_block bb;
+
+ fprintf (rtl_dump_file, "Final order:\n");
+ for (bb = traces[0].first; bb; bb = bb->rbi->next)
+ fprintf (rtl_dump_file, "%d ", bb->index);
+ fprintf (rtl_dump_file, "\n");
+ fflush (rtl_dump_file);
}
- /* Make sure we didn't select a silly next block. */
- if (! next || next == EXIT_BLOCK_PTR || RBI (next)->visited)
- next = NULL;
+ FREE (connected);
+}
+
+/* Return true when BB can and should be copied. CODE_MAY_GROW is true
+ when code size is allowed to grow by duplication. */
+
+static bool
+copy_bb_p (basic_block bb, int code_may_grow)
+{
+ int size = 0;
+ int max_size = uncond_jump_length;
+ rtx insn;
+ int n_succ;
+ edge e;
+
+ if (!bb->frequency)
+ return false;
+ if (!bb->pred || !bb->pred->pred_next)
+ return false;
+ if (!cfg_layout_can_duplicate_bb_p (bb))
+ return false;
- /* Recurse on the successors. Unroll the last call, as the normal
- case is exactly one or two edges, and we can tail recurse. */
+ /* Avoid duplicating blocks which have many successors (PR/13430). */
+ n_succ = 0;
for (e = bb->succ; e; e = e->succ_next)
- if (e->dest != EXIT_BLOCK_PTR
- && ! RBI (e->dest)->visited
- && e->dest->succ
- && ! (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH)))
- {
- if (next)
- {
- prev = make_reorder_chain_1 (next, prev);
- next = RBI (e->dest)->visited ? NULL : e->dest;
- }
- else
- next = e->dest;
- }
- if (next)
{
- bb = next;
- goto restart;
+ n_succ++;
+ if (n_succ > 8)
+ return false;
}
- return prev;
+ if (code_may_grow && maybe_hot_bb_p (bb))
+ max_size *= 8;
+
+ for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
+ size += get_attr_length (insn);
+ }
+
+ if (size <= max_size)
+ return true;
+
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file,
+ "Block %d can't be copied because its size = %d.\n",
+ bb->index, size);
+ }
+
+ return false;
}
-/* Reorder basic blocks. The main entry point to this file. */
+/* Return the length of unconditional jump instruction. */
+
+static int
+get_uncond_jump_length (void)
+{
+ rtx label, jump;
+ int length;
+
+ label = emit_label_before (gen_label_rtx (), get_insns ());
+ jump = emit_jump_insn (gen_jump (label));
+
+ length = get_attr_length (jump);
+
+ delete_insn (jump);
+ delete_insn (label);
+ return length;
+}
+
+/* Reorder basic blocks. The main entry point to this file. FLAGS is
+ the set of flags to pass to cfg_layout_initialize(). */
void
-reorder_basic_blocks ()
+reorder_basic_blocks (unsigned int flags)
{
+ int n_traces;
+ int i;
+ struct trace *traces;
+
if (n_basic_blocks <= 1)
return;
if ((* targetm.cannot_modify_jumps_p) ())
return;
- cfg_layout_initialize ();
+ timevar_push (TV_REORDER_BLOCKS);
+
+ cfg_layout_initialize (flags);
- make_reorder_chain ();
+ set_edge_can_fallthru_flag ();
+ mark_dfs_back_edges ();
+
+ /* We are estimating the length of uncond jump insn only once since the code
+ for getting the insn length always returns the minimal length now. */
+ if (uncond_jump_length == 0)
+ uncond_jump_length = get_uncond_jump_length ();
+
+ /* We need to know some information for each basic block. */
+ array_size = GET_ARRAY_SIZE (last_basic_block);
+ bbd = xmalloc (array_size * sizeof (bbro_basic_block_data));
+ for (i = 0; i < array_size; i++)
+ {
+ bbd[i].start_of_trace = -1;
+ bbd[i].end_of_trace = -1;
+ bbd[i].heap = NULL;
+ bbd[i].node = NULL;
+ }
+
+ traces = xmalloc (n_basic_blocks * sizeof (struct trace));
+ n_traces = 0;
+ find_traces (&n_traces, traces);
+ connect_traces (n_traces, traces);
+ FREE (traces);
+ FREE (bbd);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
cfg_layout_finalize ();
+
+ timevar_pop (TV_REORDER_BLOCKS);
}
diff --git a/contrib/gcc/bitmap.c b/contrib/gcc/bitmap.c
index 917e87bb0232..bffd9154aee3 100644
--- a/contrib/gcc/bitmap.c
+++ b/contrib/gcc/bitmap.c
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "flags.h"
#include "obstack.h"
@@ -44,18 +46,16 @@ bitmap_element bitmap_zero_bits; /* An element of all zero bits. */
static bitmap_element *bitmap_free; /* Freelist of bitmap elements. */
static GTY((deletable (""))) bitmap_element *bitmap_ggc_free;
-static void bitmap_elem_to_freelist PARAMS ((bitmap, bitmap_element *));
-static void bitmap_element_free PARAMS ((bitmap, bitmap_element *));
-static bitmap_element *bitmap_element_allocate PARAMS ((bitmap));
-static int bitmap_element_zerop PARAMS ((bitmap_element *));
-static void bitmap_element_link PARAMS ((bitmap, bitmap_element *));
-static bitmap_element *bitmap_find_bit PARAMS ((bitmap, unsigned int));
+static void bitmap_elem_to_freelist (bitmap, bitmap_element *);
+static void bitmap_element_free (bitmap, bitmap_element *);
+static bitmap_element *bitmap_element_allocate (bitmap);
+static int bitmap_element_zerop (bitmap_element *);
+static void bitmap_element_link (bitmap, bitmap_element *);
+static bitmap_element *bitmap_find_bit (bitmap, unsigned int);
/* Add ELEM to the appropriate freelist. */
static INLINE void
-bitmap_elem_to_freelist (head, elt)
- bitmap head;
- bitmap_element *elt;
+bitmap_elem_to_freelist (bitmap head, bitmap_element *elt)
{
if (head->using_obstack)
{
@@ -73,9 +73,7 @@ bitmap_elem_to_freelist (head, elt)
bitmap_obstack, "free" actually means "put onto the freelist". */
static INLINE void
-bitmap_element_free (head, elt)
- bitmap head;
- bitmap_element *elt;
+bitmap_element_free (bitmap head, bitmap_element *elt)
{
bitmap_element *next = elt->next;
bitmap_element *prev = elt->prev;
@@ -103,8 +101,7 @@ bitmap_element_free (head, elt)
/* Allocate a bitmap element. The bits are cleared, but nothing else is. */
static INLINE bitmap_element *
-bitmap_element_allocate (head)
- bitmap head;
+bitmap_element_allocate (bitmap head)
{
bitmap_element *element;
@@ -123,31 +120,18 @@ bitmap_element_allocate (head)
if (!bitmap_obstack_init)
{
bitmap_obstack_init = TRUE;
-
- /* Let particular systems override the size of a chunk. */
-#ifndef OBSTACK_CHUNK_SIZE
-#define OBSTACK_CHUNK_SIZE 0
-#endif
- /* Let them override the alloc and free routines too. */
-#ifndef OBSTACK_CHUNK_ALLOC
-#define OBSTACK_CHUNK_ALLOC xmalloc
-#endif
-#ifndef OBSTACK_CHUNK_FREE
-#define OBSTACK_CHUNK_FREE free
-#endif
-
+
#if !defined(__GNUC__) || (__GNUC__ < 2)
#define __alignof__(type) 0
#endif
-
+
obstack_specify_allocation (&bitmap_obstack, OBSTACK_CHUNK_SIZE,
__alignof__ (bitmap_element),
- (void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
- (void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
+ obstack_chunk_alloc,
+ obstack_chunk_free);
}
-
- element = (bitmap_element *) obstack_alloc (&bitmap_obstack,
- sizeof (bitmap_element));
+
+ element = obstack_alloc (&bitmap_obstack, sizeof (bitmap_element));
}
}
else
@@ -169,7 +153,7 @@ bitmap_element_allocate (head)
/* Release any memory allocated by bitmaps. */
void
-bitmap_release_memory ()
+bitmap_release_memory (void)
{
bitmap_free = 0;
if (bitmap_obstack_init)
@@ -182,8 +166,7 @@ bitmap_release_memory ()
/* Return nonzero if all bits in an element are zero. */
static INLINE int
-bitmap_element_zerop (element)
- bitmap_element *element;
+bitmap_element_zerop (bitmap_element *element)
{
#if BITMAP_ELEMENT_WORDS == 2
return (element->bits[0] | element->bits[1]) == 0;
@@ -201,9 +184,7 @@ bitmap_element_zerop (element)
/* Link the bitmap element into the current bitmap linked list. */
static INLINE void
-bitmap_element_link (head, element)
- bitmap head;
- bitmap_element *element;
+bitmap_element_link (bitmap head, bitmap_element *element)
{
unsigned int indx = element->indx;
bitmap_element *ptr;
@@ -258,8 +239,7 @@ bitmap_element_link (head, element)
/* Clear a bitmap by freeing the linked list. */
INLINE void
-bitmap_clear (head)
- bitmap head;
+bitmap_clear (bitmap head)
{
bitmap_element *element, *next;
@@ -275,9 +255,7 @@ bitmap_clear (head)
/* Copy a bitmap to another bitmap. */
void
-bitmap_copy (to, from)
- bitmap to;
- bitmap from;
+bitmap_copy (bitmap to, bitmap from)
{
bitmap_element *from_ptr, *to_ptr = 0;
#if BITMAP_ELEMENT_WORDS != 2
@@ -286,7 +264,7 @@ bitmap_copy (to, from)
bitmap_clear (to);
- /* Copy elements in forward direction one at a time */
+ /* Copy elements in forward direction one at a time. */
for (from_ptr = from->first; from_ptr; from_ptr = from_ptr->next)
{
bitmap_element *to_elt = bitmap_element_allocate (to);
@@ -326,9 +304,7 @@ bitmap_copy (to, from)
faster. */
static INLINE bitmap_element *
-bitmap_find_bit (head, bit)
- bitmap head;
- unsigned int bit;
+bitmap_find_bit (bitmap head, unsigned int bit)
{
bitmap_element *element;
unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
@@ -362,9 +338,7 @@ bitmap_find_bit (head, bit)
/* Clear a single bit in a bitmap. */
void
-bitmap_clear_bit (head, bit)
- bitmap head;
- int bit;
+bitmap_clear_bit (bitmap head, int bit)
{
bitmap_element *ptr = bitmap_find_bit (head, bit);
@@ -374,7 +348,7 @@ bitmap_clear_bit (head, bit)
unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
ptr->bits[word_num] &= ~ (((BITMAP_WORD) 1) << bit_num);
- /* If we cleared the entire word, free up the element */
+ /* If we cleared the entire word, free up the element. */
if (bitmap_element_zerop (ptr))
bitmap_element_free (head, ptr);
}
@@ -383,9 +357,7 @@ bitmap_clear_bit (head, bit)
/* Set a single bit in a bitmap. */
void
-bitmap_set_bit (head, bit)
- bitmap head;
- int bit;
+bitmap_set_bit (bitmap head, int bit)
{
bitmap_element *ptr = bitmap_find_bit (head, bit);
unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
@@ -406,9 +378,7 @@ bitmap_set_bit (head, bit)
/* Return whether a bit is set within a bitmap. */
int
-bitmap_bit_p (head, bit)
- bitmap head;
- int bit;
+bitmap_bit_p (bitmap head, int bit)
{
bitmap_element *ptr;
unsigned bit_num;
@@ -428,8 +398,7 @@ bitmap_bit_p (head, bit)
if the bitmap is empty. */
int
-bitmap_first_set_bit (a)
- bitmap a;
+bitmap_first_set_bit (bitmap a)
{
bitmap_element *ptr = a->first;
BITMAP_WORD word;
@@ -481,8 +450,7 @@ bitmap_first_set_bit (a)
if the bitmap is empty. */
int
-bitmap_last_set_bit (a)
- bitmap a;
+bitmap_last_set_bit (bitmap a)
{
bitmap_element *ptr = a->first;
BITMAP_WORD word;
@@ -534,11 +502,8 @@ bitmap_last_set_bit (a)
a specific bit manipulation. Return true if TO changes. */
int
-bitmap_operation (to, from1, from2, operation)
- bitmap to;
- bitmap from1;
- bitmap from2;
- enum bitmap_bits operation;
+bitmap_operation (bitmap to, bitmap from1, bitmap from2,
+ enum bitmap_bits operation)
{
#define HIGHEST_INDEX (unsigned int) ~0
@@ -697,14 +662,12 @@ bitmap_operation (to, from1, from2, operation)
/* Return true if two bitmaps are identical. */
int
-bitmap_equal_p (a, b)
- bitmap a;
- bitmap b;
+bitmap_equal_p (bitmap a, bitmap b)
{
bitmap_head c;
int ret;
- memset (&c, 0, sizeof (c));
+ memset (&c, 0, sizeof (c));
ret = ! bitmap_operation (&c, a, b, BITMAP_XOR);
bitmap_clear (&c);
@@ -715,10 +678,7 @@ bitmap_equal_p (a, b)
bitmap FROM2. */
void
-bitmap_ior_and_compl (to, from1, from2)
- bitmap to;
- bitmap from1;
- bitmap from2;
+bitmap_ior_and_compl (bitmap to, bitmap from1, bitmap from2)
{
bitmap_head tmp;
@@ -731,11 +691,7 @@ bitmap_ior_and_compl (to, from1, from2)
}
int
-bitmap_union_of_diff (dst, a, b, c)
- bitmap dst;
- bitmap a;
- bitmap b;
- bitmap c;
+bitmap_union_of_diff (bitmap dst, bitmap a, bitmap b, bitmap c)
{
bitmap_head tmp;
int changed;
@@ -753,13 +709,11 @@ bitmap_union_of_diff (dst, a, b, c)
/* Initialize a bitmap header. */
bitmap
-bitmap_initialize (head, using_obstack)
- bitmap head;
- int using_obstack;
+bitmap_initialize (bitmap head, int using_obstack)
{
if (head == NULL && ! using_obstack)
head = ggc_alloc (sizeof (*head));
-
+
head->first = head->current = 0;
head->using_obstack = using_obstack;
@@ -769,29 +723,21 @@ bitmap_initialize (head, using_obstack)
/* Debugging function to print out the contents of a bitmap. */
void
-debug_bitmap_file (file, head)
- FILE *file;
- bitmap head;
+debug_bitmap_file (FILE *file, bitmap head)
{
bitmap_element *ptr;
- fprintf (file, "\nfirst = ");
- fprintf (file, HOST_PTR_PRINTF, (PTR) head->first);
- fprintf (file, " current = ");
- fprintf (file, HOST_PTR_PRINTF, (PTR) head->current);
- fprintf (file, " indx = %u\n", head->indx);
+ fprintf (file, "\nfirst = " HOST_PTR_PRINTF
+ " current = " HOST_PTR_PRINTF " indx = %u\n",
+ (void *) head->first, (void *) head->current, head->indx);
for (ptr = head->first; ptr; ptr = ptr->next)
{
unsigned int i, j, col = 26;
- fprintf (file, "\t");
- fprintf (file, HOST_PTR_PRINTF, (PTR) ptr);
- fprintf (file, " next = ");
- fprintf (file, HOST_PTR_PRINTF, (PTR) ptr->next);
- fprintf (file, " prev = ");
- fprintf (file, HOST_PTR_PRINTF, (PTR) ptr->prev);
- fprintf (file, " indx = %u\n\t\tbits = {", ptr->indx);
+ fprintf (file, "\t" HOST_PTR_PRINTF " next = " HOST_PTR_PRINTF
+ " prev = " HOST_PTR_PRINTF " indx = %u\n\t\tbits = {",
+ (void*) ptr, (void*) ptr->next, (void*) ptr->prev, ptr->indx);
for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
for (j = 0; j < BITMAP_WORD_BITS; j++)
@@ -816,8 +762,7 @@ debug_bitmap_file (file, head)
of a bitmap. */
void
-debug_bitmap (head)
- bitmap head;
+debug_bitmap (bitmap head)
{
debug_bitmap_file (stdout, head);
}
@@ -826,11 +771,7 @@ debug_bitmap (head)
it does not print anything but the bits. */
void
-bitmap_print (file, head, prefix, suffix)
- FILE *file;
- bitmap head;
- const char *prefix;
- const char *suffix;
+bitmap_print (FILE *file, bitmap head, const char *prefix, const char *suffix)
{
const char *comma = "";
int i;
diff --git a/contrib/gcc/bitmap.h b/contrib/gcc/bitmap.h
index 85f8239cce75..4191542d3ac5 100644
--- a/contrib/gcc/bitmap.h
+++ b/contrib/gcc/bitmap.h
@@ -79,57 +79,56 @@ enum bitmap_bits {
extern bitmap_element bitmap_zero_bits; /* Zero bitmap element */
/* Clear a bitmap by freeing up the linked list. */
-extern void bitmap_clear PARAMS ((bitmap));
+extern void bitmap_clear (bitmap);
/* Copy a bitmap to another bitmap. */
-extern void bitmap_copy PARAMS ((bitmap, bitmap));
+extern void bitmap_copy (bitmap, bitmap);
/* True if two bitmaps are identical. */
-extern int bitmap_equal_p PARAMS ((bitmap, bitmap));
+extern int bitmap_equal_p (bitmap, bitmap);
/* Perform an operation on two bitmaps, yielding a third. */
-extern int bitmap_operation PARAMS ((bitmap, bitmap, bitmap, enum bitmap_bits));
+extern int bitmap_operation (bitmap, bitmap, bitmap, enum bitmap_bits);
/* `or' into one bitmap the `and' of a second bitmap witih the complement
of a third. */
-extern void bitmap_ior_and_compl PARAMS ((bitmap, bitmap, bitmap));
+extern void bitmap_ior_and_compl (bitmap, bitmap, bitmap);
/* Clear a single register in a register set. */
-extern void bitmap_clear_bit PARAMS ((bitmap, int));
+extern void bitmap_clear_bit (bitmap, int);
/* Set a single register in a register set. */
-extern void bitmap_set_bit PARAMS ((bitmap, int));
+extern void bitmap_set_bit (bitmap, int);
/* Return true if a register is set in a register set. */
-extern int bitmap_bit_p PARAMS ((bitmap, int));
+extern int bitmap_bit_p (bitmap, int);
/* Debug functions to print a bitmap linked list. */
-extern void debug_bitmap PARAMS ((bitmap));
-extern void debug_bitmap_file PARAMS ((FILE *, bitmap));
+extern void debug_bitmap (bitmap);
+extern void debug_bitmap_file (FILE *, bitmap);
-/* Print a bitmap */
-extern void bitmap_print PARAMS ((FILE *, bitmap, const char *, const char *));
+/* Print a bitmap. */
+extern void bitmap_print (FILE *, bitmap, const char *, const char *);
/* Initialize a bitmap header. If HEAD is NULL, a new header will be
allocated. USING_OBSTACK indicates how elements should be allocated. */
-extern bitmap bitmap_initialize PARAMS ((bitmap head,
- int using_obstack));
+extern bitmap bitmap_initialize (bitmap head, int using_obstack);
/* Release all memory used by the bitmap obstack. */
-extern void bitmap_release_memory PARAMS ((void));
+extern void bitmap_release_memory (void);
/* A few compatibility/functions macros for compatibility with sbitmaps */
#define dump_bitmap(file, bitmap) bitmap_print (file, bitmap, "", "\n")
#define bitmap_zero(a) bitmap_clear (a)
#define bitmap_a_or_b(a,b,c) bitmap_operation (a, b, c, BITMAP_IOR)
#define bitmap_a_and_b(a,b,c) bitmap_operation (a, b, c, BITMAP_AND)
-extern int bitmap_union_of_diff PARAMS((bitmap, bitmap, bitmap, bitmap));
-extern int bitmap_first_set_bit PARAMS((bitmap));
-extern int bitmap_last_set_bit PARAMS((bitmap));
+extern int bitmap_union_of_diff (bitmap, bitmap, bitmap, bitmap);
+extern int bitmap_first_set_bit (bitmap);
+extern int bitmap_last_set_bit (bitmap);
/* Allocate a bitmap with oballoc. */
#define BITMAP_OBSTACK_ALLOC(OBSTACK) \
- bitmap_initialize ((bitmap) obstack_alloc (OBSTACK, sizeof (bitmap_head)), 1)
+ bitmap_initialize (obstack_alloc (OBSTACK, sizeof (bitmap_head)), 1)
/* Allocate a bitmap with ggc_alloc. */
#define BITMAP_GGC_ALLOC() \
@@ -137,7 +136,7 @@ extern int bitmap_last_set_bit PARAMS((bitmap));
/* Allocate a bitmap with xmalloc. */
#define BITMAP_XMALLOC() \
- bitmap_initialize ((bitmap) xmalloc (sizeof (bitmap_head)), 1)
+ bitmap_initialize (xmalloc (sizeof (bitmap_head)), 1)
/* Do any cleanup needed on a bitmap when it is no longer used. */
#define BITMAP_FREE(BITMAP) \
@@ -249,7 +248,7 @@ do { \
ptr2_ = ptr2_->next; \
\
tmp2_ = ((ptr2_ != 0 && ptr2_->indx == ptr1_->indx) \
- ? ptr2_ : &bitmap_zero_bits); \
+ ? ptr2_ : &bitmap_zero_bits); \
\
for (; word_num_ < BITMAP_ELEMENT_WORDS; word_num_++) \
{ \
@@ -306,7 +305,7 @@ do { \
\
for (; ptr1_ != 0 ; ptr1_ = ptr1_->next) \
{ \
- /* Advance BITMAP2 to the equivalent link */ \
+ /* Advance BITMAP2 to the equivalent link. */ \
while (ptr2_ != 0 && ptr2_->indx < ptr1_->indx) \
ptr2_ = ptr2_->next; \
\
diff --git a/contrib/gcc/bt-load.c b/contrib/gcc/bt-load.c
new file mode 100644
index 000000000000..2a68cd76bdbd
--- /dev/null
+++ b/contrib/gcc/bt-load.c
@@ -0,0 +1,1377 @@
+/* Perform branch target register load optimizations.
+ Copyright (C) 2001, 2002, 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "bitmap.h"
+#include "sbitmap.h"
+#include "rtl.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "regs.h"
+#include "obstack.h"
+#include "fibheap.h"
+#include "output.h"
+#include "target.h"
+#include "expr.h"
+#include "flags.h"
+#include "insn-attr.h"
+#include "function.h"
+#include "tm_p.h"
+
+/* Target register optimizations - these are performed after reload. */
+
+typedef struct btr_def_group_s
+{
+ struct btr_def_group_s *next;
+ rtx src;
+ struct btr_def_s *members;
+} *btr_def_group;
+
+typedef struct btr_user_s
+{
+ struct btr_user_s *next;
+ basic_block bb;
+ int luid;
+ rtx insn;
+ /* If INSN has a single use of a single branch register, then
+ USE points to it within INSN. If there is more than
+ one branch register use, or the use is in some way ambiguous,
+ then USE is NULL. */
+ rtx use;
+ int n_reaching_defs;
+ int first_reaching_def;
+ char other_use_this_block;
+} *btr_user;
+
+/* btr_def structs appear on three lists:
+ 1. A list of all btr_def structures (head is
+ ALL_BTR_DEFS, linked by the NEXT field).
+ 2. A list of branch reg definitions per basic block (head is
+ BB_BTR_DEFS[i], linked by the NEXT_THIS_BB field).
+ 3. A list of all branch reg definitions belonging to the same
+ group (head is in a BTR_DEF_GROUP struct, linked by
+ NEXT_THIS_GROUP field). */
+
+typedef struct btr_def_s
+{
+ struct btr_def_s *next_this_bb;
+ struct btr_def_s *next_this_group;
+ basic_block bb;
+ int luid;
+ rtx insn;
+ int btr;
+ int cost;
+ /* For a branch register setting insn that has a constant
+ source (i.e. a label), group links together all the
+ insns with the same source. For other branch register
+ setting insns, group is NULL. */
+ btr_def_group group;
+ btr_user uses;
+ /* If this def has a reaching use which is not a simple use
+ in a branch instruction, then has_ambiguous_use will be true,
+ and we will not attempt to migrate this definition. */
+ char has_ambiguous_use;
+ /* live_range is an approximation to the true live range for this
+ def/use web, because it records the set of blocks that contain
+ the live range. There could be other live ranges for the same
+ branch register in that set of blocks, either in the block
+ containing the def (before the def), or in a block containing
+ a use (after the use). If there are such other live ranges, then
+ other_btr_uses_before_def or other_btr_uses_after_use must be set true
+ as appropriate. */
+ char other_btr_uses_before_def;
+ char other_btr_uses_after_use;
+ bitmap live_range;
+} *btr_def;
+
+static int issue_rate;
+
+static int basic_block_freq (basic_block);
+static int insn_sets_btr_p (rtx, int, int *);
+static rtx *find_btr_use (rtx);
+static int btr_referenced_p (rtx, rtx *);
+static int find_btr_reference (rtx *, void *);
+static void find_btr_def_group (btr_def_group *, btr_def);
+static btr_def add_btr_def (fibheap_t, basic_block, int, rtx,
+ unsigned int, int, btr_def_group *);
+static btr_user new_btr_user (basic_block, int, rtx);
+static void dump_hard_reg_set (HARD_REG_SET);
+static void dump_btrs_live (int);
+static void note_other_use_this_block (unsigned int, btr_user);
+static void compute_defs_uses_and_gen (fibheap_t, btr_def *,btr_user *,
+ sbitmap *, sbitmap *, HARD_REG_SET *);
+static void compute_kill (sbitmap *, sbitmap *, HARD_REG_SET *);
+static void compute_out (sbitmap *bb_out, sbitmap *, sbitmap *, int);
+static void link_btr_uses (btr_def *, btr_user *, sbitmap *, sbitmap *, int);
+static void build_btr_def_use_webs (fibheap_t);
+static int block_at_edge_of_live_range_p (int, btr_def);
+static void clear_btr_from_live_range (btr_def def);
+static void add_btr_to_live_range (btr_def);
+static void augment_live_range (bitmap, HARD_REG_SET *, basic_block,
+ basic_block);
+static int choose_btr (HARD_REG_SET);
+static void combine_btr_defs (btr_def, HARD_REG_SET *);
+static void btr_def_live_range (btr_def, HARD_REG_SET *);
+static void move_btr_def (basic_block, int, btr_def, bitmap, HARD_REG_SET *);
+static int migrate_btr_def (btr_def, int);
+static void migrate_btr_defs (enum reg_class, int);
+static int can_move_up (basic_block, rtx, int);
+static void note_btr_set (rtx, rtx, void *);
+
+/* The following code performs code motion of target load instructions
+ (instructions that set branch target registers), to move them
+ forward away from the branch instructions and out of loops (or,
+ more generally, from a more frequently executed place to a less
+ frequently executed place).
+ Moving target load instructions further in front of the branch
+ instruction that uses the target register value means that the hardware
+ has a better chance of preloading the instructions at the branch
+ target by the time the branch is reached. This avoids bubbles
+ when a taken branch needs to flush out the pipeline.
+ Moving target load instructions out of loops means they are executed
+ less frequently. */
+
+/* An obstack to hold the def-use web data structures built up for
+ migrating branch target load instructions. */
+static struct obstack migrate_btrl_obstack;
+
+/* Array indexed by basic block number, giving the set of registers
+ live in that block. */
+static HARD_REG_SET *btrs_live;
+
+/* Set of all target registers that we are willing to allocate. */
+static HARD_REG_SET all_btrs;
+
+/* Provide lower and upper bounds for target register numbers, so that
+ we don't need to search through all the hard registers all the time. */
+static int first_btr, last_btr;
+
+
+
+/* Return an estimate of the frequency of execution of block bb.
+ If we have a profiling count available, we could use it here. */
+static int
+basic_block_freq (basic_block bb)
+{
+ return bb->frequency;
+}
+
+static rtx *btr_reference_found;
+
+/* A subroutine of btr_referenced_p, called through for_each_rtx.
+ PREG is a pointer to an rtx that is to be excluded from the
+ traversal. If we find a reference to a target register anywhere
+ else, return 1, and put a pointer to it into btr_reference_found. */
+static int
+find_btr_reference (rtx *px, void *preg)
+{
+ rtx x;
+ int regno, i;
+
+ if (px == preg)
+ return -1;
+ x = *px;
+ if (GET_CODE (x) != REG)
+ return 0;
+ regno = REGNO (x);
+ for (i = HARD_REGNO_NREGS (regno, GET_MODE (x)) - 1; i >= 0; i--)
+ if (TEST_HARD_REG_BIT (all_btrs, regno+i))
+ {
+ btr_reference_found = px;
+ return 1;
+ }
+ return -1;
+}
+
+/* Return nonzero if X references (sets or reads) any branch target register.
+ If EXCLUDEP is set, disregard any references within the rtx pointed to
+ by it. If returning nonzero, also set btr_reference_found as above. */
+static int
+btr_referenced_p (rtx x, rtx *excludep)
+{
+ return for_each_rtx (&x, find_btr_reference, excludep);
+}
+
+/* Return true if insn is an instruction that sets a target register.
+ if CHECK_CONST is true, only return true if the source is constant.
+ If such a set is found and REGNO is nonzero, assign the register number
+ of the destination register to *REGNO. */
+static int
+insn_sets_btr_p (rtx insn, int check_const, int *regno)
+{
+ rtx set;
+
+ if (GET_CODE (insn) == INSN
+ && (set = single_set (insn)))
+ {
+ rtx dest = SET_DEST (set);
+ rtx src = SET_SRC (set);
+
+ if (GET_CODE (dest) == SUBREG)
+ dest = XEXP (dest, 0);
+
+ if (GET_CODE (dest) == REG
+ && TEST_HARD_REG_BIT (all_btrs, REGNO (dest)))
+ {
+ if (btr_referenced_p (src, NULL))
+ abort();
+ if (!check_const || CONSTANT_P (src))
+ {
+ if (regno)
+ *regno = REGNO (dest);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Find and return a use of a target register within an instruction INSN. */
+static rtx *
+find_btr_use (rtx insn)
+{
+ return btr_referenced_p (insn, NULL) ? btr_reference_found : NULL;
+}
+
+/* Find the group that the target register definition DEF belongs
+ to in the list starting with *ALL_BTR_DEF_GROUPS. If no such
+ group exists, create one. Add def to the group. */
+static void
+find_btr_def_group (btr_def_group *all_btr_def_groups, btr_def def)
+{
+ if (insn_sets_btr_p (def->insn, 1, NULL))
+ {
+ btr_def_group this_group;
+ rtx def_src = SET_SRC (single_set (def->insn));
+
+ /* ?? This linear search is an efficiency concern, particularly
+ as the search will almost always fail to find a match. */
+ for (this_group = *all_btr_def_groups;
+ this_group != NULL;
+ this_group = this_group->next)
+ if (rtx_equal_p (def_src, this_group->src))
+ break;
+
+ if (!this_group)
+ {
+ this_group = obstack_alloc (&migrate_btrl_obstack,
+ sizeof (struct btr_def_group_s));
+ this_group->src = def_src;
+ this_group->members = NULL;
+ this_group->next = *all_btr_def_groups;
+ *all_btr_def_groups = this_group;
+ }
+ def->group = this_group;
+ def->next_this_group = this_group->members;
+ this_group->members = def;
+ }
+ else
+ def->group = NULL;
+}
+
+/* Create a new target register definition structure, for a definition in
+ block BB, instruction INSN, and insert it into ALL_BTR_DEFS. Return
+ the new definition. */
+static btr_def
+add_btr_def (fibheap_t all_btr_defs, basic_block bb, int insn_luid, rtx insn,
+ unsigned int dest_reg, int other_btr_uses_before_def,
+ btr_def_group *all_btr_def_groups)
+{
+ btr_def this
+ = obstack_alloc (&migrate_btrl_obstack, sizeof (struct btr_def_s));
+ this->bb = bb;
+ this->luid = insn_luid;
+ this->insn = insn;
+ this->btr = dest_reg;
+ this->cost = basic_block_freq (bb);
+ this->has_ambiguous_use = 0;
+ this->other_btr_uses_before_def = other_btr_uses_before_def;
+ this->other_btr_uses_after_use = 0;
+ this->next_this_bb = NULL;
+ this->next_this_group = NULL;
+ this->uses = NULL;
+ this->live_range = NULL;
+ find_btr_def_group (all_btr_def_groups, this);
+
+ fibheap_insert (all_btr_defs, -this->cost, this);
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "Found target reg definition: sets %u { bb %d, insn %d }%s priority %d\n",
+ dest_reg, bb->index, INSN_UID (insn), (this->group ? "" : ":not const"),
+ this->cost);
+
+ return this;
+}
+
+/* Create a new target register user structure, for a use in block BB,
+ instruction INSN. Return the new user. */
+static btr_user
+new_btr_user (basic_block bb, int insn_luid, rtx insn)
+{
+ /* This instruction reads target registers. We need
+ to decide whether we can replace all target register
+ uses easily.
+ */
+ rtx *usep = find_btr_use (PATTERN (insn));
+ rtx use;
+ btr_user user = NULL;
+
+ if (usep)
+ {
+ int unambiguous_single_use;
+
+ /* We want to ensure that USE is the only use of a target
+ register in INSN, so that we know that to rewrite INSN to use
+ a different target register, all we have to do is replace USE. */
+ unambiguous_single_use = !btr_referenced_p (PATTERN (insn), usep);
+ if (!unambiguous_single_use)
+ usep = NULL;
+ }
+ use = usep ? *usep : NULL_RTX;
+ user = obstack_alloc (&migrate_btrl_obstack, sizeof (struct btr_user_s));
+ user->bb = bb;
+ user->luid = insn_luid;
+ user->insn = insn;
+ user->use = use;
+ user->other_use_this_block = 0;
+ user->next = NULL;
+ user->n_reaching_defs = 0;
+ user->first_reaching_def = -1;
+
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, "Uses target reg: { bb %d, insn %d }",
+ bb->index, INSN_UID (insn));
+
+ if (user->use)
+ fprintf (rtl_dump_file, ": unambiguous use of reg %d\n",
+ REGNO (user->use));
+ }
+
+ return user;
+}
+
+/* Write the contents of S to the dump file. */
+static void
+dump_hard_reg_set (HARD_REG_SET s)
+{
+ int reg;
+ for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++)
+ if (TEST_HARD_REG_BIT (s, reg))
+ fprintf (rtl_dump_file, " %d", reg);
+}
+
+/* Write the set of target regs live in block BB to the dump file. */
+static void
+dump_btrs_live (int bb)
+{
+ fprintf (rtl_dump_file, "BB%d live:", bb);
+ dump_hard_reg_set (btrs_live[bb]);
+ fprintf (rtl_dump_file, "\n");
+}
+
+/* REGNO is the number of a branch target register that is being used or
+ set. USERS_THIS_BB is a list of preceding branch target register users;
+ If any of them use the same register, set their other_use_this_block
+ flag. */
+static void
+note_other_use_this_block (unsigned int regno, btr_user users_this_bb)
+{
+ btr_user user;
+
+ for (user = users_this_bb; user != NULL; user = user->next)
+ if (user->use && REGNO (user->use) == regno)
+ user->other_use_this_block = 1;
+}
+
+typedef struct {
+ btr_user users_this_bb;
+ HARD_REG_SET btrs_written_in_block;
+ HARD_REG_SET btrs_live_in_block;
+ sbitmap bb_gen;
+ sbitmap *btr_defset;
+} defs_uses_info;
+
+/* Called via note_stores or directly to register stores into /
+ clobbers of a branch target register DEST that are not recognized as
+ straightforward definitions. DATA points to information about the
+ current basic block that needs updating. */
+static void
+note_btr_set (rtx dest, rtx set ATTRIBUTE_UNUSED, void *data)
+{
+ defs_uses_info *info = data;
+ int regno, end_regno;
+
+ if (GET_CODE (dest) != REG)
+ return;
+ regno = REGNO (dest);
+ end_regno = regno + HARD_REGNO_NREGS (regno, GET_MODE (dest));
+ for (; regno < end_regno; regno++)
+ if (TEST_HARD_REG_BIT (all_btrs, regno))
+ {
+ note_other_use_this_block (regno, info->users_this_bb);
+ SET_HARD_REG_BIT (info->btrs_written_in_block, regno);
+ SET_HARD_REG_BIT (info->btrs_live_in_block, regno);
+ sbitmap_difference (info->bb_gen, info->bb_gen,
+ info->btr_defset[regno - first_btr]);
+ }
+}
+
+static void
+compute_defs_uses_and_gen (fibheap_t all_btr_defs, btr_def *def_array,
+ btr_user *use_array, sbitmap *btr_defset,
+ sbitmap *bb_gen, HARD_REG_SET *btrs_written)
+{
+ /* Scan the code building up the set of all defs and all uses.
+ For each target register, build the set of defs of that register.
+ For each block, calculate the set of target registers
+ written in that block.
+ Also calculate the set of btrs ever live in that block.
+ */
+ int i;
+ int insn_luid = 0;
+ btr_def_group all_btr_def_groups = NULL;
+ defs_uses_info info;
+
+ sbitmap_vector_zero (bb_gen, n_basic_blocks);
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+ int reg;
+ btr_def defs_this_bb = NULL;
+ rtx insn;
+ rtx last;
+
+ info.users_this_bb = NULL;
+ info.bb_gen = bb_gen[i];
+ info.btr_defset = btr_defset;
+
+ CLEAR_HARD_REG_SET (info.btrs_live_in_block);
+ CLEAR_HARD_REG_SET (info.btrs_written_in_block);
+ for (reg = first_btr; reg <= last_btr; reg++)
+ if (TEST_HARD_REG_BIT (all_btrs, reg)
+ && REGNO_REG_SET_P (bb->global_live_at_start, reg))
+ SET_HARD_REG_BIT (info.btrs_live_in_block, reg);
+
+ for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb));
+ insn != last;
+ insn = NEXT_INSN (insn), insn_luid++)
+ {
+ if (INSN_P (insn))
+ {
+ int regno;
+ int insn_uid = INSN_UID (insn);
+
+ if (insn_sets_btr_p (insn, 0, &regno))
+ {
+ btr_def def = add_btr_def (
+ all_btr_defs, bb, insn_luid, insn, regno,
+ TEST_HARD_REG_BIT (info.btrs_live_in_block, regno),
+ &all_btr_def_groups);
+
+ def_array[insn_uid] = def;
+ SET_HARD_REG_BIT (info.btrs_written_in_block, regno);
+ SET_HARD_REG_BIT (info.btrs_live_in_block, regno);
+ sbitmap_difference (bb_gen[i], bb_gen[i],
+ btr_defset[regno - first_btr]);
+ SET_BIT (bb_gen[i], insn_uid);
+ def->next_this_bb = defs_this_bb;
+ defs_this_bb = def;
+ SET_BIT (btr_defset[regno - first_btr], insn_uid);
+ note_other_use_this_block (regno, info.users_this_bb);
+ }
+ else
+ {
+ if (btr_referenced_p (PATTERN (insn), NULL))
+ {
+ btr_user user = new_btr_user (bb, insn_luid, insn);
+
+ use_array[insn_uid] = user;
+ if (user->use)
+ SET_HARD_REG_BIT (info.btrs_live_in_block,
+ REGNO (user->use));
+ else
+ {
+ int reg;
+ for (reg = first_btr; reg <= last_btr; reg++)
+ if (TEST_HARD_REG_BIT (all_btrs, reg)
+ && refers_to_regno_p (reg, reg + 1, user->insn,
+ NULL))
+ {
+ note_other_use_this_block (reg,
+ info.users_this_bb);
+ SET_HARD_REG_BIT (info.btrs_live_in_block, reg);
+ }
+ note_stores (PATTERN (insn), note_btr_set, &info);
+ }
+ user->next = info.users_this_bb;
+ info.users_this_bb = user;
+ }
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ HARD_REG_SET *clobbered = &call_used_reg_set;
+ HARD_REG_SET call_saved;
+ rtx pat = PATTERN (insn);
+ int i;
+
+ /* Check for sibcall. */
+ if (GET_CODE (pat) == PARALLEL)
+ for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
+ if (GET_CODE (XVECEXP (pat, 0, i)) == RETURN)
+ {
+ COMPL_HARD_REG_SET (call_saved,
+ call_used_reg_set);
+ clobbered = &call_saved;
+ }
+
+ for (regno = first_btr; regno <= last_btr; regno++)
+ if (TEST_HARD_REG_BIT (*clobbered, regno))
+ note_btr_set (regno_reg_rtx[regno], NULL_RTX, &info);
+ }
+ }
+ }
+ }
+
+ COPY_HARD_REG_SET (btrs_live[i], info.btrs_live_in_block);
+ COPY_HARD_REG_SET (btrs_written[i], info.btrs_written_in_block);
+ if (rtl_dump_file)
+ dump_btrs_live(i);
+ }
+}
+
+static void
+compute_kill (sbitmap *bb_kill, sbitmap *btr_defset,
+ HARD_REG_SET *btrs_written)
+{
+ int i;
+ int regno;
+
+ /* For each basic block, form the set BB_KILL - the set
+ of definitions that the block kills. */
+ sbitmap_vector_zero (bb_kill, n_basic_blocks);
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ for (regno = first_btr; regno <= last_btr; regno++)
+ if (TEST_HARD_REG_BIT (all_btrs, regno)
+ && TEST_HARD_REG_BIT (btrs_written[i], regno))
+ sbitmap_a_or_b (bb_kill[i], bb_kill[i],
+ btr_defset[regno - first_btr]);
+ }
+}
+
+static void
+compute_out (sbitmap *bb_out, sbitmap *bb_gen, sbitmap *bb_kill, int max_uid)
+{
+ /* Perform iterative dataflow:
+ Initially, for all blocks, BB_OUT = BB_GEN.
+ For each block,
+ BB_IN = union over predecessors of BB_OUT(pred)
+ BB_OUT = (BB_IN - BB_KILL) + BB_GEN
+ Iterate until the bb_out sets stop growing. */
+ int i;
+ int changed;
+ sbitmap bb_in = sbitmap_alloc (max_uid);
+
+ for (i = 0; i < n_basic_blocks; i++)
+ sbitmap_copy (bb_out[i], bb_gen[i]);
+
+ changed = 1;
+ while (changed)
+ {
+ changed = 0;
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ sbitmap_union_of_preds (bb_in, bb_out, i);
+ changed |= sbitmap_union_of_diff_cg (bb_out[i], bb_gen[i],
+ bb_in, bb_kill[i]);
+ }
+ }
+ sbitmap_free (bb_in);
+}
+
+static void
+link_btr_uses (btr_def *def_array, btr_user *use_array, sbitmap *bb_out,
+ sbitmap *btr_defset, int max_uid)
+{
+ int i;
+ sbitmap reaching_defs = sbitmap_alloc (max_uid);
+
+ /* Link uses to the uses lists of all of their reaching defs.
+ Count up the number of reaching defs of each use. */
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+ rtx insn;
+ rtx last;
+
+ sbitmap_union_of_preds (reaching_defs, bb_out, i);
+ for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb));
+ insn != last;
+ insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
+ {
+ int insn_uid = INSN_UID (insn);
+
+ btr_def def = def_array[insn_uid];
+ btr_user user = use_array[insn_uid];
+ if (def != NULL)
+ {
+ /* Remove all reaching defs of regno except
+ for this one. */
+ sbitmap_difference (reaching_defs, reaching_defs,
+ btr_defset[def->btr - first_btr]);
+ SET_BIT(reaching_defs, insn_uid);
+ }
+
+ if (user != NULL)
+ {
+ /* Find all the reaching defs for this use. */
+ sbitmap reaching_defs_of_reg = sbitmap_alloc(max_uid);
+ int uid;
+
+ if (user->use)
+ sbitmap_a_and_b (
+ reaching_defs_of_reg,
+ reaching_defs,
+ btr_defset[REGNO (user->use) - first_btr]);
+ else
+ {
+ int reg;
+
+ sbitmap_zero (reaching_defs_of_reg);
+ for (reg = first_btr; reg <= last_btr; reg++)
+ if (TEST_HARD_REG_BIT (all_btrs, reg)
+ && refers_to_regno_p (reg, reg + 1, user->insn,
+ NULL))
+ sbitmap_a_or_b_and_c (reaching_defs_of_reg,
+ reaching_defs_of_reg,
+ reaching_defs,
+ btr_defset[reg - first_btr]);
+ }
+ EXECUTE_IF_SET_IN_SBITMAP (reaching_defs_of_reg, 0, uid,
+ {
+ btr_def def = def_array[uid];
+
+ /* We now know that def reaches user. */
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "Def in insn %d reaches use in insn %d\n",
+ uid, insn_uid);
+
+ user->n_reaching_defs++;
+ if (!user->use)
+ def->has_ambiguous_use = 1;
+ if (user->first_reaching_def != -1)
+ { /* There is more than one reaching def. This is
+ a rare case, so just give up on this def/use
+ web when it occurs. */
+ def->has_ambiguous_use = 1;
+ def_array[user->first_reaching_def]
+ ->has_ambiguous_use = 1;
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "(use %d has multiple reaching defs)\n",
+ insn_uid);
+ }
+ else
+ user->first_reaching_def = uid;
+ if (user->other_use_this_block)
+ def->other_btr_uses_after_use = 1;
+ user->next = def->uses;
+ def->uses = user;
+ });
+ sbitmap_free (reaching_defs_of_reg);
+ }
+
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ int regno;
+
+ for (regno = first_btr; regno <= last_btr; regno++)
+ if (TEST_HARD_REG_BIT (all_btrs, regno)
+ && TEST_HARD_REG_BIT (call_used_reg_set, regno))
+ sbitmap_difference (reaching_defs, reaching_defs,
+ btr_defset[regno - first_btr]);
+ }
+ }
+ }
+ }
+ sbitmap_free (reaching_defs);
+}
+
+static void
+build_btr_def_use_webs (fibheap_t all_btr_defs)
+{
+ const int max_uid = get_max_uid ();
+ btr_def *def_array = xcalloc (max_uid, sizeof (btr_def));
+ btr_user *use_array = xcalloc (max_uid, sizeof (btr_user));
+ sbitmap *btr_defset = sbitmap_vector_alloc (
+ (last_btr - first_btr) + 1, max_uid);
+ sbitmap *bb_gen = sbitmap_vector_alloc (n_basic_blocks, max_uid);
+ HARD_REG_SET *btrs_written = xcalloc (n_basic_blocks, sizeof (HARD_REG_SET));
+ sbitmap *bb_kill;
+ sbitmap *bb_out;
+
+ sbitmap_vector_zero (btr_defset, (last_btr - first_btr) + 1);
+
+ compute_defs_uses_and_gen (all_btr_defs, def_array, use_array, btr_defset,
+ bb_gen, btrs_written);
+
+ bb_kill = sbitmap_vector_alloc (n_basic_blocks, max_uid);
+ compute_kill (bb_kill, btr_defset, btrs_written);
+ free (btrs_written);
+
+ bb_out = sbitmap_vector_alloc (n_basic_blocks, max_uid);
+ compute_out (bb_out, bb_gen, bb_kill, max_uid);
+
+ sbitmap_vector_free (bb_gen);
+ sbitmap_vector_free (bb_kill);
+
+ link_btr_uses (def_array, use_array, bb_out, btr_defset, max_uid);
+
+ sbitmap_vector_free (bb_out);
+ sbitmap_vector_free (btr_defset);
+ free (use_array);
+ free (def_array);
+}
+
+/* Return true if basic block BB contains the start or end of the
+ live range of the definition DEF, AND there are other live
+ ranges of the same target register that include BB. */
+static int
+block_at_edge_of_live_range_p (int bb, btr_def def)
+{
+ if (def->other_btr_uses_before_def && BASIC_BLOCK (bb) == def->bb)
+ return 1;
+ else if (def->other_btr_uses_after_use)
+ {
+ btr_user user;
+ for (user = def->uses; user != NULL; user = user->next)
+ if (BASIC_BLOCK (bb) == user->bb)
+ return 1;
+ }
+ return 0;
+}
+
+/* We are removing the def/use web DEF. The target register
+ used in this web is therefore no longer live in the live range
+ of this web, so remove it from the live set of all basic blocks
+ in the live range of the web.
+ Blocks at the boundary of the live range may contain other live
+ ranges for the same target register, so we have to be careful
+ to remove the target register from the live set of these blocks
+ only if they do not contain other live ranges for the same register. */
+static void
+clear_btr_from_live_range (btr_def def)
+{
+ int bb;
+
+ EXECUTE_IF_SET_IN_BITMAP
+ (def->live_range, 0, bb,
+ {
+ if ((!def->other_btr_uses_before_def
+ && !def->other_btr_uses_after_use)
+ || !block_at_edge_of_live_range_p (bb, def))
+ {
+ CLEAR_HARD_REG_BIT (btrs_live[bb], def->btr);
+ if (rtl_dump_file)
+ dump_btrs_live (bb);
+ }
+ });
+}
+
+
+/* We are adding the def/use web DEF. Add the target register used
+ in this web to the live set of all of the basic blocks that contain
+ the live range of the web. */
+static void
+add_btr_to_live_range (btr_def def)
+{
+ int bb;
+ EXECUTE_IF_SET_IN_BITMAP
+ (def->live_range, 0, bb,
+ {
+ SET_HARD_REG_BIT (btrs_live[bb], def->btr);
+ if (rtl_dump_file)
+ dump_btrs_live (bb);
+ });
+}
+
+/* Update a live range to contain the basic block NEW_BLOCK, and all
+ blocks on paths between the existing live range and NEW_BLOCK.
+ HEAD is a block contained in the existing live range that dominates
+ all other blocks in the existing live range.
+ Also add to the set BTRS_LIVE_IN_RANGE all target registers that
+ are live in the blocks that we add to the live range.
+ It is a precondition that either NEW_BLOCK dominates HEAD,or
+ HEAD dom NEW_BLOCK. This is used to speed up the
+ implementation of this function. */
+static void
+augment_live_range (bitmap live_range, HARD_REG_SET *btrs_live_in_range,
+ basic_block head_bb, basic_block new_bb)
+{
+ basic_block *worklist, *tos;
+
+ tos = worklist = xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
+
+ if (dominated_by_p (CDI_DOMINATORS, new_bb, head_bb))
+ *tos++ = new_bb;
+ else if (dominated_by_p (CDI_DOMINATORS, head_bb, new_bb))
+ {
+ edge e;
+ int new_block = new_bb->index;
+
+ bitmap_set_bit (live_range, new_block);
+ IOR_HARD_REG_SET (*btrs_live_in_range, btrs_live[new_block]);
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file,
+ "Adding block %d to live range\n", new_block);
+ fprintf (rtl_dump_file,"Now live btrs are ");
+ dump_hard_reg_set (*btrs_live_in_range);
+ fprintf (rtl_dump_file, "\n");
+ }
+ for (e = head_bb->pred; e; e = e->pred_next)
+ *tos++ = e->src;
+ }
+ else
+ abort();
+
+ while (tos != worklist)
+ {
+ basic_block bb = *--tos;
+ if (!bitmap_bit_p (live_range, bb->index))
+ {
+ edge e;
+
+ bitmap_set_bit (live_range, bb->index);
+ IOR_HARD_REG_SET (*btrs_live_in_range,
+ btrs_live[bb->index]);
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file,
+ "Adding block %d to live range\n", bb->index);
+ fprintf (rtl_dump_file,"Now live btrs are ");
+ dump_hard_reg_set (*btrs_live_in_range);
+ fprintf (rtl_dump_file, "\n");
+ }
+
+ for (e = bb->pred; e != NULL; e = e->pred_next)
+ {
+ basic_block pred = e->src;
+ if (!bitmap_bit_p (live_range, pred->index))
+ *tos++ = pred;
+ }
+ }
+ }
+
+ free (worklist);
+}
+
+/* Return the most desirable target register that is not in
+ the set USED_BTRS. */
+static int
+choose_btr (HARD_REG_SET used_btrs)
+{
+ int i;
+ GO_IF_HARD_REG_SUBSET (all_btrs, used_btrs, give_up);
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+#ifdef REG_ALLOC_ORDER
+ int regno = reg_alloc_order[i];
+#else
+ int regno = i;
+#endif
+ if (TEST_HARD_REG_BIT (all_btrs, regno)
+ && !TEST_HARD_REG_BIT (used_btrs, regno))
+ return regno;
+ }
+give_up:
+ return -1;
+}
+
+/* Calculate the set of basic blocks that contain the live range of
+ the def/use web DEF.
+ Also calculate the set of target registers that are live at time
+ in this live range, but ignore the live range represented by DEF
+ when calculating this set. */
+static void
+btr_def_live_range (btr_def def, HARD_REG_SET *btrs_live_in_range)
+{
+ if (!def->live_range)
+ {
+ btr_user user;
+
+ def->live_range = BITMAP_XMALLOC ();
+
+ bitmap_set_bit (def->live_range, def->bb->index);
+ COPY_HARD_REG_SET (*btrs_live_in_range, btrs_live[def->bb->index]);
+
+ for (user = def->uses; user != NULL; user = user->next)
+ augment_live_range (def->live_range, btrs_live_in_range,
+ def->bb, user->bb);
+ }
+ else
+ {
+ /* def->live_range is accurate, but we need to recompute
+ the set of target registers live over it, because migration
+ of other PT instructions may have affected it.
+ */
+ int bb;
+
+ CLEAR_HARD_REG_SET (*btrs_live_in_range);
+ EXECUTE_IF_SET_IN_BITMAP
+ (def->live_range, 0, bb,
+ {
+ IOR_HARD_REG_SET (*btrs_live_in_range,
+ btrs_live[bb]);
+ });
+ }
+ if (!def->other_btr_uses_before_def &&
+ !def->other_btr_uses_after_use)
+ CLEAR_HARD_REG_BIT (*btrs_live_in_range, def->btr);
+}
+
+/* Merge into the def/use web DEF any other def/use webs in the same
+ group that are dominated by DEF, provided that there is a target
+ register available to allocate to the merged web. */
+static void
+combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
+{
+ btr_def other_def;
+
+ for (other_def = def->group->members;
+ other_def != NULL;
+ other_def = other_def->next_this_group)
+ {
+ if (other_def != def
+ && other_def->uses != NULL
+ && ! other_def->has_ambiguous_use
+ && dominated_by_p (CDI_DOMINATORS, other_def->bb, def->bb))
+ {
+ /* def->bb dominates the other def, so def and other_def could
+ be combined. */
+ /* Merge their live ranges, and get the set of
+ target registers live over the merged range. */
+ int btr;
+ HARD_REG_SET combined_btrs_live;
+ bitmap combined_live_range = BITMAP_XMALLOC ();
+ btr_user user;
+
+ if (other_def->live_range == NULL)
+ {
+ HARD_REG_SET dummy_btrs_live_in_range;
+ btr_def_live_range (other_def, &dummy_btrs_live_in_range);
+ }
+ COPY_HARD_REG_SET (combined_btrs_live, *btrs_live_in_range);
+ bitmap_copy (combined_live_range, def->live_range);
+
+ for (user = other_def->uses; user != NULL; user = user->next)
+ augment_live_range (combined_live_range, &combined_btrs_live,
+ def->bb, user->bb);
+
+ btr = choose_btr (combined_btrs_live);
+ if (btr != -1)
+ {
+ /* We can combine them. */
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "Combining def in insn %d with def in insn %d\n",
+ INSN_UID (other_def->insn), INSN_UID (def->insn));
+
+ def->btr = btr;
+ user = other_def->uses;
+ while (user != NULL)
+ {
+ btr_user next = user->next;
+
+ user->next = def->uses;
+ def->uses = user;
+ user = next;
+ }
+ /* Combining def/use webs can make target registers live
+ after uses where they previously were not. This means
+ some REG_DEAD notes may no longer be correct. We could
+ be more precise about this if we looked at the combined
+ live range, but here I just delete any REG_DEAD notes
+ in case they are no longer correct. */
+ for (user = def->uses; user != NULL; user = user->next)
+ remove_note (user->insn,
+ find_regno_note (user->insn, REG_DEAD,
+ REGNO (user->use)));
+ clear_btr_from_live_range (other_def);
+ other_def->uses = NULL;
+ bitmap_copy (def->live_range, combined_live_range);
+ if (other_def->other_btr_uses_after_use)
+ def->other_btr_uses_after_use = 1;
+ COPY_HARD_REG_SET (*btrs_live_in_range, combined_btrs_live);
+
+ /* Delete the old target register initialization. */
+ delete_insn (other_def->insn);
+
+ }
+ BITMAP_XFREE (combined_live_range);
+ }
+ }
+}
+
+/* Move the definition DEF from its current position to basic
+ block NEW_DEF_BB, and modify it to use branch target register BTR.
+ Delete the old defining insn, and insert a new one in NEW_DEF_BB.
+ Update all reaching uses of DEF in the RTL to use BTR.
+ If this new position means that other defs in the
+ same group can be combined with DEF then combine them. */
+static void
+move_btr_def (basic_block new_def_bb, int btr, btr_def def, bitmap live_range,
+ HARD_REG_SET *btrs_live_in_range)
+{
+ /* We can move the instruction.
+ Set a target register in block NEW_DEF_BB to the value
+ needed for this target register definition.
+ Replace all uses of the old target register definition by
+ uses of the new definition. Delete the old definition. */
+ basic_block b = new_def_bb;
+ rtx insp = BB_HEAD (b);
+ rtx old_insn = def->insn;
+ rtx src;
+ rtx btr_rtx;
+ rtx new_insn;
+ enum machine_mode btr_mode;
+ btr_user user;
+ rtx set;
+
+ if (rtl_dump_file)
+ fprintf(rtl_dump_file, "migrating to basic block %d, using reg %d\n",
+ new_def_bb->index, btr);
+
+ clear_btr_from_live_range (def);
+ def->btr = btr;
+ def->bb = new_def_bb;
+ def->luid = 0;
+ def->cost = basic_block_freq (new_def_bb);
+ def->other_btr_uses_before_def = 0;
+ bitmap_copy (def->live_range, live_range);
+ combine_btr_defs (def, btrs_live_in_range);
+ btr = def->btr;
+ add_btr_to_live_range (def);
+ if (GET_CODE (insp) == CODE_LABEL)
+ insp = NEXT_INSN (insp);
+ /* N.B.: insp is expected to be NOTE_INSN_BASIC_BLOCK now. Some
+ optimizations can result in insp being both first and last insn of
+ its basic block. */
+ /* ?? some assertions to check that insp is sensible? */
+
+ set = single_set (old_insn);
+ src = SET_SRC (set);
+ btr_mode = GET_MODE (SET_DEST (set));
+ btr_rtx = gen_rtx (REG, btr_mode, btr);
+
+ new_insn = gen_move_insn (btr_rtx, src);
+
+ /* Insert target register initialization at head of basic block. */
+ def->insn = emit_insn_after (new_insn, insp);
+
+ regs_ever_live[btr] = 1;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "New pt is insn %d, inserted after insn %d\n",
+ INSN_UID (def->insn), INSN_UID (insp));
+
+ /* Delete the old target register initialization. */
+ delete_insn (old_insn);
+
+ /* Replace each use of the old target register by a use of the new target
+ register. */
+ for (user = def->uses; user != NULL; user = user->next)
+ {
+ /* Some extra work here to ensure consistent modes, because
+ it seems that a target register REG rtx can be given a different
+ mode depending on the context (surely that should not be
+ the case?). */
+ rtx replacement_rtx;
+ if (GET_MODE (user->use) == GET_MODE (btr_rtx)
+ || GET_MODE (user->use) == VOIDmode)
+ replacement_rtx = btr_rtx;
+ else
+ replacement_rtx = gen_rtx (REG, GET_MODE (user->use), btr);
+ replace_rtx (user->insn, user->use, replacement_rtx);
+ user->use = replacement_rtx;
+ }
+}
+
+/* We anticipate intra-block scheduling to be done. See if INSN could move
+ up within BB by N_INSNS. */
+static int
+can_move_up (basic_block bb, rtx insn, int n_insns)
+{
+ while (insn != BB_HEAD (bb) && n_insns > 0)
+ {
+ insn = PREV_INSN (insn);
+ /* ??? What if we have an anti-dependency that actually prevents the
+ scheduler from doing the move? We'd like to re-allocate the register,
+ but not necessarily put the load into another basic block. */
+ if (INSN_P (insn))
+ n_insns--;
+ }
+ return n_insns <= 0;
+}
+
+/* Attempt to migrate the target register definition DEF to an
+ earlier point in the flowgraph.
+
+ It is a precondition of this function that DEF is migratable:
+ i.e. it has a constant source, and all uses are unambiguous.
+
+ Only migrations that reduce the cost of DEF will be made.
+ MIN_COST is the lower bound on the cost of the DEF after migration.
+ If we migrate DEF so that its cost falls below MIN_COST,
+ then we do not attempt to migrate further. The idea is that
+ we migrate definitions in a priority order based on their cost,
+ when the cost of this definition falls below MIN_COST, then
+ there is another definition with cost == MIN_COST which now
+ has a higher priority than this definition.
+
+ Return nonzero if there may be benefit from attempting to
+ migrate this DEF further (i.e. we have reduced the cost below
+ MIN_COST, but we may be able to reduce it further).
+ Return zero if no further migration is possible. */
+static int
+migrate_btr_def (btr_def def, int min_cost)
+{
+ bitmap live_range;
+ HARD_REG_SET btrs_live_in_range;
+ int btr_used_near_def = 0;
+ int def_basic_block_freq;
+ basic_block try;
+ int give_up = 0;
+ int def_moved = 0;
+ btr_user user;
+ int def_latency = 1;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "Attempting to migrate pt from insn %d (cost = %d, min_cost = %d) ... ",
+ INSN_UID (def->insn), def->cost, min_cost);
+
+ if (!def->group || def->has_ambiguous_use)
+ /* These defs are not migratable. */
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "it's not migratable\n");
+ return 0;
+ }
+
+ if (!def->uses)
+ /* We have combined this def with another in the same group, so
+ no need to consider it further.
+ */
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "it's already combined with another pt\n");
+ return 0;
+ }
+
+ btr_def_live_range (def, &btrs_live_in_range);
+ live_range = BITMAP_XMALLOC ();
+ bitmap_copy (live_range, def->live_range);
+
+#ifdef INSN_SCHEDULING
+ if ((*targetm.sched.use_dfa_pipeline_interface) ())
+ def_latency = insn_default_latency (def->insn);
+ else
+ def_latency = result_ready_cost (def->insn);
+#endif
+
+ def_latency *= issue_rate;
+
+ for (user = def->uses; user != NULL; user = user->next)
+ {
+ if (user->bb == def->bb
+ && user->luid > def->luid
+ && (def->luid + def_latency) > user->luid
+ && ! can_move_up (def->bb, def->insn,
+ (def->luid + def_latency) - user->luid))
+ {
+ btr_used_near_def = 1;
+ break;
+ }
+ }
+
+ def_basic_block_freq = basic_block_freq (def->bb);
+
+ for (try = get_immediate_dominator (CDI_DOMINATORS, def->bb);
+ !give_up && try && try != ENTRY_BLOCK_PTR && def->cost >= min_cost;
+ try = get_immediate_dominator (CDI_DOMINATORS, try))
+ {
+ /* Try to move the instruction that sets the target register into
+ basic block TRY. */
+ int try_freq = basic_block_freq (try);
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "trying block %d ...", try->index);
+
+ if (try_freq < def_basic_block_freq
+ || (try_freq == def_basic_block_freq && btr_used_near_def))
+ {
+ int btr;
+ augment_live_range (live_range, &btrs_live_in_range, def->bb, try);
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, "Now btrs live in range are: ");
+ dump_hard_reg_set (btrs_live_in_range);
+ fprintf (rtl_dump_file, "\n");
+ }
+ btr = choose_btr (btrs_live_in_range);
+ if (btr != -1)
+ {
+ move_btr_def (try, btr, def, live_range, &btrs_live_in_range);
+ bitmap_copy(live_range, def->live_range);
+ btr_used_near_def = 0;
+ def_moved = 1;
+ def_basic_block_freq = basic_block_freq (def->bb);
+ }
+ else
+ {
+ /* There are no free target registers available to move
+ this far forward, so give up */
+ give_up = 1;
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "giving up because there are no free target registers\n");
+ }
+
+ }
+ }
+ if (!def_moved)
+ {
+ give_up = 1;
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "failed to move\n");
+ }
+ BITMAP_XFREE (live_range);
+ return !give_up;
+}
+
+/* Attempt to move instructions that set target registers earlier
+ in the flowgraph, away from their corresponding uses. */
+static void
+migrate_btr_defs (enum reg_class btr_class, int allow_callee_save)
+{
+ fibheap_t all_btr_defs = fibheap_new ();
+ int reg;
+
+ gcc_obstack_init (&migrate_btrl_obstack);
+ if (rtl_dump_file)
+ {
+ int i;
+
+ for (i = 0; i < n_basic_blocks; i++)
+ {
+ basic_block bb = BASIC_BLOCK (i);
+ fprintf(rtl_dump_file,
+ "Basic block %d: count = " HOST_WIDEST_INT_PRINT_DEC
+ " loop-depth = %d idom = %d\n",
+ i, (HOST_WIDEST_INT) bb->count, bb->loop_depth,
+ get_immediate_dominator (CDI_DOMINATORS, bb)->index);
+ }
+ }
+
+ CLEAR_HARD_REG_SET (all_btrs);
+ for (first_btr = -1, reg = 0; reg < FIRST_PSEUDO_REGISTER; reg++)
+ if (TEST_HARD_REG_BIT (reg_class_contents[(int) btr_class], reg)
+ && (allow_callee_save || call_used_regs[reg] || regs_ever_live[reg]))
+ {
+ SET_HARD_REG_BIT (all_btrs, reg);
+ last_btr = reg;
+ if (first_btr < 0)
+ first_btr = reg;
+ }
+
+ btrs_live = xcalloc (n_basic_blocks, sizeof (HARD_REG_SET));
+
+ build_btr_def_use_webs (all_btr_defs);
+
+ while (!fibheap_empty (all_btr_defs))
+ {
+ btr_def def =
+ (btr_def) fibheap_extract_min (all_btr_defs);
+ int min_cost = -fibheap_min_key (all_btr_defs);
+ if (migrate_btr_def (def, min_cost))
+ {
+ fibheap_insert (all_btr_defs, -def->cost, (void *) def);
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file,
+ "Putting insn %d back on queue with priority %d\n",
+ INSN_UID (def->insn), def->cost);
+ }
+ }
+ else
+ {
+ if (def->live_range)
+ BITMAP_XFREE (def->live_range);
+ }
+ }
+
+ free (btrs_live);
+ obstack_free (&migrate_btrl_obstack, NULL);
+ fibheap_delete (all_btr_defs);
+}
+
+void
+branch_target_load_optimize (rtx insns, bool after_prologue_epilogue_gen)
+{
+ enum reg_class class = (*targetm.branch_target_register_class) ();
+ if (class != NO_REGS)
+ {
+ /* Initialize issue_rate. */
+ if (targetm.sched.issue_rate)
+ issue_rate = (*targetm.sched.issue_rate) ();
+ else
+ issue_rate = 1;
+
+ /* Build the CFG for migrate_btr_defs. */
+#if 1
+ /* This may or may not be needed, depending on where we
+ run this phase. */
+ cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
+#endif
+
+ life_analysis (insns, NULL, 0);
+
+ /* Dominator info is also needed for migrate_btr_def. */
+ calculate_dominance_info (CDI_DOMINATORS);
+ migrate_btr_defs (class,
+ ((*targetm.branch_target_register_callee_saved)
+ (after_prologue_epilogue_gen)));
+
+ free_dominance_info (CDI_DOMINATORS);
+
+ update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
+ PROP_DEATH_NOTES | PROP_REG_INFO);
+ }
+}
diff --git a/contrib/gcc/builtin-attrs.def b/contrib/gcc/builtin-attrs.def
index 7bdbd6280865..92fe65e1e0df 100644
--- a/contrib/gcc/builtin-attrs.def
+++ b/contrib/gcc/builtin-attrs.def
@@ -41,23 +41,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
DEF_ATTR_TREE_LIST (ENUM, PURPOSE, VALUE, CHAIN)
Constructs a TREE_LIST with given PURPOSE, VALUE and CHAIN (given
- as previous ENUM names).
-
- DEF_FN_ATTR (NAME, ATTRS, PREDICATE)
-
- Specifies that the function with name NAME (a previous ENUM for an
- IDENTIFIER_NODE) has attributes ATTRS (a previous ENUM) if
- PREDICATE is true. */
+ as previous ENUM names). */
DEF_ATTR_NULL_TREE (ATTR_NULL)
-/* Note that below we must avoid whitespace in arguments of CONCAT*. */
-
/* Construct a tree for a given integer and a list containing it. */
#define DEF_ATTR_FOR_INT(VALUE) \
- DEF_ATTR_INT (CONCAT2 (ATTR_,VALUE), VALUE) \
- DEF_ATTR_TREE_LIST (CONCAT2 (ATTR_LIST_,VALUE), ATTR_NULL, \
- CONCAT2 (ATTR_,VALUE), ATTR_NULL)
+ DEF_ATTR_INT (ATTR_##VALUE, VALUE) \
+ DEF_ATTR_TREE_LIST (ATTR_LIST_##VALUE, ATTR_NULL, \
+ ATTR_##VALUE, ATTR_NULL)
DEF_ATTR_FOR_INT (0)
DEF_ATTR_FOR_INT (1)
DEF_ATTR_FOR_INT (2)
@@ -67,8 +59,8 @@ DEF_ATTR_FOR_INT (4)
/* Construct a tree for a list of two integers. */
#define DEF_LIST_INT_INT(VALUE1, VALUE2) \
- DEF_ATTR_TREE_LIST (CONCAT4 (ATTR_LIST_,VALUE1,_,VALUE2), ATTR_NULL, \
- CONCAT2 (ATTR_,VALUE1), CONCAT2 (ATTR_LIST_,VALUE2))
+ DEF_ATTR_TREE_LIST (ATTR_LIST_##VALUE1##_##VALUE2, ATTR_NULL, \
+ ATTR_##VALUE1, ATTR_LIST_##VALUE2)
DEF_LIST_INT_INT (1,0)
DEF_LIST_INT_INT (1,2)
DEF_LIST_INT_INT (2,0)
@@ -86,6 +78,10 @@ DEF_ATTR_IDENT (ATTR_NONNULL, "nonnull")
DEF_ATTR_IDENT (ATTR_NORETURN, "noreturn")
DEF_ATTR_IDENT (ATTR_NOTHROW, "nothrow")
DEF_ATTR_IDENT (ATTR_PRINTF, "printf")
+DEF_ATTR_IDENT (ATTR_ASM_FPRINTF, "asm_fprintf")
+DEF_ATTR_IDENT (ATTR_GCC_DIAG, "gcc_diag")
+DEF_ATTR_IDENT (ATTR_GCC_CDIAG, "gcc_cdiag")
+DEF_ATTR_IDENT (ATTR_GCC_CXXDIAG, "gcc_cxxdiag")
DEF_ATTR_IDENT (ATTR_PURE, "pure")
DEF_ATTR_IDENT (ATTR_SCANF, "scanf")
DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon")
@@ -102,19 +98,37 @@ DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LIST, ATTR_NORETURN, \
DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_LIST, ATTR_MALLOC, \
ATTR_NULL, ATTR_NOTHROW_LIST)
-DEF_ATTR_TREE_LIST (ATTR_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, \
+DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1, ATTR_NONNULL, ATTR_LIST_1, \
ATTR_NOTHROW_LIST)
-DEF_ATTR_TREE_LIST (ATTR_NONNULL_2, ATTR_NONNULL, ATTR_LIST_2, \
+DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_2, ATTR_NONNULL, ATTR_LIST_2, \
ATTR_NOTHROW_LIST)
-DEF_ATTR_TREE_LIST (ATTR_NONNULL_3, ATTR_NONNULL, ATTR_LIST_3, \
+DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_3, ATTR_NONNULL, ATTR_LIST_3, \
ATTR_NOTHROW_LIST)
+/* Nothrow functions whose first and second parameters are nonnull pointers. */
+DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1_2, ATTR_NONNULL, ATTR_LIST_2, \
+ ATTR_NOTHROW_NONNULL_1)
+/* Nothrow functions whose first and fourth parameters are nonnull pointers. */
+DEF_ATTR_TREE_LIST (ATTR_NOTHROW_NONNULL_1_4, ATTR_NONNULL, ATTR_LIST_4, \
+ ATTR_NOTHROW_NONNULL_1)
+/* Nothrow const functions whose first parameter is a nonnull pointer. */
+DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_NONNULL_1, ATTR_CONST, ATTR_NULL, \
+ ATTR_NOTHROW_NONNULL_1)
+/* Nothrow pure functions whose first parameter is a nonnull pointer. */
+DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL_1, ATTR_PURE, ATTR_NULL, \
+ ATTR_NOTHROW_NONNULL_1)
+/* Nothrow pure functions whose first and second parameters are nonnull pointers. */
+DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NONNULL_1_2, ATTR_PURE, ATTR_NULL, \
+ ATTR_NOTHROW_NONNULL_1_2)
+/* Nothrow malloc functions whose first parameter is a nonnull pointer. */
+DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_NONNULL_1, ATTR_MALLOC, ATTR_NULL, \
+ ATTR_NOTHROW_NONNULL_1)
/* Construct a tree for a format attribute. */
#define DEF_FORMAT_ATTRIBUTE(TYPE, FA, VALUES) \
- DEF_ATTR_TREE_LIST (CONCAT4 (ATTR_,TYPE,_,VALUES), ATTR_NULL, \
- CONCAT2 (ATTR_,TYPE), CONCAT2 (ATTR_LIST_,VALUES)) \
- DEF_ATTR_TREE_LIST (CONCAT4 (ATTR_FORMAT_,TYPE,_,VALUES), ATTR_FORMAT, \
- CONCAT4 (ATTR_,TYPE,_,VALUES), CONCAT2 (ATTR_NONNULL_,FA))
+ DEF_ATTR_TREE_LIST (ATTR_##TYPE##_##VALUES, ATTR_NULL, \
+ ATTR_##TYPE, ATTR_LIST_##VALUES) \
+ DEF_ATTR_TREE_LIST (ATTR_FORMAT_##TYPE##_##VALUES, ATTR_FORMAT, \
+ ATTR_##TYPE##_##VALUES, ATTR_NOTHROW_NONNULL_##FA)
DEF_FORMAT_ATTRIBUTE(PRINTF,1,1_0)
DEF_FORMAT_ATTRIBUTE(PRINTF,1,1_2)
DEF_FORMAT_ATTRIBUTE(PRINTF,2,2_0)
@@ -131,49 +145,9 @@ DEF_FORMAT_ATTRIBUTE(STRFMON,3,3_4)
/* Construct a tree for a format_arg attribute. */
#define DEF_FORMAT_ARG_ATTRIBUTE(FA) \
- DEF_ATTR_TREE_LIST (CONCAT2 (ATTR_FORMAT_ARG_,FA), ATTR_FORMAT_ARG, \
- CONCAT2 (ATTR_LIST_,FA), CONCAT2 (ATTR_NONNULL_,FA))
+ DEF_ATTR_TREE_LIST (ATTR_FORMAT_ARG_##FA, ATTR_FORMAT_ARG, \
+ ATTR_LIST_##FA, ATTR_NOTHROW_NONNULL_##FA)
DEF_FORMAT_ARG_ATTRIBUTE(1)
DEF_FORMAT_ARG_ATTRIBUTE(2)
#undef DEF_FORMAT_ARG_ATTRIBUTE
-/* Define an attribute for a function, along with the IDENTIFIER_NODE. */
-#define DEF_FN_ATTR_IDENT(NAME, ATTRS, PREDICATE) \
- DEF_ATTR_IDENT (CONCAT2(ATTR_,NAME), STRINGX(NAME)) \
- DEF_FN_ATTR (CONCAT2(ATTR_,NAME), ATTRS, PREDICATE)
-
-/* The ISO C functions are always checked (whether <stdio.h> is
- included or not), since it is common to call printf without
- including <stdio.h>. There shouldn't be a problem with this,
- since ISO C reserves these function names whether you include the
- header file or not. In any case, the checking is harmless. With
- -ffreestanding, these default attributes are disabled, and must be
- specified manually if desired. */
-
-/* Functions from ISO/IEC 9899:1990. */
-#define DEF_C89_ATTR(NAME, ATTRS) DEF_FN_ATTR_IDENT (NAME, ATTRS, flag_hosted)
-DEF_C89_ATTR (fscanf, ATTR_FORMAT_SCANF_2_3)
-DEF_C89_ATTR (vfprintf, ATTR_FORMAT_PRINTF_2_0)
-DEF_C89_ATTR (strftime, ATTR_FORMAT_STRFTIME_3_0)
-#undef DEF_C89_ATTR
-
-/* ISO C99 adds the snprintf and vscanf family functions. */
-#define DEF_C99_ATTR(NAME, ATTRS) \
- DEF_FN_ATTR_IDENT (NAME, ATTRS, \
- (flag_hosted \
- && (flag_isoc99 || flag_noniso_default_format_attributes)))
-DEF_C99_ATTR (vfscanf, ATTR_FORMAT_SCANF_2_0)
-#undef DEF_C99_ATTR
-
-/* Functions not in any version of ISO C. */
-#define DEF_EXT_ATTR(NAME, ATTRS) \
- DEF_FN_ATTR_IDENT (NAME, ATTRS, \
- flag_hosted && flag_noniso_default_format_attributes)
-/* Uniforum/GNU gettext functions. */
-DEF_EXT_ATTR (gettext, ATTR_FORMAT_ARG_1)
-DEF_EXT_ATTR (dgettext, ATTR_FORMAT_ARG_2)
-DEF_EXT_ATTR (dcgettext, ATTR_FORMAT_ARG_2)
-/* X/Open strfmon function. */
-DEF_EXT_ATTR (strfmon, ATTR_FORMAT_STRFMON_3_4)
-#undef DEF_EXT_ATTR
-#undef DEF_FN_ATTR_IDENT
diff --git a/contrib/gcc/builtin-types.def b/contrib/gcc/builtin-types.def
index d5c39b4b8252..85b30b98caa1 100644
--- a/contrib/gcc/builtin-types.def
+++ b/contrib/gcc/builtin-types.def
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -64,18 +64,24 @@ DEF_PRIMITIVE_TYPE (BT_INT, integer_type_node)
DEF_PRIMITIVE_TYPE (BT_UNSIGNED, unsigned_type_node)
DEF_PRIMITIVE_TYPE (BT_LONG, long_integer_type_node)
DEF_PRIMITIVE_TYPE (BT_LONGLONG, long_long_integer_type_node)
+DEF_PRIMITIVE_TYPE (BT_WORD, (*lang_hooks.types.type_for_mode) (word_mode, 0))
DEF_PRIMITIVE_TYPE (BT_FLOAT, float_type_node)
DEF_PRIMITIVE_TYPE (BT_INTMAX, intmax_type_node)
DEF_PRIMITIVE_TYPE (BT_DOUBLE, double_type_node)
-DEF_PRIMITIVE_TYPE (BT_LONG_DOUBLE, long_double_type_node)
+DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE, long_double_type_node)
DEF_PRIMITIVE_TYPE (BT_COMPLEX_FLOAT, complex_float_type_node)
DEF_PRIMITIVE_TYPE (BT_COMPLEX_DOUBLE, complex_double_type_node)
-DEF_PRIMITIVE_TYPE (BT_COMPLEX_LONG_DOUBLE, complex_long_double_type_node)
+DEF_PRIMITIVE_TYPE (BT_COMPLEX_LONGDOUBLE, complex_long_double_type_node)
DEF_PRIMITIVE_TYPE (BT_PTR, ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_CONST_PTR, const_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_PTRMODE, (*lang_hooks.types.type_for_mode)(ptr_mode, 0))
+DEF_PRIMITIVE_TYPE (BT_INT_PTR, integer_ptr_type_node)
+DEF_PRIMITIVE_TYPE (BT_FLOAT_PTR, float_ptr_type_node)
+DEF_PRIMITIVE_TYPE (BT_DOUBLE_PTR, double_ptr_type_node)
+DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE_PTR, long_double_ptr_type_node)
DEF_PRIMITIVE_TYPE (BT_SIZE, size_type_node)
+DEF_PRIMITIVE_TYPE (BT_SSIZE, signed_size_type_node)
DEF_PRIMITIVE_TYPE (BT_STRING, string_type_node)
DEF_PRIMITIVE_TYPE (BT_CONST_STRING, const_string_type_node)
@@ -87,31 +93,45 @@ DEF_FUNCTION_TYPE_0 (BT_FN_PTR, BT_PTR)
DEF_FUNCTION_TYPE_0 (BT_FN_UNSIGNED, BT_UNSIGNED)
DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT, BT_FLOAT)
DEF_FUNCTION_TYPE_0 (BT_FN_DOUBLE, BT_DOUBLE)
-DEF_FUNCTION_TYPE_0 (BT_FN_LONG_DOUBLE, BT_LONG_DOUBLE)
+/* For "long double" we use LONGDOUBLE (not LONG_DOUBLE) to
+ distinguish it from two types in sequence, "long" followed by
+ "double". */
+DEF_FUNCTION_TYPE_0 (BT_FN_LONGDOUBLE, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_LONG_LONG, BT_LONG, BT_LONG)
DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_LONGLONG, BT_LONGLONG, BT_LONGLONG)
DEF_FUNCTION_TYPE_1 (BT_FN_INTMAX_INTMAX, BT_INTMAX, BT_INTMAX)
DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_FLOAT, BT_FLOAT, BT_FLOAT)
DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_DOUBLE, BT_DOUBLE, BT_DOUBLE)
-DEF_FUNCTION_TYPE_1 (BT_FN_LONG_DOUBLE_LONG_DOUBLE,
- BT_LONG_DOUBLE, BT_LONG_DOUBLE)
+DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_LONGDOUBLE,
+ BT_LONGDOUBLE, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT,
BT_COMPLEX_FLOAT, BT_COMPLEX_FLOAT)
DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
BT_COMPLEX_DOUBLE, BT_COMPLEX_DOUBLE)
-DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_LONG_DOUBLE_COMPLEX_LONG_DOUBLE,
- BT_COMPLEX_LONG_DOUBLE, BT_COMPLEX_LONG_DOUBLE)
+DEF_FUNCTION_TYPE_1 (BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE,
+ BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_COMPLEX_FLOAT,
BT_FLOAT, BT_COMPLEX_FLOAT)
DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_COMPLEX_DOUBLE,
BT_DOUBLE, BT_COMPLEX_DOUBLE)
-DEF_FUNCTION_TYPE_1 (BT_FN_LONG_DOUBLE_COMPLEX_LONG_DOUBLE,
- BT_LONG_DOUBLE, BT_COMPLEX_LONG_DOUBLE)
+DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE,
+ BT_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_PTR_UNSIGNED, BT_PTR, BT_UNSIGNED)
DEF_FUNCTION_TYPE_1 (BT_FN_PTR_SIZE, BT_PTR, BT_SIZE)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_INT, BT_INT, BT_INT)
+DEF_FUNCTION_TYPE_1 (BT_FN_INT_LONG, BT_INT, BT_LONG)
+DEF_FUNCTION_TYPE_1 (BT_FN_INT_LONGLONG, BT_INT, BT_LONGLONG)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_PTR, BT_INT, BT_PTR)
+DEF_FUNCTION_TYPE_1 (BT_FN_INT_FLOAT, BT_INT, BT_FLOAT)
+DEF_FUNCTION_TYPE_1 (BT_FN_INT_DOUBLE, BT_INT, BT_DOUBLE)
+DEF_FUNCTION_TYPE_1 (BT_FN_INT_LONGDOUBLE, BT_INT, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_1 (BT_FN_LONG_FLOAT, BT_LONG, BT_FLOAT)
+DEF_FUNCTION_TYPE_1 (BT_FN_LONG_DOUBLE, BT_LONG, BT_DOUBLE)
+DEF_FUNCTION_TYPE_1 (BT_FN_LONG_LONGDOUBLE, BT_LONG, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_FLOAT, BT_LONGLONG, BT_FLOAT)
+DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_DOUBLE, BT_LONGLONG, BT_DOUBLE)
+DEF_FUNCTION_TYPE_1 (BT_FN_LONGLONG_LONGDOUBLE, BT_LONGLONG, BT_LONGDOUBLE)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_PTR, BT_VOID, BT_PTR)
DEF_FUNCTION_TYPE_1 (BT_FN_SIZE_CONST_STRING, BT_SIZE, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_INT_CONST_STRING, BT_INT, BT_CONST_STRING)
@@ -120,8 +140,10 @@ DEF_FUNCTION_TYPE_1 (BT_FN_VOID_VALIST_REF, BT_VOID, BT_VALIST_REF)
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_INT, BT_VOID, BT_INT)
DEF_FUNCTION_TYPE_1 (BT_FN_FLOAT_CONST_STRING, BT_FLOAT, BT_CONST_STRING)
DEF_FUNCTION_TYPE_1 (BT_FN_DOUBLE_CONST_STRING, BT_DOUBLE, BT_CONST_STRING)
-DEF_FUNCTION_TYPE_1 (BT_FN_LONG_DOUBLE_CONST_STRING,
- BT_LONG_DOUBLE, BT_CONST_STRING)
+DEF_FUNCTION_TYPE_1 (BT_FN_LONGDOUBLE_CONST_STRING,
+ BT_LONGDOUBLE, BT_CONST_STRING)
+DEF_FUNCTION_TYPE_1 (BT_FN_STRING_CONST_STRING, BT_STRING, BT_CONST_STRING)
+DEF_FUNCTION_TYPE_1 (BT_FN_WORD_PTR, BT_WORD, BT_PTR)
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_INT, BT_VOID, BT_PTR, BT_INT)
DEF_FUNCTION_TYPE_2 (BT_FN_STRING_STRING_CONST_STRING,
@@ -148,8 +170,56 @@ DEF_FUNCTION_TYPE_2 (BT_FN_INT_PTR_CONST_STRING,
BT_INT, BT_PTR, BT_CONST_STRING)
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_SIZE,
BT_VOID, BT_PTR, BT_SIZE)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_FLOAT,
+ BT_FLOAT, BT_FLOAT, BT_FLOAT)
+DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_DOUBLE,
+ BT_DOUBLE, BT_DOUBLE, BT_DOUBLE)
+DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE,
+ BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_FLOATPTR,
+ BT_FLOAT, BT_FLOAT, BT_FLOAT_PTR)
+DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_DOUBLEPTR,
+ BT_DOUBLE, BT_DOUBLE, BT_DOUBLE_PTR)
+DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLEPTR,
+ BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE_PTR)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_LONGDOUBLE,
+ BT_FLOAT, BT_FLOAT, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_LONGDOUBLE,
+ BT_DOUBLE, BT_DOUBLE, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_INT,
+ BT_FLOAT, BT_FLOAT, BT_INT)
+DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_INT,
+ BT_DOUBLE, BT_DOUBLE, BT_INT)
+DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_INT,
+ BT_LONGDOUBLE, BT_LONGDOUBLE, BT_INT)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_INTPTR,
+ BT_FLOAT, BT_FLOAT, BT_INT_PTR)
+DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_INTPTR,
+ BT_DOUBLE, BT_DOUBLE, BT_INT_PTR)
+DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR,
+ BT_LONGDOUBLE, BT_LONGDOUBLE, BT_INT_PTR)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_INT_FLOAT,
+ BT_FLOAT, BT_INT, BT_FLOAT)
+DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_INT_DOUBLE,
+ BT_DOUBLE, BT_INT, BT_DOUBLE)
+DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_INT_LONGDOUBLE,
+ BT_LONGDOUBLE, BT_INT, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_LONG,
+ BT_FLOAT, BT_FLOAT, BT_LONG)
+DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_LONG,
+ BT_DOUBLE, BT_DOUBLE, BT_LONG)
+DEF_FUNCTION_TYPE_2 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONG,
+ BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONG)
DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_STRING_VALIST_ARG,
BT_INT, BT_CONST_STRING, BT_VALIST_ARG)
+DEF_FUNCTION_TYPE_2 (BT_FN_PTR_SIZE_SIZE,
+ BT_PTR, BT_SIZE, BT_SIZE)
+DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT,
+ BT_COMPLEX_FLOAT, BT_COMPLEX_FLOAT, BT_COMPLEX_FLOAT)
+DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
+ BT_COMPLEX_DOUBLE, BT_COMPLEX_DOUBLE, BT_COMPLEX_DOUBLE)
+DEF_FUNCTION_TYPE_2 (BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE,
+ BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE, BT_COMPLEX_LONGDOUBLE)
DEF_FUNCTION_TYPE_3 (BT_FN_STRING_STRING_CONST_STRING_SIZE,
BT_STRING, BT_STRING, BT_CONST_STRING, BT_SIZE)
@@ -163,15 +233,41 @@ DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_INT_SIZE,
BT_PTR, BT_PTR, BT_INT, BT_SIZE)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_INT_INT,
BT_VOID, BT_PTR, BT_INT, BT_INT)
+DEF_FUNCTION_TYPE_3 (BT_FN_VOID_CONST_PTR_PTR_SIZE,
+ BT_VOID, BT_CONST_PTR, BT_PTR, BT_SIZE)
DEF_FUNCTION_TYPE_3 (BT_FN_INT_STRING_CONST_STRING_VALIST_ARG,
BT_INT, BT_STRING, BT_CONST_STRING, BT_VALIST_ARG)
DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG,
BT_INT, BT_CONST_STRING, BT_CONST_STRING, BT_VALIST_ARG)
+DEF_FUNCTION_TYPE_3 (BT_FN_INT_PTR_CONST_STRING_VALIST_ARG,
+ BT_INT, BT_PTR, BT_CONST_STRING, BT_VALIST_ARG)
+DEF_FUNCTION_TYPE_3 (BT_FN_STRING_CONST_STRING_CONST_STRING_INT,
+ BT_STRING, BT_CONST_STRING, BT_CONST_STRING, BT_INT)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT_FLOAT_FLOAT_FLOAT,
+ BT_FLOAT, BT_FLOAT, BT_FLOAT, BT_FLOAT)
+DEF_FUNCTION_TYPE_3 (BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE,
+ BT_DOUBLE, BT_DOUBLE, BT_DOUBLE, BT_DOUBLE)
+DEF_FUNCTION_TYPE_3 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE,
+ BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE)
+DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT_FLOAT_FLOAT_INTPTR,
+ BT_FLOAT, BT_FLOAT, BT_FLOAT, BT_INT_PTR)
+DEF_FUNCTION_TYPE_3 (BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR,
+ BT_DOUBLE, BT_DOUBLE, BT_DOUBLE, BT_INT_PTR)
+DEF_FUNCTION_TYPE_3 (BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_INTPTR,
+ BT_LONGDOUBLE, BT_LONGDOUBLE, BT_LONGDOUBLE, BT_INT_PTR)
+DEF_FUNCTION_TYPE_3 (BT_FN_VOID_FLOAT_FLOATPTR_FLOATPTR,
+ BT_VOID, BT_FLOAT, BT_FLOAT_PTR, BT_FLOAT_PTR)
+DEF_FUNCTION_TYPE_3 (BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR,
+ BT_VOID, BT_DOUBLE, BT_DOUBLE_PTR, BT_DOUBLE_PTR)
+DEF_FUNCTION_TYPE_3 (BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR,
+ BT_VOID, BT_LONGDOUBLE, BT_LONGDOUBLE_PTR, BT_LONGDOUBLE_PTR)
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR,
BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_PTR)
DEF_FUNCTION_TYPE_4 (BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG,
BT_INT, BT_STRING, BT_SIZE, BT_CONST_STRING, BT_VALIST_ARG)
+DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR,
+ BT_SIZE, BT_STRING, BT_SIZE, BT_CONST_STRING, BT_CONST_PTR)
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
DEF_FUNCTION_TYPE_VAR_0 (BT_FN_INT_VAR, BT_INT)
@@ -193,6 +289,8 @@ DEF_FUNCTION_TYPE_VAR_2 (BT_FN_INT_CONST_STRING_CONST_STRING_VAR,
DEF_FUNCTION_TYPE_VAR_3 (BT_FN_INT_STRING_SIZE_CONST_STRING_VAR,
BT_INT, BT_STRING, BT_SIZE, BT_CONST_STRING)
+DEF_FUNCTION_TYPE_VAR_3 (BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR,
+ BT_SSIZE, BT_STRING, BT_SIZE, BT_CONST_STRING)
DEF_POINTER_TYPE (BT_PTR_FN_VOID_VAR, BT_FN_VOID_VAR)
DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE,
diff --git a/contrib/gcc/builtins.c b/contrib/gcc/builtins.c
index d0882740e385..dadb6cd41a0e 100644
--- a/contrib/gcc/builtins.c
+++ b/contrib/gcc/builtins.c
@@ -1,6 +1,6 @@
/* Expand builtin functions.
- Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "machmode.h"
#include "real.h"
#include "rtl.h"
@@ -62,7 +64,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
const char *const built_in_class_names[4]
= {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
-#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT) STRINGX(X),
+#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) #X,
const char *const built_in_names[(int) END_BUILTINS] =
{
#include "builtins.def"
@@ -72,86 +74,97 @@ const char *const built_in_names[(int) END_BUILTINS] =
/* Setup an array of _DECL trees, make sure each element is
initialized to NULL_TREE. */
tree built_in_decls[(int) END_BUILTINS];
-
-static int get_pointer_alignment PARAMS ((tree, unsigned int));
-static tree c_strlen PARAMS ((tree));
-static const char *c_getstr PARAMS ((tree));
-static rtx c_readstr PARAMS ((const char *,
- enum machine_mode));
-static int target_char_cast PARAMS ((tree, char *));
-static rtx get_memory_rtx PARAMS ((tree));
-static int apply_args_size PARAMS ((void));
-static int apply_result_size PARAMS ((void));
+/* Declarations used when constructing the builtin implicitly in the compiler.
+ It may be NULL_TREE when this is invalid (for instance runtime is not
+ required to implement the function call in all cases. */
+tree implicit_built_in_decls[(int) END_BUILTINS];
+
+static int get_pointer_alignment (tree, unsigned int);
+static tree c_strlen (tree, int);
+static const char *c_getstr (tree);
+static rtx c_readstr (const char *, enum machine_mode);
+static int target_char_cast (tree, char *);
+static rtx get_memory_rtx (tree);
+static tree build_string_literal (int, const char *);
+static int apply_args_size (void);
+static int apply_result_size (void);
#if defined (HAVE_untyped_call) || defined (HAVE_untyped_return)
-static rtx result_vector PARAMS ((int, rtx));
+static rtx result_vector (int, rtx);
#endif
-static rtx expand_builtin_setjmp PARAMS ((tree, rtx));
-static void expand_builtin_prefetch PARAMS ((tree));
-static rtx expand_builtin_apply_args PARAMS ((void));
-static rtx expand_builtin_apply_args_1 PARAMS ((void));
-static rtx expand_builtin_apply PARAMS ((rtx, rtx, rtx));
-static void expand_builtin_return PARAMS ((rtx));
-static enum type_class type_to_class PARAMS ((tree));
-static rtx expand_builtin_classify_type PARAMS ((tree));
-static rtx expand_builtin_mathfn PARAMS ((tree, rtx, rtx));
-static rtx expand_builtin_constant_p PARAMS ((tree));
-static rtx expand_builtin_args_info PARAMS ((tree));
-static rtx expand_builtin_next_arg PARAMS ((tree));
-static rtx expand_builtin_va_start PARAMS ((tree));
-static rtx expand_builtin_va_end PARAMS ((tree));
-static rtx expand_builtin_va_copy PARAMS ((tree));
-static rtx expand_builtin_memcmp PARAMS ((tree, tree, rtx,
- enum machine_mode));
-static rtx expand_builtin_strcmp PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx expand_builtin_strncmp PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx builtin_memcpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
- enum machine_mode));
-static rtx expand_builtin_strcat PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx expand_builtin_strncat PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx expand_builtin_strspn PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx expand_builtin_strcspn PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx expand_builtin_memcpy PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx expand_builtin_strcpy PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx builtin_strncpy_read_str PARAMS ((PTR, HOST_WIDE_INT,
- enum machine_mode));
-static rtx expand_builtin_strncpy PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx builtin_memset_read_str PARAMS ((PTR, HOST_WIDE_INT,
- enum machine_mode));
-static rtx builtin_memset_gen_str PARAMS ((PTR, HOST_WIDE_INT,
- enum machine_mode));
-static rtx expand_builtin_memset PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx expand_builtin_bzero PARAMS ((tree));
-static rtx expand_builtin_strlen PARAMS ((tree, rtx));
-static rtx expand_builtin_strstr PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx expand_builtin_strpbrk PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx expand_builtin_strchr PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx expand_builtin_strrchr PARAMS ((tree, rtx,
- enum machine_mode));
-static rtx expand_builtin_alloca PARAMS ((tree, rtx));
-static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
-static rtx expand_builtin_frame_address PARAMS ((tree));
-static rtx expand_builtin_fputs PARAMS ((tree, int, int));
-static tree stabilize_va_list PARAMS ((tree, int));
-static rtx expand_builtin_expect PARAMS ((tree, rtx));
-static tree fold_builtin_constant_p PARAMS ((tree));
-static tree fold_builtin_classify_type PARAMS ((tree));
-static tree fold_builtin_inf PARAMS ((tree, int));
-static tree fold_builtin_nan PARAMS ((tree, tree, int));
-static tree build_function_call_expr PARAMS ((tree, tree));
-static int validate_arglist PARAMS ((tree, ...));
+static rtx expand_builtin_setjmp (tree, rtx);
+static void expand_builtin_prefetch (tree);
+static rtx expand_builtin_apply_args (void);
+static rtx expand_builtin_apply_args_1 (void);
+static rtx expand_builtin_apply (rtx, rtx, rtx);
+static void expand_builtin_return (rtx);
+static enum type_class type_to_class (tree);
+static rtx expand_builtin_classify_type (tree);
+static void expand_errno_check (tree, rtx);
+static rtx expand_builtin_mathfn (tree, rtx, rtx);
+static rtx expand_builtin_mathfn_2 (tree, rtx, rtx);
+static rtx expand_builtin_constant_p (tree, enum machine_mode);
+static rtx expand_builtin_args_info (tree);
+static rtx expand_builtin_next_arg (tree);
+static rtx expand_builtin_va_start (tree);
+static rtx expand_builtin_va_end (tree);
+static rtx expand_builtin_va_copy (tree);
+static rtx expand_builtin_memcmp (tree, tree, rtx, enum machine_mode);
+static rtx expand_builtin_strcmp (tree, rtx, enum machine_mode);
+static rtx expand_builtin_strncmp (tree, rtx, enum machine_mode);
+static rtx builtin_memcpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
+static rtx expand_builtin_strcat (tree, rtx, enum machine_mode);
+static rtx expand_builtin_strncat (tree, rtx, enum machine_mode);
+static rtx expand_builtin_strspn (tree, rtx, enum machine_mode);
+static rtx expand_builtin_strcspn (tree, rtx, enum machine_mode);
+static rtx expand_builtin_memcpy (tree, rtx, enum machine_mode);
+static rtx expand_builtin_mempcpy (tree, rtx, enum machine_mode, int);
+static rtx expand_builtin_memmove (tree, rtx, enum machine_mode);
+static rtx expand_builtin_bcopy (tree);
+static rtx expand_builtin_strcpy (tree, rtx, enum machine_mode);
+static rtx expand_builtin_stpcpy (tree, rtx, enum machine_mode);
+static rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
+static rtx expand_builtin_strncpy (tree, rtx, enum machine_mode);
+static rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
+static rtx builtin_memset_gen_str (void *, HOST_WIDE_INT, enum machine_mode);
+static rtx expand_builtin_memset (tree, rtx, enum machine_mode);
+static rtx expand_builtin_bzero (tree);
+static rtx expand_builtin_strlen (tree, rtx, enum machine_mode);
+static rtx expand_builtin_strstr (tree, rtx, enum machine_mode);
+static rtx expand_builtin_strpbrk (tree, rtx, enum machine_mode);
+static rtx expand_builtin_strchr (tree, rtx, enum machine_mode);
+static rtx expand_builtin_strrchr (tree, rtx, enum machine_mode);
+static rtx expand_builtin_alloca (tree, rtx);
+static rtx expand_builtin_unop (enum machine_mode, tree, rtx, rtx, optab);
+static rtx expand_builtin_frame_address (tree, tree);
+static rtx expand_builtin_fputs (tree, rtx, bool);
+static rtx expand_builtin_printf (tree, rtx, enum machine_mode, bool);
+static rtx expand_builtin_fprintf (tree, rtx, enum machine_mode, bool);
+static rtx expand_builtin_sprintf (tree, rtx, enum machine_mode);
+static tree stabilize_va_list (tree, int);
+static rtx expand_builtin_expect (tree, rtx);
+static tree fold_builtin_constant_p (tree);
+static tree fold_builtin_classify_type (tree);
+static tree fold_builtin_inf (tree, int);
+static tree fold_builtin_nan (tree, tree, int);
+static int validate_arglist (tree, ...);
+static bool integer_valued_real_p (tree);
+static tree fold_trunc_transparent_mathfn (tree);
+static bool readonly_data_expr (tree);
+static rtx expand_builtin_fabs (tree, rtx, rtx);
+static rtx expand_builtin_cabs (tree, rtx);
+static tree fold_builtin_cabs (tree, tree, tree);
+static tree fold_builtin_trunc (tree);
+static tree fold_builtin_floor (tree);
+static tree fold_builtin_ceil (tree);
+static tree fold_builtin_bitop (tree);
+static tree fold_builtin_memcpy (tree);
+static tree fold_builtin_mempcpy (tree);
+static tree fold_builtin_memmove (tree);
+static tree fold_builtin_strcpy (tree);
+static tree fold_builtin_strncpy (tree);
+static tree fold_builtin_memcmp (tree);
+static tree fold_builtin_strcmp (tree);
+static tree fold_builtin_strncmp (tree);
/* Return the alignment in bits of EXP, a pointer valued expression.
But don't return more than MAX_ALIGN no matter what.
@@ -162,9 +175,7 @@ static int validate_arglist PARAMS ((tree, ...));
expression is actually pointing at an object whose alignment is tighter. */
static int
-get_pointer_alignment (exp, max_align)
- tree exp;
- unsigned int max_align;
+get_pointer_alignment (tree exp, unsigned int max_align)
{
unsigned int align, inner;
@@ -227,20 +238,42 @@ get_pointer_alignment (exp, max_align)
way, because it could contain a zero byte in the middle.
TREE_STRING_LENGTH is the size of the character array, not the string.
+ ONLY_VALUE should be nonzero if the result is not going to be emitted
+ into the instruction stream and zero if it is going to be expanded.
+ E.g. with i++ ? "foo" : "bar", if ONLY_VALUE is nonzero, constant 3
+ is returned, otherwise NULL, since
+ len = c_strlen (src, 1); if (len) expand_expr (len, ...); would not
+ evaluate the side-effects.
+
The value returned is of type `ssizetype'.
Unfortunately, string_constant can't access the values of const char
arrays with initializers, so neither can we do so here. */
static tree
-c_strlen (src)
- tree src;
+c_strlen (tree src, int only_value)
{
tree offset_node;
HOST_WIDE_INT offset;
int max;
const char *ptr;
+ STRIP_NOPS (src);
+ if (TREE_CODE (src) == COND_EXPR
+ && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
+ {
+ tree len1, len2;
+
+ len1 = c_strlen (TREE_OPERAND (src, 1), only_value);
+ len2 = c_strlen (TREE_OPERAND (src, 2), only_value);
+ if (tree_int_cst_equal (len1, len2))
+ return len1;
+ }
+
+ if (TREE_CODE (src) == COMPOUND_EXPR
+ && (only_value || !TREE_SIDE_EFFECTS (TREE_OPERAND (src, 0))))
+ return c_strlen (TREE_OPERAND (src, 1), only_value);
+
src = string_constant (src, &offset_node);
if (src == 0)
return 0;
@@ -299,8 +332,7 @@ c_strlen (src)
or sum of string constant and integer constant. */
static const char *
-c_getstr (src)
- tree src;
+c_getstr (tree src)
{
tree offset_node;
@@ -321,9 +353,7 @@ c_getstr (src)
GET_MODE_BITSIZE (MODE) bits from string constant STR. */
static rtx
-c_readstr (str, mode)
- const char *str;
- enum machine_mode mode;
+c_readstr (const char *str, enum machine_mode mode)
{
HOST_WIDE_INT c[2];
HOST_WIDE_INT ch;
@@ -357,9 +387,7 @@ c_readstr (str, mode)
P. */
static int
-target_char_cast (cst, p)
- tree cst;
- char *p;
+target_char_cast (tree cst, char *p)
{
unsigned HOST_WIDE_INT val, hostval;
@@ -387,10 +415,8 @@ target_char_cast (cst, p)
address located within it (depending on FNDECL_CODE). */
rtx
-expand_builtin_return_addr (fndecl_code, count, tem)
- enum built_in_function fndecl_code;
- int count;
- rtx tem;
+expand_builtin_return_addr (enum built_in_function fndecl_code, int count,
+ rtx tem)
{
int i;
@@ -450,9 +476,7 @@ static HOST_WIDE_INT setjmp_alias_set = -1;
handling code. */
void
-expand_builtin_setjmp_setup (buf_addr, receiver_label)
- rtx buf_addr;
- rtx receiver_label;
+expand_builtin_setjmp_setup (rtx buf_addr, rtx receiver_label)
{
enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
rtx stack_save;
@@ -461,10 +485,7 @@ expand_builtin_setjmp_setup (buf_addr, receiver_label)
if (setjmp_alias_set == -1)
setjmp_alias_set = new_alias_set ();
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (buf_addr) != Pmode)
- buf_addr = convert_memory_address (Pmode, buf_addr);
-#endif
+ buf_addr = convert_memory_address (Pmode, buf_addr);
buf_addr = force_reg (Pmode, force_operand (buf_addr, NULL_RTX));
@@ -513,8 +534,7 @@ expand_builtin_setjmp_setup (buf_addr, receiver_label)
This is used directly by sjlj exception handling code. */
void
-expand_builtin_setjmp_receiver (receiver_label)
- rtx receiver_label ATTRIBUTE_UNUSED;
+expand_builtin_setjmp_receiver (rtx receiver_label ATTRIBUTE_UNUSED)
{
/* Clobber the FP when we get here, so we have to make sure it's
marked as used by this function. */
@@ -586,9 +606,7 @@ expand_builtin_setjmp_receiver (receiver_label)
them. */
static rtx
-expand_builtin_setjmp (arglist, target)
- tree arglist;
- rtx target;
+expand_builtin_setjmp (tree arglist, rtx target)
{
rtx buf_addr, next_lab, cont_lab;
@@ -606,10 +624,11 @@ expand_builtin_setjmp (arglist, target)
expand_builtin_setjmp_setup (buf_addr, next_lab);
- /* Set TARGET to zero and branch to the continue label. */
+ /* Set TARGET to zero and branch to the continue label. Use emit_jump to
+ ensure that pending stack adjustments are flushed. */
emit_move_insn (target, const0_rtx);
- emit_jump_insn (gen_jump (cont_lab));
- emit_barrier ();
+ emit_jump (cont_lab);
+
emit_label (next_lab);
expand_builtin_setjmp_receiver (next_lab);
@@ -639,8 +658,7 @@ expand_builtin_setjmp (arglist, target)
them. */
void
-expand_builtin_longjmp (buf_addr, value)
- rtx buf_addr, value;
+expand_builtin_longjmp (rtx buf_addr, rtx value)
{
rtx fp, lab, stack, insn, last;
enum machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
@@ -648,10 +666,7 @@ expand_builtin_longjmp (buf_addr, value)
if (setjmp_alias_set == -1)
setjmp_alias_set = new_alias_set ();
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (buf_addr) != Pmode)
- buf_addr = convert_memory_address (Pmode, buf_addr);
-#endif
+ buf_addr = convert_memory_address (Pmode, buf_addr);
buf_addr = force_reg (Pmode, buf_addr);
@@ -695,6 +710,13 @@ expand_builtin_longjmp (buf_addr, value)
{
lab = copy_to_reg (lab);
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ gen_rtx_SCRATCH (VOIDmode))));
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ hard_frame_pointer_rtx)));
+
emit_move_insn (hard_frame_pointer_rtx, fp);
emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
@@ -729,8 +751,7 @@ expand_builtin_longjmp (buf_addr, value)
effects. */
static void
-expand_builtin_prefetch (arglist)
- tree arglist;
+expand_builtin_prefetch (tree arglist)
{
tree arg0, arg1, arg2;
rtx op0, op1, op2;
@@ -793,12 +814,9 @@ expand_builtin_prefetch (arglist)
if ((! (*insn_data[(int) CODE_FOR_prefetch].operand[0].predicate)
(op0,
insn_data[(int) CODE_FOR_prefetch].operand[0].mode))
- || (GET_MODE(op0) != Pmode))
+ || (GET_MODE (op0) != Pmode))
{
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE(op0) != Pmode)
- op0 = convert_memory_address (Pmode, op0);
-#endif
+ op0 = convert_memory_address (Pmode, op0);
op0 = force_reg (Pmode, op0);
}
emit_insn (gen_prefetch (op0, op1, op2));
@@ -816,16 +834,12 @@ expand_builtin_prefetch (arglist)
to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */
static rtx
-get_memory_rtx (exp)
- tree exp;
+get_memory_rtx (tree exp)
{
rtx addr = expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM);
rtx mem;
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (addr) != Pmode)
- addr = convert_memory_address (Pmode, addr);
-#endif
+ addr = convert_memory_address (Pmode, addr);
mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
@@ -879,8 +893,7 @@ static int apply_args_reg_offset[FIRST_PSEUDO_REGISTER];
needed in objc-act.c. */
int
-apply_args_register_offset (regno)
- int regno;
+apply_args_register_offset (int regno)
{
apply_args_size ();
@@ -896,7 +909,7 @@ apply_args_register_offset (regno)
and initialize apply_args_mode. */
static int
-apply_args_size ()
+apply_args_size (void)
{
static int size = -1;
int align;
@@ -911,7 +924,7 @@ apply_args_size ()
/* The second value is the structure value address unless this is
passed as an "invisible" first argument. */
- if (struct_value_rtx)
+ if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
size += GET_MODE_SIZE (Pmode);
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
@@ -976,7 +989,7 @@ apply_args_size ()
and initialize apply_result_mode. */
static int
-apply_result_size ()
+apply_result_size (void)
{
static int size = -1;
int align, regno;
@@ -1052,14 +1065,12 @@ apply_result_size ()
restore the values. */
static rtx
-result_vector (savep, result)
- int savep;
- rtx result;
+result_vector (int savep, rtx result)
{
int regno, size, align, nelts;
enum machine_mode mode;
rtx reg, mem;
- rtx *savevec = (rtx *) alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
+ rtx *savevec = alloca (FIRST_PSEUDO_REGISTER * sizeof (rtx));
size = nelts = 0;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
@@ -1083,11 +1094,12 @@ result_vector (savep, result)
arguments as were passed to the current function. */
static rtx
-expand_builtin_apply_args_1 ()
+expand_builtin_apply_args_1 (void)
{
- rtx registers;
+ rtx registers, tem;
int size, align, regno;
enum machine_mode mode;
+ rtx struct_incoming_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 1);
/* Create a block where the arg-pointer, structure value address,
and argument registers can be saved. */
@@ -1095,15 +1107,13 @@ expand_builtin_apply_args_1 ()
/* Walk past the arg-pointer and structure value address. */
size = GET_MODE_SIZE (Pmode);
- if (struct_value_rtx)
+ if (targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0))
size += GET_MODE_SIZE (Pmode);
/* Save each register used in calling a function to the block. */
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if ((mode = apply_args_mode[regno]) != VOIDmode)
{
- rtx tem;
-
align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
if (size % align != 0)
size = CEIL (size, align) * align;
@@ -1115,16 +1125,25 @@ expand_builtin_apply_args_1 ()
}
/* Save the arg pointer to the block. */
- emit_move_insn (adjust_address (registers, Pmode, 0),
- copy_to_reg (virtual_incoming_args_rtx));
+ tem = copy_to_reg (virtual_incoming_args_rtx);
+#ifdef STACK_GROWS_DOWNWARD
+ /* We need the pointer as the caller actually passed them to us, not
+ as we might have pretended they were passed. Make sure it's a valid
+ operand, as emit_move_insn isn't expected to handle a PLUS. */
+ tem
+ = force_operand (plus_constant (tem, current_function_pretend_args_size),
+ NULL_RTX);
+#endif
+ emit_move_insn (adjust_address (registers, Pmode, 0), tem);
+
size = GET_MODE_SIZE (Pmode);
/* Save the structure value address unless this is passed as an
"invisible" first argument. */
- if (struct_value_incoming_rtx)
+ if (struct_incoming_value)
{
emit_move_insn (adjust_address (registers, Pmode, size),
- copy_to_reg (struct_value_incoming_rtx));
+ copy_to_reg (struct_incoming_value));
size += GET_MODE_SIZE (Pmode);
}
@@ -1140,7 +1159,7 @@ expand_builtin_apply_args_1 ()
saved. */
static rtx
-expand_builtin_apply_args ()
+expand_builtin_apply_args (void)
{
/* Don't do __builtin_apply_args more than once in a function.
Save the result of the first call and reuse it. */
@@ -1175,19 +1194,16 @@ expand_builtin_apply_args ()
untyped return of whatever value was returned by the given function. */
static rtx
-expand_builtin_apply (function, arguments, argsize)
- rtx function, arguments, argsize;
+expand_builtin_apply (rtx function, rtx arguments, rtx argsize)
{
int size, align, regno;
enum machine_mode mode;
rtx incoming_args, result, reg, dest, src, call_insn;
rtx old_stack_level = 0;
rtx call_fusage = 0;
+ rtx struct_value = targetm.calls.struct_value_rtx (cfun ? TREE_TYPE (cfun->decl) : 0, 0);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (arguments) != Pmode)
- arguments = convert_memory_address (Pmode, arguments);
-#endif
+ arguments = convert_memory_address (Pmode, arguments);
/* Create a block where the return registers can be saved. */
result = assign_stack_local (BLKmode, apply_result_size (), -1);
@@ -1209,7 +1225,7 @@ expand_builtin_apply (function, arguments, argsize)
do_pending_stack_adjust ();
NO_DEFER_POP;
- /* Save the stack with nonlocal if available */
+ /* Save the stack with nonlocal if available. */
#ifdef HAVE_save_stack_nonlocal
if (HAVE_save_stack_nonlocal)
emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX);
@@ -1217,12 +1233,16 @@ expand_builtin_apply (function, arguments, argsize)
#endif
emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
- /* Push a block of memory onto the stack to store the memory arguments.
- Save the address in a register, and copy the memory arguments. ??? I
- haven't figured out how the calling convention macros effect this,
- but it's likely that the source and/or destination addresses in
- the block copy will need updating in machine specific ways. */
- dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
+ /* Allocate a block of memory onto the stack and copy the memory
+ arguments to the outgoing arguments address. */
+ allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
+ dest = virtual_outgoing_args_rtx;
+#ifndef STACK_GROWS_DOWNWARD
+ if (GET_CODE (argsize) == CONST_INT)
+ dest = plus_constant (dest, -INTVAL (argsize));
+ else
+ dest = gen_rtx_PLUS (Pmode, dest, negate_rtx (Pmode, argsize));
+#endif
dest = gen_rtx_MEM (BLKmode, dest);
set_mem_align (dest, PARM_BOUNDARY);
src = gen_rtx_MEM (BLKmode, incoming_args);
@@ -1236,7 +1256,7 @@ expand_builtin_apply (function, arguments, argsize)
/* Walk past the arg-pointer and structure value address. */
size = GET_MODE_SIZE (Pmode);
- if (struct_value_rtx)
+ if (struct_value)
size += GET_MODE_SIZE (Pmode);
/* Restore each of the registers previously saved. Make USE insns
@@ -1256,13 +1276,13 @@ expand_builtin_apply (function, arguments, argsize)
/* Restore the structure value address unless this is passed as an
"invisible" first argument. */
size = GET_MODE_SIZE (Pmode);
- if (struct_value_rtx)
+ if (struct_value)
{
rtx value = gen_reg_rtx (Pmode);
emit_move_insn (value, adjust_address (arguments, Pmode, size));
- emit_move_insn (struct_value_rtx, value);
- if (GET_CODE (struct_value_rtx) == REG)
- use_reg (&call_fusage, struct_value_rtx);
+ emit_move_insn (struct_value, value);
+ if (GET_CODE (struct_value) == REG)
+ use_reg (&call_fusage, struct_value);
size += GET_MODE_SIZE (Pmode);
}
@@ -1309,29 +1329,10 @@ expand_builtin_apply (function, arguments, argsize)
#endif
abort ();
- /* Find the CALL insn we just emitted. */
- for (call_insn = get_last_insn ();
- call_insn && GET_CODE (call_insn) != CALL_INSN;
- call_insn = PREV_INSN (call_insn))
- ;
-
- if (! call_insn)
- abort ();
-
- /* Put the register usage information on the CALL. If there is already
- some usage information, put ours at the end. */
- if (CALL_INSN_FUNCTION_USAGE (call_insn))
- {
- rtx link;
-
- for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
- link = XEXP (link, 1))
- ;
-
- XEXP (link, 1) = call_fusage;
- }
- else
- CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
+ /* Find the CALL insn we just emitted, and attach the register usage
+ information. */
+ call_insn = last_call_insn ();
+ add_function_usage_to (call_insn, call_fusage);
/* Restore the stack. */
#ifdef HAVE_save_stack_nonlocal
@@ -1345,28 +1346,20 @@ expand_builtin_apply (function, arguments, argsize)
/* Return the address of the result block. */
result = copy_addr_to_reg (XEXP (result, 0));
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (result) != ptr_mode)
- result = convert_memory_address (ptr_mode, result);
-#endif
- return result;
+ return convert_memory_address (ptr_mode, result);
}
/* Perform an untyped return. */
static void
-expand_builtin_return (result)
- rtx result;
+expand_builtin_return (rtx result)
{
int size, align, regno;
enum machine_mode mode;
rtx reg;
rtx call_fusage = 0;
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (result) != Pmode)
- result = convert_memory_address (Pmode, result);
-#endif
+ result = convert_memory_address (Pmode, result);
apply_result_size ();
result = gen_rtx_MEM (BLKmode, result);
@@ -1403,14 +1396,13 @@ expand_builtin_return (result)
/* Return whatever values was restored by jumping directly to the end
of the function. */
- expand_null_return ();
+ expand_naked_return ();
}
/* Used by expand_builtin_classify_type and fold_builtin_classify_type. */
static enum type_class
-type_to_class (type)
- tree type;
+type_to_class (tree type)
{
switch (TREE_CODE (type))
{
@@ -1442,8 +1434,7 @@ type_to_class (type)
ARGLIST. */
static rtx
-expand_builtin_classify_type (arglist)
- tree arglist;
+expand_builtin_classify_type (tree arglist)
{
if (arglist != 0)
return GEN_INT (type_to_class (TREE_TYPE (TREE_VALUE (arglist))));
@@ -1453,11 +1444,8 @@ expand_builtin_classify_type (arglist)
/* Expand expression EXP, which is a call to __builtin_constant_p. */
static rtx
-expand_builtin_constant_p (exp)
- tree exp;
+expand_builtin_constant_p (tree arglist, enum machine_mode target_mode)
{
- tree arglist = TREE_OPERAND (exp, 1);
- enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
rtx tmp;
if (arglist == 0)
@@ -1465,14 +1453,166 @@ expand_builtin_constant_p (exp)
arglist = TREE_VALUE (arglist);
/* We have taken care of the easy cases during constant folding. This
- case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE get a
- chance to see if it can deduce whether ARGLIST is constant. */
+ case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
+ get a chance to see if it can deduce whether ARGLIST is constant.
+ If CSE isn't going to run, of course, don't bother waiting. */
+
+ if (cse_not_expected)
+ return const0_rtx;
+
+ current_function_calls_constant_p = 1;
tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
- tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
+ tmp = gen_rtx_CONSTANT_P_RTX (target_mode, tmp);
return tmp;
}
+/* This helper macro, meant to be used in mathfn_built_in below,
+ determines which among a set of three builtin math functions is
+ appropriate for a given type mode. The `F' and `L' cases are
+ automatically generated from the `double' case. */
+#define CASE_MATHFN(BUILT_IN_MATHFN) \
+ case BUILT_IN_MATHFN: case BUILT_IN_MATHFN##F: case BUILT_IN_MATHFN##L: \
+ fcode = BUILT_IN_MATHFN; fcodef = BUILT_IN_MATHFN##F ; \
+ fcodel = BUILT_IN_MATHFN##L ; break;
+
+/* Return mathematic function equivalent to FN but operating directly
+ on TYPE, if available. If we can't do the conversion, return zero. */
+tree
+mathfn_built_in (tree type, enum built_in_function fn)
+{
+ const enum machine_mode type_mode = TYPE_MODE (type);
+ enum built_in_function fcode, fcodef, fcodel;
+
+ switch (fn)
+ {
+ CASE_MATHFN (BUILT_IN_ACOS)
+ CASE_MATHFN (BUILT_IN_ACOSH)
+ CASE_MATHFN (BUILT_IN_ASIN)
+ CASE_MATHFN (BUILT_IN_ASINH)
+ CASE_MATHFN (BUILT_IN_ATAN)
+ CASE_MATHFN (BUILT_IN_ATAN2)
+ CASE_MATHFN (BUILT_IN_ATANH)
+ CASE_MATHFN (BUILT_IN_CBRT)
+ CASE_MATHFN (BUILT_IN_CEIL)
+ CASE_MATHFN (BUILT_IN_COPYSIGN)
+ CASE_MATHFN (BUILT_IN_COS)
+ CASE_MATHFN (BUILT_IN_COSH)
+ CASE_MATHFN (BUILT_IN_DREM)
+ CASE_MATHFN (BUILT_IN_ERF)
+ CASE_MATHFN (BUILT_IN_ERFC)
+ CASE_MATHFN (BUILT_IN_EXP)
+ CASE_MATHFN (BUILT_IN_EXP10)
+ CASE_MATHFN (BUILT_IN_EXP2)
+ CASE_MATHFN (BUILT_IN_EXPM1)
+ CASE_MATHFN (BUILT_IN_FABS)
+ CASE_MATHFN (BUILT_IN_FDIM)
+ CASE_MATHFN (BUILT_IN_FLOOR)
+ CASE_MATHFN (BUILT_IN_FMA)
+ CASE_MATHFN (BUILT_IN_FMAX)
+ CASE_MATHFN (BUILT_IN_FMIN)
+ CASE_MATHFN (BUILT_IN_FMOD)
+ CASE_MATHFN (BUILT_IN_FREXP)
+ CASE_MATHFN (BUILT_IN_GAMMA)
+ CASE_MATHFN (BUILT_IN_HUGE_VAL)
+ CASE_MATHFN (BUILT_IN_HYPOT)
+ CASE_MATHFN (BUILT_IN_ILOGB)
+ CASE_MATHFN (BUILT_IN_INF)
+ CASE_MATHFN (BUILT_IN_J0)
+ CASE_MATHFN (BUILT_IN_J1)
+ CASE_MATHFN (BUILT_IN_JN)
+ CASE_MATHFN (BUILT_IN_LDEXP)
+ CASE_MATHFN (BUILT_IN_LGAMMA)
+ CASE_MATHFN (BUILT_IN_LLRINT)
+ CASE_MATHFN (BUILT_IN_LLROUND)
+ CASE_MATHFN (BUILT_IN_LOG)
+ CASE_MATHFN (BUILT_IN_LOG10)
+ CASE_MATHFN (BUILT_IN_LOG1P)
+ CASE_MATHFN (BUILT_IN_LOG2)
+ CASE_MATHFN (BUILT_IN_LOGB)
+ CASE_MATHFN (BUILT_IN_LRINT)
+ CASE_MATHFN (BUILT_IN_LROUND)
+ CASE_MATHFN (BUILT_IN_MODF)
+ CASE_MATHFN (BUILT_IN_NAN)
+ CASE_MATHFN (BUILT_IN_NANS)
+ CASE_MATHFN (BUILT_IN_NEARBYINT)
+ CASE_MATHFN (BUILT_IN_NEXTAFTER)
+ CASE_MATHFN (BUILT_IN_NEXTTOWARD)
+ CASE_MATHFN (BUILT_IN_POW)
+ CASE_MATHFN (BUILT_IN_POW10)
+ CASE_MATHFN (BUILT_IN_REMAINDER)
+ CASE_MATHFN (BUILT_IN_REMQUO)
+ CASE_MATHFN (BUILT_IN_RINT)
+ CASE_MATHFN (BUILT_IN_ROUND)
+ CASE_MATHFN (BUILT_IN_SCALB)
+ CASE_MATHFN (BUILT_IN_SCALBLN)
+ CASE_MATHFN (BUILT_IN_SCALBN)
+ CASE_MATHFN (BUILT_IN_SIGNIFICAND)
+ CASE_MATHFN (BUILT_IN_SIN)
+ CASE_MATHFN (BUILT_IN_SINCOS)
+ CASE_MATHFN (BUILT_IN_SINH)
+ CASE_MATHFN (BUILT_IN_SQRT)
+ CASE_MATHFN (BUILT_IN_TAN)
+ CASE_MATHFN (BUILT_IN_TANH)
+ CASE_MATHFN (BUILT_IN_TGAMMA)
+ CASE_MATHFN (BUILT_IN_TRUNC)
+ CASE_MATHFN (BUILT_IN_Y0)
+ CASE_MATHFN (BUILT_IN_Y1)
+ CASE_MATHFN (BUILT_IN_YN)
+
+ default:
+ return 0;
+ }
+
+ if (type_mode == TYPE_MODE (double_type_node))
+ return implicit_built_in_decls[fcode];
+ else if (type_mode == TYPE_MODE (float_type_node))
+ return implicit_built_in_decls[fcodef];
+ else if (type_mode == TYPE_MODE (long_double_type_node))
+ return implicit_built_in_decls[fcodel];
+ else
+ return 0;
+}
+
+/* If errno must be maintained, expand the RTL to check if the result,
+ TARGET, of a built-in function call, EXP, is NaN, and if so set
+ errno to EDOM. */
+
+static void
+expand_errno_check (tree exp, rtx target)
+{
+ rtx lab = gen_label_rtx ();
+
+ /* Test the result; if it is NaN, set errno=EDOM because
+ the argument was not in the domain. */
+ emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
+ 0, lab);
+
+#ifdef TARGET_EDOM
+ /* If this built-in doesn't throw an exception, set errno directly. */
+ if (TREE_NOTHROW (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)))
+ {
+#ifdef GEN_ERRNO_RTX
+ rtx errno_rtx = GEN_ERRNO_RTX;
+#else
+ rtx errno_rtx
+ = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
+#endif
+ emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
+ emit_label (lab);
+ return;
+ }
+#endif
+
+ /* We can't set errno=EDOM directly; let the library call do it.
+ Pop the arguments right away in case the call gets deleted. */
+ NO_DEFER_POP;
+ expand_call (exp, target, 0);
+ OK_DEFER_POP;
+ emit_label (lab);
+}
+
+
/* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
Return 0 if a normal call should be emitted rather than expanding the
function in-line. EXP is the expression that is a call to the builtin
@@ -1480,42 +1620,20 @@ expand_builtin_constant_p (exp)
SUBTARGET may be used as the target for computing one of EXP's operands. */
static rtx
-expand_builtin_mathfn (exp, target, subtarget)
- tree exp;
- rtx target, subtarget;
+expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
{
optab builtin_optab;
- rtx op0, insns;
- tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+ rtx op0, insns, before_call;
+ tree fndecl = get_callee_fndecl (exp);
tree arglist = TREE_OPERAND (exp, 1);
- enum machine_mode argmode;
+ enum machine_mode mode;
+ bool errno_set = false;
+ tree arg, narg;
if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
return 0;
- /* Stabilize and compute the argument. */
- if (TREE_CODE (TREE_VALUE (arglist)) != VAR_DECL
- && TREE_CODE (TREE_VALUE (arglist)) != PARM_DECL)
- {
- exp = copy_node (exp);
- TREE_OPERAND (exp, 1) = arglist;
- /* Wrap the computation of the argument in a SAVE_EXPR. That
- way, if we need to expand the argument again (as in the
- flag_errno_math case below where we cannot directly set
- errno), we will not perform side-effects more than once.
- Note that here we're mutating the original EXP as well as the
- copy; that's the right thing to do in case the original EXP
- is expanded later. */
- TREE_VALUE (arglist) = save_expr (TREE_VALUE (arglist));
- arglist = copy_node (arglist);
- }
- op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
-
- /* Make a suitable register to place result in. */
- target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
-
- emit_queue ();
- start_sequence ();
+ arg = TREE_VALUE (arglist);
switch (DECL_FUNCTION_CODE (fndecl))
{
@@ -1530,68 +1648,239 @@ expand_builtin_mathfn (exp, target, subtarget)
case BUILT_IN_SQRT:
case BUILT_IN_SQRTF:
case BUILT_IN_SQRTL:
- builtin_optab = sqrt_optab; break;
+ errno_set = ! tree_expr_nonnegative_p (arg);
+ builtin_optab = sqrt_optab;
+ break;
case BUILT_IN_EXP:
case BUILT_IN_EXPF:
case BUILT_IN_EXPL:
- builtin_optab = exp_optab; break;
+ errno_set = true; builtin_optab = exp_optab; break;
case BUILT_IN_LOG:
case BUILT_IN_LOGF:
case BUILT_IN_LOGL:
- builtin_optab = log_optab; break;
+ errno_set = true; builtin_optab = log_optab; break;
+ case BUILT_IN_TAN:
+ case BUILT_IN_TANF:
+ case BUILT_IN_TANL:
+ builtin_optab = tan_optab; break;
+ case BUILT_IN_ATAN:
+ case BUILT_IN_ATANF:
+ case BUILT_IN_ATANL:
+ builtin_optab = atan_optab; break;
+ case BUILT_IN_FLOOR:
+ case BUILT_IN_FLOORF:
+ case BUILT_IN_FLOORL:
+ builtin_optab = floor_optab; break;
+ case BUILT_IN_CEIL:
+ case BUILT_IN_CEILF:
+ case BUILT_IN_CEILL:
+ builtin_optab = ceil_optab; break;
+ case BUILT_IN_TRUNC:
+ case BUILT_IN_TRUNCF:
+ case BUILT_IN_TRUNCL:
+ builtin_optab = btrunc_optab; break;
+ case BUILT_IN_ROUND:
+ case BUILT_IN_ROUNDF:
+ case BUILT_IN_ROUNDL:
+ builtin_optab = round_optab; break;
+ case BUILT_IN_NEARBYINT:
+ case BUILT_IN_NEARBYINTF:
+ case BUILT_IN_NEARBYINTL:
+ builtin_optab = nearbyint_optab; break;
default:
abort ();
}
- /* Compute into TARGET.
- Set TARGET to wherever the result comes back. */
- argmode = TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist)));
- target = expand_unop (argmode, builtin_optab, op0, target, 0);
+ /* Make a suitable register to place result in. */
+ mode = TYPE_MODE (TREE_TYPE (exp));
- /* If we were unable to expand via the builtin, stop the
- sequence (without outputting the insns) and return 0, causing
- a call to the library function. */
- if (target == 0)
+ if (! flag_errno_math || ! HONOR_NANS (mode))
+ errno_set = false;
+
+ /* Before working hard, check whether the instruction is available. */
+ if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
+ target = gen_reg_rtx (mode);
+
+ /* Wrap the computation of the argument in a SAVE_EXPR, as we may
+ need to expand the argument again. This way, we will not perform
+ side-effects more the once. */
+ narg = save_expr (arg);
+ if (narg != arg)
+ {
+ arglist = build_tree_list (NULL_TREE, arg);
+ exp = build_function_call_expr (fndecl, arglist);
+ }
+
+ op0 = expand_expr (arg, subtarget, VOIDmode, 0);
+
+ emit_queue ();
+ start_sequence ();
+
+ /* Compute into TARGET.
+ Set TARGET to wherever the result comes back. */
+ target = expand_unop (mode, builtin_optab, op0, target, 0);
+
+ if (target != 0)
+ {
+ if (errno_set)
+ expand_errno_check (exp, target);
+
+ /* Output the entire sequence. */
+ insns = get_insns ();
+ end_sequence ();
+ emit_insn (insns);
+ return target;
+ }
+
+ /* If we were unable to expand via the builtin, stop the sequence
+ (without outputting the insns) and call to the library function
+ with the stabilized argument list. */
end_sequence ();
- return 0;
}
- /* If errno must be maintained, we must set it to EDOM for NaN results. */
+ before_call = get_last_insn ();
- if (flag_errno_math && HONOR_NANS (argmode))
+ target = expand_call (exp, target, target == const0_rtx);
+
+ /* If this is a sqrt operation and we don't care about errno, try to
+ attach a REG_EQUAL note with a SQRT rtx to the emitted libcall.
+ This allows the semantics of the libcall to be visible to the RTL
+ optimizers. */
+ if (builtin_optab == sqrt_optab && !errno_set)
{
- rtx lab1;
+ /* Search backwards through the insns emitted by expand_call looking
+ for the instruction with the REG_RETVAL note. */
+ rtx last = get_last_insn ();
+ while (last != before_call)
+ {
+ if (find_reg_note (last, REG_RETVAL, NULL))
+ {
+ rtx note = find_reg_note (last, REG_EQUAL, NULL);
+ /* Check that the REQ_EQUAL note is an EXPR_LIST with
+ two elements, i.e. symbol_ref(sqrt) and the operand. */
+ if (note
+ && GET_CODE (note) == EXPR_LIST
+ && GET_CODE (XEXP (note, 0)) == EXPR_LIST
+ && XEXP (XEXP (note, 0), 1) != NULL_RTX
+ && XEXP (XEXP (XEXP (note, 0), 1), 1) == NULL_RTX)
+ {
+ rtx operand = XEXP (XEXP (XEXP (note, 0), 1), 0);
+ /* Check operand is a register with expected mode. */
+ if (operand
+ && GET_CODE (operand) == REG
+ && GET_MODE (operand) == mode)
+ {
+ /* Replace the REG_EQUAL note with a SQRT rtx. */
+ rtx equiv = gen_rtx_SQRT (mode, operand);
+ set_unique_reg_note (last, REG_EQUAL, equiv);
+ }
+ }
+ break;
+ }
+ last = PREV_INSN (last);
+ }
+ }
+
+ return target;
+}
- lab1 = gen_label_rtx ();
+/* Expand a call to the builtin binary math functions (pow and atan2).
+ Return 0 if a normal call should be emitted rather than expanding the
+ function in-line. EXP is the expression that is a call to the builtin
+ function; if convenient, the result should be placed in TARGET.
+ SUBTARGET may be used as the target for computing one of EXP's
+ operands. */
- /* Test the result; if it is NaN, set errno=EDOM because
- the argument was not in the domain. */
- emit_cmp_and_jump_insns (target, target, EQ, 0, GET_MODE (target),
- 0, lab1);
+static rtx
+expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
+{
+ optab builtin_optab;
+ rtx op0, op1, insns;
+ tree fndecl = get_callee_fndecl (exp);
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree arg0, arg1, temp, narg;
+ enum machine_mode mode;
+ bool errno_set = true;
+ bool stable = true;
-#ifdef TARGET_EDOM
- {
-#ifdef GEN_ERRNO_RTX
- rtx errno_rtx = GEN_ERRNO_RTX;
-#else
- rtx errno_rtx
- = gen_rtx_MEM (word_mode, gen_rtx_SYMBOL_REF (Pmode, "errno"));
-#endif
+ if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
+ return 0;
- emit_move_insn (errno_rtx, GEN_INT (TARGET_EDOM));
- }
-#else
- /* We can't set errno=EDOM directly; let the library call do it.
- Pop the arguments right away in case the call gets deleted. */
- NO_DEFER_POP;
- expand_call (exp, target, 0);
- OK_DEFER_POP;
-#endif
+ arg0 = TREE_VALUE (arglist);
+ arg1 = TREE_VALUE (TREE_CHAIN (arglist));
- emit_label (lab1);
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_POW:
+ case BUILT_IN_POWF:
+ case BUILT_IN_POWL:
+ builtin_optab = pow_optab; break;
+ case BUILT_IN_ATAN2:
+ case BUILT_IN_ATAN2F:
+ case BUILT_IN_ATAN2L:
+ builtin_optab = atan2_optab; break;
+ default:
+ abort ();
}
+ /* Make a suitable register to place result in. */
+ mode = TYPE_MODE (TREE_TYPE (exp));
+
+ /* Before working hard, check whether the instruction is available. */
+ if (builtin_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
+ return 0;
+
+ target = gen_reg_rtx (mode);
+
+ if (! flag_errno_math || ! HONOR_NANS (mode))
+ errno_set = false;
+
+ /* Alway stabilize the argument list. */
+ narg = save_expr (arg1);
+ if (narg != arg1)
+ {
+ temp = build_tree_list (NULL_TREE, narg);
+ stable = false;
+ }
+ else
+ temp = TREE_CHAIN (arglist);
+
+ narg = save_expr (arg0);
+ if (narg != arg0)
+ {
+ arglist = tree_cons (NULL_TREE, narg, temp);
+ stable = false;
+ }
+ else if (! stable)
+ arglist = tree_cons (NULL_TREE, arg0, temp);
+
+ if (! stable)
+ exp = build_function_call_expr (fndecl, arglist);
+
+ op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
+ op1 = expand_expr (arg1, 0, VOIDmode, 0);
+
+ emit_queue ();
+ start_sequence ();
+
+ /* Compute into TARGET.
+ Set TARGET to wherever the result comes back. */
+ target = expand_binop (mode, builtin_optab, op0, op1,
+ target, 0, OPTAB_DIRECT);
+
+ /* If we were unable to expand via the builtin, stop the sequence
+ (without outputting the insns) and call to the library function
+ with the stabilized argument list. */
+ if (target == 0)
+ {
+ end_sequence ();
+ return expand_call (exp, target, target == const0_rtx);
+ }
+
+ if (errno_set)
+ expand_errno_check (exp, target);
+
/* Output the entire sequence. */
insns = get_insns ();
end_sequence ();
@@ -1600,31 +1889,295 @@ expand_builtin_mathfn (exp, target, subtarget)
return target;
}
+/* To evaluate powi(x,n), the floating point value x raised to the
+ constant integer exponent n, we use a hybrid algorithm that
+ combines the "window method" with look-up tables. For an
+ introduction to exponentiation algorithms and "addition chains",
+ see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
+ "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
+ 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
+ Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
+
+/* Provide a default value for POWI_MAX_MULTS, the maximum number of
+ multiplications to inline before calling the system library's pow
+ function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
+ so this default never requires calling pow, powf or powl. */
+
+#ifndef POWI_MAX_MULTS
+#define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
+#endif
+
+/* The size of the "optimal power tree" lookup table. All
+ exponents less than this value are simply looked up in the
+ powi_table below. This threshold is also used to size the
+ cache of pseudo registers that hold intermediate results. */
+#define POWI_TABLE_SIZE 256
+
+/* The size, in bits of the window, used in the "window method"
+ exponentiation algorithm. This is equivalent to a radix of
+ (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
+#define POWI_WINDOW_SIZE 3
+
+/* The following table is an efficient representation of an
+ "optimal power tree". For each value, i, the corresponding
+ value, j, in the table states than an optimal evaluation
+ sequence for calculating pow(x,i) can be found by evaluating
+ pow(x,j)*pow(x,i-j). An optimal power tree for the first
+ 100 integers is given in Knuth's "Seminumerical algorithms". */
+
+static const unsigned char powi_table[POWI_TABLE_SIZE] =
+ {
+ 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
+ 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
+ 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
+ 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
+ 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
+ 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
+ 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
+ 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
+ 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
+ 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
+ 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
+ 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
+ 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
+ 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
+ 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
+ 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
+ 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
+ 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
+ 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
+ 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
+ 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
+ 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
+ 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
+ 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
+ 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
+ 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
+ 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
+ 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
+ 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
+ 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
+ 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
+ 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
+ };
+
+
+/* Return the number of multiplications required to calculate
+ powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
+ subroutine of powi_cost. CACHE is an array indicating
+ which exponents have already been calculated. */
+
+static int
+powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
+{
+ /* If we've already calculated this exponent, then this evaluation
+ doesn't require any additional multiplications. */
+ if (cache[n])
+ return 0;
+
+ cache[n] = true;
+ return powi_lookup_cost (n - powi_table[n], cache)
+ + powi_lookup_cost (powi_table[n], cache) + 1;
+}
+
+/* Return the number of multiplications required to calculate
+ powi(x,n) for an arbitrary x, given the exponent N. This
+ function needs to be kept in sync with expand_powi below. */
+
+static int
+powi_cost (HOST_WIDE_INT n)
+{
+ bool cache[POWI_TABLE_SIZE];
+ unsigned HOST_WIDE_INT digit;
+ unsigned HOST_WIDE_INT val;
+ int result;
+
+ if (n == 0)
+ return 0;
+
+ /* Ignore the reciprocal when calculating the cost. */
+ val = (n < 0) ? -n : n;
+
+ /* Initialize the exponent cache. */
+ memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
+ cache[1] = true;
+
+ result = 0;
+
+ while (val >= POWI_TABLE_SIZE)
+ {
+ if (val & 1)
+ {
+ digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
+ result += powi_lookup_cost (digit, cache)
+ + POWI_WINDOW_SIZE + 1;
+ val >>= POWI_WINDOW_SIZE;
+ }
+ else
+ {
+ val >>= 1;
+ result++;
+ }
+ }
+
+ return result + powi_lookup_cost (val, cache);
+}
+
+/* Recursive subroutine of expand_powi. This function takes the array,
+ CACHE, of already calculated exponents and an exponent N and returns
+ an RTX that corresponds to CACHE[1]**N, as calculated in mode MODE. */
+
+static rtx
+expand_powi_1 (enum machine_mode mode, unsigned HOST_WIDE_INT n, rtx *cache)
+{
+ unsigned HOST_WIDE_INT digit;
+ rtx target, result;
+ rtx op0, op1;
+
+ if (n < POWI_TABLE_SIZE)
+ {
+ if (cache[n])
+ return cache[n];
+
+ target = gen_reg_rtx (mode);
+ cache[n] = target;
+
+ op0 = expand_powi_1 (mode, n - powi_table[n], cache);
+ op1 = expand_powi_1 (mode, powi_table[n], cache);
+ }
+ else if (n & 1)
+ {
+ target = gen_reg_rtx (mode);
+ digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
+ op0 = expand_powi_1 (mode, n - digit, cache);
+ op1 = expand_powi_1 (mode, digit, cache);
+ }
+ else
+ {
+ target = gen_reg_rtx (mode);
+ op0 = expand_powi_1 (mode, n >> 1, cache);
+ op1 = op0;
+ }
+
+ result = expand_mult (mode, op0, op1, target, 0);
+ if (result != target)
+ emit_move_insn (target, result);
+ return target;
+}
+
+/* Expand the RTL to evaluate powi(x,n) in mode MODE. X is the
+ floating point operand in mode MODE, and N is the exponent. This
+ function needs to be kept in sync with powi_cost above. */
+
+static rtx
+expand_powi (rtx x, enum machine_mode mode, HOST_WIDE_INT n)
+{
+ unsigned HOST_WIDE_INT val;
+ rtx cache[POWI_TABLE_SIZE];
+ rtx result;
+
+ if (n == 0)
+ return CONST1_RTX (mode);
+
+ val = (n < 0) ? -n : n;
+
+ memset (cache, 0, sizeof (cache));
+ cache[1] = x;
+
+ result = expand_powi_1 (mode, (n < 0) ? -n : n, cache);
+
+ /* If the original exponent was negative, reciprocate the result. */
+ if (n < 0)
+ result = expand_binop (mode, sdiv_optab, CONST1_RTX (mode),
+ result, NULL_RTX, 0, OPTAB_LIB_WIDEN);
+
+ return result;
+}
+
+/* Expand a call to the pow built-in mathematical function. Return 0 if
+ a normal call should be emitted rather than expanding the function
+ in-line. EXP is the expression that is a call to the builtin
+ function; if convenient, the result should be placed in TARGET. */
+
+static rtx
+expand_builtin_pow (tree exp, rtx target, rtx subtarget)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree arg0, arg1;
+
+ if (! validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
+ return 0;
+
+ arg0 = TREE_VALUE (arglist);
+ arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+
+ if (TREE_CODE (arg1) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (arg1))
+ {
+ REAL_VALUE_TYPE cint;
+ REAL_VALUE_TYPE c;
+ HOST_WIDE_INT n;
+
+ c = TREE_REAL_CST (arg1);
+ n = real_to_integer (&c);
+ real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
+ if (real_identical (&c, &cint))
+ {
+ /* If the exponent is -1, 0, 1 or 2, then expand_powi is exact.
+ Otherwise, check the number of multiplications required.
+ Note that pow never sets errno for an integer exponent. */
+ if ((n >= -1 && n <= 2)
+ || (flag_unsafe_math_optimizations
+ && ! optimize_size
+ && powi_cost (n) <= POWI_MAX_MULTS))
+ {
+ enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
+ rtx op = expand_expr (arg0, subtarget, VOIDmode, 0);
+ op = force_reg (mode, op);
+ return expand_powi (op, mode, n);
+ }
+ }
+ }
+ return expand_builtin_mathfn_2 (exp, target, NULL_RTX);
+}
+
/* Expand expression EXP which is a call to the strlen builtin. Return 0
if we failed the caller should emit a normal call, otherwise
try to get the result in TARGET, if convenient. */
static rtx
-expand_builtin_strlen (exp, target)
- tree exp;
- rtx target;
+expand_builtin_strlen (tree arglist, rtx target,
+ enum machine_mode target_mode)
{
- tree arglist = TREE_OPERAND (exp, 1);
- enum machine_mode value_mode = TYPE_MODE (TREE_TYPE (exp));
-
if (!validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
return 0;
else
{
rtx pat;
- tree src = TREE_VALUE (arglist);
-
- int align
- = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
-
+ tree len, src = TREE_VALUE (arglist);
rtx result, src_reg, char_rtx, before_strlen;
- enum machine_mode insn_mode = value_mode, char_mode;
+ enum machine_mode insn_mode = target_mode, char_mode;
enum insn_code icode = CODE_FOR_nothing;
+ int align;
+
+ /* If the length can be computed at compile-time, return it. */
+ len = c_strlen (src, 0);
+ if (len)
+ return expand_expr (len, target, target_mode, EXPAND_NORMAL);
+
+ /* If the length can be computed at compile-time and is constant
+ integer, but there are side-effects in src, evaluate
+ src for side-effects, then return len.
+ E.g. x = strlen (i++ ? "xfoo" + 1 : "bar");
+ can be optimized into: i++; x = 3; */
+ len = c_strlen (src, 1);
+ if (len && TREE_CODE (len) == INTEGER_CST)
+ {
+ expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ return expand_expr (len, target, target_mode, EXPAND_NORMAL);
+ }
+
+ align = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
/* If SRC is not a pointer type, don't do this operation inline. */
if (align == 0)
@@ -1686,12 +2239,12 @@ expand_builtin_strlen (exp, target)
emit_insn_before (pat, get_insns ());
/* Return the value in the proper mode for this function. */
- if (GET_MODE (result) == value_mode)
+ if (GET_MODE (result) == target_mode)
target = result;
else if (target != 0)
convert_move (target, result, 0);
else
- target = convert_to_mode (value_mode, result, 0);
+ target = convert_to_mode (target_mode, result, 0);
return target;
}
@@ -1702,10 +2255,7 @@ expand_builtin_strlen (exp, target)
in TARGET, if convenient (and in mode MODE if that's convenient). */
static rtx
-expand_builtin_strstr (arglist, target, mode)
- tree arglist;
- rtx target;
- enum machine_mode mode;
+expand_builtin_strstr (tree arglist, rtx target, enum machine_mode mode)
{
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
return 0;
@@ -1729,7 +2279,8 @@ expand_builtin_strstr (arglist, target, mode)
/* Return an offset into the constant string argument. */
return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
- s1, ssize_int (r - p1))),
+ s1, convert (TREE_TYPE (s1),
+ ssize_int (r - p1)))),
target, mode, EXPAND_NORMAL);
}
@@ -1739,7 +2290,7 @@ expand_builtin_strstr (arglist, target, mode)
if (p2[1] != '\0')
return 0;
- fn = built_in_decls[BUILT_IN_STRCHR];
+ fn = implicit_built_in_decls[BUILT_IN_STRCHR];
if (!fn)
return 0;
@@ -1758,10 +2309,7 @@ expand_builtin_strstr (arglist, target, mode)
in TARGET, if convenient (and in mode MODE if that's convenient). */
static rtx
-expand_builtin_strchr (arglist, target, mode)
- tree arglist;
- rtx target;
- enum machine_mode mode;
+expand_builtin_strchr (tree arglist, rtx target, enum machine_mode mode)
{
if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
return 0;
@@ -1789,7 +2337,8 @@ expand_builtin_strchr (arglist, target, mode)
/* Return an offset into the constant string argument. */
return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
- s1, ssize_int (r - p1))),
+ s1, convert (TREE_TYPE (s1),
+ ssize_int (r - p1)))),
target, mode, EXPAND_NORMAL);
}
@@ -1804,10 +2353,7 @@ expand_builtin_strchr (arglist, target, mode)
in TARGET, if convenient (and in mode MODE if that's convenient). */
static rtx
-expand_builtin_strrchr (arglist, target, mode)
- tree arglist;
- rtx target;
- enum machine_mode mode;
+expand_builtin_strrchr (tree arglist, rtx target, enum machine_mode mode)
{
if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
return 0;
@@ -1836,14 +2382,15 @@ expand_builtin_strrchr (arglist, target, mode)
/* Return an offset into the constant string argument. */
return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
- s1, ssize_int (r - p1))),
+ s1, convert (TREE_TYPE (s1),
+ ssize_int (r - p1)))),
target, mode, EXPAND_NORMAL);
}
if (! integer_zerop (s2))
return 0;
- fn = built_in_decls[BUILT_IN_STRCHR];
+ fn = implicit_built_in_decls[BUILT_IN_STRCHR];
if (!fn)
return 0;
@@ -1858,10 +2405,7 @@ expand_builtin_strrchr (arglist, target, mode)
in TARGET, if convenient (and in mode MODE if that's convenient). */
static rtx
-expand_builtin_strpbrk (arglist, target, mode)
- tree arglist;
- rtx target;
- enum machine_mode mode;
+expand_builtin_strpbrk (tree arglist, rtx target, enum machine_mode mode)
{
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
return 0;
@@ -1885,7 +2429,8 @@ expand_builtin_strpbrk (arglist, target, mode)
/* Return an offset into the constant string argument. */
return expand_expr (fold (build (PLUS_EXPR, TREE_TYPE (s1),
- s1, ssize_int (r - p1))),
+ s1, convert (TREE_TYPE (s1),
+ ssize_int (r - p1)))),
target, mode, EXPAND_NORMAL);
}
@@ -1901,7 +2446,7 @@ expand_builtin_strpbrk (arglist, target, mode)
if (p2[1] != '\0')
return 0; /* Really call strpbrk. */
- fn = built_in_decls[BUILT_IN_STRCHR];
+ fn = implicit_built_in_decls[BUILT_IN_STRCHR];
if (!fn)
return 0;
@@ -1920,10 +2465,8 @@ expand_builtin_strpbrk (arglist, target, mode)
constant. */
static rtx
-builtin_memcpy_read_str (data, offset, mode)
- PTR data;
- HOST_WIDE_INT offset;
- enum machine_mode mode;
+builtin_memcpy_read_str (void *data, HOST_WIDE_INT offset,
+ enum machine_mode mode)
{
const char *str = (const char *) data;
@@ -1936,15 +2479,11 @@ builtin_memcpy_read_str (data, offset, mode)
}
/* Expand a call to the memcpy builtin, with arguments in ARGLIST.
- Return 0 if we failed, the caller should emit a normal call, otherwise
- try to get the result in TARGET, if convenient (and in mode MODE if
- that's convenient). */
-
+ Return 0 if we failed, the caller should emit a normal call,
+ otherwise try to get the result in TARGET, if convenient (and in
+ mode MODE if that's convenient). */
static rtx
-expand_builtin_memcpy (arglist, target, mode)
- tree arglist;
- rtx target;
- enum machine_mode mode;
+expand_builtin_memcpy (tree arglist, rtx target, enum machine_mode mode)
{
if (!validate_arglist (arglist,
POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
@@ -1955,7 +2494,6 @@ expand_builtin_memcpy (arglist, target, mode)
tree src = TREE_VALUE (TREE_CHAIN (arglist));
tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
const char *src_str;
-
unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
unsigned int dest_align
= get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
@@ -1966,13 +2504,21 @@ expand_builtin_memcpy (arglist, target, mode)
return 0;
/* If the LEN parameter is zero, return DEST. */
- if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
+ if (integer_zerop (len))
{
/* Evaluate and ignore SRC in case it has side-effects. */
expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
return expand_expr (dest, target, mode, EXPAND_NORMAL);
}
+ /* If SRC and DEST are the same (and not volatile), return DEST. */
+ if (operand_equal_p (src, dest, 0))
+ {
+ /* Evaluate and ignore LEN in case it has side-effects. */
+ expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ return expand_expr (dest, target, mode, EXPAND_NORMAL);
+ }
+
/* If either SRC is not a pointer type, don't do this
operation in-line. */
if (src_align == 0)
@@ -1990,16 +2536,13 @@ expand_builtin_memcpy (arglist, target, mode)
&& GET_CODE (len_rtx) == CONST_INT
&& (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
&& can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
- (PTR) src_str, dest_align))
+ (void *) src_str, dest_align))
{
- store_by_pieces (dest_mem, INTVAL (len_rtx),
- builtin_memcpy_read_str,
- (PTR) src_str, dest_align);
+ dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
+ builtin_memcpy_read_str,
+ (void *) src_str, dest_align, 0);
dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (dest_mem) != ptr_mode)
- dest_mem = convert_memory_address (ptr_mode, dest_mem);
-#endif
+ dest_mem = convert_memory_address (ptr_mode, dest_mem);
return dest_mem;
}
@@ -2013,43 +2556,247 @@ expand_builtin_memcpy (arglist, target, mode)
if (dest_addr == 0)
{
dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (dest_addr) != ptr_mode)
- dest_addr = convert_memory_address (ptr_mode, dest_addr);
-#endif
+ dest_addr = convert_memory_address (ptr_mode, dest_addr);
}
-
return dest_addr;
}
}
+/* Expand a call to the mempcpy builtin, with arguments in ARGLIST.
+ Return 0 if we failed the caller should emit a normal call,
+ otherwise try to get the result in TARGET, if convenient (and in
+ mode MODE if that's convenient). If ENDP is 0 return the
+ destination pointer, if ENDP is 1 return the end pointer ala
+ mempcpy, and if ENDP is 2 return the end pointer minus one ala
+ stpcpy. */
+
+static rtx
+expand_builtin_mempcpy (tree arglist, rtx target, enum machine_mode mode,
+ int endp)
+{
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+ /* If return value is ignored, transform mempcpy into memcpy. */
+ else if (target == const0_rtx)
+ {
+ tree fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+
+ if (!fn)
+ return 0;
+
+ return expand_expr (build_function_call_expr (fn, arglist),
+ target, mode, EXPAND_NORMAL);
+ }
+ else
+ {
+ tree dest = TREE_VALUE (arglist);
+ tree src = TREE_VALUE (TREE_CHAIN (arglist));
+ tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+ const char *src_str;
+ unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
+ unsigned int dest_align
+ = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
+ rtx dest_mem, src_mem, len_rtx;
+
+ /* If DEST is not a pointer type, call the normal function. */
+ if (dest_align == 0)
+ return 0;
+
+ /* If SRC and DEST are the same (and not volatile), do nothing. */
+ if (operand_equal_p (src, dest, 0))
+ {
+ tree expr;
+
+ if (endp == 0)
+ {
+ /* Evaluate and ignore LEN in case it has side-effects. */
+ expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ return expand_expr (dest, target, mode, EXPAND_NORMAL);
+ }
+
+ if (endp == 2)
+ len = fold (build (MINUS_EXPR, TREE_TYPE (len), dest,
+ integer_one_node));
+ len = convert (TREE_TYPE (dest), len);
+ expr = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
+ return expand_expr (expr, target, mode, EXPAND_NORMAL);
+ }
+
+ /* If LEN is not constant, call the normal function. */
+ if (! host_integerp (len, 1))
+ return 0;
+
+ /* If the LEN parameter is zero, return DEST. */
+ if (tree_low_cst (len, 1) == 0)
+ {
+ /* Evaluate and ignore SRC in case it has side-effects. */
+ expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ return expand_expr (dest, target, mode, EXPAND_NORMAL);
+ }
+
+ /* If either SRC is not a pointer type, don't do this
+ operation in-line. */
+ if (src_align == 0)
+ return 0;
+
+ len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
+ src_str = c_getstr (src);
+
+ /* If SRC is a string constant and block move would be done
+ by pieces, we can avoid loading the string from memory
+ and only stored the computed constants. */
+ if (src_str
+ && GET_CODE (len_rtx) == CONST_INT
+ && (unsigned HOST_WIDE_INT) INTVAL (len_rtx) <= strlen (src_str) + 1
+ && can_store_by_pieces (INTVAL (len_rtx), builtin_memcpy_read_str,
+ (void *) src_str, dest_align))
+ {
+ dest_mem = get_memory_rtx (dest);
+ set_mem_align (dest_mem, dest_align);
+ dest_mem = store_by_pieces (dest_mem, INTVAL (len_rtx),
+ builtin_memcpy_read_str,
+ (void *) src_str, dest_align, endp);
+ dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
+ dest_mem = convert_memory_address (ptr_mode, dest_mem);
+ return dest_mem;
+ }
+
+ if (GET_CODE (len_rtx) == CONST_INT
+ && can_move_by_pieces (INTVAL (len_rtx),
+ MIN (dest_align, src_align)))
+ {
+ dest_mem = get_memory_rtx (dest);
+ set_mem_align (dest_mem, dest_align);
+ src_mem = get_memory_rtx (src);
+ set_mem_align (src_mem, src_align);
+ dest_mem = move_by_pieces (dest_mem, src_mem, INTVAL (len_rtx),
+ MIN (dest_align, src_align), endp);
+ dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
+ dest_mem = convert_memory_address (ptr_mode, dest_mem);
+ return dest_mem;
+ }
+
+ return 0;
+ }
+}
+
+/* Expand expression EXP, which is a call to the memmove builtin. Return 0
+ if we failed the caller should emit a normal call. */
+
+static rtx
+expand_builtin_memmove (tree arglist, rtx target, enum machine_mode mode)
+{
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+ else
+ {
+ tree dest = TREE_VALUE (arglist);
+ tree src = TREE_VALUE (TREE_CHAIN (arglist));
+ tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+
+ unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
+ unsigned int dest_align
+ = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
+
+ /* If DEST is not a pointer type, call the normal function. */
+ if (dest_align == 0)
+ return 0;
+
+ /* If the LEN parameter is zero, return DEST. */
+ if (integer_zerop (len))
+ {
+ /* Evaluate and ignore SRC in case it has side-effects. */
+ expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ return expand_expr (dest, target, mode, EXPAND_NORMAL);
+ }
+
+ /* If SRC and DEST are the same (and not volatile), return DEST. */
+ if (operand_equal_p (src, dest, 0))
+ {
+ /* Evaluate and ignore LEN in case it has side-effects. */
+ expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ return expand_expr (dest, target, mode, EXPAND_NORMAL);
+ }
+
+ /* If either SRC is not a pointer type, don't do this
+ operation in-line. */
+ if (src_align == 0)
+ return 0;
+
+ /* If src is categorized for a readonly section we can use
+ normal memcpy. */
+ if (readonly_data_expr (src))
+ {
+ tree const fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
+ if (!fn)
+ return 0;
+ return expand_expr (build_function_call_expr (fn, arglist),
+ target, mode, EXPAND_NORMAL);
+ }
+
+ /* Otherwise, call the normal function. */
+ return 0;
+ }
+}
+
+/* Expand expression EXP, which is a call to the bcopy builtin. Return 0
+ if we failed the caller should emit a normal call. */
+
+static rtx
+expand_builtin_bcopy (tree arglist)
+{
+ tree src, dest, size, newarglist;
+
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return NULL_RTX;
+
+ src = TREE_VALUE (arglist);
+ dest = TREE_VALUE (TREE_CHAIN (arglist));
+ size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+
+ /* New argument list transforming bcopy(ptr x, ptr y, int z) to
+ memmove(ptr y, ptr x, size_t z). This is done this way
+ so that if it isn't expanded inline, we fallback to
+ calling bcopy instead of memmove. */
+
+ newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
+ newarglist = tree_cons (NULL_TREE, src, newarglist);
+ newarglist = tree_cons (NULL_TREE, dest, newarglist);
+
+ return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
+}
+
/* Expand expression EXP, which is a call to the strcpy builtin. Return 0
if we failed the caller should emit a normal call, otherwise try to get
the result in TARGET, if convenient (and in mode MODE if that's
convenient). */
static rtx
-expand_builtin_strcpy (exp, target, mode)
- tree exp;
- rtx target;
- enum machine_mode mode;
+expand_builtin_strcpy (tree arglist, rtx target, enum machine_mode mode)
{
- tree arglist = TREE_OPERAND (exp, 1);
tree fn, len, src, dst;
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
return 0;
- fn = built_in_decls[BUILT_IN_MEMCPY];
+ src = TREE_VALUE (TREE_CHAIN (arglist));
+ dst = TREE_VALUE (arglist);
+
+ /* If SRC and DST are equal (and not volatile), return DST. */
+ if (operand_equal_p (src, dst, 0))
+ return expand_expr (dst, target, mode, EXPAND_NORMAL);
+
+ fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
if (!fn)
return 0;
- src = TREE_VALUE (TREE_CHAIN (arglist));
- len = c_strlen (src);
+ len = c_strlen (src, 1);
if (len == 0 || TREE_SIDE_EFFECTS (len))
return 0;
- dst = TREE_VALUE (arglist);
len = size_binop (PLUS_EXPR, len, ssize_int (1));
arglist = build_tree_list (NULL_TREE, len);
arglist = tree_cons (NULL_TREE, src, arglist);
@@ -2058,15 +2805,55 @@ expand_builtin_strcpy (exp, target, mode)
target, mode, EXPAND_NORMAL);
}
+/* Expand a call to the stpcpy builtin, with arguments in ARGLIST.
+ Return 0 if we failed the caller should emit a normal call,
+ otherwise try to get the result in TARGET, if convenient (and in
+ mode MODE if that's convenient). */
+
+static rtx
+expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode)
+{
+ if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return 0;
+ else
+ {
+ tree dst, src, len;
+
+ /* If return value is ignored, transform stpcpy into strcpy. */
+ if (target == const0_rtx)
+ {
+ tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+ if (!fn)
+ return 0;
+
+ return expand_expr (build_function_call_expr (fn, arglist),
+ target, mode, EXPAND_NORMAL);
+ }
+
+ /* Ensure we get an actual string whose length can be evaluated at
+ compile-time, not an expression containing a string. This is
+ because the latter will potentially produce pessimized code
+ when used to produce the return value. */
+ src = TREE_VALUE (TREE_CHAIN (arglist));
+ if (! c_getstr (src) || ! (len = c_strlen (src, 0)))
+ return 0;
+
+ dst = TREE_VALUE (arglist);
+ len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
+ arglist = build_tree_list (NULL_TREE, len);
+ arglist = tree_cons (NULL_TREE, src, arglist);
+ arglist = tree_cons (NULL_TREE, dst, arglist);
+ return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2);
+ }
+}
+
/* Callback routine for store_by_pieces. Read GET_MODE_BITSIZE (MODE)
bytes from constant string DATA + OFFSET and return it as target
constant. */
static rtx
-builtin_strncpy_read_str (data, offset, mode)
- PTR data;
- HOST_WIDE_INT offset;
- enum machine_mode mode;
+builtin_strncpy_read_str (void *data, HOST_WIDE_INT offset,
+ enum machine_mode mode)
{
const char *str = (const char *) data;
@@ -2080,17 +2867,14 @@ builtin_strncpy_read_str (data, offset, mode)
if we failed the caller should emit a normal call. */
static rtx
-expand_builtin_strncpy (arglist, target, mode)
- tree arglist;
- rtx target;
- enum machine_mode mode;
+expand_builtin_strncpy (tree arglist, rtx target, enum machine_mode mode)
{
if (!validate_arglist (arglist,
POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
return 0;
else
{
- tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
+ tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)), 1);
tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
tree fn;
@@ -2130,23 +2914,20 @@ expand_builtin_strncpy (arglist, target, mode)
if (!p || dest_align == 0 || !host_integerp (len, 1)
|| !can_store_by_pieces (tree_low_cst (len, 1),
builtin_strncpy_read_str,
- (PTR) p, dest_align))
+ (void *) p, dest_align))
return 0;
dest_mem = get_memory_rtx (dest);
store_by_pieces (dest_mem, tree_low_cst (len, 1),
builtin_strncpy_read_str,
- (PTR) p, dest_align);
+ (void *) p, dest_align, 0);
dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (dest_mem) != ptr_mode)
- dest_mem = convert_memory_address (ptr_mode, dest_mem);
-#endif
+ dest_mem = convert_memory_address (ptr_mode, dest_mem);
return dest_mem;
}
/* OK transform into builtin memcpy. */
- fn = built_in_decls[BUILT_IN_MEMCPY];
+ fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
if (!fn)
return 0;
return expand_expr (build_function_call_expr (fn, arglist),
@@ -2159,10 +2940,8 @@ expand_builtin_strncpy (arglist, target, mode)
constant. */
static rtx
-builtin_memset_read_str (data, offset, mode)
- PTR data;
- HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
- enum machine_mode mode;
+builtin_memset_read_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
+ enum machine_mode mode)
{
const char *c = (const char *) data;
char *p = alloca (GET_MODE_SIZE (mode));
@@ -2178,10 +2957,8 @@ builtin_memset_read_str (data, offset, mode)
4 bytes wide, return the RTL for 0x01010101*data. */
static rtx
-builtin_memset_gen_str (data, offset, mode)
- PTR data;
- HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
- enum machine_mode mode;
+builtin_memset_gen_str (void *data, HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
+ enum machine_mode mode)
{
rtx target, coeff;
size_t size;
@@ -2206,13 +2983,8 @@ builtin_memset_gen_str (data, offset, mode)
convenient). */
static rtx
-expand_builtin_memset (exp, target, mode)
- tree exp;
- rtx target;
- enum machine_mode mode;
+expand_builtin_memset (tree arglist, rtx target, enum machine_mode mode)
{
- tree arglist = TREE_OPERAND (exp, 1);
-
if (!validate_arglist (arglist,
POINTER_TYPE, INTEGER_TYPE, INTEGER_TYPE, VOID_TYPE))
return 0;
@@ -2233,7 +3005,7 @@ expand_builtin_memset (exp, target, mode)
return 0;
/* If the LEN parameter is zero, return DEST. */
- if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
+ if (integer_zerop (len))
{
/* Evaluate and ignore VAL in case it has side-effects. */
expand_expr (val, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -2256,7 +3028,7 @@ expand_builtin_memset (exp, target, mode)
c = 1;
if (!can_store_by_pieces (tree_low_cst (len, 1),
builtin_memset_read_str,
- (PTR) &c, dest_align))
+ &c, dest_align))
return 0;
val = fold (build1 (CONVERT_EXPR, unsigned_char_type_node, val));
@@ -2266,12 +3038,9 @@ expand_builtin_memset (exp, target, mode)
dest_mem = get_memory_rtx (dest);
store_by_pieces (dest_mem, tree_low_cst (len, 1),
builtin_memset_gen_str,
- (PTR) val_rtx, dest_align);
+ val_rtx, dest_align, 0);
dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (dest_mem) != ptr_mode)
- dest_mem = convert_memory_address (ptr_mode, dest_mem);
-#endif
+ dest_mem = convert_memory_address (ptr_mode, dest_mem);
return dest_mem;
}
@@ -2283,19 +3052,16 @@ expand_builtin_memset (exp, target, mode)
if (!host_integerp (len, 1))
return 0;
if (!can_store_by_pieces (tree_low_cst (len, 1),
- builtin_memset_read_str, (PTR) &c,
+ builtin_memset_read_str, &c,
dest_align))
return 0;
dest_mem = get_memory_rtx (dest);
store_by_pieces (dest_mem, tree_low_cst (len, 1),
builtin_memset_read_str,
- (PTR) &c, dest_align);
+ &c, dest_align, 0);
dest_mem = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (dest_mem) != ptr_mode)
- dest_mem = convert_memory_address (ptr_mode, dest_mem);
-#endif
+ dest_mem = convert_memory_address (ptr_mode, dest_mem);
return dest_mem;
}
@@ -2308,10 +3074,7 @@ expand_builtin_memset (exp, target, mode)
if (dest_addr == 0)
{
dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (dest_addr) != ptr_mode)
- dest_addr = convert_memory_address (ptr_mode, dest_addr);
-#endif
+ dest_addr = convert_memory_address (ptr_mode, dest_addr);
}
return dest_addr;
@@ -2322,12 +3085,9 @@ expand_builtin_memset (exp, target, mode)
if we failed the caller should emit a normal call. */
static rtx
-expand_builtin_bzero (exp)
- tree exp;
+expand_builtin_bzero (tree arglist)
{
- tree arglist = TREE_OPERAND (exp, 1);
tree dest, size, newarglist;
- rtx result;
if (!validate_arglist (arglist, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
return NULL_RTX;
@@ -2344,13 +3104,7 @@ expand_builtin_bzero (exp)
newarglist = tree_cons (NULL_TREE, integer_zero_node, newarglist);
newarglist = tree_cons (NULL_TREE, dest, newarglist);
- TREE_OPERAND (exp, 1) = newarglist;
- result = expand_builtin_memset (exp, const0_rtx, VOIDmode);
-
- /* Always restore the original arguments. */
- TREE_OPERAND (exp, 1) = arglist;
-
- return result;
+ return expand_builtin_memset (newarglist, const0_rtx, VOIDmode);
}
/* Expand expression EXP, which is a call to the memcmp built-in function.
@@ -2359,11 +3113,8 @@ expand_builtin_bzero (exp)
TARGET, if convenient (and in mode MODE, if that's convenient). */
static rtx
-expand_builtin_memcmp (exp, arglist, target, mode)
- tree exp ATTRIBUTE_UNUSED;
- tree arglist;
- rtx target;
- enum machine_mode mode;
+expand_builtin_memcmp (tree exp ATTRIBUTE_UNUSED, tree arglist, rtx target,
+ enum machine_mode mode)
{
tree arg1, arg2, len;
const char *p1, *p2;
@@ -2377,7 +3128,7 @@ expand_builtin_memcmp (exp, arglist, target, mode)
len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
/* If the len parameter is zero, return zero. */
- if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
+ if (integer_zerop (len))
{
/* Evaluate and ignore arg1 and arg2 in case they have
side-effects. */
@@ -2386,6 +3137,14 @@ expand_builtin_memcmp (exp, arglist, target, mode)
return const0_rtx;
}
+ /* If both arguments are equal (and not volatile), return zero. */
+ if (operand_equal_p (arg1, arg2, 0))
+ {
+ /* Evaluate and ignore len in case it has side-effects. */
+ expand_expr (len, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ return const0_rtx;
+ }
+
p1 = c_getstr (arg1);
p2 = c_getstr (arg2);
@@ -2402,7 +3161,7 @@ expand_builtin_memcmp (exp, arglist, target, mode)
/* If len parameter is one, return an expression corresponding to
(*(const unsigned char*)arg1 - (const unsigned char*)arg2). */
- if (host_integerp (len, 1) && tree_low_cst (len, 1) == 1)
+ if (integer_onep (len))
{
tree cst_uchar_node = build_type_variant (unsigned_char_type_node, 1, 0);
tree cst_uchar_ptr_node = build_pointer_type (cst_uchar_node);
@@ -2418,7 +3177,7 @@ expand_builtin_memcmp (exp, arglist, target, mode)
return expand_expr (result, target, mode, EXPAND_NORMAL);
}
-#ifdef HAVE_cmpstrsi
+#if defined HAVE_cmpmemsi || defined HAVE_cmpstrsi
{
rtx arg1_rtx, arg2_rtx, arg3_rtx;
rtx result;
@@ -2428,8 +3187,19 @@ expand_builtin_memcmp (exp, arglist, target, mode)
= get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
int arg2_align
= get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
- enum machine_mode insn_mode
- = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
+ enum machine_mode insn_mode;
+
+#ifdef HAVE_cmpmemsi
+ if (HAVE_cmpmemsi)
+ insn_mode = insn_data[(int) CODE_FOR_cmpmemsi].operand[0].mode;
+ else
+#endif
+#ifdef HAVE_cmpstrsi
+ if (HAVE_cmpstrsi)
+ insn_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
+ else
+#endif
+ return 0;
/* If we don't have POINTER_TYPE, call the function. */
if (arg1_align == 0 || arg2_align == 0)
@@ -2445,11 +3215,19 @@ expand_builtin_memcmp (exp, arglist, target, mode)
arg1_rtx = get_memory_rtx (arg1);
arg2_rtx = get_memory_rtx (arg2);
arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
- if (!HAVE_cmpstrsi)
- insn = NULL_RTX;
+#ifdef HAVE_cmpmemsi
+ if (HAVE_cmpmemsi)
+ insn = gen_cmpmemsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
+ GEN_INT (MIN (arg1_align, arg2_align)));
else
+#endif
+#ifdef HAVE_cmpstrsi
+ if (HAVE_cmpstrsi)
insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
GEN_INT (MIN (arg1_align, arg2_align)));
+ else
+#endif
+ abort ();
if (insn)
emit_insn (insn);
@@ -2484,10 +3262,7 @@ expand_builtin_memcmp (exp, arglist, target, mode)
the result in TARGET, if convenient. */
static rtx
-expand_builtin_strcmp (exp, target, mode)
- tree exp;
- rtx target;
- enum machine_mode mode;
+expand_builtin_strcmp (tree exp, rtx target, enum machine_mode mode)
{
tree arglist = TREE_OPERAND (exp, 1);
tree arg1, arg2;
@@ -2499,6 +3274,10 @@ expand_builtin_strcmp (exp, target, mode)
arg1 = TREE_VALUE (arglist);
arg2 = TREE_VALUE (TREE_CHAIN (arglist));
+ /* If both arguments are equal (and not volatile), return zero. */
+ if (operand_equal_p (arg1, arg2, 0))
+ return const0_rtx;
+
p1 = c_getstr (arg1);
p2 = c_getstr (arg2);
@@ -2528,85 +3307,97 @@ expand_builtin_strcmp (exp, target, mode)
#ifdef HAVE_cmpstrsi
if (HAVE_cmpstrsi)
- {
- tree len, len1, len2;
- rtx arg1_rtx, arg2_rtx, arg3_rtx;
- rtx result, insn;
-
- int arg1_align
- = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
- int arg2_align
- = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
- enum machine_mode insn_mode
- = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
-
- len1 = c_strlen (arg1);
- len2 = c_strlen (arg2);
-
- if (len1)
- len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
- if (len2)
- len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
-
- /* If we don't have a constant length for the first, use the length
- of the second, if we know it. We don't require a constant for
- this case; some cost analysis could be done if both are available
- but neither is constant. For now, assume they're equally cheap
- unless one has side effects. If both strings have constant lengths,
- use the smaller. */
-
- if (!len1)
- len = len2;
- else if (!len2)
- len = len1;
- else if (TREE_SIDE_EFFECTS (len1))
- len = len2;
- else if (TREE_SIDE_EFFECTS (len2))
- len = len1;
- else if (TREE_CODE (len1) != INTEGER_CST)
- len = len2;
- else if (TREE_CODE (len2) != INTEGER_CST)
- len = len1;
- else if (tree_int_cst_lt (len1, len2))
- len = len1;
- else
- len = len2;
+ {
+ tree len, len1, len2;
+ rtx arg1_rtx, arg2_rtx, arg3_rtx;
+ rtx result, insn;
+ tree fndecl;
- /* If both arguments have side effects, we cannot optimize. */
- if (!len || TREE_SIDE_EFFECTS (len))
- return 0;
+ int arg1_align
+ = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
+ int arg2_align
+ = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
+ enum machine_mode insn_mode
+ = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
- /* If we don't have POINTER_TYPE, call the function. */
- if (arg1_align == 0 || arg2_align == 0)
- return 0;
+ len1 = c_strlen (arg1, 1);
+ len2 = c_strlen (arg2, 1);
+
+ if (len1)
+ len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
+ if (len2)
+ len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
+
+ /* If we don't have a constant length for the first, use the length
+ of the second, if we know it. We don't require a constant for
+ this case; some cost analysis could be done if both are available
+ but neither is constant. For now, assume they're equally cheap,
+ unless one has side effects. If both strings have constant lengths,
+ use the smaller. */
+
+ if (!len1)
+ len = len2;
+ else if (!len2)
+ len = len1;
+ else if (TREE_SIDE_EFFECTS (len1))
+ len = len2;
+ else if (TREE_SIDE_EFFECTS (len2))
+ len = len1;
+ else if (TREE_CODE (len1) != INTEGER_CST)
+ len = len2;
+ else if (TREE_CODE (len2) != INTEGER_CST)
+ len = len1;
+ else if (tree_int_cst_lt (len1, len2))
+ len = len1;
+ else
+ len = len2;
- /* Make a place to write the result of the instruction. */
- result = target;
- if (! (result != 0
- && GET_CODE (result) == REG
- && GET_MODE (result) == insn_mode
- && REGNO (result) >= FIRST_PSEUDO_REGISTER))
- result = gen_reg_rtx (insn_mode);
+ /* If both arguments have side effects, we cannot optimize. */
+ if (!len || TREE_SIDE_EFFECTS (len))
+ return 0;
- arg1_rtx = get_memory_rtx (arg1);
- arg2_rtx = get_memory_rtx (arg2);
- arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
- insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
- GEN_INT (MIN (arg1_align, arg2_align)));
- if (!insn)
- return 0;
+ /* If we don't have POINTER_TYPE, call the function. */
+ if (arg1_align == 0 || arg2_align == 0)
+ return 0;
- emit_insn (insn);
+ /* Make a place to write the result of the instruction. */
+ result = target;
+ if (! (result != 0
+ && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
+ && REGNO (result) >= FIRST_PSEUDO_REGISTER))
+ result = gen_reg_rtx (insn_mode);
- /* Return the value in the proper mode for this function. */
- mode = TYPE_MODE (TREE_TYPE (exp));
- if (GET_MODE (result) == mode)
- return result;
- if (target == 0)
- return convert_to_mode (mode, result, 0);
- convert_move (target, result, 0);
- return target;
- }
+ /* Stabilize the arguments in case gen_cmpstrsi fails. */
+ arg1 = save_expr (arg1);
+ arg2 = save_expr (arg2);
+
+ arg1_rtx = get_memory_rtx (arg1);
+ arg2_rtx = get_memory_rtx (arg2);
+ arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
+ insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
+ GEN_INT (MIN (arg1_align, arg2_align)));
+ if (insn)
+ {
+ emit_insn (insn);
+
+ /* Return the value in the proper mode for this function. */
+ mode = TYPE_MODE (TREE_TYPE (exp));
+ if (GET_MODE (result) == mode)
+ return result;
+ if (target == 0)
+ return convert_to_mode (mode, result, 0);
+ convert_move (target, result, 0);
+ return target;
+ }
+
+ /* Expand the library call ourselves using a stabilized argument
+ list to avoid re-evaluating the function's arguments twice. */
+ arglist = build_tree_list (NULL_TREE, arg2);
+ arglist = tree_cons (NULL_TREE, arg1, arglist);
+ fndecl = get_callee_fndecl (exp);
+ exp = build_function_call_expr (fndecl, arglist);
+ return expand_call (exp, target, target == const0_rtx);
+ }
#endif
return 0;
}
@@ -2616,10 +3407,7 @@ expand_builtin_strcmp (exp, target, mode)
the result in TARGET, if convenient. */
static rtx
-expand_builtin_strncmp (exp, target, mode)
- tree exp;
- rtx target;
- enum machine_mode mode;
+expand_builtin_strncmp (tree exp, rtx target, enum machine_mode mode)
{
tree arglist = TREE_OPERAND (exp, 1);
tree arg1, arg2, arg3;
@@ -2634,7 +3422,7 @@ expand_builtin_strncmp (exp, target, mode)
arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
/* If the len parameter is zero, return zero. */
- if (host_integerp (arg3, 1) && tree_low_cst (arg3, 1) == 0)
+ if (integer_zerop (arg3))
{
/* Evaluate and ignore arg1 and arg2 in case they have
side-effects. */
@@ -2643,6 +3431,14 @@ expand_builtin_strncmp (exp, target, mode)
return const0_rtx;
}
+ /* If arg1 and arg2 are equal (and not volatile), return zero. */
+ if (operand_equal_p (arg1, arg2, 0))
+ {
+ /* Evaluate and ignore arg3 in case it has side-effects. */
+ expand_expr (arg3, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ return const0_rtx;
+ }
+
p1 = c_getstr (arg1);
p2 = c_getstr (arg2);
@@ -2679,88 +3475,102 @@ expand_builtin_strncmp (exp, target, mode)
using length MIN(strlen(string)+1, arg3). */
#ifdef HAVE_cmpstrsi
if (HAVE_cmpstrsi)
- {
- tree len, len1, len2;
- rtx arg1_rtx, arg2_rtx, arg3_rtx;
- rtx result, insn;
-
- int arg1_align
- = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
- int arg2_align
- = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
- enum machine_mode insn_mode
- = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
-
- len1 = c_strlen (arg1);
- len2 = c_strlen (arg2);
-
- if (len1)
- len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
- if (len2)
- len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
-
- /* If we don't have a constant length for the first, use the length
- of the second, if we know it. We don't require a constant for
- this case; some cost analysis could be done if both are available
- but neither is constant. For now, assume they're equally cheap,
- unless one has side effects. If both strings have constant lengths,
- use the smaller. */
-
- if (!len1)
- len = len2;
- else if (!len2)
- len = len1;
- else if (TREE_SIDE_EFFECTS (len1))
- len = len2;
- else if (TREE_SIDE_EFFECTS (len2))
- len = len1;
- else if (TREE_CODE (len1) != INTEGER_CST)
- len = len2;
- else if (TREE_CODE (len2) != INTEGER_CST)
- len = len1;
- else if (tree_int_cst_lt (len1, len2))
- len = len1;
- else
- len = len2;
+ {
+ tree len, len1, len2;
+ rtx arg1_rtx, arg2_rtx, arg3_rtx;
+ rtx result, insn;
+ tree fndecl;
- /* If both arguments have side effects, we cannot optimize. */
- if (!len || TREE_SIDE_EFFECTS (len))
- return 0;
+ int arg1_align
+ = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
+ int arg2_align
+ = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
+ enum machine_mode insn_mode
+ = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
- /* The actual new length parameter is MIN(len,arg3). */
- len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
+ len1 = c_strlen (arg1, 1);
+ len2 = c_strlen (arg2, 1);
+
+ if (len1)
+ len1 = size_binop (PLUS_EXPR, ssize_int (1), len1);
+ if (len2)
+ len2 = size_binop (PLUS_EXPR, ssize_int (1), len2);
+
+ /* If we don't have a constant length for the first, use the length
+ of the second, if we know it. We don't require a constant for
+ this case; some cost analysis could be done if both are available
+ but neither is constant. For now, assume they're equally cheap,
+ unless one has side effects. If both strings have constant lengths,
+ use the smaller. */
+
+ if (!len1)
+ len = len2;
+ else if (!len2)
+ len = len1;
+ else if (TREE_SIDE_EFFECTS (len1))
+ len = len2;
+ else if (TREE_SIDE_EFFECTS (len2))
+ len = len1;
+ else if (TREE_CODE (len1) != INTEGER_CST)
+ len = len2;
+ else if (TREE_CODE (len2) != INTEGER_CST)
+ len = len1;
+ else if (tree_int_cst_lt (len1, len2))
+ len = len1;
+ else
+ len = len2;
- /* If we don't have POINTER_TYPE, call the function. */
- if (arg1_align == 0 || arg2_align == 0)
- return 0;
+ /* If both arguments have side effects, we cannot optimize. */
+ if (!len || TREE_SIDE_EFFECTS (len))
+ return 0;
- /* Make a place to write the result of the instruction. */
- result = target;
- if (! (result != 0
- && GET_CODE (result) == REG
- && GET_MODE (result) == insn_mode
- && REGNO (result) >= FIRST_PSEUDO_REGISTER))
- result = gen_reg_rtx (insn_mode);
+ /* The actual new length parameter is MIN(len,arg3). */
+ len = fold (build (MIN_EXPR, TREE_TYPE (len), len, arg3));
- arg1_rtx = get_memory_rtx (arg1);
- arg2_rtx = get_memory_rtx (arg2);
- arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
- insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
- GEN_INT (MIN (arg1_align, arg2_align)));
- if (!insn)
- return 0;
+ /* If we don't have POINTER_TYPE, call the function. */
+ if (arg1_align == 0 || arg2_align == 0)
+ return 0;
- emit_insn (insn);
+ /* Make a place to write the result of the instruction. */
+ result = target;
+ if (! (result != 0
+ && GET_CODE (result) == REG && GET_MODE (result) == insn_mode
+ && REGNO (result) >= FIRST_PSEUDO_REGISTER))
+ result = gen_reg_rtx (insn_mode);
- /* Return the value in the proper mode for this function. */
- mode = TYPE_MODE (TREE_TYPE (exp));
- if (GET_MODE (result) == mode)
- return result;
- if (target == 0)
- return convert_to_mode (mode, result, 0);
- convert_move (target, result, 0);
- return target;
- }
+ /* Stabilize the arguments in case gen_cmpstrsi fails. */
+ arg1 = save_expr (arg1);
+ arg2 = save_expr (arg2);
+ len = save_expr (len);
+
+ arg1_rtx = get_memory_rtx (arg1);
+ arg2_rtx = get_memory_rtx (arg2);
+ arg3_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0);
+ insn = gen_cmpstrsi (result, arg1_rtx, arg2_rtx, arg3_rtx,
+ GEN_INT (MIN (arg1_align, arg2_align)));
+ if (insn)
+ {
+ emit_insn (insn);
+
+ /* Return the value in the proper mode for this function. */
+ mode = TYPE_MODE (TREE_TYPE (exp));
+ if (GET_MODE (result) == mode)
+ return result;
+ if (target == 0)
+ return convert_to_mode (mode, result, 0);
+ convert_move (target, result, 0);
+ return target;
+ }
+
+ /* Expand the library call ourselves using a stabilized argument
+ list to avoid re-evaluating the function's arguments twice. */
+ arglist = build_tree_list (NULL_TREE, len);
+ arglist = tree_cons (NULL_TREE, arg2, arglist);
+ arglist = tree_cons (NULL_TREE, arg1, arglist);
+ fndecl = get_callee_fndecl (exp);
+ exp = build_function_call_expr (fndecl, arglist);
+ return expand_call (exp, target, target == const0_rtx);
+ }
#endif
return 0;
}
@@ -2770,10 +3580,7 @@ expand_builtin_strncmp (exp, target, mode)
otherwise try to get the result in TARGET, if convenient. */
static rtx
-expand_builtin_strcat (arglist, target, mode)
- tree arglist;
- rtx target;
- enum machine_mode mode;
+expand_builtin_strcat (tree arglist, rtx target, enum machine_mode mode)
{
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
return 0;
@@ -2783,9 +3590,52 @@ expand_builtin_strcat (arglist, target, mode)
src = TREE_VALUE (TREE_CHAIN (arglist));
const char *p = c_getstr (src);
- /* If the string length is zero, return the dst parameter. */
- if (p && *p == '\0')
- return expand_expr (dst, target, mode, EXPAND_NORMAL);
+ if (p)
+ {
+ /* If the string length is zero, return the dst parameter. */
+ if (*p == '\0')
+ return expand_expr (dst, target, mode, EXPAND_NORMAL);
+ else if (!optimize_size)
+ {
+ /* Otherwise if !optimize_size, see if we can store by
+ pieces into (dst + strlen(dst)). */
+ tree newdst, arglist,
+ strlen_fn = implicit_built_in_decls[BUILT_IN_STRLEN];
+
+ /* This is the length argument. */
+ arglist = build_tree_list (NULL_TREE,
+ fold (size_binop (PLUS_EXPR,
+ c_strlen (src, 0),
+ ssize_int (1))));
+ /* Prepend src argument. */
+ arglist = tree_cons (NULL_TREE, src, arglist);
+
+ /* We're going to use dst more than once. */
+ dst = save_expr (dst);
+
+ /* Create strlen (dst). */
+ newdst =
+ fold (build_function_call_expr (strlen_fn,
+ build_tree_list (NULL_TREE,
+ dst)));
+ /* Create (dst + strlen (dst)). */
+ newdst = fold (build (PLUS_EXPR, TREE_TYPE (dst), dst, newdst));
+
+ /* Prepend the new dst argument. */
+ arglist = tree_cons (NULL_TREE, newdst, arglist);
+
+ /* We don't want to get turned into a memcpy if the
+ target is const0_rtx, i.e. when the return value
+ isn't used. That would produce pessimized code so
+ pass in a target of zero, it should never actually be
+ used. If this was successful return the original
+ dst, not the result of mempcpy. */
+ if (expand_builtin_mempcpy (arglist, /*target=*/0, mode, /*endp=*/0))
+ return expand_expr (dst, target, mode, EXPAND_NORMAL);
+ else
+ return 0;
+ }
+ }
return 0;
}
@@ -2796,10 +3646,7 @@ expand_builtin_strcat (arglist, target, mode)
otherwise try to get the result in TARGET, if convenient. */
static rtx
-expand_builtin_strncat (arglist, target, mode)
- tree arglist;
- rtx target;
- enum machine_mode mode;
+expand_builtin_strncat (tree arglist, rtx target, enum machine_mode mode)
{
if (!validate_arglist (arglist,
POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
@@ -2829,7 +3676,7 @@ expand_builtin_strncat (arglist, target, mode)
{
tree newarglist
= tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
- tree fn = built_in_decls[BUILT_IN_STRCAT];
+ tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
/* If the replacement _DECL isn't initialized, don't do the
transformation. */
@@ -2848,10 +3695,7 @@ expand_builtin_strncat (arglist, target, mode)
otherwise try to get the result in TARGET, if convenient. */
static rtx
-expand_builtin_strspn (arglist, target, mode)
- tree arglist;
- rtx target;
- enum machine_mode mode;
+expand_builtin_strspn (tree arglist, rtx target, enum machine_mode mode)
{
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
return 0;
@@ -2885,10 +3729,7 @@ expand_builtin_strspn (arglist, target, mode)
otherwise try to get the result in TARGET, if convenient. */
static rtx
-expand_builtin_strcspn (arglist, target, mode)
- tree arglist;
- rtx target;
- enum machine_mode mode;
+expand_builtin_strcspn (tree arglist, rtx target, enum machine_mode mode)
{
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
return 0;
@@ -2917,7 +3758,7 @@ expand_builtin_strcspn (arglist, target, mode)
if (p2 && *p2 == '\0')
{
tree newarglist = build_tree_list (NULL_TREE, s1),
- fn = built_in_decls[BUILT_IN_STRLEN];
+ fn = implicit_built_in_decls[BUILT_IN_STRLEN];
/* If the replacement _DECL isn't initialized, don't do the
transformation. */
@@ -2935,7 +3776,7 @@ expand_builtin_strcspn (arglist, target, mode)
if that's convenient. */
rtx
-expand_builtin_saveregs ()
+expand_builtin_saveregs (void)
{
rtx val, seq;
@@ -2950,21 +3791,8 @@ expand_builtin_saveregs ()
start_sequence ();
-#ifdef EXPAND_BUILTIN_SAVEREGS
/* Do whatever the machine needs done in this case. */
- val = EXPAND_BUILTIN_SAVEREGS ();
-#else
- /* ??? We used to try and build up a call to the out of line function,
- guessing about what registers needed saving etc. This became much
- harder with __builtin_va_start, since we don't have a tree for a
- call to __builtin_saveregs to fall back on. There was exactly one
- port (i860) that used this code, and I'm unconvinced it could actually
- handle the general case. So we no longer try to handle anything
- weird and make the backend absorb the evil. */
-
- error ("__builtin_saveregs not supported by this target");
- val = const0_rtx;
-#endif
+ val = targetm.calls.expand_builtin_saveregs ();
seq = get_insns ();
end_sequence ();
@@ -2986,17 +3814,10 @@ expand_builtin_saveregs ()
is controlled by the definition of CUMULATIVE_ARGS. */
static rtx
-expand_builtin_args_info (exp)
- tree exp;
+expand_builtin_args_info (tree arglist)
{
- tree arglist = TREE_OPERAND (exp, 1);
int nwords = sizeof (CUMULATIVE_ARGS) / sizeof (int);
int *word_ptr = (int *) &current_function_args_info;
-#if 0
- /* These are used by the code below that is if 0'ed away */
- int i;
- tree type, elts, result;
-#endif
if (sizeof (CUMULATIVE_ARGS) % sizeof (int) != 0)
abort ();
@@ -3019,27 +3840,12 @@ expand_builtin_args_info (exp)
error ("missing argument in `__builtin_args_info'");
return const0_rtx;
-
-#if 0
- for (i = 0; i < nwords; i++)
- elts = tree_cons (NULL_TREE, build_int_2 (word_ptr[i], 0));
-
- type = build_array_type (integer_type_node,
- build_index_type (build_int_2 (nwords, 0)));
- result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (elts));
- TREE_CONSTANT (result) = 1;
- TREE_STATIC (result) = 1;
- result = build1 (INDIRECT_REF, build_pointer_type (type), result);
- TREE_CONSTANT (result) = 1;
- return expand_expr (result, NULL_RTX, VOIDmode, 0);
-#endif
}
/* Expand ARGLIST, from a call to __builtin_next_arg. */
static rtx
-expand_builtin_next_arg (arglist)
- tree arglist;
+expand_builtin_next_arg (tree arglist)
{
tree fntype = TREE_TYPE (current_function_decl);
@@ -3083,9 +3889,7 @@ expand_builtin_next_arg (arglist)
from multiple evaluations. */
static tree
-stabilize_va_list (valist, needs_lvalue)
- tree valist;
- int needs_lvalue;
+stabilize_va_list (tree valist, int needs_lvalue)
{
if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
{
@@ -3128,13 +3932,19 @@ stabilize_va_list (valist, needs_lvalue)
return valist;
}
+/* The "standard" definition of va_list is void*. */
+
+tree
+std_build_builtin_va_list (void)
+{
+ return ptr_type_node;
+}
+
/* The "standard" implementation of va_start: just assign `nextarg' to
the variable. */
void
-std_expand_builtin_va_start (valist, nextarg)
- tree valist;
- rtx nextarg;
+std_expand_builtin_va_start (tree valist, rtx nextarg)
{
tree t;
@@ -3148,8 +3958,7 @@ std_expand_builtin_va_start (valist, nextarg)
/* Expand ARGLIST, from a call to __builtin_va_start. */
static rtx
-expand_builtin_va_start (arglist)
- tree arglist;
+expand_builtin_va_start (tree arglist)
{
rtx nextarg;
tree chain, valist;
@@ -3175,17 +3984,38 @@ expand_builtin_va_start (arglist)
current (padded) address and increment by the (padded) size. */
rtx
-std_expand_builtin_va_arg (valist, type)
- tree valist, type;
+std_expand_builtin_va_arg (tree valist, tree type)
{
tree addr_tree, t, type_size = NULL;
tree align, alignm1;
tree rounded_size;
rtx addr;
+ HOST_WIDE_INT boundary;
/* Compute the rounded size of the type. */
align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
+ boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
+
+ /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
+ requires greater alignment, we must perform dynamic alignment. */
+
+ if (boundary > PARM_BOUNDARY)
+ {
+ if (!PAD_VARARGS_DOWN)
+ {
+ t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+ build (PLUS_EXPR, TREE_TYPE (valist), valist,
+ build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
+ t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+ build (BIT_AND_EXPR, TREE_TYPE (valist), valist,
+ build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
if (type == error_mark_node
|| (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
|| TREE_OVERFLOW (type_size))
@@ -3234,8 +4064,7 @@ std_expand_builtin_va_arg (valist, type)
a very special sort of operator. */
rtx
-expand_builtin_va_arg (valist, type)
- tree valist, type;
+expand_builtin_va_arg (tree valist, tree type)
{
rtx addr, result;
tree promoted_type, want_va_type, have_va_type;
@@ -3302,6 +4131,7 @@ expand_builtin_va_arg (valist, type)
/* We can, however, treat "undefined" any way we please.
Call abort to encourage the user to fix the program. */
+ inform ("if this code is reached, the program will abort");
expand_builtin_trap ();
/* This is dead code, but go ahead and finish so that the
@@ -3321,10 +4151,7 @@ expand_builtin_va_arg (valist, type)
#endif
}
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (addr) != Pmode)
- addr = convert_memory_address (Pmode, addr);
-#endif
+ addr = convert_memory_address (Pmode, addr);
result = gen_rtx_MEM (TYPE_MODE (type), addr);
set_mem_alias_set (result, get_varargs_alias_set ());
@@ -3335,20 +4162,14 @@ expand_builtin_va_arg (valist, type)
/* Expand ARGLIST, from a call to __builtin_va_end. */
static rtx
-expand_builtin_va_end (arglist)
- tree arglist;
+expand_builtin_va_end (tree arglist)
{
tree valist = TREE_VALUE (arglist);
-#ifdef EXPAND_BUILTIN_VA_END
- valist = stabilize_va_list (valist, 0);
- EXPAND_BUILTIN_VA_END (arglist);
-#else
/* Evaluate for side effects, if needed. I hate macros that don't
do that. */
if (TREE_SIDE_EFFECTS (valist))
expand_expr (valist, const0_rtx, VOIDmode, EXPAND_NORMAL);
-#endif
return const0_rtx;
}
@@ -3358,8 +4179,7 @@ expand_builtin_va_end (arglist)
nastiness of array-type va_list types. */
static rtx
-expand_builtin_va_copy (arglist)
- tree arglist;
+expand_builtin_va_copy (tree arglist)
{
tree dst, src, t;
@@ -3385,13 +4205,8 @@ expand_builtin_va_copy (arglist)
size = expand_expr (TYPE_SIZE_UNIT (va_list_type_node), NULL_RTX,
VOIDmode, EXPAND_NORMAL);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (dstb) != Pmode)
- dstb = convert_memory_address (Pmode, dstb);
-
- if (GET_MODE (srcb) != Pmode)
- srcb = convert_memory_address (Pmode, srcb);
-#endif
+ dstb = convert_memory_address (Pmode, dstb);
+ srcb = convert_memory_address (Pmode, srcb);
/* "Dereference" to BLKmode memories. */
dstb = gen_rtx_MEM (BLKmode, dstb);
@@ -3412,12 +4227,8 @@ expand_builtin_va_copy (arglist)
__builtin_return_address. */
static rtx
-expand_builtin_frame_address (exp)
- tree exp;
+expand_builtin_frame_address (tree fndecl, tree arglist)
{
- tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
- tree arglist = TREE_OPERAND (exp, 1);
-
/* The argument must be a nonnegative integer constant.
It counts the number of frames to scan up the stack.
The value is the return address saved in that frame. */
@@ -3465,9 +4276,7 @@ expand_builtin_frame_address (exp)
the result in TARGET, if convenient. */
static rtx
-expand_builtin_alloca (arglist, target)
- tree arglist;
- rtx target;
+expand_builtin_alloca (tree arglist, rtx target)
{
rtx op0;
rtx result;
@@ -3480,24 +4289,19 @@ expand_builtin_alloca (arglist, target)
/* Allocate the desired space. */
result = allocate_dynamic_stack_space (op0, target, BITS_PER_UNIT);
-
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (result) != ptr_mode)
- result = convert_memory_address (ptr_mode, result);
-#endif
+ result = convert_memory_address (ptr_mode, result);
return result;
}
-/* Expand a call to the ffs builtin. The arguments are in ARGLIST.
+/* Expand a call to a unary builtin. The arguments are in ARGLIST.
Return 0 if a normal call should be emitted rather than expanding the
function in-line. If convenient, the result should be placed in TARGET.
SUBTARGET may be used as the target for computing one of EXP's operands. */
static rtx
-expand_builtin_ffs (arglist, target, subtarget)
- tree arglist;
- rtx target, subtarget;
+expand_builtin_unop (enum machine_mode target_mode, tree arglist, rtx target,
+ rtx subtarget, optab op_optab)
{
rtx op0;
if (!validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
@@ -3505,33 +4309,31 @@ expand_builtin_ffs (arglist, target, subtarget)
/* Compute the argument. */
op0 = expand_expr (TREE_VALUE (arglist), subtarget, VOIDmode, 0);
- /* Compute ffs, into TARGET if possible.
+ /* Compute op, into TARGET if possible.
Set TARGET to wherever the result comes back. */
target = expand_unop (TYPE_MODE (TREE_TYPE (TREE_VALUE (arglist))),
- ffs_optab, op0, target, 1);
+ op_optab, op0, target, 1);
if (target == 0)
abort ();
- return target;
+
+ return convert_to_mode (target_mode, target, 0);
}
/* If the string passed to fputs is a constant and is one character
long, we attempt to transform this call into __builtin_fputc(). */
static rtx
-expand_builtin_fputs (arglist, ignore, unlocked)
- tree arglist;
- int ignore;
- int unlocked;
+expand_builtin_fputs (tree arglist, rtx target, bool unlocked)
{
tree len, fn;
- tree fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
- : built_in_decls[BUILT_IN_FPUTC];
- tree fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
- : built_in_decls[BUILT_IN_FWRITE];
+ tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_FPUTC];
+ tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_FWRITE];
/* If the return value is used, or the replacement _DECL isn't
initialized, don't do the transformation. */
- if (!ignore || !fn_fputc || !fn_fwrite)
+ if (target != const0_rtx || !fn_fputc || !fn_fwrite)
return 0;
/* Verify the arguments in the original call. */
@@ -3540,7 +4342,7 @@ expand_builtin_fputs (arglist, ignore, unlocked)
/* Get the length of the string passed to fputs. If the length
can't be determined, punt. */
- if (!(len = c_strlen (TREE_VALUE (arglist)))
+ if (!(len = c_strlen (TREE_VALUE (arglist), 1))
|| TREE_CODE (len) != INTEGER_CST)
return 0;
@@ -3570,12 +4372,12 @@ expand_builtin_fputs (arglist, ignore, unlocked)
break;
}
}
- /* FALLTHROUGH */
+ /* Fall through. */
case 1: /* length is greater than 1, call fwrite. */
{
tree string_arg;
- /* If optimizing for size keep fputs. */
+ /* If optimizing for size keep fputs. */
if (optimize_size)
return 0;
string_arg = TREE_VALUE (arglist);
@@ -3593,8 +4395,7 @@ expand_builtin_fputs (arglist, ignore, unlocked)
}
return expand_expr (build_function_call_expr (fn, arglist),
- (ignore ? const0_rtx : NULL_RTX),
- VOIDmode, EXPAND_NORMAL);
+ const0_rtx, VOIDmode, EXPAND_NORMAL);
}
/* Expand a call to __builtin_expect. We return our argument and emit a
@@ -3602,9 +4403,7 @@ expand_builtin_fputs (arglist, ignore, unlocked)
a non-jump context. */
static rtx
-expand_builtin_expect (arglist, target)
- tree arglist;
- rtx target;
+expand_builtin_expect (tree arglist, rtx target)
{
tree exp, c;
rtx note, rtx_c;
@@ -3633,7 +4432,7 @@ expand_builtin_expect (arglist, target)
rtx_c = expand_expr (c, NULL_RTX, GET_MODE (target), EXPAND_NORMAL);
- note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
+ note = emit_note (NOTE_INSN_EXPECTED_VALUE);
NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, target, rtx_c);
}
@@ -3648,10 +4447,7 @@ expand_builtin_expect (arglist, target)
based on the test being 0/1. */
rtx
-expand_builtin_expect_jump (exp, if_false_label, if_true_label)
- tree exp;
- rtx if_false_label;
- rtx if_true_label;
+expand_builtin_expect_jump (tree exp, rtx if_false_label, rtx if_true_label)
{
tree arglist = TREE_OPERAND (exp, 1);
tree arg0 = TREE_VALUE (arglist);
@@ -3663,111 +4459,106 @@ expand_builtin_expect_jump (exp, if_false_label, if_true_label)
if (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
&& (integer_zerop (arg1) || integer_onep (arg1)))
{
- int num_jumps = 0;
- rtx insn;
-
- /* If we fail to locate an appropriate conditional jump, we'll
- fall back to normal evaluation. Ensure that the expression
- can be re-evaluated. */
- switch (unsafe_for_reeval (arg0))
- {
- case 0: /* Safe. */
- break;
-
- case 1: /* Mildly unsafe. */
- arg0 = unsave_expr (arg0);
- break;
-
- case 2: /* Wildly unsafe. */
- return NULL_RTX;
- }
+ rtx insn, drop_through_label, temp;
/* Expand the jump insns. */
start_sequence ();
do_jump (arg0, if_false_label, if_true_label);
ret = get_insns ();
+
+ drop_through_label = get_last_insn ();
+ if (drop_through_label && GET_CODE (drop_through_label) == NOTE)
+ drop_through_label = prev_nonnote_insn (drop_through_label);
+ if (drop_through_label && GET_CODE (drop_through_label) != CODE_LABEL)
+ drop_through_label = NULL_RTX;
end_sequence ();
- /* Now that the __builtin_expect has been validated, go through and add
- the expect's to each of the conditional jumps. If we run into an
- error, just give up and generate the 'safe' code of doing a SCC
- operation and then doing a branch on that. */
+ if (! if_true_label)
+ if_true_label = drop_through_label;
+ if (! if_false_label)
+ if_false_label = drop_through_label;
+
+ /* Go through and add the expect's to each of the conditional jumps. */
insn = ret;
while (insn != NULL_RTX)
{
rtx next = NEXT_INSN (insn);
- rtx pattern;
- if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn)
- && (pattern = pc_set (insn)) != NULL_RTX)
+ if (GET_CODE (insn) == JUMP_INSN && any_condjump_p (insn))
{
- rtx ifelse = SET_SRC (pattern);
- rtx label;
- int taken;
-
- if (GET_CODE (ifelse) != IF_THEN_ELSE)
- goto do_next_insn;
-
- if (GET_CODE (XEXP (ifelse, 1)) == LABEL_REF)
- {
- taken = 1;
- label = XEXP (XEXP (ifelse, 1), 0);
- }
- /* An inverted jump reverses the probabilities. */
- else if (GET_CODE (XEXP (ifelse, 2)) == LABEL_REF)
+ rtx ifelse = SET_SRC (pc_set (insn));
+ rtx then_dest = XEXP (ifelse, 1);
+ rtx else_dest = XEXP (ifelse, 2);
+ int taken = -1;
+
+ /* First check if we recognize any of the labels. */
+ if (GET_CODE (then_dest) == LABEL_REF
+ && XEXP (then_dest, 0) == if_true_label)
+ taken = 1;
+ else if (GET_CODE (then_dest) == LABEL_REF
+ && XEXP (then_dest, 0) == if_false_label)
+ taken = 0;
+ else if (GET_CODE (else_dest) == LABEL_REF
+ && XEXP (else_dest, 0) == if_false_label)
+ taken = 1;
+ else if (GET_CODE (else_dest) == LABEL_REF
+ && XEXP (else_dest, 0) == if_true_label)
+ taken = 0;
+ /* Otherwise check where we drop through. */
+ else if (else_dest == pc_rtx)
{
- taken = 0;
- label = XEXP (XEXP (ifelse, 2), 0);
+ if (next && GET_CODE (next) == NOTE)
+ next = next_nonnote_insn (next);
+
+ if (next && GET_CODE (next) == JUMP_INSN
+ && any_uncondjump_p (next))
+ temp = XEXP (SET_SRC (pc_set (next)), 0);
+ else
+ temp = next;
+
+ /* TEMP is either a CODE_LABEL, NULL_RTX or something
+ else that can't possibly match either target label. */
+ if (temp == if_false_label)
+ taken = 1;
+ else if (temp == if_true_label)
+ taken = 0;
}
- /* We shouldn't have to worry about conditional returns during
- the expansion stage, but handle it gracefully anyway. */
- else if (GET_CODE (XEXP (ifelse, 1)) == RETURN)
+ else if (then_dest == pc_rtx)
{
- taken = 1;
- label = NULL_RTX;
+ if (next && GET_CODE (next) == NOTE)
+ next = next_nonnote_insn (next);
+
+ if (next && GET_CODE (next) == JUMP_INSN
+ && any_uncondjump_p (next))
+ temp = XEXP (SET_SRC (pc_set (next)), 0);
+ else
+ temp = next;
+
+ if (temp == if_false_label)
+ taken = 0;
+ else if (temp == if_true_label)
+ taken = 1;
}
- /* An inverted return reverses the probabilities. */
- else if (GET_CODE (XEXP (ifelse, 2)) == RETURN)
+
+ if (taken != -1)
{
- taken = 0;
- label = NULL_RTX;
+ /* If the test is expected to fail, reverse the
+ probabilities. */
+ if (integer_zerop (arg1))
+ taken = 1 - taken;
+ predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
}
- else
- goto do_next_insn;
-
- /* If the test is expected to fail, reverse the
- probabilities. */
- if (integer_zerop (arg1))
- taken = 1 - taken;
-
- /* If we are jumping to the false label, reverse the
- probabilities. */
- if (label == NULL_RTX)
- ; /* conditional return */
- else if (label == if_false_label)
- taken = 1 - taken;
- else if (label != if_true_label)
- goto do_next_insn;
-
- num_jumps++;
- predict_insn_def (insn, PRED_BUILTIN_EXPECT, taken);
}
- do_next_insn:
insn = next;
}
-
- /* If no jumps were modified, fail and do __builtin_expect the normal
- way. */
- if (num_jumps == 0)
- ret = NULL_RTX;
}
return ret;
}
void
-expand_builtin_trap ()
+expand_builtin_trap (void)
{
#ifdef HAVE_trap
if (HAVE_trap)
@@ -3777,6 +4568,358 @@ expand_builtin_trap ()
emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
emit_barrier ();
}
+
+/* Expand a call to fabs, fabsf or fabsl with arguments ARGLIST.
+ Return 0 if a normal call should be emitted rather than expanding
+ the function inline. If convenient, the result should be placed
+ in TARGET. SUBTARGET may be used as the target for computing
+ the operand. */
+
+static rtx
+expand_builtin_fabs (tree arglist, rtx target, rtx subtarget)
+{
+ enum machine_mode mode;
+ tree arg;
+ rtx op0;
+
+ if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ return 0;
+
+ arg = TREE_VALUE (arglist);
+ mode = TYPE_MODE (TREE_TYPE (arg));
+ op0 = expand_expr (arg, subtarget, VOIDmode, 0);
+ return expand_abs (mode, op0, target, 0, safe_from_p (target, arg, 1));
+}
+
+/* Expand a call to cabs, cabsf or cabsl with arguments ARGLIST.
+ Return 0 if a normal call should be emitted rather than expanding
+ the function inline. If convenient, the result should be placed
+ in target. */
+
+static rtx
+expand_builtin_cabs (tree arglist, rtx target)
+{
+ enum machine_mode mode;
+ tree arg;
+ rtx op0;
+
+ if (arglist == 0 || TREE_CHAIN (arglist))
+ return 0;
+ arg = TREE_VALUE (arglist);
+ if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
+ return 0;
+
+ mode = TYPE_MODE (TREE_TYPE (arg));
+ op0 = expand_expr (arg, NULL_RTX, VOIDmode, 0);
+ return expand_complex_abs (mode, op0, target, 0);
+}
+
+/* Create a new constant string literal and return a char* pointer to it.
+ The STRING_CST value is the LEN characters at STR. */
+static tree
+build_string_literal (int len, const char *str)
+{
+ tree t, elem, index, type;
+
+ t = build_string (len, str);
+ elem = build_type_variant (char_type_node, 1, 0);
+ index = build_index_type (build_int_2 (len - 1, 0));
+ type = build_array_type (elem, index);
+ TREE_TYPE (t) = type;
+ TREE_CONSTANT (t) = 1;
+ TREE_READONLY (t) = 1;
+ TREE_STATIC (t) = 1;
+
+ type = build_pointer_type (type);
+ t = build1 (ADDR_EXPR, type, t);
+
+ type = build_pointer_type (elem);
+ t = build1 (NOP_EXPR, type, t);
+ return t;
+}
+
+/* Expand a call to printf or printf_unlocked with argument list ARGLIST.
+ Return 0 if a normal call should be emitted rather than transforming
+ the function inline. If convenient, the result should be placed in
+ TARGET with mode MODE. UNLOCKED indicates this is a printf_unlocked
+ call. */
+static rtx
+expand_builtin_printf (tree arglist, rtx target, enum machine_mode mode,
+ bool unlocked)
+{
+ tree fn_putchar = unlocked
+ ? implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_PUTCHAR];
+ tree fn_puts = unlocked ? implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_PUTS];
+ const char *fmt_str;
+ tree fn, fmt, arg;
+
+ /* If the return value is used, don't do the transformation. */
+ if (target != const0_rtx)
+ return 0;
+
+ /* Verify the required arguments in the original call. */
+ if (! arglist)
+ return 0;
+ fmt = TREE_VALUE (arglist);
+ if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
+ return 0;
+ arglist = TREE_CHAIN (arglist);
+
+ /* Check whether the format is a literal string constant. */
+ fmt_str = c_getstr (fmt);
+ if (fmt_str == NULL)
+ return 0;
+
+ /* If the format specifier was "%s\n", call __builtin_puts(arg). */
+ if (strcmp (fmt_str, "%s\n") == 0)
+ {
+ if (! arglist
+ || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
+ || TREE_CHAIN (arglist))
+ return 0;
+ fn = fn_puts;
+ }
+ /* If the format specifier was "%c", call __builtin_putchar(arg). */
+ else if (strcmp (fmt_str, "%c") == 0)
+ {
+ if (! arglist
+ || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
+ || TREE_CHAIN (arglist))
+ return 0;
+ fn = fn_putchar;
+ }
+ else
+ {
+ /* We can't handle anything else with % args or %% ... yet. */
+ if (strchr (fmt_str, '%'))
+ return 0;
+
+ if (arglist)
+ return 0;
+
+ /* If the format specifier was "", printf does nothing. */
+ if (fmt_str[0] == '\0')
+ return const0_rtx;
+ /* If the format specifier has length of 1, call putchar. */
+ if (fmt_str[1] == '\0')
+ {
+ /* Given printf("c"), (where c is any one character,)
+ convert "c"[0] to an int and pass that to the replacement
+ function. */
+ arg = build_int_2 (fmt_str[0], 0);
+ arglist = build_tree_list (NULL_TREE, arg);
+ fn = fn_putchar;
+ }
+ else
+ {
+ /* If the format specifier was "string\n", call puts("string"). */
+ size_t len = strlen (fmt_str);
+ if (fmt_str[len - 1] == '\n')
+ {
+ /* Create a NUL-terminated string that's one char shorter
+ than the original, stripping off the trailing '\n'. */
+ char *newstr = (char *) alloca (len);
+ memcpy (newstr, fmt_str, len - 1);
+ newstr[len - 1] = 0;
+
+ arg = build_string_literal (len, newstr);
+ arglist = build_tree_list (NULL_TREE, arg);
+ fn = fn_puts;
+ }
+ else
+ /* We'd like to arrange to call fputs(string,stdout) here,
+ but we need stdout and don't have a way to get it yet. */
+ return 0;
+ }
+ }
+
+ if (!fn)
+ return 0;
+ return expand_expr (build_function_call_expr (fn, arglist),
+ target, mode, EXPAND_NORMAL);
+}
+
+/* Expand a call to fprintf or fprintf_unlocked with argument list ARGLIST.
+ Return 0 if a normal call should be emitted rather than transforming
+ the function inline. If convenient, the result should be placed in
+ TARGET with mode MODE. UNLOCKED indicates this is a fprintf_unlocked
+ call. */
+static rtx
+expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode mode,
+ bool unlocked)
+{
+ tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_FPUTC];
+ tree fn_fputs = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_FPUTS];
+ const char *fmt_str;
+ tree fn, fmt, fp, arg;
+
+ /* If the return value is used, don't do the transformation. */
+ if (target != const0_rtx)
+ return 0;
+
+ /* Verify the required arguments in the original call. */
+ if (! arglist)
+ return 0;
+ fp = TREE_VALUE (arglist);
+ if (TREE_CODE (TREE_TYPE (fp)) != POINTER_TYPE)
+ return 0;
+ arglist = TREE_CHAIN (arglist);
+ if (! arglist)
+ return 0;
+ fmt = TREE_VALUE (arglist);
+ if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
+ return 0;
+ arglist = TREE_CHAIN (arglist);
+
+ /* Check whether the format is a literal string constant. */
+ fmt_str = c_getstr (fmt);
+ if (fmt_str == NULL)
+ return 0;
+
+ /* If the format specifier was "%s", call __builtin_fputs(arg,fp). */
+ if (strcmp (fmt_str, "%s") == 0)
+ {
+ if (! arglist
+ || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
+ || TREE_CHAIN (arglist))
+ return 0;
+ arg = TREE_VALUE (arglist);
+ arglist = build_tree_list (NULL_TREE, fp);
+ arglist = tree_cons (NULL_TREE, arg, arglist);
+ fn = fn_fputs;
+ }
+ /* If the format specifier was "%c", call __builtin_fputc(arg,fp). */
+ else if (strcmp (fmt_str, "%c") == 0)
+ {
+ if (! arglist
+ || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != INTEGER_TYPE
+ || TREE_CHAIN (arglist))
+ return 0;
+ arg = TREE_VALUE (arglist);
+ arglist = build_tree_list (NULL_TREE, fp);
+ arglist = tree_cons (NULL_TREE, arg, arglist);
+ fn = fn_fputc;
+ }
+ else
+ {
+ /* We can't handle anything else with % args or %% ... yet. */
+ if (strchr (fmt_str, '%'))
+ return 0;
+
+ if (arglist)
+ return 0;
+
+ /* If the format specifier was "", fprintf does nothing. */
+ if (fmt_str[0] == '\0')
+ {
+ /* Evaluate and ignore FILE* argument for side-effects. */
+ expand_expr (fp, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ return const0_rtx;
+ }
+
+ /* When "string" doesn't contain %, replace all cases of
+ fprintf(stream,string) with fputs(string,stream). The fputs
+ builtin will take care of special cases like length == 1. */
+ arglist = build_tree_list (NULL_TREE, fp);
+ arglist = tree_cons (NULL_TREE, fmt, arglist);
+ fn = fn_fputs;
+ }
+
+ if (!fn)
+ return 0;
+ return expand_expr (build_function_call_expr (fn, arglist),
+ target, mode, EXPAND_NORMAL);
+}
+
+/* Expand a call to sprintf with argument list ARGLIST. Return 0 if
+ a normal call should be emitted rather than expanding the function
+ inline. If convenient, the result should be placed in TARGET with
+ mode MODE. */
+
+static rtx
+expand_builtin_sprintf (tree arglist, rtx target, enum machine_mode mode)
+{
+ tree orig_arglist, dest, fmt;
+ const char *fmt_str;
+
+ orig_arglist = arglist;
+
+ /* Verify the required arguments in the original call. */
+ if (! arglist)
+ return 0;
+ dest = TREE_VALUE (arglist);
+ if (TREE_CODE (TREE_TYPE (dest)) != POINTER_TYPE)
+ return 0;
+ arglist = TREE_CHAIN (arglist);
+ if (! arglist)
+ return 0;
+ fmt = TREE_VALUE (arglist);
+ if (TREE_CODE (TREE_TYPE (fmt)) != POINTER_TYPE)
+ return 0;
+ arglist = TREE_CHAIN (arglist);
+
+ /* Check whether the format is a literal string constant. */
+ fmt_str = c_getstr (fmt);
+ if (fmt_str == NULL)
+ return 0;
+
+ /* If the format doesn't contain % args or %%, use strcpy. */
+ if (strchr (fmt_str, '%') == 0)
+ {
+ tree fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+ tree exp;
+
+ if (arglist || ! fn)
+ return 0;
+ expand_expr (build_function_call_expr (fn, orig_arglist),
+ const0_rtx, VOIDmode, EXPAND_NORMAL);
+ if (target == const0_rtx)
+ return const0_rtx;
+ exp = build_int_2 (strlen (fmt_str), 0);
+ exp = fold (build1 (NOP_EXPR, integer_type_node, exp));
+ return expand_expr (exp, target, mode, EXPAND_NORMAL);
+ }
+ /* If the format is "%s", use strcpy if the result isn't used. */
+ else if (strcmp (fmt_str, "%s") == 0)
+ {
+ tree fn, arg, len;
+ fn = implicit_built_in_decls[BUILT_IN_STRCPY];
+
+ if (! fn)
+ return 0;
+
+ if (! arglist || TREE_CHAIN (arglist))
+ return 0;
+ arg = TREE_VALUE (arglist);
+ if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
+ return 0;
+
+ if (target != const0_rtx)
+ {
+ len = c_strlen (arg, 1);
+ if (! len || TREE_CODE (len) != INTEGER_CST)
+ return 0;
+ }
+ else
+ len = NULL_TREE;
+
+ arglist = build_tree_list (NULL_TREE, arg);
+ arglist = tree_cons (NULL_TREE, dest, arglist);
+ expand_expr (build_function_call_expr (fn, arglist),
+ const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+ if (target == const0_rtx)
+ return const0_rtx;
+ return expand_expr (len, target, mode, EXPAND_NORMAL);
+ }
+
+ return 0;
+}
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
@@ -3785,18 +4928,15 @@ expand_builtin_trap ()
IGNORE is nonzero if the value is to be ignored. */
rtx
-expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget;
- enum machine_mode mode;
- int ignore;
+expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
+ int ignore)
{
- tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+ tree fndecl = get_callee_fndecl (exp);
tree arglist = TREE_OPERAND (exp, 1);
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+ enum machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
- /* Perform postincrements before expanding builtin functions.  */
+ /* Perform postincrements before expanding builtin functions. */
emit_queue ();
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
@@ -3804,59 +4944,41 @@ expand_builtin (exp, target, subtarget, mode, ignore)
/* When not optimizing, generate calls to library functions for a certain
set of builtins. */
- if (!optimize && !CALLED_AS_BUILT_IN (fndecl))
- switch (fcode)
- {
- case BUILT_IN_SQRT:
- case BUILT_IN_SQRTF:
- case BUILT_IN_SQRTL:
- case BUILT_IN_SIN:
- case BUILT_IN_SINF:
- case BUILT_IN_SINL:
- case BUILT_IN_COS:
- case BUILT_IN_COSF:
- case BUILT_IN_COSL:
- case BUILT_IN_EXP:
- case BUILT_IN_EXPF:
- case BUILT_IN_EXPL:
- case BUILT_IN_MEMSET:
- case BUILT_IN_MEMCPY:
- case BUILT_IN_MEMCMP:
- case BUILT_IN_BCMP:
- case BUILT_IN_BZERO:
- case BUILT_IN_INDEX:
- case BUILT_IN_RINDEX:
- case BUILT_IN_STRCHR:
- case BUILT_IN_STRRCHR:
- case BUILT_IN_STRLEN:
- case BUILT_IN_STRCPY:
- case BUILT_IN_STRNCPY:
- case BUILT_IN_STRNCMP:
- case BUILT_IN_STRSTR:
- case BUILT_IN_STRPBRK:
- case BUILT_IN_STRCAT:
- case BUILT_IN_STRNCAT:
- case BUILT_IN_STRSPN:
- case BUILT_IN_STRCSPN:
- case BUILT_IN_STRCMP:
- case BUILT_IN_FFS:
- case BUILT_IN_PUTCHAR:
- case BUILT_IN_PUTS:
- case BUILT_IN_PRINTF:
- case BUILT_IN_FPUTC:
- case BUILT_IN_FPUTS:
- case BUILT_IN_FWRITE:
- case BUILT_IN_PUTCHAR_UNLOCKED:
- case BUILT_IN_PUTS_UNLOCKED:
- case BUILT_IN_PRINTF_UNLOCKED:
- case BUILT_IN_FPUTC_UNLOCKED:
- case BUILT_IN_FPUTS_UNLOCKED:
- case BUILT_IN_FWRITE_UNLOCKED:
- return expand_call (exp, target, ignore);
+ if (!optimize
+ && !CALLED_AS_BUILT_IN (fndecl)
+ && DECL_ASSEMBLER_NAME_SET_P (fndecl)
+ && fcode != BUILT_IN_ALLOCA)
+ return expand_call (exp, target, ignore);
+
+ /* The built-in function expanders test for target == const0_rtx
+ to determine whether the function's result will be ignored. */
+ if (ignore)
+ target = const0_rtx;
+
+ /* If the result of a pure or const built-in function is ignored, and
+ none of its arguments are volatile, we can avoid expanding the
+ built-in call and just evaluate the arguments for side-effects. */
+ if (target == const0_rtx
+ && (DECL_IS_PURE (fndecl) || TREE_READONLY (fndecl)))
+ {
+ bool volatilep = false;
+ tree arg;
- default:
- break;
- }
+ for (arg = arglist; arg; arg = TREE_CHAIN (arg))
+ if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
+ {
+ volatilep = true;
+ break;
+ }
+
+ if (! volatilep)
+ {
+ for (arg = arglist; arg; arg = TREE_CHAIN (arg))
+ expand_expr (TREE_VALUE (arg), const0_rtx,
+ VOIDmode, EXPAND_NORMAL);
+ return const0_rtx;
+ }
+ }
switch (fcode)
{
@@ -3864,11 +4986,27 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_LABS:
case BUILT_IN_LLABS:
case BUILT_IN_IMAXABS:
+ /* build_function_call changes these into ABS_EXPR. */
+ abort ();
+
case BUILT_IN_FABS:
case BUILT_IN_FABSF:
case BUILT_IN_FABSL:
- /* build_function_call changes these into ABS_EXPR. */
- abort ();
+ target = expand_builtin_fabs (arglist, target, subtarget);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_CABS:
+ case BUILT_IN_CABSF:
+ case BUILT_IN_CABSL:
+ if (flag_unsafe_math_optimizations)
+ {
+ target = expand_builtin_cabs (arglist, target);
+ if (target)
+ return target;
+ }
+ break;
case BUILT_IN_CONJ:
case BUILT_IN_CONJF:
@@ -3895,6 +5033,12 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_LOG:
case BUILT_IN_LOGF:
case BUILT_IN_LOGL:
+ case BUILT_IN_TAN:
+ case BUILT_IN_TANF:
+ case BUILT_IN_TANL:
+ case BUILT_IN_ATAN:
+ case BUILT_IN_ATANF:
+ case BUILT_IN_ATANL:
/* Treat these like sqrt only if unsafe math optimizations are allowed,
because of possible accuracy problems. */
if (! flag_unsafe_math_optimizations)
@@ -3902,11 +5046,46 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_SQRT:
case BUILT_IN_SQRTF:
case BUILT_IN_SQRTL:
+ case BUILT_IN_FLOOR:
+ case BUILT_IN_FLOORF:
+ case BUILT_IN_FLOORL:
+ case BUILT_IN_CEIL:
+ case BUILT_IN_CEILF:
+ case BUILT_IN_CEILL:
+ case BUILT_IN_TRUNC:
+ case BUILT_IN_TRUNCF:
+ case BUILT_IN_TRUNCL:
+ case BUILT_IN_ROUND:
+ case BUILT_IN_ROUNDF:
+ case BUILT_IN_ROUNDL:
+ case BUILT_IN_NEARBYINT:
+ case BUILT_IN_NEARBYINTF:
+ case BUILT_IN_NEARBYINTL:
target = expand_builtin_mathfn (exp, target, subtarget);
if (target)
return target;
break;
+ case BUILT_IN_POW:
+ case BUILT_IN_POWF:
+ case BUILT_IN_POWL:
+ if (! flag_unsafe_math_optimizations)
+ break;
+ target = expand_builtin_pow (exp, target, subtarget);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_ATAN2:
+ case BUILT_IN_ATAN2F:
+ case BUILT_IN_ATAN2L:
+ if (! flag_unsafe_math_optimizations)
+ break;
+ target = expand_builtin_mathfn_2 (exp, target, subtarget);
+ if (target)
+ return target;
+ break;
+
case BUILT_IN_APPLY_ARGS:
return expand_builtin_apply_args ();
@@ -3951,7 +5130,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
return expand_builtin_saveregs ();
case BUILT_IN_ARGS_INFO:
- return expand_builtin_args_info (exp);
+ return expand_builtin_args_info (arglist);
/* Return the address of the first anonymous stack arg. */
case BUILT_IN_NEXT_ARG:
@@ -3961,11 +5140,11 @@ expand_builtin (exp, target, subtarget, mode, ignore)
return expand_builtin_classify_type (arglist);
case BUILT_IN_CONSTANT_P:
- return expand_builtin_constant_p (exp);
+ return expand_builtin_constant_p (arglist, target_mode);
case BUILT_IN_FRAME_ADDRESS:
case BUILT_IN_RETURN_ADDRESS:
- return expand_builtin_frame_address (exp);
+ return expand_builtin_frame_address (fndecl, arglist);
/* Returns the address of the area where the structure is returned.
0 otherwise. */
@@ -3984,19 +5163,58 @@ expand_builtin (exp, target, subtarget, mode, ignore)
break;
case BUILT_IN_FFS:
- target = expand_builtin_ffs (arglist, target, subtarget);
+ case BUILT_IN_FFSL:
+ case BUILT_IN_FFSLL:
+ target = expand_builtin_unop (target_mode, arglist, target,
+ subtarget, ffs_optab);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_CLZ:
+ case BUILT_IN_CLZL:
+ case BUILT_IN_CLZLL:
+ target = expand_builtin_unop (target_mode, arglist, target,
+ subtarget, clz_optab);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_CTZ:
+ case BUILT_IN_CTZL:
+ case BUILT_IN_CTZLL:
+ target = expand_builtin_unop (target_mode, arglist, target,
+ subtarget, ctz_optab);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_POPCOUNT:
+ case BUILT_IN_POPCOUNTL:
+ case BUILT_IN_POPCOUNTLL:
+ target = expand_builtin_unop (target_mode, arglist, target,
+ subtarget, popcount_optab);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_PARITY:
+ case BUILT_IN_PARITYL:
+ case BUILT_IN_PARITYLL:
+ target = expand_builtin_unop (target_mode, arglist, target,
+ subtarget, parity_optab);
if (target)
return target;
break;
case BUILT_IN_STRLEN:
- target = expand_builtin_strlen (exp, target);
+ target = expand_builtin_strlen (arglist, target, target_mode);
if (target)
return target;
break;
case BUILT_IN_STRCPY:
- target = expand_builtin_strcpy (exp, target, mode);
+ target = expand_builtin_strcpy (arglist, target, mode);
if (target)
return target;
break;
@@ -4007,6 +5225,12 @@ expand_builtin (exp, target, subtarget, mode, ignore)
return target;
break;
+ case BUILT_IN_STPCPY:
+ target = expand_builtin_stpcpy (arglist, target, mode);
+ if (target)
+ return target;
+ break;
+
case BUILT_IN_STRCAT:
target = expand_builtin_strcat (arglist, target, mode);
if (target)
@@ -4063,14 +5287,32 @@ expand_builtin (exp, target, subtarget, mode, ignore)
return target;
break;
+ case BUILT_IN_MEMPCPY:
+ target = expand_builtin_mempcpy (arglist, target, mode, /*endp=*/ 1);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_MEMMOVE:
+ target = expand_builtin_memmove (arglist, target, mode);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_BCOPY:
+ target = expand_builtin_bcopy (arglist);
+ if (target)
+ return target;
+ break;
+
case BUILT_IN_MEMSET:
- target = expand_builtin_memset (exp, target, mode);
+ target = expand_builtin_memset (arglist, target, mode);
if (target)
return target;
break;
case BUILT_IN_BZERO:
- target = expand_builtin_bzero (exp);
+ target = expand_builtin_bzero (arglist);
if (target)
return target;
break;
@@ -4127,13 +5369,44 @@ expand_builtin (exp, target, subtarget, mode, ignore)
expand_builtin_trap ();
return const0_rtx;
+ case BUILT_IN_PRINTF:
+ target = expand_builtin_printf (arglist, target, mode, false);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_PRINTF_UNLOCKED:
+ target = expand_builtin_printf (arglist, target, mode, true);
+ if (target)
+ return target;
+ break;
+
case BUILT_IN_FPUTS:
- target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 0);
+ target = expand_builtin_fputs (arglist, target, false);
if (target)
return target;
break;
+
case BUILT_IN_FPUTS_UNLOCKED:
- target = expand_builtin_fputs (arglist, ignore,/*unlocked=*/ 1);
+ target = expand_builtin_fputs (arglist, target, true);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_FPRINTF:
+ target = expand_builtin_fprintf (arglist, target, mode, false);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_FPRINTF_UNLOCKED:
+ target = expand_builtin_fprintf (arglist, target, mode, true);
+ if (target)
+ return target;
+ break;
+
+ case BUILT_IN_SPRINTF:
+ target = expand_builtin_sprintf (arglist, target, mode);
if (target)
return target;
break;
@@ -4163,6 +5436,9 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_EH_RETURN_DATA_REGNO:
return expand_builtin_eh_return_data_regno (arglist);
#endif
+ case BUILT_IN_EXTEND_POINTER:
+ return expand_builtin_extend_pointer (TREE_VALUE (arglist));
+
case BUILT_IN_VA_START:
case BUILT_IN_STDARG_START:
return expand_builtin_va_start (arglist);
@@ -4188,12 +5464,83 @@ expand_builtin (exp, target, subtarget, mode, ignore)
return expand_call (exp, target, ignore);
}
+/* Determine whether a tree node represents a call to a built-in
+ function. If the tree T is a call to a built-in function with
+ the right number of arguments of the appropriate types, return
+ the DECL_FUNCTION_CODE of the call, e.g. BUILT_IN_SQRT.
+ Otherwise the return value is END_BUILTINS. */
+
+enum built_in_function
+builtin_mathfn_code (tree t)
+{
+ tree fndecl, arglist, parmlist;
+ tree argtype, parmtype;
+
+ if (TREE_CODE (t) != CALL_EXPR
+ || TREE_CODE (TREE_OPERAND (t, 0)) != ADDR_EXPR)
+ return END_BUILTINS;
+
+ fndecl = get_callee_fndecl (t);
+ if (fndecl == NULL_TREE
+ || TREE_CODE (fndecl) != FUNCTION_DECL
+ || ! DECL_BUILT_IN (fndecl)
+ || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
+ return END_BUILTINS;
+
+ arglist = TREE_OPERAND (t, 1);
+ parmlist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
+ for (; parmlist; parmlist = TREE_CHAIN (parmlist))
+ {
+ /* If a function doesn't take a variable number of arguments,
+ the last element in the list will have type `void'. */
+ parmtype = TREE_VALUE (parmlist);
+ if (VOID_TYPE_P (parmtype))
+ {
+ if (arglist)
+ return END_BUILTINS;
+ return DECL_FUNCTION_CODE (fndecl);
+ }
+
+ if (! arglist)
+ return END_BUILTINS;
+
+ argtype = TREE_TYPE (TREE_VALUE (arglist));
+
+ if (SCALAR_FLOAT_TYPE_P (parmtype))
+ {
+ if (! SCALAR_FLOAT_TYPE_P (argtype))
+ return END_BUILTINS;
+ }
+ else if (COMPLEX_FLOAT_TYPE_P (parmtype))
+ {
+ if (! COMPLEX_FLOAT_TYPE_P (argtype))
+ return END_BUILTINS;
+ }
+ else if (POINTER_TYPE_P (parmtype))
+ {
+ if (! POINTER_TYPE_P (argtype))
+ return END_BUILTINS;
+ }
+ else if (INTEGRAL_TYPE_P (parmtype))
+ {
+ if (! INTEGRAL_TYPE_P (argtype))
+ return END_BUILTINS;
+ }
+ else
+ return END_BUILTINS;
+
+ arglist = TREE_CHAIN (arglist);
+ }
+
+ /* Variable-length argument list. */
+ return DECL_FUNCTION_CODE (fndecl);
+}
+
/* Fold a call to __builtin_constant_p, if we know it will evaluate to a
constant. ARGLIST is the argument list of the call. */
static tree
-fold_builtin_constant_p (arglist)
- tree arglist;
+fold_builtin_constant_p (tree arglist)
{
if (arglist == 0)
return 0;
@@ -4213,15 +5560,14 @@ fold_builtin_constant_p (arglist)
&& TREE_CODE (TREE_OPERAND (arglist, 0)) == STRING_CST))
return integer_one_node;
- /* If we aren't going to be running CSE or this expression
- has side effects, show we don't know it to be a constant.
- Likewise if it's a pointer or aggregate type since in those
- case we only want literals, since those are only optimized
+ /* If this expression has side effects, show we don't know it to be a
+ constant. Likewise if it's a pointer or aggregate type since in
+ those case we only want literals, since those are only optimized
when generating RTL, not later.
And finally, if we are compiling an initializer, not code, we
need to return a definite result now; there's not going to be any
more optimization done. */
- if (TREE_SIDE_EFFECTS (arglist) || cse_not_expected
+ if (TREE_SIDE_EFFECTS (arglist)
|| AGGREGATE_TYPE_P (TREE_TYPE (arglist))
|| POINTER_TYPE_P (TREE_TYPE (arglist))
|| cfun == 0)
@@ -4233,8 +5579,7 @@ fold_builtin_constant_p (arglist)
/* Fold a call to __builtin_classify_type. */
static tree
-fold_builtin_classify_type (arglist)
- tree arglist;
+fold_builtin_classify_type (tree arglist)
{
if (arglist == 0)
return build_int_2 (no_type_class, 0);
@@ -4245,9 +5590,7 @@ fold_builtin_classify_type (arglist)
/* Fold a call to __builtin_inf or __builtin_huge_val. */
static tree
-fold_builtin_inf (type, warn)
- tree type;
- int warn;
+fold_builtin_inf (tree type, int warn)
{
REAL_VALUE_TYPE real;
@@ -4261,9 +5604,7 @@ fold_builtin_inf (type, warn)
/* Fold a call to __builtin_nan or __builtin_nans. */
static tree
-fold_builtin_nan (arglist, type, quiet)
- tree arglist, type;
- int quiet;
+fold_builtin_nan (tree arglist, tree type, int quiet)
{
REAL_VALUE_TYPE real;
const char *str;
@@ -4280,21 +5621,898 @@ fold_builtin_nan (arglist, type, quiet)
return build_real (type, real);
}
+/* Return true if the floating point expression T has an integer value.
+ We also allow +Inf, -Inf and NaN to be considered integer values. */
+
+static bool
+integer_valued_real_p (tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case FLOAT_EXPR:
+ return true;
+
+ case ABS_EXPR:
+ case SAVE_EXPR:
+ case NON_LVALUE_EXPR:
+ return integer_valued_real_p (TREE_OPERAND (t, 0));
+
+ case COMPOUND_EXPR:
+ case MODIFY_EXPR:
+ case BIND_EXPR:
+ return integer_valued_real_p (TREE_OPERAND (t, 1));
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case MIN_EXPR:
+ case MAX_EXPR:
+ return integer_valued_real_p (TREE_OPERAND (t, 0))
+ && integer_valued_real_p (TREE_OPERAND (t, 1));
+
+ case COND_EXPR:
+ return integer_valued_real_p (TREE_OPERAND (t, 1))
+ && integer_valued_real_p (TREE_OPERAND (t, 2));
+
+ case REAL_CST:
+ if (! TREE_CONSTANT_OVERFLOW (t))
+ {
+ REAL_VALUE_TYPE c, cint;
+
+ c = TREE_REAL_CST (t);
+ real_trunc (&cint, TYPE_MODE (TREE_TYPE (t)), &c);
+ return real_identical (&c, &cint);
+ }
+
+ case NOP_EXPR:
+ {
+ tree type = TREE_TYPE (TREE_OPERAND (t, 0));
+ if (TREE_CODE (type) == INTEGER_TYPE)
+ return true;
+ if (TREE_CODE (type) == REAL_TYPE)
+ return integer_valued_real_p (TREE_OPERAND (t, 0));
+ break;
+ }
+
+ case CALL_EXPR:
+ switch (builtin_mathfn_code (t))
+ {
+ case BUILT_IN_CEIL:
+ case BUILT_IN_CEILF:
+ case BUILT_IN_CEILL:
+ case BUILT_IN_FLOOR:
+ case BUILT_IN_FLOORF:
+ case BUILT_IN_FLOORL:
+ case BUILT_IN_NEARBYINT:
+ case BUILT_IN_NEARBYINTF:
+ case BUILT_IN_NEARBYINTL:
+ case BUILT_IN_ROUND:
+ case BUILT_IN_ROUNDF:
+ case BUILT_IN_ROUNDL:
+ case BUILT_IN_TRUNC:
+ case BUILT_IN_TRUNCF:
+ case BUILT_IN_TRUNCL:
+ return true;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return false;
+}
+
+/* EXP is assumed to be builtin call where truncation can be propagated
+ across (for instance floor((double)f) == (double)floorf (f).
+ Do the transformation. */
+
+static tree
+fold_trunc_transparent_mathfn (tree exp)
+{
+ tree fndecl = get_callee_fndecl (exp);
+ tree arglist = TREE_OPERAND (exp, 1);
+ enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+ tree arg;
+
+ if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ return 0;
+
+ arg = TREE_VALUE (arglist);
+ /* Integer rounding functions are idempotent. */
+ if (fcode == builtin_mathfn_code (arg))
+ return arg;
+
+ /* If argument is already integer valued, and we don't need to worry
+ about setting errno, there's no need to perform rounding. */
+ if (! flag_errno_math && integer_valued_real_p (arg))
+ return arg;
+
+ if (optimize)
+ {
+ tree arg0 = strip_float_extensions (arg);
+ tree ftype = TREE_TYPE (exp);
+ tree newtype = TREE_TYPE (arg0);
+ tree decl;
+
+ if (TYPE_PRECISION (newtype) < TYPE_PRECISION (ftype)
+ && (decl = mathfn_built_in (newtype, fcode)))
+ {
+ arglist =
+ build_tree_list (NULL_TREE, fold (convert (newtype, arg0)));
+ return convert (ftype,
+ build_function_call_expr (decl, arglist));
+ }
+ }
+ return 0;
+}
+
+/* Fold function call to builtin cabs, cabsf or cabsl. FNDECL is the
+ function's DECL, ARGLIST is the argument list and TYPE is the return
+ type. Return NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_cabs (tree fndecl, tree arglist, tree type)
+{
+ tree arg;
+
+ if (!arglist || TREE_CHAIN (arglist))
+ return NULL_TREE;
+
+ arg = TREE_VALUE (arglist);
+ if (TREE_CODE (TREE_TYPE (arg)) != COMPLEX_TYPE
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != REAL_TYPE)
+ return NULL_TREE;
+
+ /* Evaluate cabs of a constant at compile-time. */
+ if (flag_unsafe_math_optimizations
+ && TREE_CODE (arg) == COMPLEX_CST
+ && TREE_CODE (TREE_REALPART (arg)) == REAL_CST
+ && TREE_CODE (TREE_IMAGPART (arg)) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (TREE_REALPART (arg))
+ && ! TREE_CONSTANT_OVERFLOW (TREE_IMAGPART (arg)))
+ {
+ REAL_VALUE_TYPE r, i;
+
+ r = TREE_REAL_CST (TREE_REALPART (arg));
+ i = TREE_REAL_CST (TREE_IMAGPART (arg));
+
+ real_arithmetic (&r, MULT_EXPR, &r, &r);
+ real_arithmetic (&i, MULT_EXPR, &i, &i);
+ real_arithmetic (&r, PLUS_EXPR, &r, &i);
+ if (real_sqrt (&r, TYPE_MODE (type), &r)
+ || ! flag_trapping_math)
+ return build_real (type, r);
+ }
+
+ /* If either part is zero, cabs is fabs of the other. */
+ if (TREE_CODE (arg) == COMPLEX_EXPR
+ && real_zerop (TREE_OPERAND (arg, 0)))
+ return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 1)));
+ if (TREE_CODE (arg) == COMPLEX_EXPR
+ && real_zerop (TREE_OPERAND (arg, 1)))
+ return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg, 0)));
+
+ if (flag_unsafe_math_optimizations)
+ {
+ enum built_in_function fcode;
+ tree sqrtfn;
+
+ fcode = DECL_FUNCTION_CODE (fndecl);
+ if (fcode == BUILT_IN_CABS)
+ sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
+ else if (fcode == BUILT_IN_CABSF)
+ sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
+ else if (fcode == BUILT_IN_CABSL)
+ sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
+ else
+ sqrtfn = NULL_TREE;
+
+ if (sqrtfn != NULL_TREE)
+ {
+ tree rpart, ipart, result, arglist;
+
+ arg = save_expr (arg);
+
+ rpart = fold (build1 (REALPART_EXPR, type, arg));
+ ipart = fold (build1 (IMAGPART_EXPR, type, arg));
+
+ rpart = save_expr (rpart);
+ ipart = save_expr (ipart);
+
+ result = fold (build (PLUS_EXPR, type,
+ fold (build (MULT_EXPR, type,
+ rpart, rpart)),
+ fold (build (MULT_EXPR, type,
+ ipart, ipart))));
+
+ arglist = build_tree_list (NULL_TREE, result);
+ return build_function_call_expr (sqrtfn, arglist);
+ }
+ }
+
+ return NULL_TREE;
+}
+
+/* Fold function call to builtin trunc, truncf or truncl. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_trunc (tree exp)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree arg;
+
+ if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ return 0;
+
+ /* Optimize trunc of constant value. */
+ arg = TREE_VALUE (arglist);
+ if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
+ {
+ REAL_VALUE_TYPE r, x;
+ tree type = TREE_TYPE (exp);
+
+ x = TREE_REAL_CST (arg);
+ real_trunc (&r, TYPE_MODE (type), &x);
+ return build_real (type, r);
+ }
+
+ return fold_trunc_transparent_mathfn (exp);
+}
+
+/* Fold function call to builtin floor, floorf or floorl. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_floor (tree exp)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree arg;
+
+ if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ return 0;
+
+ /* Optimize floor of constant value. */
+ arg = TREE_VALUE (arglist);
+ if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
+ {
+ REAL_VALUE_TYPE x;
+
+ x = TREE_REAL_CST (arg);
+ if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
+ {
+ tree type = TREE_TYPE (exp);
+ REAL_VALUE_TYPE r;
+
+ real_floor (&r, TYPE_MODE (type), &x);
+ return build_real (type, r);
+ }
+ }
+
+ return fold_trunc_transparent_mathfn (exp);
+}
+
+/* Fold function call to builtin ceil, ceilf or ceill. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_ceil (tree exp)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree arg;
+
+ if (! validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ return 0;
+
+ /* Optimize ceil of constant value. */
+ arg = TREE_VALUE (arglist);
+ if (TREE_CODE (arg) == REAL_CST && ! TREE_CONSTANT_OVERFLOW (arg))
+ {
+ REAL_VALUE_TYPE x;
+
+ x = TREE_REAL_CST (arg);
+ if (! REAL_VALUE_ISNAN (x) || ! flag_errno_math)
+ {
+ tree type = TREE_TYPE (exp);
+ REAL_VALUE_TYPE r;
+
+ real_ceil (&r, TYPE_MODE (type), &x);
+ return build_real (type, r);
+ }
+ }
+
+ return fold_trunc_transparent_mathfn (exp);
+}
+
+/* Fold function call to builtin ffs, clz, ctz, popcount and parity
+ and their long and long long variants (i.e. ffsl and ffsll).
+ Return NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_bitop (tree exp)
+{
+ tree fndecl = get_callee_fndecl (exp);
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree arg;
+
+ if (! validate_arglist (arglist, INTEGER_TYPE, VOID_TYPE))
+ return NULL_TREE;
+
+ /* Optimize for constant argument. */
+ arg = TREE_VALUE (arglist);
+ if (TREE_CODE (arg) == INTEGER_CST && ! TREE_CONSTANT_OVERFLOW (arg))
+ {
+ HOST_WIDE_INT hi, width, result;
+ unsigned HOST_WIDE_INT lo;
+ tree type, t;
+
+ type = TREE_TYPE (arg);
+ width = TYPE_PRECISION (type);
+ lo = TREE_INT_CST_LOW (arg);
+
+ /* Clear all the bits that are beyond the type's precision. */
+ if (width > HOST_BITS_PER_WIDE_INT)
+ {
+ hi = TREE_INT_CST_HIGH (arg);
+ if (width < 2 * HOST_BITS_PER_WIDE_INT)
+ hi &= ~((HOST_WIDE_INT) (-1) >> (width - HOST_BITS_PER_WIDE_INT));
+ }
+ else
+ {
+ hi = 0;
+ if (width < HOST_BITS_PER_WIDE_INT)
+ lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
+ }
+
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_FFS:
+ case BUILT_IN_FFSL:
+ case BUILT_IN_FFSLL:
+ if (lo != 0)
+ result = exact_log2 (lo & -lo) + 1;
+ else if (hi != 0)
+ result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi) + 1;
+ else
+ result = 0;
+ break;
+
+ case BUILT_IN_CLZ:
+ case BUILT_IN_CLZL:
+ case BUILT_IN_CLZLL:
+ if (hi != 0)
+ result = width - floor_log2 (hi) - 1 - HOST_BITS_PER_WIDE_INT;
+ else if (lo != 0)
+ result = width - floor_log2 (lo) - 1;
+ else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
+ result = width;
+ break;
+
+ case BUILT_IN_CTZ:
+ case BUILT_IN_CTZL:
+ case BUILT_IN_CTZLL:
+ if (lo != 0)
+ result = exact_log2 (lo & -lo);
+ else if (hi != 0)
+ result = HOST_BITS_PER_WIDE_INT + exact_log2 (hi & -hi);
+ else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
+ result = width;
+ break;
+
+ case BUILT_IN_POPCOUNT:
+ case BUILT_IN_POPCOUNTL:
+ case BUILT_IN_POPCOUNTLL:
+ result = 0;
+ while (lo)
+ result++, lo &= lo - 1;
+ while (hi)
+ result++, hi &= hi - 1;
+ break;
+
+ case BUILT_IN_PARITY:
+ case BUILT_IN_PARITYL:
+ case BUILT_IN_PARITYLL:
+ result = 0;
+ while (lo)
+ result++, lo &= lo - 1;
+ while (hi)
+ result++, hi &= hi - 1;
+ result &= 1;
+ break;
+
+ default:
+ abort();
+ }
+
+ t = build_int_2 (result, 0);
+ TREE_TYPE (t) = TREE_TYPE (exp);
+ return t;
+ }
+
+ return NULL_TREE;
+}
+
+/* Return true if EXPR is the real constant contained in VALUE. */
+
+static bool
+real_dconstp (tree expr, const REAL_VALUE_TYPE *value)
+{
+ STRIP_NOPS (expr);
+
+ return ((TREE_CODE (expr) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (expr)
+ && REAL_VALUES_EQUAL (TREE_REAL_CST (expr), *value))
+ || (TREE_CODE (expr) == COMPLEX_CST
+ && real_dconstp (TREE_REALPART (expr), value)
+ && real_zerop (TREE_IMAGPART (expr))));
+}
+
+/* A subroutine of fold_builtin to fold the various logarithmic
+ functions. EXP is the CALL_EXPR of a call to a builtin log*
+ function. VALUE is the base of the log* function. */
+
+static tree
+fold_builtin_logarithm (tree exp, const REAL_VALUE_TYPE *value)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+
+ if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ {
+ tree fndecl = get_callee_fndecl (exp);
+ tree type = TREE_TYPE (TREE_TYPE (fndecl));
+ tree arg = TREE_VALUE (arglist);
+ const enum built_in_function fcode = builtin_mathfn_code (arg);
+
+ /* Optimize log*(1.0) = 0.0. */
+ if (real_onep (arg))
+ return build_real (type, dconst0);
+
+ /* Optimize logN(N) = 1.0. If N can't be truncated to MODE
+ exactly, then only do this if flag_unsafe_math_optimizations. */
+ if (exact_real_truncate (TYPE_MODE (type), value)
+ || flag_unsafe_math_optimizations)
+ {
+ const REAL_VALUE_TYPE value_truncate =
+ real_value_truncate (TYPE_MODE (type), *value);
+ if (real_dconstp (arg, &value_truncate))
+ return build_real (type, dconst1);
+ }
+
+ /* Special case, optimize logN(expN(x)) = x. */
+ if (flag_unsafe_math_optimizations
+ && ((value == &dconste
+ && (fcode == BUILT_IN_EXP
+ || fcode == BUILT_IN_EXPF
+ || fcode == BUILT_IN_EXPL))
+ || (value == &dconst2
+ && (fcode == BUILT_IN_EXP2
+ || fcode == BUILT_IN_EXP2F
+ || fcode == BUILT_IN_EXP2L))
+ || (value == &dconst10
+ && (fcode == BUILT_IN_EXP10
+ || fcode == BUILT_IN_EXP10F
+ || fcode == BUILT_IN_EXP10L))))
+ return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
+
+ /* Optimize log*(func()) for various exponential functions. We
+ want to determine the value "x" and the power "exponent" in
+ order to transform logN(x**exponent) into exponent*logN(x). */
+ if (flag_unsafe_math_optimizations)
+ {
+ tree exponent = 0, x = 0;
+
+ switch (fcode)
+ {
+ case BUILT_IN_EXP:
+ case BUILT_IN_EXPF:
+ case BUILT_IN_EXPL:
+ /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */
+ x = build_real (type,
+ real_value_truncate (TYPE_MODE (type), dconste));
+ exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
+ break;
+ case BUILT_IN_EXP2:
+ case BUILT_IN_EXP2F:
+ case BUILT_IN_EXP2L:
+ /* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
+ x = build_real (type, dconst2);
+ exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
+ break;
+ case BUILT_IN_EXP10:
+ case BUILT_IN_EXP10F:
+ case BUILT_IN_EXP10L:
+ case BUILT_IN_POW10:
+ case BUILT_IN_POW10F:
+ case BUILT_IN_POW10L:
+ /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */
+ x = build_real (type, dconst10);
+ exponent = TREE_VALUE (TREE_OPERAND (arg, 1));
+ break;
+ case BUILT_IN_SQRT:
+ case BUILT_IN_SQRTF:
+ case BUILT_IN_SQRTL:
+ /* Prepare to do logN(sqrt(x) -> 0.5*logN(x). */
+ x = TREE_VALUE (TREE_OPERAND (arg, 1));
+ exponent = build_real (type, dconsthalf);
+ break;
+ case BUILT_IN_CBRT:
+ case BUILT_IN_CBRTF:
+ case BUILT_IN_CBRTL:
+ /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */
+ x = TREE_VALUE (TREE_OPERAND (arg, 1));
+ exponent = build_real (type, real_value_truncate (TYPE_MODE (type),
+ dconstthird));
+ break;
+ case BUILT_IN_POW:
+ case BUILT_IN_POWF:
+ case BUILT_IN_POWL:
+ /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
+ x = TREE_VALUE (TREE_OPERAND (arg, 1));
+ exponent = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
+ break;
+ default:
+ break;
+ }
+
+ /* Now perform the optimization. */
+ if (x && exponent)
+ {
+ tree logfn;
+ arglist = build_tree_list (NULL_TREE, x);
+ logfn = build_function_call_expr (fndecl, arglist);
+ return fold (build (MULT_EXPR, type, exponent, logfn));
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* A subroutine of fold_builtin to fold the various exponent
+ functions. EXP is the CALL_EXPR of a call to a builtin function.
+ VALUE is the value which will be raised to a power. */
+
+static tree
+fold_builtin_exponent (tree exp, const REAL_VALUE_TYPE *value)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+
+ if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ {
+ tree fndecl = get_callee_fndecl (exp);
+ tree type = TREE_TYPE (TREE_TYPE (fndecl));
+ tree arg = TREE_VALUE (arglist);
+
+ /* Optimize exp*(0.0) = 1.0. */
+ if (real_zerop (arg))
+ return build_real (type, dconst1);
+
+ /* Optimize expN(1.0) = N. */
+ if (real_onep (arg))
+ {
+ REAL_VALUE_TYPE cst;
+
+ real_convert (&cst, TYPE_MODE (type), value);
+ return build_real (type, cst);
+ }
+
+ /* Attempt to evaluate expN(integer) at compile-time. */
+ if (flag_unsafe_math_optimizations
+ && TREE_CODE (arg) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (arg))
+ {
+ REAL_VALUE_TYPE cint;
+ REAL_VALUE_TYPE c;
+ HOST_WIDE_INT n;
+
+ c = TREE_REAL_CST (arg);
+ n = real_to_integer (&c);
+ real_from_integer (&cint, VOIDmode, n,
+ n < 0 ? -1 : 0, 0);
+ if (real_identical (&c, &cint))
+ {
+ REAL_VALUE_TYPE x;
+
+ real_powi (&x, TYPE_MODE (type), value, n);
+ return build_real (type, x);
+ }
+ }
+
+ /* Optimize expN(logN(x)) = x. */
+ if (flag_unsafe_math_optimizations)
+ {
+ const enum built_in_function fcode = builtin_mathfn_code (arg);
+
+ if ((value == &dconste
+ && (fcode == BUILT_IN_LOG
+ || fcode == BUILT_IN_LOGF
+ || fcode == BUILT_IN_LOGL))
+ || (value == &dconst2
+ && (fcode == BUILT_IN_LOG2
+ || fcode == BUILT_IN_LOG2F
+ || fcode == BUILT_IN_LOG2L))
+ || (value == &dconst10
+ && (fcode == BUILT_IN_LOG10
+ || fcode == BUILT_IN_LOG10F
+ || fcode == BUILT_IN_LOG10L)))
+ return convert (type, TREE_VALUE (TREE_OPERAND (arg, 1)));
+ }
+ }
+
+ return 0;
+}
+
+/* Fold function call to builtin memcpy. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_memcpy (tree exp)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree dest, src, len;
+
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+
+ dest = TREE_VALUE (arglist);
+ src = TREE_VALUE (TREE_CHAIN (arglist));
+ len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+
+ /* If the LEN parameter is zero, return DEST. */
+ if (integer_zerop (len))
+ return omit_one_operand (TREE_TYPE (exp), dest, src);
+
+ /* If SRC and DEST are the same (and not volatile), return DEST. */
+ if (operand_equal_p (src, dest, 0))
+ return omit_one_operand (TREE_TYPE (exp), dest, len);
+
+ return 0;
+}
+
+/* Fold function call to builtin mempcpy. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_mempcpy (tree exp)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree dest, src, len;
+
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+
+ dest = TREE_VALUE (arglist);
+ src = TREE_VALUE (TREE_CHAIN (arglist));
+ len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+
+ /* If the LEN parameter is zero, return DEST. */
+ if (integer_zerop (len))
+ return omit_one_operand (TREE_TYPE (exp), dest, src);
+
+ /* If SRC and DEST are the same (and not volatile), return DEST+LEN. */
+ if (operand_equal_p (src, dest, 0))
+ {
+ tree temp = convert (TREE_TYPE (dest), len);
+ temp = fold (build (PLUS_EXPR, TREE_TYPE (dest), dest, len));
+ return convert (TREE_TYPE (exp), temp);
+ }
+
+ return 0;
+}
+
+/* Fold function call to builtin memmove. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_memmove (tree exp)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree dest, src, len;
+
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+
+ dest = TREE_VALUE (arglist);
+ src = TREE_VALUE (TREE_CHAIN (arglist));
+ len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+
+ /* If the LEN parameter is zero, return DEST. */
+ if (integer_zerop (len))
+ return omit_one_operand (TREE_TYPE (exp), dest, src);
+
+ /* If SRC and DEST are the same (and not volatile), return DEST. */
+ if (operand_equal_p (src, dest, 0))
+ return omit_one_operand (TREE_TYPE (exp), dest, len);
+
+ return 0;
+}
+
+/* Fold function call to builtin strcpy. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_strcpy (tree exp)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree dest, src;
+
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return 0;
+
+ dest = TREE_VALUE (arglist);
+ src = TREE_VALUE (TREE_CHAIN (arglist));
+
+ /* If SRC and DEST are the same (and not volatile), return DEST. */
+ if (operand_equal_p (src, dest, 0))
+ return convert (TREE_TYPE (exp), dest);
+
+ return 0;
+}
+
+/* Fold function call to builtin strncpy. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_strncpy (tree exp)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree dest, src, len;
+
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+
+ dest = TREE_VALUE (arglist);
+ src = TREE_VALUE (TREE_CHAIN (arglist));
+ len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+
+ /* If the LEN parameter is zero, return DEST. */
+ if (integer_zerop (len))
+ return omit_one_operand (TREE_TYPE (exp), dest, src);
+
+ return 0;
+}
+
+/* Fold function call to builtin memcmp. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_memcmp (tree exp)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree arg1, arg2, len;
+
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+
+ arg1 = TREE_VALUE (arglist);
+ arg2 = TREE_VALUE (TREE_CHAIN (arglist));
+ len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+
+ /* If the LEN parameter is zero, return zero. */
+ if (integer_zerop (len))
+ {
+ tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
+ return omit_one_operand (TREE_TYPE (exp), temp, arg1);
+ }
+
+ /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
+ if (operand_equal_p (arg1, arg2, 0))
+ return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
+
+ return 0;
+}
+
+/* Fold function call to builtin strcmp. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_strcmp (tree exp)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree arg1, arg2;
+ const char *p1, *p2;
+
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
+ return 0;
+
+ arg1 = TREE_VALUE (arglist);
+ arg2 = TREE_VALUE (TREE_CHAIN (arglist));
+
+ /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
+ if (operand_equal_p (arg1, arg2, 0))
+ return convert (TREE_TYPE (exp), integer_zero_node);
+
+ p1 = c_getstr (arg1);
+ p2 = c_getstr (arg2);
+
+ if (p1 && p2)
+ {
+ tree temp;
+ const int i = strcmp (p1, p2);
+ if (i < 0)
+ temp = integer_minus_one_node;
+ else if (i > 0)
+ temp = integer_one_node;
+ else
+ temp = integer_zero_node;
+ return convert (TREE_TYPE (exp), temp);
+ }
+
+ return 0;
+}
+
+/* Fold function call to builtin strncmp. Return
+ NULL_TREE if no simplification can be made. */
+
+static tree
+fold_builtin_strncmp (tree exp)
+{
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree arg1, arg2, len;
+ const char *p1, *p2;
+
+ if (!validate_arglist (arglist,
+ POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+ return 0;
+
+ arg1 = TREE_VALUE (arglist);
+ arg2 = TREE_VALUE (TREE_CHAIN (arglist));
+ len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+
+ /* If the LEN parameter is zero, return zero. */
+ if (integer_zerop (len))
+ {
+ tree temp = omit_one_operand (TREE_TYPE (exp), integer_zero_node, arg2);
+ return omit_one_operand (TREE_TYPE (exp), temp, arg1);
+ }
+
+ /* If ARG1 and ARG2 are the same (and not volatile), return zero. */
+ if (operand_equal_p (arg1, arg2, 0))
+ return omit_one_operand (TREE_TYPE (exp), integer_zero_node, len);
+
+ p1 = c_getstr (arg1);
+ p2 = c_getstr (arg2);
+
+ if (host_integerp (len, 1) && p1 && p2)
+ {
+ tree temp;
+ const int i = strncmp (p1, p2, tree_low_cst (len, 1));
+ if (i < 0)
+ temp = integer_minus_one_node;
+ else if (i > 0)
+ temp = integer_one_node;
+ else
+ temp = integer_zero_node;
+ return convert (TREE_TYPE (exp), temp);
+ }
+
+ return 0;
+}
+
/* Used by constant folding to eliminate some builtin calls early. EXP is
the CALL_EXPR of a call to a builtin function. */
tree
-fold_builtin (exp)
- tree exp;
+fold_builtin (tree exp)
{
- tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+ tree fndecl = get_callee_fndecl (exp);
tree arglist = TREE_OPERAND (exp, 1);
- enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
+ tree type = TREE_TYPE (TREE_TYPE (fndecl));
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
return 0;
- switch (fcode)
+ switch (DECL_FUNCTION_CODE (fndecl))
{
case BUILT_IN_CONSTANT_P:
return fold_builtin_constant_p (arglist);
@@ -4305,7 +6523,7 @@ fold_builtin (exp)
case BUILT_IN_STRLEN:
if (validate_arglist (arglist, POINTER_TYPE, VOID_TYPE))
{
- tree len = c_strlen (TREE_VALUE (arglist));
+ tree len = c_strlen (TREE_VALUE (arglist), 0);
if (len)
{
/* Convert from the internal "sizetype" type to "size_t". */
@@ -4316,25 +6534,389 @@ fold_builtin (exp)
}
break;
+ case BUILT_IN_FABS:
+ case BUILT_IN_FABSF:
+ case BUILT_IN_FABSL:
+ if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ return fold (build1 (ABS_EXPR, type, TREE_VALUE (arglist)));
+ break;
+
+ case BUILT_IN_CABS:
+ case BUILT_IN_CABSF:
+ case BUILT_IN_CABSL:
+ return fold_builtin_cabs (fndecl, arglist, type);
+
+ case BUILT_IN_SQRT:
+ case BUILT_IN_SQRTF:
+ case BUILT_IN_SQRTL:
+ if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ {
+ enum built_in_function fcode;
+ tree arg = TREE_VALUE (arglist);
+
+ /* Optimize sqrt of constant value. */
+ if (TREE_CODE (arg) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (arg))
+ {
+ REAL_VALUE_TYPE r, x;
+
+ x = TREE_REAL_CST (arg);
+ if (real_sqrt (&r, TYPE_MODE (type), &x)
+ || (!flag_trapping_math && !flag_errno_math))
+ return build_real (type, r);
+ }
+
+ /* Optimize sqrt(exp(x)) = exp(x*0.5). */
+ fcode = builtin_mathfn_code (arg);
+ if (flag_unsafe_math_optimizations
+ && (fcode == BUILT_IN_EXP
+ || fcode == BUILT_IN_EXPF
+ || fcode == BUILT_IN_EXPL))
+ {
+ tree expfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
+ arg = fold (build (MULT_EXPR, type,
+ TREE_VALUE (TREE_OPERAND (arg, 1)),
+ build_real (type, dconsthalf)));
+ arglist = build_tree_list (NULL_TREE, arg);
+ return build_function_call_expr (expfn, arglist);
+ }
+
+ /* Optimize sqrt(pow(x,y)) = pow(x,y*0.5). */
+ if (flag_unsafe_math_optimizations
+ && (fcode == BUILT_IN_POW
+ || fcode == BUILT_IN_POWF
+ || fcode == BUILT_IN_POWL))
+ {
+ tree powfn = TREE_OPERAND (TREE_OPERAND (arg, 0), 0);
+ tree arg0 = TREE_VALUE (TREE_OPERAND (arg, 1));
+ tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg, 1)));
+ tree narg1 = fold (build (MULT_EXPR, type, arg1,
+ build_real (type, dconsthalf)));
+ arglist = tree_cons (NULL_TREE, arg0,
+ build_tree_list (NULL_TREE, narg1));
+ return build_function_call_expr (powfn, arglist);
+ }
+ }
+ break;
+
+ case BUILT_IN_SIN:
+ case BUILT_IN_SINF:
+ case BUILT_IN_SINL:
+ if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ {
+ tree arg = TREE_VALUE (arglist);
+
+ /* Optimize sin(0.0) = 0.0. */
+ if (real_zerop (arg))
+ return arg;
+ }
+ break;
+
+ case BUILT_IN_COS:
+ case BUILT_IN_COSF:
+ case BUILT_IN_COSL:
+ if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ {
+ tree arg = TREE_VALUE (arglist);
+
+ /* Optimize cos(0.0) = 1.0. */
+ if (real_zerop (arg))
+ return build_real (type, dconst1);
+
+ /* Optimize cos(-x) into cos(x). */
+ if (TREE_CODE (arg) == NEGATE_EXPR)
+ {
+ tree arglist = build_tree_list (NULL_TREE,
+ TREE_OPERAND (arg, 0));
+ return build_function_call_expr (fndecl, arglist);
+ }
+ }
+ break;
+
+ case BUILT_IN_EXP:
+ case BUILT_IN_EXPF:
+ case BUILT_IN_EXPL:
+ return fold_builtin_exponent (exp, &dconste);
+ case BUILT_IN_EXP2:
+ case BUILT_IN_EXP2F:
+ case BUILT_IN_EXP2L:
+ return fold_builtin_exponent (exp, &dconst2);
+ case BUILT_IN_EXP10:
+ case BUILT_IN_EXP10F:
+ case BUILT_IN_EXP10L:
+ case BUILT_IN_POW10:
+ case BUILT_IN_POW10F:
+ case BUILT_IN_POW10L:
+ return fold_builtin_exponent (exp, &dconst10);
+ case BUILT_IN_LOG:
+ case BUILT_IN_LOGF:
+ case BUILT_IN_LOGL:
+ return fold_builtin_logarithm (exp, &dconste);
+ break;
+ case BUILT_IN_LOG2:
+ case BUILT_IN_LOG2F:
+ case BUILT_IN_LOG2L:
+ return fold_builtin_logarithm (exp, &dconst2);
+ break;
+ case BUILT_IN_LOG10:
+ case BUILT_IN_LOG10F:
+ case BUILT_IN_LOG10L:
+ return fold_builtin_logarithm (exp, &dconst10);
+ break;
+
+ case BUILT_IN_TAN:
+ case BUILT_IN_TANF:
+ case BUILT_IN_TANL:
+ if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ {
+ enum built_in_function fcode;
+ tree arg = TREE_VALUE (arglist);
+
+ /* Optimize tan(0.0) = 0.0. */
+ if (real_zerop (arg))
+ return arg;
+
+ /* Optimize tan(atan(x)) = x. */
+ fcode = builtin_mathfn_code (arg);
+ if (flag_unsafe_math_optimizations
+ && (fcode == BUILT_IN_ATAN
+ || fcode == BUILT_IN_ATANF
+ || fcode == BUILT_IN_ATANL))
+ return TREE_VALUE (TREE_OPERAND (arg, 1));
+ }
+ break;
+
+ case BUILT_IN_ATAN:
+ case BUILT_IN_ATANF:
+ case BUILT_IN_ATANL:
+ if (validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
+ {
+ tree arg = TREE_VALUE (arglist);
+
+ /* Optimize atan(0.0) = 0.0. */
+ if (real_zerop (arg))
+ return arg;
+
+ /* Optimize atan(1.0) = pi/4. */
+ if (real_onep (arg))
+ {
+ REAL_VALUE_TYPE cst;
+
+ real_convert (&cst, TYPE_MODE (type), &dconstpi);
+ cst.exp -= 2;
+ return build_real (type, cst);
+ }
+ }
+ break;
+
+ case BUILT_IN_POW:
+ case BUILT_IN_POWF:
+ case BUILT_IN_POWL:
+ if (validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE))
+ {
+ enum built_in_function fcode;
+ tree arg0 = TREE_VALUE (arglist);
+ tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+
+ /* Optimize pow(1.0,y) = 1.0. */
+ if (real_onep (arg0))
+ return omit_one_operand (type, build_real (type, dconst1), arg1);
+
+ if (TREE_CODE (arg1) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (arg1))
+ {
+ REAL_VALUE_TYPE c;
+ c = TREE_REAL_CST (arg1);
+
+ /* Optimize pow(x,0.0) = 1.0. */
+ if (REAL_VALUES_EQUAL (c, dconst0))
+ return omit_one_operand (type, build_real (type, dconst1),
+ arg0);
+
+ /* Optimize pow(x,1.0) = x. */
+ if (REAL_VALUES_EQUAL (c, dconst1))
+ return arg0;
+
+ /* Optimize pow(x,-1.0) = 1.0/x. */
+ if (REAL_VALUES_EQUAL (c, dconstm1))
+ return fold (build (RDIV_EXPR, type,
+ build_real (type, dconst1),
+ arg0));
+
+ /* Optimize pow(x,0.5) = sqrt(x). */
+ if (flag_unsafe_math_optimizations
+ && REAL_VALUES_EQUAL (c, dconsthalf))
+ {
+ tree sqrtfn;
+
+ fcode = DECL_FUNCTION_CODE (fndecl);
+ if (fcode == BUILT_IN_POW)
+ sqrtfn = implicit_built_in_decls[BUILT_IN_SQRT];
+ else if (fcode == BUILT_IN_POWF)
+ sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTF];
+ else if (fcode == BUILT_IN_POWL)
+ sqrtfn = implicit_built_in_decls[BUILT_IN_SQRTL];
+ else
+ sqrtfn = NULL_TREE;
+
+ if (sqrtfn != NULL_TREE)
+ {
+ tree arglist = build_tree_list (NULL_TREE, arg0);
+ return build_function_call_expr (sqrtfn, arglist);
+ }
+ }
+
+ /* Attempt to evaluate pow at compile-time. */
+ if (TREE_CODE (arg0) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (arg0))
+ {
+ REAL_VALUE_TYPE cint;
+ HOST_WIDE_INT n;
+
+ n = real_to_integer (&c);
+ real_from_integer (&cint, VOIDmode, n,
+ n < 0 ? -1 : 0, 0);
+ if (real_identical (&c, &cint))
+ {
+ REAL_VALUE_TYPE x;
+ bool inexact;
+
+ x = TREE_REAL_CST (arg0);
+ inexact = real_powi (&x, TYPE_MODE (type), &x, n);
+ if (flag_unsafe_math_optimizations || !inexact)
+ return build_real (type, x);
+ }
+ }
+ }
+
+ /* Optimize pow(exp(x),y) = exp(x*y). */
+ fcode = builtin_mathfn_code (arg0);
+ if (flag_unsafe_math_optimizations
+ && (fcode == BUILT_IN_EXP
+ || fcode == BUILT_IN_EXPF
+ || fcode == BUILT_IN_EXPL))
+ {
+ tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
+ tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
+ arg = fold (build (MULT_EXPR, type, arg, arg1));
+ arglist = build_tree_list (NULL_TREE, arg);
+ return build_function_call_expr (expfn, arglist);
+ }
+
+ /* Optimize pow(sqrt(x),y) = pow(x,y*0.5). */
+ if (flag_unsafe_math_optimizations
+ && (fcode == BUILT_IN_SQRT
+ || fcode == BUILT_IN_SQRTF
+ || fcode == BUILT_IN_SQRTL))
+ {
+ tree narg0 = TREE_VALUE (TREE_OPERAND (arg0, 1));
+ tree narg1 = fold (build (MULT_EXPR, type, arg1,
+ build_real (type, dconsthalf)));
+
+ arglist = tree_cons (NULL_TREE, narg0,
+ build_tree_list (NULL_TREE, narg1));
+ return build_function_call_expr (fndecl, arglist);
+ }
+
+ /* Optimize pow(pow(x,y),z) = pow(x,y*z). */
+ if (flag_unsafe_math_optimizations
+ && (fcode == BUILT_IN_POW
+ || fcode == BUILT_IN_POWF
+ || fcode == BUILT_IN_POWL))
+ {
+ tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
+ tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
+ tree narg1 = fold (build (MULT_EXPR, type, arg01, arg1));
+ arglist = tree_cons (NULL_TREE, arg00,
+ build_tree_list (NULL_TREE, narg1));
+ return build_function_call_expr (fndecl, arglist);
+ }
+ }
+ break;
+
case BUILT_IN_INF:
case BUILT_IN_INFF:
case BUILT_IN_INFL:
- return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl)), true);
+ return fold_builtin_inf (type, true);
case BUILT_IN_HUGE_VAL:
case BUILT_IN_HUGE_VALF:
case BUILT_IN_HUGE_VALL:
- return fold_builtin_inf (TREE_TYPE (TREE_TYPE (fndecl)), false);
+ return fold_builtin_inf (type, false);
case BUILT_IN_NAN:
case BUILT_IN_NANF:
case BUILT_IN_NANL:
- return fold_builtin_nan (arglist, TREE_TYPE (TREE_TYPE (fndecl)), true);
+ return fold_builtin_nan (arglist, type, true);
case BUILT_IN_NANS:
case BUILT_IN_NANSF:
case BUILT_IN_NANSL:
- return fold_builtin_nan (arglist, TREE_TYPE (TREE_TYPE (fndecl)), false);
+ return fold_builtin_nan (arglist, type, false);
+
+ case BUILT_IN_FLOOR:
+ case BUILT_IN_FLOORF:
+ case BUILT_IN_FLOORL:
+ return fold_builtin_floor (exp);
+
+ case BUILT_IN_CEIL:
+ case BUILT_IN_CEILF:
+ case BUILT_IN_CEILL:
+ return fold_builtin_ceil (exp);
+
+ case BUILT_IN_TRUNC:
+ case BUILT_IN_TRUNCF:
+ case BUILT_IN_TRUNCL:
+ return fold_builtin_trunc (exp);
+
+ case BUILT_IN_ROUND:
+ case BUILT_IN_ROUNDF:
+ case BUILT_IN_ROUNDL:
+ case BUILT_IN_NEARBYINT:
+ case BUILT_IN_NEARBYINTF:
+ case BUILT_IN_NEARBYINTL:
+ return fold_trunc_transparent_mathfn (exp);
+
+ case BUILT_IN_FFS:
+ case BUILT_IN_FFSL:
+ case BUILT_IN_FFSLL:
+ case BUILT_IN_CLZ:
+ case BUILT_IN_CLZL:
+ case BUILT_IN_CLZLL:
+ case BUILT_IN_CTZ:
+ case BUILT_IN_CTZL:
+ case BUILT_IN_CTZLL:
+ case BUILT_IN_POPCOUNT:
+ case BUILT_IN_POPCOUNTL:
+ case BUILT_IN_POPCOUNTLL:
+ case BUILT_IN_PARITY:
+ case BUILT_IN_PARITYL:
+ case BUILT_IN_PARITYLL:
+ return fold_builtin_bitop (exp);
+
+ case BUILT_IN_MEMCPY:
+ return fold_builtin_memcpy (exp);
+
+ case BUILT_IN_MEMPCPY:
+ return fold_builtin_mempcpy (exp);
+
+ case BUILT_IN_MEMMOVE:
+ return fold_builtin_memmove (exp);
+
+ case BUILT_IN_STRCPY:
+ return fold_builtin_strcpy (exp);
+
+ case BUILT_IN_STRNCPY:
+ return fold_builtin_strncpy (exp);
+
+ case BUILT_IN_MEMCMP:
+ return fold_builtin_memcmp (exp);
+
+ case BUILT_IN_STRCMP:
+ return fold_builtin_strcmp (exp);
+
+ case BUILT_IN_STRNCMP:
+ return fold_builtin_strncmp (exp);
default:
break;
@@ -4343,16 +6925,16 @@ fold_builtin (exp)
return 0;
}
-static tree
-build_function_call_expr (fn, arglist)
- tree fn, arglist;
+/* Conveniently construct a function call expression. */
+
+tree
+build_function_call_expr (tree fn, tree arglist)
{
tree call_expr;
call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
call_expr, arglist);
- TREE_SIDE_EFFECTS (call_expr) = 1;
return fold (call_expr);
}
@@ -4362,13 +6944,13 @@ build_function_call_expr (fn, arglist)
ellipses, otherwise the last specifier must be a VOID_TYPE. */
static int
-validate_arglist VPARAMS ((tree arglist, ...))
+validate_arglist (tree arglist, ...)
{
enum tree_code code;
int res = 0;
+ va_list ap;
- VA_OPEN (ap, arglist);
- VA_FIXEDARG (ap, tree, arglist);
+ va_start (ap, arglist);
do
{
@@ -4400,27 +6982,58 @@ validate_arglist VPARAMS ((tree arglist, ...))
/* We need gotos here since we can only have one VA_CLOSE in a
function. */
end: ;
- VA_CLOSE (ap);
+ va_end (ap);
return res;
}
-/* Default version of target-specific builtin setup that does nothing. */
+/* Default target-specific builtin expander that does nothing. */
+
+rtx
+default_expand_builtin (tree exp ATTRIBUTE_UNUSED,
+ rtx target ATTRIBUTE_UNUSED,
+ rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
+{
+ return NULL_RTX;
+}
+
+/* Instantiate all remaining CONSTANT_P_RTX nodes. */
void
-default_init_builtins ()
+purge_builtin_constant_p (void)
{
+ rtx insn, set, arg, new, note;
+
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ if (INSN_P (insn)
+ && (set = single_set (insn)) != NULL_RTX
+ && (GET_CODE (arg = SET_SRC (set)) == CONSTANT_P_RTX
+ || (GET_CODE (arg) == SUBREG
+ && (GET_CODE (arg = SUBREG_REG (arg))
+ == CONSTANT_P_RTX))))
+ {
+ arg = XEXP (arg, 0);
+ new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
+ validate_change (insn, &SET_SRC (set), new, 0);
+
+ /* Remove the REG_EQUAL note from the insn. */
+ if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
+ remove_note (insn, note);
+ }
}
-/* Default target-specific builtin expander that does nothing. */
+/* Returns true is EXP represents data that would potentially reside
+ in a readonly section. */
-rtx
-default_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp ATTRIBUTE_UNUSED;
- rtx target ATTRIBUTE_UNUSED;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
+static bool
+readonly_data_expr (tree exp)
{
- return NULL_RTX;
+ STRIP_NOPS (exp);
+
+ if (TREE_CODE (exp) == ADDR_EXPR)
+ return decl_readonly_section (TREE_OPERAND (exp, 0), 0);
+ else
+ return false;
}
diff --git a/contrib/gcc/builtins.def b/contrib/gcc/builtins.def
index c208b7516291..dbc61ce3775e 100644
--- a/contrib/gcc/builtins.def
+++ b/contrib/gcc/builtins.def
@@ -1,6 +1,6 @@
/* This file contains the definitions and documentation for the
builtins used in the GNU compiler.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,7 +22,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Before including this file, you should define a macro:
DEF_BUILTIN (ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P,
- FALLBACK_P, NONANSI_P, ATTRS)
+ FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT)
This macro will be called once for each builtin function. The
ENUM will be of type `enum built_in_function', and will indicate
@@ -53,34 +53,22 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
exist when compiling in ANSI conformant mode.
ATTRs is an attribute list as defined in builtin-attrs.def that
- describes the attributes of this builtin function. */
+ describes the attributes of this builtin function.
+
+ IMPLICIT specifies condition when the builtin can be produced by
+ compiler. For instance C90 reserves floorf function, but does not
+ define it's meaning. When user uses floorf we may assume that the
+ floorf has the meaning we expect, but we can't produce floorf by
+ simplifying floor((double)float) since the runtime need not implement
+ it. */
/* A GCC builtin (like __builtin_saveregs) is provided by the
compiler, but does not correspond to a function in the standard
library. */
#undef DEF_GCC_BUILTIN
#define DEF_GCC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
- DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \
- false, false, false, ATTRS)
-
-
-/* A fallback builtin is a builtin (like __builtin_puts) that falls
- back to the corresopnding library function if necessary -- but
- for which we should not introduce the non-`__builtin' variant of
- the name. */
-#undef DEF_FALLBACK_BUILTIN
-#define DEF_FALLBACK_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
- DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
- false, true, false, ATTRS)
-
-/* Like DEF_FALLBACK_BUILTIN, except that the function is not one that
- is specified by ANSI/ISO C. So, when we're being fully conformant
- we ignore the version of these builtins that does not begin with
- __builtin. */
-#undef DEF_EXT_FALLBACK_BUILTIN
-#define DEF_EXT_FALLBACK_BUILTIN(ENUM, NAME, TYPE) \
- DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
- false, true, true, ATTR_NOTHROW_LIST)
+ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \
+ false, false, false, ATTRS, true)
/* A library builtin (like __builtin_strchr) is a builtin equivalent
of an ANSI/ISO standard library function. In addition to the
@@ -90,15 +78,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
version. */
#undef DEF_LIB_BUILTIN
#define DEF_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
- DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
- true, true, false, ATTRS)
-
-/* Like DEF_LIB_BUILTIN, except that a call to the builtin should
- never fall back to the library version. */
-#undef DEF_LIB_ALWAYS_BUILTIN
-#define DEF_LIB_ALWAYS_BUILTIN(ENUM, NAME, TYPE) \
- DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
- true, false, true, ATTR_CONST_NOTHROW_LIST)
+ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
+ true, true, false, ATTRS, true)
/* Like DEF_LIB_BUILTIN, except that the function is not one that is
specified by ANSI/ISO C. So, when we're being fully conformant we
@@ -106,659 +87,467 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
__builtin. */
#undef DEF_EXT_LIB_BUILTIN
#define DEF_EXT_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
- DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
- true, true, true, ATTRS)
+ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
+ true, true, true, ATTRS, false)
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
the standard in C99 or above. */
#undef DEF_C99_BUILTIN
#define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
- DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
- true, true, !flag_isoc99, ATTRS)
-
-/* Like DEF_LIB_BUILTIN, except that the function is expanded in the
- front-end. */
-#undef DEF_FRONT_END_LIB_BUILTIN
-#define DEF_FRONT_END_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
- DEF_BUILTIN (ENUM, NAME, BUILT_IN_FRONTEND, TYPE, TYPE, \
- true, true, false, ATTRS)
-
-/* Like DEF_FRONT_END_LIB_BUILTIN, except that the function is not one
- that is specified by ANSI/ISO C. So, when we're being fully
- conformant we ignore the version of these builtins that does not
- begin with __builtin. */
-#undef DEF_EXT_FRONT_END_LIB_BUILTIN
-#define DEF_EXT_FRONT_END_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
- DEF_BUILTIN (ENUM, NAME, BUILT_IN_FRONTEND, TYPE, TYPE, \
- true, true, true, ATTRS)
-
-/* A built-in that is not currently used. */
-#undef DEF_UNUSED_BUILTIN
-#define DEF_UNUSED_BUILTIN(X) \
- DEF_BUILTIN (X, (const char *) NULL, NOT_BUILT_IN, BT_LAST, \
- BT_LAST, false, false, false, ATTR_NOTHROW_LIST)
-
-/* If SMALL_STACK is defined, then `alloca' is only defined in its
- `__builtin' form. */
-#if SMALL_STACK
-DEF_FALLBACK_BUILTIN(BUILT_IN_ALLOCA,
- "__builtin_alloca",
- BT_FN_PTR_SIZE,
- ATTR_MALLOC_NOTHROW_LIST)
-#else
-DEF_EXT_LIB_BUILTIN(BUILT_IN_ALLOCA,
- "__builtin_alloca",
- BT_FN_PTR_SIZE,
- ATTR_MALLOC_NOTHROW_LIST)
-#endif
-
-DEF_LIB_ALWAYS_BUILTIN(BUILT_IN_ABS,
- "__builtin_abs",
- BT_FN_INT_INT)
-DEF_LIB_ALWAYS_BUILTIN(BUILT_IN_LABS,
- "__builtin_labs",
- BT_FN_LONG_LONG)
-
-DEF_LIB_ALWAYS_BUILTIN(BUILT_IN_FABS,
- "__builtin_fabs",
- BT_FN_DOUBLE_DOUBLE)
-DEF_LIB_ALWAYS_BUILTIN(BUILT_IN_FABSF,
- "__builtin_fabsf",
- BT_FN_FLOAT_FLOAT)
-DEF_LIB_ALWAYS_BUILTIN(BUILT_IN_FABSL,
- "__builtin_fabsl",
- BT_FN_LONG_DOUBLE_LONG_DOUBLE)
-
-DEF_C99_BUILTIN(BUILT_IN_LLABS,
- "__builtin_llabs",
- BT_FN_LONGLONG_LONGLONG,
- ATTR_NOTHROW_LIST)
-DEF_C99_BUILTIN(BUILT_IN_IMAXABS,
- "__builtin_imaxabs",
- BT_FN_INTMAX_INTMAX,
- ATTR_NOTHROW_LIST)
-DEF_C99_BUILTIN(BUILT_IN_CONJ,
- "__builtin_conj",
- BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE,
- ATTR_NOTHROW_LIST)
-DEF_C99_BUILTIN(BUILT_IN_CONJF,
- "__builtin_conjf",
- BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT,
- ATTR_NOTHROW_LIST)
-DEF_C99_BUILTIN(BUILT_IN_CONJL,
- "__builtin_conjl",
- BT_FN_COMPLEX_LONG_DOUBLE_COMPLEX_LONG_DOUBLE,
- ATTR_NOTHROW_LIST)
-DEF_C99_BUILTIN(BUILT_IN_CREAL,
- "__builtin_creal",
- BT_FN_DOUBLE_COMPLEX_DOUBLE,
- ATTR_NOTHROW_LIST)
-DEF_C99_BUILTIN(BUILT_IN_CREALF,
- "__builtin_crealf",
- BT_FN_FLOAT_COMPLEX_FLOAT,
- ATTR_NOTHROW_LIST)
-DEF_C99_BUILTIN(BUILT_IN_CREALL,
- "__builtin_creall",
- BT_FN_LONG_DOUBLE_COMPLEX_LONG_DOUBLE,
- ATTR_NOTHROW_LIST)
-DEF_C99_BUILTIN(BUILT_IN_CIMAG,
- "__builtin_cimag",
- BT_FN_DOUBLE_COMPLEX_DOUBLE,
- ATTR_NOTHROW_LIST)
-DEF_C99_BUILTIN(BUILT_IN_CIMAGF,
- "__builtin_cimagf",
- BT_FN_FLOAT_COMPLEX_FLOAT,
- ATTR_NOTHROW_LIST)
-DEF_C99_BUILTIN(BUILT_IN_CIMAGL,
- "__builtin_cimagl",
- BT_FN_LONG_DOUBLE_COMPLEX_LONG_DOUBLE,
- ATTR_NOTHROW_LIST)
-
-DEF_UNUSED_BUILTIN(BUILT_IN_DIV)
-DEF_UNUSED_BUILTIN(BUILT_IN_LDIV)
-DEF_UNUSED_BUILTIN(BUILT_IN_FFLOOR)
-DEF_UNUSED_BUILTIN(BUILT_IN_FCEIL)
-DEF_UNUSED_BUILTIN(BUILT_IN_FMOD)
-DEF_UNUSED_BUILTIN(BUILT_IN_FREM)
-
-/* The system prototypes for `bzero' and `bcmp' functions have many
- variations, so don't specify parameters to avoid conflicts. The
- expand_* functions check the argument types anyway. */
-DEF_BUILTIN (BUILT_IN_BZERO,
- "__builtin_bzero",
- BUILT_IN_NORMAL,
- BT_FN_VOID_PTR_SIZE,
- BT_FN_VOID_VAR,
- true, true, true,
- ATTR_NOTHROW_LIST)
-DEF_BUILTIN (BUILT_IN_BCMP,
- "__builtin_bcmp",
- BUILT_IN_NORMAL,
- BT_FN_INT_CONST_PTR_CONST_PTR_SIZE,
- BT_FN_INT_VAR,
- true, true, true,
- ATTR_PURE_NOTHROW_LIST)
-
-DEF_EXT_LIB_BUILTIN(BUILT_IN_FFS,
- "__builtin_ffs",
- BT_FN_INT_INT,
- ATTR_CONST_NOTHROW_LIST)
-DEF_EXT_LIB_BUILTIN(BUILT_IN_INDEX,
- "__builtin_index",
- BT_FN_STRING_CONST_STRING_INT,
- ATTR_PURE_NOTHROW_LIST)
-DEF_EXT_LIB_BUILTIN(BUILT_IN_RINDEX,
- "__builtin_rindex",
- BT_FN_STRING_CONST_STRING_INT,
- ATTR_PURE_NOTHROW_LIST)
-
-DEF_LIB_BUILTIN(BUILT_IN_MEMCPY,
- "__builtin_memcpy",
- BT_FN_PTR_PTR_CONST_PTR_SIZE,
- ATTR_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_MEMCMP,
- "__builtin_memcmp",
- BT_FN_INT_CONST_PTR_CONST_PTR_SIZE,
- ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_MEMSET,
- "__builtin_memset",
- BT_FN_PTR_PTR_INT_SIZE,
- ATTR_NOTHROW_LIST)
-
-DEF_LIB_BUILTIN(BUILT_IN_STRCAT,
- "__builtin_strcat",
- BT_FN_STRING_STRING_CONST_STRING,
- ATTR_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_STRNCAT,
- "__builtin_strncat",
- BT_FN_STRING_STRING_CONST_STRING_SIZE,
- ATTR_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_STRCPY,
- "__builtin_strcpy",
- BT_FN_STRING_STRING_CONST_STRING,
- ATTR_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_STRNCPY,
- "__builtin_strncpy",
- BT_FN_STRING_STRING_CONST_STRING_SIZE,
- ATTR_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_STRCMP,
- "__builtin_strcmp",
- BT_FN_INT_CONST_STRING_CONST_STRING,
- ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_STRNCMP,
- "__builtin_strncmp",
- BT_FN_INT_CONST_STRING_CONST_STRING_SIZE,
- ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_STRLEN,
- "__builtin_strlen",
- BT_FN_SIZE_CONST_STRING,
- ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_STRSTR,
- "__builtin_strstr",
- BT_FN_STRING_CONST_STRING_CONST_STRING,
- ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_STRPBRK,
- "__builtin_strpbrk",
- BT_FN_STRING_CONST_STRING_CONST_STRING,
- ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_STRSPN,
- "__builtin_strspn",
- BT_FN_SIZE_CONST_STRING_CONST_STRING,
- ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_STRCSPN,
- "__builtin_strcspn",
- BT_FN_SIZE_CONST_STRING_CONST_STRING,
- ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_STRCHR,
- "__builtin_strchr",
- BT_FN_STRING_CONST_STRING_INT,
- ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_STRRCHR,
- "__builtin_strrchr",
- BT_FN_STRING_CONST_STRING_INT,
- ATTR_PURE_NOTHROW_LIST)
-
-DEF_LIB_BUILTIN(BUILT_IN_SQRT,
- "__builtin_sqrt",
- BT_FN_DOUBLE_DOUBLE,
- flag_errno_math ? ATTR_NOTHROW_LIST
- : (flag_unsafe_math_optimizations
- ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST))
-DEF_LIB_BUILTIN(BUILT_IN_SIN,
- "__builtin_sin",
- BT_FN_DOUBLE_DOUBLE,
- flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_COS,
- "__builtin_cos",
- BT_FN_DOUBLE_DOUBLE,
- flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_EXP,
- "__builtin_exp",
- BT_FN_DOUBLE_DOUBLE,
- flag_errno_math ? ATTR_NOTHROW_LIST
- : (flag_unsafe_math_optimizations
- ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST))
-DEF_LIB_BUILTIN(BUILT_IN_LOG,
- "__builtin_log",
- BT_FN_DOUBLE_DOUBLE,
- flag_errno_math ? ATTR_NOTHROW_LIST
- : (flag_unsafe_math_optimizations
- ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST))
-DEF_LIB_BUILTIN(BUILT_IN_SQRTF,
- "__builtin_sqrtf",
- BT_FN_FLOAT_FLOAT,
- flag_errno_math ? ATTR_NOTHROW_LIST
- : (flag_unsafe_math_optimizations
- ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST))
-DEF_LIB_BUILTIN(BUILT_IN_SINF,
- "__builtin_sinf",
- BT_FN_FLOAT_FLOAT,
- flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_COSF,
- "__builtin_cosf",
- BT_FN_FLOAT_FLOAT,
- flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_EXPF,
- "__builtin_expf",
- BT_FN_FLOAT_FLOAT,
- flag_errno_math ? ATTR_NOTHROW_LIST
- : (flag_unsafe_math_optimizations
- ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST))
-DEF_LIB_BUILTIN(BUILT_IN_LOGF,
- "__builtin_logf",
- BT_FN_FLOAT_FLOAT,
- flag_errno_math ? ATTR_NOTHROW_LIST
- : (flag_unsafe_math_optimizations
- ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST))
-DEF_LIB_BUILTIN(BUILT_IN_SQRTL,
- "__builtin_sqrtl",
- BT_FN_LONG_DOUBLE_LONG_DOUBLE,
- flag_errno_math ? ATTR_NOTHROW_LIST
- : (flag_unsafe_math_optimizations
- ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST))
-DEF_LIB_BUILTIN(BUILT_IN_SINL,
- "__builtin_sinl",
- BT_FN_LONG_DOUBLE_LONG_DOUBLE,
- flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_COSL,
- "__builtin_cosl",
- BT_FN_LONG_DOUBLE_LONG_DOUBLE,
- flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_EXPL,
- "__builtin_expl",
- BT_FN_LONG_DOUBLE_LONG_DOUBLE,
- flag_errno_math ? ATTR_NOTHROW_LIST
- : (flag_unsafe_math_optimizations
- ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST))
-DEF_LIB_BUILTIN(BUILT_IN_LOGL,
- "__builtin_logl",
- BT_FN_LONG_DOUBLE_LONG_DOUBLE,
- flag_errno_math ? ATTR_NOTHROW_LIST
- : (flag_unsafe_math_optimizations
- ? ATTR_CONST_NOTHROW_LIST
- : ATTR_PURE_NOTHROW_LIST))
-
-DEF_GCC_BUILTIN(BUILT_IN_INF,
- "__builtin_inf",
- BT_FN_DOUBLE,
- ATTR_CONST_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_INFF,
- "__builtin_inff",
- BT_FN_FLOAT,
- ATTR_CONST_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_INFL,
- "__builtin_infl",
- BT_FN_LONG_DOUBLE,
- ATTR_CONST_NOTHROW_LIST)
-
-DEF_GCC_BUILTIN(BUILT_IN_HUGE_VAL,
- "__builtin_huge_val",
- BT_FN_DOUBLE,
- ATTR_CONST_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_HUGE_VALF,
- "__builtin_huge_valf",
- BT_FN_FLOAT,
- ATTR_CONST_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_HUGE_VALL,
- "__builtin_huge_vall",
- BT_FN_LONG_DOUBLE,
- ATTR_CONST_NOTHROW_LIST)
-
-DEF_LIB_BUILTIN(BUILT_IN_NAN,
- "__builtin_nan",
- BT_FN_DOUBLE_CONST_STRING,
- ATTR_CONST_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_NANF,
- "__builtin_nanf",
- BT_FN_FLOAT_CONST_STRING,
- ATTR_CONST_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_NANL,
- "__builtin_nanl",
- BT_FN_LONG_DOUBLE_CONST_STRING,
- ATTR_CONST_NOTHROW_LIST)
-
-DEF_LIB_BUILTIN(BUILT_IN_NANS,
- "__builtin_nans",
- BT_FN_DOUBLE_CONST_STRING,
- ATTR_CONST_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_NANSF,
- "__builtin_nansf",
- BT_FN_FLOAT_CONST_STRING,
- ATTR_CONST_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_NANSL,
- "__builtin_nansl",
- BT_FN_LONG_DOUBLE_CONST_STRING,
- ATTR_CONST_NOTHROW_LIST)
-
-DEF_GCC_BUILTIN(BUILT_IN_SAVEREGS,
- "__builtin_saveregs",
- BT_FN_PTR_VAR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_CLASSIFY_TYPE,
- "__builtin_classify_type",
- BT_FN_INT_VAR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_NEXT_ARG,
- "__builtin_next_arg",
- BT_FN_PTR_VAR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_ARGS_INFO,
- "__builtin_args_info",
- BT_FN_INT_INT,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_CONSTANT_P,
- "__builtin_constant_p",
- BT_FN_INT_VAR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_FRAME_ADDRESS,
- "__builtin_frame_address",
- BT_FN_PTR_UNSIGNED,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_RETURN_ADDRESS,
- "__builtin_return_address",
- BT_FN_PTR_UNSIGNED,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_AGGREGATE_INCOMING_ADDRESS,
- "__builtin_aggregate_incoming_address",
- BT_FN_PTR_VAR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_APPLY_ARGS,
- "__builtin_apply_args",
- BT_FN_PTR_VAR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_APPLY,
- "__builtin_apply",
- BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_RETURN,
- "__builtin_return",
- BT_FN_VOID_PTR,
- ATTR_NORETURN_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_SETJMP,
- "__builtin_setjmp",
- BT_FN_INT_PTR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_LONGJMP,
- "__builtin_longjmp",
- BT_FN_VOID_PTR_INT,
- ATTR_NORETURN_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_TRAP,
- "__builtin_trap",
- BT_FN_VOID,
- ATTR_NORETURN_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_PREFETCH,
- "__builtin_prefetch",
- BT_FN_VOID_CONST_PTR_VAR,
- ATTR_NULL)
-
-/* stdio.h builtins (without FILE *). */
-
-DEF_FRONT_END_LIB_BUILTIN(BUILT_IN_PRINTF,
- "__builtin_printf",
- BT_FN_INT_CONST_STRING_VAR,
- ATTR_FORMAT_PRINTF_1_2)
-DEF_LIB_BUILTIN(BUILT_IN_PUTCHAR,
- "__builtin_putchar",
- BT_FN_INT_INT,
- ATTR_NOTHROW_LIST)
-DEF_LIB_BUILTIN(BUILT_IN_PUTS,
- "__builtin_puts",
- BT_FN_INT_CONST_STRING,
- ATTR_NOTHROW_LIST)
-DEF_C99_BUILTIN(BUILT_IN_SNPRINTF,
- "__builtin_snprintf",
- BT_FN_INT_STRING_SIZE_CONST_STRING_VAR,
- ATTR_FORMAT_PRINTF_3_4)
-DEF_LIB_BUILTIN(BUILT_IN_SPRINTF,
- "__builtin_sprintf",
- BT_FN_INT_STRING_CONST_STRING_VAR,
- ATTR_FORMAT_PRINTF_2_3)
-DEF_LIB_BUILTIN(BUILT_IN_SCANF,
- "__builtin_scanf",
- BT_FN_INT_CONST_STRING_VAR,
- ATTR_FORMAT_SCANF_1_2)
-DEF_LIB_BUILTIN(BUILT_IN_SSCANF,
- "__builtin_sscanf",
- BT_FN_INT_CONST_STRING_CONST_STRING_VAR,
- ATTR_FORMAT_SCANF_2_3)
-DEF_LIB_BUILTIN(BUILT_IN_VPRINTF,
- "__builtin_vprintf",
- BT_FN_INT_CONST_STRING_VALIST_ARG,
- ATTR_FORMAT_PRINTF_1_0)
-DEF_C99_BUILTIN(BUILT_IN_VSCANF,
- "__builtin_vscanf",
- BT_FN_INT_CONST_STRING_VALIST_ARG,
- ATTR_FORMAT_SCANF_1_0)
-DEF_C99_BUILTIN(BUILT_IN_VSSCANF,
- "__builtin_vsscanf",
- BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG,
- ATTR_FORMAT_SCANF_2_0)
-DEF_C99_BUILTIN(BUILT_IN_VSNPRINTF,
- "__builtin_vsnprintf",
- BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG,
- ATTR_FORMAT_PRINTF_3_0)
-DEF_LIB_BUILTIN(BUILT_IN_VSPRINTF,
- "__builtin_vsprintf",
- BT_FN_INT_STRING_CONST_STRING_VALIST_ARG,
- ATTR_FORMAT_PRINTF_2_0)
-
-
-/* stdio.h builtins (with FILE *). */
-
-/* Declare the __builtin_ style with arguments and the regular style
- without them. We rely on stdio.h to supply the arguments for the
- regular style declaration since we had to use void* instead of
- FILE* in the __builtin_ prototype supplied here. */
-
-DEF_FALLBACK_BUILTIN(BUILT_IN_FPUTC,
- "__builtin_fputc",
- BT_FN_INT_INT_PTR,
- ATTR_NOTHROW_LIST)
-DEF_BUILTIN (BUILT_IN_FPUTS,
- "__builtin_fputs",
- BUILT_IN_NORMAL,
- BT_FN_INT_CONST_STRING_PTR,
- BT_FN_INT_VAR,
- true, true, false, ATTR_NOTHROW_LIST)
-DEF_FALLBACK_BUILTIN(BUILT_IN_FWRITE,
- "__builtin_fwrite",
- BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR,
- ATTR_NOTHROW_LIST)
-DEF_FRONT_END_LIB_BUILTIN(BUILT_IN_FPRINTF,
- "__builtin_fprintf",
- BT_FN_INT_PTR_CONST_STRING_VAR,
- ATTR_FORMAT_PRINTF_2_3)
-
-/* stdio unlocked builtins (without FILE *). */
-
-DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_PUTCHAR_UNLOCKED,
- "__builtin_putchar_unlocked",
- BT_FN_INT_INT)
-DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_PUTS_UNLOCKED,
- "__builtin_puts_unlocked",
- BT_FN_INT_CONST_STRING)
-DEF_EXT_FRONT_END_LIB_BUILTIN(BUILT_IN_PRINTF_UNLOCKED,
- "__builtin_printf_unlocked",
- BT_FN_INT_CONST_STRING_VAR,
- ATTR_FORMAT_PRINTF_1_2)
-
-/* stdio unlocked builtins (with FILE *). */
-
-/* Declare the __builtin_ style with arguments and the regular style
- without them. We rely on stdio.h to supply the arguments for the
- regular style declaration since we had to use void* instead of
- FILE* in the __builtin_ prototype supplied here. */
-
-DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_FPUTC_UNLOCKED,
- "__builtin_fputc_unlocked",
- BT_FN_INT_INT_PTR)
-DEF_BUILTIN (BUILT_IN_FPUTS_UNLOCKED,
- "__builtin_fputs_unlocked",
- BUILT_IN_NORMAL,
- BT_FN_INT_CONST_STRING_PTR,
- BT_FN_INT_VAR,
- true, true, true, ATTR_NOTHROW_LIST)
-DEF_EXT_FALLBACK_BUILTIN(BUILT_IN_FWRITE_UNLOCKED,
- "__builtin_fwrite_unlocked",
- BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR)
-DEF_EXT_FRONT_END_LIB_BUILTIN(BUILT_IN_FPRINTF_UNLOCKED,
- "__builtin_fprintf_unlocked",
- BT_FN_INT_PTR_CONST_STRING_VAR,
- ATTR_FORMAT_PRINTF_2_3)
-
- /* ISO C99 floating point unordered comparisons. */
-DEF_GCC_BUILTIN(BUILT_IN_ISGREATER,
- "__builtin_isgreater",
- BT_FN_INT_VAR,
- ATTR_CONST_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_ISGREATEREQUAL,
- "__builtin_isgreaterequal",
- BT_FN_INT_VAR,
- ATTR_CONST_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_ISLESS,
- "__builtin_isless",
- BT_FN_INT_VAR,
- ATTR_CONST_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_ISLESSEQUAL,
- "__builtin_islessequal",
- BT_FN_INT_VAR,
- ATTR_CONST_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_ISLESSGREATER,
- "__builtin_islessgreater",
- BT_FN_INT_VAR,
- ATTR_CONST_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_ISUNORDERED,
- "__builtin_isunordered",
- BT_FN_INT_VAR,
- ATTR_CONST_NOTHROW_LIST)
-
-/* Various hooks for the DWARF 2 __throw routine. */
-DEF_GCC_BUILTIN(BUILT_IN_UNWIND_INIT,
- "__builtin_unwind_init",
- BT_FN_VOID,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_DWARF_CFA,
- "__builtin_dwarf_cfa",
- BT_FN_PTR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_DWARF_SP_COLUMN,
- "__builtin_dwarf_sp_column",
- BT_FN_UNSIGNED,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_INIT_DWARF_REG_SIZES,
- "__builtin_init_dwarf_reg_size_table",
- BT_FN_VOID_PTR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_FROB_RETURN_ADDR,
- "__builtin_frob_return_addr",
- BT_FN_PTR_PTR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_EXTRACT_RETURN_ADDR,
- "__builtin_extract_return_addr",
- BT_FN_PTR_PTR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_EH_RETURN,
- "__builtin_eh_return",
- BT_FN_VOID_PTRMODE_PTR,
- ATTR_NORETURN_NOTHROW_LIST)
-DEF_GCC_BUILTIN(BUILT_IN_EH_RETURN_DATA_REGNO,
- "__builtin_eh_return_data_regno",
- BT_FN_INT_INT,
- ATTR_NULL)
-
-/* Variable argument list (stdarg.h) support */
-DEF_GCC_BUILTIN(BUILT_IN_VA_START,
- "__builtin_va_start",
- BT_FN_VOID_VALIST_REF_VAR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_STDARG_START, /* backward compat */
- "__builtin_stdarg_start",
- BT_FN_VOID_VALIST_REF_VAR,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_VA_END,
- "__builtin_va_end",
- BT_FN_VOID_VALIST_REF,
- ATTR_NULL)
-DEF_GCC_BUILTIN(BUILT_IN_VA_COPY,
- "__builtin_va_copy",
- BT_FN_VOID_VALIST_REF_VALIST_ARG,
- ATTR_NULL)
-
-DEF_GCC_BUILTIN(BUILT_IN_EXPECT,
- "__builtin_expect",
- BT_FN_LONG_LONG_LONG,
- ATTR_NULL)
-
-/* C++ extensions */
-DEF_UNUSED_BUILTIN(BUILT_IN_NEW)
-DEF_UNUSED_BUILTIN(BUILT_IN_VEC_NEW)
-DEF_UNUSED_BUILTIN(BUILT_IN_DELETE)
-DEF_UNUSED_BUILTIN(BUILT_IN_VEC_DELETE)
-
-/* Declare abort, exit, _exit and _Exit */
-DEF_BUILTIN (BUILT_IN_ABORT,
- "__builtin_abort",
- NOT_BUILT_IN,
- BT_FN_VOID,
- BT_FN_VOID,
- 1, 0, 0,
- ATTR_NORETURN_NOTHROW_LIST)
-
-DEF_BUILTIN (BUILT_IN_EXIT,
- "__builtin_exit",
- NOT_BUILT_IN,
- BT_FN_VOID_INT,
- BT_FN_VOID_INT,
- 1, 0, 0,
- ATTR_NORETURN_NOTHROW_LIST)
-
-DEF_BUILTIN (BUILT_IN__EXIT,
- "__builtin__exit",
- NOT_BUILT_IN,
- BT_FN_VOID_INT,
- BT_FN_VOID_INT,
- 1, 0, 1,
- ATTR_NORETURN_NOTHROW_LIST)
-
-DEF_BUILTIN (BUILT_IN__EXIT2,
- "__builtin__Exit",
- NOT_BUILT_IN,
- BT_FN_VOID_INT,
- BT_FN_VOID_INT,
- 1, 0, !flag_isoc99,
- ATTR_NORETURN_NOTHROW_LIST)
-
+ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
+ true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS)
+
+/* Builtin that is specified by C99 and C90 reserve the name for future use.
+ We can still recognize the builtin in C90 mode but we can't produce it
+ implicitly. */
+#undef DEF_C99_C90RES_BUILTIN
+#define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
+ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
+ true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS)
+
+/* Define an attribute list for math functions that are normally
+ "impure" because some of them may write into global memory for
+ `errno'. If !flag_errno_math they are instead "const". */
+#undef ATTR_MATHFN_ERRNO
+#define ATTR_MATHFN_ERRNO (flag_errno_math ? \
+ ATTR_NOTHROW_LIST : ATTR_CONST_NOTHROW_LIST)
+
+/* Define an attribute list for math functions that are normally
+ "pure" but if flag_unsafe_math_optimizations is set they are
+ instead "const". This distinction accounts for the fact that some
+ math functions check the rounding mode which is akin to examing
+ global memory. In "unsafe" mode we can be less careful. */
+#undef ATTR_MATHFN_FPROUNDING
+#define ATTR_MATHFN_FPROUNDING (flag_unsafe_math_optimizations ? \
+ ATTR_CONST_NOTHROW_LIST : ATTR_PURE_NOTHROW_LIST)
+
+/* Define an attribute list for math functions that are normally
+ "impure" because some of them may write into global memory for
+ `errno'. If !flag_errno_math, we can possibly use "pure" or
+ "const" depending on whether we care about FP rounding. */
+#undef ATTR_MATHFN_FPROUNDING_ERRNO
+#define ATTR_MATHFN_FPROUNDING_ERRNO (flag_errno_math ? \
+ ATTR_NOTHROW_LIST : ATTR_MATHFN_FPROUNDING)
+
+/* Define an attribute list for math functions that need to mind FP
+ rounding, but because they store into memory they are never "const"
+ or "pure". Use of this macro is mainly for documentation and
+ maintenance purposes. */
+#undef ATTR_MATHFN_FPROUNDING_STORE
+#define ATTR_MATHFN_FPROUNDING_STORE ATTR_NOTHROW_LIST
+
+/* Category: math builtins. */
+DEF_LIB_BUILTIN (BUILT_IN_ACOS, "acos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_ACOSF, "acosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ACOSH, "acosh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ACOSHF, "acoshf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ACOSHL, "acoshl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_ACOSL, "acosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_LIB_BUILTIN (BUILT_IN_ASIN, "asin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_ASINF, "asinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ASINH, "asinh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_ASINHF, "asinhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_ASINHL, "asinhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_ASINL, "asinl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_LIB_BUILTIN (BUILT_IN_ATAN, "atan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_LIB_BUILTIN (BUILT_IN_ATAN2, "atan2", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_ATAN2F, "atan2f", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_ATAN2L, "atan2l", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_ATANF, "atanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_ATANH, "atanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ATANHF, "atanhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ATANHL, "atanhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_ATANL, "atanl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CBRT, "cbrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CBRTF, "cbrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CBRTL, "cbrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_LIB_BUILTIN (BUILT_IN_CEIL, "ceil", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_CEILF, "ceilf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_CEILL, "ceill", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_COPYSIGN, "copysign", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_COPYSIGNF, "copysignf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_COPYSIGNL, "copysignl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_COS, "cos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_COSF, "cosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_LIB_BUILTIN (BUILT_IN_COSH, "cosh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_COSHF, "coshf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_COSHL, "coshl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_COSL, "cosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_DREM, "drem", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_DREMF, "dremf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_DREML, "dreml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ERF, "erf", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_ERFC, "erfc", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ERFCF, "erfcf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ERFCL, "erfcl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ERFF, "erff", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_ERFL, "erfl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_LIB_BUILTIN (BUILT_IN_EXP, "exp", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10, "exp10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10F, "exp10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10L, "exp10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_EXP2, "exp2", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_EXP2F, "exp2f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_EXP2L, "exp2l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_EXPF, "expf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_EXPL, "expl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_EXPM1, "expm1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_EXPM1F, "expm1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_EXPM1L, "expm1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_LIB_BUILTIN (BUILT_IN_FABS, "fabs", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSF, "fabsf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_FDIM, "fdim", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_FDIMF, "fdimf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_FDIML, "fdiml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_LIB_BUILTIN (BUILT_IN_FLOOR, "floor", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORF, "floorf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORL, "floorl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_FMA, "fma", BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_FMAF, "fmaf", BT_FN_FLOAT_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_FMAL, "fmal", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_FMAX, "fmax", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_FMAXF, "fmaxf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_FMAXL, "fmaxl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_FMIN, "fmin", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_FMINF, "fminf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_FMINL, "fminl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_FMOD, "fmod", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODF, "fmodf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODL, "fmodl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_LIB_BUILTIN (BUILT_IN_FREXP, "frexp", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_FREXPF, "frexpf", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_FREXPL, "frexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMA, "gamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAF, "gammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAL, "gammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_GCC_BUILTIN (BUILT_IN_HUGE_VAL, "huge_val", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_HUGE_VALF, "huge_valf", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_HUGE_VALL, "huge_vall", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_HYPOT, "hypot", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_HYPOTF, "hypotf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_HYPOTL, "hypotl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ILOGB, "ilogb", BT_FN_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ILOGBF, "ilogbf", BT_FN_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ILOGBL, "ilogbl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_GCC_BUILTIN (BUILT_IN_INF, "inf", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_INFF, "inff", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_INFL, "infl", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_J0, "j0", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_J0F, "j0f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_J0L, "j0l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_J1, "j1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_J1F, "j1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_J1L, "j1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_JN, "jn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_JNF, "jnf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_JNL, "jnl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_LIB_BUILTIN (BUILT_IN_LDEXP, "ldexp", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPF, "ldexpf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPL, "ldexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LGAMMA, "lgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LGAMMAF, "lgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LGAMMAL, "lgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LLRINT, "llrint", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LLRINTF, "llrintf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LLRINTL, "llrintl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LLROUND, "llround", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LLROUNDF, "llroundf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LLROUNDL, "llroundl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_ERRNO)
+DEF_LIB_BUILTIN (BUILT_IN_LOG, "log", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_LIB_BUILTIN (BUILT_IN_LOG10, "log10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_LOG10F, "log10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_LOG10L, "log10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LOG1P, "log1p", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LOG1PF, "log1pf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LOG1PL, "log1pl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LOG2, "log2", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LOG2F, "log2f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LOG2L, "log2l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LOGB, "logb", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LOGBF, "logbf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LOGBL, "logbl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_LOGF, "logf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_LOGL, "logl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LRINT, "lrint", BT_FN_LONG_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LRINTF, "lrintf", BT_FN_LONG_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LRINTL, "lrintl", BT_FN_LONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LROUND, "lround", BT_FN_LONG_DOUBLE, ATTR_MATHFN_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LROUNDF, "lroundf", BT_FN_LONG_FLOAT, ATTR_MATHFN_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_LROUNDL, "lroundl", BT_FN_LONG_LONGDOUBLE, ATTR_MATHFN_ERRNO)
+DEF_LIB_BUILTIN (BUILT_IN_MODF, "modf", BT_FN_DOUBLE_DOUBLE_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFF, "modff", BT_FN_FLOAT_FLOAT_FLOATPTR, ATTR_MATHFN_FPROUNDING_STORE)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFL, "modfl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
+DEF_GCC_BUILTIN (BUILT_IN_NAN, "nan", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL_1)
+DEF_GCC_BUILTIN (BUILT_IN_NANF, "nanf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL_1)
+DEF_GCC_BUILTIN (BUILT_IN_NANL, "nanl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL_1)
+DEF_GCC_BUILTIN (BUILT_IN_NANS, "nans", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL_1)
+DEF_GCC_BUILTIN (BUILT_IN_NANSF, "nansf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL_1)
+DEF_GCC_BUILTIN (BUILT_IN_NANSL, "nansl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL_1)
+DEF_C99_BUILTIN (BUILT_IN_NEARBYINT, "nearbyint", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_NEARBYINTF, "nearbyintf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_NEARBYINTL, "nearbyintl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_NEXTAFTER, "nextafter", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_NEXTAFTERF, "nextafterf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_NEXTAFTERL, "nextafterl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARD, "nexttoward", BT_FN_DOUBLE_DOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARDF, "nexttowardf", BT_FN_FLOAT_FLOAT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARDL, "nexttowardl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_LIB_BUILTIN (BUILT_IN_POW, "pow", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10, "pow10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10F, "pow10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10L, "pow10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_POWF, "powf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_POWL, "powl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_REMAINDER, "remainder", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_REMAINDERF, "remainderf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_REMAINDERL, "remainderl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_REMQUO, "remquo", BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
+DEF_C99_BUILTIN (BUILT_IN_REMQUOF, "remquof", BT_FN_FLOAT_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
+DEF_C99_BUILTIN (BUILT_IN_REMQUOL, "remquol", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE)
+DEF_C99_BUILTIN (BUILT_IN_RINT, "rint", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_RINTF, "rintf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_RINTL, "rintl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_ROUND, "round", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_ROUNDF, "roundf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_ROUNDL, "roundl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALB, "scalb", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALBF, "scalbf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALBL, "scalbl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_SCALBLN, "scalbln", BT_FN_DOUBLE_DOUBLE_LONG, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_SCALBLNF, "scalblnf", BT_FN_FLOAT_FLOAT_LONG, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_SCALBLNL, "scalblnl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONG, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_SCALBN, "scalbn", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_SCALBNF, "scalbnf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_SCALBNL, "scalbnl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICAND, "significand", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDF, "significandf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDL, "significandl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_LIB_BUILTIN (BUILT_IN_SIN, "sin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOS, "sincos", BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSF, "sincosf", BT_FN_VOID_FLOAT_FLOATPTR_FLOATPTR, ATTR_MATHFN_FPROUNDING_STORE)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSL, "sincosl", BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_SINF, "sinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_LIB_BUILTIN (BUILT_IN_SINH, "sinh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_SINHF, "sinhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_SINHL, "sinhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_SINL, "sinl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_LIB_BUILTIN (BUILT_IN_SQRT, "sqrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTF, "sqrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTL, "sqrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_LIB_BUILTIN (BUILT_IN_TAN, "tan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_TANF, "tanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_LIB_BUILTIN (BUILT_IN_TANH, "tanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_TANHF, "tanhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_TANHL, "tanhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_C90RES_BUILTIN (BUILT_IN_TANL, "tanl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_TGAMMA, "tgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_TGAMMAF, "tgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_TGAMMAL, "tgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_C99_BUILTIN (BUILT_IN_TRUNC, "trunc", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_TRUNCF, "truncf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_TRUNCL, "truncl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0, "y0", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0F, "y0f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0L, "y0l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1, "y1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1F, "y1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1L, "y1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_YN, "yn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
+
+/* Category: _Complex math builtins. */
+/* The C99 clog function conflicts with C++ iostreams clog, see
+ http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00510.html */
+DEF_C99_BUILTIN (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+/*DEF_C99_BUILTIN (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)*/
+/*DEF_C99_BUILTIN (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)*/
+/*DEF_C99_BUILTIN (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)*/
+DEF_C99_BUILTIN (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+
+/* Category: string/memory builtins. */
+/* bcmp, bcopy and bzero have traditionally accepted NULL pointers
+ when the length parameter is zero, so don't apply attribute "nonnull". */
+DEF_EXT_LIB_BUILTIN (BUILT_IN_BCMP, "bcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_LIST)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_BCOPY, "bcopy", BT_FN_VOID_CONST_PTR_PTR_SIZE, ATTR_NOTHROW_LIST)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_BZERO, "bzero", BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_LIST)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_FFS, "ffs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSL, "ffsl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSLL, "ffsll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_INDEX, "index", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_1)
+DEF_LIB_BUILTIN (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_1_2)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_NOTHROW_NONNULL_1)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_RINDEX, "rindex", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_1)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_STRCHR, "strchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_1)
+DEF_LIB_BUILTIN (BUILT_IN_STRCMP, "strcmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_STRCPY, "strcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_STRCSPN, "strcspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1_2)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_STRDUP, "strdup", BT_FN_STRING_CONST_STRING, ATTR_MALLOC_NOTHROW_NONNULL_1)
+DEF_LIB_BUILTIN (BUILT_IN_STRLEN, "strlen", BT_FN_SIZE_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1)
+DEF_LIB_BUILTIN (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_STRNCMP, "strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_STRPBRK, "strpbrk", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_STRRCHR, "strrchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_1)
+DEF_LIB_BUILTIN (BUILT_IN_STRSPN, "strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_STRSTR, "strstr", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_1_2)
+
+/* Category: stdio builtins. */
+DEF_LIB_BUILTIN (BUILT_IN_FPRINTF, "fprintf", BT_FN_INT_PTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_UNLOCKED, "fprintf_unlocked", BT_FN_INT_PTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
+DEF_LIB_BUILTIN (BUILT_IN_FPUTC, "fputc", BT_FN_INT_INT_PTR, ATTR_NOTHROW_NONNULL_2)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTC_UNLOCKED, "fputc_unlocked", BT_FN_INT_INT_PTR, ATTR_NOTHROW_NONNULL_2)
+DEF_LIB_BUILTIN (BUILT_IN_FPUTS, "fputs", BT_FN_INT_CONST_STRING_PTR, ATTR_NOTHROW_NONNULL_1_2)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTS_UNLOCKED, "fputs_unlocked", BT_FN_INT_CONST_STRING_PTR, ATTR_NOTHROW_NONNULL_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_FSCANF, "fscanf", BT_FN_INT_PTR_CONST_STRING_VAR, ATTR_FORMAT_SCANF_2_3)
+DEF_LIB_BUILTIN (BUILT_IN_FWRITE, "fwrite", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR, ATTR_NOTHROW_NONNULL_1_4)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_FWRITE_UNLOCKED, "fwrite_unlocked", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR, ATTR_NOTHROW_NONNULL_1_4)
+DEF_LIB_BUILTIN (BUILT_IN_PRINTF, "printf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_PRINTF_UNLOCKED, "printf_unlocked", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2)
+DEF_LIB_BUILTIN (BUILT_IN_PUTCHAR, "putchar", BT_FN_INT_INT, ATTR_NOTHROW_LIST)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTCHAR_UNLOCKED, "putchar_unlocked", BT_FN_INT_INT, ATTR_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_PUTS, "puts", BT_FN_INT_CONST_STRING, ATTR_NOTHROW_NONNULL_1)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTS_UNLOCKED, "puts_unlocked", BT_FN_INT_CONST_STRING, ATTR_NOTHROW_NONNULL_1)
+DEF_LIB_BUILTIN (BUILT_IN_SCANF, "scanf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_SCANF_1_2)
+DEF_C99_BUILTIN (BUILT_IN_SNPRINTF, "snprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_3_4)
+DEF_LIB_BUILTIN (BUILT_IN_SPRINTF, "sprintf", BT_FN_INT_STRING_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3)
+DEF_LIB_BUILTIN (BUILT_IN_SSCANF, "sscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_FORMAT_SCANF_2_3)
+DEF_LIB_BUILTIN (BUILT_IN_VFPRINTF, "vfprintf", BT_FN_INT_PTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
+DEF_C99_BUILTIN (BUILT_IN_VFSCANF, "vfscanf", BT_FN_INT_PTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_2_0)
+DEF_LIB_BUILTIN (BUILT_IN_VPRINTF, "vprintf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_1_0)
+DEF_C99_BUILTIN (BUILT_IN_VSCANF, "vscanf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_1_0)
+DEF_C99_BUILTIN (BUILT_IN_VSNPRINTF, "vsnprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_3_0)
+DEF_LIB_BUILTIN (BUILT_IN_VSPRINTF, "vsprintf", BT_FN_INT_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0)
+DEF_C99_BUILTIN (BUILT_IN_VSSCANF, "vsscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_2_0)
+
+/* Category: miscellaneous builtins. */
+DEF_LIB_BUILTIN (BUILT_IN_ABORT, "abort", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_ABS, "abs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_AGGREGATE_INCOMING_ADDRESS, "aggregate_incoming_address", BT_FN_PTR_VAR, ATTR_NULL)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_ALLOCA, "alloca", BT_FN_PTR_SIZE, ATTR_MALLOC_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_APPLY, "apply", BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_APPLY_ARGS, "apply_args", BT_FN_PTR_VAR, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_ARGS_INFO, "args_info", BT_FN_INT_INT, ATTR_NULL)
+DEF_LIB_BUILTIN (BUILT_IN_CALLOC, "calloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_CLASSIFY_TYPE, "classify_type", BT_FN_INT_VAR, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_CLZ, "clz", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_CLZL, "clzl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_CLZLL, "clzll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_CONSTANT_P, "constant_p", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_CTZ, "ctz", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_CTZL, "ctzl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_CTZLL, "ctzll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_DCGETTEXT, "dcgettext", BT_FN_STRING_CONST_STRING_CONST_STRING_INT, ATTR_FORMAT_ARG_2)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_DGETTEXT, "dgettext", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_FORMAT_ARG_2)
+DEF_GCC_BUILTIN (BUILT_IN_DWARF_CFA, "dwarf_cfa", BT_FN_PTR, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_DWARF_SP_COLUMN, "dwarf_sp_column", BT_FN_UNSIGNED, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN, "eh_return", BT_FN_VOID_PTRMODE_PTR, ATTR_NORETURN_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN_DATA_REGNO, "eh_return_data_regno", BT_FN_INT_INT, ATTR_NULL)
+DEF_LIB_BUILTIN (BUILT_IN_EXIT, "exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_EXPECT, "expect", BT_FN_LONG_LONG_LONG, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_EXTEND_POINTER, "extend_pointer", BT_FN_WORD_PTR, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_EXTRACT_RETURN_ADDR, "extract_return_addr", BT_FN_PTR_PTR, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_FRAME_ADDRESS, "frame_address", BT_FN_PTR_UNSIGNED, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_FROB_RETURN_ADDR, "frob_return_addr", BT_FN_PTR_PTR, ATTR_NULL)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_GETTEXT, "gettext", BT_FN_STRING_CONST_STRING, ATTR_FORMAT_ARG_1)
+DEF_C99_BUILTIN (BUILT_IN_IMAXABS, "imaxabs", BT_FN_INTMAX_INTMAX, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_INIT_DWARF_REG_SIZES, "init_dwarf_reg_size_table", BT_FN_VOID_PTR, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_ISGREATER, "isgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_ISGREATEREQUAL, "isgreaterequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_ISLESSEQUAL, "islessequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_ISLESSGREATER, "islessgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_ISUNORDERED, "isunordered", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_LABS, "labs", BT_FN_LONG_LONG, ATTR_CONST_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN_LLABS, "llabs", BT_FN_LONGLONG_LONGLONG, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_LONGJMP, "longjmp", BT_FN_VOID_PTR_INT, ATTR_NORETURN_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_MALLOC, "malloc", BT_FN_PTR_SIZE, ATTR_MALLOC_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_NEXT_ARG, "next_arg", BT_FN_PTR_VAR, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_PARITY, "parity", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_PARITYL, "parityl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_PARITYLL, "parityll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_POPCOUNT, "popcount", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTL, "popcountl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTLL, "popcountll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefetch", BT_FN_VOID_CONST_PTR_VAR, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UNSIGNED, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_STDARG_START, "stdarg_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL)
+DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_3_4)
+DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_3_0)
+DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", 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_VA_COPY, "va_copy", BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_VA_END, "va_end", BT_FN_VOID_VALIST_REF, ATTR_NULL)
+DEF_GCC_BUILTIN (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NULL)
+DEF_EXT_LIB_BUILTIN (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
+DEF_C99_BUILTIN (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST)
diff --git a/contrib/gcc/c-aux-info.c b/contrib/gcc/c-aux-info.c
index 761fa848606b..e785ade2239c 100644
--- a/contrib/gcc/c-aux-info.c
+++ b/contrib/gcc/c-aux-info.c
@@ -2,7 +2,7 @@
on information stored in GCC's tree structure. This code implements the
-aux-info option.
Copyright (C) 1989, 1991, 1994, 1995, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2003 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@segfault.us.com).
This file is part of GCC.
@@ -24,10 +24,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
-#include "toplev.h"
+#include "coretypes.h"
+#include "tm.h"
#include "flags.h"
#include "tree.h"
#include "c-tree.h"
+#include "toplev.h"
enum formals_style_enum {
ansi,
@@ -39,12 +41,12 @@ typedef enum formals_style_enum formals_style;
static const char *data_type;
-static char *affix_data_type PARAMS ((const char *)) ATTRIBUTE_MALLOC;
-static const char *gen_formal_list_for_type PARAMS ((tree, formals_style));
-static int deserves_ellipsis PARAMS ((tree));
-static const char *gen_formal_list_for_func_def PARAMS ((tree, formals_style));
-static const char *gen_type PARAMS ((const char *, tree, formals_style));
-static const char *gen_decl PARAMS ((tree, int, formals_style));
+static char *affix_data_type (const char *) ATTRIBUTE_MALLOC;
+static const char *gen_formal_list_for_type (tree, formals_style);
+static int deserves_ellipsis (tree);
+static const char *gen_formal_list_for_func_def (tree, formals_style);
+static const char *gen_type (const char *, tree, formals_style);
+static const char *gen_decl (tree, int, formals_style);
/* Given a string representing an entire type or an entire declaration
which only lacks the actual "data-type" specifier (at its left end),
@@ -61,8 +63,7 @@ static const char *gen_decl PARAMS ((tree, int, formals_style));
that look as expected. */
static char *
-affix_data_type (param)
- const char *param;
+affix_data_type (const char *param)
{
char *const type_or_decl = ASTRDUP (param);
char *p = type_or_decl;
@@ -108,9 +109,7 @@ affix_data_type (param)
of empty parens here. */
static const char *
-gen_formal_list_for_type (fntype, style)
- tree fntype;
- formals_style style;
+gen_formal_list_for_type (tree fntype, formals_style style)
{
const char *formal_list = "";
tree formal_type;
@@ -192,8 +191,7 @@ gen_formal_list_for_type (fntype, style)
if the "function type" parameter list should end with an ellipsis. */
static int
-deserves_ellipsis (fntype)
- tree fntype;
+deserves_ellipsis (tree fntype)
{
tree formal_type;
@@ -228,9 +226,7 @@ deserves_ellipsis (fntype)
function formal parameter list. */
static const char *
-gen_formal_list_for_func_def (fndecl, style)
- tree fndecl;
- formals_style style;
+gen_formal_list_for_func_def (tree fndecl, formals_style style)
{
const char *formal_list = "";
tree formal_decl;
@@ -303,10 +299,7 @@ gen_formal_list_for_func_def (fndecl, style)
string onto the returned "seed". */
static const char *
-gen_type (ret_val, t, style)
- const char *ret_val;
- tree t;
- formals_style style;
+gen_type (const char *ret_val, tree t, formals_style style)
{
tree chain_p;
@@ -432,13 +425,13 @@ gen_type (ret_val, t, style)
case TYPE_DECL:
data_type = IDENTIFIER_POINTER (DECL_NAME (t));
break;
-
+
case INTEGER_TYPE:
data_type = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (t)));
/* Normally, `unsigned' is part of the deal. Not so if it comes
- with a type qualifier. */
+ with a type qualifier. */
if (TREE_UNSIGNED (t) && TYPE_QUALS (t))
- data_type = concat ("unsigned ", data_type, NULL);
+ data_type = concat ("unsigned ", data_type, NULL);
break;
case REAL_TYPE:
@@ -477,10 +470,7 @@ gen_type (ret_val, t, style)
an attached list of DECL nodes for function formal arguments is present. */
static const char *
-gen_decl (decl, is_func_definition, style)
- tree decl;
- int is_func_definition;
- formals_style style;
+gen_decl (tree decl, int is_func_definition, formals_style style)
{
const char *ret_val;
@@ -558,11 +548,8 @@ extern FILE *aux_info_file;
function definition (even the implicit ones). */
void
-gen_aux_info_record (fndecl, is_definition, is_implicit, is_prototyped)
- tree fndecl;
- int is_definition;
- int is_implicit;
- int is_prototyped;
+gen_aux_info_record (tree fndecl, int is_definition, int is_implicit,
+ int is_prototyped)
{
if (flag_gen_aux_info)
{
diff --git a/contrib/gcc/c-common.c b/contrib/gcc/c-common.c
index b40a35aecb54..c5f4dadbaa0c 100644
--- a/contrib/gcc/c-common.c
+++ b/contrib/gcc/c-common.c
@@ -1,6 +1,6 @@
/* Subroutines shared by all languages that are variants of C.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,14 +21,16 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "intl.h"
#include "tree.h"
-#include "real.h"
#include "flags.h"
-#include "toplev.h"
#include "output.h"
#include "c-pragma.h"
#include "rtl.h"
#include "ggc.h"
+#include "varray.h"
#include "expr.h"
#include "c-common.h"
#include "diagnostic.h"
@@ -37,9 +39,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "cpplib.h"
#include "target.h"
#include "langhooks.h"
-#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */
#include "tree-inline.h"
#include "c-tree.h"
+#include "toplev.h"
cpp_reader *parse_in; /* Declared in c-pragma.h. */
@@ -85,14 +87,6 @@ cpp_reader *parse_in; /* Declared in c-pragma.h. */
: "long long unsigned int"))
#endif
-#ifndef REGISTER_PREFIX
-#define REGISTER_PREFIX ""
-#endif
-
-/* The variant of the C language being processed. */
-
-enum c_language_kind c_language;
-
/* The following symbols are subsumed in the c_global_trees array, and
listed here individually for documentation purposes.
@@ -106,9 +100,9 @@ enum c_language_kind c_language;
tree long_unsigned_type_node;
tree long_long_unsigned_type_node;
- tree boolean_type_node;
- tree boolean_false_node;
- tree boolean_true_node;
+ tree truthvalue_type_node;
+ tree truthvalue_false_node;
+ tree truthvalue_true_node;
tree ptrdiff_type_node;
@@ -182,25 +176,50 @@ enum c_language_kind c_language;
tree c99_function_name_decl_node;
Stack of nested function name VAR_DECLs.
-
+
tree saved_function_name_decls;
*/
tree c_global_trees[CTI_MAX];
+/* TRUE if a code represents a statement. The front end init
+ langhook should take care of initialization of this array. */
+
+bool statement_code_p[MAX_TREE_CODES];
+
/* Switches common to the C front ends. */
/* Nonzero if prepreprocessing only. */
+
int flag_preprocess_only;
+/* Nonzero means don't output line number information. */
+
+char flag_no_line_commands;
+
+/* Nonzero causes -E output not to be done, but directives such as
+ #define that have side effects are still obeyed. */
+
+char flag_no_output;
+
+/* Nonzero means dump macros in some fashion. */
+
+char flag_dump_macros;
+
+/* Nonzero means pass #include lines through to the output. */
+
+char flag_dump_includes;
+
+/* The file name to which we should write a precompiled header, or
+ NULL if no header will be written in this compile. */
+
+const char *pch_file;
+
/* Nonzero if an ISO standard was selected. It rejects macros in the
user's namespace. */
int flag_iso;
-/* Nonzero whenever Objective-C functionality is being used. */
-int flag_objc;
-
/* Nonzero if -undef was given. It suppresses target built-in macros
and assertions. */
int flag_undef;
@@ -234,13 +253,6 @@ int flag_no_asm;
int flag_const_strings;
-/* Nonzero means `$' can be in an identifier. */
-
-#ifndef DOLLARS_IN_IDENTIFIERS
-#define DOLLARS_IN_IDENTIFIERS 1
-#endif
-int dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
-
/* Nonzero means to treat bitfields as signed unless they say `unsigned'. */
int flag_signed_bitfields = 1;
@@ -274,9 +286,10 @@ int warn_parentheses;
int warn_missing_braces;
/* Warn about comparison of signed and unsigned values.
- If -1, neither -Wsign-compare nor -Wno-sign-compare has been specified. */
+ If -1, neither -Wsign-compare nor -Wno-sign-compare has been specified
+ (in which case -Wextra gets to decide). */
-int warn_sign_compare;
+int warn_sign_compare = -1;
/* Nonzero means warn about usage of long long when `-pedantic'. */
@@ -304,9 +317,9 @@ int warn_char_subscripts;
int warn_conversion;
-/* Warn about #pragma directives that are not recognized. */
+/* Warn about #pragma directives that are not recognized. */
-int warn_unknown_pragmas; /* Tri state variable. */
+int warn_unknown_pragmas; /* Tri state variable. */
/* Warn about format/argument anomalies in calls to formatted I/O functions
(*printf, *scanf, strftime, strfmon, etc.). */
@@ -333,7 +346,25 @@ int warn_format_nonliteral;
int warn_format_security;
+/* Zero means that faster, ...NonNil variants of objc_msgSend...
+ calls will be used in ObjC; passing nil receivers to such calls
+ will most likely result in crashes. */
+int flag_nil_receivers = 1;
+
+/* Nonzero means that we will allow new ObjC exception syntax (@throw,
+ @try, etc.) in source code. */
+int flag_objc_exceptions = 0;
+
+/* Nonzero means that code generation will be altered to support
+ "zero-link" execution. This currently affects ObjC only, but may
+ affect other languages in the future. */
+int flag_zero_link = 0;
+/* Nonzero means emit an '__OBJC, __image_info' for the current translation
+ unit. It will inform the ObjC runtime that class definition(s) herein
+ contained are to replace one(s) previously loaded. */
+int flag_replace_objc_classes = 0;
+
/* C/ObjC language option variables. */
@@ -355,15 +386,10 @@ int flag_isoc94;
int flag_isoc99;
-/* Nonzero means that we have builtin functions, and main is an int */
+/* Nonzero means that we have builtin functions, and main is an int. */
int flag_hosted = 1;
-/* Nonzero means add default format_arg attributes for functions not
- in ISO C. */
-
-int flag_noniso_default_format_attributes = 1;
-
/* Nonzero means warn when casting a function call to a type that does
not match the return type (e.g. (float)sqrt() or (anything*)malloc()
when there is no previous declaration of sqrt or malloc. */
@@ -374,6 +400,10 @@ int warn_bad_function_cast;
int warn_traditional;
+/* Nonzero means warn for a declaration found after a statement. */
+
+int warn_declaration_after_statement;
+
/* Nonzero means warn for non-prototype function decls
or non-prototyped defs without previous prototype. */
@@ -400,6 +430,11 @@ int warn_main;
int warn_sequence_point;
+/* Nonzero means warn about uninitialized variable when it is initialized with itself.
+ For example: int i = i;, GCC will not warn about this when warn_init_self is nonzero. */
+
+int warn_init_self;
+
/* Nonzero means to warn about compile-time division by zero. */
int warn_div_by_zero = 1;
@@ -408,10 +443,14 @@ int warn_div_by_zero = 1;
int warn_implicit_int;
/* Warn about NULL being passed to argument slots marked as requiring
- non-NULL. */
-
+ non-NULL. */
+
int warn_nonnull;
+/* Warn about old-style parameter declaration. */
+
+int warn_old_style_definition;
+
/* ObjC language option variables. */
@@ -452,7 +491,7 @@ int warn_selector;
int warn_undeclared_selector;
-/* Warn if methods required by a protocol are not implemented in the
+/* Warn if methods required by a protocol are not implemented in the
class adopting it. When turned off, methods inherited to that
class are also considered implemented. */
@@ -471,17 +510,6 @@ int flag_no_gnu_keywords;
int flag_implement_inlines = 1;
-/* Nonzero means do emit exported implementations of templates, instead of
- multiple static copies in each file that needs a definition. */
-
-int flag_external_templates;
-
-/* Nonzero means that the decision to emit or not emit the implementation of a
- template depends on where the template is instantiated, rather than where
- it is defined. */
-
-int flag_alt_external_templates;
-
/* Nonzero means that implicit instantiations will be emitted if needed. */
int flag_implicit_templates = 1;
@@ -547,15 +575,18 @@ int flag_new_for_scope = 1;
int flag_weak = 1;
+/* 0 means we want the preprocessor to not emit line directives for
+ the current working directory. 1 means we want it to do it. -1
+ means we should decide depending on whether debugging information
+ is being emitted or not. */
+
+int flag_working_directory = -1;
+
/* Nonzero to use __cxa_atexit, rather than atexit, to register
destructors for local statics and global objects. */
int flag_use_cxa_atexit = DEFAULT_USE_CXA_ATEXIT;
-/* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc. */
-
-int flag_vtable_gc;
-
/* Nonzero means make the default pedwarns warnings instead of errors.
The value of this flag is ignored if -pedantic is specified. */
@@ -568,26 +599,15 @@ int flag_permissive;
int flag_enforce_eh_specs = 1;
-/* The version of the C++ ABI in use. The following values are
- allowed:
-
- 0: The version of the ABI believed most conformant with the
- C++ ABI specification. This ABI may change as bugs are
- discovered and fixed. Therefore, 0 will not necessarily
- indicate the same ABI in different versions of G++.
-
- 1: The version of the ABI first used in G++ 3.2.
-
- Additional positive integers will be assigned as new versions of
- the ABI become the default version of the ABI. */
-
-int flag_abi_version = 1;
-
/* Nonzero means warn about things that will change when compiling
with an ABI-compliant compiler. */
int warn_abi = 0;
+/* Nonzero means warn about invalid uses of offsetof. */
+
+int warn_invalid_offsetof = 1;
+
/* Nonzero means warn about implicit declarations. */
int warn_implicit = 1;
@@ -595,7 +615,7 @@ int warn_implicit = 1;
/* Nonzero means warn when all ctors or dtors are private, and the class
has no friends. */
-int warn_ctor_dtor_privacy = 1;
+int warn_ctor_dtor_privacy = 0;
/* Nonzero means warn in function declared in derived class has the
same name as a virtual in the base class, but fails to match the
@@ -655,15 +675,11 @@ int max_tinst_depth = 500;
type names and storage classes. It is indexed by a RID_... value. */
tree *ridpointers;
-tree (*make_fname_decl) PARAMS ((tree, int));
-
-/* If non-NULL, the address of a language-specific function that
- returns 1 for language-specific statement codes. */
-int (*lang_statement_code_p) PARAMS ((enum tree_code));
+tree (*make_fname_decl) (tree, int);
/* If non-NULL, the address of a language-specific function that takes
any action required right before expand_function_end is called. */
-void (*lang_expand_function_end) PARAMS ((void));
+void (*lang_expand_function_end) (void);
/* Nonzero means the expression being parsed will never be evaluated.
This is a count, since unevaluated expressions can nest. */
@@ -690,7 +706,7 @@ const struct fname_var_t fname_vars[] =
{NULL, 0, 0},
};
-static int constant_fits_type_p PARAMS ((tree, tree));
+static int constant_fits_type_p (tree, tree);
/* Keep a stack of if statements. We record the number of compound
statements seen up to the if keyword, as well as the line number
@@ -700,8 +716,7 @@ static int constant_fits_type_p PARAMS ((tree, tree));
typedef struct
{
int compstmt_count;
- int line;
- const char *file;
+ location_t locus;
int needs_warning;
tree if_stmt;
} if_elt;
@@ -714,90 +729,58 @@ static int if_stack_space = 0;
/* Stack pointer. */
static int if_stack_pointer = 0;
-static tree handle_packed_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_nocommon_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_common_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_noreturn_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_noinline_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_always_inline_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_used_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_unused_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_const_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_transparent_union_attribute PARAMS ((tree *, tree, tree,
- int, bool *));
-static tree handle_constructor_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_destructor_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_mode_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_section_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_aligned_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_weak_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_alias_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_visibility_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_tls_model_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_no_instrument_function_attribute PARAMS ((tree *, tree,
- tree, int,
- bool *));
-static tree handle_malloc_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_no_limit_stack_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_pure_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_deprecated_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_vector_size_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_nonnull_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_nothrow_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree handle_cleanup_attribute PARAMS ((tree *, tree, tree, int,
- bool *));
-static tree vector_size_helper PARAMS ((tree, tree));
-
-static void check_function_nonnull PARAMS ((tree, tree));
-static void check_nonnull_arg PARAMS ((void *, tree,
- unsigned HOST_WIDE_INT));
-static bool nonnull_check_p PARAMS ((tree, unsigned HOST_WIDE_INT));
-static bool get_nonnull_operand PARAMS ((tree,
- unsigned HOST_WIDE_INT *));
-void builtin_define_std PARAMS ((const char *));
-static void builtin_define_with_value PARAMS ((const char *, const char *,
- int));
-static void builtin_define_with_int_value PARAMS ((const char *,
- HOST_WIDE_INT));
-static void builtin_define_with_hex_fp_value PARAMS ((const char *, tree,
- int, const char *,
- const char *));
-static void builtin_define_type_max PARAMS ((const char *, tree, int));
-static void builtin_define_type_precision PARAMS ((const char *, tree));
-static void builtin_define_float_constants PARAMS ((const char *,
- const char *, tree));
+static tree handle_packed_attribute (tree *, tree, tree, int, bool *);
+static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *);
+static tree handle_common_attribute (tree *, tree, tree, int, bool *);
+static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
+static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
+static tree handle_always_inline_attribute (tree *, tree, tree, int,
+ bool *);
+static tree handle_used_attribute (tree *, tree, tree, int, bool *);
+static tree handle_unused_attribute (tree *, tree, tree, int, bool *);
+static tree handle_const_attribute (tree *, tree, tree, int, bool *);
+static tree handle_transparent_union_attribute (tree *, tree, tree,
+ int, bool *);
+static tree handle_constructor_attribute (tree *, tree, tree, int, bool *);
+static tree handle_destructor_attribute (tree *, tree, tree, int, bool *);
+static tree handle_mode_attribute (tree *, tree, tree, int, bool *);
+static tree handle_section_attribute (tree *, tree, tree, int, bool *);
+static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
+static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
+static tree handle_alias_attribute (tree *, tree, tree, int, bool *);
+static tree handle_visibility_attribute (tree *, tree, tree, int,
+ bool *);
+static tree handle_tls_model_attribute (tree *, tree, tree, int,
+ bool *);
+static tree handle_no_instrument_function_attribute (tree *, tree,
+ tree, int, bool *);
+static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
+static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
+ bool *);
+static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
+static tree handle_deprecated_attribute (tree *, tree, tree, int,
+ bool *);
+static tree handle_vector_size_attribute (tree *, tree, tree, int,
+ bool *);
+static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *);
+static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *);
+static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *);
+static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
+ bool *);
+static tree vector_size_helper (tree, tree);
+
+static void check_function_nonnull (tree, tree);
+static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
+static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT);
+static bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *);
+static int resort_field_decl_cmp (const void *, const void *);
/* Table of machine-independent attributes common to all C-like languages. */
const struct attribute_spec c_common_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
{ "packed", 0, 0, false, false, false,
- handle_packed_attribute },
+ handle_packed_attribute },
{ "nocommon", 0, 0, true, false, false,
handle_nocommon_attribute },
{ "common", 0, 0, true, false, false,
@@ -861,11 +844,13 @@ const struct attribute_spec c_common_attribute_table[] =
{ "may_alias", 0, 0, false, true, false, NULL },
{ "cleanup", 1, 1, true, false, false,
handle_cleanup_attribute },
+ { "warn_unused_result", 0, 0, false, true, true,
+ handle_warn_unused_result_attribute },
{ NULL, 0, 0, false, false, false, NULL }
};
/* Give the specifications for the format attributes, used by C and all
- descendents. */
+ descendants. */
const struct attribute_spec c_common_format_attribute_table[] =
{
@@ -887,21 +872,18 @@ const struct attribute_spec c_common_format_attribute_table[] =
condition to keep line number information accurate. */
void
-c_expand_start_cond (cond, compstmt_count, if_stmt)
- tree cond;
- int compstmt_count;
- tree if_stmt;
+c_expand_start_cond (tree cond, int compstmt_count, tree if_stmt)
{
/* Make sure there is enough space on the stack. */
if (if_stack_space == 0)
{
if_stack_space = 10;
- if_stack = (if_elt *) xmalloc (10 * sizeof (if_elt));
+ if_stack = xmalloc (10 * sizeof (if_elt));
}
else if (if_stack_space == if_stack_pointer)
{
if_stack_space += 10;
- if_stack = (if_elt *) xrealloc (if_stack, if_stack_space * sizeof (if_elt));
+ if_stack = xrealloc (if_stack, if_stack_space * sizeof (if_elt));
}
IF_COND (if_stmt) = cond;
@@ -909,8 +891,7 @@ c_expand_start_cond (cond, compstmt_count, if_stmt)
/* Record this if statement. */
if_stack[if_stack_pointer].compstmt_count = compstmt_count;
- if_stack[if_stack_pointer].file = input_filename;
- if_stack[if_stack_pointer].line = lineno;
+ if_stack[if_stack_pointer].locus = input_location;
if_stack[if_stack_pointer].needs_warning = 0;
if_stack[if_stack_pointer].if_stmt = if_stmt;
if_stack_pointer++;
@@ -919,7 +900,7 @@ c_expand_start_cond (cond, compstmt_count, if_stmt)
/* Called after the then-clause for an if-statement is processed. */
void
-c_finish_then ()
+c_finish_then (void)
{
tree if_stmt = if_stack[if_stack_pointer - 1].if_stmt;
RECHAIN_STMTS (if_stmt, THEN_CLAUSE (if_stmt));
@@ -929,13 +910,12 @@ c_finish_then ()
if statement had an ambiguous else clause. */
void
-c_expand_end_cond ()
+c_expand_end_cond (void)
{
if_stack_pointer--;
if (if_stack[if_stack_pointer].needs_warning)
- warning_with_file_and_line (if_stack[if_stack_pointer].file,
- if_stack[if_stack_pointer].line,
- "suggest explicit braces to avoid ambiguous `else'");
+ warning ("%Hsuggest explicit braces to avoid ambiguous `else'",
+ &if_stack[if_stack_pointer].locus);
last_expr_type = NULL_TREE;
}
@@ -943,7 +923,7 @@ c_expand_end_cond ()
of an if-then-else. */
void
-c_expand_start_else ()
+c_expand_start_else (void)
{
/* An ambiguous else warning must be generated for the enclosing if
statement, unless we see an else branch for that one, too. */
@@ -963,7 +943,7 @@ c_expand_start_else ()
/* Called after the else-clause for an if-statement is processed. */
void
-c_finish_else ()
+c_finish_else (void)
{
tree if_stmt = if_stack[if_stack_pointer - 1].if_stmt;
RECHAIN_STMTS (if_stmt, ELSE_CLAUSE (if_stmt));
@@ -978,7 +958,7 @@ c_finish_else ()
beyond what is strictly necessary for correctness. */
tree
-c_begin_if_stmt ()
+c_begin_if_stmt (void)
{
tree r;
r = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
@@ -994,7 +974,7 @@ c_begin_if_stmt ()
beyond what is strictly necessary for correctness. */
tree
-c_begin_while_stmt ()
+c_begin_while_stmt (void)
{
tree r;
r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE);
@@ -1002,9 +982,7 @@ c_begin_while_stmt ()
}
void
-c_finish_while_stmt_cond (cond, while_stmt)
- tree while_stmt;
- tree cond;
+c_finish_while_stmt_cond (tree cond, tree while_stmt)
{
WHILE_COND (while_stmt) = cond;
}
@@ -1012,11 +990,11 @@ c_finish_while_stmt_cond (cond, while_stmt)
/* Push current bindings for the function name VAR_DECLS. */
void
-start_fname_decls ()
+start_fname_decls (void)
{
unsigned ix;
tree saved = NULL_TREE;
-
+
for (ix = 0; fname_vars[ix].decl; ix++)
{
tree decl = *fname_vars[ix].decl;
@@ -1042,7 +1020,7 @@ start_fname_decls ()
involved. Pop the previous bindings. */
void
-finish_fname_decls ()
+finish_fname_decls (void)
{
unsigned ix;
tree body = NULL_TREE;
@@ -1050,21 +1028,32 @@ finish_fname_decls ()
for (; stack && TREE_VALUE (stack); stack = TREE_CHAIN (stack))
body = chainon (TREE_VALUE (stack), body);
-
+
if (body)
{
- /* They were called into existence, so add to statement tree. */
- body = chainon (body,
- TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)));
- body = build_stmt (COMPOUND_STMT, body);
-
- COMPOUND_STMT_NO_SCOPE (body) = 1;
- TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)) = body;
+ /* They were called into existence, so add to statement tree. Add
+ the DECL_STMTs inside the outermost scope. */
+ tree *p = &DECL_SAVED_TREE (current_function_decl);
+ /* Skip the dummy EXPR_STMT and any EH_SPEC_BLOCK. */
+ while (TREE_CODE (*p) != COMPOUND_STMT)
+ {
+ if (TREE_CODE (*p) == EXPR_STMT)
+ p = &TREE_CHAIN (*p);
+ else
+ p = &TREE_OPERAND(*p, 0);
+ }
+
+ p = &COMPOUND_BODY (*p);
+ if (TREE_CODE (*p) == SCOPE_STMT)
+ p = &TREE_CHAIN (*p);
+
+ body = chainon (body, *p);
+ *p = body;
}
-
+
for (ix = 0; fname_vars[ix].decl; ix++)
*fname_vars[ix].decl = NULL_TREE;
-
+
if (stack)
{
/* We had saved values, restore them. */
@@ -1074,7 +1063,7 @@ finish_fname_decls ()
{
tree decl = TREE_PURPOSE (saved);
unsigned ix = TREE_INT_CST_LOW (TREE_VALUE (saved));
-
+
*fname_vars[ix].decl = decl;
}
stack = TREE_CHAIN (stack);
@@ -1082,39 +1071,25 @@ finish_fname_decls ()
saved_function_name_decls = stack;
}
-/* Return the text name of the current function, suitable prettified
+/* Return the text name of the current function, suitably prettified
by PRETTY_P. */
const char *
-fname_as_string (pretty_p)
- int pretty_p;
+fname_as_string (int pretty_p)
{
- const char *name = NULL;
-
- if (pretty_p)
- name = (current_function_decl
- ? (*lang_hooks.decl_printable_name) (current_function_decl, 2)
- : "top level");
- else if (current_function_decl && DECL_NAME (current_function_decl))
- name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
- else
- name = "";
- return name;
-}
+ const char *name = "top level";
+ int vrb = 2;
+
+ if (! pretty_p)
+ {
+ name = "";
+ vrb = 0;
+ }
-/* Return the text name of the current function, formatted as
- required by the supplied RID value. */
+ if (current_function_decl)
+ name = (*lang_hooks.decl_printable_name) (current_function_decl, vrb);
-const char *
-fname_string (rid)
- unsigned rid;
-{
- unsigned ix;
-
- for (ix = 0; fname_vars[ix].decl; ix++)
- if (fname_vars[ix].rid == rid)
- break;
- return fname_as_string (fname_vars[ix].pretty);
+ return name;
}
/* Return the VAR_DECL for a const char array naming the current
@@ -1125,9 +1100,7 @@ fname_string (rid)
this language independent code. */
tree
-fname_decl (rid, id)
- unsigned rid;
- tree id;
+fname_decl (unsigned int rid, tree id)
{
unsigned ix;
tree decl = NULL_TREE;
@@ -1145,9 +1118,9 @@ fname_decl (rid, id)
beginning of the function and this line number will be wrong.
To avoid this problem set the lineno to 0 here; that prevents
it from appearing in the RTL. */
- int saved_lineno = lineno;
- lineno = 0;
-
+ int saved_lineno = input_line;
+ input_line = 0;
+
decl = (*make_fname_decl) (id, fname_vars[ix].pretty);
if (last_tree != saved_last_tree)
{
@@ -1162,19 +1135,18 @@ fname_decl (rid, id)
saved_function_name_decls);
}
*fname_vars[ix].decl = decl;
- lineno = saved_lineno;
+ input_line = saved_lineno;
}
if (!ix && !current_function_decl)
- pedwarn_with_decl (decl, "`%s' is not defined outside of function scope");
-
+ pedwarn ("%J'%D' is not defined outside of function scope", decl, decl);
+
return decl;
}
/* Given a STRING_CST, give it a suitable array-of-chars data type. */
tree
-fix_string_type (value)
- tree value;
+fix_string_type (tree value)
{
const int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT;
const int wide_flag = TREE_TYPE (value) == wchar_array_type_node;
@@ -1185,7 +1157,7 @@ fix_string_type (value)
/* Compute the number of elements, for the array type. */
nchars = wide_flag ? length / wchar_bytes : length;
- if (pedantic && nchars - 1 > nchars_max && c_language == clk_c)
+ if (pedantic && nchars - 1 > nchars_max && !c_dialect_cxx ())
pedwarn ("string length `%d' is greater than the length `%d' ISO C%d compilers are required to support",
nchars - 1, nchars_max, flag_isoc99 ? 99 : 89);
@@ -1212,119 +1184,6 @@ fix_string_type (value)
TREE_STATIC (value) = 1;
return value;
}
-
-/* Given a VARRAY of STRING_CST nodes, concatenate them into one
- STRING_CST. */
-
-tree
-combine_strings (strings)
- varray_type strings;
-{
- const int wchar_bytes = TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT;
- const int nstrings = VARRAY_ACTIVE_SIZE (strings);
- tree value, t;
- int length = 1;
- int wide_length = 0;
- int wide_flag = 0;
- int i;
- char *p, *q;
-
- /* Don't include the \0 at the end of each substring. Count wide
- strings and ordinary strings separately. */
- for (i = 0; i < nstrings; ++i)
- {
- t = VARRAY_TREE (strings, i);
-
- if (TREE_TYPE (t) == wchar_array_type_node)
- {
- wide_length += TREE_STRING_LENGTH (t) - wchar_bytes;
- wide_flag = 1;
- }
- else
- {
- length += (TREE_STRING_LENGTH (t) - 1);
- if (C_ARTIFICIAL_STRING_P (t) && !in_system_header)
- warning ("concatenation of string literals with __FUNCTION__ is deprecated");
- }
- }
-
- /* If anything is wide, the non-wides will be converted,
- which makes them take more space. */
- if (wide_flag)
- length = length * wchar_bytes + wide_length;
-
- p = xmalloc (length);
-
- /* Copy the individual strings into the new combined string.
- If the combined string is wide, convert the chars to ints
- for any individual strings that are not wide. */
-
- q = p;
- for (i = 0; i < nstrings; ++i)
- {
- int len, this_wide;
-
- t = VARRAY_TREE (strings, i);
- this_wide = TREE_TYPE (t) == wchar_array_type_node;
- len = TREE_STRING_LENGTH (t) - (this_wide ? wchar_bytes : 1);
- if (this_wide == wide_flag)
- {
- memcpy (q, TREE_STRING_POINTER (t), len);
- q += len;
- }
- else
- {
- const int nzeros = (TYPE_PRECISION (wchar_type_node)
- / BITS_PER_UNIT) - 1;
- int j, k;
-
- if (BYTES_BIG_ENDIAN)
- {
- for (k = 0; k < len; k++)
- {
- for (j = 0; j < nzeros; j++)
- *q++ = 0;
- *q++ = TREE_STRING_POINTER (t)[k];
- }
- }
- else
- {
- for (k = 0; k < len; k++)
- {
- *q++ = TREE_STRING_POINTER (t)[k];
- for (j = 0; j < nzeros; j++)
- *q++ = 0;
- }
- }
- }
- }
-
- /* Nul terminate the string. */
- if (wide_flag)
- {
- for (i = 0; i < wchar_bytes; i++)
- *q++ = 0;
- }
- else
- *q = 0;
-
- value = build_string (length, p);
- free (p);
-
- if (wide_flag)
- TREE_TYPE (value) = wchar_array_type_node;
- else
- TREE_TYPE (value) = char_array_type_node;
-
- return value;
-}
-
-static int is_valid_printf_arglist PARAMS ((tree));
-static rtx c_expand_builtin PARAMS ((tree, rtx, enum machine_mode, enum expand_modifier));
-static rtx c_expand_builtin_printf PARAMS ((tree, rtx, enum machine_mode,
- enum expand_modifier, int, int));
-static rtx c_expand_builtin_fprintf PARAMS ((tree, rtx, enum machine_mode,
- enum expand_modifier, int, int));
/* Print a warning if a constant expression had overflow in folding.
Invoke this function on every expression that the language
@@ -1333,8 +1192,7 @@ static rtx c_expand_builtin_fprintf PARAMS ((tree, rtx, enum machine_mode,
constant expression to overflow. */
void
-constant_expression_warning (value)
- tree value;
+constant_expression_warning (tree value)
{
if ((TREE_CODE (value) == INTEGER_CST || TREE_CODE (value) == REAL_CST
|| TREE_CODE (value) == VECTOR_CST
@@ -1351,8 +1209,7 @@ constant_expression_warning (value)
however, do not invoke this function on operands of explicit casts. */
void
-overflow_warning (value)
- tree value;
+overflow_warning (tree value)
{
if ((TREE_CODE (value) == INTEGER_CST
|| (TREE_CODE (value) == COMPLEX_CST
@@ -1386,8 +1243,7 @@ overflow_warning (value)
converted to an unsigned type. */
void
-unsigned_conversion_warning (result, operand)
- tree result, operand;
+unsigned_conversion_warning (tree result, tree operand)
{
tree type = TREE_TYPE (result);
@@ -1409,23 +1265,21 @@ unsigned_conversion_warning (result, operand)
for type TYPE (an INTEGER_TYPE). */
static int
-constant_fits_type_p (c, type)
- tree c, type;
+constant_fits_type_p (tree c, tree type)
{
if (TREE_CODE (c) == INTEGER_CST)
return int_fits_type_p (c, type);
c = convert (type, c);
return !TREE_OVERFLOW (c);
-}
+}
/* Convert EXPR to TYPE, warning about conversion problems with constants.
Invoke this function on every expression that is converted implicitly,
i.e. because of language rules and not because of an explicit cast. */
tree
-convert_and_check (type, expr)
- tree type, expr;
+convert_and_check (tree type, tree expr)
{
tree t = convert (type, expr);
if (TREE_CODE (t) == INTEGER_CST)
@@ -1488,24 +1342,21 @@ static struct tlist *warned_ids;
cache the results. */
static struct tlist_cache *save_expr_cache;
-static void add_tlist PARAMS ((struct tlist **, struct tlist *, tree, int));
-static void merge_tlist PARAMS ((struct tlist **, struct tlist *, int));
-static void verify_tree PARAMS ((tree, struct tlist **, struct tlist **, tree));
-static int warning_candidate_p PARAMS ((tree));
-static void warn_for_collisions PARAMS ((struct tlist *));
-static void warn_for_collisions_1 PARAMS ((tree, tree, struct tlist *, int));
-static struct tlist *new_tlist PARAMS ((struct tlist *, tree, tree));
-static void verify_sequence_points PARAMS ((tree));
+static void add_tlist (struct tlist **, struct tlist *, tree, int);
+static void merge_tlist (struct tlist **, struct tlist *, int);
+static void verify_tree (tree, struct tlist **, struct tlist **, tree);
+static int warning_candidate_p (tree);
+static void warn_for_collisions (struct tlist *);
+static void warn_for_collisions_1 (tree, tree, struct tlist *, int);
+static struct tlist *new_tlist (struct tlist *, tree, tree);
+static void verify_sequence_points (tree);
/* Create a new struct tlist and fill in its fields. */
static struct tlist *
-new_tlist (next, t, writer)
- struct tlist *next;
- tree t;
- tree writer;
+new_tlist (struct tlist *next, tree t, tree writer)
{
struct tlist *l;
- l = (struct tlist *) obstack_alloc (&tlist_obstack, sizeof *l);
+ l = obstack_alloc (&tlist_obstack, sizeof *l);
l->next = next;
l->expr = t;
l->writer = writer;
@@ -1516,11 +1367,7 @@ new_tlist (next, t, writer)
is nonnull, we ignore any node we find which has a writer equal to it. */
static void
-add_tlist (to, add, exclude_writer, copy)
- struct tlist **to;
- struct tlist *add;
- tree exclude_writer;
- int copy;
+add_tlist (struct tlist **to, struct tlist *add, tree exclude_writer, int copy)
{
while (add)
{
@@ -1540,10 +1387,7 @@ add_tlist (to, add, exclude_writer, copy)
write. */
static void
-merge_tlist (to, add, copy)
- struct tlist **to;
- struct tlist *add;
- int copy;
+merge_tlist (struct tlist **to, struct tlist *add, int copy)
{
struct tlist **end = to;
@@ -1578,10 +1422,8 @@ merge_tlist (to, add, copy)
is nonzero. */
static void
-warn_for_collisions_1 (written, writer, list, only_writes)
- tree written, writer;
- struct tlist *list;
- int only_writes;
+warn_for_collisions_1 (tree written, tree writer, struct tlist *list,
+ int only_writes)
{
struct tlist *tmp;
@@ -1608,11 +1450,10 @@ warn_for_collisions_1 (written, writer, list, only_writes)
can cause conflicts due to missing sequence points. */
static void
-warn_for_collisions (list)
- struct tlist *list;
+warn_for_collisions (struct tlist *list)
{
struct tlist *tmp;
-
+
for (tmp = list; tmp; tmp = tmp->next)
{
if (tmp->writer)
@@ -1623,8 +1464,7 @@ warn_for_collisions (list)
/* Return nonzero if X is a tree that can be verified by the sequence point
warnings. */
static int
-warning_candidate_p (x)
- tree x;
+warning_candidate_p (tree x)
{
return TREE_CODE (x) == VAR_DECL || TREE_CODE (x) == PARM_DECL;
}
@@ -1655,10 +1495,8 @@ warning_candidate_p (x)
way, so that no more than one access to B is recorded. */
static void
-verify_tree (x, pbefore_sp, pno_sp, writer)
- tree x;
- struct tlist **pbefore_sp, **pno_sp;
- tree writer;
+verify_tree (tree x, struct tlist **pbefore_sp, struct tlist **pno_sp,
+ tree writer)
{
struct tlist *tmp_before, *tmp_nosp, *tmp_list2, *tmp_list3;
enum tree_code code;
@@ -1788,8 +1626,7 @@ verify_tree (x, pbefore_sp, pno_sp, writer)
if (! t)
{
- t = (struct tlist_cache *) obstack_alloc (&tlist_obstack,
- sizeof *t);
+ t = obstack_alloc (&tlist_obstack, sizeof *t);
t->next = save_expr_cache;
t->expr = x;
save_expr_cache = t;
@@ -1853,8 +1690,7 @@ verify_tree (x, pbefore_sp, pno_sp, writer)
points. */
static void
-verify_sequence_points (expr)
- tree expr;
+verify_sequence_points (tree expr)
{
struct tlist *before_sp = 0, *after_sp = 0;
@@ -1872,8 +1708,7 @@ verify_sequence_points (expr)
}
tree
-c_expand_expr_stmt (expr)
- tree expr;
+c_expand_expr_stmt (tree expr)
{
/* Do default conversion if safe and possibly important,
in case within ({...}). */
@@ -1890,15 +1725,14 @@ c_expand_expr_stmt (expr)
&& TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
error ("expression statement has incomplete type");
- last_expr_type = TREE_TYPE (expr);
+ last_expr_type = TREE_TYPE (expr);
return add_stmt (build_stmt (EXPR_STMT, expr));
}
/* Validate the expression after `case' and apply default promotions. */
tree
-check_case_value (value)
- tree value;
+check_case_value (tree value)
{
if (value == NULL_TREE)
return value;
@@ -1911,7 +1745,7 @@ check_case_value (value)
switch (...) { case i: ... }
So, we try to reduce the VALUE to a constant that way. */
- if (c_language == clk_cplusplus)
+ if (c_dialect_cxx ())
{
value = decl_constant_value (value);
STRIP_TYPE_NOPS (value);
@@ -1937,9 +1771,7 @@ check_case_value (value)
that is unsigned if UNSIGNEDP is nonzero, otherwise signed. */
tree
-c_common_type_for_size (bits, unsignedp)
- unsigned bits;
- int unsignedp;
+c_common_type_for_size (unsigned int bits, int unsignedp)
{
if (bits == TYPE_PRECISION (integer_type_node))
return unsignedp ? unsigned_type_node : integer_type_node;
@@ -1976,15 +1808,19 @@ c_common_type_for_size (bits, unsignedp)
return 0;
}
+/* Used for communication between c_common_type_for_mode and
+ c_register_builtin_type. */
+static GTY(()) tree registered_builtin_types;
+
/* Return a data type that has machine mode MODE.
If the mode is an integer,
then UNSIGNEDP selects between signed and unsigned types. */
tree
-c_common_type_for_mode (mode, unsignedp)
- enum machine_mode mode;
- int unsignedp;
+c_common_type_for_mode (enum machine_mode mode, int unsignedp)
{
+ tree t;
+
if (mode == TYPE_MODE (integer_type_node))
return unsignedp ? unsigned_type_node : integer_type_node;
@@ -2030,11 +1866,14 @@ c_common_type_for_mode (mode, unsignedp)
if (mode == TYPE_MODE (long_double_type_node))
return long_double_type_node;
+ if (mode == TYPE_MODE (void_type_node))
+ return void_type_node;
+
if (mode == TYPE_MODE (build_pointer_type (char_type_node)))
- return build_pointer_type (char_type_node);
+ return unsignedp ? make_unsigned_type (mode) : make_signed_type (mode);
if (mode == TYPE_MODE (build_pointer_type (integer_type_node)))
- return build_pointer_type (integer_type_node);
+ return unsignedp ? make_unsigned_type (mode) : make_signed_type (mode);
switch (mode)
{
@@ -2064,17 +1903,22 @@ c_common_type_for_mode (mode, unsignedp)
return V2SF_type_node;
case V2DFmode:
return V2DF_type_node;
+ case V4DFmode:
+ return V4DF_type_node;
default:
break;
}
+ for (t = registered_builtin_types; t; t = TREE_CHAIN (t))
+ if (TYPE_MODE (TREE_VALUE (t)) == mode)
+ return TREE_VALUE (t);
+
return 0;
}
/* Return an unsigned type the same as TYPE in other respects. */
tree
-c_common_unsigned_type (type)
- tree type;
+c_common_unsigned_type (tree type)
{
tree type1 = TYPE_MAIN_VARIANT (type);
if (type1 == signed_char_type_node || type1 == char_type_node)
@@ -2108,8 +1952,7 @@ c_common_unsigned_type (type)
/* Return a signed type the same as TYPE in other respects. */
tree
-c_common_signed_type (type)
- tree type;
+c_common_signed_type (tree type)
{
tree type1 = TYPE_MAIN_VARIANT (type);
if (type1 == unsigned_char_type_node || type1 == char_type_node)
@@ -2144,52 +1987,70 @@ c_common_signed_type (type)
signed according to UNSIGNEDP. */
tree
-c_common_signed_or_unsigned_type (unsignedp, type)
- int unsignedp;
- tree type;
+c_common_signed_or_unsigned_type (int unsignedp, tree type)
{
if (! INTEGRAL_TYPE_P (type)
|| TREE_UNSIGNED (type) == unsignedp)
return type;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
+ /* Must check the mode of the types, not the precision. Enumeral types
+ in C++ have precision set to match their range, but may use a wider
+ mode to match an ABI. If we change modes, we may wind up with bad
+ conversions. */
+
+ if (TYPE_MODE (type) == TYPE_MODE (signed_char_type_node))
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (integer_type_node))
return unsignedp ? unsigned_type_node : integer_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (short_integer_type_node))
return unsignedp ? short_unsigned_type_node : short_integer_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (long_integer_type_node))
return unsignedp ? long_unsigned_type_node : long_integer_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (long_long_integer_type_node))
return (unsignedp ? long_long_unsigned_type_node
: long_long_integer_type_node);
- if (TYPE_PRECISION (type) == TYPE_PRECISION (widest_integer_literal_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (widest_integer_literal_type_node))
return (unsignedp ? widest_unsigned_literal_type_node
: widest_integer_literal_type_node);
#if HOST_BITS_PER_WIDE_INT >= 64
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intTI_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (intTI_type_node))
return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
#endif
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intDI_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (intDI_type_node))
return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intSI_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (intSI_type_node))
return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intHI_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (intHI_type_node))
return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
- if (TYPE_PRECISION (type) == TYPE_PRECISION (intQI_type_node))
+ if (TYPE_MODE (type) == TYPE_MODE (intQI_type_node))
return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
return type;
}
+
+/* The C version of the register_builtin_type langhook. */
+
+void
+c_register_builtin_type (tree type, const char* name)
+{
+ tree decl;
+
+ decl = build_decl (TYPE_DECL, get_identifier (name), type);
+ DECL_ARTIFICIAL (decl) = 1;
+ if (!TYPE_NAME (type))
+ TYPE_NAME (type) = decl;
+ pushdecl (decl);
+
+ registered_builtin_types = tree_cons (0, type, registered_builtin_types);
+}
+
/* Return the minimum number of bits needed to represent VALUE in a
signed or unsigned type, UNSIGNEDP says which. */
unsigned int
-min_precision (value, unsignedp)
- tree value;
- int unsignedp;
+min_precision (tree value, int unsignedp)
{
int log;
@@ -2217,8 +2078,7 @@ min_precision (value, unsignedp)
c_common_truthvalue_conversion). */
void
-binary_op_error (code)
- enum tree_code code;
+binary_op_error (enum tree_code code)
{
const char *opname;
@@ -2294,10 +2154,8 @@ binary_op_error (code)
that value. */
tree
-shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
- tree *op0_ptr, *op1_ptr;
- tree *restype_ptr;
- enum tree_code *rescode_ptr;
+shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
+ enum tree_code *rescode_ptr)
{
tree type;
tree op0 = *op0_ptr;
@@ -2397,10 +2255,12 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
type = c_common_signed_or_unsigned_type (unsignedp0,
TREE_TYPE (primop0));
- /* If TYPE is an enumeration, then we need to get its min/max
- values from it's underlying integral type, not the enumerated
- type itself. */
- if (TREE_CODE (type) == ENUMERAL_TYPE)
+ /* In C, if TYPE is an enumeration, then we need to get its
+ min/max values from it's underlying integral type, not the
+ enumerated type itself. In C++, TYPE_MAX_VALUE and
+ TYPE_MIN_VALUE have already been set correctly on the
+ enumeration type. */
+ if (!c_dialect_cxx() && TREE_CODE (type) == ENUMERAL_TYPE)
type = c_common_type_for_size (TYPE_PRECISION (type), unsignedp0);
maxval = TYPE_MAX_VALUE (type);
@@ -2437,40 +2297,40 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
if (code == NE_EXPR)
{
if (max_lt || min_gt)
- val = boolean_true_node;
+ val = truthvalue_true_node;
}
else if (code == EQ_EXPR)
{
if (max_lt || min_gt)
- val = boolean_false_node;
+ val = truthvalue_false_node;
}
else if (code == LT_EXPR)
{
if (max_lt)
- val = boolean_true_node;
+ val = truthvalue_true_node;
if (!min_lt)
- val = boolean_false_node;
+ val = truthvalue_false_node;
}
else if (code == GT_EXPR)
{
if (min_gt)
- val = boolean_true_node;
+ val = truthvalue_true_node;
if (!max_gt)
- val = boolean_false_node;
+ val = truthvalue_false_node;
}
else if (code == LE_EXPR)
{
if (!max_gt)
- val = boolean_true_node;
+ val = truthvalue_true_node;
if (min_gt)
- val = boolean_false_node;
+ val = truthvalue_false_node;
}
else if (code == GE_EXPR)
{
if (!min_lt)
- val = boolean_true_node;
+ val = truthvalue_true_node;
if (max_lt)
- val = boolean_false_node;
+ val = truthvalue_false_node;
}
/* If primop0 was sign-extended and unsigned comparison specd,
@@ -2509,9 +2369,9 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
if (TREE_CODE (primop0) != INTEGER_CST)
{
- if (val == boolean_false_node)
+ if (val == truthvalue_false_node)
warning ("comparison is always false due to limited range of data type");
- if (val == boolean_true_node)
+ if (val == truthvalue_true_node)
warning ("comparison is always true due to limited range of data type");
}
@@ -2583,7 +2443,7 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
&& ! TREE_OVERFLOW (convert (c_common_signed_type (type),
primop0))))
warning ("comparison of unsigned expression >= 0 is always true");
- value = boolean_true_node;
+ value = truthvalue_true_node;
break;
case LT_EXPR:
@@ -2592,7 +2452,7 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
&& ! TREE_OVERFLOW (convert (c_common_signed_type (type),
primop0))))
warning ("comparison of unsigned expression < 0 is always false");
- value = boolean_false_node;
+ value = truthvalue_false_node;
break;
default:
@@ -2613,7 +2473,7 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
*op0_ptr = convert (type, primop0);
*op1_ptr = convert (type, primop1);
- *restype_ptr = boolean_type_node;
+ *restype_ptr = truthvalue_type_node;
return 0;
}
@@ -2622,9 +2482,7 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr)
of pointer PTROP and integer INTOP. */
tree
-pointer_int_sum (resultcode, ptrop, intop)
- enum tree_code resultcode;
- tree ptrop, intop;
+pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
{
tree size_exp;
@@ -2653,12 +2511,6 @@ pointer_int_sum (resultcode, ptrop, intop)
pedwarn ("pointer to member function used in arithmetic");
size_exp = integer_one_node;
}
- else if (TREE_CODE (TREE_TYPE (result_type)) == OFFSET_TYPE)
- {
- if (pedantic || warn_pointer_arith)
- pedwarn ("pointer to a member used in arithmetic");
- size_exp = integer_one_node;
- }
else
size_exp = size_in_bytes (TREE_TYPE (result_type));
@@ -2698,7 +2550,7 @@ pointer_int_sum (resultcode, ptrop, intop)
if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)
|| TREE_UNSIGNED (TREE_TYPE (intop)) != TREE_UNSIGNED (sizetype))
- intop = convert (c_common_type_for_size (TYPE_PRECISION (sizetype),
+ intop = convert (c_common_type_for_size (TYPE_PRECISION (sizetype),
TREE_UNSIGNED (sizetype)), intop);
/* Replace the integer argument with a suitable product by the object size.
@@ -2725,18 +2577,20 @@ pointer_int_sum (resultcode, ptrop, intop)
This preparation consists of taking the ordinary
representation of an expression expr and producing a valid tree
boolean expression describing whether expr is nonzero. We could
- simply always do build_binary_op (NE_EXPR, expr, boolean_false_node, 1),
+ simply always do build_binary_op (NE_EXPR, expr, truthvalue_false_node, 1),
but we optimize comparisons, &&, ||, and !.
- The resulting type should always be `boolean_type_node'. */
+ The resulting type should always be `truthvalue_type_node'. */
tree
-c_common_truthvalue_conversion (expr)
- tree expr;
+c_common_truthvalue_conversion (tree expr)
{
if (TREE_CODE (expr) == ERROR_MARK)
return expr;
+ if (TREE_CODE (expr) == FUNCTION_DECL)
+ expr = build_unary_op (ADDR_EXPR, expr, 0);
+
#if 0 /* This appears to be wrong for C++. */
/* These really should return error_mark_node after 2.4 is stable.
But not all callers handle ERROR_MARK properly. */
@@ -2744,15 +2598,15 @@ c_common_truthvalue_conversion (expr)
{
case RECORD_TYPE:
error ("struct type value used where scalar is required");
- return boolean_false_node;
+ return truthvalue_false_node;
case UNION_TYPE:
error ("union type value used where scalar is required");
- return boolean_false_node;
+ return truthvalue_false_node;
case ARRAY_TYPE:
error ("array type value used where scalar is required");
- return boolean_false_node;
+ return truthvalue_false_node;
default:
break;
@@ -2769,30 +2623,42 @@ c_common_truthvalue_conversion (expr)
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
case TRUTH_NOT_EXPR:
- TREE_TYPE (expr) = boolean_type_node;
+ TREE_TYPE (expr) = truthvalue_type_node;
return expr;
case ERROR_MARK:
return expr;
case INTEGER_CST:
- return integer_zerop (expr) ? boolean_false_node : boolean_true_node;
+ return integer_zerop (expr) ? truthvalue_false_node : truthvalue_true_node;
case REAL_CST:
- return real_zerop (expr) ? boolean_false_node : boolean_true_node;
+ return real_zerop (expr) ? truthvalue_false_node : truthvalue_true_node;
case ADDR_EXPR:
- /* If we are taking the address of an external decl, it might be zero
- if it is weak, so we cannot optimize. */
- if (DECL_P (TREE_OPERAND (expr, 0))
- && DECL_EXTERNAL (TREE_OPERAND (expr, 0)))
- break;
+ {
+ if (TREE_CODE (TREE_OPERAND (expr, 0)) == FUNCTION_DECL
+ && ! DECL_WEAK (TREE_OPERAND (expr, 0)))
+ {
+ /* Common Ada/Pascal programmer's mistake. We always warn
+ about this since it is so bad. */
+ warning ("the address of `%D', will always evaluate as `true'",
+ TREE_OPERAND (expr, 0));
+ return truthvalue_true_node;
+ }
- if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
- return build (COMPOUND_EXPR, boolean_type_node,
- TREE_OPERAND (expr, 0), boolean_true_node);
- else
- return boolean_true_node;
+ /* If we are taking the address of an external decl, it might be
+ zero if it is weak, so we cannot optimize. */
+ if (DECL_P (TREE_OPERAND (expr, 0))
+ && DECL_EXTERNAL (TREE_OPERAND (expr, 0)))
+ break;
+
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
+ return build (COMPOUND_EXPR, truthvalue_type_node,
+ TREE_OPERAND (expr, 0), truthvalue_true_node);
+ else
+ return truthvalue_true_node;
+ }
case COMPLEX_EXPR:
return build_binary_op ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))
@@ -2804,7 +2670,6 @@ c_common_truthvalue_conversion (expr)
case NEGATE_EXPR:
case ABS_EXPR:
case FLOAT_EXPR:
- case FFS_EXPR:
/* These don't change whether an object is nonzero or zero. */
return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0));
@@ -2813,14 +2678,14 @@ c_common_truthvalue_conversion (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 build (COMPOUND_EXPR, boolean_type_node, TREE_OPERAND (expr, 1),
+ return build (COMPOUND_EXPR, truthvalue_type_node, TREE_OPERAND (expr, 1),
c_common_truthvalue_conversion (TREE_OPERAND (expr, 0)));
else
return c_common_truthvalue_conversion (TREE_OPERAND (expr, 0));
case COND_EXPR:
/* Distribute the conversion into the arms of a COND_EXPR. */
- return fold (build (COND_EXPR, boolean_type_node, TREE_OPERAND (expr, 0),
+ return fold (build (COND_EXPR, truthvalue_type_node, TREE_OPERAND (expr, 0),
c_common_truthvalue_conversion (TREE_OPERAND (expr, 1)),
c_common_truthvalue_conversion (TREE_OPERAND (expr, 2))));
@@ -2830,7 +2695,7 @@ c_common_truthvalue_conversion (expr)
if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE
|| TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE)
break;
- /* fall through... */
+ /* Fall through.... */
case NOP_EXPR:
/* If this is widening the argument, we can ignore it. */
if (TYPE_PRECISION (TREE_TYPE (expr))
@@ -2849,7 +2714,7 @@ c_common_truthvalue_conversion (expr)
be false. */
if (HONOR_INFINITIES (TYPE_MODE (TREE_TYPE (TREE_OPERAND (expr, 0)))))
break;
- /* fall through... */
+ /* Fall through.... */
case BIT_XOR_EXPR:
/* This and MINUS_EXPR can be changed into a comparison of the
two objects. */
@@ -2864,9 +2729,9 @@ c_common_truthvalue_conversion (expr)
case BIT_AND_EXPR:
if (integer_onep (TREE_OPERAND (expr, 1))
- && TREE_TYPE (expr) != boolean_type_node)
+ && TREE_TYPE (expr) != truthvalue_type_node)
/* Using convert here would cause infinite recursion. */
- return build1 (NOP_EXPR, boolean_type_node, expr);
+ return build1 (NOP_EXPR, truthvalue_type_node, expr);
break;
case MODIFY_EXPR:
@@ -2892,25 +2757,27 @@ c_common_truthvalue_conversion (expr)
return build_binary_op (NE_EXPR, expr, integer_zero_node, 1);
}
-static tree builtin_function_2 PARAMS ((const char *, const char *, tree, tree,
- int, enum built_in_class, int, int,
- tree));
+static tree builtin_function_2 (const char *, const char *, tree, tree,
+ int, enum built_in_class, int, int,
+ tree);
/* Make a variant type in the proper way for C/C++, propagating qualifiers
down to the element type of an array. */
tree
-c_build_qualified_type (type, type_quals)
- tree type;
- int type_quals;
+c_build_qualified_type (tree type, int type_quals)
{
+ if (type == error_mark_node)
+ return type;
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ return build_array_type (c_build_qualified_type (TREE_TYPE (type),
+ type_quals),
+ TYPE_DOMAIN (type));
+
/* A restrict-qualified pointer type must be a pointer to object or
incomplete type. Note that the use of POINTER_TYPE_P also allows
- REFERENCE_TYPEs, which is appropriate for C++. Unfortunately,
- the C++ front-end also use POINTER_TYPE for pointer-to-member
- values, so even though it should be illegal to use `restrict'
- with such an entity we don't flag that here. Thus, special case
- code for that case is required in the C++ front-end. */
+ REFERENCE_TYPEs, which is appropriate for C++. */
if ((type_quals & TYPE_QUAL_RESTRICT)
&& (!POINTER_TYPE_P (type)
|| !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
@@ -2919,23 +2786,27 @@ c_build_qualified_type (type, type_quals)
type_quals &= ~TYPE_QUAL_RESTRICT;
}
- if (TREE_CODE (type) == ARRAY_TYPE)
- return build_array_type (c_build_qualified_type (TREE_TYPE (type),
- type_quals),
- TYPE_DOMAIN (type));
return build_qualified_type (type, type_quals);
}
/* Apply the TYPE_QUALS to the new DECL. */
void
-c_apply_type_quals_to_decl (type_quals, decl)
- int type_quals;
- tree decl;
+c_apply_type_quals_to_decl (int type_quals, tree decl)
{
- if ((type_quals & TYPE_QUAL_CONST)
- || (TREE_TYPE (decl)
- && TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE))
+ tree type = TREE_TYPE (decl);
+
+ if (type == error_mark_node)
+ return;
+
+ if (((type_quals & TYPE_QUAL_CONST)
+ || (type && TREE_CODE (type) == REFERENCE_TYPE))
+ /* An object declared 'const' is only readonly after it is
+ initialized. We don't have any way of expressing this currently,
+ so we need to be conservative and unset TREE_READONLY for types
+ with constructors. Otherwise aliasing code will ignore stores in
+ an inline constructor. */
+ && !(type && TYPE_NEEDS_CONSTRUCTING (type)))
TREE_READONLY (decl) = 1;
if (type_quals & TYPE_QUAL_VOLATILE)
{
@@ -2944,11 +2815,15 @@ c_apply_type_quals_to_decl (type_quals, decl)
}
if (type_quals & TYPE_QUAL_RESTRICT)
{
- if (!TREE_TYPE (decl)
- || !POINTER_TYPE_P (TREE_TYPE (decl))
- || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (TREE_TYPE (decl))))
+ while (type && TREE_CODE (type) == ARRAY_TYPE)
+ /* Allow 'restrict' on arrays of pointers.
+ FIXME currently we just ignore it. */
+ type = TREE_TYPE (type);
+ if (!type
+ || !POINTER_TYPE_P (type)
+ || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type)))
error ("invalid use of `restrict'");
- else if (flag_strict_aliasing)
+ else if (flag_strict_aliasing && type == TREE_TYPE (decl))
/* Indicate we need to make a unique alias set for this pointer.
We can't do it here because it might be pointing to an
incomplete type. */
@@ -2960,11 +2835,10 @@ c_apply_type_quals_to_decl (type_quals, decl)
or a type. Return -1 if we don't do anything special. */
HOST_WIDE_INT
-c_common_get_alias_set (t)
- tree t;
+c_common_get_alias_set (tree t)
{
tree u;
-
+
/* Permit type-punning when accessing a union, provided the access
is directly through the union. For example, this code does not
permit taking the address of a union member and then storing
@@ -2982,7 +2856,7 @@ c_common_get_alias_set (t)
if (! TYPE_P (t))
return -1;
- /* The C standard guarantess that any object may be accessed via an
+ /* The C standard guarantees that any object may be accessed via an
lvalue that has character type. */
if (t == char_type_node
|| t == signed_char_type_node
@@ -3044,18 +2918,15 @@ c_common_get_alias_set (t)
flag controls whether we should diagnose possibly ill-formed
constructs or not. */
tree
-c_sizeof_or_alignof_type (type, op, complain)
- tree type;
- enum tree_code op;
- int complain;
+c_sizeof_or_alignof_type (tree type, enum tree_code op, int complain)
{
const char *op_name;
tree value = NULL;
enum tree_code type_code = TREE_CODE (type);
-
+
my_friendly_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR, 20020720);
op_name = op == SIZEOF_EXPR ? "sizeof" : "__alignof__";
-
+
if (type_code == FUNCTION_TYPE)
{
if (op == SIZEOF_EXPR)
@@ -3069,7 +2940,7 @@ c_sizeof_or_alignof_type (type, op, complain)
}
else if (type_code == VOID_TYPE || type_code == ERROR_MARK)
{
- if (type_code == VOID_TYPE
+ if (type_code == VOID_TYPE
&& complain && (pedantic || warn_pointer_arith))
pedwarn ("invalid application of `%s' to a void type", op_name);
value = size_one_node;
@@ -3077,7 +2948,8 @@ c_sizeof_or_alignof_type (type, op, complain)
else if (!COMPLETE_TYPE_P (type))
{
if (complain)
- error ("invalid application of `%s' to an incomplete type", op_name);
+ error ("invalid application of `%s' to incomplete type `%T' ",
+ op_name, type);
value = size_zero_node;
}
else
@@ -3097,7 +2969,7 @@ c_sizeof_or_alignof_type (type, op, complain)
`size_t', which is just a typedef for an ordinary integer type. */
value = fold (build1 (NOP_EXPR, size_type_node, value));
my_friendly_assert (!TYPE_IS_SIZETYPE (TREE_TYPE (value)), 20001021);
-
+
return value;
}
@@ -3107,14 +2979,13 @@ c_sizeof_or_alignof_type (type, op, complain)
"aligned" __attribute__ specification). */
tree
-c_alignof_expr (expr)
- tree expr;
+c_alignof_expr (tree expr)
{
tree t;
if (TREE_CODE (expr) == VAR_DECL)
t = size_int (DECL_ALIGN (expr) / BITS_PER_UNIT);
-
+
else if (TREE_CODE (expr) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1)))
{
@@ -3124,13 +2995,13 @@ c_alignof_expr (expr)
else if (TREE_CODE (expr) == COMPONENT_REF
&& TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL)
t = size_int (DECL_ALIGN (TREE_OPERAND (expr, 1)) / BITS_PER_UNIT);
-
+
else if (TREE_CODE (expr) == INDIRECT_REF)
{
tree t = TREE_OPERAND (expr, 0);
tree best = t;
int bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t)));
-
+
while (TREE_CODE (t) == NOP_EXPR
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE)
{
@@ -3157,29 +3028,25 @@ enum built_in_attribute
#define DEF_ATTR_INT(ENUM, VALUE) ENUM,
#define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
-#define DEF_FN_ATTR(NAME, ATTRS, PREDICATE) /* No entry needed in enum. */
#include "builtin-attrs.def"
#undef DEF_ATTR_NULL_TREE
#undef DEF_ATTR_INT
#undef DEF_ATTR_IDENT
#undef DEF_ATTR_TREE_LIST
-#undef DEF_FN_ATTR
ATTR_LAST
};
static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
-static bool c_attrs_initialized = false;
-
-static void c_init_attributes PARAMS ((void));
+static void c_init_attributes (void);
/* Build tree nodes and builtin functions common to both C and C++ language
frontends. */
void
-c_common_nodes_and_builtins ()
+c_common_nodes_and_builtins (void)
{
- enum builtin_type
+ enum builtin_type
{
#define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
#define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
@@ -3222,25 +3089,25 @@ c_common_nodes_and_builtins ()
/* `signed' is the same as `int'. FIXME: the declarations of "signed",
"unsigned long", "long long unsigned" and "unsigned short" were in C++
but not C. Are the conditionals here needed? */
- if (c_language == clk_cplusplus)
+ if (c_dialect_cxx ())
record_builtin_type (RID_SIGNED, NULL, integer_type_node);
record_builtin_type (RID_LONG, "long int", long_integer_type_node);
record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node);
record_builtin_type (RID_MAX, "long unsigned int",
long_unsigned_type_node);
- if (c_language == clk_cplusplus)
+ if (c_dialect_cxx ())
record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node);
record_builtin_type (RID_MAX, "long long int",
long_long_integer_type_node);
record_builtin_type (RID_MAX, "long long unsigned int",
long_long_unsigned_type_node);
- if (c_language == clk_cplusplus)
+ if (c_dialect_cxx ())
record_builtin_type (RID_MAX, "long long unsigned",
long_long_unsigned_type_node);
record_builtin_type (RID_SHORT, "short int", short_integer_type_node);
record_builtin_type (RID_MAX, "short unsigned int",
short_unsigned_type_node);
- if (c_language == clk_cplusplus)
+ if (c_dialect_cxx ())
record_builtin_type (RID_MAX, "unsigned short",
short_unsigned_type_node);
@@ -3401,7 +3268,7 @@ c_common_nodes_and_builtins ()
wchar_type_node = get_identifier (MODIFIED_WCHAR_TYPE);
wchar_type_node = TREE_TYPE (identifier_global_value (wchar_type_node));
wchar_type_size = TYPE_PRECISION (wchar_type_node);
- if (c_language == clk_cplusplus)
+ if (c_dialect_cxx ())
{
if (TREE_UNSIGNED (wchar_type_node))
wchar_type_node = make_unsigned_type (wchar_type_size);
@@ -3454,7 +3321,7 @@ c_common_nodes_and_builtins ()
va_list_arg_type_node = va_list_type_node;
va_list_ref_type_node = build_reference_type (va_list_type_node);
}
-
+
#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
builtin_types[(int) ENUM] = VALUE;
#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
@@ -3469,7 +3336,7 @@ c_common_nodes_and_builtins ()
void_list_node));
#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
builtin_types[(int) ENUM] \
- = build_function_type \
+ = build_function_type \
(builtin_types[(int) RETURN], \
tree_cons (NULL_TREE, \
builtin_types[(int) ARG1], \
@@ -3495,9 +3362,9 @@ c_common_nodes_and_builtins ()
builtin_types[(int) ARG1], \
tree_cons (NULL_TREE, \
builtin_types[(int) ARG2], \
- tree_cons \
+ tree_cons \
(NULL_TREE, \
- builtin_types[(int) ARG3], \
+ builtin_types[(int) ARG3], \
tree_cons (NULL_TREE, \
builtin_types[(int) ARG4], \
void_list_node)))));
@@ -3506,14 +3373,14 @@ c_common_nodes_and_builtins ()
= build_function_type (builtin_types[(int) RETURN], NULL_TREE);
#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
builtin_types[(int) ENUM] \
- = build_function_type (builtin_types[(int) RETURN], \
+ = build_function_type (builtin_types[(int) RETURN], \
tree_cons (NULL_TREE, \
builtin_types[(int) ARG1], \
NULL_TREE));
#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
builtin_types[(int) ENUM] \
- = build_function_type \
+ = build_function_type \
(builtin_types[(int) RETURN], \
tree_cons (NULL_TREE, \
builtin_types[(int) ARG1], \
@@ -3523,7 +3390,7 @@ c_common_nodes_and_builtins ()
#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
builtin_types[(int) ENUM] \
- = build_function_type \
+ = build_function_type \
(builtin_types[(int) RETURN], \
tree_cons (NULL_TREE, \
builtin_types[(int) ARG1], \
@@ -3548,11 +3415,10 @@ c_common_nodes_and_builtins ()
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_POINTER_TYPE
- if (!c_attrs_initialized)
- c_init_attributes ();
+ c_init_attributes ();
#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, \
- BOTH_P, FALLBACK_P, NONANSI_P, ATTRS) \
+ BOTH_P, FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT) \
if (NAME) \
{ \
tree decl; \
@@ -3579,7 +3445,9 @@ c_common_nodes_and_builtins ()
built_in_attributes[(int) ATTRS]); \
\
built_in_decls[(int) ENUM] = decl; \
- }
+ if (IMPLICIT) \
+ implicit_built_in_decls[(int) ENUM] = decl; \
+ }
#include "builtins.def"
#undef DEF_BUILTIN
@@ -3589,8 +3457,7 @@ c_common_nodes_and_builtins ()
}
tree
-build_va_arg (expr, type)
- tree expr, type;
+build_va_arg (tree expr, tree type)
{
return build1 (VA_ARG_EXPR, type, expr);
}
@@ -3605,14 +3472,13 @@ typedef struct disabled_builtin
} disabled_builtin;
static disabled_builtin *disabled_builtins = NULL;
-static bool builtin_function_disabled_p PARAMS ((const char *));
+static bool builtin_function_disabled_p (const char *);
/* Disable a built-in function specified by -fno-builtin-NAME. If NAME
begins with "__builtin_", give an error. */
void
-disable_builtin_function (name)
- const char *name;
+disable_builtin_function (const char *name)
{
if (strncmp (name, "__builtin_", strlen ("__builtin_")) == 0)
error ("cannot disable built-in function `%s'", name);
@@ -3630,8 +3496,7 @@ disable_builtin_function (name)
otherwise. */
static bool
-builtin_function_disabled_p (name)
- const char *name;
+builtin_function_disabled_p (const char *name)
{
disabled_builtin *p;
for (p = disabled_builtins; p != NULL; p = p->next)
@@ -3659,34 +3524,22 @@ builtin_function_disabled_p (name)
or if NONANSI_P and flag_no_nonansi_builtin. */
static tree
-builtin_function_2 (builtin_name, name, builtin_type, type, function_code,
- class, library_name_p, nonansi_p, attrs)
- const char *builtin_name;
- const char *name;
- tree builtin_type;
- tree type;
- int function_code;
- enum built_in_class class;
- int library_name_p;
- int nonansi_p;
- tree attrs;
+builtin_function_2 (const char *builtin_name, const char *name,
+ tree builtin_type, tree type, int function_code,
+ enum built_in_class class, int library_name_p,
+ int nonansi_p, tree attrs)
{
tree bdecl = NULL_TREE;
tree decl = NULL_TREE;
+
if (builtin_name != 0)
- {
- bdecl = builtin_function (builtin_name, builtin_type, function_code,
- class, library_name_p ? name : NULL,
- attrs);
- }
+ bdecl = builtin_function (builtin_name, builtin_type, function_code,
+ class, library_name_p ? name : NULL, attrs);
+
if (name != 0 && !flag_no_builtin && !builtin_function_disabled_p (name)
&& !(nonansi_p && flag_no_nonansi_builtin))
- {
- decl = builtin_function (name, type, function_code, class, NULL,
- attrs);
- if (nonansi_p)
- DECL_BUILT_IN_NONANSI (decl) = 1;
- }
+ decl = builtin_function (name, type, function_code, class, NULL, attrs);
+
return (bdecl != 0 ? bdecl : decl);
}
@@ -3694,8 +3547,7 @@ builtin_function_2 (builtin_name, name, builtin_type, type, function_code,
integral promotions defined in ISO C99 6.3.1.1/2. */
bool
-c_promoting_integer_type_p (t)
- tree t;
+c_promoting_integer_type_p (tree t)
{
switch (TREE_CODE (t))
{
@@ -3725,8 +3577,7 @@ c_promoting_integer_type_p (t)
and none of their types is affected by default promotions. */
int
-self_promoting_args_p (parms)
- tree parms;
+self_promoting_args_p (tree parms)
{
tree t;
for (t = parms; t; t = TREE_CHAIN (t))
@@ -3752,8 +3603,7 @@ self_promoting_args_p (parms)
element type is found. */
tree
-strip_array_types (type)
- tree type;
+strip_array_types (tree type)
{
while (TREE_CODE (type) == ARRAY_TYPE)
type = TREE_TYPE (type);
@@ -3761,8 +3611,16 @@ strip_array_types (type)
return type;
}
-static tree expand_unordered_cmp PARAMS ((tree, tree, enum tree_code,
- enum tree_code));
+/* Recursively remove any '*' or '&' operator from TYPE. */
+tree
+strip_pointer_operator (tree t)
+{
+ while (POINTER_TYPE_P (t))
+ t = TREE_TYPE (t);
+ return t;
+}
+
+static tree expand_unordered_cmp (tree, tree, enum tree_code, enum tree_code);
/* Expand a call to an unordered comparison function such as
__builtin_isgreater(). FUNCTION is the function's declaration and
@@ -3774,9 +3632,9 @@ static tree expand_unordered_cmp PARAMS ((tree, tree, enum tree_code,
rest. */
static tree
-expand_unordered_cmp (function, params, unordered_code, ordered_code)
- tree function, params;
- enum tree_code unordered_code, ordered_code;
+expand_unordered_cmp (tree function, tree params,
+ enum tree_code unordered_code,
+ enum tree_code ordered_code)
{
tree arg0, arg1, type;
enum tree_code code0, code1;
@@ -3845,8 +3703,7 @@ expand_unordered_cmp (function, params, unordered_code, ordered_code)
where the similar functionality exists in the other front ends. */
tree
-expand_tree_builtin (function, params, coerced_params)
- tree function, params, coerced_params;
+expand_tree_builtin (tree function, tree params, tree coerced_params)
{
if (DECL_BUILT_IN_CLASS (function) != BUILT_IN_NORMAL)
return NULL_TREE;
@@ -3876,14 +3733,16 @@ expand_tree_builtin (function, params, coerced_params)
case BUILT_IN_CREALL:
if (coerced_params == 0)
return integer_zero_node;
- return build_unary_op (REALPART_EXPR, TREE_VALUE (coerced_params), 0);
+ return non_lvalue (build_unary_op (REALPART_EXPR,
+ TREE_VALUE (coerced_params), 0));
case BUILT_IN_CIMAG:
case BUILT_IN_CIMAGF:
case BUILT_IN_CIMAGL:
if (coerced_params == 0)
return integer_zero_node;
- return build_unary_op (IMAGPART_EXPR, TREE_VALUE (coerced_params), 0);
+ return non_lvalue (build_unary_op (IMAGPART_EXPR,
+ TREE_VALUE (coerced_params), 0));
case BUILT_IN_ISGREATER:
return expand_unordered_cmp (function, params, UNLE_EXPR, LE_EXPR);
@@ -3910,41 +3769,6 @@ expand_tree_builtin (function, params, coerced_params)
return NULL_TREE;
}
-/* Returns nonzero if CODE is the code for a statement. */
-
-int
-statement_code_p (code)
- enum tree_code code;
-{
- switch (code)
- {
- case CLEANUP_STMT:
- case EXPR_STMT:
- case COMPOUND_STMT:
- case DECL_STMT:
- case IF_STMT:
- case FOR_STMT:
- case WHILE_STMT:
- case DO_STMT:
- case RETURN_STMT:
- case BREAK_STMT:
- case CONTINUE_STMT:
- case SCOPE_STMT:
- case SWITCH_STMT:
- case GOTO_STMT:
- case LABEL_STMT:
- case ASM_STMT:
- case FILE_STMT:
- case CASE_LABEL:
- return 1;
-
- default:
- if (lang_statement_code_p)
- return (*lang_statement_code_p) (code);
- return 0;
- }
-}
-
/* Walk the statement tree, rooted at *tp. Apply FUNC to all the
sub-trees of *TP in a pre-order traversal. FUNC is called with the
DATA and the address of each sub-tree. If FUNC returns a non-NULL
@@ -3955,11 +3779,8 @@ statement_code_p (code)
We don't need a without_duplicates variant of this one because the
statement tree is a tree, not a graph. */
-tree
-walk_stmt_tree (tp, func, data)
- tree *tp;
- walk_tree_fn func;
- void *data;
+tree
+walk_stmt_tree (tree *tp, walk_tree_fn func, void *data)
{
enum tree_code code;
int walk_subtrees;
@@ -3980,7 +3801,7 @@ walk_stmt_tree (tp, func, data)
return NULL_TREE;
/* Skip subtrees below non-statement nodes. */
- if (!statement_code_p (TREE_CODE (*tp)))
+ if (!STATEMENT_CODE_P (TREE_CODE (*tp)))
return NULL_TREE;
/* Call the function. */
@@ -3994,7 +3815,7 @@ walk_stmt_tree (tp, func, data)
/* FUNC may have modified the tree, recheck that we're looking at a
statement node. */
code = TREE_CODE (*tp);
- if (!statement_code_p (code))
+ if (!STATEMENT_CODE_P (code))
return NULL_TREE;
/* Visit the subtrees unless FUNC decided that there was nothing
@@ -4024,9 +3845,7 @@ walk_stmt_tree (tp, func, data)
K2, and 0 if K1 and K2 are equal. */
int
-case_compare (k1, k2)
- splay_tree_key k1;
- splay_tree_key k2;
+case_compare (splay_tree_key k1, splay_tree_key k2)
{
/* Consider a NULL key (such as arises with a `default' label) to be
smaller than anything else. */
@@ -4048,11 +3867,8 @@ case_compare (k1, k2)
ERROR_MARK_NODE if no CASE_LABEL is created. */
tree
-c_add_case_label (cases, cond, low_value, high_value)
- splay_tree cases;
- tree cond;
- tree low_value;
- tree high_value;
+c_add_case_label (splay_tree cases, tree cond, tree low_value,
+ tree high_value)
{
tree type;
tree label;
@@ -4074,20 +3890,15 @@ c_add_case_label (cases, cond, low_value, high_value)
return error_mark_node;
}
- if ((low_value && TREE_TYPE (low_value)
- && POINTER_TYPE_P (TREE_TYPE (low_value)))
+ if ((low_value && TREE_TYPE (low_value)
+ && POINTER_TYPE_P (TREE_TYPE (low_value)))
|| (high_value && TREE_TYPE (high_value)
&& POINTER_TYPE_P (TREE_TYPE (high_value))))
error ("pointers are not permitted as case values");
/* Case ranges are a GNU extension. */
if (high_value && pedantic)
- {
- if (c_language == clk_cplusplus)
- pedwarn ("ISO C++ forbids range expressions in switch statements");
- else
- pedwarn ("ISO C forbids range expressions in switch statements");
- }
+ pedwarn ("range expressions in switch statements are non-standard");
type = TREE_TYPE (cond);
if (low_value)
@@ -4114,8 +3925,8 @@ c_add_case_label (cases, cond, low_value, high_value)
the HIGH_VALUE to simplify later processing. */
if (tree_int_cst_equal (low_value, high_value))
high_value = NULL_TREE;
- if (low_value && high_value
- && !tree_int_cst_lt (low_value, high_value))
+ if (low_value && high_value
+ && !tree_int_cst_lt (low_value, high_value))
warning ("empty range specified");
/* Look up the LOW_VALUE in the table of case labels we already
@@ -4153,7 +3964,7 @@ c_add_case_label (cases, cond, low_value, high_value)
range is bigger than the low end of the current range, so we
are only interested if the current range is a real range, and
not an ordinary case label. */
- else if (high_bound
+ else if (high_bound
&& high_value
&& (tree_int_cst_compare ((tree) high_bound->key,
high_value)
@@ -4168,18 +3979,17 @@ c_add_case_label (cases, cond, low_value, high_value)
if (high_value)
{
error ("duplicate (or overlapping) case value");
- error_with_decl (duplicate,
- "this is the first entry overlapping that value");
+ error ("%Jthis is the first entry overlapping that value", duplicate);
}
else if (low_value)
{
error ("duplicate case value") ;
- error_with_decl (duplicate, "previously used here");
+ error ("%Jpreviously used here", duplicate);
}
else
{
error ("multiple default labels in one switch");
- error_with_decl (duplicate, "this is the first default label");
+ error ("%Jthis is the first default label", duplicate);
}
if (!cases->root)
add_stmt (build_case_label (NULL_TREE, NULL_TREE, label));
@@ -4188,29 +3998,26 @@ c_add_case_label (cases, cond, low_value, high_value)
/* Add a CASE_LABEL to the statement-tree. */
case_label = add_stmt (build_case_label (low_value, high_value, label));
/* Register this case label in the splay tree. */
- splay_tree_insert (cases,
+ splay_tree_insert (cases,
(splay_tree_key) low_value,
(splay_tree_value) case_label);
return case_label;
}
-/* Finish an expression taking the address of LABEL. Returns an
- expression for the address. */
+/* Finish an expression taking the address of LABEL (an
+ IDENTIFIER_NODE). Returns an expression for the address. */
-tree
-finish_label_address_expr (label)
- tree label;
+tree
+finish_label_address_expr (tree label)
{
tree result;
if (pedantic)
- {
- if (c_language == clk_cplusplus)
- pedwarn ("ISO C++ forbids taking the address of a label");
- else
- pedwarn ("ISO C forbids taking the address of a label");
- }
+ pedwarn ("taking the address of a label is non-standard");
+
+ if (label == error_mark_node)
+ return error_mark_node;
label = lookup_label (label);
if (label == NULL_TREE)
@@ -4231,11 +4038,9 @@ finish_label_address_expr (label)
/* Hook used by expand_expr to expand language-specific tree codes. */
rtx
-c_expand_expr (exp, target, tmode, modifier)
- tree exp;
- rtx target;
- enum machine_mode tmode;
- int modifier; /* Actually enum_modifier. */
+c_expand_expr (tree exp, rtx target, enum machine_mode tmode,
+ int modifier /* Actually enum_modifier. */,
+ rtx *alt_rtl)
{
switch (TREE_CODE (exp))
{
@@ -4244,7 +4049,26 @@ c_expand_expr (exp, target, tmode, modifier)
tree rtl_expr;
rtx result;
bool preserve_result = false;
- bool return_target = false;
+
+ if (STMT_EXPR_WARN_UNUSED_RESULT (exp) && target == const0_rtx)
+ {
+ tree stmt = STMT_EXPR_STMT (exp);
+ tree scope;
+
+ for (scope = COMPOUND_BODY (stmt);
+ scope && TREE_CODE (scope) != SCOPE_STMT;
+ scope = TREE_CHAIN (scope));
+
+ if (scope && SCOPE_STMT_BLOCK (scope))
+ warning ("%Hignoring return value of `%D', "
+ "declared with attribute warn_unused_result",
+ &expr_wfl_stack->location,
+ BLOCK_ABSTRACT_ORIGIN (SCOPE_STMT_BLOCK (scope)));
+ else
+ warning ("%Hignoring return value of function "
+ "declared with attribute warn_unused_result",
+ &expr_wfl_stack->location);
+ }
/* Since expand_expr_stmt calls free_temp_slots after every
expression statement, we must call push_temp_slots here.
@@ -4272,30 +4096,18 @@ c_expand_expr (exp, target, tmode, modifier)
if (TREE_CODE (last) == SCOPE_STMT
&& TREE_CODE (expr) == EXPR_STMT)
{
- if (target && TREE_CODE (EXPR_STMT_EXPR (expr)) == VAR_DECL
- && DECL_RTL_IF_SET (EXPR_STMT_EXPR (expr)) == target)
- /* If the last expression is a variable whose RTL is the
- same as our target, just return the target; if it
- isn't valid expanding the decl would produce different
- RTL, and store_expr would try to do a copy. */
- return_target = true;
- else
- {
- /* Otherwise, note that we want the value from the last
- expression. */
- TREE_ADDRESSABLE (expr) = 1;
- preserve_result = true;
- }
+ /* Otherwise, note that we want the value from the last
+ expression. */
+ TREE_ADDRESSABLE (expr) = 1;
+ preserve_result = true;
}
}
expand_stmt (STMT_EXPR_STMT (exp));
expand_end_stmt_expr (rtl_expr);
- result = expand_expr (rtl_expr, target, tmode, modifier);
- if (return_target)
- result = target;
- else if (preserve_result && GET_CODE (result) == MEM)
+ result = expand_expr_real (rtl_expr, target, tmode, modifier, alt_rtl);
+ if (preserve_result && GET_CODE (result) == MEM)
{
if (GET_MODE (result) != BLKmode)
result = copy_to_reg (result);
@@ -4313,20 +4125,6 @@ c_expand_expr (exp, target, tmode, modifier)
return result;
}
break;
-
- case CALL_EXPR:
- {
- if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
- && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
- == FUNCTION_DECL)
- && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
- && (DECL_BUILT_IN_CLASS (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
- == BUILT_IN_FRONTEND))
- return c_expand_builtin (exp, target, tmode, modifier);
- else
- abort ();
- }
- break;
case COMPOUND_LITERAL_EXPR:
{
@@ -4334,7 +4132,7 @@ c_expand_expr (exp, target, tmode, modifier)
literal, then return the variable. */
tree decl = COMPOUND_LITERAL_EXPR_DECL (exp);
emit_local_var (decl);
- return expand_expr (decl, target, tmode, modifier);
+ return expand_expr_real (decl, target, tmode, modifier, alt_rtl);
}
default:
@@ -4348,14 +4146,12 @@ c_expand_expr (exp, target, tmode, modifier)
/* Hook used by safe_from_p to handle language-specific tree codes. */
int
-c_safe_from_p (target, exp)
- rtx target;
- tree exp;
+c_safe_from_p (rtx target, tree exp)
{
/* We can see statements here when processing the body of a
statement-expression. For a declaration statement declaring a
variable, look at the variable's initializer. */
- if (TREE_CODE (exp) == DECL_STMT)
+ if (TREE_CODE (exp) == DECL_STMT)
{
tree decl = DECL_STMT_DECL (exp);
@@ -4366,7 +4162,7 @@ c_safe_from_p (target, exp)
}
/* For any statement, we must follow the statement-chain. */
- if (statement_code_p (TREE_CODE (exp)) && TREE_CHAIN (exp))
+ if (STATEMENT_CODE_P (TREE_CODE (exp)) && TREE_CHAIN (exp))
return safe_from_p (target, TREE_CHAIN (exp), /*top_p=*/0);
/* Assume everything else is safe. */
@@ -4376,8 +4172,7 @@ c_safe_from_p (target, exp)
/* Hook used by unsafe_for_reeval to handle language-specific tree codes. */
int
-c_common_unsafe_for_reeval (exp)
- tree exp;
+c_common_unsafe_for_reeval (tree exp)
{
/* Statement expressions may not be reevaluated, likewise compound
literals. */
@@ -4392,314 +4187,24 @@ c_common_unsafe_for_reeval (exp)
/* Hook used by staticp to handle language-specific tree codes. */
int
-c_staticp (exp)
- tree exp;
+c_staticp (tree exp)
{
if (TREE_CODE (exp) == COMPOUND_LITERAL_EXPR
&& TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (exp)))
return 1;
return 0;
}
-
-#define CALLED_AS_BUILT_IN(NODE) \
- (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
-
-static rtx
-c_expand_builtin (exp, target, tmode, modifier)
- tree exp;
- rtx target;
- enum machine_mode tmode;
- enum expand_modifier modifier;
-{
- tree type = TREE_TYPE (exp);
- tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
- tree arglist = TREE_OPERAND (exp, 1);
- enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
- enum tree_code code = TREE_CODE (exp);
- const int ignore = (target == const0_rtx
- || ((code == NON_LVALUE_EXPR || code == NOP_EXPR
- || code == CONVERT_EXPR || code == REFERENCE_EXPR
- || code == COND_EXPR)
- && TREE_CODE (type) == VOID_TYPE));
-
- if (! optimize && ! CALLED_AS_BUILT_IN (fndecl))
- return expand_call (exp, target, ignore);
-
- switch (fcode)
- {
- case BUILT_IN_PRINTF:
- target = c_expand_builtin_printf (arglist, target, tmode,
- modifier, ignore, /*unlocked=*/ 0);
- if (target)
- return target;
- break;
-
- case BUILT_IN_PRINTF_UNLOCKED:
- target = c_expand_builtin_printf (arglist, target, tmode,
- modifier, ignore, /*unlocked=*/ 1);
- if (target)
- return target;
- break;
-
- case BUILT_IN_FPRINTF:
- target = c_expand_builtin_fprintf (arglist, target, tmode,
- modifier, ignore, /*unlocked=*/ 0);
- if (target)
- return target;
- break;
-
- case BUILT_IN_FPRINTF_UNLOCKED:
- target = c_expand_builtin_fprintf (arglist, target, tmode,
- modifier, ignore, /*unlocked=*/ 1);
- if (target)
- return target;
- break;
-
- default: /* just do library call, if unknown builtin */
- error ("built-in function `%s' not currently supported",
- IDENTIFIER_POINTER (DECL_NAME (fndecl)));
- }
-
- /* The switch statement above can drop through to cause the function
- to be called normally. */
- return expand_call (exp, target, ignore);
-}
-
-/* Check an arglist to *printf for problems. The arglist should start
- at the format specifier, with the remaining arguments immediately
- following it. */
-static int
-is_valid_printf_arglist (arglist)
- tree arglist;
-{
- /* Save this value so we can restore it later. */
- const int SAVE_pedantic = pedantic;
- int diagnostic_occurred = 0;
- tree attrs;
-
- /* Set this to a known value so the user setting won't affect code
- generation. */
- pedantic = 1;
- /* Check to make sure there are no format specifier errors. */
- attrs = tree_cons (get_identifier ("format"),
- tree_cons (NULL_TREE,
- get_identifier ("printf"),
- tree_cons (NULL_TREE,
- integer_one_node,
- tree_cons (NULL_TREE,
- build_int_2 (2, 0),
- NULL_TREE))),
- NULL_TREE);
- check_function_format (&diagnostic_occurred, attrs, arglist);
-
- /* Restore the value of `pedantic'. */
- pedantic = SAVE_pedantic;
-
- /* If calling `check_function_format_ptr' produces a warning, we
- return false, otherwise we return true. */
- return ! diagnostic_occurred;
-}
-
-/* If the arguments passed to printf are suitable for optimizations,
- we attempt to transform the call. */
-static rtx
-c_expand_builtin_printf (arglist, target, tmode, modifier, ignore, unlocked)
- tree arglist;
- rtx target;
- enum machine_mode tmode;
- enum expand_modifier modifier;
- int ignore;
- int unlocked;
-{
- tree fn_putchar = unlocked ?
- built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] : built_in_decls[BUILT_IN_PUTCHAR];
- tree fn_puts = unlocked ?
- built_in_decls[BUILT_IN_PUTS_UNLOCKED] : built_in_decls[BUILT_IN_PUTS];
- tree fn, format_arg, stripped_string;
-
- /* If the return value is used, or the replacement _DECL isn't
- initialized, don't do the transformation. */
- if (!ignore || !fn_putchar || !fn_puts)
- return 0;
-
- /* Verify the required arguments in the original call. */
- if (arglist == 0
- || (TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE))
- return 0;
-
- /* Check the specifier vs. the parameters. */
- if (!is_valid_printf_arglist (arglist))
- return 0;
-
- format_arg = TREE_VALUE (arglist);
- stripped_string = format_arg;
- STRIP_NOPS (stripped_string);
- if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR)
- stripped_string = TREE_OPERAND (stripped_string, 0);
-
- /* If the format specifier isn't a STRING_CST, punt. */
- if (TREE_CODE (stripped_string) != STRING_CST)
- return 0;
-
- /* OK! We can attempt optimization. */
-
- /* If the format specifier was "%s\n", call __builtin_puts(arg2). */
- if (strcmp (TREE_STRING_POINTER (stripped_string), "%s\n") == 0)
- {
- arglist = TREE_CHAIN (arglist);
- fn = fn_puts;
- }
- /* If the format specifier was "%c", call __builtin_putchar (arg2). */
- else if (strcmp (TREE_STRING_POINTER (stripped_string), "%c") == 0)
- {
- arglist = TREE_CHAIN (arglist);
- fn = fn_putchar;
- }
- else
- {
- /* We can't handle anything else with % args or %% ... yet. */
- if (strchr (TREE_STRING_POINTER (stripped_string), '%'))
- return 0;
-
- /* If the resulting constant string has a length of 1, call
- putchar. Note, TREE_STRING_LENGTH includes the terminating
- NULL in its count. */
- if (TREE_STRING_LENGTH (stripped_string) == 2)
- {
- /* Given printf("c"), (where c is any one character,)
- convert "c"[0] to an int and pass that to the replacement
- function. */
- arglist = build_int_2 (TREE_STRING_POINTER (stripped_string)[0], 0);
- arglist = build_tree_list (NULL_TREE, arglist);
-
- fn = fn_putchar;
- }
- /* If the resulting constant was "string\n", call
- __builtin_puts("string"). Ensure "string" has at least one
- character besides the trailing \n. Note, TREE_STRING_LENGTH
- includes the terminating NULL in its count. */
- else if (TREE_STRING_LENGTH (stripped_string) > 2
- && TREE_STRING_POINTER (stripped_string)
- [TREE_STRING_LENGTH (stripped_string) - 2] == '\n')
- {
- /* Create a NULL-terminated string that's one char shorter
- than the original, stripping off the trailing '\n'. */
- const int newlen = TREE_STRING_LENGTH (stripped_string) - 1;
- char *newstr = (char *) alloca (newlen);
- memcpy (newstr, TREE_STRING_POINTER (stripped_string), newlen - 1);
- newstr[newlen - 1] = 0;
-
- arglist = fix_string_type (build_string (newlen, newstr));
- arglist = build_tree_list (NULL_TREE, arglist);
- fn = fn_puts;
- }
- else
- /* We'd like to arrange to call fputs(string) here, but we
- need stdout and don't have a way to get it ... yet. */
- return 0;
- }
-
- return expand_expr (build_function_call (fn, arglist),
- (ignore ? const0_rtx : target),
- tmode, modifier);
-}
-
-/* If the arguments passed to fprintf are suitable for optimizations,
- we attempt to transform the call. */
-static rtx
-c_expand_builtin_fprintf (arglist, target, tmode, modifier, ignore, unlocked)
- tree arglist;
- rtx target;
- enum machine_mode tmode;
- enum expand_modifier modifier;
- int ignore;
- int unlocked;
-{
- tree fn_fputc = unlocked ?
- built_in_decls[BUILT_IN_FPUTC_UNLOCKED] : built_in_decls[BUILT_IN_FPUTC];
- tree fn_fputs = unlocked ?
- built_in_decls[BUILT_IN_FPUTS_UNLOCKED] : built_in_decls[BUILT_IN_FPUTS];
- tree fn, format_arg, stripped_string;
-
- /* If the return value is used, or the replacement _DECL isn't
- initialized, don't do the transformation. */
- if (!ignore || !fn_fputc || !fn_fputs)
- return 0;
-
- /* Verify the required arguments in the original call. */
- if (arglist == 0
- || (TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
- || (TREE_CHAIN (arglist) == 0)
- || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) !=
- POINTER_TYPE))
- return 0;
-
- /* Check the specifier vs. the parameters. */
- if (!is_valid_printf_arglist (TREE_CHAIN (arglist)))
- return 0;
-
- format_arg = TREE_VALUE (TREE_CHAIN (arglist));
- stripped_string = format_arg;
- STRIP_NOPS (stripped_string);
- if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR)
- stripped_string = TREE_OPERAND (stripped_string, 0);
-
- /* If the format specifier isn't a STRING_CST, punt. */
- if (TREE_CODE (stripped_string) != STRING_CST)
- return 0;
-
- /* OK! We can attempt optimization. */
-
- /* If the format specifier was "%s", call __builtin_fputs(arg3, arg1). */
- if (strcmp (TREE_STRING_POINTER (stripped_string), "%s") == 0)
- {
- tree newarglist = build_tree_list (NULL_TREE, TREE_VALUE (arglist));
- arglist = tree_cons (NULL_TREE,
- TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
- newarglist);
- fn = fn_fputs;
- }
- /* If the format specifier was "%c", call __builtin_fputc (arg3, arg1). */
- else if (strcmp (TREE_STRING_POINTER (stripped_string), "%c") == 0)
- {
- tree newarglist = build_tree_list (NULL_TREE, TREE_VALUE (arglist));
- arglist = tree_cons (NULL_TREE,
- TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))),
- newarglist);
- fn = fn_fputc;
- }
- else
- {
- /* We can't handle anything else with % args or %% ... yet. */
- if (strchr (TREE_STRING_POINTER (stripped_string), '%'))
- return 0;
-
- /* When "string" doesn't contain %, replace all cases of
- fprintf(stream,string) with fputs(string,stream). The fputs
- builtin will take take of special cases like length==1. */
- arglist = tree_cons (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)),
- build_tree_list (NULL_TREE, TREE_VALUE (arglist)));
- fn = fn_fputs;
- }
-
- return expand_expr (build_function_call (fn, arglist),
- (ignore ? const0_rtx : target),
- tmode, modifier);
-}
/* Given a boolean expression ARG, return a tree representing an increment
or decrement (as indicated by CODE) of ARG. The front end must check for
invalid cases (e.g., decrement in C++). */
tree
-boolean_increment (code, arg)
- enum tree_code code;
- tree arg;
+boolean_increment (enum tree_code code, tree arg)
{
tree val;
- tree true_res = (c_language == clk_cplusplus
- ? boolean_true_node
- : c_bool_true_node);
+ tree true_res = boolean_true_node;
+
arg = stabilize_reference (arg);
switch (code)
{
@@ -4728,453 +4233,19 @@ boolean_increment (code, arg)
return val;
}
-/* Define NAME with value TYPE precision. */
-static void
-builtin_define_type_precision (name, type)
- const char *name;
- tree type;
-{
- builtin_define_with_int_value (name, TYPE_PRECISION (type));
-}
-
-/* Define the float.h constants for TYPE using NAME_PREFIX and FP_SUFFIX. */
-static void
-builtin_define_float_constants (name_prefix, fp_suffix, type)
- const char *name_prefix;
- const char *fp_suffix;
- tree type;
-{
- /* Used to convert radix-based values to base 10 values in several cases.
-
- In the max_exp -> max_10_exp conversion for 128-bit IEEE, we need at
- least 6 significant digits for correct results. Using the fraction
- formed by (log(2)*1e6)/(log(10)*1e6) overflows a 32-bit integer as an
- intermediate; perhaps someone can find a better approximation, in the
- mean time, I suspect using doubles won't harm the bootstrap here. */
-
- const double log10_2 = .30102999566398119521;
- double log10_b;
- const struct real_format *fmt;
-
- char name[64], buf[128];
- int dig, min_10_exp, max_10_exp;
- int decimal_dig;
-
- fmt = real_format_for_mode[TYPE_MODE (type) - QFmode];
-
- /* The radix of the exponent representation. */
- if (type == float_type_node)
- builtin_define_with_int_value ("__FLT_RADIX__", fmt->b);
- log10_b = log10_2 * fmt->log2_b;
-
- /* The number of radix digits, p, in the floating-point significand. */
- sprintf (name, "__%s_MANT_DIG__", name_prefix);
- builtin_define_with_int_value (name, fmt->p);
-
- /* The number of decimal digits, q, such that any floating-point number
- with q decimal digits can be rounded into a floating-point number with
- p radix b digits and back again without change to the q decimal digits,
-
- p log10 b if b is a power of 10
- floor((p - 1) log10 b) otherwise
- */
- dig = (fmt->p - 1) * log10_b;
- sprintf (name, "__%s_DIG__", name_prefix);
- builtin_define_with_int_value (name, dig);
-
- /* The minimum negative int x such that b**(x-1) is a normalized float. */
- sprintf (name, "__%s_MIN_EXP__", name_prefix);
- sprintf (buf, "(%d)", fmt->emin);
- builtin_define_with_value (name, buf, 0);
-
- /* The minimum negative int x such that 10**x is a normalized float,
-
- ceil (log10 (b ** (emin - 1)))
- = ceil (log10 (b) * (emin - 1))
-
- Recall that emin is negative, so the integer truncation calculates
- the ceiling, not the floor, in this case. */
- min_10_exp = (fmt->emin - 1) * log10_b;
- sprintf (name, "__%s_MIN_10_EXP__", name_prefix);
- sprintf (buf, "(%d)", min_10_exp);
- builtin_define_with_value (name, buf, 0);
-
- /* The maximum int x such that b**(x-1) is a representable float. */
- sprintf (name, "__%s_MAX_EXP__", name_prefix);
- builtin_define_with_int_value (name, fmt->emax);
-
- /* The maximum int x such that 10**x is in the range of representable
- finite floating-point numbers,
-
- floor (log10((1 - b**-p) * b**emax))
- = floor (log10(1 - b**-p) + log10(b**emax))
- = floor (log10(1 - b**-p) + log10(b)*emax)
-
- The safest thing to do here is to just compute this number. But since
- we don't link cc1 with libm, we cannot. We could implement log10 here
- a series expansion, but that seems too much effort because:
-
- Note that the first term, for all extant p, is a number exceedingly close
- to zero, but slightly negative. Note that the second term is an integer
- scaling an irrational number, and that because of the floor we are only
- interested in its integral portion.
-
- In order for the first term to have any effect on the integral portion
- of the second term, the second term has to be exceedingly close to an
- integer itself (e.g. 123.000000000001 or something). Getting a result
- that close to an integer requires that the irrational multiplicand have
- a long series of zeros in its expansion, which doesn't occur in the
- first 20 digits or so of log10(b).
-
- Hand-waving aside, crunching all of the sets of constants above by hand
- does not yield a case for which the first term is significant, which
- in the end is all that matters. */
- max_10_exp = fmt->emax * log10_b;
- sprintf (name, "__%s_MAX_10_EXP__", name_prefix);
- builtin_define_with_int_value (name, max_10_exp);
-
- /* The number of decimal digits, n, such that any floating-point number
- can be rounded to n decimal digits and back again without change to
- the value.
-
- p * log10(b) if b is a power of 10
- ceil(1 + p * log10(b)) otherwise
-
- The only macro we care about is this number for the widest supported
- floating type, but we want this value for rendering constants below. */
- {
- double d_decimal_dig = 1 + fmt->p * log10_b;
- decimal_dig = d_decimal_dig;
- if (decimal_dig < d_decimal_dig)
- decimal_dig++;
- }
- if (type == long_double_type_node)
- builtin_define_with_int_value ("__DECIMAL_DIG__", decimal_dig);
-
- /* Since, for the supported formats, B is always a power of 2, we
- construct the following numbers directly as a hexadecimal
- constants. */
-
- /* The maximum representable finite floating-point number,
- (1 - b**-p) * b**emax */
- {
- int i, n;
- char *p;
-
- strcpy (buf, "0x0.");
- n = fmt->p * fmt->log2_b;
- for (i = 0, p = buf + 4; i + 3 < n; i += 4)
- *p++ = 'f';
- if (i < n)
- *p++ = "08ce"[n - i];
- sprintf (p, "p%d", fmt->emax * fmt->log2_b);
- }
- sprintf (name, "__%s_MAX__", name_prefix);
- builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
-
- /* The minimum normalized positive floating-point number,
- b**(emin-1). */
- sprintf (name, "__%s_MIN__", name_prefix);
- sprintf (buf, "0x1p%d", (fmt->emin - 1) * fmt->log2_b);
- builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
-
- /* The difference between 1 and the least value greater than 1 that is
- representable in the given floating point type, b**(1-p). */
- sprintf (name, "__%s_EPSILON__", name_prefix);
- sprintf (buf, "0x1p%d", (1 - fmt->p) * fmt->log2_b);
- builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
-
- /* For C++ std::numeric_limits<T>::denorm_min. The minimum denormalized
- positive floating-point number, b**(emin-p). Zero for formats that
- don't support denormals. */
- sprintf (name, "__%s_DENORM_MIN__", name_prefix);
- if (fmt->has_denorm)
- {
- sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b);
- builtin_define_with_hex_fp_value (name, type, decimal_dig,
- buf, fp_suffix);
- }
- else
- {
- sprintf (buf, "0.0%s", fp_suffix);
- builtin_define_with_value (name, buf, 0);
- }
-}
-
-/* Hook that registers front end and target-specific built-ins. */
+/* Built-in macros for stddef.h, that require macros defined in this
+ file. */
void
-cb_register_builtins (pfile)
- cpp_reader *pfile;
+c_stddef_cpp_builtins(void)
{
- /* -undef turns off target-specific built-ins. */
- if (flag_undef)
- return;
-
- if (c_language == clk_cplusplus)
- {
- if (SUPPORTS_ONE_ONLY)
- cpp_define (pfile, "__GXX_WEAK__=1");
- else
- cpp_define (pfile, "__GXX_WEAK__=0");
- if (warn_deprecated)
- cpp_define (pfile, "__DEPRECATED");
- }
- if (flag_exceptions)
- cpp_define (pfile, "__EXCEPTIONS");
-
- /* represents the C++ ABI version, always defined so it can be used while
- preprocessing C and assembler. */
- cpp_define (pfile, "__GXX_ABI_VERSION=102");
-
- /* libgcc needs to know this. */
- if (USING_SJLJ_EXCEPTIONS)
- cpp_define (pfile, "__USING_SJLJ_EXCEPTIONS__");
-
- /* stddef.h needs to know these. */
builtin_define_with_value ("__SIZE_TYPE__", SIZE_TYPE, 0);
builtin_define_with_value ("__PTRDIFF_TYPE__", PTRDIFF_TYPE, 0);
builtin_define_with_value ("__WCHAR_TYPE__", MODIFIED_WCHAR_TYPE, 0);
builtin_define_with_value ("__WINT_TYPE__", WINT_TYPE, 0);
-
- /* limits.h needs to know these. */
- builtin_define_type_max ("__SCHAR_MAX__", signed_char_type_node, 0);
- builtin_define_type_max ("__SHRT_MAX__", short_integer_type_node, 0);
- builtin_define_type_max ("__INT_MAX__", integer_type_node, 0);
- builtin_define_type_max ("__LONG_MAX__", long_integer_type_node, 1);
- builtin_define_type_max ("__LONG_LONG_MAX__", long_long_integer_type_node, 2);
- builtin_define_type_max ("__WCHAR_MAX__", wchar_type_node, 0);
-
- builtin_define_type_precision ("__CHAR_BIT__", char_type_node);
-
- /* float.h needs to know these. */
-
- builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
- TARGET_FLT_EVAL_METHOD);
-
- builtin_define_float_constants ("FLT", "F", float_type_node);
- builtin_define_float_constants ("DBL", "", double_type_node);
- builtin_define_float_constants ("LDBL", "L", long_double_type_node);
-
- /* For use in assembly language. */
- builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0);
- builtin_define_with_value ("__USER_LABEL_PREFIX__", user_label_prefix, 0);
-
- /* Misc. */
- builtin_define_with_value ("__VERSION__", version_string, 1);
-
- /* Other target-independent built-ins determined by command-line
- options. */
- if (optimize_size)
- cpp_define (pfile, "__OPTIMIZE_SIZE__");
- if (optimize)
- cpp_define (pfile, "__OPTIMIZE__");
-
- if (flag_hosted)
- cpp_define (pfile, "__STDC_HOSTED__=1");
- else
- cpp_define (pfile, "__STDC_HOSTED__=0");
-
- if (fast_math_flags_set_p ())
- cpp_define (pfile, "__FAST_MATH__");
- if (flag_really_no_inline)
- cpp_define (pfile, "__NO_INLINE__");
- if (flag_signaling_nans)
- cpp_define (pfile, "__SUPPORT_SNAN__");
- if (flag_finite_math_only)
- cpp_define (pfile, "__FINITE_MATH_ONLY__=1");
- else
- cpp_define (pfile, "__FINITE_MATH_ONLY__=0");
-
- if (flag_iso)
- cpp_define (pfile, "__STRICT_ANSI__");
-
- if (!flag_signed_char)
- cpp_define (pfile, "__CHAR_UNSIGNED__");
-
- if (c_language == clk_cplusplus && TREE_UNSIGNED (wchar_type_node))
- cpp_define (pfile, "__WCHAR_UNSIGNED__");
-
- /* Make the choice of ObjC runtime visible to source code. */
- if (flag_objc && flag_next_runtime)
- cpp_define (pfile, "__NEXT_RUNTIME__");
-
- /* A straightforward target hook doesn't work, because of problems
- linking that hook's body when part of non-C front ends. */
-# define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM)
-# define preprocessing_trad_p() (cpp_get_options (pfile)->traditional)
-# define builtin_define(TXT) cpp_define (pfile, TXT)
-# define builtin_assert(TXT) cpp_assert (pfile, TXT)
- TARGET_CPU_CPP_BUILTINS ();
- TARGET_OS_CPP_BUILTINS ();
}
-/* Pass an object-like macro. If it doesn't lie in the user's
- namespace, defines it unconditionally. Otherwise define a version
- with two leading underscores, and another version with two leading
- and trailing underscores, and define the original only if an ISO
- standard was not nominated.
-
- e.g. passing "unix" defines "__unix", "__unix__" and possibly
- "unix". Passing "_mips" defines "__mips", "__mips__" and possibly
- "_mips". */
-void
-builtin_define_std (macro)
- const char *macro;
-{
- size_t len = strlen (macro);
- char *buff = alloca (len + 5);
- char *p = buff + 2;
- char *q = p + len;
-
- /* prepend __ (or maybe just _) if in user's namespace. */
- memcpy (p, macro, len + 1);
- if (!( *p == '_' && (p[1] == '_' || ISUPPER (p[1]))))
- {
- if (*p != '_')
- *--p = '_';
- if (p[1] != '_')
- *--p = '_';
- }
- cpp_define (parse_in, p);
-
- /* If it was in user's namespace... */
- if (p != buff + 2)
- {
- /* Define the macro with leading and following __. */
- if (q[-1] != '_')
- *q++ = '_';
- if (q[-2] != '_')
- *q++ = '_';
- *q = '\0';
- cpp_define (parse_in, p);
-
- /* Finally, define the original macro if permitted. */
- if (!flag_iso)
- cpp_define (parse_in, macro);
- }
-}
-
-/* Pass an object-like macro and a value to define it to. The third
- parameter says whether or not to turn the value into a string
- constant. */
static void
-builtin_define_with_value (macro, expansion, is_str)
- const char *macro;
- const char *expansion;
- int is_str;
-{
- char *buf;
- size_t mlen = strlen (macro);
- size_t elen = strlen (expansion);
- size_t extra = 2; /* space for an = and a NUL */
-
- if (is_str)
- extra += 2; /* space for two quote marks */
-
- buf = alloca (mlen + elen + extra);
- if (is_str)
- sprintf (buf, "%s=\"%s\"", macro, expansion);
- else
- sprintf (buf, "%s=%s", macro, expansion);
-
- cpp_define (parse_in, buf);
-}
-
-/* Pass an object-like macro and an integer value to define it to. */
-static void
-builtin_define_with_int_value (macro, value)
- const char *macro;
- HOST_WIDE_INT value;
-{
- char *buf;
- size_t mlen = strlen (macro);
- size_t vlen = 18;
- size_t extra = 2; /* space for = and NUL. */
-
- buf = alloca (mlen + vlen + extra);
- memcpy (buf, macro, mlen);
- buf[mlen] = '=';
- sprintf (buf + mlen + 1, HOST_WIDE_INT_PRINT_DEC, value);
-
- cpp_define (parse_in, buf);
-}
-
-/* Pass an object-like macro a hexadecimal floating-point value. */
-static void
-builtin_define_with_hex_fp_value (macro, type, digits, hex_str, fp_suffix)
- const char *macro;
- tree type ATTRIBUTE_UNUSED;
- int digits;
- const char *hex_str;
- const char *fp_suffix;
-{
- REAL_VALUE_TYPE real;
- char dec_str[64], buf[256];
-
- /* Hex values are really cool and convenient, except that they're
- not supported in strict ISO C90 mode. First, the "p-" sequence
- is not valid as part of a preprocessor number. Second, we get a
- pedwarn from the preprocessor, which has no context, so we can't
- suppress the warning with __extension__.
-
- So instead what we do is construct the number in hex (because
- it's easy to get the exact correct value), parse it as a real,
- then print it back out as decimal. */
-
- real_from_string (&real, hex_str);
- real_to_decimal (dec_str, &real, sizeof (dec_str), digits, 0);
-
- sprintf (buf, "%s=%s%s", macro, dec_str, fp_suffix);
- cpp_define (parse_in, buf);
-}
-
-/* Define MAX for TYPE based on the precision of the type. IS_LONG is
- 1 for type "long" and 2 for "long long". We have to handle
- unsigned types, since wchar_t might be unsigned. */
-
-static void
-builtin_define_type_max (macro, type, is_long)
- const char *macro;
- tree type;
- int is_long;
-{
- static const char *const values[]
- = { "127", "255",
- "32767", "65535",
- "2147483647", "4294967295",
- "9223372036854775807", "18446744073709551615",
- "170141183460469231731687303715884105727",
- "340282366920938463463374607431768211455" };
- static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" };
-
- const char *value, *suffix;
- char *buf;
- size_t idx;
-
- /* Pre-rendering the values mean we don't have to futz with printing a
- multi-word decimal value. There are also a very limited number of
- precisions that we support, so it's really a waste of time. */
- switch (TYPE_PRECISION (type))
- {
- case 8: idx = 0; break;
- case 16: idx = 2; break;
- case 32: idx = 4; break;
- case 64: idx = 6; break;
- case 128: idx = 8; break;
- default: abort ();
- }
-
- value = values[idx + TREE_UNSIGNED (type)];
- suffix = suffixes[is_long * 2 + TREE_UNSIGNED (type)];
-
- buf = alloca (strlen (macro) + 1 + strlen (value) + strlen (suffix) + 1);
- sprintf (buf, "%s=%s%s", macro, value, suffix);
-
- cpp_define (parse_in, buf);
-}
-
-static void
-c_init_attributes ()
+c_init_attributes (void)
{
/* Fill in the built_in_attributes array. */
#define DEF_ATTR_NULL_TREE(ENUM) \
@@ -5188,54 +4259,11 @@ c_init_attributes ()
= tree_cons (built_in_attributes[(int) PURPOSE], \
built_in_attributes[(int) VALUE], \
built_in_attributes[(int) CHAIN]);
-#define DEF_FN_ATTR(NAME, ATTRS, PREDICATE) /* No initialization needed. */
-#include "builtin-attrs.def"
-#undef DEF_ATTR_NULL_TREE
-#undef DEF_ATTR_INT
-#undef DEF_ATTR_IDENT
-#undef DEF_ATTR_TREE_LIST
-#undef DEF_FN_ATTR
- c_attrs_initialized = true;
-}
-
-/* Depending on the name of DECL, apply default attributes to it. */
-
-void
-c_common_insert_default_attributes (decl)
- tree decl;
-{
- tree name = DECL_NAME (decl);
-
- if (!c_attrs_initialized)
- c_init_attributes ();
-
-#define DEF_ATTR_NULL_TREE(ENUM) /* Nothing needed after initialization. */
-#define DEF_ATTR_INT(ENUM, VALUE)
-#define DEF_ATTR_IDENT(ENUM, STRING)
-#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN)
-#define DEF_FN_ATTR(NAME, ATTRS, PREDICATE) \
- if ((PREDICATE) && name == built_in_attributes[(int) NAME]) \
- decl_attributes (&decl, built_in_attributes[(int) ATTRS], \
- ATTR_FLAG_BUILT_IN);
#include "builtin-attrs.def"
#undef DEF_ATTR_NULL_TREE
#undef DEF_ATTR_INT
#undef DEF_ATTR_IDENT
#undef DEF_ATTR_TREE_LIST
-#undef DEF_FN_ATTR
-}
-
-/* Output a -Wshadow warning MSGID about NAME, an IDENTIFIER_NODE, and
- additionally give the location of the previous declaration DECL. */
-void
-shadow_warning (msgid, name, decl)
- const char *msgid;
- tree name, decl;
-{
- warning ("declaration of `%s' shadows %s", IDENTIFIER_POINTER (name), msgid);
- warning_with_file_and_line (DECL_SOURCE_FILE (decl),
- DECL_SOURCE_LINE (decl),
- "shadowed declaration is here");
}
/* Attribute handlers common to C front ends. */
@@ -5244,32 +4272,36 @@ shadow_warning (msgid, name, decl)
struct attribute_spec.handler. */
static tree
-handle_packed_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags;
- bool *no_add_attrs;
+handle_packed_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
+ int flags, bool *no_add_attrs)
{
- tree *type = NULL;
- if (DECL_P (*node))
- {
- if (TREE_CODE (*node) == TYPE_DECL)
- type = &TREE_TYPE (*node);
- }
- else
- type = node;
-
- if (type)
+ if (TYPE_P (*node))
{
if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
- *type = build_type_copy (*type);
- TYPE_PACKED (*type) = 1;
+ *node = build_type_copy (*node);
+ TYPE_PACKED (*node) = 1;
+ if (TYPE_MAIN_VARIANT (*node) == *node)
+ {
+ /* If it is the main variant, then pack the other variants
+ too. This happens in,
+
+ struct Foo {
+ struct Foo const *ptr; // creates a variant w/o packed flag
+ } __ attribute__((packed)); // packs it now.
+ */
+ tree probe;
+
+ for (probe = *node; probe; probe = TYPE_NEXT_VARIANT (probe))
+ TYPE_PACKED (probe) = 1;
+ }
+
}
else if (TREE_CODE (*node) == FIELD_DECL)
DECL_PACKED (*node) = 1;
/* We can't set DECL_PACKED for a VAR_DECL, because the bit is
- used for DECL_REGISTER. It wouldn't mean anything anyway. */
+ used for DECL_REGISTER. It wouldn't mean anything anyway.
+ We can't set DECL_PACKED on the type of a TYPE_DECL, because
+ that changes what the typedef is typing. */
else
{
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
@@ -5283,12 +4315,9 @@ handle_packed_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_nocommon_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_nocommon_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) == VAR_DECL)
DECL_COMMON (*node) = 0;
@@ -5305,12 +4334,8 @@ handle_nocommon_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_common_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_common_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) == VAR_DECL)
DECL_COMMON (*node) = 1;
@@ -5327,12 +4352,8 @@ handle_common_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_noreturn_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_noreturn_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
tree type = TREE_TYPE (*node);
@@ -5358,12 +4379,9 @@ handle_noreturn_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_noinline_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_noinline_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) == FUNCTION_DECL)
DECL_UNINLINABLE (*node) = 1;
@@ -5380,12 +4398,10 @@ handle_noinline_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_always_inline_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_always_inline_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
{
if (TREE_CODE (*node) == FUNCTION_DECL)
{
@@ -5405,19 +4421,16 @@ handle_always_inline_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_used_attribute (pnode, name, args, flags, no_add_attrs)
- tree *pnode;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_used_attribute (tree *pnode, tree name, tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
tree node = *pnode;
if (TREE_CODE (node) == FUNCTION_DECL
|| (TREE_CODE (node) == VAR_DECL && TREE_STATIC (node)))
- TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (node))
- = TREE_USED (node) = 1;
+ {
+ TREE_USED (node) = 1;
+ }
else
{
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
@@ -5431,12 +4444,8 @@ handle_used_attribute (pnode, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_unused_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags;
- bool *no_add_attrs;
+handle_unused_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (DECL_P (*node))
{
@@ -5468,12 +4477,8 @@ handle_unused_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_const_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_const_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
tree type = TREE_TYPE (*node);
@@ -5499,12 +4504,9 @@ handle_const_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_transparent_union_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags;
- bool *no_add_attrs;
+handle_transparent_union_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED, int flags,
+ bool *no_add_attrs)
{
tree decl = NULL_TREE;
tree *type = NULL;
@@ -5546,12 +4548,10 @@ handle_transparent_union_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_constructor_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_constructor_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
{
tree decl = *node;
tree type = TREE_TYPE (decl);
@@ -5576,12 +4576,10 @@ handle_constructor_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_destructor_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_destructor_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
{
tree decl = *node;
tree type = TREE_TYPE (decl);
@@ -5606,12 +4604,8 @@ handle_destructor_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_mode_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_mode_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
tree type = *node;
@@ -5626,11 +4620,12 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs)
int len = strlen (p);
enum machine_mode mode = VOIDmode;
tree typefm;
+ tree ptr_type;
if (len > 4 && p[0] == '_' && p[1] == '_'
&& p[len - 1] == '_' && p[len - 2] == '_')
{
- char *newp = (char *) alloca (len - 1);
+ char *newp = alloca (len - 1);
strcpy (newp, &p[2]);
newp[len - 4] = '\0';
@@ -5655,18 +4650,33 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs)
else if (0 == (typefm = (*lang_hooks.types.type_for_mode)
(mode, TREE_UNSIGNED (type))))
error ("no data type for mode `%s'", p);
+ else if ((TREE_CODE (type) == POINTER_TYPE
+ || TREE_CODE (type) == REFERENCE_TYPE)
+ && !(*targetm.valid_pointer_mode) (mode))
+ error ("invalid pointer mode `%s'", p);
else
{
/* If this is a vector, make sure we either have hardware
support, or we can emulate it. */
- if ((GET_MODE_CLASS (mode) == MODE_VECTOR_INT
- || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
- && !vector_mode_valid_p (mode))
+ if (VECTOR_MODE_P (mode) && !vector_mode_valid_p (mode))
{
error ("unable to emulate '%s'", GET_MODE_NAME (mode));
return NULL_TREE;
}
+ if (TREE_CODE (type) == POINTER_TYPE)
+ {
+ ptr_type = build_pointer_type_for_mode (TREE_TYPE (type),
+ mode);
+ *node = ptr_type;
+ }
+ else if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ ptr_type = build_reference_type_for_mode (TREE_TYPE (type),
+ mode);
+ *node = ptr_type;
+ }
+ else
*node = typefm;
/* No need to layout the type here. The caller should do this. */
}
@@ -5679,12 +4689,8 @@ handle_mode_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_section_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name ATTRIBUTE_UNUSED;
- tree args;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_section_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
tree decl = *node;
@@ -5698,8 +4704,8 @@ handle_section_attribute (node, name, args, flags, no_add_attrs)
&& current_function_decl != NULL_TREE
&& ! TREE_STATIC (decl))
{
- error_with_decl (decl,
- "section attribute cannot be specified for local variables");
+ error ("%Jsection attribute cannot be specified for "
+ "local variables", decl);
*no_add_attrs = true;
}
@@ -5709,8 +4715,8 @@ handle_section_attribute (node, name, args, flags, no_add_attrs)
&& strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)),
TREE_STRING_POINTER (TREE_VALUE (args))) != 0)
{
- error_with_decl (*node,
- "section of `%s' conflicts with previous declaration");
+ error ("%Jsection of '%D' conflicts with previous declaration",
+ *node, *node);
*no_add_attrs = true;
}
else
@@ -5718,15 +4724,13 @@ handle_section_attribute (node, name, args, flags, no_add_attrs)
}
else
{
- error_with_decl (*node,
- "section attribute not allowed for `%s'");
+ error ("%Jsection attribute not allowed for '%D'", *node, *node);
*no_add_attrs = true;
}
}
else
{
- error_with_decl (*node,
- "section attributes are not supported for this target");
+ error ("%Jsection attributes are not supported for this target", *node);
*no_add_attrs = true;
}
@@ -5737,12 +4741,8 @@ handle_section_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_aligned_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name ATTRIBUTE_UNUSED;
- tree args;
- int flags;
- bool *no_add_attrs;
+handle_aligned_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args,
+ int flags, bool *no_add_attrs)
{
tree decl = NULL_TREE;
tree *type = NULL;
@@ -5804,8 +4804,7 @@ handle_aligned_attribute (node, name, args, flags, no_add_attrs)
else if (TREE_CODE (decl) != VAR_DECL
&& TREE_CODE (decl) != FIELD_DECL)
{
- error_with_decl (decl,
- "alignment may not be specified for `%s'");
+ error ("%Jalignment may not be specified for '%D'", decl, decl);
*no_add_attrs = true;
}
else
@@ -5821,12 +4820,10 @@ handle_aligned_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_weak_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name ATTRIBUTE_UNUSED;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs ATTRIBUTE_UNUSED;
+handle_weak_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs ATTRIBUTE_UNUSED)
{
declare_weak (*node);
@@ -5837,20 +4834,15 @@ handle_weak_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_alias_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_alias_attribute (tree *node, tree name, tree args,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
tree decl = *node;
if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
|| (TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl)))
{
- error_with_decl (decl,
- "`%s' defined both normally and as an alias");
+ error ("%J'%D' defined both normally and as an alias", decl, decl);
*no_add_attrs = true;
}
else if (decl_function_context (decl) == 0)
@@ -5886,42 +4878,38 @@ handle_alias_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_visibility_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_visibility_attribute (tree *node, tree name, tree args,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
{
tree decl = *node;
+ tree id = TREE_VALUE (args);
+
+ *no_add_attrs = true;
if (decl_function_context (decl) != 0 || ! TREE_PUBLIC (decl))
{
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
- *no_add_attrs = true;
+ return NULL_TREE;
}
- else
- {
- tree id;
- id = TREE_VALUE (args);
- if (TREE_CODE (id) != STRING_CST)
- {
- error ("visibility arg not a string");
- *no_add_attrs = true;
- return NULL_TREE;
- }
- if (strcmp (TREE_STRING_POINTER (id), "hidden")
- && strcmp (TREE_STRING_POINTER (id), "protected")
- && strcmp (TREE_STRING_POINTER (id), "internal")
- && strcmp (TREE_STRING_POINTER (id), "default"))
- {
- error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
- *no_add_attrs = true;
- return NULL_TREE;
- }
+ if (TREE_CODE (id) != STRING_CST)
+ {
+ error ("visibility arg not a string");
+ return NULL_TREE;
}
+ if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
+ DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+ else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
+ DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
+ else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
+ DECL_VISIBILITY (decl) = VISIBILITY_PROTECTED;
+ else
+ error ("visibility arg must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
+
return NULL_TREE;
}
@@ -5929,12 +4917,8 @@ handle_visibility_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_tls_model_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_tls_model_attribute (tree *node, tree name, tree args,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
tree decl = *node;
@@ -5972,27 +4956,21 @@ handle_tls_model_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_no_instrument_function_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_no_instrument_function_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
{
tree decl = *node;
if (TREE_CODE (decl) != FUNCTION_DECL)
{
- error_with_decl (decl,
- "`%s' attribute applies only to functions",
- IDENTIFIER_POINTER (name));
+ error ("%J'%E' attribute applies only to functions", decl, name);
*no_add_attrs = true;
}
else if (DECL_INITIAL (decl))
{
- error_with_decl (decl,
- "can't set `%s' attribute after definition",
- IDENTIFIER_POINTER (name));
+ error ("%Jcan't set '%E' attribute after definition", decl, name);
*no_add_attrs = true;
}
else
@@ -6005,12 +4983,8 @@ handle_no_instrument_function_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_malloc_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_malloc_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) == FUNCTION_DECL)
DECL_IS_MALLOC (*node) = 1;
@@ -6028,27 +5002,21 @@ handle_malloc_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_no_limit_stack_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_no_limit_stack_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
{
tree decl = *node;
if (TREE_CODE (decl) != FUNCTION_DECL)
{
- error_with_decl (decl,
- "`%s' attribute applies only to functions",
- IDENTIFIER_POINTER (name));
+ error ("%J'%E' attribute applies only to functions", decl, name);
*no_add_attrs = true;
}
else if (DECL_INITIAL (decl))
{
- error_with_decl (decl,
- "can't set `%s' attribute after definition",
- IDENTIFIER_POINTER (name));
+ error ("%Jcan't set '%E' attribute after definition", decl, name);
*no_add_attrs = true;
}
else
@@ -6061,12 +5029,8 @@ handle_no_limit_stack_attribute (node, name, args, flags, no_add_attrs)
struct attribute_spec.handler. */
static tree
-handle_pure_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_pure_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) == FUNCTION_DECL)
DECL_IS_PURE (*node) = 1;
@@ -6080,75 +5044,23 @@ handle_pure_attribute (node, name, args, flags, no_add_attrs)
return NULL_TREE;
}
-/* Handle a "cleanup" attribute; arguments as in
- struct attribute_spec.handler. */
-
-static tree
-handle_cleanup_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
-{
- tree decl = *node;
- tree cleanup_id, cleanup_decl;
-
- /* ??? Could perhaps support cleanups on TREE_STATIC, much like we do
- for global destructors in C++. This requires infrastructure that
- we don't have generically at the moment. It's also not a feature
- we'd be missing too much, since we do have attribute constructor. */
- if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl))
- {
- warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
- *no_add_attrs = true;
- return NULL_TREE;
- }
-
- /* Verify that the argument is a function in scope. */
- /* ??? We could support pointers to functions here as well, if
- that was considered desirable. */
- cleanup_id = TREE_VALUE (args);
- if (TREE_CODE (cleanup_id) != IDENTIFIER_NODE)
- {
- error ("cleanup arg not an identifier");
- *no_add_attrs = true;
- return NULL_TREE;
- }
- cleanup_decl = lookup_name (cleanup_id);
- if (!cleanup_decl || TREE_CODE (cleanup_decl) != FUNCTION_DECL)
- {
- error ("cleanup arg not a function");
- *no_add_attrs = true;
- return NULL_TREE;
- }
-
- /* That the function has proper type is checked with the
- eventual call to build_function_call. */
-
- return NULL_TREE;
-}
-
/* Handle a "deprecated" attribute; arguments as in
struct attribute_spec.handler. */
-
+
static tree
-handle_deprecated_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags;
- bool *no_add_attrs;
+handle_deprecated_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED, int flags,
+ bool *no_add_attrs)
{
tree type = NULL_TREE;
int warn = 0;
const char *what = NULL;
-
+
if (DECL_P (*node))
{
tree decl = *node;
type = TREE_TYPE (decl);
-
+
if (TREE_CODE (decl) == TYPE_DECL
|| TREE_CODE (decl) == PARM_DECL
|| TREE_CODE (decl) == VAR_DECL
@@ -6167,7 +5079,7 @@ handle_deprecated_attribute (node, name, args, flags, no_add_attrs)
}
else
warn = 1;
-
+
if (warn)
{
*no_add_attrs = true;
@@ -6183,7 +5095,7 @@ handle_deprecated_attribute (node, name, args, flags, no_add_attrs)
warning ("`%s' attribute ignored for `%s'",
IDENTIFIER_POINTER (name), what);
else
- warning ("`%s' attribute ignored",
+ warning ("`%s' attribute ignored",
IDENTIFIER_POINTER (name));
}
@@ -6201,12 +5113,9 @@ static GTY(()) tree vector_type_node_list = 0;
struct attribute_spec.handler. */
static tree
-handle_vector_size_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_vector_size_attribute (tree *node, tree name, tree args,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
{
unsigned HOST_WIDE_INT vecsize, nunits;
enum machine_mode mode, orig_mode, new_mode;
@@ -6234,6 +5143,7 @@ handle_vector_size_attribute (node, name, args, flags, no_add_attrs)
while (POINTER_TYPE_P (type)
|| TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE
|| TREE_CODE (type) == ARRAY_TYPE)
type = TREE_TYPE (type);
@@ -6352,8 +5262,7 @@ handle_vector_size_attribute (node, name, args, flags, no_add_attrs)
new type which we will point to. */
static tree
-vector_size_helper (type, bottom)
- tree type, bottom;
+vector_size_helper (tree type, tree bottom)
{
tree inner, outer;
@@ -6365,16 +5274,23 @@ vector_size_helper (type, bottom)
else if (TREE_CODE (type) == ARRAY_TYPE)
{
inner = vector_size_helper (TREE_TYPE (type), bottom);
- outer = build_array_type (inner, TYPE_VALUES (type));
+ outer = build_array_type (inner, TYPE_DOMAIN (type));
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
inner = vector_size_helper (TREE_TYPE (type), bottom);
- outer = build_function_type (inner, TYPE_VALUES (type));
+ outer = build_function_type (inner, TYPE_ARG_TYPES (type));
+ }
+ else if (TREE_CODE (type) == METHOD_TYPE)
+ {
+ inner = vector_size_helper (TREE_TYPE (type), bottom);
+ outer = build_method_type_directly (TYPE_METHOD_BASETYPE (type),
+ inner,
+ TYPE_ARG_TYPES (type));
}
else
return bottom;
-
+
TREE_READONLY (outer) = TREE_READONLY (type);
TREE_THIS_VOLATILE (outer) = TREE_THIS_VOLATILE (type);
@@ -6383,18 +5299,15 @@ vector_size_helper (type, bottom)
/* Handle the "nonnull" attribute. */
static tree
-handle_nonnull_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name ATTRIBUTE_UNUSED;
- tree args;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_nonnull_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
+ tree args, int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
{
tree type = *node;
unsigned HOST_WIDE_INT attr_arg_num;
/* If no arguments are specified, all pointer arguments should be
- non-null. Veryify a full prototype is given so that the arguments
+ non-null. Verify a full prototype is given so that the arguments
will have the correct types when we actually check them later. */
if (! args)
{
@@ -6457,9 +5370,7 @@ handle_nonnull_attribute (node, name, args, flags, no_add_attrs)
that are marked as requiring a non-null pointer argument. */
static void
-check_function_nonnull (attrs, params)
- tree attrs;
- tree params;
+check_function_nonnull (tree attrs, tree params)
{
tree a, args, param;
int param_num;
@@ -6478,11 +5389,11 @@ check_function_nonnull (attrs, params)
param_num++, param = TREE_CHAIN (param))
{
if (! param)
- break;
+ break;
if (! args || nonnull_check_p (args, param_num))
- check_function_arguments_recurse (check_nonnull_arg, NULL,
- TREE_VALUE (param),
- param_num);
+ check_function_arguments_recurse (check_nonnull_arg, NULL,
+ TREE_VALUE (param),
+ param_num);
}
}
}
@@ -6493,9 +5404,7 @@ check_function_nonnull (attrs, params)
checked. */
static bool
-nonnull_check_p (args, param_num)
- tree args;
- unsigned HOST_WIDE_INT param_num;
+nonnull_check_p (tree args, unsigned HOST_WIDE_INT param_num)
{
unsigned HOST_WIDE_INT arg_num;
@@ -6515,10 +5424,8 @@ nonnull_check_p (args, param_num)
via check_function_arguments_recurse. */
static void
-check_nonnull_arg (ctx, param, param_num)
- void *ctx ATTRIBUTE_UNUSED;
- tree param;
- unsigned HOST_WIDE_INT param_num;
+check_nonnull_arg (void *ctx ATTRIBUTE_UNUSED, tree param,
+ unsigned HOST_WIDE_INT param_num)
{
/* Just skip checking the argument if it's not a pointer. This can
happen if the "nonnull" attribute was given without an operand
@@ -6536,9 +5443,7 @@ check_nonnull_arg (ctx, param, param_num)
from the attribute argument list. */
static bool
-get_nonnull_operand (arg_num_expr, valp)
- tree arg_num_expr;
- unsigned HOST_WIDE_INT *valp;
+get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
{
/* Strip any conversions from the arg number and verify they
are constants. */
@@ -6559,12 +5464,8 @@ get_nonnull_operand (arg_num_expr, valp)
struct attribute_spec.handler. */
static tree
-handle_nothrow_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_nothrow_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) == FUNCTION_DECL)
TREE_NOTHROW (*node) = 1;
@@ -6577,12 +5478,72 @@ handle_nothrow_attribute (node, name, args, flags, no_add_attrs)
return NULL_TREE;
}
+
+/* Handle a "cleanup" attribute; arguments as in
+ struct attribute_spec.handler. */
+
+static tree
+handle_cleanup_attribute (tree *node, tree name, tree args,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+ tree decl = *node;
+ tree cleanup_id, cleanup_decl;
+
+ /* ??? Could perhaps support cleanups on TREE_STATIC, much like we do
+ for global destructors in C++. This requires infrastructure that
+ we don't have generically at the moment. It's also not a feature
+ we'd be missing too much, since we do have attribute constructor. */
+ if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl))
+ {
+ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
+ /* Verify that the argument is a function in scope. */
+ /* ??? We could support pointers to functions here as well, if
+ that was considered desirable. */
+ cleanup_id = TREE_VALUE (args);
+ if (TREE_CODE (cleanup_id) != IDENTIFIER_NODE)
+ {
+ error ("cleanup arg not an identifier");
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+ cleanup_decl = lookup_name (cleanup_id);
+ if (!cleanup_decl || TREE_CODE (cleanup_decl) != FUNCTION_DECL)
+ {
+ error ("cleanup arg not a function");
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
+ /* That the function has proper type is checked with the
+ eventual call to build_function_call. */
+
+ return NULL_TREE;
+}
+
+/* Handle a "warn_unused_result" attribute. No special handling. */
+
+static tree
+handle_warn_unused_result_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+ /* Ignore the attribute for functions not returning any value. */
+ if (VOID_TYPE_P (TREE_TYPE (*node)))
+ {
+ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
/* Check for valid arguments being passed to a function. */
void
-check_function_arguments (attrs, params)
- tree attrs;
- tree params;
+check_function_arguments (tree attrs, tree params)
{
/* Check for null being passed in a pointer argument that must be
non-null. We also need to do this if format checking is enabled. */
@@ -6600,11 +5561,10 @@ check_function_arguments (attrs, params)
be checked. PARAM_NUM is the number of the argument. CALLBACK is invoked
once the argument is resolved. CTX is context for the callback. */
void
-check_function_arguments_recurse (callback, ctx, param, param_num)
- void (*callback) PARAMS ((void *, tree, unsigned HOST_WIDE_INT));
- void *ctx;
- tree param;
- unsigned HOST_WIDE_INT param_num;
+check_function_arguments_recurse (void (*callback)
+ (void *, tree, unsigned HOST_WIDE_INT),
+ void *ctx, tree param,
+ unsigned HOST_WIDE_INT param_num)
{
if (TREE_CODE (param) == NOP_EXPR)
{
@@ -6681,4 +5641,260 @@ check_function_arguments_recurse (callback, ctx, param, param_num)
(*callback) (ctx, param, param_num);
}
+/* Function to help qsort sort FIELD_DECLs by name order. */
+
+int
+field_decl_cmp (const void *x_p, const void *y_p)
+{
+ const tree *const x = x_p;
+ const tree *const y = y_p;
+ if (DECL_NAME (*x) == DECL_NAME (*y))
+ /* A nontype is "greater" than a type. */
+ return (TREE_CODE (*y) == TYPE_DECL) - (TREE_CODE (*x) == TYPE_DECL);
+ if (DECL_NAME (*x) == NULL_TREE)
+ return -1;
+ if (DECL_NAME (*y) == NULL_TREE)
+ return 1;
+ if (DECL_NAME (*x) < DECL_NAME (*y))
+ return -1;
+ return 1;
+}
+
+static struct {
+ gt_pointer_operator new_value;
+ void *cookie;
+} resort_data;
+
+/* This routine compares two fields like field_decl_cmp but using the
+pointer operator in resort_data. */
+
+static int
+resort_field_decl_cmp (const void *x_p, const void *y_p)
+{
+ const tree *const x = x_p;
+ const tree *const y = y_p;
+
+ if (DECL_NAME (*x) == DECL_NAME (*y))
+ /* A nontype is "greater" than a type. */
+ return (TREE_CODE (*y) == TYPE_DECL) - (TREE_CODE (*x) == TYPE_DECL);
+ if (DECL_NAME (*x) == NULL_TREE)
+ return -1;
+ if (DECL_NAME (*y) == NULL_TREE)
+ return 1;
+ {
+ tree d1 = DECL_NAME (*x);
+ tree d2 = DECL_NAME (*y);
+ resort_data.new_value (&d1, resort_data.cookie);
+ resort_data.new_value (&d2, resort_data.cookie);
+ if (d1 < d2)
+ return -1;
+ }
+ return 1;
+}
+
+/* Resort DECL_SORTED_FIELDS because pointers have been reordered. */
+
+void
+resort_sorted_fields (void *obj,
+ void *orig_obj ATTRIBUTE_UNUSED ,
+ gt_pointer_operator new_value,
+ void *cookie)
+{
+ struct sorted_fields_type *sf = obj;
+ resort_data.new_value = new_value;
+ resort_data.cookie = cookie;
+ qsort (&sf->elts[0], sf->len, sizeof (tree),
+ resort_field_decl_cmp);
+}
+
+/* Used by estimate_num_insns. Estimate number of instructions seen
+ by given statement. */
+static tree
+c_estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
+{
+ int *count = data;
+ tree x = *tp;
+
+ if (TYPE_P (x) || DECL_P (x))
+ {
+ *walk_subtrees = 0;
+ return NULL;
+ }
+ /* Assume that constants and references counts nothing. These should
+ be majorized by amount of operations among them we count later
+ and are common target of CSE and similar optimizations. */
+ if (TREE_CODE_CLASS (TREE_CODE (x)) == 'c'
+ || TREE_CODE_CLASS (TREE_CODE (x)) == 'r')
+ return NULL;
+ switch (TREE_CODE (x))
+ {
+ /* Recognize assignments of large structures and constructors of
+ big arrays. */
+ case MODIFY_EXPR:
+ case CONSTRUCTOR:
+ {
+ HOST_WIDE_INT size;
+
+ size = int_size_in_bytes (TREE_TYPE (x));
+
+ if (size < 0 || size > MOVE_MAX_PIECES * MOVE_RATIO)
+ *count += 10;
+ else
+ *count += ((size + MOVE_MAX_PIECES - 1) / MOVE_MAX_PIECES);
+ }
+ break;
+ case CALL_EXPR:
+ {
+ tree decl = get_callee_fndecl (x);
+
+ if (decl && DECL_BUILT_IN (decl))
+ switch (DECL_FUNCTION_CODE (decl))
+ {
+ case BUILT_IN_CONSTANT_P:
+ *walk_subtrees = 0;
+ return NULL_TREE;
+ case BUILT_IN_EXPECT:
+ return NULL_TREE;
+ default:
+ break;
+ }
+ *count += 10;
+ break;
+ }
+ /* Few special cases of expensive operations. This is usefull
+ to avoid inlining on functions having too many of these. */
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case ROUND_MOD_EXPR:
+ case RDIV_EXPR:
+ *count += 10;
+ break;
+ /* Various containers that will produce no code themselves. */
+ case INIT_EXPR:
+ case TARGET_EXPR:
+ case BIND_EXPR:
+ case BLOCK:
+ case TREE_LIST:
+ case TREE_VEC:
+ case IDENTIFIER_NODE:
+ case PLACEHOLDER_EXPR:
+ case WITH_CLEANUP_EXPR:
+ case CLEANUP_POINT_EXPR:
+ case NOP_EXPR:
+ case VIEW_CONVERT_EXPR:
+ case SAVE_EXPR:
+ case UNSAVE_EXPR:
+ case COMPLEX_EXPR:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case TRY_CATCH_EXPR:
+ case TRY_FINALLY_EXPR:
+ case LABEL_EXPR:
+ case EXIT_EXPR:
+ case LABELED_BLOCK_EXPR:
+ case EXIT_BLOCK_EXPR:
+ case EXPR_WITH_FILE_LOCATION:
+
+ case EXPR_STMT:
+ case COMPOUND_STMT:
+ case RETURN_STMT:
+ case LABEL_STMT:
+ case SCOPE_STMT:
+ case FILE_STMT:
+ case CASE_LABEL:
+ case STMT_EXPR:
+ case CLEANUP_STMT:
+
+ case SIZEOF_EXPR:
+ case ARROW_EXPR:
+ case ALIGNOF_EXPR:
+ break;
+ case DECL_STMT:
+ /* Do not account static initializers. */
+ if (TREE_STATIC (TREE_OPERAND (x, 0)))
+ *walk_subtrees = 0;
+ break;
+ default:
+ (*count)++;
+ }
+ return NULL;
+}
+
+/* Estimate number of instructions that will be created by expanding the body. */
+int
+c_estimate_num_insns (tree decl)
+{
+ int num = 0;
+ walk_tree_without_duplicates (&DECL_SAVED_TREE (decl), c_estimate_num_insns_1, &num);
+ return num;
+}
+
+/* Used by c_decl_uninit to find where expressions like x = x + 1; */
+
+static tree
+c_decl_uninit_1 (tree *t, int *walk_sub_trees, void *x)
+{
+ /* If x = EXP(&x)EXP, then do not warn about the use of x. */
+ if (TREE_CODE (*t) == ADDR_EXPR && TREE_OPERAND (*t, 0) == x)
+ {
+ *walk_sub_trees = 0;
+ return NULL_TREE;
+ }
+ if (*t == x)
+ return *t;
+ return NULL_TREE;
+}
+
+/* Find out if a variable is uninitialized based on DECL_INITIAL. */
+
+bool
+c_decl_uninit (tree t)
+{
+ /* int x = x; is GCC extension to turn off this warning, only if warn_init_self is zero. */
+ if (DECL_INITIAL (t) == t)
+ return warn_init_self ? true : false;
+
+ /* Walk the trees looking for the variable itself. */
+ if (walk_tree_without_duplicates (&DECL_INITIAL (t), c_decl_uninit_1, t))
+ return true;
+ return false;
+}
+
+/* Issue the error given by MSGID, indicating that it occurred before
+ TOKEN, which had the associated VALUE. */
+
+void
+c_parse_error (const char *msgid, enum cpp_ttype token, tree value)
+{
+ const char *string = _(msgid);
+
+ if (token == CPP_EOF)
+ error ("%s at end of input", string);
+ else if (token == CPP_CHAR || token == CPP_WCHAR)
+ {
+ unsigned int val = TREE_INT_CST_LOW (value);
+ const char *const ell = (token == CPP_CHAR) ? "" : "L";
+ if (val <= UCHAR_MAX && ISGRAPH (val))
+ error ("%s before %s'%c'", string, ell, val);
+ else
+ error ("%s before %s'\\x%x'", string, ell, val);
+ }
+ else if (token == CPP_STRING
+ || token == CPP_WSTRING)
+ error ("%s before string constant", string);
+ else if (token == CPP_NUMBER)
+ error ("%s before numeric constant", string);
+ else if (token == CPP_NAME)
+ error ("%s before \"%s\"", string, IDENTIFIER_POINTER (value));
+ else if (token < N_TTYPES)
+ error ("%s before '%s' token", string, cpp_type2name (token));
+ else
+ error ("%s", string);
+}
+
#include "gt-c-common.h"
diff --git a/contrib/gcc/c-common.def b/contrib/gcc/c-common.def
index 802238a65a2c..dfdec8c4df07 100644
--- a/contrib/gcc/c-common.def
+++ b/contrib/gcc/c-common.def
@@ -25,9 +25,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Tree nodes relevant to both C and C++. These were originally in
cp-tree.def in the cp subdir. */
-/* A node to remember a source position. */
-DEFTREECODE (SRCLOC, "srcloc", 'x', 2)
-
DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", '1', 1)
DEFTREECODE (ARROW_EXPR, "arrow_expr", 'e', 1)
DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", '1', 1)
diff --git a/contrib/gcc/c-common.h b/contrib/gcc/c-common.h
index 1f59ebd7d829..7849730f161f 100644
--- a/contrib/gcc/c-common.h
+++ b/contrib/gcc/c-common.h
@@ -1,6 +1,6 @@
/* Definitions for c-common.c.
Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -24,6 +24,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "splay-tree.h"
#include "cpplib.h"
+#include "ggc.h"
/* Usage of TREE_LANG_FLAG_?:
0: COMPOUND_STMT_NO_SCOPE (in COMPOUND_STMT).
@@ -39,6 +40,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2: STMT_LINENO_FOR_FN_P (in _STMT)
3: SCOPE_NO_CLEANUPS_P (in SCOPE_STMT)
COMPOUND_STMT_BODY_BLOCK (in COMPOUND_STMT)
+ STMT_EXPR_WARN_UNUSED_RESULT (in STMT_EXPR)
4: SCOPE_PARTIAL_P (in SCOPE_STMT)
*/
@@ -58,7 +60,7 @@ enum rid
RID_VOLATILE, RID_SIGNED, RID_AUTO, RID_RESTRICT,
/* C extensions */
- RID_BOUNDED, RID_UNBOUNDED, RID_COMPLEX, RID_THREAD,
+ RID_COMPLEX, RID_THREAD,
/* C++ */
RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE,
@@ -86,9 +88,10 @@ enum rid
RID_PUBLIC, RID_PRIVATE, RID_PROTECTED,
RID_TEMPLATE, RID_NULL, RID_CATCH,
RID_DELETE, RID_FALSE, RID_NAMESPACE,
- RID_NEW, RID_OPERATOR, RID_THIS,
- RID_THROW, RID_TRUE, RID_TRY,
- RID_TYPENAME, RID_TYPEID, RID_USING,
+ RID_NEW, RID_OFFSETOF, RID_OPERATOR,
+ RID_THIS, RID_THROW, RID_TRUE,
+ RID_TRY, RID_TYPENAME, RID_TYPEID,
+ RID_USING,
/* casts */
RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST,
@@ -97,7 +100,10 @@ enum rid
RID_ID, RID_AT_ENCODE, RID_AT_END,
RID_AT_CLASS, RID_AT_ALIAS, RID_AT_DEFS,
RID_AT_PRIVATE, RID_AT_PROTECTED, RID_AT_PUBLIC,
- RID_AT_PROTOCOL, RID_AT_SELECTOR, RID_AT_INTERFACE,
+ RID_AT_PROTOCOL, RID_AT_SELECTOR,
+ RID_AT_THROW, RID_AT_TRY, RID_AT_CATCH,
+ RID_AT_FINALLY, RID_AT_SYNCHRONIZED,
+ RID_AT_INTERFACE,
RID_AT_IMPLEMENTATION,
RID_MAX,
@@ -121,7 +127,7 @@ enum rid
/* The elements of `ridpointers' are identifier nodes for the reserved
type names and storage classes. It is indexed by a RID_... value. */
-extern tree *ridpointers;
+extern GTY ((length ("(int)RID_MAX"))) tree *ridpointers;
/* Standard named or nameless data types of the C compiler. */
@@ -145,13 +151,10 @@ enum c_tree_index
CTI_CONST_STRING_TYPE,
/* Type for boolean expressions (bool in C++, int in C). */
- CTI_BOOLEAN_TYPE,
- CTI_BOOLEAN_TRUE,
- CTI_BOOLEAN_FALSE,
- /* C99's _Bool type. */
- CTI_C_BOOL_TYPE,
- CTI_C_BOOL_TRUE,
- CTI_C_BOOL_FALSE,
+ CTI_TRUTHVALUE_TYPE,
+ CTI_TRUTHVALUE_TRUE,
+ CTI_TRUTHVALUE_FALSE,
+
CTI_DEFAULT_FUNCTION_TYPE,
CTI_G77_INTEGER_TYPE,
@@ -177,7 +180,7 @@ enum c_tree_index
struct c_common_identifier GTY(())
{
struct tree_common common;
- struct cpp_hashnode GTY ((skip (""))) node;
+ struct cpp_hashnode node;
};
#define wchar_type_node c_global_trees[CTI_WCHAR_TYPE]
@@ -191,13 +194,9 @@ struct c_common_identifier GTY(())
#define widest_integer_literal_type_node c_global_trees[CTI_WIDEST_INT_LIT_TYPE]
#define widest_unsigned_literal_type_node c_global_trees[CTI_WIDEST_UINT_LIT_TYPE]
-#define boolean_type_node c_global_trees[CTI_BOOLEAN_TYPE]
-#define boolean_true_node c_global_trees[CTI_BOOLEAN_TRUE]
-#define boolean_false_node c_global_trees[CTI_BOOLEAN_FALSE]
-
-#define c_bool_type_node c_global_trees[CTI_C_BOOL_TYPE]
-#define c_bool_true_node c_global_trees[CTI_C_BOOL_TRUE]
-#define c_bool_false_node c_global_trees[CTI_C_BOOL_FALSE]
+#define truthvalue_type_node c_global_trees[CTI_TRUTHVALUE_TYPE]
+#define truthvalue_true_node c_global_trees[CTI_TRUTHVALUE_TRUE]
+#define truthvalue_false_node c_global_trees[CTI_TRUTHVALUE_FALSE]
#define char_array_type_node c_global_trees[CTI_CHAR_ARRAY_TYPE]
#define wchar_array_type_node c_global_trees[CTI_WCHAR_ARRAY_TYPE]
@@ -223,6 +222,14 @@ struct c_common_identifier GTY(())
extern GTY(()) tree c_global_trees[CTI_MAX];
+/* In a RECORD_TYPE, a sorted array of the fields of the type, not a
+ tree for size reasons. */
+struct sorted_fields_type GTY(())
+{
+ int len;
+ tree GTY((length ("%h.len"))) elts[1];
+};
+
/* Mark which labels are explicitly declared.
These may be shadowed, and may be referenced from nested functions. */
#define C_DECLARED_LABEL_FLAG(label) TREE_LANG_FLAG_1 (label)
@@ -233,11 +240,20 @@ extern GTY(()) tree c_global_trees[CTI_MAX];
typedef enum c_language_kind
{
- clk_c = 0, /* A dialect of C: K&R C, ANSI/ISO C89, C2000, etc. */
- clk_cplusplus /* ANSI/ISO C++ */
+ clk_c = 0, /* C90, C94 or C99 */
+ clk_objc = 1, /* clk_c with ObjC features. */
+ clk_cxx = 2, /* ANSI/ISO C++ */
+ clk_objcxx = 3 /* clk_cxx with ObjC features. */
}
c_language_kind;
+/* To test for a specific language use c_language, defined by each
+ front end. For "ObjC features" or "not C++" use the macros. */
+extern c_language_kind c_language;
+
+#define c_dialect_cxx() (c_language & clk_cxx)
+#define c_dialect_objc() (c_language & clk_objc)
+
/* Information about a statement tree. */
struct stmt_tree_s GTY(()) {
@@ -305,75 +321,90 @@ struct c_language_function GTY(()) {
/* Language-specific hooks. */
-extern int (*lang_statement_code_p) PARAMS ((enum tree_code));
-extern void (*lang_expand_stmt) PARAMS ((tree));
-extern void (*lang_expand_decl_stmt) PARAMS ((tree));
-extern void (*lang_expand_function_end) PARAMS ((void));
-extern tree gettags PARAMS ((void));
+extern void (*lang_expand_stmt) (tree);
+extern void (*lang_expand_decl_stmt) (tree);
+extern void (*lang_expand_function_end) (void);
/* Callback that determines if it's ok for a function to have no
noreturn attribute. */
-extern int (*lang_missing_noreturn_ok_p) PARAMS ((tree));
-
-extern int yyparse PARAMS ((void));
-extern void free_parser_stacks PARAMS ((void));
-
-extern stmt_tree current_stmt_tree PARAMS ((void));
-extern tree *current_scope_stmt_stack PARAMS ((void));
-extern void begin_stmt_tree PARAMS ((tree *));
-extern tree add_stmt PARAMS ((tree));
-extern void add_decl_stmt PARAMS ((tree));
-extern tree add_scope_stmt PARAMS ((int, int));
-extern void finish_stmt_tree PARAMS ((tree *));
-
-extern int statement_code_p PARAMS ((enum tree_code));
-extern tree walk_stmt_tree PARAMS ((tree *,
- walk_tree_fn,
- void *));
-extern void prep_stmt PARAMS ((tree));
-extern void expand_stmt PARAMS ((tree));
-extern void shadow_warning PARAMS ((const char *,
- tree, tree));
-extern tree c_begin_if_stmt PARAMS ((void));
-extern tree c_begin_while_stmt PARAMS ((void));
-extern void c_finish_while_stmt_cond PARAMS ((tree, tree));
-
-
-/* Extra information associated with a DECL. Other C dialects extend
- this structure in various ways. The C front-end only uses this
- structure for FUNCTION_DECLs; all other DECLs have a NULL
- DECL_LANG_SPECIFIC field. */
-
-struct c_lang_decl GTY(()) {
- unsigned declared_inline : 1;
-};
+extern int (*lang_missing_noreturn_ok_p) (tree);
+
+extern int yyparse (void);
+extern stmt_tree current_stmt_tree (void);
+extern tree *current_scope_stmt_stack (void);
+extern void begin_stmt_tree (tree *);
+extern tree add_stmt (tree);
+extern void add_decl_stmt (tree);
+extern tree add_scope_stmt (int, int);
+extern void finish_stmt_tree (tree *);
+
+extern tree walk_stmt_tree (tree *, walk_tree_fn, void *);
+extern void prep_stmt (tree);
+extern void expand_stmt (tree);
+extern tree c_begin_if_stmt (void);
+extern tree c_begin_while_stmt (void);
+extern void c_finish_while_stmt_cond (tree, tree);
+
+extern int field_decl_cmp (const void *, const void *);
+extern void resort_sorted_fields (void *, void *, gt_pointer_operator,
+ void *);
+
+/* Switches common to the C front ends. */
-/* In a FUNCTION_DECL for which DECL_BUILT_IN does not hold, this is
- the approximate number of statements in this function. There is
- no need for this number to be exact; it is only used in various
- heuristics regarding optimization. */
-#define DECL_NUM_STMTS(NODE) \
- (FUNCTION_DECL_CHECK (NODE)->decl.u1.i)
+/* Nonzero if prepreprocessing only. */
-/* The variant of the C language being processed. Each C language
- front-end defines this variable. */
+extern int flag_preprocess_only;
-extern c_language_kind c_language;
+/* Zero means that faster, ...NonNil variants of objc_msgSend...
+ calls will be used in ObjC; passing nil receivers to such calls
+ will most likely result in crashes. */
+extern int flag_nil_receivers;
-/* Switches common to the C front ends. */
+/* Nonzero means that we will allow new ObjC exception syntax (@throw,
+ @try, etc.) in source code. */
+extern int flag_objc_exceptions;
-/* Nonzero if prepreprocessing only. */
-extern int flag_preprocess_only;
+/* Nonzero means that code generation will be altered to support
+ "zero-link" execution. This currently affects ObjC only, but may
+ affect other languages in the future. */
+extern int flag_zero_link;
+
+/* Nonzero means emit an '__OBJC, __image_info' for the current translation
+ unit. It will inform the ObjC runtime that class definition(s) herein
+ contained are to replace one(s) previously loaded. */
+extern int flag_replace_objc_classes;
+
+/* Nonzero means don't output line number information. */
+
+extern char flag_no_line_commands;
+
+/* Nonzero causes -E output not to be done, but directives such as
+ #define that have side effects are still obeyed. */
+
+extern char flag_no_output;
+
+/* Nonzero means dump macros in some fashion; contains the 'D', 'M' or
+ 'N' of the command line switch. */
+
+extern char flag_dump_macros;
+
+/* Nonzero means pass #include lines through to the output. */
+
+extern char flag_dump_includes;
+
+/* The file name to which we should write a precompiled header, or
+ NULL if no header will be written in this compile. */
+
+extern const char *pch_file;
/* Nonzero if an ISO standard was selected. It rejects macros in the
user's namespace. */
-extern int flag_iso;
-/* Nonzero whenever Objective-C functionality is being used. */
-extern int flag_objc;
+extern int flag_iso;
/* Nonzero if -undef was given. It suppresses target built-in macros
and assertions. */
+
extern int flag_undef;
/* Nonzero means don't recognize the non-ANSI builtin functions. */
@@ -405,10 +436,6 @@ extern int flag_no_asm;
extern int flag_const_strings;
-/* Nonzero means `$' can be in an identifier. */
-
-extern int dollars_in_ident;
-
/* Nonzero means to treat bitfields as signed unless they say `unsigned'. */
extern int flag_signed_bitfields;
@@ -523,15 +550,10 @@ extern int flag_isoc94;
extern int flag_isoc99;
-/* Nonzero means that we have builtin functions, and main is an int */
+/* Nonzero means that we have builtin functions, and main is an int. */
extern int flag_hosted;
-/* Nonzero means add default format_arg attributes for functions not
- in ISO C. */
-
-extern int flag_noniso_default_format_attributes;
-
/* Nonzero means warn when casting a function call to a type that does
not match the return type (e.g. (float)sqrt() or (anything*)malloc()
when there is no previous declaration of sqrt or malloc. */
@@ -542,6 +564,10 @@ extern int warn_bad_function_cast;
extern int warn_traditional;
+/* Nonzero means warn for a declaration found after a statement. */
+
+extern int warn_declaration_after_statement;
+
/* Nonzero means warn for non-prototype function decls
or non-prototyped defs without previous prototype. */
@@ -568,6 +594,12 @@ extern int warn_main;
extern int warn_sequence_point;
+/* Nonzero means warn about uninitialized variable when it is initialized with itself.
+ For example: int i = i;, GCC will not warn about this when warn_init_self is nonzero. */
+
+extern int warn_init_self;
+
+
/* Nonzero means to warn about compile-time division by zero. */
extern int warn_div_by_zero;
@@ -580,6 +612,10 @@ extern int warn_implicit_int;
extern int warn_nonnull;
+/* Warn about old-style parameter declaration. */
+
+extern int warn_old_style_definition;
+
/* ObjC language option variables. */
@@ -635,17 +671,6 @@ extern int flag_no_gnu_keywords;
extern int flag_implement_inlines;
-/* Nonzero means do emit exported implementations of templates, instead of
- multiple static copies in each file that needs a definition. */
-
-extern int flag_external_templates;
-
-/* Nonzero means that the decision to emit or not emit the implementation of a
- template depends on where the template is instantiated, rather than where
- it is defined. */
-
-extern int flag_alt_external_templates;
-
/* Nonzero means that implicit instantiations will be emitted if needed. */
extern int flag_implicit_templates;
@@ -711,15 +736,18 @@ extern int flag_new_for_scope;
extern int flag_weak;
+/* 0 means we want the preprocessor to not emit line directives for
+ the current working directory. 1 means we want it to do it. -1
+ means we should decide depending on whether debugging information
+ is being emitted or not. */
+
+extern int flag_working_directory;
+
/* Nonzero to use __cxa_atexit, rather than atexit, to register
destructors for local statics and global objects. */
extern int flag_use_cxa_atexit;
-/* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc. */
-
-extern int flag_vtable_gc;
-
/* Nonzero means make the default pedwarns warnings instead of errors.
The value of this flag is ignored if -pedantic is specified. */
@@ -732,26 +760,15 @@ extern int flag_permissive;
extern int flag_enforce_eh_specs;
-/* The version of the C++ ABI in use. The following values are
- allowed:
-
- 0: The version of the ABI believed most conformant with the
- C++ ABI specification. This ABI may change as bugs are
- discovered and fixed. Therefore, 0 will not necessarily
- indicate the same ABI in different versions of G++.
-
- 1: The version of the ABI first used in G++ 3.2.
-
- Additional positive integers will be assigned as new versions of
- the ABI become the default version of the ABI. */
-
-extern int flag_abi_version;
-
/* Nonzero means warn about things that will change when compiling
with an ABI-compliant compiler. */
extern int warn_abi;
+/* Nonzero means warn about invalid uses of offsetof. */
+
+extern int warn_invalid_offsetof;
+
/* Nonzero means warn about implicit declarations. */
extern int warn_implicit;
@@ -847,66 +864,60 @@ 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) PARAMS ((tree, int));
-
-extern tree identifier_global_value PARAMS ((tree));
-extern void record_builtin_type PARAMS ((enum rid,
- const char *, tree));
-extern tree build_void_list_node PARAMS ((void));
-extern void start_fname_decls PARAMS ((void));
-extern void finish_fname_decls PARAMS ((void));
-extern const char *fname_as_string PARAMS ((int));
-extern tree fname_decl PARAMS ((unsigned, tree));
-extern const char *fname_string PARAMS ((unsigned));
-
-extern void check_function_arguments PARAMS ((tree, tree));
-extern void check_function_arguments_recurse PARAMS ((void (*) (void *,
- tree,
- unsigned HOST_WIDE_INT),
- void *, tree,
- unsigned HOST_WIDE_INT));
-extern void check_function_format PARAMS ((int *, tree, tree));
-extern void set_Wformat PARAMS ((int));
-extern tree handle_format_attribute PARAMS ((tree *, tree, tree,
- int, bool *));
-extern tree handle_format_arg_attribute PARAMS ((tree *, tree, tree,
- int, bool *));
-extern void c_common_insert_default_attributes PARAMS ((tree));
-extern int c_common_decode_option PARAMS ((int, char **));
-extern tree c_common_type_for_mode PARAMS ((enum machine_mode,
- int));
-extern tree c_common_type_for_size PARAMS ((unsigned int, int));
-extern tree c_common_unsigned_type PARAMS ((tree));
-extern tree c_common_signed_type PARAMS ((tree));
-extern tree c_common_signed_or_unsigned_type PARAMS ((int, tree));
-extern tree c_common_truthvalue_conversion PARAMS ((tree));
-extern void c_apply_type_quals_to_decl PARAMS ((int, tree));
-extern tree c_sizeof_or_alignof_type PARAMS ((tree, enum tree_code, int));
-extern tree c_alignof_expr PARAMS ((tree));
+extern tree (*make_fname_decl) (tree, int);
+
+extern tree identifier_global_value (tree);
+extern void record_builtin_type (enum rid, const char *, tree);
+extern tree build_void_list_node (void);
+extern void start_fname_decls (void);
+extern void finish_fname_decls (void);
+extern const char *fname_as_string (int);
+extern tree fname_decl (unsigned, tree);
+
+extern void check_function_arguments (tree, tree);
+extern void check_function_arguments_recurse (void (*)
+ (void *, tree,
+ unsigned HOST_WIDE_INT),
+ void *, tree,
+ unsigned HOST_WIDE_INT);
+extern void check_function_format (int *, tree, tree);
+extern void set_Wformat (int);
+extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
+extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *);
+extern int c_common_handle_option (size_t code, const char *arg, int value);
+extern bool c_common_missing_argument (const char *opt, size_t code);
+extern tree c_common_type_for_mode (enum machine_mode, int);
+extern tree c_common_type_for_size (unsigned int, int);
+extern tree c_common_unsigned_type (tree);
+extern tree c_common_signed_type (tree);
+extern tree c_common_signed_or_unsigned_type (int, tree);
+extern tree c_common_truthvalue_conversion (tree);
+extern void c_apply_type_quals_to_decl (int, tree);
+extern tree c_sizeof_or_alignof_type (tree, enum tree_code, int);
+extern tree c_alignof_expr (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 PARAMS ((enum tree_code));
+extern void binary_op_error (enum tree_code);
#define my_friendly_assert(EXP, N) (void) \
(((EXP) == 0) ? (fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0) : 0)
-extern tree c_expand_expr_stmt PARAMS ((tree));
-extern void c_expand_start_cond PARAMS ((tree, int, tree));
-extern void c_finish_then PARAMS ((void));
-extern void c_expand_start_else PARAMS ((void));
-extern void c_finish_else PARAMS ((void));
-extern void c_expand_end_cond PARAMS ((void));
+extern tree c_expand_expr_stmt (tree);
+extern void c_expand_start_cond (tree, int, tree);
+extern void c_finish_then (void);
+extern void c_expand_start_else (void);
+extern void c_finish_else (void);
+extern void c_expand_end_cond (void);
/* Validate the expression after `case' and apply default promotions. */
-extern tree check_case_value PARAMS ((tree));
-extern tree fix_string_type PARAMS ((tree));
+extern tree check_case_value (tree);
+extern tree fix_string_type (tree);
struct varray_head_tag;
-extern tree combine_strings PARAMS ((struct varray_head_tag *));
-extern void constant_expression_warning PARAMS ((tree));
-extern tree convert_and_check PARAMS ((tree, tree));
-extern void overflow_warning PARAMS ((tree));
-extern void unsigned_conversion_warning PARAMS ((tree, tree));
+extern void constant_expression_warning (tree);
+extern tree convert_and_check (tree, tree);
+extern void overflow_warning (tree);
+extern void unsigned_conversion_warning (tree, tree);
/* Read the rest of the current #-directive line. */
-extern char *get_directive_line PARAMS ((void));
+extern char *get_directive_line (void);
#define GET_DIRECTIVE_LINE() get_directive_line ()
#define c_sizeof(T) c_sizeof_or_alignof_type (T, SIZEOF_EXPR, 1)
#define c_alignof(T) c_sizeof_or_alignof_type (T, ALIGNOF_EXPR, 1)
@@ -914,31 +925,41 @@ extern char *get_directive_line PARAMS ((void));
/* Subroutine of build_binary_op, used for comparison operations.
See if the operands have both been converted from subword integer types
and, if so, perhaps change them both back to their original type. */
-extern tree shorten_compare PARAMS ((tree *, tree *, tree *, enum tree_code *));
+extern tree shorten_compare (tree *, tree *, tree *, enum tree_code *);
-extern tree pointer_int_sum PARAMS ((enum tree_code, tree, tree));
-extern unsigned int min_precision PARAMS ((tree, int));
+extern tree pointer_int_sum (enum tree_code, tree, tree);
+extern unsigned int min_precision (tree, int);
/* Add qualifiers to a type, in the fashion for C. */
-extern tree c_build_qualified_type PARAMS ((tree, int));
+extern tree c_build_qualified_type (tree, int);
/* Build tree nodes and builtin functions common to both C and C++ language
frontends. */
-extern void c_common_nodes_and_builtins PARAMS ((void));
-
-extern void disable_builtin_function PARAMS ((const char *));
-
-extern tree build_va_arg PARAMS ((tree, tree));
-
-extern void c_common_init_options PARAMS ((enum c_language_kind));
-extern bool c_common_post_options PARAMS ((void));
-extern const char *c_common_init PARAMS ((const char *));
-extern void c_common_finish PARAMS ((void));
-extern void c_common_parse_file PARAMS ((int));
-extern HOST_WIDE_INT c_common_get_alias_set PARAMS ((tree));
-extern bool c_promoting_integer_type_p PARAMS ((tree));
-extern int self_promoting_args_p PARAMS ((tree));
-extern tree strip_array_types PARAMS ((tree));
+extern void c_common_nodes_and_builtins (void);
+
+extern void disable_builtin_function (const char *);
+
+extern tree build_va_arg (tree, tree);
+
+extern unsigned int c_common_init_options (unsigned int, const char **);
+extern bool c_common_post_options (const char **);
+extern bool c_common_init (void);
+extern void c_common_finish (void);
+extern void c_common_parse_file (int);
+extern HOST_WIDE_INT c_common_get_alias_set (tree);
+extern void c_register_builtin_type (tree, const char*);
+extern bool c_promoting_integer_type_p (tree);
+extern int self_promoting_args_p (tree);
+extern tree strip_array_types (tree);
+extern tree strip_pointer_operator (tree);
+
+/* This function resets the parsers' state in preparation for parsing
+ a new file. */
+extern void c_reset_state (void);
+/* This is the basic parsing function. */
+extern void c_parse_file (void);
+/* This is misnamed, it actually performs end-of-compilation processing. */
+extern void finish_file (void);
/* These macros provide convenient access to the various _STMT nodes. */
@@ -998,7 +1019,7 @@ extern tree strip_array_types PARAMS ((tree));
/* GOTO_STMT accessor. This gives access to the label associated with
a goto statement. */
#define GOTO_DESTINATION(NODE) TREE_OPERAND (GOTO_STMT_CHECK (NODE), 0)
-/* True for goto created artifically by the compiler. */
+/* True for goto created artificially by the compiler. */
#define GOTO_FAKE_P(NODE) (TREE_LANG_FLAG_0 (GOTO_STMT_CHECK (NODE)))
/* COMPOUND_STMT accessor. This gives access to the TREE_LIST of
@@ -1028,6 +1049,11 @@ extern tree strip_array_types PARAMS ((tree));
#define STMT_EXPR_NO_SCOPE(NODE) \
TREE_LANG_FLAG_0 (STMT_EXPR_CHECK (NODE))
+/* Nonzero if this statement-expression should cause warning if its result
+ is not used. */
+#define STMT_EXPR_WARN_UNUSED_RESULT(NODE) \
+ TREE_LANG_FLAG_3 (STMT_EXPR_CHECK (NODE))
+
/* LABEL_STMT accessor. This gives access to the label associated with
the given label statement. */
#define LABEL_STMT_LABEL(NODE) TREE_OPERAND (LABEL_STMT_CHECK (NODE), 0)
@@ -1121,28 +1147,48 @@ enum c_tree_code {
#undef DEFTREECODE
-extern void genrtl_do_pushlevel PARAMS ((void));
-extern void genrtl_goto_stmt PARAMS ((tree));
-extern void genrtl_expr_stmt PARAMS ((tree));
-extern void genrtl_expr_stmt_value PARAMS ((tree, int, int));
-extern void genrtl_decl_stmt PARAMS ((tree));
-extern void genrtl_if_stmt PARAMS ((tree));
-extern void genrtl_while_stmt PARAMS ((tree));
-extern void genrtl_do_stmt PARAMS ((tree));
-extern void genrtl_return_stmt PARAMS ((tree));
-extern void genrtl_for_stmt PARAMS ((tree));
-extern void genrtl_break_stmt PARAMS ((void));
-extern void genrtl_continue_stmt PARAMS ((void));
-extern void genrtl_scope_stmt PARAMS ((tree));
-extern void genrtl_switch_stmt PARAMS ((tree));
-extern void genrtl_case_label PARAMS ((tree));
-extern void genrtl_compound_stmt PARAMS ((tree));
-extern void genrtl_asm_stmt PARAMS ((tree, tree,
- tree, tree,
- tree, int));
-extern void genrtl_decl_cleanup PARAMS ((tree));
-extern int stmts_are_full_exprs_p PARAMS ((void));
-extern int anon_aggr_type_p PARAMS ((tree));
+#define c_common_stmt_codes \
+ CLEANUP_STMT, EXPR_STMT, COMPOUND_STMT, \
+ DECL_STMT, IF_STMT, FOR_STMT, \
+ WHILE_STMT, DO_STMT, RETURN_STMT, \
+ BREAK_STMT, CONTINUE_STMT, SCOPE_STMT, \
+ SWITCH_STMT, GOTO_STMT, LABEL_STMT, \
+ ASM_STMT, FILE_STMT, CASE_LABEL
+
+/* TRUE if a code represents a statement. The front end init
+ langhook should take care of initialization of this array. */
+extern bool statement_code_p[MAX_TREE_CODES];
+
+#define STATEMENT_CODE_P(CODE) statement_code_p[(int) (CODE)]
+
+#define INIT_STATEMENT_CODES(STMT_CODES) \
+ do { \
+ unsigned int i; \
+ memset (&statement_code_p, 0, sizeof (statement_code_p)); \
+ for (i = 0; i < ARRAY_SIZE (STMT_CODES); i++) \
+ statement_code_p[STMT_CODES[i]] = true; \
+ } while (0)
+
+extern void genrtl_do_pushlevel (void);
+extern void genrtl_goto_stmt (tree);
+extern void genrtl_expr_stmt (tree);
+extern void genrtl_expr_stmt_value (tree, int, int);
+extern void genrtl_decl_stmt (tree);
+extern void genrtl_if_stmt (tree);
+extern void genrtl_while_stmt (tree);
+extern void genrtl_do_stmt (tree);
+extern void genrtl_return_stmt (tree);
+extern void genrtl_for_stmt (tree);
+extern void genrtl_break_stmt (void);
+extern void genrtl_continue_stmt (void);
+extern void genrtl_scope_stmt (tree);
+extern void genrtl_switch_stmt (tree);
+extern void genrtl_case_label (tree);
+extern void genrtl_compound_stmt (tree);
+extern void genrtl_asm_stmt (tree, tree, tree, tree, tree, int);
+extern void genrtl_cleanup_stmt (tree);
+extern int stmts_are_full_exprs_p (void);
+extern int anon_aggr_type_p (tree);
/* For a VAR_DECL that is an anonymous union, these are the various
sub-variables that make up the anonymous union. */
@@ -1160,16 +1206,16 @@ extern int anon_aggr_type_p PARAMS ((tree));
an explicit asm specification. */
#define DECL_C_HARD_REGISTER(DECL) DECL_LANG_FLAG_4 (VAR_DECL_CHECK (DECL))
-extern void emit_local_var PARAMS ((tree));
-extern void make_rtl_for_local_static PARAMS ((tree));
-extern tree expand_cond PARAMS ((tree));
-extern tree c_expand_return PARAMS ((tree));
-extern tree do_case PARAMS ((tree, tree));
-extern tree build_stmt PARAMS ((enum tree_code, ...));
-extern tree build_case_label PARAMS ((tree, tree, tree));
-extern tree build_continue_stmt PARAMS ((void));
-extern tree build_break_stmt PARAMS ((void));
-extern tree build_return_stmt PARAMS ((tree));
+extern void emit_local_var (tree);
+extern void make_rtl_for_local_static (tree);
+extern tree expand_cond (tree);
+extern tree c_expand_return (tree);
+extern tree do_case (tree, tree);
+extern tree build_stmt (enum tree_code, ...);
+extern tree build_case_label (tree, tree, tree);
+extern tree build_continue_stmt (void);
+extern tree build_break_stmt (void);
+extern tree build_return_stmt (tree);
#define COMPOUND_STMT_NO_SCOPE(NODE) TREE_LANG_FLAG_0 (NODE)
@@ -1177,63 +1223,59 @@ extern tree build_return_stmt PARAMS ((tree));
initializers and cleanups. */
#define COMPOUND_STMT_BODY_BLOCK(NODE) TREE_LANG_FLAG_3 (NODE)
-extern void c_expand_asm_operands PARAMS ((tree, tree, tree, tree, int, const char *, int));
+extern void c_expand_asm_operands (tree, tree, tree, tree, int, location_t);
/* These functions must be defined by each front-end which implements
a variant of the C language. They are used in c-common.c. */
-extern tree build_unary_op PARAMS ((enum tree_code,
- tree, int));
-extern tree build_binary_op PARAMS ((enum tree_code,
- tree, tree, int));
-extern int lvalue_p PARAMS ((tree));
-extern tree default_conversion PARAMS ((tree));
+extern tree build_unary_op (enum tree_code, tree, int);
+extern tree build_binary_op (enum tree_code, tree, tree, int);
+extern int lvalue_p (tree);
+extern tree default_conversion (tree);
/* Given two integer or real types, return the type for their sum.
Given two compatible ANSI C types, returns the merged type. */
-extern tree common_type PARAMS ((tree, tree));
+extern tree common_type (tree, tree);
-extern tree expand_tree_builtin PARAMS ((tree, tree, tree));
+extern tree expand_tree_builtin (tree, tree, tree);
-extern tree decl_constant_value PARAMS ((tree));
+extern tree decl_constant_value (tree);
/* Handle increment and decrement of boolean types. */
-extern tree boolean_increment PARAMS ((enum tree_code,
- tree));
+extern tree boolean_increment (enum tree_code, tree);
/* Hook currently used only by the C++ front end to reset internal state
after entering or leaving a header file. */
-extern void extract_interface_info PARAMS ((void));
+extern void extract_interface_info (void);
-extern int case_compare PARAMS ((splay_tree_key,
- splay_tree_key));
+extern int case_compare (splay_tree_key, splay_tree_key);
-extern tree c_add_case_label PARAMS ((splay_tree,
- tree, tree,
- tree));
+extern tree c_add_case_label (splay_tree, tree, tree, tree);
-extern tree build_function_call PARAMS ((tree, tree));
+extern tree build_function_call (tree, tree);
-extern tree finish_label_address_expr PARAMS ((tree));
+extern tree finish_label_address_expr (tree);
/* Same function prototype, but the C and C++ front ends have
different implementations. Used in c-common.c. */
-extern tree lookup_label PARAMS ((tree));
+extern tree lookup_label (tree);
+
+extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
-extern rtx c_expand_expr PARAMS ((tree, rtx,
- enum machine_mode,
- int));
+extern int c_safe_from_p (rtx, tree);
-extern int c_safe_from_p PARAMS ((rtx, tree));
+extern int c_staticp (tree);
-extern int c_staticp PARAMS ((tree));
+extern int c_common_unsafe_for_reeval (tree);
-extern int c_common_unsafe_for_reeval PARAMS ((tree));
+extern void init_c_lex (void);
-extern const char *init_c_lex PARAMS ((const char *));
+extern void c_cpp_builtins (cpp_reader *);
-extern void cb_register_builtins PARAMS ((cpp_reader *));
+/* Positive if an implicit `extern "C"' scope has just been entered;
+ negative if such a scope has just been exited. */
+extern int pending_lang_change;
/* Information recorded about each file examined during compilation. */
@@ -1244,9 +1286,41 @@ struct c_fileinfo
short interface_unknown;
};
-struct c_fileinfo *get_fileinfo PARAMS ((const char *));
-extern void dump_time_statistics PARAMS ((void));
-
-extern int c_dump_tree PARAMS ((void *, tree));
+struct c_fileinfo *get_fileinfo (const char *);
+extern void dump_time_statistics (void);
+
+extern bool c_dump_tree (void *, tree);
+
+extern void pch_init (void);
+extern int c_common_valid_pch (cpp_reader *pfile, const char *name, int fd);
+extern void c_common_read_pch (cpp_reader *pfile, const char *name, int fd,
+ const char *orig);
+extern void c_common_write_pch (void);
+extern void c_common_no_more_pch (void);
+extern void builtin_define_with_value (const char *, const char *, int);
+extern void c_stddef_cpp_builtins (void);
+extern void fe_file_change (const struct line_map *);
+extern int c_estimate_num_insns (tree decl);
+extern bool c_decl_uninit (tree t);
+extern void c_parse_error (const char *, enum cpp_ttype, tree);
+
+/* The following have been moved here from c-tree.h, since they're needed
+ in the ObjC++ world, too. What is more, stub-objc.c could use a few
+ prototypes. */
+extern tree lookup_interface (tree);
+extern tree is_class_name (tree);
+extern tree objc_is_object_ptr (tree);
+extern void objc_check_decl (tree);
+extern int objc_comptypes (tree, tree, int);
+extern tree objc_message_selector (void);
+extern tree lookup_objc_ivar (tree);
+extern void *get_current_scope (void);
+extern void objc_mark_locals_volatile (void *);
+
+/* In c-ppoutput.c */
+extern void init_pp_output (FILE *);
+extern void preprocess_file (cpp_reader *);
+extern void pp_file_change (const struct line_map *);
+extern void pp_dir_change (cpp_reader *, const char *);
#endif /* ! GCC_C_COMMON_H */
diff --git a/contrib/gcc/c-convert.c b/contrib/gcc/c-convert.c
index 3634bbe44eaf..ce095acc29a5 100644
--- a/contrib/gcc/c-convert.c
+++ b/contrib/gcc/c-convert.c
@@ -1,5 +1,6 @@
/* Language-level data type conversion for GNU C.
- Copyright (C) 1987, 1988, 1991, 1998, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1991, 1998, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -26,6 +27,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "convert.h"
@@ -60,8 +63,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
not permitted by the language being compiled. */
tree
-convert (type, expr)
- tree type, expr;
+convert (tree type, tree expr)
{
tree e = expr;
enum tree_code code = TREE_CODE (type);
diff --git a/contrib/gcc/c-cppbuiltin.c b/contrib/gcc/c-cppbuiltin.c
new file mode 100644
index 000000000000..8573b8c5a46e
--- /dev/null
+++ b/contrib/gcc/c-cppbuiltin.c
@@ -0,0 +1,591 @@
+/* Define builtin-in macros for the C family front ends.
+ Copyright (C) 2002, 2003, 2004 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "flags.h"
+#include "real.h"
+#include "c-common.h"
+#include "c-pragma.h"
+#include "output.h"
+#include "except.h" /* For USING_SJLJ_EXCEPTIONS. */
+#include "toplev.h"
+#include "tm_p.h" /* Target prototypes. */
+
+#ifndef TARGET_OS_CPP_BUILTINS
+# define TARGET_OS_CPP_BUILTINS()
+#endif
+
+#ifndef TARGET_OBJFMT_CPP_BUILTINS
+# define TARGET_OBJFMT_CPP_BUILTINS()
+#endif
+
+#ifndef REGISTER_PREFIX
+#define REGISTER_PREFIX ""
+#endif
+
+/* Non-static as some targets don't use it. */
+void builtin_define_std (const char *) ATTRIBUTE_UNUSED;
+static void builtin_define_with_value_n (const char *, const char *,
+ size_t);
+static void builtin_define_with_int_value (const char *, HOST_WIDE_INT);
+static void builtin_define_with_hex_fp_value (const char *, tree,
+ int, const char *,
+ const char *);
+static void builtin_define_type_max (const char *, tree, int);
+static void builtin_define_type_precision (const char *, tree);
+static void builtin_define_float_constants (const char *, const char *,
+ tree);
+static void define__GNUC__ (void);
+
+/* Define NAME with value TYPE precision. */
+static void
+builtin_define_type_precision (const char *name, tree type)
+{
+ builtin_define_with_int_value (name, TYPE_PRECISION (type));
+}
+
+/* Define the float.h constants for TYPE using NAME_PREFIX and FP_SUFFIX. */
+static void
+builtin_define_float_constants (const char *name_prefix, const char *fp_suffix, tree type)
+{
+ /* Used to convert radix-based values to base 10 values in several cases.
+
+ In the max_exp -> max_10_exp conversion for 128-bit IEEE, we need at
+ least 6 significant digits for correct results. Using the fraction
+ formed by (log(2)*1e6)/(log(10)*1e6) overflows a 32-bit integer as an
+ intermediate; perhaps someone can find a better approximation, in the
+ mean time, I suspect using doubles won't harm the bootstrap here. */
+
+ const double log10_2 = .30102999566398119521;
+ double log10_b;
+ const struct real_format *fmt;
+
+ char name[64], buf[128];
+ int dig, min_10_exp, max_10_exp;
+ int decimal_dig;
+
+ fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
+
+ /* The radix of the exponent representation. */
+ if (type == float_type_node)
+ builtin_define_with_int_value ("__FLT_RADIX__", fmt->b);
+ log10_b = log10_2 * fmt->log2_b;
+
+ /* The number of radix digits, p, in the floating-point significand. */
+ sprintf (name, "__%s_MANT_DIG__", name_prefix);
+ builtin_define_with_int_value (name, fmt->p);
+
+ /* The number of decimal digits, q, such that any floating-point number
+ with q decimal digits can be rounded into a floating-point number with
+ p radix b digits and back again without change to the q decimal digits,
+
+ p log10 b if b is a power of 10
+ floor((p - 1) log10 b) otherwise
+ */
+ dig = (fmt->p - 1) * log10_b;
+ sprintf (name, "__%s_DIG__", name_prefix);
+ builtin_define_with_int_value (name, dig);
+
+ /* The minimum negative int x such that b**(x-1) is a normalized float. */
+ sprintf (name, "__%s_MIN_EXP__", name_prefix);
+ sprintf (buf, "(%d)", fmt->emin);
+ builtin_define_with_value (name, buf, 0);
+
+ /* The minimum negative int x such that 10**x is a normalized float,
+
+ ceil (log10 (b ** (emin - 1)))
+ = ceil (log10 (b) * (emin - 1))
+
+ Recall that emin is negative, so the integer truncation calculates
+ the ceiling, not the floor, in this case. */
+ min_10_exp = (fmt->emin - 1) * log10_b;
+ sprintf (name, "__%s_MIN_10_EXP__", name_prefix);
+ sprintf (buf, "(%d)", min_10_exp);
+ builtin_define_with_value (name, buf, 0);
+
+ /* The maximum int x such that b**(x-1) is a representable float. */
+ sprintf (name, "__%s_MAX_EXP__", name_prefix);
+ builtin_define_with_int_value (name, fmt->emax);
+
+ /* The maximum int x such that 10**x is in the range of representable
+ finite floating-point numbers,
+
+ floor (log10((1 - b**-p) * b**emax))
+ = floor (log10(1 - b**-p) + log10(b**emax))
+ = floor (log10(1 - b**-p) + log10(b)*emax)
+
+ The safest thing to do here is to just compute this number. But since
+ we don't link cc1 with libm, we cannot. We could implement log10 here
+ a series expansion, but that seems too much effort because:
+
+ Note that the first term, for all extant p, is a number exceedingly close
+ to zero, but slightly negative. Note that the second term is an integer
+ scaling an irrational number, and that because of the floor we are only
+ interested in its integral portion.
+
+ In order for the first term to have any effect on the integral portion
+ of the second term, the second term has to be exceedingly close to an
+ integer itself (e.g. 123.000000000001 or something). Getting a result
+ that close to an integer requires that the irrational multiplicand have
+ a long series of zeros in its expansion, which doesn't occur in the
+ first 20 digits or so of log10(b).
+
+ Hand-waving aside, crunching all of the sets of constants above by hand
+ does not yield a case for which the first term is significant, which
+ in the end is all that matters. */
+ max_10_exp = fmt->emax * log10_b;
+ sprintf (name, "__%s_MAX_10_EXP__", name_prefix);
+ builtin_define_with_int_value (name, max_10_exp);
+
+ /* The number of decimal digits, n, such that any floating-point number
+ can be rounded to n decimal digits and back again without change to
+ the value.
+
+ p * log10(b) if b is a power of 10
+ ceil(1 + p * log10(b)) otherwise
+
+ The only macro we care about is this number for the widest supported
+ floating type, but we want this value for rendering constants below. */
+ {
+ double d_decimal_dig = 1 + fmt->p * log10_b;
+ decimal_dig = d_decimal_dig;
+ if (decimal_dig < d_decimal_dig)
+ decimal_dig++;
+ }
+ if (type == long_double_type_node)
+ builtin_define_with_int_value ("__DECIMAL_DIG__", decimal_dig);
+
+ /* Since, for the supported formats, B is always a power of 2, we
+ construct the following numbers directly as a hexadecimal
+ constants. */
+
+ /* The maximum representable finite floating-point number,
+ (1 - b**-p) * b**emax */
+ {
+ int i, n;
+ char *p;
+
+ strcpy (buf, "0x0.");
+ n = fmt->p * fmt->log2_b;
+ for (i = 0, p = buf + 4; i + 3 < n; i += 4)
+ *p++ = 'f';
+ if (i < n)
+ *p++ = "08ce"[n - i];
+ sprintf (p, "p%d", fmt->emax * fmt->log2_b);
+ if (fmt->pnan < fmt->p)
+ {
+ /* This is an IBM extended double format made up of two IEEE
+ doubles. The value of the long double is the sum of the
+ values of the two parts. The most significant part is
+ required to be the value of the long double rounded to the
+ nearest double. Rounding means we need a slightly smaller
+ value for LDBL_MAX. */
+ buf[4 + fmt->pnan / 4] = "7bde"[fmt->pnan % 4];
+ }
+ }
+ sprintf (name, "__%s_MAX__", name_prefix);
+ builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
+
+ /* The minimum normalized positive floating-point number,
+ b**(emin-1). */
+ sprintf (name, "__%s_MIN__", name_prefix);
+ sprintf (buf, "0x1p%d", (fmt->emin - 1) * fmt->log2_b);
+ builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
+
+ /* The difference between 1 and the least value greater than 1 that is
+ representable in the given floating point type, b**(1-p). */
+ sprintf (name, "__%s_EPSILON__", name_prefix);
+ sprintf (buf, "0x1p%d", (1 - fmt->p) * fmt->log2_b);
+ builtin_define_with_hex_fp_value (name, type, decimal_dig, buf, fp_suffix);
+
+ /* For C++ std::numeric_limits<T>::denorm_min. The minimum denormalized
+ positive floating-point number, b**(emin-p). Zero for formats that
+ don't support denormals. */
+ sprintf (name, "__%s_DENORM_MIN__", name_prefix);
+ if (fmt->has_denorm)
+ {
+ sprintf (buf, "0x1p%d", (fmt->emin - fmt->p) * fmt->log2_b);
+ builtin_define_with_hex_fp_value (name, type, decimal_dig,
+ buf, fp_suffix);
+ }
+ else
+ {
+ sprintf (buf, "0.0%s", fp_suffix);
+ builtin_define_with_value (name, buf, 0);
+ }
+
+ /* For C++ std::numeric_limits<T>::has_infinity. */
+ sprintf (name, "__%s_HAS_INFINITY__", name_prefix);
+ builtin_define_with_int_value (name,
+ MODE_HAS_INFINITIES (TYPE_MODE (type)));
+ /* For C++ std::numeric_limits<T>::has_quiet_NaN. We do not have a
+ predicate to distinguish a target that has both quiet and
+ signalling NaNs from a target that has only quiet NaNs or only
+ signalling NaNs, so we assume that a target that has any kind of
+ NaN has quiet NaNs. */
+ sprintf (name, "__%s_HAS_QUIET_NAN__", name_prefix);
+ builtin_define_with_int_value (name, MODE_HAS_NANS (TYPE_MODE (type)));
+}
+
+/* Define __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__. */
+static void
+define__GNUC__ (void)
+{
+ /* The format of the version string, enforced below, is
+ ([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)? */
+ const char *q, *v = version_string;
+
+ while (*v && ! ISDIGIT (*v))
+ v++;
+ if (!*v || (v > version_string && v[-1] != '-'))
+ abort ();
+
+ q = v;
+ while (ISDIGIT (*v))
+ v++;
+ builtin_define_with_value_n ("__GNUC__", q, v - q);
+ if (c_dialect_cxx ())
+ builtin_define_with_value_n ("__GNUG__", q, v - q);
+
+ if (*v != '.' || !ISDIGIT (v[1]))
+ abort ();
+ q = ++v;
+ while (ISDIGIT (*v))
+ v++;
+ builtin_define_with_value_n ("__GNUC_MINOR__", q, v - q);
+
+ if (*v == '.')
+ {
+ if (!ISDIGIT (v[1]))
+ abort ();
+ q = ++v;
+ while (ISDIGIT (*v))
+ v++;
+ builtin_define_with_value_n ("__GNUC_PATCHLEVEL__", q, v - q);
+ }
+ else
+ builtin_define_with_value_n ("__GNUC_PATCHLEVEL__", "0", 1);
+
+ if (*v && *v != ' ' && *v != '-')
+ abort ();
+}
+
+/* Hook that registers front end and target-specific built-ins. */
+void
+c_cpp_builtins (cpp_reader *pfile)
+{
+ /* -undef turns off target-specific built-ins. */
+ if (flag_undef)
+ return;
+
+ define__GNUC__ ();
+
+ /* For stddef.h. They require macros defined in c-common.c. */
+ c_stddef_cpp_builtins ();
+
+ if (c_dialect_cxx ())
+ {
+ if (SUPPORTS_ONE_ONLY)
+ cpp_define (pfile, "__GXX_WEAK__=1");
+ else
+ cpp_define (pfile, "__GXX_WEAK__=0");
+ if (warn_deprecated)
+ cpp_define (pfile, "__DEPRECATED");
+ }
+ /* Note that we define this for C as well, so that we know if
+ __attribute__((cleanup)) will interface with EH. */
+ if (flag_exceptions)
+ cpp_define (pfile, "__EXCEPTIONS");
+
+ /* Represents the C++ ABI version, always defined so it can be used while
+ preprocessing C and assembler. */
+ if (flag_abi_version == 0)
+ /* Use a very large value so that:
+
+ #if __GXX_ABI_VERSION >= <value for version X>
+
+ will work whether the user explicitly says "-fabi-version=x" or
+ "-fabi-version=0". Do not use INT_MAX because that will be
+ different from system to system. */
+ builtin_define_with_int_value ("__GXX_ABI_VERSION", 999999);
+ else if (flag_abi_version == 1)
+ /* Due to an historical accident, this version had the value
+ "102". */
+ builtin_define_with_int_value ("__GXX_ABI_VERSION", 102);
+ else
+ /* Newer versions have values 1002, 1003, .... */
+ builtin_define_with_int_value ("__GXX_ABI_VERSION",
+ 1000 + flag_abi_version);
+
+ /* libgcc needs to know this. */
+ if (USING_SJLJ_EXCEPTIONS)
+ cpp_define (pfile, "__USING_SJLJ_EXCEPTIONS__");
+
+ /* limits.h needs to know these. */
+ builtin_define_type_max ("__SCHAR_MAX__", signed_char_type_node, 0);
+ builtin_define_type_max ("__SHRT_MAX__", short_integer_type_node, 0);
+ builtin_define_type_max ("__INT_MAX__", integer_type_node, 0);
+ builtin_define_type_max ("__LONG_MAX__", long_integer_type_node, 1);
+ builtin_define_type_max ("__LONG_LONG_MAX__", long_long_integer_type_node, 2);
+ builtin_define_type_max ("__WCHAR_MAX__", wchar_type_node, 0);
+
+ builtin_define_type_precision ("__CHAR_BIT__", char_type_node);
+
+ /* float.h needs to know these. */
+
+ builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
+ TARGET_FLT_EVAL_METHOD);
+
+ builtin_define_float_constants ("FLT", "F", float_type_node);
+ builtin_define_float_constants ("DBL", "", double_type_node);
+ builtin_define_float_constants ("LDBL", "L", long_double_type_node);
+
+ /* For use in assembly language. */
+ builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0);
+ builtin_define_with_value ("__USER_LABEL_PREFIX__", user_label_prefix, 0);
+
+ /* Misc. */
+ builtin_define_with_value ("__VERSION__", version_string, 1);
+
+ /* Definitions for LP64 model. */
+ if (TYPE_PRECISION (long_integer_type_node) == 64
+ && POINTER_SIZE == 64
+ && TYPE_PRECISION (integer_type_node) == 32)
+ {
+ cpp_define (pfile, "_LP64");
+ cpp_define (pfile, "__LP64__");
+ }
+
+ /* Other target-independent built-ins determined by command-line
+ options. */
+ if (optimize_size)
+ cpp_define (pfile, "__OPTIMIZE_SIZE__");
+ if (optimize)
+ cpp_define (pfile, "__OPTIMIZE__");
+
+ if (fast_math_flags_set_p ())
+ cpp_define (pfile, "__FAST_MATH__");
+ if (flag_really_no_inline)
+ cpp_define (pfile, "__NO_INLINE__");
+ if (flag_signaling_nans)
+ cpp_define (pfile, "__SUPPORT_SNAN__");
+ if (flag_finite_math_only)
+ cpp_define (pfile, "__FINITE_MATH_ONLY__=1");
+ else
+ cpp_define (pfile, "__FINITE_MATH_ONLY__=0");
+
+ if (flag_iso)
+ cpp_define (pfile, "__STRICT_ANSI__");
+
+ if (!flag_signed_char)
+ cpp_define (pfile, "__CHAR_UNSIGNED__");
+
+ if (c_dialect_cxx () && TREE_UNSIGNED (wchar_type_node))
+ cpp_define (pfile, "__WCHAR_UNSIGNED__");
+
+ /* Make the choice of ObjC runtime visible to source code. */
+ if (c_dialect_objc () && flag_next_runtime)
+ cpp_define (pfile, "__NEXT_RUNTIME__");
+
+ /* A straightforward target hook doesn't work, because of problems
+ linking that hook's body when part of non-C front ends. */
+# define preprocessing_asm_p() (cpp_get_options (pfile)->lang == CLK_ASM)
+# define preprocessing_trad_p() (cpp_get_options (pfile)->traditional)
+# define builtin_define(TXT) cpp_define (pfile, TXT)
+# define builtin_assert(TXT) cpp_assert (pfile, TXT)
+ TARGET_CPU_CPP_BUILTINS ();
+ TARGET_OS_CPP_BUILTINS ();
+ TARGET_OBJFMT_CPP_BUILTINS ();
+}
+
+/* Pass an object-like macro. If it doesn't lie in the user's
+ namespace, defines it unconditionally. Otherwise define a version
+ with two leading underscores, and another version with two leading
+ and trailing underscores, and define the original only if an ISO
+ standard was not nominated.
+
+ e.g. passing "unix" defines "__unix", "__unix__" and possibly
+ "unix". Passing "_mips" defines "__mips", "__mips__" and possibly
+ "_mips". */
+void
+builtin_define_std (const char *macro)
+{
+ size_t len = strlen (macro);
+ char *buff = alloca (len + 5);
+ char *p = buff + 2;
+ char *q = p + len;
+
+ /* prepend __ (or maybe just _) if in user's namespace. */
+ memcpy (p, macro, len + 1);
+ if (!( *p == '_' && (p[1] == '_' || ISUPPER (p[1]))))
+ {
+ if (*p != '_')
+ *--p = '_';
+ if (p[1] != '_')
+ *--p = '_';
+ }
+ cpp_define (parse_in, p);
+
+ /* If it was in user's namespace... */
+ if (p != buff + 2)
+ {
+ /* Define the macro with leading and following __. */
+ if (q[-1] != '_')
+ *q++ = '_';
+ if (q[-2] != '_')
+ *q++ = '_';
+ *q = '\0';
+ cpp_define (parse_in, p);
+
+ /* Finally, define the original macro if permitted. */
+ if (!flag_iso)
+ cpp_define (parse_in, macro);
+ }
+}
+
+/* Pass an object-like macro and a value to define it to. The third
+ parameter says whether or not to turn the value into a string
+ constant. */
+void
+builtin_define_with_value (const char *macro, const char *expansion, int is_str)
+{
+ char *buf;
+ size_t mlen = strlen (macro);
+ size_t elen = strlen (expansion);
+ size_t extra = 2; /* space for an = and a NUL */
+
+ if (is_str)
+ extra += 2; /* space for two quote marks */
+
+ buf = alloca (mlen + elen + extra);
+ if (is_str)
+ sprintf (buf, "%s=\"%s\"", macro, expansion);
+ else
+ sprintf (buf, "%s=%s", macro, expansion);
+
+ cpp_define (parse_in, buf);
+}
+
+/* Pass an object-like macro and a value to define it to. The third
+ parameter is the length of the expansion. */
+static void
+builtin_define_with_value_n (const char *macro, const char *expansion, size_t elen)
+{
+ char *buf;
+ size_t mlen = strlen (macro);
+
+ /* Space for an = and a NUL. */
+ buf = alloca (mlen + elen + 2);
+ memcpy (buf, macro, mlen);
+ buf[mlen] = '=';
+ memcpy (buf + mlen + 1, expansion, elen);
+ buf[mlen + elen + 1] = '\0';
+
+ cpp_define (parse_in, buf);
+}
+
+/* Pass an object-like macro and an integer value to define it to. */
+static void
+builtin_define_with_int_value (const char *macro, HOST_WIDE_INT value)
+{
+ char *buf;
+ size_t mlen = strlen (macro);
+ size_t vlen = 18;
+ size_t extra = 2; /* space for = and NUL. */
+
+ buf = alloca (mlen + vlen + extra);
+ memcpy (buf, macro, mlen);
+ buf[mlen] = '=';
+ sprintf (buf + mlen + 1, HOST_WIDE_INT_PRINT_DEC, value);
+
+ cpp_define (parse_in, buf);
+}
+
+/* Pass an object-like macro a hexadecimal floating-point value. */
+static void
+builtin_define_with_hex_fp_value (const char *macro,
+ tree type ATTRIBUTE_UNUSED, int digits,
+ const char *hex_str, const char *fp_suffix)
+{
+ REAL_VALUE_TYPE real;
+ char dec_str[64], buf[256];
+
+ /* Hex values are really cool and convenient, except that they're
+ not supported in strict ISO C90 mode. First, the "p-" sequence
+ is not valid as part of a preprocessor number. Second, we get a
+ pedwarn from the preprocessor, which has no context, so we can't
+ suppress the warning with __extension__.
+
+ So instead what we do is construct the number in hex (because
+ it's easy to get the exact correct value), parse it as a real,
+ then print it back out as decimal. */
+
+ real_from_string (&real, hex_str);
+ real_to_decimal (dec_str, &real, sizeof (dec_str), digits, 0);
+
+ sprintf (buf, "%s=%s%s", macro, dec_str, fp_suffix);
+ cpp_define (parse_in, buf);
+}
+
+/* Define MAX for TYPE based on the precision of the type. IS_LONG is
+ 1 for type "long" and 2 for "long long". We have to handle
+ unsigned types, since wchar_t might be unsigned. */
+
+static void
+builtin_define_type_max (const char *macro, tree type, int is_long)
+{
+ static const char *const values[]
+ = { "127", "255",
+ "32767", "65535",
+ "2147483647", "4294967295",
+ "9223372036854775807", "18446744073709551615",
+ "170141183460469231731687303715884105727",
+ "340282366920938463463374607431768211455" };
+ static const char *const suffixes[] = { "", "U", "L", "UL", "LL", "ULL" };
+
+ const char *value, *suffix;
+ char *buf;
+ size_t idx;
+
+ /* Pre-rendering the values mean we don't have to futz with printing a
+ multi-word decimal value. There are also a very limited number of
+ precisions that we support, so it's really a waste of time. */
+ switch (TYPE_PRECISION (type))
+ {
+ case 8: idx = 0; break;
+ case 16: idx = 2; break;
+ case 32: idx = 4; break;
+ case 64: idx = 6; break;
+ case 128: idx = 8; break;
+ default: abort ();
+ }
+
+ value = values[idx + TREE_UNSIGNED (type)];
+ suffix = suffixes[is_long * 2 + TREE_UNSIGNED (type)];
+
+ buf = alloca (strlen (macro) + 1 + strlen (value) + strlen (suffix) + 1);
+ sprintf (buf, "%s=%s%s", macro, value, suffix);
+
+ cpp_define (parse_in, buf);
+}
diff --git a/contrib/gcc/c-decl.c b/contrib/gcc/c-decl.c
index 5cb5270084df..6e87a7662baa 100644
--- a/contrib/gcc/c-decl.c
+++ b/contrib/gcc/c-decl.c
@@ -1,6 +1,6 @@
/* Process declarations and variables for C compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -28,6 +28,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "intl.h"
#include "tree.h"
#include "tree-inline.h"
@@ -43,11 +45,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "cpplib.h"
#include "target.h"
#include "debug.h"
+#include "opts.h"
#include "timevar.h"
#include "c-common.h"
#include "c-pragma.h"
+#include "cgraph.h"
+#include "hashtab.h"
#include "libfuncs.h"
#include "except.h"
+#include "langhooks-def.h"
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
enum decl_context
@@ -55,7 +61,6 @@ enum decl_context
FUNCDEF, /* Function definition */
PARM, /* Declaration of parm before function body */
FIELD, /* Declaration inside struct or union */
- BITFIELD, /* Likewise but with specified width */
TYPENAME}; /* Typename (inside cast or sizeof) */
@@ -64,8 +69,7 @@ enum decl_context
tree pending_invalid_xref;
/* File and line to appear in the eventual error message. */
-const char *pending_invalid_xref_file;
-int pending_invalid_xref_line;
+location_t pending_invalid_xref_location;
/* While defining an enum type, this is 1 plus the last enumerator
constant value. Note that will do not have to save this or `enum_overflow'
@@ -80,28 +84,38 @@ static tree enum_next_value;
static int enum_overflow;
/* Parsing a function declarator leaves a list of parameter names
- or a chain or parameter decls here. */
+ or a chain of parameter decls here. */
static tree last_function_parms;
-/* Parsing a function declarator leaves here a chain of structure
- and enum types declared in the parmlist. */
+/* ... and a chain of structure and enum types declared in the
+ parmlist here. */
static tree last_function_parm_tags;
+/* ... and a chain of all non-parameter declarations (such as
+ CONST_DECLs from enumerations) here. */
+
+static tree last_function_parm_others;
+
/* After parsing the declarator that starts a function definition,
- `start_function' puts here the list of parameter names or chain of decls.
- `store_parm_decls' finds it here. */
+ `start_function' puts the list of parameter names or chain of decls here
+ for `store_parm_decls' to find. */
static tree current_function_parms;
/* Similar, for last_function_parm_tags. */
+
static tree current_function_parm_tags;
+/* And for last_function_parm_others. */
+
+static tree current_function_parm_others;
+
/* Similar, for the file and line that the prototype came from if this is
an old-style definition. */
-static const char *current_function_prototype_file;
-static int current_function_prototype_line;
+
+static location_t current_function_prototype_locus;
/* The current statement tree. */
@@ -111,15 +125,22 @@ static GTY(()) struct stmt_tree_s c_stmt_tree;
static GTY(()) tree c_scope_stmt_stack;
-/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
- that have names. Here so we can clear out their names' definitions
- at the end of the function. */
+/* State saving variables. */
+int c_in_iteration_stmt;
+int c_in_case_stmt;
+
+/* A list of external DECLs that appeared at block scope when there was
+ some other global meaning for that identifier. */
+static GTY(()) tree truly_local_externals;
+
+/* All the builtins; this is a subset of the entries of global_scope. */
-static GTY(()) tree named_labels;
+static GTY(()) tree first_builtin_decl;
+static GTY(()) tree last_builtin_decl;
-/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */
+/* A DECL for the current file-scope context. */
-static GTY(()) tree shadowed_labels;
+static GTY(()) tree current_file_decl;
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement that specifies a return value is seen. */
@@ -145,121 +166,137 @@ static int warn_about_return_type;
static int current_extern_inline;
-/* For each binding contour we allocate a binding_level structure
- * which records the names defined in that contour.
- * Contours include:
- * 0) the global one
- * 1) one for each function definition,
- * where internal declarations of the parameters appear.
- * 2) one for each compound statement,
- * to record its declarations.
- *
- * The current meaning of a name can be found by searching the levels from
- * the current one out to the global one.
- */
-
-/* Note that the information in the `names' component of the global contour
- is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
-
-struct binding_level GTY(())
- {
- /* A chain of _DECL nodes for all variables, constants, functions,
- and typedef types. These are in the reverse of the order supplied.
- */
- tree names;
-
- /* A list of structure, union and enum definitions,
- * for looking up tag names.
- * It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name,
- * or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE,
- * or ENUMERAL_TYPE node.
- */
- tree tags;
+/* Each c_scope structure describes the complete contents of one scope.
+ Three scopes are distinguished specially: the innermost or current
+ scope, the innermost function scope, and the outermost or file scope.
- /* For each level, a list of shadowed outer-level local definitions
- to be restored when this level is popped.
- Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and
- whose TREE_VALUE is its old definition (a kind of ..._DECL node). */
- tree shadowed;
+ Most declarations are recorded in the current scope.
- /* For each level (except not the global one),
- a chain of BLOCK nodes for all the levels
- that were entered and exited one level down. */
- tree blocks;
+ All normal label declarations are recorded in the innermost
+ function scope, as are bindings of undeclared identifiers to
+ error_mark_node. (GCC permits nested functions as an extension,
+ hence the 'innermost' qualifier.) Explicitly declared labels
+ (using the __label__ extension) appear in the current scope.
- /* The BLOCK node for this level, if one has been preallocated.
- If 0, the BLOCK is allocated (if needed) when the level is popped. */
- tree this_block;
+ Being in the global scope (current_scope == global_scope) causes
+ special behavior in several places below. Also, under some
+ conditions the Objective-C front end records declarations in the
+ global scope even though that isn't the current scope.
- /* The binding level which this one is contained in (inherits from). */
- struct binding_level *level_chain;
+ The order of the names, parms, and blocks lists matters, and they
+ are frequently appended to. To avoid having to walk all the way to
+ the end of the list on each insertion, or reverse the lists later,
+ we maintain a pointer to the last list entry for each of the lists.
- /* Nonzero for the level that holds the parameters of a function. */
- char parm_flag;
+ The order of the tags, shadowed, and shadowed_tags
+ lists does not matter, so we just prepend to these lists. */
- /* Nonzero if this level "doesn't exist" for tags. */
- char tag_transparent;
-
- /* Nonzero if sublevels of this level "don't exist" for tags.
- This is set in the parm level of a function definition
- while reading the function body, so that the outermost block
- of the function body will be tag-transparent. */
- char subblocks_tag_transparent;
-
- /* Nonzero means make a BLOCK for this level regardless of all else. */
- char keep;
-
- /* Nonzero means make a BLOCK if this level has any subblocks. */
- char keep_if_subblocks;
+struct c_scope GTY(())
+{
+ /* The scope containing this one. */
+ struct c_scope *outer;
+
+ /* The next outermost function scope. */
+ struct c_scope *outer_function;
+
+ /* All variables, constants, functions, labels, and typedef names. */
+ tree names;
+ tree names_last;
+
+ /* All parameter declarations. Used only in the outermost scope of
+ a function. */
+ tree parms;
+ tree parms_last;
+
+ /* All structure, union, and enum type tags. */
+ tree tags;
+
+ /* For each scope, a list of shadowed outer-scope definitions
+ to be restored when this scope is popped.
+ Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and
+ whose TREE_VALUE is its old definition (a kind of ..._DECL node). */
+ tree shadowed;
+
+ /* For each scope, a list of shadowed outer-scope tag definitions
+ to be restored when this scope is popped.
+ Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and
+ whose TREE_VALUE is its old definition (a kind of ..._TYPE node). */
+ tree shadowed_tags;
+
+ /* For each scope (except the global one), a chain of BLOCK nodes
+ for all the scopes that were entered and exited one level down. */
+ tree blocks;
+ tree blocks_last;
+
+ /* True if we are currently filling this scope with parameter
+ declarations. */
+ BOOL_BITFIELD parm_flag : 1;
- /* List of decls in `names' that have incomplete structure or
- union types. */
- tree incomplete_list;
+ /* True if we already complained about forward parameter decls
+ in this scope. This prevents double warnings on
+ foo (int a; int b; ...) */
+ BOOL_BITFIELD warned_forward_parm_decls : 1;
- /* A list of decls giving the (reversed) specified order of parms,
- not including any forward-decls in the parmlist.
- This is so we can put the parms in proper order for assign_parms. */
- tree parm_order;
- };
+ /* True if this is the outermost block scope of a function body.
+ This scope contains the parameters, the local variables declared
+ in the outermost block, and all the labels (except those in
+ nested functions, or declared at block scope with __label__). */
+ BOOL_BITFIELD function_body : 1;
-#define NULL_BINDING_LEVEL (struct binding_level *) NULL
+ /* True means make a BLOCK for this scope no matter what. */
+ BOOL_BITFIELD keep : 1;
+};
-/* The binding level currently in effect. */
+/* The scope currently in effect. */
-static GTY(()) struct binding_level *current_binding_level;
+static GTY(()) struct c_scope *current_scope;
-/* A chain of binding_level structures awaiting reuse. */
+/* A chain of c_scope structures awaiting reuse. */
-static GTY((deletable (""))) struct binding_level *free_binding_level;
+static GTY((deletable (""))) struct c_scope *scope_freelist;
-/* The outermost binding level, for names of file scope.
- This is created when the compiler is started and exists
- through the entire run. */
+/* The innermost function scope. Ordinary (not explicitly declared)
+ labels, bindings to error_mark_node, and the lazily-created
+ bindings of __func__ and its friends get this scope. */
-static GTY(()) struct binding_level *global_binding_level;
+static GTY(()) struct c_scope *current_function_scope;
-/* Binding level structures are initialized by copying this one. */
+/* The outermost scope, corresponding to the C "file scope". This is
+ created when the compiler is started and exists through the entire run. */
-static struct binding_level clear_binding_level
- = {NULL, NULL, NULL, NULL, NULL, NULL_BINDING_LEVEL, 0, 0, 0, 0, 0, NULL,
- NULL};
+static GTY(()) struct c_scope *global_scope;
-/* Nonzero means unconditionally make a BLOCK for the next level pushed. */
+/* Append VAR to LIST in scope SCOPE. */
+#define SCOPE_LIST_APPEND(scope, list, decl) do { \
+ struct c_scope *s_ = (scope); \
+ tree d_ = (decl); \
+ if (s_->list##_last) \
+ TREE_CHAIN (s_->list##_last) = d_; \
+ else \
+ s_->list = d_; \
+ s_->list##_last = d_; \
+} while (0)
-static int keep_next_level_flag;
+/* Concatenate FROM in scope FSCOPE onto TO in scope TSCOPE. */
+#define SCOPE_LIST_CONCAT(tscope, to, fscope, from) do { \
+ struct c_scope *t_ = (tscope); \
+ struct c_scope *f_ = (fscope); \
+ if (t_->to##_last) \
+ TREE_CHAIN (t_->to##_last) = f_->from; \
+ else \
+ t_->to = f_->from; \
+ t_->to##_last = f_->from##_last; \
+} while (0)
-/* Nonzero means make a BLOCK for the next level pushed
- if it has subblocks. */
+/* True means unconditionally make a BLOCK for the next scope pushed. */
-static int keep_next_if_subblocks;
+static bool keep_next_level_flag;
-/* The chain of outer levels of label scopes.
- This uses the same data structure used for binding levels,
- but it works differently: each link in the chain records
- saved values of named_labels and shadowed_labels for
- a label binding level outside the current one. */
+/* True means the next call to pushlevel will be the outermost scope
+ of a function body, so do not push a new scope, merely cease
+ expecting parameter decls. */
-static GTY(()) struct binding_level *label_level_chain;
+static bool next_is_function_body;
/* Functions called automatically at the beginning and end of execution. */
@@ -267,32 +304,34 @@ tree static_ctors, static_dtors;
/* Forward declarations. */
-static struct binding_level * make_binding_level PARAMS ((void));
-static void pop_binding_level PARAMS ((struct binding_level **));
-static void clear_limbo_values PARAMS ((tree));
-static int duplicate_decls PARAMS ((tree, tree, int));
-static int redeclaration_error_message PARAMS ((tree, tree));
-static void storedecls PARAMS ((tree));
-static void storetags PARAMS ((tree));
-static tree lookup_tag PARAMS ((enum tree_code, tree,
- struct binding_level *, int));
-static tree lookup_tag_reverse PARAMS ((tree));
-static tree grokdeclarator PARAMS ((tree, tree, enum decl_context,
- int));
-static tree grokparms PARAMS ((tree, int));
-static void layout_array_type PARAMS ((tree));
-static tree c_make_fname_decl PARAMS ((tree, int));
-static void c_expand_body PARAMS ((tree, int, int));
-static void warn_if_shadowing PARAMS ((tree, tree));
-static bool flexible_array_type_p PARAMS ((tree));
-static int field_decl_cmp PARAMS ((const PTR, const PTR));
-static tree set_save_expr_context PARAMS ((tree *, int *, void *));
+static struct c_scope *make_scope (void);
+static void pop_scope (void);
+static tree make_label (tree, location_t);
+static void bind_label (tree, tree, struct c_scope *);
+static void implicit_decl_warning (tree);
+static tree lookup_tag (enum tree_code, tree, int);
+static tree lookup_name_current_level (tree);
+static tree grokdeclarator (tree, tree, enum decl_context, int, tree *);
+static tree grokparms (tree, int);
+static void layout_array_type (tree);
+static void store_parm_decls_newstyle (void);
+static void store_parm_decls_oldstyle (void);
+static tree c_make_fname_decl (tree, int);
+static void c_expand_body_1 (tree, int);
+static tree any_external_decl (tree);
+static void record_external_decl (tree);
+static void warn_if_shadowing (tree, tree);
+static void check_bitfield_type_and_width (tree *, tree *, const char *);
+static void clone_underlying_type (tree);
+static bool flexible_array_type_p (tree);
+static hashval_t link_hash_hash (const void *);
+static int link_hash_eq (const void *, const void *);
/* States indicating how grokdeclarator() should handle declspecs marked
with __attribute__((deprecated)). An object declared as
__attribute__((deprecated)) suppresses warnings of uses of other
deprecated items. */
-
+
enum deprecated_states {
DEPRECATED_NORMAL,
DEPRECATED_SUPPRESS
@@ -301,33 +340,25 @@ enum deprecated_states {
static enum deprecated_states deprecated_state = DEPRECATED_NORMAL;
void
-c_print_identifier (file, node, indent)
- FILE *file;
- tree node;
- int indent;
+c_print_identifier (FILE *file, tree node, int indent)
{
- print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
- print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
+ print_node (file, "symbol", IDENTIFIER_SYMBOL_VALUE (node), indent + 4);
+ print_node (file, "tag", IDENTIFIER_TAG_VALUE (node), indent + 4);
print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
- print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
- print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4);
- print_node (file, "limbo value", IDENTIFIER_LIMBO_VALUE (node), indent + 4);
if (C_IS_RESERVED_WORD (node))
{
tree rid = ridpointers[C_RID_CODE (node)];
indent_to (file, indent + 4);
- fprintf (file, "rid ");
- fprintf (file, HOST_PTR_PRINTF, (void *)rid);
- fprintf (file, " \"%s\"", IDENTIFIER_POINTER (rid));
+ fprintf (file, "rid " HOST_PTR_PRINTF " \"%s\"",
+ (void *) rid, IDENTIFIER_POINTER (rid));
}
}
/* Hook called at end of compilation to assume 1 elt
- for a top-level tentative array defn that wasn't complete before. */
+ for a file-scope tentative array defn that wasn't complete before. */
void
-c_finish_incomplete_decl (decl)
- tree decl;
+c_finish_incomplete_decl (tree decl)
{
if (TREE_CODE (decl) == VAR_DECL)
{
@@ -337,7 +368,7 @@ c_finish_incomplete_decl (decl)
&& ! DECL_EXTERNAL (decl)
&& TYPE_DOMAIN (type) == 0)
{
- warning_with_decl (decl, "array `%s' assumed to have one element");
+ warning ("%Jarray '%D' assumed to have one element", decl, decl);
complete_array_type (type, NULL_TREE, 1);
@@ -346,463 +377,339 @@ c_finish_incomplete_decl (decl)
}
}
-/* Reuse or create a struct for this binding level. */
+/* Reuse or create a struct for this scope. */
-static struct binding_level *
-make_binding_level ()
+static struct c_scope *
+make_scope (void)
{
- if (free_binding_level)
+ struct c_scope *result;
+ if (scope_freelist)
{
- struct binding_level *result = free_binding_level;
- free_binding_level = result->level_chain;
- return result;
+ result = scope_freelist;
+ scope_freelist = result->outer;
}
else
- return (struct binding_level *) ggc_alloc (sizeof (struct binding_level));
+ result = ggc_alloc_cleared (sizeof (struct c_scope));
+
+ return result;
}
-/* Remove a binding level from a list and add it to the level chain. */
+/* Remove the topmost scope from the stack and add it to the
+ free list, updating current_function_scope if necessary. */
static void
-pop_binding_level (lp)
- struct binding_level **lp;
+pop_scope (void)
{
- struct binding_level *l = *lp;
- *lp = l->level_chain;
-
- memset (l, 0, sizeof (struct binding_level));
- l->level_chain = free_binding_level;
- free_binding_level = l;
+ struct c_scope *scope = current_scope;
+
+ current_scope = scope->outer;
+ if (scope->function_body)
+ current_function_scope = scope->outer_function;
+
+ memset (scope, 0, sizeof (struct c_scope));
+ scope->outer = scope_freelist;
+ scope_freelist = scope;
}
-/* Nonzero if we are currently in the global binding level. */
+/* The Objective-C front-end often needs to determine the current scope. */
-int
-global_bindings_p ()
+void *
+get_current_scope (void)
{
- return current_binding_level == global_binding_level;
+ return current_scope;
}
+/* The following function is used only by Objective-C. It needs to live here
+ because it accesses the innards of c_scope. */
+
void
-keep_next_level ()
+objc_mark_locals_volatile (void *enclosing_blk)
{
- keep_next_level_flag = 1;
+ struct c_scope *scope;
+
+ for (scope = current_scope;
+ scope && scope != enclosing_blk;
+ scope = scope->outer)
+ {
+ tree decl;
+
+ for (decl = scope->names; decl; decl = TREE_CHAIN (decl))
+ {
+ DECL_REGISTER (decl) = 0;
+ TREE_THIS_VOLATILE (decl) = 1;
+ }
+ /* Do not climb up past the current function. */
+ if (scope->function_body)
+ break;
+ }
}
-/* Nonzero if the current level needs to have a BLOCK made. */
+/* Nonzero if we are currently in the global scope. */
int
-kept_level_p ()
+global_bindings_p (void)
{
- return ((current_binding_level->keep_if_subblocks
- && current_binding_level->blocks != 0)
- || current_binding_level->keep
- || current_binding_level->names != 0
- || (current_binding_level->tags != 0
- && !current_binding_level->tag_transparent));
+ return current_scope == global_scope;
}
-/* Identify this binding level as a level of parameters.
- DEFINITION_FLAG is 1 for a definition, 0 for a declaration.
- But it turns out there is no way to pass the right value for
- DEFINITION_FLAG, so we ignore it. */
+void
+keep_next_level (void)
+{
+ keep_next_level_flag = true;
+}
+
+/* Identify this scope as currently being filled with parameters. */
void
-declare_parm_level (definition_flag)
- int definition_flag ATTRIBUTE_UNUSED;
+declare_parm_level (void)
{
- current_binding_level->parm_flag = 1;
+ current_scope->parm_flag = true;
}
/* Nonzero if currently making parm declarations. */
int
-in_parm_level_p ()
+in_parm_level_p (void)
{
- return current_binding_level->parm_flag;
+ return current_scope->parm_flag;
}
-/* Enter a new binding level.
- If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
- not for that of tags. */
+/* Enter a new scope. The dummy parameter is for signature
+ compatibility with lang_hooks.decls.pushlevel. */
void
-pushlevel (tag_transparent)
- int tag_transparent;
+pushlevel (int dummy ATTRIBUTE_UNUSED)
{
- struct binding_level *newlevel = NULL_BINDING_LEVEL;
-
- /* If this is the top level of a function,
- just make sure that NAMED_LABELS is 0. */
-
- if (current_binding_level == global_binding_level)
+ if (next_is_function_body)
{
- named_labels = 0;
+ /* This is the transition from the parameters to the top level
+ of the function body. These are the same scope
+ (C99 6.2.1p4,6) so we do not push another scope structure.
+ next_is_function_body is set only by store_parm_decls, which
+ in turn is called when and only when we are about to
+ encounter the opening curly brace for the function body.
+
+ The outermost block of a function always gets a BLOCK node,
+ because the debugging output routines expect that each
+ function has at least one BLOCK. */
+ current_scope->parm_flag = false;
+ current_scope->function_body = true;
+ current_scope->keep = true;
+ current_scope->outer_function = current_function_scope;
+ current_function_scope = current_scope;
+
+ keep_next_level_flag = false;
+ next_is_function_body = false;
}
+ else
+ {
+ struct c_scope *scope = make_scope ();
- newlevel = make_binding_level ();
-
- /* Add this level to the front of the chain (stack) of levels that
- are active. */
-
- *newlevel = clear_binding_level;
- newlevel->tag_transparent
- = (tag_transparent
- || (current_binding_level
- ? current_binding_level->subblocks_tag_transparent
- : 0));
- newlevel->level_chain = current_binding_level;
- current_binding_level = newlevel;
- newlevel->keep = keep_next_level_flag;
- keep_next_level_flag = 0;
- newlevel->keep_if_subblocks = keep_next_if_subblocks;
- keep_next_if_subblocks = 0;
+ scope->keep = keep_next_level_flag;
+ scope->outer = current_scope;
+ current_scope = scope;
+ keep_next_level_flag = false;
+ }
}
-/* Clear the limbo values of all identifiers defined in BLOCK or a subblock. */
-
-static void
-clear_limbo_values (block)
- tree block;
-{
- tree tem;
+/* Exit a scope. Restore the state of the identifier-decl mappings
+ that were in effect when this scope was entered.
- for (tem = BLOCK_VARS (block); tem; tem = TREE_CHAIN (tem))
- if (DECL_NAME (tem) != 0)
- IDENTIFIER_LIMBO_VALUE (DECL_NAME (tem)) = 0;
-
- for (tem = BLOCK_SUBBLOCKS (block); tem; tem = TREE_CHAIN (tem))
- clear_limbo_values (tem);
-}
+ If KEEP is KEEP_YES (1), this scope had explicit declarations, so
+ create a BLOCK node to record its declarations and subblocks for
+ debugging output. If KEEP is KEEP_MAYBE, do so only if the names
+ or tags lists are nonempty.
-/* Exit a binding level.
- Pop the level off, and restore the state of the identifier-decl mappings
- that were in effect when this level was entered.
-
- If KEEP is nonzero, this level had explicit declarations, so
- and create a "block" (a BLOCK node) for the level
- to record its declarations and subblocks for symbol table output.
+ The second parameter is ignored; it is present only for
+ signature compatibility with lang_hooks.decls.poplevel.
If FUNCTIONBODY is nonzero, this level is the body of a function,
- so create a block as if KEEP were set and also clear out all
- label names.
+ even if current_scope->function_body is not set. This is used
+ by language-independent code that generates synthetic functions,
+ and cannot set current_scope->function_body.
- If REVERSE is nonzero, reverse the order of decls before putting
- them into the BLOCK. */
+ FIXME: Eliminate the need for all arguments. */
tree
-poplevel (keep, reverse, functionbody)
- int keep;
- int reverse;
- int functionbody;
+poplevel (int keep, int dummy ATTRIBUTE_UNUSED, int functionbody)
{
- tree link;
- /* The chain of decls was accumulated in reverse order.
- Put it into forward order, just for cleanliness. */
- tree decls;
- tree tags = current_binding_level->tags;
- tree subblocks = current_binding_level->blocks;
- tree block = 0;
+ struct c_scope *scope = current_scope;
+ tree block;
tree decl;
- int block_previously_created;
+ tree p;
- keep |= current_binding_level->keep;
+ /* The following line does not use |= due to a bug in HP's C compiler. */
+ scope->function_body = scope->function_body | functionbody;
- /* This warning is turned off because it causes warnings for
- declarations like `extern struct foo *x'. */
-#if 0
- /* Warn about incomplete structure types in this level. */
- for (link = tags; link; link = TREE_CHAIN (link))
- if (!COMPLETE_TYPE_P (TREE_VALUE (link)))
- {
- tree type = TREE_VALUE (link);
- tree type_name = TYPE_NAME (type);
- char *id = IDENTIFIER_POINTER (TREE_CODE (type_name) == IDENTIFIER_NODE
- ? type_name
- : DECL_NAME (type_name));
- switch (TREE_CODE (type))
- {
- case RECORD_TYPE:
- error ("`struct %s' incomplete in scope ending here", id);
- break;
- case UNION_TYPE:
- error ("`union %s' incomplete in scope ending here", id);
- break;
- case ENUMERAL_TYPE:
- error ("`enum %s' incomplete in scope ending here", id);
- break;
- }
- }
-#endif /* 0 */
+ if (keep == KEEP_MAYBE)
+ keep = (scope->names || scope->tags);
- /* Get the decls in the order they were written.
- Usually current_binding_level->names is in reverse order.
- But parameter decls were previously put in forward order. */
-
- if (reverse)
- current_binding_level->names
- = decls = nreverse (current_binding_level->names);
- else
- decls = current_binding_level->names;
-
- /* Output any nested inline functions within this block
- if they weren't already output. */
-
- for (decl = decls; decl; decl = TREE_CHAIN (decl))
- if (TREE_CODE (decl) == FUNCTION_DECL
- && ! TREE_ASM_WRITTEN (decl)
- && DECL_INITIAL (decl) != 0
- && TREE_ADDRESSABLE (decl))
- {
- /* If this decl was copied from a file-scope decl
- on account of a block-scope extern decl,
- propagate TREE_ADDRESSABLE to the file-scope decl.
-
- DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is
- true, since then the decl goes through save_for_inline_copying. */
- if (DECL_ABSTRACT_ORIGIN (decl) != 0
- && DECL_ABSTRACT_ORIGIN (decl) != decl)
- TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1;
- }
-
- /* We used to warn about unused variables in expand_end_bindings,
- i.e. while generating RTL. But in function-at-a-time mode we may
- choose to never expand a function at all (e.g. auto inlining), so
- we do this explicitly now. */
- warn_about_unused_variables (getdecls ());
-
- /* If there were any declarations or structure tags in that level,
- or if this level is a function body,
- create a BLOCK to record them for the life of this function. */
+ keep |= scope->keep;
+ keep |= scope->function_body;
+ /* If appropriate, create a BLOCK to record the decls for the life
+ of this function. */
block = 0;
- block_previously_created = (current_binding_level->this_block != 0);
- if (block_previously_created)
- block = current_binding_level->this_block;
- else if (keep || functionbody
- || (current_binding_level->keep_if_subblocks && subblocks != 0))
- block = make_node (BLOCK);
- if (block != 0)
+ if (keep)
{
- BLOCK_VARS (block) = decls;
- BLOCK_SUBBLOCKS (block) = subblocks;
+ block = make_node (BLOCK);
+ BLOCK_VARS (block) = scope->names;
+ BLOCK_SUBBLOCKS (block) = scope->blocks;
+ TREE_USED (block) = 1;
}
/* In each subblock, record that this is its superior. */
+ for (p = scope->blocks; p; p = TREE_CHAIN (p))
+ BLOCK_SUPERCONTEXT (p) = block;
+
+ /* Clear out the variable bindings in this scope.
- for (link = subblocks; link; link = TREE_CHAIN (link))
- BLOCK_SUPERCONTEXT (link) = block;
+ Propagate TREE_ADDRESSABLE from nested functions to their
+ containing functions.
- /* Clear out the meanings of the local variables of this level. */
+ Issue warnings for unused variables and labels, and errors for
+ undefined labels, if there are any. */
- for (link = decls; link; link = TREE_CHAIN (link))
+ for (p = scope->names; p; p = TREE_CHAIN (p))
{
- if (DECL_NAME (link) != 0)
+ switch (TREE_CODE (p))
{
- /* If the ident. was used or addressed via a local extern decl,
- don't forget that fact. */
- if (DECL_EXTERNAL (link))
+ case LABEL_DECL:
+ if (TREE_USED (p) && !DECL_INITIAL (p))
{
- if (TREE_USED (link))
- TREE_USED (DECL_NAME (link)) = 1;
- if (TREE_ADDRESSABLE (link))
- TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1;
+ error ("%Jlabel `%D' used but not defined", p, p);
+ DECL_INITIAL (p) = error_mark_node;
+ }
+ else if (!TREE_USED (p) && warn_unused_label)
+ {
+ if (DECL_INITIAL (p))
+ warning ("%Jlabel `%D' defined but not used", p, p);
+ else
+ warning ("%Jlabel `%D' declared but not defined", p, p);
}
- IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0;
- }
- }
-
- /* Restore all name-meanings of the outer levels
- that were shadowed by this level. */
-
- for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link))
- IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
-
- /* If the level being exited is the top level of a function,
- check over all the labels, and clear out the current
- (function local) meanings of their names. */
-
- if (functionbody)
- {
- clear_limbo_values (block);
-
- /* If this is the top level block of a function,
- the vars are the function's parameters.
- Don't leave them in the BLOCK because they are
- found in the FUNCTION_DECL instead. */
-
- BLOCK_VARS (block) = 0;
- /* Clear out the definitions of all label names,
- since their scopes end here,
- and add them to BLOCK_VARS. */
+ IDENTIFIER_LABEL_VALUE (DECL_NAME (p)) = 0;
+ break;
- for (link = named_labels; link; link = TREE_CHAIN (link))
- {
- tree label = TREE_VALUE (link);
+ case FUNCTION_DECL:
+ if (! TREE_ASM_WRITTEN (p)
+ && DECL_INITIAL (p) != 0
+ && TREE_ADDRESSABLE (p)
+ && DECL_ABSTRACT_ORIGIN (p) != 0
+ && DECL_ABSTRACT_ORIGIN (p) != p)
+ TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (p)) = 1;
+ goto normal;
+
+ case VAR_DECL:
+ /* Keep this in sync with stmt.c:warn_about_unused_variables.
+ No warnings when the global scope is popped because the
+ global scope isn't popped for the last translation unit,
+ so the warnings are done in c_write_global_declaration. */
+ if (warn_unused_variable && scope != global_scope
+ && !TREE_USED (p)
+ && !DECL_IN_SYSTEM_HEADER (p)
+ && DECL_NAME (p)
+ && !DECL_ARTIFICIAL (p))
+ warning ("%Junused variable `%D'", p, p);
+ /* fall through */
- if (DECL_INITIAL (label) == 0)
+ default:
+ normal:
+ if (DECL_NAME (p))
{
- error_with_decl (label, "label `%s' used but not defined");
- /* Avoid crashing later. */
- define_label (input_filename, lineno,
- DECL_NAME (label));
+ if (DECL_EXTERNAL (p) && scope != global_scope)
+ /* External decls stay in the symbol-value slot but are
+ inaccessible. */
+ C_DECL_INVISIBLE (p) = 1;
+ else
+ IDENTIFIER_SYMBOL_VALUE (DECL_NAME (p)) = 0;
}
- else if (warn_unused_label && !TREE_USED (label))
- warning_with_decl (label, "label `%s' defined but not used");
- IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0;
-
- /* Put the labels into the "variables" of the
- top-level block, so debugger can see them. */
- TREE_CHAIN (label) = BLOCK_VARS (block);
- BLOCK_VARS (block) = label;
+ break;
}
}
- /* Pop the current level, and free the structure for reuse. */
+ /* Clear out the parameter bindings in this scope, if any.
+ Unused-parameter warnings are handled by function.c. */
+ for (p = scope->parms; p; p = TREE_CHAIN (p))
+ if (DECL_NAME (p))
+ IDENTIFIER_SYMBOL_VALUE (DECL_NAME (p)) = 0;
+
+ /* Clear out the tag-meanings declared in this scope.
+
+ Set the TYPE_CONTEXTs for all of the tagged types belonging to
+ this scope so that they point to the appropriate construct, i.e.
+ either to the current FUNCTION_DECL node, or else to the BLOCK
+ node we just constructed.
+
+ Note that for tagged types whose scope is just the formal
+ parameter list for some function type specification, we can't
+ properly set their TYPE_CONTEXTs here, because we don't have a
+ pointer to the appropriate FUNCTION_TYPE node readily available
+ to us. For those cases, the TYPE_CONTEXTs of the relevant tagged
+ type nodes get set in `grokdeclarator' as soon as we have created
+ the FUNCTION_TYPE node which will represent the "scope" for these
+ "parameter list local" tagged types. */
+
+ decl = scope->function_body ? current_function_decl : block;
+ for (p = scope->tags; p; p = TREE_CHAIN (p))
+ {
+ if (TREE_PURPOSE (p))
+ IDENTIFIER_TAG_VALUE (TREE_PURPOSE (p)) = 0;
+ if (decl)
+ TYPE_CONTEXT (TREE_VALUE (p)) = decl;
+ }
- pop_binding_level (&current_binding_level);
+ /* Restore all name- and label-meanings from outer scopes that were
+ shadowed by this scope. */
+ for (p = scope->shadowed; p; p = TREE_CHAIN (p))
+ if (TREE_VALUE (p) && TREE_CODE (TREE_VALUE (p)) == LABEL_DECL)
+ IDENTIFIER_LABEL_VALUE (TREE_PURPOSE (p)) = TREE_VALUE (p);
+ else
+ IDENTIFIER_SYMBOL_VALUE (TREE_PURPOSE (p)) = TREE_VALUE (p);
+
+ /* Restore all tag-meanings from outer scopes that were shadowed by
+ this scope. */
+ for (p = scope->shadowed_tags; p; p = TREE_CHAIN (p))
+ IDENTIFIER_TAG_VALUE (TREE_PURPOSE (p)) = TREE_VALUE (p);
/* Dispose of the block that we just made inside some higher level. */
- if (functionbody)
+ if (scope->function_body && current_function_decl)
DECL_INITIAL (current_function_decl) = block;
- else if (block)
- {
- if (!block_previously_created)
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, block);
- }
- /* If we did not make a block for the level just exited,
- any blocks made for inner levels
- (since they cannot be recorded as subblocks in that level)
- must be carried forward so they will later become subblocks
- of something else. */
- else if (subblocks)
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, subblocks);
-
- /* Set the TYPE_CONTEXTs for all of the tagged types belonging to this
- binding contour so that they point to the appropriate construct, i.e.
- either to the current FUNCTION_DECL node, or else to the BLOCK node
- we just constructed.
-
- Note that for tagged types whose scope is just the formal parameter
- list for some function type specification, we can't properly set
- their TYPE_CONTEXTs here, because we don't have a pointer to the
- appropriate FUNCTION_TYPE node readily available to us. For those
- cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set
- in `grokdeclarator' as soon as we have created the FUNCTION_TYPE
- node which will represent the "scope" for these "parameter list local"
- tagged types. */
-
- if (functionbody)
- for (link = tags; link; link = TREE_CHAIN (link))
- TYPE_CONTEXT (TREE_VALUE (link)) = current_function_decl;
- else if (block)
- for (link = tags; link; link = TREE_CHAIN (link))
- TYPE_CONTEXT (TREE_VALUE (link)) = block;
-
- if (block)
- TREE_USED (block) = 1;
+ else if (scope->outer)
+ {
+ if (block)
+ SCOPE_LIST_APPEND (scope->outer, blocks, block);
+ /* If we did not make a block for the scope just exited, any
+ blocks made for inner scopes must be carried forward so they
+ will later become subblocks of something else. */
+ else if (scope->blocks)
+ SCOPE_LIST_CONCAT (scope->outer, blocks, scope, blocks);
+ }
+
+ /* Pop the current scope, and free the structure for reuse. */
+ pop_scope ();
return block;
}
-/* Insert BLOCK at the end of the list of subblocks of the
- current binding level. This is used when a BIND_EXPR is expanded,
- to handle the BLOCK node inside the BIND_EXPR. */
+/* Insert BLOCK at the end of the list of subblocks of the current
+ scope. This is used when a BIND_EXPR is expanded, to handle the
+ BLOCK node inside the BIND_EXPR. */
void
-insert_block (block)
- tree block;
+insert_block (tree block)
{
TREE_USED (block) = 1;
- current_binding_level->blocks
- = chainon (current_binding_level->blocks, block);
+ SCOPE_LIST_APPEND (current_scope, blocks, block);
}
-/* Set the BLOCK node for the innermost scope
- (the one we are currently in). */
+/* Set the BLOCK node for the innermost scope (the one we are
+ currently in). The RTL expansion machinery requires us to provide
+ this hook, but it is not useful in function-at-a-time mode. */
void
-set_block (block)
- tree block;
+set_block (tree block ATTRIBUTE_UNUSED)
{
- current_binding_level->this_block = block;
- current_binding_level->names = chainon (current_binding_level->names,
- BLOCK_VARS (block));
- current_binding_level->blocks = chainon (current_binding_level->blocks,
- BLOCK_SUBBLOCKS (block));
-}
-
-void
-push_label_level ()
-{
- struct binding_level *newlevel;
-
- newlevel = make_binding_level ();
-
- /* Add this level to the front of the chain (stack) of label levels. */
-
- newlevel->level_chain = label_level_chain;
- label_level_chain = newlevel;
-
- newlevel->names = named_labels;
- newlevel->shadowed = shadowed_labels;
- named_labels = 0;
- shadowed_labels = 0;
-}
-
-void
-pop_label_level ()
-{
- struct binding_level *level = label_level_chain;
- tree link, prev;
-
- /* Clear out the definitions of the declared labels in this level.
- Leave in the list any ordinary, non-declared labels. */
- for (link = named_labels, prev = 0; link;)
- {
- if (C_DECLARED_LABEL_FLAG (TREE_VALUE (link)))
- {
- if (DECL_SOURCE_LINE (TREE_VALUE (link)) == 0)
- {
- error_with_decl (TREE_VALUE (link),
- "label `%s' used but not defined");
- /* Avoid crashing later. */
- define_label (input_filename, lineno,
- DECL_NAME (TREE_VALUE (link)));
- }
- else if (warn_unused_label && !TREE_USED (TREE_VALUE (link)))
- warning_with_decl (TREE_VALUE (link),
- "label `%s' defined but not used");
- IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) = 0;
-
- /* Delete this element from the list. */
- link = TREE_CHAIN (link);
- if (prev)
- TREE_CHAIN (prev) = link;
- else
- named_labels = link;
- }
- else
- {
- prev = link;
- link = TREE_CHAIN (link);
- }
- }
-
- /* Bring back all the labels that were shadowed. */
- for (link = shadowed_labels; link; link = TREE_CHAIN (link))
- if (DECL_NAME (TREE_VALUE (link)) != 0)
- IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
- = TREE_VALUE (link);
-
- named_labels = chainon (named_labels, level->names);
- shadowed_labels = level->shadowed;
-
- /* Pop the current level, and free the structure for reuse. */
- pop_binding_level (&label_level_chain);
}
/* Push a definition or a declaration of struct, union or enum tag "name".
@@ -813,28 +720,26 @@ pop_label_level ()
In that case, the TYPE_SIZE will be zero. */
void
-pushtag (name, type)
- tree name, type;
+pushtag (tree name, tree type)
{
- struct binding_level *b;
-
- /* Find the proper binding level for this type tag. */
-
- for (b = current_binding_level; b->tag_transparent; b = b->level_chain)
- continue;
+ struct c_scope *b = current_scope;
+ /* Record the identifier as the type's name if it has none. */
if (name)
{
- /* Record the identifier as the type's name if it has none. */
-
if (TYPE_NAME (type) == 0)
TYPE_NAME (type) = name;
+
+ if (IDENTIFIER_TAG_VALUE (name))
+ b->shadowed_tags = tree_cons (name, IDENTIFIER_TAG_VALUE (name),
+ b->shadowed_tags);
+ IDENTIFIER_TAG_VALUE (name) = type;
}
b->tags = tree_cons (name, type, b->tags);
/* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the
- tagged type we just added to the current binding level. This fake
+ tagged type we just added to the current scope. This fake
NULL-named TYPE_DECL node helps dwarfout.c to know when it needs
to output a representation of a tagged type, and it also gives
us a convenient place to record the "scope start" address for the
@@ -847,599 +752,635 @@ pushtag (name, type)
TYPE_CONTEXT (type) = DECL_CONTEXT (TYPE_STUB_DECL (type));
}
-/* Handle when a new declaration NEWDECL
- has the same name as an old one OLDDECL
- in the same binding contour.
- Prints an error message if appropriate.
+/* Subroutine of compare_decls. Allow harmless mismatches in return
+ and argument types provided that the type modes match. This function
+ return a unified type given a suitable match, and 0 otherwise. */
- If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
- Otherwise, return 0.
+static tree
+match_builtin_function_types (tree newtype, tree oldtype)
+{
+ tree newrettype, oldrettype;
+ tree newargs, oldargs;
+ tree trytype, tryargs;
- When DIFFERENT_BINDING_LEVEL is true, NEWDECL is an external declaration,
- and OLDDECL is in an outer binding level and should thus not be changed. */
+ /* Accept the return type of the new declaration if same modes. */
+ oldrettype = TREE_TYPE (oldtype);
+ newrettype = TREE_TYPE (newtype);
-static int
-duplicate_decls (newdecl, olddecl, different_binding_level)
- tree newdecl, olddecl;
- int different_binding_level;
+ if (TYPE_MODE (oldrettype) != TYPE_MODE (newrettype))
+ return 0;
+
+ oldargs = TYPE_ARG_TYPES (oldtype);
+ newargs = TYPE_ARG_TYPES (newtype);
+ tryargs = newargs;
+
+ while (oldargs || newargs)
+ {
+ if (! oldargs
+ || ! newargs
+ || ! TREE_VALUE (oldargs)
+ || ! TREE_VALUE (newargs)
+ || TYPE_MODE (TREE_VALUE (oldargs))
+ != TYPE_MODE (TREE_VALUE (newargs)))
+ return 0;
+
+ oldargs = TREE_CHAIN (oldargs);
+ newargs = TREE_CHAIN (newargs);
+ }
+
+ trytype = build_function_type (newrettype, tryargs);
+ return build_type_attribute_variant (trytype, TYPE_ATTRIBUTES (oldtype));
+}
+
+/* Subroutine of diagnose_mismathed_decls. Check for function type
+ mismatch involving an empty arglist vs a nonempty one and give clearer
+ diagnostics. */
+static void
+diagnose_arglist_conflict (tree newdecl, tree olddecl,
+ tree newtype, tree oldtype)
{
- int types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
- int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
- && DECL_INITIAL (newdecl) != 0);
- tree oldtype = TREE_TYPE (olddecl);
- tree newtype = TREE_TYPE (newdecl);
- int errmsg = 0;
+ tree t;
- if (DECL_P (olddecl))
+ if (TREE_CODE (olddecl) != FUNCTION_DECL
+ || !comptypes (TREE_TYPE (oldtype), TREE_TYPE (newtype), COMPARE_STRICT)
+ || !((TYPE_ARG_TYPES (oldtype) == 0 && DECL_INITIAL (olddecl) == 0)
+ ||
+ (TYPE_ARG_TYPES (newtype) == 0 && DECL_INITIAL (newdecl) == 0)))
+ return;
+
+ t = TYPE_ARG_TYPES (oldtype);
+ if (t == 0)
+ t = TYPE_ARG_TYPES (newtype);
+ for (; t; t = TREE_CHAIN (t))
{
- if (TREE_CODE (newdecl) == FUNCTION_DECL
- && TREE_CODE (olddecl) == FUNCTION_DECL
- && (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)))
+ tree type = TREE_VALUE (t);
+
+ if (TREE_CHAIN (t) == 0
+ && TYPE_MAIN_VARIANT (type) != void_type_node)
{
- if (DECL_DECLARED_INLINE_P (newdecl)
- && DECL_UNINLINABLE (newdecl)
- && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
- /* Already warned elsewhere. */;
- else if (DECL_DECLARED_INLINE_P (olddecl)
- && DECL_UNINLINABLE (olddecl)
- && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
- /* Already warned. */;
- else if (DECL_DECLARED_INLINE_P (newdecl)
- && ! DECL_DECLARED_INLINE_P (olddecl)
- && DECL_UNINLINABLE (olddecl)
- && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
- {
- warning_with_decl (newdecl,
- "function `%s' redeclared as inline");
- warning_with_decl (olddecl,
- "previous declaration of function `%s' with attribute noinline");
- }
- else if (DECL_DECLARED_INLINE_P (olddecl)
- && DECL_UNINLINABLE (newdecl)
- && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
- {
- warning_with_decl (newdecl,
- "function `%s' redeclared with attribute noinline");
- warning_with_decl (olddecl,
- "previous declaration of function `%s' was inline");
- }
+ inform ("a parameter list with an ellipsis can't match "
+ "an empty parameter name list declaration");
+ break;
}
- DECL_ATTRIBUTES (newdecl)
- = (*targetm.merge_decl_attributes) (olddecl, newdecl);
+ if (c_type_promotes_to (type) != type)
+ {
+ inform ("an argument type that has a default promotion can't match "
+ "an empty parameter name list declaration");
+ break;
+ }
}
+}
- if (TREE_CODE (newtype) == ERROR_MARK
- || TREE_CODE (oldtype) == ERROR_MARK)
- types_match = 0;
+/* Another subroutine of diagnose_mismatched_decls. OLDDECL is an
+ old-style function definition, NEWDECL is a prototype declaration.
+ Diagnose inconsistencies in the argument list. Returns TRUE if
+ the prototype is compatible, FALSE if not. */
+static bool
+validate_proto_after_old_defn (tree newdecl, tree newtype, tree oldtype)
+{
+ tree newargs, oldargs;
+ int i;
- /* New decl is completely inconsistent with the old one =>
- tell caller to replace the old one.
- This is always an error except in the case of shadowing a builtin. */
- if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
+ /* ??? Elsewhere TYPE_MAIN_VARIANT is not used in this context. */
+#define END_OF_ARGLIST(t) (TYPE_MAIN_VARIANT (t) == void_type_node)
+
+ oldargs = TYPE_ACTUAL_ARG_TYPES (oldtype);
+ newargs = TYPE_ARG_TYPES (newtype);
+ i = 1;
+
+ for (;;)
{
- if (TREE_CODE (olddecl) == FUNCTION_DECL
- && (DECL_BUILT_IN (olddecl)
- || DECL_BUILT_IN_NONANSI (olddecl)))
+ tree oldargtype = TREE_VALUE (oldargs);
+ tree newargtype = TREE_VALUE (newargs);
+
+ if (END_OF_ARGLIST (oldargtype) && END_OF_ARGLIST (newargtype))
+ break;
+
+ /* Reaching the end of just one list means the two decls don't
+ agree on the number of arguments. */
+ if (END_OF_ARGLIST (oldargtype))
{
- /* If you declare a built-in or predefined function name as static,
- the old definition is overridden,
- but optionally warn this was a bad choice of name. */
- if (!TREE_PUBLIC (newdecl))
- {
- if (!warn_shadow)
- ;
- else if (DECL_BUILT_IN (olddecl))
- warning_with_decl (newdecl, "shadowing built-in function `%s'");
- else
- warning_with_decl (newdecl, "shadowing library function `%s'");
- }
- /* Likewise, if the built-in is not ansi, then programs can
- override it even globally without an error. */
- else if (! DECL_BUILT_IN (olddecl))
- warning_with_decl (newdecl,
- "library function `%s' declared as non-function");
-
- else if (DECL_BUILT_IN_NONANSI (olddecl))
- warning_with_decl (newdecl,
- "built-in function `%s' declared as non-function");
- else
- warning_with_decl (newdecl,
- "built-in function `%s' declared as non-function");
+ error ("%Jprototype for '%D' declares more arguments "
+ "than previous old-style definition", newdecl, newdecl);
+ return false;
}
- else
+ else if (END_OF_ARGLIST (newargtype))
{
- error_with_decl (newdecl, "`%s' redeclared as different kind of symbol");
- error_with_decl (olddecl, "previous declaration of `%s'");
+ error ("%Jprototype for '%D' declares fewer arguments "
+ "than previous old-style definition", newdecl, newdecl);
+ return false;
}
- return 0;
+ /* Type for passing arg must be consistent with that declared
+ for the arg. */
+ else if (! comptypes (oldargtype, newargtype, COMPARE_STRICT))
+ {
+ error ("%Jprototype for '%D' declares arg %d with incompatible type",
+ newdecl, newdecl, i);
+ return false;
+ }
+
+ oldargs = TREE_CHAIN (oldargs);
+ newargs = TREE_CHAIN (newargs);
+ i++;
}
- /* For real parm decl following a forward decl,
- return 1 so old decl will be reused. */
- if (types_match && TREE_CODE (newdecl) == PARM_DECL
- && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
- return 1;
+ /* If we get here, no errors were found, but do issue a warning
+ for this poor-style construct. */
+ warning ("%Jprototype for '%D' follows non-prototype definition",
+ newdecl, newdecl);
+ return true;
+#undef END_OF_ARGLIST
+}
+
+/* Subroutine of diagnose_mismatched_decls. Report the location of DECL,
+ first in a pair of mismatched declarations, using the diagnostic
+ function DIAG. */
+static void
+locate_old_decl (tree decl, void (*diag)(const char *, ...))
+{
+ if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
+ ;
+ else if (DECL_INITIAL (decl))
+ diag (N_("%Jprevious definition of '%D' was here"), decl, decl);
+ else if (C_DECL_IMPLICIT (decl))
+ diag (N_("%Jprevious implicit declaration of '%D' was here"), decl, decl);
+ else
+ diag (N_("%Jprevious declaration of '%D' was here"), decl, decl);
+}
- /* The new declaration is the same kind of object as the old one.
- The declarations may partially match. Print warnings if they don't
- match enough. Ultimately, copy most of the information from the new
- decl to the old one, and keep using the old one. */
+/* Subroutine of duplicate_decls. Compare NEWDECL to OLDDECL.
+ Returns true if the caller should proceed to merge the two, false
+ if OLDDECL should simply be discarded. As a side effect, issues
+ all necessary diagnostics for invalid or poor-style combinations.
+ If it returns true, writes the types of NEWDECL and OLDDECL to
+ *NEWTYPEP and *OLDTYPEP - these may have been adjusted from
+ TREE_TYPE (NEWDECL, OLDDECL) respectively. */
- if (TREE_CODE (olddecl) == FUNCTION_DECL && DECL_BUILT_IN (olddecl))
+static bool
+diagnose_mismatched_decls (tree newdecl, tree olddecl,
+ tree *newtypep, tree *oldtypep)
+{
+ tree newtype, oldtype;
+ bool pedwarned = false;
+ bool warned = false;
+
+ /* If we have error_mark_node for either decl or type, just discard
+ the previous decl - we're in an error cascade already. */
+ if (olddecl == error_mark_node || newdecl == error_mark_node)
+ return false;
+ *oldtypep = oldtype = TREE_TYPE (olddecl);
+ *newtypep = newtype = TREE_TYPE (newdecl);
+ if (oldtype == error_mark_node || newtype == error_mark_node)
+ return false;
+
+ /* Two different categories of symbol altogether. This is an error
+ unless OLDDECL is a builtin. OLDDECL will be discarded in any case. */
+ if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
{
- /* A function declaration for a built-in function. */
- if (!TREE_PUBLIC (newdecl))
+ if (TREE_CODE (olddecl) != FUNCTION_DECL
+ || !DECL_BUILT_IN (olddecl) || !C_DECL_INVISIBLE (olddecl))
{
- /* If you declare a built-in function name as static, the
- built-in definition is overridden,
- but optionally warn this was a bad choice of name. */
- if (warn_shadow)
- warning_with_decl (newdecl, "shadowing built-in function `%s'");
- /* Discard the old built-in function. */
- return 0;
+ error ("%J'%D' redeclared as different kind of symbol",
+ newdecl, newdecl);
+ locate_old_decl (olddecl, error);
}
- else if (!types_match)
- {
- /* Accept the return type of the new declaration if same modes. */
- tree oldreturntype = TREE_TYPE (oldtype);
- tree newreturntype = TREE_TYPE (newtype);
+ else if (TREE_PUBLIC (newdecl))
+ warning ("%Jbuilt-in function '%D' declared as non-function",
+ newdecl, newdecl);
+ else if (warn_shadow)
+ warning ("%Jshadowing built-in function '%D'",
+ newdecl, newdecl);
+ return false;
+ }
- if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype))
- {
- /* Function types may be shared, so we can't just modify
- the return type of olddecl's function type. */
- tree trytype
- = build_function_type (newreturntype,
- TYPE_ARG_TYPES (oldtype));
- trytype = build_type_attribute_variant (trytype,
- TYPE_ATTRIBUTES (oldtype));
-
- types_match = comptypes (newtype, trytype);
- if (types_match)
- oldtype = trytype;
- }
- /* Accept harmless mismatch in first argument type also.
+ if (!comptypes (oldtype, newtype, COMPARE_STRICT))
+ {
+ if (TREE_CODE (olddecl) == FUNCTION_DECL
+ && DECL_BUILT_IN (olddecl) && C_DECL_INVISIBLE (olddecl))
+ {
+ /* Accept harmless mismatch in function types.
This is for the ffs and fprintf builtins. */
- if (TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0
- && TYPE_ARG_TYPES (oldtype) != 0
- && TREE_VALUE (TYPE_ARG_TYPES (newtype)) != 0
- && TREE_VALUE (TYPE_ARG_TYPES (oldtype)) != 0
- && (TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (newtype)))
- == TYPE_MODE (TREE_VALUE (TYPE_ARG_TYPES (oldtype)))))
+ tree trytype = match_builtin_function_types (newtype, oldtype);
+
+ if (trytype && comptypes (newtype, trytype, COMPARE_STRICT))
+ *oldtypep = oldtype = trytype;
+ else
{
- /* Function types may be shared, so we can't just modify
- the return type of olddecl's function type. */
- tree trytype
- = build_function_type (TREE_TYPE (oldtype),
- tree_cons (NULL_TREE,
- TREE_VALUE (TYPE_ARG_TYPES (newtype)),
- TREE_CHAIN (TYPE_ARG_TYPES (oldtype))));
- trytype = build_type_attribute_variant (trytype,
- TYPE_ATTRIBUTES (oldtype));
-
- types_match = comptypes (newtype, trytype);
- if (types_match)
- oldtype = trytype;
+ /* If types don't match for a built-in, throw away the
+ built-in. No point in calling locate_old_decl here, it
+ won't print anything. */
+ warning ("%Jconflicting types for built-in function '%D'",
+ newdecl, newdecl);
+ return false;
}
- if (! different_binding_level)
- TREE_TYPE (olddecl) = oldtype;
}
- else if (TYPE_ARG_TYPES (oldtype) == NULL
- && TYPE_ARG_TYPES (newtype) != NULL)
+ else if (TREE_CODE (olddecl) == FUNCTION_DECL
+ && DECL_SOURCE_LINE (olddecl) == 0)
{
- /* For bcmp, bzero, fputs the builtin type has arguments not
- specified. Use the ones from the prototype so that type checking
- is done for them. */
- tree trytype
- = build_function_type (TREE_TYPE (oldtype),
- TYPE_ARG_TYPES (newtype));
- trytype = build_type_attribute_variant (trytype,
- TYPE_ATTRIBUTES (oldtype));
-
- oldtype = trytype;
- if (! different_binding_level)
- TREE_TYPE (olddecl) = oldtype;
+ /* A conflicting function declaration for a predeclared
+ function that isn't actually built in. Objective C uses
+ these. The new declaration silently overrides everything
+ but the volatility (i.e. noreturn) indication. See also
+ below. FIXME: Make Objective C use normal builtins. */
+ TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
+ return false;
}
- if (!types_match)
+ /* Permit void foo (...) to match int foo (...) if the latter is
+ the definition and implicit int was used. See
+ c-torture/compile/920625-2.c. */
+ else if (TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl)
+ && TYPE_MAIN_VARIANT (TREE_TYPE (oldtype)) == void_type_node
+ && TYPE_MAIN_VARIANT (TREE_TYPE (newtype)) == integer_type_node
+ && C_FUNCTION_IMPLICIT_INT (newdecl))
{
- /* If types don't match for a built-in, throw away the built-in. */
- warning_with_decl (newdecl, "conflicting types for built-in function `%s'");
- return 0;
+ pedwarn ("%Jconflicting types for '%D'", newdecl, newdecl);
+ /* Make sure we keep void as the return type. */
+ TREE_TYPE (newdecl) = *newtypep = newtype = oldtype;
+ C_FUNCTION_IMPLICIT_INT (newdecl) = 0;
+ pedwarned = true;
+ }
+ else
+ {
+ error ("%Jconflicting types for '%D'", newdecl, newdecl);
+ diagnose_arglist_conflict (newdecl, olddecl, newtype, oldtype);
+ locate_old_decl (olddecl, error);
+ return false;
}
}
- else if (TREE_CODE (olddecl) == FUNCTION_DECL
- && DECL_SOURCE_LINE (olddecl) == 0)
+
+ /* Redeclaration of a type is a constraint violation (6.7.2.3p1),
+ but silently ignore the redeclaration if either is in a system
+ header. (Conflicting redeclarations were handled above.) */
+ if (TREE_CODE (newdecl) == TYPE_DECL)
+ {
+ if (DECL_IN_SYSTEM_HEADER (newdecl) || DECL_IN_SYSTEM_HEADER (olddecl))
+ return true; /* allow OLDDECL to continue in use */
+
+ error ("%Jredefinition of typedef '%D'", newdecl, newdecl);
+ locate_old_decl (olddecl, error);
+ return false;
+ }
+
+ /* Function declarations can either be 'static' or 'extern' (no
+ qualifier is equivalent to 'extern' - C99 6.2.2p5) and therefore
+ can never conflict with each other on account of linkage (6.2.2p4).
+ Multiple definitions are not allowed (6.9p3,5) but GCC permits
+ two definitions if one is 'extern inline' and one is not. The non-
+ extern-inline definition supersedes the extern-inline definition. */
+ else if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
- /* A function declaration for a predeclared function
- that isn't actually built in. */
- if (!TREE_PUBLIC (newdecl))
+ /* If you declare a built-in function name as static, or
+ define the built-in with an old-style definition (so we
+ can't validate the argument list) the built-in definition is
+ overridden, but optionally warn this was a bad choice of name. */
+ if (DECL_BUILT_IN (olddecl)
+ && C_DECL_INVISIBLE (olddecl)
+ && (!TREE_PUBLIC (newdecl)
+ || (DECL_INITIAL (newdecl)
+ && !TYPE_ARG_TYPES (TREE_TYPE (newdecl)))))
{
- /* If you declare it as static, the
- default definition is overridden. */
- return 0;
+ if (warn_shadow)
+ warning ("%Jshadowing built-in function '%D'", newdecl, newdecl);
+ /* Discard the old built-in function. */
+ return false;
}
- else if (!types_match)
+
+ if (DECL_INITIAL (newdecl))
{
- /* If the types don't match, preserve volatility indication.
- Later on, we will discard everything else about the
- default declaration. */
- TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
+ if (DECL_INITIAL (olddecl)
+ && !(DECL_DECLARED_INLINE_P (olddecl)
+ && DECL_EXTERNAL (olddecl)
+ && !(DECL_DECLARED_INLINE_P (newdecl)
+ && DECL_EXTERNAL (newdecl))))
+ {
+ error ("%Jredefinition of '%D'", newdecl, newdecl);
+ locate_old_decl (olddecl, error);
+ return false;
+ }
}
- }
- /* Permit char *foo () to match void *foo (...) if not pedantic,
- if one of them came from a system header file. */
- else if (!types_match
- && TREE_CODE (olddecl) == FUNCTION_DECL
- && TREE_CODE (newdecl) == FUNCTION_DECL
- && TREE_CODE (TREE_TYPE (oldtype)) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (newtype)) == POINTER_TYPE
- && (DECL_IN_SYSTEM_HEADER (olddecl)
- || DECL_IN_SYSTEM_HEADER (newdecl))
- && ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (newtype))) == void_type_node
- && TYPE_ARG_TYPES (oldtype) == 0
- && self_promoting_args_p (TYPE_ARG_TYPES (newtype))
- && TREE_TYPE (TREE_TYPE (oldtype)) == char_type_node)
- ||
- (TREE_TYPE (TREE_TYPE (newtype)) == char_type_node
- && TYPE_ARG_TYPES (newtype) == 0
- && self_promoting_args_p (TYPE_ARG_TYPES (oldtype))
- && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node)))
- {
- if (pedantic)
- pedwarn_with_decl (newdecl, "conflicting types for `%s'");
- /* Make sure we keep void * as ret type, not char *. */
- if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (oldtype))) == void_type_node)
- TREE_TYPE (newdecl) = newtype = oldtype;
-
- /* Set DECL_IN_SYSTEM_HEADER, so that if we see another declaration
- we will come back here again. */
- DECL_IN_SYSTEM_HEADER (newdecl) = 1;
- }
- else if (!types_match
- /* Permit char *foo (int, ...); followed by char *foo ();
- if not pedantic. */
- && ! (TREE_CODE (olddecl) == FUNCTION_DECL
- && ! pedantic
- /* Return types must still match. */
- && comptypes (TREE_TYPE (oldtype),
- TREE_TYPE (newtype))
- && TYPE_ARG_TYPES (newtype) == 0))
- {
- error_with_decl (newdecl, "conflicting types for `%s'");
- /* Check for function type mismatch
- involving an empty arglist vs a nonempty one. */
- if (TREE_CODE (olddecl) == FUNCTION_DECL
- && comptypes (TREE_TYPE (oldtype),
- TREE_TYPE (newtype))
- && ((TYPE_ARG_TYPES (oldtype) == 0
- && DECL_INITIAL (olddecl) == 0)
- ||
- (TYPE_ARG_TYPES (newtype) == 0
- && DECL_INITIAL (newdecl) == 0)))
+ /* If we have a prototype after an old-style function definition,
+ the argument types must be checked specially. */
+ else if (DECL_INITIAL (olddecl)
+ && !TYPE_ARG_TYPES (oldtype) && TYPE_ARG_TYPES (newtype)
+ && TYPE_ACTUAL_ARG_TYPES (oldtype)
+ && !validate_proto_after_old_defn (newdecl, newtype, oldtype))
+ {
+ locate_old_decl (olddecl, error);
+ return false;
+ }
+ /* Mismatched non-static and static is considered poor style.
+ We only diagnose static then non-static if -Wtraditional,
+ because it is the most convenient way to get some effects
+ (see e.g. what unwind-dw2-fde-glibc.c does to the definition
+ of _Unwind_Find_FDE in unwind-dw2-fde.c). Revisit? */
+ if (TREE_PUBLIC (olddecl) && !TREE_PUBLIC (newdecl))
{
- /* Classify the problem further. */
- tree t = TYPE_ARG_TYPES (oldtype);
- if (t == 0)
- t = TYPE_ARG_TYPES (newtype);
- for (; t; t = TREE_CHAIN (t))
+ /* A static function declaration for a predeclared function
+ that isn't actually built in, silently overrides the
+ default. Objective C uses these. See also above.
+ FIXME: Make Objective C use normal builtins. */
+ if (TREE_CODE (olddecl) == FUNCTION_DECL
+ && DECL_SOURCE_LINE (olddecl) == 0)
+ return false;
+ else
{
- tree type = TREE_VALUE (t);
-
- if (TREE_CHAIN (t) == 0
- && TYPE_MAIN_VARIANT (type) != void_type_node)
- {
- error ("a parameter list with an ellipsis can't match an empty parameter name list declaration");
- break;
- }
-
- if (c_type_promotes_to (type) != type)
- {
- error ("an argument type that has a default promotion can't match an empty parameter name list declaration");
- break;
- }
+ warning ("%Jstatic declaration of '%D' follows "
+ "non-static declaration", newdecl, newdecl);
+ warned = true;
}
}
- error_with_decl (olddecl, "previous declaration of `%s'");
-
- /* This is safer because the initializer might contain references
- to variables that were declared between olddecl and newdecl. This
- will make the initializer invalid for olddecl in case it gets
- assigned to olddecl below. */
- if (TREE_CODE (newdecl) == VAR_DECL)
- DECL_INITIAL (newdecl) = 0;
- }
- /* TLS cannot follow non-TLS declaration. */
- else if (TREE_CODE (olddecl) == VAR_DECL && TREE_CODE (newdecl) == VAR_DECL
- && !DECL_THREAD_LOCAL (olddecl) && DECL_THREAD_LOCAL (newdecl))
- {
- error_with_decl (newdecl, "thread-local declaration of `%s' follows non thread-local declaration");
- error_with_decl (olddecl, "previous declaration of `%s'");
- }
- /* non-TLS declaration cannot follow TLS declaration. */
- else if (TREE_CODE (olddecl) == VAR_DECL && TREE_CODE (newdecl) == VAR_DECL
- && DECL_THREAD_LOCAL (olddecl) && !DECL_THREAD_LOCAL (newdecl))
- {
- error_with_decl (newdecl, "non thread-local declaration of `%s' follows thread-local declaration");
- error_with_decl (olddecl, "previous declaration of `%s'");
+ else if (TREE_PUBLIC (newdecl) && !TREE_PUBLIC (olddecl)
+ && warn_traditional)
+ {
+ warning ("%Jnon-static declaration of '%D' follows "
+ "static declaration", newdecl, newdecl);
+ warned = true;
+ }
}
- else
+ else if (TREE_CODE (newdecl) == VAR_DECL)
{
- errmsg = redeclaration_error_message (newdecl, olddecl);
- if (errmsg)
+ /* Only variables can be thread-local, and all declarations must
+ agree on this property. */
+ if (DECL_THREAD_LOCAL (newdecl) != DECL_THREAD_LOCAL (olddecl))
{
- switch (errmsg)
- {
- case 1:
- error_with_decl (newdecl, "redefinition of `%s'");
- break;
- case 2:
- error_with_decl (newdecl, "redeclaration of `%s'");
- break;
- case 3:
- error_with_decl (newdecl, "conflicting declarations of `%s'");
- break;
- default:
- abort ();
- }
+ if (DECL_THREAD_LOCAL (newdecl))
+ error ("%Jthread-local declaration of '%D' follows "
+ "non-thread-local declaration", newdecl, newdecl);
+ else
+ error ("%Jnon-thread-local declaration of '%D' follows "
+ "thread-local declaration", newdecl, newdecl);
- error_with_decl (olddecl,
- ((DECL_INITIAL (olddecl)
- && current_binding_level == global_binding_level)
- ? "`%s' previously defined here"
- : "`%s' previously declared here"));
- return 0;
+ locate_old_decl (olddecl, error);
+ return false;
}
- else if (TREE_CODE (newdecl) == TYPE_DECL
- && (DECL_IN_SYSTEM_HEADER (olddecl)
- || DECL_IN_SYSTEM_HEADER (newdecl)))
+
+ /* Multiple initialized definitions are not allowed (6.9p3,5). */
+ if (DECL_INITIAL (newdecl) && DECL_INITIAL (olddecl))
{
- warning_with_decl (newdecl, "redefinition of `%s'");
- warning_with_decl
- (olddecl,
- ((DECL_INITIAL (olddecl)
- && current_binding_level == global_binding_level)
- ? "`%s' previously defined here"
- : "`%s' previously declared here"));
+ error ("%Jredefinition of '%D'", newdecl, newdecl);
+ locate_old_decl (olddecl, error);
+ return false;
}
- else if (TREE_CODE (olddecl) == FUNCTION_DECL
- && DECL_INITIAL (olddecl) != 0
- && TYPE_ARG_TYPES (oldtype) == 0
- && TYPE_ARG_TYPES (newtype) != 0
- && TYPE_ACTUAL_ARG_TYPES (oldtype) != 0)
+
+ /* Objects declared at file scope: if at least one is 'extern',
+ it's fine (6.2.2p4); otherwise the linkage must agree (6.2.2p7). */
+ if (DECL_FILE_SCOPE_P (newdecl))
{
- tree type, parm;
- int nargs;
- /* Prototype decl follows defn w/o prototype. */
-
- for (parm = TYPE_ACTUAL_ARG_TYPES (oldtype),
- type = TYPE_ARG_TYPES (newtype),
- nargs = 1;
- ;
- parm = TREE_CHAIN (parm), type = TREE_CHAIN (type), nargs++)
+ if (!DECL_EXTERNAL (newdecl)
+ && !DECL_EXTERNAL (olddecl)
+ && TREE_PUBLIC (newdecl) != TREE_PUBLIC (olddecl))
{
- if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
- && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
- {
- warning_with_decl (newdecl, "prototype for `%s' follows");
- warning_with_decl (olddecl, "non-prototype definition here");
- break;
- }
- if (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == void_type_node
- || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
- {
- error_with_decl (newdecl,
- "prototype for `%s' follows and number of arguments doesn't match");
- error_with_decl (olddecl, "non-prototype definition here");
- errmsg = 1;
- break;
- }
- /* Type for passing arg must be consistent
- with that declared for the arg. */
- if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type)))
- {
- error_with_decl (newdecl,
- "prototype for `%s' follows and argument %d doesn't match",
- nargs);
- error_with_decl (olddecl, "non-prototype definition here");
- errmsg = 1;
- break;
- }
+ if (TREE_PUBLIC (newdecl))
+ error ("%Jnon-static declaration of '%D' follows "
+ "static declaration", newdecl, newdecl);
+ else
+ error ("%Jstatic declaration of '%D' follows "
+ "non-static declaration", newdecl, newdecl);
+
+ locate_old_decl (olddecl, error);
+ return false;
}
}
- /* Warn about mismatches in various flags. */
- else
+ /* Two objects with the same name declared at the same block
+ scope must both be external references (6.7p3). */
+ else if (DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl)
+ && (!DECL_EXTERNAL (newdecl) || !DECL_EXTERNAL (olddecl)))
{
- /* Warn if function is now inline
- but was previously declared not inline and has been called. */
- if (TREE_CODE (olddecl) == FUNCTION_DECL
- && ! DECL_DECLARED_INLINE_P (olddecl)
- && DECL_DECLARED_INLINE_P (newdecl)
- && TREE_USED (olddecl))
- warning_with_decl (newdecl,
- "`%s' declared inline after being called");
- if (TREE_CODE (olddecl) == FUNCTION_DECL
- && ! DECL_DECLARED_INLINE_P (olddecl)
- && DECL_DECLARED_INLINE_P (newdecl)
- && DECL_INITIAL (olddecl) != 0)
- warning_with_decl (newdecl,
- "`%s' declared inline after its definition");
-
- /* If pedantic, warn when static declaration follows a non-static
- declaration. Otherwise, do so only for functions. */
- if ((pedantic || TREE_CODE (olddecl) == FUNCTION_DECL)
- && TREE_PUBLIC (olddecl)
- && !TREE_PUBLIC (newdecl))
- warning_with_decl (newdecl, "static declaration for `%s' follows non-static");
-
- /* If warn_traditional, warn when a non-static function
- declaration follows a static one. */
- if (warn_traditional && !in_system_header
- && TREE_CODE (olddecl) == FUNCTION_DECL
- && !TREE_PUBLIC (olddecl)
- && TREE_PUBLIC (newdecl))
- warning_with_decl (newdecl, "non-static declaration for `%s' follows static");
-
- /* Warn when const declaration follows a non-const
- declaration, but not for functions. */
- if (TREE_CODE (olddecl) != FUNCTION_DECL
- && !TREE_READONLY (olddecl)
- && TREE_READONLY (newdecl))
- warning_with_decl (newdecl, "const declaration for `%s' follows non-const");
- /* These bits are logically part of the type, for variables.
- But not for functions
- (where qualifiers are not valid ANSI anyway). */
- else if (pedantic && TREE_CODE (olddecl) != FUNCTION_DECL
- && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)
- || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl)))
- pedwarn_with_decl (newdecl, "type qualifiers for `%s' conflict with previous decl");
+ if (DECL_EXTERNAL (newdecl))
+ error ("%Jextern declaration of '%D' follows "
+ "declaration with no linkage", newdecl, newdecl);
+ else if (DECL_EXTERNAL (olddecl))
+ error ("%Jdeclaration of '%D' with no linkage follows "
+ "extern declaration", newdecl, newdecl);
+ else
+ error ("%Jredeclaration of '%D' with no linkage",
+ newdecl, newdecl);
+
+ locate_old_decl (olddecl, error);
+ return false;
}
}
- /* Optionally warn about more than one declaration for the same name. */
- if (errmsg == 0 && warn_redundant_decls && DECL_SOURCE_LINE (olddecl) != 0
- /* Don't warn about a function declaration
- followed by a definition. */
- && !(TREE_CODE (newdecl) == FUNCTION_DECL && DECL_INITIAL (newdecl) != 0
- && DECL_INITIAL (olddecl) == 0)
- /* Don't warn about extern decl followed by (tentative) definition. */
- && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)))
+ /* warnings */
+ /* All decls must agree on a non-default visibility. */
+ if (DECL_VISIBILITY (newdecl) != VISIBILITY_DEFAULT
+ && DECL_VISIBILITY (olddecl) != VISIBILITY_DEFAULT
+ && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
{
- warning_with_decl (newdecl, "redundant redeclaration of `%s' in same scope");
- warning_with_decl (olddecl, "previous declaration of `%s'");
+ warning ("%Jredeclaration of '%D' with different visibility "
+ "(old visibility preserved)", newdecl, newdecl);
+ warned = true;
}
- /* Copy all the DECL_... slots specified in the new decl
- except for any that we copy here from the old type.
-
- Past this point, we don't change OLDTYPE and NEWTYPE
- even if we change the types of NEWDECL and OLDDECL. */
-
- if (types_match)
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
- /* When copying info to olddecl, we store into write_olddecl
- instead. This allows us to avoid modifying olddecl when
- different_binding_level is true. */
- tree write_olddecl = different_binding_level ? newdecl : olddecl;
+ /* Diagnose inline __attribute__ ((noinline)) which is silly. */
+ if (DECL_DECLARED_INLINE_P (newdecl)
+ && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
+ {
+ warning ("%Jinline declaration of '%D' follows "
+ "declaration with attribute noinline", newdecl, newdecl);
+ warned = true;
+ }
+ else if (DECL_DECLARED_INLINE_P (olddecl)
+ && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
+ {
+ warning ("%Jdeclaration of '%D' with attribute noinline follows "
+ "inline declaration ", newdecl, newdecl);
+ warned = true;
+ }
- /* Merge the data types specified in the two decls. */
- if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl))
+ /* Inline declaration after use or definition.
+ ??? Should we still warn about this now we have unit-at-a-time
+ mode and can get it right? */
+ if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl))
{
- if (different_binding_level)
+ if (TREE_USED (olddecl))
{
- if (TYPE_ARG_TYPES (oldtype) != 0
- && TYPE_ARG_TYPES (newtype) == 0)
- TREE_TYPE (newdecl) = common_type (newtype, oldtype);
- else
- TREE_TYPE (newdecl)
- = build_type_attribute_variant
- (newtype,
- merge_attributes (TYPE_ATTRIBUTES (newtype),
- TYPE_ATTRIBUTES (oldtype)));
+ warning ("%J'%D' declared inline after being called",
+ olddecl, olddecl);
+ warned = true;
+ }
+ else if (DECL_INITIAL (olddecl))
+ {
+ warning ("%J'%D' declared inline after its definition",
+ olddecl, olddecl);
+ warned = true;
}
- else
- TREE_TYPE (newdecl)
- = TREE_TYPE (olddecl)
- = common_type (newtype, oldtype);
+ }
+ }
+ else /* PARM_DECL, VAR_DECL */
+ {
+ /* Redeclaration of a PARM_DECL is invalid unless this is the
+ real position of a forward-declared parameter (GCC extension). */
+ if (TREE_CODE (newdecl) == PARM_DECL
+ && (!TREE_ASM_WRITTEN (olddecl) || TREE_ASM_WRITTEN (newdecl)))
+ {
+ error ("%Jredefinition of parameter '%D'", newdecl, newdecl);
+ locate_old_decl (olddecl, error);
+ return false;
}
- /* Lay the type out, unless already done. */
- if (oldtype != TREE_TYPE (newdecl))
+ /* These bits are only type qualifiers when applied to objects. */
+ if (TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl))
{
- if (TREE_TYPE (newdecl) != error_mark_node)
- layout_type (TREE_TYPE (newdecl));
- if (TREE_CODE (newdecl) != FUNCTION_DECL
- && TREE_CODE (newdecl) != TYPE_DECL
- && TREE_CODE (newdecl) != CONST_DECL)
- layout_decl (newdecl, 0);
+ if (TREE_THIS_VOLATILE (newdecl))
+ pedwarn ("%Jvolatile declaration of '%D' follows "
+ "non-volatile declaration", newdecl, newdecl);
+ else
+ pedwarn ("%Jnon-volatile declaration of '%D' follows "
+ "volatile declaration", newdecl, newdecl);
+ pedwarned = true;
}
- else
+ if (TREE_READONLY (newdecl) != TREE_READONLY (olddecl))
{
- /* Since the type is OLDDECL's, make OLDDECL's size go with. */
- DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
- DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
- DECL_MODE (newdecl) = DECL_MODE (olddecl);
- if (TREE_CODE (olddecl) != FUNCTION_DECL)
- if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
- {
- DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
- DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl);
- }
+ if (TREE_READONLY (newdecl))
+ pedwarn ("%Jconst declaration of '%D' follows "
+ "non-const declaration", newdecl, newdecl);
+ else
+ pedwarn ("%Jnon-const declaration of '%D' follows "
+ "const declaration", newdecl, newdecl);
+ pedwarned = true;
}
+ }
- /* Keep the old rtl since we can safely use it. */
- COPY_DECL_RTL (olddecl, newdecl);
+ /* Optional warning for completely redundant decls. */
+ if (!warned && !pedwarned
+ && warn_redundant_decls
+ /* Don't warn about a function declaration followed by a
+ definition. */
+ && !(TREE_CODE (newdecl) == FUNCTION_DECL
+ && DECL_INITIAL (newdecl) && !DECL_INITIAL (olddecl))
+ /* Don't warn about redundant redeclarations of builtins. */
+ && !(TREE_CODE (newdecl) == FUNCTION_DECL
+ && !DECL_BUILT_IN (newdecl)
+ && DECL_BUILT_IN (olddecl)
+ && C_DECL_INVISIBLE (olddecl))
+ /* Don't warn about an extern followed by a definition. */
+ && !(DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl))
+ /* Don't warn about forward parameter decls. */
+ && !(TREE_CODE (newdecl) == PARM_DECL
+ && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl)))
+ {
+ warning ("%Jredundant redeclaration of '%D'", newdecl, newdecl);
+ warned = true;
+ }
- /* Merge the type qualifiers. */
- if (TREE_READONLY (newdecl))
- TREE_READONLY (write_olddecl) = 1;
+ /* Report location of previous decl/defn in a consistent manner. */
+ if (warned || pedwarned)
+ locate_old_decl (olddecl, pedwarned ? pedwarn : warning);
- if (TREE_THIS_VOLATILE (newdecl))
- {
- TREE_THIS_VOLATILE (write_olddecl) = 1;
- if (TREE_CODE (newdecl) == VAR_DECL
- /* If an automatic variable is re-declared in the same
- function scope, but the old declaration was not
- volatile, make_var_volatile() would crash because the
- variable would have been assigned to a pseudo, not a
- MEM. Since this duplicate declaration is invalid
- anyway, we just skip the call. */
- && errmsg == 0)
- make_var_volatile (newdecl);
- }
+ return true;
+}
- /* Keep source location of definition rather than declaration. */
- /* When called with different_binding_level set, keep the old
- information so that meaningful diagnostics can be given. */
- if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0
- && ! different_binding_level)
- {
- DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
- DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
- }
+/* Subroutine of duplicate_decls. NEWDECL has been found to be
+ consistent with OLDDECL, but carries new information. Merge the
+ new information into OLDDECL. This function issues no
+ diagnostics. */
- /* Merge the unused-warning information. */
- if (DECL_IN_SYSTEM_HEADER (olddecl))
- DECL_IN_SYSTEM_HEADER (newdecl) = 1;
- else if (DECL_IN_SYSTEM_HEADER (newdecl))
- DECL_IN_SYSTEM_HEADER (write_olddecl) = 1;
-
- /* Merge the initialization information. */
- /* When called with different_binding_level set, don't copy over
- DECL_INITIAL, so that we don't accidentally change function
- declarations into function definitions. */
- if (DECL_INITIAL (newdecl) == 0 && ! different_binding_level)
- DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
-
- /* Merge the section attribute.
- We want to issue an error if the sections conflict but that must be
- done later in decl_attributes since we are called before attributes
- are assigned. */
- if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
- DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
-
- /* Copy the assembler name.
- Currently, it can only be defined in the prototype. */
- COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
-
- if (TREE_CODE (newdecl) == FUNCTION_DECL)
- {
- DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
- DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
- DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
- DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
- |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
- }
+static void
+merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
+{
+ int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
+ && DECL_INITIAL (newdecl) != 0);
+
+ /* For real parm decl following a forward decl, return 1 so old decl
+ will be reused. Only allow this to happen once. */
+ if (TREE_CODE (newdecl) == PARM_DECL
+ && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl))
+ {
+ TREE_ASM_WRITTEN (olddecl) = 0;
+ return;
+ }
+
+ DECL_ATTRIBUTES (newdecl)
+ = (*targetm.merge_decl_attributes) (olddecl, newdecl);
+
+ /* Merge the data types specified in the two decls. */
+ TREE_TYPE (newdecl)
+ = TREE_TYPE (olddecl)
+ = common_type (newtype, oldtype);
+
+ /* Lay the type out, unless already done. */
+ if (oldtype != TREE_TYPE (newdecl))
+ {
+ if (TREE_TYPE (newdecl) != error_mark_node)
+ layout_type (TREE_TYPE (newdecl));
+ if (TREE_CODE (newdecl) != FUNCTION_DECL
+ && TREE_CODE (newdecl) != TYPE_DECL
+ && TREE_CODE (newdecl) != CONST_DECL)
+ layout_decl (newdecl, 0);
+ }
+ else
+ {
+ /* Since the type is OLDDECL's, make OLDDECL's size go with. */
+ DECL_SIZE (newdecl) = DECL_SIZE (olddecl);
+ DECL_SIZE_UNIT (newdecl) = DECL_SIZE_UNIT (olddecl);
+ DECL_MODE (newdecl) = DECL_MODE (olddecl);
+ if (TREE_CODE (olddecl) != FUNCTION_DECL)
+ if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
+ {
+ DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl);
+ DECL_USER_ALIGN (newdecl) |= DECL_ALIGN (olddecl);
+ }
}
- /* If cannot merge, then use the new type and qualifiers,
- and don't preserve the old rtl. */
- else if (! different_binding_level)
+
+ /* Keep the old rtl since we can safely use it. */
+ COPY_DECL_RTL (olddecl, newdecl);
+
+ /* Merge the type qualifiers. */
+ if (TREE_READONLY (newdecl))
+ TREE_READONLY (olddecl) = 1;
+
+ if (TREE_THIS_VOLATILE (newdecl))
+ {
+ TREE_THIS_VOLATILE (olddecl) = 1;
+ if (TREE_CODE (newdecl) == VAR_DECL)
+ make_var_volatile (newdecl);
+ }
+
+ /* Keep source location of definition rather than declaration. */
+ if (DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
+ DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
+
+ /* Merge the unused-warning information. */
+ if (DECL_IN_SYSTEM_HEADER (olddecl))
+ DECL_IN_SYSTEM_HEADER (newdecl) = 1;
+ else if (DECL_IN_SYSTEM_HEADER (newdecl))
+ DECL_IN_SYSTEM_HEADER (olddecl) = 1;
+
+ /* Merge the initialization information. */
+ if (DECL_INITIAL (newdecl) == 0)
+ DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
+
+ /* Merge the section attribute.
+ We want to issue an error if the sections conflict but that must be
+ done later in decl_attributes since we are called before attributes
+ are assigned. */
+ if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
+ DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
+
+ /* Copy the assembler name.
+ Currently, it can only be defined in the prototype. */
+ COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
+
+ /* If either declaration has a nondefault visibility, use it. */
+ if (DECL_VISIBILITY (olddecl) != VISIBILITY_DEFAULT)
+ DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
+
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
- TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
- TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
- TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
- TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
+ DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
+ DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
+ DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
+ DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
+ |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
+ TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
+ TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
+ DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
+ DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
}
/* Merge the storage class information. */
@@ -1451,8 +1392,6 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl);
/* This is since we don't automatically
copy the attributes of NEWDECL into OLDDECL. */
- /* No need to worry about different_binding_level here because
- then TREE_PUBLIC (newdecl) was true. */
TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
/* If this clears `static', clear it in the identifier too. */
if (! TREE_PUBLIC (olddecl))
@@ -1460,18 +1399,16 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
}
if (DECL_EXTERNAL (newdecl))
{
- if (! different_binding_level)
- {
- /* Don't mess with these flags on local externs; they remain
- external even if there's a declaration at file scope which
- isn't. */
- TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
- DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
- }
+ TREE_STATIC (newdecl) = TREE_STATIC (olddecl);
+ DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl);
+
/* An extern decl does not override previous storage class. */
TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
if (! DECL_EXTERNAL (newdecl))
- DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
+ {
+ DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
+ DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
+ }
}
else
{
@@ -1487,7 +1424,11 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
been written out yet. */
if (new_is_definition && DECL_INITIAL (olddecl))
{
- if (TREE_USED (olddecl))
+ if (TREE_USED (olddecl)
+ /* In unit-at-a-time mode we never inline re-defined extern
+ inline functions. */
+ && !flag_unit_at_a_time
+ && cgraph_function_possibly_inlined_p (olddecl))
(*debug_hooks->outlining_inline_function) (olddecl);
/* The new defn must not be inline. */
@@ -1508,37 +1449,18 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
if (DECL_BUILT_IN (olddecl))
{
- /* Get rid of any built-in function if new arg types don't match it
- or if we have a function definition. */
- if (! types_match || new_is_definition)
- {
- if (! different_binding_level)
- {
- TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
- DECL_BUILT_IN_CLASS (olddecl) = NOT_BUILT_IN;
- }
- }
- else
- {
- /* If redeclaring a builtin function, and not a definition,
- it stays built in. */
- DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
- DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
- }
+ /* If redeclaring a builtin function, it stays built in. */
+ DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
+ DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
}
/* Also preserve various other info from the definition. */
if (! new_is_definition)
{
DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
- /* When called with different_binding_level set, don't copy over
- DECL_INITIAL, so that we don't accidentally change function
- declarations into function definitions. */
- if (! different_binding_level)
- DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
+ DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
- DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl);
DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
/* Set DECL_INLINE on the declaration if we've got a body
@@ -1547,9 +1469,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
{
DECL_INLINE (newdecl) = 1;
DECL_ABSTRACT_ORIGIN (newdecl)
- = (different_binding_level
- ? DECL_ORIGIN (olddecl)
- : DECL_ABSTRACT_ORIGIN (olddecl));
+ = DECL_ABSTRACT_ORIGIN (olddecl);
}
}
else
@@ -1561,25 +1481,21 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
DECL_INLINE (newdecl) = 1;
}
}
- if (different_binding_level)
- return 0;
/* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
- But preserve OLDDECL's DECL_UID. */
+ But preserve OLDDECL's DECL_UID and C_DECL_INVISIBLE. */
{
unsigned olddecl_uid = DECL_UID (olddecl);
+ unsigned olddecl_invisible = C_DECL_INVISIBLE (olddecl);
memcpy ((char *) olddecl + sizeof (struct tree_common),
(char *) newdecl + sizeof (struct tree_common),
sizeof (struct tree_decl) - sizeof (struct tree_common));
DECL_UID (olddecl) = olddecl_uid;
+ C_DECL_INVISIBLE (olddecl) = olddecl_invisible;
}
- /* NEWDECL contains the merged attribute lists.
- Update OLDDECL to be the same. */
- DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);
-
- /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
+ /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
so that encode_section_info has a chance to look at the new decl
flags and attributes. */
if (DECL_RTL_SET_P (olddecl)
@@ -1587,67 +1503,157 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
|| (TREE_CODE (olddecl) == VAR_DECL
&& TREE_STATIC (olddecl))))
make_decl_rtl (olddecl, NULL);
+}
- return 1;
+/* Handle when a new declaration NEWDECL has the same name as an old
+ one OLDDECL in the same binding contour. Prints an error message
+ if appropriate.
+
+ If safely possible, alter OLDDECL to look like NEWDECL, and return
+ true. Otherwise, return false. */
+
+static bool
+duplicate_decls (tree newdecl, tree olddecl)
+{
+ tree newtype, oldtype;
+
+ if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, &oldtype))
+ return false;
+
+ merge_decls (newdecl, olddecl, newtype, oldtype);
+ return true;
+}
+
+
+/* Return any external DECL associated with ID, whether or not it is
+ currently in scope. */
+
+static tree
+any_external_decl (tree id)
+{
+ tree decl = IDENTIFIER_SYMBOL_VALUE (id);
+ tree t;
+
+ if (decl == 0 || TREE_CODE (decl) == ERROR_MARK)
+ return 0;
+ else if (TREE_CODE (decl) != TYPE_DECL && DECL_EXTERNAL (decl))
+ return decl;
+
+ t = purpose_member (id, truly_local_externals);
+ if (t)
+ return TREE_VALUE (t);
+
+ return 0;
+}
+
+/* Record an external decl DECL. This only does something if a
+ shadowing decl already exists. */
+static void
+record_external_decl (tree decl)
+{
+ tree name = DECL_NAME (decl);
+ if (!IDENTIFIER_SYMBOL_VALUE (name))
+ return;
+
+ truly_local_externals = tree_cons (name, decl, truly_local_externals);
}
/* Check whether decl-node X shadows an existing declaration.
- OLDLOCAL is the old IDENTIFIER_LOCAL_VALUE of the DECL_NAME of X,
+ OLD is the old IDENTIFIER_SYMBOL_VALUE of the DECL_NAME of X,
which might be a NULL_TREE. */
static void
-warn_if_shadowing (x, oldlocal)
- tree x, oldlocal;
+warn_if_shadowing (tree x, tree old)
{
- tree name;
-
- if (DECL_EXTERNAL (x))
+ /* Nothing to shadow? */
+ if (old == 0
+ /* Shadow warnings not wanted? */
+ || !warn_shadow
+ /* No shadow warnings for internally generated vars. */
+ || DECL_SOURCE_LINE (x) == 0
+ /* No shadow warnings for vars made for inlining. */
+ || DECL_FROM_INLINE (x)
+ /* Don't warn about the parm names in function declarator
+ within a function declarator.
+ It would be nice to avoid warning in any function
+ declarator in a declaration, as opposed to a definition,
+ but there is no way to tell it's not a definition. */
+ || (TREE_CODE (x) == PARM_DECL && current_scope->outer->parm_flag)
+ /* Shadow warnings only apply to local variables and parameters. */
+ || (TREE_CODE (x) != PARM_DECL && DECL_FILE_SCOPE_P (x)))
return;
- name = DECL_NAME (x);
+ if (TREE_CODE (old) == PARM_DECL)
+ warning ("%Jdeclaration of '%D' shadows a parameter", x, x);
+ else if (DECL_FILE_SCOPE_P (old))
+ warning ("%Jdeclaration of '%D' shadows a global declaration", x, x);
+ else
+ warning ("%Jdeclaration of '%D' shadows a previous local", x, x);
- /* Warn if shadowing an argument at the top level of the body. */
- if (oldlocal != 0
- /* This warning doesn't apply to the parms of a nested fcn. */
- && ! current_binding_level->parm_flag
- /* Check that this is one level down from the parms. */
- && current_binding_level->level_chain->parm_flag
- /* Check that the decl being shadowed
- comes from the parm level, one level up. */
- && chain_member (oldlocal, current_binding_level->level_chain->names))
- {
- if (TREE_CODE (oldlocal) == PARM_DECL)
- pedwarn ("declaration of `%s' shadows a parameter",
- IDENTIFIER_POINTER (name));
- else
- pedwarn ("declaration of `%s' shadows a symbol from the parameter list",
- IDENTIFIER_POINTER (name));
+ warning ("%Jshadowed declaration is here", old);
+}
+
+
+/* Subroutine of pushdecl.
+
+ X is a TYPE_DECL for a typedef statement. Create a brand new
+ ..._TYPE node (which will be just a variant of the existing
+ ..._TYPE node with identical properties) and then install X
+ as the TYPE_NAME of this brand new (duplicate) ..._TYPE node.
+
+ The whole point here is to end up with a situation where each
+ and every ..._TYPE node the compiler creates will be uniquely
+ associated with AT MOST one node representing a typedef name.
+ This way, even though the compiler substitutes corresponding
+ ..._TYPE nodes for TYPE_DECL (i.e. "typedef name") nodes very
+ early on, later parts of the compiler can always do the reverse
+ translation and get back the corresponding typedef name. For
+ example, given:
+
+ typedef struct S MY_TYPE;
+ MY_TYPE object;
+
+ Later parts of the compiler might only know that `object' was of
+ type `struct S' if it were not for code just below. With this
+ code however, later parts of the compiler see something like:
+
+ struct S' == struct S
+ typedef struct S' MY_TYPE;
+ struct S' object;
+
+ And they can then deduce (from the node for type struct S') that
+ the original object declaration was:
+
+ MY_TYPE object;
+
+ Being able to do this is important for proper support of protoize,
+ and also for generating precise symbolic debugging information
+ which takes full account of the programmer's (typedef) vocabulary.
+
+ Obviously, we don't want to generate a duplicate ..._TYPE node if
+ the TYPE_DECL node that we are now processing really represents a
+ standard built-in type.
+
+ Since all standard types are effectively declared at line zero
+ in the source file, we can easily check to see if we are working
+ on a standard type by checking the current value of lineno. */
+
+static void
+clone_underlying_type (tree x)
+{
+ if (DECL_SOURCE_LINE (x) == 0)
+ {
+ if (TYPE_NAME (TREE_TYPE (x)) == 0)
+ TYPE_NAME (TREE_TYPE (x)) = x;
}
- /* Maybe warn if shadowing something else. */
- else if (warn_shadow
- /* No shadow warnings for internally generated vars. */
- && DECL_SOURCE_LINE (x) != 0
- /* No shadow warnings for vars made for inlining. */
- && ! DECL_FROM_INLINE (x))
- {
- if (TREE_CODE (x) == PARM_DECL
- && current_binding_level->level_chain->parm_flag)
- /* Don't warn about the parm names in function declarator
- within a function declarator.
- It would be nice to avoid warning in any function
- declarator in a declaration, as opposed to a definition,
- but there is no way to tell it's not a definition. */
- ;
- else if (oldlocal)
- {
- if (TREE_CODE (oldlocal) == PARM_DECL)
- shadow_warning ("a parameter", name, oldlocal);
- else
- shadow_warning ("a previous local", name, oldlocal);
- }
- else if (IDENTIFIER_GLOBAL_VALUE (name) != 0
- && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node)
- shadow_warning ("a global declaration", name,
- IDENTIFIER_GLOBAL_VALUE (name));
+ else if (TREE_TYPE (x) != error_mark_node
+ && DECL_ORIGINAL_TYPE (x) == NULL_TREE)
+ {
+ tree tt = TREE_TYPE (x);
+ DECL_ORIGINAL_TYPE (x) = tt;
+ tt = build_type_copy (tt);
+ TYPE_NAME (tt) = x;
+ TREE_USED (tt) = TREE_USED (x);
+ TREE_TYPE (x) = tt;
}
}
@@ -1660,348 +1666,107 @@ warn_if_shadowing (x, oldlocal)
to agree with what X says. */
tree
-pushdecl (x)
- tree x;
+pushdecl (tree x)
{
- tree t;
tree name = DECL_NAME (x);
- struct binding_level *b = current_binding_level;
+ struct c_scope *scope = current_scope;
+
+#ifdef ENABLE_CHECKING
+ if (error_mark_node == 0)
+ /* Called too early. */
+ abort ();
+#endif
/* Functions need the lang_decl data. */
if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x))
- DECL_LANG_SPECIFIC (x) = (struct lang_decl *)
- ggc_alloc_cleared (sizeof (struct lang_decl));
+ DECL_LANG_SPECIFIC (x) = ggc_alloc_cleared (sizeof (struct lang_decl));
- DECL_CONTEXT (x) = current_function_decl;
/* A local extern declaration for a function doesn't constitute nesting.
A local auto declaration does, since it's a forward decl
for a nested function coming later. */
- if ((TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
- && DECL_INITIAL (x) == 0 && DECL_EXTERNAL (x))
- DECL_CONTEXT (x) = 0;
+ if (current_function_decl == NULL
+ || ((TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
+ && DECL_INITIAL (x) == 0 && DECL_EXTERNAL (x)))
+ DECL_CONTEXT (x) = current_file_decl;
+ else
+ DECL_CONTEXT (x) = current_function_decl;
if (name)
{
- int different_binding_level = 0;
+ tree old;
if (warn_nested_externs
+ && scope != global_scope
&& DECL_EXTERNAL (x)
- && b != global_binding_level
- && x != IDENTIFIER_IMPLICIT_DECL (name)
- /* No error messages for __FUNCTION__ and __PRETTY_FUNCTION__. */
&& !DECL_IN_SYSTEM_HEADER (x))
warning ("nested extern declaration of `%s'",
IDENTIFIER_POINTER (name));
- t = lookup_name_current_level (name);
- if (! t && DECL_EXTERNAL (x) && TREE_PUBLIC (x))
- {
- t = IDENTIFIER_GLOBAL_VALUE (name);
- /* Type decls at global scope don't conflict with externs declared
- inside lexical blocks. */
- if (! t || TREE_CODE (t) == TYPE_DECL)
- /* If there's no visible global declaration, try for an
- invisible one. */
- t = IDENTIFIER_LIMBO_VALUE (name);
- different_binding_level = 1;
- }
- if (t != 0 && t == error_mark_node)
- /* error_mark_node is 0 for a while during initialization! */
- {
- t = 0;
- error_with_decl (x, "`%s' used prior to declaration");
- }
-
- /* If this decl is `static' and an implicit decl was seen previously,
- warn. */
- if (TREE_PUBLIC (name)
- /* Don't test for DECL_EXTERNAL, because grokdeclarator
- sets this for all functions. */
- && ! TREE_PUBLIC (x)
- && (TREE_CODE (x) == FUNCTION_DECL || b == global_binding_level)
- /* We used to warn also for explicit extern followed by static,
- but sometimes you need to do it that way. */
- && IDENTIFIER_IMPLICIT_DECL (name) != 0)
+ old = lookup_name_current_level (name);
+ if (old && duplicate_decls (x, old))
{
- pedwarn ("`%s' was declared implicitly `extern' and later `static'",
- IDENTIFIER_POINTER (name));
- pedwarn_with_file_and_line
- (DECL_SOURCE_FILE (IDENTIFIER_IMPLICIT_DECL (name)),
- DECL_SOURCE_LINE (IDENTIFIER_IMPLICIT_DECL (name)),
- "previous declaration of `%s'",
- IDENTIFIER_POINTER (name));
- TREE_THIS_VOLATILE (name) = 1;
- }
-
- if (t != 0 && duplicate_decls (x, t, different_binding_level))
- {
- if (TREE_CODE (t) == PARM_DECL)
+ /* For PARM_DECLs, old may be a forward declaration.
+ If so, we want to remove it from its old location
+ (in the variables chain) and rechain it in the
+ location given by the new declaration. */
+ if (TREE_CODE (x) == PARM_DECL)
{
- /* Don't allow more than one "real" duplicate
- of a forward parm decl. */
- TREE_ASM_WRITTEN (t) = TREE_ASM_WRITTEN (x);
- return t;
+ tree *p;
+ for (p = &scope->names; *p; p = &TREE_CHAIN (*p))
+ if (*p == old)
+ {
+ *p = TREE_CHAIN (old);
+ SCOPE_LIST_APPEND (scope, parms, old);
+ break;
+ }
}
- return t;
+ return old;
}
-
- /* If we are processing a typedef statement, generate a whole new
- ..._TYPE node (which will be just a variant of the existing
- ..._TYPE node with identical properties) and then install the
- TYPE_DECL node generated to represent the typedef name as the
- TYPE_NAME of this brand new (duplicate) ..._TYPE node.
-
- The whole point here is to end up with a situation where each
- and every ..._TYPE node the compiler creates will be uniquely
- associated with AT MOST one node representing a typedef name.
- This way, even though the compiler substitutes corresponding
- ..._TYPE nodes for TYPE_DECL (i.e. "typedef name") nodes very
- early on, later parts of the compiler can always do the reverse
- translation and get back the corresponding typedef name. For
- example, given:
-
- typedef struct S MY_TYPE;
- MY_TYPE object;
-
- Later parts of the compiler might only know that `object' was of
- type `struct S' if it were not for code just below. With this
- code however, later parts of the compiler see something like:
-
- struct S' == struct S
- typedef struct S' MY_TYPE;
- struct S' object;
-
- And they can then deduce (from the node for type struct S') that
- the original object declaration was:
-
- MY_TYPE object;
-
- Being able to do this is important for proper support of protoize,
- and also for generating precise symbolic debugging information
- which takes full account of the programmer's (typedef) vocabulary.
-
- Obviously, we don't want to generate a duplicate ..._TYPE node if
- the TYPE_DECL node that we are now processing really represents a
- standard built-in type.
-
- Since all standard types are effectively declared at line zero
- in the source file, we can easily check to see if we are working
- on a standard type by checking the current value of lineno. */
-
- if (TREE_CODE (x) == TYPE_DECL)
+ if (DECL_EXTERNAL (x) || scope == global_scope)
{
- if (DECL_SOURCE_LINE (x) == 0)
+ /* Find and check against a previous, not-in-scope, external
+ decl for this identifier. (C99 6.2.7p2: All declarations
+ that refer to the same object or function shall have
+ compatible type; otherwise, the behavior is undefined.) */
+ tree ext = any_external_decl (name);
+ if (ext)
{
- if (TYPE_NAME (TREE_TYPE (x)) == 0)
- TYPE_NAME (TREE_TYPE (x)) = x;
+ if (duplicate_decls (x, ext))
+ x = copy_node (ext);
}
- else if (TREE_TYPE (x) != error_mark_node
- && DECL_ORIGINAL_TYPE (x) == NULL_TREE)
- {
- tree tt = TREE_TYPE (x);
- DECL_ORIGINAL_TYPE (x) = tt;
- tt = build_type_copy (tt);
- TYPE_NAME (tt) = x;
- TREE_USED (tt) = TREE_USED (x);
- TREE_TYPE (x) = tt;
- }
- }
-
- /* Multiple external decls of the same identifier ought to match.
- We get warnings about inline functions where they are defined.
- Avoid duplicate warnings where they are used. */
- if (TREE_PUBLIC (x)
- && ! (TREE_CODE (x) == FUNCTION_DECL && DECL_INLINE (x)))
- {
- tree decl;
-
- if (IDENTIFIER_LIMBO_VALUE (name) != 0)
- /* Decls in limbo are always extern, so no need to check that. */
- decl = IDENTIFIER_LIMBO_VALUE (name);
else
- decl = 0;
-
- if (decl && ! comptypes (TREE_TYPE (x), TREE_TYPE (decl))
- /* If old decl is built-in, we already warned if we should. */
- && !DECL_BUILT_IN (decl))
- {
- pedwarn_with_decl (x,
- "type mismatch with previous external decl");
- pedwarn_with_decl (decl, "previous external decl of `%s'");
- }
+ record_external_decl (x);
}
- /* If a function has had an implicit declaration, and then is defined,
- make sure they are compatible. */
-
- if (IDENTIFIER_IMPLICIT_DECL (name) != 0
- && IDENTIFIER_GLOBAL_VALUE (name) == 0
- && TREE_CODE (x) == FUNCTION_DECL
- && ! comptypes (TREE_TYPE (x),
- TREE_TYPE (IDENTIFIER_IMPLICIT_DECL (name))))
- {
- warning_with_decl (x, "type mismatch with previous implicit declaration");
- warning_with_decl (IDENTIFIER_IMPLICIT_DECL (name),
- "previous implicit declaration of `%s'");
- }
-
- /* This name is new in its binding level.
- Install the new declaration and return it. */
- if (b == global_binding_level)
+ if (TREE_CODE (x) == TYPE_DECL)
+ clone_underlying_type (x);
+
+ /* If storing a local value, there may already be one
+ (inherited). If so, record it for restoration when this
+ scope ends. Take care not to do this if we are replacing an
+ older decl in the same scope (i.e. duplicate_decls returned
+ false, above). */
+ if (scope != global_scope)
{
- /* Install a global value. */
-
- /* If the first global decl has external linkage,
- warn if we later see static one. */
- if (IDENTIFIER_GLOBAL_VALUE (name) == 0 && TREE_PUBLIC (x))
- TREE_PUBLIC (name) = 1;
-
- IDENTIFIER_GLOBAL_VALUE (name) = x;
-
- /* We no longer care about any previous block level declarations. */
- IDENTIFIER_LIMBO_VALUE (name) = 0;
-
- /* Don't forget if the function was used via an implicit decl. */
- if (IDENTIFIER_IMPLICIT_DECL (name)
- && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name)))
- TREE_USED (x) = 1, TREE_USED (name) = 1;
-
- /* Don't forget if its address was taken in that way. */
- if (IDENTIFIER_IMPLICIT_DECL (name)
- && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name)))
- TREE_ADDRESSABLE (x) = 1;
-
- /* Warn about mismatches against previous implicit decl. */
- if (IDENTIFIER_IMPLICIT_DECL (name) != 0
- /* If this real decl matches the implicit, don't complain. */
- && ! (TREE_CODE (x) == FUNCTION_DECL
- && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (x)))
- == integer_type_node)))
- pedwarn ("`%s' was previously implicitly declared to return `int'",
- IDENTIFIER_POINTER (name));
-
- /* If this decl is `static' and an `extern' was seen previously,
- that is erroneous. */
- if (TREE_PUBLIC (name)
- && ! TREE_PUBLIC (x) && ! DECL_EXTERNAL (x))
+ tree inherited_decl = lookup_name (name);
+ if (inherited_decl && inherited_decl != old)
{
- /* Okay to redeclare an ANSI built-in as static. */
- if (t != 0 && DECL_BUILT_IN (t))
- ;
- /* Okay to declare a non-ANSI built-in as anything. */
- else if (t != 0 && DECL_BUILT_IN_NONANSI (t))
- ;
- /* Okay to have global type decl after an earlier extern
- declaration inside a lexical block. */
- else if (TREE_CODE (x) == TYPE_DECL)
- ;
- else if (IDENTIFIER_IMPLICIT_DECL (name))
- {
- if (! TREE_THIS_VOLATILE (name))
- pedwarn ("`%s' was declared implicitly `extern' and later `static'",
- IDENTIFIER_POINTER (name));
- }
- else
- pedwarn ("`%s' was declared `extern' and later `static'",
- IDENTIFIER_POINTER (name));
+ warn_if_shadowing (x, inherited_decl);
+ scope->shadowed = tree_cons (name, inherited_decl,
+ scope->shadowed);
}
}
- else
- {
- /* Here to install a non-global value. */
- tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
- tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name);
-
- IDENTIFIER_LOCAL_VALUE (name) = x;
-
- /* If this is an extern function declaration, see if we
- have a global definition or declaration for the function. */
- if (oldlocal == 0
- && oldglobal != 0
- && TREE_CODE (x) == FUNCTION_DECL
- && TREE_CODE (oldglobal) == FUNCTION_DECL
- && DECL_EXTERNAL (x)
- && ! DECL_DECLARED_INLINE_P (x))
- {
- /* We have one. Their types must agree. */
- if (! comptypes (TREE_TYPE (x),
- TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (name))))
- pedwarn_with_decl (x, "extern declaration of `%s' doesn't match global one");
- else
- {
- /* Inner extern decl is inline if global one is.
- Copy enough to really inline it. */
- if (DECL_DECLARED_INLINE_P (oldglobal))
- {
- DECL_DECLARED_INLINE_P (x)
- = DECL_DECLARED_INLINE_P (oldglobal);
- DECL_INLINE (x) = DECL_INLINE (oldglobal);
- DECL_INITIAL (x) = (current_function_decl == oldglobal
- ? 0 : DECL_INITIAL (oldglobal));
- DECL_SAVED_INSNS (x) = DECL_SAVED_INSNS (oldglobal);
- DECL_NUM_STMTS (x) = DECL_NUM_STMTS (oldglobal);
- DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal);
- DECL_RESULT (x) = DECL_RESULT (oldglobal);
- TREE_ASM_WRITTEN (x) = TREE_ASM_WRITTEN (oldglobal);
- DECL_ABSTRACT_ORIGIN (x)
- = DECL_ABSTRACT_ORIGIN (oldglobal);
- }
- /* Inner extern decl is built-in if global one is. */
- if (DECL_BUILT_IN (oldglobal))
- {
- DECL_BUILT_IN_CLASS (x) = DECL_BUILT_IN_CLASS (oldglobal);
- DECL_FUNCTION_CODE (x) = DECL_FUNCTION_CODE (oldglobal);
- }
- /* Keep the arg types from a file-scope fcn defn. */
- if (TYPE_ARG_TYPES (TREE_TYPE (oldglobal)) != 0
- && DECL_INITIAL (oldglobal)
- && TYPE_ARG_TYPES (TREE_TYPE (x)) == 0)
- TREE_TYPE (x) = TREE_TYPE (oldglobal);
- }
- }
-#if 0
- /* This case is probably sometimes the right thing to do. */
- /* If we have a local external declaration,
- then any file-scope declaration should not
- have been static. */
- if (oldlocal == 0 && oldglobal != 0
- && !TREE_PUBLIC (oldglobal)
- && DECL_EXTERNAL (x) && TREE_PUBLIC (x))
- warning ("`%s' locally external but globally static",
- IDENTIFIER_POINTER (name));
-#endif
-
- /* If we have a local external declaration,
- and no file-scope declaration has yet been seen,
- then if we later have a file-scope decl it must not be static. */
- if (oldlocal == 0
- && DECL_EXTERNAL (x)
- && TREE_PUBLIC (x))
- {
- if (oldglobal == 0)
- TREE_PUBLIC (name) = 1;
-
- /* Save this decl, so that we can do type checking against
- other decls after it falls out of scope.
-
- Only save it once. This prevents temporary decls created in
- expand_inline_function from being used here, since this
- will have been set when the inline function was parsed.
- It also helps give slightly better warnings. */
- if (IDENTIFIER_LIMBO_VALUE (name) == 0)
- IDENTIFIER_LIMBO_VALUE (name) = x;
- }
-
- warn_if_shadowing (x, oldlocal);
+ /* Install the new declaration in the requested scope. */
+ IDENTIFIER_SYMBOL_VALUE (name) = x;
+ C_DECL_INVISIBLE (x) = 0;
- /* If storing a local value, there may already be one (inherited).
- If so, record it for restoration when this binding level ends. */
- if (oldlocal != 0)
- b->shadowed = tree_cons (name, oldlocal, b->shadowed);
- }
+ /* If x's type is incomplete because it's based on a
+ structure or union which has not yet been fully declared,
+ attach it to that structure or union type, so we can go
+ back and complete the variable declaration later, if the
+ structure or union gets fully declared.
- /* Keep list of variables in this level with incomplete type.
If the input is erroneous, we can have error_mark in the type
slot (e.g. "f(void a, ...)") - that doesn't count as an
incomplete type. */
@@ -2012,92 +1777,97 @@ pushdecl (x)
while (TREE_CODE (element) == ARRAY_TYPE)
element = TREE_TYPE (element);
+ element = TYPE_MAIN_VARIANT (element);
+
if ((TREE_CODE (element) == RECORD_TYPE
|| TREE_CODE (element) == UNION_TYPE)
&& (TREE_CODE (x) != TYPE_DECL
- || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE))
- b->incomplete_list = tree_cons (NULL_TREE, x, b->incomplete_list);
+ || TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
+ && !COMPLETE_TYPE_P (element))
+ C_TYPE_INCOMPLETE_VARS (element)
+ = tree_cons (NULL_TREE, x, C_TYPE_INCOMPLETE_VARS (element));
}
}
- /* Put decls on list in reverse order.
- We will reverse them later if necessary. */
- TREE_CHAIN (x) = b->names;
- b->names = x;
+ if (TREE_CODE (x) == PARM_DECL)
+ SCOPE_LIST_APPEND (scope, parms, x);
+ else
+ SCOPE_LIST_APPEND (scope, names, x);
return x;
}
-/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
+/* Record X as belonging to the global scope (C99 "file scope").
+ This is used only internally by the Objective-C front end,
+ and is limited to its needs. duplicate_decls is not called;
+ if there is any preexisting decl for this identifier, it is an ICE. */
tree
-pushdecl_top_level (x)
- tree x;
+pushdecl_top_level (tree x)
{
- tree t;
- struct binding_level *b = current_binding_level;
+ tree name;
- current_binding_level = global_binding_level;
- t = pushdecl (x);
- current_binding_level = b;
- return t;
+ if (TREE_CODE (x) != VAR_DECL)
+ abort ();
+
+ name = DECL_NAME (x);
+
+ if (IDENTIFIER_SYMBOL_VALUE (name))
+ abort ();
+
+ DECL_CONTEXT (x) = current_file_decl;
+ IDENTIFIER_SYMBOL_VALUE (name) = x;
+
+ SCOPE_LIST_APPEND (global_scope, names, x);
+ return x;
}
-/* Generate an implicit declaration for identifier FUNCTIONID
- as a function of type int (). Print a warning if appropriate. */
+/* Generate an implicit declaration for identifier FUNCTIONID as a
+ function of type int (). */
tree
-implicitly_declare (functionid)
- tree functionid;
+implicitly_declare (tree functionid)
{
- tree decl;
- int traditional_warning = 0;
- /* Only one "implicit declaration" warning per identifier. */
- int implicit_warning;
-
- /* We used to reuse an old implicit decl here,
- but this loses with inline functions because it can clobber
- the saved decl chains. */
-#if 0
- if (IDENTIFIER_IMPLICIT_DECL (functionid) != 0)
- decl = IDENTIFIER_IMPLICIT_DECL (functionid);
- else
-#endif
- decl = build_decl (FUNCTION_DECL, functionid, default_function_type);
-
- /* Warn of implicit decl following explicit local extern decl.
- This is probably a program designed for traditional C. */
- if (TREE_PUBLIC (functionid) && IDENTIFIER_GLOBAL_VALUE (functionid) == 0)
- traditional_warning = 1;
+ tree decl = any_external_decl (functionid);
- /* Warn once of an implicit declaration. */
- implicit_warning = (IDENTIFIER_IMPLICIT_DECL (functionid) == 0);
+ if (decl)
+ {
+ /* 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;
+ then recycle the old declaration. */
+ if (!C_DECL_IMPLICIT (decl))
+ {
+ implicit_decl_warning (DECL_NAME (decl));
+ if (! DECL_FILE_SCOPE_P (decl))
+ warning ("%Jprevious declaration of '%D'", decl, decl);
+ C_DECL_IMPLICIT (decl) = 1;
+ }
+ /* If this function is global, then it must already be in the
+ global scope, so there's no need to push it again. */
+ if (current_scope == global_scope)
+ return decl;
+ /* If this is a local declaration, make a copy; we can't have
+ the same DECL listed in two different scopes. */
+ return pushdecl (copy_node (decl));
+ }
+ /* Not seen before. */
+ decl = build_decl (FUNCTION_DECL, functionid, default_function_type);
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
+ C_DECL_IMPLICIT (decl) = 1;
+ implicit_decl_warning (functionid);
- /* Record that we have an implicit decl and this is it. */
- IDENTIFIER_IMPLICIT_DECL (functionid) = decl;
-
- /* ANSI standard says implicit declarations are in the innermost block.
+ /* C89 says implicit declarations are in the innermost block.
So we record the decl in the standard fashion. */
- pushdecl (decl);
-
- /* This is a no-op in c-lang.c or something real in objc-act.c. */
- if (flag_objc)
- objc_check_decl (decl);
+ decl = pushdecl (decl);
+ /* No need to call objc_check_decl here - it's a function type. */
rest_of_decl_compilation (decl, NULL, 0, 0);
- if (implicit_warning)
- implicit_decl_warning (functionid);
- else if (warn_traditional && traditional_warning)
- warning ("function `%s' was previously declared within a block",
- IDENTIFIER_POINTER (functionid));
-
- /* Write a record describing this implicit function declaration to the
- prototypes file (if requested). */
-
+ /* Write a record describing this implicit function declaration
+ to the prototypes file (if requested). */
gen_aux_info_record (decl, 0, 1, 0);
/* Possibly apply some default attributes to this implicit declaration. */
@@ -2106,9 +1876,8 @@ implicitly_declare (functionid)
return decl;
}
-void
-implicit_decl_warning (id)
- tree id;
+static void
+implicit_decl_warning (tree id)
{
const char *name = IDENTIFIER_POINTER (id);
if (mesg_implicit_function_declaration == 2)
@@ -2117,152 +1886,144 @@ implicit_decl_warning (id)
warning ("implicit declaration of function `%s'", name);
}
-/* Return zero if the declaration NEWDECL is valid
- when the declaration OLDDECL (assumed to be for the same name)
- has already been seen.
- Otherwise return 1 if NEWDECL is a redefinition, 2 if it is a redeclaration,
- and 3 if it is a conflicting declaration. */
-
-static int
-redeclaration_error_message (newdecl, olddecl)
- tree newdecl, olddecl;
+/* Issue an error message for a reference to an undeclared variable
+ ID, including a reference to a builtin outside of function-call
+ context. Establish a binding of the identifier to error_mark_node
+ in an appropriate scope, which will suppress further errors for the
+ same identifier. */
+void
+undeclared_variable (tree id)
{
- if (TREE_CODE (newdecl) == TYPE_DECL)
- {
- /* Do not complain about type redeclarations where at least one
- declaration was in a system header. */
- if (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl))
- return 0;
- return 1;
- }
- else if (TREE_CODE (newdecl) == FUNCTION_DECL)
- {
- /* Declarations of functions can insist on internal linkage
- but they can't be inconsistent with internal linkage,
- so there can be no error on that account.
- However defining the same name twice is no good. */
- if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0
- /* However, defining once as extern inline and a second
- time in another way is ok. */
- && ! (DECL_DECLARED_INLINE_P (olddecl) && DECL_EXTERNAL (olddecl)
- && ! (DECL_DECLARED_INLINE_P (newdecl)
- && DECL_EXTERNAL (newdecl))))
- return 1;
- return 0;
- }
- else if (DECL_CONTEXT (newdecl) == NULL_TREE)
+ static bool already = false;
+ struct c_scope *scope;
+
+ if (current_function_decl == 0)
{
- /* Objects declared at top level: */
- /* If at least one is a reference, it's ok. */
- if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
- return 0;
- /* Reject two definitions. */
- if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0)
- return 1;
- /* Now we have two tentative defs, or one tentative and one real def. */
- /* Insist that the linkage match. */
- if (TREE_PUBLIC (olddecl) != TREE_PUBLIC (newdecl))
- return 3;
- return 0;
+ error ("`%s' undeclared here (not in a function)",
+ IDENTIFIER_POINTER (id));
+ scope = current_scope;
}
- else if (current_binding_level->parm_flag
- && TREE_ASM_WRITTEN (olddecl) && !TREE_ASM_WRITTEN (newdecl))
- return 0;
else
{
- /* Newdecl has block scope. If olddecl has block scope also, then
- reject two definitions, and reject a definition together with an
- external reference. Otherwise, it is OK, because newdecl must
- be an extern reference to olddecl. */
- if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl))
- && DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl))
- return 2;
- return 0;
+ error ("`%s' undeclared (first use in this function)",
+ IDENTIFIER_POINTER (id));
+
+ if (! already)
+ {
+ error ("(Each undeclared identifier is reported only once");
+ error ("for each function it appears in.)");
+ already = true;
+ }
+
+ scope = current_function_scope;
}
+
+ scope->shadowed = tree_cons (id, IDENTIFIER_SYMBOL_VALUE (id),
+ scope->shadowed);
+ IDENTIFIER_SYMBOL_VALUE (id) = error_mark_node;
}
-/* Get the LABEL_DECL corresponding to identifier ID as a label.
+/* Subroutine of lookup_label, declare_label, define_label: construct a
+ LABEL_DECL with all the proper frills. */
+
+static tree
+make_label (tree name, location_t location)
+{
+ tree label = build_decl (LABEL_DECL, name, void_type_node);
+
+ DECL_CONTEXT (label) = current_function_decl;
+ DECL_MODE (label) = VOIDmode;
+ DECL_SOURCE_LOCATION (label) = location;
+
+ return label;
+}
+
+/* Another subroutine of lookup_label, declare_label, define_label:
+ set up the binding of name to LABEL_DECL in the given SCOPE. */
+
+static void
+bind_label (tree name, tree label, struct c_scope *scope)
+{
+ if (IDENTIFIER_LABEL_VALUE (name))
+ scope->shadowed = tree_cons (name, IDENTIFIER_LABEL_VALUE (name),
+ scope->shadowed);
+ IDENTIFIER_LABEL_VALUE (name) = label;
+
+ SCOPE_LIST_APPEND (scope, names, label);
+}
+
+/* Get the LABEL_DECL corresponding to identifier NAME as a label.
Create one if none exists so far for the current function.
- This function is called for both label definitions and label references. */
+ This is called when a label is used in a goto expression or
+ has its address taken. */
tree
-lookup_label (id)
- tree id;
+lookup_label (tree name)
{
- tree decl = IDENTIFIER_LABEL_VALUE (id);
+ tree label;
if (current_function_decl == 0)
{
error ("label %s referenced outside of any function",
- IDENTIFIER_POINTER (id));
+ IDENTIFIER_POINTER (name));
return 0;
}
- /* Use a label already defined or ref'd with this name. */
- if (decl != 0)
+ /* Use a label already defined or ref'd with this name, but not if
+ it is inherited from a containing function and wasn't declared
+ using __label__. */
+ label = IDENTIFIER_LABEL_VALUE (name);
+ if (label && (DECL_CONTEXT (label) == current_function_decl
+ || C_DECLARED_LABEL_FLAG (label)))
{
- /* But not if it is inherited and wasn't declared to be inheritable. */
- if (DECL_CONTEXT (decl) != current_function_decl
- && ! C_DECLARED_LABEL_FLAG (decl))
- return shadow_label (id);
- return decl;
+ /* 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))
+ DECL_SOURCE_LOCATION (label) = input_location;
+ return label;
}
- decl = build_decl (LABEL_DECL, id, void_type_node);
-
- /* A label not explicitly declared must be local to where it's ref'd. */
- DECL_CONTEXT (decl) = current_function_decl;
-
- DECL_MODE (decl) = VOIDmode;
-
- /* Say where one reference is to the label,
- for the sake of the error if it is not defined. */
- DECL_SOURCE_LINE (decl) = lineno;
- DECL_SOURCE_FILE (decl) = input_filename;
+ /* No label binding for that identifier; make one. */
+ label = make_label (name, input_location);
- IDENTIFIER_LABEL_VALUE (id) = decl;
-
- named_labels = tree_cons (NULL_TREE, decl, named_labels);
-
- return decl;
+ /* Ordinary labels go in the current function scope. */
+ bind_label (name, label, current_function_scope);
+ return label;
}
-/* Make a label named NAME in the current function,
- shadowing silently any that may be inherited from containing functions
- or containing scopes.
+/* Make a label named NAME in the current function, shadowing silently
+ any that may be inherited from containing functions or containing
+ scopes. This is called for __label__ declarations. */
- Note that valid use, if the label being shadowed
- comes from another scope in the same function,
- requires calling declare_nonlocal_label right away. */
+/* Note that valid use, if the label being shadowed comes from another
+ scope in the same function, requires calling declare_nonlocal_label
+ right away. (Is this still true? -zw 2003-07-17) */
tree
-shadow_label (name)
- tree name;
+declare_label (tree name)
{
- tree decl = IDENTIFIER_LABEL_VALUE (name);
+ tree label = IDENTIFIER_LABEL_VALUE (name);
+ tree dup;
- if (decl != 0)
- {
- tree dup;
+ /* Check to make sure that the label hasn't already been declared
+ at this scope */
+ for (dup = current_scope->names; dup; dup = TREE_CHAIN (dup))
+ if (dup == label)
+ {
+ error ("duplicate label declaration `%s'", IDENTIFIER_POINTER (name));
+ error ("%Jthis is a previous declaration", dup);
- /* Check to make sure that the label hasn't already been declared
- at this label scope */
- for (dup = named_labels; dup; dup = TREE_CHAIN (dup))
- if (TREE_VALUE (dup) == decl)
- {
- error ("duplicate label declaration `%s'",
- IDENTIFIER_POINTER (name));
- error_with_decl (TREE_VALUE (dup),
- "this is a previous declaration");
- /* Just use the previous declaration. */
- return lookup_label (name);
- }
+ /* Just use the previous declaration. */
+ return dup;
+ }
- shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels);
- IDENTIFIER_LABEL_VALUE (name) = decl = 0;
- }
+ label = make_label (name, input_location);
+ C_DECLARED_LABEL_FLAG (label) = 1;
- return lookup_label (name);
+ /* Declared labels go in the current scope. */
+ bind_label (name, label, current_scope);
+ return label;
}
/* Define a label, specifying the location in the source file.
@@ -2270,133 +2031,106 @@ shadow_label (name)
Otherwise return 0. */
tree
-define_label (filename, line, name)
- const char *filename;
- int line;
- tree name;
+define_label (location_t location, tree name)
{
- tree decl = lookup_label (name);
-
- /* If label with this name is known from an outer context, shadow it. */
- if (decl != 0 && DECL_CONTEXT (decl) != current_function_decl)
+ tree label;
+
+ /* Find any preexisting label with this name. It is an error
+ if that label has already been defined in this function, or
+ if there is a containing function with a declared label with
+ the same name. */
+ label = IDENTIFIER_LABEL_VALUE (name);
+
+ if (label
+ && ((DECL_CONTEXT (label) == current_function_decl
+ && DECL_INITIAL (label) != 0)
+ || (DECL_CONTEXT (label) != current_function_decl
+ && C_DECLARED_LABEL_FLAG (label))))
{
- shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels);
- IDENTIFIER_LABEL_VALUE (name) = 0;
- decl = lookup_label (name);
+ error ("%Hduplicate label `%D'", &location, label);
+ if (DECL_INITIAL (label))
+ error ("%J`%D' previously defined here", label, label);
+ else
+ error ("%J`%D' previously declared here", label, label);
+ return 0;
}
-
- if (warn_traditional && !in_system_header && lookup_name (name))
- warning_with_file_and_line (filename, line,
- "traditional C lacks a separate namespace for labels, identifier `%s' conflicts",
- IDENTIFIER_POINTER (name));
-
- if (DECL_INITIAL (decl) != 0)
+ else if (label && DECL_CONTEXT (label) == current_function_decl)
{
- error_with_file_and_line (filename, line, "duplicate label `%s'",
- IDENTIFIER_POINTER (name));
- return 0;
+ /* The label has been used or declared already in this function,
+ but not defined. Update its location to point to this
+ definition. */
+ DECL_SOURCE_LOCATION (label) = location;
}
else
{
- /* Mark label as having been defined. */
- DECL_INITIAL (decl) = error_mark_node;
- /* Say where in the source. */
- DECL_SOURCE_FILE (decl) = filename;
- DECL_SOURCE_LINE (decl) = line;
- return decl;
- }
-}
-
-/* Return the list of declarations of the current level.
- Note that this list is in reverse order unless/until
- you nreverse it; and when you do nreverse it, you must
- store the result back using `storedecls' or you will lose. */
+ /* No label binding for that identifier; make one. */
+ label = make_label (name, location);
-tree
-getdecls ()
-{
- return current_binding_level->names;
-}
+ /* Ordinary labels go in the current function scope. */
+ bind_label (name, label, current_function_scope);
+ }
-/* Return the list of type-tags (for structs, etc) of the current level. */
+ if (warn_traditional && !in_system_header && lookup_name (name))
+ warning ("%Htraditional C lacks a separate namespace for labels, "
+ "identifier `%s' conflicts", &location,
+ IDENTIFIER_POINTER (name));
-tree
-gettags ()
-{
- return current_binding_level->tags;
+ /* Mark label as having been defined. */
+ DECL_INITIAL (label) = error_mark_node;
+ return label;
}
+
+/* Return the list of declarations of the current scope. */
-/* Store the list of declarations of the current level.
- This is done for the parameter declarations of a function being defined,
- after they are modified in the light of any missing parameters. */
-
-static void
-storedecls (decls)
- tree decls;
+tree
+getdecls (void)
{
- current_binding_level->names = decls;
+ return current_scope->names;
}
-/* Similarly, store the list of tags of the current level. */
-
-static void
-storetags (tags)
- tree tags;
-{
- current_binding_level->tags = tags;
-}
/* Given NAME, an IDENTIFIER_NODE,
return the structure (or union or enum) definition for that name.
- Searches binding levels from BINDING_LEVEL up to the global level.
- If THISLEVEL_ONLY is nonzero, searches only the specified context
- (but skips any tag-transparent contexts to find one that is
- meaningful for tags).
+ If THISLEVEL_ONLY is nonzero, searches only the current_scope.
CODE says which kind of type the caller wants;
it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE.
If the wrong kind of type is found, an error is reported. */
static tree
-lookup_tag (code, name, binding_level, thislevel_only)
- enum tree_code code;
- struct binding_level *binding_level;
- tree name;
- int thislevel_only;
+lookup_tag (enum tree_code code, tree name, int thislevel_only)
{
- struct binding_level *level;
- int thislevel = 1;
+ tree tag = IDENTIFIER_TAG_VALUE (name);
+ int thislevel = 0;
- for (level = binding_level; level; level = level->level_chain)
+ if (!tag)
+ return 0;
+
+ /* We only care about whether it's in this level if
+ thislevel_only was set or it might be a type clash. */
+ if (thislevel_only || TREE_CODE (tag) != code)
{
- tree tail;
- for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
- {
- if (TREE_PURPOSE (tail) == name)
- {
- if (TREE_CODE (TREE_VALUE (tail)) != code)
- {
- /* Definition isn't the kind we were looking for. */
- pending_invalid_xref = name;
- pending_invalid_xref_file = input_filename;
- pending_invalid_xref_line = lineno;
- /* If in the same binding level as a declaration as a tag
- of a different type, this must not be allowed to
- shadow that tag, so give the error immediately.
- (For example, "struct foo; union foo;" is invalid.) */
- if (thislevel)
- pending_xref_error ();
- }
- return TREE_VALUE (tail);
- }
- }
- if (! level->tag_transparent)
- {
- if (thislevel_only)
- return NULL_TREE;
- thislevel = 0;
- }
+ if (current_scope == global_scope
+ || purpose_member (name, current_scope->tags))
+ thislevel = 1;
}
- return NULL_TREE;
+
+ if (thislevel_only && !thislevel)
+ return 0;
+
+ if (TREE_CODE (tag) != code)
+ {
+ /* Definition isn't the kind we were looking for. */
+ pending_invalid_xref = name;
+ pending_invalid_xref_location = input_location;
+
+ /* If in the same binding level as a declaration as a tag
+ of a different type, this must not be allowed to
+ shadow that tag, so give the error immediately.
+ (For example, "struct foo; union foo;" is invalid.) */
+ if (thislevel)
+ pending_xref_error ();
+ }
+ return tag;
}
/* Print an error message now
@@ -2405,119 +2139,99 @@ lookup_tag (code, name, binding_level, thislevel_only)
when used in the `struct foo;' construct for shadowing. */
void
-pending_xref_error ()
+pending_xref_error (void)
{
if (pending_invalid_xref != 0)
- error_with_file_and_line (pending_invalid_xref_file,
- pending_invalid_xref_line,
- "`%s' defined as wrong kind of tag",
- IDENTIFIER_POINTER (pending_invalid_xref));
+ error ("%H`%s' defined as wrong kind of tag",
+ &pending_invalid_xref_location,
+ IDENTIFIER_POINTER (pending_invalid_xref));
pending_invalid_xref = 0;
}
-/* Given a type, find the tag that was defined for it and return the tag name.
- Otherwise return 0. */
-
-static tree
-lookup_tag_reverse (type)
- tree type;
-{
- struct binding_level *level;
-
- for (level = current_binding_level; level; level = level->level_chain)
- {
- tree tail;
- for (tail = level->tags; tail; tail = TREE_CHAIN (tail))
- {
- if (TREE_VALUE (tail) == type)
- return TREE_PURPOSE (tail);
- }
- }
- return NULL_TREE;
-}
-/* Look up NAME in the current binding level and its superiors
+/* Look up NAME in the current scope and its superiors
in the namespace of variables, functions and typedefs.
Return a ..._DECL node of some kind representing its definition,
or return 0 if it is undefined. */
tree
-lookup_name (name)
- tree name;
+lookup_name (tree name)
{
- tree val;
-
- if (current_binding_level != global_binding_level
- && IDENTIFIER_LOCAL_VALUE (name))
- val = IDENTIFIER_LOCAL_VALUE (name);
- else
- val = IDENTIFIER_GLOBAL_VALUE (name);
- return val;
+ tree decl = IDENTIFIER_SYMBOL_VALUE (name);
+ if (decl == 0 || decl == error_mark_node)
+ return decl;
+ if (C_DECL_INVISIBLE (decl))
+ return 0;
+ return decl;
}
-/* Similar to `lookup_name' but look only at current binding level. */
+/* Similar to `lookup_name' but look only at the current scope. */
-tree
-lookup_name_current_level (name)
- tree name;
+static tree
+lookup_name_current_level (tree name)
{
- tree t;
-
- if (current_binding_level == global_binding_level)
- return IDENTIFIER_GLOBAL_VALUE (name);
+ tree decl = IDENTIFIER_SYMBOL_VALUE (name);
- if (IDENTIFIER_LOCAL_VALUE (name) == 0)
+ if (decl == 0 || decl == error_mark_node || C_DECL_INVISIBLE (decl))
return 0;
- for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
- if (DECL_NAME (t) == name)
- break;
+ if (current_scope == global_scope)
+ return decl;
- return t;
+ /* Scan the current scope for a decl with name NAME.
+ For PARM_DECLs, we have to look at both ->parms and ->names, since
+ forward parameter declarations wind up on the ->names list. */
+ if (TREE_CODE (decl) == PARM_DECL
+ && chain_member (decl, current_scope->parms))
+ return decl;
+ if (chain_member (decl, current_scope->names))
+ return decl;
+
+ return 0;
}
/* Create the predefined scalar types of C,
and some nodes representing standard constants (0, 1, (void *) 0).
- Initialize the global binding level.
+ Initialize the global scope.
Make definitions for built-in primitive functions. */
void
-c_init_decl_processing ()
+c_init_decl_processing (void)
{
tree endlink;
tree ptr_ftype_void, ptr_ftype_ptr;
+ location_t save_loc = input_location;
/* Adds some ggc roots, and reserved words for c-parse.in. */
c_parse_init ();
- current_function_decl = NULL;
- named_labels = NULL;
- current_binding_level = NULL_BINDING_LEVEL;
- free_binding_level = NULL_BINDING_LEVEL;
+ current_function_decl = 0;
- /* Make the binding_level structure for global names. */
+ /* Make the c_scope structure for global names. */
pushlevel (0);
- global_binding_level = current_binding_level;
+ global_scope = current_scope;
+
+ /* Declarations from c_common_nodes_and_builtins must not be associated
+ with this input file, lest we get differences between using and not
+ using preprocessed headers. */
+ input_location.file = "<internal>";
+ input_location.line = 0;
+
+ /* Make the DECL for the toplevel file scope. */
+ current_file_decl = build_decl (TRANSLATION_UNIT_DECL, NULL, NULL);
build_common_tree_nodes (flag_signed_char);
c_common_nodes_and_builtins ();
- boolean_type_node = integer_type_node;
- boolean_true_node = integer_one_node;
- boolean_false_node = integer_zero_node;
+ /* In C, comparisons and TRUTH_* expressions have type int. */
+ truthvalue_type_node = integer_type_node;
+ truthvalue_true_node = integer_one_node;
+ truthvalue_false_node = integer_zero_node;
- c_bool_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
- TREE_SET_CODE (c_bool_type_node, BOOLEAN_TYPE);
- TYPE_MAX_VALUE (c_bool_type_node) = build_int_2 (1, 0);
- TREE_TYPE (TYPE_MAX_VALUE (c_bool_type_node)) = c_bool_type_node;
- TYPE_PRECISION (c_bool_type_node) = 1;
+ /* Even in C99, which has a real boolean type. */
pushdecl (build_decl (TYPE_DECL, get_identifier ("_Bool"),
- c_bool_type_node));
- c_bool_false_node = build_int_2 (0, 0);
- TREE_TYPE (c_bool_false_node) = c_bool_type_node;
- c_bool_true_node = build_int_2 (1, 0);
- TREE_TYPE (c_bool_true_node) = c_bool_type_node;
+ boolean_type_node));
endlink = void_list_node;
ptr_ftype_void = build_function_type (ptr_type_node, endlink);
@@ -2525,10 +2239,15 @@ c_init_decl_processing ()
= build_function_type (ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node, endlink));
+ input_location = save_loc;
+
pedantic_lvalues = pedantic;
make_fname_decl = c_make_fname_decl;
start_fname_decls ();
+
+ first_builtin_decl = global_scope->names;
+ last_builtin_decl = global_scope->names_last;
}
/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
@@ -2536,13 +2255,10 @@ c_init_decl_processing ()
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. This does mean that these names
- are string merging candidates, which is wrong for C99's __func__. FIXME. */
+ out the STRING_CST initializer directly. FIXME. */
static tree
-c_make_fname_decl (id, type_dep)
- tree id;
- int type_dep;
+c_make_fname_decl (tree id, int type_dep)
{
const char *name = fname_as_string (type_dep);
tree decl, type, init;
@@ -2553,19 +2269,24 @@ c_make_fname_decl (id, type_dep)
build_index_type (size_int (length)));
decl = build_decl (VAR_DECL, id, type);
- /* We don't push the decl, so have to set its context here. */
- DECL_CONTEXT (decl) = current_function_decl;
-
+
TREE_STATIC (decl) = 1;
TREE_READONLY (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
-
+
init = build_string (length + 1, name);
TREE_TYPE (init) = type;
DECL_INITIAL (decl) = init;
TREE_USED (decl) = 1;
-
+
+ if (current_function_decl)
+ {
+ DECL_CONTEXT (decl) = current_function_decl;
+ IDENTIFIER_SYMBOL_VALUE (id) = decl;
+ SCOPE_LIST_APPEND (current_function_scope, names, decl);
+ }
+
finish_decl (decl, init, NULL_TREE);
return decl;
@@ -2581,13 +2302,9 @@ c_make_fname_decl (id, type_dep)
ATTRS is nonzero, use that for the function's attribute list. */
tree
-builtin_function (name, type, function_code, class, library_name, attrs)
- const char *name;
- tree type;
- int function_code;
- enum built_in_class class;
- const char *library_name;
- tree attrs;
+builtin_function (const char *name, tree type, int function_code,
+ enum built_in_class class, const char *library_name,
+ tree attrs)
{
tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
DECL_EXTERNAL (decl) = 1;
@@ -2602,7 +2319,7 @@ builtin_function (name, type, function_code, class, library_name, attrs)
/* Warn if a function in the namespace for users
is used without an occasion to consider it declared. */
if (name[0] != '_' || name[1] != '_')
- C_DECL_ANTICIPATED (decl) = 1;
+ C_DECL_INVISIBLE (decl) = 1;
/* Possibly apply some default attributes to this built-in function. */
if (attrs)
@@ -2612,18 +2329,6 @@ builtin_function (name, type, function_code, class, library_name, attrs)
return decl;
}
-
-/* Apply default attributes to a function, if a system function with default
- attributes. */
-
-void
-c_insert_default_attributes (decl)
- tree decl;
-{
- if (!TREE_PUBLIC (decl))
- return;
- c_common_insert_default_attributes (decl);
-}
/* Called when a declaration is seen that contains no names to declare.
If its type is a reference to a structure, union or enum inherited
@@ -2634,16 +2339,15 @@ c_insert_default_attributes (decl)
Otherwise, it is an error. */
void
-shadow_tag (declspecs)
- tree declspecs;
+shadow_tag (tree declspecs)
{
shadow_tag_warned (declspecs, 0);
}
void
-shadow_tag_warned (declspecs, warned)
- tree declspecs;
- int warned;
+shadow_tag_warned (tree declspecs, int warned)
+
+
/* 1 => we have done a pedwarn. 2 => we have done a warning, but
no pedwarn. */
{
@@ -2666,7 +2370,7 @@ shadow_tag_warned (declspecs, warned)
/* Used to test also that TYPE_SIZE (value) != 0.
That caused warning for `struct foo;' at top level in the file. */
{
- tree name = lookup_tag_reverse (value);
+ tree name = TYPE_NAME (value);
tree t;
found_tag++;
@@ -2682,7 +2386,7 @@ shadow_tag_warned (declspecs, warned)
}
else
{
- t = lookup_tag (code, name, current_binding_level, 1);
+ t = lookup_tag (code, name, 1);
if (t == 0)
{
@@ -2724,11 +2428,7 @@ shadow_tag_warned (declspecs, warned)
which has TREE_STATIC set if "static" is used. */
tree
-build_array_declarator (expr, quals, static_p, vla_unspec_p)
- tree expr;
- tree quals;
- int static_p;
- int vla_unspec_p;
+build_array_declarator (tree expr, tree quals, int static_p, int vla_unspec_p)
{
tree decl;
decl = build_nt (ARRAY_REF, NULL_TREE, expr);
@@ -2754,10 +2454,7 @@ build_array_declarator (expr, quals, static_p, vla_unspec_p)
C99 grammar. */
tree
-set_array_declarator_type (decl, type, abstract_p)
- tree decl;
- tree type;
- int abstract_p;
+set_array_declarator_type (tree decl, tree type, int abstract_p)
{
TREE_OPERAND (decl, 0) = type;
if (abstract_p && (TREE_TYPE (decl) != NULL_TREE || TREE_STATIC (decl)))
@@ -2768,8 +2465,7 @@ set_array_declarator_type (decl, type, abstract_p)
/* Decode a "typename", such as "int **", returning a ..._TYPE node. */
tree
-groktypename (typename)
- tree typename;
+groktypename (tree typename)
{
tree specs, attrs;
@@ -2778,7 +2474,8 @@ groktypename (typename)
split_specs_attrs (TREE_PURPOSE (typename), &specs, &attrs);
- typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0);
+ typename = grokdeclarator (TREE_VALUE (typename), specs, TYPENAME, 0,
+ NULL);
/* Apply attributes. */
decl_attributes (&typename, attrs, 0);
@@ -2789,14 +2486,13 @@ groktypename (typename)
/* Return a PARM_DECL node for a given pair of specs and declarator. */
tree
-groktypename_in_parm_context (typename)
- tree typename;
+groktypename_in_parm_context (tree typename)
{
if (TREE_CODE (typename) != TREE_LIST)
return typename;
return grokdeclarator (TREE_VALUE (typename),
TREE_PURPOSE (typename),
- PARM, 0);
+ PARM, 0, NULL);
}
/* Decode a declarator in an ordinary declaration or data definition.
@@ -2815,27 +2511,24 @@ groktypename_in_parm_context (typename)
grokfield and not through here. */
tree
-start_decl (declarator, declspecs, initialized, attributes)
- tree declarator, declspecs;
- int initialized;
- tree attributes;
+start_decl (tree declarator, tree declspecs, int initialized, tree attributes)
{
tree decl;
tree tem;
-
+
/* An object declared as __attribute__((deprecated)) suppresses
warnings of uses of other deprecated items. */
if (lookup_attribute ("deprecated", attributes))
deprecated_state = DEPRECATED_SUPPRESS;
decl = grokdeclarator (declarator, declspecs,
- NORMAL, initialized);
-
+ NORMAL, initialized, NULL);
+
deprecated_state = DEPRECATED_NORMAL;
if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL
&& MAIN_NAME_P (DECL_NAME (decl)))
- warning_with_decl (decl, "`%s' is usually a function");
+ warning ("%J'%D' is usually a function", decl, decl);
if (initialized)
/* Is it valid for this decl to have an initializer at all?
@@ -2897,16 +2590,8 @@ start_decl (declarator, declspecs, initialized, attributes)
if (initialized)
{
-#if 0
- /* Seems redundant with grokdeclarator. */
- if (current_binding_level != global_binding_level
- && DECL_EXTERNAL (decl)
- && TREE_CODE (decl) != FUNCTION_DECL)
- warning ("declaration of `%s' has `extern' and is initialized",
- IDENTIFIER_POINTER (DECL_NAME (decl)));
-#endif
DECL_EXTERNAL (decl) = 0;
- if (current_binding_level == global_binding_level)
+ if (current_scope == global_scope)
TREE_STATIC (decl) = 1;
/* Tell `pushdecl' this is an initialized decl
@@ -2930,7 +2615,7 @@ start_decl (declarator, declspecs, initialized, attributes)
Thread-local variables are never common, since there's no entrenched
body of code to break, and it allows more efficient variable references
- in the presense of dynamic linking. */
+ in the presence of dynamic linking. */
if (TREE_CODE (decl) == VAR_DECL
&& !initialized
@@ -2942,34 +2627,48 @@ start_decl (declarator, declspecs, initialized, attributes)
/* Set attributes here so if duplicate decl, will have proper attributes. */
decl_attributes (&decl, attributes, 0);
- /* If #pragma weak was used, mark the decl weak now. */
- if (current_binding_level == global_binding_level)
- maybe_apply_pragma_weak (decl);
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ && targetm.calls.promote_prototypes (TREE_TYPE (decl)))
+ {
+ tree ce = declarator;
+
+ if (TREE_CODE (ce) == INDIRECT_REF)
+ ce = TREE_OPERAND (declarator, 0);
+ if (TREE_CODE (ce) == CALL_EXPR)
+ {
+ tree args = TREE_PURPOSE (TREE_OPERAND (ce, 1));
+ for (; args; args = TREE_CHAIN (args))
+ {
+ tree type = TREE_TYPE (args);
+ if (INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+ DECL_ARG_TYPE (args) = integer_type_node;
+ }
+ }
+ }
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl)
&& DECL_UNINLINABLE (decl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
- warning_with_decl (decl,
- "inline function `%s' given attribute noinline");
+ warning ("%Jinline function '%D' given attribute noinline", decl, decl);
- /* Add this decl to the current binding level.
+ /* Add this decl to the current scope.
TEM may equal DECL or it may be a previous decl of the same name. */
tem = pushdecl (decl);
/* For a local variable, define the RTL now. */
- if (current_binding_level != global_binding_level
+ if (current_scope != global_scope
/* But not if this is a duplicate decl
and we preserved the rtl from the previous one
(which may or may not happen). */
&& !DECL_RTL_SET_P (tem)
- && !DECL_CONTEXT (tem))
+ && DECL_FILE_SCOPE_P (tem))
{
if (TREE_TYPE (tem) != error_mark_node
- && COMPLETE_TYPE_P (TREE_TYPE (tem)))
- expand_decl (tem);
- else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
- && DECL_INITIAL (tem) != 0)
+ && (COMPLETE_TYPE_P (TREE_TYPE (tem))
+ || (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE
+ && DECL_INITIAL (tem) != 0)))
expand_decl (tem);
}
@@ -2982,16 +2681,14 @@ start_decl (declarator, declspecs, initialized, attributes)
it must be determined now, from the initial value, or it is an error. */
void
-finish_decl (decl, init, asmspec_tree)
- tree decl, init;
- tree asmspec_tree;
+finish_decl (tree decl, tree init, tree asmspec_tree)
{
tree type = TREE_TYPE (decl);
int was_incomplete = (DECL_SIZE (decl) == 0);
const char *asmspec = 0;
/* If a name was specified, get the string. */
- if (current_binding_level == global_binding_level)
+ if (current_scope == global_scope)
asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
if (asmspec_tree)
asmspec = TREE_STRING_POINTER (asmspec_tree);
@@ -2999,7 +2696,7 @@ finish_decl (decl, init, asmspec_tree)
/* If `start_decl' didn't like having an initialization, ignore it now. */
if (init != 0 && DECL_INITIAL (decl) == 0)
init = 0;
-
+
/* Don't crash if parm is initialized. */
if (TREE_CODE (decl) == PARM_DECL)
init = 0;
@@ -3007,7 +2704,12 @@ finish_decl (decl, init, asmspec_tree)
if (init)
store_init_value (decl, init);
- /* Deduce size of array from initialization, if not already known */
+ if (c_dialect_objc () && (TREE_CODE (decl) == VAR_DECL
+ || TREE_CODE (decl) == FUNCTION_DECL
+ || TREE_CODE (decl) == FIELD_DECL))
+ objc_check_decl (decl);
+
+ /* Deduce size of array from initialization, if not already known. */
if (TREE_CODE (type) == ARRAY_TYPE
&& TYPE_DOMAIN (type) == 0
&& TREE_CODE (decl) != TYPE_DECL)
@@ -3025,12 +2727,12 @@ finish_decl (decl, init, asmspec_tree)
type = TREE_TYPE (decl);
if (failure == 1)
- error_with_decl (decl, "initializer fails to determine size of `%s'");
+ error ("%Jinitializer fails to determine size of '%D'", decl, decl);
else if (failure == 2)
{
if (do_default)
- error_with_decl (decl, "array size missing in `%s'");
+ error ("%Jarray size missing in '%D'", decl, decl);
/* If a `static' var's size isn't known,
make it extern as well as static, so it does not get
allocated.
@@ -3046,7 +2748,7 @@ finish_decl (decl, init, asmspec_tree)
warn only if the value is less than zero. */
else if (pedantic && TYPE_DOMAIN (type) != 0
&& tree_int_cst_sgn (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) < 0)
- error_with_decl (decl, "zero or negative size array `%s'");
+ error ("%Jzero or negative size array '%D'", decl, decl);
layout_decl (decl, 0);
}
@@ -3068,13 +2770,13 @@ finish_decl (decl, init, asmspec_tree)
Otherwise, let it through, but if it is not `extern'
then it may cause an error message later. */
(DECL_INITIAL (decl) != 0
- || DECL_CONTEXT (decl) != 0)
+ || !DECL_FILE_SCOPE_P (decl))
:
/* An automatic variable with an incomplete type
is an error. */
!DECL_EXTERNAL (decl)))
{
- error_with_decl (decl, "storage size of `%s' isn't known");
+ error ("%Jstorage size of '%D' isn't known", decl, decl);
TREE_TYPE (decl) = error_mark_node;
}
@@ -3084,23 +2786,49 @@ finish_decl (decl, init, asmspec_tree)
if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
constant_expression_warning (DECL_SIZE (decl));
else
- error_with_decl (decl, "storage size of `%s' isn't constant");
+ error ("%Jstorage size of '%D' isn't constant", decl, decl);
}
if (TREE_USED (type))
TREE_USED (decl) = 1;
}
- /* If this is a function and an assembler name is specified, it isn't
- builtin any more. Also reset DECL_RTL so we can give it its new
- name. */
+ /* If this is a function and an assembler name is specified, reset DECL_RTL
+ so we can give it its new name. Also, update built_in_decls if it
+ was a normal built-in. */
if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
{
- DECL_BUILT_IN_CLASS (decl) = NOT_BUILT_IN;
+ /* ASMSPEC is given, and not the name of a register. Mark the
+ name with a star so assemble_name won't munge it. */
+ char *starred = alloca (strlen (asmspec) + 2);
+ starred[0] = '*';
+ strcpy (starred + 1, asmspec);
+
+ if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+ {
+ tree builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
+ SET_DECL_RTL (builtin, NULL_RTX);
+ SET_DECL_ASSEMBLER_NAME (builtin, get_identifier (starred));
+#ifdef TARGET_MEM_FUNCTIONS
+ if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMCPY)
+ init_block_move_fn (starred);
+ else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMSET)
+ init_block_clear_fn (starred);
+#else
+ if (DECL_FUNCTION_CODE (decl) == BUILT_IN_BCOPY)
+ init_block_move_fn (starred);
+ else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_BZERO)
+ init_block_clear_fn (starred);
+#endif
+ }
SET_DECL_RTL (decl, NULL_RTX);
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
+ change_decl_assembler_name (decl, get_identifier (starred));
}
+ /* If #pragma weak was used, mark the decl weak now. */
+ if (current_scope == global_scope)
+ maybe_apply_pragma_weak (decl);
+
/* Output the assembler code and/or RTL code for variables and functions,
unless the type is an undefined structure or union.
If not, it will get done when the type is completed. */
@@ -3108,10 +2836,10 @@ finish_decl (decl, init, asmspec_tree)
if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
{
/* This is a no-op in c-lang.c or something real in objc-act.c. */
- if (flag_objc)
+ if (c_dialect_objc ())
objc_check_decl (decl);
- if (!DECL_CONTEXT (decl))
+ if (DECL_FILE_SCOPE_P (decl))
{
if (DECL_INITIAL (decl) == NULL_TREE
|| DECL_INITIAL (decl) == error_mark_node)
@@ -3119,9 +2847,7 @@ finish_decl (decl, init, asmspec_tree)
when a tentative file-scope definition is seen.
But at end of compilation, do output code for them. */
DECL_DEFER_OUTPUT (decl) = 1;
- rest_of_decl_compilation (decl, asmspec,
- (DECL_CONTEXT (decl) == 0
- || TREE_ASM_WRITTEN (decl)), 0);
+ rest_of_decl_compilation (decl, asmspec, true, 0);
}
else
{
@@ -3140,20 +2866,20 @@ finish_decl (decl, init, asmspec_tree)
ordinary, non-register local variable. Historically,
GCC has accepted -- but ignored -- the ASMSPEC in
this case. */
- if (TREE_CODE (decl) == VAR_DECL
+ if (TREE_CODE (decl) == VAR_DECL
&& !DECL_REGISTER (decl)
&& !TREE_STATIC (decl))
- warning_with_decl (decl,
- "ignoring asm-specifier for non-static local variable `%s'");
+ warning ("%Jignoring asm-specifier for non-static local "
+ "variable '%D'", decl, decl);
else
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
+ change_decl_assembler_name (decl, get_identifier (asmspec));
}
if (TREE_CODE (decl) != FUNCTION_DECL)
add_decl_stmt (decl);
}
- if (DECL_CONTEXT (decl) != 0)
+ if (!DECL_FILE_SCOPE_P (decl))
{
/* Recompute the RTL of a local array now
if it used to be an incomplete type. */
@@ -3169,18 +2895,17 @@ finish_decl (decl, init, asmspec_tree)
}
}
+ /* If this was marked 'used', be sure it will be output. */
+ if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
+ mark_referenced (DECL_ASSEMBLER_NAME (decl));
+
if (TREE_CODE (decl) == TYPE_DECL)
- {
- /* This is a no-op in c-lang.c or something real in objc-act.c. */
- if (flag_objc)
- objc_check_decl (decl);
- rest_of_decl_compilation (decl, NULL, DECL_CONTEXT (decl) == 0, 0);
- }
+ rest_of_decl_compilation (decl, NULL, DECL_FILE_SCOPE_P (decl), 0);
/* At the end of a declaration, throw away any variable type sizes
of types defined inside that declaration. There is no use
computing them in the following function definition. */
- if (current_binding_level == global_binding_level)
+ if (current_scope == global_scope)
get_pending_sizes ();
/* Install a cleanup (aka destructor) if one was given. */
@@ -3219,65 +2944,63 @@ finish_decl (decl, init, asmspec_tree)
}
}
-/* Given a parsed parameter declaration,
- decode it into a PARM_DECL and push that on the current binding level.
- Also, for the sake of forward parm decls,
- record the given order of parms in `parm_order'. */
+/* Given a parsed parameter declaration, decode it into a PARM_DECL
+ and push that on the current scope. */
void
-push_parm_decl (parm)
- tree parm;
+push_parm_decl (tree parm)
{
tree decl;
- int old_immediate_size_expand = immediate_size_expand;
- /* Don't try computing parm sizes now -- wait till fn is called. */
+
+ /* Don't attempt to expand sizes while parsing this decl.
+ (We can get here with i_s_e 1 somehow from Objective-C.) */
+ int save_immediate_size_expand = immediate_size_expand;
immediate_size_expand = 0;
decl = grokdeclarator (TREE_VALUE (TREE_PURPOSE (parm)),
- TREE_PURPOSE (TREE_PURPOSE (parm)), PARM, 0);
+ TREE_PURPOSE (TREE_PURPOSE (parm)),
+ PARM, 0, NULL);
decl_attributes (&decl, TREE_VALUE (parm), 0);
-#if 0
- if (DECL_NAME (decl))
- {
- tree olddecl;
- olddecl = lookup_name (DECL_NAME (decl));
- if (pedantic && olddecl != 0 && TREE_CODE (olddecl) == TYPE_DECL)
- pedwarn_with_decl (decl,
- "ISO C forbids parameter `%s' shadowing typedef");
- }
-#endif
-
decl = pushdecl (decl);
- immediate_size_expand = old_immediate_size_expand;
-
- current_binding_level->parm_order
- = tree_cons (NULL_TREE, decl, current_binding_level->parm_order);
-
- /* Add this decl to the current binding level. */
finish_decl (decl, NULL_TREE, NULL_TREE);
+
+ immediate_size_expand = save_immediate_size_expand;
}
-/* Clear the given order of parms in `parm_order'.
- Used at start of parm list,
- and also at semicolon terminating forward decls. */
+/* Mark all the parameter declarations to date as forward decls,
+ shift them to the variables list, and reset the parameters list.
+ Also diagnose use of this extension. */
void
-clear_parm_order ()
+mark_forward_parm_decls (void)
{
- current_binding_level->parm_order = NULL_TREE;
+ tree parm;
+
+ if (pedantic && !current_scope->warned_forward_parm_decls)
+ {
+ pedwarn ("ISO C forbids forward parameter declarations");
+ current_scope->warned_forward_parm_decls = true;
+ }
+
+ for (parm = current_scope->parms; parm; parm = TREE_CHAIN (parm))
+ TREE_ASM_WRITTEN (parm) = 1;
+
+ SCOPE_LIST_CONCAT (current_scope, names, current_scope, parms);
+ current_scope->parms = 0;
+ current_scope->parms_last = 0;
}
+static GTY(()) int compound_literal_number;
+
/* 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
literal. */
tree
-build_compound_literal (type, init)
- tree type;
- tree init;
+build_compound_literal (tree type, tree init)
{
/* 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
@@ -3287,7 +3010,7 @@ build_compound_literal (type, init)
tree stmt;
DECL_EXTERNAL (decl) = 0;
TREE_PUBLIC (decl) = 0;
- TREE_STATIC (decl) = (current_binding_level == global_binding_level);
+ TREE_STATIC (decl) = (current_scope == global_scope);
DECL_CONTEXT (decl) = current_function_decl;
TREE_USED (decl) = 1;
TREE_TYPE (decl) = type;
@@ -3316,10 +3039,10 @@ build_compound_literal (type, init)
/* This decl needs a name for the assembler output. We also need
a unique suffix to be added to the name. */
char *name;
- extern int var_labelno;
- ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal", var_labelno);
- var_labelno++;
+ ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal",
+ compound_literal_number);
+ compound_literal_number++;
DECL_NAME (decl) = get_identifier (name);
DECL_DEFER_OUTPUT (decl) = 1;
DECL_COMDAT (decl) = 1;
@@ -3336,10 +3059,7 @@ build_compound_literal (type, init)
2 if there was no information (in which case assume 1 if DO_DEFAULT). */
int
-complete_array_type (type, initial_value, do_default)
- tree type;
- tree initial_value;
- int do_default;
+complete_array_type (tree type, tree initial_value, int do_default)
{
tree maxindex = NULL_TREE;
int value = 0;
@@ -3405,8 +3125,7 @@ complete_array_type (type, initial_value, do_default)
or a union containing such a structure (possibly recursively). */
static bool
-flexible_array_type_p (type)
- tree type;
+flexible_array_type_p (tree type)
{
tree x;
switch (TREE_CODE (type))
@@ -3435,6 +3154,77 @@ flexible_array_type_p (type)
}
}
+/* Performs sanity checks on the TYPE and WIDTH of the bit-field NAME,
+ replacing with appropriate values if they are invalid. */
+static void
+check_bitfield_type_and_width (tree *type, tree *width, const char *orig_name)
+{
+ tree type_mv;
+ unsigned int max_width;
+ unsigned HOST_WIDE_INT w;
+ const char *name = orig_name ? orig_name: _("<anonymous>");
+
+ /* Necessary? */
+ STRIP_NOPS (*width);
+
+ /* Detect and ignore out of range field width and process valid
+ field widths. */
+ if (TREE_CODE (*width) != INTEGER_CST)
+ {
+ error ("bit-field `%s' width not an integer constant", name);
+ *width = integer_one_node;
+ }
+ else
+ {
+ constant_expression_warning (*width);
+ if (tree_int_cst_sgn (*width) < 0)
+ {
+ error ("negative width in bit-field `%s'", name);
+ *width = integer_one_node;
+ }
+ else if (integer_zerop (*width) && orig_name)
+ {
+ error ("zero width for bit-field `%s'", name);
+ *width = integer_one_node;
+ }
+ }
+
+ /* Detect invalid bit-field type. */
+ if (TREE_CODE (*type) != INTEGER_TYPE
+ && TREE_CODE (*type) != BOOLEAN_TYPE
+ && TREE_CODE (*type) != ENUMERAL_TYPE)
+ {
+ error ("bit-field `%s' has invalid type", name);
+ *type = unsigned_type_node;
+ }
+
+ type_mv = TYPE_MAIN_VARIANT (*type);
+ if (pedantic
+ && type_mv != integer_type_node
+ && type_mv != unsigned_type_node
+ && type_mv != boolean_type_node)
+ pedwarn ("type of bit-field `%s' is a GCC extension", name);
+
+ if (type_mv == boolean_type_node)
+ max_width = CHAR_TYPE_SIZE;
+ else
+ max_width = TYPE_PRECISION (*type);
+
+ if (0 < compare_tree_int (*width, max_width))
+ {
+ error ("width of `%s' exceeds its type", name);
+ w = max_width;
+ *width = build_int_2 (w, 0);
+ }
+ else
+ w = tree_low_cst (*width, 1);
+
+ if (TREE_CODE (*type) == ENUMERAL_TYPE
+ && (w < min_precision (TYPE_MIN_VALUE (*type), TREE_UNSIGNED (*type))
+ || w < min_precision (TYPE_MAX_VALUE (*type), TREE_UNSIGNED (*type))))
+ warning ("`%s' is narrower than values of its type", name);
+}
+
/* Given declspecs and a declarator,
determine the name and type of the object declared
and construct a ..._DECL node for it.
@@ -3454,8 +3244,9 @@ flexible_array_type_p (type)
TYPENAME if for a typename (in a cast or sizeof).
Don't make a DECL node; just return the ..._TYPE node.
FIELD for a struct or union field; make a FIELD_DECL.
- BITFIELD for a field with specified width.
INITIALIZED is 1 if the decl has an initializer.
+ WIDTH is non-NULL for bit-fields, and is a pointer to an INTEGER_CST node
+ representing the width of the bit-field.
In the TYPENAME case, DECLARATOR is really an absolute declarator.
It may also be so in the PARM case, for a prototype where the
@@ -3465,11 +3256,8 @@ flexible_array_type_p (type)
and `extern' are interpreted. */
static tree
-grokdeclarator (declarator, declspecs, decl_context, initialized)
- tree declspecs;
- tree declarator;
- enum decl_context decl_context;
- int initialized;
+grokdeclarator (tree declarator, tree declspecs,
+ enum decl_context decl_context, int initialized, tree *width)
{
int specbits = 0;
tree spec;
@@ -3484,19 +3272,17 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
int explicit_char = 0;
int defaulted_int = 0;
tree typedef_decl = 0;
- const char *name;
+ const char *name, *orig_name;
tree typedef_type = 0;
int funcdef_flag = 0;
enum tree_code innermost_code = ERROR_MARK;
- int bitfield = 0;
int size_varies = 0;
tree decl_attr = NULL_TREE;
tree array_ptr_quals = NULL_TREE;
int array_parm_static = 0;
tree returned_attrs = NULL_TREE;
-
- if (decl_context == BITFIELD)
- bitfield = 1, decl_context = FIELD;
+ bool bitfield = width != NULL;
+ tree element_type;
if (decl_context == FUNCDEF)
funcdef_flag = 1, decl_context = NORMAL;
@@ -3529,6 +3315,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
default:
abort ();
}
+ orig_name = name;
if (name == 0)
name = "type name";
}
@@ -3539,15 +3326,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
if (funcdef_flag && innermost_code != CALL_EXPR)
return 0;
- /* Anything declared one level down from the top level
- must be one of the parameters of a function
- (because the body is at least two levels down). */
-
/* If this looks like a function definition, make it one,
even if it occurs where parms are expected.
Then store_parm_decls will reject it and not use it as a parm. */
if (decl_context == NORMAL && !funcdef_flag
- && current_binding_level->parm_flag)
+ && current_scope->parm_flag)
decl_context = PARM;
/* Look through the decl specs and record which ones appear.
@@ -3602,7 +3385,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
{
if (i == RID_CONST || i == RID_VOLATILE || i == RID_RESTRICT)
{
- if (!flag_isoc99)
+ if (pedantic && !flag_isoc99)
pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
}
else
@@ -3765,7 +3548,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
}
/* Decide whether an integer type is signed or not.
- Optionally treat bitfields as signed by default. */
+ Optionally treat bit-fields as signed by default. */
if (specbits & 1 << (int) RID_UNSIGNED
|| (bitfield && ! flag_signed_bitfields
&& (explicit_int || defaulted_int || explicit_char
@@ -3837,21 +3620,37 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
}
}
+ /* Check the type and width of a bit-field. */
+ if (bitfield)
+ check_bitfield_type_and_width (&type, width, orig_name);
+
/* Figure out the type qualifiers for the declaration. There are
two ways a declaration can become qualified. One is something
like `const int i' where the `const' is explicit. Another is
something like `typedef const int CI; CI i' where the type of the
- declaration contains the `const'. */
- constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (type);
- restrictp = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (type);
- volatilep = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (type);
+ declaration contains the `const'. A third possibility is that
+ there is a type qualifier on the element type of a typedefed
+ array type, in which case we should extract that qualifier so
+ that c_apply_type_quals_to_decls receives the full list of
+ qualifiers to work with (C90 is not entirely clear about whether
+ duplicate qualifiers should be diagnosed in this case, but it
+ seems most appropriate to do so). */
+ element_type = strip_array_types (type);
+ constp = !! (specbits & 1 << (int) RID_CONST) + TYPE_READONLY (element_type);
+ restrictp
+ = !! (specbits & 1 << (int) RID_RESTRICT) + TYPE_RESTRICT (element_type);
+ volatilep
+ = !! (specbits & 1 << (int) RID_VOLATILE) + TYPE_VOLATILE (element_type);
inlinep = !! (specbits & (1 << (int) RID_INLINE));
- if (constp > 1 && ! flag_isoc99)
- pedwarn ("duplicate `const'");
- if (restrictp > 1 && ! flag_isoc99)
- pedwarn ("duplicate `restrict'");
- if (volatilep > 1 && ! flag_isoc99)
- pedwarn ("duplicate `volatile'");
+ if (pedantic && !flag_isoc99)
+ {
+ if (constp > 1)
+ pedwarn ("duplicate `const'");
+ if (restrictp > 1)
+ pedwarn ("duplicate `restrict'");
+ if (volatilep > 1)
+ pedwarn ("duplicate `volatile'");
+ }
if (! flag_gen_aux_info && (TYPE_QUALS (type)))
type = TYPE_MAIN_VARIANT (type);
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
@@ -3888,7 +3687,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
| (1 << (int) RID_THREAD))))
{
if (specbits & 1 << (int) RID_AUTO
- && (pedantic || current_binding_level == global_binding_level))
+ && (pedantic || current_scope == global_scope))
pedwarn ("function definition declared `auto'");
if (specbits & 1 << (int) RID_REGISTER)
error ("function definition declared `register'");
@@ -3925,16 +3724,16 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
}
else if (specbits & 1 << (int) RID_EXTERN && initialized && ! funcdef_flag)
{
- /* `extern' with initialization is invalid if not at top level. */
- if (current_binding_level == global_binding_level)
+ /* `extern' with initialization is invalid if not at file scope. */
+ if (current_scope == global_scope)
warning ("`%s' initialized and declared `extern'", name);
else
error ("`%s' has both `extern' and initializer", name);
}
- else if (current_binding_level == global_binding_level)
+ else if (current_scope == global_scope)
{
if (specbits & 1 << (int) RID_AUTO)
- error ("top-level declaration of `%s' specifies `auto'", name);
+ error ("file-scope declaration of `%s' specifies `auto'", name);
}
else
{
@@ -4038,7 +3837,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
type = error_mark_node;
}
- if (pedantic && flexible_array_type_p (type))
+ if (pedantic && !in_system_header && flexible_array_type_p (type))
pedwarn ("invalid use of structure with flexible array member");
if (size == error_mark_node)
@@ -4154,14 +3953,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
if (pedantic && !COMPLETE_TYPE_P (type))
pedwarn ("array type has incomplete element type");
-#if 0
- /* We shouldn't have a function type here at all!
- Functions aren't allowed as array elements. */
- if (pedantic && TREE_CODE (type) == FUNCTION_TYPE
- && (constp || volatilep))
- pedwarn ("ISO C forbids const or volatile function types");
-#endif
-
/* Build the array type itself, then merge any constancy or
volatility into the target type. We must do it in this order
to ensure that the TYPE_MAIN_VARIANT field of the array type
@@ -4229,7 +4020,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
{
/* Type qualifiers on a function return type are normally
permitted by the standard but have no effect, so give a
- warning at -W. Qualifiers on a void return type have
+ warning at -Wextra. Qualifiers on a void return type have
meaning as a GNU extension, and are banned on function
definitions in ISO C. FIXME: strictly we shouldn't
pedwarn for qualified void return types except on function
@@ -4312,12 +4103,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
if (erred)
error ("invalid type modifier within pointer declarator");
- if (constp > 1 && ! flag_isoc99)
- pedwarn ("duplicate `const'");
- if (volatilep > 1 && ! flag_isoc99)
- pedwarn ("duplicate `volatile'");
- if (restrictp > 1 && ! flag_isoc99)
- pedwarn ("duplicate `restrict'");
+ if (pedantic && !flag_isoc99)
+ {
+ if (constp > 1)
+ pedwarn ("duplicate `const'");
+ if (volatilep > 1)
+ pedwarn ("duplicate `volatile'");
+ if (restrictp > 1)
+ pedwarn ("duplicate `restrict'");
+ }
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
@@ -4405,7 +4199,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
if (VOID_TYPE_P (type) && decl_context != PARM
&& ! ((decl_context != FIELD && TREE_CODE (type) != FUNCTION_TYPE)
&& ((specbits & (1 << (int) RID_EXTERN))
- || (current_binding_level == global_binding_level
+ || (current_scope == global_scope
&& !(specbits
& ((1 << (int) RID_STATIC) | (1 << (int) RID_REGISTER)))))))
{
@@ -4486,7 +4280,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
}
else if (type_quals)
type = c_build_qualified_type (type, type_quals);
-
+
type_as_written = type;
decl = build_decl (PARM_DECL, declarator, type);
@@ -4523,15 +4317,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
}
/* Move type qualifiers down to element of an array. */
if (TREE_CODE (type) == ARRAY_TYPE && type_quals)
- {
- type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
- type_quals),
- TYPE_DOMAIN (type));
-#if 0
- /* Leave the field const or volatile as well. */
- type_quals = TYPE_UNQUALIFIED;
-#endif
- }
+ type = build_array_type (c_build_qualified_type (TREE_TYPE (type),
+ type_quals),
+ TYPE_DOMAIN (type));
decl = build_decl (FIELD_DECL, declarator, type);
DECL_NONADDRESSABLE_P (decl) = bitfield;
@@ -4546,19 +4334,19 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
That is a case not specified by ANSI C,
and we use it for forward declarations for nested functions. */
int extern_ref = (!(specbits & (1 << (int) RID_AUTO))
- || current_binding_level == global_binding_level);
+ || current_scope == global_scope);
if (specbits & (1 << (int) RID_AUTO)
- && (pedantic || current_binding_level == global_binding_level))
+ && (pedantic || current_scope == global_scope))
pedwarn ("invalid storage class for function `%s'", name);
if (specbits & (1 << (int) RID_REGISTER))
error ("invalid storage class for function `%s'", name);
if (specbits & (1 << (int) RID_THREAD))
error ("invalid storage class for function `%s'", name);
- /* Function declaration not at top level.
+ /* Function declaration not at file scope.
Storage classes other than `extern' are not allowed
and `extern' makes no difference. */
- if (current_binding_level != global_binding_level
+ if (current_scope != global_scope
&& (specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_INLINE)))
&& pedantic)
pedwarn ("invalid storage class for function `%s'", name);
@@ -4566,8 +4354,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
decl = build_decl (FUNCTION_DECL, declarator, type);
decl = build_decl_attribute_variant (decl, decl_attr);
- DECL_LANG_SPECIFIC (decl) = (struct lang_decl *)
- ggc_alloc_cleared (sizeof (struct lang_decl));
+ DECL_LANG_SPECIFIC (decl)
+ = ggc_alloc_cleared (sizeof (struct lang_decl));
if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl))
pedwarn ("ISO C forbids qualified function types");
@@ -4595,7 +4383,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
}
else if (inlinep)
{
- /* Assume that otherwise the function can be inlined. */
+ /* Record that the function is declared `inline'. */
DECL_DECLARED_INLINE_P (decl) = 1;
/* Do not mark bare declarations as DECL_INLINE. Doing so
@@ -4613,12 +4401,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
two things: let the function be deferred until it is actually
needed, and let dwarf2 know that the function is inlinable. */
else if (flag_inline_trees == 2 && initialized)
- {
- if (!DECL_INLINE (decl))
- DID_INLINE_FUNC (decl) = 1;
- DECL_INLINE (decl) = 1;
- DECL_DECLARED_INLINE_P (decl) = 0;
- }
+ DECL_INLINE (decl) = 1;
}
else
{
@@ -4634,33 +4417,46 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
type_quals),
TYPE_DOMAIN (type));
TYPE_ALIGN (type) = saved_align;
-#if 0 /* Leave the variable const or volatile as well. */
- type_quals = TYPE_UNQUALIFIED;
-#endif
}
else if (type_quals)
type = c_build_qualified_type (type, type_quals);
-
+
+ /* It is invalid to create an `extern' declaration for a
+ variable if there is a global declaration that is
+ `static' and the global declaration is not visible. */
+ if (extern_ref && current_scope != global_scope)
+ {
+ tree global_decl;
+
+ global_decl = identifier_global_value (declarator);
+ if (global_decl
+ && TREE_CODE (global_decl) == VAR_DECL
+ && lookup_name (declarator) != global_decl
+ && !TREE_PUBLIC (global_decl))
+ error ("variable previously declared `static' redeclared "
+ "`extern'");
+ }
+
decl = build_decl (VAR_DECL, declarator, type);
if (size_varies)
C_DECL_VARIABLE_SIZE (decl) = 1;
if (inlinep)
- pedwarn_with_decl (decl, "variable `%s' declared `inline'");
+ pedwarn ("%Jvariable '%D' declared `inline'", decl, decl);
DECL_EXTERNAL (decl) = extern_ref;
- /* At top level, the presence of a `static' or `register' storage
+ /* At file scope, the presence of a `static' or `register' storage
class specifier, or the absence of all storage class specifiers
makes this declaration a definition (perhaps tentative). Also,
the absence of both `static' and `register' makes it public. */
- if (current_binding_level == global_binding_level)
+ if (current_scope == global_scope)
{
TREE_PUBLIC (decl) = !(specbits & ((1 << (int) RID_STATIC)
| (1 << (int) RID_REGISTER)));
TREE_STATIC (decl) = !extern_ref;
}
- /* Not at top level, only `static' makes a static definition. */
+ /* Not at file scope, only `static' makes a static definition. */
else
{
TREE_STATIC (decl) = (specbits & (1 << (int) RID_STATIC)) != 0;
@@ -4693,6 +4489,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (decl)))
c_mark_addressable (decl);
+#ifdef ENABLE_CHECKING
+ /* This is the earliest point at which we might know the assembler
+ name of a variable. Thus, if it's known before this, die horribly. */
+ if (DECL_ASSEMBLER_NAME_SET_P (decl))
+ abort ();
+#endif
+
decl_attributes (&decl, returned_attrs, 0);
return decl;
@@ -4718,14 +4521,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
when FUNCDEF_FLAG is zero. */
static tree
-grokparms (parms_info, funcdef_flag)
- tree parms_info;
- int funcdef_flag;
+grokparms (tree parms_info, int funcdef_flag)
{
tree first_parm = TREE_CHAIN (parms_info);
last_function_parms = TREE_PURPOSE (parms_info);
last_function_parm_tags = TREE_VALUE (parms_info);
+ last_function_parm_others = TREE_TYPE (parms_info);
if (warn_strict_prototypes && first_parm == 0 && !funcdef_flag
&& !in_system_header)
@@ -4744,239 +4546,186 @@ grokparms (parms_info, funcdef_flag)
{
tree parm;
tree typelt;
- /* We no longer test FUNCDEF_FLAG.
- If the arg types are incomplete in a declaration,
+ /* If the arg types are incomplete in a declaration,
they must include undefined tags.
These tags can never be defined in the scope of the declaration,
so the types can never be completed,
and no call can be compiled successfully. */
-#if 0
- /* In a fcn definition, arg types must be complete. */
- if (funcdef_flag)
-#endif
- for (parm = last_function_parms, typelt = first_parm;
- parm;
- parm = TREE_CHAIN (parm))
- /* Skip over any enumeration constants declared here. */
- if (TREE_CODE (parm) == PARM_DECL)
- {
- /* Barf if the parameter itself has an incomplete type. */
- tree type = TREE_VALUE (typelt);
- if (type == error_mark_node)
- continue;
- if (!COMPLETE_TYPE_P (type))
- {
- if (funcdef_flag && DECL_NAME (parm) != 0)
- error ("parameter `%s' has incomplete type",
- IDENTIFIER_POINTER (DECL_NAME (parm)));
- else
- warning ("parameter has incomplete type");
- if (funcdef_flag)
- {
- TREE_VALUE (typelt) = error_mark_node;
- TREE_TYPE (parm) = error_mark_node;
- }
- }
-#if 0
- /* This has been replaced by parm_tags_warning, which
- uses a more accurate criterion for what to warn
- about. */
- else
- {
- /* Now warn if is a pointer to an incomplete type. */
- while (TREE_CODE (type) == POINTER_TYPE
- || TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
- type = TYPE_MAIN_VARIANT (type);
- if (!COMPLETE_TYPE_P (type))
- {
- if (DECL_NAME (parm) != 0)
- warning ("parameter `%s' points to incomplete type",
- IDENTIFIER_POINTER (DECL_NAME (parm)));
- else
- warning ("parameter points to incomplete type");
- }
- }
-#endif
- typelt = TREE_CHAIN (typelt);
- }
+
+ for (parm = last_function_parms, typelt = first_parm;
+ parm;
+ parm = TREE_CHAIN (parm))
+ /* Skip over any enumeration constants declared here. */
+ if (TREE_CODE (parm) == PARM_DECL)
+ {
+ /* Barf if the parameter itself has an incomplete type. */
+ tree type = TREE_VALUE (typelt);
+ if (type == error_mark_node)
+ continue;
+ if (!COMPLETE_TYPE_P (type))
+ {
+ if (funcdef_flag && DECL_NAME (parm) != 0)
+ error ("parameter `%s' has incomplete type",
+ IDENTIFIER_POINTER (DECL_NAME (parm)));
+ else
+ warning ("parameter has incomplete type");
+ if (funcdef_flag)
+ {
+ TREE_VALUE (typelt) = error_mark_node;
+ TREE_TYPE (parm) = error_mark_node;
+ }
+ }
+ typelt = TREE_CHAIN (typelt);
+ }
return first_parm;
}
}
/* Return a tree_list node with info on a parameter list just parsed.
- The TREE_PURPOSE is a chain of decls of those parms.
+ The TREE_PURPOSE is a list of decls of those parms.
The TREE_VALUE is a list of structure, union and enum tags defined.
The TREE_CHAIN is a list of argument types to go in the FUNCTION_TYPE.
+ The TREE_TYPE is a list of non-parameter decls which appeared with the
+ parameters.
This tree_list node is later fed to `grokparms'.
VOID_AT_END nonzero means append `void' to the end of the type-list.
Zero means the parmlist ended with an ellipsis so don't append `void'. */
tree
-get_parm_info (void_at_end)
- int void_at_end;
+get_parm_info (int void_at_end)
{
- tree decl, t;
+ tree decl, type, list;
tree types = 0;
- int erred = 0;
- tree tags = gettags ();
- tree parms = getdecls ();
- tree new_parms = 0;
- tree order = current_binding_level->parm_order;
-
- /* Just `void' (and no ellipsis) is special. There are really no parms.
- But if the `void' is qualified (by `const' or `volatile') or has a
- storage class specifier (`register'), then the behavior is undefined;
- by not counting it as the special case of `void' we will cause an
- error later. Typedefs for `void' are OK (see DR#157). */
+ tree *last_type = &types;
+ tree tags = current_scope->tags;
+ tree parms = current_scope->parms;
+ tree others = current_scope->names;
+ static bool explained_incomplete_types = false;
+ bool gave_void_only_once_err = false;
+
+ /* Just "void" (and no ellipsis) is special. There are really no parms.
+ But if the "void" is qualified (by "const" or "volatile"), or has a
+ storage class specifier ("register"), then the behavior is undefined;
+ issue an error. Typedefs for "void" are OK (see DR#157). */
if (void_at_end && parms != 0
&& TREE_CHAIN (parms) == 0
&& VOID_TYPE_P (TREE_TYPE (parms))
- && ! TREE_THIS_VOLATILE (parms)
- && ! TREE_READONLY (parms)
- && ! DECL_REGISTER (parms)
- && DECL_NAME (parms) == 0)
+ && !DECL_NAME (parms))
{
- parms = NULL_TREE;
- storedecls (NULL_TREE);
- return tree_cons (NULL_TREE, NULL_TREE,
- tree_cons (NULL_TREE, void_type_node, NULL_TREE));
+ if (TREE_THIS_VOLATILE (parms)
+ || TREE_READONLY (parms)
+ || DECL_REGISTER (parms))
+ error ("\"void\" as only parameter may not be qualified");
+
+ return tree_cons (0, 0, tree_cons (0, void_type_node, 0));
}
- /* Extract enumerator values and other non-parms declared with the parms.
- Likewise any forward parm decls that didn't have real parm decls. */
- for (decl = parms; decl;)
+ /* Sanity check all of the parameter declarations. */
+ for (decl = parms; decl; decl = TREE_CHAIN (decl))
{
- tree next = TREE_CHAIN (decl);
-
if (TREE_CODE (decl) != PARM_DECL)
+ abort ();
+ if (TREE_ASM_WRITTEN (decl))
+ abort ();
+
+ /* Since there is a prototype, args are passed in their
+ declared types. The back end may override this. */
+ type = TREE_TYPE (decl);
+ DECL_ARG_TYPE (decl) = type;
+
+ /* Check for (..., void, ...) and issue an error. */
+ if (VOID_TYPE_P (type) && !DECL_NAME (decl) && !gave_void_only_once_err)
{
- TREE_CHAIN (decl) = new_parms;
- new_parms = decl;
- }
- else if (TREE_ASM_WRITTEN (decl))
- {
- error_with_decl (decl,
- "parameter `%s' has just a forward declaration");
- TREE_CHAIN (decl) = new_parms;
- new_parms = decl;
+ error ("\"void\" must be the only parameter");
+ gave_void_only_once_err = true;
}
- decl = next;
- }
- /* Put the parm decls back in the order they were in in the parm list. */
- for (t = order; t; t = TREE_CHAIN (t))
- {
- if (TREE_CHAIN (t))
- TREE_CHAIN (TREE_VALUE (t)) = TREE_VALUE (TREE_CHAIN (t));
- else
- TREE_CHAIN (TREE_VALUE (t)) = 0;
+ type = build_tree_list (0, type);
+ *last_type = type;
+ last_type = &TREE_CHAIN (type);
}
- new_parms = chainon (order ? nreverse (TREE_VALUE (order)) : 0,
- new_parms);
-
- /* Store the parmlist in the binding level since the old one
- is no longer a valid list. (We have changed the chain pointers.) */
- storedecls (new_parms);
-
- for (decl = new_parms; decl; decl = TREE_CHAIN (decl))
- /* There may also be declarations for enumerators if an enumeration
- type is declared among the parms. Ignore them here. */
+ /* Check the list of non-parameter decls for any forward parm decls
+ that never got real decls. */
+ for (decl = others; decl; decl = TREE_CHAIN (decl))
if (TREE_CODE (decl) == PARM_DECL)
{
- /* Since there is a prototype,
- args are passed in their declared types. */
- tree type = TREE_TYPE (decl);
- DECL_ARG_TYPE (decl) = type;
- if (PROMOTE_PROTOTYPES
- && INTEGRAL_TYPE_P (type)
- && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
- DECL_ARG_TYPE (decl) = integer_type_node;
-
- types = tree_cons (NULL_TREE, TREE_TYPE (decl), types);
- if (VOID_TYPE_P (TREE_VALUE (types)) && ! erred
- && DECL_NAME (decl) == 0)
- {
- error ("`void' in parameter list must be the entire list");
- erred = 1;
- }
- }
-
- if (void_at_end)
- return tree_cons (new_parms, tags,
- nreverse (tree_cons (NULL_TREE, void_type_node, types)));
-
- return tree_cons (new_parms, tags, nreverse (types));
-}
-
-/* At end of parameter list, warn about any struct, union or enum tags
- defined within. Do so because these types cannot ever become complete. */
+ if (!TREE_ASM_WRITTEN (decl))
+ abort ();
-void
-parmlist_tags_warning ()
-{
- tree elt;
- static int already;
+ error ("%Jparameter \"%D\" has just a forward declaration",
+ decl, decl);
+ }
- for (elt = current_binding_level->tags; elt; elt = TREE_CHAIN (elt))
+ /* Warn about any struct, union or enum tags defined within this
+ list. The scope of such types is limited to this declaration,
+ which is rarely if ever desirable (it's impossible to call such
+ a function with type-correct arguments). */
+ for (decl = tags; decl; decl = TREE_CHAIN (decl))
{
- enum tree_code code = TREE_CODE (TREE_VALUE (elt));
+ enum tree_code code = TREE_CODE (TREE_VALUE (decl));
+ const char *keyword;
/* An anonymous union parm type is meaningful as a GNU extension.
So don't warn for that. */
- if (code == UNION_TYPE && TREE_PURPOSE (elt) == 0 && !pedantic)
+ if (code == UNION_TYPE && TREE_PURPOSE (decl) == 0 && !pedantic)
continue;
- if (TREE_PURPOSE (elt) != 0)
- {
- if (code == RECORD_TYPE)
- warning ("`struct %s' declared inside parameter list",
- IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
- else if (code == UNION_TYPE)
- warning ("`union %s' declared inside parameter list",
- IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
- else
- warning ("`enum %s' declared inside parameter list",
- IDENTIFIER_POINTER (TREE_PURPOSE (elt)));
- }
- else
+
+ /* The keyword should not be translated. */
+ switch (code)
{
- /* For translation these need to be separate warnings */
- if (code == RECORD_TYPE)
- warning ("anonymous struct declared inside parameter list");
- else if (code == UNION_TYPE)
- warning ("anonymous union declared inside parameter list");
- else
- warning ("anonymous enum declared inside parameter list");
+ case RECORD_TYPE: keyword = "struct"; break;
+ case UNION_TYPE: keyword = "union"; break;
+ case ENUMERAL_TYPE: keyword = "enum"; break;
+ default: abort ();
}
- if (! already)
+
+ if (TREE_PURPOSE (decl))
+ /* The first %s will be one of 'struct', 'union', or 'enum'. */
+ warning ("\"%s %s\" declared inside parameter list",
+ keyword, IDENTIFIER_POINTER (TREE_PURPOSE (decl)));
+ else
+ /* The %s will be one of 'struct', 'union', or 'enum'. */
+ warning ("anonymous %s declared inside parameter list", keyword);
+
+ if (! explained_incomplete_types)
{
- warning ("its scope is only this definition or declaration, which is probably not what you want");
- already = 1;
+ warning ("its scope is only this definition or declaration,"
+ " which is probably not what you want");
+ explained_incomplete_types = true;
}
}
+
+
+ if (void_at_end)
+ {
+ type = build_tree_list (0, void_type_node);
+ *last_type = type;
+ }
+
+ list = tree_cons (parms, tags, types);
+ TREE_TYPE (list) = others;
+ return list;
}
/* Get the struct, enum or union (CODE says which) with tag NAME.
Define the tag as a forward-reference if it is not defined. */
tree
-xref_tag (code, name)
- enum tree_code code;
- tree name;
+xref_tag (enum tree_code code, tree name)
{
/* If a cross reference is requested, look up the type
already defined for this tag and return it. */
- tree ref = lookup_tag (code, name, current_binding_level, 0);
+ tree ref = lookup_tag (code, name, 0);
/* If this is the right type of tag, return what we found.
(This reference will be shadowed by shadow_tag later if appropriate.)
If this is the wrong type of tag, do not return it. If it was the
- wrong type in the same binding level, we will have had an error
- message already; if in a different binding level and declaring
+ wrong type in the same scope, we will have had an error
+ message already; if in a different scope and declaring
a name, pending_xref_error will give an error message; but if in a
- different binding level and not declaring a name, this tag should
+ different scope and not declaring a name, this tag should
shadow the previous declaration of a different type of tag, and
this would not work properly if we return the reference found.
(For example, with "struct foo" in an outer scope, "union foo;"
@@ -5008,22 +4757,20 @@ xref_tag (code, name)
return ref;
}
-/* Make sure that the tag NAME is defined *in the current binding level*
+/* Make sure that the tag NAME is defined *in the current scope*
at least as a forward reference.
CODE says which kind of tag NAME ought to be. */
tree
-start_struct (code, name)
- enum tree_code code;
- tree name;
+start_struct (enum tree_code code, tree name)
{
- /* If there is already a tag defined at this binding level
+ /* If there is already a tag defined at this scope
(as a forward reference), just return it. */
tree ref = 0;
if (name != 0)
- ref = lookup_tag (code, name, current_binding_level, 1);
+ ref = lookup_tag (code, name, 1);
if (ref && TREE_CODE (ref) == code)
{
if (TYPE_FIELDS (ref))
@@ -5032,7 +4779,7 @@ start_struct (code, name)
error ("redefinition of `union %s'", IDENTIFIER_POINTER (name));
else
error ("redefinition of `struct %s'", IDENTIFIER_POINTER (name));
- }
+ }
}
else
{
@@ -5041,7 +4788,7 @@ start_struct (code, name)
ref = make_node (code);
pushtag (name, ref);
}
-
+
C_TYPE_BEING_DEFINED (ref) = 1;
TYPE_PACKED (ref) = flag_pack_struct;
return ref;
@@ -5049,17 +4796,14 @@ start_struct (code, name)
/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)
of a structure component, returning a FIELD_DECL node.
- WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node.
+ WIDTH is non-NULL for bit-fields only, and is an INTEGER_CST node.
This is done during the parsing of the struct declaration.
The FIELD_DECL nodes are chained together and the lot of them
are ultimately passed to `build_struct' to make the RECORD_TYPE node. */
tree
-grokfield (filename, line, declarator, declspecs, width)
- const char *filename ATTRIBUTE_UNUSED;
- int line ATTRIBUTE_UNUSED;
- tree declarator, declspecs, width;
+grokfield (tree declarator, tree declspecs, tree width)
{
tree value;
@@ -5080,7 +4824,7 @@ grokfield (filename, line, declarator, declspecs, width)
again this is an anonymous struct.
Otherwise this is an error.
- Oh what a horrid tangled web we weave. I wonder if MS consiously
+ Oh what a horrid tangled web we weave. I wonder if MS consciously
took this from Plan 9 or if it was an accident of implementation
that took root before someone noticed the bug... */
@@ -5107,50 +4851,81 @@ grokfield (filename, line, declarator, declspecs, width)
}
}
- value = grokdeclarator (declarator, declspecs, width ? BITFIELD : FIELD, 0);
+ value = grokdeclarator (declarator, declspecs, FIELD, 0,
+ width ? &width : NULL);
finish_decl (value, NULL_TREE, NULL_TREE);
DECL_INITIAL (value) = width;
- if (flag_objc)
- objc_check_decl (value);
return value;
}
-/* Function to help qsort sort FIELD_DECLs by name order. */
+/* Generate an error for any duplicate field names in FIELDLIST. Munge
+ the list such that this does not present a problem later. */
-
-static int
-field_decl_cmp (xp, yp)
- const PTR xp;
- const PTR yp;
+static void
+detect_field_duplicates (tree fieldlist)
{
- tree *x = (tree *)xp, *y = (tree *)yp;
-
- if (DECL_NAME (*x) == DECL_NAME (*y))
- return 0;
- if (DECL_NAME (*x) == NULL)
- return -1;
- if (DECL_NAME (*y) == NULL)
- return 1;
- if (DECL_NAME (*x) < DECL_NAME (*y))
- return -1;
- return 1;
+ tree x, y;
+ int timeout = 10;
+
+ /* First, see if there are more than "a few" fields.
+ This is trivially true if there are zero or one fields. */
+ if (!fieldlist)
+ return;
+ x = TREE_CHAIN (fieldlist);
+ if (!x)
+ return;
+ do {
+ timeout--;
+ x = TREE_CHAIN (x);
+ } while (timeout > 0 && x);
+
+ /* If there were "few" fields, avoid the overhead of allocating
+ a hash table. Instead just do the nested traversal thing. */
+ if (timeout > 0)
+ {
+ for (x = TREE_CHAIN (fieldlist); x ; x = TREE_CHAIN (x))
+ if (DECL_NAME (x))
+ {
+ for (y = fieldlist; y != x; y = TREE_CHAIN (y))
+ if (DECL_NAME (y) == DECL_NAME (x))
+ {
+ error ("%Jduplicate member '%D'", x, x);
+ DECL_NAME (x) = NULL_TREE;
+ }
+ }
+ }
+ else
+ {
+ htab_t htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
+ void **slot;
+
+ for (x = fieldlist; x ; x = TREE_CHAIN (x))
+ if ((y = DECL_NAME (x)) != 0)
+ {
+ slot = htab_find_slot (htab, y, INSERT);
+ if (*slot)
+ {
+ error ("%Jduplicate member '%D'", x, x);
+ DECL_NAME (x) = NULL_TREE;
+ }
+ *slot = y;
+ }
+
+ htab_delete (htab);
+ }
}
-
-
+
/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
FIELDLIST is a chain of FIELD_DECL nodes for the fields.
ATTRIBUTES are attributes to be applied to the structure. */
tree
-finish_struct (t, fieldlist, attributes)
- tree t;
- tree fieldlist;
- tree attributes;
+finish_struct (tree t, tree fieldlist, tree attributes)
{
tree x;
- int toplevel = global_binding_level == current_binding_level;
+ int toplevel = global_scope == current_scope;
int saw_named_field;
/* If this type was previously laid out as a forward reference,
@@ -5224,91 +4999,12 @@ finish_struct (t, fieldlist, attributes)
error ("nested redefinition of `%s'",
IDENTIFIER_POINTER (TYPE_NAME (t)));
- /* Detect invalid bit-field size. */
- if (DECL_INITIAL (x))
- STRIP_NOPS (DECL_INITIAL (x));
if (DECL_INITIAL (x))
{
- if (TREE_CODE (DECL_INITIAL (x)) == INTEGER_CST)
- constant_expression_warning (DECL_INITIAL (x));
- else
- {
- error_with_decl (x,
- "bit-field `%s' width not an integer constant");
- DECL_INITIAL (x) = NULL;
- }
- }
-
- /* Detect invalid bit-field type. */
- if (DECL_INITIAL (x)
- && TREE_CODE (TREE_TYPE (x)) != INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE
- && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE)
- {
- error_with_decl (x, "bit-field `%s' has invalid type");
- DECL_INITIAL (x) = NULL;
- }
-
- if (DECL_INITIAL (x) && pedantic
- && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != integer_type_node
- && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != unsigned_type_node
- && TYPE_MAIN_VARIANT (TREE_TYPE (x)) != c_bool_type_node
- /* Accept an enum that's equivalent to int or unsigned int. */
- && !(TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
- && (TYPE_PRECISION (TREE_TYPE (x))
- == TYPE_PRECISION (integer_type_node))))
- pedwarn_with_decl (x, "bit-field `%s' type invalid in ISO C");
-
- /* Detect and ignore out of range field width and process valid
- field widths. */
- if (DECL_INITIAL (x))
- {
- int max_width
- = (TYPE_MAIN_VARIANT (TREE_TYPE (x)) == c_bool_type_node
- ? CHAR_TYPE_SIZE : TYPE_PRECISION (TREE_TYPE (x)));
-
- if (tree_int_cst_sgn (DECL_INITIAL (x)) < 0)
- error_with_decl (x, "negative width in bit-field `%s'");
- else if (0 < compare_tree_int (DECL_INITIAL (x), max_width))
- pedwarn_with_decl (x, "width of `%s' exceeds its type");
- else if (integer_zerop (DECL_INITIAL (x)) && DECL_NAME (x) != 0)
- error_with_decl (x, "zero width for bit-field `%s'");
- else
- {
- /* The test above has assured us that TREE_INT_CST_HIGH is 0. */
- unsigned HOST_WIDE_INT width
- = tree_low_cst (DECL_INITIAL (x), 1);
-
- if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
- && (width < min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)),
- TREE_UNSIGNED (TREE_TYPE (x)))
- || (width
- < min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
- TREE_UNSIGNED (TREE_TYPE (x))))))
- warning_with_decl (x,
- "`%s' is narrower than values of its type");
-
- DECL_SIZE (x) = bitsize_int (width);
- DECL_BIT_FIELD (x) = 1;
- SET_DECL_C_BIT_FIELD (x);
-
- if (width == 0
- && ! (* targetm.ms_bitfield_layout_p) (t))
- {
- /* field size 0 => force desired amount of alignment. */
-#ifdef EMPTY_FIELD_BOUNDARY
- DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY);
-#endif
-#ifdef PCC_BITFIELD_TYPE_MATTERS
- if (PCC_BITFIELD_TYPE_MATTERS)
- {
- DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
- TYPE_ALIGN (TREE_TYPE (x)));
- DECL_USER_ALIGN (x) |= TYPE_USER_ALIGN (TREE_TYPE (x));
- }
-#endif
- }
- }
+ unsigned HOST_WIDE_INT width = tree_low_cst (DECL_INITIAL (x), 1);
+ DECL_SIZE (x) = bitsize_int (width);
+ DECL_BIT_FIELD (x) = 1;
+ SET_DECL_C_BIT_FIELD (x);
}
DECL_INITIAL (x) = 0;
@@ -5320,46 +5016,31 @@ finish_struct (t, fieldlist, attributes)
&& TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (x))) == NULL_TREE)
{
if (TREE_CODE (t) == UNION_TYPE)
- error_with_decl (x, "flexible array member in union");
+ {
+ error ("%Jflexible array member in union", x);
+ TREE_TYPE (x) = error_mark_node;
+ }
else if (TREE_CHAIN (x) != NULL_TREE)
- error_with_decl (x, "flexible array member not at end of struct");
+ {
+ error ("%Jflexible array member not at end of struct", x);
+ TREE_TYPE (x) = error_mark_node;
+ }
else if (! saw_named_field)
- error_with_decl (x, "flexible array member in otherwise empty struct");
+ {
+ error ("%Jflexible array member in otherwise empty struct", x);
+ TREE_TYPE (x) = error_mark_node;
+ }
}
- if (pedantic && TREE_CODE (t) == RECORD_TYPE
+ if (pedantic && !in_system_header && TREE_CODE (t) == RECORD_TYPE
&& flexible_array_type_p (TREE_TYPE (x)))
- pedwarn_with_decl (x, "invalid use of structure with flexible array member");
+ pedwarn ("%Jinvalid use of structure with flexible array member", x);
if (DECL_NAME (x))
saw_named_field = 1;
}
- /* Delete all duplicate fields from the fieldlist */
- for (x = fieldlist; x && TREE_CHAIN (x);)
- /* Anonymous fields aren't duplicates. */
- if (DECL_NAME (TREE_CHAIN (x)) == 0)
- x = TREE_CHAIN (x);
- else
- {
- tree y = fieldlist;
-
- while (1)
- {
- if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
- break;
- if (y == x)
- break;
- y = TREE_CHAIN (y);
- }
- if (DECL_NAME (y) == DECL_NAME (TREE_CHAIN (x)))
- {
- error_with_decl (TREE_CHAIN (x), "duplicate member `%s'");
- TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x));
- }
- else
- x = TREE_CHAIN (x);
- }
+ detect_field_duplicates (fieldlist);
/* Now we have the nearly final fieldlist. Record it,
then lay out the structure or union (including the fields). */
@@ -5368,7 +5049,7 @@ finish_struct (t, fieldlist, attributes)
layout_type (t);
- /* Delete all zero-width bit-fields from the fieldlist */
+ /* Delete all zero-width bit-fields from the fieldlist. */
{
tree *fieldlistp = &fieldlist;
while (*fieldlistp)
@@ -5384,7 +5065,7 @@ finish_struct (t, fieldlist, attributes)
TYPE_FIELDS (t) = fieldlist;
/* If there are lots of fields, sort so we can look through them fast.
- We arbitrarily consider 16 or more elts to be "a lot". */
+ We arbitrarily consider 16 or more elts to be "a lot". */
{
int len = 0;
@@ -5399,37 +5080,40 @@ finish_struct (t, fieldlist, attributes)
if (len > 15)
{
tree *field_array;
- char *space;
-
+ struct lang_type *space;
+ struct sorted_fields_type *space2;
+
len += list_length (x);
-
+
/* Use the same allocation policy here that make_node uses, to
ensure that this lives as long as the rest of the struct decl.
All decls in an inline function need to be saved. */
-
- space = ggc_alloc (sizeof (struct lang_type) + len * sizeof (tree));
-
+
+ space = ggc_alloc (sizeof (struct lang_type));
+ space2 = ggc_alloc (sizeof (struct sorted_fields_type) + len * sizeof (tree));
+
len = 0;
- field_array = &(((struct lang_type *) space)->elts[0]);
+ space->s = space2;
+ field_array = &space2->elts[0];
for (x = fieldlist; x; x = TREE_CHAIN (x))
{
field_array[len++] = x;
-
- /* if there is anonymous struct or unoin break out of the loop */
+
+ /* If there is anonymous struct or union, break out of the loop. */
if (DECL_NAME (x) == NULL)
break;
}
- /* found no anonymous struct/union add the TYPE_LANG_SPECIFIC. */
+ /* Found no anonymous struct/union. Add the TYPE_LANG_SPECIFIC. */
if (x == NULL)
{
- TYPE_LANG_SPECIFIC (t) = (struct lang_type *) space;
- TYPE_LANG_SPECIFIC (t)->len = len;
- field_array = &TYPE_LANG_SPECIFIC (t)->elts[0];
+ TYPE_LANG_SPECIFIC (t) = space;
+ TYPE_LANG_SPECIFIC (t)->s->len = len;
+ field_array = TYPE_LANG_SPECIFIC (t)->s->elts;
qsort (field_array, len, sizeof (tree), field_decl_cmp);
}
}
}
-
+
for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
{
TYPE_FIELDS (x) = TYPE_FIELDS (t);
@@ -5450,63 +5134,24 @@ finish_struct (t, fieldlist, attributes)
/* If this structure or union completes the type of any previous
variable declaration, lay it out and output its rtl. */
-
- if (current_binding_level->incomplete_list != NULL_TREE)
+ for (x = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
+ x;
+ x = TREE_CHAIN (x))
{
- tree prev = NULL_TREE;
-
- for (x = current_binding_level->incomplete_list; x; x = TREE_CHAIN (x))
- {
- tree decl = TREE_VALUE (x);
-
- if (TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == TYPE_MAIN_VARIANT (t)
- && TREE_CODE (decl) != TYPE_DECL)
- {
- layout_decl (decl, 0);
- /* This is a no-op in c-lang.c or something real in
- objc-act.c. */
- if (flag_objc)
- objc_check_decl (decl);
- rest_of_decl_compilation (decl, NULL, toplevel, 0);
- if (! toplevel)
- expand_decl (decl);
- /* Unlink X from the incomplete list. */
- if (prev)
- TREE_CHAIN (prev) = TREE_CHAIN (x);
- else
- current_binding_level->incomplete_list = TREE_CHAIN (x);
- }
- else if (!COMPLETE_TYPE_P (TREE_TYPE (decl))
- && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
- {
- tree element = TREE_TYPE (decl);
- while (TREE_CODE (element) == ARRAY_TYPE)
- element = TREE_TYPE (element);
- if (element == t)
- {
- layout_array_type (TREE_TYPE (decl));
- if (TREE_CODE (decl) != TYPE_DECL)
- {
- layout_decl (decl, 0);
- if (flag_objc)
- objc_check_decl (decl);
- rest_of_decl_compilation (decl, NULL, toplevel, 0);
- if (! toplevel)
- expand_decl (decl);
- }
- /* Unlink X from the incomplete list. */
- if (prev)
- TREE_CHAIN (prev) = TREE_CHAIN (x);
- else
- current_binding_level->incomplete_list = TREE_CHAIN (x);
- }
- else
- prev = x;
- }
- else
- prev = x;
+ tree decl = TREE_VALUE (x);
+ if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
+ layout_array_type (TREE_TYPE (decl));
+ if (TREE_CODE (decl) != TYPE_DECL)
+ {
+ layout_decl (decl, 0);
+ if (c_dialect_objc ())
+ objc_check_decl (decl);
+ rest_of_decl_compilation (decl, NULL, toplevel, 0);
+ if (! toplevel)
+ expand_decl (decl);
}
}
+ C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t)) = 0;
/* Finish debugging output for this type. */
rest_of_type_compilation (t, toplevel);
@@ -5517,8 +5162,7 @@ finish_struct (t, fieldlist, attributes)
/* Lay out the type T, and its element type, and so on. */
static void
-layout_array_type (t)
- tree t;
+layout_array_type (tree t)
{
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
layout_array_type (TREE_TYPE (t));
@@ -5532,8 +5176,7 @@ layout_array_type (t)
may be used to declare the individual values as they are read. */
tree
-start_enum (name)
- tree name;
+start_enum (tree name)
{
tree enumtype = 0;
@@ -5542,7 +5185,7 @@ start_enum (name)
forward reference. */
if (name != 0)
- enumtype = lookup_tag (ENUMERAL_TYPE, name, current_binding_level, 1);
+ enumtype = lookup_tag (ENUMERAL_TYPE, name, 1);
if (enumtype == 0 || TREE_CODE (enumtype) != ENUMERAL_TYPE)
{
@@ -5578,15 +5221,12 @@ start_enum (name)
Returns ENUMTYPE. */
tree
-finish_enum (enumtype, values, attributes)
- tree enumtype;
- tree values;
- tree attributes;
+finish_enum (tree enumtype, tree values, tree attributes)
{
tree pair, tem;
tree minnode = 0, maxnode = 0, enum_value_type;
int precision, unsign;
- int toplevel = (global_binding_level == current_binding_level);
+ int toplevel = (global_scope == current_scope);
if (in_parm_level_p ())
warning ("enum defined inside parms");
@@ -5657,11 +5297,6 @@ finish_enum (enumtype, values, attributes)
tree enu = TREE_PURPOSE (pair);
TREE_TYPE (enu) = enumtype;
- DECL_SIZE (enu) = TYPE_SIZE (enumtype);
- DECL_SIZE_UNIT (enu) = TYPE_SIZE_UNIT (enumtype);
- DECL_ALIGN (enu) = TYPE_ALIGN (enumtype);
- DECL_USER_ALIGN (enu) = TYPE_USER_ALIGN (enumtype);
- DECL_MODE (enu) = TYPE_MODE (enumtype);
/* The ISO C Standard mandates enumerators to have type int,
even though the underlying type of an enum type is
@@ -5711,8 +5346,7 @@ finish_enum (enumtype, values, attributes)
Assignment of sequential values by default is handled here. */
tree
-build_enumerator (name, value)
- tree name, value;
+build_enumerator (tree name, tree value)
{
tree decl, type;
@@ -5787,8 +5421,7 @@ build_enumerator (name, value)
yyparse to report a parse error. */
int
-start_function (declspecs, declarator, attributes)
- tree declarator, declspecs, attributes;
+start_function (tree declspecs, tree declarator, tree attributes)
{
tree decl1, old_decl;
tree restype;
@@ -5799,13 +5432,13 @@ start_function (declspecs, declarator, attributes)
current_function_returns_abnormally = 0;
warn_about_return_type = 0;
current_extern_inline = 0;
- named_labels = 0;
- shadowed_labels = 0;
+ c_in_iteration_stmt = 0;
+ c_in_case_stmt = 0;
/* Don't expand any sizes in the return type of the function. */
immediate_size_expand = 0;
- decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1);
+ decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL);
/* If the declarator is not suitable for a function definition,
cause a syntax error. */
@@ -5817,15 +5450,10 @@ start_function (declspecs, declarator, attributes)
decl_attributes (&decl1, attributes, 0);
- /* If #pragma weak was used, mark the decl weak now. */
- if (current_binding_level == global_binding_level)
- maybe_apply_pragma_weak (decl1);
-
if (DECL_DECLARED_INLINE_P (decl1)
&& DECL_UNINLINABLE (decl1)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl1)))
- warning_with_decl (decl1,
- "inline function `%s' given attribute noinline");
+ warning ("%Jinline function '%D' given attribute noinline", decl1, decl1);
announce_function (decl1);
@@ -5845,6 +5473,7 @@ start_function (declspecs, declarator, attributes)
where store_parm_decls will find them. */
current_function_parms = last_function_parms;
current_function_parm_tags = last_function_parm_tags;
+ current_function_parm_others = last_function_parm_others;
/* Make the init_value nonzero so pushdecl knows this is not tentative.
error_mark_node is replaced below (in poplevel) with the BLOCK. */
@@ -5861,52 +5490,40 @@ start_function (declspecs, declarator, attributes)
&& TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0)
{
TREE_TYPE (decl1) = TREE_TYPE (old_decl);
- current_function_prototype_file = DECL_SOURCE_FILE (old_decl);
- current_function_prototype_line = DECL_SOURCE_LINE (old_decl);
+ current_function_prototype_locus = DECL_SOURCE_LOCATION (old_decl);
}
- /* If there is no explicit declaration, look for any out-of-scope implicit
- declarations. */
- if (old_decl == 0)
- old_decl = IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1));
-
/* Optionally warn of old-fashioned def with no previous prototype. */
if (warn_strict_prototypes
&& TYPE_ARG_TYPES (TREE_TYPE (decl1)) == 0
- && !(old_decl != 0
- && (TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0
- || (DECL_BUILT_IN (old_decl)
- && ! C_DECL_ANTICIPATED (old_decl)))))
+ && C_DECL_ISNT_PROTOTYPE (old_decl))
warning ("function declaration isn't a prototype");
/* Optionally warn of any global def with no previous prototype. */
else if (warn_missing_prototypes
&& TREE_PUBLIC (decl1)
- && !(old_decl != 0
- && (TYPE_ARG_TYPES (TREE_TYPE (old_decl)) != 0
- || (DECL_BUILT_IN (old_decl)
- && ! C_DECL_ANTICIPATED (old_decl))))
- && ! MAIN_NAME_P (DECL_NAME (decl1)))
- warning_with_decl (decl1, "no previous prototype for `%s'");
+ && ! MAIN_NAME_P (DECL_NAME (decl1))
+ && C_DECL_ISNT_PROTOTYPE (old_decl))
+ warning ("%Jno previous prototype for '%D'", decl1, decl1);
/* Optionally warn of any def with no previous prototype
if the function has already been used. */
else if (warn_missing_prototypes
&& old_decl != 0 && TREE_USED (old_decl)
&& TYPE_ARG_TYPES (TREE_TYPE (old_decl)) == 0)
- warning_with_decl (decl1,
- "`%s' was used with no prototype before its definition");
+ warning ("%J'%D' was used with no prototype before its definition",
+ decl1, 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_with_decl (decl1, "no previous declaration for `%s'");
+ warning ("%Jno previous declaration for '%D'", decl1, decl1);
/* Optionally warn of any def with no previous declaration
if the function has already been used. */
else if (warn_missing_declarations
&& old_decl != 0 && TREE_USED (old_decl)
- && old_decl == IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)))
- warning_with_decl (decl1,
- "`%s' was used with no declaration before its definition");
+ && C_DECL_IMPLICIT (old_decl))
+ warning ("%J`%D' was used with no declaration before its definition",
+ decl1, decl1);
/* This is a definition, not a reference.
So normally clear DECL_EXTERNAL.
@@ -5922,6 +5539,17 @@ start_function (declspecs, declarator, attributes)
if (current_function_decl != 0)
TREE_PUBLIC (decl1) = 0;
+#ifdef ENABLE_CHECKING
+ /* This is the earliest point at which we might know the assembler
+ name of the function. Thus, if it's set before this, die horribly. */
+ if (DECL_ASSEMBLER_NAME_SET_P (decl1))
+ abort ();
+#endif
+
+ /* If #pragma weak was used, mark the decl weak now. */
+ if (current_scope == global_scope)
+ maybe_apply_pragma_weak (decl1);
+
/* Warn for unlikely, improbable, or stupid declarations of `main'. */
if (warn_main > 0 && MAIN_NAME_P (DECL_NAME (decl1)))
{
@@ -5930,7 +5558,7 @@ start_function (declspecs, declarator, attributes)
if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl1)))
!= integer_type_node)
- pedwarn_with_decl (decl1, "return type of `%s' is not `int'");
+ pedwarn ("%Jreturn type of '%D' is not `int'", decl1, decl1);
for (args = TYPE_ARG_TYPES (TREE_TYPE (decl1)); args;
args = TREE_CHAIN (args))
@@ -5945,8 +5573,8 @@ start_function (declspecs, declarator, attributes)
{
case 1:
if (TYPE_MAIN_VARIANT (type) != integer_type_node)
- pedwarn_with_decl (decl1,
- "first argument of `%s' should be `int'");
+ pedwarn ("%Jfirst argument of '%D' should be `int'",
+ decl1, decl1);
break;
case 2:
@@ -5954,8 +5582,8 @@ start_function (declspecs, declarator, attributes)
|| TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
!= char_type_node))
- pedwarn_with_decl (decl1,
- "second argument of `%s' should be `char **'");
+ pedwarn ("%Jsecond argument of '%D' should be 'char **'",
+ decl1, decl1);
break;
case 3:
@@ -5963,8 +5591,8 @@ start_function (declspecs, declarator, attributes)
|| TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
|| (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
!= char_type_node))
- pedwarn_with_decl (decl1,
- "third argument of `%s' should probably be `char **'");
+ pedwarn ("%Jthird argument of '%D' should probably be "
+ "'char **'", decl1, decl1);
break;
}
}
@@ -5973,10 +5601,10 @@ start_function (declspecs, declarator, attributes)
argument because it's only mentioned in an appendix of the
standard. */
if (argct > 0 && (argct < 2 || argct > 3))
- pedwarn_with_decl (decl1, "`%s' takes only zero or two arguments");
+ pedwarn ("%J'%D' takes only zero or two arguments", decl1, decl1);
if (! TREE_PUBLIC (decl1))
- pedwarn_with_decl (decl1, "`%s' is normally a non-static function");
+ pedwarn ("%J'%D' is normally a non-static function", decl1, decl1);
}
/* Record the decl so that the function name is defined.
@@ -5986,8 +5614,7 @@ start_function (declspecs, declarator, attributes)
current_function_decl = pushdecl (decl1);
pushlevel (0);
- declare_parm_level (1);
- current_binding_level->subblocks_tag_transparent = 1;
+ declare_parm_level ();
make_decl_rtl (current_function_decl, NULL);
@@ -6014,398 +5641,335 @@ start_function (declspecs, declarator, attributes)
immediate_size_expand = old_immediate_size_expand;
start_fname_decls ();
-
+
return 1;
}
-/* Store the parameter declarations into the current function declaration.
- This is called after parsing the parameter declarations, before
- digesting the body of the function.
-
- For an old-style definition, modify the function's type
- to specify at least the number of arguments. */
-
-void
-store_parm_decls ()
+/* Subroutine of store_parm_decls which handles new-style function
+ definitions (prototype format). The parms already have decls, so we
+ need only record them as in effect and complain if any redundant
+ old-style parm decls were written. */
+static void
+store_parm_decls_newstyle (void)
{
+ tree decl, last;
tree fndecl = current_function_decl;
- tree parm;
-
- /* This is either a chain of PARM_DECLs (if a prototype was used)
- or a list of IDENTIFIER_NODEs (for an old-fashioned C definition). */
- tree specparms = current_function_parms;
-
- /* This is a list of types declared among parms in a prototype. */
- tree parmtags = current_function_parm_tags;
-
- /* This is a chain of PARM_DECLs from old-style parm declarations. */
- tree parmdecls = getdecls ();
-
- /* This is a chain of any other decls that came in among the parm
- declarations. If a parm is declared with enum {foo, bar} x;
- then CONST_DECLs for foo and bar are put here. */
- tree nonparms = 0;
-
- /* The function containing FNDECL, if any. */
- tree context = decl_function_context (fndecl);
-
- /* Nonzero if this definition is written with a prototype. */
- int prototype = 0;
-
- int saved_warn_shadow = warn_shadow;
+ tree parms = current_function_parms;
+ tree tags = current_function_parm_tags;
+ tree others = current_function_parm_others;
- /* Don't re-emit shadow warnings. */
- warn_shadow = 0;
-
- if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST)
+ if (current_scope->parms || current_scope->names || current_scope->tags)
{
- /* This case is when the function was defined with an ANSI prototype.
- The parms already have decls, so we need not do anything here
- except record them as in effect
- and complain if any redundant old-style parm decls were written. */
-
- tree next;
- tree others = 0;
+ error ("%Jold-style parameter declarations in prototyped "
+ "function definition", fndecl);
- prototype = 1;
+ /* Get rid of the old-style declarations. */
+ poplevel (0, 0, 0);
+ pushlevel (0);
+ }
- if (parmdecls != 0)
+ /* Now make all the parameter declarations visible in the function body.
+ We can bypass most of the grunt work of pushdecl. */
+ for (last = 0, decl = parms; decl; last = decl, decl = TREE_CHAIN (decl))
+ {
+ DECL_CONTEXT (decl) = current_function_decl;
+ if (DECL_NAME (decl) == 0)
+ error ("%Jparameter name omitted", decl);
+ else
{
- tree decl, link;
-
- error_with_decl (fndecl,
- "parm types given both in parmlist and separately");
- /* Get rid of the erroneous decls; don't keep them on
- the list of parms, since they might not be PARM_DECLs. */
- for (decl = current_binding_level->names;
- decl; decl = TREE_CHAIN (decl))
- if (DECL_NAME (decl))
- IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)) = 0;
- for (link = current_binding_level->shadowed;
- link; link = TREE_CHAIN (link))
- IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link);
- current_binding_level->names = 0;
- current_binding_level->shadowed = 0;
- }
-
- specparms = nreverse (specparms);
- for (parm = specparms; parm; parm = next)
- {
- next = TREE_CHAIN (parm);
- if (TREE_CODE (parm) == PARM_DECL)
- {
- if (DECL_NAME (parm) == 0)
- error_with_decl (parm, "parameter name omitted");
- else if (TREE_CODE (TREE_TYPE (parm)) != ERROR_MARK
- && VOID_TYPE_P (TREE_TYPE (parm)))
- {
- error_with_decl (parm, "parameter `%s' declared void");
- /* Change the type to error_mark_node so this parameter
- will be ignored by assign_parms. */
- TREE_TYPE (parm) = error_mark_node;
- }
- pushdecl (parm);
- }
- else
- {
- /* If we find an enum constant or a type tag,
- put it aside for the moment. */
- TREE_CHAIN (parm) = 0;
- others = chainon (others, parm);
- }
+ if (IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)))
+ current_scope->shadowed
+ = tree_cons (DECL_NAME (decl),
+ IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)),
+ current_scope->shadowed);
+ IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)) = decl;
}
+ }
+ current_scope->parms = parms;
+ current_scope->parms_last = last;
- /* Get the decls in their original chain order
- and record in the function. */
- DECL_ARGUMENTS (fndecl) = getdecls ();
+ /* Record the parameter list in the function declaration. */
+ DECL_ARGUMENTS (fndecl) = parms;
-#if 0
- /* If this function takes a variable number of arguments,
- add a phony parameter to the end of the parm list,
- to represent the position of the first unnamed argument. */
- if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
- != void_type_node)
+ /* Now make all the ancillary declarations visible, likewise. */
+ for (last = 0, decl = others; decl; last = decl, decl = TREE_CHAIN (decl))
+ {
+ DECL_CONTEXT (decl) = current_function_decl;
+ if (DECL_NAME (decl)
+ && TYPE_MAIN_VARIANT (TREE_TYPE (decl)) != void_type_node)
{
- tree dummy = build_decl (PARM_DECL, NULL_TREE, void_type_node);
- /* Let's hope the address of the unnamed parm
- won't depend on its type. */
- TREE_TYPE (dummy) = integer_type_node;
- DECL_ARG_TYPE (dummy) = integer_type_node;
- DECL_ARGUMENTS (fndecl) = chainon (DECL_ARGUMENTS (fndecl), dummy);
+ if (IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)))
+ current_scope->shadowed
+ = tree_cons (DECL_NAME (decl),
+ IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)),
+ current_scope->shadowed);
+ IDENTIFIER_SYMBOL_VALUE (DECL_NAME (decl)) = decl;
}
-#endif
+ }
+ current_scope->names = others;
+ current_scope->names_last = last;
- /* Now pushdecl the enum constants. */
- for (parm = others; parm; parm = next)
- {
- next = TREE_CHAIN (parm);
- if (DECL_NAME (parm) == 0)
- ;
- else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node)
- ;
- else if (TREE_CODE (parm) != PARM_DECL)
- pushdecl (parm);
- }
+ /* And all the tag declarations. */
+ for (decl = tags; decl; decl = TREE_CHAIN (decl))
+ if (TREE_PURPOSE (decl))
+ {
+ if (IDENTIFIER_TAG_VALUE (TREE_PURPOSE (decl)))
+ current_scope->shadowed_tags
+ = tree_cons (TREE_PURPOSE (decl),
+ IDENTIFIER_SYMBOL_VALUE (TREE_PURPOSE (decl)),
+ current_scope->shadowed_tags);
+ IDENTIFIER_TAG_VALUE (TREE_PURPOSE (decl)) = TREE_VALUE (decl);
+ }
+ current_scope->tags = tags;
+}
- storetags (chainon (parmtags, gettags ()));
- }
- else
- {
- /* SPECPARMS is an identifier list--a chain of TREE_LIST nodes
- each with a parm name as the TREE_VALUE.
+/* Subroutine of store_parm_decls which handles old-style function
+ definitions (separate parameter list and declarations). */
- PARMDECLS is a chain of declarations for parameters.
- Warning! It can also contain CONST_DECLs which are not parameters
- but are names of enumerators of any enum types
- declared among the parameters.
+static void
+store_parm_decls_oldstyle (void)
+{
+ tree parm, decl, last;
+ tree fndecl = current_function_decl;
- First match each formal parameter name with its declaration.
- Associate decls with the names and store the decls
- into the TREE_PURPOSE slots. */
+ /* This is the identifier list from the function declarator. */
+ tree parmids = current_function_parms;
- /* We use DECL_WEAK as a flag to show which parameters have been
- seen already since it is not used on PARM_DECL or CONST_DECL. */
- for (parm = parmdecls; parm; parm = TREE_CHAIN (parm))
- DECL_WEAK (parm) = 0;
+ /* We use DECL_WEAK as a flag to show which parameters have been
+ seen already, since it is not used on PARM_DECL. */
+#ifdef ENABLE_CHECKING
+ for (parm = current_scope->parms; parm; parm = TREE_CHAIN (parm))
+ if (DECL_WEAK (parm))
+ abort ();
+#endif
- for (parm = specparms; parm; parm = TREE_CHAIN (parm))
+ /* Match each formal parameter name with its declaration. Save each
+ decl in the appropriate TREE_PURPOSE slot of the parmids chain. */
+ for (parm = parmids; parm; parm = TREE_CHAIN (parm))
+ {
+ if (TREE_VALUE (parm) == 0)
{
- tree tail, found = NULL;
+ error ("%Jparameter name missing from parameter list", fndecl);
+ TREE_PURPOSE (parm) = 0;
+ continue;
+ }
- if (TREE_VALUE (parm) == 0)
+ decl = IDENTIFIER_SYMBOL_VALUE (TREE_VALUE (parm));
+ if (decl && DECL_CONTEXT (decl) == fndecl)
+ {
+ /* If we got something other than a PARM_DECL it is an error. */
+ if (TREE_CODE (decl) != PARM_DECL)
+ error ("%J\"%D\" declared as a non-parameter", decl, decl);
+ /* If the declaration is already marked, we have a duplicate
+ name. Complain and ignore the duplicate. */
+ else if (DECL_WEAK (decl))
{
- error_with_decl (fndecl,
- "parameter name missing from parameter list");
+ error ("%Jmultiple parameters named \"%D\"", decl, decl);
TREE_PURPOSE (parm) = 0;
continue;
}
-
- /* See if any of the parmdecls specifies this parm by name.
- Ignore any enumerator decls. */
- for (tail = parmdecls; tail; tail = TREE_CHAIN (tail))
- if (DECL_NAME (tail) == TREE_VALUE (parm)
- && TREE_CODE (tail) == PARM_DECL)
- {
- found = tail;
- break;
- }
-
- /* If declaration already marked, we have a duplicate name.
- Complain, and don't use this decl twice. */
- if (found && DECL_WEAK (found))
+ /* If the declaration says "void", complain and turn it into
+ an int. */
+ else if (VOID_TYPE_P (TREE_TYPE (decl)))
{
- error_with_decl (found, "multiple parameters named `%s'");
- found = 0;
+ error ("%Jparameter \"%D\" declared void", decl, decl);
+ TREE_TYPE (decl) = integer_type_node;
+ DECL_ARG_TYPE (decl) = integer_type_node;
+ layout_decl (decl, 0);
}
+ }
+ /* If no declaration found, default to int. */
+ else
+ {
+ decl = build_decl (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);
- /* If the declaration says "void", complain and ignore it. */
- if (found && VOID_TYPE_P (TREE_TYPE (found)))
- {
- error_with_decl (found, "parameter `%s' declared void");
- TREE_TYPE (found) = integer_type_node;
- DECL_ARG_TYPE (found) = integer_type_node;
- layout_decl (found, 0);
- }
+ if (flag_isoc99)
+ pedwarn ("%Jtype of \"%D\" defaults to \"int\"", decl, decl);
+ else if (extra_warnings)
+ warning ("%Jtype of \"%D\" defaults to \"int\"", decl, decl);
+ }
- /* If no declaration found, default to int. */
- if (!found)
- {
- found = build_decl (PARM_DECL, TREE_VALUE (parm),
- integer_type_node);
- DECL_ARG_TYPE (found) = TREE_TYPE (found);
- DECL_SOURCE_LINE (found) = DECL_SOURCE_LINE (fndecl);
- DECL_SOURCE_FILE (found) = DECL_SOURCE_FILE (fndecl);
- if (flag_isoc99)
- pedwarn_with_decl (found, "type of `%s' defaults to `int'");
- else if (extra_warnings)
- warning_with_decl (found, "type of `%s' defaults to `int'");
- pushdecl (found);
- }
+ TREE_PURPOSE (parm) = decl;
+ DECL_WEAK (decl) = 1;
+ }
- TREE_PURPOSE (parm) = found;
+ /* Now examine the parms chain for incomplete declarations
+ and declarations with no corresponding names. */
- /* Mark this decl as "already found". */
- DECL_WEAK (found) = 1;
+ for (parm = current_scope->parms; parm; parm = TREE_CHAIN (parm))
+ {
+ if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
+ {
+ error ("%Jparameter \"%D\" has incomplete type", parm, parm);
+ TREE_TYPE (parm) = error_mark_node;
}
- /* Put anything which is on the parmdecls chain and which is
- not a PARM_DECL onto the list NONPARMS. (The types of
- non-parm things which might appear on the list include
- enumerators and NULL-named TYPE_DECL nodes.) Complain about
- any actual PARM_DECLs not matched with any names. */
-
- nonparms = 0;
- for (parm = parmdecls; parm;)
+ if (! DECL_WEAK (parm))
{
- tree next = TREE_CHAIN (parm);
- TREE_CHAIN (parm) = 0;
+ error ("%Jdeclaration for parameter \"%D\" but no such parameter",
+ parm, parm);
- if (TREE_CODE (parm) != PARM_DECL)
- nonparms = chainon (nonparms, parm);
- else
- {
- /* Complain about args with incomplete types. */
- if (!COMPLETE_TYPE_P (TREE_TYPE (parm)))
- {
- error_with_decl (parm, "parameter `%s' has incomplete type");
- TREE_TYPE (parm) = error_mark_node;
- }
+ /* Pretend the parameter was not missing.
+ This gets us to a standard state and minimizes
+ further error messages. */
+ parmids = chainon (parmids, tree_cons (parm, 0, 0));
+ }
+ }
- if (! DECL_WEAK (parm))
- {
- error_with_decl (parm,
- "declaration for parameter `%s' but no such parameter");
- /* Pretend the parameter was not missing.
- This gets us to a standard state and minimizes
- further error messages. */
- specparms
- = chainon (specparms,
- tree_cons (parm, NULL_TREE, NULL_TREE));
- }
- }
+ /* Chain the declarations together in the order of the list of
+ names. Store that chain in the function decl, replacing the
+ list of names. Update the current scope to match. */
+ DECL_ARGUMENTS (fndecl) = 0;
- parm = next;
- }
+ for (parm = parmids; parm; parm = TREE_CHAIN (parm))
+ if (TREE_PURPOSE (parm))
+ break;
+ if (parm && TREE_PURPOSE (parm))
+ {
+ last = TREE_PURPOSE (parm);
+ DECL_ARGUMENTS (fndecl) = last;
+ current_scope->parms = last;
+ DECL_WEAK (last) = 0;
- /* Chain the declarations together in the order of the list of
- names. Store that chain in the function decl, replacing the
- list of names. */
- parm = specparms;
- DECL_ARGUMENTS (fndecl) = 0;
- {
- tree last;
- for (last = 0; parm; parm = TREE_CHAIN (parm))
- if (TREE_PURPOSE (parm))
- {
- if (last == 0)
- DECL_ARGUMENTS (fndecl) = TREE_PURPOSE (parm);
- else
- TREE_CHAIN (last) = TREE_PURPOSE (parm);
- last = TREE_PURPOSE (parm);
- TREE_CHAIN (last) = 0;
- }
- }
+ for (parm = TREE_CHAIN (parm); parm; parm = TREE_CHAIN (parm))
+ if (TREE_PURPOSE (parm))
+ {
+ TREE_CHAIN (last) = TREE_PURPOSE (parm);
+ last = TREE_PURPOSE (parm);
+ DECL_WEAK (last) = 0;
+ }
+ current_scope->parms_last = last;
+ TREE_CHAIN (last) = 0;
+ }
- /* If there was a previous prototype,
- set the DECL_ARG_TYPE of each argument according to
- the type previously specified, and report any mismatches. */
+ /* If there was a previous prototype,
+ set the DECL_ARG_TYPE of each argument according to
+ the type previously specified, and report any mismatches. */
- if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
+ if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
+ {
+ tree type;
+ for (parm = DECL_ARGUMENTS (fndecl),
+ type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
+ parm || (type && (TYPE_MAIN_VARIANT (TREE_VALUE (type))
+ != void_type_node));
+ parm = TREE_CHAIN (parm), type = TREE_CHAIN (type))
{
- tree type;
- for (parm = DECL_ARGUMENTS (fndecl),
- type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
- parm || (type && (TYPE_MAIN_VARIANT (TREE_VALUE (type))
- != void_type_node));
- parm = TREE_CHAIN (parm), type = TREE_CHAIN (type))
+ if (parm == 0 || type == 0
+ || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
{
- if (parm == 0 || type == 0
- || TYPE_MAIN_VARIANT (TREE_VALUE (type)) == void_type_node)
- {
- error ("number of arguments doesn't match prototype");
- error_with_file_and_line (current_function_prototype_file,
- current_function_prototype_line,
- "prototype declaration");
- break;
- }
- /* Type for passing arg must be consistent with that
- declared for the arg. ISO C says we take the unqualified
- type for parameters declared with qualified type. */
- if (! comptypes (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)),
- TYPE_MAIN_VARIANT (TREE_VALUE (type))))
+ error ("number of arguments doesn't match prototype");
+ error ("%Hprototype declaration",
+ &current_function_prototype_locus);
+ break;
+ }
+ /* Type for passing arg must be consistent with that
+ declared for the arg. ISO C says we take the unqualified
+ type for parameters declared with qualified type. */
+ if (! comptypes (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)),
+ TYPE_MAIN_VARIANT (TREE_VALUE (type)),
+ COMPARE_STRICT))
+ {
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
+ == TYPE_MAIN_VARIANT (TREE_VALUE (type)))
{
- if (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
- == TYPE_MAIN_VARIANT (TREE_VALUE (type)))
+ /* Adjust argument to match prototype. E.g. a previous
+ `int foo(float);' prototype causes
+ `int foo(x) float x; {...}' to be treated like
+ `int foo(float x) {...}'. This is particularly
+ useful for argument types like uid_t. */
+ DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
+
+ if (targetm.calls.promote_prototypes (TREE_TYPE (current_function_decl))
+ && INTEGRAL_TYPE_P (TREE_TYPE (parm))
+ && TYPE_PRECISION (TREE_TYPE (parm))
+ < TYPE_PRECISION (integer_type_node))
+ DECL_ARG_TYPE (parm) = integer_type_node;
+
+ if (pedantic)
{
- /* Adjust argument to match prototype. E.g. a previous
- `int foo(float);' prototype causes
- `int foo(x) float x; {...}' to be treated like
- `int foo(float x) {...}'. This is particularly
- useful for argument types like uid_t. */
- DECL_ARG_TYPE (parm) = TREE_TYPE (parm);
-
- if (PROMOTE_PROTOTYPES
- && INTEGRAL_TYPE_P (TREE_TYPE (parm))
- && TYPE_PRECISION (TREE_TYPE (parm))
- < TYPE_PRECISION (integer_type_node))
- DECL_ARG_TYPE (parm) = integer_type_node;
-
- if (pedantic)
- {
- pedwarn ("promoted argument `%s' doesn't match prototype",
- IDENTIFIER_POINTER (DECL_NAME (parm)));
- warning_with_file_and_line
- (current_function_prototype_file,
- current_function_prototype_line,
- "prototype declaration");
- }
- }
- else
- {
- error ("argument `%s' doesn't match prototype",
- IDENTIFIER_POINTER (DECL_NAME (parm)));
- error_with_file_and_line (current_function_prototype_file,
- current_function_prototype_line,
- "prototype declaration");
+ pedwarn ("promoted argument \"%D\" "
+ "doesn't match prototype", parm);
+ pedwarn ("%Hprototype declaration",
+ &current_function_prototype_locus);
}
}
+ else
+ {
+ error ("argument \"%D\" doesn't match prototype", parm);
+ error ("%Hprototype declaration",
+ &current_function_prototype_locus);
+ }
}
- TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = 0;
}
+ TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = 0;
+ }
- /* Otherwise, create a prototype that would match. */
+ /* Otherwise, create a prototype that would match. */
- else
- {
- tree actual = 0, last = 0, type;
+ else
+ {
+ tree actual = 0, last = 0, type;
- for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm))
- {
- type = tree_cons (NULL_TREE, DECL_ARG_TYPE (parm), NULL_TREE);
- if (last)
- TREE_CHAIN (last) = type;
- else
- actual = type;
- last = type;
- }
- type = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
+ for (parm = DECL_ARGUMENTS (fndecl); parm; parm = TREE_CHAIN (parm))
+ {
+ type = tree_cons (NULL_TREE, DECL_ARG_TYPE (parm), NULL_TREE);
if (last)
TREE_CHAIN (last) = type;
else
actual = type;
+ last = type;
+ }
+ type = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
+ if (last)
+ TREE_CHAIN (last) = type;
+ else
+ actual = type;
- /* We are going to assign a new value for the TYPE_ACTUAL_ARG_TYPES
- of the type of this function, but we need to avoid having this
- affect the types of other similarly-typed functions, so we must
- first force the generation of an identical (but separate) type
- node for the relevant function type. The new node we create
- will be a variant of the main variant of the original function
- type. */
+ /* We are going to assign a new value for the TYPE_ACTUAL_ARG_TYPES
+ of the type of this function, but we need to avoid having this
+ affect the types of other similarly-typed functions, so we must
+ first force the generation of an identical (but separate) type
+ node for the relevant function type. The new node we create
+ will be a variant of the main variant of the original function
+ type. */
- TREE_TYPE (fndecl) = build_type_copy (TREE_TYPE (fndecl));
+ TREE_TYPE (fndecl) = build_type_copy (TREE_TYPE (fndecl));
- TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = actual;
- }
+ TYPE_ACTUAL_ARG_TYPES (TREE_TYPE (fndecl)) = actual;
+ }
+}
- /* Now store the final chain of decls for the arguments
- as the decl-chain of the current lexical scope.
- Put the enumerators in as well, at the front so that
- DECL_ARGUMENTS is not modified. */
+/* Store the parameter declarations into the current function declaration.
+ This is called after parsing the parameter declarations, before
+ digesting the body of the function.
- storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl)));
- }
+ For an old-style definition, construct a prototype out of the old-style
+ parameter declarations and inject it into the function's type. */
- /* Make sure the binding level for the top of the function body
- gets a BLOCK if there are any in the function.
- Otherwise, the dbx output is wrong. */
+void
+store_parm_decls (void)
+{
+ tree fndecl = current_function_decl;
- keep_next_if_subblocks = 1;
+ /* The function containing FNDECL, if any. */
+ tree context = decl_function_context (fndecl);
- /* ??? This might be an improvement,
- but needs to be thought about some more. */
-#if 0
- keep_next_level_flag = 1;
-#endif
+ /* True if this definition is written with a prototype. */
+ bool prototype = (current_function_parms
+ && TREE_CODE (current_function_parms) != TREE_LIST);
+
+ if (prototype)
+ store_parm_decls_newstyle ();
+ else
+ store_parm_decls_oldstyle ();
+
+ /* The next call to pushlevel will be a function body. */
+
+ next_is_function_body = true;
/* Write a record describing this function definition to the prototypes
file (if requested). */
@@ -6413,10 +5977,10 @@ store_parm_decls ()
gen_aux_info_record (fndecl, 1, 0, prototype);
/* Initialize the RTL code for the function. */
- init_function_start (fndecl, input_filename, lineno);
+ allocate_struct_function (fndecl);
/* Begin the statement tree for this function. */
- begin_stmt_tree (&DECL_SAVED_TREE (current_function_decl));
+ begin_stmt_tree (&DECL_SAVED_TREE (fndecl));
/* If this is a nested function, save away the sizes of any
variable-size types so that we can expand them when generating
@@ -6425,7 +5989,7 @@ store_parm_decls ()
{
tree t;
- DECL_LANG_SPECIFIC (fndecl)->pending_sizes
+ DECL_LANG_SPECIFIC (fndecl)->pending_sizes
= nreverse (get_pending_sizes ());
for (t = DECL_LANG_SPECIFIC (fndecl)->pending_sizes;
t;
@@ -6442,38 +6006,55 @@ store_parm_decls ()
not safe to try to expand expressions involving them. */
immediate_size_expand = 0;
cfun->x_dont_save_pending_sizes_p = 1;
-
- warn_shadow = saved_warn_shadow;
}
/* Finish up a function declaration and compile that function
all the way to assembler language output. The free the storage
for the function definition.
- This is called after parsing the body of the function definition.
-
- NESTED is nonzero if the function being finished is nested in another.
- CAN_DEFER_P is nonzero if the function may be deferred. */
+ This is called after parsing the body of the function definition. */
void
-finish_function (nested, can_defer_p)
- int nested;
- int can_defer_p;
+finish_function (void)
{
tree fndecl = current_function_decl;
-#if 0
- /* This caused &foo to be of type ptr-to-const-function which then
- got a warning when stored in a ptr-to-function variable. */
- TREE_READONLY (fndecl) = 1;
-#endif
+ /* When a function declaration is totally empty, e.g.
+ void foo(void) { }
+ (the argument list is irrelevant) the compstmt rule will not
+ bother calling pushlevel/poplevel, which means we get here with
+ the scope stack out of sync. Detect this situation by noticing
+ that current_scope is still as store_parm_decls left it, and do
+ a dummy push/pop to get back to consistency.
+ Note that the call to pushlevel does not actually push another
+ scope - see there for details. */
+
+ if (current_scope->parm_flag && next_is_function_body)
+ {
+ pushlevel (0);
+ poplevel (0, 0, 0);
+ }
- poplevel (1, 0, 1);
- BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
+ if (TREE_CODE (fndecl) == FUNCTION_DECL
+ && targetm.calls.promote_prototypes (TREE_TYPE (fndecl)))
+ {
+ tree args = DECL_ARGUMENTS (fndecl);
+ for (; args; args = TREE_CHAIN (args))
+ {
+ tree type = TREE_TYPE (args);
+ if (INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+ DECL_ARG_TYPE (args) = integer_type_node;
+ }
+ }
+
+ if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node)
+ BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;
/* Must mark the RESULT_DECL as being in this function. */
- DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
+ if (DECL_RESULT (fndecl) && DECL_RESULT (fndecl) != error_mark_node)
+ DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;
if (MAIN_NAME_P (DECL_NAME (fndecl)) && flag_hosted)
{
@@ -6482,8 +6063,8 @@ finish_function (nested, can_defer_p)
{
/* If warn_main is 1 (-Wmain) or 2 (-Wall), we have already warned.
If warn_main is -1 (-Wno-main) we don't want to be warned. */
- if (! warn_main)
- pedwarn_with_decl (fndecl, "return type of `%s' is not `int'");
+ if (!warn_main)
+ pedwarn ("%Jreturn type of '%D' is not `int'", fndecl, fndecl);
}
else
{
@@ -6496,7 +6077,7 @@ finish_function (nested, can_defer_p)
#endif
}
}
-
+
finish_fname_decls ();
/* Tie off the statement tree for this function. */
@@ -6517,237 +6098,68 @@ finish_function (nested, can_defer_p)
&& DECL_INLINE (fndecl))
warning ("no return statement in function returning non-void");
- /* With just -W, complain only if function returns both with
+ /* With just -Wextra, complain only if function returns both with
and without a value. */
if (extra_warnings
&& current_function_returns_value
&& current_function_returns_null)
warning ("this function may return with or without a value");
- /* Clear out memory we no longer need. */
- free_after_parsing (cfun);
- /* Since we never call rest_of_compilation, we never clear
- CFUN. Do so explicitly. */
- free_after_compilation (cfun);
+ /* We're leaving the context of this function, so zap cfun. It's still in
+ DECL_SAVED_INSNS, and we'll restore it in tree_rest_of_compilation. */
cfun = NULL;
- if (! nested)
- {
- /* Generate RTL for the body of this function. */
- c_expand_body (fndecl, nested, can_defer_p);
-
- /* Let the error reporting routines know that we're outside a
- function. For a nested function, this value is used in
- c_pop_function_context and then reset via pop_function_context. */
- current_function_decl = NULL;
- }
+ /* ??? Objc emits functions after finalizing the compilation unit.
+ This should be cleaned up later and this conditional removed. */
+ if (!cgraph_global_info_ready)
+ cgraph_finalize_function (fndecl, false);
+ else
+ c_expand_body (fndecl);
+ current_function_decl = NULL;
}
/* Generate the RTL for a deferred function FNDECL. */
void
-c_expand_deferred_function (fndecl)
- tree fndecl;
+c_expand_deferred_function (tree fndecl)
{
/* DECL_INLINE or DECL_RESULT might got cleared after the inline
function was deferred, e.g. in duplicate_decls. */
if (DECL_INLINE (fndecl) && DECL_RESULT (fndecl))
{
- c_expand_body (fndecl, 0, 0);
+ if (flag_inline_trees)
+ {
+ timevar_push (TV_INTEGRATION);
+ optimize_inline_calls (fndecl);
+ timevar_pop (TV_INTEGRATION);
+ }
+ c_expand_body (fndecl);
current_function_decl = NULL;
}
}
-/* Called to move the SAVE_EXPRs for parameter declarations in a
- nested function into the nested function. DATA is really the
- nested FUNCTION_DECL. */
-
-static tree
-set_save_expr_context (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees;
- void *data;
-{
- if (TREE_CODE (*tp) == SAVE_EXPR && !SAVE_EXPR_CONTEXT (*tp))
- SAVE_EXPR_CONTEXT (*tp) = (tree) data;
- /* Do not walk back into the SAVE_EXPR_CONTEXT; that will cause
- circularity. */
- else if (DECL_P (*tp))
- *walk_subtrees = 0;
-
- return NULL_TREE;
-}
-
/* Generate the RTL for the body of FNDECL. If NESTED_P is nonzero,
then we are already in the process of generating RTL for another
- function. If can_defer_p is zero, we won't attempt to defer the
- generation of RTL. */
+ function. */
static void
-c_expand_body (fndecl, nested_p, can_defer_p)
- tree fndecl;
- int nested_p, can_defer_p;
+c_expand_body_1 (tree fndecl, int nested_p)
{
- int uninlinable = 1;
- int saved_lineno;
- const char *saved_input_filename;
-
- /* There's no reason to do any of the work here if we're only doing
- semantic analysis; this code just generates RTL. */
- if (flag_syntax_only)
- return;
-
- saved_lineno = lineno;
- saved_input_filename = input_filename;
- lineno = DECL_SOURCE_LINE (fndecl);
- input_filename = DECL_SOURCE_FILE (fndecl);
-
- if (flag_inline_trees)
- {
- /* First, cache whether the current function is inlinable. Some
- predicates depend on cfun and current_function_decl to
- function completely. */
- timevar_push (TV_INTEGRATION);
- uninlinable = ! tree_inlinable_function_p (fndecl);
-
- if (! uninlinable && can_defer_p
- /* Save function tree for inlining. Should return 0 if the
- language does not support function deferring or the
- function could not be deferred. */
- && defer_fn (fndecl))
- {
- /* Let the back-end know that this function exists. */
- (*debug_hooks->deferred_inline_function) (fndecl);
- timevar_pop (TV_INTEGRATION);
- lineno = saved_lineno;
- input_filename = saved_input_filename;
- return;
- }
-
- /* Then, inline any functions called in it. */
- optimize_inline_calls (fndecl);
- timevar_pop (TV_INTEGRATION);
- }
-
- timevar_push (TV_EXPAND);
-
if (nested_p)
{
/* Make sure that we will evaluate variable-sized types involved
in our function's type. */
expand_pending_sizes (DECL_LANG_SPECIFIC (fndecl)->pending_sizes);
+
/* Squirrel away our current state. */
push_function_context ();
}
+
+ tree_rest_of_compilation (fndecl, nested_p);
- /* Initialize the RTL code for the function. */
- current_function_decl = fndecl;
- init_function_start (fndecl, input_filename, DECL_SOURCE_LINE (fndecl));
-
- /* This function is being processed in whole-function mode. */
- cfun->x_whole_function_mode_p = 1;
-
- /* Even though we're inside a function body, we still don't want to
- call expand_expr to calculate the size of a variable-sized array.
- We haven't necessarily assigned RTL to all variables yet, so it's
- not safe to try to expand expressions involving them. */
- immediate_size_expand = 0;
- cfun->x_dont_save_pending_sizes_p = 1;
-
- /* Set up parameters and prepare for return, for the function. */
- expand_function_start (fndecl, 0);
-
- /* If the function has a variably modified type, there may be
- SAVE_EXPRs in the parameter types. Their context must be set to
- refer to this function; they cannot be expanded in the containing
- function. */
- if (decl_function_context (fndecl)
- && variably_modified_type_p (TREE_TYPE (fndecl)))
- walk_tree (&TREE_TYPE (fndecl), set_save_expr_context, fndecl,
- NULL);
-
- /* If this function is `main', emit a call to `__main'
- to run global initializers, etc. */
- if (DECL_NAME (fndecl)
- && MAIN_NAME_P (DECL_NAME (fndecl))
- && DECL_CONTEXT (fndecl) == NULL_TREE)
- expand_main_function ();
-
- /* Generate the RTL for this function. */
- expand_stmt (DECL_SAVED_TREE (fndecl));
-
- /* Keep the function body if it's needed for inlining or dumping. */
- if (uninlinable && !dump_enabled_p (TDI_all))
- {
- /* Allow the body of the function to be garbage collected. */
- DECL_SAVED_TREE (fndecl) = NULL_TREE;
- }
-
- /* We hard-wired immediate_size_expand to zero above.
- expand_function_end will decrement this variable. So, we set the
- variable to one here, so that after the decrement it will remain
- zero. */
- immediate_size_expand = 1;
-
- /* Allow language dialects to perform special processing. */
- if (lang_expand_function_end)
- (*lang_expand_function_end) ();
-
- /* Generate rtl for function exit. */
- expand_function_end (input_filename, lineno, 0);
-
- /* If this is a nested function, protect the local variables in the stack
- above us from being collected while we're compiling this function. */
if (nested_p)
- ggc_push_context ();
-
- /* Run the optimizers and output the assembler code for this function. */
- rest_of_compilation (fndecl);
-
- /* Undo the GC context switch. */
- if (nested_p)
- ggc_pop_context ();
-
- /* If requested, warn about function definitions where the function will
- return a value (usually of some struct or union type) which itself will
- take up a lot of stack space. */
-
- if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
- {
- tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
-
- if (ret_type && TYPE_SIZE_UNIT (ret_type)
- && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
- && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
- larger_than_size))
- {
- unsigned int size_as_int
- = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
-
- if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
- warning_with_decl (fndecl,
- "size of return value of `%s' is %u bytes",
- size_as_int);
- else
- warning_with_decl (fndecl,
- "size of return value of `%s' is larger than %d bytes",
- larger_than_size);
- }
- }
-
- if (DECL_SAVED_INSNS (fndecl) == 0 && ! nested_p
- && ! flag_inline_trees)
- {
- /* Stop pointing to the local nodes about to be freed.
- But DECL_INITIAL must remain nonzero so we know this
- was an actual function definition.
- For a nested function, this is done in c_pop_function_context.
- If rest_of_compilation set this to 0, leave it 0. */
- if (DECL_INITIAL (fndecl) != 0)
- DECL_INITIAL (fndecl) = error_mark_node;
-
- DECL_ARGUMENTS (fndecl) = 0;
- }
+ /* Return to the enclosing function. */
+ pop_function_context ();
if (DECL_STATIC_CONSTRUCTOR (fndecl))
{
@@ -6766,20 +6178,22 @@ c_expand_body (fndecl, nested_p, can_defer_p)
else
static_dtors = tree_cons (NULL_TREE, fndecl, static_dtors);
}
+}
- if (nested_p)
- /* Return to the enclosing function. */
- pop_function_context ();
- timevar_pop (TV_EXPAND);
+/* Like c_expand_body_1 but only for unnested functions. */
+
+void
+c_expand_body (tree fndecl)
+{
- lineno = saved_lineno;
- input_filename = saved_input_filename;
+ if (DECL_INITIAL (fndecl) && DECL_INITIAL (fndecl) != error_mark_node)
+ c_expand_body_1 (fndecl, 0);
}
/* Check the declarations given in a for-loop for satisfying the C99
constraints. */
void
-check_for_loop_decls ()
+check_for_loop_decls (void)
{
tree t;
@@ -6788,7 +6202,7 @@ check_for_loop_decls ()
/* 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 declaration used outside C99 mode");
+ error ("'for' loop initial declaration used outside C99 mode");
return;
}
/* C99 subclause 6.8.5 paragraph 3:
@@ -6805,20 +6219,20 @@ check_for_loop_decls ()
interpretation, to avoid creating an extension which later causes
problems. */
- for (t = gettags (); t; t = TREE_CHAIN (t))
+ for (t = current_scope->tags; t; t = TREE_CHAIN (t))
{
if (TREE_PURPOSE (t) != 0)
{
enum tree_code code = TREE_CODE (TREE_VALUE (t));
-
+
if (code == RECORD_TYPE)
- error ("`struct %s' declared in `for' loop initial declaration",
+ error ("'struct %s' declared in 'for' loop initial declaration",
IDENTIFIER_POINTER (TREE_PURPOSE (t)));
else if (code == UNION_TYPE)
- error ("`union %s' declared in `for' loop initial declaration",
+ error ("'union %s' declared in 'for' loop initial declaration",
IDENTIFIER_POINTER (TREE_PURPOSE (t)));
else
- error ("`enum %s' declared in `for' loop initial declaration",
+ error ("'enum %s' declared in 'for' loop initial declaration",
IDENTIFIER_POINTER (TREE_PURPOSE (t)));
}
}
@@ -6826,69 +6240,44 @@ check_for_loop_decls ()
for (t = getdecls (); t; t = TREE_CHAIN (t))
{
if (TREE_CODE (t) != VAR_DECL && DECL_NAME (t))
- error_with_decl (t, "declaration of non-variable `%s' in `for' loop initial declaration");
+ error ("%Jdeclaration of non-variable '%D' in 'for' loop "
+ "initial declaration", t, t);
else if (TREE_STATIC (t))
- error_with_decl (t, "declaration of static variable `%s' in `for' loop initial declaration");
+ error ("%Jdeclaration of static variable '%D' in 'for' loop "
+ "initial declaration", t, t);
else if (DECL_EXTERNAL (t))
- error_with_decl (t, "declaration of `extern' variable `%s' in `for' loop initial declaration");
+ error ("%Jdeclaration of 'extern' variable '%D' in 'for' loop "
+ "initial declaration", t, t);
}
}
-/* Save and restore the variables in this file and elsewhere
- that keep track of the progress of compilation of the current function.
- Used for nested functions. */
-
-struct language_function GTY(())
-{
- struct c_language_function base;
- tree named_labels;
- tree shadowed_labels;
- int returns_value;
- int returns_null;
- int returns_abnormally;
- int warn_about_return_type;
- int extern_inline;
- struct binding_level *binding_level;
-};
-
/* Save and reinitialize the variables
used during compilation of a C function. */
void
-c_push_function_context (f)
- struct function *f;
+c_push_function_context (struct function *f)
{
struct language_function *p;
- p = ((struct language_function *)
- ggc_alloc (sizeof (struct language_function)));
+ p = ggc_alloc (sizeof (struct language_function));
f->language = p;
p->base.x_stmt_tree = c_stmt_tree;
p->base.x_scope_stmt_stack = c_scope_stmt_stack;
- p->named_labels = named_labels;
- p->shadowed_labels = shadowed_labels;
+ p->x_in_iteration_stmt = c_in_iteration_stmt;
+ p->x_in_case_stmt = c_in_case_stmt;
p->returns_value = current_function_returns_value;
p->returns_null = current_function_returns_null;
p->returns_abnormally = current_function_returns_abnormally;
p->warn_about_return_type = warn_about_return_type;
p->extern_inline = current_extern_inline;
- p->binding_level = current_binding_level;
}
/* Restore the variables used during compilation of a C function. */
void
-c_pop_function_context (f)
- struct function *f;
+c_pop_function_context (struct function *f)
{
struct language_function *p = f->language;
- tree link;
-
- /* Bring back all the labels that were shadowed. */
- for (link = shadowed_labels; link; link = TREE_CHAIN (link))
- if (DECL_NAME (TREE_VALUE (link)) != 0)
- IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)))
- = TREE_VALUE (link);
if (DECL_SAVED_INSNS (current_function_decl) == 0
&& DECL_SAVED_TREE (current_function_decl) == NULL_TREE)
@@ -6902,14 +6291,13 @@ c_pop_function_context (f)
c_stmt_tree = p->base.x_stmt_tree;
c_scope_stmt_stack = p->base.x_scope_stmt_stack;
- named_labels = p->named_labels;
- shadowed_labels = p->shadowed_labels;
+ c_in_iteration_stmt = p->x_in_iteration_stmt;
+ c_in_case_stmt = p->x_in_case_stmt;
current_function_returns_value = p->returns_value;
current_function_returns_null = p->returns_null;
current_function_returns_abnormally = p->returns_abnormally;
warn_about_return_type = p->warn_about_return_type;
current_extern_inline = p->extern_inline;
- current_binding_level = p->binding_level;
f->language = NULL;
}
@@ -6917,17 +6305,15 @@ c_pop_function_context (f)
/* Copy the DECL_LANG_SPECIFIC data associated with DECL. */
void
-c_dup_lang_specific_decl (decl)
- tree decl;
+c_dup_lang_specific_decl (tree decl)
{
struct lang_decl *ld;
if (!DECL_LANG_SPECIFIC (decl))
return;
- ld = (struct lang_decl *) ggc_alloc (sizeof (struct lang_decl));
- memcpy ((char *) ld, (char *) DECL_LANG_SPECIFIC (decl),
- sizeof (struct lang_decl));
+ ld = ggc_alloc (sizeof (struct lang_decl));
+ memcpy (ld, DECL_LANG_SPECIFIC (decl), sizeof (struct lang_decl));
DECL_LANG_SPECIFIC (decl) = ld;
}
@@ -6941,7 +6327,7 @@ c_dup_lang_specific_decl (decl)
at the end of the statement. */
int
-stmts_are_full_exprs_p ()
+stmts_are_full_exprs_p (void)
{
return 0;
}
@@ -6951,7 +6337,7 @@ stmts_are_full_exprs_p ()
returned. */
stmt_tree
-current_stmt_tree ()
+current_stmt_tree (void)
{
return &c_stmt_tree;
}
@@ -6959,7 +6345,7 @@ current_stmt_tree ()
/* Returns the stack of SCOPE_STMTs for the current function. */
tree *
-current_scope_stmt_stack ()
+current_scope_stmt_stack (void)
{
return &c_scope_stmt_stack;
}
@@ -6968,8 +6354,7 @@ current_scope_stmt_stack ()
C. */
int
-anon_aggr_type_p (node)
- tree node ATTRIBUTE_UNUSED;
+anon_aggr_type_p (tree node ATTRIBUTE_UNUSED)
{
return 0;
}
@@ -6977,7 +6362,7 @@ anon_aggr_type_p (node)
/* Dummy function in place of callback used by C++. */
void
-extract_interface_info ()
+extract_interface_info (void)
{
}
@@ -6985,7 +6370,7 @@ extract_interface_info ()
statement tree. */
tree
-c_begin_compound_stmt ()
+c_begin_compound_stmt (void)
{
tree stmt;
@@ -6999,8 +6384,7 @@ c_begin_compound_stmt ()
common code. */
void
-c_expand_decl_stmt (t)
- tree t;
+c_expand_decl_stmt (tree t)
{
tree decl = DECL_STMT_DECL (t);
@@ -7008,27 +6392,32 @@ c_expand_decl_stmt (t)
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_CONTEXT (decl) == current_function_decl
&& DECL_SAVED_TREE (decl))
- c_expand_body (decl, /*nested_p=*/1, /*can_defer_p=*/0);
+ c_expand_body_1 (decl, 1);
}
-/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
- the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++. */
+/* Return the global value of T as a symbol. */
tree
-identifier_global_value (t)
- tree t;
+identifier_global_value (tree t)
{
- return IDENTIFIER_GLOBAL_VALUE (t);
+ tree decl = IDENTIFIER_SYMBOL_VALUE (t);
+ if (decl == 0 || DECL_FILE_SCOPE_P (decl))
+ return decl;
+
+ /* Shadowed by something else; find the true global value. */
+ for (decl = global_scope->names; decl; decl = TREE_CHAIN (decl))
+ if (DECL_NAME (decl) == t)
+ return decl;
+
+ /* Only local values for this decl. */
+ return 0;
}
/* Record a builtin type for C. If NAME is non-NULL, it is the name used;
otherwise the name is found in ridpointers from RID_INDEX. */
void
-record_builtin_type (rid_index, name, type)
- enum rid rid_index;
- const char *name;
- tree type;
+record_builtin_type (enum rid rid_index, const char *name, tree type)
{
tree id;
if (name == 0)
@@ -7040,7 +6429,7 @@ record_builtin_type (rid_index, name, type)
/* Build the void_list_node (void_type_node having been created). */
tree
-build_void_list_node ()
+build_void_list_node (void)
{
tree t = build_tree_list (NULL_TREE, void_type_node);
return t;
@@ -7056,8 +6445,7 @@ build_void_list_node ()
if attributes are present) and whose type is the modifier list. */
tree
-make_pointer_declarator (type_quals_attrs, target)
- tree type_quals_attrs, target;
+make_pointer_declarator (tree type_quals_attrs, tree target)
{
tree quals, attrs;
tree itarget = target;
@@ -7067,4 +6455,194 @@ make_pointer_declarator (type_quals_attrs, target)
return build1 (INDIRECT_REF, quals, itarget);
}
+/* A wrapper around lhd_set_decl_assembler_name that gives static
+ variables their C names if they are at file scope and only one
+ translation unit is being compiled, for backwards compatibility
+ with certain bizarre assembler hacks (like crtstuff.c). */
+
+void
+c_static_assembler_name (tree decl)
+{
+ if (num_in_fnames == 1
+ && !TREE_PUBLIC (decl) && DECL_CONTEXT (decl)
+ && TREE_CODE (DECL_CONTEXT (decl)) == TRANSLATION_UNIT_DECL)
+ SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
+ else
+ lhd_set_decl_assembler_name (decl);
+}
+
+/* Hash and equality functions for link_hash_table: key off
+ DECL_ASSEMBLER_NAME. */
+
+static hashval_t
+link_hash_hash (const void *x_p)
+{
+ tree x = (tree)x_p;
+ return (hashval_t) (long)DECL_ASSEMBLER_NAME (x);
+}
+
+static int
+link_hash_eq (const void *x1_p, const void *x2_p)
+{
+ tree x1 = (tree)x1_p;
+ tree x2 = (tree)x2_p;
+ return DECL_ASSEMBLER_NAME (x1) == DECL_ASSEMBLER_NAME (x2);
+}
+
+/* Propagate information between definitions and uses between multiple
+ translation units in TU_LIST based on linkage rules. */
+
+void
+merge_translation_unit_decls (void)
+{
+ const tree tu_list = current_file_decl;
+ tree tu;
+ tree decl;
+ htab_t link_hash_table;
+ tree block;
+
+ /* Create the BLOCK that poplevel would have created, but don't
+ actually call poplevel since that's expensive. */
+ block = make_node (BLOCK);
+ BLOCK_VARS (block) = current_scope->names;
+ TREE_USED (block) = 1;
+ DECL_INITIAL (current_file_decl) = block;
+
+ /* If only one translation unit seen, no copying necessary. */
+ if (TREE_CHAIN (tu_list) == NULL_TREE)
+ return;
+
+ link_hash_table = htab_create (1021, link_hash_hash, link_hash_eq, NULL);
+
+ /* Enter any actual definitions into the hash table. */
+ for (tu = tu_list; tu; tu = TREE_CHAIN (tu))
+ for (decl = BLOCK_VARS (DECL_INITIAL (tu)); decl; decl = TREE_CHAIN (decl))
+ if (TREE_PUBLIC (decl) && ! DECL_EXTERNAL (decl))
+ {
+ PTR *slot;
+ slot = htab_find_slot (link_hash_table, decl, INSERT);
+
+ /* If we've already got a definition, work out which one is
+ the real one, put it into the hash table, and make the
+ other one DECL_EXTERNAL. This is important to avoid
+ putting out two definitions of the same symbol in the
+ assembly output. */
+ if (*slot != NULL)
+ {
+ tree old_decl = (tree) *slot;
+
+ /* If this is weak or common or whatever, suppress it
+ in favor of the other definition. */
+ if (DECL_WEAK (decl))
+ DECL_EXTERNAL (decl) = 1;
+ else if (DECL_WEAK (old_decl) && ! DECL_WEAK (decl))
+ DECL_EXTERNAL (old_decl) = 1;
+ else if (DECL_COMMON (decl) || DECL_ONE_ONLY (decl))
+ DECL_EXTERNAL (decl) = 1;
+ else if (DECL_COMMON (old_decl) || DECL_ONE_ONLY (old_decl))
+ DECL_EXTERNAL (old_decl) = 1;
+
+ if (DECL_EXTERNAL (decl))
+ {
+ DECL_INITIAL (decl) = NULL_TREE;
+ DECL_COMMON (decl) = 0;
+ DECL_ONE_ONLY (decl) = 0;
+ DECL_WEAK (decl) = 0;
+ }
+ else if (DECL_EXTERNAL (old_decl))
+ {
+ DECL_INITIAL (old_decl) = NULL_TREE;
+ DECL_COMMON (old_decl) = 0;
+ DECL_ONE_ONLY (old_decl) = 0;
+ DECL_WEAK (old_decl) = 0;
+ *slot = decl;
+ }
+ else
+ {
+ error ("%Jredefinition of global '%D'", decl, decl);
+ error ("%J'%D' previously defined here", old_decl, old_decl);
+ }
+ }
+ else
+ *slot = decl;
+ }
+
+ /* Now insert the desired information from all the definitions
+ into any plain declarations. */
+ for (tu = tu_list; tu; tu = TREE_CHAIN (tu))
+ for (decl = BLOCK_VARS (DECL_INITIAL (tu)); decl; decl = TREE_CHAIN (decl))
+ if (TREE_PUBLIC (decl) && DECL_EXTERNAL (decl))
+ {
+ tree global_decl;
+ global_decl = htab_find (link_hash_table, decl);
+
+ if (! global_decl)
+ continue;
+
+ /* Print any appropriate error messages, and partially merge
+ the decls. */
+ (void) duplicate_decls (decl, global_decl);
+ }
+
+ htab_delete (link_hash_table);
+}
+
+/* Perform final processing on file-scope data. */
+
+void
+c_write_global_declarations(void)
+{
+ tree link;
+
+ for (link = current_file_decl; link; link = TREE_CHAIN (link))
+ {
+ tree globals = BLOCK_VARS (DECL_INITIAL (link));
+ int len = list_length (globals);
+ tree *vec = xmalloc (sizeof (tree) * len);
+ int i;
+ tree decl;
+
+ /* Process the decls in the order they were written. */
+
+ for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
+ vec[i] = decl;
+
+ wrapup_global_declarations (vec, len);
+
+ check_global_declarations (vec, len);
+
+ /* Clean up. */
+ free (vec);
+ }
+}
+
+/* Reset the parser's state in preparation for a new file. */
+
+void
+c_reset_state (void)
+{
+ tree link;
+ tree file_scope_decl;
+
+ /* Pop the global scope. */
+ if (current_scope != global_scope)
+ current_scope = global_scope;
+ file_scope_decl = current_file_decl;
+ DECL_INITIAL (file_scope_decl) = poplevel (1, 0, 0);
+ BLOCK_SUPERCONTEXT (DECL_INITIAL (file_scope_decl)) = file_scope_decl;
+ truly_local_externals = NULL_TREE;
+
+ /* Start a new global binding level. */
+ pushlevel (0);
+ global_scope = current_scope;
+ current_file_decl = build_decl (TRANSLATION_UNIT_DECL, NULL, NULL);
+ TREE_CHAIN (current_file_decl) = file_scope_decl;
+
+ /* Reintroduce the builtin declarations. */
+ for (link = first_builtin_decl;
+ link != TREE_CHAIN (last_builtin_decl);
+ link = TREE_CHAIN (link))
+ pushdecl (copy_node (link));
+}
+
#include "gt-c-decl.h"
diff --git a/contrib/gcc/c-dump.c b/contrib/gcc/c-dump.c
index 65407a507d5c..5403bf88601f 100644
--- a/contrib/gcc/c-dump.c
+++ b/contrib/gcc/c-dump.c
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "c-tree.h"
#include "tree-dump.h"
@@ -28,9 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Dump information common to statements from STMT. */
void
-dump_stmt (di, t)
- dump_info_p di;
- tree t;
+dump_stmt (dump_info_p di, tree t)
{
dump_int (di, "line", STMT_LINENO (t));
}
@@ -38,19 +38,15 @@ dump_stmt (di, t)
/* Dump the next statement after STMT. */
void
-dump_next_stmt (di, t)
- dump_info_p di;
- tree t;
+dump_next_stmt (dump_info_p di, tree t)
{
dump_child ("next", TREE_CHAIN (t));
}
/* Dump any C-specific tree codes and attributes of common codes. */
-int
-c_dump_tree (dump_info, t)
- void *dump_info;
- tree t;
+bool
+c_dump_tree (void *dump_info, tree t)
{
enum tree_code code;
dump_info_p di = (dump_info_p) dump_info;
@@ -192,5 +188,5 @@ c_dump_tree (dump_info, t)
break;
}
- return 0;
+ return false;
}
diff --git a/contrib/gcc/c-errors.c b/contrib/gcc/c-errors.c
index 1bd52a8ed6fd..fa71b8cfa97d 100644
--- a/contrib/gcc/c-errors.c
+++ b/contrib/gcc/c-errors.c
@@ -1,5 +1,5 @@
/* Various diagnostic subroutines for the GNU C language.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "c-tree.h"
#include "tm_p.h"
@@ -30,14 +32,32 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Issue an ISO C99 pedantic warning MSGID. */
void
-pedwarn_c99 VPARAMS ((const char *msgid, ...))
+pedwarn_c99 (const char *msgid, ...)
{
diagnostic_info diagnostic;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
- diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
+ va_list ap;
+
+ va_start (ap, msgid);
+ diagnostic_set_info (&diagnostic, msgid, &ap, input_location,
flag_isoc99 ? pedantic_error_kind () : DK_WARNING);
report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
+ va_end (ap);
+}
+
+/* Issue an ISO C90 pedantic warning MSGID. This function is supposed to
+ be used for matters that are allowed in ISO C99 but not supported in
+ ISO C90, thus we explicitly don't pedwarn when C99 is specified.
+ (There is no flag_c90.) */
+
+void
+pedwarn_c90 (const char *msgid, ...)
+{
+ diagnostic_info diagnostic;
+ va_list ap;
+
+ va_start (ap, msgid);
+ diagnostic_set_info (&diagnostic, msgid, &ap, input_location,
+ flag_isoc99 ? DK_WARNING : pedantic_error_kind ());
+ report_diagnostic (&diagnostic);
+ va_end (ap);
}
diff --git a/contrib/gcc/c-format.c b/contrib/gcc/c-format.c
index 083e91278f86..a532259750c4 100644
--- a/contrib/gcc/c-format.c
+++ b/contrib/gcc/c-format.c
@@ -1,6 +1,6 @@
/* Check calls to formatted I/O functions (-Wformat).
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "toplev.h"
@@ -32,17 +34,16 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Set format warning options according to a -Wformat=n option. */
void
-set_Wformat (setting)
- int setting;
+set_Wformat (int setting)
{
warn_format = setting;
- warn_format_y2k = setting;
warn_format_extra_args = setting;
warn_format_zero_length = setting;
if (setting != 1)
{
warn_format_nonliteral = setting;
warn_format_security = setting;
+ warn_format_y2k = setting;
}
/* Make sure not to disable -Wnonnull if -Wformat=0 is specified. */
if (setting)
@@ -54,9 +55,11 @@ set_Wformat (setting)
/* This must be in the same order as format_types, with format_type_error
last. */
-enum format_type { printf_format_type, scanf_format_type,
- strftime_format_type, strfmon_format_type,
- format_type_error };
+enum format_type { printf_format_type, asm_fprintf_format_type,
+ gcc_diag_format_type, gcc_cdiag_format_type,
+ gcc_cxxdiag_format_type,
+ scanf_format_type, strftime_format_type,
+ strfmon_format_type, format_type_error };
typedef struct function_format_info
{
@@ -65,72 +68,47 @@ typedef struct function_format_info
unsigned HOST_WIDE_INT first_arg_num; /* number of first arg (zero for varargs) */
} function_format_info;
-static bool decode_format_attr PARAMS ((tree,
- function_format_info *, int));
-static enum format_type decode_format_type PARAMS ((const char *));
+static bool decode_format_attr (tree, function_format_info *, int);
+static enum format_type decode_format_type (const char *);
-/* Handle a "format" attribute; arguments as in
+static bool check_format_string (tree argument,
+ unsigned HOST_WIDE_INT format_num,
+ int flags, bool *no_add_attrs);
+static bool get_constant (tree expr, unsigned HOST_WIDE_INT *value,
+ int validated_p);
+
+
+/* Handle a "format_arg" attribute; arguments as in
struct attribute_spec.handler. */
tree
-handle_format_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name ATTRIBUTE_UNUSED;
- tree args;
- int flags;
- bool *no_add_attrs;
+handle_format_arg_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
+ tree args, int flags, bool *no_add_attrs)
{
tree type = *node;
- function_format_info info;
+ tree format_num_expr = TREE_VALUE (args);
+ unsigned HOST_WIDE_INT format_num;
tree argument;
- unsigned HOST_WIDE_INT arg_num;
- if (!decode_format_attr (args, &info, 0))
+ if (!get_constant (format_num_expr, &format_num, 0))
{
+ error ("format string has invalid operand number");
*no_add_attrs = true;
return NULL_TREE;
}
- /* If a parameter list is specified, verify that the format_num
- argument is actually a string, in case the format attribute
- is in error. */
argument = TYPE_ARG_TYPES (type);
if (argument)
{
- for (arg_num = 1; argument != 0 && arg_num != info.format_num;
- ++arg_num, argument = TREE_CHAIN (argument))
- ;
-
- if (! argument
- || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
- || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
- != char_type_node))
- {
- if (!(flags & (int) ATTR_FLAG_BUILT_IN))
- error ("format string arg not a string type");
- *no_add_attrs = true;
- return NULL_TREE;
- }
-
- else if (info.first_arg_num != 0)
- {
- /* Verify that first_arg_num points to the last arg,
- the ... */
- while (argument)
- arg_num++, argument = TREE_CHAIN (argument);
-
- if (arg_num != info.first_arg_num)
- {
- if (!(flags & (int) ATTR_FLAG_BUILT_IN))
- error ("args to be formatted is not '...'");
- *no_add_attrs = true;
- return NULL_TREE;
- }
- }
+ if (!check_format_string (argument, format_num, flags, no_add_attrs))
+ return NULL_TREE;
}
- if (info.format_type == strftime_format_type && info.first_arg_num != 0)
+ if (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
+ || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
+ != char_type_node))
{
- error ("strftime formats cannot format arguments");
+ if (!(flags & (int) ATTR_FLAG_BUILT_IN))
+ error ("function does not return string type");
*no_add_attrs = true;
return NULL_TREE;
}
@@ -138,75 +116,57 @@ handle_format_attribute (node, name, args, flags, no_add_attrs)
return NULL_TREE;
}
-
-/* Handle a "format_arg" attribute; arguments as in
- struct attribute_spec.handler. */
-tree
-handle_format_arg_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name ATTRIBUTE_UNUSED;
- tree args;
- int flags;
- bool *no_add_attrs;
+/* Verify that the format_num argument is actually a string, in case
+ the format attribute is in error. */
+static bool
+check_format_string (tree argument, unsigned HOST_WIDE_INT format_num,
+ int flags, bool *no_add_attrs)
{
- tree type = *node;
- tree format_num_expr = TREE_VALUE (args);
- unsigned HOST_WIDE_INT format_num;
- unsigned HOST_WIDE_INT arg_num;
- tree argument;
-
- /* Strip any conversions from the first arg number and verify it
- is a constant. */
- while (TREE_CODE (format_num_expr) == NOP_EXPR
- || TREE_CODE (format_num_expr) == CONVERT_EXPR
- || TREE_CODE (format_num_expr) == NON_LVALUE_EXPR)
- format_num_expr = TREE_OPERAND (format_num_expr, 0);
+ unsigned HOST_WIDE_INT i;
- if (TREE_CODE (format_num_expr) != INTEGER_CST
- || TREE_INT_CST_HIGH (format_num_expr) != 0)
+ for (i = 1; i != format_num; i++)
{
- error ("format string has invalid operand number");
- *no_add_attrs = true;
- return NULL_TREE;
- }
-
- format_num = TREE_INT_CST_LOW (format_num_expr);
-
- /* If a parameter list is specified, verify that the format_num
- argument is actually a string, in case the format attribute
- is in error. */
- argument = TYPE_ARG_TYPES (type);
- if (argument)
- {
- for (arg_num = 1; argument != 0 && arg_num != format_num;
- ++arg_num, argument = TREE_CHAIN (argument))
- ;
-
- if (! argument
- || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
- || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
- != char_type_node))
- {
- if (!(flags & (int) ATTR_FLAG_BUILT_IN))
- error ("format string arg not a string type");
- *no_add_attrs = true;
- return NULL_TREE;
- }
+ if (argument == 0)
+ break;
+ argument = TREE_CHAIN (argument);
}
- if (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE
- || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type)))
+ if (!argument
+ || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE
+ || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument)))
!= char_type_node))
{
if (!(flags & (int) ATTR_FLAG_BUILT_IN))
- error ("function does not return string type");
+ error ("format string arg not a string type");
*no_add_attrs = true;
- return NULL_TREE;
+ return false;
}
- return NULL_TREE;
+ return true;
}
+/* Strip any conversions from the expression, verify it is a constant,
+ and store its value. If validated_p is true, abort on errors.
+ Returns true on success, false otherwise. */
+static bool
+get_constant(tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
+{
+ while (TREE_CODE (expr) == NOP_EXPR
+ || TREE_CODE (expr) == CONVERT_EXPR
+ || TREE_CODE (expr) == NON_LVALUE_EXPR)
+ expr = TREE_OPERAND (expr, 0);
+
+ if (TREE_CODE (expr) != INTEGER_CST || TREE_INT_CST_HIGH (expr) != 0)
+ {
+ if (validated_p)
+ abort ();
+ return false;
+ }
+
+ *value = TREE_INT_CST_LOW (expr);
+
+ return true;
+}
/* Decode the arguments to a "format" attribute into a function_format_info
structure. It is already known that the list is of the right length.
@@ -216,10 +176,7 @@ handle_format_arg_attribute (node, name, args, flags, no_add_attrs)
successfully decoded, false otherwise. */
static bool
-decode_format_attr (args, info, validated_p)
- tree args;
- function_format_info *info;
- int validated_p;
+decode_format_attr (tree args, function_format_info *info, int validated_p)
{
tree format_type_id = TREE_VALUE (args);
tree format_num_expr = TREE_VALUE (TREE_CHAIN (args));
@@ -248,31 +205,18 @@ decode_format_attr (args, info, validated_p)
}
}
- /* Strip any conversions from the string index and first arg number
- and verify they are constants. */
- while (TREE_CODE (format_num_expr) == NOP_EXPR
- || TREE_CODE (format_num_expr) == CONVERT_EXPR
- || TREE_CODE (format_num_expr) == NON_LVALUE_EXPR)
- format_num_expr = TREE_OPERAND (format_num_expr, 0);
-
- while (TREE_CODE (first_arg_num_expr) == NOP_EXPR
- || TREE_CODE (first_arg_num_expr) == CONVERT_EXPR
- || TREE_CODE (first_arg_num_expr) == NON_LVALUE_EXPR)
- first_arg_num_expr = TREE_OPERAND (first_arg_num_expr, 0);
-
- if (TREE_CODE (format_num_expr) != INTEGER_CST
- || TREE_INT_CST_HIGH (format_num_expr) != 0
- || TREE_CODE (first_arg_num_expr) != INTEGER_CST
- || TREE_INT_CST_HIGH (first_arg_num_expr) != 0)
+ if (!get_constant (format_num_expr, &info->format_num, validated_p))
{
- if (validated_p)
- abort ();
error ("format string has invalid operand number");
return false;
}
- info->format_num = TREE_INT_CST_LOW (format_num_expr);
- info->first_arg_num = TREE_INT_CST_LOW (first_arg_num_expr);
+ if (!get_constant (first_arg_num_expr, &info->first_arg_num, validated_p))
+ {
+ error ("'...' has invalid operand number");
+ return false;
+ }
+
if (info->first_arg_num != 0 && info->first_arg_num <= info->format_num)
{
if (validated_p)
@@ -317,7 +261,7 @@ enum format_std_version
or inheriting from, for the purpose of format features supported. */
#define CPLUSPLUS_STD_VER STD_C94
/* The C standard version we are checking formats against when pedantic. */
-#define C_STD_VER ((int)(c_language == clk_cplusplus \
+#define C_STD_VER ((int)(c_dialect_cxx () \
? CPLUSPLUS_STD_VER \
: (flag_isoc99 \
? STD_C99 \
@@ -325,7 +269,7 @@ enum format_std_version
/* The name to give to the standard version we are warning about when
pedantic. FEATURE_VER is the version in which the feature warned out
appeared, which is higher than C_STD_VER. */
-#define C_STD_NAME(FEATURE_VER) (c_language == clk_cplusplus \
+#define C_STD_NAME(FEATURE_VER) (c_dialect_cxx () \
? "ISO C++" \
: ((FEATURE_VER) == STD_EXT \
? "ISO C" \
@@ -371,15 +315,15 @@ enum
typedef struct
{
/* Name of the single-character length modifier. */
- const char *const name;
+ const char *name;
/* Index into a format_char_info.types array. */
- const enum format_lengths index;
+ enum format_lengths index;
/* Standard version this length appears in. */
- const enum format_std_version std;
+ enum format_std_version std;
/* Same, if the modifier can be repeated, or NULL if it can't. */
- const char *const double_name;
- const enum format_lengths double_index;
- const enum format_std_version double_std;
+ const char *double_name;
+ enum format_lengths double_index;
+ enum format_std_version double_std;
} format_length_info;
@@ -400,6 +344,7 @@ typedef struct
/* Macros to fill out tables of these. */
+#define NOARGUMENTS { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }
#define BADLEN { 0, NULL, NULL }
#define NOLENGTHS { BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }
@@ -408,18 +353,18 @@ typedef struct
which act identically), and the length modifiers used with it. */
typedef struct
{
- const char *const format_chars;
- const int pointer_count;
- const enum format_std_version std;
+ const char *format_chars;
+ int pointer_count;
+ enum format_std_version std;
/* Types accepted for each length modifier. */
- const format_type_detail types[FMT_LEN_MAX];
+ format_type_detail types[FMT_LEN_MAX];
/* List of other modifier characters allowed with these specifiers.
This lists flags, and additionally "w" for width, "p" for precision
(right precision, for strfmon), "#" for left precision (strfmon),
"a" for scanf "a" allocation extension (not applicable in C99 mode),
"*" for scanf suppression, and "E" and "O" for those strftime
modifiers. */
- const char *const flag_chars;
+ const char *flag_chars;
/* List of additional flags describing these conversion specifiers.
"c" for generic character pointers being allowed, "2" for strftime
two digit year formats, "3" for strftime formats giving two digit
@@ -429,7 +374,7 @@ typedef struct
"R" if the argument is a pointer which is dereferenced and read from,
"i" for printf integer formats where the '0' flag is ignored with
precision, and "[" for the starting character of a scanf scanset. */
- const char *const flags2;
+ const char *flags2;
} format_char_info;
@@ -437,7 +382,7 @@ typedef struct
typedef struct
{
/* The flag character in question (0 for end of array). */
- const int flag_char;
+ int flag_char;
/* Zero if this entry describes the flag character in general, or a
nonzero character that may be found in flags2 if it describes the
flag when used with certain formats only. If the latter, only
@@ -446,18 +391,18 @@ typedef struct
will be used, if non-NULL and the standard version is higher than
the unpredicated one, for any pedantic warning. For example, 'o'
for strftime formats (meaning 'O' is an extension over C99). */
- const int predicate;
+ int predicate;
/* Nonzero if the next character after this flag in the format should
be skipped ('=' in strfmon), zero otherwise. */
- const int skip_next_char;
+ int skip_next_char;
/* The name to use for this flag in diagnostic messages. For example,
N_("`0' flag"), N_("field width"). */
- const char *const name;
+ const char *name;
/* Long name for this flag in diagnostic messages; currently only used for
"ISO C does not support ...". For example, N_("the `I' printf flag"). */
- const char *const long_name;
+ const char *long_name;
/* The standard version in which it appeared. */
- const enum format_std_version std;
+ enum format_std_version std;
} format_flag_spec;
@@ -466,16 +411,16 @@ typedef struct
typedef struct
{
/* The first flag character in question (0 for end of array). */
- const int flag_char1;
+ int flag_char1;
/* The second flag character. */
- const int flag_char2;
+ int flag_char2;
/* Nonzero if the message should say that the first flag is ignored with
the second, zero if the combination should simply be objected to. */
- const int ignored;
+ int ignored;
/* Zero if this entry applies whenever this flag combination occurs,
a nonzero character from flags2 if it only applies in some
circumstances (e.g. 'i' for printf formats ignoring 0 with precision). */
- const int predicate;
+ int predicate;
} format_flag_pair;
@@ -484,43 +429,43 @@ typedef struct
{
/* The name of this kind of format, for use in diagnostics. Also
the name of the attribute (without preceding and following __). */
- const char *const name;
+ const char *name;
/* Specifications of the length modifiers accepted; possibly NULL. */
- const format_length_info *const length_char_specs;
+ const format_length_info *length_char_specs;
/* Details of the conversion specification characters accepted. */
- const format_char_info *const conversion_specs;
+ const format_char_info *conversion_specs;
/* String listing the flag characters that are accepted. */
- const char *const flag_chars;
+ const char *flag_chars;
/* String listing modifier characters (strftime) accepted. May be NULL. */
- const char *const modifier_chars;
+ const char *modifier_chars;
/* Details of the flag characters, including pseudo-flags. */
- const format_flag_spec *const flag_specs;
+ const format_flag_spec *flag_specs;
/* Details of bad combinations of flags. */
- const format_flag_pair *const bad_flag_pairs;
+ const format_flag_pair *bad_flag_pairs;
/* Flags applicable to this kind of format. */
- const int flags;
+ int flags;
/* Flag character to treat a width as, or 0 if width not used. */
- const int width_char;
+ int width_char;
/* Flag character to treat a left precision (strfmon) as,
or 0 if left precision not used. */
- const int left_precision_char;
+ int left_precision_char;
/* Flag character to treat a precision (for strfmon, right precision) as,
or 0 if precision not used. */
- const int precision_char;
+ int precision_char;
/* If a flag character has the effect of suppressing the conversion of
an argument ('*' in scanf), that flag character, otherwise 0. */
- const int suppression_char;
+ int suppression_char;
/* Flag character to treat a length modifier as (ignored if length
modifiers not used). Need not be placed in flag_chars for conversion
specifiers, but is used to check for bad combinations such as length
modifier with assignment suppression in scanf. */
- const int length_code_char;
+ int length_code_char;
/* Pointer to type of argument expected if '*' is used for a width,
or NULL if '*' not used for widths. */
- tree *const width_type;
+ tree *width_type;
/* Pointer to type of argument expected if '*' is used for a precision,
or NULL if '*' not used for precisions. */
- tree *const precision_type;
+ tree *precision_type;
} format_kind_info;
@@ -572,6 +517,25 @@ static const format_length_info printf_length_specs[] =
{ NULL, 0, 0, NULL, 0, 0 }
};
+/* Length specifiers valid for asm_fprintf. */
+static const format_length_info asm_fprintf_length_specs[] =
+{
+ { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
+ { "w", FMT_LEN_none, STD_C89, NULL, 0, 0 },
+ { NULL, 0, 0, NULL, 0, 0 }
+};
+
+/* Length specifiers valid for GCC diagnostics. */
+static const format_length_info gcc_diag_length_specs[] =
+{
+ { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 },
+ { "w", FMT_LEN_none, STD_C89, NULL, 0, 0 },
+ { NULL, 0, 0, NULL, 0, 0 }
+};
+
+/* The custom diagnostics all accept the same length specifiers. */
+#define gcc_cdiag_length_specs gcc_diag_length_specs
+#define gcc_cxxdiag_length_specs gcc_diag_length_specs
/* This differs from printf_length_specs only in that "Z" is not accepted. */
static const format_length_info scanf_length_specs[] =
@@ -620,6 +584,52 @@ static const format_flag_pair printf_flag_pairs[] =
{ 0, 0, 0, 0 }
};
+static const format_flag_spec asm_fprintf_flag_specs[] =
+{
+ { ' ', 0, 0, N_("` ' flag"), N_("the ` ' printf flag"), STD_C89 },
+ { '+', 0, 0, N_("`+' flag"), N_("the `+' printf flag"), STD_C89 },
+ { '#', 0, 0, N_("`#' flag"), N_("the `#' printf flag"), STD_C89 },
+ { '0', 0, 0, N_("`0' flag"), N_("the `0' printf flag"), STD_C89 },
+ { '-', 0, 0, N_("`-' flag"), N_("the `-' printf flag"), STD_C89 },
+ { '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 }
+};
+
+static const format_flag_pair asm_fprintf_flag_pairs[] =
+{
+ { ' ', '+', 1, 0 },
+ { '0', '-', 1, 0 },
+ { '0', 'p', 1, 'i' },
+ { 0, 0, 0, 0 }
+};
+
+static const format_flag_pair gcc_diag_flag_pairs[] =
+{
+ { 0, 0, 0, 0 }
+};
+
+#define gcc_cdiag_flag_pairs gcc_diag_flag_pairs
+#define gcc_cxxdiag_flag_pairs gcc_diag_flag_pairs
+
+static const format_flag_spec gcc_diag_flag_specs[] =
+{
+ { '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 }
+};
+
+#define gcc_cdiag_flag_specs gcc_diag_flag_specs
+
+static const format_flag_spec gcc_cxxdiag_flag_specs[] =
+{
+ { '+', 0, 0, N_("`+' flag"), N_("the `+' printf flag"), STD_C89 },
+ { '#', 0, 0, N_("`#' flag"), N_("the `#' printf flag"), 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 }
+};
static const format_flag_spec scanf_flag_specs[] =
{
@@ -745,23 +755,112 @@ static const format_flag_pair strfmon_flag_pairs[] =
static const format_char_info print_char_table[] =
{
/* C89 conversion specifiers. */
- { "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "-wp0 +'I", "i" },
- { "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0#", "i" },
- { "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0'I", "i" },
- { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "" },
- { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "" },
- { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
- { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR" },
- { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c" },
- { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W" },
+ { "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM }, "-wp0 +'I", "i" },
+ { "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0#", "i" },
+ { "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM }, "-wp0'I", "i" },
+ { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'I", "" },
+ { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#I", "" },
+ { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
+ { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR" },
+ { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c" },
+ { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM }, "", "W" },
/* C99 conversion specifiers. */
- { "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'", "" },
- { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "" },
+ { "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#'I", "" },
+ { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN }, "-wp0 +#", "" },
/* X/Open conversion specifiers. */
- { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
- { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R" },
+ { "C", 0, STD_EXT, { TEX_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
+ { "S", 1, STD_EXT, { TEX_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "R" },
/* GNU conversion specifiers. */
- { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "" },
+ { "m", 0, STD_EXT, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "" },
+ { NULL, 0, 0, NOLENGTHS, NULL, NULL }
+};
+
+static const format_char_info asm_fprintf_char_table[] =
+{
+ /* C89 conversion specifiers. */
+ { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0 +", "i" },
+ { "oxX", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0#", "i" },
+ { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp0", "i" },
+ { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "" },
+ { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR" },
+
+ /* asm_fprintf conversion specifiers. */
+ { "O", 0, STD_C89, NOARGUMENTS, "", "" },
+ { "R", 0, STD_C89, NOARGUMENTS, "", "" },
+ { "I", 0, STD_C89, NOARGUMENTS, "", "" },
+ { "L", 0, STD_C89, NOARGUMENTS, "", "" },
+ { "U", 0, STD_C89, NOARGUMENTS, "", "" },
+ { "r", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "@", 0, STD_C89, NOARGUMENTS, "", "" },
+ { NULL, 0, 0, NOLENGTHS, NULL, NULL }
+};
+
+static const format_char_info gcc_diag_char_table[] =
+{
+ /* C89 conversion specifiers. */
+ { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "p", "cR" },
+ { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "c" },
+
+ /* Custom conversion specifiers. */
+
+ /* %H will require "location_t" at runtime. */
+ { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+
+ /* These will require a "tree" at runtime. */
+ { "J", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+
+ { "m", 0, STD_C89, NOARGUMENTS, "", "" },
+ { NULL, 0, 0, NOLENGTHS, NULL, NULL }
+};
+
+static const format_char_info gcc_cdiag_char_table[] =
+{
+ /* C89 conversion specifiers. */
+ { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "p", "cR" },
+ { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "c" },
+
+ /* Custom conversion specifiers. */
+
+ /* %H will require "location_t" at runtime. */
+ { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+
+ /* These will require a "tree" at runtime. */
+ { "DEFJT", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+
+ { "m", 0, STD_C89, NOARGUMENTS, "", "" },
+ { NULL, 0, 0, NOLENGTHS, NULL, NULL }
+};
+
+static const format_char_info gcc_cxxdiag_char_table[] =
+{
+ /* C89 conversion specifiers. */
+ { "di", 0, STD_C89, { T89_I, BADLEN, BADLEN, T89_L, T9L_LL, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "ox", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "u", 0, STD_C89, { T89_UI, BADLEN, BADLEN, T89_UL, T9L_ULL, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+ { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "p", "cR" },
+ { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "c" },
+
+ /* Custom conversion specifiers. */
+
+ /* %H will require "location_t" at runtime. */
+ { "H", 0, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+
+ /* These will require a "tree" at runtime. */
+ { "ADEFJTV",0,STD_C89,{ T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "+#", "" },
+
+ /* These accept either an `int' or an `enum tree_code' (which is handled as an `int'.) */
+ { "CLOPQ",0,STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "" },
+
+ { "m", 0, STD_C89, NOARGUMENTS, "", "" },
{ NULL, 0, 0, NOLENGTHS, NULL, NULL }
};
@@ -820,7 +919,7 @@ static const format_char_info monetary_char_table[] =
/* This must be in the same order as enum format_type. */
-static const format_kind_info format_types[] =
+static const format_kind_info format_types_orig[] =
{
{ "printf", printf_length_specs, print_char_table, " +#0-'I", NULL,
printf_flag_specs, printf_flag_pairs,
@@ -828,6 +927,30 @@ static const format_kind_info format_types[] =
'w', 0, 'p', 0, 'L',
&integer_type_node, &integer_type_node
},
+ { "asm_fprintf", asm_fprintf_length_specs, asm_fprintf_char_table, " +#0-", NULL,
+ asm_fprintf_flag_specs, asm_fprintf_flag_pairs,
+ FMT_FLAG_ARG_CONVERT|FMT_FLAG_EMPTY_PREC_OK,
+ 'w', 0, 'p', 0, 'L',
+ NULL, NULL
+ },
+ { "gcc_diag", gcc_diag_length_specs, gcc_diag_char_table, "", NULL,
+ gcc_diag_flag_specs, gcc_diag_flag_pairs,
+ FMT_FLAG_ARG_CONVERT,
+ 0, 0, 'p', 0, 'L',
+ NULL, &integer_type_node
+ },
+ { "gcc_cdiag", gcc_cdiag_length_specs, gcc_cdiag_char_table, "", NULL,
+ gcc_cdiag_flag_specs, gcc_cdiag_flag_pairs,
+ FMT_FLAG_ARG_CONVERT,
+ 0, 0, 'p', 0, 'L',
+ NULL, &integer_type_node
+ },
+ { "gcc_cxxdiag", gcc_cxxdiag_length_specs, gcc_cxxdiag_char_table, "+#", NULL,
+ gcc_cxxdiag_flag_specs, gcc_cxxdiag_flag_pairs,
+ FMT_FLAG_ARG_CONVERT,
+ 0, 0, 'p', 0, 'L',
+ NULL, &integer_type_node
+ },
{ "scanf", scanf_length_specs, scan_char_table, "*'I", NULL,
scanf_flag_specs, scanf_flag_pairs,
FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK,
@@ -846,6 +969,12 @@ static const format_kind_info format_types[] =
}
};
+/* This layer of indirection allows GCC to reassign format_types with
+ new data if necessary, while still allowing the original data to be
+ const. */
+static const format_kind_info *format_types = format_types_orig;
+/* We can modify this one. */
+static format_kind_info *dynamic_format_types;
/* Structure detailing the results of checking a format function call
where the format expression may be a conditional expression with
@@ -882,32 +1011,30 @@ typedef struct
int *status;
} format_check_context;
-static void check_format_info PARAMS ((int *, function_format_info *, tree));
-static void check_format_arg PARAMS ((void *, tree, unsigned HOST_WIDE_INT));
-static void check_format_info_main PARAMS ((int *, format_check_results *,
- function_format_info *,
- const char *, int, tree,
- unsigned HOST_WIDE_INT));
-static void status_warning PARAMS ((int *, const char *, ...))
+static void check_format_info (int *, function_format_info *, tree);
+static void check_format_arg (void *, tree, unsigned HOST_WIDE_INT);
+static void check_format_info_main (int *, format_check_results *,
+ function_format_info *,
+ const char *, int, tree,
+ unsigned HOST_WIDE_INT);
+static void status_warning (int *, const char *, ...)
ATTRIBUTE_PRINTF_2;
-static void init_dollar_format_checking PARAMS ((int, tree));
-static int maybe_read_dollar_number PARAMS ((int *, const char **, int,
- tree, tree *,
- const format_kind_info *));
-static void finish_dollar_format_checking PARAMS ((int *, format_check_results *, int));
+static void init_dollar_format_checking (int, tree);
+static int maybe_read_dollar_number (int *, const char **, int,
+ tree, tree *, const format_kind_info *);
+static void finish_dollar_format_checking (int *, format_check_results *, int);
-static const format_flag_spec *get_flag_spec PARAMS ((const format_flag_spec *,
- int, const char *));
+static const format_flag_spec *get_flag_spec (const format_flag_spec *,
+ int, const char *);
-static void check_format_types PARAMS ((int *, format_wanted_type *));
+static void check_format_types (int *, format_wanted_type *);
/* Decode a format type from a string, returning the type, or
format_type_error if not valid, in which case the caller should print an
error message. */
static enum format_type
-decode_format_type (s)
- const char *s;
+decode_format_type (const char *s)
{
int i;
int slen;
@@ -934,10 +1061,7 @@ decode_format_type (s)
attribute themselves. */
void
-check_function_format (status, attrs, params)
- int *status;
- tree attrs;
- tree params;
+check_function_format (int *status, tree attrs, tree params)
{
tree a;
@@ -994,25 +1118,24 @@ check_function_format (status, attrs, params)
it warns as usual by replicating the innards of the warning
function from diagnostic.c. */
static void
-status_warning VPARAMS ((int *status, const char *msgid, ...))
+status_warning (int *status, const char *msgid, ...)
{
diagnostic_info diagnostic ;
-
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, int *, status);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_list ap;
+
+ va_start (ap, msgid);
if (status)
*status = 1;
else
{
/* This duplicates the warning function behavior. */
- diagnostic_set_info (&diagnostic, _(msgid), &ap, input_filename, lineno,
- DK_WARNING);
+ diagnostic_set_info (&diagnostic, _(msgid), &ap,
+ input_location, DK_WARNING);
report_diagnostic (&diagnostic);
}
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Variables used by the checking of $ operand number formats. */
@@ -1031,9 +1154,7 @@ static int dollar_format_warned;
function; PARAMS is the list of arguments starting at this argument. */
static void
-init_dollar_format_checking (first_arg_num, params)
- int first_arg_num;
- tree params;
+init_dollar_format_checking (int first_arg_num, tree params)
{
tree oparams = params;
@@ -1088,14 +1209,9 @@ init_dollar_format_checking (first_arg_num, params)
a $ format is found, *FORMAT is updated to point just after it. */
static int
-maybe_read_dollar_number (status, format, dollar_needed, params, param_ptr,
- fki)
- int *status;
- const char **format;
- int dollar_needed;
- tree params;
- tree *param_ptr;
- const format_kind_info *fki;
+maybe_read_dollar_number (int *status, const char **format,
+ int dollar_needed, tree params, tree *param_ptr,
+ const format_kind_info *fki)
{
int argnum;
int overflow_flag;
@@ -1200,10 +1316,7 @@ maybe_read_dollar_number (status, format, dollar_needed, params, param_ptr,
pointers. */
static void
-finish_dollar_format_checking (status, res, pointer_gap_ok)
- int *status;
- format_check_results *res;
- int pointer_gap_ok;
+finish_dollar_format_checking (int *status, format_check_results *res, int pointer_gap_ok)
{
int i;
bool found_pointer_gap = false;
@@ -1238,10 +1351,7 @@ finish_dollar_format_checking (status, res, pointer_gap_ok)
of these is found, it is returned, otherwise NULL is returned. */
static const format_flag_spec *
-get_flag_spec (spec, flag, predicates)
- const format_flag_spec *spec;
- int flag;
- const char *predicates;
+get_flag_spec (const format_flag_spec *spec, int flag, const char *predicates)
{
int i;
for (i = 0; spec[i].flag_char != 0; i++)
@@ -1269,10 +1379,7 @@ get_flag_spec (spec, flag, predicates)
PARAMS is the list of argument values. */
static void
-check_format_info (status, info, params)
- int *status;
- function_format_info *info;
- tree params;
+check_format_info (int *status, function_format_info *info, tree params)
{
format_check_context format_ctx;
unsigned HOST_WIDE_INT arg_num;
@@ -1370,10 +1477,8 @@ check_format_info (status, info, params)
format_check_context. */
static void
-check_format_arg (ctx, format_tree, arg_num)
- void *ctx;
- tree format_tree;
- unsigned HOST_WIDE_INT arg_num;
+check_format_arg (void *ctx, tree format_tree,
+ unsigned HOST_WIDE_INT arg_num)
{
format_check_context *format_ctx = ctx;
format_check_results *res = format_ctx->res;
@@ -1529,15 +1634,10 @@ check_format_arg (ctx, format_tree, arg_num)
argument in the list of arguments. */
static void
-check_format_info_main (status, res, info, format_chars, format_length,
- params, arg_num)
- int *status;
- format_check_results *res;
- function_format_info *info;
- const char *format_chars;
- int format_length;
- tree params;
- unsigned HOST_WIDE_INT arg_num;
+check_format_info_main (int *status, format_check_results *res,
+ function_format_info *info, const char *format_chars,
+ int format_length, tree params,
+ unsigned HOST_WIDE_INT arg_num)
{
const char *orig_format_chars = format_chars;
tree first_fillin_param = params;
@@ -2160,9 +2260,7 @@ check_format_info_main (status, res, info, format_chars, format_length,
/* Check the argument types from a single format conversion (possibly
including width and precision arguments). */
static void
-check_format_types (status, types)
- int *status;
- format_wanted_type *types;
+check_format_types (int *status, format_wanted_type *types)
{
for (; types != 0; types = types->next)
{
@@ -2306,19 +2404,24 @@ check_format_types (status, types)
{
const char *this;
const char *that;
+ tree tmp;
+
+ tmp = TYPE_NAME (wanted_type);
+ if (TREE_CODE (tmp) == TYPE_DECL)
+ tmp = DECL_NAME (tmp);
+ this = IDENTIFIER_POINTER (tmp);
- this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type)));
that = 0;
if (TYPE_NAME (orig_cur_type) != 0
&& TREE_CODE (orig_cur_type) != INTEGER_TYPE
&& !(TREE_CODE (orig_cur_type) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (orig_cur_type)) == INTEGER_TYPE))
{
- if (TREE_CODE (TYPE_NAME (orig_cur_type)) == TYPE_DECL
- && DECL_NAME (TYPE_NAME (orig_cur_type)) != 0)
- that = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (orig_cur_type)));
- else
- that = IDENTIFIER_POINTER (TYPE_NAME (orig_cur_type));
+ tmp = TYPE_NAME (orig_cur_type);
+ if (TREE_CODE (tmp) == TYPE_DECL)
+ tmp = DECL_NAME (tmp);
+ if (tmp)
+ that = IDENTIFIER_POINTER (tmp);
}
/* A nameless type can't possibly match what the format wants.
@@ -2358,3 +2461,287 @@ check_format_types (status, types)
}
}
}
+
+/* Given a format_char_info array FCI, and a character C, this function
+ returns the index into the conversion_specs where that specifier's
+ data is located. If the character isn't found it aborts. */
+static unsigned int
+find_char_info_specifier_index (const format_char_info *fci, int c)
+{
+ unsigned int i = 0;
+
+ while (fci->format_chars)
+ {
+ if (strchr (fci->format_chars, c))
+ return i;
+ i++; fci++;
+ }
+
+ /* We shouldn't be looking for a non-existent specifier. */
+ abort ();
+}
+
+/* Given a format_length_info array FLI, and a character C, this
+ function returns the index into the conversion_specs where that
+ modifier's data is located. If the character isn't found it
+ aborts. */
+static unsigned int
+find_length_info_modifier_index (const format_length_info *fli, int c)
+{
+ unsigned int i = 0;
+
+ while (fli->name)
+ {
+ if (strchr (fli->name, c))
+ return i;
+ i++; fli++;
+ }
+
+ /* We shouldn't be looking for a non-existent modifier. */
+ abort ();
+}
+
+/* Determine the type of HOST_WIDE_INT in the code being compiled for
+ use in GCC's __asm_fprintf__ custom format attribute. You must
+ have set dynamic_format_types before calling this function. */
+static void
+init_dynamic_asm_fprintf_info (void)
+{
+ static tree hwi;
+
+ if (!hwi)
+ {
+ format_length_info *new_asm_fprintf_length_specs;
+ unsigned int i;
+
+ /* Find the underlying type for HOST_WIDE_INT. For the %w
+ length modifier to work, one must have issued: "typedef
+ HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
+ prior to using that modifier. */
+ if (!(hwi = maybe_get_identifier ("__gcc_host_wide_int__"))
+ || !(hwi = DECL_ORIGINAL_TYPE (identifier_global_value (hwi))))
+ abort ();
+
+ /* Create a new (writable) copy of asm_fprintf_length_specs. */
+ new_asm_fprintf_length_specs = xmemdup (asm_fprintf_length_specs,
+ sizeof (asm_fprintf_length_specs),
+ sizeof (asm_fprintf_length_specs));
+
+ /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
+ i = find_length_info_modifier_index (new_asm_fprintf_length_specs, 'w');
+ if (hwi == long_integer_type_node)
+ new_asm_fprintf_length_specs[i].index = FMT_LEN_l;
+ else if (hwi == long_long_integer_type_node)
+ new_asm_fprintf_length_specs[i].index = FMT_LEN_ll;
+ else
+ abort ();
+
+ /* Assign the new data for use. */
+ dynamic_format_types[asm_fprintf_format_type].length_char_specs =
+ new_asm_fprintf_length_specs;
+ }
+}
+
+/* Determine the types of "tree" and "location_t" in the code being
+ compiled for use in GCC's diagnostic custom format attributes. You
+ must have set dynamic_format_types before calling this function. */
+static void
+init_dynamic_diag_info (void)
+{
+ static tree t, loc, hwi;
+
+ if (!loc || !t || !hwi)
+ {
+ static format_char_info *diag_fci, *cdiag_fci, *cxxdiag_fci;
+ static format_length_info *diag_ls;
+ unsigned int i;
+
+ /* For the GCC-diagnostics custom format specifiers to work, one
+ must have declared `tree' and/or `location_t' prior to using
+ those attributes. If we haven't seen these declarations then
+ you shouldn't use the specifiers requiring these types.
+ However we don't force a hard ICE because we may see only one
+ or the other type. */
+ if ((loc = maybe_get_identifier ("location_t")))
+ loc = TREE_TYPE (identifier_global_value (loc));
+
+ /* We need to grab the underlying `union tree_node' so peek into
+ an extra type level. */
+ if ((t = maybe_get_identifier ("tree")))
+ t = TREE_TYPE (TREE_TYPE (identifier_global_value (t)));
+
+ /* Find the underlying type for HOST_WIDE_INT. For the %w
+ length modifier to work, one must have issued: "typedef
+ HOST_WIDE_INT __gcc_host_wide_int__;" in one's source code
+ prior to using that modifier. */
+ if ((hwi = maybe_get_identifier ("__gcc_host_wide_int__")))
+ hwi = DECL_ORIGINAL_TYPE (identifier_global_value (hwi));
+
+ /* Assign the new data for use. */
+
+ /* All the GCC diag formats use the same length specs. */
+ if (! diag_ls)
+ dynamic_format_types[gcc_diag_format_type].length_char_specs =
+ dynamic_format_types[gcc_cdiag_format_type].length_char_specs =
+ dynamic_format_types[gcc_cxxdiag_format_type].length_char_specs =
+ diag_ls = xmemdup (gcc_diag_length_specs,
+ sizeof (gcc_diag_length_specs),
+ sizeof (gcc_diag_length_specs));
+ if (hwi)
+ {
+ /* HOST_WIDE_INT must be one of 'long' or 'long long'. */
+ i = find_length_info_modifier_index (diag_ls, 'w');
+ if (hwi == long_integer_type_node)
+ diag_ls[i].index = FMT_LEN_l;
+ else if (hwi == long_long_integer_type_node)
+ diag_ls[i].index = FMT_LEN_ll;
+ else
+ abort ();
+ }
+
+ /* Handle the __gcc_diag__ format specifics. */
+ if (! diag_fci)
+ dynamic_format_types[gcc_diag_format_type].conversion_specs =
+ diag_fci = xmemdup (gcc_diag_char_table,
+ sizeof(gcc_diag_char_table),
+ sizeof(gcc_diag_char_table));
+ if (loc)
+ {
+ i = find_char_info_specifier_index (diag_fci, 'H');
+ diag_fci[i].types[0].type = &loc;
+ diag_fci[i].pointer_count = 1;
+ }
+ if (t)
+ {
+ i = find_char_info_specifier_index (diag_fci, 'J');
+ diag_fci[i].types[0].type = &t;
+ diag_fci[i].pointer_count = 1;
+ }
+
+ /* Handle the __gcc_cdiag__ format specifics. */
+ if (! cdiag_fci)
+ dynamic_format_types[gcc_cdiag_format_type].conversion_specs =
+ cdiag_fci = xmemdup (gcc_cdiag_char_table,
+ sizeof(gcc_cdiag_char_table),
+ sizeof(gcc_cdiag_char_table));
+ if (loc)
+ {
+ i = find_char_info_specifier_index (cdiag_fci, 'H');
+ cdiag_fci[i].types[0].type = &loc;
+ cdiag_fci[i].pointer_count = 1;
+ }
+ if (t)
+ {
+ /* All specifiers taking a tree share the same struct. */
+ i = find_char_info_specifier_index (cdiag_fci, 'D');
+ cdiag_fci[i].types[0].type = &t;
+ cdiag_fci[i].pointer_count = 1;
+ i = find_char_info_specifier_index (cdiag_fci, 'J');
+ cdiag_fci[i].types[0].type = &t;
+ cdiag_fci[i].pointer_count = 1;
+ }
+
+ /* Handle the __gcc_cxxdiag__ format specifics. */
+ if (! cxxdiag_fci)
+ dynamic_format_types[gcc_cxxdiag_format_type].conversion_specs =
+ cxxdiag_fci = xmemdup (gcc_cxxdiag_char_table,
+ sizeof(gcc_cxxdiag_char_table),
+ sizeof(gcc_cxxdiag_char_table));
+ if (loc)
+ {
+ i = find_char_info_specifier_index (cxxdiag_fci, 'H');
+ cxxdiag_fci[i].types[0].type = &loc;
+ cxxdiag_fci[i].pointer_count = 1;
+ }
+ if (t)
+ {
+ /* All specifiers taking a tree share the same struct. */
+ i = find_char_info_specifier_index (cxxdiag_fci, 'D');
+ cxxdiag_fci[i].types[0].type = &t;
+ cxxdiag_fci[i].pointer_count = 1;
+ i = find_char_info_specifier_index (cxxdiag_fci, 'J');
+ cxxdiag_fci[i].types[0].type = &t;
+ cxxdiag_fci[i].pointer_count = 1;
+ }
+ }
+}
+
+/* Handle a "format" attribute; arguments as in
+ struct attribute_spec.handler. */
+tree
+handle_format_attribute (tree *node, tree name ATTRIBUTE_UNUSED, tree args,
+ int flags, bool *no_add_attrs)
+{
+ tree type = *node;
+ function_format_info info;
+ tree argument;
+
+ if (!decode_format_attr (args, &info, 0))
+ {
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
+ argument = TYPE_ARG_TYPES (type);
+ if (argument)
+ {
+ if (!check_format_string (argument, info.format_num, flags,
+ no_add_attrs))
+ return NULL_TREE;
+
+ if (info.first_arg_num != 0)
+ {
+ unsigned HOST_WIDE_INT arg_num = 1;
+
+ /* Verify that first_arg_num points to the last arg,
+ the ... */
+ while (argument)
+ arg_num++, argument = TREE_CHAIN (argument);
+
+ if (arg_num != info.first_arg_num)
+ {
+ if (!(flags & (int) ATTR_FLAG_BUILT_IN))
+ error ("args to be formatted is not '...'");
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+ }
+ }
+
+ if (info.format_type == strftime_format_type && info.first_arg_num != 0)
+ {
+ error ("strftime formats cannot format arguments");
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
+ /* If this is a custom GCC-internal format type, we have to
+ initialize certain bits a runtime. */
+ if (info.format_type == asm_fprintf_format_type
+ || info.format_type == gcc_diag_format_type
+ || info.format_type == gcc_cdiag_format_type
+ || info.format_type == gcc_cxxdiag_format_type)
+ {
+ /* Our first time through, we have to make sure that our
+ format_type data is allocated dynamically and is modifiable. */
+ if (!dynamic_format_types)
+ format_types = dynamic_format_types =
+ xmemdup (format_types_orig, sizeof (format_types_orig),
+ sizeof (format_types_orig));
+
+ /* If this is format __asm_fprintf__, we have to initialize
+ GCC's notion of HOST_WIDE_INT for checking %wd. */
+ if (info.format_type == asm_fprintf_format_type)
+ init_dynamic_asm_fprintf_info();
+ /* If this is one of the diagnostic attributes, then we have to
+ initialize `location_t' and `tree' at runtime. */
+ else if (info.format_type == gcc_diag_format_type
+ || info.format_type == gcc_cdiag_format_type
+ || info.format_type == gcc_cxxdiag_format_type)
+ init_dynamic_diag_info();
+ else
+ abort();
+ }
+
+ return NULL_TREE;
+}
diff --git a/contrib/gcc/c-incpath.c b/contrib/gcc/c-incpath.c
new file mode 100644
index 000000000000..b90bb7fde5d1
--- /dev/null
+++ b/contrib/gcc/c-incpath.c
@@ -0,0 +1,364 @@
+/* Set up combined include path chain for the preprocessor.
+ Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ Broken out of cppinit.c and cppfiles.c and rewritten Mar 2003.
+
+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 2, 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, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "cpplib.h"
+#include "prefix.h"
+#include "intl.h"
+#include "c-incpath.h"
+#include "cppdefault.h"
+
+/* Windows does not natively support inodes, and neither does MSDOS.
+ Cygwin's emulation can generate non-unique inodes, so don't use it.
+ VMS has non-numeric inodes. */
+#ifdef VMS
+# define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
+# define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
+#else
+# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
+# define INO_T_EQ(A, B) 0
+# else
+# define INO_T_EQ(A, B) ((A) == (B))
+# endif
+# define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
+#endif
+
+static void add_env_var_paths (const char *, int);
+static void add_standard_paths (const char *, const char *, int);
+static void free_path (struct cpp_dir *, int);
+static void merge_include_chains (cpp_reader *, int);
+static struct cpp_dir *remove_duplicates (cpp_reader *, struct cpp_dir *,
+ struct cpp_dir *,
+ struct cpp_dir *, int);
+
+/* Include chains heads and tails. */
+static struct cpp_dir *heads[4];
+static struct cpp_dir *tails[4];
+static bool quote_ignores_source_dir;
+enum { REASON_QUIET = 0, REASON_NOENT, REASON_DUP, REASON_DUP_SYS };
+
+/* Free an element of the include chain, possibly giving a reason. */
+static void
+free_path (struct cpp_dir *path, int reason)
+{
+ switch (reason)
+ {
+ case REASON_DUP:
+ case REASON_DUP_SYS:
+ fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), path->name);
+ if (reason == REASON_DUP_SYS)
+ fprintf (stderr,
+ _(" as it is a non-system directory that duplicates a system directory\n"));
+ break;
+
+ case REASON_NOENT:
+ fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"),
+ path->name);
+ break;
+
+ case REASON_QUIET:
+ default:
+ break;
+ }
+
+ free (path->name);
+ free (path);
+}
+
+/* Read ENV_VAR for a PATH_SEPARATOR-separated list of file names; and
+ append all the names to the search path CHAIN. */
+static void
+add_env_var_paths (const char *env_var, int chain)
+{
+ char *p, *q, *path;
+
+ GET_ENVIRONMENT (q, env_var);
+
+ if (!q)
+ return;
+
+ for (p = q; *q; p = q + 1)
+ {
+ q = p;
+ while (*q != 0 && *q != PATH_SEPARATOR)
+ q++;
+
+ if (p == q)
+ path = xstrdup (".");
+ else
+ {
+ path = xmalloc (q - p + 1);
+ memcpy (path, p, q - p);
+ path[q - p] = '\0';
+ }
+
+ add_path (path, chain, chain == SYSTEM);
+ }
+}
+
+/* Append the standard include chain defined in cppdefault.c. */
+static void
+add_standard_paths (const char *sysroot, const char *iprefix, int cxx_stdinc)
+{
+ const struct default_include *p;
+ size_t len;
+
+ if (iprefix && (len = cpp_GCC_INCLUDE_DIR_len) != 0)
+ {
+ /* Look for directories that start with the standard prefix.
+ "Translate" them, ie. replace /usr/local/lib/gcc... with
+ IPREFIX and search them first. */
+ for (p = cpp_include_defaults; p->fname; p++)
+ {
+ if (!p->cplusplus || cxx_stdinc)
+ {
+ /* Should we be translating sysrooted dirs too? Assume
+ that iprefix and sysroot are mutually exclusive, for
+ now. */
+ if (sysroot && p->add_sysroot)
+ continue;
+ if (!strncmp (p->fname, cpp_GCC_INCLUDE_DIR, len))
+ {
+ char *str = concat (iprefix, p->fname + len, NULL);
+ add_path (str, SYSTEM, p->cxx_aware);
+ }
+ }
+ }
+ }
+
+ for (p = cpp_include_defaults; p->fname; p++)
+ {
+ if (!p->cplusplus || cxx_stdinc)
+ {
+ char *str;
+
+ /* Should this directory start with the sysroot? */
+ if (sysroot && p->add_sysroot)
+ str = concat (sysroot, p->fname, NULL);
+ else
+ str = update_path (p->fname, p->component);
+
+ add_path (str, SYSTEM, p->cxx_aware);
+ }
+ }
+}
+
+/* For each duplicate path in chain HEAD, keep just the first one.
+ Remove each path in chain HEAD that also exists in chain SYSTEM.
+ Set the NEXT pointer of the last path in the resulting chain to
+ JOIN, unless it duplicates JOIN in which case the last path is
+ removed. Return the head of the resulting chain. Any of HEAD,
+ JOIN and SYSTEM can be NULL. */
+static struct cpp_dir *
+remove_duplicates (cpp_reader *pfile, struct cpp_dir *head,
+ struct cpp_dir *system, struct cpp_dir *join,
+ int verbose)
+{
+ struct cpp_dir **pcur, *tmp, *cur;
+ struct stat st;
+
+ for (pcur = &head; *pcur; )
+ {
+ int reason = REASON_QUIET;
+
+ cur = *pcur;
+
+ if (stat (cur->name, &st))
+ {
+ /* Dirs that don't exist are silently ignored, unless verbose. */
+ if (errno != ENOENT)
+ cpp_errno (pfile, CPP_DL_ERROR, cur->name);
+ else
+ reason = REASON_NOENT;
+ }
+ else if (!S_ISDIR (st.st_mode))
+ cpp_error_with_line (pfile, CPP_DL_ERROR, 0, 0,
+ "%s: not a directory", cur->name);
+ else
+ {
+ INO_T_COPY (cur->ino, st.st_ino);
+ cur->dev = st.st_dev;
+
+ /* Remove this one if it is in the system chain. */
+ reason = REASON_DUP_SYS;
+ for (tmp = system; tmp; tmp = tmp->next)
+ if (INO_T_EQ (tmp->ino, cur->ino) && tmp->dev == cur->dev)
+ break;
+
+ if (!tmp)
+ {
+ /* Duplicate of something earlier in the same chain? */
+ reason = REASON_DUP;
+ for (tmp = head; tmp != cur; tmp = tmp->next)
+ if (INO_T_EQ (cur->ino, tmp->ino) && cur->dev == tmp->dev)
+ break;
+
+ if (tmp == cur
+ /* Last in the chain and duplicate of JOIN? */
+ && !(cur->next == NULL && join
+ && INO_T_EQ (cur->ino, join->ino)
+ && cur->dev == join->dev))
+ {
+ /* Unique, so keep this directory. */
+ pcur = &cur->next;
+ continue;
+ }
+ }
+ }
+
+ /* Remove this entry from the chain. */
+ *pcur = cur->next;
+ free_path (cur, verbose ? reason: REASON_QUIET);
+ }
+
+ *pcur = join;
+ return head;
+}
+
+/* Merge the four include chains together in the order quote, bracket,
+ system, after. Remove duplicate dirs (as determined by
+ INO_T_EQ()).
+
+ We can't just merge the lists and then uniquify them because then
+ we may lose directories from the <> search path that should be
+ there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however safe
+ to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written -Ibar -I- -Ifoo
+ -Iquux. */
+static void
+merge_include_chains (cpp_reader *pfile, int verbose)
+{
+ /* Join the SYSTEM and AFTER chains. Remove duplicates in the
+ resulting SYSTEM chain. */
+ if (heads[SYSTEM])
+ tails[SYSTEM]->next = heads[AFTER];
+ else
+ heads[SYSTEM] = heads[AFTER];
+ heads[SYSTEM] = remove_duplicates (pfile, heads[SYSTEM], 0, 0, verbose);
+
+ /* Remove duplicates from BRACKET that are in itself or SYSTEM, and
+ join it to SYSTEM. */
+ heads[BRACKET] = remove_duplicates (pfile, heads[BRACKET], heads[SYSTEM],
+ heads[SYSTEM], verbose);
+
+ /* Remove duplicates from QUOTE that are in itself or SYSTEM, and
+ join it to BRACKET. */
+ heads[QUOTE] = remove_duplicates (pfile, heads[QUOTE], heads[SYSTEM],
+ heads[BRACKET], verbose);
+
+ /* If verbose, print the list of dirs to search. */
+ if (verbose)
+ {
+ struct cpp_dir *p;
+
+ fprintf (stderr, _("#include \"...\" search starts here:\n"));
+ for (p = heads[QUOTE];; p = p->next)
+ {
+ if (p == heads[BRACKET])
+ fprintf (stderr, _("#include <...> search starts here:\n"));
+ if (!p)
+ break;
+ fprintf (stderr, " %s\n", p->name);
+ }
+ fprintf (stderr, _("End of search list.\n"));
+ }
+}
+
+/* Use given -I paths for #include "..." but not #include <...>, and
+ don't search the directory of the present file for #include "...".
+ (Note that -I. -I- is not the same as the default setup; -I. uses
+ the compiler's working dir.) */
+void
+split_quote_chain (void)
+{
+ heads[QUOTE] = heads[BRACKET];
+ tails[QUOTE] = tails[BRACKET];
+ heads[BRACKET] = NULL;
+ tails[BRACKET] = NULL;
+ /* This is NOT redundant. */
+ quote_ignores_source_dir = true;
+}
+
+/* Add PATH to the include chain CHAIN. PATH must be malloc-ed and
+ NUL-terminated. */
+void
+add_path (char *path, int chain, int cxx_aware)
+{
+ struct cpp_dir *p;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Convert all backslashes to slashes. The native CRT stat()
+ function does not recognise a directory that ends in a backslash
+ (unless it is a drive root dir, such "c:\"). Forward slashes,
+ trailing or otherwise, cause no problems for stat(). */
+ char* c;
+ for (c = path; *c; c++)
+ if (*c == '\\') *c = '/';
+#endif
+
+ p = xmalloc (sizeof (struct cpp_dir));
+ p->next = NULL;
+ p->name = path;
+ if (chain == SYSTEM || chain == AFTER)
+ p->sysp = 1 + !cxx_aware;
+ else
+ p->sysp = 0;
+
+ if (tails[chain])
+ tails[chain]->next = p;
+ else
+ heads[chain] = p;
+ tails[chain] = p;
+}
+
+/* Exported function to handle include chain merging, duplicate
+ removal, and registration with cpplib. */
+void
+register_include_chains (cpp_reader *pfile, const char *sysroot,
+ const char *iprefix, int stdinc, int cxx_stdinc,
+ int verbose)
+{
+ static const char *const lang_env_vars[] =
+ { "C_INCLUDE_PATH", "CPLUS_INCLUDE_PATH",
+ "OBJC_INCLUDE_PATH", "OBJCPLUS_INCLUDE_PATH" };
+ cpp_options *cpp_opts = cpp_get_options (pfile);
+ size_t idx = (cpp_opts->objc ? 2: 0);
+
+ if (cpp_opts->cplusplus)
+ idx++;
+ else
+ cxx_stdinc = false;
+
+ /* CPATH and language-dependent environment variables may add to the
+ include chain. */
+ add_env_var_paths ("CPATH", BRACKET);
+ add_env_var_paths (lang_env_vars[idx], SYSTEM);
+
+ /* Finally chain on the standard directories. */
+ if (stdinc)
+ add_standard_paths (sysroot, iprefix, cxx_stdinc);
+
+ merge_include_chains (pfile, verbose);
+
+ cpp_set_include_chains (pfile, heads[QUOTE], heads[BRACKET],
+ quote_ignores_source_dir);
+}
diff --git a/contrib/gcc/c-incpath.h b/contrib/gcc/c-incpath.h
new file mode 100644
index 000000000000..31ed657da2a5
--- /dev/null
+++ b/contrib/gcc/c-incpath.h
@@ -0,0 +1,23 @@
+/* Set up combined include path for the preprocessor.
+ Copyright (C) 2003 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 2, 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, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+extern void split_quote_chain (void);
+extern void add_path (char *, int, int);
+extern void register_include_chains (cpp_reader *, const char *,
+ const char *, int, int, int);
+
+enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };
diff --git a/contrib/gcc/c-lang.c b/contrib/gcc/c-lang.c
index 8614e2500e5e..1a097e277979 100644
--- a/contrib/gcc/c-lang.c
+++ b/contrib/gcc/c-lang.c
@@ -1,6 +1,6 @@
/* Language-specific hook definitions for C front end.
Copyright (C) 1991, 1995, 1997, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,14 +22,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "c-tree.h"
#include "c-common.h"
#include "ggc.h"
#include "langhooks.h"
#include "langhooks-def.h"
+#include "diagnostic.h"
+#include "c-pretty-print.h"
-static void c_init_options PARAMS ((void));
+static void c_initialize_diagnostics (diagnostic_context *);
+
+enum c_language_kind c_language = clk_c;
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
@@ -40,9 +46,13 @@ static void c_init_options PARAMS ((void));
#undef LANG_HOOKS_FINISH
#define LANG_HOOKS_FINISH c_common_finish
#undef LANG_HOOKS_INIT_OPTIONS
-#define LANG_HOOKS_INIT_OPTIONS c_init_options
-#undef LANG_HOOKS_DECODE_OPTION
-#define LANG_HOOKS_DECODE_OPTION c_common_decode_option
+#define LANG_HOOKS_INIT_OPTIONS c_common_init_options
+#undef LANG_HOOKS_INITIALIZE_DIAGNOSTICS
+#define LANG_HOOKS_INITIALIZE_DIAGNOSTICS c_initialize_diagnostics
+#undef LANG_HOOKS_HANDLE_OPTION
+#define LANG_HOOKS_HANDLE_OPTION c_common_handle_option
+#undef LANG_HOOKS_MISSING_ARGUMENT
+#define LANG_HOOKS_MISSING_ARGUMENT c_common_missing_argument
#undef LANG_HOOKS_POST_OPTIONS
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
#undef LANG_HOOKS_GET_ALIAS_SET
@@ -57,14 +67,16 @@ static void c_init_options PARAMS ((void));
#define LANG_HOOKS_PARSE_FILE c_common_parse_file
#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion
-#undef LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES
-#define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES c_insert_default_attributes
#undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl
#undef LANG_HOOKS_UNSAFE_FOR_REEVAL
#define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval
#undef LANG_HOOKS_STATICP
#define LANG_HOOKS_STATICP c_staticp
+#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
+#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME c_static_assembler_name
+#undef LANG_HOOKS_NO_BODY_BLOCKS
+#define LANG_HOOKS_NO_BODY_BLOCKS true
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
#undef LANG_HOOKS_PRINT_IDENTIFIER
@@ -75,6 +87,11 @@ static void c_init_options PARAMS ((void));
#define LANG_HOOKS_FUNCTION_LEAVE_NESTED c_pop_function_context
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL c_dup_lang_specific_decl
+#undef LANG_HOOKS_DECL_UNINIT
+#define LANG_HOOKS_DECL_UNINIT c_decl_uninit
+
+#undef LANG_HOOKS_RTL_EXPAND_STMT
+#define LANG_HOOKS_RTL_EXPAND_STMT expand_stmt
/* Attribute hooks. */
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
@@ -94,9 +111,14 @@ static void c_init_options PARAMS ((void));
#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
c_convert_parm_for_inlining
+#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS
+#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS c_estimate_num_insns
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN c_dump_tree
+#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
+#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION c_expand_body
+
#undef LANG_HOOKS_TYPE_FOR_MODE
#define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode
#undef LANG_HOOKS_TYPE_FOR_SIZE
@@ -111,6 +133,11 @@ static void c_init_options PARAMS ((void));
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR c_incomplete_type_error
#undef LANG_HOOKS_TYPE_PROMOTES_TO
#define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to
+#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
+#define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
+
+#undef LANG_HOOKS_WRITE_GLOBALS
+#define LANG_HOOKS_WRITE_GLOBALS c_write_global_declarations
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
@@ -152,69 +179,23 @@ const char *const tree_code_name[] = {
};
#undef DEFTREECODE
-static void
-c_init_options ()
-{
- c_common_init_options (clk_c);
-}
-
-/* Used by c-lex.c, but only for objc. */
-
-tree
-lookup_interface (arg)
- tree arg ATTRIBUTE_UNUSED;
-{
- return 0;
-}
-
-tree
-is_class_name (arg)
- tree arg ATTRIBUTE_UNUSED;
-{
- return 0;
-}
-
-tree
-objc_is_id (arg)
- tree arg ATTRIBUTE_UNUSED;
-{
- return 0;
-}
-
void
-objc_check_decl (decl)
- tree decl ATTRIBUTE_UNUSED;
-{
-}
-
-int
-objc_comptypes (lhs, rhs, reflexive)
- tree lhs ATTRIBUTE_UNUSED;
- tree rhs ATTRIBUTE_UNUSED;
- int reflexive ATTRIBUTE_UNUSED;
-{
- return -1;
-}
-
-tree
-objc_message_selector ()
+finish_file (void)
{
- return 0;
-}
-
-/* Used by c-typeck.c (build_external_ref), but only for objc. */
-
-tree
-lookup_objc_ivar (id)
- tree id ATTRIBUTE_UNUSED;
-{
- return 0;
+ c_objc_common_finish_file ();
}
-void
-finish_file ()
+static void
+c_initialize_diagnostics (diagnostic_context *context)
{
- c_objc_common_finish_file ();
+ pretty_printer *base = context->printer;
+ c_pretty_printer *pp = xmalloc (sizeof (c_pretty_printer));
+ memcpy (pp_base (pp), base, sizeof (pretty_printer));
+ pp_c_pretty_printer_init (pp);
+ context->printer = (pretty_printer *) pp;
+
+ /* It is safe to free this object because it was previously malloc()'d. */
+ free (base);
}
#include "gtype-c.h"
diff --git a/contrib/gcc/c-lex.c b/contrib/gcc/c-lex.c
index c852e311cb99..aba571fab9a2 100644
--- a/contrib/gcc/c-lex.c
+++ b/contrib/gcc/c-lex.c
@@ -1,6 +1,6 @@
/* Mainly the interface between cpplib and the C front ends.
Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997
- 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "real.h"
#include "rtl.h"
@@ -40,24 +42,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "splay-tree.h"
#include "debug.h"
-#ifdef MULTIBYTE_CHARS
-#include "mbchar.h"
-#include <locale.h>
-#endif /* MULTIBYTE_CHARS */
-
/* The current line map. */
static const struct line_map *map;
-/* The line used to refresh the lineno global variable after each token. */
-static unsigned int src_lineno;
-
/* We may keep statistics about how long which files took to compile. */
static int header_time, body_time;
static splay_tree file_info_tree;
-/* File used for outputting assembler code. */
-extern FILE *asm_out_file;
-
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE TYPE_PRECISION (wchar_type_node)
@@ -67,33 +58,24 @@ extern FILE *asm_out_file;
int pending_lang_change; /* If we need to switch languages - C++ only */
int c_header_level; /* depth in C headers - C++ only */
-/* Nonzero tells yylex to ignore \ in string constants. */
-static int ignore_escape_flag;
-
-static tree interpret_integer PARAMS ((const cpp_token *, unsigned int));
-static tree interpret_float PARAMS ((const cpp_token *, unsigned int));
+static tree interpret_integer (const cpp_token *, unsigned int);
+static tree interpret_float (const cpp_token *, unsigned int);
static enum integer_type_kind
- narrowest_unsigned_type PARAMS ((tree, unsigned int));
+ narrowest_unsigned_type (tree, unsigned int);
static enum integer_type_kind
- narrowest_signed_type PARAMS ((tree, unsigned int));
-static tree lex_string PARAMS ((const unsigned char *, unsigned int,
- int));
-static tree lex_charconst PARAMS ((const cpp_token *));
-static void update_header_times PARAMS ((const char *));
-static int dump_one_header PARAMS ((splay_tree_node, void *));
-static void cb_line_change PARAMS ((cpp_reader *, const cpp_token *, int));
-static void cb_ident PARAMS ((cpp_reader *, unsigned int,
- const cpp_string *));
-static void cb_file_change PARAMS ((cpp_reader *, const struct line_map *));
-static void cb_def_pragma PARAMS ((cpp_reader *, unsigned int));
-static void cb_define PARAMS ((cpp_reader *, unsigned int,
- cpp_hashnode *));
-static void cb_undef PARAMS ((cpp_reader *, unsigned int,
- cpp_hashnode *));
+ narrowest_signed_type (tree, unsigned int);
+static enum cpp_ttype lex_string (const cpp_token *, tree *, bool);
+static tree lex_charconst (const cpp_token *);
+static void update_header_times (const char *);
+static int dump_one_header (splay_tree_node, void *);
+static void cb_line_change (cpp_reader *, const cpp_token *, int);
+static void cb_ident (cpp_reader *, unsigned int, const cpp_string *);
+static void cb_def_pragma (cpp_reader *, unsigned int);
+static void cb_define (cpp_reader *, unsigned int, cpp_hashnode *);
+static void cb_undef (cpp_reader *, unsigned int, cpp_hashnode *);
-const char *
-init_c_lex (filename)
- const char *filename;
+void
+init_c_lex (void)
{
struct cpp_callbacks *cb;
struct c_fileinfo *toplevel;
@@ -109,19 +91,14 @@ init_c_lex (filename)
body_time = get_run_time ();
toplevel->time = body_time;
}
-
-#ifdef MULTIBYTE_CHARS
- /* Change to the native locale for multibyte conversions. */
- setlocale (LC_CTYPE, "");
- GET_ENVIRONMENT (literal_codeset, "LANG");
-#endif
cb = cpp_get_callbacks (parse_in);
cb->line_change = cb_line_change;
cb->ident = cb_ident;
- cb->file_change = cb_file_change;
cb->def_pragma = cb_def_pragma;
+ cb->valid_pch = c_common_valid_pch;
+ cb->read_pch = c_common_read_pch;
/* Set the debug callbacks if we can use them. */
if (debug_info_level == DINFO_LEVEL_VERBOSE
@@ -131,38 +108,10 @@ init_c_lex (filename)
cb->define = cb_define;
cb->undef = cb_undef;
}
-
- /* Start it at 0. */
- lineno = 0;
-
- return cpp_read_main_file (parse_in, filename, ident_hash);
-}
-
-/* A thin wrapper around the real parser that initializes the
- integrated preprocessor after debug output has been initialized.
- Also, make sure the start_source_file debug hook gets called for
- the primary source file. */
-
-void
-c_common_parse_file (set_yydebug)
- int set_yydebug ATTRIBUTE_UNUSED;
-{
-#if YYDEBUG != 0
- yydebug = set_yydebug;
-#else
- warning ("YYDEBUG not defined");
-#endif
-
- (*debug_hooks->start_source_file) (lineno, input_filename);
- cpp_finish_options (parse_in);
-
- yyparse ();
- free_parser_stacks ();
}
struct c_fileinfo *
-get_fileinfo (name)
- const char *name;
+get_fileinfo (const char *name)
{
splay_tree_node n;
struct c_fileinfo *fi;
@@ -171,7 +120,7 @@ get_fileinfo (name)
if (n)
return (struct c_fileinfo *) n->value;
- fi = (struct c_fileinfo *) xmalloc (sizeof (struct c_fileinfo));
+ fi = xmalloc (sizeof (struct c_fileinfo));
fi->time = 0;
fi->interface_only = 0;
fi->interface_unknown = 1;
@@ -181,8 +130,7 @@ get_fileinfo (name)
}
static void
-update_header_times (name)
- const char *name;
+update_header_times (const char *name)
{
/* Changing files again. This means currently collected time
is charged against header time, and body time starts back at 0. */
@@ -197,9 +145,7 @@ update_header_times (name)
}
static int
-dump_one_header (n, dummy)
- splay_tree_node n;
- void *dummy ATTRIBUTE_UNUSED;
+dump_one_header (splay_tree_node n, void *dummy ATTRIBUTE_UNUSED)
{
print_time ((const char *) n->key,
((struct c_fileinfo *) n->value)->time);
@@ -207,7 +153,7 @@ dump_one_header (n, dummy)
}
void
-dump_time_statistics ()
+dump_time_statistics (void)
{
struct c_fileinfo *file = get_fileinfo (input_filename);
int this_time = get_run_time ();
@@ -224,17 +170,20 @@ dump_time_statistics ()
}
static void
-cb_ident (pfile, line, str)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
- unsigned int line ATTRIBUTE_UNUSED;
- const cpp_string *str ATTRIBUTE_UNUSED;
+cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED,
+ unsigned int line ATTRIBUTE_UNUSED,
+ const cpp_string *str ATTRIBUTE_UNUSED)
{
#ifdef ASM_OUTPUT_IDENT
if (! flag_no_ident)
{
/* Convert escapes in the string. */
- tree value = lex_string (str->text, str->len, 0);
- ASM_OUTPUT_IDENT (asm_out_file, TREE_STRING_POINTER (value));
+ cpp_string cstr = { 0, 0 };
+ if (cpp_interpret_string (pfile, str, 1, &cstr, false))
+ {
+ ASM_OUTPUT_IDENT (asm_out_file, (const char *) cstr.text);
+ free ((void *)cstr.text);
+ }
}
#endif
}
@@ -242,35 +191,33 @@ cb_ident (pfile, line, str)
/* Called at the start of every non-empty line. TOKEN is the first
lexed token on the line. Used for diagnostic line numbers. */
static void
-cb_line_change (pfile, token, parsing_args)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
- const cpp_token *token;
- int parsing_args;
+cb_line_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const cpp_token *token,
+ int parsing_args)
{
if (token->type == CPP_EOF || parsing_args)
return;
- src_lineno = SOURCE_LINE (map, token->line);
+ input_line = SOURCE_LINE (map, token->line);
}
-static void
-cb_file_change (pfile, new_map)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
- const struct line_map *new_map;
+void
+fe_file_change (const struct line_map *new_map)
{
- unsigned int to_line = SOURCE_LINE (new_map, new_map->to_line);
+ if (new_map == NULL)
+ {
+ map = NULL;
+ return;
+ }
if (new_map->reason == LC_ENTER)
{
/* Don't stack the main buffer on the input stack;
we already did in compile_file. */
- if (map == NULL)
- main_input_filename = new_map->to_file;
- else
+ if (map != NULL)
{
int included_at = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
- lineno = included_at;
+ input_line = included_at;
push_srcloc (new_map->to_file, 1);
(*debug_hooks->start_source_file) (included_at, new_map->to_file);
#ifndef NO_IMPLICIT_EXTERN_C
@@ -295,14 +242,14 @@ cb_file_change (pfile, new_map)
}
#endif
pop_srcloc ();
-
- (*debug_hooks->end_source_file) (to_line);
+
+ (*debug_hooks->end_source_file) (new_map->to_line);
}
update_header_times (new_map->to_file);
in_system_header = new_map->sysp != 0;
input_filename = new_map->to_file;
- lineno = to_line;
+ input_line = new_map->to_line;
map = new_map;
/* Hook for C++. */
@@ -310,9 +257,7 @@ cb_file_change (pfile, new_map)
}
static void
-cb_def_pragma (pfile, line)
- cpp_reader *pfile;
- unsigned int line;
+cb_def_pragma (cpp_reader *pfile, unsigned int line)
{
/* Issue a warning message if we have been asked to do so. Ignore
unknown pragmas in system headers unless an explicit
@@ -332,17 +277,14 @@ cb_def_pragma (pfile, line)
name = cpp_token_as_text (pfile, s);
}
- lineno = SOURCE_LINE (map, line);
+ input_line = SOURCE_LINE (map, line);
warning ("ignoring #pragma %s %s", space, name);
}
}
/* #define callback for DWARF and DWARF2 debug info. */
static void
-cb_define (pfile, line, node)
- cpp_reader *pfile;
- unsigned int line;
- cpp_hashnode *node;
+cb_define (cpp_reader *pfile, unsigned int line, cpp_hashnode *node)
{
(*debug_hooks->define) (SOURCE_LINE (map, line),
(const char *) cpp_macro_definition (pfile, node));
@@ -350,353 +292,39 @@ cb_define (pfile, line, node)
/* #undef callback for DWARF and DWARF2 debug info. */
static void
-cb_undef (pfile, line, node)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
- unsigned int line;
- cpp_hashnode *node;
+cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, unsigned int line,
+ cpp_hashnode *node)
{
(*debug_hooks->undef) (SOURCE_LINE (map, line),
(const char *) NODE_NAME (node));
}
-
-#if 0 /* not yet */
-/* Returns nonzero if C is a universal-character-name. Give an error if it
- is not one which may appear in an identifier, as per [extendid].
-
- Note that extended character support in identifiers has not yet been
- implemented. It is my personal opinion that this is not a desirable
- feature. Portable code cannot count on support for more than the basic
- identifier character set. */
-
-static inline int
-is_extended_char (c)
- int c;
-{
-#ifdef TARGET_EBCDIC
- return 0;
-#else
- /* ASCII. */
- if (c < 0x7f)
- return 0;
-
- /* None of the valid chars are outside the Basic Multilingual Plane (the
- low 16 bits). */
- if (c > 0xffff)
- {
- error ("universal-character-name '\\U%08x' not valid in identifier", c);
- return 1;
- }
-
- /* Latin */
- if ((c >= 0x00c0 && c <= 0x00d6)
- || (c >= 0x00d8 && c <= 0x00f6)
- || (c >= 0x00f8 && c <= 0x01f5)
- || (c >= 0x01fa && c <= 0x0217)
- || (c >= 0x0250 && c <= 0x02a8)
- || (c >= 0x1e00 && c <= 0x1e9a)
- || (c >= 0x1ea0 && c <= 0x1ef9))
- return 1;
-
- /* Greek */
- if ((c == 0x0384)
- || (c >= 0x0388 && c <= 0x038a)
- || (c == 0x038c)
- || (c >= 0x038e && c <= 0x03a1)
- || (c >= 0x03a3 && c <= 0x03ce)
- || (c >= 0x03d0 && c <= 0x03d6)
- || (c == 0x03da)
- || (c == 0x03dc)
- || (c == 0x03de)
- || (c == 0x03e0)
- || (c >= 0x03e2 && c <= 0x03f3)
- || (c >= 0x1f00 && c <= 0x1f15)
- || (c >= 0x1f18 && c <= 0x1f1d)
- || (c >= 0x1f20 && c <= 0x1f45)
- || (c >= 0x1f48 && c <= 0x1f4d)
- || (c >= 0x1f50 && c <= 0x1f57)
- || (c == 0x1f59)
- || (c == 0x1f5b)
- || (c == 0x1f5d)
- || (c >= 0x1f5f && c <= 0x1f7d)
- || (c >= 0x1f80 && c <= 0x1fb4)
- || (c >= 0x1fb6 && c <= 0x1fbc)
- || (c >= 0x1fc2 && c <= 0x1fc4)
- || (c >= 0x1fc6 && c <= 0x1fcc)
- || (c >= 0x1fd0 && c <= 0x1fd3)
- || (c >= 0x1fd6 && c <= 0x1fdb)
- || (c >= 0x1fe0 && c <= 0x1fec)
- || (c >= 0x1ff2 && c <= 0x1ff4)
- || (c >= 0x1ff6 && c <= 0x1ffc))
- return 1;
-
- /* Cyrillic */
- if ((c >= 0x0401 && c <= 0x040d)
- || (c >= 0x040f && c <= 0x044f)
- || (c >= 0x0451 && c <= 0x045c)
- || (c >= 0x045e && c <= 0x0481)
- || (c >= 0x0490 && c <= 0x04c4)
- || (c >= 0x04c7 && c <= 0x04c8)
- || (c >= 0x04cb && c <= 0x04cc)
- || (c >= 0x04d0 && c <= 0x04eb)
- || (c >= 0x04ee && c <= 0x04f5)
- || (c >= 0x04f8 && c <= 0x04f9))
- return 1;
-
- /* Armenian */
- if ((c >= 0x0531 && c <= 0x0556)
- || (c >= 0x0561 && c <= 0x0587))
- return 1;
-
- /* Hebrew */
- if ((c >= 0x05d0 && c <= 0x05ea)
- || (c >= 0x05f0 && c <= 0x05f4))
- return 1;
-
- /* Arabic */
- if ((c >= 0x0621 && c <= 0x063a)
- || (c >= 0x0640 && c <= 0x0652)
- || (c >= 0x0670 && c <= 0x06b7)
- || (c >= 0x06ba && c <= 0x06be)
- || (c >= 0x06c0 && c <= 0x06ce)
- || (c >= 0x06e5 && c <= 0x06e7))
- return 1;
-
- /* Devanagari */
- if ((c >= 0x0905 && c <= 0x0939)
- || (c >= 0x0958 && c <= 0x0962))
- return 1;
-
- /* Bengali */
- if ((c >= 0x0985 && c <= 0x098c)
- || (c >= 0x098f && c <= 0x0990)
- || (c >= 0x0993 && c <= 0x09a8)
- || (c >= 0x09aa && c <= 0x09b0)
- || (c == 0x09b2)
- || (c >= 0x09b6 && c <= 0x09b9)
- || (c >= 0x09dc && c <= 0x09dd)
- || (c >= 0x09df && c <= 0x09e1)
- || (c >= 0x09f0 && c <= 0x09f1))
- return 1;
-
- /* Gurmukhi */
- if ((c >= 0x0a05 && c <= 0x0a0a)
- || (c >= 0x0a0f && c <= 0x0a10)
- || (c >= 0x0a13 && c <= 0x0a28)
- || (c >= 0x0a2a && c <= 0x0a30)
- || (c >= 0x0a32 && c <= 0x0a33)
- || (c >= 0x0a35 && c <= 0x0a36)
- || (c >= 0x0a38 && c <= 0x0a39)
- || (c >= 0x0a59 && c <= 0x0a5c)
- || (c == 0x0a5e))
- return 1;
-
- /* Gujarati */
- if ((c >= 0x0a85 && c <= 0x0a8b)
- || (c == 0x0a8d)
- || (c >= 0x0a8f && c <= 0x0a91)
- || (c >= 0x0a93 && c <= 0x0aa8)
- || (c >= 0x0aaa && c <= 0x0ab0)
- || (c >= 0x0ab2 && c <= 0x0ab3)
- || (c >= 0x0ab5 && c <= 0x0ab9)
- || (c == 0x0ae0))
- return 1;
-
- /* Oriya */
- if ((c >= 0x0b05 && c <= 0x0b0c)
- || (c >= 0x0b0f && c <= 0x0b10)
- || (c >= 0x0b13 && c <= 0x0b28)
- || (c >= 0x0b2a && c <= 0x0b30)
- || (c >= 0x0b32 && c <= 0x0b33)
- || (c >= 0x0b36 && c <= 0x0b39)
- || (c >= 0x0b5c && c <= 0x0b5d)
- || (c >= 0x0b5f && c <= 0x0b61))
- return 1;
-
- /* Tamil */
- if ((c >= 0x0b85 && c <= 0x0b8a)
- || (c >= 0x0b8e && c <= 0x0b90)
- || (c >= 0x0b92 && c <= 0x0b95)
- || (c >= 0x0b99 && c <= 0x0b9a)
- || (c == 0x0b9c)
- || (c >= 0x0b9e && c <= 0x0b9f)
- || (c >= 0x0ba3 && c <= 0x0ba4)
- || (c >= 0x0ba8 && c <= 0x0baa)
- || (c >= 0x0bae && c <= 0x0bb5)
- || (c >= 0x0bb7 && c <= 0x0bb9))
- return 1;
-
- /* Telugu */
- if ((c >= 0x0c05 && c <= 0x0c0c)
- || (c >= 0x0c0e && c <= 0x0c10)
- || (c >= 0x0c12 && c <= 0x0c28)
- || (c >= 0x0c2a && c <= 0x0c33)
- || (c >= 0x0c35 && c <= 0x0c39)
- || (c >= 0x0c60 && c <= 0x0c61))
- return 1;
-
- /* Kannada */
- if ((c >= 0x0c85 && c <= 0x0c8c)
- || (c >= 0x0c8e && c <= 0x0c90)
- || (c >= 0x0c92 && c <= 0x0ca8)
- || (c >= 0x0caa && c <= 0x0cb3)
- || (c >= 0x0cb5 && c <= 0x0cb9)
- || (c >= 0x0ce0 && c <= 0x0ce1))
- return 1;
-
- /* Malayalam */
- if ((c >= 0x0d05 && c <= 0x0d0c)
- || (c >= 0x0d0e && c <= 0x0d10)
- || (c >= 0x0d12 && c <= 0x0d28)
- || (c >= 0x0d2a && c <= 0x0d39)
- || (c >= 0x0d60 && c <= 0x0d61))
- return 1;
-
- /* Thai */
- if ((c >= 0x0e01 && c <= 0x0e30)
- || (c >= 0x0e32 && c <= 0x0e33)
- || (c >= 0x0e40 && c <= 0x0e46)
- || (c >= 0x0e4f && c <= 0x0e5b))
- return 1;
-
- /* Lao */
- if ((c >= 0x0e81 && c <= 0x0e82)
- || (c == 0x0e84)
- || (c == 0x0e87)
- || (c == 0x0e88)
- || (c == 0x0e8a)
- || (c == 0x0e0d)
- || (c >= 0x0e94 && c <= 0x0e97)
- || (c >= 0x0e99 && c <= 0x0e9f)
- || (c >= 0x0ea1 && c <= 0x0ea3)
- || (c == 0x0ea5)
- || (c == 0x0ea7)
- || (c == 0x0eaa)
- || (c == 0x0eab)
- || (c >= 0x0ead && c <= 0x0eb0)
- || (c == 0x0eb2)
- || (c == 0x0eb3)
- || (c == 0x0ebd)
- || (c >= 0x0ec0 && c <= 0x0ec4)
- || (c == 0x0ec6))
- return 1;
-
- /* Georgian */
- if ((c >= 0x10a0 && c <= 0x10c5)
- || (c >= 0x10d0 && c <= 0x10f6))
- return 1;
-
- /* Hiragana */
- if ((c >= 0x3041 && c <= 0x3094)
- || (c >= 0x309b && c <= 0x309e))
- return 1;
-
- /* Katakana */
- if ((c >= 0x30a1 && c <= 0x30fe))
- return 1;
-
- /* Bopmofo */
- if ((c >= 0x3105 && c <= 0x312c))
- return 1;
-
- /* Hangul */
- if ((c >= 0x1100 && c <= 0x1159)
- || (c >= 0x1161 && c <= 0x11a2)
- || (c >= 0x11a8 && c <= 0x11f9))
- return 1;
-
- /* CJK Unified Ideographs */
- if ((c >= 0xf900 && c <= 0xfa2d)
- || (c >= 0xfb1f && c <= 0xfb36)
- || (c >= 0xfb38 && c <= 0xfb3c)
- || (c == 0xfb3e)
- || (c >= 0xfb40 && c <= 0xfb41)
- || (c >= 0xfb42 && c <= 0xfb44)
- || (c >= 0xfb46 && c <= 0xfbb1)
- || (c >= 0xfbd3 && c <= 0xfd3f)
- || (c >= 0xfd50 && c <= 0xfd8f)
- || (c >= 0xfd92 && c <= 0xfdc7)
- || (c >= 0xfdf0 && c <= 0xfdfb)
- || (c >= 0xfe70 && c <= 0xfe72)
- || (c == 0xfe74)
- || (c >= 0xfe76 && c <= 0xfefc)
- || (c >= 0xff21 && c <= 0xff3a)
- || (c >= 0xff41 && c <= 0xff5a)
- || (c >= 0xff66 && c <= 0xffbe)
- || (c >= 0xffc2 && c <= 0xffc7)
- || (c >= 0xffca && c <= 0xffcf)
- || (c >= 0xffd2 && c <= 0xffd7)
- || (c >= 0xffda && c <= 0xffdc)
- || (c >= 0x4e00 && c <= 0x9fa5))
- return 1;
-
- error ("universal-character-name '\\u%04x' not valid in identifier", c);
- return 1;
-#endif
-}
-
-/* Add the UTF-8 representation of C to the token_buffer. */
-
-static void
-utf8_extend_token (c)
- int c;
-{
- int shift, mask;
-
- if (c <= 0x0000007f)
- {
- extend_token (c);
- return;
- }
- else if (c <= 0x000007ff)
- shift = 6, mask = 0xc0;
- else if (c <= 0x0000ffff)
- shift = 12, mask = 0xe0;
- else if (c <= 0x001fffff)
- shift = 18, mask = 0xf0;
- else if (c <= 0x03ffffff)
- shift = 24, mask = 0xf8;
- else
- shift = 30, mask = 0xfc;
-
- extend_token (mask | (c >> shift));
- do
- {
- shift -= 6;
- extend_token ((unsigned char) (0x80 | (c >> shift)));
- }
- while (shift);
-}
-#endif
-int
-c_lex (value)
- tree *value;
+static inline const cpp_token *
+get_nonpadding_token (void)
{
const cpp_token *tok;
-
- retry:
timevar_push (TV_CPP);
do
tok = cpp_get_token (parse_in);
while (tok->type == CPP_PADDING);
timevar_pop (TV_CPP);
- /* The C++ front end does horrible things with the current line
- number. To ensure an accurate line number, we must reset it
- every time we return a token. */
- lineno = src_lineno;
+ return tok;
+}
+
+int
+c_lex_with_flags (tree *value, unsigned char *cpp_flags)
+{
+ const cpp_token *tok;
+ location_t atloc;
+ static bool no_more_pch;
- *value = NULL_TREE;
+ retry:
+ tok = get_nonpadding_token ();
+
+ retry_after_at:
switch (tok->type)
{
- /* Issue this error here, where we can get at tok->val.c. */
- case CPP_OTHER:
- if (ISGRAPH (tok->val.c))
- error ("stray '%c' in program", tok->val.c);
- else
- error ("stray '\\%o' in program", tok->val.c);
- goto retry;
-
case CPP_NAME:
*value = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
break;
@@ -726,6 +354,50 @@ c_lex (value)
}
break;
+ case CPP_ATSIGN:
+ /* An @ may give the next token special significance in Objective-C. */
+ atloc = input_location;
+ tok = get_nonpadding_token ();
+ if (c_dialect_objc ())
+ {
+ tree val;
+ switch (tok->type)
+ {
+ case CPP_NAME:
+ val = HT_IDENT_TO_GCC_IDENT (HT_NODE (tok->val.node));
+ if (C_IS_RESERVED_WORD (val)
+ && OBJC_IS_AT_KEYWORD (C_RID_CODE (val)))
+ {
+ *value = val;
+ return CPP_AT_NAME;
+ }
+ break;
+
+ case CPP_STRING:
+ case CPP_WSTRING:
+ return lex_string (tok, value, true);
+
+ default: break;
+ }
+ }
+
+ /* ... or not. */
+ error ("%Hstray '@' in program", &atloc);
+ goto retry_after_at;
+
+ case CPP_OTHER:
+ {
+ cppchar_t c = tok->val.str.text[0];
+
+ if (c == '"' || c == '\'')
+ error ("missing terminating %c character", (int) c);
+ else if (ISGRAPH (c))
+ error ("stray '%c' in program", (int) c);
+ else
+ error ("stray '\\%o' in program", (int) c);
+ }
+ goto retry;
+
case CPP_CHAR:
case CPP_WCHAR:
*value = lex_charconst (tok);
@@ -733,8 +405,7 @@ c_lex (value)
case CPP_STRING:
case CPP_WSTRING:
- *value = lex_string (tok->val.str.text, tok->val.str.len,
- tok->type == CPP_WSTRING);
+ return lex_string (tok, value, false);
break;
/* These tokens should not be visible outside cpplib. */
@@ -743,19 +414,33 @@ c_lex (value)
case CPP_MACRO_ARG:
abort ();
- default: break;
+ default:
+ *value = NULL_TREE;
+ break;
}
+ if (! no_more_pch)
+ {
+ no_more_pch = true;
+ c_common_no_more_pch ();
+ }
+
+ if (cpp_flags)
+ *cpp_flags = tok->flags;
return tok->type;
}
+int
+c_lex (tree *value)
+{
+ return c_lex_with_flags (value, NULL);
+}
+
/* Returns the narrowest C-visible unsigned type, starting with the
minimum specified by FLAGS, that can fit VALUE, or itk_none if
there isn't one. */
static enum integer_type_kind
-narrowest_unsigned_type (value, flags)
- tree value;
- unsigned int flags;
+narrowest_unsigned_type (tree value, unsigned int flags)
{
enum integer_type_kind itk;
@@ -779,9 +464,7 @@ narrowest_unsigned_type (value, flags)
/* Ditto, but narrowest signed type. */
static enum integer_type_kind
-narrowest_signed_type (value, flags)
- tree value;
- unsigned int flags;
+narrowest_signed_type (tree value, unsigned int flags)
{
enum integer_type_kind itk;
@@ -805,9 +488,7 @@ narrowest_signed_type (value, flags)
/* Interpret TOKEN, an integer with FLAGS as classified by cpplib. */
static tree
-interpret_integer (token, flags)
- const cpp_token *token;
- unsigned int flags;
+interpret_integer (const cpp_token *token, unsigned int flags)
{
tree value, type;
enum integer_type_kind itk;
@@ -885,9 +566,7 @@ interpret_integer (token, flags)
/* Interpret TOKEN, a floating point number with FLAGS as classified
by cpplib. */
static tree
-interpret_float (token, flags)
- const cpp_token *token;
- unsigned int flags;
+interpret_float (const cpp_token *token, unsigned int flags)
{
tree type;
tree value;
@@ -948,112 +627,105 @@ interpret_float (token, flags)
return value;
}
-static tree
-lex_string (str, len, wide)
- const unsigned char *str;
- unsigned int len;
- int wide;
+/* Convert a series of STRING and/or WSTRING tokens into a tree,
+ performing string constant concatenation. TOK is the first of
+ these. VALP is the location to write the string into. OBJC_STRING
+ indicates whether an '@' token preceded the incoming token.
+ Returns the CPP token type of the result (CPP_STRING, CPP_WSTRING,
+ or CPP_OBJC_STRING).
+
+ This is unfortunately more work than it should be. If any of the
+ strings in the series has an L prefix, the result is a wide string
+ (6.4.5p4). Whether or not the result is a wide string affects the
+ meaning of octal and hexadecimal escapes (6.4.4.4p6,9). But escape
+ sequences do not continue across the boundary between two strings in
+ a series (6.4.5p7), so we must not lose the boundaries. Therefore
+ cpp_interpret_string takes a vector of cpp_string structures, which
+ we must arrange to provide. */
+
+static enum cpp_ttype
+lex_string (const cpp_token *tok, tree *valp, bool objc_string)
{
tree value;
- char *buf = alloca ((len + 1) * (wide ? WCHAR_BYTES : 1));
- char *q = buf;
- const unsigned char *p = str, *limit = str + len;
- cppchar_t c;
-
-#ifdef MULTIBYTE_CHARS
- /* Reset multibyte conversion state. */
- (void) local_mbtowc (NULL, NULL, 0);
-#endif
+ bool wide = false;
+ size_t count = 1;
+ struct obstack str_ob;
+ cpp_string istr;
- while (p < limit)
- {
-#ifdef MULTIBYTE_CHARS
- wchar_t wc;
- int char_len;
+ /* Try to avoid the overhead of creating and destroying an obstack
+ for the common case of just one string. */
+ cpp_string str = tok->val.str;
+ cpp_string *strs = &str;
- char_len = local_mbtowc (&wc, (const char *) p, limit - p);
- if (char_len == -1)
- {
- warning ("ignoring invalid multibyte character");
- char_len = 1;
- c = *p++;
- }
- else
- {
- p += char_len;
- c = wc;
- }
-#else
- c = *p++;
-#endif
+ if (tok->type == CPP_WSTRING)
+ wide = true;
- if (c == '\\' && !ignore_escape_flag)
- c = cpp_parse_escape (parse_in, &p, limit, wide);
-
- /* Add this single character into the buffer either as a wchar_t,
- a multibyte sequence, or as a single byte. */
- if (wide)
- {
- unsigned charwidth = TYPE_PRECISION (char_type_node);
- unsigned bytemask = (1 << charwidth) - 1;
- int byte;
+ tok = get_nonpadding_token ();
+ if (c_dialect_objc () && tok->type == CPP_ATSIGN)
+ {
+ objc_string = true;
+ tok = get_nonpadding_token ();
+ }
+ if (tok->type == CPP_STRING || tok->type == CPP_WSTRING)
+ {
+ gcc_obstack_init (&str_ob);
+ obstack_grow (&str_ob, &str, sizeof (cpp_string));
- for (byte = 0; byte < WCHAR_BYTES; ++byte)
- {
- int n;
- if (byte >= (int) sizeof (c))
- n = 0;
- else
- n = (c >> (byte * charwidth)) & bytemask;
- if (BYTES_BIG_ENDIAN)
- q[WCHAR_BYTES - byte - 1] = n;
- else
- q[byte] = n;
- }
- q += WCHAR_BYTES;
- }
-#ifdef MULTIBYTE_CHARS
- else if (char_len > 1)
+ do
{
- /* We're dealing with a multibyte character. */
- for ( ; char_len >0; --char_len)
+ count++;
+ if (tok->type == CPP_WSTRING)
+ wide = true;
+ obstack_grow (&str_ob, &tok->val.str, sizeof (cpp_string));
+
+ tok = get_nonpadding_token ();
+ if (c_dialect_objc () && tok->type == CPP_ATSIGN)
{
- *q++ = *(p - char_len);
+ objc_string = true;
+ tok = get_nonpadding_token ();
}
}
-#endif
- else
- {
- *q++ = c;
- }
+ while (tok->type == CPP_STRING || tok->type == CPP_WSTRING);
+ strs = obstack_finish (&str_ob);
}
- /* Terminate the string value, either with a single byte zero
- or with a wide zero. */
+ /* We have read one more token than we want. */
+ _cpp_backup_tokens (parse_in, 1);
- if (wide)
+ if (count > 1 && !objc_string && warn_traditional && !in_system_header)
+ warning ("traditional C rejects string constant concatenation");
+
+ if (cpp_interpret_string (parse_in, strs, count, &istr, wide))
{
- memset (q, 0, WCHAR_BYTES);
- q += WCHAR_BYTES;
+ value = build_string (istr.len, (char *)istr.text);
+ free ((void *)istr.text);
}
else
{
- *q++ = '\0';
+ /* Callers cannot generally handle error_mark_node in this context,
+ so return the empty string instead. cpp_interpret_string has
+ issued an error. */
+ if (wide)
+ value = build_string (TYPE_PRECISION (wchar_type_node)
+ / TYPE_PRECISION (char_type_node),
+ "\0\0\0"); /* widest supported wchar_t
+ is 32 bits */
+ else
+ value = build_string (1, "");
}
- value = build_string (q - buf, buf);
+ TREE_TYPE (value) = wide ? wchar_array_type_node : char_array_type_node;
+ *valp = fix_string_type (value);
- if (wide)
- TREE_TYPE (value) = wchar_array_type_node;
- else
- TREE_TYPE (value) = char_array_type_node;
- return value;
+ if (strs != &str)
+ obstack_free (&str_ob, 0);
+
+ return objc_string ? CPP_OBJC_STRING : wide ? CPP_WSTRING : CPP_STRING;
}
/* Converts a (possibly wide) character constant token into a tree. */
static tree
-lex_charconst (token)
- const cpp_token *token;
+lex_charconst (const cpp_token *token)
{
cppchar_t result;
tree type, value;
@@ -1061,7 +733,7 @@ lex_charconst (token)
int unsignedp;
result = cpp_interpret_charconst (parse_in, token,
- &chars_seen, &unsignedp);
+ &chars_seen, &unsignedp);
/* Cast to cppchar_signed_t to get correct sign-extension of RESULT
before possibly widening to HOST_WIDE_INT for build_int_2. */
@@ -1074,7 +746,7 @@ lex_charconst (token)
type = wchar_type_node;
/* In C, a character constant has type 'int'.
In C++ 'char', but multi-char charconsts have type 'int'. */
- else if ((c_language == clk_c) || chars_seen > 1)
+ else if (!c_dialect_cxx () || chars_seen > 1)
type = integer_type_node;
else
type = char_type_node;
diff --git a/contrib/gcc/c-objc-common.c b/contrib/gcc/c-objc-common.c
index db3e7584a5fa..fe0c0d5b9337 100644
--- a/contrib/gcc/c-objc-common.c
+++ b/contrib/gcc/c-objc-common.c
@@ -1,5 +1,5 @@
/* Some code common to C and ObjC front ends.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,6 +20,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "insn-config.h"
@@ -35,18 +37,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "langhooks.h"
#include "target.h"
+#include "cgraph.h"
-static bool c_tree_printer PARAMS ((output_buffer *, text_info *));
-static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
-static void expand_deferred_fns PARAMS ((void));
-static tree start_cdtor PARAMS ((int));
-static void finish_cdtor PARAMS ((tree));
-
-static GTY(()) varray_type deferred_fns;
+static bool c_tree_printer (pretty_printer *, text_info *);
+static tree start_cdtor (int);
+static void finish_cdtor (tree);
int
-c_missing_noreturn_ok_p (decl)
- tree decl;
+c_missing_noreturn_ok_p (tree decl)
{
/* A missing noreturn is not ok for freestanding implementations and
ok for the `main' function in hosted implementations. */
@@ -58,124 +56,51 @@ c_missing_noreturn_ok_p (decl)
such functions always being inlined when optimizing. */
int
-c_disregard_inline_limits (fn)
- tree fn;
+c_disregard_inline_limits (tree fn)
{
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
return 1;
- return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
-}
-
-static tree
-inline_forbidden_p (nodep, walk_subtrees, fn)
- tree *nodep;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *fn;
-{
- tree node = *nodep;
- tree t;
-
- switch (TREE_CODE (node))
- {
- case CALL_EXPR:
- t = get_callee_fndecl (node);
-
- if (! t)
- break;
-
- /* We cannot inline functions that call setjmp. */
- if (setjmp_call_p (t))
- return node;
-
- switch (DECL_FUNCTION_CODE (t))
- {
- /* We cannot inline functions that take a variable number of
- arguments. */
- case BUILT_IN_VA_START:
- case BUILT_IN_STDARG_START:
- case BUILT_IN_NEXT_ARG:
- case BUILT_IN_VA_END:
-#if 0
- /* Functions that need information about the address of the
- caller can't (shouldn't?) be inlined. */
- case BUILT_IN_RETURN_ADDRESS:
-#endif
- return node;
-
- default:
- break;
- }
-
- break;
-
- case DECL_STMT:
- /* We cannot inline functions that contain other functions. */
- if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
- && DECL_INITIAL (TREE_OPERAND (node, 0)))
- return node;
- break;
-
- case GOTO_STMT:
- case GOTO_EXPR:
- t = TREE_OPERAND (node, 0);
-
- /* We will not inline a function which uses computed goto. The
- addresses of its local labels, which may be tucked into
- global storage, are of course not constant across
- instantiations, which causes unexpected behavior. */
- if (TREE_CODE (t) != LABEL_DECL)
- return node;
-
- /* We cannot inline a nested function that jumps to a nonlocal
- label. */
- if (TREE_CODE (t) == LABEL_DECL
- && DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn)
- return node;
-
- break;
-
- case RECORD_TYPE:
- case UNION_TYPE:
- /* We cannot inline a function of the form
-
- void F (int i) { struct S { int ar[i]; } s; }
-
- Attempting to do so produces a catch-22 in tree-inline.c.
- If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
- UNION_TYPE nodes, then it goes into infinite recursion on a
- structure containing a pointer to its own type. If it doesn't,
- then the type node for S doesn't get adjusted properly when
- F is inlined, and we abort in find_function_data. */
- for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
- if (variably_modified_type_p (TREE_TYPE (t)))
- return node;
-
- default:
- break;
- }
-
- return NULL_TREE;
+ return (!flag_really_no_inline && DECL_DECLARED_INLINE_P (fn)
+ && DECL_EXTERNAL (fn));
}
int
-c_cannot_inline_tree_fn (fnp)
- tree *fnp;
+c_cannot_inline_tree_fn (tree *fnp)
{
tree fn = *fnp;
tree t;
+ bool do_warning = (warn_inline
+ && DECL_INLINE (fn)
+ && DECL_DECLARED_INLINE_P (fn)
+ && !DECL_IN_SYSTEM_HEADER (fn));
if (flag_really_no_inline
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
- return 1;
+ {
+ if (do_warning)
+ warning ("%Jfunction '%F' can never be inlined because it "
+ "is suppressed using -fno-inline", fn, fn);
+ goto cannot_inline;
+ }
- /* Don't auto-inline anything that might not be bound within
+ /* Don't auto-inline anything that might not be bound within
this unit of translation. */
if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
- goto cannot_inline;
+ {
+ if (do_warning)
+ warning ("%Jfunction '%F' can never be inlined because it might not "
+ "be bound within this unit of translation", fn, fn);
+ goto cannot_inline;
+ }
if (! function_attribute_inlinable_p (fn))
- goto cannot_inline;
+ {
+ if (do_warning)
+ warning ("%Jfunction '%F' can never be inlined because it uses "
+ "attributes conflicting with inlining", fn, fn);
+ goto cannot_inline;
+ }
/* If a function has pending sizes, we must not defer its
compilation, and we can't inline it as a tree. */
@@ -185,39 +110,26 @@ c_cannot_inline_tree_fn (fnp)
put_pending_sizes (t);
if (t)
- goto cannot_inline;
+ {
+ if (do_warning)
+ warning ("%Jfunction '%F' can never be inlined because it has "
+ "pending sizes", fn, fn);
+ goto cannot_inline;
+ }
}
- if (DECL_CONTEXT (fn))
+ if (! DECL_FILE_SCOPE_P (fn))
{
/* If a nested function has pending sizes, we may have already
saved them. */
if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
- goto cannot_inline;
- }
- else
- {
- /* We rely on the fact that this function is called upfront,
- just before we start expanding a function. If FN is active
- (i.e., it's the current_function_decl or a parent thereof),
- we have to walk FN's saved tree. Otherwise, we can safely
- assume we have done it before and, if we didn't mark it as
- uninlinable (in which case we wouldn't have been called), it
- is inlinable. Unfortunately, this strategy doesn't work for
- nested functions, because they're only expanded as part of
- their enclosing functions, so the inlinability test comes in
- late. */
- t = current_function_decl;
-
- while (t && t != fn)
- t = DECL_CONTEXT (t);
- if (! t)
- return 0;
+ {
+ if (do_warning)
+ warning ("%Jnested function '%F' can never be inlined because it "
+ "has possibly saved pending sizes", fn, fn);
+ goto cannot_inline;
+ }
}
-
- if (walk_tree_without_duplicates
- (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn))
- goto cannot_inline;
return 0;
@@ -229,8 +141,7 @@ c_cannot_inline_tree_fn (fnp)
/* Called from check_global_declarations. */
bool
-c_warn_unused_global_decl (decl)
- tree decl;
+c_warn_unused_global_decl (tree decl)
{
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
return false;
@@ -241,15 +152,19 @@ c_warn_unused_global_decl (decl)
}
/* Initialization common to C and Objective-C front ends. */
-const char *
-c_objc_common_init (filename)
- const char *filename;
+bool
+c_objc_common_init (void)
{
+ static const enum tree_code stmt_codes[] = {
+ c_common_stmt_codes
+ };
+
+ INIT_STATEMENT_CODES (stmt_codes);
+
c_init_decl_processing ();
- filename = c_common_init (filename);
- if (filename == NULL)
- return NULL;
+ if (c_common_init () == false)
+ return false;
lang_expand_decl_stmt = c_expand_decl_stmt;
@@ -269,50 +184,11 @@ c_objc_common_init (filename)
mesg_implicit_function_declaration = 0;
}
- VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
-
- return filename;
-}
-
-/* Register a function tree, so that its optimization and conversion
- to RTL is only done at the end of the compilation. */
-
-int
-defer_fn (fn)
- tree fn;
-{
- VARRAY_PUSH_TREE (deferred_fns, fn);
-
- return 1;
-}
-
-/* Expand deferred functions for C and ObjC. */
-
-static void
-expand_deferred_fns ()
-{
- unsigned int i;
-
- for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
- {
- tree decl = VARRAY_TREE (deferred_fns, i);
-
- if (! TREE_ASM_WRITTEN (decl))
- {
- /* For static inline functions, delay the decision whether to
- emit them or not until wrapup_global_declarations. */
- if (! TREE_PUBLIC (decl))
- DECL_DEFER_OUTPUT (decl) = 1;
- c_expand_deferred_function (decl);
- }
- }
-
- deferred_fns = 0;
+ return true;
}
static tree
-start_cdtor (method_type)
- int method_type;
+start_cdtor (int method_type)
{
tree fnname = get_file_function_name (method_type);
tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
@@ -338,8 +214,7 @@ start_cdtor (method_type)
}
static void
-finish_cdtor (body)
- tree body;
+finish_cdtor (tree body)
{
tree scope;
tree block;
@@ -351,15 +226,23 @@ finish_cdtor (body)
RECHAIN_STMTS (body, COMPOUND_BODY (body));
- finish_function (0, 0);
+ finish_function ();
}
/* Called at end of parsing, but before end-of-file processing. */
void
-c_objc_common_finish_file ()
+c_objc_common_finish_file (void)
{
- expand_deferred_fns ();
+ if (pch_file)
+ c_common_write_pch ();
+
+ /* If multiple translation units were built, copy information between
+ them based on linkage rules. */
+ merge_translation_unit_decls ();
+
+ cgraph_finalize_compilation_unit ();
+ cgraph_optimize ();
if (static_ctors)
{
@@ -399,6 +282,7 @@ c_objc_common_finish_file ()
source-level entity onto BUFFER. The meaning of the format specifiers
is as follows:
%D: a general decl,
+ %E: An expression,
%F: a function declaration,
%T: a type.
@@ -407,28 +291,44 @@ c_objc_common_finish_file ()
Please notice when called, the `%' part was already skipped by the
diagnostic machinery. */
static bool
-c_tree_printer (buffer, text)
- output_buffer *buffer;
- text_info *text;
+c_tree_printer (pretty_printer *pp, text_info *text)
{
tree t = va_arg (*text->args_ptr, tree);
+ const char *n = "({anonymous})";
switch (*text->format_spec)
{
case 'D':
case 'F':
+ if (DECL_NAME (t))
+ n = (*lang_hooks.decl_printable_name) (t, 2);
+ break;
+
case 'T':
- {
- const char *n = DECL_NAME (t)
- ? (*lang_hooks.decl_printable_name) (t, 2)
- : "({anonymous})";
- output_add_string (buffer, n);
- }
- return true;
+ if (TREE_CODE (t) == TYPE_DECL)
+ {
+ if (DECL_NAME (t))
+ n = (*lang_hooks.decl_printable_name) (t, 2);
+ }
+ else
+ {
+ t = TYPE_NAME (t);
+ if (t)
+ n = IDENTIFIER_POINTER (t);
+ }
+ break;
+
+ case 'E':
+ if (TREE_CODE (t) == IDENTIFIER_NODE)
+ n = IDENTIFIER_POINTER (t);
+ else
+ return false;
+ break;
default:
return false;
}
-}
-#include "gt-c-objc-common.h"
+ pp_string (pp, n);
+ return true;
+}
diff --git a/contrib/gcc/c-opts.c b/contrib/gcc/c-opts.c
index 77a468ab1847..93637a2f2a84 100644
--- a/contrib/gcc/c-opts.c
+++ b/contrib/gcc/c-opts.c
@@ -1,5 +1,5 @@
/* C/ObjC/C++ command line option handling.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Neil Booth.
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "c-common.h"
#include "c-pragma.h"
@@ -30,12 +32,27 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tree-inline.h"
#include "diagnostic.h"
#include "intl.h"
+#include "cppdefault.h"
+#include "c-incpath.h"
+#include "debug.h" /* For debug_hooks. */
+#include "opts.h"
+#include "options.h"
+
+#ifndef DOLLARS_IN_IDENTIFIERS
+# define DOLLARS_IN_IDENTIFIERS true
+#endif
+
+#ifndef TARGET_SYSTEM_ROOT
+# define TARGET_SYSTEM_ROOT NULL
+#endif
+
+static int saved_lineno;
/* CPP's options. */
static cpp_options *cpp_opts;
/* Input filename. */
-static const char *in_fname;
+static const char *this_input_filename;
/* Filename and stream for preprocessed output. */
static const char *out_fname;
@@ -47,584 +64,201 @@ static bool deps_append;
/* If dependency switches (-MF etc.) have been given. */
static bool deps_seen;
+/* If -v seen. */
+static bool verbose;
+
/* Dependency output file. */
static const char *deps_file;
-/* Number of deferred options, deferred options array size. */
-static size_t deferred_count, deferred_size;
-
-static void missing_arg PARAMS ((size_t));
-static size_t find_opt PARAMS ((const char *, int));
-static void set_Wimplicit PARAMS ((int));
-static void complain_wrong_lang PARAMS ((size_t, int));
-static void write_langs PARAMS ((char *, int));
-static void print_help PARAMS ((void));
-static void handle_OPT_d PARAMS ((const char *));
-static void set_std_cxx98 PARAMS ((int));
-static void set_std_c89 PARAMS ((int, int));
-static void set_std_c99 PARAMS ((int));
-static void check_deps_environment_vars PARAMS ((void));
-static void preprocess_file PARAMS ((void));
-static void handle_deferred_opts PARAMS ((void));
-static void sanitize_cpp_opts PARAMS ((void));
+/* The prefix given by -iprefix, if any. */
+static const char *iprefix;
+
+/* The system root, if any. Overridden by -isysroot. */
+static const char *sysroot = TARGET_SYSTEM_ROOT;
+
+/* Zero disables all standard directories for headers. */
+static bool std_inc = true;
+
+/* Zero disables the C++-specific standard directories for headers. */
+static bool std_cxx_inc = true;
+
+/* If the quote chain has been split by -I-. */
+static bool quote_chain_split;
+
+/* If -Wunused-macros. */
+static bool warn_unused_macros;
+
+/* Number of deferred options. */
+static size_t deferred_count;
+
+/* Number of deferred options scanned for -include. */
+static size_t include_cursor;
+
+/* Permit Fotran front-end options. */
+static bool permit_fortran_options;
+
+static void set_Wimplicit (int);
+static void handle_OPT_d (const char *);
+static void set_std_cxx98 (int);
+static void set_std_c89 (int, int);
+static void set_std_c99 (int);
+static void check_deps_environment_vars (void);
+static void handle_deferred_opts (void);
+static void sanitize_cpp_opts (void);
+static void add_prefixed_path (const char *, size_t);
+static void push_command_line_include (void);
+static void cb_file_change (cpp_reader *, const struct line_map *);
+static void cb_dir_change (cpp_reader *, const char *);
+static void finish_options (void);
#ifndef STDC_0_IN_SYSTEM_HEADERS
#define STDC_0_IN_SYSTEM_HEADERS 0
#endif
-#define CL_C_ONLY (1 << 0) /* Only C. */
-#define CL_OBJC_ONLY (1 << 1) /* Only ObjC. */
-#define CL_CXX_ONLY (1 << 2) /* Only C++. */
-#define CL_OBJCXX_ONLY (1 << 3) /* Only ObjC++. */
-#define CL_JOINED (1 << 4) /* If takes joined argument. */
-#define CL_SEPARATE (1 << 5) /* If takes a separate argument. */
-
-#define CL_ARG (CL_JOINED | CL_SEPARATE)
-#define CL_C (CL_C_ONLY | CL_OBJC_ONLY)
-#define CL_OBJC (CL_OBJC_ONLY | CL_OBJCXX_ONLY)
-#define CL_CXX (CL_CXX_ONLY | CL_OBJCXX_ONLY)
-#define CL_ALL (CL_C | CL_CXX)
-
-/* This is the list of all command line options, with the leading "-"
- removed. It must be sorted in ASCII collating order. All options
- beginning with "f" or "W" are implicitly assumed to take a "no-"
- form; this form should not be listed. The variable "on" is true if
- the positive form is given, otherwise it is false. If you don't
- want to allow a "no-" form, your handler should reject "on" being
- false by returning zero. See, for example, the handling of
- -ftabstop=.
-
- If the user gives an option to a front end that doesn't support it,
- an error is output, mentioning which front ends the option is valid
- for. If you don't want this, you must accept it for all front
- ends, and test for the front end in the option handler. See, for
- example, the handling of -Wno-strict-prototypes for C++.
-
- If you request an argument with CL_JOINED, CL_SEPARATE or their
- combination CL_ARG, it is stored in the variable "arg", which is
- guaranteed to be non-NULL and to not be an empty string. It points
- to the argument either within the argv[] vector or within one of
- that vector's strings, and so the text is permanent and copies need
- not be made. Be sure to add an error message in missing_arg() if
- the default is not appropriate. */
-
-#define COMMAND_LINE_OPTIONS \
- OPT("-help", CL_ALL, OPT__help) \
- OPT("C", CL_ALL, OPT_C) \
- OPT("CC", CL_ALL, OPT_CC) \
- OPT("E", CL_ALL, OPT_E) \
- OPT("H", CL_ALL, OPT_H) \
- OPT("M", CL_ALL, OPT_M) \
- OPT("MD", CL_ALL | CL_SEPARATE, OPT_MD) \
- OPT("MF", CL_ALL | CL_ARG, OPT_MF) \
- OPT("MG", CL_ALL, OPT_MG) \
- OPT("MM", CL_ALL, OPT_MM) \
- OPT("MMD", CL_ALL | CL_SEPARATE, OPT_MMD) \
- OPT("MP", CL_ALL, OPT_MP) \
- OPT("MQ", CL_ALL | CL_ARG, OPT_MQ) \
- OPT("MT", CL_ALL | CL_ARG, OPT_MT) \
- OPT("P", CL_ALL, OPT_P) \
- OPT("Wabi", CL_CXX, OPT_Wabi) \
- OPT("Wall", CL_ALL, OPT_Wall) \
- OPT("Wbad-function-cast", CL_C, OPT_Wbad_function_cast) \
- OPT("Wcast-qual", CL_ALL, OPT_Wcast_qual) \
- OPT("Wchar-subscripts", CL_ALL, OPT_Wchar_subscripts) \
- OPT("Wcomment", CL_ALL, OPT_Wcomment) \
- OPT("Wcomments", CL_ALL, OPT_Wcomments) \
- OPT("Wconversion", CL_ALL, OPT_Wconversion) \
- OPT("Wctor-dtor-privacy", CL_CXX, OPT_Wctor_dtor_privacy) \
- OPT("Wdeprecated", CL_CXX, OPT_Wdeprecated) \
- OPT("Wdiv-by-zero", CL_C, OPT_Wdiv_by_zero) \
- OPT("Weffc++", CL_CXX, OPT_Weffcxx) \
- OPT("Wendif-labels", CL_ALL, OPT_Wendif_labels) \
- OPT("Werror", CL_ALL, OPT_Werror) \
- OPT("Werror-implicit-function-declaration", \
- CL_C, OPT_Werror_implicit_function_decl) \
- OPT("Wfloat-equal", CL_ALL, OPT_Wfloat_equal) \
- OPT("Wformat", CL_ALL, OPT_Wformat) \
- OPT("Wformat-extra-args", CL_ALL, OPT_Wformat_extra_args) \
- OPT("Wformat-nonliteral", CL_ALL, OPT_Wformat_nonliteral) \
- OPT("Wformat-security", CL_ALL, OPT_Wformat_security) \
- OPT("Wformat-y2k", CL_ALL, OPT_Wformat_y2k) \
- OPT("Wformat-zero-length", CL_C, OPT_Wformat_zero_length) \
- OPT("Wformat=", CL_ALL | CL_JOINED, OPT_Wformat_eq) \
- OPT("Wimplicit", CL_ALL, OPT_Wimplicit) \
- OPT("Wimplicit-function-declaration", CL_C, OPT_Wimplicit_function_decl) \
- OPT("Wimplicit-int", CL_C, OPT_Wimplicit_int) \
- OPT("Wimport", CL_ALL, OPT_Wimport) \
- OPT("Wlong-long", CL_ALL, OPT_Wlong_long) \
- OPT("Wmain", CL_C, OPT_Wmain) \
- OPT("Wmissing-braces", CL_ALL, OPT_Wmissing_braces) \
- OPT("Wmissing-declarations", CL_C, OPT_Wmissing_declarations) \
- OPT("Wmissing-format-attribute",CL_ALL, OPT_Wmissing_format_attribute) \
- OPT("Wmissing-prototypes", CL_ALL, OPT_Wmissing_prototypes) \
- OPT("Wmultichar", CL_ALL, OPT_Wmultichar) \
- OPT("Wnested-externs", CL_C, OPT_Wnested_externs) \
- OPT("Wnon-template-friend", CL_CXX, OPT_Wnon_template_friend) \
- OPT("Wnon-virtual-dtor", CL_CXX, OPT_Wnon_virtual_dtor) \
- OPT("Wnonnull", CL_C, OPT_Wnonnull) \
- OPT("Wold-style-cast", CL_CXX, OPT_Wold_style_cast) \
- OPT("Woverloaded-virtual", CL_CXX, OPT_Woverloaded_virtual) \
- OPT("Wparentheses", CL_ALL, OPT_Wparentheses) \
- OPT("Wpmf-conversions", CL_CXX, OPT_Wpmf_conversions) \
- OPT("Wpointer-arith", CL_ALL, OPT_Wpointer_arith) \
- OPT("Wprotocol", CL_OBJC, OPT_Wprotocol) \
- OPT("Wredundant-decls", CL_ALL, OPT_Wredundant_decls) \
- OPT("Wreorder", CL_CXX, OPT_Wreorder) \
- OPT("Wreturn-type", CL_ALL, OPT_Wreturn_type) \
- OPT("Wselector", CL_OBJC, OPT_Wselector) \
- OPT("Wsequence-point", CL_C, OPT_Wsequence_point) \
- OPT("Wsign-compare", CL_ALL, OPT_Wsign_compare) \
- OPT("Wsign-promo", CL_CXX, OPT_Wsign_promo) \
- OPT("Wstrict-prototypes", CL_ALL, OPT_Wstrict_prototypes) \
- OPT("Wsynth", CL_CXX, OPT_Wsynth) \
- OPT("Wsystem-headers", CL_ALL, OPT_Wsystem_headers) \
- OPT("Wtraditional", CL_C, OPT_Wtraditional) \
- OPT("Wtrigraphs", CL_ALL, OPT_Wtrigraphs) \
- OPT("Wundeclared-selector", CL_OBJC, OPT_Wundeclared_selector) \
- OPT("Wundef", CL_ALL, OPT_Wundef) \
- OPT("Wunknown-pragmas", CL_ALL, OPT_Wunknown_pragmas) \
- OPT("Wunused-macros", CL_ALL, OPT_Wunused_macros) \
- OPT("Wwrite-strings", CL_ALL, OPT_Wwrite_strings) \
- OPT("ansi", CL_ALL, OPT_ansi) \
- OPT("d", CL_ALL | CL_JOINED, OPT_d) \
- OPT("fabi-version=", CL_CXX | CL_JOINED, OPT_fabi_version) \
- OPT("faccess-control", CL_CXX, OPT_faccess_control) \
- OPT("fall-virtual", CL_CXX, OPT_fall_virtual) \
- OPT("falt-external-templates",CL_CXX, OPT_falt_external_templates) \
- OPT("fasm", CL_ALL, OPT_fasm) \
- OPT("fbuiltin", CL_ALL, OPT_fbuiltin) \
- OPT("fbuiltin-", CL_ALL | CL_JOINED, OPT_fbuiltin_) \
- OPT("fcheck-new", CL_CXX, OPT_fcheck_new) \
- OPT("fcond-mismatch", CL_ALL, OPT_fcond_mismatch) \
- OPT("fconserve-space", CL_CXX, OPT_fconserve_space) \
- OPT("fconst-strings", CL_CXX, OPT_fconst_strings) \
- OPT("fconstant-string-class=", CL_OBJC | CL_JOINED, \
- OPT_fconstant_string_class) \
- OPT("fdefault-inline", CL_CXX, OPT_fdefault_inline) \
- OPT("fdollars-in-identifiers",CL_ALL, OPT_fdollars_in_identifiers) \
- OPT("fdump-", CL_ALL | CL_JOINED, OPT_fdump) \
- OPT("felide-constructors", CL_CXX, OPT_felide_constructors) \
- OPT("fenforce-eh-specs", CL_CXX, OPT_fenforce_eh_specs) \
- OPT("fenum-int-equiv", CL_CXX, OPT_fenum_int_equiv) \
- OPT("fexternal-templates", CL_CXX, OPT_fexternal_templates) \
- OPT("ffixed-form", CL_C, OPT_ffixed_form) \
- OPT("ffixed-line-length-", CL_C | CL_JOINED, OPT_ffixed_line_length) \
- OPT("ffor-scope", CL_CXX, OPT_ffor_scope) \
- OPT("ffreestanding", CL_C, OPT_ffreestanding) \
- OPT("fgnu-keywords", CL_CXX, OPT_fgnu_keywords) \
- OPT("fgnu-runtime", CL_OBJC, OPT_fgnu_runtime) \
- OPT("fguiding-decls", CL_CXX, OPT_fguiding_decls) \
- OPT("fhandle-exceptions", CL_CXX, OPT_fhandle_exceptions) \
- OPT("fhonor-std", CL_CXX, OPT_fhonor_std) \
- OPT("fhosted", CL_C, OPT_fhosted) \
- OPT("fhuge-objects", CL_CXX, OPT_fhuge_objects) \
- OPT("fimplement-inlines", CL_CXX, OPT_fimplement_inlines) \
- OPT("fimplicit-inline-templates", CL_CXX, OPT_fimplicit_inline_templates) \
- OPT("fimplicit-templates", CL_CXX, OPT_fimplicit_templates) \
- OPT("flabels-ok", CL_CXX, OPT_flabels_ok) \
- OPT("fms-extensions", CL_ALL, OPT_fms_extensions) \
- OPT("fname-mangling-version-",CL_CXX | CL_JOINED, OPT_fname_mangling) \
- OPT("fnew-abi", CL_CXX, OPT_fnew_abi) \
- OPT("fnext-runtime", CL_OBJC, OPT_fnext_runtime) \
- OPT("fnonansi-builtins", CL_CXX, OPT_fnonansi_builtins) \
- OPT("fnonnull-objects", CL_CXX, OPT_fnonnull_objects) \
- OPT("foperator-names", CL_CXX, OPT_foperator_names) \
- OPT("foptional-diags", CL_CXX, OPT_foptional_diags) \
- OPT("fpermissive", CL_CXX, OPT_fpermissive) \
- OPT("fpreprocessed", CL_ALL, OPT_fpreprocessed) \
- OPT("frepo", CL_CXX, OPT_frepo) \
- OPT("frtti", CL_CXX, OPT_frtti) \
- OPT("fshort-double", CL_ALL, OPT_fshort_double) \
- OPT("fshort-enums", CL_ALL, OPT_fshort_enums) \
- OPT("fshort-wchar", CL_ALL, OPT_fshort_wchar) \
- OPT("fshow-column", CL_ALL, OPT_fshow_column) \
- OPT("fsigned-bitfields", CL_ALL, OPT_fsigned_bitfields) \
- OPT("fsigned-char", CL_ALL, OPT_fsigned_char) \
- OPT("fsquangle", CL_CXX, OPT_fsquangle) \
- OPT("fstats", CL_CXX, OPT_fstats) \
- OPT("fstrict-prototype", CL_CXX, OPT_fstrict_prototype) \
- OPT("ftabstop=", CL_ALL | CL_JOINED, OPT_ftabstop) \
- OPT("ftemplate-depth-", CL_CXX | CL_JOINED, OPT_ftemplate_depth) \
- OPT("fthis-is-variable", CL_CXX, OPT_fthis_is_variable) \
- OPT("funsigned-bitfields", CL_ALL, OPT_funsigned_bitfields) \
- OPT("funsigned-char", CL_ALL, OPT_funsigned_char) \
- OPT("fuse-cxa-atexit", CL_CXX, OPT_fuse_cxa_atexit) \
- OPT("fvtable-gc", CL_CXX, OPT_fvtable_gc) \
- OPT("fvtable-thunks", CL_CXX, OPT_fvtable_thunks) \
- OPT("fweak", CL_CXX, OPT_fweak) \
- OPT("fxref", CL_CXX, OPT_fxref) \
- OPT("gen-decls", CL_OBJC, OPT_gen_decls) \
- OPT("lang-asm", CL_C_ONLY, OPT_lang_asm) \
- OPT("lang-objc", CL_ALL, OPT_lang_objc) \
- OPT("nostdinc", CL_ALL, OPT_nostdinc) \
- OPT("nostdinc++", CL_ALL, OPT_nostdincplusplus) \
- OPT("o", CL_ALL | CL_ARG, OPT_o) \
- OPT("pedantic", CL_ALL, OPT_pedantic) \
- OPT("pedantic-errors", CL_ALL, OPT_pedantic_errors) \
- OPT("print-objc-runtime-info", CL_OBJC, OPT_print_objc_runtime_info) \
- OPT("remap", CL_ALL, OPT_remap) \
- OPT("std=c++98", CL_CXX, OPT_std_cplusplus98) \
- OPT("std=c89", CL_C, OPT_std_c89) \
- OPT("std=c99", CL_C, OPT_std_c99) \
- OPT("std=c9x", CL_C, OPT_std_c9x) \
- OPT("std=gnu++98", CL_CXX, OPT_std_gnuplusplus98) \
- OPT("std=gnu89", CL_C, OPT_std_gnu89) \
- OPT("std=gnu99", CL_C, OPT_std_gnu99) \
- OPT("std=gnu9x", CL_C, OPT_std_gnu9x) \
- OPT("std=iso9899:1990", CL_C, OPT_std_iso9899_1990) \
- OPT("std=iso9899:199409", CL_C, OPT_std_iso9899_199409) \
- OPT("std=iso9899:1999", CL_C, OPT_std_iso9899_1999) \
- OPT("std=iso9899:199x", CL_C, OPT_std_iso9899_199x) \
- OPT("traditional-cpp", CL_ALL, OPT_traditional_cpp) \
- OPT("trigraphs", CL_ALL, OPT_trigraphs) \
- OPT("undef", CL_ALL, OPT_undef) \
- OPT("v", CL_ALL, OPT_v) \
- OPT("w", CL_ALL, OPT_w)
-
-#define OPT(text, flags, code) code,
-enum opt_code
-{
- COMMAND_LINE_OPTIONS
- N_OPTS
-};
-#undef OPT
-
-struct cl_option
-{
- const char *opt_text;
- unsigned char opt_len;
- unsigned char flags;
- ENUM_BITFIELD (opt_code) opt_code : 2 * CHAR_BIT;
-};
-
-#define OPT(text, flags, code) { text, sizeof(text) - 1, flags, code },
-#ifdef HOST_EBCDIC
-static struct cl_option cl_options[] =
-#else
-static const struct cl_option cl_options[] =
-#endif
-{
- COMMAND_LINE_OPTIONS
-};
-#undef OPT
-#undef COMMAND_LINE_OPTIONS
-
-/* Holds switches parsed by c_common_decode_option (), but whose
- handling is deffered to c_common_post_options (). */
-static void defer_opt PARAMS ((enum opt_code, const char *));
+/* Holds switches parsed by c_common_handle_option (), but whose
+ handling is deferred to c_common_post_options (). */
+static void defer_opt (enum opt_code, const char *);
static struct deferred_opt
{
enum opt_code code;
const char *arg;
} *deferred_opts;
-
-#ifdef HOST_EBCDIC
-static int opt_comp PARAMS ((const void *, const void *));
-
-/* Run-time sorting of options array. */
-static int
-opt_comp (p1, p2)
- const void *p1, *p2;
-{
- return strcmp (((struct cl_option *) p1)->opt_text,
- ((struct cl_option *) p2)->opt_text);
-}
-#endif
-
-/* Complain that switch OPT_INDEX expects an argument but none was
- provided. */
-static void
-missing_arg (opt_index)
- size_t opt_index;
+/* Complain that switch CODE expects an argument but none was
+ provided. OPT was the command-line option. Return FALSE to get
+ the default message in opts.c, TRUE if we provide a specialized
+ one. */
+bool
+c_common_missing_argument (const char *opt, size_t code)
{
- const char *opt_text = cl_options[opt_index].opt_text;
-
- switch (cl_options[opt_index].opt_code)
+ switch (code)
{
- case OPT_Wformat_eq:
- case OPT_d:
- case OPT_fabi_version:
- case OPT_fbuiltin_:
- case OPT_fdump:
- case OPT_fname_mangling:
- case OPT_ftabstop:
- case OPT_ftemplate_depth:
default:
- error ("missing argument to \"-%s\"", opt_text);
+ /* Pick up the default message. */
+ return false;
+
+ case OPT_fconstant_string_class_:
+ error ("no class name specified with \"%s\"", opt);
break;
- case OPT_fconstant_string_class:
- error ("no class name specified with \"-%s\"", opt_text);
+ case OPT_A:
+ error ("assertion missing after \"%s\"", opt);
+ break;
+
+ case OPT_D:
+ case OPT_U:
+ error ("macro name missing after \"%s\"", opt);
+ break;
+
+ case OPT_I:
+ case OPT_idirafter:
+ case OPT_isysroot:
+ case OPT_isystem:
+ error ("missing path after \"%s\"", opt);
break;
case OPT_MF:
case OPT_MD:
case OPT_MMD:
+ case OPT_include:
+ case OPT_imacros:
case OPT_o:
- error ("missing filename after \"-%s\"", opt_text);
+ error ("missing filename after \"%s\"", opt);
break;
case OPT_MQ:
case OPT_MT:
- error ("missing target after \"-%s\"", opt_text);
+ error ("missing makefile target after \"%s\"", opt);
break;
}
-}
-/* Perform a binary search to find which option the command-line INPUT
- matches. Returns its index in the option array, and N_OPTS on
- failure.
-
- Complications arise since some options can be suffixed with an
- argument, and multiple complete matches can occur, e.g. -pedantic
- and -pedantic-errors. Also, some options are only accepted by some
- languages. If a switch matches for a different language and
- doesn't match any alternatives for the true front end, the index of
- the matched switch is returned anyway. The caller should check for
- this case. */
-static size_t
-find_opt (input, lang_flag)
- const char *input;
- int lang_flag;
-{
- size_t md, mn, mx;
- size_t opt_len;
- size_t result = N_OPTS;
- int comp;
-
- mn = 0;
- mx = N_OPTS;
-
- while (mx > mn)
- {
- md = (mn + mx) / 2;
-
- opt_len = cl_options[md].opt_len;
- comp = strncmp (input, cl_options[md].opt_text, opt_len);
-
- if (comp < 0)
- mx = md;
- else if (comp > 0)
- mn = md + 1;
- else
- {
- /* The switch matches. It it an exact match? */
- if (input[opt_len] == '\0')
- return md;
- else
- {
- mn = md + 1;
-
- /* If the switch takes no arguments this is not a proper
- match, so we continue the search (e.g. input="stdc++"
- match was "stdc"). */
- if (!(cl_options[md].flags & CL_JOINED))
- continue;
-
- /* Is this switch valid for this front end? */
- if (!(cl_options[md].flags & lang_flag))
- {
- /* If subsequently we don't find a better match,
- return this and let the caller report it as a bad
- match. */
- result = md;
- continue;
- }
-
- /* Two scenarios remain: we have the switch's argument,
- or we match a longer option. This can happen with
- -iwithprefix and -withprefixbefore. The longest
- possible option match succeeds.
-
- Scan forwards, and return an exact match. Otherwise
- return the longest valid option-accepting match (mx).
- This loops at most twice with current options. */
- mx = md;
- for (md = md + 1; md < (size_t) N_OPTS; md++)
- {
- opt_len = cl_options[md].opt_len;
- if (strncmp (input, cl_options[md].opt_text, opt_len))
- break;
- if (input[opt_len] == '\0')
- return md;
- if (cl_options[md].flags & lang_flag
- && cl_options[md].flags & CL_JOINED)
- mx = md;
- }
-
- return mx;
- }
- }
- }
-
- return result;
+ return true;
}
/* Defer option CODE with argument ARG. */
static void
-defer_opt (code, arg)
- enum opt_code code;
- const char *arg;
+defer_opt (enum opt_code code, const char *arg)
{
- /* FIXME: this should be in c_common_init_options, which should take
- argc and argv. */
- if (!deferred_opts)
- {
- extern int save_argc;
- deferred_size = save_argc;
- deferred_opts = (struct deferred_opt *)
- xmalloc (deferred_size * sizeof (struct deferred_opt));
- }
-
- if (deferred_count == deferred_size)
- abort ();
-
deferred_opts[deferred_count].code = code;
deferred_opts[deferred_count].arg = arg;
deferred_count++;
}
/* Common initialization before parsing options. */
-void
-c_common_init_options (lang)
- enum c_language_kind lang;
+unsigned int
+c_common_init_options (unsigned int argc, const char **argv ATTRIBUTE_UNUSED)
{
-#ifdef HOST_EBCDIC
- /* For non-ASCII hosts, the cl_options array needs to be sorted at
- runtime. */
- qsort (cl_options, N_OPTS, sizeof (struct cl_option), opt_comp);
-#endif
-#if ENABLE_CHECKING
- {
- size_t i;
+ static const unsigned int lang_flags[] = {CL_C, CL_ObjC, CL_CXX, CL_ObjCXX};
+ unsigned int result;
- for (i = 1; i < N_OPTS; i++)
- if (strcmp (cl_options[i - 1].opt_text, cl_options[i].opt_text) >= 0)
- error ("options array incorrectly sorted: %s is before %s",
- cl_options[i - 1].opt_text, cl_options[i].opt_text);
- }
-#endif
+ /* This is conditionalized only because that is the way the front
+ ends used to do it. Maybe this should be unconditional? */
+ if (c_dialect_cxx ())
+ {
+ /* By default wrap lines at 80 characters. Is getenv
+ ("COLUMNS") preferable? */
+ diagnostic_line_cutoff (global_dc) = 80;
+ /* By default, emit location information once for every
+ diagnostic message. */
+ diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
+ }
- c_language = lang;
- parse_in = cpp_create_reader (lang == clk_c ? CLK_GNUC89 : CLK_GNUCXX);
- cpp_opts = cpp_get_options (parse_in);
- if (flag_objc)
- cpp_opts->objc = 1;
+ parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89,
+ ident_hash);
- flag_const_strings = (lang == clk_cplusplus);
- warn_pointer_arith = (lang == clk_cplusplus);
- if (lang == clk_c)
- warn_sign_compare = -1;
-}
+ cpp_opts = cpp_get_options (parse_in);
+ cpp_opts->dollars_in_ident = DOLLARS_IN_IDENTIFIERS;
+ cpp_opts->objc = c_dialect_objc ();
-/* Handle one command-line option in (argc, argv).
- Can be called multiple times, to handle multiple sets of options.
- Returns number of strings consumed. */
-int
-c_common_decode_option (argc, argv)
- int argc;
- char **argv;
-{
- static const int lang_flags[] = {CL_C_ONLY, CL_C, CL_CXX_ONLY, CL_CXX};
- size_t opt_index;
- const char *opt, *arg = 0;
- char *dup = 0;
- bool on = true;
- int result, lang_flag;
- const struct cl_option *option;
- enum opt_code code;
+ /* Reset to avoid warnings on internal definitions. We set it just
+ before passing on command-line options to cpplib. */
+ cpp_opts->warn_dollars = 0;
- opt = argv[0];
+ flag_const_strings = c_dialect_cxx ();
+ flag_exceptions = c_dialect_cxx ();
+ warn_pointer_arith = c_dialect_cxx ();
- /* Interpret "-" or a non-switch as a file name. */
- if (opt[0] != '-' || opt[1] == '\0')
- {
- if (!in_fname)
- in_fname = opt;
- else if (!out_fname)
- out_fname = opt;
- else
- {
- error ("too many filenames given. Type %s --help for usage",
- progname);
- return argc;
- }
+ deferred_opts = xmalloc (argc * sizeof (struct deferred_opt));
- return 1;
- }
+ result = lang_flags[c_language];
- /* Drop the "no-" from negative switches. */
- if ((opt[1] == 'W' || opt[1] == 'f')
- && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
+ /* If potentially preprocessing Fortran we have to accept its front
+ end options since the driver passes most of them through. */
+#ifdef CL_F77
+ if (c_language == clk_c && argc > 2
+ && !strcmp (argv[2], "-traditional-cpp" ))
{
- size_t len = strlen (opt) - 3;
-
- dup = xmalloc (len + 1);
- dup[0] = '-';
- dup[1] = opt[1];
- memcpy (dup + 2, opt + 5, len - 2 + 1);
- opt = dup;
- on = false;
+ permit_fortran_options = true;
+ result |= CL_F77;
}
+#endif
- result = cpp_handle_option (parse_in, argc, argv);
-
- /* Skip over '-'. */
- lang_flag = lang_flags[(c_language << 1) + flag_objc];
- opt_index = find_opt (opt + 1, lang_flag);
- if (opt_index == N_OPTS)
- goto done;
-
- result = 1;
- option = &cl_options[opt_index];
-
- /* Sort out any argument the switch takes. */
- if (option->flags & CL_ARG)
- {
- if (option->flags & CL_JOINED)
- {
- /* Have arg point to the original switch. This is because
- some code, such as disable_builtin_function, expects its
- argument to be persistent until the program exits. */
- arg = argv[0] + cl_options[opt_index].opt_len + 1;
- if (!on)
- arg += strlen ("no-");
- }
-
- /* If we don't have an argument, and CL_SEPARATE, try the next
- argument in the vector. */
- if (!arg || (*arg == '\0' && option->flags & CL_SEPARATE))
- {
- arg = argv[1];
- result = 2;
- }
+ return result;
+}
- if (!arg || *arg == '\0')
- {
- missing_arg (opt_index);
- result = argc;
- goto done;
- }
- }
+/* Handle switch SCODE with argument ARG. VALUE is true, unless no-
+ form of an -f or -W option was given. Returns 0 if the switch was
+ invalid, a negative number to prevent language-independent
+ processing in toplev.c (a hack necessary for the short-term). */
+int
+c_common_handle_option (size_t scode, const char *arg, int value)
+{
+ const struct cl_option *option = &cl_options[scode];
+ enum opt_code code = (enum opt_code) scode;
+ int result = 1;
- /* Complain about the wrong language after we've swallowed any
- necessary extra argument. Eventually make this a hard error
- after the call to find_opt, and return argc. */
- if (!(cl_options[opt_index].flags & lang_flag))
+ switch (code)
{
- complain_wrong_lang (opt_index, on);
- goto done;
- }
+ default:
+ result = permit_fortran_options;
+ break;
- switch (code = option->opt_code)
- {
- case N_OPTS: /* Shut GCC up. */
+ case OPT__output_pch_:
+ pch_file = arg;
break;
- case OPT__help:
- print_help ();
+ case OPT_A:
+ defer_opt (code, arg);
break;
case OPT_C:
@@ -636,6 +270,10 @@ c_common_decode_option (argc, argv)
cpp_opts->discard_comments_in_macro_exp = 0;
break;
+ case OPT_D:
+ defer_opt (code, arg);
+ break;
+
case OPT_E:
flag_preprocess_only = 1;
break;
@@ -644,6 +282,18 @@ c_common_decode_option (argc, argv)
cpp_opts->print_include_names = 1;
break;
+ case OPT_I:
+ if (strcmp (arg, "-"))
+ add_path (xstrdup (arg), BRACKET, 0);
+ else
+ {
+ if (quote_chain_split)
+ error ("-I- specified twice");
+ quote_chain_split = true;
+ split_quote_chain ();
+ }
+ break;
+
case OPT_M:
case OPT_MM:
/* When doing dependencies with -M or -MM, suppress normal
@@ -651,7 +301,7 @@ c_common_decode_option (argc, argv)
depends on this. Preprocessed output does occur if -MD, -MMD
or environment var dependency generation is used. */
cpp_opts->deps.style = (code == OPT_M ? DEPS_SYSTEM: DEPS_USER);
- cpp_opts->no_output = 1;
+ flag_no_output = 1;
cpp_opts->inhibit_warnings = 1;
break;
@@ -683,306 +333,328 @@ c_common_decode_option (argc, argv)
break;
case OPT_P:
- cpp_opts->no_line_commands = 1;
+ flag_no_line_commands = 1;
+ break;
+
+ case OPT_fworking_directory:
+ flag_working_directory = value;
+ break;
+
+ case OPT_U:
+ defer_opt (code, arg);
break;
case OPT_Wabi:
- warn_abi = on;
+ warn_abi = value;
break;
case OPT_Wall:
- set_Wunused (on);
- set_Wformat (on);
- set_Wimplicit (on);
- warn_char_subscripts = on;
- warn_missing_braces = on;
- warn_parentheses = on;
- warn_return_type = on;
- warn_sequence_point = on; /* Was C only. */
- if (c_language == clk_cplusplus)
- warn_sign_compare = on;
- warn_switch = on;
- warn_strict_aliasing = on;
-
+ set_Wunused (value);
+ set_Wformat (value);
+ set_Wimplicit (value);
+ warn_char_subscripts = value;
+ warn_missing_braces = value;
+ warn_parentheses = value;
+ warn_return_type = value;
+ warn_sequence_point = value; /* Was C only. */
+ if (c_dialect_cxx ())
+ warn_sign_compare = value;
+ warn_switch = value;
+ warn_strict_aliasing = value;
+
/* Only warn about unknown pragmas that are not in system
- headers. */
- warn_unknown_pragmas = on;
+ headers. */
+ warn_unknown_pragmas = value;
/* We save the value of warn_uninitialized, since if they put
-Wuninitialized on the command line, we need to generate a
warning about not using it without also specifying -O. */
if (warn_uninitialized != 1)
- warn_uninitialized = (on ? 2 : 0);
+ warn_uninitialized = (value ? 2 : 0);
- if (c_language == clk_c)
+ if (!c_dialect_cxx ())
/* We set this to 2 here, but 1 in -Wmain, so -ffreestanding
can turn it off only if it's not explicit. */
- warn_main = on * 2;
+ warn_main = value * 2;
else
{
/* C++-specific warnings. */
- warn_ctor_dtor_privacy = on;
- warn_nonvdtor = on;
- warn_reorder = on;
- warn_nontemplate_friend = on;
+ warn_nonvdtor = value;
+ warn_reorder = value;
+ warn_nontemplate_friend = value;
}
- cpp_opts->warn_trigraphs = on;
- cpp_opts->warn_comments = on;
- cpp_opts->warn_num_sign_change = on;
- cpp_opts->warn_multichar = on; /* Was C++ only. */
+ cpp_opts->warn_trigraphs = value;
+ cpp_opts->warn_comments = value;
+ cpp_opts->warn_num_sign_change = value;
+ cpp_opts->warn_multichar = value; /* Was C++ only. */
break;
case OPT_Wbad_function_cast:
- warn_bad_function_cast = on;
+ warn_bad_function_cast = value;
break;
case OPT_Wcast_qual:
- warn_cast_qual = on;
+ warn_cast_qual = value;
break;
case OPT_Wchar_subscripts:
- warn_char_subscripts = on;
+ warn_char_subscripts = value;
break;
case OPT_Wcomment:
case OPT_Wcomments:
- cpp_opts->warn_comments = on;
+ cpp_opts->warn_comments = value;
break;
case OPT_Wconversion:
- warn_conversion = on;
+ warn_conversion = value;
break;
case OPT_Wctor_dtor_privacy:
- warn_ctor_dtor_privacy = on;
+ warn_ctor_dtor_privacy = value;
+ break;
+
+ case OPT_Wdeclaration_after_statement:
+ warn_declaration_after_statement = value;
break;
case OPT_Wdeprecated:
- warn_deprecated = on;
+ warn_deprecated = value;
+ cpp_opts->warn_deprecated = value;
break;
case OPT_Wdiv_by_zero:
- warn_div_by_zero = on;
+ warn_div_by_zero = value;
break;
- case OPT_Weffcxx:
- warn_ecpp = on;
+ case OPT_Weffc__:
+ warn_ecpp = value;
break;
case OPT_Wendif_labels:
- cpp_opts->warn_endif_labels = on;
+ cpp_opts->warn_endif_labels = value;
break;
case OPT_Werror:
- cpp_opts->warnings_are_errors = on;
+ cpp_opts->warnings_are_errors = value;
break;
- case OPT_Werror_implicit_function_decl:
- if (!on)
- result = 0;
- else
- mesg_implicit_function_declaration = 2;
+ case OPT_Werror_implicit_function_declaration:
+ mesg_implicit_function_declaration = 2;
break;
case OPT_Wfloat_equal:
- warn_float_equal = on;
+ warn_float_equal = value;
break;
case OPT_Wformat:
- set_Wformat (on);
+ set_Wformat (value);
break;
- case OPT_Wformat_eq:
+ case OPT_Wformat_:
set_Wformat (atoi (arg));
break;
case OPT_Wformat_extra_args:
- warn_format_extra_args = on;
+ warn_format_extra_args = value;
break;
case OPT_Wformat_nonliteral:
- warn_format_nonliteral = on;
+ warn_format_nonliteral = value;
break;
case OPT_Wformat_security:
- warn_format_security = on;
+ warn_format_security = value;
break;
case OPT_Wformat_y2k:
- warn_format_y2k = on;
+ warn_format_y2k = value;
break;
case OPT_Wformat_zero_length:
- warn_format_zero_length = on;
+ warn_format_zero_length = value;
+ break;
+
+ case OPT_Winit_self:
+ warn_init_self = value;
break;
case OPT_Wimplicit:
- set_Wimplicit (on);
+ set_Wimplicit (value);
break;
- case OPT_Wimplicit_function_decl:
- mesg_implicit_function_declaration = on;
+ case OPT_Wimplicit_function_declaration:
+ mesg_implicit_function_declaration = value;
break;
case OPT_Wimplicit_int:
- warn_implicit_int = on;
+ warn_implicit_int = value;
break;
case OPT_Wimport:
- cpp_opts->warn_import = on;
+ /* Silently ignore for now. */
+ break;
+
+ case OPT_Winvalid_offsetof:
+ warn_invalid_offsetof = value;
+ break;
+
+ case OPT_Winvalid_pch:
+ cpp_opts->warn_invalid_pch = value;
break;
case OPT_Wlong_long:
- warn_long_long = on;
+ warn_long_long = value;
break;
case OPT_Wmain:
- if (on)
+ if (value)
warn_main = 1;
else
warn_main = -1;
break;
case OPT_Wmissing_braces:
- warn_missing_braces = on;
+ warn_missing_braces = value;
break;
case OPT_Wmissing_declarations:
- warn_missing_declarations = on;
+ warn_missing_declarations = value;
break;
case OPT_Wmissing_format_attribute:
- warn_missing_format_attribute = on;
+ warn_missing_format_attribute = value;
break;
case OPT_Wmissing_prototypes:
- warn_missing_prototypes = on;
+ warn_missing_prototypes = value;
break;
case OPT_Wmultichar:
- cpp_opts->warn_multichar = on;
+ cpp_opts->warn_multichar = value;
break;
case OPT_Wnested_externs:
- warn_nested_externs = on;
+ warn_nested_externs = value;
break;
case OPT_Wnon_template_friend:
- warn_nontemplate_friend = on;
+ warn_nontemplate_friend = value;
break;
case OPT_Wnon_virtual_dtor:
- warn_nonvdtor = on;
+ warn_nonvdtor = value;
break;
case OPT_Wnonnull:
- warn_nonnull = on;
+ warn_nonnull = value;
+ break;
+
+ case OPT_Wold_style_definition:
+ warn_old_style_definition = value;
break;
case OPT_Wold_style_cast:
- warn_old_style_cast = on;
+ warn_old_style_cast = value;
break;
case OPT_Woverloaded_virtual:
- warn_overloaded_virtual = on;
+ warn_overloaded_virtual = value;
break;
case OPT_Wparentheses:
- warn_parentheses = on;
+ warn_parentheses = value;
break;
case OPT_Wpmf_conversions:
- warn_pmf2ptr = on;
+ warn_pmf2ptr = value;
break;
case OPT_Wpointer_arith:
- warn_pointer_arith = on;
+ warn_pointer_arith = value;
break;
case OPT_Wprotocol:
- warn_protocol = on;
+ warn_protocol = value;
break;
case OPT_Wselector:
- warn_selector = on;
+ warn_selector = value;
break;
case OPT_Wredundant_decls:
- warn_redundant_decls = on;
+ warn_redundant_decls = value;
break;
case OPT_Wreorder:
- warn_reorder = on;
+ warn_reorder = value;
break;
case OPT_Wreturn_type:
- warn_return_type = on;
+ warn_return_type = value;
break;
case OPT_Wsequence_point:
- warn_sequence_point = on;
+ warn_sequence_point = value;
break;
case OPT_Wsign_compare:
- warn_sign_compare = on;
+ warn_sign_compare = value;
break;
case OPT_Wsign_promo:
- warn_sign_promo = on;
+ warn_sign_promo = value;
break;
case OPT_Wstrict_prototypes:
- if (!on && c_language == clk_cplusplus)
- warning ("-Wno-strict-prototypes is not supported in C++");
- else
- warn_strict_prototypes = on;
+ warn_strict_prototypes = value;
break;
case OPT_Wsynth:
- warn_synth = on;
+ warn_synth = value;
break;
case OPT_Wsystem_headers:
- cpp_opts->warn_system_headers = on;
+ cpp_opts->warn_system_headers = value;
break;
case OPT_Wtraditional:
- warn_traditional = on;
- cpp_opts->warn_traditional = on;
+ warn_traditional = value;
+ cpp_opts->warn_traditional = value;
break;
case OPT_Wtrigraphs:
- cpp_opts->warn_trigraphs = on;
+ cpp_opts->warn_trigraphs = value;
break;
case OPT_Wundeclared_selector:
- warn_undeclared_selector = on;
+ warn_undeclared_selector = value;
break;
case OPT_Wundef:
- cpp_opts->warn_undef = on;
+ cpp_opts->warn_undef = value;
break;
case OPT_Wunknown_pragmas:
/* Set to greater than 1, so that even unknown pragmas in
- system headers will be warned about. */
- warn_unknown_pragmas = on * 2;
+ system headers will be warned about. */
+ warn_unknown_pragmas = value * 2;
break;
case OPT_Wunused_macros:
- cpp_opts->warn_unused_macros = on;
+ warn_unused_macros = value;
break;
case OPT_Wwrite_strings:
- if (c_language == clk_c)
- flag_const_strings = on;
+ if (!c_dialect_cxx ())
+ flag_const_strings = value;
else
- warn_write_strings = on;
+ warn_write_strings = value;
break;
-
+
case OPT_ansi:
- if (c_language == clk_c)
+ if (!c_dialect_cxx ())
set_std_c89 (false, true);
else
set_std_cxx98 (true);
@@ -993,20 +665,22 @@ c_common_decode_option (argc, argv)
break;
case OPT_fcond_mismatch:
- if (c_language == clk_c)
+ if (!c_dialect_cxx ())
{
- flag_cond_mismatch = on;
+ flag_cond_mismatch = value;
break;
}
/* Fall through. */
case OPT_fall_virtual:
+ case OPT_falt_external_templates:
case OPT_fenum_int_equiv:
+ case OPT_fexternal_templates:
case OPT_fguiding_decls:
case OPT_fhonor_std:
case OPT_fhuge_objects:
case OPT_flabels_ok:
- case OPT_fname_mangling:
+ case OPT_fname_mangling_version_:
case OPT_fnew_abi:
case OPT_fnonnull_objects:
case OPT_fsquangle:
@@ -1014,240 +688,275 @@ c_common_decode_option (argc, argv)
case OPT_fthis_is_variable:
case OPT_fvtable_thunks:
case OPT_fxref:
- warning ("switch \"%s\" is no longer supported", argv[0]);
- break;
-
- case OPT_fabi_version:
- flag_abi_version = read_integral_parameter (arg, argv[0], 1);
+ case OPT_fvtable_gc:
+ warning ("switch \"%s\" is no longer supported", option->opt_text);
break;
case OPT_faccess_control:
- flag_access_control = on;
- break;
-
- case OPT_falt_external_templates:
- flag_alt_external_templates = on;
- if (on)
- flag_external_templates = true;
- cp_deprecated:
- warning ("switch \"%s\" is deprecated, please see documentation for details", argv[0]);
+ flag_access_control = value;
break;
case OPT_fasm:
- flag_no_asm = !on;
+ flag_no_asm = !value;
break;
case OPT_fbuiltin:
- flag_no_builtin = !on;
+ flag_no_builtin = !value;
break;
case OPT_fbuiltin_:
- if (on)
+ if (value)
result = 0;
else
disable_builtin_function (arg);
break;
case OPT_fdollars_in_identifiers:
- dollars_in_ident = on;
+ cpp_opts->dollars_in_ident = value;
break;
- case OPT_fdump:
- if (!on || !dump_switch_p (argv[0] + strlen ("-f")))
+ case OPT_fdump_:
+ if (!dump_switch_p (arg))
result = 0;
break;
case OPT_ffreestanding:
- on = !on;
- /* Fall through... */
+ value = !value;
+ /* Fall through.... */
case OPT_fhosted:
- flag_hosted = on;
- flag_no_builtin = !on;
+ flag_hosted = value;
+ flag_no_builtin = !value;
/* warn_main will be 2 if set by -Wall, 1 if set by -Wmain */
- if (!on && warn_main == 2)
+ if (!value && warn_main == 2)
warn_main = 0;
break;
case OPT_fshort_double:
- flag_short_double = on;
+ flag_short_double = value;
break;
case OPT_fshort_enums:
- flag_short_enums = on;
+ flag_short_enums = value;
break;
case OPT_fshort_wchar:
- flag_short_wchar = on;
+ flag_short_wchar = value;
break;
case OPT_fsigned_bitfields:
- flag_signed_bitfields = on;
+ flag_signed_bitfields = value;
explicit_flag_signed_bitfields = 1;
break;
case OPT_fsigned_char:
- flag_signed_char = on;
+ flag_signed_char = value;
break;
case OPT_funsigned_bitfields:
- flag_signed_bitfields = !on;
+ flag_signed_bitfields = !value;
explicit_flag_signed_bitfields = 1;
break;
case OPT_funsigned_char:
- flag_signed_char = !on;
+ flag_signed_char = !value;
break;
case OPT_fcheck_new:
- flag_check_new = on;
+ flag_check_new = value;
break;
case OPT_fconserve_space:
- flag_conserve_space = on;
+ flag_conserve_space = value;
break;
case OPT_fconst_strings:
- flag_const_strings = on;
+ flag_const_strings = value;
break;
- case OPT_fconstant_string_class:
+ case OPT_fconstant_string_class_:
constant_string_class_name = arg;
break;
case OPT_fdefault_inline:
- flag_default_inline = on;
+ flag_default_inline = value;
break;
case OPT_felide_constructors:
- flag_elide_constructors = on;
+ flag_elide_constructors = value;
break;
case OPT_fenforce_eh_specs:
- flag_enforce_eh_specs = on;
+ flag_enforce_eh_specs = value;
break;
- case OPT_fexternal_templates:
- flag_external_templates = on;
- goto cp_deprecated;
-
case OPT_ffixed_form:
- case OPT_ffixed_line_length:
+ case OPT_ffixed_line_length_:
/* Fortran front end options ignored when preprocessing only. */
- if (flag_preprocess_only)
- result = -1;
+ if (!flag_preprocess_only)
+ result = 0;
break;
case OPT_ffor_scope:
- flag_new_for_scope = on;
+ flag_new_for_scope = value;
break;
case OPT_fgnu_keywords:
- flag_no_gnu_keywords = !on;
+ flag_no_gnu_keywords = !value;
break;
case OPT_fgnu_runtime:
- flag_next_runtime = !on;
+ flag_next_runtime = !value;
break;
case OPT_fhandle_exceptions:
- warning ("-fhandle-exceptions has been renamed to -fexceptions (and is now on by default)");
- flag_exceptions = on;
+ warning ("-fhandle-exceptions has been renamed -fexceptions (and is now on by default)");
+ flag_exceptions = value;
break;
case OPT_fimplement_inlines:
- flag_implement_inlines = on;
+ flag_implement_inlines = value;
break;
case OPT_fimplicit_inline_templates:
- flag_implicit_inline_templates = on;
+ flag_implicit_inline_templates = value;
break;
case OPT_fimplicit_templates:
- flag_implicit_templates = on;
+ flag_implicit_templates = value;
break;
case OPT_fms_extensions:
- flag_ms_extensions = on;
+ flag_ms_extensions = value;
break;
case OPT_fnext_runtime:
- flag_next_runtime = on;
+ flag_next_runtime = value;
+ break;
+
+ case OPT_fnil_receivers:
+ flag_nil_receivers = value;
break;
case OPT_fnonansi_builtins:
- flag_no_nonansi_builtin = !on;
+ flag_no_nonansi_builtin = !value;
+ break;
+
+ case OPT_fobjc_exceptions:
+ flag_objc_exceptions = value;
break;
case OPT_foperator_names:
- cpp_opts->operator_names = on;
+ cpp_opts->operator_names = value;
break;
case OPT_foptional_diags:
- flag_optional_diags = on;
+ flag_optional_diags = value;
+ break;
+
+ case OPT_fpch_deps:
+ cpp_opts->restore_pch_deps = value;
break;
case OPT_fpermissive:
- flag_permissive = on;
+ flag_permissive = value;
break;
case OPT_fpreprocessed:
- cpp_opts->preprocessed = on;
+ cpp_opts->preprocessed = value;
break;
+ case OPT_freplace_objc_classes:
+ flag_replace_objc_classes = value;
+ break;
+
case OPT_frepo:
- flag_use_repository = on;
- if (on)
+ flag_use_repository = value;
+ if (value)
flag_implicit_templates = 0;
break;
case OPT_frtti:
- flag_rtti = on;
+ flag_rtti = value;
break;
case OPT_fshow_column:
- cpp_opts->show_column = on;
+ cpp_opts->show_column = value;
break;
case OPT_fstats:
- flag_detailed_statistics = on;
+ flag_detailed_statistics = value;
break;
- case OPT_ftabstop:
- /* Don't recognize -fno-tabstop=. */
- if (!on)
- return 0;
-
+ case OPT_ftabstop_:
/* It is documented that we silently ignore silly values. */
- {
- char *endptr;
- long tabstop = strtol (arg, &endptr, 10);
- if (*endptr == '\0' && tabstop >= 1 && tabstop <= 100)
- cpp_opts->tabstop = tabstop;
- }
+ if (value >= 1 && value <= 100)
+ cpp_opts->tabstop = value;
break;
- case OPT_ftemplate_depth:
- max_tinst_depth = read_integral_parameter (arg, argv[0], 0);
+ case OPT_fexec_charset_:
+ cpp_opts->narrow_charset = arg;
break;
- case OPT_fvtable_gc:
- flag_vtable_gc = on;
+ case OPT_fwide_exec_charset_:
+ cpp_opts->wide_charset = arg;
+ break;
+
+ case OPT_finput_charset_:
+ cpp_opts->input_charset = arg;
+ break;
+
+ case OPT_ftemplate_depth_:
+ max_tinst_depth = value;
break;
case OPT_fuse_cxa_atexit:
- flag_use_cxa_atexit = on;
+ flag_use_cxa_atexit = value;
break;
case OPT_fweak:
- flag_weak = on;
+ flag_weak = value;
+ break;
+
+ case OPT_fzero_link:
+ flag_zero_link = value;
break;
case OPT_gen_decls:
flag_gen_declaration = 1;
break;
+ case OPT_idirafter:
+ add_path (xstrdup (arg), AFTER, 0);
+ break;
+
+ case OPT_imacros:
+ case OPT_include:
+ defer_opt (code, arg);
+ break;
+
+ case OPT_iprefix:
+ iprefix = arg;
+ break;
+
+ case OPT_isysroot:
+ sysroot = arg;
+ break;
+
+ case OPT_isystem:
+ add_path (xstrdup (arg), SYSTEM, 0);
+ break;
+
+ case OPT_iwithprefix:
+ add_prefixed_path (arg, SYSTEM);
+ break;
+
+ case OPT_iwithprefixbefore:
+ add_prefixed_path (arg, BRACKET);
+ break;
+
case OPT_lang_asm:
cpp_set_lang (parse_in, CLK_ASM);
+ cpp_opts->dollars_in_ident = false;
break;
case OPT_lang_objc:
@@ -1255,24 +964,18 @@ c_common_decode_option (argc, argv)
break;
case OPT_nostdinc:
- /* No default include directories. You must specify all
- include-file directories with -I. */
- cpp_opts->no_standard_includes = 1;
+ std_inc = false;
break;
- case OPT_nostdincplusplus:
- /* No default C++-specific include directories. */
- cpp_opts->no_standard_cplusplus_includes = 1;
+ case OPT_nostdinc__:
+ std_cxx_inc = false;
break;
case OPT_o:
if (!out_fname)
out_fname = arg;
else
- {
- error ("output filename specified twice");
- result = argc;
- }
+ error ("output filename specified twice");
break;
/* We need to handle the -pedantic switches here, rather than in
@@ -1280,7 +983,7 @@ c_common_decode_option (argc, argv)
is not overridden. */
case OPT_pedantic_errors:
cpp_opts->pedantic_errors = 1;
- /* fall through */
+ /* Fall through. */
case OPT_pedantic:
cpp_opts->pedantic = 1;
cpp_opts->warn_endif_labels = 1;
@@ -1294,9 +997,9 @@ c_common_decode_option (argc, argv)
cpp_opts->remap = 1;
break;
- case OPT_std_cplusplus98:
- case OPT_std_gnuplusplus98:
- set_std_cxx98 (code == OPT_std_cplusplus98 /* ISO */);
+ case OPT_std_c__98:
+ case OPT_std_gnu__98:
+ set_std_cxx98 (code == OPT_std_c__98 /* ISO */);
break;
case OPT_std_c89:
@@ -1338,23 +1041,27 @@ c_common_decode_option (argc, argv)
break;
case OPT_v:
- cpp_opts->verbose = 1;
+ verbose = true;
break;
}
- done:
- if (dup)
- free (dup);
return result;
}
/* Post-switch processing. */
bool
-c_common_post_options ()
+c_common_post_options (const char **pfilename)
{
+ struct cpp_callbacks *cb;
+
/* Canonicalize the input and output filenames. */
- if (in_fname == NULL || !strcmp (in_fname, "-"))
- in_fname = "";
+ if (in_fnames == NULL)
+ {
+ in_fnames = xmalloc (sizeof (in_fnames[0]));
+ in_fnames[0] = "";
+ }
+ else if (strcmp (in_fnames[0], "-") == 0)
+ in_fnames[0] = "";
if (out_fname == NULL || !strcmp (out_fname, "-"))
out_fname = "";
@@ -1366,11 +1073,19 @@ c_common_post_options ()
sanitize_cpp_opts ();
+ register_include_chains (parse_in, sysroot, iprefix,
+ std_inc, std_cxx_inc && c_dialect_cxx (), verbose);
+
flag_inline_trees = 1;
/* Use tree inlining if possible. Function instrumentation is only
done in the RTL level, so we disable tree inlining. */
- if (! flag_instrument_function_entry_exit)
+ if (flag_instrument_function_entry_exit)
+ {
+ flag_no_inline = 1;
+ flag_really_no_inline = 1;
+ }
+ else
{
if (!flag_no_inline)
flag_no_inline = 1;
@@ -1381,6 +1096,11 @@ c_common_post_options ()
}
}
+ /* -Wextra implies -Wsign-compare, but not if explicitly
+ overridden. */
+ if (warn_sign_compare == -1)
+ warn_sign_compare = extra_warnings;
+
/* Special format checking options don't work without -Wformat; warn if
they are used. */
if (warn_format_y2k && !warn_format)
@@ -1396,36 +1116,66 @@ c_common_post_options ()
if (warn_missing_format_attribute && !warn_format)
warning ("-Wmissing-format-attribute ignored without -Wformat");
+ if (flag_preprocess_only)
+ {
+ /* Open the output now. We must do so even if flag_no_output is
+ on, because there may be other output than from the actual
+ preprocessing (e.g. from -dM). */
+ if (out_fname[0] == '\0')
+ out_stream = stdout;
+ else
+ out_stream = fopen (out_fname, "w");
+
+ if (out_stream == NULL)
+ {
+ fatal_error ("opening output file %s: %m", out_fname);
+ return false;
+ }
+
+ if (num_in_fnames > 1)
+ error ("too many filenames given. Type %s --help for usage",
+ progname);
+
+ init_pp_output (out_stream);
+ }
+ else
+ {
+ init_c_lex ();
+
+ /* Yuk. WTF is this? I do know ObjC relies on it somewhere. */
+ input_line = 0;
+ }
+
+ cb = cpp_get_callbacks (parse_in);
+ cb->file_change = cb_file_change;
+ cb->dir_change = cb_dir_change;
+ cpp_post_options (parse_in);
+
+ saved_lineno = input_line;
+ input_line = 0;
+
/* If an error has occurred in cpplib, note it so we fail
immediately. */
errorcount += cpp_errors (parse_in);
- return flag_preprocess_only;
-}
+ *pfilename = this_input_filename
+ = cpp_read_main_file (parse_in, in_fnames[0]);
+ if (this_input_filename == NULL)
+ return true;
-/* Preprocess the input file to out_stream. */
-static void
-preprocess_file ()
-{
- /* Open the output now. We must do so even if no_output is on,
- because there may be other output than from the actual
- preprocessing (e.g. from -dM). */
- if (out_fname[0] == '\0')
- out_stream = stdout;
- else
- out_stream = fopen (out_fname, "w");
+ if (flag_working_directory
+ && flag_preprocess_only && ! flag_no_line_commands)
+ pp_dir_change (parse_in, get_src_pwd ());
- if (out_stream == NULL)
- fatal_io_error ("opening output file %s", out_fname);
- else
- cpp_preprocess_file (parse_in, in_fname, out_stream);
+ return flag_preprocess_only;
}
/* Front end initialization common to C, ObjC and C++. */
-const char *
-c_common_init (filename)
- const char *filename;
+bool
+c_common_init (void)
{
+ input_line = saved_lineno;
+
/* Set up preprocessor arithmetic. Must be done after call to
c_common_nodes_and_builtins for type nodes to be good. */
cpp_opts->precision = TYPE_PRECISION (intmax_type_node);
@@ -1433,31 +1183,68 @@ c_common_init (filename)
cpp_opts->int_precision = TYPE_PRECISION (integer_type_node);
cpp_opts->wchar_precision = TYPE_PRECISION (wchar_type_node);
cpp_opts->unsigned_wchar = TREE_UNSIGNED (wchar_type_node);
+ cpp_opts->bytes_big_endian = BYTES_BIG_ENDIAN;
- /* Register preprocessor built-ins before calls to
- cpp_main_file. */
- cpp_get_callbacks (parse_in)->register_builtins = cb_register_builtins;
+ /* This can't happen until after wchar_precision and bytes_big_endian
+ are known. */
+ cpp_init_iconv (parse_in);
- /* NULL is passed up to toplev.c and we exit quickly. */
if (flag_preprocess_only)
{
- preprocess_file ();
- return NULL;
+ finish_options ();
+ preprocess_file (parse_in);
+ return false;
}
- /* Do this before initializing pragmas, as then cpplib's hash table
- has been set up. NOTE: we are using our own file name here, not
- the one supplied. */
- filename = init_c_lex (in_fname);
-
+ /* Has to wait until now so that cpplib has its hash table. */
init_pragma ();
- return filename;
+ return true;
+}
+
+/* Initialize the integrated preprocessor after debug output has been
+ initialized; loop over each input file. */
+void
+c_common_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
+{
+ unsigned file_index;
+
+#if YYDEBUG != 0
+ yydebug = set_yydebug;
+#else
+ warning ("YYDEBUG not defined");
+#endif
+
+ file_index = 0;
+
+ do
+ {
+ if (file_index > 0)
+ {
+ /* Reset the state of the parser. */
+ c_reset_state();
+
+ /* Reset cpplib's macros and start a new file. */
+ cpp_undef_all (parse_in);
+ main_input_filename = this_input_filename
+ = cpp_read_main_file (parse_in, in_fnames[file_index]);
+ if (this_input_filename == NULL)
+ break;
+ }
+ finish_options ();
+ if (file_index == 0)
+ pch_init();
+ c_parse_file ();
+
+ file_index++;
+ } while (file_index < num_in_fnames);
+
+ finish_file ();
}
/* Common finish hook for the C, ObjC and C++ front ends. */
void
-c_common_finish ()
+c_common_finish (void)
{
FILE *deps_stream = NULL;
@@ -1471,7 +1258,7 @@ c_common_finish ()
{
deps_stream = fopen (deps_file, deps_append ? "a": "w");
if (!deps_stream)
- fatal_io_error ("opening dependency file %s", deps_file);
+ fatal_error ("opening dependency file %s: %m", deps_file);
}
}
@@ -1481,10 +1268,10 @@ c_common_finish ()
if (deps_stream && deps_stream != out_stream
&& (ferror (deps_stream) || fclose (deps_stream)))
- fatal_io_error ("closing dependency file %s", deps_file);
+ fatal_error ("closing dependency file %s: %m", deps_file);
if (out_stream && (ferror (out_stream) || fclose (out_stream)))
- fatal_io_error ("when writing output to %s", out_fname);
+ fatal_error ("when writing output to %s: %m", out_fname);
}
/* Either of two environment variables can specify output of
@@ -1495,7 +1282,7 @@ c_common_finish ()
rather than overwriting it, and like Sun's compiler
SUNPRO_DEPENDENCIES suppresses the dependency on the main file. */
static void
-check_deps_environment_vars ()
+check_deps_environment_vars (void)
{
char *spec;
@@ -1533,7 +1320,7 @@ check_deps_environment_vars ()
/* Handle deferred command line switches. */
static void
-handle_deferred_opts ()
+handle_deferred_opts (void)
{
size_t i;
@@ -1541,25 +1328,15 @@ handle_deferred_opts ()
{
struct deferred_opt *opt = &deferred_opts[i];
- switch (opt->code)
- {
- case OPT_MT:
- case OPT_MQ:
- cpp_add_dependency_target (parse_in, opt->arg, opt->code == OPT_MQ);
- break;
-
- default:
- abort ();
- }
+ if (opt->code == OPT_MT || opt->code == OPT_MQ)
+ cpp_add_dependency_target (parse_in, opt->arg, opt->code == OPT_MQ);
}
-
- free (deferred_opts);
}
/* These settings are appropriate for GCC, but not necessarily so for
cpplib as a library. */
static void
-sanitize_cpp_opts ()
+sanitize_cpp_opts (void)
{
/* If we don't know what style of dependencies to output, complain
if any other dependency switches have been given. */
@@ -1568,16 +1345,16 @@ sanitize_cpp_opts ()
/* -dM and dependencies suppress normal output; do it here so that
the last -d[MDN] switch overrides earlier ones. */
- if (cpp_opts->dump_macros == dump_only)
- cpp_opts->no_output = 1;
+ if (flag_dump_macros == 'M')
+ flag_no_output = 1;
/* Disable -dD, -dN and -dI if normal output is suppressed. Allow
-dM since at least glibc relies on -M -dM to work. */
- if (cpp_opts->no_output)
+ if (flag_no_output)
{
- if (cpp_opts->dump_macros != dump_only)
- cpp_opts->dump_macros = dump_none;
- cpp_opts->dump_includes = 0;
+ if (flag_dump_macros != 'M')
+ flag_dump_macros = 0;
+ flag_dump_includes = 0;
}
cpp_opts->unsigned_char = !flag_signed_char;
@@ -1587,20 +1364,155 @@ sanitize_cpp_opts ()
and/or -Wtraditional, whatever the ordering. */
cpp_opts->warn_long_long
= warn_long_long && ((!flag_isoc99 && pedantic) || warn_traditional);
+
+ /* If we're generating preprocessor output, emit current directory
+ if explicitly requested or if debugging information is enabled.
+ ??? Maybe we should only do it for debugging formats that
+ actually output the current directory? */
+ if (flag_working_directory == -1)
+ flag_working_directory = (debug_info_level != DINFO_LEVEL_NONE);
+}
+
+/* Add include path with a prefix at the front of its name. */
+static void
+add_prefixed_path (const char *suffix, size_t chain)
+{
+ char *path;
+ const char *prefix;
+ size_t prefix_len, suffix_len;
+
+ suffix_len = strlen (suffix);
+ prefix = iprefix ? iprefix : cpp_GCC_INCLUDE_DIR;
+ prefix_len = iprefix ? strlen (iprefix) : cpp_GCC_INCLUDE_DIR_len;
+
+ path = xmalloc (prefix_len + suffix_len + 1);
+ memcpy (path, prefix, prefix_len);
+ memcpy (path + prefix_len, suffix, suffix_len);
+ path[prefix_len + suffix_len] = '\0';
+
+ add_path (path, chain, 0);
+}
+
+/* Handle -D, -U, -A, -imacros, and the first -include. */
+static void
+finish_options (void)
+{
+ if (!cpp_opts->preprocessed)
+ {
+ size_t i;
+
+ cpp_change_file (parse_in, LC_RENAME, _("<built-in>"));
+ cpp_init_builtins (parse_in, flag_hosted);
+ c_cpp_builtins (parse_in);
+
+ /* We're about to send user input to cpplib, so make it warn for
+ things that we previously (when we sent it internal definitions)
+ told it to not warn.
+
+ C99 permits implementation-defined characters in identifiers.
+ The documented meaning of -std= is to turn off extensions that
+ conflict with the specified standard, and since a strictly
+ conforming program cannot contain a '$', we do not condition
+ their acceptance on the -std= setting. */
+ cpp_opts->warn_dollars = (cpp_opts->pedantic && !cpp_opts->c99);
+
+ cpp_change_file (parse_in, LC_RENAME, _("<command line>"));
+ for (i = 0; i < deferred_count; i++)
+ {
+ struct deferred_opt *opt = &deferred_opts[i];
+
+ if (opt->code == OPT_D)
+ cpp_define (parse_in, opt->arg);
+ else if (opt->code == OPT_U)
+ cpp_undef (parse_in, opt->arg);
+ else if (opt->code == OPT_A)
+ {
+ if (opt->arg[0] == '-')
+ cpp_unassert (parse_in, opt->arg + 1);
+ else
+ cpp_assert (parse_in, opt->arg);
+ }
+ }
+
+ /* Handle -imacros after -D and -U. */
+ for (i = 0; i < deferred_count; i++)
+ {
+ struct deferred_opt *opt = &deferred_opts[i];
+
+ if (opt->code == OPT_imacros
+ && cpp_push_include (parse_in, opt->arg))
+ {
+ /* Disable push_command_line_include callback for now. */
+ include_cursor = deferred_count + 1;
+ cpp_scan_nooutput (parse_in);
+ }
+ }
+ }
+
+ include_cursor = 0;
+ push_command_line_include ();
+}
+
+/* Give CPP the next file given by -include, if any. */
+static void
+push_command_line_include (void)
+{
+ while (include_cursor < deferred_count)
+ {
+ struct deferred_opt *opt = &deferred_opts[include_cursor++];
+
+ if (! cpp_opts->preprocessed && opt->code == OPT_include
+ && cpp_push_include (parse_in, opt->arg))
+ return;
+ }
+
+ if (include_cursor == deferred_count)
+ {
+ include_cursor++;
+ /* -Wunused-macros should only warn about macros defined hereafter. */
+ cpp_opts->warn_unused_macros = warn_unused_macros;
+ /* Restore the line map from <command line>. */
+ if (! cpp_opts->preprocessed)
+ cpp_change_file (parse_in, LC_RENAME, main_input_filename);
+
+ /* Set this here so the client can change the option if it wishes,
+ and after stacking the main file so we don't trace the main file. */
+ cpp_get_line_maps (parse_in)->trace_includes
+ = cpp_opts->print_include_names;
+ }
+}
+
+/* File change callback. Has to handle -include files. */
+static void
+cb_file_change (cpp_reader *pfile ATTRIBUTE_UNUSED,
+ const struct line_map *new_map)
+{
+ if (flag_preprocess_only)
+ pp_file_change (new_map);
+ else
+ fe_file_change (new_map);
+
+ if (new_map == 0 || (new_map->reason == LC_LEAVE && MAIN_FILE_P (new_map)))
+ push_command_line_include ();
+}
+
+void
+cb_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
+{
+ if (! set_src_pwd (dir))
+ warning ("too late for # directive to set debug directory");
}
/* Set the C 89 standard (with 1994 amendments if C94, without GNU
extensions if ISO). There is no concept of gnu94. */
static void
-set_std_c89 (c94, iso)
- int c94, iso;
+set_std_c89 (int c94, int iso)
{
cpp_set_lang (parse_in, c94 ? CLK_STDC94: iso ? CLK_STDC89: CLK_GNUC89);
flag_iso = iso;
flag_no_asm = iso;
flag_no_gnu_keywords = iso;
flag_no_nonansi_builtin = iso;
- flag_noniso_default_format_attributes = !iso;
flag_isoc94 = c94;
flag_isoc99 = 0;
flag_writable_strings = 0;
@@ -1608,13 +1520,11 @@ set_std_c89 (c94, iso)
/* Set the C 99 standard (without GNU extensions if ISO). */
static void
-set_std_c99 (iso)
- int iso;
+set_std_c99 (int iso)
{
cpp_set_lang (parse_in, iso ? CLK_STDC99: CLK_GNUC99);
flag_no_asm = iso;
flag_no_nonansi_builtin = iso;
- flag_noniso_default_format_attributes = !iso;
flag_iso = iso;
flag_isoc99 = 1;
flag_isoc94 = 1;
@@ -1623,20 +1533,17 @@ set_std_c99 (iso)
/* Set the C++ 98 standard (without GNU extensions if ISO). */
static void
-set_std_cxx98 (iso)
- int iso;
+set_std_cxx98 (int iso)
{
cpp_set_lang (parse_in, iso ? CLK_CXX98: CLK_GNUCXX);
flag_no_gnu_keywords = iso;
flag_no_nonansi_builtin = iso;
- flag_noniso_default_format_attributes = !iso;
flag_iso = iso;
}
/* Handle setting implicit to ON. */
static void
-set_Wimplicit (on)
- int on;
+set_Wimplicit (int on)
{
warn_implicit = on;
warn_implicit_int = on;
@@ -1652,148 +1559,21 @@ set_Wimplicit (on)
/* Args to -d specify what to dump. Silently ignore
unrecognized options; they may be aimed at toplev.c. */
static void
-handle_OPT_d (arg)
- const char *arg;
+handle_OPT_d (const char *arg)
{
char c;
while ((c = *arg++) != '\0')
switch (c)
{
- case 'M':
- cpp_opts->dump_macros = dump_only;
- break;
-
- case 'N':
- cpp_opts->dump_macros = dump_names;
- break;
-
- case 'D':
- cpp_opts->dump_macros = dump_definitions;
+ case 'M': /* Dump macros only. */
+ case 'N': /* Dump names. */
+ case 'D': /* Dump definitions. */
+ flag_dump_macros = c;
break;
case 'I':
- cpp_opts->dump_includes = 1;
+ flag_dump_includes = 1;
break;
}
}
-
-/* Write a slash-separated list of languages in FLAGS to BUF. */
-static void
-write_langs (buf, flags)
- char *buf;
- int flags;
-{
- *buf = '\0';
- if (flags & CL_C_ONLY)
- strcat (buf, "C");
- if (flags & CL_OBJC_ONLY)
- {
- if (*buf)
- strcat (buf, "/");
- strcat (buf, "ObjC");
- }
- if (flags & CL_CXX_ONLY)
- {
- if (*buf)
- strcat (buf, "/");
- strcat (buf, "C++");
- }
-}
-
-/* Complain that switch OPT_INDEX does not apply to this front end. */
-static void
-complain_wrong_lang (opt_index, on)
- size_t opt_index;
- int on;
-{
- char ok_langs[60], bad_langs[60];
- int ok_flags = cl_options[opt_index].flags;
-
- write_langs (ok_langs, ok_flags);
- write_langs (bad_langs, ~ok_flags);
- warning ("\"-%c%s%s\" is valid for %s but not for %s",
- cl_options[opt_index].opt_text[0], on ? "" : "no-",
- cl_options[opt_index].opt_text + 1, ok_langs, bad_langs);
-}
-
-/* Handle --help output. */
-static void
-print_help ()
-{
- /* To keep the lines from getting too long for some compilers, limit
- to about 500 characters (6 lines) per chunk. */
- fputs (_("\
-Switches:\n\
- -include <file> Include the contents of <file> before other files\n\
- -imacros <file> Accept definition of macros in <file>\n\
- -iprefix <path> Specify <path> as a prefix for next two options\n\
- -iwithprefix <dir> Add <dir> to the end of the system include path\n\
- -iwithprefixbefore <dir> Add <dir> to the end of the main include path\n\
- -isystem <dir> Add <dir> to the start of the system include path\n\
-"), stdout);
- fputs (_("\
- -idirafter <dir> Add <dir> to the end of the system include path\n\
- -I <dir> Add <dir> to the end of the main include path\n\
- -I- Fine-grained include path control; see info docs\n\
- -nostdinc Do not search system include directories\n\
- (dirs specified with -isystem will still be used)\n\
- -nostdinc++ Do not search system include directories for C++\n\
- -o <file> Put output into <file>\n\
-"), stdout);
- fputs (_("\
- -trigraphs Support ISO C trigraphs\n\
- -std=<std name> Specify the conformance standard; one of:\n\
- gnu89, gnu99, c89, c99, iso9899:1990,\n\
- iso9899:199409, iso9899:1999, c++98\n\
- -w Inhibit warning messages\n\
- -W[no-]trigraphs Warn if trigraphs are encountered\n\
- -W[no-]comment{s} Warn if one comment starts inside another\n\
-"), stdout);
- fputs (_("\
- -W[no-]traditional Warn about features not present in traditional C\n\
- -W[no-]undef Warn if an undefined macro is used by #if\n\
- -W[no-]import Warn about the use of the #import directive\n\
-"), stdout);
- fputs (_("\
- -W[no-]error Treat all warnings as errors\n\
- -W[no-]system-headers Do not suppress warnings from system headers\n\
- -W[no-]all Enable most preprocessor warnings\n\
-"), stdout);
- fputs (_("\
- -M Generate make dependencies\n\
- -MM As -M, but ignore system header files\n\
- -MD Generate make dependencies and compile\n\
- -MMD As -MD, but ignore system header files\n\
- -MF <file> Write dependency output to the given file\n\
- -MG Treat missing header file as generated files\n\
-"), stdout);
- fputs (_("\
- -MP Generate phony targets for all headers\n\
- -MQ <target> Add a MAKE-quoted target\n\
- -MT <target> Add an unquoted target\n\
-"), stdout);
- fputs (_("\
- -D<macro> Define a <macro> with string '1' as its value\n\
- -D<macro>=<val> Define a <macro> with <val> as its value\n\
- -A<question>=<answer> Assert the <answer> to <question>\n\
- -A-<question>=<answer> Disable the <answer> to <question>\n\
- -U<macro> Undefine <macro> \n\
- -v Display the version number\n\
-"), stdout);
- fputs (_("\
- -H Print the name of header files as they are used\n\
- -C Do not discard comments\n\
- -dM Display a list of macro definitions active at end\n\
- -dD Preserve macro definitions in output\n\
- -dN As -dD except that only the names are preserved\n\
- -dI Include #include directives in the output\n\
-"), stdout);
- fputs (_("\
- -f[no-]preprocessed Treat the input file as already preprocessed\n\
- -ftabstop=<number> Distance between tab stops for column reporting\n\
- -P Do not generate #line directives\n\
- -remap Remap file names when including files\n\
- --help Display this information\n\
-"), stdout);
-}
diff --git a/contrib/gcc/c-parse.in b/contrib/gcc/c-parse.in
index 59e399bc3b40..f03526607bd6 100644
--- a/contrib/gcc/c-parse.in
+++ b/contrib/gcc/c-parse.in
@@ -1,6 +1,6 @@
/* YACC parser for C syntax and for Objective C. -*-c-*-
- Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,21 +20,23 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* This file defines the grammar of C and that of Objective C.
- ifobjc ... end ifobjc conditionals contain code for Objective C only.
- ifc ... end ifc conditionals contain code for C only.
+ @@ifobjc ... @@end_ifobjc conditionals contain code for Objective C only.
+ @@ifc ... @@end_ifc conditionals contain code for C only.
Sed commands in Makefile.in are used to convert this file into
c-parse.y and into objc-parse.y. */
/* To whomever it may concern: I have heard that such a thing was once
written by AT&T, but I have never seen it. */
-ifc
+@@ifc
%expect 10 /* shift/reduce conflicts, and no reduce/reduce conflicts. */
-end ifc
+@@end_ifc
%{
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "input.h"
#include "cpplib.h"
@@ -43,17 +45,14 @@ end ifc
#include "c-pragma.h" /* For YYDEBUG definition, and parse_in. */
#include "c-tree.h"
#include "flags.h"
+#include "varray.h"
#include "output.h"
#include "toplev.h"
#include "ggc.h"
-#ifdef MULTIBYTE_CHARS
-#include <locale.h>
-#endif
-
-ifobjc
+@@ifobjc
#include "objc-act.h"
-end ifobjc
+@@end_ifobjc
/* Like YYERROR but do call yyerror. */
#define YYERROR1 { yyerror ("syntax error"); YYERROR; }
@@ -76,15 +75,13 @@ do { \
newsize = *(YYSSZ) *= 2; \
if (malloced_yyss) \
{ \
- newss = (short *) \
- really_call_realloc (*(SS), newsize * sizeof (short)); \
- newvs = (YYSTYPE *) \
- really_call_realloc (*(VS), newsize * sizeof (YYSTYPE)); \
+ newss = really_call_realloc (*(SS), newsize * sizeof (short)); \
+ newvs = really_call_realloc (*(VS), newsize * sizeof (YYSTYPE)); \
} \
else \
{ \
- newss = (short *) really_call_malloc (newsize * sizeof (short)); \
- newvs = (YYSTYPE *) really_call_malloc (newsize * sizeof (YYSTYPE)); \
+ newss = really_call_malloc (newsize * sizeof (short)); \
+ newvs = really_call_malloc (newsize * sizeof (YYSTYPE)); \
if (newss) \
memcpy (newss, *(SS), (SSSIZE)); \
if (newvs) \
@@ -105,7 +102,7 @@ do { \
%start program
%union {long itype; tree ttype; enum tree_code code;
- const char *filename; int lineno; }
+ location_t location; }
/* All identifiers that are not reserved words
and are not declared typedefs in the current block */
@@ -135,6 +132,7 @@ do { \
/* String constants in raw form.
yylval is a STRING_CST node. */
+
%token STRING
/* "...", used for functions with variable arglists. */
@@ -147,9 +145,7 @@ do { \
%token ATTRIBUTE EXTENSION LABEL
%token REALPART IMAGPART VA_ARG CHOOSE_EXPR TYPES_COMPATIBLE_P
%token PTR_VALUE PTR_BASE PTR_EXTENT
-
-/* function name can be a string const or a var decl. */
-%token STRING_FUNC_NAME VAR_FUNC_NAME
+%token FUNC_NAME
/* Add precedence rules to solve dangling else s/r conflict */
%nonassoc IF
@@ -179,6 +175,8 @@ do { \
Objective C, so that the token codes are the same in both. */
%token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
%token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS
+%token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED
+%token OBJC_STRING
%type <code> unop
%type <ttype> ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
@@ -206,7 +204,7 @@ do { \
%type <ttype> init maybeasm
%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
%type <ttype> maybe_attribute attributes attribute attribute_list attrib
-%type <ttype> any_word extension
+%type <ttype> any_word
%type <ttype> compstmt compstmt_start compstmt_nostart compstmt_primary_start
%type <ttype> do_stmt_start poplevel stmt label
@@ -232,12 +230,11 @@ do { \
%type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1
%type <ttype> identifiers_or_typenames
-%type <itype> setspecs setspecs_fp
+%type <itype> setspecs setspecs_fp extension
-%type <filename> save_filename
-%type <lineno> save_lineno
+%type <location> save_location
-ifobjc
+@@ifobjc
/* the Objective-C nonterminals */
%type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator
@@ -246,10 +243,13 @@ ifobjc
%type <ttype> keywordexpr keywordarglist keywordarg
%type <ttype> myparms myparm optparmlist reservedwords objcselectorexpr
%type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
-%type <ttype> objc_string non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr
+%type <ttype> non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr
-%type <ttype> CLASSNAME OBJECTNAME
-end ifobjc
+%type <ttype> CLASSNAME OBJECTNAME OBJC_STRING
+
+%type <ttype> superclass
+%type <itype> objc_try_catch_stmt objc_finally_block
+@@end_ifobjc
%{
/* Number of statements (loosely speaking) and compound statements
@@ -257,10 +257,10 @@ end ifobjc
static int stmt_count;
static int compstmt_count;
-/* Input file and line number of the end of the body of last simple_if;
+/* Input location of the end of the body of last simple_if;
used by the stmt-rule immediately after simple_if returns. */
-static const char *if_stmt_file;
-static int if_stmt_line;
+static location_t if_stmt_locus;
+
/* List of types and structure classes of the current declaration. */
static GTY(()) tree current_declspecs;
@@ -295,22 +295,21 @@ static GTY(()) tree declspec_stack;
/* For __extension__, save/restore the warning flags which are
controlled by __extension__. */
-#define SAVE_EXT_FLAGS() \
- size_int (pedantic \
- | (warn_pointer_arith << 1) \
- | (warn_traditional << 2) \
- | (flag_iso << 3))
+#define SAVE_EXT_FLAGS() \
+ (pedantic \
+ | (warn_pointer_arith << 1) \
+ | (warn_traditional << 2) \
+ | (flag_iso << 3))
-#define RESTORE_EXT_FLAGS(tval) \
+#define RESTORE_EXT_FLAGS(val) \
do { \
- int val = tree_low_cst (tval, 0); \
pedantic = val & 1; \
warn_pointer_arith = (val >> 1) & 1; \
warn_traditional = (val >> 2) & 1; \
flag_iso = (val >> 3) & 1; \
} while (0)
-ifobjc
+@@ifobjc
/* Objective-C specific parser/lexer information */
static enum tree_code objc_inherit_code;
@@ -322,11 +321,11 @@ static int objc_pq_context = 0, objc_public_flag = 0;
exists. */
static int objc_need_raw_identifier;
#define OBJC_NEED_RAW_IDENTIFIER(VAL) objc_need_raw_identifier = VAL
-end ifobjc
+@@end_ifobjc
-ifc
+@@ifc
#define OBJC_NEED_RAW_IDENTIFIER(VAL) /* nothing */
-end ifc
+@@end_ifc
static bool parsing_iso_function_signature;
@@ -334,17 +333,16 @@ static bool parsing_iso_function_signature;
#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
-static void yyprint PARAMS ((FILE *, int, YYSTYPE));
-static void yyerror PARAMS ((const char *));
-static int yylexname PARAMS ((void));
-static int yylexstring PARAMS ((void));
-static inline int _yylex PARAMS ((void));
-static int yylex PARAMS ((void));
-static void init_reswords PARAMS ((void));
+static void yyprint (FILE *, int, YYSTYPE);
+static void yyerror (const char *);
+static int yylexname (void);
+static inline int _yylex (void);
+static int yylex (void);
+static void init_reswords (void);
/* Initialisation routine for this file. */
void
-c_parse_init ()
+c_parse_init (void)
{
init_reswords ();
}
@@ -355,20 +353,8 @@ c_parse_init ()
program: /* empty */
{ if (pedantic)
pedwarn ("ISO C forbids an empty source file");
- finish_file ();
}
| extdefs
- {
- /* In case there were missing closebraces,
- get us back to the global binding level. */
- while (! global_bindings_p ())
- poplevel (0, 0, 0);
- /* __FUNCTION__ is defined at file scope (""). This
- call may not be necessary as my tests indicate it
- still works without it. */
- finish_fname_decls ();
- finish_file ();
- }
;
/* the reason for the strange actions in this rule
@@ -388,9 +374,9 @@ extdef:
extdef_1:
fndef
| datadef
-ifobjc
+@@ifobjc
| objcdef
-end ifobjc
+@@end_ifobjc
| ASM_KEYWORD '(' expr ')' ';'
{ STRIP_NOPS ($3);
if ((TREE_CODE ($3) == ADDR_EXPR
@@ -430,12 +416,11 @@ fndef:
all_prefix_attributes))
YYERROR1;
}
- old_style_parm_decls
- { store_parm_decls (); }
- save_filename save_lineno compstmt_or_error
- { DECL_SOURCE_FILE (current_function_decl) = $7;
- DECL_SOURCE_LINE (current_function_decl) = $8;
- finish_function (0, 1);
+ old_style_parm_decls save_location
+ { DECL_SOURCE_LOCATION (current_function_decl) = $6;
+ store_parm_decls (); }
+ compstmt_or_error
+ { finish_function ();
POP_DECLSPEC_STACK; }
| declspecs_ts setspecs declarator error
{ POP_DECLSPEC_STACK; }
@@ -444,12 +429,11 @@ fndef:
all_prefix_attributes))
YYERROR1;
}
- old_style_parm_decls
- { store_parm_decls (); }
- save_filename save_lineno compstmt_or_error
- { DECL_SOURCE_FILE (current_function_decl) = $7;
- DECL_SOURCE_LINE (current_function_decl) = $8;
- finish_function (0, 1);
+ old_style_parm_decls save_location
+ { DECL_SOURCE_LOCATION (current_function_decl) = $6;
+ store_parm_decls (); }
+ compstmt_or_error
+ { finish_function ();
POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_declarator error
{ POP_DECLSPEC_STACK; }
@@ -458,12 +442,11 @@ fndef:
all_prefix_attributes))
YYERROR1;
}
- old_style_parm_decls
- { store_parm_decls (); }
- save_filename save_lineno compstmt_or_error
- { DECL_SOURCE_FILE (current_function_decl) = $6;
- DECL_SOURCE_LINE (current_function_decl) = $7;
- finish_function (0, 1);
+ old_style_parm_decls save_location
+ { DECL_SOURCE_LOCATION (current_function_decl) = $5;
+ store_parm_decls (); }
+ compstmt_or_error
+ { finish_function ();
POP_DECLSPEC_STACK; }
| setspecs notype_declarator error
{ POP_DECLSPEC_STACK; }
@@ -472,10 +455,10 @@ fndef:
identifier:
IDENTIFIER
| TYPENAME
-ifobjc
+@@ifobjc
| OBJECTNAME
| CLASSNAME
-end ifobjc
+@@end_ifobjc
;
unop: '&'
@@ -484,10 +467,10 @@ unop: '&'
{ $$ = NEGATE_EXPR; }
| '+'
{ $$ = CONVERT_EXPR;
-ifc
+@@ifc
if (warn_traditional && !in_system_header)
warning ("traditional C rejects the unary plus operator");
-end ifc
+@@end_ifc
}
| PLUSPLUS
{ $$ = PREINCREMENT_EXPR; }
@@ -598,26 +581,26 @@ expr_no_commas:
| expr_no_commas ANDAND
{ $1 = c_common_truthvalue_conversion
(default_conversion ($1));
- skip_evaluation += $1 == boolean_false_node; }
+ skip_evaluation += $1 == truthvalue_false_node; }
expr_no_commas
- { skip_evaluation -= $1 == boolean_false_node;
+ { skip_evaluation -= $1 == truthvalue_false_node;
$$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $4); }
| expr_no_commas OROR
{ $1 = c_common_truthvalue_conversion
(default_conversion ($1));
- skip_evaluation += $1 == boolean_true_node; }
+ skip_evaluation += $1 == truthvalue_true_node; }
expr_no_commas
- { skip_evaluation -= $1 == boolean_true_node;
+ { skip_evaluation -= $1 == truthvalue_true_node;
$$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $4); }
| expr_no_commas '?'
{ $1 = c_common_truthvalue_conversion
(default_conversion ($1));
- skip_evaluation += $1 == boolean_false_node; }
+ skip_evaluation += $1 == truthvalue_false_node; }
expr ':'
- { skip_evaluation += (($1 == boolean_true_node)
- - ($1 == boolean_false_node)); }
+ { skip_evaluation += (($1 == truthvalue_true_node)
+ - ($1 == truthvalue_false_node)); }
expr_no_commas
- { skip_evaluation -= $1 == boolean_true_node;
+ { skip_evaluation -= $1 == truthvalue_true_node;
$$ = build_conditional_expr ($1, $4, $7); }
| expr_no_commas '?'
{ if (pedantic)
@@ -626,9 +609,9 @@ expr_no_commas:
$<ttype>2 = save_expr ($1);
$1 = c_common_truthvalue_conversion
(default_conversion ($<ttype>2));
- skip_evaluation += $1 == boolean_true_node; }
+ skip_evaluation += $1 == truthvalue_true_node; }
':' expr_no_commas
- { skip_evaluation -= $1 == boolean_true_node;
+ { skip_evaluation -= $1 == truthvalue_true_node;
$$ = build_conditional_expr ($1, $<ttype>2, $5); }
| expr_no_commas '=' expr_no_commas
{ char class;
@@ -657,8 +640,7 @@ primary:
}
| CONSTANT
| STRING
- { $$ = fix_string_type ($$); }
- | VAR_FUNC_NAME
+ | FUNC_NAME
{ $$ = fname_decl (C_RID_CODE ($$), $$); }
| '(' typename ')' '{'
{ start_init (NULL_TREE, NULL, 0);
@@ -670,7 +652,7 @@ primary:
finish_init ();
if (pedantic && ! flag_isoc99)
- pedwarn ("ISO C89 forbids compound literals");
+ pedwarn ("ISO C90 forbids compound literals");
$$ = build_compound_literal (type, constructor);
}
| '(' expr ')'
@@ -685,8 +667,6 @@ primary:
if (pedantic)
pedwarn ("ISO C forbids braced-groups within expressions");
- pop_label_level ();
-
saved_last_tree = COMPOUND_BODY ($1);
RECHAIN_STMTS ($1, COMPOUND_BODY ($1));
last_tree = saved_last_tree;
@@ -698,7 +678,6 @@ primary:
}
| compstmt_primary_start error ')'
{
- pop_label_level ();
last_tree = COMPOUND_BODY ($1);
TREE_CHAIN (last_tree) = NULL_TREE;
$$ = error_mark_node;
@@ -725,36 +704,36 @@ primary:
e1 = TYPE_MAIN_VARIANT (groktypename ($3));
e2 = TYPE_MAIN_VARIANT (groktypename ($5));
- $$ = comptypes (e1, e2)
+ $$ = comptypes (e1, e2, COMPARE_STRICT)
? build_int_2 (1, 0) : build_int_2 (0, 0);
}
| primary '[' expr ']' %prec '.'
{ $$ = build_array_ref ($1, $3); }
| primary '.' identifier
{
-ifobjc
+@@ifobjc
if (!is_public ($1, $3))
$$ = error_mark_node;
else
-end ifobjc
+@@end_ifobjc
$$ = build_component_ref ($1, $3);
}
| primary POINTSAT identifier
{
tree expr = build_indirect_ref ($1, "->");
-ifobjc
+@@ifobjc
if (!is_public (expr, $3))
$$ = error_mark_node;
else
-end ifobjc
+@@end_ifobjc
$$ = build_component_ref (expr, $3);
}
| primary PLUSPLUS
{ $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
| primary MINUSMINUS
{ $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
-ifobjc
+@@ifobjc
| objcmessageexpr
{ $$ = build_message_expr ($1); }
| objcselectorexpr
@@ -763,22 +742,11 @@ ifobjc
{ $$ = build_protocol_expr ($1); }
| objcencodeexpr
{ $$ = build_encode_expr ($1); }
- | objc_string
+ | OBJC_STRING
{ $$ = build_objc_string_object ($1); }
-end ifobjc
+@@end_ifobjc
;
-ifobjc
-/* Produces an STRING_CST with perhaps more STRING_CSTs chained
- onto it, which is to be read as an ObjC string object. */
-objc_string:
- '@' STRING
- { $$ = $2; }
- | objc_string '@' STRING
- { $$ = chainon ($1, $3); }
- ;
-end ifobjc
-
old_style_parm_decls:
old_style_parm_decls_1
{
@@ -792,16 +760,23 @@ old_style_parm_decls_1:
if (warn_traditional && !in_system_header
&& parsing_iso_function_signature)
warning ("traditional C rejects ISO C style function definitions");
+ if (warn_old_style_definition && !in_system_header
+ && !parsing_iso_function_signature)
+ warning ("old-style parameter declaration");
parsing_iso_function_signature = false; /* Reset after warning. */
}
| datadecls
+ {
+ if (warn_old_style_definition && !in_system_header)
+ warning ("old-style parameter declaration");
+ }
;
/* The following are analogous to lineno_decl, decls and decl
except that they do not allow nested functions.
They are used for old-style parm decls. */
lineno_datadecl:
- save_filename save_lineno datadecl
+ save_location datadecl
{ }
;
@@ -833,7 +808,7 @@ datadecl:
This is to avoid shift/reduce conflicts in contexts
where statement labels are allowed. */
lineno_decl:
- save_filename save_lineno decl
+ save_location decl
{ }
;
@@ -1384,7 +1359,7 @@ typespec_nonreserved_nonattr:
{ /* For a typedef name, record the meaning, not the name.
In case of `foo foo, bar;'. */
$$ = lookup_name ($1); }
-ifobjc
+@@ifobjc
| CLASSNAME protocolrefs
{ $$ = get_static_reference ($1, $2); }
| OBJECTNAME protocolrefs
@@ -1394,9 +1369,13 @@ ifobjc
- nisse@lysator.liu.se */
| non_empty_protocolrefs
{ $$ = get_object_reference ($1); }
-end ifobjc
+@@end_ifobjc
| typeof '(' expr ')'
- { skip_evaluation--; $$ = TREE_TYPE ($3); }
+ { skip_evaluation--;
+ if (TREE_CODE ($3) == COMPONENT_REF
+ && DECL_C_BIT_FIELD (TREE_OPERAND ($3, 1)))
+ error ("`typeof' applied to a bit-field");
+ $$ = TREE_TYPE ($3); }
| typeof '(' typename ')'
{ skip_evaluation--; $$ = groktypename ($3); }
;
@@ -1454,7 +1433,7 @@ notype_initdcl:
so that the header files compile. */
maybe_attribute:
/* empty */
- { $$ = NULL_TREE; }
+ { $$ = NULL_TREE; }
| attributes
{ $$ = $1; }
;
@@ -1536,7 +1515,7 @@ initlist1:
initelt:
designator_list '=' initval
{ if (pedantic && ! flag_isoc99)
- pedwarn ("ISO C89 forbids specifying subobject to initialize"); }
+ pedwarn ("ISO C90 forbids specifying subobject to initialize"); }
| designator initval
{ if (pedantic)
pedwarn ("obsolete use of designated initializer without `='"); }
@@ -1589,19 +1568,19 @@ nested_function:
}
parsing_iso_function_signature = false; /* Don't warn about nested functions. */
}
- old_style_parm_decls
- { store_parm_decls (); }
+ old_style_parm_decls save_location
+ { tree decl = current_function_decl;
+ DECL_SOURCE_LOCATION (decl) = $4;
+ store_parm_decls (); }
/* This used to use compstmt_or_error.
That caused a bug with input `f(g) int g {}',
where the use of YYERROR1 above caused an error
which then was handled by compstmt_or_error.
There followed a repeated execution of that same rule,
which called YYERROR1 again, and so on. */
- save_filename save_lineno compstmt
+ compstmt
{ tree decl = current_function_decl;
- DECL_SOURCE_FILE (decl) = $5;
- DECL_SOURCE_LINE (decl) = $6;
- finish_function (1, 1);
+ finish_function ();
pop_function_context ();
add_decl_stmt (decl); }
;
@@ -1620,19 +1599,19 @@ notype_nested_function:
}
parsing_iso_function_signature = false; /* Don't warn about nested functions. */
}
- old_style_parm_decls
- { store_parm_decls (); }
+ old_style_parm_decls save_location
+ { tree decl = current_function_decl;
+ DECL_SOURCE_LOCATION (decl) = $4;
+ store_parm_decls (); }
/* This used to use compstmt_or_error.
That caused a bug with input `f(g) int g {}',
where the use of YYERROR1 above caused an error
which then was handled by compstmt_or_error.
There followed a repeated execution of that same rule,
which called YYERROR1 again, and so on. */
- save_filename save_lineno compstmt
+ compstmt
{ tree decl = current_function_decl;
- DECL_SOURCE_FILE (decl) = $5;
- DECL_SOURCE_LINE (decl) = $6;
- finish_function (1, 1);
+ finish_function ();
pop_function_context ();
add_decl_stmt (decl); }
;
@@ -1660,9 +1639,9 @@ after_type_declarator:
| '*' maybe_type_quals_attrs after_type_declarator %prec UNARY
{ $$ = make_pointer_declarator ($2, $3); }
| TYPENAME
-ifobjc
+@@ifobjc
| OBJECTNAME
-end ifobjc
+@@end_ifobjc
;
/* Kinds of declarator that can appear in a parameter list
@@ -1683,9 +1662,9 @@ parm_declarator_starttypename:
| parm_declarator_starttypename array_declarator %prec '.'
{ $$ = set_array_declarator_type ($2, $1, 0); }
| TYPENAME
-ifobjc
+@@ifobjc
| OBJECTNAME
-end ifobjc
+@@end_ifobjc
;
parm_declarator_nostarttypename:
@@ -1755,18 +1734,20 @@ structsp_attr:
/* Start scope of tag before parsing components. */
}
component_decl_list '}' maybe_attribute
- { $$ = finish_struct ($<ttype>4, $5, chainon ($1, $7)); }
+ { $$ = finish_struct ($<ttype>4, nreverse ($5),
+ chainon ($1, $7)); }
| struct_head '{' component_decl_list '}' maybe_attribute
{ $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE),
- $3, chainon ($1, $5));
+ nreverse ($3), chainon ($1, $5));
}
| union_head identifier '{'
{ $$ = start_struct (UNION_TYPE, $2); }
component_decl_list '}' maybe_attribute
- { $$ = finish_struct ($<ttype>4, $5, chainon ($1, $7)); }
+ { $$ = finish_struct ($<ttype>4, nreverse ($5),
+ chainon ($1, $7)); }
| union_head '{' component_decl_list '}' maybe_attribute
{ $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE),
- $3, chainon ($1, $5));
+ nreverse ($3), chainon ($1, $5));
}
| enum_head identifier '{'
{ $$ = start_enum ($2); }
@@ -1805,44 +1786,45 @@ maybecomma_warn:
pedwarn ("comma at end of enumerator list"); }
;
+/* We chain the components in reverse order. They are put in forward
+ order in structsp_attr.
+
+ Note that component_declarator returns single decls, so components
+ and components_notype can use TREE_CHAIN directly, wheras components
+ and components_notype return lists (of comma separated decls), so
+ component_decl_list and component_decl_list2 must use chainon.
+
+ The theory behind all this is that there will be more semicolon
+ separated fields than comma separated fields, and so we'll be
+ minimizing the number of node traversals required by chainon. */
+
component_decl_list:
component_decl_list2
{ $$ = $1; }
| component_decl_list2 component_decl
- { $$ = chainon ($1, $2);
+ { $$ = chainon ($2, $1);
pedwarn ("no semicolon at end of struct or union"); }
;
component_decl_list2: /* empty */
{ $$ = NULL_TREE; }
| component_decl_list2 component_decl ';'
- { $$ = chainon ($1, $2); }
+ { $$ = chainon ($2, $1); }
| component_decl_list2 ';'
{ if (pedantic)
pedwarn ("extra semicolon in struct or union specified"); }
-ifobjc
+@@ifobjc
/* foo(sizeof(struct{ @defs(ClassName)})); */
| DEFS '(' CLASSNAME ')'
- {
- tree interface = lookup_interface ($3);
-
- if (interface)
- $$ = get_class_ivars (interface);
- else
- {
- error ("cannot find interface declaration for `%s'",
- IDENTIFIER_POINTER ($3));
- $$ = NULL_TREE;
- }
- }
-end ifobjc
+ { $$ = nreverse (get_class_ivars_from_name ($3)); }
+@@end_ifobjc
;
component_decl:
declspecs_nosc_ts setspecs components
{ $$ = $3;
POP_DECLSPEC_STACK; }
- | declspecs_nosc_ts setspecs save_filename save_lineno
+ | declspecs_nosc_ts setspecs
{
/* Support for unnamed structs or unions as members of
structs or unions (which is [a] useful and [b] supports
@@ -1850,7 +1832,7 @@ component_decl:
if (pedantic)
pedwarn ("ISO C doesn't support unnamed structs/unions");
- $$ = grokfield($3, $4, NULL, current_declspecs, NULL_TREE);
+ $$ = grokfield(NULL, current_declspecs, NULL_TREE);
POP_DECLSPEC_STACK; }
| declspecs_nosc_nots setspecs components_notype
{ $$ = $3;
@@ -1858,7 +1840,7 @@ component_decl:
| declspecs_nosc_nots
{ if (pedantic)
pedwarn ("ISO C forbids member declarations with no members");
- shadow_tag($1);
+ shadow_tag_warned ($1, pedantic);
$$ = NULL_TREE; }
| error
{ $$ = NULL_TREE; }
@@ -1870,45 +1852,47 @@ component_decl:
components:
component_declarator
| components ',' maybe_resetattrs component_declarator
- { $$ = chainon ($1, $4); }
+ { TREE_CHAIN ($4) = $1; $$ = $4; }
;
components_notype:
component_notype_declarator
| components_notype ',' maybe_resetattrs component_notype_declarator
- { $$ = chainon ($1, $4); }
+ { TREE_CHAIN ($4) = $1; $$ = $4; }
;
component_declarator:
- save_filename save_lineno declarator maybe_attribute
- { $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
- decl_attributes (&$$, chainon ($4, all_prefix_attributes), 0); }
- | save_filename save_lineno
- declarator ':' expr_no_commas maybe_attribute
- { $$ = grokfield ($1, $2, $3, current_declspecs, $5);
- decl_attributes (&$$, chainon ($6, all_prefix_attributes), 0); }
- | save_filename save_lineno ':' expr_no_commas maybe_attribute
- { $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4);
- decl_attributes (&$$, chainon ($5, all_prefix_attributes), 0); }
+ declarator maybe_attribute
+ { $$ = grokfield ($1, current_declspecs, NULL_TREE);
+ decl_attributes (&$$,
+ chainon ($2, all_prefix_attributes), 0); }
+ | declarator ':' expr_no_commas maybe_attribute
+ { $$ = grokfield ($1, current_declspecs, $3);
+ decl_attributes (&$$,
+ chainon ($4, all_prefix_attributes), 0); }
+ | ':' expr_no_commas maybe_attribute
+ { $$ = grokfield (NULL_TREE, current_declspecs, $2);
+ decl_attributes (&$$,
+ chainon ($3, all_prefix_attributes), 0); }
;
component_notype_declarator:
- save_filename save_lineno notype_declarator maybe_attribute
- { $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
- decl_attributes (&$$, chainon ($4, all_prefix_attributes), 0); }
- | save_filename save_lineno
- notype_declarator ':' expr_no_commas maybe_attribute
- { $$ = grokfield ($1, $2, $3, current_declspecs, $5);
- decl_attributes (&$$, chainon ($6, all_prefix_attributes), 0); }
- | save_filename save_lineno ':' expr_no_commas maybe_attribute
- { $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4);
- decl_attributes (&$$, chainon ($5, all_prefix_attributes), 0); }
+ notype_declarator maybe_attribute
+ { $$ = grokfield ($1, current_declspecs, NULL_TREE);
+ decl_attributes (&$$,
+ chainon ($2, all_prefix_attributes), 0); }
+ | notype_declarator ':' expr_no_commas maybe_attribute
+ { $$ = grokfield ($1, current_declspecs, $3);
+ decl_attributes (&$$,
+ chainon ($4, all_prefix_attributes), 0); }
+ | ':' expr_no_commas maybe_attribute
+ { $$ = grokfield (NULL_TREE, current_declspecs, $2);
+ decl_attributes (&$$,
+ chainon ($3, all_prefix_attributes), 0); }
;
/* We chain the enumerators in reverse order.
- They are put in forward order where enumlist is used.
- (The order used to be significant, but no longer is so.
- However, we still maintain the order, just to be clean.) */
+ They are put in forward order in structsp_attr. */
enumlist:
enumerator
@@ -1916,7 +1900,7 @@ enumlist:
{ if ($1 == error_mark_node)
$$ = $1;
else
- $$ = chainon ($3, $1); }
+ TREE_CHAIN ($3) = $1, $$ = $3; }
| error
{ $$ = error_mark_node; }
;
@@ -1992,16 +1976,16 @@ direct_absdcl1:
/* The [...] part of a declarator for an array type. */
array_declarator:
- '[' maybe_type_quals_attrs expr ']'
+ '[' maybe_type_quals_attrs expr_no_commas ']'
{ $$ = build_array_declarator ($3, $2, 0, 0); }
| '[' maybe_type_quals_attrs ']'
{ $$ = build_array_declarator (NULL_TREE, $2, 0, 0); }
| '[' maybe_type_quals_attrs '*' ']'
{ $$ = build_array_declarator (NULL_TREE, $2, 0, 1); }
- | '[' STATIC maybe_type_quals_attrs expr ']'
+ | '[' STATIC maybe_type_quals_attrs expr_no_commas ']'
{ $$ = build_array_declarator ($4, $3, 1, 0); }
/* declspecs_nosc_nots is a synonym for type_quals_attrs. */
- | '[' declspecs_nosc_nots STATIC expr ']'
+ | '[' declspecs_nosc_nots STATIC expr_no_commas ']'
{ $$ = build_array_declarator ($4, $2, 1, 0); }
;
@@ -2016,7 +2000,7 @@ stmts_and_decls:
| lineno_stmt_decl_or_labels_ending_decl
| lineno_stmt_decl_or_labels_ending_label
{
- pedwarn ("deprecated use of label at end of compound statement");
+ error ("label at end of compound statement");
}
| lineno_stmt_decl_or_labels_ending_error
;
@@ -2032,8 +2016,11 @@ lineno_stmt_decl_or_labels_ending_stmt:
lineno_stmt_decl_or_labels_ending_decl:
lineno_decl
| lineno_stmt_decl_or_labels_ending_stmt lineno_decl
- { if (pedantic && !flag_isoc99)
- pedwarn ("ISO C89 forbids mixed declarations and code"); }
+ {
+ if ((pedantic && !flag_isoc99)
+ || warn_declaration_after_statement)
+ pedwarn_c90 ("ISO C90 forbids mixed declarations and code");
+ }
| lineno_stmt_decl_or_labels_ending_decl lineno_decl
| lineno_stmt_decl_or_labels_ending_error lineno_decl
;
@@ -2065,15 +2052,17 @@ pushlevel: /* empty */
{ pushlevel (0);
clear_last_expr ();
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
-ifobjc
- if (objc_method_context)
- add_objc_decls ();
-end ifobjc
}
;
poplevel: /* empty */
- { $$ = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); }
+ {
+@@ifobjc
+ if (c_dialect_objc ())
+ objc_clear_super_receiver ();
+@@end_ifobjc
+ $$ = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
+ }
;
/* Start and end blocks created for the new scopes of C99. */
@@ -2084,10 +2073,6 @@ c99_block_start: /* empty */
pushlevel (0);
clear_last_expr ();
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
-ifobjc
- if (objc_method_context)
- add_objc_decls ();
-end ifobjc
}
else
$$ = NULL_TREE;
@@ -2101,7 +2086,7 @@ c99_block_end: /* empty */
{ if (flag_isoc99)
{
tree scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
- $$ = poplevel (kept_level_p (), 0, 0);
+ $$ = poplevel (KEEP_MAYBE, 0, 0);
SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
= SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
= $$;
@@ -2129,7 +2114,7 @@ label_decl:
{ tree link;
for (link = $2; link; link = TREE_CHAIN (link))
{
- tree label = shadow_label (TREE_VALUE (link));
+ tree label = declare_label (TREE_VALUE (link));
C_DECLARED_LABEL_FLAG (label) = 1;
add_decl_stmt (label);
}
@@ -2151,7 +2136,7 @@ compstmt_start: '{' { compstmt_count++;
compstmt_nostart: '}'
{ $$ = convert (void_type_node, integer_zero_node); }
| pushlevel maybe_label_decls compstmt_contents_nonempty '}' poplevel
- { $$ = poplevel (kept_level_p (), 1, 0);
+ { $$ = poplevel (KEEP_MAYBE, 0, 0);
SCOPE_STMT_BLOCK (TREE_PURPOSE ($5))
= SCOPE_STMT_BLOCK (TREE_VALUE ($5))
= $$; }
@@ -2174,9 +2159,9 @@ compstmt_primary_start:
there is a way to turn off the entire subtree of blocks
that are contained in it. */
keep_next_level ();
- push_label_level ();
compstmt_count++;
$$ = add_stmt (build_stmt (COMPOUND_STMT, last_tree));
+ last_expr_type = NULL_TREE;
}
;
@@ -2211,8 +2196,7 @@ if_prefix:
{ c_expand_start_cond (c_common_truthvalue_conversion ($4),
compstmt_count,$<ttype>2);
$<itype>$ = stmt_count;
- if_stmt_file = $<filename>-2;
- if_stmt_line = $<lineno>-1; }
+ if_stmt_locus = $<location>-1; }
;
/* This is a subroutine of stmt.
@@ -2222,6 +2206,7 @@ do_stmt_start:
DO
{ stmt_count++;
compstmt_count++;
+ c_in_iteration_stmt++;
$<ttype>$
= add_stmt (build_stmt (DO_STMT, NULL_TREE,
NULL_TREE));
@@ -2232,22 +2217,18 @@ do_stmt_start:
DO_COND ($<ttype>$) = error_mark_node; }
c99_block_lineno_labeled_stmt WHILE
{ $$ = $<ttype>2;
- RECHAIN_STMTS ($$, DO_BODY ($$)); }
+ RECHAIN_STMTS ($$, DO_BODY ($$));
+ c_in_iteration_stmt--; }
;
/* The forced readahead in here is because we might be at the end of a
line, and the line and file won't be bumped until yylex absorbs the
first token on the next line. */
-save_filename:
- { if (yychar == YYEMPTY)
- yychar = YYLEX;
- $$ = input_filename; }
- ;
-save_lineno:
+save_location:
{ if (yychar == YYEMPTY)
yychar = YYLEX;
- $$ = lineno; }
+ $$ = input_location; }
;
lineno_labeled_stmt:
@@ -2263,10 +2244,10 @@ c99_block_lineno_labeled_stmt:
;
lineno_stmt:
- save_filename save_lineno stmt
- { if ($3)
+ save_location stmt
+ { if ($2)
{
- STMT_LINENO ($3) = $2;
+ STMT_LINENO ($2) = $1.line;
/* ??? We currently have no way of recording
the filename for a statement. This probably
matters little in practice at the moment,
@@ -2277,10 +2258,10 @@ lineno_stmt:
;
lineno_label:
- save_filename save_lineno label
- { if ($3)
+ save_location label
+ { if ($2)
{
- STMT_LINENO ($3) = $2;
+ STMT_LINENO ($2) = $1.line;
}
}
;
@@ -2301,8 +2282,8 @@ select_or_iter_stmt:
else statement. Increment stmt_count so we don't
give a second error if this is a nested `if'. */
if (extra_warnings && stmt_count++ == $<itype>1)
- warning_with_file_and_line (if_stmt_file, if_stmt_line,
- "empty body in an if-statement"); }
+ warning ("%Hempty body in an if-statement",
+ &if_stmt_locus); }
/* Make sure c_expand_end_cond is run once
for each call to c_expand_start_cond.
Otherwise a crash is likely. */
@@ -2320,17 +2301,19 @@ select_or_iter_stmt:
{ stmt_count++;
$<ttype>$ = c_begin_while_stmt (); }
'(' expr ')'
- { $4 = c_common_truthvalue_conversion ($4);
+ { c_in_iteration_stmt++;
+ $4 = c_common_truthvalue_conversion ($4);
c_finish_while_stmt_cond
(c_common_truthvalue_conversion ($4), $<ttype>2);
$<ttype>$ = add_stmt ($<ttype>2); }
c99_block_lineno_labeled_stmt
- { RECHAIN_STMTS ($<ttype>6, WHILE_BODY ($<ttype>6)); }
+ { c_in_iteration_stmt--;
+ RECHAIN_STMTS ($<ttype>6, WHILE_BODY ($<ttype>6)); }
| do_stmt_start
'(' expr ')' ';'
{ DO_COND ($1) = c_common_truthvalue_conversion ($3); }
| do_stmt_start error
- { }
+ { }
| FOR
{ $<ttype>$ = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE,
NULL_TREE, NULL_TREE);
@@ -2343,14 +2326,18 @@ select_or_iter_stmt:
FOR_COND ($<ttype>2)
= c_common_truthvalue_conversion ($6); }
xexpr ')'
- { FOR_EXPR ($<ttype>2) = $9; }
+ { c_in_iteration_stmt++;
+ FOR_EXPR ($<ttype>2) = $9; }
c99_block_lineno_labeled_stmt
- { RECHAIN_STMTS ($<ttype>2, FOR_BODY ($<ttype>2)); }
+ { RECHAIN_STMTS ($<ttype>2, FOR_BODY ($<ttype>2));
+ c_in_iteration_stmt--;}
| SWITCH '(' expr ')'
{ stmt_count++;
- $<ttype>$ = c_start_case ($3); }
+ $<ttype>$ = c_start_case ($3);
+ c_in_case_stmt++; }
c99_block_lineno_labeled_stmt
- { c_finish_case (); }
+ { c_finish_case ();
+ c_in_case_stmt--; }
;
for_init_stmt:
@@ -2373,9 +2360,21 @@ stmt:
$$ = NULL_TREE; }
| BREAK ';'
{ stmt_count++;
+ if (!(c_in_iteration_stmt || c_in_case_stmt))
+ {
+ error ("break statement not within loop or switch");
+ $$ = NULL_TREE;
+ }
+ else
$$ = add_stmt (build_break_stmt ()); }
| CONTINUE ';'
{ stmt_count++;
+ if (!c_in_iteration_stmt)
+ {
+ error ("continue statement not within a loop");
+ $$ = NULL_TREE;
+ }
+ else
$$ = add_stmt (build_continue_stmt ()); }
| RETURN ';'
{ stmt_count++;
@@ -2397,7 +2396,7 @@ stmt:
$$ = build_asm_stmt ($2, $4, $6, $8, NULL_TREE); }
/* This is the case with clobbered registers as well. */
| ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':'
- asm_operands ':' asm_clobbers ')' ';'
+ asm_operands ':' asm_clobbers ')' ';'
{ stmt_count++;
$$ = build_asm_stmt ($2, $4, $6, $8, $10); }
| GOTO identifier ';'
@@ -2420,6 +2419,59 @@ stmt:
$$ = add_stmt (build_stmt (GOTO_STMT, $3)); }
| ';'
{ $$ = NULL_TREE; }
+@@ifobjc
+ | AT_THROW expr ';'
+ { stmt_count++;
+ $$ = objc_build_throw_stmt ($2);
+ }
+ | AT_THROW ';'
+ { stmt_count++;
+ $$ = objc_build_throw_stmt (NULL_TREE);
+ }
+ | objc_try_catch_stmt
+ { objc_build_finally_prologue (); }
+ objc_finally_block
+ { $$ = objc_build_try_catch_finally_stmt ($1, $3); }
+ | AT_SYNCHRONIZED '(' expr ')'
+ { objc_build_synchronized_prologue ($3); }
+ compstmt
+ { $$ = objc_build_synchronized_epilogue (); }
+ ;
+
+objc_try_catch_stmt:
+ objc_try_stmt
+ { objc_build_try_epilogue (1); }
+ objc_catch_list
+ { objc_build_catch_epilogue (); $$ = 1; }
+ | objc_try_stmt
+ { objc_build_try_epilogue (0); $$ = 0; }
+ ;
+
+
+objc_try_stmt:
+ AT_TRY
+ { objc_build_try_prologue (); }
+ compstmt
+ ;
+
+objc_catch_list:
+ objc_catch_list objc_catch_block
+ | objc_catch_block
+ ;
+
+objc_catch_block:
+ AT_CATCH '(' parm ')'
+ { objc_build_catch_stmt ($3); }
+ compstmt
+ { stmt_count++; }
+ ;
+
+objc_finally_block:
+ AT_FINALLY compstmt
+ { $$ = 1; }
+ | /* NULL */
+ { $$ = 0; }
+@@end_ifobjc
;
/* Any kind of label, including jump labels and case labels.
@@ -2435,12 +2487,12 @@ label: CASE expr_no_commas ':'
| DEFAULT ':'
{ stmt_count++;
$$ = do_case (NULL_TREE, NULL_TREE); }
- | identifier save_filename save_lineno ':' maybe_attribute
- { tree label = define_label ($2, $3, $1);
+ | identifier save_location ':' maybe_attribute
+ { tree label = define_label ($2, $1);
stmt_count++;
if (label)
{
- decl_attributes (&label, $5, 0);
+ decl_attributes (&label, $4, 0);
$$ = add_stmt (build_stmt (LABEL_STMT, label));
}
else
@@ -2452,10 +2504,9 @@ label: CASE expr_no_commas ':'
maybe_type_qual:
/* empty */
- { emit_line_note (input_filename, lineno);
- $$ = NULL_TREE; }
+ { $$ = NULL_TREE; }
| TYPE_QUAL
- { emit_line_note (input_filename, lineno); }
+ { }
;
xexpr:
@@ -2501,24 +2552,16 @@ asm_clobbers:
parmlist:
maybe_attribute
{ pushlevel (0);
- clear_parm_order ();
- declare_parm_level (0); }
+ declare_parm_level (); }
parmlist_1
{ $$ = $3;
- parmlist_tags_warning ();
poplevel (0, 0, 0); }
;
parmlist_1:
parmlist_2 ')'
| parms ';'
- { tree parm;
- if (pedantic)
- pedwarn ("ISO C forbids forward parameter declarations");
- /* Mark the forward decls as such. */
- for (parm = getdecls (); parm; parm = TREE_CHAIN (parm))
- TREE_ASM_WRITTEN (parm) = 1;
- clear_parm_order (); }
+ { mark_forward_parm_decls (); }
maybe_attribute
{ /* Dummy action so attributes are in known place
on parser stack. */ }
@@ -2541,13 +2584,16 @@ parmlist_2: /* empty */
tries to verify that BUILT_IN_NEXT_ARG is being used
correctly. */
error ("ISO C requires a named argument before `...'");
+ parsing_iso_function_signature = true;
}
| parms
{ $$ = get_parm_info (1);
parsing_iso_function_signature = true;
}
| parms ',' ELLIPSIS
- { $$ = get_parm_info (0); }
+ { $$ = get_parm_info (0);
+ parsing_iso_function_signature = true;
+ }
;
parms:
@@ -2623,11 +2669,9 @@ setspecs_fp:
parmlist_or_identifiers:
maybe_attribute
{ pushlevel (0);
- clear_parm_order ();
- declare_parm_level (1); }
+ declare_parm_level (); }
parmlist_or_identifiers_1
{ $$ = $3;
- parmlist_tags_warning ();
poplevel (0, 0, 0); }
;
@@ -2674,7 +2718,7 @@ extension:
flag_iso = 0; }
;
-ifobjc
+@@ifobjc
/* Objective-C productions. */
objcdef:
@@ -2718,103 +2762,41 @@ aliasdecl:
}
;
-classdef:
- INTERFACE identifier protocolrefs '{'
- {
- objc_interface_context = objc_ivar_context
- = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3);
- objc_public_flag = 0;
- }
- ivar_decl_list '}'
- {
- continue_class (objc_interface_context);
- }
- methodprotolist
- END
- {
- finish_class (objc_interface_context);
- objc_interface_context = NULL_TREE;
- }
+superclass:
+ ':' identifier { $$ = $2; }
+ | /* NULL */ %prec HYPERUNARY { $$ = NULL_TREE; }
+ ;
- | INTERFACE identifier protocolrefs
- {
- objc_interface_context
- = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3);
- continue_class (objc_interface_context);
- }
- methodprotolist
- END
- {
- finish_class (objc_interface_context);
- objc_interface_context = NULL_TREE;
- }
+class_ivars:
+ '{' ivar_decl_list '}'
+ | /* NULL */
+ ;
- | INTERFACE identifier ':' identifier protocolrefs '{'
+classdef:
+ INTERFACE identifier superclass protocolrefs
{
objc_interface_context = objc_ivar_context
- = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5);
+ = start_class (CLASS_INTERFACE_TYPE, $2, $3, $4);
objc_public_flag = 0;
}
- ivar_decl_list '}'
+ class_ivars
{
continue_class (objc_interface_context);
}
- methodprotolist
- END
- {
- finish_class (objc_interface_context);
- objc_interface_context = NULL_TREE;
- }
-
- | INTERFACE identifier ':' identifier protocolrefs
- {
- objc_interface_context
- = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5);
- continue_class (objc_interface_context);
- }
- methodprotolist
- END
+ methodprotolist END
{
finish_class (objc_interface_context);
objc_interface_context = NULL_TREE;
}
- | IMPLEMENTATION identifier '{'
- {
- objc_implementation_context = objc_ivar_context
- = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE);
- objc_public_flag = 0;
- }
- ivar_decl_list '}'
- {
- objc_ivar_chain
- = continue_class (objc_implementation_context);
- }
-
- | IMPLEMENTATION identifier
- {
- objc_implementation_context
- = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE);
- objc_ivar_chain
- = continue_class (objc_implementation_context);
- }
-
- | IMPLEMENTATION identifier ':' identifier '{'
+ | IMPLEMENTATION identifier superclass
{
objc_implementation_context = objc_ivar_context
- = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
+ = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $3, NULL_TREE);
objc_public_flag = 0;
}
- ivar_decl_list '}'
- {
- objc_ivar_chain
- = continue_class (objc_implementation_context);
- }
-
- | IMPLEMENTATION identifier ':' identifier
+ class_ivars
{
- objc_implementation_context
- = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE);
objc_ivar_chain
= continue_class (objc_implementation_context);
}
@@ -2825,8 +2807,7 @@ classdef:
= start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6);
continue_class (objc_interface_context);
}
- methodprotolist
- END
+ methodprotolist END
{
finish_class (objc_interface_context);
objc_interface_context = NULL_TREE;
@@ -2973,10 +2954,9 @@ methoddef:
methoddecl
{
objc_pq_context = 0;
- if (objc_inherit_code == CLASS_METHOD_DECL)
- add_class_method (objc_implementation_context, $3);
- else
- add_instance_method (objc_implementation_context, $3);
+ objc_add_method (objc_implementation_context,
+ $3,
+ objc_inherit_code == CLASS_METHOD_DECL);
start_method_def ($3);
}
optarglist
@@ -2995,14 +2975,8 @@ methoddef:
methodprotolist:
/* empty */
- | {$<ttype>$ = NULL_TREE; } methodprotolist2
- ;
-
-methodprotolist2: /* eliminates a shift/reduce conflict */
- methodproto
- | datadef
- | methodprotolist2 methodproto
- | methodprotolist2 {$<ttype>$ = NULL_TREE; } datadef
+ | methodprotolist methodproto
+ | methodprotolist { $<ttype>$ = NULL_TREE; } datadef
;
semi_or_error:
@@ -3020,10 +2994,9 @@ methodproto:
{
/* Forget protocol qualifiers here. */
objc_pq_context = 0;
- if (objc_inherit_code == CLASS_METHOD_DECL)
- add_class_method (objc_interface_context, $3);
- else
- add_instance_method (objc_interface_context, $3);
+ objc_add_method (objc_interface_context,
+ $3,
+ objc_inherit_code == CLASS_METHOD_DECL);
}
semi_or_error
;
@@ -3108,7 +3081,7 @@ myparm:
optparmlist:
/* empty */
{
- $$ = NULL_TREE;
+ $$ = NULL_TREE;
}
| ',' ELLIPSIS
{
@@ -3121,7 +3094,7 @@ optparmlist:
}
parmlist_2
{
- /* returns a tree list node generated by get_parm_info */
+ /* returns a tree list node generated by get_parm_info */
$$ = $3;
poplevel (0, 0, 0);
}
@@ -3220,6 +3193,10 @@ receiver:
{
$$ = get_class_reference ($1);
}
+ | TYPENAME
+ {
+ $$ = get_class_reference ($1);
+ }
;
objcmessageexpr:
@@ -3274,7 +3251,7 @@ objcencodeexpr:
}
;
-end ifobjc
+@@end_ifobjc
%%
/* yylex() is a thin wrapper around c_lex(), all it does is translate
@@ -3309,8 +3286,6 @@ static const struct resword reswords[] =
{ "__asm__", RID_ASM, 0 },
{ "__attribute", RID_ATTRIBUTE, 0 },
{ "__attribute__", RID_ATTRIBUTE, 0 },
- { "__bounded", RID_BOUNDED, 0 },
- { "__bounded__", RID_BOUNDED, 0 },
{ "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 },
{ "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 },
{ "__builtin_va_arg", RID_VA_ARG, 0 },
@@ -3340,8 +3315,6 @@ static const struct resword reswords[] =
{ "__thread", RID_THREAD, 0 },
{ "__typeof", RID_TYPEOF, 0 },
{ "__typeof__", RID_TYPEOF, 0 },
- { "__unbounded", RID_UNBOUNDED, 0 },
- { "__unbounded__", RID_UNBOUNDED, 0 },
{ "__volatile", RID_VOLATILE, 0 },
{ "__volatile__", RID_VOLATILE, 0 },
{ "asm", RID_ASM, D_EXT },
@@ -3380,7 +3353,7 @@ static const struct resword reswords[] =
{ "void", RID_VOID, 0 },
{ "volatile", RID_VOLATILE, 0 },
{ "while", RID_WHILE, 0 },
-ifobjc
+@@ifobjc
{ "id", RID_ID, D_OBJC },
/* These objc keywords are recognized only immediately after
@@ -3397,7 +3370,11 @@ ifobjc
{ "protocol", RID_AT_PROTOCOL, D_OBJC },
{ "public", RID_AT_PUBLIC, D_OBJC },
{ "selector", RID_AT_SELECTOR, D_OBJC },
-
+ { "throw", RID_AT_THROW, D_OBJC },
+ { "try", RID_AT_TRY, D_OBJC },
+ { "catch", RID_AT_CATCH, D_OBJC },
+ { "finally", RID_AT_FINALLY, D_OBJC },
+ { "synchronized", RID_AT_SYNCHRONIZED, D_OBJC },
/* These are recognized only in protocol-qualifier context
(see above) */
{ "bycopy", RID_BYCOPY, D_OBJC },
@@ -3406,7 +3383,7 @@ ifobjc
{ "inout", RID_INOUT, D_OBJC },
{ "oneway", RID_ONEWAY, D_OBJC },
{ "out", RID_OUT, D_OBJC },
-end ifobjc
+@@end_ifobjc
};
#define N_reswords (sizeof reswords / sizeof (struct resword))
@@ -3430,8 +3407,6 @@ static const short rid_to_yy[RID_MAX] =
/* RID_RESTRICT */ TYPE_QUAL,
/* C extensions */
- /* RID_BOUNDED */ TYPE_QUAL,
- /* RID_UNBOUNDED */ TYPE_QUAL,
/* RID_COMPLEX */ TYPESPEC,
/* RID_THREAD */ SCSPEC,
@@ -3490,9 +3465,9 @@ static const short rid_to_yy[RID_MAX] =
/* RID_CHOOSE_EXPR */ CHOOSE_EXPR,
/* RID_TYPES_COMPATIBLE_P */ TYPES_COMPATIBLE_P,
- /* RID_FUNCTION_NAME */ STRING_FUNC_NAME,
- /* RID_PRETTY_FUNCTION_NAME */ STRING_FUNC_NAME,
- /* RID_C99_FUNCTION_NAME */ VAR_FUNC_NAME,
+ /* RID_FUNCTION_NAME */ FUNC_NAME,
+ /* RID_PRETTY_FUNCTION_NAME */ FUNC_NAME,
+ /* RID_C99_FUNCTION_NAME */ FUNC_NAME,
/* C++ */
/* RID_BOOL */ TYPESPEC,
@@ -3508,6 +3483,7 @@ static const short rid_to_yy[RID_MAX] =
/* RID_FALSE */ 0,
/* RID_NAMESPACE */ 0,
/* RID_NEW */ 0,
+ /* RID_OFFSETOF */ 0,
/* RID_OPERATOR */ 0,
/* RID_THIS */ 0,
/* RID_THROW */ 0,
@@ -3535,25 +3511,27 @@ static const short rid_to_yy[RID_MAX] =
/* RID_AT_PUBLIC */ PUBLIC,
/* RID_AT_PROTOCOL */ PROTOCOL,
/* RID_AT_SELECTOR */ SELECTOR,
+ /* RID_AT_THROW */ AT_THROW,
+ /* RID_AT_TRY */ AT_TRY,
+ /* RID_AT_CATCH */ AT_CATCH,
+ /* RID_AT_FINALLY */ AT_FINALLY,
+ /* RID_AT_SYNCHRONIZED */ AT_SYNCHRONIZED,
/* RID_AT_INTERFACE */ INTERFACE,
/* RID_AT_IMPLEMENTATION */ IMPLEMENTATION
};
static void
-init_reswords ()
+init_reswords (void)
{
unsigned int i;
tree id;
int mask = (flag_isoc99 ? 0 : D_C89)
| (flag_no_asm ? (flag_isoc99 ? D_EXT : D_EXT|D_EXT89) : 0);
- if (!flag_objc)
+ if (!c_dialect_objc ())
mask |= D_OBJC;
- /* It is not necessary to register ridpointers as a GC root, because
- all the trees it points to are permanently interned in the
- get_identifier hash anyway. */
- ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree));
+ ridpointers = ggc_calloc ((int) RID_MAX, sizeof (tree));
for (i = 0; i < N_reswords; i++)
{
/* If a keyword is disabled, do not enter it into the table
@@ -3571,48 +3549,26 @@ init_reswords ()
#define NAME(type) cpp_type2name (type)
static void
-yyerror (msgid)
- const char *msgid;
+yyerror (const char *msgid)
{
- const char *string = _(msgid);
-
- if (last_token == CPP_EOF)
- error ("%s at end of input", string);
- else if (last_token == CPP_CHAR || last_token == CPP_WCHAR)
- {
- unsigned int val = TREE_INT_CST_LOW (yylval.ttype);
- const char *const ell = (last_token == CPP_CHAR) ? "" : "L";
- if (val <= UCHAR_MAX && ISGRAPH (val))
- error ("%s before %s'%c'", string, ell, val);
- else
- error ("%s before %s'\\x%x'", string, ell, val);
- }
- else if (last_token == CPP_STRING
- || last_token == CPP_WSTRING)
- error ("%s before string constant", string);
- else if (last_token == CPP_NUMBER)
- error ("%s before numeric constant", string);
- else if (last_token == CPP_NAME)
- error ("%s before \"%s\"", string, IDENTIFIER_POINTER (yylval.ttype));
- else
- error ("%s before '%s' token", string, NAME(last_token));
+ c_parse_error (msgid, last_token, yylval.ttype);
}
static int
-yylexname ()
+yylexname (void)
{
tree decl;
-ifobjc
+@@ifobjc
int objc_force_identifier = objc_need_raw_identifier;
OBJC_NEED_RAW_IDENTIFIER (0);
-end ifobjc
+@@end_ifobjc
if (C_IS_RESERVED_WORD (yylval.ttype))
{
enum rid rid_code = C_RID_CODE (yylval.ttype);
-ifobjc
+@@ifobjc
/* Turn non-typedefed refs to "id" into plain identifiers; this
allows constructs like "void foo(id id);" to work. */
if (rid_code == RID_ID)
@@ -3624,24 +3580,11 @@ ifobjc
if (!OBJC_IS_AT_KEYWORD (rid_code)
&& (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context))
-end ifobjc
+@@end_ifobjc
{
- int yycode = rid_to_yy[(int) rid_code];
- if (yycode == STRING_FUNC_NAME)
- {
- /* __FUNCTION__ and __PRETTY_FUNCTION__ get converted
- to string constants. */
- const char *name = fname_string (rid_code);
-
- yylval.ttype = build_string (strlen (name) + 1, name);
- C_ARTIFICIAL_STRING_P (yylval.ttype) = 1;
- last_token = CPP_STRING; /* so yyerror won't choke */
- return STRING;
- }
-
/* Return the canonical spelling for this keyword. */
yylval.ttype = ridpointers[(int) rid_code];
- return yycode;
+ return rid_to_yy[(int) rid_code];
}
}
@@ -3651,7 +3594,7 @@ end ifobjc
if (TREE_CODE (decl) == TYPE_DECL)
return TYPENAME;
}
-ifobjc
+@@ifobjc
else
{
tree objc_interface_decl = is_class_name (yylval.ttype);
@@ -3665,65 +3608,13 @@ ifobjc
return CLASSNAME;
}
}
-end ifobjc
+@@end_ifobjc
return IDENTIFIER;
}
-/* Concatenate strings before returning them to the parser. This isn't quite
- as good as having it done in the lexer, but it's better than nothing. */
-
-static int
-yylexstring ()
-{
- enum cpp_ttype next_type;
- tree orig = yylval.ttype;
-
- next_type = c_lex (&yylval.ttype);
- if (next_type == CPP_STRING
- || next_type == CPP_WSTRING
- || (next_type == CPP_NAME && yylexname () == STRING))
- {
- varray_type strings;
-
-ifc
- static int last_lineno = 0;
- static const char *last_input_filename = 0;
- if (warn_traditional && !in_system_header
- && (lineno != last_lineno || !last_input_filename ||
- strcmp (last_input_filename, input_filename)))
- {
- warning ("traditional C rejects string concatenation");
- last_lineno = lineno;
- last_input_filename = input_filename;
- }
-end ifc
-
- VARRAY_TREE_INIT (strings, 32, "strings");
- VARRAY_PUSH_TREE (strings, orig);
-
- do
- {
- VARRAY_PUSH_TREE (strings, yylval.ttype);
- next_type = c_lex (&yylval.ttype);
- }
- while (next_type == CPP_STRING
- || next_type == CPP_WSTRING
- || (next_type == CPP_NAME && yylexname () == STRING));
-
- yylval.ttype = combine_strings (strings);
- }
- else
- yylval.ttype = orig;
-
- /* We will have always read one token too many. */
- _cpp_backup_tokens (parse_in, 1);
-
- return STRING;
-}
-
static inline int
-_yylex ()
+_yylex (void)
{
get_next:
last_token = c_lex (&yylval.ttype);
@@ -3787,13 +3678,11 @@ _yylex ()
return 0;
case CPP_NAME:
- {
- int ret = yylexname ();
- if (ret == STRING)
- return yylexstring ();
- else
- return ret;
- }
+ return yylexname ();
+
+ case CPP_AT_NAME:
+ /* This only happens in Objective-C; it must be a keyword. */
+ return rid_to_yy [(int) C_RID_CODE (yylval.ttype)];
case CPP_NUMBER:
case CPP_CHAR:
@@ -3802,30 +3691,10 @@ _yylex ()
case CPP_STRING:
case CPP_WSTRING:
- return yylexstring ();
+ return STRING;
- /* This token is Objective-C specific. It gives the next token
- special significance. */
- case CPP_ATSIGN:
-ifobjc
- {
- tree after_at;
- enum cpp_ttype after_at_type;
-
- after_at_type = c_lex (&after_at);
-
- if (after_at_type == CPP_NAME
- && C_IS_RESERVED_WORD (after_at)
- && OBJC_IS_AT_KEYWORD (C_RID_CODE (after_at)))
- {
- yylval.ttype = after_at;
- last_token = after_at_type;
- return rid_to_yy [(int) C_RID_CODE (after_at)];
- }
- _cpp_backup_tokens (parse_in, 1);
- return '@';
- }
-end ifobjc
+ case CPP_OBJC_STRING:
+ return OBJC_STRING;
/* These tokens are C++ specific (and will not be generated
in C mode, but let's be cautious). */
@@ -3849,7 +3718,7 @@ end ifobjc
}
static int
-yylex()
+yylex (void)
{
int r;
timevar_push (TV_LEX);
@@ -3861,10 +3730,7 @@ yylex()
/* Function used when yydebug is set, to print a token in more detail. */
static void
-yyprint (file, yychar, yyl)
- FILE *file;
- int yychar;
- YYSTYPE yyl;
+yyprint (FILE *file, int yychar, YYSTYPE yyl)
{
tree t = yyl.ttype;
@@ -3886,25 +3752,11 @@ yyprint (file, yychar, yyl)
case CONSTANT:
fprintf (file, " %s", GET_MODE_NAME (TYPE_MODE (TREE_TYPE (t))));
if (TREE_CODE (t) == INTEGER_CST)
- fprintf (file,
-#if HOST_BITS_PER_WIDE_INT == 64
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
- " 0x%x%016x",
-#else
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
- " 0x%lx%016lx",
-#else
- " 0x%llx%016llx",
-#endif
-#endif
-#else
-#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
- " 0x%lx%08lx",
-#else
- " 0x%x%08x",
-#endif
-#endif
- TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t));
+ {
+ fputs (" ", file);
+ fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
+ TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t));
+ }
break;
}
}
@@ -3912,15 +3764,25 @@ yyprint (file, yychar, yyl)
/* This is not the ideal place to put these, but we have to get them out
of c-lex.c because cp/lex.c has its own versions. */
-/* Free malloced parser stacks if necessary. */
-
+/* Parse the file. */
void
-free_parser_stacks ()
+c_parse_file (void)
{
+ yyparse ();
+ /* In case there were missing closebraces, get us back to the global
+ binding level. */
+ while (! global_bindings_p ())
+ poplevel (0, 0, 0);
+ /* __FUNCTION__ is defined at file scope (""). This
+ call may not be necessary as my tests indicate it
+ still works without it. */
+ finish_fname_decls ();
+
if (malloced_yyss)
{
free (malloced_yyss);
free (malloced_yyvs);
+ malloced_yyss = 0;
}
}
diff --git a/contrib/gcc/c-pch.c b/contrib/gcc/c-pch.c
new file mode 100644
index 000000000000..8e4b60243592
--- /dev/null
+++ b/contrib/gcc/c-pch.c
@@ -0,0 +1,433 @@
+/* Precompiled header implementation for the C languages.
+ Copyright (C) 2000, 2002, 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "version.h"
+#include "cpplib.h"
+#include "tree.h"
+#include "flags.h"
+#include "c-common.h"
+#include "output.h"
+#include "toplev.h"
+#include "debug.h"
+#include "c-pragma.h"
+#include "ggc.h"
+#include "langhooks.h"
+#include "hosthooks.h"
+#include "target.h"
+
+/* This structure is read very early when validating the PCH, and
+ might be read for a PCH which is for a completely different compiler
+ for a different operating system. Thus, it should really only contain
+ 'unsigned char' entries, at least in the initial entries.
+
+ If you add or change entries before version_length, you should increase
+ the version number in get_ident().
+
+ There are a bunch of fields named *_length; those are lengths of data that
+ follows this structure in the same order as the fields in the structure.
+
+ The flags_info field is used to verify that certain flags settings that
+ have to be the same during the compilation of the PCH and a compilation
+ using the PCH are indeed the same. */
+
+struct c_pch_validity
+{
+ unsigned char host_machine_length;
+ unsigned char target_machine_length;
+ unsigned char version_length;
+ unsigned char debug_info_type;
+ unsigned int flags_info;
+ void (*pch_init) (void);
+ size_t target_data_length;
+};
+
+/* If -funit-at-a-time is set, we require that it was also set during the
+ compilation of the PCH we may be using. */
+#define FLAG_UNIT_AT_A_TIME_SET 1 << 0
+
+struct c_pch_header
+{
+ unsigned long asm_size;
+};
+
+#define IDENT_LENGTH 8
+
+/* The file we'll be writing the PCH to. */
+static FILE *pch_outfile;
+
+/* The position in the assembler output file when pch_init was called. */
+static long asm_file_startpos;
+
+/* The host and target machines. */
+static const char host_machine[] = HOST_MACHINE;
+static const char target_machine[] = TARGET_MACHINE;
+
+static const char *get_ident (void);
+
+/* Compute an appropriate 8-byte magic number for the PCH file, so that
+ utilities like file(1) can identify it, and so that GCC can quickly
+ ignore non-PCH files and PCH files that are of a completely different
+ format. */
+
+static const char *
+get_ident(void)
+{
+ static char result[IDENT_LENGTH];
+ static const char template[IDENT_LENGTH] = "gpch.012";
+ static const char c_language_chars[] = "Co+O";
+
+ memcpy (result, template, IDENT_LENGTH);
+ result[4] = c_language_chars[c_language];
+
+ return result;
+}
+
+/* Prepare to write a PCH file. This is called at the start of
+ compilation. */
+
+void
+pch_init (void)
+{
+ FILE *f;
+ struct c_pch_validity v;
+ void *target_validity;
+ static const char partial_pch[IDENT_LENGTH] = "gpcWrite";
+ unsigned int current_flags_info = 0;
+
+ if (! pch_file)
+ return;
+
+ if (flag_unit_at_a_time)
+ current_flags_info |= FLAG_UNIT_AT_A_TIME_SET;
+
+ f = fopen (pch_file, "w+b");
+ if (f == NULL)
+ fatal_error ("can't create precompiled header %s: %m", pch_file);
+ pch_outfile = f;
+
+ if (strlen (host_machine) > 255 || strlen (target_machine) > 255
+ || strlen (version_string) > 255)
+ abort ();
+
+ v.host_machine_length = strlen (host_machine);
+ v.target_machine_length = strlen (target_machine);
+ v.version_length = strlen (version_string);
+ v.debug_info_type = write_symbols;
+ v.flags_info = current_flags_info;
+ v.pch_init = &pch_init;
+ target_validity = targetm.get_pch_validity (&v.target_data_length);
+
+ if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
+ || fwrite (&v, sizeof (v), 1, f) != 1
+ || fwrite (host_machine, v.host_machine_length, 1, f) != 1
+ || fwrite (target_machine, v.target_machine_length, 1, f) != 1
+ || fwrite (version_string, v.version_length, 1, f) != 1
+ || fwrite (target_validity, v.target_data_length, 1, f) != 1)
+ fatal_error ("can't write to %s: %m", pch_file);
+
+ /* We need to be able to re-read the output. */
+ /* The driver always provides a valid -o option. */
+ if (asm_file_name == NULL
+ || strcmp (asm_file_name, "-") == 0)
+ fatal_error ("`%s' is not a valid output file", asm_file_name);
+
+ asm_file_startpos = ftell (asm_out_file);
+
+ /* Let the debugging format deal with the PCHness. */
+ (*debug_hooks->handle_pch) (0);
+
+ cpp_save_state (parse_in, f);
+}
+
+/* Write the PCH file. This is called at the end of a compilation which
+ will produce a PCH file. */
+
+void
+c_common_write_pch (void)
+{
+ char *buf;
+ long asm_file_end;
+ long written;
+ struct c_pch_header h;
+
+ (*debug_hooks->handle_pch) (1);
+
+ cpp_write_pch_deps (parse_in, pch_outfile);
+
+ asm_file_end = ftell (asm_out_file);
+ h.asm_size = asm_file_end - asm_file_startpos;
+
+ if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
+ fatal_error ("can't write %s: %m", pch_file);
+
+ buf = xmalloc (16384);
+ fflush (asm_out_file);
+
+ if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
+ fatal_error ("can't seek in %s: %m", asm_file_name);
+
+ for (written = asm_file_startpos; written < asm_file_end; )
+ {
+ long size = asm_file_end - written;
+ if (size > 16384)
+ size = 16384;
+ if (fread (buf, size, 1, asm_out_file) != 1)
+ fatal_error ("can't read %s: %m", asm_file_name);
+ if (fwrite (buf, size, 1, pch_outfile) != 1)
+ fatal_error ("can't write %s: %m", pch_file);
+ written += size;
+ }
+ free (buf);
+ /* asm_out_file can be written afterwards, so must be flushed first. */
+ fflush (asm_out_file);
+
+ gt_pch_save (pch_outfile);
+ cpp_write_pch_state (parse_in, pch_outfile);
+
+ if (fseek (pch_outfile, 0, SEEK_SET) != 0
+ || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1)
+ fatal_error ("can't write %s: %m", pch_file);
+
+ fclose (pch_outfile);
+}
+
+/* Check the PCH file called NAME, open on FD, to see if it can be
+ used in this compilation. Return 1 if valid, 0 if the file can't
+ be used now but might be if it's seen later in the compilation, and
+ 2 if this file could never be used in the compilation. */
+
+int
+c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
+{
+ int sizeread;
+ int result;
+ char ident[IDENT_LENGTH];
+ char short_strings[256 * 3];
+ int strings_length;
+ const char *pch_ident;
+ struct c_pch_validity v;
+ unsigned int current_flags_info = 0;
+
+ if (flag_unit_at_a_time)
+ current_flags_info |= FLAG_UNIT_AT_A_TIME_SET;
+
+ /* Perform a quick test of whether this is a valid
+ precompiled header for the current language
+ and with the current flag settings. */
+
+ sizeread = read (fd, ident, IDENT_LENGTH);
+ if (sizeread == -1)
+ fatal_error ("can't read %s: %m", name);
+ else if (sizeread != IDENT_LENGTH)
+ return 2;
+
+ pch_ident = get_ident();
+ if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ {
+ if (memcmp (ident, pch_ident, 5) == 0)
+ /* It's a PCH, for the right language, but has the wrong version.
+ */
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s: not compatible with this GCC version", name);
+ else if (memcmp (ident, pch_ident, 4) == 0)
+ /* It's a PCH for the wrong language. */
+ cpp_error (pfile, CPP_DL_WARNING, "%s: not for %s", name,
+ lang_hooks.name);
+ else
+ /* Not any kind of PCH. */
+ cpp_error (pfile, CPP_DL_WARNING, "%s: not a PCH file", name);
+ }
+ return 2;
+ }
+
+ /* At this point, we know it's a PCH file, so it ought to be long enough
+ that we can read a c_pch_validity structure. */
+ if (read (fd, &v, sizeof (v)) != sizeof (v))
+ fatal_error ("can't read %s: %m", name);
+
+ strings_length = (v.host_machine_length + v.target_machine_length
+ + v.version_length);
+ if (read (fd, short_strings, strings_length) != strings_length)
+ fatal_error ("can't read %s: %m", name);
+ if (v.host_machine_length != strlen (host_machine)
+ || memcmp (host_machine, short_strings, strlen (host_machine)) != 0)
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s: created on host `%.*s', but used on host `%s'", name,
+ v.host_machine_length, short_strings, host_machine);
+ return 2;
+ }
+ if (v.target_machine_length != strlen (target_machine)
+ || memcmp (target_machine, short_strings + v.host_machine_length,
+ strlen (target_machine)) != 0)
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s: created for target `%.*s', but used for target `%s'",
+ name, v.target_machine_length,
+ short_strings + v.host_machine_length, target_machine);
+ return 2;
+ }
+ if (v.version_length != strlen (version_string)
+ || memcmp (version_string,
+ (short_strings + v.host_machine_length
+ + v.target_machine_length),
+ v.version_length) != 0)
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s: created by version `%.*s', but this is version `%s'",
+ name, v.version_length,
+ (short_strings + v.host_machine_length
+ + v.target_machine_length),
+ version_string);
+ return 2;
+ }
+ if (v.flags_info != current_flags_info)
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s: created using different flags",
+ name);
+ return 2;
+ }
+
+ /* The allowable debug info combinations are that either the PCH file
+ was built with the same as is being used now, or the PCH file was
+ built for some kind of debug info but now none is in use. */
+ if (v.debug_info_type != write_symbols
+ && write_symbols != NO_DEBUG)
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s: created with -g%s, but used with -g%s", name,
+ debug_type_names[v.debug_info_type],
+ debug_type_names[write_symbols]);
+ return 2;
+ }
+
+ /* If the text segment was not loaded at the same address as it was
+ when the PCH file was created, function pointers loaded from the
+ PCH will not be valid. We could in theory remap all the function
+ pointers, but no support for that exists at present. */
+ if (v.pch_init != &pch_init)
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s: had text segment at different address", name);
+ return 2;
+ }
+
+ /* Check the target-specific validity data. */
+ {
+ void *this_file_data = xmalloc (v.target_data_length);
+ const char *msg;
+
+ if ((size_t) read (fd, this_file_data, v.target_data_length)
+ != v.target_data_length)
+ fatal_error ("can't read %s: %m", name);
+ msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
+ free (this_file_data);
+ if (msg != NULL)
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_WARNING, "%s: %s", name, msg);
+ return 2;
+ }
+ }
+
+ /* Check the preprocessor macros are the same as when the PCH was
+ generated. */
+
+ result = cpp_valid_state (pfile, name, fd);
+ if (result == -1)
+ return 2;
+ else
+ return result == 0;
+}
+
+/* Load in the PCH file NAME, open on FD. It was originally searched for
+ by ORIG_NAME. */
+
+void
+c_common_read_pch (cpp_reader *pfile, const char *name,
+ int fd, const char *orig_name ATTRIBUTE_UNUSED)
+{
+ FILE *f;
+ struct c_pch_header h;
+ char *buf;
+ unsigned long written;
+ struct save_macro_data *smd;
+
+ f = fdopen (fd, "rb");
+ if (f == NULL)
+ {
+ cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
+ return;
+ }
+
+ cpp_get_callbacks (parse_in)->valid_pch = NULL;
+
+ if (fread (&h, sizeof (h), 1, f) != 1)
+ {
+ cpp_errno (pfile, CPP_DL_ERROR, "reading");
+ return;
+ }
+
+ buf = xmalloc (16384);
+ for (written = 0; written < h.asm_size; )
+ {
+ long size = h.asm_size - written;
+ if (size > 16384)
+ size = 16384;
+ if (fread (buf, size, 1, f) != 1
+ || fwrite (buf, size, 1, asm_out_file) != 1)
+ cpp_errno (pfile, CPP_DL_ERROR, "reading");
+ written += size;
+ }
+ free (buf);
+
+ cpp_prepare_state (pfile, &smd);
+
+ gt_pch_restore (f);
+
+ if (cpp_read_state (pfile, name, f, smd) != 0)
+ return;
+
+ fclose (f);
+}
+
+/* Indicate that no more PCH files should be read. */
+
+void
+c_common_no_more_pch (void)
+{
+ if (cpp_get_callbacks (parse_in)->valid_pch)
+ {
+ cpp_get_callbacks (parse_in)->valid_pch = NULL;
+ host_hooks.gt_pch_use_address (NULL, 0);
+ }
+}
diff --git a/contrib/gcc/c-ppoutput.c b/contrib/gcc/c-ppoutput.c
new file mode 100644
index 000000000000..e97c9bc8ff79
--- /dev/null
+++ b/contrib/gcc/c-ppoutput.c
@@ -0,0 +1,415 @@
+/* Preprocess only, using cpplib.
+ Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+ Written by Per Bothner, 1994-95.
+
+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 2, 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, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "cpplib.h"
+#include "cpphash.h"
+#include "tree.h"
+#include "c-common.h" /* For flags. */
+#include "c-pragma.h" /* For parse_in. */
+
+/* Encapsulates state used to convert a stream of tokens into a text
+ file. */
+static struct
+{
+ FILE *outf; /* Stream to write to. */
+ const struct line_map *map; /* Logical to physical line mappings. */
+ const cpp_token *prev; /* Previous token. */
+ const cpp_token *source; /* Source token for spacing. */
+ fileline line; /* Line currently being written. */
+ unsigned char printed; /* Nonzero if something output at line. */
+} print;
+
+/* General output routines. */
+static void scan_translation_unit (cpp_reader *);
+static void scan_translation_unit_trad (cpp_reader *);
+static void account_for_newlines (const unsigned char *, size_t);
+static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
+
+static void print_line (const struct line_map *, fileline, const char *);
+static void maybe_print_line (const struct line_map *, fileline);
+
+/* Callback routines for the parser. Most of these are active only
+ in specific modes. */
+static void cb_line_change (cpp_reader *, const cpp_token *, int);
+static void cb_define (cpp_reader *, fileline, cpp_hashnode *);
+static void cb_undef (cpp_reader *, fileline, cpp_hashnode *);
+static void cb_include (cpp_reader *, fileline, const unsigned char *,
+ const char *, int);
+static void cb_ident (cpp_reader *, fileline, const cpp_string *);
+static void cb_def_pragma (cpp_reader *, fileline);
+
+/* Preprocess and output. */
+void
+preprocess_file (cpp_reader *pfile)
+{
+ /* A successful cpp_read_main_file guarantees that we can call
+ cpp_scan_nooutput or cpp_get_token next. */
+ if (flag_no_output)
+ {
+ /* Scan -included buffers, then the main file. */
+ while (pfile->buffer->prev)
+ cpp_scan_nooutput (pfile);
+ cpp_scan_nooutput (pfile);
+ }
+ else if (cpp_get_options (pfile)->traditional)
+ scan_translation_unit_trad (pfile);
+ else
+ scan_translation_unit (pfile);
+
+ /* -dM command line option. Should this be elsewhere? */
+ if (flag_dump_macros == 'M')
+ cpp_forall_identifiers (pfile, dump_macro, NULL);
+
+ /* Flush any pending output. */
+ if (print.printed)
+ putc ('\n', print.outf);
+}
+
+/* Set up the callbacks as appropriate. */
+void
+init_pp_output (FILE *out_stream)
+{
+ cpp_callbacks *cb = cpp_get_callbacks (parse_in);
+
+ if (!flag_no_output)
+ {
+ cb->line_change = cb_line_change;
+ /* Don't emit #pragma or #ident directives if we are processing
+ assembly language; the assembler may choke on them. */
+ if (cpp_get_options (parse_in)->lang != CLK_ASM)
+ {
+ cb->ident = cb_ident;
+ cb->def_pragma = cb_def_pragma;
+ }
+ }
+
+ if (flag_dump_includes)
+ cb->include = cb_include;
+
+ if (flag_dump_macros == 'N' || flag_dump_macros == 'D')
+ {
+ cb->define = cb_define;
+ cb->undef = cb_undef;
+ }
+
+ /* Initialize the print structure. Setting print.line to -1 here is
+ a trick to guarantee that the first token of the file will cause
+ a linemarker to be output by maybe_print_line. */
+ print.line = (fileline) -1;
+ print.printed = 0;
+ print.prev = 0;
+ print.map = 0;
+ print.outf = out_stream;
+}
+
+/* Writes out the preprocessed file, handling spacing and paste
+ avoidance issues. */
+static void
+scan_translation_unit (cpp_reader *pfile)
+{
+ bool avoid_paste = false;
+
+ print.source = NULL;
+ for (;;)
+ {
+ const cpp_token *token = cpp_get_token (pfile);
+
+ if (token->type == CPP_PADDING)
+ {
+ avoid_paste = true;
+ if (print.source == NULL
+ || (!(print.source->flags & PREV_WHITE)
+ && token->val.source == NULL))
+ print.source = token->val.source;
+ continue;
+ }
+
+ if (token->type == CPP_EOF)
+ break;
+
+ /* Subtle logic to output a space if and only if necessary. */
+ if (avoid_paste)
+ {
+ if (print.source == NULL)
+ print.source = token;
+ if (print.source->flags & PREV_WHITE
+ || (print.prev
+ && cpp_avoid_paste (pfile, print.prev, token))
+ || (print.prev == NULL && token->type == CPP_HASH))
+ putc (' ', print.outf);
+ }
+ else if (token->flags & PREV_WHITE)
+ putc (' ', print.outf);
+
+ avoid_paste = false;
+ print.source = NULL;
+ print.prev = token;
+ cpp_output_token (token, print.outf);
+
+ if (token->type == CPP_COMMENT)
+ account_for_newlines (token->val.str.text, token->val.str.len);
+ }
+}
+
+/* Adjust print.line for newlines embedded in output. */
+static void
+account_for_newlines (const unsigned char *str, size_t len)
+{
+ while (len--)
+ if (*str++ == '\n')
+ print.line++;
+}
+
+/* Writes out a traditionally preprocessed file. */
+static void
+scan_translation_unit_trad (cpp_reader *pfile)
+{
+ while (_cpp_read_logical_line_trad (pfile))
+ {
+ size_t len = pfile->out.cur - pfile->out.base;
+ maybe_print_line (print.map, pfile->out.first_line);
+ fwrite (pfile->out.base, 1, len, print.outf);
+ print.printed = 1;
+ if (!CPP_OPTION (pfile, discard_comments))
+ account_for_newlines (pfile->out.base, len);
+ }
+}
+
+/* If the token read on logical line LINE needs to be output on a
+ different line to the current one, output the required newlines or
+ a line marker, and return 1. Otherwise return 0. */
+static void
+maybe_print_line (const struct line_map *map, fileline line)
+{
+ /* End the previous line of text. */
+ if (print.printed)
+ {
+ putc ('\n', print.outf);
+ print.line++;
+ print.printed = 0;
+ }
+
+ if (line >= print.line && line < print.line + 8)
+ {
+ while (line > print.line)
+ {
+ putc ('\n', print.outf);
+ print.line++;
+ }
+ }
+ else
+ print_line (map, line, "");
+}
+
+/* Output a line marker for logical line LINE. Special flags are "1"
+ or "2" indicating entering or leaving a file. */
+static void
+print_line (const struct line_map *map, fileline line, const char *special_flags)
+{
+ /* End any previous line of text. */
+ if (print.printed)
+ putc ('\n', print.outf);
+ print.printed = 0;
+
+ print.line = line;
+ if (!flag_no_line_commands)
+ {
+ size_t to_file_len = strlen (map->to_file);
+ unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
+ unsigned char *p;
+
+ /* cpp_quote_string does not nul-terminate, so we have to do it
+ ourselves. */
+ p = cpp_quote_string (to_file_quoted,
+ (unsigned char *)map->to_file, to_file_len);
+ *p = '\0';
+ fprintf (print.outf, "# %u \"%s\"%s",
+ SOURCE_LINE (map, print.line),
+ to_file_quoted, special_flags);
+
+ if (map->sysp == 2)
+ fputs (" 3 4", print.outf);
+ else if (map->sysp == 1)
+ fputs (" 3", print.outf);
+
+ putc ('\n', print.outf);
+ }
+}
+
+/* Called when a line of output is started. TOKEN is the first token
+ of the line, and at end of file will be CPP_EOF. */
+static void
+cb_line_change (cpp_reader *pfile, const cpp_token *token,
+ int parsing_args)
+{
+ if (token->type == CPP_EOF || parsing_args)
+ return;
+
+ maybe_print_line (print.map, token->line);
+ print.prev = 0;
+ print.source = 0;
+
+ /* Supply enough spaces to put this token in its original column,
+ one space per column greater than 2, since scan_translation_unit
+ will provide a space if PREV_WHITE. Don't bother trying to
+ reconstruct tabs; we can't get it right in general, and nothing
+ ought to care. Some things do care; the fault lies with them. */
+ if (!CPP_OPTION (pfile, traditional))
+ {
+ print.printed = 1;
+ if (token->col > 2)
+ {
+ unsigned int spaces = token->col - 2;
+
+ while (spaces--)
+ putc (' ', print.outf);
+ }
+ }
+}
+
+static void
+cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
+ const cpp_string *str)
+{
+ maybe_print_line (print.map, line);
+ fprintf (print.outf, "#ident \"%s\"\n", str->text);
+ print.line++;
+}
+
+static void
+cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node)
+{
+ maybe_print_line (print.map, line);
+ fputs ("#define ", print.outf);
+
+ /* 'D' is whole definition; 'N' is name only. */
+ if (flag_dump_macros == 'D')
+ fputs ((const char *) cpp_macro_definition (pfile, node),
+ print.outf);
+ else
+ fputs ((const char *) NODE_NAME (node), print.outf);
+
+ putc ('\n', print.outf);
+ print.line++;
+}
+
+static void
+cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
+ cpp_hashnode *node)
+{
+ maybe_print_line (print.map, line);
+ fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
+ print.line++;
+}
+
+static void
+cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line,
+ const unsigned char *dir, const char *header, int angle_brackets)
+{
+ maybe_print_line (print.map, line);
+ if (angle_brackets)
+ fprintf (print.outf, "#%s <%s>\n", dir, header);
+ else
+ fprintf (print.outf, "#%s \"%s\"\n", dir, header);
+ print.line++;
+}
+
+/* Callback called when -fworking-director and -E to emit working
+ diretory in cpp output file. */
+
+void
+pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
+{
+ size_t to_file_len = strlen (dir);
+ unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1);
+ unsigned char *p;
+
+ /* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */
+ p = cpp_quote_string (to_file_quoted, (unsigned char *) dir, to_file_len);
+ *p = '\0';
+ fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted);
+}
+
+/* The file name, line number or system header flags have changed, as
+ described in MAP. From this point on, the old print.map might be
+ pointing to freed memory, and so must not be dereferenced. */
+
+void
+pp_file_change (const struct line_map *map)
+{
+ const char *flags = "";
+
+ if (flag_no_line_commands || flag_no_output)
+ return;
+
+ if (map != NULL)
+ {
+ /* First time? */
+ if (print.map == NULL)
+ {
+ /* Avoid printing foo.i when the main file is foo.c. */
+ if (!cpp_get_options (parse_in)->preprocessed)
+ print_line (map, map->from_line, flags);
+ }
+ else
+ {
+ /* Bring current file to correct line when entering a new file. */
+ if (map->reason == LC_ENTER)
+ maybe_print_line (map - 1, map->from_line - 1);
+
+ if (map->reason == LC_ENTER)
+ flags = " 1";
+ else if (map->reason == LC_LEAVE)
+ flags = " 2";
+ print_line (map, map->from_line, flags);
+ }
+ }
+
+ print.map = map;
+}
+
+/* Copy a #pragma directive to the preprocessed output. */
+static void
+cb_def_pragma (cpp_reader *pfile, fileline line)
+{
+ maybe_print_line (print.map, line);
+ fputs ("#pragma ", print.outf);
+ cpp_output_line (pfile, print.outf);
+ print.line++;
+}
+
+/* Dump out the hash table. */
+static int
+dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
+{
+ if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
+ {
+ fputs ("#define ", print.outf);
+ fputs ((const char *) cpp_macro_definition (pfile, node),
+ print.outf);
+ putc ('\n', print.outf);
+ print.line++;
+ }
+
+ return 1;
+}
diff --git a/contrib/gcc/c-pragma.c b/contrib/gcc/c-pragma.c
index 819e6965bd6b..10c8caea35d9 100644
--- a/contrib/gcc/c-pragma.c
+++ b/contrib/gcc/c-pragma.c
@@ -1,5 +1,5 @@
/* Handle #pragma, system V.4 style. Supports #pragma weak and #pragma pack.
- Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "function.h"
@@ -47,7 +49,7 @@ typedef struct align_stack GTY(())
static GTY(()) struct align_stack * alignment_stack;
#ifdef HANDLE_PRAGMA_PACK
-static void handle_pragma_pack PARAMS ((cpp_reader *));
+static void handle_pragma_pack (cpp_reader *);
#ifdef HANDLE_PRAGMA_PACK_PUSH_POP
/* If we have a "global" #pragma pack(<n>) in effect when the first
@@ -59,14 +61,12 @@ static int default_alignment;
#define SET_GLOBAL_ALIGNMENT(ALIGN) \
(default_alignment = maximum_field_alignment = (ALIGN))
-static void push_alignment PARAMS ((int, tree));
-static void pop_alignment PARAMS ((tree));
+static void push_alignment (int, tree);
+static void pop_alignment (tree);
/* Push an alignment value onto the stack. */
static void
-push_alignment (alignment, id)
- int alignment;
- tree id;
+push_alignment (int alignment, tree id)
{
if (alignment_stack == NULL
|| alignment_stack->alignment != alignment
@@ -74,7 +74,7 @@ push_alignment (alignment, id)
{
align_stack * entry;
- entry = (align_stack *) ggc_alloc (sizeof (* entry));
+ entry = ggc_alloc (sizeof (* entry));
entry->alignment = alignment;
entry->num_pushes = 1;
@@ -97,8 +97,7 @@ push_alignment (alignment, id)
/* Undo a push of an alignment onto the stack. */
static void
-pop_alignment (id)
- tree id;
+pop_alignment (tree id)
{
align_stack * entry;
@@ -155,8 +154,7 @@ pop_alignment (id)
#pragma pack (pop)
#pragma pack (pop, ID) */
static void
-handle_pragma_pack (dummy)
- cpp_reader *dummy ATTRIBUTE_UNUSED;
+handle_pragma_pack (cpp_reader *dummy ATTRIBUTE_UNUSED)
{
tree x, id = 0;
int align = -1;
@@ -259,12 +257,11 @@ handle_pragma_pack (dummy)
static GTY(()) tree pending_weaks;
#ifdef HANDLE_PRAGMA_WEAK
-static void apply_pragma_weak PARAMS ((tree, tree));
-static void handle_pragma_weak PARAMS ((cpp_reader *));
+static void apply_pragma_weak (tree, tree);
+static void handle_pragma_weak (cpp_reader *);
static void
-apply_pragma_weak (decl, value)
- tree decl, value;
+apply_pragma_weak (tree decl, tree value)
{
if (value)
{
@@ -276,15 +273,16 @@ apply_pragma_weak (decl, value)
}
if (SUPPORTS_WEAK && DECL_EXTERNAL (decl) && TREE_USED (decl)
+ && !DECL_WEAK (decl) /* Don't complain about a redundant #pragma. */
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
- warning_with_decl (decl, "applying #pragma weak `%s' after first use results in unspecified behavior");
+ warning ("%Japplying #pragma weak '%D' after first use results "
+ "in unspecified behavior", decl, decl);
declare_weak (decl);
}
void
-maybe_apply_pragma_weak (decl)
- tree decl;
+maybe_apply_pragma_weak (tree decl)
{
tree *p, t, id;
@@ -316,8 +314,7 @@ maybe_apply_pragma_weak (decl)
/* #pragma weak name [= value] */
static void
-handle_pragma_weak (dummy)
- cpp_reader *dummy ATTRIBUTE_UNUSED;
+handle_pragma_weak (cpp_reader *dummy ATTRIBUTE_UNUSED)
{
tree name, value, x, decl;
enum cpp_ttype t;
@@ -348,8 +345,7 @@ handle_pragma_weak (dummy)
}
#else
void
-maybe_apply_pragma_weak (decl)
- tree decl ATTRIBUTE_UNUSED;
+maybe_apply_pragma_weak (tree decl ATTRIBUTE_UNUSED)
{
}
#endif /* HANDLE_PRAGMA_WEAK */
@@ -357,12 +353,11 @@ maybe_apply_pragma_weak (decl)
static GTY(()) tree pending_redefine_extname;
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
-static void handle_pragma_redefine_extname PARAMS ((cpp_reader *));
+static void handle_pragma_redefine_extname (cpp_reader *);
/* #pragma redefined_extname oldname newname */
static void
-handle_pragma_redefine_extname (dummy)
- cpp_reader *dummy ATTRIBUTE_UNUSED;
+handle_pragma_redefine_extname (cpp_reader *dummy ATTRIBUTE_UNUSED)
{
tree oldname, newname, decl, x;
enum cpp_ttype t;
@@ -382,12 +377,13 @@ handle_pragma_redefine_extname (dummy)
warning ("junk at end of #pragma redefine_extname");
decl = identifier_global_value (oldname);
- if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+ if (decl && (TREE_CODE (decl) == FUNCTION_DECL
+ || TREE_CODE (decl) == VAR_DECL))
{
if (DECL_ASSEMBLER_NAME_SET_P (decl)
&& DECL_ASSEMBLER_NAME (decl) != newname)
warning ("#pragma redefine_extname conflicts with declaration");
- SET_DECL_ASSEMBLER_NAME (decl, newname);
+ change_decl_assembler_name (decl, newname);
}
else
add_to_renaming_pragma_list(oldname, newname);
@@ -395,8 +391,7 @@ handle_pragma_redefine_extname (dummy)
#endif
void
-add_to_renaming_pragma_list (oldname, newname)
- tree oldname, newname;
+add_to_renaming_pragma_list (tree oldname, tree newname)
{
pending_redefine_extname
= tree_cons (oldname, newname, pending_redefine_extname);
@@ -405,12 +400,11 @@ add_to_renaming_pragma_list (oldname, newname)
static GTY(()) tree pragma_extern_prefix;
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
-static void handle_pragma_extern_prefix PARAMS ((cpp_reader *));
+static void handle_pragma_extern_prefix (cpp_reader *);
/* #pragma extern_prefix "prefix" */
static void
-handle_pragma_extern_prefix (dummy)
- cpp_reader *dummy ATTRIBUTE_UNUSED;
+handle_pragma_extern_prefix (cpp_reader *dummy ATTRIBUTE_UNUSED)
{
tree prefix, x;
enum cpp_ttype t;
@@ -429,12 +423,11 @@ handle_pragma_extern_prefix (dummy)
}
#endif
-/* Hook from the front ends to apply the results of one of the preceeding
+/* Hook from the front ends to apply the results of one of the preceding
pragmas that rename variables. */
tree
-maybe_apply_renaming_pragma (decl, asmname)
- tree decl, asmname;
+maybe_apply_renaming_pragma (tree decl, tree asmname)
{
tree oldname;
@@ -488,26 +481,34 @@ maybe_apply_renaming_pragma (decl, asmname)
return asmname;
}
+/* Front-end wrapper for pragma registration to avoid dragging
+ cpplib.h in almost everywhere. */
+void
+c_register_pragma (const char *space, const char *name,
+ void (*handler) (struct cpp_reader *))
+{
+ cpp_register_pragma (parse_in, space, name, handler);
+}
+
+/* Set up front-end pragmas. */
void
-init_pragma ()
+init_pragma (void)
{
#ifdef HANDLE_PRAGMA_PACK
- cpp_register_pragma (parse_in, 0, "pack", handle_pragma_pack);
+ c_register_pragma (0, "pack", handle_pragma_pack);
#endif
#ifdef HANDLE_PRAGMA_WEAK
- cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
+ c_register_pragma (0, "weak", handle_pragma_weak);
#endif
#ifdef HANDLE_PRAGMA_REDEFINE_EXTNAME
- cpp_register_pragma (parse_in, 0, "redefine_extname",
- handle_pragma_redefine_extname);
+ c_register_pragma (0, "redefine_extname", handle_pragma_redefine_extname);
#endif
#ifdef HANDLE_PRAGMA_EXTERN_PREFIX
- cpp_register_pragma (parse_in, 0, "extern_prefix",
- handle_pragma_extern_prefix);
+ c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
#endif
#ifdef REGISTER_TARGET_PRAGMAS
- REGISTER_TARGET_PRAGMAS (parse_in);
+ REGISTER_TARGET_PRAGMAS ();
#endif
}
diff --git a/contrib/gcc/c-pragma.h b/contrib/gcc/c-pragma.h
index 7911c5a65028..a1469db17423 100644
--- a/contrib/gcc/c-pragma.h
+++ b/contrib/gcc/c-pragma.h
@@ -1,5 +1,5 @@
/* Pragma related interfaces.
- Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@@ -26,15 +26,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define YYDEBUG 1
extern int yydebug;
-struct cpp_reader;
extern struct cpp_reader* parse_in;
-#ifdef HANDLE_SYSV_PRAGMA
-#if ((defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_WEAK_ALIAS)) \
- || defined (ASM_WEAKEN_DECL))
#define HANDLE_PRAGMA_WEAK SUPPORTS_WEAK
-#endif
+#ifdef HANDLE_SYSV_PRAGMA
/* We always support #pragma pack for SYSV pragmas. */
#ifndef HANDLE_PRAGMA_PACK
#define HANDLE_PRAGMA_PACK 1
@@ -48,22 +44,17 @@ extern struct cpp_reader* parse_in;
#define HANDLE_PRAGMA_PACK 1
#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */
-extern void init_pragma PARAMS ((void));
-
-/* Duplicate prototypes for the register_pragma stuff and the typedef for
- cpp_reader, to avoid dragging cpplib.h in almost everywhere... */
-#ifndef GCC_CPPLIB_H
-typedef struct cpp_reader cpp_reader;
-
-extern void cpp_register_pragma PARAMS ((cpp_reader *,
- const char *, const char *,
- void (*) PARAMS ((cpp_reader *))));
-#endif
+extern void init_pragma (void);
-extern void maybe_apply_pragma_weak PARAMS ((tree));
-extern tree maybe_apply_renaming_pragma PARAMS ((tree, tree));
-extern void add_to_renaming_pragma_list PARAMS ((tree, tree));
+/* Front-end wrapper for pragma registration to avoid dragging
+ cpplib.h in almost everywhere. */
+extern void c_register_pragma (const char *, const char *,
+ void (*) (struct cpp_reader *));
+extern void maybe_apply_pragma_weak (tree);
+extern tree maybe_apply_renaming_pragma (tree, tree);
+extern void add_to_renaming_pragma_list (tree, tree);
-extern int c_lex PARAMS ((tree *));
+extern int c_lex (tree *);
+extern int c_lex_with_flags (tree *, unsigned char *);
#endif /* GCC_C_PRAGMA_H */
diff --git a/contrib/gcc/c-pretty-print.c b/contrib/gcc/c-pretty-print.c
index 377018ed21ee..bcbfd793ad38 100644
--- a/contrib/gcc/c-pretty-print.c
+++ b/contrib/gcc/c-pretty-print.c
@@ -1,5 +1,5 @@
/* Subroutines common to both C and C++ pretty-printers.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
@@ -21,266 +21,638 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "real.h"
#include "c-pretty-print.h"
#include "c-tree.h"
-/* literal */
-static void pp_c_char PARAMS ((c_pretty_printer, int));
-static void pp_c_character_literal PARAMS ((c_pretty_printer, tree));
-static void pp_c_bool_literal PARAMS ((c_pretty_printer, tree));
-static bool pp_c_enumerator PARAMS ((c_pretty_printer, tree));
-static void pp_c_integer_literal PARAMS ((c_pretty_printer, tree));
-static void pp_c_real_literal PARAMS ((c_pretty_printer, tree));
-static void pp_c_string_literal PARAMS ((c_pretty_printer, tree));
+/* The pretty-printer code is primarily designed to closely follow
+ (GNU) C and C++ grammars. That is to be contrasted with spaghetti
+ codes we used to have in the past. Following a structured
+ approach (preferably the official grammars) is believed to make it
+ much easier to add extensions and nifty pretty-printing effects that
+ takes expression or declaration contexts into account. */
+
+
+#define pp_c_maybe_whitespace(PP) \
+ do { \
+ if (pp_base (PP)->padding == pp_before) \
+ pp_c_whitespace (PP); \
+ } while (0)
+
+#define pp_c_left_bracket(PP) \
+ do { \
+ pp_left_bracket (PP); \
+ pp_base (PP)->padding = pp_none; \
+ } while (0)
+
+#define pp_c_right_bracket(PP) \
+ do { \
+ pp_right_bracket (PP); \
+ pp_base (PP)->padding = pp_none; \
+ } while (0)
+
+#define pp_c_star(PP) \
+ do { \
+ pp_star (PP); \
+ pp_base (PP)->padding = pp_none; \
+ } while (0)
-static void pp_c_primary_expression PARAMS ((c_pretty_printer, tree));
+/* literal */
+static void pp_c_char (c_pretty_printer *, int);
/* postfix-expression */
-static void pp_c_initializer_list PARAMS ((c_pretty_printer, tree));
-
-static void pp_c_unary_expression PARAMS ((c_pretty_printer, tree));
-static void pp_c_multiplicative_expression PARAMS ((c_pretty_printer, tree));
-static void pp_c_additive_expression PARAMS ((c_pretty_printer, tree));
-static void pp_c_shift_expression PARAMS ((c_pretty_printer, tree));
-static void pp_c_relational_expression PARAMS ((c_pretty_printer, tree));
-static void pp_c_equality_expression PARAMS ((c_pretty_printer, tree));
-static void pp_c_and_expression PARAMS ((c_pretty_printer, tree));
-static void pp_c_exclusive_or_expression PARAMS ((c_pretty_printer,
- tree));
-static void pp_c_inclusive_or_expression PARAMS ((c_pretty_printer,
- tree));
-static void pp_c_logical_and_expression PARAMS ((c_pretty_printer, tree));
-static void pp_c_conditional_expression PARAMS ((c_pretty_printer, tree));
-static void pp_c_assignment_expression PARAMS ((c_pretty_printer, tree));
+static void pp_c_initializer_list (c_pretty_printer *, tree);
+static void pp_c_brace_enclosed_initializer_list (c_pretty_printer *, tree);
+
+static void pp_c_multiplicative_expression (c_pretty_printer *, tree);
+static void pp_c_additive_expression (c_pretty_printer *, tree);
+static void pp_c_shift_expression (c_pretty_printer *, tree);
+static void pp_c_relational_expression (c_pretty_printer *, tree);
+static void pp_c_equality_expression (c_pretty_printer *, tree);
+static void pp_c_and_expression (c_pretty_printer *, tree);
+static void pp_c_exclusive_or_expression (c_pretty_printer *, tree);
+static void pp_c_inclusive_or_expression (c_pretty_printer *, tree);
+static void pp_c_logical_and_expression (c_pretty_printer *, tree);
+static void pp_c_conditional_expression (c_pretty_printer *, tree);
+static void pp_c_assignment_expression (c_pretty_printer *, tree);
/* declarations. */
-static void pp_c_declaration_specifiers PARAMS ((c_pretty_printer, tree));
-static void pp_c_init_declarator PARAMS ((c_pretty_printer, tree));
-static void pp_c_declarator PARAMS ((c_pretty_printer, tree));
-static void pp_c_direct_declarator PARAMS ((c_pretty_printer, tree));
-static void pp_c_abstract_declarator PARAMS ((c_pretty_printer, tree));
-static void pp_c_specifier_qualifier_list PARAMS ((c_pretty_printer, tree));
-static void pp_c_simple_type_specifier PARAMS ((c_pretty_printer, tree));
-static void pp_c_parameter_declaration PARAMS ((c_pretty_printer, tree));
-static void pp_c_type_id PARAMS ((c_pretty_printer, tree));
-static void pp_c_storage_class_specifier PARAMS ((c_pretty_printer, tree));
-static void pp_c_function_specifier PARAMS ((c_pretty_printer, tree));
+
+
+/* Helper functions. */
+
+void
+pp_c_whitespace (c_pretty_printer *pp)
+{
+ pp_space (pp);
+ pp_base (pp)->padding = pp_none;
+}
+
+void
+pp_c_left_paren (c_pretty_printer *pp)
+{
+ pp_left_paren (pp);
+ pp_base (pp)->padding = pp_none;
+}
+
+void
+pp_c_right_paren (c_pretty_printer *pp)
+{
+ pp_right_paren (pp);
+ pp_base (pp)->padding = pp_none;
+}
+
+void
+pp_c_left_brace (c_pretty_printer *pp)
+{
+ pp_left_brace (pp);
+ pp_base (pp)->padding = pp_none;
+}
+
+void
+pp_c_right_brace (c_pretty_printer *pp)
+{
+ pp_right_brace (pp);
+ pp_base (pp)->padding = pp_none;
+}
+
+void
+pp_c_dot (c_pretty_printer *pp)
+{
+ pp_dot (pp);
+ pp_base (pp)->padding = pp_none;
+}
+
+void
+pp_c_ampersand (c_pretty_printer *pp)
+{
+ pp_ampersand (pp);
+ pp_base (pp)->padding = pp_none;
+}
+
+void
+pp_c_arrow (c_pretty_printer *pp)
+{
+ pp_arrow (pp);
+ pp_base (pp)->padding = pp_none;
+}
+
+void
+pp_c_semicolon(c_pretty_printer *pp)
+{
+ pp_semicolon (pp);
+ pp_base (pp)->padding = pp_none;
+}
+
+static void
+pp_c_cv_qualifier (c_pretty_printer *pp, const char *cv)
+{
+ const char *p = pp_last_position_in_text (pp);
+ if (p != NULL && *p == '*')
+ pp_c_whitespace (pp);
+ pp_c_identifier (pp, cv);
+}
+
+/* Pretty-print T using the type-cast notation '( type-name )'. */
+
+static void
+pp_c_type_cast (c_pretty_printer *pp, tree t)
+{
+ pp_c_left_paren (pp);
+ pp_type_id (pp, t);
+ pp_c_right_paren (pp);
+}
+
+void
+pp_c_space_for_pointer_operator (c_pretty_printer *pp, tree t)
+{
+ if (POINTER_TYPE_P (t))
+ {
+ tree pointee = strip_pointer_operator (TREE_TYPE (t));
+ if (TREE_CODE (pointee) != ARRAY_TYPE
+ && TREE_CODE (pointee) != FUNCTION_TYPE)
+ pp_c_whitespace (pp);
+ }
+}
/* Declarations. */
-/* Print out CV-qualifiers. Take care of possible extensions. */
+/* C++ cv-qualifiers are called type-qualifiers in C. Print out the
+ cv-qualifiers of T. If T is a declaration then it is the cv-qualifier
+ of its type. Take care of possible extensions.
+
+ type-qualifier-list:
+ type-qualifier
+ type-qualifier-list type-qualifier
+
+ type-qualifier:
+ const
+ restrict -- C99
+ __restrict__ -- GNU C
+ volatile */
+
void
-pp_c_cv_qualifier (ppi, cv)
- c_pretty_printer ppi;
- int cv;
+pp_c_type_qualifier_list (c_pretty_printer *pp, tree t)
{
- if (cv & TYPE_QUAL_CONST)
- pp_c_identifier (ppi, "const");
- if (cv & TYPE_QUAL_VOLATILE)
- pp_c_identifier (ppi, "volatile");
- if (cv & TYPE_QUAL_RESTRICT)
- pp_c_identifier (ppi, flag_isoc99 ? "restrict" : "__restrict__");
+ int qualifiers;
+
+ if (!TYPE_P (t))
+ t = TREE_TYPE (t);
+
+ qualifiers = TYPE_QUALS (t);
+ if (qualifiers & TYPE_QUAL_CONST)
+ pp_c_cv_qualifier (pp, "const");
+ if (qualifiers & TYPE_QUAL_VOLATILE)
+ pp_c_cv_qualifier (pp, "volatile");
+ if (qualifiers & TYPE_QUAL_RESTRICT)
+ pp_c_cv_qualifier (pp, flag_isoc99 ? "restrict" : "__restrict__");
}
+/* pointer:
+ * type-qualifier-list(opt)
+ * type-qualifier-list(opt) pointer */
+
static void
-pp_c_simple_type_specifier (ppi, t)
- c_pretty_printer ppi;
- tree t;
+pp_c_pointer (c_pretty_printer *pp, tree t)
+{
+ if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
+ t = TREE_TYPE (t);
+ switch (TREE_CODE (t))
+ {
+ case POINTER_TYPE:
+ /* It is easier to handle C++ reference types here. */
+ case REFERENCE_TYPE:
+ if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
+ pp_c_pointer (pp, TREE_TYPE (t));
+ if (TREE_CODE (t) == POINTER_TYPE)
+ pp_c_star (pp);
+ else
+ pp_c_ampersand (pp);
+ pp_c_type_qualifier_list (pp, t);
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ }
+}
+
+/* type-specifier:
+ void
+ char
+ short
+ int
+ long
+ float
+ double
+ signed
+ unsigned
+ _Bool -- C99
+ _Complex -- C99
+ _Imaginary -- C99
+ struct-or-union-specifier
+ enum-specifier
+ typedef-name.
+
+ GNU extensions.
+ simple-type-specifier:
+ __complex__
+ __vector__ */
+
+void
+pp_c_type_specifier (c_pretty_printer *pp, tree t)
{
const enum tree_code code = TREE_CODE (t);
switch (code)
{
case ERROR_MARK:
- pp_c_identifier (ppi, "<type-error>");
- break;
-
-#if 0
- case UNKNOWN_TYPE:
- pp_c_identifier (ppi, "<unkown-type>");
+ pp_c_identifier (pp, "<type-error>");
break;
-#endif
case IDENTIFIER_NODE:
- pp_c_tree_identifier (ppi, t);
+ pp_c_tree_identifier (pp, t);
break;
-
+
case VOID_TYPE:
case BOOLEAN_TYPE:
case CHAR_TYPE:
case INTEGER_TYPE:
case REAL_TYPE:
- pp_c_tree_identifier (ppi, DECL_NAME (t));
- break;
-
- case COMPLEX_TYPE:
- case VECTOR_TYPE:
- pp_c_simple_type_specifier (ppi, TYPE_MAIN_VARIANT (TREE_TYPE (t)));
- if (code == COMPLEX_TYPE)
- pp_c_identifier (ppi, flag_isoc99 ? "_Complex" : "__complex__");
- else if (code == VECTOR_TYPE)
- pp_c_identifier (ppi, "__vector__");
+ if (TYPE_NAME (t))
+ t = TYPE_NAME (t);
+ else
+ t = c_common_type_for_mode (TYPE_MODE (t), TREE_UNSIGNED (t));
+ pp_c_type_specifier (pp, t);
break;
case TYPE_DECL:
if (DECL_NAME (t))
- pp_c_tree_identifier (ppi, DECL_NAME (t));
+ pp_id_expression (pp, t);
else
- pp_c_identifier (ppi, "<typedef-error>");
+ pp_c_identifier (pp, "<typedef-error>");
break;
case UNION_TYPE:
case RECORD_TYPE:
case ENUMERAL_TYPE:
if (code == UNION_TYPE)
- pp_c_identifier (ppi, "union");
+ pp_c_identifier (pp, "union");
else if (code == RECORD_TYPE)
- pp_c_identifier (ppi, "struct");
+ pp_c_identifier (pp, "struct");
else if (code == ENUMERAL_TYPE)
- pp_c_identifier (ppi, "enum");
+ pp_c_identifier (pp, "enum");
else
- pp_c_identifier (ppi, "<tag-error>");
-
+ pp_c_identifier (pp, "<tag-error>");
+
if (TYPE_NAME (t))
- pp_c_tree_identifier (ppi, TYPE_NAME (t));
+ pp_id_expression (pp, TYPE_NAME (t));
else
- pp_c_identifier (ppi, "<anonymous>");
+ pp_c_identifier (pp, "<anonymous>");
break;
default:
- pp_unsupported_tree (ppi, t);
+ pp_unsupported_tree (pp, t);
+ break;
}
}
-static inline void
-pp_c_specifier_qualifier_list (ppi, t)
- c_pretty_printer ppi;
- tree t;
+/* specifier-qualifier-list:
+ type-specifier specifier-qualifier-list-opt
+ type-qualifier specifier-qualifier-list-opt
+
+
+ Implementation note: Because of the non-linearities in array or
+ function declarations, this routine prints not just the
+ specifier-qualifier-list of such entities or types of such entities,
+ but also the 'pointer' production part of their declarators. The
+ remaining part is done by pp_declarator or pp_c_abstract_declarator. */
+
+void
+pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t)
{
- pp_c_simple_type_specifier (ppi, TYPE_MAIN_VARIANT (TREE_TYPE (t)));
- pp_c_cv_qualifier (ppi, TYPE_QUALS (t));
+ const enum tree_code code = TREE_CODE (t);
+
+ if (TREE_CODE (t) != POINTER_TYPE)
+ pp_c_type_qualifier_list (pp, t);
+ switch (code)
+ {
+ case REFERENCE_TYPE:
+ case POINTER_TYPE:
+ {
+ /* Get the types-specifier of this type. */
+ tree pointee = strip_pointer_operator (TREE_TYPE (t));
+ pp_c_specifier_qualifier_list (pp, pointee);
+ if (TREE_CODE (pointee) == ARRAY_TYPE
+ || TREE_CODE (pointee) == FUNCTION_TYPE)
+ {
+ pp_c_whitespace (pp);
+ pp_c_left_paren (pp);
+ }
+ pp_ptr_operator (pp, t);
+ }
+ break;
+
+ case FUNCTION_TYPE:
+ case ARRAY_TYPE:
+ pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
+ break;
+
+ case VECTOR_TYPE:
+ case COMPLEX_TYPE:
+ pp_c_specifier_qualifier_list (pp, TREE_TYPE (t));
+ if (code == COMPLEX_TYPE)
+ pp_c_identifier (pp, flag_isoc99 ? "_Complex" : "__complex__");
+ else if (code == VECTOR_TYPE)
+ pp_c_identifier (pp, "__vector__");
+ break;
+
+ default:
+ pp_simple_type_specifier (pp, t);
+ break;
+ }
}
+/* parameter-type-list:
+ parameter-list
+ parameter-list , ...
+
+ parameter-list:
+ parameter-declaration
+ parameter-list , parameter-declaration
+
+ parameter-declaration:
+ declaration-specifiers declarator
+ declaration-specifiers abstract-declarator(opt) */
+
+void
+pp_c_parameter_type_list (c_pretty_printer *pp, tree t)
+{
+ bool want_parm_decl = DECL_P (t) && !(pp->flags & pp_c_flag_abstract);
+ tree parms = want_parm_decl ? DECL_ARGUMENTS (t) : TYPE_ARG_TYPES (t);
+ pp_c_left_paren (pp);
+ if (parms == void_list_node)
+ pp_c_identifier (pp, "void");
+ else
+ {
+ bool first = true;
+ for ( ; parms && parms != void_list_node; parms = TREE_CHAIN (parms))
+ {
+ if (!first)
+ pp_separate_with (pp, ',');
+ first = false;
+ pp_declaration_specifiers
+ (pp, want_parm_decl ? parms : TREE_VALUE (parms));
+ if (want_parm_decl)
+ pp_declarator (pp, parms);
+ else
+ pp_abstract_declarator (pp, TREE_VALUE (parms));
+ }
+ }
+ pp_c_right_paren (pp);
+}
+
+/* abstract-declarator:
+ pointer
+ pointer(opt) direct-abstract-declarator */
+
static void
-pp_c_abstract_declarator (ppi, t)
- c_pretty_printer ppi;
- tree t;
+pp_c_abstract_declarator (c_pretty_printer *pp, tree t)
{
- pp_unsupported_tree (ppi, t);
+ if (TREE_CODE (t) == POINTER_TYPE)
+ {
+ if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
+ || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
+ pp_c_right_paren (pp);
+ t = TREE_TYPE (t);
+ }
+
+ pp_direct_abstract_declarator (pp, t);
+}
+
+/* direct-abstract-declarator:
+ ( abstract-declarator )
+ direct-abstract-declarator(opt) [ assignment-expression(opt) ]
+ direct-abstract-declarator(opt) [ * ]
+ direct-abstract-declarator(opt) ( parameter-type-list(opt) ) */
+
+void
+pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case POINTER_TYPE:
+ pp_abstract_declarator (pp, t);
+ break;
+
+ case FUNCTION_TYPE:
+ pp_c_parameter_type_list (pp, t);
+ pp_direct_abstract_declarator (pp, TREE_TYPE (t));
+ break;
+
+ case ARRAY_TYPE:
+ pp_c_left_bracket (pp);
+ if (TYPE_DOMAIN (t))
+ pp_expression (pp, TYPE_MAX_VALUE (TYPE_DOMAIN (t)));
+ pp_c_right_bracket (pp);
+ pp_direct_abstract_declarator (pp, TREE_TYPE (t));
+ break;
+
+ case IDENTIFIER_NODE:
+ case VOID_TYPE:
+ case BOOLEAN_TYPE:
+ case INTEGER_TYPE:
+ case REAL_TYPE:
+ case ENUMERAL_TYPE:
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case VECTOR_TYPE:
+ case COMPLEX_TYPE:
+ case TYPE_DECL:
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ break;
+ }
}
+/* type-name:
+ specifier-qualifier-list abstract-declarator(opt) */
-static inline void
-pp_c_type_id (ppi, t)
- c_pretty_printer ppi;
- tree t;
+void
+pp_c_type_id (c_pretty_printer *pp, tree t)
{
- pp_c_specifier_qualifier_list (ppi, t);
- pp_c_abstract_declarator (ppi, t);
+ pp_c_specifier_qualifier_list (pp, t);
+ pp_abstract_declarator (pp, t);
}
-static inline void
-pp_c_storage_class_specifier (pp, t)
- c_pretty_printer pp;
- tree t;
+/* storage-class-specifier:
+ typedef
+ extern
+ static
+ auto
+ register */
+
+void
+pp_c_storage_class_specifier (c_pretty_printer *pp, tree t)
{
if (TREE_CODE (t) == TYPE_DECL)
pp_c_identifier (pp, "typedef");
- else if (DECL_REGISTER (t))
- pp_c_identifier (pp, "register");
+ else if (DECL_P (t))
+ {
+ if (DECL_REGISTER (t))
+ pp_c_identifier (pp, "register");
+ else if (TREE_STATIC (t) && TREE_CODE (t) == VAR_DECL)
+ pp_c_identifier (pp, "static");
+ }
}
-static inline void
-pp_c_function_specifier (pp, t)
- c_pretty_printer pp;
- tree t;
+/* function-specifier:
+ inline */
+
+void
+pp_c_function_specifier (c_pretty_printer *pp, tree t)
{
if (TREE_CODE (t) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (t))
pp_c_identifier (pp, "inline");
}
-static inline void
-pp_c_declaration_specifiers (pp, t)
- c_pretty_printer pp;
- tree t;
-{
- pp_c_storage_class_specifier (pp, t);
- pp_c_function_specifier (pp, t);
- pp_type_specifier (pp, TYPE_MAIN_VARIANT (TREE_TYPE (t)));
- pp_c_cv_qualifier (pp, TYPE_QUALS (TREE_TYPE (t)));
-}
+/* declaration-specifiers:
+ storage-class-specifier declaration-specifiers(opt)
+ type-specifier declaration-specifiers(opt)
+ type-qualifier declaration-specifiers(opt)
+ function-specifier declaration-specifiers(opt) */
-static inline void
-pp_c_direct_declarator (pp, t)
- c_pretty_printer pp;
- tree t;
+void
+pp_c_declaration_specifiers (c_pretty_printer *pp, tree t)
{
- pp_unsupported_tree (pp, t);
+ pp_storage_class_specifier (pp, t);
+ pp_function_specifier (pp, t);
+ pp_c_specifier_qualifier_list (pp, DECL_P (t) ? TREE_TYPE (t) : t);
}
-static inline void
-pp_c_declarator (pp, t)
- c_pretty_printer pp;
- tree t;
+/* direct-declarator
+ identifier
+ ( declarator )
+ direct-declarator [ type-qualifier-list(opt) assignment-expression(opt) ]
+ direct-declarator [ static type-qualifier-list(opt) assignment-expression(opt)]
+ direct-declarator [ type-qualifier-list static assignment-expression ]
+ direct-declarator [ type-qualifier-list * ]
+ direct-declaratpr ( parameter-type-list )
+ direct-declarator ( identifier-list(opt) ) */
+
+void
+pp_c_direct_declarator (c_pretty_printer *pp, tree t)
{
- pp_unsupported_tree (pp, t);
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case TYPE_DECL:
+ case FIELD_DECL:
+ case LABEL_DECL:
+ if (DECL_NAME (t))
+ {
+ pp_c_space_for_pointer_operator (pp, TREE_TYPE (t));
+ pp_c_tree_identifier (pp, DECL_NAME (t));
+ }
+ case ARRAY_TYPE:
+ case POINTER_TYPE:
+ pp_abstract_declarator (pp, TREE_TYPE (t));
+ break;
+
+ case FUNCTION_TYPE:
+ pp_parameter_list (pp, t);
+ pp_abstract_declarator (pp, TREE_TYPE (t));
+ break;
+
+ case FUNCTION_DECL:
+ pp_c_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
+ pp_c_tree_identifier (pp, DECL_NAME (t));
+ if (pp_c_base (pp)->flags & pp_c_flag_abstract)
+ pp_abstract_declarator (pp, TREE_TYPE (t));
+ else
+ {
+ pp_parameter_list (pp, t);
+ pp_abstract_declarator (pp, TREE_TYPE (TREE_TYPE (t)));
+ }
+ break;
+
+ case INTEGER_TYPE:
+ case REAL_TYPE:
+ case ENUMERAL_TYPE:
+ case UNION_TYPE:
+ case RECORD_TYPE:
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ break;
+ }
}
-static inline void
-pp_c_init_declarator (pp, t)
- c_pretty_printer pp;
- tree t;
+
+/* declarator:
+ pointer(opt) direct-declarator */
+
+void
+pp_c_declarator (c_pretty_printer *pp, tree t)
{
- pp_declarator (pp, t);
- if (DECL_INITIAL (t))
+ switch (TREE_CODE (t))
{
- pp_whitespace (pp);
- pp_equal (pp);
- pp_whitespace (pp);
- pp_c_initializer (pp, DECL_INITIAL (t));
+ case INTEGER_TYPE:
+ case REAL_TYPE:
+ case ENUMERAL_TYPE:
+ case UNION_TYPE:
+ case RECORD_TYPE:
+ break;
+
+ case VAR_DECL:
+ case PARM_DECL:
+ case FIELD_DECL:
+ case ARRAY_TYPE:
+ case FUNCTION_TYPE:
+ case FUNCTION_DECL:
+ case TYPE_DECL:
+ pp_direct_declarator (pp, t);
+ break;
+
+
+ default:
+ pp_unsupported_tree (pp, t);
+ break;
}
}
+/* declaration:
+ declaration-specifiers init-declarator-list(opt) ; */
+
void
-pp_c_declaration (pp, t)
- c_pretty_printer pp;
- tree t;
+pp_c_declaration (c_pretty_printer *pp, tree t)
{
pp_declaration_specifiers (pp, t);
pp_c_init_declarator (pp, t);
}
-static void
-pp_c_parameter_declaration (pp, t)
- c_pretty_printer pp;
- tree t;
-{
- pp_unsupported_tree (pp, t);
-}
-
/* Pretty-print ATTRIBUTES using GNU C extension syntax. */
-void
-pp_c_attributes (pp, attributes)
- c_pretty_printer pp;
- tree attributes;
+
+void
+pp_c_attributes (c_pretty_printer *pp, tree attributes)
{
if (attributes == NULL_TREE)
return;
-
+
pp_c_identifier (pp, "__attribute__");
- pp_c_left_paren (pp);
+ pp_c_left_paren (pp);
pp_c_left_paren (pp);
for (; attributes != NULL_TREE; attributes = TREE_CHAIN (attributes))
{
pp_tree_identifier (pp, TREE_PURPOSE (attributes));
if (TREE_VALUE (attributes))
- {
- pp_c_left_paren (pp);
- pp_c_expression_list (pp, TREE_VALUE (attributes));
- pp_c_right_paren (pp);
- }
-
+ pp_c_call_argument_list (pp, TREE_VALUE (attributes));
+
if (TREE_CHAIN (attributes))
pp_separate_with (pp, ',');
}
@@ -288,223 +660,285 @@ pp_c_attributes (pp, attributes)
pp_c_right_paren (pp);
}
+/* function-definition:
+ declaration-specifiers declarator compound-statement */
+
+void
+pp_c_function_definition (c_pretty_printer *pp, tree t)
+{
+ pp_declaration_specifiers (pp, t);
+ pp_declarator (pp, t);
+ pp_needs_newline (pp) = true;
+ pp_statement (pp, DECL_SAVED_TREE (t));
+ pp_newline (pp);
+ pp_flush (pp);
+}
+
/* Expressions. */
/* Print out a c-char. */
+
static void
-pp_c_char (ppi, c)
- c_pretty_printer ppi;
- int c;
+pp_c_char (c_pretty_printer *pp, int c)
{
switch (c)
{
case TARGET_NEWLINE:
- pp_identifier (ppi, "\\n");
+ pp_string (pp, "\\n");
break;
case TARGET_TAB:
- pp_identifier (ppi, "\\t");
+ pp_string (pp, "\\t");
break;
case TARGET_VT:
- pp_identifier (ppi, "\\v");
+ pp_string (pp, "\\v");
break;
case TARGET_BS:
- pp_identifier (ppi, "\\b");
+ pp_string (pp, "\\b");
break;
case TARGET_CR:
- pp_identifier (ppi, "\\r");
+ pp_string (pp, "\\r");
break;
case TARGET_FF:
- pp_identifier (ppi, "\\f");
+ pp_string (pp, "\\f");
break;
case TARGET_BELL:
- pp_identifier (ppi, "\\a");
+ pp_string (pp, "\\a");
break;
case '\\':
- pp_identifier (ppi, "\\\\");
+ pp_string (pp, "\\\\");
break;
case '\'':
- pp_identifier (ppi, "\\'");
+ pp_string (pp, "\\'");
break;
case '\"':
- pp_identifier (ppi, "\\\"");
+ pp_string (pp, "\\\"");
break;
default:
if (ISPRINT (c))
- pp_character (ppi, c);
+ pp_character (pp, c);
else
- pp_format_scalar (ppi, "\\%03o", (unsigned) c);
+ pp_scalar (pp, "\\%03o", (unsigned) c);
break;
}
}
/* Print out a STRING literal. */
-static inline void
-pp_c_string_literal (ppi, s)
- c_pretty_printer ppi;
- tree s;
+
+void
+pp_c_string_literal (c_pretty_printer *pp, tree s)
{
const char *p = TREE_STRING_POINTER (s);
int n = TREE_STRING_LENGTH (s) - 1;
int i;
- pp_doublequote (ppi);
+ pp_doublequote (pp);
for (i = 0; i < n; ++i)
- pp_c_char (ppi, p[i]);
- pp_doublequote (ppi);
+ pp_c_char (pp, p[i]);
+ pp_doublequote (pp);
+}
+
+static void
+pp_c_integer_constant (c_pretty_printer *pp, tree i)
+{
+ tree type = TREE_TYPE (i);
+
+ if (TREE_INT_CST_HIGH (i) == 0)
+ pp_wide_integer (pp, TREE_INT_CST_LOW (i));
+ else
+ {
+ if (tree_int_cst_sgn (i) < 0)
+ {
+ pp_c_char (pp, '-');
+ i = build_int_2 (-TREE_INT_CST_LOW (i),
+ ~TREE_INT_CST_HIGH (i) + !TREE_INT_CST_LOW (i));
+ }
+ sprintf (pp_buffer (pp)->digit_buffer,
+ HOST_WIDE_INT_PRINT_DOUBLE_HEX,
+ TREE_INT_CST_HIGH (i), TREE_INT_CST_LOW (i));
+ pp_string (pp, pp_buffer (pp)->digit_buffer);
+ }
+ if (TREE_UNSIGNED (type))
+ pp_character (pp, 'u');
+ if (type == long_integer_type_node || type == long_unsigned_type_node)
+ pp_character (pp, 'l');
+ else if (type == long_long_integer_type_node
+ || type == long_long_unsigned_type_node)
+ pp_string (pp, "ll");
}
/* Print out a CHARACTER literal. */
-static inline void
-pp_c_character_literal (ppi, c)
- c_pretty_printer ppi;
- tree c;
+
+static void
+pp_c_character_constant (c_pretty_printer *pp, tree c)
{
- pp_quote (ppi);
- pp_c_char (ppi, tree_low_cst (c, 0));
- pp_quote (ppi);
+ tree type = TREE_TYPE (c);
+ if (type == wchar_type_node)
+ pp_character (pp, 'L');
+ pp_quote (pp);
+ if (host_integerp (c, TREE_UNSIGNED (type)))
+ pp_c_char (pp, tree_low_cst (c, TREE_UNSIGNED (type)));
+ else
+ pp_scalar (pp, "\\x%x", (unsigned) TREE_INT_CST_LOW (c));
+ pp_quote (pp);
}
/* Print out a BOOLEAN literal. */
-static inline void
-pp_c_bool_literal (ppi, b)
- c_pretty_printer ppi;
- tree b;
+
+static void
+pp_c_bool_constant (c_pretty_printer *pp, tree b)
{
- if (b == boolean_false_node || integer_zerop (b))
+ if (b == boolean_false_node)
{
- if (c_language == clk_cplusplus)
- pp_c_identifier (ppi, "false");
- else if (c_language == clk_c && flag_isoc99)
- pp_c_identifier (ppi, "_False");
+ if (c_dialect_cxx ())
+ pp_c_identifier (pp, "false");
+ else if (flag_isoc99)
+ pp_c_identifier (pp, "_False");
else
- pp_unsupported_tree (ppi, b);
+ pp_unsupported_tree (pp, b);
}
else if (b == boolean_true_node)
{
- if (c_language == clk_cplusplus)
- pp_c_identifier (ppi, "true");
- else if (c_language == clk_c && flag_isoc99)
- pp_c_identifier (ppi, "_True");
+ if (c_dialect_cxx ())
+ pp_c_identifier (pp, "true");
+ else if (flag_isoc99)
+ pp_c_identifier (pp, "_True");
else
- pp_unsupported_tree (ppi, b);
+ pp_unsupported_tree (pp, b);
}
+ else if (TREE_CODE (b) == INTEGER_CST)
+ pp_c_integer_constant (pp, b);
else
- pp_unsupported_tree (ppi, b);
+ pp_unsupported_tree (pp, b);
}
-/* Attempt to print out an ENUMERATOR. Return true on success. Else return
+/* Attempt to print out an ENUMERATOR. Return true on success. Else return
false; that means the value was obtained by a cast, in which case
print out the type-id part of the cast-expression -- the casted value
is then printed by pp_c_integer_literal. */
+
static bool
-pp_c_enumerator (ppi, e)
- c_pretty_printer ppi;
- tree e;
+pp_c_enumeration_constant (c_pretty_printer *pp, tree e)
{
+ bool value_is_named = true;
tree type = TREE_TYPE (e);
tree value;
/* Find the name of this constant. */
- for (value = TYPE_VALUES (type);
+ for (value = TYPE_VALUES (type);
value != NULL_TREE && !tree_int_cst_equal (TREE_VALUE (value), e);
value = TREE_CHAIN (value))
;
-
+
if (value != NULL_TREE)
- pp_c_tree_identifier (ppi, TREE_PURPOSE (value));
+ pp_id_expression (pp, TREE_PURPOSE (value));
else
{
/* Value must have been cast. */
- pp_c_left_paren (ppi);
- pp_type_id (ppi, type);
- pp_c_right_paren (ppi);
- return false;
+ pp_c_type_cast (pp, type);
+ value_is_named = false;
}
-
- return true;
+
+ return value_is_named;
}
-/* Print out an INTEGER constant value. */
+/* Print out a REAL value as a decimal-floating-constant. */
+
static void
-pp_c_integer_literal (ppi, i)
- c_pretty_printer ppi;
- tree i;
+pp_c_floating_constant (c_pretty_printer *pp, tree r)
{
- tree type = TREE_TYPE (i);
-
- if (type == boolean_type_node)
- pp_c_bool_literal (ppi, i);
- else if (type == char_type_node)
- pp_c_character_literal (ppi, i);
- else if (TREE_CODE (type) == ENUMERAL_TYPE
- && pp_c_enumerator (ppi, i))
- ;
- else
- {
- if (host_integerp (i, 0))
- pp_wide_integer (ppi, TREE_INT_CST_LOW (i));
- else
- {
- if (tree_int_cst_sgn (i) < 0)
- {
- static char format[10]; /* "%x%09999x\0" */
- if (!format[0])
- sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
-
- pp_c_char (ppi, '-');
- i = build_int_2 (-TREE_INT_CST_LOW (i),
- ~TREE_INT_CST_HIGH (i) + !TREE_INT_CST_LOW (i));
- sprintf (pp_buffer (ppi)->digit_buffer, format,
- TREE_INT_CST_HIGH (i), TREE_INT_CST_LOW (i));
- pp_identifier (ppi, pp_buffer (ppi)->digit_buffer);
-
- }
- }
- }
+ real_to_decimal (pp_buffer (pp)->digit_buffer, &TREE_REAL_CST (r),
+ sizeof (pp_buffer (pp)->digit_buffer), 0, 1);
+ pp_string (pp, pp_buffer(pp)->digit_buffer);
+ if (TREE_TYPE (r) == float_type_node)
+ pp_character (pp, 'f');
+ else if (TREE_TYPE (r) == long_double_type_node)
+ pp_character (pp, 'l');
}
-/* Print out a REAL value. */
-static inline void
-pp_c_real_literal (ppi, r)
- c_pretty_printer ppi;
- tree r;
+/* Pretty-print a compound literal expression. GNU extensions include
+ vector constants. */
+
+static void
+pp_c_compound_literal (c_pretty_printer *pp, tree e)
{
- real_to_decimal (pp_buffer (ppi)->digit_buffer, &TREE_REAL_CST (r),
- sizeof (pp_buffer (ppi)->digit_buffer), 0, 1);
- pp_identifier (ppi, pp_buffer(ppi)->digit_buffer);
+ tree type = TREE_TYPE (e);
+ pp_c_type_cast (pp, type);
+
+ switch (TREE_CODE (type))
+ {
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ARRAY_TYPE:
+ case VECTOR_TYPE:
+ case COMPLEX_TYPE:
+ pp_c_brace_enclosed_initializer_list (pp, e);
+ break;
+
+ default:
+ pp_unsupported_tree (pp, e);
+ break;
+ }
}
+/* constant:
+ integer-constant
+ floating-constant
+ enumeration-constant
+ character-constant */
void
-pp_c_literal (ppi, e)
- c_pretty_printer ppi;
- tree e;
+pp_c_constant (c_pretty_printer *pp, tree e)
{
- switch (TREE_CODE (e))
+ const enum tree_code code = TREE_CODE (e);
+
+ switch (code)
{
case INTEGER_CST:
- pp_c_integer_literal (ppi, e);
+ {
+ tree type = TREE_TYPE (e);
+ if (type == boolean_type_node)
+ pp_c_bool_constant (pp, e);
+ else if (type == char_type_node)
+ pp_c_character_constant (pp, e);
+ else if (TREE_CODE (type) == ENUMERAL_TYPE
+ && pp_c_enumeration_constant (pp, e))
+ ;
+ else
+ pp_c_integer_constant (pp, e);
+ }
break;
-
+
case REAL_CST:
- pp_c_real_literal (ppi, e);
+ pp_c_floating_constant (pp, e);
break;
-
+
case STRING_CST:
- pp_c_string_literal (ppi, e);
- break;
+ pp_c_string_literal (pp, e);
+ break;
default:
- pp_unsupported_tree (ppi, e);
+ pp_unsupported_tree (pp, e);
break;
}
}
-/* Pretty-print a C primary-expression. */
-static void
-pp_c_primary_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+void
+pp_c_identifier (c_pretty_printer *pp, const char *id)
+{
+ pp_c_maybe_whitespace (pp);
+ pp_identifier (pp, id);
+ pp_base (pp)->padding = pp_before;
+}
+
+/* Pretty-print a C primary-expression.
+ primary-expression:
+ identifier
+ constant
+ string-literal
+ ( expression ) */
+
+void
+pp_c_primary_expression (c_pretty_printer *pp, tree e)
{
switch (TREE_CODE (e))
{
@@ -517,153 +951,246 @@ pp_c_primary_expression (ppi, e)
e = DECL_NAME (e);
/* Fall through. */
case IDENTIFIER_NODE:
- pp_c_tree_identifier (ppi, e);
+ pp_c_tree_identifier (pp, e);
break;
case ERROR_MARK:
- pp_c_identifier (ppi, "<erroneous-expression>");
+ pp_c_identifier (pp, "<erroneous-expression>");
break;
-
+
case RESULT_DECL:
- pp_c_identifier (ppi, "<return-value>");
+ pp_c_identifier (pp, "<return-value>");
break;
case INTEGER_CST:
case REAL_CST:
case STRING_CST:
- pp_c_literal (ppi, e);
+ pp_c_constant (pp, e);
break;
- case TARGET_EXPR:
- pp_c_left_paren (ppi);
- pp_c_identifier (ppi, "__builtin_memcpy");
- pp_c_left_paren (ppi);
- pp_ampersand (ppi);
- pp_c_primary_expression (ppi, TREE_OPERAND (e, 0));
- pp_separate_with (ppi, ',');
- pp_ampersand (ppi);
- pp_initializer (ppi, TREE_OPERAND (e, 1));
- if (TREE_OPERAND (e, 2))
- {
- pp_separate_with (ppi, ',');
- pp_c_expression (ppi, TREE_OPERAND (e, 2));
- }
- pp_c_right_paren (ppi);
-
case STMT_EXPR:
- pp_c_left_paren (ppi);
- pp_statement (ppi, STMT_EXPR_STMT (e));
- pp_c_right_paren (ppi);
+ pp_c_left_paren (pp);
+ pp_statement (pp, STMT_EXPR_STMT (e));
+ pp_c_right_paren (pp);
break;
default:
- /* Make sure this call won't cause any infinite loop. */
- pp_c_left_paren (ppi);
- pp_c_expression (ppi, e);
- pp_c_right_paren (ppi);
+ /* FIXME: Make sure we won't get into an infinie loop. */
+ pp_c_left_paren (pp);
+ pp_expression (pp, e);
+ pp_c_right_paren (pp);
break;
}
}
-/* Print out a C initializer -- also support C compound-literals. */
-void
-pp_c_initializer (ppi, e)
- c_pretty_printer ppi;
- tree e;
+/* Print out a C initializer -- also support C compound-literals.
+ initializer:
+ assignment-expression:
+ { initializer-list }
+ { initializer-list , } */
+
+static void
+pp_c_initializer (c_pretty_printer *pp, tree e)
{
if (TREE_CODE (e) == CONSTRUCTOR)
{
enum tree_code code = TREE_CODE (TREE_TYPE (e));
if (code == RECORD_TYPE || code == UNION_TYPE || code == ARRAY_TYPE)
- {
- pp_left_brace (ppi);
- pp_c_initializer_list (ppi, e);
- pp_right_brace (ppi);
- }
+ pp_c_brace_enclosed_initializer_list (pp, e);
else
- pp_unsupported_tree (ppi, TREE_OPERAND (e, 1));
+ pp_unsupported_tree (pp, TREE_OPERAND (e, 1));
}
else
- pp_assignment_expression (ppi, e);
+ pp_expression (pp, e);
+}
+
+/* init-declarator:
+ declarator:
+ declarator = initializer */
+
+void
+pp_c_init_declarator (c_pretty_printer *pp, tree t)
+{
+ pp_declarator (pp, t);
+ if (DECL_INITIAL (t))
+ {
+ tree init = DECL_INITIAL (t);
+ /* This C++ bit is handled here because it is easier to do so.
+ In templates, the C++ parser builds a TREE_LIST for a
+ direct-initialization; the TREE_PURPOSE is the variable to
+ initialize and the TREE_VALUE is the initializer. */
+ if (TREE_CODE (init) == TREE_LIST)
+ {
+ pp_c_left_paren (pp);
+ pp_expression (pp, TREE_VALUE (init));
+ pp_right_paren (pp);
+ }
+ else
+ {
+ pp_space (pp);
+ pp_equal (pp);
+ pp_space (pp);
+ pp_c_initializer (pp, init);
+ }
+ }
}
+/* initializer-list:
+ designation(opt) initializer
+ initializer-list , designation(opt) initializer
+
+ designation:
+ designator-list =
+
+ designator-list:
+ designator
+ designator-list designator
+
+ designator:
+ [ constant-expression ]
+ identifier */
+
static void
-pp_c_initializer_list (ppi, e)
- c_pretty_printer ppi;
- tree e;
+pp_c_initializer_list (c_pretty_printer *pp, tree e)
{
tree type = TREE_TYPE (e);
const enum tree_code code = TREE_CODE (type);
- if (code == RECORD_TYPE || code == UNION_TYPE || code == ARRAY_TYPE)
+ switch (code)
{
- tree init = TREE_OPERAND (e, 1);
- for (; init != NULL_TREE; init = TREE_CHAIN (init))
- {
- if (code == RECORD_TYPE || code == UNION_TYPE)
- {
- pp_dot (ppi);
- pp_c_primary_expression (ppi, TREE_PURPOSE (init));
- }
- else
- {
- pp_c_left_bracket (ppi);
- if (TREE_PURPOSE (init))
- pp_c_literal (ppi, TREE_PURPOSE (init));
- pp_c_right_bracket (ppi);
- }
- pp_c_whitespace (ppi);
- pp_equal (ppi);
- pp_c_whitespace (ppi);
- pp_initializer (ppi, TREE_VALUE (init));
- if (TREE_CHAIN (init))
- pp_separate_with (ppi, ',');
- }
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ARRAY_TYPE:
+ {
+ tree init = TREE_OPERAND (e, 0);
+ for (; init != NULL_TREE; init = TREE_CHAIN (init))
+ {
+ if (code == RECORD_TYPE || code == UNION_TYPE)
+ {
+ pp_c_dot (pp);
+ pp_c_primary_expression (pp, TREE_PURPOSE (init));
+ }
+ else
+ {
+ pp_c_left_bracket (pp);
+ if (TREE_PURPOSE (init))
+ pp_c_constant (pp, TREE_PURPOSE (init));
+ pp_c_right_bracket (pp);
+ }
+ pp_c_whitespace (pp);
+ pp_equal (pp);
+ pp_c_whitespace (pp);
+ pp_initializer (pp, TREE_VALUE (init));
+ if (TREE_CHAIN (init))
+ pp_separate_with (pp, ',');
+ }
+ }
+ break;
+
+ case VECTOR_TYPE:
+ pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e));
+ break;
+
+ case COMPLEX_TYPE:
+ {
+ const bool cst = TREE_CODE (e) == COMPLEX_CST;
+ pp_expression (pp, cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0));
+ pp_separate_with (pp, ',');
+ pp_expression (pp, cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1));
+ }
+ break;
+
+ default:
+ pp_unsupported_tree (pp, type);
+ break;
+ }
+}
+
+/* Pretty-print a brace-enclosed initializer-list. */
+
+static void
+pp_c_brace_enclosed_initializer_list (c_pretty_printer *pp, tree l)
+{
+ pp_c_left_brace (pp);
+ pp_c_initializer_list (pp, l);
+ pp_c_right_brace (pp);
+}
+
+
+/* This is a convenient function, used to bridge gap between C and C++
+ grammars.
+
+ id-expression:
+ identifier */
+
+void
+pp_c_id_expression (c_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case CONST_DECL:
+ case TYPE_DECL:
+ case FUNCTION_DECL:
+ case FIELD_DECL:
+ case LABEL_DECL:
+ t = DECL_NAME (t);
+ case IDENTIFIER_NODE:
+ pp_c_tree_identifier (pp, t);
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ break;
}
- else
- pp_unsupported_tree (ppi, type);
}
+/* postfix-expression:
+ primary-expression
+ postfix-expression [ expression ]
+ postfix-expression ( argument-expression-list(opt) )
+ postfix-expression . identifier
+ postfix-expression -> identifier
+ postfix-expression ++
+ postfix-expression --
+ ( type-name ) { initializer-list }
+ ( type-name ) { initializer-list , } */
+
void
-pp_c_postfix_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+pp_c_postfix_expression (c_pretty_printer *pp, tree e)
{
enum tree_code code = TREE_CODE (e);
switch (code)
{
case POSTINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
- pp_postfix_expression (ppi, TREE_OPERAND (e, 0));
- pp_identifier (ppi, code == POSTINCREMENT_EXPR ? "++" : "--");
+ pp_postfix_expression (pp, TREE_OPERAND (e, 0));
+ pp_identifier (pp, code == POSTINCREMENT_EXPR ? "++" : "--");
break;
-
+
case ARROW_EXPR:
- pp_postfix_expression (ppi, TREE_OPERAND (e, 0));
- pp_arrow (ppi);
+ pp_postfix_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_arrow (pp);
break;
case ARRAY_REF:
- pp_postfix_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_left_bracket (ppi);
- pp_c_expression (ppi, TREE_OPERAND (e, 1));
- pp_c_right_bracket (ppi);
+ pp_postfix_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_left_bracket (pp);
+ pp_expression (pp, TREE_OPERAND (e, 1));
+ pp_c_right_bracket (pp);
break;
case CALL_EXPR:
- pp_postfix_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_left_paren (ppi);
- pp_c_expression_list (ppi, TREE_OPERAND (e, 1));
- pp_c_right_paren (ppi);
+ pp_postfix_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_call_argument_list (pp, TREE_OPERAND (e, 1));
break;
case ABS_EXPR:
- case FFS_EXPR:
- pp_c_identifier (ppi,
- code == ABS_EXPR ? "__builtin_abs" : "__builtin_ffs");
- pp_c_left_paren (ppi);
- pp_c_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_right_paren (ppi);
+ pp_c_identifier (pp, "__builtin_abs");
+ pp_c_left_paren (pp);
+ pp_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_right_paren (pp);
break;
case COMPONENT_REF:
@@ -671,185 +1198,180 @@ pp_c_postfix_expression (ppi, e)
tree object = TREE_OPERAND (e, 0);
if (TREE_CODE (object) == INDIRECT_REF)
{
- pp_postfix_expression (ppi, TREE_OPERAND (object, 0));
- pp_arrow (ppi);
+ pp_postfix_expression (pp, TREE_OPERAND (object, 0));
+ pp_c_arrow (pp);
}
else
{
- pp_postfix_expression (ppi, object);
- pp_dot (ppi);
+ pp_postfix_expression (pp, object);
+ pp_c_dot (pp);
}
- pp_c_expression (ppi, TREE_OPERAND (e, 1));
+ pp_expression (pp, TREE_OPERAND (e, 1));
}
break;
case COMPLEX_CST:
case VECTOR_CST:
case COMPLEX_EXPR:
- pp_c_left_paren (ppi);
- pp_type_id (ppi, TREE_TYPE (e));
- pp_c_right_paren (ppi);
- pp_left_brace (ppi);
-
- if (code == COMPLEX_CST)
- {
- pp_c_expression (ppi, TREE_REALPART (e));
- pp_separate_with (ppi, ',');
- pp_c_expression (ppi, TREE_IMAGPART (e));
- }
- else if (code == VECTOR_CST)
- pp_c_expression_list (ppi, TREE_VECTOR_CST_ELTS (e));
- else if (code == COMPLEX_EXPR)
- {
- pp_c_expression (ppi, TREE_OPERAND (e, 0));
- pp_separate_with (ppi, ',');
- pp_c_expression (ppi, TREE_OPERAND (e, 1));
- }
-
- pp_right_brace (ppi);
+ pp_c_compound_literal (pp, e);
break;
case COMPOUND_LITERAL_EXPR:
- e = DECL_INITIAL (e);
+ e = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (e));
/* Fall through. */
case CONSTRUCTOR:
- pp_initializer (ppi, e);
+ pp_initializer (pp, e);
break;
-
-#if 0
- case SRCLOC:
- pp_left_paren (ppi);
- pp_identifier (ppi, "__location__");
- pp_right_paren (ppi);
- pp_whitespace (ppi);
- pp_left_brace (ppi);
- pp_dot (ppi);
- pp_identifier (ppi, "file");
- pp_whitespace (ppi);
- pp_equal (ppi);
- pp_c_whitespace (ppi);
- pp_c_expression (ppi, SRCLOC_FILE (e));
- pp_separate_with (ppi, ',');
- pp_dot (ppi);
- pp_identifier (ppi, "line");
- pp_whitespace (ppi);
- pp_equal (ppi);
- pp_c_whitespace (ppi);
- pp_c_expression (ppi, SRCLOC_LINE (e));
- pp_right_brace (ppi);
- break;
-#endif
case VA_ARG_EXPR:
- pp_c_identifier (ppi, "__builtin_va_arg");
- pp_c_left_paren (ppi);
- pp_assignment_expression (ppi, TREE_OPERAND (e, 0));
- pp_separate_with (ppi, ',');
- pp_type_id (ppi, TREE_TYPE (e));
- pp_c_right_paren (ppi);
+ pp_c_identifier (pp, "__builtin_va_arg");
+ pp_c_left_paren (pp);
+ pp_assignment_expression (pp, TREE_OPERAND (e, 0));
+ pp_separate_with (pp, ',');
+ pp_type_id (pp, TREE_TYPE (e));
+ pp_c_right_paren (pp);
break;
+ case ADDR_EXPR:
+ if (TREE_CODE (TREE_OPERAND (e, 0)) == FUNCTION_DECL)
+ {
+ pp_c_id_expression (pp, TREE_OPERAND (e, 0));
+ break;
+ }
+ /* else fall through. */
+
default:
- pp_primary_expression (ppi, e);
+ pp_primary_expression (pp, e);
break;
}
}
-/* Print out an expression-list; E is expected to be a TREE_LIST */
+/* Print out an expression-list; E is expected to be a TREE_LIST. */
+
void
-pp_c_expression_list (ppi, e)
- c_pretty_printer ppi;
- tree e;
+pp_c_expression_list (c_pretty_printer *pp, tree e)
{
for (; e != NULL_TREE; e = TREE_CHAIN (e))
{
- pp_c_assignment_expression (ppi, TREE_VALUE (e));
+ pp_expression (pp, TREE_VALUE (e));
if (TREE_CHAIN (e))
- pp_separate_with (ppi, ',');
+ pp_separate_with (pp, ',');
}
}
-static void
-pp_c_unary_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+/* Print out an expression-list in parens, as in a function call. */
+
+void
+pp_c_call_argument_list (c_pretty_printer *pp, tree t)
+{
+ pp_c_left_paren (pp);
+ if (t && TREE_CODE (t) == TREE_LIST)
+ pp_c_expression_list (pp, t);
+ pp_c_right_paren (pp);
+}
+
+/* unary-expression:
+ postfix-expression
+ ++ cast-expression
+ -- cast-expression
+ unary-operator cast-expression
+ sizeof unary-expression
+ sizeof ( type-id )
+
+ unary-operator: one of
+ * & + - ! ~
+
+ GNU extensions.
+ unary-expression:
+ __alignof__ unary-expression
+ __alignof__ ( type-id )
+ __real__ unary-expression
+ __imag__ unary-expression */
+
+void
+pp_c_unary_expression (c_pretty_printer *pp, tree e)
{
enum tree_code code = TREE_CODE (e);
switch (code)
{
case PREINCREMENT_EXPR:
case PREDECREMENT_EXPR:
- pp_identifier (ppi, code == PREINCREMENT_EXPR ? "++" : "--");
- pp_c_unary_expression (ppi, TREE_OPERAND (e, 0));
+ pp_identifier (pp, code == PREINCREMENT_EXPR ? "++" : "--");
+ pp_c_unary_expression (pp, TREE_OPERAND (e, 0));
break;
-
+
case ADDR_EXPR:
case INDIRECT_REF:
- case CONVERT_EXPR:
case NEGATE_EXPR:
case BIT_NOT_EXPR:
case TRUTH_NOT_EXPR:
case CONJ_EXPR:
- if (code == ADDR_EXPR)
- pp_ampersand (ppi);
+ /* String literal are used by address. */
+ if (code == ADDR_EXPR && TREE_CODE (TREE_OPERAND (e, 0)) != STRING_CST)
+ pp_ampersand (pp);
else if (code == INDIRECT_REF)
- pp_star (ppi);
+ pp_c_star (pp);
else if (code == NEGATE_EXPR)
- pp_minus (ppi);
+ pp_minus (pp);
else if (code == BIT_NOT_EXPR || code == CONJ_EXPR)
- pp_complement (ppi);
+ pp_complement (pp);
else if (code == TRUTH_NOT_EXPR)
- pp_exclamation (ppi);
- pp_c_cast_expression (ppi, TREE_OPERAND (e, 0));
+ pp_exclamation (pp);
+ pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
break;
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
- pp_c_identifier (ppi, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
- pp_c_whitespace (ppi);
+ pp_c_identifier (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
+ pp_c_whitespace (pp);
if (TYPE_P (TREE_OPERAND (e, 0)))
- {
- pp_c_left_paren (ppi);
- pp_type_id (ppi, TREE_OPERAND (e, 0));
- pp_c_right_paren (ppi);
- }
+ pp_c_type_cast (pp, TREE_OPERAND (e, 0));
else
- pp_c_unary_expression (ppi, TREE_OPERAND (e, 0));
+ pp_unary_expression (pp, TREE_OPERAND (e, 0));
break;
case REALPART_EXPR:
case IMAGPART_EXPR:
- pp_c_identifier (ppi, code == REALPART_EXPR ? "__real__" : "__imag__");
- pp_c_whitespace (ppi);
- pp_unary_expression (ppi, TREE_OPERAND (e, 0));
+ pp_c_identifier (pp, code == REALPART_EXPR ? "__real__" : "__imag__");
+ pp_c_whitespace (pp);
+ pp_unary_expression (pp, TREE_OPERAND (e, 0));
break;
-
+
default:
- pp_postfix_expression (ppi, e);
+ pp_postfix_expression (pp, e);
break;
}
}
+/* cast-expression:
+ unary-expression
+ ( type-name ) cast-expression */
+
void
-pp_c_cast_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+pp_c_cast_expression (c_pretty_printer *pp, tree e)
{
- if (TREE_CODE (e) == CONVERT_EXPR || TREE_CODE (e) == FLOAT_EXPR)
+ switch (TREE_CODE (e))
{
- pp_c_left_paren (ppi);
- pp_type_id (ppi, TREE_TYPE (e));
- pp_c_right_paren (ppi);
- pp_c_cast_expression (ppi, TREE_OPERAND (e, 0));
+ case FLOAT_EXPR:
+ case FIX_TRUNC_EXPR:
+ case CONVERT_EXPR:
+ pp_c_type_cast (pp, TREE_TYPE (e));
+ pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
+ break;
+
+ default:
+ pp_unary_expression (pp, e);
}
- else
- pp_unary_expression (ppi, e);
}
+/* multiplicative-expression:
+ cast-expression
+ multiplicative-expression * cast-expression
+ multiplicative-expression / cast-expression
+ multiplicative-expression % cast-expression */
+
static void
-pp_c_multiplicative_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+pp_c_multiplicative_expression (c_pretty_printer *pp, tree e)
{
enum tree_code code = TREE_CODE (e);
switch (code)
@@ -857,76 +1379,87 @@ pp_c_multiplicative_expression (ppi, e)
case MULT_EXPR:
case TRUNC_DIV_EXPR:
case TRUNC_MOD_EXPR:
- pp_c_multiplicative_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_whitespace (ppi);
+ pp_multiplicative_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_whitespace (pp);
if (code == MULT_EXPR)
- pp_star (ppi);
+ pp_c_star (pp);
else if (code == TRUNC_DIV_EXPR)
- pp_slash (ppi);
+ pp_slash (pp);
else
- pp_modulo (ppi);
- pp_c_whitespace (ppi);
- pp_c_cast_expression (ppi, TREE_OPERAND (e, 1));
+ pp_modulo (pp);
+ pp_c_whitespace (pp);
+ pp_c_cast_expression (pp, TREE_OPERAND (e, 1));
break;
default:
- pp_c_cast_expression (ppi, e);
+ pp_c_cast_expression (pp, e);
break;
}
}
-static inline void
-pp_c_additive_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+/* additive-expression:
+ multiplicative-expression
+ additive-expression + multiplicative-expression
+ additive-expression - multiplicative-expression */
+
+static void
+pp_c_additive_expression (c_pretty_printer *pp, tree e)
{
enum tree_code code = TREE_CODE (e);
switch (code)
{
case PLUS_EXPR:
case MINUS_EXPR:
- pp_c_additive_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_whitespace (ppi);
+ pp_c_additive_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_whitespace (pp);
if (code == PLUS_EXPR)
- pp_plus (ppi);
+ pp_plus (pp);
else
- pp_minus (ppi);
- pp_c_whitespace (ppi);
- pp_multiplicative_expression (ppi, TREE_OPERAND (e, 1));
+ pp_minus (pp);
+ pp_c_whitespace (pp);
+ pp_multiplicative_expression (pp, TREE_OPERAND (e, 1));
break;
default:
- pp_multiplicative_expression (ppi, e);
+ pp_multiplicative_expression (pp, e);
break;
}
}
-static inline void
-pp_c_shift_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+/* additive-expression:
+ additive-expression
+ shift-expression << additive-expression
+ shift-expression >> additive-expression */
+
+static void
+pp_c_shift_expression (c_pretty_printer *pp, tree e)
{
enum tree_code code = TREE_CODE (e);
switch (code)
{
case LSHIFT_EXPR:
case RSHIFT_EXPR:
- pp_c_shift_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_whitespace (ppi);
- pp_identifier (ppi, code == LSHIFT_EXPR ? "<<" : ">>");
- pp_c_whitespace (ppi);
- pp_c_additive_expression (ppi, TREE_OPERAND (e, 1));
+ pp_c_shift_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_whitespace (pp);
+ pp_identifier (pp, code == LSHIFT_EXPR ? "<<" : ">>");
+ pp_c_whitespace (pp);
+ pp_c_additive_expression (pp, TREE_OPERAND (e, 1));
break;
default:
- pp_c_additive_expression (ppi, e);
+ pp_c_additive_expression (pp, e);
}
}
+/* relational-expression:
+ shift-expression
+ relational-expression < shift-expression
+ relational-expression > shift-expression
+ relational-expression <= shift-expression
+ relational-expression >= shift-expression */
+
static void
-pp_c_relational_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+pp_c_relational_expression (c_pretty_printer *pp, tree e)
{
enum tree_code code = TREE_CODE (e);
switch (code)
@@ -935,194 +1468,221 @@ pp_c_relational_expression (ppi, e)
case GT_EXPR:
case LE_EXPR:
case GE_EXPR:
- pp_c_relational_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_whitespace (ppi);
+ pp_c_relational_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_whitespace (pp);
if (code == LT_EXPR)
- pp_less (ppi);
+ pp_less (pp);
else if (code == GT_EXPR)
- pp_greater (ppi);
+ pp_greater (pp);
else if (code == LE_EXPR)
- pp_identifier (ppi, "<=");
+ pp_identifier (pp, "<=");
else if (code == GE_EXPR)
- pp_identifier (ppi, ">=");
- pp_c_whitespace (ppi);
- pp_c_shift_expression (ppi, TREE_OPERAND (e, 1));
+ pp_identifier (pp, ">=");
+ pp_c_whitespace (pp);
+ pp_c_shift_expression (pp, TREE_OPERAND (e, 1));
break;
default:
- pp_c_shift_expression (ppi, e);
+ pp_c_shift_expression (pp, e);
break;
}
}
-static inline void
-pp_c_equality_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+/* equality-expression:
+ relational-expression
+ equality-expression == relational-expression
+ equality-equality != relational-expression */
+
+static void
+pp_c_equality_expression (c_pretty_printer *pp, tree e)
{
enum tree_code code = TREE_CODE (e);
switch (code)
{
case EQ_EXPR:
case NE_EXPR:
- pp_c_equality_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_maybe_whitespace (ppi);
- pp_identifier (ppi, code == EQ_EXPR ? "==" : "!=");
- pp_c_whitespace (ppi);
- pp_c_relational_expression (ppi, TREE_OPERAND (e, 1));
- break;
-
+ pp_c_equality_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_whitespace (pp);
+ pp_identifier (pp, code == EQ_EXPR ? "==" : "!=");
+ pp_c_whitespace (pp);
+ pp_c_relational_expression (pp, TREE_OPERAND (e, 1));
+ break;
+
default:
- pp_c_relational_expression (ppi, e);
+ pp_c_relational_expression (pp, e);
break;
}
}
-static inline void
-pp_c_and_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+/* AND-expression:
+ equality-expression
+ AND-expression & equality-equality */
+
+static void
+pp_c_and_expression (c_pretty_printer *pp, tree e)
{
if (TREE_CODE (e) == BIT_AND_EXPR)
{
- pp_c_and_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_maybe_whitespace (ppi);
- pp_ampersand (ppi);
- pp_c_whitespace (ppi);
- pp_c_equality_expression (ppi, TREE_OPERAND (e, 1));
+ pp_c_and_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_whitespace (pp);
+ pp_ampersand (pp);
+ pp_c_whitespace (pp);
+ pp_c_equality_expression (pp, TREE_OPERAND (e, 1));
}
else
- pp_c_equality_expression (ppi, e);
+ pp_c_equality_expression (pp, e);
}
-static inline void
-pp_c_exclusive_or_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+/* exclusive-OR-expression:
+ AND-expression
+ exclusive-OR-expression ^ AND-expression */
+
+static void
+pp_c_exclusive_or_expression (c_pretty_printer *pp, tree e)
{
if (TREE_CODE (e) == BIT_XOR_EXPR)
{
- pp_c_exclusive_or_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_maybe_whitespace (ppi);
- pp_carret (ppi);
- pp_c_whitespace (ppi);
- pp_c_and_expression (ppi, TREE_OPERAND (e, 1));
+ pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_maybe_whitespace (pp);
+ pp_carret (pp);
+ pp_c_whitespace (pp);
+ pp_c_and_expression (pp, TREE_OPERAND (e, 1));
}
else
- pp_c_and_expression (ppi, e);
+ pp_c_and_expression (pp, e);
}
-static inline void
-pp_c_inclusive_or_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+/* inclusive-OR-expression:
+ exclusive-OR-expression
+ inclusive-OR-expression | exclusive-OR-expression */
+
+static void
+pp_c_inclusive_or_expression (c_pretty_printer *pp, tree e)
{
if (TREE_CODE (e) == BIT_IOR_EXPR)
{
- pp_c_exclusive_or_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_maybe_whitespace (ppi);
- pp_bar (ppi);
- pp_c_whitespace (ppi);
- pp_c_exclusive_or_expression (ppi, TREE_OPERAND (e, 1));
+ pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_whitespace (pp);
+ pp_bar (pp);
+ pp_c_whitespace (pp);
+ pp_c_exclusive_or_expression (pp, TREE_OPERAND (e, 1));
}
else
- pp_c_exclusive_or_expression (ppi, e);
+ pp_c_exclusive_or_expression (pp, e);
}
-static inline void
-pp_c_logical_and_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+/* logical-AND-expression:
+ inclusive-OR-expression
+ logical-AND-expression && inclusive-OR-expression */
+
+static void
+pp_c_logical_and_expression (c_pretty_printer *pp, tree e)
{
if (TREE_CODE (e) == TRUTH_ANDIF_EXPR)
{
- pp_c_logical_and_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_maybe_whitespace (ppi);
- pp_identifier (ppi, "&&");
- pp_c_whitespace (ppi);
- pp_c_inclusive_or_expression (ppi, TREE_OPERAND (e, 1));
+ pp_c_logical_and_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_whitespace (pp);
+ pp_identifier (pp, "&&");
+ pp_c_whitespace (pp);
+ pp_c_inclusive_or_expression (pp, TREE_OPERAND (e, 1));
}
else
- pp_c_inclusive_or_expression (ppi, e);
+ pp_c_inclusive_or_expression (pp, e);
}
+/* logical-OR-expression:
+ logical-AND-expression
+ logical-OR-expression || logical-AND-expression */
+
void
-pp_c_logical_or_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+pp_c_logical_or_expression (c_pretty_printer *pp, tree e)
{
if (TREE_CODE (e) == TRUTH_ORIF_EXPR)
{
- pp_c_logical_or_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_maybe_whitespace (ppi);
- pp_identifier (ppi, "||");
- pp_c_whitespace (ppi);
- pp_c_logical_and_expression (ppi, TREE_OPERAND (e, 1));
+ pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_whitespace (pp);
+ pp_identifier (pp, "||");
+ pp_c_whitespace (pp);
+ pp_c_logical_and_expression (pp, TREE_OPERAND (e, 1));
}
else
- pp_c_logical_and_expression (ppi, e);
+ pp_c_logical_and_expression (pp, e);
}
+/* conditional-expression:
+ logical-OR-expression
+ logical-OR-expression ? expression : conditional-expression */
+
static void
-pp_c_conditional_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+pp_c_conditional_expression (c_pretty_printer *pp, tree e)
{
if (TREE_CODE (e) == COND_EXPR)
{
- pp_c_logical_or_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_maybe_whitespace (ppi);
- pp_question (ppi);
- pp_c_whitespace (ppi);
- pp_c_expression (ppi, TREE_OPERAND (e, 1));
- pp_c_maybe_whitespace (ppi);
- pp_colon (ppi);
- pp_c_whitespace (ppi);
- pp_c_conditional_expression (ppi, TREE_OPERAND (e, 2));
+ pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_whitespace (pp);
+ pp_question (pp);
+ pp_c_whitespace (pp);
+ pp_expression (pp, TREE_OPERAND (e, 1));
+ pp_c_whitespace (pp);
+ pp_colon (pp);
+ pp_c_whitespace (pp);
+ pp_c_conditional_expression (pp, TREE_OPERAND (e, 2));
}
else
- pp_c_logical_or_expression (ppi, e);
+ pp_c_logical_or_expression (pp, e);
}
-/* Pretty-print a C assignment-expression. */
+/* assignment-expression:
+ conditional-expression
+ unary-expression assignment-operator assignment-expression
+
+ assignment-expression: one of
+ = *= /= %= += -= >>= <<= &= ^= |= */
+
static void
-pp_c_assignment_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+pp_c_assignment_expression (c_pretty_printer *pp, tree e)
{
if (TREE_CODE (e) == MODIFY_EXPR || TREE_CODE (e) == INIT_EXPR)
{
- pp_c_unary_expression (ppi, TREE_OPERAND (e, 0));
- pp_c_maybe_whitespace (ppi);
- pp_equal (ppi);
- pp_whitespace (ppi);
- pp_c_assignment_expression (ppi, TREE_OPERAND (e, 1));
+ pp_c_unary_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_whitespace (pp);
+ pp_equal (pp);
+ pp_space (pp);
+ pp_c_expression (pp, TREE_OPERAND (e, 1));
}
else
- pp_c_conditional_expression (ppi, e);
+ pp_c_conditional_expression (pp, e);
}
-/* Pretty-print an expression. */
+/* expression:
+ assignment-expression
+ expression , assignment-expression
+
+ Implementation note: instead of going through the usual recursion
+ chain, I take the liberty of dispatching nodes to the appropriate
+ functions. This makes some redundancy, but it worths it. That also
+ prevents a possible infinite recursion between pp_c_primary_expression ()
+ and pp_c_expression (). */
+
void
-pp_c_expression (ppi, e)
- c_pretty_printer ppi;
- tree e;
+pp_c_expression (c_pretty_printer *pp, tree e)
{
switch (TREE_CODE (e))
{
case INTEGER_CST:
- pp_c_integer_literal (ppi, e);
+ pp_c_integer_constant (pp, e);
break;
-
+
case REAL_CST:
- pp_c_real_literal (ppi, e);
+ pp_c_floating_constant (pp, e);
break;
case STRING_CST:
- pp_c_string_literal (ppi, e);
+ pp_c_string_literal (pp, e);
break;
-
+
+ case IDENTIFIER_NODE:
case FUNCTION_DECL:
case VAR_DECL:
case CONST_DECL:
@@ -1131,9 +1691,8 @@ pp_c_expression (ppi, e)
case FIELD_DECL:
case LABEL_DECL:
case ERROR_MARK:
- case TARGET_EXPR:
case STMT_EXPR:
- pp_c_primary_expression (ppi, e);
+ pp_primary_expression (pp, e);
break;
case POSTINCREMENT_EXPR:
@@ -1143,14 +1702,13 @@ pp_c_expression (ppi, e)
case CALL_EXPR:
case COMPONENT_REF:
case COMPLEX_CST:
+ case COMPLEX_EXPR:
case VECTOR_CST:
case ABS_EXPR:
- case FFS_EXPR:
case CONSTRUCTOR:
case COMPOUND_LITERAL_EXPR:
- case COMPLEX_EXPR:
case VA_ARG_EXPR:
- pp_c_postfix_expression (ppi, e);
+ pp_postfix_expression (pp, e);
break;
case CONJ_EXPR:
@@ -1165,324 +1723,430 @@ pp_c_expression (ppi, e)
case ALIGNOF_EXPR:
case REALPART_EXPR:
case IMAGPART_EXPR:
- pp_c_unary_expression (ppi, e);
+ pp_c_unary_expression (pp, e);
break;
- case CONVERT_EXPR:
case FLOAT_EXPR:
- pp_c_cast_expression (ppi, e);
+ case FIX_TRUNC_EXPR:
+ case CONVERT_EXPR:
+ pp_c_cast_expression (pp, e);
break;
case MULT_EXPR:
case TRUNC_MOD_EXPR:
case TRUNC_DIV_EXPR:
- pp_c_multiplicative_expression (ppi, e);
+ pp_multiplicative_expression (pp, e);
break;
case LSHIFT_EXPR:
case RSHIFT_EXPR:
- pp_c_shift_expression (ppi, e);
+ pp_c_shift_expression (pp, e);
break;
case LT_EXPR:
case GT_EXPR:
case LE_EXPR:
case GE_EXPR:
- pp_c_relational_expression (ppi, e);
+ pp_c_relational_expression (pp, e);
break;
case BIT_AND_EXPR:
- pp_c_and_expression (ppi, e);
+ pp_c_and_expression (pp, e);
break;
case BIT_XOR_EXPR:
- pp_c_exclusive_or_expression (ppi, e);
+ pp_c_exclusive_or_expression (pp, e);
break;
case BIT_IOR_EXPR:
- pp_c_inclusive_or_expression (ppi, e);
+ pp_c_inclusive_or_expression (pp, e);
break;
case TRUTH_ANDIF_EXPR:
- pp_c_logical_and_expression (ppi, e);
+ pp_c_logical_and_expression (pp, e);
break;
case TRUTH_ORIF_EXPR:
- pp_c_logical_or_expression (ppi, e);
+ pp_c_logical_or_expression (pp, e);
break;
+ case EQ_EXPR:
+ case NE_EXPR:
+ pp_c_equality_expression (pp, e);
+ break;
+
case COND_EXPR:
- pp_c_conditional_expression (ppi, e);
+ pp_conditional_expression (pp, e);
+ break;
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ pp_c_additive_expression (pp, e);
break;
case MODIFY_EXPR:
case INIT_EXPR:
- pp_c_assignment_expression (ppi, e);
+ pp_assignment_expression (pp, e);
break;
- case NOP_EXPR:
- pp_c_expression (ppi, TREE_OPERAND (e, 0));
+ case COMPOUND_EXPR:
+ pp_c_left_paren (pp);
+ pp_expression (pp, TREE_OPERAND (e, 0));
+ pp_separate_with (pp, ',');
+ pp_assignment_expression (pp, TREE_OPERAND (e, 1));
+ pp_c_right_paren (pp);
break;
- case COMPOUND_EXPR:
- pp_c_left_paren (ppi);
- pp_c_expression (ppi, TREE_OPERAND (e, 0));
- pp_separate_with (ppi, ',');
- pp_assignment_expression (ppi, TREE_OPERAND (e, 1));
- pp_c_right_paren (ppi);
+ case NOP_EXPR:
+ case NON_LVALUE_EXPR:
+ case SAVE_EXPR:
+ case UNSAVE_EXPR:
+ pp_expression (pp, TREE_OPERAND (e, 0));
break;
-
+ case TARGET_EXPR:
+ pp_postfix_expression (pp, TREE_OPERAND (e, 1));
+ break;
+
default:
- pp_unsupported_tree (ppi, e);
+ pp_unsupported_tree (pp, e);
break;
}
}
+
/* Statements. */
+
+/* statement:
+ labeled-statement
+ compound-statement
+ expression-statement
+ selection-statement
+ iteration-statement
+ jump-statement */
+
void
-pp_c_statement (ppi, stmt)
- c_pretty_printer ppi;
- tree stmt;
+pp_c_statement (c_pretty_printer *pp, tree stmt)
{
- const enum tree_code code = TREE_CODE (stmt);
+ enum tree_code code;
+
+ if (stmt == NULL)
+ return;
+
+ code = TREE_CODE (stmt);
switch (code)
{
+ /* labeled-statement:
+ identifier : statement
+ case constant-expression : statement
+ default : statement */
case LABEL_STMT:
case CASE_LABEL:
- pp_newline (ppi);
+ if (pp_needs_newline (pp))
+ pp_newline_and_indent (pp, -3);
+ else
+ pp_indentation (pp) -= 3;
if (code == LABEL_STMT)
- pp_tree_identifier (ppi, DECL_NAME (LABEL_STMT_LABEL (stmt)));
- else if (code == LABEL_STMT)
+ pp_tree_identifier (pp, DECL_NAME (LABEL_STMT_LABEL (stmt)));
+ else if (code == CASE_LABEL)
{
if (CASE_LOW (stmt) == NULL_TREE)
- pp_identifier (ppi, "default");
+ pp_identifier (pp, "default");
else
{
- pp_c_identifier (ppi, "case");
- pp_c_whitespace (ppi);
- pp_conditional_expression (ppi, CASE_LOW (stmt));
+ pp_c_identifier (pp, "case");
+ pp_c_whitespace (pp);
+ pp_conditional_expression (pp, CASE_LOW (stmt));
if (CASE_HIGH (stmt))
{
- pp_identifier (ppi, "...");
- pp_conditional_expression (ppi, CASE_HIGH (stmt));
+ pp_identifier (pp, "...");
+ pp_conditional_expression (pp, CASE_HIGH (stmt));
}
}
}
- pp_colon (ppi);
- pp_newline_and_indent (ppi, 3);
+ pp_colon (pp);
+ pp_indentation (pp) += 3;
+ pp_needs_newline (pp) = true;
break;
+ /* compound-statement:
+ { block-item-list(opt) }
+
+ block-item-list:
+ block-item
+ block-item-list block-item
+
+ block-item:
+ declaration
+ statement */
case COMPOUND_STMT:
- pp_left_brace (ppi);
- pp_newline_and_indent (ppi, 3);
+ if (pp_needs_newline (pp))
+ pp_newline_and_indent (pp, 0);
+ pp_c_left_brace (pp);
+ pp_newline_and_indent (pp, 3);
for (stmt = COMPOUND_BODY (stmt); stmt; stmt = TREE_CHAIN (stmt))
- pp_c_statement (ppi, stmt);
- pp_newline_and_indent (ppi, -3);
- pp_right_brace (ppi);
- pp_newline (ppi);
+ pp_statement (pp, stmt);
+ pp_newline_and_indent (pp, -3);
+ pp_c_right_brace (pp);
+ pp_needs_newline (pp) = true;
break;
+ /* expression-statement:
+ expression(opt) ; */
case EXPR_STMT:
case CLEANUP_STMT:
- pp_newline (ppi);
- pp_c_expression (ppi, code == EXPR_STMT
- ? EXPR_STMT_EXPR (stmt)
- : CLEANUP_EXPR (stmt));
- pp_semicolon (ppi);
- pp_newline (ppi);
+ if (pp_needs_newline (pp))
+ pp_newline_and_indent (pp, 0);
+ {
+ tree e = code == EXPR_STMT
+ ? EXPR_STMT_EXPR (stmt)
+ : CLEANUP_EXPR (stmt);
+ if (e)
+ pp_expression (pp, e);
+ }
+ pp_c_semicolon (pp);
+ pp_needs_newline (pp) = true;
break;
+ /* selection-statement:
+ if ( expression ) statement
+ if ( expression ) statement else statement
+ switch ( expression ) statement */
case IF_STMT:
- pp_c_identifier (ppi, "if");
- pp_whitespace (ppi);
- pp_c_left_paren (ppi);
- pp_c_expression (ppi, IF_COND (stmt));
- pp_right_paren (ppi);
- pp_newline_and_indent (ppi, 3);
- pp_statement (ppi, THEN_CLAUSE (stmt));
- pp_newline_and_indent (ppi, -3);
+ if (pp_needs_newline (pp))
+ pp_newline_and_indent (pp, 0);
+ pp_c_identifier (pp, "if");
+ pp_c_whitespace (pp);
+ pp_c_left_paren (pp);
+ pp_expression (pp, IF_COND (stmt));
+ pp_c_right_paren (pp);
+ pp_newline_and_indent (pp, 3);
+ pp_statement (pp, THEN_CLAUSE (stmt));
+ pp_newline_and_indent (pp, -3);
if (ELSE_CLAUSE (stmt))
{
tree else_clause = ELSE_CLAUSE (stmt);
- pp_c_identifier (ppi, "else");
+ pp_c_identifier (pp, "else");
if (TREE_CODE (else_clause) == IF_STMT)
- pp_c_whitespace (ppi);
+ pp_c_whitespace (pp);
else
- pp_newline_and_indent (ppi, 3);
- pp_statement (ppi, else_clause);
+ pp_newline_and_indent (pp, 3);
+ pp_statement (pp, else_clause);
if (TREE_CODE (else_clause) != IF_STMT)
- pp_newline_and_indent (ppi, -3);
+ pp_newline_and_indent (pp, -3);
}
break;
case SWITCH_STMT:
- pp_newline (ppi);
- pp_c_identifier (ppi, "switch");
- pp_whitespace (ppi);
- pp_c_left_paren (ppi);
- pp_c_expression (ppi, SWITCH_COND (stmt));
- pp_right_paren (ppi);
- pp_newline_and_indent (ppi, 3);
- pp_statement (ppi, SWITCH_BODY (stmt));
- pp_newline_and_indent (ppi, -3);
- break;
-
+ if (pp_needs_newline (pp))
+ pp_newline_and_indent (pp, 0);
+ pp_c_identifier (pp, "switch");
+ pp_space (pp);
+ pp_c_left_paren (pp);
+ pp_expression (pp, SWITCH_COND (stmt));
+ pp_c_right_paren (pp);
+ pp_indentation (pp) += 3;
+ pp_needs_newline (pp) = true;
+ pp_statement (pp, SWITCH_BODY (stmt));
+ pp_newline_and_indent (pp, -3);
+ break;
+
+ /* iteration-statement:
+ while ( expression ) statement
+ do statement while ( expression ) ;
+ for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
+ for ( declaration expression(opt) ; expression(opt) ) statement */
case WHILE_STMT:
- pp_c_identifier (ppi, "while");
- pp_whitespace (ppi);
- pp_c_left_paren (ppi);
- pp_c_expression (ppi, WHILE_COND (stmt));
- pp_right_paren (ppi);
- pp_newline_and_indent (ppi, 3);
- pp_statement (ppi, WHILE_BODY (stmt));
- pp_newline_and_indent (ppi, -3);
+ if (pp_needs_newline (pp))
+ pp_newline_and_indent (pp, 0);
+ pp_c_identifier (pp, "while");
+ pp_space (pp);
+ pp_c_left_paren (pp);
+ pp_expression (pp, WHILE_COND (stmt));
+ pp_c_right_paren (pp);
+ pp_newline_and_indent (pp, 3);
+ pp_statement (pp, WHILE_BODY (stmt));
+ pp_indentation (pp) -= 3;
+ pp_needs_newline (pp) = true;
break;
case DO_STMT:
- pp_c_identifier (ppi, "do");
- pp_newline_and_indent (ppi, 3);
- pp_statement (ppi, DO_BODY (stmt));
- pp_newline_and_indent (ppi, -3);
- pp_c_identifier (ppi, "while");
- pp_whitespace (ppi);
- pp_c_left_paren (ppi);
- pp_c_expression (ppi, DO_COND (stmt));
- pp_c_right_paren (ppi);
- pp_semicolon (ppi);
- pp_newline (ppi);
+ if (pp_needs_newline (pp))
+ pp_newline_and_indent (pp, 0);
+ pp_c_identifier (pp, "do");
+ pp_newline_and_indent (pp, 3);
+ pp_statement (pp, DO_BODY (stmt));
+ pp_newline_and_indent (pp, -3);
+ pp_c_identifier (pp, "while");
+ pp_space (pp);
+ pp_c_left_paren (pp);
+ pp_expression (pp, DO_COND (stmt));
+ pp_c_right_paren (pp);
+ pp_c_semicolon (pp);
+ pp_needs_newline (pp) = true;
break;
case FOR_STMT:
- pp_c_identifier (ppi, "for");
- pp_whitespace (ppi);
- pp_c_left_paren (ppi);
- pp_statement (ppi, FOR_INIT_STMT (stmt));
- pp_c_whitespace (ppi);
+ if (pp_needs_newline (pp))
+ pp_newline_and_indent (pp, 0);
+ pp_c_identifier (pp, "for");
+ pp_space (pp);
+ pp_c_left_paren (pp);
+ if (FOR_INIT_STMT (stmt))
+ pp_statement (pp, FOR_INIT_STMT (stmt));
+ else
+ pp_c_semicolon (pp);
+ pp_needs_newline (pp) = false;
+ pp_c_whitespace (pp);
if (FOR_COND (stmt))
- pp_c_expression (ppi, FOR_COND (stmt));
- pp_semicolon (ppi);
- pp_c_whitespace (ppi);
+ pp_expression (pp, FOR_COND (stmt));
+ pp_c_semicolon (pp);
+ pp_needs_newline (pp) = false;
+ pp_c_whitespace (pp);
if (FOR_EXPR (stmt))
- pp_c_expression (ppi, FOR_EXPR (stmt));
- pp_right_paren (ppi);
- pp_newline_and_indent (ppi, 3);
- pp_statement (ppi, FOR_BODY (stmt));
- pp_newline_and_indent (ppi, -3);
- break;
-
+ pp_expression (pp, FOR_EXPR (stmt));
+ pp_c_right_paren (pp);
+ pp_newline_and_indent (pp, 3);
+ pp_statement (pp, FOR_BODY (stmt));
+ pp_indentation (pp) -= 3;
+ pp_needs_newline (pp) = true;
+ break;
+
+ /* jump-statement:
+ goto identifier;
+ continue ;
+ return expression(opt) ; */
case BREAK_STMT:
case CONTINUE_STMT:
- pp_newline (ppi);
- pp_identifier (ppi, code == BREAK_STMT ? "break" : "continue");
- pp_semicolon (ppi);
- pp_newline (ppi);
+ if (pp_needs_newline (pp))
+ pp_newline_and_indent (pp, 0);
+ pp_identifier (pp, code == BREAK_STMT ? "break" : "continue");
+ pp_c_semicolon (pp);
+ pp_needs_newline (pp) = true;
break;
case RETURN_STMT:
case GOTO_STMT:
{
- tree e = code == RETURN_STMT
+ tree e = code == RETURN_STMT
? RETURN_STMT_EXPR (stmt)
: GOTO_DESTINATION (stmt);
-
- pp_newline (ppi);
- pp_c_identifier (ppi, code == RETURN_STMT ? "return" : "goto");
+ if (pp_needs_newline (pp))
+ pp_newline_and_indent (pp, 0);
+ pp_c_identifier (pp, code == RETURN_STMT ? "return" : "goto");
+ pp_c_whitespace (pp);
if (e)
- pp_c_expression (ppi, e);
- pp_semicolon (ppi);
- pp_newline (ppi);
+ {
+ if (TREE_CODE (e) == INIT_EXPR
+ && TREE_CODE (TREE_OPERAND (e, 0)) == RESULT_DECL)
+ e = TREE_OPERAND (e, 1);
+ pp_expression (pp, e);
+ }
+ pp_c_semicolon (pp);
+ pp_needs_newline (pp) = true;
}
break;
case SCOPE_STMT:
if (!SCOPE_NULLIFIED_P (stmt) && SCOPE_NO_CLEANUPS_P (stmt))
- {
- if (SCOPE_BEGIN_P (stmt))
- {
- pp_left_brace (ppi);
- pp_newline_and_indent (ppi, 3);
- }
- else if (SCOPE_END_P (stmt))
- {
- pp_right_brace (ppi);
- pp_newline_and_indent (ppi, -3);
- }
- }
+ {
+ int i = 0;
+ if (pp_needs_newline (pp))
+ pp_newline_and_indent (pp, 0);
+ if (SCOPE_BEGIN_P (stmt))
+ {
+ pp_left_brace (pp);
+ i = 3;
+ }
+ else if (SCOPE_END_P (stmt))
+ {
+ pp_right_brace (pp);
+ i = -3;
+ }
+ pp_indentation (pp) += i;
+ pp_needs_newline (pp) = true;
+ }
break;
case DECL_STMT:
- pp_declaration (ppi, DECL_STMT_DECL (stmt));
- pp_semicolon (ppi);
- pp_newline (ppi);
+ if (pp_needs_newline (pp))
+ pp_newline_and_indent (pp, 0);
+ pp_declaration (pp, DECL_STMT_DECL (stmt));
+ pp_needs_newline (pp) = true;
break;
case ASM_STMT:
{
bool has_volatile_p = ASM_VOLATILE_P (stmt);
- bool is_extended = has_volatile_p || ASM_INPUTS (stmt)
+ bool is_extended = has_volatile_p || ASM_INPUTS (stmt)
|| ASM_OUTPUTS (stmt) || ASM_CLOBBERS (stmt);
- pp_c_identifier (ppi, is_extended ? "__asm__" : "asm");
+ pp_c_identifier (pp, is_extended ? "__asm__" : "asm");
if (has_volatile_p)
- pp_c_identifier (ppi, "__volatile__");
- pp_whitespace (ppi);
- pp_c_left_paren (ppi);
- pp_c_string_literal (ppi, ASM_STRING (stmt));
+ pp_c_identifier (pp, "__volatile__");
+ pp_space (pp);
+ pp_c_left_paren (pp);
+ pp_c_string_literal (pp, ASM_STRING (stmt));
if (is_extended)
{
- pp_whitespace (ppi);
- pp_separate_with (ppi, ':');
+ pp_space (pp);
+ pp_separate_with (pp, ':');
if (ASM_OUTPUTS (stmt))
- pp_c_expression (ppi, ASM_OUTPUTS (stmt));
- pp_whitespace (ppi);
- pp_separate_with (ppi, ':');
+ pp_expression (pp, ASM_OUTPUTS (stmt));
+ pp_space (pp);
+ pp_separate_with (pp, ':');
if (ASM_INPUTS (stmt))
- pp_c_expression (ppi, ASM_INPUTS (stmt));
- pp_whitespace (ppi);
- pp_separate_with (ppi, ':');
+ pp_expression (pp, ASM_INPUTS (stmt));
+ pp_space (pp);
+ pp_separate_with (pp, ':');
if (ASM_CLOBBERS (stmt))
- pp_c_expression (ppi, ASM_CLOBBERS (stmt));
+ pp_expression (pp, ASM_CLOBBERS (stmt));
}
- pp_right_paren (ppi);
- pp_newline (ppi);
+ pp_c_right_paren (pp);
+ pp_newline (pp);
}
break;
case FILE_STMT:
- pp_c_identifier (ppi, "__FILE__");
- pp_whitespace (ppi);
- pp_equal (ppi);
- pp_c_whitespace (ppi);
- pp_c_identifier (ppi, FILE_STMT_FILENAME (stmt));
- pp_semicolon (ppi);
- pp_newline (ppi);
+ pp_c_identifier (pp, "__FILE__");
+ pp_space (pp);
+ pp_equal (pp);
+ pp_c_whitespace (pp);
+ pp_c_identifier (pp, FILE_STMT_FILENAME (stmt));
+ pp_c_semicolon (pp);
+ pp_needs_newline (pp) = true;
break;
default:
- pp_unsupported_tree (ppi, stmt);
+ pp_unsupported_tree (pp, stmt);
}
-
}
/* Initialize the PRETTY-PRINTER for handling C codes. */
+
void
-pp_c_pretty_printer_init (pp)
- c_pretty_printer pp;
+pp_c_pretty_printer_init (c_pretty_printer *pp)
{
pp->offset_list = 0;
pp->declaration = pp_c_declaration;
pp->declaration_specifiers = pp_c_declaration_specifiers;
- pp->type_specifier = pp_c_simple_type_specifier;
pp->declarator = pp_c_declarator;
pp->direct_declarator = pp_c_direct_declarator;
- pp->parameter_declaration = pp_c_parameter_declaration;
+ pp->type_specifier_seq = pp_c_specifier_qualifier_list;
+ pp->abstract_declarator = pp_c_abstract_declarator;
+ pp->direct_abstract_declarator = pp_c_direct_abstract_declarator;
+ pp->ptr_operator = pp_c_pointer;
+ pp->parameter_list = pp_c_parameter_type_list;
pp->type_id = pp_c_type_id;
+ pp->simple_type_specifier = pp_c_type_specifier;
+ pp->function_specifier = pp_c_function_specifier;
+ pp->storage_class_specifier = pp_c_storage_class_specifier;
pp->statement = pp_c_statement;
+ pp->id_expression = pp_c_id_expression;
pp->primary_expression = pp_c_primary_expression;
pp->postfix_expression = pp_c_postfix_expression;
pp->unary_expression = pp_c_unary_expression;
@@ -1490,4 +2154,5 @@ pp_c_pretty_printer_init (pp)
pp->multiplicative_expression = pp_c_multiplicative_expression;
pp->conditional_expression = pp_c_conditional_expression;
pp->assignment_expression = pp_c_assignment_expression;
+ pp->expression = pp_c_expression;
}
diff --git a/contrib/gcc/c-pretty-print.h b/contrib/gcc/c-pretty-print.h
index 0ab702e0a51a..39e0be77d2d9 100644
--- a/contrib/gcc/c-pretty-print.h
+++ b/contrib/gcc/c-pretty-print.h
@@ -1,5 +1,5 @@
/* Various declarations for the C and C++ pretty-printers.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
@@ -27,139 +27,174 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "pretty-print.h"
+typedef enum
+ {
+ pp_c_flag_abstract = 1 << 1,
+ pp_c_flag_last_bit = 2
+ } pp_c_pretty_print_flags;
+
+
/* The data type used to bundle information necessary for pretty-printing
a C or C++ entity. */
-typedef struct c_pretty_print_info *c_pretty_printer;
+typedef struct c_pretty_print_info c_pretty_printer;
/* The type of a C pretty-printer 'member' function. */
-typedef void (*c_pretty_print_fn) PARAMS ((c_pretty_printer, tree));
-
+typedef void (*c_pretty_print_fn) (c_pretty_printer *, tree);
+
+/* The datatype that contains information necessary for pretty-printing
+ a tree that represents a C construct. Any pretty-printer for a
+ language using C/c++ syntax can derive from this datatype and reuse
+ facilities provided here. It can do so by having a subobject of type
+ c_pretty_printer and override the macro pp_c_base to return a pointer
+ to that subobject. Such a pretty-printer has the responsibility to
+ initialize the pp_base() part, then call pp_c_pretty_printer_init
+ to set up the components that are specific to the C pretty-printer.
+ A derived pretty-printer can override any function listed in the
+ vtable below. See cp/cxx-pretty-print.h and cp/cxx-pretty-print.c
+ for an example of derivation. */
struct c_pretty_print_info
{
- struct pretty_print_info base;
+ pretty_printer base;
/* Points to the first element of an array of offset-list.
Not used yet. */
int *offset_list;
- /* These must be overriden by each of the C and C++ front-end to
- reflect their understanding of syntatic productions when they differ. */
+ pp_flags flags;
+
+ /* These must be overridden by each of the C and C++ front-end to
+ reflect their understanding of syntactic productions when they differ. */
c_pretty_print_fn declaration;
c_pretty_print_fn declaration_specifiers;
- c_pretty_print_fn type_specifier;
c_pretty_print_fn declarator;
+ c_pretty_print_fn abstract_declarator;
+ c_pretty_print_fn direct_abstract_declarator;
+ c_pretty_print_fn type_specifier_seq;
c_pretty_print_fn direct_declarator;
- c_pretty_print_fn parameter_declaration;
+ c_pretty_print_fn ptr_operator;
+ c_pretty_print_fn parameter_list;
c_pretty_print_fn type_id;
+ c_pretty_print_fn simple_type_specifier;
+ c_pretty_print_fn function_specifier;
+ c_pretty_print_fn storage_class_specifier;
+ c_pretty_print_fn initializer;
c_pretty_print_fn statement;
+ c_pretty_print_fn id_expression;
c_pretty_print_fn primary_expression;
c_pretty_print_fn postfix_expression;
c_pretty_print_fn unary_expression;
- c_pretty_print_fn initializer;
c_pretty_print_fn multiplicative_expression;
c_pretty_print_fn conditional_expression;
c_pretty_print_fn assignment_expression;
+ c_pretty_print_fn expression;
};
-#define pp_c_left_paren(PPI) \
- do { \
- pp_left_paren (PPI); \
- pp_c_base (PPI)->base.padding = pp_none; \
- } while (0)
-#define pp_c_right_paren(PPI) \
- do { \
- pp_right_paren (PPI); \
- pp_c_base (PPI)->base.padding = pp_none; \
- } while (0)
-#define pp_c_left_bracket(PPI) \
- do { \
- pp_left_bracket (PPI); \
- pp_c_base (PPI)->base.padding = pp_none; \
- } while (0)
-#define pp_c_right_bracket(PPI) \
- do { \
- pp_right_bracket (PPI); \
- pp_c_base (PPI)->base.padding = pp_none; \
- } while (0)
-#define pp_c_whitespace(PPI) \
- do { \
- pp_whitespace (PPI); \
- pp_c_base (PPI)->base.padding = pp_none; \
- } while (0)
-#define pp_c_maybe_whitespace(PPI) \
- do { \
- if (pp_c_base (PPI)->base.padding != pp_none) \
- pp_c_whitespace (PPI); \
- } while (0)
-#define pp_c_identifier(PPI, ID) \
- do { \
- pp_c_maybe_whitespace (PPI); \
- pp_identifier (PPI, ID); \
- pp_c_base (PPI)->base.padding = pp_before; \
- } while (0)
+/* Override the pp_base macro. Derived pretty-printers should not
+ touch this macro. Instead they should override pp_c_base instead. */
+#undef pp_base
+#define pp_base(PP) (&pp_c_base (PP)->base)
+
#define pp_c_tree_identifier(PPI, ID) \
pp_c_identifier (PPI, IDENTIFIER_POINTER (ID))
-/* Returns the 'output_buffer *' associated with a PRETTY-PRINTER, the latter
- being something digestible by pp_c_base. */
-#define pp_buffer(PPI) pp_c_base (PPI)->base.buffer
-
#define pp_declaration(PPI, T) \
- (*pp_c_base (PPI)->declaration) (pp_c_base (PPI), T)
+ pp_c_base (PPI)->declaration (pp_c_base (PPI), T)
#define pp_declaration_specifiers(PPI, D) \
- (*pp_c_base (PPI)->declaration_specifiers) (pp_c_base (PPI), D)
-#define pp_type_specifier(PPI, D) \
- (*pp_c_base (PPI)->type_specifier) (pp_c_base (PPI), D)
+ pp_c_base (PPI)->declaration_specifiers (pp_c_base (PPI), D)
+#define pp_abstract_declarator(PP, D) \
+ pp_c_base (PP)->abstract_declarator (pp_c_base (PP), D)
+#define pp_type_specifier_seq(PPI, D) \
+ pp_c_base (PPI)->type_specifier_seq (pp_c_base (PPI), D)
#define pp_declarator(PPI, D) \
- (*pp_c_base (PPI)->declarator) (pp_c_base (PPI), D)
+ pp_c_base (PPI)->declarator (pp_c_base (PPI), D)
#define pp_direct_declarator(PPI, D) \
- (*pp_c_base (PPI)->direct_declarator) (pp_c_base (PPI), D)
-#define pp_parameter_declaration(PPI, T) \
- (*pp_c_base (PPI)->parameter_declaration) (pp_c_base (PPI), T)
+ pp_c_base (PPI)->direct_declarator (pp_c_base (PPI), D)
+#define pp_direct_abstract_declarator(PP, D) \
+ pp_c_base (PP)->direct_abstract_declarator (pp_c_base (PP), D)
+#define pp_ptr_operator(PP, D) \
+ pp_c_base (PP)->ptr_operator (pp_c_base (PP), D)
+#define pp_parameter_list(PPI, T) \
+ pp_c_base (PPI)->parameter_list (pp_c_base (PPI), T)
#define pp_type_id(PPI, D) \
- (*pp_c_base (PPI)->type_id) (pp_c_base (PPI), D)
+ pp_c_base (PPI)->type_id (pp_c_base (PPI), D)
+#define pp_simple_type_specifier(PP, T) \
+ pp_c_base (PP)->simple_type_specifier (pp_c_base (PP), T)
+#define pp_function_specifier(PP, D) \
+ pp_c_base (PP)->function_specifier (pp_c_base (PP), D)
+#define pp_storage_class_specifier(PP, D) \
+ pp_c_base (PP)->storage_class_specifier (pp_c_base (PP), D);
#define pp_statement(PPI, S) \
- (*pp_c_base (PPI)->statement) (pp_c_base (PPI), S)
+ pp_c_base (PPI)->statement (pp_c_base (PPI), S)
+#define pp_id_expression(PP, E) \
+ pp_c_base (PP)->id_expression (pp_c_base (PP), E)
#define pp_primary_expression(PPI, E) \
- (*pp_c_base (PPI)->primary_expression) (pp_c_base (PPI), E)
+ pp_c_base (PPI)->primary_expression (pp_c_base (PPI), E)
#define pp_postfix_expression(PPI, E) \
- (*pp_c_base (PPI)->postfix_expression) (pp_c_base (PPI), E)
+ pp_c_base (PPI)->postfix_expression (pp_c_base (PPI), E)
#define pp_unary_expression(PPI, E) \
- (*pp_c_base (PPI)->unary_expression) (pp_c_base (PPI), E)
+ pp_c_base (PPI)->unary_expression (pp_c_base (PPI), E)
#define pp_initializer(PPI, E) \
- (*pp_c_base (PPI)->initializer) (pp_c_base (PPI), E)
+ pp_c_base (PPI)->initializer (pp_c_base (PPI), E)
#define pp_multiplicative_expression(PPI, E) \
- (*pp_c_base (PPI)->multiplicative_expression) (pp_c_base (PPI), E)
+ pp_c_base (PPI)->multiplicative_expression (pp_c_base (PPI), E)
#define pp_conditional_expression(PPI, E) \
- (*pp_c_base (PPI)->conditional_expression) (pp_c_base (PPI), E)
+ pp_c_base (PPI)->conditional_expression (pp_c_base (PPI), E)
#define pp_assignment_expression(PPI, E) \
- (*pp_c_base (PPI)->assignment_expression) (pp_c_base (PPI), E)
+ pp_c_base (PPI)->assignment_expression (pp_c_base (PPI), E)
+#define pp_expression(PP, E) \
+ pp_c_base (PP)->expression (pp_c_base (PP), E)
/* Returns the c_pretty_printer base object of PRETTY-PRINTER. This
- macro must be overriden by any subclass of c_pretty_print_info. */
+ macro must be overridden by any subclass of c_pretty_print_info. */
#define pp_c_base(PP) (PP)
-extern void pp_c_pretty_printer_init PARAMS ((c_pretty_printer));
+extern void pp_c_pretty_printer_init (c_pretty_printer *);
+void pp_c_whitespace (c_pretty_printer *);
+void pp_c_left_paren (c_pretty_printer *);
+void pp_c_right_paren (c_pretty_printer *);
+void pp_c_left_brace (c_pretty_printer *);
+void pp_c_right_brace (c_pretty_printer *);
+void pp_c_dot (c_pretty_printer *);
+void pp_c_ampersand (c_pretty_printer *);
+void pp_c_arrow (c_pretty_printer *);
+void pp_c_semicolon (c_pretty_printer *);
+void pp_c_space_for_pointer_operator (c_pretty_printer *, tree);
/* Declarations. */
-void pp_c_attributes PARAMS ((c_pretty_printer, tree));
-void pp_c_cv_qualifier PARAMS ((c_pretty_printer, int));
-void pp_c_parameter_declaration_clause PARAMS ((c_pretty_printer, tree));
-void pp_c_declaration PARAMS ((c_pretty_printer, tree));
+void pp_c_function_definition (c_pretty_printer *, tree);
+void pp_c_attributes (c_pretty_printer *, tree);
+void pp_c_type_qualifier_list (c_pretty_printer *, tree);
+void pp_c_parameter_type_list (c_pretty_printer *, tree);
+void pp_c_declaration (c_pretty_printer *, tree);
+void pp_c_declaration_specifiers (c_pretty_printer *, tree);
+void pp_c_declarator (c_pretty_printer *, tree);
+void pp_c_direct_declarator (c_pretty_printer *, tree);
+void pp_c_specifier_qualifier_list (c_pretty_printer *, tree);
+void pp_c_function_specifier (c_pretty_printer *, tree);
+void pp_c_type_id (c_pretty_printer *, tree);
+void pp_c_direct_abstract_declarator (c_pretty_printer *, tree);
+void pp_c_type_specifier (c_pretty_printer *, tree);
+void pp_c_storage_class_specifier (c_pretty_printer *, tree);
/* Statements. */
-void pp_c_statement PARAMS ((c_pretty_printer, tree));
+void pp_c_statement (c_pretty_printer *, tree);
/* Expressions. */
-void pp_c_expression PARAMS ((c_pretty_printer, tree));
-void pp_c_logical_or_expression PARAMS ((c_pretty_printer, tree));
-void pp_c_expression_list PARAMS ((c_pretty_printer, tree));
-void pp_c_cast_expression PARAMS ((c_pretty_printer, tree));
-void pp_c_postfix_expression PARAMS ((c_pretty_printer, tree));
-void pp_c_initializer PARAMS ((c_pretty_printer, tree));
-void pp_c_literal PARAMS ((c_pretty_printer, tree));
+void pp_c_expression (c_pretty_printer *, tree);
+void pp_c_logical_or_expression (c_pretty_printer *, tree);
+void pp_c_expression_list (c_pretty_printer *, tree);
+void pp_c_call_argument_list (c_pretty_printer *, tree);
+void pp_c_unary_expression (c_pretty_printer *, tree);
+void pp_c_cast_expression (c_pretty_printer *, tree);
+void pp_c_postfix_expression (c_pretty_printer *, tree);
+void pp_c_primary_expression (c_pretty_printer *, tree);
+void pp_c_init_declarator (c_pretty_printer *, tree);
+void pp_c_constant (c_pretty_printer *, tree);
+void pp_c_id_expression (c_pretty_printer *, tree);
+void pp_c_identifier (c_pretty_printer *, const char *);
+void pp_c_string_literal (c_pretty_printer *, tree);
#endif /* GCC_C_PRETTY_PRINTER */
diff --git a/contrib/gcc/c-semantics.c b/contrib/gcc/c-semantics.c
index 8559fa17a756..38c4021d6cf1 100644
--- a/contrib/gcc/c-semantics.c
+++ b/contrib/gcc/c-semantics.c
@@ -1,7 +1,7 @@
/* This file contains the definitions and documentation for the common
tree codes used in the GNU C and C++ compilers (see c-common.def
- for the standard codes).
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ for the standard codes).
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Written by Benjamin Chelf (chelf@codesourcery.com).
This file is part of GCC.
@@ -23,12 +23,18 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "function.h"
#include "splay-tree.h"
#include "varray.h"
#include "c-common.h"
#include "except.h"
+/* In order for the format checking to accept the C frontend
+ diagnostic framework extensions, you must define this token before
+ including toplev.h. */
+#define GCC_DIAG_STYLE __gcc_cdiag__
#include "toplev.h"
#include "flags.h"
#include "ggc.h"
@@ -37,23 +43,29 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "output.h"
#include "timevar.h"
#include "predict.h"
+#include "tree-inline.h"
/* If non-NULL, the address of a language-specific function for
expanding statements. */
-void (*lang_expand_stmt) PARAMS ((tree));
+void (*lang_expand_stmt) (tree);
/* If non-NULL, the address of a language-specific function for
expanding a DECL_STMT. After the language-independent cases are
handled, this function will be called. If this function is not
defined, it is assumed that declarations other than those for
variables and labels do not require any RTL generation. */
-void (*lang_expand_decl_stmt) PARAMS ((tree));
+void (*lang_expand_decl_stmt) (tree);
+
+static tree find_reachable_label_1 (tree *, int *, void *);
+static tree find_reachable_label (tree);
+static bool expand_unreachable_if_stmt (tree);
+static tree expand_unreachable_stmt (tree, int);
+static void genrtl_do_stmt_1 (tree, tree);
/* Create an empty statement tree rooted at T. */
void
-begin_stmt_tree (t)
- tree *t;
+begin_stmt_tree (tree *t)
{
/* We create a trivial EXPR_STMT so that last_tree is never NULL in
what follows. We remove the extraneous statement in
@@ -67,8 +79,7 @@ begin_stmt_tree (t)
/* T is a statement. Add it to the statement-tree. */
tree
-add_stmt (t)
- tree t;
+add_stmt (tree t)
{
if (input_filename != last_expr_filename)
{
@@ -86,15 +97,11 @@ add_stmt (t)
/* Add T to the statement-tree. */
TREE_CHAIN (last_tree) = t;
last_tree = t;
-
+
/* When we expand a statement-tree, we must know whether or not the
statements are full-expressions. We record that fact here. */
STMT_IS_FULL_EXPR_P (last_tree) = stmts_are_full_exprs_p ();
- /* Keep track of the number of statements in this function. */
- if (current_function_decl)
- ++DECL_NUM_STMTS (current_function_decl);
-
return t;
}
@@ -102,14 +109,13 @@ add_stmt (t)
DECL. */
void
-add_decl_stmt (decl)
- tree decl;
+add_decl_stmt (tree decl)
{
tree decl_stmt;
/* We need the type to last until instantiation time. */
decl_stmt = build_stmt (DECL_STMT, decl);
- add_stmt (decl_stmt);
+ add_stmt (decl_stmt);
}
/* Add a scope-statement to the statement-tree. BEGIN_P indicates
@@ -123,9 +129,7 @@ add_decl_stmt (decl)
SCOPE_BEGIN_P set. */
tree
-add_scope_stmt (begin_p, partial_p)
- int begin_p;
- int partial_p;
+add_scope_stmt (int begin_p, int partial_p)
{
tree *stack_ptr = current_scope_stmt_stack ();
tree ss;
@@ -144,6 +148,8 @@ add_scope_stmt (begin_p, partial_p)
}
else
{
+ if (partial_p != SCOPE_PARTIAL_P (TREE_PURPOSE (top)))
+ abort ();
TREE_VALUE (top) = ss;
*stack_ptr = TREE_CHAIN (top);
}
@@ -157,11 +163,10 @@ add_scope_stmt (begin_p, partial_p)
/* Finish the statement tree rooted at T. */
void
-finish_stmt_tree (t)
- tree *t;
+finish_stmt_tree (tree *t)
{
tree stmt;
-
+
/* Remove the fake extra statement added in begin_stmt_tree. */
stmt = TREE_CHAIN (*t);
*t = stmt;
@@ -171,7 +176,7 @@ finish_stmt_tree (t)
{
/* The line-number recorded in the outermost statement in a function
is the line number of the end of the function. */
- STMT_LINENO (stmt) = lineno;
+ STMT_LINENO (stmt) = input_line;
STMT_LINENO_FOR_FN_P (stmt) = 1;
}
}
@@ -183,23 +188,23 @@ finish_stmt_tree (t)
in the grammar. */
tree
-build_stmt VPARAMS ((enum tree_code code, ...))
+build_stmt (enum tree_code code, ...)
{
tree t;
int length;
int i;
+ va_list p;
- VA_OPEN (p, code);
- VA_FIXEDARG (p, enum tree_code, code);
+ va_start (p, code);
t = make_node (code);
length = TREE_CODE_LENGTH (code);
- STMT_LINENO (t) = lineno;
+ STMT_LINENO (t) = input_line;
for (i = 0; i < length; i++)
TREE_OPERAND (t, i) = va_arg (p, tree);
- VA_CLOSE (p);
+ va_end (p);
return t;
}
@@ -209,23 +214,21 @@ build_stmt VPARAMS ((enum tree_code code, ...))
as the condition is returned. Otherwise, T itself is returned. */
tree
-expand_cond (t)
- tree t;
+expand_cond (tree t)
{
if (t && TREE_CODE (t) == TREE_LIST)
{
expand_stmt (TREE_PURPOSE (t));
return TREE_VALUE (t);
}
- else
+ else
return t;
}
/* Create RTL for the local static variable DECL. */
void
-make_rtl_for_local_static (decl)
- tree decl;
+make_rtl_for_local_static (tree decl)
{
const char *asmspec = NULL;
@@ -260,8 +263,7 @@ make_rtl_for_local_static (decl)
/* Let the back-end know about DECL. */
void
-emit_local_var (decl)
- tree decl;
+emit_local_var (tree decl)
{
/* Create RTL for this variable. */
if (!DECL_RTL_SET_P (decl))
@@ -276,45 +278,47 @@ emit_local_var (decl)
expand_decl (decl);
}
- /* Actually do the initialization. */
- if (stmts_are_full_exprs_p ())
- expand_start_target_temps ();
+ if (DECL_INITIAL (decl))
+ {
+ /* Actually do the initialization. */
+ if (stmts_are_full_exprs_p ())
+ expand_start_target_temps ();
- expand_decl_init (decl);
+ expand_decl_init (decl);
- if (stmts_are_full_exprs_p ())
- expand_end_target_temps ();
+ if (stmts_are_full_exprs_p ())
+ expand_end_target_temps ();
+ }
}
/* Helper for generating the RTL at the beginning of a scope. */
void
-genrtl_do_pushlevel ()
+genrtl_do_pushlevel (void)
{
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
clear_last_expr ();
}
/* Generate the RTL for DESTINATION, which is a GOTO_STMT. */
void
-genrtl_goto_stmt (destination)
- tree destination;
+genrtl_goto_stmt (tree destination)
{
if (TREE_CODE (destination) == IDENTIFIER_NODE)
abort ();
-
+
/* We warn about unused labels with -Wunused. That means we have to
mark the used labels as used. */
if (TREE_CODE (destination) == LABEL_DECL)
TREE_USED (destination) = 1;
-
- emit_line_note (input_filename, lineno);
-
+
+ emit_line_note (input_location);
+
if (TREE_CODE (destination) == LABEL_DECL)
{
label_rtx (destination);
- expand_goto (destination);
+ expand_goto (destination);
}
else
expand_computed_goto (destination);
@@ -325,8 +329,7 @@ genrtl_goto_stmt (destination)
used for new code. */
void
-genrtl_expr_stmt (expr)
- tree expr;
+genrtl_expr_stmt (tree expr)
{
genrtl_expr_stmt_value (expr, -1, 1);
}
@@ -338,21 +341,19 @@ genrtl_expr_stmt (expr)
MAYBE_LAST is nonzero if this EXPR_STMT might be the last statement
in expression statement. */
-void
-genrtl_expr_stmt_value (expr, want_value, maybe_last)
- tree expr;
- int want_value, maybe_last;
+void
+genrtl_expr_stmt_value (tree expr, int want_value, int maybe_last)
{
if (expr != NULL_TREE)
{
- emit_line_note (input_filename, lineno);
-
+ emit_line_note (input_location);
+
if (stmts_are_full_exprs_p ())
expand_start_target_temps ();
-
+
if (expr != error_mark_node)
expand_expr_stmt_value (expr, want_value, maybe_last);
-
+
if (stmts_are_full_exprs_p ())
expand_end_target_temps ();
}
@@ -361,11 +362,10 @@ genrtl_expr_stmt_value (expr, want_value, maybe_last)
/* Generate the RTL for T, which is a DECL_STMT. */
void
-genrtl_decl_stmt (t)
- tree t;
+genrtl_decl_stmt (tree t)
{
tree decl;
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
decl = DECL_STMT_DECL (t);
/* If this is a declaration for an automatic local
variable, initialize it. Note that we might also see a
@@ -373,7 +373,7 @@ genrtl_decl_stmt (t)
`extern'). We don't have to handle the initialization
of those objects here; they can only be declarations,
rather than definitions. */
- if (TREE_CODE (decl) == VAR_DECL
+ if (TREE_CODE (decl) == VAR_DECL
&& !TREE_STATIC (decl)
&& !DECL_EXTERNAL (decl))
{
@@ -381,12 +381,12 @@ genrtl_decl_stmt (t)
if (!anon_aggr_type_p (TREE_TYPE (decl)))
emit_local_var (decl);
else
- expand_anon_union_decl (decl, NULL_TREE,
+ expand_anon_union_decl (decl, NULL_TREE,
DECL_ANON_UNION_ELEMS (decl));
}
else if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
make_rtl_for_local_static (decl);
- else if (TREE_CODE (decl) == LABEL_DECL
+ else if (TREE_CODE (decl) == LABEL_DECL
&& C_DECLARED_LABEL_FLAG (decl))
declare_nonlocal_label (decl);
else if (lang_expand_decl_stmt)
@@ -396,20 +396,29 @@ genrtl_decl_stmt (t)
/* Generate the RTL for T, which is an IF_STMT. */
void
-genrtl_if_stmt (t)
- tree t;
+genrtl_if_stmt (tree t)
{
tree cond;
genrtl_do_pushlevel ();
cond = expand_cond (IF_COND (t));
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
expand_start_cond (cond, 0);
if (THEN_CLAUSE (t))
- expand_stmt (THEN_CLAUSE (t));
+ {
+ tree nextt = THEN_CLAUSE (t);
+
+ if (cond && integer_zerop (cond))
+ nextt = expand_unreachable_stmt (nextt, warn_notreached);
+ expand_stmt (nextt);
+ }
+
if (ELSE_CLAUSE (t))
{
+ tree nextt = ELSE_CLAUSE (t);
expand_start_else ();
- expand_stmt (ELSE_CLAUSE (t));
+ if (cond && integer_nonzerop (cond))
+ nextt = expand_unreachable_stmt (nextt, warn_notreached);
+ expand_stmt (nextt);
}
expand_end_cond ();
}
@@ -417,33 +426,33 @@ genrtl_if_stmt (t)
/* Generate the RTL for T, which is a WHILE_STMT. */
void
-genrtl_while_stmt (t)
- tree t;
+genrtl_while_stmt (tree t)
{
- tree cond;
- emit_nop ();
- emit_line_note (input_filename, lineno);
- expand_start_loop (1);
- genrtl_do_pushlevel ();
+ tree cond = WHILE_COND (t);
- cond = expand_cond (WHILE_COND (t));
- emit_line_note (input_filename, lineno);
- expand_exit_loop_top_cond (0, cond);
+ emit_line_note (input_location);
+ expand_start_loop (1);
genrtl_do_pushlevel ();
-
+
+ if (cond && !integer_nonzerop (cond))
+ {
+ cond = expand_cond (cond);
+ emit_line_note (input_location);
+ expand_exit_loop_top_cond (0, cond);
+ genrtl_do_pushlevel ();
+ }
+
expand_stmt (WHILE_BODY (t));
expand_end_loop ();
}
-/* Generate the RTL for T, which is a DO_STMT. */
+/* Generate the RTL for a DO_STMT with condition COND and loop BODY
+ body. This is reused for expanding unreachable WHILE_STMTS. */
-void
-genrtl_do_stmt (t)
- tree t;
+static void
+genrtl_do_stmt_1 (tree cond, tree body)
{
- tree cond = DO_COND (t);
-
/* Recognize the common special-case of do { ... } while (0) and do
not emit the loop widgetry in this case. In particular this
avoids cluttering the rtl with dummy loop notes, which can affect
@@ -452,30 +461,46 @@ genrtl_do_stmt (t)
if (!cond || integer_zerop (cond))
{
expand_start_null_loop ();
- expand_stmt (DO_BODY (t));
+ expand_stmt (body);
expand_end_null_loop ();
}
+ else if (integer_nonzerop (cond))
+ {
+ emit_line_note (input_location);
+ expand_start_loop (1);
+
+ expand_stmt (body);
+
+ emit_line_note (input_location);
+ expand_end_loop ();
+ }
else
{
- emit_nop ();
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
expand_start_loop_continue_elsewhere (1);
- expand_stmt (DO_BODY (t));
+ expand_stmt (body);
expand_loop_continue_here ();
cond = expand_cond (cond);
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
expand_exit_loop_if_false (0, cond);
expand_end_loop ();
}
}
+/* Generate the RTL for T, which is a DO_STMT. */
+
+void
+genrtl_do_stmt (tree t)
+{
+ genrtl_do_stmt_1 (DO_COND (t), DO_BODY (t));
+}
+
/* Build the node for a return statement and return it. */
tree
-build_return_stmt (expr)
- tree expr;
+build_return_stmt (tree expr)
{
return (build_stmt (RETURN_STMT, expr));
}
@@ -483,14 +508,13 @@ build_return_stmt (expr)
/* Generate the RTL for STMT, which is a RETURN_STMT. */
void
-genrtl_return_stmt (stmt)
- tree stmt;
+genrtl_return_stmt (tree stmt)
{
tree expr;
expr = RETURN_STMT_EXPR (stmt);
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
if (!expr)
expand_null_return ();
else
@@ -504,12 +528,10 @@ genrtl_return_stmt (stmt)
/* Generate the RTL for T, which is a FOR_STMT. */
void
-genrtl_for_stmt (t)
- tree t;
+genrtl_for_stmt (tree t)
{
- tree cond;
- const char *saved_filename;
- int saved_lineno;
+ tree cond = FOR_COND (t);
+ location_t saved_loc;
if (NEW_FOR_SCOPE_P (t))
genrtl_do_pushlevel ();
@@ -517,40 +539,44 @@ genrtl_for_stmt (t)
expand_stmt (FOR_INIT_STMT (t));
/* Expand the initialization. */
- emit_nop ();
- emit_line_note (input_filename, lineno);
- expand_start_loop_continue_elsewhere (1);
+ emit_line_note (input_location);
+ if (FOR_EXPR (t))
+ expand_start_loop_continue_elsewhere (1);
+ else
+ expand_start_loop (1);
genrtl_do_pushlevel ();
- cond = expand_cond (FOR_COND (t));
/* Save the filename and line number so that we expand the FOR_EXPR
we can reset them back to the saved values. */
- saved_filename = input_filename;
- saved_lineno = lineno;
+ saved_loc = input_location;
/* Expand the condition. */
- emit_line_note (input_filename, lineno);
- if (cond)
- expand_exit_loop_top_cond (0, cond);
+ if (cond && !integer_nonzerop (cond))
+ {
+ cond = expand_cond (cond);
+ emit_line_note (input_location);
+ expand_exit_loop_top_cond (0, cond);
+ genrtl_do_pushlevel ();
+ }
/* Expand the body. */
- genrtl_do_pushlevel ();
expand_stmt (FOR_BODY (t));
/* Expand the increment expression. */
- input_filename = saved_filename;
- lineno = saved_lineno;
- emit_line_note (input_filename, lineno);
- expand_loop_continue_here ();
+ input_location = saved_loc;
+ emit_line_note (input_location);
if (FOR_EXPR (t))
- genrtl_expr_stmt (FOR_EXPR (t));
+ {
+ expand_loop_continue_here ();
+ genrtl_expr_stmt (FOR_EXPR (t));
+ }
expand_end_loop ();
}
/* Build a break statement node and return it. */
tree
-build_break_stmt ()
+build_break_stmt (void)
{
return (build_stmt (BREAK_STMT));
}
@@ -558,17 +584,17 @@ build_break_stmt ()
/* Generate the RTL for a BREAK_STMT. */
void
-genrtl_break_stmt ()
+genrtl_break_stmt (void)
{
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
if ( ! expand_exit_something ())
- error ("break statement not within loop or switch");
+ abort ();
}
/* Build a continue statement node and return it. */
tree
-build_continue_stmt ()
+build_continue_stmt (void)
{
return (build_stmt (CONTINUE_STMT));
}
@@ -576,18 +602,17 @@ build_continue_stmt ()
/* Generate the RTL for a CONTINUE_STMT. */
void
-genrtl_continue_stmt ()
+genrtl_continue_stmt (void)
{
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
if (! expand_continue_loop (0))
- error ("continue statement not within a loop");
+ abort ();
}
/* Generate the RTL for T, which is a SCOPE_STMT. */
void
-genrtl_scope_stmt (t)
- tree t;
+genrtl_scope_stmt (tree t)
{
tree block = SCOPE_STMT_BLOCK (t);
@@ -600,10 +625,8 @@ genrtl_scope_stmt (t)
}
else if (!SCOPE_NULLIFIED_P (t))
{
- rtx note = emit_note (NULL,
- (SCOPE_BEGIN_P (t)
- ? NOTE_INSN_BLOCK_BEG
- : NOTE_INSN_BLOCK_END));
+ rtx note = emit_note (SCOPE_BEGIN_P (t)
+ ? NOTE_INSN_BLOCK_BEG : NOTE_INSN_BLOCK_END);
NOTE_BLOCK (note) = block;
}
@@ -615,9 +638,10 @@ genrtl_scope_stmt (t)
for (fn = BLOCK_VARS (block); fn; fn = TREE_CHAIN (fn))
{
- if (TREE_CODE (fn) == FUNCTION_DECL
+ if (TREE_CODE (fn) == FUNCTION_DECL
&& DECL_CONTEXT (fn) == current_function_decl
&& DECL_SAVED_INSNS (fn)
+ && DECL_SAVED_INSNS (fn)->saved_for_inline
&& !TREE_ASM_WRITTEN (fn)
&& TREE_ADDRESSABLE (fn))
{
@@ -632,31 +656,27 @@ genrtl_scope_stmt (t)
/* Generate the RTL for T, which is a SWITCH_STMT. */
void
-genrtl_switch_stmt (t)
- tree t;
+genrtl_switch_stmt (tree t)
{
tree cond;
genrtl_do_pushlevel ();
-
+
cond = expand_cond (SWITCH_COND (t));
if (cond == error_mark_node)
/* The code is in error, but we don't want expand_end_case to
crash. */
- cond = boolean_false_node;
+ cond = truthvalue_false_node;
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
expand_start_case (1, cond, TREE_TYPE (cond), "switch statement");
- expand_stmt (SWITCH_BODY (t));
+ expand_stmt (expand_unreachable_stmt (SWITCH_BODY (t), warn_notreached));
expand_end_case_type (cond, SWITCH_TYPE (t));
}
/* Create a CASE_LABEL tree node and return it. */
tree
-build_case_label (low_value, high_value, label_decl)
- tree low_value;
- tree high_value;
- tree label_decl;
+build_case_label (tree low_value, tree high_value, tree label_decl)
{
return build_stmt (CASE_LABEL, low_value, high_value, label_decl);
}
@@ -664,9 +684,8 @@ build_case_label (low_value, high_value, label_decl)
/* Generate the RTL for a CASE_LABEL. */
-void
-genrtl_case_label (case_label)
- tree case_label;
+void
+genrtl_case_label (tree case_label)
{
tree duplicate;
tree cleanup;
@@ -675,7 +694,7 @@ genrtl_case_label (case_label)
if (cleanup)
{
static int explained = 0;
- warning ("destructor needed for `%#D'", (TREE_PURPOSE (cleanup)));
+ warning ("destructor needed for `%D'", (TREE_PURPOSE (cleanup)));
warning ("where case label appears here");
if (!explained)
{
@@ -684,15 +703,14 @@ genrtl_case_label (case_label)
}
}
- add_case_node (CASE_LOW (case_label), CASE_HIGH (case_label),
+ add_case_node (CASE_LOW (case_label), CASE_HIGH (case_label),
CASE_LABEL_DECL (case_label), &duplicate);
}
/* Generate the RTL for T, which is a COMPOUND_STMT. */
void
-genrtl_compound_stmt (t)
- tree t;
+genrtl_compound_stmt (tree t)
{
#ifdef ENABLE_CHECKING
struct nesting *n = current_nesting_level ();
@@ -710,14 +728,8 @@ genrtl_compound_stmt (t)
/* Generate the RTL for an ASM_STMT. */
void
-genrtl_asm_stmt (cv_qualifier, string, output_operands,
- input_operands, clobbers, asm_input_p)
- tree cv_qualifier;
- tree string;
- tree output_operands;
- tree input_operands;
- tree clobbers;
- int asm_input_p;
+genrtl_asm_stmt (tree cv_qualifier, tree string, tree output_operands,
+ tree input_operands, tree clobbers, int asm_input_p)
{
if (cv_qualifier != NULL_TREE
&& cv_qualifier != ridpointers[(int) RID_VOLATILE])
@@ -727,23 +739,23 @@ genrtl_asm_stmt (cv_qualifier, string, output_operands,
cv_qualifier = NULL_TREE;
}
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
if (asm_input_p)
expand_asm (string, cv_qualifier != NULL_TREE);
else
- c_expand_asm_operands (string, output_operands, input_operands,
+ c_expand_asm_operands (string, output_operands, input_operands,
clobbers, cv_qualifier != NULL_TREE,
- input_filename, lineno);
+ input_location);
}
-/* Generate the RTL for a DECL_CLEANUP. */
+/* Generate the RTL for a CLEANUP_STMT. */
-void
-genrtl_decl_cleanup (t)
- tree t;
+void
+genrtl_cleanup_stmt (tree t)
{
tree decl = CLEANUP_DECL (t);
- if (!decl || (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node))
+ if (!decl || !DECL_P (decl)
+ || (DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node))
expand_decl_cleanup_eh (decl, CLEANUP_EXPR (t), CLEANUP_EH_ONLY (t));
}
@@ -751,11 +763,10 @@ genrtl_decl_cleanup (t)
for the substitution. */
void
-prep_stmt (t)
- tree t;
+prep_stmt (tree t)
{
if (!STMT_LINENO_FOR_FN_P (t))
- lineno = STMT_LINENO (t);
+ input_line = STMT_LINENO (t);
current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t);
}
@@ -763,8 +774,7 @@ prep_stmt (t)
other statements at its nesting level. */
void
-expand_stmt (t)
- tree t;
+expand_stmt (tree t)
{
while (t && t != error_mark_node)
{
@@ -782,7 +792,8 @@ expand_stmt (t)
case RETURN_STMT:
genrtl_return_stmt (t);
- break;
+ t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
+ goto process_t;
case EXPR_STMT:
genrtl_expr_stmt_value (EXPR_STMT_EXPR (t), TREE_ADDRESSABLE (t),
@@ -817,11 +828,13 @@ expand_stmt (t)
case BREAK_STMT:
genrtl_break_stmt ();
- break;
+ t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
+ goto process_t;
case CONTINUE_STMT:
genrtl_continue_stmt ();
- break;
+ t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
+ goto process_t;
case SWITCH_STMT:
genrtl_switch_stmt (t);
@@ -841,12 +854,13 @@ expand_stmt (t)
&& TREE_CODE (GOTO_DESTINATION (t)) == LABEL_DECL
&& flag_guess_branch_prob)
{
- rtx note = emit_note (NULL, NOTE_INSN_PREDICTION);
+ rtx note = emit_note (NOTE_INSN_PREDICTION);
NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_GOTO, NOT_TAKEN);
}
genrtl_goto_stmt (GOTO_DESTINATION (t));
- break;
+ t = expand_unreachable_stmt (TREE_CHAIN (t), warn_notreached);
+ goto process_t;
case ASM_STMT:
genrtl_asm_stmt (ASM_CV_QUAL (t), ASM_STRING (t),
@@ -859,22 +873,186 @@ expand_stmt (t)
break;
case CLEANUP_STMT:
- genrtl_decl_cleanup (t);
+ genrtl_cleanup_stmt (t);
break;
default:
if (lang_expand_stmt)
(*lang_expand_stmt) (t);
- else
+ else
abort ();
break;
}
+ /* Go on to the next statement in this scope. */
+ t = TREE_CHAIN (t);
+
+ process_t:
/* Restore saved state. */
current_stmt_tree ()->stmts_are_full_exprs_p
= saved_stmts_are_full_exprs_p;
+ }
+}
+
+/* If *TP is a potentially reachable label, return nonzero. */
- /* Go on to the next statement in this scope. */
+static tree
+find_reachable_label_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ switch (TREE_CODE (*tp))
+ {
+ case LABEL_STMT:
+ case CASE_LABEL:
+ return *tp;
+
+ default:
+ break;
+ }
+ return NULL_TREE;
+}
+
+/* Determine whether expression EXP contains a potentially
+ reachable label. */
+static tree
+find_reachable_label (tree exp)
+{
+ location_t saved_loc = input_location;
+ tree ret = walk_tree_without_duplicates
+ (&exp, find_reachable_label_1, NULL);
+ input_location = saved_loc;
+ return ret;
+}
+
+/* Expand an unreachable if statement, T. This function returns
+ true if the IF_STMT contains a potentially reachable code_label. */
+static bool
+expand_unreachable_if_stmt (tree t)
+{
+ tree n;
+
+ if (find_reachable_label (IF_COND (t)) != NULL_TREE)
+ {
+ genrtl_if_stmt (t);
+ return true;
+ }
+
+ if (THEN_CLAUSE (t) && ELSE_CLAUSE (t))
+ {
+ n = expand_unreachable_stmt (THEN_CLAUSE (t), 0);
+
+ if (n != NULL_TREE)
+ {
+ rtx label;
+ expand_stmt (n);
+ label = gen_label_rtx ();
+ emit_jump (label);
+ expand_stmt (expand_unreachable_stmt (ELSE_CLAUSE (t), 0));
+ emit_label (label);
+ return true;
+ }
+ else
+ n = expand_unreachable_stmt (ELSE_CLAUSE (t), 0);
+ }
+ else if (THEN_CLAUSE (t))
+ n = expand_unreachable_stmt (THEN_CLAUSE (t), 0);
+ else if (ELSE_CLAUSE (t))
+ n = expand_unreachable_stmt (ELSE_CLAUSE (t), 0);
+ else
+ n = NULL_TREE;
+
+ expand_stmt (n);
+
+ return n != NULL_TREE;
+}
+
+/* Expand an unreachable statement list. This function skips all
+ statements preceding the first potentially reachable label and
+ then returns the label (or, in same cases, the statement after
+ one containing the label). */
+static tree
+expand_unreachable_stmt (tree t, int warn)
+{
+ int saved;
+
+ while (t && t != error_mark_node)
+ {
+ if (warn)
+ switch (TREE_CODE (t))
+ {
+ case BREAK_STMT:
+ case CONTINUE_STMT:
+ case EXPR_STMT:
+ case GOTO_STMT:
+ case IF_STMT:
+ case RETURN_STMT:
+ if (!STMT_LINENO_FOR_FN_P (t))
+ input_line = STMT_LINENO (t);
+ warning("will never be executed");
+ warn = false;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (TREE_CODE (t))
+ {
+ case GOTO_STMT:
+ case CONTINUE_STMT:
+ case BREAK_STMT:
+ break;
+
+ case FILE_STMT:
+ input_filename = FILE_STMT_FILENAME (t);
+ break;
+
+ case RETURN_STMT:
+ if (find_reachable_label (RETURN_STMT_EXPR (t)) != NULL_TREE)
+ return t;
+ break;
+
+ case EXPR_STMT:
+ if (find_reachable_label (EXPR_STMT_EXPR (t)) != NULL_TREE)
+ return t;
+ break;
+
+ case IF_STMT:
+ if (expand_unreachable_if_stmt (t))
+ return TREE_CHAIN (t);
+ break;
+
+ case WHILE_STMT:
+ /* If the start of a while statement is unreachable, there is
+ no need to rotate the loop, instead the WHILE_STMT can be
+ expanded like a DO_STMT. */
+ genrtl_do_stmt_1 (WHILE_COND (t), WHILE_BODY (t));
+ return TREE_CHAIN (t);
+
+ case COMPOUND_STMT:
+ {
+ tree n;
+ n = expand_unreachable_stmt (COMPOUND_BODY (t), warn);
+ if (n != NULL_TREE)
+ {
+ expand_stmt (n);
+ return TREE_CHAIN (t);
+ }
+ warn = false;
+ break;
+ }
+
+ case SCOPE_STMT:
+ saved = stmts_are_full_exprs_p ();
+ prep_stmt (t);
+ genrtl_scope_stmt (t);
+ current_stmt_tree ()->stmts_are_full_exprs_p = saved;
+ break;
+
+ default:
+ return t;
+ }
t = TREE_CHAIN (t);
}
+ return NULL_TREE;
}
diff --git a/contrib/gcc/c-tree.h b/contrib/gcc/c-tree.h
index 159c235224e2..0500f81a3d8c 100644
--- a/contrib/gcc/c-tree.h
+++ b/contrib/gcc/c-tree.h
@@ -1,6 +1,6 @@
/* Definitions for C parsing and type checking.
Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -37,22 +37,19 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
struct lang_identifier GTY(())
{
struct c_common_identifier common_id;
- tree global_value;
- tree local_value;
+ tree symbol_value;
+ tree tag_value;
tree label_value;
- tree implicit_decl;
- tree error_locus;
- tree limbo_value;
};
/* The resulting tree type. */
-union lang_tree_node
+union lang_tree_node
GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
- chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
+ chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *)TYPE_NEXT_VARIANT (&%h.generic) : (union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
{
- union tree_node GTY ((tag ("0"),
- desc ("tree_node_structure (&%h)")))
+ union tree_node GTY ((tag ("0"),
+ desc ("tree_node_structure (&%h)")))
generic;
struct lang_identifier GTY ((tag ("1"))) identifier;
};
@@ -61,7 +58,6 @@ union lang_tree_node
struct lang_decl GTY(())
{
- struct c_lang_decl base;
/* The return types and parameter types may have variable size.
This is a list of any SAVE_EXPRs that need to be evaluated to
compute those sizes. */
@@ -71,30 +67,17 @@ struct lang_decl GTY(())
/* Macros for access to language-specific slots in an identifier. */
/* Each of these slots contains a DECL node or null. */
-/* This represents the value which the identifier has in the
- file-scope namespace. */
-#define IDENTIFIER_GLOBAL_VALUE(NODE) \
- (((struct lang_identifier *) (NODE))->global_value)
-/* This represents the value which the identifier has in the current
- scope. */
-#define IDENTIFIER_LOCAL_VALUE(NODE) \
- (((struct lang_identifier *) (NODE))->local_value)
-/* This represents the value which the identifier has as a label in
- the current label scope. */
+/* The value of the identifier in the namespace of "ordinary identifiers"
+ (data objects, enum constants, functions, typedefs). */
+#define IDENTIFIER_SYMBOL_VALUE(NODE) \
+ (((struct lang_identifier *) (NODE))->symbol_value)
+/* The value of the identifier in the namespace of struct, union,
+ and enum tags. */
+#define IDENTIFIER_TAG_VALUE(NODE) \
+ (((struct lang_identifier *) (NODE))->tag_value)
+/* The value of the identifier in the namespace of labels. */
#define IDENTIFIER_LABEL_VALUE(NODE) \
(((struct lang_identifier *) (NODE))->label_value)
-/* This records the extern decl of this identifier, if it has had one
- at any point in this compilation. */
-#define IDENTIFIER_LIMBO_VALUE(NODE) \
- (((struct lang_identifier *) (NODE))->limbo_value)
-/* This records the implicit function decl of this identifier, if it
- has had one at any point in this compilation. */
-#define IDENTIFIER_IMPLICIT_DECL(NODE) \
- (((struct lang_identifier *) (NODE))->implicit_decl)
-/* This is the last function in which we printed an "undefined variable"
- message for this identifier. Value is a FUNCTION_DECL or null. */
-#define IDENTIFIER_ERROR_LOCUS(NODE) \
- (((struct lang_identifier *) (NODE))->error_locus)
/* In identifiers, C uses the following fields in a special way:
TREE_PUBLIC to record that there was a previous local extern decl.
@@ -111,22 +94,19 @@ struct lang_decl GTY(())
nonzero if the definition of the type has already started. */
#define C_TYPE_BEING_DEFINED(TYPE) TYPE_LANG_FLAG_0 (TYPE)
+/* In an incomplete RECORD_TYPE or UNION_TYPE, a list of variable
+ declarations whose type would be completed by completing that type. */
+#define C_TYPE_INCOMPLETE_VARS(TYPE) TYPE_VFIELD (TYPE)
+
/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a
keyword. C_RID_CODE (node) is then the RID_* value of the keyword,
and C_RID_YYCODE is the token number wanted by Yacc. */
#define C_IS_RESERVED_WORD(ID) TREE_LANG_FLAG_0 (ID)
-/* This function was declared inline. This flag controls the linkage
- semantics of 'inline'; whether or not the function is inlined is
- controlled by DECL_INLINE. */
-#define DECL_DECLARED_INLINE_P(NODE) \
- (DECL_LANG_SPECIFIC (NODE)->base.declared_inline)
-
/* In a RECORD_TYPE, a sorted array of the fields of the type. */
struct lang_type GTY(())
{
- int len;
- tree GTY((length ("%h.len"))) elts[1];
+ struct sorted_fields_type * GTY ((reorder ("resort_sorted_fields"))) s;
};
/* Record whether a type or decl was written with nonconstant size.
@@ -134,13 +114,6 @@ struct lang_type GTY(())
#define C_TYPE_VARIABLE_SIZE(TYPE) TYPE_LANG_FLAG_1 (TYPE)
#define C_DECL_VARIABLE_SIZE(TYPE) DECL_LANG_FLAG_0 (TYPE)
-#if 0 /* Not used. */
-/* Record whether a decl for a function or function pointer has
- already been mentioned (in a warning) because it was called
- but didn't have a prototype. */
-#define C_MISSING_PROTOTYPE_WARNED(DECL) DECL_LANG_FLAG_2 (DECL)
-#endif
-
/* Store a value in that field. */
#define C_SET_EXP_ORIGINAL_CODE(EXP, CODE) \
(TREE_COMPLEXITY (EXP) = (int) (CODE))
@@ -152,103 +125,122 @@ struct lang_type GTY(())
return type. */
#define C_FUNCTION_IMPLICIT_INT(EXP) DECL_LANG_FLAG_1 (EXP)
-/* Nonzero for a declaration of a built in function if there has been no
- occasion that would declare the function in ordinary C.
- Using the function draws a pedantic warning in this case. */
-#define C_DECL_ANTICIPATED(EXP) DECL_LANG_FLAG_3 (EXP)
+/* For a FUNCTION_DECL, nonzero if it was an implicit declaration. */
+#define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP)
+
+/* Nonzero for a declaration of an external object which is not
+ currently in scope. This is either a built-in declaration of
+ a library function, before a real declaration has been seen,
+ or a declaration that appeared in an inner scope that has ended. */
+#define C_DECL_INVISIBLE(EXP) DECL_LANG_FLAG_3 (EXP)
+
+/* Nonzero for a decl which either doesn't exist or isn't a prototype.
+ N.B. Could be simplified if all built-in decls had complete prototypes
+ (but this is presently difficult because some of them need FILE*). */
+#define C_DECL_ISNT_PROTOTYPE(EXP) \
+ (EXP == 0 \
+ || (TYPE_ARG_TYPES (TREE_TYPE (EXP)) == 0 \
+ && !DECL_BUILT_IN (EXP)))
/* For FUNCTION_TYPE, a hidden list of types of arguments. The same as
TYPE_ARG_TYPES for functions with prototypes, but created for functions
without prototypes. */
#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_BINFO (NODE)
-
-/* in c-lang.c and objc-act.c */
-extern tree lookup_interface PARAMS ((tree));
-extern tree is_class_name PARAMS ((tree));
-extern tree objc_is_id PARAMS ((tree));
-extern void objc_check_decl PARAMS ((tree));
-extern void finish_file PARAMS ((void));
-extern int objc_comptypes PARAMS ((tree, tree, int));
-extern tree objc_message_selector PARAMS ((void));
-extern tree lookup_objc_ivar PARAMS ((tree));
+/* Values for the first parameter to poplevel. */
+#define KEEP_NO 0
+#define KEEP_YES 1
+#define KEEP_MAYBE 2
+
+/* Save and restore the variables in this file and elsewhere
+ that keep track of the progress of compilation of the current function.
+ Used for nested functions. */
+
+struct language_function GTY(())
+{
+ struct c_language_function base;
+ int returns_value;
+ int returns_null;
+ int returns_abnormally;
+ int warn_about_return_type;
+ int extern_inline;
+ int x_in_iteration_stmt;
+ int x_in_case_stmt;
+};
/* in c-parse.in */
-extern void c_parse_init PARAMS ((void));
+extern void c_parse_init (void);
/* in c-aux-info.c */
-extern void gen_aux_info_record PARAMS ((tree, int, int, int));
+extern void gen_aux_info_record (tree, int, int, int);
/* in c-decl.c */
-extern int global_bindings_p PARAMS ((void));
-extern int kept_level_p PARAMS ((void));
-extern tree getdecls PARAMS ((void));
-extern void pushlevel PARAMS ((int));
-extern tree poplevel PARAMS ((int,int, int));
-extern void insert_block PARAMS ((tree));
-extern void set_block PARAMS ((tree));
-extern tree pushdecl PARAMS ((tree));
-
-extern void c_insert_default_attributes PARAMS ((tree));
-extern void c_init_decl_processing PARAMS ((void));
-extern void c_dup_lang_specific_decl PARAMS ((tree));
-extern void c_print_identifier PARAMS ((FILE *, tree, int));
-extern tree build_array_declarator PARAMS ((tree, tree, int, int));
-extern tree build_enumerator PARAMS ((tree, tree));
-extern void check_for_loop_decls PARAMS ((void));
-extern void clear_parm_order PARAMS ((void));
-extern int complete_array_type PARAMS ((tree, tree, int));
-extern void declare_parm_level PARAMS ((int));
-extern tree define_label PARAMS ((const char *, int,
- tree));
-extern void finish_decl PARAMS ((tree, tree, tree));
-extern tree finish_enum PARAMS ((tree, tree, tree));
-extern void finish_function PARAMS ((int, int));
-extern tree finish_struct PARAMS ((tree, tree, tree));
-extern tree get_parm_info PARAMS ((int));
-extern tree grokfield PARAMS ((const char *, int, tree, tree, tree));
-extern tree groktypename PARAMS ((tree));
-extern tree groktypename_in_parm_context PARAMS ((tree));
-extern tree implicitly_declare PARAMS ((tree));
-extern void implicit_decl_warning PARAMS ((tree));
-extern int in_parm_level_p PARAMS ((void));
-extern void keep_next_level PARAMS ((void));
-extern tree lookup_name PARAMS ((tree));
-extern tree lookup_name_current_level PARAMS ((tree));
-extern void parmlist_tags_warning PARAMS ((void));
-extern void pending_xref_error PARAMS ((void));
-extern void c_push_function_context PARAMS ((struct function *));
-extern void c_pop_function_context PARAMS ((struct function *));
-extern void pop_label_level PARAMS ((void));
-extern void push_label_level PARAMS ((void));
-extern void push_parm_decl PARAMS ((tree));
-extern tree pushdecl_top_level PARAMS ((tree));
-extern void pushtag PARAMS ((tree, tree));
-extern tree set_array_declarator_type PARAMS ((tree, tree, int));
-extern tree shadow_label PARAMS ((tree));
-extern void shadow_tag PARAMS ((tree));
-extern void shadow_tag_warned PARAMS ((tree, int));
-extern tree start_enum PARAMS ((tree));
-extern int start_function PARAMS ((tree, tree, tree));
-extern tree start_decl PARAMS ((tree, tree, int,
- tree));
-extern tree start_struct PARAMS ((enum tree_code, tree));
-extern void store_parm_decls PARAMS ((void));
-extern tree xref_tag PARAMS ((enum tree_code, tree));
-extern tree c_begin_compound_stmt PARAMS ((void));
-extern void c_expand_deferred_function PARAMS ((tree));
-extern void c_expand_decl_stmt PARAMS ((tree));
-extern tree make_pointer_declarator PARAMS ((tree, tree));
+extern int c_in_iteration_stmt;
+extern int c_in_case_stmt;
+
+extern int global_bindings_p (void);
+extern tree getdecls (void);
+extern void pushlevel (int);
+extern void insert_block (tree);
+extern void set_block (tree);
+extern tree pushdecl (tree);
+extern void c_expand_body (tree);
+
+extern void c_init_decl_processing (void);
+extern void c_dup_lang_specific_decl (tree);
+extern void c_print_identifier (FILE *, tree, int);
+extern tree build_array_declarator (tree, tree, int, int);
+extern tree build_enumerator (tree, tree);
+extern void check_for_loop_decls (void);
+extern void mark_forward_parm_decls (void);
+extern int complete_array_type (tree, tree, int);
+extern void declare_parm_level (void);
+extern void undeclared_variable (tree);
+extern tree declare_label (tree);
+extern tree define_label (location_t, tree);
+extern void finish_decl (tree, tree, tree);
+extern tree finish_enum (tree, tree, tree);
+extern void finish_function (void);
+extern tree finish_struct (tree, tree, tree);
+extern tree get_parm_info (int);
+extern tree grokfield (tree, tree, tree);
+extern tree groktypename (tree);
+extern tree groktypename_in_parm_context (tree);
+extern tree implicitly_declare (tree);
+extern int in_parm_level_p (void);
+extern void keep_next_level (void);
+extern tree lookup_name (tree);
+extern void pending_xref_error (void);
+extern void c_push_function_context (struct function *);
+extern void c_pop_function_context (struct function *);
+extern void push_parm_decl (tree);
+extern tree pushdecl_top_level (tree);
+extern void pushtag (tree, tree);
+extern tree set_array_declarator_type (tree, tree, int);
+extern void shadow_tag (tree);
+extern void shadow_tag_warned (tree, int);
+extern tree start_enum (tree);
+extern int start_function (tree, tree, tree);
+extern tree start_decl (tree, tree, int, tree);
+extern tree start_struct (enum tree_code, tree);
+extern void store_parm_decls (void);
+extern tree xref_tag (enum tree_code, tree);
+extern tree c_begin_compound_stmt (void);
+extern void c_expand_deferred_function (tree);
+extern void c_expand_decl_stmt (tree);
+extern void c_static_assembler_name (tree);
+extern tree make_pointer_declarator (tree, tree);
+extern void merge_translation_unit_decls (void);
/* in c-objc-common.c */
-extern int c_disregard_inline_limits PARAMS ((tree));
-extern int c_cannot_inline_tree_fn PARAMS ((tree *));
-extern const char *c_objc_common_init PARAMS ((const char *));
-extern int c_missing_noreturn_ok_p PARAMS ((tree));
-extern void c_objc_common_finish_file PARAMS ((void));
-extern int defer_fn PARAMS ((tree));
-extern bool c_warn_unused_global_decl PARAMS ((tree));
+extern int c_disregard_inline_limits (tree);
+extern int c_cannot_inline_tree_fn (tree *);
+extern bool c_objc_common_init (void);
+extern int c_missing_noreturn_ok_p (tree);
+extern void c_objc_common_finish_file (void);
+extern int defer_fn (tree);
+extern bool c_warn_unused_global_decl (tree);
#define c_build_type_variant(TYPE, CONST_P, VOLATILE_P) \
c_build_qualified_type ((TYPE), \
@@ -256,47 +248,51 @@ extern bool c_warn_unused_global_decl PARAMS ((tree));
((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
#define c_sizeof_nowarn(T) c_sizeof_or_alignof_type (T, SIZEOF_EXPR, 0)
+
/* in c-typeck.c */
-extern tree require_complete_type PARAMS ((tree));
-extern int comptypes PARAMS ((tree, tree));
-extern tree c_size_in_bytes PARAMS ((tree));
-extern bool c_mark_addressable PARAMS ((tree));
-extern void c_incomplete_type_error PARAMS ((tree, tree));
-extern tree c_type_promotes_to PARAMS ((tree));
-extern tree build_component_ref PARAMS ((tree, tree));
-extern tree build_indirect_ref PARAMS ((tree, const char *));
-extern tree build_array_ref PARAMS ((tree, tree));
-extern tree build_external_ref PARAMS ((tree, int));
-extern tree parser_build_binary_op PARAMS ((enum tree_code,
- tree, tree));
-extern int c_tree_expr_nonnegative_p PARAMS ((tree));
-extern void readonly_warning PARAMS ((tree, const char *));
-extern tree build_conditional_expr PARAMS ((tree, tree, tree));
-extern tree build_compound_expr PARAMS ((tree));
-extern tree c_cast_expr PARAMS ((tree, tree));
-extern tree build_c_cast PARAMS ((tree, tree));
-extern tree build_modify_expr PARAMS ((tree, enum tree_code,
- tree));
-extern void store_init_value PARAMS ((tree, tree));
-extern void error_init PARAMS ((const char *));
-extern void pedwarn_init PARAMS ((const char *));
-extern void start_init PARAMS ((tree, tree, int));
-extern void finish_init PARAMS ((void));
-extern void really_start_incremental_init PARAMS ((tree));
-extern void push_init_level PARAMS ((int));
-extern tree pop_init_level PARAMS ((int));
-extern void set_init_index PARAMS ((tree, tree));
-extern void set_init_label PARAMS ((tree));
-extern void process_init_element PARAMS ((tree));
-extern tree build_compound_literal PARAMS ((tree, tree));
-extern void pedwarn_c99 PARAMS ((const char *, ...))
- ATTRIBUTE_PRINTF_1;
-extern tree c_start_case PARAMS ((tree));
-extern void c_finish_case PARAMS ((void));
-extern tree simple_asm_stmt PARAMS ((tree));
-extern tree build_asm_stmt PARAMS ((tree, tree, tree,
- tree, tree));
-extern tree c_convert_parm_for_inlining PARAMS ((tree, tree, tree));
+
+/* For use with comptypes. */
+enum {
+ COMPARE_STRICT = 0
+};
+
+extern tree require_complete_type (tree);
+extern int comptypes (tree, tree, int);
+extern tree c_size_in_bytes (tree);
+extern bool c_mark_addressable (tree);
+extern void c_incomplete_type_error (tree, tree);
+extern tree c_type_promotes_to (tree);
+extern tree build_component_ref (tree, tree);
+extern tree build_indirect_ref (tree, const char *);
+extern tree build_array_ref (tree, tree);
+extern tree build_external_ref (tree, int);
+extern tree parser_build_binary_op (enum tree_code, tree, tree);
+extern int c_tree_expr_nonnegative_p (tree);
+extern void readonly_error (tree, const char *);
+extern tree build_conditional_expr (tree, tree, tree);
+extern tree build_compound_expr (tree);
+extern tree c_cast_expr (tree, tree);
+extern tree build_c_cast (tree, tree);
+extern tree build_modify_expr (tree, enum tree_code, tree);
+extern void store_init_value (tree, tree);
+extern void error_init (const char *);
+extern void pedwarn_init (const char *);
+extern void start_init (tree, tree, int);
+extern void finish_init (void);
+extern void really_start_incremental_init (tree);
+extern void push_init_level (int);
+extern tree pop_init_level (int);
+extern void set_init_index (tree, tree);
+extern void set_init_label (tree);
+extern void process_init_element (tree);
+extern tree build_compound_literal (tree, tree);
+extern void pedwarn_c90 (const char *, ...) ATTRIBUTE_PRINTF_1;
+extern void pedwarn_c99 (const char *, ...) ATTRIBUTE_PRINTF_1;
+extern tree c_start_case (tree);
+extern void c_finish_case (void);
+extern tree simple_asm_stmt (tree);
+extern tree build_asm_stmt (tree, tree, tree, tree, tree);
+extern tree c_convert_parm_for_inlining (tree, tree, tree, int);
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement that specifies a return value is seen. */
@@ -318,9 +314,17 @@ extern int current_function_returns_abnormally;
extern int system_header_p;
/* In c-decl.c */
-extern void c_finish_incomplete_decl PARAMS ((tree));
+extern void c_finish_incomplete_decl (tree);
+extern void *get_current_scope (void);
+extern void objc_mark_locals_volatile (void *);
+extern void c_write_global_declarations (void);
extern GTY(()) tree static_ctors;
extern GTY(()) tree static_dtors;
+/* In order for the format checking to accept the C frontend
+ diagnostic framework extensions, you must include this file before
+ toplev.h, not after. */
+#define GCC_DIAG_STYLE __gcc_cdiag__
+
#endif /* ! GCC_C_TREE_H */
diff --git a/contrib/gcc/c-typeck.c b/contrib/gcc/c-typeck.c
index 40dc44de5107..c8d71e128f6b 100644
--- a/contrib/gcc/c-typeck.c
+++ b/contrib/gcc/c-typeck.c
@@ -1,6 +1,6 @@
/* Build expressions with type checking for C compiler.
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -31,6 +31,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "c-tree.h"
@@ -47,48 +49,48 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
message within this initializer. */
static int missing_braces_mentioned;
-/* 1 if we explained undeclared var errors. */
-static int undeclared_variable_notice;
-
-static tree qualify_type PARAMS ((tree, tree));
-static int comp_target_types PARAMS ((tree, tree, int));
-static int function_types_compatible_p PARAMS ((tree, tree));
-static int type_lists_compatible_p PARAMS ((tree, tree));
-static tree decl_constant_value_for_broken_optimization PARAMS ((tree));
-static tree default_function_array_conversion PARAMS ((tree));
-static tree lookup_field PARAMS ((tree, tree));
-static tree convert_arguments PARAMS ((tree, tree, tree, tree));
-static tree pointer_diff PARAMS ((tree, tree));
-static tree unary_complex_lvalue PARAMS ((enum tree_code, tree, int));
-static void pedantic_lvalue_warning PARAMS ((enum tree_code));
-static tree internal_build_compound_expr PARAMS ((tree, int));
-static tree convert_for_assignment PARAMS ((tree, tree, const char *,
- tree, tree, int));
-static void warn_for_assignment PARAMS ((const char *, const char *,
- tree, int));
-static tree valid_compound_expr_initializer PARAMS ((tree, tree));
-static void push_string PARAMS ((const char *));
-static void push_member_name PARAMS ((tree));
-static void push_array_bounds PARAMS ((int));
-static int spelling_length PARAMS ((void));
-static char *print_spelling PARAMS ((char *));
-static void warning_init PARAMS ((const char *));
-static tree digest_init PARAMS ((tree, tree, int));
-static void output_init_element PARAMS ((tree, tree, tree, int));
-static void output_pending_init_elements PARAMS ((int));
-static int set_designator PARAMS ((int));
-static void push_range_stack PARAMS ((tree));
-static void add_pending_init PARAMS ((tree, tree));
-static void set_nonincremental_init PARAMS ((void));
-static void set_nonincremental_init_from_string PARAMS ((tree));
-static tree find_init_member PARAMS ((tree));
+static int require_constant_value;
+static int require_constant_elements;
+
+static tree qualify_type (tree, tree);
+static int same_translation_unit_p (tree, tree);
+static int tagged_types_tu_compatible_p (tree, tree, int);
+static int comp_target_types (tree, tree, int);
+static int function_types_compatible_p (tree, tree, int);
+static int type_lists_compatible_p (tree, tree, int);
+static tree decl_constant_value_for_broken_optimization (tree);
+static tree default_function_array_conversion (tree);
+static tree lookup_field (tree, tree);
+static tree convert_arguments (tree, tree, tree, tree);
+static tree pointer_diff (tree, tree);
+static tree unary_complex_lvalue (enum tree_code, tree, int);
+static void pedantic_lvalue_warning (enum tree_code);
+static tree internal_build_compound_expr (tree, int);
+static tree convert_for_assignment (tree, tree, const char *, tree, tree,
+ int);
+static void warn_for_assignment (const char *, const char *, tree, int);
+static tree valid_compound_expr_initializer (tree, tree);
+static void push_string (const char *);
+static void push_member_name (tree);
+static void push_array_bounds (int);
+static int spelling_length (void);
+static char *print_spelling (char *);
+static void warning_init (const char *);
+static tree digest_init (tree, tree, int);
+static void output_init_element (tree, tree, tree, int);
+static void output_pending_init_elements (int);
+static int set_designator (int);
+static void push_range_stack (tree);
+static void add_pending_init (tree, tree);
+static void set_nonincremental_init (void);
+static void set_nonincremental_init_from_string (tree);
+static tree find_init_member (tree);
/* Do `exp = require_complete_type (exp);' to make sure exp
does not have an incomplete type. (That includes void types.) */
tree
-require_complete_type (value)
- tree value;
+require_complete_type (tree value)
{
tree type = TREE_TYPE (value);
@@ -108,9 +110,7 @@ require_complete_type (value)
and TYPE is the type that was invalid. */
void
-c_incomplete_type_error (value, type)
- tree value;
- tree type;
+c_incomplete_type_error (tree value, tree type)
{
const char *type_code_string;
@@ -177,8 +177,7 @@ c_incomplete_type_error (value, type)
arguments and return the new type. */
tree
-c_type_promotes_to (type)
- tree type;
+c_type_promotes_to (tree type)
{
if (TYPE_MAIN_VARIANT (type) == float_type_node)
return double_type_node;
@@ -199,10 +198,9 @@ c_type_promotes_to (type)
as well as those of TYPE. */
static tree
-qualify_type (type, like)
- tree type, like;
+qualify_type (tree type, tree like)
{
- return c_build_qualified_type (type,
+ return c_build_qualified_type (type,
TYPE_QUALS (type) | TYPE_QUALS (like));
}
@@ -215,8 +213,7 @@ qualify_type (type, like)
if the operands have the given two types. */
tree
-common_type (t1, t2)
- tree t1, t2;
+common_type (tree t1, tree t2)
{
enum tree_code code1;
enum tree_code code2;
@@ -286,26 +283,36 @@ common_type (t1, t2)
if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
|| TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
- return build_type_attribute_variant (long_unsigned_type_node,
- attributes);
+ {
+ t1 = build_qualified_type (long_unsigned_type_node,
+ TYPE_QUALS (t1));
+ return build_type_attribute_variant (t1, attributes);
+ }
if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
|| TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
{
+ tree ntype;
+
/* But preserve unsignedness from the other type,
since long cannot hold all the values of an unsigned int. */
if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2))
- t1 = long_unsigned_type_node;
+ ntype = long_unsigned_type_node;
else
- t1 = long_integer_type_node;
- return build_type_attribute_variant (t1, attributes);
+ ntype = long_integer_type_node;
+
+ ntype = build_qualified_type (ntype, TYPE_QUALS (t1));
+ return build_type_attribute_variant (ntype, attributes);
}
/* Likewise, prefer long double to double even if same size. */
if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
|| TYPE_MAIN_VARIANT (t2) == long_double_type_node)
- return build_type_attribute_variant (long_double_type_node,
- attributes);
+ {
+ t1 = build_qualified_type (long_double_type_node,
+ TYPE_QUALS (t1));
+ return build_type_attribute_variant (t1, attributes);
+ }
/* Otherwise prefer the unsigned one. */
@@ -325,16 +332,12 @@ common_type (t1, t2)
tree pointed_to_2 = TREE_TYPE (t2);
tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1),
TYPE_MAIN_VARIANT (pointed_to_2));
- t1 = build_pointer_type (c_build_qualified_type
- (target,
- TYPE_QUALS (pointed_to_1) |
+ t1 = build_pointer_type (c_build_qualified_type
+ (target,
+ TYPE_QUALS (pointed_to_1) |
TYPE_QUALS (pointed_to_2)));
return build_type_attribute_variant (t1, attributes);
}
-#if 0
- t1 = build_pointer_type (common_type (TREE_TYPE (t1), TREE_TYPE (t2)));
- return build_type_attribute_variant (t1, attributes);
-#endif
case ARRAY_TYPE:
{
@@ -382,7 +385,7 @@ common_type (t1, t2)
lists, argument by argument. */
pushlevel (0);
- declare_parm_level (1);
+ declare_parm_level ();
len = list_length (p1);
newargs = 0;
@@ -407,7 +410,7 @@ common_type (t1, t2)
TREE_VALUE (n) = TREE_VALUE (p1);
goto parm_done;
}
-
+
/* Given wait (union {union wait *u; int *i} *)
and wait (union wait *),
prefer union wait * as type of parm. */
@@ -417,7 +420,8 @@ common_type (t1, t2)
tree memb;
for (memb = TYPE_FIELDS (TREE_VALUE (p1));
memb; memb = TREE_CHAIN (memb))
- if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2)))
+ if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2),
+ COMPARE_STRICT))
{
TREE_VALUE (n) = TREE_VALUE (p2);
if (pedantic)
@@ -431,7 +435,8 @@ common_type (t1, t2)
tree memb;
for (memb = TYPE_FIELDS (TREE_VALUE (p2));
memb; memb = TREE_CHAIN (memb))
- if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1)))
+ if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1),
+ COMPARE_STRICT))
{
TREE_VALUE (n) = TREE_VALUE (p1);
if (pedantic)
@@ -460,8 +465,7 @@ common_type (t1, t2)
but a warning may be needed if you use them together. */
int
-comptypes (type1, type2)
- tree type1, type2;
+comptypes (tree type1, tree type2, int flags)
{
tree t1 = type1;
tree t2 = type2;
@@ -483,12 +487,13 @@ comptypes (type1, type2)
&& TYPE_DOMAIN (t2) != 0)
t2 = TYPE_DOMAIN (t2);
- /* Treat an enum type as the integer type of the same width and
- signedness. */
+ /* Enumerated types are compatible with integer types, but this is
+ not transitive: two enumerated types in the same translation unit
+ are compatible with each other only if they are the same type. */
- if (TREE_CODE (t1) == ENUMERAL_TYPE)
+ if (TREE_CODE (t1) == ENUMERAL_TYPE && TREE_CODE (t2) != ENUMERAL_TYPE)
t1 = c_common_type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1));
- if (TREE_CODE (t2) == ENUMERAL_TYPE)
+ else if (TREE_CODE (t2) == ENUMERAL_TYPE && TREE_CODE (t1) != ENUMERAL_TYPE)
t2 = c_common_type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2));
if (t1 == t2)
@@ -496,7 +501,8 @@ comptypes (type1, type2)
/* Different classes of types can't be compatible. */
- if (TREE_CODE (t1) != TREE_CODE (t2)) return 0;
+ if (TREE_CODE (t1) != TREE_CODE (t2))
+ return 0;
/* Qualifiers must match. */
@@ -520,12 +526,16 @@ comptypes (type1, type2)
switch (TREE_CODE (t1))
{
case POINTER_TYPE:
+ /* We must give ObjC the first crack at comparing pointers, since
+ protocol qualifiers may be involved. */
+ if (c_dialect_objc () && (val = objc_comptypes (t1, t2, 0)) >= 0)
+ break;
val = (TREE_TYPE (t1) == TREE_TYPE (t2)
- ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2)));
+ ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2), flags));
break;
case FUNCTION_TYPE:
- val = function_types_compatible_p (t1, t2);
+ val = function_types_compatible_p (t1, t2, flags);
break;
case ARRAY_TYPE:
@@ -538,7 +548,8 @@ comptypes (type1, type2)
/* Target types must match incl. qualifiers. */
if (TREE_TYPE (t1) != TREE_TYPE (t2)
- && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2))))
+ && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2),
+ flags)))
return 0;
/* Sizes must match unless one is missing or variable. */
@@ -568,8 +579,21 @@ comptypes (type1, type2)
}
case RECORD_TYPE:
- if (flag_objc && objc_comptypes (t1, t2, 0) == 1)
+ /* We are dealing with two distinct structs. In assorted Objective-C
+ corner cases, however, these can still be deemed equivalent. */
+ if (c_dialect_objc () && objc_comptypes (t1, t2, 0) == 1)
val = 1;
+
+ case ENUMERAL_TYPE:
+ case UNION_TYPE:
+ if (val != 1 && !same_translation_unit_p (t1, t2))
+ val = tagged_types_tu_compatible_p (t1, t2, flags);
+ break;
+
+ case VECTOR_TYPE:
+ /* The target might allow certain vector types to be compatible. */
+ val = (*targetm.vector_opaque_p) (t1)
+ || (*targetm.vector_opaque_p) (t2);
break;
default:
@@ -586,9 +610,7 @@ comptypes (type1, type2)
*/
static int
-comp_target_types (ttl, ttr, reflexive)
- tree ttl, ttr;
- int reflexive;
+comp_target_types (tree ttl, tree ttr, int reflexive)
{
int val;
@@ -597,7 +619,7 @@ comp_target_types (ttl, ttr, reflexive)
return val;
val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)),
- TYPE_MAIN_VARIANT (TREE_TYPE (ttr)));
+ TYPE_MAIN_VARIANT (TREE_TYPE (ttr)), COMPARE_STRICT);
if (val == 2 && pedantic)
pedwarn ("types are not quite compatible");
@@ -606,24 +628,222 @@ comp_target_types (ttl, ttr, reflexive)
/* Subroutines of `comptypes'. */
+/* Determine whether two types derive from the same translation unit.
+ If the CONTEXT chain ends in a null, that type's context is still
+ being parsed, so if two types have context chains ending in null,
+ they're in the same translation unit. */
+static int
+same_translation_unit_p (tree t1, tree t2)
+{
+ while (t1 && TREE_CODE (t1) != TRANSLATION_UNIT_DECL)
+ switch (TREE_CODE_CLASS (TREE_CODE (t1)))
+ {
+ case 'd': t1 = DECL_CONTEXT (t1); break;
+ case 't': t1 = TYPE_CONTEXT (t1); break;
+ case 'b': t1 = BLOCK_SUPERCONTEXT (t1); break;
+ default: abort ();
+ }
+
+ while (t2 && TREE_CODE (t2) != TRANSLATION_UNIT_DECL)
+ switch (TREE_CODE_CLASS (TREE_CODE (t2)))
+ {
+ case 'd': t2 = DECL_CONTEXT (t1); break;
+ case 't': t2 = TYPE_CONTEXT (t2); break;
+ case 'b': t2 = BLOCK_SUPERCONTEXT (t2); break;
+ default: abort ();
+ }
+
+ return t1 == t2;
+}
+
+/* The C standard says that two structures in different translation
+ units are compatible with each other only if the types of their
+ fields are compatible (among other things). So, consider two copies
+ of this structure: */
+
+struct tagged_tu_seen {
+ const struct tagged_tu_seen * next;
+ tree t1;
+ tree t2;
+};
+
+/* Can they be compatible with each other? We choose to break the
+ recursion by allowing those types to be compatible. */
+
+static const struct tagged_tu_seen * tagged_tu_seen_base;
+
+/* Return 1 if two 'struct', 'union', or 'enum' types T1 and T2 are
+ 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. */
+
+static int
+tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
+{
+ tree s1, s2;
+ bool needs_warning = false;
+
+ /* We have to verify that the tags of the types are the same. This
+ is harder than it looks because this may be a typedef, so we have
+ to go look at the original type. It may even be a typedef of a
+ typedef... */
+ while (TYPE_NAME (t1)
+ && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL
+ && DECL_ORIGINAL_TYPE (TYPE_NAME (t1)))
+ t1 = DECL_ORIGINAL_TYPE (TYPE_NAME (t1));
+
+ while (TYPE_NAME (t2)
+ && TREE_CODE (TYPE_NAME (t2)) == TYPE_DECL
+ && DECL_ORIGINAL_TYPE (TYPE_NAME (t2)))
+ t2 = DECL_ORIGINAL_TYPE (TYPE_NAME (t2));
+
+ /* C90 didn't have the requirement that the two tags be the same. */
+ if (flag_isoc99 && TYPE_NAME (t1) != TYPE_NAME (t2))
+ return 0;
+
+ /* C90 didn't say what happened if one or both of the types were
+ incomplete; we choose to follow C99 rules here, which is that they
+ are compatible. */
+ if (TYPE_SIZE (t1) == NULL
+ || TYPE_SIZE (t2) == NULL)
+ return 1;
+
+ {
+ const struct tagged_tu_seen * tts_i;
+ for (tts_i = tagged_tu_seen_base; tts_i != NULL; tts_i = tts_i->next)
+ if (tts_i->t1 == t1 && tts_i->t2 == t2)
+ return 1;
+ }
+
+ switch (TREE_CODE (t1))
+ {
+ case ENUMERAL_TYPE:
+ {
+ if (list_length (TYPE_VALUES (t1)) != list_length (TYPE_VALUES (t2)))
+ return 0;
+
+ for (s1 = TYPE_VALUES (t1); s1; s1 = TREE_CHAIN (s1))
+ {
+ s2 = purpose_member (TREE_PURPOSE (s1), TYPE_VALUES (t2));
+ if (s2 == NULL
+ || simple_cst_equal (TREE_VALUE (s1), TREE_VALUE (s2)) != 1)
+ return 0;
+ }
+ return 1;
+ }
+
+ case UNION_TYPE:
+ {
+ if (list_length (TYPE_FIELDS (t1)) != list_length (TYPE_FIELDS (t2)))
+ return 0;
+
+ for (s1 = TYPE_FIELDS (t1); s1; s1 = TREE_CHAIN (s1))
+ {
+ bool ok = false;
+ struct tagged_tu_seen tts;
+
+ tts.next = tagged_tu_seen_base;
+ tts.t1 = t1;
+ tts.t2 = t2;
+ tagged_tu_seen_base = &tts;
+
+ if (DECL_NAME (s1) != NULL)
+ for (s2 = TYPE_VALUES (t2); s2; s2 = TREE_CHAIN (s2))
+ if (DECL_NAME (s1) == DECL_NAME (s2))
+ {
+ int result;
+ result = comptypes (TREE_TYPE (s1), TREE_TYPE (s2), flags);
+ if (result == 0)
+ break;
+ if (result == 2)
+ needs_warning = true;
+
+ if (TREE_CODE (s1) == FIELD_DECL
+ && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
+ DECL_FIELD_BIT_OFFSET (s2)) != 1)
+ break;
+
+ ok = true;
+ break;
+ }
+ tagged_tu_seen_base = tts.next;
+ if (! ok)
+ return 0;
+ }
+ return needs_warning ? 2 : 1;
+ }
+
+ case RECORD_TYPE:
+ {
+ struct tagged_tu_seen tts;
+
+ tts.next = tagged_tu_seen_base;
+ tts.t1 = t1;
+ tts.t2 = t2;
+ tagged_tu_seen_base = &tts;
+
+ for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2);
+ s1 && s2;
+ s1 = TREE_CHAIN (s1), s2 = TREE_CHAIN (s2))
+ {
+ int result;
+ if (TREE_CODE (s1) != TREE_CODE (s2)
+ || DECL_NAME (s1) != DECL_NAME (s2))
+ break;
+ result = comptypes (TREE_TYPE (s1), TREE_TYPE (s2), flags);
+ if (result == 0)
+ break;
+ if (result == 2)
+ needs_warning = true;
+
+ if (TREE_CODE (s1) == FIELD_DECL
+ && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
+ DECL_FIELD_BIT_OFFSET (s2)) != 1)
+ break;
+ }
+ tagged_tu_seen_base = tts.next;
+ if (s1 && s2)
+ return 0;
+ return needs_warning ? 2 : 1;
+ }
+
+ default:
+ abort ();
+ }
+}
+
/* Return 1 if two function types F1 and F2 are compatible.
If either type specifies no argument types,
the other must specify a fixed number of self-promoting arg types.
- Otherwise, if one type specifies only the number of arguments,
+ 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. */
static int
-function_types_compatible_p (f1, f2)
- tree f1, f2;
+function_types_compatible_p (tree f1, tree f2, int flags)
{
tree args1, args2;
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
int val = 1;
int val1;
-
- if (!(TREE_TYPE (f1) == TREE_TYPE (f2)
- || (val = comptypes (TREE_TYPE (f1), TREE_TYPE (f2)))))
+ tree ret1, ret2;
+
+ ret1 = TREE_TYPE (f1);
+ ret2 = TREE_TYPE (f2);
+
+ /* 'volatile' qualifiers on a function's return type mean the function
+ is noreturn. */
+ if (pedantic && TYPE_VOLATILE (ret1) != TYPE_VOLATILE (ret2))
+ pedwarn ("function return types not compatible due to `volatile'");
+ if (TYPE_VOLATILE (ret1))
+ ret1 = build_qualified_type (TYPE_MAIN_VARIANT (ret1),
+ TYPE_QUALS (ret1) & ~TYPE_QUAL_VOLATILE);
+ if (TYPE_VOLATILE (ret2))
+ ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2),
+ TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE);
+ val = comptypes (ret1, ret2, flags);
+ if (val == 0)
return 0;
args1 = TYPE_ARG_TYPES (f1);
@@ -640,7 +860,8 @@ function_types_compatible_p (f1, 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),
+ flags))
val = 2;
return val;
}
@@ -649,13 +870,14 @@ function_types_compatible_p (f1, 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),
+ flags))
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, flags);
return val1 != 1 ? val1 : val;
}
@@ -664,8 +886,7 @@ function_types_compatible_p (f1, f2)
or 2 for compatible with warning. */
static int
-type_lists_compatible_p (args1, args2)
- tree args1, args2;
+type_lists_compatible_p (tree args1, tree args2, int flags)
{
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
int val = 1;
@@ -693,8 +914,13 @@ type_lists_compatible_p (args1, args2)
if (c_type_promotes_to (TREE_VALUE (args1)) != TREE_VALUE (args1))
return 0;
}
- else if (! (newval = comptypes (TYPE_MAIN_VARIANT (TREE_VALUE (args1)),
- TYPE_MAIN_VARIANT (TREE_VALUE (args2)))))
+ /* If one of the lists has an error marker, ignore this arg. */
+ else if (TREE_CODE (TREE_VALUE (args1)) == ERROR_MARK
+ || TREE_CODE (TREE_VALUE (args2)) == ERROR_MARK)
+ ;
+ else if (! (newval = comptypes (TYPE_MAIN_VARIANT (TREE_VALUE (args1)),
+ TYPE_MAIN_VARIANT (TREE_VALUE (args2)),
+ flags)))
{
/* Allow wait (union {union wait *u; int *i} *)
and wait (union wait *) to be compatible. */
@@ -708,7 +934,8 @@ type_lists_compatible_p (args1, args2)
tree memb;
for (memb = TYPE_FIELDS (TREE_VALUE (args1));
memb; memb = TREE_CHAIN (memb))
- if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2)))
+ if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2),
+ flags))
break;
if (memb == 0)
return 0;
@@ -723,7 +950,8 @@ type_lists_compatible_p (args1, args2)
tree memb;
for (memb = TYPE_FIELDS (TREE_VALUE (args2));
memb; memb = TREE_CHAIN (memb))
- if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1)))
+ if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1),
+ flags))
break;
if (memb == 0)
return 0;
@@ -744,8 +972,7 @@ type_lists_compatible_p (args1, args2)
/* Compute the size to increment a pointer by. */
tree
-c_size_in_bytes (type)
- tree type;
+c_size_in_bytes (tree type)
{
enum tree_code code = TREE_CODE (type);
@@ -767,8 +994,7 @@ c_size_in_bytes (type)
/* Return either DECL or its known constant value (if it has one). */
tree
-decl_constant_value (decl)
- tree decl;
+decl_constant_value (tree decl)
{
if (/* Don't change a variable array bound or initial value to a constant
in a place where a variable is invalid. */
@@ -796,8 +1022,7 @@ decl_constant_value (decl)
right test for avoiding misoptimizations either. */
static tree
-decl_constant_value_for_broken_optimization (decl)
- tree decl;
+decl_constant_value_for_broken_optimization (tree decl)
{
if (pedantic || DECL_MODE (decl) == BLKmode)
return decl;
@@ -811,8 +1036,7 @@ decl_constant_value_for_broken_optimization (decl)
return EXP. */
static tree
-default_function_array_conversion (exp)
- tree exp;
+default_function_array_conversion (tree exp)
{
tree orig_exp;
tree type = TREE_TYPE (exp);
@@ -820,7 +1044,7 @@ default_function_array_conversion (exp)
int not_lvalue = 0;
/* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as
- an lvalue.
+ an lvalue.
Do not use STRIP_NOPS here! It will remove conversions from pointer
to integer and cause infinite recursion. */
@@ -858,9 +1082,9 @@ default_function_array_conversion (exp)
}
if (TYPE_QUALS (type) || constp || volatilep)
- restype
+ restype
= c_build_qualified_type (restype,
- TYPE_QUALS (type)
+ TYPE_QUALS (type)
| (constp * TYPE_QUAL_CONST)
| (volatilep * TYPE_QUAL_VOLATILE));
@@ -914,8 +1138,7 @@ default_function_array_conversion (exp)
In addition, manifest constants symbols are replaced by their values. */
tree
-default_conversion (exp)
- tree exp;
+default_conversion (tree exp)
{
tree orig_exp;
tree type = TREE_TYPE (exp);
@@ -938,7 +1161,7 @@ default_conversion (exp)
}
/* Strip NON_LVALUE_EXPRs and no-op conversions, since we aren't using as
- an lvalue.
+ an lvalue.
Do not use STRIP_NOPS here! It will remove conversions from pointer
to integer and cause infinite recursion. */
@@ -999,10 +1222,9 @@ default_conversion (exp)
TREE_VALUE of the list. Normally the list is of length one, but if
the component is embedded within (nested) anonymous structures or
unions, the list steps down the chain to the component. */
-
+
static tree
-lookup_field (decl, component)
- tree decl, component;
+lookup_field (tree decl, tree component)
{
tree type = TREE_TYPE (decl);
tree field;
@@ -1015,11 +1237,11 @@ lookup_field (decl, component)
if (TYPE_LANG_SPECIFIC (type))
{
int bot, top, half;
- tree *field_array = &TYPE_LANG_SPECIFIC (type)->elts[0];
+ tree *field_array = &TYPE_LANG_SPECIFIC (type)->s->elts[0];
field = TYPE_FIELDS (type);
bot = 0;
- top = TYPE_LANG_SPECIFIC (type)->len;
+ top = TYPE_LANG_SPECIFIC (type)->s->len;
while (top - bot > 1)
{
half = (top - bot + 1) >> 1;
@@ -1038,7 +1260,7 @@ lookup_field (decl, component)
if (anon)
return tree_cons (NULL_TREE, field, anon);
- }
+ }
}
/* Entire record is only anon unions. */
@@ -1091,8 +1313,7 @@ lookup_field (decl, component)
structure or union value DATUM. COMPONENT is an IDENTIFIER_NODE. */
tree
-build_component_ref (datum, component)
- tree datum, component;
+build_component_ref (tree datum, tree component)
{
tree type = TREE_TYPE (datum);
enum tree_code code = TREE_CODE (type);
@@ -1180,9 +1401,7 @@ build_component_ref (datum, component)
ERRORSTRING is the name of the operator to appear in error messages. */
tree
-build_indirect_ref (ptr, errorstring)
- tree ptr;
- const char *errorstring;
+build_indirect_ref (tree ptr, const char *errorstring)
{
tree pointer = default_conversion (ptr);
tree type = TREE_TYPE (pointer);
@@ -1190,7 +1409,6 @@ build_indirect_ref (ptr, errorstring)
if (TREE_CODE (type) == POINTER_TYPE)
{
if (TREE_CODE (pointer) == ADDR_EXPR
- && !flag_volatile
&& (TREE_TYPE (TREE_OPERAND (pointer, 0))
== TREE_TYPE (type)))
return TREE_OPERAND (pointer, 0);
@@ -1216,7 +1434,7 @@ build_indirect_ref (ptr, errorstring)
to change it via some other pointer. */
TREE_READONLY (ref) = TYPE_READONLY (t);
TREE_SIDE_EFFECTS (ref)
- = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile;
+ = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer);
TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
return ref;
}
@@ -1236,8 +1454,7 @@ build_indirect_ref (ptr, errorstring)
by functions). */
tree
-build_array_ref (array, index)
- tree array, index;
+build_array_ref (tree array, tree index)
{
if (index == 0)
{
@@ -1321,7 +1538,7 @@ build_array_ref (array, index)
TREE_THIS_VOLATILE (rval)
|= (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (array)))
/* This was added by rms on 16 Nov 91.
- It fixes vol struct foo *a; a->elts[1]
+ It fixes vol struct foo *a; a->elts[1]
in an inline function.
Hope it doesn't break something else. */
| TREE_THIS_VOLATILE (array));
@@ -1371,72 +1588,18 @@ build_array_ref (array, index)
/* Build an external reference to identifier ID. FUN indicates
whether this will be used for a function call. */
tree
-build_external_ref (id, fun)
- tree id;
- int fun;
+build_external_ref (tree id, int fun)
{
tree ref;
tree decl = lookup_name (id);
tree objc_ivar = lookup_objc_ivar (id);
- if (decl && TREE_DEPRECATED (decl))
- warn_deprecated_use (decl);
-
- if (!decl || decl == error_mark_node || C_DECL_ANTICIPATED (decl))
- {
- if (objc_ivar)
- ref = objc_ivar;
- else if (fun)
- {
- if (!decl || decl == error_mark_node)
- /* Ordinary implicit function declaration. */
- ref = implicitly_declare (id);
- else
- {
- /* Implicit declaration of built-in function. Don't
- change the built-in declaration, but don't let this
- go by silently, either. */
- implicit_decl_warning (id);
-
- /* only issue this warning once */
- C_DECL_ANTICIPATED (decl) = 0;
- ref = decl;
- }
- }
- else
- {
- /* Reference to undeclared variable, including reference to
- builtin outside of function-call context. */
- if (current_function_decl == 0)
- error ("`%s' undeclared here (not in a function)",
- IDENTIFIER_POINTER (id));
- else
- {
- if (IDENTIFIER_GLOBAL_VALUE (id) != error_mark_node
- || IDENTIFIER_ERROR_LOCUS (id) != current_function_decl)
- {
- error ("`%s' undeclared (first use in this function)",
- IDENTIFIER_POINTER (id));
-
- if (! undeclared_variable_notice)
- {
- error ("(Each undeclared identifier is reported only once");
- error ("for each function it appears in.)");
- undeclared_variable_notice = 1;
- }
- }
- IDENTIFIER_GLOBAL_VALUE (id) = error_mark_node;
- IDENTIFIER_ERROR_LOCUS (id) = current_function_decl;
- }
- return error_mark_node;
- }
- }
- else
+ if (decl && decl != error_mark_node)
{
/* Properly declared variable or function reference. */
if (!objc_ivar)
ref = decl;
- else if (decl != objc_ivar && IDENTIFIER_LOCAL_VALUE (id))
+ else if (decl != objc_ivar && !DECL_FILE_SCOPE_P (decl))
{
warning ("local declaration of `%s' hides instance variable",
IDENTIFIER_POINTER (id));
@@ -1445,10 +1608,27 @@ build_external_ref (id, fun)
else
ref = objc_ivar;
}
+ else if (objc_ivar)
+ ref = objc_ivar;
+ else if (fun)
+ /* Implicit function declaration. */
+ ref = implicitly_declare (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);
+ return error_mark_node;
+ }
if (TREE_TYPE (ref) == error_mark_node)
return error_mark_node;
+ if (TREE_DEPRECATED (ref))
+ warn_deprecated_use (ref);
+
if (!skip_evaluation)
assemble_external (ref);
TREE_USED (ref) = 1;
@@ -1459,13 +1639,13 @@ build_external_ref (id, fun)
TREE_CONSTANT (ref) = 1;
}
else if (current_function_decl != 0
- && DECL_CONTEXT (current_function_decl) != 0
+ && !DECL_FILE_SCOPE_P (current_function_decl)
&& (TREE_CODE (ref) == VAR_DECL
|| TREE_CODE (ref) == PARM_DECL
|| TREE_CODE (ref) == FUNCTION_DECL))
{
tree context = decl_function_context (ref);
-
+
if (context != 0 && context != current_function_decl)
DECL_NONLOCAL (ref) = 1;
}
@@ -1479,12 +1659,12 @@ build_external_ref (id, fun)
FUNCTION's data type may be a function type or a pointer-to-function. */
tree
-build_function_call (function, params)
- tree function, params;
+build_function_call (tree function, tree params)
{
tree fntype, fundecl = 0;
tree coerced_params;
- tree name = NULL_TREE, assembler_name = NULL_TREE, result;
+ tree name = NULL_TREE, result;
+ tree tem;
/* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
STRIP_TYPE_NOPS (function);
@@ -1493,7 +1673,6 @@ build_function_call (function, params)
if (TREE_CODE (function) == FUNCTION_DECL)
{
name = DECL_NAME (function);
- assembler_name = DECL_ASSEMBLER_NAME (function);
/* Differs from default_conversion by not setting TREE_ADDRESSABLE
(because calling an inline function does not mean the function
@@ -1525,6 +1704,51 @@ build_function_call (function, params)
/* fntype now gets the type of function pointed to. */
fntype = TREE_TYPE (fntype);
+ /* Check that the function is called through a compatible prototype.
+ If it is not, replace the call by a trap, wrapped up in a compound
+ expression if necessary. This has the nice side-effect to prevent
+ the tree-inliner from generating invalid assignment trees which may
+ blow up in the RTL expander later.
+
+ ??? This doesn't work for Objective-C because objc_comptypes
+ refuses to compare function prototypes, yet the compiler appears
+ to build calls that are flagged as invalid by C's comptypes. */
+ if (! c_dialect_objc ()
+ && TREE_CODE (function) == NOP_EXPR
+ && TREE_CODE (tem = TREE_OPERAND (function, 0)) == ADDR_EXPR
+ && TREE_CODE (tem = TREE_OPERAND (tem, 0)) == FUNCTION_DECL
+ && ! comptypes (fntype, TREE_TYPE (tem), COMPARE_STRICT))
+ {
+ tree return_type = TREE_TYPE (fntype);
+ tree trap = build_function_call (built_in_decls[BUILT_IN_TRAP],
+ NULL_TREE);
+
+ /* 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. */
+ warning ("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 ("if this code is reached, the program will abort");
+
+ if (VOID_TYPE_P (return_type))
+ return trap;
+ else
+ {
+ tree rhs;
+
+ if (AGGREGATE_TYPE_P (return_type))
+ rhs = build_compound_literal (return_type,
+ build_constructor (return_type,
+ NULL_TREE));
+ else
+ rhs = fold (build1 (NOP_EXPR, return_type, integer_zero_node));
+
+ return build (COMPOUND_EXPR, return_type, trap, rhs);
+ }
+ }
+
/* Convert the parameters to the types declared in the
function prototype, or apply default promotions. */
@@ -1552,7 +1776,18 @@ build_function_call (function, params)
result = build (CALL_EXPR, TREE_TYPE (fntype),
function, coerced_params, NULL_TREE);
TREE_SIDE_EFFECTS (result) = 1;
- result = fold (result);
+
+ if (require_constant_value)
+ {
+ result = fold_initializer (result);
+
+ if (TREE_CONSTANT (result)
+ && (name == NULL_TREE
+ || strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0))
+ pedwarn_init ("initializer element is not constant");
+ }
+ else
+ result = fold (result);
if (VOID_TYPE_P (TREE_TYPE (result)))
return result;
@@ -1578,8 +1813,7 @@ build_function_call (function, params)
with the elements of the list in the TREE_VALUE slots of those nodes. */
static tree
-convert_arguments (typelist, values, name, fundecl)
- tree typelist, values, name, fundecl;
+convert_arguments (tree typelist, tree values, tree name, tree fundecl)
{
tree typetail, valtail;
tree result = NULL;
@@ -1696,14 +1930,6 @@ convert_arguments (typelist, values, name, fundecl)
&& TREE_CODE (TREE_OPERAND (val, 0)) == INTEGER_CST
&& int_fits_type_p (TREE_OPERAND (val, 0), type))
;
-#if 0 /* We never get such tree structure here. */
- else if (TREE_CODE (TREE_TYPE (val)) == ENUMERAL_TYPE
- && int_fits_type_p (TYPE_MIN_VALUE (TREE_TYPE (val)), type)
- && int_fits_type_p (TYPE_MAX_VALUE (TREE_TYPE (val)), type))
- /* Change in signedness doesn't matter
- if an enum value is unaffected. */
- ;
-#endif
/* If the value is extended from a narrower
unsigned type, it doesn't matter whether we
pass it as signed or unsigned; the value
@@ -1718,11 +1944,11 @@ convert_arguments (typelist, values, name, fundecl)
}
}
- parmval = convert_for_assignment (type, val,
+ parmval = convert_for_assignment (type, val,
(char *) 0, /* arg passing */
fundecl, name, parmnum + 1);
-
- if (PROMOTE_PROTOTYPES
+
+ if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0)
&& INTEGRAL_TYPE_P (type)
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
parmval = default_conversion (parmval);
@@ -1761,9 +1987,7 @@ convert_arguments (typelist, values, name, fundecl)
in a way that is likely to confuse the user. */
tree
-parser_build_binary_op (code, arg1, arg2)
- enum tree_code code;
- tree arg1, arg2;
+parser_build_binary_op (enum tree_code code, tree arg1, tree arg2)
{
tree result = build_binary_op (code, arg1, arg2, 1);
@@ -1864,756 +2088,22 @@ parser_build_binary_op (code, arg1, arg2)
return result;
}
-
-/* Build a binary-operation expression without default conversions.
- CODE is the kind of expression to build.
- This function differs from `build' in several ways:
- the data type of the result is computed and recorded in it,
- warnings are generated if arg data types are invalid,
- special handling for addition and subtraction of pointers is known,
- and some optimization is done (operations on narrow ints
- are done in the narrower type when that gives the same result).
- Constant folding is also done before the result is returned.
-
- Note that the operands will never have enumeral types, or function
- or array types, because either they will have the default conversions
- performed or they have both just been converted to some other type in which
- the arithmetic is to be done. */
-
-tree
-build_binary_op (code, orig_op0, orig_op1, convert_p)
- enum tree_code code;
- tree orig_op0, orig_op1;
- int convert_p;
-{
- tree type0, type1;
- enum tree_code code0, code1;
- tree op0, op1;
-
- /* Expression code to give to the expression when it is built.
- Normally this is CODE, which is what the caller asked for,
- but in some special cases we change it. */
- enum tree_code resultcode = code;
-
- /* Data type in which the computation is to be performed.
- In the simplest cases this is the common type of the arguments. */
- tree result_type = NULL;
-
- /* Nonzero means operands have already been type-converted
- in whatever way is necessary.
- Zero means they need to be converted to RESULT_TYPE. */
- int converted = 0;
-
- /* Nonzero means create the expression with this type, rather than
- RESULT_TYPE. */
- tree build_type = 0;
-
- /* Nonzero means after finally constructing the expression
- convert it to this type. */
- tree final_type = 0;
-
- /* Nonzero if this is an operation like MIN or MAX which can
- safely be computed in short if both args are promoted shorts.
- Also implies COMMON.
- -1 indicates a bitwise operation; this makes a difference
- in the exact conditions for when it is safe to do the operation
- in a narrower mode. */
- int shorten = 0;
-
- /* Nonzero if this is a comparison operation;
- if both args are promoted shorts, compare the original shorts.
- Also implies COMMON. */
- int short_compare = 0;
-
- /* Nonzero if this is a right-shift operation, which can be computed on the
- original short and then promoted if the operand is a promoted short. */
- int short_shift = 0;
-
- /* Nonzero means set RESULT_TYPE to the common type of the args. */
- int common = 0;
-
- if (convert_p)
- {
- op0 = default_conversion (orig_op0);
- op1 = default_conversion (orig_op1);
- }
- else
- {
- op0 = orig_op0;
- op1 = orig_op1;
- }
-
- type0 = TREE_TYPE (op0);
- type1 = TREE_TYPE (op1);
-
- /* The expression codes of the data types of the arguments tell us
- whether the arguments are integers, floating, pointers, etc. */
- code0 = TREE_CODE (type0);
- code1 = TREE_CODE (type1);
-
- /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
- STRIP_TYPE_NOPS (op0);
- STRIP_TYPE_NOPS (op1);
-
- /* If an error was already reported for one of the arguments,
- avoid reporting another error. */
-
- if (code0 == ERROR_MARK || code1 == ERROR_MARK)
- return error_mark_node;
-
- switch (code)
- {
- case PLUS_EXPR:
- /* Handle the pointer + int case. */
- if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
- return pointer_int_sum (PLUS_EXPR, op0, op1);
- else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
- return pointer_int_sum (PLUS_EXPR, op1, op0);
- else
- common = 1;
- break;
-
- case MINUS_EXPR:
- /* 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, 1))
- return pointer_diff (op0, op1);
- /* Handle pointer minus int. Just like pointer plus int. */
- else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
- return pointer_int_sum (MINUS_EXPR, op0, op1);
- else
- common = 1;
- break;
-
- case MULT_EXPR:
- common = 1;
- break;
-
- case TRUNC_DIV_EXPR:
- case CEIL_DIV_EXPR:
- case FLOOR_DIV_EXPR:
- case ROUND_DIV_EXPR:
- case EXACT_DIV_EXPR:
- /* Floating point division by zero is a legitimate way to obtain
- infinities and NaNs. */
- if (warn_div_by_zero && skip_evaluation == 0 && integer_zerop (op1))
- warning ("division by zero");
-
- if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
- || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
- && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
- || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
- {
- if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
- resultcode = RDIV_EXPR;
- else
- /* Although it would be tempting to shorten always here, that
- loses on some targets, since the modulo instruction is
- undefined if the quotient can't be represented in the
- computation mode. We shorten only if unsigned or if
- dividing by something we know != -1. */
- shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
- || (TREE_CODE (op1) == INTEGER_CST
- && ! integer_all_onesp (op1)));
- common = 1;
- }
- break;
-
- case BIT_AND_EXPR:
- case BIT_ANDTC_EXPR:
- case BIT_IOR_EXPR:
- case BIT_XOR_EXPR:
- if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
- shorten = -1;
- else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
- common = 1;
- break;
-
- case TRUNC_MOD_EXPR:
- case FLOOR_MOD_EXPR:
- if (warn_div_by_zero && skip_evaluation == 0 && integer_zerop (op1))
- warning ("division by zero");
-
- 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
- quotient can't be represented in the computation mode. We shorten
- only if unsigned or if dividing by something we know != -1. */
- shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
- || (TREE_CODE (op1) == INTEGER_CST
- && ! integer_all_onesp (op1)));
- common = 1;
- }
- break;
-
- case TRUTH_ANDIF_EXPR:
- case TRUTH_ORIF_EXPR:
- case TRUTH_AND_EXPR:
- case TRUTH_OR_EXPR:
- case TRUTH_XOR_EXPR:
- if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE
- || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
- && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE
- || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
- {
- /* Result of these operations is always an int,
- but that does not mean the operands should be
- converted to ints! */
- result_type = integer_type_node;
- op0 = c_common_truthvalue_conversion (op0);
- op1 = c_common_truthvalue_conversion (op1);
- converted = 1;
- }
- break;
-
- /* Shift operations: result has same type as first operand;
- always convert second operand to int.
- Also set SHORT_SHIFT if shifting rightward. */
-
- case RSHIFT_EXPR:
- if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
- {
- if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
- {
- if (tree_int_cst_sgn (op1) < 0)
- warning ("right shift count is negative");
- else
- {
- if (! integer_zerop (op1))
- short_shift = 1;
-
- if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
- warning ("right shift count >= width of type");
- }
- }
-
- /* Use the type of the value to be shifted. */
- result_type = type0;
- /* Convert the shift-count to an integer, regardless of size
- of value being shifted. */
- if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
- op1 = convert (integer_type_node, op1);
- /* Avoid converting op1 to result_type later. */
- converted = 1;
- }
- break;
-
- case LSHIFT_EXPR:
- if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
- {
- if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
- {
- if (tree_int_cst_sgn (op1) < 0)
- warning ("left shift count is negative");
-
- else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
- warning ("left shift count >= width of type");
- }
-
- /* Use the type of the value to be shifted. */
- result_type = type0;
- /* Convert the shift-count to an integer, regardless of size
- of value being shifted. */
- if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
- op1 = convert (integer_type_node, op1);
- /* Avoid converting op1 to result_type later. */
- converted = 1;
- }
- break;
-
- case RROTATE_EXPR:
- case LROTATE_EXPR:
- if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
- {
- if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
- {
- if (tree_int_cst_sgn (op1) < 0)
- warning ("shift count is negative");
- else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
- warning ("shift count >= width of type");
- }
-
- /* Use the type of the value to be shifted. */
- result_type = type0;
- /* Convert the shift-count to an integer, regardless of size
- of value being shifted. */
- if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
- op1 = convert (integer_type_node, op1);
- /* Avoid converting op1 to result_type later. */
- converted = 1;
- }
- break;
-
- case EQ_EXPR:
- case NE_EXPR:
- if (warn_float_equal && (code0 == REAL_TYPE || code1 == REAL_TYPE))
- warning ("comparing floating point with == or != is unsafe");
- /* Result of comparison is always int,
- but don't convert the args to int! */
- build_type = integer_type_node;
- if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
- || code0 == COMPLEX_TYPE
- || code0 == VECTOR_TYPE)
- && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
- || code1 == COMPLEX_TYPE
- || code1 == VECTOR_TYPE))
- short_compare = 1;
- else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
- {
- tree tt0 = TREE_TYPE (type0);
- tree tt1 = TREE_TYPE (type1);
- /* 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, 1))
- result_type = common_type (type0, type1);
- else if (VOID_TYPE_P (tt0))
- {
- /* op0 != orig_op0 detects the case of something
- whose value is 0 but which isn't a valid null ptr const. */
- if (pedantic && (!integer_zerop (op0) || op0 != orig_op0)
- && TREE_CODE (tt1) == FUNCTION_TYPE)
- pedwarn ("ISO C forbids comparison of `void *' with function pointer");
- }
- else if (VOID_TYPE_P (tt1))
- {
- if (pedantic && (!integer_zerop (op1) || op1 != orig_op1)
- && TREE_CODE (tt0) == FUNCTION_TYPE)
- pedwarn ("ISO C forbids comparison of `void *' with function pointer");
- }
- else
- pedwarn ("comparison of distinct pointer types lacks a cast");
-
- if (result_type == NULL_TREE)
- result_type = ptr_type_node;
- }
- else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
- && integer_zerop (op1))
- result_type = type0;
- else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
- && integer_zerop (op0))
- result_type = type1;
- else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
- {
- result_type = type0;
- pedwarn ("comparison between pointer and integer");
- }
- else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
- {
- result_type = type1;
- pedwarn ("comparison between pointer and integer");
- }
- break;
-
- case MAX_EXPR:
- case MIN_EXPR:
- if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
- && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
- shorten = 1;
- else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
- {
- if (comp_target_types (type0, type1, 1))
- {
- result_type = common_type (type0, type1);
- if (pedantic
- && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
- pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
- }
- else
- {
- result_type = ptr_type_node;
- pedwarn ("comparison of distinct pointer types lacks a cast");
- }
- }
- break;
-
- case LE_EXPR:
- case GE_EXPR:
- case LT_EXPR:
- case GT_EXPR:
- build_type = integer_type_node;
- if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
- && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
- short_compare = 1;
- else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
- {
- if (comp_target_types (type0, type1, 1))
- {
- result_type = common_type (type0, type1);
- if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
- != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
- pedwarn ("comparison of complete and incomplete pointers");
- else if (pedantic
- && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
- pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
- }
- else
- {
- result_type = ptr_type_node;
- pedwarn ("comparison of distinct pointer types lacks a cast");
- }
- }
- else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
- && integer_zerop (op1))
- {
- result_type = type0;
- if (pedantic || extra_warnings)
- pedwarn ("ordered comparison of pointer with integer zero");
- }
- else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
- && integer_zerop (op0))
- {
- result_type = type1;
- if (pedantic)
- pedwarn ("ordered comparison of pointer with integer zero");
- }
- else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
- {
- result_type = type0;
- pedwarn ("comparison between pointer and integer");
- }
- else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
- {
- result_type = type1;
- pedwarn ("comparison between pointer and integer");
- }
- break;
-
- case UNORDERED_EXPR:
- case ORDERED_EXPR:
- case UNLT_EXPR:
- case UNLE_EXPR:
- case UNGT_EXPR:
- case UNGE_EXPR:
- case UNEQ_EXPR:
- build_type = integer_type_node;
- if (code0 != REAL_TYPE || code1 != REAL_TYPE)
- {
- error ("unordered comparison on non-floating point argument");
- return error_mark_node;
- }
- common = 1;
- break;
-
- default:
- break;
- }
-
- if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
- || code0 == VECTOR_TYPE)
- &&
- (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE
- || code1 == VECTOR_TYPE))
- {
- int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
-
- if (shorten || common || short_compare)
- result_type = common_type (type0, type1);
-
- /* For certain operations (which identify themselves by shorten != 0)
- if both args were extended from the same smaller type,
- do the arithmetic in that type and then extend.
-
- shorten !=0 and !=1 indicates a bitwise operation.
- For them, this optimization is safe only if
- both args are zero-extended or both are sign-extended.
- Otherwise, we might change the result.
- Eg, (short)-1 | (unsigned short)-1 is (int)-1
- but calculated in (unsigned short) it would be (unsigned short)-1. */
-
- if (shorten && none_complex)
- {
- int unsigned0, unsigned1;
- tree arg0 = get_narrower (op0, &unsigned0);
- tree arg1 = get_narrower (op1, &unsigned1);
- /* UNS is 1 if the operation to be done is an unsigned one. */
- int uns = TREE_UNSIGNED (result_type);
- tree type;
-
- final_type = result_type;
-
- /* Handle the case that OP0 (or OP1) does not *contain* a conversion
- but it *requires* conversion to FINAL_TYPE. */
-
- if ((TYPE_PRECISION (TREE_TYPE (op0))
- == TYPE_PRECISION (TREE_TYPE (arg0)))
- && TREE_TYPE (op0) != final_type)
- unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0));
- if ((TYPE_PRECISION (TREE_TYPE (op1))
- == TYPE_PRECISION (TREE_TYPE (arg1)))
- && TREE_TYPE (op1) != final_type)
- unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1));
-
- /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE. */
-
- /* For bitwise operations, signedness of nominal type
- does not matter. Consider only how operands were extended. */
- if (shorten == -1)
- uns = unsigned0;
-
- /* Note that in all three cases below we refrain from optimizing
- an unsigned operation on sign-extended args.
- That would not be valid. */
-
- /* Both args variable: if both extended in same way
- from same width, do it in that width.
- Do it unsigned if args were zero-extended. */
- if ((TYPE_PRECISION (TREE_TYPE (arg0))
- < TYPE_PRECISION (result_type))
- && (TYPE_PRECISION (TREE_TYPE (arg1))
- == TYPE_PRECISION (TREE_TYPE (arg0)))
- && unsigned0 == unsigned1
- && (unsigned0 || !uns))
- result_type
- = c_common_signed_or_unsigned_type
- (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
- else if (TREE_CODE (arg0) == INTEGER_CST
- && (unsigned1 || !uns)
- && (TYPE_PRECISION (TREE_TYPE (arg1))
- < TYPE_PRECISION (result_type))
- && (type
- = c_common_signed_or_unsigned_type (unsigned1,
- TREE_TYPE (arg1)),
- int_fits_type_p (arg0, type)))
- result_type = type;
- else if (TREE_CODE (arg1) == INTEGER_CST
- && (unsigned0 || !uns)
- && (TYPE_PRECISION (TREE_TYPE (arg0))
- < TYPE_PRECISION (result_type))
- && (type
- = c_common_signed_or_unsigned_type (unsigned0,
- TREE_TYPE (arg0)),
- int_fits_type_p (arg1, type)))
- result_type = type;
- }
-
- /* Shifts can be shortened if shifting right. */
-
- if (short_shift)
- {
- int unsigned_arg;
- tree arg0 = get_narrower (op0, &unsigned_arg);
-
- final_type = result_type;
-
- if (arg0 == op0 && final_type == TREE_TYPE (op0))
- unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0));
-
- if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
- /* We can shorten only if the shift count is less than the
- number of bits in the smaller type size. */
- && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
- /* We cannot drop an unsigned shift after sign-extension. */
- && (!TREE_UNSIGNED (final_type) || unsigned_arg))
- {
- /* Do an unsigned shift if the operand was zero-extended. */
- result_type
- = c_common_signed_or_unsigned_type (unsigned_arg,
- TREE_TYPE (arg0));
- /* Convert value-to-be-shifted to that type. */
- if (TREE_TYPE (op0) != result_type)
- op0 = convert (result_type, op0);
- converted = 1;
- }
- }
-
- /* Comparison operations are shortened too but differently.
- They identify themselves by setting short_compare = 1. */
-
- if (short_compare)
- {
- /* Don't write &op0, etc., because that would prevent op0
- from being kept in a register.
- Instead, make copies of the our local variables and
- pass the copies by reference, then copy them back afterward. */
- tree xop0 = op0, xop1 = op1, xresult_type = result_type;
- enum tree_code xresultcode = resultcode;
- tree val
- = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
-
- if (val != 0)
- return val;
-
- op0 = xop0, op1 = xop1;
- converted = 1;
- resultcode = xresultcode;
-
- if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare != 0)
- && skip_evaluation == 0)
- {
- int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
- int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
- int unsignedp0, unsignedp1;
- tree primop0 = get_narrower (op0, &unsignedp0);
- tree primop1 = get_narrower (op1, &unsignedp1);
-
- xop0 = orig_op0;
- xop1 = orig_op1;
- STRIP_TYPE_NOPS (xop0);
- STRIP_TYPE_NOPS (xop1);
-
- /* Give warnings for comparisons between signed and unsigned
- quantities that may fail.
-
- Do the checking based on the original operand trees, so that
- casts will be considered, but default promotions won't be.
-
- Do not warn if the comparison is being done in a signed type,
- since the signed type will only be chosen if it can represent
- all the values of the unsigned type. */
- if (! TREE_UNSIGNED (result_type))
- /* OK */;
- /* Do not warn if both operands are the same signedness. */
- else if (op0_signed == op1_signed)
- /* OK */;
- else
- {
- tree sop, uop;
-
- if (op0_signed)
- sop = xop0, uop = xop1;
- else
- sop = xop1, uop = xop0;
-
- /* Do not warn if the signed quantity is an
- unsuffixed integer literal (or some static
- constant expression involving such literals or a
- conditional expression involving such literals)
- and it is non-negative. */
- if (c_tree_expr_nonnegative_p (sop))
- /* OK */;
- /* Do not warn if the comparison is an equality operation,
- the unsigned quantity is an integral constant, and it
- would fit in the result if the result were signed. */
- else if (TREE_CODE (uop) == INTEGER_CST
- && (resultcode == EQ_EXPR || resultcode == NE_EXPR)
- && int_fits_type_p
- (uop, c_common_signed_type (result_type)))
- /* OK */;
- /* Do not warn if the unsigned quantity is an enumeration
- constant and its maximum value would fit in the result
- if the result were signed. */
- else if (TREE_CODE (uop) == INTEGER_CST
- && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE
- && int_fits_type_p
- (TYPE_MAX_VALUE (TREE_TYPE(uop)),
- c_common_signed_type (result_type)))
- /* OK */;
- else
- warning ("comparison between signed and unsigned");
- }
-
- /* Warn if two unsigned values are being compared in a size
- larger than their original size, and one (and only one) is the
- result of a `~' operator. This comparison will always fail.
-
- Also warn if one operand is a constant, and the constant
- does not have all bits set that are set in the ~ operand
- when it is extended. */
-
- if ((TREE_CODE (primop0) == BIT_NOT_EXPR)
- != (TREE_CODE (primop1) == BIT_NOT_EXPR))
- {
- if (TREE_CODE (primop0) == BIT_NOT_EXPR)
- primop0 = get_narrower (TREE_OPERAND (primop0, 0),
- &unsignedp0);
- else
- primop1 = get_narrower (TREE_OPERAND (primop1, 0),
- &unsignedp1);
-
- if (host_integerp (primop0, 0) || host_integerp (primop1, 0))
- {
- tree primop;
- HOST_WIDE_INT constant, mask;
- int unsignedp, bits;
-
- if (host_integerp (primop0, 0))
- {
- primop = primop1;
- unsignedp = unsignedp1;
- constant = tree_low_cst (primop0, 0);
- }
- else
- {
- primop = primop0;
- unsignedp = unsignedp0;
- constant = tree_low_cst (primop1, 0);
- }
-
- bits = TYPE_PRECISION (TREE_TYPE (primop));
- if (bits < TYPE_PRECISION (result_type)
- && bits < HOST_BITS_PER_WIDE_INT && unsignedp)
- {
- mask = (~ (HOST_WIDE_INT) 0) << bits;
- if ((mask & constant) != mask)
- warning ("comparison of promoted ~unsigned with constant");
- }
- }
- else if (unsignedp0 && unsignedp1
- && (TYPE_PRECISION (TREE_TYPE (primop0))
- < TYPE_PRECISION (result_type))
- && (TYPE_PRECISION (TREE_TYPE (primop1))
- < TYPE_PRECISION (result_type)))
- warning ("comparison of promoted ~unsigned with unsigned");
- }
- }
- }
- }
-
- /* At this point, RESULT_TYPE must be nonzero to avoid an error message.
- If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
- Then the expression will be built.
- It will be given type FINAL_TYPE if that is nonzero;
- otherwise, it will be given type RESULT_TYPE. */
-
- if (!result_type)
- {
- binary_op_error (code);
- return error_mark_node;
- }
-
- if (! converted)
- {
- if (TREE_TYPE (op0) != result_type)
- op0 = convert (result_type, op0);
- if (TREE_TYPE (op1) != result_type)
- op1 = convert (result_type, op1);
- }
-
- if (build_type == NULL_TREE)
- build_type = result_type;
-
- {
- tree result = build (resultcode, build_type, op0, op1);
- tree folded;
-
- folded = fold (result);
- if (folded == result)
- TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
- if (final_type != 0)
- return convert (final_type, folded);
- return folded;
- }
-}
/* Return true if `t' is known to be non-negative. */
int
-c_tree_expr_nonnegative_p (t)
- tree t;
+c_tree_expr_nonnegative_p (tree t)
{
if (TREE_CODE (t) == STMT_EXPR)
{
- t=COMPOUND_BODY (STMT_EXPR_STMT (t));
+ t = COMPOUND_BODY (STMT_EXPR_STMT (t));
/* Find the last statement in the chain, ignoring the final
* scope statement */
- while (TREE_CHAIN (t) != NULL_TREE
+ while (TREE_CHAIN (t) != NULL_TREE
&& TREE_CODE (TREE_CHAIN (t)) != SCOPE_STMT)
- t=TREE_CHAIN (t);
+ t = TREE_CHAIN (t);
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
}
return tree_expr_nonnegative_p (t);
@@ -2623,8 +2113,7 @@ c_tree_expr_nonnegative_p (t)
The resulting tree has type int. */
static tree
-pointer_diff (op0, op1)
- tree op0, op1;
+pointer_diff (tree op0, tree op1)
{
tree result, folded;
tree restype = ptrdiff_type_node;
@@ -2709,10 +2198,7 @@ pointer_diff (op0, op1)
arrays to pointers in C99. */
tree
-build_unary_op (code, xarg, flag)
- enum tree_code code;
- tree xarg;
- int flag;
+build_unary_op (enum tree_code code, tree xarg, int flag)
{
/* No default_conversion here. It causes trouble for ADDR_EXPR. */
tree arg = xarg;
@@ -2777,8 +2263,7 @@ build_unary_op (code, xarg, flag)
break;
case ABS_EXPR:
- if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
- || typecode == COMPLEX_TYPE))
+ if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE))
{
error ("wrong type argument to abs");
return error_mark_node;
@@ -2830,7 +2315,7 @@ build_unary_op (code, xarg, flag)
return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg));
else
return convert (TREE_TYPE (arg), integer_zero_node);
-
+
case PREINCREMENT_EXPR:
case POSTINCREMENT_EXPR:
case PREDECREMENT_EXPR:
@@ -2968,10 +2453,10 @@ build_unary_op (code, xarg, flag)
/* Report a read-only lvalue. */
if (TREE_READONLY (arg))
- readonly_warning (arg,
- ((code == PREINCREMENT_EXPR
- || code == POSTINCREMENT_EXPR)
- ? "increment" : "decrement"));
+ readonly_error (arg,
+ ((code == PREINCREMENT_EXPR
+ || code == POSTINCREMENT_EXPR)
+ ? "increment" : "decrement"));
if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
val = boolean_increment (code, arg);
@@ -3011,28 +2496,6 @@ build_unary_op (code, xarg, flag)
if (val != 0)
return val;
-#if 0 /* Turned off because inconsistent;
- float f; *&(int)f = 3.4 stores in int format
- whereas (int)f = 3.4 stores in float format. */
- /* Address of a cast is just a cast of the address
- of the operand of the cast. */
- switch (TREE_CODE (arg))
- {
- case NOP_EXPR:
- case CONVERT_EXPR:
- case FLOAT_EXPR:
- case FIX_TRUNC_EXPR:
- case FIX_FLOOR_EXPR:
- case FIX_ROUND_EXPR:
- case FIX_CEIL_EXPR:
- if (pedantic)
- pedwarn ("ISO C forbids the address of a cast expression");
- return convert (build_pointer_type (TREE_TYPE (arg)),
- build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0),
- 0));
- }
-#endif
-
/* Anything not already handled and not a true memory reference
or a non-lvalue array is an error. */
else if (typecode != FUNCTION_TYPE && !flag
@@ -3084,7 +2547,7 @@ build_unary_op (code, xarg, flag)
file-scope function counts as a constant. */
if (staticp (arg)
&& ! (TREE_CODE (arg) == FUNCTION_DECL
- && DECL_CONTEXT (arg) != 0))
+ && !DECL_FILE_SCOPE_P (arg)))
TREE_CONSTANT (addr) = 1;
return addr;
}
@@ -3095,45 +2558,16 @@ build_unary_op (code, xarg, flag)
if (argtype == 0)
argtype = TREE_TYPE (arg);
- return fold (build1 (code, argtype, arg));
+ val = build1 (code, argtype, arg);
+ return require_constant_value ? fold_initializer (val) : fold (val);
}
-#if 0
-/* If CONVERSIONS is a conversion expression or a nested sequence of such,
- convert ARG with the same conversions in the same order
- and return the result. */
-
-static tree
-convert_sequence (conversions, arg)
- tree conversions;
- tree arg;
-{
- switch (TREE_CODE (conversions))
- {
- case NOP_EXPR:
- case CONVERT_EXPR:
- case FLOAT_EXPR:
- case FIX_TRUNC_EXPR:
- case FIX_FLOOR_EXPR:
- case FIX_ROUND_EXPR:
- case FIX_CEIL_EXPR:
- return convert (TREE_TYPE (conversions),
- convert_sequence (TREE_OPERAND (conversions, 0),
- arg));
-
- default:
- return arg;
- }
-}
-#endif /* 0 */
-
/* Return nonzero if REF is an lvalue valid for this language.
Lvalues can be assigned, unless their type has TYPE_READONLY.
Lvalues can have their address taken, unless they have DECL_REGISTER. */
int
-lvalue_p (ref)
- tree ref;
+lvalue_p (tree ref)
{
enum tree_code code = TREE_CODE (ref);
@@ -3170,9 +2604,7 @@ lvalue_p (ref)
otherwise, print an error message and return zero. */
int
-lvalue_or_else (ref, msgid)
- tree ref;
- const char *msgid;
+lvalue_or_else (tree ref, const char *msgid)
{
int win = lvalue_p (ref);
@@ -3189,12 +2621,9 @@ lvalue_or_else (ref, msgid)
a pointer in C99.
If ARG is not a kind of expression we can handle, return zero. */
-
+
static tree
-unary_complex_lvalue (code, arg, flag)
- enum tree_code code;
- tree arg;
- int flag;
+unary_complex_lvalue (enum tree_code code, tree arg, int flag)
{
/* Handle (a, b) used as an "lvalue". */
if (TREE_CODE (arg) == COMPOUND_EXPR)
@@ -3231,44 +2660,40 @@ unary_complex_lvalue (code, arg, flag)
COMPOUND_EXPR, or CONVERT_EXPR (for casts). */
static void
-pedantic_lvalue_warning (code)
- enum tree_code code;
+pedantic_lvalue_warning (enum tree_code code)
{
- if (pedantic)
- switch (code)
- {
- case COND_EXPR:
- pedwarn ("ISO C forbids use of conditional expressions as lvalues");
- break;
- case COMPOUND_EXPR:
- pedwarn ("ISO C forbids use of compound expressions as lvalues");
- break;
- default:
- pedwarn ("ISO C forbids use of cast expressions as lvalues");
- break;
- }
+ switch (code)
+ {
+ case COND_EXPR:
+ pedwarn ("use of conditional expressions as lvalues is deprecated");
+ break;
+ case COMPOUND_EXPR:
+ pedwarn ("use of compound expressions as lvalues is deprecated");
+ break;
+ default:
+ pedwarn ("use of cast expressions as lvalues is deprecated");
+ break;
+ }
}
/* Warn about storing in something that is `const'. */
void
-readonly_warning (arg, msgid)
- tree arg;
- const char *msgid;
+readonly_error (tree arg, const char *msgid)
{
if (TREE_CODE (arg) == COMPONENT_REF)
{
if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
- readonly_warning (TREE_OPERAND (arg, 0), msgid);
+ readonly_error (TREE_OPERAND (arg, 0), msgid);
else
- pedwarn ("%s of read-only member `%s'", _(msgid),
- IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
+ error ("%s of read-only member `%s'", _(msgid),
+ IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
}
else if (TREE_CODE (arg) == VAR_DECL)
- pedwarn ("%s of read-only variable `%s'", _(msgid),
- IDENTIFIER_POINTER (DECL_NAME (arg)));
+ error ("%s of read-only variable `%s'", _(msgid),
+ IDENTIFIER_POINTER (DECL_NAME (arg)));
else
- pedwarn ("%s of read-only location", _(msgid));
+ error ("%s of read-only location", _(msgid));
}
/* Mark EXP saying that we need to be able to take the
@@ -3276,8 +2701,7 @@ readonly_warning (arg, msgid)
Returns true if successful. */
bool
-c_mark_addressable (exp)
- tree exp;
+c_mark_addressable (tree exp)
{
tree x = exp;
@@ -3313,7 +2737,7 @@ c_mark_addressable (exp)
if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)
&& DECL_NONLOCAL (x))
{
- if (TREE_PUBLIC (x))
+ if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
{
error ("global register variable `%s' used in nested function",
IDENTIFIER_POINTER (DECL_NAME (x)));
@@ -3324,7 +2748,7 @@ c_mark_addressable (exp)
}
else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x))
{
- if (TREE_PUBLIC (x))
+ if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
{
error ("address of global register variable `%s' requested",
IDENTIFIER_POINTER (DECL_NAME (x)));
@@ -3350,11 +2774,7 @@ c_mark_addressable (exp)
/* drops in */
case FUNCTION_DECL:
TREE_ADDRESSABLE (x) = 1;
-#if 0 /* poplevel deals with this now. */
- if (DECL_CONTEXT (x) == 0)
- TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1;
-#endif
-
+ /* drops out */
default:
return true;
}
@@ -3363,8 +2783,7 @@ c_mark_addressable (exp)
/* Build and return a conditional expression IFEXP ? OP1 : OP2. */
tree
-build_conditional_expr (ifexp, op1, op2)
- tree ifexp, op1, op2;
+build_conditional_expr (tree ifexp, tree op1, tree op2)
{
tree type1;
tree type2;
@@ -3375,23 +2794,6 @@ build_conditional_expr (ifexp, op1, op2)
ifexp = c_common_truthvalue_conversion (default_conversion (ifexp));
-#if 0 /* Produces wrong result if within sizeof. */
- /* Don't promote the operands separately if they promote
- the same way. Return the unpromoted type and let the combined
- value get promoted if necessary. */
-
- if (TREE_TYPE (op1) == TREE_TYPE (op2)
- && TREE_CODE (TREE_TYPE (op1)) != ARRAY_TYPE
- && TREE_CODE (TREE_TYPE (op1)) != ENUMERAL_TYPE
- && TREE_CODE (TREE_TYPE (op1)) != FUNCTION_TYPE)
- {
- if (TREE_CODE (ifexp) == INTEGER_CST)
- return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
-
- return fold (build (COND_EXPR, TREE_TYPE (op1), ifexp, op1, op2));
- }
-#endif
-
/* Promote both alternatives. */
if (TREE_CODE (TREE_TYPE (op1)) != VOID_TYPE)
@@ -3408,7 +2810,7 @@ build_conditional_expr (ifexp, op1, op2)
code1 = TREE_CODE (type1);
type2 = TREE_TYPE (op2);
code2 = TREE_CODE (type2);
-
+
/* Quickly detect the usual case where op1 and op2 have the same type
after promotion. */
if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
@@ -3430,8 +2832,7 @@ build_conditional_expr (ifexp, op1, 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 ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare)
- && !skip_evaluation)
+ if (warn_sign_compare && !skip_evaluation)
{
int unsigned_op1 = TREE_UNSIGNED (TREE_TYPE (orig_op1));
int unsigned_op2 = TREE_UNSIGNED (TREE_TYPE (orig_op2));
@@ -3532,7 +2933,7 @@ build_conditional_expr (ifexp, op1, op2)
op1 = convert_and_check (result_type, op1);
if (result_type != TREE_TYPE (op2))
op2 = convert_and_check (result_type, op2);
-
+
if (TREE_CODE (ifexp) == INTEGER_CST)
return pedantic_non_lvalue (integer_zerop (ifexp) ? op2 : op1);
@@ -3543,16 +2944,13 @@ build_conditional_expr (ifexp, op1, op2)
that performs them all and returns the value of the last of them. */
tree
-build_compound_expr (list)
- tree list;
+build_compound_expr (tree list)
{
return internal_build_compound_expr (list, TRUE);
}
static tree
-internal_build_compound_expr (list, first_p)
- tree list;
- int first_p;
+internal_build_compound_expr (tree list, int first_p)
{
tree rest;
@@ -3564,14 +2962,6 @@ internal_build_compound_expr (list, first_p)
TREE_VALUE (list)
= default_function_array_conversion (TREE_VALUE (list));
-#if 0 /* If something inside inhibited lvalueness, we should not override. */
- /* Consider (x, y+0), which is not an lvalue since y+0 is not. */
-
- /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
- if (TREE_CODE (list) == NON_LVALUE_EXPR)
- list = TREE_OPERAND (list, 0);
-#endif
-
/* Don't let (0, 0) be null pointer constant. */
if (!first_p && integer_zerop (TREE_VALUE (list)))
return non_lvalue (TREE_VALUE (list));
@@ -3583,17 +2973,12 @@ internal_build_compound_expr (list, first_p)
if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
{
/* The left-hand operand of a comma expression is like an expression
- statement: with -W or -Wunused, we should warn if it doesn't have
+ statement: with -Wextra or -Wunused, we should warn if it doesn't have
any side-effects, unless it was explicitly cast to (void). */
- if ((extra_warnings || warn_unused_value)
+ if (warn_unused_value
&& ! (TREE_CODE (TREE_VALUE (list)) == CONVERT_EXPR
&& VOID_TYPE_P (TREE_TYPE (TREE_VALUE (list)))))
warning ("left-hand operand of comma expression has no effect");
-
- /* When pedantic, a compound expression can be neither an lvalue
- nor an integer constant expression. */
- if (! pedantic)
- return rest;
}
/* With -Wunused, we should also warn if the left-hand operand does have
@@ -3609,27 +2994,19 @@ internal_build_compound_expr (list, first_p)
/* Build an expression representing a cast to type TYPE of expression EXPR. */
tree
-build_c_cast (type, expr)
- tree type;
- tree expr;
+build_c_cast (tree type, tree expr)
{
tree value = expr;
-
+
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
/* The ObjC front-end uses TYPE_MAIN_VARIANT to tie together types differing
only in <protocol> qualifications. But when constructing cast expressions,
the protocols do matter and must be kept around. */
- if (!flag_objc || !objc_is_id (type))
+ if (!c_dialect_objc () || !objc_is_object_ptr (type))
type = TYPE_MAIN_VARIANT (type);
-#if 0
- /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
- if (TREE_CODE (value) == NON_LVALUE_EXPR)
- value = TREE_OPERAND (value, 0);
-#endif
-
if (TREE_CODE (type) == ARRAY_TYPE)
{
error ("cast specifies array type");
@@ -3658,27 +3035,19 @@ build_c_cast (type, expr)
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
- TYPE_MAIN_VARIANT (TREE_TYPE (value))))
+ TYPE_MAIN_VARIANT (TREE_TYPE (value)), COMPARE_STRICT))
break;
if (field)
{
- const char *name;
tree t;
if (pedantic)
pedwarn ("ISO C forbids casts to union type");
- if (TYPE_NAME (type) != 0)
- {
- if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
- name = IDENTIFIER_POINTER (TYPE_NAME (type));
- else
- name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
- }
- else
- name = "";
- t = digest_init (type, build (CONSTRUCTOR, type, NULL_TREE,
- build_tree_list (field, value)), 0);
+ t = digest_init (type,
+ build_constructor (type,
+ build_tree_list (field, value)),
+ 0);
TREE_CONSTANT (t) = TREE_CONSTANT (value);
return t;
}
@@ -3780,7 +3149,7 @@ build_c_cast (type, expr)
&& flag_strict_aliasing && warn_strict_aliasing
&& !VOID_TYPE_P (TREE_TYPE (type)))
{
- /* Casting the address of a decl to non void pointer. Warn
+ /* Casting the address of a decl to non void pointer. Warn
if the cast breaks type based aliasing. */
if (!COMPLETE_TYPE_P (TREE_TYPE (type)))
warning ("type-punning to incomplete type might break strict-aliasing rules");
@@ -3789,8 +3158,30 @@ build_c_cast (type, expr)
get_alias_set (TREE_TYPE (type))))
warning ("dereferencing type-punned pointer will break strict-aliasing rules");
}
-
+
+ /* If pedantic, warn for conversions between function and object
+ pointer types, except for converting a null pointer constant
+ to function pointer type. */
+ if (pedantic
+ && TREE_CODE (type) == POINTER_TYPE
+ && TREE_CODE (otype) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (otype)) == FUNCTION_TYPE
+ && TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)
+ pedwarn ("ISO C forbids conversion of function pointer to object pointer type");
+
+ if (pedantic
+ && TREE_CODE (type) == POINTER_TYPE
+ && TREE_CODE (otype) == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE
+ && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE
+ && !(integer_zerop (value) && TREE_TYPE (otype) == void_type_node
+ && TREE_CODE (expr) != NOP_EXPR))
+ pedwarn ("ISO C forbids conversion of object pointer to function pointer type");
+
ovalue = value;
+ /* Replace a nonvolatile const static variable with its value. */
+ if (optimize && TREE_CODE (value) == VAR_DECL)
+ value = decl_constant_value (value);
value = convert (type, value);
/* Ignore any integer overflow caused by the cast. */
@@ -3816,8 +3207,7 @@ build_c_cast (type, expr)
/* Interpret a cast of expression EXPR to type TYPE. */
tree
-c_cast_expr (type, expr)
- tree type, expr;
+c_cast_expr (tree type, tree expr)
{
int saved_wsp = warn_strict_prototypes;
@@ -3838,9 +3228,7 @@ c_cast_expr (type, expr)
Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment. */
tree
-build_modify_expr (lhs, modifycode, rhs)
- tree lhs, rhs;
- enum tree_code modifycode;
+build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
{
tree result;
tree newrhs;
@@ -3874,7 +3262,7 @@ build_modify_expr (lhs, modifycode, rhs)
return error_mark_node;
return build (COMPOUND_EXPR, lhstype,
TREE_OPERAND (lhs, 0), newrhs);
-
+
/* Handle (a ? b : c) used as an "lvalue". */
case COND_EXPR:
pedantic_lvalue_warning (COND_EXPR);
@@ -3938,7 +3326,7 @@ build_modify_expr (lhs, modifycode, rhs)
pedantic_lvalue_warning (CONVERT_EXPR);
return convert (TREE_TYPE (lhs), result);
}
-
+
default:
break;
}
@@ -3955,7 +3343,7 @@ build_modify_expr (lhs, modifycode, rhs)
|| ((TREE_CODE (lhstype) == RECORD_TYPE
|| TREE_CODE (lhstype) == UNION_TYPE)
&& C_TYPE_FIELDS_READONLY (lhstype)))
- readonly_warning (lhs, "assignment");
+ readonly_error (lhs, "assignment");
/* If storing into a structure or union member,
it has probably been given type `int'.
@@ -4015,11 +3403,8 @@ build_modify_expr (lhs, modifycode, rhs)
PARMNUM is the number of the argument, for printing in error messages. */
static tree
-convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
- tree type, rhs;
- const char *errtype;
- tree fundecl, funname;
- int parmnum;
+convert_for_assignment (tree type, tree rhs, const char *errtype,
+ tree fundecl, tree funname, int parmnum)
{
enum tree_code codel = TREE_CODE (type);
tree rhstype;
@@ -4049,7 +3434,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
/* Check for Objective-C protocols. This will automatically
issue a warning if there are protocol violations. No need to
use the return value. */
- if (flag_objc)
+ if (c_dialect_objc ())
objc_comptypes (type, rhstype, 0);
return rhs;
}
@@ -4059,11 +3444,11 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
error ("void value not ignored as it ought to be");
return error_mark_node;
}
- /* A type converts to a reference to it.
+ /* A type converts to a reference to it.
This code doesn't fully support references, it's just for the
special case of va_start and va_copy. */
if (codel == REFERENCE_TYPE
- && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
+ && comptypes (TREE_TYPE (type), TREE_TYPE (rhs), COMPARE_STRICT) == 1)
{
if (!lvalue_p (rhs))
{
@@ -4085,8 +3470,13 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
rhs = build1 (NOP_EXPR, type, rhs);
return rhs;
}
+ /* Some types can interconvert without explicit casts. */
+ else if (codel == VECTOR_TYPE && coder == VECTOR_TYPE
+ && ((*targetm.vector_opaque_p) (type)
+ || (*targetm.vector_opaque_p) (rhstype)))
+ return convert (type, rhs);
/* Arithmetic types all interconvert, and enum is treated like int. */
- else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
+ else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
|| codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE
|| codel == BOOLEAN_TYPE)
&& (coder == INTEGER_TYPE || coder == REAL_TYPE
@@ -4107,7 +3497,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
tree memb_type = TREE_TYPE (memb_types);
if (comptypes (TYPE_MAIN_VARIANT (memb_type),
- TYPE_MAIN_VARIANT (rhstype)))
+ TYPE_MAIN_VARIANT (rhstype), COMPARE_STRICT))
break;
if (TREE_CODE (memb_type) != POINTER_TYPE)
@@ -4179,7 +3569,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
errtype, funname,
parmnum);
}
-
+
if (pedantic && ! DECL_IN_SYSTEM_HEADER (fundecl))
pedwarn ("ISO C prohibits argument conversion to union type");
@@ -4193,12 +3583,21 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
{
tree ttl = TREE_TYPE (type);
tree ttr = TREE_TYPE (rhstype);
+ bool is_opaque_pointer;
+ int target_cmp = 0; /* Cache comp_target_types () result. */
+
+ /* Opaque pointers are treated like void pointers. */
+ is_opaque_pointer = ((*targetm.vector_opaque_p) (type)
+ || (*targetm.vector_opaque_p) (rhstype))
+ && TREE_CODE (ttl) == VECTOR_TYPE
+ && TREE_CODE (ttr) == VECTOR_TYPE;
/* Any non-function converts to a [const][volatile] void *
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)
- || comp_target_types (type, rhstype, 0)
+ || (target_cmp = comp_target_types (type, rhstype, 0))
+ || is_opaque_pointer
|| (c_common_unsigned_type (TYPE_MAIN_VARIANT (ttl))
== c_common_unsigned_type (TYPE_MAIN_VARIANT (ttr))))
{
@@ -4223,7 +3622,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
/* If this is not a case of ignoring a mismatch in signedness,
no warning. */
else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
- || comp_target_types (type, rhstype, 0))
+ || target_cmp)
;
/* If there is a mismatch, do warn. */
else if (pedantic)
@@ -4263,12 +3662,10 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
&& TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE
&& TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST
&& integer_zerop (TREE_OPERAND (rhs, 0))))
- {
warn_for_assignment ("%s makes pointer from integer without a cast",
errtype, funname, parmnum);
- return convert (type, rhs);
- }
- return null_pointer_node;
+
+ return convert (type, rhs);
}
else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
{
@@ -4282,13 +3679,13 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
if (!errtype)
{
if (funname)
- {
- tree selector = objc_message_selector ();
-
- if (selector && parmnum > 2)
- error ("incompatible type for argument %d of `%s'",
+ {
+ tree selector = objc_message_selector ();
+
+ if (selector && parmnum > 2)
+ error ("incompatible type for argument %d of `%s'",
parmnum - 2, IDENTIFIER_POINTER (selector));
- else
+ else
error ("incompatible type for argument %d of `%s'",
parmnum, IDENTIFIER_POINTER (funname));
}
@@ -4302,11 +3699,12 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
return error_mark_node;
}
-/* Convert VALUE for assignment into inlined parameter PARM. */
+/* Convert VALUE for assignment into inlined parameter PARM. ARGNUM
+ is used for error and waring reporting and indicates which argument
+ is being processed. */
tree
-c_convert_parm_for_inlining (parm, value, fn)
- tree parm, value, fn;
+c_convert_parm_for_inlining (tree parm, tree value, tree fn, int argnum)
{
tree ret, type;
@@ -4316,10 +3714,10 @@ c_convert_parm_for_inlining (parm, value, fn)
return value;
type = TREE_TYPE (parm);
- ret = convert_for_assignment (type, value,
+ ret = convert_for_assignment (type, value,
(char *) 0 /* arg passing */, fn,
- DECL_NAME (fn), 0);
- if (PROMOTE_PROTOTYPES
+ DECL_NAME (fn), argnum);
+ if (targetm.calls.promote_prototypes (TREE_TYPE (fn))
&& INTEGRAL_TYPE_P (type)
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
ret = default_conversion (ret);
@@ -4334,17 +3732,14 @@ c_convert_parm_for_inlining (parm, value, fn)
Objective-C selector. */
static void
-warn_for_assignment (msgid, opname, function, argnum)
- const char *msgid;
- const char *opname;
- tree function;
- int argnum;
+warn_for_assignment (const char *msgid, const char *opname, tree function,
+ int argnum)
{
if (opname == 0)
{
tree selector = objc_message_selector ();
char * new_opname;
-
+
if (selector && argnum > 2)
{
function = selector;
@@ -4353,12 +3748,11 @@ warn_for_assignment (msgid, opname, function, argnum)
if (argnum == 0)
{
if (function)
- {
+ {
/* Function name is known; supply it. */
const char *const argstring = _("passing arg of `%s'");
- new_opname = (char *) alloca (IDENTIFIER_LENGTH (function)
- + strlen (argstring) + 1
- + 1);
+ new_opname = alloca (IDENTIFIER_LENGTH (function)
+ + strlen (argstring) + 1 + 1);
sprintf (new_opname, argstring,
IDENTIFIER_POINTER (function));
}
@@ -4366,7 +3760,7 @@ warn_for_assignment (msgid, opname, function, argnum)
{
/* Function name unknown (call through ptr). */
const char *const argnofun = _("passing arg of pointer to function");
- new_opname = (char *) alloca (strlen (argnofun) + 1 + 1);
+ new_opname = alloca (strlen (argnofun) + 1 + 1);
sprintf (new_opname, argnofun);
}
}
@@ -4374,9 +3768,8 @@ warn_for_assignment (msgid, opname, function, argnum)
{
/* Function name is known; supply it. */
const char *const argstring = _("passing arg %d of `%s'");
- new_opname = (char *) alloca (IDENTIFIER_LENGTH (function)
- + strlen (argstring) + 1 + 25
- /*%d*/ + 1);
+ new_opname = alloca (IDENTIFIER_LENGTH (function)
+ + strlen (argstring) + 1 + 25 /*%d*/ + 1);
sprintf (new_opname, argstring, argnum,
IDENTIFIER_POINTER (function));
}
@@ -4384,7 +3777,7 @@ warn_for_assignment (msgid, opname, function, argnum)
{
/* Function name unknown (call through ptr); just give arg number. */
const char *const argnofun = _("passing arg %d of pointer to function");
- new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1);
+ new_opname = alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1);
sprintf (new_opname, argnofun, argnum);
}
opname = new_opname;
@@ -4399,9 +3792,7 @@ warn_for_assignment (msgid, opname, function, argnum)
which is allowed with a warning when -pedantic is specified. */
static tree
-valid_compound_expr_initializer (value, endtype)
- tree value;
- tree endtype;
+valid_compound_expr_initializer (tree value, tree endtype)
{
if (TREE_CODE (value) == COMPOUND_EXPR)
{
@@ -4424,8 +3815,7 @@ valid_compound_expr_initializer (value, endtype)
If the init is invalid, store an ERROR_MARK. */
void
-store_init_value (decl, init)
- tree decl, init;
+store_init_value (tree decl, tree init)
{
tree value, type;
@@ -4441,35 +3831,6 @@ store_init_value (decl, init)
/* Store the expression if valid; else report error. */
-#if 0
- /* Note that this is the only place we can detect the error
- in a case such as struct foo bar = (struct foo) { x, y };
- where there is one initial value which is a constructor expression. */
- if (value == error_mark_node)
- ;
- else if (TREE_STATIC (decl) && ! TREE_CONSTANT (value))
- {
- error ("initializer for static variable is not constant");
- value = error_mark_node;
- }
- else if (TREE_STATIC (decl)
- && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
- {
- error ("initializer for static variable uses complicated arithmetic");
- value = error_mark_node;
- }
- else
- {
- if (pedantic && TREE_CODE (value) == CONSTRUCTOR)
- {
- if (! TREE_CONSTANT (value))
- pedwarn ("aggregate initializer is not constant");
- else if (! TREE_STATIC (value))
- pedwarn ("aggregate initializer uses complicated arithmetic");
- }
- }
-#endif
-
if (warn_traditional && !in_system_header
&& AGGREGATE_TYPE_P (TREE_TYPE (decl)) && ! TREE_STATIC (decl))
warning ("traditional C rejects automatic aggregate initialization");
@@ -4548,12 +3909,10 @@ static int spelling_size; /* Size of the spelling stack. */
{ \
spelling_size += 10; \
if (spelling_base == 0) \
- spelling_base \
- = (struct spelling *) xmalloc (spelling_size * sizeof (struct spelling)); \
+ spelling_base = xmalloc (spelling_size * sizeof (struct spelling)); \
else \
- spelling_base \
- = (struct spelling *) xrealloc (spelling_base, \
- spelling_size * sizeof (struct spelling)); \
+ spelling_base = xrealloc (spelling_base, \
+ spelling_size * sizeof (struct spelling)); \
RESTORE_SPELLING_DEPTH (depth); \
} \
\
@@ -4565,8 +3924,7 @@ static int spelling_size; /* Size of the spelling stack. */
/* Push STRING on the stack. Printed literally. */
static void
-push_string (string)
- const char *string;
+push_string (const char *string)
{
PUSH_SPELLING (SPELLING_STRING, string, u.s);
}
@@ -4574,9 +3932,7 @@ push_string (string)
/* Push a member name on the stack. Printed as '.' STRING. */
static void
-push_member_name (decl)
- tree decl;
-
+push_member_name (tree decl)
{
const char *const string
= DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : "<anonymous>";
@@ -4586,8 +3942,7 @@ push_member_name (decl)
/* Push an array bounds on the stack. Printed as [BOUNDS]. */
static void
-push_array_bounds (bounds)
- int bounds;
+push_array_bounds (int bounds)
{
PUSH_SPELLING (SPELLING_BOUNDS, bounds, u.i);
}
@@ -4595,7 +3950,7 @@ push_array_bounds (bounds)
/* Compute the maximum size in bytes of the printed spelling. */
static int
-spelling_length ()
+spelling_length (void)
{
int size = 0;
struct spelling *p;
@@ -4614,8 +3969,7 @@ spelling_length ()
/* Print the spelling to BUFFER and return it. */
static char *
-print_spelling (buffer)
- char *buffer;
+print_spelling (char *buffer)
{
char *d = buffer;
struct spelling *p;
@@ -4643,13 +3997,12 @@ print_spelling (buffer)
The component name is taken from the spelling stack. */
void
-error_init (msgid)
- const char *msgid;
+error_init (const char *msgid)
{
char *ofwhat;
error ("%s", _(msgid));
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
+ ofwhat = print_spelling (alloca (spelling_length () + 1));
if (*ofwhat)
error ("(near initialization for `%s')", ofwhat);
}
@@ -4659,13 +4012,12 @@ error_init (msgid)
The component name is taken from the spelling stack. */
void
-pedwarn_init (msgid)
- const char *msgid;
+pedwarn_init (const char *msgid)
{
char *ofwhat;
pedwarn ("%s", _(msgid));
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
+ ofwhat = print_spelling (alloca (spelling_length () + 1));
if (*ofwhat)
pedwarn ("(near initialization for `%s')", ofwhat);
}
@@ -4675,13 +4027,12 @@ pedwarn_init (msgid)
The component name is taken from the spelling stack. */
static void
-warning_init (msgid)
- const char *msgid;
+warning_init (const char *msgid)
{
char *ofwhat;
warning ("%s", _(msgid));
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
+ ofwhat = print_spelling (alloca (spelling_length () + 1));
if (*ofwhat)
warning ("(near initialization for `%s')", ofwhat);
}
@@ -4693,9 +4044,7 @@ warning_init (msgid)
elements are seen. */
static tree
-digest_init (type, init, require_constant)
- tree type, init;
- int require_constant;
+digest_init (tree type, tree init, int require_constant)
{
enum tree_code code = TREE_CODE (type);
tree inside_init = init;
@@ -4727,7 +4076,7 @@ digest_init (type, init, require_constant)
&& ((inside_init && TREE_CODE (inside_init) == STRING_CST)))
{
if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
- TYPE_MAIN_VARIANT (type)))
+ TYPE_MAIN_VARIANT (type), COMPARE_STRICT))
return inside_init;
if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
@@ -4764,36 +4113,41 @@ digest_init (type, init, require_constant)
return inside_init;
}
}
+
/* Build a VECTOR_CST from a *constant* vector constructor. If the
vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
below and handle as a constructor. */
- if (code == VECTOR_TYPE
- && comptypes (TREE_TYPE (inside_init), type)
- && TREE_CONSTANT (inside_init))
- {
- if (TREE_CODE (inside_init) == VECTOR_CST
- && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
- TYPE_MAIN_VARIANT (type)))
- return inside_init;
- else
- return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
- }
+ if (code == VECTOR_TYPE
+ && comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT)
+ && TREE_CONSTANT (inside_init))
+ {
+ if (TREE_CODE (inside_init) == VECTOR_CST
+ && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
+ TYPE_MAIN_VARIANT (type),
+ COMPARE_STRICT))
+ return inside_init;
+ else
+ return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
+ }
/* Any type can be initialized
from an expression of the same type, optionally with braces. */
if (inside_init && TREE_TYPE (inside_init) != 0
&& (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
- TYPE_MAIN_VARIANT (type))
+ TYPE_MAIN_VARIANT (type), COMPARE_STRICT)
|| (code == ARRAY_TYPE
- && comptypes (TREE_TYPE (inside_init), type))
+ && comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT))
|| (code == VECTOR_TYPE
- && comptypes (TREE_TYPE (inside_init), type))
+ && comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT))
|| (code == POINTER_TYPE
- && (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
- || TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)
+ && TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
&& comptypes (TREE_TYPE (TREE_TYPE (inside_init)),
- TREE_TYPE (type)))))
+ TREE_TYPE (type), COMPARE_STRICT))
+ || (code == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE
+ && comptypes (TREE_TYPE (inside_init),
+ TREE_TYPE (type), COMPARE_STRICT))))
{
if (code == POINTER_TYPE)
{
@@ -4805,7 +4159,12 @@ digest_init (type, init, require_constant)
return error_mark_node;
}
}
-
+
+ if (code == VECTOR_TYPE)
+ /* Although the types are compatible, we may require a
+ conversion. */
+ inside_init = convert (type, inside_init);
+
if (require_constant && !flag_isoc99
&& TREE_CODE (inside_init) == COMPOUND_LITERAL_EXPR)
{
@@ -4842,7 +4201,7 @@ digest_init (type, init, require_constant)
if (flag_pedantic_errors)
inside_init = error_mark_node;
}
- else if (require_constant
+ else if (require_constant
&& (!TREE_CONSTANT (inside_init)
/* This test catches things like `7 / 0' which
result in an expression for which TREE_CONSTANT
@@ -4946,9 +4305,6 @@ static int constructor_simple;
/* 1 if this constructor is erroneous so far. */
static int constructor_erroneous;
-/* 1 if have called defer_addressed_constants. */
-static int constructor_subconstants_deferred;
-
/* Structure for managing pending initializer elements, organized as an
AVL tree. */
@@ -4974,9 +4330,6 @@ static int constructor_depth;
/* 0 if implicitly pushing constructor levels is allowed. */
int constructor_no_implicit = 0; /* 0 for C; 1 for some other languages. */
-static int require_constant_value;
-static int require_constant_elements;
-
/* DECL node for which an initializer is being read.
0 means we are reading a constructor expression
such as (struct foo) {...}. */
@@ -5066,7 +4419,6 @@ struct initializer_stack
char top_level;
char require_constant_value;
char require_constant_elements;
- char deferred;
};
struct initializer_stack *initializer_stack;
@@ -5074,14 +4426,10 @@ struct initializer_stack *initializer_stack;
/* Prepare to parse and output the initializer for variable DECL. */
void
-start_init (decl, asmspec_tree, top_level)
- tree decl;
- tree asmspec_tree;
- int top_level;
+start_init (tree decl, tree asmspec_tree, int top_level)
{
const char *locus;
- struct initializer_stack *p
- = (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack));
+ struct initializer_stack *p = xmalloc (sizeof (struct initializer_stack));
const char *asmspec = 0;
if (asmspec_tree)
@@ -5097,14 +4445,12 @@ start_init (decl, asmspec_tree, top_level)
p->spelling = spelling;
p->spelling_base = spelling_base;
p->spelling_size = spelling_size;
- p->deferred = constructor_subconstants_deferred;
p->top_level = constructor_top_level;
p->next = initializer_stack;
initializer_stack = p;
constructor_decl = decl;
constructor_asmspec = asmspec;
- constructor_subconstants_deferred = 0;
constructor_designated = 0;
constructor_top_level = top_level;
@@ -5142,16 +4488,10 @@ start_init (decl, asmspec_tree, top_level)
}
void
-finish_init ()
+finish_init (void)
{
struct initializer_stack *p = initializer_stack;
- /* Output subconstants (string constants, usually)
- that were referenced within this initializer and saved up.
- Must do this if and only if we called defer_addressed_constants. */
- if (constructor_subconstants_deferred)
- output_deferred_addressed_constants ();
-
/* Free the whole constructor stack of this initializer. */
while (constructor_stack)
{
@@ -5164,6 +4504,8 @@ finish_init ()
abort ();
/* Pop back to the data of the outer initializer (if any). */
+ free (spelling_base);
+
constructor_decl = p->decl;
constructor_asmspec = p->asmspec;
require_constant_value = p->require_constant_value;
@@ -5174,7 +4516,6 @@ finish_init ()
spelling = p->spelling;
spelling_base = p->spelling_base;
spelling_size = p->spelling_size;
- constructor_subconstants_deferred = p->deferred;
constructor_top_level = p->top_level;
initializer_stack = p->next;
free (p);
@@ -5188,15 +4529,16 @@ finish_init ()
For an initializer for a decl, TYPE is zero. */
void
-really_start_incremental_init (type)
- tree type;
+really_start_incremental_init (tree type)
{
- struct constructor_stack *p
- = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack));
+ struct constructor_stack *p = xmalloc (sizeof (struct constructor_stack));
if (type == 0)
type = TREE_TYPE (constructor_decl);
+ if ((*targetm.vector_opaque_p) (type))
+ error ("opaque vector types cannot be initialized");
+
p->type = constructor_type;
p->fields = constructor_fields;
p->index = constructor_index;
@@ -5292,8 +4634,7 @@ really_start_incremental_init (type)
IMPLICIT is 1 (or 2 if the push is because of designator list). */
void
-push_init_level (implicit)
- int implicit;
+push_init_level (int implicit)
{
struct constructor_stack *p;
tree value = NULL_TREE;
@@ -5307,7 +4648,7 @@ push_init_level (implicit)
&& constructor_fields == 0)
process_init_element (pop_init_level (1));
else if (TREE_CODE (constructor_type) == ARRAY_TYPE
- && constructor_max_index
+ && constructor_max_index
&& tree_int_cst_lt (constructor_max_index, constructor_index))
process_init_element (pop_init_level (1));
else
@@ -5326,7 +4667,7 @@ push_init_level (implicit)
value = find_init_member (constructor_index);
}
- p = (struct constructor_stack *) xmalloc (sizeof (struct constructor_stack));
+ p = xmalloc (sizeof (struct constructor_stack));
p->type = constructor_type;
p->fields = constructor_fields;
p->index = constructor_index;
@@ -5400,7 +4741,7 @@ push_init_level (implicit)
{
constructor_constant = TREE_CONSTANT (value);
constructor_simple = TREE_STATIC (value);
- constructor_elements = TREE_OPERAND (value, 1);
+ constructor_elements = CONSTRUCTOR_ELTS (value);
if (constructor_elements
&& (TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == ARRAY_TYPE))
@@ -5453,7 +4794,7 @@ push_init_level (implicit)
constructor_max_index = build_int_2 (-1, -1);
constructor_index
- = convert (bitsizetype,
+ = convert (bitsizetype,
TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
}
else
@@ -5476,7 +4817,7 @@ push_init_level (implicit)
}
}
-/* At the end of an implicit or explicit brace level,
+/* At the end of an implicit or explicit brace level,
finish up that level of constructor.
If we were outputting the elements as they are read, return 0
from inner levels (process_init_element ignores that),
@@ -5485,8 +4826,7 @@ push_init_level (implicit)
Otherwise, return a CONSTRUCTOR expression. */
tree
-pop_init_level (implicit)
- int implicit;
+pop_init_level (int implicit)
{
struct constructor_stack *p;
tree constructor = 0;
@@ -5502,6 +4842,10 @@ pop_init_level (implicit)
abort ();
}
+ /* Now output all pending elements. */
+ constructor_incremental = 1;
+ output_pending_init_elements (1);
+
p = constructor_stack;
/* Error for initializing a flexible array member, or a zero-length
@@ -5556,10 +4900,6 @@ pop_init_level (implicit)
}
}
- /* Now output all pending elements. */
- constructor_incremental = 1;
- output_pending_init_elements (1);
-
/* Pad out the end of the structure. */
if (p->replacement_value)
/* If this closes a superfluous brace pair,
@@ -5594,8 +4934,8 @@ pop_init_level (implicit)
constructor = error_mark_node;
else
{
- constructor = build (CONSTRUCTOR, constructor_type, NULL_TREE,
- nreverse (constructor_elements));
+ constructor = build_constructor (constructor_type,
+ nreverse (constructor_elements));
if (constructor_constant)
TREE_CONSTANT (constructor) = 1;
if (constructor_constant && constructor_simple)
@@ -5638,8 +4978,7 @@ pop_init_level (implicit)
ARRAY argument is nonzero for array ranges. Returns zero for success. */
static int
-set_designator (array)
- int array;
+set_designator (int array)
{
tree subtype;
enum tree_code subcode;
@@ -5708,13 +5047,11 @@ set_designator (array)
NULL_TREE if there is no range designator at this level. */
static void
-push_range_stack (range_end)
- tree range_end;
+push_range_stack (tree range_end)
{
struct constructor_range_stack *p;
- p = (struct constructor_range_stack *)
- ggc_alloc (sizeof (struct constructor_range_stack));
+ p = ggc_alloc (sizeof (struct constructor_range_stack));
p->prev = constructor_range_stack;
p->next = 0;
p->fields = constructor_fields;
@@ -5732,8 +5069,7 @@ push_range_stack (range_end)
of indices, running from FIRST through LAST. */
void
-set_init_index (first, last)
- tree first, last;
+set_init_index (tree first, tree last)
{
if (set_designator (1))
return;
@@ -5801,8 +5137,7 @@ set_init_index (first, last)
/* Within a struct initializer, specify the next field to be initialized. */
void
-set_init_label (fieldname)
- tree fieldname;
+set_init_label (tree fieldname)
{
tree tail;
@@ -5817,7 +5152,7 @@ set_init_label (fieldname)
error_init ("field name not in record or union initializer");
return;
}
-
+
for (tail = TYPE_FIELDS (constructor_type); tail;
tail = TREE_CHAIN (tail))
{
@@ -5839,12 +5174,11 @@ set_init_label (fieldname)
}
/* Add a new initializer to the tree of pending initializers. PURPOSE
- identifies the initializer, either array index or field in a structure.
+ identifies the initializer, either array index or field in a structure.
VALUE is the value of that index or field. */
static void
-add_pending_init (purpose, value)
- tree purpose, value;
+add_pending_init (tree purpose, tree value)
{
struct init_node *p, **q, *r;
@@ -5891,7 +5225,7 @@ add_pending_init (purpose, value)
}
}
- r = (struct init_node *) ggc_alloc (sizeof (struct init_node));
+ r = ggc_alloc (sizeof (struct init_node));
r->purpose = purpose;
r->value = value;
@@ -6059,7 +5393,7 @@ add_pending_init (purpose, value)
/* Build AVL tree from a sorted chain. */
static void
-set_nonincremental_init ()
+set_nonincremental_init (void)
{
tree chain;
@@ -6078,7 +5412,7 @@ set_nonincremental_init ()
&& DECL_C_BIT_FIELD (constructor_unfilled_fields)
&& DECL_NAME (constructor_unfilled_fields) == 0)
constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields);
-
+
}
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
@@ -6095,8 +5429,7 @@ set_nonincremental_init ()
/* Build AVL tree from a string constant. */
static void
-set_nonincremental_init_from_string (str)
- tree str;
+set_nonincremental_init_from_string (tree str)
{
tree value, purpose, type;
HOST_WIDE_INT val[2];
@@ -6179,8 +5512,7 @@ set_nonincremental_init_from_string (str)
not initialized yet. */
static tree
-find_init_member (field)
- tree field;
+find_init_member (tree field)
{
struct init_node *p;
@@ -6242,17 +5574,20 @@ find_init_member (field)
it is 0 while outputting pending elements, to avoid recursion.) */
static void
-output_init_element (value, type, field, pending)
- tree value, type, field;
- int pending;
+output_init_element (tree value, tree type, tree field, int pending)
{
+ if (type == error_mark_node)
+ {
+ constructor_erroneous = 1;
+ return;
+ }
if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE
|| (TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
&& !(TREE_CODE (value) == STRING_CST
&& TREE_CODE (type) == ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE)
&& !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
- TYPE_MAIN_VARIANT (type))))
+ TYPE_MAIN_VARIANT (type), COMPARE_STRICT)))
value = default_conversion (value);
if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR
@@ -6396,19 +5731,18 @@ output_init_element (value, type, field, pending)
we can output all the pending elements. */
static void
-output_pending_init_elements (all)
- int all;
+output_pending_init_elements (int all)
{
struct init_node *elt = constructor_pending_elts;
tree next;
retry:
- /* Look thru the whole pending tree.
+ /* Look through the whole pending tree.
If we find an element that should be output now,
output it. Otherwise, set NEXT to the element
that comes first among those still pending. */
-
+
next = 0;
while (elt)
{
@@ -6537,8 +5871,7 @@ output_pending_init_elements (all)
it calls output_init_element. */
void
-process_init_element (value)
- tree value;
+process_init_element (tree value)
{
tree orig_value = value;
int string_flag = value != 0 && TREE_CODE (value) == STRING_CST;
@@ -6894,8 +6227,7 @@ process_init_element (value)
/* Build a simple asm-statement, from one string literal. */
tree
-simple_asm_stmt (expr)
- tree expr;
+simple_asm_stmt (tree expr)
{
STRIP_NOPS (expr);
@@ -6921,12 +6253,8 @@ simple_asm_stmt (expr)
STRING, some OUTPUTS, some INPUTS, and some CLOBBERS. */
tree
-build_asm_stmt (cv_qualifier, string, outputs, inputs, clobbers)
- tree cv_qualifier;
- tree string;
- tree outputs;
- tree inputs;
- tree clobbers;
+build_asm_stmt (tree cv_qualifier, tree string, tree outputs, tree inputs,
+ tree clobbers)
{
tree tail;
@@ -6975,7 +6303,7 @@ build_asm_stmt (cv_qualifier, string, outputs, inputs, clobbers)
TREE_VALUE (tail) = output;
}
- /* Perform default conversions on array and function inputs.
+ /* Perform default conversions on array and function inputs.
Don't do this for other types as it would screw up operands
expected to be in memory. */
for (tail = inputs; tail; tail = TREE_CHAIN (tail))
@@ -6992,16 +6320,13 @@ build_asm_stmt (cv_qualifier, string, outputs, inputs, clobbers)
Arguments are same as for expand_asm_operands. */
void
-c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
- tree string, outputs, inputs, clobbers;
- int vol;
- const char *filename;
- int line;
+c_expand_asm_operands (tree string, tree outputs, tree inputs,
+ tree clobbers, int vol, location_t locus)
{
int noutputs = list_length (outputs);
int i;
/* o[I] is the place that output number I should be written. */
- tree *o = (tree *) alloca (noutputs * sizeof (tree));
+ tree *o = alloca (noutputs * sizeof (tree));
tree tail;
/* Record the contents of OUTPUTS before it is modified. */
@@ -7014,7 +6339,7 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
/* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
OUTPUTS some trees for where the values were actually stored. */
- expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line);
+ expand_asm_operands (string, outputs, inputs, clobbers, vol, locus);
/* Copy all the intermediate outputs into the specified outputs. */
for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
@@ -7039,7 +6364,7 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
|| ((TREE_CODE (type) == RECORD_TYPE
|| TREE_CODE (type) == UNION_TYPE)
&& C_TYPE_FIELDS_READONLY (type)))
- readonly_warning (o[i], "modification by `asm'");
+ readonly_error (o[i], "modification by `asm'");
}
}
@@ -7052,8 +6377,7 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
or a null pointer for `return;' with no value. */
tree
-c_expand_return (retval)
- tree retval;
+c_expand_return (tree retval)
{
tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
@@ -7116,7 +6440,7 @@ c_expand_return (retval)
inner = TREE_OPERAND (inner, 0);
continue;
}
-
+
case ADDR_EXPR:
inner = TREE_OPERAND (inner, 0);
@@ -7168,8 +6492,7 @@ static struct c_switch *switch_stack;
SWITCH_STMT. */
tree
-c_start_case (exp)
- tree exp;
+c_start_case (tree exp)
{
enum tree_code code;
tree type, orig_type = error_mark_node;
@@ -7201,7 +6524,7 @@ c_start_case (exp)
}
/* Add this new SWITCH_STMT to the stack. */
- cs = (struct c_switch *) xmalloc (sizeof (*cs));
+ cs = xmalloc (sizeof (*cs));
cs->switch_stmt = build_stmt (SWITCH_STMT, exp, NULL_TREE, orig_type);
cs->cases = splay_tree_new (case_compare, NULL, NULL);
cs->next = switch_stack;
@@ -7213,19 +6536,25 @@ c_start_case (exp)
/* Process a case label. */
tree
-do_case (low_value, high_value)
- tree low_value;
- tree high_value;
+do_case (tree low_value, tree high_value)
{
tree label = NULL_TREE;
if (switch_stack)
{
- label = c_add_case_label (switch_stack->cases,
- SWITCH_COND (switch_stack->switch_stmt),
+ bool switch_was_empty_p = (SWITCH_BODY (switch_stack->switch_stmt) == NULL_TREE);
+
+ label = c_add_case_label (switch_stack->cases,
+ SWITCH_COND (switch_stack->switch_stmt),
low_value, high_value);
if (label == error_mark_node)
label = NULL_TREE;
+ else if (switch_was_empty_p)
+ {
+ /* Attach the first case label to the SWITCH_BODY. */
+ SWITCH_BODY (switch_stack->switch_stmt) = TREE_CHAIN (switch_stack->switch_stmt);
+ TREE_CHAIN (switch_stack->switch_stmt) = NULL_TREE;
+ }
}
else if (low_value)
error ("case label not within a switch statement");
@@ -7238,14 +6567,744 @@ do_case (low_value, high_value)
/* Finish the switch statement. */
void
-c_finish_case ()
+c_finish_case (void)
{
struct c_switch *cs = switch_stack;
- RECHAIN_STMTS (cs->switch_stmt, SWITCH_BODY (cs->switch_stmt));
+ /* Rechain the next statements to the SWITCH_STMT. */
+ last_tree = cs->switch_stmt;
/* Pop the stack. */
switch_stack = switch_stack->next;
splay_tree_delete (cs->cases);
free (cs);
}
+
+/* Build a binary-operation expression without default conversions.
+ CODE is the kind of expression to build.
+ This function differs from `build' in several ways:
+ the data type of the result is computed and recorded in it,
+ warnings are generated if arg data types are invalid,
+ special handling for addition and subtraction of pointers is known,
+ and some optimization is done (operations on narrow ints
+ are done in the narrower type when that gives the same result).
+ Constant folding is also done before the result is returned.
+
+ Note that the operands will never have enumeral types, or function
+ or array types, because either they will have the default conversions
+ performed or they have both just been converted to some other type in which
+ the arithmetic is to be done. */
+
+tree
+build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
+ int convert_p)
+{
+ tree type0, type1;
+ enum tree_code code0, code1;
+ tree op0, op1;
+
+ /* Expression code to give to the expression when it is built.
+ Normally this is CODE, which is what the caller asked for,
+ but in some special cases we change it. */
+ enum tree_code resultcode = code;
+
+ /* Data type in which the computation is to be performed.
+ In the simplest cases this is the common type of the arguments. */
+ tree result_type = NULL;
+
+ /* Nonzero means operands have already been type-converted
+ in whatever way is necessary.
+ Zero means they need to be converted to RESULT_TYPE. */
+ int converted = 0;
+
+ /* Nonzero means create the expression with this type, rather than
+ RESULT_TYPE. */
+ tree build_type = 0;
+
+ /* Nonzero means after finally constructing the expression
+ convert it to this type. */
+ tree final_type = 0;
+
+ /* Nonzero if this is an operation like MIN or MAX which can
+ safely be computed in short if both args are promoted shorts.
+ Also implies COMMON.
+ -1 indicates a bitwise operation; this makes a difference
+ in the exact conditions for when it is safe to do the operation
+ in a narrower mode. */
+ int shorten = 0;
+
+ /* Nonzero if this is a comparison operation;
+ if both args are promoted shorts, compare the original shorts.
+ Also implies COMMON. */
+ int short_compare = 0;
+
+ /* Nonzero if this is a right-shift operation, which can be computed on the
+ original short and then promoted if the operand is a promoted short. */
+ int short_shift = 0;
+
+ /* Nonzero means set RESULT_TYPE to the common type of the args. */
+ int common = 0;
+
+ if (convert_p)
+ {
+ op0 = default_conversion (orig_op0);
+ op1 = default_conversion (orig_op1);
+ }
+ else
+ {
+ op0 = orig_op0;
+ op1 = orig_op1;
+ }
+
+ type0 = TREE_TYPE (op0);
+ type1 = TREE_TYPE (op1);
+
+ /* The expression codes of the data types of the arguments tell us
+ whether the arguments are integers, floating, pointers, etc. */
+ code0 = TREE_CODE (type0);
+ code1 = TREE_CODE (type1);
+
+ /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
+ STRIP_TYPE_NOPS (op0);
+ STRIP_TYPE_NOPS (op1);
+
+ /* If an error was already reported for one of the arguments,
+ avoid reporting another error. */
+
+ if (code0 == ERROR_MARK || code1 == ERROR_MARK)
+ return error_mark_node;
+
+ switch (code)
+ {
+ case PLUS_EXPR:
+ /* Handle the pointer + int case. */
+ if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
+ return pointer_int_sum (PLUS_EXPR, op0, op1);
+ else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
+ return pointer_int_sum (PLUS_EXPR, op1, op0);
+ else
+ common = 1;
+ break;
+
+ case MINUS_EXPR:
+ /* 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, 1))
+ return pointer_diff (op0, op1);
+ /* Handle pointer minus int. Just like pointer plus int. */
+ else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
+ return pointer_int_sum (MINUS_EXPR, op0, op1);
+ else
+ common = 1;
+ break;
+
+ case MULT_EXPR:
+ common = 1;
+ break;
+
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ /* Floating point division by zero is a legitimate way to obtain
+ infinities and NaNs. */
+ if (warn_div_by_zero && skip_evaluation == 0 && integer_zerop (op1))
+ warning ("division by zero");
+
+ if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
+ || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
+ || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
+ {
+ if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
+ resultcode = RDIV_EXPR;
+ else
+ /* Although it would be tempting to shorten always here, that
+ loses on some targets, since the modulo instruction is
+ undefined if the quotient can't be represented in the
+ computation mode. We shorten only if unsigned or if
+ dividing by something we know != -1. */
+ shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
+ || (TREE_CODE (op1) == INTEGER_CST
+ && ! integer_all_onesp (op1)));
+ common = 1;
+ }
+ break;
+
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ shorten = -1;
+ else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
+ common = 1;
+ break;
+
+ case TRUNC_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ if (warn_div_by_zero && skip_evaluation == 0 && integer_zerop (op1))
+ warning ("division by zero");
+
+ 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
+ quotient can't be represented in the computation mode. We shorten
+ only if unsigned or if dividing by something we know != -1. */
+ shorten = (TREE_UNSIGNED (TREE_TYPE (orig_op0))
+ || (TREE_CODE (op1) == INTEGER_CST
+ && ! integer_all_onesp (op1)));
+ common = 1;
+ }
+ break;
+
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ case TRUTH_XOR_EXPR:
+ if ((code0 == INTEGER_TYPE || code0 == POINTER_TYPE
+ || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == POINTER_TYPE
+ || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
+ {
+ /* Result of these operations is always an int,
+ but that does not mean the operands should be
+ converted to ints! */
+ result_type = integer_type_node;
+ op0 = c_common_truthvalue_conversion (op0);
+ op1 = c_common_truthvalue_conversion (op1);
+ converted = 1;
+ }
+ break;
+
+ /* Shift operations: result has same type as first operand;
+ always convert second operand to int.
+ Also set SHORT_SHIFT if shifting rightward. */
+
+ case RSHIFT_EXPR:
+ if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ {
+ if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
+ {
+ if (tree_int_cst_sgn (op1) < 0)
+ warning ("right shift count is negative");
+ else
+ {
+ if (! integer_zerop (op1))
+ short_shift = 1;
+
+ if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
+ warning ("right shift count >= width of type");
+ }
+ }
+
+ /* Use the type of the value to be shifted. */
+ result_type = type0;
+ /* Convert the shift-count to an integer, regardless of size
+ of value being shifted. */
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
+ op1 = convert (integer_type_node, op1);
+ /* Avoid converting op1 to result_type later. */
+ converted = 1;
+ }
+ break;
+
+ case LSHIFT_EXPR:
+ if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ {
+ if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
+ {
+ if (tree_int_cst_sgn (op1) < 0)
+ warning ("left shift count is negative");
+
+ else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
+ warning ("left shift count >= width of type");
+ }
+
+ /* Use the type of the value to be shifted. */
+ result_type = type0;
+ /* Convert the shift-count to an integer, regardless of size
+ of value being shifted. */
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
+ op1 = convert (integer_type_node, op1);
+ /* Avoid converting op1 to result_type later. */
+ converted = 1;
+ }
+ break;
+
+ case RROTATE_EXPR:
+ case LROTATE_EXPR:
+ if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ {
+ if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
+ {
+ if (tree_int_cst_sgn (op1) < 0)
+ warning ("shift count is negative");
+ else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
+ warning ("shift count >= width of type");
+ }
+
+ /* Use the type of the value to be shifted. */
+ result_type = type0;
+ /* Convert the shift-count to an integer, regardless of size
+ of value being shifted. */
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
+ op1 = convert (integer_type_node, op1);
+ /* Avoid converting op1 to result_type later. */
+ converted = 1;
+ }
+ break;
+
+ case EQ_EXPR:
+ case NE_EXPR:
+ if (warn_float_equal && (code0 == REAL_TYPE || code1 == REAL_TYPE))
+ warning ("comparing floating point with == or != is unsafe");
+ /* Result of comparison is always int,
+ but don't convert the args to int! */
+ build_type = integer_type_node;
+ if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
+ || code0 == COMPLEX_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == REAL_TYPE
+ || code1 == COMPLEX_TYPE))
+ short_compare = 1;
+ else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
+ {
+ tree tt0 = TREE_TYPE (type0);
+ tree tt1 = TREE_TYPE (type1);
+ /* 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, 1))
+ result_type = common_type (type0, type1);
+ else if (VOID_TYPE_P (tt0))
+ {
+ /* op0 != orig_op0 detects the case of something
+ whose value is 0 but which isn't a valid null ptr const. */
+ if (pedantic && (!integer_zerop (op0) || op0 != orig_op0)
+ && TREE_CODE (tt1) == FUNCTION_TYPE)
+ pedwarn ("ISO C forbids comparison of `void *' with function pointer");
+ }
+ else if (VOID_TYPE_P (tt1))
+ {
+ if (pedantic && (!integer_zerop (op1) || op1 != orig_op1)
+ && TREE_CODE (tt0) == FUNCTION_TYPE)
+ pedwarn ("ISO C forbids comparison of `void *' with function pointer");
+ }
+ else
+ pedwarn ("comparison of distinct pointer types lacks a cast");
+
+ if (result_type == NULL_TREE)
+ result_type = ptr_type_node;
+ }
+ else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
+ && integer_zerop (op1))
+ result_type = type0;
+ else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
+ && integer_zerop (op0))
+ result_type = type1;
+ else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
+ {
+ result_type = type0;
+ pedwarn ("comparison between pointer and integer");
+ }
+ else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
+ {
+ result_type = type1;
+ pedwarn ("comparison between pointer and integer");
+ }
+ break;
+
+ case MAX_EXPR:
+ case MIN_EXPR:
+ if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
+ shorten = 1;
+ else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
+ {
+ if (comp_target_types (type0, type1, 1))
+ {
+ result_type = common_type (type0, type1);
+ if (pedantic
+ && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
+ pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
+ }
+ else
+ {
+ result_type = ptr_type_node;
+ pedwarn ("comparison of distinct pointer types lacks a cast");
+ }
+ }
+ break;
+
+ case LE_EXPR:
+ case GE_EXPR:
+ case LT_EXPR:
+ case GT_EXPR:
+ build_type = integer_type_node;
+ if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
+ && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
+ short_compare = 1;
+ else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
+ {
+ if (comp_target_types (type0, type1, 1))
+ {
+ result_type = common_type (type0, type1);
+ if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
+ != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
+ pedwarn ("comparison of complete and incomplete pointers");
+ else if (pedantic
+ && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
+ pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
+ }
+ else
+ {
+ result_type = ptr_type_node;
+ pedwarn ("comparison of distinct pointer types lacks a cast");
+ }
+ }
+ else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
+ && integer_zerop (op1))
+ {
+ result_type = type0;
+ if (pedantic || extra_warnings)
+ pedwarn ("ordered comparison of pointer with integer zero");
+ }
+ else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
+ && integer_zerop (op0))
+ {
+ result_type = type1;
+ if (pedantic)
+ pedwarn ("ordered comparison of pointer with integer zero");
+ }
+ else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
+ {
+ result_type = type0;
+ pedwarn ("comparison between pointer and integer");
+ }
+ else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
+ {
+ result_type = type1;
+ pedwarn ("comparison between pointer and integer");
+ }
+ break;
+
+ case UNORDERED_EXPR:
+ case ORDERED_EXPR:
+ case UNLT_EXPR:
+ case UNLE_EXPR:
+ case UNGT_EXPR:
+ case UNGE_EXPR:
+ case UNEQ_EXPR:
+ build_type = integer_type_node;
+ if (code0 != REAL_TYPE || code1 != REAL_TYPE)
+ {
+ error ("unordered comparison on non-floating point argument");
+ return error_mark_node;
+ }
+ common = 1;
+ break;
+
+ default:
+ break;
+ }
+
+ if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
+ || code0 == VECTOR_TYPE)
+ &&
+ (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE
+ || code1 == VECTOR_TYPE))
+ {
+ int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
+
+ if (shorten || common || short_compare)
+ result_type = common_type (type0, type1);
+
+ /* For certain operations (which identify themselves by shorten != 0)
+ if both args were extended from the same smaller type,
+ do the arithmetic in that type and then extend.
+
+ shorten !=0 and !=1 indicates a bitwise operation.
+ For them, this optimization is safe only if
+ both args are zero-extended or both are sign-extended.
+ Otherwise, we might change the result.
+ Eg, (short)-1 | (unsigned short)-1 is (int)-1
+ but calculated in (unsigned short) it would be (unsigned short)-1. */
+
+ if (shorten && none_complex)
+ {
+ int unsigned0, unsigned1;
+ tree arg0 = get_narrower (op0, &unsigned0);
+ tree arg1 = get_narrower (op1, &unsigned1);
+ /* UNS is 1 if the operation to be done is an unsigned one. */
+ int uns = TREE_UNSIGNED (result_type);
+ tree type;
+
+ final_type = result_type;
+
+ /* Handle the case that OP0 (or OP1) does not *contain* a conversion
+ but it *requires* conversion to FINAL_TYPE. */
+
+ if ((TYPE_PRECISION (TREE_TYPE (op0))
+ == TYPE_PRECISION (TREE_TYPE (arg0)))
+ && TREE_TYPE (op0) != final_type)
+ unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0));
+ if ((TYPE_PRECISION (TREE_TYPE (op1))
+ == TYPE_PRECISION (TREE_TYPE (arg1)))
+ && TREE_TYPE (op1) != final_type)
+ unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1));
+
+ /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE. */
+
+ /* For bitwise operations, signedness of nominal type
+ does not matter. Consider only how operands were extended. */
+ if (shorten == -1)
+ uns = unsigned0;
+
+ /* Note that in all three cases below we refrain from optimizing
+ an unsigned operation on sign-extended args.
+ That would not be valid. */
+
+ /* Both args variable: if both extended in same way
+ from same width, do it in that width.
+ Do it unsigned if args were zero-extended. */
+ if ((TYPE_PRECISION (TREE_TYPE (arg0))
+ < TYPE_PRECISION (result_type))
+ && (TYPE_PRECISION (TREE_TYPE (arg1))
+ == TYPE_PRECISION (TREE_TYPE (arg0)))
+ && unsigned0 == unsigned1
+ && (unsigned0 || !uns))
+ result_type
+ = c_common_signed_or_unsigned_type
+ (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
+ else if (TREE_CODE (arg0) == INTEGER_CST
+ && (unsigned1 || !uns)
+ && (TYPE_PRECISION (TREE_TYPE (arg1))
+ < TYPE_PRECISION (result_type))
+ && (type
+ = c_common_signed_or_unsigned_type (unsigned1,
+ TREE_TYPE (arg1)),
+ int_fits_type_p (arg0, type)))
+ result_type = type;
+ else if (TREE_CODE (arg1) == INTEGER_CST
+ && (unsigned0 || !uns)
+ && (TYPE_PRECISION (TREE_TYPE (arg0))
+ < TYPE_PRECISION (result_type))
+ && (type
+ = c_common_signed_or_unsigned_type (unsigned0,
+ TREE_TYPE (arg0)),
+ int_fits_type_p (arg1, type)))
+ result_type = type;
+ }
+
+ /* Shifts can be shortened if shifting right. */
+
+ if (short_shift)
+ {
+ int unsigned_arg;
+ tree arg0 = get_narrower (op0, &unsigned_arg);
+
+ final_type = result_type;
+
+ if (arg0 == op0 && final_type == TREE_TYPE (op0))
+ unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0));
+
+ if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type)
+ /* We can shorten only if the shift count is less than the
+ number of bits in the smaller type size. */
+ && compare_tree_int (op1, TYPE_PRECISION (TREE_TYPE (arg0))) < 0
+ /* We cannot drop an unsigned shift after sign-extension. */
+ && (!TREE_UNSIGNED (final_type) || unsigned_arg))
+ {
+ /* Do an unsigned shift if the operand was zero-extended. */
+ result_type
+ = c_common_signed_or_unsigned_type (unsigned_arg,
+ TREE_TYPE (arg0));
+ /* Convert value-to-be-shifted to that type. */
+ if (TREE_TYPE (op0) != result_type)
+ op0 = convert (result_type, op0);
+ converted = 1;
+ }
+ }
+
+ /* Comparison operations are shortened too but differently.
+ They identify themselves by setting short_compare = 1. */
+
+ if (short_compare)
+ {
+ /* Don't write &op0, etc., because that would prevent op0
+ from being kept in a register.
+ Instead, make copies of the our local variables and
+ pass the copies by reference, then copy them back afterward. */
+ tree xop0 = op0, xop1 = op1, xresult_type = result_type;
+ enum tree_code xresultcode = resultcode;
+ tree val
+ = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
+
+ if (val != 0)
+ return val;
+
+ op0 = xop0, op1 = xop1;
+ converted = 1;
+ resultcode = xresultcode;
+
+ if (warn_sign_compare && skip_evaluation == 0)
+ {
+ int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
+ int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
+ int unsignedp0, unsignedp1;
+ tree primop0 = get_narrower (op0, &unsignedp0);
+ tree primop1 = get_narrower (op1, &unsignedp1);
+
+ xop0 = orig_op0;
+ xop1 = orig_op1;
+ STRIP_TYPE_NOPS (xop0);
+ STRIP_TYPE_NOPS (xop1);
+
+ /* Give warnings for comparisons between signed and unsigned
+ quantities that may fail.
+
+ Do the checking based on the original operand trees, so that
+ casts will be considered, but default promotions won't be.
+
+ Do not warn if the comparison is being done in a signed type,
+ since the signed type will only be chosen if it can represent
+ all the values of the unsigned type. */
+ if (! TREE_UNSIGNED (result_type))
+ /* OK */;
+ /* Do not warn if both operands are the same signedness. */
+ else if (op0_signed == op1_signed)
+ /* OK */;
+ else
+ {
+ tree sop, uop;
+
+ if (op0_signed)
+ sop = xop0, uop = xop1;
+ else
+ sop = xop1, uop = xop0;
+
+ /* Do not warn if the signed quantity is an
+ unsuffixed integer literal (or some static
+ constant expression involving such literals or a
+ conditional expression involving such literals)
+ and it is non-negative. */
+ if (c_tree_expr_nonnegative_p (sop))
+ /* OK */;
+ /* Do not warn if the comparison is an equality operation,
+ the unsigned quantity is an integral constant, and it
+ would fit in the result if the result were signed. */
+ else if (TREE_CODE (uop) == INTEGER_CST
+ && (resultcode == EQ_EXPR || resultcode == NE_EXPR)
+ && int_fits_type_p
+ (uop, c_common_signed_type (result_type)))
+ /* OK */;
+ /* Do not warn if the unsigned quantity is an enumeration
+ constant and its maximum value would fit in the result
+ if the result were signed. */
+ else if (TREE_CODE (uop) == INTEGER_CST
+ && TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE
+ && int_fits_type_p
+ (TYPE_MAX_VALUE (TREE_TYPE(uop)),
+ c_common_signed_type (result_type)))
+ /* OK */;
+ else
+ warning ("comparison between signed and unsigned");
+ }
+
+ /* Warn if two unsigned values are being compared in a size
+ larger than their original size, and one (and only one) is the
+ result of a `~' operator. This comparison will always fail.
+
+ Also warn if one operand is a constant, and the constant
+ does not have all bits set that are set in the ~ operand
+ when it is extended. */
+
+ if ((TREE_CODE (primop0) == BIT_NOT_EXPR)
+ != (TREE_CODE (primop1) == BIT_NOT_EXPR))
+ {
+ if (TREE_CODE (primop0) == BIT_NOT_EXPR)
+ primop0 = get_narrower (TREE_OPERAND (primop0, 0),
+ &unsignedp0);
+ else
+ primop1 = get_narrower (TREE_OPERAND (primop1, 0),
+ &unsignedp1);
+
+ if (host_integerp (primop0, 0) || host_integerp (primop1, 0))
+ {
+ tree primop;
+ HOST_WIDE_INT constant, mask;
+ int unsignedp, bits;
+
+ if (host_integerp (primop0, 0))
+ {
+ primop = primop1;
+ unsignedp = unsignedp1;
+ constant = tree_low_cst (primop0, 0);
+ }
+ else
+ {
+ primop = primop0;
+ unsignedp = unsignedp0;
+ constant = tree_low_cst (primop1, 0);
+ }
+
+ bits = TYPE_PRECISION (TREE_TYPE (primop));
+ if (bits < TYPE_PRECISION (result_type)
+ && bits < HOST_BITS_PER_WIDE_INT && unsignedp)
+ {
+ mask = (~ (HOST_WIDE_INT) 0) << bits;
+ if ((mask & constant) != mask)
+ warning ("comparison of promoted ~unsigned with constant");
+ }
+ }
+ else if (unsignedp0 && unsignedp1
+ && (TYPE_PRECISION (TREE_TYPE (primop0))
+ < TYPE_PRECISION (result_type))
+ && (TYPE_PRECISION (TREE_TYPE (primop1))
+ < TYPE_PRECISION (result_type)))
+ warning ("comparison of promoted ~unsigned with unsigned");
+ }
+ }
+ }
+ }
+
+ /* At this point, RESULT_TYPE must be nonzero to avoid an error message.
+ If CONVERTED is zero, both args will be converted to type RESULT_TYPE.
+ Then the expression will be built.
+ It will be given type FINAL_TYPE if that is nonzero;
+ otherwise, it will be given type RESULT_TYPE. */
+
+ if (!result_type)
+ {
+ binary_op_error (code);
+ return error_mark_node;
+ }
+
+ if (! converted)
+ {
+ if (TREE_TYPE (op0) != result_type)
+ op0 = convert (result_type, op0);
+ if (TREE_TYPE (op1) != result_type)
+ op1 = convert (result_type, op1);
+ }
+
+ if (build_type == NULL_TREE)
+ build_type = result_type;
+
+ {
+ tree result = build (resultcode, build_type, op0, op1);
+ tree folded;
+
+ /* Treat expressions in initializers specially as they can't trap. */
+ folded = require_constant_value ? fold_initializer (result)
+ : fold (result);
+ if (folded == result)
+ TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1);
+ if (final_type != 0)
+ return convert (final_type, folded);
+ return folded;
+ }
+}
diff --git a/contrib/gcc/c.opt b/contrib/gcc/c.opt
new file mode 100644
index 000000000000..2a2ff85b7380
--- /dev/null
+++ b/contrib/gcc/c.opt
@@ -0,0 +1,825 @@
+; Options for the C, ObjC, C++ and ObjC++ front ends.
+; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the Free
+; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+; 02111-1307, USA.
+
+
+; This file is processed by the script opts.sh. It is a database of
+; command line options, with each record separated by a blank line,
+; and each field appearing on its own line. The first field is the
+; command-line switch with the leading "-" removed. All options
+; beginning with "f" or "W" are implicitly assumed to take a "no-"
+; form; this form should not be listed. If you do not want this
+; negative form and you want it to be automatically rejected, add
+; RejectNegative to the second field.
+
+; The second field is a space-separated list of which parts of the
+; compiler recognize the switch, as declared by "Language" entries.
+; If the switch takes an argument, then you should also specify
+; "Joined" and/or "Separate" to indicate where the argument can
+; appear. If a Joined argument can legitimately be omitted, specify
+; "JoinedOrMissing" instead of "Joined". If the argument to a switch
+; is a non-negative integer, you can specify "UInteger" and the switch
+; decoder will convert the argument for you, or complain to the user
+; if the argument is invalid.
+
+; The third field is the help text to output with --help. This is
+; automatically line-wrapped on output. Normally the switch is output
+; automatically, with the help text on the right hand side of the
+; output. However, if the help text contains a tab character, the
+; text to the left of the tab is output instead of the switch, and the
+; text to its right forms the help. This is useful for elaborating on
+; what type of argument a switch takes, for example. If the second
+; field contains "Undocumented" then nothing is output with --help.
+; Only do this with good reason like the switch being internal between
+; the driver and the front end - it is not an excuse to leave a switch
+; undocumented.
+
+; Comments can appear on their own line anwhere in the file, preceded
+; by a semicolon. Whitespace is permitted before the semicolon.
+
+; For each switch XXX below, an enumeration constant is created by the
+; script opts.sh spelt OPT_XXX, but with all non-alphanumeric
+; characters replaced with an underscore.
+
+; Please try to keep this file in ASCII collating order.
+
+Language
+C
+
+Language
+ObjC
+
+Language
+C++
+
+Language
+ObjC++
+
+-output-pch=
+C ObjC C++ ObjC++ Joined Separate
+
+A
+C ObjC C++ ObjC++ Joined Separate
+-A<question>=<answer> Assert the <answer> to <question>. Putting '-' before <question> disables the <answer> to <question>
+
+C
+C ObjC C++ ObjC++
+Do not discard comments
+
+CC
+C ObjC C++ ObjC++
+Do not discard comments in macro expansions
+
+D
+C ObjC C++ ObjC++ Joined Separate
+-D<macro>[=<val>] Define a <macro> with <val> as its value. If just <macro> is given, <val> is taken to be 1
+
+E
+C ObjC C++ ObjC++ Undocumented
+
+H
+C ObjC C++ ObjC++
+Print the name of header files as they are used
+
+I
+C ObjC C++ ObjC++ Joined Separate
+-I <dir> Add <dir> to the end of the main include path. -I- gives more include path control; see info documentation
+
+M
+C ObjC C++ ObjC++
+Generate make dependencies
+
+MD
+C ObjC C++ ObjC++ Separate
+Generate make dependencies and compile
+
+MF
+C ObjC C++ ObjC++ Joined Separate
+-MF <file> Write dependency output to the given file
+
+MG
+C ObjC C++ ObjC++
+Treat missing header files as generated files
+
+MM
+C ObjC C++ ObjC++
+Like -M but ignore system header files
+
+MMD
+C ObjC C++ ObjC++ Separate
+Like -MD but ignore system header files
+
+MP
+C ObjC C++ ObjC++
+Generate phony targets for all headers
+
+MQ
+C ObjC C++ ObjC++ Joined Separate
+-MQ <target> Add a MAKE-quoted target
+
+MT
+C ObjC C++ ObjC++ Joined Separate
+-MT <target> Add an unquoted target
+
+P
+C ObjC C++ ObjC++
+Do not generate #line directives
+
+U
+C ObjC C++ ObjC++ Joined Separate
+-U<macro> Undefine <macro>
+
+Wabi
+C++ ObjC++
+
+Wall
+C ObjC C++ ObjC++
+Enable most warning messages
+
+Wbad-function-cast
+C ObjC
+Warn about casting functions to incompatible types
+
+Wcast-qual
+C ObjC C++ ObjC++
+Warn about casts which discard qualifiers
+
+Wchar-subscripts
+C ObjC C++ ObjC++
+Warn about subscripts whose type is \"char\"
+
+Wcomment
+C ObjC C++ ObjC++
+Warn about possibly nested block comments, and C++ comments spanning more than one physical line
+
+Wcomments
+C ObjC C++ ObjC++
+Synonym for -Wcomment
+
+Wconversion
+C ObjC C++ ObjC++
+Warn about possibly confusing type conversions
+
+Wctor-dtor-privacy
+C++ ObjC++
+Warn when all constructors and destructors are private
+
+Wdeclaration-after-statement
+C ObjC
+Warn when a declaration is found after a statement
+
+Wdeprecated
+C++ ObjC++
+Warn about deprecated compiler features
+
+Wdiv-by-zero
+C ObjC
+Warn about compile-time integer division by zero
+
+Weffc++
+C++ ObjC++
+Warn about violations of Effective C++ style rules
+
+Wendif-labels
+C ObjC C++ ObjC++
+Warn about stray tokens after #elif and #endif
+
+Werror
+C ObjC C++ ObjC++
+; Documented in common.opt
+
+Werror-implicit-function-declaration
+C ObjC RejectNegative
+Make implicit function declarations an error
+
+Wfloat-equal
+C ObjC C++ ObjC++
+Warn if testing floating point numbers for equality
+
+Wformat
+C ObjC C++ ObjC++
+Warn about printf/scanf/strftime/strfmon format string anomalies
+
+Wformat-extra-args
+C ObjC C++ ObjC++
+Warn if passing too many arguments to a function for its format string
+
+Wformat-nonliteral
+C ObjC C++ ObjC++
+Warn about format strings that are not literals
+
+Wformat-security
+C ObjC C++ ObjC++
+Warn about possible security problems with format functions
+
+Wformat-y2k
+C ObjC C++ ObjC++
+Warn about strftime formats yielding 2-digit years
+
+Wformat-zero-length
+C ObjC
+
+Wformat=
+C ObjC C++ ObjC++ Joined
+
+Winit-self
+C ObjC C++ ObjC++
+Warn about variables which are initialized to themselves.
+
+Wimplicit
+C ObjC C++ ObjC++
+
+Wimplicit-function-declaration
+C ObjC
+Warn about implicit function declarations
+
+Wimplicit-int
+C ObjC
+Warn when a declaration does not specify a type
+
+Wimport
+C ObjC C++ ObjC++
+Deprecated. This switch has no effect.
+
+Winvalid-offsetof
+C++ ObjC++
+Warn about invalid uses of the \"offsetof\" macro
+
+Winvalid-pch
+C ObjC C++ ObjC++
+Warn about PCH files that are found but not used
+
+Wlong-long
+C ObjC C++ ObjC++
+Do not warn about using \"long long\" when -pedantic
+
+Wmain
+C ObjC
+Warn about suspicious declarations of \"main\"
+
+Wmissing-braces
+C ObjC C++ ObjC++
+Warn about possibly missing braces around initializers
+
+Wmissing-declarations
+C ObjC
+Warn about global functions without previous declarations
+
+Wmissing-format-attribute
+C ObjC C++ ObjC++
+Warn about functions which might be candidates for format attributes
+
+Wmissing-prototypes
+C ObjC
+Warn about global functions without prototypes
+
+Wmultichar
+C ObjC C++ ObjC++
+Warn about use of multi-character character constants
+
+Wnested-externs
+C ObjC
+Warn about \"extern\" declarations not at file scope
+
+Wnon-template-friend
+C++ ObjC++
+Warn when non-templatized friend functions are declared within a template
+
+Wnon-virtual-dtor
+C++ ObjC++
+Warn about non-virtual destructors
+
+Wnonnull
+C ObjC
+
+Wold-style-cast
+C++ ObjC++
+Warn if a C-style cast is used in a program
+
+Wold-style-definition
+C ObjC
+Warn if an old-style parameter definition is used
+
+Woverloaded-virtual
+C++ ObjC++
+Warn about overloaded virtual function names
+
+Wparentheses
+C ObjC C++ ObjC++
+Warn about possibly missing parentheses
+
+Wpmf-conversions
+C++ ObjC++
+Warn when converting the type of pointers to member functions
+
+Wpointer-arith
+C ObjC C++ ObjC++
+Warn about function pointer arithmetic
+
+Wprotocol
+ObjC ObjC++
+Warn if inherited methods are unimplemented
+
+Wredundant-decls
+C ObjC C++ ObjC++
+Warn about multiple declarations of the same object
+
+Wreorder
+C++ ObjC++
+Warn when the compiler reorders code
+
+Wreturn-type
+C ObjC C++ ObjC++
+Warn whenever a function's return type defaults to \"int\" (C), or about inconsistent return types (C++)
+
+Wselector
+ObjC ObjC++
+Warn if a selector has multiple methods
+
+Wsequence-point
+C ObjC
+Warn about possible violations of sequence point rules
+
+Wsign-compare
+C ObjC C++ ObjC++
+Warn about signed-unsigned comparisons
+
+Wsign-promo
+C++ ObjC++
+Warn when overload promotes from unsigned to signed
+
+Wstrict-prototypes
+C ObjC
+Warn about unprototyped function declarations
+
+Wsynth
+C++ ObjC++
+Warn when synthesis behavior differs from Cfront
+
+Wsystem-headers
+C ObjC C++ ObjC++
+Do not suppress warnings from system headers
+
+Wtraditional
+C ObjC
+Warn about features not present in traditional C
+
+Wtrigraphs
+C ObjC C++ ObjC++
+Warn if trigraphs are encountered that might affect the meaning of the program
+
+Wundeclared-selector
+ObjC ObjC++
+
+Wundef
+C ObjC C++ ObjC++
+Warn if an undefined macro is used in an #if directive
+
+Wunknown-pragmas
+C ObjC C++ ObjC++
+Warn about unrecognized pragmas
+
+Wunused-macros
+C ObjC C++ ObjC++
+Warn about macros defined in the main file that are not used
+
+Wwrite-strings
+C ObjC C++ ObjC++
+Give strings the type \"array of char\"
+
+ansi
+C ObjC C++ ObjC++
+A synonym for -std=c89. In a future version of GCC it will become synonymous with -std=c99 instead
+
+d
+C ObjC C++ ObjC++ Joined
+; Documented in common.opt. FIXME - what about -dI, -dD, -dN and -dD?
+
+faccess-control
+C++ ObjC++
+Enforce class member access control semantics
+
+fall-virtual
+C++ ObjC++
+
+falt-external-templates
+C++ ObjC++
+Change when template instances are emitted
+
+fasm
+C ObjC C++ ObjC++
+Recognize the \"asm\" keyword
+
+fbuiltin
+C ObjC C++ ObjC++
+Recognize built-in functions
+
+fbuiltin-
+C ObjC C++ ObjC++ Joined
+
+fcheck-new
+C++ ObjC++
+Check the return value of new
+
+fcond-mismatch
+C ObjC C++ ObjC++
+Allow the arguments of the '?' operator to have different types
+
+fconserve-space
+C++ ObjC++
+Reduce the size of object files
+
+fconst-strings
+C++ ObjC++
+Make string literals \"const char[]\" not \"char[]\"
+
+fconstant-string-class=
+ObjC ObjC++ Joined
+-fconst-string-class=<name> Use class <name> for constant strings
+
+fdefault-inline
+C++ ObjC++
+Inline member functions by default
+
+fdollars-in-identifiers
+C ObjC C++ ObjC++
+Permit '$' as an identifier character
+
+fdump-
+C ObjC C++ ObjC++ Joined RejectNegative
+-fdump-<type> Dump various compiler internals to a file
+
+felide-constructors
+C++ ObjC++
+
+fenforce-eh-specs
+C++ ObjC++
+Generate code to check exception specifications
+
+fenum-int-equiv
+C++ ObjC++
+
+fexec-charset=
+C ObjC C++ ObjC++ Joined RejectNegative
+-fexec-charset=<cset> Convert all strings and character constants to character set <cset>
+
+finput-charset=
+C ObjC C++ ObjC++ Joined RejectNegative
+-finput-charset=<cset> Specify the default character set for source files.
+
+
+fexternal-templates
+C++ ObjC++
+
+ffixed-form
+C ObjC
+
+ffixed-line-length-
+C ObjC Joined
+
+ffor-scope
+C++ ObjC++
+Scope of for-init-statement variables is local to the loop
+
+ffreestanding
+C ObjC
+Do not assume that standard C libraries and \"main\" exist
+
+fgnu-keywords
+C++ ObjC++
+Recognize GNU-defined keywords
+
+fgnu-runtime
+ObjC ObjC++
+Generate code for GNU runtime environment
+
+fguiding-decls
+C++ ObjC++
+
+fhandle-exceptions
+C++ ObjC++
+
+fhonor-std
+C++ ObjC++
+
+fhosted
+C ObjC
+Assume normal C execution environment
+
+fhuge-objects
+C++ ObjC++
+Enable support for huge objects
+
+fimplement-inlines
+C++ ObjC++
+Export functions even if they can be inlined
+
+fimplicit-inline-templates
+C++ ObjC++
+Emit implicit instantiations of inline templates
+
+fimplicit-templates
+C++ ObjC++
+Emit implicit instantiations of templates
+
+flabels-ok
+C++ ObjC++
+
+fms-extensions
+C ObjC C++ ObjC++
+Don't warn about uses of Microsoft extensions
+
+fname-mangling-version-
+C++ ObjC++ Joined
+
+fnew-abi
+C++ ObjC++
+
+fnext-runtime
+ObjC ObjC++
+Generate code for NeXT (Apple Mac OS X) runtime environment
+
+fnil-receivers
+ObjC ObjC++
+Assume that receivers of Objective-C messages may be nil
+
+fnonansi-builtins
+C++ ObjC++
+
+fnonnull-objects
+C++ ObjC++
+
+fobjc-exceptions
+ObjC ObjC++
+Enable Objective-C exception and synchronization syntax
+
+foperator-names
+C++ ObjC++
+Recognize C++ kewords like \"compl\" and \"xor\"
+
+foptional-diags
+C++ ObjC++
+Enable optional diagnostics
+
+fpch-deps
+C ObjC C++ ObjC++
+
+fpermissive
+C++ ObjC++
+Downgrade conformance errors to warnings
+
+fpreprocessed
+C ObjC C++ ObjC++
+Treat the input file as already preprocessed
+
+freplace-objc-classes
+ObjC ObjC++
+Used in Fix-and-Continue mode to indicate that object files may be swapped in at runtime
+
+frepo
+C++ ObjC++
+Enable automatic template instantiation
+
+frtti
+C++ ObjC++
+Generate run time type descriptor information
+
+fshort-double
+C ObjC C++ ObjC++
+Use the same size for double as for float
+
+fshort-enums
+C ObjC C++ ObjC++
+Use the narrowest integer type possible for enumeration types
+
+fshort-wchar
+C ObjC C++ ObjC++
+Force the underlying type for \"wchar_t\" to be \"unsigned short\"
+
+fshow-column
+C ObjC C++ ObjC++
+
+fsigned-bitfields
+C ObjC C++ ObjC++
+When \"signed\" or \"unsigned\" is not given make the bitfield signed
+
+fsigned-char
+C ObjC C++ ObjC++
+Make \"char\" signed by default
+
+fsquangle
+C++ ObjC++
+
+fstats
+C++ ObjC++
+Display statistics accumulated during compilation
+
+fstrict-prototype
+C++ ObjC++
+
+ftabstop=
+C ObjC C++ ObjC++ Joined RejectNegative UInteger
+-ftabstop=<number> Distance between tab stops for column reporting
+
+ftemplate-depth-
+C++ ObjC++ Joined RejectNegative UInteger
+-ftemplate-depth-<number> Specify maximum template instantiation depth
+
+fthis-is-variable
+C++ ObjC++
+
+funsigned-bitfields
+C ObjC C++ ObjC++
+When \"signed\" or \"unsigned\" is not given make the bitfield unsigned
+
+funsigned-char
+C ObjC C++ ObjC++
+Make \"char\" unsigned by default
+
+fuse-cxa-atexit
+C++ ObjC++
+Use __cxa_atexit to register destructors
+
+fvtable-gc
+C++ ObjC++
+Discard unused virtual functions
+
+fvtable-thunks
+C++ ObjC++
+Implement vtables using thunks
+
+fweak
+C++ ObjC++
+Emit common-like symbols as weak symbols
+
+fwide-exec-charset=
+C ObjC C++ ObjC++ Joined RejectNegative
+-fwide-exec-charset=<cset> Convert all wide strings and character constants to character set <cset>
+
+fworking-directory
+C ObjC C++ ObjC++
+Generate a #line directive pointing at the current working directory
+
+fxref
+C++ ObjC++
+Emit cross referencing information
+
+fzero-link
+ObjC ObjC++
+Generate lazy class lookup (via objc_getClass()) for use in Zero-Link mode
+
+gen-decls
+ObjC ObjC++
+Dump declarations to a .decl file
+
+idirafter
+C ObjC C++ ObjC++ Joined Separate
+-idirafter <dir> Add <dir> to the end of the system include path
+
+imacros
+C ObjC C++ ObjC++ Joined Separate
+-imacros <file> Accept definition of macros in <file>
+
+include
+C ObjC C++ ObjC++ Joined Separate
+-include <file> Include the contents of <file> before other files
+
+iprefix
+C ObjC C++ ObjC++ Joined Separate
+-iprefix <path> Specify <path> as a prefix for next two options
+
+isysroot
+C ObjC C++ ObjC++ Joined Separate
+-isysroot <dir> Set <dir> to be the system root directory
+
+isystem
+C ObjC C++ ObjC++ Joined Separate
+-isystem <dir> Add <dir> to the start of the system include path
+
+iwithprefix
+C ObjC C++ ObjC++ Joined Separate
+-iwithprefix <dir> Add <dir> to the end of the system include path
+
+iwithprefixbefore
+C ObjC C++ ObjC++ Joined Separate
+-iwithprefixbefore <dir> Add <dir> to the end of the main include path
+
+lang-asm
+C Undocumented
+
+lang-objc
+C ObjC C++ ObjC++ Undocumented
+
+nostdinc
+C ObjC C++ ObjC++
+Do not search standard system include directories (those specified with -isystem will still be used)
+
+nostdinc++
+C++ ObjC++
+Do not search standard system include directories for C++
+
+o
+C ObjC C++ ObjC++ Joined Separate
+; Documented in common.opt
+
+pedantic
+C ObjC C++ ObjC++
+; Documented in common.opt
+
+pedantic-errors
+C ObjC C++ ObjC++
+; Documented in common.opt
+
+print-objc-runtime-info
+ObjC ObjC++
+Generate C header of platform-specific features
+
+remap
+C ObjC C++ ObjC++
+Remap file names when including files
+
+std=c++98
+C++ ObjC++
+Conform to the ISO 1998 C++ standard
+
+std=c89
+C ObjC
+Conform to the ISO 1990 C standard
+
+std=c99
+C ObjC
+Conform to the ISO 1999 C standard
+
+std=c9x
+C ObjC
+Deprecated in favor of -std=c99
+
+std=gnu++98
+C++ ObjC++
+Conform to the ISO 1998 C++ standard with GNU extensions
+
+std=gnu89
+C ObjC
+Conform to the ISO 1990 C standard with GNU extensions
+
+std=gnu99
+C ObjC
+Conform to the ISO 1999 C standard with GNU extensions
+
+std=gnu9x
+C ObjC
+Deprecated in favor of -std=gnu99
+
+std=iso9899:1990
+C ObjC
+Deprecated in favor of -std=c89
+
+std=iso9899:199409
+C ObjC
+Conform to the ISO 1990 C standard as amended in 1994
+
+std=iso9899:1999
+C ObjC
+Deprecated in favor of -std=c99
+
+std=iso9899:199x
+C ObjC
+Deprecated in favor of -std=c99
+
+traditional-cpp
+C ObjC C++ ObjC++
+Enable traditional preprocessing
+
+trigraphs
+C ObjC C++ ObjC++
+-trigraphs Support ISO C trigraphs
+
+undef
+C ObjC C++ ObjC++
+Do not predefine system-specific and GCC-specific macros
+
+v
+C ObjC C++ ObjC++
+Enable verbose output
+
+w
+C ObjC C++ ObjC++
+; Documented in common.opt
+
+; This comment is to ensure we retain the blank line above.
diff --git a/contrib/gcc/caller-save.c b/contrib/gcc/caller-save.c
index b7e3ceac7b5d..7133fe393abd 100644
--- a/contrib/gcc/caller-save.c
+++ b/contrib/gcc/caller-save.c
@@ -1,6 +1,6 @@
/* Save and restore call-clobbered registers which are live across a call.
Copyright (C) 1989, 1992, 1994, 1995, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "insn-config.h"
#include "flags.h"
@@ -49,13 +51,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
register because it is live we first try to save in multi-register modes.
If that is not possible the save is done one register at a time. */
-static enum machine_mode
+static enum machine_mode
regno_save_mode[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
/* For each hard register, a place on the stack where it can be saved,
if needed. */
-static rtx
+static rtx
regno_save_mem[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1];
/* We will only make a register eligible for caller-save if it can be
@@ -66,7 +68,7 @@ static rtx
static int
reg_save_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
-static int
+static int
reg_restore_code[FIRST_PSEUDO_REGISTER][MAX_MACHINE_MODE];
/* Set of hard regs currently residing in save area (during insn scan). */
@@ -86,29 +88,28 @@ static HARD_REG_SET referenced_regs;
static HARD_REG_SET this_insn_sets;
-static void mark_set_regs PARAMS ((rtx, rtx, void *));
-static void mark_referenced_regs PARAMS ((rtx));
-static int insert_save PARAMS ((struct insn_chain *, int, int,
- HARD_REG_SET *,
- enum machine_mode *));
-static int insert_restore PARAMS ((struct insn_chain *, int, int,
- int, enum machine_mode *));
-static struct insn_chain *insert_one_insn PARAMS ((struct insn_chain *, int,
- int, rtx));
-static void add_stored_regs PARAMS ((rtx, rtx, void *));
+static void mark_set_regs (rtx, rtx, void *);
+static void mark_referenced_regs (rtx);
+static int insert_save (struct insn_chain *, int, int, HARD_REG_SET *,
+ enum machine_mode *);
+static int insert_restore (struct insn_chain *, int, int, int,
+ enum machine_mode *);
+static struct insn_chain *insert_one_insn (struct insn_chain *, int, int,
+ rtx);
+static void add_stored_regs (rtx, rtx, void *);
/* Initialize for caller-save.
Look at all the hard registers that are used by a call and for which
regclass.c has not already excluded from being used across a call.
- Ensure that we can find a mode to save the register and that there is a
+ Ensure that we can find a mode to save the register and that there is a
simple insn to save and restore the register. This latter check avoids
problems that would occur if we tried to save the MQ register of some
machines directly into memory. */
void
-init_caller_save ()
+init_caller_save (void)
{
rtx addr_reg;
int offset;
@@ -182,7 +183,7 @@ init_caller_save ()
address = addr_reg;
/* Next we try to form an insn to save and restore the register. We
- see if such an insn is recognized and meets its constraints.
+ see if such an insn is recognized and meets its constraints.
To avoid lots of unnecessary RTL allocation, we construct all the RTL
once, then modify the memory and register operands in-place. */
@@ -254,7 +255,7 @@ init_caller_save ()
/* Initialize save areas by showing that we haven't allocated any yet. */
void
-init_save_areas ()
+init_save_areas (void)
{
int i, j;
@@ -272,17 +273,17 @@ init_save_areas ()
Future work:
In the fallback case we should iterate backwards across all possible
- modes for the save, choosing the largest available one instead of
+ modes for the save, choosing the largest available one instead of
falling back to the smallest mode immediately. (eg TF -> DF -> SF).
We do not try to use "move multiple" instructions that exist
- on some machines (such as the 68k moveml). It could be a win to try
+ on some machines (such as the 68k moveml). It could be a win to try
and use them when possible. The hard part is doing it in a way that is
- machine independent since they might be saving non-consecutive
+ machine independent since they might be saving non-consecutive
registers. (imagine caller-saving d0,d1,a0,a1 on the 68k) */
void
-setup_save_areas ()
+setup_save_areas (void)
{
int i, j, k;
unsigned int r;
@@ -298,7 +299,7 @@ setup_save_areas ()
if (reg_renumber[i] >= 0 && REG_N_CALLS_CROSSED (i) > 0)
{
unsigned int regno = reg_renumber[i];
- unsigned int endregno
+ unsigned int endregno
= regno + HARD_REGNO_NREGS (regno, GET_MODE (regno_reg_rtx[i]));
for (r = regno; r < endregno; r++)
@@ -365,7 +366,7 @@ setup_save_areas ()
/* Find the places where hard regs are live across calls and save them. */
void
-save_call_clobbered_regs ()
+save_call_clobbered_regs (void)
{
struct insn_chain *chain, *next;
enum machine_mode save_mode [FIRST_PSEUDO_REGISTER];
@@ -407,7 +408,7 @@ save_call_clobbered_regs ()
regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS, save_mode);
}
- if (code == CALL_INSN)
+ if (code == CALL_INSN && ! find_reg_note (insn, REG_NORETURN, NULL))
{
int regno;
HARD_REG_SET hard_regs_to_save;
@@ -486,7 +487,7 @@ save_call_clobbered_regs ()
regno += insert_restore (chain, GET_CODE (insn) == JUMP_INSN,
regno, MOVE_MAX_WORDS, save_mode);
}
- }
+ }
}
/* Here from note_stores when an insn stores a value in a register.
@@ -494,10 +495,8 @@ save_call_clobbered_regs ()
been assigned hard regs have had their register number changed already,
so we can ignore pseudos. */
static void
-mark_set_regs (reg, setter, data)
- rtx reg;
- rtx setter ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+mark_set_regs (rtx reg, rtx setter ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
{
int regno, endregno, i;
enum machine_mode mode = GET_MODE (reg);
@@ -527,10 +526,7 @@ mark_set_regs (reg, setter, data)
been assigned hard regs have had their register number changed already,
so we can ignore pseudos. */
static void
-add_stored_regs (reg, setter, data)
- rtx reg;
- rtx setter;
- void *data;
+add_stored_regs (rtx reg, rtx setter, void *data)
{
int regno, endregno, i;
enum machine_mode mode = GET_MODE (reg);
@@ -560,8 +556,7 @@ add_stored_regs (reg, setter, data)
/* Walk X and record all referenced registers in REFERENCED_REGS. */
static void
-mark_referenced_regs (x)
- rtx x;
+mark_referenced_regs (rtx x)
{
enum rtx_code code = GET_CODE (x);
const char *fmt;
@@ -573,8 +568,10 @@ mark_referenced_regs (x)
{
x = SET_DEST (x);
code = GET_CODE (x);
- if (code == REG || code == PC || code == CC0
+ if ((code == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
+ || code == PC || code == CC0
|| (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG
+ && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER
/* If we're setting only part of a multi-word register,
we shall mark it as referenced, because the words
that are not being set should be restored. */
@@ -637,12 +634,8 @@ mark_referenced_regs (x)
Return the extra number of registers saved. */
static int
-insert_restore (chain, before_p, regno, maxrestore, save_mode)
- struct insn_chain *chain;
- int before_p;
- int regno;
- int maxrestore;
- enum machine_mode *save_mode;
+insert_restore (struct insn_chain *chain, int before_p, int regno,
+ int maxrestore, enum machine_mode *save_mode)
{
int i, k;
rtx pat = NULL_RTX;
@@ -679,7 +672,7 @@ insert_restore (chain, before_p, regno, maxrestore, save_mode)
ok = 0;
break;
}
- /* Must do this one restore at a time */
+ /* Must do this one restore at a time. */
if (! ok)
continue;
@@ -693,7 +686,7 @@ insert_restore (chain, before_p, regno, maxrestore, save_mode)
&& numregs == (unsigned int) HARD_REGNO_NREGS (regno, save_mode [regno]))
mem = adjust_address (mem, save_mode[regno], 0);
pat = gen_rtx_SET (VOIDmode,
- gen_rtx_REG (GET_MODE (mem),
+ gen_rtx_REG (GET_MODE (mem),
regno), mem);
code = reg_restore_code[regno][GET_MODE (mem)];
new = insert_one_insn (chain, before_p, code, pat);
@@ -706,19 +699,15 @@ insert_restore (chain, before_p, regno, maxrestore, save_mode)
n_regs_saved--;
}
- /* Tell our callers how many extra registers we saved/restored */
+ /* Tell our callers how many extra registers we saved/restored. */
return numregs - 1;
}
/* Like insert_restore above, but save registers instead. */
static int
-insert_save (chain, before_p, regno, to_save, save_mode)
- struct insn_chain *chain;
- int before_p;
- int regno;
- HARD_REG_SET *to_save;
- enum machine_mode *save_mode;
+insert_save (struct insn_chain *chain, int before_p, int regno,
+ HARD_REG_SET (*to_save), enum machine_mode *save_mode)
{
int i;
unsigned int k;
@@ -740,7 +729,7 @@ insert_save (chain, before_p, regno, to_save, save_mode)
/* Get the pattern to emit and update our status.
- See if we can save several registers with a single instruction.
+ See if we can save several registers with a single instruction.
Work backwards to the single register case. */
for (i = MOVE_MAX_WORDS; i > 0; i--)
{
@@ -755,7 +744,7 @@ insert_save (chain, before_p, regno, to_save, save_mode)
ok = 0;
break;
}
- /* Must do this one save at a time */
+ /* Must do this one save at a time. */
if (! ok)
continue;
@@ -782,21 +771,17 @@ insert_save (chain, before_p, regno, to_save, save_mode)
n_regs_saved++;
}
- /* Tell our callers how many extra registers we saved/restored */
+ /* Tell our callers how many extra registers we saved/restored. */
return numregs - 1;
}
/* Emit a new caller-save insn and set the code. */
static struct insn_chain *
-insert_one_insn (chain, before_p, code, pat)
- struct insn_chain *chain;
- int before_p;
- int code;
- rtx pat;
+insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
{
rtx insn = chain->insn;
struct insn_chain *new;
-
+
#ifdef HAVE_cc0
/* If INSN references CC0, put our insns in front of the insn that sets
CC0. This is always safe, since the only way we could be passed an
@@ -849,8 +834,8 @@ insert_one_insn (chain, before_p, code, pat)
}
}
CLEAR_REG_SET (&new->dead_or_set);
- if (chain->insn == BLOCK_HEAD (chain->block))
- BLOCK_HEAD (chain->block) = new->insn;
+ if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block)))
+ BB_HEAD (BASIC_BLOCK (chain->block)) = new->insn;
}
else
{
@@ -869,8 +854,8 @@ insert_one_insn (chain, before_p, code, pat)
note_stores (PATTERN (chain->insn), add_stored_regs,
&new->live_throughout);
CLEAR_REG_SET (&new->dead_or_set);
- if (chain->insn == BLOCK_END (chain->block))
- BLOCK_END (chain->block) = new->insn;
+ if (chain->insn == BB_END (BASIC_BLOCK (chain->block)))
+ BB_END (BASIC_BLOCK (chain->block)) = new->insn;
}
new->block = chain->block;
new->is_caller_save_insn = 1;
diff --git a/contrib/gcc/calls.c b/contrib/gcc/calls.c
index 675674ec7f55..5dc96c684fd3 100644
--- a/contrib/gcc/calls.c
+++ b/contrib/gcc/calls.c
@@ -1,6 +1,6 @@
/* Convert function calls to rtl insns, for GNU C compiler.
- Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,10 +21,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "flags.h"
#include "expr.h"
+#include "optabs.h"
#include "libfuncs.h"
#include "function.h"
#include "regs.h"
@@ -35,36 +38,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "sbitmap.h"
#include "langhooks.h"
#include "target.h"
+#include "cgraph.h"
#include "except.h"
-#if !defined FUNCTION_OK_FOR_SIBCALL
-#define FUNCTION_OK_FOR_SIBCALL(DECL) 1
-#endif
-
-/* Decide whether a function's arguments should be processed
- from first to last or from last to first.
-
- They should if the stack and args grow in opposite directions, but
- only if we have push insns. */
-
-#ifdef PUSH_ROUNDING
-
-#ifndef PUSH_ARGS_REVERSED
-#if defined (STACK_GROWS_DOWNWARD) != defined (ARGS_GROW_DOWNWARD)
-#define PUSH_ARGS_REVERSED PUSH_ARGS
-#endif
-#endif
-
-#endif
-
-#ifndef PUSH_ARGS_REVERSED
-#define PUSH_ARGS_REVERSED 0
-#endif
-
-#ifndef STACK_POINTER_OFFSET
-#define STACK_POINTER_OFFSET 0
-#endif
-
/* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits. */
#define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
@@ -99,16 +75,8 @@ struct arg_data
even though pass_on_stack is zero, just because FUNCTION_ARG says so.
pass_on_stack identifies arguments that *cannot* go in registers. */
int pass_on_stack;
- /* Offset of this argument from beginning of stack-args. */
- struct args_size offset;
- /* Similar, but offset to the start of the stack slot. Different from
- OFFSET if this arg pads downward. */
- struct args_size slot_offset;
- /* Size of this argument on the stack, rounded up for any padding it gets,
- parts of the argument passed in registers do not count.
- If REG_PARM_STACK_SPACE is defined, then register parms
- are counted here as well. */
- struct args_size size;
+ /* Some fields packaged up for locate_and_pad_parm. */
+ struct locate_and_pad_arg_data locate;
/* Location on the stack at which parameter should be stored. The store
has already been done if STACK == VALUE. */
rtx stack;
@@ -124,9 +92,6 @@ struct arg_data
word-sized pseudos we made. */
rtx *aligned_regs;
int n_aligned_regs;
- /* The amount that the stack pointer needs to be adjusted to
- force alignment for the next argument. */
- struct args_size alignment_pad;
};
/* A vector of one char per byte of stack space. A byte if nonzero if
@@ -152,87 +117,43 @@ static sbitmap stored_args_map;
argument list for the constructor call. */
int stack_arg_under_construction;
-static int calls_function PARAMS ((tree, int));
-static int calls_function_1 PARAMS ((tree, int));
-
-/* Nonzero if this is a call to a `const' function. */
-#define ECF_CONST 1
-/* Nonzero if this is a call to a `volatile' function. */
-#define ECF_NORETURN 2
-/* Nonzero if this is a call to malloc or a related function. */
-#define ECF_MALLOC 4
-/* Nonzero if it is plausible that this is a call to alloca. */
-#define ECF_MAY_BE_ALLOCA 8
-/* Nonzero if this is a call to a function that won't throw an exception. */
-#define ECF_NOTHROW 16
-/* Nonzero if this is a call to setjmp or a related function. */
-#define ECF_RETURNS_TWICE 32
-/* Nonzero if this is a call to `longjmp'. */
-#define ECF_LONGJMP 64
-/* Nonzero if this is a syscall that makes a new process in the image of
- the current one. */
-#define ECF_FORK_OR_EXEC 128
-#define ECF_SIBCALL 256
-/* Nonzero if this is a call to "pure" function (like const function,
- but may read memory. */
-#define ECF_PURE 512
-/* Nonzero if this is a call to a function that returns with the stack
- pointer depressed. */
-#define ECF_SP_DEPRESSED 1024
-/* Nonzero if this call is known to always return. */
-#define ECF_ALWAYS_RETURN 2048
-/* Create libcall block around the call. */
-#define ECF_LIBCALL_BLOCK 4096
-
-static void emit_call_1 PARAMS ((rtx, tree, tree, HOST_WIDE_INT,
- HOST_WIDE_INT, HOST_WIDE_INT, rtx,
- rtx, int, rtx, int,
- CUMULATIVE_ARGS *));
-static void precompute_register_parameters PARAMS ((int,
- struct arg_data *,
- int *));
-static int store_one_arg PARAMS ((struct arg_data *, rtx, int, int,
- int));
-static void store_unaligned_arguments_into_pseudos PARAMS ((struct arg_data *,
- int));
-static int finalize_must_preallocate PARAMS ((int, int,
- struct arg_data *,
- struct args_size *));
-static void precompute_arguments PARAMS ((int, int,
- struct arg_data *));
-static int compute_argument_block_size PARAMS ((int,
- struct args_size *,
- int));
-static void initialize_argument_information PARAMS ((int,
- struct arg_data *,
- struct args_size *,
- int, tree, tree,
- CUMULATIVE_ARGS *,
- int, rtx *, int *,
- int *, int *));
-static void compute_argument_addresses PARAMS ((struct arg_data *,
- rtx, int));
-static rtx rtx_for_function_call PARAMS ((tree, tree));
-static void load_register_parameters PARAMS ((struct arg_data *,
- int, rtx *, int));
-static rtx emit_library_call_value_1 PARAMS ((int, rtx, rtx,
- enum libcall_type,
- enum machine_mode,
- int, va_list));
-static int special_function_p PARAMS ((tree, int));
-static int flags_from_decl_or_type PARAMS ((tree));
-static rtx try_to_integrate PARAMS ((tree, tree, rtx,
- int, tree, rtx));
-static int check_sibcall_argument_overlap_1 PARAMS ((rtx));
-static int check_sibcall_argument_overlap PARAMS ((rtx, struct arg_data *));
-
-static int combine_pending_stack_adjustment_and_call
- PARAMS ((int, struct args_size *, int));
-static tree fix_unsafe_tree PARAMS ((tree));
+static int calls_function (tree, int);
+static int calls_function_1 (tree, int);
+
+static void emit_call_1 (rtx, tree, tree, HOST_WIDE_INT, HOST_WIDE_INT,
+ HOST_WIDE_INT, rtx, rtx, int, rtx, int,
+ CUMULATIVE_ARGS *);
+static void precompute_register_parameters (int, struct arg_data *, int *);
+static int store_one_arg (struct arg_data *, rtx, int, int, int);
+static void store_unaligned_arguments_into_pseudos (struct arg_data *, int);
+static int finalize_must_preallocate (int, int, struct arg_data *,
+ struct args_size *);
+static void precompute_arguments (int, int, struct arg_data *);
+static int compute_argument_block_size (int, struct args_size *, int);
+static void initialize_argument_information (int, struct arg_data *,
+ struct args_size *, int, tree,
+ tree, CUMULATIVE_ARGS *, int,
+ rtx *, int *, int *, int *,
+ bool);
+static void compute_argument_addresses (struct arg_data *, rtx, int);
+static rtx rtx_for_function_call (tree, tree);
+static void load_register_parameters (struct arg_data *, int, rtx *, int,
+ int, int *);
+static rtx emit_library_call_value_1 (int, rtx, rtx, enum libcall_type,
+ enum machine_mode, int, va_list);
+static int special_function_p (tree, int);
+static rtx try_to_integrate (tree, tree, rtx, int, tree, rtx);
+static int check_sibcall_argument_overlap_1 (rtx);
+static int check_sibcall_argument_overlap (rtx, struct arg_data *, int);
+
+static int combine_pending_stack_adjustment_and_call (int, struct args_size *,
+ int);
+static tree fix_unsafe_tree (tree);
+static bool shift_returned_value (tree, rtx *);
#ifdef REG_PARM_STACK_SPACE
-static rtx save_fixed_argument_area PARAMS ((int, rtx, int *, int *));
-static void restore_fixed_argument_area PARAMS ((rtx, rtx, int, int));
+static rtx save_fixed_argument_area (int, rtx, int *, int *);
+static void restore_fixed_argument_area (rtx, rtx, int, int);
#endif
/* If WHICH is 1, return 1 if EXP contains a call to the built-in function
@@ -246,9 +167,7 @@ static void restore_fixed_argument_area PARAMS ((rtx, rtx, int, int));
static tree calls_function_save_exprs;
static int
-calls_function (exp, which)
- tree exp;
- int which;
+calls_function (tree exp, int which)
{
int val;
@@ -261,9 +180,7 @@ calls_function (exp, which)
/* Recursive function to do the work of above function. */
static int
-calls_function_1 (exp, which)
- tree exp;
- int which;
+calls_function_1 (tree exp, int which)
{
int i;
enum tree_code code = TREE_CODE (exp);
@@ -343,8 +260,8 @@ calls_function_1 (exp, which)
break;
}
- /* Only expressions, references, and blocks can contain calls. */
- if (! IS_EXPR_CODE_CLASS (class) && class != 'r' && class != 'b')
+ /* Only expressions and blocks can contain calls. */
+ if (! IS_EXPR_CODE_CLASS (class) && class != 'b')
return 0;
for (i = 0; i < length; i++)
@@ -363,12 +280,8 @@ calls_function_1 (exp, which)
CALL_INSN_FUNCTION_USAGE information. */
rtx
-prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen, sibcallp)
- rtx funexp;
- tree fndecl;
- rtx *call_fusage;
- int reg_parm_seen;
- int sibcallp;
+prepare_call_address (rtx funexp, tree fndecl, rtx *call_fusage,
+ int reg_parm_seen, int sibcallp)
{
rtx static_chain_value = 0;
@@ -378,7 +291,7 @@ prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen, sibcallp)
/* Get possible static chain value for nested function in C. */
static_chain_value = lookup_static_chain (fndecl);
- /* Make a valid memory address and copy constants thru pseudo-regs,
+ /* Make a valid memory address and copy constants through pseudo-regs,
but not for a constant address if -fno-function-cse. */
if (GET_CODE (funexp) != SYMBOL_REF)
/* If we are using registers for parameters, force the
@@ -449,21 +362,13 @@ prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen, sibcallp)
denote registers used by the called function. */
static void
-emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
- struct_value_size, next_arg_reg, valreg, old_inhibit_defer_pop,
- call_fusage, ecf_flags, args_so_far)
- rtx funexp;
- tree fndecl ATTRIBUTE_UNUSED;
- tree funtype ATTRIBUTE_UNUSED;
- HOST_WIDE_INT stack_size ATTRIBUTE_UNUSED;
- HOST_WIDE_INT rounded_stack_size;
- HOST_WIDE_INT struct_value_size ATTRIBUTE_UNUSED;
- rtx next_arg_reg ATTRIBUTE_UNUSED;
- rtx valreg;
- int old_inhibit_defer_pop;
- rtx call_fusage;
- int ecf_flags;
- CUMULATIVE_ARGS *args_so_far ATTRIBUTE_UNUSED;
+emit_call_1 (rtx funexp, tree fndecl ATTRIBUTE_UNUSED, tree funtype ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT stack_size ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT rounded_stack_size,
+ HOST_WIDE_INT struct_value_size ATTRIBUTE_UNUSED,
+ rtx next_arg_reg ATTRIBUTE_UNUSED, rtx valreg,
+ int old_inhibit_defer_pop, rtx call_fusage, int ecf_flags,
+ CUMULATIVE_ARGS *args_so_far ATTRIBUTE_UNUSED)
{
rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
rtx call_insn;
@@ -477,7 +382,7 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
#ifdef CALL_POPS_ARGS
n_popped += CALL_POPS_ARGS (* args_so_far);
#endif
-
+
/* Ensure address is valid. SYMBOL_REF is already valid, so no need,
and we don't want to load it into a register as an optimization,
because prepare_call_address already did it if it should be done. */
@@ -576,14 +481,8 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
#endif
abort ();
- /* Find the CALL insn we just emitted. */
- for (call_insn = get_last_insn ();
- call_insn && GET_CODE (call_insn) != CALL_INSN;
- call_insn = PREV_INSN (call_insn))
- ;
-
- if (! call_insn)
- abort ();
+ /* Find the call we just emitted. */
+ call_insn = last_call_insn ();
/* Mark memory as used for "pure" function call. */
if (ecf_flags & ECF_PURE)
@@ -594,20 +493,8 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))),
call_fusage);
- /* Put the register usage information on the CALL. If there is already
- some usage information, put ours at the end. */
- if (CALL_INSN_FUNCTION_USAGE (call_insn))
- {
- rtx link;
-
- for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
- link = XEXP (link, 1))
- ;
-
- XEXP (link, 1) = call_fusage;
- }
- else
- CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
+ /* Put the register usage information there. */
+ add_function_usage_to (call_insn, call_fusage);
/* If this is a const call, then set the insn's unchanging bit. */
if (ecf_flags & (ECF_CONST | ECF_PURE))
@@ -641,10 +528,6 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
if the context of the call as a whole permits. */
inhibit_defer_pop = old_inhibit_defer_pop;
- /* Don't bother cleaning up after a noreturn function. */
- if (ecf_flags & (ECF_NORETURN | ECF_LONGJMP))
- return;
-
if (n_popped > 0)
{
if (!already_popped)
@@ -668,7 +551,7 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
if (rounded_stack_size != 0)
{
- if (ecf_flags & ECF_SP_DEPRESSED)
+ if (ecf_flags & (ECF_SP_DEPRESSED | ECF_NORETURN | ECF_LONGJMP))
/* Just pretend we did the pop. */
stack_pointer_delta -= rounded_stack_size;
else if (flag_defer_pop && inhibit_defer_pop == 0
@@ -701,24 +584,25 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
Similarly set LONGJMP for if the function is in the longjmp family.
- Set MALLOC for any of the standard memory allocation functions which
- allocate from the heap.
-
Set MAY_BE_ALLOCA for any memory allocation function that might allocate
space from the stack such as alloca. */
static int
-special_function_p (fndecl, flags)
- tree fndecl;
- int flags;
+special_function_p (tree fndecl, int flags)
{
if (! (flags & ECF_MALLOC)
&& fndecl && DECL_NAME (fndecl)
&& IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 17
/* Exclude functions not at the file scope, or not `extern',
since they are not the magic functions we would otherwise
- think they are. */
- && DECL_CONTEXT (fndecl) == NULL_TREE && TREE_PUBLIC (fndecl))
+ think they are.
+ FIXME: this should be handled with attributes, not with this
+ hacky imitation of DECL_ASSEMBLER_NAME. It's (also) wrong
+ because you can declare fork() inside a function if you
+ wish. */
+ && (DECL_CONTEXT (fndecl) == NULL_TREE
+ || TREE_CODE (DECL_CONTEXT (fndecl)) == TRANSLATION_UNIT_DECL)
+ && TREE_PUBLIC (fndecl))
{
const char *name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
const char *tname = name;
@@ -783,19 +667,6 @@ special_function_p (fndecl, flags)
|| ((tname[5] == 'p' || tname[5] == 'e')
&& tname[6] == '\0'))))
flags |= ECF_FORK_OR_EXEC;
-
- /* Do not add any more malloc-like functions to this list,
- instead mark them as malloc functions using the malloc attribute.
- Note, realloc is not suitable for attribute malloc since
- it may return the same address across multiple calls.
- C++ operator new is not suitable because it is not required
- to return a unique pointer; indeed, the standard placement new
- just returns its argument. */
- else if (TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == Pmode
- && (! strcmp (tname, "malloc")
- || ! strcmp (tname, "calloc")
- || ! strcmp (tname, "strdup")))
- flags |= ECF_MALLOC;
}
return flags;
}
@@ -803,16 +674,14 @@ special_function_p (fndecl, flags)
/* Return nonzero when tree represent call to longjmp. */
int
-setjmp_call_p (fndecl)
- tree fndecl;
+setjmp_call_p (tree fndecl)
{
return special_function_p (fndecl, 0) & ECF_RETURNS_TWICE;
}
/* Return true when exp contains alloca call. */
bool
-alloca_call_p (exp)
- tree exp;
+alloca_call_p (tree exp)
{
if (TREE_CODE (exp) == CALL_EXPR
&& TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
@@ -826,23 +695,31 @@ alloca_call_p (exp)
/* Detect flags (function attributes) from the function decl or type node. */
-static int
-flags_from_decl_or_type (exp)
- tree exp;
+int
+flags_from_decl_or_type (tree exp)
{
int flags = 0;
tree type = exp;
- /* ??? We can't set IS_MALLOC for function types? */
+
if (DECL_P (exp))
{
+ struct cgraph_rtl_info *i = cgraph_rtl_info (exp);
type = TREE_TYPE (exp);
+ if (i)
+ {
+ if (i->pure_function)
+ flags |= ECF_PURE | ECF_LIBCALL_BLOCK;
+ if (i->const_function)
+ flags |= ECF_CONST | ECF_LIBCALL_BLOCK;
+ }
+
/* The function exp may have the `malloc' attribute. */
- if (DECL_P (exp) && DECL_IS_MALLOC (exp))
+ if (DECL_IS_MALLOC (exp))
flags |= ECF_MALLOC;
/* The function exp may have the `pure' attribute. */
- if (DECL_P (exp) && DECL_IS_PURE (exp))
+ if (DECL_IS_PURE (exp))
flags |= ECF_PURE | ECF_LIBCALL_BLOCK;
if (TREE_NOTHROW (exp))
@@ -869,6 +746,28 @@ flags_from_decl_or_type (exp)
return flags;
}
+/* Detect flags from a CALL_EXPR. */
+
+int
+call_expr_flags (tree t)
+{
+ int flags;
+ tree decl = get_callee_fndecl (t);
+
+ if (decl)
+ flags = flags_from_decl_or_type (decl);
+ else
+ {
+ t = TREE_TYPE (TREE_OPERAND (t, 0));
+ if (t && TREE_CODE (t) == POINTER_TYPE)
+ flags = flags_from_decl_or_type (TREE_TYPE (t));
+ else
+ flags = 0;
+ }
+
+ return flags;
+}
+
/* Precompute all register parameters as described by ARGS, storing values
into fields within the ARGS array.
@@ -877,10 +776,7 @@ flags_from_decl_or_type (exp)
Set REG_PARM_SEEN if we encounter a register parameter. */
static void
-precompute_register_parameters (num_actuals, args, reg_parm_seen)
- int num_actuals;
- struct arg_data *args;
- int *reg_parm_seen;
+precompute_register_parameters (int num_actuals, struct arg_data *args, int *reg_parm_seen)
{
int i;
@@ -945,96 +841,88 @@ precompute_register_parameters (num_actuals, args, reg_parm_seen)
parameters, we must save and restore it. */
static rtx
-save_fixed_argument_area (reg_parm_stack_space, argblock,
- low_to_save, high_to_save)
- int reg_parm_stack_space;
- rtx argblock;
- int *low_to_save;
- int *high_to_save;
+save_fixed_argument_area (int reg_parm_stack_space, rtx argblock, int *low_to_save, int *high_to_save)
{
- int i;
- rtx save_area = NULL_RTX;
+ int low;
+ int high;
- /* Compute the boundary of the that needs to be saved, if any. */
+ /* Compute the boundary of the area that needs to be saved, if any. */
+ high = reg_parm_stack_space;
#ifdef ARGS_GROW_DOWNWARD
- for (i = 0; i < reg_parm_stack_space + 1; i++)
-#else
- for (i = 0; i < reg_parm_stack_space; i++)
+ high += 1;
#endif
- {
- if (i >= highest_outgoing_arg_in_use
- || stack_usage_map[i] == 0)
- continue;
+ if (high > highest_outgoing_arg_in_use)
+ high = highest_outgoing_arg_in_use;
- if (*low_to_save == -1)
- *low_to_save = i;
+ for (low = 0; low < high; low++)
+ if (stack_usage_map[low] != 0)
+ {
+ int num_to_save;
+ enum machine_mode save_mode;
+ int delta;
+ rtx stack_area;
+ rtx save_area;
- *high_to_save = i;
- }
+ while (stack_usage_map[--high] == 0)
+ ;
- if (*low_to_save >= 0)
- {
- int num_to_save = *high_to_save - *low_to_save + 1;
- enum machine_mode save_mode
- = mode_for_size (num_to_save * BITS_PER_UNIT, MODE_INT, 1);
- rtx stack_area;
+ *low_to_save = low;
+ *high_to_save = high;
+
+ num_to_save = high - low + 1;
+ save_mode = mode_for_size (num_to_save * BITS_PER_UNIT, MODE_INT, 1);
- /* If we don't have the required alignment, must do this in BLKmode. */
- if ((*low_to_save & (MIN (GET_MODE_SIZE (save_mode),
- BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1)))
- save_mode = BLKmode;
+ /* If we don't have the required alignment, must do this
+ in BLKmode. */
+ if ((low & (MIN (GET_MODE_SIZE (save_mode),
+ BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1)))
+ save_mode = BLKmode;
#ifdef ARGS_GROW_DOWNWARD
- stack_area
- = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- plus_constant (argblock,
- - *high_to_save)));
+ delta = -high;
#else
- stack_area = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- plus_constant (argblock,
- *low_to_save)));
+ delta = low;
#endif
+ stack_area = gen_rtx_MEM (save_mode,
+ memory_address (save_mode,
+ plus_constant (argblock,
+ delta)));
- set_mem_align (stack_area, PARM_BOUNDARY);
- if (save_mode == BLKmode)
- {
- save_area = assign_stack_temp (BLKmode, num_to_save, 0);
- emit_block_move (validize_mem (save_area), stack_area,
- GEN_INT (num_to_save), BLOCK_OP_CALL_PARM);
- }
- else
- {
- save_area = gen_reg_rtx (save_mode);
- emit_move_insn (save_area, stack_area);
- }
- }
+ set_mem_align (stack_area, PARM_BOUNDARY);
+ if (save_mode == BLKmode)
+ {
+ save_area = assign_stack_temp (BLKmode, num_to_save, 0);
+ emit_block_move (validize_mem (save_area), stack_area,
+ GEN_INT (num_to_save), BLOCK_OP_CALL_PARM);
+ }
+ else
+ {
+ save_area = gen_reg_rtx (save_mode);
+ emit_move_insn (save_area, stack_area);
+ }
+
+ return save_area;
+ }
- return save_area;
+ return NULL_RTX;
}
static void
-restore_fixed_argument_area (save_area, argblock, high_to_save, low_to_save)
- rtx save_area;
- rtx argblock;
- int high_to_save;
- int low_to_save;
+restore_fixed_argument_area (rtx save_area, rtx argblock, int high_to_save, int low_to_save)
{
enum machine_mode save_mode = GET_MODE (save_area);
+ int delta;
+ rtx stack_area;
+
#ifdef ARGS_GROW_DOWNWARD
- rtx stack_area
- = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- plus_constant (argblock,
- - high_to_save)));
+ delta = -high_to_save;
#else
- rtx stack_area
- = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- plus_constant (argblock,
- low_to_save)));
+ delta = low_to_save;
#endif
+ stack_area = gen_rtx_MEM (save_mode,
+ memory_address (save_mode,
+ plus_constant (argblock, delta)));
+ set_mem_align (stack_area, PARM_BOUNDARY);
if (save_mode != BLKmode)
emit_move_insn (stack_area, save_area);
@@ -1055,9 +943,7 @@ restore_fixed_argument_area (save_area, argblock, high_to_save, low_to_save)
the aligned_regs array if it is nonzero. */
static void
-store_unaligned_arguments_into_pseudos (args, num_actuals)
- struct arg_data *args;
- int num_actuals;
+store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
{
int i, j;
@@ -1068,22 +954,26 @@ store_unaligned_arguments_into_pseudos (args, num_actuals)
< (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
{
int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
- int big_endian_correction = 0;
-
- args[i].n_aligned_regs
- = args[i].partial ? args[i].partial
- : (bytes + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+ int nregs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ int endian_correction = 0;
- args[i].aligned_regs = (rtx *) xmalloc (sizeof (rtx)
- * args[i].n_aligned_regs);
+ args[i].n_aligned_regs = args[i].partial ? args[i].partial : nregs;
+ args[i].aligned_regs = xmalloc (sizeof (rtx) * args[i].n_aligned_regs);
- /* Structures smaller than a word are aligned to the least
- significant byte (to the right). On a BYTES_BIG_ENDIAN machine,
+ /* Structures smaller than a word are normally aligned to the
+ least significant byte. On a BYTES_BIG_ENDIAN machine,
this means we must skip the empty high order bytes when
calculating the bit offset. */
- if (BYTES_BIG_ENDIAN
- && bytes < UNITS_PER_WORD)
- big_endian_correction = (BITS_PER_WORD - (bytes * BITS_PER_UNIT));
+ if (bytes < UNITS_PER_WORD
+#ifdef BLOCK_REG_PADDING
+ && (BLOCK_REG_PADDING (args[i].mode,
+ TREE_TYPE (args[i].tree_value), 1)
+ == downward)
+#else
+ && BYTES_BIG_ENDIAN
+#endif
+ )
+ endian_correction = BITS_PER_WORD - bytes * BITS_PER_UNIT;
for (j = 0; j < args[i].n_aligned_regs; j++)
{
@@ -1092,6 +982,8 @@ store_unaligned_arguments_into_pseudos (args, num_actuals)
int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD);
args[i].aligned_regs[j] = reg;
+ word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
+ word_mode, word_mode, BITS_PER_WORD);
/* There is no need to restrict this code to loading items
in TYPE_ALIGN sized hunks. The bitfield instructions can
@@ -1107,11 +999,8 @@ store_unaligned_arguments_into_pseudos (args, num_actuals)
emit_move_insn (reg, const0_rtx);
bytes -= bitsize / BITS_PER_UNIT;
- store_bit_field (reg, bitsize, big_endian_correction, word_mode,
- extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
- word_mode, word_mode,
- BITS_PER_WORD),
- BITS_PER_WORD);
+ store_bit_field (reg, bitsize, endian_correction, word_mode,
+ word, BITS_PER_WORD);
}
}
}
@@ -1135,26 +1024,22 @@ store_unaligned_arguments_into_pseudos (args, num_actuals)
and may be modified by this routine.
OLD_PENDING_ADJ, MUST_PREALLOCATE and FLAGS are pointers to integer
- flags which may may be modified by this routine. */
+ flags which may may be modified by this routine.
+
+ CALL_FROM_THUNK_P is true if this call is the jump from a thunk to
+ the thunked-to function. */
static void
-initialize_argument_information (num_actuals, args, args_size, n_named_args,
- actparms, fndecl, args_so_far,
- reg_parm_stack_space, old_stack_level,
- old_pending_adj, must_preallocate,
- ecf_flags)
- int num_actuals ATTRIBUTE_UNUSED;
- struct arg_data *args;
- struct args_size *args_size;
- int n_named_args ATTRIBUTE_UNUSED;
- tree actparms;
- tree fndecl;
- CUMULATIVE_ARGS *args_so_far;
- int reg_parm_stack_space;
- rtx *old_stack_level;
- int *old_pending_adj;
- int *must_preallocate;
- int *ecf_flags;
+initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
+ struct arg_data *args,
+ struct args_size *args_size,
+ int n_named_args ATTRIBUTE_UNUSED,
+ tree actparms, tree fndecl,
+ CUMULATIVE_ARGS *args_so_far,
+ int reg_parm_stack_space,
+ rtx *old_stack_level, int *old_pending_adj,
+ int *must_preallocate, int *ecf_flags,
+ bool call_from_thunk_p)
{
/* 1 if scanning parms front to back, -1 if scanning back to front. */
int inc;
@@ -1162,7 +1047,6 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
/* Count arg position in order args appear. */
int argpos;
- struct args_size alignment_pad;
int i;
tree p;
@@ -1218,8 +1102,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
with those made by function.c. */
/* See if this argument should be passed by invisible reference. */
- if ((TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
- && contains_placeholder_p (TYPE_SIZE (type)))
+ if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type))
|| TREE_ADDRESSABLE (type)
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
|| FUNCTION_ARG_PASS_BY_REFERENCE (*args_so_far, TYPE_MODE (type),
@@ -1229,7 +1112,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
{
/* If we're compiling a thunk, pass through invisible
references instead of making a copy. */
- if (current_function_is_thunk
+ if (call_from_thunk_p
#ifdef FUNCTION_ARG_CALLEE_COPIES
|| (FUNCTION_ARG_CALLEE_COPIES (*args_so_far, TYPE_MODE (type),
type, argpos < n_named_args)
@@ -1314,9 +1197,8 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
mode = TYPE_MODE (type);
unsignedp = TREE_UNSIGNED (type);
-#ifdef PROMOTE_FUNCTION_ARGS
- mode = promote_mode (type, mode, &unsignedp, 1);
-#endif
+ if (targetm.calls.promote_function_args (fndecl ? TREE_TYPE (fndecl) : 0))
+ mode = promote_mode (type, mode, &unsignedp, 1);
args[i].unsignedp = unsignedp;
args[i].mode = mode;
@@ -1373,39 +1255,22 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
#else
args[i].reg != 0,
#endif
- fndecl, args_size, &args[i].offset,
- &args[i].size, &alignment_pad);
-
-#ifndef ARGS_GROW_DOWNWARD
- args[i].slot_offset = *args_size;
+ args[i].pass_on_stack ? 0 : args[i].partial,
+ fndecl, args_size, &args[i].locate);
+#ifdef BLOCK_REG_PADDING
+ else
+ /* The argument is passed entirely in registers. See at which
+ end it should be padded. */
+ args[i].locate.where_pad =
+ BLOCK_REG_PADDING (mode, type,
+ int_size_in_bytes (type) <= UNITS_PER_WORD);
#endif
- args[i].alignment_pad = alignment_pad;
-
- /* If a part of the arg was put into registers,
- don't include that part in the amount pushed. */
- if (reg_parm_stack_space == 0 && ! args[i].pass_on_stack)
- args[i].size.constant -= ((args[i].partial * UNITS_PER_WORD)
- / (PARM_BOUNDARY / BITS_PER_UNIT)
- * (PARM_BOUNDARY / BITS_PER_UNIT));
-
/* Update ARGS_SIZE, the total stack space for args so far. */
- args_size->constant += args[i].size.constant;
- if (args[i].size.var)
- {
- ADD_PARM_SIZE (*args_size, args[i].size.var);
- }
-
- /* Since the slot offset points to the bottom of the slot,
- we must record it after incrementing if the args grow down. */
-#ifdef ARGS_GROW_DOWNWARD
- args[i].slot_offset = *args_size;
-
- args[i].slot_offset.constant = -args_size->constant;
- if (args_size->var)
- SUB_PARM_SIZE (args[i].slot_offset, args_size->var);
-#endif
+ args_size->constant += args[i].locate.size.constant;
+ if (args[i].locate.size.var)
+ ADD_PARM_SIZE (*args_size, args[i].locate.size.var);
/* Increment ARGS_SO_FAR, which has info about which arg-registers
have been used, etc. */
@@ -1422,11 +1287,9 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
for arguments passed in registers. */
static int
-compute_argument_block_size (reg_parm_stack_space, args_size,
- preferred_stack_boundary)
- int reg_parm_stack_space;
- struct args_size *args_size;
- int preferred_stack_boundary ATTRIBUTE_UNUSED;
+compute_argument_block_size (int reg_parm_stack_space,
+ struct args_size *args_size,
+ int preferred_stack_boundary ATTRIBUTE_UNUSED)
{
int unadjusted_args_size = args_size->constant;
@@ -1509,10 +1372,7 @@ compute_argument_block_size (reg_parm_stack_space, args_size,
precomputed argument. */
static void
-precompute_arguments (flags, num_actuals, args)
- int flags;
- int num_actuals;
- struct arg_data *args;
+precompute_arguments (int flags, int num_actuals, struct arg_data *args)
{
int i;
@@ -1580,11 +1440,7 @@ precompute_arguments (flags, num_actuals, args)
compute and return the final value for MUST_PREALLOCATE. */
static int
-finalize_must_preallocate (must_preallocate, num_actuals, args, args_size)
- int must_preallocate;
- int num_actuals;
- struct arg_data *args;
- struct args_size *args_size;
+finalize_must_preallocate (int must_preallocate, int num_actuals, struct arg_data *args, struct args_size *args_size)
{
/* See if we have or want to preallocate stack space.
@@ -1643,10 +1499,7 @@ finalize_must_preallocate (must_preallocate, num_actuals, args, args_size)
ARGBLOCK is an rtx for the address of the outgoing arguments. */
static void
-compute_argument_addresses (args, argblock, num_actuals)
- struct arg_data *args;
- rtx argblock;
- int num_actuals;
+compute_argument_addresses (struct arg_data *args, rtx argblock, int num_actuals)
{
if (argblock)
{
@@ -1658,8 +1511,8 @@ compute_argument_addresses (args, argblock, num_actuals)
for (i = 0; i < num_actuals; i++)
{
- rtx offset = ARGS_SIZE_RTX (args[i].offset);
- rtx slot_offset = ARGS_SIZE_RTX (args[i].slot_offset);
+ rtx offset = ARGS_SIZE_RTX (args[i].locate.offset);
+ rtx slot_offset = ARGS_SIZE_RTX (args[i].locate.slot_offset);
rtx addr;
/* Skip this parm if it will not be passed on the stack. */
@@ -1707,9 +1560,7 @@ compute_argument_addresses (args, argblock, num_actuals)
ADDR is the operand 0 of CALL_EXPR for this call. */
static rtx
-rtx_for_function_call (fndecl, addr)
- tree fndecl;
- tree addr;
+rtx_for_function_call (tree fndecl, tree addr)
{
rtx funexp;
@@ -1730,10 +1581,8 @@ rtx_for_function_call (fndecl, addr)
else
/* Generate an rtx (probably a pseudo-register) for the address. */
{
- rtx funaddr;
push_temp_slots ();
- funaddr = funexp
- = expand_expr (addr, NULL_RTX, VOIDmode, 0);
+ funexp = expand_expr (addr, NULL_RTX, VOIDmode, 0);
pop_temp_slots (); /* FUNEXP can't be BLKmode. */
emit_queue ();
}
@@ -1745,53 +1594,83 @@ rtx_for_function_call (fndecl, addr)
expressions were already evaluated.
Mark all register-parms as living through the call, putting these USE
- insns in the CALL_INSN_FUNCTION_USAGE field. */
+ insns in the CALL_INSN_FUNCTION_USAGE field.
+
+ When IS_SIBCALL, perform the check_sibcall_overlap_argument_overlap
+ checking, setting *SIBCALL_FAILURE if appropriate. */
static void
-load_register_parameters (args, num_actuals, call_fusage, flags)
- struct arg_data *args;
- int num_actuals;
- rtx *call_fusage;
- int flags;
+load_register_parameters (struct arg_data *args, int num_actuals,
+ rtx *call_fusage, int flags, int is_sibcall,
+ int *sibcall_failure)
{
int i, j;
-#ifdef LOAD_ARGS_REVERSED
- for (i = num_actuals - 1; i >= 0; i--)
-#else
for (i = 0; i < num_actuals; i++)
-#endif
{
rtx reg = ((flags & ECF_SIBCALL)
? args[i].tail_call_reg : args[i].reg);
- int partial = args[i].partial;
- int nregs;
-
if (reg)
{
+ int partial = args[i].partial;
+ int nregs;
+ int size = 0;
+ rtx before_arg = get_last_insn ();
/* Set to non-negative if must move a word at a time, even if just
one word (e.g, partial == 1 && mode == DFmode). Set to -1 if
we just use a normal move insn. This value can be zero if the
argument is a zero size structure with no fields. */
- nregs = (partial ? partial
- : (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode
- ? ((int_size_in_bytes (TREE_TYPE (args[i].tree_value))
- + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
- : -1));
+ nregs = -1;
+ if (partial)
+ nregs = partial;
+ else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode)
+ {
+ size = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
+ nregs = (size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+ }
+ else
+ size = GET_MODE_SIZE (args[i].mode);
/* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (reg) == PARALLEL)
- emit_group_load (reg, args[i].value,
- int_size_in_bytes (TREE_TYPE (args[i].tree_value)));
+ {
+ tree type = TREE_TYPE (args[i].tree_value);
+ emit_group_load (reg, args[i].value, type,
+ int_size_in_bytes (type));
+ }
/* If simple case, just do move. If normal partial, store_one_arg
has already loaded the register for us. In all other cases,
load the register(s) from memory. */
else if (nregs == -1)
- emit_move_insn (reg, args[i].value);
+ {
+ emit_move_insn (reg, args[i].value);
+#ifdef BLOCK_REG_PADDING
+ /* Handle case where we have a value that needs shifting
+ up to the msb. eg. a QImode value and we're padding
+ upward on a BYTES_BIG_ENDIAN machine. */
+ if (size < UNITS_PER_WORD
+ && (args[i].locate.where_pad
+ == (BYTES_BIG_ENDIAN ? upward : downward)))
+ {
+ rtx x;
+ int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
+
+ /* Assigning REG here rather than a temp makes CALL_FUSAGE
+ report the whole reg as used. Strictly speaking, the
+ call only uses SIZE bytes at the msb end, but it doesn't
+ seem worth generating rtl to say that. */
+ reg = gen_rtx_REG (word_mode, REGNO (reg));
+ x = expand_binop (word_mode, ashl_optab, reg,
+ GEN_INT (shift), reg, 1, OPTAB_WIDEN);
+ if (x != reg)
+ emit_move_insn (reg, x);
+ }
+#endif
+ }
/* If we have pre-computed the values to put in the registers in
the case of non-aligned structures, copy them in now. */
@@ -1802,9 +1681,37 @@ load_register_parameters (args, num_actuals, call_fusage, flags)
args[i].aligned_regs[j]);
else if (partial == 0 || args[i].pass_on_stack)
- move_block_to_reg (REGNO (reg),
- validize_mem (args[i].value), nregs,
- args[i].mode);
+ {
+ rtx mem = validize_mem (args[i].value);
+
+#ifdef BLOCK_REG_PADDING
+ /* Handle a BLKmode that needs shifting. */
+ if (nregs == 1 && size < UNITS_PER_WORD
+ && args[i].locate.where_pad == downward)
+ {
+ rtx tem = operand_subword_force (mem, 0, args[i].mode);
+ rtx ri = gen_rtx_REG (word_mode, REGNO (reg));
+ rtx x = gen_reg_rtx (word_mode);
+ int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
+ optab dir = BYTES_BIG_ENDIAN ? lshr_optab : ashl_optab;
+
+ emit_move_insn (x, tem);
+ x = expand_binop (word_mode, dir, x, GEN_INT (shift),
+ ri, 1, OPTAB_WIDEN);
+ if (x != ri)
+ emit_move_insn (ri, x);
+ }
+ else
+#endif
+ move_block_to_reg (REGNO (reg), mem, nregs, args[i].mode);
+ }
+
+ /* When a parameter is a block, and perhaps in other cases, it is
+ possible that it did a load from an argument slot that was
+ already clobbered. */
+ if (is_sibcall
+ && check_sibcall_argument_overlap (before_arg, &args[i], 0))
+ *sibcall_failure = 1;
/* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */
@@ -1822,13 +1729,8 @@ load_register_parameters (args, num_actuals, call_fusage, flags)
about the parameters. */
static rtx
-try_to_integrate (fndecl, actparms, target, ignore, type, structure_value_addr)
- tree fndecl;
- tree actparms;
- rtx target;
- int ignore;
- tree type;
- rtx structure_value_addr;
+try_to_integrate (tree fndecl, tree actparms, rtx target, int ignore,
+ tree type, rtx structure_value_addr)
{
rtx temp;
rtx before_call;
@@ -1863,9 +1765,11 @@ try_to_integrate (fndecl, actparms, target, ignore, type, structure_value_addr)
the stack before executing the inlined function if it
makes any calls. */
- for (i = reg_parm_stack_space - 1; i >= 0; i--)
- if (i < highest_outgoing_arg_in_use && stack_usage_map[i] != 0)
- break;
+ i = reg_parm_stack_space;
+ if (i > highest_outgoing_arg_in_use)
+ i = highest_outgoing_arg_in_use;
+ while (--i >= 0 && stack_usage_map[i] == 0)
+ ;
if (stack_arg_under_construction || i >= 0)
{
@@ -1931,7 +1835,7 @@ try_to_integrate (fndecl, actparms, target, ignore, type, structure_value_addr)
if (DECL_INLINE (fndecl) && warn_inline && !flag_no_inline
&& optimize > 0 && !TREE_ADDRESSABLE (fndecl))
{
- warning_with_decl (fndecl, "inlining failed in call to `%s'");
+ warning ("%Jinlining failed in call to '%F'", fndecl, fndecl);
warning ("called from here");
}
(*lang_hooks.mark_addressable) (fndecl);
@@ -1948,12 +1852,9 @@ try_to_integrate (fndecl, actparms, target, ignore, type, structure_value_addr)
be popped after the call. Returns the adjustment. */
static int
-combine_pending_stack_adjustment_and_call (unadjusted_args_size,
- args_size,
- preferred_unit_stack_boundary)
- int unadjusted_args_size;
- struct args_size *args_size;
- int preferred_unit_stack_boundary;
+combine_pending_stack_adjustment_and_call (int unadjusted_args_size,
+ struct args_size *args_size,
+ int preferred_unit_stack_boundary)
{
/* The number of bytes to pop so that the stack will be
under-aligned by UNADJUSTED_ARGS_SIZE bytes. */
@@ -2004,8 +1905,7 @@ combine_pending_stack_adjustment_and_call (unadjusted_args_size,
zero otherwise. */
static int
-check_sibcall_argument_overlap_1 (x)
- rtx x;
+check_sibcall_argument_overlap_1 (rtx x)
{
RTX_CODE code;
int i, j;
@@ -2062,14 +1962,13 @@ check_sibcall_argument_overlap_1 (x)
/* Scan sequence after INSN if it does not dereference any argument slots
we already clobbered by tail call arguments (as noted in stored_args_map
- bitmap). Add stack slots for ARG to stored_args_map bitmap afterwards.
- Return nonzero if sequence after INSN dereferences such argument slots,
- zero otherwise. */
+ bitmap). If MARK_STORED_ARGS_MAP, add stack slots for ARG to
+ stored_args_map bitmap afterwards (when ARG is a register MARK_STORED_ARGS_MAP
+ should be 0). Return nonzero if sequence after INSN dereferences such argument
+ slots, zero otherwise. */
static int
-check_sibcall_argument_overlap (insn, arg)
- rtx insn;
- struct arg_data *arg;
+check_sibcall_argument_overlap (rtx insn, struct arg_data *arg, int mark_stored_args_map)
{
int low, high;
@@ -2083,20 +1982,22 @@ check_sibcall_argument_overlap (insn, arg)
&& check_sibcall_argument_overlap_1 (PATTERN (insn)))
break;
+ if (mark_stored_args_map)
+ {
#ifdef ARGS_GROW_DOWNWARD
- low = -arg->slot_offset.constant - arg->size.constant;
+ low = -arg->locate.slot_offset.constant - arg->locate.size.constant;
#else
- low = arg->slot_offset.constant;
+ low = arg->locate.slot_offset.constant;
#endif
- for (high = low + arg->size.constant; low < high; low++)
- SET_BIT (stored_args_map, low);
+ for (high = low + arg->locate.size.constant; low < high; low++)
+ SET_BIT (stored_args_map, low);
+ }
return insn != NULL_RTX;
}
static tree
-fix_unsafe_tree (t)
- tree t;
+fix_unsafe_tree (tree t)
{
switch (unsafe_for_reeval (t))
{
@@ -2123,6 +2024,34 @@ fix_unsafe_tree (t)
return t;
}
+
+/* If function value *VALUE was returned at the most significant end of a
+ register, shift it towards the least significant end and convert it to
+ TYPE's mode. Return true and update *VALUE if some action was needed.
+
+ TYPE is the type of the function's return value, which is known not
+ to have mode BLKmode. */
+
+static bool
+shift_returned_value (tree type, rtx *value)
+{
+ if (targetm.calls.return_in_msb (type))
+ {
+ HOST_WIDE_INT shift;
+
+ shift = (GET_MODE_BITSIZE (GET_MODE (*value))
+ - BITS_PER_UNIT * int_size_in_bytes (type));
+ if (shift > 0)
+ {
+ *value = expand_binop (GET_MODE (*value), lshr_optab, *value,
+ GEN_INT (shift), 0, 1, OPTAB_WIDEN);
+ *value = convert_to_mode (TYPE_MODE (type), *value, 0);
+ return true;
+ }
+ }
+ return false;
+}
+
/* Generate all the code for a function call
and return an rtx for its value.
Store the value in TARGET (specified as an rtx) if convenient.
@@ -2130,10 +2059,7 @@ fix_unsafe_tree (t)
If IGNORE is nonzero, then we ignore the value of the function call. */
rtx
-expand_call (exp, target, ignore)
- tree exp;
- rtx target;
- int ignore;
+expand_call (tree exp, rtx target, int ignore)
{
/* Nonzero if we are currently expanding a call. */
static int currently_expanding_call = 0;
@@ -2150,9 +2076,12 @@ expand_call (exp, target, ignore)
rtx tail_call_insns = NULL_RTX;
/* Data type of the function. */
tree funtype;
+ tree type_arg_types;
/* Declaration of the function being called,
or 0 if the function is computed (not known by name). */
tree fndecl = 0;
+ /* The type of the function being called. */
+ tree fntype;
rtx insn;
int try_tail_call = 1;
int try_tail_recursion = 1;
@@ -2175,6 +2104,7 @@ expand_call (exp, target, ignore)
/* Nonzero if called function returns an aggregate in memory PCC style,
by returning the address of where to find it. */
int pcc_struct_value = 0;
+ rtx struct_value = 0;
/* Number of actual parameters in this call, including struct value addr. */
int num_actuals;
@@ -2219,19 +2149,28 @@ expand_call (exp, target, ignore)
int is_integrable = 0;
#ifdef REG_PARM_STACK_SPACE
/* Define the boundary of the register parm stack space that needs to be
- save, if any. */
- int low_to_save = -1, high_to_save;
+ saved, if any. */
+ int low_to_save, high_to_save;
rtx save_area = 0; /* Place that it is saved */
#endif
int initial_highest_arg_in_use = highest_outgoing_arg_in_use;
+ rtx temp_target = 0;
char *initial_stack_usage_map = stack_usage_map;
- int old_stack_arg_under_construction = 0;
+ int old_stack_allocated;
+
+ /* State variables to track stack modifications. */
rtx old_stack_level = 0;
+ int old_stack_arg_under_construction = 0;
int old_pending_adj = 0;
int old_inhibit_defer_pop = inhibit_defer_pop;
- int old_stack_allocated;
+
+ /* Some stack pointer alterations we make are performed via
+ allocate_dynamic_stack_space. This modifies the stack_pointer_delta,
+ which we then also need to save/restore along the way. */
+ int old_stack_pointer_delta = 0;
+
rtx call_fusage;
tree p = TREE_OPERAND (exp, 0);
tree addr = TREE_OPERAND (exp, 0);
@@ -2251,6 +2190,7 @@ expand_call (exp, target, ignore)
fndecl = get_callee_fndecl (exp);
if (fndecl)
{
+ fntype = TREE_TYPE (fndecl);
if (!flag_no_inline
&& fndecl != current_function_decl
&& DECL_INLINE (fndecl)
@@ -2267,19 +2207,65 @@ expand_call (exp, target, ignore)
if (DECL_INLINE (fndecl) && warn_inline && !flag_no_inline
&& optimize > 0)
{
- warning_with_decl (fndecl, "can't inline call to `%s'");
+ warning ("%Jcan't inline call to '%F'", fndecl, fndecl);
warning ("called from here");
}
(*lang_hooks.mark_addressable) (fndecl);
}
+ if (ignore
+ && lookup_attribute ("warn_unused_result",
+ TYPE_ATTRIBUTES (TREE_TYPE (fndecl))))
+ warning ("ignoring return value of `%D', "
+ "declared with attribute warn_unused_result", fndecl);
+
flags |= flags_from_decl_or_type (fndecl);
}
/* If we don't have specific function to call, see if we have a
attributes set in the type. */
else
- flags |= flags_from_decl_or_type (TREE_TYPE (TREE_TYPE (p)));
+ {
+ fntype = TREE_TYPE (TREE_TYPE (p));
+ if (ignore
+ && lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (fntype)))
+ warning ("ignoring return value of function "
+ "declared with attribute warn_unused_result");
+ flags |= flags_from_decl_or_type (fntype);
+ }
+
+ struct_value = targetm.calls.struct_value_rtx (fntype, 0);
+
+ /* Warn if this value is an aggregate type,
+ regardless of which calling convention we are using for it. */
+ if (warn_aggregate_return && AGGREGATE_TYPE_P (TREE_TYPE (exp)))
+ warning ("function call has aggregate value");
+
+ /* If the result of a pure or const function call is ignored (or void),
+ and none of its arguments are volatile, we can avoid expanding the
+ call and just evaluate the arguments for side-effects. */
+ if ((flags & (ECF_CONST | ECF_PURE))
+ && (ignore || target == const0_rtx
+ || TYPE_MODE (TREE_TYPE (exp)) == VOIDmode))
+ {
+ bool volatilep = false;
+ tree arg;
+
+ for (arg = actparms; arg; arg = TREE_CHAIN (arg))
+ if (TREE_THIS_VOLATILE (TREE_VALUE (arg)))
+ {
+ volatilep = true;
+ break;
+ }
+
+ if (! volatilep)
+ {
+ for (arg = actparms; arg; arg = TREE_CHAIN (arg))
+ expand_expr (TREE_VALUE (arg), const0_rtx,
+ VOIDmode, EXPAND_NORMAL);
+ return const0_rtx;
+ }
+ }
#ifdef REG_PARM_STACK_SPACE
#ifdef MAYBE_REG_PARM_STACK_SPACE
@@ -2294,15 +2280,10 @@ expand_call (exp, target, ignore)
must_preallocate = 1;
#endif
- /* Warn if this value is an aggregate type,
- regardless of which calling convention we are using for it. */
- if (warn_aggregate_return && AGGREGATE_TYPE_P (TREE_TYPE (exp)))
- warning ("function call has aggregate value");
-
/* Set up a place to return a structure. */
/* Cater to broken compilers. */
- if (aggregate_value_p (exp))
+ if (aggregate_value_p (exp, fndecl))
{
/* This call returns a big structure. */
flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
@@ -2324,7 +2305,17 @@ expand_call (exp, target, ignore)
{
struct_value_size = int_size_in_bytes (TREE_TYPE (exp));
- if (target && GET_CODE (target) == MEM)
+ if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (exp))
+ {
+ /* The structure value address arg is already in actparms.
+ Pull it out. It might be nice to just leave it there, but
+ we need to set structure_value_addr. */
+ tree return_arg = TREE_VALUE (actparms);
+ actparms = TREE_CHAIN (actparms);
+ structure_value_addr = expand_expr (return_arg, NULL_RTX,
+ VOIDmode, EXPAND_NORMAL);
+ }
+ else if (target && GET_CODE (target) == MEM)
structure_value_addr = XEXP (target, 0);
else
{
@@ -2354,6 +2345,12 @@ expand_call (exp, target, ignore)
/* Figure out the amount to which the stack should be aligned. */
preferred_stack_boundary = PREFERRED_STACK_BOUNDARY;
+ if (fndecl)
+ {
+ struct cgraph_rtl_info *i = cgraph_rtl_info (fndecl);
+ if (i && i->preferred_incoming_stack_boundary)
+ preferred_stack_boundary = i->preferred_incoming_stack_boundary;
+ }
/* Operand 0 is a pointer-to-function; get the type of the function. */
funtype = TREE_TYPE (addr);
@@ -2361,6 +2358,16 @@ expand_call (exp, target, ignore)
abort ();
funtype = TREE_TYPE (funtype);
+ /* Munge the tree to split complex arguments into their imaginary
+ and real parts. */
+ if (targetm.calls.split_complex_arg)
+ {
+ type_arg_types = split_complex_types (TYPE_ARG_TYPES (funtype));
+ actparms = split_complex_values (actparms);
+ }
+ else
+ type_arg_types = TYPE_ARG_TYPES (funtype);
+
/* See if this is a call to a function that can return more than once
or a call to longjmp or malloc. */
flags |= special_function_p (fndecl, flags);
@@ -2370,7 +2377,7 @@ expand_call (exp, target, ignore)
/* If struct_value_rtx is 0, it means pass the address
as if it were an extra parameter. */
- if (structure_value_addr && struct_value_rtx == 0)
+ if (structure_value_addr && struct_value == 0)
{
/* If structure_value_addr is a REG other than
virtual_outgoing_args_rtx, we can use always use it. If it
@@ -2381,7 +2388,8 @@ expand_call (exp, target, ignore)
|| (ACCUMULATE_OUTGOING_ARGS
&& stack_arg_under_construction
&& structure_value_addr == virtual_outgoing_args_rtx)
- ? copy_addr_to_reg (structure_value_addr)
+ ? copy_addr_to_reg (convert_memory_address
+ (Pmode, structure_value_addr))
: structure_value_addr);
actparms
@@ -2397,28 +2405,11 @@ expand_call (exp, target, ignore)
num_actuals++;
/* Compute number of named args.
- Normally, don't include the last named arg if anonymous args follow.
- We do include the last named arg if STRICT_ARGUMENT_NAMING is nonzero.
- (If no anonymous args follow, the result of list_length is actually
- one too large. This is harmless.)
-
- If PRETEND_OUTGOING_VARARGS_NAMED is set and STRICT_ARGUMENT_NAMING is
- zero, this machine will be able to place unnamed args that were
- passed in registers into the stack. So treat all args as named.
- This allows the insns emitting for a specific argument list to be
- independent of the function declaration.
-
- If PRETEND_OUTGOING_VARARGS_NAMED is not set, we do not have any
- reliable way to pass unnamed args in registers, so we must force
- them into memory. */
+ First, do a raw count of the args for INIT_CUMULATIVE_ARGS. */
- if ((STRICT_ARGUMENT_NAMING
- || ! PRETEND_OUTGOING_VARARGS_NAMED)
- && TYPE_ARG_TYPES (funtype) != 0)
+ if (type_arg_types != 0)
n_named_args
- = (list_length (TYPE_ARG_TYPES (funtype))
- /* Don't include the last named arg. */
- - (STRICT_ARGUMENT_NAMING ? 0 : 1)
+ = (list_length (type_arg_types)
/* Count the struct value address, if it is passed as a parm. */
+ structure_value_addr_parm);
else
@@ -2428,14 +2419,43 @@ expand_call (exp, target, ignore)
/* Start updating where the next arg would go.
On some machines (such as the PA) indirect calls have a different
- calling convention than normal calls. The last argument in
+ calling convention than normal calls. The fourth argument in
INIT_CUMULATIVE_ARGS tells the backend if this is an indirect call
or not. */
- INIT_CUMULATIVE_ARGS (args_so_far, funtype, NULL_RTX, (fndecl == 0));
+ INIT_CUMULATIVE_ARGS (args_so_far, funtype, NULL_RTX, fndecl, n_named_args);
+
+ /* Now possibly adjust the number of named args.
+ Normally, don't include the last named arg if anonymous args follow.
+ We do include the last named arg if
+ targetm.calls.strict_argument_naming() returns nonzero.
+ (If no anonymous args follow, the result of list_length is actually
+ one too large. This is harmless.)
+
+ If targetm.calls.pretend_outgoing_varargs_named() returns
+ nonzero, and targetm.calls.strict_argument_naming() returns zero,
+ this machine will be able to place unnamed args that were passed
+ in registers into the stack. So treat all args as named. This
+ allows the insns emitting for a specific argument list to be
+ independent of the function declaration.
+
+ If targetm.calls.pretend_outgoing_varargs_named() returns zero,
+ we do not have any reliable way to pass unnamed args in
+ registers, so we must force them into memory. */
+
+ if (type_arg_types != 0
+ && targetm.calls.strict_argument_naming (&args_so_far))
+ ;
+ else if (type_arg_types != 0
+ && ! targetm.calls.pretend_outgoing_varargs_named (&args_so_far))
+ /* Don't include the last named arg. */
+ --n_named_args;
+ else
+ /* Treat all args as named. */
+ n_named_args = num_actuals;
/* Make a vector to hold all the information about each arg. */
- args = (struct arg_data *) alloca (num_actuals * sizeof (struct arg_data));
- memset ((char *) args, 0, num_actuals * sizeof (struct arg_data));
+ args = alloca (num_actuals * sizeof (struct arg_data));
+ memset (args, 0, num_actuals * sizeof (struct arg_data));
/* Build up entries in the ARGS array, compute the size of the
arguments into ARGS_SIZE, etc. */
@@ -2443,7 +2463,8 @@ expand_call (exp, target, ignore)
n_named_args, actparms, fndecl,
&args_so_far, reg_parm_stack_space,
&old_stack_level, &old_pending_adj,
- &must_preallocate, &flags);
+ &must_preallocate, &flags,
+ CALL_FROM_THUNK_P (exp));
if (args_size.var)
{
@@ -2482,12 +2503,16 @@ expand_call (exp, target, ignore)
finished with regular parsing. Which means that some of the
machinery we use to generate tail-calls is no longer in place.
This is most often true of sjlj-exceptions, which we couldn't
- tail-call to anyway. */
+ tail-call to anyway.
+ If current_nesting_level () == 0, we're being called after
+ the function body has been expanded. This can happen when
+ setting up trampolines in expand_function_end. */
if (currently_expanding_call++ != 0
|| !flag_optimize_sibling_calls
|| !rtx_equal_function_value_matters
- || any_pending_cleanups (1)
+ || current_nesting_level () == 0
+ || any_pending_cleanups ()
|| args_size.var)
try_tail_call = try_tail_recursion = 0;
@@ -2510,16 +2535,17 @@ expand_call (exp, target, ignore)
It does not seem worth the effort since few optimizable
sibling calls will return a structure. */
|| structure_value_addr != NULL_RTX
- /* If the register holding the address is a callee saved
- register, then we lose. We have no way to prevent that,
- so we only allow calls to named functions. */
- /* ??? This could be done by having the insn constraints
- use a register class that is all call-clobbered. Any
- reload insns generated to fix things up would appear
- before the sibcall_epilogue. */
- || fndecl == NULL_TREE
+ /* Check whether the target is able to optimize the call
+ into a sibcall. */
+ || !(*targetm.function_ok_for_sibcall) (fndecl, exp)
+ /* Functions that do not return exactly once may not be sibcall
+ optimized. */
|| (flags & (ECF_RETURNS_TWICE | ECF_LONGJMP | ECF_NORETURN))
- || !FUNCTION_OK_FOR_SIBCALL (fndecl)
+ || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr)))
+ /* If the called function is nested in the current one, it might access
+ some of the caller's arguments, but could clobber them beforehand if
+ the argument areas are shared. */
+ || (fndecl && decl_function_context (fndecl) == current_function_decl)
/* If this function requires more stack slots than the current
function, we cannot change it into a sibling call. */
|| args_size.constant > current_function_args_size
@@ -2573,12 +2599,12 @@ expand_call (exp, target, ignore)
if (try_tail_recursion)
actparms = tree_cons (NULL_TREE, args[i].tree_value, actparms);
}
- /* Do the same for the function address if it is an expression. */
+ /* Do the same for the function address if it is an expression. */
if (!fndecl)
addr = fix_unsafe_tree (addr);
/* Expanding one of those dangerous arguments could have added
cleanups, but otherwise give it a whirl. */
- if (any_pending_cleanups (1))
+ if (any_pending_cleanups ())
try_tail_call = try_tail_recursion = 0;
}
@@ -2610,7 +2636,7 @@ expand_call (exp, target, ignore)
expand_start_target_temps ();
if (optimize_tail_recursion (actparms, get_last_insn ()))
{
- if (any_pending_cleanups (1))
+ if (any_pending_cleanups ())
try_tail_call = try_tail_recursion = 0;
else
tail_recursion_insns = get_insns ();
@@ -2633,9 +2659,7 @@ expand_call (exp, target, ignore)
is subject to race conditions, just as with multithreaded
programs. */
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__bb_fork_func"),
- LCT_ALWAYS_RETURN,
- VOIDmode, 0);
+ emit_library_call (gcov_flush_libfunc, LCT_ALWAYS_RETURN, VOIDmode, 0);
}
/* Ensure current function's preferred stack boundary is at least
@@ -2644,6 +2668,8 @@ expand_call (exp, target, ignore)
if (cfun->preferred_stack_boundary < preferred_stack_boundary
&& fndecl != current_function_decl)
cfun->preferred_stack_boundary = preferred_stack_boundary;
+ if (fndecl == current_function_decl)
+ cfun->recursive_call_emit = true;
preferred_unit_stack_boundary = preferred_stack_boundary / BITS_PER_UNIT;
@@ -2652,7 +2678,7 @@ expand_call (exp, target, ignore)
/* We want to make two insn chains; one for a sibling call, the other
for a normal call. We will select one of the two chains after
initial RTL generation is complete. */
- for (pass = 0; pass < 2; pass++)
+ for (pass = try_tail_call ? 0 : 1; pass < 2; pass++)
{
int sibcall_failure = 0;
/* We want to emit any pending stack adjustments before the tail
@@ -2666,9 +2692,6 @@ expand_call (exp, target, ignore)
if (pass == 0)
{
- if (! try_tail_call)
- continue;
-
/* Emit any queued insns now; otherwise they would end up in
only one of the alternates. */
emit_queue ();
@@ -2768,6 +2791,7 @@ expand_call (exp, target, ignore)
if (old_stack_level == 0)
{
emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
+ old_stack_pointer_delta = stack_pointer_delta;
old_pending_adj = pending_stack_adjust;
pending_stack_adjust = 0;
/* stack_arg_under_construction says whether a stack arg is
@@ -2826,8 +2850,7 @@ expand_call (exp, target, ignore)
highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
needed);
#endif
- stack_usage_map
- = (char *) alloca (highest_outgoing_arg_in_use);
+ stack_usage_map = alloca (highest_outgoing_arg_in_use);
if (initial_highest_arg_in_use)
memcpy (stack_usage_map, initial_stack_usage_map,
@@ -2884,7 +2907,12 @@ expand_call (exp, target, ignore)
if (needed == 0)
argblock = virtual_outgoing_args_rtx;
else
- argblock = push_block (GEN_INT (needed), 0, 0);
+ {
+ argblock = push_block (GEN_INT (needed), 0, 0);
+#ifdef ARGS_GROW_DOWNWARD
+ argblock = plus_constant (argblock, needed);
+#endif
+ }
/* We only really need to call `copy_to_reg' in the case
where push insns are going to be used to pass ARGBLOCK
@@ -2894,51 +2922,55 @@ expand_call (exp, target, ignore)
VIRTUAL_OUTGOING_ARGS_RTX changes as well. But might
as well always do it. */
argblock = copy_to_reg (argblock);
+ }
+ }
+ }
- /* The save/restore code in store_one_arg handles all
- cases except one: a constructor call (including a C
- function returning a BLKmode struct) to initialize
- an argument. */
- if (stack_arg_under_construction)
- {
+ if (ACCUMULATE_OUTGOING_ARGS)
+ {
+ /* The save/restore code in store_one_arg handles all
+ cases except one: a constructor call (including a C
+ function returning a BLKmode struct) to initialize
+ an argument. */
+ if (stack_arg_under_construction)
+ {
#ifndef OUTGOING_REG_PARM_STACK_SPACE
- rtx push_size = GEN_INT (reg_parm_stack_space
- + adjusted_args_size.constant);
+ rtx push_size = GEN_INT (reg_parm_stack_space
+ + adjusted_args_size.constant);
#else
- rtx push_size = GEN_INT (adjusted_args_size.constant);
+ rtx push_size = GEN_INT (adjusted_args_size.constant);
#endif
- if (old_stack_level == 0)
- {
- emit_stack_save (SAVE_BLOCK, &old_stack_level,
- NULL_RTX);
- old_pending_adj = pending_stack_adjust;
- pending_stack_adjust = 0;
- /* stack_arg_under_construction says whether a stack
- arg is being constructed at the old stack level.
- Pushing the stack gets a clean outgoing argument
- block. */
- old_stack_arg_under_construction
- = stack_arg_under_construction;
- stack_arg_under_construction = 0;
- /* Make a new map for the new argument list. */
- stack_usage_map = (char *)
- alloca (highest_outgoing_arg_in_use);
- memset (stack_usage_map, 0, highest_outgoing_arg_in_use);
- highest_outgoing_arg_in_use = 0;
- }
- allocate_dynamic_stack_space (push_size, NULL_RTX,
- BITS_PER_UNIT);
- }
- /* If argument evaluation might modify the stack pointer,
- copy the address of the argument list to a register. */
- for (i = 0; i < num_actuals; i++)
- if (args[i].pass_on_stack)
- {
- argblock = copy_addr_to_reg (argblock);
- break;
- }
+ if (old_stack_level == 0)
+ {
+ emit_stack_save (SAVE_BLOCK, &old_stack_level,
+ NULL_RTX);
+ old_stack_pointer_delta = stack_pointer_delta;
+ old_pending_adj = pending_stack_adjust;
+ pending_stack_adjust = 0;
+ /* stack_arg_under_construction says whether a stack
+ arg is being constructed at the old stack level.
+ Pushing the stack gets a clean outgoing argument
+ block. */
+ old_stack_arg_under_construction
+ = stack_arg_under_construction;
+ stack_arg_under_construction = 0;
+ /* Make a new map for the new argument list. */
+ stack_usage_map = alloca (highest_outgoing_arg_in_use);
+ memset (stack_usage_map, 0, highest_outgoing_arg_in_use);
+ highest_outgoing_arg_in_use = 0;
}
+ allocate_dynamic_stack_space (push_size, NULL_RTX,
+ BITS_PER_UNIT);
}
+
+ /* If argument evaluation might modify the stack pointer,
+ copy the address of the argument list to a register. */
+ for (i = 0; i < num_actuals; i++)
+ if (args[i].pass_on_stack)
+ {
+ argblock = copy_addr_to_reg (argblock);
+ break;
+ }
}
compute_argument_addresses (args, argblock, num_actuals);
@@ -3011,8 +3043,16 @@ expand_call (exp, target, ignore)
reg_parm_stack_space)
|| (pass == 0
&& check_sibcall_argument_overlap (before_arg,
- &args[i])))
+ &args[i], 1)))
sibcall_failure = 1;
+
+ if (flags & ECF_CONST
+ && args[i].stack
+ && args[i].value == args[i].stack)
+ call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_USE (VOIDmode,
+ args[i].value),
+ call_fusage);
}
/* If we have a parm that is passed in registers but not in memory
@@ -3035,7 +3075,7 @@ expand_call (exp, target, ignore)
reg_parm_stack_space)
|| (pass == 0
&& check_sibcall_argument_overlap (before_arg,
- &args[i])))
+ &args[i], 1)))
sibcall_failure = 1;
}
@@ -3058,19 +3098,22 @@ expand_call (exp, target, ignore)
structure value. */
if (pass != 0 && structure_value_addr && ! structure_value_addr_parm)
{
- emit_move_insn (struct_value_rtx,
+ structure_value_addr
+ = convert_memory_address (Pmode, structure_value_addr);
+ emit_move_insn (struct_value,
force_reg (Pmode,
force_operand (structure_value_addr,
NULL_RTX)));
- if (GET_CODE (struct_value_rtx) == REG)
- use_reg (&call_fusage, struct_value_rtx);
+ if (GET_CODE (struct_value) == REG)
+ use_reg (&call_fusage, struct_value);
}
funexp = prepare_call_address (funexp, fndecl, &call_fusage,
reg_parm_seen, pass == 0);
- load_register_parameters (args, num_actuals, &call_fusage, flags);
+ load_register_parameters (args, num_actuals, &call_fusage, flags,
+ pass == 0, &sibcall_failure);
/* Perform postincrements before actually calling the function. */
emit_queue ();
@@ -3103,12 +3146,6 @@ expand_call (exp, target, ignore)
next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
flags, & args_so_far);
- /* Verify that we've deallocated all the stack we used. */
- if (pass
- && ! (flags & (ECF_NORETURN | ECF_LONGJMP))
- && old_stack_allocated != stack_pointer_delta - pending_stack_adjust)
- abort ();
-
/* If call is cse'able, make appropriate pair of reg-notes around it.
Test valreg so we don't crash; may safely ignore `const'
if return type is void. Disable for PARALLEL return values, because
@@ -3116,10 +3153,19 @@ expand_call (exp, target, ignore)
if (pass && (flags & ECF_LIBCALL_BLOCK))
{
rtx insns;
+ rtx insn;
+ bool failed = valreg == 0 || GET_CODE (valreg) == PARALLEL;
- if (valreg == 0 || GET_CODE (valreg) == PARALLEL)
+ insns = get_insns ();
+
+ /* Expansion of block moves possibly introduced a loop that may
+ not appear inside libcall block. */
+ for (insn = insns; insn; insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == JUMP_INSN)
+ failed = true;
+
+ if (failed)
{
- insns = get_insns ();
end_sequence ();
emit_insn (insns);
}
@@ -3133,23 +3179,33 @@ expand_call (exp, target, ignore)
mark_reg_pointer (temp,
TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))));
- /* Construct an "equal form" for the value which mentions all the
- arguments in order as well as the function name. */
- for (i = 0; i < num_actuals; i++)
- note = gen_rtx_EXPR_LIST (VOIDmode,
- args[i].initial_value, note);
- note = gen_rtx_EXPR_LIST (VOIDmode, funexp, note);
-
- insns = get_insns ();
end_sequence ();
-
- if (flags & ECF_PURE)
- note = gen_rtx_EXPR_LIST (VOIDmode,
+ if (flag_unsafe_math_optimizations
+ && fndecl
+ && DECL_BUILT_IN (fndecl)
+ && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SQRT
+ || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SQRTF
+ || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SQRTL))
+ note = gen_rtx_fmt_e (SQRT,
+ GET_MODE (temp),
+ args[0].initial_value);
+ else
+ {
+ /* Construct an "equal form" for the value which
+ mentions all the arguments in order as well as
+ the function name. */
+ for (i = 0; i < num_actuals; i++)
+ note = gen_rtx_EXPR_LIST (VOIDmode,
+ args[i].initial_value, note);
+ note = gen_rtx_EXPR_LIST (VOIDmode, funexp, note);
+
+ if (flags & ECF_PURE)
+ note = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_USE (VOIDmode,
gen_rtx_MEM (BLKmode,
gen_rtx_SCRATCH (VOIDmode))),
note);
-
+ }
emit_libcall_block (insns, temp, valreg, note);
valreg = temp;
@@ -3200,27 +3256,24 @@ expand_call (exp, target, ignore)
emit_barrier_after (last);
- /* Stack adjustments after a noreturn call are dead code. */
- stack_pointer_delta = old_stack_allocated;
- pending_stack_adjust = 0;
+ /* Stack adjustments after a noreturn call are dead code.
+ However when NO_DEFER_POP is in effect, we must preserve
+ stack_pointer_delta. */
+ if (inhibit_defer_pop == 0)
+ {
+ stack_pointer_delta = old_stack_allocated;
+ pending_stack_adjust = 0;
+ }
}
if (flags & ECF_LONGJMP)
current_function_calls_longjmp = 1;
- /* If this function is returning into a memory location marked as
- readonly, it means it is initializing that location. But we normally
- treat functions as not clobbering such locations, so we need to
- specify that this one does. */
- if (target != 0 && GET_CODE (target) == MEM
- && structure_value_addr != 0 && RTX_UNCHANGING_P (target))
- emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
-
/* If value type not void, return an rtx for the value. */
/* If there are cleanups to be called, don't use a hard reg as target.
We need to double check this and see if it matters anymore. */
- if (any_pending_cleanups (1))
+ if (any_pending_cleanups ())
{
if (target && REG_P (target)
&& REGNO (target) < FIRST_PSEUDO_REGISTER)
@@ -3255,7 +3308,11 @@ expand_call (exp, target, ignore)
The Irix 6 ABI has examples of this. */
else if (GET_CODE (valreg) == PARALLEL)
{
- if (target == 0)
+ /* Second condition is added because "target" is freed at the
+ the end of "pass0" for -O2 when call is made to
+ expand_end_target_temps (). Its "in_use" flag has been set
+ to false, so allocate a new temp. */
+ if (target == 0 || (pass == 1 && target == temp_target))
{
/* This will only be assigned once, so it can be readonly. */
tree nt = build_qualified_type (TREE_TYPE (exp),
@@ -3263,11 +3320,12 @@ expand_call (exp, target, ignore)
| TYPE_QUAL_CONST));
target = assign_temp (nt, 0, 1, 1);
+ temp_target = target;
preserve_temp_slots (target);
}
if (! rtx_equal_p (target, valreg))
- emit_group_store (target, valreg,
+ emit_group_store (target, valreg, TREE_TYPE (exp),
int_size_in_bytes (TREE_TYPE (exp)));
/* We can not support sibling calls for this case. */
@@ -3284,6 +3342,12 @@ expand_call (exp, target, ignore)
If they refer to the same register, this move will be a no-op,
except when function inlining is being done. */
emit_move_insn (target, valreg);
+
+ /* If we are setting a MEM, this code must be executed. Since it is
+ emitted after the call insn, sibcall optimization cannot be
+ performed in that case. */
+ if (GET_CODE (target) == MEM)
+ sibcall_failure = 1;
}
else if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
{
@@ -3293,9 +3357,15 @@ expand_call (exp, target, ignore)
sibcall_failure = 1;
}
else
- target = copy_to_reg (valreg);
+ {
+ if (shift_returned_value (TREE_TYPE (exp), &valreg))
+ sibcall_failure = 1;
-#ifdef PROMOTE_FUNCTION_RETURN
+ target = copy_to_reg (valreg);
+ }
+
+ if (targetm.calls.promote_function_return(funtype))
+ {
/* If we promoted this return value, make the proper SUBREG. TARGET
might be const0_rtx here, so be careful. */
if (GET_CODE (target) == REG
@@ -3326,7 +3396,7 @@ expand_call (exp, target, ignore)
SUBREG_PROMOTED_VAR_P (target) = 1;
SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp);
}
-#endif
+ }
/* If size of args is variable or this was a constructor call for a stack
argument, restore saved stack-pointer value. */
@@ -3334,6 +3404,7 @@ expand_call (exp, target, ignore)
if (old_stack_level && ! (flags & ECF_SP_DEPRESSED))
{
emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
+ stack_pointer_delta = old_stack_pointer_delta;
pending_stack_adjust = old_pending_adj;
stack_arg_under_construction = old_stack_arg_under_construction;
highest_outgoing_arg_in_use = initial_highest_arg_in_use;
@@ -3344,10 +3415,8 @@ expand_call (exp, target, ignore)
{
#ifdef REG_PARM_STACK_SPACE
if (save_area)
- {
- restore_fixed_argument_area (save_area, argblock,
- high_to_save, low_to_save);
- }
+ restore_fixed_argument_area (save_area, argblock,
+ high_to_save, low_to_save);
#endif
/* If we saved any argument areas, restore them. */
@@ -3364,7 +3433,7 @@ expand_call (exp, target, ignore)
emit_move_insn (stack_area, args[i].save_area);
else
emit_block_move (stack_area, args[i].save_area,
- GEN_INT (args[i].size.constant),
+ GEN_INT (args[i].locate.size.constant),
BLOCK_OP_CALL_PARM);
}
@@ -3392,6 +3461,22 @@ expand_call (exp, target, ignore)
expand_end_target_temps ();
}
+ /* If this function is returning into a memory location marked as
+ readonly, it means it is initializing that location. We normally treat
+ functions as not clobbering such locations, so we need to specify that
+ this one does. We do this by adding the appropriate CLOBBER to the
+ CALL_INSN function usage list. This cannot be done by emitting a
+ standalone CLOBBER after the call because the latter would be ignored
+ by at least the delay slot scheduling pass. We do this now instead of
+ adding to call_fusage before the call to emit_call_1 because TARGET
+ may be modified in the meantime. */
+ if (structure_value_addr != 0 && target != 0
+ && GET_CODE (target) == MEM && RTX_UNCHANGING_P (target))
+ add_function_usage_to
+ (last_call_insn (),
+ gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_CLOBBER (VOIDmode, target),
+ NULL_RTX));
+
insns = get_insns ();
end_sequence ();
@@ -3416,7 +3501,15 @@ expand_call (exp, target, ignore)
sbitmap_free (stored_args_map);
}
else
- normal_call_insns = insns;
+ {
+ normal_call_insns = insns;
+
+ /* Verify that we've deallocated all the stack we used. */
+ if (! (flags & (ECF_NORETURN | ECF_LONGJMP))
+ && old_stack_allocated != stack_pointer_delta
+ - pending_stack_adjust)
+ abort ();
+ }
/* If something prevents making this a sibling call,
zero out the sequence. */
@@ -3483,20 +3576,115 @@ expand_call (exp, target, ignore)
return target;
}
+
+/* Traverse an argument list in VALUES and expand all complex
+ arguments into their components. */
+tree
+split_complex_values (tree values)
+{
+ tree p;
+
+ /* Before allocating memory, check for the common case of no complex. */
+ for (p = values; p; p = TREE_CHAIN (p))
+ {
+ tree type = TREE_TYPE (TREE_VALUE (p));
+ if (type && TREE_CODE (type) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (type))
+ goto found;
+ }
+ return values;
+
+ found:
+ values = copy_list (values);
+
+ for (p = values; p; p = TREE_CHAIN (p))
+ {
+ tree complex_value = TREE_VALUE (p);
+ tree complex_type;
+
+ complex_type = TREE_TYPE (complex_value);
+ if (!complex_type)
+ continue;
+
+ if (TREE_CODE (complex_type) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (complex_type))
+ {
+ tree subtype;
+ tree real, imag, next;
+
+ subtype = TREE_TYPE (complex_type);
+ complex_value = save_expr (complex_value);
+ real = build1 (REALPART_EXPR, subtype, complex_value);
+ imag = build1 (IMAGPART_EXPR, subtype, complex_value);
+
+ TREE_VALUE (p) = real;
+ next = TREE_CHAIN (p);
+ imag = build_tree_list (NULL_TREE, imag);
+ TREE_CHAIN (p) = imag;
+ TREE_CHAIN (imag) = next;
+
+ /* Skip the newly created node. */
+ p = TREE_CHAIN (p);
+ }
+ }
+
+ return values;
+}
+
+/* Traverse a list of TYPES and expand all complex types into their
+ components. */
+tree
+split_complex_types (tree types)
+{
+ tree p;
+
+ /* Before allocating memory, check for the common case of no complex. */
+ for (p = types; p; p = TREE_CHAIN (p))
+ {
+ tree type = TREE_VALUE (p);
+ if (TREE_CODE (type) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (type))
+ goto found;
+ }
+ return types;
+
+ found:
+ types = copy_list (types);
+
+ for (p = types; p; p = TREE_CHAIN (p))
+ {
+ tree complex_type = TREE_VALUE (p);
+
+ if (TREE_CODE (complex_type) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (complex_type))
+ {
+ tree next, imag;
+
+ /* Rewrite complex type with component type. */
+ TREE_VALUE (p) = TREE_TYPE (complex_type);
+ next = TREE_CHAIN (p);
+
+ /* Add another component type for the imaginary part. */
+ imag = build_tree_list (NULL_TREE, TREE_VALUE (p));
+ TREE_CHAIN (p) = imag;
+ TREE_CHAIN (imag) = next;
+
+ /* Skip the newly created node. */
+ p = TREE_CHAIN (p);
+ }
+ }
+
+ return types;
+}
/* Output a library call to function FUN (a SYMBOL_REF rtx).
The RETVAL parameter specifies whether return value needs to be saved, other
parameters are documented in the emit_library_call function below. */
static rtx
-emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
- int retval;
- rtx orgfun;
- rtx value;
- enum libcall_type fn_type;
- enum machine_mode outmode;
- int nargs;
- va_list p;
+emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
+ enum libcall_type fn_type,
+ enum machine_mode outmode, int nargs, va_list p)
{
/* Total size in bytes of all the stack-parms scanned so far. */
struct args_size args_size;
@@ -3506,7 +3694,6 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
rtx fun;
int inc;
int count;
- struct args_size alignment_pad;
rtx argblock = 0;
CUMULATIVE_ARGS args_so_far;
struct arg
@@ -3515,8 +3702,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
enum machine_mode mode;
rtx reg;
int partial;
- struct args_size offset;
- struct args_size size;
+ struct locate_and_pad_arg_data locate;
rtx save_area;
};
struct arg *argvec;
@@ -3535,7 +3721,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#ifdef REG_PARM_STACK_SPACE
/* Define the boundary of the register parm stack space that needs to be
save, if any. */
- int low_to_save = -1, high_to_save = 0;
+ int low_to_save, high_to_save;
rtx save_area = 0; /* Place that it is saved. */
#endif
@@ -3543,6 +3729,8 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
int initial_highest_arg_in_use = highest_outgoing_arg_in_use;
char *initial_stack_usage_map = stack_usage_map;
+ rtx struct_value = targetm.calls.struct_value_rtx (0, 0);
+
#ifdef REG_PARM_STACK_SPACE
#ifdef MAYBE_REG_PARM_STACK_SPACE
reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
@@ -3595,7 +3783,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
if (outmode != VOIDmode)
{
tfom = (*lang_hooks.types.type_for_mode) (outmode, 0);
- if (aggregate_value_p (tfom))
+ if (aggregate_value_p (tfom, 0))
{
#ifdef PCC_STATIC_STRUCT_RETURN
rtx pointer_reg
@@ -3627,13 +3815,13 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
of the full argument passing conventions to limit complexity here since
library functions shouldn't have many args. */
- argvec = (struct arg *) alloca ((nargs + 1) * sizeof (struct arg));
- memset ((char *) argvec, 0, (nargs + 1) * sizeof (struct arg));
+ argvec = alloca ((nargs + 1) * sizeof (struct arg));
+ memset (argvec, 0, (nargs + 1) * sizeof (struct arg));
#ifdef INIT_CUMULATIVE_LIBCALL_ARGS
INIT_CUMULATIVE_LIBCALL_ARGS (args_so_far, outmode, fun);
#else
- INIT_CUMULATIVE_ARGS (args_so_far, NULL_TREE, fun, 0);
+ INIT_CUMULATIVE_ARGS (args_so_far, NULL_TREE, fun, 0, nargs);
#endif
args_size.constant = 0;
@@ -3650,7 +3838,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
/* If there's a structure value address to be passed,
either pass it in the special place, or pass it as an extra argument. */
- if (mem_value && struct_value_rtx == 0 && ! pcc_struct_value)
+ if (mem_value && struct_value == 0 && ! pcc_struct_value)
{
rtx addr = XEXP (mem_value, 0);
nargs++;
@@ -3676,12 +3864,11 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#else
argvec[count].reg != 0,
#endif
- NULL_TREE, &args_size, &argvec[count].offset,
- &argvec[count].size, &alignment_pad);
+ 0, NULL_TREE, &args_size, &argvec[count].locate);
if (argvec[count].reg == 0 || argvec[count].partial != 0
|| reg_parm_stack_space > 0)
- args_size.constant += argvec[count].size.constant;
+ args_size.constant += argvec[count].locate.size.constant;
FUNCTION_ARG_ADVANCE (args_so_far, Pmode, (tree) 0, 1);
@@ -3699,13 +3886,6 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
|| (GET_MODE (val) != mode && GET_MODE (val) != VOIDmode))
abort ();
- /* On some machines, there's no way to pass a float to a library fcn.
- Pass it as a double instead. */
-#ifdef LIBGCC_NEEDS_DOUBLE
- if (LIBGCC_NEEDS_DOUBLE && mode == SFmode)
- val = convert_modes (DFmode, SFmode, val, 0), mode = DFmode;
-#endif
-
/* There's no need to call protect_from_queue, because
either emit_move_insn or emit_push_insn will do that. */
@@ -3719,7 +3899,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
{
rtx slot;
int must_copy = 1
-#ifdef FUNCTION_ARG_CALLEE_COPIES
+#ifdef FUNCTION_ARG_CALLEE_COPIES
&& ! FUNCTION_ARG_CALLEE_COPIES (args_so_far, mode,
NULL_TREE, 1)
#endif
@@ -3755,12 +3935,12 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
{
tree type = (*lang_hooks.types.type_for_mode) (mode, 0);
- slot = gen_rtx_MEM (mode,
- expand_expr (build1 (ADDR_EXPR,
- build_pointer_type
- (type),
- make_tree (type, val)),
- NULL_RTX, VOIDmode, 0));
+ slot
+ = gen_rtx_MEM (mode,
+ expand_expr (build1 (ADDR_EXPR,
+ build_pointer_type (type),
+ make_tree (type, val)),
+ NULL_RTX, VOIDmode, 0));
}
call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
@@ -3795,18 +3975,15 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#else
argvec[count].reg != 0,
#endif
- NULL_TREE, &args_size, &argvec[count].offset,
- &argvec[count].size, &alignment_pad);
+ argvec[count].partial,
+ NULL_TREE, &args_size, &argvec[count].locate);
- if (argvec[count].size.var)
+ if (argvec[count].locate.size.var)
abort ();
- if (reg_parm_stack_space == 0 && argvec[count].partial)
- argvec[count].size.constant -= argvec[count].partial * UNITS_PER_WORD;
-
if (argvec[count].reg == 0 || argvec[count].partial != 0
|| reg_parm_stack_space > 0)
- args_size.constant += argvec[count].size.constant;
+ args_size.constant += argvec[count].locate.size.constant;
FUNCTION_ARG_ADVANCE (args_so_far, mode, (tree) 0, 1);
}
@@ -3867,7 +4044,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
needed);
#endif
- stack_usage_map = (char *) alloca (highest_outgoing_arg_in_use);
+ stack_usage_map = alloca (highest_outgoing_arg_in_use);
if (initial_highest_arg_in_use)
memcpy (stack_usage_map, initial_stack_usage_map,
@@ -3916,62 +4093,9 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
{
/* The argument list is the property of the called routine and it
may clobber it. If the fixed area has been used for previous
- parameters, we must save and restore it.
-
- Here we compute the boundary of the that needs to be saved, if any. */
-
-#ifdef ARGS_GROW_DOWNWARD
- for (count = 0; count < reg_parm_stack_space + 1; count++)
-#else
- for (count = 0; count < reg_parm_stack_space; count++)
-#endif
- {
- if (count >= highest_outgoing_arg_in_use
- || stack_usage_map[count] == 0)
- continue;
-
- if (low_to_save == -1)
- low_to_save = count;
-
- high_to_save = count;
- }
-
- if (low_to_save >= 0)
- {
- int num_to_save = high_to_save - low_to_save + 1;
- enum machine_mode save_mode
- = mode_for_size (num_to_save * BITS_PER_UNIT, MODE_INT, 1);
- rtx stack_area;
-
- /* If we don't have the required alignment, must do this in BLKmode. */
- if ((low_to_save & (MIN (GET_MODE_SIZE (save_mode),
- BIGGEST_ALIGNMENT / UNITS_PER_WORD) - 1)))
- save_mode = BLKmode;
-
-#ifdef ARGS_GROW_DOWNWARD
- stack_area = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- plus_constant (argblock,
- -high_to_save)));
-#else
- stack_area = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- plus_constant (argblock,
- low_to_save)));
-#endif
- if (save_mode == BLKmode)
- {
- save_area = assign_stack_temp (BLKmode, num_to_save, 0);
- set_mem_align (save_area, PARM_BOUNDARY);
- emit_block_move (save_area, stack_area, GEN_INT (num_to_save),
- BLOCK_OP_CALL_PARM);
- }
- else
- {
- save_area = gen_reg_rtx (save_mode);
- emit_move_insn (save_area, stack_area);
- }
- }
+ parameters, we must save and restore it. */
+ save_area = save_fixed_argument_area (reg_parm_stack_space, argblock,
+ &low_to_save, &high_to_save);
}
#endif
@@ -3997,44 +4121,44 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
#ifdef ARGS_GROW_DOWNWARD
/* stack_slot is negative, but we want to index stack_usage_map
with positive values. */
- upper_bound = -argvec[argnum].offset.constant + 1;
- lower_bound = upper_bound - argvec[argnum].size.constant;
+ upper_bound = -argvec[argnum].locate.offset.constant + 1;
+ lower_bound = upper_bound - argvec[argnum].locate.size.constant;
#else
- lower_bound = argvec[argnum].offset.constant;
- upper_bound = lower_bound + argvec[argnum].size.constant;
+ lower_bound = argvec[argnum].locate.offset.constant;
+ upper_bound = lower_bound + argvec[argnum].locate.size.constant;
#endif
- for (i = lower_bound; i < upper_bound; i++)
- if (stack_usage_map[i]
- /* Don't store things in the fixed argument area at this
- point; it has already been saved. */
- && i > reg_parm_stack_space)
- break;
+ i = lower_bound;
+ /* Don't worry about things in the fixed argument area;
+ it has already been saved. */
+ if (i < reg_parm_stack_space)
+ i = reg_parm_stack_space;
+ while (i < upper_bound && stack_usage_map[i] == 0)
+ i++;
- if (i != upper_bound)
+ if (i < upper_bound)
{
- /* We need to make a save area. See what mode we can make
- it. */
+ /* We need to make a save area. */
+ unsigned int size
+ = argvec[argnum].locate.size.constant * BITS_PER_UNIT;
enum machine_mode save_mode
- = mode_for_size (argvec[argnum].size.constant
- * BITS_PER_UNIT,
- MODE_INT, 1);
+ = mode_for_size (size, MODE_INT, 1);
+ rtx adr
+ = plus_constant (argblock,
+ argvec[argnum].locate.offset.constant);
rtx stack_area
- = gen_rtx_MEM
- (save_mode,
- memory_address
- (save_mode,
- plus_constant (argblock,
- argvec[argnum].offset.constant)));
+ = gen_rtx_MEM (save_mode, memory_address (save_mode, adr));
+
if (save_mode == BLKmode)
{
argvec[argnum].save_area
= assign_stack_temp (BLKmode,
- argvec[argnum].size.constant, 0);
+ argvec[argnum].locate.size.constant,
+ 0);
emit_block_move (validize_mem (argvec[argnum].save_area),
stack_area,
- GEN_INT (argvec[argnum].size.constant),
+ GEN_INT (argvec[argnum].locate.size.constant),
BLOCK_OP_CALL_PARM);
}
else
@@ -4048,8 +4172,9 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
emit_push_insn (val, mode, NULL_TREE, NULL_RTX, PARM_BOUNDARY,
partial, reg, 0, argblock,
- GEN_INT (argvec[argnum].offset.constant),
- reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
+ GEN_INT (argvec[argnum].locate.offset.constant),
+ reg_parm_stack_space,
+ ARGS_SIZE_RTX (argvec[argnum].locate.alignment_pad));
/* Now mark the segment we just used. */
if (ACCUMULATE_OUTGOING_ARGS)
@@ -4086,7 +4211,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
/* Handle calls that pass values in multiple non-contiguous
locations. The PA64 has examples of this for library calls. */
if (reg != 0 && GET_CODE (reg) == PARALLEL)
- emit_group_load (reg, val, GET_MODE_SIZE (GET_MODE (val)));
+ emit_group_load (reg, val, NULL_TREE, GET_MODE_SIZE (GET_MODE (val)));
else if (reg != 0 && partial == 0)
emit_move_insn (reg, val);
@@ -4104,14 +4229,14 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
}
/* Pass the function the address in which to return a structure value. */
- if (mem_value != 0 && struct_value_rtx != 0 && ! pcc_struct_value)
+ if (mem_value != 0 && struct_value != 0 && ! pcc_struct_value)
{
- emit_move_insn (struct_value_rtx,
+ emit_move_insn (struct_value,
force_reg (Pmode,
force_operand (XEXP (mem_value, 0),
NULL_RTX)));
- if (GET_CODE (struct_value_rtx) == REG)
- use_reg (&call_fusage, struct_value_rtx);
+ if (GET_CODE (struct_value) == REG)
+ use_reg (&call_fusage, struct_value);
}
/* Don't allow popping to be deferred, since then
@@ -4190,7 +4315,8 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
if (GET_CODE (valreg) == PARALLEL)
{
temp = gen_reg_rtx (outmode);
- emit_group_store (temp, valreg, outmode);
+ emit_group_store (temp, valreg, NULL_TREE,
+ GET_MODE_SIZE (outmode));
valreg = temp;
}
@@ -4233,7 +4359,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
{
if (value == 0)
value = gen_reg_rtx (outmode);
- emit_group_store (value, valreg, outmode);
+ emit_group_store (value, valreg, NULL_TREE, GET_MODE_SIZE (outmode));
}
else if (value != 0)
emit_move_insn (value, valreg);
@@ -4245,29 +4371,8 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
{
#ifdef REG_PARM_STACK_SPACE
if (save_area)
- {
- enum machine_mode save_mode = GET_MODE (save_area);
-#ifdef ARGS_GROW_DOWNWARD
- rtx stack_area
- = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- plus_constant (argblock,
- - high_to_save)));
-#else
- rtx stack_area
- = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- plus_constant (argblock, low_to_save)));
-#endif
-
- set_mem_align (stack_area, PARM_BOUNDARY);
- if (save_mode != BLKmode)
- emit_move_insn (stack_area, save_area);
- else
- emit_block_move (stack_area, save_area,
- GEN_INT (high_to_save - low_to_save + 1),
- BLOCK_OP_CALL_PARM);
- }
+ restore_fixed_argument_area (save_area, argblock,
+ high_to_save, low_to_save);
#endif
/* If we saved any argument areas, restore them. */
@@ -4275,17 +4380,15 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
if (argvec[count].save_area)
{
enum machine_mode save_mode = GET_MODE (argvec[count].save_area);
- rtx stack_area
- = gen_rtx_MEM (save_mode,
- memory_address
- (save_mode,
- plus_constant (argblock,
- argvec[count].offset.constant)));
+ rtx adr = plus_constant (argblock,
+ argvec[count].locate.offset.constant);
+ rtx stack_area = gen_rtx_MEM (save_mode,
+ memory_address (save_mode, adr));
if (save_mode == BLKmode)
emit_block_move (stack_area,
validize_mem (argvec[count].save_area),
- GEN_INT (argvec[count].size.constant),
+ GEN_INT (argvec[count].locate.size.constant),
BLOCK_OP_CALL_PARM);
else
emit_move_insn (stack_area, argvec[count].save_area);
@@ -4314,18 +4417,14 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
or other LCT_ value for other types of library calls. */
void
-emit_library_call VPARAMS((rtx orgfun, enum libcall_type fn_type,
- enum machine_mode outmode, int nargs, ...))
+emit_library_call (rtx orgfun, enum libcall_type fn_type,
+ enum machine_mode outmode, int nargs, ...)
{
- VA_OPEN (p, nargs);
- VA_FIXEDARG (p, rtx, orgfun);
- VA_FIXEDARG (p, int, fn_type);
- VA_FIXEDARG (p, enum machine_mode, outmode);
- VA_FIXEDARG (p, int, nargs);
+ va_list p;
+ va_start (p, nargs);
emit_library_call_value_1 (0, orgfun, NULL_RTX, fn_type, outmode, nargs, p);
-
- VA_CLOSE (p);
+ va_end (p);
}
/* Like emit_library_call except that an extra argument, VALUE,
@@ -4337,23 +4436,17 @@ emit_library_call VPARAMS((rtx orgfun, enum libcall_type fn_type,
If VALUE is nonzero, VALUE is returned. */
rtx
-emit_library_call_value VPARAMS((rtx orgfun, rtx value,
- enum libcall_type fn_type,
- enum machine_mode outmode, int nargs, ...))
+emit_library_call_value (rtx orgfun, rtx value,
+ enum libcall_type fn_type,
+ enum machine_mode outmode, int nargs, ...)
{
rtx result;
-
- VA_OPEN (p, nargs);
- VA_FIXEDARG (p, rtx, orgfun);
- VA_FIXEDARG (p, rtx, value);
- VA_FIXEDARG (p, int, fn_type);
- VA_FIXEDARG (p, enum machine_mode, outmode);
- VA_FIXEDARG (p, int, nargs);
+ va_list p;
+ va_start (p, nargs);
result = emit_library_call_value_1 (1, orgfun, value, fn_type, outmode,
nargs, p);
-
- VA_CLOSE (p);
+ va_end (p);
return result;
}
@@ -4378,12 +4471,8 @@ emit_library_call_value VPARAMS((rtx orgfun, rtx value,
zero otherwise. */
static int
-store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
- struct arg_data *arg;
- rtx argblock;
- int flags;
- int variable_size ATTRIBUTE_UNUSED;
- int reg_parm_stack_space;
+store_one_arg (struct arg_data *arg, rtx argblock, int flags,
+ int variable_size ATTRIBUTE_UNUSED, int reg_parm_stack_space)
{
tree pval = arg->tree_value;
rtx reg = 0;
@@ -4413,32 +4502,31 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
else
upper_bound = 0;
- lower_bound = upper_bound - arg->size.constant;
+ lower_bound = upper_bound - arg->locate.size.constant;
#else
if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS)
lower_bound = INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1));
else
lower_bound = 0;
- upper_bound = lower_bound + arg->size.constant;
+ upper_bound = lower_bound + arg->locate.size.constant;
#endif
- for (i = lower_bound; i < upper_bound; i++)
- if (stack_usage_map[i]
- /* Don't store things in the fixed argument area at this point;
- it has already been saved. */
- && i > reg_parm_stack_space)
- break;
+ i = lower_bound;
+ /* Don't worry about things in the fixed argument area;
+ it has already been saved. */
+ if (i < reg_parm_stack_space)
+ i = reg_parm_stack_space;
+ while (i < upper_bound && stack_usage_map[i] == 0)
+ i++;
- if (i != upper_bound)
+ if (i < upper_bound)
{
- /* We need to make a save area. See what mode we can make it. */
- enum machine_mode save_mode
- = mode_for_size (arg->size.constant * BITS_PER_UNIT, MODE_INT, 1);
- rtx stack_area
- = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- XEXP (arg->stack_slot, 0)));
+ /* We need to make a save area. */
+ unsigned int size = arg->locate.size.constant * BITS_PER_UNIT;
+ enum machine_mode save_mode = mode_for_size (size, MODE_INT, 1);
+ rtx adr = memory_address (save_mode, XEXP (arg->stack_slot, 0));
+ rtx stack_area = gen_rtx_MEM (save_mode, adr);
if (save_mode == BLKmode)
{
@@ -4564,10 +4652,10 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
/* This isn't already where we want it on the stack, so put it there.
This can either be done with push or copy insns. */
- emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX,
+ emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX,
PARM_BOUNDARY, partial, reg, used - size, argblock,
- ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
- ARGS_SIZE_RTX (arg->alignment_pad));
+ ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space,
+ ARGS_SIZE_RTX (arg->locate.alignment_pad));
/* Unless this is a partially-in-register argument, the argument is now
in the stack. */
@@ -4589,17 +4677,27 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
/* Round its size up to a multiple
of the allocation unit for arguments. */
- if (arg->size.var != 0)
+ if (arg->locate.size.var != 0)
{
excess = 0;
- size_rtx = ARGS_SIZE_RTX (arg->size);
+ size_rtx = ARGS_SIZE_RTX (arg->locate.size);
}
else
{
/* PUSH_ROUNDING has no effect on us, because
emit_push_insn for BLKmode is careful to avoid it. */
- excess = (arg->size.constant - int_size_in_bytes (TREE_TYPE (pval))
- + partial * UNITS_PER_WORD);
+ if (reg && GET_CODE (reg) == PARALLEL)
+ {
+ /* Use the size of the elt to compute excess. */
+ rtx elt = XEXP (XVECEXP (reg, 0, 0), 0);
+ excess = (arg->locate.size.constant
+ - int_size_in_bytes (TREE_TYPE (pval))
+ + partial * GET_MODE_SIZE (GET_MODE (elt)));
+ }
+ else
+ excess = (arg->locate.size.constant
+ - int_size_in_bytes (TREE_TYPE (pval))
+ + partial * UNITS_PER_WORD);
size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)),
NULL_RTX, TYPE_MODE (sizetype), 0);
}
@@ -4612,7 +4710,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
PARM_BOUNDARY, but the actual argument isn't. */
if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
{
- if (arg->size.var)
+ if (arg->locate.size.var)
parm_align = BITS_PER_UNIT;
else if (excess)
{
@@ -4624,7 +4722,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
if ((flags & ECF_SIBCALL) && GET_CODE (arg->value) == MEM)
{
/* emit_push_insn might not work properly if arg->value and
- argblock + arg->offset areas overlap. */
+ argblock + arg->locate.offset areas overlap. */
rtx x = arg->value;
int i = 0;
@@ -4637,18 +4735,18 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
if (XEXP (x, 0) != current_function_internal_arg_pointer)
i = INTVAL (XEXP (XEXP (x, 0), 1));
- /* expand_call should ensure this */
- if (arg->offset.var || GET_CODE (size_rtx) != CONST_INT)
+ /* expand_call should ensure this. */
+ if (arg->locate.offset.var || GET_CODE (size_rtx) != CONST_INT)
abort ();
- if (arg->offset.constant > i)
+ if (arg->locate.offset.constant > i)
{
- if (arg->offset.constant < i + INTVAL (size_rtx))
+ if (arg->locate.offset.constant < i + INTVAL (size_rtx))
sibcall_failure = 1;
}
- else if (arg->offset.constant < i)
+ else if (arg->locate.offset.constant < i)
{
- if (i < arg->offset.constant + INTVAL (size_rtx))
+ if (i < arg->locate.offset.constant + INTVAL (size_rtx))
sibcall_failure = 1;
}
}
@@ -4656,8 +4754,8 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
parm_align, partial, reg, excess, argblock,
- ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
- ARGS_SIZE_RTX (arg->alignment_pad));
+ ARGS_SIZE_RTX (arg->locate.offset), reg_parm_stack_space,
+ ARGS_SIZE_RTX (arg->locate.alignment_pad));
/* Unless this is a partially-in-register argument, the argument is now
in the stack.
@@ -4694,3 +4792,45 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space)
return sibcall_failure;
}
+
+/* Nonzero if we do not know how to pass TYPE solely in registers.
+ We cannot do so in the following cases:
+
+ - if the type has variable size
+ - if the type is marked as addressable (it is required to be constructed
+ into the stack)
+ - if the padding and mode of the type is such that a copy into a register
+ would put it into the wrong part of the register.
+
+ Which padding can't be supported depends on the byte endianness.
+
+ A value in a register is implicitly padded at the most significant end.
+ On a big-endian machine, that is the lower end in memory.
+ So a value padded in memory at the upper end can't go in a register.
+ For a little-endian machine, the reverse is true. */
+
+bool
+default_must_pass_in_stack (enum machine_mode mode, tree type)
+{
+ if (!type)
+ return false;
+
+ /* If the type has variable size... */
+ if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+ return true;
+
+ /* If the type is marked as addressable (it is required
+ to be constructed into the stack)... */
+ if (TREE_ADDRESSABLE (type))
+ return true;
+
+ /* If the padding and mode of the type is such that a copy into
+ a register would put it into the wrong part of the register. */
+ if (mode == BLKmode
+ && int_size_in_bytes (type) % (PARM_BOUNDARY / BITS_PER_UNIT)
+ && (FUNCTION_ARG_PADDING (mode, type)
+ == (BYTES_BIG_ENDIAN ? upward : downward)))
+ return true;
+
+ return false;
+}
diff --git a/contrib/gcc/cfg.c b/contrib/gcc/cfg.c
index 2d1158096086..804258536660 100644
--- a/contrib/gcc/cfg.c
+++ b/contrib/gcc/cfg.c
@@ -1,6 +1,6 @@
/* Control flow graph manipulation code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,7 +20,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* This file contains low level functions to manipulate the CFG and
- analyze it. All other modules should not transform the datastructure
+ analyze it. All other modules should not transform the data structure
directly and use abstraction instead. The file is supposed to be
ordered bottom-up and should not contain any code dependent on a
particular intermediate language (RTL or trees).
@@ -39,10 +39,16 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
- Allocation of AUX fields for basic blocks
alloc_aux_for_blocks, free_aux_for_blocks, alloc_aux_for_block
- clear_bb_flags
+ - Consistency checking
+ verify_flow_info
+ - Dumping and debugging
+ print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n
*/
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "hard-reg-set.h"
@@ -55,12 +61,21 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "tm_p.h"
#include "obstack.h"
+#include "alloc-pool.h"
/* The obstack on which the flow graph components are allocated. */
struct obstack flow_obstack;
static char *flow_firstobj;
+/* Basic block object pool. */
+
+static alloc_pool bb_pool;
+
+/* Edge object pool. */
+
+static alloc_pool edge_pool;
+
/* Number of basic blocks in the current function. */
int n_basic_blocks;
@@ -73,11 +88,6 @@ int last_basic_block;
int n_edges;
-/* First edge in the deleted edges chain. */
-
-edge first_deleted_edge;
-static basic_block first_deleted_block;
-
/* The basic block array. */
varray_type basic_block_info;
@@ -101,9 +111,11 @@ struct basic_block_def entry_exit_blocks[2]
EXIT_BLOCK_PTR, /* next_bb */
0, /* loop_depth */
NULL, /* loop_father */
+ { NULL, NULL }, /* dom */
0, /* count */
0, /* frequency */
- 0 /* flags */
+ 0, /* flags */
+ NULL /* rbi */
},
{
NULL, /* head */
@@ -122,56 +134,59 @@ struct basic_block_def entry_exit_blocks[2]
NULL, /* next_bb */
0, /* loop_depth */
NULL, /* loop_father */
+ { NULL, NULL }, /* dom */
0, /* count */
0, /* frequency */
- 0 /* flags */
+ 0, /* flags */
+ NULL /* rbi */
}
};
-void debug_flow_info PARAMS ((void));
-static void free_edge PARAMS ((edge));
+void debug_flow_info (void);
+static void free_edge (edge);
/* Called once at initialization time. */
void
-init_flow ()
+init_flow (void)
{
static int initialized;
- first_deleted_edge = 0;
- first_deleted_block = 0;
n_edges = 0;
if (!initialized)
{
gcc_obstack_init (&flow_obstack);
- flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
+ flow_firstobj = obstack_alloc (&flow_obstack, 0);
initialized = 1;
}
else
{
+ free_alloc_pool (bb_pool);
+ free_alloc_pool (edge_pool);
obstack_free (&flow_obstack, flow_firstobj);
- flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
+ flow_firstobj = obstack_alloc (&flow_obstack, 0);
}
+ bb_pool = create_alloc_pool ("Basic block pool",
+ sizeof (struct basic_block_def), 100);
+ edge_pool = create_alloc_pool ("Edge pool",
+ sizeof (struct edge_def), 100);
}
/* Helper function for remove_edge and clear_edges. Frees edge structure
without actually unlinking it from the pred/succ lists. */
static void
-free_edge (e)
- edge e;
+free_edge (edge e)
{
n_edges--;
- memset (e, 0, sizeof *e);
- e->succ_next = first_deleted_edge;
- first_deleted_edge = e;
+ pool_free (edge_pool, e);
}
/* Free the memory associated with the edge structures. */
void
-clear_edges ()
+clear_edges (void)
{
basic_block bb;
edge e;
@@ -211,28 +226,17 @@ clear_edges ()
/* Allocate memory for basic_block. */
basic_block
-alloc_block ()
+alloc_block (void)
{
basic_block bb;
-
- if (first_deleted_block)
- {
- bb = first_deleted_block;
- first_deleted_block = (basic_block) bb->succ;
- bb->succ = NULL;
- }
- else
- {
- bb = (basic_block) obstack_alloc (&flow_obstack, sizeof *bb);
- memset (bb, 0, sizeof *bb);
- }
+ bb = pool_alloc (bb_pool);
+ memset (bb, 0, sizeof (*bb));
return bb;
}
/* Link block B to chain after AFTER. */
void
-link_block (b, after)
- basic_block b, after;
+link_block (basic_block b, basic_block after)
{
b->next_bb = after->next_bb;
b->prev_bb = after;
@@ -242,8 +246,7 @@ link_block (b, after)
/* Unlink block B from chain. */
void
-unlink_block (b)
- basic_block b;
+unlink_block (basic_block b)
{
b->next_bb->prev_bb = b->prev_bb;
b->prev_bb->next_bb = b->next_bb;
@@ -251,11 +254,11 @@ unlink_block (b)
/* Sequentially order blocks and compact the arrays. */
void
-compact_blocks ()
+compact_blocks (void)
{
int i;
basic_block bb;
-
+
i = 0;
FOR_EACH_BB (bb)
{
@@ -270,22 +273,15 @@ compact_blocks ()
last_basic_block = n_basic_blocks;
}
-
/* Remove block B from the basic block array. */
void
-expunge_block (b)
- basic_block b;
+expunge_block (basic_block b)
{
unlink_block (b);
BASIC_BLOCK (b->index) = NULL;
n_basic_blocks--;
-
- /* Invalidate data to make bughunting easier. */
- memset (b, 0, sizeof *b);
- b->index = -3;
- b->succ = (edge) first_deleted_block;
- first_deleted_block = (basic_block) b;
+ pool_free (bb_pool, b);
}
/* Create an edge connecting SRC and DEST with flags FLAGS. Return newly
@@ -293,22 +289,11 @@ expunge_block (b)
possibly already exist. */
edge
-unchecked_make_edge (src, dst, flags)
- basic_block src, dst;
- int flags;
+unchecked_make_edge (basic_block src, basic_block dst, int flags)
{
edge e;
-
- if (first_deleted_edge)
- {
- e = first_deleted_edge;
- first_deleted_edge = e->succ_next;
- }
- else
- {
- e = (edge) obstack_alloc (&flow_obstack, sizeof *e);
- memset (e, 0, sizeof *e);
- }
+ e = pool_alloc (edge_pool);
+ memset (e, 0, sizeof (*e));
n_edges++;
e->succ_next = src->succ;
@@ -322,14 +307,12 @@ unchecked_make_edge (src, dst, flags)
return e;
}
+
/* Create an edge connecting SRC and DST with FLAGS optionally using
edge cache CACHE. Return the new edge, NULL if already exist. */
edge
-cached_make_edge (edge_cache, src, dst, flags)
- sbitmap *edge_cache;
- basic_block src, dst;
- int flags;
+cached_make_edge (sbitmap *edge_cache, basic_block src, basic_block dst, int flags)
{
int use_edge_cache;
edge e;
@@ -351,7 +334,7 @@ cached_make_edge (edge_cache, src, dst, flags)
if (flags == 0)
return NULL;
- /* FALLTHRU */
+ /* Fall through. */
case 0:
for (e = src->succ; e; e = e->succ_next)
if (e->dest == dst)
@@ -374,9 +357,7 @@ cached_make_edge (edge_cache, src, dst, flags)
created edge or NULL if already exist. */
edge
-make_edge (src, dest, flags)
- basic_block src, dest;
- int flags;
+make_edge (basic_block src, basic_block dest, int flags)
{
return cached_make_edge (NULL, src, dest, flags);
}
@@ -385,9 +366,7 @@ make_edge (src, dest, flags)
that it is the single edge leaving SRC. */
edge
-make_single_succ_edge (src, dest, flags)
- basic_block src, dest;
- int flags;
+make_single_succ_edge (basic_block src, basic_block dest, int flags)
{
edge e = make_edge (src, dest, flags);
@@ -399,8 +378,7 @@ make_single_succ_edge (src, dest, flags)
/* This function will remove an edge from the flow graph. */
void
-remove_edge (e)
- edge e;
+remove_edge (edge e)
{
edge last_pred = NULL;
edge last_succ = NULL;
@@ -435,9 +413,7 @@ remove_edge (e)
/* Redirect an edge's successor from one block to another. */
void
-redirect_edge_succ (e, new_succ)
- edge e;
- basic_block new_succ;
+redirect_edge_succ (edge e, basic_block new_succ)
{
edge *pe;
@@ -455,9 +431,7 @@ redirect_edge_succ (e, new_succ)
/* Like previous but avoid possible duplicate edge. */
edge
-redirect_edge_succ_nodup (e, new_succ)
- edge e;
- basic_block new_succ;
+redirect_edge_succ_nodup (edge e, basic_block new_succ)
{
edge s;
@@ -485,9 +459,7 @@ redirect_edge_succ_nodup (e, new_succ)
/* Redirect an edge's predecessor from one block to another. */
void
-redirect_edge_pred (e, new_pred)
- edge e;
- basic_block new_pred;
+redirect_edge_pred (edge e, basic_block new_pred)
{
edge *pe;
@@ -504,7 +476,7 @@ redirect_edge_pred (e, new_pred)
}
void
-clear_bb_flags ()
+clear_bb_flags (void)
{
basic_block bb;
@@ -513,8 +485,7 @@ clear_bb_flags ()
}
void
-dump_flow_info (file)
- FILE *file;
+dump_flow_info (FILE *file)
{
int i;
int max_regno = max_reg_num ();
@@ -522,48 +493,49 @@ dump_flow_info (file)
static const char * const reg_class_names[] = REG_CLASS_NAMES;
fprintf (file, "%d registers.\n", max_regno);
- for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
- if (REG_N_REFS (i))
- {
- enum reg_class class, altclass;
-
- fprintf (file, "\nRegister %d used %d times across %d insns",
- i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
- if (REG_BASIC_BLOCK (i) >= 0)
- fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
- if (REG_N_SETS (i))
- fprintf (file, "; set %d time%s", REG_N_SETS (i),
- (REG_N_SETS (i) == 1) ? "" : "s");
- if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
- fprintf (file, "; user var");
- if (REG_N_DEATHS (i) != 1)
- fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
- if (REG_N_CALLS_CROSSED (i) == 1)
- fprintf (file, "; crosses 1 call");
- else if (REG_N_CALLS_CROSSED (i))
- fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
- if (regno_reg_rtx[i] != NULL
- && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
- fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
-
- class = reg_preferred_class (i);
- altclass = reg_alternate_class (i);
- if (class != GENERAL_REGS || altclass != ALL_REGS)
- {
- if (altclass == ALL_REGS || class == ALL_REGS)
- fprintf (file, "; pref %s", reg_class_names[(int) class]);
- else if (altclass == NO_REGS)
- fprintf (file, "; %s or none", reg_class_names[(int) class]);
- else
- fprintf (file, "; pref %s, else %s",
- reg_class_names[(int) class],
- reg_class_names[(int) altclass]);
- }
-
- if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
- fprintf (file, "; pointer");
- fprintf (file, ".\n");
- }
+ if (reg_n_info)
+ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ if (REG_N_REFS (i))
+ {
+ enum reg_class class, altclass;
+
+ fprintf (file, "\nRegister %d used %d times across %d insns",
+ i, REG_N_REFS (i), REG_LIVE_LENGTH (i));
+ if (REG_BASIC_BLOCK (i) >= 0)
+ fprintf (file, " in block %d", REG_BASIC_BLOCK (i));
+ if (REG_N_SETS (i))
+ fprintf (file, "; set %d time%s", REG_N_SETS (i),
+ (REG_N_SETS (i) == 1) ? "" : "s");
+ if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
+ fprintf (file, "; user var");
+ if (REG_N_DEATHS (i) != 1)
+ fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
+ if (REG_N_CALLS_CROSSED (i) == 1)
+ fprintf (file, "; crosses 1 call");
+ else if (REG_N_CALLS_CROSSED (i))
+ fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
+ if (regno_reg_rtx[i] != NULL
+ && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
+ fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
+
+ class = reg_preferred_class (i);
+ altclass = reg_alternate_class (i);
+ if (class != GENERAL_REGS || altclass != ALL_REGS)
+ {
+ if (altclass == ALL_REGS || class == ALL_REGS)
+ fprintf (file, "; pref %s", reg_class_names[(int) class]);
+ else if (altclass == NO_REGS)
+ fprintf (file, "; %s or none", reg_class_names[(int) class]);
+ else
+ fprintf (file, "; pref %s, else %s",
+ reg_class_names[(int) class],
+ reg_class_names[(int) altclass]);
+ }
+
+ if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
+ fprintf (file, "; pointer");
+ fprintf (file, ".\n");
+ }
fprintf (file, "\n%d basic blocks, %d edges.\n", n_basic_blocks, n_edges);
FOR_EACH_BB (bb)
@@ -573,7 +545,7 @@ dump_flow_info (file)
gcov_type lsum;
fprintf (file, "\nBasic block %d: first insn %d, last %d, ",
- bb->index, INSN_UID (bb->head), INSN_UID (bb->end));
+ bb->index, INSN_UID (BB_HEAD (bb)), INSN_UID (BB_END (bb)));
fprintf (file, "prev %d, next %d, ",
bb->prev_bb->index, bb->next_bb->index);
fprintf (file, "loop_depth %d, count ", bb->loop_depth);
@@ -603,7 +575,7 @@ dump_flow_info (file)
/* Check the consistency of profile information. We can't do that
in verify_flow_info, as the counts may get invalid for incompletely
- solved graphs, later elliminating of conditionals or roundoff errors.
+ solved graphs, later eliminating of conditionals or roundoff errors.
It is still practical to have them reported for debugging of simple
testcases. */
sum = 0;
@@ -637,16 +609,13 @@ dump_flow_info (file)
}
void
-debug_flow_info ()
+debug_flow_info (void)
{
dump_flow_info (stderr);
}
void
-dump_edge_info (file, e, do_succ)
- FILE *file;
- edge e;
- int do_succ;
+dump_edge_info (FILE *file, edge e, int do_succ)
{
basic_block side = (do_succ ? e->dest : e->src);
@@ -668,8 +637,10 @@ dump_edge_info (file, e, do_succ)
if (e->flags)
{
- static const char * const bitnames[]
- = {"fallthru", "ab", "abcall", "eh", "fake", "dfs_back", "can_fallthru"};
+ static const char * const bitnames[] = {
+ "fallthru", "ab", "abcall", "eh", "fake", "dfs_back",
+ "can_fallthru", "irreducible", "sibcall", "loop_exit"
+ };
int comma = 0;
int i, flags = e->flags;
@@ -703,9 +674,7 @@ static void *first_edge_aux_obj = 0;
be first initialized by alloc_aux_for_blocks. */
inline void
-alloc_aux_for_block (bb, size)
- basic_block bb;
- int size;
+alloc_aux_for_block (basic_block bb, int size)
{
/* Verify that aux field is clear. */
if (bb->aux || !first_block_aux_obj)
@@ -718,8 +687,7 @@ alloc_aux_for_block (bb, size)
alloc_aux_for_block for each basic block. */
void
-alloc_aux_for_blocks (size)
- int size;
+alloc_aux_for_blocks (int size)
{
static int initialized;
@@ -732,7 +700,7 @@ alloc_aux_for_blocks (size)
/* Check whether AUX data are still allocated. */
else if (first_block_aux_obj)
abort ();
- first_block_aux_obj = (char *) obstack_alloc (&block_aux_obstack, 0);
+ first_block_aux_obj = obstack_alloc (&block_aux_obstack, 0);
if (size)
{
basic_block bb;
@@ -745,7 +713,7 @@ alloc_aux_for_blocks (size)
/* Clear AUX pointers of all blocks. */
void
-clear_aux_for_blocks ()
+clear_aux_for_blocks (void)
{
basic_block bb;
@@ -757,7 +725,7 @@ clear_aux_for_blocks ()
of all blocks. */
void
-free_aux_for_blocks ()
+free_aux_for_blocks (void)
{
if (!first_block_aux_obj)
abort ();
@@ -771,9 +739,7 @@ free_aux_for_blocks ()
be first initialized by alloc_aux_for_edges. */
inline void
-alloc_aux_for_edge (e, size)
- edge e;
- int size;
+alloc_aux_for_edge (edge e, int size)
{
/* Verify that aux field is clear. */
if (e->aux || !first_edge_aux_obj)
@@ -786,8 +752,7 @@ alloc_aux_for_edge (e, size)
alloc_aux_for_edge for each basic edge. */
void
-alloc_aux_for_edges (size)
- int size;
+alloc_aux_for_edges (int size)
{
static int initialized;
@@ -801,7 +766,7 @@ alloc_aux_for_edges (size)
else if (first_edge_aux_obj)
abort ();
- first_edge_aux_obj = (char *) obstack_alloc (&edge_aux_obstack, 0);
+ first_edge_aux_obj = obstack_alloc (&edge_aux_obstack, 0);
if (size)
{
basic_block bb;
@@ -819,7 +784,7 @@ alloc_aux_for_edges (size)
/* Clear AUX pointers of all edges. */
void
-clear_aux_for_edges ()
+clear_aux_for_edges (void)
{
basic_block bb;
edge e;
@@ -835,7 +800,7 @@ clear_aux_for_edges ()
of all edges. */
void
-free_aux_for_edges ()
+free_aux_for_edges (void)
{
if (!first_edge_aux_obj)
abort ();
@@ -844,3 +809,186 @@ free_aux_for_edges ()
clear_aux_for_edges ();
}
+
+/* Verify the CFG consistency.
+
+ Currently it does following checks edge and basic block list correctness
+ and calls into IL dependent checking then. */
+void
+verify_flow_info (void)
+{
+ size_t *edge_checksum;
+ int num_bb_notes, err = 0;
+ basic_block bb, last_bb_seen;
+ basic_block *last_visited;
+
+ last_visited = xcalloc (last_basic_block + 2, sizeof (basic_block));
+ edge_checksum = xcalloc (last_basic_block + 2, sizeof (size_t));
+
+ /* Check bb chain & numbers. */
+ last_bb_seen = ENTRY_BLOCK_PTR;
+ FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
+ {
+ if (bb != EXIT_BLOCK_PTR
+ && bb != BASIC_BLOCK (bb->index))
+ {
+ error ("bb %d on wrong place", bb->index);
+ err = 1;
+ }
+
+ if (bb->prev_bb != last_bb_seen)
+ {
+ error ("prev_bb of %d should be %d, not %d",
+ bb->index, last_bb_seen->index, bb->prev_bb->index);
+ err = 1;
+ }
+
+ last_bb_seen = bb;
+ }
+
+ /* Now check the basic blocks (boundaries etc.) */
+ FOR_EACH_BB_REVERSE (bb)
+ {
+ int n_fallthru = 0;
+ edge e;
+
+ if (bb->count < 0)
+ {
+ error ("verify_flow_info: Wrong count of block %i %i",
+ bb->index, (int)bb->count);
+ err = 1;
+ }
+ if (bb->frequency < 0)
+ {
+ error ("verify_flow_info: Wrong frequency of block %i %i",
+ bb->index, bb->frequency);
+ err = 1;
+ }
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if (last_visited [e->dest->index + 2] == bb)
+ {
+ error ("verify_flow_info: Duplicate edge %i->%i",
+ e->src->index, e->dest->index);
+ err = 1;
+ }
+ if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
+ {
+ error ("verify_flow_info: Wrong probability of edge %i->%i %i",
+ e->src->index, e->dest->index, e->probability);
+ err = 1;
+ }
+ if (e->count < 0)
+ {
+ error ("verify_flow_info: Wrong count of edge %i->%i %i",
+ e->src->index, e->dest->index, (int)e->count);
+ err = 1;
+ }
+
+ last_visited [e->dest->index + 2] = bb;
+
+ if (e->flags & EDGE_FALLTHRU)
+ n_fallthru++;
+
+ if (e->src != bb)
+ {
+ error ("verify_flow_info: Basic block %d succ edge is corrupted",
+ bb->index);
+ fprintf (stderr, "Predecessor: ");
+ dump_edge_info (stderr, e, 0);
+ fprintf (stderr, "\nSuccessor: ");
+ dump_edge_info (stderr, e, 1);
+ fprintf (stderr, "\n");
+ err = 1;
+ }
+
+ edge_checksum[e->dest->index + 2] += (size_t) e;
+ }
+ if (n_fallthru > 1)
+ {
+ error ("Wrong amount of branch edges after unconditional jump %i", bb->index);
+ err = 1;
+ }
+
+ for (e = bb->pred; e; e = e->pred_next)
+ {
+ if (e->dest != bb)
+ {
+ error ("basic block %d pred edge is corrupted", bb->index);
+ fputs ("Predecessor: ", stderr);
+ dump_edge_info (stderr, e, 0);
+ fputs ("\nSuccessor: ", stderr);
+ dump_edge_info (stderr, e, 1);
+ fputc ('\n', stderr);
+ err = 1;
+ }
+ edge_checksum[e->dest->index + 2] -= (size_t) e;
+ }
+ }
+
+ /* Complete edge checksumming for ENTRY and EXIT. */
+ {
+ edge e;
+
+ for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
+ edge_checksum[e->dest->index + 2] += (size_t) e;
+
+ for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
+ edge_checksum[e->dest->index + 2] -= (size_t) e;
+ }
+
+ FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
+ if (edge_checksum[bb->index + 2])
+ {
+ error ("basic block %i edge lists are corrupted", bb->index);
+ err = 1;
+ }
+
+ num_bb_notes = 0;
+ last_bb_seen = ENTRY_BLOCK_PTR;
+
+ /* Clean up. */
+ free (last_visited);
+ free (edge_checksum);
+ err |= cfg_hooks->cfgh_verify_flow_info ();
+ if (err)
+ internal_error ("verify_flow_info failed");
+}
+
+/* Print out one basic block with live information at start and end. */
+
+void
+dump_bb (basic_block bb, FILE *outf)
+{
+ edge e;
+
+ fprintf (outf, ";; Basic block %d, loop depth %d, count ",
+ bb->index, bb->loop_depth);
+ fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
+ putc ('\n', outf);
+ fputs (";; Predecessors: ", outf);
+ for (e = bb->pred; e; e = e->pred_next)
+ dump_edge_info (outf, e, 0);
+ putc ('\n', outf);
+
+ cfg_hooks->dump_bb (bb, outf);
+
+ fputs (";; Successors: ", outf);
+ for (e = bb->succ; e; e = e->succ_next)
+ dump_edge_info (outf, e, 1);
+ putc ('\n', outf);
+}
+
+void
+debug_bb (basic_block bb)
+{
+ dump_bb (bb, stderr);
+}
+
+basic_block
+debug_bb_n (int n)
+{
+ basic_block bb = BASIC_BLOCK (n);
+ dump_bb (bb, stderr);
+ return bb;
+}
diff --git a/contrib/gcc/cfganal.c b/contrib/gcc/cfganal.c
index 3831c5f4768a..aa3965cac07c 100644
--- a/contrib/gcc/cfganal.c
+++ b/contrib/gcc/cfganal.c
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* This file contains various simple utilities to analyze the CFG. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "hard-reg-set.h"
#include "basic-block.h"
@@ -44,29 +46,25 @@ struct depth_first_search_dsS {
};
typedef struct depth_first_search_dsS *depth_first_search_ds;
-static void flow_dfs_compute_reverse_init
- PARAMS ((depth_first_search_ds));
-static void flow_dfs_compute_reverse_add_bb
- PARAMS ((depth_first_search_ds, basic_block));
-static basic_block flow_dfs_compute_reverse_execute
- PARAMS ((depth_first_search_ds));
-static void flow_dfs_compute_reverse_finish
- PARAMS ((depth_first_search_ds));
-static void remove_fake_successors PARAMS ((basic_block));
-static bool need_fake_edge_p PARAMS ((rtx));
-static bool flow_active_insn_p PARAMS ((rtx));
+static void flow_dfs_compute_reverse_init (depth_first_search_ds);
+static void flow_dfs_compute_reverse_add_bb (depth_first_search_ds,
+ basic_block);
+static basic_block flow_dfs_compute_reverse_execute (depth_first_search_ds);
+static void flow_dfs_compute_reverse_finish (depth_first_search_ds);
+static void remove_fake_successors (basic_block);
+static bool need_fake_edge_p (rtx);
+static bool flow_active_insn_p (rtx);
/* Like active_insn_p, except keep the return value clobber around
even after reload. */
static bool
-flow_active_insn_p (insn)
- rtx insn;
+flow_active_insn_p (rtx insn)
{
if (active_insn_p (insn))
return true;
- /* A clobber of the function return value exists for buggy
+ /* A clobber of the function return value exists for buggy
programs that fail to return a value. Its effect is to
keep the return value from being live across the entire
function. If we allow it to be skipped, we introduce the
@@ -83,8 +81,7 @@ flow_active_insn_p (insn)
its single destination. */
bool
-forwarder_block_p (bb)
- basic_block bb;
+forwarder_block_p (basic_block bb)
{
rtx insn;
@@ -92,7 +89,7 @@ forwarder_block_p (bb)
|| !bb->succ || bb->succ->succ_next)
return false;
- for (insn = bb->head; insn != bb->end; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
if (INSN_P (insn) && flow_active_insn_p (insn))
return false;
@@ -104,16 +101,15 @@ forwarder_block_p (bb)
/* Return nonzero if we can reach target from src by falling through. */
bool
-can_fallthru (src, target)
- basic_block src, target;
+can_fallthru (basic_block src, basic_block target)
{
- rtx insn = src->end;
- rtx insn2 = target->head;
+ rtx insn = BB_END (src);
+ rtx insn2 = target == EXIT_BLOCK_PTR ? NULL : BB_HEAD (target);
if (src->next_bb != target)
return 0;
- if (!active_insn_p (insn2))
+ if (insn2 && !active_insn_p (insn2))
insn2 = next_active_insn (insn2);
/* ??? Later we may add code to move jump tables offline. */
@@ -131,7 +127,7 @@ can_fallthru (src, target)
and heavily borrowed from flow_depth_first_order_compute. */
bool
-mark_dfs_back_edges ()
+mark_dfs_back_edges (void)
{
edge *stack;
int *pre;
@@ -143,11 +139,11 @@ mark_dfs_back_edges ()
bool found = false;
/* Allocate the preorder and postorder number arrays. */
- pre = (int *) xcalloc (last_basic_block, sizeof (int));
- post = (int *) xcalloc (last_basic_block, sizeof (int));
+ pre = xcalloc (last_basic_block, sizeof (int));
+ post = xcalloc (last_basic_block, sizeof (int));
/* Allocate stack for back-tracking up CFG. */
- stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
+ stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
@@ -215,7 +211,7 @@ mark_dfs_back_edges ()
/* Set the flag EDGE_CAN_FALLTHRU for edges that can be fallthru. */
void
-set_edge_can_fallthru_flag ()
+set_edge_can_fallthru_flag (void)
{
basic_block bb;
@@ -232,15 +228,15 @@ set_edge_can_fallthru_flag ()
e->flags |= EDGE_CAN_FALLTHRU;
}
- /* If the BB ends with an invertable condjump all (2) edges are
+ /* If the BB ends with an invertible condjump all (2) edges are
CAN_FALLTHRU edges. */
if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
continue;
- if (!any_condjump_p (bb->end))
+ if (!any_condjump_p (BB_END (bb)))
continue;
- if (!invert_jump (bb->end, JUMP_LABEL (bb->end), 0))
+ if (!invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0))
continue;
- invert_jump (bb->end, JUMP_LABEL (bb->end), 0);
+ invert_jump (BB_END (bb), JUMP_LABEL (BB_END (bb)), 0);
bb->succ->flags |= EDGE_CAN_FALLTHRU;
bb->succ->succ_next->flags |= EDGE_CAN_FALLTHRU;
}
@@ -250,8 +246,7 @@ set_edge_can_fallthru_flag ()
Helper function for the flow_call_edges_add. */
static bool
-need_fake_edge_p (insn)
- rtx insn;
+need_fake_edge_p (rtx insn)
{
if (!INSN_P (insn))
return false;
@@ -280,8 +275,7 @@ need_fake_edge_p (insn)
that all subsequent instructions must be executed. */
int
-flow_call_edges_add (blocks)
- sbitmap blocks;
+flow_call_edges_add (sbitmap blocks)
{
int i;
int blocks_split = 0;
@@ -311,10 +305,10 @@ flow_call_edges_add (blocks)
if (check_last_block)
{
basic_block bb = EXIT_BLOCK_PTR->prev_bb;
- rtx insn = bb->end;
+ rtx insn = BB_END (bb);
/* Back up past insns that must be kept in the same block as a call. */
- while (insn != bb->head
+ while (insn != BB_HEAD (bb)
&& keep_with_call_p (insn))
insn = PREV_INSN (insn);
@@ -339,6 +333,7 @@ flow_call_edges_add (blocks)
for (i = 0; i < last_bb; i++)
{
basic_block bb = BASIC_BLOCK (i);
+ rtx libcall_end = NULL_RTX;
rtx insn;
rtx prev_insn;
@@ -348,7 +343,7 @@ flow_call_edges_add (blocks)
if (blocks && !TEST_BIT (blocks, i))
continue;
- for (insn = bb->end; ; insn = prev_insn)
+ for (insn = BB_END (bb); ; insn = prev_insn)
{
prev_insn = PREV_INSN (insn);
if (need_fake_edge_p (insn))
@@ -356,10 +351,14 @@ flow_call_edges_add (blocks)
edge e;
rtx split_at_insn = insn;
+ /* Don't split libcalls. */
+ if (libcall_end)
+ split_at_insn = libcall_end;
+
/* Don't split the block between a call and an insn that should
remain in the same block as the call. */
- if (GET_CODE (insn) == CALL_INSN)
- while (split_at_insn != bb->end
+ else if (GET_CODE (insn) == CALL_INSN)
+ while (split_at_insn != BB_END (bb)
&& keep_with_call_p (NEXT_INSN (split_at_insn)))
split_at_insn = NEXT_INSN (split_at_insn);
@@ -369,7 +368,7 @@ flow_call_edges_add (blocks)
cause us to mark that edge as fake and remove it later. */
#ifdef ENABLE_CHECKING
- if (split_at_insn == bb->end)
+ if (split_at_insn == BB_END (bb))
for (e = bb->succ; e; e = e->succ_next)
if (e->dest == EXIT_BLOCK_PTR)
abort ();
@@ -377,7 +376,7 @@ flow_call_edges_add (blocks)
/* Note that the following may create a new basic block
and renumber the existing basic blocks. */
- if (split_at_insn != bb->end)
+ if (split_at_insn != BB_END (bb))
{
e = split_block (bb, split_at_insn);
if (e)
@@ -387,7 +386,15 @@ flow_call_edges_add (blocks)
make_edge (bb, EXIT_BLOCK_PTR, EDGE_FAKE);
}
- if (insn == bb->head)
+ /* Watch out for REG_LIBCALL/REG_RETVAL notes so that we know
+ whether we are currently in a libcall or not. Remember that
+ we are scanning backwards! */
+ if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
+ libcall_end = insn;
+ if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
+ libcall_end = NULL_RTX;
+
+ if (insn == BB_HEAD (bb))
break;
}
}
@@ -403,13 +410,12 @@ flow_call_edges_add (blocks)
block is reachable. */
void
-find_unreachable_blocks ()
+find_unreachable_blocks (void)
{
edge e;
basic_block *tos, *worklist, bb;
- tos = worklist =
- (basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
+ tos = worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
/* Clear all the reachability flags. */
@@ -459,7 +465,7 @@ find_unreachable_blocks ()
and the data structure is filled in. */
struct edge_list *
-create_edge_list ()
+create_edge_list (void)
{
struct edge_list *elist;
edge e;
@@ -479,10 +485,10 @@ create_edge_list ()
num_edges++;
}
- elist = (struct edge_list *) xmalloc (sizeof (struct edge_list));
+ elist = xmalloc (sizeof (struct edge_list));
elist->num_blocks = block_count;
elist->num_edges = num_edges;
- elist->index_to_edge = (edge *) xmalloc (sizeof (edge) * num_edges);
+ elist->index_to_edge = xmalloc (sizeof (edge) * num_edges);
num_edges = 0;
@@ -497,8 +503,7 @@ create_edge_list ()
/* This function free's memory associated with an edge list. */
void
-free_edge_list (elist)
- struct edge_list *elist;
+free_edge_list (struct edge_list *elist)
{
if (elist)
{
@@ -510,9 +515,7 @@ free_edge_list (elist)
/* This function provides debug output showing an edge list. */
void
-print_edge_list (f, elist)
- FILE *f;
- struct edge_list *elist;
+print_edge_list (FILE *f, struct edge_list *elist)
{
int x;
@@ -539,9 +542,7 @@ print_edge_list (f, elist)
extra edges. */
void
-verify_edge_list (f, elist)
- FILE *f;
- struct edge_list *elist;
+verify_edge_list (FILE *f, struct edge_list *elist)
{
int pred, succ, index;
edge e;
@@ -606,9 +607,7 @@ verify_edge_list (f, elist)
a specified predecessor and successor. */
int
-find_edge_index (edge_list, pred, succ)
- struct edge_list *edge_list;
- basic_block pred, succ;
+find_edge_index (struct edge_list *edge_list, basic_block pred, basic_block succ)
{
int x;
@@ -623,10 +622,7 @@ find_edge_index (edge_list, pred, succ)
/* Dump the list of basic blocks in the bitmap NODES. */
void
-flow_nodes_print (str, nodes, file)
- const char *str;
- const sbitmap nodes;
- FILE *file;
+flow_nodes_print (const char *str, const sbitmap nodes, FILE *file)
{
int node;
@@ -641,11 +637,7 @@ flow_nodes_print (str, nodes, file)
/* Dump the list of edges in the array EDGE_LIST. */
void
-flow_edge_list_print (str, edge_list, num_edges, file)
- const char *str;
- const edge *edge_list;
- int num_edges;
- FILE *file;
+flow_edge_list_print (const char *str, const edge *edge_list, int num_edges, FILE *file)
{
int i;
@@ -666,8 +658,7 @@ flow_edge_list_print (str, edge_list, num_edges, file)
list it is in. */
static void
-remove_fake_successors (bb)
- basic_block bb;
+remove_fake_successors (basic_block bb)
{
edge e;
@@ -686,7 +677,7 @@ remove_fake_successors (bb)
fake predecessors. */
void
-remove_fake_edges ()
+remove_fake_edges (void)
{
basic_block bb;
@@ -699,7 +690,7 @@ remove_fake_edges ()
edges to exist. */
void
-add_noreturn_fake_exit_edges ()
+add_noreturn_fake_exit_edges (void)
{
basic_block bb;
@@ -720,7 +711,7 @@ add_noreturn_fake_exit_edges ()
nodes not reachable from the exit block. */
void
-connect_infinite_loops_to_exit ()
+connect_infinite_loops_to_exit (void)
{
basic_block unvisited_block;
struct depth_first_search_dsS dfs_ds;
@@ -745,11 +736,10 @@ connect_infinite_loops_to_exit ()
return;
}
-/* Compute reverse top sort order */
+/* Compute reverse top sort order. */
void
-flow_reverse_top_sort_order_compute (rts_order)
- int *rts_order;
+flow_reverse_top_sort_order_compute (int *rts_order)
{
edge *stack;
int sp;
@@ -757,7 +747,7 @@ flow_reverse_top_sort_order_compute (rts_order)
sbitmap visited;
/* Allocate stack for back-tracking up CFG. */
- stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
+ stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
@@ -817,9 +807,7 @@ flow_reverse_top_sort_order_compute (rts_order)
possible. */
int
-flow_depth_first_order_compute (dfs_order, rc_order)
- int *dfs_order;
- int *rc_order;
+flow_depth_first_order_compute (int *dfs_order, int *rc_order)
{
edge *stack;
int sp;
@@ -828,7 +816,7 @@ flow_depth_first_order_compute (dfs_order, rc_order)
sbitmap visited;
/* Allocate stack for back-tracking up CFG. */
- stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
+ stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
@@ -920,8 +908,7 @@ struct dfst_node
2) Walking the resulting tree from right to left. */
void
-flow_preorder_transversal_compute (pot_order)
- int *pot_order;
+flow_preorder_transversal_compute (int *pot_order)
{
edge e;
edge *stack;
@@ -934,12 +921,11 @@ flow_preorder_transversal_compute (pot_order)
basic_block bb;
/* Allocate stack for back-tracking up CFG. */
- stack = (edge *) xmalloc ((n_basic_blocks + 1) * sizeof (edge));
+ stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
sp = 0;
/* Allocate the tree. */
- dfst = (struct dfst_node *) xcalloc (last_basic_block,
- sizeof (struct dfst_node));
+ dfst = xcalloc (last_basic_block, sizeof (struct dfst_node));
FOR_EACH_BB (bb)
{
@@ -949,9 +935,7 @@ flow_preorder_transversal_compute (pot_order)
dfst[bb->index].node
= (max_successors
- ? (struct dfst_node **) xcalloc (max_successors,
- sizeof (struct dfst_node *))
- : NULL);
+ ? xcalloc (max_successors, sizeof (struct dfst_node *)) : NULL);
}
/* Allocate bitmap to track nodes that have been visited. */
@@ -1060,12 +1044,11 @@ flow_preorder_transversal_compute (pot_order)
element on the stack. */
static void
-flow_dfs_compute_reverse_init (data)
- depth_first_search_ds data;
+flow_dfs_compute_reverse_init (depth_first_search_ds data)
{
/* Allocate stack for back-tracking up CFG. */
- data->stack = (basic_block *) xmalloc ((n_basic_blocks - (INVALID_BLOCK + 1))
- * sizeof (basic_block));
+ data->stack = xmalloc ((n_basic_blocks - (INVALID_BLOCK + 1))
+ * sizeof (basic_block));
data->sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
@@ -1082,9 +1065,7 @@ flow_dfs_compute_reverse_init (data)
block. */
static void
-flow_dfs_compute_reverse_add_bb (data, bb)
- depth_first_search_ds data;
- basic_block bb;
+flow_dfs_compute_reverse_add_bb (depth_first_search_ds data, basic_block bb)
{
data->stack[data->sp++] = bb;
SET_BIT (data->visited_blocks, bb->index - (INVALID_BLOCK + 1));
@@ -1096,8 +1077,7 @@ flow_dfs_compute_reverse_add_bb (data, bb)
available. */
static basic_block
-flow_dfs_compute_reverse_execute (data)
- depth_first_search_ds data;
+flow_dfs_compute_reverse_execute (depth_first_search_ds data)
{
basic_block bb;
edge e;
@@ -1125,8 +1105,7 @@ flow_dfs_compute_reverse_execute (data)
reverse graph. */
static void
-flow_dfs_compute_reverse_finish (data)
- depth_first_search_ds data;
+flow_dfs_compute_reverse_finish (depth_first_search_ds data)
{
free (data->stack);
sbitmap_free (data->visited_blocks);
@@ -1136,13 +1115,9 @@ flow_dfs_compute_reverse_finish (data)
if REVERSE, go against direction of edges. Returns number of blocks
found and their list in RSLT. RSLT can contain at most RSLT_MAX items. */
int
-dfs_enumerate_from (bb, reverse, predicate, rslt, rslt_max, data)
- basic_block bb;
- int reverse;
- bool (*predicate) PARAMS ((basic_block, void *));
- basic_block *rslt;
- int rslt_max;
- void *data;
+dfs_enumerate_from (basic_block bb, int reverse,
+ bool (*predicate) (basic_block, void *),
+ basic_block *rslt, int rslt_max, void *data)
{
basic_block *st, lbb;
int sp = 0, tv = 0;
diff --git a/contrib/gcc/cfgbuild.c b/contrib/gcc/cfgbuild.c
index 795ae1719dca..5805e587ec82 100644
--- a/contrib/gcc/cfgbuild.c
+++ b/contrib/gcc/cfgbuild.c
@@ -34,6 +34,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "hard-reg-set.h"
@@ -46,24 +48,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "timevar.h"
-static int count_basic_blocks PARAMS ((rtx));
-static void find_basic_blocks_1 PARAMS ((rtx));
-static rtx find_label_refs PARAMS ((rtx, rtx));
-static void make_edges PARAMS ((rtx, basic_block,
- basic_block, int));
-static void make_label_edge PARAMS ((sbitmap *, basic_block,
- rtx, int));
-static void make_eh_edge PARAMS ((sbitmap *, basic_block, rtx));
-static void find_bb_boundaries PARAMS ((basic_block));
-static void compute_outgoing_frequencies PARAMS ((basic_block));
-static bool inside_basic_block_p PARAMS ((rtx));
+static int count_basic_blocks (rtx);
+static void find_basic_blocks_1 (rtx);
+static rtx find_label_refs (rtx, rtx);
+static void make_edges (rtx, basic_block, basic_block, int);
+static void make_label_edge (sbitmap *, basic_block, rtx, int);
+static void make_eh_edge (sbitmap *, basic_block, rtx);
+static void find_bb_boundaries (basic_block);
+static void compute_outgoing_frequencies (basic_block);
/* Return true if insn is something that should be contained inside basic
block. */
-static bool
-inside_basic_block_p (insn)
- rtx insn;
+bool
+inside_basic_block_p (rtx insn)
{
switch (GET_CODE (insn))
{
@@ -95,8 +93,7 @@ inside_basic_block_p (insn)
the basic block. */
bool
-control_flow_insn_p (insn)
- rtx insn;
+control_flow_insn_p (rtx insn)
{
rtx note;
@@ -124,7 +121,7 @@ control_flow_insn_p (insn)
return (flag_non_call_exceptions && can_throw_internal (insn));
case BARRIER:
- /* It is nonsence to reach barrier when looking for the
+ /* It is nonsense to reach barrier when looking for the
end of basic block, but before dead code is eliminated
this may happen. */
return false;
@@ -137,8 +134,7 @@ control_flow_insn_p (insn)
/* Count the basic blocks of the function. */
static int
-count_basic_blocks (f)
- rtx f;
+count_basic_blocks (rtx f)
{
int count = 0;
bool saw_insn = false;
@@ -146,7 +142,7 @@ count_basic_blocks (f)
for (insn = f; insn; insn = NEXT_INSN (insn))
{
- /* Code labels and barriers causes curent basic block to be
+ /* Code labels and barriers causes current basic block to be
terminated at previous real insn. */
if ((GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == BARRIER)
&& saw_insn)
@@ -179,9 +175,7 @@ count_basic_blocks (f)
This is used to scan the alternatives of a call placeholder. */
static rtx
-find_label_refs (f, lvl)
- rtx f;
- rtx lvl;
+find_label_refs (rtx f, rtx lvl)
{
rtx insn;
@@ -228,11 +222,7 @@ find_label_refs (f, lvl)
/* Create an edge from a basic block to a label. */
static void
-make_label_edge (edge_cache, src, label, flags)
- sbitmap *edge_cache;
- basic_block src;
- rtx label;
- int flags;
+make_label_edge (sbitmap *edge_cache, basic_block src, rtx label, int flags)
{
if (GET_CODE (label) != CODE_LABEL)
abort ();
@@ -251,10 +241,7 @@ make_label_edge (edge_cache, src, label, flags)
/* Create the edges generated by INSN in REGION. */
static void
-make_eh_edge (edge_cache, src, insn)
- sbitmap *edge_cache;
- basic_block src;
- rtx insn;
+make_eh_edge (sbitmap *edge_cache, basic_block src, rtx insn)
{
int is_call = GET_CODE (insn) == CALL_INSN ? EDGE_ABNORMAL_CALL : 0;
rtx handlers, i;
@@ -277,10 +264,7 @@ make_eh_edge (edge_cache, src, insn)
the list of exception regions active at the end of the basic block. */
static void
-make_edges (label_value_list, min, max, update_p)
- rtx label_value_list;
- basic_block min, max;
- int update_p;
+make_edges (rtx label_value_list, basic_block min, basic_block max, int update_p)
{
basic_block bb;
sbitmap *edge_cache = NULL;
@@ -319,13 +303,14 @@ make_edges (label_value_list, min, max, update_p)
enum rtx_code code;
int force_fallthru = 0;
- if (GET_CODE (bb->head) == CODE_LABEL && LABEL_ALT_ENTRY_P (bb->head))
+ if (GET_CODE (BB_HEAD (bb)) == CODE_LABEL
+ && LABEL_ALT_ENTRY_P (BB_HEAD (bb)))
cached_make_edge (NULL, ENTRY_BLOCK_PTR, bb, 0);
/* Examine the last instruction of the block, and discover the
ways we can leave the block. */
- insn = bb->end;
+ insn = BB_END (bb);
code = GET_CODE (insn);
/* A branch. */
@@ -342,12 +327,8 @@ make_edges (label_value_list, min, max, update_p)
else if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
;
- /* ??? Recognize a tablejump and do the right thing. */
- else if ((tmp = JUMP_LABEL (insn)) != NULL_RTX
- && (tmp = NEXT_INSN (tmp)) != NULL_RTX
- && GET_CODE (tmp) == JUMP_INSN
- && (GET_CODE (PATTERN (tmp)) == ADDR_VEC
- || GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
+ /* Recognize a tablejump and do the right thing. */
+ else if (tablejump_p (insn, NULL, &tmp))
{
rtvec vec;
int j;
@@ -410,7 +391,7 @@ make_edges (label_value_list, min, max, update_p)
in the first place. */
if (code == CALL_INSN && SIBLING_CALL_P (insn))
cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR,
- EDGE_ABNORMAL | EDGE_ABNORMAL_CALL);
+ EDGE_SIBCALL | EDGE_ABNORMAL);
/* If this is a CALL_INSN, then mark it as reaching the active EH
handler for this CALL_INSN. If we're handling non-call
@@ -442,15 +423,17 @@ make_edges (label_value_list, min, max, update_p)
}
/* Find out if we can drop through to the next block. */
- insn = next_nonnote_insn (insn);
+ insn = NEXT_INSN (insn);
+ while (insn
+ && GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK)
+ insn = NEXT_INSN (insn);
+
if (!insn || (bb->next_bb == EXIT_BLOCK_PTR && force_fallthru))
cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
else if (bb->next_bb != EXIT_BLOCK_PTR)
{
- rtx tmp = bb->next_bb->head;
- if (GET_CODE (tmp) == NOTE)
- tmp = next_nonnote_insn (tmp);
- if (force_fallthru || insn == tmp)
+ if (force_fallthru || insn == BB_HEAD (bb->next_bb))
cached_make_edge (edge_cache, bb, bb->next_bb, EDGE_FALLTHRU);
}
}
@@ -465,8 +448,7 @@ make_edges (label_value_list, min, max, update_p)
will be used in make_edges for use with computed gotos. */
static void
-find_basic_blocks_1 (f)
- rtx f;
+find_basic_blocks_1 (rtx f)
{
rtx insn, next;
rtx bb_note = NULL_RTX;
@@ -605,10 +587,8 @@ find_basic_blocks_1 (f)
numbers in use. */
void
-find_basic_blocks (f, nregs, file)
- rtx f;
- int nregs ATTRIBUTE_UNUSED;
- FILE *file ATTRIBUTE_UNUSED;
+find_basic_blocks (rtx f, int nregs ATTRIBUTE_UNUSED,
+ FILE *file ATTRIBUTE_UNUSED)
{
basic_block bb;
@@ -623,7 +603,7 @@ find_basic_blocks (f, nregs, file)
tag for reuse during create_basic_block, just in case some pass
copies around basic block notes improperly. */
FOR_EACH_BB (bb)
- bb->aux = NULL;
+ bb->aux = NULL;
VARRAY_FREE (basic_block_info);
}
@@ -668,15 +648,14 @@ enum state {BLOCK_NEW = 0, BLOCK_ORIGINAL, BLOCK_TO_SPLIT};
and create new basic blocks in the progress. */
static void
-find_bb_boundaries (bb)
- basic_block bb;
+find_bb_boundaries (basic_block bb)
{
- rtx insn = bb->head;
- rtx end = bb->end;
+ rtx insn = BB_HEAD (bb);
+ rtx end = BB_END (bb);
rtx flow_transfer_insn = NULL_RTX;
edge fallthru = NULL;
- if (insn == bb->end)
+ if (insn == BB_END (bb))
return;
if (GET_CODE (insn) == CODE_LABEL)
@@ -692,7 +671,7 @@ find_bb_boundaries (bb)
{
fallthru = split_block (bb, PREV_INSN (insn));
if (flow_transfer_insn)
- bb->end = flow_transfer_insn;
+ BB_END (bb) = flow_transfer_insn;
bb = fallthru->dest;
remove_edge (fallthru);
@@ -706,7 +685,7 @@ find_bb_boundaries (bb)
if (flow_transfer_insn && inside_basic_block_p (insn))
{
fallthru = split_block (bb, PREV_INSN (insn));
- bb->end = flow_transfer_insn;
+ BB_END (bb) = flow_transfer_insn;
bb = fallthru->dest;
remove_edge (fallthru);
flow_transfer_insn = NULL_RTX;
@@ -723,7 +702,7 @@ find_bb_boundaries (bb)
return and barrier, or possibly other sequence not behaving like
ordinary jump, we need to take care and move basic block boundary. */
if (flow_transfer_insn)
- bb->end = flow_transfer_insn;
+ BB_END (bb) = flow_transfer_insn;
/* We've possibly replaced the conditional jump by conditional jump
followed by cleanup at fallthru edge, so the outgoing edges may
@@ -735,22 +714,19 @@ find_bb_boundaries (bb)
and probabilities of outgoing edges. */
static void
-compute_outgoing_frequencies (b)
- basic_block b;
+compute_outgoing_frequencies (basic_block b)
{
edge e, f;
if (b->succ && b->succ->succ_next && !b->succ->succ_next->succ_next)
{
- rtx note = find_reg_note (b->end, REG_BR_PROB, NULL);
+ rtx note = find_reg_note (BB_END (b), REG_BR_PROB, NULL);
int probability;
if (!note)
return;
- probability = INTVAL (XEXP (find_reg_note (b->end,
- REG_BR_PROB, NULL),
- 0));
+ probability = INTVAL (XEXP (note, 0));
e = BRANCH_EDGE (b);
e->probability = probability;
e->count = ((b->count * probability + REG_BR_PROB_BASE / 2)
@@ -772,8 +748,7 @@ compute_outgoing_frequencies (b)
basic block. Update the data structure. */
void
-find_many_sub_basic_blocks (blocks)
- sbitmap blocks;
+find_many_sub_basic_blocks (sbitmap blocks)
{
basic_block bb, min, max;
@@ -810,7 +785,7 @@ find_many_sub_basic_blocks (blocks)
{
bb->count = 0;
bb->frequency = 0;
- for (e = bb->pred; e; e=e->pred_next)
+ for (e = bb->pred; e; e = e->pred_next)
{
bb->count += e->count;
bb->frequency += EDGE_FREQUENCY (e);
@@ -827,8 +802,7 @@ find_many_sub_basic_blocks (blocks)
/* Like above but for single basic block only. */
void
-find_sub_basic_blocks (bb)
- basic_block bb;
+find_sub_basic_blocks (basic_block bb)
{
basic_block min, max, b;
basic_block next = bb->next_bb;
@@ -851,7 +825,7 @@ find_sub_basic_blocks (bb)
{
b->count = 0;
b->frequency = 0;
- for (e = b->pred; e; e=e->pred_next)
+ for (e = b->pred; e; e = e->pred_next)
{
b->count += e->count;
b->frequency += EDGE_FREQUENCY (e);
diff --git a/contrib/gcc/cfgcleanup.c b/contrib/gcc/cfgcleanup.c
index df914ec0cf27..06fb9131a0dd 100644
--- a/contrib/gcc/cfgcleanup.c
+++ b/contrib/gcc/cfgcleanup.c
@@ -1,6 +1,6 @@
/* Control flow optimization code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -33,6 +33,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "hard-reg-set.h"
#include "basic-block.h"
@@ -46,6 +48,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "params.h"
#include "tm_p.h"
#include "target.h"
+#include "expr.h"
/* cleanup_cfg maintains following flags for each basic block. */
@@ -65,36 +68,29 @@ enum bb_flags
#define FORWARDER_BLOCK_P(BB) (BB_FLAGS (BB) & BB_FORWARDER_BLOCK)
-static bool try_crossjump_to_edge PARAMS ((int, edge, edge));
-static bool try_crossjump_bb PARAMS ((int, basic_block));
-static bool outgoing_edges_match PARAMS ((int,
- basic_block, basic_block));
-static int flow_find_cross_jump PARAMS ((int, basic_block, basic_block,
- rtx *, rtx *));
-static bool insns_match_p PARAMS ((int, rtx, rtx));
-
-static bool label_is_jump_target_p PARAMS ((rtx, rtx));
-static bool tail_recursion_label_p PARAMS ((rtx));
-static void merge_blocks_move_predecessor_nojumps PARAMS ((basic_block,
- basic_block));
-static void merge_blocks_move_successor_nojumps PARAMS ((basic_block,
- basic_block));
-static bool merge_blocks PARAMS ((edge,basic_block,basic_block,
- int));
-static bool try_optimize_cfg PARAMS ((int));
-static bool try_simplify_condjump PARAMS ((basic_block));
-static bool try_forward_edges PARAMS ((int, basic_block));
-static edge thread_jump PARAMS ((int, edge, basic_block));
-static bool mark_effect PARAMS ((rtx, bitmap));
-static void notice_new_block PARAMS ((basic_block));
-static void update_forwarder_flag PARAMS ((basic_block));
-static int mentions_nonequal_regs PARAMS ((rtx *, void *));
+static bool try_crossjump_to_edge (int, edge, edge);
+static bool try_crossjump_bb (int, basic_block);
+static bool outgoing_edges_match (int, basic_block, basic_block);
+static int flow_find_cross_jump (int, basic_block, basic_block, rtx *, rtx *);
+static bool insns_match_p (int, rtx, rtx);
+
+static bool tail_recursion_label_p (rtx);
+static void merge_blocks_move_predecessor_nojumps (basic_block, basic_block);
+static void merge_blocks_move_successor_nojumps (basic_block, basic_block);
+static bool try_optimize_cfg (int);
+static bool try_simplify_condjump (basic_block);
+static bool try_forward_edges (int, basic_block);
+static edge thread_jump (int, edge, basic_block);
+static bool mark_effect (rtx, bitmap);
+static void notice_new_block (basic_block);
+static void update_forwarder_flag (basic_block);
+static int mentions_nonequal_regs (rtx *, void *);
+static void merge_memattrs (rtx, rtx);
/* Set flags for newly created block. */
static void
-notice_new_block (bb)
- basic_block bb;
+notice_new_block (basic_block bb)
{
if (!bb)
return;
@@ -106,8 +102,7 @@ notice_new_block (bb)
/* Recompute forwarder flag after block has been modified. */
static void
-update_forwarder_flag (bb)
- basic_block bb;
+update_forwarder_flag (basic_block bb)
{
if (forwarder_block_p (bb))
BB_SET_FLAG (bb, BB_FORWARDER_BLOCK);
@@ -119,8 +114,7 @@ update_forwarder_flag (bb)
Return true if something changed. */
static bool
-try_simplify_condjump (cbranch_block)
- basic_block cbranch_block;
+try_simplify_condjump (basic_block cbranch_block)
{
basic_block jump_block, jump_dest_block, cbranch_dest_block;
edge cbranch_jump_edge, cbranch_fallthru_edge;
@@ -136,7 +130,7 @@ try_simplify_condjump (cbranch_block)
/* Verify that we've got a normal conditional branch at the end
of the block. */
- cbranch_insn = cbranch_block->end;
+ cbranch_insn = BB_END (cbranch_block);
if (!any_condjump_p (cbranch_insn))
return false;
@@ -166,7 +160,7 @@ try_simplify_condjump (cbranch_block)
if (rtl_dump_file)
fprintf (rtl_dump_file, "Simplifying condjump %i around jump %i\n",
- INSN_UID (cbranch_insn), INSN_UID (jump_block->end));
+ INSN_UID (cbranch_insn), INSN_UID (BB_END (jump_block)));
/* Success. Update the CFG to match. Note that after this point
the edge variable names appear backwards; the redirection is done
@@ -179,19 +173,19 @@ try_simplify_condjump (cbranch_block)
cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU;
update_br_prob_note (cbranch_block);
- end = jump_block->end;
+ end = BB_END (jump_block);
/* Deleting a block may produce unreachable code warning even when we are
- not deleting anything live. Supress it by moving all the line number
+ not deleting anything live. Suppress it by moving all the line number
notes out of the block. */
- for (insn = jump_block->head; insn != NEXT_INSN (jump_block->end);
+ for (insn = BB_HEAD (jump_block); insn != NEXT_INSN (BB_END (jump_block));
insn = next)
{
next = NEXT_INSN (insn);
if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
{
- if (insn == jump_block->end)
+ if (insn == BB_END (jump_block))
{
- jump_block->end = PREV_INSN (insn);
+ BB_END (jump_block) = PREV_INSN (insn);
if (insn == end)
break;
}
@@ -200,7 +194,7 @@ try_simplify_condjump (cbranch_block)
}
}
/* Delete the block with the unconditional jump, and clean up the mess. */
- flow_delete_block (jump_block);
+ delete_block (jump_block);
tidy_fallthru_edge (cbranch_jump_edge, cbranch_block, cbranch_dest_block);
return true;
@@ -210,9 +204,7 @@ try_simplify_condjump (cbranch_block)
on register. Used by jump threading. */
static bool
-mark_effect (exp, nonequal)
- rtx exp;
- regset nonequal;
+mark_effect (rtx exp, regset nonequal)
{
int regno;
rtx dest;
@@ -258,12 +250,10 @@ mark_effect (exp, nonequal)
}
}
-/* Return nonzero if X is an register set in regset DATA.
+/* Return nonzero if X is a register set in regset DATA.
Called via for_each_rtx. */
static int
-mentions_nonequal_regs (x, data)
- rtx *x;
- void *data;
+mentions_nonequal_regs (rtx *x, void *data)
{
regset nonequal = (regset) data;
if (REG_P (*x))
@@ -284,14 +274,11 @@ mentions_nonequal_regs (x, data)
return 0;
}
/* Attempt to prove that the basic block B will have no side effects and
- allways continues in the same edge if reached via E. Return the edge
+ always continues in the same edge if reached via E. Return the edge
if exist, NULL otherwise. */
static edge
-thread_jump (mode, e, b)
- int mode;
- edge e;
- basic_block b;
+thread_jump (int mode, edge e, basic_block b)
{
rtx set1, set2, cond1, cond2, insn;
enum rtx_code code1, code2, reversed_code2;
@@ -314,17 +301,17 @@ thread_jump (mode, e, b)
}
/* Second branch must end with onlyjump, as we will eliminate the jump. */
- if (!any_condjump_p (e->src->end))
+ if (!any_condjump_p (BB_END (e->src)))
return NULL;
- if (!any_condjump_p (b->end) || !onlyjump_p (b->end))
+ if (!any_condjump_p (BB_END (b)) || !onlyjump_p (BB_END (b)))
{
BB_SET_FLAG (b, BB_NONTHREADABLE_BLOCK);
return NULL;
}
- set1 = pc_set (e->src->end);
- set2 = pc_set (b->end);
+ set1 = pc_set (BB_END (e->src));
+ set2 = pc_set (BB_END (b));
if (((e->flags & EDGE_FALLTHRU) != 0)
!= (XEXP (SET_SRC (set1), 1) == pc_rtx))
reverse1 = true;
@@ -332,19 +319,19 @@ thread_jump (mode, e, b)
cond1 = XEXP (SET_SRC (set1), 0);
cond2 = XEXP (SET_SRC (set2), 0);
if (reverse1)
- code1 = reversed_comparison_code (cond1, e->src->end);
+ code1 = reversed_comparison_code (cond1, BB_END (e->src));
else
code1 = GET_CODE (cond1);
code2 = GET_CODE (cond2);
- reversed_code2 = reversed_comparison_code (cond2, b->end);
+ reversed_code2 = reversed_comparison_code (cond2, BB_END (b));
if (!comparison_dominates_p (code1, code2)
&& !comparison_dominates_p (code1, reversed_code2))
return NULL;
/* Ensure that the comparison operators are equivalent.
- ??? This is far too pesimistic. We should allow swapped operands,
+ ??? This is far too pessimistic. We should allow swapped operands,
different CCmodes, or for example comparisons for interval, that
dominate even when operands are not equivalent. */
if (!rtx_equal_p (XEXP (cond1, 0), XEXP (cond2, 0))
@@ -353,7 +340,7 @@ thread_jump (mode, e, b)
/* Short circuit cases where block B contains some side effects, as we can't
safely bypass it. */
- for (insn = NEXT_INSN (b->head); insn != NEXT_INSN (b->end);
+ for (insn = NEXT_INSN (BB_HEAD (b)); insn != NEXT_INSN (BB_END (b));
insn = NEXT_INSN (insn))
if (INSN_P (insn) && side_effects_p (PATTERN (insn)))
{
@@ -364,7 +351,7 @@ thread_jump (mode, e, b)
cselib_init ();
/* First process all values computed in the source basic block. */
- for (insn = NEXT_INSN (e->src->head); insn != NEXT_INSN (e->src->end);
+ for (insn = NEXT_INSN (BB_HEAD (e->src)); insn != NEXT_INSN (BB_END (e->src));
insn = NEXT_INSN (insn))
if (INSN_P (insn))
cselib_process_insn (insn);
@@ -376,7 +363,7 @@ thread_jump (mode, e, b)
processing as if it were same basic block.
Our goal is to prove that whole block is an NOOP. */
- for (insn = NEXT_INSN (b->head); insn != NEXT_INSN (b->end) && !failed;
+ for (insn = NEXT_INSN (BB_HEAD (b)); insn != NEXT_INSN (BB_END (b)) && !failed;
insn = NEXT_INSN (insn))
{
if (INSN_P (insn))
@@ -433,9 +420,7 @@ failed_exit:
Return true if successful. */
static bool
-try_forward_edges (mode, b)
- basic_block b;
- int mode;
+try_forward_edges (int mode, basic_block b)
{
bool changed = false;
edge e, next, *threaded_edges = NULL;
@@ -525,7 +510,7 @@ try_forward_edges (mode, b)
if ((mode & CLEANUP_PRE_LOOP) && optimize)
{
rtx insn = (target->succ->flags & EDGE_FALLTHRU
- ? target->head : prev_nonnote_insn (target->end));
+ ? BB_HEAD (target) : prev_nonnote_insn (BB_END (target)));
if (GET_CODE (insn) != NOTE)
insn = NEXT_INSN (insn);
@@ -543,7 +528,7 @@ try_forward_edges (mode, b)
at this time; it can mess up the loop optimizer's
recognition of some patterns. */
- insn = PREV_INSN (target->head);
+ insn = PREV_INSN (BB_HEAD (target));
if (insn && GET_CODE (insn) == NOTE
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
break;
@@ -662,43 +647,10 @@ try_forward_edges (mode, b)
return changed;
}
-/* Return true if LABEL is a target of JUMP_INSN. This applies only
- to non-complex jumps. That is, direct unconditional, conditional,
- and tablejumps, but not computed jumps or returns. It also does
- not apply to the fallthru case of a conditional jump. */
-
-static bool
-label_is_jump_target_p (label, jump_insn)
- rtx label, jump_insn;
-{
- rtx tmp = JUMP_LABEL (jump_insn);
-
- if (label == tmp)
- return true;
-
- if (tmp != NULL_RTX
- && (tmp = NEXT_INSN (tmp)) != NULL_RTX
- && GET_CODE (tmp) == JUMP_INSN
- && (tmp = PATTERN (tmp),
- GET_CODE (tmp) == ADDR_VEC
- || GET_CODE (tmp) == ADDR_DIFF_VEC))
- {
- rtvec vec = XVEC (tmp, GET_CODE (tmp) == ADDR_DIFF_VEC);
- int i, veclen = GET_NUM_ELEM (vec);
-
- for (i = 0; i < veclen; ++i)
- if (XEXP (RTVEC_ELT (vec, i), 0) == label)
- return true;
- }
-
- return false;
-}
-
/* Return true if LABEL is used for tail recursion. */
static bool
-tail_recursion_label_p (label)
- rtx label;
+tail_recursion_label_p (rtx label)
{
rtx x;
@@ -714,12 +666,11 @@ tail_recursion_label_p (label)
any jumps (aside from the jump from A to B). */
static void
-merge_blocks_move_predecessor_nojumps (a, b)
- basic_block a, b;
+merge_blocks_move_predecessor_nojumps (basic_block a, basic_block b)
{
rtx barrier;
- barrier = next_nonnote_insn (a->end);
+ barrier = next_nonnote_insn (BB_END (a));
if (GET_CODE (barrier) != BARRIER)
abort ();
delete_insn (barrier);
@@ -731,12 +682,12 @@ merge_blocks_move_predecessor_nojumps (a, b)
and adjust the block trees appropriately. Even better would be to have
a tighter connection between block trees and rtl so that this is not
necessary. */
- if (squeeze_notes (&a->head, &a->end))
+ if (squeeze_notes (&BB_HEAD (a), &BB_END (a)))
abort ();
/* Scramble the insn chain. */
- if (a->end != PREV_INSN (b->head))
- reorder_insns_nobb (a->head, a->end, PREV_INSN (b->head));
+ if (BB_END (a) != PREV_INSN (BB_HEAD (b)))
+ reorder_insns_nobb (BB_HEAD (a), BB_END (a), PREV_INSN (BB_HEAD (b)));
a->flags |= BB_DIRTY;
if (rtl_dump_file)
@@ -749,7 +700,7 @@ merge_blocks_move_predecessor_nojumps (a, b)
link_block (a, b->prev_bb);
/* Now blocks A and B are contiguous. Merge them. */
- merge_blocks_nomove (a, b);
+ merge_blocks (a, b);
}
/* Blocks A and B are to be merged into a single block. B has no outgoing
@@ -757,29 +708,23 @@ merge_blocks_move_predecessor_nojumps (a, b)
any jumps (aside from the jump from A to B). */
static void
-merge_blocks_move_successor_nojumps (a, b)
- basic_block a, b;
+merge_blocks_move_successor_nojumps (basic_block a, basic_block b)
{
rtx barrier, real_b_end;
+ rtx label, table;
- real_b_end = b->end;
- barrier = NEXT_INSN (b->end);
+ real_b_end = BB_END (b);
- /* Recognize a jump table following block B. */
- if (barrier
- && GET_CODE (barrier) == CODE_LABEL
- && NEXT_INSN (barrier)
- && GET_CODE (NEXT_INSN (barrier)) == JUMP_INSN
- && (GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_VEC
- || GET_CODE (PATTERN (NEXT_INSN (barrier))) == ADDR_DIFF_VEC))
+ /* If there is a jump table following block B temporarily add the jump table
+ to block B so that it will also be moved to the correct location. */
+ if (tablejump_p (BB_END (b), &label, &table)
+ && prev_active_insn (label) == BB_END (b))
{
- /* Temporarily add the table jump insn to b, so that it will also
- be moved to the correct location. */
- b->end = NEXT_INSN (barrier);
- barrier = NEXT_INSN (b->end);
+ BB_END (b) = table;
}
/* There had better have been a barrier there. Delete it. */
+ barrier = NEXT_INSN (BB_END (b));
if (barrier && GET_CODE (barrier) == BARRIER)
delete_insn (barrier);
@@ -790,53 +735,60 @@ merge_blocks_move_successor_nojumps (a, b)
and adjust the block trees appropriately. Even better would be to have
a tighter connection between block trees and rtl so that this is not
necessary. */
- if (squeeze_notes (&b->head, &b->end))
+ if (squeeze_notes (&BB_HEAD (b), &BB_END (b)))
abort ();
/* Scramble the insn chain. */
- reorder_insns_nobb (b->head, b->end, a->end);
+ reorder_insns_nobb (BB_HEAD (b), BB_END (b), BB_END (a));
/* Restore the real end of b. */
- b->end = real_b_end;
+ BB_END (b) = real_b_end;
if (rtl_dump_file)
fprintf (rtl_dump_file, "Moved block %d after %d and merged.\n",
b->index, a->index);
/* Now blocks A and B are contiguous. Merge them. */
- merge_blocks_nomove (a, b);
+ merge_blocks (a, b);
}
/* Attempt to merge basic blocks that are potentially non-adjacent.
- Return true iff the attempt succeeded. */
-
-static bool
-merge_blocks (e, b, c, mode)
- edge e;
- basic_block b, c;
- int mode;
+ Return NULL iff the attempt failed, otherwise return basic block
+ where cleanup_cfg should continue. Because the merging commonly
+ moves basic block away or introduces another optimization
+ possibility, return basic block just before B so cleanup_cfg don't
+ need to iterate.
+
+ It may be good idea to return basic block before C in the case
+ C has been moved after B and originally appeared earlier in the
+ insn sequence, but we have no information available about the
+ relative ordering of these two. Hopefully it is not too common. */
+
+static basic_block
+merge_blocks_move (edge e, basic_block b, basic_block c, int mode)
{
+ basic_block next;
/* If C has a tail recursion label, do not merge. There is no
edge recorded from the call_placeholder back to this label, as
that would make optimize_sibling_and_tail_recursive_calls more
complex for no gain. */
if ((mode & CLEANUP_PRE_SIBCALL)
- && GET_CODE (c->head) == CODE_LABEL
- && tail_recursion_label_p (c->head))
- return false;
+ && GET_CODE (BB_HEAD (c)) == CODE_LABEL
+ && tail_recursion_label_p (BB_HEAD (c)))
+ return NULL;
/* If B has a fallthru edge to C, no need to move anything. */
if (e->flags & EDGE_FALLTHRU)
{
int b_index = b->index, c_index = c->index;
- merge_blocks_nomove (b, c);
+ merge_blocks (b, c);
update_forwarder_flag (b);
if (rtl_dump_file)
fprintf (rtl_dump_file, "Merged %d and %d without moving.\n",
b_index, c_index);
- return true;
+ return b->prev_bb == ENTRY_BLOCK_PTR ? b : b->prev_bb;
}
/* Otherwise we will need to move code around. Do that only if expensive
@@ -852,7 +804,7 @@ merge_blocks (e, b, c, mode)
been if B is a forwarder block and C has no fallthru edge, but
that should be cleaned up by bb-reorder instead. */
if (FORWARDER_BLOCK_P (b) || FORWARDER_BLOCK_P (c))
- return false;
+ return NULL;
/* We must make sure to not munge nesting of lexical blocks,
and loop notes. This is done by squeezing out all the notes
@@ -870,6 +822,9 @@ merge_blocks (e, b, c, mode)
b_has_incoming_fallthru = (tmp_edge != NULL);
b_fallthru_edge = tmp_edge;
+ next = b->prev_bb;
+ if (next == c)
+ next = next->prev_bb;
/* Otherwise, we're going to try to move C after B. If C does
not have an outgoing fallthru, then it can be moved
@@ -877,7 +832,7 @@ merge_blocks (e, b, c, mode)
if (! c_has_outgoing_fallthru)
{
merge_blocks_move_successor_nojumps (b, c);
- return true;
+ return next == ENTRY_BLOCK_PTR ? next->next_bb : next;
}
/* If B does not have an incoming fallthru, then it can be moved
@@ -890,26 +845,106 @@ merge_blocks (e, b, c, mode)
basic_block bb;
if (b_fallthru_edge->src == ENTRY_BLOCK_PTR)
- return false;
+ return NULL;
bb = force_nonfallthru (b_fallthru_edge);
if (bb)
notice_new_block (bb);
}
merge_blocks_move_predecessor_nojumps (b, c);
- return true;
+ return next == ENTRY_BLOCK_PTR ? next->next_bb : next;
}
- return false;
+ return NULL;
}
+/* Removes the memory attributes of MEM expression
+ if they are not equal. */
+
+void
+merge_memattrs (rtx x, rtx y)
+{
+ int i;
+ int j;
+ enum rtx_code code;
+ const char *fmt;
+
+ if (x == y)
+ return;
+ if (x == 0 || y == 0)
+ return;
+
+ code = GET_CODE (x);
+
+ if (code != GET_CODE (y))
+ return;
+
+ if (GET_MODE (x) != GET_MODE (y))
+ return;
+
+ if (code == MEM && MEM_ATTRS (x) != MEM_ATTRS (y))
+ {
+ if (! MEM_ATTRS (x))
+ MEM_ATTRS (y) = 0;
+ else if (! MEM_ATTRS (y))
+ MEM_ATTRS (x) = 0;
+ else
+ {
+ if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
+ {
+ set_mem_alias_set (x, 0);
+ set_mem_alias_set (y, 0);
+ }
+
+ if (! mem_expr_equal_p (MEM_EXPR (x), MEM_EXPR (y)))
+ {
+ set_mem_expr (x, 0);
+ set_mem_expr (y, 0);
+ set_mem_offset (x, 0);
+ set_mem_offset (y, 0);
+ }
+ else if (MEM_OFFSET (x) != MEM_OFFSET (y))
+ {
+ set_mem_offset (x, 0);
+ set_mem_offset (y, 0);
+ }
+
+ set_mem_size (x, MAX (MEM_SIZE (x), MEM_SIZE (y)));
+ set_mem_size (y, MEM_SIZE (x));
+
+ set_mem_align (x, MIN (MEM_ALIGN (x), MEM_ALIGN (y)));
+ set_mem_align (y, MEM_ALIGN (x));
+ }
+ }
+
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ switch (fmt[i])
+ {
+ case 'E':
+ /* Two vectors must have the same length. */
+ if (XVECLEN (x, i) != XVECLEN (y, i))
+ return;
+
+ for (j = 0; j < XVECLEN (x, i); j++)
+ merge_memattrs (XVECEXP (x, i, j), XVECEXP (y, i, j));
+
+ break;
+
+ case 'e':
+ merge_memattrs (XEXP (x, i), XEXP (y, i));
+ }
+ }
+ return;
+}
+
+
/* Return true if I1 and I2 are equivalent and thus can be crossjumped. */
static bool
-insns_match_p (mode, i1, i2)
- int mode ATTRIBUTE_UNUSED;
- rtx i1, i2;
+insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
{
rtx p1, p2;
@@ -974,7 +1009,15 @@ insns_match_p (mode, i1, i2)
#endif
if (reload_completed
- ? ! rtx_renumbered_equal_p (p1, p2) : ! rtx_equal_p (p1, p2))
+ ? 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);
@@ -1001,11 +1044,9 @@ insns_match_p (mode, i1, i2)
return true;
}
}
-
- return false;
}
- return true;
+ return false;
}
/* Look through the insns at the end of BB1 and BB2 and find the longest
@@ -1016,10 +1057,8 @@ insns_match_p (mode, i1, i2)
store the head of the blocks in *F1 and *F2. */
static int
-flow_find_cross_jump (mode, bb1, bb2, f1, f2)
- int mode ATTRIBUTE_UNUSED;
- basic_block bb1, bb2;
- rtx *f1, *f2;
+flow_find_cross_jump (int mode ATTRIBUTE_UNUSED, basic_block bb1,
+ basic_block bb2, rtx *f1, rtx *f2)
{
rtx i1, i2, last1, last2, afterlast1, afterlast2;
int ninsns = 0;
@@ -1027,7 +1066,7 @@ flow_find_cross_jump (mode, bb1, bb2, f1, f2)
/* Skip simple jumps at the end of the blocks. Complex jumps still
need to be compared for equivalence, which we'll do below. */
- i1 = bb1->end;
+ i1 = BB_END (bb1);
last1 = afterlast1 = last2 = afterlast2 = NULL_RTX;
if (onlyjump_p (i1)
|| (returnjump_p (i1) && !side_effects_p (PATTERN (i1))))
@@ -1036,7 +1075,7 @@ flow_find_cross_jump (mode, bb1, bb2, f1, f2)
i1 = PREV_INSN (i1);
}
- i2 = bb2->end;
+ i2 = BB_END (bb2);
if (onlyjump_p (i2)
|| (returnjump_p (i2) && !side_effects_p (PATTERN (i2))))
{
@@ -1050,18 +1089,20 @@ flow_find_cross_jump (mode, bb1, bb2, f1, f2)
while (true)
{
/* Ignore notes. */
- while (!INSN_P (i1) && i1 != bb1->head)
+ while (!INSN_P (i1) && i1 != BB_HEAD (bb1))
i1 = PREV_INSN (i1);
- while (!INSN_P (i2) && i2 != bb2->head)
+ while (!INSN_P (i2) && i2 != BB_HEAD (bb2))
i2 = PREV_INSN (i2);
- if (i1 == bb1->head || i2 == bb2->head)
+ if (i1 == BB_HEAD (bb1) || i2 == BB_HEAD (bb2))
break;
if (!insns_match_p (mode, i1, i2))
break;
+ merge_memattrs (i1, i2);
+
/* Don't begin a cross-jump with a NOTE insn. */
if (INSN_P (i1))
{
@@ -1102,16 +1143,16 @@ flow_find_cross_jump (mode, bb1, bb2, f1, f2)
Two, it keeps line number notes as matched as may be. */
if (ninsns)
{
- while (last1 != bb1->head && !INSN_P (PREV_INSN (last1)))
+ while (last1 != BB_HEAD (bb1) && !INSN_P (PREV_INSN (last1)))
last1 = PREV_INSN (last1);
- if (last1 != bb1->head && GET_CODE (PREV_INSN (last1)) == CODE_LABEL)
+ if (last1 != BB_HEAD (bb1) && GET_CODE (PREV_INSN (last1)) == CODE_LABEL)
last1 = PREV_INSN (last1);
- while (last2 != bb2->head && !INSN_P (PREV_INSN (last2)))
+ while (last2 != BB_HEAD (bb2) && !INSN_P (PREV_INSN (last2)))
last2 = PREV_INSN (last2);
- if (last2 != bb2->head && GET_CODE (PREV_INSN (last2)) == CODE_LABEL)
+ if (last2 != BB_HEAD (bb2) && GET_CODE (PREV_INSN (last2)) == CODE_LABEL)
last2 = PREV_INSN (last2);
*f1 = last1;
@@ -1128,10 +1169,7 @@ flow_find_cross_jump (mode, bb1, bb2, f1, f2)
We may assume that there exists one edge with a common destination. */
static bool
-outgoing_edges_match (mode, bb1, bb2)
- int mode;
- basic_block bb1;
- basic_block bb2;
+outgoing_edges_match (int mode, basic_block bb1, basic_block bb2)
{
int nehedges1 = 0, nehedges2 = 0;
edge fallthru1 = 0, fallthru2 = 0;
@@ -1141,18 +1179,18 @@ outgoing_edges_match (mode, bb1, bb2)
unconditional jump, or a fake edge to exit. */
if (bb1->succ && !bb1->succ->succ_next
&& (bb1->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0
- && (GET_CODE (bb1->end) != JUMP_INSN || simplejump_p (bb1->end)))
+ && (GET_CODE (BB_END (bb1)) != JUMP_INSN || simplejump_p (BB_END (bb1))))
return (bb2->succ && !bb2->succ->succ_next
&& (bb2->succ->flags & (EDGE_COMPLEX | EDGE_FAKE)) == 0
- && (GET_CODE (bb2->end) != JUMP_INSN || simplejump_p (bb2->end)));
+ && (GET_CODE (BB_END (bb2)) != JUMP_INSN || simplejump_p (BB_END (bb2))));
/* Match conditional jumps - this may get tricky when fallthru and branch
edges are crossed. */
if (bb1->succ
&& bb1->succ->succ_next
&& !bb1->succ->succ_next->succ_next
- && any_condjump_p (bb1->end)
- && onlyjump_p (bb1->end))
+ && any_condjump_p (BB_END (bb1))
+ && onlyjump_p (BB_END (bb1)))
{
edge b1, f1, b2, f2;
bool reverse, match;
@@ -1162,19 +1200,8 @@ outgoing_edges_match (mode, bb1, bb2)
if (!bb2->succ
|| !bb2->succ->succ_next
|| bb2->succ->succ_next->succ_next
- || !any_condjump_p (bb2->end)
- || !onlyjump_p (bb2->end))
- return false;
-
- /* Do not crossjump across loop boundaries. This is a temporary
- workaround for the common scenario in which crossjumping results
- in killing the duplicated loop condition, making bb-reorder rotate
- the loop incorectly, leaving an extra unconditional jump inside
- the loop.
-
- This check should go away once bb-reorder knows how to duplicate
- code in this case or rotate the loops to avoid this scenario. */
- if (bb1->loop_depth != bb2->loop_depth)
+ || !any_condjump_p (BB_END (bb2))
+ || !onlyjump_p (BB_END (bb2)))
return false;
b1 = BRANCH_EDGE (bb1);
@@ -1206,8 +1233,8 @@ outgoing_edges_match (mode, bb1, bb2)
else
return false;
- set1 = pc_set (bb1->end);
- set2 = pc_set (bb2->end);
+ set1 = pc_set (BB_END (bb1));
+ set2 = pc_set (BB_END (bb2));
if ((XEXP (SET_SRC (set1), 1) == pc_rtx)
!= (XEXP (SET_SRC (set2), 1) == pc_rtx))
reverse = !reverse;
@@ -1216,7 +1243,7 @@ outgoing_edges_match (mode, bb1, bb2)
cond2 = XEXP (SET_SRC (set2), 0);
code1 = GET_CODE (cond1);
if (reverse)
- code2 = reversed_comparison_code (cond2, bb2->end);
+ code2 = reversed_comparison_code (cond2, BB_END (bb2));
else
code2 = GET_CODE (cond2);
@@ -1274,11 +1301,85 @@ outgoing_edges_match (mode, bb1, bb2)
/* Generic case - we are seeing a computed jump, table jump or trapping
instruction. */
+#ifndef CASE_DROPS_THROUGH
+ /* Check whether there are tablejumps in the end of BB1 and BB2.
+ Return true if they are identical. */
+ {
+ rtx label1, label2;
+ rtx table1, table2;
+
+ if (tablejump_p (BB_END (bb1), &label1, &table1)
+ && tablejump_p (BB_END (bb2), &label2, &table2)
+ && GET_CODE (PATTERN (table1)) == GET_CODE (PATTERN (table2)))
+ {
+ /* The labels should never be the same rtx. If they really are same
+ the jump tables are same too. So disable crossjumping of blocks BB1
+ and BB2 because when deleting the common insns in the end of BB1
+ by delete_block () the jump table would be deleted too. */
+ /* If LABEL2 is referenced in BB1->END do not do anything
+ because we would loose information when replacing
+ LABEL1 by LABEL2 and then LABEL2 by LABEL1 in BB1->END. */
+ if (label1 != label2 && !rtx_referenced_p (label2, BB_END (bb1)))
+ {
+ /* Set IDENTICAL to true when the tables are identical. */
+ bool identical = false;
+ rtx p1, p2;
+
+ p1 = PATTERN (table1);
+ p2 = PATTERN (table2);
+ if (GET_CODE (p1) == ADDR_VEC && rtx_equal_p (p1, p2))
+ {
+ identical = true;
+ }
+ else if (GET_CODE (p1) == ADDR_DIFF_VEC
+ && (XVECLEN (p1, 1) == XVECLEN (p2, 1))
+ && rtx_equal_p (XEXP (p1, 2), XEXP (p2, 2))
+ && rtx_equal_p (XEXP (p1, 3), XEXP (p2, 3)))
+ {
+ int i;
+
+ identical = true;
+ for (i = XVECLEN (p1, 1) - 1; i >= 0 && identical; i--)
+ if (!rtx_equal_p (XVECEXP (p1, 1, i), XVECEXP (p2, 1, i)))
+ identical = false;
+ }
+
+ if (identical)
+ {
+ replace_label_data rr;
+ bool match;
+
+ /* Temporarily replace references to LABEL1 with LABEL2
+ in BB1->END so that we could compare the instructions. */
+ rr.r1 = label1;
+ rr.r2 = label2;
+ rr.update_label_nuses = false;
+ for_each_rtx (&BB_END (bb1), replace_label, &rr);
+
+ match = insns_match_p (mode, BB_END (bb1), BB_END (bb2));
+ if (rtl_dump_file && match)
+ fprintf (rtl_dump_file,
+ "Tablejumps in bb %i and %i match.\n",
+ bb1->index, bb2->index);
+
+ /* Set the original label in BB1->END because when deleting
+ a block whose end is a tablejump, the tablejump referenced
+ from the instruction is deleted too. */
+ rr.r1 = label2;
+ rr.r2 = label1;
+ for_each_rtx (&BB_END (bb1), replace_label, &rr);
+
+ return match;
+ }
+ }
+ return false;
+ }
+ }
+#endif
+
/* First ensure that the instructions match. There may be many outgoing
- edges so this test is generally cheaper.
- ??? Currently the tablejumps will never match, as they do have
- different tables. */
- if (!insns_match_p (mode, bb1->end, bb2->end))
+ edges so this test is generally cheaper. */
+ if (!insns_match_p (mode, BB_END (bb1), BB_END (bb2)))
return false;
/* Search the outgoing edges, ensure that the counts do match, find possible
@@ -1317,17 +1418,19 @@ outgoing_edges_match (mode, bb1, bb2)
return false;
}
- /* In case we do have EH edges, ensure we are in the same region. */
- if (nehedges1)
- {
- rtx n1 = find_reg_note (bb1->end, REG_EH_REGION, 0);
- rtx n2 = find_reg_note (bb2->end, REG_EH_REGION, 0);
+ /* Ensure the same EH region. */
+ {
+ rtx n1 = find_reg_note (BB_END (bb1), REG_EH_REGION, 0);
+ rtx n2 = find_reg_note (BB_END (bb2), REG_EH_REGION, 0);
- if (XEXP (n1, 0) != XEXP (n2, 0))
- return false;
- }
+ if (!n1 && n2)
+ return false;
- /* We don't need to match the rest of edges as above checks should be enought
+ if (n1 && (!n2 || XEXP (n1, 0) != XEXP (n2, 0)))
+ return false;
+ }
+
+ /* We don't need to match the rest of edges as above checks should be enough
to ensure that they are equivalent. */
return true;
}
@@ -1337,9 +1440,7 @@ outgoing_edges_match (mode, bb1, bb2)
(maybe the middle of) E1->SRC to (maybe the middle of) E2->SRC. */
static bool
-try_crossjump_to_edge (mode, e1, e2)
- int mode;
- edge e1, e2;
+try_crossjump_to_edge (int mode, edge e1, edge e2)
{
int nmatch;
basic_block src1 = e1->src, src2 = e2->src;
@@ -1390,8 +1491,41 @@ try_crossjump_to_edge (mode, e1, e2)
if (!nmatch)
return false;
+#ifndef CASE_DROPS_THROUGH
+ /* Here we know that the insns in the end of SRC1 which are common with SRC2
+ will be deleted.
+ If we have tablejumps in the end of SRC1 and SRC2
+ they have been already compared for equivalence in outgoing_edges_match ()
+ so replace the references to TABLE1 by references to TABLE2. */
+ {
+ rtx label1, label2;
+ rtx table1, table2;
+
+ if (tablejump_p (BB_END (src1), &label1, &table1)
+ && tablejump_p (BB_END (src2), &label2, &table2)
+ && label1 != label2)
+ {
+ replace_label_data rr;
+ rtx insn;
+
+ /* Replace references to LABEL1 with LABEL2. */
+ rr.r1 = label1;
+ rr.r2 = label2;
+ rr.update_label_nuses = true;
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ /* Do not replace the label in SRC1->END because when deleting
+ a block whose end is a tablejump, the tablejump referenced
+ from the instruction is deleted too. */
+ if (insn != BB_END (src1))
+ for_each_rtx (&insn, replace_label, &rr);
+ }
+ }
+ }
+#endif
+
/* Avoid splitting if possible. */
- if (newpos2 == src2->head)
+ if (newpos2 == BB_HEAD (src2))
redirect_to = src2;
else
{
@@ -1478,7 +1612,7 @@ try_crossjump_to_edge (mode, e1, e2)
to_remove = redirect_from->succ->dest;
redirect_edge_and_branch_force (redirect_from->succ, redirect_to);
- flow_delete_block (to_remove);
+ delete_block (to_remove);
update_forwarder_flag (redirect_from);
@@ -1490,9 +1624,7 @@ try_crossjump_to_edge (mode, e1, e2)
any changes made. */
static bool
-try_crossjump_bb (mode, bb)
- int mode;
- basic_block bb;
+try_crossjump_bb (int mode, basic_block bb)
{
edge e, e2, nexte2, nexte, fallthru;
bool changed;
@@ -1585,13 +1717,12 @@ try_crossjump_bb (mode, bb)
instructions etc. Return nonzero if changes were made. */
static bool
-try_optimize_cfg (mode)
- int mode;
+try_optimize_cfg (int mode)
{
bool changed_overall = false;
bool changed;
int iterations = 0;
- basic_block bb, b;
+ basic_block bb, b, next;
if (mode & CLEANUP_CROSSJUMP)
add_noreturn_fake_exit_edges ();
@@ -1631,8 +1762,9 @@ try_optimize_cfg (mode)
fprintf (rtl_dump_file, "Deleting block %i.\n",
b->index);
- flow_delete_block (b);
- changed = true;
+ delete_block (b);
+ if (!(mode & CLEANUP_CFGLAYOUT))
+ changed = true;
b = c;
}
@@ -1642,9 +1774,9 @@ try_optimize_cfg (mode)
if (b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
&& !(b->pred->flags & EDGE_COMPLEX)
- && GET_CODE (b->head) == CODE_LABEL
+ && GET_CODE (BB_HEAD (b)) == CODE_LABEL
&& (!(mode & CLEANUP_PRE_SIBCALL)
- || !tail_recursion_label_p (b->head))
+ || !tail_recursion_label_p (BB_HEAD (b)))
/* If the previous block ends with a branch to this
block, we can't delete the label. Normally this
is a condjump that is yet to be simplified, but
@@ -1652,23 +1784,32 @@ try_optimize_cfg (mode)
some element going to the same place as the
default (fallthru). */
&& (b->pred->src == ENTRY_BLOCK_PTR
- || GET_CODE (b->pred->src->end) != JUMP_INSN
- || ! label_is_jump_target_p (b->head,
- b->pred->src->end)))
+ || GET_CODE (BB_END (b->pred->src)) != JUMP_INSN
+ || ! label_is_jump_target_p (BB_HEAD (b),
+ BB_END (b->pred->src))))
{
- rtx label = b->head;
+ rtx label = BB_HEAD (b);
- b->head = NEXT_INSN (b->head);
delete_insn_chain (label, label);
+ /* In the case label is undeletable, move it after the
+ BASIC_BLOCK note. */
+ if (NOTE_LINE_NUMBER (BB_HEAD (b)) == NOTE_INSN_DELETED_LABEL)
+ {
+ rtx bb_note = NEXT_INSN (BB_HEAD (b));
+
+ reorder_insns_nobb (label, label, bb_note);
+ BB_HEAD (b) = bb_note;
+ }
if (rtl_dump_file)
fprintf (rtl_dump_file, "Deleted label in block %i.\n",
b->index);
}
/* If we fall through an empty block, we can remove it. */
- if (b->pred->pred_next == NULL
+ if (!(mode & CLEANUP_CFGLAYOUT)
+ && b->pred->pred_next == NULL
&& (b->pred->flags & EDGE_FALLTHRU)
- && GET_CODE (b->head) != CODE_LABEL
+ && GET_CODE (BB_HEAD (b)) != CODE_LABEL
&& FORWARDER_BLOCK_P (b)
/* Note that forwarder_block_p true ensures that
there is a successor for this block. */
@@ -1682,42 +1823,61 @@ try_optimize_cfg (mode)
c = b->prev_bb == ENTRY_BLOCK_PTR ? b->next_bb : b->prev_bb;
redirect_edge_succ_nodup (b->pred, b->succ->dest);
- flow_delete_block (b);
+ delete_block (b);
changed = true;
b = c;
}
- /* Merge blocks. Loop because chains of blocks might be
- combineable. */
- while ((s = b->succ) != NULL
- && s->succ_next == NULL
- && !(s->flags & EDGE_COMPLEX)
- && (c = s->dest) != EXIT_BLOCK_PTR
- && c->pred->pred_next == NULL
- && b != c
- /* If the jump insn has side effects,
- we can't kill the edge. */
- && (GET_CODE (b->end) != JUMP_INSN
- || (flow2_completed
- ? simplejump_p (b->end)
- : onlyjump_p (b->end)))
- && merge_blocks (s, b, c, mode))
- changed_here = true;
+ if ((s = b->succ) != NULL
+ && s->succ_next == NULL
+ && !(s->flags & EDGE_COMPLEX)
+ && (c = s->dest) != EXIT_BLOCK_PTR
+ && c->pred->pred_next == NULL
+ && b != c)
+ {
+ /* When not in cfg_layout mode use code aware of reordering
+ INSN. This code possibly creates new basic blocks so it
+ does not fit merge_blocks interface and is kept here in
+ hope that it will become useless once more of compiler
+ is transformed to use cfg_layout mode. */
+
+ if ((mode & CLEANUP_CFGLAYOUT)
+ && can_merge_blocks_p (b, c))
+ {
+ merge_blocks (b, c);
+ update_forwarder_flag (b);
+ changed_here = true;
+ }
+ else if (!(mode & CLEANUP_CFGLAYOUT)
+ /* If the jump insn has side effects,
+ we can't kill the edge. */
+ && (GET_CODE (BB_END (b)) != JUMP_INSN
+ || (reload_completed
+ ? simplejump_p (BB_END (b))
+ : onlyjump_p (BB_END (b))))
+ && (next = merge_blocks_move (s, b, c, mode)))
+ {
+ b = next;
+ changed_here = true;
+ }
+ }
/* Simplify branch over branch. */
- if ((mode & CLEANUP_EXPENSIVE) && try_simplify_condjump (b))
+ if ((mode & CLEANUP_EXPENSIVE)
+ && !(mode & CLEANUP_CFGLAYOUT)
+ && try_simplify_condjump (b))
changed_here = true;
/* If B has a single outgoing edge, but uses a
non-trivial jump instruction without side-effects, we
can either delete the jump entirely, or replace it
- with a simple unconditional jump. Use
- redirect_edge_and_branch to do the dirty work. */
+ with a simple unconditional jump. */
if (b->succ
&& ! b->succ->succ_next
&& b->succ->dest != EXIT_BLOCK_PTR
- && onlyjump_p (b->end)
- && redirect_edge_and_branch (b->succ, b->succ->dest))
+ && onlyjump_p (BB_END (b))
+ && try_redirect_by_replacing_jump (b->succ, b->succ->dest,
+ (mode & CLEANUP_CFGLAYOUT) != 0))
{
update_forwarder_flag (b);
changed_here = true;
@@ -1765,7 +1925,7 @@ try_optimize_cfg (mode)
/* Delete all unreachable basic blocks. */
bool
-delete_unreachable_blocks ()
+delete_unreachable_blocks (void)
{
bool changed = false;
basic_block b, next_bb;
@@ -1780,7 +1940,7 @@ delete_unreachable_blocks ()
if (!(b->flags & BB_REACHABLE))
{
- flow_delete_block (b);
+ delete_block (b);
changed = true;
}
}
@@ -1793,8 +1953,7 @@ delete_unreachable_blocks ()
/* Tidy the CFG by deleting unreachable code and whatnot. */
bool
-cleanup_cfg (mode)
- int mode;
+cleanup_cfg (int mode)
{
bool changed = false;
@@ -1803,7 +1962,7 @@ cleanup_cfg (mode)
{
changed = true;
/* We've possibly created trivially dead code. Cleanup it right
- now to introduce more oppurtunities for try_optimize_cfg. */
+ now to introduce more opportunities for try_optimize_cfg. */
if (!(mode & (CLEANUP_NO_INSN_DEL
| CLEANUP_UPDATE_LIFE | CLEANUP_PRE_SIBCALL))
&& !reload_completed)
@@ -1817,14 +1976,15 @@ cleanup_cfg (mode)
delete_unreachable_blocks (), changed = true;
if (mode & CLEANUP_UPDATE_LIFE)
{
- /* Cleaning up CFG introduces more oppurtunities for dead code
- removal that in turn may introduce more oppurtunities for
+ /* Cleaning up CFG introduces more opportunities for dead code
+ removal that in turn may introduce more opportunities for
cleaning up the CFG. */
if (!update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
PROP_DEATH_NOTES
| PROP_SCAN_DEAD_CODE
| PROP_KILL_DEAD_CODE
- | PROP_LOG_LINKS))
+ | ((mode & CLEANUP_LOG_LINKS)
+ ? PROP_LOG_LINKS : 0)))
break;
}
else if (!(mode & (CLEANUP_NO_INSN_DEL | CLEANUP_PRE_SIBCALL))
diff --git a/contrib/gcc/cfghooks.c b/contrib/gcc/cfghooks.c
new file mode 100644
index 000000000000..525289c04f84
--- /dev/null
+++ b/contrib/gcc/cfghooks.c
@@ -0,0 +1,48 @@
+/* Hooks for cfg representation specific functions.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by Sebastian Pop <s.pop@laposte.net>
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "basic-block.h"
+
+extern struct cfg_hooks rtl_cfg_hooks;
+extern struct cfg_hooks cfg_layout_rtl_cfg_hooks;
+
+/* A pointer to one of the hooks containers. */
+struct cfg_hooks *cfg_hooks;
+
+/* Initialization of functions specific to the rtl IR. */
+void
+rtl_register_cfg_hooks (void)
+{
+ cfg_hooks = &rtl_cfg_hooks;
+}
+
+/* Initialization of functions specific to the rtl IR. */
+void
+cfg_layout_rtl_register_cfg_hooks (void)
+{
+ cfg_hooks = &cfg_layout_rtl_cfg_hooks;
+}
diff --git a/contrib/gcc/cfghooks.h b/contrib/gcc/cfghooks.h
new file mode 100644
index 000000000000..5ef3b1f5480f
--- /dev/null
+++ b/contrib/gcc/cfghooks.h
@@ -0,0 +1,83 @@
+/* Hooks for cfg representation specific functions.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by Sebastian Pop <s.pop@laposte.net>
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef GCC_CFGHOOKS_H
+#define GCC_CFGHOOKS_H
+
+struct cfg_hooks
+{
+ /* Debugging. Do not use macros to hook these so they can be called from
+ debugger! */
+ int (*cfgh_verify_flow_info) (void);
+ void (*dump_bb) (basic_block, FILE *);
+
+ /* Basic CFG manipulation. */
+
+ /* Return new basic block. */
+ basic_block (*create_basic_block) (void *head, void *end, basic_block after);
+
+ /* Redirect edge E to the given basic block B and update underlying program
+ representation. Returns false when edge is not easily redirectable for
+ whatever reason. */
+ bool (*redirect_edge_and_branch) (edge e, basic_block b);
+
+ /* Same as the above but allows redirecting of fallthru edges. In that case
+ newly created forwarder basic block is returned. It aborts when called
+ on abnormal edge. */
+ basic_block (*redirect_edge_and_branch_force) (edge, basic_block);
+
+ /* Remove given basic block and all edges possibly pointing into it. */
+ void (*delete_block) (basic_block);
+
+ /* Split basic block B after specified instruction I. */
+ edge (*split_block) (basic_block b, void * i);
+
+ /* Return true when blocks A and B can be merged into single basic block. */
+ bool (*can_merge_blocks_p) (basic_block a, basic_block b);
+
+ /* Merge blocks A and B. */
+ void (*merge_blocks) (basic_block a, basic_block b);
+
+ /* Higher level functions representable by primitive operations above if
+ we didn't have some oddities in RTL and Tree representations. */
+ basic_block (*cfgh_split_edge) (edge);
+};
+
+#define redirect_edge_and_branch(e,b) cfg_hooks->redirect_edge_and_branch (e,b)
+#define redirect_edge_and_branch_force(e,b) cfg_hooks->redirect_edge_and_branch_force (e,b)
+#define split_block(e,i) cfg_hooks->split_block (e,i)
+#define delete_block(b) cfg_hooks->delete_block (b)
+#define split_edge(e) cfg_hooks->cfgh_split_edge (e)
+#define create_basic_block(h,e,a) cfg_hooks->create_basic_block (h,e,a)
+#define can_merge_blocks_p(a,b) cfg_hooks->can_merge_blocks_p (a,b)
+#define merge_blocks(a,b) cfg_hooks->merge_blocks (a,b)
+
+/* Hooks containers. */
+extern struct cfg_hooks rtl_cfg_hooks;
+
+/* A pointer to one of the hooks containers. */
+extern struct cfg_hooks *cfg_hooks;
+
+/* Declarations. */
+extern void rtl_register_cfg_hooks (void);
+extern void cfg_layout_rtl_register_cfg_hooks (void);
+
+#endif /* GCC_CFGHOOKS_H */
diff --git a/contrib/gcc/cfglayout.c b/contrib/gcc/cfglayout.c
index ca5f4751a418..4794ee129d62 100644
--- a/contrib/gcc/cfglayout.c
+++ b/contrib/gcc/cfglayout.c
@@ -1,5 +1,5 @@
/* Basic block reordering routines for the GNU compiler.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,6 +20,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "hard-reg-set.h"
@@ -29,32 +31,36 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "function.h"
#include "obstack.h"
#include "cfglayout.h"
+#include "cfgloop.h"
+#include "target.h"
+#include "ggc.h"
+#include "alloc-pool.h"
/* The contents of the current function definition are allocated
in this obstack, and all are freed at the end of the function. */
extern struct obstack flow_obstack;
+alloc_pool cfg_layout_pool;
+
/* Holds the interesting trailing notes for the function. */
-static rtx function_footer;
+rtx cfg_layout_function_footer, cfg_layout_function_header;
-static rtx skip_insns_after_block PARAMS ((basic_block));
-static void record_effective_endpoints PARAMS ((void));
-static rtx label_for_bb PARAMS ((basic_block));
-static void fixup_reorder_chain PARAMS ((void));
+static rtx skip_insns_after_block (basic_block);
+static void record_effective_endpoints (void);
+static rtx label_for_bb (basic_block);
+static void fixup_reorder_chain (void);
-static void set_block_levels PARAMS ((tree, int));
-static void change_scope PARAMS ((rtx, tree, tree));
+static void set_block_levels (tree, int);
+static void change_scope (rtx, tree, tree);
-void verify_insn_chain PARAMS ((void));
-static void cleanup_unconditional_jumps PARAMS ((void));
-static void fixup_fallthru_exit_predecessor PARAMS ((void));
-static rtx unlink_insn_chain PARAMS ((rtx, rtx));
-static rtx duplicate_insn_chain PARAMS ((rtx, rtx));
+void verify_insn_chain (void);
+static void fixup_fallthru_exit_predecessor (void);
+static rtx duplicate_insn_chain (rtx, rtx);
+static void break_superblocks (void);
+static tree insn_scope (rtx);
-static rtx
-unlink_insn_chain (first, last)
- rtx first;
- rtx last;
+rtx
+unlink_insn_chain (rtx first, rtx last)
{
rtx prevfirst = PREV_INSN (first);
rtx nextlast = NEXT_INSN (last);
@@ -77,16 +83,15 @@ unlink_insn_chain (first, last)
we return the last one. Otherwise, we return the end of BB. */
static rtx
-skip_insns_after_block (bb)
- basic_block bb;
+skip_insns_after_block (basic_block bb)
{
rtx insn, last_insn, next_head, prev;
next_head = NULL_RTX;
if (bb->next_bb != EXIT_BLOCK_PTR)
- next_head = bb->next_bb->head;
+ next_head = BB_HEAD (bb->next_bb);
- for (last_insn = insn = bb->end; (insn = NEXT_INSN (insn)) != 0; )
+ for (last_insn = insn = BB_END (bb); (insn = NEXT_INSN (insn)) != 0; )
{
if (insn == next_head)
break;
@@ -143,7 +148,7 @@ skip_insns_after_block (bb)
created by removing the basic block originally following
NOTE_INSN_LOOP_BEG. In such case reorder the notes. */
- for (insn = last_insn; insn != bb->end; insn = prev)
+ for (insn = last_insn; insn != BB_END (bb); insn = prev)
{
prev = PREV_INSN (insn);
if (GET_CODE (insn) == NOTE)
@@ -165,10 +170,9 @@ skip_insns_after_block (bb)
/* Locate or create a label for a given basic block. */
static rtx
-label_for_bb (bb)
- basic_block bb;
+label_for_bb (basic_block bb)
{
- rtx label = bb->head;
+ rtx label = BB_HEAD (bb);
if (GET_CODE (label) != CODE_LABEL)
{
@@ -185,45 +189,122 @@ label_for_bb (bb)
block, as defined by skip_insns_after_block above. */
static void
-record_effective_endpoints ()
+record_effective_endpoints (void)
{
- rtx next_insn = get_insns ();
+ rtx next_insn;
basic_block bb;
+ rtx insn;
+ for (insn = get_insns ();
+ insn
+ && GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK;
+ insn = NEXT_INSN (insn))
+ continue;
+ if (!insn)
+ abort (); /* No basic blocks at all? */
+ if (PREV_INSN (insn))
+ cfg_layout_function_header =
+ unlink_insn_chain (get_insns (), PREV_INSN (insn));
+ else
+ cfg_layout_function_header = NULL_RTX;
+
+ next_insn = get_insns ();
FOR_EACH_BB (bb)
{
rtx end;
- if (PREV_INSN (bb->head) && next_insn != bb->head)
- RBI (bb)->header = unlink_insn_chain (next_insn,
- PREV_INSN (bb->head));
+ if (PREV_INSN (BB_HEAD (bb)) && next_insn != BB_HEAD (bb))
+ bb->rbi->header = unlink_insn_chain (next_insn,
+ PREV_INSN (BB_HEAD (bb)));
end = skip_insns_after_block (bb);
- if (NEXT_INSN (bb->end) && bb->end != end)
- RBI (bb)->footer = unlink_insn_chain (NEXT_INSN (bb->end), end);
- next_insn = NEXT_INSN (bb->end);
+ if (NEXT_INSN (BB_END (bb)) && BB_END (bb) != end)
+ bb->rbi->footer = unlink_insn_chain (NEXT_INSN (BB_END (bb)), end);
+ next_insn = NEXT_INSN (BB_END (bb));
}
- function_footer = next_insn;
- if (function_footer)
- function_footer = unlink_insn_chain (function_footer, get_last_insn ());
+ cfg_layout_function_footer = next_insn;
+ if (cfg_layout_function_footer)
+ cfg_layout_function_footer = unlink_insn_chain (cfg_layout_function_footer, get_last_insn ());
}
-/* Build a varray mapping INSN_UID to lexical block. Return it. */
+/* Data structures representing mapping of INSN_LOCATOR into scope blocks, line
+ numbers and files. In order to be GGC friendly we need to use separate
+ varrays. This also slightly improve the memory locality in binary search.
+ The _locs array contains locators where the given property change. The
+ block_locators_blocks contains the scope block that is used for all insn
+ locator greater than corresponding block_locators_locs value and smaller
+ than the following one. Similarly for the other properties. */
+static GTY(()) varray_type block_locators_locs;
+static GTY(()) varray_type block_locators_blocks;
+static GTY(()) varray_type line_locators_locs;
+static GTY(()) varray_type line_locators_lines;
+static GTY(()) varray_type file_locators_locs;
+static GTY(()) varray_type file_locators_files;
+int prologue_locator;
+int epilogue_locator;
+
+/* During the RTL expansion the lexical blocks and line numbers are
+ represented via INSN_NOTEs. Replace them by representation using
+ INSN_LOCATORs. */
void
-scope_to_insns_initialize ()
+insn_locators_initialize (void)
{
tree block = NULL;
+ tree last_block = NULL;
rtx insn, next;
+ int loc = 0;
+ int line_number = 0, last_line_number = 0;
+ char *file_name = NULL, *last_file_name = NULL;
+
+ prologue_locator = epilogue_locator = 0;
+
+ VARRAY_INT_INIT (block_locators_locs, 32, "block_locators_locs");
+ VARRAY_TREE_INIT (block_locators_blocks, 32, "block_locators_blocks");
+ VARRAY_INT_INIT (line_locators_locs, 32, "line_locators_locs");
+ VARRAY_INT_INIT (line_locators_lines, 32, "line_locators_lines");
+ VARRAY_INT_INIT (file_locators_locs, 32, "file_locators_locs");
+ VARRAY_CHAR_PTR_INIT (file_locators_files, 32, "file_locators_files");
for (insn = get_insns (); insn; insn = next)
{
next = NEXT_INSN (insn);
- if (active_insn_p (insn)
- && GET_CODE (PATTERN (insn)) != ADDR_VEC
- && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
- INSN_SCOPE (insn) = block;
+ if ((active_insn_p (insn)
+ && GET_CODE (PATTERN (insn)) != ADDR_VEC
+ && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
+ || !NEXT_INSN (insn)
+ || (!prologue_locator && file_name))
+ {
+ if (last_block != block)
+ {
+ loc++;
+ VARRAY_PUSH_INT (block_locators_locs, loc);
+ VARRAY_PUSH_TREE (block_locators_blocks, block);
+ last_block = block;
+ }
+ if (last_line_number != line_number)
+ {
+ loc++;
+ VARRAY_PUSH_INT (line_locators_locs, loc);
+ VARRAY_PUSH_INT (line_locators_lines, line_number);
+ last_line_number = line_number;
+ }
+ if (last_file_name != file_name)
+ {
+ loc++;
+ VARRAY_PUSH_INT (file_locators_locs, loc);
+ VARRAY_PUSH_CHAR_PTR (file_locators_files, file_name);
+ last_file_name = file_name;
+ }
+ }
+ if (!prologue_locator && file_name)
+ prologue_locator = loc;
+ if (!NEXT_INSN (insn))
+ epilogue_locator = loc;
+ if (active_insn_p (insn))
+ INSN_LOCATOR (insn) = loc;
else if (GET_CODE (insn) == NOTE)
{
switch (NOTE_LINE_NUMBER (insn))
@@ -234,9 +315,16 @@ scope_to_insns_initialize ()
break;
case NOTE_INSN_BLOCK_END:
block = BLOCK_SUPERCONTEXT (block);
+ if (block && TREE_CODE (block) == FUNCTION_DECL)
+ block = 0;
delete_insn (insn);
break;
default:
+ if (NOTE_LINE_NUMBER (insn) > 0)
+ {
+ line_number = NOTE_LINE_NUMBER (insn);
+ file_name = (char *)NOTE_SOURCE_FILE (insn);
+ }
break;
}
}
@@ -251,9 +339,7 @@ scope_to_insns_initialize ()
found in the block tree. */
static void
-set_block_levels (block, level)
- tree block;
- int level;
+set_block_levels (tree block, int level)
{
while (block)
{
@@ -265,8 +351,7 @@ set_block_levels (block, level)
/* Return sope resulting from combination of S1 and S2. */
tree
-choose_inner_scope (s1, s2)
- tree s1, s2;
+choose_inner_scope (tree s1, tree s2)
{
if (!s1)
return s2;
@@ -280,9 +365,7 @@ choose_inner_scope (s1, s2)
/* Emit lexical block notes needed to change scope from S1 to S2. */
static void
-change_scope (orig_insn, s1, s2)
- rtx orig_insn;
- tree s1, s2;
+change_scope (rtx orig_insn, tree s1, tree s2)
{
rtx insn = orig_insn;
tree com = NULL_TREE;
@@ -324,11 +407,119 @@ change_scope (orig_insn, s1, s2)
}
}
+/* Return lexical scope block insn belong to. */
+static tree
+insn_scope (rtx insn)
+{
+ int max = VARRAY_ACTIVE_SIZE (block_locators_locs);
+ int min = 0;
+ int loc = INSN_LOCATOR (insn);
+
+ /* When block_locators_locs was initialized, the pro- and epilogue
+ insns didn't exist yet and can therefore not be found this way.
+ But we know that they belong to the outer most block of the
+ current function.
+ Without this test, the prologue would be put inside the block of
+ the first valid instruction in the function and when that first
+ insn is part of an inlined function then the low_pc of that
+ inlined function is messed up. Likewise for the epilogue and
+ the last valid instruction. */
+ if (loc == prologue_locator || loc == epilogue_locator)
+ return DECL_INITIAL (cfun->decl);
+
+ if (!max || !loc)
+ return NULL;
+ while (1)
+ {
+ int pos = (min + max) / 2;
+ int tmp = VARRAY_INT (block_locators_locs, pos);
+
+ if (tmp <= loc && min != pos)
+ min = pos;
+ else if (tmp > loc && max != pos)
+ max = pos;
+ else
+ {
+ min = pos;
+ break;
+ }
+ }
+ return VARRAY_TREE (block_locators_blocks, min);
+}
+
+/* Return line number of the statement specified by the locator. */
+int
+locator_line (int loc)
+{
+ int max = VARRAY_ACTIVE_SIZE (line_locators_locs);
+ int min = 0;
+
+ if (!max || !loc)
+ return 0;
+ while (1)
+ {
+ int pos = (min + max) / 2;
+ int tmp = VARRAY_INT (line_locators_locs, pos);
+
+ if (tmp <= loc && min != pos)
+ min = pos;
+ else if (tmp > loc && max != pos)
+ max = pos;
+ else
+ {
+ min = pos;
+ break;
+ }
+ }
+ return VARRAY_INT (line_locators_lines, min);
+}
+
+/* Return line number of the statement that produced this insn. */
+int
+insn_line (rtx insn)
+{
+ return locator_line (INSN_LOCATOR (insn));
+}
+
+/* Return source file of the statement specified by LOC. */
+const char *
+locator_file (int loc)
+{
+ int max = VARRAY_ACTIVE_SIZE (file_locators_locs);
+ int min = 0;
+
+ if (!max || !loc)
+ return NULL;
+ while (1)
+ {
+ int pos = (min + max) / 2;
+ int tmp = VARRAY_INT (file_locators_locs, pos);
+
+ if (tmp <= loc && min != pos)
+ min = pos;
+ else if (tmp > loc && max != pos)
+ max = pos;
+ else
+ {
+ min = pos;
+ break;
+ }
+ }
+ return VARRAY_CHAR_PTR (file_locators_files, min);
+}
+
+/* Return source file of the statement that produced this insn. */
+const char *
+insn_file (rtx insn)
+{
+ return locator_file (INSN_LOCATOR (insn));
+}
+
/* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based
on the scope tree and the newly reordered instructions. */
void
-scope_to_insns_finalize ()
+reemit_insn_block_notes (void)
{
tree cur_block = DECL_INITIAL (cfun->decl);
rtx insn, note;
@@ -340,7 +531,7 @@ scope_to_insns_finalize ()
{
tree this_block;
- this_block = INSN_SCOPE (insn);
+ this_block = insn_scope (insn);
/* For sequences compute scope resulting from merging all scopes
of instructions nested inside. */
if (GET_CODE (PATTERN (insn)) == SEQUENCE)
@@ -351,7 +542,7 @@ scope_to_insns_finalize ()
this_block = NULL;
for (i = 0; i < XVECLEN (body, 0); i++)
this_block = choose_inner_scope (this_block,
- INSN_SCOPE (XVECEXP (body, 0, i)));
+ insn_scope (XVECEXP (body, 0, i)));
}
if (! this_block)
continue;
@@ -364,7 +555,7 @@ scope_to_insns_finalize ()
}
/* change_scope emits before the insn, not after. */
- note = emit_note (NULL, NOTE_INSN_DELETED);
+ note = emit_note (NOTE_INSN_DELETED);
change_scope (note, cur_block, DECL_INITIAL (cfun->decl));
delete_insn (note);
@@ -374,40 +565,48 @@ scope_to_insns_finalize ()
/* Given a reorder chain, rearrange the code to match. */
static void
-fixup_reorder_chain ()
+fixup_reorder_chain (void)
{
basic_block bb, prev_bb;
int index;
rtx insn = NULL;
+ if (cfg_layout_function_header)
+ {
+ set_first_insn (cfg_layout_function_header);
+ insn = cfg_layout_function_header;
+ while (NEXT_INSN (insn))
+ insn = NEXT_INSN (insn);
+ }
+
/* First do the bulk reordering -- rechain the blocks without regard to
the needed changes to jumps and labels. */
for (bb = ENTRY_BLOCK_PTR->next_bb, index = 0;
bb != 0;
- bb = RBI (bb)->next, index++)
+ bb = bb->rbi->next, index++)
{
- if (RBI (bb)->header)
+ if (bb->rbi->header)
{
if (insn)
- NEXT_INSN (insn) = RBI (bb)->header;
+ NEXT_INSN (insn) = bb->rbi->header;
else
- set_first_insn (RBI (bb)->header);
- PREV_INSN (RBI (bb)->header) = insn;
- insn = RBI (bb)->header;
+ set_first_insn (bb->rbi->header);
+ PREV_INSN (bb->rbi->header) = insn;
+ insn = bb->rbi->header;
while (NEXT_INSN (insn))
insn = NEXT_INSN (insn);
}
if (insn)
- NEXT_INSN (insn) = bb->head;
+ NEXT_INSN (insn) = BB_HEAD (bb);
else
- set_first_insn (bb->head);
- PREV_INSN (bb->head) = insn;
- insn = bb->end;
- if (RBI (bb)->footer)
+ set_first_insn (BB_HEAD (bb));
+ PREV_INSN (BB_HEAD (bb)) = insn;
+ insn = BB_END (bb);
+ if (bb->rbi->footer)
{
- NEXT_INSN (insn) = RBI (bb)->footer;
- PREV_INSN (RBI (bb)->footer) = insn;
+ NEXT_INSN (insn) = bb->rbi->footer;
+ PREV_INSN (bb->rbi->footer) = insn;
while (NEXT_INSN (insn))
insn = NEXT_INSN (insn);
}
@@ -416,9 +615,9 @@ fixup_reorder_chain ()
if (index != n_basic_blocks)
abort ();
- NEXT_INSN (insn) = function_footer;
- if (function_footer)
- PREV_INSN (function_footer) = insn;
+ NEXT_INSN (insn) = cfg_layout_function_footer;
+ if (cfg_layout_function_footer)
+ PREV_INSN (cfg_layout_function_footer) = insn;
while (NEXT_INSN (insn))
insn = NEXT_INSN (insn);
@@ -427,11 +626,12 @@ fixup_reorder_chain ()
#ifdef ENABLE_CHECKING
verify_insn_chain ();
#endif
+ delete_dead_jumptables ();
/* Now add jumps and labels as needed to match the blocks new
outgoing edges. */
- for (bb = ENTRY_BLOCK_PTR->next_bb; bb ; bb = RBI (bb)->next)
+ for (bb = ENTRY_BLOCK_PTR->next_bb; bb ; bb = bb->rbi->next)
{
edge e_fall, e_taken, e;
rtx bb_end_insn;
@@ -449,23 +649,20 @@ fixup_reorder_chain ()
else if (! (e->flags & EDGE_EH))
e_taken = e;
- bb_end_insn = bb->end;
+ bb_end_insn = BB_END (bb);
if (GET_CODE (bb_end_insn) == JUMP_INSN)
{
if (any_condjump_p (bb_end_insn))
{
/* If the old fallthru is still next, nothing to do. */
- if (RBI (bb)->next == e_fall->dest
- || (!RBI (bb)->next
+ if (bb->rbi->next == e_fall->dest
+ || (!bb->rbi->next
&& e_fall->dest == EXIT_BLOCK_PTR))
continue;
- if (!e_taken)
- e_taken = e_fall;
-
/* The degenerated case of conditional jump jumping to the next
instruction can happen on target having jumps with side
- effects.
+ effects.
Create temporarily the duplicated edge representing branch.
It will get unidentified by force_nonfallthru_and_redirect
@@ -478,7 +675,9 @@ fixup_reorder_chain ()
e_fake = unchecked_make_edge (bb, e_fall->dest, 0);
- note = find_reg_note (bb->end, REG_BR_PROB, NULL_RTX);
+ if (!redirect_jump (BB_END (bb), block_label (bb), 0))
+ abort ();
+ note = find_reg_note (BB_END (bb), REG_BR_PROB, NULL_RTX);
if (note)
{
int prob = INTVAL (XEXP (note, 0));
@@ -497,7 +696,7 @@ fixup_reorder_chain ()
such as happens at the very end of a function, then we'll
need to add a new unconditional jump. Choose the taken
edge based on known or assumed probability. */
- else if (RBI (bb)->next != e_taken->dest)
+ else if (bb->rbi->next != e_taken->dest)
{
rtx note = find_reg_note (bb_end_insn, REG_BR_PROB, 0);
@@ -536,7 +735,7 @@ fixup_reorder_chain ()
#ifdef CASE_DROPS_THROUGH
/* Except for VAX. Since we didn't have predication for the
tablejump, the fallthru block should not have moved. */
- if (RBI (bb)->next == e_fall->dest)
+ if (bb->rbi->next == e_fall->dest)
continue;
bb_end_insn = skip_insns_after_block (bb);
#else
@@ -553,11 +752,11 @@ fixup_reorder_chain ()
continue;
/* If the fallthru block is still next, nothing to do. */
- if (RBI (bb)->next == e_fall->dest)
+ if (bb->rbi->next == e_fall->dest)
continue;
/* A fallthru to exit block. */
- if (!RBI (bb)->next && e_fall->dest == EXIT_BLOCK_PTR)
+ if (!bb->rbi->next && e_fall->dest == EXIT_BLOCK_PTR)
continue;
}
@@ -565,10 +764,10 @@ fixup_reorder_chain ()
nb = force_nonfallthru (e_fall);
if (nb)
{
- alloc_aux_for_block (nb, sizeof (struct reorder_block_def));
- RBI (nb)->visited = 1;
- RBI (nb)->next = RBI (bb)->next;
- RBI (bb)->next = nb;
+ cfg_layout_initialize_rbi (nb);
+ nb->rbi->visited = 1;
+ nb->rbi->next = bb->rbi->next;
+ bb->rbi->next = nb;
/* Don't process this new block. */
bb = nb;
}
@@ -579,13 +778,13 @@ fixup_reorder_chain ()
if (rtl_dump_file)
{
fprintf (rtl_dump_file, "Reordered sequence:\n");
- for (bb = ENTRY_BLOCK_PTR->next_bb, index = 0; bb; bb = RBI (bb)->next, index ++)
+ for (bb = ENTRY_BLOCK_PTR->next_bb, index = 0; bb; bb = bb->rbi->next, index ++)
{
fprintf (rtl_dump_file, " %i ", index);
- if (RBI (bb)->original)
+ if (bb->rbi->original)
fprintf (rtl_dump_file, "duplicate of %i ",
- RBI (bb)->original->index);
- else if (forwarder_block_p (bb) && GET_CODE (bb->head) != CODE_LABEL)
+ bb->rbi->original->index);
+ else if (forwarder_block_p (bb) && GET_CODE (BB_HEAD (bb)) != CODE_LABEL)
fprintf (rtl_dump_file, "compensation ");
else
fprintf (rtl_dump_file, "bb %i ", bb->index);
@@ -597,7 +796,7 @@ fixup_reorder_chain ()
bb = ENTRY_BLOCK_PTR->next_bb;
index = 0;
- for (; bb; prev_bb = bb, bb = RBI (bb)->next, index ++)
+ for (; bb; prev_bb = bb, bb = bb->rbi->next, index ++)
{
bb->index = index;
BASIC_BLOCK (index) = bb;
@@ -607,6 +806,16 @@ fixup_reorder_chain ()
}
prev_bb->next_bb = EXIT_BLOCK_PTR;
EXIT_BLOCK_PTR->prev_bb = prev_bb;
+
+ /* Annoying special case - jump around dead jumptables left in the code. */
+ FOR_EACH_BB (bb)
+ {
+ edge e;
+ for (e = bb->succ; e && !(e->flags & EDGE_FALLTHRU); e = e->succ_next)
+ continue;
+ if (e && !can_fallthru (e->src, e->dest))
+ force_nonfallthru (e);
+ }
}
/* Perform sanity checks on the insn chain.
@@ -616,7 +825,7 @@ fixup_reorder_chain ()
3. Check that get_last_insn () returns the actual end of chain. */
void
-verify_insn_chain ()
+verify_insn_chain (void)
{
rtx x, prevx, nextx;
int insn_cnt1, insn_cnt2;
@@ -640,71 +849,10 @@ verify_insn_chain ()
abort ();
}
-/* Remove any unconditional jumps and forwarder block creating fallthru
- edges instead. During BB reordering, fallthru edges are not required
- to target next basic block in the linear CFG layout, so the unconditional
- jumps are not needed. */
-
-static void
-cleanup_unconditional_jumps ()
-{
- basic_block bb;
-
- FOR_EACH_BB (bb)
- {
- if (!bb->succ)
- continue;
- if (bb->succ->flags & EDGE_FALLTHRU)
- continue;
- if (!bb->succ->succ_next)
- {
- rtx insn;
- if (GET_CODE (bb->head) != CODE_LABEL && forwarder_block_p (bb)
- && bb->prev_bb != ENTRY_BLOCK_PTR)
- {
- basic_block prev = bb->prev_bb;
-
- if (rtl_dump_file)
- fprintf (rtl_dump_file, "Removing forwarder BB %i\n",
- bb->index);
-
- redirect_edge_succ_nodup (bb->pred, bb->succ->dest);
- flow_delete_block (bb);
- bb = prev;
- }
- else if (simplejump_p (bb->end))
- {
- rtx jump = bb->end;
-
- if (rtl_dump_file)
- fprintf (rtl_dump_file, "Removing jump %i in BB %i\n",
- INSN_UID (jump), bb->index);
- delete_insn (jump);
- bb->succ->flags |= EDGE_FALLTHRU;
- }
- else
- continue;
-
- insn = NEXT_INSN (bb->end);
- while (insn
- && (GET_CODE (insn) != NOTE
- || NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK))
- {
- rtx next = NEXT_INSN (insn);
-
- if (GET_CODE (insn) == BARRIER)
- delete_barrier (insn);
-
- insn = next;
- }
- }
- }
-}
-
/* The block falling through to exit must be the last one in the
reordered chain. Ensure that this condition is met. */
static void
-fixup_fallthru_exit_predecessor ()
+fixup_fallthru_exit_predecessor (void)
{
edge e;
basic_block bb = NULL;
@@ -713,29 +861,27 @@ fixup_fallthru_exit_predecessor ()
if (e->flags & EDGE_FALLTHRU)
bb = e->src;
- if (bb && RBI (bb)->next)
+ if (bb && bb->rbi->next)
{
basic_block c = ENTRY_BLOCK_PTR->next_bb;
- while (RBI (c)->next != bb)
- c = RBI (c)->next;
+ while (c->rbi->next != bb)
+ c = c->rbi->next;
- RBI (c)->next = RBI (bb)->next;
- while (RBI (c)->next)
- c = RBI (c)->next;
+ c->rbi->next = bb->rbi->next;
+ while (c->rbi->next)
+ c = c->rbi->next;
- RBI (c)->next = bb;
- RBI (bb)->next = NULL;
+ c->rbi->next = bb;
+ bb->rbi->next = NULL;
}
}
/* Return true in case it is possible to duplicate the basic block BB. */
bool
-cfg_layout_can_duplicate_bb_p (bb)
- basic_block bb;
+cfg_layout_can_duplicate_bb_p (basic_block bb)
{
- rtx next;
edge s;
if (bb == EXIT_BLOCK_PTR || bb == ENTRY_BLOCK_PTR)
@@ -748,32 +894,41 @@ cfg_layout_can_duplicate_bb_p (bb)
return false;
/* Do not attempt to duplicate tablejumps, as we need to unshare
- the dispatch table. This is dificult to do, as the instructions
+ the dispatch table. This is difficult to do, as the instructions
computing jump destination may be hoisted outside the basic block. */
- if (GET_CODE (bb->end) == JUMP_INSN && JUMP_LABEL (bb->end)
- && (next = next_nonnote_insn (JUMP_LABEL (bb->end)))
- && GET_CODE (next) == JUMP_INSN
- && (GET_CODE (PATTERN (next)) == ADDR_VEC
- || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
+ if (tablejump_p (BB_END (bb), NULL, NULL))
return false;
+
+ /* Do not duplicate blocks containing insns that can't be copied. */
+ if (targetm.cannot_copy_insn_p)
+ {
+ rtx insn = BB_HEAD (bb);
+ while (1)
+ {
+ if (INSN_P (insn) && (*targetm.cannot_copy_insn_p) (insn))
+ return false;
+ if (insn == BB_END (bb))
+ break;
+ insn = NEXT_INSN (insn);
+ }
+ }
+
return true;
}
static rtx
-duplicate_insn_chain (from, to)
- rtx from, to;
+duplicate_insn_chain (rtx from, rtx to)
{
rtx insn, last;
/* Avoid updating of boundaries of previous basic block. The
note will get removed from insn stream in fixup. */
- last = emit_note (NULL, NOTE_INSN_DELETED);
+ last = emit_note (NOTE_INSN_DELETED);
/* Create copy at the end of INSN chain. The chain will
be reordered later. */
for (insn = from; insn != NEXT_INSN (to); insn = NEXT_INSN (insn))
{
- rtx new;
switch (GET_CODE (insn))
{
case INSN:
@@ -785,7 +940,7 @@ duplicate_insn_chain (from, to)
if (GET_CODE (PATTERN (insn)) == ADDR_VEC
|| GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
break;
- new = emit_copy_of_insn_after (insn, get_last_insn ());
+ emit_copy_of_insn_after (insn, get_last_insn ());
break;
case CODE_LABEL:
@@ -833,7 +988,7 @@ duplicate_insn_chain (from, to)
abort ();
break;
case NOTE_INSN_REPEATED_LINE_NUMBER:
- emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
+ emit_note_copy (insn);
break;
default:
@@ -841,7 +996,7 @@ duplicate_insn_chain (from, to)
abort ();
/* It is possible that no_line_number is set and the note
won't be emitted. */
- emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
+ emit_note_copy (insn);
}
break;
default:
@@ -852,62 +1007,12 @@ duplicate_insn_chain (from, to)
delete_insn (last);
return insn;
}
-
-/* Redirect Edge to DEST. */
-void
-cfg_layout_redirect_edge (e, dest)
- edge e;
- basic_block dest;
-{
- basic_block src = e->src;
- basic_block old_next_bb = src->next_bb;
-
- /* Redirect_edge_and_branch may decide to turn branch into fallthru edge
- in the case the basic block appears to be in sequence. Avoid this
- transformation. */
-
- src->next_bb = NULL;
- if (e->flags & EDGE_FALLTHRU)
- {
- /* Redirect any branch edges unified with the fallthru one. */
- if (GET_CODE (src->end) == JUMP_INSN
- && JUMP_LABEL (src->end) == e->dest->head)
- {
- if (!redirect_jump (src->end, block_label (dest), 0))
- abort ();
- }
- /* In case we are redirecting fallthru edge to the branch edge
- of conditional jump, remove it. */
- if (src->succ->succ_next
- && !src->succ->succ_next->succ_next)
- {
- edge s = e->succ_next ? e->succ_next : src->succ;
- if (s->dest == dest
- && any_condjump_p (src->end)
- && onlyjump_p (src->end))
- delete_insn (src->end);
- }
- redirect_edge_succ_nodup (e, dest);
- }
- else
- redirect_edge_and_branch (e, dest);
-
- /* We don't want simplejumps in the insn stream during cfglayout. */
- if (simplejump_p (src->end))
- {
- delete_insn (src->end);
- delete_barrier (NEXT_INSN (src->end));
- src->succ->flags |= EDGE_FALLTHRU;
- }
- src->next_bb = old_next_bb;
-}
-
-/* Create a duplicate of the basic block BB and redirect edge E into it. */
+/* Create a duplicate of the basic block BB and redirect edge E into it.
+ If E is not specified, BB is just copied, but updating the frequencies
+ etc. is left to the caller. */
basic_block
-cfg_layout_duplicate_bb (bb, e)
- basic_block bb;
- edge e;
+cfg_layout_duplicate_bb (basic_block bb, edge e)
{
rtx insn;
edge s, n;
@@ -923,30 +1028,29 @@ cfg_layout_duplicate_bb (bb, e)
abort ();
#endif
- insn = duplicate_insn_chain (bb->head, bb->end);
+ insn = duplicate_insn_chain (BB_HEAD (bb), BB_END (bb));
new_bb = create_basic_block (insn,
insn ? get_last_insn () : NULL,
EXIT_BLOCK_PTR->prev_bb);
- alloc_aux_for_block (new_bb, sizeof (struct reorder_block_def));
- if (RBI (bb)->header)
+ if (bb->rbi->header)
{
- insn = RBI (bb)->header;
+ insn = bb->rbi->header;
while (NEXT_INSN (insn))
insn = NEXT_INSN (insn);
- insn = duplicate_insn_chain (RBI (bb)->header, insn);
+ insn = duplicate_insn_chain (bb->rbi->header, insn);
if (insn)
- RBI (new_bb)->header = unlink_insn_chain (insn, get_last_insn ());
+ new_bb->rbi->header = unlink_insn_chain (insn, get_last_insn ());
}
- if (RBI (bb)->footer)
+ if (bb->rbi->footer)
{
- insn = RBI (bb)->footer;
+ insn = bb->rbi->footer;
while (NEXT_INSN (insn))
insn = NEXT_INSN (insn);
- insn = duplicate_insn_chain (RBI (bb)->footer, insn);
+ insn = duplicate_insn_chain (bb->rbi->footer, insn);
if (insn)
- RBI (new_bb)->footer = unlink_insn_chain (insn, get_last_insn ());
+ new_bb->rbi->footer = unlink_insn_chain (insn, get_last_insn ());
}
if (bb->global_live_at_start)
@@ -961,57 +1065,126 @@ cfg_layout_duplicate_bb (bb, e)
new_bb->flags = bb->flags;
for (s = bb->succ; s; s = s->succ_next)
{
- n = make_edge (new_bb, s->dest, s->flags);
+ /* Since we are creating edges from a new block to successors
+ of another block (which therefore are known to be disjoint), there
+ is no need to actually check for duplicated edges. */
+ n = unchecked_make_edge (new_bb, s->dest, s->flags);
n->probability = s->probability;
- if (new_count)
- /* Take care for overflows! */
- n->count = s->count * (new_count * 10000 / bb->count) / 10000;
+ if (e && bb->count)
+ {
+ /* Take care for overflows! */
+ n->count = s->count * (new_count * 10000 / bb->count) / 10000;
+ s->count -= n->count;
+ }
else
- n->count = 0;
- s->count -= n->count;
+ n->count = s->count;
+ n->aux = s->aux;
}
- new_bb->count = new_count;
- bb->count -= new_count;
-
if (e)
{
+ new_bb->count = new_count;
+ bb->count -= new_count;
+
new_bb->frequency = EDGE_FREQUENCY (e);
bb->frequency -= EDGE_FREQUENCY (e);
- cfg_layout_redirect_edge (e, new_bb);
+ redirect_edge_and_branch_force (e, new_bb);
+
+ if (bb->count < 0)
+ bb->count = 0;
+ if (bb->frequency < 0)
+ bb->frequency = 0;
+ }
+ else
+ {
+ new_bb->count = bb->count;
+ new_bb->frequency = bb->frequency;
}
- if (bb->count < 0)
- bb->count = 0;
- if (bb->frequency < 0)
- bb->frequency = 0;
+ new_bb->rbi->original = bb;
+ bb->rbi->copy = new_bb;
- RBI (new_bb)->original = bb;
return new_bb;
}
+void
+cfg_layout_initialize_rbi (basic_block bb)
+{
+ if (bb->rbi)
+ abort ();
+ bb->rbi = pool_alloc (cfg_layout_pool);
+ memset (bb->rbi, 0, sizeof (struct reorder_block_def));
+}
+
/* Main entry point to this module - initialize the datastructures for
- CFG layout changes. It keeps LOOPS up-to-date if not null. */
+ CFG layout changes. It keeps LOOPS up-to-date if not null.
+
+ FLAGS is a set of additional flags to pass to cleanup_cfg(). It should
+ include CLEANUP_UPDATE_LIFE if liveness information must be kept up
+ to date. */
void
-cfg_layout_initialize ()
+cfg_layout_initialize (unsigned int flags)
{
+ basic_block bb;
+
/* Our algorithm depends on fact that there are now dead jumptables
around the code. */
- alloc_aux_for_blocks (sizeof (struct reorder_block_def));
+ cfg_layout_pool =
+ create_alloc_pool ("cfg layout pool", sizeof (struct reorder_block_def),
+ n_basic_blocks + 2);
+ FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
+ cfg_layout_initialize_rbi (bb);
- cleanup_unconditional_jumps ();
+ cfg_layout_rtl_register_cfg_hooks ();
record_effective_endpoints ();
+
+ cleanup_cfg (CLEANUP_CFGLAYOUT | flags);
+}
+
+/* Splits superblocks. */
+static void
+break_superblocks (void)
+{
+ sbitmap superblocks;
+ int i, need;
+
+ superblocks = sbitmap_alloc (n_basic_blocks);
+ sbitmap_zero (superblocks);
+
+ need = 0;
+
+ for (i = 0; i < n_basic_blocks; i++)
+ if (BASIC_BLOCK(i)->flags & BB_SUPERBLOCK)
+ {
+ BASIC_BLOCK(i)->flags &= ~BB_SUPERBLOCK;
+ SET_BIT (superblocks, i);
+ need = 1;
+ }
+
+ if (need)
+ {
+ rebuild_jump_labels (get_insns ());
+ find_many_sub_basic_blocks (superblocks);
+ }
+
+ free (superblocks);
}
/* Finalize the changes: reorder insn list according to the sequence, enter
compensation code, rebuild scope forest. */
void
-cfg_layout_finalize ()
+cfg_layout_finalize (void)
{
+ basic_block bb;
+
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+ rtl_register_cfg_hooks ();
fixup_fallthru_exit_predecessor ();
fixup_reorder_chain ();
@@ -1019,9 +1192,132 @@ cfg_layout_finalize ()
verify_insn_chain ();
#endif
- free_aux_for_blocks ();
+ free_alloc_pool (cfg_layout_pool);
+ FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
+ bb->rbi = NULL;
+
+ break_superblocks ();
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
}
+
+/* Checks whether all N blocks in BBS array can be copied. */
+bool
+can_copy_bbs_p (basic_block *bbs, unsigned n)
+{
+ unsigned i;
+ edge e;
+ int ret = true;
+
+ for (i = 0; i < n; i++)
+ bbs[i]->rbi->duplicated = 1;
+
+ for (i = 0; i < n; i++)
+ {
+ /* In case we should redirect abnormal edge during duplication, fail. */
+ for (e = bbs[i]->succ; e; e = e->succ_next)
+ if ((e->flags & EDGE_ABNORMAL)
+ && e->dest->rbi->duplicated)
+ {
+ ret = false;
+ goto end;
+ }
+
+ if (!cfg_layout_can_duplicate_bb_p (bbs[i]))
+ {
+ ret = false;
+ break;
+ }
+ }
+
+end:
+ for (i = 0; i < n; i++)
+ bbs[i]->rbi->duplicated = 0;
+
+ return ret;
+}
+
+/* Duplicates N basic blocks stored in array BBS. Newly created basic blocks
+ are placed into array NEW_BBS in the same order. Edges from basic blocks
+ in BBS are also duplicated and copies of those of them
+ that lead into BBS are redirected to appropriate newly created block. The
+ function assigns bbs into loops (copy of basic block bb is assigned to
+ bb->loop_father->copy loop, so this must be set up correctly in advance)
+ and updates dominators locally (LOOPS structure that contains the information
+ about dominators is passed to enable this).
+
+ BASE is the superloop to that basic block belongs; if its header or latch
+ is copied, we do not set the new blocks as header or latch.
+
+ Created copies of N_EDGES edges in array EDGES are stored in array NEW_EDGES,
+ also in the same order. */
+
+void
+copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
+ edge *edges, unsigned n_edges, edge *new_edges,
+ struct loop *base)
+{
+ unsigned i, j;
+ basic_block bb, new_bb, dom_bb;
+ edge e;
+
+ /* Duplicate bbs, update dominators, assign bbs to loops. */
+ for (i = 0; i < n; i++)
+ {
+ /* Duplicate. */
+ bb = bbs[i];
+ new_bb = new_bbs[i] = cfg_layout_duplicate_bb (bb, NULL);
+ bb->rbi->duplicated = 1;
+ /* Add to loop. */
+ add_bb_to_loop (new_bb, bb->loop_father->copy);
+ add_to_dominance_info (CDI_DOMINATORS, new_bb);
+ /* Possibly set header. */
+ if (bb->loop_father->header == bb && bb->loop_father != base)
+ new_bb->loop_father->header = new_bb;
+ /* Or latch. */
+ if (bb->loop_father->latch == bb && bb->loop_father != base)
+ new_bb->loop_father->latch = new_bb;
+ }
+
+ /* Set dominators. */
+ for (i = 0; i < n; i++)
+ {
+ bb = bbs[i];
+ new_bb = new_bbs[i];
+
+ dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
+ if (dom_bb->rbi->duplicated)
+ {
+ dom_bb = dom_bb->rbi->copy;
+ set_immediate_dominator (CDI_DOMINATORS, new_bb, dom_bb);
+ }
+ }
+
+ /* Redirect edges. */
+ for (j = 0; j < n_edges; j++)
+ new_edges[j] = NULL;
+ for (i = 0; i < n; i++)
+ {
+ new_bb = new_bbs[i];
+ bb = bbs[i];
+
+ for (e = new_bb->succ; e; e = e->succ_next)
+ {
+ for (j = 0; j < n_edges; j++)
+ if (edges[j] && edges[j]->src == bb && edges[j]->dest == e->dest)
+ new_edges[j] = e;
+
+ if (!e->dest->rbi->duplicated)
+ continue;
+ redirect_edge_and_branch_force (e, e->dest->rbi->copy);
+ }
+ }
+
+ /* Clear information about duplicates. */
+ for (i = 0; i < n; i++)
+ bbs[i]->rbi->duplicated = 0;
+}
+
+#include "gt-cfglayout.h"
diff --git a/contrib/gcc/cfglayout.h b/contrib/gcc/cfglayout.h
index e4e27d00ed44..c0b250ece16b 100644
--- a/contrib/gcc/cfglayout.h
+++ b/contrib/gcc/cfglayout.h
@@ -1,5 +1,5 @@
/* Basic block reordering routines for the GNU compiler.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -25,17 +25,23 @@ typedef struct reorder_block_def
rtx footer;
basic_block next;
basic_block original;
+ /* Used by loop copying. */
+ basic_block copy;
+ int duplicated;
/* These fields are used by bb-reorder pass. */
int visited;
} *reorder_block_def;
-#define RBI(BB) ((reorder_block_def) (BB)->aux)
-
-extern void cfg_layout_initialize PARAMS ((void));
-extern void cfg_layout_finalize PARAMS ((void));
-extern bool cfg_layout_can_duplicate_bb_p PARAMS ((basic_block));
-extern basic_block cfg_layout_duplicate_bb PARAMS ((basic_block, edge));
-extern void scope_to_insns_initialize PARAMS ((void));
-extern void scope_to_insns_finalize PARAMS ((void));
-extern void cfg_layout_redirect_edge PARAMS ((edge, basic_block));
+extern rtx cfg_layout_function_footer;
+
+extern void cfg_layout_initialize (unsigned int);
+extern void cfg_layout_finalize (void);
+extern bool cfg_layout_can_duplicate_bb_p (basic_block);
+extern basic_block cfg_layout_duplicate_bb (basic_block, edge);
+extern void insn_locators_initialize (void);
+extern void reemit_insn_block_notes (void);
+extern bool can_copy_bbs_p (basic_block *, unsigned);
+extern void copy_bbs (basic_block *, unsigned, basic_block *,
+ edge *, unsigned, edge *, struct loop *);
+extern void cfg_layout_initialize_rbi (basic_block);
diff --git a/contrib/gcc/cfgloop.c b/contrib/gcc/cfgloop.c
index c8f7603535de..69097c009a9c 100644
--- a/contrib/gcc/cfgloop.c
+++ b/contrib/gcc/cfgloop.c
@@ -1,5 +1,5 @@
/* Natural loop discovery code for GNU compiler.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,43 +20,42 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "toplev.h"
+#include "cfgloop.h"
+#include "flags.h"
/* Ratio of frequencies of edges so that one of more latch edges is
considered to belong to inner loop with same header. */
#define HEAVY_EDGE_RATIO 8
-static void flow_loops_cfg_dump PARAMS ((const struct loops *,
- FILE *));
-static void flow_loop_entry_edges_find PARAMS ((struct loop *));
-static void flow_loop_exit_edges_find PARAMS ((struct loop *));
-static int flow_loop_nodes_find PARAMS ((basic_block, struct loop *));
-static void flow_loop_pre_header_scan PARAMS ((struct loop *));
-static basic_block flow_loop_pre_header_find PARAMS ((basic_block,
- dominance_info));
-static int flow_loop_level_compute PARAMS ((struct loop *));
-static int flow_loops_level_compute PARAMS ((struct loops *));
-static basic_block make_forwarder_block PARAMS ((basic_block, int, int,
- edge, int));
-static void canonicalize_loop_headers PARAMS ((void));
-static bool glb_enum_p PARAMS ((basic_block, void *));
-static void redirect_edge_with_latch_update PARAMS ((edge, basic_block));
-static void flow_loop_free PARAMS ((struct loop *));
+static void flow_loops_cfg_dump (const struct loops *, FILE *);
+static void flow_loop_entry_edges_find (struct loop *);
+static void flow_loop_exit_edges_find (struct loop *);
+static int flow_loop_nodes_find (basic_block, struct loop *);
+static void flow_loop_pre_header_scan (struct loop *);
+static basic_block flow_loop_pre_header_find (basic_block);
+static int flow_loop_level_compute (struct loop *);
+static int flow_loops_level_compute (struct loops *);
+static void establish_preds (struct loop *);
+static basic_block make_forwarder_block (basic_block, int, int, edge, int);
+static void canonicalize_loop_headers (void);
+static bool glb_enum_p (basic_block, void *);
+static void redirect_edge_with_latch_update (edge, basic_block);
/* Dump loop related CFG information. */
static void
-flow_loops_cfg_dump (loops, file)
- const struct loops *loops;
- FILE *file;
+flow_loops_cfg_dump (const struct loops *loops, FILE *file)
{
int i;
basic_block bb;
- if (! loops->num || ! file || ! loops->cfg.dom)
+ if (! loops->num || ! file)
return;
FOR_EACH_BB (bb)
@@ -93,9 +92,7 @@ flow_loops_cfg_dump (loops, file)
/* Return nonzero if the nodes of LOOP are a subset of OUTER. */
bool
-flow_loop_nested_p (outer, loop)
- const struct loop *outer;
- const struct loop *loop;
+flow_loop_nested_p (const struct loop *outer, const struct loop *loop)
{
return loop->depth > outer->depth
&& loop->pred[outer->depth] == outer;
@@ -105,14 +102,12 @@ flow_loop_nested_p (outer, loop)
using auxiliary dump callback function LOOP_DUMP_AUX if non null. */
void
-flow_loop_dump (loop, file, loop_dump_aux, verbose)
- const struct loop *loop;
- FILE *file;
- void (*loop_dump_aux) PARAMS((const struct loop *, FILE *, int));
- int verbose;
+flow_loop_dump (const struct loop *loop, FILE *file,
+ void (*loop_dump_aux) (const struct loop *, FILE *, int),
+ int verbose)
{
basic_block *bbs;
- int i;
+ unsigned i;
if (! loop || ! loop->header)
return;
@@ -150,11 +145,7 @@ flow_loop_dump (loop, file, loop_dump_aux, verbose)
using auxiliary dump callback function LOOP_DUMP_AUX if non null. */
void
-flow_loops_dump (loops, file, loop_dump_aux, verbose)
- const struct loops *loops;
- FILE *file;
- void (*loop_dump_aux) PARAMS((const struct loop *, FILE *, int));
- int verbose;
+flow_loops_dump (const struct loops *loops, FILE *file, void (*loop_dump_aux) (const struct loop *, FILE *, int), int verbose)
{
int i;
int num_loops;
@@ -181,9 +172,8 @@ flow_loops_dump (loops, file, loop_dump_aux, verbose)
}
/* Free data allocated for LOOP. */
-static void
-flow_loop_free (loop)
- struct loop *loop;
+void
+flow_loop_free (struct loop *loop)
{
if (loop->pre_header_edges)
free (loop->pre_header_edges);
@@ -199,12 +189,11 @@ flow_loop_free (loop)
/* Free all the memory allocated for LOOPS. */
void
-flow_loops_free (loops)
- struct loops *loops;
+flow_loops_free (struct loops *loops)
{
if (loops->parray)
{
- int i;
+ unsigned i;
if (! loops->num)
abort ();
@@ -223,9 +212,6 @@ flow_loops_free (loops)
free (loops->parray);
loops->parray = NULL;
- if (loops->cfg.dom)
- free_dominance_info (loops->cfg.dom);
-
if (loops->cfg.dfs_order)
free (loops->cfg.dfs_order);
if (loops->cfg.rc_order)
@@ -236,9 +222,8 @@ flow_loops_free (loops)
/* Find the entry edges into the LOOP. */
-static void
-flow_loop_entry_edges_find (loop)
- struct loop *loop;
+static void
+flow_loop_entry_edges_find (struct loop *loop)
{
edge e;
int num_entries;
@@ -253,7 +238,7 @@ flow_loop_entry_edges_find (loop)
if (! num_entries)
abort ();
- loop->entry_edges = (edge *) xmalloc (num_entries * sizeof (edge *));
+ loop->entry_edges = xmalloc (num_entries * sizeof (edge *));
num_entries = 0;
for (e = loop->header->pred; e; e = e->pred_next)
@@ -268,12 +253,11 @@ flow_loop_entry_edges_find (loop)
/* Find the exit edges from the LOOP. */
static void
-flow_loop_exit_edges_find (loop)
- struct loop *loop;
+flow_loop_exit_edges_find (struct loop *loop)
{
edge e;
basic_block node, *bbs;
- int num_exits, i;
+ unsigned num_exits, i;
loop->exit_edges = NULL;
loop->num_exits = 0;
@@ -301,7 +285,7 @@ flow_loop_exit_edges_find (loop)
return;
}
- loop->exit_edges = (edge *) xmalloc (num_exits * sizeof (edge *));
+ loop->exit_edges = xmalloc (num_exits * sizeof (edge *));
/* Store all exiting edges into an array. */
num_exits = 0;
@@ -324,35 +308,31 @@ flow_loop_exit_edges_find (loop)
Return the number of nodes within the loop. */
static int
-flow_loop_nodes_find (header, loop)
- basic_block header;
- struct loop *loop;
+flow_loop_nodes_find (basic_block header, struct loop *loop)
{
basic_block *stack;
int sp;
int num_nodes = 1;
- int findex, lindex;
header->loop_father = loop;
header->loop_depth = loop->depth;
- findex = lindex = header->index;
if (loop->latch->loop_father != loop)
{
- stack = (basic_block *) xmalloc (n_basic_blocks * sizeof (basic_block));
+ stack = xmalloc (n_basic_blocks * sizeof (basic_block));
sp = 0;
num_nodes++;
stack[sp++] = loop->latch;
loop->latch->loop_father = loop;
loop->latch->loop_depth = loop->depth;
-
+
while (sp)
{
basic_block node;
edge e;
node = stack[--sp];
-
+
for (e = node->pred; e; e = e->pred_next)
{
basic_block ancestor = e->src;
@@ -376,8 +356,7 @@ flow_loop_nodes_find (header, loop)
the edges along the trace from the root node to the loop header. */
static void
-flow_loop_pre_header_scan (loop)
- struct loop *loop;
+flow_loop_pre_header_scan (struct loop *loop)
{
int num;
basic_block ebb;
@@ -398,7 +377,7 @@ flow_loop_pre_header_scan (loop)
num++)
ebb = ebb->pred->src;
- loop->pre_header_edges = (edge *) xmalloc (num * sizeof (edge));
+ loop->pre_header_edges = xmalloc (num * sizeof (edge));
loop->num_pre_header_edges = num;
/* Store edges in order that they are followed. The source of the first edge
@@ -409,13 +388,10 @@ flow_loop_pre_header_scan (loop)
}
/* Return the block for the pre-header of the loop with header
- HEADER where DOM specifies the dominator information. Return NULL if
- there is no pre-header. */
+ HEADER. Return NULL if there is no pre-header. */
static basic_block
-flow_loop_pre_header_find (header, dom)
- basic_block header;
- dominance_info dom;
+flow_loop_pre_header_find (basic_block header)
{
basic_block pre_header;
edge e;
@@ -428,7 +404,7 @@ flow_loop_pre_header_find (header, dom)
basic_block node = e->src;
if (node != ENTRY_BLOCK_PTR
- && ! dominated_by_p (dom, node, header))
+ && ! dominated_by_p (CDI_DOMINATORS, node, header))
{
if (pre_header == NULL)
pre_header = node;
@@ -445,29 +421,40 @@ flow_loop_pre_header_find (header, dom)
return pre_header;
}
+static void
+establish_preds (struct loop *loop)
+{
+ struct loop *ploop, *father = loop->outer;
+
+ loop->depth = father->depth + 1;
+ if (loop->pred)
+ free (loop->pred);
+ loop->pred = xmalloc (sizeof (struct loop *) * loop->depth);
+ memcpy (loop->pred, father->pred, sizeof (struct loop *) * father->depth);
+ loop->pred[father->depth] = father;
+
+ for (ploop = loop->inner; ploop; ploop = ploop->next)
+ establish_preds (ploop);
+}
+
/* Add LOOP to the loop hierarchy tree where FATHER is father of the
- added loop. */
+ added loop. If LOOP has some children, take care of that their
+ pred field will be initialized correctly. */
void
-flow_loop_tree_node_add (father, loop)
- struct loop *father;
- struct loop *loop;
+flow_loop_tree_node_add (struct loop *father, struct loop *loop)
{
loop->next = father->inner;
father->inner = loop;
loop->outer = father;
- loop->depth = father->depth + 1;
- loop->pred = xmalloc (sizeof (struct loop *) * loop->depth);
- memcpy (loop->pred, father->pred, sizeof (struct loop *) * father->depth);
- loop->pred[father->depth] = father;
+ establish_preds (loop);
}
/* Remove LOOP from the loop hierarchy tree. */
void
-flow_loop_tree_node_remove (loop)
- struct loop *loop;
+flow_loop_tree_node_remove (struct loop *loop)
{
struct loop *prev, *father;
@@ -492,8 +479,7 @@ flow_loop_tree_node_remove (loop)
for the natural loop specified by LOOP. Returns the loop level. */
static int
-flow_loop_level_compute (loop)
- struct loop *loop;
+flow_loop_level_compute (struct loop *loop)
{
struct loop *inner;
int level = 1;
@@ -523,8 +509,7 @@ flow_loop_level_compute (loop)
level. */
static int
-flow_loops_level_compute (loops)
- struct loops *loops;
+flow_loops_level_compute (struct loops *loops)
{
return flow_loop_level_compute (loops->tree_root);
}
@@ -533,10 +518,7 @@ flow_loops_level_compute (loops)
about it specified by FLAGS. */
int
-flow_loop_scan (loops, loop, flags)
- struct loops *loops;
- struct loop *loop;
- int flags;
+flow_loop_scan (struct loop *loop, int flags)
{
if (flags & LOOP_ENTRY_EDGES)
{
@@ -555,8 +537,7 @@ flow_loop_scan (loops, loop, flags)
if (flags & LOOP_PRE_HEADER)
{
/* Look to see if the loop has a pre-header node. */
- loop->pre_header
- = flow_loop_pre_header_find (loop->header, loops->cfg.dom);
+ loop->pre_header = flow_loop_pre_header_find (loop->header);
/* Find the blocks within the extended basic block of
the loop pre-header. */
@@ -571,9 +552,7 @@ flow_loop_scan (loops, loop, flags)
/* Redirect edge and update latch and header info. */
static void
-redirect_edge_with_latch_update (e, to)
- edge e;
- basic_block to;
+redirect_edge_with_latch_update (edge e, basic_block to)
{
basic_block jump;
@@ -595,13 +574,7 @@ redirect_edge_with_latch_update (e, to)
part. */
static basic_block
-make_forwarder_block (bb, redirect_latch, redirect_nonlatch, except,
- conn_latch)
- basic_block bb;
- int redirect_latch;
- int redirect_nonlatch;
- edge except;
- int conn_latch;
+make_forwarder_block (basic_block bb, int redirect_latch, int redirect_nonlatch, edge except, int conn_latch)
{
edge e, next_e, fallthru;
basic_block dummy;
@@ -609,6 +582,10 @@ make_forwarder_block (bb, redirect_latch, redirect_nonlatch, except,
insn = PREV_INSN (first_insn_after_basic_block_note (bb));
+ /* For empty block split_block will return NULL. */
+ if (BB_END (bb) == insn)
+ emit_note_after (NOTE_INSN_DELETED, insn);
+
fallthru = split_block (bb, insn);
dummy = fallthru->src;
bb = fallthru->dest;
@@ -643,14 +620,13 @@ make_forwarder_block (bb, redirect_latch, redirect_nonlatch, except,
/* Takes care of merging natural loops with shared headers. */
static void
-canonicalize_loop_headers ()
+canonicalize_loop_headers (void)
{
- dominance_info dom;
basic_block header;
edge e;
-
+
/* Compute the dominators. */
- dom = calculate_dominance_info (CDI_DOMINATORS);
+ calculate_dominance_info (CDI_DOMINATORS);
alloc_aux_for_blocks (sizeof (int));
alloc_aux_for_edges (sizeof (int));
@@ -669,7 +645,7 @@ canonicalize_loop_headers ()
have_abnormal_edge = 1;
if (latch != ENTRY_BLOCK_PTR
- && dominated_by_p (dom, latch, header))
+ && dominated_by_p (CDI_DOMINATORS, latch, header))
{
num_latches++;
LATCH_EDGE (e) = 1;
@@ -681,6 +657,8 @@ canonicalize_loop_headers ()
HEADER_BLOCK (header) = num_latches;
}
+ free_dominance_info (CDI_DOMINATORS);
+
if (HEADER_BLOCK (ENTRY_BLOCK_PTR->succ->dest))
{
basic_block bb;
@@ -688,7 +666,7 @@ canonicalize_loop_headers ()
/* We could not redirect edges freely here. On the other hand,
we can simply split the edge from entry block. */
bb = split_edge (ENTRY_BLOCK_PTR->succ);
-
+
alloc_aux_for_edge (bb->succ, sizeof (int));
LATCH_EDGE (bb->succ) = 0;
alloc_aux_for_block (bb, sizeof (int));
@@ -746,7 +724,6 @@ canonicalize_loop_headers ()
free_aux_for_blocks ();
free_aux_for_edges ();
- free_dominance_info (dom);
}
/* Find all the natural loops in the function and save in LOOPS structure and
@@ -755,16 +732,13 @@ canonicalize_loop_headers ()
loops found. */
int
-flow_loops_find (loops, flags)
- struct loops *loops;
- int flags;
+flow_loops_find (struct loops *loops, int flags)
{
int i;
int b;
int num_loops;
edge e;
sbitmap headers;
- dominance_info dom;
int *dfs_order;
int *rc_order;
basic_block header;
@@ -790,7 +764,7 @@ flow_loops_find (loops, flags)
canonicalize_loop_headers ();
/* Compute the dominators. */
- dom = loops->cfg.dom = calculate_dominance_info (CDI_DOMINATORS);
+ calculate_dominance_info (CDI_DOMINATORS);
/* Count the number of loop headers. This should be the
same as the number of natural loops. */
@@ -801,7 +775,7 @@ flow_loops_find (loops, flags)
FOR_EACH_BB (header)
{
int more_latches = 0;
-
+
header->loop_depth = 0;
/* If we have an abnormal predecessor, do not consider the
@@ -824,7 +798,8 @@ flow_loops_find (loops, flags)
node (header) that dominates all the nodes in the
loop. It also has single back edge to the header
from a latch node. */
- if (latch != ENTRY_BLOCK_PTR && dominated_by_p (dom, latch, header))
+ if (latch != ENTRY_BLOCK_PTR
+ && dominated_by_p (CDI_DOMINATORS, latch, header))
{
/* Shared headers should be eliminated by now. */
if (more_latches)
@@ -837,7 +812,7 @@ flow_loops_find (loops, flags)
}
/* Allocate loop structures. */
- loops->parray = (struct loop **) xcalloc (num_loops + 1, sizeof (struct loop *));
+ loops->parray = xcalloc (num_loops + 1, sizeof (struct loop *));
/* Dummy loop containing whole function. */
loops->parray[0] = xcalloc (1, sizeof (struct loop));
@@ -864,12 +839,11 @@ flow_loops_find (loops, flags)
{
/* Compute depth first search order of the CFG so that outer
natural loops will be found before inner natural loops. */
- dfs_order = (int *) xmalloc (n_basic_blocks * sizeof (int));
- rc_order = (int *) xmalloc (n_basic_blocks * sizeof (int));
+ dfs_order = xmalloc (n_basic_blocks * sizeof (int));
+ rc_order = xmalloc (n_basic_blocks * sizeof (int));
flow_depth_first_order_compute (dfs_order, rc_order);
/* Save CFG derived information to avoid recomputing it. */
- loops->cfg.dom = dom;
loops->cfg.dfs_order = dfs_order;
loops->cfg.rc_order = rc_order;
@@ -885,7 +859,7 @@ flow_loops_find (loops, flags)
continue;
header = BASIC_BLOCK (rc_order[b]);
-
+
loop = loops->parray[num_loops] = xcalloc (1, sizeof (struct loop));
loop->header = header;
@@ -898,7 +872,7 @@ flow_loops_find (loops, flags)
basic_block latch = e->src;
if (latch != ENTRY_BLOCK_PTR
- && dominated_by_p (dom, latch, header))
+ && dominated_by_p (CDI_DOMINATORS, latch, header))
{
loop->latch = latch;
break;
@@ -909,26 +883,27 @@ flow_loops_find (loops, flags)
loop->num_nodes = flow_loop_nodes_find (loop->header, loop);
}
- sbitmap_free (headers);
-
/* Assign the loop nesting depth and enclosed loop level for each
loop. */
loops->levels = flow_loops_level_compute (loops);
/* Scan the loops. */
for (i = 1; i < num_loops; i++)
- flow_loop_scan (loops, loops->parray[i], flags);
+ flow_loop_scan (loops->parray[i], flags);
loops->num = num_loops;
}
else
{
- loops->cfg.dom = NULL;
- free_dominance_info (dom);
+ free_dominance_info (CDI_DOMINATORS);
}
+
+ sbitmap_free (headers);
+
+ loops->state = 0;
#ifdef ENABLE_CHECKING
verify_flow_info ();
- verify_loop_structure (loops, 0);
+ verify_loop_structure (loops);
#endif
return loops->num;
@@ -938,9 +913,7 @@ flow_loops_find (loops, flags)
specified by LOOPS. */
int
-flow_loops_update (loops, flags)
- struct loops *loops;
- int flags;
+flow_loops_update (struct loops *loops, int flags)
{
/* One day we may want to update the current loop data. For now
throw away the old stuff and rebuild what we need. */
@@ -952,9 +925,7 @@ flow_loops_update (loops, flags)
/* Return nonzero if basic block BB belongs to LOOP. */
bool
-flow_bb_inside_loop_p (loop, bb)
- const struct loop *loop;
- const basic_block bb;
+flow_bb_inside_loop_p (const struct loop *loop, const basic_block bb)
{
struct loop *source_loop;
@@ -968,9 +939,7 @@ flow_bb_inside_loop_p (loop, bb)
/* Return nonzero if edge E enters header of LOOP from outside of LOOP. */
bool
-flow_loop_outside_edge_p (loop, e)
- const struct loop *loop;
- edge e;
+flow_loop_outside_edge_p (const struct loop *loop, edge e)
{
if (e->dest != loop->header)
abort ();
@@ -979,20 +948,19 @@ flow_loop_outside_edge_p (loop, e)
/* Enumeration predicate for get_loop_body. */
static bool
-glb_enum_p (bb, glb_header)
- basic_block bb;
- void *glb_header;
+glb_enum_p (basic_block bb, void *glb_header)
{
return bb != (basic_block) glb_header;
}
-/* Gets basic blocks of a loop. */
+/* Gets basic blocks of a LOOP. Header is the 0-th block, rest is in dfs
+ order against direction of edges from latch. Specially, if
+ header != latch, latch is the 1-st block. */
basic_block *
-get_loop_body (loop)
- const struct loop *loop;
+get_loop_body (const struct loop *loop)
{
basic_block *tovisit, bb;
- int tv = 0;
+ unsigned tv = 0;
if (!loop->num_nodes)
abort ();
@@ -1003,7 +971,7 @@ get_loop_body (loop)
if (loop->latch == EXIT_BLOCK_PTR)
{
/* There may be blocks unreachable from EXIT_BLOCK. */
- if (loop->num_nodes != n_basic_blocks + 2)
+ if (loop->num_nodes != (unsigned) n_basic_blocks + 2)
abort ();
FOR_EACH_BB (bb)
tovisit[tv++] = bb;
@@ -1021,14 +989,41 @@ get_loop_body (loop)
return tovisit;
}
+/* Gets exit edges of a LOOP, returning their number in N_EDGES. */
+edge *
+get_loop_exit_edges (const struct loop *loop, unsigned int *n_edges)
+{
+ edge *edges, e;
+ unsigned i, n;
+ basic_block * body;
+
+ if (loop->latch == EXIT_BLOCK_PTR)
+ abort ();
+
+ body = get_loop_body (loop);
+ n = 0;
+ for (i = 0; i < loop->num_nodes; i++)
+ for (e = body[i]->succ; e; e = e->succ_next)
+ if (!flow_bb_inside_loop_p (loop, e->dest))
+ n++;
+ edges = xmalloc (n * sizeof (edge));
+ *n_edges = n;
+ n = 0;
+ for (i = 0; i < loop->num_nodes; i++)
+ for (e = body[i]->succ; e; e = e->succ_next)
+ if (!flow_bb_inside_loop_p (loop, e->dest))
+ edges[n++] = e;
+ free (body);
+
+ return edges;
+}
+
/* Adds basic block BB to LOOP. */
void
-add_bb_to_loop (bb, loop)
- basic_block bb;
- struct loop *loop;
- {
+add_bb_to_loop (basic_block bb, struct loop *loop)
+{
int i;
-
+
bb->loop_father = loop;
bb->loop_depth = loop->depth;
loop->num_nodes++;
@@ -1038,9 +1033,8 @@ add_bb_to_loop (bb, loop)
/* Remove basic block BB from loops. */
void
-remove_bb_from_loops (bb)
- basic_block bb;
- {
+remove_bb_from_loops (basic_block bb)
+{
int i;
struct loop *loop = bb->loop_father;
@@ -1053,13 +1047,11 @@ remove_bb_from_loops (bb)
/* Finds nearest common ancestor in loop tree for given loops. */
struct loop *
-find_common_loop (loop_s, loop_d)
- struct loop *loop_s;
- struct loop *loop_d;
+find_common_loop (struct loop *loop_s, struct loop *loop_d)
{
if (!loop_s) return loop_d;
if (!loop_d) return loop_s;
-
+
if (loop_s->depth < loop_d->depth)
loop_d = loop_d->pred[loop_s->depth];
else if (loop_s->depth > loop_d->depth)
@@ -1073,21 +1065,56 @@ find_common_loop (loop_s, loop_d)
return loop_s;
}
-/* Checks that LOOPS are allright:
- -- sizes of loops are allright
+/* Cancels the LOOP; it must be innermost one. */
+void
+cancel_loop (struct loops *loops, struct loop *loop)
+{
+ basic_block *bbs;
+ unsigned i;
+
+ if (loop->inner)
+ abort ();
+
+ /* Move blocks up one level (they should be removed as soon as possible). */
+ bbs = get_loop_body (loop);
+ for (i = 0; i < loop->num_nodes; i++)
+ bbs[i]->loop_father = loop->outer;
+
+ /* Remove the loop from structure. */
+ flow_loop_tree_node_remove (loop);
+
+ /* Remove loop from loops array. */
+ loops->parray[loop->num] = NULL;
+
+ /* Free loop data. */
+ flow_loop_free (loop);
+}
+
+/* Cancels LOOP and all its subloops. */
+void
+cancel_loop_tree (struct loops *loops, struct loop *loop)
+{
+ while (loop->inner)
+ cancel_loop_tree (loops, loop->inner);
+ cancel_loop (loops, loop);
+}
+
+/* Checks that LOOPS are all right:
+ -- sizes of loops are all right
-- results of get_loop_body really belong to the loop
-- loop header have just single entry edge and single latch edge
-- loop latches have only single successor that is header of their loop
+ -- irreducible loops are correctly marked
*/
void
-verify_loop_structure (loops, flags)
- struct loops *loops;
- int flags;
+verify_loop_structure (struct loops *loops)
{
- int *sizes, i, j;
+ unsigned *sizes, i, j;
+ sbitmap irreds;
basic_block *bbs, bb;
struct loop *loop;
int err = 0;
+ edge e;
/* Check sizes. */
sizes = xcalloc (loops->num, sizeof (int));
@@ -1137,14 +1164,14 @@ verify_loop_structure (loops, flags)
if (!loop)
continue;
- if ((flags & VLS_EXPECT_PREHEADERS)
+ if ((loops->state & LOOPS_HAVE_PREHEADERS)
&& (!loop->header->pred->pred_next
|| loop->header->pred->pred_next->pred_next))
{
error ("Loop %d's header does not have exactly 2 entries.", i);
err = 1;
}
- if (flags & VLS_EXPECT_SIMPLE_LATCHES)
+ if (loops->state & LOOPS_HAVE_SIMPLE_LATCHES)
{
if (!loop->latch->succ
|| loop->latch->succ->succ_next)
@@ -1168,6 +1195,68 @@ verify_loop_structure (loops, flags)
error ("Loop %d's header does not belong directly to it.", i);
err = 1;
}
+ if ((loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
+ && (loop_latch_edge (loop)->flags & EDGE_IRREDUCIBLE_LOOP))
+ {
+ error ("Loop %d's latch is marked as part of irreducible region.", i);
+ err = 1;
+ }
+ }
+
+ /* Check irreducible loops. */
+ if (loops->state & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
+ {
+ /* Record old info. */
+ irreds = sbitmap_alloc (last_basic_block);
+ FOR_EACH_BB (bb)
+ {
+ if (bb->flags & BB_IRREDUCIBLE_LOOP)
+ SET_BIT (irreds, bb->index);
+ else
+ RESET_BIT (irreds, bb->index);
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->flags & EDGE_IRREDUCIBLE_LOOP)
+ e->flags |= EDGE_ALL_FLAGS + 1;
+ }
+
+ /* Recount it. */
+ mark_irreducible_loops (loops);
+
+ /* Compare. */
+ FOR_EACH_BB (bb)
+ {
+ if ((bb->flags & BB_IRREDUCIBLE_LOOP)
+ && !TEST_BIT (irreds, bb->index))
+ {
+ error ("Basic block %d should be marked irreducible.", bb->index);
+ err = 1;
+ }
+ else if (!(bb->flags & BB_IRREDUCIBLE_LOOP)
+ && TEST_BIT (irreds, bb->index))
+ {
+ error ("Basic block %d should not be marked irreducible.", bb->index);
+ err = 1;
+ }
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if ((e->flags & EDGE_IRREDUCIBLE_LOOP)
+ && !(e->flags & (EDGE_ALL_FLAGS + 1)))
+ {
+ error ("Edge from %d to %d should be marked irreducible.",
+ e->src->index, e->dest->index);
+ err = 1;
+ }
+ else if (!(e->flags & EDGE_IRREDUCIBLE_LOOP)
+ && (e->flags & (EDGE_ALL_FLAGS + 1)))
+ {
+ error ("Edge from %d to %d should not be marked irreducible.",
+ e->src->index, e->dest->index);
+ err = 1;
+ }
+ e->flags &= ~(EDGE_ALL_FLAGS + 1);
+ }
+ }
+ free (irreds);
}
if (err)
@@ -1176,8 +1265,7 @@ verify_loop_structure (loops, flags)
/* Returns latch edge of LOOP. */
edge
-loop_latch_edge (loop)
- struct loop *loop;
+loop_latch_edge (const struct loop *loop)
{
edge e;
@@ -1189,8 +1277,7 @@ loop_latch_edge (loop)
/* Returns preheader edge of LOOP. */
edge
-loop_preheader_edge (loop)
- struct loop *loop;
+loop_preheader_edge (const struct loop *loop)
{
edge e;
@@ -1199,4 +1286,3 @@ loop_preheader_edge (loop)
return e;
}
-
diff --git a/contrib/gcc/cfgloop.h b/contrib/gcc/cfgloop.h
new file mode 100644
index 000000000000..33e906d6a6bc
--- /dev/null
+++ b/contrib/gcc/cfgloop.h
@@ -0,0 +1,341 @@
+/* Natural loop functions
+ Copyright (C) 1987, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Structure to hold decision about unrolling/peeling. */
+enum lpt_dec
+{
+ LPT_NONE,
+ LPT_PEEL_COMPLETELY,
+ LPT_PEEL_SIMPLE,
+ LPT_UNROLL_CONSTANT,
+ LPT_UNROLL_RUNTIME,
+ LPT_UNROLL_STUPID
+};
+
+struct lpt_decision
+{
+ enum lpt_dec decision;
+ unsigned times;
+};
+
+/* Description of loop for simple loop unrolling. */
+struct loop_desc
+{
+ int postincr; /* 1 if increment/decrement is done after loop exit condition. */
+ rtx stride; /* Value added to VAR in each iteration. */
+ rtx var; /* Loop control variable. */
+ enum machine_mode inner_mode;
+ /* The mode from that it is extended. */
+ enum rtx_code extend; /* With this extend. */
+ rtx var_alts; /* List of definitions of its initial value. */
+ rtx lim; /* Expression var is compared with. */
+ rtx lim_alts; /* List of definitions of its initial value. */
+ bool const_iter; /* True if it iterates constant number of times. */
+ unsigned HOST_WIDE_INT niter;
+ /* Number of iterations if it is constant. */
+ bool may_be_zero; /* If we cannot determine that the first iteration will pass. */
+ enum rtx_code cond; /* Exit condition. */
+ int neg; /* Set to 1 if loop ends when condition is satisfied. */
+ edge out_edge; /* The exit edge. */
+ edge in_edge; /* And the other one. */
+ int n_branches; /* Number of branches inside the loop. */
+};
+
+/* Structure to hold information for each natural loop. */
+struct loop
+{
+ /* Index into loops array. */
+ int num;
+
+ /* Basic block of loop header. */
+ basic_block header;
+
+ /* Basic block of loop latch. */
+ basic_block latch;
+
+ /* Basic block of loop preheader or NULL if it does not exist. */
+ basic_block pre_header;
+
+ /* For loop unrolling/peeling decision. */
+ struct lpt_decision lpt_decision;
+
+ /* Simple loop description. */
+ int simple;
+ struct loop_desc desc;
+ int has_desc;
+
+ /* Number of loop insns. */
+ unsigned ninsns;
+
+ /* Average number of executed insns per iteration. */
+ unsigned av_ninsns;
+
+ /* Array of edges along the preheader extended basic block trace.
+ The source of the first edge is the root node of preheader
+ extended basic block, if it exists. */
+ edge *pre_header_edges;
+
+ /* Number of edges along the pre_header extended basic block trace. */
+ int num_pre_header_edges;
+
+ /* The first block in the loop. This is not necessarily the same as
+ the loop header. */
+ basic_block first;
+
+ /* The last block in the loop. This is not necessarily the same as
+ the loop latch. */
+ basic_block last;
+
+ /* Bitmap of blocks contained within the loop. */
+ sbitmap nodes;
+
+ /* Number of blocks contained within the loop. */
+ unsigned num_nodes;
+
+ /* Array of edges that enter the loop. */
+ edge *entry_edges;
+
+ /* Number of edges that enter the loop. */
+ int num_entries;
+
+ /* Array of edges that exit the loop. */
+ edge *exit_edges;
+
+ /* Number of edges that exit the loop. */
+ int num_exits;
+
+ /* Bitmap of blocks that dominate all exits of the loop. */
+ sbitmap exits_doms;
+
+ /* The loop nesting depth. */
+ int depth;
+
+ /* Superloops of the loop. */
+ struct loop **pred;
+
+ /* The height of the loop (enclosed loop levels) within the loop
+ hierarchy tree. */
+ int level;
+
+ /* The outer (parent) loop or NULL if outermost loop. */
+ struct loop *outer;
+
+ /* The first inner (child) loop or NULL if innermost loop. */
+ struct loop *inner;
+
+ /* Link to the next (sibling) loop. */
+ struct loop *next;
+
+ /* Loop that is copy of this loop. */
+ struct loop *copy;
+
+ /* Nonzero if the loop is invalid (e.g., contains setjmp.). */
+ int invalid;
+
+ /* Auxiliary info specific to a pass. */
+ void *aux;
+
+ /* The following are currently used by loop.c but they are likely to
+ disappear as loop.c is converted to use the CFG. */
+
+ /* Nonzero if the loop has a NOTE_INSN_LOOP_VTOP. */
+ rtx vtop;
+
+ /* Nonzero if the loop has a NOTE_INSN_LOOP_CONT.
+ A continue statement will generate a branch to NEXT_INSN (cont). */
+ rtx cont;
+
+ /* The dominator of cont. */
+ rtx cont_dominator;
+
+ /* The NOTE_INSN_LOOP_BEG. */
+ rtx start;
+
+ /* The NOTE_INSN_LOOP_END. */
+ rtx end;
+
+ /* For a rotated loop that is entered near the bottom,
+ this is the label at the top. Otherwise it is zero. */
+ rtx top;
+
+ /* Place in the loop where control enters. */
+ rtx scan_start;
+
+ /* The position where to sink insns out of the loop. */
+ rtx sink;
+
+ /* List of all LABEL_REFs which refer to code labels outside the
+ loop. Used by routines that need to know all loop exits, such as
+ final_biv_value and final_giv_value.
+
+ This does not include loop exits due to return instructions.
+ This is because all bivs and givs are pseudos, and hence must be
+ dead after a return, so the presence of a return does not affect
+ any of the optimizations that use this info. It is simpler to
+ just not include return instructions on this list. */
+ rtx exit_labels;
+
+ /* The number of LABEL_REFs on exit_labels for this loop and all
+ loops nested inside it. */
+ int exit_count;
+};
+
+/* Flags for state of loop structure. */
+enum
+{
+ LOOPS_HAVE_PREHEADERS = 1,
+ LOOPS_HAVE_SIMPLE_LATCHES = 2,
+ LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4
+};
+
+/* Structure to hold CFG information about natural loops within a function. */
+struct loops
+{
+ /* Number of natural loops in the function. */
+ unsigned num;
+
+ /* Maximum nested loop level in the function. */
+ unsigned levels;
+
+ /* Array of natural loop descriptors (scanning this array in reverse order
+ will find the inner loops before their enclosing outer loops). */
+ struct loop *array;
+
+ /* The above array is unused in new loop infrastructure and is kept only for
+ purposes of the old loop optimizer. Instead we store just pointers to
+ loops here. */
+ struct loop **parray;
+
+ /* Pointer to root of loop hierarchy tree. */
+ struct loop *tree_root;
+
+ /* Information derived from the CFG. */
+ struct cfg
+ {
+ /* The ordering of the basic blocks in a depth first search. */
+ int *dfs_order;
+
+ /* The reverse completion ordering of the basic blocks found in a
+ depth first search. */
+ int *rc_order;
+ } cfg;
+
+ /* Headers shared by multiple loops that should be merged. */
+ sbitmap shared_headers;
+
+ /* State of loops. */
+ int state;
+};
+
+/* Flags for loop discovery. */
+
+#define LOOP_TREE 1 /* Build loop hierarchy tree. */
+#define LOOP_PRE_HEADER 2 /* Analyze loop preheader. */
+#define LOOP_ENTRY_EDGES 4 /* Find entry edges. */
+#define LOOP_EXIT_EDGES 8 /* Find exit edges. */
+#define LOOP_EDGES (LOOP_ENTRY_EDGES | LOOP_EXIT_EDGES)
+#define LOOP_ALL 15 /* All of the above */
+
+/* Loop recognition. */
+extern int flow_loops_find (struct loops *, int flags);
+extern int flow_loops_update (struct loops *, int flags);
+extern void flow_loops_free (struct loops *);
+extern void flow_loops_dump (const struct loops *, FILE *,
+ void (*)(const struct loop *, FILE *, int), int);
+extern void flow_loop_dump (const struct loop *, FILE *,
+ void (*)(const struct loop *, FILE *, int), int);
+extern int flow_loop_scan (struct loop *, int);
+extern void flow_loop_free (struct loop *);
+void mark_irreducible_loops (struct loops *);
+
+/* Loop data structure manipulation/querying. */
+extern void flow_loop_tree_node_add (struct loop *, struct loop *);
+extern void flow_loop_tree_node_remove (struct loop *);
+extern bool flow_loop_outside_edge_p (const struct loop *, edge);
+extern bool flow_loop_nested_p (const struct loop *, const struct loop *);
+extern bool flow_bb_inside_loop_p (const struct loop *, const basic_block);
+extern struct loop * find_common_loop (struct loop *, struct loop *);
+extern int num_loop_insns (struct loop *);
+extern int average_num_loop_insns (struct loop *);
+
+/* Loops & cfg manipulation. */
+extern basic_block *get_loop_body (const struct loop *);
+extern edge *get_loop_exit_edges (const struct loop *, unsigned *);
+
+extern edge loop_preheader_edge (const struct loop *);
+extern edge loop_latch_edge (const struct loop *);
+
+extern void add_bb_to_loop (basic_block, struct loop *);
+extern void remove_bb_from_loops (basic_block);
+
+extern void cancel_loop (struct loops *, struct loop *);
+extern void cancel_loop_tree (struct loops *, struct loop *);
+
+extern basic_block loop_split_edge_with (edge, rtx);
+extern int fix_loop_placement (struct loop *);
+
+enum
+{
+ CP_SIMPLE_PREHEADERS = 1
+};
+
+extern void create_preheaders (struct loops *, int);
+extern void force_single_succ_latches (struct loops *);
+
+extern void verify_loop_structure (struct loops *);
+
+/* Loop analysis. */
+extern bool simple_loop_p (struct loop *, struct loop_desc *);
+extern rtx count_loop_iterations (struct loop_desc *, rtx, rtx);
+extern bool just_once_each_iteration_p (struct loop *, basic_block);
+extern unsigned expected_loop_iterations (const struct loop *);
+
+/* Loop manipulation. */
+extern bool can_duplicate_loop_p (struct loop *loop);
+
+#define DLTHE_FLAG_UPDATE_FREQ 1 /* Update frequencies in
+ duplicate_loop_to_header_edge. */
+
+extern int duplicate_loop_to_header_edge (struct loop *, edge, struct loops *,
+ unsigned, sbitmap, edge, edge *,
+ unsigned *, int);
+extern struct loop *loopify (struct loops *, edge, edge, basic_block);
+extern void unloop (struct loops *, struct loop *);
+extern bool remove_path (struct loops *, edge);
+extern edge split_loop_bb (basic_block, rtx);
+
+/* Loop optimizer initialization. */
+extern struct loops *loop_optimizer_init (FILE *);
+extern void loop_optimizer_finalize (struct loops *, FILE *);
+
+/* Optimization passes. */
+extern void unswitch_loops (struct loops *);
+
+enum
+{
+ UAP_PEEL = 1, /* Enables loop peeling. */
+ UAP_UNROLL = 2, /* Enables peeling of loops if it seems profitable. */
+ UAP_UNROLL_ALL = 4 /* Enables peeling of all loops. */
+};
+
+extern void unroll_and_peel_loops (struct loops *, int);
+extern bool is_bct_cond (rtx);
+extern rtx get_var_set_from_bct (rtx);
diff --git a/contrib/gcc/cfgloopanal.c b/contrib/gcc/cfgloopanal.c
new file mode 100644
index 000000000000..6cc8f66c87a0
--- /dev/null
+++ b/contrib/gcc/cfgloopanal.c
@@ -0,0 +1,1482 @@
+/* Natural loop analysis code for GNU compiler.
+ Copyright (C) 2002, 2003, 2004 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "cfgloop.h"
+#include "expr.h"
+#include "output.h"
+/* Needed for doloop_condition_get(). */
+#include "loop.h"
+
+struct unmark_altered_insn_data;
+static void unmark_altered (rtx, rtx, regset);
+static void blocks_invariant_registers (basic_block *, int, regset);
+static void unmark_altered_insn (rtx, rtx, struct unmark_altered_insn_data *);
+static void blocks_single_set_registers (basic_block *, int, rtx *);
+static int invariant_rtx_wrto_regs_p_helper (rtx *, regset);
+static bool invariant_rtx_wrto_regs_p (rtx, regset);
+static rtx test_for_iteration (struct loop_desc *desc, unsigned HOST_WIDE_INT);
+static bool constant_iterations (struct loop_desc *, unsigned HOST_WIDE_INT *,
+ bool *);
+static bool simple_loop_exit_p (struct loop *, edge, regset,
+ rtx *, struct loop_desc *);
+static rtx variable_initial_value (rtx, regset, rtx, rtx *, enum machine_mode);
+static rtx variable_initial_values (edge, rtx, enum machine_mode);
+static bool simple_condition_p (struct loop *, rtx, regset,
+ struct loop_desc *);
+static basic_block simple_increment (struct loop *, rtx *, struct loop_desc *);
+static rtx count_strange_loop_iterations (rtx, rtx, enum rtx_code,
+ int, rtx, enum machine_mode,
+ enum machine_mode);
+static unsigned HOST_WIDEST_INT inverse (unsigned HOST_WIDEST_INT, int);
+static bool fits_in_mode_p (enum machine_mode mode, rtx expr);
+
+/* Computes inverse to X modulo (1 << MOD). */
+static unsigned HOST_WIDEST_INT
+inverse (unsigned HOST_WIDEST_INT x, int mod)
+{
+ unsigned HOST_WIDEST_INT mask =
+ ((unsigned HOST_WIDEST_INT) 1 << (mod - 1) << 1) - 1;
+ unsigned HOST_WIDEST_INT rslt = 1;
+ int i;
+
+ for (i = 0; i < mod - 1; i++)
+ {
+ rslt = (rslt * x) & mask;
+ x = (x * x) & mask;
+ }
+
+ return rslt;
+}
+
+/* Checks whether BB is executed exactly once in each LOOP iteration. */
+bool
+just_once_each_iteration_p (struct loop *loop, basic_block bb)
+{
+ /* It must be executed at least once each iteration. */
+ if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
+ return false;
+
+ /* And just once. */
+ if (bb->loop_father != loop)
+ return false;
+
+ /* But this was not enough. We might have some irreducible loop here. */
+ if (bb->flags & BB_IRREDUCIBLE_LOOP)
+ return false;
+
+ return true;
+}
+
+
+/* Unmarks modified registers; helper to blocks_invariant_registers. */
+static void
+unmark_altered (rtx what, rtx by ATTRIBUTE_UNUSED, regset regs)
+{
+ if (GET_CODE (what) == SUBREG)
+ what = SUBREG_REG (what);
+ if (!REG_P (what))
+ return;
+ CLEAR_REGNO_REG_SET (regs, REGNO (what));
+}
+
+/* Marks registers that are invariant inside blocks BBS. */
+static void
+blocks_invariant_registers (basic_block *bbs, int nbbs, regset regs)
+{
+ rtx insn;
+ int i;
+
+ for (i = 0; i < max_reg_num (); i++)
+ SET_REGNO_REG_SET (regs, i);
+ for (i = 0; i < nbbs; i++)
+ for (insn = BB_HEAD (bbs[i]);
+ insn != NEXT_INSN (BB_END (bbs[i]));
+ insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ note_stores (PATTERN (insn),
+ (void (*) (rtx, rtx, void *)) unmark_altered,
+ regs);
+}
+
+/* Unmarks modified registers; helper to blocks_single_set_registers. */
+struct unmark_altered_insn_data
+{
+ rtx *regs;
+ rtx insn;
+};
+
+static void
+unmark_altered_insn (rtx what, rtx by ATTRIBUTE_UNUSED,
+ struct unmark_altered_insn_data *data)
+{
+ int rn;
+
+ if (GET_CODE (what) == SUBREG)
+ what = SUBREG_REG (what);
+ if (!REG_P (what))
+ return;
+ rn = REGNO (what);
+ if (data->regs[rn] == data->insn)
+ return;
+ data->regs[rn] = NULL;
+}
+
+/* Marks registers that have just single simple set in BBS; the relevant
+ insn is returned in REGS. */
+static void
+blocks_single_set_registers (basic_block *bbs, int nbbs, rtx *regs)
+{
+ rtx insn;
+ int i;
+ struct unmark_altered_insn_data data;
+
+ for (i = 0; i < max_reg_num (); i++)
+ regs[i] = NULL;
+
+ for (i = 0; i < nbbs; i++)
+ for (insn = BB_HEAD (bbs[i]);
+ insn != NEXT_INSN (BB_END (bbs[i]));
+ insn = NEXT_INSN (insn))
+ {
+ rtx set = single_set (insn);
+
+ if (!set && is_bct_cond (insn))
+ set = get_var_set_from_bct(insn);
+
+ if (!set)
+ continue;
+ if (!REG_P (SET_DEST (set)))
+ continue;
+ regs[REGNO (SET_DEST (set))] = insn;
+ }
+
+ data.regs = regs;
+ for (i = 0; i < nbbs; i++)
+ for (insn = BB_HEAD (bbs[i]);
+ insn != NEXT_INSN (BB_END (bbs[i]));
+ insn = NEXT_INSN (insn))
+ {
+ if (!INSN_P (insn))
+ continue;
+ data.insn = insn;
+ note_stores (PATTERN (insn),
+ (void (*) (rtx, rtx, void *)) unmark_altered_insn,
+ &data);
+ }
+}
+
+/* Helper for invariant_rtx_wrto_regs_p. */
+static int
+invariant_rtx_wrto_regs_p_helper (rtx *expr, regset invariant_regs)
+{
+ switch (GET_CODE (*expr))
+ {
+ case CC0:
+ case PC:
+ case UNSPEC_VOLATILE:
+ return 1;
+
+ case CONST_INT:
+ case CONST_DOUBLE:
+ case CONST:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ return 0;
+
+ case ASM_OPERANDS:
+ return MEM_VOLATILE_P (*expr);
+
+ case MEM:
+ /* If the memory is not constant, assume it is modified. If it is
+ constant, we still have to check the address. */
+ return !RTX_UNCHANGING_P (*expr);
+
+ case REG:
+ return !REGNO_REG_SET_P (invariant_regs, REGNO (*expr));
+
+ default:
+ return 0;
+ }
+}
+
+/* Checks that EXPR is invariant provided that INVARIANT_REGS are invariant. */
+static bool
+invariant_rtx_wrto_regs_p (rtx expr, regset invariant_regs)
+{
+ return !for_each_rtx (&expr, (rtx_function) invariant_rtx_wrto_regs_p_helper,
+ invariant_regs);
+}
+
+/* Checks whether CONDITION is a simple comparison in that one of operands
+ is register and the other one is invariant in the LOOP. Fills var, lim
+ and cond fields in DESC. */
+static bool
+simple_condition_p (struct loop *loop ATTRIBUTE_UNUSED, rtx condition,
+ regset invariant_regs, struct loop_desc *desc)
+{
+ rtx op0, op1;
+
+ /* Check condition. */
+ switch (GET_CODE (condition))
+ {
+ case EQ:
+ case NE:
+ case LE:
+ case LT:
+ case GE:
+ case GT:
+ case GEU:
+ case GTU:
+ case LEU:
+ case LTU:
+ break;
+ default:
+ return false;
+ }
+
+ /* Of integers or pointers. */
+ if (GET_MODE_CLASS (GET_MODE (XEXP (condition, 0))) != MODE_INT
+ && GET_MODE_CLASS (GET_MODE (XEXP (condition, 0))) != MODE_PARTIAL_INT)
+ return false;
+
+ /* One of operands must be a simple register. */
+ op0 = XEXP (condition, 0);
+ op1 = XEXP (condition, 1);
+
+ /* One of operands must be invariant. */
+ if (invariant_rtx_wrto_regs_p (op0, invariant_regs))
+ {
+ /* And the other one must be a register. */
+ if (!REG_P (op1))
+ return false;
+ desc->var = op1;
+ desc->lim = op0;
+
+ desc->cond = swap_condition (GET_CODE (condition));
+ if (desc->cond == UNKNOWN)
+ return false;
+ return true;
+ }
+
+ /* Check the other operand. */
+ if (!invariant_rtx_wrto_regs_p (op1, invariant_regs))
+ return false;
+ if (!REG_P (op0))
+ return false;
+
+ desc->var = op0;
+ desc->lim = op1;
+
+ desc->cond = GET_CODE (condition);
+
+ return true;
+}
+
+/* Checks whether DESC->var is incremented/decremented exactly once each
+ iteration. Fills in DESC->stride and returns block in that DESC->var is
+ modified. */
+static basic_block
+simple_increment (struct loop *loop, rtx *simple_increment_regs,
+ struct loop_desc *desc)
+{
+ rtx mod_insn, mod_insn1, set, set_src, set_add;
+ basic_block mod_bb, mod_bb1;
+
+ /* Find insn that modifies var. */
+ mod_insn = simple_increment_regs[REGNO (desc->var)];
+ if (!mod_insn)
+ return NULL;
+ mod_bb = BLOCK_FOR_INSN (mod_insn);
+
+ /* Check that it is executed exactly once each iteration. */
+ if (!just_once_each_iteration_p (loop, mod_bb))
+ return NULL;
+
+ /* mod_insn must be a simple increment/decrement. */
+ set = single_set (mod_insn);
+
+ if (!set && is_bct_cond (mod_insn))
+ set = get_var_set_from_bct(mod_insn);
+
+ if (!set)
+ abort ();
+ if (!rtx_equal_p (SET_DEST (set), desc->var))
+ abort ();
+
+ set_src = find_reg_equal_equiv_note (mod_insn);
+ if (!set_src)
+ set_src = SET_SRC (set);
+
+ /* Check for variables that iterate in narrower mode. */
+ if (GET_CODE (set_src) == SIGN_EXTEND
+ || GET_CODE (set_src) == ZERO_EXTEND)
+ {
+ /* If we are sign extending variable that is then compared unsigned
+ or vice versa, there is something weird happening. */
+ if (desc->cond != EQ
+ && desc->cond != NE
+ && ((desc->cond == LEU
+ || desc->cond == LTU
+ || desc->cond == GEU
+ || desc->cond == GTU)
+ ^ (GET_CODE (set_src) == ZERO_EXTEND)))
+ return NULL;
+
+ if (GET_CODE (XEXP (set_src, 0)) != SUBREG
+ || SUBREG_BYTE (XEXP (set_src, 0)) != 0
+ || GET_MODE (SUBREG_REG (XEXP (set_src, 0))) != GET_MODE (desc->var))
+ return NULL;
+
+ desc->inner_mode = GET_MODE (XEXP (set_src, 0));
+ desc->extend = GET_CODE (set_src);
+ set_src = SUBREG_REG (XEXP (set_src, 0));
+
+ if (GET_CODE (set_src) != REG)
+ return NULL;
+
+ /* Find where the reg is set. */
+ mod_insn1 = simple_increment_regs[REGNO (set_src)];
+ if (!mod_insn1)
+ return NULL;
+
+ mod_bb1 = BLOCK_FOR_INSN (mod_insn1);
+ if (!dominated_by_p (CDI_DOMINATORS, mod_bb, mod_bb1))
+ return NULL;
+ if (mod_bb1 == mod_bb)
+ {
+ for (;
+ mod_insn != PREV_INSN (BB_HEAD (mod_bb));
+ mod_insn = PREV_INSN (mod_insn))
+ if (mod_insn == mod_insn1)
+ break;
+
+ if (mod_insn == PREV_INSN (BB_HEAD (mod_bb)))
+ return NULL;
+ }
+
+ /* Replace the source with the possible place of increment. */
+ set = single_set (mod_insn1);
+ if (!set)
+ abort ();
+ if (!rtx_equal_p (SET_DEST (set), set_src))
+ abort ();
+
+ set_src = find_reg_equal_equiv_note (mod_insn1);
+ if (!set_src)
+ set_src = SET_SRC (set);
+ }
+ else
+ {
+ desc->inner_mode = GET_MODE (desc->var);
+ desc->extend = NIL;
+ }
+
+ if (GET_CODE (set_src) != PLUS)
+ return NULL;
+ if (!rtx_equal_p (XEXP (set_src, 0), desc->var))
+ return NULL;
+
+ /* Set desc->stride. */
+ set_add = XEXP (set_src, 1);
+ if (CONSTANT_P (set_add))
+ desc->stride = set_add;
+ else
+ return NULL;
+
+ return mod_bb;
+}
+
+/* Tries to find initial value of VAR in INSN. This value must be invariant
+ wrto INVARIANT_REGS. If SET_INSN is not NULL, insn in that var is set is
+ placed here. INNER_MODE is mode in that induction variable VAR iterates. */
+static rtx
+variable_initial_value (rtx insn, regset invariant_regs,
+ rtx var, rtx *set_insn, enum machine_mode inner_mode)
+{
+ basic_block bb;
+ rtx set;
+ rtx ret = NULL;
+
+ /* Go back through cfg. */
+ bb = BLOCK_FOR_INSN (insn);
+ while (1)
+ {
+ for (; insn != BB_HEAD (bb); insn = PREV_INSN (insn))
+ {
+ if (INSN_P (insn))
+ note_stores (PATTERN (insn),
+ (void (*) (rtx, rtx, void *)) unmark_altered,
+ invariant_regs);
+ if (modified_between_p (var, PREV_INSN (insn), NEXT_INSN (insn)))
+ break;
+ }
+
+ if (insn != BB_HEAD (bb))
+ {
+ /* We found place where var is set. */
+ rtx set_dest;
+ rtx val;
+ rtx note;
+
+ set = single_set (insn);
+ if (!set)
+ return NULL;
+ set_dest = SET_DEST (set);
+ if (!rtx_equal_p (set_dest, var))
+ return NULL;
+
+ note = find_reg_equal_equiv_note (insn);
+ if (note && GET_CODE (XEXP (note, 0)) != EXPR_LIST)
+ val = XEXP (note, 0);
+ else
+ val = SET_SRC (set);
+
+ /* If we know that the initial value is indeed in range of
+ the inner mode, record the fact even in case the value itself
+ is useless. */
+ if ((GET_CODE (val) == SIGN_EXTEND
+ || GET_CODE (val) == ZERO_EXTEND)
+ && GET_MODE (XEXP (val, 0)) == inner_mode)
+ ret = gen_rtx_fmt_e (GET_CODE (val),
+ GET_MODE (var),
+ gen_rtx_fmt_ei (SUBREG,
+ inner_mode,
+ var, 0));
+
+ if (!invariant_rtx_wrto_regs_p (val, invariant_regs))
+ return ret;
+
+ if (set_insn)
+ *set_insn = insn;
+ return val;
+ }
+
+
+ if (bb->pred->pred_next || bb->pred->src == ENTRY_BLOCK_PTR)
+ return NULL;
+
+ bb = bb->pred->src;
+ insn = BB_END (bb);
+ }
+
+ return NULL;
+}
+
+/* Returns list of definitions of initial value of VAR at edge E. INNER_MODE
+ is mode in that induction variable VAR really iterates. */
+static rtx
+variable_initial_values (edge e, rtx var, enum machine_mode inner_mode)
+{
+ rtx set_insn, list;
+ regset invariant_regs;
+ regset_head invariant_regs_head;
+ int i;
+
+ invariant_regs = INITIALIZE_REG_SET (invariant_regs_head);
+ for (i = 0; i < max_reg_num (); i++)
+ SET_REGNO_REG_SET (invariant_regs, i);
+
+ list = alloc_EXPR_LIST (0, copy_rtx (var), NULL);
+
+ if (e->src == ENTRY_BLOCK_PTR)
+ return list;
+
+ set_insn = BB_END (e->src);
+ while (REG_P (var)
+ && (var = variable_initial_value (set_insn, invariant_regs, var,
+ &set_insn, inner_mode)))
+ list = alloc_EXPR_LIST (0, copy_rtx (var), list);
+
+ FREE_REG_SET (invariant_regs);
+ return list;
+}
+
+/* Counts constant number of iterations of the loop described by DESC;
+ returns false if impossible. */
+static bool
+constant_iterations (struct loop_desc *desc, unsigned HOST_WIDE_INT *niter,
+ bool *may_be_zero)
+{
+ rtx test, expr;
+ rtx ainit, alim;
+
+ test = test_for_iteration (desc, 0);
+ if (test == const0_rtx)
+ {
+ *niter = 0;
+ *may_be_zero = false;
+ return true;
+ }
+
+ *may_be_zero = (test != const_true_rtx);
+
+ /* It would make a little sense to check every with every when we
+ know that all but the first alternative are simply registers. */
+ for (ainit = desc->var_alts; ainit; ainit = XEXP (ainit, 1))
+ {
+ alim = XEXP (desc->lim_alts, 0);
+ if (!(expr = count_loop_iterations (desc, XEXP (ainit, 0), alim)))
+ continue;
+ if (GET_CODE (expr) == CONST_INT)
+ {
+ *niter = INTVAL (expr);
+ return true;
+ }
+ }
+ for (alim = XEXP (desc->lim_alts, 1); alim; alim = XEXP (alim, 1))
+ {
+ ainit = XEXP (desc->var_alts, 0);
+ if (!(expr = count_loop_iterations (desc, ainit, XEXP (alim, 0))))
+ continue;
+ if (GET_CODE (expr) == CONST_INT)
+ {
+ *niter = INTVAL (expr);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Attempts to determine a number of iterations of a "strange" loop.
+ Its induction variable starts with value INIT, is compared by COND
+ with LIM. If POSTINCR, it is incremented after the test. It is incremented
+ by STRIDE each iteration, has mode MODE but iterates in INNER_MODE.
+
+ By "strange" we mean loops where induction variable increases in the wrong
+ direction wrto comparison, i.e. for (i = 6; i > 5; i++). */
+static rtx
+count_strange_loop_iterations (rtx init, rtx lim, enum rtx_code cond,
+ int postincr, rtx stride, enum machine_mode mode,
+ enum machine_mode inner_mode)
+{
+ rtx rqmt, n_to_wrap, before_wrap, after_wrap;
+ rtx mode_min, mode_max;
+ int size;
+
+ /* This could be handled, but it is not important enough to lose time with
+ it just now. */
+ if (mode != inner_mode)
+ return NULL_RTX;
+
+ if (!postincr)
+ init = simplify_gen_binary (PLUS, mode, init, stride);
+
+ /* If we are able to prove that we don't pass the first test, we are
+ done. */
+ rqmt = simplify_relational_operation (cond, mode, init, lim);
+ if (rqmt == const0_rtx)
+ return const0_rtx;
+
+ /* And if we don't know we pass it, the things are too complicated for us. */
+ if (rqmt != const_true_rtx)
+ return NULL_RTX;
+
+ switch (cond)
+ {
+ case GE:
+ case GT:
+ case LE:
+ case LT:
+ size = GET_MODE_BITSIZE (mode);
+ mode_min = gen_int_mode (-((unsigned HOST_WIDEST_INT) 1 << (size - 1)),
+ mode);
+ mode_max = gen_int_mode (((unsigned HOST_WIDEST_INT) 1 << (size - 1)) - 1,
+ mode);
+
+ break;
+
+ case GEU:
+ case GTU:
+ case LEU:
+ case LTU:
+ case EQ:
+ mode_min = const0_rtx;
+ mode_max = simplify_gen_binary (MINUS, mode, const0_rtx, const1_rtx);
+ break;
+
+ default:
+ abort ();
+ }
+
+ switch (cond)
+ {
+ case EQ:
+ /* This iterates once, as init == lim. */
+ return const1_rtx;
+
+ /* The behavior is undefined in signed cases. Never mind, we still
+ try to behave sanely. */
+ case GE:
+ case GT:
+ case GEU:
+ case GTU:
+ if (INTVAL (stride) <= 0)
+ abort ();
+ n_to_wrap = simplify_gen_binary (MINUS, mode, mode_max, copy_rtx (init));
+ n_to_wrap = simplify_gen_binary (UDIV, mode, n_to_wrap, stride);
+ before_wrap = simplify_gen_binary (MULT, mode,
+ copy_rtx (n_to_wrap), stride);
+ before_wrap = simplify_gen_binary (PLUS, mode,
+ before_wrap, copy_rtx (init));
+ after_wrap = simplify_gen_binary (PLUS, mode,
+ before_wrap, stride);
+ if (GET_CODE (after_wrap) != CONST_INT)
+ {
+ after_wrap = simplify_gen_binary (PLUS, mode, mode_min, stride);
+ after_wrap = simplify_gen_binary (MINUS, mode, after_wrap, const1_rtx);
+ }
+ break;
+
+ case LE:
+ case LT:
+ case LEU:
+ case LTU:
+ if (INTVAL (stride) >= 0)
+ abort ();
+ stride = simplify_gen_unary (NEG, mode, stride, mode);
+ n_to_wrap = simplify_gen_binary (MINUS, mode, copy_rtx (init), mode_min);
+ n_to_wrap = simplify_gen_binary (UDIV, mode, n_to_wrap, stride);
+ before_wrap = simplify_gen_binary (MULT, mode,
+ copy_rtx (n_to_wrap), stride);
+ before_wrap = simplify_gen_binary (MINUS, mode,
+ copy_rtx (init), before_wrap);
+ after_wrap = simplify_gen_binary (MINUS, mode,
+ before_wrap, stride);
+ if (GET_CODE (after_wrap) != CONST_INT)
+ {
+ after_wrap = simplify_gen_binary (MINUS, mode, mode_max, stride);
+ after_wrap = simplify_gen_binary (PLUS, mode, after_wrap, const1_rtx);
+ }
+ break;
+ default:
+ abort ();
+ }
+
+ /* If this is const_true_rtx and we did not take a conservative approximation
+ of after_wrap above, we might iterate the calculation (but of course we
+ would have to take care about infinite cases). Ignore this for now. */
+ rqmt = simplify_relational_operation (cond, mode, after_wrap, lim);
+ if (rqmt != const0_rtx)
+ return NULL_RTX;
+
+ return simplify_gen_binary (PLUS, mode, n_to_wrap, const1_rtx);
+}
+
+/* Checks whether value of EXPR fits into range of MODE. */
+static bool
+fits_in_mode_p (enum machine_mode mode, rtx expr)
+{
+ unsigned HOST_WIDEST_INT val;
+ int n_bits = 0;
+
+ if (GET_CODE (expr) == CONST_INT)
+ {
+ for (val = INTVAL (expr); val; val >>= 1)
+ n_bits++;
+
+ return n_bits <= GET_MODE_BITSIZE (mode);
+ }
+
+ if (GET_CODE (expr) == SIGN_EXTEND
+ || GET_CODE (expr) == ZERO_EXTEND)
+ return GET_MODE (XEXP (expr, 0)) == mode;
+
+ return false;
+}
+
+/* Return RTX expression representing number of iterations of loop as bounded
+ by test described by DESC (in the case loop really has multiple exit
+ edges, fewer iterations may happen in the practice).
+
+ Return NULL if it is unknown. Additionally the value may be invalid for
+ paradoxical loop (lets define paradoxical loops as loops whose test is
+ failing at -1th iteration, for instance "for (i=5;i<1;i++);").
+
+ These cases needs to be either cared by copying the loop test in the front
+ of loop or keeping the test in first iteration of loop.
+
+ When INIT/LIM are set, they are used instead of var/lim of DESC. */
+rtx
+count_loop_iterations (struct loop_desc *desc, rtx init, rtx lim)
+{
+ enum rtx_code cond = desc->cond;
+ rtx stride = desc->stride;
+ rtx mod, exp, ainit, bound;
+ rtx overflow_check, mx, mxp;
+ enum machine_mode mode = GET_MODE (desc->var);
+ unsigned HOST_WIDEST_INT s, size, d;
+
+ /* Give up on floating point modes and friends. It can be possible to do
+ the job for constant loop bounds, but it is probably not worthwhile. */
+ if (!INTEGRAL_MODE_P (mode))
+ return NULL;
+
+ init = copy_rtx (init ? init : desc->var);
+ lim = copy_rtx (lim ? lim : desc->lim);
+
+ /* Ensure that we always handle the condition to stay inside loop. */
+ if (desc->neg)
+ cond = reverse_condition (cond);
+
+ if (desc->inner_mode != mode)
+ {
+ /* We have a case when the variable in fact iterates in the narrower
+ mode. This has following consequences:
+
+ For induction variable itself, if !desc->postincr, it does not mean
+ anything too special, since we know the variable is already in range
+ of the inner mode when we compare it (so it is just needed to shorten
+ it into the mode before calculations are done, so that we don't risk
+ wrong results). More complicated case is when desc->postincr; then
+ the first two iterations are special (the first one because the value
+ may be out of range, the second one because after shortening it to the
+ range it may have absolutely any value), and we do not handle this in
+ unrolling. So if we aren't able to prove that the initial value is in
+ the range, we fail in this case.
+
+ Step is just moduled to fit into inner mode.
+
+ If lim is out of range, then either the loop is infinite (and then
+ we may unroll however we like to), or exits in the first iteration
+ (this is also ok, since we handle it specially for this case anyway).
+ So we may safely assume that it fits into the inner mode. */
+
+ for (ainit = desc->var_alts; ainit; ainit = XEXP (ainit, 1))
+ if (fits_in_mode_p (desc->inner_mode, XEXP (ainit, 0)))
+ break;
+
+ if (!ainit)
+ {
+ if (desc->postincr)
+ return NULL_RTX;
+
+ init = simplify_gen_unary (desc->extend,
+ mode,
+ simplify_gen_subreg (desc->inner_mode,
+ init,
+ mode,
+ 0),
+ desc->inner_mode);
+ }
+
+ stride = simplify_gen_subreg (desc->inner_mode, stride, mode, 0);
+ if (stride == const0_rtx)
+ return NULL_RTX;
+ }
+
+ /* Prepare condition to verify that we do not risk overflow. */
+ if (stride == const1_rtx
+ || stride == constm1_rtx
+ || cond == NE
+ || cond == EQ)
+ {
+ /* Overflow at NE conditions does not occur. EQ condition
+ is weird and is handled in count_strange_loop_iterations.
+ If stride is 1, overflow may occur only for <= and >= conditions,
+ and then they are infinite, so it does not bother us. */
+ overflow_check = const0_rtx;
+ }
+ else
+ {
+ if (cond == LT || cond == LTU)
+ mx = simplify_gen_binary (MINUS, mode, lim, const1_rtx);
+ else if (cond == GT || cond == GTU)
+ mx = simplify_gen_binary (PLUS, mode, lim, const1_rtx);
+ else
+ mx = lim;
+ if (mode != desc->inner_mode)
+ mxp = simplify_gen_subreg (desc->inner_mode, mx, mode, 0);
+ else
+ mxp = mx;
+ mxp = simplify_gen_binary (PLUS, desc->inner_mode, mxp, stride);
+ if (mode != desc->inner_mode)
+ mxp = simplify_gen_unary (desc->extend, mode, mxp, desc->inner_mode);
+ overflow_check = simplify_gen_relational (cond, SImode, mode, mx, mxp);
+ }
+
+ /* Compute absolute value of the difference of initial and final value. */
+ if (INTVAL (stride) > 0)
+ {
+ /* Handle strange tests specially. */
+ if (cond == EQ || cond == GE || cond == GT || cond == GEU
+ || cond == GTU)
+ return count_strange_loop_iterations (init, lim, cond, desc->postincr,
+ stride, mode, desc->inner_mode);
+ exp = simplify_gen_binary (MINUS, mode, lim, init);
+ }
+ else
+ {
+ if (cond == EQ || cond == LE || cond == LT || cond == LEU
+ || cond == LTU)
+ return count_strange_loop_iterations (init, lim, cond, desc->postincr,
+ stride, mode, desc->inner_mode);
+ exp = simplify_gen_binary (MINUS, mode, init, lim);
+ stride = simplify_gen_unary (NEG, mode, stride, mode);
+ }
+
+ /* If there is a risk of overflow (i.e. when we increment value satisfying
+ a condition, we may again obtain a value satisfying the condition),
+ fail. */
+ if (overflow_check != const0_rtx)
+ return NULL_RTX;
+
+ /* Normalize difference so the value is always first examined
+ and later incremented. Do not do this for a loop ending with a branch
+ and count register. */
+ if (!is_bct_cond (BB_END (desc->out_edge->src)) && (!desc->postincr))
+ exp = simplify_gen_binary (MINUS, mode, exp, stride);
+
+ /* Determine delta caused by exit condition. */
+ switch (cond)
+ {
+ case NE:
+ /* NE tests are easy to handle, because we just perform simple
+ arithmetics modulo power of 2. Let's use the fact to compute the
+ number of iterations exactly. We are now in situation when we want to
+ solve an equation stride * i = c (mod size of inner_mode).
+ Let nsd (stride, size of mode) = d. If d does not divide c, the
+ loop is infinite. Otherwise, the number of iterations is
+ (inverse(s/d) * (c/d)) mod (size of mode/d). */
+ size = GET_MODE_BITSIZE (desc->inner_mode);
+ s = INTVAL (stride);
+ d = 1;
+ while (s % 2 != 1)
+ {
+ s /= 2;
+ d *= 2;
+ size--;
+ }
+ bound = gen_int_mode (((unsigned HOST_WIDEST_INT) 1 << (size - 1 ) << 1) - 1,
+ mode);
+ exp = simplify_gen_binary (UDIV, mode, exp, gen_int_mode (d, mode));
+ exp = simplify_gen_binary (MULT, mode,
+ exp, gen_int_mode (inverse (s, size), mode));
+ exp = simplify_gen_binary (AND, mode, exp, bound);
+ break;
+
+ case LT:
+ case GT:
+ case LTU:
+ case GTU:
+ break;
+ case LE:
+ case GE:
+ case LEU:
+ case GEU:
+ exp = simplify_gen_binary (PLUS, mode, exp, const1_rtx);
+ break;
+ default:
+ abort ();
+ }
+
+ if (cond != NE && stride != const1_rtx)
+ {
+ /* Number of iterations is now (EXP + STRIDE - 1 / STRIDE),
+ but we need to take care for overflows. */
+
+ mod = simplify_gen_binary (UMOD, mode, exp, stride);
+
+ /* This is dirty trick. When we can't compute number of iterations
+ to be constant, we simply ignore the possible overflow, as
+ runtime unroller always use power of 2 amounts and does not
+ care about possible lost bits. */
+
+ if (GET_CODE (mod) != CONST_INT)
+ {
+ rtx stridem1 = simplify_gen_binary (PLUS, mode, stride, constm1_rtx);
+ exp = simplify_gen_binary (PLUS, mode, exp, stridem1);
+ exp = simplify_gen_binary (UDIV, mode, exp, stride);
+ }
+ else
+ {
+ exp = simplify_gen_binary (UDIV, mode, exp, stride);
+ if (mod != const0_rtx)
+ exp = simplify_gen_binary (PLUS, mode, exp, const1_rtx);
+ }
+ }
+
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, "; Number of iterations: ");
+ print_simple_rtl (rtl_dump_file, exp);
+ fprintf (rtl_dump_file, "\n");
+ }
+
+ return exp;
+}
+
+/* Return simplified RTX expression representing the value of test
+ described of DESC at given iteration of loop. */
+
+static rtx
+test_for_iteration (struct loop_desc *desc, unsigned HOST_WIDE_INT iter)
+{
+ enum rtx_code cond = desc->cond;
+ rtx exp = XEXP (desc->var_alts, 0);
+ rtx addval;
+
+ /* Give up on floating point modes and friends. It can be possible to do
+ the job for constant loop bounds, but it is probably not worthwhile. */
+ if (!INTEGRAL_MODE_P (GET_MODE (desc->var)))
+ return NULL;
+
+ /* Ensure that we always handle the condition to stay inside loop. */
+ if (desc->neg)
+ cond = reverse_condition (cond);
+
+ /* Compute the value of induction variable. */
+ addval = simplify_gen_binary (MULT, GET_MODE (desc->var),
+ desc->stride,
+ gen_int_mode (desc->postincr
+ ? iter : iter + 1,
+ GET_MODE (desc->var)));
+ exp = simplify_gen_binary (PLUS, GET_MODE (desc->var), exp, addval);
+ /* Test at given condition. */
+ exp = simplify_gen_relational (cond, SImode,
+ GET_MODE (desc->var), exp, desc->lim);
+
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, "; Conditional to continue loop at "
+ HOST_WIDE_INT_PRINT_UNSIGNED "th iteration: ", iter);
+ print_simple_rtl (rtl_dump_file, exp);
+ fprintf (rtl_dump_file, "\n");
+ }
+ return exp;
+}
+
+
+/* Tests whether exit at EXIT_EDGE from LOOP is simple. Returns simple loop
+ description joined to it in in DESC. INVARIANT_REGS and SINGLE_SET_REGS
+ are results of blocks_{invariant,single_set}_regs over BODY. */
+static bool
+simple_loop_exit_p (struct loop *loop, edge exit_edge,
+ regset invariant_regs, rtx *single_set_regs,
+ struct loop_desc *desc)
+{
+ basic_block mod_bb, exit_bb;
+ int fallthru_out;
+ rtx condition;
+ edge ei, e;
+
+ exit_bb = exit_edge->src;
+
+ fallthru_out = (exit_edge->flags & EDGE_FALLTHRU);
+
+ if (!exit_bb)
+ return false;
+
+ /* It must be tested (at least) once during any iteration. */
+ if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit_bb))
+ return false;
+
+ /* It must end in a simple conditional jump. */
+ if (!any_condjump_p (BB_END (exit_bb)))
+ return false;
+
+ ei = exit_bb->succ;
+ if (ei == exit_edge)
+ ei = ei->succ_next;
+
+ desc->out_edge = exit_edge;
+ desc->in_edge = ei;
+
+ /* Condition must be a simple comparison in that one of operands
+ is register and the other one is invariant. */
+ if (!(condition = get_condition (BB_END (exit_bb), NULL, false)))
+ return false;
+
+ if (!simple_condition_p (loop, condition, invariant_regs, desc))
+ return false;
+
+ /* Var must be simply incremented or decremented in exactly one insn that
+ is executed just once every iteration. */
+ if (!(mod_bb = simple_increment (loop, single_set_regs, desc)))
+ return false;
+
+ /* OK, it is simple loop. Now just fill in remaining info. */
+ desc->postincr = !dominated_by_p (CDI_DOMINATORS, exit_bb, mod_bb);
+ desc->neg = !fallthru_out;
+
+ /* Find initial value of var and alternative values for lim. */
+ e = loop_preheader_edge (loop);
+ desc->var_alts = variable_initial_values (e, desc->var, desc->inner_mode);
+ desc->lim_alts = variable_initial_values (e, desc->lim, desc->inner_mode);
+
+ /* Number of iterations. */
+ desc->const_iter =
+ constant_iterations (desc, &desc->niter, &desc->may_be_zero);
+ if (!desc->const_iter && !count_loop_iterations (desc, NULL, NULL))
+ return false;
+ return true;
+}
+
+/* Tests whether LOOP is simple for loop. Returns simple loop description
+ in DESC. */
+bool
+simple_loop_p (struct loop *loop, struct loop_desc *desc)
+{
+ unsigned i;
+ basic_block *body;
+ edge e;
+ struct loop_desc act;
+ bool any = false;
+ regset invariant_regs;
+ regset_head invariant_regs_head;
+ rtx *single_set_regs;
+ int n_branches;
+
+ body = get_loop_body (loop);
+
+ invariant_regs = INITIALIZE_REG_SET (invariant_regs_head);
+ single_set_regs = xmalloc (max_reg_num () * sizeof (rtx));
+
+ blocks_invariant_registers (body, loop->num_nodes, invariant_regs);
+ blocks_single_set_registers (body, loop->num_nodes, single_set_regs);
+
+ n_branches = 0;
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ for (e = body[i]->succ; e; e = e->succ_next)
+ if (!flow_bb_inside_loop_p (loop, e->dest)
+ && simple_loop_exit_p (loop, e,
+ invariant_regs, single_set_regs, &act))
+ {
+ /* Prefer constant iterations; the less the better. */
+ if (!any)
+ any = true;
+ else if (!act.const_iter
+ || (desc->const_iter && act.niter >= desc->niter))
+ continue;
+ *desc = act;
+ }
+
+ if (body[i]->succ && body[i]->succ->succ_next)
+ n_branches++;
+ }
+ desc->n_branches = n_branches;
+
+ if (rtl_dump_file && any)
+ {
+ fprintf (rtl_dump_file, "; Simple loop %i\n", loop->num);
+ if (desc->postincr)
+ fprintf (rtl_dump_file,
+ "; does postincrement after loop exit condition\n");
+
+ fprintf (rtl_dump_file, "; Induction variable:");
+ print_simple_rtl (rtl_dump_file, desc->var);
+ fputc ('\n', rtl_dump_file);
+
+ fprintf (rtl_dump_file, "; Initial values:");
+ print_simple_rtl (rtl_dump_file, desc->var_alts);
+ fputc ('\n', rtl_dump_file);
+
+ fprintf (rtl_dump_file, "; Stride:");
+ print_simple_rtl (rtl_dump_file, desc->stride);
+ fputc ('\n', rtl_dump_file);
+
+ fprintf (rtl_dump_file, "; Compared with:");
+ print_simple_rtl (rtl_dump_file, desc->lim);
+ fputc ('\n', rtl_dump_file);
+
+ fprintf (rtl_dump_file, "; Alternative values:");
+ print_simple_rtl (rtl_dump_file, desc->lim_alts);
+ fputc ('\n', rtl_dump_file);
+
+ fprintf (rtl_dump_file, "; Exit condition:");
+ if (desc->neg)
+ fprintf (rtl_dump_file, "(negated)");
+ fprintf (rtl_dump_file, "%s\n", GET_RTX_NAME (desc->cond));
+
+ fprintf (rtl_dump_file, "; Number of branches:");
+ fprintf (rtl_dump_file, "%d\n", desc->n_branches);
+
+ fputc ('\n', rtl_dump_file);
+ }
+
+ free (body);
+ FREE_REG_SET (invariant_regs);
+ free (single_set_regs);
+ return any;
+}
+
+/* Marks blocks and edges that are part of non-recognized loops; i.e. we
+ throw away all latch edges and mark blocks inside any remaining cycle.
+ Everything is a bit complicated due to fact we do not want to do this
+ for parts of cycles that only "pass" through some loop -- i.e. for
+ each cycle, we want to mark blocks that belong directly to innermost
+ loop containing the whole cycle. */
+void
+mark_irreducible_loops (struct loops *loops)
+{
+ int *dfs_in, *closed, *mr, *mri, *n_edges, *stack;
+ unsigned i;
+ edge **edges, e;
+ edge *estack;
+ basic_block act;
+ int stack_top, tick, depth;
+ struct loop *cloop;
+
+ /* Reset the flags. */
+ FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
+ {
+ act->flags &= ~BB_IRREDUCIBLE_LOOP;
+ for (e = act->succ; e; e = e->succ_next)
+ e->flags &= ~EDGE_IRREDUCIBLE_LOOP;
+ }
+
+ /* The first last_basic_block + 1 entries are for real blocks (including
+ entry); then we have loops->num - 1 fake blocks for loops to that we
+ assign edges leading from loops (fake loop 0 is not interesting). */
+ dfs_in = xmalloc ((last_basic_block + loops->num) * sizeof (int));
+ closed = xmalloc ((last_basic_block + loops->num) * sizeof (int));
+ mr = xmalloc ((last_basic_block + loops->num) * sizeof (int));
+ mri = xmalloc ((last_basic_block + loops->num) * sizeof (int));
+ n_edges = xmalloc ((last_basic_block + loops->num) * sizeof (int));
+ edges = xmalloc ((last_basic_block + loops->num) * sizeof (edge *));
+ stack = xmalloc ((n_basic_blocks + loops->num) * sizeof (int));
+ estack = xmalloc ((n_basic_blocks + loops->num) * sizeof (edge));
+
+ /* Create the edge lists. */
+ for (i = 0; i < last_basic_block + loops->num; i++)
+ n_edges[i] = 0;
+ FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
+ for (e = act->succ; e; e = e->succ_next)
+ {
+ /* Ignore edges to exit. */
+ if (e->dest == EXIT_BLOCK_PTR)
+ continue;
+ /* And latch edges. */
+ if (e->dest->loop_father->header == e->dest
+ && e->dest->loop_father->latch == act)
+ continue;
+ /* Edges inside a single loop should be left where they are. Edges
+ to subloop headers should lead to representative of the subloop,
+ but from the same place. */
+ if (act->loop_father == e->dest->loop_father
+ || act->loop_father == e->dest->loop_father->outer)
+ {
+ n_edges[act->index + 1]++;
+ continue;
+ }
+ /* Edges exiting loops remain. They should lead from representative
+ of the son of nearest common ancestor of the loops in that
+ act lays. */
+ depth = find_common_loop (act->loop_father, e->dest->loop_father)->depth + 1;
+ if (depth == act->loop_father->depth)
+ cloop = act->loop_father;
+ else
+ cloop = act->loop_father->pred[depth];
+ n_edges[cloop->num + last_basic_block]++;
+ }
+
+ for (i = 0; i < last_basic_block + loops->num; i++)
+ {
+ edges[i] = xmalloc (n_edges[i] * sizeof (edge));
+ n_edges[i] = 0;
+ }
+
+ FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
+ for (e = act->succ; e; e = e->succ_next)
+ {
+ if (e->dest == EXIT_BLOCK_PTR)
+ continue;
+ if (e->dest->loop_father->header == e->dest
+ && e->dest->loop_father->latch == act)
+ continue;
+ if (act->loop_father == e->dest->loop_father
+ || act->loop_father == e->dest->loop_father->outer)
+ {
+ edges[act->index + 1][n_edges[act->index + 1]++] = e;
+ continue;
+ }
+ depth = find_common_loop (act->loop_father, e->dest->loop_father)->depth + 1;
+ if (depth == act->loop_father->depth)
+ cloop = act->loop_father;
+ else
+ cloop = act->loop_father->pred[depth];
+ i = cloop->num + last_basic_block;
+ edges[i][n_edges[i]++] = e;
+ }
+
+ /* Compute dfs numbering, starting from loop headers, and mark found
+ loops. */
+ tick = 0;
+ for (i = 0; i < last_basic_block + loops->num; i++)
+ {
+ dfs_in[i] = -1;
+ closed[i] = 0;
+ mr[i] = last_basic_block + loops->num;
+ mri[i] = -1;
+ }
+
+ stack_top = 0;
+ for (i = 0; i < loops->num; i++)
+ if (loops->parray[i])
+ {
+ stack[stack_top] = loops->parray[i]->header->index + 1;
+ estack[stack_top] = NULL;
+ stack_top++;
+ }
+
+ while (stack_top)
+ {
+ int idx, sidx;
+
+ idx = stack[stack_top - 1];
+ if (dfs_in[idx] < 0)
+ dfs_in[idx] = tick++;
+
+ while (n_edges[idx])
+ {
+ e = edges[idx][--n_edges[idx]];
+ sidx = e->dest->loop_father->header == e->dest
+ ? e->dest->loop_father->num + last_basic_block
+ : e->dest->index + 1;
+ if (closed[sidx])
+ {
+ if (mri[sidx] != -1 && !closed[mri[sidx]])
+ {
+ if (mr[sidx] < mr[idx])
+ {
+ mr[idx] = mr[sidx];
+ mri[idx] = mri[sidx];
+ }
+
+ if (mr[sidx] <= dfs_in[idx])
+ e->flags |= EDGE_IRREDUCIBLE_LOOP;
+ }
+ continue;
+ }
+ if (dfs_in[sidx] < 0)
+ {
+ stack[stack_top] = sidx;
+ estack[stack_top] = e;
+ stack_top++;
+ goto next;
+ }
+ if (dfs_in[sidx] < mr[idx])
+ {
+ mr[idx] = dfs_in[sidx];
+ mri[idx] = sidx;
+ }
+ e->flags |= EDGE_IRREDUCIBLE_LOOP;
+ }
+
+ /* Return back. */
+ closed[idx] = 1;
+ e = estack[stack_top - 1];
+ stack_top--;
+ if (e)
+ {
+ /* Propagate information back. */
+ sidx = stack[stack_top - 1];
+ if (mr[sidx] > mr[idx])
+ {
+ mr[sidx] = mr[idx];
+ mri[sidx] = mri[idx];
+ }
+ if (mr[idx] <= dfs_in[sidx])
+ e->flags |= EDGE_IRREDUCIBLE_LOOP;
+ }
+ /* Mark the block if relevant. */
+ if (idx && idx <= last_basic_block && mr[idx] <= dfs_in[idx])
+ BASIC_BLOCK (idx - 1)->flags |= BB_IRREDUCIBLE_LOOP;
+next:;
+ }
+
+ free (stack);
+ free (estack);
+ free (dfs_in);
+ free (closed);
+ free (mr);
+ free (mri);
+ for (i = 0; i < last_basic_block + loops->num; i++)
+ free (edges[i]);
+ free (edges);
+ free (n_edges);
+ loops->state |= LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
+}
+
+/* Counts number of insns inside LOOP. */
+int
+num_loop_insns (struct loop *loop)
+{
+ basic_block *bbs, bb;
+ unsigned i, ninsns = 0;
+ rtx insn;
+
+ bbs = get_loop_body (loop);
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ bb = bbs[i];
+ ninsns++;
+ for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ ninsns++;
+ }
+ free(bbs);
+
+ return ninsns;
+}
+
+/* Counts number of insns executed on average per iteration LOOP. */
+int
+average_num_loop_insns (struct loop *loop)
+{
+ basic_block *bbs, bb;
+ unsigned i, binsns, ninsns, ratio;
+ rtx insn;
+
+ ninsns = 0;
+ bbs = get_loop_body (loop);
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ bb = bbs[i];
+
+ binsns = 1;
+ for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ binsns++;
+
+ ratio = loop->header->frequency == 0
+ ? BB_FREQ_MAX
+ : (bb->frequency * BB_FREQ_MAX) / loop->header->frequency;
+ ninsns += binsns * ratio;
+ }
+ free(bbs);
+
+ ninsns /= BB_FREQ_MAX;
+ if (!ninsns)
+ ninsns = 1; /* To avoid division by zero. */
+
+ return ninsns;
+}
+
+/* Returns expected number of LOOP iterations.
+ Compute upper bound on number of iterations in case they do not fit integer
+ to help loop peeling heuristics. Use exact counts if at all possible. */
+unsigned
+expected_loop_iterations (const struct loop *loop)
+{
+ edge e;
+
+ if (loop->header->count)
+ {
+ gcov_type count_in, count_latch, expected;
+
+ count_in = 0;
+ count_latch = 0;
+
+ for (e = loop->header->pred; e; e = e->pred_next)
+ if (e->src == loop->latch)
+ count_latch = e->count;
+ else
+ count_in += e->count;
+
+ if (count_in == 0)
+ return 0;
+
+ expected = (count_latch + count_in - 1) / count_in;
+
+ /* Avoid overflows. */
+ return (expected > REG_BR_PROB_BASE ? REG_BR_PROB_BASE : expected);
+ }
+ else
+ {
+ int freq_in, freq_latch;
+
+ freq_in = 0;
+ freq_latch = 0;
+
+ for (e = loop->header->pred; e; e = e->pred_next)
+ if (e->src == loop->latch)
+ freq_latch = EDGE_FREQUENCY (e);
+ else
+ freq_in += EDGE_FREQUENCY (e);
+
+ if (freq_in == 0)
+ return 0;
+
+ return (freq_latch + freq_in - 1) / freq_in;
+ }
+}
+
+/* This function checks if an instruction is a branch and count instruction
+ no matter if the flag HAVE_doloop_end is enabled or not. An alternative
+ would be the modification of doloop_condition_get function itself. */
+bool
+is_bct_cond (rtx insn)
+{
+ if (GET_CODE (insn) != JUMP_INSN)
+ return false;
+
+#ifdef HAVE_doloop_end
+ if (!doloop_condition_get (PATTERN(insn)))
+ return false;
+#else
+ return false;
+#endif
+
+ return true;
+}
+
+/* Extract the increment of the count register from the branch and count
+ instruction. */
+rtx
+get_var_set_from_bct (rtx insn)
+{
+ rtx rhs, lhs, cond;
+ rtx pattern;
+ rtx set;
+ pattern = PATTERN (insn);
+
+ if (!is_bct_cond (insn))
+ abort ();
+
+ set = XVECEXP (pattern, 0, 1);
+
+ /* IA64 has the decrement conditional, i.e. done only when the loop does not
+ end. We match (set (x (if_then_else (ne x 0) (plus x -1) x))) here. */
+
+ lhs = XEXP (set, 0);
+ rhs = XEXP (set, 1);
+ if (GET_CODE (set) != IF_THEN_ELSE)
+ return set;
+
+ cond = XEXP (rhs, 0);
+ if (GET_CODE (cond) != NE
+ || !rtx_equal_p (XEXP (cond, 0), lhs)
+ || !rtx_equal_p (XEXP (cond, 1), const0_rtx))
+ return set;
+
+ rhs = XEXP (rhs, 1);
+
+ return gen_rtx_SET (GET_MODE (lhs), lhs, rhs);
+}
+
diff --git a/contrib/gcc/cfgloopmanip.c b/contrib/gcc/cfgloopmanip.c
new file mode 100644
index 000000000000..6a877d83f51e
--- /dev/null
+++ b/contrib/gcc/cfgloopmanip.c
@@ -0,0 +1,1244 @@
+/* Loop manipulation code for GNU compiler.
+ Copyright (C) 2002, 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "cfgloop.h"
+#include "cfglayout.h"
+#include "output.h"
+
+static struct loop * duplicate_loop (struct loops *, struct loop *,
+ struct loop *);
+static void duplicate_subloops (struct loops *, struct loop *, struct loop *);
+static void copy_loops_to (struct loops *, struct loop **, int,
+ struct loop *);
+static void loop_redirect_edge (edge, basic_block);
+static bool loop_delete_branch_edge (edge, int);
+static void remove_bbs (basic_block *, int);
+static bool rpe_enum_p (basic_block, void *);
+static int find_path (edge, basic_block **);
+static bool alp_enum_p (basic_block, void *);
+static void add_loop (struct loops *, struct loop *);
+static void fix_loop_placements (struct loops *, struct loop *);
+static bool fix_bb_placement (struct loops *, basic_block);
+static void fix_bb_placements (struct loops *, basic_block);
+static void place_new_loop (struct loops *, struct loop *);
+static void scale_loop_frequencies (struct loop *, int, int);
+static void scale_bbs_frequencies (basic_block *, int, int, int);
+static basic_block create_preheader (struct loop *, int);
+static void fix_irreducible_loops (basic_block);
+
+/* Splits basic block BB after INSN, returns created edge. Updates loops
+ and dominators. */
+edge
+split_loop_bb (basic_block bb, rtx insn)
+{
+ edge e;
+
+ /* Split the block. */
+ e = split_block (bb, insn);
+
+ /* Add dest to loop. */
+ add_bb_to_loop (e->dest, e->src->loop_father);
+
+ /* Fix dominators. */
+ add_to_dominance_info (CDI_DOMINATORS, e->dest);
+ redirect_immediate_dominators (CDI_DOMINATORS, e->src, e->dest);
+ set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src);
+
+ return e;
+}
+
+/* Checks whether basic block BB is dominated by DATA. */
+static bool
+rpe_enum_p (basic_block bb, void *data)
+{
+ return dominated_by_p (CDI_DOMINATORS, bb, data);
+}
+
+/* Remove basic blocks BBS from loop structure and dominance info,
+ and delete them afterwards. */
+static void
+remove_bbs (basic_block *bbs, int nbbs)
+{
+ int i;
+
+ for (i = 0; i < nbbs; i++)
+ {
+ remove_bb_from_loops (bbs[i]);
+ delete_from_dominance_info (CDI_DOMINATORS, bbs[i]);
+ delete_block (bbs[i]);
+ }
+}
+
+/* Find path -- i.e. the basic blocks dominated by edge E and put them
+ into array BBS, that will be allocated large enough to contain them.
+ E->dest must have exactly one predecessor for this to work (it is
+ easy to achieve and we do not put it here because we do not want to
+ alter anything by this function). The number of basic blocks in the
+ path is returned. */
+static int
+find_path (edge e, basic_block **bbs)
+{
+ if (e->dest->pred->pred_next)
+ abort ();
+
+ /* Find bbs in the path. */
+ *bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
+ return dfs_enumerate_from (e->dest, 0, rpe_enum_p, *bbs,
+ n_basic_blocks, e->dest);
+}
+
+/* Fix placement of basic block BB inside loop hierarchy stored in LOOPS --
+ Let L be a loop to that BB belongs. Then every successor of BB must either
+ 1) belong to some superloop of loop L, or
+ 2) be a header of loop K such that K->outer is superloop of L
+ Returns true if we had to move BB into other loop to enforce this condition,
+ false if the placement of BB was already correct (provided that placements
+ of its successors are correct). */
+static bool
+fix_bb_placement (struct loops *loops, basic_block bb)
+{
+ edge e;
+ struct loop *loop = loops->tree_root, *act;
+
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if (e->dest == EXIT_BLOCK_PTR)
+ continue;
+
+ act = e->dest->loop_father;
+ if (act->header == e->dest)
+ act = act->outer;
+
+ if (flow_loop_nested_p (loop, act))
+ loop = act;
+ }
+
+ if (loop == bb->loop_father)
+ return false;
+
+ remove_bb_from_loops (bb);
+ add_bb_to_loop (bb, loop);
+
+ return true;
+}
+
+/* Fix placements of basic blocks inside loop hierarchy stored in loops; i.e.
+ enforce condition condition stated in description of fix_bb_placement. We
+ start from basic block FROM that had some of its successors removed, so that
+ his placement no longer has to be correct, and iteratively fix placement of
+ its predecessors that may change if placement of FROM changed. Also fix
+ placement of subloops of FROM->loop_father, that might also be altered due
+ to this change; the condition for them is similar, except that instead of
+ successors we consider edges coming out of the loops. */
+static void
+fix_bb_placements (struct loops *loops, basic_block from)
+{
+ sbitmap in_queue;
+ basic_block *queue, *qtop, *qbeg, *qend;
+ struct loop *base_loop;
+ edge e;
+
+ /* We pass through blocks back-reachable from FROM, testing whether some
+ of their successors moved to outer loop. It may be necessary to
+ iterate several times, but it is finite, as we stop unless we move
+ the basic block up the loop structure. The whole story is a bit
+ more complicated due to presence of subloops, those are moved using
+ fix_loop_placement. */
+
+ base_loop = from->loop_father;
+ if (base_loop == loops->tree_root)
+ return;
+
+ in_queue = sbitmap_alloc (last_basic_block);
+ sbitmap_zero (in_queue);
+ SET_BIT (in_queue, from->index);
+ /* Prevent us from going out of the base_loop. */
+ SET_BIT (in_queue, base_loop->header->index);
+
+ queue = xmalloc ((base_loop->num_nodes + 1) * sizeof (basic_block));
+ qtop = queue + base_loop->num_nodes + 1;
+ qbeg = queue;
+ qend = queue + 1;
+ *qbeg = from;
+
+ while (qbeg != qend)
+ {
+ from = *qbeg;
+ qbeg++;
+ if (qbeg == qtop)
+ qbeg = queue;
+ RESET_BIT (in_queue, from->index);
+
+ if (from->loop_father->header == from)
+ {
+ /* Subloop header, maybe move the loop upward. */
+ if (!fix_loop_placement (from->loop_father))
+ continue;
+ }
+ else
+ {
+ /* Ordinary basic block. */
+ if (!fix_bb_placement (loops, from))
+ continue;
+ }
+
+ /* Something has changed, insert predecessors into queue. */
+ for (e = from->pred; e; e = e->pred_next)
+ {
+ basic_block pred = e->src;
+ struct loop *nca;
+
+ if (TEST_BIT (in_queue, pred->index))
+ continue;
+
+ /* If it is subloop, then it either was not moved, or
+ the path up the loop tree from base_loop do not contain
+ it. */
+ nca = find_common_loop (pred->loop_father, base_loop);
+ if (pred->loop_father != base_loop
+ && (nca == base_loop
+ || nca != pred->loop_father))
+ pred = pred->loop_father->header;
+ else if (!flow_loop_nested_p (from->loop_father, pred->loop_father))
+ {
+ /* No point in processing it. */
+ continue;
+ }
+
+ if (TEST_BIT (in_queue, pred->index))
+ continue;
+
+ /* Schedule the basic block. */
+ *qend = pred;
+ qend++;
+ if (qend == qtop)
+ qend = queue;
+ SET_BIT (in_queue, pred->index);
+ }
+ }
+ free (in_queue);
+ free (queue);
+}
+
+/* Basic block from has lost one or more of its predecessors, so it might
+ mo longer be part irreducible loop. Fix it and proceed recursively
+ for its successors if needed. */
+static void
+fix_irreducible_loops (basic_block from)
+{
+ basic_block bb;
+ basic_block *stack;
+ int stack_top;
+ sbitmap on_stack;
+ edge *edges, e;
+ unsigned n_edges, i;
+
+ if (!(from->flags & BB_IRREDUCIBLE_LOOP))
+ return;
+
+ on_stack = sbitmap_alloc (last_basic_block);
+ sbitmap_zero (on_stack);
+ SET_BIT (on_stack, from->index);
+ stack = xmalloc (from->loop_father->num_nodes * sizeof (basic_block));
+ stack[0] = from;
+ stack_top = 1;
+
+ while (stack_top)
+ {
+ bb = stack[--stack_top];
+ RESET_BIT (on_stack, bb->index);
+
+ for (e = bb->pred; e; e = e->pred_next)
+ if (e->flags & EDGE_IRREDUCIBLE_LOOP)
+ break;
+ if (e)
+ continue;
+
+ bb->flags &= ~BB_IRREDUCIBLE_LOOP;
+ if (bb->loop_father->header == bb)
+ edges = get_loop_exit_edges (bb->loop_father, &n_edges);
+ else
+ {
+ n_edges = 0;
+ for (e = bb->succ; e; e = e->succ_next)
+ n_edges++;
+ edges = xmalloc (n_edges * sizeof (edge));
+ n_edges = 0;
+ for (e = bb->succ; e; e = e->succ_next)
+ edges[n_edges++] = e;
+ }
+
+ for (i = 0; i < n_edges; i++)
+ {
+ e = edges[i];
+
+ if (e->flags & EDGE_IRREDUCIBLE_LOOP)
+ {
+ if (!flow_bb_inside_loop_p (from->loop_father, e->dest))
+ continue;
+
+ e->flags &= ~EDGE_IRREDUCIBLE_LOOP;
+ if (TEST_BIT (on_stack, e->dest->index))
+ continue;
+
+ SET_BIT (on_stack, e->dest->index);
+ stack[stack_top++] = e->dest;
+ }
+ }
+ free (edges);
+ }
+
+ free (on_stack);
+ free (stack);
+}
+
+/* Removes path beginning at edge E, i.e. remove basic blocks dominated by E
+ and update loop structure stored in LOOPS and dominators. Return true if
+ we were able to remove the path, false otherwise (and nothing is affected
+ then). */
+bool
+remove_path (struct loops *loops, edge e)
+{
+ edge ae;
+ basic_block *rem_bbs, *bord_bbs, *dom_bbs, from, bb;
+ int i, nrem, n_bord_bbs, n_dom_bbs;
+ sbitmap seen;
+
+ if (!loop_delete_branch_edge (e, 0))
+ return false;
+
+ /* We need to check whether basic blocks are dominated by the edge
+ e, but we only have basic block dominators. This is easy to
+ fix -- when e->dest has exactly one predecessor, this corresponds
+ to blocks dominated by e->dest, if not, split the edge. */
+ if (e->dest->pred->pred_next)
+ e = loop_split_edge_with (e, NULL_RTX)->pred;
+
+ /* It may happen that by removing path we remove one or more loops
+ we belong to. In this case first unloop the loops, then proceed
+ normally. We may assume that e->dest is not a header of any loop,
+ as it now has exactly one predecessor. */
+ while (e->src->loop_father->outer
+ && dominated_by_p (CDI_DOMINATORS,
+ e->src->loop_father->latch, e->dest))
+ unloop (loops, e->src->loop_father);
+
+ /* Identify the path. */
+ nrem = find_path (e, &rem_bbs);
+
+ n_bord_bbs = 0;
+ bord_bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
+ seen = sbitmap_alloc (last_basic_block);
+ sbitmap_zero (seen);
+
+ /* Find "border" hexes -- i.e. those with predecessor in removed path. */
+ for (i = 0; i < nrem; i++)
+ SET_BIT (seen, rem_bbs[i]->index);
+ for (i = 0; i < nrem; i++)
+ {
+ bb = rem_bbs[i];
+ for (ae = rem_bbs[i]->succ; ae; ae = ae->succ_next)
+ if (ae->dest != EXIT_BLOCK_PTR && !TEST_BIT (seen, ae->dest->index))
+ {
+ SET_BIT (seen, ae->dest->index);
+ bord_bbs[n_bord_bbs++] = ae->dest;
+ }
+ }
+
+ /* Remove the path. */
+ from = e->src;
+ if (!loop_delete_branch_edge (e, 1))
+ abort ();
+ dom_bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
+
+ /* Cancel loops contained in the path. */
+ for (i = 0; i < nrem; i++)
+ if (rem_bbs[i]->loop_father->header == rem_bbs[i])
+ cancel_loop_tree (loops, rem_bbs[i]->loop_father);
+
+ remove_bbs (rem_bbs, nrem);
+ free (rem_bbs);
+
+ /* Find blocks whose dominators may be affected. */
+ n_dom_bbs = 0;
+ sbitmap_zero (seen);
+ for (i = 0; i < n_bord_bbs; i++)
+ {
+ basic_block ldom;
+
+ bb = get_immediate_dominator (CDI_DOMINATORS, bord_bbs[i]);
+ if (TEST_BIT (seen, bb->index))
+ continue;
+ SET_BIT (seen, bb->index);
+
+ for (ldom = first_dom_son (CDI_DOMINATORS, bb);
+ ldom;
+ ldom = next_dom_son (CDI_DOMINATORS, ldom))
+ if (!dominated_by_p (CDI_DOMINATORS, from, ldom))
+ dom_bbs[n_dom_bbs++] = ldom;
+ }
+
+ free (seen);
+
+ /* Recount dominators. */
+ iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, n_dom_bbs);
+ free (dom_bbs);
+
+ /* These blocks have lost some predecessor(s), thus their irreducible
+ status could be changed. */
+ for (i = 0; i < n_bord_bbs; i++)
+ fix_irreducible_loops (bord_bbs[i]);
+ free (bord_bbs);
+
+ /* Fix placements of basic blocks inside loops and the placement of
+ loops in the loop tree. */
+ fix_bb_placements (loops, from);
+ fix_loop_placements (loops, from->loop_father);
+
+ return true;
+}
+
+/* Predicate for enumeration in add_loop. */
+static bool
+alp_enum_p (basic_block bb, void *alp_header)
+{
+ return bb != (basic_block) alp_header;
+}
+
+/* Given LOOP structure with filled header and latch, find the body of the
+ corresponding loop and add it to LOOPS tree. */
+static void
+add_loop (struct loops *loops, struct loop *loop)
+{
+ basic_block *bbs;
+ int i, n;
+
+ /* Add it to loop structure. */
+ place_new_loop (loops, loop);
+ loop->level = 1;
+
+ /* Find its nodes. */
+ bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
+ n = dfs_enumerate_from (loop->latch, 1, alp_enum_p,
+ bbs, n_basic_blocks, loop->header);
+
+ for (i = 0; i < n; i++)
+ add_bb_to_loop (bbs[i], loop);
+ add_bb_to_loop (loop->header, loop);
+
+ free (bbs);
+}
+
+/* Multiply all frequencies of basic blocks in array BBS of length NBBS
+ by NUM/DEN. */
+static void
+scale_bbs_frequencies (basic_block *bbs, int nbbs, int num, int den)
+{
+ int i;
+ edge e;
+
+ for (i = 0; i < nbbs; i++)
+ {
+ bbs[i]->frequency = (bbs[i]->frequency * num) / den;
+ bbs[i]->count = (bbs[i]->count * num) / den;
+ for (e = bbs[i]->succ; e; e = e->succ_next)
+ e->count = (e->count * num) /den;
+ }
+}
+
+/* Multiply all frequencies in LOOP by NUM/DEN. */
+static void
+scale_loop_frequencies (struct loop *loop, int num, int den)
+{
+ basic_block *bbs;
+
+ bbs = get_loop_body (loop);
+ scale_bbs_frequencies (bbs, loop->num_nodes, num, den);
+ free (bbs);
+}
+
+/* Make area between HEADER_EDGE and LATCH_EDGE a loop by connecting
+ latch to header and update loop tree stored in LOOPS and dominators
+ accordingly. Everything between them plus LATCH_EDGE destination must
+ be dominated by HEADER_EDGE destination, and back-reachable from
+ LATCH_EDGE source. HEADER_EDGE is redirected to basic block SWITCH_BB,
+ SWITCH_BB->succ to original destination of LATCH_EDGE and
+ SWITCH_BB->succ->succ_next to original destination of HEADER_EDGE.
+ Returns newly created loop. */
+struct loop *
+loopify (struct loops *loops, edge latch_edge, edge header_edge, basic_block switch_bb)
+{
+ basic_block succ_bb = latch_edge->dest;
+ basic_block pred_bb = header_edge->src;
+ basic_block *dom_bbs, *body;
+ unsigned n_dom_bbs, i;
+ sbitmap seen;
+ struct loop *loop = xcalloc (1, sizeof (struct loop));
+ struct loop *outer = succ_bb->loop_father->outer;
+ int freq, prob, tot_prob;
+ gcov_type cnt;
+ edge e;
+
+ loop->header = header_edge->dest;
+ loop->latch = latch_edge->src;
+
+ freq = EDGE_FREQUENCY (header_edge);
+ cnt = header_edge->count;
+ prob = switch_bb->succ->probability;
+ tot_prob = prob + switch_bb->succ->succ_next->probability;
+ if (tot_prob == 0)
+ tot_prob = 1;
+
+ /* Redirect edges. */
+ loop_redirect_edge (latch_edge, loop->header);
+ loop_redirect_edge (header_edge, switch_bb);
+ loop_redirect_edge (switch_bb->succ->succ_next, loop->header);
+ loop_redirect_edge (switch_bb->succ, succ_bb);
+
+ /* Update dominators. */
+ set_immediate_dominator (CDI_DOMINATORS, switch_bb, pred_bb);
+ set_immediate_dominator (CDI_DOMINATORS, loop->header, switch_bb);
+ set_immediate_dominator (CDI_DOMINATORS, succ_bb, switch_bb);
+
+ /* Compute new loop. */
+ add_loop (loops, loop);
+ flow_loop_tree_node_add (outer, loop);
+
+ /* Add switch_bb to appropriate loop. */
+ add_bb_to_loop (switch_bb, outer);
+
+ /* Fix frequencies. */
+ switch_bb->frequency = freq;
+ switch_bb->count = cnt;
+ for (e = switch_bb->succ; e; e = e->succ_next)
+ e->count = (switch_bb->count * e->probability) / REG_BR_PROB_BASE;
+ scale_loop_frequencies (loop, prob, tot_prob);
+ scale_loop_frequencies (succ_bb->loop_father, tot_prob - prob, tot_prob);
+
+ /* Update dominators of blocks outside of LOOP. */
+ dom_bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
+ n_dom_bbs = 0;
+ seen = sbitmap_alloc (last_basic_block);
+ sbitmap_zero (seen);
+ body = get_loop_body (loop);
+
+ for (i = 0; i < loop->num_nodes; i++)
+ SET_BIT (seen, body[i]->index);
+
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ basic_block ldom;
+
+ for (ldom = first_dom_son (CDI_DOMINATORS, body[i]);
+ ldom;
+ ldom = next_dom_son (CDI_DOMINATORS, ldom))
+ if (!TEST_BIT (seen, ldom->index))
+ {
+ SET_BIT (seen, ldom->index);
+ dom_bbs[n_dom_bbs++] = ldom;
+ }
+ }
+
+ iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, n_dom_bbs);
+
+ free (body);
+ free (seen);
+ free (dom_bbs);
+
+ return loop;
+}
+
+/* Remove the latch edge of a LOOP and update LOOPS tree to indicate that
+ the LOOP was removed. After this function, original loop latch will
+ have no successor, which caller is expected to fix somehow. */
+void
+unloop (struct loops *loops, struct loop *loop)
+{
+ basic_block *body;
+ struct loop *ploop;
+ unsigned i, n;
+ basic_block latch = loop->latch;
+ edge *edges;
+ unsigned n_edges;
+
+ /* This is relatively straightforward. The dominators are unchanged, as
+ loop header dominates loop latch, so the only thing we have to care of
+ is the placement of loops and basic blocks inside the loop tree. We
+ move them all to the loop->outer, and then let fix_bb_placements do
+ its work. */
+
+ body = get_loop_body (loop);
+ edges = get_loop_exit_edges (loop, &n_edges);
+ n = loop->num_nodes;
+ for (i = 0; i < n; i++)
+ if (body[i]->loop_father == loop)
+ {
+ remove_bb_from_loops (body[i]);
+ add_bb_to_loop (body[i], loop->outer);
+ }
+ free(body);
+
+ while (loop->inner)
+ {
+ ploop = loop->inner;
+ flow_loop_tree_node_remove (ploop);
+ flow_loop_tree_node_add (loop->outer, ploop);
+ }
+
+ /* Remove the loop and free its data. */
+ flow_loop_tree_node_remove (loop);
+ loops->parray[loop->num] = NULL;
+ flow_loop_free (loop);
+
+ remove_edge (latch->succ);
+ fix_bb_placements (loops, latch);
+
+ /* If the loop was inside an irreducible region, we would have to somehow
+ update the irreducible marks inside its body. While it is certainly
+ possible to do, it is a bit complicated and this situation should be
+ very rare, so we just remark all loops in this case. */
+ for (i = 0; i < n_edges; i++)
+ if (edges[i]->flags & EDGE_IRREDUCIBLE_LOOP)
+ break;
+ if (i != n_edges)
+ mark_irreducible_loops (loops);
+ free (edges);
+}
+
+/* Fix placement of LOOP inside loop tree, i.e. find the innermost superloop
+ FATHER of LOOP such that all of the edges coming out of LOOP belong to
+ FATHER, and set it as outer loop of LOOP. Return 1 if placement of
+ LOOP changed. */
+int
+fix_loop_placement (struct loop *loop)
+{
+ basic_block *body;
+ unsigned i;
+ edge e;
+ struct loop *father = loop->pred[0], *act;
+
+ body = get_loop_body (loop);
+ for (i = 0; i < loop->num_nodes; i++)
+ for (e = body[i]->succ; e; e = e->succ_next)
+ if (!flow_bb_inside_loop_p (loop, e->dest))
+ {
+ act = find_common_loop (loop, e->dest->loop_father);
+ if (flow_loop_nested_p (father, act))
+ father = act;
+ }
+ free (body);
+
+ if (father != loop->outer)
+ {
+ for (act = loop->outer; act != father; act = act->outer)
+ act->num_nodes -= loop->num_nodes;
+ flow_loop_tree_node_remove (loop);
+ flow_loop_tree_node_add (father, loop);
+ return 1;
+ }
+ return 0;
+}
+
+/* Fix placement of superloops of LOOP inside loop tree, i.e. ensure that
+ condition stated in description of fix_loop_placement holds for them.
+ It is used in case when we removed some edges coming out of LOOP, which
+ may cause the right placement of LOOP inside loop tree to change. */
+static void
+fix_loop_placements (struct loops *loops, struct loop *loop)
+{
+ struct loop *outer;
+
+ while (loop->outer)
+ {
+ outer = loop->outer;
+ if (!fix_loop_placement (loop))
+ break;
+
+ /* Changing the placement of a loop in the loop tree may alter the
+ validity of condition 2) of the description of fix_bb_placement
+ for its preheader, because the successor is the header and belongs
+ to the loop. So call fix_bb_placements to fix up the placement
+ of the preheader and (possibly) of its predecessors. */
+ fix_bb_placements (loops, loop_preheader_edge (loop)->src);
+ loop = outer;
+ }
+}
+
+/* Creates place for a new LOOP in LOOPS structure. */
+static void
+place_new_loop (struct loops *loops, struct loop *loop)
+{
+ loops->parray =
+ xrealloc (loops->parray, (loops->num + 1) * sizeof (struct loop *));
+ loops->parray[loops->num] = loop;
+
+ loop->num = loops->num++;
+}
+
+/* Copies copy of LOOP as subloop of TARGET loop, placing newly
+ created loop into LOOPS structure. */
+static struct loop *
+duplicate_loop (struct loops *loops, struct loop *loop, struct loop *target)
+{
+ struct loop *cloop;
+ cloop = xcalloc (1, sizeof (struct loop));
+ place_new_loop (loops, cloop);
+
+ /* Initialize copied loop. */
+ cloop->level = loop->level;
+
+ /* Set it as copy of loop. */
+ loop->copy = cloop;
+
+ /* Add it to target. */
+ flow_loop_tree_node_add (target, cloop);
+
+ return cloop;
+}
+
+/* Copies structure of subloops of LOOP into TARGET loop, placing
+ newly created loops into loop tree stored in LOOPS. */
+static void
+duplicate_subloops (struct loops *loops, struct loop *loop, struct loop *target)
+{
+ struct loop *aloop, *cloop;
+
+ for (aloop = loop->inner; aloop; aloop = aloop->next)
+ {
+ cloop = duplicate_loop (loops, aloop, target);
+ duplicate_subloops (loops, aloop, cloop);
+ }
+}
+
+/* Copies structure of subloops of N loops, stored in array COPIED_LOOPS,
+ into TARGET loop, placing newly created loops into loop tree LOOPS. */
+static void
+copy_loops_to (struct loops *loops, struct loop **copied_loops, int n, struct loop *target)
+{
+ struct loop *aloop;
+ int i;
+
+ for (i = 0; i < n; i++)
+ {
+ aloop = duplicate_loop (loops, copied_loops[i], target);
+ duplicate_subloops (loops, copied_loops[i], aloop);
+ }
+}
+
+/* Redirects edge E to basic block DEST. */
+static void
+loop_redirect_edge (edge e, basic_block dest)
+{
+ if (e->dest == dest)
+ return;
+
+ redirect_edge_and_branch_force (e, dest);
+}
+
+/* Deletes edge E from a branch if possible. Unless REALLY_DELETE is set,
+ just test whether it is possible to remove the edge. */
+static bool
+loop_delete_branch_edge (edge e, int really_delete)
+{
+ basic_block src = e->src;
+ int irr;
+ edge snd;
+
+ if (src->succ->succ_next)
+ {
+ basic_block newdest;
+
+ /* Cannot handle more than two exit edges. */
+ if (src->succ->succ_next->succ_next)
+ return false;
+ /* And it must be just a simple branch. */
+ if (!any_condjump_p (BB_END (src)))
+ return false;
+
+ snd = e == src->succ ? src->succ->succ_next : src->succ;
+ newdest = snd->dest;
+ if (newdest == EXIT_BLOCK_PTR)
+ return false;
+
+ /* Hopefully the above conditions should suffice. */
+ if (!really_delete)
+ return true;
+
+ /* Redirecting behaves wrongly wrto this flag. */
+ irr = snd->flags & EDGE_IRREDUCIBLE_LOOP;
+
+ if (!redirect_edge_and_branch (e, newdest))
+ return false;
+ src->succ->flags &= ~EDGE_IRREDUCIBLE_LOOP;
+ src->succ->flags |= irr;
+
+ return true;
+ }
+ else
+ {
+ /* Cannot happen -- we are using this only to remove an edge
+ from branch. */
+ abort ();
+ }
+
+ return false; /* To avoid warning, cannot get here. */
+}
+
+/* Check whether LOOP's body can be duplicated. */
+bool
+can_duplicate_loop_p (struct loop *loop)
+{
+ int ret;
+ basic_block *bbs = get_loop_body (loop);
+
+ ret = can_copy_bbs_p (bbs, loop->num_nodes);
+ free (bbs);
+
+ return ret;
+}
+
+#define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
+
+/* Duplicates body of LOOP to given edge E NDUPL times. Takes care of updating
+ LOOPS structure and dominators. E's destination must be LOOP header for
+ this to work, i.e. it must be entry or latch edge of this loop; these are
+ unique, as the loops must have preheaders for this function to work
+ correctly (in case E is latch, the function unrolls the loop, if E is entry
+ edge, it peels the loop). Store edges created by copying ORIG edge from
+ copies corresponding to set bits in WONT_EXIT bitmap (bit 0 corresponds to
+ original LOOP body, the other copies are numbered in order given by control
+ flow through them) into TO_REMOVE array. Returns false if duplication is
+ impossible. */
+int
+duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
+ unsigned int ndupl, sbitmap wont_exit,
+ edge orig, edge *to_remove,
+ unsigned int *n_to_remove, int flags)
+{
+ struct loop *target, *aloop;
+ struct loop **orig_loops;
+ unsigned n_orig_loops;
+ basic_block header = loop->header, latch = loop->latch;
+ basic_block *new_bbs, *bbs, *first_active;
+ basic_block new_bb, bb, first_active_latch = NULL;
+ edge ae, latch_edge;
+ edge spec_edges[2], new_spec_edges[2];
+#define SE_LATCH 0
+#define SE_ORIG 1
+ unsigned i, j, n;
+ int is_latch = (latch == e->src);
+ int scale_act = 0, *scale_step = NULL, scale_main = 0;
+ int p, freq_in, freq_le, freq_out_orig;
+ int prob_pass_thru, prob_pass_wont_exit, prob_pass_main;
+ int add_irreducible_flag;
+
+ if (e->dest != loop->header)
+ abort ();
+ if (ndupl <= 0)
+ abort ();
+
+ if (orig)
+ {
+ /* Orig must be edge out of the loop. */
+ if (!flow_bb_inside_loop_p (loop, orig->src))
+ abort ();
+ if (flow_bb_inside_loop_p (loop, orig->dest))
+ abort ();
+ }
+
+ bbs = get_loop_body (loop);
+
+ /* Check whether duplication is possible. */
+ if (!can_copy_bbs_p (bbs, loop->num_nodes))
+ {
+ free (bbs);
+ return false;
+ }
+ new_bbs = xmalloc (sizeof (basic_block) * loop->num_nodes);
+
+ /* In case we are doing loop peeling and the loop is in the middle of
+ irreducible region, the peeled copies will be inside it too. */
+ add_irreducible_flag = e->flags & EDGE_IRREDUCIBLE_LOOP;
+ if (is_latch && add_irreducible_flag)
+ abort ();
+
+ /* Find edge from latch. */
+ latch_edge = loop_latch_edge (loop);
+
+ if (flags & DLTHE_FLAG_UPDATE_FREQ)
+ {
+ /* Calculate coefficients by that we have to scale frequencies
+ of duplicated loop bodies. */
+ freq_in = header->frequency;
+ freq_le = EDGE_FREQUENCY (latch_edge);
+ if (freq_in == 0)
+ freq_in = 1;
+ if (freq_in < freq_le)
+ freq_in = freq_le;
+ freq_out_orig = orig ? EDGE_FREQUENCY (orig) : freq_in - freq_le;
+ if (freq_out_orig > freq_in - freq_le)
+ freq_out_orig = freq_in - freq_le;
+ prob_pass_thru = RDIV (REG_BR_PROB_BASE * freq_le, freq_in);
+ prob_pass_wont_exit =
+ RDIV (REG_BR_PROB_BASE * (freq_le + freq_out_orig), freq_in);
+
+ scale_step = xmalloc (ndupl * sizeof (int));
+
+ for (i = 1; i <= ndupl; i++)
+ scale_step[i - 1] = TEST_BIT (wont_exit, i)
+ ? prob_pass_wont_exit
+ : prob_pass_thru;
+
+ if (is_latch)
+ {
+ prob_pass_main = TEST_BIT (wont_exit, 0)
+ ? prob_pass_wont_exit
+ : prob_pass_thru;
+ p = prob_pass_main;
+ scale_main = REG_BR_PROB_BASE;
+ for (i = 0; i < ndupl; i++)
+ {
+ scale_main += p;
+ p = RDIV (p * scale_step[i], REG_BR_PROB_BASE);
+ }
+ scale_main = RDIV (REG_BR_PROB_BASE * REG_BR_PROB_BASE, scale_main);
+ scale_act = RDIV (scale_main * prob_pass_main, REG_BR_PROB_BASE);
+ }
+ else
+ {
+ scale_main = REG_BR_PROB_BASE;
+ for (i = 0; i < ndupl; i++)
+ scale_main = RDIV (scale_main * scale_step[i], REG_BR_PROB_BASE);
+ scale_act = REG_BR_PROB_BASE - prob_pass_thru;
+ }
+ for (i = 0; i < ndupl; i++)
+ if (scale_step[i] < 0 || scale_step[i] > REG_BR_PROB_BASE)
+ abort ();
+ if (scale_main < 0 || scale_main > REG_BR_PROB_BASE
+ || scale_act < 0 || scale_act > REG_BR_PROB_BASE)
+ abort ();
+ }
+
+ /* Loop the new bbs will belong to. */
+ target = e->src->loop_father;
+
+ /* Original loops. */
+ n_orig_loops = 0;
+ for (aloop = loop->inner; aloop; aloop = aloop->next)
+ n_orig_loops++;
+ orig_loops = xcalloc (n_orig_loops, sizeof (struct loop *));
+ for (aloop = loop->inner, i = 0; aloop; aloop = aloop->next, i++)
+ orig_loops[i] = aloop;
+
+ loop->copy = target;
+
+ n = loop->num_nodes;
+
+ first_active = xmalloc (n * sizeof (basic_block));
+ if (is_latch)
+ {
+ memcpy (first_active, bbs, n * sizeof (basic_block));
+ first_active_latch = latch;
+ }
+
+ /* Record exit edge in original loop body. */
+ if (orig && TEST_BIT (wont_exit, 0))
+ to_remove[(*n_to_remove)++] = orig;
+
+ spec_edges[SE_ORIG] = orig;
+ spec_edges[SE_LATCH] = latch_edge;
+
+ for (j = 0; j < ndupl; j++)
+ {
+ /* Copy loops. */
+ copy_loops_to (loops, orig_loops, n_orig_loops, target);
+
+ /* Copy bbs. */
+ copy_bbs (bbs, n, new_bbs, spec_edges, 2, new_spec_edges, loop);
+
+ /* Note whether the blocks and edges belong to an irreducible loop. */
+ if (add_irreducible_flag)
+ {
+ for (i = 0; i < n; i++)
+ new_bbs[i]->rbi->duplicated = 1;
+ for (i = 0; i < n; i++)
+ {
+ new_bb = new_bbs[i];
+ if (new_bb->loop_father == target)
+ new_bb->flags |= BB_IRREDUCIBLE_LOOP;
+
+ for (ae = new_bb->succ; ae; ae = ae->succ_next)
+ if (ae->dest->rbi->duplicated
+ && (ae->src->loop_father == target
+ || ae->dest->loop_father == target))
+ ae->flags |= EDGE_IRREDUCIBLE_LOOP;
+ }
+ for (i = 0; i < n; i++)
+ new_bbs[i]->rbi->duplicated = 0;
+ }
+
+ /* Redirect the special edges. */
+ if (is_latch)
+ {
+ redirect_edge_and_branch_force (latch_edge, new_bbs[0]);
+ redirect_edge_and_branch_force (new_spec_edges[SE_LATCH],
+ loop->header);
+ set_immediate_dominator (CDI_DOMINATORS, new_bbs[0], latch);
+ latch = loop->latch = new_bbs[1];
+ e = latch_edge = new_spec_edges[SE_LATCH];
+ }
+ else
+ {
+ redirect_edge_and_branch_force (new_spec_edges[SE_LATCH],
+ loop->header);
+ redirect_edge_and_branch_force (e, new_bbs[0]);
+ set_immediate_dominator (CDI_DOMINATORS, new_bbs[0], e->src);
+ e = new_spec_edges[SE_LATCH];
+ }
+
+ /* Record exit edge in this copy. */
+ if (orig && TEST_BIT (wont_exit, j + 1))
+ to_remove[(*n_to_remove)++] = new_spec_edges[SE_ORIG];
+
+ /* Record the first copy in the control flow order if it is not
+ the original loop (i.e. in case of peeling). */
+ if (!first_active_latch)
+ {
+ memcpy (first_active, new_bbs, n * sizeof (basic_block));
+ first_active_latch = new_bbs[1];
+ }
+
+ /* Set counts and frequencies. */
+ if (flags & DLTHE_FLAG_UPDATE_FREQ)
+ {
+ scale_bbs_frequencies (new_bbs, n, scale_act, REG_BR_PROB_BASE);
+ scale_act = RDIV (scale_act * scale_step[j], REG_BR_PROB_BASE);
+ }
+ }
+ free (new_bbs);
+ free (orig_loops);
+
+ /* Update the original loop. */
+ if (!is_latch)
+ set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src);
+ if (flags & DLTHE_FLAG_UPDATE_FREQ)
+ {
+ scale_bbs_frequencies (bbs, n, scale_main, REG_BR_PROB_BASE);
+ free (scale_step);
+ }
+
+ /* Update dominators of outer blocks if affected. */
+ for (i = 0; i < n; i++)
+ {
+ basic_block dominated, dom_bb, *dom_bbs;
+ int n_dom_bbs,j;
+
+ bb = bbs[i];
+ n_dom_bbs = get_dominated_by (CDI_DOMINATORS, bb, &dom_bbs);
+ for (j = 0; j < n_dom_bbs; j++)
+ {
+ dominated = dom_bbs[j];
+ if (flow_bb_inside_loop_p (loop, dominated))
+ continue;
+ dom_bb = nearest_common_dominator (
+ CDI_DOMINATORS, first_active[i], first_active_latch);
+ set_immediate_dominator (CDI_DOMINATORS, dominated, dom_bb);
+ }
+ free (dom_bbs);
+ }
+ free (first_active);
+
+ free (bbs);
+
+ return true;
+}
+
+/* Creates a pre-header for a LOOP. Returns newly created block. Unless
+ CP_SIMPLE_PREHEADERS is set in FLAGS, we only force LOOP to have single
+ entry; otherwise we also force preheader block to have only one successor.
+ The function also updates dominators stored in DOM. */
+static basic_block
+create_preheader (struct loop *loop, int flags)
+{
+ edge e, fallthru;
+ basic_block dummy;
+ basic_block jump, src = 0;
+ struct loop *cloop, *ploop;
+ int nentry = 0;
+ rtx insn;
+
+ cloop = loop->outer;
+
+ for (e = loop->header->pred; e; e = e->pred_next)
+ {
+ if (e->src == loop->latch)
+ continue;
+ nentry++;
+ }
+ if (!nentry)
+ abort ();
+ if (nentry == 1)
+ {
+ for (e = loop->header->pred; e->src == loop->latch; e = e->pred_next);
+ if (!(flags & CP_SIMPLE_PREHEADERS)
+ || !e->src->succ->succ_next)
+ return NULL;
+ }
+
+ insn = first_insn_after_basic_block_note (loop->header);
+ if (insn)
+ insn = PREV_INSN (insn);
+ else
+ insn = get_last_insn ();
+ if (insn == BB_END (loop->header))
+ {
+ /* Split_block would not split block after its end. */
+ emit_note_after (NOTE_INSN_DELETED, insn);
+ }
+ fallthru = split_block (loop->header, insn);
+ dummy = fallthru->src;
+ loop->header = fallthru->dest;
+
+ /* The header could be a latch of some superloop(s); due to design of
+ split_block, it would now move to fallthru->dest. */
+ for (ploop = loop; ploop; ploop = ploop->outer)
+ if (ploop->latch == dummy)
+ ploop->latch = fallthru->dest;
+
+ add_to_dominance_info (CDI_DOMINATORS, fallthru->dest);
+
+ /* Redirect edges. */
+ for (e = dummy->pred; e; e = e->pred_next)
+ {
+ src = e->src;
+ if (src == loop->latch)
+ break;
+ }
+ if (!e)
+ abort ();
+
+ dummy->frequency -= EDGE_FREQUENCY (e);
+ dummy->count -= e->count;
+ fallthru->count -= e->count;
+ jump = redirect_edge_and_branch_force (e, loop->header);
+ if (jump)
+ {
+ add_to_dominance_info (CDI_DOMINATORS, jump);
+ set_immediate_dominator (CDI_DOMINATORS, jump, src);
+ add_bb_to_loop (jump, loop);
+ loop->latch = jump;
+ }
+
+ /* Update structures. */
+ redirect_immediate_dominators (CDI_DOMINATORS, dummy, loop->header);
+ set_immediate_dominator (CDI_DOMINATORS, loop->header, dummy);
+ loop->header->loop_father = loop;
+ add_bb_to_loop (dummy, cloop);
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Created preheader block for loop %i\n",
+ loop->num);
+
+ return dummy;
+}
+
+/* Create preheaders for each loop from loop tree stored in LOOPS; for meaning
+ of FLAGS see create_preheader. */
+void
+create_preheaders (struct loops *loops, int flags)
+{
+ unsigned i;
+ for (i = 1; i < loops->num; i++)
+ create_preheader (loops->parray[i], flags);
+ loops->state |= LOOPS_HAVE_PREHEADERS;
+}
+
+/* Forces all loop latches of loops from loop tree LOOPS to have only single
+ successor. */
+void
+force_single_succ_latches (struct loops *loops)
+{
+ unsigned i;
+ struct loop *loop;
+ edge e;
+
+ for (i = 1; i < loops->num; i++)
+ {
+ loop = loops->parray[i];
+ if (loop->latch != loop->header
+ && !loop->latch->succ->succ_next)
+ continue;
+
+ for (e = loop->header->pred; e->src != loop->latch; e = e->pred_next)
+ continue;
+
+ loop_split_edge_with (e, NULL_RTX);
+ }
+ loops->state |= LOOPS_HAVE_SIMPLE_LATCHES;
+}
+
+/* A quite stupid function to put INSNS on edge E. They are supposed to form
+ just one basic block. Jumps in INSNS are not handled, so cfg do not have to
+ be ok after this function. The created block is placed on correct place
+ in LOOPS structure and its dominator is set. */
+basic_block
+loop_split_edge_with (edge e, rtx insns)
+{
+ basic_block src, dest, new_bb;
+ struct loop *loop_c;
+ edge new_e;
+
+ src = e->src;
+ dest = e->dest;
+
+ loop_c = find_common_loop (src->loop_father, dest->loop_father);
+
+ /* Create basic block for it. */
+
+ new_bb = split_edge (e);
+ add_to_dominance_info (CDI_DOMINATORS, new_bb);
+ add_bb_to_loop (new_bb, loop_c);
+ new_bb->flags = insns ? BB_SUPERBLOCK : 0;
+
+ new_e = new_bb->succ;
+ if (e->flags & EDGE_IRREDUCIBLE_LOOP)
+ {
+ new_bb->flags |= BB_IRREDUCIBLE_LOOP;
+ new_e->flags |= EDGE_IRREDUCIBLE_LOOP;
+ }
+
+ if (insns)
+ emit_insn_after (insns, BB_END (new_bb));
+
+ set_immediate_dominator (CDI_DOMINATORS, new_bb, src);
+ set_immediate_dominator (CDI_DOMINATORS, dest,
+ recount_dominator (CDI_DOMINATORS, dest));
+
+ if (dest->loop_father->latch == src)
+ dest->loop_father->latch = new_bb;
+
+ return new_bb;
+}
diff --git a/contrib/gcc/cfgrtl.c b/contrib/gcc/cfgrtl.c
index e01960668480..bad9e77b5d5a 100644
--- a/contrib/gcc/cfgrtl.c
+++ b/contrib/gcc/cfgrtl.c
@@ -1,6 +1,6 @@
/* Control flow graph manipulation code for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -23,27 +23,24 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
that are aware of the RTL intermediate language.
Available functionality:
+ - Basic CFG/RTL manipulation API documented in cfghooks.h
- CFG-aware instruction chain manipulation
delete_insn, delete_insn_chain
- - Basic block manipulation
- create_basic_block, flow_delete_block, split_block,
- merge_blocks_nomove
+ - Edge splitting and committing to edges
+ insert_insn_on_edge, commit_edge_insertions
+ - CFG updating after insn simplification
+ purge_dead_edges, purge_all_dead_edges
+
+ Functions not supposed for generic use:
- Infrastructure to determine quickly basic block for insn
compute_bb_for_insn, update_bb_for_insn, set_block_for_insn,
- Edge redirection with updating and optimizing of insn chain
- block_label, redirect_edge_and_branch,
- redirect_edge_and_branch_force, tidy_fallthru_edge, force_nonfallthru
- - Edge splitting and commiting to edges
- split_edge, insert_insn_on_edge, commit_edge_insertions
- - Dumping and debugging
- print_rtl_with_bb, dump_bb, debug_bb, debug_bb_n
- - Consistency checking
- verify_flow_info
- - CFG updating after constant propagation
- purge_dead_edges, purge_all_dead_edges */
+ block_label, tidy_fallthru_edge, force_nonfallthru */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "hard-reg-set.h"
@@ -57,6 +54,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm_p.h"
#include "obstack.h"
#include "insn-config.h"
+#include "cfglayout.h"
+#include "expr.h"
/* Stubs in case we don't have a return insn. */
#ifndef HAVE_return
@@ -70,20 +69,31 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
rtx label_value_list;
rtx tail_recursion_label_list;
-static int can_delete_note_p PARAMS ((rtx));
-static int can_delete_label_p PARAMS ((rtx));
-static void commit_one_edge_insertion PARAMS ((edge, int));
-static bool try_redirect_by_replacing_jump PARAMS ((edge, basic_block));
-static rtx last_loop_beg_note PARAMS ((rtx));
-static bool back_edge_of_syntactic_loop_p PARAMS ((basic_block, basic_block));
-static basic_block force_nonfallthru_and_redirect PARAMS ((edge, basic_block));
+static int can_delete_note_p (rtx);
+static int can_delete_label_p (rtx);
+static void commit_one_edge_insertion (edge, int);
+static rtx last_loop_beg_note (rtx);
+static bool back_edge_of_syntactic_loop_p (basic_block, basic_block);
+basic_block force_nonfallthru_and_redirect (edge, basic_block);
+static basic_block rtl_split_edge (edge);
+static int rtl_verify_flow_info (void);
+static edge cfg_layout_split_block (basic_block, void *);
+static bool cfg_layout_redirect_edge_and_branch (edge, basic_block);
+static basic_block cfg_layout_redirect_edge_and_branch_force (edge, basic_block);
+static void cfg_layout_delete_block (basic_block);
+static void rtl_delete_block (basic_block);
+static basic_block rtl_redirect_edge_and_branch_force (edge, basic_block);
+static bool rtl_redirect_edge_and_branch (edge, basic_block);
+static edge rtl_split_block (basic_block, void *);
+static void rtl_dump_bb (basic_block, FILE *);
+static int rtl_verify_flow_info_1 (void);
+static void mark_killed_regs (rtx, rtx, void *);
/* Return true if NOTE is not one of the ones that must be kept paired,
so that we may simply delete it. */
static int
-can_delete_note_p (note)
- rtx note;
+can_delete_note_p (rtx note)
{
return (NOTE_LINE_NUMBER (note) == NOTE_INSN_DELETED
|| NOTE_LINE_NUMBER (note) == NOTE_INSN_BASIC_BLOCK
@@ -93,8 +103,7 @@ can_delete_note_p (note)
/* True if a given label can be deleted. */
static int
-can_delete_label_p (label)
- rtx label;
+can_delete_label_p (rtx label)
{
return (!LABEL_PRESERVE_P (label)
/* User declared labels must be preserved. */
@@ -106,8 +115,7 @@ can_delete_label_p (label)
/* Delete INSN by patching it out. Return the next insn. */
rtx
-delete_insn (insn)
- rtx insn;
+delete_insn (rtx insn)
{
rtx next = NEXT_INSN (insn);
rtx note;
@@ -148,9 +156,15 @@ delete_insn (insn)
LABEL_NUSES (JUMP_LABEL (insn))--;
/* Also if deleting an insn that references a label. */
- else if ((note = find_reg_note (insn, REG_LABEL, NULL_RTX)) != NULL_RTX
- && GET_CODE (XEXP (note, 0)) == CODE_LABEL)
- LABEL_NUSES (XEXP (note, 0))--;
+ else
+ {
+ while ((note = find_reg_note (insn, REG_LABEL, NULL_RTX)) != NULL_RTX
+ && GET_CODE (XEXP (note, 0)) == CODE_LABEL)
+ {
+ LABEL_NUSES (XEXP (note, 0))--;
+ remove_note (insn, note);
+ }
+ }
if (GET_CODE (insn) == JUMP_INSN
&& (GET_CODE (PATTERN (insn)) == ADDR_VEC
@@ -178,15 +192,14 @@ delete_insn (insn)
/* Like delete_insn but also purge dead edges from BB. */
rtx
-delete_insn_and_edges (insn)
- rtx insn;
+delete_insn_and_edges (rtx insn)
{
rtx x;
bool purge = false;
if (INSN_P (insn)
&& BLOCK_FOR_INSN (insn)
- && BLOCK_FOR_INSN (insn)->end == insn)
+ && BB_END (BLOCK_FOR_INSN (insn)) == insn)
purge = true;
x = delete_insn (insn);
if (purge)
@@ -198,8 +211,7 @@ delete_insn_and_edges (insn)
that must be paired. */
void
-delete_insn_chain (start, finish)
- rtx start, finish;
+delete_insn_chain (rtx start, rtx finish)
{
rtx next;
@@ -222,14 +234,13 @@ delete_insn_chain (start, finish)
/* Like delete_insn but also purge dead edges from BB. */
void
-delete_insn_chain_and_edges (first, last)
- rtx first, last;
+delete_insn_chain_and_edges (rtx first, rtx last)
{
bool purge = false;
if (INSN_P (last)
&& BLOCK_FOR_INSN (last)
- && BLOCK_FOR_INSN (last)->end == last)
+ && BB_END (BLOCK_FOR_INSN (last)) == last)
purge = true;
delete_insn_chain (first, last);
if (purge)
@@ -245,9 +256,7 @@ delete_insn_chain_and_edges (first, last)
AFTER is the basic block we should be put after. */
basic_block
-create_basic_block_structure (head, end, bb_note, after)
- rtx head, end, bb_note;
- basic_block after;
+create_basic_block_structure (rtx head, rtx end, rtx bb_note, basic_block after)
{
basic_block bb;
@@ -301,8 +310,8 @@ create_basic_block_structure (head, end, bb_note, after)
if (NEXT_INSN (end) == bb_note)
end = bb_note;
- bb->head = head;
- bb->end = end;
+ BB_HEAD (bb) = head;
+ BB_END (bb) = end;
bb->index = last_basic_block++;
bb->flags = BB_NEW;
link_block (bb, after);
@@ -321,11 +330,10 @@ create_basic_block_structure (head, end, bb_note, after)
create new empty basic block before HEAD. Both END and HEAD can be NULL to
create basic block at the end of INSN chain. */
-basic_block
-create_basic_block (head, end, after)
- rtx head, end;
- basic_block after;
+static basic_block
+rtl_create_basic_block (void *headp, void *endp, basic_block after)
{
+ rtx head = headp, end = endp;
basic_block bb;
/* Place the new block just after the end. */
@@ -337,6 +345,15 @@ create_basic_block (head, end, after)
bb->aux = NULL;
return bb;
}
+
+static basic_block
+cfg_layout_create_basic_block (void *head, void *end, basic_block after)
+{
+ basic_block newbb = rtl_create_basic_block (head, end, after);
+
+ cfg_layout_initialize_rbi (newbb);
+ return newbb;
+}
/* Delete the insns in a (non-live) block. We physically delete every
non-deleted-note insn, and update the flow graph appropriately.
@@ -346,11 +363,9 @@ create_basic_block (head, end, after)
/* ??? Preserving all such notes strikes me as wrong. It would be nice
to post-process the stream to remove empty blocks, loops, ranges, etc. */
-int
-flow_delete_block_noexpunge (b)
- basic_block b;
+static void
+rtl_delete_block (basic_block b)
{
- int deleted_handler = 0;
rtx insn, end, tmp;
/* If the head of this block is a CODE_LABEL, then it might be the
@@ -363,7 +378,7 @@ flow_delete_block_noexpunge (b)
/* Get rid of all NOTE_INSN_PREDICTIONs and NOTE_INSN_LOOP_CONTs
hanging before the block. */
- for (insn = PREV_INSN (b->head); insn; insn = PREV_INSN (insn))
+ for (insn = PREV_INSN (BB_HEAD (b)); insn; insn = PREV_INSN (insn))
{
if (GET_CODE (insn) != NOTE)
break;
@@ -372,21 +387,16 @@ flow_delete_block_noexpunge (b)
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
}
- insn = b->head;
+ insn = BB_HEAD (b);
- never_reached_warning (insn, b->end);
+ never_reached_warning (insn, BB_END (b));
if (GET_CODE (insn) == CODE_LABEL)
maybe_remove_eh_handler (insn);
/* Include any jump table following the basic block. */
- end = b->end;
- if (GET_CODE (end) == JUMP_INSN
- && (tmp = JUMP_LABEL (end)) != NULL_RTX
- && (tmp = NEXT_INSN (tmp)) != NULL_RTX
- && GET_CODE (tmp) == JUMP_INSN
- && (GET_CODE (PATTERN (tmp)) == ADDR_VEC
- || GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
+ end = BB_END (b);
+ if (tablejump_p (end, NULL, &tmp))
end = tmp;
/* Include any barrier that may follow the basic block. */
@@ -395,7 +405,7 @@ flow_delete_block_noexpunge (b)
end = tmp;
/* Selectively delete the entire chain. */
- b->head = NULL;
+ BB_HEAD (b) = NULL;
delete_insn_chain (insn, end);
/* Remove the edges into and out of this block. Note that there may
@@ -408,34 +418,23 @@ flow_delete_block_noexpunge (b)
b->pred = NULL;
b->succ = NULL;
- return deleted_handler;
-}
-
-int
-flow_delete_block (b)
- basic_block b;
-{
- int deleted_handler = flow_delete_block_noexpunge (b);
-
/* Remove the basic block from the array. */
expunge_block (b);
-
- return deleted_handler;
}
/* Records the basic block struct in BLOCK_FOR_INSN for every insn. */
void
-compute_bb_for_insn ()
+compute_bb_for_insn (void)
{
basic_block bb;
FOR_EACH_BB (bb)
{
- rtx end = bb->end;
+ rtx end = BB_END (bb);
rtx insn;
- for (insn = bb->head; ; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
{
BLOCK_FOR_INSN (insn) = bb;
if (insn == end)
@@ -447,7 +446,7 @@ compute_bb_for_insn ()
/* Release the basic_block_for_insn array. */
void
-free_bb_for_insn ()
+free_bb_for_insn (void)
{
rtx insn;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
@@ -458,15 +457,15 @@ free_bb_for_insn ()
/* Update insns block within BB. */
void
-update_bb_for_insn (bb)
- basic_block bb;
+update_bb_for_insn (basic_block bb)
{
rtx insn;
- for (insn = bb->head; ; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
{
- set_block_for_insn (insn, bb);
- if (insn == bb->end)
+ if (GET_CODE (insn) != BARRIER)
+ set_block_for_insn (insn, bb);
+ if (insn == BB_END (bb))
break;
}
}
@@ -476,25 +475,24 @@ update_bb_for_insn (bb)
this function renumbers all the basic blocks so that the new
one has a number one greater than the block split. */
-edge
-split_block (bb, insn)
- basic_block bb;
- rtx insn;
+static edge
+rtl_split_block (basic_block bb, void *insnp)
{
basic_block new_bb;
edge new_edge;
edge e;
+ rtx insn = insnp;
/* There is no point splitting the block after its end. */
- if (bb->end == insn)
+ if (BB_END (bb) == insn)
return 0;
/* Create the new basic block. */
- new_bb = create_basic_block (NEXT_INSN (insn), bb->end, bb);
+ new_bb = create_basic_block (NEXT_INSN (insn), BB_END (bb), bb);
new_bb->count = bb->count;
new_bb->frequency = bb->frequency;
new_bb->loop_depth = bb->loop_depth;
- bb->end = insn;
+ BB_END (bb) = insn;
/* Redirect the outgoing edges. */
new_bb->succ = bb->succ;
@@ -533,17 +531,42 @@ split_block (bb, insn)
return new_edge;
}
+/* Assume that the code of basic block B has been merged into A.
+ Do corresponding CFG updates: redirect edges accordingly etc. */
+static void
+update_cfg_after_block_merging (basic_block a, basic_block b)
+{
+ edge e;
+
+ /* Normally there should only be one successor of A and that is B, but
+ partway though the merge of blocks for conditional_execution we'll
+ be merging a TEST block with THEN and ELSE successors. Free the
+ whole lot of them and hope the caller knows what they're doing. */
+ while (a->succ)
+ remove_edge (a->succ);
+
+ /* Adjust the edges out of B for the new owner. */
+ for (e = b->succ; e; e = e->succ_next)
+ e->src = a;
+ a->succ = b->succ;
+ a->flags |= b->flags;
+
+ /* B hasn't quite yet ceased to exist. Attempt to prevent mishap. */
+ b->pred = b->succ = NULL;
+ a->global_live_at_end = b->global_live_at_end;
+
+ expunge_block (b);
+}
+
/* Blocks A and B are to be merged into a single block A. The insns
- are already contiguous, hence `nomove'. */
+ are already contiguous. */
-void
-merge_blocks_nomove (a, b)
- basic_block a, b;
+static void
+rtl_merge_blocks (basic_block a, basic_block b)
{
- rtx b_head = b->head, b_end = b->end, a_end = a->end;
+ rtx b_head = BB_HEAD (b), b_end = BB_END (b), a_end = BB_END (a);
rtx del_first = NULL_RTX, del_last = NULL_RTX;
int b_empty = 0;
- edge e;
/* If there was a CODE_LABEL beginning B, delete it. */
if (GET_CODE (b_head) == CODE_LABEL)
@@ -578,7 +601,7 @@ merge_blocks_nomove (a, b)
for (prev = PREV_INSN (a_end); ; prev = PREV_INSN (prev))
if (GET_CODE (prev) != NOTE
|| NOTE_LINE_NUMBER (prev) == NOTE_INSN_BASIC_BLOCK
- || prev == a->head)
+ || prev == BB_HEAD (a))
break;
del_first = a_end;
@@ -592,7 +615,7 @@ merge_blocks_nomove (a, b)
prev = prev_nonnote_insn (prev);
if (!prev)
- prev = a->head;
+ prev = BB_HEAD (a);
del_first = tmp;
}
#endif
@@ -602,24 +625,7 @@ merge_blocks_nomove (a, b)
else if (GET_CODE (NEXT_INSN (a_end)) == BARRIER)
del_first = NEXT_INSN (a_end);
- /* Normally there should only be one successor of A and that is B, but
- partway though the merge of blocks for conditional_execution we'll
- be merging a TEST block with THEN and ELSE successors. Free the
- whole lot of them and hope the caller knows what they're doing. */
- while (a->succ)
- remove_edge (a->succ);
-
- /* Adjust the edges out of B for the new owner. */
- for (e = b->succ; e; e = e->succ_next)
- e->src = a;
- a->succ = b->succ;
- a->flags |= b->flags;
-
- /* B hasn't quite yet ceased to exist. Attempt to prevent mishap. */
- b->pred = b->succ = NULL;
- a->global_live_at_end = b->global_live_at_end;
-
- expunge_block (b);
+ update_cfg_after_block_merging (a, b);
/* Delete everything marked above as well as crap that might be
hanging out between the two blocks. */
@@ -638,25 +644,42 @@ merge_blocks_nomove (a, b)
a_end = b_end;
}
- a->end = a_end;
+ BB_END (a) = a_end;
+}
+
+/* Return true when block A and B can be merged. */
+static bool
+rtl_can_merge_blocks (basic_block a,basic_block b)
+{
+ /* There must be exactly one edge in between the blocks. */
+ return (a->succ && !a->succ->succ_next && a->succ->dest == b
+ && !b->pred->pred_next && a != b
+ /* Must be simple edge. */
+ && !(a->succ->flags & EDGE_COMPLEX)
+ && a->next_bb == b
+ && a != ENTRY_BLOCK_PTR && b != EXIT_BLOCK_PTR
+ /* If the jump insn has side effects,
+ we can't kill the edge. */
+ && (GET_CODE (BB_END (a)) != JUMP_INSN
+ || (reload_completed
+ ? simplejump_p (BB_END (a)) : onlyjump_p (BB_END (a)))));
}
/* Return the label in the head of basic block BLOCK. Create one if it doesn't
exist. */
rtx
-block_label (block)
- basic_block block;
+block_label (basic_block block)
{
if (block == EXIT_BLOCK_PTR)
return NULL_RTX;
- if (GET_CODE (block->head) != CODE_LABEL)
+ if (GET_CODE (BB_HEAD (block)) != CODE_LABEL)
{
- block->head = emit_label_before (gen_label_rtx (), block->head);
+ BB_HEAD (block) = emit_label_before (gen_label_rtx (), BB_HEAD (block));
}
- return block->head;
+ return BB_HEAD (block);
}
/* Attempt to perform edge redirection by replacing possibly complex jump
@@ -664,15 +687,13 @@ block_label (block)
apply only if all edges now point to the same block. The parameters and
return values are equivalent to redirect_edge_and_branch. */
-static bool
-try_redirect_by_replacing_jump (e, target)
- edge e;
- basic_block target;
+bool
+try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout)
{
basic_block src = e->src;
- rtx insn = src->end, kill_from;
+ rtx insn = BB_END (src), kill_from;
edge tmp;
- rtx set, table;
+ rtx set;
int fallthru = 0;
/* Verify that all targets will be TARGET. */
@@ -682,11 +703,7 @@ try_redirect_by_replacing_jump (e, target)
if (tmp || !onlyjump_p (insn))
return false;
- if (flow2_completed && JUMP_LABEL (insn)
- && (table = NEXT_INSN (JUMP_LABEL (insn))) != NULL_RTX
- && GET_CODE (table) == JUMP_INSN
- && (GET_CODE (PATTERN (table)) == ADDR_VEC
- || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
+ if ((!optimize || reload_completed) && tablejump_p (insn, NULL, NULL))
return false;
/* Avoid removing branch with side effects. */
@@ -703,14 +720,38 @@ try_redirect_by_replacing_jump (e, target)
#endif
/* See if we can create the fallthru edge. */
- if (can_fallthru (src, target))
+ if (in_cfglayout || can_fallthru (src, target))
{
if (rtl_dump_file)
fprintf (rtl_dump_file, "Removing jump %i.\n", INSN_UID (insn));
fallthru = 1;
/* Selectively unlink whole insn chain. */
- delete_insn_chain (kill_from, PREV_INSN (target->head));
+ if (in_cfglayout)
+ {
+ rtx insn = src->rbi->footer;
+
+ delete_insn_chain (kill_from, BB_END (src));
+
+ /* Remove barriers but keep jumptables. */
+ while (insn)
+ {
+ if (GET_CODE (insn) == BARRIER)
+ {
+ if (PREV_INSN (insn))
+ NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
+ else
+ src->rbi->footer = NEXT_INSN (insn);
+ if (NEXT_INSN (insn))
+ PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
+ }
+ if (GET_CODE (insn) == CODE_LABEL)
+ break;
+ insn = NEXT_INSN (insn);
+ }
+ }
+ else
+ delete_insn_chain (kill_from, PREV_INSN (BB_HEAD (target)));
}
/* If this already is simplejump, redirect it. */
@@ -737,14 +778,14 @@ try_redirect_by_replacing_jump (e, target)
else
{
rtx target_label = block_label (target);
- rtx barrier, tmp;
+ rtx barrier, label, table;
- emit_jump_insn_after (gen_jump (target_label), insn);
- JUMP_LABEL (src->end) = target_label;
+ emit_jump_insn_after_noloc (gen_jump (target_label), insn);
+ JUMP_LABEL (BB_END (src)) = target_label;
LABEL_NUSES (target_label)++;
if (rtl_dump_file)
fprintf (rtl_dump_file, "Replacing insn %i by jump %i\n",
- INSN_UID (insn), INSN_UID (src->end));
+ INSN_UID (insn), INSN_UID (BB_END (src)));
delete_insn_chain (kill_from, insn);
@@ -752,18 +793,36 @@ try_redirect_by_replacing_jump (e, target)
/* Recognize a tablejump that we are converting to a
simple jump and remove its associated CODE_LABEL
and ADDR_VEC or ADDR_DIFF_VEC. */
- if ((tmp = JUMP_LABEL (insn)) != NULL_RTX
- && (tmp = NEXT_INSN (tmp)) != NULL_RTX
- && GET_CODE (tmp) == JUMP_INSN
- && (GET_CODE (PATTERN (tmp)) == ADDR_VEC
- || GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
- {
- delete_insn_chain (JUMP_LABEL (insn), tmp);
- }
+ if (tablejump_p (insn, &label, &table))
+ delete_insn_chain (label, table);
- barrier = next_nonnote_insn (src->end);
+ barrier = next_nonnote_insn (BB_END (src));
if (!barrier || GET_CODE (barrier) != BARRIER)
- emit_barrier_after (src->end);
+ emit_barrier_after (BB_END (src));
+ else
+ {
+ if (barrier != NEXT_INSN (BB_END (src)))
+ {
+ /* Move the jump before barrier so that the notes
+ which originally were or were created before jump table are
+ inside the basic block. */
+ rtx new_insn = BB_END (src);
+ rtx tmp;
+
+ for (tmp = NEXT_INSN (BB_END (src)); tmp != barrier;
+ tmp = NEXT_INSN (tmp))
+ set_block_for_insn (tmp, src);
+
+ NEXT_INSN (PREV_INSN (new_insn)) = NEXT_INSN (new_insn);
+ PREV_INSN (NEXT_INSN (new_insn)) = PREV_INSN (new_insn);
+
+ NEXT_INSN (new_insn) = barrier;
+ NEXT_INSN (PREV_INSN (barrier)) = new_insn;
+
+ PREV_INSN (new_insn) = PREV_INSN (barrier);
+ PREV_INSN (barrier) = new_insn;
+ }
+ }
}
/* Keep only one edge out and set proper flags. */
@@ -780,9 +839,9 @@ try_redirect_by_replacing_jump (e, target)
/* We don't want a block to end on a line-number note since that has
the potential of changing the code between -g and not -g. */
- while (GET_CODE (e->src->end) == NOTE
- && NOTE_LINE_NUMBER (e->src->end) >= 0)
- delete_insn (e->src->end);
+ while (GET_CODE (BB_END (e->src)) == NOTE
+ && NOTE_LINE_NUMBER (BB_END (e->src)) >= 0)
+ delete_insn (BB_END (e->src));
if (e->dest != target)
redirect_edge_succ (e, target);
@@ -799,8 +858,7 @@ try_redirect_by_replacing_jump (e, target)
test. */
static rtx
-last_loop_beg_note (insn)
- rtx insn;
+last_loop_beg_note (rtx insn)
{
rtx last = insn;
@@ -813,37 +871,14 @@ last_loop_beg_note (insn)
return last;
}
-/* Attempt to change code to redirect edge E to TARGET. Don't do that on
- expense of adding new instructions or reordering basic blocks.
-
- Function can be also called with edge destination equivalent to the TARGET.
- Then it should try the simplifications and do nothing if none is possible.
-
- Return true if transformation succeeded. We still return false in case E
- already destinated TARGET and we didn't managed to simplify instruction
- stream. */
-
-bool
-redirect_edge_and_branch (e, target)
- edge e;
- basic_block target;
+/* Redirect edge representing branch of (un)conditional jump or tablejump. */
+static bool
+redirect_branch_edge (edge e, basic_block target)
{
rtx tmp;
- rtx old_label = e->dest->head;
+ rtx old_label = BB_HEAD (e->dest);
basic_block src = e->src;
- rtx insn = src->end;
-
- if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
- return false;
-
- if (try_redirect_by_replacing_jump (e, target))
- return true;
-
- /* Do this fast path late, as we want above code to simplify for cases
- where called on single edge leaving basic block containing nontrivial
- jump insn. */
- else if (e->dest == target)
- return false;
+ rtx insn = BB_END (src);
/* We can only redirect non-fallthru edges of jump insn. */
if (e->flags & EDGE_FALLTHRU)
@@ -852,11 +887,7 @@ redirect_edge_and_branch (e, target)
return false;
/* Recognize a tablejump and adjust all matching cases. */
- if ((tmp = JUMP_LABEL (insn)) != NULL_RTX
- && (tmp = NEXT_INSN (tmp)) != NULL_RTX
- && GET_CODE (tmp) == JUMP_INSN
- && (GET_CODE (PATTERN (tmp)) == ADDR_VEC
- || GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
+ if (tablejump_p (insn, NULL, &tmp))
{
rtvec vec;
int j;
@@ -877,7 +908,7 @@ redirect_edge_and_branch (e, target)
++LABEL_NUSES (new_label);
}
- /* Handle casesi dispatch insns */
+ /* Handle casesi dispatch insns. */
if ((tmp = single_set (insn)) != NULL
&& SET_DEST (tmp) == pc_rtx
&& GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
@@ -921,6 +952,33 @@ redirect_edge_and_branch (e, target)
if (e->dest != target)
redirect_edge_succ_nodup (e, target);
+ return true;
+}
+
+/* Attempt to change code to redirect edge E to TARGET. Don't do that on
+ expense of adding new instructions or reordering basic blocks.
+
+ Function can be also called with edge destination equivalent to the TARGET.
+ Then it should try the simplifications and do nothing if none is possible.
+
+ Return true if transformation succeeded. We still return false in case E
+ already destinated TARGET and we didn't managed to simplify instruction
+ stream. */
+
+static bool
+rtl_redirect_edge_and_branch (edge e, basic_block target)
+{
+ if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
+ return false;
+
+ if (e->dest == target)
+ return true;
+
+ if (try_redirect_by_replacing_jump (e, target, false))
+ return true;
+
+ if (!redirect_branch_edge (e, target))
+ return false;
return true;
}
@@ -928,10 +986,8 @@ redirect_edge_and_branch (e, target)
/* Like force_nonfallthru below, but additionally performs redirection
Used by redirect_edge_and_branch_force. */
-static basic_block
-force_nonfallthru_and_redirect (e, target)
- edge e;
- basic_block target;
+basic_block
+force_nonfallthru_and_redirect (edge e, basic_block target)
{
basic_block jump_block, new_bb = NULL, src = e->src;
rtx note;
@@ -940,20 +996,20 @@ force_nonfallthru_and_redirect (e, target)
/* In the case the last instruction is conditional jump to the next
instruction, first redirect the jump itself and then continue
- by creating an basic block afterwards to redirect fallthru edge. */
+ by creating a basic block afterwards to redirect fallthru edge. */
if (e->src != ENTRY_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR
- && any_condjump_p (e->src->end)
+ && any_condjump_p (BB_END (e->src))
/* When called from cfglayout, fallthru edges do not
- neccessarily go to the next block. */
+ necessarily go to the next block. */
&& e->src->next_bb == e->dest
- && JUMP_LABEL (e->src->end) == e->dest->head)
+ && JUMP_LABEL (BB_END (e->src)) == BB_HEAD (e->dest))
{
rtx note;
edge b = unchecked_make_edge (e->src, target, 0);
- if (!redirect_jump (e->src->end, block_label (target), 0))
+ if (!redirect_jump (BB_END (e->src), block_label (target), 0))
abort ();
- note = find_reg_note (e->src->end, REG_BR_PROB, NULL_RTX);
+ note = find_reg_note (BB_END (e->src), REG_BR_PROB, NULL_RTX);
if (note)
{
int prob = INTVAL (XEXP (note, 0));
@@ -974,7 +1030,7 @@ force_nonfallthru_and_redirect (e, target)
/* Irritating special case - fallthru edge to the same block as abnormal
edge.
We can't redirect abnormal edge, but we still can split the fallthru
- one and create separate abnormal edge to original destination.
+ one and create separate abnormal edge to original destination.
This allows bb-reorder to make such edge non-fallthru. */
if (e->dest != target)
abort ();
@@ -988,7 +1044,7 @@ force_nonfallthru_and_redirect (e, target)
/* We can't redirect the entry block. Create an empty block at the
start of the function which we use to add the new jump. */
edge *pe1;
- basic_block bb = create_basic_block (e->dest->head, NULL, ENTRY_BLOCK_PTR);
+ basic_block bb = create_basic_block (BB_HEAD (e->dest), NULL, ENTRY_BLOCK_PTR);
/* Change the existing edge's source to be the new block, and add
a new edge from the entry block to the new block. */
@@ -1008,19 +1064,16 @@ force_nonfallthru_and_redirect (e, target)
{
/* Create the new structures. */
+ /* If the old block ended with a tablejump, skip its table
+ by searching forward from there. Otherwise start searching
+ forward from the last instruction of the old block. */
+ if (!tablejump_p (BB_END (e->src), NULL, &note))
+ note = BB_END (e->src);
+
/* Position the new block correctly relative to loop notes. */
- note = last_loop_beg_note (e->src->end);
+ note = last_loop_beg_note (note);
note = NEXT_INSN (note);
- /* ... and ADDR_VECs. */
- if (note != NULL
- && GET_CODE (note) == CODE_LABEL
- && NEXT_INSN (note)
- && GET_CODE (NEXT_INSN (note)) == JUMP_INSN
- && (GET_CODE (PATTERN (NEXT_INSN (note))) == ADDR_DIFF_VEC
- || GET_CODE (PATTERN (NEXT_INSN (note))) == ADDR_VEC))
- note = NEXT_INSN (NEXT_INSN (note));
-
jump_block = create_basic_block (note, NULL, e->src);
jump_block->count = e->count;
jump_block->frequency = EDGE_FREQUENCY (e);
@@ -1056,19 +1109,19 @@ force_nonfallthru_and_redirect (e, target)
if (target == EXIT_BLOCK_PTR)
{
if (HAVE_return)
- emit_jump_insn_after (gen_return (), jump_block->end);
+ emit_jump_insn_after_noloc (gen_return (), BB_END (jump_block));
else
abort ();
}
else
{
rtx label = block_label (target);
- emit_jump_insn_after (gen_jump (label), jump_block->end);
- JUMP_LABEL (jump_block->end) = label;
+ emit_jump_insn_after_noloc (gen_jump (label), BB_END (jump_block));
+ JUMP_LABEL (BB_END (jump_block)) = label;
LABEL_NUSES (label)++;
}
- emit_barrier_after (jump_block->end);
+ emit_barrier_after (BB_END (jump_block));
redirect_edge_succ_nodup (e, target);
if (abnormal_edge_flags)
@@ -1082,8 +1135,7 @@ force_nonfallthru_and_redirect (e, target)
Return newly created BB or NULL if none. */
basic_block
-force_nonfallthru (e)
- edge e;
+force_nonfallthru (edge e)
{
return force_nonfallthru_and_redirect (e, e->dest);
}
@@ -1092,10 +1144,8 @@ force_nonfallthru (e)
basic block. Return new basic block if created, NULL otherwise.
Abort if conversion is impossible. */
-basic_block
-redirect_edge_and_branch_force (e, target)
- edge e;
- basic_block target;
+static basic_block
+rtl_redirect_edge_and_branch_force (edge e, basic_block target)
{
if (redirect_edge_and_branch (e, target)
|| e->dest == target)
@@ -1110,9 +1160,7 @@ redirect_edge_and_branch_force (e, target)
fact true, delete the jump and barriers that are in the way. */
void
-tidy_fallthru_edge (e, b, c)
- edge e;
- basic_block b, c;
+tidy_fallthru_edge (edge e, basic_block b, basic_block c)
{
rtx q;
@@ -1126,14 +1174,14 @@ tidy_fallthru_edge (e, b, c)
So search through a sequence of barriers, labels, and notes for
the head of block C and assert that we really do fall through. */
- for (q = NEXT_INSN (b->end); q != c->head; q = NEXT_INSN (q))
+ for (q = NEXT_INSN (BB_END (b)); q != BB_HEAD (c); q = NEXT_INSN (q))
if (INSN_P (q))
return;
/* Remove what will soon cease being the jump insn from the source block.
If block B consisted only of this single jump, turn it into a deleted
note. */
- q = b->end;
+ q = BB_END (b);
if (GET_CODE (q) == JUMP_INSN
&& onlyjump_p (q)
&& (any_uncondjump_p (q)
@@ -1155,8 +1203,8 @@ tidy_fallthru_edge (e, b, c)
}
/* Selectively unlink the sequence. */
- if (q != PREV_INSN (c->head))
- delete_insn_chain (NEXT_INSN (q), PREV_INSN (c->head));
+ if (q != PREV_INSN (BB_HEAD (c)))
+ delete_insn_chain (NEXT_INSN (q), PREV_INSN (BB_HEAD (c)));
e->flags |= EDGE_FALLTHRU;
}
@@ -1167,7 +1215,7 @@ tidy_fallthru_edge (e, b, c)
is how find_basic_blocks created them. */
void
-tidy_fallthru_edges ()
+tidy_fallthru_edges (void)
{
basic_block b, c;
@@ -1197,8 +1245,8 @@ tidy_fallthru_edges ()
&& s->succ_next == NULL
&& s->dest == c
/* If the jump insn has side effects, we can't tidy the edge. */
- && (GET_CODE (b->end) != JUMP_INSN
- || onlyjump_p (b->end)))
+ && (GET_CODE (BB_END (b)) != JUMP_INSN
+ || onlyjump_p (BB_END (b))))
tidy_fallthru_edge (s, b, c);
}
}
@@ -1207,8 +1255,7 @@ tidy_fallthru_edges ()
is back edge of syntactic loop. */
static bool
-back_edge_of_syntactic_loop_p (bb1, bb2)
- basic_block bb1, bb2;
+back_edge_of_syntactic_loop_p (basic_block bb1, basic_block bb2)
{
rtx insn;
int count = 0;
@@ -1225,7 +1272,7 @@ back_edge_of_syntactic_loop_p (bb1, bb2)
if (!bb)
return false;
- for (insn = bb1->end; insn != bb2->head && count >= 0;
+ for (insn = BB_END (bb1); insn != BB_HEAD (bb2) && count >= 0;
insn = NEXT_INSN (insn))
if (GET_CODE (insn) == NOTE)
{
@@ -1245,12 +1292,10 @@ back_edge_of_syntactic_loop_p (bb1, bb2)
The case of a block ending in an unconditional jump to a
block with multiple predecessors is not handled optimally. */
-basic_block
-split_edge (edge_in)
- edge edge_in;
+static basic_block
+rtl_split_edge (edge edge_in)
{
basic_block bb;
- edge edge_out;
rtx before;
/* Abnormal edges cannot be split. */
@@ -1290,14 +1335,14 @@ split_edge (edge_in)
we confuse the loop optimizer into thinking the loop is a phony. */
if (edge_in->dest != EXIT_BLOCK_PTR
- && PREV_INSN (edge_in->dest->head)
- && GET_CODE (PREV_INSN (edge_in->dest->head)) == NOTE
- && (NOTE_LINE_NUMBER (PREV_INSN (edge_in->dest->head))
+ && PREV_INSN (BB_HEAD (edge_in->dest))
+ && GET_CODE (PREV_INSN (BB_HEAD (edge_in->dest))) == NOTE
+ && (NOTE_LINE_NUMBER (PREV_INSN (BB_HEAD (edge_in->dest)))
== NOTE_INSN_LOOP_BEG)
&& !back_edge_of_syntactic_loop_p (edge_in->dest, edge_in->src))
- before = PREV_INSN (edge_in->dest->head);
+ before = PREV_INSN (BB_HEAD (edge_in->dest));
else if (edge_in->dest != EXIT_BLOCK_PTR)
- before = edge_in->dest->head;
+ before = BB_HEAD (edge_in->dest);
else
before = NULL_RTX;
@@ -1316,9 +1361,9 @@ split_edge (edge_in)
edge_in->dest->global_live_at_start);
}
- edge_out = make_single_succ_edge (bb, edge_in->dest, EDGE_FALLTHRU);
+ make_single_succ_edge (bb, edge_in->dest, EDGE_FALLTHRU);
- /* For non-fallthry edges, we must adjust the predecessor's
+ /* For non-fallthru edges, we must adjust the predecessor's
jump instruction to target our new block. */
if ((edge_in->flags & EDGE_FALLTHRU) == 0)
{
@@ -1336,9 +1381,7 @@ split_edge (edge_in)
CFG until commit_edge_insertions is called. */
void
-insert_insn_on_edge (pattern, e)
- rtx pattern;
- edge e;
+insert_insn_on_edge (rtx pattern, edge e)
{
/* We cannot insert instructions on an abnormal critical edge.
It will be easier to find the culprit if we die now. */
@@ -1356,12 +1399,105 @@ insert_insn_on_edge (pattern, e)
end_sequence ();
}
+/* Called from safe_insert_insn_on_edge through note_stores, marks live
+ registers that are killed by the store. */
+static void
+mark_killed_regs (rtx reg, rtx set ATTRIBUTE_UNUSED, void *data)
+{
+ regset killed = data;
+ int regno, i;
+
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+ if (!REG_P (reg))
+ return;
+ regno = REGNO (reg);
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ SET_REGNO_REG_SET (killed, regno);
+ else
+ {
+ for (i = 0; i < (int) HARD_REGNO_NREGS (regno, GET_MODE (reg)); i++)
+ SET_REGNO_REG_SET (killed, regno + i);
+ }
+}
+
+/* Similar to insert_insn_on_edge, tries to put INSN to edge E. Additionally
+ it checks whether this will not clobber the registers that are live on the
+ edge (i.e. it requires liveness information to be up-to-date) and if there
+ are some, then it tries to save and restore them. Returns true if
+ successful. */
+bool
+safe_insert_insn_on_edge (rtx insn, edge e)
+{
+ rtx x;
+ regset_head killed_head;
+ regset killed = INITIALIZE_REG_SET (killed_head);
+ rtx save_regs = NULL_RTX;
+ int regno, noccmode;
+ enum machine_mode mode;
+
+#ifdef AVOID_CCMODE_COPIES
+ noccmode = true;
+#else
+ noccmode = false;
+#endif
+
+ for (x = insn; x; x = NEXT_INSN (x))
+ if (INSN_P (x))
+ note_stores (PATTERN (x), mark_killed_regs, killed);
+ bitmap_operation (killed, killed, e->dest->global_live_at_start,
+ BITMAP_AND);
+
+ EXECUTE_IF_SET_IN_REG_SET (killed, 0, regno,
+ {
+ mode = regno < FIRST_PSEUDO_REGISTER
+ ? reg_raw_mode[regno]
+ : GET_MODE (regno_reg_rtx[regno]);
+ if (mode == VOIDmode)
+ return false;
+
+ if (noccmode && mode == CCmode)
+ return false;
+
+ save_regs = alloc_EXPR_LIST (0,
+ alloc_EXPR_LIST (0,
+ gen_reg_rtx (mode),
+ gen_raw_REG (mode, regno)),
+ save_regs);
+ });
+
+ if (save_regs)
+ {
+ rtx from, to;
+
+ start_sequence ();
+ for (x = save_regs; x; x = XEXP (x, 1))
+ {
+ from = XEXP (XEXP (x, 0), 1);
+ to = XEXP (XEXP (x, 0), 0);
+ emit_move_insn (to, from);
+ }
+ emit_insn (insn);
+ for (x = save_regs; x; x = XEXP (x, 1))
+ {
+ from = XEXP (XEXP (x, 0), 0);
+ to = XEXP (XEXP (x, 0), 1);
+ emit_move_insn (to, from);
+ }
+ insn = get_insns ();
+ end_sequence ();
+ free_EXPR_LIST_list (&save_regs);
+ }
+ insert_insn_on_edge (insn, e);
+
+ FREE_REG_SET (killed);
+ return true;
+}
+
/* Update the CFG for the instructions queued on edge E. */
static void
-commit_one_edge_insertion (e, watch_calls)
- edge e;
- int watch_calls;
+commit_one_edge_insertion (edge e, int watch_calls)
{
rtx before = NULL_RTX, after = NULL_RTX, insns, tmp, last;
basic_block bb = NULL;
@@ -1374,11 +1510,11 @@ commit_one_edge_insertion (e, watch_calls)
its return value. */
if (watch_calls && (e->flags & EDGE_FALLTHRU) && !e->dest->pred->pred_next
&& e->src != ENTRY_BLOCK_PTR
- && GET_CODE (e->src->end) == CALL_INSN)
+ && GET_CODE (BB_END (e->src)) == CALL_INSN)
{
- rtx next = next_nonnote_insn (e->src->end);
+ rtx next = next_nonnote_insn (BB_END (e->src));
- after = e->dest->head;
+ after = BB_HEAD (e->dest);
/* The first insn after the call may be a stack pop, skip it. */
while (next
&& keep_with_call_p (next))
@@ -1398,12 +1534,12 @@ commit_one_edge_insertion (e, watch_calls)
/* Get the location correct wrt a code label, and "nice" wrt
a basic block note, and before everything else. */
- tmp = bb->head;
+ tmp = BB_HEAD (bb);
if (GET_CODE (tmp) == CODE_LABEL)
tmp = NEXT_INSN (tmp);
if (NOTE_INSN_BASIC_BLOCK_P (tmp))
tmp = NEXT_INSN (tmp);
- if (tmp == bb->head)
+ if (tmp == BB_HEAD (bb))
before = tmp;
else if (tmp)
after = PREV_INSN (tmp);
@@ -1425,8 +1561,8 @@ commit_one_edge_insertion (e, watch_calls)
We know this block has a single successor, so we can just emit
the queued insns before the jump. */
- if (GET_CODE (bb->end) == JUMP_INSN)
- for (before = bb->end;
+ if (GET_CODE (BB_END (bb)) == JUMP_INSN)
+ for (before = BB_END (bb);
GET_CODE (PREV_INSN (before)) == NOTE
&& NOTE_LINE_NUMBER (PREV_INSN (before)) ==
NOTE_INSN_LOOP_BEG; before = PREV_INSN (before))
@@ -1437,14 +1573,14 @@ commit_one_edge_insertion (e, watch_calls)
if ((e->flags & EDGE_FALLTHRU) == 0)
abort ();
- after = bb->end;
+ after = BB_END (bb);
}
}
/* Otherwise we must split the edge. */
else
{
bb = split_edge (e);
- after = bb->end;
+ after = BB_END (bb);
}
}
@@ -1452,11 +1588,11 @@ commit_one_edge_insertion (e, watch_calls)
if (before)
{
- emit_insn_before (insns, before);
+ emit_insn_before_noloc (insns, before);
last = prev_nonnote_insn (before);
}
else
- last = emit_insn_after (insns, after);
+ last = emit_insn_after_noloc (insns, after);
if (returnjump_p (last))
{
@@ -1486,7 +1622,7 @@ commit_one_edge_insertion (e, watch_calls)
/* Update the CFG for all queued instructions. */
void
-commit_edge_insertions ()
+commit_edge_insertions (void)
{
basic_block bb;
sbitmap blocks;
@@ -1505,8 +1641,8 @@ commit_edge_insertions ()
next = e->succ_next;
if (e->insns)
{
- changed = true;
- commit_one_edge_insertion (e, false);
+ changed = true;
+ commit_one_edge_insertion (e, false);
}
}
}
@@ -1520,6 +1656,10 @@ commit_edge_insertions ()
if (bb->aux)
{
SET_BIT (blocks, bb->index);
+ /* Check for forgotten bb->aux values before commit_edge_insertions
+ call. */
+ if (bb->aux != &bb->aux)
+ abort ();
bb->aux = NULL;
}
find_many_sub_basic_blocks (blocks);
@@ -1530,7 +1670,7 @@ commit_edge_insertions ()
code on edges between call and storing its return value. */
void
-commit_edge_insertions_watch_calls ()
+commit_edge_insertions_watch_calls (void)
{
basic_block bb;
sbitmap blocks;
@@ -1564,6 +1704,10 @@ commit_edge_insertions_watch_calls ()
if (bb->aux)
{
SET_BIT (blocks, bb->index);
+ /* Check for forgotten bb->aux values before commit_edge_insertions
+ call. */
+ if (bb->aux != &bb->aux)
+ abort ();
bb->aux = NULL;
}
find_many_sub_basic_blocks (blocks);
@@ -1572,64 +1716,30 @@ commit_edge_insertions_watch_calls ()
/* Print out one basic block with live information at start and end. */
-void
-dump_bb (bb, outf)
- basic_block bb;
- FILE *outf;
+static void
+rtl_dump_bb (basic_block bb, FILE *outf)
{
rtx insn;
rtx last;
- edge e;
-
- fprintf (outf, ";; Basic block %d, loop depth %d, count ",
- bb->index, bb->loop_depth);
- fprintf (outf, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count);
- putc ('\n', outf);
-
- fputs (";; Predecessors: ", outf);
- for (e = bb->pred; e; e = e->pred_next)
- dump_edge_info (outf, e, 0);
- putc ('\n', outf);
fputs (";; Registers live at start:", outf);
dump_regset (bb->global_live_at_start, outf);
putc ('\n', outf);
- for (insn = bb->head, last = NEXT_INSN (bb->end); insn != last;
+ for (insn = BB_HEAD (bb), last = NEXT_INSN (BB_END (bb)); insn != last;
insn = NEXT_INSN (insn))
print_rtl_single (outf, insn);
fputs (";; Registers live at end:", outf);
dump_regset (bb->global_live_at_end, outf);
putc ('\n', outf);
-
- fputs (";; Successors: ", outf);
- for (e = bb->succ; e; e = e->succ_next)
- dump_edge_info (outf, e, 1);
- putc ('\n', outf);
-}
-
-void
-debug_bb (bb)
- basic_block bb;
-{
- dump_bb (bb, stderr);
-}
-
-void
-debug_bb_n (n)
- int n;
-{
- dump_bb (BASIC_BLOCK (n), stderr);
}
/* Like print_rtl, but also print out live information for the start of each
basic block. */
void
-print_rtl_with_bb (outf, rtx_first)
- FILE *outf;
- rtx rtx_first;
+print_rtl_with_bb (FILE *outf, rtx rtx_first)
{
rtx tmp_rtx;
@@ -1639,12 +1749,9 @@ print_rtl_with_bb (outf, rtx_first)
{
enum bb_state { NOT_IN_BB, IN_ONE_BB, IN_MULTIPLE_BB };
int max_uid = get_max_uid ();
- basic_block *start
- = (basic_block *) xcalloc (max_uid, sizeof (basic_block));
- basic_block *end
- = (basic_block *) xcalloc (max_uid, sizeof (basic_block));
- enum bb_state *in_bb_p
- = (enum bb_state *) xcalloc (max_uid, sizeof (enum bb_state));
+ basic_block *start = xcalloc (max_uid, sizeof (basic_block));
+ basic_block *end = xcalloc (max_uid, sizeof (basic_block));
+ enum bb_state *in_bb_p = xcalloc (max_uid, sizeof (enum bb_state));
basic_block bb;
@@ -1652,9 +1759,9 @@ print_rtl_with_bb (outf, rtx_first)
{
rtx x;
- start[INSN_UID (bb->head)] = bb;
- end[INSN_UID (bb->end)] = bb;
- for (x = bb->head; x != NULL_RTX; x = NEXT_INSN (x))
+ start[INSN_UID (BB_HEAD (bb))] = bb;
+ end[INSN_UID (BB_END (bb))] = bb;
+ for (x = BB_HEAD (bb); x != NULL_RTX; x = NEXT_INSN (x))
{
enum bb_state state = IN_MULTIPLE_BB;
@@ -1662,7 +1769,7 @@ print_rtl_with_bb (outf, rtx_first)
state = IN_ONE_BB;
in_bb_p[INSN_UID (x)] = state;
- if (x == bb->end)
+ if (x == BB_END (bb))
break;
}
}
@@ -1715,80 +1822,50 @@ print_rtl_with_bb (outf, rtx_first)
}
void
-update_br_prob_note (bb)
- basic_block bb;
+update_br_prob_note (basic_block bb)
{
rtx note;
- if (GET_CODE (bb->end) != JUMP_INSN)
+ if (GET_CODE (BB_END (bb)) != JUMP_INSN)
return;
- note = find_reg_note (bb->end, REG_BR_PROB, NULL_RTX);
+ note = find_reg_note (BB_END (bb), REG_BR_PROB, NULL_RTX);
if (!note || INTVAL (XEXP (note, 0)) == BRANCH_EDGE (bb)->probability)
return;
XEXP (note, 0) = GEN_INT (BRANCH_EDGE (bb)->probability);
}
-/* Verify the CFG consistency. This function check some CFG invariants and
- aborts when something is wrong. Hope that this function will help to
- convert many optimization passes to preserve CFG consistent.
+/* Verify the CFG and RTL consistency common for both underlying RTL and
+ cfglayout RTL.
Currently it does following checks:
- test head/end pointers
- overlapping of basic blocks
- - edge list correctness
- headers of basic blocks (the NOTE_INSN_BASIC_BLOCK note)
- tails of basic blocks (ensure that boundary is necessary)
- scans body of the basic block for JUMP_INSN, CODE_LABEL
and NOTE_INSN_BASIC_BLOCK
- - check that all insns are in the basic blocks
- (except the switch handling code, barriers and notes)
- - check that all returns are followed by barriers
In future it can be extended check a lot of other stuff as well
(reachability of basic blocks, life information, etc. etc.). */
-
-void
-verify_flow_info ()
+static int
+rtl_verify_flow_info_1 (void)
{
const int max_uid = get_max_uid ();
- const rtx rtx_first = get_insns ();
rtx last_head = get_last_insn ();
- basic_block *bb_info, *last_visited;
- size_t *edge_checksum;
+ basic_block *bb_info;
rtx x;
- int num_bb_notes, err = 0;
+ int err = 0;
basic_block bb, last_bb_seen;
- bb_info = (basic_block *) xcalloc (max_uid, sizeof (basic_block));
- last_visited = (basic_block *) xcalloc (last_basic_block + 2,
- sizeof (basic_block));
- edge_checksum = (size_t *) xcalloc (last_basic_block + 2, sizeof (size_t));
+ bb_info = xcalloc (max_uid, sizeof (basic_block));
/* Check bb chain & numbers. */
last_bb_seen = ENTRY_BLOCK_PTR;
- FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, NULL, next_bb)
- {
- if (bb != EXIT_BLOCK_PTR
- && bb != BASIC_BLOCK (bb->index))
- {
- error ("bb %d on wrong place", bb->index);
- err = 1;
- }
-
- if (bb->prev_bb != last_bb_seen)
- {
- error ("prev_bb of %d should be %d, not %d",
- bb->index, last_bb_seen->index, bb->prev_bb->index);
- err = 1;
- }
-
- last_bb_seen = bb;
- }
FOR_EACH_BB_REVERSE (bb)
{
- rtx head = bb->head;
- rtx end = bb->end;
+ rtx head = BB_HEAD (bb);
+ rtx end = BB_END (bb);
/* Verify the end of the basic block is in the INSN chain. */
for (x = last_head; x != NULL_RTX; x = PREV_INSN (x))
@@ -1835,60 +1912,30 @@ verify_flow_info ()
FOR_EACH_BB_REVERSE (bb)
{
int n_fallthru = 0, n_eh = 0, n_call = 0, n_abnormal = 0, n_branch = 0;
- edge e;
+ edge e, fallthru = NULL;
rtx note;
- if (INSN_P (bb->end)
- && (note = find_reg_note (bb->end, REG_BR_PROB, NULL_RTX))
+ if (INSN_P (BB_END (bb))
+ && (note = find_reg_note (BB_END (bb), REG_BR_PROB, NULL_RTX))
&& bb->succ && bb->succ->succ_next
- && any_condjump_p (bb->end))
+ && any_condjump_p (BB_END (bb)))
{
if (INTVAL (XEXP (note, 0)) != BRANCH_EDGE (bb)->probability)
{
- error ("verify_flow_info: REG_BR_PROB does not match cfg %i %i",
+ error ("verify_flow_info: REG_BR_PROB does not match cfg %wi %i",
INTVAL (XEXP (note, 0)), BRANCH_EDGE (bb)->probability);
err = 1;
}
}
- if (bb->count < 0)
- {
- error ("verify_flow_info: Wrong count of block %i %i",
- bb->index, (int)bb->count);
- err = 1;
- }
- if (bb->frequency < 0)
- {
- error ("verify_flow_info: Wrong frequency of block %i %i",
- bb->index, bb->frequency);
- err = 1;
- }
for (e = bb->succ; e; e = e->succ_next)
{
- if (last_visited [e->dest->index + 2] == bb)
- {
- error ("verify_flow_info: Duplicate edge %i->%i",
- e->src->index, e->dest->index);
- err = 1;
- }
- if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
- {
- error ("verify_flow_info: Wrong probability of edge %i->%i %i",
- e->src->index, e->dest->index, e->probability);
- err = 1;
- }
- if (e->count < 0)
- {
- error ("verify_flow_info: Wrong count of edge %i->%i %i",
- e->src->index, e->dest->index, (int)e->count);
- err = 1;
- }
-
- last_visited [e->dest->index + 2] = bb;
-
if (e->flags & EDGE_FALLTHRU)
- n_fallthru++;
+ n_fallthru++, fallthru = e;
- if ((e->flags & ~EDGE_DFS_BACK) == 0)
+ if ((e->flags & ~(EDGE_DFS_BACK
+ | EDGE_CAN_FALLTHRU
+ | EDGE_IRREDUCIBLE_LOOP
+ | EDGE_LOOP_EXIT)) == 0)
n_branch++;
if (e->flags & EDGE_ABNORMAL_CALL)
@@ -1898,131 +1945,54 @@ verify_flow_info ()
n_eh++;
else if (e->flags & EDGE_ABNORMAL)
n_abnormal++;
-
- if ((e->flags & EDGE_FALLTHRU)
- && e->src != ENTRY_BLOCK_PTR
- && e->dest != EXIT_BLOCK_PTR)
- {
- rtx insn;
-
- if (e->src->next_bb != e->dest)
- {
- error
- ("verify_flow_info: Incorrect blocks for fallthru %i->%i",
- e->src->index, e->dest->index);
- err = 1;
- }
- else
- for (insn = NEXT_INSN (e->src->end); insn != e->dest->head;
- insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == BARRIER
-#ifndef CASE_DROPS_THROUGH
- || INSN_P (insn)
-#else
- || (INSN_P (insn) && ! JUMP_TABLE_DATA_P (insn))
-#endif
- )
- {
- error ("verify_flow_info: Incorrect fallthru %i->%i",
- e->src->index, e->dest->index);
- fatal_insn ("wrong insn in the fallthru edge", insn);
- err = 1;
- }
- }
-
- if (e->src != bb)
- {
- error ("verify_flow_info: Basic block %d succ edge is corrupted",
- bb->index);
- fprintf (stderr, "Predecessor: ");
- dump_edge_info (stderr, e, 0);
- fprintf (stderr, "\nSuccessor: ");
- dump_edge_info (stderr, e, 1);
- fprintf (stderr, "\n");
- err = 1;
- }
-
- edge_checksum[e->dest->index + 2] += (size_t) e;
}
- if (n_eh && GET_CODE (PATTERN (bb->end)) != RESX
- && !find_reg_note (bb->end, REG_EH_REGION, NULL_RTX))
+ if (n_eh && GET_CODE (PATTERN (BB_END (bb))) != RESX
+ && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX))
{
error ("Missing REG_EH_REGION note in the end of bb %i", bb->index);
err = 1;
}
if (n_branch
- && (GET_CODE (bb->end) != JUMP_INSN
- || (n_branch > 1 && (any_uncondjump_p (bb->end)
- || any_condjump_p (bb->end)))))
+ && (GET_CODE (BB_END (bb)) != JUMP_INSN
+ || (n_branch > 1 && (any_uncondjump_p (BB_END (bb))
+ || any_condjump_p (BB_END (bb))))))
{
error ("Too many outgoing branch edges from bb %i", bb->index);
err = 1;
}
- if (n_fallthru && any_uncondjump_p (bb->end))
+ if (n_fallthru && any_uncondjump_p (BB_END (bb)))
{
error ("Fallthru edge after unconditional jump %i", bb->index);
err = 1;
}
- if (n_branch != 1 && any_uncondjump_p (bb->end))
+ if (n_branch != 1 && any_uncondjump_p (BB_END (bb)))
{
error ("Wrong amount of branch edges after unconditional jump %i", bb->index);
err = 1;
}
- if (n_branch != 1 && any_condjump_p (bb->end)
- && JUMP_LABEL (bb->end) != bb->next_bb->head)
+ if (n_branch != 1 && any_condjump_p (BB_END (bb))
+ && JUMP_LABEL (BB_END (bb)) != BB_HEAD (fallthru->dest))
{
error ("Wrong amount of branch edges after conditional jump %i", bb->index);
err = 1;
}
- if (n_call && GET_CODE (bb->end) != CALL_INSN)
+ if (n_call && GET_CODE (BB_END (bb)) != CALL_INSN)
{
error ("Call edges for non-call insn in bb %i", bb->index);
err = 1;
}
if (n_abnormal
- && (GET_CODE (bb->end) != CALL_INSN && n_call != n_abnormal)
- && (GET_CODE (bb->end) != JUMP_INSN
- || any_condjump_p (bb->end)
- || any_uncondjump_p (bb->end)))
+ && (GET_CODE (BB_END (bb)) != CALL_INSN && n_call != n_abnormal)
+ && (GET_CODE (BB_END (bb)) != JUMP_INSN
+ || any_condjump_p (BB_END (bb))
+ || any_uncondjump_p (BB_END (bb))))
{
error ("Abnormal edges for no purpose in bb %i", bb->index);
err = 1;
}
- if (!n_fallthru)
- {
- rtx insn;
-
- /* Ensure existence of barrier in BB with no fallthru edges. */
- for (insn = bb->end; !insn || GET_CODE (insn) != BARRIER;
- insn = NEXT_INSN (insn))
- if (!insn
- || (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK))
- {
- error ("missing barrier after block %i", bb->index);
- err = 1;
- break;
- }
- }
-
- for (e = bb->pred; e; e = e->pred_next)
- {
- if (e->dest != bb)
- {
- error ("basic block %d pred edge is corrupted", bb->index);
- fputs ("Predecessor: ", stderr);
- dump_edge_info (stderr, e, 0);
- fputs ("\nSuccessor: ", stderr);
- dump_edge_info (stderr, e, 1);
- fputc ('\n', stderr);
- err = 1;
- }
- edge_checksum[e->dest->index + 2] -= (size_t) e;
- }
-
- for (x = bb->head; x != NEXT_INSN (bb->end); x = NEXT_INSN (x))
+ for (x = BB_HEAD (bb); x != NEXT_INSN (BB_END (bb)); x = NEXT_INSN (x))
if (BLOCK_FOR_INSN (x) != bb)
{
debug_rtx (x);
@@ -2041,10 +2011,10 @@ verify_flow_info ()
/* OK pointers are correct. Now check the header of basic
block. It ought to contain optional CODE_LABEL followed
by NOTE_BASIC_BLOCK. */
- x = bb->head;
+ x = BB_HEAD (bb);
if (GET_CODE (x) == CODE_LABEL)
{
- if (bb->end == x)
+ if (BB_END (bb) == x)
{
error ("NOTE_INSN_BASIC_BLOCK is missing for block %d",
bb->index);
@@ -2061,7 +2031,7 @@ verify_flow_info ()
err = 1;
}
- if (bb->end == x)
+ if (BB_END (bb) == x)
/* Do checks for empty blocks her. e */
;
else
@@ -2074,12 +2044,10 @@ verify_flow_info ()
err = 1;
}
- if (x == bb->end)
+ if (x == BB_END (bb))
break;
- if (GET_CODE (x) == JUMP_INSN
- || GET_CODE (x) == CODE_LABEL
- || GET_CODE (x) == BARRIER)
+ if (control_flow_insn_p (x))
{
error ("in basic block %d:", bb->index);
fatal_insn ("flow control insn inside a basic block", x);
@@ -2087,23 +2055,82 @@ verify_flow_info ()
}
}
- /* Complete edge checksumming for ENTRY and EXIT. */
- {
- edge e;
+ /* Clean up. */
+ free (bb_info);
+ return err;
+}
+
+/* Verify the CFG and RTL consistency common for both underlying RTL and
+ cfglayout RTL.
+
+ Currently it does following checks:
+ - all checks of rtl_verify_flow_info_1
+ - check that all insns are in the basic blocks
+ (except the switch handling code, barriers and notes)
+ - check that all returns are followed by barriers
+ - check that all fallthru edge points to the adjacent blocks. */
+static int
+rtl_verify_flow_info (void)
+{
+ basic_block bb;
+ int err = rtl_verify_flow_info_1 ();
+ rtx x;
+ int num_bb_notes;
+ const rtx rtx_first = get_insns ();
+ basic_block last_bb_seen = ENTRY_BLOCK_PTR, curr_bb = NULL;
- for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
- edge_checksum[e->dest->index + 2] += (size_t) e;
+ FOR_EACH_BB_REVERSE (bb)
+ {
+ edge e;
+ for (e = bb->succ; e; e = e->succ_next)
+ if (e->flags & EDGE_FALLTHRU)
+ break;
+ if (!e)
+ {
+ rtx insn;
- for (e = EXIT_BLOCK_PTR->pred; e ; e = e->pred_next)
- edge_checksum[e->dest->index + 2] -= (size_t) e;
- }
+ /* Ensure existence of barrier in BB with no fallthru edges. */
+ for (insn = BB_END (bb); !insn || GET_CODE (insn) != BARRIER;
+ insn = NEXT_INSN (insn))
+ if (!insn
+ || (GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK))
+ {
+ error ("missing barrier after block %i", bb->index);
+ err = 1;
+ break;
+ }
+ }
+ else if (e->src != ENTRY_BLOCK_PTR
+ && e->dest != EXIT_BLOCK_PTR)
+ {
+ rtx insn;
- FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
- if (edge_checksum[bb->index + 2])
- {
- error ("basic block %i edge lists are corrupted", bb->index);
- err = 1;
- }
+ if (e->src->next_bb != e->dest)
+ {
+ error
+ ("verify_flow_info: Incorrect blocks for fallthru %i->%i",
+ e->src->index, e->dest->index);
+ err = 1;
+ }
+ else
+ for (insn = NEXT_INSN (BB_END (e->src)); insn != BB_HEAD (e->dest);
+ insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == BARRIER
+#ifndef CASE_DROPS_THROUGH
+ || INSN_P (insn)
+#else
+ || (INSN_P (insn) && ! JUMP_TABLE_DATA_P (insn))
+#endif
+ )
+ {
+ error ("verify_flow_info: Incorrect fallthru %i->%i",
+ e->src->index, e->dest->index);
+ fatal_insn ("wrong insn in the fallthru edge", insn);
+ err = 1;
+ }
+ }
+ }
num_bb_notes = 0;
last_bb_seen = ENTRY_BLOCK_PTR;
@@ -2116,12 +2143,12 @@ verify_flow_info ()
num_bb_notes++;
if (bb != last_bb_seen->next_bb)
- internal_error ("basic blocks not numbered consecutively");
+ internal_error ("basic blocks not laid down consecutively");
- last_bb_seen = bb;
+ curr_bb = last_bb_seen = bb;
}
- if (!bb_info[INSN_UID (x)])
+ if (!curr_bb)
{
switch (GET_CODE (x))
{
@@ -2150,6 +2177,8 @@ verify_flow_info ()
&& returnjump_p (x) && ! condjump_p (x)
&& ! (NEXT_INSN (x) && GET_CODE (NEXT_INSN (x)) == BARRIER))
fatal_insn ("return not followed by barrier", x);
+ if (curr_bb && x == BB_END (curr_bb))
+ curr_bb = NULL;
}
if (num_bb_notes != n_basic_blocks)
@@ -2157,13 +2186,7 @@ verify_flow_info ()
("number of bb notes in insn chain (%d) != n_basic_blocks (%d)",
num_bb_notes, n_basic_blocks);
- if (err)
- internal_error ("verify_flow_info failed");
-
- /* Clean up. */
- free (bb_info);
- free (last_visited);
- free (edge_checksum);
+ return err;
}
/* Assume that the preceding pass has possibly eliminated jump instructions
@@ -2171,11 +2194,10 @@ verify_flow_info ()
Return true if any edges are eliminated. */
bool
-purge_dead_edges (bb)
- basic_block bb;
+purge_dead_edges (basic_block bb)
{
edge e, next;
- rtx insn = bb->end, note;
+ rtx insn = BB_END (bb), note;
bool purged = false;
/* If this instruction cannot trap, remove REG_EH_REGION notes. */
@@ -2196,12 +2218,12 @@ purge_dead_edges (bb)
next = e->succ_next;
if (e->flags & EDGE_EH)
{
- if (can_throw_internal (bb->end))
+ if (can_throw_internal (BB_END (bb)))
continue;
}
else if (e->flags & EDGE_ABNORMAL_CALL)
{
- if (GET_CODE (bb->end) == CALL_INSN
+ if (GET_CODE (BB_END (bb)) == CALL_INSN
&& (! (note = find_reg_note (insn, REG_EH_REGION, NULL))
|| INTVAL (XEXP (note, 0)) >= 0))
continue;
@@ -2251,7 +2273,7 @@ purge_dead_edges (bb)
block, so we should keep the edge. */
continue;
else if (e->dest != EXIT_BLOCK_PTR
- && e->dest->head == JUMP_LABEL (insn))
+ && BB_HEAD (e->dest) == JUMP_LABEL (insn))
/* If the destination block is the target of the jump,
keep the edge. */
continue;
@@ -2261,8 +2283,8 @@ purge_dead_edges (bb)
continue;
else if ((e->flags & EDGE_EH) && can_throw_internal (insn))
/* Keep the edges that correspond to exceptions thrown by
- this instruction and rematerialize the EDGE_ABNORMAL flag
- we just cleared above. */
+ this instruction and rematerialize the EDGE_ABNORMAL
+ flag we just cleared above. */
{
e->flags |= EDGE_ABNORMAL;
continue;
@@ -2305,6 +2327,19 @@ purge_dead_edges (bb)
return purged;
}
+ else if (GET_CODE (insn) == CALL_INSN && SIBLING_CALL_P (insn))
+ {
+ /* First, there should not be any EH or ABCALL edges resulting
+ from non-local gotos and the like. If there were, we shouldn't
+ have created the sibcall in the first place. Second, there
+ should of course never have been a fallthru edge. */
+ if (!bb->succ || bb->succ->succ_next)
+ abort ();
+ if (bb->succ->flags != (EDGE_SIBCALL | EDGE_ABNORMAL))
+ abort ();
+
+ return 0;
+ }
/* If we don't see a jump insn, we don't know exactly why the block would
have been broken at this point. Look for a simple, non-fallthru edge,
@@ -2345,8 +2380,7 @@ purge_dead_edges (bb)
true if some edge has been eliminated. */
bool
-purge_all_dead_edges (update_life_p)
- int update_life_p;
+purge_all_dead_edges (int update_life_p)
{
int purged = false;
sbitmap blocks = 0;
@@ -2376,3 +2410,342 @@ purge_all_dead_edges (update_life_p)
sbitmap_free (blocks);
return purged;
}
+
+/* Same as split_block but update cfg_layout structures. */
+static edge
+cfg_layout_split_block (basic_block bb, void *insnp)
+{
+ rtx insn = insnp;
+
+ edge fallthru = rtl_split_block (bb, insn);
+
+ fallthru->dest->rbi->footer = fallthru->src->rbi->footer;
+ fallthru->src->rbi->footer = NULL;
+ return fallthru;
+}
+
+
+/* Redirect Edge to DEST. */
+static bool
+cfg_layout_redirect_edge_and_branch (edge e, basic_block dest)
+{
+ basic_block src = e->src;
+ bool ret;
+
+ if (e->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))
+ return false;
+
+ if (e->dest == dest)
+ return true;
+
+ if (e->src != ENTRY_BLOCK_PTR
+ && try_redirect_by_replacing_jump (e, dest, true))
+ return true;
+
+ if (e->src == ENTRY_BLOCK_PTR
+ && (e->flags & EDGE_FALLTHRU) && !(e->flags & EDGE_COMPLEX))
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Redirecting entry edge from bb %i to %i\n",
+ e->src->index, dest->index);
+
+ redirect_edge_succ (e, dest);
+ return true;
+ }
+
+ /* Redirect_edge_and_branch may decide to turn branch into fallthru edge
+ in the case the basic block appears to be in sequence. Avoid this
+ transformation. */
+
+ if (e->flags & EDGE_FALLTHRU)
+ {
+ /* Redirect any branch edges unified with the fallthru one. */
+ if (GET_CODE (BB_END (src)) == JUMP_INSN
+ && label_is_jump_target_p (BB_HEAD (e->dest),
+ BB_END (src)))
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Fallthru edge unified with branch "
+ "%i->%i redirected to %i\n",
+ e->src->index, e->dest->index, dest->index);
+ e->flags &= ~EDGE_FALLTHRU;
+ if (!redirect_branch_edge (e, dest))
+ abort ();
+ e->flags |= EDGE_FALLTHRU;
+ return true;
+ }
+ /* In case we are redirecting fallthru edge to the branch edge
+ of conditional jump, remove it. */
+ if (src->succ->succ_next
+ && !src->succ->succ_next->succ_next)
+ {
+ edge s = e->succ_next ? e->succ_next : src->succ;
+ if (s->dest == dest
+ && any_condjump_p (BB_END (src))
+ && onlyjump_p (BB_END (src)))
+ delete_insn (BB_END (src));
+ }
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Fallthru edge %i->%i redirected to %i\n",
+ e->src->index, e->dest->index, dest->index);
+ redirect_edge_succ_nodup (e, dest);
+
+ ret = true;
+ }
+ else
+ ret = redirect_branch_edge (e, dest);
+
+ /* We don't want simplejumps in the insn stream during cfglayout. */
+ if (simplejump_p (BB_END (src)))
+ abort ();
+
+ return ret;
+}
+
+/* Simple wrapper as we always can redirect fallthru edges. */
+static basic_block
+cfg_layout_redirect_edge_and_branch_force (edge e, basic_block dest)
+{
+ if (!cfg_layout_redirect_edge_and_branch (e, dest))
+ abort ();
+ return NULL;
+}
+
+/* Same as flow_delete_block but update cfg_layout structures. */
+static void
+cfg_layout_delete_block (basic_block bb)
+{
+ rtx insn, next, prev = PREV_INSN (BB_HEAD (bb)), *to, remaints;
+
+ if (bb->rbi->header)
+ {
+ next = BB_HEAD (bb);
+ if (prev)
+ NEXT_INSN (prev) = bb->rbi->header;
+ else
+ set_first_insn (bb->rbi->header);
+ PREV_INSN (bb->rbi->header) = prev;
+ insn = bb->rbi->header;
+ while (NEXT_INSN (insn))
+ insn = NEXT_INSN (insn);
+ NEXT_INSN (insn) = next;
+ PREV_INSN (next) = insn;
+ }
+ next = NEXT_INSN (BB_END (bb));
+ if (bb->rbi->footer)
+ {
+ insn = bb->rbi->footer;
+ while (insn)
+ {
+ if (GET_CODE (insn) == BARRIER)
+ {
+ if (PREV_INSN (insn))
+ NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
+ else
+ bb->rbi->footer = NEXT_INSN (insn);
+ if (NEXT_INSN (insn))
+ PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
+ }
+ if (GET_CODE (insn) == CODE_LABEL)
+ break;
+ insn = NEXT_INSN (insn);
+ }
+ if (bb->rbi->footer)
+ {
+ insn = BB_END (bb);
+ NEXT_INSN (insn) = bb->rbi->footer;
+ PREV_INSN (bb->rbi->footer) = insn;
+ while (NEXT_INSN (insn))
+ insn = NEXT_INSN (insn);
+ NEXT_INSN (insn) = next;
+ if (next)
+ PREV_INSN (next) = insn;
+ else
+ set_last_insn (insn);
+ }
+ }
+ if (bb->next_bb != EXIT_BLOCK_PTR)
+ to = &bb->next_bb->rbi->header;
+ else
+ to = &cfg_layout_function_footer;
+ rtl_delete_block (bb);
+
+ if (prev)
+ prev = NEXT_INSN (prev);
+ else
+ prev = get_insns ();
+ if (next)
+ next = PREV_INSN (next);
+ else
+ next = get_last_insn ();
+
+ if (next && NEXT_INSN (next) != prev)
+ {
+ remaints = unlink_insn_chain (prev, next);
+ insn = remaints;
+ while (NEXT_INSN (insn))
+ insn = NEXT_INSN (insn);
+ NEXT_INSN (insn) = *to;
+ if (*to)
+ PREV_INSN (*to) = insn;
+ *to = remaints;
+ }
+}
+
+/* Return true when blocks A and B can be safely merged. */
+static bool
+cfg_layout_can_merge_blocks_p (basic_block a, basic_block b)
+{
+ /* There must be exactly one edge in between the blocks. */
+ return (a->succ && !a->succ->succ_next && a->succ->dest == b
+ && !b->pred->pred_next && a != b
+ /* Must be simple edge. */
+ && !(a->succ->flags & EDGE_COMPLEX)
+ && a != ENTRY_BLOCK_PTR && b != EXIT_BLOCK_PTR
+ /* If the jump insn has side effects,
+ we can't kill the edge. */
+ && (GET_CODE (BB_END (a)) != JUMP_INSN
+ || (reload_completed
+ ? simplejump_p (BB_END (a)) : onlyjump_p (BB_END (a)))));
+}
+
+/* Merge block A and B, abort when it is not possible. */
+static void
+cfg_layout_merge_blocks (basic_block a, basic_block b)
+{
+#ifdef ENABLE_CHECKING
+ if (!cfg_layout_can_merge_blocks_p (a, b))
+ abort ();
+#endif
+
+ /* If there was a CODE_LABEL beginning B, delete it. */
+ if (GET_CODE (BB_HEAD (b)) == CODE_LABEL)
+ delete_insn (BB_HEAD (b));
+
+ /* We should have fallthru edge in a, or we can do dummy redirection to get
+ it cleaned up. */
+ if (GET_CODE (BB_END (a)) == JUMP_INSN)
+ try_redirect_by_replacing_jump (a->succ, b, true);
+ if (GET_CODE (BB_END (a)) == JUMP_INSN)
+ abort ();
+
+ /* Possible line number notes should appear in between. */
+ if (b->rbi->header)
+ {
+ rtx first = BB_END (a), last;
+
+ last = emit_insn_after_noloc (b->rbi->header, BB_END (a));
+ delete_insn_chain (NEXT_INSN (first), last);
+ b->rbi->header = NULL;
+ }
+
+ /* In the case basic blocks are not adjacent, move them around. */
+ if (NEXT_INSN (BB_END (a)) != BB_HEAD (b))
+ {
+ rtx first = unlink_insn_chain (BB_HEAD (b), BB_END (b));
+
+ emit_insn_after_noloc (first, BB_END (a));
+ /* Skip possible DELETED_LABEL insn. */
+ if (!NOTE_INSN_BASIC_BLOCK_P (first))
+ first = NEXT_INSN (first);
+ if (!NOTE_INSN_BASIC_BLOCK_P (first))
+ abort ();
+ BB_HEAD (b) = NULL;
+ delete_insn (first);
+ }
+ /* Otherwise just re-associate the instructions. */
+ else
+ {
+ rtx insn;
+
+ for (insn = BB_HEAD (b);
+ insn != NEXT_INSN (BB_END (b));
+ insn = NEXT_INSN (insn))
+ set_block_for_insn (insn, a);
+ insn = BB_HEAD (b);
+ /* Skip possible DELETED_LABEL insn. */
+ if (!NOTE_INSN_BASIC_BLOCK_P (insn))
+ insn = NEXT_INSN (insn);
+ if (!NOTE_INSN_BASIC_BLOCK_P (insn))
+ abort ();
+ BB_HEAD (b) = NULL;
+ BB_END (a) = BB_END (b);
+ delete_insn (insn);
+ }
+
+ /* Possible tablejumps and barriers should appear after the block. */
+ if (b->rbi->footer)
+ {
+ if (!a->rbi->footer)
+ a->rbi->footer = b->rbi->footer;
+ else
+ {
+ rtx last = a->rbi->footer;
+
+ while (NEXT_INSN (last))
+ last = NEXT_INSN (last);
+ NEXT_INSN (last) = b->rbi->footer;
+ PREV_INSN (b->rbi->footer) = last;
+ }
+ b->rbi->footer = NULL;
+ }
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Merged blocks %d and %d.\n",
+ a->index, b->index);
+
+ update_cfg_after_block_merging (a, b);
+}
+
+/* Split edge E. */
+static basic_block
+cfg_layout_split_edge (edge e)
+{
+ edge new_e;
+ basic_block new_bb =
+ create_basic_block (e->src != ENTRY_BLOCK_PTR
+ ? NEXT_INSN (BB_END (e->src)) : get_insns (),
+ NULL_RTX, e->src);
+
+ new_bb->count = e->count;
+ new_bb->frequency = EDGE_FREQUENCY (e);
+
+ new_e = make_edge (new_bb, e->dest, EDGE_FALLTHRU);
+ new_e->probability = REG_BR_PROB_BASE;
+ new_e->count = e->count;
+ redirect_edge_and_branch_force (e, new_bb);
+
+ return new_bb;
+}
+
+/* Implementation of CFG manipulation for linearized RTL. */
+struct cfg_hooks rtl_cfg_hooks = {
+ rtl_verify_flow_info,
+ rtl_dump_bb,
+ rtl_create_basic_block,
+ rtl_redirect_edge_and_branch,
+ rtl_redirect_edge_and_branch_force,
+ rtl_delete_block,
+ rtl_split_block,
+ rtl_can_merge_blocks, /* can_merge_blocks_p */
+ rtl_merge_blocks,
+ rtl_split_edge
+};
+
+/* Implementation of CFG manipulation for cfg layout RTL, where
+ basic block connected via fallthru edges does not have to be adjacent.
+ This representation will hopefully become the default one in future
+ version of the compiler. */
+struct cfg_hooks cfg_layout_rtl_cfg_hooks = {
+ rtl_verify_flow_info_1,
+ rtl_dump_bb,
+ cfg_layout_create_basic_block,
+ cfg_layout_redirect_edge_and_branch,
+ cfg_layout_redirect_edge_and_branch_force,
+ cfg_layout_delete_block,
+ cfg_layout_split_block,
+ cfg_layout_can_merge_blocks_p,
+ cfg_layout_merge_blocks,
+ cfg_layout_split_edge
+};
diff --git a/contrib/gcc/cgraph.c b/contrib/gcc/cgraph.c
new file mode 100644
index 000000000000..775f0a3fe057
--- /dev/null
+++ b/contrib/gcc/cgraph.c
@@ -0,0 +1,644 @@
+/* Callgraph handling code.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Jan Hubicka
+
+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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "langhooks.h"
+#include "hashtab.h"
+#include "toplev.h"
+#include "flags.h"
+#include "ggc.h"
+#include "debug.h"
+#include "target.h"
+#include "cgraph.h"
+#include "varray.h"
+#include "output.h"
+#include "intl.h"
+
+
+/* Hash table used to convert declarations into nodes. */
+static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
+
+/* The linked list of cgraph nodes. */
+struct cgraph_node *cgraph_nodes;
+
+/* Queue of cgraph nodes scheduled to be lowered. */
+struct cgraph_node *cgraph_nodes_queue;
+
+/* Number of nodes in existence. */
+int cgraph_n_nodes;
+
+/* Maximal uid used in cgraph nodes. */
+int cgraph_max_uid;
+
+/* Set when whole unit has been analyzed so we can access global info. */
+bool cgraph_global_info_ready = false;
+
+/* Hash table used to convert declarations into nodes. */
+static GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash;
+
+/* Queue of cgraph nodes scheduled to be lowered and output. */
+struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
+
+/* Number of nodes in existence. */
+int cgraph_varpool_n_nodes;
+
+/* The linked list of cgraph varpool nodes. */
+static GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes;
+
+static struct cgraph_edge *create_edge (struct cgraph_node *,
+ struct cgraph_node *);
+static hashval_t hash_node (const void *);
+static int eq_node (const void *, const void *);
+
+/* Returns a hash code for P. */
+
+static hashval_t
+hash_node (const void *p)
+{
+ return ((hashval_t)
+ IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
+ (((struct cgraph_node *) p)->decl)));
+}
+
+/* Returns nonzero if P1 and P2 are equal. */
+
+static int
+eq_node (const void *p1, const void *p2)
+{
+ return ((DECL_ASSEMBLER_NAME (((struct cgraph_node *) p1)->decl)) ==
+ (tree) p2);
+}
+
+/* Return cgraph node assigned to DECL. Create new one when needed. */
+struct cgraph_node *
+cgraph_node (tree decl)
+{
+ struct cgraph_node *node;
+ struct cgraph_node **slot;
+
+ if (TREE_CODE (decl) != FUNCTION_DECL)
+ abort ();
+
+ if (!cgraph_hash)
+ cgraph_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
+
+ slot = (struct cgraph_node **)
+ htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl),
+ IDENTIFIER_HASH_VALUE
+ (DECL_ASSEMBLER_NAME (decl)), INSERT);
+ if (*slot)
+ return *slot;
+ node = ggc_alloc_cleared (sizeof (*node));
+ node->decl = decl;
+ node->next = cgraph_nodes;
+ node->uid = cgraph_max_uid++;
+ if (cgraph_nodes)
+ cgraph_nodes->previous = node;
+ node->previous = NULL;
+ cgraph_nodes = node;
+ cgraph_n_nodes++;
+ *slot = node;
+ if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
+ {
+ node->origin = cgraph_node (DECL_CONTEXT (decl));
+ node->next_nested = node->origin->nested;
+ node->origin->nested = node;
+ }
+ return node;
+}
+
+/* Try to find existing function for identifier ID. */
+struct cgraph_node *
+cgraph_node_for_identifier (tree id)
+{
+ struct cgraph_node **slot;
+
+ if (TREE_CODE (id) != IDENTIFIER_NODE)
+ abort ();
+
+ if (!cgraph_hash)
+ return NULL;
+
+ slot = (struct cgraph_node **)
+ htab_find_slot_with_hash (cgraph_hash, id,
+ IDENTIFIER_HASH_VALUE (id), NO_INSERT);
+ if (!slot)
+ return NULL;
+ return *slot;
+}
+
+/* Create edge from CALLER to CALLEE in the cgraph. */
+
+static struct cgraph_edge *
+create_edge (struct cgraph_node *caller, struct cgraph_node *callee)
+{
+ struct cgraph_edge *edge = ggc_alloc (sizeof (struct cgraph_edge));
+ struct cgraph_edge *edge2;
+
+ if (!DECL_SAVED_TREE (callee->decl))
+ edge->inline_failed = N_("function body not available");
+ else if (callee->local.redefined_extern_inline)
+ edge->inline_failed = N_("redefined extern inline functions are not "
+ "considered for inlining");
+ else if (callee->local.inlinable)
+ edge->inline_failed = N_("function not considered for inlining");
+ else
+ edge->inline_failed = N_("function not inlinable");
+
+ /* At the moment we don't associate calls with specific CALL_EXPRs
+ as we probably ought to, so we must preserve inline_call flags to
+ be the same in all copies of the same edge. */
+ if (cgraph_global_info_ready)
+ for (edge2 = caller->callees; edge2; edge2 = edge2->next_callee)
+ if (edge2->callee == callee)
+ {
+ edge->inline_failed = edge2->inline_failed;
+ break;
+ }
+
+ edge->caller = caller;
+ edge->callee = callee;
+ edge->next_caller = callee->callers;
+ edge->next_callee = caller->callees;
+ caller->callees = edge;
+ callee->callers = edge;
+ return edge;
+}
+
+/* Remove the edge from CALLER to CALLEE in the cgraph. */
+
+void
+cgraph_remove_edge (struct cgraph_node *caller, struct cgraph_node *callee)
+{
+ struct cgraph_edge **edge, **edge2;
+
+ for (edge = &callee->callers; *edge && (*edge)->caller != caller;
+ edge = &((*edge)->next_caller))
+ continue;
+ if (!*edge)
+ abort ();
+ *edge = (*edge)->next_caller;
+ for (edge2 = &caller->callees; *edge2 && (*edge2)->callee != callee;
+ edge2 = &(*edge2)->next_callee)
+ continue;
+ if (!*edge2)
+ abort ();
+ *edge2 = (*edge2)->next_callee;
+}
+
+/* Remove the node from cgraph. */
+
+void
+cgraph_remove_node (struct cgraph_node *node)
+{
+ void **slot;
+ while (node->callers)
+ cgraph_remove_edge (node->callers->caller, node);
+ while (node->callees)
+ cgraph_remove_edge (node, node->callees->callee);
+ while (node->nested)
+ cgraph_remove_node (node->nested);
+ if (node->origin)
+ {
+ struct cgraph_node **node2 = &node->origin->nested;
+
+ while (*node2 != node)
+ node2 = &(*node2)->next_nested;
+ *node2 = node->next_nested;
+ }
+ if (node->previous)
+ node->previous->next = node->next;
+ else
+ cgraph_nodes = node->next;
+ if (node->next)
+ node->next->previous = node->previous;
+ DECL_SAVED_TREE (node->decl) = NULL;
+ DECL_SAVED_INSNS (node->decl) = NULL;
+ DECL_ARGUMENTS (node->decl) = NULL;
+ DECL_INITIAL (node->decl) = error_mark_node;
+ slot =
+ htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (node->decl),
+ IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
+ (node->decl)), NO_INSERT);
+ if (slot == 0)
+ {
+ /* We use DECL_ASSEMBLER_NAME as key, which may not work in
+ all cases. See PR/15666. Gcc 3.5 uses DECL_UID as key,
+ which doesn't have this problem. */
+ if (!DECL_BUILT_IN (node->decl))
+ abort ();
+ }
+ else
+ htab_clear_slot (cgraph_hash, slot);
+ /* Do not free the structure itself so the walk over chain can continue. */
+}
+
+/* Notify finalize_compilation_unit that given node is reachable. */
+
+void
+cgraph_mark_reachable_node (struct cgraph_node *node)
+{
+ if (!node->reachable && node->local.finalized)
+ {
+ notice_global_symbol (node->decl);
+ node->reachable = 1;
+
+ node->next_needed = cgraph_nodes_queue;
+ cgraph_nodes_queue = node;
+
+ /* At the moment frontend automatically emits all nested functions. */
+ if (node->nested)
+ {
+ struct cgraph_node *node2;
+
+ for (node2 = node->nested; node2; node2 = node2->next_nested)
+ if (!node2->reachable)
+ cgraph_mark_reachable_node (node2);
+ }
+ }
+}
+
+/* Likewise indicate that a node is needed, i.e. reachable via some
+ external means. */
+
+void
+cgraph_mark_needed_node (struct cgraph_node *node)
+{
+ node->needed = 1;
+ cgraph_mark_reachable_node (node);
+}
+
+/* Record call from CALLER to CALLEE. */
+
+struct cgraph_edge *
+cgraph_record_call (tree caller, tree callee)
+{
+ return create_edge (cgraph_node (caller), cgraph_node (callee));
+}
+
+void
+cgraph_remove_call (tree caller, tree callee)
+{
+ cgraph_remove_edge (cgraph_node (caller), cgraph_node (callee));
+}
+
+/* Return true when CALLER_DECL calls CALLEE_DECL. */
+
+bool
+cgraph_calls_p (tree caller_decl, tree callee_decl)
+{
+ struct cgraph_node *caller = cgraph_node (caller_decl);
+ struct cgraph_node *callee = cgraph_node (callee_decl);
+ struct cgraph_edge *edge;
+
+ for (edge = callee->callers; edge && (edge)->caller != caller;
+ edge = (edge->next_caller))
+ continue;
+ return edge != NULL;
+}
+
+/* Return local info for the compiled function. */
+
+struct cgraph_local_info *
+cgraph_local_info (tree decl)
+{
+ struct cgraph_node *node;
+ if (TREE_CODE (decl) != FUNCTION_DECL)
+ abort ();
+ node = cgraph_node (decl);
+ return &node->local;
+}
+
+/* Return local info for the compiled function. */
+
+struct cgraph_global_info *
+cgraph_global_info (tree decl)
+{
+ struct cgraph_node *node;
+ if (TREE_CODE (decl) != FUNCTION_DECL || !cgraph_global_info_ready)
+ abort ();
+ node = cgraph_node (decl);
+ return &node->global;
+}
+
+/* Return local info for the compiled function. */
+
+struct cgraph_rtl_info *
+cgraph_rtl_info (tree decl)
+{
+ struct cgraph_node *node;
+ if (TREE_CODE (decl) != FUNCTION_DECL)
+ abort ();
+ node = cgraph_node (decl);
+ if (decl != current_function_decl
+ && !TREE_ASM_WRITTEN (node->decl))
+ return NULL;
+ return &node->rtl;
+}
+
+/* Return name of the node used in debug output. */
+const char *
+cgraph_node_name (struct cgraph_node *node)
+{
+ return (*lang_hooks.decl_printable_name) (node->decl, 2);
+}
+
+/* Dump the callgraph. */
+
+void
+dump_cgraph (FILE *f)
+{
+ struct cgraph_node *node;
+
+ fprintf (f, "callgraph:\n\n");
+ for (node = cgraph_nodes; node; node = node->next)
+ {
+ struct cgraph_edge *edge;
+ fprintf (f, "%s:", cgraph_node_name (node));
+ if (node->local.self_insns)
+ fprintf (f, " %i insns", node->local.self_insns);
+ if (node->global.insns && node->global.insns != node->local.self_insns)
+ fprintf (f, " (%i after inlining)", node->global.insns);
+ if (node->origin)
+ fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
+ if (node->needed)
+ fprintf (f, " needed");
+ else if (node->reachable)
+ fprintf (f, " reachable");
+ if (DECL_SAVED_TREE (node->decl))
+ fprintf (f, " tree");
+
+ if (node->local.local)
+ fprintf (f, " local");
+ if (node->local.disregard_inline_limits)
+ fprintf (f, " always_inline");
+ else if (node->local.inlinable)
+ fprintf (f, " inlinable");
+ if (node->global.cloned_times > 1)
+ fprintf (f, " cloned %ix", node->global.cloned_times);
+
+ fprintf (f, "\n called by: ");
+ for (edge = node->callers; edge; edge = edge->next_caller)
+ {
+ fprintf (f, "%s ", cgraph_node_name (edge->caller));
+ if (!edge->inline_failed)
+ fprintf(f, "(inlined) ");
+ }
+
+ fprintf (f, "\n calls: ");
+ for (edge = node->callees; edge; edge = edge->next_callee)
+ {
+ fprintf (f, "%s ", cgraph_node_name (edge->callee));
+ if (!edge->inline_failed)
+ fprintf(f, "(inlined) ");
+ }
+ fprintf (f, "\n");
+ }
+}
+
+/* Returns a hash code for P. */
+
+static hashval_t
+cgraph_varpool_hash_node (const void *p)
+{
+ return ((hashval_t)
+ IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
+ (((struct cgraph_varpool_node *) p)->decl)));
+}
+
+/* Returns nonzero if P1 and P2 are equal. */
+
+static int
+eq_cgraph_varpool_node (const void *p1, const void *p2)
+{
+ return ((DECL_ASSEMBLER_NAME (((struct cgraph_varpool_node *) p1)->decl)) ==
+ (tree) p2);
+}
+
+/* Return cgraph_varpool node assigned to DECL. Create new one when needed. */
+struct cgraph_varpool_node *
+cgraph_varpool_node (tree decl)
+{
+ struct cgraph_varpool_node *node;
+ struct cgraph_varpool_node **slot;
+
+ if (!DECL_P (decl) || TREE_CODE (decl) == FUNCTION_DECL)
+ abort ();
+
+ if (!cgraph_varpool_hash)
+ cgraph_varpool_hash = htab_create_ggc (10, cgraph_varpool_hash_node,
+ eq_cgraph_varpool_node, NULL);
+ slot = (struct cgraph_varpool_node **)
+ htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl),
+ IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (decl)),
+ INSERT);
+ if (*slot)
+ return *slot;
+ node = ggc_alloc_cleared (sizeof (*node));
+ node->decl = decl;
+ cgraph_varpool_n_nodes++;
+ cgraph_varpool_nodes = node;
+ *slot = node;
+ return node;
+}
+
+/* Set the DECL_ASSEMBLER_NAME and update cgraph hashtables. */
+void
+change_decl_assembler_name (tree decl, tree name)
+{
+ struct cgraph_node *node = NULL;
+ struct cgraph_varpool_node *vnode = NULL;
+ void **slot;
+
+ if (!DECL_ASSEMBLER_NAME_SET_P (decl))
+ {
+ SET_DECL_ASSEMBLER_NAME (decl, name);
+ return;
+ }
+ if (name == DECL_ASSEMBLER_NAME (decl))
+ return;
+
+ if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
+ && DECL_RTL_SET_P (decl))
+ warning ("%D renamed after being referenced in assembly", decl);
+
+ if (TREE_CODE (decl) == FUNCTION_DECL && cgraph_hash)
+ {
+ /* Take a look whether declaration is in the cgraph structure. */
+ slot =
+ htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl),
+ IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
+ (decl)), NO_INSERT);
+ if (slot)
+ node = *slot;
+
+ /* It is, verify that we are the canonical node for this decl. */
+ if (node && node->decl == decl)
+ {
+ node = *slot;
+ htab_clear_slot (cgraph_hash, slot);
+ }
+ else
+ node = NULL;
+ }
+ if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) && cgraph_varpool_hash)
+ {
+ /* Take a look whether declaration is in the cgraph structure. */
+ slot =
+ htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl),
+ IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
+ (decl)), NO_INSERT);
+ if (slot)
+ vnode = *slot;
+
+ /* It is, verify that we are the canonical vnode for this decl. */
+ if (vnode && vnode->decl == decl)
+ {
+ vnode = *slot;
+ htab_clear_slot (cgraph_varpool_hash, slot);
+ }
+ else
+ vnode = NULL;
+ }
+ SET_DECL_ASSEMBLER_NAME (decl, name);
+ if (node)
+ {
+ slot =
+ htab_find_slot_with_hash (cgraph_hash, name,
+ IDENTIFIER_HASH_VALUE (name), INSERT);
+ if (*slot)
+ abort ();
+ *slot = node;
+ }
+ if (vnode)
+ {
+ slot =
+ htab_find_slot_with_hash (cgraph_varpool_hash, name,
+ IDENTIFIER_HASH_VALUE (name), INSERT);
+ if (*slot)
+ abort ();
+ *slot = vnode;
+ }
+}
+
+/* Try to find existing function for identifier ID. */
+struct cgraph_varpool_node *
+cgraph_varpool_node_for_identifier (tree id)
+{
+ struct cgraph_varpool_node **slot;
+
+ if (TREE_CODE (id) != IDENTIFIER_NODE)
+ abort ();
+
+ if (!cgraph_varpool_hash)
+ return NULL;
+
+ slot = (struct cgraph_varpool_node **)
+ htab_find_slot_with_hash (cgraph_varpool_hash, id,
+ IDENTIFIER_HASH_VALUE (id), NO_INSERT);
+ if (!slot)
+ return NULL;
+ return *slot;
+}
+
+/* Notify finalize_compilation_unit that given node is reachable
+ or needed. */
+void
+cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node)
+{
+ if (!node->needed && node->finalized)
+ {
+ node->next_needed = cgraph_varpool_nodes_queue;
+ cgraph_varpool_nodes_queue = node;
+ notice_global_symbol (node->decl);
+ }
+ node->needed = 1;
+}
+
+void
+cgraph_varpool_finalize_decl (tree decl)
+{
+ struct cgraph_varpool_node *node = cgraph_varpool_node (decl);
+
+ /* The first declaration of a variable that comes through this function
+ decides whether it is global (in C, has external linkage)
+ or local (in C, has internal linkage). So do nothing more
+ if this function has already run. */
+ if (node->finalized)
+ return;
+ if (node->needed)
+ {
+ node->next_needed = cgraph_varpool_nodes_queue;
+ cgraph_varpool_nodes_queue = node;
+ notice_global_symbol (decl);
+ }
+ node->finalized = true;
+
+ if (/* Externally visible variables must be output. The exception are
+ COMDAT functions that must be output only when they are needed. */
+ (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
+ /* Function whose name is output to the assembler file must be produced.
+ It is possible to assemble the name later after finalizing the function
+ and the fact is noticed in assemble_name then. */
+ || (DECL_ASSEMBLER_NAME_SET_P (decl)
+ && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
+ {
+ cgraph_varpool_mark_needed_node (node);
+ }
+}
+
+bool
+cgraph_varpool_assemble_pending_decls (void)
+{
+ bool changed = false;
+
+ while (cgraph_varpool_nodes_queue)
+ {
+ tree decl = cgraph_varpool_nodes_queue->decl;
+ struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue;
+
+ cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed;
+ if (!TREE_ASM_WRITTEN (decl))
+ {
+ assemble_variable (decl, 0, 1, 0);
+ changed = true;
+ }
+ node->next_needed = NULL;
+ }
+ return changed;
+}
+
+/* Return true when the DECL can possibly be inlined. */
+bool
+cgraph_function_possibly_inlined_p (tree decl)
+{
+ if (!cgraph_global_info_ready)
+ return (DECL_INLINE (decl)
+ && (!flag_really_no_inline
+ || (*lang_hooks.tree_inlining.disregard_inline_limits) (decl)));
+ return cgraph_node (decl)->global.inlined;
+}
+
+#include "gt-cgraph.h"
diff --git a/contrib/gcc/cgraph.h b/contrib/gcc/cgraph.h
new file mode 100644
index 000000000000..b845ef7b5973
--- /dev/null
+++ b/contrib/gcc/cgraph.h
@@ -0,0 +1,192 @@
+/* Callgraph handling code.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Jan Hubicka
+
+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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef GCC_CGRAPH_H
+#define GCC_CGRAPH_H
+
+/* Information about the function collected locally.
+ Available after function is analyzed. */
+
+struct cgraph_local_info GTY(())
+{
+ /* Size of the function before inlining. */
+ int self_insns;
+
+ /* Set when function function is visible in current compilation unit only
+ and it's address is never taken. */
+ bool local;
+ /* Set once it has been finalized so we consider it to be output. */
+ bool finalized;
+
+ /* False when there something makes inlining impossible (such as va_arg). */
+ bool inlinable;
+ /* True when function should be inlined independently on it's size. */
+ bool disregard_inline_limits;
+ /* True when the function has been originally extern inline, but it is
+ redefined now. */
+ bool redefined_extern_inline;
+};
+
+/* Information about the function that needs to be computed globally
+ once compilation is finished. Available only with -funit-at-time. */
+
+struct cgraph_global_info GTY(())
+{
+ /* Estimated size of the function after inlining. */
+ int insns;
+
+ /* Number of times given function will be cloned during output. */
+ int cloned_times;
+
+ /* Set when the function will be inlined exactly once. */
+ bool inline_once;
+
+ /* Set to true for all reachable functions before inlining is decided.
+ Once we inline all calls to the function and the function is local,
+ it is set to false. */
+ bool will_be_output;
+
+ /* Set iff at least one of the caller edges has inline_call flag set. */
+ bool inlined;
+};
+
+/* Information about the function that is propagated by the RTL backend.
+ Available only for functions that has been already assembled. */
+
+struct cgraph_rtl_info GTY(())
+{
+ bool const_function;
+ bool pure_function;
+ int preferred_incoming_stack_boundary;
+};
+
+
+/* The cgraph data structure.
+ Each function decl has assigned cgraph_node listing callees and callers. */
+
+struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
+{
+ tree decl;
+ struct cgraph_edge *callees;
+ struct cgraph_edge *callers;
+ struct cgraph_node *next;
+ struct cgraph_node *previous;
+ /* For nested functions points to function the node is nested in. */
+ struct cgraph_node *origin;
+ /* Points to first nested function, if any. */
+ struct cgraph_node *nested;
+ /* Pointer to the next function with same origin, if any. */
+ struct cgraph_node *next_nested;
+ /* Pointer to the next function in cgraph_nodes_queue. */
+ struct cgraph_node *next_needed;
+ PTR GTY ((skip (""))) aux;
+
+ struct cgraph_local_info local;
+ struct cgraph_global_info global;
+ struct cgraph_rtl_info rtl;
+ /* Unique id of the node. */
+ int uid;
+ /* Set when function must be output - it is externally visible
+ or it's address is taken. */
+ bool needed;
+ /* Set when function is reachable by call from other function
+ that is either reachable or needed. */
+ bool reachable;
+ /* Set once the function has been instantiated and its callee
+ lists created. */
+ bool analyzed;
+ /* Set when function is scheduled to be assembled. */
+ bool output;
+};
+
+struct cgraph_edge GTY(())
+{
+ struct cgraph_node *caller;
+ struct cgraph_node *callee;
+ struct cgraph_edge *next_caller;
+ struct cgraph_edge *next_callee;
+ /* When NULL, inline this call. When non-NULL, points to the explanation
+ why function was not inlined. */
+ const char *inline_failed;
+};
+
+/* The cgraph_varpool data structure.
+ Each static variable decl has assigned cgraph_varpool_node. */
+
+struct cgraph_varpool_node GTY(())
+{
+ tree decl;
+ /* Pointer to the next function in cgraph_varpool_nodes_queue. */
+ struct cgraph_varpool_node *next_needed;
+
+ /* Set when function must be output - it is externally visible
+ or it's address is taken. */
+ bool needed;
+ /* Set once it has been finalized so we consider it to be output. */
+ bool finalized;
+ /* Set when function is scheduled to be assembled. */
+ bool output;
+};
+
+extern GTY(()) struct cgraph_node *cgraph_nodes;
+extern GTY(()) int cgraph_n_nodes;
+extern GTY(()) int cgraph_max_uid;
+extern bool cgraph_global_info_ready;
+extern GTY(()) struct cgraph_node *cgraph_nodes_queue;
+extern FILE *cgraph_dump_file;
+
+extern GTY(()) int cgraph_varpool_n_nodes;
+extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
+
+
+/* In cgraph.c */
+void dump_cgraph (FILE *);
+void cgraph_remove_edge (struct cgraph_node *, struct cgraph_node *);
+void cgraph_remove_call (tree, tree);
+void cgraph_remove_node (struct cgraph_node *);
+struct cgraph_edge *cgraph_record_call (tree, tree);
+struct cgraph_node *cgraph_node (tree decl);
+struct cgraph_node *cgraph_node_for_identifier (tree id);
+bool cgraph_calls_p (tree, tree);
+struct cgraph_local_info *cgraph_local_info (tree);
+struct cgraph_global_info *cgraph_global_info (tree);
+struct cgraph_rtl_info *cgraph_rtl_info (tree);
+const char * cgraph_node_name (struct cgraph_node *);
+
+struct cgraph_varpool_node *cgraph_varpool_node (tree decl);
+struct cgraph_varpool_node *cgraph_varpool_node_for_identifier (tree id);
+void cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *);
+void cgraph_varpool_finalize_decl (tree);
+bool cgraph_varpool_assemble_pending_decls (void);
+
+bool cgraph_function_possibly_inlined_p (tree);
+
+/* In cgraphunit.c */
+bool cgraph_assemble_pending_functions (void);
+void cgraph_finalize_function (tree, bool);
+void cgraph_finalize_compilation_unit (void);
+void cgraph_create_edges (tree, tree);
+void cgraph_optimize (void);
+void cgraph_mark_needed_node (struct cgraph_node *);
+void cgraph_mark_reachable_node (struct cgraph_node *);
+bool cgraph_inline_p (tree, tree, const char **reason);
+
+#endif /* GCC_CGRAPH_H */
diff --git a/contrib/gcc/cgraphunit.c b/contrib/gcc/cgraphunit.c
new file mode 100644
index 000000000000..75ad3c8135e0
--- /dev/null
+++ b/contrib/gcc/cgraphunit.c
@@ -0,0 +1,1613 @@
+/* Callgraph based intraprocedural optimizations.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Jan Hubicka
+
+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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "tree-inline.h"
+#include "langhooks.h"
+#include "hashtab.h"
+#include "toplev.h"
+#include "flags.h"
+#include "ggc.h"
+#include "debug.h"
+#include "target.h"
+#include "cgraph.h"
+#include "diagnostic.h"
+#include "timevar.h"
+#include "params.h"
+#include "fibheap.h"
+#include "c-common.h"
+#include "intl.h"
+#include "function.h"
+
+#define INSNS_PER_CALL 10
+
+static void cgraph_expand_all_functions (void);
+static void cgraph_mark_functions_to_output (void);
+static void cgraph_expand_function (struct cgraph_node *);
+static tree record_call_1 (tree *, int *, void *);
+static void cgraph_mark_local_functions (void);
+static void cgraph_optimize_function (struct cgraph_node *);
+static bool cgraph_default_inline_p (struct cgraph_node *n);
+static void cgraph_analyze_function (struct cgraph_node *node);
+static void cgraph_decide_inlining_incrementally (struct cgraph_node *);
+
+/* Statistics we collect about inlining algorithm. */
+static int ncalls_inlined;
+static int nfunctions_inlined;
+static int initial_insns;
+static int overall_insns;
+
+/* Records tree nodes seen in cgraph_create_edges. Simply using
+ walk_tree_without_duplicates doesn't guarantee each node is visited
+ once because it gets a new htab upon each recursive call from
+ record_calls_1. */
+static htab_t visited_nodes;
+
+/* Determine if function DECL is needed. That is, visible to something
+ either outside this translation unit, something magic in the system
+ configury, or (if not doing unit-at-a-time) to something we havn't
+ seen yet. */
+
+static bool
+decide_is_function_needed (struct cgraph_node *node, tree decl)
+{
+ /* If we decided it was needed before, but at the time we didn't have
+ the body of the function available, then it's still needed. We have
+ to go back and re-check its dependencies now. */
+ if (node->needed)
+ return true;
+
+ /* Externally visible functions must be output. The exception is
+ COMDAT functions that must be output only when they are needed. */
+ if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
+ return true;
+
+ /* Constructors and destructors are reachable from the runtime by
+ some mechanism. */
+ if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
+ return true;
+
+ /* If the user told us it is used, then it must be so. */
+ if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
+ return true;
+
+ /* ??? If the assembler name is set by hand, it is possible to assemble
+ the name later after finalizing the function and the fact is noticed
+ in assemble_name then. This is arguably a bug. */
+ if (DECL_ASSEMBLER_NAME_SET_P (decl)
+ && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
+ return true;
+
+ if (flag_unit_at_a_time)
+ return false;
+
+ /* If not doing unit at a time, then we'll only defer this function
+ if its marked for inlining. Otherwise we want to emit it now. */
+
+ /* "extern inline" functions are never output locally. */
+ if (DECL_EXTERNAL (decl))
+ return false;
+ /* We want to emit COMDAT functions only when absolutely necessary. */
+ if (DECL_COMDAT (decl))
+ return false;
+ if (!DECL_INLINE (decl)
+ || (!node->local.disregard_inline_limits
+ /* When declared inline, defer even the uninlinable functions.
+ This allows them to be eliminated when unused. */
+ && !DECL_DECLARED_INLINE_P (decl)
+ && (!node->local.inlinable || !cgraph_default_inline_p (node))))
+ return true;
+
+ return false;
+}
+
+/* When not doing unit-at-a-time, output all functions enqueued.
+ Return true when such a functions were found. */
+
+bool
+cgraph_assemble_pending_functions (void)
+{
+ bool output = false;
+
+ if (flag_unit_at_a_time)
+ return false;
+
+ while (cgraph_nodes_queue)
+ {
+ struct cgraph_node *n = cgraph_nodes_queue;
+
+ cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
+ if (!n->origin && !DECL_EXTERNAL (n->decl))
+ {
+ cgraph_expand_function (n);
+ output = true;
+ }
+ }
+
+ return output;
+}
+
+/* DECL has been parsed. Take it, queue it, compile it at the whim of the
+ logic in effect. If NESTED is true, then our caller cannot stand to have
+ the garbage collector run at the moment. We would need to either create
+ a new GC context, or just not compile right now. */
+
+void
+cgraph_finalize_function (tree decl, bool nested)
+{
+ struct cgraph_node *node = cgraph_node (decl);
+
+ if (node->local.finalized)
+ {
+ /* As an GCC extension we allow redefinition of the function. The
+ semantics when both copies of bodies differ is not well defined.
+ We replace the old body with new body so in unit at a time mode
+ we always use new body, while in normal mode we may end up with
+ old body inlined into some functions and new body expanded and
+ inlined in others.
+
+ ??? It may make more sense to use one body for inlining and other
+ body for expanding the function but this is difficult to do. */
+
+ /* If node->output is set, then this is a unit-at-a-time compilation
+ and we have already begun whole-unit analysis. This is *not*
+ testing for whether we've already emitted the function. That
+ case can be sort-of legitimately seen with real function
+ redefinition errors. I would argue that the front end should
+ never present us with such a case, but don't enforce that for now. */
+ if (node->output)
+ abort ();
+
+ /* Reset our datastructures so we can analyze the function again. */
+ memset (&node->local, 0, sizeof (node->local));
+ memset (&node->global, 0, sizeof (node->global));
+ memset (&node->rtl, 0, sizeof (node->rtl));
+ node->analyzed = false;
+ node->local.redefined_extern_inline = true;
+ while (node->callees)
+ cgraph_remove_edge (node, node->callees->callee);
+
+ /* We may need to re-queue the node for assembling in case
+ we already proceeded it and ignored as not needed. */
+ if (node->reachable && !flag_unit_at_a_time)
+ {
+ struct cgraph_node *n;
+
+ for (n = cgraph_nodes_queue; n; n = n->next_needed)
+ if (n == node)
+ break;
+ if (!n)
+ node->reachable = 0;
+ }
+ }
+
+ notice_global_symbol (decl);
+ node->decl = decl;
+ node->local.finalized = true;
+
+ /* If not unit at a time, then we need to create the call graph
+ now, so that called functions can be queued and emitted now. */
+ if (!flag_unit_at_a_time)
+ {
+ cgraph_analyze_function (node);
+ cgraph_decide_inlining_incrementally (node);
+ }
+
+ if (decide_is_function_needed (node, decl))
+ cgraph_mark_needed_node (node);
+
+ /* If not unit at a time, go ahead and emit everything we've found
+ to be reachable at this time. */
+ if (!nested)
+ {
+ if (!cgraph_assemble_pending_functions ())
+ ggc_collect ();
+ }
+
+ /* If we've not yet emitted decl, tell the debug info about it. */
+ if (!TREE_ASM_WRITTEN (decl))
+ (*debug_hooks->deferred_inline_function) (decl);
+
+ /* We will never really output the function body, clear the SAVED_INSNS array
+ early then. */
+ if (DECL_EXTERNAL (decl))
+ DECL_SAVED_INSNS (decl) = NULL;
+}
+
+/* Walk tree and record all calls. Called via walk_tree. */
+static tree
+record_call_1 (tree *tp, int *walk_subtrees, void *data)
+{
+ tree t = *tp;
+
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ /* ??? Really, we should mark this decl as *potentially* referenced
+ by this function and re-examine whether the decl is actually used
+ after rtl has been generated. */
+ if (TREE_STATIC (t))
+ cgraph_varpool_mark_needed_node (cgraph_varpool_node (t));
+ break;
+
+ case ADDR_EXPR:
+ if (flag_unit_at_a_time)
+ {
+ /* Record dereferences to the functions. This makes the
+ functions reachable unconditionally. */
+ tree decl = TREE_OPERAND (*tp, 0);
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ cgraph_mark_needed_node (cgraph_node (decl));
+ }
+ break;
+
+ case CALL_EXPR:
+ {
+ tree decl = get_callee_fndecl (*tp);
+ if (decl && TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ cgraph_record_call (data, decl);
+
+ /* When we see a function call, we don't want to look at the
+ function reference in the ADDR_EXPR that is hanging from
+ the CALL_EXPR we're examining here, because we would
+ conclude incorrectly that the function's address could be
+ taken by something that is not a function call. So only
+ walk the function parameter list, skip the other subtrees. */
+
+ walk_tree (&TREE_OPERAND (*tp, 1), record_call_1, data,
+ visited_nodes);
+ *walk_subtrees = 0;
+ }
+ break;
+ }
+
+ default:
+ /* Save some cycles by not walking types and declaration as we
+ won't find anything useful there anyway. */
+ if (DECL_P (*tp) || TYPE_P (*tp))
+ {
+ *walk_subtrees = 0;
+ break;
+ }
+
+ if ((unsigned int) TREE_CODE (t) >= LAST_AND_UNUSED_TREE_CODE)
+ return (*lang_hooks.callgraph.analyze_expr) (tp, walk_subtrees, data);
+ break;
+ }
+
+ return NULL;
+}
+
+/* Create cgraph edges for function calls inside BODY from DECL. */
+
+void
+cgraph_create_edges (tree decl, tree body)
+{
+ /* The nodes we're interested in are never shared, so walk
+ the tree ignoring duplicates. */
+ visited_nodes = htab_create (37, htab_hash_pointer,
+ htab_eq_pointer, NULL);
+ walk_tree (&body, record_call_1, decl, visited_nodes);
+ htab_delete (visited_nodes);
+ visited_nodes = NULL;
+}
+
+/* Analyze the function scheduled to be output. */
+static void
+cgraph_analyze_function (struct cgraph_node *node)
+{
+ tree decl = node->decl;
+ struct cgraph_edge *e;
+
+ current_function_decl = decl;
+
+ /* First kill forward declaration so reverse inlining works properly. */
+ cgraph_create_edges (decl, DECL_SAVED_TREE (decl));
+
+ node->local.inlinable = tree_inlinable_function_p (decl);
+ if (!node->local.self_insns)
+ node->local.self_insns
+ = (*lang_hooks.tree_inlining.estimate_num_insns) (decl);
+ if (node->local.inlinable)
+ node->local.disregard_inline_limits
+ = (*lang_hooks.tree_inlining.disregard_inline_limits) (decl);
+ for (e = node->callers; e; e = e->next_caller)
+ if (e->inline_failed)
+ {
+ if (node->local.redefined_extern_inline)
+ e->inline_failed = N_("redefined extern inline functions are not "
+ "considered for inlining");
+ else if (!node->local.inlinable)
+ e->inline_failed = N_("function not inlinable");
+ else
+ e->inline_failed = N_("function not considered for inlining");
+ }
+ if (flag_really_no_inline && !node->local.disregard_inline_limits)
+ node->local.inlinable = 0;
+ /* Inlining characteristics are maintained by the cgraph_mark_inline. */
+ node->global.insns = node->local.self_insns;
+ if (!DECL_EXTERNAL (decl))
+ {
+ node->global.cloned_times = 1;
+ node->global.will_be_output = true;
+ }
+
+ node->analyzed = true;
+ current_function_decl = NULL;
+
+ /* Possibly warn about unused parameters. */
+ if (warn_unused_parameter)
+ do_warn_unused_parameter (decl);
+}
+
+/* Analyze the whole compilation unit once it is parsed completely. */
+
+void
+cgraph_finalize_compilation_unit (void)
+{
+ struct cgraph_node *node;
+
+ if (!flag_unit_at_a_time)
+ {
+ cgraph_assemble_pending_functions ();
+ return;
+ }
+
+ cgraph_varpool_assemble_pending_decls ();
+ if (!quiet_flag)
+ fprintf (stderr, "\nAnalyzing compilation unit\n");
+
+ timevar_push (TV_CGRAPH);
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, "Initial entry points:");
+ for (node = cgraph_nodes; node; node = node->next)
+ if (node->needed && DECL_SAVED_TREE (node->decl))
+ fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
+ fprintf (cgraph_dump_file, "\n");
+ }
+
+ /* Propagate reachability flag and lower representation of all reachable
+ functions. In the future, lowering will introduce new functions and
+ new entry points on the way (by template instantiation and virtual
+ method table generation for instance). */
+ while (cgraph_nodes_queue)
+ {
+ struct cgraph_edge *edge;
+ tree decl = cgraph_nodes_queue->decl;
+
+ node = cgraph_nodes_queue;
+ cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
+
+ /* ??? It is possible to create extern inline function and later using
+ weak alas attribute to kill it's body. See
+ gcc.c-torture/compile/20011119-1.c */
+ if (!DECL_SAVED_TREE (decl))
+ continue;
+
+ if (node->analyzed || !node->reachable || !DECL_SAVED_TREE (decl))
+ abort ();
+
+ cgraph_analyze_function (node);
+
+ for (edge = node->callees; edge; edge = edge->next_callee)
+ if (!edge->callee->reachable)
+ cgraph_mark_reachable_node (edge->callee);
+
+ cgraph_varpool_assemble_pending_decls ();
+ }
+
+ /* Collect entry points to the unit. */
+
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, "Unit entry points:");
+ for (node = cgraph_nodes; node; node = node->next)
+ if (node->needed && DECL_SAVED_TREE (node->decl))
+ fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
+ fprintf (cgraph_dump_file, "\n\nInitial ");
+ dump_cgraph (cgraph_dump_file);
+ }
+
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, "\nReclaiming functions:");
+
+ for (node = cgraph_nodes; node; node = node->next)
+ {
+ tree decl = node->decl;
+
+ if (!node->reachable && DECL_SAVED_TREE (decl))
+ {
+ cgraph_remove_node (node);
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
+ }
+ else
+ node->next_needed = NULL;
+ }
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, "\n\nReclaimed ");
+ dump_cgraph (cgraph_dump_file);
+ }
+ ggc_collect ();
+ timevar_pop (TV_CGRAPH);
+}
+
+/* Figure out what functions we want to assemble. */
+
+static void
+cgraph_mark_functions_to_output (void)
+{
+ struct cgraph_node *node;
+
+ for (node = cgraph_nodes; node; node = node->next)
+ {
+ tree decl = node->decl;
+ struct cgraph_edge *e;
+
+ if (node->output)
+ abort ();
+
+ for (e = node->callers; e; e = e->next_caller)
+ if (e->inline_failed)
+ break;
+
+ /* We need to output all local functions that are used and not
+ always inlined, as well as those that are reachable from
+ outside the current compilation unit. */
+ if (DECL_SAVED_TREE (decl)
+ && (node->needed
+ || (e && node->reachable))
+ && !TREE_ASM_WRITTEN (decl) && !node->origin
+ && !DECL_EXTERNAL (decl))
+ node->output = 1;
+ else
+ DECL_SAVED_INSNS (decl) = NULL;
+ }
+}
+
+/* Optimize the function before expansion. */
+
+static void
+cgraph_optimize_function (struct cgraph_node *node)
+{
+ tree decl = node->decl;
+
+ timevar_push (TV_INTEGRATION);
+ /* optimize_inline_calls avoids inlining of current_function_decl. */
+ current_function_decl = decl;
+ if (flag_inline_trees)
+ {
+ struct cgraph_edge *e;
+
+ for (e = node->callees; e; e = e->next_callee)
+ if (!e->inline_failed || warn_inline
+ || (DECL_DECLARED_INLINE_P (e->callee->decl)
+ && lookup_attribute ("always_inline",
+ DECL_ATTRIBUTES (e->callee->decl))))
+ break;
+ if (e)
+ optimize_inline_calls (decl);
+ }
+ if (node->nested)
+ {
+ for (node = node->nested; node; node = node->next_nested)
+ cgraph_optimize_function (node);
+ }
+ timevar_pop (TV_INTEGRATION);
+}
+
+/* Expand function specified by NODE. */
+
+static void
+cgraph_expand_function (struct cgraph_node *node)
+{
+ tree decl = node->decl;
+
+ if (flag_unit_at_a_time)
+ announce_function (decl);
+
+ cgraph_optimize_function (node);
+
+ /* Generate RTL for the body of DECL. Nested functions are expanded
+ via lang_expand_decl_stmt. */
+ (*lang_hooks.callgraph.expand_function) (decl);
+ if (DECL_DEFER_OUTPUT (decl))
+ abort ();
+
+ current_function_decl = NULL;
+}
+
+/* Fill array order with all nodes with output flag set in the reverse
+ topological order. */
+
+static int
+cgraph_postorder (struct cgraph_node **order)
+{
+ struct cgraph_node *node, *node2;
+ int stack_size = 0;
+ int order_pos = 0;
+ struct cgraph_edge *edge, last;
+
+ struct cgraph_node **stack =
+ xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
+
+ /* We have to deal with cycles nicely, so use a depth first traversal
+ output algorithm. Ignore the fact that some functions won't need
+ to be output and put them into order as well, so we get dependencies
+ right through intline functions. */
+ for (node = cgraph_nodes; node; node = node->next)
+ node->aux = NULL;
+ for (node = cgraph_nodes; node; node = node->next)
+ if (!node->aux)
+ {
+ node2 = node;
+ if (!node->callers)
+ node->aux = &last;
+ else
+ node->aux = node->callers;
+ while (node2)
+ {
+ while (node2->aux != &last)
+ {
+ edge = node2->aux;
+ if (edge->next_caller)
+ node2->aux = edge->next_caller;
+ else
+ node2->aux = &last;
+ if (!edge->caller->aux)
+ {
+ if (!edge->caller->callers)
+ edge->caller->aux = &last;
+ else
+ edge->caller->aux = edge->caller->callers;
+ stack[stack_size++] = node2;
+ node2 = edge->caller;
+ break;
+ }
+ }
+ if (node2->aux == &last)
+ {
+ order[order_pos++] = node2;
+ if (stack_size)
+ node2 = stack[--stack_size];
+ else
+ node2 = NULL;
+ }
+ }
+ }
+ free (stack);
+ return order_pos;
+}
+
+#define INLINED_TIMES(node) ((size_t)(node)->aux)
+#define SET_INLINED_TIMES(node,times) ((node)->aux = (void *)(times))
+
+/* Return list of nodes we decided to inline NODE into, set their output
+ flag and compute INLINED_TIMES.
+
+ We do simple backtracing to get INLINED_TIMES right. This should not be
+ expensive as we limit the amount of inlining. Alternatively we may first
+ discover set of nodes, topologically sort these and propagate
+ INLINED_TIMES */
+
+static int
+cgraph_inlined_into (struct cgraph_node *node, struct cgraph_node **array)
+{
+ int nfound = 0;
+ struct cgraph_edge **stack;
+ struct cgraph_edge *e, *e1;
+ int sp;
+ int i;
+
+ /* Fast path: since we traverse in mostly topological order, we will likely
+ find no edges. */
+ for (e = node->callers; e; e = e->next_caller)
+ if (!e->inline_failed)
+ break;
+
+ if (!e)
+ return 0;
+
+ /* Allocate stack for back-tracking up callgraph. */
+ stack = xmalloc ((cgraph_n_nodes + 1) * sizeof (struct cgraph_edge));
+ sp = 0;
+
+ /* Push the first edge on to the stack. */
+ stack[sp++] = e;
+
+ while (sp)
+ {
+ struct cgraph_node *caller;
+
+ /* Look at the edge on the top of the stack. */
+ e = stack[sp - 1];
+ caller = e->caller;
+
+ /* Check if the caller destination has been visited yet. */
+ if (!caller->output)
+ {
+ array[nfound++] = e->caller;
+ /* Mark that we have visited the destination. */
+ caller->output = true;
+ SET_INLINED_TIMES (caller, 0);
+ }
+ SET_INLINED_TIMES (caller, INLINED_TIMES (caller) + 1);
+
+ for (e1 = caller->callers; e1; e1 = e1->next_caller)
+ if (!e1->inline_failed)
+ break;
+
+ if (e1)
+ stack[sp++] = e1;
+ else
+ {
+ while (true)
+ {
+ for (e1 = e->next_caller; e1; e1 = e1->next_caller)
+ if (!e1->inline_failed)
+ break;
+
+ if (e1)
+ {
+ stack[sp - 1] = e1;
+ break;
+ }
+ else
+ {
+ sp--;
+ if (!sp)
+ break;
+ e = stack[sp - 1];
+ }
+ }
+ }
+ }
+
+ free (stack);
+
+
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, " Found inline predecesors of %s:",
+ cgraph_node_name (node));
+ for (i = 0; i < nfound; i++)
+ {
+ fprintf (cgraph_dump_file, " %s", cgraph_node_name (array[i]));
+ if (INLINED_TIMES (array[i]) != 1)
+ fprintf (cgraph_dump_file, " (%i times)",
+ (int)INLINED_TIMES (array[i]));
+ }
+ fprintf (cgraph_dump_file, "\n");
+ }
+
+ return nfound;
+}
+
+/* Return list of nodes we decided to inline into NODE, set their output
+ flag and compute INLINED_TIMES.
+
+ This function is identical to cgraph_inlined_into with callers and callees
+ nodes swapped. */
+
+static int
+cgraph_inlined_callees (struct cgraph_node *node, struct cgraph_node **array)
+{
+ int nfound = 0;
+ struct cgraph_edge **stack;
+ struct cgraph_edge *e, *e1;
+ int sp;
+ int i;
+
+ /* Fast path: since we traverse in mostly topological order, we will likely
+ find no edges. */
+ for (e = node->callees; e; e = e->next_callee)
+ if (!e->inline_failed)
+ break;
+
+ if (!e)
+ return 0;
+
+ /* Allocate stack for back-tracking up callgraph. */
+ stack = xmalloc ((cgraph_n_nodes + 1) * sizeof (struct cgraph_edge));
+ sp = 0;
+
+ /* Push the first edge on to the stack. */
+ stack[sp++] = e;
+
+ while (sp)
+ {
+ struct cgraph_node *callee;
+
+ /* Look at the edge on the top of the stack. */
+ e = stack[sp - 1];
+ callee = e->callee;
+
+ /* Check if the callee destination has been visited yet. */
+ if (!callee->output)
+ {
+ array[nfound++] = e->callee;
+ /* Mark that we have visited the destination. */
+ callee->output = true;
+ SET_INLINED_TIMES (callee, 0);
+ }
+ SET_INLINED_TIMES (callee, INLINED_TIMES (callee) + 1);
+
+ for (e1 = callee->callees; e1; e1 = e1->next_callee)
+ if (!e1->inline_failed)
+ break;
+ if (e1)
+ stack[sp++] = e1;
+ else
+ {
+ while (true)
+ {
+ for (e1 = e->next_callee; e1; e1 = e1->next_callee)
+ if (!e1->inline_failed)
+ break;
+
+ if (e1)
+ {
+ stack[sp - 1] = e1;
+ break;
+ }
+ else
+ {
+ sp--;
+ if (!sp)
+ break;
+ e = stack[sp - 1];
+ }
+ }
+ }
+ }
+
+ free (stack);
+
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, " Found inline successors of %s:",
+ cgraph_node_name (node));
+ for (i = 0; i < nfound; i++)
+ {
+ fprintf (cgraph_dump_file, " %s", cgraph_node_name (array[i]));
+ if (INLINED_TIMES (array[i]) != 1)
+ fprintf (cgraph_dump_file, " (%i times)",
+ (int)INLINED_TIMES (array[i]));
+ }
+ fprintf (cgraph_dump_file, "\n");
+ }
+
+ return nfound;
+}
+
+/* Perform reachability analysis and reclaim all unreachable nodes.
+ This function also remove unneeded bodies of extern inline functions
+ and thus needs to be done only after inlining decisions has been made. */
+static bool
+cgraph_remove_unreachable_nodes (void)
+{
+ struct cgraph_node *first = (void *) 1;
+ struct cgraph_node *node;
+ bool changed = false;
+ int insns = 0;
+
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, "\nReclaiming functions:");
+#ifdef ENABLE_CHECKING
+ for (node = cgraph_nodes; node; node = node->next)
+ if (node->aux)
+ abort ();
+#endif
+ for (node = cgraph_nodes; node; node = node->next)
+ if (node->needed && (!DECL_EXTERNAL (node->decl) || !node->analyzed))
+ {
+ node->aux = first;
+ first = node;
+ }
+ else if (node->aux)
+ abort ();
+
+ /* Perform reachability analysis. As a special case do not consider
+ extern inline functions not inlined as live because we won't output
+ them at all. */
+ while (first != (void *) 1)
+ {
+ struct cgraph_edge *e;
+ node = first;
+ first = first->aux;
+
+ for (e = node->callees; e; e = e->next_callee)
+ if (!e->callee->aux
+ && node->analyzed
+ && (!e->inline_failed || !e->callee->analyzed
+ || !DECL_EXTERNAL (e->callee->decl)))
+ {
+ e->callee->aux = first;
+ first = e->callee;
+ }
+ }
+
+ /* Remove unreachable nodes. Extern inline functions need special care;
+ Unreachable extern inline functions shall be removed.
+ Reachable extern inline functions we never inlined shall get their bodies
+ elliminated
+ Reachable extern inline functions we sometimes inlined will be turned into
+ unanalyzed nodes so they look like for true extern functions to the rest
+ of code. */
+ for (node = cgraph_nodes; node; node = node->next)
+ {
+ if (!node->aux)
+ {
+ int local_insns;
+ tree decl = node->decl;
+
+ if (DECL_SAVED_INSNS (decl))
+ local_insns = node->local.self_insns;
+ else
+ local_insns = 0;
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
+ if (!node->analyzed || !DECL_EXTERNAL (node->decl))
+ cgraph_remove_node (node);
+ else
+ {
+ struct cgraph_edge *e;
+
+ for (e = node->callers; e; e = e->next_caller)
+ if (e->caller->aux)
+ break;
+ if (e || node->needed)
+ {
+ DECL_SAVED_TREE (node->decl) = NULL_TREE;
+ while (node->callees)
+ cgraph_remove_edge (node, node->callees->callee);
+ node->analyzed = false;
+ }
+ else
+ cgraph_remove_node (node);
+ }
+ if (!DECL_SAVED_TREE (decl))
+ insns += local_insns;
+ changed = true;
+ }
+ }
+ for (node = cgraph_nodes; node; node = node->next)
+ node->aux = NULL;
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, "\nReclaimed %i insns", insns);
+ return changed;
+}
+
+
+/* Estimate size 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)
+{
+ return (what->global.insns - INSNS_PER_CALL) * times + to->global.insns;
+}
+
+/* Estimate the growth caused by inlining NODE into all callees. */
+
+static int
+cgraph_estimate_growth (struct cgraph_node *node)
+{
+ int growth = 0;
+ int calls_saved = 0;
+ int clones_added = 0;
+ struct cgraph_edge *e;
+
+ for (e = node->callers; e; e = e->next_caller)
+ if (e->inline_failed)
+ {
+ growth += ((cgraph_estimate_size_after_inlining (1, e->caller, node)
+ -
+ e->caller->global.insns) *e->caller->global.cloned_times);
+ calls_saved += e->caller->global.cloned_times;
+ clones_added += e->caller->global.cloned_times;
+ }
+
+ /* ??? Wrong for self recursive functions or cases where we decide to not
+ inline for different reasons, but it is not big deal as in that case
+ we will keep the body around, but we will also avoid some inlining. */
+ if (!node->needed && !node->origin && !DECL_EXTERNAL (node->decl))
+ growth -= node->global.insns, clones_added--;
+
+ if (!calls_saved)
+ calls_saved = 1;
+
+ return growth;
+}
+
+/* Update insn sizes after inlining WHAT into TO that is already inlined into
+ all nodes in INLINED array. */
+
+static void
+cgraph_mark_inline (struct cgraph_node *to, struct cgraph_node *what,
+ struct cgraph_node **inlined, int ninlined,
+ struct cgraph_node **inlined_callees,
+ int ninlined_callees)
+{
+ int i;
+ int times = 0;
+ int clones = 0;
+ struct cgraph_edge *e;
+ bool called = false;
+ int new_insns;
+
+ what->global.inlined = 1;
+ for (e = what->callers; e; e = e->next_caller)
+ {
+ if (e->caller == to)
+ {
+ if (!e->inline_failed)
+ continue;
+ e->inline_failed = NULL;
+ times++;
+ clones += e->caller->global.cloned_times;
+ }
+ else if (e->inline_failed)
+ called = true;
+ }
+ if (!times)
+ abort ();
+ ncalls_inlined += times;
+
+ new_insns = cgraph_estimate_size_after_inlining (times, to, what);
+ if (to->global.will_be_output)
+ overall_insns += new_insns - to->global.insns;
+ to->global.insns = new_insns;
+
+ if (!called && !what->needed && !what->origin
+ && flag_unit_at_a_time
+ && !DECL_EXTERNAL (what->decl))
+ {
+ if (!what->global.will_be_output)
+ abort ();
+ clones--;
+ nfunctions_inlined++;
+ what->global.will_be_output = 0;
+ overall_insns -= what->global.insns;
+ }
+ what->global.cloned_times += clones;
+ for (i = 0; i < ninlined; i++)
+ {
+ new_insns =
+ cgraph_estimate_size_after_inlining (INLINED_TIMES (inlined[i]) *
+ times, inlined[i], what);
+ if (inlined[i]->global.will_be_output)
+ overall_insns += new_insns - inlined[i]->global.insns;
+ inlined[i]->global.insns = new_insns;
+ }
+ for (i = 0; i < ninlined_callees; i++)
+ {
+ inlined_callees[i]->global.cloned_times +=
+ INLINED_TIMES (inlined_callees[i]) * clones;
+ }
+}
+
+/* Return false when inlining WHAT into TO is not good idea as it would cause
+ too large growth of function bodies. */
+
+static bool
+cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
+ struct cgraph_node **inlined, int ninlined,
+ const char **reason)
+{
+ int i;
+ int times = 0;
+ struct cgraph_edge *e;
+ int newsize;
+ int limit;
+
+ for (e = to->callees; e; e = e->next_callee)
+ if (e->callee == what)
+ times++;
+
+ /* When inlining large function body called once into small function,
+ take the inlined function as base for limiting the growth. */
+ if (to->local.self_insns > what->local.self_insns)
+ limit = to->local.self_insns;
+ else
+ limit = what->local.self_insns;
+
+ limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
+
+ newsize = cgraph_estimate_size_after_inlining (times, to, what);
+ if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
+ && newsize > limit)
+ {
+ *reason = N_("--param large-function-growth limit reached");
+ return false;
+ }
+ for (i = 0; i < ninlined; i++)
+ {
+ newsize =
+ cgraph_estimate_size_after_inlining (INLINED_TIMES (inlined[i]) *
+ times, inlined[i], what);
+ if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
+ && newsize >
+ inlined[i]->local.self_insns *
+ (100 + PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH)) / 100)
+ {
+ *reason = N_("--param large-function-growth limit reached while inlining the caller");
+ return false;
+ }
+ }
+ return true;
+}
+
+/* Return true when function N is small enough to be inlined. */
+
+static bool
+cgraph_default_inline_p (struct cgraph_node *n)
+{
+ if (!DECL_INLINE (n->decl) || !DECL_SAVED_TREE (n->decl))
+ return false;
+ if (DECL_DECLARED_INLINE_P (n->decl))
+ return n->global.insns < MAX_INLINE_INSNS_SINGLE;
+ else
+ return n->global.insns < MAX_INLINE_INSNS_AUTO;
+}
+
+/* Set inline_failed for all callers of given function to REASON. */
+
+static void
+cgraph_set_inline_failed (struct cgraph_node *node, const char *reason)
+{
+ struct cgraph_edge *e;
+
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, "Inlining failed: %s\n", reason);
+ for (e = node->callers; e; e = e->next_caller)
+ if (e->inline_failed)
+ e->inline_failed = reason;
+}
+
+/* We use greedy algorithm for inlining of small functions:
+ All inline candidates are put into prioritized heap based on estimated
+ growth of the overall number of instructions and then update the estimates.
+
+ INLINED and INLINED_CALEES are just pointers to arrays large enough
+ to be passed to cgraph_inlined_into and cgraph_inlined_callees. */
+
+static void
+cgraph_decide_inlining_of_small_functions (struct cgraph_node **inlined,
+ struct cgraph_node **inlined_callees)
+{
+ int i;
+ struct cgraph_node *node;
+ fibheap_t heap = fibheap_new ();
+ struct fibnode **heap_node =
+ xcalloc (cgraph_max_uid, sizeof (struct fibnode *));
+ int ninlined, ninlined_callees;
+ int max_insns = ((HOST_WIDEST_INT) initial_insns
+ * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);
+
+ /* Put all inline candidates into the heap. */
+
+ for (node = cgraph_nodes; node; node = node->next)
+ {
+ if (!node->local.inlinable || !node->callers
+ || node->local.disregard_inline_limits)
+ continue;
+
+ if (!cgraph_default_inline_p (node))
+ {
+ cgraph_set_inline_failed (node,
+ N_("--param max-inline-insns-single limit reached"));
+ continue;
+ }
+ heap_node[node->uid] =
+ fibheap_insert (heap, cgraph_estimate_growth (node), node);
+ }
+
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, "\nDeciding on smaller functions:\n");
+ while (overall_insns <= max_insns && (node = fibheap_extract_min (heap)))
+ {
+ struct cgraph_edge *e;
+ int old_insns = overall_insns;
+
+ heap_node[node->uid] = NULL;
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "\nConsidering %s with %i insns\n"
+ " Estimated growth is %+i insns.\n",
+ cgraph_node_name (node), node->global.insns,
+ cgraph_estimate_growth (node));
+ if (!cgraph_default_inline_p (node))
+ {
+ cgraph_set_inline_failed (node,
+ N_("--param max-inline-insns-single limit reached after inlining into the callee"));
+ continue;
+ }
+ ninlined_callees = cgraph_inlined_callees (node, inlined_callees);
+ for (e = node->callers; e; e = e->next_caller)
+ if (e->inline_failed)
+ {
+ /* Marking recursive function inlinine has sane semantic and
+ thus we should not warn on it. */
+ if (e->caller == node)
+ {
+ e->inline_failed = "";
+ continue;
+ }
+ ninlined = cgraph_inlined_into (e->caller, inlined);
+ if (e->callee->output)
+ e->inline_failed = "";
+ if (e->callee->output
+ || !cgraph_check_inline_limits (e->caller, node, inlined,
+ ninlined, &e->inline_failed))
+ {
+ for (i = 0; i < ninlined; i++)
+ inlined[i]->output = 0, inlined[i]->aux = 0;
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, " Not inlining into %s.\n",
+ cgraph_node_name (e->caller));
+ continue;
+ }
+ cgraph_mark_inline (e->caller, node, inlined, ninlined,
+ inlined_callees, ninlined_callees);
+ if (heap_node[e->caller->uid])
+ fibheap_replace_key (heap, heap_node[e->caller->uid],
+ cgraph_estimate_growth (e->caller));
+
+ /* Size of the functions we updated into has changed, so update
+ the keys. */
+ for (i = 0; i < ninlined; i++)
+ {
+ inlined[i]->output = 0, inlined[i]->aux = 0;
+ if (heap_node[inlined[i]->uid])
+ fibheap_replace_key (heap, heap_node[inlined[i]->uid],
+ cgraph_estimate_growth (inlined[i]));
+ }
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ " Inlined into %s which now has %i insns.\n",
+ cgraph_node_name (e->caller),
+ e->caller->global.insns);
+ }
+
+ /* Similarly all functions called by the function we just inlined
+ are now called more times; update keys. */
+
+ for (e = node->callees; e; e = e->next_callee)
+ if (e->inline_failed && heap_node[e->callee->uid])
+ fibheap_replace_key (heap, heap_node[e->callee->uid],
+ cgraph_estimate_growth (e->callee));
+
+ for (i = 0; i < ninlined_callees; i++)
+ {
+ struct cgraph_edge *e;
+
+ for (e = inlined_callees[i]->callees; e; e = e->next_callee)
+ if (e->inline_failed && heap_node[e->callee->uid])
+ fibheap_replace_key (heap, heap_node[e->callee->uid],
+ cgraph_estimate_growth (e->callee));
+
+ inlined_callees[i]->output = 0;
+ inlined_callees[i]->aux = 0;
+ }
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ " Inlined %i times for a net change of %+i insns.\n",
+ node->global.cloned_times, overall_insns - old_insns);
+ }
+ while ((node = fibheap_extract_min (heap)) != NULL)
+ if (!node->local.disregard_inline_limits)
+ cgraph_set_inline_failed (node, N_("--param inline-unit-growth limit reached"));
+ fibheap_delete (heap);
+ free (heap_node);
+}
+
+/* Decide on the inlining. We do so in the topological order to avoid
+ expenses on updating datastructures. */
+
+static void
+cgraph_decide_inlining (void)
+{
+ struct cgraph_node *node;
+ int nnodes;
+ struct cgraph_node **order =
+ xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
+ struct cgraph_node **inlined =
+ xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
+ struct cgraph_node **inlined_callees =
+ xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
+ int ninlined;
+ int ninlined_callees;
+ int old_insns = 0;
+ int i, y;
+
+ for (node = cgraph_nodes; node; node = node->next)
+ initial_insns += node->local.self_insns;
+ overall_insns = initial_insns;
+
+ nnodes = cgraph_postorder (order);
+
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "\nDeciding on inlining. Starting with %i insns.\n",
+ initial_insns);
+
+ for (node = cgraph_nodes; node; node = node->next)
+ node->aux = 0;
+
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, "\nInlining always_inline functions:\n");
+#ifdef ENABLE_CHECKING
+ for (node = cgraph_nodes; node; node = node->next)
+ if (node->aux || node->output)
+ abort ();
+#endif
+
+ /* In the first pass mark all always_inline edges. Do this with a priority
+ so none of our later choices will make this impossible. */
+ for (i = nnodes - 1; i >= 0; i--)
+ {
+ struct cgraph_edge *e;
+
+ node = order[i];
+
+ for (e = node->callees; e; e = e->next_callee)
+ if (e->callee->local.disregard_inline_limits)
+ break;
+ if (!e)
+ continue;
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "\nConsidering %s %i insns (always inline)\n",
+ cgraph_node_name (e->callee), e->callee->global.insns);
+ ninlined = cgraph_inlined_into (order[i], inlined);
+ for (; e; e = e->next_callee)
+ {
+ old_insns = overall_insns;
+ if (!e->inline_failed || !e->callee->local.inlinable
+ || !e->callee->local.disregard_inline_limits)
+ continue;
+ if (e->callee->output || e->callee == node)
+ {
+ e->inline_failed = N_("recursive inlining");
+ continue;
+ }
+ ninlined_callees =
+ cgraph_inlined_callees (e->callee, inlined_callees);
+ cgraph_mark_inline (node, e->callee, inlined, ninlined,
+ inlined_callees, ninlined_callees);
+ for (y = 0; y < ninlined_callees; y++)
+ inlined_callees[y]->output = 0, inlined_callees[y]->aux = 0;
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ " Inlined into %s which now has %i insns.\n",
+ cgraph_node_name (node->callees->caller),
+ node->callees->caller->global.insns);
+ }
+ if (cgraph_dump_file && node->global.cloned_times > 0)
+ fprintf (cgraph_dump_file,
+ " Inlined %i times for a net change of %+i insns.\n",
+ node->global.cloned_times, overall_insns - old_insns);
+ for (y = 0; y < ninlined; y++)
+ inlined[y]->output = 0, inlined[y]->aux = 0;
+ }
+#ifdef ENABLE_CHECKING
+ for (node = cgraph_nodes; node; node = node->next)
+ if (node->aux || node->output)
+ abort ();
+#endif
+
+ if (!flag_really_no_inline)
+ {
+ cgraph_decide_inlining_of_small_functions (inlined, inlined_callees);
+#ifdef ENABLE_CHECKING
+ for (node = cgraph_nodes; node; node = node->next)
+ if (node->aux || node->output)
+ abort ();
+#endif
+
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, "\nDeciding on functions called once:\n");
+
+ /* And finally decide what functions are called once. */
+
+ for (i = nnodes - 1; i >= 0; i--)
+ {
+ node = order[i];
+
+ if (node->callers && !node->callers->next_caller && !node->needed
+ && node->local.inlinable && node->callers->inline_failed
+ && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl))
+ {
+ bool ok = true;
+ struct cgraph_node *node1;
+
+ /* Verify that we won't duplicate the caller. */
+ for (node1 = node->callers->caller;
+ node1->callers && !node1->callers->inline_failed
+ && ok; node1 = node1->callers->caller)
+ if (node1->callers->next_caller || node1->needed)
+ ok = false;
+ if (ok)
+ {
+ const char *dummy_reason;
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "\nConsidering %s %i insns.\n"
+ " Called once from %s %i insns.\n",
+ cgraph_node_name (node), node->global.insns,
+ cgraph_node_name (node->callers->caller),
+ node->callers->caller->global.insns);
+ ninlined = cgraph_inlined_into (node->callers->caller,
+ inlined);
+ old_insns = overall_insns;
+
+ /* Inlining functions once would never cause inlining warnings. */
+ if (cgraph_check_inline_limits
+ (node->callers->caller, node, inlined, ninlined,
+ &dummy_reason))
+ {
+ ninlined_callees =
+ cgraph_inlined_callees (node, inlined_callees);
+ cgraph_mark_inline (node->callers->caller, node, inlined,
+ ninlined, inlined_callees,
+ ninlined_callees);
+ for (y = 0; y < ninlined_callees; y++)
+ inlined_callees[y]->output = 0, inlined_callees[y]->aux = 0;
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ " Inlined into %s which now has %i insns"
+ " for a net change of %+i insns.\n",
+ cgraph_node_name (node->callers->caller),
+ node->callers->caller->global.insns,
+ overall_insns - old_insns);
+ }
+ else
+ {
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ " Inline limit reached, not inlined.\n");
+ }
+ for (y = 0; y < ninlined; y++)
+ inlined[y]->output = 0, inlined[y]->aux = 0;
+ }
+ }
+ }
+ }
+ cgraph_remove_unreachable_nodes ();
+
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "\nInlined %i calls, eliminated %i functions, "
+ "%i insns turned to %i insns.\n\n",
+ ncalls_inlined, nfunctions_inlined, initial_insns,
+ overall_insns);
+ free (order);
+ free (inlined);
+ free (inlined_callees);
+}
+
+/* Decide on the inlining. We do so in the topological order to avoid
+ expenses on updating datastructures. */
+
+static void
+cgraph_decide_inlining_incrementally (struct cgraph_node *node)
+{
+ struct cgraph_edge *e;
+ struct cgraph_node **inlined =
+ xmalloc (sizeof (struct cgraph_node *) * cgraph_n_nodes);
+ struct cgraph_node **inlined_callees =
+ xmalloc (sizeof (struct cgraph_node *) * cgraph_n_nodes);
+ int ninlined;
+ int ninlined_callees;
+ int y;
+
+ ninlined = cgraph_inlined_into (node, inlined);
+
+ /* First of all look for always inline functions. */
+ for (e = node->callees; e; e = e->next_callee)
+ if (e->callee->local.disregard_inline_limits && e->inline_failed
+ /* ??? It is possible that renaming variable removed the function body
+ in duplicate_decls. See gcc.c-torture/compile/20011119-2.c */
+ && DECL_SAVED_TREE (e->callee->decl))
+ {
+ if (e->callee->output || e->callee == node)
+ {
+ e->inline_failed = N_("recursive inlining");
+ continue;
+ }
+ ninlined_callees = cgraph_inlined_callees (e->callee, inlined_callees);
+ cgraph_mark_inline (node, e->callee, inlined, ninlined,
+ inlined_callees, ninlined_callees);
+ for (y = 0; y < ninlined_callees; y++)
+ inlined_callees[y]->output = 0, inlined_callees[y]->aux = 0;
+ }
+
+ if (!flag_really_no_inline)
+ {
+ /* Now do the automatic inlining. */
+ for (e = node->callees; e; e = e->next_callee)
+ if (e->callee->local.inlinable && e->inline_failed
+ && cgraph_default_inline_p (e->callee)
+ && cgraph_check_inline_limits (node, e->callee, inlined,
+ ninlined, &e->inline_failed)
+ && DECL_SAVED_TREE (e->callee->decl))
+ {
+ /* Marking recursive function inlinine has sane semantic and thus
+ we should not warn on it. */
+ if (e->callee->output || e->callee == node)
+ {
+ e->inline_failed = "";
+ continue;
+ }
+ ninlined_callees = cgraph_inlined_callees (e->callee,
+ inlined_callees);
+ cgraph_mark_inline (node, e->callee, inlined, ninlined,
+ inlined_callees, ninlined_callees);
+ for (y = 0; y < ninlined_callees; y++)
+ inlined_callees[y]->output = 0, inlined_callees[y]->aux = 0;
+ }
+ }
+
+ /* Clear the flags set by cgraph_inlined_into. */
+ for (y = 0; y < ninlined; y++)
+ inlined[y]->output = 0, inlined[y]->aux = 0;
+
+ free (inlined);
+ free (inlined_callees);
+}
+
+
+/* Return true when CALLER_DECL should be inlined into CALLEE_DECL.
+ When returned false and reason is non-NULL, set it to the reason
+ why the call was not inlined. */
+
+bool
+cgraph_inline_p (tree caller_decl, tree callee_decl, const char **reason)
+{
+ struct cgraph_node *caller = cgraph_node (caller_decl);
+ struct cgraph_node *callee = cgraph_node (callee_decl);
+ struct cgraph_edge *e;
+
+ for (e = caller->callees; e; e = e->next_callee)
+ if (e->callee == callee)
+ {
+ if (e->inline_failed && reason)
+ *reason = e->inline_failed;
+ return !e->inline_failed;
+ }
+ /* We do not record builtins in the callgraph. Perhaps it would make more
+ sense to do so and then prune out those not overwritten by explicit
+ function body. */
+ if (reason)
+ *reason = "originally indirect function calls never inlined";
+ return false;
+}
+/* Expand all functions that must be output.
+
+ Attempt to topologically sort the nodes so function is output when
+ all called functions are already assembled to allow data to be
+ propagated across the callgraph. Use a stack to get smaller distance
+ between a function and it's callees (later we may choose to use a more
+ sophisticated algorithm for function reordering; we will likely want
+ to use subsections to make the output functions appear in top-down
+ order). */
+
+static void
+cgraph_expand_all_functions (void)
+{
+ struct cgraph_node *node;
+ struct cgraph_node **order =
+ xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
+ int order_pos = 0;
+ int i;
+
+ cgraph_mark_functions_to_output ();
+
+ order_pos = cgraph_postorder (order);
+
+ for (i = order_pos - 1; i >= 0; i--)
+ {
+ node = order[i];
+ if (node->output)
+ {
+ if (!node->reachable)
+ abort ();
+ node->output = 0;
+ cgraph_expand_function (node);
+ }
+ }
+ free (order);
+}
+
+/* Mark all local functions.
+
+ A local function is one whose calls can occur only in the
+ current compilation unit and all it's calls are explicit,
+ so we can change its calling convention.
+ We simply mark all static functions whose address is not taken
+ as local. */
+
+static void
+cgraph_mark_local_functions (void)
+{
+ struct cgraph_node *node;
+
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, "\nMarking local functions:");
+
+ /* Figure out functions we want to assemble. */
+ for (node = cgraph_nodes; node; node = node->next)
+ {
+ node->local.local = (!node->needed
+ && DECL_SAVED_TREE (node->decl)
+ && !TREE_PUBLIC (node->decl));
+ if (cgraph_dump_file && node->local.local)
+ fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
+ }
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file, "\n\n");
+}
+
+/* Perform simple optimizations based on callgraph. */
+
+void
+cgraph_optimize (void)
+{
+ if (!flag_unit_at_a_time)
+ return;
+ timevar_push (TV_CGRAPHOPT);
+ if (!quiet_flag)
+ fprintf (stderr, "Performing intraprocedural optimizations\n");
+
+ cgraph_mark_local_functions ();
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, "Marked ");
+ dump_cgraph (cgraph_dump_file);
+ }
+
+ cgraph_decide_inlining ();
+ cgraph_global_info_ready = true;
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, "Optimized ");
+ dump_cgraph (cgraph_dump_file);
+ }
+ timevar_pop (TV_CGRAPHOPT);
+
+ /* Output everything. */
+ if (!quiet_flag)
+ fprintf (stderr, "Assembling functions:\n");
+ cgraph_expand_all_functions ();
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, "\nFinal ");
+ dump_cgraph (cgraph_dump_file);
+ }
+}
diff --git a/contrib/gcc/collect2.c b/contrib/gcc/collect2.c
index 7b3dfaafa99a..4fbe3a420032 100644
--- a/contrib/gcc/collect2.c
+++ b/contrib/gcc/collect2.c
@@ -1,7 +1,7 @@
/* Collect static initialization info into data structures that can be
traversed by C++ initialization and finalization routines.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Chris Smith (csmith@convex.com).
Heavily modified by Michael Meissner (meissner@cygnus.com),
Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
@@ -28,6 +28,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include <signal.h>
#if ! defined( SIGCHLD ) && defined( SIGCLD )
# define SIGCHLD SIGCLD
@@ -67,7 +69,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifdef CROSS_COMPILE
#undef SUNOS4_SHARED_LIBRARIES
#undef OBJECT_FORMAT_COFF
-#undef OBJECT_FORMAT_ROSE
#undef MD_EXEC_PREFIX
#undef REAL_LD_FILE_NAME
#undef REAL_NM_FILE_NAME
@@ -79,7 +80,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
In a cross-compiler, this means you need a cross nm,
but that is not quite as unpleasant as special headers. */
-#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE)
+#if !defined (OBJECT_FORMAT_COFF)
#define OBJECT_FORMAT_NONE
#endif
@@ -102,7 +103,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* 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
- that either do not have an ISCOFF macro in /usr/include or for those
+ that either do not have an ISCOFF macro in /usr/include or for those
where it is wrong. */
#ifndef MY_ISCOFF
@@ -111,24 +112,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#endif /* OBJECT_FORMAT_COFF */
-#ifdef OBJECT_FORMAT_ROSE
-
-#ifdef _OSF_SOURCE
-#define USE_MMAP
-#endif
-
-#ifdef USE_MMAP
-#include <sys/mman.h>
-#endif
-
-#include <unistd.h>
-#include <mach_o_format.h>
-#include <mach_o_header.h>
-#include <mach_o_vals.h>
-#include <mach_o_types.h>
-
-#endif /* OBJECT_FORMAT_ROSE */
-
#ifdef OBJECT_FORMAT_NONE
/* Default flags to pass to nm. */
@@ -167,13 +150,17 @@ int do_collecting = 1;
int do_collecting = 0;
#endif
+#ifndef COLLECT_PARSE_FLAG
+#define COLLECT_PARSE_FLAG(FLAG)
+#endif
+
/* Nonzero if we should suppress the automatic demangling of identifiers
in linker error messages. Set from COLLECT_NO_DEMANGLE. */
int no_demangle;
/* Linked lists of constructor and destructor names. */
-struct id
+struct id
{
struct id *next;
int sequence;
@@ -233,7 +220,7 @@ static struct head frame_tables; /* list of frame unwind info tables */
struct obstack temporary_obstack;
char * temporary_firstobj;
-/* Holds the return value of pexecute. */
+/* Holds the return value of pexecute and fork. */
int pid;
/* Structure to hold all the directories in which to search for files to
@@ -262,59 +249,55 @@ static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
static const char *const libexts[3] = {"a", "so", NULL}; /* possible library extensions */
#endif
-static void handler PARAMS ((int));
-static int is_ctor_dtor PARAMS ((const char *));
-static char *find_a_file PARAMS ((struct path_prefix *, const char *));
-static void add_prefix PARAMS ((struct path_prefix *, const char *));
-static void prefix_from_env PARAMS ((const char *, struct path_prefix *));
-static void prefix_from_string PARAMS ((const char *, struct path_prefix *));
-static void do_wait PARAMS ((const char *));
-static void fork_execute PARAMS ((const char *, char **));
-static void maybe_unlink PARAMS ((const char *));
-static void add_to_list PARAMS ((struct head *, const char *));
-static int extract_init_priority PARAMS ((const char *));
-static void sort_ids PARAMS ((struct head *));
-static void write_list PARAMS ((FILE *, const char *, struct id *));
+static void handler (int);
+static int is_ctor_dtor (const char *);
+static char *find_a_file (struct path_prefix *, const char *);
+static void add_prefix (struct path_prefix *, const char *);
+static void prefix_from_env (const char *, struct path_prefix *);
+static void prefix_from_string (const char *, struct path_prefix *);
+static void do_wait (const char *);
+static void fork_execute (const char *, char **);
+static void maybe_unlink (const char *);
+static void add_to_list (struct head *, const char *);
+static int extract_init_priority (const char *);
+static void sort_ids (struct head *);
+static void write_list (FILE *, const char *, struct id *);
#ifdef COLLECT_EXPORT_LIST
-static void dump_list PARAMS ((FILE *, const char *, struct id *));
+static void dump_list (FILE *, const char *, struct id *);
#endif
#if 0
-static void dump_prefix_list PARAMS ((FILE *, const char *, struct prefix_list *));
+static void dump_prefix_list (FILE *, const char *, struct prefix_list *);
#endif
-static void write_list_with_asm PARAMS ((FILE *, const char *, struct id *));
-static void write_c_file PARAMS ((FILE *, const char *));
-static void write_c_file_stat PARAMS ((FILE *, const char *));
+static void write_list_with_asm (FILE *, const char *, struct id *);
+static void write_c_file (FILE *, const char *);
+static void write_c_file_stat (FILE *, const char *);
#ifndef LD_INIT_SWITCH
-static void write_c_file_glob PARAMS ((FILE *, const char *));
+static void write_c_file_glob (FILE *, const char *);
#endif
-static void scan_prog_file PARAMS ((const char *, enum pass));
+static void scan_prog_file (const char *, enum pass);
#ifdef SCAN_LIBRARIES
-static void scan_libraries PARAMS ((const char *));
+static void scan_libraries (const char *);
#endif
#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
-static int is_in_args PARAMS ((const char *, const char **, const char **));
+static int is_in_args (const char *, const char **, const char **);
#endif
#ifdef COLLECT_EXPORT_LIST
#if 0
-static int is_in_list PARAMS ((const char *, struct id *));
+static int is_in_list (const char *, struct id *);
#endif
-static void write_aix_file PARAMS ((FILE *, struct id *));
-static char *resolve_lib_name PARAMS ((const char *));
-static int ignore_library PARAMS ((const char *));
+static void write_aix_file (FILE *, struct id *);
+static char *resolve_lib_name (const char *);
#endif
-static char *extract_string PARAMS ((const char **));
+static char *extract_string (const char **);
#ifndef HAVE_DUP2
-static int dup2 PARAMS ((int, int));
static int
-dup2 (oldfd, newfd)
- int oldfd;
- int newfd;
+dup2 (int oldfd, int newfd)
{
int fdtmp[256];
int fdx = 0;
int fd;
-
+
if (oldfd == newfd)
return oldfd;
close (newfd);
@@ -330,8 +313,7 @@ dup2 (oldfd, newfd)
/* Delete tempfiles and exit function. */
void
-collect_exit (status)
- int status;
+collect_exit (int status)
{
if (c_file != 0 && c_file[0])
maybe_unlink (c_file);
@@ -359,29 +341,28 @@ collect_exit (status)
/* Notify user of a non-error. */
void
-notice VPARAMS ((const char *msgid, ...))
+notice (const char *msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_list ap;
+ va_start (ap, msgid);
vfprintf (stderr, _(msgid), ap);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Die when sys call fails. */
void
-fatal_perror VPARAMS ((const char * msgid, ...))
+fatal_perror (const char * msgid, ...)
{
int e = errno;
+ va_list ap;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
+ va_start (ap, msgid);
fprintf (stderr, "collect2: ");
vfprintf (stderr, _(msgid), ap);
fprintf (stderr, ": %s\n", xstrerror (e));
- VA_CLOSE (ap);
+ va_end (ap);
collect_exit (FATAL_EXIT_CODE);
}
@@ -389,15 +370,15 @@ fatal_perror VPARAMS ((const char * msgid, ...))
/* Just die. */
void
-fatal VPARAMS ((const char * msgid, ...))
+fatal (const char * msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
+ va_list ap;
+
+ va_start (ap, msgid);
fprintf (stderr, "collect2: ");
vfprintf (stderr, _(msgid), ap);
fprintf (stderr, "\n");
- VA_CLOSE (ap);
+ va_end (ap);
collect_exit (FATAL_EXIT_CODE);
}
@@ -405,29 +386,28 @@ fatal VPARAMS ((const char * msgid, ...))
/* Write error message. */
void
-error VPARAMS ((const char * msgid, ...))
+error (const char * msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_list ap;
+ va_start (ap, msgid);
fprintf (stderr, "collect2: ");
vfprintf (stderr, _(msgid), ap);
fprintf (stderr, "\n");
- VA_CLOSE(ap);
+ va_end(ap);
}
/* In case obstack is linked in, and abort is defined to fancy_abort,
provide a default entry. */
void
-fancy_abort ()
+fancy_abort (void)
{
fatal ("internal error");
}
static void
-handler (signo)
- int signo;
+handler (int signo)
{
if (c_file != 0 && c_file[0])
maybe_unlink (c_file);
@@ -449,8 +429,7 @@ handler (signo)
int
-file_exists (name)
- const char *name;
+file_exists (const char *name)
{
return access (name, R_OK) == 0;
}
@@ -458,8 +437,7 @@ file_exists (name)
/* Parse a reasonable subset of shell quoting syntax. */
static char *
-extract_string (pp)
- const char **pp;
+extract_string (const char **pp)
{
const char *p = *pp;
int backquote = 0;
@@ -489,8 +467,7 @@ extract_string (pp)
}
void
-dump_file (name)
- const char *name;
+dump_file (const char *name)
{
FILE *stream = fopen (name, "r");
@@ -552,8 +529,7 @@ dump_file (name)
nothing special (0). */
static int
-is_ctor_dtor (s)
- const char *s;
+is_ctor_dtor (const char *s)
{
struct names { const char *const name; const int len; const int ret;
const int two_underscores; };
@@ -577,14 +553,6 @@ is_ctor_dtor (s)
{ "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 },
{ "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
{ "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
-#ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions.
- cfront has its own linker procedure to collect them;
- if collect2 gets them too, they get collected twice
- when the cfront procedure is run and the compiler used
- for linking happens to be GCC. */
- { "sti__", sizeof ("sti__")-1, 1, 1 },
- { "std__", sizeof ("std__")-1, 2, 1 },
-#endif /* CFRONT_LOSSAGE */
{ NULL, 0, 0, 0 }
};
@@ -619,14 +587,12 @@ static const char *const target_machine = TARGET_MACHINE;
#endif
/* Search for NAME using prefix list PPREFIX. We only look for executable
- files.
+ files.
Return 0 if not found, otherwise return its name, allocated with malloc. */
static char *
-find_a_file (pprefix, name)
- struct path_prefix *pprefix;
- const char *name;
+find_a_file (struct path_prefix *pprefix, const char *name)
{
char *temp;
struct prefix_list *pl;
@@ -634,7 +600,7 @@ find_a_file (pprefix, name)
if (debug)
fprintf (stderr, "Looking for '%s'\n", name);
-
+
#ifdef HOST_EXECUTABLE_SUFFIX
len += strlen (HOST_EXECUTABLE_SUFFIX);
#endif
@@ -655,7 +621,7 @@ find_a_file (pprefix, name)
if (debug)
fprintf (stderr, " - found: absolute path\n");
-
+
return temp;
}
@@ -664,7 +630,7 @@ find_a_file (pprefix, name)
So try appending that. */
strcpy (temp, name);
strcat (temp, HOST_EXECUTABLE_SUFFIX);
-
+
if (access (temp, X_OK) == 0)
return temp;
#endif
@@ -679,7 +645,7 @@ find_a_file (pprefix, name)
strcpy (temp, pl->prefix);
strcat (temp, name);
-
+
if (stat (temp, &st) >= 0
&& ! S_ISDIR (st.st_mode)
&& access (temp, X_OK) == 0)
@@ -689,7 +655,7 @@ find_a_file (pprefix, name)
/* Some systems have a suffix for executable files.
So try appending that. */
strcat (temp, HOST_EXECUTABLE_SUFFIX);
-
+
if (stat (temp, &st) >= 0
&& ! S_ISDIR (st.st_mode)
&& access (temp, X_OK) == 0)
@@ -707,9 +673,7 @@ find_a_file (pprefix, name)
/* Add an entry for PREFIX to prefix list PPREFIX. */
static void
-add_prefix (pprefix, prefix)
- struct path_prefix *pprefix;
- const char *prefix;
+add_prefix (struct path_prefix *pprefix, const char *prefix)
{
struct prefix_list *pl, **prev;
int len;
@@ -723,13 +687,13 @@ add_prefix (pprefix, prefix)
else
prev = &pprefix->plist;
- /* Keep track of the longest prefix */
+ /* Keep track of the longest prefix. */
len = strlen (prefix);
if (len > pprefix->max_len)
pprefix->max_len = len;
- pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
+ pl = xmalloc (sizeof (struct prefix_list));
pl->prefix = xstrdup (prefix);
if (*prev)
@@ -743,9 +707,7 @@ add_prefix (pprefix, prefix)
add of the entries to PPREFIX. */
static void
-prefix_from_env (env, pprefix)
- const char *env;
- struct path_prefix *pprefix;
+prefix_from_env (const char *env, struct path_prefix *pprefix)
{
const char *p;
GET_ENVIRONMENT (p, env);
@@ -755,16 +717,14 @@ prefix_from_env (env, pprefix)
}
static void
-prefix_from_string (p, pprefix)
- const char *p;
- struct path_prefix *pprefix;
+prefix_from_string (const char *p, struct path_prefix *pprefix)
{
const char *startp, *endp;
- char *nstore = (char *) xmalloc (strlen (p) + 3);
+ char *nstore = xmalloc (strlen (p) + 3);
if (debug)
fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR);
-
+
startp = endp = p;
while (1)
{
@@ -785,7 +745,7 @@ prefix_from_string (p, pprefix)
if (debug)
fprintf (stderr, " - add prefix: %s\n", nstore);
-
+
add_prefix (pprefix, nstore);
if (*endp == 0)
break;
@@ -798,11 +758,8 @@ prefix_from_string (p, pprefix)
/* Main program. */
-int main PARAMS ((int, char *[]));
int
-main (argc, argv)
- int argc;
- char *argv[];
+main (int argc, char **argv)
{
static const char *const ld_suffix = "ld";
static const char *const real_ld_suffix = "real-ld";
@@ -885,9 +842,9 @@ main (argc, 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 = (char **) xcalloc(sizeof (char *), argc+3));
- ld2 = (const char **)(ld2_argv = (char **) xcalloc(sizeof (char *), argc+10));
- object = (const char **)(object_lst = (char **) xcalloc(sizeof (char *), argc));
+ ld1 = (const char **)(ld1_argv = xcalloc(sizeof (char *), argc+3));
+ ld2 = (const char **)(ld2_argv = xcalloc(sizeof (char *), argc+10));
+ object = (const char **)(object_lst = xcalloc(sizeof (char *), argc));
#ifdef DEBUG
debug = 1;
@@ -898,10 +855,13 @@ main (argc, argv)
are called. */
{
int i;
-
+
for (i = 1; argv[i] != NULL; i ++)
- if (! strcmp (argv[i], "-debug"))
- debug = 1;
+ {
+ if (! strcmp (argv[i], "-debug"))
+ debug = 1;
+ COLLECT_PARSE_FLAG (argv[i]);
+ }
vflag = debug;
}
@@ -912,7 +872,7 @@ main (argc, argv)
#endif
obstack_begin (&temporary_obstack, 0);
- temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
+ temporary_firstobj = obstack_alloc (&temporary_obstack, 0);
current_demangling_style = auto_demangling;
p = getenv ("COLLECT_GCC_OPTIONS");
@@ -924,11 +884,11 @@ main (argc, argv)
}
obstack_free (&temporary_obstack, temporary_firstobj);
- /* -fno-exceptions -w */
- num_c_args += 2;
+ /* -fno-profile-arcs -fno-test-coverage -fno-branch-probabilities
+ -fno-exceptions -w */
+ num_c_args += 5;
- c_ptr = (const char **)
- (c_argv = (char **) xcalloc (sizeof (char *), num_c_args));
+ c_ptr = (const char **) (c_argv = xcalloc (sizeof (char *), num_c_args));
if (argc < 2)
fatal ("no arguments");
@@ -1061,7 +1021,7 @@ main (argc, argv)
add_prefix (&libpath_lib_dirs, "/usr/lib");
#endif
- /* Get any options that the upper GCC wants to pass to the sub-GCC.
+ /* Get any options that the upper GCC wants to pass to the sub-GCC.
AIX support needs to know if -shared has been specified before
parsing commandline arguments. */
@@ -1087,6 +1047,9 @@ main (argc, argv)
}
}
obstack_free (&temporary_obstack, temporary_firstobj);
+ *c_ptr++ = "-fno-profile-arcs";
+ *c_ptr++ = "-fno-test-coverage";
+ *c_ptr++ = "-fno-branch-probabilities";
*c_ptr++ = "-fno-exceptions";
*c_ptr++ = "-w";
@@ -1151,10 +1114,10 @@ main (argc, argv)
#ifdef COLLECT_EXPORT_LIST
/* Saving directories where to search for libraries. */
- case 'L':
+ case 'L':
add_prefix (&cmdline_lib_dirs, arg+2);
break;
-#else
+#else
#if LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
case 'L':
if (is_in_args (arg, (const char **) ld1_argv, ld1-1))
@@ -1219,8 +1182,8 @@ main (argc, argv)
*object++ = arg;
#ifdef COLLECT_EXPORT_LIST
/* libraries can be specified directly, i.e. without -l flag. */
- else
- {
+ else
+ {
/* Saving a full library name. */
add_to_list (&libs, arg);
}
@@ -1254,7 +1217,7 @@ main (argc, argv)
if (exports.first)
{
char *buf = concat ("-bE:", export_file, NULL);
-
+
*ld1++ = buf;
*ld2++ = buf;
@@ -1378,15 +1341,15 @@ main (argc, argv)
)
{
#ifdef COLLECT_EXPORT_LIST
- /* Do tlink without additional code generation */
+ /* Do tlink without additional code generation. */
do_tlink (ld1_argv, object_lst);
#endif
/* Strip now if it was requested on the command line. */
if (strip_flag)
{
- char **real_strip_argv = (char **) xcalloc (sizeof (char *), 3);
+ char **real_strip_argv = xcalloc (sizeof (char *), 3);
const char ** strip_argv = (const char **) real_strip_argv;
-
+
strip_argv[0] = strip_file_name;
strip_argv[1] = output_file;
strip_argv[2] = (char *) 0;
@@ -1435,10 +1398,12 @@ main (argc, argv)
if (! exports.first)
*ld2++ = concat ("-bE:", export_file, NULL);
+#ifndef LD_INIT_SWITCH
add_to_list (&exports, initname);
add_to_list (&exports, fininame);
add_to_list (&exports, "_GLOBAL__DI");
add_to_list (&exports, "_GLOBAL__DD");
+#endif
exportf = fopen (export_file, "w");
if (exportf == (FILE *) 0)
fatal_perror ("fopen %s", export_file);
@@ -1469,16 +1434,16 @@ main (argc, argv)
fork_execute ("gcc", c_argv);
#ifdef COLLECT_EXPORT_LIST
- /* On AIX we must call tlink because of possible templates resolution */
+ /* On AIX we must call tlink because of possible templates resolution. */
do_tlink (ld2_argv, object_lst);
#else
- /* Otherwise, simply call ld because tlink is already done */
+ /* Otherwise, simply call ld because tlink is already done. */
fork_execute ("ld", ld2_argv);
/* Let scan_prog_file do any final mods (OSF/rose needs this for
constructors/destructors in shared libraries. */
scan_prog_file (output_file, PASS_SECOND);
-#endif
+#endif
maybe_unlink (c_file);
maybe_unlink (o_file);
@@ -1494,8 +1459,7 @@ main (argc, argv)
/* Wait for a process to finish, and exit if a nonzero status is found. */
int
-collect_wait (prog)
- const char *prog;
+collect_wait (const char *prog)
{
int status;
@@ -1518,8 +1482,7 @@ collect_wait (prog)
}
static void
-do_wait (prog)
- const char *prog;
+do_wait (const char *prog)
{
int ret = collect_wait (prog);
if (ret != 0)
@@ -1533,10 +1496,7 @@ do_wait (prog)
/* Execute a program, and wait for the reply. */
void
-collect_execute (prog, argv, redir)
- const char *prog;
- char **argv;
- const char *redir;
+collect_execute (const char *prog, char **argv, const char *redir)
{
char *errmsg_fmt;
char *errmsg_arg;
@@ -1588,8 +1548,7 @@ collect_execute (prog, argv, redir)
dup2 (redir_handle, STDERR_FILENO);
}
- pid = pexecute (argv[0], argv, argv[0], NULL,
- &errmsg_fmt, &errmsg_arg,
+ pid = pexecute (argv[0], argv, argv[0], NULL, &errmsg_fmt, &errmsg_arg,
(PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH));
if (redir)
@@ -1607,9 +1566,7 @@ collect_execute (prog, argv, redir)
}
static void
-fork_execute (prog, argv)
- const char *prog;
- char **argv;
+fork_execute (const char *prog, char **argv)
{
collect_execute (prog, argv, NULL);
do_wait (prog);
@@ -1618,8 +1575,7 @@ fork_execute (prog, argv)
/* Unlink a file unless we are debugging. */
static void
-maybe_unlink (file)
- const char *file;
+maybe_unlink (const char *file)
{
if (!debug)
unlink (file);
@@ -1633,12 +1589,9 @@ static long sequence_number = 0;
/* Add a name to a linked list. */
static void
-add_to_list (head_ptr, name)
- struct head *head_ptr;
- const char *name;
+add_to_list (struct head *head_ptr, const char *name)
{
- struct id *newid
- = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1);
+ struct id *newid = xcalloc (sizeof (struct id) + strlen (name), 1);
struct id *p;
strcpy (newid->name, name);
@@ -1668,8 +1621,7 @@ add_to_list (head_ptr, name)
looks like "_GLOBAL_.I.12345.foo". */
static int
-extract_init_priority (name)
- const char *name;
+extract_init_priority (const char *name)
{
int pos = 0, pri;
@@ -1686,8 +1638,7 @@ extract_init_priority (name)
ctors will be run from right to left, dtors from left to right. */
static void
-sort_ids (head_ptr)
- struct head *head_ptr;
+sort_ids (struct head *head_ptr)
{
/* id holds the current element to insert. id_next holds the next
element to insert. id_ptr iterates through the already sorted elements
@@ -1728,10 +1679,7 @@ sort_ids (head_ptr)
/* Write: `prefix', the names on list LIST, `suffix'. */
static void
-write_list (stream, prefix, list)
- FILE *stream;
- const char *prefix;
- struct id *list;
+write_list (FILE *stream, const char *prefix, struct id *list)
{
while (list)
{
@@ -1745,10 +1693,8 @@ write_list (stream, prefix, list)
[ARGS_BEGIN,ARGS_END). */
static int
-is_in_args (string, args_begin, args_end)
- const char *string;
- const char **args_begin;
- const char **args_end;
+is_in_args (const char *string, const char **args_begin,
+ const char **args_end)
{
const char **args_pointer;
for (args_pointer = args_begin; args_pointer != args_end; ++args_pointer)
@@ -1762,9 +1708,7 @@ is_in_args (string, args_begin, args_end)
/* This function is really used only on AIX, but may be useful. */
#if 0
static int
-is_in_list (prefix, list)
- const char *prefix;
- struct id *list;
+is_in_list (const char *prefix, struct id *list)
{
while (list)
{
@@ -1779,10 +1723,7 @@ is_in_list (prefix, list)
/* Added for debugging purpose. */
#ifdef COLLECT_EXPORT_LIST
static void
-dump_list (stream, prefix, list)
- FILE *stream;
- const char *prefix;
- struct id *list;
+dump_list (FILE *stream, const char *prefix, struct id *list)
{
while (list)
{
@@ -1794,10 +1735,7 @@ dump_list (stream, prefix, list)
#if 0
static void
-dump_prefix_list (stream, prefix, list)
- FILE *stream;
- const char *prefix;
- struct prefix_list *list;
+dump_prefix_list (FILE *stream, const char *prefix, struct prefix_list *list)
{
while (list)
{
@@ -1808,10 +1746,7 @@ dump_prefix_list (stream, prefix, list)
#endif
static void
-write_list_with_asm (stream, prefix, list)
- FILE *stream;
- const char *prefix;
- struct id *list;
+write_list_with_asm (FILE *stream, const char *prefix, struct id *list)
{
while (list)
{
@@ -1825,9 +1760,7 @@ write_list_with_asm (stream, prefix, list)
object), along with the functions to execute them. */
static void
-write_c_file_stat (stream, name)
- FILE *stream;
- const char *name ATTRIBUTE_UNUSED;
+write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
{
const char *p, *q;
char *prefix, *r;
@@ -1875,7 +1808,7 @@ write_c_file_stat (stream, name)
free (prefix);
- /* Write the tables as C code */
+ /* Write the tables as C code. */
fprintf (stream, "static int count;\n");
fprintf (stream, "typedef void entry_pt();\n");
@@ -1956,16 +1889,14 @@ write_c_file_stat (stream, name)
#ifndef LD_INIT_SWITCH
static void
-write_c_file_glob (stream, name)
- FILE *stream;
- const char *name ATTRIBUTE_UNUSED;
+write_c_file_glob (FILE *stream, const char *name ATTRIBUTE_UNUSED)
{
- /* Write the tables as C code */
+ /* Write the tables as C code. */
int frames = (frame_tables.number > 0);
fprintf (stream, "typedef void entry_pt();\n\n");
-
+
write_list_with_asm (stream, "extern entry_pt ", constructors.first);
if (frames)
@@ -2021,9 +1952,7 @@ write_c_file_glob (stream, name)
#endif /* ! LD_INIT_SWITCH */
static void
-write_c_file (stream, name)
- FILE *stream;
- const char *name;
+write_c_file (FILE *stream, const char *name)
{
fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
#ifndef LD_INIT_SWITCH
@@ -2037,9 +1966,7 @@ write_c_file (stream, name)
#ifdef COLLECT_EXPORT_LIST
static void
-write_aix_file (stream, list)
- FILE *stream;
- struct id *list;
+write_aix_file (FILE *stream, struct id *list)
{
for (; list; list = list->next)
{
@@ -2061,12 +1988,10 @@ write_aix_file (stream, list)
destructor table has the same format, and begins at __DTOR_LIST__. */
static void
-scan_prog_file (prog_name, which_pass)
- const char *prog_name;
- enum pass which_pass;
+scan_prog_file (const char *prog_name, enum pass which_pass)
{
- void (*int_handler) PARAMS ((int));
- void (*quit_handler) PARAMS ((int));
+ void (*int_handler) (int);
+ void (*quit_handler) (int);
char *real_nm_argv[4];
const char **nm_argv = (const char **) real_nm_argv;
int argc = 0;
@@ -2110,7 +2035,7 @@ scan_prog_file (prog_name, which_pass)
fflush (stdout);
fflush (stderr);
- /* Spawn child nm on pipe */
+ /* Spawn child nm on pipe. */
pid = vfork ();
if (pid == -1)
fatal_perror (VFORK_STRING);
@@ -2132,9 +2057,9 @@ scan_prog_file (prog_name, which_pass)
}
/* Parent context from here on. */
- int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
+ int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
#ifdef SIGQUIT
- quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
+ quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
#endif
if (close (pipe_fd[1]) < 0)
@@ -2158,7 +2083,7 @@ scan_prog_file (prog_name, which_pass)
if (ch != '_')
continue;
-
+
name = p;
/* Find the end of the symbol name.
Do not include `|', because Encore nm can tack that on the end. */
@@ -2238,8 +2163,8 @@ scan_prog_file (prog_name, which_pass)
#include <sys/dir.h>
/* pointers to the object file */
-unsigned object; /* address of memory mapped file */
-unsigned objsize; /* size of memory mapped to file */
+unsigned object; /* address of memory mapped file */
+unsigned objsize; /* size of memory mapped to file */
char * code; /* pointer to code segment */
char * data; /* pointer to data segment */
struct nlist *symtab; /* pointer to symbol table */
@@ -2249,11 +2174,8 @@ struct head libraries;
/* Map the file indicated by NAME into memory and store its address. */
-static void mapfile PARAMS ((const char *));
-
static void
-mapfile (name)
- const char *name;
+mapfile (const char *name)
{
int fp;
struct stat s;
@@ -2275,11 +2197,8 @@ mapfile (name)
static const char *libname;
-static int libselect PARAMS ((struct direct *));
-
static int
-libselect (d)
- struct direct *d;
+libselect (struct direct *d)
{
return (strncmp (libname, d->d_name, strlen (libname)) == 0);
}
@@ -2291,11 +2210,9 @@ libselect (d)
We must verify that the extension is numeric, because Sun saves the
original versions of patched libraries with a .FCS extension. Files with
invalid extensions must go last in the sort, so that they will not be used. */
-static int libcompare PARAMS ((struct direct **, struct direct **));
static int
-libcompare (d1, d2)
- struct direct **d1, **d2;
+libcompare (struct direct **d1, struct direct **d2)
{
int i1, i2 = strlen (libname);
char *e1 = (*d1)->d_name + i2;
@@ -2336,11 +2253,9 @@ libcompare (d1, d2)
/* Given the name NAME of a dynamic dependency, find its pathname and add
it to the list of libraries. */
-static void locatelib PARAMS ((const char *));
static void
-locatelib (name)
- const char *name;
+locatelib (const char *name)
{
static const char **l;
static int cnt;
@@ -2353,7 +2268,7 @@ locatelib (name)
char *ld_rules;
char *ldr = 0;
/* counting elements in array, need 1 extra for null */
- cnt = 1;
+ cnt = 1;
ld_rules = (char *) (ld_2->ld_rules + code);
if (ld_rules)
{
@@ -2374,12 +2289,12 @@ locatelib (name)
cnt++;
q = xstrdup (p);
}
- l = (const char **) xmalloc ((cnt + 3) * sizeof (char *));
+ l = xmalloc ((cnt + 3) * sizeof (char *));
pp = l;
if (ldr)
{
*pp++ = ldr;
- for (; *ldr != 0; ldr++)
+ for (; *ldr != 0; ldr++)
if (*ldr == ':')
{
*ldr++ = 0;
@@ -2389,7 +2304,7 @@ locatelib (name)
if (q)
{
*pp++ = q;
- for (; *q != 0; q++)
+ for (; *q != 0; q++)
if (*q == ':')
{
*q++ = 0;
@@ -2428,9 +2343,8 @@ locatelib (name)
/* Scan the _DYNAMIC structure of the output file to find shared libraries
that it depends upon and any constructors or destructors they contain. */
-static void
-scan_libraries (prog_name)
- const char *prog_name;
+static void
+scan_libraries (const char *prog_name)
{
struct exec *header;
char *base;
@@ -2490,7 +2404,7 @@ scan_libraries (prog_name)
if (debug)
fprintf (stderr, "\n");
- /* now iterate through the library list adding their symbols to
+ /* Now iterate through the library list adding their symbols to
the list. */
for (list = libraries.first; list; list = list->next)
scan_prog_file (list->name, PASS_LIB);
@@ -2503,14 +2417,13 @@ scan_libraries (prog_name)
the output file depends upon and their initialization/finalization
routines, if any. */
-static void
-scan_libraries (prog_name)
- const char *prog_name;
+static void
+scan_libraries (const char *prog_name)
{
static struct head libraries; /* list of shared libraries found */
struct id *list;
- void (*int_handler) PARAMS ((int));
- void (*quit_handler) PARAMS ((int));
+ void (*int_handler) (int);
+ void (*quit_handler) (int);
char *real_ldd_argv[4];
const char **ldd_argv = (const char **) real_ldd_argv;
int argc = 0;
@@ -2551,7 +2464,7 @@ scan_libraries (prog_name)
fflush (stdout);
fflush (stderr);
- /* Spawn child ldd on pipe */
+ /* Spawn child ldd on pipe. */
pid = vfork ();
if (pid == -1)
fatal_perror (VFORK_STRING);
@@ -2573,9 +2486,9 @@ scan_libraries (prog_name)
}
/* Parent context from here on. */
- int_handler = (void (*) PARAMS ((int))) signal (SIGINT, SIG_IGN);
+ int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN);
#ifdef SIGQUIT
- quit_handler = (void (*) PARAMS ((int))) signal (SIGQUIT, SIG_IGN);
+ quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN);
#endif
if (close (pipe_fd[1]) < 0)
@@ -2600,7 +2513,7 @@ scan_libraries (prog_name)
fatal ("dynamic dependency %s not found", buf);
/* Find the end of the symbol name. */
- for (end = p;
+ for (end = p;
(ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|';
end++)
continue;
@@ -2627,7 +2540,7 @@ scan_libraries (prog_name)
signal (SIGQUIT, quit_handler);
#endif
- /* now iterate through the library list adding their symbols to
+ /* Now iterate through the library list adding their symbols to
the list. */
for (list = libraries.first; list; list = list->next)
scan_prog_file (list->name, PASS_LIB);
@@ -2645,7 +2558,7 @@ scan_libraries (prog_name)
#ifdef OBJECT_FORMAT_COFF
-#if defined(EXTENDED_COFF)
+#if defined (EXTENDED_COFF)
# define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax)
# define GCC_SYMENT SYMR
@@ -2658,14 +2571,26 @@ scan_libraries (prog_name)
# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms)
# define GCC_SYMENT SYMENT
-# define GCC_OK_SYMBOL(X) \
- (((X).n_sclass == C_EXT) && \
- ((X).n_scnum > N_UNDEF) && \
- (aix64_flag \
- || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
- || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
-# define GCC_UNDEF_SYMBOL(X) \
- (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
+# if defined (C_WEAKEXT)
+# define GCC_OK_SYMBOL(X) \
+ (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
+ ((X).n_scnum > N_UNDEF) && \
+ (aix64_flag \
+ || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
+ || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
+# define GCC_UNDEF_SYMBOL(X) \
+ (((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
+ ((X).n_scnum == N_UNDEF))
+# else
+# define GCC_OK_SYMBOL(X) \
+ (((X).n_sclass == C_EXT) && \
+ ((X).n_scnum > N_UNDEF) && \
+ (aix64_flag \
+ || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
+ || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
+# define GCC_UNDEF_SYMBOL(X) \
+ (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
+# endif
# define GCC_SYMINC(X) ((X).n_numaux+1)
# define GCC_SYMZERO(X) 0
@@ -2682,7 +2607,43 @@ scan_libraries (prog_name)
#endif
-extern char *ldgetname ();
+#ifdef COLLECT_EXPORT_LIST
+/* Array of standard AIX libraries which should not
+ be scanned for ctors/dtors. */
+static const char *const aix_std_libs[] = {
+ "/unix",
+ "/lib/libc.a",
+ "/lib/libm.a",
+ "/lib/libc_r.a",
+ "/lib/libm_r.a",
+ "/usr/lib/libc.a",
+ "/usr/lib/libm.a",
+ "/usr/lib/libc_r.a",
+ "/usr/lib/libm_r.a",
+ "/usr/lib/threads/libc.a",
+ "/usr/ccs/lib/libc.a",
+ "/usr/ccs/lib/libm.a",
+ "/usr/ccs/lib/libc_r.a",
+ "/usr/ccs/lib/libm_r.a",
+ NULL
+};
+
+/* This function checks the filename and returns 1
+ if this name matches the location of a standard AIX library. */
+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;
+ return 0;
+}
+#endif /* COLLECT_EXPORT_LIST */
+
+#if defined (HAVE_DECL_LDGETNAME) && !HAVE_DECL_LDGETNAME
+extern char *ldgetname (LDFILE *, GCC_SYMENT *);
+#endif
/* COFF version to scan the name list of the loaded program for
the symbols g++ uses for static constructors and destructors.
@@ -2694,9 +2655,7 @@ extern char *ldgetname ();
destructor table has the same format, and begins at __DTOR_LIST__. */
static void
-scan_prog_file (prog_name, which_pass)
- const char *prog_name;
- enum pass which_pass;
+scan_prog_file (const char *prog_name, enum pass which_pass)
{
LDFILE *ldptr = NULL;
int sym_index, sym_count;
@@ -2748,7 +2707,7 @@ scan_prog_file (prog_name, which_pass)
char *name;
if ((name = ldgetname (ldptr, &symbol)) == NULL)
- continue; /* should never happen */
+ continue; /* Should never happen. */
#ifdef XCOFF_DEBUGGING_INFO
/* All AIX function names have a duplicate entry
@@ -2762,7 +2721,7 @@ scan_prog_file (prog_name, which_pass)
case 1:
if (! is_shared)
add_to_list (&constructors, name);
-#ifdef COLLECT_EXPORT_LIST
+#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
if (which_pass == PASS_OBJ)
add_to_list (&exports, name);
#endif
@@ -2771,7 +2730,7 @@ scan_prog_file (prog_name, which_pass)
case 2:
if (! is_shared)
add_to_list (&destructors, name);
-#ifdef COLLECT_EXPORT_LIST
+#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
if (which_pass == PASS_OBJ)
add_to_list (&exports, name);
#endif
@@ -2796,7 +2755,7 @@ scan_prog_file (prog_name, which_pass)
case 5:
if (! is_shared)
add_to_list (&frame_tables, name);
-#ifdef COLLECT_EXPORT_LIST
+#if defined (COLLECT_EXPORT_LIST) && !defined (LD_INIT_SWITCH)
if (which_pass == PASS_OBJ)
add_to_list (&exports, name);
#endif
@@ -2804,13 +2763,14 @@ scan_prog_file (prog_name, which_pass)
default: /* not a constructor or destructor */
#ifdef COLLECT_EXPORT_LIST
- /* If we are building a shared object on AIX we need
- to explicitly export all global symbols. */
- if (shared_obj)
- {
- if (which_pass == PASS_OBJ && (! export_flag))
- add_to_list (&exports, name);
- }
+ /* Explicitly export all global symbols when
+ building a shared object on AIX, but do not
+ re-export symbols from another shared object
+ and do not export symbols if the user
+ provides an explicit export list. */
+ if (shared_obj && !is_shared
+ && which_pass == PASS_OBJ && !export_flag)
+ add_to_list (&exports, name);
#endif
continue;
}
@@ -2859,8 +2819,7 @@ scan_prog_file (prog_name, which_pass)
/* Given a library name without "lib" prefix, this function
returns a full library name including a path. */
static char *
-resolve_lib_name (name)
- const char *name;
+resolve_lib_name (const char *name)
{
char *lib_buf;
int i, j, l = 0;
@@ -2884,7 +2843,7 @@ resolve_lib_name (name)
p = "/";
for (j = 0; libexts[j]; j++)
{
- sprintf (lib_buf, "%s%slib%s.%s",
+ sprintf (lib_buf, "%s%slib%s.%s",
list->prefix, p, name, libexts[j]);
if (debug) fprintf (stderr, "searching for: %s\n", lib_buf);
if (file_exists (lib_buf))
@@ -2901,700 +2860,4 @@ if (debug) fprintf (stderr, "found: %s\n", lib_buf);
fatal ("library lib%s not found", name);
return (NULL);
}
-
-/* Array of standard AIX libraries which should not
- be scanned for ctors/dtors. */
-static const char *const aix_std_libs[] = {
- "/unix",
- "/lib/libc.a",
- "/lib/libm.a",
- "/lib/libc_r.a",
- "/lib/libm_r.a",
- "/usr/lib/libc.a",
- "/usr/lib/libm.a",
- "/usr/lib/libc_r.a",
- "/usr/lib/libm_r.a",
- "/usr/lib/threads/libc.a",
- "/usr/ccs/lib/libc.a",
- "/usr/ccs/lib/libm.a",
- "/usr/ccs/lib/libc_r.a",
- "/usr/ccs/lib/libm_r.a",
- NULL
-};
-
-/* This function checks the filename and returns 1
- if this name matches the location of a standard AIX library. */
-static int
-ignore_library (name)
- const char *name;
-{
- const char *const *p = &aix_std_libs[0];
- while (*p++ != NULL)
- if (! strcmp (name, *p)) return 1;
- return 0;
-}
#endif /* COLLECT_EXPORT_LIST */
-
-
-/*
- * OSF/rose specific stuff.
- */
-
-#ifdef OBJECT_FORMAT_ROSE
-
-/* Union of the various load commands */
-
-typedef union load_union
-{
- ldc_header_t hdr; /* common header */
- load_cmd_map_command_t map; /* map indexing other load cmds */
- interpreter_command_t iprtr; /* interpreter pathname */
- strings_command_t str; /* load commands strings section */
- region_command_t region; /* region load command */
- reloc_command_t reloc; /* relocation section */
- package_command_t pkg; /* package load command */
- symbols_command_t sym; /* symbol sections */
- entry_command_t ent; /* program start section */
- gen_info_command_t info; /* object information */
- func_table_command_t func; /* function constructors/destructors */
-} load_union_t;
-
-/* Structure to point to load command and data section in memory. */
-
-typedef struct load_all
-{
- load_union_t *load; /* load command */
- char *section; /* pointer to section */
-} load_all_t;
-
-/* Structure to contain information about a file mapped into memory. */
-
-struct file_info
-{
- char *start; /* start of map */
- char *name; /* filename */
- long size; /* size of the file */
- long rounded_size; /* size rounded to page boundary */
- int fd; /* file descriptor */
- int rw; /* != 0 if opened read/write */
- int use_mmap; /* != 0 if mmap'ed */
-};
-
-extern int decode_mach_o_hdr ();
-extern int encode_mach_o_hdr ();
-
-static void add_func_table PARAMS ((mo_header_t *, load_all_t *,
- symbol_info_t *, int));
-static void print_header PARAMS ((mo_header_t *));
-static void print_load_command PARAMS ((load_union_t *, size_t, int));
-static void bad_header PARAMS ((int));
-static struct file_info *read_file PARAMS ((const char *, int, int));
-static void end_file PARAMS ((struct file_info *));
-
-/* OSF/rose specific version to scan the name list of the loaded
- program for the symbols g++ uses for static constructors and
- destructors.
-
- The constructor table begins at __CTOR_LIST__ and contains a count
- of the number of pointers (or -1 if the constructors are built in a
- separate section by the linker), followed by the pointers to the
- constructor functions, terminated with a null pointer. The
- destructor table has the same format, and begins at __DTOR_LIST__. */
-
-static void
-scan_prog_file (prog_name, which_pass)
- const char *prog_name;
- enum pass which_pass;
-{
- char *obj;
- mo_header_t hdr;
- load_all_t *load_array;
- load_all_t *load_end;
- load_all_t *load_cmd;
- int symbol_load_cmds;
- off_t offset;
- int i;
- int num_syms;
- int status;
- char *str_sect;
- struct file_info *obj_file;
- int prog_fd;
- mo_lcid_t cmd_strings = -1;
- symbol_info_t *main_sym = 0;
- int rw = (which_pass != PASS_FIRST);
-
- prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY);
- if (prog_fd < 0)
- fatal_perror ("open %s", prog_name);
-
- obj_file = read_file (prog_name, prog_fd, rw);
- obj = obj_file->start;
-
- status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr);
- if (status != MO_HDR_CONV_SUCCESS)
- bad_header (status);
-
-
- /* Do some basic sanity checks. Note we explicitly use the big endian magic number,
- since the hardware will automatically swap bytes for us on loading little endian
- integers. */
-
-#ifndef CROSS_COMPILE
- if (hdr.moh_magic != MOH_MAGIC_MSB
- || hdr.moh_header_version != MOH_HEADER_VERSION
- || hdr.moh_byte_order != OUR_BYTE_ORDER
- || hdr.moh_data_rep_id != OUR_DATA_REP_ID
- || hdr.moh_cpu_type != OUR_CPU_TYPE
- || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE
- || hdr.moh_vendor_type != OUR_VENDOR_TYPE)
- {
- fatal ("incompatibilities between object file & expected values");
- }
-#endif
-
- if (debug)
- print_header (&hdr);
-
- offset = hdr.moh_first_cmd_off;
- load_end = load_array
- = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2);
-
- /* Build array of load commands, calculating the offsets */
- for (i = 0; i < hdr.moh_n_load_cmds; i++)
- {
- load_union_t *load_hdr; /* load command header */
-
- load_cmd = load_end++;
- load_hdr = (load_union_t *) (obj + offset);
-
- /* If modifying the program file, copy the header. */
- if (rw)
- {
- load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size);
- memcpy ((char *)ptr, (char *)load_hdr, load_hdr->hdr.ldci_cmd_size);
- load_hdr = ptr;
-
- /* null out old command map, because we will rewrite at the end. */
- if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP)
- {
- cmd_strings = ptr->map.lcm_ld_cmd_strings;
- ptr->hdr.ldci_cmd_type = LDC_UNDEFINED;
- }
- }
-
- load_cmd->load = load_hdr;
- if (load_hdr->hdr.ldci_section_off > 0)
- load_cmd->section = obj + load_hdr->hdr.ldci_section_off;
-
- if (debug)
- print_load_command (load_hdr, offset, i);
-
- offset += load_hdr->hdr.ldci_cmd_size;
- }
-
- /* If the last command is the load command map and is not undefined,
- decrement the count of load commands. */
- if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED)
- {
- load_end--;
- hdr.moh_n_load_cmds--;
- }
-
- /* Go through and process each symbol table section. */
- symbol_load_cmds = 0;
- for (load_cmd = load_array; load_cmd < load_end; load_cmd++)
- {
- load_union_t *load_hdr = load_cmd->load;
-
- if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS)
- {
- symbol_load_cmds++;
-
- if (debug)
- {
- const char *kind = "unknown";
-
- switch (load_hdr->sym.symc_kind)
- {
- case SYMC_IMPORTS: kind = "imports"; break;
- case SYMC_DEFINED_SYMBOLS: kind = "defined"; break;
- case SYMC_STABS: kind = "stabs"; break;
- }
-
- notice ("\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n",
- symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind);
- }
-
- if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS)
- continue;
-
- str_sect = load_array[load_hdr->sym.symc_strings_section].section;
- if (str_sect == (char *) 0)
- fatal ("string section missing");
-
- if (load_cmd->section == (char *) 0)
- fatal ("section pointer missing");
-
- num_syms = load_hdr->sym.symc_nentries;
- for (i = 0; i < num_syms; i++)
- {
- symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i;
- char *name = sym->si_name.symbol_name + str_sect;
-
- if (name[0] != '_')
- continue;
-
- if (rw)
- {
- char *n = name + strlen (name) - strlen (NAME__MAIN);
-
- if ((n - name) < 0 || strcmp (n, NAME__MAIN))
- continue;
- while (n != name)
- if (*--n != '_')
- continue;
-
- main_sym = sym;
- }
- else
- {
- switch (is_ctor_dtor (name))
- {
- case 1:
- add_to_list (&constructors, name);
- break;
-
- case 2:
- add_to_list (&destructors, name);
- break;
-
- default: /* not a constructor or destructor */
- continue;
- }
- }
-
- if (debug)
- fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n",
- sym->si_type, sym->si_sc_type, sym->si_flags, name);
- }
- }
- }
-
- if (symbol_load_cmds == 0)
- fatal ("no symbol table found");
-
- /* Update the program file now, rewrite header and load commands. At present,
- we assume that there is enough space after the last load command to insert
- one more. Since the first section written out is page aligned, and the
- number of load commands is small, this is ok for the present. */
-
- if (rw)
- {
- load_union_t *load_map;
- size_t size;
-
- if (cmd_strings == -1)
- fatal ("no cmd_strings found");
-
- /* Add __main to initializer list.
- If we are building a program instead of a shared library, do not
- do anything, since in the current version, you cannot do mallocs
- and such in the constructors. */
-
- if (main_sym != (symbol_info_t *) 0
- && ((hdr.moh_flags & MOH_EXECABLE_F) == 0))
- add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION);
-
- if (debug)
- notice ("\nUpdating header and load commands.\n\n");
-
- hdr.moh_n_load_cmds++;
- size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1));
-
- /* Create new load command map. */
- if (debug)
- notice ("load command map, %d cmds, new size %ld.\n",
- (int) hdr.moh_n_load_cmds, (long) size);
-
- load_map = (load_union_t *) xcalloc (1, size);
- load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP;
- load_map->map.ldc_header.ldci_cmd_size = size;
- load_map->map.lcm_ld_cmd_strings = cmd_strings;
- load_map->map.lcm_nentries = hdr.moh_n_load_cmds;
- load_array[hdr.moh_n_load_cmds-1].load = load_map;
-
- offset = hdr.moh_first_cmd_off;
- for (i = 0; i < hdr.moh_n_load_cmds; i++)
- {
- load_map->map.lcm_map[i] = offset;
- if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP)
- hdr.moh_load_map_cmd_off = offset;
-
- offset += load_array[i].load->hdr.ldci_cmd_size;
- }
-
- hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR;
-
- if (debug)
- print_header (&hdr);
-
- /* Write header */
- status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR);
- if (status != MO_HDR_CONV_SUCCESS)
- bad_header (status);
-
- if (debug)
- notice ("writing load commands.\n\n");
-
- /* Write load commands */
- offset = hdr.moh_first_cmd_off;
- for (i = 0; i < hdr.moh_n_load_cmds; i++)
- {
- load_union_t *load_hdr = load_array[i].load;
- size_t size = load_hdr->hdr.ldci_cmd_size;
-
- if (debug)
- print_load_command (load_hdr, offset, i);
-
- bcopy ((char *) load_hdr, (char *) (obj + offset), size);
- offset += size;
- }
- }
-
- end_file (obj_file);
-
- if (close (prog_fd))
- fatal_perror ("close %s", prog_name);
-
- if (debug)
- fprintf (stderr, "\n");
-}
-
-
-/* Add a function table to the load commands to call a function
- on initiation or termination of the process. */
-
-static void
-add_func_table (hdr_p, load_array, sym, type)
- mo_header_t *hdr_p; /* pointer to global header */
- load_all_t *load_array; /* array of ptrs to load cmds */
- symbol_info_t *sym; /* pointer to symbol entry */
- int type; /* fntc_type value */
-{
- /* Add a new load command. */
- int num_cmds = ++hdr_p->moh_n_load_cmds;
- int load_index = num_cmds - 1;
- size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t);
- load_union_t *ptr = xcalloc (1, size);
- load_all_t *load_cmd;
- int i;
-
- /* Set the unresolved address bit in the header to force the loader to be
- used, since kernel exec does not call the initialization functions. */
- hdr_p->moh_flags |= MOH_UNRESOLVED_F;
-
- load_cmd = &load_array[load_index];
- load_cmd->load = ptr;
- load_cmd->section = (char *) 0;
-
- /* Fill in func table load command. */
- ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE;
- ptr->func.ldc_header.ldci_cmd_size = size;
- ptr->func.ldc_header.ldci_section_off = 0;
- ptr->func.ldc_header.ldci_section_len = 0;
- ptr->func.fntc_type = type;
- ptr->func.fntc_nentries = 1;
-
- /* copy address, turn it from abs. address to (region,offset) if necessary. */
- /* Is the symbol already expressed as (region, offset)? */
- if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0)
- {
- ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid;
- ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff;
- }
-
- /* If not, figure out which region it's in. */
- else
- {
- mo_vm_addr_t addr = sym->si_value.abs_val;
- int found = 0;
-
- for (i = 0; i < load_index; i++)
- {
- if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION)
- {
- region_command_t *region_ptr = &load_array[i].load->region;
-
- if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0
- && addr >= region_ptr->regc_addr.vm_addr
- && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size)
- {
- ptr->func.fntc_entry_loc[0].adr_lcid = i;
- ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr;
- found++;
- break;
- }
- }
- }
-
- if (!found)
- fatal ("could not convert 0x%l.8x into a region", addr);
- }
-
- if (debug)
- notice ("%s function, region %d, offset = %ld (0x%.8lx)\n",
- type == FNTC_INITIALIZATION ? "init" : "term",
- (int) ptr->func.fntc_entry_loc[i].adr_lcid,
- (long) ptr->func.fntc_entry_loc[i].adr_sctoff,
- (long) ptr->func.fntc_entry_loc[i].adr_sctoff);
-
-}
-
-
-/* Print the global header for an OSF/rose object. */
-
-static void
-print_header (hdr_ptr)
- mo_header_t *hdr_ptr;
-{
- fprintf (stderr, "\nglobal header:\n");
- fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic);
- fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version);
- fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version);
- fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version);
- fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size);
- fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order);
- fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id);
- fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type);
- fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype);
- fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type);
- fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off);
- fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off);
- fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds);
- fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds);
- fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags);
-
- if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F)
- fprintf (stderr, ", relocatable");
-
- if (hdr_ptr->moh_flags & MOH_LINKABLE_F)
- fprintf (stderr, ", linkable");
-
- if (hdr_ptr->moh_flags & MOH_EXECABLE_F)
- fprintf (stderr, ", execable");
-
- if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F)
- fprintf (stderr, ", executable");
-
- if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F)
- fprintf (stderr, ", unresolved");
-
- fprintf (stderr, "\n\n");
- return;
-}
-
-
-/* Print a short summary of a load command. */
-
-static void
-print_load_command (load_hdr, offset, number)
- load_union_t *load_hdr;
- size_t offset;
- int number;
-{
- mo_long_t type = load_hdr->hdr.ldci_cmd_type;
- const char *type_str = (char *) 0;
-
- switch (type)
- {
- case LDC_UNDEFINED: type_str = "UNDEFINED"; break;
- case LDC_CMD_MAP: type_str = "CMD_MAP"; break;
- case LDC_INTERPRETER: type_str = "INTERPRETER"; break;
- case LDC_STRINGS: type_str = "STRINGS"; break;
- case LDC_REGION: type_str = "REGION"; break;
- case LDC_RELOC: type_str = "RELOC"; break;
- case LDC_PACKAGE: type_str = "PACKAGE"; break;
- case LDC_SYMBOLS: type_str = "SYMBOLS"; break;
- case LDC_ENTRY: type_str = "ENTRY"; break;
- case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break;
- case LDC_GEN_INFO: type_str = "GEN_INFO"; break;
- }
-
- fprintf (stderr,
- "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx",
- number,
- (long) load_hdr->hdr.ldci_cmd_size,
- (long) offset,
- (long) load_hdr->hdr.ldci_section_off,
- (long) load_hdr->hdr.ldci_section_len);
-
- if (type_str == (char *) 0)
- fprintf (stderr, ", ty: unknown (%ld)\n", (long) type);
-
- else if (type != LDC_REGION)
- fprintf (stderr, ", ty: %s\n", type_str);
-
- else
- {
- const char *region = "";
- switch (load_hdr->region.regc_usage_type)
- {
- case REG_TEXT_T: region = ", .text"; break;
- case REG_DATA_T: region = ", .data"; break;
- case REG_BSS_T: region = ", .bss"; break;
- case REG_GLUE_T: region = ", .glue"; break;
-#if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/
- case REG_RDATA_T: region = ", .rdata"; break;
- case REG_SDATA_T: region = ", .sdata"; break;
- case REG_SBSS_T: region = ", .sbss"; break;
-#endif
- }
-
- fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n",
- type_str,
- (long) load_hdr->region.regc_vm_addr,
- (long) load_hdr->region.regc_vm_size,
- region);
- }
-
- return;
-}
-
-
-/* Fatal error when {en,de}code_mach_o_header fails. */
-
-static void
-bad_header (status)
- int status;
-{
- switch (status)
- {
- case MO_ERROR_BAD_MAGIC: fatal ("bad magic number");
- case MO_ERROR_BAD_HDR_VERS: fatal ("bad header version");
- case MO_ERROR_BAD_RAW_HDR_VERS: fatal ("bad raw header version");
- case MO_ERROR_BUF2SML: fatal ("raw header buffer too small");
- case MO_ERROR_OLD_RAW_HDR_FILE: fatal ("old raw header file");
- case MO_ERROR_UNSUPPORTED_VERS: fatal ("unsupported version");
- default:
- fatal ("unknown {de,en}code_mach_o_hdr return value %d", status);
- }
-}
-
-
-/* Read a file into a memory buffer. */
-
-static struct file_info *
-read_file (name, fd, rw)
- const char *name; /* filename */
- int fd; /* file descriptor */
- int rw; /* read/write */
-{
- struct stat stat_pkt;
- struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1);
-#ifdef USE_MMAP
- static int page_size;
-#endif
-
- if (fstat (fd, &stat_pkt) < 0)
- fatal_perror ("fstat %s", name);
-
- p->name = name;
- p->size = stat_pkt.st_size;
- p->rounded_size = stat_pkt.st_size;
- p->fd = fd;
- p->rw = rw;
-
-#ifdef USE_MMAP
- if (debug)
- fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only");
-
- if (page_size == 0)
- page_size = sysconf (_SC_PAGE_SIZE);
-
- p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size;
- p->start = mmap ((caddr_t) 0,
- (rw) ? p->rounded_size : p->size,
- (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ,
- MAP_FILE | MAP_VARIABLE | MAP_SHARED,
- fd,
- 0L);
-
- if (p->start != (char *) 0 && p->start != (char *) -1)
- p->use_mmap = 1;
-
- else
-#endif /* USE_MMAP */
- {
- long len;
-
- if (debug)
- fprintf (stderr, "read %s\n", name);
-
- p->use_mmap = 0;
- p->start = xmalloc (p->size);
- if (lseek (fd, 0L, SEEK_SET) < 0)
- fatal_perror ("lseek %s 0", name);
-
- len = read (fd, p->start, p->size);
- if (len < 0)
- fatal_perror ("read %s", name);
-
- if (len != p->size)
- fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name);
- }
-
- return p;
-}
-
-/* Do anything necessary to write a file back from memory. */
-
-static void
-end_file (ptr)
- struct file_info *ptr; /* file information block */
-{
-#ifdef USE_MMAP
- if (ptr->use_mmap)
- {
- if (ptr->rw)
- {
- if (debug)
- fprintf (stderr, "msync %s\n", ptr->name);
-
- if (msync (ptr->start, ptr->rounded_size, MS_ASYNC))
- fatal_perror ("msync %s", ptr->name);
- }
-
- if (debug)
- fprintf (stderr, "munmap %s\n", ptr->name);
-
- if (munmap (ptr->start, ptr->size))
- fatal_perror ("munmap %s", ptr->name);
- }
- else
-#endif /* USE_MMAP */
- {
- if (ptr->rw)
- {
- long len;
-
- if (debug)
- fprintf (stderr, "write %s\n", ptr->name);
-
- if (lseek (ptr->fd, 0L, SEEK_SET) < 0)
- fatal_perror ("lseek %s 0", ptr->name);
-
- len = write (ptr->fd, ptr->start, ptr->size);
- if (len < 0)
- fatal_perror ("write %s", ptr->name);
-
- if (len != ptr->size)
- fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name);
- }
-
- free (ptr->start);
- }
-
- free (ptr);
-}
-
-#endif /* OBJECT_FORMAT_ROSE */
diff --git a/contrib/gcc/collect2.h b/contrib/gcc/collect2.h
index f67882025391..2434f169be5f 100644
--- a/contrib/gcc/collect2.h
+++ b/contrib/gcc/collect2.h
@@ -1,5 +1,5 @@
-/* Header file for collect/tlink routines.
- Copyright (C) 1998 Free Software Foundation, Inc.
+/* Header file for collect/tlink routines.
+ Copyright (C) 1998, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,17 +21,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_COLLECT2_H
#define GCC_COLLECT2_H
-extern void do_tlink PARAMS ((char **, char **));
+extern void do_tlink (char **, char **);
-extern void collect_execute PARAMS ((const char *, char **, const char *));
+extern void collect_execute (const char *, char **, const char *);
-extern void collect_exit PARAMS ((int)) ATTRIBUTE_NORETURN;
+extern void collect_exit (int) ATTRIBUTE_NORETURN;
-extern int collect_wait PARAMS ((const char *));
+extern int collect_wait (const char *);
-extern void dump_file PARAMS ((const char *));
+extern void dump_file (const char *);
-extern int file_exists PARAMS ((const char *));
+extern int file_exists (const char *);
extern const char *ldout;
extern const char *c_file_name;
@@ -39,12 +39,11 @@ extern struct obstack temporary_obstack;
extern char *temporary_firstobj;
extern int vflag, debug;
-extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
-extern void error PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-extern void notice PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-extern void fatal PARAMS ((const char *, ...))
- ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-extern void fatal_perror PARAMS ((const char *, ...))
+extern void fancy_abort (void) ATTRIBUTE_NORETURN;
+extern void error (const char *, ...) ATTRIBUTE_PRINTF_1;
+extern void notice (const char *, ...) ATTRIBUTE_PRINTF_1;
+extern void fatal (const char *, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+extern void fatal_perror (const char *, ...)
ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
#endif /* ! GCC_COLLECT2_H */
diff --git a/contrib/gcc/combine.c b/contrib/gcc/combine.c
index cec5a29cf511..4d06322d1e17 100644
--- a/contrib/gcc/combine.c
+++ b/contrib/gcc/combine.c
@@ -1,6 +1,6 @@
/* Optimize by combining instructions for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -53,10 +53,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
flow.c aren't completely updated:
- reg_live_length is not updated
- - reg_n_refs is not adjusted in the rare case when a register is
- no longer required in a computation
- - there are extremely rare cases (see distribute_regnotes) when a
- REG_DEAD note is lost
- a LOG_LINKS entry that refers to an insn with multiple SETs may be
removed because there is no way to know which register it was
linking
@@ -76,7 +72,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
+#include "tree.h"
#include "tm_p.h"
#include "flags.h"
#include "regs.h"
@@ -90,6 +89,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "recog.h"
#include "real.h"
#include "toplev.h"
+#include "target.h"
+
+#ifndef SHIFT_COUNT_TRUNCATED
+#define SHIFT_COUNT_TRUNCATED 0
+#endif
/* It is not safe to use ordinary gen_lowpart in combine.
Use gen_lowpart_for_combine instead. See comments there. */
@@ -173,11 +177,6 @@ static int last_call_cuid;
static rtx subst_insn;
-/* This is an insn that belongs before subst_insn, but is not currently
- on the insn chain. */
-
-static rtx subst_prev_insn;
-
/* This is the lowest CUID that `subst' is currently dealing with.
get_last_value will not return a value if the register was set at or
after this CUID. If not for this mechanism, we could get confused if
@@ -205,7 +204,6 @@ static basic_block this_basic_block;
After combine, we'll need to re-do global life analysis with
those blocks as starting points. */
static sbitmap refresh_blocks;
-static int need_refresh;
/* The next group of arrays allows the recording of the last value assigned
to (hard or pseudo) register n. We use this information to see if an
@@ -344,87 +342,79 @@ static struct undobuf undobuf;
static int n_occurrences;
-static void do_SUBST PARAMS ((rtx *, rtx));
-static void do_SUBST_INT PARAMS ((int *, int));
-static void init_reg_last_arrays PARAMS ((void));
-static void setup_incoming_promotions PARAMS ((void));
-static void set_nonzero_bits_and_sign_copies PARAMS ((rtx, rtx, void *));
-static int cant_combine_insn_p PARAMS ((rtx));
-static int can_combine_p PARAMS ((rtx, rtx, rtx, rtx, rtx *, rtx *));
-static int sets_function_arg_p PARAMS ((rtx));
-static int combinable_i3pat PARAMS ((rtx, rtx *, rtx, rtx, int, rtx *));
-static int contains_muldiv PARAMS ((rtx));
-static rtx try_combine PARAMS ((rtx, rtx, rtx, int *));
-static void undo_all PARAMS ((void));
-static void undo_commit PARAMS ((void));
-static rtx *find_split_point PARAMS ((rtx *, rtx));
-static rtx subst PARAMS ((rtx, rtx, rtx, int, int));
-static rtx combine_simplify_rtx PARAMS ((rtx, enum machine_mode, int, int));
-static rtx simplify_if_then_else PARAMS ((rtx));
-static rtx simplify_set PARAMS ((rtx));
-static rtx simplify_logical PARAMS ((rtx, int));
-static rtx expand_compound_operation PARAMS ((rtx));
-static rtx expand_field_assignment PARAMS ((rtx));
-static rtx make_extraction PARAMS ((enum machine_mode, rtx, HOST_WIDE_INT,
- rtx, unsigned HOST_WIDE_INT, int,
- int, int));
-static rtx extract_left_shift PARAMS ((rtx, int));
-static rtx make_compound_operation PARAMS ((rtx, enum rtx_code));
-static int get_pos_from_mask PARAMS ((unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *));
-static rtx force_to_mode PARAMS ((rtx, enum machine_mode,
- unsigned HOST_WIDE_INT, rtx, int));
-static rtx if_then_else_cond PARAMS ((rtx, rtx *, rtx *));
-static rtx known_cond PARAMS ((rtx, enum rtx_code, rtx, rtx));
-static int rtx_equal_for_field_assignment_p PARAMS ((rtx, rtx));
-static rtx make_field_assignment PARAMS ((rtx));
-static rtx apply_distributive_law PARAMS ((rtx));
-static rtx simplify_and_const_int PARAMS ((rtx, enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
-static unsigned HOST_WIDE_INT cached_nonzero_bits
- PARAMS ((rtx, enum machine_mode, rtx,
- enum machine_mode,
- unsigned HOST_WIDE_INT));
-static unsigned HOST_WIDE_INT nonzero_bits1
- PARAMS ((rtx, enum machine_mode, rtx,
- enum machine_mode,
- unsigned HOST_WIDE_INT));
-static unsigned int cached_num_sign_bit_copies
- PARAMS ((rtx, enum machine_mode, rtx,
- enum machine_mode, unsigned int));
-static unsigned int num_sign_bit_copies1
- PARAMS ((rtx, enum machine_mode, rtx,
- enum machine_mode, unsigned int));
-static int merge_outer_ops PARAMS ((enum rtx_code *, HOST_WIDE_INT *,
- enum rtx_code, HOST_WIDE_INT,
- enum machine_mode, int *));
-static rtx simplify_shift_const PARAMS ((rtx, enum rtx_code, enum machine_mode,
- rtx, int));
-static int recog_for_combine PARAMS ((rtx *, rtx, rtx *));
-static rtx gen_lowpart_for_combine PARAMS ((enum machine_mode, rtx));
-static rtx gen_binary PARAMS ((enum rtx_code, enum machine_mode,
- rtx, rtx));
-static enum rtx_code simplify_comparison PARAMS ((enum rtx_code, rtx *, rtx *));
-static void update_table_tick PARAMS ((rtx));
-static void record_value_for_reg PARAMS ((rtx, rtx, rtx));
-static void check_promoted_subreg PARAMS ((rtx, rtx));
-static void record_dead_and_set_regs_1 PARAMS ((rtx, rtx, void *));
-static void record_dead_and_set_regs PARAMS ((rtx));
-static int get_last_value_validate PARAMS ((rtx *, rtx, int, int));
-static rtx get_last_value PARAMS ((rtx));
-static int use_crosses_set_p PARAMS ((rtx, int));
-static void reg_dead_at_p_1 PARAMS ((rtx, rtx, void *));
-static int reg_dead_at_p PARAMS ((rtx, rtx));
-static void move_deaths PARAMS ((rtx, rtx, int, rtx, rtx *));
-static int reg_bitfield_target_p PARAMS ((rtx, rtx));
-static void distribute_notes PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx));
-static void distribute_links PARAMS ((rtx));
-static void mark_used_regs_combine PARAMS ((rtx));
-static int insn_cuid PARAMS ((rtx));
-static void record_promoted_value PARAMS ((rtx, rtx));
-static rtx reversed_comparison PARAMS ((rtx, enum machine_mode, rtx, rtx));
-static enum rtx_code combine_reversed_comparison_code PARAMS ((rtx));
-static void adjust_for_new_dest PARAMS ((rtx));
+static void do_SUBST (rtx *, rtx);
+static void do_SUBST_INT (int *, int);
+static void init_reg_last_arrays (void);
+static void setup_incoming_promotions (void);
+static void set_nonzero_bits_and_sign_copies (rtx, rtx, void *);
+static int cant_combine_insn_p (rtx);
+static int can_combine_p (rtx, rtx, rtx, rtx, rtx *, rtx *);
+static int combinable_i3pat (rtx, rtx *, rtx, rtx, int, rtx *);
+static int contains_muldiv (rtx);
+static rtx try_combine (rtx, rtx, rtx, int *);
+static void undo_all (void);
+static void undo_commit (void);
+static rtx *find_split_point (rtx *, rtx);
+static rtx subst (rtx, rtx, rtx, int, int);
+static rtx combine_simplify_rtx (rtx, enum machine_mode, int, int);
+static rtx simplify_if_then_else (rtx);
+static rtx simplify_set (rtx);
+static rtx simplify_logical (rtx, int);
+static rtx expand_compound_operation (rtx);
+static rtx expand_field_assignment (rtx);
+static rtx make_extraction (enum machine_mode, rtx, HOST_WIDE_INT,
+ rtx, unsigned HOST_WIDE_INT, int, int, int);
+static rtx extract_left_shift (rtx, int);
+static rtx make_compound_operation (rtx, enum rtx_code);
+static int get_pos_from_mask (unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT *);
+static rtx force_to_mode (rtx, enum machine_mode,
+ unsigned HOST_WIDE_INT, rtx, int);
+static rtx if_then_else_cond (rtx, rtx *, rtx *);
+static rtx known_cond (rtx, enum rtx_code, rtx, rtx);
+static int rtx_equal_for_field_assignment_p (rtx, rtx);
+static rtx make_field_assignment (rtx);
+static rtx apply_distributive_law (rtx);
+static rtx simplify_and_const_int (rtx, enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
+static unsigned HOST_WIDE_INT cached_nonzero_bits (rtx, enum machine_mode,
+ rtx, enum machine_mode,
+ unsigned HOST_WIDE_INT);
+static unsigned HOST_WIDE_INT nonzero_bits1 (rtx, enum machine_mode, rtx,
+ enum machine_mode,
+ unsigned HOST_WIDE_INT);
+static unsigned int cached_num_sign_bit_copies (rtx, enum machine_mode, rtx,
+ enum machine_mode,
+ unsigned int);
+static unsigned int num_sign_bit_copies1 (rtx, enum machine_mode, rtx,
+ enum machine_mode, unsigned int);
+static int merge_outer_ops (enum rtx_code *, HOST_WIDE_INT *, enum rtx_code,
+ HOST_WIDE_INT, enum machine_mode, int *);
+static rtx simplify_shift_const (rtx, enum rtx_code, enum machine_mode, rtx,
+ int);
+static int recog_for_combine (rtx *, rtx, rtx *);
+static rtx gen_lowpart_for_combine (enum machine_mode, rtx);
+static rtx gen_binary (enum rtx_code, enum machine_mode, rtx, rtx);
+static enum rtx_code simplify_comparison (enum rtx_code, rtx *, rtx *);
+static void update_table_tick (rtx);
+static void record_value_for_reg (rtx, rtx, rtx);
+static void check_promoted_subreg (rtx, rtx);
+static void record_dead_and_set_regs_1 (rtx, rtx, void *);
+static void record_dead_and_set_regs (rtx);
+static int get_last_value_validate (rtx *, rtx, int, int);
+static rtx get_last_value (rtx);
+static int use_crosses_set_p (rtx, int);
+static void reg_dead_at_p_1 (rtx, rtx, void *);
+static int reg_dead_at_p (rtx, rtx);
+static void move_deaths (rtx, rtx, int, rtx, rtx *);
+static int reg_bitfield_target_p (rtx, rtx);
+static void distribute_notes (rtx, rtx, rtx, rtx);
+static void distribute_links (rtx);
+static void mark_used_regs_combine (rtx);
+static int insn_cuid (rtx);
+static void record_promoted_value (rtx, rtx);
+static rtx reversed_comparison (rtx, enum machine_mode, rtx, rtx);
+static enum rtx_code combine_reversed_comparison_code (rtx);
/* Substitute NEWVAL, an rtx expression, into INTO, a place in some
insn. The substitution can be undone by undo_all. If INTO is already
@@ -433,8 +423,7 @@ static void adjust_for_new_dest PARAMS ((rtx));
the undo table. */
static void
-do_SUBST (into, newval)
- rtx *into, newval;
+do_SUBST (rtx *into, rtx newval)
{
struct undo *buf;
rtx oldval = *into;
@@ -467,12 +456,12 @@ do_SUBST (into, newval)
|| (GET_CODE (oldval) == ZERO_EXTEND
&& GET_CODE (XEXP (oldval, 0)) == CONST_INT))
abort ();
- }
+ }
if (undobuf.frees)
buf = undobuf.frees, undobuf.frees = buf->next;
else
- buf = (struct undo *) xmalloc (sizeof (struct undo));
+ buf = xmalloc (sizeof (struct undo));
buf->is_int = 0;
buf->where.r = into;
@@ -489,8 +478,7 @@ do_SUBST (into, newval)
not safe. */
static void
-do_SUBST_INT (into, newval)
- int *into, newval;
+do_SUBST_INT (int *into, int newval)
{
struct undo *buf;
int oldval = *into;
@@ -501,7 +489,7 @@ do_SUBST_INT (into, newval)
if (undobuf.frees)
buf = undobuf.frees, undobuf.frees = buf->next;
else
- buf = (struct undo *) xmalloc (sizeof (struct undo));
+ buf = xmalloc (sizeof (struct undo));
buf->is_int = 1;
buf->where.i = into;
@@ -519,9 +507,7 @@ do_SUBST_INT (into, newval)
Return nonzero if the combiner has turned an indirect jump
instruction into a direct jump. */
int
-combine_instructions (f, nregs)
- rtx f;
- unsigned int nregs;
+combine_instructions (rtx f, unsigned int nregs)
{
rtx insn, next;
#ifdef HAVE_cc0
@@ -539,23 +525,18 @@ combine_instructions (f, nregs)
combine_max_regno = nregs;
- reg_nonzero_bits = ((unsigned HOST_WIDE_INT *)
- xcalloc (nregs, sizeof (unsigned HOST_WIDE_INT)));
- reg_sign_bit_copies
- = (unsigned char *) xcalloc (nregs, sizeof (unsigned char));
-
- reg_last_death = (rtx *) xmalloc (nregs * sizeof (rtx));
- reg_last_set = (rtx *) xmalloc (nregs * sizeof (rtx));
- reg_last_set_value = (rtx *) xmalloc (nregs * sizeof (rtx));
- reg_last_set_table_tick = (int *) xmalloc (nregs * sizeof (int));
- reg_last_set_label = (int *) xmalloc (nregs * sizeof (int));
- reg_last_set_invalid = (char *) xmalloc (nregs * sizeof (char));
- reg_last_set_mode
- = (enum machine_mode *) xmalloc (nregs * sizeof (enum machine_mode));
- reg_last_set_nonzero_bits
- = (unsigned HOST_WIDE_INT *) xmalloc (nregs * sizeof (HOST_WIDE_INT));
- reg_last_set_sign_bit_copies
- = (char *) xmalloc (nregs * sizeof (char));
+ reg_nonzero_bits = xcalloc (nregs, sizeof (unsigned HOST_WIDE_INT));
+ reg_sign_bit_copies = xcalloc (nregs, sizeof (unsigned char));
+
+ reg_last_death = xmalloc (nregs * sizeof (rtx));
+ reg_last_set = xmalloc (nregs * sizeof (rtx));
+ reg_last_set_value = xmalloc (nregs * sizeof (rtx));
+ reg_last_set_table_tick = xmalloc (nregs * sizeof (int));
+ reg_last_set_label = xmalloc (nregs * sizeof (int));
+ reg_last_set_invalid = xmalloc (nregs * sizeof (char));
+ reg_last_set_mode = xmalloc (nregs * sizeof (enum machine_mode));
+ reg_last_set_nonzero_bits = xmalloc (nregs * sizeof (HOST_WIDE_INT));
+ reg_last_set_sign_bit_copies = xmalloc (nregs * sizeof (char));
init_reg_last_arrays ();
@@ -567,7 +548,7 @@ combine_instructions (f, nregs)
if (INSN_UID (insn) > i)
i = INSN_UID (insn);
- uid_cuid = (int *) xmalloc ((i + 1) * sizeof (int));
+ uid_cuid = xmalloc ((i + 1) * sizeof (int));
max_uid_cuid = i;
nonzero_bits_mode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
@@ -590,15 +571,10 @@ combine_instructions (f, nregs)
label_tick = 1;
- /* We need to initialize it here, because record_dead_and_set_regs may call
- get_last_value. */
- subst_prev_insn = NULL_RTX;
-
setup_incoming_promotions ();
refresh_blocks = sbitmap_alloc (last_basic_block);
sbitmap_zero (refresh_blocks);
- need_refresh = 0;
for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
{
@@ -636,8 +612,8 @@ combine_instructions (f, nregs)
FOR_EACH_BB (this_basic_block)
{
- for (insn = this_basic_block->head;
- insn != NEXT_INSN (this_basic_block->end);
+ for (insn = BB_HEAD (this_basic_block);
+ insn != NEXT_INSN (BB_END (this_basic_block));
insn = next ? next : NEXT_INSN (insn))
{
next = 0;
@@ -808,50 +784,51 @@ combine_instructions (f, nregs)
/* Wipe the reg_last_xxx arrays in preparation for another pass. */
static void
-init_reg_last_arrays ()
+init_reg_last_arrays (void)
{
unsigned int nregs = combine_max_regno;
- memset ((char *) reg_last_death, 0, nregs * sizeof (rtx));
- memset ((char *) reg_last_set, 0, nregs * sizeof (rtx));
- memset ((char *) reg_last_set_value, 0, nregs * sizeof (rtx));
- memset ((char *) reg_last_set_table_tick, 0, nregs * sizeof (int));
- memset ((char *) reg_last_set_label, 0, nregs * sizeof (int));
+ memset (reg_last_death, 0, nregs * sizeof (rtx));
+ memset (reg_last_set, 0, nregs * sizeof (rtx));
+ memset (reg_last_set_value, 0, nregs * sizeof (rtx));
+ memset (reg_last_set_table_tick, 0, nregs * sizeof (int));
+ memset (reg_last_set_label, 0, nregs * sizeof (int));
memset (reg_last_set_invalid, 0, nregs * sizeof (char));
- memset ((char *) reg_last_set_mode, 0, nregs * sizeof (enum machine_mode));
- memset ((char *) reg_last_set_nonzero_bits, 0, nregs * sizeof (HOST_WIDE_INT));
+ memset (reg_last_set_mode, 0, nregs * sizeof (enum machine_mode));
+ memset (reg_last_set_nonzero_bits, 0, nregs * sizeof (HOST_WIDE_INT));
memset (reg_last_set_sign_bit_copies, 0, nregs * sizeof (char));
}
/* Set up any promoted values for incoming argument registers. */
static void
-setup_incoming_promotions ()
+setup_incoming_promotions (void)
{
-#ifdef PROMOTE_FUNCTION_ARGS
unsigned int regno;
rtx reg;
enum machine_mode mode;
int unsignedp;
rtx first = get_insns ();
+ if (targetm.calls.promote_function_args (TREE_TYPE (cfun->decl)))
+ {
#ifndef OUTGOING_REGNO
#define OUTGOING_REGNO(N) N
#endif
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- /* Check whether this register can hold an incoming pointer
- argument. FUNCTION_ARG_REGNO_P tests outgoing register
- numbers, so translate if necessary due to register windows. */
- if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (regno))
- && (reg = promoted_input_arg (regno, &mode, &unsignedp)) != 0)
- {
- record_value_for_reg
- (reg, first, gen_rtx_fmt_e ((unsignedp ? ZERO_EXTEND
- : SIGN_EXTEND),
- GET_MODE (reg),
- gen_rtx_CLOBBER (mode, const0_rtx)));
- }
-#endif
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ /* Check whether this register can hold an incoming pointer
+ argument. FUNCTION_ARG_REGNO_P tests outgoing register
+ numbers, so translate if necessary due to register windows. */
+ if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (regno))
+ && (reg = promoted_input_arg (regno, &mode, &unsignedp)) != 0)
+ {
+ record_value_for_reg
+ (reg, first, gen_rtx_fmt_e ((unsignedp ? ZERO_EXTEND
+ : SIGN_EXTEND),
+ GET_MODE (reg),
+ gen_rtx_CLOBBER (mode, const0_rtx)));
+ }
+ }
}
/* Called via note_stores. If X is a pseudo that is narrower than
@@ -866,10 +843,8 @@ setup_incoming_promotions ()
by any set of X. */
static void
-set_nonzero_bits_and_sign_copies (x, set, data)
- rtx x;
- rtx set;
- void *data ATTRIBUTE_UNUSED;
+set_nonzero_bits_and_sign_copies (rtx x, rtx set,
+ void *data ATTRIBUTE_UNUSED)
{
unsigned int num;
@@ -951,12 +926,8 @@ set_nonzero_bits_and_sign_copies (x, set, data)
will return 1. */
static int
-can_combine_p (insn, i3, pred, succ, pdest, psrc)
- rtx insn;
- rtx i3;
- rtx pred ATTRIBUTE_UNUSED;
- rtx succ;
- rtx *pdest, *psrc;
+can_combine_p (rtx insn, rtx i3, rtx pred ATTRIBUTE_UNUSED, rtx succ,
+ rtx *pdest, rtx *psrc)
{
int i;
rtx set = 0, src, dest;
@@ -991,6 +962,7 @@ can_combine_p (insn, i3, pred, succ, pdest, psrc)
for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
{
rtx elt = XVECEXP (PATTERN (insn), 0, i);
+ rtx note;
switch (GET_CODE (elt))
{
@@ -1041,6 +1013,8 @@ can_combine_p (insn, i3, pred, succ, pdest, psrc)
/* Ignore SETs whose result isn't used but not those that
have side-effects. */
if (find_reg_note (insn, REG_UNUSED, SET_DEST (elt))
+ && (!(note = find_reg_note (insn, REG_EH_REGION, NULL_RTX))
+ || INTVAL (XEXP (note, 0)) <= 0)
&& ! side_effects_p (elt))
break;
@@ -1075,8 +1049,6 @@ can_combine_p (insn, i3, pred, succ, pdest, psrc)
/* Don't eliminate a store in the stack pointer. */
if (dest == stack_pointer_rtx
- /* If we couldn't eliminate a field assignment, we can't combine. */
- || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART
/* Don't combine with an insn that sets a register to itself if it has
a REG_EQUAL note. This may be part of a REG_NO_CONFLICT sequence. */
|| (rtx_equal_p (src, dest) && find_reg_note (insn, REG_EQUAL, NULL_RTX))
@@ -1239,46 +1211,6 @@ can_combine_p (insn, i3, pred, succ, pdest, psrc)
return 1;
}
-/* Check if PAT is an insn - or a part of it - used to set up an
- argument for a function in a hard register. */
-
-static int
-sets_function_arg_p (pat)
- rtx pat;
-{
- int i;
- rtx inner_dest;
-
- switch (GET_CODE (pat))
- {
- case INSN:
- return sets_function_arg_p (PATTERN (pat));
-
- case PARALLEL:
- for (i = XVECLEN (pat, 0); --i >= 0;)
- if (sets_function_arg_p (XVECEXP (pat, 0, i)))
- return 1;
-
- break;
-
- case SET:
- inner_dest = SET_DEST (pat);
- while (GET_CODE (inner_dest) == STRICT_LOW_PART
- || GET_CODE (inner_dest) == SUBREG
- || GET_CODE (inner_dest) == ZERO_EXTRACT)
- inner_dest = XEXP (inner_dest, 0);
-
- return (GET_CODE (inner_dest) == REG
- && REGNO (inner_dest) < FIRST_PSEUDO_REGISTER
- && FUNCTION_ARG_REGNO_P (REGNO (inner_dest)));
-
- default:
- break;
- }
-
- return 0;
-}
-
/* LOC is the location within I3 that contains its pattern or the component
of a PARALLEL of the pattern. We validate that it is valid for combining.
@@ -1317,61 +1249,31 @@ sets_function_arg_p (pat)
Return 1 if the combination is valid, zero otherwise. */
static int
-combinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed)
- rtx i3;
- rtx *loc;
- rtx i2dest;
- rtx i1dest;
- int i1_not_in_src;
- rtx *pi3dest_killed;
+combinable_i3pat (rtx i3, rtx *loc, rtx i2dest, rtx i1dest,
+ int i1_not_in_src, rtx *pi3dest_killed)
{
rtx x = *loc;
if (GET_CODE (x) == SET)
{
- rtx set = expand_field_assignment (x);
+ rtx set = x ;
rtx dest = SET_DEST (set);
rtx src = SET_SRC (set);
rtx inner_dest = dest;
-#if 0
- rtx inner_src = src;
-#endif
-
- SUBST (*loc, set);
-
while (GET_CODE (inner_dest) == STRICT_LOW_PART
|| GET_CODE (inner_dest) == SUBREG
|| GET_CODE (inner_dest) == ZERO_EXTRACT)
inner_dest = XEXP (inner_dest, 0);
- /* We probably don't need this any more now that LIMIT_RELOAD_CLASS
- was added. */
-#if 0
- while (GET_CODE (inner_src) == STRICT_LOW_PART
- || GET_CODE (inner_src) == SUBREG
- || GET_CODE (inner_src) == ZERO_EXTRACT)
- inner_src = XEXP (inner_src, 0);
-
- /* If it is better that two different modes keep two different pseudos,
- avoid combining them. This avoids producing the following pattern
- on a 386:
- (set (subreg:SI (reg/v:QI 21) 0)
- (lshiftrt:SI (reg/v:SI 20)
- (const_int 24)))
- If that were made, reload could not handle the pair of
- reg 20/21, since it would try to get any GENERAL_REGS
- but some of them don't handle QImode. */
-
- if (rtx_equal_p (inner_src, i2dest)
- && GET_CODE (inner_dest) == REG
- && ! MODES_TIEABLE_P (GET_MODE (i2dest), GET_MODE (inner_dest)))
- return 0;
-#endif
-
- /* Check for the case where I3 modifies its output, as
- discussed above. */
- if ((inner_dest != dest
+ /* Check for the case where I3 modifies its output, as discussed
+ above. We don't want to prevent pseudos from being combined
+ into the address of a MEM, so only prevent the combination if
+ i1 or i2 set the same MEM. */
+ if ((inner_dest != dest &&
+ (GET_CODE (inner_dest) != MEM
+ || rtx_equal_p (i2dest, inner_dest)
+ || (i1dest && rtx_equal_p (i1dest, inner_dest)))
&& (reg_overlap_mentioned_p (i2dest, inner_dest)
|| (i1dest && reg_overlap_mentioned_p (i1dest, inner_dest))))
@@ -1433,8 +1335,7 @@ combinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed)
and division. We don't count multiplications by powers of two here. */
static int
-contains_muldiv (x)
- rtx x;
+contains_muldiv (rtx x)
{
switch (GET_CODE (x))
{
@@ -1465,8 +1366,7 @@ contains_muldiv (x)
can't perform combinations. */
static int
-cant_combine_insn_p (insn)
- rtx insn;
+cant_combine_insn_p (rtx insn)
{
rtx set;
rtx src, dest;
@@ -1477,10 +1377,10 @@ cant_combine_insn_p (insn)
if (! INSN_P (insn))
return 1;
- /* Never combine loads and stores involving hard regs. The register
- allocator can usually handle such reg-reg moves by tying. If we allow
- the combiner to make substitutions of hard regs, we risk aborting in
- reload on machines that have SMALL_REGISTER_CLASSES.
+ /* Never combine loads and stores involving hard regs that are likely
+ to be spilled. The register allocator can usually handle such
+ reg-reg moves by tying. If we allow the combiner to make
+ substitutions of likely-spilled regs, we may abort in reload.
As an exception, we allow combinations involving fixed regs; these are
not available to the register allocator so there's no risk involved. */
@@ -1495,9 +1395,11 @@ cant_combine_insn_p (insn)
dest = SUBREG_REG (dest);
if (REG_P (src) && REG_P (dest)
&& ((REGNO (src) < FIRST_PSEUDO_REGISTER
- && ! fixed_regs[REGNO (src)])
+ && ! fixed_regs[REGNO (src)]
+ && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (src))))
|| (REGNO (dest) < FIRST_PSEUDO_REGISTER
- && ! fixed_regs[REGNO (dest)])))
+ && ! fixed_regs[REGNO (dest)]
+ && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (dest))))))
return 1;
return 0;
@@ -1509,8 +1411,7 @@ cant_combine_insn_p (insn)
the results of the insn and a LOG_LINK pointing to the insn. */
static void
-adjust_for_new_dest (insn)
- rtx insn;
+adjust_for_new_dest (rtx insn)
{
rtx *loc;
@@ -1548,9 +1449,7 @@ adjust_for_new_dest (insn)
new direct jump instruction. */
static rtx
-try_combine (i3, i2, i1, new_direct_jump_p)
- rtx i3, i2, i1;
- int *new_direct_jump_p;
+try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
{
/* New patterns for I3 and I2, respectively. */
rtx newpat, newi2pat = 0;
@@ -1727,7 +1626,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
abort ();
lo &= ~(UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1);
- lo |= (INTVAL (SET_SRC (PATTERN (i3)))
+ lo |= (INTVAL (SET_SRC (PATTERN (i3)))
& (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1));
}
else if (HOST_BITS_PER_WIDE_INT == BITS_PER_WORD)
@@ -1799,11 +1698,10 @@ try_combine (i3, i2, i1, new_direct_jump_p)
never appear in the insn stream so giving it the same INSN_UID
as I2 will not cause a problem. */
- subst_prev_insn = i1
- = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
- BLOCK_FOR_INSN (i2), INSN_SCOPE (i2),
- XVECEXP (PATTERN (i2), 0, 1), -1, NULL_RTX,
- NULL_RTX);
+ i1 = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
+ BLOCK_FOR_INSN (i2), INSN_LOCATOR (i2),
+ XVECEXP (PATTERN (i2), 0, 1), -1, NULL_RTX,
+ NULL_RTX);
SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
@@ -1962,7 +1860,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
&& XEXP (SET_SRC (PATTERN (i3)), 1) == const0_rtx
&& rtx_equal_p (XEXP (SET_SRC (PATTERN (i3)), 0), i2dest))
{
-#ifdef EXTRA_CC_MODES
+#ifdef SELECT_CC_MODE
rtx *cc_use;
enum machine_mode compare_mode;
#endif
@@ -1972,7 +1870,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
i2_is_used = 1;
-#ifdef EXTRA_CC_MODES
+#ifdef SELECT_CC_MODE
/* See if a COMPARE with the operand we substituted in should be done
with the mode that is currently being used. If not, do the same
processing we do in `subst' for a SET; namely, if the destination
@@ -2121,7 +2019,8 @@ try_combine (i3, i2, i1, new_direct_jump_p)
insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
/* If the result isn't valid, see if it is a PARALLEL of two SETs where
- the second SET's destination is a register that is unused. In that case,
+ the second SET's destination is a register that is unused and isn't
+ marked as an instruction that might trap in an EH region. In that case,
we just need the first SET. This can occur when simplifying a divmod
insn. We *must* test for this case here because the code below that
splits two independent SETs doesn't handle this case correctly when it
@@ -2133,33 +2032,45 @@ try_combine (i3, i2, i1, new_direct_jump_p)
&& XVECLEN (newpat, 0) == 2
&& GET_CODE (XVECEXP (newpat, 0, 0)) == SET
&& GET_CODE (XVECEXP (newpat, 0, 1)) == SET
- && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1))) == REG
- && find_reg_note (i3, REG_UNUSED, SET_DEST (XVECEXP (newpat, 0, 1)))
- && ! side_effects_p (SET_SRC (XVECEXP (newpat, 0, 1)))
&& asm_noperands (newpat) < 0)
{
- newpat = XVECEXP (newpat, 0, 0);
- insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
- }
+ rtx set0 = XVECEXP (newpat, 0, 0);
+ rtx set1 = XVECEXP (newpat, 0, 1);
+ rtx note;
- else if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL
- && XVECLEN (newpat, 0) == 2
- && GET_CODE (XVECEXP (newpat, 0, 0)) == SET
- && GET_CODE (XVECEXP (newpat, 0, 1)) == SET
- && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0))) == REG
- && find_reg_note (i3, REG_UNUSED, SET_DEST (XVECEXP (newpat, 0, 0)))
- && ! side_effects_p (SET_SRC (XVECEXP (newpat, 0, 0)))
- && asm_noperands (newpat) < 0)
- {
- newpat = XVECEXP (newpat, 0, 1);
- insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
-
- if (insn_code_number >= 0)
+ if (((GET_CODE (SET_DEST (set1)) == REG
+ && find_reg_note (i3, REG_UNUSED, SET_DEST (set1)))
+ || (GET_CODE (SET_DEST (set1)) == SUBREG
+ && find_reg_note (i3, REG_UNUSED, SUBREG_REG (SET_DEST (set1)))))
+ && (!(note = find_reg_note (i3, REG_EH_REGION, NULL_RTX))
+ || INTVAL (XEXP (note, 0)) <= 0)
+ && ! side_effects_p (SET_SRC (set1)))
{
- /* If we will be able to accept this, we have made a change to the
- destination of I3. This requires us to do a few adjustments. */
- PATTERN (i3) = newpat;
- adjust_for_new_dest (i3);
+ newpat = set0;
+ insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
+ }
+
+ else if (((GET_CODE (SET_DEST (set0)) == REG
+ && find_reg_note (i3, REG_UNUSED, SET_DEST (set0)))
+ || (GET_CODE (SET_DEST (set0)) == SUBREG
+ && find_reg_note (i3, REG_UNUSED,
+ SUBREG_REG (SET_DEST (set0)))))
+ && (!(note = find_reg_note (i3, REG_EH_REGION, NULL_RTX))
+ || INTVAL (XEXP (note, 0)) <= 0)
+ && ! side_effects_p (SET_SRC (set0)))
+ {
+ newpat = set1;
+ insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
+
+ if (insn_code_number >= 0)
+ {
+ /* If we will be able to accept this, we have made a
+ change to the destination of I3. This requires us to
+ do a few adjustments. */
+
+ PATTERN (i3) = newpat;
+ adjust_for_new_dest (i3);
+ }
}
}
@@ -2446,7 +2357,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
for (insn = NEXT_INSN (i3);
insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR
- || insn != this_basic_block->next_bb->head);
+ || insn != BB_HEAD (this_basic_block->next_bb));
insn = NEXT_INSN (insn))
{
if (INSN_P (insn) && reg_referenced_p (ni2dest, PATTERN (insn)))
@@ -2562,7 +2473,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
REG_N_DEATHS (REGNO (XEXP (note, 0)))++;
distribute_notes (new_other_notes, undobuf.other_insn,
- undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX);
+ undobuf.other_insn, NULL_RTX);
}
#ifdef HAVE_cc0
/* If I2 is the setter CC0 and I3 is the user CC0 then check whether
@@ -2586,15 +2497,6 @@ try_combine (i3, i2, i1, new_direct_jump_p)
rtx i3links, i2links, i1links = 0;
rtx midnotes = 0;
unsigned int regno;
- /* Compute which registers we expect to eliminate. newi2pat may be setting
- either i3dest or i2dest, so we must check it. Also, i1dest may be the
- same as i3dest, in which case newi2pat may be setting i1dest. */
- rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat))
- || i2dest_in_i2src || i2dest_in_i1src
- ? 0 : i2dest);
- rtx elim_i1 = (i1 == 0 || i1dest_in_i1src
- || (newi2pat && reg_set_p (i1dest, newi2pat))
- ? 0 : i1dest);
/* Get the old REG_NOTES and LOG_LINKS from all our insns and
clear them. */
@@ -2664,7 +2566,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
SET_DEST (XVECEXP (PATTERN (i2), 0, i))))
for (temp = NEXT_INSN (i2);
temp && (this_basic_block->next_bb == EXIT_BLOCK_PTR
- || this_basic_block->head != temp);
+ || BB_HEAD (this_basic_block) != temp);
temp = NEXT_INSN (temp))
if (temp != i3 && INSN_P (temp))
for (link = LOG_LINKS (temp); link; link = XEXP (link, 1))
@@ -2725,17 +2627,13 @@ try_combine (i3, i2, i1, new_direct_jump_p)
/* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */
if (i3notes)
- distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX,
- elim_i2, elim_i1);
+ distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX);
if (i2notes)
- distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX,
- elim_i2, elim_i1);
+ distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX);
if (i1notes)
- distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX,
- elim_i2, elim_i1);
+ distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX);
if (midnotes)
- distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
- elim_i2, elim_i1);
+ distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX);
/* Distribute any notes added to I2 or I3 by recog_for_combine. We
know these are REG_UNUSED and want them to go to the desired insn,
@@ -2748,7 +2646,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
if (GET_CODE (XEXP (temp, 0)) == REG)
REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
- distribute_notes (new_i2_notes, i2, i2, NULL_RTX, NULL_RTX, NULL_RTX);
+ distribute_notes (new_i2_notes, i2, i2, NULL_RTX);
}
if (new_i3_notes)
@@ -2757,7 +2655,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
if (GET_CODE (XEXP (temp, 0)) == REG)
REG_N_DEATHS (REGNO (XEXP (temp, 0)))++;
- distribute_notes (new_i3_notes, i3, i3, NULL_RTX, NULL_RTX, NULL_RTX);
+ distribute_notes (new_i3_notes, i3, i3, NULL_RTX);
}
/* If I3DEST was used in I3SRC, it really died in I3. We may need to
@@ -2775,12 +2673,11 @@ try_combine (i3, i2, i1, new_direct_jump_p)
if (newi2pat && reg_set_p (i3dest_killed, newi2pat))
distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
NULL_RTX),
- NULL_RTX, i2, NULL_RTX, elim_i2, elim_i1);
+ NULL_RTX, i2, NULL_RTX);
else
distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed,
NULL_RTX),
- NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
- elim_i2, elim_i1);
+ NULL_RTX, i3, newi2pat ? i2 : NULL_RTX);
}
if (i2dest_in_i2src)
@@ -2790,11 +2687,10 @@ try_combine (i3, i2, i1, new_direct_jump_p)
if (newi2pat && reg_set_p (i2dest, newi2pat))
distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
- NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
+ NULL_RTX, i2, NULL_RTX);
else
distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX),
- NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
- NULL_RTX, NULL_RTX);
+ NULL_RTX, i3, newi2pat ? i2 : NULL_RTX);
}
if (i1dest_in_i1src)
@@ -2804,11 +2700,10 @@ try_combine (i3, i2, i1, new_direct_jump_p)
if (newi2pat && reg_set_p (i1dest, newi2pat))
distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
- NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX);
+ NULL_RTX, i2, NULL_RTX);
else
distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX),
- NULL_RTX, i3, newi2pat ? i2 : NULL_RTX,
- NULL_RTX, NULL_RTX);
+ NULL_RTX, i3, newi2pat ? i2 : NULL_RTX);
}
distribute_links (i3links);
@@ -2880,6 +2775,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
if (returnjump_p (i3) || any_uncondjump_p (i3))
{
*new_direct_jump_p = 1;
+ mark_jump_label (PATTERN (i3), i3, 0);
if ((temp = next_nonnote_insn (i3)) == NULL_RTX
|| GET_CODE (temp) != BARRIER)
@@ -2896,7 +2792,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
|| GET_CODE (temp) != BARRIER)
emit_barrier_after (undobuf.other_insn);
}
-
+
/* An NOOP jump does not need barrier, but it does need cleaning up
of CFG. */
if (GET_CODE (newpat) == SET
@@ -2908,10 +2804,6 @@ try_combine (i3, i2, i1, new_direct_jump_p)
combine_successes++;
undo_commit ();
- /* Clear this here, so that subsequent get_last_value calls are not
- affected. */
- subst_prev_insn = NULL_RTX;
-
if (added_links_insn
&& (newi2pat == 0 || INSN_CUID (added_links_insn) < INSN_CUID (i2))
&& INSN_CUID (added_links_insn) < INSN_CUID (i3))
@@ -2923,7 +2815,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
/* Undo all the modifications recorded in undobuf. */
static void
-undo_all ()
+undo_all (void)
{
struct undo *undo, *next;
@@ -2940,17 +2832,13 @@ undo_all ()
}
undobuf.undos = 0;
-
- /* Clear this here, so that subsequent get_last_value calls are not
- affected. */
- subst_prev_insn = NULL_RTX;
}
/* We've committed to accepting the changes we made. Move all
of the undos to the free list. */
static void
-undo_commit ()
+undo_commit (void)
{
struct undo *undo, *next;
@@ -2972,9 +2860,7 @@ undo_commit ()
two insns. */
static rtx *
-find_split_point (loc, insn)
- rtx *loc;
- rtx insn;
+find_split_point (rtx *loc, rtx insn)
{
rtx x = *loc;
enum rtx_code code = GET_CODE (x);
@@ -3183,7 +3069,7 @@ find_split_point (loc, insn)
break;
case NE:
- /* if STORE_FLAG_VALUE is -1, this is (NE X 0) and only one bit of X
+ /* If STORE_FLAG_VALUE is -1, this is (NE X 0) and only one bit of X
is known to be on, this can be converted into a NEG of a shift. */
if (STORE_FLAG_VALUE == -1 && XEXP (SET_SRC (x), 1) == const0_rtx
&& GET_MODE (SET_SRC (x)) == GET_MODE (XEXP (SET_SRC (x), 0))
@@ -3389,10 +3275,7 @@ find_split_point (loc, insn)
by copying if `n_occurrences' is nonzero. */
static rtx
-subst (x, from, to, in_dest, unique_copy)
- rtx x, from, to;
- int in_dest;
- int unique_copy;
+subst (rtx x, rtx from, rtx to, int in_dest, int unique_copy)
{
enum rtx_code code = GET_CODE (x);
enum machine_mode op0_mode = VOIDmode;
@@ -3605,7 +3488,9 @@ subst (x, from, to, in_dest, unique_copy)
if (GET_CODE (new) == CLOBBER && XEXP (new, 0) == const0_rtx)
return new;
- if (GET_CODE (new) == CONST_INT && GET_CODE (x) == SUBREG)
+ if (GET_CODE (x) == SUBREG
+ && (GET_CODE (new) == CONST_INT
+ || GET_CODE (new) == CONST_DOUBLE))
{
enum machine_mode mode = GET_MODE (x);
@@ -3662,11 +3547,8 @@ subst (x, from, to, in_dest, unique_copy)
X is returned; IN_DEST is nonzero if we are inside a SET_DEST. */
static rtx
-combine_simplify_rtx (x, op0_mode, last, in_dest)
- rtx x;
- enum machine_mode op0_mode;
- int last;
- int in_dest;
+combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int last,
+ int in_dest)
{
enum rtx_code code = GET_CODE (x);
enum machine_mode mode = GET_MODE (x);
@@ -3765,15 +3647,19 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
return x;
/* Simplify the alternative arms; this may collapse the true and
- false arms to store-flag values. */
- true_rtx = subst (true_rtx, pc_rtx, pc_rtx, 0, 0);
- false_rtx = subst (false_rtx, pc_rtx, pc_rtx, 0, 0);
+ false arms to store-flag values. Be careful to use copy_rtx
+ here since true_rtx or false_rtx might share RTL with x as a
+ result of the if_then_else_cond call above. */
+ true_rtx = subst (copy_rtx (true_rtx), pc_rtx, pc_rtx, 0, 0);
+ false_rtx = subst (copy_rtx (false_rtx), pc_rtx, pc_rtx, 0, 0);
/* If true_rtx and false_rtx are not general_operands, an if_then_else
is unlikely to be simpler. */
if (general_operand (true_rtx, VOIDmode)
&& general_operand (false_rtx, VOIDmode))
{
+ enum rtx_code reversed;
+
/* Restarting if we generate a store-flag expression will cause
us to loop. Just drop through in this case. */
@@ -3782,9 +3668,10 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
if (true_rtx == const_true_rtx && false_rtx == const0_rtx)
x = gen_binary (cond_code, mode, cond, cop1);
else if (true_rtx == const0_rtx && false_rtx == const_true_rtx
- && reverse_condition (cond_code) != UNKNOWN)
- x = gen_binary (reverse_condition (cond_code),
- mode, cond, cop1);
+ && ((reversed = reversed_comparison_code_parts
+ (cond_code, cond, cop1, NULL))
+ != UNKNOWN))
+ x = gen_binary (reversed, mode, cond, cop1);
/* Likewise, we can make the negate of a comparison operation
if the result values are - STORE_FLAG_VALUE and zero. */
@@ -3797,11 +3684,13 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
mode);
else if (GET_CODE (false_rtx) == CONST_INT
&& INTVAL (false_rtx) == - STORE_FLAG_VALUE
- && true_rtx == const0_rtx)
+ && true_rtx == const0_rtx
+ && ((reversed = reversed_comparison_code_parts
+ (cond_code, cond, cop1, NULL))
+ != UNKNOWN))
x = simplify_gen_unary (NEG, mode,
- gen_binary (reverse_condition
- (cond_code),
- mode, cond, cop1),
+ gen_binary (reversed, mode,
+ cond, cop1),
mode);
else
return gen_rtx_IF_THEN_ELSE (mode,
@@ -3821,6 +3710,8 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
switch (GET_RTX_CLASS (code))
{
case '1':
+ if (op0_mode == VOIDmode)
+ op0_mode = GET_MODE (XEXP (x, 0));
temp = simplify_unary_operation (code, mode, XEXP (x, 0), op0_mode);
break;
case '<':
@@ -3966,33 +3857,6 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
break;
case NOT:
- /* (not (plus X -1)) can become (neg X). */
- if (GET_CODE (XEXP (x, 0)) == PLUS
- && XEXP (XEXP (x, 0), 1) == constm1_rtx)
- return gen_rtx_NEG (mode, XEXP (XEXP (x, 0), 0));
-
- /* Similarly, (not (neg X)) is (plus X -1). */
- if (GET_CODE (XEXP (x, 0)) == NEG)
- return gen_rtx_PLUS (mode, XEXP (XEXP (x, 0), 0), constm1_rtx);
-
- /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
- if (GET_CODE (XEXP (x, 0)) == XOR
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
- && (temp = simplify_unary_operation (NOT, mode,
- XEXP (XEXP (x, 0), 1),
- mode)) != 0)
- return gen_binary (XOR, mode, XEXP (XEXP (x, 0), 0), temp);
-
- /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for operands
- other than 1, but that is not valid. We could do a similar
- simplification for (not (lshiftrt C X)) where C is just the sign bit,
- but this doesn't seem common enough to bother with. */
- if (GET_CODE (XEXP (x, 0)) == ASHIFT
- && XEXP (XEXP (x, 0), 0) == const1_rtx)
- return gen_rtx_ROTATE (mode, simplify_gen_unary (NOT, mode,
- const1_rtx, mode),
- XEXP (XEXP (x, 0), 1));
-
if (GET_CODE (XEXP (x, 0)) == SUBREG
&& subreg_lowpart_p (XEXP (x, 0))
&& (GET_MODE_SIZE (GET_MODE (XEXP (x, 0)))
@@ -4009,24 +3873,6 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
return gen_lowpart_for_combine (mode, x);
}
- /* If STORE_FLAG_VALUE is -1, (not (comparison foo bar)) can be done by
- reversing the comparison code if valid. */
- if (STORE_FLAG_VALUE == -1
- && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
- && (reversed = reversed_comparison (x, mode, XEXP (XEXP (x, 0), 0),
- XEXP (XEXP (x, 0), 1))))
- return reversed;
-
- /* (not (ashiftrt foo C)) where C is the number of bits in FOO minus 1
- is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1, so we can
- perform the above simplification. */
-
- if (STORE_FLAG_VALUE == -1
- && GET_CODE (XEXP (x, 0)) == ASHIFTRT
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
- && INTVAL (XEXP (XEXP (x, 0), 1)) == GET_MODE_BITSIZE (mode) - 1)
- return gen_rtx_GE (mode, XEXP (XEXP (x, 0), 0), const0_rtx);
-
/* Apply De Morgan's laws to reduce number of patterns for machines
with negating logical insns (and-not, nand, etc.). If result has
only one NOT, put it first, since that is how the patterns are
@@ -4057,61 +3903,12 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
break;
case NEG:
- /* (neg (plus X 1)) can become (not X). */
- if (GET_CODE (XEXP (x, 0)) == PLUS
- && XEXP (XEXP (x, 0), 1) == const1_rtx)
- return gen_rtx_NOT (mode, XEXP (XEXP (x, 0), 0));
-
- /* Similarly, (neg (not X)) is (plus X 1). */
- if (GET_CODE (XEXP (x, 0)) == NOT)
- return plus_constant (XEXP (XEXP (x, 0), 0), 1);
-
- /* (neg (minus X Y)) can become (minus Y X). This transformation
- isn't safe for modes with signed zeros, since if X and Y are
- both +0, (minus Y X) is the same as (minus X Y). If the rounding
- mode is towards +infinity (or -infinity) then the two expressions
- will be rounded differently. */
- if (GET_CODE (XEXP (x, 0)) == MINUS
- && !HONOR_SIGNED_ZEROS (mode)
- && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
- return gen_binary (MINUS, mode, XEXP (XEXP (x, 0), 1),
- XEXP (XEXP (x, 0), 0));
-
- /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
- if (GET_CODE (XEXP (x, 0)) == PLUS
- && !HONOR_SIGNED_ZEROS (mode)
- && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
- {
- temp = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 0), 0), mode);
- temp = combine_simplify_rtx (temp, mode, last, in_dest);
- return gen_binary (MINUS, mode, temp, XEXP (XEXP (x, 0), 1));
- }
-
- /* (neg (mult A B)) becomes (mult (neg A) B).
- This works even for floating-point values. */
- if (GET_CODE (XEXP (x, 0)) == MULT)
- {
- temp = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 0), 0), mode);
- return gen_binary (MULT, mode, temp, XEXP (XEXP (x, 0), 1));
- }
-
/* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
- if (GET_CODE (XEXP (x, 0)) == XOR && XEXP (XEXP (x, 0), 1) == const1_rtx
+ if (GET_CODE (XEXP (x, 0)) == XOR
+ && XEXP (XEXP (x, 0), 1) == const1_rtx
&& nonzero_bits (XEXP (XEXP (x, 0), 0), mode) == 1)
return gen_binary (PLUS, mode, XEXP (XEXP (x, 0), 0), constm1_rtx);
- /* NEG commutes with ASHIFT since it is multiplication. Only do this
- if we can then eliminate the NEG (e.g.,
- if the operand is a constant). */
-
- if (GET_CODE (XEXP (x, 0)) == ASHIFT)
- {
- temp = simplify_unary_operation (NEG, mode,
- XEXP (XEXP (x, 0), 0), mode);
- if (temp)
- return gen_binary (ASHIFT, mode, temp, XEXP (XEXP (x, 0), 1));
- }
-
temp = expand_compound_operation (XEXP (x, 0));
/* For C equal to the width of MODE minus 1, (neg (ashiftrt X C)) can be
@@ -4228,6 +4025,36 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
&& GET_MODE (XEXP (XEXP (x, 0), 0)) == mode)
return XEXP (XEXP (x, 0), 0);
+ /* (float_truncate:SF (float_truncate:DF foo:XF))
+ = (float_truncate:SF foo:XF).
+ This may eliminate double rounding, so it is unsafe.
+
+ (float_truncate:SF (float_extend:XF foo:DF))
+ = (float_truncate:SF foo:DF).
+
+ (float_truncate:DF (float_extend:XF foo:SF))
+ = (float_extend:SF foo:DF). */
+ if ((GET_CODE (XEXP (x, 0)) == FLOAT_TRUNCATE
+ && flag_unsafe_math_optimizations)
+ || GET_CODE (XEXP (x, 0)) == FLOAT_EXTEND)
+ return simplify_gen_unary (GET_MODE_SIZE (GET_MODE (XEXP (XEXP (x, 0),
+ 0)))
+ > GET_MODE_SIZE (mode)
+ ? FLOAT_TRUNCATE : FLOAT_EXTEND,
+ mode,
+ XEXP (XEXP (x, 0), 0), mode);
+
+ /* (float_truncate (float x)) is (float x) */
+ if (GET_CODE (XEXP (x, 0)) == FLOAT
+ && (flag_unsafe_math_optimizations
+ || ((unsigned)significand_size (GET_MODE (XEXP (x, 0)))
+ >= (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))
+ - num_sign_bit_copies (XEXP (XEXP (x, 0), 0),
+ GET_MODE (XEXP (XEXP (x, 0), 0)))))))
+ return simplify_gen_unary (FLOAT, mode,
+ XEXP (XEXP (x, 0), 0),
+ GET_MODE (XEXP (XEXP (x, 0), 0)));
+
/* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
(OP:SF foo:SF) if OP is NEG or ABS. */
if ((GET_CODE (XEXP (x, 0)) == ABS
@@ -4244,7 +4071,23 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
&& GET_CODE (SUBREG_REG (XEXP (x, 0))) == FLOAT_TRUNCATE)
return SUBREG_REG (XEXP (x, 0));
break;
+ case FLOAT_EXTEND:
+ /* (float_extend (float_extend x)) is (float_extend x)
+
+ (float_extend (float x)) is (float x) assuming that double
+ rounding can't happen.
+ */
+ if (GET_CODE (XEXP (x, 0)) == FLOAT_EXTEND
+ || (GET_CODE (XEXP (x, 0)) == FLOAT
+ && ((unsigned)significand_size (GET_MODE (XEXP (x, 0)))
+ >= (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))
+ - num_sign_bit_copies (XEXP (XEXP (x, 0), 0),
+ GET_MODE (XEXP (XEXP (x, 0), 0)))))))
+ return simplify_gen_unary (GET_CODE (XEXP (x, 0)), mode,
+ XEXP (XEXP (x, 0), 0),
+ GET_MODE (XEXP (XEXP (x, 0), 0)));
+ break;
#ifdef HAVE_cc0
case COMPARE:
/* Convert (compare FOO (const_int 0)) to FOO unless we aren't
@@ -4285,11 +4128,11 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
case PLUS:
/* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)).
*/
- if (GET_CODE (XEXP (x, 0)) == MULT
+ if (GET_CODE (XEXP (x, 0)) == MULT
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == NEG)
{
rtx in1, in2;
-
+
in1 = XEXP (XEXP (XEXP (x, 0), 0), 0);
in2 = XEXP (XEXP (x, 0), 1);
return gen_binary (MINUS, mode, XEXP (x, 1),
@@ -4352,7 +4195,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
"a = (b & 8) == 0;" */
if (XEXP (x, 1) == constm1_rtx
&& GET_CODE (XEXP (x, 0)) != REG
- && ! (GET_CODE (XEXP (x,0)) == SUBREG
+ && ! (GET_CODE (XEXP (x, 0)) == SUBREG
&& GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG)
&& nonzero_bits (XEXP (x, 0), mode) == 1)
return simplify_shift_const (NULL_RTX, ASHIFTRT, mode,
@@ -4404,24 +4247,24 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
/* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A).
*/
- if (GET_CODE (XEXP (x, 1)) == MULT
+ if (GET_CODE (XEXP (x, 1)) == MULT
&& GET_CODE (XEXP (XEXP (x, 1), 0)) == NEG)
{
rtx in1, in2;
-
+
in1 = XEXP (XEXP (XEXP (x, 1), 0), 0);
in2 = XEXP (XEXP (x, 1), 1);
return gen_binary (PLUS, mode, gen_binary (MULT, mode, in1, in2),
XEXP (x, 0));
}
- /* Canonicalize (minus (neg A) (mult B C)) to
- (minus (mult (neg B) C) A). */
- if (GET_CODE (XEXP (x, 1)) == MULT
+ /* Canonicalize (minus (neg A) (mult B C)) to
+ (minus (mult (neg B) C) A). */
+ if (GET_CODE (XEXP (x, 1)) == MULT
&& GET_CODE (XEXP (x, 0)) == NEG)
{
rtx in1, in2;
-
+
in1 = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 1), 0), mode);
in2 = XEXP (XEXP (x, 1), 1);
return gen_binary (MINUS, mode, gen_binary (MULT, mode, in1, in2),
@@ -4491,10 +4334,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
with it. */
if (GET_CODE (XEXP (x, 0)) == COMPARE
|| (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_CC
-#ifdef HAVE_cc0
- && XEXP (x, 0) != cc0_rtx
-#endif
- ))
+ && ! CC0_P (XEXP (x, 0))))
{
rtx op0 = XEXP (x, 0);
rtx op1 = XEXP (x, 1);
@@ -4616,7 +4456,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
if (new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
- == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE(mode)-1))
+ == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1))
&& op1 == const0_rtx
&& mode == GET_MODE (op0)
&& (i = exact_log2 (nonzero_bits (op0, mode))) >= 0)
@@ -4695,6 +4535,13 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
break;
+ case POPCOUNT:
+ case PARITY:
+ /* (pop* (zero_extend <X>)) = (pop* <X>) */
+ if (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND)
+ SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
+ break;
+
case FLOAT:
/* (float (sign_extend <X>)) = (float <X>). */
if (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND)
@@ -4711,7 +4558,6 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
return simplify_shift_const (x, code, mode, XEXP (x, 0),
INTVAL (XEXP (x, 1)));
-#ifdef SHIFT_COUNT_TRUNCATED
else if (SHIFT_COUNT_TRUNCATED && GET_CODE (XEXP (x, 1)) != REG)
SUBST (XEXP (x, 1),
force_to_mode (XEXP (x, 1), GET_MODE (XEXP (x, 1)),
@@ -4719,8 +4565,6 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
<< exact_log2 (GET_MODE_BITSIZE (GET_MODE (x))))
- 1,
NULL_RTX, 0));
-#endif
-
break;
case VEC_SELECT:
@@ -4772,8 +4616,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
/* Simplify X, an IF_THEN_ELSE expression. Return the new expression. */
static rtx
-simplify_if_then_else (x)
- rtx x;
+simplify_if_then_else (rtx x)
{
enum machine_mode mode = GET_MODE (x);
rtx cond = XEXP (x, 0);
@@ -5092,14 +4935,22 @@ simplify_if_then_else (x)
simplify_shift_const (NULL_RTX, ASHIFT, mode,
gen_lowpart_for_combine (mode, XEXP (cond, 0)), i);
+ /* (IF_THEN_ELSE (NE REG 0) (0) (8)) is REG for nonzero_bits (REG) == 8. */
+ if (true_code == NE && XEXP (cond, 1) == const0_rtx
+ && false_rtx == const0_rtx && GET_CODE (true_rtx) == CONST_INT
+ && GET_MODE (XEXP (cond, 0)) == mode
+ && (INTVAL (true_rtx) & GET_MODE_MASK (mode))
+ == nonzero_bits (XEXP (cond, 0), mode)
+ && (i = exact_log2 (INTVAL (true_rtx) & GET_MODE_MASK (mode))) >= 0)
+ return XEXP (cond, 0);
+
return x;
}
/* Simplify X, a SET expression. Return the new expression. */
static rtx
-simplify_set (x)
- rtx x;
+simplify_set (rtx x)
{
rtx src = SET_SRC (x);
rtx dest = SET_DEST (x);
@@ -5177,13 +5028,12 @@ simplify_set (x)
/* Simplify our comparison, if possible. */
new_code = simplify_comparison (old_code, &op0, &op1);
-#ifdef EXTRA_CC_MODES
+#ifdef SELECT_CC_MODE
/* If this machine has CC modes other than CCmode, check to see if we
need to use a different CC mode here. */
compare_mode = SELECT_CC_MODE (new_code, op0, op1);
-#endif /* EXTRA_CC_MODES */
-#if !defined (HAVE_cc0) && defined (EXTRA_CC_MODES)
+#ifndef HAVE_cc0
/* If the mode changed, we have to change SET_DEST, the mode in the
compare, and the mode in the place SET_DEST is used. If SET_DEST is
a hard register, just build new versions with the proper mode. If it
@@ -5207,16 +5057,19 @@ simplify_set (x)
dest = new_dest;
}
}
-#endif
+#endif /* cc0 */
+#endif /* SELECT_CC_MODE */
/* If the code changed, we have to build a new comparison in
undobuf.other_insn. */
if (new_code != old_code)
{
+ int other_changed_previously = other_changed;
unsigned HOST_WIDE_INT mask;
SUBST (*cc_use, gen_rtx_fmt_ee (new_code, GET_MODE (*cc_use),
dest, const0_rtx));
+ other_changed = 1;
/* If the only change we made was to change an EQ into an NE or
vice versa, OP0 has only one bit that might be nonzero, and OP1
@@ -5226,7 +5079,7 @@ simplify_set (x)
if (((old_code == NE && new_code == EQ)
|| (old_code == EQ && new_code == NE))
- && ! other_changed && op1 == const0_rtx
+ && ! other_changed_previously && op1 == const0_rtx
&& GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT
&& exact_log2 (mask = nonzero_bits (op0, GET_MODE (op0))) >= 0)
{
@@ -5236,13 +5089,11 @@ simplify_set (x)
&& ! check_asm_operands (pat)))
{
PUT_CODE (*cc_use, old_code);
- other_insn = 0;
+ other_changed = 0;
op0 = gen_binary (XOR, GET_MODE (op0), op0, GEN_INT (mask));
}
}
-
- other_changed = 1;
}
if (other_changed)
@@ -5301,12 +5152,12 @@ simplify_set (x)
+ (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
#ifndef WORD_REGISTER_OPERATIONS
&& (GET_MODE_SIZE (GET_MODE (src))
- < GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
+ < GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
#endif
#ifdef CANNOT_CHANGE_MODE_CLASS
&& ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER
&& REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
- GET_MODE (SUBREG_REG (src)),
+ GET_MODE (SUBREG_REG (src)),
GET_MODE (src)))
#endif
&& (GET_CODE (dest) == REG
@@ -5393,16 +5244,16 @@ simplify_set (x)
if (GET_CODE (true_rtx) == IOR
&& rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
- term1 = false_rtx, true_rtx = XEXP(true_rtx, 1), false_rtx = const0_rtx;
+ term1 = false_rtx, true_rtx = XEXP (true_rtx, 1), false_rtx = const0_rtx;
else if (GET_CODE (true_rtx) == IOR
&& rtx_equal_p (XEXP (true_rtx, 1), false_rtx))
- term1 = false_rtx, true_rtx = XEXP(true_rtx, 0), false_rtx = const0_rtx;
+ term1 = false_rtx, true_rtx = XEXP (true_rtx, 0), false_rtx = const0_rtx;
else if (GET_CODE (false_rtx) == IOR
&& rtx_equal_p (XEXP (false_rtx, 0), true_rtx))
- term1 = true_rtx, false_rtx = XEXP(false_rtx, 1), true_rtx = const0_rtx;
+ term1 = true_rtx, false_rtx = XEXP (false_rtx, 1), true_rtx = const0_rtx;
else if (GET_CODE (false_rtx) == IOR
&& rtx_equal_p (XEXP (false_rtx, 1), true_rtx))
- term1 = true_rtx, false_rtx = XEXP(false_rtx, 0), true_rtx = const0_rtx;
+ term1 = true_rtx, false_rtx = XEXP (false_rtx, 0), true_rtx = const0_rtx;
term2 = gen_binary (AND, GET_MODE (src),
XEXP (XEXP (src, 0), 0), true_rtx);
@@ -5435,9 +5286,7 @@ simplify_set (x)
result. LAST is nonzero if this is the last retry. */
static rtx
-simplify_logical (x, last)
- rtx x;
- int last;
+simplify_logical (rtx x, int last)
{
enum machine_mode mode = GET_MODE (x);
rtx op0 = XEXP (x, 0);
@@ -5747,8 +5596,7 @@ simplify_logical (x, last)
It is the inverse of this function, loosely speaking. */
static rtx
-expand_compound_operation (x)
- rtx x;
+expand_compound_operation (rtx x)
{
unsigned HOST_WIDE_INT pos = 0, len;
int unsignedp = 0;
@@ -5845,7 +5693,15 @@ expand_compound_operation (x)
== 0)))
{
rtx temp = gen_rtx_ZERO_EXTEND (GET_MODE (x), XEXP (x, 0));
- return expand_compound_operation (temp);
+ rtx temp2 = expand_compound_operation (temp);
+
+ /* Make sure this is a profitable operation. */
+ if (rtx_cost (x, SET) > rtx_cost (temp2, SET))
+ return temp2;
+ else if (rtx_cost (x, SET) > rtx_cost (temp, SET))
+ return temp;
+ else
+ return x;
}
/* We can optimize some special cases of ZERO_EXTEND. */
@@ -5948,8 +5804,7 @@ expand_compound_operation (x)
support variable lengths. */
static rtx
-expand_field_assignment (x)
- rtx x;
+expand_field_assignment (rtx x)
{
rtx inner;
rtx pos; /* Always counts from low bit. */
@@ -6099,15 +5954,9 @@ expand_field_assignment (x)
can't handle it. */
static rtx
-make_extraction (mode, inner, pos, pos_rtx, len,
- unsignedp, in_dest, in_compare)
- enum machine_mode mode;
- rtx inner;
- HOST_WIDE_INT pos;
- rtx pos_rtx;
- unsigned HOST_WIDE_INT len;
- int unsignedp;
- int in_dest, in_compare;
+make_extraction (enum machine_mode mode, rtx inner, HOST_WIDE_INT pos,
+ rtx pos_rtx, unsigned HOST_WIDE_INT len, int unsignedp,
+ int in_dest, int in_compare)
{
/* This mode describes the size of the storage area
to fetch the overall value from. Within that, we
@@ -6214,30 +6063,36 @@ make_extraction (mode, inner, pos, pos_rtx, len,
}
else if (GET_CODE (inner) == REG)
{
- /* We can't call gen_lowpart_for_combine here since we always want
- a SUBREG and it would sometimes return a new hard register. */
if (tmode != inner_mode)
{
- HOST_WIDE_INT final_word = pos / BITS_PER_WORD;
-
- if (WORDS_BIG_ENDIAN
- && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD)
- final_word = ((GET_MODE_SIZE (inner_mode)
- - GET_MODE_SIZE (tmode))
- / UNITS_PER_WORD) - final_word;
-
- final_word *= UNITS_PER_WORD;
- if (BYTES_BIG_ENDIAN &&
- GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (tmode))
- final_word += (GET_MODE_SIZE (inner_mode)
- - GET_MODE_SIZE (tmode)) % UNITS_PER_WORD;
-
- /* Avoid creating invalid subregs, for example when
- simplifying (x>>32)&255. */
- if (final_word >= GET_MODE_SIZE (inner_mode))
- return NULL_RTX;
-
- new = gen_rtx_SUBREG (tmode, inner, final_word);
+ /* We can't call gen_lowpart_for_combine in a DEST since we
+ always want a SUBREG (see below) and it would sometimes
+ return a new hard register. */
+ if (pos || in_dest)
+ {
+ HOST_WIDE_INT final_word = pos / BITS_PER_WORD;
+
+ if (WORDS_BIG_ENDIAN
+ && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD)
+ final_word = ((GET_MODE_SIZE (inner_mode)
+ - GET_MODE_SIZE (tmode))
+ / UNITS_PER_WORD) - final_word;
+
+ final_word *= UNITS_PER_WORD;
+ if (BYTES_BIG_ENDIAN &&
+ GET_MODE_SIZE (inner_mode) > GET_MODE_SIZE (tmode))
+ final_word += (GET_MODE_SIZE (inner_mode)
+ - GET_MODE_SIZE (tmode)) % UNITS_PER_WORD;
+
+ /* Avoid creating invalid subregs, for example when
+ simplifying (x>>32)&255. */
+ if (final_word >= GET_MODE_SIZE (inner_mode))
+ return NULL_RTX;
+
+ new = gen_rtx_SUBREG (tmode, inner, final_word);
+ }
+ else
+ new = gen_lowpart_for_combine (tmode, inner);
}
else
new = inner;
@@ -6491,9 +6346,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
with any other operations in X. Return X without that shift if so. */
static rtx
-extract_left_shift (x, count)
- rtx x;
- int count;
+extract_left_shift (rtx x, int count)
{
enum rtx_code code = GET_CODE (x);
enum machine_mode mode = GET_MODE (x);
@@ -6520,7 +6373,7 @@ extract_left_shift (x, count)
case PLUS: case IOR: case XOR: case AND:
/* If we can safely shift this constant and we find the inner shift,
make a new operation. */
- if (GET_CODE (XEXP (x,1)) == CONST_INT
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
&& (INTVAL (XEXP (x, 1)) & ((((HOST_WIDE_INT) 1 << count)) - 1)) == 0
&& (tem = extract_left_shift (XEXP (x, 0), count)) != 0)
return gen_binary (code, mode, tem,
@@ -6554,9 +6407,7 @@ extract_left_shift (x, count)
or a COMPARE against zero, it is COMPARE. */
static rtx
-make_compound_operation (x, in_code)
- rtx x;
- enum rtx_code in_code;
+make_compound_operation (rtx x, enum rtx_code in_code)
{
enum rtx_code code = GET_CODE (x);
enum machine_mode mode = GET_MODE (x);
@@ -6824,9 +6675,7 @@ make_compound_operation (x, in_code)
*PLEN is set to the length of the field. */
static int
-get_pos_from_mask (m, plen)
- unsigned HOST_WIDE_INT m;
- unsigned HOST_WIDE_INT *plen;
+get_pos_from_mask (unsigned HOST_WIDE_INT m, unsigned HOST_WIDE_INT *plen)
{
/* Get the bit number of the first 1 bit from the right, -1 if none. */
int pos = exact_log2 (m & -m);
@@ -6863,12 +6712,8 @@ get_pos_from_mask (m, plen)
NOT, NEG, or XOR. */
static rtx
-force_to_mode (x, mode, mask, reg, just_select)
- rtx x;
- enum machine_mode mode;
- unsigned HOST_WIDE_INT mask;
- rtx reg;
- int just_select;
+force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
+ rtx reg, int just_select)
{
enum rtx_code code = GET_CODE (x);
int next_select = just_select || code == XOR || code == NOT || code == NEG;
@@ -6903,15 +6748,13 @@ force_to_mode (x, mode, mask, reg, just_select)
mask &= GET_MODE_MASK (op_mode);
/* When we have an arithmetic operation, or a shift whose count we
- do not know, we need to assume that all bit the up to the highest-order
+ do not know, we need to assume that all bits up to the highest-order
bit in MASK will be needed. This is how we form such a mask. */
- if (op_mode)
- fuller_mask = (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT
- ? GET_MODE_MASK (op_mode)
- : (((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1))
- - 1));
+ if (mask & ((unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)))
+ fuller_mask = ~(unsigned HOST_WIDE_INT) 0;
else
- fuller_mask = ~(HOST_WIDE_INT) 0;
+ fuller_mask = (((unsigned HOST_WIDE_INT) 1 << (floor_log2 (mask) + 1))
+ - 1);
/* Determine what bits of X are guaranteed to be (non)zero. */
nonzero = nonzero_bits (x, mode);
@@ -7303,8 +7146,7 @@ force_to_mode (x, mode, mask, reg, just_select)
&& (INTVAL (XEXP (x, 1))
<= GET_MODE_BITSIZE (GET_MODE (x)) - (floor_log2 (mask) + 1))
&& GET_CODE (XEXP (x, 0)) == ASHIFT
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
- && INTVAL (XEXP (XEXP (x, 0), 1)) == INTVAL (XEXP (x, 1)))
+ && XEXP (XEXP (x, 0), 1) == XEXP (x, 1))
return force_to_mode (XEXP (XEXP (x, 0), 0), mode, mask,
reg, next_select);
@@ -7322,7 +7164,7 @@ force_to_mode (x, mode, mask, reg, just_select)
temp = simplify_binary_operation (code == ROTATE ? ROTATERT : ROTATE,
GET_MODE (x), GEN_INT (mask),
XEXP (x, 1));
- if (temp && GET_CODE(temp) == CONST_INT)
+ if (temp && GET_CODE (temp) == CONST_INT)
SUBST (XEXP (x, 0),
force_to_mode (XEXP (x, 0), GET_MODE (x),
INTVAL (temp), reg, next_select));
@@ -7379,7 +7221,8 @@ force_to_mode (x, mode, mask, reg, just_select)
which is equal to STORE_FLAG_VALUE. */
if ((mask & ~STORE_FLAG_VALUE) == 0 && XEXP (x, 1) == const0_rtx
&& exact_log2 (nonzero_bits (XEXP (x, 0), mode)) >= 0
- && nonzero_bits (XEXP (x, 0), mode) == STORE_FLAG_VALUE)
+ && (nonzero_bits (XEXP (x, 0), mode)
+ == (unsigned HOST_WIDE_INT) STORE_FLAG_VALUE))
return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select);
break;
@@ -7395,7 +7238,7 @@ force_to_mode (x, mode, mask, reg, just_select)
SUBST (XEXP (x, 2),
gen_lowpart_for_combine (GET_MODE (x),
force_to_mode (XEXP (x, 2), mode,
- mask, reg,next_select)));
+ mask, reg, next_select)));
break;
default:
@@ -7414,9 +7257,7 @@ force_to_mode (x, mode, mask, reg, just_select)
If we return zero, we set *PTRUE and *PFALSE to X. */
static rtx
-if_then_else_cond (x, ptrue, pfalse)
- rtx x;
- rtx *ptrue, *pfalse;
+if_then_else_cond (rtx x, rtx *ptrue, rtx *pfalse)
{
enum machine_mode mode = GET_MODE (x);
enum rtx_code code = GET_CODE (x);
@@ -7425,7 +7266,7 @@ if_then_else_cond (x, ptrue, pfalse)
/* If we are comparing a value against zero, we are done. */
if ((code == NE || code == EQ)
- && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0)
+ && XEXP (x, 1) == const0_rtx)
{
*ptrue = (code == NE) ? const_true_rtx : const0_rtx;
*pfalse = (code == NE) ? const0_rtx : const_true_rtx;
@@ -7559,12 +7400,16 @@ if_then_else_cond (x, ptrue, pfalse)
&& 0 != (cond0 = if_then_else_cond (SUBREG_REG (x),
&true0, &false0)))
{
- *ptrue = simplify_gen_subreg (mode, true0,
+ true0 = simplify_gen_subreg (mode, true0,
+ GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
+ false0 = simplify_gen_subreg (mode, false0,
GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
- *pfalse = simplify_gen_subreg (mode, false0,
- GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
-
- return cond0;
+ if (true0 && false0)
+ {
+ *ptrue = true0;
+ *pfalse = false0;
+ return cond0;
+ }
}
/* If X is a constant, this isn't special and will cause confusions
@@ -7592,7 +7437,7 @@ if_then_else_cond (x, ptrue, pfalse)
}
/* Likewise for 0 or a single bit. */
- else if (mode != VOIDmode
+ else if (SCALAR_INT_MODE_P (mode)
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& exact_log2 (nz = nonzero_bits (x, mode)) >= 0)
{
@@ -7614,10 +7459,7 @@ if_then_else_cond (x, ptrue, pfalse)
arise with IF_THEN_ELSE expressions. */
static rtx
-known_cond (x, cond, reg, val)
- rtx x;
- enum rtx_code cond;
- rtx reg, val;
+known_cond (rtx x, enum rtx_code cond, rtx reg, rtx val)
{
enum rtx_code code = GET_CODE (x);
rtx temp;
@@ -7768,9 +7610,7 @@ known_cond (x, cond, reg, val)
assignment as a field assignment. */
static int
-rtx_equal_for_field_assignment_p (x, y)
- rtx x;
- rtx y;
+rtx_equal_for_field_assignment_p (rtx x, rtx y)
{
if (x == y || rtx_equal_p (x, y))
return 1;
@@ -7807,8 +7647,7 @@ rtx_equal_for_field_assignment_p (x, y)
We only handle the most common cases. */
static rtx
-make_field_assignment (x)
- rtx x;
+make_field_assignment (rtx x)
{
rtx dest = SET_DEST (x);
rtx src = SET_SRC (x);
@@ -7918,6 +7757,17 @@ make_field_assignment (x)
: ((unsigned HOST_WIDE_INT) 1 << len) - 1,
dest, 0);
+ /* If SRC is masked by an AND that does not make a difference in
+ the value being stored, strip it. */
+ if (GET_CODE (assign) == ZERO_EXTRACT
+ && GET_CODE (XEXP (assign, 1)) == CONST_INT
+ && INTVAL (XEXP (assign, 1)) < HOST_BITS_PER_WIDE_INT
+ && GET_CODE (src) == AND
+ && GET_CODE (XEXP (src, 1)) == CONST_INT
+ && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (src, 1))
+ == ((unsigned HOST_WIDE_INT) 1 << INTVAL (XEXP (assign, 1))) - 1))
+ src = XEXP (src, 0);
+
return gen_rtx_SET (VOIDmode, assign, src);
}
@@ -7925,18 +7775,17 @@ make_field_assignment (x)
if so. */
static rtx
-apply_distributive_law (x)
- rtx x;
+apply_distributive_law (rtx x)
{
enum rtx_code code = GET_CODE (x);
+ enum rtx_code inner_code;
rtx lhs, rhs, other;
rtx tem;
- enum rtx_code inner_code;
- /* Distributivity is not true for floating point.
- It can change the value. So don't do it.
- -- rms and moshier@world.std.com. */
- if (FLOAT_MODE_P (GET_MODE (x)))
+ /* Distributivity is not true for floating point as it can change the
+ value. So we don't do it unless -funsafe-math-optimizations. */
+ if (FLOAT_MODE_P (GET_MODE (x))
+ && ! flag_unsafe_math_optimizations)
return x;
/* The outer operation can only be one of the following: */
@@ -7944,7 +7793,8 @@ apply_distributive_law (x)
&& code != PLUS && code != MINUS)
return x;
- lhs = XEXP (x, 0), rhs = XEXP (x, 1);
+ lhs = XEXP (x, 0);
+ rhs = XEXP (x, 1);
/* If either operand is a primitive we can't do anything, so get out
fast. */
@@ -8031,7 +7881,7 @@ apply_distributive_law (x)
tem = gen_binary (code, GET_MODE (x), lhs, rhs);
/* There is one exception to the general way of distributing:
- (a ^ b) | (a ^ c) -> (~a) & (b ^ c) */
+ (a | c) ^ (b | c) -> (a ^ b) & ~c */
if (code == XOR && inner_code == IOR)
{
inner_code = AND;
@@ -8052,11 +7902,8 @@ apply_distributive_law (x)
X is zero, we are to always construct the equivalent form. */
static rtx
-simplify_and_const_int (x, mode, varop, constop)
- rtx x;
- enum machine_mode mode;
- rtx varop;
- unsigned HOST_WIDE_INT constop;
+simplify_and_const_int (rtx x, enum machine_mode mode, rtx varop,
+ unsigned HOST_WIDE_INT constop)
{
unsigned HOST_WIDE_INT nonzero;
int i;
@@ -8180,12 +8027,9 @@ simplify_and_const_int (x, mode, varop, constop)
identical subexpressions on the first or the second level. */
static unsigned HOST_WIDE_INT
-cached_nonzero_bits (x, mode, known_x, known_mode, known_ret)
- rtx x;
- enum machine_mode mode;
- rtx known_x;
- enum machine_mode known_mode;
- unsigned HOST_WIDE_INT known_ret;
+cached_nonzero_bits (rtx x, enum machine_mode mode, rtx known_x,
+ enum machine_mode known_mode,
+ unsigned HOST_WIDE_INT known_ret)
{
if (x == known_x && mode == known_mode)
return known_ret;
@@ -8236,12 +8080,9 @@ cached_nonzero_bits (x, mode, known_x, known_mode, known_ret)
a shift, AND, or zero_extract, we can do better. */
static unsigned HOST_WIDE_INT
-nonzero_bits1 (x, mode, known_x, known_mode, known_ret)
- rtx x;
- enum machine_mode mode;
- rtx known_x;
- enum machine_mode known_mode;
- unsigned HOST_WIDE_INT known_ret;
+nonzero_bits1 (rtx x, enum machine_mode mode, rtx known_x,
+ enum machine_mode known_mode,
+ unsigned HOST_WIDE_INT known_ret)
{
unsigned HOST_WIDE_INT nonzero = GET_MODE_MASK (mode);
unsigned HOST_WIDE_INT inner_nz;
@@ -8314,7 +8155,8 @@ nonzero_bits1 (x, mode, known_x, known_mode, known_ret)
stack to be momentarily aligned only to that amount,
so we pick the least alignment. */
if (x == stack_pointer_rtx && PUSH_ARGS)
- alignment = MIN (PUSH_ROUNDING (1), alignment);
+ alignment = MIN ((unsigned HOST_WIDE_INT) PUSH_ROUNDING (1),
+ alignment);
#endif
nonzero &= ~(alignment - 1);
@@ -8496,14 +8338,15 @@ nonzero_bits1 (x, mode, known_x, known_mode, known_ret)
nonzero_bits_with_known (XEXP (x, 0), mode);
unsigned HOST_WIDE_INT nz1 =
nonzero_bits_with_known (XEXP (x, 1), mode);
+ int sign_index = GET_MODE_BITSIZE (GET_MODE (x)) - 1;
int width0 = floor_log2 (nz0) + 1;
int width1 = floor_log2 (nz1) + 1;
int low0 = floor_log2 (nz0 & -nz0);
int low1 = floor_log2 (nz1 & -nz1);
HOST_WIDE_INT op0_maybe_minusp
- = (nz0 & ((HOST_WIDE_INT) 1 << (mode_width - 1)));
+ = (nz0 & ((HOST_WIDE_INT) 1 << sign_index));
HOST_WIDE_INT op1_maybe_minusp
- = (nz1 & ((HOST_WIDE_INT) 1 << (mode_width - 1)));
+ = (nz1 & ((HOST_WIDE_INT) 1 << sign_index));
unsigned int result_width = mode_width;
int result_low = 0;
@@ -8662,8 +8505,31 @@ nonzero_bits1 (x, mode, known_x, known_mode, known_ret)
break;
case FFS:
+ case POPCOUNT:
/* This is at most the number of bits in the mode. */
- nonzero = ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width) + 1)) - 1;
+ nonzero = ((HOST_WIDE_INT) 2 << (floor_log2 (mode_width))) - 1;
+ break;
+
+ case CLZ:
+ /* If CLZ has a known value at zero, then the nonzero bits are
+ that value, plus the number of bits in the mode minus one. */
+ if (CLZ_DEFINED_VALUE_AT_ZERO (mode, nonzero))
+ nonzero |= ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1;
+ else
+ nonzero = -1;
+ break;
+
+ case CTZ:
+ /* If CTZ has a known value at zero, then the nonzero bits are
+ that value, plus the number of bits in the mode minus one. */
+ if (CTZ_DEFINED_VALUE_AT_ZERO (mode, nonzero))
+ nonzero |= ((HOST_WIDE_INT) 1 << (floor_log2 (mode_width))) - 1;
+ else
+ nonzero = -1;
+ break;
+
+ case PARITY:
+ nonzero = 1;
break;
case IF_THEN_ELSE:
@@ -8690,12 +8556,9 @@ nonzero_bits1 (x, mode, known_x, known_mode, known_ret)
first or the second level. */
static unsigned int
-cached_num_sign_bit_copies (x, mode, known_x, known_mode, known_ret)
- rtx x;
- enum machine_mode mode;
- rtx known_x;
- enum machine_mode known_mode;
- unsigned int known_ret;
+cached_num_sign_bit_copies (rtx x, enum machine_mode mode, rtx known_x,
+ enum machine_mode known_mode,
+ unsigned int known_ret)
{
if (x == known_x && mode == known_mode)
return known_ret;
@@ -8741,12 +8604,9 @@ cached_num_sign_bit_copies (x, mode, known_x, known_mode, known_ret)
be between 1 and the number of bits in MODE. */
static unsigned int
-num_sign_bit_copies1 (x, mode, known_x, known_mode, known_ret)
- rtx x;
- enum machine_mode mode;
- rtx known_x;
- enum machine_mode known_mode;
- unsigned int known_ret;
+num_sign_bit_copies1 (rtx x, enum machine_mode mode, rtx known_x,
+ enum machine_mode known_mode,
+ unsigned int known_ret)
{
enum rtx_code code = GET_CODE (x);
unsigned int bitwidth;
@@ -9105,10 +8965,7 @@ num_sign_bit_copies1 (x, mode, known_x, known_mode, known_ret)
implies that it must be called from a define_split. */
unsigned int
-extended_count (x, mode, unsignedp)
- rtx x;
- enum machine_mode mode;
- int unsignedp;
+extended_count (rtx x, enum machine_mode mode, int unsignedp)
{
if (nonzero_sign_valid == 0)
return 0;
@@ -9143,13 +9000,7 @@ extended_count (x, mode, unsignedp)
return 0 and do not change *POP0, *PCONST0, and *PCOMP_P. */
static int
-merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
- enum rtx_code *pop0;
- HOST_WIDE_INT *pconst0;
- enum rtx_code op1;
- HOST_WIDE_INT const1;
- enum machine_mode mode;
- int *pcomp_p;
+merge_outer_ops (enum rtx_code *pop0, HOST_WIDE_INT *pconst0, enum rtx_code op1, HOST_WIDE_INT const1, enum machine_mode mode, int *pcomp_p)
{
enum rtx_code op0 = *pop0;
HOST_WIDE_INT const0 = *pconst0;
@@ -9221,7 +9072,7 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
op0 = AND, *pcomp_p = 1;
else /* op1 == IOR */
/* (a | b) ^ b == a & ~b */
- op0 = AND, *pconst0 = ~const0;
+ op0 = AND, const0 = ~const0;
break;
case AND:
@@ -9267,12 +9118,9 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
are ASHIFTRT and ROTATE, which are always done in their original mode, */
static rtx
-simplify_shift_const (x, code, result_mode, varop, orig_count)
- rtx x;
- enum rtx_code code;
- enum machine_mode result_mode;
- rtx varop;
- int orig_count;
+simplify_shift_const (rtx x, enum rtx_code code,
+ enum machine_mode result_mode, rtx varop,
+ int orig_count)
{
enum rtx_code orig_code = code;
unsigned int count;
@@ -9291,10 +9139,8 @@ simplify_shift_const (x, code, result_mode, varop, orig_count)
/* Make sure and truncate the "natural" shift on the way in. We don't
want to do this inside the loop as it makes it more difficult to
combine shifts. */
-#ifdef SHIFT_COUNT_TRUNCATED
if (SHIFT_COUNT_TRUNCATED)
orig_count &= GET_MODE_BITSIZE (mode) - 1;
-#endif
/* If we were given an invalid count, don't do anything except exactly
what was requested. */
@@ -9400,6 +9246,16 @@ simplify_shift_const (x, code, result_mode, varop, orig_count)
== 0))
code = LSHIFTRT;
+ if (code == LSHIFTRT
+ && GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
+ && !(nonzero_bits (varop, shift_mode) >> count))
+ varop = const0_rtx;
+ if (code == ASHIFT
+ && GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
+ && !((nonzero_bits (varop, shift_mode) << count)
+ & GET_MODE_MASK (shift_mode)))
+ varop = const0_rtx;
+
switch (GET_CODE (varop))
{
case SIGN_EXTEND:
@@ -9754,7 +9610,7 @@ simplify_shift_const (x, code, result_mode, varop, orig_count)
break;
case EQ:
- /* convert (lshiftrt (eq FOO 0) C) to (xor FOO 1) if STORE_FLAG_VALUE
+ /* Convert (lshiftrt (eq FOO 0) C) to (xor FOO 1) if STORE_FLAG_VALUE
says that the sign bit can be tested, FOO has mode MODE, C is
GET_MODE_BITSIZE (MODE) - 1, and FOO has only its low-order bit
that may be nonzero. */
@@ -9984,7 +9840,7 @@ simplify_shift_const (x, code, result_mode, varop, orig_count)
/* If COMPLEMENT_P is set, we have to complement X before doing the outer
operation. */
if (complement_p)
- x =simplify_gen_unary (NOT, result_mode, x, result_mode);
+ x = simplify_gen_unary (NOT, result_mode, x, result_mode);
if (outer_op != NIL)
{
@@ -10020,17 +9876,14 @@ simplify_shift_const (x, code, result_mode, varop, orig_count)
or -1. */
static int
-recog_for_combine (pnewpat, insn, pnotes)
- rtx *pnewpat;
- rtx insn;
- rtx *pnotes;
+recog_for_combine (rtx *pnewpat, rtx insn, rtx *pnotes)
{
rtx pat = *pnewpat;
int insn_code_number;
int num_clobbers_to_add = 0;
int i;
rtx notes = 0;
- rtx dummy_insn;
+ rtx old_notes, old_pat;
/* If PAT is a PARALLEL, check to see if it contains the CLOBBER
we use to indicate that something didn't match. If we find such a
@@ -10041,13 +9894,12 @@ recog_for_combine (pnewpat, insn, pnotes)
&& XEXP (XVECEXP (pat, 0, i), 0) == const0_rtx)
return -1;
- /* *pnewpat does not have to be actual PATTERN (insn), so make a dummy
- instruction for pattern recognition. */
- dummy_insn = shallow_copy_rtx (insn);
- PATTERN (dummy_insn) = pat;
- REG_NOTES (dummy_insn) = 0;
+ old_pat = PATTERN (insn);
+ old_notes = REG_NOTES (insn);
+ PATTERN (insn) = pat;
+ REG_NOTES (insn) = 0;
- insn_code_number = recog (pat, dummy_insn, &num_clobbers_to_add);
+ insn_code_number = recog (pat, insn, &num_clobbers_to_add);
/* If it isn't, there is the possibility that we previously had an insn
that clobbered some register as a side effect, but the combined
@@ -10072,9 +9924,11 @@ recog_for_combine (pnewpat, insn, pnotes)
if (pos == 1)
pat = XVECEXP (pat, 0, 0);
- PATTERN (dummy_insn) = pat;
- insn_code_number = recog (pat, dummy_insn, &num_clobbers_to_add);
+ PATTERN (insn) = pat;
+ insn_code_number = recog (pat, insn, &num_clobbers_to_add);
}
+ PATTERN (insn) = old_pat;
+ REG_NOTES (insn) = old_notes;
/* Recognize all noop sets, these will be killed by followup pass. */
if (insn_code_number < 0 && GET_CODE (pat) == SET && set_noop_p (pat))
@@ -10128,15 +9982,21 @@ recog_for_combine (pnewpat, insn, pnotes)
#undef gen_lowpart
static rtx
-gen_lowpart_for_combine (mode, x)
- enum machine_mode mode;
- rtx x;
+gen_lowpart_for_combine (enum machine_mode mode, rtx x)
{
rtx result;
if (GET_MODE (x) == mode)
return x;
+ /* Return identity if this is a CONST or symbolic
+ reference. */
+ if (mode == Pmode
+ && (GET_CODE (x) == CONST
+ || GET_CODE (x) == SYMBOL_REF
+ || GET_CODE (x) == LABEL_REF))
+ return x;
+
/* We can only support MODE being wider than a word if X is a
constant integer or has a mode the same size. */
@@ -10220,6 +10080,8 @@ gen_lowpart_for_combine (mode, x)
{
sub_mode = int_mode_for_mode (mode);
x = gen_lowpart_common (sub_mode, x);
+ if (x == 0)
+ return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
}
res = simplify_gen_subreg (mode, x, sub_mode, offset);
if (res)
@@ -10232,10 +10094,7 @@ gen_lowpart_for_combine (mode, x)
fold; if not, a new expression is allocated. */
static rtx
-gen_binary (code, mode, op0, op1)
- enum rtx_code code;
- enum machine_mode mode;
- rtx op0, op1;
+gen_binary (enum rtx_code code, enum machine_mode mode, rtx op0, rtx op1)
{
rtx result;
rtx tem;
@@ -10244,7 +10103,7 @@ gen_binary (code, mode, op0, op1)
return op0;
else if (GET_CODE (op1) == CLOBBER)
return op1;
-
+
if (GET_RTX_CLASS (code) == 'c'
&& swap_commutative_operands_p (op0, op1))
tem = op0, op0 = op1, op1 = tem;
@@ -10299,10 +10158,7 @@ gen_binary (code, mode, op0, op1)
should have been detected earlier. Hence we ignore all such cases. */
static enum rtx_code
-simplify_comparison (code, pop0, pop1)
- enum rtx_code code;
- rtx *pop0;
- rtx *pop1;
+simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
{
rtx op0 = *pop0;
rtx op1 = *pop1;
@@ -10325,12 +10181,9 @@ simplify_comparison (code, pop0, pop1)
&& (GET_MODE (SUBREG_REG (XEXP (XEXP (op0, 0), 0)))
== GET_MODE (SUBREG_REG (XEXP (XEXP (op1, 0), 0))))
&& GET_CODE (XEXP (op0, 1)) == CONST_INT
- && GET_CODE (XEXP (op1, 1)) == CONST_INT
- && GET_CODE (XEXP (XEXP (op0, 0), 1)) == CONST_INT
- && GET_CODE (XEXP (XEXP (op1, 0), 1)) == CONST_INT
- && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (op1, 1))
- && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (XEXP (op0, 0), 1))
- && INTVAL (XEXP (op0, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
+ && XEXP (op0, 1) == XEXP (op1, 1)
+ && XEXP (op0, 1) == XEXP (XEXP (op0, 0), 1)
+ && XEXP (op0, 1) == XEXP (XEXP (op1, 0), 1)
&& (INTVAL (XEXP (op0, 1))
== (GET_MODE_BITSIZE (GET_MODE (op0))
- (GET_MODE_BITSIZE
@@ -10646,7 +10499,7 @@ simplify_comparison (code, pop0, pop1)
/* (unsigned) > 0x7fffffff is equivalent to < 0. */
else if ((mode_width <= HOST_BITS_PER_WIDE_INT)
- && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1))
+ && (const_op == ((HOST_WIDE_INT) 1 << (mode_width - 1)) - 1))
{
const_op = 0, op1 = const0_rtx;
code = LT;
@@ -10684,8 +10537,10 @@ simplify_comparison (code, pop0, pop1)
a constant that has only a single bit set and are comparing it
with zero, we can convert this into an equality comparison
between the position and the location of the single bit. */
-
- if (GET_CODE (XEXP (op0, 0)) == CONST_INT
+ /* Except we can't if SHIFT_COUNT_TRUNCATED is set, since we might
+ have already reduced the shift count modulo the word size. */
+ if (!SHIFT_COUNT_TRUNCATED
+ && GET_CODE (XEXP (op0, 0)) == CONST_INT
&& XEXP (op0, 1) == const1_rtx
&& equality_comparison_p && const_op == 0
&& (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0)
@@ -10975,9 +10830,7 @@ simplify_comparison (code, pop0, pop1)
/* We can't do anything if OP0 is a condition code value, rather
than an actual data value. */
if (const_op != 0
-#ifdef HAVE_cc0
- || XEXP (op0, 0) == cc0_rtx
-#endif
+ || CC0_P (XEXP (op0, 0))
|| GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
break;
@@ -11095,70 +10948,84 @@ simplify_comparison (code, pop0, pop1)
continue;
}
- /* If this is (and:M1 (subreg:M2 X 0) (const_int C1)) where C1 fits
- in both M1 and M2 and the SUBREG is either paradoxical or
- represents the low part, permute the SUBREG and the AND and
- try again. */
- if (GET_CODE (XEXP (op0, 0)) == SUBREG
+ /* If this is (and:M1 (subreg:M2 X 0) (const_int C1)) where C1
+ fits in both M1 and M2 and the SUBREG is either paradoxical
+ or represents the low part, permute the SUBREG and the AND
+ and try again. */
+ if (GET_CODE (XEXP (op0, 0)) == SUBREG)
+ {
+ unsigned HOST_WIDE_INT c1;
+ tmode = GET_MODE (SUBREG_REG (XEXP (op0, 0)));
/* Require an integral mode, to avoid creating something like
(AND:SF ...). */
- && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
- && (0
+ if (SCALAR_INT_MODE_P (tmode)
+ /* It is unsafe to commute the AND into the SUBREG if the
+ SUBREG is paradoxical and WORD_REGISTER_OPERATIONS is
+ not defined. As originally written the upper bits
+ have a defined value due to the AND operation.
+ However, if we commute the AND inside the SUBREG then
+ they no longer have defined values and the meaning of
+ the code has been changed. */
+ && (0
#ifdef WORD_REGISTER_OPERATIONS
- || ((mode_width
- > (GET_MODE_BITSIZE
- (GET_MODE (SUBREG_REG (XEXP (op0, 0))))))
- && mode_width <= BITS_PER_WORD)
-#endif
- || ((mode_width
- <= (GET_MODE_BITSIZE
- (GET_MODE (SUBREG_REG (XEXP (op0, 0))))))
- && subreg_lowpart_p (XEXP (op0, 0))))
-#ifndef WORD_REGISTER_OPERATIONS
- /* It is unsafe to commute the AND into the SUBREG if the SUBREG
- is paradoxical and WORD_REGISTER_OPERATIONS is not defined.
- As originally written the upper bits have a defined value
- due to the AND operation. However, if we commute the AND
- inside the SUBREG then they no longer have defined values
- and the meaning of the code has been changed. */
- && (GET_MODE_SIZE (GET_MODE (XEXP (op0, 0)))
- <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0)))))
+ || (mode_width > GET_MODE_BITSIZE (tmode)
+ && mode_width <= BITS_PER_WORD)
#endif
- && GET_CODE (XEXP (op0, 1)) == CONST_INT
- && mode_width <= HOST_BITS_PER_WIDE_INT
- && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
- <= HOST_BITS_PER_WIDE_INT)
- && (INTVAL (XEXP (op0, 1)) & ~mask) == 0
- && 0 == (~GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
- & INTVAL (XEXP (op0, 1)))
- && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1)) != mask
- && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
- != GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0))))))
-
- {
- op0
- = gen_lowpart_for_combine
- (mode,
- gen_binary (AND, GET_MODE (SUBREG_REG (XEXP (op0, 0))),
- SUBREG_REG (XEXP (op0, 0)), XEXP (op0, 1)));
- continue;
+ || (mode_width <= GET_MODE_BITSIZE (tmode)
+ && subreg_lowpart_p (XEXP (op0, 0))))
+ && GET_CODE (XEXP (op0, 1)) == CONST_INT
+ && mode_width <= HOST_BITS_PER_WIDE_INT
+ && GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT
+ && ((c1 = INTVAL (XEXP (op0, 1))) & ~mask) == 0
+ && (c1 & ~GET_MODE_MASK (tmode)) == 0
+ && c1 != mask
+ && c1 != GET_MODE_MASK (tmode))
+ {
+ op0 = gen_binary (AND, tmode,
+ SUBREG_REG (XEXP (op0, 0)),
+ gen_int_mode (c1, tmode));
+ op0 = gen_lowpart_for_combine (mode, op0);
+ continue;
+ }
}
- /* Convert (ne (and (lshiftrt (not X)) 1) 0) to
- (eq (and (lshiftrt X) 1) 0). */
+ /* Convert (ne (and (not X) 1) 0) to (eq (and X 1) 0). */
if (const_op == 0 && equality_comparison_p
&& XEXP (op0, 1) == const1_rtx
- && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
- && GET_CODE (XEXP (XEXP (op0, 0), 0)) == NOT)
+ && GET_CODE (XEXP (op0, 0)) == NOT)
{
op0 = simplify_and_const_int
- (op0, mode,
- gen_rtx_LSHIFTRT (mode, XEXP (XEXP (XEXP (op0, 0), 0), 0),
- XEXP (XEXP (op0, 0), 1)),
- (HOST_WIDE_INT) 1);
+ (NULL_RTX, mode, XEXP (XEXP (op0, 0), 0), (HOST_WIDE_INT) 1);
code = (code == NE ? EQ : NE);
continue;
}
+
+ /* Convert (ne (and (lshiftrt (not X)) 1) 0) to
+ (eq (and (lshiftrt X) 1) 0).
+ Also handle the case where (not X) is expressed using xor. */
+ if (const_op == 0 && equality_comparison_p
+ && XEXP (op0, 1) == const1_rtx
+ && GET_CODE (XEXP (op0, 0)) == LSHIFTRT)
+ {
+ rtx shift_op = XEXP (XEXP (op0, 0), 0);
+ rtx shift_count = XEXP (XEXP (op0, 0), 1);
+
+ if (GET_CODE (shift_op) == NOT
+ || (GET_CODE (shift_op) == XOR
+ && GET_CODE (XEXP (shift_op, 1)) == CONST_INT
+ && GET_CODE (shift_count) == CONST_INT
+ && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
+ && (INTVAL (XEXP (shift_op, 1))
+ == (HOST_WIDE_INT) 1 << INTVAL (shift_count))))
+ {
+ op0 = simplify_and_const_int
+ (NULL_RTX, mode,
+ gen_rtx_LSHIFTRT (mode, XEXP (shift_op, 0), shift_count),
+ (HOST_WIDE_INT) 1);
+ code = (code == NE ? EQ : NE);
+ continue;
+ }
+ }
break;
case ASHIFT:
@@ -11346,9 +11213,6 @@ simplify_comparison (code, pop0, pop1)
op1 = make_compound_operation (op1, SET);
if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0)
- /* Case 3 above, to sometimes allow (subreg (mem x)), isn't
- implemented. */
- && GET_CODE (SUBREG_REG (op0)) == REG
&& GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
&& GET_MODE_CLASS (GET_MODE (SUBREG_REG (op0))) == MODE_INT
&& (code == NE || code == EQ))
@@ -11356,8 +11220,13 @@ simplify_comparison (code, pop0, pop1)
if (GET_MODE_SIZE (GET_MODE (op0))
> GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0))))
{
- op0 = SUBREG_REG (op0);
- op1 = gen_lowpart_for_combine (GET_MODE (op0), op1);
+ /* For paradoxical subregs, allow case 1 as above. Case 3 isn't
+ implemented. */
+ if (GET_CODE (SUBREG_REG (op0)) == REG)
+ {
+ op0 = SUBREG_REG (op0);
+ op1 = gen_lowpart_for_combine (GET_MODE (op0), op1);
+ }
}
else if ((GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
<= HOST_BITS_PER_WIDE_INT)
@@ -11459,8 +11328,7 @@ simplify_comparison (code, pop0, pop1)
/* Like jump.c' reversed_comparison_code, but use combine infrastructure for
searching backward. */
static enum rtx_code
-combine_reversed_comparison_code (exp)
- rtx exp;
+combine_reversed_comparison_code (rtx exp)
{
enum rtx_code code1 = reversed_comparison_code (exp, NULL);
rtx x;
@@ -11476,12 +11344,11 @@ combine_reversed_comparison_code (exp)
return reversed_comparison_code_parts (GET_CODE (exp),
XEXP (x, 0), XEXP (x, 1), NULL);
}
+
/* Return comparison with reversed code of EXP and operands OP0 and OP1.
Return NULL_RTX in case we fail to do the reversal. */
static rtx
-reversed_comparison (exp, mode, op0, op1)
- rtx exp, op0, op1;
- enum machine_mode mode;
+reversed_comparison (rtx exp, enum machine_mode mode, rtx op0, rtx op1)
{
enum rtx_code reversed_code = combine_reversed_comparison_code (exp);
if (reversed_code == UNKNOWN)
@@ -11495,8 +11362,7 @@ reversed_comparison (exp, mode, op0, op1)
for each register mentioned. Similar to mention_regs in cse.c */
static void
-update_table_tick (x)
- rtx x;
+update_table_tick (rtx x)
{
enum rtx_code code = GET_CODE (x);
const char *fmt = GET_RTX_FORMAT (code);
@@ -11556,7 +11422,7 @@ update_table_tick (x)
break;
}
}
-
+
update_table_tick (XEXP (x, i));
}
}
@@ -11567,10 +11433,7 @@ update_table_tick (x)
with VALUE also zero and is used to invalidate the register. */
static void
-record_value_for_reg (reg, insn, value)
- rtx reg;
- rtx insn;
- rtx value;
+record_value_for_reg (rtx reg, rtx insn, rtx value)
{
unsigned int regno = REGNO (reg);
unsigned int endregno
@@ -11677,9 +11540,7 @@ record_value_for_reg (reg, insn, value)
set is occurring. */
static void
-record_dead_and_set_regs_1 (dest, setter, data)
- rtx dest, setter;
- void *data;
+record_dead_and_set_regs_1 (rtx dest, rtx setter, void *data)
{
rtx record_dead_insn = (rtx) data;
@@ -11721,8 +11582,7 @@ record_dead_and_set_regs_1 (dest, setter, data)
subroutine call). */
static void
-record_dead_and_set_regs (insn)
- rtx insn;
+record_dead_and_set_regs (rtx insn)
{
rtx link;
unsigned int i;
@@ -11780,9 +11640,7 @@ record_dead_and_set_regs (insn)
missed because of that. */
static void
-record_promoted_value (insn, subreg)
- rtx insn;
- rtx subreg;
+record_promoted_value (rtx insn, rtx subreg)
{
rtx links, set;
unsigned int regno = REGNO (SUBREG_REG (subreg));
@@ -11824,9 +11682,7 @@ record_promoted_value (insn, subreg)
note what it implies to the registers used in it. */
static void
-check_promoted_subreg (insn, x)
- rtx insn;
- rtx x;
+check_promoted_subreg (rtx insn, rtx x)
{
if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x)
&& GET_CODE (SUBREG_REG (x)) == REG)
@@ -11863,11 +11719,7 @@ check_promoted_subreg (insn, x)
we don't know exactly what registers it was produced from. */
static int
-get_last_value_validate (loc, insn, tick, replace)
- rtx *loc;
- rtx insn;
- int tick;
- int replace;
+get_last_value_validate (rtx *loc, rtx insn, int tick, int replace)
{
rtx x = *loc;
const char *fmt = GET_RTX_FORMAT (GET_CODE (x));
@@ -11967,8 +11819,7 @@ get_last_value_validate (loc, insn, tick, replace)
is known longer known reliably. */
static rtx
-get_last_value (x)
- rtx x;
+get_last_value (rtx x)
{
unsigned int regno;
rtx value;
@@ -12032,9 +11883,7 @@ get_last_value (x)
that is set in an instruction more recent than FROM_CUID. */
static int
-use_crosses_set_p (x, from_cuid)
- rtx x;
- int from_cuid;
+use_crosses_set_p (rtx x, int from_cuid)
{
const char *fmt;
int i;
@@ -12092,10 +11941,7 @@ static int reg_dead_flag;
reg_dead_flag to 1 if X is a CLOBBER and to -1 it is a SET. */
static void
-reg_dead_at_p_1 (dest, x, data)
- rtx dest;
- rtx x;
- void *data ATTRIBUTE_UNUSED;
+reg_dead_at_p_1 (rtx dest, rtx x, void *data ATTRIBUTE_UNUSED)
{
unsigned int regno, endregno;
@@ -12119,9 +11965,7 @@ reg_dead_at_p_1 (dest, x, data)
must be assumed to be always live. */
static int
-reg_dead_at_p (reg, insn)
- rtx reg;
- rtx insn;
+reg_dead_at_p (rtx reg, rtx insn)
{
basic_block block;
unsigned int i;
@@ -12162,7 +12006,7 @@ reg_dead_at_p (reg, insn)
else
{
FOR_EACH_BB (block)
- if (insn == block->head)
+ if (insn == BB_HEAD (block))
break;
if (block == EXIT_BLOCK_PTR)
@@ -12180,8 +12024,7 @@ reg_dead_at_p (reg, insn)
that in flow.c, but much simpler since we don't care about pseudos. */
static void
-mark_used_regs_combine (x)
- rtx x;
+mark_used_regs_combine (rtx x)
{
RTX_CODE code = GET_CODE (x);
unsigned int regno;
@@ -12286,9 +12129,7 @@ mark_used_regs_combine (x)
Return the note used to record the death, if there was one. */
rtx
-remove_death (regno, insn)
- unsigned int regno;
- rtx insn;
+remove_death (unsigned int regno, rtx insn)
{
rtx note = find_regno_note (insn, REG_DEAD, regno);
@@ -12312,12 +12153,8 @@ remove_death (regno, insn)
notes will then be distributed as needed. */
static void
-move_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes)
- rtx x;
- rtx maybe_kill_insn;
- int from_cuid;
- rtx to_insn;
- rtx *pnotes;
+move_deaths (rtx x, rtx maybe_kill_insn, int from_cuid, rtx to_insn,
+ rtx *pnotes)
{
const char *fmt;
int len, i;
@@ -12485,9 +12322,7 @@ move_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes)
pattern of an insn. X must be a REG. */
static int
-reg_bitfield_target_p (x, body)
- rtx x;
- rtx body;
+reg_bitfield_target_p (rtx x, rtx body)
{
int i;
@@ -12532,19 +12367,11 @@ reg_bitfield_target_p (x, body)
as appropriate. I3 and I2 are the insns resulting from the combination
insns including FROM (I2 may be zero).
- ELIM_I2 and ELIM_I1 are either zero or registers that we know will
- not need REG_DEAD notes because they are being substituted for. This
- saves searching in the most common cases.
-
Each note in the list is either ignored or placed on some insns, depending
on the type of note. */
static void
-distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
- rtx notes;
- rtx from_insn;
- rtx i3, i2;
- rtx elim_i2, elim_i1;
+distribute_notes (rtx notes, rtx from_insn, rtx i3, rtx i2)
{
rtx note, next_note;
rtx tem;
@@ -12570,6 +12397,10 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
place = i3;
break;
+ case REG_VALUE_PROFILE:
+ /* Just get rid of this note, as it is unused later anyway. */
+ break;
+
case REG_VTABLE_REF:
/* ??? Should remain with *a particular* memory load. Given the
nature of vtable data, the last insn seems relatively safe. */
@@ -12739,8 +12570,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
break;
case REG_NONNEG:
- case REG_WAS_0:
- /* These notes say something about the value of a register prior
+ /* This note says something about the value of a register prior
to the execution of an insn. It is too much trouble to see
if the note is still correct in all situations. It is better
to simply delete it. */
@@ -12762,6 +12592,9 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
libcall sequence, don't add the notes. */
else if (XEXP (note, 0) == from_insn)
tem = place = 0;
+ /* Don't add the dangling REG_RETVAL note. */
+ else if (! tem)
+ place = 0;
}
break;
@@ -12779,6 +12612,9 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
libcall sequence, don't add the notes. */
else if (XEXP (note, 0) == from_insn)
tem = place = 0;
+ /* Don't add the dangling REG_LIBCALL note. */
+ else if (! tem)
+ place = 0;
}
break;
@@ -12807,10 +12643,6 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
&& reg_referenced_p (XEXP (note, 0), PATTERN (i2)))
place = i2;
- if (rtx_equal_p (XEXP (note, 0), elim_i2)
- || rtx_equal_p (XEXP (note, 0), elim_i1))
- break;
-
if (place == 0)
{
basic_block bb = this_basic_block;
@@ -12819,15 +12651,18 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
{
if (! INSN_P (tem))
{
- if (tem == bb->head)
+ if (tem == BB_HEAD (bb))
break;
continue;
}
/* If the register is being set at TEM, see if that is all
TEM is doing. If so, delete TEM. Otherwise, make this
- into a REG_UNUSED note instead. */
- if (reg_set_p (XEXP (note, 0), PATTERN (tem)))
+ into a REG_UNUSED note instead. Don't delete sets to
+ global register vars. */
+ if ((REGNO (XEXP (note, 0)) >= FIRST_PSEUDO_REGISTER
+ || !global_regs[REGNO (XEXP (note, 0))])
+ && reg_set_p (XEXP (note, 0), PATTERN (tem)))
{
rtx set = single_set (tem);
rtx inner_dest = 0;
@@ -12864,11 +12699,12 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
This might delete other dead insns recursively.
First set the pattern to something that won't use
any register. */
+ rtx old_notes = REG_NOTES (tem);
PATTERN (tem) = pc_rtx;
+ REG_NOTES (tem) = NULL;
- distribute_notes (REG_NOTES (tem), tem, tem,
- NULL_RTX, NULL_RTX, NULL_RTX);
+ distribute_notes (old_notes, tem, tem, NULL_RTX);
distribute_links (LOG_LINKS (tem));
PUT_CODE (tem, NOTE);
@@ -12880,10 +12716,11 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
if (cc0_setter)
{
PATTERN (cc0_setter) = pc_rtx;
+ old_notes = REG_NOTES (cc0_setter);
+ REG_NOTES (cc0_setter) = NULL;
- distribute_notes (REG_NOTES (cc0_setter),
- cc0_setter, cc0_setter,
- NULL_RTX, NULL_RTX, NULL_RTX);
+ distribute_notes (old_notes, cc0_setter,
+ cc0_setter, NULL_RTX);
distribute_links (LOG_LINKS (cc0_setter));
PUT_CODE (cc0_setter, NOTE);
@@ -12944,7 +12781,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
break;
}
- if (tem == bb->head)
+ if (tem == BB_HEAD (bb))
break;
}
@@ -12956,10 +12793,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
if (REG_NOTE_KIND (note) == REG_DEAD && place == 0
&& REGNO_REG_SET_P (bb->global_live_at_start,
REGNO (XEXP (note, 0))))
- {
- SET_BIT (refresh_blocks, this_basic_block->index);
- need_refresh = 1;
- }
+ SET_BIT (refresh_blocks, this_basic_block->index);
}
/* If the register is set or already dead at PLACE, we needn't do
@@ -12976,10 +12810,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
the note is a noop, we'll need do a global live update
after we remove them in delete_noop_moves. */
if (noop_move_p (place))
- {
- SET_BIT (refresh_blocks, this_basic_block->index);
- need_refresh = 1;
- }
+ SET_BIT (refresh_blocks, this_basic_block->index);
if (dead_or_set_p (place, XEXP (note, 0))
|| reg_bitfield_target_p (XEXP (note, 0), PATTERN (place)))
@@ -13037,7 +12868,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
= gen_rtx_EXPR_LIST (REG_DEAD, piece, NULL_RTX);
distribute_notes (new_note, place, place,
- NULL_RTX, NULL_RTX, NULL_RTX);
+ NULL_RTX);
}
else if (! refers_to_regno_p (i, i + 1,
PATTERN (place), 0)
@@ -13047,11 +12878,10 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
{
if (! INSN_P (tem))
{
- if (tem == bb->head)
+ if (tem == BB_HEAD (bb))
{
SET_BIT (refresh_blocks,
this_basic_block->index);
- need_refresh = 1;
break;
}
continue;
@@ -13111,8 +12941,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
pointing at I3 when I3's destination is changed. */
static void
-distribute_links (links)
- rtx links;
+distribute_links (rtx links)
{
rtx link, next_link;
@@ -13156,7 +12985,7 @@ distribute_links (links)
for (insn = NEXT_INSN (XEXP (link, 0));
(insn && (this_basic_block->next_bb == EXIT_BLOCK_PTR
- || this_basic_block->next_bb->head != insn));
+ || BB_HEAD (this_basic_block->next_bb) != insn));
insn = NEXT_INSN (insn))
if (INSN_P (insn) && reg_overlap_mentioned_p (reg, PATTERN (insn)))
{
@@ -13170,6 +12999,8 @@ distribute_links (links)
place = insn;
break;
}
+ else if (INSN_P (insn) && reg_set_p (reg, insn))
+ break;
/* If we found a place to put the link, place it there unless there
is already a link to the same insn as LINK at that point. */
@@ -13200,8 +13031,7 @@ distribute_links (links)
/* Compute INSN_CUID for INSN, which is an insn made by combine. */
static int
-insn_cuid (insn)
- rtx insn;
+insn_cuid (rtx insn)
{
while (insn != 0 && INSN_UID (insn) > max_uid_cuid
&& GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == USE)
@@ -13214,8 +13044,7 @@ insn_cuid (insn)
}
void
-dump_combine_stats (file)
- FILE *file;
+dump_combine_stats (FILE *file)
{
fnotice
(file,
@@ -13224,8 +13053,7 @@ dump_combine_stats (file)
}
void
-dump_combine_total_stats (file)
- FILE *file;
+dump_combine_total_stats (FILE *file)
{
fnotice
(file,
diff --git a/contrib/gcc/common.opt b/contrib/gcc/common.opt
new file mode 100644
index 000000000000..261c8d299bb3
--- /dev/null
+++ b/contrib/gcc/common.opt
@@ -0,0 +1,808 @@
+; Options for the language- and target-independent parts of the compiler.
+; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the Free
+; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+; 02111-1307, USA.
+
+; See c.opt for a description of this file's format.
+
+; Please try to keep this file in ASCII collating order.
+
+-help
+Common
+Display this information
+
+-param
+Common Separate
+--param <param>=<value> Set paramter <param> to value. See below for a complete list of parameters
+
+-target-help
+Common
+
+-version
+Common
+
+G
+Common Joined Separate UInteger
+-G<number> Put global and static data smaller than <number> bytes into a special section (on some targets)
+
+O
+Common JoinedOrMissing
+-O<number> Set optimization level to <number>
+
+Os
+Common
+Optimize for space rather than speed
+
+W
+Common RejectNegative
+This switch is deprecated; use -Wextra instead
+
+Waggregate-return
+Common
+Warn about returning structures, unions or arrays
+
+Wcast-align
+Common
+Warn about pointer casts which increase alignment
+
+Wdeprecated-declarations
+Common
+Warn about uses of __attribute__((deprecated)) declarations
+
+Wdisabled-optimization
+Common
+Warn when an optimization pass is disabled
+
+Werror
+Common
+Treat all warnings as errors
+
+Wextra
+Common
+Print extra (possibly unwanted) warnings
+
+Winline
+Common
+Warn when an inlined function cannot be inlined
+
+Wlarger-than-
+Common RejectNegative Joined UInteger
+-Wlarger-than-<number> Warn if an object is larger than <number> bytes
+
+Wmissing-noreturn
+Common
+Warn about functions which might be candidates for __attribute__((noreturn))
+
+Wpacked
+Common
+Warn when the packed attribute has no effect on struct layout
+
+Wpadded
+Common
+Warn when padding is required to align structure members
+
+Wshadow
+Common
+Warn when one local variable shadows another
+
+Wstrict-aliasing
+Common
+Warn about code which might break strict aliasing rules
+
+Wswitch
+Common
+Warn about enumerated switches, with no default, missing a case
+
+Wswitch-default
+Common
+Warn about enumerated switches missing a \"default:\" statement
+
+Wswitch-enum
+Common
+Warn about all enumerated switches missing a specific case
+
+Wsystem-headers
+Common
+Do not suppress warnings from system headers
+
+Wuninitialized
+Common
+Warn about uninitialized automatic variables
+
+Wunreachable-code
+Common
+Warn about code that will never be executed
+
+Wunused
+Common
+Enable all -Wunused- warnings
+
+Wunused-function
+Common
+Warn when a function is unused
+
+Wunused-label
+Common
+Warn when a label is unused
+
+Wunused-parameter
+Common
+Warn when a function parameter is unused
+
+Wunused-value
+Common
+Warn when an expression value is unused
+
+Wunused-variable
+Common
+Warn when a variable is unused
+
+aux-info
+Common Separate
+-aux-info <file> Emit declaration information into <file>
+
+aux-info=
+Common Joined
+
+auxbase
+Common Separate
+
+auxbase-strip
+Common Separate
+
+d
+Common Joined
+-d<letters> Enable dumps from specific passes of the compiler
+
+dumpbase
+Common Separate
+-dumpbase <file> Set the file basename to be used for dumps
+
+fPIC
+Common
+
+fPIE
+Common
+
+fabi-version=
+Common Joined UInteger
+
+falign-functions
+Common
+Align the start of functions
+
+falign-functions=
+Common RejectNegative Joined UInteger
+
+falign-jumps
+Common
+Align labels which are only reached by jumping
+
+falign-jumps=
+Common RejectNegative Joined UInteger
+
+falign-labels
+Common
+Align all labels
+
+falign-labels=
+Common RejectNegative Joined UInteger
+
+falign-loops
+Common
+Align the start of loops
+
+falign-loops=
+Common RejectNegative Joined UInteger
+
+fargument-alias
+Common
+Specify that arguments may alias each other and globals
+
+fargument-noalias
+Common
+Assume arguments may alias globals but not each other
+
+fargument-noalias-global
+Common
+Assume arguments alias neither each other nor globals
+
+fasynchronous-unwind-tables
+Common
+Generate unwind tables that are exact at each instruction boundary
+
+fbounds-check
+Common
+Generate code to check bounds before indexing arrays
+
+fbranch-count-reg
+Common
+Replace add, compare, branch with branch on count register
+
+fbranch-probabilities
+Common
+Use profiling information for branch probabilities
+
+fbranch-target-load-optimize
+Common
+Perform branch target load optimization before prologue / epilogue threading
+
+fbranch-target-load-optimize2
+Common
+Perform branch target load optimization after prologue / epilogue threading
+
+fcall-saved-
+Common Joined RejectNegative
+-fcall-saved-<register> Mark <register> as being preserved across functions
+
+fcall-used-
+Common Joined RejectNegative
+-fcall-used-<register> Mark <register> as being corrupted by function calls
+
+fcaller-saves
+Common
+Save registers around function calls
+
+fcommon
+Common
+Do not put uninitialized globals in the common section
+
+fcprop-registers
+Common
+Perform a register copy-propagation optimization pass
+
+fcrossjumping
+Common
+Perform cross-jumping optimization
+
+fcse-follow-jumps
+Common
+When running CSE, follow jumps to their targets
+
+fcse-skip-blocks
+Common
+When running CSE, follow conditional jumps
+
+fdata-sections
+Common
+Place data items into their own section
+
+fdefer-pop
+Common
+Defer popping functions args from stack until later
+
+fdelayed-branch
+Common
+Attempt to fill delay slots of branch instructions
+
+fdelete-null-pointer-checks
+Common
+Delete useless null pointer checks
+
+fdiagnostics-show-location=
+Common Joined RejectNegative
+-fdiagnostics-show-location=[once|every-line] How often to emit source location at the beginning of line-wrapped diagnostics
+
+fdump-unnumbered
+Common
+Suppress output of instruction numbers and line number notes in debugging dumps
+
+feliminate-dwarf2-dups
+Common
+Perform DWARF2 duplicate elimination
+
+feliminate-unused-debug-symbols
+Common
+Perform unused type elimination in debug info
+
+feliminate-unused-debug-types
+Common
+Perform unused type elimination in debug info
+
+fexceptions
+Common
+Enable exception handling
+
+fexpensive-optimizations
+Common
+Perform a number of minor, expensive optimizations
+
+ffast-math
+Common
+
+ffinite-math-only
+Common
+Assume no NaNs or infinities are generated
+
+ffixed-
+Common Joined RejectNegative
+-ffixed-<register> Mark <register> as being unavailable to the compiler
+
+ffloat-store
+Common
+Do not store floats in registers
+
+fforce-addr
+Common
+Copy memory address constants into registers before use
+
+fforce-mem
+Common
+Copy memory operands into registers before use
+
+ffunction-cse
+Common
+Allow function addresses to be held in registers
+
+ffunction-sections
+Common
+Place each function into its own section
+
+fgcse
+Common
+Perform global common subexpression elimination
+
+fgcse-lm
+Common
+Perform enhanced load motion during global common subexpression elimination
+
+fgcse-sm
+Common
+Perform store motion after global common subexpression elimination
+
+fgcse-las
+Common
+Perform redundant load after store elimination in global common subexpression elimination
+
+fguess-branch-probability
+Common
+Enable guessing of branch probabilities
+
+fident
+Common
+Process #ident directives
+
+fif-conversion
+Common
+Perform conversion of conditional jumps to branchless equivalents
+
+fif-conversion2
+Common
+Perform conversion of conditional jumps to conditional execution
+
+finhibit-size-directive
+Common
+Do not generate .size directives
+
+finline
+Common
+Pay attention to the \"inline\" keyword
+
+finline-functions
+Common
+Integrate simple functions into their callers
+
+finline-limit-
+Common RejectNegative Joined UInteger
+
+finline-limit=
+Common RejectNegative Joined UInteger
+-finline-limit=<number> Limit the size of inlined functions to <number>
+
+finstrument-functions
+Common
+Instrument function entry and exit with profiling calls
+
+fkeep-inline-functions
+Common
+Generate code for functions even if they are fully inlined
+
+fkeep-static-consts
+Common
+Emit static const variables even if they are not used
+
+fleading-underscore
+Common
+Give external symbols a leading underscore
+
+floop-optimize
+Common
+Perform loop optimizations
+
+fmath-errno
+Common
+Set errno after built-in math functions
+
+fmem-report
+Common
+Report on permanent memory allocation
+
+fmerge-all-constants
+Common
+Attempt to merge identical constants and constant variables
+
+fmerge-constants
+Common
+Attempt to merge identical constants across compilation units
+
+fmessage-length=
+Common RejectNegative Joined UInteger
+-fmessage-length=<number> Limit diagnostics to <number> characters per line. 0 suppresses line-wrapping
+
+fmove-all-movables
+Common
+Force all loop invariant computations out of loops
+
+fnew-ra
+Common
+Use graph-coloring register allocation
+
+fnon-call-exceptions
+Common
+Support synchronous non-call exceptions
+
+fold-unroll-loops
+Common
+Perform loop unrolling when iteration count is known
+
+fold-unroll-all-loops
+Common
+Perform loop unrolling for all loops
+
+fomit-frame-pointer
+Common
+When possible do not generate stack frames
+
+foptimize-register-move
+Common
+Do the full register move optimization pass
+
+foptimize-sibling-calls
+Common
+Optimize sibling and tail recursive calls
+
+fpack-struct
+Common
+Pack structure members together without holes
+
+fpcc-struct-return
+Common
+Return small aggregates in memory, not registers
+
+fpeel-loops
+Common
+Perform loop peeling
+
+fpeephole
+Common
+Enable machine specific peephole optimizations
+
+fpeephole2
+Common
+Enable an RTL peephole pass before sched2
+
+fpic
+Common
+Generate position-independent code if possible
+
+fpie
+Common
+Generate position-independent code for executables if possible
+
+fprefetch-loop-arrays
+Common
+Generate prefetch instructions, if available, for arrays in loops
+
+fprofile
+Common
+Enable basic program profiling code
+
+fprofile-arcs
+Common
+Insert arc-based program profiling code
+
+fprofile-generate
+Common
+Enable common options for generating profile info for profile feedback directed optimizations
+
+fprofile-use
+Common
+Enable common options for performing profile feedback directed optimizations
+
+fprofile-values
+Common
+Insert code to profile values of expressions
+
+frandom-seed
+Common
+
+frandom-seed=
+Common Joined RejectNegative
+-frandom-seed=<string> Make compile reproducible using <string>
+
+freduce-all-givs
+Common
+Strength reduce all loop general induction variables
+
+freg-struct-return
+Common
+Return small aggregates in registers
+
+fregmove
+Common
+Enables a register move optimization
+
+frename-registers
+Common
+Perform a register renaming optimization pass
+
+freorder-blocks
+Common
+Reorder basic blocks to improve code placement
+
+freorder-functions
+Common
+Reorder functions to improve code placement
+
+frerun-cse-after-loop
+Common
+Add a common subexpression elimination pass after loop optimizations
+
+frerun-loop-opt
+Common
+Run the loop optimizer twice
+
+frounding-math
+Common
+Disable optimizations that assume default FP rounding behavior
+
+fsched-interblock
+Common
+Enable scheduling across basic blocks
+
+fsched-spec
+Common
+Allow speculative motion of non-loads
+
+fsched-spec-load
+Common
+Allow speculative motion of some loads
+
+fsched-spec-load-dangerous
+Common
+Allow speculative motion of more loads
+
+fsched-verbose=
+Common RejectNegative Joined
+-fsched-verbose=<number> Set the verbosity level of the scheduler
+
+fsched2-use-superblocks
+Common
+If scheduling post reload, do superblock scheduling
+
+fsched2-use-traces
+Common
+If scheduling post reload, do trace scheduling
+
+fschedule-insns
+Common
+Reschedule instructions before register allocation
+
+fschedule-insns2
+Common
+Reschedule instructions after register allocation
+
+fsched-stalled-insns
+Common
+Allow premature scheduling of queued insns
+
+fsched-stalled-insns=
+Common RejectNegative Joined UInteger
+-fsched-stalled-insns=<number> Set number of queued insns that can be prematurely scheduled
+
+fsched-stalled-insns-dep
+Common
+Set dependence distance checking in premature scheduling of queued insns
+
+fsched-stalled-insns-dep=
+Common RejectNegative Joined UInteger
+-fsched-stalled-insns-dep=<number> Set dependence distance checking in premature scheduling of queued insns
+
+fshared-data
+Common
+Mark data as shared rather than private
+
+fsignaling-nans
+Common
+Disable optimizations observable by IEEE signaling NaNs
+
+fsingle-precision-constant
+Common
+Convert floating point constants to single precision constants
+
+fstack-check
+Common
+Insert stack checking code into the program
+
+fstack-limit
+Common
+
+fstack-limit-register=
+Common RejectNegative Joined
+-fstack-limit-register=<register> Trap if the stack goes past <register>
+
+fstack-limit-symbol=
+Common RejectNegative Joined
+-fstack-limit-symbol=<name> Trap if the stack goes past symbol <name>
+
+fstrength-reduce
+Common
+Perform strength reduction optimizations
+
+fstrict-aliasing
+Common
+Assume strict aliasing rules apply
+
+fsyntax-only
+Common
+Check for syntax errors, then stop
+
+ftest-coverage
+Common
+Create data files needed by \"gcov\"
+
+fthread-jumps
+Common
+Perform jump threading optimizations
+
+ftime-report
+Common
+Report the time taken by each compiler pass
+
+ftls-model=
+Common Joined RejectNegative
+-ftls-model=[global-dynamic|local-dynamic|initial-exec|local-exec] Set the default thread-local storage code generation model
+
+ftracer
+Common
+Perform superblock formation via tail duplication
+
+ftrapping-math
+Common
+Assume floating-point operations can trap
+
+ftrapv
+Common
+Trap for signed overflow in addition, subtraction and multiplication
+
+funit-at-a-time
+Common
+Compile whole compilation unit at a time
+
+funroll-loops
+Common
+Perform loop unrolling when iteration count is known
+
+funroll-all-loops
+Common
+Perform loop unrolling for all loops
+
+funsafe-math-optimizations
+Common
+Allow math optimizations that may violate IEEE or ISO standards
+
+funswitch-loops
+Common
+Perform loop unswitching
+
+funwind-tables
+Common
+Just generate unwind tables for exception handling
+
+fverbose-asm
+Common
+Add extra commentary to assembler output
+
+fvpt
+Common
+Use expression value profiles in optimizations
+
+fweb
+Common
+Construct webs and split unrelated uses of single variable
+
+fwrapv
+Common
+Assume signed arithmetic overflow wraps around
+
+fwritable-strings
+Common
+Store strings in writable data section
+
+fzero-initialized-in-bss
+Common
+Put zero initialized data in the bss section
+
+g
+Common JoinedOrMissing
+Generate debug information in default format
+
+gcoff
+Common JoinedOrMissing
+Generate debug information in COFF format
+
+gdwarf-2
+Common JoinedOrMissing
+Generate debug information in DWARF v2 format
+
+ggdb
+Common JoinedOrMissing
+Generate debug information in default extended format
+
+gstabs
+Common JoinedOrMissing
+Generate debug information in STABS format
+
+gstabs+
+Common JoinedOrMissing
+Generate debug information in extended STABS format
+
+gvms
+Common JoinedOrMissing
+Generate debug information in VMS format
+
+gxcoff
+Common JoinedOrMissing
+Generate debug information in XCOFF format
+
+gxcoff+
+Common JoinedOrMissing
+Generate debug information in extended XCOFF format
+
+m
+Common Joined
+
+o
+Common Joined Separate
+-o <file> Place output into <file>
+
+p
+Common
+Enable function profiling
+
+pedantic
+Common
+Issue warnings needed for strict compliance to the standard
+
+pedantic-errors
+Common
+Like -pedantic but issue them as errors
+
+quiet
+Common
+Do not display functions compiled or elapsed time
+
+version
+Common
+Display the compiler's version
+
+w
+Common
+Suppress warnings
+
+; This comment is to ensure we retain the blank line above.
diff --git a/contrib/gcc/config.build b/contrib/gcc/config.build
new file mode 100644
index 000000000000..83b126b9dfe5
--- /dev/null
+++ b/contrib/gcc/config.build
@@ -0,0 +1,123 @@
+# GCC build-specific configuration file.
+# Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# 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 2, 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 COPYING. If not, write to the Free
+#Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+#02111-1307, USA.
+
+# This is the GCC build-specific configuration file
+# where a configuration type is mapped to different system-specific
+# definitions and files. This is invoked by the autoconf-generated
+# configure script. Putting it in a separate shell file lets us skip
+# running autoconf when modifying build-specific information.
+
+# This file switches on the shell variable ${build}. As much of this
+# as possible should be replaced with autoconf tests in the future.
+
+# This file sets the following shell variables for use by the
+# autoconf-generated configure script:
+#
+# build_xm_defines List of macros to define when compiling for the
+# build machine.
+#
+# build_xm_file List of files to include when compiling for the
+# build machine.
+#
+# build_install_headers_dir
+# Target to use when installing header files.
+#
+# build_exeext Set to the suffix, if the build machine requires
+# executables to have a file name suffix.
+
+# Default settings.
+build_xm_file=
+build_xm_defines=
+build_exeext=
+build_install_headers_dir=install-headers-tar
+
+# System-specific settings.
+case $build in
+ alpha*-dec-osf4*)
+ # Some versions of OSF4 (specifically X4.0-9 296.7) have
+ # a broken tar, so we use cpio instead.
+ build_install_headers_dir=install-headers-cpio
+ ;;
+ alpha*-dec-*vms*)
+ build_xm_file=alpha/xm-vms.h
+ build_exeext=.exe
+ build_install_headers_dir=install-headers-cp
+ prefix=/gnu
+ local_prefix=/gnu
+ ;;
+ hppa1.0-*-hpux1[01]* | \
+ hppa*64*-*-hpux11* | \
+ hppa1.1-*-hpux11* | \
+ hppa2*-*-hpux11* )
+ build_install_headers_dir=install-headers-cpio
+ ;;
+ i370-*-opened* | i370-*-mvs* )
+ # IBM 360/370/390 Architecture
+ build_xm_defines='FATAL_EXIT_CODE=12'
+ ;;
+ i[34567]86-*-cygwin* | i[34567]86-*-pe )
+ build_xm_file=i386/xm-cygwin.h
+ build_exeext=.exe
+ ;;
+ i[34567]86-*-mingw32*)
+ build_xm_file=i386/xm-mingw32.h
+ build_exeext=.exe
+ ;;
+ i[34567]86-pc-msdosdjgpp*)
+ build_xm_file=i386/xm-djgpp.h
+ build_exeext=.exe
+ ;;
+ i[34567]86-*-sco3.2v5*)
+ # 80386 running SCO Open Server 5
+ build_install_headers_dir=install-headers-cpio
+ ;;
+ i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4* )
+ build_xm_defines="SMALL_ARG_MAX"
+ build_install_headers_dir=install-headers-cpio
+ ;;
+ i[34567]86-*-solaris2*)
+ build_xm_defines="SMALL_ARG_MAX"
+ ;;
+ i[34567]86-*-sysv4*)
+ # Intel x86 running system V r4
+ build_xm_defines="SMALL_ARG_MAX"
+ build_install_headers_dir=install-headers-cpio
+ ;;
+ i[34567]86-*-udk*)
+ # Intel x86 on SCO UW/OSR5 Dev Kit
+ build_install_headers_dir=install-headers-cpio
+ ;;
+ i[34567]86-*-uwin*)
+ build_exeext=.exe
+ ;;
+ i386-*-vsta)
+ # Intel 80386's running VSTa kernel
+ ;;
+ m68000-hp-hpux* | m68k-hp-hpux*)
+ # HP 9000 series 300
+ build_install_headers_dir=install-headers-cpio
+ ;;
+ *-*-sysv*)
+ # All other System V variants.
+ build_install_headers_dir=install-headers-cpio
+ ;;
+esac
+
diff --git a/contrib/gcc/config.gcc b/contrib/gcc/config.gcc
index e00f913bb7f8..09466478a9de 100644
--- a/contrib/gcc/config.gcc
+++ b/contrib/gcc/config.gcc
@@ -1,5 +1,6 @@
-# GCC build-, host- and target-specific configuration file.
-# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+# GCC target-specific configuration file.
+# Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+# Free Software Foundation, Inc.
#This file is part of GCC.
@@ -18,15 +19,13 @@
#Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#02111-1307, USA.
-# This is the GCC build-, host- and target-specific configuration file
-# where a configuration type, as recognized and generated by config.bfd,
-# is mapped to different system-specific definitions and files. This is
-# invoked by the autoconf-generated configure script, called for build,
-# host and target in that order, setting ${machine} to each. Putting it
-# in a separate shell file lets us skip running autoconf when modifying
-# build-, host- and target-specific information.
+# This is the GCC target-specific configuration file
+# where a configuration type is mapped to different system-specific
+# definitions and files. This is invoked by the autoconf-generated
+# configure script. Putting it in a separate shell file lets us skip
+# running autoconf when modifying target-specific information.
-# This file switches on the shell variable ${machine}, and also uses the
+# This file switches on the shell variable ${target}, and also uses the
# following shell variables:
#
# with_* Various variables as set by configure.
@@ -34,6 +33,11 @@
# enable_threads_flag Either the name, yes or no depending on whether
# threads support was requested.
#
+# default_use_cxa_atexit
+# "no" by default, can be set to "yes" if a target
+# wishes to use __cxa_atexit() by default if the
+# $enable___cxa_atexit variable is not set.
+#
# gas_flag Either yes or no depending on whether GNU as was
# requested.
#
@@ -43,7 +47,8 @@
# This file sets the following shell variables for use by the
# autoconf-generated configure script:
#
-# cpu_type The name of the cpu, if different from machine.
+# cpu_type The name of the cpu, if different from the first
+# chunk of the canonical target name.
#
# tm_defines List of target macros to define for all compilations.
#
@@ -79,11 +84,12 @@
# the compiler proper (cc1, cc1obj, cc1plus)
# depending on target.
#
+# extra_gcc_objs List of extra objects that should be linked into
+# the compiler driver (gcc) depending on target.
+#
# extra_headers List of used header files from the directory
# config/${cpu_type}.
#
-# host_xmake_file List of host-specific makefile-fragments.
-#
# extra_passes List of extra executables compiled for this target
# machine, used for compiling from source to object.
#
@@ -92,12 +98,6 @@
#
# extra_programs Like extra_passes, but these are used when linking.
#
-# host_extra_objs List of extra host-dependent objects that should
-# be linked into the compiler proper.
-#
-# host_extra_gcc_objs List of extra host-dependent objects that should
-# be linked into the gcc driver.
-#
# c_target_objs List of extra target-dependent objects that be
# linked into the C compiler only.
#
@@ -106,18 +106,6 @@
#
# target_gtfiles List of extra source files with type information.
#
-# build_xm_defines List of macros to define when compiling for the
-# build machine.
-#
-# build_xm_file List of files to include when compiling for the
-# build machine.
-#
-# host_xm_defines List of macros to define when compiling for the
-# host machine.
-#
-# host_xm_file List of files to include when compiling for the
-# host machine.
-#
# xm_defines List of macros to define when compiling for the
# target machine.
#
@@ -129,60 +117,42 @@
#
# target_cpu_default Set to override the default target model.
#
-# build_install_headers_dir
-# Target to use when installing header files.
-#
-# host_truncate_target
-# Non-empty if the target name should be truncated
-# on this host, due to filename length issues.
-#
# gdb_needs_out_file_path
# Set to yes if gdb needs a dir command with
# `dirname $out_file`.
#
-# build_exeext Set to the suffix, if the build machine requires
-# executables to have a file name suffix.
-#
-# host_exeext Set to the suffix, if the host machine requires
-# executables to have a file name suffix.
-#
# thread_file Set to control which thread package to use.
#
# gas Set to yes or no depending on whether the target
# system normally uses GNU as.
-
-# The following variables are used in each case-construct to build up the
-# outgoing variables:
-#
-# xmake_file Makefile-fragment when this system is as a host,
-# for host_xmake_file.
#
-# extra_host_objs List of extra objects that should be linked into
-# the compiler proper when this system is a host,
-# for host_extra_objs.
+# need_64bit_hwint Set to yes if HOST_WIDE_INT must be 64 bits wide
+# for this target. This is true iff
+# MAX_LONG_TYPE_SIZE is 64. (The code which
+# determines the underlying integral type for
+# HOST_WIDE_INT cannot see the definition of
+# MAX_LONG_TYPE_SIZE.)
#
-# install_headers_dir Makefile-target for how the header file directory
-# is installed, when this system is a build system,
-# for build_install_headers_dir.
+# configure_default_options
+# Set to an initializer for configure_default_options
+# in configargs.h, based on --with-cpu et cetera.
#
-# truncate_target Non-empty if the target name should be truncated
-# when this system is a host, due to filename length
-# issues. For host_truncate_target.
-#
-# exeext The suffix for executables on this system.
+# use_fixproto Set to "yes" if fixproto should be run normally,
+# "no" if fixproto should never be run.
+
+# The following variables are used in each case-construct to build up the
+# outgoing variables:
#
# gnu_ld Set to yes or no depending on whether the target
# system normally uses GNU ld.
out_file=
-xmake_file=
tmake_file=
extra_headers=
extra_passes=
extra_parts=
extra_programs=
extra_objs=
-extra_host_objs=
extra_gcc_objs=
c_target_objs=
cxx_target_objs=
@@ -192,15 +162,8 @@ xm_defines=
use_collect2=
# Set this to override the default target model.
target_cpu_default=
-# Set this to control how the header file directory is installed.
-install_headers_dir=install-headers-tar
-# Set this if directory names should be truncated to 14 characters.
-truncate_target=
# Set this if gdb needs a dir command with `dirname $out_file`
gdb_needs_out_file_path=
-# Set this if the build machine requires executables to have a
-# file name suffix.
-exeext=
# Set this to control which thread package will be used.
thread_file=
# Reinitialize these from the flag values every loop pass, since some
@@ -208,69 +171,39 @@ thread_file=
gas="$gas_flag"
gnu_ld="$gnu_ld_flag"
enable_threads=$enable_threads_flag
+default_use_cxa_atexit=no
target_gtfiles=
+need_64bit_hwint=
+
+# Default to not using fixproto. Targets which need fixproto should
+# specifically set this to 'yes'.
+use_fixproto=no
+
+# Don't carry these over build->host->target. Please.
+xm_file=
+md_file=
# Obsolete configurations.
-case $machine in
- m88k-*-* \
- | mn10200-*-* \
- | romp-*-* \
- | alpha*-*-interix* \
- | alpha*-*-linux*libc1* \
- | alpha*-*-linux*ecoff* \
- | arm*-*-aout* \
- | arm*-*-conix* \
- | arm*-*-oabi \
- | strongarm-*-coff* \
- | hppa1.0-*-osf* \
- | hppa1.0-*-bsd* \
- | hppa1.[01]-*-hpux[789]* \
- | hppa*-*-hiux* \
- | hppa*-*-lites* \
- | i?86-*-win32 \
- | m68000-hp-bsd* \
- | m68000-sun-sunos* \
- | m68000-att-sysv* \
- | m68k-atari-sysv* \
- | m68k-motorola-sysv* \
- | m68k-ncr-sysv* \
- | m68k-plexus-sysv* \
- | m68k-tti-* \
- | m68k-crds-unos* \
- | m68k-cbm-sysv* \
- | m68k-ccur-rtu* \
- | m68k-hp-bsd* \
- | m68k-sun-mach* \
- | m68k-sun-sunos* \
- | m68k-*-linux*aout* \
- | m68k-*-linux*libc1* \
- | m68k-*-psos* \
- | mips*-*-ecoff* \
- | mips-sni-sysv4 \
- | mips64orion-*-rtems* \
- | ns32k-*-openbsd* \
- | powerpc*-*-sysv* \
- | powerpc*-*-linux*libc1* \
- | rs6000-ibm-aix[123]* \
- | rs6000-bull-bosx \
- | rs6000-*-mach* \
- | sparc-*-aout* \
- | sparc-*-netbsd*aout* \
- | sparc-*-bsd* \
- | sparc-*-chorusos* \
- | sparc-*-linux*aout* \
- | sparc-*-linux*libc1* \
- | sparc-*-lynxos* \
- | sparc-hal-solaris2* \
- | sparc-*-sunos[34]* \
- | sparclet-*-aout* \
- | sparclite-*-aout* \
- | sparc86x-*-aout* \
- | v850-*-rtems* \
- | vax-*-vms* \
- )
+case ${target} in
+ d30v-* | \
+ dsp16xx-* | \
+ i370-* | \
+ i960-* | \
+ i?86-moss-msdos | i?86-*-moss* | \
+ i?86-ncr-sysv4* | \
+ i?86-*-netware | \
+ i?86-*-freebsd2* | i?86-*-freebsd*aout* | \
+ i?86-*-linux*aout* | \
+ i?86-*-linux*libc1* | \
+ i?86-*-interix | \
+ i?86-*-mach* | \
+ i?86-*-udk* | \
+ i?86-*-sysv[123]* | \
+ i386-*-vsta | \
+ m68k-hp-hpux* | m68000-hp-hpux* | \
+ m68k-*-sysv4*)
if test "x$enable_obsolete" != xyes; then
- echo "*** Configuration $machine is obsolete." >&2
+ echo "*** Configuration ${target} is obsolete." >&2
echo "*** Specify --enable-obsolete to build it anyway." >&2
echo "*** Support will be REMOVED in the next major release of GCC," >&2
echo "*** unless a maintainer comes forward." >&2
@@ -278,23 +211,60 @@ case $machine in
fi;;
esac
+# Unsupported targets list. Do not put an entry in this list unless
+# it would otherwise be caught by a more permissive pattern. The list
+# should be in alphabetical order.
+case ${target} in
+ alpha*-*-linux*libc1* \
+ | i[34567]86-sequent-sysv \
+ | i[34567]86-sequent-sysv[123]* \
+ | i[34567]86-go32-* \
+ | i[34567]86-*-go32* \
+ | m68k-*-linux*aout* \
+ | m68k-*-linux*libc1* \
+ | mips64orion*-*-rtems* \
+ | powerpc-*-linux*libc1* \
+ | sparc-*-linux*aout* \
+ | sparc-*-linux*libc1* \
+ | sparc-hal-solaris2* \
+ | thumb-*-* \
+ | *-*-linux*coff* \
+ | *-*-linux*oldld* \
+ | *-*-rtemsaout* \
+ | *-*-rtemscoff* \
+ | vax-*-vms* \
+ )
+ echo "*** Configuration ${target} not supported" 1>&2
+ exit 1
+ ;;
+esac
+
# Set default cpu_type, tm_file, tm_p_file and xm_file so it can be
# updated in each machine entry. Also set default extra_headers for some
# machines.
tm_p_file=
-cpu_type=`echo $machine | sed 's/-.*$//'`
-case $machine in
+cpu_type=`echo ${target} | sed 's/-.*$//'`
+case ${target} in
alpha*-*-*)
cpu_type=alpha
+ need_64bit_hwint=yes
+ ;;
+am33_2.0-*-linux*)
+ cpu_type=mn10300
;;
strongarm*-*-*)
cpu_type=arm
;;
arm*-*-*)
cpu_type=arm
+ extra_headers="mmintrin.h"
+ ;;
+ep9312*-*-*)
+ cpu_type=arm
;;
xscale-*-*)
cpu_type=arm
+ extra_headers="mmintrin.h"
;;
i[34567]86-*-*)
cpu_type=i386
@@ -303,13 +273,18 @@ i[34567]86-*-*)
x86_64-*-*)
cpu_type=i386
extra_headers="mmintrin.h xmmintrin.h emmintrin.h pmmintrin.h"
+ need_64bit_hwint=yes
;;
ia64-*-*)
extra_headers=ia64intrin.h
+ need_64bit_hwint=yes
;;
hppa*-*-* | parisc*-*-*)
cpu_type=pa
;;
+m32r*-*-*)
+ cpu_type=m32r
+ ;;
m680[012]0-*-*)
cpu_type=m68k
extra_headers=math-68881.h
@@ -319,17 +294,30 @@ m68k-*-*)
;;
mips*-*-*)
cpu_type=mips
+ need_64bit_hwint=yes
;;
powerpc*-*-*)
cpu_type=rs6000
extra_headers="ppc-asm.h altivec.h spe.h"
+ need_64bit_hwint=yes
+ ;;
+rs6000*-*-*)
+ need_64bit_hwint=yes
+ ;;
+sparc64*-*-*)
+ cpu_type=sparc
+ need_64bit_hwint=yes
;;
sparc*-*-*)
cpu_type=sparc
;;
+s390*-*-*)
+ need_64bit_hwint=yes
+ ;;
# Note the 'l'; we need to be able to match e.g. "shle" or "shl".
sh[123456789l]*-*-*)
cpu_type=sh
+ need_64bit_hwint=yes
;;
tic4x-*-*)
cpu_type=c4x
@@ -347,168 +335,217 @@ then
extra_modes=${cpu_type}/${cpu_type}-modes.def
fi
-case $machine in
+case ${target} in
x86_64-*-*)
tm_file="i386/biarch64.h ${tm_file}"
;;
esac
# On a.out targets, we need to use collect2.
-case $machine in
+case ${target} in
*-*-*aout*)
use_collect2=yes
;;
esac
-# Common parts for GNU/Linux, GNU/Hurd, OpenBSD, NetBSD, and FreeBSD systems.
-case $machine in
+# Common parts for widely ported systems.
+case ${target} in
+*-*-darwin*)
+ tm_file="${tm_file} darwin.h"
+ tm_p_file="${tm_p_file} darwin-protos.h"
+ tmake_file="t-darwin"
+ target_gtfiles="\$(srcdir)/config/darwin.c"
+ c_target_objs="darwin-c.o"
+ cxx_target_objs="darwin-c.o"
+ extra_parts="crt2.o"
+ extra_objs="darwin.o"
+ case ${enable_threads} in
+ "" | yes | posix) thread_file='posix' ;;
+ esac
+ ;;
+*-*-freebsd[12] | *-*-freebsd[12].* | *-*-freebsd*aout*)
+ # This is the place-holder for the generic a.out configuration
+ # of FreeBSD. No actual configuration resides here since
+ # there was only ever a bare-bones ix86 configuration for
+ # a.out and it exists solely in the machine-specific section.
+ # This place-holder must exist to avoid dropping into
+ # the generic ELF configuration of FreeBSD (i.e. it must be
+ # ordered before that section).
+ ;;
+*-*-freebsd*)
+ # This is the generic ELF configuration of FreeBSD. Later
+ # machine-specific sections may refine and add to this
+ # configuration.
+ #
+ # Due to tm_file entry ordering issues that vary between cpu
+ # architectures, we only define fbsd_tm_file to allow the
+ # machine-specific section to dictate the final order of all
+ # entries of tm_file with the minor exception that components
+ # of the tm_file set here will always be of the form:
+ #
+ # freebsd<version_number>.h [freebsd-<conf_option>.h ...] freebsd-spec.h freebsd.h
+ #
+ # The machine-specific section should not tamper with this
+ # ordering but may order all other entries of tm_file as it
+ # pleases around the provided core setting.
+ gas=yes
+ gnu_ld=yes
+ extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o"
+ case ${target} in
+ *-*-freebsd3 | *-*-freebsd[3].*)
+ tm_defines="${tm_defines} FBSD_MAJOR=3" ;;
+ *-*-freebsd4 | *-*-freebsd[4].*)
+ tm_defines="${tm_defines} FBSD_MAJOR=4" ;;
+ *-*-freebsd5 | *-*-freebsd[5].*)
+ tm_defines="${tm_defines} FBSD_MAJOR=5" ;;
+ *-*-freebsd6 | *-*-freebsd[6].*)
+ tm_defines="${tm_defines} FBSD_MAJOR=6" ;;
+ *)
+ echo 'Please update *-*-freebsd* in gcc/config.gcc'
+ exit 1
+ ;;
+ esac
+ tmake_file="t-slibgcc-elf-ver t-freebsd"
+ case ${enable_threads} in
+ no)
+ fbsd_tm_file="${fbsd_tm_file} freebsd-nthr.h"
+ ;;
+ "" | yes | posix)
+ thread_file='posix'
+ tmake_file="${tmake_file} t-freebsd-thread"
+ # Before 5.0, FreeBSD can't bind shared libraries to -lc
+ # when "optionally" threaded via weak pthread_* checks.
+ case ${target} in
+ *-*-freebsd[34] | *-*-freebsd[34].*)
+ tmake_file="${tmake_file} t-slibgcc-nolc-override"
+ ;;
+ esac
+ ;;
+ *)
+ echo 'Unknown thread configuration for FreeBSD'
+ exit 1
+ ;;
+ esac
+ fbsd_tm_file="${fbsd_tm_file} freebsd-spec.h freebsd.h"
+ ;;
+*-*-kfreebsd*-gnu)
+ # Must come before *-*-gnu*
+ xm_defines=POSIX # needed for cross-compiling from FreeBSD?
+ extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
+ # GNU tools are the only tools.
+ gas=yes
+ gnu_ld=yes
+ case ${enable_threads} in
+ "" | yes | posix) thread_file='posix' ;;
+ esac
+ ;;
+*-*-linux*libc1* | *-*-linux*aout*)
+ # Avoid the generic linux case.
+ ;;
*-*-linux*)
- xm_defines=POSIX
- case $machine in
- *-*-linux*ecoff* | *-*-linux*libc1* | *-*-linux*oldld* | *-*-linux*aout*)
- ;;
- *)
- extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
- gas=yes gnu_ld=yes
- case x${enable_threads} in
- x | xyes | xposix) thread_file='posix'
- ;;
- esac
- ;;
- esac
- ;;
+ # Must come before *-*-gnu* (because of *-*-linux-gnu* systems).
+ extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
+ gas=yes
+ gnu_ld=yes
+ case ${enable_threads} in
+ "" | yes | posix) thread_file='posix' ;;
+ esac
+ ;;
*-*-gnu*)
- # On the Hurd, the setup is just about the same on
- # each different CPU. The specific machines that we
- # support are matched above and just set $cpu_type.
- xm_defines=POSIX
- tm_file="${cpu_type}/gnu.h"
- extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
- # GNU always uses ELF.
- elf=yes
- # GNU tools are the only tools.
- gnu_ld=yes
- gas=yes
- # These details are the same as for Linux.
- # But here we need a little extra magic.
- tmake_file="t-slibgcc-elf-ver t-linux t-gnu"
- case $machine in
- alpha*)
- tm_file="${cpu_type}/${cpu_type}.h alpha/elf.h alpha/linux.h alpha/linux-elf.h gnu.h ${tm_file}"
- ;;
- i[34567]86-*-*)
- tm_file="${cpu_type}/${cpu_type}.h i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h linux.h i386/linux.h gnu.h ${tm_file}"
- ;;
- esac
- ;;
-*-*-openbsd*)
- tm_file=${cpu_type}/openbsd.h
- tmake_file="t-libc-ok t-openbsd t-libgcc-pic"
- xm_defines=POSIX
- if test x$enable_threads = xyes; then
- thread_file='posix'
- tmake_file="${tmake_file} t-openbsd-thread"
- fi
- ;;
+ # On the Hurd, the setup is just about the same on
+ # each different CPU. The specific machines that we
+ # support are matched above and just set $cpu_type.
+ tm_file="${cpu_type}/gnu.h"
+ extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
+ # GNU tools are the only tools.
+ gas=yes
+ gnu_ld=yes
+ # These details are the same as for Linux.
+ # But here we need a little extra magic.
+ tmake_file="t-slibgcc-elf-ver t-linux t-gnu"
+ case ${target} in
+ alpha*)
+ tm_file="${cpu_type}/${cpu_type}.h alpha/elf.h alpha/linux.h alpha/linux-elf.h gnu.h ${tm_file}"
+ ;;
+ i[34567]86-*-*)
+ tm_file="${cpu_type}/${cpu_type}.h i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h linux.h i386/linux.h gnu.h ${tm_file}"
+ ;;
+ esac
+ ;;
*-*-netbsd*)
- tmake_file="t-slibgcc-elf-ver t-libc-ok t-netbsd"
- xm_defines=POSIX
- gas=yes
- gnu_ld=yes
+ tmake_file="t-slibgcc-elf-ver t-libc-ok t-netbsd t-libgcc-pic"
+ gas=yes
+ gnu_ld=yes
- # NetBSD 2.0 and later get POSIX threads enabled by default.
- # Allow them to be explicitly enabled on any other version.
- case x${enable_threads} in
- x)
- case $machine in
- *-*-netbsd[2-9]* | *-*-netbsdelf[2-9]*)
- thread_file='posix'
- tm_defines="${tm_defines} NETBSD_ENABLE_PTHREADS"
- ;;
- esac
- ;;
- xyes | xposix)
- thread_file='posix'
- tm_defines="${tm_defines} NETBSD_ENABLE_PTHREADS"
- ;;
- esac
+ # NetBSD 2.0 and later get POSIX threads enabled by default.
+ # Allow them to be explicitly enabled on any other version.
+ case ${enable_threads} in
+ "")
+ case ${target} in
+ *-*-netbsd[2-9]* | *-*-netbsdelf[2-9]*)
+ thread_file='posix'
+ tm_defines="${tm_defines} NETBSD_ENABLE_PTHREADS"
+ ;;
+ esac
+ ;;
+ yes | posix)
+ thread_file='posix'
+ tm_defines="${tm_defines} NETBSD_ENABLE_PTHREADS"
+ ;;
+ esac
- # NetBSD 1.7 and later are set up to use GCC's crtstuff for
- # ELF configurations. We will clear extra_parts in the
- # a.out configurations.
- case $machine in
- *-*-netbsd*1.[7-9]* | *-*-netbsd[2-9]* | *-*-netbsdelf[2-9]*)
- extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
- ;;
- esac
- ;;
-*-*-freebsd[12] | *-*-freebsd[12].* | *-*-freebsd*aout*)
- # This is the place-holder for the generic a.out configuration
- # of FreeBSD. No actual configuration resides here since
- # there was only ever a bare-bones ix86 configuration for
- # a.out and it exists solely in the machine-specific section.
- # This place-holder must exist to avoid dropping into
- # the generic ELF configuration of FreeBSD (i.e. it must be
- # ordered before that section).
- ;;
-*-*-freebsd*)
- # This is the generic ELF configuration of FreeBSD. Later
- # machine-specific sections may refine and add to this
- # configuration.
- #
- # Due to tm_file entry ordering issues that vary between cpu
- # architectures, we only define fbsd_tm_file to allow the
- # machine-specific section to dictate the final order of all
- # entries of tm_file with the minor exception that components
- # of the tm_file set here will always be of the form:
- #
- # freebsd<version_number>.h [freebsd-<conf_option>.h ...] freebsd-spec.h freebsd.h
- #
- # The machine-specific section should not tamper with this
- # ordering but may order all other entries of tm_file as it
- # pleases around the provided core setting.
- gas=yes
- gnu_ld=yes
- extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o"
- case $machine in
- *-*-freebsd3 | *-*-freebsd[3].*) fbsd_tm_file="freebsd3.h";;
- *-*-freebsd4 | *-*-freebsd[4].*) fbsd_tm_file="freebsd4.h";;
- *-*-freebsd5 | *-*-freebsd[5].*) fbsd_tm_file="freebsd5.h";;
- *-*-freebsd6 | *-*-freebsd[6].*) fbsd_tm_file="freebsd6.h";;
- *) echo 'Please update *-*-freebsd* in gcc/config.gcc'; exit 1;;
- esac
- tmake_file="t-slibgcc-elf-ver t-freebsd"
- xmake_file=none
- xm_defines=POSIX
- case x${enable_threads} in
- xno) fbsd_tm_file="${fbsd_tm_file} freebsd-nthr.h";;
- x | xyes | xpthreads | xposix)
- thread_file='posix'
- tmake_file="${tmake_file} t-freebsd-thread"
- # Before 5.0, FreeBSD can't bind shared libraries to -lc
- # when "optionally" threaded via weak pthread_* checks.
- case $machine in
- *-*-freebsd[34] | *-*-freebsd[34].*)
- tmake_file="${tmake_file} t-slibgcc-nolc-override";;
- esac
- ;;
- *) echo 'Unknown thread configuration for FreeBSD'; exit 1;;
- esac
- fbsd_tm_file="${fbsd_tm_file} freebsd-spec.h freebsd.h"
- ;;
+ # NetBSD 1.7 and later are set up to use GCC's crtstuff for
+ # ELF configurations. We will clear extra_parts in the
+ # a.out configurations.
+ case ${target} in
+ *-*-netbsd*1.[7-9]* | *-*-netbsd[2-9]* | *-*-netbsdelf[2-9]*)
+ extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
+ ;;
+ esac
+
+ # NetBSD 2.0 and later provide __cxa_atexit(), which we use by
+ # default (unless overridden by --disable-__cxa_atexit).
+ case ${target} in
+ *-*-netbsd[2-9]* | *-*-netbsdelf[2-9]*)
+ default_use_cxa_atexit=yes
+ ;;
+ esac
+ ;;
+*-*-openbsd*)
+ tmake_file="t-libc-ok t-openbsd t-libgcc-pic"
+ case ${enable_threads} in
+ yes)
+ thread_file='posix'
+ tmake_file="${tmake_file} t-openbsd-thread"
+ ;;
+ esac
+ ;;
+*-*-rtems*)
+ case ${enable_threads} in
+ yes) thread_file='rtems' ;;
+ esac
+ ;;
+*-*-vxworks*)
+ tmake_file=t-vxworks
+ tm_file="${tm_file} elfos.h svr4.h vxworks.h"
+ case ${enable_threads} in
+ no) ;;
+ "" | yes | vxworks) thread_file='vxworks' ;;
+ *) echo 'Unknown thread configuration for VxWorks'; exit 1 ;;
+ esac
+ use_collect2=yes
+ xm_defines=POSIX
+ ;;
esac
-case $machine in
+case ${target} in
# Support site-specific machine types.
*local*)
- rest=`echo $machine | sed -e "s/$cpu_type-//"`
+ rest=`echo ${target} | sed -e "s/$cpu_type-//"`
tm_file=${cpu_type}/$rest.h
if test -f $srcdir/config/${cpu_type}/xm-$rest.h
then xm_file=${cpu_type}/xm-$rest.h
fi
- if test -f $srcdir/config/${cpu_type}/x-$rest
- then xmake_file=${cpu_type}/x-$rest
- fi
if test -f $srcdir/config/${cpu_type}/t-$rest
then tmake_file=${cpu_type}/t-$rest
fi
@@ -520,41 +557,7 @@ alpha*-*-unicosmk*)
# Don't include t-ieee for now because we don't support that yet
# tmake_file="alpha/t-ieee"
tmake_file="alpha/t-unicosmk"
- ;;
-alpha-*-interix)
- tm_file="${tm_file} alpha/alpha32.h interix.h alpha/alpha-interix.h"
-
- # GAS + IEEE_CONFORMANT+IEEE (no inexact);
- #target_cpu_default="MASK_GAS|MASK_IEEE_CONFORMANT|MASK_IEEE"
-
- # GAS + IEEE_CONFORMANT
- target_cpu_default="MASK_GAS|MASK_IEEE_CONFORMANT"
-
- xm_defines=POSIX
- xm_file="alpha/xm-alpha-interix.h"
- tmake_file="alpha/t-alpha t-interix alpha/t-interix alpha/t-ieee"
- if test x$enable_threads = xyes ; then
- thread_file='posix'
- fi
- if test x$stabs = xyes ; then
- tm_file="${tm_file} dbxcoff.h"
- fi
- #prefix='$$INTERIX_ROOT'/usr/contrib
- #local_prefix='$$INTERIX_ROOT'/usr/contrib
- ;;
-alpha*-*-linux*ecoff*)
- echo "Configuration $machine no longer supported" 1>&2
- exit 1
- ;;
-alpha*-*-linux*libc1*)
- tm_file="${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h"
- target_cpu_default="MASK_GAS"
- tmake_file="t-slibgcc-elf-ver t-linux t-linux-gnulibc1 alpha/t-alpha alpha/t-crtfm alpha/t-ieee"
- extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
- gas=yes gnu_ld=yes
- if test x$enable_threads = xyes; then
- thread_file='posix'
- fi
+ use_fixproto=yes
;;
alpha*-*-linux*)
tm_file="${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h"
@@ -576,16 +579,14 @@ alpha*-*-netbsd*)
target_cpu_default="MASK_GAS"
tmake_file="${tmake_file} alpha/t-alpha alpha/t-ieee"
;;
-
alpha*-*-openbsd*)
- tm_file="${cpu_type}/${cpu_type}.h ${tm_file}"
+ tm_defines="OBSD_NO_DYNAMIC_LIBRARIES OBSD_HAS_DECLARE_FUNCTION_NAME OBSD_HAS_DECLARE_FUNCTION_SIZE OBSD_HAS_DECLARE_OBJECT"
+ tm_file="alpha/alpha.h openbsd.h alpha/openbsd.h"
# default x-alpha is only appropriate for dec-osf.
target_cpu_default="MASK_GAS"
tmake_file="alpha/t-alpha alpha/t-ieee"
;;
-
alpha*-dec-osf[45]*)
- xm_defines=POSIX
if test x$stabs = xyes
then
tm_file="${tm_file} dbx.h"
@@ -598,13 +599,10 @@ alpha*-dec-osf[45]*)
tmake_file="alpha/t-alpha alpha/t-ieee alpha/t-crtfm alpha/t-osf4"
tm_file="${tm_file} alpha/osf.h"
extra_headers=va_list.h
- case $machine in
+ case ${target} in
*-*-osf4*)
- # Some versions of OSF4 (specifically X4.0-9 296.7) have
- # a broken tar, so we use cpio instead.
- install_headers_dir=install-headers-cpio
# Set target_cpu_default except on 4.0a.
- case $machine in
+ case ${target} in
*-*-osf4.0a) ;;
*) target_cpu_default=MASK_SUPPORT_ARCH
esac
@@ -614,75 +612,44 @@ alpha*-dec-osf[45]*)
target_cpu_default=MASK_SUPPORT_ARCH
;;
esac
- ;;
-alpha*-*-vxworks*)
- xm_defines=POSIX
- tm_file="${tm_file} dbx.h alpha/vxworks.h"
- tmake_file="alpha/t-alpha alpha/t-ieee"
- if [ x$gas != xyes ]
- then
- extra_passes="mips-tfile mips-tdump"
- fi
- use_collect2=yes
- thread_file='vxworks'
+ case ${enable_threads} in
+ "" | yes | posix)
+ thread_file='posix'
+ tmake_file="${tmake_file} alpha/t-osf-pthread"
+ ;;
+ esac
;;
alpha64-dec-*vms*)
- xm_defines=POSIX
tm_file="${tm_file} alpha/vms.h alpha/vms64.h"
- xm_file="alpha/xm-vms.h alpha/xm-vms64.h"
+ xm_file="alpha/xm-vms.h"
tmake_file="alpha/t-alpha alpha/t-vms alpha/t-vms64 alpha/t-ieee"
- xmake_file=alpha/x-vms
- exeext=.exe
- # This removes the cpu type and manufacturer components and
- # replaces "." with "_" in the operating system version.
- case $host in *-*-*vms*)
- target_alias=`echo $host \
- | sed 's/.*-.*-\(.*\)$/\1/' | sed 's/\./_/g'`
- ;;
- esac
- install_headers_dir=install-headers-cp
prefix=/gnu
local_prefix=/gnu
;;
alpha*-dec-*vms*)
- xm_defines=POSIX
tm_file="${tm_file} alpha/vms.h"
xm_file=alpha/xm-vms.h
tmake_file="alpha/t-alpha alpha/t-vms alpha/t-ieee"
- xmake_file=alpha/x-vms
- exeext=.exe
- # This removes the cpu type and manufacturer components and
- # replaces "." with "_" in the operating system version.
- case $host in *-*-*vms*)
- target_alias=`echo $host \
- | sed 's/.*-.*-\(.*\)$/\1/' | sed 's/\./_/g'`
- ;;
- esac
- install_headers_dir=install-headers-cp
prefix=/gnu
local_prefix=/gnu
;;
arc-*-elf*)
tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
extra_parts="crtinit.o crtfini.o"
+ use_fixproto=yes
;;
arm-*-coff* | armel-*-coff*)
- tm_file="arm/semi.h arm/aout.h arm/arm.h arm/coff.h"
+ tm_file="arm/semi.h arm/aout.h arm/arm.h arm/coff.h dbxcoff.h"
tmake_file=arm/t-arm-coff
;;
-arm-*-vxworks*)
- tm_file="arm/semi.h arm/aout.h arm/coff.h arm/vxarm.h arm/arm.h"
- tmake_file=arm/t-arm-coff
- thread_file='vxworks'
- ;;
-arm-semi-aout | armel-semi-aout)
- tm_file="arm/semi.h arm/aout.h arm/arm.h"
- tmake_file=arm/t-semi
- ;;
arm-semi-aof | armel-semi-aof)
tm_file="arm/semiaof.h arm/aof.h arm/arm.h"
tmake_file=arm/t-semi
;;
+arm-wrs-vxworks)
+ tm_file="dbxelf.h elfos.h svr4.h vxworks.h arm/elf.h arm/aout.h arm/arm.h arm/vxworks.h"
+ tmake_file="${tmake_file} arm/t-vxworks"
+ ;;
arm*-*-freebsd*|strongarm*-*-freebsd*)
tm_file="dbxelf.h elfos.h ${fbsd_tm_file} arm/elf.h arm/aout.h arm/freebsd.h arm/arm.h"
tmake_file="${tmake_file} arm/t-strongarm-elf"
@@ -698,62 +665,48 @@ arm*-*-netbsd*)
use_collect2=yes
;;
arm*-*-linux*) # ARM GNU/Linux with ELF
- tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/linux-gas.h arm/linux-elf.h"
+ tm_file="dbxelf.h elfos.h linux.h arm/elf.h arm/linux-gas.h arm/linux-elf.h arm/aout.h arm/arm.h"
tmake_file="t-slibgcc-elf-ver t-linux arm/t-linux"
extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
gnu_ld=yes
- case x${enable_threads} in
- x | xyes | xpthreads | xposix)
- thread_file='posix'
- ;;
- esac
;;
arm*-*-uclinux*) # ARM ucLinux
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/linux-gas.h arm/linux-elf.h arm/uclinux-elf.h"
tmake_file=arm/t-arm-elf
;;
-arm*-*-aout)
- tm_file="arm/aout.h arm/arm.h"
- tmake_file=arm/t-arm-aout
- ;;
arm*-*-ecos-elf)
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/ecos-elf.h"
tmake_file=arm/t-arm-elf
;;
arm*-*-rtems*)
- xm_defines=POSIX
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h arm/rtems-elf.h rtems.h"
tmake_file="arm/t-arm-elf t-rtems"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
;;
-arm*-*-elf)
+arm*-*-elf | ep9312-*-elf)
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
tmake_file=arm/t-arm-elf
;;
-arm*-*-conix*)
- tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/conix-elf.h arm/aout.h arm/arm.h"
- tmake_file=arm/t-arm-elf
- ;;
-arm*-*-oabi)
- tm_file="arm/unknown-elf-oabi.h dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
- tmake_file=arm/t-arm-elf
+arm*-wince-pe*)
+ tm_file="arm/semi.h arm/aout.h arm/arm.h arm/coff.h dbxcoff.h arm/pe.h arm/wince-pe.h"
+ tmake_file=arm/t-wince-pe
+ extra_objs="pe.o"
;;
arm-*-pe*)
- tm_file="arm/semi.h arm/aout.h arm/arm.h arm/coff.h arm/pe.h"
+ tm_file="arm/semi.h arm/aout.h arm/arm.h arm/coff.h dbxcoff.h arm/pe.h"
tmake_file=arm/t-pe
extra_objs="pe.o"
;;
+arm*-*-kaos*)
+ tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h kaos.h arm/kaos-arm.h"
+ tmake_file=arm/t-arm-elf
+ ;;
avr-*-*)
+ tm_file="avr/avr.h dbxelf.h"
+ use_fixproto=yes
;;
c4x-*-rtems* | tic4x-*-rtems*)
- xm_defines=POSIX
tmake_file="c4x/t-c4x t-rtems"
tm_file="c4x/c4x.h c4x/rtems.h rtems.h"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
c_target_objs="c4x-c.o"
cxx_target_objs="c4x-c.o"
;;
@@ -780,140 +733,81 @@ d30v-*)
tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
;;
dsp16xx-*)
+ use_fixproto=yes
;;
fr30-*-elf)
tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
tmake_file=fr30/t-fr30
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
+ use_fixproto=yes
;;
frv-*-elf)
tm_file="dbxelf.h elfos.h svr4.h ${tm_file} frv/frv-abi.h"
tmake_file=frv/t-frv
+ use_fixproto=yes
;;
h8300-*-rtems*)
- xm_defines=POSIX
- tmake_file="h8300/t-h8300 t-rtems"
- tm_file="h8300/h8300.h h8300/rtems.h rtems.h"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
+ tmake_file="h8300/t-h8300 t-rtems h8300/t-rtems"
+ tm_file="h8300/h8300.h dbxcoff.h h8300/coff.h h8300/rtems.h rtems.h"
;;
h8300-*-elf*)
tmake_file="h8300/t-h8300 h8300/t-elf"
- tm_file="h8300/h8300.h h8300/elf.h"
+ tm_file="h8300/h8300.h dbxelf.h elfos.h h8300/elf.h"
+ use_fixproto=yes
;;
h8300-*-*)
+ tm_file="h8300/h8300.h dbxcoff.h h8300/coff.h"
+ use_fixproto=yes
;;
hppa*64*-*-linux* | parisc*64*-*-linux*)
target_cpu_default="(MASK_PA_11 | MASK_PA_20)"
tm_file="pa/pa64-start.h ${tm_file} dbxelf.h elfos.h svr4.h linux.h \
pa/pa-linux.h pa/pa64-regs.h pa/pa-64.h pa/pa64-linux.h"
- tmake_file=pa/t-linux64
+ tmake_file="t-slibgcc-elf-ver t-linux pa/t-linux64"
gas=yes gnu_ld=yes
+ need_64bit_hwint=yes
;;
hppa*-*-linux* | parisc*-*-linux*)
target_cpu_default="MASK_PA_11 | MASK_NO_SPACE_REGS"
tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h pa/pa-linux.h \
pa/pa32-regs.h pa/pa32-linux.h"
tmake_file="t-slibgcc-elf-ver t-linux pa/t-linux"
+ # if not configured with --enable-sjlj-exceptions, bump the
+ # libgcc version number
+ if test x$sjlj != x1; then
+ tmake_file="$tmake_file pa/t-slibgcc-elf-ver"
+ fi
;;
-hppa*-*-openbsd*)
- target_cpu_default="MASK_PA_11"
- tmake_file=pa/t-bsd
- ;;
+# port not yet contributed.
+#hppa*-*-openbsd*)
+# target_cpu_default="MASK_PA_11"
+# ;;
hppa1.1-*-pro*)
target_cpu_default="(MASK_JUMP_IN_DELAY | MASK_PORTABLE_RUNTIME | MASK_GAS | MASK_NO_SPACE_REGS | MASK_SOFT_FLOAT)"
tm_file="${tm_file} pa/pa32-regs.h dbxelf.h elfos.h pa/elf.h pa/pa-pro-end.h libgloss.h"
- tmake_file="pa/t-bsd pa/t-pro"
- xmake_file="pa/x-ada"
+ tmake_file="pa/t-pro"
;;
hppa1.1-*-osf*)
target_cpu_default="MASK_PA_11"
- tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-osf.h"
- tmake_file="pa/t-bsd pa/t-pa"
- xmake_file="pa/x-ada"
+ tm_file="${tm_file} pa/pa32-regs.h dbxelf.h pa/som.h pa/pa-osf.h"
+ tmake_file="pa/t-pa"
use_collect2=yes
;;
hppa1.1-*-rtems*)
- xm_defines=POSIX
target_cpu_default="(MASK_JUMP_IN_DELAY | MASK_PORTABLE_RUNTIME | MASK_GAS | MASK_NO_SPACE_REGS | MASK_SOFT_FLOAT)"
tm_file="${tm_file} pa/pa32-regs.h dbxelf.h elfos.h pa/elf.h pa/pa-pro-end.h libgloss.h pa/rtems.h rtems.h"
- tmake_file="pa/t-bsd pa/t-pro t-rtems"
- xmake_file="pa/x-ada"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
- ;;
-hppa1.0-*-osf*)
- tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-osf.h"
- tmake_file="pa/t-bsd pa/t-pa"
- xmake_file="pa/x-ada"
- use_collect2=yes
+ tmake_file="pa/t-pro t-rtems"
;;
hppa1.1-*-bsd*)
- tm_file="${tm_file} pa/pa32-regs.h pa/som.h"
+ tm_file="${tm_file} pa/pa32-regs.h dbxelf.h pa/som.h"
target_cpu_default="MASK_PA_11"
- tmake_file="pa/t-bsd pa/t-pa"
- xmake_file="pa/x-ada"
- use_collect2=yes
- ;;
-hppa1.0-*-bsd*)
- tm_file="${tm_file} pa/pa32-regs.h pa/som.h"
- tmake_file="pa/t-bsd pa/t-pa"
- xmake_file="pa/x-ada"
- use_collect2=yes
- ;;
-hppa1.0-*-hpux7*)
- tm_file="pa/pa-oldas.h ${tm_file} pa/pa32-regs.h pa/som.h pa/pa-hpux7.h"
- xm_defines=POSIX
- tmake_file=pa/t-pa-hpux
- install_headers_dir=install-headers-cpio
- use_collect2=yes
- ;;
-hppa1.0-*-hpux8.0[0-2]*)
- tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-hpux.h"
- xm_defines=POSIX
- tmake_file=pa/t-pa-hpux
- if test x$gas != xyes
- then
- tm_file="pa/pa-oldas.h ${tm_file}"
- fi
- install_headers_dir=install-headers-cpio
- use_collect2=yes
- ;;
-hppa1.1-*-hpux8.0[0-2]*)
- target_cpu_default="MASK_PA_11"
- tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-hpux.h"
- xm_defines=POSIX
- tmake_file=pa/t-pa-hpux
- if test x$gas != xyes
- then
- tm_file="pa/pa-oldas.h ${tm_file}"
- fi
- install_headers_dir=install-headers-cpio
- use_collect2=yes
- ;;
-hppa1.1-*-hpux8*)
- target_cpu_default="MASK_PA_11"
- tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-hpux.h"
- xm_defines=POSIX
- tmake_file=pa/t-pa-hpux
- install_headers_dir=install-headers-cpio
- use_collect2=yes
- ;;
-hppa1.0-*-hpux8*)
- tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-hpux.h"
- xm_defines=POSIX
- tmake_file=pa/t-pa-hpux
- install_headers_dir=install-headers-cpio
+ tmake_file="pa/t-pa"
use_collect2=yes
;;
hppa1.1-*-hpux10* | hppa2*-*-hpux10*)
target_cpu_default="MASK_PA_11"
- tm_file="${tm_file} pa/pa32-regs.h pa/long_double.h pa/som.h pa/pa-hpux.h pa/pa-hpux10.h"
- xm_defines=POSIX
+ tm_file="${tm_file} pa/pa32-regs.h dbxelf.h pa/som.h pa/pa-hpux.h pa/pa-hpux10.h"
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
- xmake_file="pa/x-ada"
if test x$enable_threads = x; then
enable_threads=$have_pthread_h
fi
@@ -922,14 +816,12 @@ hppa1.1-*-hpux10* | hppa2*-*-hpux10*)
tmake_file="${tmake_file} pa/t-dce-thr"
;;
esac
- install_headers_dir=install-headers-cpio
use_collect2=yes
+ use_fixproto=yes
;;
hppa1.0-*-hpux10*)
- tm_file="${tm_file} pa/pa32-regs.h pa/long_double.h pa/som.h pa/pa-hpux.h pa/pa-hpux10.h"
- xm_defines=POSIX
+ tm_file="${tm_file} pa/pa32-regs.h dbxelf.h pa/som.h pa/pa-hpux.h pa/pa-hpux10.h"
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
- xmake_file="pa/x-ada"
if test x$enable_threads = x; then
enable_threads=$have_pthread_h
fi
@@ -938,23 +830,22 @@ hppa1.0-*-hpux10*)
tmake_file="${tmake_file} pa/t-dce-thr"
;;
esac
- install_headers_dir=install-headers-cpio
use_collect2=yes
+ use_fixproto=yes
;;
hppa*64*-*-hpux11*)
- xm_defines=POSIX
if test x$gas = xyes
then
tm_file="pa/pa64-start.h ${tm_file} dbxelf.h elfos.h \
- pa/pa64-regs.h pa/long_double.h pa/pa-hpux.h \
+ pa/pa64-regs.h pa/pa-hpux.h \
pa/pa-hpux11.h pa/pa-64.h pa/pa64-hpux.h"
else
tm_file="pa/pa64-start.h ${tm_file} dbxelf.h pa/elf.h \
- pa/pa64-regs.h pa/long_double.h pa/pa-hpux.h \
+ pa/pa64-regs.h pa/pa-hpux.h \
pa/pa-hpux11.h pa/pa-64.h pa/pa64-hpux.h"
fi
+ need_64bit_hwint=yes
tmake_file="pa/t-pa64 pa/t-pa-hpux"
- xmake_file="pa/x-ada"
target_cpu_default="(MASK_PA_11|MASK_PA_20|MASK_GAS)"
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
if test x$gnu_ld = xyes
@@ -966,156 +857,83 @@ hppa*64*-*-hpux11*)
thread_file=posix
;;
esac
- install_headers_dir=install-headers-cpio
;;
hppa1.1-*-hpux11* | hppa2*-*-hpux11*)
target_cpu_default="MASK_PA_11"
- tm_file="${tm_file} pa/pa32-regs.h pa/long_double.h pa/som.h pa/pa-hpux.h pa/pa-hpux11.h"
- xm_defines=POSIX
+ tm_file="${tm_file} pa/pa32-regs.h dbxelf.h pa/som.h pa/pa-hpux.h pa/pa-hpux11.h"
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
- xmake_file="pa/x-ada"
case x${enable_threads} in
xyes | xposix )
thread_file=posix
;;
esac
- install_headers_dir=install-headers-cpio
use_collect2=yes
;;
hppa1.0-*-hpux11*)
- tm_file="${tm_file} pa/pa32-regs.h pa/long_double.h pa/som.h pa/pa-hpux.h pa/pa-hpux11.h"
- xm_defines=POSIX
+ tm_file="${tm_file} pa/pa32-regs.h dbxelf.h pa/som.h pa/pa-hpux.h pa/pa-hpux11.h"
tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
- xmake_file="pa/x-ada"
case x${enable_threads} in
xyes | xposix )
thread_file=posix
;;
esac
- install_headers_dir=install-headers-cpio
- use_collect2=yes
- ;;
-hppa1.1-*-hpux* | hppa2*-*-hpux*)
- target_cpu_default="MASK_PA_11"
- tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-hpux.h pa/pa-hpux9.h"
- xm_defines=POSIX
- tmake_file=pa/t-pa-hpux
- install_headers_dir=install-headers-cpio
- use_collect2=yes
- ;;
-hppa1.0-*-hpux*)
- tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-hpux.h pa/pa-hpux9.h"
- xm_defines=POSIX
- tmake_file=pa/t-pa-hpux
- install_headers_dir=install-headers-cpio
- use_collect2=yes
- ;;
-hppa1.1-*-hiux* | hppa2*-*-hiux*)
- target_cpu_default="MASK_PA_11"
- tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-hpux.h pa/pa-hiux.h"
- xm_defines=POSIX
- tmake_file=pa/t-pa-hpux
- install_headers_dir=install-headers-cpio
- use_collect2=yes
- ;;
-hppa1.0-*-hiux*)
- tm_file="${tm_file} pa/pa32-regs.h pa/som.h pa/pa-hpux.h pa/pa-hiux.h"
- xm_defines=POSIX
- tmake_file=pa/t-pa-hpux
- install_headers_dir=install-headers-cpio
- use_collect2=yes
- ;;
-hppa*-*-lites*)
- tm_file="${tm_file} pa/pa32-regs.h dbxelf.h elfos.h pa/elf.h"
- target_cpu_default="MASK_PA_11"
- tmake_file="pa/t-bsd pa/t-pa"
- xmake_file="pa/x-ada"
- use_collect2=yes
- ;;
-hppa*-*-mpeix*)
- tm_file="${tm_file} pa/pa32-regs.h pa/long_double.h pa/som.h pa/pa-mpeix.h"
- tmake_file=pa/t-mpeix
- echo "You must use gas. Assuming it is already installed."
- gas=yes
- install_headers_dir=install-headers-tar
use_collect2=yes
;;
i370-*-opened*) # IBM 360/370/390 Architecture
- xm_defines='POSIX FATAL_EXIT_CODE=12'
- tm_file=i370/oe.h
- tmake_file="i370/t-oe i370/t-i370"
+ xm_defines='FATAL_EXIT_CODE=12'
+ tm_file="i370/oe.h i370/i370.h"
+ tmake_file="i370/t-i370"
c_target_objs="i370-c.o"
cxx_target_objs="i370-c.o"
+ # Don't bother fixing up header files; they're weird.
;;
i370-*-mvs*)
- xm_defines='POSIX FATAL_EXIT_CODE=12'
- tm_file=i370/mvs.h
+ xm_defines='FATAL_EXIT_CODE=12'
+ tm_file="i370/mvs.h i370/i370.h"
tmake_file="i370/t-i370"
c_target_objs="i370-c.o"
cxx_target_objs="i370-c.o"
+ use_fixproto=yes
;;
i370-*-linux*)
- tm_file="dbxelf.h elfos.h svr4.h linux.h i370/linux.h ${tm_file}"
+ tm_file="dbxelf.h elfos.h svr4.h linux.h i370/linux.h i370/i370.h"
tmake_file="t-slibgcc-elf-ver t-linux"
# broken_install=yes
- elf=yes
;;
i[34567]86-*-darwin*)
- tm_file="${tm_file} darwin.h i386/darwin.h"
- tm_p_file="${tm_p_file} darwin-protos.h"
- tmake_file="t-darwin"
- extra_objs="darwin.o"
- target_gtfiles="\$(srcdir)/config/darwin.c"
- c_target_objs="darwin-c.o"
- cxx_target_objs="darwin-c.o"
- extra_parts="crt2.o"
- # Darwin linker does collect2 functionality
- use_collect2=no
+ tm_file="${tm_file} i386/darwin.h"
;;
i[34567]86-*-elf*)
- xm_defines=POSIX
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/i386elf.h"
tmake_file="i386/t-i386elf t-svr4"
+ use_fixproto=yes
;;
i[34567]86-ncr-sysv4*) # NCR 3000 - ix86 running system V.4
- xm_defines="POSIX SMALL_ARG_MAX"
- if test x$stabs = xyes -a x$gas = xyes
- then
- tm_file=i386/sysv4gdb.h
- else
- tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h i386/sysv4-cpp.h"
- fi
+ xm_defines="SMALL_ARG_MAX"
+ tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h i386/sysv4-cpp.h"
extra_parts="crtbegin.o crtend.o"
tmake_file=i386/t-crtpic
+ use_fixproto=yes
;;
i[34567]86-*-netware) # Intel 80386's running netware
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h netware.h i386/netware.h"
- tmake_file=i386/t-netware
;;
i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4*)
if test x$gas = xyes
then
tm_file="${tm_file} usegas.h"
fi
- xm_defines="POSIX SMALL_ARG_MAX"
+ xm_defines="SMALL_ARG_MAX"
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h ptx4.h i386/ptx4-i.h"
tmake_file=t-svr4
extra_parts="crtbegin.o crtend.o"
- install_headers_dir=install-headers-cpio
- ;;
-i[34567]86-sequent-sysv*) # would otherwise be caught by i?86-*-sysv*
- echo "*** Configuration $machine not supported" 1>&2
- exit 1
- ;;
-i[34567]86-wrs-vxworks*)
- tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h i386/vxi386.h"
- thread_file='vxworks'
+ use_fixproto=yes
;;
i[34567]86-*-aout*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h i386/i386-aout.h"
+ use_fixproto=yes
;;
i[34567]86-*-beoself* | i[34567]86-*-beos*)
- xm_defines=POSIX
tmake_file='i386/t-beos i386/t-crtpic'
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/beos-elf.h"
extra_parts='crtbegin.o crtend.o'
@@ -1143,7 +961,7 @@ x86_64-*-netbsd*)
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h netbsd.h netbsd-elf.h i386/x86-64.h i386/netbsd64.h"
;;
i[34567]86-*-openbsd*)
- tm_file="${cpu_type}/${cpu_type}.h i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h openbsd-oldgas.h openbsd.h ${tm_file}"
+ tm_file="i386/i386.h i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h openbsd-oldgas.h openbsd.h i386/openbsd.h"
# needed to unconfuse gdb
tmake_file="t-libc-ok t-openbsd i386/t-openbsd"
# we need collect2 until our bug is fixed...
@@ -1151,14 +969,11 @@ i[34567]86-*-openbsd*)
;;
i[34567]86-*-coff*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/i386-coff.h"
- ;;
-i[34567]86-*-linux*oldld*) # would otherwise be caught by i?86-*-linux*
- echo "*** Configuration $machine not supported" 1>&2
- exit 1
+ use_fixproto=yes
;;
i[34567]86-*-linux*aout*) # Intel 80386's running GNU/Linux
# with a.out format
- tmake_file="t-linux-aout i386/t-crtstuff"
+ tmake_file="i386/t-crtstuff"
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h linux-aout.h i386/linux-aout.h"
gnu_ld=yes
;;
@@ -1184,60 +999,55 @@ x86_64-*-linux*)
i386/x86-64.h i386/linux64.h"
tmake_file="t-slibgcc-elf-ver t-linux i386/t-linux64"
;;
-i[34567]86-*-gnu*)
+i[34567]86-*-kfreebsd*-gnu) # must be before i[34567]86-*-gnu*
+ tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h linux.h i386/linux.h kfreebsdgnu.h i386/kfreebsdgnu.h"
+ tmake_file="t-slibgcc-elf-ver t-kfreebsd-gnu i386/t-crtstuff"
+ float_format=i386
+ use_fixproto=no
;;
-i[34567]86-go32-msdos | i[34567]86-*-go32*)
- echo "GO32/DJGPP V1.X is no longer supported. Use *-pc-msdosdjgpp for DJGPP V2.X instead."
- exit 1
+i[34567]86-*-gnu*)
;;
i[34567]86-pc-msdosdjgpp*)
xm_file=i386/xm-djgpp.h
- tm_file="dbxcoff.h ${tm_file} i386/djgpp.h"
+ tm_file="dbxcoff.h ${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/djgpp.h"
tmake_file=i386/t-djgpp
gnu_ld=yes
gas=yes
- exeext=.exe
- case $host in *pc-msdosdjgpp*)
- target_alias=djgpp
- ;;
- esac
;;
i[34567]86-moss-msdos* | i[34567]86-*-moss*)
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h linux.h i386/linux.h i386/moss.h"
tmake_file=t-libc-ok
gnu_ld=yes
gas=yes
+ use_fixproto=yes
;;
i[34567]86-*-lynxos*)
if test x$gas = xyes
then
- tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h lynx.h i386/lynx.h"
+ tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h svr3.h lynx.h i386/lynx.h"
else
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h lynx-ng.h i386/lynx-ng.h"
fi
+ use_fixproto=yes
;;
i[34567]86-*-mach*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/gstabs.h i386/mach.h"
# tmake_file=t-libc-ok
use_collect2=yes
+ use_fixproto=yes
;;
-i[34567]86-go32-rtems* | i[34567]86-*-rtemscoff*)
- # would otherwise be caught by i?86-*-rtems*
- echo "*** Configuration $machine not supported" 1>&2
- exit 1
+i[34567]86-*-nto-qnx*)
+ tm_file="${tm_file} i386/att.h dbxelf.h tm-dwarf2.h elfos.h svr4.h i386/unix.h i386/nto.h"
+ tmake_file=i386/t-nto
+ gnu_ld=yes
+ gas=yes
;;
i[34567]86-*-rtems*)
- xm_defines=POSIX
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/i386elf.h i386/rtemself.h rtems.h"
extra_parts="crtbegin.o crtend.o crti.o crtn.o"
tmake_file="i386/t-rtems-i386 i386/t-crtstuff t-rtems"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
;;
i[34567]86-*-sco3.2v5*) # 80386 running SCO Open Server 5
- xm_defines=POSIX
- install_headers_dir=install-headers-cpio
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/sco5.h"
if test x$gas = xyes
then
@@ -1245,9 +1055,10 @@ i[34567]86-*-sco3.2v5*) # 80386 running SCO Open Server 5
fi
tmake_file=i386/t-sco5
extra_parts="crtbegin.o crtend.o"
+ use_fixproto=yes
;;
i[34567]86-*-solaris2*)
- xm_defines="POSIX SMALL_ARG_MAX"
+ xm_defines="SMALL_ARG_MAX"
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h sol2.h i386/sol2.h"
tmake_file="i386/t-sol2 t-svr4"
if test x$gnu_ld = xyes; then
@@ -1255,6 +1066,11 @@ i[34567]86-*-solaris2*)
else
tmake_file="$tmake_file t-slibgcc-sld"
fi
+ case ${target} in
+ *-*-solaris2.[789] | *-*-solaris2.1[0-9])
+ tm_file="$tm_file tm-dwarf2.h"
+ ;;
+ esac
extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o"
if test x${enable_threads} = x; then
enable_threads=$have_pthread_h
@@ -1271,7 +1087,6 @@ i[34567]86-*-solaris2*)
fi
;;
i[34567]86-*-sysv5*) # Intel x86 on System V Release 5
- xm_defines=POSIX
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h i386/sysv5.h"
if test x$stabs = xyes
then
@@ -1282,9 +1097,10 @@ i[34567]86-*-sysv5*) # Intel x86 on System V Release 5
if test x$enable_threads = xyes; then
thread_file='posix'
fi
+ use_fixproto=yes
;;
i[34567]86-*-sysv4*) # Intel 80386's running system V.4
- xm_defines="POSIX SMALL_ARG_MAX"
+ xm_defines="SMALL_ARG_MAX"
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h i386/sysv4-cpp.h"
if test x$stabs = xyes
then
@@ -1292,16 +1108,15 @@ i[34567]86-*-sysv4*) # Intel 80386's running system V.4
fi
tmake_file="i386/t-crtpic t-svr4"
extra_parts="crtbegin.o crtend.o"
+ use_fixproto=yes
;;
i[34567]86-*-udk*) # Intel x86 on SCO UW/OSR5 Dev Kit
- xm_defines=POSIX
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h i386/sysv4.h i386/sysv5.h i386/udk.h"
tmake_file="i386/t-crtpic i386/t-udk t-svr4"
extra_parts="crtbegin.o crtend.o"
- install_headers_dir=install-headers-cpio
+ use_fixproto=yes
;;
i[34567]86-*-sysv*) # Intel 80386's running system V
- xm_defines=POSIX
if test x$gas = xyes
then
if test x$stabs = xyes
@@ -1320,67 +1135,58 @@ i[34567]86-*-sysv*) # Intel 80386's running system V
tmake_file=i386/t-crtstuff
fi
tmake_file="$tmake_file i386/t-crtpic"
+ use_fixproto=yes
;;
i386-*-vsta) # Intel 80386's running VSTa kernel
- xm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/xm-vsta.h"
- tm_file="${tm_file} i386/vsta.h"
+ xm_file="i386/xm-vsta.h"
+ tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/vsta.h"
+ use_fixproto=yes
;;
-i[34567]86-*-win32)
- xm_defines=POSIX
- xm_file=i386/xm-cygwin.h
- tmake_file=i386/t-cygwin
- tm_file="${tm_file} i386/win32.h"
- extra_objs=winnt.o
- if test x$enable_threads = xyes; then
- thread_file='win32'
- fi
- exeext=.exe
+i[4567]86-wrs-vxworks)
+ tm_file="${tm_file} i386/sysv4.h i386/unix.h i386/vxworks.h"
+ tmake_file="${tmake_file} i386/t-vxworks"
;;
i[34567]86-*-pe | i[34567]86-*-cygwin*)
- xm_defines=POSIX
+ tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/cygwin.h"
xm_file=i386/xm-cygwin.h
- tmake_file=i386/t-cygwin
- tm_file=i386/cygwin.h
+ tmake_file="i386/t-cygwin i386/t-cygming"
extra_objs=winnt.o
+ c_target_objs=cygwin2.o
+ cxx_target_objs=cygwin2.o
+ extra_gcc_objs=cygwin1.o
if test x$enable_threads = xyes; then
- thread_file='win32'
+ thread_file='posix'
fi
- exeext=.exe
;;
i[34567]86-*-mingw32*)
- tm_file=i386/mingw32.h
- xm_defines=POSIX
+ tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/mingw32.h"
xm_file=i386/xm-mingw32.h
- tmake_file="i386/t-cygwin i386/t-mingw32"
+ tmake_file="i386/t-cygming i386/t-mingw32"
extra_objs=winnt.o
if test x$enable_threads = xyes; then
thread_file='win32'
fi
- exeext=.exe
- case $machine in
+ case ${target} in
*mingw32crt*)
tm_file="${tm_file} i386/crtdll.h"
;;
- *minwg32msv* | *mingw32*)
+ *mingw32msv* | *mingw32*)
;;
esac
;;
i[34567]86-*-uwin*)
- tm_file="i386/cygwin.h i386/uwin.h"
+ tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygwin.h i386/uwin.h"
tmake_file="i386/t-cygwin i386/t-uwin"
extra_objs=winnt.o
if test x$enable_threads = xyes; then
thread_file='win32'
fi
- exeext=.exe
+ use_fixproto=yes
;;
i[34567]86-*-interix3*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/i386-interix.h i386/i386-interix3.h interix.h interix3.h"
- xm_file="i386/xm-i386-interix.h"
- xm_defines=POSIX
- tmake_file="t-interix i386/t-interix"
+ tmake_file="i386/t-interix"
extra_objs=winnt.o
- xmake_file="x-interix"
if test x$enable_threads = xyes ; then
thread_file='posix'
fi
@@ -1390,9 +1196,7 @@ i[34567]86-*-interix3*)
;;
i[34567]86-*-interix*)
tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h i386/i386-interix.h interix.h"
- xm_file="i386/xm-i386-interix.h"
- xm_defines=POSIX
- tmake_file="t-interix i386/t-interix"
+ tmake_file="i386/t-interix"
extra_objs=winnt.o
if test x$enable_threads = xyes ; then
thread_file='posix'
@@ -1401,30 +1205,16 @@ i[34567]86-*-interix*)
tm_file="${tm_file} dbxcoff.h"
fi
;;
-i960-wrs-vxworks5 | i960-wrs-vxworks5.0*)
- tm_file="${tm_file} i960/vx960.h"
- tmake_file=i960/t-vxworks960
- use_collect2=yes
- thread_file='vxworks'
- c_target_objs="i960-c.o"
- cxx_target_objs="i960-c.o"
- ;;
-i960-wrs-vxworks5* | i960-wrs-vxworks)
- tm_file="${tm_file} dbxcoff.h i960/i960-coff.h i960/vx960-coff.h"
- tmake_file=i960/t-vxworks960
- use_collect2=yes
- thread_file='vxworks'
- c_target_objs="i960-c.o"
- cxx_target_objs="i960-c.o"
- ;;
-i960-wrs-vxworks*)
- tm_file="${tm_file} i960/vx960.h"
- tmake_file=i960/t-vxworks960
- use_collect2=yes
- thread_file='vxworks'
- c_target_objs="i960-c.o"
- cxx_target_objs="i960-c.o"
+i[34567]86-*-kaos*)
+ tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/i386elf.h kaos.h i386/kaos-i386.h"
+ tmake_file="i386/t-i386elf t-svr4"
;;
+i860-*-sysv4*)
+ tm_file="${tm_file} elfos.h svr4.h i860/sysv4.h"
+ tmake_file="i860/t-i860 i860/t-svr4"
+ extra_parts="crtbegin.o crtend.o"
+ use_fixproto=yes
+ ;;
i960-*-coff*)
tm_file="${tm_file} dbxcoff.h i960/i960-coff.h libgloss.h"
tmake_file=i960/t-960bare
@@ -1432,12 +1222,8 @@ i960-*-coff*)
cxx_target_objs="i960-c.o"
;;
i960-*-rtems)
- xm_defines=POSIX
tmake_file="i960/t-960bare t-rtems"
tm_file="${tm_file} dbxcoff.h i960/i960-coff.h i960/rtems.h rtems.h"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
c_target_objs="i960-c.o"
cxx_target_objs="i960-c.o"
;;
@@ -1446,12 +1232,7 @@ i960-*-*) # Default i960 environment.
tmake_file=i960/t-960bare
c_target_objs="i960-c.o"
cxx_target_objs="i960-c.o"
- ;;
-ia64*-*-aix*)
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h ia64/sysv4.h ia64/aix.h"
- tmake_file="ia64/t-ia64 ia64/t-aix"
- target_cpu_default="MASK_GNU_AS|MASK_GNU_LD"
- extra_parts="crti.o crtn.o crtbegin.o crtend.o crtbeginS.o crtendS.o"
+ use_fixproto=yes
;;
ia64*-*-elf*)
tm_file="${tm_file} dbxelf.h elfos.h ia64/sysv4.h ia64/elf.h"
@@ -1466,6 +1247,7 @@ ia64*-*-elf*)
target_cpu_default="${target_cpu_default}|MASK_GNU_LD"
fi
extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtfastmath.o"
+ use_fixproto=yes
;;
ia64*-*-freebsd*)
tm_file="${tm_file} dbxelf.h elfos.h ${fbsd_tm_file} ia64/sysv4.h ia64/freebsd.h"
@@ -1483,7 +1265,7 @@ ia64*-*-linux*)
fi
;;
ia64*-*-hpux*)
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h ia64/sysv4.h ia64/hpux.h ia64/hpux_longdouble.h"
+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h ia64/sysv4.h ia64/hpux.h"
tmake_file="ia64/t-ia64 ia64/t-hpux"
target_cpu_default="MASK_GNU_AS"
case x$enable_threads in
@@ -1494,12 +1276,50 @@ ia64*-*-hpux*)
use_collect2=no
c_target_objs="ia64-c.o"
cxx_target_objs="ia64-c.o"
+ # If we decide to run fixproto we should define FIXPROTO_DEFINES
+ # in ia64/t-hpux, and also fix the definition of putenv in
+ # sys-protos.h (const char not char).
;;
ip2k-*-elf)
- ;;
+ tm_file="elfos.h ${tm_file}"
+ use_fixproto=yes
+ ;;
+iq2000*-*-elf*)
+ tm_file="svr4.h elfos.h iq2000/iq2000.h"
+ tmake_file=iq2000/t-iq2000
+ out_file=iq2000/iq2000.c
+ md_file=iq2000/iq2000.md
+ use_fixproto=yes
+ ;;
m32r-*-elf*)
tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
+ extra_parts="crtinit.o crtfini.o"
+ use_fixproto=yes
+ ;;
+m32rle-*-elf*)
+ tm_file="dbxelf.h elfos.h svr4.h m32r/little.h ${tm_file}"
extra_parts="crtinit.o crtfini.o m32rx/crtinit.o m32rx/crtfini.o"
+ use_fixproto=yes
+ ;;
+m32r-*-linux*)
+ tm_file="dbxelf.h elfos.h svr4.h linux.h ${tm_file} m32r/linux.h"
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
+ tmake_file="m32r/t-linux"
+ gnu_ld=yes
+ use_fixproto=yes
+ if test x$enable_threads = xyes; then
+ thread_file='posix'
+ fi
+ ;;
+m32rle-*-linux*)
+ tm_file="dbxelf.h elfos.h svr4.h linux.h m32r/little.h ${tm_file} m32r/linux.h"
+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
+ tmake_file="m32r/t-linux"
+ gnu_ld=yes
+ use_fixproto=yes
+ if test x$enable_threads = xyes; then
+ thread_file='posix'
+ fi
;;
# m68hc11 and m68hc12 share the same machine description.
m68hc11-*-*|m6811-*-*)
@@ -1508,6 +1328,7 @@ m68hc11-*-*|m6811-*-*)
md_file="m68hc11/m68hc11.md"
out_file="m68hc11/m68hc11.c"
tmake_file="m68hc11/t-m68hc11-gas"
+ use_fixproto=yes
;;
m68hc12-*-*|m6812-*-*)
tm_file="m68hc11/m68hc12.h dbxelf.h elfos.h m68hc11/m68hc11.h"
@@ -1515,183 +1336,60 @@ m68hc12-*-*|m6812-*-*)
md_file="m68hc11/m68hc11.md"
out_file="m68hc11/m68hc11.c"
tmake_file="m68hc11/t-m68hc11-gas"
+ use_fixproto=yes
;;
-m68000-hp-bsd*) # HP 9000/200 running BSD
- tm_file=m68k/hp2bsd.h
- use_collect2=yes
- ;;
m68000-hp-hpux*) # HP 9000 series 300
- xm_defines=POSIX
+ tm_file="m68k/hp320base.h m68k/m68k.h m68k/hp320.h m68k/hp310.h"
+ tm_defines="TARGET_DEFAULT=0" # 68000, no 68881, no bitfield ops
if test x$gas = xyes
then
- tm_file=m68k/hp310g.h
- else
- tm_file=m68k/hp310.h
+ tm_defines="${tm_defines} DBX_DEBUGGING_INFO=1 USE_GAS"
fi
tmake_file=m68k/t-hp320
- install_headers_dir=install-headers-cpio
- use_collect2=yes
- ;;
-m68000-sun-sunos3*)
- tm_file=m68k/sun2.h
- use_collect2=yes
- ;;
-m68000-sun-sunos4*)
- tm_file=m68k/sun2o4.h
- use_collect2=yes
- ;;
-m68000-att-sysv*)
- xm_defines=POSIX
- if test x$gas = xyes
- then
- tm_file=m68k/3b1g.h
- else
- tm_file=m68k/3b1.h
- fi
- use_collect2=yes
- ;;
-m68k-atari-sysv4*) # Atari variant of V.4.
- tm_file=m68k/atari.h
- xm_defines=POSIX
- tmake_file=t-svr4
- extra_parts="crtbegin.o crtend.o"
- ;;
-m68k-apollo-sysv* | m68k-bull-sysv*)
- # can otherwise be caught by m68k-*-sysv4*
- echo "*** Configuration $machine not supported" 1>&2
- exit 1
- ;;
-m68k-motorola-sysv*)
- tm_file=m68k/mot3300.h
- xm_defines=POSIX
- if test x$gas = xyes
- then
- if test x$gnu_ld = xyes
- then
- tmake_file=m68k/t-mot3300-gald
- else
- tmake_file=m68k/t-mot3300-gas
- use_collect2=yes
- fi
- else
- if test x$gnu_ld = xyes
- then
- tmake_file=m68k/t-mot3300-gld
- else
- tmake_file=m68k/t-mot3300
- use_collect2=yes
- fi
- fi
- gdb_needs_out_file_path=yes
- extra_parts="crt0.o mcrt0.o"
- ;;
-m68k-ncr-sysv*) # NCR Tower 32 SVR3
- tm_file=m68k/tower-as.h
- xm_defines=POSIX
- extra_parts="crtbegin.o crtend.o"
- ;;
-m68k-plexus-sysv*)
- tm_file=m68k/plexus.h
- xm_defines=POSIX
- use_collect2=yes
- ;;
-m68k-tti-*)
- tm_file=m68k/pbb.h
- xm_defines=POSIX
- ;;
-m68k-crds-unos*)
- xm_defines=POSIX
- tm_file=m68k/crds.h
- use_collect2=yes
- ;;
-m68k-cbm-sysv4*) # Commodore variant of V.4.
- tm_file=m68k/amix.h
- xm_defines=POSIX
- tmake_file=t-svr4
- extra_parts="crtbegin.o crtend.o"
- ;;
-m68k-ccur-rtu)
- tm_file=m68k/ccur-GAS.h
- use_collect2=yes
- ;;
-m68k-hp-bsd4.4*) # HP 9000/3xx running 4.4bsd
- tm_file=m68k/hp3bsd44.h
- use_collect2=yes
- ;;
-m68k-hp-bsd*) # HP 9000/3xx running Berkeley Unix
- tm_file=m68k/hp3bsd.h
use_collect2=yes
+ use_fixproto=yes
;;
m68k-hp-hpux7*) # HP 9000 series 300 running HPUX version 7.
- xm_defines=POSIX
+ tm_file="m68k/hp320base.h m68k/m68k.h m68k/hp320.h"
if test x$gas = xyes
then
- xmake_file=m68k/x-hp320g
- tm_file=m68k/hp320g.h
+ tm_defines="DBX_DEBUGGING_INFO=1 USE_GAS"
else
- xmake_file=m68k/x-hp320
- tm_file=m68k/hpux7.h
+ tm_defines="NO_DOT_IN_LABEL NO_BUGS"
fi
- install_headers_dir=install-headers-cpio
use_collect2=yes
+ use_fixproto=yes
;;
m68k-hp-hpux*) # HP 9000 series 300
- xm_defines=POSIX
+ tm_file="m68k/hp320base.h m68k/m68k.h m68k/hp320.h"
if test x$gas = xyes
then
- xmake_file=m68k/x-hp320g
- tm_file=m68k/hp320g.h
- else
- xmake_file=m68k/x-hp320
- tm_file=m68k/hp320.h
- fi
- install_headers_dir=install-headers-cpio
- use_collect2=yes
- ;;
-m68k-sun-mach*)
- tm_file=m68k/sun3mach.h
- use_collect2=yes
- ;;
-m68k-sun-sunos3*)
- if test x$with_fp = xno
- then
- tm_file=m68k/sun3n3.h
- else
- tm_file=m68k/sun3o3.h
+ tm_defines="DBX_DEBUGGING_INFO=1 USE_GAS"
fi
use_collect2=yes
- ;;
-m68k-sun-sunos*) # For SunOS 4 (the default).
- if test x$with_fp = xno
- then
- tm_file=m68k/sun3n.h
- else
- tm_file=m68k/sun3.h
- fi
- use_collect2=yes
- ;;
-m68k-wrs-vxworks*)
- tm_file=m68k/vxm68k.h
- tmake_file=m68k/t-vxworks68
- thread_file='vxworks'
+ use_fixproto=yes
;;
m68k-*-aout*)
tmake_file=m68k/t-m68kbare
- tm_file="m68k/m68k-aout.h libgloss.h"
+ tm_file="m68k/m68k.h m68k/m68k-none.h m68k/m68kemb.h m68k/m68k-aout.h libgloss.h"
;;
m68k-*-coff*)
tmake_file=m68k/t-m68kbare
- tm_file="m68k/m68k-coff.h dbx.h"
+ tm_defines="MOTOROLA USE_GAS"
+ tm_file="m68k/m68k.h m68k/m68k-none.h m68k/m68kemb.h dbxcoff.h m68k/coff.h dbx.h"
+ use_fixproto=yes
;;
m68020-*-elf* | m68k-*-elf*)
- tm_file="m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/m68kemb.h m68k/m68020-elf.h"
- xm_defines=POSIX
+ tm_file="m68k/m68k.h m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/m68kemb.h m68k/m68020-elf.h"
+ tm_defines="MOTOROLA USE_GAS"
tmake_file=m68k/t-m68kelf
extra_parts="crtbegin.o crtend.o"
+ use_fixproto=yes
;;
m68010-*-netbsdelf* | m68k*-*-netbsdelf*)
tm_file="${tm_file} dbxelf.h elfos.h netbsd.h netbsd-elf.h m68k/netbsd-elf.h"
- case $machine in
+ tm_defines="MOTOROLA USE_GAS"
+ case ${target} in
m68010*)
target_cpu_default="0"
;;
@@ -1701,248 +1399,224 @@ m68010-*-netbsdelf* | m68k*-*-netbsdelf*)
esac
;;
m68k*-*-netbsd*)
- tm_file=m68k/netbsd.h
+ if test "x$enable_obsolete" != xyes; then
+ echo "*** Configuration ${target} is obsolete." >&2
+ echo "*** Specify --enable-obsolete to build it anyway." >&2
+ echo "*** Support will be REMOVED in the next major release of GCC," >&2
+ echo "*** unless a maintainer comes forward." >&2
+ exit 1
+ fi
+ tm_file="m68k/m68k.h netbsd.h netbsd-aout.h m68k/netbsd.h"
tmake_file=t-netbsd
extra_parts=""
use_collect2=yes
;;
m68k*-*-openbsd*)
# needed to unconfuse gdb
+ tm_defines="OBSD_OLD_GAS TARGET_DEFAULT=(MASK_68020|MASK_68881|MASK_BITFIELD)"
+ tm_file="m68k/m68k.h openbsd.h m68k/openbsd.h"
tmake_file="t-libc-ok t-openbsd m68k/t-openbsd"
# we need collect2 until our bug is fixed...
use_collect2=yes
;;
m68k-*-sysv4*) # Motorola m68k's running system V.4
- tm_file=m68k/m68kv4.h
- xm_defines=POSIX
+ tm_file="m68k/m68k.h m68k/sgs.h dbxelf.h elfos.h svr4.h m68k/m68kv4.h"
+ tm_defines="MOTOROLA SGS SGS_CMP_ORDER SGS_SWITCH_TABLES"
tmake_file=t-svr4
extra_parts="crtbegin.o crtend.o"
+ use_fixproto=yes
;;
-m68k-*-linux*aout*) # Motorola m68k's running GNU/Linux
- # with a.out format
- tm_file=m68k/linux-aout.h
- tmake_file="t-linux-aout m68k/t-linux-aout"
- gnu_ld=yes
- ;;
-m68k-*-linux*libc1) # Motorola m68k's running GNU/Linux
- # with ELF format using the
- # GNU/Linux C library 5
- tm_file=m68k/linux.h
- tmake_file="t-slibgcc-elf-ver t-linux t-linux-gnulibc1 m68k/t-linux"
- extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- gnu_ld=yes
+m68k-*-uclinux*) # Motorola m68k/ColdFire running uClinux with uClibc
+ tm_file="m68k/m68k.h m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/uclinux.h"
+ tm_defines="MOTOROLA USE_GAS"
+ tmake_file=m68k/t-uclinux
+ use_fixproto=no
;;
m68k-*-linux*) # Motorola m68k's running GNU/Linux
# with ELF format using glibc 2
# aka the GNU/Linux C library 6.
- tm_file=m68k/linux.h
- tmake_file="t-slibgcc-elf-ver t-linux m68k/t-linux"
- ;;
-m68k-*-psos*)
- tmake_file=m68k/t-m68kbare
- tm_file=m68k/m68k-psos.h
- ;;
-m68k-*-rtemscoff*) # would otherwise be caught by m68k-*-rtems*
- echo "*** Configuration $machine not supported" 1>&2
- exit 1
+ tm_file="m68k/m68k.h dbxelf.h elfos.h svr4.h linux.h m68k/linux.h"
+ tm_defines="MOTOROLA USE_GAS"
+ tmake_file="t-slibgcc-elf-ver t-linux"
+ # if not configured with --enable-sjlj-exceptions, bump the
+ # libgcc version number
+ if test x$sjlj != x1; then
+ tmake_file="$tmake_file m68k/t-slibgcc-elf-ver"
+ fi
;;
m68k-*-rtems*)
- xm_defines=POSIX
tmake_file="m68k/t-m68kbare m68k/t-crtstuff t-rtems m68k/t-rtems"
- tm_file="m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/m68kemb.h m68k/m68020-elf.h m68k/rtemself.h rtems.h"
+ tm_file="m68k/m68k.h m68k/m68k-none.h m68k/m68kelf.h dbxelf.h elfos.h m68k/m68kemb.h m68k/m68020-elf.h m68k/rtemself.h rtems.h"
+ tm_defines="MOTOROLA USE_GAS"
extra_parts="crtbegin.o crtend.o"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
- ;;
-m88k-*-aout*)
- xm_defines=POSIX
- tm_file=m88k/m88k-aout.h
- ;;
-m88k-*-openbsd*)
- tmake_file="${tmake_file} m88k/t-luna-gas"
- tm_file="m88k/aout-dbx.h aoutos.h m88k/m88k.h openbsd.h ${tm_file}"
- ;;
-m88k-*-sysv4*)
- xm_defines=POSIX
- tm_file="dbxelf.h elfos.h svr4.h m88k/sysv4.h"
- extra_parts="crtbegin.o crtend.o"
- tmake_file=m88k/t-sysv4
;;
mcore-*-elf)
tm_file="dbxelf.h elfos.h svr4.h ${tm_file} mcore/mcore-elf.h"
tmake_file=mcore/t-mcore
+ use_fixproto=yes
;;
mcore-*-pe*)
- tm_file=mcore/mcore-pe.h
+ tm_file="svr3.h dbxcoff.h ${tm_file} mcore/mcore-pe.h"
tmake_file=mcore/t-mcore-pe
+ use_fixproto=yes
;;
-mips-sgi-irix6*o32) # SGI System V.4., IRIX 6, O32 ABI
+mips-sgi-irix6*) # SGI System V.4., IRIX 6
+ tm_file="${tm_file} mips/iris5.h mips/iris6.h"
+ tmake_file="mips/t-iris mips/t-iris5-6 mips/t-iris6"
if test x$gas = xyes
then
- tm_file="mips/iris5.h mips/iris5gas.h mips/iris6-o32-gas.h"
- if test x$stabs = xyes
- then
- tm_file="${tm_file} dbx.h mips/dbxmdebug.h"
- fi
- tmake_file=mips/t-iris5-gas
- else
- tm_file="mips/iris5.h mips/iris6-o32-as.h"
- tmake_file=mips/t-iris5-as
+ tm_file="${tm_file} mips/iris6gas.h"
fi
- tm_file="${tm_file} mips/iris6-o32.h"
- tmake_file="${tmake_file} mips/t-iris mips/t-iris5-6"
- xm_defines=POSIX
- xm_file=mips/xm-iris5.h
- # mips-tfile doesn't work yet
- # See comment in mips/iris5.h file.
- use_collect2=yes
-# if test x$enable_threads = xyes; then
-# thread_file='irix'
-# fi
- ;;
-mips-sgi-irix6*) # SGI System V.4., IRIX 6
if test "x$gnu_ld" = xyes
then
- tm_file="mips/iris6.h mips/iris6gld.h"
- else
- tm_file=mips/iris6.h
+ tm_file="${tm_file} mips/iris6gld.h"
+ tmake_file="$tmake_file mips/t-irix-gld"
+ fi
+ target_cpu_default="MASK_ABICALLS|MASK_FLOAT64|MASK_64BIT"
+ tm_defines="MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_N32"
+ # See comment in mips/iris5.h file. Only enabled for O32 ABI
+ # without GNU as.
+ if test x$gas = xno
+ then
+ use_collect2=yes
fi
- tmake_file="mips/t-iris mips/t-iris5-6 mips/t-iris6"
- xm_defines=POSIX
# if test x$enable_threads = xyes; then
# thread_file='irix'
# fi
- ;;
-mips-wrs-vxworks)
- tm_file="${tm_file} mips/elf.h mips/vxworks.h"
- tmake_file=mips/t-ecoff
- gas=yes
- gnu_ld=yes
- extra_parts="crtbegin.o crtend.o"
- thread_file='vxworks'
+ use_fixproto=yes
;;
mips-sgi-irix5cross64) # Irix5 host, Irix 6 target, cross64
- tm_file="mips/iris6.h mips/cross64.h"
- xm_defines=POSIX
- xm_file=mips/xm-iris5.h
+ tm_file="${tm_file} mips/iris5.h mips/iris6.h mips/cross64.h"
tmake_file="mips/t-iris mips/t-cross64"
+ target_cpu_default="MASK_ABICALLS|MASK_FLOAT64|MASK_64BIT"
+ tm_defines="MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_N32"
# See comment in mips/iris[56].h files.
use_collect2=yes
# if test x$enable_threads = xyes; then
# thread_file='irix'
# fi
+ use_fixproto=yes
;;
-mips-sni-sysv4)
- if test x$gas = xyes
- then
- if test x$stabs = xyes
- then
- tm_file=mips/iris5gdb.h
- else
- tm_file="mips/sni-svr4.h mips/sni-gas.h"
- fi
- else
- tm_file=mips/sni-svr4.h
- fi
- xm_defines=POSIX
- if test x$gnu_ld != xyes
- then
- use_collect2=yes
- fi
- ;;
mips-sgi-irix5*) # SGI System V.4., IRIX 5
+ tm_file="${tm_file} mips/iris5.h"
if test x$gas = xyes
then
- tm_file="mips/iris5.h mips/iris5gas.h"
+ tm_file="${tm_file} mips/sdb.h mips/iris5gas.h"
if test x$stabs = xyes
then
tm_file="${tm_file} dbx.h mips/dbxmdebug.h"
fi
tmake_file=mips/t-iris5-gas
else
- tm_file=mips/iris5.h
tmake_file=mips/t-iris5-as
fi
+ if test "x$gnu_ld" = xyes
+ then
+ tm_file="${tm_file} mips/iris5gld.h"
+ tmake_file="$tmake_file mips/t-irix-gld"
+ fi
tmake_file="${tmake_file} mips/t-iris mips/t-iris5-6"
- xm_defines=POSIX
- xm_file=mips/xm-iris5.h
+ target_cpu_default="MASK_ABICALLS"
# mips-tfile doesn't work yet
# See comment in mips/iris5.h file.
- use_collect2=yes
+ if test x$gas = xno
+ then
+ use_collect2=yes
+ fi
# if test x$enable_threads = xyes; then
# thread_file='irix'
# fi
- ;;
-mips-sgi-*) # would otherwise be caught by mips-*-elf*
- echo "*** Configuration $machine not supported" 1>&2
- exit 1
+ use_fixproto=yes
;;
mips*-*-netbsd*) # NetBSD/mips, either endian.
target_cpu_default="MASK_GAS|MASK_ABICALLS"
- tm_file="elfos.h ${tm_file} mips/netbsd.h"
- tmake_file="${tmake_file} mips/t-netbsd"
+ tm_file="elfos.h ${tm_file} mips/elf.h netbsd.h netbsd-elf.h mips/netbsd.h"
+ ;;
+mips64*-*-linux*)
+ tm_file="dbxelf.h elfos.h svr4.h linux.h ${tm_file} mips/linux.h mips/linux64.h"
+ tmake_file="t-slibgcc-elf-ver t-linux mips/t-linux64"
+
+ # This default ABI is a partial lie: t-linux64 overrides the
+ # DRIVER_SELF_SPEC that sets the default abi, in the spec file
+ # that is installed. What GCC thinks of as the default must
+ # remain as ABI_32 such that the SONAMEs of the libgcc shared
+ # libraries remain compatible with those of mips-linux-gnu.
+ tm_defines="MIPS_ISA_DEFAULT=1 MIPS_ABI_DEFAULT=ABI_32"
+ target_cpu_default="MASK_ABICALLS|MASK_FLOAT64|MASK_64BIT"
+ extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
+ gnu_ld=yes
+ gas=yes
;;
mips*-*-linux*) # Linux MIPS, either endian.
tm_file="dbxelf.h elfos.h svr4.h linux.h ${tm_file} mips/linux.h"
- case $machine in
+ case ${target} in
mipsisa32*-*)
target_cpu_default="MASK_SOFT_FLOAT"
tm_defines="MIPS_ISA_DEFAULT=32"
;;
esac
- tmake_file="t-slibgcc-elf-ver t-linux mips/t-linux"
- ;;
-mips*el-*-openbsd*) # mips little endian
- target_cpu_default="MASK_GAS|MASK_ABICALLS"
+ tmake_file="t-slibgcc-elf-ver t-linux"
;;
-mips*-*-openbsd*) # mips big endian
+mips*-*-openbsd*)
+ tm_defines="OBSD_HAS_DECLARE_FUNCTION_NAME OBSD_HAS_DECLARE_OBJECT OBSD_HAS_CORRECT_SPECS"
target_cpu_default="MASK_GAS|MASK_ABICALLS"
- tm_file="mips/openbsd-be.h ${tm_file}"
- ;;
-mips-*-ecoff* | mipsel-*-ecoff*)
- if test x$stabs = xyes; then
- tm_file="${tm_file} dbx.h"
- fi
- tmake_file=mips/t-ecoff
+ tm_file="mips/mips.h openbsd.h mips/openbsd.h mips/sdb.h"
+ case ${target} in
+ mips*el-*-openbsd*)
+ tm_defines="${tm_defines} TARGET_ENDIAN_DEFAULT=0";;
+ *) tm_defines="${tm_defines} TARGET_ENDIAN_DEFAULT=MASK_BIG_ENDIAN";;
+ esac
;;
mipsisa32-*-elf* | mipsisa32el-*-elf*)
tm_file="${tm_file} mips/elf.h"
tmake_file=mips/t-isa3264
- tm_defines="MIPS_ISA_DEFAULT=32 MIPS_ABI_DEFAULT=ABI_MEABI"
+ tm_defines="MIPS_ISA_DEFAULT=32 MIPS_ABI_DEFAULT=ABI_EABI"
+ use_fixproto=yes
+ ;;
+mipsisa32r2-*-elf* | mipsisa32r2el-*-elf*)
+ tm_file="${tm_file} mips/elf.h"
+ tmake_file=mips/t-isa3264
+ tm_defines="MIPS_ISA_DEFAULT=33 MIPS_ABI_DEFAULT=ABI_EABI"
+ use_fixproto=yes
;;
mipsisa64-*-elf* | mipsisa64el-*-elf*)
tm_file="${tm_file} mips/elf.h"
tmake_file=mips/t-isa3264
target_cpu_default="MASK_64BIT|MASK_FLOAT64|MASK_GAS"
- tm_defines="MIPS_ISA_DEFAULT=64 MIPS_ABI_DEFAULT=ABI_MEABI"
+ tm_defines="MIPS_ISA_DEFAULT=64 MIPS_ABI_DEFAULT=ABI_EABI"
+ use_fixproto=yes
;;
mipsisa64sr71k-*-elf*)
tm_file="${tm_file} mips/elf.h"
tmake_file=mips/t-sr71k
target_cpu_default="MASK_64BIT|MASK_FLOAT64|MASK_GAS"
- tm_defines="MIPS_ISA_DEFAULT=64 MIPS_CPU_STRING_DEFAULT=\\\"sr71000\\\" MIPS_ABI_DEFAULT=ABI_MEABI"
+ tm_defines="MIPS_ISA_DEFAULT=64 MIPS_CPU_STRING_DEFAULT=\\\"sr71000\\\" MIPS_ABI_DEFAULT=ABI_EABI"
+ use_fixproto=yes
;;
mipsisa64sb1-*-elf* | mipsisa64sb1el-*-elf*)
tm_file="${tm_file} mips/elf.h"
tmake_file=mips/t-elf
target_cpu_default="MASK_64BIT|MASK_FLOAT64|MASK_GAS"
tm_defines="MIPS_ISA_DEFAULT=64 MIPS_CPU_STRING_DEFAULT=\\\"sb1\\\" MIPS_ABI_DEFAULT=ABI_O64"
+ use_fixproto=yes
;;
mips-*-elf* | mipsel-*-elf*)
tm_file="${tm_file} mips/elf.h"
tmake_file=mips/t-elf
+ use_fixproto=yes
;;
mips64-*-elf* | mips64el-*-elf*)
tm_file="${tm_file} mips/elf64.h"
tmake_file=mips/t-elf
target_cpu_default="MASK_64BIT|MASK_FLOAT64|MASK_GAS"
tm_defines="MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_O64"
+ use_fixproto=yes
;;
mips64vr-*-elf* | mips64vrel-*-elf*)
tm_file="mips/vr.h ${tm_file} mips/elf64.h"
tm_defines="MIPS_ABI_DEFAULT=ABI_O64 MIPS_MARCH_CONTROLS_SOFT_FLOAT=1"
tmake_file=mips/t-vr
+ use_fixproto=yes
;;
mips64orion-*-elf* | mips64orionel-*-elf*)
tm_file="${tm_file} mips/elforion.h mips/elf64.h"
@@ -1950,39 +1624,33 @@ mips64orion-*-elf* | mips64orionel-*-elf*)
tmake_file=mips/t-elf
target_cpu_default="MASK_64BIT|MASK_FLOAT64|MASK_GAS"
tm_defines="MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_O64"
- ;;
-mips64orion-*-rtems*)
- xm_defines=POSIX
- tm_file="${tm_file} mips/elforion.h mips/elf64.h mips/rtems64.h rtems.h"
- tmake_file="mips/t-elf t-rtems"
- tmake_file=mips/t-elf
- target_cpu_default="MASK_64BIT|MASK_FLOAT64|MASK_GAS"
- tm_defines="MIPS_ISA_DEFAULT=3 MIPS_ABI_DEFAULT=ABI_O64"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
+ use_fixproto=yes
;;
mips*-*-rtems*)
- xm_defines=POSIX
tm_file="${tm_file} mips/elf.h mips/rtems.h rtems.h"
tmake_file="mips/t-elf t-rtems mips/t-rtems"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
+ ;;
+mips-wrs-vxworks)
+ # We want vxworks.h after mips/elf.h, which unfortunately means we
+ # have to redo the tm_file list from scratch.
+ tm_file="elfos.h mips/mips.h svr4.h mips/elf.h vxworks.h mips/vxworks.h"
+ tmake_file="${tmake_file} mips/t-vxworks"
+ target_cpu_default="MASK_GAS"
+ ;;
+mips-wrs-windiss) # Instruction-level simulator for VxWorks.
+ xm_defines=POSIX
+ tm_file="elfos.h mips/mips.h svr4.h mips/elf.h windiss.h mips/windiss.h"
+ tmake_file="${tmake_file} mips/t-elf"
+ target_cpu_default="MASK_GAS"
+ thread_file=
;;
mipstx39-*-elf* | mipstx39el-*-elf*)
tm_file="${tm_file} mips/r3900.h mips/elf.h"
tmake_file=mips/t-r3900
+ use_fixproto=yes
;;
mmix-knuth-mmixware)
- ;;
-mn10200-*-*)
- tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
- if test x$stabs = xyes
- then
- tm_file="${tm_file} dbx.h"
- fi
- use_collect2=no
+ need_64bit_hwint=yes
;;
mn10300-*-*)
tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
@@ -1991,9 +1659,10 @@ mn10300-*-*)
tm_file="${tm_file} dbx.h"
fi
use_collect2=no
+ use_fixproto=yes
;;
ns32k-*-netbsdelf*)
- echo "GCC does not yet support the ${machine} target"; exit 1
+ echo "GCC does not yet support the ${target} target"; exit 1
;;
ns32k-*-netbsd*)
tm_file="${tm_file} netbsd.h netbsd-aout.h ns32k/netbsd.h"
@@ -2004,252 +1673,188 @@ ns32k-*-netbsd*)
;;
pdp11-*-bsd)
tm_file="${tm_file} pdp11/2bsd.h"
+ use_fixproto=yes
;;
pdp11-*-*)
+ use_fixproto=yes
;;
avr-*-*)
+ use_fixproto=yes
;;
-ns32k-*-openbsd*)
- # Nothing special
- ;;
-romp-*-openbsd*)
- # Nothing special
- ;;
-powerpc-*-openbsd*)
- tmake_file="${tmake_file} rs6000/t-rs6000 rs6000/t-openbsd"
- extra_headers=
- ;;
+# port not yet contributed
+#powerpc-*-openbsd*)
+# tmake_file="${tmake_file} rs6000/t-fprules "
+# extra_headers=
+# ;;
powerpc64-*-linux*)
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux64.h"
- out_file=rs6000/rs6000.c
- tmake_file="rs6000/t-rs6000 t-slibgcc-elf-ver t-linux rs6000/t-linux64"
+ tm_file="rs6000/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h"
+ case x$with_cpu in
+ x|xpowerpc64|xdefault64) tm_file="${tm_file} rs6000/default64.h";;
+ esac
+ tm_file="${tm_file} rs6000/linux64.h"
+ tmake_file="rs6000/t-fprules t-slibgcc-elf-ver t-linux rs6000/t-ppccomm rs6000/t-linux64"
;;
powerpc64-*-gnu*)
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux64.h rs6000/gnu.h"
- out_file=rs6000/rs6000.c
- tmake_file="rs6000/t-rs6000 t-slibgcc-elf-ver t-gnu rs6000/t-linux64"
+ tmake_file="rs6000/t-fprules t-slibgcc-elf-ver t-gnu rs6000/t-linux64"
;;
powerpc-*-beos*)
tm_file="${tm_file} rs6000/aix.h rs6000/beos.h rs6000/xcoff.h"
- xm_defines=POSIX
- tmake_file=rs6000/t-beos
+ tmake_file="rs6000/t-fprules rs6000/t-beos"
extra_headers=
+ use_fixproto=yes
;;
powerpc-*-darwin*)
- tm_file="${tm_file} darwin.h rs6000/darwin.h"
- tm_p_file="${tm_p_file} darwin-protos.h"
- tmake_file="rs6000/t-rs6000 t-darwin rs6000/t-darwin"
- extra_objs="darwin.o"
- target_gtfiles="\$(srcdir)/config/darwin.c"
- c_target_objs="darwin-c.o"
- cxx_target_objs="darwin-c.o"
- extra_parts="crt2.o"
- # Darwin linker does collect2 functionality
- use_collect2=no
+ tm_file="${tm_file} rs6000/darwin.h"
+ tmake_file="t-darwin t-slibgcc-darwin rs6000/t-darwin"
extra_headers=altivec.h
;;
powerpc*-*-freebsd*)
tm_file="${tm_file} dbxelf.h elfos.h ${fbsd_tm_file} rs6000/sysv4.h rs6000/freebsd.h"
- xm_file=rs6000/xm-sysv4.h
- out_file=rs6000/rs6000.c
- tmake_file="rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
- ;;
-powerpc-*-sysv*)
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h"
- xm_defines=POSIX
- tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
;;
powerpc-*-netbsd*)
tm_file="${tm_file} dbxelf.h elfos.h netbsd.h netbsd-elf.h freebsd-spec.h rs6000/sysv4.h rs6000/netbsd.h"
tmake_file="${tmake_file} rs6000/t-netbsd"
;;
powerpc-*-chorusos*)
- xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h chorus.h"
- tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
- case x${enable_threads} in
- xyes | xpthreads | xposix)
- thread_file='posix'
- ;;
+ tmake_file="rs6000/t-fprules rs6000/t-ppcos rs6000/t-ppccomm"
+ case ${enable_threads} in
+ yes | posix)
+ thread_file='posix'
+ ;;
esac
- ;;
-powerpc-*-eabiaix*)
- xm_defines=POSIX
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabiaix.h"
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+ use_fixproto=yes
;;
powerpc-*-eabispe*)
- xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabispe.h"
- tmake_file="rs6000/t-ppcendian rs6000/t-ppccomm"
+ tmake_file="rs6000/t-spe rs6000/t-ppccomm"
;;
powerpc-*-eabisimaltivec*)
- xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabisim.h rs6000/eabialtivec.h"
- tmake_file="rs6000/t-ppcendian rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcendian rs6000/t-ppccomm"
;;
powerpc-*-eabisim*)
- xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabisim.h"
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
;;
powerpc-*-elf*)
- xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h"
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
+ use_fixproto=yes
;;
powerpc-*-eabialtivec*)
- xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabialtivec.h"
- tmake_file="rs6000/t-ppcendian rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcendian rs6000/t-ppccomm"
;;
powerpc-*-eabi*)
- xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h"
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
;;
powerpc-*-rtems*)
- xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/eabi.h rs6000/rtems.h rtems.h"
- tmake_file="rs6000/t-rtems t-rtems rs6000/t-ppccomm"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
+ tmake_file="rs6000/t-fprules rs6000/t-rtems t-rtems rs6000/t-ppccomm"
;;
-powerpc-*-linux*libc1)
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h"
- out_file=rs6000/rs6000.c
- tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-linux t-linux-gnulibc1 rs6000/t-ppccomm"
- if test x$enable_threads = xyes; then
- thread_file='posix'
- fi
- ;;
-powerpc-*-linux-gnualtivec*)
+powerpc-*-linux*altivec*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h"
- out_file=rs6000/rs6000.c
- tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
+ ;;
+powerpc-*-linux*spe*)
+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxspe.h"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
;;
powerpc-*-linux*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h"
- out_file=rs6000/rs6000.c
- tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcos t-slibgcc-elf-ver t-linux rs6000/t-ppccomm"
;;
powerpc-*-gnu-gnualtivec*)
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h rs6000/gnu.h"
- out_file=rs6000/rs6000.c
- tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
powerpc-*-gnu*)
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/gnu.h"
- out_file=rs6000/rs6000.c
- tmake_file="rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcos t-slibgcc-elf-ver t-gnu rs6000/t-ppccomm"
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
powerpc-wrs-vxworks*)
- xm_defines=POSIX
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/vxppc.h"
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
- thread_file='vxworks'
- ;;
-powerpc-wrs-windiss*)
- xm_defines=POSIX
+ # We want vxworks.h after rs6000/sysv4.h, which unfortunately
+ # means we have to redo the tm_file list from scratch.
+ tm_file="rs6000/rs6000.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h"
+ tm_file="${tm_file} vxworks.h rs6000/vxworks.h"
+ tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-ppccomm rs6000/t-vxworks"
+ extra_headers=ppc-asm.h
+ ;;
+powerpc-wrs-windiss*) # Instruction-level simulator for VxWorks.
tm_file="${tm_file} elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/windiss.h"
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
thread_file=""
- ;;
-powerpcle-wrs-vxworks*)
- xm_defines=POSIX
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/vxppc.h"
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
- thread_file='vxworks'
+ use_fixproto=yes
;;
powerpcle-*-sysv*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h"
- xm_defines=POSIX
- tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcos rs6000/t-ppccomm"
+ use_fixproto=yes
;;
powerpcle-*-elf*)
- xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h"
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
+ use_fixproto=yes
;;
powerpcle-*-eabisim*)
- xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/eabisim.h"
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
;;
powerpcle-*-eabi*)
- xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h"
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
;;
-rs6000-ibm-aix3.[01]*)
- xm_defines=POSIX
- tm_file="${tm_file} rs6000/aix.h rs6000/aix31.h rs6000/xcoff.h"
- use_collect2=yes
+powerpc-*-kaos*)
+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h kaos.h rs6000/kaos-ppc.h"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
;;
-rs6000-ibm-aix3.2.[456789]* | powerpc-ibm-aix3.2.[456789]*)
- xm_defines=POSIX
- tm_file="${tm_file} rs6000/aix.h rs6000/aix3newas.h rs6000/xcoff.h"
- tmake_file=rs6000/t-newas
- use_collect2=yes
- extra_headers=
+powerpcle-*-kaos*)
+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/sysv4le.h kaos.h rs6000/kaos-ppc.h"
+ tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
;;
rs6000-ibm-aix4.[12]* | powerpc-ibm-aix4.[12]*)
- xm_defines=POSIX
tm_file="${tm_file} rs6000/aix.h rs6000/aix41.h rs6000/xcoff.h"
- tmake_file=rs6000/t-newas
+ tmake_file="rs6000/t-fprules rs6000/t-newas"
use_collect2=yes
extra_headers=
+ use_fixproto=yes
;;
rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
- xm_defines=POSIX
- tm_file="${tm_file} rs6000/aix.h rs6000/aix43.h rs6000/xcoff.h"
+ tm_file="rs6000/biarch64.h ${tm_file} rs6000/aix.h rs6000/aix43.h rs6000/xcoff.h"
tmake_file=rs6000/t-aix43
use_collect2=yes
thread_file='aix'
extra_headers=
;;
rs6000-ibm-aix5.1.* | powerpc-ibm-aix5.1.*)
- xm_defines=POSIX
- tm_file="${tm_file} rs6000/aix.h rs6000/aix51.h rs6000/xcoff.h"
+ tm_file="rs6000/biarch64.h ${tm_file} rs6000/aix.h rs6000/aix51.h rs6000/xcoff.h"
tmake_file=rs6000/t-aix43
use_collect2=yes
thread_file='aix'
extra_headers=
;;
rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*)
- xm_defines=POSIX
tm_file="${tm_file} rs6000/aix.h rs6000/aix52.h rs6000/xcoff.h"
tmake_file=rs6000/t-aix52
use_collect2=yes
thread_file='aix'
extra_headers=
;;
-rs6000-ibm-aix*)
- xm_defines=POSIX
- tm_file="${tm_file} rs6000/aix.h rs6000/xcoff.h"
- use_collect2=yes
- ;;
-rs6000-bull-bosx)
- xm_defines=POSIX
- tm_file="${tm_file} rs6000/aix.h rs6000/xcoff.h"
- use_collect2=yes
- ;;
-rs6000-*-mach*)
- tm_file="${tm_file} rs6000/mach.h"
- xm_defines=POSIX
- use_collect2=yes
- ;;
rs6000-*-lynxos*)
- tm_file="lynx.h rs6000/lynx.h"
- tmake_file=rs6000/t-rs6000
+ tm_file="svr3.h lynx.h rs6000/lynxbase.h rs6000/rs6000.h rs6000/lynx.h"
+ tmake_file=rs6000/t-fprules
use_collect2=yes
+ use_fixproto=yes
;;
s390-*-linux*)
tm_file="s390/s390.h dbxelf.h elfos.h svr4.h linux.h s390/linux.h"
@@ -2263,16 +1868,25 @@ s390x-*-linux*)
out_file=s390/s390.c
tmake_file="t-slibgcc-elf-ver t-linux s390/t-crtstuff s390/t-linux64"
;;
-sh-*-elf* | sh[2346l]*-*-elf*)
+s390x-ibm-tpf*)
+ tm_file="s390/s390x.h s390/s390.h dbxelf.h elfos.h svr4.h s390/tpf.h"
+ tm_p_file=s390/s390-protos.h
+ md_file=s390/s390.md
+ extra_modes=s390/s390-modes.def
+ extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
+ out_file=s390/s390.c
+ tmake_file="t-slibgcc-elf-ver s390/t-crtstuff s390/t-tpf"
+ ;;
+sh-*-elf* | sh[2346l]*-*-elf* | sh*-*-kaos*)
tmake_file="sh/t-sh sh/t-elf"
- case $machine in
+ case ${target} in
shl* | sh64l*)
tm_file="sh/little.h ${tm_file}"
tmake_file="${tmake_file} sh/t-le"
;;
esac
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h sh/embed-elf.h"
- case $machine in
+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h sh/elf.h sh/embed-elf.h"
+ case ${target} in
sh64*)
tmake_file="${tmake_file} sh/t-sh64"
tm_file="${tm_file} sh/sh64.h"
@@ -2282,31 +1896,28 @@ sh-*-elf* | sh[2346l]*-*-elf*)
sh4*) target_cpu_default="SELECT_SH4" ;;
sh3e*) target_cpu_default="SELECT_SH3E" ;;
sh3*) target_cpu_default="SELECT_SH3" ;;
+ sh2e*) target_cpu_default="SELECT_SH2E" ;;
sh2*) target_cpu_default="SELECT_SH2" ;;
esac
- case $machine in
+ case ${target} in
sh[234]*) tmake_file="${tmake_file} sh/t-monolib" ;;
esac
+ case ${target} in
+ sh*-*-kaos*) tm_file="${tm_file} kaos.h sh/kaos-sh.h" ;;
+ esac
+ use_fixproto=yes
;;
-sh-*-rtemself*)
- xm_defines=POSIX
- tmake_file="sh/t-sh sh/t-elf t-rtems"
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h sh/embed-elf.h sh/rtemself.h rtems.h"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
+sh-*-rtemscoff*)
+ tmake_file="sh/t-sh t-rtems"
+ tm_file="${tm_file} dbxcoff.h sh/coff.h sh/rtems.h rtems.h"
;;
sh-*-rtems*)
- xm_defines=POSIX
- tmake_file="sh/t-sh t-rtems"
- tm_file="${tm_file} sh/coff.h sh/rtems.h rtems.h"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
+ tmake_file="sh/t-sh sh/t-elf t-rtems"
+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h sh/elf.h sh/embed-elf.h sh/rtemself.h rtems.h"
;;
sh-*-linux* | sh[2346lbe]*-*-linux*)
- tmake_file="sh/t-sh sh/t-elf"
- case $machine in
+ tmake_file="sh/t-sh sh/t-elf t-slibgcc-elf-ver t-linux"
+ case ${target} in
sh*be-*-* | sh*eb-*-*) ;;
*)
tm_file="sh/little.h ${tm_file}"
@@ -2315,8 +1926,7 @@ sh-*-linux* | sh[2346lbe]*-*-linux*)
esac
tmake_file="${tmake_file} sh/t-linux"
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sh/elf.h sh/linux.h"
- gas=yes gnu_ld=yes
- case $machine in
+ case ${target} in
sh64*)
tmake_file="${tmake_file} sh/t-sh64"
tm_file="${tm_file} sh/sh64.h"
@@ -2328,9 +1938,12 @@ sh-*-linux* | sh[2346lbe]*-*-linux*)
sh3e[lb]*) target_cpu_default="SELECT_SH3" ;;
sh3e*) target_cpu_default="SELECT_SH3E" ;;
sh3*) target_cpu_default="SELECT_SH3" ;;
+ sh2e[lb]e*) target_cpu_default="SELECT_SH2E" ;;
+ sh2e[lb]*) target_cpu_default="SELECT_SH2" ;;
+ sh2e*) target_cpu_default="SELECT_SH2E" ;;
sh2*) target_cpu_default="SELECT_SH2" ;;
esac
- case $machine in
+ case ${target} in
sh[234]*) tmake_file="${tmake_file} sh/t-monolib" ;;
esac
;;
@@ -2338,7 +1951,7 @@ sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \
sh64-*-netbsd* | sh64l*-*-netbsd*)
tm_file="${tm_file} dbxelf.h elfos.h sh/elf.h netbsd.h netbsd-elf.h sh/netbsd-elf.h"
tmake_file="${tmake_file} sh/t-sh sh/t-elf"
- case $machine in
+ case ${target} in
sh*l*-*)
tm_file="sh/little.h ${tm_file}"
tmake_file="${tmake_file} sh/t-le"
@@ -2347,10 +1960,10 @@ sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \
tmake_file="${tmake_file} sh/t-be"
;;
esac
- case $machine in
+ case ${target} in
sh5*-*)
# SHmedia, 32-bit ABI
- target_cpu_default="SH5_BIT|SH4_BIT|SH3E_BIT"
+ target_cpu_default="SH5_BIT|SH4_BIT|SH3_BIT|SH_E_BIT"
tmake_file="${tmake_file} sh/t-sh64 sh/t-netbsd-sh5"
;;
sh64*-*)
@@ -2365,103 +1978,48 @@ sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \
;;
esac
;;
+sh-wrs-vxworks)
+ tmake_file="$tmake_file sh/t-sh sh/t-elf sh/t-vxworks"
+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h sh/embed-elf.h sh/vxworks.h"
+ ;;
sh-*-*)
- tm_file="${tm_file} sh/coff.h"
+ tm_file="${tm_file} dbxcoff.h sh/coff.h"
+ use_fixproto=yes
;;
sparc-tti-*)
tm_file="${tm_file} sparc/pbd.h"
- xm_defines=POSIX
- ;;
-sparc64-wrs-vxworks*)
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/elf.h sparc/biarch64.h gofast.h sparc/vxsparc64.h"
- tmake_file="sparc/t-vxsparc64 sparc/t-crtfm"
- use_collect2=yes
- ;;
-sparc-wrs-vxworks* | sparclite-wrs-vxworks*)
- tm_file="${tm_file} aoutos.h sparc/aout.h gofast.h sparc/vxsparc.h"
- tmake_file=sparc/t-vxsparc
- use_collect2=yes
- thread_file='vxworks'
- ;;
-sparc-*-aout*)
- tmake_file=sparc/t-sparcbare
- tm_file="sparc/sparc.h aoutos.h sparc/aout.h libgloss.h"
+ use_fixproto=yes
;;
sparc-*-netbsdelf*)
tm_file="${tm_file} elfos.h svr4.h sparc/sysv4.h netbsd.h netbsd-elf.h sparc/netbsd-elf.h"
;;
-sparc-*-netbsd*)
- tm_file="${tm_file} sparc/aout.h netbsd.h netbsd-aout.h sparc/netbsd.h"
- tmake_file=t-netbsd
- extra_parts=""
- use_collect2=yes
- ;;
sparc-*-openbsd*)
- tm_file="sparc/sparc.h ${tm_file}"
+ tm_defines=OBSD_OLD_GAS
+ tm_file="sparc/sparc.h openbsd.h sparc/openbsd.h"
# needed to unconfuse gdb
tmake_file="t-libc-ok t-openbsd sparc/t-openbsd"
# we need collect2 until our bug is fixed...
use_collect2=yes
;;
sparc64-*-openbsd*)
- tm_file="sparc/openbsd1-64.h sparc/sparc.h elfos.h svr4.h sparc/sysv4.h sparc/sol2.h sparc/sp64-elf.h openbsd.h sparc/openbsd64.h"
- xm_file=sparc/xm-sp64.h
+ tm_file="sparc/openbsd1-64.h sparc/sparc.h elfos.h svr4.h sparc/sysv4.h sparc/sp64-elf.h openbsd.h sparc/openbsd64.h"
gas=yes gnu_ld=yes
with_cpu=ultrasparc
;;
-sparc-*-bsd*)
- tm_file="${tm_file} sparc/bsd.h"
- ;;
-sparc-*-chorusos*)
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/elf.h chorus.h"
- tmake_file="sparc/t-chorus-elf sparc/t-crtfm"
- extra_parts="crti.o crtn.o crtbegin.o crtend.o"
- case x${enable_threads} in
- xyes | xpthreads | xposix)
- thread_file='posix'
- ;;
- esac
- ;;
sparc-*-elf*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/elf.h"
tmake_file="sparc/t-elf sparc/t-crtfm"
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
- ;;
-sparc-*-linux*aout*) # SPARC's running GNU/Linux, a.out
- tm_file="aoutos.h sparc/sparc.h sparc/aout.h sparc/linux-aout.h"
- gnu_ld=yes
- ;;
-sparc-*-linux*libc1*) # SPARC's running GNU/Linux, libc5
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux.h"
- tmake_file="t-slibgcc-elf-ver t-linux t-linux-gnulibc1 sparc/t-crtfm"
- extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
- gnu_ld=yes
+ use_fixproto=yes
;;
sparc-*-linux*) # SPARC's running GNU/Linux, libc6
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/linux.h"
tmake_file="t-slibgcc-elf-ver t-linux sparc/t-crtfm"
;;
-sparc-*-lynxos*)
- if test x$gas = xyes
- then
- tm_file="${tm_file} lynx.h sparc/aout.h sparc/lynx.h"
- else
- tm_file="${tm_file} lynx-ng.h sparc/aout.h sparc/lynx-ng.h"
- fi
- tmake_file=sparc/t-sunos41
- ;;
-sparc-*-rtemsaout*) # would otherwise be caught by sparc-*-rtems*
- echo "*** Configuration $machine not supported" 1>&2
- exit 1
- ;;
sparc-*-rtems*)
- xm_defines=POSIX
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/elf.h sparc/rtemself.h rtems.h"
tmake_file="sparc/t-elf sparc/t-crtfm t-rtems"
extra_parts="crti.o crtn.o crtbegin.o crtend.o"
- if test x$enable_threads = xyes; then
- thread_file='rtems'
- fi
;;
sparc64-*-solaris2* | sparcv9-*-solaris2*)
tm_file="sparc/biarch64.h ${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/sol2-64.h sparc/sol2-bi.h"
@@ -2471,7 +2029,6 @@ sparc64-*-solaris2* | sparcv9-*-solaris2*)
if test x$gas = xyes; then
tm_file="${tm_file} sparc/sol2-gas-bi.h"
fi
- xm_defines=POSIX
tmake_file="sparc/t-sol2 sparc/t-sol2-64 sparc/t-crtfm"
if test x$gnu_ld = xyes; then
tmake_file="$tmake_file t-slibgcc-elf-ver"
@@ -2492,20 +2049,8 @@ sparc64-*-solaris2* | sparcv9-*-solaris2*)
thread_file='solaris'
fi
fi
+ need_64bit_hwint=yes
;;
-sparc-hal-solaris2*)
- xm_defines=POSIX
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/hal.h"
- tmake_file="sparc/t-halos sparc/t-sol2 sparc/t-crtfm"
- if test x$gnu_ld = xyes; then
- tm_file="${tm_file} sparc/sol2-gld.h"
- tmake_file="$tmake_file t-slibgcc-elf-ver"
- else
- tmake_file="$tmake_file t-slibgcc-sld"
- fi
- extra_parts="crt1.o crti.o crtn.o gmon.o crtbegin.o crtend.o"
- thread_file='solaris'
- ;;
sparc-*-solaris2*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h"
if test x$gnu_ld = xyes; then
@@ -2517,7 +2062,7 @@ sparc-*-solaris2*)
else
tmake_file="$tmake_file t-slibgcc-sld"
fi
- case $machine in
+ case ${target} in
*-*-solaris2.[0-6] | *-*-solaris2.[0-6].*)
if test x$gnu_ld = xno; then
tm_file="${tm_file} sparc/sol26-sld.h"
@@ -2532,9 +2077,9 @@ sparc-*-solaris2*)
tm_file="${tm_file} sparc/sol2-gas-bi.h"
fi
tmake_file="$tmake_file sparc/t-sol2-64"
+ need_64bit_hwint=yes
;;
esac
- xm_defines=POSIX
extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o"
if test x${enable_threads} = x; then
enable_threads=$have_pthread_h
@@ -2550,76 +2095,47 @@ sparc-*-solaris2*)
fi
fi
;;
-sparc-*-sunos4.0*)
- tm_file="${tm_file} sparc/aout.h sparc/sunos4.h"
- use_collect2=yes
- ;;
-sparc-*-sunos4*)
- tm_file="${tm_file} sparc/aout.h sparc/sunos4.h"
- tmake_file=sparc/t-sunos41
- use_collect2=yes
- if test x$gas = xyes; then
- tm_file="${tm_file} sparc/sun4gas.h"
- fi
- ;;
-sparc-*-sunos3*)
- tm_file="${tm_file} sparc/aout.h sparc/sun4o3.h"
- use_collect2=yes
- ;;
sparc-*-sysv4*)
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h"
- xm_defines=POSIX
+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/sysv4-only.h"
tmake_file=t-svr4
extra_parts="crtbegin.o crtend.o"
- ;;
-sparc-*-vxsim*)
- xm_defines=POSIX
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sparc/vxsim.h"
- tmake_file=sparc/t-vxsparc
- ;;
-sparclet-*-aout*)
- tm_file="${tm_file} aoutos.h sparc/aout.h sparc/splet.h libgloss.h"
- tmake_file=sparc/t-splet
+ use_fixproto=yes
;;
sparclite-*-coff*)
- tm_file="${tm_file} gofast.h sparc/lite.h svr3.h sparc/litecoff.h dbxcoff.h libgloss.h"
- tmake_file=sparc/t-sparclite
- ;;
-sparclite-*-aout*)
- tm_file="${tm_file} gofast.h sparc/aout.h sparc/lite.h aoutos.h libgloss.h"
+ tm_file="${tm_file} sparc/lite.h svr3.h sparc/litecoff.h dbxcoff.h libgloss.h"
tmake_file=sparc/t-sparclite
;;
sparclite-*-elf*)
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/elf.h gofast.h sparc/liteelf.h"
+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/elf.h sparc/liteelf.h"
tmake_file="sparc/t-sparclite sparc/t-crtfm"
extra_parts="crtbegin.o crtend.o"
- ;;
-sparc86x-*-aout*)
- tm_file="${tm_file} gofast.h sparc/aout.h sparc/sp86x-aout.h aoutos.h libgloss.h"
- tmake_file=sparc/t-sp86x
+ use_fixproto=yes
;;
sparc86x-*-elf*)
- tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/elf.h gofast.h sparc/sp86x-elf.h"
+ tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/elf.h sparc/sp86x-elf.h"
tmake_file="sparc/t-sp86x sparc/t-crtfm"
extra_parts="crtbegin.o crtend.o"
+ use_fixproto=yes
;;
sparc64-*-aout*)
- tm_file="sparc/sparc.h aoutos.h sparc/aout.h sparc/sp64-aout.h"
+ tm_file="sparc/sparc.h sparc/aout.h sparc/sp64-aout.h"
+ use_fixproto=yes
;;
sparc64-*-elf*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h sparc/sysv4.h sol2.h sparc/sol2.h sparc/sp64-elf.h"
tmake_file="${tmake_file} sparc/t-crtfm"
extra_parts="crtbegin.o crtend.o"
+ use_fixproto=yes
;;
sparc64-*-freebsd*|ultrasparc-*-freebsd*)
tm_file="${tm_file} ${fbsd_tm_file} dbxelf.h elfos.h sparc/sysv4.h sparc/freebsd.h"
tmake_file="${tmake_file} sparc/t-crtfm"
- xmake_file=none
case "x$with_cpu" in
xultrasparc) ;;
x) with_cpu=ultrasparc ;;
*) echo "$with_cpu not supported for freebsd target"; exit 1 ;;
esac
+ need_64bit_hwint=yes
;;
sparc64-*-linux*) # 64-bit SPARC's running GNU/Linux
tmake_file="t-slibgcc-elf-ver t-linux sparc/t-linux64 sparc/t-crtfm"
@@ -2636,32 +2152,31 @@ strongarm-*-elf*)
out_file=arm/arm.c
md_file=arm/arm.md
extra_modes=arm/arm-modes.def
- ;;
-strongarm-*-coff*)
- tm_file="arm/semi.h arm/aout.h arm/coff.h arm/strongarm-coff.h arm/arm.h"
- tmake_file=arm/t-strongarm-coff
- out_file=arm/arm.c
- md_file=arm/arm.md
- extra_modes=arm/arm-modes.def
+ use_fixproto=yes
;;
strongarm-*-pe)
- tm_file="arm/semi.h arm/aout.h arm/coff.h arm/strongarm-coff.h arm/arm.h arm/pe.h arm/strongarm-pe.h"
+ tm_file="arm/semi.h arm/aout.h arm/coff.h dbxcoff.h arm/strongarm-coff.h arm/arm.h arm/pe.h arm/strongarm-pe.h"
tmake_file=arm/t-strongarm-pe
out_file=arm/arm.c
md_file=arm/arm.md
extra_modes=arm/arm-modes.def
extra_objs=pe.o
+ use_fixproto=yes
;;
-thumb*-*-*)
- { echo "config.gcc: error:
-*** The Thumb targets have been deprecated. The equivalent
-*** ARM based toolchain can now generate Thumb instructions
-*** when the -mthumb switch is given to the compiler." 1>&2; exit 1; }
+strongarm-*-kaos*)
+ tm_file="arm/strongarm-elf.h dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h kaos.h arm/kaos-strongarm.h"
+ tmake_file=arm/t-strongarm-elf
+ out_file=arm/arm.c
+ md_file=arm/arm.md
+ extra_modes=arm/arm-modes.def
;;
-v850-*-rtems*)
- xm_defines=POSIX
- tm_file="dbxelf.h elfos.h svr4.h ${tm_file} v850/v850.h v850/rtems.h rtems.h"
- tmake_file="v850/t-v850 t-rtems"
+v850e1-*-*)
+ target_cpu_default="TARGET_CPU_v850e1"
+ tm_file="dbxelf.h elfos.h svr4.h v850/v850.h"
+ tm_p_file=v850/v850-protos.h
+ tmake_file=v850/t-v850e
+ md_file=v850/v850.md
+ out_file=v850/v850.c
if test x$stabs = xyes
then
tm_file="${tm_file} dbx.h"
@@ -2669,12 +2184,13 @@ v850-*-rtems*)
use_collect2=no
c_target_objs="v850-c.o"
cxx_target_objs="v850-c.o"
+ use_fixproto=yes
;;
v850e-*-*)
target_cpu_default="TARGET_CPU_v850e"
tm_file="dbxelf.h elfos.h svr4.h v850/v850.h"
tm_p_file=v850/v850-protos.h
- tmake_file=v850/t-v850
+ tmake_file=v850/t-v850e
md_file=v850/v850.md
out_file=v850/v850.c
if test x$stabs = xyes
@@ -2684,6 +2200,7 @@ v850e-*-*)
use_collect2=no
c_target_objs="v850-c.o"
cxx_target_objs="v850-c.o"
+ use_fixproto=yes
;;
v850-*-*)
target_cpu_default="TARGET_CPU_generic"
@@ -2696,18 +2213,19 @@ v850-*-*)
use_collect2=no
c_target_objs="v850-c.o"
cxx_target_objs="v850-c.o"
+ use_fixproto=yes
;;
vax-*-bsd*) # VAXen running BSD
tm_file="${tm_file} vax/bsd.h"
use_collect2=yes
+ use_fixproto=yes
;;
vax-*-sysv*) # VAXen running system V
tm_file="${tm_file} vax/vaxv.h"
- xm_defines=POSIX
+ use_fixproto=yes
;;
vax-*-netbsdelf*)
tm_file="${tm_file} elfos.h netbsd.h netbsd-elf.h vax/elf.h vax/netbsd-elf.h"
- float_format=vax
;;
vax-*-netbsd*)
tm_file="${tm_file} netbsd.h netbsd-aout.h vax/netbsd.h"
@@ -2716,17 +2234,22 @@ vax-*-netbsd*)
use_collect2=yes
;;
vax-*-openbsd*)
- tm_file="vax/vax.h vax/openbsd1.h openbsd.h ${tm_file}"
+ tm_file="vax/vax.h vax/openbsd1.h openbsd.h vax/openbsd.h"
use_collect2=yes
;;
vax-*-ultrix*) # VAXen running ultrix
tm_file="${tm_file} vax/ultrix.h"
- ;;
-vax-*-vms*) # VAXen running VMS
- xm_file=vax/xm-vms.h
- tm_file=vax/vms.h
+ use_fixproto=yes
;;
vax-*-*) # VAX default entry
+ if test "x$enable_obsolete" != xyes; then
+ echo "*** Configuration ${target} is obsolete." >&2
+ echo "*** Specify --enable-obsolete to build it anyway." >&2
+ echo "*** Support will be REMOVED in the next major release of GCC," >&2
+ echo "*** unless a maintainer comes forward." >&2
+ exit 1
+ fi
+ use_fixproto=yes
;;
xscale-*-elf)
tm_file="arm/xscale-elf.h dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/aout.h arm/arm.h"
@@ -2734,13 +2257,15 @@ xscale-*-elf)
out_file=arm/arm.c
md_file=arm/arm.md
extra_modes=arm/arm-modes.def
+ use_fixproto=yes
;;
xscale-*-coff)
- tm_file="arm/semi.h arm/aout.h arm/coff.h arm/xscale-coff.h arm/arm.h"
+ tm_file="arm/semi.h arm/aout.h arm/coff.h dbxcoff.h arm/xscale-coff.h arm/arm.h"
tmake_file=arm/t-xscale-coff
out_file=arm/arm.c
md_file=arm/arm.md
extra_modes=arm/arm-modes.def
+ use_fixproto=yes
;;
xstormy16-*-elf)
# For historical reasons, the target files omit the 'x'.
@@ -2750,301 +2275,540 @@ xstormy16-*-elf)
out_file=stormy16/stormy16.c
tmake_file="stormy16/t-stormy16"
extra_parts="crtbegin.o crtend.o"
+ use_fixproto=yes
;;
xtensa-*-elf*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h xtensa/elf.h"
- with_newlib=yes
- tmake_file=xtensa/t-xtensa
- extra_parts="crtbegin.o crtend.o"
- fixincludes=Makefile.in # newlib headers should be OK
+ tmake_file="xtensa/t-xtensa xtensa/t-elf"
;;
xtensa-*-linux*)
tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h xtensa/linux.h"
- tmake_file="t-slibgcc-elf-ver t-linux xtensa/t-xtensa"
+ tmake_file="t-slibgcc-elf-ver t-linux xtensa/t-xtensa xtensa/t-linux"
+ ;;
+am33_2.0-*-linux*)
+ tm_file="mn10300/mn10300.h dbxelf.h elfos.h linux.h mn10300/linux.h"
+ tmake_file="t-slibgcc-elf-ver t-linux mn10300/t-linux"
+ gas=yes gnu_ld=yes
+ extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o"
+ use_collect2=no
;;
*)
- echo "*** Configuration $machine not supported" 1>&2
+ echo "*** Configuration ${target} not supported" 1>&2
exit 1
;;
esac
-case $machine in
-*-*-sysv*)
- install_headers_dir=install-headers-cpio
- ;;
+# Support for --with-cpu and related options (and a few unrelated options,
+# too).
+case ${with_cpu} in
+ yes | no)
+ echo "--with-cpu must be passed a value" 1>&2
+ exit 1
+ ;;
esac
-# Distinguish i[34567]86
-# Also, do not run mips-tfile on MIPS if using gas.
-# Process --with-cpu= for PowerPC/rs6000
-target_cpu_default2=
-case $machine in
-i486-*-*)
- target_cpu_default2=TARGET_CPU_DEFAULT_i486
- ;;
-i586-*-*)
- case $target_alias in
- k6_2-*)
- target_cpu_default2=TARGET_CPU_DEFAULT_k6_2
+# If there is no $with_cpu option, try to infer one from ${target}.
+# This block sets nothing except for with_cpu.
+if test x$with_cpu = x ; then
+ case ${target} in
+ ep9312-*-*)
+ # A Cirrus ARM variant.
+ with_cpu="ep9312"
+ ;;
+ i486-*-*)
+ with_cpu=i486
+ ;;
+ i586-*-*)
+ case ${target_noncanonical} in
+ k6_2-*)
+ with_cpu=k6-2
+ ;;
+ k6_3-*)
+ with_cpu=k6-3
+ ;;
+ k6-*)
+ with_cpu=k6
+ ;;
+ pentium_mmx-*|winchip_c6-*|winchip2-*|c3-*)
+ with_cpu=pentium-mmx
+ ;;
+ *)
+ with_cpu=pentium
+ ;;
+ esac
+ ;;
+ i686-*-* | i786-*-*)
+ case ${target_noncanonical} in
+ k8-*|opteron-*|athlon_64-*)
+ with_cpu=k8
+ ;;
+ athlon_xp-*|athlon_mp-*|athlon_4-*)
+ with_cpu=athlon-4
+ ;;
+ athlon_tbird-*|athlon-*)
+ with_cpu=athlon
+ ;;
+ pentium2-*)
+ with_cpu=pentium2
+ ;;
+ pentium3-*|pentium3m-*)
+ with_cpu=pentium3
+ ;;
+ pentium4-*|pentium4m-*)
+ with_cpu=pentium4
+ ;;
+ prescott-*)
+ with_cpu=prescott
+ ;;
+ nocona-*)
+ with_cpu=nocona
+ ;;
+ pentium_m-*)
+ with_cpu=pentium-m
+ ;;
+ *)
+ with_cpu=pentiumpro
+ ;;
+ esac
+ ;;
+ x86_64-*-*)
+ with_cpu=k8
+ ;;
+ alphaev6[78]*-*-*)
+ with_cpu=ev67
+ ;;
+ alphaev6*-*-*)
+ with_cpu=ev6
+ ;;
+ alphapca56*-*-*)
+ with_cpu=pca56
+ ;;
+ alphaev56*-*-*)
+ with_cpu=ev56
+ ;;
+ alphaev5*-*-*)
+ with_cpu=ev5
+ ;;
+ sparc*-*-*)
+ with_cpu="`echo ${target} | sed 's/-.*$//'`"
+ if [ x$with_cpu = xsparc64 ]; then
+ with_cpu=v9
+ fi
+ ;;
+ esac
+fi
+
+ # Similarly for --with-schedule.
+ if test x$with_schedule = x; then
+ case ${target} in
+ hppa1* | parisc1*)
+ # Override default PA8000 scheduling model.
+ with_schedule=7100LC
;;
- k6_3-*)
- target_cpu_default2=TARGET_CPU_DEFAULT_k6_3
+ esac
+ fi
+
+ # Validate and mark as valid any --with options supported
+ # by this target. In order to use a particular --with option
+ # you must list it in supported_defaults; validating the value
+ # is optional. This case statement should set nothing besides
+ # supported_defaults.
+
+ supported_defaults=
+ case "${target}" in
+ alpha*-*-*)
+ supported_defaults="cpu tune"
+ for which in cpu tune; do
+ eval "val=\$with_$which"
+ case "$val" in
+ "" \
+ | ev4 | ev45 | 21064 | ev5 | 21164 | ev56 | 21164a \
+ | pca56 | 21164PC | 21164pc | ev6 | 21264 | ev67 \
+ | 21264a)
+ ;;
+ *)
+ echo "Unknown CPU used in --with-$which=$val" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+
+ arm*-*-*)
+ supported_defaults="arch cpu float tune"
+ for which in cpu tune; do
+ eval "val=\$with_$which"
+ case "$val" in
+ "" \
+ | arm[236789] | arm250 | arm[67][01]0 \
+ | arm60 | arm620 | arm7d | arm7di \
+ | arm7m | arm7dm | arm7dmi | arm[79]tdmi \
+ | arm70 | arm700i | arm710t | arm720 \
+ | arm720t | arm740t | arm710c | arm920 \
+ | arm920t | arm926ejs | arm940t | arm9e | arm10tdmi \
+ | arm7100 | arm7500 | arm7500fe | arm810 \
+ | arm1026ejs | arm1020t | arm1136js | arm1136jfs \
+ | xscale | iwmmxt \
+ | ep9312 \
+ | strongarm | strongarm110 | strongarm11[01]0)
+ # OK
+ ;;
+ *)
+ echo "Unknown CPU used in --with-$which=$val" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ case "$with_arch" in
+ "" \
+ | armv[2345] | armv2a | armv3m | armv4t | armv5t \
+ | armv5te | armv6j | ep9312)
+ # OK
;;
- k6-*)
- target_cpu_default2=TARGET_CPU_DEFAULT_k6
+ *)
+ echo "Unknown arch used in --with-arch=$with_arch" 1>&2
+ exit 1
;;
- pentium_mmx-*|winchip_c6-*|winchip2-*|c3-*)
- target_cpu_default2=TARGET_CPU_DEFAULT_pentium_mmx
+ esac
+
+ case "$with_float" in
+ "" \
+ | soft | hard)
+ # OK
;;
*)
- target_cpu_default2=TARGET_CPU_DEFAULT_pentium
+ echo "Unknown floating point type used in --with-float=$with_float" 1>&2
+ exit 1
;;
- esac
- ;;
-i686-*-* | i786-*-*)
- case $target_alias in
- athlon_xp-*|athlon_mp-*|athlon_4-*)
- target_cpu_default2=TARGET_CPU_DEFAULT_athlon_sse
+ esac
+
+ if test "x$with_arch" != x && test "x$with_cpu" != x; then
+ echo "Warning: --with-arch overrides --with-cpu" 1>&2
+ fi
+ ;;
+
+ hppa*-*-* | parisc*-*-*)
+ supported_defaults="arch schedule"
+
+ case "$with_arch" in
+ "" | 1.0 | 1.1 | 2.0)
+ # OK
;;
- athlon_tbird-*|athlon-*)
- target_cpu_default2=TARGET_CPU_DEFAULT_athlon
+ *)
+ echo "Unknown architecture used in --with-arch=$with_arch" 1>&2
+ exit 1
;;
- pentium2-*)
- target_cpu_default2=TARGET_CPU_DEFAULT_pentium2
+ esac
+
+ case "$with_schedule" in
+ "" | 700 | 7100 | 7100LC | 7200 | 7300 | 8000)
+ # OK
;;
- pentium3-*)
- target_cpu_default2=TARGET_CPU_DEFAULT_pentium3
+ *)
+ echo "Unknown processor used in --with-schedule=$with_schedule." 1>&2
+ exit 1
;;
- pentium4-*)
- target_cpu_default2=TARGET_CPU_DEFAULT_pentium4
+ esac
+ ;;
+
+ i[34567]86-*-* | x86_64-*-*)
+ supported_defaults="arch cpu tune"
+ for which in arch cpu tune; do
+ eval "val=\$with_$which"
+ case ${val} in
+ "" | i386 | i486 \
+ | i586 | pentium | pentium-mmx | winchip-c6 | winchip2 \
+ | c3 | c3-2 | i686 | pentiumpro | pentium2 | pentium3 \
+ | pentium4 | k6 | k6-2 | k6-3 | athlon | athlon-tbird \
+ | athlon-4 | athlon-xp | athlon-mp | k8 | opteron \
+ | athlon64 | athlon-fx | prescott | pentium-m \
+ | pentium4m | pentium3m| nocona)
+ # OK
+ ;;
+ *)
+ echo "Unknown CPU given in --with-$which=$val." 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+
+ mips*-*-*)
+ supported_defaults="abi arch float tune"
+
+ case ${with_float} in
+ "" | soft | hard)
+ # OK
;;
*)
- target_cpu_default2=TARGET_CPU_DEFAULT_pentiumpro
+ echo "Unknown floating point type used in --with-float=$with_float" 1>&2
+ exit 1
;;
- esac
- ;;
-x86_64-*-*)
- # We should have hammer chip here, but it does not exist yet and
- # thus it is not supported. Athlon_SSE is probably equivalent feature
- # wise to hammer from our point of view except for 64bit mode.
- target_cpu_default2=TARGET_CPU_DEFAULT_athlon_sse
- ;;
-alpha*-*-*)
- case $machine in
- alphaev6[78]*)
- target_cpu_default2="MASK_CPU_EV6|MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX"
+ esac
+
+ case ${with_abi} in
+ "" | 32 | o64 | n32 | 64 | eabi)
+ # OK
;;
- alphaev6*)
- target_cpu_default2="MASK_CPU_EV6|MASK_BWX|MASK_MAX|MASK_FIX"
+ *)
+ echo "Unknown ABI used in --with-abi=$with_abi" 1>&2
+ exit 1
;;
- alphapca56*)
- target_cpu_default2="MASK_CPU_EV5|MASK_BWX|MASK_MAX"
+ esac
+ ;;
+
+ powerpc*-*-* | rs6000-*-*)
+ supported_defaults="cpu float tune"
+
+ for which in cpu tune; do
+ eval "val=\$with_$which"
+ case ${val} in
+ default32 | default64)
+ with_which="with_$which"
+ eval $with_which=
+ ;;
+ "" | common \
+ | power | power2 | power3 | power4 \
+ | powerpc | powerpc64 \
+ | rios | rios1 | rios2 | rsc | rsc1 | rs64a \
+ | 401 | 403 | 405 | 405fp | 440 | 440fp | 505 \
+ | 601 | 602 | 603 | 603e | ec603e | 604 \
+ | 604e | 620 | 630 | 740 | 750 | 7400 | 7450 \
+ | 8540 | 801 | 821 | 823 | 860 | 970 | G3 | G4 | G5)
+ # OK
+ ;;
+ *)
+ echo "Unknown cpu used in --with-$which=$val." 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+
+ s390*-*-*)
+ supported_defaults="arch mode tune"
+
+ for which in arch tune; do
+ eval "val=\$with_$which"
+ case ${val} in
+ "" | g5 | g6 | z900 | z990)
+ # OK
+ ;;
+ *)
+ echo "Unknown cpu used in --with-$which=$val." 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ case ${with_mode} in
+ "" | esa | zarch)
+ # OK
;;
- alphaev56*)
- target_cpu_default2="MASK_CPU_EV5|MASK_BWX"
+ *)
+ echo "Unknown architecture mode used in --with-mode=$with_mode." 1>&2
+ exit 1
;;
- alphaev5*)
- target_cpu_default2="MASK_CPU_EV5"
+ esac
+ ;;
+
+ sparc*-*-*)
+ supported_defaults="cpu float tune"
+
+ for which in cpu tune; do
+ eval "val=\$with_$which"
+ case ${val} in
+ "" | sparc | sparcv9 | sparc64 | sparc86x \
+ | v7 | cypress | v8 | supersparc | sparclite | f930 \
+ | f934 | hypersparc | sparclite86x | sparclet | tsc701 \
+ | v9 | ultrasparc | ultrasparc3)
+ # OK
+ ;;
+ *)
+ echo "Unknown cpu used in --with-$which=$val" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+
+ case ${with_float} in
+ "" | soft | hard)
+ # OK
;;
+ *)
+ echo "Unknown floating point type used in --with-float=$with_float" 1>&2
+ exit 1
+ ;;
+ esac
+ ;;
+
+ v850*-*-*)
+ supported_defaults=cpu
+ case ${with_cpu} in
+ "" | v850e | v850e1)
+ # OK
+ ;;
+ *)
+ echo "Unknown cpu used in --with-cpu=$with_cpu" 1>&2
+ exit 1
+ ;;
+ esac
+ ;;
esac
- if test x$gas = xyes
- then
- if test "$target_cpu_default2" = ""
+ # Set some miscellaneous flags for particular targets.
+ target_cpu_default2=
+ case ${target} in
+ alpha*-*-*)
+ if test x$gas = xyes
then
target_cpu_default2="MASK_GAS"
- else
- target_cpu_default2="${target_cpu_default2}|MASK_GAS"
fi
- fi
- ;;
-arm*-*-*)
- case "x$with_cpu" in
+ ;;
+
+ arm*-*-*)
+ case "x$with_cpu" in
x)
# The most generic
target_cpu_default2="TARGET_CPU_generic"
;;
- # Distinguish cores, and major variants
- # arm7m doesn't exist, but D & I don't affect code
- xarm[236789] | xarm250 | xarm[67][01]0 \
- | xarm7m | xarm7dm | xarm7dmi | xarm[79]tdmi \
- | xarm7100 | xarm7500 | xarm7500fe | xarm810 \
- | xxscale \
- | xstrongarm | xstrongarm110 | xstrongarm1100)
+ *)
target_cpu_default2="TARGET_CPU_$with_cpu"
;;
+ esac
+ ;;
- xyes | xno)
- echo "--with-cpu must be passed a value" 1>&2
- exit 1
- ;;
+ hppa*-*-* | parisc*-*-*)
+ if test x$gas = xyes
+ then
+ target_cpu_default2="MASK_GAS|MASK_JUMP_IN_DELAY"
+ fi
+ ;;
- *)
- if test x$pass2done = xyes
+ mips*-*-*)
+ case ${target} in
+ mips*-*-ecoff* | mips*-*-elf*)
+ if test x$gas = xyes
then
- echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2
- exit 1
+ if test x$gnu_ld = xyes
+ then
+ target_cpu_default2="MASK_GAS|MASK_SPLIT_ADDR"
+ else
+ target_cpu_default2="MASK_GAS"
+ fi
fi
;;
- esac
- ;;
-
-hppa*-*-* | parisc*-*-*)
- if test x$gas = xyes
- then
- target_cpu_default2="MASK_GAS|MASK_JUMP_IN_DELAY"
- fi
- case $machine in
- hppa1* | parisc1*)
- tm_defines="TARGET_SCHED_DEFAULT=\\\"7100LC\\\""
- ;;
- esac
- ;;
-mips*-*-*)
- case $machine in
- mips*-*-ecoff* | mips*-*-elf*)
- if test x$gas = xyes
- then
- if test x$gnu_ld = xyes
+ mips*-*-*)
+ if test x$gas = xyes
then
- target_cpu_default2="MASK_GAS|MASK_SPLIT_ADDR"
- else
target_cpu_default2="MASK_GAS"
fi
+ ;;
+ esac
+ case ${target} in
+ mips*el-*-*)
+ tm_defines="TARGET_ENDIAN_DEFAULT=0 $tm_defines"
+ ;;
+ esac
+ case $tm_file in
+ *mips/elf.h* | *mips/elf64.h*)
+ tm_defines="OBJECT_FORMAT_ELF $tm_defines"
+ ;;
+ esac
+ if test "x$enable_gofast" = xyes
+ then
+ tm_defines="US_SOFTWARE_GOFAST $tm_defines"
+ tmake_file="mips/t-gofast $tmake_file"
+ else
+ tmake_file="mips/t-mips $tmake_file"
fi
;;
- mips*-*-*)
- if test x$gas = xyes
+
+ powerpc*-*-* | rs6000-*-*)
+ if test x$enable_altivec = xyes
then
- target_cpu_default2="MASK_GAS"
+ tm_file="$tm_file rs6000/altivec-defs.h"
fi
+ # FIXME: The PowerPC port uses the value set at compile time,
+ # although it's only cosmetic.
+ if test "x$with_cpu" != x
+ then
+ target_cpu_default2="\\\"$with_cpu\\\""
+ fi
+ out_file=rs6000/rs6000.c
+ c_target_objs="${c_target_objs} rs6000-c.o"
+ cxx_target_objs="${cxx_target_objs} rs6000-c.o"
+ tmake_file="rs6000/t-rs6000 ${tmake_file}"
;;
- esac
- case $machine in
- mips*el-*-*)
- tm_defines="TARGET_ENDIAN_DEFAULT=0 $tm_defines"
- ;;
- esac
- case $tm_file in
- *mips/elf.h* | *mips/elf64.h*)
- tm_defines="OBJECT_FORMAT_ELF $tm_defines"
- ;;
- esac
- if test "x$enable_gofast" = xyes
- then
- tm_defines="INIT_SUBTARGET_OPTABS=INIT_GOFAST_OPTABS $tm_defines"
- tm_file="gofast.h $tm_file"
- tmake_file="mips/t-gofast $tmake_file"
- else
- tmake_file="mips/t-mips $tmake_file"
- fi
- ;;
-powerpc*-*-* | rs6000-*-*)
- if test x$enable_altivec = xyes
- then
- tm_file="$tm_file rs6000/altivec-defs.h"
- fi
- case "x$with_cpu" in
- x)
- ;;
- xcommon | xpower | xpower2 | xpower3 | xpowerpc | xpowerpc64 \
- | xrios | xrios1 | xrios2 | xrsc | xrsc1 | xrs64a \
- | x601 | x602 | x603 | x603e | x604 | x604e | x620 | x630 \
- | x740 | x750 | x7400 | x7450 | x505)
- target_cpu_default2="\\\"$with_cpu\\\""
+ sparc*-*-*)
+ # Some standard aliases.
+ case x$with_cpu in
+ xsparc)
+ with_cpu=v7
;;
-
- x401 | x403 | x405 | xec603e | x801 | x821 | x823 | x860)
- target_cpu_default2="\\\"$with_cpu\\\""
+ xsparc86x)
+ with_cpu=sparclite86x
;;
-
- xyes | xno)
- echo "--with-cpu must be passed a value" 1>&2
- exit 1
+ xsparcv9 | xsparc64)
+ with_cpu=v9
;;
+ esac
- *)
- if test x$pass2done = xyes
- then
- echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2
- exit 1
- fi
- ;;
- esac
- c_target_objs="${c_target_objs} rs6000-c.o"
- cxx_target_objs="${cxx_target_objs} rs6000-c.o"
- tmake_file="${tmake_file} rs6000/t-rs6000-c-rule"
- ;;
-sparc*-*-*)
- case ".$with_cpu" in
- .)
- target_cpu_default2=TARGET_CPU_"`echo $machine | sed 's/-.*$//'`"
- ;;
- .supersparc | .hypersparc | .ultrasparc | .v7 | .v8 | .v9)
- target_cpu_default2="TARGET_CPU_$with_cpu"
- ;;
- *)
- if test x$pass2done = xyes
- then
- echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2
- exit 1
- fi
- ;;
- esac
- ;;
-v850*-*-*)
- case "x$with_cpu" in
+ # The Sparc port checks this value at compile-time.
+ target_cpu_default2="TARGET_CPU_$with_cpu"
+ ;;
+ v850*-*-*)
+ # FIXME: The v850 is "special" in that it does not support
+ # runtime CPU selection, only --with-cpu.
+ case "x$with_cpu" in
x)
;;
xv850e)
target_cpu_default2="TARGET_CPU_$with_cpu"
;;
- *)
- if test x$pass2done = xyes
- then
- echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2
- exit 1
- fi
- ;;
+ esac
+ ;;
esac
- ;;
-esac
-if test "$target_cpu_default2" != ""
-then
- if test "$target_cpu_default" != ""
+ t=
+ all_defaults="abi cpu arch tune schedule float mode"
+ for option in $all_defaults
+ do
+ eval "val=\$with_$option"
+ if test -n "$val"; then
+ case " $supported_defaults " in
+ *" $option "*)
+ ;;
+ *)
+ echo "This target does not support --with-$option." 2>&1
+ exit 1
+ ;;
+ esac
+
+ if test "x$t" = x
+ then
+ t="{ \"$option\", \"$val\" }"
+ else
+ t="${t}, { \"$option\", \"$val\" }"
+ fi
+ fi
+ done
+ if test "x$t" = x
then
- target_cpu_default="(${target_cpu_default}|${target_cpu_default2})"
+ configure_default_options="{ { NULL, NULL} }"
else
- target_cpu_default=$target_cpu_default2
+ configure_default_options="{ ${t} }"
fi
-fi
-# Save data on machine being used to compile GCC in build_xm_file.
-# Save data on host machine in vars host_xm_file and host_xmake_file.
-if test x$pass1done = x
-then
- if test x$xm_file != x
- then build_xm_file=$xm_file
- fi
- build_xm_defines=$xm_defines
- build_install_headers_dir=$install_headers_dir
- build_exeext=$exeext
- pass1done=yes
-else
- if test x$pass2done = x
+ if test "$target_cpu_default2" != ""
then
- if test x$xm_file != x
- then host_xm_file=$xm_file
+ if test "$target_cpu_default" != ""
+ then
+ target_cpu_default="(${target_cpu_default}|${target_cpu_default2})"
+ else
+ target_cpu_default=$target_cpu_default2
fi
- host_xm_defines=$xm_defines
- host_xmake_file="$xmake_file"
- host_truncate_target=$truncate_target
- host_extra_gcc_objs=$extra_gcc_objs
- host_extra_objs=$extra_host_objs
- host_exeext=$exeext
- pass2done=yes
fi
-fi
diff --git a/contrib/gcc/config.host b/contrib/gcc/config.host
new file mode 100644
index 000000000000..fa6bced73dbe
--- /dev/null
+++ b/contrib/gcc/config.host
@@ -0,0 +1,155 @@
+# GCC host-specific configuration file.
+# Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# 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 2, 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 COPYING. If not, write to the Free
+#Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+#02111-1307, USA.
+
+# This is the GCC host-specific configuration file
+# where a configuration type is mapped to different system-specific
+# definitions and files. This is invoked by the autoconf-generated
+# configure script. Putting it in a separate shell file lets us skip
+# running autoconf when modifying host-specific information.
+
+# This file switches on the shell variable ${host}. As much of this as
+# is reasonable should be replaced with autoconf tests in the future.
+
+# This file sets the following shell variables for use by the
+# autoconf-generated configure script:
+#
+# host_xm_file List of files to include when compiling for the
+# host machine.
+#
+# host_xm_defines List of macros to define when compiling for the
+# host machine.
+#
+# host_xmake_file List of host-specific makefile-fragments.
+#
+# host_exeext Set to the suffix, if the host machine requires
+# executables to have a file name suffix.
+#
+# host_extra_objs List of extra host-dependent objects that should
+# be linked into the compiler proper.
+#
+# host_extra_gcc_objs List of extra host-dependent objects that should
+# be linked into the gcc driver.
+#
+# out_host_hook_obj An object file that provides the host hooks.
+
+# When setting any of these variables, check to see if a corresponding
+# variable is present in config.build; if so, you will likely want to
+# set it in both places.
+
+# Default settings.
+host_xm_file=
+host_xm_defines=
+host_xmake_file=
+host_exeext=
+host_extra_objs=
+host_extra_gcc_objs=
+out_host_hook_obj=host-default.o
+
+# Unsupported hosts list. Generally, only include hosts known to fail here,
+# since we allow hosts not listed to be supported generically.
+case ${host} in
+ i[34567]86-sequent-sysv \
+ | i[34567]86-sequent-sysv[123]* \
+ | i[34567]86-go32-* \
+ | i[34567]86-*-go32* \
+ | vax-*-vms*)
+ echo "*** Configuration for host ${host} not supported" 1>&2
+ exit 1
+ ;;
+esac
+
+# Machine-specific settings.
+case ${host} in
+ alpha*-dec-*vms*)
+ host_xm_file=alpha/xm-vms.h
+ host_xmake_file=alpha/x-vms
+ host_exeext=.exe
+ # This removes the cpu type and manufacturer components and
+ # replaces "." with "_" in the operating system version.
+ target_noncanonical=`echo $host | sed 's/.*-.*-\(.*\)$/\1/' | sed 's/\./_/g'`
+ prefix=/gnu
+ local_prefix=/gnu
+ ;;
+ hppa1.1-*-pro*)
+ host_xmake_file="pa/x-ada"
+ ;;
+ hppa1.1-*-osf*)
+ host_xmake_file="pa/x-ada"
+ ;;
+ hppa1.1-*-rtems*)
+ host_xmake_file="pa/x-ada"
+ ;;
+ hppa1.1-*-bsd*)
+ host_xmake_file="pa/x-ada"
+ ;;
+ hppa1.0-*-hpux10* | hppa1.1-*-hpux10* | hppa2*-*-hpux10* | \
+ hppa1.0-*-hpux11* | hppa1.1-*-hpux11* | hppa2*-*-hpux11* | \
+ hppa*64*-*-hpux11*)
+ host_xmake_file="pa/x-ada"
+ ;;
+ i370-*-opened* | i370-*-mvs* ) # IBM 360/370/390 Architecture
+ host_xm_defines='FATAL_EXIT_CODE=12'
+ ;;
+ i[34567]86-sequent-ptx4*)
+ host_xm_defines="SMALL_ARG_MAX"
+ ;;
+ i[34567]86-*-solaris2*)
+ host_xm_defines="SMALL_ARG_MAX"
+ ;;
+ i[34567]86-*-sysv4*) # Intel 80386's running System V Release 4
+ host_xm_defines="SMALL_ARG_MAX"
+ ;;
+ i[34567]86-pc-msdosdjgpp*)
+ host_xm_file=i386/xm-djgpp.h
+ host_exeext=.exe
+ # Shorten $target_noncanonical for 8.3 filename conventions.
+ case ${target} in
+ *pc-msdosdjgpp*)
+ target_noncanonical=djgpp
+ ;;
+ esac
+ ;;
+ i[34567]86-*-pe | i[34567]86-*-cygwin*)
+ host_xm_file=i386/xm-cygwin.h
+ host_exeext=.exe
+ ;;
+ i[34567]86-*-mingw32*)
+ host_xm_file=i386/xm-mingw32.h
+ host_xmake_file=i386/x-mingw32
+ host_exeext=.exe
+ ;;
+ i[34567]86-*-uwin*)
+ echo "*** UWIN may not be used as a host platform because"
+ echo "*** linking with posix.dll is not allowed by the GNU GPL."
+ exit 1
+ ;;
+ i[34567]86-*-interix3*)
+ host_xmake_file="x-interix"
+ ;;
+ i860-*-sysv4*)
+ host_xmake_file=i860/x-sysv4
+ ;;
+ powerpc-*-darwin*)
+ # powerpc-darwin host support.
+ out_host_hook_obj=host-darwin.o
+ host_xmake_file=rs6000/x-darwin
+ ;;
+esac
diff --git a/contrib/gcc/config.in b/contrib/gcc/config.in
index 1e81188293b8..f791507cebef 100644
--- a/contrib/gcc/config.in
+++ b/contrib/gcc/config.in
@@ -1,631 +1,569 @@
-/* config.in. Generated automatically from configure.in by autoheader. */
+/* config.in. Generated from configure.ac by autoheader. */
-/* Define if using alloca.c. */
-#undef C_ALLOCA
+/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
+#undef BYTEORDER
-/* Define to empty if the keyword does not work. */
-#undef const
-
-/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
- This function is required for alloca.c support on those systems. */
-#undef CRAY_STACKSEG_END
-
-/* Define to the type of elements in the array set by `getgroups'.
- Usually this is either `int' or `gid_t'. */
-#undef GETGROUPS_T
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef gid_t
-
-/* Define if you have alloca, as a function or macro. */
-#undef HAVE_ALLOCA
-
-/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
-#undef HAVE_ALLOCA_H
-
-/* Define if you have the ANSI # stringizing operator in cpp. */
-#undef HAVE_STRINGIZE
-
-/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
-#undef HAVE_SYS_WAIT_H
-
-/* Define if you have <vfork.h>. */
-#undef HAVE_VFORK_H
-
-/* Define as __inline if that's what the C compiler calls it. */
-#undef inline
+/* Define as the number of bits in a byte, if \`limits.h' doesn't. */
+#undef CHAR_BIT
-/* Define if your C compiler doesn't accept -c and -o together. */
-#undef NO_MINUS_C_MINUS_O
+/* Define 0/1 to force the choice for exception handling model. */
+#undef CONFIG_SJLJ_EXCEPTIONS
-/* Define to `long' if <sys/types.h> doesn't define. */
-#undef off_t
+/* Define to enable the use of a default assembler. */
+#undef DEFAULT_ASSEMBLER
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef pid_t
+/* Define to enable the use of a default linker. */
+#undef DEFAULT_LINKER
-/* Define to `unsigned' if <sys/types.h> doesn't define. */
-#undef size_t
+/* Define if you want to use __cxa_atexit, rather than atexit, to register C++
+ destructors for local statics and global objects. This is essential for
+ fully standards-compliant handling of destructors, but requires
+ __cxa_atexit in libc. */
+#undef DEFAULT_USE_CXA_ATEXIT
-/* If using the C implementation of alloca, define if you know the
- direction of stack growth for your system; otherwise it will be
- automatically deduced at run-time.
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown
- */
-#undef STACK_DIRECTION
+/* Define if you want more run-time sanity checks. This one gets a grab bag of
+ miscellaneous but relatively cheap checks. */
+#undef ENABLE_CHECKING
-/* Define if you have the ANSI C header files. */
-#undef STDC_HEADERS
+/* Define if you want fold checked that it never destructs its argument. This
+ is quite expensive. */
+#undef ENABLE_FOLD_CHECKING
-/* Define if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
+/* Define if you want the garbage collector to operate in maximally paranoid
+ mode, validating the entire heap and collecting garbage at every
+ opportunity. This is extremely expensive. */
+#undef ENABLE_GC_ALWAYS_COLLECT
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef uid_t
+/* Define if you want the garbage collector to do object poisoning and other
+ memory allocation checks. This is quite expensive. */
+#undef ENABLE_GC_CHECKING
-/* Define vfork as fork if vfork does not work. */
-#undef vfork
+/* Define to 1 if translation of program messages to the user's native
+ language is requested. */
+#undef ENABLE_NLS
-/* Define if your assembler supports specifying the maximum number
- of bytes to skip when using the GAS .p2align command. */
-#undef HAVE_GAS_MAX_SKIP_P2ALIGN
+/* Define if you want all operations on RTL (the basic data structure of the
+ optimizer and back end) to be checked for dynamic type safety at runtime.
+ This is quite expensive. */
+#undef ENABLE_RTL_CHECKING
-/* Define if your assembler supports .balign and .p2align. */
-#undef HAVE_GAS_BALIGN_AND_P2ALIGN
+/* Define if you want RTL flag accesses to be checked against the RTL codes
+ that are supported for each access macro. This is relatively cheap. */
+#undef ENABLE_RTL_FLAG_CHECKING
-/* Define if your assembler uses the old HImode fild and fist notation. */
-#undef HAVE_GAS_FILDS_FISTS
+/* Define if you want all operations on trees (the basic data structure of the
+ front ends) to be checked for dynamic type safety at runtime. This is
+ moderately expensive. */
+#undef ENABLE_TREE_CHECKING
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef ssize_t
+/* Define if you want to run subprograms and generated programs through
+ valgrind (a memory checker). This is extremely expensive. */
+#undef ENABLE_VALGRIND_CHECKING
-/* Define if cpp should also search $prefix/include. */
-#undef PREFIX_INCLUDE_DIR
+/* Define to 1 if installation paths should be looked up in Windows32
+ Registry. Ignored on non windows32 hosts. */
+#undef ENABLE_WIN32_REGISTRY
-/* Define if you have the __argz_count function. */
-#undef HAVE___ARGZ_COUNT
+/* Define to the name of a file containing a list of extra machine modes for
+ this architecture. */
+#undef EXTRA_MODES_FILE
-/* Define if you have the __argz_next function. */
-#undef HAVE___ARGZ_NEXT
+/* Define to enable detailed memory allocation stats gathering. */
+#undef GATHER_STATISTICS
-/* Define if you have the __argz_stringify function. */
-#undef HAVE___ARGZ_STRINGIFY
+/* Define to the type of elements in the array set by `getgroups'. Usually
+ this is either `int' or `gid_t'. */
+#undef GETGROUPS_T
-/* Define if you have the alphasort function. */
+/* Define to 1 if you have the `alphasort' function. */
#undef HAVE_ALPHASORT
-/* Define if you have the atoll function. */
-#undef HAVE_ATOLL
-
-/* Define if you have the atoq function. */
-#undef HAVE_ATOQ
-
-/* Define if you have the clock function. */
-#undef HAVE_CLOCK
-
-/* Define if you have the dcgettext function. */
-#undef HAVE_DCGETTEXT
-
-/* Define if you have the dup2 function. */
-#undef HAVE_DUP2
+/* Define if your assembler supports dwarf2 .file/.loc directives, and
+ preserves file table indices exactly as given. */
+#undef HAVE_AS_DWARF2_DEBUG_LINE
-/* Define if you have the feof_unlocked function. */
-#undef HAVE_FEOF_UNLOCKED
+/* Define if your assembler supports explicit relocations. */
+#undef HAVE_AS_EXPLICIT_RELOCS
-/* Define if you have the fgets_unlocked function. */
-#undef HAVE_FGETS_UNLOCKED
+/* Define if your assembler supports the --gdwarf2 option. */
+#undef HAVE_AS_GDWARF2_DEBUG_FLAG
-/* Define if you have the fprintf_unlocked function. */
-#undef HAVE_FPRINTF_UNLOCKED
+/* Define true if the assembler supports '.long foo@GOTOFF'. */
+#undef HAVE_AS_GOTOFF_IN_DATA
-/* Define if you have the fputc_unlocked function. */
-#undef HAVE_FPUTC_UNLOCKED
+/* Define if your assembler supports the --gstabs option. */
+#undef HAVE_AS_GSTABS_DEBUG_FLAG
-/* Define if you have the fputs_unlocked function. */
-#undef HAVE_FPUTS_UNLOCKED
+/* Define if your assembler supports the Sun syntax for cmov. */
+#undef HAVE_AS_IX86_CMOV_SUN_SYNTAX
-/* Define if you have the fwrite_unlocked function. */
-#undef HAVE_FWRITE_UNLOCKED
+/* Define if your assembler supports .sleb128 and .uleb128. */
+#undef HAVE_AS_LEB128
-/* Define if you have the getcwd function. */
-#undef HAVE_GETCWD
+/* Define if your assembler supports ltoffx and ldxmov relocations. */
+#undef HAVE_AS_LTOFFX_LDXMOV_RELOCS
-/* Define if you have the getegid function. */
-#undef HAVE_GETEGID
+/* Define if your assembler supports mfcr field. */
+#undef HAVE_AS_MFCRF
-/* Define if you have the geteuid function. */
-#undef HAVE_GETEUID
+/* Define if your assembler supports the -no-mul-bug-abort option. */
+#undef HAVE_AS_NO_MUL_BUG_ABORT_OPTION
-/* Define if you have the getgid function. */
-#undef HAVE_GETGID
+/* Define if your assembler supports offsetable %lo(). */
+#undef HAVE_AS_OFFSETABLE_LO10
-/* Define if you have the getrlimit function. */
-#undef HAVE_GETRLIMIT
+/* Define if your assembler supports .register. */
+#undef HAVE_AS_REGISTER_PSEUDO_OP
-/* Define if you have the getrusage function. */
-#undef HAVE_GETRUSAGE
+/* Define if your assembler supports -relax option. */
+#undef HAVE_AS_RELAX_OPTION
-/* Define if you have the gettimeofday function. */
-#undef HAVE_GETTIMEOFDAY
+/* Define if your assembler and linker support unaligned PC relative relocs.
+ */
+#undef HAVE_AS_SPARC_UA_PCREL
-/* Define if you have the getuid function. */
-#undef HAVE_GETUID
+/* Define if your assembler and linker support unaligned PC relative relocs
+ against hidden symbols. */
+#undef HAVE_AS_SPARC_UA_PCREL_HIDDEN
-/* Define if you have the kill function. */
-#undef HAVE_KILL
+/* Define if your assembler supports thread-local storage. */
+#undef HAVE_AS_TLS
-/* Define if you have the lstat function. */
-#undef HAVE_LSTAT
+/* Define to 1 if you have the `atoll' function. */
+#undef HAVE_ATOLL
-/* Define if you have the mempcpy function. */
-#undef HAVE_MEMPCPY
+/* Define to 1 if you have the `atoq' function. */
+#undef HAVE_ATOQ
-/* Define if you have the mmap function. */
-#undef HAVE_MMAP
+/* Define to 1 if you have the `clock' function. */
+#undef HAVE_CLOCK
-/* Define if you have the munmap function. */
-#undef HAVE_MUNMAP
+/* Define if <time.h> defines clock_t. */
+#undef HAVE_CLOCK_T
-/* Define if you have the nl_langinfo function. */
-#undef HAVE_NL_LANGINFO
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_ABORT
-/* Define if you have the putc_unlocked function. */
-#undef HAVE_PUTC_UNLOCKED
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_ATOF
-/* Define if you have the putenv function. */
-#undef HAVE_PUTENV
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_ATOL
-/* Define if you have the scandir function. */
-#undef HAVE_SCANDIR
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_BASENAME
-/* Define if you have the setenv function. */
-#undef HAVE_SETENV
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_CALLOC
-/* Define if you have the setlocale function. */
-#undef HAVE_SETLOCALE
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_CLOCK
-/* Define if you have the setrlimit function. */
-#undef HAVE_SETRLIMIT
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_ERRNO
-/* Define if you have the stpcpy function. */
-#undef HAVE_STPCPY
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_FPRINTF_UNLOCKED
-/* Define if you have the strcasecmp function. */
-#undef HAVE_STRCASECMP
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_FPUTS_UNLOCKED
-/* Define if you have the strchr function. */
-#undef HAVE_STRCHR
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_FREE
-/* Define if you have the strdup function. */
-#undef HAVE_STRDUP
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_FWRITE_UNLOCKED
-/* Define if you have the strsignal function. */
-#undef HAVE_STRSIGNAL
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_GETCWD
-/* Define if you have the strtoul function. */
-#undef HAVE_STRTOUL
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_GETENV
-/* Define if you have the sysconf function. */
-#undef HAVE_SYSCONF
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_GETOPT
-/* Define if you have the times function. */
-#undef HAVE_TIMES
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_GETRLIMIT
-/* Define if you have the tsearch function. */
-#undef HAVE_TSEARCH
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_GETRUSAGE
-/* Define if you have the <argz.h> header file. */
-#undef HAVE_ARGZ_H
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_GETWD
-/* Define if you have the <direct.h> header file. */
-#undef HAVE_DIRECT_H
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_LDGETNAME
-/* Define if you have the <fcntl.h> header file. */
-#undef HAVE_FCNTL_H
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_MALLOC
-/* Define if you have the <langinfo.h> header file. */
-#undef HAVE_LANGINFO_H
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_PUTC_UNLOCKED
-/* Define if you have the <limits.h> header file. */
-#undef HAVE_LIMITS_H
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_REALLOC
-/* Define if you have the <locale.h> header file. */
-#undef HAVE_LOCALE_H
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_SBRK
-/* Define if you have the <malloc.h> header file. */
-#undef HAVE_MALLOC_H
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_SETRLIMIT
-/* Define if you have the <nl_types.h> header file. */
-#undef HAVE_NL_TYPES_H
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_SNPRINTF
-/* Define if you have the <stddef.h> header file. */
-#undef HAVE_STDDEF_H
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_STRSIGNAL
-/* Define if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_STRSTR
-/* Define if you have the <string.h> header file. */
-#undef HAVE_STRING_H
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_TIMES
-/* Define if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
+/* Define to 1 if we found this declaration otherwise define to 0. */
+#undef HAVE_DECL_VASPRINTF
-/* Define if you have the <sys/file.h> header file. */
-#undef HAVE_SYS_FILE_H
+/* Define to 1 if you have the <direct.h> header file. */
+#undef HAVE_DIRECT_H
-/* Define if you have the <sys/mman.h> header file. */
-#undef HAVE_SYS_MMAN_H
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
-/* Define if you have the <sys/param.h> header file. */
-#undef HAVE_SYS_PARAM_H
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
-/* Define if you have the <sys/resource.h> header file. */
-#undef HAVE_SYS_RESOURCE_H
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
-/* Define if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
+/* Define to 1 if you have the `fprintf_unlocked' function. */
+#undef HAVE_FPRINTF_UNLOCKED
-/* Define if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
+/* Define to 1 if you have the `fputc_unlocked' function. */
+#undef HAVE_FPUTC_UNLOCKED
-/* Define if you have the <sys/times.h> header file. */
-#undef HAVE_SYS_TIMES_H
+/* Define to 1 if you have the `fputs_unlocked' function. */
+#undef HAVE_FPUTS_UNLOCKED
-/* Define if you have the <time.h> header file. */
-#undef HAVE_TIME_H
+/* Define to 1 if you have the `fwrite_unlocked' function. */
+#undef HAVE_FWRITE_UNLOCKED
-/* Define if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
+/* Define if your assembler supports .balign and .p2align. */
+#undef HAVE_GAS_BALIGN_AND_P2ALIGN
-/* Define to enable the use of a default linker. */
-#undef DEFAULT_LINKER
+/* Define if your assembler uses the new HImode fild and fist notation. */
+#undef HAVE_GAS_FILDS_FISTS
-/* Define to enable the use of a default assembler. */
-#undef DEFAULT_ASSEMBLER
+/* Define if your assembler and linker support .hidden. */
+#undef HAVE_GAS_HIDDEN
-/* Define if your compiler understands volatile. */
-#undef HAVE_VOLATILE
+/* Define if your assembler supports specifying the maximum number of bytes to
+ skip when using the GAS .p2align command. */
+#undef HAVE_GAS_MAX_SKIP_P2ALIGN
-/* Define if your compiler supports the `long double' type. */
-#undef HAVE_LONG_DOUBLE
+/* Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.
+ */
+#undef HAVE_GAS_SHF_MERGE
-/* Define if your compiler supports the `long long' type. */
-#undef HAVE_LONG_LONG
+/* Define if your assembler supports .subsection and .subsection -1 starts
+ emitting at the beginning of your section. */
+#undef HAVE_GAS_SUBSECTION_ORDERING
-/* Define if your compiler supports the `__int64' type. */
-#undef HAVE___INT64
+/* Define if your assembler supports .weak. */
+#undef HAVE_GAS_WEAK
-/* Define if the `_Bool' type is built-in. */
-#undef HAVE__BOOL
+/* Define to 1 if you have the `getrlimit' function. */
+#undef HAVE_GETRLIMIT
-/* The number of bytes in type short */
-#undef SIZEOF_SHORT
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
-/* The number of bytes in type int */
-#undef SIZEOF_INT
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
-/* The number of bytes in type long */
-#undef SIZEOF_LONG
+/* Define if you have the iconv() function. */
+#undef HAVE_ICONV
-/* The number of bytes in type long long */
-#undef SIZEOF_LONG_LONG
+/* Define to 1 if you have the <iconv.h> header file. */
+#undef HAVE_ICONV_H
-/* The number of bytes in type __int64 */
-#undef SIZEOF___INT64
+/* Define .init_array/.fini_array sections are available and working. */
+#undef HAVE_INITFINI_ARRAY
-/* Define if the host execution character set is EBCDIC. */
-#undef HOST_EBCDIC
+/* Define if you have a working <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
-/* Define if you want more run-time sanity checks. This one gets a grab
- bag of miscellaneous but relatively cheap checks. */
-#undef ENABLE_CHECKING
+/* Define to 1 if you have the `kill' function. */
+#undef HAVE_KILL
-/* Define if you want all operations on trees (the basic data
- structure of the front ends) to be checked for dynamic type safety
- at runtime. This is moderately expensive. */
-#undef ENABLE_TREE_CHECKING
+/* Define to 1 if you have the <langinfo.h> header file. */
+#undef HAVE_LANGINFO_H
-/* Define if you want all operations on RTL (the basic data structure
- of the optimizer and back end) to be checked for dynamic type safety
- at runtime. This is quite expensive. */
-#undef ENABLE_RTL_CHECKING
+/* Define if your <locale.h> file defines LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
-/* Define if you want RTL flag accesses to be checked against the RTL
- codes that are supported for each access macro. This is relatively
- cheap. */
-#undef ENABLE_RTL_FLAG_CHECKING
+/* Define to 1 if you have the <ldfcn.h> header file. */
+#undef HAVE_LDFCN_H
-/* Define if you want the garbage collector to do object poisoning and
- other memory allocation checks. This is quite expensive. */
-#undef ENABLE_GC_CHECKING
+/* Define if your linker supports --as-needed and --no-as-needed options. */
+#undef HAVE_LD_AS_NEEDED
-/* Define if you want the garbage collector to operate in maximally
- paranoid mode, validating the entire heap and collecting garbage at
- every opportunity. This is extremely expensive. */
-#undef ENABLE_GC_ALWAYS_COLLECT
+/* Define if your linker supports --eh-frame-hdr option. */
+#undef HAVE_LD_EH_FRAME_HDR
-/* Define if you want to run subprograms and generated programs
- through valgrind (a memory checker). This is extremely expensive. */
-#undef ENABLE_VALGRIND_CHECKING
+/* Define if your linker supports -pie option. */
+#undef HAVE_LD_PIE
-/* Define if you want to use __cxa_atexit, rather than atexit, to
- register C++ destructors for local statics and global objects.
- This is essential for fully standards-compliant handling of
- destructors, but requires __cxa_atexit in libc. */
-#undef DEFAULT_USE_CXA_ATEXIT
+/* Define if your linker links a mix of read-only and read-write sections into
+ a read-write section. */
+#undef HAVE_LD_RO_RW_SECTION_MIXING
-/* Define if you want the C and C++ compilers to support multibyte
- character sets for source code. */
-#undef MULTIBYTE_CHARS
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
-/* Always define this when using the GNU C Library */
-#undef _GNU_SOURCE
+/* Define to 1 if you have the <locale.h> header file. */
+#undef HAVE_LOCALE_H
-/* Define if you have a working <stdbool.h> header file. */
-#undef HAVE_STDBOOL_H
+/* Define if your compiler supports the \`long long' type. */
+#undef HAVE_LONG_LONG
-/* Define if you can safely include both <string.h> and <strings.h>. */
-#undef STRING_WITH_STRINGS
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
-/* Define as the number of bits in a byte, if `limits.h' doesn't. */
-#undef CHAR_BIT
+/* Define to 1 if you have the `mbstowcs' function. */
+#undef HAVE_MBSTOWCS
-/* Define if the host machine stores words of multi-word integers in
- big-endian order. */
-#undef HOST_WORDS_BIG_ENDIAN
+/* Define if valgrind's memcheck.h header is installed. */
+#undef HAVE_MEMCHECK_H
-/* Define to the floating point format of the host machine, if not IEEE. */
-#undef HOST_FLOAT_FORMAT
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
-/* Define to 1 if the host machine stores floating point numbers in
- memory with the word containing the sign bit at the lowest address,
- or to 0 if it does it the other way around.
+/* Define to 1 if you have the `mincore' function. */
+#undef HAVE_MINCORE
- This macro should not be defined if the ordering is the same as for
- multi-word integers. */
-#undef HOST_FLOAT_WORDS_BIG_ENDIAN
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
-/* Define if you have a working <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
+/* Define if mmap with MAP_ANON(YMOUS) works. */
+#undef HAVE_MMAP_ANON
-/* Define if printf supports %p. */
-#undef HAVE_PRINTF_PTR
+/* Define if mmap of /dev/zero works. */
+#undef HAVE_MMAP_DEV_ZERO
/* Define if read-only mmap of a plain file works. */
#undef HAVE_MMAP_FILE
-/* Define if mmap of /dev/zero works. */
-#undef HAVE_MMAP_DEV_ZERO
-
-/* Define if mmap with MAP_ANON(YMOUS) works. */
-#undef HAVE_MMAP_ANON
+/* Define to 1 if you have the `nl_langinfo' function. */
+#undef HAVE_NL_LANGINFO
-/* Define if you have the iconv() function. */
-#undef HAVE_ICONV
+/* Define if printf supports "%p". */
+#undef HAVE_PRINTF_PTR
-/* Define as const if the declaration of iconv() needs const. */
-#undef ICONV_CONST
+/* Define to 1 if you have the `putc_unlocked' function. */
+#undef HAVE_PUTC_UNLOCKED
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_GETENV
+/* Define to 1 if you have the `scandir' function. */
+#undef HAVE_SCANDIR
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_ATOL
+/* Define to 1 if you have the `setlocale' function. */
+#undef HAVE_SETLOCALE
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_SBRK
+/* Define to 1 if you have the `setrlimit' function. */
+#undef HAVE_SETRLIMIT
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_ABORT
+/* Define if you have a working <stdbool.h> header file. */
+#undef HAVE_STDBOOL_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_ATOF
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_GETCWD
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_GETWD
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_STRSIGNAL
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_PUTC_UNLOCKED
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_FPUTS_UNLOCKED
+/* Define to 1 if you have the `strsignal' function. */
+#undef HAVE_STRSIGNAL
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_FWRITE_UNLOCKED
+/* Define if <sys/times.h> defines struct tms. */
+#undef HAVE_STRUCT_TMS
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_FPRINTF_UNLOCKED
+/* Define to 1 if you have the `sysconf' function. */
+#undef HAVE_SYSCONF
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_STRSTR
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_ERRNO
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_VASPRINTF
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_MALLOC
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_REALLOC
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_CALLOC
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_FREE
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_BASENAME
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_GETOPT
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_CLOCK
+/* Define to 1 if you have the `times' function. */
+#undef HAVE_TIMES
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_GETRLIMIT
+/* Define to 1 if you have the <time.h> header file. */
+#undef HAVE_TIME_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_SETRLIMIT
+/* Define if <sys/types.h> defines \`uchar'. */
+#undef HAVE_UCHAR
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_GETRUSAGE
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
-/* Define to `long' if <sys/resource.h> doesn't define. */
-#undef rlim_t
+/* Define if valgrind's valgrind/memcheck.h header is installed. */
+#undef HAVE_VALGRIND_MEMCHECK_H
-/* Define to 1 if we found this declaration otherwise define to 0. */
-#undef HAVE_DECL_TIMES
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
-/* Define if <sys/times.h> defines struct tms. */
-#undef HAVE_STRUCT_TMS
+/* Define to 1 if you have the <vfork.h> header file. */
+#undef HAVE_VFORK_H
-/* Define if <time.h> defines clock_t. */
-#undef HAVE_CLOCK_T
+/* Define to 1 if you have the <wchar.h> header file. */
+#undef HAVE_WCHAR_H
-/* Define .init_array/.fini_array sections are available and working. */
-#undef HAVE_INITFINI_ARRAY
+/* Define to 1 if you have the `wcswidth' function. */
+#undef HAVE_WCSWIDTH
-/* Define if host mkdir takes a single argument. */
-#undef MKDIR_TAKES_ONE_ARG
+/* Define to 1 if `fork' works. */
+#undef HAVE_WORKING_FORK
-/* Define 0/1 to force the choice for exception handling model. */
-#undef CONFIG_SJLJ_EXCEPTIONS
+/* Define this macro if mbstowcs does not crash when its first argument is
+ NULL. */
+#undef HAVE_WORKING_MBSTOWCS
-/* Define if gcc should use -lunwind. */
-#undef USE_LIBUNWIND_EXCEPTIONS
+/* Define to 1 if `vfork' works. */
+#undef HAVE_WORKING_VFORK
-/* Define to the name of a file containing a list of extra machine modes
- for this architecture. */
-#undef EXTRA_MODES_FILE
+/* Define if the \`_Bool' type is built-in. */
+#undef HAVE__BOOL
-/* Define if the target architecture needs extra machine modes to represent
- the results of comparisons. */
-#undef EXTRA_CC_MODES
+/* Define if your compiler supports the \`__int64' type. */
+#undef HAVE___INT64
-/* Define if you have the iconv() function. */
-#undef HAVE_ICONV
+/* Define if the host machine stores words of multi-word integers in
+ big-endian order. */
+#undef HOST_WORDS_BIG_ENDIAN
/* Define as const if the declaration of iconv() needs const. */
#undef ICONV_CONST
-/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
-#undef HAVE_LANGINFO_CODESET
+/* Define if host mkdir takes a single argument. */
+#undef MKDIR_TAKES_ONE_ARG
-/* Define if your <locale.h> file defines LC_MESSAGES. */
-#undef HAVE_LC_MESSAGES
+/* Define to 1 if HOST_WIDE_INT must be 64 bits wide (see hwint.h). */
+#undef NEED_64BIT_HOST_WIDE_INT
-/* Define to 1 if translation of program messages to the user's native language
- is requested. */
-#undef ENABLE_NLS
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
-/* Define if you have the <libintl.h> header file. */
-#undef HAVE_LIBINTL_H
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
-/* Define if the GNU gettext() function is already present or preinstalled. */
-#undef HAVE_GETTEXT
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
-/* Define to use the libintl included with this package instead of any
- version in the system libraries. */
-#undef USE_INCLUDED_LIBINTL
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
-/* Define to 1 if installation paths should be looked up in Windows32
- Registry. Ignored on non windows32 hosts. */
-#undef ENABLE_WIN32_REGISTRY
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
-/* Define to be the last portion of registry key on windows hosts. */
-#undef WIN32_REGISTRY_KEY
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
-/* Define if your assembler supports .subsection and .subsection -1 starts
- emitting at the beginning of your section. */
-#undef HAVE_GAS_SUBSECTION_ORDERING
-
-/* Define if your assembler supports .weak. */
-#undef HAVE_GAS_WEAK
-
-/* Define if your assembler supports .hidden. */
-#undef HAVE_GAS_HIDDEN
-
-/* Define if your assembler supports .uleb128. */
-#undef HAVE_AS_LEB128
+/* Define to PREFIX/include if cpp should also search that directory. */
+#undef PREFIX_INCLUDE_DIR
-/* Define if your assembler mis-optimizes .eh_frame data. */
-#undef USE_AS_TRADITIONAL_FORMAT
+/* The number of bytes in type int */
+#undef SIZEOF_INT
-/* Define if your assembler supports marking sections with SHF_MERGE flag. */
-#undef HAVE_GAS_SHF_MERGE
+/* The number of bytes in type long */
+#undef SIZEOF_LONG
-/* Define if your assembler supports thread-local storage. */
-#undef HAVE_AS_TLS
+/* The number of bytes in type long long */
+#undef SIZEOF_LONG_LONG
-/* Define if your assembler supports explicit relocations. */
-#undef HAVE_AS_EXPLICIT_RELOCS
+/* The number of bytes in type short */
+#undef SIZEOF_SHORT
-/* Define if your assembler supports .register. */
-#undef HAVE_AS_REGISTER_PSEUDO_OP
+/* The number of bytes in type void * */
+#undef SIZEOF_VOID_P
-/* Define if your assembler supports -relax option. */
-#undef HAVE_AS_RELAX_OPTION
+/* The number of bytes in type __int64 */
+#undef SIZEOF___INT64
-/* Define if your assembler and linker support unaligned PC relative relocs. */
-#undef HAVE_AS_SPARC_UA_PCREL
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
-/* Define if your assembler and linker support unaligned PC relative relocs against hidden symbols. */
-#undef HAVE_AS_SPARC_UA_PCREL_HIDDEN
+/* Define if you can safely include both <string.h> and <strings.h>. */
+#undef STRING_WITH_STRINGS
-/* Define if your assembler supports offsetable %lo(). */
-#undef HAVE_AS_OFFSETABLE_LO10
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
-/* Define if your assembler supports the Sun syntax for cmov. */
-#undef HAVE_AS_IX86_CMOV_SUN_SYNTAX
+/* Define if your assembler mis-optimizes .eh_frame data. */
+#undef USE_AS_TRADITIONAL_FORMAT
-/* Define true if the assembler supports '.long foo@GOTOFF'. */
-#undef HAVE_AS_GOTOFF_IN_DATA
+/* Define if gcc should use -lunwind. */
+#undef USE_LIBUNWIND_EXCEPTIONS
-/* Define if your assembler supports ltoffx and ldxmov relocations. */
-#undef HAVE_AS_LTOFFX_LDXMOV_RELOCS
+/* Define to be the last portion of registry key on windows hosts. */
+#undef WIN32_REGISTRY_KEY
-/* Define if your assembler supports dwarf2 .file/.loc directives,
- and preserves file table indices exactly as given. */
-#undef HAVE_AS_DWARF2_DEBUG_LINE
+/* whether byteorder is bigendian */
+#undef WORDS_BIGENDIAN
-/* Define if your assembler supports the --gdwarf2 option. */
-#undef HAVE_AS_GDWARF2_DEBUG_FLAG
+/* Always define this when using the GNU C Library */
+#undef _GNU_SOURCE
-/* Define if your assembler supports the --gstabs option. */
-#undef HAVE_AS_GSTABS_DEBUG_FLAG
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
-/* Define if your linker links a mix of read-only
- and read-write sections into a read-write section. */
-#undef HAVE_LD_RO_RW_SECTION_MIXING
+/* Define as `__inline' if that's what the C compiler calls it, or to nothing
+ if it is not supported. */
+#undef inline
-/* Define if your linker supports --eh-frame-hdr option. */
-#undef HAVE_LD_EH_FRAME_HDR
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
-/* Define if your MIPS libgloss linker scripts consistently include STARTUP directives. */
-#undef HAVE_MIPS_LIBGLOSS_STARTUP_DIRECTIVES
+/* Define to \`long' if <sys/resource.h> doesn't define. */
+#undef rlim_t
+/* Define to `int' if <sys/types.h> does not define. */
+#undef ssize_t
-/* Bison unconditionally undefines `const' if neither `__STDC__' nor
- __cplusplus are defined. That's a problem since we use `const' in
- the GCC headers, and the resulting bison code is therefore type
- unsafe. Thus, we must match the bison behavior here. */
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
-#ifndef __STDC__
-#ifndef __cplusplus
-#undef const
-#define const
-#endif
-#endif
+/* Define as `fork' if `vfork' does not work. */
+#undef vfork
diff --git a/contrib/gcc/config/alpha/alpha-modes.def b/contrib/gcc/config/alpha/alpha-modes.def
new file mode 100644
index 000000000000..8e9e6984bd25
--- /dev/null
+++ b/contrib/gcc/config/alpha/alpha-modes.def
@@ -0,0 +1,23 @@
+/* Alpha extra machine modes.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* 128-bit floating point. This gets reset in alpha_override_options
+ if VAX float format is in use. */
+FLOAT_MODE (TF, 16, ieee_quad_format);
diff --git a/contrib/gcc/config/alpha/alpha-protos.h b/contrib/gcc/config/alpha/alpha-protos.h
index fe4943bfeb87..95f1ad25c7c6 100644
--- a/contrib/gcc/config/alpha/alpha-protos.h
+++ b/contrib/gcc/config/alpha/alpha-protos.h
@@ -1,182 +1,123 @@
/* Prototypes for alpha.c functions used in the md file & elsewhere.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
extern int alpha_next_sequence_number;
-extern void literal_section PARAMS ((void));
-extern void override_options PARAMS ((void));
-extern int zap_mask PARAMS ((HOST_WIDE_INT));
-extern int direct_return PARAMS ((void));
-
-extern int alpha_sa_size PARAMS ((void));
-extern int alpha_pv_save_size PARAMS ((void));
-extern int alpha_using_fp PARAMS ((void));
-extern void alpha_write_verstamp PARAMS ((FILE *));
-extern void alpha_expand_prologue PARAMS ((void));
-extern void alpha_expand_epilogue PARAMS ((void));
-extern void alpha_output_filename PARAMS ((FILE *, const char *));
-extern void alpha_output_lineno PARAMS ((FILE *, int));
-
-extern int reg_or_0_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_6bit_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_8bit_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_const_int_operand PARAMS ((rtx, enum machine_mode));
-extern int cint8_operand PARAMS ((rtx, enum machine_mode));
-extern int add_operand PARAMS ((rtx, enum machine_mode));
-extern int sext_add_operand PARAMS ((rtx, enum machine_mode));
-extern int const48_operand PARAMS ((rtx, enum machine_mode));
-extern int and_operand PARAMS ((rtx, enum machine_mode));
-extern int or_operand PARAMS ((rtx, enum machine_mode));
-extern int mode_width_operand PARAMS ((rtx, enum machine_mode));
-extern int mode_mask_operand PARAMS ((rtx, enum machine_mode));
-extern int mul8_operand PARAMS ((rtx, enum machine_mode));
-extern int const0_operand PARAMS ((rtx, enum machine_mode));
-extern int hard_fp_register_operand PARAMS ((rtx, enum machine_mode));
-extern int hard_int_register_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int some_operand PARAMS ((rtx, enum machine_mode));
-extern int some_ni_operand PARAMS ((rtx, enum machine_mode));
-extern int input_operand PARAMS ((rtx, enum machine_mode));
-extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
-extern int direct_call_operand PARAMS ((rtx, enum machine_mode));
-extern int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int small_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int some_small_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int global_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int dtp16_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int dtp32_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int gotdtp_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int tp16_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int tp32_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int gottp_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int call_operand PARAMS ((rtx, enum machine_mode));
-extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int alpha_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int alpha_zero_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int alpha_swapped_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int signed_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int alpha_fp_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int divmod_operator PARAMS ((rtx, enum machine_mode));
-extern int aligned_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int unaligned_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_unaligned_mem_operand PARAMS ((rtx, enum machine_mode));
-extern int any_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_not_elim_operand PARAMS ((rtx, enum machine_mode));
-extern int normal_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_no_subreg_operand PARAMS ((rtx, enum machine_mode));
-extern int addition_operation PARAMS ((rtx, enum machine_mode));
-
-extern bool alpha_const_ok_for_letter_p PARAMS ((HOST_WIDE_INT, int));
-extern bool alpha_const_double_ok_for_letter_p PARAMS ((rtx, int));
-extern bool alpha_extra_constraint PARAMS ((rtx, int));
-
-extern rtx alpha_tablejump_addr_vec PARAMS ((rtx));
-extern rtx alpha_tablejump_best_label PARAMS ((rtx));
-
-extern bool alpha_legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
-extern rtx alpha_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
-extern rtx alpha_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
- int, int, int));
-
-extern rtx split_small_symbolic_operand PARAMS ((rtx));
-
-extern void get_aligned_mem PARAMS ((rtx, rtx *, rtx *));
-extern rtx get_unaligned_address PARAMS ((rtx, int));
-extern enum reg_class alpha_preferred_reload_class PARAMS ((rtx,
- enum reg_class));
-extern enum reg_class secondary_reload_class PARAMS ((enum reg_class,
- enum machine_mode,
- rtx, int));
-
-extern void alpha_set_memflags PARAMS ((rtx, rtx));
-extern rtx alpha_emit_set_const PARAMS ((rtx, enum machine_mode,
- HOST_WIDE_INT, int));
-extern rtx alpha_emit_set_long_const PARAMS ((rtx, HOST_WIDE_INT,
- HOST_WIDE_INT));
-extern bool alpha_expand_mov PARAMS ((enum machine_mode, rtx *));
-extern bool alpha_expand_mov_nobwx PARAMS ((enum machine_mode, rtx *));
-extern void alpha_emit_floatuns PARAMS ((rtx[]));
-extern rtx alpha_emit_conditional_move PARAMS ((rtx, enum machine_mode));
-extern void alpha_split_tfmode_pair PARAMS ((rtx[]));
-extern void alpha_split_tfmode_frobsign PARAMS ((rtx[],
- rtx (*)(rtx, rtx, rtx)));
-extern void alpha_expand_unaligned_load PARAMS ((rtx, rtx, HOST_WIDE_INT,
- HOST_WIDE_INT, int));
-extern void alpha_expand_unaligned_store PARAMS ((rtx, rtx, HOST_WIDE_INT,
- HOST_WIDE_INT));
-extern int alpha_expand_block_move PARAMS ((rtx []));
-extern int alpha_expand_block_clear PARAMS ((rtx []));
-extern rtx alpha_expand_zap_mask PARAMS ((HOST_WIDE_INT));
-extern void alpha_expand_builtin_vector_binop PARAMS ((rtx (*)(rtx, rtx, rtx),
- enum machine_mode,
- rtx, rtx, rtx));
-extern rtx alpha_return_addr PARAMS ((int, rtx));
-extern rtx alpha_gp_save_rtx PARAMS ((void));
-extern void print_operand PARAMS ((FILE *, rtx, int));
-extern void print_operand_address PARAMS ((FILE *, rtx));
-extern void alpha_initialize_trampoline PARAMS ((rtx, rtx, rtx, int, int, int));
-extern void alpha_reorg PARAMS ((rtx));
-
-extern tree alpha_build_va_list PARAMS ((void));
-extern void alpha_va_start PARAMS ((tree, rtx));
-extern rtx alpha_va_arg PARAMS ((tree, tree));
-extern rtx function_arg PARAMS ((CUMULATIVE_ARGS, enum machine_mode,
- tree, int));
-extern void alpha_start_function PARAMS ((FILE *, const char *, tree));
-extern void alpha_end_function PARAMS ((FILE *, const char *, tree));
-
-extern int alpha_find_lo_sum_using_gp PARAMS ((rtx));
+extern void literal_section (void);
+extern void override_options (void);
+extern int zap_mask (HOST_WIDE_INT);
+extern int direct_return (void);
+
+extern int alpha_sa_size (void);
+extern HOST_WIDE_INT alpha_initial_elimination_offset (unsigned int,
+ unsigned int);
+extern int alpha_pv_save_size (void);
+extern int alpha_using_fp (void);
+extern void alpha_expand_prologue (void);
+extern void alpha_expand_epilogue (void);
+extern void alpha_output_filename (FILE *, const char *);
+extern void alpha_output_lineno (FILE *, int);
+
+extern bool alpha_const_ok_for_letter_p (HOST_WIDE_INT, int);
+extern bool alpha_const_double_ok_for_letter_p (rtx, int);
+extern bool alpha_extra_constraint (rtx, int);
+
+extern rtx alpha_tablejump_addr_vec (rtx);
+extern rtx alpha_tablejump_best_label (rtx);
+
+extern bool alpha_legitimate_address_p (enum machine_mode, rtx, int);
+extern rtx alpha_legitimize_address (rtx, rtx, enum machine_mode);
+extern rtx alpha_legitimize_reload_address (rtx, enum machine_mode,
+ int, int, int);
+
+extern rtx split_small_symbolic_operand (rtx);
+
+extern void get_aligned_mem (rtx, rtx *, rtx *);
+extern rtx get_unaligned_address (rtx, int);
+extern enum reg_class alpha_preferred_reload_class (rtx, enum reg_class);
+extern enum reg_class secondary_reload_class (enum reg_class,
+ enum machine_mode, rtx, int);
+
+extern void alpha_set_memflags (rtx, rtx);
+extern rtx alpha_emit_set_const (rtx, enum machine_mode, HOST_WIDE_INT, int);
+extern rtx alpha_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
+extern bool alpha_expand_mov (enum machine_mode, rtx *);
+extern bool alpha_expand_mov_nobwx (enum machine_mode, rtx *);
+extern void alpha_emit_floatuns (rtx[]);
+extern rtx alpha_emit_conditional_move (rtx, enum machine_mode);
+extern void alpha_split_tfmode_pair (rtx[]);
+extern void alpha_split_tfmode_frobsign (rtx[], rtx (*)(rtx, rtx, rtx));
+extern void alpha_expand_unaligned_load (rtx, rtx, HOST_WIDE_INT,
+ HOST_WIDE_INT, int);
+extern void alpha_expand_unaligned_store (rtx, rtx, HOST_WIDE_INT,
+ HOST_WIDE_INT);
+extern int alpha_expand_block_move (rtx []);
+extern int alpha_expand_block_clear (rtx []);
+extern rtx alpha_expand_zap_mask (HOST_WIDE_INT);
+extern void alpha_expand_builtin_vector_binop (rtx (*)(rtx, rtx, rtx),
+ enum machine_mode,
+ rtx, rtx, rtx);
+extern rtx alpha_return_addr (int, rtx);
+extern rtx alpha_gp_save_rtx (void);
+extern void print_operand (FILE *, rtx, int);
+extern void print_operand_address (FILE *, rtx);
+extern void alpha_initialize_trampoline (rtx, rtx, rtx, int, int, int);
+
+extern void alpha_va_start (tree, rtx);
+extern rtx alpha_va_arg (tree, tree);
+extern rtx function_arg (CUMULATIVE_ARGS, enum machine_mode, tree, int);
+extern rtx function_value (tree, tree, enum machine_mode);
+
+extern void alpha_start_function (FILE *, const char *, tree);
+extern void alpha_end_function (FILE *, const char *, tree);
+
+extern int alpha_find_lo_sum_using_gp (rtx);
#ifdef REAL_VALUE_TYPE
-extern int check_float_value PARAMS ((enum machine_mode,
- REAL_VALUE_TYPE *, int));
+extern int check_float_value (enum machine_mode, REAL_VALUE_TYPE *, int);
#endif
#ifdef RTX_CODE
-extern rtx alpha_emit_conditional_branch PARAMS ((enum rtx_code));
-extern rtx alpha_emit_setcc PARAMS ((enum rtx_code));
-extern int alpha_split_conditional_move PARAMS ((enum rtx_code, rtx, rtx,
- rtx, rtx));
-extern void alpha_emit_xfloating_arith PARAMS ((enum rtx_code, rtx[]));
-extern void alpha_emit_xfloating_cvt PARAMS ((enum rtx_code, rtx[]));
+extern rtx alpha_emit_conditional_branch (enum rtx_code);
+extern rtx alpha_emit_setcc (enum rtx_code);
+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[]);
#endif
-extern rtx alpha_need_linkage PARAMS ((const char *, int));
-extern rtx alpha_use_linkage PARAMS ((rtx, tree, int, int));
+extern rtx alpha_need_linkage (const char *, int);
+extern rtx alpha_use_linkage (rtx, tree, int, int);
#if TARGET_ABI_OPEN_VMS
-#ifdef HAVE_MACHINE_MODES
-extern enum avms_arg_type alpha_arg_type PARAMS ((enum machine_mode));
+extern enum avms_arg_type alpha_arg_type (enum machine_mode);
+extern rtx alpha_arg_info_reg_val (CUMULATIVE_ARGS);
#endif
-extern rtx alpha_arg_info_reg_val PARAMS ((CUMULATIVE_ARGS));
-#endif /* TARGET_ABI_OPEN_VMS */
-extern rtx unicosmk_add_call_info_word PARAMS ((rtx));
+extern rtx unicosmk_add_call_info_word (rtx);
#if TARGET_ABI_UNICOSMK
-extern void unicosmk_defer_case_vector PARAMS ((rtx, rtx));
-extern void unicosmk_add_extern PARAMS ((const char *));
-extern void unicosmk_output_align PARAMS ((FILE *, int));
-extern char * unicosmk_text_section PARAMS ((void));
-extern char * unicosmk_data_section PARAMS ((void));
-extern void unicosmk_asm_file_start PARAMS ((FILE *));
-extern void unicosmk_asm_file_end PARAMS ((FILE *));
-extern void unicosmk_output_common PARAMS ((FILE *, const char *, int, int));
-#endif /* TARGET_ABI_UNICOSMK */
+extern void unicosmk_defer_case_vector (rtx, rtx);
+extern void unicosmk_add_extern (const char *);
+extern void unicosmk_output_align (FILE *, int);
+extern char * unicosmk_text_section (void);
+extern char * unicosmk_data_section (void);
+extern void unicosmk_output_common (FILE *, const char *, int, int);
+extern int unicosmk_initial_elimination_offset (int, int);
+#endif
diff --git a/contrib/gcc/config/alpha/alpha.c b/contrib/gcc/config/alpha/alpha.c
index 42b57e18a21a..0086968afb7a 100644
--- a/contrib/gcc/config/alpha/alpha.c
+++ b/contrib/gcc/config/alpha/alpha.c
@@ -1,28 +1,30 @@
/* Subroutines used for code generation on the DEC Alpha.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "regs.h"
@@ -48,6 +50,8 @@ Boston, MA 02111-1307, USA. */
#include "target-def.h"
#include "debug.h"
#include "langhooks.h"
+#include <splay-tree.h>
+#include "cfglayout.h"
/* Specify which cpu to schedule for. */
@@ -103,110 +107,70 @@ static int alpha_function_needs_gp;
/* The alias set for prologue/epilogue register save/restore. */
-static int alpha_sr_alias_set;
+static GTY(()) int alpha_sr_alias_set;
/* The assembler name of the current function. */
static const char *alpha_fnname;
/* The next explicit relocation sequence number. */
+extern GTY(()) int alpha_next_sequence_number;
int alpha_next_sequence_number = 1;
/* The literal and gpdisp sequence numbers for this insn, as printed
by %# and %* respectively. */
+extern GTY(()) int alpha_this_literal_sequence_number;
+extern GTY(()) int alpha_this_gpdisp_sequence_number;
int alpha_this_literal_sequence_number;
int alpha_this_gpdisp_sequence_number;
-/* Declarations of static functions. */
-static int tls_symbolic_operand_1
- PARAMS ((rtx, enum machine_mode, int, int));
-static enum tls_model tls_symbolic_operand_type
- PARAMS ((rtx));
-static bool decl_in_text_section
- PARAMS ((tree));
-static bool alpha_in_small_data_p
- PARAMS ((tree));
-static void alpha_encode_section_info
- PARAMS ((tree, int));
-static const char *alpha_strip_name_encoding
- PARAMS ((const char *));
-static int some_small_symbolic_operand_1
- PARAMS ((rtx *, void *));
-static int split_small_symbolic_operand_1
- PARAMS ((rtx *, void *));
-static void alpha_set_memflags_1
- PARAMS ((rtx, int, int, int));
-static rtx alpha_emit_set_const_1
- PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT, int));
-static void alpha_expand_unaligned_load_words
- PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
-static void alpha_expand_unaligned_store_words
- PARAMS ((rtx *out_regs, rtx smem, HOST_WIDE_INT words, HOST_WIDE_INT ofs));
-static void alpha_init_builtins
- PARAMS ((void));
-static rtx alpha_expand_builtin
- PARAMS ((tree, rtx, rtx, enum machine_mode, int));
-static void alpha_sa_mask
- PARAMS ((unsigned long *imaskP, unsigned long *fmaskP));
-static int find_lo_sum_using_gp
- PARAMS ((rtx *, void *));
-static int alpha_does_function_need_gp
- PARAMS ((void));
-static int alpha_ra_ever_killed
- PARAMS ((void));
-static const char *get_trap_mode_suffix
- PARAMS ((void));
-static const char *get_round_mode_suffix
- PARAMS ((void));
-static const char *get_some_local_dynamic_name
- PARAMS ((void));
-static int get_some_local_dynamic_name_1
- PARAMS ((rtx *, void *));
-static rtx set_frame_related_p
- PARAMS ((void));
-static const char *alpha_lookup_xfloating_lib_func
- PARAMS ((enum rtx_code));
-static int alpha_compute_xfloating_mode_arg
- PARAMS ((enum rtx_code, enum alpha_fp_rounding_mode));
-static void alpha_emit_xfloating_libcall
- PARAMS ((const char *, rtx, rtx[], int, rtx));
-static rtx alpha_emit_xfloating_compare
- PARAMS ((enum rtx_code, rtx, rtx));
-static void alpha_output_function_end_prologue
- PARAMS ((FILE *));
-static int alpha_adjust_cost
- PARAMS ((rtx, rtx, rtx, int));
-static int alpha_issue_rate
- PARAMS ((void));
-static int alpha_use_dfa_pipeline_interface
- PARAMS ((void));
-static int alpha_multipass_dfa_lookahead
- PARAMS ((void));
-
-#ifdef OBJECT_FORMAT_ELF
-static void alpha_elf_select_rtx_section
- PARAMS ((enum machine_mode, rtx, unsigned HOST_WIDE_INT));
-#endif
-
-#if TARGET_ABI_OPEN_VMS
-static bool alpha_linkage_symbol_p
- PARAMS ((const char *symname));
-static void alpha_write_linkage
- PARAMS ((FILE *, const char *, tree));
-#endif
-
-#if TARGET_ABI_OSF
-static void alpha_output_mi_thunk_osf
- PARAMS ((FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
-#endif
+/* Costs of various operations on the different architectures. */
-static struct machine_function * alpha_init_machine_status
- PARAMS ((void));
+struct alpha_rtx_cost_data
+{
+ unsigned char fp_add;
+ unsigned char fp_mult;
+ unsigned char fp_div_sf;
+ unsigned char fp_div_df;
+ unsigned char int_mult_si;
+ unsigned char int_mult_di;
+ unsigned char int_shift;
+ unsigned char int_cmov;
+};
-static void unicosmk_output_deferred_case_vectors PARAMS ((FILE *));
-static void unicosmk_gen_dsib PARAMS ((unsigned long *imaskP));
-static void unicosmk_output_ssib PARAMS ((FILE *, const char *));
-static int unicosmk_need_dex PARAMS ((rtx));
+static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] =
+{
+ { /* EV4 */
+ COSTS_N_INSNS (6), /* fp_add */
+ COSTS_N_INSNS (6), /* fp_mult */
+ COSTS_N_INSNS (34), /* fp_div_sf */
+ COSTS_N_INSNS (63), /* fp_div_df */
+ COSTS_N_INSNS (23), /* int_mult_si */
+ COSTS_N_INSNS (23), /* int_mult_di */
+ COSTS_N_INSNS (2), /* int_shift */
+ COSTS_N_INSNS (2), /* int_cmov */
+ },
+ { /* EV5 */
+ COSTS_N_INSNS (4), /* fp_add */
+ COSTS_N_INSNS (4), /* fp_mult */
+ COSTS_N_INSNS (15), /* fp_div_sf */
+ COSTS_N_INSNS (22), /* fp_div_df */
+ COSTS_N_INSNS (8), /* int_mult_si */
+ COSTS_N_INSNS (12), /* int_mult_di */
+ COSTS_N_INSNS (1) + 1, /* int_shift */
+ COSTS_N_INSNS (1), /* int_cmov */
+ },
+ { /* EV6 */
+ COSTS_N_INSNS (4), /* fp_add */
+ COSTS_N_INSNS (4), /* fp_mult */
+ COSTS_N_INSNS (12), /* fp_div_sf */
+ COSTS_N_INSNS (15), /* fp_div_df */
+ COSTS_N_INSNS (7), /* int_mult_si */
+ COSTS_N_INSNS (7), /* int_mult_di */
+ COSTS_N_INSNS (1), /* int_shift */
+ COSTS_N_INSNS (2), /* int_cmov */
+ },
+};
/* Get the number of args of a function in one of two ways. */
#if TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK
@@ -217,99 +181,24 @@ static int unicosmk_need_dex PARAMS ((rtx));
#define REG_PV 27
#define REG_RA 26
-
-/* Initialize the GCC target structure. */
-#if TARGET_ABI_OPEN_VMS
-const struct attribute_spec vms_attribute_table[];
-static unsigned int vms_section_type_flags PARAMS ((tree, const char *, int));
-static void vms_asm_named_section PARAMS ((const char *, unsigned int));
-static void vms_asm_out_constructor PARAMS ((rtx, int));
-static void vms_asm_out_destructor PARAMS ((rtx, int));
-# undef TARGET_ATTRIBUTE_TABLE
-# define TARGET_ATTRIBUTE_TABLE vms_attribute_table
-# undef TARGET_SECTION_TYPE_FLAGS
-# define TARGET_SECTION_TYPE_FLAGS vms_section_type_flags
-#endif
-
-#undef TARGET_IN_SMALL_DATA_P
-#define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO alpha_encode_section_info
-#undef TARGET_STRIP_NAME_ENCODING
-#define TARGET_STRIP_NAME_ENCODING alpha_strip_name_encoding
-
-#if TARGET_ABI_UNICOSMK
-static void unicosmk_asm_named_section PARAMS ((const char *, unsigned int));
-static void unicosmk_insert_attributes PARAMS ((tree, tree *));
-static unsigned int unicosmk_section_type_flags PARAMS ((tree, const char *,
- int));
-static void unicosmk_unique_section PARAMS ((tree, int));
-# undef TARGET_INSERT_ATTRIBUTES
-# define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
-# undef TARGET_SECTION_TYPE_FLAGS
-# define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
-# undef TARGET_ASM_UNIQUE_SECTION
-# define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
-# undef TARGET_ASM_GLOBALIZE_LABEL
-# define TARGET_ASM_GLOBALIZE_LABEL hook_FILEptr_constcharptr_void
-#endif
-
-#undef TARGET_ASM_ALIGNED_HI_OP
-#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
-#undef TARGET_ASM_ALIGNED_DI_OP
-#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
-/* Default unaligned ops are provided for ELF systems. To get unaligned
- data for non-ELF systems, we have to turn off auto alignment. */
-#ifndef OBJECT_FORMAT_ELF
-#undef TARGET_ASM_UNALIGNED_HI_OP
-#define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
-#undef TARGET_ASM_UNALIGNED_SI_OP
-#define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
-#undef TARGET_ASM_UNALIGNED_DI_OP
-#define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
-#endif
-
-#ifdef OBJECT_FORMAT_ELF
-#undef TARGET_ASM_SELECT_RTX_SECTION
-#define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section
-#endif
-
-#undef TARGET_ASM_FUNCTION_END_PROLOGUE
-#define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
-
-#undef TARGET_SCHED_ADJUST_COST
-#define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
-#undef TARGET_SCHED_ISSUE_RATE
-#define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
-#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
-#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE \
- alpha_use_dfa_pipeline_interface
-#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
-#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
- alpha_multipass_dfa_lookahead
-
-#undef TARGET_HAVE_TLS
-#define TARGET_HAVE_TLS HAVE_AS_TLS
-
-#undef TARGET_INIT_BUILTINS
-#define TARGET_INIT_BUILTINS alpha_init_builtins
-#undef TARGET_EXPAND_BUILTIN
-#define TARGET_EXPAND_BUILTIN alpha_expand_builtin
+/* Declarations of static functions. */
+static struct machine_function *alpha_init_machine_status (void);
+static rtx alpha_emit_xfloating_compare (enum rtx_code, rtx, rtx);
-#if TARGET_ABI_OSF
-#undef TARGET_ASM_OUTPUT_MI_THUNK
-#define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
-#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
-#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
+#if TARGET_ABI_OPEN_VMS
+static void alpha_write_linkage (FILE *, const char *, tree);
#endif
-struct gcc_target targetm = TARGET_INITIALIZER;
+static void unicosmk_output_deferred_case_vectors (FILE *);
+static void unicosmk_gen_dsib (unsigned long *);
+static void unicosmk_output_ssib (FILE *, const char *);
+static int unicosmk_need_dex (rtx);
/* Parse target option strings. */
void
-override_options ()
+override_options (void)
{
int i;
static const struct cpu_table {
@@ -344,7 +233,7 @@ override_options ()
flag_pic = 0;
}
- /* On Unicos/Mk, the native compiler consistenly generates /d suffices for
+ /* On Unicos/Mk, the native compiler consistently generates /d suffices for
floating-point instructions. Make that the default for this target. */
if (TARGET_ABI_UNICOSMK)
alpha_fprm = ALPHA_FPRM_DYN;
@@ -501,6 +390,9 @@ override_options ()
warning ("trap mode not supported for VAX floats");
alpha_fptm = ALPHA_FPTM_SU;
}
+ if (target_flags_explicit & MASK_LONG_DOUBLE_128)
+ warning ("128-bit long double not supported for VAX floats");
+ target_flags &= ~MASK_LONG_DOUBLE_128;
}
{
@@ -583,17 +475,16 @@ override_options ()
/* Tell the compiler when we're using VAX floating point. */
if (TARGET_FLOAT_VAX)
{
- real_format_for_mode[SFmode - QFmode] = &vax_f_format;
- real_format_for_mode[DFmode - QFmode] = &vax_g_format;
- real_format_for_mode[TFmode - QFmode] = NULL;
+ REAL_MODE_FORMAT (SFmode) = &vax_f_format;
+ REAL_MODE_FORMAT (DFmode) = &vax_g_format;
+ REAL_MODE_FORMAT (TFmode) = NULL;
}
}
/* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
int
-zap_mask (value)
- HOST_WIDE_INT value;
+zap_mask (HOST_WIDE_INT value)
{
int i;
@@ -609,9 +500,7 @@ zap_mask (value)
register, it must be in the proper mode unless MODE is VOIDmode. */
int
-reg_or_0_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+reg_or_0_operand (rtx op, enum machine_mode mode)
{
return op == CONST0_RTX (mode) || register_operand (op, mode);
}
@@ -620,9 +509,7 @@ reg_or_0_operand (op, mode)
any register. */
int
-reg_or_6bit_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+reg_or_6bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT
&& (unsigned HOST_WIDE_INT) INTVAL (op) < 64)
@@ -633,9 +520,7 @@ reg_or_6bit_operand (op, mode)
/* Return 1 if OP is an 8-bit constant or any register. */
int
-reg_or_8bit_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+reg_or_8bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT
&& (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)
@@ -645,9 +530,7 @@ reg_or_8bit_operand (op, mode)
/* Return 1 if OP is a constant or any register. */
int
-reg_or_const_int_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+reg_or_const_int_operand (rtx op, enum machine_mode mode)
{
return GET_CODE (op) == CONST_INT || register_operand (op, mode);
}
@@ -655,9 +538,7 @@ reg_or_const_int_operand (op, mode)
/* Return 1 if OP is an 8-bit constant. */
int
-cint8_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+cint8_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return ((GET_CODE (op) == CONST_INT
&& (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100));
@@ -666,9 +547,7 @@ cint8_operand (op, mode)
/* Return 1 if the operand is a valid second operand to an add insn. */
int
-add_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+add_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
/* Constraints I, J, O and P are covered by K. */
@@ -682,9 +561,7 @@ add_operand (op, mode)
add insn. */
int
-sext_add_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+sext_add_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
@@ -696,9 +573,7 @@ sext_add_operand (op, mode)
/* Return 1 if OP is the constant 4 or 8. */
int
-const48_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+const48_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& (INTVAL (op) == 4 || INTVAL (op) == 8));
@@ -707,9 +582,7 @@ const48_operand (op, mode)
/* Return 1 if OP is a valid first operand to an AND insn. */
int
-and_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+and_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == VOIDmode)
return (zap_mask (CONST_DOUBLE_LOW (op))
@@ -726,9 +599,7 @@ and_operand (op, mode)
/* Return 1 if OP is a valid first operand to an IOR or XOR insn. */
int
-or_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+or_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
@@ -741,9 +612,7 @@ or_operand (op, mode)
mode smaller than DImode. */
int
-mode_width_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mode_width_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& (INTVAL (op) == 8 || INTVAL (op) == 16
@@ -754,9 +623,7 @@ mode_width_operand (op, mode)
smaller than an integer. */
int
-mode_mask_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mode_mask_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == CONST_INT)
{
@@ -783,9 +650,7 @@ mode_mask_operand (op, mode)
/* Return 1 if OP is a multiple of 8 less than 64. */
int
-mul8_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mul8_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& (unsigned HOST_WIDE_INT) INTVAL (op) < 64
@@ -795,9 +660,7 @@ mul8_operand (op, mode)
/* Return 1 if OP is the zero constant for MODE. */
int
-const0_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+const0_operand (rtx op, enum machine_mode mode)
{
return op == CONST0_RTX (mode);
}
@@ -805,9 +668,7 @@ const0_operand (op, mode)
/* Return 1 if OP is a hard floating-point register. */
int
-hard_fp_register_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+hard_fp_register_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
@@ -820,9 +681,7 @@ hard_fp_register_operand (op, mode)
/* Return 1 if OP is a hard general register. */
int
-hard_int_register_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+hard_int_register_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
@@ -836,9 +695,7 @@ hard_int_register_operand (op, mode)
int
-reg_or_cint_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+reg_or_cint_operand (rtx op, enum machine_mode mode)
{
return (GET_CODE (op) == CONST_INT
|| register_operand (op, mode));
@@ -848,9 +705,7 @@ reg_or_cint_operand (op, mode)
if it is a MEM, it need not be valid. */
int
-some_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+some_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
@@ -881,9 +736,7 @@ some_operand (op, mode)
/* Likewise, but don't accept constants. */
int
-some_ni_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+some_ni_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return 0;
@@ -897,9 +750,7 @@ some_ni_operand (op, mode)
/* Return 1 if OP is a valid operand for the source of a move insn. */
int
-input_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+input_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
@@ -964,60 +815,89 @@ input_operand (op, mode)
file, and in the same section as the current function. */
int
-current_file_function_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+samegp_function_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != SYMBOL_REF)
- return 0;
+ return false;
/* Easy test for recursion. */
if (op == XEXP (DECL_RTL (current_function_decl), 0))
- return 1;
+ return true;
- /* Otherwise, we need the DECL for the SYMBOL_REF, which we can't get.
- So SYMBOL_REF_FLAG has been declared to imply that the function is
- in the default text section. So we must also check that the current
- function is also in the text section. */
- if (SYMBOL_REF_FLAG (op) && decl_in_text_section (current_function_decl))
- return 1;
+ /* Functions that are not local can be overridden, and thus may
+ not share the same gp. */
+ if (! SYMBOL_REF_LOCAL_P (op))
+ return false;
- return 0;
+ /* If -msmall-data is in effect, assume that there is only one GP
+ for the module, and so any local symbol has this property. We
+ need explicit relocations to be able to enforce this for symbols
+ not defined in this unit of translation, however. */
+ if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA)
+ return true;
+
+ /* Functions that are not external are defined in this UoT,
+ and thus must share the same gp. */
+ return ! SYMBOL_REF_EXTERNAL_P (op);
}
/* Return 1 if OP is a SYMBOL_REF for which we can make a call via bsr. */
int
-direct_call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+direct_call_operand (rtx op, enum machine_mode mode)
{
- /* Must be defined in this file. */
- if (! current_file_function_operand (op, mode))
- return 0;
+ tree op_decl, cfun_sec, op_sec;
+
+ /* Must share the same GP. */
+ if (!samegp_function_operand (op, mode))
+ return false;
/* If profiling is implemented via linker tricks, we can't jump
- to the nogp alternate entry point. */
+ to the nogp alternate entry point. Note that current_function_profile
+ would not be correct, since that doesn't indicate if the target
+ function uses profiling. */
/* ??? TARGET_PROFILING_NEEDS_GP isn't really the right test,
but is approximately correct for the OSF ABIs. Don't know
what to do for VMS, NT, or UMK. */
- if (! TARGET_PROFILING_NEEDS_GP
- && ! current_function_profile)
- return 0;
+ if (!TARGET_PROFILING_NEEDS_GP && profile_flag)
+ return false;
- return 1;
+ /* Must be a function. In some cases folks create thunks in static
+ data structures and then make calls to them. If we allow the
+ direct call, we'll get an error from the linker about !samegp reloc
+ against a symbol without a .prologue directive. */
+ if (!SYMBOL_REF_FUNCTION_P (op))
+ return false;
+
+ /* Must be "near" so that the branch is assumed to reach. With
+ -msmall-text, this is assumed true of all local symbols. Since
+ we've already checked samegp, locality is already assured. */
+ if (TARGET_SMALL_TEXT)
+ return true;
+
+ /* Otherwise, a decl is "near" if it is defined in the same section. */
+ if (flag_function_sections)
+ return false;
+
+ op_decl = SYMBOL_REF_DECL (op);
+ if (DECL_ONE_ONLY (current_function_decl)
+ || (op_decl && DECL_ONE_ONLY (op_decl)))
+ return false;
+
+ cfun_sec = DECL_SECTION_NAME (current_function_decl);
+ op_sec = op_decl ? DECL_SECTION_NAME (op_decl) : NULL;
+ return ((!cfun_sec && !op_sec)
+ || (cfun_sec && op_sec
+ && strcmp (TREE_STRING_POINTER (cfun_sec),
+ TREE_STRING_POINTER (op_sec)) == 0));
}
/* Return true if OP is a LABEL_REF, or SYMBOL_REF or CONST referencing
a (non-tls) variable known to be defined in this file. */
int
-local_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+local_symbolic_operand (rtx op, enum machine_mode mode)
{
- const char *str;
-
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
@@ -1032,38 +912,15 @@ local_symbolic_operand (op, mode)
if (GET_CODE (op) != SYMBOL_REF)
return 0;
- /* Easy pickings. */
- if (CONSTANT_POOL_ADDRESS_P (op) || STRING_POOL_ADDRESS_P (op))
- return 1;
-
- /* ??? SYMBOL_REF_FLAG is set for local function symbols, but we
- run into problems with the rtl inliner in that the symbol was
- once external, but is local after inlining, which results in
- unrecognizable insns. */
-
- str = XSTR (op, 0);
-
- /* If @[LS], then alpha_encode_section_info sez it's local. */
- if (str[0] == '@' && (str[1] == 'L' || str[1] == 'S'))
- return 1;
-
- /* If *$, then ASM_GENERATE_INTERNAL_LABEL sez it's local. */
- if (str[0] == '*' && str[1] == '$')
- return 1;
-
- return 0;
+ return SYMBOL_REF_LOCAL_P (op) && !SYMBOL_REF_TLS_MODEL (op);
}
/* Return true if OP is a SYMBOL_REF or CONST referencing a variable
known to be defined in this file in the small data area. */
int
-small_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+small_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- const char *str;
-
if (! TARGET_SMALL_DATA)
return 0;
@@ -1078,25 +935,22 @@ small_symbolic_operand (op, mode)
if (GET_CODE (op) != SYMBOL_REF)
return 0;
+ /* ??? There's no encode_section_info equivalent for the rtl
+ constant pool, so SYMBOL_FLAG_SMALL never gets set. */
if (CONSTANT_POOL_ADDRESS_P (op))
- return GET_MODE_SIZE (get_pool_mode (op)) <= (unsigned) g_switch_value;
- else
- {
- str = XSTR (op, 0);
- return str[0] == '@' && str[1] == 'S';
- }
+ return GET_MODE_SIZE (get_pool_mode (op)) <= g_switch_value;
+
+ return (SYMBOL_REF_LOCAL_P (op)
+ && SYMBOL_REF_SMALL_P (op)
+ && SYMBOL_REF_TLS_MODEL (op) == 0);
}
/* Return true if OP is a SYMBOL_REF or CONST referencing a variable
not known (or known not) to be defined in this file. */
int
-global_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+global_symbolic_operand (rtx op, enum machine_mode mode)
{
- const char *str;
-
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
@@ -1108,20 +962,13 @@ global_symbolic_operand (op, mode)
if (GET_CODE (op) != SYMBOL_REF)
return 0;
- if (local_symbolic_operand (op, mode))
- return 0;
-
- /* Also verify that it's not a TLS symbol. */
- str = XSTR (op, 0);
- return str[0] != '%' && str[0] != '@';
+ return !SYMBOL_REF_LOCAL_P (op) && !SYMBOL_REF_TLS_MODEL (op);
}
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
int
-call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+call_operand (rtx op, enum machine_mode mode)
{
if (mode != Pmode)
return 0;
@@ -1130,7 +977,7 @@ call_operand (op, mode)
{
if (TARGET_ABI_OSF)
{
- /* Disallow virtual registers to cope with pathalogical test cases
+ /* Disallow virtual registers to cope with pathological test cases
such as compile/930117-1.c in which the virtual reg decomposes
to the frame pointer. Which is a hard reg that is not $27. */
return (REGNO (op) == 27 || REGNO (op) > LAST_VIRTUAL_REGISTER);
@@ -1150,9 +997,7 @@ call_operand (op, mode)
possibly with an offset. */
int
-symbolic_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+symbolic_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
@@ -1169,14 +1014,8 @@ symbolic_operand (op, mode)
/* Return true if OP is valid for a particular TLS relocation. */
static int
-tls_symbolic_operand_1 (op, mode, size, unspec)
- rtx op;
- enum machine_mode mode;
- int size, unspec;
+tls_symbolic_operand_1 (rtx op, enum machine_mode mode, int size, int unspec)
{
- const char *str;
- int letter;
-
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
@@ -1190,32 +1029,35 @@ tls_symbolic_operand_1 (op, mode, size, unspec)
if (GET_CODE (op) != SYMBOL_REF)
return 0;
- str = XSTR (op, 0);
- if (str[0] == '%')
+ if (SYMBOL_REF_LOCAL_P (op))
{
- if (size != 64)
+ if (alpha_tls_size > size)
return 0;
}
- else if (str[0] == '@')
+ else
{
- if (alpha_tls_size > size)
+ if (size != 64)
return 0;
}
- else
- return 0;
-
- letter = (unspec == UNSPEC_DTPREL ? 'D' : 'T');
- return str[1] == letter;
+ switch (SYMBOL_REF_TLS_MODEL (op))
+ {
+ case TLS_MODEL_LOCAL_DYNAMIC:
+ return unspec == UNSPEC_DTPREL;
+ case TLS_MODEL_INITIAL_EXEC:
+ return unspec == UNSPEC_TPREL && size == 64;
+ case TLS_MODEL_LOCAL_EXEC:
+ return unspec == UNSPEC_TPREL;
+ default:
+ abort ();
+ }
}
/* Return true if OP is valid for 16-bit DTP relative relocations. */
int
-dtp16_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+dtp16_symbolic_operand (rtx op, enum machine_mode mode)
{
return tls_symbolic_operand_1 (op, mode, 16, UNSPEC_DTPREL);
}
@@ -1223,9 +1065,7 @@ dtp16_symbolic_operand (op, mode)
/* Return true if OP is valid for 32-bit DTP relative relocations. */
int
-dtp32_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+dtp32_symbolic_operand (rtx op, enum machine_mode mode)
{
return tls_symbolic_operand_1 (op, mode, 32, UNSPEC_DTPREL);
}
@@ -1233,9 +1073,7 @@ dtp32_symbolic_operand (op, mode)
/* Return true if OP is valid for 64-bit DTP relative relocations. */
int
-gotdtp_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gotdtp_symbolic_operand (rtx op, enum machine_mode mode)
{
return tls_symbolic_operand_1 (op, mode, 64, UNSPEC_DTPREL);
}
@@ -1243,9 +1081,7 @@ gotdtp_symbolic_operand (op, mode)
/* Return true if OP is valid for 16-bit TP relative relocations. */
int
-tp16_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+tp16_symbolic_operand (rtx op, enum machine_mode mode)
{
return tls_symbolic_operand_1 (op, mode, 16, UNSPEC_TPREL);
}
@@ -1253,9 +1089,7 @@ tp16_symbolic_operand (op, mode)
/* Return true if OP is valid for 32-bit TP relative relocations. */
int
-tp32_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+tp32_symbolic_operand (rtx op, enum machine_mode mode)
{
return tls_symbolic_operand_1 (op, mode, 32, UNSPEC_TPREL);
}
@@ -1263,9 +1097,7 @@ tp32_symbolic_operand (op, mode)
/* Return true if OP is valid for 64-bit TP relative relocations. */
int
-gottp_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gottp_symbolic_operand (rtx op, enum machine_mode mode)
{
return tls_symbolic_operand_1 (op, mode, 64, UNSPEC_TPREL);
}
@@ -1274,9 +1106,7 @@ gottp_symbolic_operand (op, mode)
comparisons are valid in which insn. */
int
-alpha_comparison_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+alpha_comparison_operator (rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
@@ -1291,9 +1121,7 @@ alpha_comparison_operator (op, mode)
Here we know which comparisons are valid in which insn. */
int
-alpha_zero_comparison_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+alpha_zero_comparison_operator (rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
@@ -1307,9 +1135,7 @@ alpha_zero_comparison_operator (op, mode)
/* Return 1 if OP is a valid Alpha swapped comparison operator. */
int
-alpha_swapped_comparison_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+alpha_swapped_comparison_operator (rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
@@ -1325,9 +1151,7 @@ alpha_swapped_comparison_operator (op, mode)
/* Return 1 if OP is a signed comparison operation. */
int
-signed_comparison_operator (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+signed_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
@@ -1343,9 +1167,7 @@ signed_comparison_operator (op, mode)
Here we know which comparisons are valid in which insn. */
int
-alpha_fp_comparison_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+alpha_fp_comparison_operator (rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
@@ -1358,20 +1180,21 @@ alpha_fp_comparison_operator (op, mode)
/* Return 1 if this is a divide or modulus operator. */
int
-divmod_operator (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+divmod_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- switch (GET_CODE (op))
- {
- case DIV: case MOD: case UDIV: case UMOD:
- return 1;
+ enum rtx_code code = GET_CODE (op);
- default:
- break;
- }
+ return (code == DIV || code == MOD || code == UDIV || code == UMOD);
+}
- return 0;
+/* Return 1 if this is a float->int conversion operator. */
+
+int
+fix_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ enum rtx_code code = GET_CODE (op);
+
+ return (code == FIX || code == UNSIGNED_FIX);
}
/* Return 1 if this memory address is a known aligned register plus
@@ -1381,9 +1204,7 @@ divmod_operator (op, mode)
Take into account what reload will do. */
int
-aligned_memory_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+aligned_memory_operand (rtx op, enum machine_mode mode)
{
rtx base;
@@ -1401,9 +1222,10 @@ aligned_memory_operand (op, mode)
}
}
- if (GET_CODE (op) != MEM
- || GET_MODE (op) != mode)
+ if (GET_CODE (op) != MEM)
return 0;
+ if (MEM_ALIGN (op) >= 32)
+ return 1;
op = XEXP (op, 0);
/* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo)
@@ -1425,9 +1247,7 @@ aligned_memory_operand (op, mode)
/* Similar, but return 1 if OP is a MEM which is not alignable. */
int
-unaligned_memory_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+unaligned_memory_operand (rtx op, enum machine_mode mode)
{
rtx base;
@@ -1445,8 +1265,9 @@ unaligned_memory_operand (op, mode)
}
}
- if (GET_CODE (op) != MEM
- || GET_MODE (op) != mode)
+ if (GET_CODE (op) != MEM)
+ return 0;
+ if (MEM_ALIGN (op) >= 32)
return 0;
op = XEXP (op, 0);
@@ -1469,9 +1290,7 @@ unaligned_memory_operand (op, mode)
/* Return 1 if OP is either a register or an unaligned memory location. */
int
-reg_or_unaligned_mem_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_unaligned_mem_operand (rtx op, enum machine_mode mode)
{
return register_operand (op, mode) || unaligned_memory_operand (op, mode);
}
@@ -1479,9 +1298,7 @@ reg_or_unaligned_mem_operand (op, mode)
/* Return 1 if OP is any memory location. During reload a pseudo matches. */
int
-any_memory_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+any_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == MEM
|| (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
@@ -1504,9 +1321,7 @@ any_memory_operand (op, mode)
preventing combine from making the optimization. */
int
-reg_not_elim_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+reg_not_elim_operand (rtx op, enum machine_mode mode)
{
rtx inner = op;
if (GET_CODE (op) == SUBREG)
@@ -1522,9 +1337,7 @@ reg_not_elim_operand (op, mode)
will do. */
int
-normal_memory_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+normal_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (reload_in_progress)
{
@@ -1551,9 +1364,7 @@ normal_memory_operand (op, mode)
int->fp conversion. */
int
-reg_no_subreg_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+reg_no_subreg_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != REG)
return 0;
@@ -1565,9 +1376,7 @@ reg_no_subreg_operand (op, mode)
elimination. */
int
-addition_operation (op, mode)
- register rtx op;
- enum machine_mode mode;
+addition_operation (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return 0;
@@ -1583,9 +1392,7 @@ addition_operation (op, mode)
the range defined for C in [I-P]. */
bool
-alpha_const_ok_for_letter_p (value, c)
- HOST_WIDE_INT value;
- int c;
+alpha_const_ok_for_letter_p (HOST_WIDE_INT value, int c)
{
switch (c)
{
@@ -1624,9 +1431,7 @@ alpha_const_ok_for_letter_p (value, c)
matches for C in [GH]. */
bool
-alpha_const_double_ok_for_letter_p (value, c)
- rtx value;
- int c;
+alpha_const_double_ok_for_letter_p (rtx value, int c)
{
switch (c)
{
@@ -1650,9 +1455,7 @@ alpha_const_double_ok_for_letter_p (value, c)
matches for C. */
bool
-alpha_extra_constraint (value, c)
- rtx value;
- int c;
+alpha_extra_constraint (rtx value, int c)
{
switch (c)
{
@@ -1678,7 +1481,7 @@ alpha_extra_constraint (value, c)
/* Return 1 if this function can directly return via $26. */
int
-direct_return ()
+direct_return (void)
{
return (! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK
&& reload_completed
@@ -1691,8 +1494,7 @@ direct_return ()
/* Return the ADDR_VEC associated with a tablejump insn. */
rtx
-alpha_tablejump_addr_vec (insn)
- rtx insn;
+alpha_tablejump_addr_vec (rtx insn)
{
rtx tmp;
@@ -1711,8 +1513,7 @@ alpha_tablejump_addr_vec (insn)
/* Return the label of the predicted edge, or CONST0_RTX if we don't know. */
rtx
-alpha_tablejump_best_label (insn)
- rtx insn;
+alpha_tablejump_best_label (rtx insn)
{
rtx jump_table = alpha_tablejump_addr_vec (insn);
rtx best_label = NULL_RTX;
@@ -1746,77 +1547,58 @@ alpha_tablejump_best_label (insn)
/* Return the TLS model to use for SYMBOL. */
static enum tls_model
-tls_symbolic_operand_type (symbol)
- rtx symbol;
+tls_symbolic_operand_type (rtx symbol)
{
- const char *str;
+ enum tls_model model;
if (GET_CODE (symbol) != SYMBOL_REF)
return 0;
- str = XSTR (symbol, 0);
+ model = SYMBOL_REF_TLS_MODEL (symbol);
- if (str[0] == '%')
- {
- /* ??? Be prepared for -ftls-model=local-dynamic. Perhaps we shouldn't
- have separately encoded local-ness. On well, maybe the user will use
- attribute visibility next time. At least we don't crash... */
- if (str[1] == 'G' || str[1] == 'D')
- return TLS_MODEL_GLOBAL_DYNAMIC;
- if (str[1] == 'T')
- return TLS_MODEL_INITIAL_EXEC;
- }
- else if (str[0] == '@')
- {
- if (str[1] == 'D')
- {
- /* Local dynamic is a waste if we're not going to combine
- the __tls_get_addr calls. So avoid it if not optimizing. */
- if (optimize)
- return TLS_MODEL_LOCAL_DYNAMIC;
- else
- return TLS_MODEL_GLOBAL_DYNAMIC;
- }
- if (str[1] == 'T')
- {
- /* 64-bit local exec is the same as initial exec except without
- the dynamic relocation. In either case we use a got entry. */
- if (alpha_tls_size == 64)
- return TLS_MODEL_INITIAL_EXEC;
- else
- return TLS_MODEL_LOCAL_EXEC;
- }
- }
+ /* Local-exec with a 64-bit size is the same code as initial-exec. */
+ if (model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64)
+ model = TLS_MODEL_INITIAL_EXEC;
- return 0;
+ return model;
}
-
-/* Return true if the function DECL will be placed in the default text
- section. */
-/* ??? Ideally we'd be able to always move from a SYMBOL_REF back to the
- decl, as that would allow us to determine if two functions are in the
- same section, which is what we really want to know. */
+/* Return true if the function DECL will share the same GP as any
+ function in the current unit of translation. */
static bool
-decl_in_text_section (decl)
- tree decl;
+decl_has_samegp (tree decl)
{
- return (DECL_SECTION_NAME (decl) == NULL_TREE
- && ! (flag_function_sections
- || (targetm.have_named_sections
- && DECL_ONE_ONLY (decl))));
+ /* Functions that are not local can be overridden, and thus may
+ not share the same gp. */
+ if (!(*targetm.binds_local_p) (decl))
+ return false;
+
+ /* If -msmall-data is in effect, assume that there is only one GP
+ for the module, and so any local symbol has this property. We
+ need explicit relocations to be able to enforce this for symbols
+ not defined in this unit of translation, however. */
+ if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA)
+ return true;
+
+ /* Functions that are not external are defined in this UoT. */
+ /* ??? Irritatingly, static functions not yet emitted are still
+ marked "external". Apply this to non-static functions only. */
+ return !TREE_PUBLIC (decl) || !DECL_EXTERNAL (decl);
}
/* Return true if EXP should be placed in the small data section. */
static bool
-alpha_in_small_data_p (exp)
- tree exp;
+alpha_in_small_data_p (tree exp)
{
/* We want to merge strings, so we never consider them small data. */
if (TREE_CODE (exp) == STRING_CST)
return false;
+ /* Functions are never in the small data area. Duh. */
+ if (TREE_CODE (exp) == FUNCTION_DECL)
+ return false;
+
if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
{
const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
@@ -1830,136 +1612,16 @@ alpha_in_small_data_p (exp)
/* If this is an incomplete type with size 0, then we can't put it
in sdata because it might be too big when completed. */
- if (size > 0 && size <= g_switch_value)
+ if (size > 0 && (unsigned HOST_WIDE_INT) size <= g_switch_value)
return true;
}
return false;
}
-/* If we are referencing a function that is static, make the SYMBOL_REF
- special. We use this to see indicate we can branch to this function
- without setting PV or restoring GP.
-
- If this is a variable that is known to be defined locally, add "@v"
- to the name. If in addition the variable is to go in .sdata/.sbss,
- then add "@s" instead. */
-
-static void
-alpha_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
-{
- const char *symbol_str;
- bool is_local;
- char encoding = 0;
- rtx rtl, symbol;
-
- rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
-
- /* Careful not to prod global register variables. */
- if (GET_CODE (rtl) != MEM)
- return;
- symbol = XEXP (rtl, 0);
- if (GET_CODE (symbol) != SYMBOL_REF)
- return;
-
- if (TREE_CODE (decl) == FUNCTION_DECL)
- {
- /* We mark public functions once they are emitted; otherwise we
- don't know that they exist in this unit of translation. */
- if (TREE_PUBLIC (decl))
- return;
-
- /* Do not mark functions that are not in .text; otherwise we
- don't know that they are near enough for a direct branch. */
- if (! decl_in_text_section (decl))
- return;
-
- SYMBOL_REF_FLAG (symbol) = 1;
- return;
- }
-
- /* Early out if we're not going to do anything with this data. */
- if (! TARGET_EXPLICIT_RELOCS)
- return;
-
- symbol_str = XSTR (symbol, 0);
-
- /* A variable is considered "local" if it is defined in this module. */
- is_local = (*targetm.binds_local_p) (decl);
-
- /* Care for TLS variables. */
- if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
- {
- switch (decl_tls_model (decl))
- {
- case TLS_MODEL_GLOBAL_DYNAMIC:
- encoding = 'G';
- break;
- case TLS_MODEL_LOCAL_DYNAMIC:
- encoding = 'D';
- break;
- case TLS_MODEL_INITIAL_EXEC:
- case TLS_MODEL_LOCAL_EXEC:
- encoding = 'T';
- break;
- }
- }
- else if (is_local)
- {
- /* Determine if DECL will wind up in .sdata/.sbss. */
- if (alpha_in_small_data_p (decl))
- encoding = 'S';
- else
- encoding = 'L';
- }
-
- /* Finally, encode this into the symbol string. */
- if (encoding)
- {
- char *newstr;
- size_t len;
- char want_prefix = (is_local ? '@' : '%');
- char other_prefix = (is_local ? '%' : '@');
-
- if (symbol_str[0] == want_prefix)
- {
- if (symbol_str[1] == encoding)
- return;
- symbol_str += 2;
- }
- else if (symbol_str[0] == other_prefix)
- symbol_str += 2;
-
- len = strlen (symbol_str) + 1;
- newstr = alloca (len + 2);
-
- newstr[0] = want_prefix;
- newstr[1] = encoding;
- memcpy (newstr + 2, symbol_str, len);
-
- XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2 - 1);
- }
-}
-
-/* Undo the effects of the above. */
-
-static const char *
-alpha_strip_name_encoding (str)
- const char *str;
-{
- if (str[0] == '@' || str[0] == '%')
- str += 2;
- if (str[0] == '*')
- str++;
- return str;
-}
-
#if TARGET_ABI_OPEN_VMS
static bool
-alpha_linkage_symbol_p (symname)
- const char *symname;
+alpha_linkage_symbol_p (const char *symname)
{
int symlen = strlen (symname);
@@ -1988,10 +1650,7 @@ alpha_linkage_symbol_p (symname)
low-order three bits; this is an "unaligned" access. */
bool
-alpha_legitimate_address_p (mode, x, strict)
- enum machine_mode mode;
- rtx x;
- int strict;
+alpha_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
{
/* If this is an ldq_u type address, discard the outer AND. */
if (mode == DImode
@@ -2087,14 +1746,24 @@ alpha_legitimate_address_p (mode, x, strict)
return false;
}
+/* Build the SYMBOL_REF for __tls_get_addr. */
+
+static GTY(()) rtx tls_get_addr_libfunc;
+
+static rtx
+get_tls_get_addr (void)
+{
+ if (!tls_get_addr_libfunc)
+ tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
+ return tls_get_addr_libfunc;
+}
+
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address. */
rtx
-alpha_legitimize_address (x, scratch, mode)
- rtx x;
- rtx scratch;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+alpha_legitimize_address (rtx x, rtx scratch,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT addend;
@@ -2154,7 +1823,7 @@ alpha_legitimize_address (x, scratch, mode)
r0 = gen_rtx_REG (Pmode, 0);
r16 = gen_rtx_REG (Pmode, 16);
- tga = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_addr");
+ tga = get_tls_get_addr ();
dest = gen_reg_rtx (Pmode);
seq = GEN_INT (alpha_next_sequence_number++);
@@ -2175,7 +1844,7 @@ alpha_legitimize_address (x, scratch, mode)
r0 = gen_rtx_REG (Pmode, 0);
r16 = gen_rtx_REG (Pmode, 16);
- tga = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_addr");
+ tga = get_tls_get_addr ();
scratch = gen_reg_rtx (Pmode);
seq = GEN_INT (alpha_next_sequence_number++);
@@ -2278,23 +1947,30 @@ alpha_legitimize_address (x, scratch, mode)
}
}
+/* We do not allow indirect calls to be optimized into sibling calls, nor
+ can we allow a call to a function with a different GP to be optimized
+ into a sibcall. */
+
+static bool
+alpha_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
+{
+ /* Can't do indirect tail calls, since we don't know if the target
+ uses the same GP. */
+ if (!decl)
+ return false;
+
+ /* Otherwise, we can make a tail call if the target function shares
+ the same GP. */
+ return decl_has_samegp (decl);
+}
+
/* For TARGET_EXPLICIT_RELOCS, we don't obfuscate a SYMBOL_REF to a
small symbolic operand until after reload. At which point we need
to replace (mem (symbol_ref)) with (mem (lo_sum $29 symbol_ref))
so that sched2 has the proper dependency information. */
-int
-some_small_symbolic_operand (x, mode)
- rtx x;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return for_each_rtx (&x, some_small_symbolic_operand_1, NULL);
-}
-
static int
-some_small_symbolic_operand_1 (px, data)
- rtx *px;
- void *data ATTRIBUTE_UNUSED;
+some_small_symbolic_operand_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
{
rtx x = *px;
@@ -2305,19 +1981,14 @@ some_small_symbolic_operand_1 (px, data)
return small_symbolic_operand (x, Pmode) != 0;
}
-rtx
-split_small_symbolic_operand (x)
- rtx x;
+int
+some_small_symbolic_operand (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- x = copy_insn (x);
- for_each_rtx (&x, split_small_symbolic_operand_1, NULL);
- return x;
+ return for_each_rtx (&x, some_small_symbolic_operand_1, NULL);
}
static int
-split_small_symbolic_operand_1 (px, data)
- rtx *px;
- void *data ATTRIBUTE_UNUSED;
+split_small_symbolic_operand_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
{
rtx x = *px;
@@ -2335,16 +2006,48 @@ split_small_symbolic_operand_1 (px, data)
return 0;
}
+rtx
+split_small_symbolic_operand (rtx x)
+{
+ x = copy_insn (x);
+ for_each_rtx (&x, split_small_symbolic_operand_1, NULL);
+ return x;
+}
+
+/* Indicate that INSN cannot be duplicated. This is true for any insn
+ that we've marked with gpdisp relocs, since those have to stay in
+ 1-1 correspondence with one another.
+
+ Technically we could copy them if we could set up a mapping from one
+ sequence number to another, across the set of insns to be duplicated.
+ This seems overly complicated and error-prone since interblock motion
+ from sched-ebb could move one of the pair of insns to a different block.
+
+ Also cannot allow jsr insns to be duplicated. If they throw exceptions,
+ then they'll be in a different block from their ldgp. Which could lead
+ the bb reorder code to think that it would be ok to copy just the block
+ containing the call and branch to the block containing the ldgp. */
+
+static bool
+alpha_cannot_copy_insn_p (rtx insn)
+{
+ if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
+ return false;
+ if (recog_memoized (insn) >= 0)
+ return get_attr_cannot_copy (insn);
+ else
+ return false;
+}
+
+
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and return the new rtx. */
rtx
-alpha_legitimize_reload_address (x, mode, opnum, type, ind_levels)
- rtx x;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int opnum;
- int type;
- int ind_levels ATTRIBUTE_UNUSED;
+alpha_legitimize_reload_address (rtx x,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int opnum, int type,
+ int ind_levels ATTRIBUTE_UNUSED)
{
/* We must recognize output that we have already generated ourselves. */
if (GET_CODE (x) == PLUS
@@ -2393,15 +2096,154 @@ alpha_legitimize_reload_address (x, mode, opnum, type, ind_levels)
return NULL_RTX;
}
+/* Compute a (partial) cost for rtx X. Return true if the complete
+ cost has been computed, and false if subexpressions should be
+ scanned. In either case, *TOTAL contains the cost result. */
+
+static bool
+alpha_rtx_costs (rtx x, int code, int outer_code, int *total)
+{
+ enum machine_mode mode = GET_MODE (x);
+ bool float_mode_p = FLOAT_MODE_P (mode);
+
+ switch (code)
+ {
+ /* If this is an 8-bit constant, return zero since it can be used
+ nearly anywhere with no cost. If it is a valid operand for an
+ ADD or AND, likewise return 0 if we know it will be used in that
+ context. Otherwise, return 2 since it might be used there later.
+ All other constants take at least two insns. */
+ case CONST_INT:
+ if (INTVAL (x) >= 0 && INTVAL (x) < 256)
+ {
+ *total = 0;
+ return true;
+ }
+ /* FALLTHRU */
+
+ case CONST_DOUBLE:
+ if (x == CONST0_RTX (mode))
+ *total = 0;
+ else if ((outer_code == PLUS && add_operand (x, VOIDmode))
+ || (outer_code == AND && and_operand (x, VOIDmode)))
+ *total = 0;
+ else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode))
+ *total = 2;
+ else
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case CONST:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode))
+ *total = COSTS_N_INSNS (outer_code != MEM);
+ else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode))
+ *total = COSTS_N_INSNS (1 + (outer_code != MEM));
+ else if (tls_symbolic_operand_type (x))
+ /* Estimate of cost for call_pal rduniq. */
+ *total = COSTS_N_INSNS (15);
+ else
+ /* Otherwise we do a load from the GOT. */
+ *total = COSTS_N_INSNS (alpha_memory_latency);
+ return true;
+
+ case PLUS:
+ case MINUS:
+ if (float_mode_p)
+ *total = alpha_rtx_cost_data[alpha_cpu].fp_add;
+ else if (GET_CODE (XEXP (x, 0)) == MULT
+ && const48_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
+ {
+ *total = (rtx_cost (XEXP (XEXP (x, 0), 0), outer_code)
+ + rtx_cost (XEXP (x, 1), outer_code) + 2);
+ return true;
+ }
+ return false;
+
+ case MULT:
+ if (float_mode_p)
+ *total = alpha_rtx_cost_data[alpha_cpu].fp_mult;
+ else if (mode == DImode)
+ *total = alpha_rtx_cost_data[alpha_cpu].int_mult_di;
+ else
+ *total = alpha_rtx_cost_data[alpha_cpu].int_mult_si;
+ return false;
+
+ case ASHIFT:
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && INTVAL (XEXP (x, 1)) <= 3)
+ {
+ *total = COSTS_N_INSNS (1);
+ return false;
+ }
+ /* FALLTHRU */
+
+ case ASHIFTRT:
+ case LSHIFTRT:
+ *total = alpha_rtx_cost_data[alpha_cpu].int_shift;
+ return false;
+
+ case IF_THEN_ELSE:
+ if (float_mode_p)
+ *total = alpha_rtx_cost_data[alpha_cpu].fp_add;
+ else
+ *total = alpha_rtx_cost_data[alpha_cpu].int_cmov;
+ return false;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ if (!float_mode_p)
+ *total = COSTS_N_INSNS (70); /* ??? */
+ else if (mode == SFmode)
+ *total = alpha_rtx_cost_data[alpha_cpu].fp_div_sf;
+ else
+ *total = alpha_rtx_cost_data[alpha_cpu].fp_div_df;
+ return false;
+
+ case MEM:
+ *total = COSTS_N_INSNS (alpha_memory_latency);
+ return true;
+
+ case NEG:
+ if (! float_mode_p)
+ {
+ *total = COSTS_N_INSNS (1);
+ return false;
+ }
+ /* FALLTHRU */
+
+ case ABS:
+ if (! float_mode_p)
+ {
+ *total = COSTS_N_INSNS (1) + alpha_rtx_cost_data[alpha_cpu].int_cmov;
+ return false;
+ }
+ /* FALLTHRU */
+
+ case FLOAT:
+ case UNSIGNED_FLOAT:
+ case FIX:
+ case UNSIGNED_FIX:
+ case FLOAT_EXTEND:
+ case FLOAT_TRUNCATE:
+ *total = alpha_rtx_cost_data[alpha_cpu].fp_add;
+ return false;
+
+ default:
+ return false;
+ }
+}
+
/* REF is an alignable memory location. Place an aligned SImode
reference into *PALIGNED_MEM and the number of bits to shift into
*PBITNUM. SCRATCH is a free register for use in reloading out
of range stack slots. */
void
-get_aligned_mem (ref, paligned_mem, pbitnum)
- rtx ref;
- rtx *paligned_mem, *pbitnum;
+get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum)
{
rtx base;
HOST_WIDE_INT offset = 0;
@@ -2439,9 +2281,7 @@ get_aligned_mem (ref, paligned_mem, pbitnum)
Add EXTRA_OFFSET to the address we return. */
rtx
-get_unaligned_address (ref, extra_offset)
- rtx ref;
- int extra_offset;
+get_unaligned_address (rtx ref, int extra_offset)
{
rtx base;
HOST_WIDE_INT offset = 0;
@@ -2474,9 +2314,7 @@ get_unaligned_address (ref, extra_offset)
symbolic constants cannot be dropped to memory. */
enum reg_class
-alpha_preferred_reload_class(x, class)
- rtx x;
- enum reg_class class;
+alpha_preferred_reload_class(rtx x, enum reg_class class)
{
/* Zero is present in any register class. */
if (x == CONST0_RTX (GET_MODE (x)))
@@ -2513,11 +2351,8 @@ alpha_preferred_reload_class(x, class)
from register elimination into a DImode fp register. */
enum reg_class
-secondary_reload_class (class, mode, x, in)
- enum reg_class class;
- enum machine_mode mode;
- rtx x;
- int in;
+secondary_reload_class (enum reg_class class, enum machine_mode mode,
+ rtx x, int in)
{
if ((mode == QImode || mode == HImode) && ! TARGET_BWX)
{
@@ -2555,9 +2390,7 @@ secondary_reload_class (class, mode, x, in)
found in part of X. */
static void
-alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
- rtx x;
- int in_struct_p, volatile_p, unchanging_p;
+alpha_set_memflags_1 (rtx x, int in_struct_p, int volatile_p, int unchanging_p)
{
int i;
@@ -2607,9 +2440,7 @@ alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p)
a MEM, don't do anything. */
void
-alpha_set_memflags (insn, ref)
- rtx insn;
- rtx ref;
+alpha_set_memflags (rtx insn, rtx ref)
{
int in_struct_p, volatile_p, unchanging_p;
@@ -2629,62 +2460,11 @@ alpha_set_memflags (insn, ref)
alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p);
}
-/* 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. */
-
-rtx
-alpha_emit_set_const (target, mode, c, n)
- rtx target;
- enum machine_mode mode;
- HOST_WIDE_INT c;
- int n;
-{
- rtx result = 0;
- rtx orig_target = target;
- int i;
-
- /* If we can't make any pseudos, TARGET is an SImode hard register, we
- can't load this constant in one insn, do this in DImode. */
- if (no_new_pseudos && mode == SImode
- && GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER
- && (result = alpha_emit_set_const_1 (target, mode, c, 1)) == 0)
- {
- target = gen_lowpart (DImode, target);
- mode = DImode;
- }
-
- /* Try 1 insn, then 2, then up to N. */
- for (i = 1; i <= n; i++)
- {
- result = alpha_emit_set_const_1 (target, mode, c, i);
- if (result)
- {
- rtx insn = get_last_insn ();
- rtx set = single_set (insn);
- if (! CONSTANT_P (SET_SRC (set)))
- set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c));
- break;
- }
- }
-
- /* Allow for the case where we changed the mode of TARGET. */
- if (result == target)
- result = orig_target;
-
- return result;
-}
-
-/* Internal routine for the above to check for N or below insns. */
+/* Internal routine for alpha_emit_set_const to check for N or below insns. */
static rtx
-alpha_emit_set_const_1 (target, mode, c, n)
- rtx target;
- enum machine_mode mode;
- HOST_WIDE_INT c;
- int n;
+alpha_emit_set_const_1 (rtx target, enum machine_mode mode,
+ HOST_WIDE_INT c, int n)
{
HOST_WIDE_INT new;
int i, bits;
@@ -2730,7 +2510,14 @@ alpha_emit_set_const_1 (target, mode, c, n)
}
else if (n >= 2 + (extra != 0))
{
- temp = copy_to_suggested_reg (GEN_INT (high << 16), subtarget, mode);
+ if (no_new_pseudos)
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (high << 16)));
+ temp = target;
+ }
+ else
+ temp = copy_to_suggested_reg (GEN_INT (high << 16),
+ subtarget, mode);
/* As of 2002-02-23, addsi3 is only available when not optimizing.
This means that if we go through expand_binop, we'll try to
@@ -2866,15 +2653,58 @@ alpha_emit_set_const_1 (target, mode, c, n)
return 0;
}
+/* Try to output insns to set TARGET equal to the constant C if it can be
+ done in less than N insns. Do all computations in MODE. Returns the place
+ where the output has been placed if it can be done and the insns have been
+ emitted. If it would take more than N insns, zero is returned and no
+ insns and emitted. */
+
+rtx
+alpha_emit_set_const (rtx target, enum machine_mode mode,
+ HOST_WIDE_INT c, int n)
+{
+ rtx result = 0;
+ rtx orig_target = target;
+ int i;
+
+ /* If we can't make any pseudos, TARGET is an SImode hard register, we
+ can't load this constant in one insn, do this in DImode. */
+ if (no_new_pseudos && mode == SImode
+ && GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER
+ && (result = alpha_emit_set_const_1 (target, mode, c, 1)) == 0)
+ {
+ target = gen_lowpart (DImode, target);
+ mode = DImode;
+ }
+
+ /* Try 1 insn, then 2, then up to N. */
+ for (i = 1; i <= n; i++)
+ {
+ result = alpha_emit_set_const_1 (target, mode, c, i);
+ if (result)
+ {
+ rtx insn = get_last_insn ();
+ rtx set = single_set (insn);
+ if (! CONSTANT_P (SET_SRC (set)))
+ set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c));
+ break;
+ }
+ }
+
+ /* Allow for the case where we changed the mode of TARGET. */
+ if (result == target)
+ result = orig_target;
+
+ return result;
+}
+
/* Having failed to find a 3 insn sequence in alpha_emit_set_const,
fall back to a straight forward decomposition. We do this to avoid
exponential run times encountered when looking for longer sequences
with alpha_emit_set_const. */
rtx
-alpha_emit_set_long_const (target, c1, c2)
- rtx target;
- HOST_WIDE_INT c1, c2;
+alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
{
HOST_WIDE_INT d1, d2, d3, d4;
@@ -2931,9 +2761,7 @@ alpha_emit_set_long_const (target, c1, c2)
We don't handle non-bwx subword loads here. */
bool
-alpha_expand_mov (mode, operands)
- enum machine_mode mode;
- rtx *operands;
+alpha_expand_mov (enum machine_mode mode, rtx *operands)
{
/* If the output is not a register, the input must be. */
if (GET_CODE (operands[0]) == MEM
@@ -2949,8 +2777,12 @@ alpha_expand_mov (mode, operands)
compiled at the end of compilation. In the meantime, someone can
re-encode-section-info on some symbol changing it e.g. from global
to local-not-small. If this happens, we'd have emitted a plain
- load rather than a high+losum load and not recognize the insn. */
- if (TARGET_EXPLICIT_RELOCS
+ load rather than a high+losum load and not recognize the insn.
+
+ So if rtl inlining is in effect, we delay the global/not-global
+ decision until rest_of_compilation by wrapping it in an
+ UNSPEC_SYMBOL. */
+ if (TARGET_EXPLICIT_RELOCS && flag_inline_functions
&& rtx_equal_function_value_matters
&& global_symbolic_operand (operands[1], mode))
{
@@ -3027,9 +2859,7 @@ alpha_expand_mov (mode, operands)
return true if all work is done. */
bool
-alpha_expand_mov_nobwx (mode, operands)
- enum machine_mode mode;
- rtx *operands;
+alpha_expand_mov_nobwx (enum machine_mode mode, rtx *operands)
{
/* If the output is not a register, the input must be. */
if (GET_CODE (operands[0]) == MEM)
@@ -3062,13 +2892,24 @@ alpha_expand_mov_nobwx (mode, operands)
{
rtx aligned_mem, bitnum;
rtx scratch = gen_reg_rtx (SImode);
+ rtx subtarget;
+ bool copyout;
get_aligned_mem (operands[1], &aligned_mem, &bitnum);
+ subtarget = operands[0];
+ if (GET_CODE (subtarget) == REG)
+ subtarget = gen_lowpart (DImode, subtarget), copyout = false;
+ else
+ subtarget = gen_reg_rtx (DImode), copyout = true;
+
emit_insn ((mode == QImode
? gen_aligned_loadqi
: gen_aligned_loadhi)
- (operands[0], aligned_mem, bitnum, scratch));
+ (subtarget, aligned_mem, bitnum, scratch));
+
+ if (copyout)
+ emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
}
}
else
@@ -3077,16 +2918,28 @@ alpha_expand_mov_nobwx (mode, operands)
code depend on parameter evaluation order which will cause
bootstrap failures. */
- rtx temp1 = gen_reg_rtx (DImode);
- rtx temp2 = gen_reg_rtx (DImode);
- rtx seq = ((mode == QImode
- ? gen_unaligned_loadqi
- : gen_unaligned_loadhi)
- (operands[0], get_unaligned_address (operands[1], 0),
- temp1, temp2));
+ rtx temp1, temp2, seq, subtarget;
+ bool copyout;
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+
+ subtarget = operands[0];
+ if (GET_CODE (subtarget) == REG)
+ subtarget = gen_lowpart (DImode, subtarget), copyout = false;
+ else
+ subtarget = gen_reg_rtx (DImode), copyout = true;
+
+ seq = ((mode == QImode
+ ? gen_unaligned_loadqi
+ : gen_unaligned_loadhi)
+ (subtarget, get_unaligned_address (operands[1], 0),
+ temp1, temp2));
alpha_set_memflags (seq, operands[1]);
emit_insn (seq);
+
+ if (copyout)
+ emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
}
return true;
}
@@ -3182,8 +3035,7 @@ alpha_expand_mov_nobwx (mode, operands)
much lower minimum execution time. */
void
-alpha_emit_floatuns (operands)
- rtx operands[2];
+alpha_emit_floatuns (rtx operands[2])
{
rtx neglab, donelab, i0, i1, f0, in, out;
enum machine_mode mode;
@@ -3217,8 +3069,7 @@ alpha_emit_floatuns (operands)
/* Generate the comparison for a conditional branch. */
rtx
-alpha_emit_conditional_branch (code)
- enum rtx_code code;
+alpha_emit_conditional_branch (enum rtx_code code)
{
enum rtx_code cmp_code, branch_code;
enum machine_mode cmp_mode, branch_mode = VOIDmode;
@@ -3374,8 +3225,7 @@ alpha_emit_conditional_branch (code)
valid. Return the final comparison, or NULL if we can't work. */
rtx
-alpha_emit_setcc (code)
- enum rtx_code code;
+alpha_emit_setcc (enum rtx_code code)
{
enum rtx_code cmp_code;
rtx op0 = alpha_compare.op0, op1 = alpha_compare.op1;
@@ -3486,10 +3336,9 @@ alpha_emit_setcc (code)
If both of the operands that set cc0 are nonzero we must emit
an insn to perform the compare (it can't be done within
the conditional move). */
+
rtx
-alpha_emit_conditional_move (cmp, mode)
- rtx cmp;
- enum machine_mode mode;
+alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (cmp);
enum rtx_code cmov_code = NE;
@@ -3624,9 +3473,8 @@ alpha_emit_conditional_move (cmp, mode)
cases we wouldn't have before cse. */
int
-alpha_split_conditional_move (code, dest, cond, t_rtx, f_rtx)
- enum rtx_code code;
- rtx dest, cond, t_rtx, f_rtx;
+alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond,
+ rtx t_rtx, rtx f_rtx)
{
HOST_WIDE_INT t, f, diff;
enum machine_mode mode;
@@ -3659,7 +3507,7 @@ alpha_split_conditional_move (code, dest, cond, t_rtx, f_rtx)
be shared. */
if (f == 0 && exact_log2 (diff) > 0
- /* On EV6, we've got enough shifters to make non-arithmatic shifts
+ /* On EV6, we've got enough shifters to make non-arithmetic shifts
viable over a longer latency cmove. On EV5, the E0 slot is a
scarce resource, and on EV4 shift has the same latency as a cmove. */
&& (diff <= 8 || alpha_cpu == PROCESSOR_EV6))
@@ -3711,8 +3559,7 @@ alpha_split_conditional_move (code, dest, cond, t_rtx, f_rtx)
given operation. */
static const char *
-alpha_lookup_xfloating_lib_func (code)
- enum rtx_code code;
+alpha_lookup_xfloating_lib_func (enum rtx_code code)
{
struct xfloating_op
{
@@ -3798,9 +3645,8 @@ alpha_lookup_xfloating_lib_func (code)
Compute that here. */
static int
-alpha_compute_xfloating_mode_arg (code, round)
- enum rtx_code code;
- enum alpha_fp_rounding_mode round;
+alpha_compute_xfloating_mode_arg (enum rtx_code code,
+ enum alpha_fp_rounding_mode round)
{
int mode;
@@ -3844,12 +3690,8 @@ alpha_compute_xfloating_mode_arg (code, round)
*/
static void
-alpha_emit_xfloating_libcall (func, target, operands, noperands, equiv)
- const char *func;
- rtx target;
- rtx operands[];
- int noperands;
- rtx equiv;
+alpha_emit_xfloating_libcall (const char *func, rtx target, rtx operands[],
+ int noperands, rtx equiv)
{
rtx usage = NULL_RTX, tmp, reg;
int regno = 16, i;
@@ -3902,7 +3744,7 @@ alpha_emit_xfloating_libcall (func, target, operands, noperands, equiv)
abort ();
}
- tmp = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, (char *) func));
+ tmp = gen_rtx_MEM (QImode, init_one_libfunc (func));
tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
const0_rtx, const0_rtx));
CALL_INSN_FUNCTION_USAGE (tmp) = usage;
@@ -3916,9 +3758,7 @@ alpha_emit_xfloating_libcall (func, target, operands, noperands, equiv)
/* Emit an X_floating library function call for arithmetic (+,-,*,/). */
void
-alpha_emit_xfloating_arith (code, operands)
- enum rtx_code code;
- rtx operands[];
+alpha_emit_xfloating_arith (enum rtx_code code, rtx operands[])
{
const char *func;
int mode;
@@ -3938,9 +3778,7 @@ alpha_emit_xfloating_arith (code, operands)
/* Emit an X_floating library function call for a comparison. */
static rtx
-alpha_emit_xfloating_compare (code, op0, op1)
- enum rtx_code code;
- rtx op0, op1;
+alpha_emit_xfloating_compare (enum rtx_code code, rtx op0, rtx op1)
{
const char *func;
rtx out, operands[2];
@@ -3962,13 +3800,15 @@ alpha_emit_xfloating_compare (code, op0, op1)
/* Emit an X_floating library function call for a conversion. */
void
-alpha_emit_xfloating_cvt (code, operands)
- enum rtx_code code;
- rtx operands[];
+alpha_emit_xfloating_cvt (enum rtx_code orig_code, rtx operands[])
{
int noperands = 1, mode;
rtx out_operands[2];
const char *func;
+ enum rtx_code code = orig_code;
+
+ if (code == UNSIGNED_FIX)
+ code = FIX;
func = alpha_lookup_xfloating_lib_func (code);
@@ -3991,7 +3831,8 @@ alpha_emit_xfloating_cvt (code, operands)
}
alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
- gen_rtx_fmt_e (code, GET_MODE (operands[0]),
+ gen_rtx_fmt_e (orig_code,
+ GET_MODE (operands[0]),
operands[1]));
}
@@ -4000,8 +3841,7 @@ alpha_emit_xfloating_cvt (code, operands)
little-endian. */
void
-alpha_split_tfmode_pair (operands)
- rtx operands[4];
+alpha_split_tfmode_pair (rtx operands[4])
{
if (GET_CODE (operands[1]) == REG)
{
@@ -4037,9 +3877,7 @@ alpha_split_tfmode_pair (operands)
logical operation to be performed. */
void
-alpha_split_tfmode_frobsign (operands, operation)
- rtx operands[3];
- rtx (*operation) PARAMS ((rtx, rtx, rtx));
+alpha_split_tfmode_frobsign (rtx operands[3], rtx (*operation) (rtx, rtx, rtx))
{
rtx high_bit = operands[2];
rtx scratch;
@@ -4106,10 +3944,8 @@ alpha_split_tfmode_frobsign (operands, operation)
*/
void
-alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
- rtx tgt, mem;
- HOST_WIDE_INT size, ofs;
- int sign;
+alpha_expand_unaligned_load (rtx tgt, rtx mem, HOST_WIDE_INT size,
+ HOST_WIDE_INT ofs, int sign)
{
rtx meml, memh, addr, extl, exth, tmp, mema;
enum machine_mode mode;
@@ -4232,9 +4068,8 @@ alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
/* Similarly, use ins and msk instructions to perform unaligned stores. */
void
-alpha_expand_unaligned_store (dst, src, size, ofs)
- rtx dst, src;
- HOST_WIDE_INT size, ofs;
+alpha_expand_unaligned_store (rtx dst, rtx src,
+ HOST_WIDE_INT size, HOST_WIDE_INT ofs)
{
rtx dstl, dsth, addr, insl, insh, meml, memh, dsta;
@@ -4377,10 +4212,8 @@ alpha_expand_unaligned_store (dst, src, size, ofs)
/* Load an integral number of consecutive unaligned quadwords. */
static void
-alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
- rtx *out_regs;
- rtx smem;
- HOST_WIDE_INT words, ofs;
+alpha_expand_unaligned_load_words (rtx *out_regs, rtx smem,
+ HOST_WIDE_INT words, HOST_WIDE_INT ofs)
{
rtx const im8 = GEN_INT (-8);
rtx const i64 = GEN_INT (64);
@@ -4461,10 +4294,8 @@ alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
may be NULL to store zeros. */
static void
-alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
- rtx *data_regs;
- rtx dmem;
- HOST_WIDE_INT words, ofs;
+alpha_expand_unaligned_store_words (rtx *data_regs, rtx dmem,
+ HOST_WIDE_INT words, HOST_WIDE_INT ofs)
{
rtx const im8 = GEN_INT (-8);
rtx const i64 = GEN_INT (64);
@@ -4578,8 +4409,7 @@ alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
operands[3] is the alignment. */
int
-alpha_expand_block_move (operands)
- rtx operands[];
+alpha_expand_block_move (rtx operands[])
{
rtx bytes_rtx = operands[2];
rtx align_rtx = operands[3];
@@ -4653,7 +4483,8 @@ alpha_expand_block_move (operands)
is held in the register. Nor if there is not a mode that
handles the exact size. */
mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1);
- if (mode != BLKmode
+ if (GET_CODE (tmp) == REG
+ && mode != BLKmode
&& GET_MODE_SIZE (GET_MODE (tmp)) >= bytes)
{
if (mode == TImode)
@@ -4773,7 +4604,7 @@ alpha_expand_block_move (operands)
tmp = XEXP (XEXP (orig_dst, 0), 0);
mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1);
- if (GET_MODE (tmp) == mode)
+ if (GET_CODE (tmp) == REG && GET_MODE (tmp) == mode)
{
if (nregs == 1)
{
@@ -4915,8 +4746,7 @@ alpha_expand_block_move (operands)
}
int
-alpha_expand_block_clear (operands)
- rtx operands[];
+alpha_expand_block_clear (rtx operands[])
{
rtx bytes_rtx = operands[1];
rtx align_rtx = operands[2];
@@ -5206,8 +5036,7 @@ alpha_expand_block_clear (operands)
/* Returns a mask so that zap(x, value) == x & mask. */
rtx
-alpha_expand_zap_mask (value)
- HOST_WIDE_INT value;
+alpha_expand_zap_mask (HOST_WIDE_INT value)
{
rtx result;
int i;
@@ -5252,10 +5081,9 @@ alpha_expand_zap_mask (value)
}
void
-alpha_expand_builtin_vector_binop (gen, mode, op0, op1, op2)
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
- enum machine_mode mode;
- rtx op0, op1, op2;
+alpha_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx),
+ enum machine_mode mode,
+ rtx op0, rtx op1, rtx op2)
{
op0 = gen_lowpart (mode, op0);
@@ -5276,11 +5104,7 @@ alpha_expand_builtin_vector_binop (gen, mode, op0, op1, op2)
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
static int
-alpha_adjust_cost (insn, link, dep_insn, cost)
- rtx insn;
- rtx link;
- rtx dep_insn;
- int cost;
+alpha_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
enum attr_type insn_type, dep_insn_type;
@@ -5311,13 +5135,13 @@ alpha_adjust_cost (insn, link, dep_insn, cost)
/* The number of instructions that can be issued per cycle. */
static int
-alpha_issue_rate ()
+alpha_issue_rate (void)
{
return (alpha_cpu == PROCESSOR_EV4 ? 2 : 4);
}
static int
-alpha_use_dfa_pipeline_interface ()
+alpha_use_dfa_pipeline_interface (void)
{
return true;
}
@@ -5328,10 +5152,10 @@ alpha_use_dfa_pipeline_interface ()
For EV4, loads can be issued to either IB0 or IB1, thus we have 2
alternative schedules. For EV5, we can choose between E0/E1 and
- FA/FM. For EV6, an arithmatic insn can be issued to U0/U1/L0/L1. */
+ FA/FM. For EV6, an arithmetic insn can be issued to U0/U1/L0/L1. */
static int
-alpha_multipass_dfa_lookahead ()
+alpha_multipass_dfa_lookahead (void)
{
return (alpha_cpu == PROCESSOR_EV6 ? 4 : 2);
}
@@ -5340,7 +5164,7 @@ alpha_multipass_dfa_lookahead ()
struct machine_function GTY(())
{
- /* For unicosmk. */
+ /* For unicosmk. */
/* List of call information words for calls from this function. */
struct rtx_def *first_ciw;
struct rtx_def *last_ciw;
@@ -5349,14 +5173,14 @@ struct machine_function GTY(())
/* List of deferred case vectors. */
struct rtx_def *addr_list;
- /* For OSF. */
+ /* For OSF. */
const char *some_ld_name;
};
/* How to allocate a 'struct machine_function'. */
static struct machine_function *
-alpha_init_machine_status ()
+alpha_init_machine_status (void)
{
return ((struct machine_function *)
ggc_alloc_cleared (sizeof (struct machine_function)));
@@ -5367,9 +5191,7 @@ alpha_init_machine_status ()
/* Start the ball rolling with RETURN_ADDR_RTX. */
rtx
-alpha_return_addr (count, frame)
- int count;
- rtx frame ATTRIBUTE_UNUSED;
+alpha_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
{
if (count != 0)
return const0_rtx;
@@ -5381,7 +5203,7 @@ alpha_return_addr (count, frame)
function. Needed only if TARGET_LD_BUGGY_LDGP. */
rtx
-alpha_gp_save_rtx ()
+alpha_gp_save_rtx (void)
{
rtx r = get_hard_reg_initial_val (DImode, 29);
if (GET_CODE (r) != MEM)
@@ -5390,7 +5212,7 @@ alpha_gp_save_rtx ()
}
static int
-alpha_ra_ever_killed ()
+alpha_ra_ever_killed (void)
{
rtx top;
@@ -5409,7 +5231,7 @@ alpha_ra_ever_killed ()
instruction, or NULL. */
static const char *
-get_trap_mode_suffix ()
+get_trap_mode_suffix (void)
{
enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn);
@@ -5476,7 +5298,7 @@ get_trap_mode_suffix ()
instruction, or NULL. */
static const char *
-get_round_mode_suffix ()
+get_round_mode_suffix (void)
{
enum attr_round_suffix s = get_attr_round_suffix (current_output_insn);
@@ -5507,8 +5329,23 @@ get_round_mode_suffix ()
/* Locate some local-dynamic symbol still in use by this function
so that we can print its name in some movdi_er_tlsldm pattern. */
+static int
+get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
+{
+ rtx x = *px;
+
+ if (GET_CODE (x) == SYMBOL_REF
+ && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
+ {
+ cfun->machine->some_ld_name = XSTR (x, 0);
+ return 1;
+ }
+
+ return 0;
+}
+
static const char *
-get_some_local_dynamic_name ()
+get_some_local_dynamic_name (void)
{
rtx insn;
@@ -5523,33 +5360,10 @@ get_some_local_dynamic_name ()
abort ();
}
-static int
-get_some_local_dynamic_name_1 (px, data)
- rtx *px;
- void *data ATTRIBUTE_UNUSED;
-{
- rtx x = *px;
-
- if (GET_CODE (x) == SYMBOL_REF)
- {
- const char *str = XSTR (x, 0);
- if (str[0] == '@' && str[1] == 'D')
- {
- cfun->machine->some_ld_name = str;
- return 1;
- }
- }
-
- return 0;
-}
-
/* Print an operand. Recognize special options, documented below. */
void
-print_operand (file, x, code)
- FILE *file;
- rtx x;
- int code;
+print_operand (FILE *file, rtx x, int code)
{
int i;
@@ -5585,6 +5399,13 @@ print_operand (file, x, code)
fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
break;
+ case '+':
+ /* Generates a nop after a noreturn call at the very end of the
+ function. */
+ if (next_real_insn (current_output_insn) == 0)
+ fprintf (file, "\n\tnop");
+ break;
+
case '#':
if (alpha_this_literal_sequence_number == 0)
alpha_this_literal_sequence_number = alpha_next_sequence_number++;
@@ -5894,9 +5715,7 @@ print_operand (file, x, code)
}
void
-print_operand_address (file, addr)
- FILE *file;
- rtx addr;
+print_operand_address (FILE *file, rtx addr)
{
int basereg = 31;
HOST_WIDE_INT offset = 0;
@@ -5944,10 +5763,7 @@ print_operand_address (file, addr)
}
if (offset)
- {
- fputc ('+', file);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
- }
+ fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
addr = XEXP (addr, 0);
if (GET_CODE (addr) == REG)
@@ -5981,7 +5797,7 @@ print_operand_address (file, addr)
&& GET_CODE (XEXP (addr, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF)
{
- fprintf (file, "%s+%d",
+ fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC,
XSTR (XEXP (XEXP (addr, 0), 0), 0),
INTVAL (XEXP (XEXP (addr, 0), 1)));
return;
@@ -5991,8 +5807,7 @@ print_operand_address (file, addr)
else
abort ();
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
- fprintf (file, "($%d)", basereg);
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg);
}
/* Emit RTL insns to initialize the variable parts of a trampoline at
@@ -6009,9 +5824,8 @@ print_operand_address (file, addr)
Note that the hint field is PC (new) + 4 * bits 13:0. */
void
-alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
- rtx tramp, fnaddr, cxt;
- int fnofs, cxtofs, jmpofs;
+alpha_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt,
+ int fnofs, int cxtofs, int jmpofs)
{
rtx temp, temp1, addr;
/* VMS really uses DImode pointers in memory at this point. */
@@ -6050,8 +5864,8 @@ alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
emit_move_insn (gen_rtx_MEM (SImode, addr), temp1);
}
-#ifdef TRANSFER_FROM_TRAMPOLINE
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
+#ifdef ENABLE_EXECUTE_STACK
+ emit_library_call (init_one_libfunc ("__enable_execute_stack"),
0, VOIDmode, 1, tramp, Pmode);
#endif
@@ -6076,23 +5890,31 @@ alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
and the rest are pushed. */
rtx
-function_arg (cum, mode, type, named)
- CUMULATIVE_ARGS cum;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
+function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type,
+ int named ATTRIBUTE_UNUSED)
{
int basereg;
int num_args;
- /* Set up defaults for FP operands passed in FP registers, and
- integral operands passed in integer registers. */
- if (TARGET_FPREGS
- && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
- || GET_MODE_CLASS (mode) == MODE_FLOAT))
- basereg = 32 + 16;
- else
+ /* Don't get confused and pass small structures in FP registers. */
+ if (type && AGGREGATE_TYPE_P (type))
basereg = 16;
+ else
+ {
+#ifdef ENABLE_CHECKING
+ /* With alpha_split_complex_arg, we shouldn't see any raw complex
+ values here. */
+ if (COMPLEX_MODE_P (mode))
+ abort ();
+#endif
+
+ /* Set up defaults for FP operands passed in FP registers, and
+ integral operands passed in integer registers. */
+ if (TARGET_FPREGS && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ basereg = 32 + 16;
+ else
+ basereg = 16;
+ }
/* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
the three platforms, so we can't avoid conditional compilation. */
@@ -6105,8 +5927,7 @@ function_arg (cum, mode, type, named)
if (num_args >= 6 || MUST_PASS_IN_STACK (mode, type))
return NULL_RTX;
}
-#else
-#if TARGET_ABI_UNICOSMK
+#elif TARGET_ABI_UNICOSMK
{
int size;
@@ -6170,7 +5991,7 @@ function_arg (cum, mode, type, named)
}
}
}
-#else
+#elif TARGET_ABI_OSF
{
if (cum >= 6)
return NULL_RTX;
@@ -6184,16 +6005,133 @@ function_arg (cum, mode, type, named)
else if (FUNCTION_ARG_PASS_BY_REFERENCE (cum, mode, type, named))
basereg = 16;
}
-#endif /* TARGET_ABI_UNICOSMK */
-#endif /* TARGET_ABI_OPEN_VMS */
+#else
+#error Unhandled ABI
+#endif
return gen_rtx_REG (mode, num_args + basereg);
}
-tree
-alpha_build_va_list ()
+/* Return true if TYPE must be returned in memory, instead of in registers. */
+
+static bool
+alpha_return_in_memory (tree type, tree fndecl ATTRIBUTE_UNUSED)
+{
+ enum machine_mode mode = VOIDmode;
+ int size;
+
+ if (type)
+ {
+ mode = TYPE_MODE (type);
+
+ /* All aggregates are returned in memory. */
+ if (AGGREGATE_TYPE_P (type))
+ return true;
+ }
+
+ size = GET_MODE_SIZE (mode);
+ switch (GET_MODE_CLASS (mode))
+ {
+ case MODE_VECTOR_FLOAT:
+ /* Pass all float vectors in memory, like an aggregate. */
+ return true;
+
+ case MODE_COMPLEX_FLOAT:
+ /* We judge complex floats on the size of their element,
+ not the size of the whole type. */
+ size = GET_MODE_UNIT_SIZE (mode);
+ break;
+
+ case MODE_INT:
+ case MODE_FLOAT:
+ case MODE_COMPLEX_INT:
+ case MODE_VECTOR_INT:
+ break;
+
+ default:
+ /* ??? We get called on all sorts of random stuff from
+ aggregate_value_p. We can't abort, but it's not clear
+ what's safe to return. Pretend it's a struct I guess. */
+ return true;
+ }
+
+ /* Otherwise types must fit in one register. */
+ return size > UNITS_PER_WORD;
+}
+
+/* Define how to find the value returned by a function. VALTYPE is the
+ data type of the value (as a tree). If the precise function being
+ called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
+ MODE is set instead of VALTYPE for libcalls.
+
+ On Alpha the value is found in $0 for integer functions and
+ $f0 for floating-point functions. */
+
+rtx
+function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
+ enum machine_mode mode)
+{
+ unsigned int regnum;
+ enum mode_class class;
+
+#ifdef ENABLE_CHECKING
+ if (valtype && alpha_return_in_memory (valtype, func))
+ abort ();
+#endif
+
+ if (valtype)
+ mode = TYPE_MODE (valtype);
+
+ class = GET_MODE_CLASS (mode);
+ switch (class)
+ {
+ case MODE_INT:
+ /* Do the same thing as PROMOTE_MODE. */
+ mode = DImode;
+ /* FALLTHRU */
+
+ case MODE_COMPLEX_INT:
+ case MODE_VECTOR_INT:
+ regnum = 0;
+ break;
+
+ case MODE_FLOAT:
+ regnum = 32;
+ break;
+
+ case MODE_COMPLEX_FLOAT:
+ {
+ enum machine_mode cmode = GET_MODE_INNER (mode);
+
+ return gen_rtx_PARALLEL
+ (VOIDmode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 32),
+ GEN_INT (0)),
+ gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 33),
+ GEN_INT (GET_MODE_SIZE (cmode)))));
+ }
+
+ default:
+ abort ();
+ }
+
+ return gen_rtx_REG (mode, regnum);
+}
+
+/* TCmode complex values are passed by invisible reference. We
+ should not split these values. */
+
+static bool
+alpha_split_complex_arg (tree type)
{
- tree base, ofs, record, type_decl;
+ return TYPE_MODE (type) != TCmode;
+}
+
+static tree
+alpha_build_builtin_va_list (void)
+{
+ tree base, ofs, space, record, type_decl;
if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
return ptr_type_node;
@@ -6205,9 +6143,16 @@ alpha_build_va_list ()
/* C++? SET_IS_AGGR_TYPE (record, 1); */
+ /* Dummy field to prevent alignment warnings. */
+ space = build_decl (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"),
integer_type_node);
DECL_FIELD_CONTEXT (ofs) = record;
+ TREE_CHAIN (ofs) = space;
base = build_decl (FIELD_DECL, get_identifier ("__base"),
ptr_type_node);
@@ -6220,10 +6165,87 @@ alpha_build_va_list ()
return record;
}
+/* Perform any needed actions needed for a function that is receiving a
+ variable number of arguments. */
+
+static void
+alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED,
+ int *pretend_size, int no_rtl)
+{
+#if TARGET_ABI_UNICOSMK
+ /* On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
+ arguments on the stack. Unfortunately, it doesn't always store the first
+ one (i.e. the one that arrives in $16 or $f16). This is not a problem
+ with stdargs as we always have at least one named argument there. */
+ int num_reg_words = pcum->num_reg_words;
+ if (num_reg_words < 6)
+ {
+ if (!no_rtl)
+ {
+ emit_insn (gen_umk_mismatch_args (GEN_INT (num_reg_words + 1)));
+ emit_insn (gen_arg_home_umk ());
+ }
+ *pretend_size = 0;
+ }
+#elif TARGET_ABI_OPEN_VMS
+ /* For VMS, we allocate space for all 6 arg registers plus a count.
+
+ However, if NO registers need to be saved, don't allocate any space.
+ This is not only because we won't need the space, but because AP
+ includes the current_pretend_args_size and we don't want to mess up
+ any ap-relative addresses already made. */
+ if (pcum->num_args < 6)
+ {
+ if (!no_rtl)
+ {
+ emit_move_insn (gen_rtx_REG (DImode, 1), virtual_incoming_args_rtx);
+ emit_insn (gen_arg_home ());
+ }
+ *pretend_size = 7 * UNITS_PER_WORD;
+ }
+#else
+ /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
+ only push those that are remaining. However, if NO registers need to
+ be saved, don't allocate any space. This is not only because we won't
+ need the space, but because AP includes the current_pretend_args_size
+ and we don't want to mess up any ap-relative addresses already made.
+
+ If we are not to use the floating-point registers, save the integer
+ registers where we would put the floating-point registers. This is
+ not the most efficient way to implement varargs with just one register
+ class, but it isn't worth doing anything more efficient in this rare
+ case. */
+ CUMULATIVE_ARGS cum = *pcum;
+
+ if (cum >= 6)
+ return;
+
+ if (!no_rtl)
+ {
+ int set = get_varargs_alias_set ();
+ rtx tmp;
+
+ tmp = gen_rtx_MEM (BLKmode,
+ plus_constant (virtual_incoming_args_rtx,
+ (cum + 6) * UNITS_PER_WORD));
+ set_mem_alias_set (tmp, set);
+ move_block_from_reg (16 + cum, tmp, 6 - cum);
+
+ tmp = gen_rtx_MEM (BLKmode,
+ plus_constant (virtual_incoming_args_rtx,
+ cum * UNITS_PER_WORD));
+ set_mem_alias_set (tmp, set);
+ move_block_from_reg (16 + (TARGET_FPREGS ? 32 : 0) + cum, tmp,
+ 6 - cum);
+ }
+ *pretend_size = 12 * UNITS_PER_WORD;
+#endif
+}
+
void
-alpha_va_start (valist, nextarg)
- tree valist;
- rtx nextarg ATTRIBUTE_UNUSED;
+alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT offset;
tree t, offset_field, base_field;
@@ -6285,8 +6307,7 @@ alpha_va_start (valist, nextarg)
}
rtx
-alpha_va_arg (valist, type)
- tree valist, type;
+alpha_va_arg (tree valist, tree type)
{
rtx addr;
tree t, type_size, rounded_size;
@@ -6339,7 +6360,27 @@ alpha_va_arg (valist, type)
indirect = 1;
rounded_size = size_int (UNITS_PER_WORD);
}
- else if (FLOAT_TYPE_P (type))
+ else if (TREE_CODE (type) == COMPLEX_TYPE)
+ {
+ rtx real_part, imag_part, value, tmp;
+
+ real_part = alpha_va_arg (valist, TREE_TYPE (type));
+ imag_part = alpha_va_arg (valist, TREE_TYPE (type));
+
+ /* ??? Most irritatingly, we're not returning the value here,
+ but the address. Since real_part and imag_part are not
+ necessarily contiguous, we must copy to local storage. */
+
+ real_part = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (type)), real_part);
+ imag_part = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (type)), imag_part);
+ value = gen_rtx_CONCAT (TYPE_MODE (type), real_part, imag_part);
+
+ tmp = assign_temp (type, 0, 1, 0);
+ emit_move_insn (tmp, value);
+
+ return XEXP (tmp, 0);
+ }
+ else if (TREE_CODE (type) == REAL_TYPE)
{
tree fpaddend, cond;
@@ -6546,7 +6587,7 @@ static struct alpha_builtin_def const two_arg_builtins[] = {
};
static void
-alpha_init_builtins ()
+alpha_init_builtins (void)
{
const struct alpha_builtin_def *p;
tree ftype;
@@ -6597,12 +6638,10 @@ alpha_init_builtins ()
IGNORE is nonzero if the value is to be ignored. */
static rtx
-alpha_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
+alpha_expand_builtin (tree exp, rtx target,
+ rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
{
#define MAX_ARGS 2
@@ -6686,7 +6725,7 @@ alpha_expand_builtin (exp, target, subtarget, mode, ignore)
/* These variables are used for communication between the following functions.
They indicate various things about the current function being compiled
that are used to tell what kind of prologue, epilogue and procedure
- descriptior to generate. */
+ descriptor to generate. */
/* Nonzero if we need a stack procedure. */
enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
@@ -6706,21 +6745,16 @@ static int vms_base_regno;
/* Compute register masks for saved registers. */
static void
-alpha_sa_mask (imaskP, fmaskP)
- unsigned long *imaskP;
- unsigned long *fmaskP;
+alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
{
unsigned long imask = 0;
unsigned long fmask = 0;
unsigned int i;
- /* Irritatingly, there are two kinds of thunks -- those created with
- TARGET_ASM_OUTPUT_MI_THUNK and those with DECL_THUNK_P that go
- through the regular part of the compiler. In the
- TARGET_ASM_OUTPUT_MI_THUNK case we don't have valid register life
- info, but assemble_start_function wants to output .frame and
- .mask directives. */
- if (current_function_is_thunk && !no_new_pseudos)
+ /* When outputting a thunk, we don't have valid register life info,
+ but assemble_start_function wants to output .frame and .mask
+ directives. */
+ if (current_function_is_thunk)
{
*imaskP = 0;
*fmaskP = 0;
@@ -6728,7 +6762,7 @@ alpha_sa_mask (imaskP, fmaskP)
}
if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
- imask |= (1L << HARD_FRAME_POINTER_REGNUM);
+ imask |= (1UL << HARD_FRAME_POINTER_REGNUM);
/* One for every register we have to save. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
@@ -6737,9 +6771,9 @@ alpha_sa_mask (imaskP, fmaskP)
&& (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
{
if (i < 32)
- imask |= (1L << i);
+ imask |= (1UL << i);
else
- fmask |= (1L << (i - 32));
+ fmask |= (1UL << (i - 32));
}
/* We need to restore these for the handler. */
@@ -6750,7 +6784,7 @@ alpha_sa_mask (imaskP, fmaskP)
unsigned regno = EH_RETURN_DATA_REGNO (i);
if (regno == INVALID_REGNUM)
break;
- imask |= 1L << regno;
+ imask |= 1UL << regno;
}
/* Glibc likes to use $31 as an unwind stopper for crt0. To
@@ -6758,19 +6792,19 @@ alpha_sa_mask (imaskP, fmaskP)
zero in the prologue of _Unwind_RaiseException et al. */
imask |= 1UL << 31;
}
-
+
/* If any register spilled, then spill the return address also. */
/* ??? This is required by the Digital stack unwind specification
and isn't needed if we're doing Dwarf2 unwinding. */
if (imask || fmask || alpha_ra_ever_killed ())
- imask |= (1L << REG_RA);
+ imask |= (1UL << REG_RA);
*imaskP = imask;
*fmaskP = fmask;
}
int
-alpha_sa_size ()
+alpha_sa_size (void)
{
unsigned long mask[2];
int sa_size = 0;
@@ -6872,15 +6906,39 @@ alpha_sa_size ()
return sa_size * 8;
}
+/* Define the offset between two registers, one to be eliminated,
+ and the other its replacement, at the start of a routine. */
+
+HOST_WIDE_INT
+alpha_initial_elimination_offset (unsigned int from,
+ unsigned int to ATTRIBUTE_UNUSED)
+{
+ HOST_WIDE_INT ret;
+
+ ret = alpha_sa_size ();
+ ret += ALPHA_ROUND (current_function_outgoing_args_size);
+
+ if (from == FRAME_POINTER_REGNUM)
+ ;
+ else if (from == ARG_POINTER_REGNUM)
+ ret += (ALPHA_ROUND (get_frame_size ()
+ + current_function_pretend_args_size)
+ - current_function_pretend_args_size);
+ else
+ abort ();
+
+ return ret;
+}
+
int
-alpha_pv_save_size ()
+alpha_pv_save_size (void)
{
alpha_sa_size ();
return alpha_procedure_type == PT_STACK ? 8 : 0;
}
int
-alpha_using_fp ()
+alpha_using_fp (void)
{
alpha_sa_size ();
return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
@@ -6900,22 +6958,19 @@ const struct attribute_spec vms_attribute_table[] =
#endif
static int
-find_lo_sum_using_gp (px, data)
- rtx *px;
- void *data ATTRIBUTE_UNUSED;
+find_lo_sum_using_gp (rtx *px, void *data ATTRIBUTE_UNUSED)
{
return GET_CODE (*px) == LO_SUM && XEXP (*px, 0) == pic_offset_table_rtx;
}
int
-alpha_find_lo_sum_using_gp (insn)
- rtx insn;
+alpha_find_lo_sum_using_gp (rtx insn)
{
return for_each_rtx (&PATTERN (insn), find_lo_sum_using_gp, NULL) > 0;
}
static int
-alpha_does_function_need_gp ()
+alpha_does_function_need_gp (void)
{
rtx insn;
@@ -6923,12 +6978,21 @@ alpha_does_function_need_gp ()
if (! TARGET_ABI_OSF)
return 0;
+ /* We need the gp to load the address of __mcount. */
if (TARGET_PROFILING_NEEDS_GP && current_function_profile)
return 1;
+ /* The code emitted by alpha_output_mi_thunk_osf uses the gp. */
if (current_function_is_thunk)
return 1;
+ /* The nonlocal receiver pattern assumes that the gp is valid for
+ the nested function. Reasonable because it's almost always set
+ correctly already. For the cases where that's wrong, make sure
+ the nested function loads its gp on entry. */
+ if (current_function_has_nonlocal_goto)
+ return 1;
+
/* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
Even if we are a static function, we still need to do this in case
our address is taken and passed to something like qsort. */
@@ -6947,27 +7011,12 @@ alpha_does_function_need_gp ()
return 0;
}
-/* Write a version stamp. Don't write anything if we are running as a
- cross-compiler. Otherwise, use the versions in /usr/include/stamp.h. */
-
-#ifdef HAVE_STAMP_H
-#include <stamp.h>
-#endif
-
-void
-alpha_write_verstamp (file)
- FILE *file ATTRIBUTE_UNUSED;
-{
-#ifdef MS_STAMP
- fprintf (file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
-#endif
-}
/* Helper function to set RTX_FRAME_RELATED_P on instructions, including
sequences. */
static rtx
-set_frame_related_p ()
+set_frame_related_p (void)
{
rtx seq = get_insns ();
rtx insn;
@@ -7015,7 +7064,7 @@ set_frame_related_p ()
simply allocate stack without saving registers. */
void
-alpha_expand_prologue ()
+alpha_expand_prologue (void)
{
/* Registers to save. */
unsigned long imask = 0;
@@ -7143,15 +7192,14 @@ alpha_expand_prologue ()
and subtract it to sp.
Yes, that's correct -- we have to reload the whole constant
- into a temporary via ldah+lda then subtract from sp. To
- ensure we get ldah+lda, we use a special pattern. */
+ into a temporary via ldah+lda then subtract from sp. */
HOST_WIDE_INT lo, hi;
lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
hi = frame_size - lo;
emit_move_insn (ptr, GEN_INT (hi));
- emit_insn (gen_nt_lda (ptr, GEN_INT (lo)));
+ emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo)));
seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
ptr));
}
@@ -7203,18 +7251,18 @@ alpha_expand_prologue ()
}
/* Save register RA next. */
- if (imask & (1L << REG_RA))
+ if (imask & (1UL << REG_RA))
{
mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
set_mem_alias_set (mem, alpha_sr_alias_set);
FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
- imask &= ~(1L << REG_RA);
+ imask &= ~(1UL << REG_RA);
reg_offset += 8;
}
/* Now save any other registers required to be saved. */
for (i = 0; i < 31; i++)
- if (imask & (1L << i))
+ if (imask & (1UL << i))
{
mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
set_mem_alias_set (mem, alpha_sr_alias_set);
@@ -7224,24 +7272,24 @@ alpha_expand_prologue ()
/* Store a zero if requested for unwinding. */
if (imask & (1UL << 31))
- {
- rtx insn, t;
-
- mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
- set_mem_alias_set (mem, alpha_sr_alias_set);
- insn = emit_move_insn (mem, const0_rtx);
-
- RTX_FRAME_RELATED_P (insn) = 1;
- t = gen_rtx_REG (Pmode, 31);
- t = gen_rtx_SET (VOIDmode, mem, t);
- t = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, t, REG_NOTES (insn));
- REG_NOTES (insn) = t;
-
- reg_offset += 8;
- }
-
+ {
+ rtx insn, t;
+
+ mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
+ set_mem_alias_set (mem, alpha_sr_alias_set);
+ insn = emit_move_insn (mem, const0_rtx);
+
+ RTX_FRAME_RELATED_P (insn) = 1;
+ t = gen_rtx_REG (Pmode, 31);
+ t = gen_rtx_SET (VOIDmode, mem, t);
+ t = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, t, REG_NOTES (insn));
+ REG_NOTES (insn) = t;
+
+ reg_offset += 8;
+ }
+
for (i = 0; i < 31; i++)
- if (fmask & (1L << i))
+ if (fmask & (1UL << i))
{
mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
set_mem_alias_set (mem, alpha_sr_alias_set);
@@ -7257,7 +7305,7 @@ alpha_expand_prologue ()
reg_offset = -56;
for (i = 9; i < 15; i++)
- if (imask & (1L << i))
+ if (imask & (1UL << i))
{
mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
reg_offset));
@@ -7266,7 +7314,7 @@ alpha_expand_prologue ()
reg_offset -= 8;
}
for (i = 2; i < 10; i++)
- if (fmask & (1L << i))
+ if (fmask & (1UL << i))
{
mem = gen_rtx_MEM (DFmode, plus_constant (hard_frame_pointer_rtx,
reg_offset));
@@ -7294,11 +7342,31 @@ alpha_expand_prologue ()
/* If we have to allocate space for outgoing args, do it now. */
if (current_function_outgoing_args_size != 0)
- FRP (emit_move_insn
- (stack_pointer_rtx,
- plus_constant (hard_frame_pointer_rtx,
- - (ALPHA_ROUND
- (current_function_outgoing_args_size)))));
+ {
+ rtx seq
+ = emit_move_insn (stack_pointer_rtx,
+ plus_constant
+ (hard_frame_pointer_rtx,
+ - (ALPHA_ROUND
+ (current_function_outgoing_args_size))));
+
+ /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
+ if ! frame_pointer_needed. Setting the bit will change the CFA
+ computation rule to use sp again, which would be wrong if we had
+ frame_pointer_needed, as this means sp might move unpredictably
+ later on.
+
+ Also, note that
+ frame_pointer_needed
+ => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
+ and
+ current_function_outgoing_args_size != 0
+ => alpha_procedure_type != PT_NULL,
+
+ so when we are not setting the bit here, we are guaranteed to
+ have emitted an FRP frame pointer update just before. */
+ RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
+ }
}
else if (!TARGET_ABI_UNICOSMK)
{
@@ -7332,17 +7400,15 @@ alpha_expand_prologue ()
/* Output the textual info surrounding the prologue. */
void
-alpha_start_function (file, fnname, decl)
- FILE *file;
- const char *fnname;
- tree decl ATTRIBUTE_UNUSED;
+alpha_start_function (FILE *file, const char *fnname,
+ tree decl ATTRIBUTE_UNUSED)
{
unsigned long imask = 0;
unsigned long fmask = 0;
/* Stack space needed for pushing registers clobbered by us. */
HOST_WIDE_INT sa_size;
/* Complete stack size needed. */
- HOST_WIDE_INT frame_size;
+ unsigned HOST_WIDE_INT frame_size;
/* Offset from base reg to register save area. */
HOST_WIDE_INT reg_offset;
char *entry_label = (char *) alloca (strlen (fnname) + 6);
@@ -7400,7 +7466,7 @@ alpha_start_function (file, fnname, decl)
#ifdef ASM_OUTPUT_SOURCE_LINE
if (debug_info_level != DINFO_LEVEL_TERSE)
ASM_OUTPUT_SOURCE_LINE (file,
- DECL_SOURCE_LINE (current_function_decl));
+ DECL_SOURCE_LINE (current_function_decl), 0);
#endif
}
@@ -7458,23 +7524,17 @@ alpha_start_function (file, fnname, decl)
if (TARGET_ABI_UNICOSMK)
;
else if (TARGET_ABI_OPEN_VMS)
- {
- fprintf (file, "\t.frame $%d,", vms_unwind_regno);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC,
- frame_size >= ((HOST_WIDE_INT) 1 << 31) ? 0 : frame_size);
- fputs (",$26,", file);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, reg_offset);
- fputs ("\n", file);
- }
+ fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
+ HOST_WIDE_INT_PRINT_DEC "\n",
+ vms_unwind_regno,
+ frame_size >= (1UL << 31) ? 0 : frame_size,
+ reg_offset);
else if (!flag_inhibit_size_directive)
- {
- fprintf (file, "\t.frame $%d,",
- (frame_pointer_needed
- ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM));
- fprintf (file, HOST_WIDE_INT_PRINT_DEC,
- frame_size >= (1l << 31) ? 0 : frame_size);
- fprintf (file, ",$26,%d\n", current_function_pretend_args_size);
- }
+ fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
+ (frame_pointer_needed
+ ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
+ frame_size >= (1UL << 31) ? 0 : frame_size,
+ current_function_pretend_args_size);
/* Describe which registers were spilled. */
if (TARGET_ABI_UNICOSMK)
@@ -7484,7 +7544,7 @@ alpha_start_function (file, fnname, decl)
if (imask)
/* ??? Does VMS care if mask contains ra? The old code didn't
set it, so I don't here. */
- fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1L << REG_RA));
+ fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA));
if (fmask)
fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
if (alpha_procedure_type == PT_REGISTER)
@@ -7494,23 +7554,17 @@ alpha_start_function (file, fnname, decl)
{
if (imask)
{
- fprintf (file, "\t.mask 0x%lx,", imask);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC,
- frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
- putc ('\n', file);
+ fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask,
+ frame_size >= (1UL << 31) ? 0 : reg_offset - frame_size);
for (i = 0; i < 32; ++i)
- if (imask & (1L << i))
+ if (imask & (1UL << i))
reg_offset += 8;
}
if (fmask)
- {
- fprintf (file, "\t.fmask 0x%lx,", fmask);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC,
- frame_size >= (1l << 31) ? 0 : reg_offset - frame_size);
- putc ('\n', file);
- }
+ fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask,
+ frame_size >= (1UL << 31) ? 0 : reg_offset - frame_size);
}
#if TARGET_ABI_OPEN_VMS
@@ -7529,8 +7583,7 @@ alpha_start_function (file, fnname, decl)
/* Emit the .prologue note at the scheduled end of the prologue. */
static void
-alpha_output_function_end_prologue (file)
- FILE *file;
+alpha_output_function_end_prologue (FILE *file)
{
if (TARGET_ABI_UNICOSMK)
;
@@ -7552,7 +7605,7 @@ alpha_output_function_end_prologue (file)
#define FRP(exp) exp
void
-alpha_expand_epilogue ()
+alpha_expand_epilogue (void)
{
/* Registers to save. */
unsigned long imask = 0;
@@ -7644,10 +7697,10 @@ alpha_expand_epilogue ()
FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
reg_offset += 8;
- imask &= ~(1L << REG_RA);
+ imask &= ~(1UL << REG_RA);
for (i = 0; i < 31; ++i)
- if (imask & (1L << i))
+ if (imask & (1UL << i))
{
if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
fp_offset = reg_offset;
@@ -7664,7 +7717,7 @@ alpha_expand_epilogue ()
reg_offset += 8;
for (i = 0; i < 31; ++i)
- if (fmask & (1L << i))
+ if (fmask & (1UL << i))
{
mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
set_mem_alias_set (mem, alpha_sr_alias_set);
@@ -7679,7 +7732,7 @@ alpha_expand_epilogue ()
reg_offset = -56;
for (i = 9; i < 15; i++)
- if (imask & (1L << i))
+ if (imask & (1UL << i))
{
mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
reg_offset));
@@ -7689,7 +7742,7 @@ alpha_expand_epilogue ()
}
for (i = 2; i < 10; i++)
- if (fmask & (1L << i))
+ if (fmask & (1UL << i))
{
mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
reg_offset));
@@ -7810,46 +7863,10 @@ alpha_expand_epilogue ()
}
}
-#if TARGET_ABI_OPEN_VMS
-#include <splay-tree.h>
-
-/* Structure to collect function names for final output
- in link section. */
-
-enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
-enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
-
-struct alpha_funcs
-{
- int num;
- splay_tree links;
-};
-
-struct alpha_links
-{
- int num;
- rtx linkage;
- enum links_kind lkind;
- enum reloc_kind rkind;
-};
-
-static splay_tree alpha_funcs_tree;
-static splay_tree alpha_links_tree;
-
-static int mark_alpha_links_node PARAMS ((splay_tree_node, void *));
-static void mark_alpha_links PARAMS ((void *));
-static int alpha_write_one_linkage PARAMS ((splay_tree_node, void *));
-
-static int alpha_funcs_num;
-#endif
-
/* Output the rest of the textual info surrounding the epilogue. */
void
-alpha_end_function (file, fnname, decl)
- FILE *file;
- const char *fnname;
- tree decl;
+alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
{
/* End the function. */
if (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive)
@@ -7864,17 +7881,6 @@ alpha_end_function (file, fnname, decl)
alpha_write_linkage (file, fnname, decl);
#endif
- /* Show that we know this function if it is called again.
-
- Do this only for functions whose symbols bind locally.
-
- Don't do this for functions not defined in the .text section, as
- otherwise it's not unlikely that the destination is out of range
- for a direct branch. */
-
- if ((*targetm.binds_local_p) (decl) && decl_in_text_section (decl))
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
-
/* Output jump tables and the static subroutine information block. */
if (TARGET_ABI_UNICOSMK)
{
@@ -7894,23 +7900,20 @@ alpha_end_function (file, fnname, decl)
Not sure why this idea hasn't been explored before... */
static void
-alpha_output_mi_thunk_osf (file, thunk_fndecl, delta, vcall_offset, function)
- FILE *file;
- tree thunk_fndecl ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset;
- tree function;
+alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
+ tree function)
{
HOST_WIDE_INT hi, lo;
rtx this, insn, funexp;
/* We always require a valid GP. */
emit_insn (gen_prologue_ldgp ());
- emit_note (NULL, NOTE_INSN_PROLOGUE_END);
+ emit_note (NOTE_INSN_PROLOGUE_END);
/* Find the "this" pointer. If the function returns a structure,
the structure return pointer is in $16. */
- if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
+ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
this = gen_rtx_REG (Pmode, 17);
else
this = gen_rtx_REG (Pmode, 16);
@@ -7980,6 +7983,7 @@ alpha_output_mi_thunk_osf (file, thunk_fndecl, delta, vcall_offset, function)
instruction scheduling worth while. Note that use_thunk calls
assemble_start_function and assemble_end_function. */
insn = get_insns ();
+ insn_locators_initialize ();
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1, 0);
@@ -8016,9 +8020,7 @@ long alpha_auto_offset;
/* Emit a new filename to a stream. */
void
-alpha_output_filename (stream, name)
- FILE *stream;
- const char *name;
+alpha_output_filename (FILE *stream, const char *name)
{
static int first_time = TRUE;
char ltext_label_name[100];
@@ -8059,13 +8061,11 @@ alpha_output_filename (stream, name)
fprintf (stream, "\n");
}
}
-
+
/* Emit a linenumber to a stream. */
void
-alpha_output_lineno (stream, line)
- FILE *stream;
- int line;
+alpha_output_lineno (FILE *stream, int line)
{
if (write_symbols == DBX_DEBUG)
{
@@ -8089,18 +8089,12 @@ struct shadow_summary
} used, defd;
};
-static void summarize_insn PARAMS ((rtx, struct shadow_summary *, int));
-static void alpha_handle_trap_shadows PARAMS ((rtx));
-
/* Summary the effects of expression X on the machine. Update SUM, a pointer
to the summary structure. SET is nonzero if the insn is setting the
object, otherwise zero. */
static void
-summarize_insn (x, sum, set)
- rtx x;
- struct shadow_summary *sum;
- int set;
+summarize_insn (rtx x, struct shadow_summary *sum, int set)
{
const char *format_ptr;
int i, j;
@@ -8254,8 +8248,7 @@ summarize_insn (x, sum, set)
(d) The trap shadow may not include any branch instructions. */
static void
-alpha_handle_trap_shadows (insns)
- rtx insns;
+alpha_handle_trap_shadows (void)
{
struct shadow_summary shadow;
int trap_pending, exception_nesting;
@@ -8268,7 +8261,7 @@ alpha_handle_trap_shadows (insns)
shadow.used.mem = 0;
shadow.defd = shadow.used;
- for (i = insns; i ; i = NEXT_INSN (i))
+ for (i = get_insns (); i ; i = NEXT_INSN (i))
{
if (GET_CODE (i) == NOTE)
{
@@ -8388,7 +8381,7 @@ alpha_handle_trap_shadows (insns)
}
/* Alpha can only issue instruction groups simultaneously if they are
- suitibly aligned. This is very processor-specific. */
+ suitably aligned. This is very processor-specific. */
enum alphaev4_pipe {
EV4_STOP = 0,
@@ -8408,19 +8401,8 @@ enum alphaev5_pipe {
EV5_FM = 64
};
-static enum alphaev4_pipe alphaev4_insn_pipe PARAMS ((rtx));
-static enum alphaev5_pipe alphaev5_insn_pipe PARAMS ((rtx));
-static rtx alphaev4_next_group PARAMS ((rtx, int *, int *));
-static rtx alphaev5_next_group PARAMS ((rtx, int *, int *));
-static rtx alphaev4_next_nop PARAMS ((int *));
-static rtx alphaev5_next_nop PARAMS ((int *));
-
-static void alpha_align_insns
- PARAMS ((rtx, unsigned int, rtx (*)(rtx, int *, int *), rtx (*)(int *)));
-
static enum alphaev4_pipe
-alphaev4_insn_pipe (insn)
- rtx insn;
+alphaev4_insn_pipe (rtx insn)
{
if (recog_memoized (insn) < 0)
return EV4_STOP;
@@ -8462,8 +8444,7 @@ alphaev4_insn_pipe (insn)
}
static enum alphaev5_pipe
-alphaev5_insn_pipe (insn)
- rtx insn;
+alphaev5_insn_pipe (rtx insn)
{
if (recog_memoized (insn) < 0)
return EV5_STOP;
@@ -8518,9 +8499,7 @@ alphaev5_insn_pipe (insn)
LEN is, of course, the length of the group in bytes. */
static rtx
-alphaev4_next_group (insn, pin_use, plen)
- rtx insn;
- int *pin_use, *plen;
+alphaev4_next_group (rtx insn, int *pin_use, int *plen)
{
int len, in_use;
@@ -8618,9 +8597,7 @@ alphaev4_next_group (insn, pin_use, plen)
LEN is, of course, the length of the group in bytes. */
static rtx
-alphaev5_next_group (insn, pin_use, plen)
- rtx insn;
- int *pin_use, *plen;
+alphaev5_next_group (rtx insn, int *pin_use, int *plen)
{
int len, in_use;
@@ -8745,8 +8722,7 @@ alphaev5_next_group (insn, pin_use, plen)
}
static rtx
-alphaev4_next_nop (pin_use)
- int *pin_use;
+alphaev4_next_nop (int *pin_use)
{
int in_use = *pin_use;
rtx nop;
@@ -8774,8 +8750,7 @@ alphaev4_next_nop (pin_use)
}
static rtx
-alphaev5_next_nop (pin_use)
- int *pin_use;
+alphaev5_next_nop (int *pin_use)
{
int in_use = *pin_use;
rtx nop;
@@ -8805,11 +8780,9 @@ alphaev5_next_nop (pin_use)
/* The instruction group alignment main loop. */
static void
-alpha_align_insns (insns, max_align, next_group, next_nop)
- rtx insns;
- unsigned int max_align;
- rtx (*next_group) PARAMS ((rtx, int *, int *));
- rtx (*next_nop) PARAMS ((int *));
+alpha_align_insns (unsigned int max_align,
+ rtx (*next_group) (rtx, int *, int *),
+ rtx (*next_nop) (int *))
{
/* ALIGN is the known alignment for the insn group. */
unsigned int align;
@@ -8819,7 +8792,7 @@ alpha_align_insns (insns, max_align, next_group, next_nop)
rtx i, next;
/* Let shorten branches care for assigning alignments to code labels. */
- shorten_branches (insns);
+ shorten_branches (get_insns ());
if (align_functions < 4)
align = 4;
@@ -8829,7 +8802,7 @@ alpha_align_insns (insns, max_align, next_group, next_nop)
align = max_align;
ofs = prev_in_use = 0;
- i = insns;
+ i = get_insns ();
if (GET_CODE (i) == NOTE)
i = next_nonnote_insn (i);
@@ -8900,7 +8873,7 @@ alpha_align_insns (insns, max_align, next_group, next_nop)
int nop_count = (align - ofs) / 4;
rtx where;
- /* Insert nops before labels, branches, and calls to truely merge
+ /* Insert nops before labels, branches, and calls to truly merge
the execution of the nops with the previous instruction group. */
where = prev_nonnote_insn (i);
if (where)
@@ -8931,12 +8904,11 @@ alpha_align_insns (insns, max_align, next_group, next_nop)
/* Machine dependent reorg pass. */
-void
-alpha_reorg (insns)
- rtx insns;
+static void
+alpha_reorg (void)
{
if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
- alpha_handle_trap_shadows (insns);
+ alpha_handle_trap_shadows ();
/* Due to the number of extra trapb insns, don't bother fixing up
alignment when trap precision is instruction. Moreover, we can
@@ -8946,25 +8918,60 @@ alpha_reorg (insns)
&& flag_schedule_insns_after_reload)
{
if (alpha_cpu == PROCESSOR_EV4)
- alpha_align_insns (insns, 8, alphaev4_next_group, alphaev4_next_nop);
+ alpha_align_insns (8, alphaev4_next_group, alphaev4_next_nop);
else if (alpha_cpu == PROCESSOR_EV5)
- alpha_align_insns (insns, 16, alphaev5_next_group, alphaev5_next_nop);
+ alpha_align_insns (16, alphaev5_next_group, alphaev5_next_nop);
}
}
+#if !TARGET_ABI_UNICOSMK
+
+#ifdef HAVE_STAMP_H
+#include <stamp.h>
+#endif
+
+static void
+alpha_file_start (void)
+{
+#ifdef OBJECT_FORMAT_ELF
+ /* If emitting dwarf2 debug information, we cannot generate a .file
+ directive to start the file, as it will conflict with dwarf2out
+ file numbers. So it's only useful when emitting mdebug output. */
+ targetm.file_start_file_directive = (write_symbols == DBX_DEBUG);
+#endif
+
+ default_file_start ();
+#ifdef MS_STAMP
+ fprintf (asm_out_file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
+#endif
+
+ fputs ("\t.set noreorder\n", asm_out_file);
+ fputs ("\t.set volatile\n", asm_out_file);
+ if (!TARGET_ABI_OPEN_VMS)
+ fputs ("\t.set noat\n", asm_out_file);
+ if (TARGET_EXPLICIT_RELOCS)
+ fputs ("\t.set nomacro\n", asm_out_file);
+ if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX)
+ fprintf (asm_out_file,
+ "\t.arch %s\n",
+ TARGET_CPU_EV6 ? "ev6"
+ : (TARGET_CPU_EV5
+ ? (TARGET_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5")
+ : "ev4"));
+}
+#endif
+
#ifdef OBJECT_FORMAT_ELF
/* Switch to the section to which we should output X. The only thing
special we do here is to honor small data. */
static void
-alpha_elf_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align;
+alpha_elf_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align)
{
if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
- /* ??? Consider using mergable sdata sections. */
+ /* ??? Consider using mergeable sdata sections. */
sdata_section ();
else
default_elf_select_rtx_section (mode, x, align);
@@ -8972,13 +8979,40 @@ alpha_elf_select_rtx_section (mode, x, align)
#endif /* OBJECT_FORMAT_ELF */
+/* Structure to collect function names for final output in link section. */
+/* Note that items marked with GTY can't be ifdef'ed out. */
+
+enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
+enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
+
+struct alpha_links GTY(())
+{
+ int num;
+ rtx linkage;
+ enum links_kind lkind;
+ enum reloc_kind rkind;
+};
+
+struct alpha_funcs GTY(())
+{
+ int num;
+ splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
+ links;
+};
+
+static GTY ((param1_is (char *), param2_is (struct alpha_links *)))
+ splay_tree alpha_links_tree;
+static GTY ((param1_is (tree), param2_is (struct alpha_funcs *)))
+ splay_tree alpha_funcs_tree;
+
+static GTY(()) int alpha_funcs_num;
+
#if TARGET_ABI_OPEN_VMS
/* Return the VMS argument type corresponding to MODE. */
enum avms_arg_type
-alpha_arg_type (mode)
- enum machine_mode mode;
+alpha_arg_type (enum machine_mode mode)
{
switch (mode)
{
@@ -8995,8 +9029,7 @@ alpha_arg_type (mode)
register value. */
rtx
-alpha_arg_info_reg_val (cum)
- CUMULATIVE_ARGS cum;
+alpha_arg_info_reg_val (CUMULATIVE_ARGS cum)
{
unsigned HOST_WIDE_INT regval = cum.num_args;
int i;
@@ -9007,26 +9040,6 @@ alpha_arg_info_reg_val (cum)
return GEN_INT (regval);
}
-/* Protect alpha_links from garbage collection. */
-
-static int
-mark_alpha_links_node (node, data)
- splay_tree_node node;
- void *data ATTRIBUTE_UNUSED;
-{
- struct alpha_links *links = (struct alpha_links *) node->value;
- ggc_mark_rtx (links->linkage);
- return 0;
-}
-
-static void
-mark_alpha_links (ptr)
- void *ptr;
-{
- splay_tree tree = *(splay_tree *) ptr;
- splay_tree_foreach (tree, mark_alpha_links_node, NULL);
-}
-
/* 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.
@@ -9034,25 +9047,23 @@ mark_alpha_links (ptr)
Return an SYMBOL_REF rtx for the linkage. */
rtx
-alpha_need_linkage (name, is_local)
- const char *name;
- int is_local;
+alpha_need_linkage (const char *name, int is_local)
{
splay_tree_node node;
struct alpha_links *al;
- struct alpha_funcs *cfaf;
if (name[0] == '*')
name++;
if (is_local)
{
- alpha_funcs_tree = splay_tree_new
- ((splay_tree_compare_fn) splay_tree_compare_pointers,
- (splay_tree_delete_key_fn) free,
- (splay_tree_delete_key_fn) free);
+ struct alpha_funcs *cfaf;
+
+ if (!alpha_funcs_tree)
+ alpha_funcs_tree = splay_tree_new_ggc ((splay_tree_compare_fn)
+ splay_tree_compare_pointers);
- cfaf = (struct alpha_funcs *) xmalloc (sizeof (struct alpha_funcs));
+ cfaf = (struct alpha_funcs *) ggc_alloc (sizeof (struct alpha_funcs));
cfaf->links = 0;
cfaf->num = ++alpha_funcs_num;
@@ -9060,7 +9071,6 @@ alpha_need_linkage (name, is_local)
splay_tree_insert (alpha_funcs_tree,
(splay_tree_key) current_function_decl,
(splay_tree_value) cfaf);
-
}
if (alpha_links_tree)
@@ -9087,17 +9097,10 @@ alpha_need_linkage (name, is_local)
}
}
else
- {
- alpha_links_tree = splay_tree_new
- ((splay_tree_compare_fn) strcmp,
- (splay_tree_delete_key_fn) free,
- (splay_tree_delete_key_fn) free);
+ alpha_links_tree = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
- ggc_add_root (&alpha_links_tree, 1, 1, mark_alpha_links);
- }
-
- al = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
- name = xstrdup (name);
+ al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
+ name = ggc_strdup (name);
/* Assume external if no definition. */
al->lkind = (is_local ? KIND_UNUSED : KIND_EXTERN);
@@ -9123,11 +9126,7 @@ alpha_need_linkage (name, is_local)
}
rtx
-alpha_use_linkage (linkage, cfundecl, lflag, rflag)
- rtx linkage;
- tree cfundecl;
- int lflag;
- int rflag;
+alpha_use_linkage (rtx linkage, tree cfundecl, int lflag, int rflag)
{
splay_tree_node cfunnode;
struct alpha_funcs *cfaf;
@@ -9151,13 +9150,7 @@ alpha_use_linkage (linkage, cfundecl, lflag, rflag)
al = (struct alpha_links *) lnode->value;
}
else
- {
- cfaf->links = splay_tree_new
- ((splay_tree_compare_fn) strcmp,
- (splay_tree_delete_key_fn) free,
- (splay_tree_delete_key_fn) free);
- ggc_add_root (&cfaf->links, 1, 1, mark_alpha_links);
- }
+ cfaf->links = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
if (!al)
{
@@ -9173,7 +9166,7 @@ alpha_use_linkage (linkage, cfundecl, lflag, rflag)
name_len = strlen (name);
- al = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
+ al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
al->num = cfaf->num;
node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
@@ -9207,9 +9200,7 @@ alpha_use_linkage (linkage, cfundecl, lflag, rflag)
}
static int
-alpha_write_one_linkage (node, data)
- splay_tree_node node;
- void *data;
+alpha_write_one_linkage (splay_tree_node node, void *data)
{
const char *const name = (const char *) node->key;
struct alpha_links *link = (struct alpha_links *) node->value;
@@ -9248,10 +9239,7 @@ alpha_write_one_linkage (node, data)
}
static void
-alpha_write_linkage (stream, funname, fundecl)
- FILE *stream;
- const char *funname;
- tree fundecl;
+alpha_write_linkage (FILE *stream, const char *funname, tree fundecl)
{
splay_tree_node node;
struct alpha_funcs *func;
@@ -9286,10 +9274,7 @@ alpha_write_linkage (stream, funname, fundecl)
#define SECTION_VMS_INITIALIZE (SECTION_VMS_GLOBAL << 1)
static unsigned int
-vms_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
+vms_section_type_flags (tree decl, const char *name, int reloc)
{
unsigned int flags = default_section_type_flags (decl, name, reloc);
@@ -9311,9 +9296,7 @@ vms_section_type_flags (decl, name, reloc)
the section; 0 if the default should be used. */
static void
-vms_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+vms_asm_named_section (const char *name, unsigned int flags)
{
fputc ('\n', asm_out_file);
fprintf (asm_out_file, ".section\t%s", name);
@@ -9339,9 +9322,7 @@ vms_asm_named_section (name, flags)
used by a normal pointer. */
static void
-vms_asm_out_constructor (symbol, priority)
- rtx symbol;
- int priority ATTRIBUTE_UNUSED;
+vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
ctors_section ();
assemble_align (BITS_PER_WORD);
@@ -9349,9 +9330,7 @@ vms_asm_out_constructor (symbol, priority)
}
static void
-vms_asm_out_destructor (symbol, priority)
- rtx symbol;
- int priority ATTRIBUTE_UNUSED;
+vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
dtors_section ();
assemble_align (BITS_PER_WORD);
@@ -9360,19 +9339,17 @@ vms_asm_out_destructor (symbol, priority)
#else
rtx
-alpha_need_linkage (name, is_local)
- const char *name ATTRIBUTE_UNUSED;
- int is_local ATTRIBUTE_UNUSED;
+alpha_need_linkage (const char *name ATTRIBUTE_UNUSED,
+ int is_local ATTRIBUTE_UNUSED)
{
return NULL_RTX;
}
rtx
-alpha_use_linkage (linkage, cfundecl, lflag, rflag)
- rtx linkage ATTRIBUTE_UNUSED;
- tree cfundecl ATTRIBUTE_UNUSED;
- int lflag ATTRIBUTE_UNUSED;
- int rflag ATTRIBUTE_UNUSED;
+alpha_use_linkage (rtx linkage ATTRIBUTE_UNUSED,
+ tree cfundecl ATTRIBUTE_UNUSED,
+ int lflag ATTRIBUTE_UNUSED,
+ int rflag ATTRIBUTE_UNUSED)
{
return NULL_RTX;
}
@@ -9381,21 +9358,11 @@ alpha_use_linkage (linkage, cfundecl, lflag, rflag)
#if TARGET_ABI_UNICOSMK
-static void unicosmk_output_module_name PARAMS ((FILE *));
-static void unicosmk_output_default_externs PARAMS ((FILE *));
-static void unicosmk_output_dex PARAMS ((FILE *));
-static void unicosmk_output_externs PARAMS ((FILE *));
-static void unicosmk_output_addr_vec PARAMS ((FILE *, rtx));
-static const char *unicosmk_ssib_name PARAMS ((void));
-static int unicosmk_special_name PARAMS ((const char *));
-
/* Define the offset between two registers, one to be eliminated, and the
other its replacement, at the start of a routine. */
int
-unicosmk_initial_elimination_offset (from, to)
- int from;
- int to;
+unicosmk_initial_elimination_offset (int from, int to)
{
int fixed_size;
@@ -9423,112 +9390,27 @@ unicosmk_initial_elimination_offset (from, to)
or '$'. */
static void
-unicosmk_output_module_name (file)
- FILE *file;
+unicosmk_output_module_name (FILE *file)
{
- const char *name;
-
- /* Strip directories. */
-
- name = strrchr (main_input_filename, '/');
- if (name)
- ++name;
- else
- name = main_input_filename;
-
+ const char *name = lbasename (main_input_filename);
+ unsigned len = strlen (name);
+ char *clean_name = alloca (len + 2);
+ char *ptr = clean_name;
+
/* CAM only accepts module names that start with a letter or '$'. We
prefix the module name with a '$' if necessary. */
if (!ISALPHA (*name))
- putc ('$', file);
- output_clean_symbol_name (file, name);
-}
-
-/* Output text that to appear at the beginning of an assembler file. */
-
-void
-unicosmk_asm_file_start (file)
- FILE *file;
-{
- int i;
-
- fputs ("\t.ident\t", file);
- unicosmk_output_module_name (file);
- fputs ("\n\n", file);
-
- /* The Unicos/Mk assembler uses different register names. Instead of trying
- to support them, we simply use micro definitions. */
-
- /* CAM has different register names: rN for the integer register N and fN
- for the floating-point register N. Instead of trying to use these in
- alpha.md, we define the symbols $N and $fN to refer to the appropriate
- register. */
-
- for (i = 0; i < 32; ++i)
- fprintf (file, "$%d <- r%d\n", i, i);
-
- for (i = 0; i < 32; ++i)
- fprintf (file, "$f%d <- f%d\n", i, i);
-
- putc ('\n', file);
-
- /* The .align directive fill unused space with zeroes which does not work
- in code sections. We define the macro 'gcc@code@align' which uses nops
- instead. Note that it assumes that code sections always have the
- biggest possible alignment since . refers to the current offset from
- the beginning of the section. */
-
- fputs ("\t.macro gcc@code@align n\n", file);
- fputs ("gcc@n@bytes = 1 << n\n", file);
- fputs ("gcc@here = . % gcc@n@bytes\n", file);
- fputs ("\t.if ne, gcc@here, 0\n", file);
- fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", file);
- fputs ("\tbis r31,r31,r31\n", file);
- fputs ("\t.endr\n", file);
- fputs ("\t.endif\n", file);
- fputs ("\t.endm gcc@code@align\n\n", file);
-
- /* Output extern declarations which should always be visible. */
- unicosmk_output_default_externs (file);
-
- /* Open a dummy section. We always need to be inside a section for the
- section-switching code to work correctly.
- ??? This should be a module id or something like that. I still have to
- figure out what the rules for those are. */
- fputs ("\n\t.psect\t$SG00000,data\n", file);
-}
-
-/* Output text to appear at the end of an assembler file. This includes all
- pending extern declarations and DEX expressions. */
-
-void
-unicosmk_asm_file_end (file)
- FILE *file;
-{
- fputs ("\t.endp\n\n", file);
-
- /* Output all pending externs. */
-
- unicosmk_output_externs (file);
-
- /* Output dex definitions used for functions whose names conflict with
- register names. */
-
- unicosmk_output_dex (file);
-
- fputs ("\t.end\t", file);
- unicosmk_output_module_name (file);
- putc ('\n', file);
+ *ptr++ = '$';
+ memcpy (ptr, name, len + 1);
+ clean_symbol_name (clean_name);
+ fputs (clean_name, file);
}
/* Output the definition of a common variable. */
void
-unicosmk_output_common (file, name, size, align)
- FILE *file;
- const char *name;
- int size;
- int align;
+unicosmk_output_common (FILE *file, const char *name, int size, int align)
{
tree name_tree;
printf ("T3E__: common %s\n", name);
@@ -9549,10 +9431,8 @@ unicosmk_output_common (file, name, size, align)
static int current_section_align;
static unsigned int
-unicosmk_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc ATTRIBUTE_UNUSED;
+unicosmk_section_type_flags (tree decl, const char *name,
+ int reloc ATTRIBUTE_UNUSED)
{
unsigned int flags = default_section_type_flags (decl, name, reloc);
@@ -9581,9 +9461,7 @@ unicosmk_section_type_flags (decl, name, reloc)
declaration. */
static void
-unicosmk_unique_section (decl, reloc)
- tree decl;
- int reloc ATTRIBUTE_UNUSED;
+unicosmk_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
{
const char *name;
int len;
@@ -9592,7 +9470,7 @@ unicosmk_unique_section (decl, reloc)
abort ();
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
- name = alpha_strip_name_encoding (name);
+ name = default_strip_name_encoding (name);
len = strlen (name);
if (TREE_CODE (decl) == FUNCTION_DECL)
@@ -9624,9 +9502,7 @@ unicosmk_unique_section (decl, reloc)
the section; 0 if the default should be used. */
static void
-unicosmk_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+unicosmk_asm_named_section (const char *name, unsigned int flags)
{
const char *kind;
@@ -9654,9 +9530,7 @@ unicosmk_asm_named_section (name, flags)
}
static void
-unicosmk_insert_attributes (decl, attr_ptr)
- tree decl;
- tree *attr_ptr ATTRIBUTE_UNUSED;
+unicosmk_insert_attributes (tree decl, tree *attr_ptr ATTRIBUTE_UNUSED)
{
if (DECL_P (decl)
&& (TREE_PUBLIC (decl) || TREE_CODE (decl) == FUNCTION_DECL))
@@ -9667,9 +9541,7 @@ unicosmk_insert_attributes (decl, attr_ptr)
in code sections because .align fill unused space with zeroes. */
void
-unicosmk_output_align (file, align)
- FILE *file;
- int align;
+unicosmk_output_align (FILE *file, int align)
{
if (inside_function)
fprintf (file, "\tgcc@code@align\t%d\n", align);
@@ -9682,9 +9554,7 @@ unicosmk_output_align (file, align)
does not allow data definitions in code sections. */
void
-unicosmk_defer_case_vector (lab, vec)
- rtx lab;
- rtx vec;
+unicosmk_defer_case_vector (rtx lab, rtx vec)
{
struct machine_function *machine = cfun->machine;
@@ -9696,16 +9566,14 @@ unicosmk_defer_case_vector (lab, vec)
/* Output a case vector. */
static void
-unicosmk_output_addr_vec (file, vec)
- FILE *file;
- rtx vec;
+unicosmk_output_addr_vec (FILE *file, rtx vec)
{
rtx lab = XEXP (vec, 0);
rtx body = XEXP (vec, 1);
int vlen = XVECLEN (body, 0);
int idx;
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (lab));
+ (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (lab));
for (idx = 0; idx < vlen; idx++)
{
@@ -9717,8 +9585,7 @@ unicosmk_output_addr_vec (file, vec)
/* Output current function's deferred case vectors. */
static void
-unicosmk_output_deferred_case_vectors (file)
- FILE *file;
+unicosmk_output_deferred_case_vectors (FILE *file)
{
struct machine_function *machine = cfun->machine;
rtx t;
@@ -9731,13 +9598,48 @@ unicosmk_output_deferred_case_vectors (file)
unicosmk_output_addr_vec (file, XEXP (t, 0));
}
+/* Generate the name of the SSIB section for the current function. */
+
+#define SSIB_PREFIX "__SSIB_"
+#define SSIB_PREFIX_LEN 7
+
+static const char *
+unicosmk_ssib_name (void)
+{
+ /* This is ok since CAM won't be able to deal with names longer than that
+ anyway. */
+
+ static char name[256];
+
+ rtx x;
+ const char *fnname;
+ int len;
+
+ x = DECL_RTL (cfun->decl);
+ if (GET_CODE (x) != MEM)
+ abort ();
+ x = XEXP (x, 0);
+ if (GET_CODE (x) != SYMBOL_REF)
+ abort ();
+ fnname = XSTR (x, 0);
+
+ len = strlen (fnname);
+ if (len + SSIB_PREFIX_LEN > 255)
+ len = 255 - SSIB_PREFIX_LEN;
+
+ strcpy (name, SSIB_PREFIX);
+ strncpy (name + SSIB_PREFIX_LEN, fnname, len);
+ name[len + SSIB_PREFIX_LEN] = 0;
+
+ return name;
+}
+
/* Set up the dynamic subprogram information block (DSIB) and update the
frame pointer register ($15) for subroutines which have a frame. If the
subroutine doesn't have a frame, simply increment $15. */
static void
-unicosmk_gen_dsib (imaskP)
- unsigned long * imaskP;
+unicosmk_gen_dsib (unsigned long *imaskP)
{
if (alpha_procedure_type == PT_STACK)
{
@@ -9755,14 +9657,14 @@ unicosmk_gen_dsib (imaskP)
mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 56));
set_mem_alias_set (mem, alpha_sr_alias_set);
FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
- (*imaskP) &= ~(1L << REG_RA);
+ (*imaskP) &= ~(1UL << REG_RA);
/* Save the old frame pointer. */
mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 48));
set_mem_alias_set (mem, alpha_sr_alias_set);
FRP (emit_move_insn (mem, hard_frame_pointer_rtx));
- (*imaskP) &= ~(1L << HARD_FRAME_POINTER_REGNUM);
+ (*imaskP) &= ~(1UL << HARD_FRAME_POINTER_REGNUM);
emit_insn (gen_blockage ());
@@ -9800,49 +9702,11 @@ unicosmk_gen_dsib (imaskP)
}
}
-#define SSIB_PREFIX "__SSIB_"
-#define SSIB_PREFIX_LEN 7
-
-/* Generate the name of the SSIB section for the current function. */
-
-static const char *
-unicosmk_ssib_name ()
-{
- /* This is ok since CAM won't be able to deal with names longer than that
- anyway. */
-
- static char name[256];
-
- rtx x;
- const char *fnname;
- int len;
-
- x = DECL_RTL (cfun->decl);
- if (GET_CODE (x) != MEM)
- abort ();
- x = XEXP (x, 0);
- if (GET_CODE (x) != SYMBOL_REF)
- abort ();
- fnname = alpha_strip_name_encoding (XSTR (x, 0));
-
- len = strlen (fnname);
- if (len + SSIB_PREFIX_LEN > 255)
- len = 255 - SSIB_PREFIX_LEN;
-
- strcpy (name, SSIB_PREFIX);
- strncpy (name + SSIB_PREFIX_LEN, fnname, len);
- name[len + SSIB_PREFIX_LEN] = 0;
-
- return name;
-}
-
/* Output the static subroutine information block for the current
function. */
static void
-unicosmk_output_ssib (file, fnname)
- FILE *file;
- const char *fnname;
+unicosmk_output_ssib (FILE *file, const char *fnname)
{
int len;
int i;
@@ -9889,14 +9753,12 @@ unicosmk_output_ssib (file, fnname)
for (x = machine->first_ciw; x; x = XEXP (x, 1))
{
ciw = XEXP (x, 0);
- fprintf (file, "\t.quad\t");
#if HOST_BITS_PER_WIDE_INT == 32
- fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
+ fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_DOUBLE_HEX "\n",
CONST_DOUBLE_HIGH (ciw), CONST_DOUBLE_LOW (ciw));
#else
- fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (ciw));
+ fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n", INTVAL (ciw));
#endif
- fprintf (file, "\n");
}
}
@@ -9906,8 +9768,7 @@ unicosmk_output_ssib (file, fnname)
X is a CONST_INT or CONST_DOUBLE representing the CIW. */
rtx
-unicosmk_add_call_info_word (x)
- rtx x;
+unicosmk_add_call_info_word (rtx x)
{
rtx node;
struct machine_function *machine = cfun->machine;
@@ -9922,13 +9783,13 @@ unicosmk_add_call_info_word (x)
++machine->ciw_count;
return GEN_INT (machine->ciw_count
- + strlen (current_function_name)/8 + 5);
+ + strlen (current_function_name ())/8 + 5);
}
static char unicosmk_section_buf[100];
char *
-unicosmk_text_section ()
+unicosmk_text_section (void)
{
static int count = 0;
sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@text___%d,code",
@@ -9937,7 +9798,7 @@ unicosmk_text_section ()
}
char *
-unicosmk_data_section ()
+unicosmk_data_section (void)
{
static int count = 1;
sprintf (unicosmk_section_buf, "\t.endp\n\n\t.psect\tgcc@data___%d,data",
@@ -9953,6 +9814,7 @@ unicosmk_data_section ()
/* List of identifiers for which an extern declaration might have to be
emitted. */
+/* FIXME: needs to use GC, so it can be saved and restored for PCH. */
struct unicosmk_extern_list
{
@@ -9965,8 +9827,7 @@ static struct unicosmk_extern_list *unicosmk_extern_head = 0;
/* Output extern declarations which are required for every asm file. */
static void
-unicosmk_output_default_externs (file)
- FILE *file;
+unicosmk_output_default_externs (FILE *file)
{
static const char *const externs[] =
{ "__T3E_MISMATCH" };
@@ -9984,8 +9845,7 @@ unicosmk_output_default_externs (file)
referenced but not defined. */
static void
-unicosmk_output_externs (file)
- FILE *file;
+unicosmk_output_externs (FILE *file)
{
struct unicosmk_extern_list *p;
const char *real_name;
@@ -9998,7 +9858,7 @@ unicosmk_output_externs (file)
/* We have to strip the encoding and possibly remove user_label_prefix
from the identifier in order to handle -fleading-underscore and
explicit asm names correctly (cf. gcc.dg/asm-names-1.c). */
- real_name = alpha_strip_name_encoding (p->name);
+ real_name = default_strip_name_encoding (p->name);
if (len && p->name[0] == '*'
&& !memcmp (real_name, user_label_prefix, len))
real_name += len;
@@ -10017,8 +9877,7 @@ unicosmk_output_externs (file)
/* Record an extern. */
void
-unicosmk_add_extern (name)
- const char *name;
+unicosmk_add_extern (const char *name)
{
struct unicosmk_extern_list *p;
@@ -10035,6 +9894,7 @@ unicosmk_add_extern (name)
/* Structure to collect identifiers which have been replaced by DEX
expressions. */
+/* FIXME: needs to use GC, so it can be saved and restored for PCH. */
struct unicosmk_dex {
struct unicosmk_dex *next;
@@ -10053,8 +9913,7 @@ static int unicosmk_dex_count = 0;
/* Check if NAME must be replaced by a DEX expression. */
static int
-unicosmk_special_name (name)
- const char *name;
+unicosmk_special_name (const char *name)
{
if (name[0] == '*')
++name;
@@ -10083,8 +9942,7 @@ unicosmk_special_name (name)
otherwise. */
static int
-unicosmk_need_dex (x)
- rtx x;
+unicosmk_need_dex (rtx x)
{
struct unicosmk_dex *dex;
const char *name;
@@ -10117,8 +9975,7 @@ unicosmk_need_dex (x)
/* Output the DEX definitions for this file. */
static void
-unicosmk_output_dex (file)
- FILE *file;
+unicosmk_output_dex (FILE *file)
{
struct unicosmk_dex *dex;
int i;
@@ -10140,39 +9997,264 @@ unicosmk_output_dex (file)
fprintf (file, "\t.dexend\n");
}
+/* Output text that to appear at the beginning of an assembler file. */
+
+static void
+unicosmk_file_start (void)
+{
+ int i;
+
+ fputs ("\t.ident\t", asm_out_file);
+ unicosmk_output_module_name (asm_out_file);
+ fputs ("\n\n", asm_out_file);
+
+ /* The Unicos/Mk assembler uses different register names. Instead of trying
+ to support them, we simply use micro definitions. */
+
+ /* CAM has different register names: rN for the integer register N and fN
+ for the floating-point register N. Instead of trying to use these in
+ alpha.md, we define the symbols $N and $fN to refer to the appropriate
+ register. */
+
+ for (i = 0; i < 32; ++i)
+ fprintf (asm_out_file, "$%d <- r%d\n", i, i);
+
+ for (i = 0; i < 32; ++i)
+ fprintf (asm_out_file, "$f%d <- f%d\n", i, i);
+
+ putc ('\n', asm_out_file);
+
+ /* The .align directive fill unused space with zeroes which does not work
+ in code sections. We define the macro 'gcc@code@align' which uses nops
+ instead. Note that it assumes that code sections always have the
+ biggest possible alignment since . refers to the current offset from
+ the beginning of the section. */
+
+ fputs ("\t.macro gcc@code@align n\n", asm_out_file);
+ fputs ("gcc@n@bytes = 1 << n\n", asm_out_file);
+ fputs ("gcc@here = . % gcc@n@bytes\n", asm_out_file);
+ fputs ("\t.if ne, gcc@here, 0\n", asm_out_file);
+ fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", asm_out_file);
+ fputs ("\tbis r31,r31,r31\n", asm_out_file);
+ fputs ("\t.endr\n", asm_out_file);
+ fputs ("\t.endif\n", asm_out_file);
+ fputs ("\t.endm gcc@code@align\n\n", asm_out_file);
+
+ /* Output extern declarations which should always be visible. */
+ unicosmk_output_default_externs (asm_out_file);
+
+ /* Open a dummy section. We always need to be inside a section for the
+ section-switching code to work correctly.
+ ??? This should be a module id or something like that. I still have to
+ figure out what the rules for those are. */
+ fputs ("\n\t.psect\t$SG00000,data\n", asm_out_file);
+}
+
+/* Output text to appear at the end of an assembler file. This includes all
+ pending extern declarations and DEX expressions. */
+
+static void
+unicosmk_file_end (void)
+{
+ fputs ("\t.endp\n\n", asm_out_file);
+
+ /* Output all pending externs. */
+
+ unicosmk_output_externs (asm_out_file);
+
+ /* Output dex definitions used for functions whose names conflict with
+ register names. */
+
+ unicosmk_output_dex (asm_out_file);
+
+ fputs ("\t.end\t", asm_out_file);
+ unicosmk_output_module_name (asm_out_file);
+ putc ('\n', asm_out_file);
+}
+
#else
static void
-unicosmk_output_deferred_case_vectors (file)
- FILE *file ATTRIBUTE_UNUSED;
+unicosmk_output_deferred_case_vectors (FILE *file ATTRIBUTE_UNUSED)
{}
static void
-unicosmk_gen_dsib (imaskP)
- unsigned long * imaskP ATTRIBUTE_UNUSED;
+unicosmk_gen_dsib (unsigned long *imaskP ATTRIBUTE_UNUSED)
{}
static void
-unicosmk_output_ssib (file, fnname)
- FILE * file ATTRIBUTE_UNUSED;
- const char * fnname ATTRIBUTE_UNUSED;
+unicosmk_output_ssib (FILE * file ATTRIBUTE_UNUSED,
+ const char * fnname ATTRIBUTE_UNUSED)
{}
rtx
-unicosmk_add_call_info_word (x)
- rtx x ATTRIBUTE_UNUSED;
+unicosmk_add_call_info_word (rtx x ATTRIBUTE_UNUSED)
{
return NULL_RTX;
}
static int
-unicosmk_need_dex (x)
- rtx x ATTRIBUTE_UNUSED;
+unicosmk_need_dex (rtx x ATTRIBUTE_UNUSED)
{
return 0;
}
#endif /* TARGET_ABI_UNICOSMK */
+static void
+alpha_init_libfuncs (void)
+{
+ if (TARGET_ABI_UNICOSMK)
+ {
+ /* Prevent gcc from generating calls to __divsi3. */
+ set_optab_libfunc (sdiv_optab, SImode, 0);
+ set_optab_libfunc (udiv_optab, SImode, 0);
+
+ /* Use the functions provided by the system library
+ for DImode integer division. */
+ set_optab_libfunc (sdiv_optab, DImode, "$sldiv");
+ set_optab_libfunc (udiv_optab, DImode, "$uldiv");
+ }
+ else if (TARGET_ABI_OPEN_VMS)
+ {
+ /* Use the VMS runtime library functions for division and
+ remainder. */
+ set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
+ set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
+ set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
+ set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
+ set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
+ set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
+ set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
+ set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
+ }
+}
+
+
+/* Initialize the GCC target structure. */
+#if TARGET_ABI_OPEN_VMS
+# undef TARGET_ATTRIBUTE_TABLE
+# define TARGET_ATTRIBUTE_TABLE vms_attribute_table
+# undef TARGET_SECTION_TYPE_FLAGS
+# define TARGET_SECTION_TYPE_FLAGS vms_section_type_flags
+#endif
+
+#undef TARGET_IN_SMALL_DATA_P
+#define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
+
+#if TARGET_ABI_UNICOSMK
+# undef TARGET_INSERT_ATTRIBUTES
+# define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
+# undef TARGET_SECTION_TYPE_FLAGS
+# define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
+# undef TARGET_ASM_UNIQUE_SECTION
+# define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
+# undef TARGET_ASM_GLOBALIZE_LABEL
+# define TARGET_ASM_GLOBALIZE_LABEL hook_void_FILEptr_constcharptr
+#endif
+
+#undef TARGET_ASM_ALIGNED_HI_OP
+#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
+#undef TARGET_ASM_ALIGNED_DI_OP
+#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
+
+/* Default unaligned ops are provided for ELF systems. To get unaligned
+ data for non-ELF systems, we have to turn off auto alignment. */
+#ifndef OBJECT_FORMAT_ELF
+#undef TARGET_ASM_UNALIGNED_HI_OP
+#define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
+#undef TARGET_ASM_UNALIGNED_SI_OP
+#define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
+#undef TARGET_ASM_UNALIGNED_DI_OP
+#define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
+#endif
+
+#ifdef OBJECT_FORMAT_ELF
+#undef TARGET_ASM_SELECT_RTX_SECTION
+#define TARGET_ASM_SELECT_RTX_SECTION alpha_elf_select_rtx_section
+#endif
+
+#undef TARGET_ASM_FUNCTION_END_PROLOGUE
+#define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
+
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
+
+#if TARGET_ABI_UNICOSMK
+#undef TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START unicosmk_file_start
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END unicosmk_file_end
+#else
+#undef TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START alpha_file_start
+#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
+#endif
+
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE \
+ alpha_use_dfa_pipeline_interface
+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
+ alpha_multipass_dfa_lookahead
+
+#undef TARGET_HAVE_TLS
+#define TARGET_HAVE_TLS HAVE_AS_TLS
+
+#undef TARGET_INIT_BUILTINS
+#define TARGET_INIT_BUILTINS alpha_init_builtins
+#undef TARGET_EXPAND_BUILTIN
+#define TARGET_EXPAND_BUILTIN alpha_expand_builtin
+
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
+#undef TARGET_CANNOT_COPY_INSN_P
+#define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
+
+#if TARGET_ABI_OSF
+#undef TARGET_ASM_OUTPUT_MI_THUNK
+#define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
+#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
+#endif
+
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS alpha_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
+
+#undef TARGET_MACHINE_DEPENDENT_REORG
+#define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
+
+#undef TARGET_PROMOTE_FUNCTION_ARGS
+#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
+#undef TARGET_PROMOTE_FUNCTION_RETURN
+#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
+#undef TARGET_PROMOTE_PROTOTYPES
+#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_false
+#undef TARGET_STRUCT_VALUE_RTX
+#define TARGET_STRUCT_VALUE_RTX hook_rtx_tree_int_null
+#undef TARGET_RETURN_IN_MEMORY
+#define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
+#undef TARGET_SETUP_INCOMING_VARARGS
+#define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
+#undef TARGET_STRICT_ARGUMENT_NAMING
+#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
+#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
+#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
+#undef TARGET_SPLIT_COMPLEX_ARG
+#define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
+
+#undef TARGET_BUILD_BUILTIN_VA_LIST
+#define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
+
+struct gcc_target targetm = TARGET_INITIALIZER;
+
+
#include "gt-alpha.h"
diff --git a/contrib/gcc/config/alpha/alpha.h b/contrib/gcc/config/alpha/alpha.h
index 6b52700e7e8f..d59797c103fa 100644
--- a/contrib/gcc/config/alpha/alpha.h
+++ b/contrib/gcc/config/alpha/alpha.h
@@ -1,22 +1,22 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -67,6 +67,8 @@ Boston, MA 02111-1307, USA. */
builtin_define ("_IEEE_FP"); \
if (TARGET_IEEE_WITH_INEXACT) \
builtin_define ("_IEEE_FP_INEXACT"); \
+ if (TARGET_LONG_DOUBLE_128) \
+ builtin_define ("__LONG_DOUBLE_128__"); \
\
/* Macros dependent on the C dialect. */ \
SUBTARGET_LANGUAGE_CPP_BUILTINS(); \
@@ -78,14 +80,14 @@ Boston, MA 02111-1307, USA. */
{ \
if (preprocessing_asm_p ()) \
builtin_define_std ("LANGUAGE_ASSEMBLY"); \
- else if (c_language == clk_c) \
- builtin_define_std ("LANGUAGE_C"); \
- else if (c_language == clk_cplusplus) \
+ else if (c_dialect_cxx ()) \
{ \
builtin_define ("__LANGUAGE_C_PLUS_PLUS"); \
builtin_define ("__LANGUAGE_C_PLUS_PLUS__"); \
} \
- if (flag_objc) \
+ else \
+ builtin_define_std ("LANGUAGE_C"); \
+ if (c_dialect_objc ()) \
{ \
builtin_define ("__LANGUAGE_OBJECTIVE_C"); \
builtin_define ("__LANGUAGE_OBJECTIVE_C__"); \
@@ -112,9 +114,12 @@ Boston, MA 02111-1307, USA. */
mirrors this list, so changes to alpha.md must be made at the same time. */
enum processor_type
- {PROCESSOR_EV4, /* 2106[46]{a,} */
+{
+ PROCESSOR_EV4, /* 2106[46]{a,} */
PROCESSOR_EV5, /* 21164{a,pc,} */
- PROCESSOR_EV6}; /* 21264 */
+ PROCESSOR_EV6, /* 21264 */
+ PROCESSOR_MAX
+};
extern enum processor_type alpha_cpu;
@@ -222,6 +227,15 @@ extern int alpha_tls_size;
#define MASK_TLS_KERNEL (1 << 14)
#define TARGET_TLS_KERNEL (target_flags & MASK_TLS_KERNEL)
+/* This means use direct branches to local functions. */
+#define MASK_SMALL_TEXT (1 << 15)
+#define TARGET_SMALL_TEXT (target_flags & MASK_SMALL_TEXT)
+
+/* This means use IEEE quad-format for long double. Assumes the
+ presence of the GEM support library routines. */
+#define MASK_LONG_DOUBLE_128 (1 << 16)
+#define TARGET_LONG_DOUBLE_128 (target_flags & MASK_LONG_DOUBLE_128)
+
/* This means that the processor is an EV5, EV56, or PCA56.
Unlike alpha_cpu this is not affected by -mtune= setting. */
#define MASK_CPU_EV5 (1 << 28)
@@ -254,7 +268,7 @@ extern int alpha_tls_size;
#define TARGET_CAN_FAULT_IN_PROLOGUE 0
#endif
#ifndef TARGET_HAS_XFLOATING_LIBS
-#define TARGET_HAS_XFLOATING_LIBS 0
+#define TARGET_HAS_XFLOATING_LIBS TARGET_LONG_DOUBLE_128
#endif
#ifndef TARGET_PROFILING_NEEDS_GP
#define TARGET_PROFILING_NEEDS_GP 0
@@ -310,8 +324,15 @@ extern int alpha_tls_size;
N_("Emit 16-bit relocations to the small data areas")}, \
{"large-data", -MASK_SMALL_DATA, \
N_("Emit 32-bit relocations to the small data areas")}, \
+ {"small-text", MASK_SMALL_TEXT, \
+ N_("Emit direct branches to local functions")}, \
+ {"large-text", -MASK_SMALL_TEXT, ""}, \
{"tls-kernel", MASK_TLS_KERNEL, \
N_("Emit rdval instead of rduniq for thread pointer")}, \
+ {"long-double-128", MASK_LONG_DOUBLE_128, \
+ N_("Use 128-bit long double")}, \
+ {"long-double-64", -MASK_LONG_DOUBLE_128, \
+ N_("Use 64-bit long double")}, \
{"", TARGET_DEFAULT | TARGET_CPU_DEFAULT \
| TARGET_DEFAULT_EXPLICIT_RELOCS, ""} }
@@ -340,27 +361,34 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
#define TARGET_OPTIONS \
{ \
{"cpu=", &alpha_cpu_string, \
- N_("Use features of and schedule given CPU")}, \
+ N_("Use features of and schedule given CPU"), 0}, \
{"tune=", &alpha_tune_string, \
- N_("Schedule given CPU")}, \
+ N_("Schedule given CPU"), 0}, \
{"fp-rounding-mode=", &alpha_fprm_string, \
- N_("Control the generated fp rounding mode")}, \
+ N_("Control the generated fp rounding mode"), 0}, \
{"fp-trap-mode=", &alpha_fptm_string, \
- N_("Control the IEEE trap mode")}, \
+ N_("Control the IEEE trap mode"), 0}, \
{"trap-precision=", &alpha_tp_string, \
- N_("Control the precision given to fp exceptions")}, \
+ N_("Control the precision given to fp exceptions"), 0}, \
{"memory-latency=", &alpha_mlat_string, \
- N_("Tune expected memory latency")}, \
+ N_("Tune expected memory latency"), 0}, \
{"tls-size=", &alpha_tls_size_string, \
- N_("Specify bit size of immediate TLS offsets")}, \
+ N_("Specify bit size of immediate TLS offsets"), 0}, \
}
+/* Support for a compile-time default CPU, et cetera. The rules are:
+ --with-cpu is ignored if -mcpu is specified.
+ --with-tune is ignored if -mtune is specified. */
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }
+
/* This macro defines names of additional specifications to put in the
specs that can be used in various specifications like CC1_SPEC. Its
definition is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
+ specification name, and a string constant that used by the GCC driver
program.
Do not define this macro if it does not need to do anything. */
@@ -421,7 +449,18 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
#define FLOAT_TYPE_SIZE 32
#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 64
+#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_128 ? 128 : 64)
+
+/* Define this to set long double type size to use in libgcc2.c, which can
+ not depend on target_flags. */
+#ifdef __LONG_DOUBLE_128__
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128
+#else
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
+#endif
+
+/* Work around target_flags dependency in ada/targtyps.c. */
+#define WIDEST_HARDWARE_FP_SIZE 64
#define WCHAR_TYPE "unsigned int"
#define WCHAR_TYPE_SIZE 32
@@ -444,15 +483,6 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
(MODE) = DImode; \
}
-/* Define this if function arguments should also be promoted using the above
- procedure. */
-
-#define PROMOTE_FUNCTION_ARGS
-
-/* Likewise, if the function return value is promoted. */
-
-#define PROMOTE_FUNCTION_RETURN
-
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields.
@@ -482,7 +512,7 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
#define PARM_BOUNDARY 64
/* Boundary (in *bits*) on which stack pointer should be aligned. */
-#define STACK_BOUNDARY 64
+#define STACK_BOUNDARY 128
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32
@@ -571,44 +601,30 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
/* List the order in which to allocate registers. Each register must be
- listed once, even those in FIXED_REGISTERS.
-
- We allocate in the following order:
- $f10-$f15 (nonsaved floating-point register)
- $f22-$f30 (likewise)
- $f21-$f16 (likewise, but input args)
- $f0 (nonsaved, but return value)
- $f1 (nonsaved, but immediate before saved)
- $f2-$f9 (saved floating-point registers)
- $1-$8 (nonsaved integer registers)
- $22-$25 (likewise)
- $28 (likewise)
- $0 (likewise, but return value)
- $21-$16 (likewise, but input args)
- $27 (procedure value in OSF, nonsaved in NT)
- $9-$14 (saved integer registers)
- $26 (return PC)
- $15 (frame pointer)
- $29 (global pointer)
- $30, $31, $f31 (stack pointer and always zero/ap & fp) */
-
-#define REG_ALLOC_ORDER \
- {42, 43, 44, 45, 46, 47, \
- 54, 55, 56, 57, 58, 59, 60, 61, 62, \
- 53, 52, 51, 50, 49, 48, \
- 32, 33, \
- 34, 35, 36, 37, 38, 39, 40, 41, \
- 1, 2, 3, 4, 5, 6, 7, 8, \
- 22, 23, 24, 25, \
- 28, \
- 0, \
- 21, 20, 19, 18, 17, 16, \
- 27, \
- 9, 10, 11, 12, 13, 14, \
- 26, \
- 15, \
- 29, \
- 30, 31, 63 }
+ listed once, even those in FIXED_REGISTERS. */
+
+#define REG_ALLOC_ORDER { \
+ 1, 2, 3, 4, 5, 6, 7, 8, /* nonsaved integer registers */ \
+ 22, 23, 24, 25, 28, /* likewise */ \
+ 0, /* likewise, but return value */ \
+ 21, 20, 19, 18, 17, 16, /* likewise, but input args */ \
+ 27, /* likewise, but OSF procedure value */ \
+ \
+ 42, 43, 44, 45, 46, 47, /* nonsaved floating-point registers */ \
+ 54, 55, 56, 57, 58, 59, /* likewise */ \
+ 60, 61, 62, /* likewise */ \
+ 32, 33, /* likewise, but return values */ \
+ 53, 52, 51, 50, 49, 48, /* likewise, but input args */ \
+ \
+ 9, 10, 11, 12, 13, 14, /* saved integer registers */ \
+ 26, /* return address */ \
+ 15, /* hard frame pointer */ \
+ \
+ 34, 35, 36, 37, 38, 39, /* saved floating-point registers */ \
+ 40, 41, /* likewise */ \
+ \
+ 29, 30, 31, 63 /* gp, sp, ap, sfp */ \
+}
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
@@ -620,12 +636,11 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
On Alpha, the integer registers can hold any mode. The floating-point
- registers can hold 32-bit and 64-bit integers as well, but not 16-bit
- or 8-bit values. */
+ registers can hold 64-bit integers as well, but not smaller values. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
((REGNO) >= 32 && (REGNO) <= 62 \
- ? GET_MODE_UNIT_SIZE (MODE) == 8 || GET_MODE_UNIT_SIZE (MODE) == 4 \
+ ? (MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode \
: 1)
/* Value is 1 if MODE is a supported vector mode. */
@@ -686,11 +701,6 @@ extern const char *alpha_tls_size_string; /* For -mtls-size= */
current_file functions. Moreover, we do not expose the ldgp
until after reload, so we're probably safe. */
/* #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED */
-
-/* Register in which address to store a structure value
- arrives in the function. On the Alpha, the address is passed
- as a hidden argument. */
-#define STRUCT_VALUE 0
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.
@@ -810,7 +820,7 @@ enum reg_class {
'U' is a symbolic operand.
- 'W' is a vector zero. */
+ 'W' is a vector zero. */
#define EXTRA_CONSTRAINT alpha_extra_constraint
@@ -953,19 +963,8 @@ extern int alpha_memory_latency;
/* Define the offset between two registers, one to be eliminated, and the other
its replacement, at the start of a routine. */
-#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-{ if ((FROM) == FRAME_POINTER_REGNUM) \
- (OFFSET) = (ALPHA_ROUND (current_function_outgoing_args_size) \
- + alpha_sa_size ()); \
- else if ((FROM) == ARG_POINTER_REGNUM) \
- (OFFSET) = (ALPHA_ROUND (current_function_outgoing_args_size) \
- + alpha_sa_size () \
- + (ALPHA_ROUND (get_frame_size () \
- + current_function_pretend_args_size) \
- - current_function_pretend_args_size)); \
- else \
- abort (); \
-}
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ ((OFFSET) = alpha_initial_elimination_offset(FROM, TO))
/* Define this if stack space is still allocated for a parameter passed
in a register. */
@@ -988,37 +987,14 @@ extern int alpha_memory_latency;
On Alpha the value is found in $0 for integer functions and
$f0 for floating-point functions. */
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx_REG (((INTEGRAL_TYPE_P (VALTYPE) \
- && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
- || POINTER_TYPE_P (VALTYPE)) \
- ? word_mode : TYPE_MODE (VALTYPE), \
- ((TARGET_FPREGS \
- && (TREE_CODE (VALTYPE) == REAL_TYPE \
- || TREE_CODE (VALTYPE) == COMPLEX_TYPE)) \
- ? 32 : 0))
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+ function_value (VALTYPE, FUNC, VOIDmode)
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
-#define LIBCALL_VALUE(MODE) \
- gen_rtx_REG (MODE, \
- (TARGET_FPREGS \
- && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
- ? 32 : 0))
-
-/* The definition of this macro implies that there are cases where
- a scalar value cannot be returned in registers.
-
- For the Alpha, any structure or union type is returned in memory, as
- are integers whose size is larger than 64 bits. */
-
-#define RETURN_IN_MEMORY(TYPE) \
- (TYPE_MODE (TYPE) == BLKmode \
- || TYPE_MODE (TYPE) == TFmode \
- || TYPE_MODE (TYPE) == TCmode \
- || (TREE_CODE (TYPE) == INTEGER_TYPE && TYPE_PRECISION (TYPE) > 64))
+#define LIBCALL_VALUE(MODE) \
+ function_value (NULL, NULL, MODE)
/* 1 if N is a possible register number for a function value
as seen by the caller. */
@@ -1048,7 +1024,8 @@ extern int alpha_memory_latency;
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) (CUM) = 0
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
+ (CUM) = 0
/* Define intermediate macro to compute the size (in registers) of an argument
for the Alpha. */
@@ -1096,13 +1073,6 @@ extern int alpha_memory_latency;
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
((MODE) == TFmode || (MODE) == TCmode)
-/* Specify the padding direction of arguments.
-
- On the Alpha, we must pad upwards in order to be able to pass args in
- registers. */
-
-#define FUNCTION_ARG_PADDING(MODE, TYPE) upward
-
/* For an arg passed partly in registers and partly in memory,
this is the number of registers used.
For args passed entirely in registers or entirely in memory, zero. */
@@ -1111,68 +1081,6 @@ extern int alpha_memory_latency;
((CUM) < 6 && 6 < (CUM) + ALPHA_ARG_SIZE (MODE, TYPE, NAMED) \
? 6 - (CUM) : 0)
-/* Perform any needed actions needed for a function that is receiving a
- variable number of arguments.
-
- CUM is as above.
-
- MODE and TYPE are the mode and type of the current parameter.
-
- PRETEND_SIZE is a variable that should be set to the amount of stack
- that must be pushed by the prolog to pretend that our caller pushed
- it.
-
- Normally, this macro will push all remaining incoming registers on the
- stack and set PRETEND_SIZE to the length of the registers pushed.
-
- On the Alpha, we allocate space for all 12 arg registers, but only
- push those that are remaining.
-
- However, if NO registers need to be saved, don't allocate any space.
- This is not only because we won't need the space, but because AP includes
- the current_pretend_args_size and we don't want to mess up any
- ap-relative addresses already made.
-
- If we are not to use the floating-point registers, save the integer
- registers where we would put the floating-point registers. This is
- not the most efficient way to implement varargs with just one register
- class, but it isn't worth doing anything more efficient in this rare
- case. */
-
-#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
-{ if ((CUM) < 6) \
- { \
- if (! (NO_RTL)) \
- { \
- rtx tmp; int set = get_varargs_alias_set (); \
- tmp = gen_rtx_MEM (BLKmode, \
- plus_constant (virtual_incoming_args_rtx, \
- ((CUM) + 6)* UNITS_PER_WORD)); \
- set_mem_alias_set (tmp, set); \
- move_block_from_reg \
- (16 + CUM, tmp, \
- 6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD); \
- \
- tmp = gen_rtx_MEM (BLKmode, \
- plus_constant (virtual_incoming_args_rtx, \
- (CUM) * UNITS_PER_WORD)); \
- set_mem_alias_set (tmp, set); \
- move_block_from_reg \
- (16 + (TARGET_FPREGS ? 32 : 0) + CUM, tmp, \
- 6 - (CUM), (6 - (CUM)) * UNITS_PER_WORD); \
- } \
- PRETEND_SIZE = 12 * UNITS_PER_WORD; \
- } \
-}
-
-/* We do not allow indirect calls to be optimized into sibling calls, nor
- can we allow a call to a function in a different compilation unit to
- be optimized into a sibcall. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) \
- (DECL \
- && (! TREE_PUBLIC (DECL) \
- || (TREE_ASM_WRITTEN (DECL) && (*targetm.binds_local_p) (DECL))))
-
/* 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
@@ -1212,6 +1120,10 @@ extern struct alpha_compare alpha_compare;
#define PROFILE_BEFORE_PROLOGUE 1
+/* Never use profile counters. */
+
+#define NO_PROFILE_COUNTERS 1
+
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. Under OSF/1, profiling is enabled
by simply passing -pg to the assembler and linker. */
@@ -1287,12 +1199,6 @@ do { \
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT 0 */
-/* #define HAVE_POST_DECREMENT 0 */
-
-/* #define HAVE_PRE_DECREMENT 0 */
-/* #define HAVE_PRE_INCREMENT 0 */
-
/* Macros to check register numbers against specific register classes. */
/* These assume that REGNO is a hard or pseudo reg number.
@@ -1417,14 +1323,6 @@ do { \
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
{ if (GET_CODE (ADDR) == AND) goto LABEL; }
-
-/* Compute the cost of an address. For the Alpha, all valid addresses are
- the same cost. */
-
-#define ADDRESS_COST(X) 0
-
-/* Machine-dependent reorg pass. */
-#define MACHINE_DEPENDENT_REORG(X) alpha_reorg(X)
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */
@@ -1443,14 +1341,6 @@ do { \
/* Define this as 1 if `char' should by default be signed; else as 0. */
#define DEFAULT_SIGNED_CHAR 1
-/* This flag, if defined, says the same insns that convert to a signed fixnum
- also convert validly to an unsigned one.
-
- We actually lie a bit here as overflow conditions are different. But
- they aren't being checked anyway. */
-
-#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
-
/* Max number of bytes we can move to or from memory
in one reasonably fast instruction. */
@@ -1494,10 +1384,9 @@ do { \
is done just by pretending it is already truncated. */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-/* We assume that the store-condition-codes instructions store 0 for false
- and some other value for true. This is the value stored for true. */
-
-#define STORE_FLAG_VALUE 1
+/* The CIX ctlz and cttz instructions return 64 for zero. */
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, TARGET_CIX)
+#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, TARGET_CIX)
/* Define the value returned by a floating-point comparison instruction. */
@@ -1548,162 +1437,6 @@ do { \
/* Define this to be nonzero if shift instructions ignore all but the low-order
few bits. */
#define SHIFT_COUNT_TRUNCATED 1
-
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch.
-
- If this is an 8-bit constant, return zero since it can be used
- nearly anywhere with no cost. If it is a valid operand for an
- ADD or AND, likewise return 0 if we know it will be used in that
- context. Otherwise, return 2 since it might be used there later.
- All other constants take at least two insns. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (INTVAL (RTX) >= 0 && INTVAL (RTX) < 256) \
- return 0; \
- case CONST_DOUBLE: \
- if ((RTX) == CONST0_RTX (GET_MODE (RTX))) \
- return 0; \
- else if (((OUTER_CODE) == PLUS && add_operand (RTX, VOIDmode)) \
- || ((OUTER_CODE) == AND && and_operand (RTX, VOIDmode))) \
- return 0; \
- else if (add_operand (RTX, VOIDmode) || and_operand (RTX, VOIDmode)) \
- return 2; \
- else \
- return COSTS_N_INSNS (2); \
- case CONST: \
- case SYMBOL_REF: \
- case LABEL_REF: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- return COSTS_N_INSNS (3); \
- case PROCESSOR_EV5: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (2); \
- default: abort(); \
- }
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case PLUS: case MINUS: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- return COSTS_N_INSNS (6); \
- case PROCESSOR_EV5: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (4); \
- default: abort(); \
- } \
- else if (GET_CODE (XEXP (X, 0)) == MULT \
- && const48_operand (XEXP (XEXP (X, 0), 1), VOIDmode)) \
- return (2 + rtx_cost (XEXP (XEXP (X, 0), 0), OUTER_CODE) \
- + rtx_cost (XEXP (X, 1), OUTER_CODE)); \
- break; \
- case MULT: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- return COSTS_N_INSNS (6); \
- return COSTS_N_INSNS (23); \
- case PROCESSOR_EV5: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- return COSTS_N_INSNS (4); \
- else if (GET_MODE (X) == DImode) \
- return COSTS_N_INSNS (12); \
- else \
- return COSTS_N_INSNS (8); \
- case PROCESSOR_EV6: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- return COSTS_N_INSNS (4); \
- else \
- return COSTS_N_INSNS (7); \
- default: abort(); \
- } \
- case ASHIFT: \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && INTVAL (XEXP (X, 1)) <= 3) \
- break; \
- /* ... fall through ... */ \
- case ASHIFTRT: case LSHIFTRT: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- return COSTS_N_INSNS (2); \
- case PROCESSOR_EV5: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (1); \
- default: abort(); \
- } \
- case IF_THEN_ELSE: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (2); \
- case PROCESSOR_EV5: \
- return COSTS_N_INSNS (1); \
- default: abort(); \
- } \
- case DIV: case UDIV: case MOD: case UMOD: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- if (GET_MODE (X) == SFmode) \
- return COSTS_N_INSNS (34); \
- else if (GET_MODE (X) == DFmode) \
- return COSTS_N_INSNS (63); \
- else \
- return COSTS_N_INSNS (70); \
- case PROCESSOR_EV5: \
- if (GET_MODE (X) == SFmode) \
- return COSTS_N_INSNS (15); \
- else if (GET_MODE (X) == DFmode) \
- return COSTS_N_INSNS (22); \
- else \
- return COSTS_N_INSNS (70); /* ??? */ \
- case PROCESSOR_EV6: \
- if (GET_MODE (X) == SFmode) \
- return COSTS_N_INSNS (12); \
- else if (GET_MODE (X) == DFmode) \
- return COSTS_N_INSNS (15); \
- else \
- return COSTS_N_INSNS (70); /* ??? */ \
- default: abort(); \
- } \
- case MEM: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (3); \
- case PROCESSOR_EV5: \
- return COSTS_N_INSNS (2); \
- default: abort(); \
- } \
- case NEG: case ABS: \
- if (! FLOAT_MODE_P (GET_MODE (X))) \
- break; \
- /* ... fall through ... */ \
- case FLOAT: case UNSIGNED_FLOAT: case FIX: case UNSIGNED_FIX: \
- case FLOAT_EXTEND: case FLOAT_TRUNCATE: \
- switch (alpha_cpu) \
- { \
- case PROCESSOR_EV4: \
- return COSTS_N_INSNS (6); \
- case PROCESSOR_EV5: \
- case PROCESSOR_EV6: \
- return COSTS_N_INSNS (4); \
- default: abort(); \
- }
/* Control the assembler format that we output. */
@@ -1759,18 +1492,12 @@ do { \
#define USER_LABEL_PREFIX ""
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, "$%s%d:\n", PREFIX, NUM)
-
/* This is how to output a label for a jump table. Arguments are the same as
- for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
+ for (*targetm.asm_out.internal_label), except the insn for the jump table is
passed. */
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
-{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
+{ ASM_OUTPUT_ALIGN (FILE, 2); (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); }
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
@@ -1824,22 +1551,6 @@ do { \
} \
while (0)
-/* This is how to output an insn to push a register on the stack.
- It need not be very fast code. */
-
-#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
- fprintf (FILE, "\tsubq $30,8,$30\n\tst%s $%s%d,0($30)\n", \
- (REGNO) > 32 ? "t" : "q", (REGNO) > 32 ? "f" : "", \
- (REGNO) & 31);
-
-/* This is how to output an insn to pop a register from the stack.
- It need not be very fast code. */
-
-#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
- fprintf (FILE, "\tld%s $%s%d,0($30)\n\taddq $30,8,$30\n", \
- (REGNO) > 32 ? "t" : "q", (REGNO) > 32 ? "f" : "", \
- (REGNO) & 31);
-
/* This is how to output an element of a case-vector that is absolute.
(Alpha does not use such vectors, but we must define this macro anyway.) */
@@ -1862,7 +1573,7 @@ do { \
/* This is how to advance the location counter by SIZE bytes. */
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.space %d\n", (SIZE))
+ fprintf (FILE, "\t.space "HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
/* This says how to output an assembler line
to define a global common symbol. */
@@ -1870,7 +1581,7 @@ do { \
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs ("\t.comm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%d\n", (SIZE)))
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)))
/* This says how to output an assembler line
to define a local common symbol. */
@@ -1878,15 +1589,7 @@ do { \
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE,ROUNDED) \
( fputs ("\t.lcomm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%d\n", (SIZE)))
-
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable named NAME.
- LABELNO is an integer which is different for each call. */
-
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)))
/* Print operand X (an rtx) in assembler syntax to file FILE.
@@ -1908,11 +1611,14 @@ do { \
- Generates double precision suffix for floating point
instructions (t for IEEE, g for VAX)
+
+ + Generates a nop instruction after a noreturn call at the very end
+ of the function
*/
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
((CODE) == '/' || (CODE) == ',' || (CODE) == '-' || (CODE) == '~' \
- || (CODE) == '#' || (CODE) == '*' || (CODE) == '&')
+ || (CODE) == '#' || (CODE) == '*' || (CODE) == '&' || (CODE) == '+')
/* Print a memory address as an operand to reference that memory location. */
@@ -1943,8 +1649,9 @@ do { \
{"signed_comparison_operator", {EQ, NE, LE, LT, GE, GT}}, \
{"alpha_fp_comparison_operator", {EQ, LE, LT, UNORDERED}}, \
{"divmod_operator", {DIV, MOD, UDIV, UMOD}}, \
+ {"fix_operator", {FIX, UNSIGNED_FIX}}, \
{"const0_operand", {CONST_INT, CONST_DOUBLE, CONST_VECTOR}}, \
- {"current_file_function_operand", {SYMBOL_REF}}, \
+ {"samegp_function_operand", {SYMBOL_REF}}, \
{"direct_call_operand", {SYMBOL_REF}}, \
{"local_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{"small_symbolic_operand", {SYMBOL_REF, CONST}}, \
@@ -1965,6 +1672,7 @@ do { \
{"unaligned_memory_operand", {MEM}}, \
{"reg_or_unaligned_mem_operand", {SUBREG, REG, MEM}}, \
{"any_memory_operand", {MEM}}, \
+ {"normal_memory_operand", {MEM}}, \
{"hard_fp_register_operand", {SUBREG, REG}}, \
{"hard_int_register_operand", {SUBREG, REG}}, \
{"reg_not_elim_operand", {SUBREG, REG}}, \
@@ -1974,10 +1682,6 @@ do { \
{"some_small_symbolic_operand", {SET, PARALLEL, PREFETCH, UNSPEC, \
UNSPEC_VOLATILE}},
-/* Define the `__builtin_va_list' type for the ABI. */
-#define BUILD_VA_LIST_TYPE(VALIST) \
- (VALIST) = alpha_build_va_list ()
-
/* Implement `va_start' for varargs and stdarg. */
#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
alpha_va_start (valist, nextarg)
@@ -2024,7 +1728,7 @@ extern long alpha_auto_offset;
#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET + alpha_arg_offset)
-#define ASM_OUTPUT_SOURCE_LINE(STREAM, LINE) \
+#define ASM_OUTPUT_SOURCE_LINE(STREAM, LINE, COUNTER) \
alpha_output_lineno (STREAM, LINE)
#define ASM_OUTPUT_SOURCE_FILENAME(STREAM, NAME) \
diff --git a/contrib/gcc/config/alpha/alpha.md b/contrib/gcc/config/alpha/alpha.md
index f7e9fa404bc9..998e30055aee 100644
--- a/contrib/gcc/config/alpha/alpha.md
+++ b/contrib/gcc/config/alpha/alpha.md
@@ -1,22 +1,22 @@
;; Machine description for DEC Alpha for GNU C compiler
;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-;; 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+;; 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
@@ -30,7 +30,7 @@
(UNSPEC_INSXH 2)
(UNSPEC_MSKXH 3)
(UNSPEC_CVTQL 4)
- (UNSPEC_NT_LDA 5)
+ (UNSPEC_CVTLQ 5)
(UNSPEC_UMK_LAUM 6)
(UNSPEC_UMK_LALM 7)
(UNSPEC_UMK_LAL 8)
@@ -97,8 +97,8 @@
;; separately.
(define_attr "type"
- "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,\
-fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
+ "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,
+ icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_string "iadd"))
;; Describe a user's asm statement.
@@ -120,7 +120,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
;; The ROUND_SUFFIX attribute marks which instructions require a
;; rounding-mode suffix. The value NONE indicates no suffix,
-;; the value NORMAL indicates a suffix controled by alpha_fprm.
+;; the value NORMAL indicates a suffix controlled by alpha_fprm.
(define_attr "round_suffix" "none,normal,c"
(const_string "none"))
@@ -133,7 +133,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
;; V_SV_SVI accepts /v, /sv and /svi (cvttq only)
;; U_SU_SUI accepts /u, /su and /sui (most fp instructions)
;;
-;; The actual suffix emitted is controled by alpha_fptm.
+;; The actual suffix emitted is controlled by alpha_fptm.
(define_attr "trap_suffix" "none,su,sui,v_sv,v_sv_svi,u_su_sui"
(const_string "none"))
@@ -154,6 +154,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
]
(const_string "no")))
+;; The CANNOT_COPY attribute marks instructions with relocations that
+;; cannot easily be duplicated. This includes insns with gpdisp relocs
+;; since they have to stay in 1-1 correspondence with one another. This
+;; also includes jsr insns, since they must stay in correspondence with
+;; the immediately following gpdisp instructions.
+
+(define_attr "cannot_copy" "false,true"
+ (const_string "false"))
;; Include scheduling descriptions.
@@ -177,41 +185,36 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
""
"")
-(define_insn "*extendsidi2_nofix"
- [(set (match_operand:DI 0 "register_operand" "=r,r,*f,?*f")
- (sign_extend:DI
- (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,m")))]
- "! TARGET_FIX"
- "@
- addl $31,%1,%0
- ldl %0,%1
- cvtlq %1,%0
- lds %0,%1\;cvtlq %0,%0"
- [(set_attr "type" "iadd,ild,fadd,fld")
- (set_attr "length" "*,*,*,8")])
+(define_insn "*cvtlq"
+ [(set (match_operand:DI 0 "register_operand" "=f")
+ (unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")]
+ UNSPEC_CVTLQ))]
+ ""
+ "cvtlq %1,%0"
+ [(set_attr "type" "fadd")])
-(define_insn "*extendsidi2_fix"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r,?*f,?*f")
+(define_insn "*extendsidi2_1"
+ [(set (match_operand:DI 0 "register_operand" "=r,r,!*f")
(sign_extend:DI
- (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,*f,m")))]
- "TARGET_FIX"
+ (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
+ ""
"@
addl $31,%1,%0
ldl %0,%1
- ftois %1,%0
- cvtlq %1,%0
lds %0,%1\;cvtlq %0,%0"
- [(set_attr "type" "iadd,ild,ftoi,fadd,fld")
- (set_attr "length" "*,*,*,*,8")])
+ [(set_attr "type" "iadd,ild,fld")
+ (set_attr "length" "*,*,8")])
-;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
(define_split
[(set (match_operand:DI 0 "hard_fp_register_operand" "")
(sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
"reload_completed"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (sign_extend:DI (match_dup 2)))]
- "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
+ (set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+ operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));
+})
;; Optimize sign-extension of SImode loads. This shows up in the wake of
;; reload when converting fp->int.
@@ -227,28 +230,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(sign_extend:DI (match_dup 1)))]
"")
-(define_peephole2
- [(set (match_operand:SI 0 "hard_int_register_operand" "")
- (match_operand:SI 1 "hard_fp_register_operand" ""))
- (set (match_operand:DI 2 "hard_int_register_operand" "")
- (sign_extend:DI (match_dup 0)))]
- "TARGET_FIX
- && (true_regnum (operands[0]) == true_regnum (operands[2])
- || peep2_reg_dead_p (2, operands[0]))"
- [(set (match_dup 2)
- (sign_extend:DI (match_dup 1)))]
- "")
-
-(define_peephole2
- [(set (match_operand:DI 0 "hard_fp_register_operand" "")
- (sign_extend:DI (match_operand:SI 1 "hard_fp_register_operand" "")))
- (set (match_operand:DI 2 "hard_int_register_operand" "")
- (match_dup 0))]
- "TARGET_FIX && peep2_reg_dead_p (2, operands[0])"
- [(set (match_dup 2)
- (sign_extend:DI (match_dup 1)))]
- "")
-
;; Don't say we have addsi3 if optimizing. This generates better code. We
;; have the anonymous addsi3 pattern below in case combine wants to make it.
(define_expand "addsi3"
@@ -413,7 +394,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
(high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
- "TARGET_EXPLICIT_RELOCS"
+ "TARGET_EXPLICIT_RELOCS && reload_completed"
"ldah %0,%2(%1)\t\t!gprelhigh"
[(set_attr "usegp" "yes")])
@@ -1337,7 +1318,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"eqv %r1,%2,%0"
[(set_attr "type" "ilog")])
-;; Handle the FFS insn iff we support CIX.
+;; Handle FFS and related insns iff we support CIX.
(define_expand "ffsdi2"
[(set (match_dup 2)
@@ -1361,6 +1342,27 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just
; reuse the existing type name.
[(set_attr "type" "mvi")])
+
+(define_insn "clzdi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (clz:DI (match_operand:DI 1 "register_operand" "r")))]
+ "TARGET_CIX"
+ "ctlz %1,%0"
+ [(set_attr "type" "mvi")])
+
+(define_insn "ctzdi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ctz:DI (match_operand:DI 1 "register_operand" "r")))]
+ "TARGET_CIX"
+ "cttz %1,%0"
+ [(set_attr "type" "mvi")])
+
+(define_insn "popcountdi2"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
+ "TARGET_CIX"
+ "ctpop %1,%0"
+ [(set_attr "type" "mvi")])
;; Next come the shifts and the various extract and insert operations.
@@ -2305,8 +2307,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
;; processing, it is cheaper to do the truncation in the int regs.
(define_insn "*cvtql"
- [(set (match_operand:SI 0 "register_operand" "=f")
- (unspec:SI [(match_operand:DI 1 "reg_or_0_operand" "fG")]
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")]
UNSPEC_CVTQL))]
"TARGET_FP"
"cvtql%/ %R1,%0"
@@ -2316,37 +2318,46 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(define_insn_and_split "*fix_truncdfsi_ieee"
[(set (match_operand:SI 0 "memory_operand" "=m")
- (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")) 0))
+ (subreg:SI
+ (match_operator:DI 4 "fix_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
(clobber (match_scratch:DI 2 "=&f"))
- (clobber (match_scratch:SI 3 "=&f"))]
+ (clobber (match_scratch:SF 3 "=&f"))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"#"
"&& reload_completed"
- [(set (match_dup 2) (fix:DI (match_dup 1)))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
- (set (match_dup 0) (match_dup 3))]
- ""
+ [(set (match_dup 2) (match_op_dup 4 [(match_dup 1)]))
+ (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 5) (match_dup 3))]
+{
+ operands[5] = adjust_address (operands[0], SFmode, 0);
+}
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
(define_insn_and_split "*fix_truncdfsi_internal"
[(set (match_operand:SI 0 "memory_operand" "=m")
- (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")) 0))
+ (subreg:SI
+ (match_operator:DI 3 "fix_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
(clobber (match_scratch:DI 2 "=f"))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"#"
"&& reload_completed"
- [(set (match_dup 2) (fix:DI (match_dup 1)))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
- (set (match_dup 0) (match_dup 3))]
- ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
- "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
+ [(set (match_dup 2) (match_op_dup 3 [(match_dup 1)]))
+ (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 5) (match_dup 4))]
+{
+ operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
+ operands[5] = adjust_address (operands[0], SFmode, 0);
+}
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
(define_insn "*fix_truncdfdi_ieee"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
- (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+ (match_operator:DI 2 "fix_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
@@ -2354,9 +2365,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(set_attr "round_suffix" "c")
(set_attr "trap_suffix" "v_sv_svi")])
-(define_insn "fix_truncdfdi2"
+(define_insn "*fix_truncdfdi2"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
- (fix:DI (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+ (match_operator:DI 2 "fix_operator"
+ [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
"TARGET_FP"
"cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
@@ -2364,44 +2376,64 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(set_attr "round_suffix" "c")
(set_attr "trap_suffix" "v_sv_svi")])
+(define_expand "fix_truncdfdi2"
+ [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ (fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
+ "TARGET_FP"
+ "")
+
+(define_expand "fixuns_truncdfdi2"
+ [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
+ "TARGET_FP"
+ "")
+
;; Likewise between SFmode and SImode.
(define_insn_and_split "*fix_truncsfsi_ieee"
[(set (match_operand:SI 0 "memory_operand" "=m")
- (subreg:SI (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))) 0))
+ (subreg:SI
+ (match_operator:DI 4 "fix_operator"
+ [(float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
(clobber (match_scratch:DI 2 "=&f"))
- (clobber (match_scratch:SI 3 "=&f"))]
+ (clobber (match_scratch:SF 3 "=&f"))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"#"
"&& reload_completed"
- [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
- (set (match_dup 0) (match_dup 3))]
- ""
+ [(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))]))
+ (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 5) (match_dup 3))]
+{
+ operands[5] = adjust_address (operands[0], SFmode, 0);
+}
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
(define_insn_and_split "*fix_truncsfsi_internal"
[(set (match_operand:SI 0 "memory_operand" "=m")
- (subreg:SI (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))) 0))
+ (subreg:SI
+ (match_operator:DI 3 "fix_operator"
+ [(float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
(clobber (match_scratch:DI 2 "=f"))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"#"
"&& reload_completed"
- [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
- (set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_CVTQL))
- (set (match_dup 0) (match_dup 3))]
- ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
- "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
+ [(set (match_dup 2) (match_op_dup 3 [(float_extend:DF (match_dup 1))]))
+ (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
+ (set (match_dup 5) (match_dup 4))]
+{
+ operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
+ operands[5] = adjust_address (operands[0], SFmode, 0);
+}
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
(define_insn "*fix_truncsfdi_ieee"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
- (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))))]
+ (match_operator:DI 2 "fix_operator"
+ [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
"cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
@@ -2409,10 +2441,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(set_attr "round_suffix" "c")
(set_attr "trap_suffix" "v_sv_svi")])
-(define_insn "fix_truncsfdi2"
+(define_insn "*fix_truncsfdi2"
[(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
- (fix:DI (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))))]
+ (match_operator:DI 2 "fix_operator"
+ [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
"TARGET_FP"
"cvt%-q%/ %R1,%0"
[(set_attr "type" "fadd")
@@ -2420,12 +2452,31 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(set_attr "round_suffix" "c")
(set_attr "trap_suffix" "v_sv_svi")])
+(define_expand "fix_truncsfdi2"
+ [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
+ "TARGET_FP"
+ "")
+
+(define_expand "fixuns_truncsfdi2"
+ [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ (unsigned_fix:DI
+ (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
+ "TARGET_FP"
+ "")
+
(define_expand "fix_trunctfdi2"
[(use (match_operand:DI 0 "register_operand" ""))
(use (match_operand:TF 1 "general_operand" ""))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (FIX, operands); DONE;")
+(define_expand "fixuns_trunctfdi2"
+ [(use (match_operand:DI 0 "register_operand" ""))
+ (use (match_operand:TF 1 "general_operand" ""))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;")
+
(define_insn "*floatdisf_ieee"
[(set (match_operand:SF 0 "register_operand" "=&f")
(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
@@ -2446,6 +2497,35 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "sui")])
+(define_insn_and_split "*floatsisf2_ieee"
+ [(set (match_operand:SF 0 "register_operand" "=&f")
+ (float:SF (match_operand:SI 1 "memory_operand" "m")))
+ (clobber (match_scratch:DI 2 "=&f"))
+ (clobber (match_scratch:SF 3 "=&f"))]
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+ (set (match_dup 0) (float:SF (match_dup 2)))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+})
+
+(define_insn_and_split "*floatsisf2"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (float:SF (match_operand:SI 1 "memory_operand" "m")))]
+ "TARGET_FP"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (match_dup 1))
+ (set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ))
+ (set (match_dup 0) (float:SF (match_dup 2)))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+ operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
+})
+
(define_insn "*floatdidf_ieee"
[(set (match_operand:DF 0 "register_operand" "=&f")
(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
@@ -2466,6 +2546,36 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "sui")])
+(define_insn_and_split "*floatsidf2_ieee"
+ [(set (match_operand:DF 0 "register_operand" "=&f")
+ (float:DF (match_operand:SI 1 "memory_operand" "m")))
+ (clobber (match_scratch:DI 2 "=&f"))
+ (clobber (match_scratch:SF 3 "=&f"))]
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+ (set (match_dup 0) (float:DF (match_dup 2)))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+})
+
+(define_insn_and_split "*floatsidf2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (float:DF (match_operand:SI 1 "memory_operand" "m")))]
+ "TARGET_FP"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
+ (set (match_dup 0) (float:DF (match_dup 2)))]
+{
+ operands[1] = adjust_address (operands[1], SFmode, 0);
+ operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
+ operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]));
+})
+
(define_expand "floatditf2"
[(use (match_operand:TF 0 "register_operand" ""))
(use (match_operand:DI 1 "general_operand" ""))]
@@ -4594,7 +4704,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
- bsr $26,$%0..ng
+ bsr $26,%0\t\t!samegp
ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
[(set_attr "type" "jsr")
(set_attr "length" "12,*,16")])
@@ -4607,8 +4717,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
- && ! current_file_function_operand (operands[0], Pmode)
- && peep2_regno_dead_p (1, 29)"
+ && ! samegp_function_operand (operands[0], Pmode)
+ && (peep2_regno_dead_p (1, 29)
+ || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
[(parallel [(call (mem:DI (match_dup 2))
(match_dup 1))
(set (reg:DI 26) (plus:DI (pc) (const_int 4)))
@@ -4637,8 +4748,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
- && ! current_file_function_operand (operands[0], Pmode)
- && ! peep2_regno_dead_p (1, 29)"
+ && ! samegp_function_operand (operands[0], Pmode)
+ && ! (peep2_regno_dead_p (1, 29)
+ || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
[(parallel [(call (mem:DI (match_dup 2))
(match_dup 1))
(set (reg:DI 26) (plus:DI (pc) (const_int 4)))
@@ -4678,7 +4790,18 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (match_operand 3 "const_int_operand" ""))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%0),%2%J3"
- [(set_attr "type" "jsr")])
+ [(set_attr "type" "jsr")
+ (set_attr "cannot_copy" "true")])
+
+;; We output a nop after noreturn calls at the very end of the function to
+;; ensure that the return address always remains in the caller's code range,
+;; as not doing so might confuse unwinding engines.
+;;
+;; The potential change in insn length is not reflected in the length
+;; attributes at this stage. Since the extra space is only actually added at
+;; the very end of the compilation process (via final/print_operand), it
+;; really seems harmless and not worth the trouble of some extra computation
+;; cost and complexity.
(define_insn "*call_osf_1_noreturn"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
@@ -4688,9 +4811,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
"@
- jsr $26,($27),0
- bsr $26,$%0..ng
- jsr $26,%0"
+ jsr $26,($27),0%+
+ bsr $26,$%0..ng%+
+ jsr $26,%0%+"
[(set_attr "type" "jsr")
(set_attr "length" "*,*,8")])
@@ -4715,7 +4838,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
- br $31,$%0..ng
+ br $31,%0\t\t!samegp
ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#"
[(set_attr "type" "jsr")
(set_attr "length" "*,8")])
@@ -4754,20 +4877,19 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (reg:DI 26))
(clobber (reg:DI 27))]
"TARGET_ABI_OPEN_VMS"
- "*
{
switch (which_alternative)
{
case 0:
- return \"mov %2,$27\;jsr $26,0\;ldq $27,0($29)\";
+ return "mov %2,$27\;jsr $26,0\;ldq $27,0($29)";
case 1:
operands [2] = alpha_use_linkage (operands [0], cfun->decl, 1, 0);
operands [3] = alpha_use_linkage (operands [0], cfun->decl, 0, 0);
- return \"ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)\";
+ return "ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)";
default:
abort();
}
-}"
+}
[(set_attr "type" "jsr")
(set_attr "length" "12,16")])
@@ -5086,27 +5208,10 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
operands[1] = force_reg (TFmode, operands[1]);
})
-(define_insn "*movsi_nofix"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
- (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
- "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK) && ! TARGET_FIX
- && (register_operand (operands[0], SImode)
- || reg_or_0_operand (operands[1], SImode))"
- "@
- bis $31,%r1,%0
- lda %0,%1($31)
- ldah %0,%h1($31)
- ldl %0,%1
- stl %r1,%0
- cpys %R1,%R1,%0
- ld%, %0,%1
- st%, %R1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
-
-(define_insn "*movsi_fix"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
- (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
- "TARGET_ABI_OSF && TARGET_FIX
+(define_insn "*movsi"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m")
+ (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ"))]
+ "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK)
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
@@ -5114,38 +5219,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
lda %0,%1($31)
ldah %0,%h1($31)
ldl %0,%1
- stl %r1,%0
- cpys %R1,%R1,%0
- ld%, %0,%1
- st%, %R1,%0
- ftois %1,%0
- itofs %1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
-
-(define_insn "*movsi_nt_vms_nofix"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
- (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
- "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
- && !TARGET_FIX
- && (register_operand (operands[0], SImode)
- || reg_or_0_operand (operands[1], SImode))"
- "@
- bis $31,%1,%0
- lda %0,%1
- ldah %0,%h1
- lda %0,%1
- ldl %0,%1
- stl %r1,%0
- cpys %R1,%R1,%0
- ld%, %0,%1
- st%, %R1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
+ stl %r1,%0"
+ [(set_attr "type" "ilog,iadd,iadd,ild,ist")])
-(define_insn "*movsi_nt_vms_fix"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m,r,*f")
- (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f,*f,r"))]
+(define_insn "*movsi_nt_vms"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m")
+ (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ"))]
"(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
- && TARGET_FIX
&& (register_operand (operands[0], SImode)
|| reg_or_0_operand (operands[1], SImode))"
"@
@@ -5154,13 +5234,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
ldah %0,%h1
lda %0,%1
ldl %0,%1
- stl %r1,%0
- cpys %R1,%R1,%0
- ld%, %0,%1
- st%, %R1,%0
- ftois %1,%0
- itofs %1,%0"
- [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
+ stl %r1,%0"
+ [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist")])
(define_insn "*movhi_nobwx"
[(set (match_operand:HI 0 "register_operand" "=r,r")
@@ -5243,7 +5318,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
;; Split the load of an address into a four-insn sequence on Unicos/Mk.
;; Always generate a REG_EQUAL note for the last instruction to facilitate
-;; optimisations. If the symbolic operand is a label_ref, generate REG_LABEL
+;; optimizations. If the symbolic operand is a label_ref, generate REG_LABEL
;; notes and update LABEL_NUSES because this is not done automatically.
;; Labels may be incorrectly deleted if we don't do this.
;;
@@ -5399,7 +5474,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
UNSPEC_SYMBOL))]
- "TARGET_EXPLICIT_RELOCS"
+ "TARGET_EXPLICIT_RELOCS && flag_inline_functions"
"#"
""
[(set (match_dup 0) (match_dup 1))]
@@ -5635,7 +5710,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(define_expand "aligned_loadqi"
[(set (match_operand:SI 3 "register_operand" "")
(match_operand:SI 1 "memory_operand" ""))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (subreg:DI (match_dup 3) 0)
(const_int 8)
(match_operand:DI 2 "const_int_operand" "")))]
@@ -5646,7 +5721,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(define_expand "aligned_loadhi"
[(set (match_operand:SI 3 "register_operand" "")
(match_operand:SI 1 "memory_operand" ""))
- (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (subreg:DI (match_dup 3) 0)
(const_int 16)
(match_operand:DI 2 "const_int_operand" "")))]
@@ -5662,7 +5737,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
;; operand 3 can overlap the input and output registers.
(define_expand "unaligned_loadqi"
- [(use (match_operand:QI 0 "register_operand" ""))
+ [(use (match_operand:DI 0 "register_operand" ""))
(use (match_operand:DI 1 "address_operand" ""))
(use (match_operand:DI 2 "register_operand" ""))
(use (match_operand:DI 3 "register_operand" ""))]
@@ -5683,7 +5758,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_int -8))))
(set (match_operand:DI 3 "register_operand" "")
(match_dup 1))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (match_dup 2)
(const_int 8)
(ashift:DI (match_dup 3) (const_int 3))))]
@@ -5696,7 +5771,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_int -8))))
(set (match_operand:DI 3 "register_operand" "")
(match_dup 1))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (match_dup 2)
(const_int 8)
(minus:DI
@@ -5706,7 +5781,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"")
(define_expand "unaligned_loadhi"
- [(use (match_operand:QI 0 "register_operand" ""))
+ [(use (match_operand:DI 0 "register_operand" ""))
(use (match_operand:DI 1 "address_operand" ""))
(use (match_operand:DI 2 "register_operand" ""))
(use (match_operand:DI 3 "register_operand" ""))]
@@ -5727,7 +5802,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_int -8))))
(set (match_operand:DI 3 "register_operand" "")
(match_dup 1))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (match_dup 2)
(const_int 16)
(ashift:DI (match_dup 3) (const_int 3))))]
@@ -5740,7 +5815,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(const_int -8))))
(set (match_operand:DI 3 "register_operand" "")
(plus:DI (match_dup 1) (const_int 1)))
- (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
+ (set (match_operand:DI 0 "register_operand" "")
(zero_extract:DI (match_dup 2)
(const_int 16)
(minus:DI
@@ -5935,9 +6010,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
{
rtx scratch, seq;
- if (GET_CODE (operands[1]) != MEM)
- abort ();
-
if (aligned_memory_operand (operands[1], QImode))
{
seq = gen_reload_inqi_help (operands[0], operands[1],
@@ -5956,8 +6028,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
addr = get_unaligned_address (operands[1], 0);
- seq = gen_unaligned_loadqi (operands[0], addr, scratch,
- gen_rtx_REG (DImode, REGNO (operands[0])));
+ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
+ seq = gen_unaligned_loadqi (operands[0], addr, scratch, operands[0]);
alpha_set_memflags (seq, operands[1]);
}
emit_insn (seq);
@@ -5972,9 +6044,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
{
rtx scratch, seq;
- if (GET_CODE (operands[1]) != MEM)
- abort ();
-
if (aligned_memory_operand (operands[1], HImode))
{
seq = gen_reload_inhi_help (operands[0], operands[1],
@@ -5993,8 +6062,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
addr = get_unaligned_address (operands[1], 0);
- seq = gen_unaligned_loadhi (operands[0], addr, scratch,
- gen_rtx_REG (DImode, REGNO (operands[0])));
+ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
+ seq = gen_unaligned_loadhi (operands[0], addr, scratch, operands[0]);
alpha_set_memflags (seq, operands[1]);
}
emit_insn (seq);
@@ -6007,9 +6076,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:TI 2 "register_operand" "=&r")])]
"! TARGET_BWX"
{
- if (GET_CODE (operands[0]) != MEM)
- abort ();
-
if (aligned_memory_operand (operands[0], QImode))
{
emit_insn (gen_reload_outqi_help
@@ -6042,9 +6108,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:TI 2 "register_operand" "=&r")])]
"! TARGET_BWX"
{
- if (GET_CODE (operands[0]) != MEM)
- abort ();
-
if (aligned_memory_operand (operands[0], HImode))
{
emit_insn (gen_reload_outhi_help
@@ -6075,71 +6138,47 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
;; always get a proper address for a stack slot during reload_foo
;; expansion, so we must delay our address manipulations until after.
-(define_insn "reload_inqi_help"
+(define_insn_and_split "reload_inqi_help"
[(set (match_operand:QI 0 "register_operand" "=r")
(match_operand:QI 1 "memory_operand" "m"))
(clobber (match_operand:SI 2 "register_operand" "=r"))]
"! TARGET_BWX && (reload_in_progress || reload_completed)"
- "#")
-
-(define_insn "reload_inhi_help"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (match_operand:HI 1 "memory_operand" "m"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))]
- "! TARGET_BWX && (reload_in_progress || reload_completed)"
- "#")
-
-(define_insn "reload_outqi_help"
- [(set (match_operand:QI 0 "memory_operand" "=m")
- (match_operand:QI 1 "register_operand" "r"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))
- (clobber (match_operand:SI 3 "register_operand" "=r"))]
- "! TARGET_BWX && (reload_in_progress || reload_completed)"
- "#")
-
-(define_insn "reload_outhi_help"
- [(set (match_operand:HI 0 "memory_operand" "=m")
- (match_operand:HI 1 "register_operand" "r"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))
- (clobber (match_operand:SI 3 "register_operand" "=r"))]
- "! TARGET_BWX && (reload_in_progress || reload_completed)"
- "#")
-
-(define_split
- [(set (match_operand:QI 0 "register_operand" "")
- (match_operand:QI 1 "memory_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))]
+ "#"
"! TARGET_BWX && reload_completed"
[(const_int 0)]
{
rtx aligned_mem, bitnum;
get_aligned_mem (operands[1], &aligned_mem, &bitnum);
-
+ operands[0] = gen_lowpart (DImode, operands[0]);
emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
operands[2]));
DONE;
})
-(define_split
- [(set (match_operand:HI 0 "register_operand" "")
- (match_operand:HI 1 "memory_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))]
+(define_insn_and_split "reload_inhi_help"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (match_operand:HI 1 "memory_operand" "m"))
+ (clobber (match_operand:SI 2 "register_operand" "=r"))]
+ "! TARGET_BWX && (reload_in_progress || reload_completed)"
+ "#"
"! TARGET_BWX && reload_completed"
[(const_int 0)]
{
rtx aligned_mem, bitnum;
get_aligned_mem (operands[1], &aligned_mem, &bitnum);
-
+ operands[0] = gen_lowpart (DImode, operands[0]);
emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
operands[2]));
DONE;
})
-(define_split
- [(set (match_operand:QI 0 "memory_operand" "")
- (match_operand:QI 1 "register_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+(define_insn_and_split "reload_outqi_help"
+ [(set (match_operand:QI 0 "memory_operand" "=m")
+ (match_operand:QI 1 "register_operand" "r"))
+ (clobber (match_operand:SI 2 "register_operand" "=r"))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))]
+ "! TARGET_BWX && (reload_in_progress || reload_completed)"
+ "#"
"! TARGET_BWX && reload_completed"
[(const_int 0)]
{
@@ -6150,11 +6189,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
DONE;
})
-(define_split
- [(set (match_operand:HI 0 "memory_operand" "")
- (match_operand:HI 1 "register_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))
- (clobber (match_operand:SI 3 "register_operand" ""))]
+(define_insn_and_split "reload_outhi_help"
+ [(set (match_operand:HI 0 "memory_operand" "=m")
+ (match_operand:HI 1 "register_operand" "r"))
+ (clobber (match_operand:SI 2 "register_operand" "=r"))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))]
+ "! TARGET_BWX && (reload_in_progress || reload_completed)"
+ "#"
"! TARGET_BWX && reload_completed"
[(const_int 0)]
{
@@ -6494,6 +6535,56 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
FAIL;
})
+(define_expand "movstrdi"
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
+ (use (match_operand:DI 2 "immediate_operand" ""))
+ (use (match_operand:DI 3 "immediate_operand" ""))
+ (use (match_dup 4))
+ (clobber (reg:DI 25))
+ (clobber (reg:DI 16))
+ (clobber (reg:DI 17))
+ (clobber (reg:DI 18))
+ (clobber (reg:DI 19))
+ (clobber (reg:DI 20))
+ (clobber (reg:DI 26))
+ (clobber (reg:DI 27))])]
+ "TARGET_ABI_OPEN_VMS"
+{
+ operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$MOVE");
+ alpha_need_linkage (XSTR (operands[4], 0), 0);
+})
+
+(define_insn "*movstrdi_1"
+ [(set (match_operand:BLK 0 "memory_operand" "=m,=m")
+ (match_operand:BLK 1 "memory_operand" "m,m"))
+ (use (match_operand:DI 2 "nonmemory_operand" "r,i"))
+ (use (match_operand:DI 3 "immediate_operand" ""))
+ (use (match_operand:DI 4 "call_operand" "i,i"))
+ (clobber (reg:DI 25))
+ (clobber (reg:DI 16))
+ (clobber (reg:DI 17))
+ (clobber (reg:DI 18))
+ (clobber (reg:DI 19))
+ (clobber (reg:DI 20))
+ (clobber (reg:DI 26))
+ (clobber (reg:DI 27))]
+ "TARGET_ABI_OPEN_VMS"
+{
+ operands [5] = alpha_use_linkage (operands [4], cfun->decl, 0, 1);
+ switch (which_alternative)
+ {
+ case 0:
+ return "lda $16,%0\;bis $31,%2,$17\;lda $18,%1\;ldq $26,%5\;lda $25,3($31)\;jsr $26,%4\;ldq $27,0($29)";
+ case 1:
+ return "lda $16,%0\;lda $17,%2($31)\;lda $18,%1\;ldq $26,%5\;lda $25,3($31)\;jsr $26,%4\;ldq $27,0($29)";
+ default:
+ abort();
+ }
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "28")])
+
(define_expand "clrstrqi"
[(parallel [(set (match_operand:BLK 0 "memory_operand" "")
(const_int 0))
@@ -6506,6 +6597,51 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
else
FAIL;
})
+
+(define_expand "clrstrdi"
+ [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
+ (const_int 0))
+ (use (match_operand:DI 1 "immediate_operand" ""))
+ (use (match_operand:DI 2 "immediate_operand" ""))
+ (use (match_dup 3))
+ (clobber (reg:DI 25))
+ (clobber (reg:DI 16))
+ (clobber (reg:DI 17))
+ (clobber (reg:DI 26))
+ (clobber (reg:DI 27))])]
+ "TARGET_ABI_OPEN_VMS"
+{
+ operands[3] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO");
+ alpha_need_linkage (XSTR (operands[3], 0), 0);
+})
+
+(define_insn "*clrstrdi_1"
+ [(set (match_operand:BLK 0 "memory_operand" "=m,=m")
+ (const_int 0))
+ (use (match_operand:DI 1 "nonmemory_operand" "r,i"))
+ (use (match_operand:DI 2 "immediate_operand" ""))
+ (use (match_operand:DI 3 "call_operand" "i,i"))
+ (clobber (reg:DI 25))
+ (clobber (reg:DI 16))
+ (clobber (reg:DI 17))
+ (clobber (reg:DI 26))
+ (clobber (reg:DI 27))]
+ "TARGET_ABI_OPEN_VMS"
+{
+ operands [4] = alpha_use_linkage (operands [3], cfun->decl, 0, 1);
+ switch (which_alternative)
+ {
+ case 0:
+ return "lda $16,%0\;bis $31,%1,$17\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
+ case 1:
+ return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
+ default:
+ abort();
+ }
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "24")])
+
;; Subroutine of stack space allocation. Perform a stack probe.
(define_expand "probe_stack"
@@ -6605,7 +6741,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
""
{
operands[2] = gen_label_rtx ();
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
+ (*targetm.asm_out.internal_label) (asm_out_file, "L",
CODE_LABEL_NUMBER (operands[2]));
return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
@@ -6648,7 +6784,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand 2 "const_int_operand" "")]
UNSPECV_LDGP1))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "ldah %0,0(%1)\t\t!gpdisp!%2")
+ "ldah %0,0(%1)\t\t!gpdisp!%2"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6656,7 +6793,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand 2 "const_int_operand" "")]
UNSPEC_LDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "lda %0,0(%1)\t\t!gpdisp!%2")
+ "lda %0,0(%1)\t\t!gpdisp!%2"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6664,7 +6802,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand 2 "const_int_operand" "")]
UNSPECV_PLDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
- "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:")
+ "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_1"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6672,7 +6811,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand 2 "const_int_operand" "")]
UNSPECV_LDGP1))]
""
- "ldgp %0,0(%1)\n$%~..ng:")
+ "ldgp %0,0(%1)\n$%~..ng:"
+ [(set_attr "cannot_copy" "true")])
(define_insn "*prologue_ldgp_2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -6722,17 +6862,6 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
DONE;
})
-;; In creating a large stack frame, NT _must_ use ldah+lda to load
-;; the frame size into a register. We use this pattern to ensure
-;; we get lda instead of addq.
-(define_insn "nt_lda"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(match_dup 0)
- (match_operand:DI 1 "const_int_operand" "n")]
- UNSPEC_NT_LDA))]
- ""
- "lda %0,%1(%0)")
-
(define_expand "builtin_longjmp"
[(use (match_operand:DI 0 "register_operand" "r"))]
"TARGET_ABI_OSF"
@@ -6786,7 +6915,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
[(const_int 0)]
"
{
- emit_note (NULL, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
DONE;
}")
@@ -7046,7 +7175,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extxl_be;
else
@@ -7061,7 +7190,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extxl_be;
else
@@ -7076,7 +7205,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extxl_be;
else
@@ -7091,7 +7220,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extxl_be;
else
@@ -7106,7 +7235,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extwh_be;
else
@@ -7121,7 +7250,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extlh_be;
else
@@ -7136,7 +7265,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_extqh_be;
else
@@ -7151,7 +7280,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_insbl_be;
else
@@ -7167,7 +7296,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_inswl_be;
else
@@ -7183,7 +7312,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_insll_be;
else
@@ -7200,7 +7329,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx);
if (WORDS_BIG_ENDIAN)
gen = gen_insql_be;
else
@@ -7245,7 +7374,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
rtx mask;
if (WORDS_BIG_ENDIAN)
gen = gen_mskxl_be;
@@ -7262,7 +7391,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
rtx mask;
if (WORDS_BIG_ENDIAN)
gen = gen_mskxl_be;
@@ -7279,7 +7408,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
rtx mask;
if (WORDS_BIG_ENDIAN)
gen = gen_mskxl_be;
@@ -7296,7 +7425,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(match_operand:DI 2 "reg_or_8bit_operand" "")]
""
{
- rtx (*gen) PARAMS ((rtx, rtx, rtx, rtx));
+ rtx (*gen) (rtx, rtx, rtx, rtx);
rtx mask;
if (WORDS_BIG_ENDIAN)
gen = gen_mskxl_be;
@@ -7719,7 +7848,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
- bsr $26,$%1..ng
+ bsr $26,%1\t\t!samegp
ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),0\t\t!lituse_jsr!%#\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
[(set_attr "type" "jsr")
(set_attr "length" "12,*,16")])
@@ -7733,8 +7862,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
- && ! current_file_function_operand (operands[1], Pmode)
- && peep2_regno_dead_p (1, 29)"
+ && ! samegp_function_operand (operands[1], Pmode)
+ && (peep2_regno_dead_p (1, 29)
+ || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
[(parallel [(set (match_dup 0)
(call (mem:DI (match_dup 3))
(match_dup 2)))
@@ -7765,8 +7895,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
- && ! current_file_function_operand (operands[1], Pmode)
- && ! peep2_regno_dead_p (1, 29)"
+ && ! samegp_function_operand (operands[1], Pmode)
+ && ! (peep2_regno_dead_p (1, 29)
+ || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
[(parallel [(set (match_dup 0)
(call (mem:DI (match_dup 3))
(match_dup 2)))
@@ -7808,7 +7939,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (match_operand 4 "" ""))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%1),%3%J4"
- [(set_attr "type" "jsr")])
+ [(set_attr "type" "jsr")
+ (set_attr "cannot_copy" "true")])
(define_insn "*call_value_osf_1_noreturn"
[(set (match_operand 0 "" "")
@@ -7819,9 +7951,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
&& find_reg_note (insn, REG_NORETURN, NULL_RTX)"
"@
- jsr $26,($27),0
- bsr $26,$%1..ng
- jsr $26,%1"
+ jsr $26,($27),0%+
+ bsr $26,$%1..ng%+
+ jsr $26,%1%+"
[(set_attr "type" "jsr")
(set_attr "length" "*,*,8")])
@@ -7910,7 +8042,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
- br $31,$%1..ng
+ br $31,%1\t\t!samegp
ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#"
[(set_attr "type" "jsr")
(set_attr "length" "*,8")])
@@ -7952,20 +8084,19 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(use (reg:DI 26))
(clobber (reg:DI 27))]
"TARGET_ABI_OPEN_VMS"
- "*
{
switch (which_alternative)
{
case 0:
- return \"mov %3,$27\;jsr $26,0\;ldq $27,0($29)\";
+ return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)";
case 1:
operands [3] = alpha_use_linkage (operands [1], cfun->decl, 1, 0);
operands [4] = alpha_use_linkage (operands [1], cfun->decl, 0, 0);
- return \"ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)\";
+ return "ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)";
default:
abort();
}
-}"
+}
[(set_attr "type" "jsr")
(set_attr "length" "12,16")])
diff --git a/contrib/gcc/config/alpha/elf.h b/contrib/gcc/config/alpha/elf.h
index dbe926386641..34bba3ecb179 100644
--- a/contrib/gcc/config/alpha/elf.h
+++ b/contrib/gcc/config/alpha/elf.h
@@ -1,24 +1,24 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha w/ELF.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Richard Henderson (rth@tamu.edu).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+Boston, MA 02111-1307, USA. */
#undef OBJECT_FORMAT_COFF
#undef EXTENDED_COFF
@@ -35,8 +35,13 @@ Boston, MA 02111-1307, USA. */
#undef ASM_FINAL_SPEC
-#undef CPP_SUBTARGET_SPEC
-#define CPP_SUBTARGET_SPEC "-D__ELF__"
+/* alpha/ doesn't use elfos.h for some reason. */
+#define TARGET_OBJFMT_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__ELF__"); \
+ } \
+ while (0)
#undef CC1_SPEC
#define CC1_SPEC "%{G*}"
@@ -44,27 +49,6 @@ Boston, MA 02111-1307, USA. */
#undef ASM_SPEC
#define ASM_SPEC "%{G*} %{relax:-relax} %{!gstabs*:-no-mdebug}%{gstabs*:-mdebug}"
-/* Output at beginning of assembler file. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
-do { \
- if (write_symbols == DBX_DEBUG) \
- { \
- alpha_write_verstamp (FILE); \
- output_file_directive (FILE, main_input_filename); \
- } \
- fprintf (FILE, "\t.set noat\n"); \
- fprintf (FILE, "\t.set noreorder\n"); \
- if (TARGET_EXPLICIT_RELOCS) \
- fprintf (FILE, "\t.set nomacro\n"); \
- if (TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX) \
- { \
- fprintf (FILE, "\t.arch %s\n", \
- (TARGET_CPU_EV6 ? "ev6" \
- : TARGET_MAX ? "pca56" : "ev56")); \
- } \
-} while (0)
-
#undef IDENT_ASM_OP
#define IDENT_ASM_OP "\t.ident\t"
@@ -81,7 +65,7 @@ do { \
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(FILE, SIZE) \
- fprintf (FILE, "%s%u\n", SKIP_ASM_OP, (SIZE))
+ fprintf (FILE, "%s"HOST_WIDE_INT_PRINT_UNSIGNED"\n", SKIP_ASM_OP, (SIZE))
/* Output the label which precedes a jumptable. Note that for all svr4
systems where we actually generate jumptables (which is to say every
@@ -103,7 +87,7 @@ do { \
#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE) \
do { \
ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \
+ (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); \
} while (0)
/* The standard SVR4 assembler seems to require that certain builtin
@@ -127,7 +111,7 @@ do { \
do { \
fprintf ((FILE), "%s", COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+ fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
} while (0)
/* This says how to output assembler code to declare an
@@ -156,7 +140,6 @@ do { \
#undef ASM_OUTPUT_ALIGNED_BSS
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
do { \
- (*targetm.asm_out.globalize_label) (FILE, NAME); \
ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
} while (0)
@@ -166,7 +149,7 @@ do { \
not defined, the default value is `BIGGEST_ALIGNMENT'.
This value is really 2^63. Since gcc figures the alignment in bits,
- we could only potentially get to 2^60 on suitible hosts. Due to other
+ we could only potentially get to 2^60 on suitable hosts. Due to other
considerations in varasm, we must restrict this to what fits in an int. */
#undef MAX_OFILE_ALIGNMENT
@@ -227,12 +210,12 @@ do { \
SECTION_FUNCTION_TEMPLATE(sbss_section, in_sbss, SBSS_SECTION_ASM_OP) \
SECTION_FUNCTION_TEMPLATE(sdata_section, in_sdata, SDATA_SECTION_ASM_OP)
-extern void sbss_section PARAMS ((void));
-extern void sdata_section PARAMS ((void));
+extern void sbss_section (void);
+extern void sdata_section (void);
#undef SECTION_FUNCTION_TEMPLATE
#define SECTION_FUNCTION_TEMPLATE(FN, ENUM, OP) \
-void FN () \
+void FN (void) \
{ \
if (in_section != ENUM) \
{ \
@@ -406,14 +389,18 @@ void FN () \
/* Provide a STARTFILE_SPEC appropriate for ELF. Here we add the
(even more) magical crtbegin.o file which provides part of the
support for getting C++ file-scope static object constructed
- before entering `main'. */
+ before entering `main'. */
#undef STARTFILE_SPEC
+#ifdef HAVE_LD_PIE
+#define STARTFILE_SPEC \
+ "%{!shared: %{pg|p:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+#else
#define STARTFILE_SPEC \
- "%{!shared: \
- %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
- crti.o%s %{static:crtbeginT.o%s}\
- %{!static:%{shared:crtbeginS.o%s}%{!shared:crtbegin.o%s}}"
+ "%{!shared: %{pg|p:gcrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+#endif
/* Provide a ENDFILE_SPEC appropriate for ELF. Here we tack on the
magical crtend.o file which provides part of the support for
@@ -423,7 +410,7 @@ void FN () \
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
- %{shared:crtendS.o%s}%{!shared:crtend.o%s} crtn.o%s"
+ %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
/* We support #pragma. */
#define HANDLE_SYSV_PRAGMA 1
diff --git a/contrib/gcc/config/alpha/ev4.md b/contrib/gcc/config/alpha/ev4.md
index 41e1efd4cd78..cee3ae608ee7 100644
--- a/contrib/gcc/config/alpha/ev4.md
+++ b/contrib/gcc/config/alpha/ev4.md
@@ -1,20 +1,20 @@
;; Scheduling description for Alpha EV4.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/alpha/ev5.md b/contrib/gcc/config/alpha/ev5.md
index 832cf6be8f36..20757e15159d 100644
--- a/contrib/gcc/config/alpha/ev5.md
+++ b/contrib/gcc/config/alpha/ev5.md
@@ -1,20 +1,20 @@
;; Scheduling description for Alpha EV5.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/alpha/ev6.md b/contrib/gcc/config/alpha/ev6.md
index 12204b69d6a7..23a09b053a37 100644
--- a/contrib/gcc/config/alpha/ev6.md
+++ b/contrib/gcc/config/alpha/ev6.md
@@ -1,20 +1,20 @@
;; Scheduling description for Alpha EV6.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/alpha/freebsd.h b/contrib/gcc/config/alpha/freebsd.h
index f809c62012e3..0b293610f4ce 100644
--- a/contrib/gcc/config/alpha/freebsd.h
+++ b/contrib/gcc/config/alpha/freebsd.h
@@ -1,31 +1,35 @@
/* Definitions for DEC Alpha/AXP running FreeBSD using the ELF format
- Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
+
/* Provide a FBSD_TARGET_CPU_CPP_BUILTINS and CPP_SPEC appropriate for
FreeBSD/alpha. Besides the dealing with
the GCC option `-posix', and PIC issues as on all FreeBSD platforms, we must
deal with the Alpha's FP issues. */
-#undef FBSD_TARGET_CPU_CPP_BUILTINS
+#undef FBSD_TARGET_CPU_CPP_BUILTINS
#define FBSD_TARGET_CPU_CPP_BUILTINS() \
do \
{ \
@@ -41,16 +45,16 @@ Boston, MA 02111-1307, USA. */
#define CPP_SPEC "%(cpp_subtarget) %{posix:-D_POSIX_SOURCE}"
#define LINK_SPEC "%{G*} %{relax:-relax} \
- %{p:%e`-p' not supported; use `-pg' and gprof(1)} \
+ %{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \
%{Wl,*:%*} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
%{shared:-Bshareable %{h*} %{soname*}} \
- %{symbolic:-Bsymbolic} \
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
- %{static:-Bstatic}}"
+ %{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }} \
+ %{static:-Bstatic}} \
+ %{symbolic:-Bsymbolic}"
/************************[ Target stuff ]***********************************/
diff --git a/contrib/gcc/config/alpha/gnu.h b/contrib/gcc/config/alpha/gnu.h
index 9b25daff6a54..40348c60abbb 100644
--- a/contrib/gcc/config/alpha/gnu.h
+++ b/contrib/gcc/config/alpha/gnu.h
@@ -6,12 +6,8 @@
#undef TARGET_OS_CPP_BUILTINS /* config.gcc includes alpha/linux.h. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
- builtin_define ("__GNU__"); \
- builtin_define ("__ELF__"); \
- builtin_define ("__gnu_hurd__"); \
+ HURD_TARGET_OS_CPP_BUILTINS(); \
builtin_define ("_LONGLONG"); \
- builtin_define_std ("unix"); \
- builtin_assert ("system=gnu"); \
} while (0)
#undef ELF_DYNAMIC_LINKER
diff --git a/contrib/gcc/config/alpha/lib1funcs.asm b/contrib/gcc/config/alpha/lib1funcs.asm
index 6bea231bc067..a2abb1f8ae49 100644
--- a/contrib/gcc/config/alpha/lib1funcs.asm
+++ b/contrib/gcc/config/alpha/lib1funcs.asm
@@ -307,7 +307,7 @@ $46:
conventions. */
#if TYPE == UNSIGNED && SIZE == 32
/* This could be avoided by adding some CPP hair to the divide loop.
- It is probably not worth the added complexity. */
+ It is probably not worth the added complexity. */
addl RETREG,0,RETREG
#endif
diff --git a/contrib/gcc/config/alpha/linux-elf.h b/contrib/gcc/config/alpha/linux-elf.h
index 49f518137e16..025b9a20b8ad 100644
--- a/contrib/gcc/config/alpha/linux-elf.h
+++ b/contrib/gcc/config/alpha/linux-elf.h
@@ -3,20 +3,20 @@
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Contributed by Richard Henderson.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -27,11 +27,7 @@ Boston, MA 02111-1307, USA. */
#define SUBTARGET_EXTRA_SPECS \
{ "elf_dynamic_linker", ELF_DYNAMIC_LINKER },
-#ifdef USE_GNULIBC_1
-#define ELF_DYNAMIC_LINKER "/lib/ld.so.1"
-#else
#define ELF_DYNAMIC_LINKER "/lib/ld-linux.so.2"
-#endif
#define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \
%{O*:-O3} %{!O*:-O1} \
@@ -42,8 +38,8 @@ Boston, MA 02111-1307, USA. */
%{!dynamic-linker:-dynamic-linker %(elf_dynamic_linker)}} \
%{static:-static}}"
-#ifndef USE_GNULIBC_1
#undef LIB_SPEC
#define LIB_SPEC \
-"%{pthread:-lpthread }%{shared:-lc}%{!shared:%{profile:-lc_p}%{!profile:-lc}} "
-#endif
+"%{pthread:-lpthread} %{shared:-lc}%{!shared:%{profile:-lc_p}%{!profile:-lc}} "
+
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
diff --git a/contrib/gcc/config/alpha/linux.h b/contrib/gcc/config/alpha/linux.h
index 3a2940cc3078..a4bc3d3e4a4b 100644
--- a/contrib/gcc/config/alpha/linux.h
+++ b/contrib/gcc/config/alpha/linux.h
@@ -1,22 +1,22 @@
/* Definitions of target machine for GNU compiler,
for Alpha Linux-based GNU systems.
- Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 2002, 2003 Free Software Foundation, Inc.
Contributed by Richard Henderson.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -30,8 +30,10 @@ Boston, MA 02111-1307, USA. */
builtin_define_std ("linux"); \
builtin_define_std ("unix"); \
builtin_assert ("system=linux"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=posix"); \
/* The GNU C++ standard library requires this. */ \
- if (c_language == clk_cplusplus) \
+ if (c_dialect_cxx ()) \
builtin_define ("_GNU_SOURCE"); \
} while (0)
@@ -59,6 +61,10 @@ Boston, MA 02111-1307, USA. */
/* Define this so that all GNU/Linux targets handle the same pragmas. */
#define HANDLE_PRAGMA_PACK_PUSH_POP
+/* Determine whether the the entire c99 runtime is present in the
+ runtime library. */
+#define TARGET_C99_FUNCTIONS 1
+
#define TARGET_HAS_F_SETLKW
#define LINK_GCC_C_SEQUENCE_SPEC \
diff --git a/contrib/gcc/config/alpha/netbsd.h b/contrib/gcc/config/alpha/netbsd.h
index e1da9cfe188a..d4f833a0860e 100644
--- a/contrib/gcc/config/alpha/netbsd.h
+++ b/contrib/gcc/config/alpha/netbsd.h
@@ -1,21 +1,21 @@
/* Definitions of target machine for GNU compiler,
for Alpha NetBSD systems.
- Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,7 +25,6 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
NETBSD_OS_CPP_BUILTINS_ELF(); \
- NETBSD_OS_CPP_BUILTINS_LP64(); \
} while (0)
@@ -77,7 +76,7 @@ Boston, MA 02111-1307, USA. */
/* Attempt to enable execute permissions on the stack. */
-#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
+#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
#undef TARGET_VERSION
diff --git a/contrib/gcc/config/alpha/openbsd.h b/contrib/gcc/config/alpha/openbsd.h
index b82b66df3c8c..b9df2e4255c5 100644
--- a/contrib/gcc/config/alpha/openbsd.h
+++ b/contrib/gcc/config/alpha/openbsd.h
@@ -1,36 +1,26 @@
/* Configuration file for an alpha OpenBSD target.
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* We settle for little endian for now. */
#define TARGET_ENDIAN_DEFAULT 0
-#define OBSD_NO_DYNAMIC_LIBRARIES
-#define OBSD_HAS_DECLARE_FUNCTION_NAME
-#define OBSD_HAS_DECLARE_FUNCTION_SIZE
-#define OBSD_HAS_DECLARE_OBJECT
-
-/* alpha ecoff supports only weak aliases, see below. */
-#define ASM_WEAKEN_LABEL(FILE,NAME) ASM_OUTPUT_WEAK_ALIAS (FILE,NAME,0)
-
-#include <openbsd.h>
-
/* Controlling the compilation driver. */
/* alpha needs __start. */
@@ -82,38 +72,18 @@ Boston, MA 02111-1307, USA. */
/* Assembler format: exception region output. */
/* All configurations that don't use elf must be explicit about not using
- dwarf unwind information. egcs doesn't try too hard to check internal
- configuration files... */
+ dwarf unwind information. */
#ifdef INCOMING_RETURN_ADDR_RTX
#undef DWARF2_UNWIND_INFO
#define DWARF2_UNWIND_INFO 0
#endif
-/* Assembler format: file framework. */
-
-/* Taken from alpha/osf.h. This used to be common to all alpha
- configurations, but elf has departed from it.
- Check alpha/alpha.h, alpha/osf.h for it when egcs is upgraded. */
-#ifndef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
-{ \
- alpha_write_verstamp (FILE); \
- fprintf (FILE, "\t.set noreorder\n"); \
- fprintf (FILE, "\t.set volatile\n"); \
- fprintf (FILE, "\t.set noat\n"); \
- if (TARGET_SUPPORT_ARCH) \
- fprintf (FILE, "\t.arch %s\n", \
- TARGET_CPU_EV6 ? "ev6" \
- : (TARGET_CPU_EV5 \
- ? (TARGET_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5") \
- : "ev4")); \
- \
- ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
-}
-#endif
-
/* Assembler format: label output. */
+/* alpha ecoff supports only weak aliases. */
+#undef ASM_WEAKEN_LABEL
+#define ASM_WEAKEN_LABEL(FILE,NAME) ASM_OUTPUT_WEAK_ALIAS (FILE,NAME,0)
+
#define ASM_OUTPUT_WEAK_ALIAS(FILE,NAME,VALUE) \
do { \
fputs ("\t.weakext\t", FILE); \
diff --git a/contrib/gcc/config/alpha/osf.h b/contrib/gcc/config/alpha/osf.h
index 2be2a424d359..1ae6db3caf40 100644
--- a/contrib/gcc/config/alpha/osf.h
+++ b/contrib/gcc/config/alpha/osf.h
@@ -1,22 +1,22 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha on OSF/1.
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003,
+ 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -49,6 +49,13 @@ Boston, MA 02111-1307, USA. */
to be defined for <math.h>. */ \
if (LONG_DOUBLE_TYPE_SIZE == 128) \
builtin_define ("__X_FLOAT"); \
+ \
+ /* Tru64 UNIX V4/V5 provide several ISO C94 \
+ features protected by the corresponding \
+ __STDC_VERSION__ macro. libstdc++ v3 \
+ needs them as well. */ \
+ if (c_dialect_cxx ()) \
+ builtin_define ("__STDC_VERSION__=199409L"); \
} while (0)
/* Accept DEC C flags for multithreaded programs. We use _PTHREAD_USE_D4
@@ -84,22 +91,6 @@ Boston, MA 02111-1307, USA. */
#define MD_STARTFILE_PREFIX "/usr/lib/cmplrs/cc/"
-#define ASM_FILE_START(FILE) \
-{ \
- alpha_write_verstamp (FILE); \
- fprintf (FILE, "\t.set noreorder\n"); \
- fprintf (FILE, "\t.set volatile\n"); \
- fprintf (FILE, "\t.set noat\n"); \
- if (TARGET_SUPPORT_ARCH) \
- fprintf (FILE, "\t.arch %s\n", \
- TARGET_CPU_EV6 ? "ev6" \
- : (TARGET_CPU_EV5 \
- ? (TARGET_MAX ? "pca56" : TARGET_BWX ? "ev56" : "ev5") \
- : "ev4")); \
- \
- ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
-}
-
/* Tru64 UNIX V5.1 requires a special as flag. Empty by default. */
#define ASM_OLDAS_SPEC ""
@@ -154,14 +145,11 @@ Boston, MA 02111-1307, USA. */
/* Attempt to turn on access permissions for the stack. */
-#define TRANSFER_FROM_TRAMPOLINE \
-extern void __enable_execute_stack PARAMS ((void *)); \
- \
+#define ENABLE_EXECUTE_STACK \
void \
-__enable_execute_stack (addr) \
- void *addr; \
+__enable_execute_stack (void *addr) \
{ \
- extern int mprotect PARAMS ((const void *, size_t, int)); \
+ extern int mprotect (const void *, size_t, int); \
long size = getpagesize (); \
long mask = ~(size-1); \
char *page = (char *) (((long) addr) & mask); \
@@ -181,6 +169,10 @@ __enable_execute_stack (addr) \
#define LD_INIT_SWITCH "-init"
#define LD_FINI_SWITCH "-fini"
+/* The linker needs a space after "-o". This allows -oldstyle_liblookup to
+ be passed to ld. */
+#define SWITCHES_NEED_SPACES "o"
+
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations.
diff --git a/contrib/gcc/config/alpha/osf5.h b/contrib/gcc/config/alpha/osf5.h
index e483124691e7..e96ae7e22125 100644
--- a/contrib/gcc/config/alpha/osf5.h
+++ b/contrib/gcc/config/alpha/osf5.h
@@ -1,29 +1,26 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha on Tru64 5.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Tru64 5.1 uses IEEE QUAD format. */
-/* ??? However, since there is no support for VAX H_floating, we must
- drop back to a 64-bit long double to avoid a crash looking for the
- format associated with TFmode. */
-#undef LONG_DOUBLE_TYPE_SIZE
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_FLOAT_VAX ? 64 : 128)
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT MASK_FP | MASK_FPREGS | MASK_LONG_DOUBLE_128
/* In Tru64 UNIX V5.1, Compaq introduced a new assembler
(/usr/lib/cmplrs/cc/adu) which currently (versions between 3.04.29 and
@@ -49,3 +46,8 @@
linked. */
#undef TARGET_LD_BUGGY_LDGP
#define TARGET_LD_BUGGY_LDGP 1
+
+/* Tru64 v5.1 has the float and long double forms of math functions. */
+#undef TARGET_C99_FUNCTIONS
+#define TARGET_C99_FUNCTIONS 1
+
diff --git a/contrib/gcc/config/alpha/t-osf-pthread b/contrib/gcc/config/alpha/t-osf-pthread
new file mode 100644
index 000000000000..968e65cce9ef
--- /dev/null
+++ b/contrib/gcc/config/alpha/t-osf-pthread
@@ -0,0 +1,5 @@
+# Provide dummy POSIX threads functions
+LIB2FUNCS_EXTRA += $(srcdir)/gthr-posix.c
+
+# Compile libgcc2 with POSIX threads supports
+TARGET_LIBGCC2_CFLAGS=-pthread
diff --git a/contrib/gcc/config/alpha/t-osf4 b/contrib/gcc/config/alpha/t-osf4
index 0525d617662f..fe747a3d521d 100644
--- a/contrib/gcc/config/alpha/t-osf4
+++ b/contrib/gcc/config/alpha/t-osf4
@@ -10,7 +10,11 @@ SHLIB_NAME = @shlib_base_name@.so
SHLIB_SONAME = @shlib_base_name@.so.1
SHLIB_OBJS = @shlib_objs@
+# Hide all POSIX threads related symbols provided by gthr-posix.c. This
+# only has an effect if t-osf-pthread is in use.
SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
+ -Wl,-hidden_symbol,pthread\* -Wl,-hidden_symbol,__pthread\* \
+ -Wl,-hidden_symbol,sched_get_\* -Wl,-hidden_symbol,sched_yield \
-Wl,-msym -Wl,-set_version,gcc.1 -Wl,-soname,$(SHLIB_SONAME) \
-o $(SHLIB_NAME) @multilib_flags@ $(SHLIB_OBJS) -lc && \
rm -f $(SHLIB_SONAME) && \
diff --git a/contrib/gcc/config/alpha/unicosmk.h b/contrib/gcc/config/alpha/unicosmk.h
index 8f7b53db0718..9d966d6e27c6 100644
--- a/contrib/gcc/config/alpha/unicosmk.h
+++ b/contrib/gcc/config/alpha/unicosmk.h
@@ -4,20 +4,20 @@
Free Software Foundation, Inc.
Contributed by Roman Lechtchinsky (rl@cs.tu-berlin.de)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -102,8 +102,6 @@ Boston, MA 02111-1307, USA. */
other its replacement, at the start of a routine. This is somewhat
complicated on the T3E which is why we use a function. */
-extern int unicosmk_initial_elimination_offset PARAMS ((int, int));
-
#undef INITIAL_ELIMINATION_OFFSET
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
do { \
@@ -178,7 +176,7 @@ typedef struct {
function whose data type is FNTYPE. For a library call, FNTYPE is 0. */
#undef INIT_CUMULATIVE_ARGS
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
do { (CUM).num_args = 0; \
(CUM).num_arg_words = 0; \
(CUM).num_reg_words = 0; \
@@ -220,41 +218,11 @@ do { \
++(CUM).num_args; \
} while(0)
-/* We want the default definition for this.
- ??? In fact, we should delete the definition from alpha.h as it
- corresponds to the default definition for little-endian machines. */
-
-#undef FUNCTION_ARG_PADDING
-
/* An argument is passed either entirely in registers or entirely on stack. */
#undef FUNCTION_ARG_PARTIAL_NREGS
/* #define FUNCTION_ARG_PARTIAL_NREGS(CUM,MODE,TYPE,NAMED) 0 */
-/* Perform any needed actions needed for a function that is receiving a
- variable number of arguments.
-
- On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
- arguments on the stack. Unfortunately, it doesn't always store the first
- one (i.e. the one that arrives in $16 or $f16). This is not a problem
- with stdargs as we always have at least one named argument there. */
-
-#undef SETUP_INCOMING_VARARGS
-#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
-{ if ((CUM).num_reg_words < 6) \
- { \
- if (! (NO_RTL)) \
- { \
- int start = (CUM).num_reg_words + 1; \
- \
- emit_insn (gen_umk_mismatch_args (GEN_INT (start))); \
- emit_insn (gen_arg_home_umk ()); \
- } \
- \
- PRETEND_SIZE = 0; \
- } \
-}
-
/* This ensures that $15 increments/decrements in leaf functions won't get
eliminated. */
@@ -319,43 +287,33 @@ do { fprintf (FILE, "\tbr $1,0\n"); \
COMMON_SECTION \
SSIB_SECTION
-extern void common_section PARAMS ((void));
+extern void common_section (void);
#define COMMON_SECTION \
void \
-common_section () \
+common_section (void) \
{ \
in_section = in_common; \
}
-extern void ssib_section PARAMS ((void));
+extern void ssib_section (void);
#define SSIB_SECTION \
void \
-ssib_section () \
+ssib_section (void) \
{ \
in_section = in_ssib; \
}
-/* This outputs text to go at the start of an assembler file. */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) unicosmk_asm_file_start (FILE)
-
-/* This outputs text to go at the end of an assembler file. */
-
-#undef ASM_FILE_END
-#define ASM_FILE_END(FILE) unicosmk_asm_file_end (FILE)
-
-/* We take care of that in ASM_FILE_START. */
+/* We take care of this in unicosmk_file_start. */
#undef ASM_OUTPUT_SOURCE_FILENAME
/* This is how to output a label for a jump table. Arguments are the same as
- for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
+ for (*targetm.asm_out.internal_label), except the insn for the jump table is
passed. */
#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM)
+ (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM)
/* CAM has some restrictions with respect to string literals. It won't
accept lines with more that 256 characters which means that we have
@@ -453,7 +411,8 @@ ssib_section () \
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(STREAM,SIZE) \
- fprintf ((STREAM), "\t.byte\t0:%d\n", (SIZE));
+ fprintf ((STREAM), "\t.byte\t0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
+ (SIZE));
/* This says how to output an assembler line to define a global common
symbol. We need the alignment information because it has to be supplied
@@ -470,7 +429,7 @@ ssib_section () \
do { data_section (); \
fprintf (FILE, "\t.align\t%d\n", floor_log2 ((ALIGN) / BITS_PER_UNIT));\
ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- fprintf (FILE, "\t.byte 0:%d\n", SIZE); \
+ fprintf (FILE, "\t.byte 0:"HOST_WIDE_INT_PRINT_UNSIGNED"\n",(SIZE));\
} while (0)
/* CAM does not allow us to declare a symbol as external first and then
@@ -521,28 +480,9 @@ ssib_section () \
#undef SDB_DEBUGGING_INFO
#undef MIPS_DEBUGGING_INFO
#undef DBX_DEBUGGING_INFO
-#undef DWARF_DEBUGGING_INFO
#undef DWARF2_DEBUGGING_INFO
#undef DWARF2_UNWIND_INFO
#undef INCOMING_RETURN_ADDR_RTX
-
-
-/* We use the functions provided by the system library for integer
- division. */
-
-#undef UDIVDI3_LIBCALL
-#undef DIVDI3_LIBCALL
-#define UDIVDI3_LIBCALL "$uldiv"
-#define DIVDI3_LIBCALL "$sldiv"
-
-/* This is necessary to prevent gcc from generating calls to __divsi3. */
-
-#define INIT_TARGET_OPTABS \
- do { \
- sdiv_optab->handlers[(int) SImode].libfunc = NULL_RTX; \
- udiv_optab->handlers[(int) SImode].libfunc = NULL_RTX; \
- } while (0)
-
#undef ASM_OUTPUT_SOURCE_LINE
/* We don't need a start file. */
@@ -555,7 +495,6 @@ ssib_section () \
#undef LIB_SPEC
#define LIB_SPEC "-L/opt/ctl/craylibs/craylibs -lu -lm -lc -lsma"
-#undef BUILD_VA_LIST_TYPE
#undef EXPAND_BUILTIN_VA_START
#undef EXPAND_BUILTIN_VA_ARG
diff --git a/contrib/gcc/config/alpha/vms-cc.c b/contrib/gcc/config/alpha/vms-cc.c
index 26c3ae3b1ffc..672a30fe4683 100644
--- a/contrib/gcc/config/alpha/vms-cc.c
+++ b/contrib/gcc/config/alpha/vms-cc.c
@@ -1,21 +1,21 @@
/* VMS DEC C wrapper.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,6 +25,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#undef PATH_SEPARATOR
#undef PATH_SEPARATOR_STR
@@ -32,50 +34,47 @@ Boston, MA 02111-1307, USA. */
#define PATH_SEPARATOR_STR ","
/* These can be set by command line arguments */
-int verbose = 0;
-int save_temps = 0;
+static int verbose = 0;
+static int save_temps = 0;
-int comp_arg_max = -1;
-const char **comp_args = 0;
-int comp_arg_index = -1;
-char *objfilename = 0;
+static int comp_arg_max = -1;
+static const char **comp_args = 0;
+static int comp_arg_index = -1;
+static char *objfilename = 0;
-char *system_search_dirs = (char *) "";
-char *search_dirs;
+static char *system_search_dirs = (char *) "";
+static char *search_dirs;
-char *default_defines = (char *) "";
-char *defines;
+static char *default_defines = (char *) "";
+static char *defines;
/* Translate a Unix syntax directory specification into VMS syntax.
- If indicators of VMS syntax found, return input string. */
-static char *to_host_dir_spec PARAMS ((char *));
+ If indicators of VMS syntax found, return input string. */
+static char *to_host_dir_spec (char *);
/* Translate a Unix syntax file specification into VMS syntax.
- If indicators of VMS syntax found, return input string. */
-static char *to_host_file_spec PARAMS ((char *));
+ If indicators of VMS syntax found, return input string. */
+static char *to_host_file_spec (char *);
-/* Add a translated arg to the list to be passed to DEC CC */
-static void addarg PARAMS ((const char *));
+/* Add a translated arg to the list to be passed to DEC CC. */
+static void addarg (const char *);
/* Preprocess the number of args in P_ARGC and contained in ARGV.
- Look for special flags, etc. that must be handled first. */
-static void preprocess_args PARAMS ((int *, char **));
+ Look for special flags, etc. that must be handled first. */
+static void preprocess_args (int *, char **);
/* Process the number of args in P_ARGC and contained in ARGV. Look
- for special flags, etc. that must be handled for the VMS compiler. */
-static void process_args PARAMS ((int *, char **));
+ for special flags, etc. that must be handled for the VMS compiler. */
+static void process_args (int *, char **);
/* Action routine called by decc$to_vms */
-static int translate_unix PARAMS ((char *, int));
-
-int main PARAMS ((int, char **));
+static int translate_unix (char *, int);
/* Add the argument contained in STR to the list of arguments to pass to the
compiler. */
static void
-addarg (str)
- const char *str;
+addarg (const char *str)
{
int i;
@@ -98,9 +97,7 @@ addarg (str)
}
static void
-preprocess_args (p_argc, argv)
- int *p_argc;
- char *argv[];
+preprocess_args (int *p_argc, char *argv[])
{
int i;
@@ -120,9 +117,7 @@ preprocess_args (p_argc, argv)
}
static void
-process_args (p_argc, argv)
- int *p_argc;
- char *argv[];
+process_args (int *p_argc, char *argv[])
{
int i;
@@ -183,9 +178,7 @@ process_args (p_argc, argv)
typedef struct dsc {unsigned short len, mbz; char *adr; } Descr;
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
int i;
char cwdev [128], *devptr;
@@ -318,17 +311,14 @@ static char new_host_dirspec [255];
static char filename_buff [256];
static int
-translate_unix (name, type)
- char *name;
- int type ATTRIBUTE_UNUSED;
+translate_unix (char *name, int type ATTRIBUTE_UNUSED)
{
strcpy (filename_buff, name);
return 0;
}
static char *
-to_host_dir_spec (dirspec)
- char *dirspec;
+to_host_dir_spec (char *dirspec)
{
int len = strlen (dirspec);
@@ -351,8 +341,7 @@ to_host_dir_spec (dirspec)
}
static char *
-to_host_file_spec (filespec)
- char *filespec;
+to_host_file_spec (char *filespec)
{
strcpy (new_host_filespec, "");
if (strchr (filespec, ']') || strchr (filespec, ':'))
diff --git a/contrib/gcc/config/alpha/vms-crt0-64.c b/contrib/gcc/config/alpha/vms-crt0-64.c
index 82ba3229772c..9792f9205a55 100644
--- a/contrib/gcc/config/alpha/vms-crt0-64.c
+++ b/contrib/gcc/config/alpha/vms-crt0-64.c
@@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -77,7 +77,7 @@ __main (arg1, arg2, arg3, image_file_desc, arg5, arg6)
#pragma __pointer_size long
- /* Reallocate argv with 64 bit pointers. */
+ /* Reallocate argv with 64 bit pointers. */
long_argv = (char **) malloc (sizeof (char *) * (argc + 1));
for (i = 0; i < argc; i++)
diff --git a/contrib/gcc/config/alpha/vms-crt0.c b/contrib/gcc/config/alpha/vms-crt0.c
index b7665f9fcb4e..88896c63af75 100644
--- a/contrib/gcc/config/alpha/vms-crt0.c
+++ b/contrib/gcc/config/alpha/vms-crt0.c
@@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -33,7 +33,7 @@ You Lose! This file can only be compiled with DEC C.
#else
/* This file can only be compiled with DEC C, due to the call to
- lib$establish. */
+ lib$establish. */
#include <stdlib.h>
#include <string.h>
diff --git a/contrib/gcc/config/alpha/vms-dwarf2.asm b/contrib/gcc/config/alpha/vms-dwarf2.asm
index a94ae24b1521..1f68a80be25a 100644
--- a/contrib/gcc/config/alpha/vms-dwarf2.asm
+++ b/contrib/gcc/config/alpha/vms-dwarf2.asm
@@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/alpha/vms-dwarf2eh.asm b/contrib/gcc/config/alpha/vms-dwarf2eh.asm
index 22f705035115..2cdbeb1bcabc 100644
--- a/contrib/gcc/config/alpha/vms-dwarf2eh.asm
+++ b/contrib/gcc/config/alpha/vms-dwarf2eh.asm
@@ -2,9 +2,9 @@
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/alpha/vms-ld.c b/contrib/gcc/config/alpha/vms-ld.c
index e5688d89d535..cb1d4c93faaa 100644
--- a/contrib/gcc/config/alpha/vms-ld.c
+++ b/contrib/gcc/config/alpha/vms-ld.c
@@ -1,22 +1,22 @@
/* VMS linker wrapper.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -26,6 +26,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
typedef struct dsc {unsigned short len, mbz; char *adr; } Descr;
@@ -42,7 +44,7 @@ static char *vmsdwarf2spec = 0;
/* File specification for vms-dwarf2eh.o. */
static char *vmsdwarf2ehspec = 0;
-/* verbose = 1 if -v passed. */
+/* verbose = 1 if -v passed. */
static int verbose = 0;
/* save_temps = 1 if -save-temps passed. */
@@ -87,39 +89,38 @@ static char *search_dirs;
/* Add STR to the list of arguments to pass to the linker. Expand the list as
necessary to accommodate. */
-static void addarg PARAMS ((const char *));
+static void addarg (const char *);
/* Check to see if NAME is a regular file, i.e. not a directory */
-static int is_regular_file PARAMS ((char *));
+static int is_regular_file (char *);
/* Translate a Unix syntax file specification FILESPEC into VMS syntax.
- If indicators of VMS syntax found, return input string. */
-static char *to_host_file_spec PARAMS ((char *));
+ If indicators of VMS syntax found, return input string. */
+static char *to_host_file_spec (char *);
-/* Locate the library named LIB_NAME in the set of paths PATH_VAL. */
-static char *locate_lib PARAMS ((char *, char *));
+/* Locate the library named LIB_NAME in the set of paths PATH_VAL. */
+static char *locate_lib (char *, char *);
/* Given a library name NAME, i.e. foo, Look for libfoo.lib and then
libfoo.a in the set of directories we are allowed to search in. */
-static const char *expand_lib PARAMS ((char *));
+static const char *expand_lib (char *);
/* Preprocess the number of args P_ARGC in ARGV.
- Look for special flags, etc. that must be handled first. */
-static void preprocess_args PARAMS ((int *, char **));
+ Look for special flags, etc. that must be handled first. */
+static void preprocess_args (int *, char **);
/* Preprocess the number of args P_ARGC in ARGV. Look for
- special flags, etc. that must be handled for the VMS linker. */
-static void process_args PARAMS ((int *, char **));
+ special flags, etc. that must be handled for the VMS linker. */
+static void process_args (int *, char **);
/* Action routine called by decc$to_vms. NAME is a file name or
- directory name. TYPE is unused. */
-static int translate_unix PARAMS ((char *, int));
+ directory name. TYPE is unused. */
+static int translate_unix (char *, int);
-int main PARAMS ((int, char **));
+int main (int, char **);
static void
-addarg (str)
- const char *str;
+addarg (const char *str)
{
int i;
@@ -142,9 +143,7 @@ addarg (str)
}
static char *
-locate_lib (lib_name, path_val)
- char *lib_name;
- char *path_val;
+locate_lib (char *lib_name, char *path_val)
{
int lib_len = strlen (lib_name);
char *eptr, *sptr;
@@ -204,8 +203,7 @@ locate_lib (lib_name, path_val)
}
static const char *
-expand_lib (name)
- char *name;
+expand_lib (char *name)
{
char *lib, *lib_path;
@@ -238,8 +236,7 @@ expand_lib (name)
}
static int
-is_regular_file (name)
- char *name;
+is_regular_file (char *name)
{
int ret;
struct stat statbuf;
@@ -249,9 +246,7 @@ is_regular_file (name)
}
static void
-preprocess_args (p_argc, argv)
- int *p_argc;
- char **argv;
+preprocess_args (int *p_argc, char **argv)
{
int i;
@@ -303,9 +298,7 @@ preprocess_args (p_argc, argv)
}
static void
-process_args (p_argc, argv)
- int *p_argc;
- char **argv;
+process_args (int *p_argc, char **argv)
{
int i;
@@ -379,9 +372,7 @@ process_args (p_argc, argv)
and args to be what the VMS linker wants. */
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
int i;
char cwdev [128], *devptr;
@@ -751,17 +742,14 @@ static char new_host_filespec [255];
static char filename_buff [256];
static int
-translate_unix (name, type)
- char *name;
- int type ATTRIBUTE_UNUSED;
+translate_unix (char *name, int type ATTRIBUTE_UNUSED)
{
strcpy (filename_buff, name);
return 0;
}
static char *
-to_host_file_spec (filespec)
- char *filespec;
+to_host_file_spec (char *filespec)
{
strcpy (new_host_filespec, "");
if (strchr (filespec, ']') || strchr (filespec, ':'))
diff --git a/contrib/gcc/config/alpha/vms-psxcrt0-64.c b/contrib/gcc/config/alpha/vms-psxcrt0-64.c
index b16e8b4ae8d9..8ca9e1d07b53 100644
--- a/contrib/gcc/config/alpha/vms-psxcrt0-64.c
+++ b/contrib/gcc/config/alpha/vms-psxcrt0-64.c
@@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -79,7 +79,7 @@ __main (arg1, arg2, arg3, image_file_desc, arg5, arg6)
#pragma __pointer_size long
- /* Reallocate argv with 64 bit pointers. */
+ /* Reallocate argv with 64 bit pointers. */
long_argv = (char **) malloc (sizeof (char *) * (argc + 1));
for (i = 0; i < argc; i++)
diff --git a/contrib/gcc/config/alpha/vms-psxcrt0.c b/contrib/gcc/config/alpha/vms-psxcrt0.c
index c4140b4f8b52..65962ee22196 100644
--- a/contrib/gcc/config/alpha/vms-psxcrt0.c
+++ b/contrib/gcc/config/alpha/vms-psxcrt0.c
@@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -33,7 +33,7 @@ You Lose! This file can only be compiled with DEC C.
#else
/* This file can only be compiled with DEC C, due to the call to
- lib$establish. */
+ lib$establish. */
#include <stdlib.h>
#include <string.h>
diff --git a/contrib/gcc/config/alpha/vms.h b/contrib/gcc/config/alpha/vms.h
index 8df61564e722..f7058f3ff399 100644
--- a/contrib/gcc/config/alpha/vms.h
+++ b/contrib/gcc/config/alpha/vms.h
@@ -1,21 +1,21 @@
/* Output variables, constants and external declarations, for GNU compiler.
- Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002
+ Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -41,9 +41,6 @@ Boston, MA 02111-1307, USA. */
builtin_define ("__IEEE_FLOAT"); \
} while (0)
-/* By default, allow $ to be part of an identifier. */
-#define DOLLARS_IN_IDENTIFIERS 2
-
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_FP|MASK_FPREGS|MASK_GAS)
#undef TARGET_ABI_OPEN_VMS
@@ -54,9 +51,6 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (%s)", TARGET_NAME);
-/* The structure return address arrives as an "argument" on VMS. */
-#undef STRUCT_VALUE_REGNUM
-#define STRUCT_VALUE 0
#undef PCC_STATIC_STRUCT_RETURN
/* "long" is 32 bits, but 64 bits for Ada. */
@@ -178,7 +172,7 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
For a library call, FNTYPE is 0. */
#undef INIT_CUMULATIVE_ARGS
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
(CUM).num_args = 0; \
(CUM).atypes[0] = (CUM).atypes[1] = (CUM).atypes[2] = I64; \
(CUM).atypes[3] = (CUM).atypes[4] = (CUM).atypes[5] = I64;
@@ -205,61 +199,10 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
+ ALPHA_ARG_SIZE (MODE, TYPE, NAMED) \
? 6 - (CUM).num_args : 0)
-/* Perform any needed actions needed for a function that is receiving a
- variable number of arguments.
-
- CUM is as for INIT_CUMULATIVE_ARGS.
-
- MODE and TYPE are the mode and type of the current parameter.
-
- PRETEND_SIZE is a variable that should be set to the amount of stack
- that must be pushed by the prolog to pretend that our caller pushed
- it.
-
- Normally, this macro will push all remaining incoming registers on the
- stack and set PRETEND_SIZE to the length of the registers pushed.
-
- For VMS, we allocate space for all 6 arg registers plus a count.
-
- However, if NO registers need to be saved, don't allocate any space.
- This is not only because we won't need the space, but because AP includes
- the current_pretend_args_size and we don't want to mess up any
- ap-relative addresses already made. */
-
-#undef SETUP_INCOMING_VARARGS
-#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
-{ if ((CUM).num_args < 6) \
- { \
- if (! (NO_RTL)) \
- { \
- emit_move_insn (gen_rtx_REG (DImode, 1), \
- virtual_incoming_args_rtx); \
- emit_insn (gen_arg_home ()); \
- } \
- \
- PRETEND_SIZE = 7 * UNITS_PER_WORD; \
- } \
-}
-
/* ABI has stack checking, but it's broken. */
#undef STACK_CHECK_BUILTIN
#define STACK_CHECK_BUILTIN 0
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
-{ \
- alpha_write_verstamp (FILE); \
- fprintf (FILE, "\t.set noreorder\n"); \
- fprintf (FILE, "\t.set volatile\n"); \
- if (TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX) \
- { \
- fprintf (FILE, "\t.arch %s\n", \
- (TARGET_CPU_EV6 ? "ev6" \
- : TARGET_MAX ? "pca56" : "ev56")); \
- } \
- ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \
-}
-
#define LINK_SECTION_ASM_OP "\t.link"
#define READONLY_DATA_SECTION_ASM_OP "\t.rdata"
#define LITERALS_SECTION_ASM_OP "\t.literals"
@@ -272,7 +215,7 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
void \
-link_section () \
+link_section (void) \
{ \
if (in_section != in_link) \
{ \
@@ -281,7 +224,7 @@ link_section () \
} \
} \
void \
-literals_section () \
+literals_section (void) \
{ \
if (in_section != in_literals) \
{ \
@@ -290,8 +233,8 @@ literals_section () \
} \
}
-extern void link_section PARAMS ((void));
-extern void literals_section PARAMS ((void));
+extern void link_section (void);
+extern void literals_section (void);
#undef ASM_OUTPUT_ADDR_DIFF_ELT
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort ()
@@ -306,7 +249,7 @@ extern void literals_section PARAMS ((void));
#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
-{ ASM_OUTPUT_ALIGN (FILE, 3); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
+{ ASM_OUTPUT_ALIGN (FILE, 3); (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); }
/* This says how to output assembler code to declare an
uninitialized external linkage data object. */
@@ -318,7 +261,7 @@ extern void literals_section PARAMS ((void));
do { \
fprintf ((FILE), "%s", COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+ fprintf ((FILE), "," HOST_WIDE_INT_PRINT_UNSIGNED ",%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
} while (0)
@@ -448,10 +391,7 @@ do { \
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE VMS_AND_DWARF2_DEBUG
-#undef ASM_FORMAT_PRIVATE_NAME
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 12), \
- sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
+#define ASM_PN_FORMAT "%s___%lu"
/* ??? VMS uses different linkage. */
#undef TARGET_ASM_OUTPUT_MI_THUNK
@@ -479,7 +419,7 @@ do { \
}
/* Link with vms-dwarf2.o if -g (except -g0). This causes the
- VMS link to pull all the dwarf2 debug sections together. */
+ VMS link to pull all the dwarf2 debug sections together. */
#undef LINK_SPEC
#define LINK_SPEC "%{g:-g vms-dwarf2.o%s} %{g0} %{g1:-g1 vms-dwarf2.o%s} \
%{g2:-g2 vms-dwarf2.o%s} %{g3:-g3 vms-dwarf2.o%s} %{shared} %{v} %{map}"
@@ -491,16 +431,6 @@ do { \
#undef LIB_SPEC
#define LIB_SPEC "-lc"
-/* Define the names of the division and modulus functions. */
-#define DIVSI3_LIBCALL "OTS$DIV_I"
-#define DIVDI3_LIBCALL "OTS$DIV_L"
-#define UDIVSI3_LIBCALL "OTS$DIV_UI"
-#define UDIVDI3_LIBCALL "OTS$DIV_UL"
-#define MODSI3_LIBCALL "OTS$REM_I"
-#define MODDI3_LIBCALL "OTS$REM_L"
-#define UMODSI3_LIBCALL "OTS$REM_UI"
-#define UMODDI3_LIBCALL "OTS$REM_UL"
-
#define NAME__MAIN "__gccmain"
#define SYMBOL__MAIN __gccmain
diff --git a/contrib/gcc/config/alpha/vms64.h b/contrib/gcc/config/alpha/vms64.h
index 3b4f5874669c..29de9a556dc2 100644
--- a/contrib/gcc/config/alpha/vms64.h
+++ b/contrib/gcc/config/alpha/vms64.h
@@ -2,20 +2,20 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/alpha/vms_tramp.asm b/contrib/gcc/config/alpha/vms_tramp.asm
index 9a6a1c8a2413..1eb1e2b4b6b1 100644
--- a/contrib/gcc/config/alpha/vms_tramp.asm
+++ b/contrib/gcc/config/alpha/vms_tramp.asm
@@ -2,9 +2,9 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -18,13 +18,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/alpha/xm-vms.h b/contrib/gcc/config/alpha/xm-vms.h
index 7bfcebae81c8..bdac52e78aa1 100644
--- a/contrib/gcc/config/alpha/xm-vms.h
+++ b/contrib/gcc/config/alpha/xm-vms.h
@@ -2,26 +2,23 @@
Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc.
Contributed by Klaus Kaempf (kkaempf@progis.de).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define HOST_WIDE_INT long long
-#define HOST_BITS_PER_WIDE_INT 64
-
/* A couple of conditionals for execution machine are controlled here. */
#ifndef VMS
#define VMS
diff --git a/contrib/gcc/config/arm/README-interworking b/contrib/gcc/config/arm/README-interworking
index de8b27841b24..0a03cdc3c9d9 100644
--- a/contrib/gcc/config/arm/README-interworking
+++ b/contrib/gcc/config/arm/README-interworking
@@ -404,7 +404,7 @@ Instead the pseudo op is attached to a new label .real_start_of_<name>
(where <name> is the name of the function) which indicates the start
of the Thumb code. This does have the interesting side effect in that
if this function is now called from a Thumb mode piece of code
-outsside of the current file, the linker will generate a calling stub
+outside of the current file, the linker will generate a calling stub
to switch from Thumb mode into ARM mode, and then this is immediately
overridden by the function's header which switches back into Thumb
mode.
diff --git a/contrib/gcc/config/arm/aof.h b/contrib/gcc/config/arm/aof.h
index 965337cf7006..5a6ab2c0e2c8 100644
--- a/contrib/gcc/config/arm/aof.h
+++ b/contrib/gcc/config/arm/aof.h
@@ -1,24 +1,24 @@
/* Definitions of target machine for GNU compiler, for Advanced RISC Machines
ARM compilation, AOF Assembler.
- Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 2000, 2003 Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rearnsha@armltd.co.uk)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
@@ -27,7 +27,7 @@ Boston, MA 02111-1307, USA. */
#define LINK_LIBGCC_SPECIAL 1
#define LINK_SPEC "%{aof} %{bin} %{aif} %{ihf} %{shl,*} %{reent*} %{split} \
- %{ov*,*} %{reloc*} -nodebug"
+ %{ov*} %{reloc*} -nodebug"
#define STARTFILE_SPEC "crtbegin.o%s"
@@ -59,64 +59,70 @@ Boston, MA 02111-1307, USA. */
#define EXTRA_SECTIONS in_zero_init, in_common
#define EXTRA_SECTION_FUNCTIONS \
-ZERO_INIT_SECTION \
-COMMON_SECTION
+ ZERO_INIT_SECTION \
+ COMMON_SECTION
#define ZERO_INIT_SECTION \
-void \
-zero_init_section () \
-{ \
- static int zero_init_count = 1; \
- if (in_section != in_zero_init) \
- { \
- fprintf (asm_out_file, "\tAREA |C$$zidata%d|,NOINIT\n", \
- zero_init_count++); \
- in_section = in_zero_init; \
- } \
-}
+ void \
+ zero_init_section () \
+ { \
+ static int zero_init_count = 1; \
+ \
+ if (in_section != in_zero_init) \
+ { \
+ fprintf (asm_out_file, "\tAREA |C$$zidata%d|,NOINIT\n", \
+ zero_init_count++); \
+ in_section = in_zero_init; \
+ } \
+ }
/* Used by ASM_OUTPUT_COMMON (below) to tell varasm.c that we've
changed areas. */
#define COMMON_SECTION \
-void \
-common_section () \
-{ \
- if (in_section != in_common) \
- { \
+ void \
+ common_section () \
+ { \
+ if (in_section != in_common) \
in_section = in_common; \
- } \
-}
-#define CTOR_LIST_BEGIN \
-asm (CTORS_SECTION_ASM_OP); \
-extern func_ptr __CTOR_END__[1]; \
-func_ptr __CTOR_LIST__[1] = {__CTOR_END__};
+ }
-#define CTOR_LIST_END \
-asm (CTORS_SECTION_ASM_OP); \
-func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
+#define CTOR_LIST_BEGIN \
+ asm (CTORS_SECTION_ASM_OP); \
+ extern func_ptr __CTOR_END__[1]; \
+ func_ptr __CTOR_LIST__[1] = {__CTOR_END__};
-#define DO_GLOBAL_CTORS_BODY \
-do { \
- func_ptr *ptr = __CTOR_LIST__ + 1; \
- while (*ptr) \
- (*ptr++) (); \
-} while (0)
+#define CTOR_LIST_END \
+ asm (CTORS_SECTION_ASM_OP); \
+ func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
-#define DTOR_LIST_BEGIN \
-asm (DTORS_SECTION_ASM_OP); \
-extern func_ptr __DTOR_END__[1]; \
-func_ptr __DTOR_LIST__[1] = {__DTOR_END__};
+#define DO_GLOBAL_CTORS_BODY \
+ do \
+ { \
+ func_ptr *ptr = __CTOR_LIST__ + 1; \
+ \
+ while (*ptr) \
+ (*ptr++) (); \
+ } \
+ while (0)
-#define DTOR_LIST_END \
-asm (DTORS_SECTION_ASM_OP); \
-func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
+#define DTOR_LIST_BEGIN \
+ asm (DTORS_SECTION_ASM_OP); \
+ extern func_ptr __DTOR_END__[1]; \
+ func_ptr __DTOR_LIST__[1] = {__DTOR_END__};
-#define DO_GLOBAL_DTORS_BODY \
-do { \
- func_ptr *ptr = __DTOR_LIST__ + 1; \
- while (*ptr) \
- (*ptr++) (); \
-} while (0)
+#define DTOR_LIST_END \
+ asm (DTORS_SECTION_ASM_OP); \
+ func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
+
+#define DO_GLOBAL_DTORS_BODY \
+ do \
+ { \
+ func_ptr *ptr = __DTOR_LIST__ + 1; \
+ \
+ while (*ptr) \
+ (*ptr++) (); \
+ } \
+ while (0)
/* We really want to put Thumb tables in a read-only data section, but
switching to another section during function output is not
@@ -124,68 +130,18 @@ do { \
whole table generation until the end of the function. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
-#ifndef ARM_OS_NAME
-#define ARM_OS_NAME "(generic)"
-#endif
-
-/* For the AOF linker, we need to reference __main to force the standard
- library to get linked in. */
-
-#define ASM_FILE_START(STREAM) \
-{ \
- fprintf ((STREAM), "%s Generated by gcc %s for ARM/%s\n", \
- ASM_COMMENT_START, version_string, ARM_OS_NAME); \
- fprintf ((STREAM), "__r0\tRN\t0\n"); \
- fprintf ((STREAM), "__a1\tRN\t0\n"); \
- fprintf ((STREAM), "__a2\tRN\t1\n"); \
- fprintf ((STREAM), "__a3\tRN\t2\n"); \
- fprintf ((STREAM), "__a4\tRN\t3\n"); \
- fprintf ((STREAM), "__v1\tRN\t4\n"); \
- fprintf ((STREAM), "__v2\tRN\t5\n"); \
- fprintf ((STREAM), "__v3\tRN\t6\n"); \
- fprintf ((STREAM), "__v4\tRN\t7\n"); \
- fprintf ((STREAM), "__v5\tRN\t8\n"); \
- fprintf ((STREAM), "__v6\tRN\t9\n"); \
- fprintf ((STREAM), "__sl\tRN\t10\n"); \
- fprintf ((STREAM), "__fp\tRN\t11\n"); \
- fprintf ((STREAM), "__ip\tRN\t12\n"); \
- fprintf ((STREAM), "__sp\tRN\t13\n"); \
- fprintf ((STREAM), "__lr\tRN\t14\n"); \
- fprintf ((STREAM), "__pc\tRN\t15\n"); \
- fprintf ((STREAM), "__f0\tFN\t0\n"); \
- fprintf ((STREAM), "__f1\tFN\t1\n"); \
- fprintf ((STREAM), "__f2\tFN\t2\n"); \
- fprintf ((STREAM), "__f3\tFN\t3\n"); \
- fprintf ((STREAM), "__f4\tFN\t4\n"); \
- fprintf ((STREAM), "__f5\tFN\t5\n"); \
- fprintf ((STREAM), "__f6\tFN\t6\n"); \
- fprintf ((STREAM), "__f7\tFN\t7\n"); \
- text_section (); \
-}
-
/* Some systems use __main in a way incompatible with its use in gcc, in these
cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
give the same symbol without quotes for an alternative entry point. You
- must define both, or neither. */
+ must define both, or neither. */
#define NAME__MAIN "__gccmain"
#define SYMBOL__MAIN __gccmain
-#define ASM_FILE_END(STREAM) \
-do \
-{ \
- if (flag_pic) \
- aof_dump_pic_table (STREAM); \
- aof_dump_imports (STREAM); \
- fputs ("\tEND\n", (STREAM)); \
-} while (0);
-
#define ASM_COMMENT_START ";"
+#define ASM_APP_ON ""
+#define ASM_APP_OFF ""
-#define ASM_APP_ON ""
-
-#define ASM_APP_OFF ""
-
-#define ASM_OUTPUT_ASCII(STREAM,PTR,LEN) \
+#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \
{ \
int i; \
const char *ptr = (PTR); \
@@ -193,31 +149,30 @@ do \
for (i = 0; i < (long)(LEN); i++) \
fprintf ((STREAM), " &%02x%s", \
(unsigned ) *(ptr++), \
- (i + 1 < (long)(LEN) \
+ (i + 1 < (long)(LEN) \
? ((i & 3) == 3 ? "\n\tDCB" : ",") \
: "\n")); \
}
#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == '\n')
-/* Output of Uninitialized Variables */
+/* Output of Uninitialized Variables. */
-#define ASM_OUTPUT_COMMON(STREAM,NAME,SIZE,ROUNDED) \
+#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
(common_section (), \
fprintf ((STREAM), "\tAREA "), \
assemble_name ((STREAM), (NAME)), \
fprintf ((STREAM), ", DATA, COMMON\n\t%% %d\t%s size=%d\n", \
- (ROUNDED), ASM_COMMENT_START, SIZE))
+ (int)(ROUNDED), ASM_COMMENT_START, (int)(SIZE)))
-#define ASM_OUTPUT_LOCAL(STREAM,NAME,SIZE,ROUNDED) \
+#define ASM_OUTPUT_LOCAL(STREAM, NAME, SIZE, ROUNDED) \
(zero_init_section (), \
assemble_name ((STREAM), (NAME)), \
fprintf ((STREAM), "\n"), \
fprintf ((STREAM), "\t%% %d\t%s size=%d\n", \
- (ROUNDED), ASM_COMMENT_START, SIZE))
+ (int)(ROUNDED), ASM_COMMENT_START, (int)(SIZE)))
/* Output and Generation of Labels */
-
extern int arm_main_function;
/* Globalizing directive for a label. */
@@ -267,26 +222,31 @@ do { \
#define ASM_GENERATE_INTERNAL_LABEL(STRING,PREFIX,NUM) \
sprintf ((STRING), "*|%s..%ld|", (PREFIX), (long)(NUM))
-#define ASM_FORMAT_PRIVATE_NAME(OUTVAR,NAME,NUMBER) \
- ((OUTVAR) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER)))
-
-/* How initialization functions are handled */
+/* How initialization functions are handled. */
#define CTORS_SECTION_ASM_OP "\tAREA\t|C$$gnu_ctorsvec|, DATA, READONLY"
#define DTORS_SECTION_ASM_OP "\tAREA\t|C$$gnu_dtorsvec|, DATA, READONLY"
-/* Output of Assembler Instructions */
-
-#define REGISTER_NAMES \
-{ \
- "a1", "a2", "a3", "a4", \
- "v1", "v2", "v3", "v4", \
- "v5", "v6", "sl", "fp", \
- "ip", "sp", "lr", "pc", \
- "f0", "f1", "f2", "f3", \
- "f4", "f5", "f6", "f7", \
- "cc", "sfp", "afp" \
+/* Output of Assembler Instructions. */
+
+#define REGISTER_NAMES \
+{ \
+ "a1", "a2", "a3", "a4", \
+ "v1", "v2", "v3", "v4", \
+ "v5", "v6", "sl", "fp", \
+ "ip", "sp", "lr", "pc", \
+ "f0", "f1", "f2", "f3", \
+ "f4", "f5", "f6", "f7", \
+ "cc", "sfp", "afp", \
+ "mv0", "mv1", "mv2", "mv3", \
+ "mv4", "mv5", "mv6", "mv7", \
+ "mv8", "mv9", "mv10", "mv11", \
+ "mv12", "mv13", "mv14", "mv15", \
+ "wcgr0", "wcgr1", "wcgr2", "wcgr3", \
+ "wr0", "wr1", "wr2", "wr3", \
+ "wr4", "wr5", "wr6", "wr7", \
+ "wr8", "wr9", "wr10", "wr11", \
+ "wr12", "wr13", "wr14", "wr15" \
}
#define ADDITIONAL_REGISTER_NAMES \
@@ -316,37 +276,40 @@ do { \
/* AOF does not prefix user function names with an underscore. */
#define ARM_MCOUNT_NAME "_mcount"
-/* Output of Dispatch Tables */
-
-#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL) \
- do { \
- if (TARGET_ARM) \
- fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE)); \
- else \
- fprintf ((STREAM), "\tDCD\t|L..%d| - |L..%d|\n", (VALUE), (REL)); \
- } while (0)
-
-#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM,VALUE) \
+/* Output of Dispatch Tables. */
+#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
+ do \
+ { \
+ if (TARGET_ARM) \
+ fprintf ((STREAM), "\tb\t|L..%d|\n", (VALUE)); \
+ else \
+ fprintf ((STREAM), "\tDCD\t|L..%d| - |L..%d|\n", (VALUE), (REL)); \
+ } \
+ while (0)
+
+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
fprintf ((STREAM), "\tDCD\t|L..%d|\n", (VALUE))
-/* A label marking the start of a jump table is a data label. */
-#define ASM_OUTPUT_CASE_LABEL(STREAM,PREFIX,NUM,TABLE) \
+/* A label marking the start of a jump table is a data label. */
+#define ASM_OUTPUT_CASE_LABEL(STREAM, PREFIX, NUM, TABLE) \
fprintf ((STREAM), "\tALIGN\n|%s..%d|\n", (PREFIX), (NUM))
-/* Assembler Commands for Alignment */
-
-#define ASM_OUTPUT_SKIP(STREAM,NBYTES) \
- fprintf ((STREAM), "\t%%\t%d\n", (NBYTES))
-
-#define ASM_OUTPUT_ALIGN(STREAM,POWER) \
-do { \
- register int amount = 1 << (POWER); \
- if (amount == 2) \
- fprintf ((STREAM), "\tALIGN 2\n"); \
- else if (amount == 4) \
- fprintf ((STREAM), "\tALIGN\n"); \
- else \
- fprintf ((STREAM), "\tALIGN %d\n", amount); \
-} while (0)
+/* Assembler Commands for Alignment. */
+#define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
+ fprintf ((STREAM), "\t%%\t%d\n", (int) (NBYTES))
+
+#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
+ do \
+ { \
+ int amount = 1 << (POWER); \
+ \
+ if (amount == 2) \
+ fprintf ((STREAM), "\tALIGN 2\n"); \
+ else if (amount == 4) \
+ fprintf ((STREAM), "\tALIGN\n"); \
+ else \
+ fprintf ((STREAM), "\tALIGN %d\n", amount); \
+ } \
+ while (0)
#undef DBX_DEBUGGING_INFO
diff --git a/contrib/gcc/config/arm/aout.h b/contrib/gcc/config/arm/aout.h
index 8f4a6056f989..1f060fafc7b1 100644
--- a/contrib/gcc/config/arm/aout.h
+++ b/contrib/gcc/config/arm/aout.h
@@ -3,40 +3,22 @@
Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rearnsha@armltd.co.uk).
-This file is part of GNU CC.
-
-GNU CC 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.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#ifndef ARM_OS_NAME
-#define ARM_OS_NAME "(generic)"
-#endif
-
-/* The text to go at the start of the assembler file */
-#ifndef ASM_FILE_START
-#define ASM_FILE_START(STREAM) \
-{ \
- asm_fprintf (STREAM,"%Rrfp\t.req\t%Rr9\n"); \
- asm_fprintf (STREAM,"%Rsl\t.req\t%Rr10\n"); \
- asm_fprintf (STREAM,"%Rfp\t.req\t%Rr11\n"); \
- asm_fprintf (STREAM,"%Rip\t.req\t%Rr12\n"); \
- asm_fprintf (STREAM,"%Rsp\t.req\t%Rr13\n"); \
- asm_fprintf (STREAM,"%Rlr\t.req\t%Rr14\n"); \
- asm_fprintf (STREAM,"%Rpc\t.req\t%Rr15\n"); \
-}
-#endif
+ 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 2, 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 COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#ifndef ASM_APP_ON
#define ASM_APP_ON ""
@@ -52,7 +34,7 @@ Boston, MA 02111-1307, USA. */
/* Note: If USER_LABEL_PREFIX or LOCAL_LABEL_PREFIX are changed,
make sure that this change is reflected in the function
- coff_arm_is_local_label_name() in bfd/coff-arm.c */
+ coff_arm_is_local_label_name() in bfd/coff-arm.c. */
#ifndef REGISTER_PREFIX
#define REGISTER_PREFIX ""
#endif
@@ -65,7 +47,6 @@ Boston, MA 02111-1307, USA. */
#define LOCAL_LABEL_PREFIX ""
#endif
-
/* The assembler's names for the registers. */
#ifndef REGISTER_NAMES
#define REGISTER_NAMES \
@@ -73,7 +54,16 @@ Boston, MA 02111-1307, USA. */
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc", \
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
- "cc", "sfp", "afp" \
+ "cc", "sfp", "afp", \
+ "mv0", "mv1", "mv2", "mv3", \
+ "mv4", "mv5", "mv6", "mv7", \
+ "mv8", "mv9", "mv10", "mv11", \
+ "mv12", "mv13", "mv14", "mv15", \
+ "wcgr0", "wcgr1", "wcgr2", "wcgr3", \
+ "wr0", "wr1", "wr2", "wr3", \
+ "wr4", "wr5", "wr6", "wr7", \
+ "wr8", "wr9", "wr10", "wr11", \
+ "wr12", "wr13", "wr14", "wr15" \
}
#endif
@@ -98,11 +88,75 @@ Boston, MA 02111-1307, USA. */
{"r12", 12}, /* ip */ \
{"r13", 13}, /* sp */ \
{"r14", 14}, /* lr */ \
- {"r15", 15} /* pc */ \
+ {"r15", 15}, /* pc */ \
+ {"mvf0", 27}, \
+ {"mvf1", 28}, \
+ {"mvf2", 29}, \
+ {"mvf3", 30}, \
+ {"mvf4", 31}, \
+ {"mvf5", 32}, \
+ {"mvf6", 33}, \
+ {"mvf7", 34}, \
+ {"mvf8", 35}, \
+ {"mvf9", 36}, \
+ {"mvf10", 37}, \
+ {"mvf11", 38}, \
+ {"mvf12", 39}, \
+ {"mvf13", 40}, \
+ {"mvf14", 41}, \
+ {"mvf15", 42}, \
+ {"mvd0", 27}, \
+ {"mvd1", 28}, \
+ {"mvd2", 29}, \
+ {"mvd3", 30}, \
+ {"mvd4", 31}, \
+ {"mvd5", 32}, \
+ {"mvd6", 33}, \
+ {"mvd7", 34}, \
+ {"mvd8", 35}, \
+ {"mvd9", 36}, \
+ {"mvd10", 37}, \
+ {"mvd11", 38}, \
+ {"mvd12", 39}, \
+ {"mvd13", 40}, \
+ {"mvd14", 41}, \
+ {"mvd15", 42}, \
+ {"mvfx0", 27}, \
+ {"mvfx1", 28}, \
+ {"mvfx2", 29}, \
+ {"mvfx3", 30}, \
+ {"mvfx4", 31}, \
+ {"mvfx5", 32}, \
+ {"mvfx6", 33}, \
+ {"mvfx7", 34}, \
+ {"mvfx8", 35}, \
+ {"mvfx9", 36}, \
+ {"mvfx10", 37}, \
+ {"mvfx11", 38}, \
+ {"mvfx12", 39}, \
+ {"mvfx13", 40}, \
+ {"mvfx14", 41}, \
+ {"mvfx15", 42}, \
+ {"mvdx0", 27}, \
+ {"mvdx1", 28}, \
+ {"mvdx2", 29}, \
+ {"mvdx3", 30}, \
+ {"mvdx4", 31}, \
+ {"mvdx5", 32}, \
+ {"mvdx6", 33}, \
+ {"mvdx7", 34}, \
+ {"mvdx8", 35}, \
+ {"mvdx9", 36}, \
+ {"mvdx10", 37}, \
+ {"mvdx11", 38}, \
+ {"mvdx12", 39}, \
+ {"mvdx13", 40}, \
+ {"mvdx14", 41}, \
+ {"mvdx15", 42} \
}
#endif
-/* Arm Assembler barfs on dollars */
+/* Arm Assembler barfs on dollars. */
#define DOLLARS_IN_IDENTIFIERS 0
#ifndef NO_DOLLAR_IN_LABEL
@@ -110,7 +164,7 @@ Boston, MA 02111-1307, USA. */
#endif
/* Generate DBX debugging information. riscix.h will undefine this because
- the native assembler does not support stabs. */
+ the native assembler does not support stabs. */
#define DBX_DEBUGGING_INFO 1
/* Acorn dbx moans about continuation chars, so don't use any. */
@@ -127,7 +181,7 @@ Boston, MA 02111-1307, USA. */
output_quoted_string (STREAM, NAME); \
fprintf (STREAM, ",%d,0,315,%s\n", N_SO, &ltext_label_name[1]); \
text_section (); \
- ASM_OUTPUT_INTERNAL_LABEL (STREAM, "Ltext", 0); \
+ (*targetm.asm_out.internal_label) (STREAM, "Ltext", 0); \
} \
while (0)
@@ -151,11 +205,6 @@ Boston, MA 02111-1307, USA. */
sprintf (STRING, "*%s%s%u", LOCAL_LABEL_PREFIX, PREFIX, (unsigned int)(NUM))
#endif
-/* Construct a private name. */
-#define ASM_FORMAT_PRIVATE_NAME(OUTVAR, NAME, NUMBER) \
- ((OUTVAR) = (char *) alloca (strlen (NAME) + 10), \
- sprintf (OUTVAR, "%s.%d", NAME, NUMBER))
-
/* Output an element of a dispatch table. */
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
asm_fprintf (STREAM, "\t.word\t%LL%d\n", VALUE)
@@ -173,12 +222,12 @@ Boston, MA 02111-1307, USA. */
#undef ASM_OUTPUT_ASCII
#define ASM_OUTPUT_ASCII(STREAM, PTR, LEN) \
- output_ascii_pseudo_op (STREAM, (const unsigned char *)(PTR), LEN)
+ output_ascii_pseudo_op (STREAM, (const unsigned char *) (PTR), LEN)
/* Output a gap. In fact we fill it with nulls. */
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
- fprintf (STREAM, "\t.space\t%d\n", NBYTES)
+ fprintf (STREAM, "\t.space\t%d\n", (int) (NBYTES))
/* Align output to a power of two. Horrible /bin/as. */
#ifndef ASM_OUTPUT_ALIGN
@@ -195,7 +244,7 @@ Boston, MA 02111-1307, USA. */
while (0)
#endif
-/* Output a common block */
+/* Output a common block. */
#ifndef ASM_OUTPUT_COMMON
#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
do \
@@ -203,7 +252,7 @@ Boston, MA 02111-1307, USA. */
fprintf (STREAM, "\t.comm\t"); \
assemble_name (STREAM, NAME); \
asm_fprintf (STREAM, ", %d\t%@ %d\n", \
- ROUNDED, SIZE); \
+ (int)(ROUNDED), (int)(SIZE)); \
} \
while (0)
#endif
@@ -219,7 +268,7 @@ Boston, MA 02111-1307, USA. */
bss_section (); \
ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT)); \
ASM_OUTPUT_LABEL (STREAM, NAME); \
- fprintf (STREAM, "\t.space\t%d\n", SIZE); \
+ fprintf (STREAM, "\t.space\t%d\n", (int)(SIZE)); \
} \
while (0)
#endif
@@ -229,9 +278,6 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ALIGNED_BSS(STREAM, DECL, NAME, SIZE, ALIGN) \
asm_output_aligned_bss (STREAM, DECL, NAME, SIZE, ALIGN)
#endif
-
-/* Output a source line for the debugger. */
-/* #define ASM_OUTPUT_SOURCE_LINE(STREAM,LINE) */
/* Output a #ident directive. */
#ifndef ASM_OUTPUT_IDENT
diff --git a/contrib/gcc/config/arm/arm-modes.def b/contrib/gcc/config/arm/arm-modes.def
index 48f9ddfb0bd1..b85355191418 100644
--- a/contrib/gcc/config/arm/arm-modes.def
+++ b/contrib/gcc/config/arm/arm-modes.def
@@ -5,42 +5,48 @@
More major hacks by Richard Earnshaw (rearnsha@arm.com)
Minor hacks by Nick Clifton (nickc@cygnus.com)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Extended precision floating point.
+ FIXME What format is this? */
+FLOAT_MODE (XF, 12, 0);
/* CCFPEmode should be used with floating inequalities,
CCFPmode should be used with floating equalities.
CC_NOOVmode should be used with SImode integer equalities.
CC_Zmode should be used if only the Z flag is set correctly
- CCmode should be used otherwise. */
+ CC_Nmode should be used if only the N (sign) flag is set correctly
+ CCmode should be used otherwise. */
-CC (CC_NOOV)
-CC (CC_Z)
-CC (CC_SWP)
-CC (CCFP)
-CC (CCFPE)
-CC (CC_DNE)
-CC (CC_DEQ)
-CC (CC_DLE)
-CC (CC_DLT)
-CC (CC_DGE)
-CC (CC_DGT)
-CC (CC_DLEU)
-CC (CC_DLTU)
-CC (CC_DGEU)
-CC (CC_DGTU)
-CC (CC_C)
+CC_MODE (CC_NOOV);
+CC_MODE (CC_Z);
+CC_MODE (CC_SWP);
+CC_MODE (CCFP);
+CC_MODE (CCFPE);
+CC_MODE (CC_DNE);
+CC_MODE (CC_DEQ);
+CC_MODE (CC_DLE);
+CC_MODE (CC_DLT);
+CC_MODE (CC_DGE);
+CC_MODE (CC_DGT);
+CC_MODE (CC_DLEU);
+CC_MODE (CC_DLTU);
+CC_MODE (CC_DGEU);
+CC_MODE (CC_DGTU);
+CC_MODE (CC_C);
+CC_MODE (CC_N);
diff --git a/contrib/gcc/config/arm/arm-protos.h b/contrib/gcc/config/arm/arm-protos.h
index cae9bea4ce8e..471254efe4e1 100644
--- a/contrib/gcc/config/arm/arm-protos.h
+++ b/contrib/gcc/config/arm/arm-protos.h
@@ -1,220 +1,206 @@
/* Prototypes for exported functions defined in arm.c and pe.c
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Richard Earnshaw (rearnsha@arm.com)
Minor hacks by Nick Clifton (nickc@cygnus.com)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your option)
+ any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#ifndef GCC_ARM_PROTOS_H
#define GCC_ARM_PROTOS_H
-extern void rdata_section PARAMS ((void));
-extern void arm_override_options PARAMS ((void));
-extern int use_return_insn PARAMS ((int));
-extern int arm_regno_class PARAMS ((int));
-extern void arm_finalize_pic PARAMS ((int));
-extern int arm_volatile_func PARAMS ((void));
-extern const char * arm_output_epilogue PARAMS ((int));
-extern void arm_expand_prologue PARAMS ((void));
-extern HOST_WIDE_INT arm_get_frame_size PARAMS ((void));
-/* Used in arm.md, but defined in output.c. */
-extern void assemble_align PARAMS ((int));
-extern const char * arm_strip_name_encoding PARAMS ((const char *));
-extern void arm_asm_output_labelref PARAMS ((FILE *, const char *));
-extern unsigned long arm_current_func_type PARAMS ((void));
-extern unsigned int arm_compute_initial_elimination_offset PARAMS ((unsigned int, unsigned int));
+extern void arm_override_options (void);
+extern int use_return_insn (int, rtx);
+extern int arm_regno_class (int);
+extern void arm_finalize_pic (int);
+extern int arm_volatile_func (void);
+extern const char *arm_output_epilogue (rtx);
+extern void arm_expand_prologue (void);
+extern HOST_WIDE_INT arm_get_frame_size (void);
+extern const char *arm_strip_name_encoding (const char *);
+extern void arm_asm_output_labelref (FILE *, const char *);
+extern unsigned long arm_current_func_type (void);
+extern unsigned int arm_compute_initial_elimination_offset (unsigned int,
+ unsigned int);
#ifdef TREE_CODE
-extern int arm_return_in_memory PARAMS ((tree));
-extern void arm_encode_call_attribute PARAMS ((tree, int));
-extern int arm_function_ok_for_sibcall PARAMS ((tree));
+extern int arm_return_in_memory (tree);
+extern void arm_encode_call_attribute (tree, int);
#endif
#ifdef RTX_CODE
-extern int arm_hard_regno_mode_ok PARAMS ((unsigned int,
- enum machine_mode));
-extern int const_ok_for_arm PARAMS ((HOST_WIDE_INT));
-extern int arm_split_constant PARAMS ((RTX_CODE, enum machine_mode,
- HOST_WIDE_INT, rtx, rtx, int));
-extern RTX_CODE arm_canonicalize_comparison PARAMS ((RTX_CODE, rtx *));
-extern int legitimate_pic_operand_p PARAMS ((rtx));
-extern rtx legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
-extern int arm_rtx_costs PARAMS ((rtx, RTX_CODE, RTX_CODE));
-extern int const_double_rtx_ok_for_fpu PARAMS ((rtx));
-extern int neg_const_double_rtx_ok_for_fpu PARAMS ((rtx));
+extern int arm_hard_regno_mode_ok (unsigned int, enum machine_mode);
+extern int const_ok_for_arm (HOST_WIDE_INT);
+extern int arm_split_constant (RTX_CODE, enum machine_mode, HOST_WIDE_INT, rtx,
+ rtx, int);
+extern RTX_CODE arm_canonicalize_comparison (RTX_CODE, rtx *);
+extern int legitimate_pic_operand_p (rtx);
+extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
+extern int arm_legitimate_address_p (enum machine_mode, rtx, int);
+extern int thumb_legitimate_address_p (enum machine_mode, rtx, int);
+extern int thumb_legitimate_offset_p (enum machine_mode, HOST_WIDE_INT);
+extern rtx arm_legitimize_address (rtx, rtx, enum machine_mode);
+extern int const_double_rtx_ok_for_fpa (rtx);
+extern int neg_const_double_rtx_ok_for_fpa (rtx);
/* Predicates. */
-extern int s_register_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_hard_register_operand PARAMS ((rtx, enum machine_mode));
-extern int f_register_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_int_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_reload_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_rhs_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_rhsm_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_add_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_not_operand PARAMS ((rtx, enum machine_mode));
-extern int offsettable_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int alignable_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int bad_signed_byte_operand PARAMS ((rtx, enum machine_mode));
-extern int fpu_rhs_operand PARAMS ((rtx, enum machine_mode));
-extern int fpu_add_operand PARAMS ((rtx, enum machine_mode));
-extern int power_of_two_operand PARAMS ((rtx, enum machine_mode));
-extern int nonimmediate_di_operand PARAMS ((rtx, enum machine_mode));
-extern int di_operand PARAMS ((rtx, enum machine_mode));
-extern int nonimmediate_soft_df_operand PARAMS ((rtx, enum machine_mode));
-extern int soft_df_operand PARAMS ((rtx, enum machine_mode));
-extern int index_operand PARAMS ((rtx, enum machine_mode));
-extern int const_shift_operand PARAMS ((rtx, enum machine_mode));
-extern int arm_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int shiftable_operator PARAMS ((rtx, enum machine_mode));
-extern int shift_operator PARAMS ((rtx, enum machine_mode));
-extern int equality_operator PARAMS ((rtx, enum machine_mode));
-extern int minmax_operator PARAMS ((rtx, enum machine_mode));
-extern int cc_register PARAMS ((rtx, enum machine_mode));
-extern int dominant_cc_register PARAMS ((rtx, enum machine_mode));
-extern int logical_binary_operator PARAMS ((rtx, enum machine_mode));
-extern int multi_register_push PARAMS ((rtx, enum machine_mode));
-extern int load_multiple_operation PARAMS ((rtx, enum machine_mode));
-extern int store_multiple_operation PARAMS ((rtx, enum machine_mode));
-
-extern int symbol_mentioned_p PARAMS ((rtx));
-extern int label_mentioned_p PARAMS ((rtx));
-extern RTX_CODE minmax_code PARAMS ((rtx));
-extern int adjacent_mem_locations PARAMS ((rtx, rtx));
-extern int load_multiple_sequence PARAMS ((rtx *, int, int *, int *,
- HOST_WIDE_INT *));
-extern const char * emit_ldm_seq PARAMS ((rtx *, int));
-extern int store_multiple_sequence PARAMS ((rtx *, int, int *, int *,
- HOST_WIDE_INT *));
-extern const char * emit_stm_seq PARAMS ((rtx *, int));
-extern rtx arm_gen_load_multiple PARAMS ((int, int, rtx, int, int, int,
- int, int));
-extern rtx arm_gen_store_multiple PARAMS ((int, int, rtx, int, int, int,
- int, int));
-extern int arm_gen_movstrqi PARAMS ((rtx *));
-extern rtx arm_gen_rotated_half_load PARAMS ((rtx));
-extern enum machine_mode arm_select_cc_mode PARAMS ((RTX_CODE, rtx, rtx));
-extern rtx arm_gen_compare_reg PARAMS ((RTX_CODE, rtx, rtx));
-extern rtx arm_gen_return_addr_mask PARAMS ((void));
-extern void arm_reload_in_hi PARAMS ((rtx *));
-extern void arm_reload_out_hi PARAMS ((rtx *));
-extern void arm_reorg PARAMS ((rtx));
-extern const char * fp_immediate_constant PARAMS ((rtx));
-extern const char * output_call PARAMS ((rtx *));
-extern const char * output_call_mem PARAMS ((rtx *));
-extern const char * output_mov_long_double_fpu_from_arm PARAMS ((rtx *));
-extern const char * output_mov_long_double_arm_from_fpu PARAMS ((rtx *));
-extern const char * output_mov_long_double_arm_from_arm PARAMS ((rtx *));
-extern const char * output_mov_double_fpu_from_arm PARAMS ((rtx *));
-extern const char * output_mov_double_arm_from_fpu PARAMS ((rtx *));
-extern const char * output_move_double PARAMS ((rtx *));
-extern const char * output_mov_immediate PARAMS ((rtx *));
-extern const char * output_add_immediate PARAMS ((rtx *));
-extern const char * arithmetic_instr PARAMS ((rtx, int));
-extern void output_ascii_pseudo_op PARAMS ((FILE *, const unsigned char *,
- int));
-extern const char * output_return_instruction PARAMS ((rtx, int, int));
-extern void arm_poke_function_name PARAMS ((FILE *, const char *));
-extern void arm_print_operand PARAMS ((FILE *, rtx, int));
-extern void arm_print_operand_address PARAMS ((FILE *, rtx));
-extern void arm_final_prescan_insn PARAMS ((rtx));
-extern int arm_go_if_legitimate_address PARAMS ((enum machine_mode, rtx));
-extern int arm_debugger_arg_offset PARAMS ((int, rtx));
-extern int arm_is_longcall_p PARAMS ((rtx, int, int));
+extern int s_register_operand (rtx, enum machine_mode);
+extern int arm_hard_register_operand (rtx, enum machine_mode);
+extern int f_register_operand (rtx, enum machine_mode);
+extern int reg_or_int_operand (rtx, enum machine_mode);
+extern int arm_reload_memory_operand (rtx, enum machine_mode);
+extern int arm_rhs_operand (rtx, enum machine_mode);
+extern int arm_rhsm_operand (rtx, enum machine_mode);
+extern int arm_add_operand (rtx, enum machine_mode);
+extern int arm_addimm_operand (rtx, enum machine_mode);
+extern int arm_not_operand (rtx, enum machine_mode);
+extern int offsettable_memory_operand (rtx, enum machine_mode);
+extern int alignable_memory_operand (rtx, enum machine_mode);
+extern int bad_signed_byte_operand (rtx, enum machine_mode);
+extern int fpa_rhs_operand (rtx, enum machine_mode);
+extern int fpa_add_operand (rtx, enum machine_mode);
+extern int power_of_two_operand (rtx, enum machine_mode);
+extern int nonimmediate_di_operand (rtx, enum machine_mode);
+extern int di_operand (rtx, enum machine_mode);
+extern int nonimmediate_soft_df_operand (rtx, enum machine_mode);
+extern int soft_df_operand (rtx, enum machine_mode);
+extern int index_operand (rtx, enum machine_mode);
+extern int const_shift_operand (rtx, enum machine_mode);
+extern int arm_comparison_operator (rtx, enum machine_mode);
+extern int shiftable_operator (rtx, enum machine_mode);
+extern int shift_operator (rtx, enum machine_mode);
+extern int equality_operator (rtx, enum machine_mode);
+extern int minmax_operator (rtx, enum machine_mode);
+extern int cc_register (rtx, enum machine_mode);
+extern int dominant_cc_register (rtx, enum machine_mode);
+extern int logical_binary_operator (rtx, enum machine_mode);
+extern int multi_register_push (rtx, enum machine_mode);
+extern int load_multiple_operation (rtx, enum machine_mode);
+extern int store_multiple_operation (rtx, enum machine_mode);
+extern int cirrus_fp_register (rtx, enum machine_mode);
+extern int cirrus_general_operand (rtx, enum machine_mode);
+extern int cirrus_register_operand (rtx, enum machine_mode);
+extern int cirrus_shift_const (rtx, enum machine_mode);
+extern int cirrus_memory_offset (rtx);
+
+extern int symbol_mentioned_p (rtx);
+extern int label_mentioned_p (rtx);
+extern RTX_CODE minmax_code (rtx);
+extern int adjacent_mem_locations (rtx, rtx);
+extern int load_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);
+extern const char *emit_ldm_seq (rtx *, int);
+extern int store_multiple_sequence (rtx *, int, int *, int *, HOST_WIDE_INT *);
+extern const char * emit_stm_seq (rtx *, int);
+extern rtx arm_gen_load_multiple (int, int, rtx, int, int, int, int, int);
+extern rtx arm_gen_store_multiple (int, int, rtx, int, int, int, int, int);
+extern int arm_gen_movstrqi (rtx *);
+extern rtx arm_gen_rotated_half_load (rtx);
+extern enum machine_mode arm_select_cc_mode (RTX_CODE, rtx, rtx);
+extern enum machine_mode arm_select_dominance_cc_mode (rtx, rtx,
+ HOST_WIDE_INT);
+extern rtx arm_gen_compare_reg (RTX_CODE, rtx, rtx);
+extern rtx arm_gen_return_addr_mask (void);
+extern void arm_reload_in_hi (rtx *);
+extern void arm_reload_out_hi (rtx *);
+extern const char *fp_immediate_constant (rtx);
+extern const char *output_call (rtx *);
+extern const char *output_call_mem (rtx *);
+extern const char *output_mov_long_double_fpa_from_arm (rtx *);
+extern const char *output_mov_long_double_arm_from_fpa (rtx *);
+extern const char *output_mov_long_double_arm_from_arm (rtx *);
+extern const char *output_mov_double_fpa_from_arm (rtx *);
+extern const char *output_mov_double_arm_from_fpa (rtx *);
+extern const char *output_move_double (rtx *);
+extern const char *output_mov_immediate (rtx *);
+extern const char *output_add_immediate (rtx *);
+extern const char *arithmetic_instr (rtx, int);
+extern void output_ascii_pseudo_op (FILE *, const unsigned char *, int);
+extern const char *output_return_instruction (rtx, int, int);
+extern void arm_poke_function_name (FILE *, const char *);
+extern void arm_print_operand (FILE *, rtx, int);
+extern void arm_print_operand_address (FILE *, rtx);
+extern void arm_final_prescan_insn (rtx);
+extern int arm_go_if_legitimate_address (enum machine_mode, rtx);
+extern int arm_debugger_arg_offset (int, rtx);
+extern int arm_is_longcall_p (rtx, int, int);
+extern int arm_emit_vector_const (FILE *, rtx);
+extern const char * arm_output_load_gr (rtx *);
#if defined TREE_CODE
-extern rtx arm_function_arg PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode, tree, int));
-extern void arm_init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx,
- int));
-extern rtx arm_va_arg PARAMS ((tree, tree));
-extern int arm_function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-
+extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
+extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
+extern rtx arm_va_arg (tree, tree);
+extern int arm_function_arg_pass_by_reference (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
#endif
#if defined AOF_ASSEMBLER
-extern rtx aof_pic_entry PARAMS ((rtx));
-extern void aof_dump_pic_table PARAMS ((FILE *));
-extern char * aof_text_section PARAMS ((void));
-extern char * aof_data_section PARAMS ((void));
-extern void aof_add_import PARAMS ((const char *));
-extern void aof_delete_import PARAMS ((const char *));
-extern void aof_dump_imports PARAMS ((FILE *));
-extern void zero_init_section PARAMS ((void));
-extern void common_section PARAMS ((void));
+extern rtx aof_pic_entry (rtx);
+extern char *aof_text_section (void);
+extern char *aof_data_section (void);
+extern void aof_add_import (const char *);
+extern void aof_delete_import (const char *);
+extern void zero_init_section (void);
+extern void common_section (void);
#endif /* AOF_ASSEMBLER */
#endif /* RTX_CODE */
-extern int arm_float_words_big_endian PARAMS ((void));
+extern int arm_float_words_big_endian (void);
/* Thumb functions. */
-extern void arm_init_expanders PARAMS ((void));
-extern int thumb_far_jump_used_p PARAMS ((int));
-extern const char * thumb_unexpanded_epilogue PARAMS ((void));
-extern HOST_WIDE_INT thumb_get_frame_size PARAMS ((void));
-extern void thumb_expand_prologue PARAMS ((void));
-extern void thumb_expand_epilogue PARAMS ((void));
+extern void arm_init_expanders (void);
+extern int thumb_far_jump_used_p (int);
+extern const char *thumb_unexpanded_epilogue (void);
+extern HOST_WIDE_INT thumb_get_frame_size (void);
+extern void thumb_expand_prologue (void);
+extern void thumb_expand_epilogue (void);
#ifdef TREE_CODE
-extern int is_called_in_ARM_mode PARAMS ((tree));
+extern int is_called_in_ARM_mode (tree);
#endif
-extern int thumb_shiftable_const PARAMS ((unsigned HOST_WIDE_INT));
+extern int thumb_shiftable_const (unsigned HOST_WIDE_INT);
#ifdef RTX_CODE
-extern void thumb_final_prescan_insn PARAMS ((rtx));
-extern const char * thumb_load_double_from_address
- PARAMS ((rtx *));
-extern const char * thumb_output_move_mem_multiple
- PARAMS ((int, rtx *));
-extern void thumb_expand_movstrqi PARAMS ((rtx *));
-extern int thumb_cmp_operand PARAMS ((rtx, enum machine_mode));
-extern rtx * thumb_legitimize_pic_address
- PARAMS ((rtx, enum machine_mode, rtx));
-extern int thumb_go_if_legitimate_address
- PARAMS ((enum machine_mode, rtx));
-extern rtx arm_return_addr PARAMS ((int, rtx));
-extern void thumb_reload_out_hi PARAMS ((rtx *));
-extern void thumb_reload_in_hi PARAMS ((rtx *));
+extern void thumb_final_prescan_insn (rtx);
+extern const char *thumb_load_double_from_address (rtx *);
+extern const char *thumb_output_move_mem_multiple (int, rtx *);
+extern void thumb_expand_movstrqi (rtx *);
+extern int thumb_cmp_operand (rtx, enum machine_mode);
+extern int thumb_cbrch_target_operand (rtx, enum machine_mode);
+extern rtx *thumb_legitimize_pic_address (rtx, enum machine_mode, rtx);
+extern int thumb_go_if_legitimate_address (enum machine_mode, rtx);
+extern rtx arm_return_addr (int, rtx);
+extern void thumb_reload_out_hi (rtx *);
+extern void thumb_reload_in_hi (rtx *);
#endif
/* Defined in pe.c. */
-extern int arm_dllexport_name_p PARAMS ((const char *));
-extern int arm_dllimport_name_p PARAMS ((const char *));
+extern int arm_dllexport_name_p (const char *);
+extern int arm_dllimport_name_p (const char *);
#ifdef TREE_CODE
-extern void arm_pe_unique_section PARAMS ((tree, int));
-extern void arm_pe_encode_section_info PARAMS ((tree, int));
-extern int arm_dllexport_p PARAMS ((tree));
-extern int arm_dllimport_p PARAMS ((tree));
-extern void arm_mark_dllexport PARAMS ((tree));
-extern void arm_mark_dllimport PARAMS ((tree));
-#endif
-
-extern void arm_init_builtins PARAMS ((void));
-#if defined (TREE_CODE) && defined (RTX_CODE)
-extern rtx arm_expand_builtin PARAMS ((tree, rtx, rtx,
- enum machine_mode, int));
+extern void arm_pe_unique_section (tree, int);
+extern void arm_pe_encode_section_info (tree, rtx, int);
+extern int arm_dllexport_p (tree);
+extern int arm_dllimport_p (tree);
+extern void arm_mark_dllexport (tree);
+extern void arm_mark_dllimport (tree);
#endif
-#ifdef GCC_C_PRAGMA_H /* included from code that cares about pragmas */
-extern void arm_pr_long_calls PARAMS ((cpp_reader *));
-extern void arm_pr_no_long_calls PARAMS ((cpp_reader *));
-extern void arm_pr_long_calls_off PARAMS ((cpp_reader *));
-#endif
+extern void arm_pr_long_calls (struct cpp_reader *);
+extern void arm_pr_no_long_calls (struct cpp_reader *);
+extern void arm_pr_long_calls_off (struct cpp_reader *);
#endif /* ! GCC_ARM_PROTOS_H */
diff --git a/contrib/gcc/config/arm/arm.c b/contrib/gcc/config/arm/arm.c
index 7422f1d03aff..91e4486d0bbb 100644
--- a/contrib/gcc/config/arm/arm.c
+++ b/contrib/gcc/config/arm/arm.c
@@ -1,29 +1,31 @@
/* Output routines for GCC for ARM.
- Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
- Free Software Foundation, Inc.
+ Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk).
More major hacks by Richard Earnshaw (rearnsha@arm.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "obstack.h"
@@ -48,91 +50,107 @@ Boston, MA 02111-1307, USA. */
#include "tm_p.h"
#include "target.h"
#include "target-def.h"
+#include "debug.h"
/* Forward definitions of types. */
typedef struct minipool_node Mnode;
typedef struct minipool_fixup Mfix;
-/* In order to improve the layout of the prototypes below
- some short type abbreviations are defined here. */
-#define Hint HOST_WIDE_INT
-#define Mmode enum machine_mode
-#define Ulong unsigned long
-#define Ccstar const char *
-
const struct attribute_spec arm_attribute_table[];
/* Forward function declarations. */
-static void arm_add_gc_roots PARAMS ((void));
-static int arm_gen_constant PARAMS ((enum rtx_code, Mmode, Hint, rtx, rtx, int, int));
-static unsigned bit_count PARAMS ((Ulong));
-static int const_ok_for_op PARAMS ((Hint, enum rtx_code));
-static rtx emit_multi_reg_push PARAMS ((int));
-static rtx emit_sfm PARAMS ((int, int));
+static void arm_add_gc_roots (void);
+static int arm_gen_constant (enum rtx_code, enum machine_mode, HOST_WIDE_INT,
+ rtx, rtx, int, int);
+static unsigned bit_count (unsigned long);
+static int arm_address_register_rtx_p (rtx, int);
+static int arm_legitimate_index_p (enum machine_mode, rtx, int);
+static int thumb_base_register_rtx_p (rtx, enum machine_mode, int);
+inline static int thumb_index_register_rtx_p (rtx, int);
+static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
+static rtx emit_multi_reg_push (int);
+static rtx emit_sfm (int, int);
#ifndef AOF_ASSEMBLER
-static bool arm_assemble_integer PARAMS ((rtx, unsigned int, int));
+static bool arm_assemble_integer (rtx, unsigned int, int);
#endif
-static Ccstar fp_const_from_val PARAMS ((REAL_VALUE_TYPE *));
-static arm_cc get_arm_condition_code PARAMS ((rtx));
-static void init_fpa_table PARAMS ((void));
-static Hint int_log2 PARAMS ((Hint));
-static rtx is_jump_table PARAMS ((rtx));
-static Ccstar output_multi_immediate PARAMS ((rtx *, Ccstar, Ccstar, int, Hint));
-static void print_multi_reg PARAMS ((FILE *, Ccstar, int, int));
-static Mmode select_dominance_cc_mode PARAMS ((rtx, rtx, Hint));
-static Ccstar shift_op PARAMS ((rtx, Hint *));
-static struct machine_function * arm_init_machine_status PARAMS ((void));
-static int number_of_first_bit_set PARAMS ((int));
-static void replace_symbols_in_block PARAMS ((tree, rtx, rtx));
-static void thumb_exit PARAMS ((FILE *, int, rtx));
-static void thumb_pushpop PARAMS ((FILE *, int, int));
-static Ccstar thumb_condition_code PARAMS ((rtx, int));
-static rtx is_jump_table PARAMS ((rtx));
-static Hint get_jump_table_size PARAMS ((rtx));
-static Mnode * move_minipool_fix_forward_ref PARAMS ((Mnode *, Mnode *, Hint));
-static Mnode * add_minipool_forward_ref PARAMS ((Mfix *));
-static Mnode * move_minipool_fix_backward_ref PARAMS ((Mnode *, Mnode *, Hint));
-static Mnode * add_minipool_backward_ref PARAMS ((Mfix *));
-static void assign_minipool_offsets PARAMS ((Mfix *));
-static void arm_print_value PARAMS ((FILE *, rtx));
-static void dump_minipool PARAMS ((rtx));
-static int arm_barrier_cost PARAMS ((rtx));
-static Mfix * create_fix_barrier PARAMS ((Mfix *, Hint));
-static void push_minipool_barrier PARAMS ((rtx, Hint));
-static void push_minipool_fix PARAMS ((rtx, Hint, rtx *, Mmode, rtx));
-static void note_invalid_constants PARAMS ((rtx, Hint));
-static int current_file_function_operand PARAMS ((rtx));
-static Ulong arm_compute_save_reg0_reg12_mask PARAMS ((void));
-static Ulong arm_compute_save_reg_mask PARAMS ((void));
-static Ulong arm_isr_value PARAMS ((tree));
-static Ulong arm_compute_func_type PARAMS ((void));
-static tree arm_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
-static tree arm_handle_isr_attribute PARAMS ((tree *, tree, tree, int, bool *));
-static void arm_output_function_epilogue PARAMS ((FILE *, Hint));
-static void arm_output_function_prologue PARAMS ((FILE *, Hint));
-static void thumb_output_function_prologue PARAMS ((FILE *, Hint));
-static int arm_comp_type_attributes PARAMS ((tree, tree));
-static void arm_set_default_type_attributes PARAMS ((tree));
-static int arm_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static int count_insns_for_constant PARAMS ((HOST_WIDE_INT, int));
-static int arm_get_strip_length PARAMS ((int));
+static const char *fp_const_from_val (REAL_VALUE_TYPE *);
+static arm_cc get_arm_condition_code (rtx);
+static void init_fpa_table (void);
+static HOST_WIDE_INT int_log2 (HOST_WIDE_INT);
+static rtx is_jump_table (rtx);
+static const char *output_multi_immediate (rtx *, const char *, const char *,
+ int, HOST_WIDE_INT);
+static void print_multi_reg (FILE *, const char *, int, int);
+static const char *shift_op (rtx, HOST_WIDE_INT *);
+static struct machine_function *arm_init_machine_status (void);
+static int number_of_first_bit_set (int);
+static void replace_symbols_in_block (tree, rtx, rtx);
+static void thumb_exit (FILE *, int, rtx);
+static void thumb_pushpop (FILE *, int, int, int *, int);
+static rtx is_jump_table (rtx);
+static HOST_WIDE_INT get_jump_table_size (rtx);
+static Mnode *move_minipool_fix_forward_ref (Mnode *, Mnode *, HOST_WIDE_INT);
+static Mnode *add_minipool_forward_ref (Mfix *);
+static Mnode *move_minipool_fix_backward_ref (Mnode *, Mnode *, HOST_WIDE_INT);
+static Mnode *add_minipool_backward_ref (Mfix *);
+static void assign_minipool_offsets (Mfix *);
+static void arm_print_value (FILE *, rtx);
+static void dump_minipool (rtx);
+static int arm_barrier_cost (rtx);
+static Mfix *create_fix_barrier (Mfix *, HOST_WIDE_INT);
+static void push_minipool_barrier (rtx, HOST_WIDE_INT);
+static void push_minipool_fix (rtx, HOST_WIDE_INT, rtx *, enum machine_mode,
+ rtx);
+static void arm_reorg (void);
+static bool note_invalid_constants (rtx, HOST_WIDE_INT, int);
+static int current_file_function_operand (rtx);
+static unsigned long arm_compute_save_reg0_reg12_mask (void);
+static unsigned long arm_compute_save_reg_mask (void);
+static unsigned long arm_isr_value (tree);
+static unsigned long arm_compute_func_type (void);
+static tree arm_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
+static tree arm_handle_isr_attribute (tree *, tree, tree, int, bool *);
+static void arm_output_function_epilogue (FILE *, HOST_WIDE_INT);
+static void arm_output_function_prologue (FILE *, HOST_WIDE_INT);
+static void thumb_output_function_prologue (FILE *, HOST_WIDE_INT);
+static int arm_comp_type_attributes (tree, tree);
+static void arm_set_default_type_attributes (tree);
+static int arm_adjust_cost (rtx, rtx, rtx, int);
+static int arm_use_dfa_pipeline_interface (void);
+static int count_insns_for_constant (HOST_WIDE_INT, int);
+static int arm_get_strip_length (int);
+static bool arm_function_ok_for_sibcall (tree, tree);
+static void arm_internal_label (FILE *, const char *, unsigned long);
+static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
+ tree);
+static int arm_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code);
+static bool arm_rtx_costs (rtx, int, int, int *);
+static int arm_address_cost (rtx);
+static bool arm_memory_load_p (rtx);
+static bool arm_cirrus_insn_p (rtx);
+static void cirrus_reorg (rtx);
+static void arm_init_builtins (void);
+static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+static void arm_init_iwmmxt_builtins (void);
+static rtx safe_vector_operand (rtx, enum machine_mode);
+static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx);
+static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int);
+static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+
#ifdef OBJECT_FORMAT_ELF
-static void arm_elf_asm_named_section PARAMS ((const char *, unsigned int));
+static void arm_elf_asm_named_section (const char *, unsigned int);
#endif
#ifndef ARM_PE
-static void arm_encode_section_info PARAMS ((tree, int));
+static void arm_encode_section_info (tree, rtx, int);
#endif
#ifdef AOF_ASSEMBLER
-static void aof_globalize_label PARAMS ((FILE *, const char *));
+static void aof_globalize_label (FILE *, const char *);
+static void aof_dump_imports (FILE *);
+static void aof_dump_pic_table (FILE *);
+static void aof_file_start (void);
+static void aof_file_end (void);
#endif
-static void arm_output_mi_thunk PARAMS ((FILE *, tree,
- HOST_WIDE_INT,
- HOST_WIDE_INT, tree));
-
-#undef Hint
-#undef Mmode
-#undef Ulong
-#undef Ccstar
+
/* Initialize the GCC target structure. */
#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
@@ -152,6 +170,10 @@ static void arm_output_mi_thunk PARAMS ((FILE *, tree,
#define TARGET_ASM_ALIGNED_SI_OP "\tDCD\t"
#undef TARGET_ASM_GLOBALIZE_LABEL
#define TARGET_ASM_GLOBALIZE_LABEL aof_globalize_label
+#undef TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START aof_file_start
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END aof_file_end
#else
#undef TARGET_ASM_ALIGNED_SI_OP
#define TARGET_ASM_ALIGNED_SI_OP NULL
@@ -171,15 +193,12 @@ static void arm_output_mi_thunk PARAMS ((FILE *, tree,
#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES arm_set_default_type_attributes
-#undef TARGET_INIT_BUILTINS
-#define TARGET_INIT_BUILTINS arm_init_builtins
-
-#undef TARGET_EXPAND_BUILTIN
-#define TARGET_EXPAND_BUILTIN arm_expand_builtin
-
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE arm_use_dfa_pipeline_interface
+
#undef TARGET_ENCODE_SECTION_INFO
#ifdef ARM_PE
#define TARGET_ENCODE_SECTION_INFO arm_pe_encode_section_info
@@ -187,14 +206,33 @@ static void arm_output_mi_thunk PARAMS ((FILE *, tree,
#define TARGET_ENCODE_SECTION_INFO arm_encode_section_info
#endif
-#undef TARGET_STRIP_NAME_ENCODING
+#undef TARGET_STRIP_NAME_ENCODING
#define TARGET_STRIP_NAME_ENCODING arm_strip_name_encoding
-#undef TARGET_ASM_OUTPUT_MI_THUNK
+#undef TARGET_ASM_INTERNAL_LABEL
+#define TARGET_ASM_INTERNAL_LABEL arm_internal_label
+
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL arm_function_ok_for_sibcall
+
+#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK arm_output_mi_thunk
-#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
+#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS arm_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST arm_address_cost
+
+#undef TARGET_MACHINE_DEPENDENT_REORG
+#define TARGET_MACHINE_DEPENDENT_REORG arm_reorg
+
+#undef TARGET_INIT_BUILTINS
+#define TARGET_INIT_BUILTINS arm_init_builtins
+#undef TARGET_EXPAND_BUILTIN
+#define TARGET_EXPAND_BUILTIN arm_expand_builtin
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Obstack for minipool constant handling. */
@@ -215,10 +253,10 @@ int making_const_table;
rtx arm_compare_op0, arm_compare_op1;
/* What type of floating point are we tuning for? */
-enum floating_point_type arm_fpu;
+enum fputype arm_fpu_tune;
/* What type of floating point instructions are available? */
-enum floating_point_type arm_fpu_arch;
+enum fputype arm_fpu_arch;
/* What program mode is the cpu running in? 26-bit mode or 32-bit mode. */
enum prog_mode_type arm_prgmode;
@@ -240,8 +278,13 @@ int arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY;
#define FL_THUMB (1 << 6) /* Thumb aware */
#define FL_LDSCHED (1 << 7) /* Load scheduling necessary */
#define FL_STRONG (1 << 8) /* StrongARM */
-#define FL_ARCH5E (1 << 9) /* DSP extenstions to v5 */
+#define FL_ARCH5E (1 << 9) /* DSP extensions to v5 */
#define FL_XSCALE (1 << 10) /* XScale */
+#define FL_CIRRUS (1 << 11) /* Cirrus/DSP. */
+#define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */
+#define FL_ARCH6J (1 << 12) /* Architecture rel 6. Adds
+ media instructions. */
+#define FL_VFPV2 (1 << 13) /* Vector Floating Point V2. */
/* The bits in this mask specify which
instructions we are allowed to generate. */
@@ -274,12 +317,21 @@ int arm_ld_sched = 0;
/* Nonzero if this chip is a StrongARM. */
int arm_is_strong = 0;
+/* Nonzero if this chip supports Intel Wireless MMX technology. */
+int arm_arch_iwmmxt = 0;
+
/* Nonzero if this chip is an XScale. */
-int arm_is_xscale = 0;
+int arm_arch_xscale = 0;
+
+/* Nonzero if tuning for XScale */
+int arm_tune_xscale = 0;
/* Nonzero if this chip is an ARM6 or an ARM7. */
int arm_is_6_or_7 = 0;
+/* Nonzero if this chip is a Cirrus/DSP. */
+int arm_is_cirrus = 0;
+
/* Nonzero if generating Thumb instructions. */
int thumb_code = 0;
@@ -352,16 +404,17 @@ static const struct processors all_cores[] =
{"arm700", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm700i", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
{"arm710", FL_MODE26 | FL_MODE32 },
- {"arm710t", FL_MODE26 | FL_MODE32 | FL_THUMB },
{"arm720", FL_MODE26 | FL_MODE32 },
- {"arm720t", FL_MODE26 | FL_MODE32 | FL_THUMB },
- {"arm740t", FL_MODE26 | FL_MODE32 | FL_THUMB },
{"arm710c", FL_MODE26 | FL_MODE32 },
{"arm7100", FL_MODE26 | FL_MODE32 },
{"arm7500", FL_MODE26 | FL_MODE32 },
- /* Doesn't have an external co-proc, but does have embedded fpu. */
+ /* Doesn't have an external co-proc, but does have embedded fpa. */
{"arm7500fe", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
+ /* V4 Architecture Processors */
{"arm7tdmi", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
+ {"arm710t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
+ {"arm720t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
+ {"arm740t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
{"arm8", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
{"arm810", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
{"arm9", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
@@ -370,14 +423,21 @@ static const struct processors all_cores[] =
{"arm940t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
{"arm9tdmi", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
{"arm9e", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
+ {"ep9312", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_CIRRUS },
{"strongarm", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
{"strongarm110", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
{"strongarm1100", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
{"strongarm1110", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
+ /* V5 Architecture Processors */
{"arm10tdmi", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_ARCH5 },
{"arm1020t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_ARCH5 },
+ {"arm926ejs", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E },
+ {"arm1026ejs", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E },
{"xscale", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE },
-
+ {"iwmmxt", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE | FL_IWMMXT },
+ /* V6 Architecture Processors */
+ {"arm1136js", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6J },
+ {"arm1136jfs", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6J | FL_VFPV2 },
{NULL, 0}
};
@@ -396,10 +456,13 @@ static const struct processors all_architectures[] =
{ "armv5", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 },
{ "armv5t", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 },
{ "armv5te", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E },
+ { "armv6j", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6J },
+ { "ep9312", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_CIRRUS },
+ {"iwmmxt", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE | FL_IWMMXT },
{ NULL, 0 }
};
-/* This is a magic stucture. The 'string' field is magically filled in
+/* This is a magic structure. The 'string' field is magically filled in
with a pointer to the value specified by the user on the command line
assuming that the user has specified such a value. */
@@ -413,8 +476,7 @@ struct arm_cpu_select arm_select[] =
/* Return the number of bits set in VALUE. */
static unsigned
-bit_count (value)
- unsigned long value;
+bit_count (unsigned long value)
{
unsigned long count = 0;
@@ -430,7 +492,7 @@ bit_count (value)
/* Fix up any incompatible options that the user has specified.
This has now turned into a maze. */
void
-arm_override_options ()
+arm_override_options (void)
{
unsigned i;
@@ -493,6 +555,12 @@ arm_override_options ()
{ TARGET_CPU_arm9, "arm9" },
{ TARGET_CPU_strongarm, "strongarm" },
{ TARGET_CPU_xscale, "xscale" },
+ { TARGET_CPU_ep9312, "ep9312" },
+ { TARGET_CPU_iwmmxt, "iwmmxt" },
+ { TARGET_CPU_arm926ej_s, "arm926ej-s" },
+ { TARGET_CPU_arm1026ej_s, "arm1026ej-s" },
+ { TARGET_CPU_arm1136j_s, "arm1136j_s" },
+ { TARGET_CPU_arm1136jf_s, "arm1136jf_s" },
{ TARGET_CPU_generic, "arm" },
{ 0, 0 }
};
@@ -622,6 +690,9 @@ arm_override_options ()
target_flags &= ~ARM_FLAG_THUMB;
}
+ if (!TARGET_APCS_32)
+ inform ("future releases of GCC will not support -mapcs-26");
+
if (TARGET_APCS_FRAME && TARGET_THUMB)
{
/* warning ("ignoring -mapcs-frame because -mthumb was used"); */
@@ -684,40 +755,62 @@ arm_override_options ()
arm_arch4 = (insn_flags & FL_ARCH4) != 0;
arm_arch5 = (insn_flags & FL_ARCH5) != 0;
arm_arch5e = (insn_flags & FL_ARCH5E) != 0;
- arm_is_xscale = (insn_flags & FL_XSCALE) != 0;
+ arm_arch_xscale = (insn_flags & FL_XSCALE) != 0;
arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
arm_is_strong = (tune_flags & FL_STRONG) != 0;
thumb_code = (TARGET_ARM == 0);
arm_is_6_or_7 = (((tune_flags & (FL_MODE26 | FL_MODE32))
&& !(tune_flags & FL_ARCH4))) != 0;
+ arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
+ arm_is_cirrus = (tune_flags & FL_CIRRUS) != 0;
+ arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
- /* Default value for floating point code... if no co-processor
- bus, then schedule for emulated floating point. Otherwise,
- assume the user has an FPA.
- Note: this does not prevent use of floating point instructions,
- -msoft-float does that. */
- arm_fpu = (tune_flags & FL_CO_PROC) ? FP_HARD : FP_SOFT3;
+ if (TARGET_IWMMXT && (! TARGET_ATPCS))
+ target_flags |= ARM_FLAG_ATPCS;
+
+ if (arm_is_cirrus)
+ {
+ arm_fpu_tune = FPUTYPE_MAVERICK;
+
+ /* Ignore -mhard-float if -mcpu=ep9312. */
+ if (TARGET_HARD_FLOAT)
+ target_flags ^= ARM_FLAG_SOFT_FLOAT;
+ }
+ else
+ /* Default value for floating point code... if no co-processor
+ bus, then schedule for emulated floating point. Otherwise,
+ assume the user has an FPA.
+ Note: this does not prevent use of floating point instructions,
+ -msoft-float does that. */
+ arm_fpu_tune = (tune_flags & FL_CO_PROC) ? FPUTYPE_FPA : FPUTYPE_FPA_EMU3;
if (target_fp_name)
{
if (streq (target_fp_name, "2"))
- arm_fpu_arch = FP_SOFT2;
+ arm_fpu_arch = FPUTYPE_FPA_EMU2;
else if (streq (target_fp_name, "3"))
- arm_fpu_arch = FP_SOFT3;
+ arm_fpu_arch = FPUTYPE_FPA_EMU3;
else
error ("invalid floating point emulation option: -mfpe-%s",
target_fp_name);
}
else
- arm_fpu_arch = FP_DEFAULT;
+ arm_fpu_arch = FPUTYPE_DEFAULT;
- if (TARGET_FPE && arm_fpu != FP_HARD)
- arm_fpu = FP_SOFT2;
+ if (TARGET_FPE)
+ {
+ if (arm_fpu_tune == FPUTYPE_FPA_EMU3)
+ arm_fpu_tune = FPUTYPE_FPA_EMU2;
+ else if (arm_fpu_tune == FPUTYPE_MAVERICK)
+ warning ("-mfpe switch not supported by ep9312 target cpu - ignored.");
+ else if (arm_fpu_tune != FPUTYPE_FPA)
+ arm_fpu_tune = FPUTYPE_FPA_EMU2;
+ }
/* For arm2/3 there is no need to do any scheduling if there is only
a floating point emulator, or we are doing software floating-point. */
- if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD)
+ if ((TARGET_SOFT_FLOAT || arm_fpu_tune != FPUTYPE_FPA)
&& (tune_flags & FL_MODE32) == 0)
flag_schedule_insns = flag_schedule_insns_after_reload = 0;
@@ -756,30 +849,44 @@ arm_override_options ()
flag_schedule_insns = 0;
}
- /* If optimizing for space, don't synthesize constants.
- For processors with load scheduling, it never costs more than 2 cycles
- to load a constant, and the load scheduler may well reduce that to 1. */
- if (optimize_size || (tune_flags & FL_LDSCHED))
- arm_constant_limit = 1;
-
- if (arm_is_xscale)
- arm_constant_limit = 2;
-
- /* If optimizing for size, bump the number of instructions that we
- are prepared to conditionally execute (even on a StrongARM).
- Otherwise for the StrongARM, which has early execution of branches,
- a sequence that is worth skipping is shorter. */
if (optimize_size)
- max_insns_skipped = 6;
- else if (arm_is_strong)
- max_insns_skipped = 3;
+ {
+ /* There's some dispute as to whether this should be 1 or 2. However,
+ experiments seem to show that in pathological cases a setting of
+ 1 degrades less severely than a setting of 2. This could change if
+ other parts of the compiler change their behavior. */
+ arm_constant_limit = 1;
+
+ /* If optimizing for size, bump the number of instructions that we
+ are prepared to conditionally execute (even on a StrongARM). */
+ max_insns_skipped = 6;
+ }
+ else
+ {
+ /* For processors with load scheduling, it never costs more than
+ 2 cycles to load a constant, and the load scheduler may well
+ reduce that to 1. */
+ if (tune_flags & FL_LDSCHED)
+ arm_constant_limit = 1;
+
+ /* On XScale the longer latency of a load makes it more difficult
+ to achieve a good schedule, so it's faster to synthesize
+ constants that can be done in two insns. */
+ if (arm_tune_xscale)
+ arm_constant_limit = 2;
+
+ /* StrongARM has early execution of branches, so a sequence
+ that is worth skipping is shorter. */
+ if (arm_is_strong)
+ max_insns_skipped = 3;
+ }
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
}
static void
-arm_add_gc_roots ()
+arm_add_gc_roots (void)
{
gcc_obstack_init(&minipool_obstack);
minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0);
@@ -816,8 +923,7 @@ static const isr_attribute_arg isr_attribute_args [] =
function, or ARM_FT_UNKNOWN if the type cannot be determined. */
static unsigned long
-arm_isr_value (argument)
- tree argument;
+arm_isr_value (tree argument)
{
const isr_attribute_arg * ptr;
const char * arg;
@@ -834,7 +940,7 @@ arm_isr_value (argument)
arg = TREE_STRING_POINTER (TREE_VALUE (argument));
/* Check it against the list of known arguments. */
- for (ptr = isr_attribute_args; ptr->arg != NULL; ptr ++)
+ for (ptr = isr_attribute_args; ptr->arg != NULL; ptr++)
if (streq (arg, ptr->arg))
return ptr->return_value;
@@ -845,7 +951,7 @@ arm_isr_value (argument)
/* Computes the type of the current function. */
static unsigned long
-arm_compute_func_type ()
+arm_compute_func_type (void)
{
unsigned long type = ARM_FT_UNKNOWN;
tree a;
@@ -892,7 +998,7 @@ arm_compute_func_type ()
/* Returns the type of the current function. */
unsigned long
-arm_current_func_type ()
+arm_current_func_type (void)
{
if (ARM_FUNC_TYPE (cfun->machine->func_type) == ARM_FT_UNKNOWN)
cfun->machine->func_type = arm_compute_func_type ();
@@ -900,20 +1006,22 @@ arm_current_func_type ()
return cfun->machine->func_type;
}
-/* Return 1 if it is possible to return using a single instruction. */
+/* Return 1 if it is possible to return using a single instruction.
+ If SIBLING is non-null, this is a test for a return before a sibling
+ call. SIBLING is the call insn, so we can examine its register usage. */
int
-use_return_insn (iscond)
- int iscond;
+use_return_insn (int iscond, rtx sibling)
{
int regno;
unsigned int func_type;
unsigned long saved_int_regs;
+ unsigned HOST_WIDE_INT stack_adjust;
/* Never use a return instruction before reload has run. */
if (!reload_completed)
return 0;
-
+
func_type = arm_current_func_type ();
/* Naked functions and volatile functions need special
@@ -924,19 +1032,61 @@ use_return_insn (iscond)
/* So do interrupt functions that use the frame pointer. */
if (IS_INTERRUPT (func_type) && frame_pointer_needed)
return 0;
-
+
+ stack_adjust = arm_get_frame_size () + current_function_outgoing_args_size;
+
/* As do variadic functions. */
if (current_function_pretend_args_size
|| cfun->machine->uses_anonymous_args
- /* Of if the function calls __builtin_eh_return () */
+ /* Or if the function calls __builtin_eh_return () */
|| ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER
- /* Or if there is no frame pointer and there is a stack adjustment. */
- || ((arm_get_frame_size () + current_function_outgoing_args_size != 0)
- && !frame_pointer_needed))
+ /* Or if the function calls alloca */
+ || current_function_calls_alloca
+ /* Or if there is a stack adjustment. However, if the stack pointer
+ is saved on the stack, we can use a pre-incrementing stack load. */
+ || !(stack_adjust == 0 || (frame_pointer_needed && stack_adjust == 4)))
return 0;
saved_int_regs = arm_compute_save_reg_mask ();
+ /* Unfortunately, the insn
+
+ ldmib sp, {..., sp, ...}
+
+ triggers a bug on most SA-110 based devices, such that the stack
+ pointer won't be correctly restored if the instruction takes a
+ page fault. We work around this problem by popping r3 along with
+ the other registers, since that is never slower than executing
+ another instruction.
+
+ We test for !arm_arch5 here, because code for any architecture
+ less than this could potentially be run on one of the buggy
+ chips. */
+ if (stack_adjust == 4 && !arm_arch5)
+ {
+ /* Validate that r3 is a call-clobbered register (always true in
+ the default abi) ... */
+ if (!call_used_regs[3])
+ return 0;
+
+ /* ... that it isn't being used for a return value (always true
+ until we implement return-in-regs), or for a tail-call
+ argument ... */
+ if (sibling)
+ {
+ if (GET_CODE (sibling) != CALL_INSN)
+ abort ();
+
+ if (find_regno_fusage (sibling, USE, 3))
+ return 0;
+ }
+
+ /* ... and that there are no call-saved registers in r0-r2
+ (always true in the default ABI). */
+ if (saved_int_regs & 0x7)
+ return 0;
+ }
+
/* Can't be done if interworking with Thumb, and any registers have been
stacked. */
if (TARGET_INTERWORK && saved_int_regs != 0)
@@ -960,21 +1110,25 @@ use_return_insn (iscond)
if (saved_int_regs && !(saved_int_regs & (1 << LR_REGNUM)))
return 0;
- /* Can't be done if any of the FPU regs are pushed,
+ /* Can't be done if any of the FPA regs are pushed,
since this also requires an insn. */
if (TARGET_HARD_FLOAT)
for (regno = FIRST_ARM_FP_REGNUM; regno <= LAST_ARM_FP_REGNUM; regno++)
if (regs_ever_live[regno] && !call_used_regs[regno])
return 0;
+ if (TARGET_REALLY_IWMMXT)
+ for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++)
+ if (regs_ever_live[regno] && ! call_used_regs [regno])
+ return 0;
+
return 1;
}
/* Return TRUE if int I is a valid immediate ARM constant. */
int
-const_ok_for_arm (i)
- HOST_WIDE_INT i;
+const_ok_for_arm (HOST_WIDE_INT i)
{
unsigned HOST_WIDE_INT mask = ~(unsigned HOST_WIDE_INT)0xFF;
@@ -1005,9 +1159,7 @@ const_ok_for_arm (i)
/* Return true if I is a valid constant for the operation CODE. */
static int
-const_ok_for_op (i, code)
- HOST_WIDE_INT i;
- enum rtx_code code;
+const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
{
if (const_ok_for_arm (i))
return 1;
@@ -1041,13 +1193,8 @@ const_ok_for_op (i, code)
Return value is the number of insns emitted. */
int
-arm_split_constant (code, mode, val, target, source, subtargets)
- enum rtx_code code;
- enum machine_mode mode;
- HOST_WIDE_INT val;
- rtx target;
- rtx source;
- int subtargets;
+arm_split_constant (enum rtx_code code, enum machine_mode mode,
+ HOST_WIDE_INT val, rtx target, rtx source, int subtargets)
{
if (subtargets || code == SET
|| (GET_CODE (target) == REG && GET_CODE (source) == REG
@@ -1095,9 +1242,7 @@ arm_split_constant (code, mode, val, target, source, subtargets)
}
static int
-count_insns_for_constant (remainder, i)
- HOST_WIDE_INT remainder;
- int i;
+count_insns_for_constant (HOST_WIDE_INT remainder, int i)
{
HOST_WIDE_INT temp1;
int num_insns = 0;
@@ -1127,14 +1272,9 @@ count_insns_for_constant (remainder, i)
RTL generation. */
static int
-arm_gen_constant (code, mode, val, target, source, subtargets, generate)
- enum rtx_code code;
- enum machine_mode mode;
- HOST_WIDE_INT val;
- rtx target;
- rtx source;
- int subtargets;
- int generate;
+arm_gen_constant (enum rtx_code code, enum machine_mode mode,
+ HOST_WIDE_INT val, rtx target, rtx source, int subtargets,
+ int generate)
{
int can_invert = 0;
int can_negate = 0;
@@ -1709,9 +1849,7 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
immediate value easier to load. */
enum rtx_code
-arm_canonicalize_comparison (code, op1)
- enum rtx_code code;
- rtx * op1;
+arm_canonicalize_comparison (enum rtx_code code, rtx * op1)
{
unsigned HOST_WIDE_INT i = INTVAL (*op1);
@@ -1771,10 +1909,8 @@ arm_canonicalize_comparison (code, op1)
/* Decide whether a type should be returned in memory (true)
or in a register (false). This is called by the macro
RETURN_IN_MEMORY. */
-
int
-arm_return_in_memory (type)
- tree type;
+arm_return_in_memory (tree type)
{
HOST_WIDE_INT size;
@@ -1791,12 +1927,12 @@ arm_return_in_memory (type)
return (size < 0 || size > UNITS_PER_WORD);
}
- /* For the arm-wince targets we choose to be compitable with Microsoft's
+ /* For the arm-wince targets we choose to be compatible with Microsoft's
ARM and Thumb compilers, which always return aggregates in memory. */
#ifndef ARM_WINCE
/* All structures/unions bigger than one word are returned in memory.
Also catch the case where int_size_in_bytes returns -1. In this case
- the aggregate is either huge or of varaible size, and in either case
+ the aggregate is either huge or of variable size, and in either case
we will want to return it via memory and not in a register. */
if (size < 0 || size > UNITS_PER_WORD)
return 1;
@@ -1876,11 +2012,13 @@ arm_return_in_memory (type)
return 1;
}
-/* Indicate whether or not words of a double are in big-endian order. */
+/* Indicate whether or not words of a double are in big-endian order. */
int
-arm_float_words_big_endian ()
+arm_float_words_big_endian (void)
{
+ if (TARGET_CIRRUS)
+ return 0;
/* For FPA, float words are always big-endian. For VFP, floats words
follow the memory system mode. */
@@ -1901,14 +2039,13 @@ arm_float_words_big_endian ()
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is NULL. */
void
-arm_init_cumulative_args (pcum, fntype, libname, indirect)
- CUMULATIVE_ARGS * pcum;
- tree fntype;
- rtx libname ATTRIBUTE_UNUSED;
- int indirect ATTRIBUTE_UNUSED;
+arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
+ rtx libname ATTRIBUTE_UNUSED,
+ tree fndecl ATTRIBUTE_UNUSED)
{
/* On the ARM, the offset starts at 0. */
- pcum->nregs = ((fntype && aggregate_value_p (TREE_TYPE (fntype))) ? 1 : 0);
+ pcum->nregs = ((fntype && aggregate_value_p (TREE_TYPE (fntype), fntype)) ? 1 : 0);
+ pcum->iwmmxt_nregs = 0;
pcum->call_cookie = CALL_NORMAL;
@@ -1924,6 +2061,24 @@ arm_init_cumulative_args (pcum, fntype, libname, indirect)
else if (lookup_attribute ("long_call", TYPE_ATTRIBUTES (fntype)))
pcum->call_cookie = CALL_LONG;
}
+
+ /* Varargs vectors are treated the same as long long.
+ named_count avoids having to change the way arm handles 'named' */
+ pcum->named_count = 0;
+ pcum->nargs = 0;
+
+ if (TARGET_REALLY_IWMMXT && fntype)
+ {
+ tree fn_arg;
+
+ for (fn_arg = TYPE_ARG_TYPES (fntype);
+ fn_arg;
+ fn_arg = TREE_CHAIN (fn_arg))
+ pcum->named_count += 1;
+
+ if (! pcum->named_count)
+ pcum->named_count = INT_MAX;
+ }
}
/* Determine where to put an argument to a function.
@@ -1940,12 +2095,33 @@ arm_init_cumulative_args (pcum, fntype, libname, indirect)
(otherwise it is an extra parameter matching an ellipsis). */
rtx
-arm_function_arg (pcum, mode, type, named)
- CUMULATIVE_ARGS * pcum;
- enum machine_mode mode;
- tree type ATTRIBUTE_UNUSED;
- int named;
+arm_function_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
+ tree type ATTRIBUTE_UNUSED, int named)
{
+ if (TARGET_REALLY_IWMMXT)
+ {
+ if (VECTOR_MODE_SUPPORTED_P (mode))
+ {
+ /* varargs vectors are treated the same as long long.
+ named_count avoids having to change the way arm handles 'named' */
+ if (pcum->named_count <= pcum->nargs + 1)
+ {
+ if (pcum->nregs == 1)
+ pcum->nregs += 1;
+ if (pcum->nregs <= 2)
+ return gen_rtx_REG (mode, pcum->nregs);
+ else
+ return NULL_RTX;
+ }
+ else if (pcum->iwmmxt_nregs <= 9)
+ return gen_rtx_REG (mode, pcum->iwmmxt_nregs + FIRST_IWMMXT_REGNUM);
+ else
+ return NULL_RTX;
+ }
+ else if ((mode == DImode || mode == DFmode) && pcum->nregs & 1)
+ pcum->nregs += 1;
+ }
+
if (mode == VOIDmode)
/* Compute operand 2 of the call insn. */
return GEN_INT (pcum->call_cookie);
@@ -1960,11 +2136,9 @@ arm_function_arg (pcum, mode, type, named)
extension to the ARM ABI. */
int
-arm_function_arg_pass_by_reference (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type;
- int named ATTRIBUTE_UNUSED;
+arm_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type, int named ATTRIBUTE_UNUSED)
{
return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
}
@@ -1972,8 +2146,7 @@ arm_function_arg_pass_by_reference (cum, mode, type, named)
/* Implement va_arg. */
rtx
-arm_va_arg (valist, type)
- tree valist, type;
+arm_va_arg (tree valist, tree type)
{
/* Variable sized types are passed by reference. */
if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
@@ -1982,6 +2155,26 @@ arm_va_arg (valist, type)
return gen_rtx_MEM (ptr_mode, force_reg (Pmode, addr));
}
+ if (FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), NULL) == IWMMXT_ALIGNMENT)
+ {
+ tree minus_eight;
+ tree t;
+
+ /* Maintain 64-bit alignment of the valist pointer by
+ constructing: valist = ((valist + (8 - 1)) & -8). */
+ minus_eight = build_int_2 (- (IWMMXT_ALIGNMENT / BITS_PER_UNIT), -1);
+ t = build_int_2 ((IWMMXT_ALIGNMENT / BITS_PER_UNIT) - 1, 0);
+ t = build (PLUS_EXPR, TREE_TYPE (valist), valist, t);
+ t = build (BIT_AND_EXPR, TREE_TYPE (t), t, minus_eight);
+ t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+ /* This is to stop the combine pass optimizing
+ away the alignment adjustment. */
+ mark_reg_pointer (arg_pointer_rtx, PARM_BOUNDARY);
+ }
+
return std_expand_builtin_va_arg (valist, type);
}
@@ -1996,22 +2189,19 @@ typedef enum
static arm_pragma_enum arm_pragma_long_calls = OFF;
void
-arm_pr_long_calls (pfile)
- cpp_reader * pfile ATTRIBUTE_UNUSED;
+arm_pr_long_calls (struct cpp_reader * pfile ATTRIBUTE_UNUSED)
{
arm_pragma_long_calls = LONG;
}
void
-arm_pr_no_long_calls (pfile)
- cpp_reader * pfile ATTRIBUTE_UNUSED;
+arm_pr_no_long_calls (struct cpp_reader * pfile ATTRIBUTE_UNUSED)
{
arm_pragma_long_calls = SHORT;
}
void
-arm_pr_long_calls_off (pfile)
- cpp_reader * pfile ATTRIBUTE_UNUSED;
+arm_pr_long_calls_off (struct cpp_reader * pfile ATTRIBUTE_UNUSED)
{
arm_pragma_long_calls = OFF;
}
@@ -2050,14 +2240,9 @@ const struct attribute_spec arm_attribute_table[] =
/* Handle an attribute requiring a FUNCTION_DECL;
arguments as in struct attribute_spec.handler. */
-
static tree
-arm_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
- tree * node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool * no_add_attrs;
+arm_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) != FUNCTION_DECL)
{
@@ -2071,14 +2256,9 @@ arm_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
/* Handle an "interrupt" or "isr" attribute;
arguments as in struct attribute_spec.handler. */
-
static tree
-arm_handle_isr_attribute (node, name, args, flags, no_add_attrs)
- tree * node;
- tree name;
- tree args;
- int flags;
- bool * no_add_attrs;
+arm_handle_isr_attribute (tree *node, tree name, tree args, int flags,
+ bool *no_add_attrs)
{
if (DECL_P (*node))
{
@@ -2136,11 +2316,8 @@ arm_handle_isr_attribute (node, name, args, flags, no_add_attrs)
/* Return 0 if the attributes for two types are incompatible, 1 if they
are compatible, and 2 if they are nearly compatible (which causes a
warning to be generated). */
-
static int
-arm_comp_type_attributes (type1, type2)
- tree type1;
- tree type2;
+arm_comp_type_attributes (tree type1, tree type2)
{
int l1, l2, s1, s2;
@@ -2181,11 +2358,8 @@ arm_comp_type_attributes (type1, type2)
/* Encode long_call or short_call attribute by prefixing
symbol name in DECL with a special character FLAG. */
-
void
-arm_encode_call_attribute (decl, flag)
- tree decl;
- int flag;
+arm_encode_call_attribute (tree decl, int flag)
{
const char * str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
int len = strlen (str);
@@ -2206,10 +2380,8 @@ arm_encode_call_attribute (decl, flag)
/* Assigns default attributes to newly defined type. This is used to
set short_call/long_call attributes for function types of
functions defined inside corresponding #pragma scopes. */
-
static void
-arm_set_default_type_attributes (type)
- tree type;
+arm_set_default_type_attributes (tree type)
{
/* Add __attribute__ ((long_call)) to all functions, when
inside #pragma long_calls or __attribute__ ((short_call)),
@@ -2232,12 +2404,10 @@ arm_set_default_type_attributes (type)
}
/* Return 1 if the operand is a SYMBOL_REF for a function known to be
- defined within the current compilation unit. If this caanot be
+ defined within the current compilation unit. If this cannot be
determined, then 0 is returned. */
-
static int
-current_file_function_operand (sym_ref)
- rtx sym_ref;
+current_file_function_operand (rtx sym_ref)
{
/* This is a bit of a fib. A function will have a short call flag
applied to its name if it has the short call attribute, or it has
@@ -2277,12 +2447,8 @@ current_file_function_operand (sym_ref)
"call_symbol" and "call_symbol_value" patterns and to 0 in the "call"
and "call_value" patterns. This is because of the difference in the
SYM_REFs passed by these patterns. */
-
int
-arm_is_longcall_p (sym_ref, call_cookie, call_symbol)
- rtx sym_ref;
- int call_cookie;
- int call_symbol;
+arm_is_longcall_p (rtx sym_ref, int call_cookie, int call_symbol)
{
if (!call_symbol)
{
@@ -2310,17 +2476,18 @@ arm_is_longcall_p (sym_ref, call_cookie, call_symbol)
}
/* Return nonzero if it is ok to make a tail-call to DECL. */
-
-int
-arm_function_ok_for_sibcall (decl)
- tree decl;
+static bool
+arm_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
{
int call_type = TARGET_LONG_CALLS ? CALL_LONG : CALL_NORMAL;
+ if (cfun->machine->sibcall_blocked)
+ return false;
+
/* Never tailcall something for which we have no decl, or if we
are in Thumb mode. */
if (decl == NULL || TARGET_THUMB)
- return 0;
+ return false;
/* Get the calling method. */
if (lookup_attribute ("short_call", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
@@ -2332,26 +2499,29 @@ arm_function_ok_for_sibcall (decl)
a branch instruction. However, if not compiling PIC, we know
we can reach the symbol if it is in this compilation unit. */
if (call_type == CALL_LONG && (flag_pic || !TREE_ASM_WRITTEN (decl)))
- return 0;
+ return false;
/* If we are interworking and the function is not declared static
then we can't tail-call it unless we know that it exists in this
compilation unit (since it might be a Thumb routine). */
if (TARGET_INTERWORK && TREE_PUBLIC (decl) && !TREE_ASM_WRITTEN (decl))
- return 0;
+ return false;
/* Never tailcall from an ISR routine - it needs a special exit sequence. */
if (IS_INTERRUPT (arm_current_func_type ()))
- return 0;
+ return false;
/* Everything else is ok. */
- return 1;
+ return true;
}
+/* Addressing mode support functions. */
+
+/* Return nonzero if X is a legitimate immediate operand when compiling
+ for PIC. */
int
-legitimate_pic_operand_p (x)
- rtx x;
+legitimate_pic_operand_p (rtx x)
{
if (CONSTANT_P (x)
&& flag_pic
@@ -2365,10 +2535,7 @@ legitimate_pic_operand_p (x)
}
rtx
-legitimize_pic_address (orig, mode, reg)
- rtx orig;
- enum machine_mode mode;
- rtx reg;
+legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
{
if (GET_CODE (orig) == SYMBOL_REF
|| GET_CODE (orig) == LABEL_REF)
@@ -2406,7 +2573,7 @@ legitimize_pic_address (orig, mode, reg)
if ((GET_CODE (orig) == LABEL_REF
|| (GET_CODE (orig) == SYMBOL_REF &&
- ENCODED_SHORT_CALL_ATTR_P (XSTR (orig, 0))))
+ SYMBOL_REF_LOCAL_P (orig)))
&& NEED_GOT_RELOC)
pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
else
@@ -2455,14 +2622,14 @@ legitimize_pic_address (orig, mode, reg)
{
/* The base register doesn't really matter, we only want to
test the index for the appropriate mode. */
- ARM_GO_IF_LEGITIMATE_INDEX (mode, 0, offset, win);
-
- if (!no_new_pseudos)
- offset = force_reg (Pmode, offset);
- else
- abort ();
+ if (!arm_legitimate_index_p (mode, offset, 0))
+ {
+ if (!no_new_pseudos)
+ offset = force_reg (Pmode, offset);
+ else
+ abort ();
+ }
- win:
if (GET_CODE (offset) == CONST_INT)
return plus_constant (base, INTVAL (offset));
}
@@ -2486,10 +2653,8 @@ legitimize_pic_address (orig, mode, reg)
generated insns at the start of the function); false if called
by an exception receiver that needs the PIC register reloaded
(in which case the insns are just dumped at the current location). */
-
void
-arm_finalize_pic (prologue)
- int prologue ATTRIBUTE_UNUSED;
+arm_finalize_pic (int prologue ATTRIBUTE_UNUSED)
{
#ifndef AOF_ASSEMBLER
rtx l1, pic_tmp, pic_tmp2, seq, pic_rtx;
@@ -2540,6 +2705,417 @@ arm_finalize_pic (prologue)
#endif /* AOF_ASSEMBLER */
}
+/* Return nonzero if X is valid as an ARM state addressing register. */
+static int
+arm_address_register_rtx_p (rtx x, int strict_p)
+{
+ int regno;
+
+ if (GET_CODE (x) != REG)
+ return 0;
+
+ regno = REGNO (x);
+
+ if (strict_p)
+ return ARM_REGNO_OK_FOR_BASE_P (regno);
+
+ return (regno <= LAST_ARM_REGNUM
+ || regno >= FIRST_PSEUDO_REGISTER
+ || regno == FRAME_POINTER_REGNUM
+ || regno == ARG_POINTER_REGNUM);
+}
+
+/* Return nonzero if X is a valid ARM state address operand. */
+int
+arm_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
+{
+ if (arm_address_register_rtx_p (x, strict_p))
+ return 1;
+
+ else if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)
+ return arm_address_register_rtx_p (XEXP (x, 0), strict_p);
+
+ else if ((GET_CODE (x) == POST_MODIFY || GET_CODE (x) == PRE_MODIFY)
+ && GET_MODE_SIZE (mode) <= 4
+ && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
+ && GET_CODE (XEXP (x, 1)) == PLUS
+ && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
+ return arm_legitimate_index_p (mode, XEXP (XEXP (x, 1), 1), strict_p);
+
+ /* After reload constants split into minipools will have addresses
+ from a LABEL_REF. */
+ else if (reload_completed
+ && (GET_CODE (x) == LABEL_REF
+ || (GET_CODE (x) == CONST
+ && GET_CODE (XEXP (x, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
+ return 1;
+
+ else if (mode == TImode)
+ return 0;
+
+ else if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
+ {
+ if (GET_CODE (x) == PLUS
+ && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
+
+ if (val == 4 || val == -4 || val == -8)
+ return 1;
+ }
+ }
+
+ else if (GET_CODE (x) == PLUS)
+ {
+ rtx xop0 = XEXP (x, 0);
+ rtx xop1 = XEXP (x, 1);
+
+ return ((arm_address_register_rtx_p (xop0, strict_p)
+ && arm_legitimate_index_p (mode, xop1, strict_p))
+ || (arm_address_register_rtx_p (xop1, strict_p)
+ && arm_legitimate_index_p (mode, xop0, strict_p)));
+ }
+
+#if 0
+ /* Reload currently can't handle MINUS, so disable this for now */
+ else if (GET_CODE (x) == MINUS)
+ {
+ rtx xop0 = XEXP (x, 0);
+ rtx xop1 = XEXP (x, 1);
+
+ return (arm_address_register_rtx_p (xop0, strict_p)
+ && arm_legitimate_index_p (mode, xop1, strict_p));
+ }
+#endif
+
+ else if (GET_MODE_CLASS (mode) != MODE_FLOAT
+ && GET_CODE (x) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (x)
+ && ! (flag_pic
+ && symbol_mentioned_p (get_pool_constant (x))))
+ return 1;
+
+ else if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == POST_DEC)
+ && (GET_MODE_SIZE (mode) <= 4)
+ && arm_address_register_rtx_p (XEXP (x, 0), strict_p))
+ return 1;
+
+ return 0;
+}
+
+/* Return nonzero if INDEX is valid for an address index operand in
+ ARM state. */
+static int
+arm_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p)
+{
+ HOST_WIDE_INT range;
+ enum rtx_code code = GET_CODE (index);
+
+ if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ return (code == CONST_INT && INTVAL (index) < 1024
+ && INTVAL (index) > -1024
+ && (INTVAL (index) & 3) == 0);
+
+ if (TARGET_CIRRUS
+ && (GET_MODE_CLASS (mode) == MODE_FLOAT || mode == DImode))
+ return (code == CONST_INT
+ && INTVAL (index) < 255
+ && INTVAL (index) > -255);
+
+ if (arm_address_register_rtx_p (index, strict_p)
+ && GET_MODE_SIZE (mode) <= 4)
+ return 1;
+
+ if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))
+ return (code == CONST_INT
+ && INTVAL (index) < 256
+ && INTVAL (index) > -256);
+
+ /* XXX What about ldrsb? */
+ if (GET_MODE_SIZE (mode) <= 4 && code == MULT
+ && (!arm_arch4 || (mode) != HImode))
+ {
+ rtx xiop0 = XEXP (index, 0);
+ rtx xiop1 = XEXP (index, 1);
+
+ return ((arm_address_register_rtx_p (xiop0, strict_p)
+ && power_of_two_operand (xiop1, SImode))
+ || (arm_address_register_rtx_p (xiop1, strict_p)
+ && power_of_two_operand (xiop0, SImode)));
+ }
+
+ if (GET_MODE_SIZE (mode) <= 4
+ && (code == LSHIFTRT || code == ASHIFTRT
+ || code == ASHIFT || code == ROTATERT)
+ && (!arm_arch4 || (mode) != HImode))
+ {
+ rtx op = XEXP (index, 1);
+
+ return (arm_address_register_rtx_p (XEXP (index, 0), strict_p)
+ && GET_CODE (op) == CONST_INT
+ && INTVAL (op) > 0
+ && INTVAL (op) <= 31);
+ }
+
+ /* XXX For ARM v4 we may be doing a sign-extend operation during the
+ load, but that has a restricted addressing range and we are unable
+ to tell here whether that is the case. To be safe we restrict all
+ loads to that range. */
+ if (arm_arch4)
+ range = (mode == HImode || mode == QImode) ? 256 : 4096;
+ else
+ range = (mode == HImode) ? 4095 : 4096;
+
+ return (code == CONST_INT
+ && INTVAL (index) < range
+ && INTVAL (index) > -range);
+}
+
+/* Return nonzero if X is valid as a Thumb state base register. */
+static int
+thumb_base_register_rtx_p (rtx x, enum machine_mode mode, int strict_p)
+{
+ int regno;
+
+ if (GET_CODE (x) != REG)
+ return 0;
+
+ regno = REGNO (x);
+
+ if (strict_p)
+ return THUMB_REGNO_MODE_OK_FOR_BASE_P (regno, mode);
+
+ return (regno <= LAST_LO_REGNUM
+ || regno > LAST_VIRTUAL_REGISTER
+ || regno == FRAME_POINTER_REGNUM
+ || (GET_MODE_SIZE (mode) >= 4
+ && (regno == STACK_POINTER_REGNUM
+ || regno >= FIRST_PSEUDO_REGISTER
+ || x == hard_frame_pointer_rtx
+ || x == arg_pointer_rtx)));
+}
+
+/* Return nonzero if x is a legitimate index register. This is the case
+ for any base register that can access a QImode object. */
+inline static int
+thumb_index_register_rtx_p (rtx x, int strict_p)
+{
+ return thumb_base_register_rtx_p (x, QImode, strict_p);
+}
+
+/* Return nonzero if x is a legitimate Thumb-state address.
+
+ The AP may be eliminated to either the SP or the FP, so we use the
+ least common denominator, e.g. SImode, and offsets from 0 to 64.
+
+ ??? Verify whether the above is the right approach.
+
+ ??? Also, the FP may be eliminated to the SP, so perhaps that
+ needs special handling also.
+
+ ??? Look at how the mips16 port solves this problem. It probably uses
+ better ways to solve some of these problems.
+
+ Although it is not incorrect, we don't accept QImode and HImode
+ 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
+thumb_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
+{
+ /* ??? Not clear if this is right. Experiment. */
+ if (GET_MODE_SIZE (mode) < 4
+ && !(reload_in_progress || reload_completed)
+ && (reg_mentioned_p (frame_pointer_rtx, x)
+ || reg_mentioned_p (arg_pointer_rtx, x)
+ || reg_mentioned_p (virtual_incoming_args_rtx, x)
+ || reg_mentioned_p (virtual_outgoing_args_rtx, x)
+ || reg_mentioned_p (virtual_stack_dynamic_rtx, x)
+ || reg_mentioned_p (virtual_stack_vars_rtx, x)))
+ return 0;
+
+ /* Accept any base register. SP only in SImode or larger. */
+ else if (thumb_base_register_rtx_p (x, mode, strict_p))
+ return 1;
+
+ /* This is PC relative data before arm_reorg runs. */
+ else if (GET_MODE_SIZE (mode) >= 4 && CONSTANT_P (x)
+ && GET_CODE (x) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (x) && ! flag_pic)
+ return 1;
+
+ /* This is PC relative data after arm_reorg runs. */
+ else if (GET_MODE_SIZE (mode) >= 4 && reload_completed
+ && (GET_CODE (x) == LABEL_REF
+ || (GET_CODE (x) == CONST
+ && GET_CODE (XEXP (x, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
+ return 1;
+
+ /* Post-inc indexing only supported for SImode and larger. */
+ else if (GET_CODE (x) == POST_INC && GET_MODE_SIZE (mode) >= 4
+ && thumb_index_register_rtx_p (XEXP (x, 0), strict_p))
+ return 1;
+
+ else if (GET_CODE (x) == PLUS)
+ {
+ /* REG+REG address can be any two index registers. */
+ /* We disallow FRAME+REG addressing since we know that FRAME
+ will be replaced with STACK, and SP relative addressing only
+ permits SP+OFFSET. */
+ if (GET_MODE_SIZE (mode) <= 4
+ && XEXP (x, 0) != frame_pointer_rtx
+ && XEXP (x, 1) != frame_pointer_rtx
+ && thumb_index_register_rtx_p (XEXP (x, 0), strict_p)
+ && thumb_index_register_rtx_p (XEXP (x, 1), strict_p))
+ return 1;
+
+ /* REG+const has 5-7 bit offset for non-SP registers. */
+ else if ((thumb_index_register_rtx_p (XEXP (x, 0), strict_p)
+ || XEXP (x, 0) == arg_pointer_rtx)
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && thumb_legitimate_offset_p (mode, INTVAL (XEXP (x, 1))))
+ return 1;
+
+ /* REG+const has 10 bit offset for SP, but only SImode and
+ larger is supported. */
+ /* ??? Should probably check for DI/DFmode overflow here
+ just like GO_IF_LEGITIMATE_OFFSET does. */
+ else if (GET_CODE (XEXP (x, 0)) == REG
+ && REGNO (XEXP (x, 0)) == STACK_POINTER_REGNUM
+ && GET_MODE_SIZE (mode) >= 4
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && INTVAL (XEXP (x, 1)) >= 0
+ && INTVAL (XEXP (x, 1)) + GET_MODE_SIZE (mode) <= 1024
+ && (INTVAL (XEXP (x, 1)) & 3) == 0)
+ return 1;
+
+ else if (GET_CODE (XEXP (x, 0)) == REG
+ && REGNO (XEXP (x, 0)) == FRAME_POINTER_REGNUM
+ && GET_MODE_SIZE (mode) >= 4
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (INTVAL (XEXP (x, 1)) & 3) == 0)
+ return 1;
+ }
+
+ else if (GET_MODE_CLASS (mode) != MODE_FLOAT
+ && GET_MODE_SIZE (mode) == 4
+ && GET_CODE (x) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (x)
+ && !(flag_pic
+ && symbol_mentioned_p (get_pool_constant (x))))
+ return 1;
+
+ return 0;
+}
+
+/* Return nonzero if VAL can be used as an offset in a Thumb-state address
+ instruction of mode MODE. */
+int
+thumb_legitimate_offset_p (enum machine_mode mode, HOST_WIDE_INT val)
+{
+ switch (GET_MODE_SIZE (mode))
+ {
+ case 1:
+ return val >= 0 && val < 32;
+
+ case 2:
+ return val >= 0 && val < 64 && (val & 1) == 0;
+
+ default:
+ return (val >= 0
+ && (val + GET_MODE_SIZE (mode)) <= 128
+ && (val & 3) == 0);
+ }
+}
+
+/* Try machine-dependent ways of modifying an illegitimate address
+ to be legitimate. If we find one, return the new, valid address. */
+rtx
+arm_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
+{
+ if (GET_CODE (x) == PLUS)
+ {
+ rtx xop0 = XEXP (x, 0);
+ rtx xop1 = XEXP (x, 1);
+
+ if (CONSTANT_P (xop0) && !symbol_mentioned_p (xop0))
+ xop0 = force_reg (SImode, xop0);
+
+ if (CONSTANT_P (xop1) && !symbol_mentioned_p (xop1))
+ xop1 = force_reg (SImode, xop1);
+
+ if (ARM_BASE_REGISTER_RTX_P (xop0)
+ && GET_CODE (xop1) == CONST_INT)
+ {
+ HOST_WIDE_INT n, low_n;
+ rtx base_reg, val;
+ n = INTVAL (xop1);
+
+ if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
+ {
+ low_n = n & 0x0f;
+ n &= ~0x0f;
+ if (low_n > 4)
+ {
+ n += 16;
+ low_n -= 16;
+ }
+ }
+ else
+ {
+ low_n = ((mode) == TImode ? 0
+ : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff));
+ n -= low_n;
+ }
+
+ base_reg = gen_reg_rtx (SImode);
+ val = force_operand (gen_rtx_PLUS (SImode, xop0,
+ GEN_INT (n)), NULL_RTX);
+ emit_move_insn (base_reg, val);
+ x = (low_n == 0 ? base_reg
+ : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n)));
+ }
+ else if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
+ x = gen_rtx_PLUS (SImode, xop0, xop1);
+ }
+
+ /* XXX We don't allow MINUS any more -- see comment in
+ arm_legitimate_address_p (). */
+ else if (GET_CODE (x) == MINUS)
+ {
+ rtx xop0 = XEXP (x, 0);
+ rtx xop1 = XEXP (x, 1);
+
+ if (CONSTANT_P (xop0))
+ xop0 = force_reg (SImode, xop0);
+
+ if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1))
+ xop1 = force_reg (SImode, xop1);
+
+ if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
+ x = gen_rtx_MINUS (SImode, xop0, xop1);
+ }
+
+ if (flag_pic)
+ {
+ /* We need to find and carefully transform any SYMBOL and LABEL
+ references; so go back to the original address expression. */
+ rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX);
+
+ if (new_x != orig_x)
+ x = new_x;
+ }
+
+ return x;
+}
+
+
+
#define REG_OR_SUBREG_REG(X) \
(GET_CODE (X) == REG \
|| (GET_CODE (X) == SUBREG && GET_CODE (SUBREG_REG (X)) == REG))
@@ -2550,12 +3126,9 @@ arm_finalize_pic (prologue)
#ifndef COSTS_N_INSNS
#define COSTS_N_INSNS(N) ((N) * 4 - 2)
#endif
-
-int
-arm_rtx_costs (x, code, outer)
- rtx x;
- enum rtx_code code;
- enum rtx_code outer;
+/* Worker routine for arm_rtx_costs. */
+static inline int
+arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer)
{
enum machine_mode mode = GET_MODE (x);
enum rtx_code subcode;
@@ -2605,12 +3178,12 @@ arm_rtx_costs (x, code, outer)
return COSTS_N_INSNS (2);
return COSTS_N_INSNS (3);
}
- else if (outer == PLUS
+ else if ((outer == PLUS || outer == COMPARE)
&& INTVAL (x) < 256 && INTVAL (x) > -256)
- return 0;
- else if (outer == COMPARE
- && (unsigned HOST_WIDE_INT) INTVAL (x) < 256)
- return 0;
+ return 0;
+ else if (outer == AND
+ && INTVAL (x) < 256 && INTVAL (x) >= -256)
+ return COSTS_N_INSNS (1);
else if (outer == ASHIFT || outer == ASHIFTRT
|| outer == LSHIFTRT)
return 0;
@@ -2634,7 +3207,7 @@ arm_rtx_costs (x, code, outer)
case AND:
case XOR:
case IOR:
- /* XXX guess. */
+ /* XXX guess. */
return 8;
case ADDRESSOF:
@@ -2647,7 +3220,7 @@ arm_rtx_costs (x, code, outer)
? 4 : 0));
case IF_THEN_ELSE:
- /* XXX a guess. */
+ /* XXX a guess. */
if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
return 14;
return 2;
@@ -2673,16 +3246,6 @@ arm_rtx_costs (x, code, outer)
default:
return 99;
-#if 0
- case FFS:
- case FLOAT:
- case FIX:
- case UNSIGNED_FIX:
- /* XXX guess */
- fprintf (stderr, "unexpected code for thumb in rtx_costs: %s\n",
- rtx_name[code]);
- abort ();
-#endif
}
}
@@ -2697,7 +3260,9 @@ arm_rtx_costs (x, code, outer)
case DIV:
case MOD:
- return 100;
+ case UDIV:
+ case UMOD:
+ return optimize_size ? COSTS_N_INSNS (2) : 100;
case ROTATE:
if (mode == SImode && GET_CODE (XEXP (x, 1)) == REG)
@@ -2735,11 +3300,11 @@ arm_rtx_costs (x, code, outer)
if (GET_MODE_CLASS (mode) == MODE_FLOAT)
return (2 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
|| (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
- && const_double_rtx_ok_for_fpu (XEXP (x, 1))))
+ && const_double_rtx_ok_for_fpa (XEXP (x, 1))))
? 0 : 8)
+ ((REG_OR_SUBREG_REG (XEXP (x, 0))
|| (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE
- && const_double_rtx_ok_for_fpu (XEXP (x, 0))))
+ && const_double_rtx_ok_for_fpa (XEXP (x, 0))))
? 0 : 8));
if (((GET_CODE (XEXP (x, 0)) == CONST_INT
@@ -2764,7 +3329,7 @@ arm_rtx_costs (x, code, outer)
return (2 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
+ ((REG_OR_SUBREG_REG (XEXP (x, 1))
|| (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
- && const_double_rtx_ok_for_fpu (XEXP (x, 1))))
+ && const_double_rtx_ok_for_fpa (XEXP (x, 1))))
? 0 : 8));
/* Fall through */
@@ -2830,19 +3395,41 @@ arm_rtx_costs (x, code, outer)
{
unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1))
& (unsigned HOST_WIDE_INT) 0xffffffff);
- int add_cost = const_ok_for_arm (i) ? 4 : 8;
- int j;
+ int cost, const_ok = const_ok_for_arm (i);
+ int j, booth_unit_size;
+
+ if (arm_tune_xscale)
+ {
+ unsigned HOST_WIDE_INT masked_const;
+
+ /* The cost will be related to two insns.
+ First a load of the constant (MOV or LDR), then a multiply. */
+ cost = 2;
+ if (! const_ok)
+ cost += 1; /* LDR is probably more expensive because
+ of longer result latency. */
+ masked_const = i & 0xffff8000;
+ if (masked_const != 0 && masked_const != 0xffff8000)
+ {
+ masked_const = i & 0xf8000000;
+ if (masked_const == 0 || masked_const == 0xf8000000)
+ cost += 1;
+ else
+ cost += 2;
+ }
+ return cost;
+ }
/* Tune as appropriate. */
- int booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
-
+ cost = const_ok ? 4 : 8;
+ booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
for (j = 0; i && j < 32; j += booth_unit_size)
{
i >>= booth_unit_size;
- add_cost += 2;
+ cost += 2;
}
- return add_cost;
+ return cost;
}
return (((tune_flags & FL_FAST_MULT) ? 8 : 30)
@@ -2900,6 +3487,13 @@ arm_rtx_costs (x, code, outer)
case SImode:
return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
+ case V8QImode:
+ case V4HImode:
+ case V2SImode:
+ case V4QImode:
+ case V2HImode:
+ return 1;
+
default:
break;
}
@@ -2924,10 +3518,10 @@ arm_rtx_costs (x, code, outer)
return 6;
case CONST_DOUBLE:
- if (const_double_rtx_ok_for_fpu (x))
+ if (const_double_rtx_ok_for_fpa (x))
return outer == SET ? 2 : -1;
else if ((outer == COMPARE || outer == PLUS)
- && neg_const_double_rtx_ok_for_fpu (x))
+ && neg_const_double_rtx_ok_for_fpa (x))
return -1;
return 7;
@@ -2936,21 +3530,82 @@ arm_rtx_costs (x, code, outer)
}
}
+static bool
+arm_rtx_costs (rtx x, int code, int outer_code, int *total)
+{
+ *total = arm_rtx_costs_1 (x, code, outer_code);
+ return true;
+}
+
+/* All address computations that can be done are free, but rtx cost returns
+ the same for practically all of them. So we weight the different types
+ of address here in the order (most pref first):
+ PRE/POST_INC/DEC, SHIFT or NON-INT sum, INT sum, REG, MEM or LABEL. */
+static inline int
+arm_arm_address_cost (rtx x)
+{
+ enum rtx_code c = GET_CODE (x);
+
+ if (c == PRE_INC || c == PRE_DEC || c == POST_INC || c == POST_DEC)
+ return 0;
+ if (c == MEM || c == LABEL_REF || c == SYMBOL_REF)
+ return 10;
+
+ if (c == PLUS || c == MINUS)
+ {
+ char cl0 = GET_RTX_CLASS (GET_CODE (XEXP (x, 0)));
+ char cl1 = GET_RTX_CLASS (GET_CODE (XEXP (x, 1)));
+
+ if (GET_CODE (XEXP (x, 0)) == CONST_INT)
+ return 2;
+
+ if (cl0 == '2' || cl0 == 'c' || cl1 == '2' || cl1 == 'c')
+ return 3;
+
+ return 4;
+ }
+
+ return 6;
+}
+
+static inline int
+arm_thumb_address_cost (rtx x)
+{
+ enum rtx_code c = GET_CODE (x);
+
+ if (c == REG)
+ return 1;
+ if (c == PLUS
+ && GET_CODE (XEXP (x, 0)) == REG
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ return 1;
+
+ return 2;
+}
+
+static int
+arm_address_cost (rtx x)
+{
+ return TARGET_ARM ? arm_arm_address_cost (x) : arm_thumb_address_cost (x);
+}
+
+static int
+arm_use_dfa_pipeline_interface (void)
+{
+ return true;
+}
+
static int
-arm_adjust_cost (insn, link, dep, cost)
- rtx insn;
- rtx link;
- rtx dep;
- int cost;
+arm_adjust_cost (rtx insn, rtx link, rtx dep, int cost)
{
rtx i_pat, d_pat;
/* Some true dependencies can have a higher cost depending
on precisely how certain input operands are used. */
- if (arm_is_xscale
+ if (arm_tune_xscale
&& REG_NOTE_KIND (link) == 0
- && recog_memoized (insn) < 0
- && recog_memoized (dep) < 0)
+ && recog_memoized (insn) >= 0
+ && recog_memoized (dep) >= 0)
{
int shift_opnum = get_attr_shift (insn);
enum attr_type attr_type = get_attr_type (dep);
@@ -3017,8 +3672,6 @@ arm_adjust_cost (insn, link, dep, cost)
return cost;
}
-/* This code has been fixed for cross compilation. */
-
static int fpa_consts_inited = 0;
static const char * const strings_fpa[8] =
@@ -3030,7 +3683,7 @@ static const char * const strings_fpa[8] =
static REAL_VALUE_TYPE values_fpa[8];
static void
-init_fpa_table ()
+init_fpa_table (void)
{
int i;
REAL_VALUE_TYPE r;
@@ -3044,11 +3697,9 @@ init_fpa_table ()
fpa_consts_inited = 1;
}
-/* Return TRUE if rtx X is a valid immediate FPU constant. */
-
+/* Return TRUE if rtx X is a valid immediate FPA constant. */
int
-const_double_rtx_ok_for_fpu (x)
- rtx x;
+const_double_rtx_ok_for_fpa (rtx x)
{
REAL_VALUE_TYPE r;
int i;
@@ -3067,11 +3718,9 @@ const_double_rtx_ok_for_fpu (x)
return 0;
}
-/* Return TRUE if rtx X is a valid immediate FPU constant. */
-
+/* Return TRUE if rtx X is a valid immediate FPA constant. */
int
-neg_const_double_rtx_ok_for_fpu (x)
- rtx x;
+neg_const_double_rtx_ok_for_fpa (rtx x)
{
REAL_VALUE_TYPE r;
int i;
@@ -3100,11 +3749,8 @@ neg_const_double_rtx_ok_for_fpu (x)
code. SUBREG(MEM) always needs a reload in the places where
s_register_operand is used, and this seemed to lead to excessive
reloading. */
-
int
-s_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+s_register_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return 0;
@@ -3121,11 +3767,8 @@ s_register_operand (op, mode)
}
/* A hard register operand (even before reload. */
-
int
-arm_hard_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arm_hard_register_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return 0;
@@ -3135,11 +3778,8 @@ arm_hard_register_operand (op, mode)
}
/* Only accept reg, subreg(reg), const_int. */
-
int
-reg_or_int_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_int_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return 1;
@@ -3158,11 +3798,8 @@ reg_or_int_operand (op, mode)
}
/* Return 1 if OP is an item in memory, given that we are in reload. */
-
int
-arm_reload_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+arm_reload_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int regno = true_regnum (op);
@@ -3176,18 +3813,11 @@ arm_reload_memory_operand (op, mode)
memory access (architecture V4).
MODE is QImode if called when computing constraints, or VOIDmode when
emitting patterns. In this latter case we cannot use memory_operand()
- because it will fail on badly formed MEMs, which is precisly what we are
+ because it will fail on badly formed MEMs, which is precisely what we are
trying to catch. */
-
int
-bad_signed_byte_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+bad_signed_byte_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
-#if 0
- if ((mode == QImode && !memory_operand (op, mode)) || GET_CODE (op) != MEM)
- return 0;
-#endif
if (GET_CODE (op) != MEM)
return 0;
@@ -3211,11 +3841,8 @@ bad_signed_byte_operand (op, mode)
}
/* Return TRUE for valid operands for the rhs of an ARM instruction. */
-
int
-arm_rhs_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arm_rhs_operand (rtx op, enum machine_mode mode)
{
return (s_register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op))));
@@ -3223,11 +3850,8 @@ arm_rhs_operand (op, mode)
/* Return TRUE for valid operands for the
rhs of an ARM instruction, or a load. */
-
int
-arm_rhsm_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arm_rhsm_operand (rtx op, enum machine_mode mode)
{
return (s_register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op)))
@@ -3236,11 +3860,8 @@ arm_rhsm_operand (op, mode)
/* Return TRUE for valid operands for the rhs of an ARM instruction, or if a
constant that is valid when negated. */
-
int
-arm_add_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arm_add_operand (rtx op, enum machine_mode mode)
{
if (TARGET_THUMB)
return thumb_cmp_operand (op, mode);
@@ -3251,10 +3872,17 @@ arm_add_operand (op, mode)
|| const_ok_for_arm (-INTVAL (op)))));
}
+/* Return TRUE for valid ARM constants (or when valid if negated). */
+int
+arm_addimm_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return (GET_CODE (op) == CONST_INT
+ && (const_ok_for_arm (INTVAL (op))
+ || const_ok_for_arm (-INTVAL (op))));
+}
+
int
-arm_not_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arm_not_operand (rtx op, enum machine_mode mode)
{
return (s_register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT
@@ -3264,11 +3892,8 @@ arm_not_operand (op, mode)
/* Return TRUE if the operand is a memory reference which contains an
offsettable address. */
-
int
-offsettable_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+offsettable_memory_operand (rtx op, enum machine_mode mode)
{
if (mode == VOIDmode)
mode = GET_MODE (op);
@@ -3281,11 +3906,8 @@ offsettable_memory_operand (op, mode)
/* Return TRUE if the operand is a memory reference which is, or can be
made word aligned by adjusting the offset. */
-
int
-alignable_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+alignable_memory_operand (rtx op, enum machine_mode mode)
{
rtx reg;
@@ -3310,11 +3932,8 @@ alignable_memory_operand (op, mode)
/* Similar to s_register_operand, but does not allow hard integer
registers. */
-
int
-f_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+f_register_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return 0;
@@ -3326,15 +3945,12 @@ f_register_operand (op, mode)
to be a register operand. */
return (GET_CODE (op) == REG
&& (REGNO (op) >= FIRST_PSEUDO_REGISTER
- || REGNO_REG_CLASS (REGNO (op)) == FPU_REGS));
+ || REGNO_REG_CLASS (REGNO (op)) == FPA_REGS));
}
-/* Return TRUE for valid operands for the rhs of an FPU instruction. */
-
+/* Return TRUE for valid operands for the rhs of an FPA instruction. */
int
-fpu_rhs_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fpa_rhs_operand (rtx op, enum machine_mode mode)
{
if (s_register_operand (op, mode))
return TRUE;
@@ -3343,15 +3959,13 @@ fpu_rhs_operand (op, mode)
return FALSE;
if (GET_CODE (op) == CONST_DOUBLE)
- return const_double_rtx_ok_for_fpu (op);
+ return const_double_rtx_ok_for_fpa (op);
return FALSE;
}
int
-fpu_add_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fpa_add_operand (rtx op, enum machine_mode mode)
{
if (s_register_operand (op, mode))
return TRUE;
@@ -3360,18 +3974,263 @@ fpu_add_operand (op, mode)
return FALSE;
if (GET_CODE (op) == CONST_DOUBLE)
- return (const_double_rtx_ok_for_fpu (op)
- || neg_const_double_rtx_ok_for_fpu (op));
+ return (const_double_rtx_ok_for_fpa (op)
+ || neg_const_double_rtx_ok_for_fpa (op));
return FALSE;
}
-/* Return nonzero if OP is a constant power of two. */
+/* Return nonzero if OP is a valid Cirrus memory address pattern. */
+int
+cirrus_memory_offset (rtx op)
+{
+ /* Reject eliminable registers. */
+ if (! (reload_in_progress || reload_completed)
+ && ( reg_mentioned_p (frame_pointer_rtx, op)
+ || reg_mentioned_p (arg_pointer_rtx, op)
+ || reg_mentioned_p (virtual_incoming_args_rtx, op)
+ || reg_mentioned_p (virtual_outgoing_args_rtx, op)
+ || reg_mentioned_p (virtual_stack_dynamic_rtx, op)
+ || reg_mentioned_p (virtual_stack_vars_rtx, op)))
+ return 0;
+
+ if (GET_CODE (op) == MEM)
+ {
+ rtx ind;
+
+ ind = XEXP (op, 0);
+
+ /* Match: (mem (reg)). */
+ if (GET_CODE (ind) == REG)
+ return 1;
+
+ /* Match:
+ (mem (plus (reg)
+ (const))). */
+ if (GET_CODE (ind) == PLUS
+ && GET_CODE (XEXP (ind, 0)) == REG
+ && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
+ && GET_CODE (XEXP (ind, 1)) == CONST_INT)
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Return nonzero if OP is a Cirrus or general register. */
+int
+cirrus_register_operand (rtx op, enum machine_mode mode)
+{
+ if (GET_MODE (op) != mode && mode != VOIDmode)
+ return FALSE;
+
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ return (GET_CODE (op) == REG
+ && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS
+ || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS));
+}
+
+/* Return nonzero if OP is a cirrus FP register. */
+int
+cirrus_fp_register (rtx op, enum machine_mode mode)
+{
+ if (GET_MODE (op) != mode && mode != VOIDmode)
+ return FALSE;
+
+ if (GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ return (GET_CODE (op) == REG
+ && (REGNO (op) >= FIRST_PSEUDO_REGISTER
+ || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS));
+}
+
+/* Return nonzero if OP is a 6bit constant (0..63). */
+int
+cirrus_shift_const (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return (GET_CODE (op) == CONST_INT
+ && INTVAL (op) >= 0
+ && INTVAL (op) < 64);
+}
+
+/* Returns TRUE if INSN is an "LDR REG, ADDR" instruction.
+ Use by the Cirrus Maverick code which has to workaround
+ a hardware bug triggered by such instructions. */
+static bool
+arm_memory_load_p (rtx insn)
+{
+ rtx body, lhs, rhs;;
+
+ if (insn == NULL_RTX || GET_CODE (insn) != INSN)
+ return false;
+
+ body = PATTERN (insn);
+
+ if (GET_CODE (body) != SET)
+ return false;
+
+ lhs = XEXP (body, 0);
+ rhs = XEXP (body, 1);
+
+ lhs = REG_OR_SUBREG_RTX (lhs);
+
+ /* If the destination is not a general purpose
+ register we do not have to worry. */
+ if (GET_CODE (lhs) != REG
+ || REGNO_REG_CLASS (REGNO (lhs)) != GENERAL_REGS)
+ return false;
+
+ /* As well as loads from memory we also have to react
+ to loads of invalid constants which will be turned
+ into loads from the minipool. */
+ return (GET_CODE (rhs) == MEM
+ || GET_CODE (rhs) == SYMBOL_REF
+ || note_invalid_constants (insn, -1, false));
+}
+
+/* Return TRUE if INSN is a Cirrus instruction. */
+static bool
+arm_cirrus_insn_p (rtx insn)
+{
+ enum attr_cirrus attr;
+
+ /* get_attr aborts on USE and CLOBBER. */
+ if (!insn
+ || GET_CODE (insn) != INSN
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return 0;
+
+ attr = get_attr_cirrus (insn);
+
+ return attr != CIRRUS_NOT;
+}
+
+/* Cirrus reorg for invalid instruction combinations. */
+static void
+cirrus_reorg (rtx first)
+{
+ enum attr_cirrus attr;
+ rtx body = PATTERN (first);
+ rtx t;
+ int nops;
+
+ /* Any branch must be followed by 2 non Cirrus instructions. */
+ if (GET_CODE (first) == JUMP_INSN && GET_CODE (body) != RETURN)
+ {
+ nops = 0;
+ t = next_nonnote_insn (first);
+
+ if (arm_cirrus_insn_p (t))
+ ++ nops;
+
+ if (arm_cirrus_insn_p (next_nonnote_insn (t)))
+ ++ nops;
+
+ while (nops --)
+ emit_insn_after (gen_nop (), first);
+
+ return;
+ }
+
+ /* (float (blah)) is in parallel with a clobber. */
+ if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
+ body = XVECEXP (body, 0, 0);
+
+ if (GET_CODE (body) == SET)
+ {
+ rtx lhs = XEXP (body, 0), rhs = XEXP (body, 1);
+
+ /* cfldrd, cfldr64, cfstrd, cfstr64 must
+ be followed by a non Cirrus insn. */
+ if (get_attr_cirrus (first) == CIRRUS_DOUBLE)
+ {
+ if (arm_cirrus_insn_p (next_nonnote_insn (first)))
+ emit_insn_after (gen_nop (), first);
+
+ return;
+ }
+ else if (arm_memory_load_p (first))
+ {
+ unsigned int arm_regno;
+
+ /* Any ldr/cfmvdlr, ldr/cfmvdhr, ldr/cfmvsr, ldr/cfmv64lr,
+ ldr/cfmv64hr combination where the Rd field is the same
+ in both instructions must be split with a non Cirrus
+ insn. Example:
+
+ ldr r0, blah
+ nop
+ cfmvsr mvf0, r0. */
+
+ /* Get Arm register number for ldr insn. */
+ if (GET_CODE (lhs) == REG)
+ arm_regno = REGNO (lhs);
+ else if (GET_CODE (rhs) == REG)
+ arm_regno = REGNO (rhs);
+ else
+ abort ();
+
+ /* Next insn. */
+ first = next_nonnote_insn (first);
+
+ if (! arm_cirrus_insn_p (first))
+ return;
+
+ body = PATTERN (first);
+
+ /* (float (blah)) is in parallel with a clobber. */
+ if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0))
+ body = XVECEXP (body, 0, 0);
+ if (GET_CODE (body) == FLOAT)
+ body = XEXP (body, 0);
+
+ if (get_attr_cirrus (first) == CIRRUS_MOVE
+ && GET_CODE (XEXP (body, 1)) == REG
+ && arm_regno == REGNO (XEXP (body, 1)))
+ emit_insn_after (gen_nop (), first);
+
+ return;
+ }
+ }
+
+ /* get_attr aborts on USE and CLOBBER. */
+ if (!first
+ || GET_CODE (first) != INSN
+ || GET_CODE (PATTERN (first)) == USE
+ || GET_CODE (PATTERN (first)) == CLOBBER)
+ return;
+
+ attr = get_attr_cirrus (first);
+
+ /* Any coprocessor compare instruction (cfcmps, cfcmpd, ...)
+ must be followed by a non-coprocessor instruction. */
+ if (attr == CIRRUS_COMPARE)
+ {
+ nops = 0;
+
+ t = next_nonnote_insn (first);
+
+ if (arm_cirrus_insn_p (t))
+ ++ nops;
+
+ if (arm_cirrus_insn_p (next_nonnote_insn (t)))
+ ++ nops;
+
+ while (nops --)
+ emit_insn_after (gen_nop (), first);
+
+ return;
+ }
+}
+
+/* Return nonzero if OP is a constant power of two. */
int
-power_of_two_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+power_of_two_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == CONST_INT)
{
@@ -3387,11 +4246,8 @@ power_of_two_operand (op, mode)
Either: REG, SUBREG, CONST_DOUBLE or MEM(DImode_address).
Note that this disallows MEM(REG+REG), but allows
MEM(PRE/POST_INC/DEC(REG)). */
-
int
-di_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+di_operand (rtx op, enum machine_mode mode)
{
if (s_register_operand (op, mode))
return TRUE;
@@ -3417,11 +4273,8 @@ di_operand (op, mode)
}
/* Like di_operand, but don't accept constants. */
-
int
-nonimmediate_di_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+nonimmediate_di_operand (rtx op, enum machine_mode mode)
{
if (s_register_operand (op, mode))
return TRUE;
@@ -3442,11 +4295,8 @@ nonimmediate_di_operand (op, mode)
Either: REG, SUBREG, CONST_DOUBLE or MEM(DImode_address).
Note that this disallows MEM(REG+REG), but allows
MEM(PRE/POST_INC/DEC(REG)). */
-
int
-soft_df_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+soft_df_operand (rtx op, enum machine_mode mode)
{
if (s_register_operand (op, mode))
return TRUE;
@@ -3474,11 +4324,8 @@ soft_df_operand (op, mode)
}
/* Like soft_df_operand, but don't accept constants. */
-
int
-nonimmediate_soft_df_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+nonimmediate_soft_df_operand (rtx op, enum machine_mode mode)
{
if (s_register_operand (op, mode))
return TRUE;
@@ -3495,11 +4342,8 @@ nonimmediate_soft_df_operand (op, mode)
}
/* Return TRUE for valid index operands. */
-
int
-index_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+index_operand (rtx op, enum machine_mode mode)
{
return (s_register_operand (op, mode)
|| (immediate_operand (op, mode)
@@ -3510,11 +4354,8 @@ index_operand (op, mode)
/* Return TRUE for valid shifts by a constant. This also accepts any
power of two on the (somewhat overly relaxed) assumption that the
shift operator in this case was a mult. */
-
int
-const_shift_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+const_shift_operand (rtx op, enum machine_mode mode)
{
return (power_of_two_operand (op, mode)
|| (immediate_operand (op, mode)
@@ -3524,11 +4365,8 @@ const_shift_operand (op, mode)
/* Return TRUE for arithmetic operators which can be combined with a multiply
(shift). */
-
int
-shiftable_operator (x, mode)
- rtx x;
- enum machine_mode mode;
+shiftable_operator (rtx x, enum machine_mode mode)
{
enum rtx_code code;
@@ -3542,11 +4380,8 @@ shiftable_operator (x, mode)
}
/* Return TRUE for binary logical operators. */
-
int
-logical_binary_operator (x, mode)
- rtx x;
- enum machine_mode mode;
+logical_binary_operator (rtx x, enum machine_mode mode)
{
enum rtx_code code;
@@ -3559,11 +4394,8 @@ logical_binary_operator (x, mode)
}
/* Return TRUE for shift operators. */
-
int
-shift_operator (x, mode)
- rtx x;
- enum machine_mode mode;
+shift_operator (rtx x,enum machine_mode mode)
{
enum rtx_code code;
@@ -3580,21 +4412,15 @@ shift_operator (x, mode)
}
/* Return TRUE if x is EQ or NE. */
-
int
-equality_operator (x, mode)
- rtx x;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+equality_operator (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (x) == EQ || GET_CODE (x) == NE;
}
/* Return TRUE if x is a comparison operator other than LTGT or UNEQ. */
-
int
-arm_comparison_operator (x, mode)
- rtx x;
- enum machine_mode mode;
+arm_comparison_operator (rtx x, enum machine_mode mode)
{
return (comparison_operator (x, mode)
&& GET_CODE (x) != LTGT
@@ -3602,11 +4428,8 @@ arm_comparison_operator (x, mode)
}
/* Return TRUE for SMIN SMAX UMIN UMAX operators. */
-
int
-minmax_operator (x, mode)
- rtx x;
- enum machine_mode mode;
+minmax_operator (rtx x, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (x);
@@ -3618,11 +4441,8 @@ minmax_operator (x, mode)
/* Return TRUE if this is the condition code register, if we aren't given
a mode, accept any class CCmode register. */
-
int
-cc_register (x, mode)
- rtx x;
- enum machine_mode mode;
+cc_register (rtx x, enum machine_mode mode)
{
if (mode == VOIDmode)
{
@@ -3643,11 +4463,8 @@ cc_register (x, mode)
/* Return TRUE if this is the condition code register, if we aren't given
a mode, accept any class CCmode register which indicates a dominance
expression. */
-
int
-dominant_cc_register (x, mode)
- rtx x;
- enum machine_mode mode;
+dominant_cc_register (rtx x, enum machine_mode mode)
{
if (mode == VOIDmode)
{
@@ -3657,7 +4474,7 @@ dominant_cc_register (x, mode)
return FALSE;
}
- if ( mode != CC_DNEmode && mode != CC_DEQmode
+ if (mode != CC_DNEmode && mode != CC_DEQmode
&& mode != CC_DLEmode && mode != CC_DLTmode
&& mode != CC_DGEmode && mode != CC_DGTmode
&& mode != CC_DLEUmode && mode != CC_DLTUmode
@@ -3668,10 +4485,8 @@ dominant_cc_register (x, mode)
}
/* Return TRUE if X references a SYMBOL_REF. */
-
int
-symbol_mentioned_p (x)
- rtx x;
+symbol_mentioned_p (rtx x)
{
const char * fmt;
int i;
@@ -3699,10 +4514,8 @@ symbol_mentioned_p (x)
}
/* Return TRUE if X references a LABEL_REF. */
-
int
-label_mentioned_p (x)
- rtx x;
+label_mentioned_p (rtx x)
{
const char * fmt;
int i;
@@ -3729,8 +4542,7 @@ label_mentioned_p (x)
}
enum rtx_code
-minmax_code (x)
- rtx x;
+minmax_code (rtx x)
{
enum rtx_code code = GET_CODE (x);
@@ -3747,10 +4559,8 @@ minmax_code (x)
}
/* Return 1 if memory locations are adjacent. */
-
int
-adjacent_mem_locations (a, b)
- rtx a, b;
+adjacent_mem_locations (rtx a, rtx b)
{
if ((GET_CODE (XEXP (a, 0)) == REG
|| (GET_CODE (XEXP (a, 0)) == PLUS
@@ -3778,6 +4588,12 @@ adjacent_mem_locations (a, b)
else
reg1 = REGNO (XEXP (b, 0));
+ /* Don't accept any offset that will require multiple
+ instructions to handle, since this would cause the
+ arith_adjacentmem pattern to output an overlong sequence. */
+ if (!const_ok_for_op (PLUS, val0) || !const_ok_for_op (PLUS, val1))
+ return 0;
+
return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4);
}
return 0;
@@ -3785,11 +4601,8 @@ adjacent_mem_locations (a, b)
/* Return 1 if OP is a load multiple operation. It is known to be
parallel and the first section will be tested. */
-
int
-load_multiple_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT count = XVECLEN (op, 0);
int dest_regno;
@@ -3810,7 +4623,6 @@ load_multiple_operation (op, mode)
/* Now check it more carefully. */
if (GET_CODE (SET_DEST (elt)) != REG
|| GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
- || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))
|| GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
|| INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
return 0;
@@ -3848,11 +4660,8 @@ load_multiple_operation (op, mode)
/* Return 1 if OP is a store multiple operation. It is known to be
parallel and the first section will be tested. */
-
int
-store_multiple_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT count = XVECLEN (op, 0);
int src_regno;
@@ -3873,7 +4682,6 @@ store_multiple_operation (op, mode)
/* Now check it more carefully. */
if (GET_CODE (SET_DEST (elt)) != REG
|| GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
- || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))
|| GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
|| INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
return 0;
@@ -3910,12 +4718,8 @@ store_multiple_operation (op, mode)
}
int
-load_multiple_sequence (operands, nops, regs, base, load_offset)
- rtx * operands;
- int nops;
- int * regs;
- int * base;
- HOST_WIDE_INT * load_offset;
+load_multiple_sequence (rtx *operands, int nops, int *regs, int *base,
+ HOST_WIDE_INT *load_offset)
{
int unsorted_regs[4];
HOST_WIDE_INT unsorted_offsets[4];
@@ -4085,9 +4889,7 @@ load_multiple_sequence (operands, nops, regs, base, load_offset)
}
const char *
-emit_ldm_seq (operands, nops)
- rtx * operands;
- int nops;
+emit_ldm_seq (rtx *operands, int nops)
{
int regs[4];
int base_reg;
@@ -4145,12 +4947,8 @@ emit_ldm_seq (operands, nops)
}
int
-store_multiple_sequence (operands, nops, regs, base, load_offset)
- rtx * operands;
- int nops;
- int * regs;
- int * base;
- HOST_WIDE_INT * load_offset;
+store_multiple_sequence (rtx *operands, int nops, int *regs, int *base,
+ HOST_WIDE_INT * load_offset)
{
int unsorted_regs[4];
HOST_WIDE_INT unsorted_offsets[4];
@@ -4282,9 +5080,7 @@ store_multiple_sequence (operands, nops, regs, base, load_offset)
}
const char *
-emit_stm_seq (operands, nops)
- rtx * operands;
- int nops;
+emit_stm_seq (rtx *operands, int nops)
{
int regs[4];
int base_reg;
@@ -4328,9 +5124,7 @@ emit_stm_seq (operands, nops)
}
int
-multi_register_push (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+multi_register_push (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != PARALLEL
|| (GET_CODE (XVECEXP (op, 0, 0)) != SET)
@@ -4344,16 +5138,9 @@ multi_register_push (op, mode)
/* Routines for use in generating RTL. */
rtx
-arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
- in_struct_p, scalar_p)
- int base_regno;
- int count;
- rtx from;
- int up;
- int write_back;
- int unchanging_p;
- int in_struct_p;
- int scalar_p;
+arm_gen_load_multiple (int base_regno, int count, rtx from, int up,
+ int write_back, int unchanging_p, int in_struct_p,
+ int scalar_p)
{
int i = 0, j;
rtx result;
@@ -4388,7 +5175,7 @@ arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
As a compromise, we use ldr for counts of 1 or 2 regs, and ldm
for counts of 3 or 4 regs. */
- if (arm_is_xscale && count <= 2 && ! optimize_size)
+ if (arm_tune_xscale && count <= 2 && ! optimize_size)
{
rtx seq;
@@ -4437,16 +5224,9 @@ arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
}
rtx
-arm_gen_store_multiple (base_regno, count, to, up, write_back, unchanging_p,
- in_struct_p, scalar_p)
- int base_regno;
- int count;
- rtx to;
- int up;
- int write_back;
- int unchanging_p;
- int in_struct_p;
- int scalar_p;
+arm_gen_store_multiple (int base_regno, int count, rtx to, int up,
+ int write_back, int unchanging_p, int in_struct_p,
+ int scalar_p)
{
int i = 0, j;
rtx result;
@@ -4455,7 +5235,7 @@ arm_gen_store_multiple (base_regno, count, to, up, write_back, unchanging_p,
/* See arm_gen_load_multiple for discussion of
the pros/cons of ldm/stm usage for XScale. */
- if (arm_is_xscale && count <= 2 && ! optimize_size)
+ if (arm_tune_xscale && count <= 2 && ! optimize_size)
{
rtx seq;
@@ -4505,8 +5285,7 @@ arm_gen_store_multiple (base_regno, count, to, up, write_back, unchanging_p,
}
int
-arm_gen_movstrqi (operands)
- rtx * operands;
+arm_gen_movstrqi (rtx *operands)
{
HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes;
int i;
@@ -4689,8 +5468,7 @@ arm_gen_movstrqi (operands)
known to be alignable and of the form reg, or plus (reg, const). */
rtx
-arm_gen_rotated_half_load (memref)
- rtx memref;
+arm_gen_rotated_half_load (rtx memref)
{
HOST_WIDE_INT offset = 0;
rtx base = XEXP (memref, 0);
@@ -4714,19 +5492,17 @@ arm_gen_rotated_half_load (memref)
return gen_rtx_ROTATE (SImode, base, GEN_INT (16));
}
-/* Select a dominance comparison mode if possible. We support three forms.
- COND_OR == 0 => (X && Y)
- COND_OR == 1 => ((! X( || Y)
- COND_OR == 2 => (X || Y)
- If we are unable to support a dominance comparsison we return CC mode.
- This will then fail to match for the RTL expressions that generate this
- call. */
-
-static enum machine_mode
-select_dominance_cc_mode (x, y, cond_or)
- rtx x;
- rtx y;
- HOST_WIDE_INT cond_or;
+/* Select a dominance comparison mode if possible for a test of the general
+ form (OP (COND_OR (X) (Y)) (const_int 0)). We support three forms.
+ COND_OR == DOM_CC_X_AND_Y => (X && Y)
+ COND_OR == DOM_CC_NX_OR_Y => ((! X) || Y)
+ COND_OR == DOM_CC_X_OR_Y => (X || Y)
+ In all cases OP will be either EQ or NE, but we don't need to know which
+ here. If we are unable to support a dominance comparison we return
+ CC mode. This will then fail to match for the RTL expressions that
+ generate this call. */
+enum machine_mode
+arm_select_dominance_cc_mode (rtx x, rtx y, HOST_WIDE_INT cond_or)
{
enum rtx_code cond1, cond2;
int swapped = 0;
@@ -4743,7 +5519,7 @@ select_dominance_cc_mode (x, y, cond_or)
/* The if_then_else variant of this tests the second condition if the
first passes, but is true if the first fails. Reverse the first
condition to get a true "inclusive-or" expression. */
- if (cond_or == 1)
+ if (cond_or == DOM_CC_NX_OR_Y)
cond1 = reverse_condition (cond1);
/* If the comparisons are not equal, and one doesn't dominate the other,
@@ -4763,7 +5539,7 @@ select_dominance_cc_mode (x, y, cond_or)
switch (cond1)
{
case EQ:
- if (cond2 == EQ || !cond_or)
+ if (cond2 == EQ || cond_or == DOM_CC_X_AND_Y)
return CC_DEQmode;
switch (cond2)
@@ -4778,7 +5554,7 @@ select_dominance_cc_mode (x, y, cond_or)
break;
case LT:
- if (cond2 == LT || !cond_or)
+ if (cond2 == LT || cond_or == DOM_CC_X_AND_Y)
return CC_DLTmode;
if (cond2 == LE)
return CC_DLEmode;
@@ -4787,7 +5563,7 @@ select_dominance_cc_mode (x, y, cond_or)
break;
case GT:
- if (cond2 == GT || !cond_or)
+ if (cond2 == GT || cond_or == DOM_CC_X_AND_Y)
return CC_DGTmode;
if (cond2 == GE)
return CC_DGEmode;
@@ -4796,7 +5572,7 @@ select_dominance_cc_mode (x, y, cond_or)
break;
case LTU:
- if (cond2 == LTU || !cond_or)
+ if (cond2 == LTU || cond_or == DOM_CC_X_AND_Y)
return CC_DLTUmode;
if (cond2 == LEU)
return CC_DLEUmode;
@@ -4805,7 +5581,7 @@ select_dominance_cc_mode (x, y, cond_or)
break;
case GTU:
- if (cond2 == GTU || !cond_or)
+ if (cond2 == GTU || cond_or == DOM_CC_X_AND_Y)
return CC_DGTUmode;
if (cond2 == GEU)
return CC_DGEUmode;
@@ -4838,10 +5614,7 @@ select_dominance_cc_mode (x, y, cond_or)
}
enum machine_mode
-arm_select_cc_mode (op, x, y)
- enum rtx_code op;
- rtx x;
- rtx y;
+arm_select_cc_mode (enum rtx_code op, rtx x, rtx y)
{
/* All floating point compares return CCFP if it is an equality
comparison, and CCFPE otherwise. */
@@ -4865,6 +5638,8 @@ arm_select_cc_mode (op, x, y)
case LE:
case GT:
case GE:
+ if (TARGET_CIRRUS)
+ return CCFPmode;
return CCFPEmode;
default:
@@ -4904,24 +5679,35 @@ arm_select_cc_mode (op, x, y)
|| XEXP (x, 2) == const1_rtx)
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
- return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
- INTVAL (XEXP (x, 2)));
+ return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
+ INTVAL (XEXP (x, 2)));
/* Alternate canonicalizations of the above. These are somewhat cleaner. */
if (GET_CODE (x) == AND
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
- return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 0);
+ return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
+ DOM_CC_X_AND_Y);
if (GET_CODE (x) == IOR
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
- return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 2);
+ return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
+ DOM_CC_X_OR_Y);
+
+ /* An operation (on Thumb) where we want to test for a single bit.
+ This is done by shifting that bit up into the top bit of a
+ scratch register; we can then branch on the sign bit. */
+ if (TARGET_THUMB
+ && GET_MODE (x) == SImode
+ && (op == EQ || op == NE)
+ && (GET_CODE (x) == ZERO_EXTRACT))
+ return CC_Nmode;
/* An operation that sets the condition codes as a side-effect, the
V flag is not set correctly, so we can only use comparisons where
this doesn't matter. (For LT and GE we can use "mi" and "pl"
- instead. */
+ instead.) */
if (GET_MODE (x) == SImode
&& y == const0_rtx
&& (op == EQ || op == NE || op == LT || op == GE)
@@ -4931,7 +5717,8 @@ arm_select_cc_mode (op, x, y)
|| GET_CODE (x) == NOT || GET_CODE (x) == NEG
|| GET_CODE (x) == LSHIFTRT
|| GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
- || GET_CODE (x) == ROTATERT || GET_CODE (x) == ZERO_EXTRACT))
+ || GET_CODE (x) == ROTATERT
+ || (TARGET_ARM && GET_CODE (x) == ZERO_EXTRACT)))
return CC_NOOVmode;
if (GET_MODE (x) == QImode && (op == EQ || op == NE))
@@ -4948,11 +5735,8 @@ arm_select_cc_mode (op, x, y)
/* X and Y are two things to compare using CODE. Emit the compare insn and
return the rtx for register 0 in the proper mode. FP means this is a
floating point compare: I don't think that it is needed on the arm. */
-
rtx
-arm_gen_compare_reg (code, x, y)
- enum rtx_code code;
- rtx x, y;
+arm_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
{
enum machine_mode mode = SELECT_CC_MODE (code, x, y);
rtx cc_reg = gen_rtx_REG (mode, CC_REGNUM);
@@ -4966,9 +5750,8 @@ arm_gen_compare_reg (code, x, y)
/* Generate a sequence of insns that will generate the correct return
address mask depending on the physical architecture that the program
is running on. */
-
rtx
-arm_gen_return_addr_mask ()
+arm_gen_return_addr_mask (void)
{
rtx reg = gen_reg_rtx (Pmode);
@@ -4977,8 +5760,7 @@ arm_gen_return_addr_mask ()
}
void
-arm_reload_in_hi (operands)
- rtx * operands;
+arm_reload_in_hi (rtx *operands)
{
rtx ref = operands[1];
rtx base, scratch;
@@ -5089,16 +5871,14 @@ arm_reload_in_hi (operands)
0))));
}
-/* Handle storing a half-word to memory during reload by synthesising as two
+/* Handle storing a half-word to memory during reload by synthesizing as two
byte stores. Take care not to clobber the input values until after we
have moved them somewhere safe. This code assumes that if the DImode
scratch in operands[2] overlaps either the input value or output address
in some way, then that value must die in this insn (we absolutely need
two scratch registers for some corner cases). */
-
void
-arm_reload_out_hi (operands)
- rtx * operands;
+arm_reload_out_hi (rtx *operands)
{
rtx ref = operands[0];
rtx outval = operands[1];
@@ -5256,11 +6036,8 @@ arm_reload_out_hi (operands)
}
/* Print a symbolic form of X to the debug file, F. */
-
static void
-arm_print_value (f, x)
- FILE * f;
- rtx x;
+arm_print_value (FILE *f, rtx x)
{
switch (GET_CODE (x))
{
@@ -5272,6 +6049,21 @@ arm_print_value (f, x)
fprintf (f, "<0x%lx,0x%lx>", (long)XWINT (x, 2), (long)XWINT (x, 3));
return;
+ case CONST_VECTOR:
+ {
+ int i;
+
+ fprintf (f, "<");
+ for (i = 0; i < CONST_VECTOR_NUNITS (x); i++)
+ {
+ fprintf (f, HOST_WIDE_INT_PRINT_HEX, INTVAL (CONST_VECTOR_ELT (x, i)));
+ if (i < (CONST_VECTOR_NUNITS (x) - 1))
+ fputc (',', f);
+ }
+ fprintf (f, ">");
+ }
+ return;
+
case CONST_STRING:
fprintf (f, "\"%s\"", XSTR (x, 0));
return;
@@ -5392,6 +6184,8 @@ struct minipool_node
rtx value;
/* The mode of value. */
enum machine_mode mode;
+ /* The size of the value. With iWMMXt enabled
+ sizes > 4 also imply an alignment of 8-bytes. */
int fix_size;
};
@@ -5425,10 +6219,8 @@ Mfix * minipool_barrier;
/* Determines if INSN is the start of a jump table. Returns the end
of the TABLE or NULL_RTX. */
-
static rtx
-is_jump_table (insn)
- rtx insn;
+is_jump_table (rtx insn)
{
rtx table;
@@ -5450,8 +6242,7 @@ is_jump_table (insn)
#endif
static HOST_WIDE_INT
-get_jump_table_size (insn)
- rtx insn;
+get_jump_table_size (rtx insn)
{
/* ADDR_VECs only take room if read-only data does into the text
section. */
@@ -5472,13 +6263,10 @@ get_jump_table_size (insn)
/* Move a minipool fix MP from its current location to before MAX_MP.
If MAX_MP is NULL, then MP doesn't need moving, but the addressing
- contrains may need updating. */
-
+ constraints may need updating. */
static Mnode *
-move_minipool_fix_forward_ref (mp, max_mp, max_address)
- Mnode * mp;
- Mnode * max_mp;
- HOST_WIDE_INT max_address;
+move_minipool_fix_forward_ref (Mnode *mp, Mnode *max_mp,
+ HOST_WIDE_INT max_address)
{
/* This should never be true and the code below assumes these are
different. */
@@ -5533,10 +6321,8 @@ move_minipool_fix_forward_ref (mp, max_mp, max_address)
/* Add a constant to the minipool for a forward reference. Returns the
node added or NULL if the constant will not fit in this pool. */
-
static Mnode *
-add_minipool_forward_ref (fix)
- Mfix * fix;
+add_minipool_forward_ref (Mfix *fix)
{
/* If set, max_mp is the first pool_entry that has a lower
constraint than the one we are trying to add. */
@@ -5575,13 +6361,26 @@ add_minipool_forward_ref (fix)
if (max_mp == NULL
&& mp->max_address > max_address)
max_mp = mp;
+
+ /* If we are inserting an 8-bytes aligned quantity and
+ we have not already found an insertion point, then
+ make sure that all such 8-byte aligned quantities are
+ placed at the start of the pool. */
+ if (TARGET_REALLY_IWMMXT
+ && max_mp == NULL
+ && fix->fix_size == 8
+ && mp->fix_size != 8)
+ {
+ max_mp = mp;
+ max_address = mp->max_address;
+ }
}
/* The value is not currently in the minipool, so we need to create
a new entry for it. If MAX_MP is NULL, the entry will be put on
the end of the list since the placement is less constrained than
any existing entry. Otherwise, we insert the new fix before
- MAX_MP and, if neceesary, adjust the constraints on the other
+ MAX_MP and, if necessary, adjust the constraints on the other
entries. */
mp = xmalloc (sizeof (* mp));
mp->fix_size = fix->fix_size;
@@ -5639,10 +6438,8 @@ add_minipool_forward_ref (fix)
}
static Mnode *
-move_minipool_fix_backward_ref (mp, min_mp, min_address)
- Mnode * mp;
- Mnode * min_mp;
- HOST_WIDE_INT min_address;
+move_minipool_fix_backward_ref (Mnode *mp, Mnode *min_mp,
+ HOST_WIDE_INT min_address)
{
HOST_WIDE_INT offset;
@@ -5702,17 +6499,15 @@ move_minipool_fix_backward_ref (mp, min_mp, min_address)
somewhat confusing because the calculated offsets for each fix do
not take into account the size of the pool (which is still under
construction. */
-
static Mnode *
-add_minipool_backward_ref (fix)
- Mfix * fix;
+add_minipool_backward_ref (Mfix *fix)
{
/* If set, min_mp is the last pool_entry that has a lower constraint
than the one we are trying to add. */
- Mnode * min_mp = NULL;
+ Mnode *min_mp = NULL;
/* This can be negative, since it is only a constraint. */
HOST_WIDE_INT min_address = fix->address - fix->backwards;
- Mnode * mp;
+ Mnode *mp;
/* If we can't reach the current pool from this insn, or if we can't
insert this entry at the end of the pool without pushing other
@@ -5752,7 +6547,14 @@ add_minipool_backward_ref (fix)
{
/* Note the insertion point if necessary. */
if (mp->min_address < min_address)
- min_mp = mp;
+ {
+ /* For now, we do not allow the insertion of 8-byte alignment
+ requiring nodes anywhere but at the start of the pool. */
+ if (TARGET_REALLY_IWMMXT && fix->fix_size == 8 && mp->fix_size != 8)
+ return NULL;
+ else
+ min_mp = mp;
+ }
else if (mp->max_address
< minipool_barrier->address + mp->offset + fix->fix_size)
{
@@ -5763,6 +6565,18 @@ add_minipool_backward_ref (fix)
min_mp = mp;
min_address = mp->min_address + fix->fix_size;
}
+ /* If we are inserting an 8-bytes aligned quantity and
+ we have not already found an insertion point, then
+ make sure that all such 8-byte aligned quantities are
+ placed at the start of the pool. */
+ else if (TARGET_REALLY_IWMMXT
+ && min_mp == NULL
+ && fix->fix_size == 8
+ && mp->fix_size < 8)
+ {
+ min_mp = mp;
+ min_address = mp->min_address + fix->fix_size;
+ }
}
}
@@ -5829,11 +6643,10 @@ add_minipool_backward_ref (fix)
}
static void
-assign_minipool_offsets (barrier)
- Mfix * barrier;
+assign_minipool_offsets (Mfix *barrier)
{
HOST_WIDE_INT offset = 0;
- Mnode * mp;
+ Mnode *mp;
minipool_barrier = barrier;
@@ -5848,19 +6661,27 @@ assign_minipool_offsets (barrier)
/* Output the literal table */
static void
-dump_minipool (scan)
- rtx scan;
+dump_minipool (rtx scan)
{
Mnode * mp;
Mnode * nmp;
+ int align64 = 0;
+
+ if (TARGET_REALLY_IWMMXT)
+ for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
+ if (mp->refcount > 0 && mp->fix_size == 8)
+ {
+ align64 = 1;
+ break;
+ }
if (rtl_dump_file)
fprintf (rtl_dump_file,
- ";; Emitting minipool after insn %u; address %ld\n",
- INSN_UID (scan), (unsigned long) minipool_barrier->address);
+ ";; Emitting minipool after insn %u; address %ld; align %d (bytes)\n",
+ INSN_UID (scan), (unsigned long) minipool_barrier->address, align64 ? 8 : 4);
scan = emit_label_after (gen_label_rtx (), scan);
- scan = emit_insn_after (gen_align_4 (), scan);
+ scan = emit_insn_after (align64 ? gen_align_8 () : gen_align_4 (), scan);
scan = emit_label_after (minipool_vector_label, scan);
for (mp = minipool_vector_head; mp != NULL; mp = nmp)
@@ -5919,10 +6740,8 @@ dump_minipool (scan)
}
/* Return the cost of forcibly inserting a barrier after INSN. */
-
static int
-arm_barrier_cost (insn)
- rtx insn;
+arm_barrier_cost (rtx insn)
{
/* Basing the location of the pool on the loop depth is preferable,
but at the moment, the basic block information seems to be
@@ -5956,11 +6775,8 @@ arm_barrier_cost (insn)
(FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
Create the barrier by inserting a jump and add a new fix entry for
it. */
-
static Mfix *
-create_fix_barrier (fix, max_address)
- Mfix * fix;
- HOST_WIDE_INT max_address;
+create_fix_barrier (Mfix *fix, HOST_WIDE_INT max_address)
{
HOST_WIDE_INT count = 0;
rtx barrier;
@@ -6042,9 +6858,7 @@ create_fix_barrier (fix, max_address)
/* Record that there is a natural barrier in the insn stream at
ADDRESS. */
static void
-push_minipool_barrier (insn, address)
- rtx insn;
- HOST_WIDE_INT address;
+push_minipool_barrier (rtx insn, HOST_WIDE_INT address)
{
Mfix * fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* fix));
@@ -6066,17 +6880,13 @@ push_minipool_barrier (insn, address)
fixing; VALUE is the constant that must be loaded, which is of type
MODE. */
static void
-push_minipool_fix (insn, address, loc, mode, value)
- rtx insn;
- HOST_WIDE_INT address;
- rtx * loc;
- enum machine_mode mode;
- rtx value;
+push_minipool_fix (rtx insn, HOST_WIDE_INT address, rtx *loc,
+ enum machine_mode mode, rtx value)
{
Mfix * fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* fix));
#ifdef AOF_ASSEMBLER
- /* PIC symbol refereneces need to be converted into offsets into the
+ /* PIC symbol references need to be converted into offsets into the
based area. */
/* XXX This shouldn't be done here. */
if (flag_pic && GET_CODE (value) == SYMBOL_REF)
@@ -6099,6 +6909,13 @@ push_minipool_fix (insn, address, loc, mode, value)
if (fix->forwards == 0 && fix->backwards == 0)
abort ();
+ /* With iWMMXt enabled, the pool is aligned to an 8-byte boundary.
+ So there might be an empty word before the start of the pool.
+ Hence we reduce the forward range by 4 to allow for this
+ possibility. */
+ if (TARGET_REALLY_IWMMXT && fix->fix_size == 8)
+ fix->forwards -= 4;
+
if (rtl_dump_file)
{
fprintf (rtl_dump_file,
@@ -6121,13 +6938,15 @@ push_minipool_fix (insn, address, loc, mode, value)
minipool_fix_tail = fix;
}
-/* Scan INSN and note any of its operands that need fixing. */
-
-static void
-note_invalid_constants (insn, address)
- rtx insn;
- HOST_WIDE_INT address;
+/* Scan INSN and note any of its operands that need fixing.
+ If DO_PUSHES is false we do not actually push any of the fixups
+ needed. The function returns TRUE is any fixups were needed/pushed.
+ This is used by arm_memory_load_p() which needs to know about loads
+ of constants that will be converted into minipool loads. */
+static bool
+note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
{
+ bool result = false;
int opno;
extract_insn (insn);
@@ -6135,8 +6954,10 @@ note_invalid_constants (insn, address)
if (!constrain_operands (1))
fatal_insn_not_found (insn);
- /* Fill in recog_op_alt with information about the constraints of this
- insn. */
+ if (recog_data.n_alternatives == 0)
+ return false;
+
+ /* Fill in recog_op_alt with information about the constraints of this insn. */
preprocess_constraints ();
for (opno = 0; opno < recog_data.n_operands; opno++)
@@ -6154,32 +6975,47 @@ note_invalid_constants (insn, address)
rtx op = recog_data.operand[opno];
if (CONSTANT_P (op))
- push_minipool_fix (insn, address, recog_data.operand_loc[opno],
- recog_data.operand_mode[opno], op);
-#if 0
- /* RWE: Now we look correctly at the operands for the insn,
- this shouldn't be needed any more. */
-#ifndef AOF_ASSEMBLER
- /* XXX Is this still needed? */
- else if (GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_PIC_SYM)
- push_minipool_fix (insn, address, recog_data.operand_loc[opno],
- recog_data.operand_mode[opno],
- XVECEXP (op, 0, 0));
-#endif
-#endif
+ {
+ if (do_pushes)
+ push_minipool_fix (insn, address, recog_data.operand_loc[opno],
+ recog_data.operand_mode[opno], op);
+ result = true;
+ }
else if (GET_CODE (op) == MEM
&& GET_CODE (XEXP (op, 0)) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (XEXP (op, 0)))
- push_minipool_fix (insn, address, recog_data.operand_loc[opno],
- recog_data.operand_mode[opno],
- get_pool_constant (XEXP (op, 0)));
+ {
+ if (do_pushes)
+ {
+ rtx cop = avoid_constant_pool_reference (op);
+
+ /* Casting the address of something to a mode narrower
+ than a word can cause avoid_constant_pool_reference()
+ to return the pool reference itself. That's no good to
+ us here. Lets just hope that we can use the
+ constant pool value directly. */
+ if (op == cop)
+ cop = get_pool_constant (XEXP (op, 0));
+
+ push_minipool_fix (insn, address,
+ recog_data.operand_loc[opno],
+ recog_data.operand_mode[opno], cop);
+ }
+
+ result = true;
+ }
}
}
+
+ return result;
}
-void
-arm_reorg (first)
- rtx first;
+/* Gcc puts the pool in the wrong place for ARM, since we can only
+ load addresses a limited distance around the pc. We do some
+ special munging to move the constant pool values to the correct
+ point in the code. */
+static void
+arm_reorg (void)
{
rtx insn;
HOST_WIDE_INT address = 0;
@@ -6189,20 +7025,26 @@ arm_reorg (first)
/* The first insn must always be a note, or the code below won't
scan it properly. */
- if (GET_CODE (first) != NOTE)
+ insn = get_insns ();
+ if (GET_CODE (insn) != NOTE)
abort ();
/* Scan all the insns and record the operands that will need fixing. */
- for (insn = next_nonnote_insn (first); insn; insn = next_nonnote_insn (insn))
+ for (insn = next_nonnote_insn (insn); insn; insn = next_nonnote_insn (insn))
{
+ if (TARGET_CIRRUS_FIX_INVALID_INSNS
+ && (arm_cirrus_insn_p (insn)
+ || GET_CODE (insn) == JUMP_INSN
+ || arm_memory_load_p (insn)))
+ cirrus_reorg (insn);
+
if (GET_CODE (insn) == BARRIER)
push_minipool_barrier (insn, address);
- else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
- || GET_CODE (insn) == JUMP_INSN)
+ else if (INSN_P (insn))
{
rtx table;
- note_invalid_constants (insn, address);
+ note_invalid_constants (insn, address, true);
address += get_attr_length (insn);
/* If the insn is a vector jump, add the size of the table
@@ -6336,10 +7178,8 @@ arm_reorg (first)
/* If the rtx is the correct value then return the string of the number.
In this way we can ensure that valid double constants are generated even
when cross compiling. */
-
const char *
-fp_immediate_constant (x)
- rtx x;
+fp_immediate_constant (rtx x)
{
REAL_VALUE_TYPE r;
int i;
@@ -6356,10 +7196,8 @@ fp_immediate_constant (x)
}
/* As for fp_immediate_constant, but value is passed directly, not in rtx. */
-
static const char *
-fp_const_from_val (r)
- REAL_VALUE_TYPE * r;
+fp_const_from_val (REAL_VALUE_TYPE *r)
{
int i;
@@ -6377,13 +7215,8 @@ fp_const_from_val (r)
MASK is the ARM register set mask of which only bits 0-15 are important.
REG is the base register, either the frame pointer or the stack pointer,
INSTR is the possibly suffixed load or store instruction. */
-
static void
-print_multi_reg (stream, instr, reg, mask)
- FILE * stream;
- const char * instr;
- int reg;
- int mask;
+print_multi_reg (FILE *stream, const char *instr, int reg, int mask)
{
int i;
int not_first = FALSE;
@@ -6402,14 +7235,25 @@ print_multi_reg (stream, instr, reg, mask)
not_first = TRUE;
}
- fprintf (stream, "}%s\n", TARGET_APCS_32 ? "" : "^");
+ fprintf (stream, "}");
+
+ /* Add a ^ character for the 26-bit ABI, but only if we were loading
+ the PC. Otherwise we would generate an UNPREDICTABLE instruction.
+ Strictly speaking the instruction would be unpredicatble only if
+ we were writing back the base register as well, but since we never
+ want to generate an LDM type 2 instruction (register bank switching)
+ which is what you get if the PC is not being loaded, we do not need
+ to check for writeback. */
+ if (! TARGET_APCS_32
+ && ((mask & (1 << PC_REGNUM)) != 0))
+ fprintf (stream, "^");
+
+ fprintf (stream, "\n");
}
/* Output a 'call' insn. */
-
const char *
-output_call (operands)
- rtx * operands;
+output_call (rtx *operands)
{
/* Handle calls to lr using ip (which may be clobbered in subr anyway). */
@@ -6430,10 +7274,8 @@ output_call (operands)
}
/* Output a 'call' insn that is a reference in memory. */
-
const char *
-output_call_mem (operands)
- rtx * operands;
+output_call_mem (rtx *operands)
{
if (TARGET_INTERWORK)
{
@@ -6460,13 +7302,11 @@ output_call_mem (operands)
}
-/* Output a move from arm registers to an fpu registers.
- OPERANDS[0] is an fpu register.
+/* Output a move from arm registers to an fpa registers.
+ OPERANDS[0] is an fpa register.
OPERANDS[1] is the first registers of an arm register pair. */
-
const char *
-output_mov_long_double_fpu_from_arm (operands)
- rtx * operands;
+output_mov_long_double_fpa_from_arm (rtx *operands)
{
int arm_reg0 = REGNO (operands[1]);
rtx ops[3];
@@ -6484,13 +7324,11 @@ output_mov_long_double_fpu_from_arm (operands)
return "";
}
-/* Output a move from an fpu register to arm registers.
+/* Output a move from an fpa register to arm registers.
OPERANDS[0] is the first registers of an arm register pair.
- OPERANDS[1] is an fpu register. */
-
+ OPERANDS[1] is an fpa register. */
const char *
-output_mov_long_double_arm_from_fpu (operands)
- rtx * operands;
+output_mov_long_double_arm_from_fpa (rtx *operands)
{
int arm_reg0 = REGNO (operands[0]);
rtx ops[3];
@@ -6510,10 +7348,8 @@ output_mov_long_double_arm_from_fpu (operands)
/* Output a move from arm registers to arm registers of a long double
OPERANDS[0] is the destination.
OPERANDS[1] is the source. */
-
const char *
-output_mov_long_double_arm_from_arm (operands)
- rtx * operands;
+output_mov_long_double_arm_from_arm (rtx *operands)
{
/* We have to be careful here because the two might overlap. */
int dest_start = REGNO (operands[0]);
@@ -6544,13 +7380,11 @@ output_mov_long_double_arm_from_arm (operands)
}
-/* Output a move from arm registers to an fpu registers.
- OPERANDS[0] is an fpu register.
+/* Output a move from arm registers to an fpa registers.
+ OPERANDS[0] is an fpa register.
OPERANDS[1] is the first registers of an arm register pair. */
-
const char *
-output_mov_double_fpu_from_arm (operands)
- rtx * operands;
+output_mov_double_fpa_from_arm (rtx *operands)
{
int arm_reg0 = REGNO (operands[1]);
rtx ops[2];
@@ -6565,13 +7399,11 @@ output_mov_double_fpu_from_arm (operands)
return "";
}
-/* Output a move from an fpu register to arm registers.
+/* Output a move from an fpa register to arm registers.
OPERANDS[0] is the first registers of an arm register pair.
- OPERANDS[1] is an fpu register. */
-
+ OPERANDS[1] is an fpa register. */
const char *
-output_mov_double_arm_from_fpu (operands)
- rtx * operands;
+output_mov_double_arm_from_fpa (rtx *operands)
{
int arm_reg0 = REGNO (operands[0]);
rtx ops[2];
@@ -6589,10 +7421,8 @@ output_mov_double_arm_from_fpu (operands)
/* Output a move between double words.
It must be REG<-REG, REG<-CONST_DOUBLE, REG<-CONST_INT, REG<-MEM
or MEM<-REG and all MEMs must be offsettable addresses. */
-
const char *
-output_move_double (operands)
- rtx * operands;
+output_move_double (rtx *operands)
{
enum rtx_code code0 = GET_CODE (operands[0]);
enum rtx_code code1 = GET_CODE (operands[1]);
@@ -6616,6 +7446,105 @@ output_move_double (operands)
else
output_asm_insn ("mov%?\t%R0, %R1\n\tmov%?\t%Q0, %Q1", operands);
}
+ else if (code1 == CONST_VECTOR)
+ {
+ HOST_WIDE_INT hint = 0;
+
+ switch (GET_MODE (operands[1]))
+ {
+ case V2SImode:
+ otherops[1] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 1)));
+ operands[1] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)));
+ break;
+
+ case V4HImode:
+ if (BYTES_BIG_ENDIAN)
+ {
+ hint = INTVAL (CONST_VECTOR_ELT (operands[1], 2));
+ hint <<= 16;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3));
+ }
+ else
+ {
+ hint = INTVAL (CONST_VECTOR_ELT (operands[1], 3));
+ hint <<= 16;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2));
+ }
+
+ otherops[1] = GEN_INT (hint);
+ hint = 0;
+
+ if (BYTES_BIG_ENDIAN)
+ {
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
+ hint <<= 16;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
+ }
+ else
+ {
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
+ hint <<= 16;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
+ }
+
+ operands[1] = GEN_INT (hint);
+ break;
+
+ case V8QImode:
+ if (BYTES_BIG_ENDIAN)
+ {
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 4));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 5));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 6));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 7));
+ }
+ else
+ {
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 7));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 6));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 5));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 4));
+ }
+
+ otherops[1] = GEN_INT (hint);
+ hint = 0;
+
+ if (BYTES_BIG_ENDIAN)
+ {
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3));
+ }
+ else
+ {
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
+ hint <<= 8;
+ hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
+ }
+
+ operands[1] = GEN_INT (hint);
+ break;
+
+ default:
+ abort ();
+ }
+ output_mov_immediate (operands);
+ output_mov_immediate (otherops);
+ }
else if (code1 == CONST_DOUBLE)
{
if (GET_MODE (operands[1]) == DFmode)
@@ -6715,7 +7644,7 @@ output_move_double (operands)
{
if (GET_CODE (otherops[2]) == CONST_INT)
{
- switch (INTVAL (otherops[2]))
+ switch ((int) INTVAL (otherops[2]))
{
case -8:
output_asm_insn ("ldm%?db\t%1, %M0", otherops);
@@ -6791,7 +7720,7 @@ output_move_double (operands)
case PLUS:
if (GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
{
- switch (INTVAL (XEXP (XEXP (operands[0], 0), 1)))
+ switch ((int) INTVAL (XEXP (XEXP (operands[0], 0), 1)))
{
case -8:
output_asm_insn ("stm%?db\t%m0, %M1", operands);
@@ -6825,10 +7754,8 @@ output_move_double (operands)
/* Output an arbitrary MOV reg, #n.
OPERANDS[0] is a register. OPERANDS[1] is a const_int. */
-
const char *
-output_mov_immediate (operands)
- rtx * operands;
+output_mov_immediate (rtx *operands)
{
HOST_WIDE_INT n = INTVAL (operands[1]);
@@ -6848,9 +7775,9 @@ output_mov_immediate (operands)
int i;
/* If all else fails, make it out of ORRs or BICs as appropriate. */
- for (i = 0; i < 32; i ++)
+ for (i = 0; i < 32; i++)
if (n & 1 << i)
- n_ones ++;
+ n_ones++;
if (n_ones > 16) /* Shorter to use MVN with BIC in this case. */
output_multi_immediate (operands, "mvn%?\t%0, %1", "bic%?\t%0, %0, %1", 1, ~ n);
@@ -6863,10 +7790,8 @@ output_mov_immediate (operands)
/* Output an ADD r, s, #n where n may be too big for one instruction.
If adding zero to one register, output nothing. */
-
const char *
-output_add_immediate (operands)
- rtx * operands;
+output_add_immediate (rtx *operands)
{
HOST_WIDE_INT n = INTVAL (operands[2]);
@@ -6891,14 +7816,9 @@ output_add_immediate (operands)
INSTR2 is the output pattern to use for subsequent constants.
IMMED_OP is the index of the constant slot in OPERANDS.
N is the constant value. */
-
static const char *
-output_multi_immediate (operands, instr1, instr2, immed_op, n)
- rtx * operands;
- const char * instr1;
- const char * instr2;
- int immed_op;
- HOST_WIDE_INT n;
+output_multi_immediate (rtx *operands, const char *instr1, const char *instr2,
+ int immed_op, HOST_WIDE_INT n)
{
#if HOST_BITS_PER_WIDE_INT > 32
n &= 0xffffffff;
@@ -6935,11 +7855,8 @@ output_multi_immediate (operands, instr1, instr2, immed_op, n)
The returned result should not be overwritten. OP is the rtx of the
operation. SHIFT_FIRST_ARG is TRUE if the first argument of the operator
was shifted. */
-
const char *
-arithmetic_instr (op, shift_first_arg)
- rtx op;
- int shift_first_arg;
+arithmetic_instr (rtx op, int shift_first_arg)
{
switch (GET_CODE (op))
{
@@ -6968,11 +7885,8 @@ arithmetic_instr (op, shift_first_arg)
OP is the rtx code of the shift.
On exit, *AMOUNTP will be -1 if the shift is by a register, or a constant
shift. */
-
static const char *
-shift_op (op, amountp)
- rtx op;
- HOST_WIDE_INT *amountp;
+shift_op (rtx op, HOST_WIDE_INT *amountp)
{
const char * mnem;
enum rtx_code code = GET_CODE (op);
@@ -7045,8 +7959,7 @@ shift_op (op, amountp)
/* Obtain the shift from the POWER of two. */
static HOST_WIDE_INT
-int_log2 (power)
- HOST_WIDE_INT power;
+int_log2 (HOST_WIDE_INT power)
{
HOST_WIDE_INT shift = 0;
@@ -7054,7 +7967,7 @@ int_log2 (power)
{
if (shift > 31)
abort ();
- shift ++;
+ shift++;
}
return shift;
@@ -7065,10 +7978,7 @@ int_log2 (power)
#define MAX_ASCII_LEN 51
void
-output_ascii_pseudo_op (stream, p, len)
- FILE * stream;
- const unsigned char * p;
- int len;
+output_ascii_pseudo_op (FILE *stream, const unsigned char *p, int len)
{
int i;
int len_so_far = 0;
@@ -7122,7 +8032,7 @@ output_ascii_pseudo_op (stream, p, len)
case '\\':
putc ('\\', stream);
len_so_far++;
- /* drop through. */
+ /* Drop through. */
default:
if (c >= ' ' && c <= '~')
@@ -7145,9 +8055,8 @@ output_ascii_pseudo_op (stream, p, len)
/* Compute the register sabe mask for registers 0 through 12
inclusive. This code is used by both arm_compute_save_reg_mask
and arm_compute_initial_elimination_offset. */
-
static unsigned long
-arm_compute_save_reg0_reg12_mask ()
+arm_compute_save_reg0_reg12_mask (void)
{
unsigned long func_type = arm_current_func_type ();
unsigned int save_reg_mask = 0;
@@ -7207,7 +8116,7 @@ arm_compute_save_reg0_reg12_mask ()
saved on the stack for the current function. */
static unsigned long
-arm_compute_save_reg_mask ()
+arm_compute_save_reg_mask (void)
{
unsigned int save_reg_mask = 0;
unsigned long func_type = arm_current_func_type ();
@@ -7239,7 +8148,7 @@ arm_compute_save_reg_mask ()
it. If we are pushing other registers onto the stack however, we
can save an instruction in the epilogue by pushing the link register
now and then popping it back into the PC. This incurs extra memory
- accesses though, so we only do it when optimising for size, and only
+ accesses though, so we only do it when optimizing for size, and only
if we know that we will not need a fancy return sequence. */
if (regs_ever_live [LR_REGNUM]
|| (save_reg_mask
@@ -7250,17 +8159,41 @@ arm_compute_save_reg_mask ()
if (cfun->machine->lr_save_eliminated)
save_reg_mask &= ~ (1 << LR_REGNUM);
+ if (TARGET_REALLY_IWMMXT
+ && ((bit_count (save_reg_mask)
+ + ARM_NUM_INTS (current_function_pretend_args_size)) % 2) != 0)
+ {
+ unsigned int reg;
+
+ /* The total number of registers that are going to be pushed
+ onto the stack is odd. We need to ensure that the stack
+ is 64-bit aligned before we start to save iWMMXt registers,
+ and also before we start to create locals. (A local variable
+ might be a double or long long which we will load/store using
+ an iWMMXt instruction). Therefore we need to push another
+ ARM register, so that the stack will be 64-bit aligned. We
+ try to avoid using the arg registers (r0 -r3) as they might be
+ used to pass values in a tail call. */
+ for (reg = 4; reg <= 12; reg++)
+ if ((save_reg_mask & (1 << reg)) == 0)
+ break;
+
+ if (reg <= 12)
+ save_reg_mask |= (1 << reg);
+ else
+ {
+ cfun->machine->sibcall_blocked = 1;
+ save_reg_mask |= (1 << 3);
+ }
+ }
+
return save_reg_mask;
}
-/* Generate a function exit sequence. If REALLY_RETURN is true, then do
+/* Generate a function exit sequence. If REALLY_RETURN is false, then do
everything bar the final return instruction. */
-
const char *
-output_return_instruction (operand, really_return, reverse)
- rtx operand;
- int really_return;
- int reverse;
+output_return_instruction (rtx operand, int really_return, int reverse)
{
char conditional[10];
char instr[100];
@@ -7275,8 +8208,9 @@ output_return_instruction (operand, really_return, reverse)
if (IS_VOLATILE (func_type) && TARGET_ABORT_NORETURN)
{
- /* If this function was declared non-returning, and we have found a tail
- call, then we have to trust that the called function won't return. */
+ /* If this function was declared non-returning, and we have
+ found a tail call, then we have to trust that the called
+ function won't return. */
if (really_return)
{
rtx ops[2];
@@ -7315,15 +8249,25 @@ output_return_instruction (operand, really_return, reverse)
return_reg = reg_names[LR_REGNUM];
if ((live_regs_mask & (1 << IP_REGNUM)) == (1 << IP_REGNUM))
- /* There are two possible reasons for the IP register being saved.
- Either a stack frame was created, in which case IP contains the
- old stack pointer, or an ISR routine corrupted it. If this in an
- ISR routine then just restore IP, otherwise restore IP into SP. */
- if (! IS_INTERRUPT (func_type))
- {
- live_regs_mask &= ~ (1 << IP_REGNUM);
- live_regs_mask |= (1 << SP_REGNUM);
- }
+ {
+ /* There are three possible reasons for the IP register
+ being saved. 1) a stack frame was created, in which case
+ IP contains the old stack pointer, or 2) an ISR routine
+ corrupted it, or 3) it was saved to align the stack on
+ iWMMXt. In case 1, restore IP into SP, otherwise just
+ restore IP. */
+ if (frame_pointer_needed)
+ {
+ live_regs_mask &= ~ (1 << IP_REGNUM);
+ live_regs_mask |= (1 << SP_REGNUM);
+ }
+ else
+ {
+ if (! IS_INTERRUPT (func_type)
+ && ! TARGET_REALLY_IWMMXT)
+ abort ();
+ }
+ }
/* On some ARM architectures it is faster to use LDR rather than
LDM to load a single register. On other architectures, the
@@ -7348,11 +8292,29 @@ output_return_instruction (operand, really_return, reverse)
char *p;
int first = 1;
- /* Generate the load multiple instruction to restore the registers. */
- if (frame_pointer_needed)
- sprintf (instr, "ldm%sea\t%%|fp, {", conditional);
- else if (live_regs_mask & (1 << SP_REGNUM))
- sprintf (instr, "ldm%sfd\t%%|sp, {", conditional);
+ /* Generate the load multiple instruction to restore the
+ registers. Note we can get here, even if
+ frame_pointer_needed is true, but only if sp already
+ points to the base of the saved core registers. */
+ if (live_regs_mask & (1 << SP_REGNUM))
+ {
+ unsigned HOST_WIDE_INT stack_adjust =
+ arm_get_frame_size () + current_function_outgoing_args_size;
+
+ if (stack_adjust != 0 && stack_adjust != 4)
+ abort ();
+
+ if (stack_adjust && arm_arch5)
+ sprintf (instr, "ldm%sib\t%%|sp, {", conditional);
+ else
+ {
+ /* If we can't use ldmib (SA110 bug), then try to pop r3
+ instead. */
+ if (stack_adjust)
+ live_regs_mask |= 1 << 3;
+ sprintf (instr, "ldm%sfd\t%%|sp, {", conditional);
+ }
+ }
else
sprintf (instr, "ldm%sfd\t%%|sp!, {", conditional);
@@ -7378,20 +8340,22 @@ output_return_instruction (operand, really_return, reverse)
if (live_regs_mask & (1 << LR_REGNUM))
{
- int l = strlen (return_reg);
-
- if (! first)
- {
- memcpy (p, ", ", 2);
- p += 2;
- }
-
- memcpy (p, "%|", 2);
- memcpy (p + 2, return_reg, l);
- strcpy (p + 2 + l, ((TARGET_APCS_32
- && !IS_INTERRUPT (func_type))
- || !really_return)
- ? "}" : "}^");
+ sprintf (p, "%s%%|%s}", first ? "" : ", ", return_reg);
+ /* Decide if we need to add the ^ symbol to the end of the
+ register list. This causes the saved condition codes
+ register to be copied into the current condition codes
+ register. We do the copy if we are conforming to the 32-bit
+ ABI and this is an interrupt function, or if we are
+ conforming to the 26-bit ABI. There is a special case for
+ the 26-bit ABI however, which is if we are writing back the
+ stack pointer but not loading the PC. In this case adding
+ the ^ symbol would create a type 2 LDM instruction, where
+ writeback is UNPREDICTABLE. We are safe in leaving the ^
+ character off in this case however, since the actual return
+ instruction will be a MOVS which will restore the CPSR. */
+ if ((TARGET_APCS_32 && IS_INTERRUPT (func_type))
+ || (! TARGET_APCS_32 && really_return))
+ strcat (p, "^");
}
else
strcpy (p, "}");
@@ -7471,18 +8435,15 @@ output_return_instruction (operand, really_return, reverse)
a leaf function. These function types will not contain a stack
backtrace structure, therefore it is not possible to determine the
function name. */
-
void
-arm_poke_function_name (stream, name)
- FILE * stream;
- const char * name;
+arm_poke_function_name (FILE *stream, const char *name)
{
unsigned long alignlength;
unsigned long length;
rtx x;
length = strlen (name) + 1;
- alignlength = ROUND_UP (length);
+ alignlength = ROUND_UP_WORD (length);
ASM_OUTPUT_ASCII (stream, name, length);
ASM_OUTPUT_ALIGN (stream, 2);
@@ -7492,11 +8453,8 @@ arm_poke_function_name (stream, name)
/* Place some comments into the assembler stream
describing the current function. */
-
static void
-arm_output_function_prologue (f, frame_size)
- FILE * f;
- HOST_WIDE_INT frame_size;
+arm_output_function_prologue (FILE *f, HOST_WIDE_INT frame_size)
{
unsigned long func_type;
@@ -7543,7 +8501,7 @@ arm_output_function_prologue (f, frame_size)
if (IS_NESTED (func_type))
asm_fprintf (f, "\t%@ Nested: function declared inside another function.\n");
- asm_fprintf (f, "\t%@ args = %d, pretend = %d, frame = %d\n",
+ asm_fprintf (f, "\t%@ args = %d, pretend = %d, frame = %wd\n",
current_function_args_size,
current_function_pretend_args_size, frame_size);
@@ -7563,8 +8521,7 @@ arm_output_function_prologue (f, frame_size)
}
const char *
-arm_output_epilogue (really_return)
- int really_return;
+arm_output_epilogue (rtx sibling)
{
int reg;
unsigned long saved_regs_mask;
@@ -7576,10 +8533,12 @@ arm_output_epilogue (really_return)
int frame_size = arm_get_frame_size ();
FILE * f = asm_out_file;
rtx eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
+ unsigned int lrm_count = 0;
+ int really_return = (sibling == NULL);
/* If we have already generated the return instruction
then it is futile to generate anything else. */
- if (use_return_insn (FALSE) && return_used_this_function)
+ if (use_return_insn (FALSE, sibling) && return_used_this_function)
return "";
func_type = arm_current_func_type ();
@@ -7607,12 +8566,15 @@ arm_output_epilogue (really_return)
abort ();
saved_regs_mask = arm_compute_save_reg_mask ();
-
+
+ if (TARGET_IWMMXT)
+ lrm_count = bit_count (saved_regs_mask);
+
/* XXX We should adjust floats_offset for any anonymous args, and then
re-adjust vfp_offset below to compensate. */
/* Compute how far away the floats will be. */
- for (reg = 0; reg <= LAST_ARM_REGNUM; reg ++)
+ for (reg = 0; reg <= LAST_ARM_REGNUM; reg++)
if (saved_regs_mask & (1 << reg))
floats_offset += 4;
@@ -7620,7 +8582,7 @@ arm_output_epilogue (really_return)
{
int vfp_offset = 4;
- if (arm_fpu_arch == FP_SOFT2)
+ if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
{
for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
if (regs_ever_live[reg] && !call_used_regs[reg])
@@ -7665,6 +8627,26 @@ arm_output_epilogue (really_return)
FP_REGNUM, floats_offset - vfp_offset);
}
+ if (TARGET_IWMMXT)
+ {
+ /* The frame pointer is guaranteed to be non-double-word aligned.
+ This is because it is set to (old_stack_pointer - 4) and the
+ old_stack_pointer was double word aligned. Thus the offset to
+ the iWMMXt registers to be loaded must also be non-double-word
+ sized, so that the resultant address *is* double-word aligned.
+ We can ignore floats_offset since that was already included in
+ the live_regs_mask. */
+ lrm_count += (lrm_count % 2 ? 2 : 1);
+
+ for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
+ if (regs_ever_live[reg] && !call_used_regs[reg])
+ {
+ asm_fprintf (f, "\twldrd\t%r, [%r, #-%d]\n",
+ reg, FP_REGNUM, lrm_count * 4);
+ lrm_count += 2;
+ }
+ }
+
/* saved_regs_mask should contain the IP, which at the time of stack
frame generation actually contains the old stack pointer. So a
quick way to unwind the stack is just pop the IP register directly
@@ -7684,8 +8666,22 @@ arm_output_epilogue (really_return)
saved_regs_mask &= ~ (1 << LR_REGNUM);
else
saved_regs_mask &= ~ (1 << PC_REGNUM);
-
- print_multi_reg (f, "ldmea\t%r", FP_REGNUM, saved_regs_mask);
+
+ /* We must use SP as the base register, because SP is one of the
+ registers being restored. If an interrupt or page fault
+ happens in the ldm instruction, the SP might or might not
+ have been restored. That would be bad, as then SP will no
+ longer indicate the safe area of stack, and we can get stack
+ corruption. Using SP as the base register means that it will
+ be reset correctly to the original value, should an interrupt
+ occur. If the stack pointer already points at the right
+ place, then omit the subtraction. */
+ if (((frame_size + current_function_outgoing_args_size + floats_offset)
+ != 4 * (1 + (int) bit_count (saved_regs_mask)))
+ || current_function_calls_alloca)
+ asm_fprintf (f, "\tsub\t%r, %r, #%d\n", SP_REGNUM, FP_REGNUM,
+ 4 * bit_count (saved_regs_mask));
+ print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
if (IS_INTERRUPT (func_type))
/* Interrupt handlers will have pushed the
@@ -7703,7 +8699,7 @@ arm_output_epilogue (really_return)
output_add_immediate (operands);
}
- if (arm_fpu_arch == FP_SOFT2)
+ if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
{
for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg++)
if (regs_ever_live[reg] && !call_used_regs[reg])
@@ -7742,6 +8738,11 @@ arm_output_epilogue (really_return)
start_reg, reg - start_reg, SP_REGNUM);
}
+ if (TARGET_IWMMXT)
+ for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
+ if (regs_ever_live[reg] && !call_used_regs[reg])
+ asm_fprintf (f, "\twldrd\t%r, [%r, #+8]!\n", reg, SP_REGNUM);
+
/* If we can, restore the LR into the PC. */
if (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
&& really_return
@@ -7784,13 +8785,6 @@ arm_output_epilogue (really_return)
}
}
-#if 0
- if (ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER)
- /* Adjust the stack to remove the exception handler stuff. */
- asm_fprintf (f, "\tadd\t%r, %r, %r\n", SP_REGNUM, SP_REGNUM,
- REGNO (eh_ofs));
-#endif
-
if (! really_return
|| (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
&& current_function_pretend_args_size == 0
@@ -7842,9 +8836,8 @@ arm_output_epilogue (really_return)
}
static void
-arm_output_function_epilogue (file, frame_size)
- FILE *file ATTRIBUTE_UNUSED;
- HOST_WIDE_INT frame_size;
+arm_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT frame_size)
{
if (TARGET_THUMB)
{
@@ -7858,7 +8851,7 @@ arm_output_function_epilogue (file, frame_size)
/* We need to take into account any stack-frame rounding. */
frame_size = arm_get_frame_size ();
- if (use_return_insn (FALSE)
+ if (use_return_insn (FALSE, NULL)
&& return_used_this_function
&& (frame_size + current_function_outgoing_args_size) != 0
&& !frame_pointer_needed)
@@ -7873,10 +8866,8 @@ arm_output_function_epilogue (file, frame_size)
Unfortunately, since this insn does not reflect very well the actual
semantics of the operation, we need to annotate the insn for the benefit
of DWARF2 frame unwind information. */
-
static rtx
-emit_multi_reg_push (mask)
- int mask;
+emit_multi_reg_push (int mask)
{
int num_regs = 0;
int num_dwarf_regs;
@@ -8002,9 +8993,7 @@ emit_multi_reg_push (mask)
}
static rtx
-emit_sfm (base_reg, count)
- int base_reg;
- int count;
+emit_sfm (int base_reg, int count)
{
rtx par;
rtx dwarf;
@@ -8094,11 +9083,8 @@ emit_sfm (base_reg, count)
The sign of the number returned reflects the direction of stack
growth, so the values are positive for all eliminations except
from the soft frame pointer to the hard frame pointer. */
-
unsigned int
-arm_compute_initial_elimination_offset (from, to)
- unsigned int from;
- unsigned int to;
+arm_compute_initial_elimination_offset (unsigned int from, unsigned int to)
{
unsigned int local_vars = arm_get_frame_size ();
unsigned int outgoing_args = current_function_outgoing_args_size;
@@ -8118,34 +9104,32 @@ arm_compute_initial_elimination_offset (from, to)
/* Make sure that we compute which registers will be saved
on the stack using the same algorithm that is used by
- arm_compute_save_reg_mask(). */
- reg_mask = arm_compute_save_reg0_reg12_mask ();
+ the prologue creation code. */
+ reg_mask = arm_compute_save_reg_mask ();
/* Now count the number of bits set in save_reg_mask.
- For each set bit we need 4 bytes of stack space. */
- while (reg_mask)
- {
- call_saved_registers += 4;
- reg_mask = reg_mask & ~ (reg_mask & - reg_mask);
- }
-
- if ((regs_ever_live[LR_REGNUM]
- /* If optimizing for size, then we save the link register if
- any other integer register is saved. This gives a smaller
- return sequence. */
- || (optimize_size && call_saved_registers > 0))
- /* But if a stack frame is going to be created, the LR will
- be saved as part of that, so we do not need to allow for
- it here. */
- && ! frame_pointer_needed)
- call_saved_registers += 4;
+ If we have already counted the registers in the stack
+ frame, do not count them again. Non call-saved registers
+ might be saved in the call-save area of the stack, if
+ doing so will preserve the stack's alignment. Hence we
+ must count them here. For each set bit we need 4 bytes
+ of stack space. */
+ if (frame_pointer_needed)
+ reg_mask &= 0x07ff;
+ call_saved_registers += 4 * bit_count (reg_mask);
/* If the hard floating point registers are going to be
used then they must be saved on the stack as well.
Each register occupies 12 bytes of stack space. */
- for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg ++)
+ for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg++)
if (regs_ever_live[reg] && ! call_used_regs[reg])
call_saved_registers += 12;
+
+ if (TARGET_REALLY_IWMMXT)
+ /* Check for the call-saved iWMMXt registers. */
+ for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
+ if (regs_ever_live[reg] && ! call_used_regs [reg])
+ call_saved_registers += 8;
}
/* The stack frame contains 4 registers - the old frame pointer,
@@ -8227,13 +9211,12 @@ arm_compute_initial_elimination_offset (from, to)
/* Calculate the size of the stack frame, taking into account any
padding that is required to ensure stack-alignment. */
-
HOST_WIDE_INT
-arm_get_frame_size ()
+arm_get_frame_size (void)
{
int regno;
- int base_size = ROUND_UP (get_frame_size ());
+ int base_size = ROUND_UP_WORD (get_frame_size ());
int entry_size = 0;
unsigned long func_type = arm_current_func_type ();
int leaf;
@@ -8288,6 +9271,14 @@ arm_get_frame_size ()
entry_size += 12;
}
+ if (TARGET_REALLY_IWMMXT)
+ {
+ /* Check for the call-saved iWMMXt registers. */
+ for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++)
+ if (regs_ever_live [regno] && ! call_used_regs [regno])
+ entry_size += 8;
+ }
+
if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
base_size += 4;
if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
@@ -8299,9 +9290,8 @@ arm_get_frame_size ()
}
/* Generate the prologue instructions for entry into an ARM function. */
-
void
-arm_expand_prologue ()
+arm_expand_prologue (void)
{
int reg;
rtx amount;
@@ -8460,12 +9450,24 @@ arm_expand_prologue ()
RTX_FRAME_RELATED_P (insn) = 1;
}
+ if (TARGET_IWMMXT)
+ for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
+ if (regs_ever_live[reg] && ! call_used_regs [reg])
+ {
+ insn = gen_rtx_PRE_DEC (V2SImode, stack_pointer_rtx);
+ insn = gen_rtx_MEM (V2SImode, insn);
+ insn = emit_insn (gen_rtx_SET (VOIDmode, insn,
+ gen_rtx_REG (V2SImode, reg)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
+
if (! IS_VOLATILE (func_type))
{
- /* Save any floating point call-saved registers used by this function. */
- if (arm_fpu_arch == FP_SOFT2)
+ /* Save any floating point call-saved registers used by this
+ function. */
+ if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
{
- for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg --)
+ for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
if (regs_ever_live[reg] && !call_used_regs[reg])
{
insn = gen_rtx_PRE_DEC (XFmode, stack_pointer_rtx);
@@ -8479,7 +9481,7 @@ arm_expand_prologue ()
{
int start_reg = LAST_ARM_FP_REGNUM;
- for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg --)
+ for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
{
if (regs_ever_live[reg] && !call_used_regs[reg])
{
@@ -8524,7 +9526,8 @@ arm_expand_prologue ()
insn = gen_rtx_REG (SImode, 3);
else /* if (current_function_pretend_args_size == 0) */
{
- insn = gen_rtx_PLUS (SImode, hard_frame_pointer_rtx, GEN_INT (4));
+ insn = gen_rtx_PLUS (SImode, hard_frame_pointer_rtx,
+ GEN_INT (4));
insn = gen_rtx_MEM (SImode, insn);
}
@@ -8587,12 +9590,8 @@ arm_expand_prologue ()
before output.
If CODE is 'B' then output a bitwise inverted value of X (a const int).
If X is a REG and CODE is `M', output a ldm/stm style multi-reg. */
-
void
-arm_print_operand (stream, x, code)
- FILE * stream;
- rtx x;
- int code;
+arm_print_operand (FILE *stream, rtx x, int code)
{
switch (code)
{
@@ -8655,6 +9654,16 @@ arm_print_operand (stream, x, code)
fprintf (stream, "%s", arithmetic_instr (x, 1));
return;
+ /* Truncate Cirrus shift counts. */
+ case 's':
+ if (GET_CODE (x) == CONST_INT)
+ {
+ fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0x3f);
+ return;
+ }
+ arm_print_operand (stream, x, 0);
+ return;
+
case 'I':
fprintf (stream, "%s", arithmetic_instr (x, 0));
return;
@@ -8670,10 +9679,7 @@ arm_print_operand (stream, x, code)
if (val == -1)
arm_print_operand (stream, XEXP (x, 1), 0);
else
- {
- fputc ('#', stream);
- fprintf (stream, HOST_WIDE_INT_PRINT_DEC, val);
- }
+ fprintf (stream, "#" HOST_WIDE_INT_PRINT_DEC, val);
}
}
return;
@@ -8682,13 +9688,13 @@ arm_print_operand (stream, x, code)
In a pair of registers containing a DI or DF value the 'Q'
operand returns the register number of the register containing
- the least signficant part of the value. The 'R' operand returns
+ the least significant part of the value. The 'R' operand returns
the register number of the register containing the most
significant part of the value.
The 'H' operand returns the higher of the two register numbers.
On a run where WORDS_BIG_ENDIAN is true the 'H' operand is the
- same as the 'Q' operand, since the most signficant part of the
+ same as the 'Q' operand, since the most significant part of the
value is held in the lower number register. The reverse is true
on systems where WORDS_BIG_ENDIAN is false.
@@ -8740,11 +9746,8 @@ arm_print_operand (stream, x, code)
if (x == const_true_rtx)
return;
- if (TARGET_ARM)
- fputs (arm_condition_codes[get_arm_condition_code (x)],
- stream);
- else
- fputs (thumb_condition_code (x, 0), stream);
+ fputs (arm_condition_codes[get_arm_condition_code (x)],
+ stream);
return;
case 'D':
@@ -8753,12 +9756,76 @@ arm_print_operand (stream, x, code)
if (x == const_true_rtx)
abort ();
- if (TARGET_ARM)
- fputs (arm_condition_codes[ARM_INVERSE_CONDITION_CODE
- (get_arm_condition_code (x))],
- stream);
+ fputs (arm_condition_codes[ARM_INVERSE_CONDITION_CODE
+ (get_arm_condition_code (x))],
+ stream);
+ return;
+
+ /* Cirrus registers can be accessed in a variety of ways:
+ single floating point (f)
+ double floating point (d)
+ 32bit integer (fx)
+ 64bit integer (dx). */
+ case 'W': /* Cirrus register in F mode. */
+ case 'X': /* Cirrus register in D mode. */
+ case 'Y': /* Cirrus register in FX mode. */
+ case 'Z': /* Cirrus register in DX mode. */
+ if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != CIRRUS_REGS)
+ abort ();
+
+ fprintf (stream, "mv%s%s",
+ code == 'W' ? "f"
+ : code == 'X' ? "d"
+ : code == 'Y' ? "fx" : "dx", reg_names[REGNO (x)] + 2);
+
+ return;
+
+ /* Print cirrus register in the mode specified by the register's mode. */
+ case 'V':
+ {
+ int mode = GET_MODE (x);
+
+ if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != CIRRUS_REGS)
+ abort ();
+
+ fprintf (stream, "mv%s%s",
+ mode == DFmode ? "d"
+ : mode == SImode ? "fx"
+ : mode == DImode ? "dx"
+ : "f", reg_names[REGNO (x)] + 2);
+
+ return;
+ }
+
+ case 'U':
+ if (GET_CODE (x) != REG
+ || REGNO (x) < FIRST_IWMMXT_GR_REGNUM
+ || REGNO (x) > LAST_IWMMXT_GR_REGNUM)
+ /* Bad value for wCG register number. */
+ abort ();
+ else
+ fprintf (stream, "%d", REGNO (x) - FIRST_IWMMXT_GR_REGNUM);
+ return;
+
+ /* Print an iWMMXt control register name. */
+ case 'w':
+ if (GET_CODE (x) != CONST_INT
+ || INTVAL (x) < 0
+ || INTVAL (x) >= 16)
+ /* Bad value for wC register number. */
+ abort ();
else
- fputs (thumb_condition_code (x, 1), stream);
+ {
+ static const char * wc_reg_names [16] =
+ {
+ "wCID", "wCon", "wCSSF", "wCASF",
+ "wC4", "wC5", "wC6", "wC7",
+ "wCGR0", "wCGR1", "wCGR2", "wCGR3",
+ "wC12", "wC13", "wC14", "wC15"
+ };
+
+ fprintf (stream, wc_reg_names [INTVAL (x)]);
+ }
return;
default:
@@ -8787,12 +9854,8 @@ arm_print_operand (stream, x, code)
#ifndef AOF_ASSEMBLER
/* Target hook for assembling integer objects. The ARM version needs to
handle word-sized values specially. */
-
static bool
-arm_assemble_integer (x, size, aligned_p)
- rtx x;
- unsigned int size;
- int aligned_p;
+arm_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
if (size == UNITS_PER_WORD && aligned_p)
{
@@ -8800,13 +9863,13 @@ arm_assemble_integer (x, size, aligned_p)
output_addr_const (asm_out_file, x);
/* Mark symbols as position independent. We only do this in the
- .text segment, not in the .data segment. */
+ .text segment, not in the .data segment. */
if (NEED_GOT_RELOC && flag_pic && making_const_table &&
(GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
{
if (GET_CODE (x) == SYMBOL_REF
&& (CONSTANT_POOL_ADDRESS_P (x)
- || ENCODED_SHORT_CALL_ATTR_P (XSTR (x, 0))))
+ || SYMBOL_REF_LOCAL_P (x)))
fputs ("(GOTOFF)", asm_out_file);
else if (GET_CODE (x) == LABEL_REF)
fputs ("(GOTOFF)", asm_out_file);
@@ -8817,6 +9880,36 @@ arm_assemble_integer (x, size, aligned_p)
return true;
}
+ if (VECTOR_MODE_SUPPORTED_P (GET_MODE (x)))
+ {
+ int i, units;
+
+ if (GET_CODE (x) != CONST_VECTOR)
+ abort ();
+
+ units = CONST_VECTOR_NUNITS (x);
+
+ switch (GET_MODE (x))
+ {
+ case V2SImode: size = 4; break;
+ case V4HImode: size = 2; break;
+ case V8QImode: size = 1; break;
+ default:
+ abort ();
+ }
+
+ for (i = 0; i < units; i++)
+ {
+ rtx elt;
+
+ elt = CONST_VECTOR_ELT (x, i);
+ assemble_integer
+ (elt, size, i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT, 1);
+ }
+
+ return true;
+ }
+
return default_assemble_integer (x, size, aligned_p);
}
#endif
@@ -8838,7 +9931,7 @@ arm_assemble_integer (x, size, aligned_p)
0 -> 2 final_prescan_insn if the `target' is an unconditional branch
1 -> 3 ASM_OUTPUT_OPCODE after not having output the conditional branch
2 -> 4 ASM_OUTPUT_OPCODE after not having output the conditional branch
- 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL if the `target' label is reached
+ 3 -> 0 (*targetm.asm_out.internal_label) if the `target' label is reached
(the target label has CODE_LABEL_NUMBER equal to arm_target_label).
4 -> 0 final_prescan_insn if the `target' unconditional branch is reached
(the target insn is arm_target_insn).
@@ -8855,10 +9948,8 @@ arm_assemble_integer (x, size, aligned_p)
/* Returns the index of the ARM condition code string in
`arm_condition_codes'. COMPARISON should be an rtx like
`(eq (...) (...))'. */
-
static enum arm_cond_code
-get_arm_condition_code (comparison)
- rtx comparison;
+get_arm_condition_code (rtx comparison)
{
enum machine_mode mode = GET_MODE (XEXP (comparison, 0));
int code;
@@ -8907,6 +9998,14 @@ get_arm_condition_code (comparison)
default: abort ();
}
+ case CC_Nmode:
+ switch (comp_code)
+ {
+ case NE: return ARM_MI;
+ case EQ: return ARM_PL;
+ default: abort ();
+ }
+
case CCFPEmode:
case CCFPmode:
/* These encodings assume that AC=1 in the FPA system control
@@ -8978,10 +10077,8 @@ get_arm_condition_code (comparison)
abort ();
}
-
void
-arm_final_prescan_insn (insn)
- rtx insn;
+arm_final_prescan_insn (rtx insn)
{
/* BODY will hold the body of INSN. */
rtx body = PATTERN (insn);
@@ -9065,15 +10162,6 @@ arm_final_prescan_insn (insn)
if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
body = XVECEXP (body, 0, 0);
-#if 0
- /* If this is a conditional return then we don't want to know */
- if (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
- && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
- && (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN
- || GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN))
- return;
-#endif
-
if (reverse
|| (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
&& GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
@@ -9201,7 +10289,8 @@ arm_final_prescan_insn (insn)
/* If this is an unconditional branch to the same label, succeed.
If it is to another label, do nothing. If it is conditional,
fail. */
- /* XXX Probably, the tests for SET and the PC are unnecessary. */
+ /* XXX Probably, the tests for SET and the PC are
+ unnecessary. */
scanbody = PATTERN (this_insn);
if (GET_CODE (scanbody) == SET
@@ -9219,7 +10308,7 @@ arm_final_prescan_insn (insn)
/* Fail if a conditional return is undesirable (eg on a
StrongARM), but still allow this if optimizing for size. */
else if (GET_CODE (scanbody) == RETURN
- && !use_return_insn (TRUE)
+ && !use_return_insn (TRUE, NULL)
&& !optimize_size)
fail = TRUE;
else if (GET_CODE (scanbody) == RETURN
@@ -9252,6 +10341,18 @@ arm_final_prescan_insn (insn)
|| GET_CODE (scanbody) == PARALLEL)
|| get_attr_conds (this_insn) != CONDS_NOCOND)
fail = TRUE;
+
+ /* A conditional cirrus instruction must be followed by
+ a non Cirrus instruction. However, since we
+ conditionalize instructions in this function and by
+ the time we get here we can't add instructions
+ (nops), because shorten_branches() has already been
+ called, we will disable conditionalizing Cirrus
+ instructions to be safe. */
+ if (GET_CODE (scanbody) != USE
+ && GET_CODE (scanbody) != CLOBBER
+ && get_attr_cirrus (this_insn) != CIRRUS_NOT)
+ fail = TRUE;
break;
default:
@@ -9273,7 +10374,7 @@ arm_final_prescan_insn (insn)
}
if (!this_insn)
{
- /* Oh, dear! we ran off the end.. give up */
+ /* Oh, dear! we ran off the end.. give up. */
recog (PATTERN (insn), insn, NULL);
arm_ccfsm_state = 0;
arm_target_insn = NULL;
@@ -9318,11 +10419,8 @@ arm_final_prescan_insn (insn)
/* Returns true if REGNO is a valid register
for holding a quantity of tyoe MODE. */
-
int
-arm_hard_regno_mode_ok (regno, mode)
- unsigned int regno;
- enum machine_mode mode;
+arm_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
{
if (GET_MODE_CLASS (mode) == MODE_CC)
return regno == CC_REGNUM;
@@ -9335,8 +10433,22 @@ arm_hard_regno_mode_ok (regno, mode)
start of an even numbered register pair. */
return (ARM_NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM);
+ if (IS_CIRRUS_REGNUM (regno))
+ /* We have outlawed SI values in Cirrus registers because they
+ reside in the lower 32 bits, but SF values reside in the
+ upper 32 bits. This causes gcc all sorts of grief. We can't
+ even split the registers into pairs because Cirrus SI values
+ get sign extended to 64bits-- aldyh. */
+ return (GET_MODE_CLASS (mode) == MODE_FLOAT) || (mode == DImode);
+
+ if (IS_IWMMXT_GR_REGNUM (regno))
+ return mode == SImode;
+
+ if (IS_IWMMXT_REGNUM (regno))
+ return VALID_IWMMXT_REG_MODE (mode);
+
if (regno <= LAST_ARM_REGNUM)
- /* We allow any value to be stored in the general regisetrs. */
+ /* We allow any value to be stored in the general registers. */
return 1;
if ( regno == FRAME_POINTER_REGNUM
@@ -9344,7 +10456,7 @@ arm_hard_regno_mode_ok (regno, mode)
/* We only allow integers in the fake hard registers. */
return GET_MODE_CLASS (mode) == MODE_INT;
- /* The only registers left are the FPU registers
+ /* The only registers left are the FPA registers
which we only allow to hold FP values. */
return GET_MODE_CLASS (mode) == MODE_FLOAT
&& regno >= FIRST_ARM_FP_REGNUM
@@ -9352,8 +10464,7 @@ arm_hard_regno_mode_ok (regno, mode)
}
int
-arm_regno_class (regno)
- int regno;
+arm_regno_class (int regno)
{
if (TARGET_THUMB)
{
@@ -9374,16 +10485,22 @@ arm_regno_class (regno)
if (regno == CC_REGNUM)
return NO_REGS;
- return FPU_REGS;
+ if (IS_CIRRUS_REGNUM (regno))
+ return CIRRUS_REGS;
+
+ if (IS_IWMMXT_REGNUM (regno))
+ return IWMMXT_REGS;
+
+ if (IS_IWMMXT_GR_REGNUM (regno))
+ return IWMMXT_GR_REGS;
+
+ return FPA_REGS;
}
/* Handle a special case when computing the offset
of an argument from the frame pointer. */
-
int
-arm_debugger_arg_offset (value, addr)
- int value;
- rtx addr;
+arm_debugger_arg_offset (int value, rtx addr)
{
rtx insn;
@@ -9434,7 +10551,7 @@ arm_debugger_arg_offset (value, addr)
which is the frame pointer
a constant integer
- then... */
+ then... */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
@@ -9462,30 +10579,568 @@ arm_debugger_arg_offset (value, addr)
return value;
}
+
+#define def_mbuiltin(MASK, NAME, TYPE, CODE) \
+ do \
+ { \
+ if ((MASK) & insn_flags) \
+ builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE); \
+ } \
+ while (0)
+
+struct builtin_description
+{
+ const unsigned int mask;
+ const enum insn_code icode;
+ const char * const name;
+ const enum arm_builtins code;
+ const enum rtx_code comparison;
+ const unsigned int flag;
+};
-#define def_builtin(NAME, TYPE, CODE) \
- builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE)
+static const struct builtin_description bdesc_2arg[] =
+{
+#define IWMMXT_BUILTIN(code, string, builtin) \
+ { FL_IWMMXT, CODE_FOR_##code, "__builtin_arm_" string, \
+ ARM_BUILTIN_##builtin, 0, 0 },
+
+ IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB)
+ IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH)
+ IWMMXT_BUILTIN (addv2si3, "waddw", WADDW)
+ IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB)
+ IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH)
+ IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW)
+ IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB)
+ IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH)
+ IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW)
+ IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB)
+ IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH)
+ IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW)
+ IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB)
+ IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH)
+ IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW)
+ IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB)
+ IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH)
+ IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW)
+ IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL)
+ IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsh", WMULSH)
+ IWMMXT_BUILTIN (umulv4hi3_highpart, "wmuluh", WMULUH)
+ IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB)
+ IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH)
+ IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW)
+ IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB)
+ IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH)
+ IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW)
+ IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB)
+ IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH)
+ IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW)
+ IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB)
+ IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB)
+ IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH)
+ IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH)
+ IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW)
+ IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW)
+ IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB)
+ IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB)
+ IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH)
+ IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH)
+ IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW)
+ IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW)
+ IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND)
+ IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN)
+ IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR)
+ IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR)
+ IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B)
+ IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H)
+ IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR)
+ IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR)
+ IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB)
+ IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH)
+ IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW)
+ IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB)
+ IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH)
+ IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW)
+ IWMMXT_BUILTIN (iwmmxt_wmadds, "wmadds", WMADDS)
+ IWMMXT_BUILTIN (iwmmxt_wmaddu, "wmaddu", WMADDU)
+
+#define IWMMXT_BUILTIN2(code, builtin) \
+ { FL_IWMMXT, CODE_FOR_##code, NULL, ARM_BUILTIN_##builtin, 0, 0 },
+
+ IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS)
+ IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS)
+ IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS)
+ IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS)
+ IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS)
+ IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
+ IWMMXT_BUILTIN2 (ashlv4hi3_di, WSLLH)
+ IWMMXT_BUILTIN2 (ashlv4hi3, WSLLHI)
+ IWMMXT_BUILTIN2 (ashlv2si3_di, WSLLW)
+ IWMMXT_BUILTIN2 (ashlv2si3, WSLLWI)
+ IWMMXT_BUILTIN2 (ashldi3_di, WSLLD)
+ IWMMXT_BUILTIN2 (ashldi3_iwmmxt, WSLLDI)
+ IWMMXT_BUILTIN2 (lshrv4hi3_di, WSRLH)
+ IWMMXT_BUILTIN2 (lshrv4hi3, WSRLHI)
+ IWMMXT_BUILTIN2 (lshrv2si3_di, WSRLW)
+ IWMMXT_BUILTIN2 (lshrv2si3, WSRLWI)
+ IWMMXT_BUILTIN2 (lshrdi3_di, WSRLD)
+ IWMMXT_BUILTIN2 (lshrdi3, WSRLDI)
+ IWMMXT_BUILTIN2 (ashrv4hi3_di, WSRAH)
+ IWMMXT_BUILTIN2 (ashrv4hi3, WSRAHI)
+ IWMMXT_BUILTIN2 (ashrv2si3_di, WSRAW)
+ IWMMXT_BUILTIN2 (ashrv2si3, WSRAWI)
+ IWMMXT_BUILTIN2 (ashrdi3_di, WSRAD)
+ IWMMXT_BUILTIN2 (ashrdi3, WSRADI)
+ IWMMXT_BUILTIN2 (rorv4hi3_di, WRORH)
+ IWMMXT_BUILTIN2 (rorv4hi3, WRORHI)
+ IWMMXT_BUILTIN2 (rorv2si3_di, WRORW)
+ IWMMXT_BUILTIN2 (rorv2si3, WRORWI)
+ IWMMXT_BUILTIN2 (rordi3_di, WRORD)
+ IWMMXT_BUILTIN2 (rordi3, WRORDI)
+ IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
+ IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
+};
-void
-arm_init_builtins ()
+static const struct builtin_description bdesc_1arg[] =
+{
+ IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB)
+ IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH)
+ IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW)
+ IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB)
+ IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH)
+ IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW)
+ IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB)
+ IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH)
+ IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW)
+ IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB)
+ IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH)
+ IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW)
+ IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB)
+ IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH)
+ IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW)
+ IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB)
+ IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH)
+ IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW)
+};
+
+/* Set up all the iWMMXt builtins. This is
+ not called if TARGET_IWMMXT is zero. */
+
+static void
+arm_init_iwmmxt_builtins (void)
{
+ const struct builtin_description * d;
+ size_t i;
tree endlink = void_list_node;
- tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
- tree pchar_type_node = build_pointer_type (char_type_node);
- tree int_ftype_int, void_ftype_pchar;
+ tree int_ftype_int
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, integer_type_node, endlink));
+ tree v8qi_ftype_v8qi_v8qi_int
+ = build_function_type (V8QI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ tree_cons (NULL_TREE,
+ integer_type_node,
+ endlink))));
+ tree v4hi_ftype_v4hi_int
+ = build_function_type (V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree v2si_ftype_v2si_int
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree v2si_ftype_di_di
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, long_long_integer_type_node,
+ tree_cons (NULL_TREE, long_long_integer_type_node,
+ endlink)));
+ tree di_ftype_di_int
+ = build_function_type (long_long_integer_type_node,
+ tree_cons (NULL_TREE, long_long_integer_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree di_ftype_di_int_int
+ = build_function_type (long_long_integer_type_node,
+ tree_cons (NULL_TREE, long_long_integer_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ tree_cons (NULL_TREE,
+ integer_type_node,
+ endlink))));
+ tree int_ftype_v8qi
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ endlink));
+ tree int_ftype_v4hi
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink));
+ tree int_ftype_v2si
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ endlink));
+ tree int_ftype_v8qi_int
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree int_ftype_v4hi_int
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree int_ftype_v2si_int
+ = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree v8qi_ftype_v8qi_int_int
+ = build_function_type (V8QI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ tree_cons (NULL_TREE,
+ integer_type_node,
+ endlink))));
+ tree v4hi_ftype_v4hi_int_int
+ = build_function_type (V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ tree_cons (NULL_TREE,
+ integer_type_node,
+ endlink))));
+ tree v2si_ftype_v2si_int_int
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ tree_cons (NULL_TREE,
+ integer_type_node,
+ endlink))));
+ /* Miscellaneous. */
+ tree v8qi_ftype_v4hi_v4hi
+ = build_function_type (V8QI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink)));
+ tree v4hi_ftype_v2si_v2si
+ = build_function_type (V4HI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ endlink)));
+ tree v2si_ftype_v4hi_v4hi
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink)));
+ tree v2si_ftype_v8qi_v8qi
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ endlink)));
+ tree v4hi_ftype_v4hi_di
+ = build_function_type (V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE,
+ long_long_integer_type_node,
+ endlink)));
+ tree v2si_ftype_v2si_di
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE,
+ long_long_integer_type_node,
+ endlink)));
+ tree void_ftype_int_int
+ = build_function_type (void_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ tree_cons (NULL_TREE, integer_type_node,
+ endlink)));
+ tree di_ftype_void
+ = build_function_type (long_long_unsigned_type_node, endlink);
+ tree di_ftype_v8qi
+ = build_function_type (long_long_integer_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ endlink));
+ tree di_ftype_v4hi
+ = build_function_type (long_long_integer_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink));
+ tree di_ftype_v2si
+ = build_function_type (long_long_integer_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ endlink));
+ tree v2si_ftype_v4hi
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink));
+ tree v4hi_ftype_v8qi
+ = build_function_type (V4HI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ endlink));
+
+ tree di_ftype_di_v4hi_v4hi
+ = build_function_type (long_long_unsigned_type_node,
+ tree_cons (NULL_TREE,
+ long_long_unsigned_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE,
+ V4HI_type_node,
+ endlink))));
+
+ tree di_ftype_v4hi_v4hi
+ = build_function_type (long_long_unsigned_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink)));
+
+ /* Normal vector binops. */
+ tree v8qi_ftype_v8qi_v8qi
+ = build_function_type (V8QI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ tree_cons (NULL_TREE, V8QI_type_node,
+ endlink)));
+ tree v4hi_ftype_v4hi_v4hi
+ = build_function_type (V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ tree_cons (NULL_TREE, V4HI_type_node,
+ endlink)));
+ tree v2si_ftype_v2si_v2si
+ = build_function_type (V2SI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, V2SI_type_node,
+ endlink)));
+ tree di_ftype_di_di
+ = build_function_type (long_long_unsigned_type_node,
+ tree_cons (NULL_TREE, long_long_unsigned_type_node,
+ tree_cons (NULL_TREE,
+ long_long_unsigned_type_node,
+ endlink)));
+
+ /* Add all builtins that are more or less simple operations on two
+ operands. */
+ for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
+ {
+ /* Use one of the operands; the target can have a different mode for
+ mask-generating compares. */
+ enum machine_mode mode;
+ tree type;
+
+ if (d->name == 0)
+ continue;
+
+ mode = insn_data[d->icode].operand[1].mode;
+
+ switch (mode)
+ {
+ case V8QImode:
+ type = v8qi_ftype_v8qi_v8qi;
+ break;
+ case V4HImode:
+ type = v4hi_ftype_v4hi_v4hi;
+ break;
+ case V2SImode:
+ type = v2si_ftype_v2si_v2si;
+ break;
+ case DImode:
+ type = di_ftype_di_di;
+ break;
+
+ default:
+ abort ();
+ }
+
+ def_mbuiltin (d->mask, d->name, type, d->code);
+ }
+
+ /* Add the remaining MMX insns with somewhat more complicated types. */
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wzero", di_ftype_void, ARM_BUILTIN_WZERO);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_setwcx", void_ftype_int_int, ARM_BUILTIN_SETWCX);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_getwcx", int_ftype_int, ARM_BUILTIN_GETWCX);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSLLH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllw", v2si_ftype_v2si_di, ARM_BUILTIN_WSLLW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wslld", di_ftype_di_di, ARM_BUILTIN_WSLLD);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSLLHI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllwi", v2si_ftype_v2si_int, ARM_BUILTIN_WSLLWI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wslldi", di_ftype_di_int, ARM_BUILTIN_WSLLDI);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSRLH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlw", v2si_ftype_v2si_di, ARM_BUILTIN_WSRLW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrld", di_ftype_di_di, ARM_BUILTIN_WSRLD);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSRLHI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlwi", v2si_ftype_v2si_int, ARM_BUILTIN_WSRLWI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrldi", di_ftype_di_int, ARM_BUILTIN_WSRLDI);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrah", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSRAH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsraw", v2si_ftype_v2si_di, ARM_BUILTIN_WSRAW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrad", di_ftype_di_di, ARM_BUILTIN_WSRAD);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrahi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSRAHI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrawi", v2si_ftype_v2si_int, ARM_BUILTIN_WSRAWI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsradi", di_ftype_di_int, ARM_BUILTIN_WSRADI);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WRORH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorw", v2si_ftype_v2si_di, ARM_BUILTIN_WRORW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrord", di_ftype_di_di, ARM_BUILTIN_WRORD);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WRORHI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorwi", v2si_ftype_v2si_int, ARM_BUILTIN_WRORWI);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrordi", di_ftype_di_int, ARM_BUILTIN_WRORDI);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wshufh", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSHUFH);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadb", v2si_ftype_v8qi_v8qi, ARM_BUILTIN_WSADB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadh", v2si_ftype_v4hi_v4hi, ARM_BUILTIN_WSADH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadbz", v2si_ftype_v8qi_v8qi, ARM_BUILTIN_WSADBZ);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadhz", v2si_ftype_v4hi_v4hi, ARM_BUILTIN_WSADHZ);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsb", int_ftype_v8qi_int, ARM_BUILTIN_TEXTRMSB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsh", int_ftype_v4hi_int, ARM_BUILTIN_TEXTRMSH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsw", int_ftype_v2si_int, ARM_BUILTIN_TEXTRMSW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmub", int_ftype_v8qi_int, ARM_BUILTIN_TEXTRMUB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmuh", int_ftype_v4hi_int, ARM_BUILTIN_TEXTRMUH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmuw", int_ftype_v2si_int, ARM_BUILTIN_TEXTRMUW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrb", v8qi_ftype_v8qi_int_int, ARM_BUILTIN_TINSRB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrh", v4hi_ftype_v4hi_int_int, ARM_BUILTIN_TINSRH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrw", v2si_ftype_v2si_int_int, ARM_BUILTIN_TINSRW);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_waccb", di_ftype_v8qi, ARM_BUILTIN_WACCB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wacch", di_ftype_v4hi, ARM_BUILTIN_WACCH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_waccw", di_ftype_v2si, ARM_BUILTIN_WACCW);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskb", int_ftype_v8qi, ARM_BUILTIN_TMOVMSKB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskh", int_ftype_v4hi, ARM_BUILTIN_TMOVMSKH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskw", int_ftype_v2si, ARM_BUILTIN_TMOVMSKW);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackhss", v8qi_ftype_v4hi_v4hi, ARM_BUILTIN_WPACKHSS);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackhus", v8qi_ftype_v4hi_v4hi, ARM_BUILTIN_WPACKHUS);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackwus", v4hi_ftype_v2si_v2si, ARM_BUILTIN_WPACKWUS);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackwss", v4hi_ftype_v2si_v2si, ARM_BUILTIN_WPACKWSS);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackdus", v2si_ftype_di_di, ARM_BUILTIN_WPACKDUS);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackdss", v2si_ftype_di_di, ARM_BUILTIN_WPACKDSS);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehub", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKEHUB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehuh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKEHUH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehuw", di_ftype_v2si, ARM_BUILTIN_WUNPCKEHUW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsb", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKEHSB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKEHSH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsw", di_ftype_v2si, ARM_BUILTIN_WUNPCKEHSW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelub", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKELUB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckeluh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKELUH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckeluw", di_ftype_v2si, ARM_BUILTIN_WUNPCKELUW);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsb", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKELSB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKELSH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsw", di_ftype_v2si, ARM_BUILTIN_WUNPCKELSW);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacs", di_ftype_di_v4hi_v4hi, ARM_BUILTIN_WMACS);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacsz", di_ftype_v4hi_v4hi, ARM_BUILTIN_WMACSZ);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacu", di_ftype_di_v4hi_v4hi, ARM_BUILTIN_WMACU);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacuz", di_ftype_v4hi_v4hi, ARM_BUILTIN_WMACUZ);
+
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_walign", v8qi_ftype_v8qi_v8qi_int, ARM_BUILTIN_WALIGN);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmia", di_ftype_di_int_int, ARM_BUILTIN_TMIA);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiaph", di_ftype_di_int_int, ARM_BUILTIN_TMIAPH);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiabb", di_ftype_di_int_int, ARM_BUILTIN_TMIABB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiabt", di_ftype_di_int_int, ARM_BUILTIN_TMIABT);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiatb", di_ftype_di_int_int, ARM_BUILTIN_TMIATB);
+ def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiatt", di_ftype_di_int_int, ARM_BUILTIN_TMIATT);
+}
+
+static void
+arm_init_builtins (void)
+{
+ if (TARGET_REALLY_IWMMXT)
+ arm_init_iwmmxt_builtins ();
+}
+
+/* Errors in the source file can cause expand_expr to return const0_rtx
+ where we expect a vector. To avoid crashing, use one of the vector
+ clear instructions. */
+
+static rtx
+safe_vector_operand (rtx x, enum machine_mode mode)
+{
+ if (x != const0_rtx)
+ return x;
+ x = gen_reg_rtx (mode);
+
+ emit_insn (gen_iwmmxt_clrdi (mode == DImode ? x
+ : gen_rtx_SUBREG (DImode, x, 0)));
+ return x;
+}
+
+/* Subroutine of arm_expand_builtin to take care of binop insns. */
+
+static rtx
+arm_expand_binop_builtin (enum insn_code icode,
+ tree arglist, rtx target)
+{
+ rtx pat;
+ tree arg0 = TREE_VALUE (arglist);
+ tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ enum machine_mode tmode = insn_data[icode].operand[0].mode;
+ enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+ enum machine_mode mode1 = insn_data[icode].operand[2].mode;
+
+ if (VECTOR_MODE_P (mode0))
+ op0 = safe_vector_operand (op0, mode0);
+ if (VECTOR_MODE_P (mode1))
+ op1 = safe_vector_operand (op1, mode1);
+
+ if (! target
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ /* In case the insn wants input operands in modes different from
+ the result, abort. */
+ if (GET_MODE (op0) != mode0 || GET_MODE (op1) != mode1)
+ abort ();
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+
+ pat = GEN_FCN (icode) (target, op0, op1);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ return target;
+}
- /* void func (char *) */
- void_ftype_pchar
- = build_function_type_list (void_type_node, pchar_type_node, NULL_TREE);
+/* Subroutine of arm_expand_builtin to take care of unop insns. */
- /* int func (int) */
- int_ftype_int
- = build_function_type (integer_type_node, int_endlink);
+static rtx
+arm_expand_unop_builtin (enum insn_code icode,
+ tree arglist, rtx target, int do_load)
+{
+ rtx pat;
+ tree arg0 = TREE_VALUE (arglist);
+ rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ enum machine_mode tmode = insn_data[icode].operand[0].mode;
+ enum machine_mode mode0 = insn_data[icode].operand[1].mode;
+
+ if (! target
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+ if (do_load)
+ op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
+ else
+ {
+ if (VECTOR_MODE_P (mode0))
+ op0 = safe_vector_operand (op0, mode0);
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+ }
- /* Initialize arm V5 builtins. */
- if (arm_arch5)
- def_builtin ("__builtin_clz", int_ftype_int, ARM_BUILTIN_CLZ);
+ pat = GEN_FCN (icode) (target, op0);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ return target;
}
/* Expand an expression EXP that calls a built-in function,
@@ -9494,47 +11149,223 @@ arm_init_builtins ()
SUBTARGET may be used as the target for computing one of EXP's operands.
IGNORE is nonzero if the value is to be ignored. */
-rtx
-arm_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
-{
- enum insn_code icode;
- tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
- tree arglist = TREE_OPERAND (exp, 1);
- tree arg0;
- rtx op0, pat;
- enum machine_mode tmode, mode0;
- int fcode = DECL_FUNCTION_CODE (fndecl);
+static rtx
+arm_expand_builtin (tree exp,
+ rtx target,
+ rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
+{
+ const struct builtin_description * d;
+ enum insn_code icode;
+ tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+ tree arglist = TREE_OPERAND (exp, 1);
+ tree arg0;
+ tree arg1;
+ tree arg2;
+ rtx op0;
+ rtx op1;
+ rtx op2;
+ rtx pat;
+ int fcode = DECL_FUNCTION_CODE (fndecl);
+ size_t i;
+ enum machine_mode tmode;
+ enum machine_mode mode0;
+ enum machine_mode mode1;
+ enum machine_mode mode2;
switch (fcode)
{
- default:
- break;
-
- case ARM_BUILTIN_CLZ:
- icode = CODE_FOR_clz;
+ case ARM_BUILTIN_TEXTRMSB:
+ case ARM_BUILTIN_TEXTRMUB:
+ case ARM_BUILTIN_TEXTRMSH:
+ case ARM_BUILTIN_TEXTRMUH:
+ case ARM_BUILTIN_TEXTRMSW:
+ case ARM_BUILTIN_TEXTRMUW:
+ icode = (fcode == ARM_BUILTIN_TEXTRMSB ? CODE_FOR_iwmmxt_textrmsb
+ : fcode == ARM_BUILTIN_TEXTRMUB ? CODE_FOR_iwmmxt_textrmub
+ : fcode == ARM_BUILTIN_TEXTRMSH ? CODE_FOR_iwmmxt_textrmsh
+ : fcode == ARM_BUILTIN_TEXTRMUH ? CODE_FOR_iwmmxt_textrmuh
+ : CODE_FOR_iwmmxt_textrmw);
+
+ arg0 = TREE_VALUE (arglist);
+ arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ tmode = insn_data[icode].operand[0].mode;
+ mode0 = insn_data[icode].operand[1].mode;
+ mode1 = insn_data[icode].operand[2].mode;
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+ {
+ /* @@@ better error message */
+ error ("selector must be an immediate");
+ return gen_reg_rtx (tmode);
+ }
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+ pat = GEN_FCN (icode) (target, op0, op1);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ return target;
+
+ case ARM_BUILTIN_TINSRB:
+ case ARM_BUILTIN_TINSRH:
+ case ARM_BUILTIN_TINSRW:
+ icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb
+ : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh
+ : CODE_FOR_iwmmxt_tinsrw);
+ arg0 = TREE_VALUE (arglist);
+ arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
+ tmode = insn_data[icode].operand[0].mode;
+ mode0 = insn_data[icode].operand[1].mode;
+ mode1 = insn_data[icode].operand[2].mode;
+ mode2 = insn_data[icode].operand[3].mode;
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
+ op0 = copy_to_mode_reg (mode0, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+ if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
+ {
+ /* @@@ better error message */
+ error ("selector must be an immediate");
+ return const0_rtx;
+ }
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+ pat = GEN_FCN (icode) (target, op0, op1, op2);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ return target;
+
+ case ARM_BUILTIN_SETWCX:
+ arg0 = TREE_VALUE (arglist);
+ arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ emit_insn (gen_iwmmxt_tmcr (op0, op1));
+ return 0;
+
+ case ARM_BUILTIN_GETWCX:
+ arg0 = TREE_VALUE (arglist);
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ target = gen_reg_rtx (SImode);
+ emit_insn (gen_iwmmxt_tmrc (target, op0));
+ return target;
+
+ case ARM_BUILTIN_WSHUFH:
+ icode = CODE_FOR_iwmmxt_wshufh;
+ arg0 = TREE_VALUE (arglist);
+ arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ tmode = insn_data[icode].operand[0].mode;
+ mode1 = insn_data[icode].operand[1].mode;
+ mode2 = insn_data[icode].operand[2].mode;
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
+ op0 = copy_to_mode_reg (mode1, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
+ {
+ /* @@@ better error message */
+ error ("mask must be an immediate");
+ return const0_rtx;
+ }
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+ pat = GEN_FCN (icode) (target, op0, op1);
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+ return target;
+
+ case ARM_BUILTIN_WSADB:
+ return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadb, arglist, target);
+ case ARM_BUILTIN_WSADH:
+ return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadh, arglist, target);
+ case ARM_BUILTIN_WSADBZ:
+ return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, arglist, target);
+ case ARM_BUILTIN_WSADHZ:
+ return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, arglist, target);
+
+ /* Several three-argument builtins. */
+ case ARM_BUILTIN_WMACS:
+ case ARM_BUILTIN_WMACU:
+ case ARM_BUILTIN_WALIGN:
+ case ARM_BUILTIN_TMIA:
+ case ARM_BUILTIN_TMIAPH:
+ case ARM_BUILTIN_TMIATT:
+ case ARM_BUILTIN_TMIATB:
+ case ARM_BUILTIN_TMIABT:
+ case ARM_BUILTIN_TMIABB:
+ icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs
+ : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu
+ : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia
+ : fcode == ARM_BUILTIN_TMIAPH ? CODE_FOR_iwmmxt_tmiaph
+ : fcode == ARM_BUILTIN_TMIABB ? CODE_FOR_iwmmxt_tmiabb
+ : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt
+ : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb
+ : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt
+ : CODE_FOR_iwmmxt_walign);
arg0 = TREE_VALUE (arglist);
+ arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
tmode = insn_data[icode].operand[0].mode;
mode0 = insn_data[icode].operand[1].mode;
+ mode1 = insn_data[icode].operand[2].mode;
+ mode2 = insn_data[icode].operand[3].mode;
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
op0 = copy_to_mode_reg (mode0, op0);
+ if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
+ op1 = copy_to_mode_reg (mode1, op1);
+ if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
+ op2 = copy_to_mode_reg (mode2, op2);
if (target == 0
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
- pat = GEN_FCN (icode) (target, op0);
+ pat = GEN_FCN (icode) (target, op0, op1, op2);
if (! pat)
return 0;
emit_insn (pat);
return target;
+
+ case ARM_BUILTIN_WZERO:
+ target = gen_reg_rtx (DImode);
+ emit_insn (gen_iwmmxt_clrdi (target));
+ return target;
+
+ default:
+ break;
}
+ for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
+ if (d->code == (const enum arm_builtins) fcode)
+ return arm_expand_binop_builtin (d->icode, arglist, target);
+
+ for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
+ if (d->code == (const enum arm_builtins) fcode)
+ return arm_expand_unop_builtin (d->icode, arglist, target, 0);
+
/* @@@ Should really do something sensible here. */
return NULL_RTX;
}
@@ -9543,12 +11374,8 @@ arm_expand_builtin (exp, target, subtarget, mode, ignore)
checking to see if any of the variables created in that
function match the RTX called 'orig'. If they do then
replace them with the RTX called 'new'. */
-
static void
-replace_symbols_in_block (block, orig, new)
- tree block;
- rtx orig;
- rtx new;
+replace_symbols_in_block (tree block, rtx orig, rtx new)
{
for (; block; block = BLOCK_CHAIN (block))
{
@@ -9577,12 +11404,8 @@ replace_symbols_in_block (block, orig, new)
/* Return the number (counting from 0) of
the least significant set bit in MASK. */
-#ifdef __GNUC__
-inline
-#endif
-static int
-number_of_first_bit_set (mask)
- int mask;
+inline static int
+number_of_first_bit_set (int mask)
{
int bit;
@@ -9598,10 +11421,7 @@ number_of_first_bit_set (mask)
If 'reg_containing_return_addr' is -1, then the return address is
actually on the stack, at the stack pointer. */
static void
-thumb_exit (f, reg_containing_return_addr, eh_ofs)
- FILE * f;
- int reg_containing_return_addr;
- rtx eh_ofs;
+thumb_exit (FILE *f, int reg_containing_return_addr, rtx eh_ofs)
{
unsigned regs_available_for_popping;
unsigned regs_to_pop;
@@ -9756,7 +11576,8 @@ thumb_exit (f, reg_containing_return_addr, eh_ofs)
}
/* Pop as many registers as we can. */
- thumb_pushpop (f, regs_available_for_popping, FALSE);
+ thumb_pushpop (f, regs_available_for_popping, FALSE, NULL,
+ regs_available_for_popping);
/* Process the registers we popped. */
if (reg_containing_return_addr == -1)
@@ -9768,7 +11589,7 @@ thumb_exit (f, reg_containing_return_addr, eh_ofs)
number_of_first_bit_set (regs_available_for_popping);
/* Remove this register for the mask of available registers, so that
- the return address will not be corrupted by futher pops. */
+ the return address will not be corrupted by further pops. */
regs_available_for_popping &= ~(1 << reg_containing_return_addr);
}
@@ -9837,7 +11658,8 @@ thumb_exit (f, reg_containing_return_addr, eh_ofs)
int popped_into;
int move_to;
- thumb_pushpop (f, regs_available_for_popping, FALSE);
+ thumb_pushpop (f, regs_available_for_popping, FALSE, NULL,
+ regs_available_for_popping);
/* We have popped either FP or SP.
Move whichever one it is into the correct register. */
@@ -9857,7 +11679,8 @@ thumb_exit (f, reg_containing_return_addr, eh_ofs)
{
int popped_into;
- thumb_pushpop (f, regs_available_for_popping, FALSE);
+ thumb_pushpop (f, regs_available_for_popping, FALSE, NULL,
+ regs_available_for_popping);
popped_into = number_of_first_bit_set (regs_available_for_popping);
@@ -9887,16 +11710,20 @@ thumb_exit (f, reg_containing_return_addr, eh_ofs)
asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
}
-/* Emit code to push or pop registers to or from the stack. */
-
+/* Emit code to push or pop registers to or from the stack. F is the
+ assembly file. MASK is the registers to push or pop. PUSH is
+ non-zero if we should push, and zero if we should pop. For debugging
+ output, if pushing, adjust CFA_OFFSET by the amount of space added
+ to the stack. REAL_REGS should have the same number of bits set as
+ MASK, and will be used instead (in the same order) to describe which
+ registers were saved - this is used to mark the save slots when we
+ push high registers after moving them to low registers. */
static void
-thumb_pushpop (f, mask, push)
- FILE * f;
- int mask;
- int push;
+thumb_pushpop (FILE *f, int mask, int push, int *cfa_offset, int real_regs)
{
int regno;
int lo_mask = mask & 0xFF;
+ int pushed_words = 0;
if (lo_mask == 0 && !push && (mask & (1 << 15)))
{
@@ -9917,6 +11744,8 @@ thumb_pushpop (f, mask, push)
if ((lo_mask & ~1) != 0)
fprintf (f, ", ");
+
+ pushed_words++;
}
}
@@ -9927,6 +11756,8 @@ thumb_pushpop (f, mask, push)
fprintf (f, ", ");
asm_fprintf (f, "%r", LR_REGNUM);
+
+ pushed_words++;
}
else if (!push && (mask & (1 << PC_REGNUM)))
{
@@ -9951,11 +11782,27 @@ thumb_pushpop (f, mask, push)
}
fprintf (f, "}\n");
+
+ if (push && pushed_words && dwarf2out_do_frame ())
+ {
+ char *l = dwarf2out_cfi_label ();
+ int pushed_mask = real_regs;
+
+ *cfa_offset += pushed_words * 4;
+ dwarf2out_def_cfa (l, SP_REGNUM, *cfa_offset);
+
+ pushed_words = 0;
+ pushed_mask = real_regs;
+ for (regno = 0; regno <= 14; regno++, pushed_mask >>= 1)
+ {
+ if (pushed_mask & 1)
+ dwarf2out_reg_save (l, regno, 4 * pushed_words++ - *cfa_offset);
+ }
+ }
}
void
-thumb_final_prescan_insn (insn)
- rtx insn;
+thumb_final_prescan_insn (rtx insn)
{
if (flag_print_asm_name)
asm_fprintf (asm_out_file, "%@ 0x%04x\n",
@@ -9963,8 +11810,7 @@ thumb_final_prescan_insn (insn)
}
int
-thumb_shiftable_const (val)
- unsigned HOST_WIDE_INT val;
+thumb_shiftable_const (unsigned HOST_WIDE_INT val)
{
unsigned HOST_WIDE_INT mask = 0xff;
int i;
@@ -9981,10 +11827,8 @@ thumb_shiftable_const (val)
/* Returns nonzero if the current function contains,
or might contain a far jump. */
-
int
-thumb_far_jump_used_p (in_prologue)
- int in_prologue;
+thumb_far_jump_used_p (int in_prologue)
{
rtx insn;
@@ -10039,7 +11883,7 @@ thumb_far_jump_used_p (in_prologue)
&& get_attr_far_jump (insn) == FAR_JUMP_YES
)
{
- /* Record the fact that we have decied that
+ /* Record the fact that we have decided that
the function does use far jumps. */
cfun->machine->far_jump_used = 1;
return 1;
@@ -10050,10 +11894,8 @@ thumb_far_jump_used_p (in_prologue)
}
/* Return nonzero if FUNC must be entered in ARM mode. */
-
int
-is_called_in_ARM_mode (func)
- tree func;
+is_called_in_ARM_mode (tree func)
{
if (TREE_CODE (func) != FUNCTION_DECL)
abort ();
@@ -10069,10 +11911,9 @@ is_called_in_ARM_mode (func)
#endif
}
-/* The bits which aren't usefully expanded as rtl. */
-
+/* The bits which aren't usefully expanded as rtl. */
const char *
-thumb_unexpanded_epilogue ()
+thumb_unexpanded_epilogue (void)
{
int regno;
int live_regs_mask = 0;
@@ -10096,7 +11937,7 @@ thumb_unexpanded_epilogue ()
high_regs_pushed++;
/* The prolog may have pushed some high registers to use as
- work registers. eg the testuite file:
+ work registers. eg the testsuite file:
gcc/testsuite/gcc/gcc.c-torture/execute/complex-2.c
compiles to produce:
push {r4, r5, r6, r7, lr}
@@ -10155,8 +11996,8 @@ thumb_unexpanded_epilogue ()
mask &= (2 << regno) - 1; /* A noop if regno == 8 */
- /* Pop the values into the low register(s). */
- thumb_pushpop (asm_out_file, mask, 0);
+ /* Pop the values into the low register(s). */
+ thumb_pushpop (asm_out_file, mask, 0, NULL, mask);
/* Move the value(s) into the high registers. */
for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
@@ -10183,7 +12024,7 @@ thumb_unexpanded_epilogue ()
{
/* The stack backtrace structure creation code had to
push R7 in order to get a work register, so we pop
- it now. */
+ it now. */
live_regs_mask |= (1 << LAST_LO_REGNUM);
}
@@ -10198,7 +12039,8 @@ thumb_unexpanded_epilogue ()
structure was created which includes an adjusted stack
pointer, so just pop everything. */
if (live_regs_mask)
- thumb_pushpop (asm_out_file, live_regs_mask, FALSE);
+ thumb_pushpop (asm_out_file, live_regs_mask, FALSE, NULL,
+ live_regs_mask);
if (eh_ofs)
thumb_exit (asm_out_file, 2, eh_ofs);
@@ -10218,11 +12060,13 @@ thumb_unexpanded_epilogue ()
live_regs_mask &= ~(1 << PC_REGNUM);
if (live_regs_mask)
- thumb_pushpop (asm_out_file, live_regs_mask, FALSE);
+ thumb_pushpop (asm_out_file, live_regs_mask, FALSE, NULL,
+ live_regs_mask);
if (had_to_push_lr)
/* Get the return address into a temporary register. */
- thumb_pushpop (asm_out_file, 1 << LAST_ARG_REGNUM, 0);
+ thumb_pushpop (asm_out_file, 1 << LAST_ARG_REGNUM, 0, NULL,
+ 1 << LAST_ARG_REGNUM);
/* Remove the argument registers that were pushed onto the stack. */
asm_fprintf (asm_out_file, "\tadd\t%r, %r, #%d\n",
@@ -10240,9 +12084,8 @@ thumb_unexpanded_epilogue ()
}
/* Functions to save and restore machine-specific function data. */
-
static struct machine_function *
-arm_init_machine_status ()
+arm_init_machine_status (void)
{
struct machine_function *machine;
machine = (machine_function *) ggc_alloc_cleared (sizeof (machine_function));
@@ -10255,11 +12098,8 @@ arm_init_machine_status ()
/* Return an RTX indicating where the return address to the
calling function can be found. */
-
rtx
-arm_return_addr (count, frame)
- int count;
- rtx frame ATTRIBUTE_UNUSED;
+arm_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
{
if (count != 0)
return NULL_RTX;
@@ -10275,20 +12115,19 @@ arm_return_addr (count, frame)
}
/* Do anything needed before RTL is emitted for each function. */
-
void
-arm_init_expanders ()
+arm_init_expanders (void)
{
/* Arrange to initialize and mark the machine per-function status. */
init_machine_status = arm_init_machine_status;
}
HOST_WIDE_INT
-thumb_get_frame_size ()
+thumb_get_frame_size (void)
{
int regno;
- int base_size = ROUND_UP (get_frame_size ());
+ int base_size = ROUND_UP_WORD (get_frame_size ());
int count_regs = 0;
int entry_size = 0;
int leaf;
@@ -10370,10 +12209,11 @@ thumb_get_frame_size ()
}
/* Generate the rest of a function's prologue. */
-
void
-thumb_expand_prologue ()
+thumb_expand_prologue (void)
{
+ rtx insn, dwarf;
+
HOST_WIDE_INT amount = (thumb_get_frame_size ()
+ current_function_outgoing_args_size);
unsigned long func_type;
@@ -10391,15 +12231,21 @@ thumb_expand_prologue ()
}
if (frame_pointer_needed)
- emit_insn (gen_movsi (hard_frame_pointer_rtx, stack_pointer_rtx));
+ {
+ insn = emit_insn (gen_movsi (hard_frame_pointer_rtx, stack_pointer_rtx));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
if (amount)
{
- amount = ROUND_UP (amount);
+ amount = ROUND_UP_WORD (amount);
if (amount < 512)
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (- amount)));
+ {
+ insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (- amount)));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
else
{
int regno;
@@ -10429,7 +12275,7 @@ thumb_expand_prologue ()
{
rtx spare = gen_rtx (REG, SImode, IP_REGNUM);
- /* Choose an arbitary, non-argument low register. */
+ /* Choose an arbitrary, non-argument low register. */
reg = gen_rtx (REG, SImode, LAST_LO_REGNUM);
/* Save it by copying it into a high, scratch register. */
@@ -10439,8 +12285,16 @@ thumb_expand_prologue ()
/* Decrement the stack. */
emit_insn (gen_movsi (reg, GEN_INT (- amount)));
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- reg));
+ insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx, reg));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ dwarf = gen_rtx_SET (SImode, stack_pointer_rtx,
+ plus_constant (stack_pointer_rtx,
+ GEN_INT (- amount)));
+ RTX_FRAME_RELATED_P (dwarf) = 1;
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
+ REG_NOTES (insn));
/* Restore the low register's original value. */
emit_insn (gen_movsi (reg, spare));
@@ -10456,8 +12310,17 @@ thumb_expand_prologue ()
reg = gen_rtx (REG, SImode, regno);
emit_insn (gen_movsi (reg, GEN_INT (- amount)));
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- reg));
+
+ insn = emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx, reg));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ dwarf = gen_rtx_SET (SImode, stack_pointer_rtx,
+ plus_constant (stack_pointer_rtx,
+ GEN_INT (- amount)));
+ RTX_FRAME_RELATED_P (dwarf) = 1;
+ REG_NOTES (insn)
+ = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
+ REG_NOTES (insn));
}
}
}
@@ -10467,11 +12330,12 @@ thumb_expand_prologue ()
}
void
-thumb_expand_epilogue ()
+thumb_expand_epilogue (void)
{
HOST_WIDE_INT amount = (thumb_get_frame_size ()
+ current_function_outgoing_args_size);
-
+ int regno;
+
/* Naked functions don't have prologues. */
if (IS_NAKED (arm_current_func_type ()))
return;
@@ -10480,7 +12344,7 @@ thumb_expand_epilogue ()
emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
else if (amount)
{
- amount = ROUND_UP (amount);
+ amount = ROUND_UP_WORD (amount);
if (amount < 512)
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
@@ -10501,15 +12365,23 @@ thumb_expand_epilogue ()
if (current_function_profile || TARGET_NO_SCHED_PRO)
emit_insn (gen_blockage ());
+
+ /* Emit a clobber for each insn that will be restored in the epilogue,
+ so that flow2 will get register lifetimes correct. */
+ for (regno = 0; regno < 13; regno++)
+ if (regs_ever_live[regno] && !call_used_regs[regno])
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, regno)));
+
+ if (! regs_ever_live[LR_REGNUM])
+ emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, LR_REGNUM)));
}
static void
-thumb_output_function_prologue (f, size)
- FILE * f;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
int live_regs_mask = 0;
int high_regs_pushed = 0;
+ int cfa_offset = 0;
int regno;
if (IS_NAKED (arm_current_func_type ()))
@@ -10536,7 +12408,7 @@ thumb_output_function_prologue (f, size)
the assembler to bypass the ARM code when this function
is called from a Thumb encoded function elsewhere in the
same file. Hence the definition of STUB_NAME here must
- agree with the definition in gas/config/tc-arm.c */
+ agree with the definition in gas/config/tc-arm.c. */
#define STUB_NAME ".real_start_of"
@@ -10572,6 +12444,16 @@ thumb_output_function_prologue (f, size)
asm_fprintf (f, "\tsub\t%r, %r, #%d\n",
SP_REGNUM, SP_REGNUM,
current_function_pretend_args_size);
+
+ /* We don't need to record the stores for unwinding (would it
+ help the debugger any if we did?), but record the change in
+ the stack pointer. */
+ if (dwarf2out_do_frame ())
+ {
+ char *l = dwarf2out_cfi_label ();
+ cfa_offset = cfa_offset + current_function_pretend_args_size;
+ dwarf2out_def_cfa (l, SP_REGNUM, cfa_offset);
+ }
}
for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
@@ -10611,7 +12493,7 @@ thumb_output_function_prologue (f, size)
if (regs_ever_live [LAST_ARG_REGNUM] == 0)
work_register = LAST_ARG_REGNUM;
- else /* We must push a register of our own */
+ else /* We must push a register of our own. */
live_regs_mask |= (1 << LAST_LO_REGNUM);
}
@@ -10627,9 +12509,16 @@ thumb_output_function_prologue (f, size)
asm_fprintf
(f, "\tsub\t%r, %r, #16\t%@ Create stack backtrace structure\n",
SP_REGNUM, SP_REGNUM);
-
+
+ if (dwarf2out_do_frame ())
+ {
+ char *l = dwarf2out_cfi_label ();
+ cfa_offset = cfa_offset + 16;
+ dwarf2out_def_cfa (l, SP_REGNUM, cfa_offset);
+ }
+
if (live_regs_mask)
- thumb_pushpop (f, live_regs_mask, 1);
+ thumb_pushpop (f, live_regs_mask, 1, &cfa_offset, live_regs_mask);
for (offset = 0, wr = 1 << 15; wr != 0; wr >>= 1)
if (wr & live_regs_mask)
@@ -10673,7 +12562,7 @@ thumb_output_function_prologue (f, size)
ARM_HARD_FRAME_POINTER_REGNUM, work_register);
}
else if (live_regs_mask)
- thumb_pushpop (f, live_regs_mask, 1);
+ thumb_pushpop (f, live_regs_mask, 1, &cfa_offset, live_regs_mask);
for (regno = 8; regno < 13; regno++)
if (THUMB_REG_PUSHED_P (regno))
@@ -10701,6 +12590,8 @@ thumb_output_function_prologue (f, size)
while (high_regs_pushed > 0)
{
+ int real_regs_mask = 0;
+
for (regno = LAST_LO_REGNUM; regno >= 0; regno--)
{
if (mask & (1 << regno))
@@ -10708,6 +12599,7 @@ thumb_output_function_prologue (f, size)
asm_fprintf (f, "\tmov\t%r, %r\n", regno, next_hi_reg);
high_regs_pushed--;
+ real_regs_mask |= (1 << next_hi_reg);
if (high_regs_pushed)
{
@@ -10723,8 +12615,8 @@ thumb_output_function_prologue (f, size)
}
}
}
-
- thumb_pushpop (f, mask, 1);
+
+ thumb_pushpop (f, mask, 1, &cfa_offset, real_regs_mask);
}
if (pushable_regs == 0
@@ -10736,10 +12628,8 @@ thumb_output_function_prologue (f, size)
/* Handle the case of a double word load into a low register from
a computed memory address. The computed address may involve a
register which is overwritten by the load. */
-
const char *
-thumb_load_double_from_address (operands)
- rtx *operands;
+thumb_load_double_from_address (rtx *operands)
{
rtx addr;
rtx base;
@@ -10858,11 +12748,8 @@ thumb_load_double_from_address (operands)
return "";
}
-
const char *
-thumb_output_move_mem_multiple (n, operands)
- int n;
- rtx * operands;
+thumb_output_move_mem_multiple (int n, rtx *operands)
{
rtx tmp;
@@ -10911,10 +12798,8 @@ thumb_output_move_mem_multiple (n, operands)
}
/* Routines for generating rtl. */
-
void
-thumb_expand_movstrqi (operands)
- rtx * operands;
+thumb_expand_movstrqi (rtx *operands)
{
rtx out = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
rtx in = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
@@ -10964,70 +12849,58 @@ thumb_expand_movstrqi (operands)
}
int
-thumb_cmp_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+thumb_cmp_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT
- && (unsigned HOST_WIDE_INT) (INTVAL (op)) < 256)
- || register_operand (op, mode));
+ && INTVAL (op) < 256
+ && INTVAL (op) >= 0)
+ || s_register_operand (op, mode));
}
-static const char *
-thumb_condition_code (x, invert)
- rtx x;
- int invert;
+int
+thumb_cmpneg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- static const char * const conds[] =
- {
- "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
- "hi", "ls", "ge", "lt", "gt", "le"
- };
- int val;
+ return (GET_CODE (op) == CONST_INT
+ && INTVAL (op) < 0
+ && INTVAL (op) > -256);
+}
- switch (GET_CODE (x))
- {
- case EQ: val = 0; break;
- case NE: val = 1; break;
- case GEU: val = 2; break;
- case LTU: val = 3; break;
- case GTU: val = 8; break;
- case LEU: val = 9; break;
- case GE: val = 10; break;
- case LT: val = 11; break;
- case GT: val = 12; break;
- case LE: val = 13; break;
- default:
- abort ();
- }
+/* Return TRUE if a result can be stored in OP without clobbering the
+ condition code register. Prior to reload we only accept a
+ register. After reload we have to be able to handle memory as
+ well, since a pseudo may not get a hard reg and reload cannot
+ handle output-reloads on jump insns.
+
+ We could possibly handle mem before reload as well, but that might
+ complicate things with the need to handle increment
+ side-effects. */
- return conds[val ^ invert];
+int
+thumb_cbrch_target_operand (rtx op, enum machine_mode mode)
+{
+ return (s_register_operand (op, mode)
+ || ((reload_in_progress || reload_completed)
+ && memory_operand (op, mode)));
}
/* Handle storing a half-word to memory during reload. */
-
void
-thumb_reload_out_hi (operands)
- rtx * operands;
+thumb_reload_out_hi (rtx *operands)
{
emit_insn (gen_thumb_movhi_clobber (operands[0], operands[1], operands[2]));
}
-/* Handle storing a half-word to memory during reload. */
-
+/* Handle reading a half-word from memory during reload. */
void
-thumb_reload_in_hi (operands)
- rtx * operands ATTRIBUTE_UNUSED;
+thumb_reload_in_hi (rtx *operands ATTRIBUTE_UNUSED)
{
abort ();
}
/* Return the length of a function name prefix
that starts with the character 'c'. */
-
static int
-arm_get_strip_length (c)
- int c;
+arm_get_strip_length (int c)
{
switch (c)
{
@@ -11038,10 +12911,8 @@ arm_get_strip_length (c)
/* Return a pointer to a function's name with any
and all prefix encodings stripped from it. */
-
const char *
-arm_strip_name_encoding (name)
- const char * name;
+arm_strip_name_encoding (const char *name)
{
int skip;
@@ -11054,11 +12925,8 @@ arm_strip_name_encoding (name)
/* If there is a '*' anywhere in the name's prefix, then
emit the stripped name verbatim, otherwise prepend an
underscore if leading underscores are being used. */
-
void
-arm_asm_output_labelref (stream, name)
- FILE * stream;
- const char * name;
+arm_asm_output_labelref (FILE *stream, const char *name)
{
int skip;
int verbatim = 0;
@@ -11089,8 +12957,7 @@ struct pic_chain
static struct pic_chain * aof_pic_chain = NULL;
rtx
-aof_pic_entry (x)
- rtx x;
+aof_pic_entry (rtx x)
{
struct pic_chain ** chainp;
int offset;
@@ -11112,8 +12979,7 @@ aof_pic_entry (x)
}
void
-aof_dump_pic_table (f)
- FILE * f;
+aof_dump_pic_table (FILE *f)
{
struct pic_chain * chain;
@@ -11136,7 +13002,7 @@ aof_dump_pic_table (f)
int arm_text_section_count = 1;
char *
-aof_text_section ()
+aof_text_section (void )
{
static char buf[100];
sprintf (buf, "\tAREA |C$$code%d|, CODE, READONLY",
@@ -11149,7 +13015,7 @@ aof_text_section ()
static int arm_data_section_count = 1;
char *
-aof_data_section ()
+aof_data_section (void)
{
static char buf[100];
sprintf (buf, "\tAREA |C$$data%d|, DATA", arm_data_section_count++);
@@ -11175,8 +13041,7 @@ struct import
static struct import * imports_list = NULL;
void
-aof_add_import (name)
- const char * name;
+aof_add_import (const char *name)
{
struct import * new;
@@ -11191,8 +13056,7 @@ aof_add_import (name)
}
void
-aof_delete_import (name)
- const char * name;
+aof_delete_import (const char *name)
{
struct import ** old;
@@ -11208,9 +13072,8 @@ aof_delete_import (name)
int arm_main_function = 0;
-void
-aof_dump_imports (f)
- FILE * f;
+static void
+aof_dump_imports (FILE *f)
{
/* The AOF assembler needs this to cause the startup code to be extracted
from the library. Brining in __main causes the whole thing to work
@@ -11233,14 +13096,52 @@ aof_dump_imports (f)
}
static void
-aof_globalize_label (stream, name)
- FILE *stream;
- const char *name;
+aof_globalize_label (FILE *stream, const char *name)
{
default_globalize_label (stream, name);
if (! strcmp (name, "main"))
arm_main_function = 1;
}
+
+static void
+aof_file_start (void)
+{
+ fputs ("__r0\tRN\t0\n", asm_out_file);
+ fputs ("__a1\tRN\t0\n", asm_out_file);
+ fputs ("__a2\tRN\t1\n", asm_out_file);
+ fputs ("__a3\tRN\t2\n", asm_out_file);
+ fputs ("__a4\tRN\t3\n", asm_out_file);
+ fputs ("__v1\tRN\t4\n", asm_out_file);
+ fputs ("__v2\tRN\t5\n", asm_out_file);
+ fputs ("__v3\tRN\t6\n", asm_out_file);
+ fputs ("__v4\tRN\t7\n", asm_out_file);
+ fputs ("__v5\tRN\t8\n", asm_out_file);
+ fputs ("__v6\tRN\t9\n", asm_out_file);
+ fputs ("__sl\tRN\t10\n", asm_out_file);
+ fputs ("__fp\tRN\t11\n", asm_out_file);
+ fputs ("__ip\tRN\t12\n", asm_out_file);
+ fputs ("__sp\tRN\t13\n", asm_out_file);
+ fputs ("__lr\tRN\t14\n", asm_out_file);
+ fputs ("__pc\tRN\t15\n", asm_out_file);
+ fputs ("__f0\tFN\t0\n", asm_out_file);
+ fputs ("__f1\tFN\t1\n", asm_out_file);
+ fputs ("__f2\tFN\t2\n", asm_out_file);
+ fputs ("__f3\tFN\t3\n", asm_out_file);
+ fputs ("__f4\tFN\t4\n", asm_out_file);
+ fputs ("__f5\tFN\t5\n", asm_out_file);
+ fputs ("__f6\tFN\t6\n", asm_out_file);
+ fputs ("__f7\tFN\t7\n", asm_out_file);
+ text_section ();
+}
+
+static void
+aof_file_end (void)
+{
+ if (flag_pic)
+ aof_dump_pic_table (asm_out_file);
+ aof_dump_imports (asm_out_file);
+ fputs ("\tEND\n", asm_out_file);
+}
#endif /* AOF_ASSEMBLER */
#ifdef OBJECT_FORMAT_ELF
@@ -11252,9 +13153,7 @@ aof_globalize_label (stream, name)
used before the section type. */
static void
-arm_elf_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+arm_elf_asm_named_section (const char *name, unsigned int flags)
{
char flagchars[10], *f = flagchars;
@@ -11309,20 +13208,14 @@ arm_elf_asm_named_section (name, flags)
simplification. */
static void
-arm_encode_section_info (decl, first)
- tree decl;
- int first;
+arm_encode_section_info (tree decl, rtx rtl, int first)
{
/* This doesn't work with AOF syntax, since the string table may be in
a different AREA. */
#ifndef AOF_ASSEMBLER
if (optimize > 0 && TREE_CONSTANT (decl)
&& (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
- {
- rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
- ? TREE_CST_RTL (decl) : DECL_RTL (decl));
- SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
- }
+ SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
#endif
/* If we are referencing a function that is weak then encode a long call
@@ -11338,24 +13231,43 @@ arm_encode_section_info (decl, first)
}
#endif /* !ARM_PE */
+static void
+arm_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
+{
+ if (arm_ccfsm_state == 3 && (unsigned) arm_target_label == labelno
+ && !strcmp (prefix, "L"))
+ {
+ arm_ccfsm_state = 0;
+ arm_target_insn = NULL;
+ }
+ default_internal_label (stream, prefix, labelno);
+}
+
/* Output code to add DELTA to the first argument, and then jump
to FUNCTION. Used for C++ multiple inheritance. */
-
static void
-arm_output_mi_thunk (file, thunk, delta, vcall_offset, function)
- FILE *file;
- tree thunk ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
- tree function;
+arm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
+ tree function)
{
+ static int thunk_label = 0;
+ char label[256];
int mi_delta = delta;
const char *const mi_op = mi_delta < 0 ? "sub" : "add";
int shift = 0;
- int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)))
+ int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
? 1 : 0);
if (mi_delta < 0)
mi_delta = - mi_delta;
+ if (TARGET_THUMB)
+ {
+ int labelno = thunk_label++;
+ ASM_GENERATE_INTERNAL_LABEL (label, "LTHUMBFUNC", labelno);
+ fputs ("\tldr\tr12, ", file);
+ assemble_name (file, label);
+ fputc ('\n', file);
+ }
while (mi_delta != 0)
{
if ((mi_delta & (3 << shift)) == 0)
@@ -11369,10 +13281,78 @@ arm_output_mi_thunk (file, thunk, delta, vcall_offset, function)
shift += 8;
}
}
- fputs ("\tb\t", file);
- assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
- if (NEED_PLT_RELOC)
- fputs ("(PLT)", file);
- fputc ('\n', file);
+ if (TARGET_THUMB)
+ {
+ fprintf (file, "\tbx\tr12\n");
+ ASM_OUTPUT_ALIGN (file, 2);
+ assemble_name (file, label);
+ fputs (":\n", file);
+ assemble_integer (XEXP (DECL_RTL (function), 0), 4, BITS_PER_WORD, 1);
+ }
+ else
+ {
+ fputs ("\tb\t", file);
+ assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
+ if (NEED_PLT_RELOC)
+ fputs ("(PLT)", file);
+ fputc ('\n', file);
+ }
+}
+
+int
+arm_emit_vector_const (FILE *file, rtx x)
+{
+ int i;
+ const char * pattern;
+
+ if (GET_CODE (x) != CONST_VECTOR)
+ abort ();
+
+ switch (GET_MODE (x))
+ {
+ case V2SImode: pattern = "%08x"; break;
+ case V4HImode: pattern = "%04x"; break;
+ case V8QImode: pattern = "%02x"; break;
+ default: abort ();
+ }
+
+ fprintf (file, "0x");
+ for (i = CONST_VECTOR_NUNITS (x); i--;)
+ {
+ rtx element;
+
+ element = CONST_VECTOR_ELT (x, i);
+ fprintf (file, pattern, INTVAL (element));
+ }
+
+ return 1;
}
+const char *
+arm_output_load_gr (rtx *operands)
+{
+ rtx reg;
+ rtx offset;
+ rtx wcgr;
+ rtx sum;
+
+ if (GET_CODE (operands [1]) != MEM
+ || GET_CODE (sum = XEXP (operands [1], 0)) != PLUS
+ || GET_CODE (reg = XEXP (sum, 0)) != REG
+ || GET_CODE (offset = XEXP (sum, 1)) != CONST_INT
+ || ((INTVAL (offset) < 1024) && (INTVAL (offset) > -1024)))
+ return "wldrw%?\t%0, %1";
+
+ /* Fix up an out-of-range load of a GR register. */
+ output_asm_insn ("str%?\t%0, [sp, #-4]!\t@ Start of GR load expansion", & reg);
+ wcgr = operands[0];
+ operands[0] = reg;
+ output_asm_insn ("ldr%?\t%0, %1", operands);
+
+ operands[0] = wcgr;
+ operands[1] = reg;
+ output_asm_insn ("tmcr%?\t%0, %1", operands);
+ output_asm_insn ("ldr%?\t%0, [sp], #4\t@ End of GR load expansion", & reg);
+
+ return "";
+}
diff --git a/contrib/gcc/config/arm/arm.h b/contrib/gcc/config/arm/arm.h
index eda2d47feff7..3a13d919243b 100644
--- a/contrib/gcc/config/arm/arm.h
+++ b/contrib/gcc/config/arm/arm.h
@@ -1,27 +1,27 @@
/* Definitions of target machine for GNU compiler, for ARM.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk).
More major hacks by Richard Earnshaw (rearnsha@arm.com)
Minor hacks by Nick Clifton (nickc@cygnus.com)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#ifndef GCC_ARM_H
#define GCC_ARM_H
@@ -96,6 +96,12 @@ Boston, MA 02111-1307, USA. */
#define TARGET_CPU_arm9 0x0080
#define TARGET_CPU_arm9tdmi 0x0080
#define TARGET_CPU_xscale 0x0100
+#define TARGET_CPU_ep9312 0x0200
+#define TARGET_CPU_iwmmxt 0x0400
+#define TARGET_CPU_arm926ej_s 0x0800
+#define TARGET_CPU_arm1026ej_s 0x1000
+#define TARGET_CPU_arm1136j_s 0x2000
+#define TARGET_CPU_arm1136jf_s 0x4000
/* Configure didn't specify. */
#define TARGET_CPU_generic 0x8000
@@ -124,12 +130,12 @@ 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
- is not needed. */
+ is not needed. */
extern int return_used_this_function;
/* Used to produce AOF syntax assembler. */
extern GTY(()) rtx aof_pic_label;
-/* Just in case configure has failed to define anything. */
+/* Just in case configure has failed to define anything. */
#ifndef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT TARGET_CPU_generic
#endif
@@ -164,7 +170,21 @@ extern GTY(()) rtx aof_pic_label;
#if TARGET_CPU_DEFAULT == TARGET_CPU_xscale
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__"
#else
-Unrecognized value in TARGET_CPU_DEFAULT.
+#if TARGET_CPU_DEFAULT == TARGET_CPU_ep9312
+#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__ -D__MAVERICK__"
+/* Set TARGET_DEFAULT to the default, but without soft-float. */
+#ifdef TARGET_DEFAULT
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT \
+ (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS | ARM_FLAG_APCS_FRAME)
+#endif
+#else
+#if TARGET_CPU_DEFAULT == TARGET_CPU_iwmmxt
+#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__ -D__IWMMXT__"
+#else
+#error Unrecognized value in TARGET_CPU_DEFAULT.
+#endif
+#endif
#endif
#endif
#endif
@@ -212,6 +232,8 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{march=strongarm1100:-D__ARM_ARCH_4__} \
%{march=xscale:-D__ARM_ARCH_5TE__} \
%{march=xscale:-D__XSCALE__} \
+%{march=ep9312:-D__ARM_ARCH_4T__} \
+%{march=ep9312:-D__MAVERICK__} \
%{march=armv2:-D__ARM_ARCH_2__} \
%{march=armv2a:-D__ARM_ARCH_2__} \
%{march=armv3:-D__ARM_ARCH_3__} \
@@ -251,6 +273,11 @@ Unrecognized value in TARGET_CPU_DEFAULT.
%{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
%{mcpu=xscale:-D__ARM_ARCH_5TE__} \
%{mcpu=xscale:-D__XSCALE__} \
+ %{mcpu=ep9312:-D__ARM_ARCH_4T__} \
+ %{mcpu=ep9312:-D__MAVERICK__} \
+ %{mcpu=iwmmxt:-D__ARM_ARCH_5TE__} \
+ %{mcpu=iwmmxt:-D__XSCALE__} \
+ %{mcpu=iwmmxt:-D__IWMMXT__} \
%{!mcpu*:%(cpp_cpu_arch_default)}} \
"
@@ -263,7 +290,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
+ specification name, and a string constant that used by the GCC driver
program.
Do not define this macro if it does not need to do anything. */
@@ -345,7 +372,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
function tries to return. */
#define ARM_FLAG_ABORT_NORETURN (1 << 13)
-/* Nonzero if function prologues should not load the PIC register. */
+/* Nonzero if function prologues should not load the PIC register. */
#define ARM_FLAG_SINGLE_PIC_BASE (1 << 14)
/* Nonzero if all call instructions should be indirect. */
@@ -376,6 +403,9 @@ Unrecognized value in TARGET_CPU_DEFAULT.
/* Nonzero means to use ARM/Thumb Procedure Call Standard conventions. */
#define ARM_FLAG_ATPCS (1 << 22)
+/* Fix invalid Cirrus instruction combinations by inserting NOPs. */
+#define CIRRUS_FIX_INVALID_INSNS (1 << 23)
+
#define TARGET_APCS_FRAME (target_flags & ARM_FLAG_APCS_FRAME)
#define TARGET_POKE_FUNCTION_NAME (target_flags & ARM_FLAG_POKE)
#define TARGET_FPE (target_flags & ARM_FLAG_FPE)
@@ -387,6 +417,10 @@ Unrecognized value in TARGET_CPU_DEFAULT.
#define TARGET_MMU_TRAPS (target_flags & ARM_FLAG_MMU_TRAPS)
#define TARGET_SOFT_FLOAT (target_flags & ARM_FLAG_SOFT_FLOAT)
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
+#define TARGET_CIRRUS (arm_is_cirrus)
+#define TARGET_ANY_HARD_FLOAT (TARGET_HARD_FLOAT || TARGET_CIRRUS)
+#define TARGET_IWMMXT (arm_arch_iwmmxt)
+#define TARGET_REALLY_IWMMXT (TARGET_IWMMXT && TARGET_ARM)
#define TARGET_VFP (target_flags & ARM_FLAG_VFP)
#define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END)
#define TARGET_INTERWORK (target_flags & ARM_FLAG_INTERWORK)
@@ -403,6 +437,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
#define TARGET_BACKTRACE (leaf_function_p () \
? (target_flags & THUMB_FLAG_LEAF_BACKTRACE) \
: (target_flags & THUMB_FLAG_BACKTRACE))
+#define TARGET_CIRRUS_FIX_INVALID_INSNS (target_flags & CIRRUS_FIX_INVALID_INSNS)
/* SUBTARGET_SWITCHES is used to add flags on a per-config basis. */
#ifndef SUBTARGET_SWITCHES
@@ -421,8 +456,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
{"fpe", ARM_FLAG_FPE, "" }, \
{"apcs-32", ARM_FLAG_APCS_32, \
N_("Use the 32-bit version of the APCS") }, \
- {"apcs-26", -ARM_FLAG_APCS_32, \
- N_("Use the 26-bit version of the APCS") }, \
+ {"apcs-26", -ARM_FLAG_APCS_32, ""}, \
{"apcs-stack-check", ARM_FLAG_APCS_STACK, "" }, \
{"no-apcs-stack-check", -ARM_FLAG_APCS_STACK, "" }, \
{"apcs-float", ARM_FLAG_APCS_FLOAT, \
@@ -434,10 +468,6 @@ Unrecognized value in TARGET_CPU_DEFAULT.
{"alignment-traps", ARM_FLAG_MMU_TRAPS, \
N_("The MMU will trap on unaligned accesses") }, \
{"no-alignment-traps", -ARM_FLAG_MMU_TRAPS, "" }, \
- {"short-load-bytes", ARM_FLAG_MMU_TRAPS, "" }, \
- {"no-short-load-bytes", -ARM_FLAG_MMU_TRAPS, "" }, \
- {"short-load-words", -ARM_FLAG_MMU_TRAPS, "" }, \
- {"no-short-load-words", ARM_FLAG_MMU_TRAPS, "" }, \
{"soft-float", ARM_FLAG_SOFT_FLOAT, \
N_("Use library calls to perform FP operations") }, \
{"hard-float", -ARM_FLAG_SOFT_FLOAT, \
@@ -481,6 +511,10 @@ Unrecognized value in TARGET_CPU_DEFAULT.
N_("Thumb: Assume function pointers may go to non-Thumb aware code") }, \
{"no-caller-super-interworking", -THUMB_FLAG_CALLER_SUPER_INTERWORKING, \
"" }, \
+ {"cirrus-fix-invalid-insns", CIRRUS_FIX_INVALID_INSNS, \
+ N_("Cirrus: Place NOPs to avoid invalid instruction combinations") }, \
+ {"no-cirrus-fix-invalid-insns", -CIRRUS_FIX_INVALID_INSNS, \
+ N_("Cirrus: Do not break up invalid instruction combinations with NOPs") },\
SUBTARGET_SWITCHES \
{"", TARGET_DEFAULT, "" } \
}
@@ -488,19 +522,33 @@ Unrecognized value in TARGET_CPU_DEFAULT.
#define TARGET_OPTIONS \
{ \
{"cpu=", & arm_select[0].string, \
- N_("Specify the name of the target CPU") }, \
+ N_("Specify the name of the target CPU"), 0}, \
{"arch=", & arm_select[1].string, \
- N_("Specify the name of the target architecture") }, \
- {"tune=", & arm_select[2].string, "" }, \
- {"fpe=", & target_fp_name, "" }, \
+ N_("Specify the name of the target architecture"), 0}, \
+ {"tune=", & arm_select[2].string, "", 0}, \
+ {"fpe=", & target_fp_name, "" , 0}, \
{"fp=", & target_fp_name, \
- N_("Specify the version of the floating point emulator") }, \
+ N_("Specify the version of the floating point emulator"), 0},\
{"structure-size-boundary=", & structure_size_string, \
- N_("Specify the minimum bit alignment of structures") }, \
+ N_("Specify the minimum bit alignment of structures"), 0}, \
{"pic-register=", & arm_pic_register_string, \
- N_("Specify the register to be used for PIC addressing") } \
+ N_("Specify the register to be used for PIC addressing"), 0} \
}
+/* Support for a compile-time default CPU, et cetera. The rules are:
+ --with-arch is ignored if -march or -mcpu are specified.
+ --with-cpu is ignored if -march or -mcpu are specified, and is overridden
+ by --with-arch.
+ --with-tune is ignored if -mtune or -mcpu are specified (but not affected
+ by -march).
+ --with-float is ignored if -mhard-float or -msoft-float are
+ specified. */
+#define OPTION_DEFAULT_SPECS \
+ {"arch", "%{!march=*:%{!mcpu=*:-march=%(VALUE)}}" }, \
+ {"cpu", "%{!march=*:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
+ {"tune", "%{!mcpu=*:%{!mtune=*:-mtune=%(VALUE)}}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }
+
struct arm_cpu_select
{
const char * string;
@@ -519,33 +567,45 @@ enum prog_mode_type
prog_mode32
};
-/* Recast the program mode class to be the prog_mode attribute */
+/* Recast the program mode class to be the prog_mode attribute. */
#define arm_prog_mode ((enum attr_prog_mode) arm_prgmode)
extern enum prog_mode_type arm_prgmode;
/* What sort of floating point unit do we have? Hardware or software.
If software, is it issue 2 or issue 3? */
-enum floating_point_type
+enum fputype
{
- FP_HARD,
- FP_SOFT2,
- FP_SOFT3
+ /* Software floating point, FPA style double fmt. */
+ FPUTYPE_SOFT_FPA,
+ /* Full FPA support. */
+ FPUTYPE_FPA,
+ /* Emulated FPA hardware, Issue 2 emulator (no LFM/SFM). */
+ FPUTYPE_FPA_EMU2,
+ /* Emulated FPA hardware, Issue 3 emulator. */
+ FPUTYPE_FPA_EMU3,
+ /* Cirrus Maverick floating point co-processor. */
+ FPUTYPE_MAVERICK
};
/* Recast the floating point class to be the floating point attribute. */
-#define arm_fpu_attr ((enum attr_fpu) arm_fpu)
+#define arm_fpu_attr ((enum attr_fpu) arm_fpu_tune)
/* What type of floating point to tune for */
-extern enum floating_point_type arm_fpu;
+extern enum fputype arm_fpu_tune;
/* What type of floating point instructions are available */
-extern enum floating_point_type arm_fpu_arch;
+extern enum fputype arm_fpu_arch;
/* Default floating point architecture. Override in sub-target if
necessary. */
-#ifndef FP_DEFAULT
-#define FP_DEFAULT FP_SOFT2
+#ifndef FPUTYPE_DEFAULT
+#define FPUTYPE_DEFAULT FPUTYPE_FPA_EMU2
+#endif
+
+#if TARGET_CPU_DEFAULT == TARGET_CPU_ep9312
+#undef FPUTYPE_DEFAULT
+#define FPUTYPE_DEFAULT FPUTYPE_MAVERICK
#endif
/* Nonzero if the processor has a fast multiply insn, and one that does
@@ -570,14 +630,23 @@ extern int thumb_code;
/* Nonzero if this chip is a StrongARM. */
extern int arm_is_strong;
+/* Nonzero if this chip is a Cirrus variant. */
+extern int arm_is_cirrus;
+
+/* Nonzero if this chip supports Intel XScale with Wireless MMX technology. */
+extern int arm_arch_iwmmxt;
+
/* Nonzero if this chip is an XScale. */
-extern int arm_is_xscale;
+extern int arm_arch_xscale;
+
+/* Nonzero if tuning for XScale */
+extern int arm_tune_xscale;
/* Nonzero if this chip is an ARM6 or an ARM7. */
extern int arm_is_6_or_7;
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_APCS_FRAME)
+#define TARGET_DEFAULT (ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
#endif
/* The frame pointer register used in gcc has nothing to do with debugging;
@@ -641,20 +710,6 @@ extern int arm_is_6_or_7;
/* This is required to ensure that push insns always push a word. */
#define PROMOTE_FUNCTION_ARGS
-/* For the ARM:
- I think I have added all the code to make this work. Unfortunately,
- early releases of the floating point emulation code on RISCiX used a
- different format for extended precision numbers. On my RISCiX box there
- is a bug somewhere which causes the machine to lock up when running enquire
- with long doubles. There is the additional aspect that Norcroft C
- treats long doubles as doubles and we ought to remain compatible.
- Perhaps someone with an FPA coprocessor and not running RISCiX would like
- to try this someday. */
-/* #define LONG_DOUBLE_TYPE_SIZE 96 */
-
-/* Disable XFmode patterns in md file */
-#define ENABLE_XF_PATTERNS 0
-
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */
#define BITS_BIG_ENDIAN 0
@@ -679,14 +734,16 @@ extern int arm_is_6_or_7;
#endif
/* Define this if most significant word of doubles is the lowest numbered.
- The rules are different based on whether or not we use FPA-format or
- VFP-format doubles. */
+ The rules are different based on whether or not we use FPA-format,
+ VFP-format or some other floating point co-processor's format doubles. */
#define FLOAT_WORDS_BIG_ENDIAN (arm_float_words_big_endian ())
#define UNITS_PER_WORD 4
#define PARM_BOUNDARY 32
+#define IWMMXT_ALIGNMENT 64
+
#define STACK_BOUNDARY 32
#define PREFERRED_STACK_BOUNDARY (TARGET_ATPCS ? 64 : 32)
@@ -700,13 +757,53 @@ extern int arm_is_6_or_7;
#define EMPTY_FIELD_BOUNDARY 32
-#define BIGGEST_ALIGNMENT 32
+#define BIGGEST_ALIGNMENT (TARGET_REALLY_IWMMXT ? 64 : 32)
+
+#define TYPE_NEEDS_IWMMXT_ALIGNMENT(TYPE) \
+ (TARGET_REALLY_IWMMXT \
+ && ((TREE_CODE (TYPE) == VECTOR_TYPE) || (TYPE_MODE (TYPE) == DImode) || (TYPE_MODE (TYPE) == DFmode)))
+
+/* XXX Blah -- this macro is used directly by libobjc. Since it
+ supports no vector modes, cut out the complexity and fall back
+ on BIGGEST_FIELD_ALIGNMENT. */
+#ifdef IN_TARGET_LIBS
+#define BIGGEST_FIELD_ALIGNMENT 64
+#else
+/* An expression for the alignment of a structure field FIELD if the
+ alignment computed in the usual way is COMPUTED. GCC uses this
+ value instead of the value in `BIGGEST_ALIGNMENT' or
+ `BIGGEST_FIELD_ALIGNMENT', if defined, for structure fields only. */
+#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
+ (TYPE_NEEDS_IWMMXT_ALIGNMENT (TREE_TYPE (FIELD)) \
+ ? IWMMXT_ALIGNMENT \
+ : (COMPUTED))
+#endif
+
+/* If defined, a C expression to compute the alignment for a static variable.
+ TYPE is the data type, and ALIGN is the alignment that the object
+ would ordinarily have. The value of this macro is used instead of that
+ alignment to align the object.
+
+ If this macro is not defined, then ALIGN is used. */
+#define DATA_ALIGNMENT(TYPE, ALIGN) \
+ (TYPE_NEEDS_IWMMXT_ALIGNMENT (TYPE) ? IWMMXT_ALIGNMENT : ALIGN)
+
+/* If defined, a C expression to compute the alignment for a
+ variables in the local store. TYPE is the data type, and
+ BASIC-ALIGN is the alignment that the object would ordinarily
+ have. The value of this macro is used instead of that alignment
+ to align the object.
+
+ If this macro is not defined, then BASIC-ALIGN is used. */
+#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
+ (TYPE_NEEDS_IWMMXT_ALIGNMENT (TYPE) ? IWMMXT_ALIGNMENT : ALIGN)
/* Make strings word-aligned so strcpy from constants will be faster. */
-#define CONSTANT_ALIGNMENT_FACTOR (TARGET_THUMB || ! arm_is_xscale ? 1 : 2)
+#define CONSTANT_ALIGNMENT_FACTOR (TARGET_THUMB || ! arm_tune_xscale ? 1 : 2)
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
- ((TREE_CODE (EXP) == STRING_CST \
+ ((TARGET_REALLY_IWMMXT && TREE_CODE (EXP) == VECTOR_TYPE) ? IWMMXT_ALIGNMENT : \
+ (TREE_CODE (EXP) == STRING_CST \
&& (ALIGN) < BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR) \
? BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR : (ALIGN))
@@ -721,7 +818,7 @@ extern int arm_structure_size_boundary;
/* This is the value used to initialize arm_structure_size_boundary. If a
particular arm target wants to change the default value it should change
- the definition of this macro, not STRUCTRUE_SIZE_BOUNDARY. See netbsd.h
+ the definition of this macro, not STRUCTURE_SIZE_BOUNDARY. See netbsd.h
for an example of this. */
#ifndef DEFAULT_STRUCTURE_SIZE_BOUNDARY
#define DEFAULT_STRUCTURE_SIZE_BOUNDARY 32
@@ -770,6 +867,11 @@ extern const char * structure_size_string;
*: See CONDITIONAL_REGISTER_USAGE */
+/*
+ mvf0 Cirrus floating point result
+ mvf1-mvf3 Cirrus floating point scratch
+ mvf4-mvf15 S Cirrus floating point variable. */
+
/* The stack backtrace structure is as follows:
fp points to here: | save code pointer | [fp]
| return link value | [fp, #-4]
@@ -799,7 +901,12 @@ extern const char * structure_size_string;
0,0,0,0,0,0,0,0, \
0,0,0,0,0,1,0,1, \
0,0,0,0,0,0,0,0, \
- 1,1,1 \
+ 1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1 \
}
/* 1 for registers not available across function calls.
@@ -809,13 +916,18 @@ extern const char * structure_size_string;
and the register where structure-value addresses are passed.
Aside from that, you can include as many other registers as you like.
The CC is not preserved over function calls on the ARM 6, so it is
- easier to assume this for all. SFP is preserved, since FP is. */
+ easier to assume this for all. SFP is preserved, since FP is. */
#define CALL_USED_REGISTERS \
{ \
1,1,1,1,0,0,0,0, \
0,0,0,0,1,1,1,1, \
1,1,1,1,0,0,0,0, \
- 1,1,1 \
+ 1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1,1,1,1,1, \
+ 1,1,1,1 \
}
#ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE
@@ -832,7 +944,57 @@ extern const char * structure_size_string;
regno <= LAST_ARM_FP_REGNUM; ++regno) \
fixed_regs[regno] = call_used_regs[regno] = 1; \
} \
- if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
+ \
+ if (TARGET_THUMB && optimize_size) \
+ { \
+ /* When optimizing for size, it's better not to use \
+ the HI regs, because of the overhead of stacking \
+ them. */ \
+ for (regno = FIRST_HI_REGNUM; \
+ regno <= LAST_HI_REGNUM; ++regno) \
+ fixed_regs[regno] = call_used_regs[regno] = 1; \
+ } \
+ \
+ /* The link register can be clobbered by any branch insn, \
+ but we have no way to track that at present, so mark \
+ it as unavailable. */ \
+ if (TARGET_THUMB) \
+ fixed_regs[LR_REGNUM] = call_used_regs[LR_REGNUM] = 1; \
+ \
+ if (TARGET_CIRRUS) \
+ { \
+ for (regno = FIRST_ARM_FP_REGNUM; \
+ regno <= LAST_ARM_FP_REGNUM; ++ regno) \
+ fixed_regs[regno] = call_used_regs[regno] = 1; \
+ for (regno = FIRST_CIRRUS_FP_REGNUM; \
+ regno <= LAST_CIRRUS_FP_REGNUM; ++ regno) \
+ { \
+ fixed_regs[regno] = 0; \
+ call_used_regs[regno] = regno < FIRST_CIRRUS_FP_REGNUM + 4; \
+ } \
+ } \
+ \
+ if (TARGET_REALLY_IWMMXT) \
+ { \
+ regno = FIRST_IWMMXT_GR_REGNUM; \
+ /* The 2002/10/09 revision of the XScale ABI has wCG0 \
+ and wCG1 as call-preserved registers. The 2002/11/21 \
+ revision changed this so that all wCG registers are \
+ scratch registers. */ \
+ for (regno = FIRST_IWMMXT_GR_REGNUM; \
+ regno <= LAST_IWMMXT_GR_REGNUM; ++ regno) \
+ fixed_regs[regno] = call_used_regs[regno] = 0; \
+ /* The XScale ABI has wR0 - wR9 as scratch registers, \
+ the rest as call-preserved registers. */ \
+ for (regno = FIRST_IWMMXT_REGNUM; \
+ regno <= LAST_IWMMXT_REGNUM; ++ regno) \
+ { \
+ fixed_regs[regno] = 0; \
+ call_used_regs[regno] = regno < FIRST_IWMMXT_REGNUM + 10; \
+ } \
+ } \
+ \
+ if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
{ \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
@@ -850,7 +1012,7 @@ extern const char * structure_size_string;
SUBTARGET_CONDITIONAL_REGISTER_USAGE \
}
-/* These are a couple of extensions to the formats accecpted
+/* These are a couple of extensions to the formats accepted
by asm_fprintf:
%@ prints out ASM_COMMENT_START
%r prints out REGISTER_PREFIX reg_names[arg] */
@@ -865,7 +1027,7 @@ extern const char * structure_size_string;
break;
/* Round X up to the nearest word. */
-#define ROUND_UP(X) (((X) + 3) & ~3)
+#define ROUND_UP_WORD(X) (((X) + 3) & ~3)
/* Convert fron bytes to ints. */
#define ARM_NUM_INTS(X) (((X) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
@@ -882,7 +1044,7 @@ extern const char * structure_size_string;
/* The number of (integer) argument register available. */
#define NUM_ARG_REGS 4
-/* Return the regiser number of the N'th (integer) argument. */
+/* Return the register number of the N'th (integer) argument. */
#define ARG_REGISTER(N) (N - 1)
#if 0 /* FIXME: The ARM backend has special code to handle structure
@@ -905,8 +1067,11 @@ extern const char * structure_size_string;
/* The number of the last argument register. */
#define LAST_ARG_REGNUM ARG_REGISTER (NUM_ARG_REGS)
-/* The number of the last "lo" register (thumb). */
+/* The numbers of the Thumb register ranges. */
+#define FIRST_LO_REGNUM 0
#define LAST_LO_REGNUM 7
+#define FIRST_HI_REGNUM 8
+#define LAST_HI_REGNUM 11
/* The register that holds the return address in exception handlers. */
#define EXCEPTION_LR_REGNUM 2
@@ -922,7 +1087,7 @@ extern const char * structure_size_string;
should point to a special register that we will make sure is eliminated.
For the Thumb we have another problem. The TPCS defines the frame pointer
- as r11, and GCC belives that it is always possible to use the frame pointer
+ as r11, and GCC believes that it is always possible to use the frame pointer
as base register for addressing purposes. (See comments in
find_reloads_address()). But - the Thumb does not allow high registers,
including r11, to be used as base address registers. Hence our problem.
@@ -930,7 +1095,7 @@ extern const char * structure_size_string;
The solution used here, and in the old thumb port is to use r7 instead of
r11 as the hard frame pointer and to have special code to generate
backtrace structures on the stack (if required to do so via a command line
- option) using r11. This is the only 'user visable' use of r11 as a frame
+ option) using r11. This is the only 'user visible' use of r11 as a frame
pointer. */
#define ARM_HARD_FRAME_POINTER_REGNUM 11
#define THUMB_HARD_FRAME_POINTER_REGNUM 7
@@ -949,14 +1114,30 @@ extern const char * structure_size_string;
#define FIRST_ARM_FP_REGNUM 16
#define LAST_ARM_FP_REGNUM 23
+#define FIRST_IWMMXT_GR_REGNUM 43
+#define LAST_IWMMXT_GR_REGNUM 46
+#define FIRST_IWMMXT_REGNUM 47
+#define LAST_IWMMXT_REGNUM 62
+#define IS_IWMMXT_REGNUM(REGNUM) \
+ (((REGNUM) >= FIRST_IWMMXT_REGNUM) && ((REGNUM) <= LAST_IWMMXT_REGNUM))
+#define IS_IWMMXT_GR_REGNUM(REGNUM) \
+ (((REGNUM) >= FIRST_IWMMXT_GR_REGNUM) && ((REGNUM) <= LAST_IWMMXT_GR_REGNUM))
+
/* Base register for access to local variables of the function. */
#define FRAME_POINTER_REGNUM 25
/* Base register for access to arguments of the function. */
#define ARG_POINTER_REGNUM 26
-/* The number of hard registers is 16 ARM + 8 FPU + 1 CC + 1 SFP. */
-#define FIRST_PSEUDO_REGISTER 27
+#define FIRST_CIRRUS_FP_REGNUM 27
+#define LAST_CIRRUS_FP_REGNUM 42
+#define IS_CIRRUS_REGNUM(REGNUM) \
+ (((REGNUM) >= FIRST_CIRRUS_FP_REGNUM) && ((REGNUM) <= LAST_CIRRUS_FP_REGNUM))
+
+/* The number of hard registers is 16 ARM + 8 FPA + 1 CC + 1 SFP + 1 AFP. */
+/* + 16 Cirrus registers take us up to 43. */
+/* Intel Wireless MMX Technology registers add 16 + 4 more. */
+#define FIRST_PSEUDO_REGISTER 63
/* Value should be nonzero if functions must have frame pointers.
Zero means the frame pointer need not be set up (and parms may be accessed
@@ -973,7 +1154,7 @@ extern const char * structure_size_string;
This is ordinarily the length in words of a value of mode MODE
but can be less for certain modes in special long registers.
- On the ARM regs are UNITS_PER_WORD bits wide; FPU regs can hold any FP
+ On the ARM regs are UNITS_PER_WORD bits wide; FPA regs can hold any FP
mode. */
#define HARD_REGNO_NREGS(REGNO, MODE) \
((TARGET_ARM \
@@ -993,6 +1174,12 @@ extern const char * structure_size_string;
#define MODES_TIEABLE_P(MODE1, MODE2) \
(GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
+#define VECTOR_MODE_SUPPORTED_P(MODE) \
+ ((MODE) == V2SImode || (MODE) == V4HImode || (MODE) == V8QImode)
+
+#define VALID_IWMMXT_REG_MODE(MODE) \
+ (VECTOR_MODE_SUPPORTED_P (MODE) || (MODE) == DImode)
+
/* The order in which register should be allocated. It is good to use ip
since no saving is required (though calls clobber it) and it never contains
function parameters. It is quite good to use lr since other calls may
@@ -1004,6 +1191,11 @@ extern const char * structure_size_string;
3, 2, 1, 0, 12, 14, 4, 5, \
6, 7, 8, 10, 9, 11, 13, 15, \
16, 17, 18, 19, 20, 21, 22, 23, \
+ 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, \
24, 25, 26 \
}
@@ -1016,12 +1208,15 @@ extern const char * structure_size_string;
/* Register and constant classes. */
-/* Register classes: used to be simple, just all ARM regs or all FPU regs
+/* Register classes: used to be simple, just all ARM regs or all FPA regs
Now that the Thumb is involved it has become more complicated. */
enum reg_class
{
NO_REGS,
- FPU_REGS,
+ FPA_REGS,
+ CIRRUS_REGS,
+ IWMMXT_GR_REGS,
+ IWMMXT_REGS,
LO_REGS,
STACK_REG,
BASE_REGS,
@@ -1034,11 +1229,14 @@ enum reg_class
#define N_REG_CLASSES (int) LIM_REG_CLASSES
-/* Give names of register classes as strings for dump file. */
+/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
{ \
"NO_REGS", \
- "FPU_REGS", \
+ "FPA_REGS", \
+ "CIRRUS_REGS", \
+ "IWMMXT_GR_REGS", \
+ "IWMMXT_REGS", \
"LO_REGS", \
"STACK_REG", \
"BASE_REGS", \
@@ -1053,15 +1251,18 @@ enum reg_class
of length N_REG_CLASSES. */
#define REG_CLASS_CONTENTS \
{ \
- { 0x0000000 }, /* NO_REGS */ \
- { 0x0FF0000 }, /* FPU_REGS */ \
- { 0x00000FF }, /* LO_REGS */ \
- { 0x0002000 }, /* STACK_REG */ \
- { 0x00020FF }, /* BASE_REGS */ \
- { 0x000FF00 }, /* HI_REGS */ \
- { 0x1000000 }, /* CC_REG */ \
- { 0x200FFFF }, /* GENERAL_REGS */ \
- { 0x2FFFFFF } /* ALL_REGS */ \
+ { 0x00000000, 0x0 }, /* NO_REGS */ \
+ { 0x00FF0000, 0x0 }, /* FPA_REGS */ \
+ { 0xF8000000, 0x000007FF }, /* CIRRUS_REGS */ \
+ { 0x00000000, 0x00007800 }, /* IWMMXT_GR_REGS */\
+ { 0x00000000, 0x7FFF8000 }, /* IWMMXT_REGS */ \
+ { 0x000000FF, 0x0 }, /* LO_REGS */ \
+ { 0x00002000, 0x0 }, /* STACK_REG */ \
+ { 0x000020FF, 0x0 }, /* BASE_REGS */ \
+ { 0x0000FF00, 0x0 }, /* HI_REGS */ \
+ { 0x01000000, 0x0 }, /* CC_REG */ \
+ { 0x0200FFFF, 0x0 }, /* GENERAL_REGS */\
+ { 0xFAFFFFFF, 0x7FFFFFFF } /* ALL_REGS */ \
}
/* The same information, inverted:
@@ -1070,12 +1271,18 @@ enum reg_class
or could index an array. */
#define REGNO_REG_CLASS(REGNO) arm_regno_class (REGNO)
+/* FPA registers can't do dubreg as all values are reformatted to internal
+ precision. */
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (FPA_REGS, (CLASS)) : 0)
+
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
#define BASE_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS)
/* For the Thumb the high registers cannot be used as base registers
- when addressing quanitities in QI or HI mode; if we don't know the
+ when addressing quantities in QI or HI mode; if we don't know the
mode, then we must be conservative. After reload we must also be
conservative, since we can't support SP+reg addressing, and we
can't fix up any bad substitutions. */
@@ -1086,14 +1293,17 @@ enum reg_class
/* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
registers explicitly used in the rtl to be used as spill registers
but prevents the compiler from extending the lifetime of these
- registers. */
+ registers. */
#define SMALL_REGISTER_CLASSES TARGET_THUMB
/* Get reg_class from a letter such as appears in the machine description.
- We only need constraint `f' for FPU_REGS (`r' == GENERAL_REGS) for the
+ We only need constraint `f' for FPA_REGS (`r' == GENERAL_REGS) for the
ARM, but several more letters for the Thumb. */
#define REG_CLASS_FROM_LETTER(C) \
- ( (C) == 'f' ? FPU_REGS \
+ ( (C) == 'f' ? FPA_REGS \
+ : (C) == 'v' ? CIRRUS_REGS \
+ : (C) == 'y' ? IWMMXT_REGS \
+ : (C) == 'z' ? IWMMXT_GR_REGS \
: (C) == 'l' ? (TARGET_ARM ? GENERAL_REGS : LO_REGS) \
: TARGET_ARM ? NO_REGS \
: (C) == 'h' ? HI_REGS \
@@ -1136,11 +1346,11 @@ enum reg_class
(TARGET_ARM ? \
CONST_OK_FOR_ARM_LETTER (VALUE, C) : CONST_OK_FOR_THUMB_LETTER (VALUE, C))
-/* Constant letter 'G' for the FPU immediate constants.
+/* Constant letter 'G' for the FPA immediate constants.
'H' means the same constant negated. */
#define CONST_DOUBLE_OK_FOR_ARM_LETTER(X, C) \
- ((C) == 'G' ? const_double_rtx_ok_for_fpu (X) : \
- (C) == 'H' ? neg_const_double_rtx_ok_for_fpu (X) : 0)
+ ((C) == 'G' ? const_double_rtx_ok_for_fpa (X) : \
+ (C) == 'H' ? neg_const_double_rtx_ok_for_fpa (X) : 0)
#define CONST_DOUBLE_OK_FOR_LETTER_P(X, C) \
(TARGET_ARM ? \
@@ -1150,15 +1360,16 @@ enum reg_class
an offset from a register.
`S' means any symbol that has the SYMBOL_REF_FLAG set or a CONSTANT_POOL
address. This means that the symbol is in the text segment and can be
- accessed without using a load. */
+ accessed without using a load. */
#define EXTRA_CONSTRAINT_ARM(OP, C) \
((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG : \
(C) == 'R' ? (GET_CODE (OP) == MEM \
&& GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \
&& CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \
- (C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) \
- : 0)
+ (C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) : \
+ (C) == 'T' ? cirrus_memory_offset (OP) : \
+ 0)
#define EXTRA_CONSTRAINT_THUMB(X, C) \
((C) == 'Q' ? (GET_CODE (X) == MEM \
@@ -1200,15 +1411,23 @@ enum reg_class
? GENERAL_REGS : NO_REGS) \
: THUMB_SECONDARY_OUTPUT_RELOAD_CLASS (CLASS, MODE, X))
-/* If we need to load shorts byte-at-a-time, then we need a scratch. */
+/* If we need to load shorts byte-at-a-time, then we need a scratch. */
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
+ /* Cannot load constants into Cirrus registers. */ \
+ ((TARGET_CIRRUS \
+ && (CLASS) == CIRRUS_REGS \
+ && (CONSTANT_P (X) || GET_CODE (X) == SYMBOL_REF)) \
+ ? GENERAL_REGS : \
(TARGET_ARM ? \
+ (((CLASS) == IWMMXT_REGS || (CLASS) == IWMMXT_GR_REGS) \
+ && CONSTANT_P (X)) \
+ ? GENERAL_REGS : \
(((MODE) == HImode && ! arm_arch4 && TARGET_MMU_TRAPS \
&& (GET_CODE (X) == MEM \
|| ((GET_CODE (X) == REG || GET_CODE (X) == SUBREG) \
&& true_regnum (X) == -1))) \
? GENERAL_REGS : NO_REGS) \
- : THUMB_SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X))
+ : THUMB_SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X)))
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
@@ -1231,6 +1450,9 @@ enum reg_class
\
if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode)) \
low = ((val & 0xf) ^ 0x8) - 0x8; \
+ else if (TARGET_CIRRUS) \
+ /* Need to be careful, -256 is not a valid offset. */ \
+ low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
else if (MODE == SImode \
|| (MODE == SFmode && TARGET_SOFT_FLOAT) \
|| ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \
@@ -1267,7 +1489,7 @@ enum reg_class
} \
while (0)
-/* ??? If an HImode FP+large_offset address is converted to an HImode
+/* XXX If an HImode FP+large_offset address is converted to an HImode
SP+large_offset address, then reload won't know how to fix it. It sees
only that SP isn't valid for HImode, and so reloads the SP into an index
register, but the resulting address is still invalid because the offset
@@ -1282,7 +1504,7 @@ enum reg_class
&& GET_CODE (XEXP (X, 0)) == REG \
&& XEXP (X, 0) == stack_pointer_rtx \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
- && ! THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
+ && ! thumb_legitimate_offset_p (MODE, INTVAL (XEXP (X, 1)))) \
{ \
rtx orig_X = X; \
X = copy_rtx (X); \
@@ -1301,15 +1523,24 @@ enum reg_class
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
- ARM regs are UNITS_PER_WORD bits while FPU regs can hold any FP mode */
+ ARM regs are UNITS_PER_WORD bits while FPA regs can hold any FP mode */
#define CLASS_MAX_NREGS(CLASS, MODE) \
- ((CLASS) == FPU_REGS ? 1 : ARM_NUM_REGS (MODE))
+ (((CLASS) == FPA_REGS || (CLASS) == CIRRUS_REGS) ? 1 : ARM_NUM_REGS (MODE))
-/* Moves between FPU_REGS and GENERAL_REGS are two memory insns. */
+/* If defined, gives a class of registers that cannot be used as the
+ operand of a SUBREG that changes the mode of the object illegally. */
+
+/* Moves between FPA_REGS and GENERAL_REGS are two memory insns. */
#define REGISTER_MOVE_COST(MODE, FROM, TO) \
(TARGET_ARM ? \
- ((FROM) == FPU_REGS && (TO) != FPU_REGS ? 20 : \
- (FROM) != FPU_REGS && (TO) == FPU_REGS ? 20 : 2) \
+ ((FROM) == FPA_REGS && (TO) != FPA_REGS ? 20 : \
+ (FROM) != FPA_REGS && (TO) == FPA_REGS ? 20 : \
+ (FROM) == IWMMXT_REGS && (TO) != IWMMXT_REGS ? 4 : \
+ (FROM) != IWMMXT_REGS && (TO) == IWMMXT_REGS ? 4 : \
+ (FROM) == IWMMXT_GR_REGS || (TO) == IWMMXT_GR_REGS ? 20 : \
+ (FROM) == CIRRUS_REGS && (TO) != CIRRUS_REGS ? 20 : \
+ (FROM) != CIRRUS_REGS && (TO) == CIRRUS_REGS ? 20 : \
+ 2) \
: \
((FROM) == HI_REGS || (TO) == HI_REGS) ? 4 : 2)
@@ -1334,8 +1565,8 @@ enum reg_class
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by. */
/* The push insns do not do this rounding implicitly.
- So don't define this. */
-/* #define PUSH_ROUNDING(NPUSHED) ROUND_UP (NPUSHED) */
+ So don't define this. */
+/* #define PUSH_ROUNDING(NPUSHED) ROUND_UP_WORD (NPUSHED) */
/* Define this if the maximum size of all the outgoing args is to be
accumulated and pushed during the prologue. The amount can be
@@ -1361,6 +1592,10 @@ enum reg_class
#define LIBCALL_VALUE(MODE) \
(TARGET_ARM && TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT \
? gen_rtx_REG (MODE, FIRST_ARM_FP_REGNUM) \
+ : TARGET_ARM && TARGET_CIRRUS && GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ ? gen_rtx_REG (MODE, FIRST_CIRRUS_FP_REGNUM) \
+ : TARGET_REALLY_IWMMXT && VECTOR_MODE_SUPPORTED_P (MODE) \
+ ? gen_rtx_REG (MODE, FIRST_IWMMXT_REGNUM) \
: gen_rtx_REG (MODE, ARG_REGISTER (1)))
/* Define how to find the value returned by a function.
@@ -1372,18 +1607,21 @@ enum reg_class
/* 1 if N is a possible register number for a function value.
On the ARM, only r0 and f0 can return results. */
+/* On a Cirrus chip, mvf0 can return results. */
#define FUNCTION_VALUE_REGNO_P(REGNO) \
((REGNO) == ARG_REGISTER (1) \
+ || (TARGET_ARM && ((REGNO) == FIRST_CIRRUS_FP_REGNUM) && TARGET_CIRRUS) \
+ || (TARGET_ARM && ((REGNO) == FIRST_IWMMXT_REGNUM) && TARGET_IWMMXT) \
|| (TARGET_ARM && ((REGNO) == FIRST_ARM_FP_REGNUM) && TARGET_HARD_FLOAT))
/* How large values are returned */
/* A C expression which can inhibit the returning of certain function values
- in registers, based on the type of value. */
+ in registers, based on the type of value. */
#define RETURN_IN_MEMORY(TYPE) arm_return_in_memory (TYPE)
/* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return
values must be in memory. On the ARM, they need only do so if larger
- than a word, or if they contain elements offset from zero in the struct. */
+ than a word, or if they contain elements offset from zero in the struct. */
#define DEFAULT_PCC_STRUCT_RETURN 0
/* Flags for the call/call_value rtl operations set up by function_arg. */
@@ -1417,7 +1655,7 @@ enum reg_class
#define ARM_FT_INTERRUPT (1 << 2) /* Note overlap with FT_ISR and above. */
#define ARM_FT_NAKED (1 << 3) /* No prologue or epilogue. */
#define ARM_FT_VOLATILE (1 << 4) /* Does not return. */
-#define ARM_FT_NESTED (1 << 5) /* Embedded inside another func. */
+#define ARM_FT_NESTED (1 << 5) /* Embedded inside another func. */
/* Some macros to test these flags. */
#define ARM_FUNC_TYPE(t) (t & ARM_FT_TYPE_MASK)
@@ -1430,7 +1668,7 @@ enum reg_class
This is added to the cfun structure. */
typedef struct machine_function GTY(())
{
- /* Additionsl stack adjustment in __builtin_eh_throw. */
+ /* Additional stack adjustment in __builtin_eh_throw. */
rtx eh_epilogue_sp_ofs;
/* Records if LR has to be saved for far jumps. */
int far_jump_used;
@@ -1444,6 +1682,9 @@ typedef struct machine_function GTY(())
unsigned long func_type;
/* Record if the function has a variable argument list. */
int uses_anonymous_args;
+ /* Records if sibcalls are blocked because an argument
+ register is needed to preserve stack alignment. */
+ int sibcall_blocked;
}
machine_function;
@@ -1454,7 +1695,11 @@ typedef struct
{
/* This is the number of registers of arguments scanned so far. */
int nregs;
- /* One of CALL_NORMAL, CALL_LONG or CALL_SHORT . */
+ /* This is the number of iWMMXt register arguments scanned so far. */
+ int iwmmxt_nregs;
+ int named_count;
+ int nargs;
+ /* One of CALL_NORMAL, CALL_LONG or CALL_SHORT. */
int call_cookie;
} CUMULATIVE_ARGS;
@@ -1483,7 +1728,8 @@ typedef struct
this is the number of registers used.
For args passed entirely in registers or entirely in memory, zero. */
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
- ( NUM_ARG_REGS > (CUM).nregs \
+ (VECTOR_MODE_SUPPORTED_P (MODE) ? 0 : \
+ NUM_ARG_REGS > (CUM).nregs \
&& (NUM_ARG_REGS < ((CUM).nregs + ARM_NUM_REGS2 (MODE, TYPE))) \
? NUM_ARG_REGS - (CUM).nregs : 0)
@@ -1499,30 +1745,40 @@ typedef struct
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0.
On the ARM, the offset starts at 0. */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
- arm_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (INDIRECT))
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
+ arm_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL))
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
(TYPE is null for libcalls where that information may not be available.) */
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
+ (CUM).nargs += 1; \
+ if (VECTOR_MODE_SUPPORTED_P (MODE)) \
+ if ((CUM).named_count <= (CUM).nargs) \
+ (CUM).nregs += 2; \
+ else \
+ (CUM).iwmmxt_nregs += 1; \
+ else \
(CUM).nregs += ARM_NUM_REGS2 (MODE, TYPE)
+/* If defined, a C expression that gives the alignment boundary, in bits, of an
+ argument with the specified mode and type. If it is not defined,
+ `PARM_BOUNDARY' is used for all arguments. */
+#define FUNCTION_ARG_BOUNDARY(MODE,TYPE) \
+ (TARGET_REALLY_IWMMXT && (VALID_IWMMXT_REG_MODE (MODE) || ((MODE) == DFmode)) \
+ ? IWMMXT_ALIGNMENT : PARM_BOUNDARY)
+
/* 1 if N is a possible register number for function argument passing.
On the ARM, r0-r3 are used to pass args. */
-#define FUNCTION_ARG_REGNO_P(REGNO) (IN_RANGE ((REGNO), 0, 3))
+#define FUNCTION_ARG_REGNO_P(REGNO) \
+ (IN_RANGE ((REGNO), 0, 3) \
+ || (TARGET_REALLY_IWMMXT && IN_RANGE ((REGNO), FIRST_IWMMXT_REGNUM, FIRST_IWMMXT_REGNUM + 9)))
/* Implement `va_arg'. */
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
arm_va_arg (valist, type)
-/* Tail calling. */
-
-/* A C expression that evaluates to true if it is ok to perform a sibling
- call to DECL. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) arm_function_ok_for_sibcall ((DECL))
-
/* Perform any actions needed for a function that is receiving a variable
number of arguments. CUM is as above. MODE and TYPE are the mode and type
of the current parameter. PRETEND_SIZE is a variable that should be set to
@@ -1610,7 +1866,7 @@ typedef struct
/* Determine if the epilogue should be output as RTL.
You should override this if you define FUNCTION_EXTRA_EPILOGUE. */
#define USE_RETURN_INSN(ISCOND) \
- (TARGET_ARM ? use_return_insn (ISCOND) : 0)
+ (TARGET_ARM ? use_return_insn (ISCOND, NULL) : 0)
/* Definitions for register eliminations.
@@ -1721,7 +1977,7 @@ typedef struct
ldr pc, [pc]
.word static chain value
.word function's address
- ??? FIXME: When the trampoline returns, r8 will be clobbered. */
+ XXX FIXME: When the trampoline returns, r8 will be clobbered. */
#define ARM_TRAMPOLINE_TEMPLATE(FILE) \
{ \
asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n", \
@@ -1770,20 +2026,30 @@ typedef struct
/* Emit RTL insns to initialize the variable parts of a trampoline.
FNADDR is an RTX for the address of the function's pure code.
CXT is an RTX for the static chain value for the function. */
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-{ \
- emit_move_insn \
- (gen_rtx_MEM (SImode, plus_constant (TRAMP, TARGET_ARM ? 8 : 16)), CXT); \
- emit_move_insn \
- (gen_rtx_MEM (SImode, plus_constant (TRAMP, TARGET_ARM ? 12 : 20)), FNADDR); \
+#ifndef INITIALIZE_TRAMPOLINE
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
+{ \
+ emit_move_insn (gen_rtx_MEM (SImode, \
+ plus_constant (TRAMP, \
+ TARGET_ARM ? 8 : 16)), \
+ CXT); \
+ emit_move_insn (gen_rtx_MEM (SImode, \
+ plus_constant (TRAMP, \
+ TARGET_ARM ? 12 : 20)), \
+ FNADDR); \
}
+#endif
/* Addressing modes, and classification of registers for them. */
-#define HAVE_POST_INCREMENT 1
-#define HAVE_PRE_INCREMENT TARGET_ARM
-#define HAVE_POST_DECREMENT TARGET_ARM
-#define HAVE_PRE_DECREMENT TARGET_ARM
+#define HAVE_POST_INCREMENT 1
+#define HAVE_PRE_INCREMENT TARGET_ARM
+#define HAVE_POST_DECREMENT TARGET_ARM
+#define HAVE_PRE_DECREMENT TARGET_ARM
+#define HAVE_PRE_MODIFY_DISP TARGET_ARM
+#define HAVE_POST_MODIFY_DISP TARGET_ARM
+#define HAVE_PRE_MODIFY_REG TARGET_ARM
+#define HAVE_POST_MODIFY_REG TARGET_ARM
/* Macros to check register numbers against specific register classes. */
@@ -1791,7 +2057,7 @@ typedef struct
They give nonzero only if REGNO is a hard reg of the suitable class
or a pseudo reg currently allocated to a suitable hard reg.
Since they use reg_renumber, they are safe only once reg_renumber
- has been allocated, which happens in local-alloc.c. */
+ has been allocated, which happens in local-alloc.c. */
#define TEST_REGNO(R, TEST, VALUE) \
((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE))
@@ -1817,7 +2083,7 @@ typedef struct
REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode)
/* Maximum number of registers that can appear in a valid memory address.
- Shifts in addresses can't be by a register. */
+ Shifts in addresses can't be by a register. */
#define MAX_REGS_PER_ADDRESS 2
/* Recognize any constant value that is a valid address. */
@@ -1872,7 +2138,7 @@ typedef struct
#define SUBTARGET_NAME_ENCODING_LENGTHS
#endif
-/* This is a C fragement for the inside of a switch statement.
+/* This is a C fragment for the inside of a switch statement.
Each case label should return the number of characters to
be stripped from the start of a function's name, if that
name starts with the indicated character. */
@@ -1913,6 +2179,8 @@ typedef struct
|| (X) == hard_frame_pointer_rtx \
|| (X) == arg_pointer_rtx)))
+#define REG_STRICT_P 0
+
#else /* REG_OK_STRICT */
#define ARM_REG_OK_FOR_BASE_P(X) \
@@ -1921,6 +2189,8 @@ typedef struct
#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE) \
THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
+#define REG_STRICT_P 1
+
#endif /* REG_OK_STRICT */
/* Now define some helpers in terms of the above. */
@@ -1948,340 +2218,56 @@ typedef struct
/* 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. */
+ that wants to use this address. */
-/* --------------------------------arm version----------------------------- */
#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))
-/* A C statement (sans semicolon) to jump to LABEL for legitimate index RTXs
- used by the macro GO_IF_LEGITIMATE_ADDRESS. Floating point indices can
- only be small constants. */
-#define ARM_GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL) \
- do \
- { \
- HOST_WIDE_INT range; \
- enum rtx_code code = GET_CODE (INDEX); \
- \
- if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
- { \
- if (code == CONST_INT && INTVAL (INDEX) < 1024 \
- && INTVAL (INDEX) > -1024 \
- && (INTVAL (INDEX) & 3) == 0) \
- goto LABEL; \
- } \
- else \
- { \
- if (ARM_INDEX_REGISTER_RTX_P (INDEX) \
- && GET_MODE_SIZE (MODE) <= 4) \
- goto LABEL; \
- if (GET_MODE_SIZE (MODE) <= 4 && code == MULT \
- && (! arm_arch4 || (MODE) != HImode)) \
- { \
- rtx xiop0 = XEXP (INDEX, 0); \
- rtx xiop1 = XEXP (INDEX, 1); \
- if (ARM_INDEX_REGISTER_RTX_P (xiop0) \
- && power_of_two_operand (xiop1, SImode)) \
- goto LABEL; \
- if (ARM_INDEX_REGISTER_RTX_P (xiop1) \
- && power_of_two_operand (xiop0, SImode)) \
- goto LABEL; \
- } \
- if (GET_MODE_SIZE (MODE) <= 4 \
- && (code == LSHIFTRT || code == ASHIFTRT \
- || code == ASHIFT || code == ROTATERT) \
- && (! arm_arch4 || (MODE) != HImode)) \
- { \
- rtx op = XEXP (INDEX, 1); \
- if (ARM_INDEX_REGISTER_RTX_P (XEXP (INDEX, 0)) \
- && GET_CODE (op) == CONST_INT && INTVAL (op) > 0 \
- && INTVAL (op) <= 31) \
- goto LABEL; \
- } \
- /* NASTY: Since this limits the addressing of unsigned \
- byte loads. */ \
- range = ((MODE) == HImode || (MODE) == QImode) \
- ? (arm_arch4 ? 256 : 4095) : 4096; \
- if (code == CONST_INT && INTVAL (INDEX) < range \
- && INTVAL (INDEX) > -range) \
- goto LABEL; \
- } \
- } \
- while (0)
+#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN) \
+ { \
+ if (arm_legitimate_address_p (MODE, X, REG_STRICT_P)) \
+ goto WIN; \
+ }
-/* Jump to LABEL if X is a valid address RTX. This must take
- REG_OK_STRICT into account when deciding about valid registers.
+#define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE,X,WIN) \
+ { \
+ if (thumb_legitimate_address_p (MODE, X, REG_STRICT_P)) \
+ goto WIN; \
+ }
- Allow REG, REG+REG, REG+INDEX, INDEX+REG, REG-INDEX, and non
- floating SYMBOL_REF to the constant pool. Allow REG-only and
- AUTINC-REG if handling TImode or HImode. Other symbol refs must be
- forced though a static cell to ensure addressability. */
-#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
-{ \
- if (ARM_BASE_REGISTER_RTX_P (X)) \
- goto LABEL; \
- else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \
- && GET_CODE (XEXP (X, 0)) == REG \
- && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \
- goto LABEL; \
- else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \
- && (GET_CODE (X) == LABEL_REF \
- || (GET_CODE (X) == CONST \
- && GET_CODE (XEXP ((X), 0)) == PLUS \
- && GET_CODE (XEXP (XEXP ((X), 0), 0)) == LABEL_REF \
- && GET_CODE (XEXP (XEXP ((X), 0), 1)) == CONST_INT)))\
- goto LABEL; \
- else if ((MODE) == TImode) \
- ; \
- else if ((MODE) == DImode || (TARGET_SOFT_FLOAT && (MODE) == DFmode)) \
- { \
- if (GET_CODE (X) == PLUS && ARM_BASE_REGISTER_RTX_P (XEXP (X, 0)) \
- && GET_CODE (XEXP (X, 1)) == CONST_INT) \
- { \
- HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
- if (val == 4 || val == -4 || val == -8) \
- goto LABEL; \
- } \
- } \
- else if (GET_CODE (X) == PLUS) \
- { \
- rtx xop0 = XEXP (X, 0); \
- rtx xop1 = XEXP (X, 1); \
- \
- if (ARM_BASE_REGISTER_RTX_P (xop0)) \
- ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL); \
- else if (ARM_BASE_REGISTER_RTX_P (xop1)) \
- ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL); \
- } \
- /* Reload currently can't handle MINUS, so disable this for now */ \
- /* else if (GET_CODE (X) == MINUS) \
- { \
- rtx xop0 = XEXP (X,0); \
- rtx xop1 = XEXP (X,1); \
- \
- if (ARM_BASE_REGISTER_RTX_P (xop0)) \
- ARM_GO_IF_LEGITIMATE_INDEX (MODE, -1, xop1, LABEL); \
- } */ \
- else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \
- && GET_CODE (X) == SYMBOL_REF \
- && CONSTANT_POOL_ADDRESS_P (X) \
- && ! (flag_pic \
- && symbol_mentioned_p (get_pool_constant (X)))) \
- goto LABEL; \
- else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC) \
- && (GET_MODE_SIZE (MODE) <= 4) \
- && GET_CODE (XEXP (X, 0)) == REG \
- && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \
- goto LABEL; \
-}
-
-/* ---------------------thumb version----------------------------------*/
-#define THUMB_LEGITIMATE_OFFSET(MODE, VAL) \
- (GET_MODE_SIZE (MODE) == 1 ? ((unsigned HOST_WIDE_INT) (VAL) < 32) \
- : GET_MODE_SIZE (MODE) == 2 ? ((unsigned HOST_WIDE_INT) (VAL) < 64 \
- && ((VAL) & 1) == 0) \
- : ((VAL) >= 0 && ((VAL) + GET_MODE_SIZE (MODE)) <= 128 \
- && ((VAL) & 3) == 0))
-
-/* The AP may be eliminated to either the SP or the FP, so we use the
- least common denominator, e.g. SImode, and offsets from 0 to 64. */
-
-/* ??? Verify whether the above is the right approach. */
-
-/* ??? Also, the FP may be eliminated to the SP, so perhaps that
- needs special handling also. */
-
-/* ??? Look at how the mips16 port solves this problem. It probably uses
- better ways to solve some of these problems. */
-
-/* Although it is not incorrect, we don't accept QImode and HImode
- 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. */
-#define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
-{ \
-/* ??? Not clear if this is right. Experiment. */ \
- if (GET_MODE_SIZE (MODE) < 4 \
- && ! (reload_in_progress || reload_completed) \
- && ( reg_mentioned_p (frame_pointer_rtx, X) \
- || reg_mentioned_p (arg_pointer_rtx, X) \
- || reg_mentioned_p (virtual_incoming_args_rtx, X) \
- || reg_mentioned_p (virtual_outgoing_args_rtx, X) \
- || reg_mentioned_p (virtual_stack_dynamic_rtx, X) \
- || reg_mentioned_p (virtual_stack_vars_rtx, X))) \
- ; \
- /* Accept any base register. SP only in SImode or larger. */ \
- else if (GET_CODE (X) == REG \
- && THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE)) \
- goto WIN; \
- /* This is PC relative data before MACHINE_DEPENDENT_REORG runs. */ \
- else if (GET_MODE_SIZE (MODE) >= 4 && CONSTANT_P (X) \
- && GET_CODE (X) == SYMBOL_REF \
- && CONSTANT_POOL_ADDRESS_P (X) && ! flag_pic) \
- goto WIN; \
- /* This is PC relative data after MACHINE_DEPENDENT_REORG runs. */ \
- else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \
- && (GET_CODE (X) == LABEL_REF \
- || (GET_CODE (X) == CONST \
- && GET_CODE (XEXP (X, 0)) == PLUS \
- && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT))) \
- goto WIN; \
- /* Post-inc indexing only supported for SImode and larger. */ \
- else if (GET_CODE (X) == POST_INC && GET_MODE_SIZE (MODE) >= 4 \
- && GET_CODE (XEXP (X, 0)) == REG \
- && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0))) \
- goto WIN; \
- else if (GET_CODE (X) == PLUS) \
- { \
- /* REG+REG address can be any two index registers. */ \
- /* We disallow FRAME+REG addressing since we know that FRAME \
- will be replaced with STACK, and SP relative addressing only \
- permits SP+OFFSET. */ \
- if (GET_MODE_SIZE (MODE) <= 4 \
- && GET_CODE (XEXP (X, 0)) == REG \
- && GET_CODE (XEXP (X, 1)) == REG \
- && XEXP (X, 0) != frame_pointer_rtx \
- && XEXP (X, 1) != frame_pointer_rtx \
- && XEXP (X, 0) != virtual_stack_vars_rtx \
- && XEXP (X, 1) != virtual_stack_vars_rtx \
- && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
- && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 1))) \
- goto WIN; \
- /* REG+const has 5-7 bit offset for non-SP registers. */ \
- else if (GET_CODE (XEXP (X, 0)) == REG \
- && (THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
- || XEXP (X, 0) == arg_pointer_rtx) \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
- goto WIN; \
- /* REG+const has 10 bit offset for SP, but only SImode and \
- larger is supported. */ \
- /* ??? Should probably check for DI/DFmode overflow here \
- just like GO_IF_LEGITIMATE_OFFSET does. */ \
- else if (GET_CODE (XEXP (X, 0)) == REG \
- && REGNO (XEXP (X, 0)) == STACK_POINTER_REGNUM \
- && GET_MODE_SIZE (MODE) >= 4 \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (X, 1)) \
- + GET_MODE_SIZE (MODE)) <= 1024 \
- && (INTVAL (XEXP (X, 1)) & 3) == 0) \
- goto WIN; \
- else if (GET_CODE (XEXP (X, 0)) == REG \
- && REGNO (XEXP (X, 0)) == FRAME_POINTER_REGNUM \
- && GET_MODE_SIZE (MODE) >= 4 \
- && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (INTVAL (XEXP (X, 1)) & 3) == 0) \
- goto WIN; \
- } \
- else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \
- && GET_CODE (X) == SYMBOL_REF \
- && CONSTANT_POOL_ADDRESS_P (X) \
- && ! (flag_pic \
- && symbol_mentioned_p (get_pool_constant (X)))) \
- goto WIN; \
-}
-
-/* ------------------------------------------------------------------- */
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
if (TARGET_ARM) \
ARM_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN) \
else /* if (TARGET_THUMB) */ \
THUMB_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN)
-/* ------------------------------------------------------------------- */
+
/* Try machine-dependent ways of modifying an illegitimate address
- to be legitimate. If we find one, return the new, valid address.
- This macro is used in only one place: `memory_address' in explow.c.
-
- 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.
-
- On the ARM, try to convert [REG, #BIGCONST]
- into ADD BASE, REG, #UPPERCONST and [BASE, #VALIDCONST],
- where VALIDCONST == 0 in case of TImode. */
-#define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-{ \
- if (GET_CODE (X) == PLUS) \
- { \
- rtx xop0 = XEXP (X, 0); \
- rtx xop1 = XEXP (X, 1); \
- \
- if (CONSTANT_P (xop0) && ! symbol_mentioned_p (xop0)) \
- xop0 = force_reg (SImode, xop0); \
- if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
- xop1 = force_reg (SImode, xop1); \
- if (ARM_BASE_REGISTER_RTX_P (xop0) \
- && GET_CODE (xop1) == CONST_INT) \
- { \
- HOST_WIDE_INT n, low_n; \
- rtx base_reg, val; \
- n = INTVAL (xop1); \
- \
- if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode)) \
- { \
- low_n = n & 0x0f; \
- n &= ~0x0f; \
- if (low_n > 4) \
- { \
- n += 16; \
- low_n -= 16; \
- } \
- } \
- else \
- { \
- low_n = ((MODE) == TImode ? 0 \
- : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff)); \
- n -= low_n; \
- } \
- base_reg = gen_reg_rtx (SImode); \
- val = force_operand (gen_rtx_PLUS (SImode, xop0, \
- GEN_INT (n)), NULL_RTX); \
- emit_move_insn (base_reg, val); \
- (X) = (low_n == 0 ? base_reg \
- : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n))); \
- } \
- else if (xop0 != XEXP (X, 0) || xop1 != XEXP (x, 1)) \
- (X) = gen_rtx_PLUS (SImode, xop0, xop1); \
- } \
- else if (GET_CODE (X) == MINUS) \
- { \
- rtx xop0 = XEXP (X, 0); \
- rtx xop1 = XEXP (X, 1); \
- \
- if (CONSTANT_P (xop0)) \
- xop0 = force_reg (SImode, xop0); \
- if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
- xop1 = force_reg (SImode, xop1); \
- if (xop0 != XEXP (X, 0) || xop1 != XEXP (X, 1)) \
- (X) = gen_rtx_MINUS (SImode, xop0, xop1); \
- } \
- if (flag_pic) \
- (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
- if (memory_address_p (MODE, X)) \
- goto WIN; \
-}
+ to be legitimate. If we find one, return the new, valid address. */
+#define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
+do { \
+ X = arm_legitimize_address (X, OLDX, MODE); \
+ \
+ if (memory_address_p (MODE, X)) \
+ goto WIN; \
+} while (0)
-#define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
- if (flag_pic) \
- (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX);
-
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
- if (TARGET_ARM) \
- ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN) \
- else \
- THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN)
+#define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
+do { \
+ if (flag_pic) \
+ (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
+} while (0)
+
+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
+do { \
+ if (TARGET_ARM) \
+ ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN); \
+ else \
+ THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN); \
+} while (0)
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for. */
@@ -2305,7 +2291,7 @@ typedef struct
/* Define as C expression which evaluates to nonzero if the tablejump
instruction expects the table to contain offsets from the address of the
table.
- Do not define this if the table should contain absolute addresses. */
+ Do not define this if the table should contain absolute addresses. */
/* #define CASE_VECTOR_PC_RELATIVE 1 */
/* signed 'char' is most compatible, but RISC OS wants it unsigned.
@@ -2322,7 +2308,7 @@ typedef struct
#define MOVE_MAX 4
#undef MOVE_RATIO
-#define MOVE_RATIO (arm_is_xscale ? 4 : 2)
+#define MOVE_RATIO (arm_tune_xscale ? 4 : 2)
/* Define if operations between registers always perform the operation
on the full register even if a narrower mode is specified. */
@@ -2350,7 +2336,7 @@ typedef struct
/* This is all wrong. Defining SHIFT_COUNT_TRUNCATED tells combine that
code like (X << (Y % 32)) for register X, Y is equivalent to (X << Y).
On the arm, Y in a register is used modulo 256 for the shift. Only for
- rotates is modulo 32 used. */
+ rotates is modulo 32 used. */
/* #define SHIFT_COUNT_TRUNCATED 1 */
/* All integers have the same format so truncation is easy. */
@@ -2370,44 +2356,12 @@ typedef struct
( (X) == frame_pointer_rtx || (X) == stack_pointer_rtx \
|| (X) == arg_pointer_rtx)
-#define DEFAULT_RTX_COSTS(X, CODE, OUTER_CODE) \
- return arm_rtx_costs (X, CODE, OUTER_CODE);
-
/* Moves to and from memory are quite expensive */
#define MEMORY_MOVE_COST(M, CLASS, IN) \
(TARGET_ARM ? 10 : \
((GET_MODE_SIZE (M) < 4 ? 8 : 2 * GET_MODE_SIZE (M)) \
* (CLASS == LO_REGS ? 1 : 2)))
-/* All address computations that can be done are free, but rtx cost returns
- the same for practically all of them. So we weight the different types
- of address here in the order (most pref first):
- PRE/POST_INC/DEC, SHIFT or NON-INT sum, INT sum, REG, MEM or LABEL. */
-#define ARM_ADDRESS_COST(X) \
- (10 - ((GET_CODE (X) == MEM || GET_CODE (X) == LABEL_REF \
- || GET_CODE (X) == SYMBOL_REF) \
- ? 0 \
- : ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC \
- || GET_CODE (X) == POST_INC || GET_CODE (X) == POST_DEC) \
- ? 10 \
- : (((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS) \
- ? 6 + (GET_CODE (XEXP (X, 1)) == CONST_INT ? 2 \
- : ((GET_RTX_CLASS (GET_CODE (XEXP (X, 0))) == '2' \
- || GET_RTX_CLASS (GET_CODE (XEXP (X, 0))) == 'c' \
- || GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == '2' \
- || GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == 'c') \
- ? 1 : 0)) \
- : 4)))))
-
-#define THUMB_ADDRESS_COST(X) \
- ((GET_CODE (X) == REG \
- || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \
- && GET_CODE (XEXP (X, 1)) == CONST_INT)) \
- ? 1 : 2)
-
-#define ADDRESS_COST(X) \
- (TARGET_ARM ? ARM_ADDRESS_COST (X) : THUMB_ADDRESS_COST (X))
-
/* Try to generate sequences that don't involve branches, we can then use
conditional instructions */
#define BRANCH_COST \
@@ -2444,13 +2398,13 @@ extern const char * arm_pic_register_string;
extern int making_const_table;
/* Handle pragmas for compatibility with Intel's compilers. */
-#define REGISTER_TARGET_PRAGMAS(PFILE) do { \
- cpp_register_pragma (PFILE, 0, "long_calls", arm_pr_long_calls); \
- cpp_register_pragma (PFILE, 0, "no_long_calls", arm_pr_no_long_calls); \
- cpp_register_pragma (PFILE, 0, "long_calls_off", arm_pr_long_calls_off); \
+#define REGISTER_TARGET_PRAGMAS() do { \
+ c_register_pragma (0, "long_calls", arm_pr_long_calls); \
+ c_register_pragma (0, "no_long_calls", arm_pr_no_long_calls); \
+ c_register_pragma (0, "long_calls_off", arm_pr_long_calls_off); \
} while (0)
-/* Condition code information. */
+/* Condition code information. */
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison. */
@@ -2472,54 +2426,33 @@ extern int making_const_table;
} \
while (0)
-#define STORE_FLAG_VALUE 1
-
+/* The arm5 clz instruction returns 32. */
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
-
-/* Gcc puts the pool in the wrong place for ARM, since we can only
- load addresses a limited distance around the pc. We do some
- special munging to move the constant pool values to the correct
- point in the code. */
-#define MACHINE_DEPENDENT_REORG(INSN) \
- arm_reorg (INSN); \
-
#undef ASM_APP_OFF
#define ASM_APP_OFF (TARGET_THUMB ? "\t.code\t16\n" : "")
-/* Output an internal label definition. */
-#ifndef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) \
- do \
- { \
- char * s = (char *) alloca (40 + strlen (PREFIX)); \
- \
- if (arm_ccfsm_state == 3 && arm_target_label == (NUM) \
- && !strcmp (PREFIX, "L")) \
- { \
- arm_ccfsm_state = 0; \
- arm_target_insn = NULL; \
- } \
- ASM_GENERATE_INTERNAL_LABEL (s, (PREFIX), (NUM)); \
- ASM_OUTPUT_LABEL (STREAM, s); \
- } \
- while (0)
-#endif
-
/* Output a push or a pop instruction (only used when profiling). */
#define ASM_OUTPUT_REG_PUSH(STREAM, REGNO) \
- if (TARGET_ARM) \
- asm_fprintf (STREAM,"\tstmfd\t%r!,{%r}\n", \
- STACK_POINTER_REGNUM, REGNO); \
- else \
- asm_fprintf (STREAM, "\tpush {%r}\n", REGNO)
+ do \
+ { \
+ if (TARGET_ARM) \
+ asm_fprintf (STREAM,"\tstmfd\t%r!,{%r}\n", \
+ STACK_POINTER_REGNUM, REGNO); \
+ else \
+ asm_fprintf (STREAM, "\tpush {%r}\n", REGNO); \
+ } while (0)
#define ASM_OUTPUT_REG_POP(STREAM, REGNO) \
- if (TARGET_ARM) \
- asm_fprintf (STREAM, "\tldmfd\t%r!,{%r}\n", \
- STACK_POINTER_REGNUM, REGNO); \
- else \
- asm_fprintf (STREAM, "\tpop {%r}\n", REGNO)
+ do \
+ { \
+ if (TARGET_ARM) \
+ asm_fprintf (STREAM, "\tldmfd\t%r!,{%r}\n", \
+ STACK_POINTER_REGNUM, REGNO); \
+ else \
+ asm_fprintf (STREAM, "\tpop {%r}\n", REGNO); \
+ } while (0)
/* This is how to output a label which precedes a jumptable. Since
Thumb instructions are 2 bytes, we may need explicit alignment here. */
@@ -2529,7 +2462,7 @@ extern int making_const_table;
{ \
if (TARGET_THUMB) \
ASM_OUTPUT_ALIGN (FILE, 2); \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \
+ (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); \
} \
while (0)
@@ -2538,10 +2471,11 @@ extern int making_const_table;
{ \
if (TARGET_THUMB) \
{ \
- if (is_called_in_ARM_mode (DECL)) \
+ if (is_called_in_ARM_mode (DECL) \
+ || current_function_is_thunk) \
fprintf (STREAM, "\t.code 32\n") ; \
else \
- fprintf (STREAM, "\t.thumb_func\n") ; \
+ fprintf (STREAM, "\t.code 16\n\t.thumb_func\n") ; \
} \
if (TARGET_POKE_FUNCTION_NAME) \
arm_poke_function_name (STREAM, (char *) NAME); \
@@ -2572,19 +2506,19 @@ extern int making_const_table;
/* To support -falign-* switches we need to use .p2align so
that alignment directives in code sections will be padded
with no-op instructions, rather than zeroes. */
-#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
+#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE, LOG, MAX_SKIP) \
if ((LOG) != 0) \
{ \
if ((MAX_SKIP) == 0) \
- fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+ fprintf ((FILE), "\t.p2align %d\n", (int) (LOG)); \
else \
fprintf ((FILE), "\t.p2align %d,,%d\n", \
- (LOG), (MAX_SKIP)); \
+ (int) (LOG), (int) (MAX_SKIP)); \
}
#endif
/* Only perform branch elimination (by making instructions conditional) if
- we're optimising. Otherwise it's of no use anyway. */
+ we're optimizing. Otherwise it's of no use anyway. */
#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
if (TARGET_ARM && optimize) \
arm_final_prescan_insn (INSN); \
@@ -2609,79 +2543,99 @@ extern int making_const_table;
: 0))))
/* Output the address of an operand. */
-#define ARM_PRINT_OPERAND_ADDRESS(STREAM, X) \
-{ \
- int is_minus = GET_CODE (X) == MINUS; \
- \
- if (GET_CODE (X) == REG) \
- asm_fprintf (STREAM, "[%r, #0]", REGNO (X)); \
- else if (GET_CODE (X) == PLUS || is_minus) \
- { \
- rtx base = XEXP (X, 0); \
- rtx index = XEXP (X, 1); \
- HOST_WIDE_INT offset = 0; \
- if (GET_CODE (base) != REG) \
- { \
- /* Ensure that BASE is a register */ \
- /* (one of them must be). */ \
- rtx temp = base; \
- base = index; \
- index = temp; \
- } \
- switch (GET_CODE (index)) \
- { \
- case CONST_INT: \
- offset = INTVAL (index); \
- if (is_minus) \
- offset = -offset; \
- asm_fprintf (STREAM, "[%r, #%d]", \
- REGNO (base), offset); \
- break; \
- \
- case REG: \
- asm_fprintf (STREAM, "[%r, %s%r]", \
- REGNO (base), is_minus ? "-" : "", \
- REGNO (index)); \
- break; \
- \
- case MULT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- case ASHIFT: \
- case ROTATERT: \
- { \
- asm_fprintf (STREAM, "[%r, %s%r", \
- REGNO (base), is_minus ? "-" : "", \
- REGNO (XEXP (index, 0))); \
- arm_print_operand (STREAM, index, 'S'); \
- fputs ("]", STREAM); \
- break; \
- } \
- \
- default: \
- abort(); \
- } \
- } \
- else if ( GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_INC\
- || GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_DEC)\
- { \
- extern int output_memory_reference_mode; \
- \
- if (GET_CODE (XEXP (X, 0)) != REG) \
- abort (); \
- \
- if (GET_CODE (X) == PRE_DEC || GET_CODE (X) == PRE_INC) \
- asm_fprintf (STREAM, "[%r, #%s%d]!", \
- REGNO (XEXP (X, 0)), \
- GET_CODE (X) == PRE_DEC ? "-" : "", \
- GET_MODE_SIZE (output_memory_reference_mode));\
- else \
- asm_fprintf (STREAM, "[%r], #%s%d", \
- REGNO (XEXP (X, 0)), \
- GET_CODE (X) == POST_DEC ? "-" : "", \
- GET_MODE_SIZE (output_memory_reference_mode));\
- } \
- else output_addr_const (STREAM, X); \
+#define ARM_PRINT_OPERAND_ADDRESS(STREAM, X) \
+{ \
+ int is_minus = GET_CODE (X) == MINUS; \
+ \
+ if (GET_CODE (X) == REG) \
+ asm_fprintf (STREAM, "[%r, #0]", REGNO (X)); \
+ else if (GET_CODE (X) == PLUS || is_minus) \
+ { \
+ rtx base = XEXP (X, 0); \
+ rtx index = XEXP (X, 1); \
+ HOST_WIDE_INT offset = 0; \
+ if (GET_CODE (base) != REG) \
+ { \
+ /* Ensure that BASE is a register. */ \
+ /* (one of them must be). */ \
+ rtx temp = base; \
+ base = index; \
+ index = temp; \
+ } \
+ switch (GET_CODE (index)) \
+ { \
+ case CONST_INT: \
+ offset = INTVAL (index); \
+ if (is_minus) \
+ offset = -offset; \
+ asm_fprintf (STREAM, "[%r, #%wd]", \
+ REGNO (base), offset); \
+ break; \
+ \
+ case REG: \
+ asm_fprintf (STREAM, "[%r, %s%r]", \
+ REGNO (base), is_minus ? "-" : "", \
+ REGNO (index)); \
+ break; \
+ \
+ case MULT: \
+ case ASHIFTRT: \
+ case LSHIFTRT: \
+ case ASHIFT: \
+ case ROTATERT: \
+ { \
+ asm_fprintf (STREAM, "[%r, %s%r", \
+ REGNO (base), is_minus ? "-" : "", \
+ REGNO (XEXP (index, 0))); \
+ arm_print_operand (STREAM, index, 'S'); \
+ fputs ("]", STREAM); \
+ break; \
+ } \
+ \
+ default: \
+ abort(); \
+ } \
+ } \
+ else if (GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_INC \
+ || GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_DEC) \
+ { \
+ extern enum machine_mode output_memory_reference_mode; \
+ \
+ if (GET_CODE (XEXP (X, 0)) != REG) \
+ abort (); \
+ \
+ if (GET_CODE (X) == PRE_DEC || GET_CODE (X) == PRE_INC) \
+ asm_fprintf (STREAM, "[%r, #%s%d]!", \
+ REGNO (XEXP (X, 0)), \
+ GET_CODE (X) == PRE_DEC ? "-" : "", \
+ GET_MODE_SIZE (output_memory_reference_mode)); \
+ else \
+ asm_fprintf (STREAM, "[%r], #%s%d", \
+ REGNO (XEXP (X, 0)), \
+ GET_CODE (X) == POST_DEC ? "-" : "", \
+ GET_MODE_SIZE (output_memory_reference_mode)); \
+ } \
+ else if (GET_CODE (X) == PRE_MODIFY) \
+ { \
+ asm_fprintf (STREAM, "[%r, ", REGNO (XEXP (X, 0))); \
+ if (GET_CODE (XEXP (XEXP (X, 1), 1)) == CONST_INT) \
+ asm_fprintf (STREAM, "#%wd]!", \
+ INTVAL (XEXP (XEXP (X, 1), 1))); \
+ else \
+ asm_fprintf (STREAM, "%r]!", \
+ REGNO (XEXP (XEXP (X, 1), 1))); \
+ } \
+ else if (GET_CODE (X) == POST_MODIFY) \
+ { \
+ asm_fprintf (STREAM, "[%r], ", REGNO (XEXP (X, 0))); \
+ if (GET_CODE (XEXP (XEXP (X, 1), 1)) == CONST_INT) \
+ asm_fprintf (STREAM, "#%wd", \
+ INTVAL (XEXP (XEXP (X, 1), 1))); \
+ else \
+ asm_fprintf (STREAM, "%r", \
+ REGNO (XEXP (XEXP (X, 1), 1))); \
+ } \
+ else output_addr_const (STREAM, X); \
}
#define THUMB_PRINT_OPERAND_ADDRESS(STREAM, X) \
@@ -2692,10 +2646,12 @@ extern int making_const_table;
asm_fprintf (STREAM, "%r!", REGNO (XEXP (X, 0))); \
else if (GET_CODE (X) == PLUS) \
{ \
+ if (GET_CODE (XEXP (X, 0)) != REG) \
+ abort (); \
if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
- asm_fprintf (STREAM, "[%r, #%d]", \
+ asm_fprintf (STREAM, "[%r, #%wd]", \
REGNO (XEXP (X, 0)), \
- (int) INTVAL (XEXP (X, 1))); \
+ INTVAL (XEXP (X, 1))); \
else \
asm_fprintf (STREAM, "[%r, %r]", \
REGNO (XEXP (X, 0)), \
@@ -2710,7 +2666,12 @@ extern int making_const_table;
ARM_PRINT_OPERAND_ADDRESS (STREAM, X) \
else \
THUMB_PRINT_OPERAND_ADDRESS (STREAM, X)
-
+
+#define OUTPUT_ADDR_CONST_EXTRA(FILE, X, FAIL) \
+ if (GET_CODE (X) != CONST_VECTOR \
+ || ! arm_emit_vector_const (FILE, X)) \
+ goto FAIL;
+
/* A C expression whose value is RTL representing the value of the return
address for the frame COUNT steps up from the current frame. */
@@ -2746,13 +2707,16 @@ extern int making_const_table;
{"arm_hard_register_operand", {REG}}, \
{"f_register_operand", {SUBREG, REG}}, \
{"arm_add_operand", {SUBREG, REG, CONST_INT}}, \
- {"fpu_add_operand", {SUBREG, REG, CONST_DOUBLE}}, \
- {"fpu_rhs_operand", {SUBREG, REG, CONST_DOUBLE}}, \
+ {"arm_addimm_operand", {CONST_INT}}, \
+ {"fpa_add_operand", {SUBREG, REG, CONST_DOUBLE}}, \
+ {"fpa_rhs_operand", {SUBREG, REG, CONST_DOUBLE}}, \
{"arm_rhs_operand", {SUBREG, REG, CONST_INT}}, \
{"arm_not_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_int_operand", {SUBREG, REG, CONST_INT}}, \
{"index_operand", {SUBREG, REG, CONST_INT}}, \
{"thumb_cmp_operand", {SUBREG, REG, CONST_INT}}, \
+ {"thumb_cmpneg_operand", {CONST_INT}}, \
+ {"thumb_cbrch_target_operand", {SUBREG, REG, MEM}}, \
{"offsettable_memory_operand", {MEM}}, \
{"bad_signed_byte_operand", {MEM}}, \
{"alignable_memory_operand", {MEM}}, \
@@ -2774,18 +2738,180 @@ extern int making_const_table;
{"multi_register_push", {PARALLEL}}, \
{"cc_register", {REG}}, \
{"logical_binary_operator", {AND, IOR, XOR}}, \
+ {"cirrus_register_operand", {REG}}, \
+ {"cirrus_fp_register", {REG}}, \
+ {"cirrus_shift_const", {CONST_INT}}, \
{"dominant_cc_register", {REG}},
/* Define this if you have special predicates that know special things
about modes. Genrecog will warn about certain forms of
match_operand without a mode; if the operand predicate is listed in
- SPECIAL_MODE_PREDICATES, the warning will be suppressed. */
+ SPECIAL_MODE_PREDICATES, the warning will be suppressed. */
#define SPECIAL_MODE_PREDICATES \
"cc_register", "dominant_cc_register",
enum arm_builtins
{
- ARM_BUILTIN_CLZ,
+ ARM_BUILTIN_GETWCX,
+ ARM_BUILTIN_SETWCX,
+
+ ARM_BUILTIN_WZERO,
+
+ ARM_BUILTIN_WAVG2BR,
+ ARM_BUILTIN_WAVG2HR,
+ ARM_BUILTIN_WAVG2B,
+ ARM_BUILTIN_WAVG2H,
+
+ ARM_BUILTIN_WACCB,
+ ARM_BUILTIN_WACCH,
+ ARM_BUILTIN_WACCW,
+
+ ARM_BUILTIN_WMACS,
+ ARM_BUILTIN_WMACSZ,
+ ARM_BUILTIN_WMACU,
+ ARM_BUILTIN_WMACUZ,
+
+ ARM_BUILTIN_WSADB,
+ ARM_BUILTIN_WSADBZ,
+ ARM_BUILTIN_WSADH,
+ ARM_BUILTIN_WSADHZ,
+
+ ARM_BUILTIN_WALIGN,
+
+ ARM_BUILTIN_TMIA,
+ ARM_BUILTIN_TMIAPH,
+ ARM_BUILTIN_TMIABB,
+ ARM_BUILTIN_TMIABT,
+ ARM_BUILTIN_TMIATB,
+ ARM_BUILTIN_TMIATT,
+
+ ARM_BUILTIN_TMOVMSKB,
+ ARM_BUILTIN_TMOVMSKH,
+ ARM_BUILTIN_TMOVMSKW,
+
+ ARM_BUILTIN_TBCSTB,
+ ARM_BUILTIN_TBCSTH,
+ ARM_BUILTIN_TBCSTW,
+
+ ARM_BUILTIN_WMADDS,
+ ARM_BUILTIN_WMADDU,
+
+ ARM_BUILTIN_WPACKHSS,
+ ARM_BUILTIN_WPACKWSS,
+ ARM_BUILTIN_WPACKDSS,
+ ARM_BUILTIN_WPACKHUS,
+ ARM_BUILTIN_WPACKWUS,
+ ARM_BUILTIN_WPACKDUS,
+
+ ARM_BUILTIN_WADDB,
+ ARM_BUILTIN_WADDH,
+ ARM_BUILTIN_WADDW,
+ ARM_BUILTIN_WADDSSB,
+ ARM_BUILTIN_WADDSSH,
+ ARM_BUILTIN_WADDSSW,
+ ARM_BUILTIN_WADDUSB,
+ ARM_BUILTIN_WADDUSH,
+ ARM_BUILTIN_WADDUSW,
+ ARM_BUILTIN_WSUBB,
+ ARM_BUILTIN_WSUBH,
+ ARM_BUILTIN_WSUBW,
+ ARM_BUILTIN_WSUBSSB,
+ ARM_BUILTIN_WSUBSSH,
+ ARM_BUILTIN_WSUBSSW,
+ ARM_BUILTIN_WSUBUSB,
+ ARM_BUILTIN_WSUBUSH,
+ ARM_BUILTIN_WSUBUSW,
+
+ ARM_BUILTIN_WAND,
+ ARM_BUILTIN_WANDN,
+ ARM_BUILTIN_WOR,
+ ARM_BUILTIN_WXOR,
+
+ ARM_BUILTIN_WCMPEQB,
+ ARM_BUILTIN_WCMPEQH,
+ ARM_BUILTIN_WCMPEQW,
+ ARM_BUILTIN_WCMPGTUB,
+ ARM_BUILTIN_WCMPGTUH,
+ ARM_BUILTIN_WCMPGTUW,
+ ARM_BUILTIN_WCMPGTSB,
+ ARM_BUILTIN_WCMPGTSH,
+ ARM_BUILTIN_WCMPGTSW,
+
+ ARM_BUILTIN_TEXTRMSB,
+ ARM_BUILTIN_TEXTRMSH,
+ ARM_BUILTIN_TEXTRMSW,
+ ARM_BUILTIN_TEXTRMUB,
+ ARM_BUILTIN_TEXTRMUH,
+ ARM_BUILTIN_TEXTRMUW,
+ ARM_BUILTIN_TINSRB,
+ ARM_BUILTIN_TINSRH,
+ ARM_BUILTIN_TINSRW,
+
+ ARM_BUILTIN_WMAXSW,
+ ARM_BUILTIN_WMAXSH,
+ ARM_BUILTIN_WMAXSB,
+ ARM_BUILTIN_WMAXUW,
+ ARM_BUILTIN_WMAXUH,
+ ARM_BUILTIN_WMAXUB,
+ ARM_BUILTIN_WMINSW,
+ ARM_BUILTIN_WMINSH,
+ ARM_BUILTIN_WMINSB,
+ ARM_BUILTIN_WMINUW,
+ ARM_BUILTIN_WMINUH,
+ ARM_BUILTIN_WMINUB,
+
+ ARM_BUILTIN_WMULUH,
+ ARM_BUILTIN_WMULSH,
+ ARM_BUILTIN_WMULUL,
+
+ ARM_BUILTIN_PSADBH,
+ ARM_BUILTIN_WSHUFH,
+
+ ARM_BUILTIN_WSLLH,
+ ARM_BUILTIN_WSLLW,
+ ARM_BUILTIN_WSLLD,
+ ARM_BUILTIN_WSRAH,
+ ARM_BUILTIN_WSRAW,
+ ARM_BUILTIN_WSRAD,
+ ARM_BUILTIN_WSRLH,
+ ARM_BUILTIN_WSRLW,
+ ARM_BUILTIN_WSRLD,
+ ARM_BUILTIN_WRORH,
+ ARM_BUILTIN_WRORW,
+ ARM_BUILTIN_WRORD,
+ ARM_BUILTIN_WSLLHI,
+ ARM_BUILTIN_WSLLWI,
+ ARM_BUILTIN_WSLLDI,
+ ARM_BUILTIN_WSRAHI,
+ ARM_BUILTIN_WSRAWI,
+ ARM_BUILTIN_WSRADI,
+ ARM_BUILTIN_WSRLHI,
+ ARM_BUILTIN_WSRLWI,
+ ARM_BUILTIN_WSRLDI,
+ ARM_BUILTIN_WRORHI,
+ ARM_BUILTIN_WRORWI,
+ ARM_BUILTIN_WRORDI,
+
+ ARM_BUILTIN_WUNPCKIHB,
+ ARM_BUILTIN_WUNPCKIHH,
+ ARM_BUILTIN_WUNPCKIHW,
+ ARM_BUILTIN_WUNPCKILB,
+ ARM_BUILTIN_WUNPCKILH,
+ ARM_BUILTIN_WUNPCKILW,
+
+ ARM_BUILTIN_WUNPCKEHSB,
+ ARM_BUILTIN_WUNPCKEHSH,
+ ARM_BUILTIN_WUNPCKEHSW,
+ ARM_BUILTIN_WUNPCKEHUB,
+ ARM_BUILTIN_WUNPCKEHUH,
+ ARM_BUILTIN_WUNPCKEHUW,
+ ARM_BUILTIN_WUNPCKELSB,
+ ARM_BUILTIN_WUNPCKELSH,
+ ARM_BUILTIN_WUNPCKELSW,
+ ARM_BUILTIN_WUNPCKELUB,
+ ARM_BUILTIN_WUNPCKELUH,
+ ARM_BUILTIN_WUNPCKELUW,
+
ARM_BUILTIN_MAX
};
#endif /* ! GCC_ARM_H */
diff --git a/contrib/gcc/config/arm/arm.md b/contrib/gcc/config/arm/arm.md
index 0e6071295b90..9f10d1063dfa 100644
--- a/contrib/gcc/config/arm/arm.md
+++ b/contrib/gcc/config/arm/arm.md
@@ -1,32 +1,29 @@
;;- Machine description for ARM for GNU compiler
;; Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
-;; 2001, 2002 Free Software Foundation, Inc.
+;; 2001, 2002, 2003 2004 Free Software Foundation, Inc.
;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
;; and Martin Simmons (@harleqn.co.uk).
;; More major hacks by Richard Earnshaw (rearnsha@arm.com).
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC 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.
+;; 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 2, or (at your
+;; option) any later version.
-;; GNU CC 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.
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
-;; There are patterns in this file to support XFmode arithmetic.
-;; Unfortunately RISC iX doesn't work well with these so they are disabled.
-;; (See arm.h)
;;---------------------------------------------------------------------------
;; Constants
@@ -41,6 +38,13 @@
(LAST_ARM_REGNUM 15)
]
)
+;; 3rd operand to select_dominance_cc_mode
+(define_constants
+ [(DOM_CC_X_AND_Y 0)
+ (DOM_CC_NX_OR_Y 1)
+ (DOM_CC_X_OR_Y 2)
+ ]
+)
;; UNSPEC Usage:
;; Note: sin and cos are no-longer used.
@@ -65,15 +69,24 @@
; prevent combine from trying to rip it apart.
(UNSPEC_PRLG_STK 5) ; A special barrier that prevents frame accesses
; being scheduled before the stack adjustment insn.
- (UNSPEC_CLZ 5) ; `clz' instruction, count leading zeros (SImode):
- ; operand 0 is the result,
- ; operand 1 is the parameter.
(UNSPEC_PROLOGUE_USE 6) ; As USE insns are not meaningful after reload,
; this unspec is used to prevent the deletion of
; instructions setting registers for EH handling
; and stack frame generation. Operand 0 is the
; register to "use".
(UNSPEC_CHECK_ARCH 7); Set CCs to indicate 26-bit or 32-bit mode.
+ (UNSPEC_WSHUFH 8) ; Used by the intrinsic form of the iWMMXt WSHUFH instruction.
+ (UNSPEC_WACC 9) ; Used by the intrinsic form of the iWMMXt WACC instruction.
+ (UNSPEC_TMOVMSK 10) ; Used by the intrinsic form of the iWMMXt TMOVMSK instruction.
+ (UNSPEC_WSAD 11) ; Used by the intrinsic form of the iWMMXt WSAD instruction.
+ (UNSPEC_WSADZ 12) ; Used by the intrinsic form of the iWMMXt WSADZ instruction.
+ (UNSPEC_WMACS 13) ; Used by the intrinsic form of the iWMMXt WMACS instruction.
+ (UNSPEC_WMACU 14) ; Used by the intrinsic form of the iWMMXt WMACU instruction.
+ (UNSPEC_WMACSZ 15) ; Used by the intrinsic form of the iWMMXt WMACSZ instruction.
+ (UNSPEC_WMACUZ 16) ; Used by the intrinsic form of the iWMMXt WMACUZ instruction.
+ (UNSPEC_CLRDI 17) ; Used by the intrinsic form of the iWMMXt CLRDI instruction.
+ (UNSPEC_WMADDS 18) ; Used by the intrinsic form of the iWMMXt WMADDS instruction.
+ (UNSPEC_WMADDU 19) ; Used by the intrinsic form of the iWMMXt WMADDU instruction.
]
)
@@ -98,6 +111,12 @@
; a 32-bit object.
(VUNSPEC_POOL_8 7) ; `pool-entry(8)'. An entry in the constant pool for
; a 64-bit object.
+ (VUNSPEC_TMRC 8) ; Used by the iWMMXt TMRC instruction.
+ (VUNSPEC_TMCR 9) ; Used by the iWMMXt TMCR instruction.
+ (VUNSPEC_ALIGN8 10) ; 8-byte alignment version of VUNSPEC_ALIGN
+ (VUNSPEC_WCMP_EQ 11) ; Used by the iWMMXt WCMPEQ instructions
+ (VUNSPEC_WCMP_GTU 12) ; Used by the iWMMXt WCMPGTU instructions
+ (VUNSPEC_WCMP_GT 13) ; Used by the iwMMXT WCMPGT instructions
]
)
@@ -120,13 +139,14 @@
;; Operand number of an input operand that is shifted. Zero if the
;; given instruction does not shift one of its input operands.
-(define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_is_xscale")))
+(define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_tune_xscale")))
(define_attr "shift" "" (const_int 0))
; Floating Point Unit. If we only have floating point emulation, then there
; is no point in scheduling the floating point insns. (Well, for best
; performance we should try and group them together).
-(define_attr "fpu" "fpa,fpe2,fpe3" (const (symbol_ref "arm_fpu_attr")))
+(define_attr "fpu" "softfpa,fpa,fpe2,fpe3,maverick"
+ (const (symbol_ref "arm_fpu_attr")))
; LENGTH of an instruction (in bytes)
(define_attr "length" "" (const_int 4))
@@ -157,7 +177,6 @@
; mult a multiply instruction
; block blockage insn, this blocks all functional units
; float a floating point arithmetic operation (subject to expansion)
-; fdivx XFmode floating point division
; fdivd DFmode floating point division
; fdivs SFmode floating point division
; fmul Floating point multiply
@@ -178,9 +197,12 @@
; store2 store 2 words
; store3 store 3 words
; store4 store 4 words
+; Additions for Cirrus Maverick co-processor:
+; mav_farith Floating point arithmetic (4 cycle)
+; mav_dmult Double multiplies (7 cycle)
;
(define_attr "type"
- "normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4"
+ "normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4,mav_farith,mav_dmult"
(const_string "normal"))
; Load scheduling, set from the arm_ld_sched variable
@@ -221,7 +243,7 @@
; Only model the write buffer for ARM6 and ARM7. Earlier processors don't
; have one. Later ones, such as StrongARM, have write-back caches, so don't
-; suffer blockages enough to warrent modelling this (and it can adversely
+; suffer blockages enough to warrant modelling this (and it can adversely
; affect the schedule).
(define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7")))
@@ -245,50 +267,10 @@
;; distant label. Only applicable to Thumb code.
(define_attr "far_jump" "yes,no" (const_string "no"))
-;; (define_function_unit {name} {num-units} {n-users} {test}
-;; {ready-delay} {issue-delay} [{conflict-list}])
-
-;;--------------------------------------------------------------------
-;; Floating point unit (FPA)
-;;--------------------------------------------------------------------
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "fdivx")) 71 69)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "fdivd")) 59 57)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "fdivs")) 31 29)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "fmul")) 9 7)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "ffmul")) 6 4)
+(define_automaton "arm")
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "farith")) 4 2)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "ffarith")) 2 2)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "r_2_f")) 5 3)
-
-(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "f_2_r")) 1 2)
-
-; The fpa10 doesn't really have a memory read unit, but it can start to
-; speculatively execute the instruction in the pipeline, provided the data
-; is already loaded, so pretend reads have a delay of 2 (and that the
-; pipeline is infinite).
-
-(define_function_unit "fpa_mem" 1 0 (and (eq_attr "fpu" "fpa")
- (eq_attr "type" "f_load")) 3 1)
-
-;;--------------------------------------------------------------------
;; Write buffer
-;;--------------------------------------------------------------------
+;
; Strictly, we should model a 4-deep write buffer for ARM7xx based chips
;
; The write buffer on some of the arm6 processors is hard to model exactly.
@@ -300,102 +282,101 @@
; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous
; (they aren't allowed to be at present) then there is a startup cost of 1MCLK
; cycle to add as well.
+(define_cpu_unit "write_buf" "arm")
-(define_function_unit "write_buf" 1 2
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store1,r_mem_f")) 5 3)
-(define_function_unit "write_buf" 1 2
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store2")) 7 4)
-(define_function_unit "write_buf" 1 2
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store3")) 9 5)
-(define_function_unit "write_buf" 1 2
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store4")) 11 6)
-
-;;--------------------------------------------------------------------
;; Write blockage unit
-;;--------------------------------------------------------------------
+;
; The write_blockage unit models (partially), the fact that reads will stall
; until the write buffer empties.
; The f_mem_r and r_mem_f could also block, but they are to the stack,
; so we don't model them here
-(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store1")) 5 5
- [(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store2")) 7 7
- [(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes")
- (eq_attr "type" "store3")) 9 9
- [(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0
- (and (eq_attr "model_wbuf" "yes") (eq_attr "type" "store4")) 11 11
- [(eq_attr "write_conflict" "yes")])
-(define_function_unit "write_blockage" 1 0
- (and (eq_attr "model_wbuf" "yes")
- (eq_attr "write_conflict" "yes")) 1 1)
-
-;;--------------------------------------------------------------------
-;; Core unit
-;;--------------------------------------------------------------------
-; Everything must spend at least one cycle in the core unit
-(define_function_unit "core" 1 0 (eq_attr "core_cycles" "single") 1 1)
-
-(define_function_unit "core" 1 0
- (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1")) 1 1)
-
-(define_function_unit "core" 1 0
- (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 2 1)
-
-;; We do not need to conditionalize the define_function_unit immediately
-;; above. This one will be ignored for anything other than xscale
-;; compiles and for xscale compiles it provides a larger delay
-;; and the scheduler will DTRT.
-;; FIXME: this test needs to be revamped to not depend on this feature
-;; of the scheduler.
-
-(define_function_unit "core" 1 0
- (and (and (eq_attr "ldsched" "yes") (eq_attr "type" "load"))
- (eq_attr "is_xscale" "yes"))
- 3 1)
+(define_cpu_unit "write_blockage" "arm")
-(define_function_unit "core" 1 0
- (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load,store1")) 2 2)
+;; Core
+;
+(define_cpu_unit "core" "arm")
-(define_function_unit "core" 1 0
- (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_load")) 3 3)
+(define_insn_reservation "r_mem_f_wbuf" 5
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "r_mem_f"))
+ "core+write_buf*3")
-(define_function_unit "core" 1 0
- (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_store")) 4 4)
+(define_insn_reservation "store1_wbuf" 5
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store1"))
+ "core+write_buf*3+write_blockage*5")
-(define_function_unit "core" 1 0
- (and (eq_attr "fpu" "fpa") (eq_attr "type" "r_mem_f")) 6 6)
+(define_insn_reservation "store2_wbuf" 7
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store2"))
+ "core+write_buf*4+write_blockage*7")
-(define_function_unit "core" 1 0
- (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r")) 7 7)
+(define_insn_reservation "store3_wbuf" 9
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store3"))
+ "core+write_buf*5+write_blockage*9")
-(define_function_unit "core" 1 0
- (and (eq_attr "ldsched" "no") (eq_attr "type" "mult")) 16 16)
+(define_insn_reservation "store4_wbuf" 11
+ (and (eq_attr "model_wbuf" "yes")
+ (eq_attr "type" "store4"))
+ "core+write_buf*6+write_blockage*11")
-(define_function_unit "core" 1 0
- (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "no"))
- (eq_attr "type" "mult")) 4 4)
+(define_insn_reservation "store2" 3
+ (and (eq_attr "model_wbuf" "no")
+ (eq_attr "type" "store2"))
+ "core*3")
-(define_function_unit "core" 1 0
- (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "yes"))
- (eq_attr "type" "mult")) 3 2)
+(define_insn_reservation "store3" 4
+ (and (eq_attr "model_wbuf" "no")
+ (eq_attr "type" "store3"))
+ "core*4")
-(define_function_unit "core" 1 0 (eq_attr "type" "store2") 3 3)
+(define_insn_reservation "store4" 5
+ (and (eq_attr "model_wbuf" "no")
+ (eq_attr "type" "store4"))
+ "core*5")
-(define_function_unit "core" 1 0 (eq_attr "type" "store3") 4 4)
+(define_insn_reservation "store1_ldsched" 1
+ (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1"))
+ "core")
-(define_function_unit "core" 1 0 (eq_attr "type" "store4") 5 5)
+(define_insn_reservation "load_ldsched_xscale" 3
+ (and (and (eq_attr "ldsched" "yes") (eq_attr "type" "load"))
+ (eq_attr "is_xscale" "yes"))
+ "core")
+
+(define_insn_reservation "load_ldsched" 2
+ (and (and (eq_attr "ldsched" "yes") (eq_attr "type" "load"))
+ (eq_attr "is_xscale" "no"))
+ "core")
+
+(define_insn_reservation "load_or_store" 2
+ (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load,store1"))
+ "core*2")
+
+(define_insn_reservation "mult" 16
+ (and (eq_attr "ldsched" "no") (eq_attr "type" "mult"))
+ "core*16")
+
+(define_insn_reservation "mult_ldsched_strongarm" 3
+ (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "yes"))
+ (eq_attr "type" "mult"))
+ "core*2")
+
+(define_insn_reservation "mult_ldsched" 4
+ (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "no"))
+ (eq_attr "type" "mult"))
+ "core*4")
-(define_function_unit "core" 1 0
+(define_insn_reservation "multi_cycle" 32
(and (eq_attr "core_cycles" "multi")
- (eq_attr "type" "!mult,load,store1,store2,store3,store4")) 32 32)
+ (eq_attr "type" "!mult,load,store1,store2,store3,store4"))
+ "core*32")
+
+(define_insn_reservation "single_cycle" 1
+ (eq_attr "core_cycles" "single")
+ "core")
+
;;---------------------------------------------------------------------------
;; Insn patterns
@@ -405,6 +386,8 @@
;; Note: For DImode insns, there is normally no reason why operands should
;; not be in the same register, what we don't want is for something being
;; written to partially overlap something that is an input.
+;; Cirrus 64bit additions should not be split because we have a native
+;; 64bit addition instructions.
(define_expand "adddi3"
[(parallel
@@ -414,6 +397,16 @@
(clobber (reg:CC CC_REGNUM))])]
"TARGET_EITHER"
"
+ if (TARGET_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[0], DImode))
+ operands[0] = force_reg (DImode, operands[0]);
+ if (!cirrus_fp_register (operands[1], DImode))
+ operands[1] = force_reg (DImode, operands[1]);
+ emit_insn (gen_cirrus_adddi3 (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+
if (TARGET_THUMB)
{
if (GET_CODE (operands[1]) != REG)
@@ -440,7 +433,7 @@
(plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0")
(match_operand:DI 2 "s_register_operand" "r, 0")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM"
+ "TARGET_ARM && !TARGET_CIRRUS"
"#"
"TARGET_ARM && reload_completed"
[(parallel [(set (reg:CC_C CC_REGNUM)
@@ -468,7 +461,7 @@
(match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:DI 1 "s_register_operand" "r,0")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM"
+ "TARGET_ARM && !TARGET_CIRRUS"
"#"
"TARGET_ARM && reload_completed"
[(parallel [(set (reg:CC_C CC_REGNUM)
@@ -497,7 +490,7 @@
(match_operand:SI 2 "s_register_operand" "r,r"))
(match_operand:DI 1 "s_register_operand" "r,0")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_ARM"
+ "TARGET_ARM && !TARGET_CIRRUS"
"#"
"TARGET_ARM && reload_completed"
[(parallel [(set (reg:CC_C CC_REGNUM)
@@ -534,7 +527,7 @@
"
)
-; If there is a scratch available, this will be faster than synthesising the
+; If there is a scratch available, this will be faster than synthesizing the
; addition.
(define_peephole2
[(match_scratch:SI 3 "r")
@@ -674,6 +667,60 @@
[(set_attr "conds" "set")]
)
+;; This is the canonicalization of addsi3_compare0_for_combiner when the
+;; addend is a constant.
+(define_insn "*cmpsi2_addneg"
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC
+ (match_operand:SI 1 "s_register_operand" "r,r")
+ (match_operand:SI 2 "arm_addimm_operand" "I,L")))
+ (set (match_operand:SI 0 "s_register_operand" "=r,r")
+ (plus:SI (match_dup 1)
+ (match_operand:SI 3 "arm_addimm_operand" "L,I")))]
+ "TARGET_ARM && INTVAL (operands[2]) == -INTVAL (operands[3])"
+ "@
+ sub%?s\\t%0, %1, %2
+ add%?s\\t%0, %1, #%n2"
+ [(set_attr "conds" "set")]
+)
+
+;; Convert the sequence
+;; sub rd, rn, #1
+;; cmn rd, #1 (equivalent to cmp rd, #-1)
+;; bne dest
+;; into
+;; subs rd, rn, #1
+;; bcs dest ((unsigned)rn >= 1)
+;; similarly for the beq variant using bcc.
+;; This is a common looping idiom (while (n--))
+(define_peephole2
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (plus:SI (match_operand:SI 1 "s_register_operand" "")
+ (const_int -1)))
+ (set (match_operand 2 "cc_register" "")
+ (compare (match_dup 0) (const_int -1)))
+ (set (pc)
+ (if_then_else (match_operator 3 "equality_operator"
+ [(match_dup 2) (const_int 0)])
+ (match_operand 4 "" "")
+ (match_operand 5 "" "")))]
+ "TARGET_ARM && peep2_reg_dead_p (3, operands[2])"
+ [(parallel[
+ (set (match_dup 2)
+ (compare:CC
+ (match_dup 1) (const_int 1)))
+ (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))])
+ (set (pc)
+ (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)])
+ (match_dup 4)
+ (match_dup 5)))]
+ "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM);
+ operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
+ ? GEU : LTU),
+ VOIDmode,
+ operands[2], const0_rtx);"
+)
+
;; The next four insns work because they compare the result with one of
;; the operands, and we know that the use of the condition code is
;; either GEU or LTU, so we can use the carry flag from the addition
@@ -745,13 +792,13 @@
)
(define_insn "*addsi3_carryin_shift"
- [(set (match_operand:SI 0 "s_register_operand" "")
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
(plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))
(plus:SI
(match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "")
- (match_operand:SI 4 "reg_or_int_operand" "")])
- (match_operand:SI 1 "s_register_operand" ""))))]
+ [(match_operand:SI 3 "s_register_operand" "r")
+ (match_operand:SI 4 "reg_or_int_operand" "rM")])
+ (match_operand:SI 1 "s_register_operand" "r"))))]
"TARGET_ARM"
"adc%?\\t%0, %1, %3%S2"
[(set_attr "conds" "use")]
@@ -800,77 +847,41 @@
(set_attr "length" "4,8")]
)
-(define_insn "addsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f,f")
- (plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
- (match_operand:SF 2 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- adf%?s\\t%0, %1, %2
- suf%?s\\t%0, %1, #%N2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "adddf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
- (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- adf%?d\\t%0, %1, %2
- suf%?d\\t%0, %1, #%N2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*adddf_esfdf_df"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (plus:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f,f"))
- (match_operand:DF 2 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- adf%?d\\t%0, %1, %2
- suf%?d\\t%0, %1, #%N2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*adddf_df_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (plus:DF (match_operand:DF 1 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "adf%?d\\t%0, %1, %2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
+; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
+ (match_operand:SI 2 "s_register_operand" ""))
+ (const_int -1)))
+ (clobber (match_operand:SI 3 "s_register_operand" ""))]
+ "TARGET_ARM"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))]
+ "
+ operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1));
+")
-(define_insn "*adddf_esfdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (plus:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "adf%?d\\t%0, %1, %2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
+(define_expand "addsf3"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (plus:SF (match_operand:SF 1 "s_register_operand" "")
+ (match_operand:SF 2 "fpa_add_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS
+ && !cirrus_fp_register (operands[2], SFmode))
+ operands[2] = force_reg (SFmode, operands[2]);
+")
-(define_insn "addxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f,f")
- (plus:XF (match_operand:XF 1 "s_register_operand" "f,f")
- (match_operand:XF 2 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "@
- adf%?e\\t%0, %1, %2
- suf%?e\\t%0, %1, #%N2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
+(define_expand "adddf3"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (plus:DF (match_operand:DF 1 "s_register_operand" "")
+ (match_operand:DF 2 "fpa_add_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS
+ && !cirrus_fp_register (operands[2], DFmode))
+ operands[2] = force_reg (DFmode, operands[2]);
+")
(define_expand "subdi3"
[(parallel
@@ -880,6 +891,15 @@
(clobber (reg:CC CC_REGNUM))])]
"TARGET_EITHER"
"
+ if (TARGET_CIRRUS
+ && TARGET_ARM
+ && cirrus_fp_register (operands[0], DImode)
+ && cirrus_fp_register (operands[1], DImode))
+ {
+ emit_insn (gen_cirrus_subdi3 (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+
if (TARGET_THUMB)
{
if (GET_CODE (operands[1]) != REG)
@@ -1065,76 +1085,36 @@
(set_attr "length" "*,8")]
)
-(define_insn "subsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f,f")
- (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
- (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- suf%?s\\t%0, %1, %2
- rsf%?s\\t%0, %2, %1"
- [(set_attr "type" "farith")]
-)
-
-(define_insn "subdf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
- (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- suf%?d\\t%0, %1, %2
- rsf%?d\\t%0, %2, %1"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*subdf_esfdf_df"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (minus:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "suf%?d\\t%0, %1, %2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*subdf_df_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f,f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- suf%?d\\t%0, %1, %2
- rsf%?d\\t%0, %2, %1"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
+(define_expand "subsf3"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (minus:SF (match_operand:SF 1 "fpa_rhs_operand" "")
+ (match_operand:SF 2 "fpa_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[1], SFmode))
+ operands[1] = force_reg (SFmode, operands[1]);
+ if (!cirrus_fp_register (operands[2], SFmode))
+ operands[2] = force_reg (SFmode, operands[2]);
+ }
+")
-(define_insn "*subdf_esfdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (minus:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "suf%?d\\t%0, %1, %2"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
+(define_expand "subdf3"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (minus:DF (match_operand:DF 1 "fpa_rhs_operand" "")
+ (match_operand:DF 2 "fpa_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[1], DFmode))
+ operands[1] = force_reg (DFmode, operands[1]);
+ if (!cirrus_fp_register (operands[2], DFmode))
+ operands[2] = force_reg (DFmode, operands[2]);
+ }
+")
-(define_insn "subxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f,f")
- (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
- (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "@
- suf%?e\\t%0, %1, %2
- rsf%?e\\t%0, %2, %1"
- [(set_attr "type" "farith")
- (set_attr "predicable" "yes")]
-)
;; Multiplication insns
@@ -1185,7 +1165,7 @@
(const_int 0)))
(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
(mult:SI (match_dup 2) (match_dup 1)))]
- "TARGET_ARM && !arm_is_xscale"
+ "TARGET_ARM && !arm_arch_xscale"
"mul%?s\\t%0, %2, %1"
[(set_attr "conds" "set")
(set_attr "type" "mult")]
@@ -1198,7 +1178,7 @@
(match_operand:SI 1 "s_register_operand" "%?r,0"))
(const_int 0)))
(clobber (match_scratch:SI 0 "=&r,&r"))]
- "TARGET_ARM && !arm_is_xscale"
+ "TARGET_ARM && !arm_arch_xscale"
"mul%?s\\t%0, %2, %1"
[(set_attr "conds" "set")
(set_attr "type" "mult")]
@@ -1229,7 +1209,7 @@
(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r")
(plus:SI (mult:SI (match_dup 2) (match_dup 1))
(match_dup 3)))]
- "TARGET_ARM && !arm_is_xscale"
+ "TARGET_ARM && !arm_arch_xscale"
"mla%?s\\t%0, %2, %1, %3"
[(set_attr "conds" "set")
(set_attr "type" "mult")]
@@ -1244,13 +1224,13 @@
(match_operand:SI 3 "s_register_operand" "?r,r,0,0"))
(const_int 0)))
(clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))]
- "TARGET_ARM && !arm_is_xscale"
+ "TARGET_ARM && !arm_arch_xscale"
"mla%?s\\t%0, %2, %1, %3"
[(set_attr "conds" "set")
(set_attr "type" "mult")]
)
-;; Unnamed template to match long long multiply-accumlate (smlal)
+;; Unnamed template to match long long multiply-accumulate (smlal)
(define_insn "*mulsidi3adddi"
[(set (match_operand:DI 0 "s_register_operand" "=&r")
@@ -1287,7 +1267,7 @@
(set_attr "predicable" "yes")]
)
-;; Unnamed template to match long long unsigned multiply-accumlate (umlal)
+;; Unnamed template to match long long unsigned multiply-accumulate (umlal)
(define_insn "*umulsidi3adddi"
[(set (match_operand:DI 0 "s_register_operand" "=&r")
@@ -1338,9 +1318,50 @@
(match_operand:HI 1 "s_register_operand" "%r"))
(sign_extend:SI
(match_operand:HI 2 "s_register_operand" "r"))))]
- "TARGET_ARM && arm_is_xscale"
+ "TARGET_ARM && arm_arch5e"
"smulbb%?\\t%0, %1, %2"
- [(set_attr "type" "mult")]
+ [(set_attr "type" "mult")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*mulhisi3tb"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (mult:SI (ashiftrt:SI
+ (match_operand:SI 1 "s_register_operand" "r")
+ (const_int 16))
+ (sign_extend:SI
+ (match_operand:HI 2 "s_register_operand" "r"))))]
+ "TARGET_ARM && arm_arch5e"
+ "smultb%?\\t%0, %1, %2"
+ [(set_attr "type" "mult")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*mulhisi3bt"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (mult:SI (sign_extend:SI
+ (match_operand:HI 1 "s_register_operand" "r"))
+ (ashiftrt:SI
+ (match_operand:SI 2 "s_register_operand" "r")
+ (const_int 16))))]
+ "TARGET_ARM && arm_arch5e"
+ "smulbt%?\\t%0, %1, %2"
+ [(set_attr "type" "mult")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*mulhisi3tt"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (mult:SI (ashiftrt:SI
+ (match_operand:SI 1 "s_register_operand" "r")
+ (const_int 16))
+ (ashiftrt:SI
+ (match_operand:SI 2 "s_register_operand" "r")
+ (const_int 16))))]
+ "TARGET_ARM && arm_arch5e"
+ "smultt%?\\t%0, %1, %2"
+ [(set_attr "type" "mult")
+ (set_attr "predicable" "yes")]
)
(define_insn "*mulhisi3addsi"
@@ -1350,9 +1371,10 @@
(match_operand:HI 2 "s_register_operand" "%r"))
(sign_extend:SI
(match_operand:HI 3 "s_register_operand" "r")))))]
- "TARGET_ARM && arm_is_xscale"
+ "TARGET_ARM && arm_arch5e"
"smlabb%?\\t%0, %2, %3, %1"
- [(set_attr "type" "mult")]
+ [(set_attr "type" "mult")
+ (set_attr "predicable" "yes")]
)
(define_insn "*mulhidi3adddi"
@@ -1363,210 +1385,64 @@
(match_operand:HI 2 "s_register_operand" "%r"))
(sign_extend:DI
(match_operand:HI 3 "s_register_operand" "r")))))]
- "TARGET_ARM && arm_is_xscale"
+ "TARGET_ARM && arm_arch5e"
"smlalbb%?\\t%Q0, %R0, %2, %3"
-[(set_attr "type" "mult")])
-
-(define_insn "mulsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (mult:SF (match_operand:SF 1 "s_register_operand" "f")
- (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "fml%?s\\t%0, %1, %2"
- [(set_attr "type" "ffmul")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "muldf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mult:DF (match_operand:DF 1 "s_register_operand" "f")
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "muf%?d\\t%0, %1, %2"
- [(set_attr "type" "fmul")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*muldf_esfdf_df"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mult:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "muf%?d\\t%0, %1, %2"
- [(set_attr "type" "fmul")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*muldf_df_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mult:DF (match_operand:DF 1 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "muf%?d\\t%0, %1, %2"
- [(set_attr "type" "fmul")
- (set_attr "predicable" "yes")]
-)
+ [(set_attr "type" "mult")
+ (set_attr "predicable" "yes")])
-(define_insn "*muldf_esfdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mult:DF
- (float_extend:DF (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF (match_operand:SF 2 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "muf%?d\\t%0, %1, %2"
- [(set_attr "type" "fmul")
- (set_attr "predicable" "yes")]
-)
+(define_expand "mulsf3"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (mult:SF (match_operand:SF 1 "s_register_operand" "")
+ (match_operand:SF 2 "fpa_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS
+ && !cirrus_fp_register (operands[2], SFmode))
+ operands[2] = force_reg (SFmode, operands[2]);
+")
-(define_insn "mulxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (mult:XF (match_operand:XF 1 "s_register_operand" "f")
- (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "muf%?e\\t%0, %1, %2"
- [(set_attr "type" "fmul")
- (set_attr "predicable" "yes")]
-)
+(define_expand "muldf3"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (mult:DF (match_operand:DF 1 "s_register_operand" "")
+ (match_operand:DF 2 "fpa_rhs_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS
+ && !cirrus_fp_register (operands[2], DFmode))
+ operands[2] = force_reg (DFmode, operands[2]);
+")
;; Division insns
-(define_insn "divsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f,f")
- (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
- (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- fdv%?s\\t%0, %1, %2
- frd%?s\\t%0, %2, %1"
- [(set_attr "type" "fdivs")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "divdf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f")
- (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
- (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- dvf%?d\\t%0, %1, %2
- rdf%?d\\t%0, %2, %1"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*divdf_esfdf_df"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (div:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "dvf%?d\\t%0, %1, %2"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*divdf_df_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
+(define_expand "divsf3"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (div:SF (match_operand:SF 1 "fpa_rhs_operand" "")
+ (match_operand:SF 2 "fpa_rhs_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
- "rdf%?d\\t%0, %2, %1"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
+ "")
-(define_insn "*divdf_esfdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (div:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
+(define_expand "divdf3"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (div:DF (match_operand:DF 1 "fpa_rhs_operand" "")
+ (match_operand:DF 2 "fpa_rhs_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
- "dvf%?d\\t%0, %1, %2"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "divxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f,f")
- (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G")
- (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "@
- dvf%?e\\t%0, %1, %2
- rdf%?e\\t%0, %2, %1"
- [(set_attr "type" "fdivx")
- (set_attr "predicable" "yes")]
-)
+ "")
;; Modulo insns
-(define_insn "modsf3"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (mod:SF (match_operand:SF 1 "s_register_operand" "f")
- (match_operand:SF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "rmf%?s\\t%0, %1, %2"
- [(set_attr "type" "fdivs")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "moddf3"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mod:DF (match_operand:DF 1 "s_register_operand" "f")
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "rmf%?d\\t%0, %1, %2"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*moddf_esfdf_df"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mod:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (match_operand:DF 2 "fpu_rhs_operand" "fG")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "rmf%?d\\t%0, %1, %2"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*moddf_df_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mod:DF (match_operand:DF 1 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
+(define_expand "modsf3"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (mod:SF (match_operand:SF 1 "s_register_operand" "")
+ (match_operand:SF 2 "fpa_rhs_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
- "rmf%?d\\t%0, %1, %2"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
+ "")
-(define_insn "*moddf_esfdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (mod:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))
- (float_extend:DF
- (match_operand:SF 2 "s_register_operand" "f"))))]
+(define_expand "moddf3"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (mod:DF (match_operand:DF 1 "s_register_operand" "")
+ (match_operand:DF 2 "fpa_rhs_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
- "rmf%?d\\t%0, %1, %2"
- [(set_attr "type" "fdivd")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "modxf3"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (mod:XF (match_operand:XF 1 "s_register_operand" "f")
- (match_operand:XF 2 "fpu_rhs_operand" "fG")))]
- "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "rmf%?e\\t%0, %1, %2"
- [(set_attr "type" "fdivx")
- (set_attr "predicable" "yes")]
-)
+ "")
;; Boolean and,ior,xor insns
@@ -1579,7 +1455,7 @@
(match_operator:DI 6 "logical_binary_operator"
[(match_operand:DI 1 "s_register_operand" "")
(match_operand:DI 2 "s_register_operand" "")]))]
- "TARGET_ARM && reload_completed"
+ "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
[(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
(set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
"
@@ -1656,7 +1532,7 @@
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(and:DI (match_operand:DI 1 "s_register_operand" "%0,r")
(match_operand:DI 2 "s_register_operand" "r,r")))]
- "TARGET_ARM"
+ "TARGET_ARM && ! TARGET_IWMMXT"
"#"
[(set_attr "length" "8")]
)
@@ -1859,6 +1735,83 @@
(set_attr "length" "8")]
)
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (zero_extract:SI (match_operand:SI 1 "s_register_operand" "")
+ (match_operand:SI 2 "const_int_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")))
+ (clobber (match_operand:SI 4 "s_register_operand" ""))]
+ "TARGET_THUMB"
+ [(set (match_dup 4) (ashift:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (lshiftrt:SI (match_dup 4) (match_dup 3)))]
+ "{
+ HOST_WIDE_INT temp = INTVAL (operands[2]);
+
+ operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
+ operands[3] = GEN_INT (32 - temp);
+ }"
+)
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "shiftable_operator"
+ [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")
+ (match_operand:SI 4 "const_int_operand" ""))
+ (match_operand:SI 5 "s_register_operand" "")]))
+ (clobber (match_operand:SI 6 "s_register_operand" ""))]
+ "TARGET_ARM"
+ [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
+ (set (match_dup 0)
+ (match_op_dup 1
+ [(lshiftrt:SI (match_dup 6) (match_dup 4))
+ (match_dup 5)]))]
+ "{
+ HOST_WIDE_INT temp = INTVAL (operands[3]);
+
+ operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
+ operands[4] = GEN_INT (32 - temp);
+ }"
+)
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (sign_extract:SI (match_operand:SI 1 "s_register_operand" "")
+ (match_operand:SI 2 "const_int_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")))]
+ "TARGET_THUMB"
+ [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 3)))]
+ "{
+ HOST_WIDE_INT temp = INTVAL (operands[2]);
+
+ operands[2] = GEN_INT (32 - temp - INTVAL (operands[3]));
+ operands[3] = GEN_INT (32 - temp);
+ }"
+)
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "shiftable_operator"
+ [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")
+ (match_operand:SI 4 "const_int_operand" ""))
+ (match_operand:SI 5 "s_register_operand" "")]))
+ (clobber (match_operand:SI 6 "s_register_operand" ""))]
+ "TARGET_ARM"
+ [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3)))
+ (set (match_dup 0)
+ (match_op_dup 1
+ [(ashiftrt:SI (match_dup 6) (match_dup 4))
+ (match_dup 5)]))]
+ "{
+ HOST_WIDE_INT temp = INTVAL (operands[3]);
+
+ operands[3] = GEN_INT (32 - temp - INTVAL (operands[4]));
+ operands[4] = GEN_INT (32 - temp);
+ }"
+)
+
;;; ??? This pattern is bogus. If operand3 has bits outside the range
;;; represented by the bitfield, then this will produce incorrect results.
;;; Somewhere, the value needs to be truncated. On targets like the m68k,
@@ -1918,7 +1871,7 @@
/* A Trick, since we are setting the bottom bits in the word,
we can shift operand[3] up, operand[0] down, OR them together
and rotate the result back again. This takes 3 insns, and
- the third might be mergable into another op. */
+ the third might be mergeable into another op. */
/* The shift up copes with the possibility that operand[3] is
wider than the bitfield. */
rtx op0 = gen_reg_rtx (SImode);
@@ -2010,7 +1963,7 @@
(match_operand:DI 2 "s_register_operand" "0,r")))]
"TARGET_ARM"
"#"
- "TARGET_ARM && reload_completed"
+ "TARGET_ARM && reload_completed && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))"
[(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2)))
(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))]
"
@@ -2136,7 +2089,7 @@
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(ior:DI (match_operand:DI 1 "s_register_operand" "%0,r")
(match_operand:DI 2 "s_register_operand" "r,r")))]
- "TARGET_ARM"
+ "TARGET_ARM && ! TARGET_IWMMXT"
"#"
[(set_attr "length" "8")
(set_attr "predicable" "yes")]
@@ -2258,7 +2211,7 @@
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
(xor:DI (match_operand:DI 1 "s_register_operand" "%0,r")
(match_operand:DI 2 "s_register_operand" "r,r")))]
- "TARGET_ARM"
+ "TARGET_ARM && !TARGET_IWMMXT"
"#"
[(set_attr "length" "8")
(set_attr "predicable" "yes")]
@@ -2367,6 +2320,109 @@
(set_attr "predicable" "yes")]
)
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "logical_binary_operator"
+ [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")
+ (match_operand:SI 4 "const_int_operand" ""))
+ (match_operator:SI 9 "logical_binary_operator"
+ [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
+ (match_operand:SI 6 "const_int_operand" ""))
+ (match_operand:SI 7 "s_register_operand" "")])]))
+ (clobber (match_operand:SI 8 "s_register_operand" ""))]
+ "TARGET_ARM
+ && GET_CODE (operands[1]) == GET_CODE (operands[9])
+ && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
+ [(set (match_dup 8)
+ (match_op_dup 1
+ [(ashift:SI (match_dup 2) (match_dup 4))
+ (match_dup 5)]))
+ (set (match_dup 0)
+ (match_op_dup 1
+ [(lshiftrt:SI (match_dup 8) (match_dup 6))
+ (match_dup 7)]))]
+ "
+ operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
+")
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "logical_binary_operator"
+ [(match_operator:SI 9 "logical_binary_operator"
+ [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "")
+ (match_operand:SI 6 "const_int_operand" ""))
+ (match_operand:SI 7 "s_register_operand" "")])
+ (zero_extract:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")
+ (match_operand:SI 4 "const_int_operand" ""))]))
+ (clobber (match_operand:SI 8 "s_register_operand" ""))]
+ "TARGET_ARM
+ && GET_CODE (operands[1]) == GET_CODE (operands[9])
+ && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
+ [(set (match_dup 8)
+ (match_op_dup 1
+ [(ashift:SI (match_dup 2) (match_dup 4))
+ (match_dup 5)]))
+ (set (match_dup 0)
+ (match_op_dup 1
+ [(lshiftrt:SI (match_dup 8) (match_dup 6))
+ (match_dup 7)]))]
+ "
+ operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
+")
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "logical_binary_operator"
+ [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")
+ (match_operand:SI 4 "const_int_operand" ""))
+ (match_operator:SI 9 "logical_binary_operator"
+ [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
+ (match_operand:SI 6 "const_int_operand" ""))
+ (match_operand:SI 7 "s_register_operand" "")])]))
+ (clobber (match_operand:SI 8 "s_register_operand" ""))]
+ "TARGET_ARM
+ && GET_CODE (operands[1]) == GET_CODE (operands[9])
+ && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
+ [(set (match_dup 8)
+ (match_op_dup 1
+ [(ashift:SI (match_dup 2) (match_dup 4))
+ (match_dup 5)]))
+ (set (match_dup 0)
+ (match_op_dup 1
+ [(ashiftrt:SI (match_dup 8) (match_dup 6))
+ (match_dup 7)]))]
+ "
+ operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
+")
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "logical_binary_operator"
+ [(match_operator:SI 9 "logical_binary_operator"
+ [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "")
+ (match_operand:SI 6 "const_int_operand" ""))
+ (match_operand:SI 7 "s_register_operand" "")])
+ (sign_extract:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")
+ (match_operand:SI 4 "const_int_operand" ""))]))
+ (clobber (match_operand:SI 8 "s_register_operand" ""))]
+ "TARGET_ARM
+ && GET_CODE (operands[1]) == GET_CODE (operands[9])
+ && INTVAL (operands[3]) == 32 - INTVAL (operands[6])"
+ [(set (match_dup 8)
+ (match_op_dup 1
+ [(ashift:SI (match_dup 2) (match_dup 4))
+ (match_dup 5)]))
+ (set (match_dup 0)
+ (match_op_dup 1
+ [(ashiftrt:SI (match_dup 8) (match_dup 6))
+ (match_dup 7)]))]
+ "
+ operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4])));
+")
;; Minimum and maximum insns
@@ -2596,6 +2652,19 @@
[(set_attr "length" "2")]
)
+(define_expand "ashldi3"
+ [(set (match_operand:DI 0 "s_register_operand" "")
+ (ashift:DI (match_operand:DI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "TARGET_ARM && (TARGET_IWMMXT || TARGET_CIRRUS)"
+ "
+ if (! s_register_operand (operands[1], DImode))
+ operands[1] = copy_to_mode_reg (DImode, operands[1]);
+ if (! s_register_operand (operands[2], SImode))
+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
+ "
+)
+
(define_insn "*arm_shiftsi3"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(match_operator:SI 3 "shift_operator"
@@ -2769,49 +2838,33 @@
[(set_attr "length" "2")]
)
-(define_insn "negsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "mnf%?s\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "negdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "mnf%?d\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*negdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (neg:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "mnf%?d\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
+(define_expand "negsf2"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (neg:SF (match_operand:SF 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ ""
)
-(define_insn "negxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (neg:XF (match_operand:XF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "mnf%?e\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
+(define_expand "negdf2"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (neg:DF (match_operand:DF 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "")
;; abssi2 doesn't really clobber the condition codes if a different register
;; is being set. To keep things simple, assume during rtl manipulations that
;; it does, but tell the final scan operator the truth. Similarly for
;; (neg (abs...))
-(define_insn "abssi2"
+(define_expand "abssi2"
+ [(parallel
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (abs:SI (match_operand:SI 1 "s_register_operand" "")))
+ (clobber (reg:CC CC_REGNUM))])]
+ "TARGET_ARM"
+ "")
+
+(define_insn "*arm_abssi2"
[(set (match_operand:SI 0 "s_register_operand" "=r,&r")
(abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
(clobber (reg:CC CC_REGNUM))]
@@ -2839,147 +2892,29 @@
(set_attr "length" "8")]
)
-(define_insn "abssf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "abs%?s\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "absdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "abs%?d\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "*absdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (abs:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "abs%?d\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "absxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (abs:XF (match_operand:XF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "abs%?e\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
+(define_expand "abssf2"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (abs:SF (match_operand:SF 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "")
-(define_insn "sqrtsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "sqt%?s\\t%0, %1"
- [(set_attr "type" "float_em")
- (set_attr "predicable" "yes")]
-)
+(define_expand "absdf2"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (abs:DF (match_operand:DF 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "")
-(define_insn "sqrtdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
+(define_expand "sqrtsf2"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
- "sqt%?d\\t%0, %1"
- [(set_attr "type" "float_em")
- (set_attr "predicable" "yes")]
-)
+ "")
-(define_insn "*sqrtdf_esfdf"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (sqrt:DF (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
+(define_expand "sqrtdf2"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
- "sqt%?d\\t%0, %1"
- [(set_attr "type" "float_em")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "sqrtxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "sqt%?e\\t%0, %1"
- [(set_attr "type" "float_em")
- (set_attr "predicable" "yes")]
-)
-
-;; SIN COS TAN and family are always emulated, so it's probably better
-;; to always call a library function.
-;(define_insn "sinsf2"
-; [(set (match_operand:SF 0 "s_register_operand" "=f")
-; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")]
-; UNSPEC_SIN))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
-; "sin%?s\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "sindf2"
-; [(set (match_operand:DF 0 "s_register_operand" "=f")
-; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")]
-; UNSPEC_SIN))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
-; "sin%?d\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "*sindf_esfdf"
-; [(set (match_operand:DF 0 "s_register_operand" "=f")
-; (unspec:DF [(float_extend:DF
-; (match_operand:SF 1 "s_register_operand" "f"))]
-; UNSPEC_SIN))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
-; "sin%?d\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "sinxf2"
-; [(set (match_operand:XF 0 "s_register_operand" "=f")
-; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")]
-; UNSPEC_SIN))]
-; "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
-; "sin%?e\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "cossf2"
-; [(set (match_operand:SF 0 "s_register_operand" "=f")
-; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")]
-; UNSPEC_COS))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
-; "cos%?s\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "cosdf2"
-; [(set (match_operand:DF 0 "s_register_operand" "=f")
-; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")]
-; UNSPEC_COS))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
-; "cos%?d\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "*cosdf_esfdf"
-; [(set (match_operand:DF 0 "s_register_operand" "=f")
-; (unspec:DF [(float_extend:DF
-; (match_operand:SF 1 "s_register_operand" "f"))]
-; UNSPEC_COS))]
-; "TARGET_ARM && TARGET_HARD_FLOAT"
-; "cos%?d\\t%0, %1"
-;[(set_attr "type" "float_em")])
-;
-;(define_insn "cosxf2"
-; [(set (match_operand:XF 0 "s_register_operand" "=f")
-; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")]
-; UNSEPC_COS))]
-; "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
-; "cos%?e\\t%0, %1"
-;[(set_attr "type" "float_em")])
+ "")
(define_insn_and_split "one_cmpldi2"
[(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
@@ -3046,90 +2981,68 @@
;; Fixed <--> Floating conversion insns
-(define_insn "floatsisf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "flt%?s\\t%0, %1"
- [(set_attr "type" "r_2_f")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "floatsidf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "flt%?d\\t%0, %1"
- [(set_attr "type" "r_2_f")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "floatsixf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (float:XF (match_operand:SI 1 "s_register_operand" "r")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "flt%?e\\t%0, %1"
- [(set_attr "type" "r_2_f")
- (set_attr "predicable" "yes")]
-)
+(define_expand "floatsisf2"
+ [(set (match_operand:SF 0 "s_register_operand" "")
+ (float:SF (match_operand:SI 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS)
+ {
+ emit_insn (gen_cirrus_floatsisf2 (operands[0], operands[1]));
+ DONE;
+ }
+")
-(define_insn "fix_truncsfsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (fix:SI (match_operand:SF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "fix%?z\\t%0, %1"
- [(set_attr "type" "f_2_r")
- (set_attr "predicable" "yes")]
-)
+(define_expand "floatsidf2"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (float:DF (match_operand:SI 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS)
+ {
+ emit_insn (gen_cirrus_floatsidf2 (operands[0], operands[1]));
+ DONE;
+ }
+")
-(define_insn "fix_truncdfsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (fix:SI (match_operand:DF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "fix%?z\\t%0, %1"
- [(set_attr "type" "f_2_r")
- (set_attr "predicable" "yes")]
-)
+(define_expand "fix_truncsfsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[0], SImode))
+ operands[0] = force_reg (SImode, operands[0]);
+ if (!cirrus_fp_register (operands[1], SFmode))
+ operands[1] = force_reg (SFmode, operands[0]);
+ emit_insn (gen_cirrus_truncsfsi2 (operands[0], operands[1]));
+ DONE;
+ }
+")
-(define_insn "fix_truncxfsi2"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (fix:SI (match_operand:XF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "fix%?z\\t%0, %1"
- [(set_attr "type" "f_2_r")
- (set_attr "predicable" "yes")]
-)
+(define_expand "fix_truncdfsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ "
+ if (TARGET_CIRRUS)
+ {
+ if (!cirrus_fp_register (operands[1], DFmode))
+ operands[1] = force_reg (DFmode, operands[0]);
+ emit_insn (gen_cirrus_truncdfsi2 (operands[0], operands[1]));
+ DONE;
+ }
+")
;; Truncation insns
-(define_insn "truncdfsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
- (float_truncate:SF
- (match_operand:DF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "mvf%?s\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "truncxfsf2"
- [(set (match_operand:SF 0 "s_register_operand" "=f")
+(define_expand "truncdfsf2"
+ [(set (match_operand:SF 0 "s_register_operand" "")
(float_truncate:SF
- (match_operand:XF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "mvf%?s\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "truncxfdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (float_truncate:DF
- (match_operand:XF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "mvf%?d\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
+ (match_operand:DF 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ ""
)
;; Zero and sign extension instructions.
@@ -3632,7 +3545,7 @@
(sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
"TARGET_ARM && arm_arch4"
"*
- /* If the address is invalid, this will split the instruction into two. */
+ /* If the address is invalid, this will split the instruction into two. */
if (bad_signed_byte_operand (operands[1], VOIDmode))
return \"#\";
return \"ldr%?sb\\t%0, %1\";
@@ -3668,7 +3581,7 @@
XEXP (operands[2], 0) = plus_constant (operands[3], low);
operands[1] = plus_constant (XEXP (operands[1], 0), offset - low);
}
- /* Ensure the sum is in correct canonical form */
+ /* Ensure the sum is in correct canonical form. */
else if (GET_CODE (operands[1]) == PLUS
&& GET_CODE (XEXP (operands[1], 1)) != CONST_INT
&& !s_register_operand (XEXP (operands[1], 1), VOIDmode))
@@ -3730,7 +3643,7 @@
(sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
"TARGET_ARM && arm_arch4"
"*
- /* If the address is invalid, this will split the instruction into two. */
+ /* If the address is invalid, this will split the instruction into two. */
if (bad_signed_byte_operand (operands[1], VOIDmode))
return \"#\";
return \"ldr%?sb\\t%0, %1\";
@@ -3765,7 +3678,7 @@
XEXP (operands[2], 0) = plus_constant (operands[0], low);
operands[1] = plus_constant (XEXP (operands[1], 0), offset - low);
}
- /* Ensure the sum is in correct canonical form */
+ /* Ensure the sum is in correct canonical form. */
else if (GET_CODE (operands[1]) == PLUS
&& GET_CODE (XEXP (operands[1], 1)) != CONST_INT
&& !s_register_operand (XEXP (operands[1], 1), VOIDmode))
@@ -3854,33 +3767,12 @@
(set_attr "pool_range" "32,32")]
)
-(define_insn "extendsfdf2"
- [(set (match_operand:DF 0 "s_register_operand" "=f")
- (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "mvf%?d\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "extendsfxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "mvf%?e\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
-)
-
-(define_insn "extenddfxf2"
- [(set (match_operand:XF 0 "s_register_operand" "=f")
- (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "mvf%?e\\t%0, %1"
- [(set_attr "type" "ffarith")
- (set_attr "predicable" "yes")]
+(define_expand "extendsfdf2"
+ [(set (match_operand:DF 0 "s_register_operand" "")
+ (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
+ ""
)
-
;; Move insns (including loads and stores)
@@ -3962,7 +3854,7 @@
(define_insn "*arm_movdi"
[(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>")
(match_operand:DI 1 "di_operand" "rIK,mi,r"))]
- "TARGET_ARM"
+ "TARGET_ARM && !TARGET_CIRRUS && ! TARGET_IWMMXT"
"*
return (output_move_double (operands));
"
@@ -3980,6 +3872,7 @@
[(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r")
(match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))]
"TARGET_THUMB
+ && !TARGET_CIRRUS
&& ( register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode))"
"*
@@ -4025,7 +3918,7 @@
"
if (TARGET_ARM)
{
- /* Everything except mem = const or mem = mem can be done easily */
+ /* Everything except mem = const or mem = mem can be done easily. */
if (GET_CODE (operands[0]) == MEM)
operands[1] = force_reg (SImode, operands[1]);
if (GET_CODE (operands[1]) == CONST_INT
@@ -4039,7 +3932,7 @@
DONE;
}
}
- else /* TARGET_THUMB.... */
+ else /* TARGET_THUMB.... */
{
if (!no_new_pseudos)
{
@@ -4060,7 +3953,7 @@
(define_insn "*arm_movsi_insn"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m")
(match_operand:SI 1 "general_operand" "rI,K,mi,r"))]
- "TARGET_ARM
+ "TARGET_ARM && ! TARGET_IWMMXT
&& ( register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
"@
@@ -4174,7 +4067,7 @@
;; This variant is used for AOF assembly, since it needs to mention the
;; pic register in the rtl.
(define_expand "pic_load_addr_based"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(unspec:SI [(match_operand 1 "" "") (match_dup 2)] UNSPEC_PIC_SYM))]
"TARGET_ARM && flag_pic"
"operands[2] = pic_offset_table_rtx;"
@@ -4212,7 +4105,7 @@
(use (label_ref (match_operand 1 "" "")))]
"TARGET_THUMB && flag_pic"
"*
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
CODE_LABEL_NUMBER (operands[1]));
return \"add\\t%0, %|pc\";
"
@@ -4227,7 +4120,7 @@
(use (label_ref (match_operand 1 "" "")))]
"TARGET_ARM && flag_pic"
"*
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
CODE_LABEL_NUMBER (operands[1]));
return \"add%?\\t%0, %|pc, %0\";
"
@@ -4275,7 +4168,7 @@
(set (match_dup 2)
(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
;; store the high byte
- (set (match_dup 4) (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
+ (set (match_dup 4) (match_dup 5))]
"TARGET_ARM"
"
{
@@ -4291,7 +4184,8 @@
operands[1] = adjust_address (operands[1], QImode, 0);
operands[3] = gen_lowpart (QImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
- operands[2] = gen_reg_rtx (SImode);
+ operands[2] = gen_reg_rtx (SImode);
+ operands[5] = gen_lowpart (QImode, operands[2]);
}"
)
@@ -4299,7 +4193,7 @@
[(set (match_dup 4) (match_dup 3))
(set (match_dup 2)
(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
- (set (match_operand 1 "" "") (subreg:QI (match_dup 2) 3))]
+ (set (match_operand 1 "" "") (match_dup 5))]
"TARGET_ARM"
"
{
@@ -4316,13 +4210,14 @@
operands[3] = gen_lowpart (QImode, operands[0]);
operands[0] = gen_lowpart (SImode, operands[0]);
operands[2] = gen_reg_rtx (SImode);
+ operands[5] = gen_lowpart (QImode, operands[2]);
}"
)
;; Subroutine to store a half word integer constant into memory.
(define_expand "storeinthi"
[(set (match_operand 0 "" "")
- (subreg:QI (match_operand 1 "" "") 0))
+ (match_operand 1 "" ""))
(set (match_dup 3) (match_dup 2))]
"TARGET_ARM"
"
@@ -4363,6 +4258,7 @@
operands[3] = adjust_address (op0, QImode, 1);
operands[0] = adjust_address (operands[0], QImode, 0);
operands[2] = gen_lowpart (QImode, operands[2]);
+ operands[1] = gen_lowpart (QImode, operands[1]);
}"
)
@@ -4523,7 +4419,7 @@
}
}
}
- /* Handle loading a large integer during reload */
+ /* Handle loading a large integer during reload. */
else if (GET_CODE (operands[1]) == CONST_INT
&& !const_ok_for_arm (INTVAL (operands[1]))
&& !const_ok_for_arm (~INTVAL (operands[1])))
@@ -4567,7 +4463,7 @@
= replace_equiv_address (operands[1],
copy_to_reg (XEXP (operands[1], 0)));
}
- /* Handle loading a large integer during reload */
+ /* Handle loading a large integer during reload. */
else if (GET_CODE (operands[1]) == CONST_INT
&& !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I'))
{
@@ -4585,8 +4481,8 @@
)
(define_insn "*thumb_movhi_insn"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l, m,*r,*h,l")
- (match_operand:HI 1 "general_operand" "l,mn,l,*h,*r,I"))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l")
+ (match_operand:HI 1 "general_operand" "l,m,l,*h,*r,I"))]
"TARGET_THUMB
&& ( register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode))"
@@ -4618,8 +4514,7 @@
return \"ldrh %0, %1\";
}"
[(set_attr "length" "2,4,2,2,2,2")
- (set_attr "type" "*,load,store1,*,*,*")
- (set_attr "pool_range" "*,64,*,*,*,*")]
+ (set_attr "type" "*,load,store1,*,*,*")]
)
@@ -4683,11 +4578,12 @@
(set (match_dup 3)
(ashiftrt:SI (match_dup 2) (const_int 16)))
(set (match_operand:HI 0 "s_register_operand" "")
- (subreg:HI (match_dup 3) 0))]
+ (match_dup 4))]
"TARGET_ARM"
"
operands[2] = gen_reg_rtx (SImode);
operands[3] = gen_reg_rtx (SImode);
+ operands[4] = gen_lowpart (HImode, operands[3]);
"
)
@@ -4871,7 +4767,7 @@
= replace_equiv_address (operands[1],
copy_to_reg (XEXP (operands[1], 0)));
}
- /* Handle loading a large integer during reload */
+ /* Handle loading a large integer during reload. */
else if (GET_CODE (operands[1]) == CONST_INT
&& !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I'))
{
@@ -4959,39 +4855,11 @@
"
)
-(define_insn "*arm_movsf_hard_insn"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f, m,f,r,r,r, m")
- (match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))]
- "TARGET_ARM
- && TARGET_HARD_FLOAT
- && (GET_CODE (operands[0]) != MEM
- || register_operand (operands[1], SFmode))"
- "@
- mvf%?s\\t%0, %1
- mnf%?s\\t%0, #%N1
- ldf%?s\\t%0, %1
- stf%?s\\t%1, %0
- str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
- stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
- mov%?\\t%0, %1
- ldr%?\\t%0, %1\\t%@ float
- str%?\\t%1, %0\\t%@ float"
- [(set_attr "length" "4,4,4,4,8,8,4,4,4")
- (set_attr "predicable" "yes")
- (set_attr "type"
- "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")
- (set_attr "pool_range" "*,*,1024,*,*,*,*,4096,*")
- (set_attr "neg_pool_range" "*,*,1012,*,*,*,*,4084,*")]
-)
-
-;; Exactly the same as above, except that all `f' cases are deleted.
-;; This is necessary to prevent reload from ever trying to use a `f' reg
-;; when -msoft-float.
-
(define_insn "*arm_movsf_soft_insn"
[(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
(match_operand:SF 1 "general_operand" "r,mE,r"))]
"TARGET_ARM
+ && !TARGET_CIRRUS
&& TARGET_SOFT_FLOAT
&& (GET_CODE (operands[0]) != MEM
|| register_operand (operands[1], SFmode))"
@@ -5090,48 +4958,11 @@
}"
)
-(define_insn "*movdf_hard_insn"
- [(set (match_operand:DF 0 "nonimmediate_operand"
- "=r,Q,r,m,r, f, f,f, m,!f,!r")
- (match_operand:DF 1 "general_operand"
- "Q, r,r,r,mF,fG,H,mF,f,r, f"))]
- "TARGET_ARM
- && TARGET_HARD_FLOAT
- && (GET_CODE (operands[0]) != MEM
- || register_operand (operands[1], DFmode))"
- "*
- {
- switch (which_alternative)
- {
- default:
- case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
- case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
- case 2: case 3: case 4: return output_move_double (operands);
- case 5: return \"mvf%?d\\t%0, %1\";
- case 6: return \"mnf%?d\\t%0, #%N1\";
- case 7: return \"ldf%?d\\t%0, %1\";
- case 8: return \"stf%?d\\t%1, %0\";
- case 9: return output_mov_double_fpu_from_arm (operands);
- case 10: return output_mov_double_arm_from_fpu (operands);
- }
- }
- "
- [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
- (set_attr "predicable" "yes")
- (set_attr "type"
- "load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
- (set_attr "pool_range" "*,*,*,*,1020,*,*,1024,*,*,*")
- (set_attr "neg_pool_range" "*,*,*,*,1008,*,*,1008,*,*,*")]
-)
-
-;; Software floating point version. This is essentially the same as movdi.
-;; Do not use `f' as a constraint to prevent reload from ever trying to use
-;; an `f' reg.
-
(define_insn "*movdf_soft_insn"
[(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,m")
(match_operand:DF 1 "soft_df_operand" "r,mF,r"))]
"TARGET_ARM && TARGET_SOFT_FLOAT
+ && !TARGET_CIRRUS
"
"* return output_move_double (operands);"
[(set_attr "length" "8,8,8")
@@ -5180,39 +5011,27 @@
(set_attr "pool_range" "*,*,*,1020,*,*")]
)
+;; Vector Moves
+(define_expand "movv2si"
+ [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
+ (match_operand:V2SI 1 "general_operand" ""))]
+ "TARGET_REALLY_IWMMXT"
+{
+})
-(define_expand "movxf"
- [(set (match_operand:XF 0 "general_operand" "")
- (match_operand:XF 1 "general_operand" ""))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "")
-
-;; Even when the XFmode patterns aren't enabled, we enable this after
-;; reloading so that we can push floating point registers in the prologue.
+(define_expand "movv4hi"
+ [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
+ (match_operand:V4HI 1 "general_operand" ""))]
+ "TARGET_REALLY_IWMMXT"
+{
+})
-(define_insn "*movxf_hard_insn"
- [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,f,m,f,r,r")
- (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
- "TARGET_ARM && TARGET_HARD_FLOAT && (ENABLE_XF_PATTERNS || reload_completed)"
- "*
- switch (which_alternative)
- {
- default:
- case 0: return \"mvf%?e\\t%0, %1\";
- case 1: return \"mnf%?e\\t%0, #%N1\";
- case 2: return \"ldf%?e\\t%0, %1\";
- case 3: return \"stf%?e\\t%1, %0\";
- case 4: return output_mov_long_double_fpu_from_arm (operands);
- case 5: return output_mov_long_double_arm_from_fpu (operands);
- case 6: return output_mov_long_double_arm_from_arm (operands);
- }
- "
- [(set_attr "length" "4,4,4,4,8,8,12")
- (set_attr "predicable" "yes")
- (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")
- (set_attr "pool_range" "*,*,1024,*,*,*,*")
- (set_attr "neg_pool_range" "*,*,1004,*,*,*,*")]
-)
+(define_expand "movv8qi"
+ [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
+ (match_operand:V8QI 1 "general_operand" ""))]
+ "TARGET_REALLY_IWMMXT"
+{
+})
;; load- and store-multiple insns
@@ -5347,7 +5166,7 @@
(use (match_operand:SI 2 "" ""))])]
"TARGET_ARM"
"
- /* Support only fixed point registers */
+ /* Support only fixed point registers. */
if (GET_CODE (operands[2]) != CONST_INT
|| INTVAL (operands[2]) > 14
|| INTVAL (operands[2]) < 2
@@ -5538,7 +5357,7 @@
;; Compare & branch insns
-;; The range calcualations are based as follows:
+;; The range calculations are based as follows:
;; For forward branches, the address calculation returns the address of
;; the next instruction. This is 2 beyond the branch instruction.
;; For backward branches, the address calculation returns the address of
@@ -5554,17 +5373,36 @@
;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048).
;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256).
-(define_insn "cbranchsi4"
- [(set (pc)
- (if_then_else
- (match_operator 0 "arm_comparison_operator"
- [(match_operand:SI 1 "register_operand" "l,r")
- (match_operand:SI 2 "nonmemory_operand" "rI,r")])
- (label_ref (match_operand 3 "" ""))
- (pc)))]
+(define_expand "cbranchsi4"
+ [(set (pc) (if_then_else
+ (match_operator 0 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_THUMB"
+ "
+ if (thumb_cmpneg_operand (operands[2], SImode))
+ {
+ emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2],
+ operands[3], operands[0]));
+ DONE;
+ }
+ if (!thumb_cmp_operand (operands[2], SImode))
+ operands[2] = force_reg (SImode, operands[2]);
+ ")
+
+(define_insn "*cbranchsi4_insn"
+ [(set (pc) (if_then_else
+ (match_operator 0 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "l,*h")
+ (match_operand:SI 2 "thumb_cmp_operand" "lI*h,*r")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
"TARGET_THUMB"
"*
output_asm_insn (\"cmp\\t%1, %2\", operands);
+
switch (get_attr_length (insn))
{
case 4: return \"b%d0\\t%l3\";
@@ -5589,13 +5427,111 @@
(const_int 8))))]
)
+(define_insn "cbranchsi4_scratch"
+ [(set (pc) (if_then_else
+ (match_operator 4 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "l,0")
+ (match_operand:SI 2 "thumb_cmpneg_operand" "L,J")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 0 "=l,l"))]
+ "TARGET_THUMB"
+ "*
+ output_asm_insn (\"add\\t%0, %1, #%n2\", operands);
+
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d4\\t%l3\";
+ case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
+ }
+ "
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+(define_insn "*movsi_cbranchsi4"
+ [(set (pc)
+ (if_then_else
+ (match_operator 3 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "0,l,l,l")
+ (const_int 0)])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*h,*m")
+ (match_dup 1))]
+ "TARGET_THUMB"
+ "*{
+ if (which_alternative == 0)
+ output_asm_insn (\"cmp\t%0, #0\", operands);
+ else if (which_alternative == 1)
+ output_asm_insn (\"sub\t%0, %1, #0\", operands);
+ else
+ {
+ output_asm_insn (\"cmp\t%1, #0\", operands);
+ if (which_alternative == 2)
+ output_asm_insn (\"mov\t%0, %1\", operands);
+ else
+ output_asm_insn (\"str\t%1, %0\", operands);
+ }
+ switch (get_attr_length (insn) - ((which_alternative > 1) ? 2 : 0))
+ {
+ case 4: return \"b%d3\\t%l2\";
+ case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (gt (symbol_ref ("which_alternative"))
+ (const_int 1))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (le (symbol_ref ("which_alternative"))
+ (const_int 1))
+ (if_then_else
+ (and (ge (minus (match_dup 2) (pc)) (const_int -250))
+ (le (minus (match_dup 2) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
+ (le (minus (match_dup 2) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 2) (pc)) (const_int -248))
+ (le (minus (match_dup 2) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 2) (pc)) (const_int -2038))
+ (le (minus (match_dup 2) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
(define_insn "*negated_cbranchsi4"
[(set (pc)
(if_then_else
- (match_operator 0 "arm_comparison_operator"
- [(match_operand:SI 1 "register_operand" "l")
- (neg:SI (match_operand:SI 2 "nonmemory_operand" "l"))])
- (label_ref (match_operand 3 "" ""))
+ (match_operator 0 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "l")
+ (neg:SI (match_operand:SI 2 "s_register_operand" "l"))])
+ (label_ref (match_operand 3 "" ""))
(pc)))]
"TARGET_THUMB"
"*
@@ -5624,6 +5560,836 @@
(const_int 8))))]
)
+(define_insn "*tbit_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 0 "equality_operator"
+ [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l")
+ (const_int 1)
+ (match_operand:SI 2 "const_int_operand" "i"))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 4 "=l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ rtx op[3];
+ op[0] = operands[4];
+ op[1] = operands[1];
+ op[2] = GEN_INT (32 - 1 - INTVAL (operands[2]));
+
+ output_asm_insn (\"lsl\\t%0, %1, %2\", op);
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d0\\t%l3\";
+ case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+
+(define_insn "*tstsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 3 "equality_operator"
+ [(and:SI (match_operand:SI 0 "s_register_operand" "%l")
+ (match_operand:SI 1 "s_register_operand" "l"))
+ (const_int 0)])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ "TARGET_THUMB"
+ "*
+ {
+ output_asm_insn (\"tst\\t%0, %1\", operands);
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d3\\t%l2\";
+ case 6: return \"b%D3\\t.LCB%=\;b\\t%l2\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D3\\t.LCB%=\;bl\\t%l2\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 2) (pc)) (const_int -250))
+ (le (minus (match_dup 2) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 2) (pc)) (const_int -2040))
+ (le (minus (match_dup 2) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+
+(define_insn "*andsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 5 "equality_operator"
+ [(and:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
+ (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
+ (const_int 0)])
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+ (and:SI (match_dup 2) (match_dup 3)))
+ (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ if (which_alternative == 0)
+ output_asm_insn (\"and\\t%0, %3\", operands);
+ else if (which_alternative == 1)
+ {
+ output_asm_insn (\"and\\t%1, %3\", operands);
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ }
+ else
+ {
+ output_asm_insn (\"and\\t%1, %3\", operands);
+ output_asm_insn (\"str\\t%1, %0\", operands);
+ }
+
+ switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
+ {
+ case 4: return \"b%d5\\t%l4\";
+ case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -250))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
+(define_insn "*orrsi3_cbranch_scratch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 4 "equality_operator"
+ [(ior:SI (match_operand:SI 1 "s_register_operand" "%0")
+ (match_operand:SI 2 "s_register_operand" "l"))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 0 "=l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ output_asm_insn (\"orr\\t%0, %2\", operands);
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d4\\t%l3\";
+ case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+
+(define_insn "*orrsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 5 "equality_operator"
+ [(ior:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
+ (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
+ (const_int 0)])
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+ (ior:SI (match_dup 2) (match_dup 3)))
+ (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ if (which_alternative == 0)
+ output_asm_insn (\"orr\\t%0, %3\", operands);
+ else if (which_alternative == 1)
+ {
+ output_asm_insn (\"orr\\t%1, %3\", operands);
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ }
+ else
+ {
+ output_asm_insn (\"orr\\t%1, %3\", operands);
+ output_asm_insn (\"str\\t%1, %0\", operands);
+ }
+
+ switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
+ {
+ case 4: return \"b%d5\\t%l4\";
+ case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -250))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
+(define_insn "*xorsi3_cbranch_scratch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 4 "equality_operator"
+ [(xor:SI (match_operand:SI 1 "s_register_operand" "%0")
+ (match_operand:SI 2 "s_register_operand" "l"))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 0 "=l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ output_asm_insn (\"eor\\t%0, %2\", operands);
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d4\\t%l3\";
+ case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+
+(define_insn "*xorsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 5 "equality_operator"
+ [(xor:SI (match_operand:SI 2 "s_register_operand" "%0,1,1,1")
+ (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
+ (const_int 0)])
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+ (xor:SI (match_dup 2) (match_dup 3)))
+ (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ if (which_alternative == 0)
+ output_asm_insn (\"eor\\t%0, %3\", operands);
+ else if (which_alternative == 1)
+ {
+ output_asm_insn (\"eor\\t%1, %3\", operands);
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ }
+ else
+ {
+ output_asm_insn (\"eor\\t%1, %3\", operands);
+ output_asm_insn (\"str\\t%1, %0\", operands);
+ }
+
+ switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
+ {
+ case 4: return \"b%d5\\t%l4\";
+ case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -250))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
+(define_insn "*bicsi3_cbranch_scratch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 4 "equality_operator"
+ [(and:SI (not:SI (match_operand:SI 2 "s_register_operand" "l"))
+ (match_operand:SI 1 "s_register_operand" "0"))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 0 "=l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ output_asm_insn (\"bic\\t%0, %2\", operands);
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d4\\t%l3\";
+ case 6: return \"b%D4\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D4\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+
+(define_insn "*bicsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 5 "equality_operator"
+ [(and:SI (not:SI (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
+ (match_operand:SI 2 "s_register_operand" "0,1,1,1"))
+ (const_int 0)])
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+ (and:SI (not:SI (match_dup 3)) (match_dup 2)))
+ (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ if (which_alternative == 0)
+ output_asm_insn (\"bic\\t%0, %3\", operands);
+ else if (which_alternative == 1)
+ {
+ output_asm_insn (\"bic\\t%1, %3\", operands);
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ }
+ else
+ {
+ output_asm_insn (\"bic\\t%1, %3\", operands);
+ output_asm_insn (\"str\\t%1, %0\", operands);
+ }
+
+ switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
+ {
+ case 4: return \"b%d5\\t%l4\";
+ case 6: return \"b%D5\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D5\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
+ }
+ }"
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -250))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
+(define_insn "*cbranchne_decr1"
+ [(set (pc)
+ (if_then_else (match_operator 3 "equality_operator"
+ [(match_operand:SI 2 "s_register_operand" "l,l,1,l")
+ (const_int 0)])
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+ (plus:SI (match_dup 2) (const_int -1)))
+ (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+ "TARGET_THUMB"
+ "*
+ {
+ rtx cond[2];
+ cond[0] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE
+ ? GEU : LTU),
+ VOIDmode, operands[2], const1_rtx);
+ cond[1] = operands[4];
+
+ if (which_alternative == 0)
+ output_asm_insn (\"sub\\t%0, %2, #1\", operands);
+ else if (which_alternative == 1)
+ {
+ /* We must provide an alternative for a hi reg because reload
+ cannot handle output reloads on a jump instruction, but we
+ can't subtract into that. Fortunately a mov from lo to hi
+ does not clobber the condition codes. */
+ output_asm_insn (\"sub\\t%1, %2, #1\", operands);
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ }
+ else
+ {
+ /* Similarly, but the target is memory. */
+ output_asm_insn (\"sub\\t%1, %2, #1\", operands);
+ output_asm_insn (\"str\\t%1, %0\", operands);
+ }
+
+ switch (get_attr_length (insn) - (which_alternative ? 2 : 0))
+ {
+ case 4:
+ output_asm_insn (\"b%d0\\t%l1\", cond);
+ return \"\";
+ case 6:
+ output_asm_insn (\"b%D0\\t.LCB%=\", cond);
+ return \"b\\t%l4\\t%@long jump\\n.LCB%=:\";
+ default:
+ output_asm_insn (\"b%D0\\t.LCB%=\", cond);
+ return \"bl\\t%l4\\t%@far jump\\n.LCB%=:\";
+ }
+ }
+ "
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set_attr_alternative "length"
+ [
+ ;; Alternative 0
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -250))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ ;; Alternative 1
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))
+ ;; Alternative 2
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))
+ ;; Alternative 3
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -248))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2038))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))])]
+)
+
+(define_insn "*addsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 4 "comparison_operator"
+ [(plus:SI
+ (match_operand:SI 2 "s_register_operand" "%l,0,*0,1,1,1")
+ (match_operand:SI 3 "reg_or_int_operand" "lL,IJ,*r,lIJ,lIJ,lIJ"))
+ (const_int 0)])
+ (label_ref (match_operand 5 "" ""))
+ (pc)))
+ (set
+ (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,l,*!h,*?h,*?m,*?m")
+ (plus:SI (match_dup 2) (match_dup 3)))
+ (clobber (match_scratch:SI 1 "=X,X,X,l,&l,&l"))]
+ "TARGET_THUMB
+ && (GET_CODE (operands[4]) == EQ
+ || GET_CODE (operands[4]) == NE
+ || GET_CODE (operands[4]) == GE
+ || GET_CODE (operands[4]) == LT)"
+ "*
+ {
+ rtx cond[3];
+
+
+ cond[0] = (which_alternative < 3) ? operands[0] : operands[1];
+ cond[1] = operands[2];
+ cond[2] = operands[3];
+
+ if (GET_CODE (cond[2]) == CONST_INT && INTVAL (cond[2]) < 0)
+ output_asm_insn (\"sub\\t%0, %1, #%n2\", cond);
+ else
+ output_asm_insn (\"add\\t%0, %1, %2\", cond);
+
+ if (which_alternative >= 3
+ && which_alternative < 4)
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ else if (which_alternative >= 4)
+ output_asm_insn (\"str\\t%1, %0\", operands);
+
+ switch (get_attr_length (insn) - ((which_alternative >= 3) ? 2 : 0))
+ {
+ case 4:
+ return \"b%d4\\t%l5\";
+ case 6:
+ return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
+ default:
+ return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
+ }
+ }
+ "
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (lt (symbol_ref ("which_alternative"))
+ (const_int 3))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (lt (symbol_ref ("which_alternative"))
+ (const_int 3))
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -250))
+ (le (minus (match_dup 5) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
+ (le (minus (match_dup 5) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -248))
+ (le (minus (match_dup 5) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
+ (le (minus (match_dup 5) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
+(define_insn "*addsi3_cbranch_scratch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 3 "comparison_operator"
+ [(plus:SI
+ (match_operand:SI 1 "s_register_operand" "%l,l,l,0")
+ (match_operand:SI 2 "reg_or_int_operand" "J,l,I,L"))
+ (const_int 0)])
+ (label_ref (match_operand 4 "" ""))
+ (pc)))
+ (clobber (match_scratch:SI 0 "=X,X,l,l"))]
+ "TARGET_THUMB
+ && (GET_CODE (operands[3]) == EQ
+ || GET_CODE (operands[3]) == NE
+ || GET_CODE (operands[3]) == GE
+ || GET_CODE (operands[3]) == LT)"
+ "*
+ {
+ switch (which_alternative)
+ {
+ case 0:
+ output_asm_insn (\"cmp\t%1, #%n2\", operands);
+ break;
+ case 1:
+ output_asm_insn (\"cmn\t%1, %2\", operands);
+ break;
+ case 3:
+ output_asm_insn (\"add\t%0, %1, %2\", operands);
+ break;
+ case 4:
+ output_asm_insn (\"add\t%0, %0, %2\", operands);
+ break;
+ }
+
+ switch (get_attr_length (insn))
+ {
+ case 4:
+ return \"b%d3\\t%l4\";
+ case 6:
+ return \"b%D3\\t.LCB%=\;b\\t%l4\\t%@long jump\\n.LCB%=:\";
+ default:
+ return \"b%D3\\t.LCB%=\;bl\\t%l4\\t%@far jump\\n.LCB%=:\";
+ }
+ }
+ "
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -250))
+ (le (minus (match_dup 4) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 4) (pc)) (const_int -2040))
+ (le (minus (match_dup 4) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
+
+(define_insn "*subsi3_cbranch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 4 "comparison_operator"
+ [(minus:SI
+ (match_operand:SI 2 "s_register_operand" "l,l,1,l")
+ (match_operand:SI 3 "s_register_operand" "l,l,l,l"))
+ (const_int 0)])
+ (label_ref (match_operand 5 "" ""))
+ (pc)))
+ (set (match_operand:SI 0 "thumb_cbrch_target_operand" "=l,*?h,*?m,*?m")
+ (minus:SI (match_dup 2) (match_dup 3)))
+ (clobber (match_scratch:SI 1 "=X,l,&l,&l"))]
+ "TARGET_THUMB
+ && (GET_CODE (operands[4]) == EQ
+ || GET_CODE (operands[4]) == NE
+ || GET_CODE (operands[4]) == GE
+ || GET_CODE (operands[4]) == LT)"
+ "*
+ {
+ if (which_alternative == 0)
+ output_asm_insn (\"sub\\t%0, %2, %3\", operands);
+ else if (which_alternative == 1)
+ {
+ /* We must provide an alternative for a hi reg because reload
+ cannot handle output reloads on a jump instruction, but we
+ can't subtract into that. Fortunately a mov from lo to hi
+ does not clobber the condition codes. */
+ output_asm_insn (\"sub\\t%1, %2, %3\", operands);
+ output_asm_insn (\"mov\\t%0, %1\", operands);
+ }
+ else
+ {
+ /* Similarly, but the target is memory. */
+ output_asm_insn (\"sub\\t%1, %2, %3\", operands);
+ output_asm_insn (\"str\\t%1, %0\", operands);
+ }
+
+ switch (get_attr_length (insn) - ((which_alternative != 0) ? 2 : 0))
+ {
+ case 4:
+ return \"b%d4\\t%l5\";
+ case 6:
+ return \"b%D4\\t.LCB%=\;b\\t%l5\\t%@long jump\\n.LCB%=:\";
+ default:
+ return \"b%D4\\t.LCB%=\;bl\\t%l5\\t%@far jump\\n.LCB%=:\";
+ }
+ }
+ "
+ [(set (attr "far_jump")
+ (if_then_else
+ (ior (and (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (eq_attr "length" "8"))
+ (eq_attr "length" "10"))
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (eq (symbol_ref ("which_alternative"))
+ (const_int 0))
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -250))
+ (le (minus (match_dup 5) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -2040))
+ (le (minus (match_dup 5) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8)))
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -248))
+ (le (minus (match_dup 5) (pc)) (const_int 256)))
+ (const_int 6)
+ (if_then_else
+ (and (ge (minus (match_dup 5) (pc)) (const_int -2038))
+ (le (minus (match_dup 5) (pc)) (const_int 2048)))
+ (const_int 8)
+ (const_int 10)))))]
+)
+
+(define_insn "*subsi3_cbranch_scratch"
+ [(set (pc)
+ (if_then_else
+ (match_operator 0 "arm_comparison_operator"
+ [(minus:SI (match_operand:SI 1 "register_operand" "l")
+ (match_operand:SI 2 "nonmemory_operand" "l"))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_THUMB
+ && (GET_CODE (operands[0]) == EQ
+ || GET_CODE (operands[0]) == NE
+ || GET_CODE (operands[0]) == GE
+ || GET_CODE (operands[0]) == LT)"
+ "*
+ output_asm_insn (\"cmp\\t%1, %2\", operands);
+ switch (get_attr_length (insn))
+ {
+ case 4: return \"b%d0\\t%l3\";
+ case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\";
+ default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\";
+ }
+ "
+ [(set (attr "far_jump")
+ (if_then_else
+ (eq_attr "length" "8")
+ (const_string "yes")
+ (const_string "no")))
+ (set (attr "length")
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -250))
+ (le (minus (match_dup 3) (pc)) (const_int 256)))
+ (const_int 4)
+ (if_then_else
+ (and (ge (minus (match_dup 3) (pc)) (const_int -2040))
+ (le (minus (match_dup 3) (pc)) (const_int 2048)))
+ (const_int 6)
+ (const_int 8))))]
+)
;; Comparison and test insns
@@ -5640,9 +6406,12 @@
(define_expand "cmpsf"
[(match_operand:SF 0 "s_register_operand" "")
- (match_operand:SF 1 "fpu_rhs_operand" "")]
- "TARGET_ARM && TARGET_HARD_FLOAT"
+ (match_operand:SF 1 "fpa_rhs_operand" "")]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
"
+ if (TARGET_CIRRUS && !cirrus_fp_register (operands[1], SFmode))
+ operands[1] = force_reg (SFmode, operands[1]);
+
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
DONE;
@@ -5651,20 +6420,12 @@
(define_expand "cmpdf"
[(match_operand:DF 0 "s_register_operand" "")
- (match_operand:DF 1 "fpu_rhs_operand" "")]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "
- arm_compare_op0 = operands[0];
- arm_compare_op1 = operands[1];
- DONE;
+ (match_operand:DF 1 "fpa_rhs_operand" "")]
+ "TARGET_ARM && TARGET_ANY_HARD_FLOAT"
"
-)
+ if (TARGET_CIRRUS && !cirrus_fp_register (operands[1], DFmode))
+ operands[1] = force_reg (DFmode, operands[1]);
-(define_expand "cmpxf"
- [(match_operand:XF 0 "s_register_operand" "")
- (match_operand:XF 1 "fpu_rhs_operand" "")]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "
arm_compare_op0 = operands[0];
arm_compare_op1 = operands[1];
DONE;
@@ -5721,124 +6482,47 @@
]
)
-(define_insn "*cmpsf_insn"
- [(set (reg:CCFP CC_REGNUM)
- (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
- (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- cmf%?\\t%0, %1
- cnf%?\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmpdf_insn"
- [(set (reg:CCFP CC_REGNUM)
- (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
- (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- cmf%?\\t%0, %1
- cnf%?\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmpesfdf_df"
- [(set (reg:CCFP CC_REGNUM)
- (compare:CCFP (float_extend:DF
- (match_operand:SF 0 "s_register_operand" "f,f"))
- (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- cmf%?\\t%0, %1
- cnf%?\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmpdf_esfdf"
+;; Cirrus SF compare instruction
+(define_insn "*cirrus_cmpsf"
[(set (reg:CCFP CC_REGNUM)
- (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "cmf%?\\t%0, %1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
+ (compare:CCFP (match_operand:SF 0 "cirrus_fp_register" "v")
+ (match_operand:SF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcmps%?\\tr15, %V0, %V1"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "compare")]
)
-(define_insn "*cmpxf_insn"
+;; Cirrus DF compare instruction
+(define_insn "*cirrus_cmpdf"
[(set (reg:CCFP CC_REGNUM)
- (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f")
- (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "@
- cmf%?\\t%0, %1
- cnf%?\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmpsf_trap"
- [(set (reg:CCFPE CC_REGNUM)
- (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
- (match_operand:SF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- cmf%?e\\t%0, %1
- cnf%?e\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmpdf_trap"
- [(set (reg:CCFPE CC_REGNUM)
- (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
- (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- cmf%?e\\t%0, %1
- cnf%?e\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmp_esfdf_df_trap"
- [(set (reg:CCFPE CC_REGNUM)
- (compare:CCFPE (float_extend:DF
- (match_operand:SF 0 "s_register_operand" "f,f"))
- (match_operand:DF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- cmf%?e\\t%0, %1
- cnf%?e\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
-
-(define_insn "*cmp_df_esfdf_trap"
- [(set (reg:CCFPE CC_REGNUM)
- (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
- (float_extend:DF
- (match_operand:SF 1 "s_register_operand" "f"))))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "cmf%?e\\t%0, %1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
-)
+ (compare:CCFP (match_operand:DF 0 "cirrus_fp_register" "v")
+ (match_operand:DF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcmpd%?\\tr15, %V0, %V1"
+ [(set_attr "type" "mav_farith")
+ (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_CIRRUS"
+ "{
+ arm_compare_op0 = operands[0];
+ arm_compare_op1 = operands[1];
+ DONE;
+ }")
-(define_insn "*cmpxf_trap"
- [(set (reg:CCFPE CC_REGNUM)
- (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f")
- (match_operand:XF 1 "fpu_add_operand" "fG,H")))]
- "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT"
- "@
- cmf%?e\\t%0, %1
- cnf%?e\\t%0, #%N1"
- [(set_attr "conds" "set")
- (set_attr "type" "f_2_r")]
+(define_insn "*cirrus_cmpdi"
+ [(set (reg:CC CC_REGNUM)
+ (compare:CC (match_operand:DI 0 "cirrus_fp_register" "v")
+ (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcmp64%?\\tr15, %V0, %V1"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "compare")]
)
; This insn allows redundant compares to be removed by cse, nothing should
@@ -6137,77 +6821,77 @@
; scc insns
(define_expand "seq"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(eq:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sne"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(ne:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sgt"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(gt:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sle"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(le:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sge"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(ge:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);"
)
(define_expand "slt"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(lt:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sgtu"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(gtu:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sleu"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(leu:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sgeu"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(geu:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sltu"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(ltu:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM"
"operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);"
)
(define_expand "sunordered"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(unordered:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
@@ -6215,7 +6899,7 @@
)
(define_expand "sordered"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(ordered:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
@@ -6223,7 +6907,7 @@
)
(define_expand "sungt"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(ungt:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
@@ -6231,7 +6915,7 @@
)
(define_expand "sunge"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(unge:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
@@ -6239,7 +6923,7 @@
)
(define_expand "sunlt"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(unlt:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
@@ -6247,7 +6931,7 @@
)
(define_expand "sunle"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
+ [(set (match_operand:SI 0 "s_register_operand" "")
(unle:SI (match_dup 1) (const_int 0)))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
@@ -6258,14 +6942,14 @@
;;; simple ARM instructions.
;
; (define_expand "suneq"
-; [(set (match_operand:SI 0 "s_register_operand" "=r")
+; [(set (match_operand:SI 0 "s_register_operand" "")
; (uneq:SI (match_dup 1) (const_int 0)))]
; "TARGET_ARM && TARGET_HARD_FLOAT"
; "abort ();"
; )
;
; (define_expand "sltgt"
-; [(set (match_operand:SI 0 "s_register_operand" "=r")
+; [(set (match_operand:SI 0 "s_register_operand" "")
; (ltgt:SI (match_dup 1) (const_int 0)))]
; "TARGET_ARM && TARGET_HARD_FLOAT"
; "abort ();"
@@ -6338,9 +7022,9 @@
FAIL;
/* When compiling for SOFT_FLOAT, ensure both arms are in registers.
- Otherwise, ensure it is a valid FP add operand */
+ Otherwise, ensure it is a valid FP add operand. */
if ((!TARGET_HARD_FLOAT)
- || (!fpu_add_operand (operands[3], SFmode)))
+ || (!fpa_add_operand (operands[3], SFmode)))
operands[3] = force_reg (SFmode, operands[3]);
ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1);
@@ -6352,7 +7036,7 @@
[(set (match_operand:DF 0 "s_register_operand" "")
(if_then_else:DF (match_operand 1 "arm_comparison_operator" "")
(match_operand:DF 2 "s_register_operand" "")
- (match_operand:DF 3 "fpu_add_operand" "")))]
+ (match_operand:DF 3 "fpa_add_operand" "")))]
"TARGET_ARM && TARGET_HARD_FLOAT"
"
{
@@ -6388,28 +7072,6 @@
(set_attr "conds" "use")]
)
-(define_insn "*movsfcc_hard_insn"
- [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
- (if_then_else:SF
- (match_operator 3 "arm_comparison_operator"
- [(match_operand 4 "cc_register" "") (const_int 0)])
- (match_operand:SF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H")
- (match_operand:SF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- mvf%D3s\\t%0, %2
- mnf%D3s\\t%0, #%N2
- mvf%d3s\\t%0, %1
- mnf%d3s\\t%0, #%N1
- mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
- mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
- mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
- mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
- [(set_attr "length" "4,4,4,4,8,8,8,8")
- (set_attr "type" "ffarith")
- (set_attr "conds" "use")]
-)
-
(define_insn "*movsfcc_soft_insn"
[(set (match_operand:SF 0 "s_register_operand" "=r,r")
(if_then_else:SF (match_operator 3 "arm_comparison_operator"
@@ -6423,28 +7085,6 @@
[(set_attr "conds" "use")]
)
-(define_insn "*movdfcc_insn"
- [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
- (if_then_else:DF
- (match_operator 3 "arm_comparison_operator"
- [(match_operand 4 "cc_register" "") (const_int 0)])
- (match_operand:DF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H")
- (match_operand:DF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))]
- "TARGET_ARM && TARGET_HARD_FLOAT"
- "@
- mvf%D3d\\t%0, %2
- mnf%D3d\\t%0, #%N2
- mvf%d3d\\t%0, %1
- mnf%d3d\\t%0, #%N1
- mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
- mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
- mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
- mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
- [(set_attr "length" "4,4,4,4,8,8,8,8")
- (set_attr "type" "ffarith")
- (set_attr "conds" "use")]
-)
-
;; Jump and linkage insns
@@ -6570,7 +7210,7 @@
)
(define_insn "*call_value_indirect"
- [(set (match_operand 0 "" "=l")
+ [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
@@ -6609,8 +7249,8 @@
)
(define_insn "*call_value_reg"
- [(set (match_operand 0 "" "=r,f")
- (call (mem:SI (match_operand:SI 1 "s_register_operand" "r,r"))
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:SI 1 "s_register_operand" "r"))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
@@ -6623,8 +7263,8 @@
)
(define_insn "*call_value_mem"
- [(set (match_operand 0 "" "=r,f")
- (call (mem:SI (match_operand:SI 1 "memory_operand" "m,m"))
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:SI 1 "memory_operand" "m"))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
@@ -6640,7 +7280,7 @@
;; The 'a' causes the operand to be treated as an address, i.e. no '#' output.
(define_insn "*call_symbol"
- [(call (mem:SI (match_operand:SI 0 "" "X"))
+ [(call (mem:SI (match_operand:SI 0 "" ""))
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
(clobber (reg:SI LR_REGNUM))]
@@ -6655,8 +7295,8 @@
)
(define_insn "*call_value_symbol"
- [(set (match_operand 0 "s_register_operand" "=r,f")
- (call (mem:SI (match_operand:SI 1 "" "X,X"))
+ [(set (match_operand 0 "s_register_operand" "")
+ (call (mem:SI (match_operand:SI 1 "" ""))
(match_operand:SI 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
@@ -6671,7 +7311,7 @@
)
(define_insn "*call_insn"
- [(call (mem:SI (match_operand:SI 0 "" "X"))
+ [(call (mem:SI (match_operand:SI 0 "" ""))
(match_operand:SI 1 "" ""))
(use (match_operand 2 "" ""))
(clobber (reg:SI LR_REGNUM))]
@@ -6684,8 +7324,8 @@
)
(define_insn "*call_value_insn"
- [(set (match_operand 0 "register_operand" "=l")
- (call (mem:SI (match_operand 1 "" "X"))
+ [(set (match_operand 0 "register_operand" "")
+ (call (mem:SI (match_operand 1 "" ""))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))]
@@ -6738,8 +7378,8 @@
)
(define_insn "*sibcall_value_insn"
- [(set (match_operand 0 "s_register_operand" "=r,f")
- (call (mem:SI (match_operand:SI 1 "" "X,X"))
+ [(set (match_operand 0 "s_register_operand" "")
+ (call (mem:SI (match_operand:SI 1 "" "X"))
(match_operand 2 "" "")))
(return)
(use (match_operand 3 "" ""))]
@@ -6764,6 +7404,7 @@
return output_return_instruction (const_true_rtx, TRUE, FALSE);
}"
[(set_attr "type" "load")
+ (set_attr "length" "12")
(set_attr "predicable" "yes")]
)
@@ -6784,6 +7425,7 @@
return output_return_instruction (operands[0], TRUE, FALSE);
}"
[(set_attr "conds" "use")
+ (set_attr "length" "12")
(set_attr "type" "load")]
)
@@ -6821,7 +7463,7 @@
(const_int 67108860)))] ; 0x03fffffc
"TARGET_ARM"
"
- operands[1] = gen_rtx_REG (CC_NOOVmode, 24);
+ operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM);
")
(define_insn "*check_arch2"
@@ -6997,6 +7639,24 @@
]
)
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "shiftable_operator"
+ [(match_operator:SI 2 "shiftable_operator"
+ [(match_operator:SI 3 "shift_operator"
+ [(match_operand:SI 4 "s_register_operand" "")
+ (match_operand:SI 5 "reg_or_int_operand" "")])
+ (match_operand:SI 6 "s_register_operand" "")])
+ (match_operand:SI 7 "arm_rhs_operand" "")]))
+ (clobber (match_operand:SI 8 "s_register_operand" ""))]
+ "TARGET_ARM"
+ [(set (match_dup 8)
+ (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
+ (match_dup 6)]))
+ (set (match_dup 0)
+ (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
+ "")
+
(define_insn "*arith_shiftsi_compare0"
[(set (reg:CC_NOOV CC_REGNUM)
(compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
@@ -7112,11 +7772,17 @@
(clobber (reg:CC CC_REGNUM))]
"TARGET_ARM"
"*
- if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx)
- return \"mov\\t%0, %2, lsr #31\";
+ if (operands[3] == const0_rtx)
+ {
+ if (GET_CODE (operands[1]) == LT)
+ return \"mov\\t%0, %2, lsr #31\";
+
+ if (GET_CODE (operands[1]) == GE)
+ return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
- if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx)
- return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\";
+ if (GET_CODE (operands[1]) == EQ)
+ return \"rsbs\\t%0, %2, #1\;movcc\\t%0, #0\";
+ }
if (GET_CODE (operands[1]) == NE)
{
@@ -7347,6 +8013,192 @@
(set_attr "length" "8")]
)
+(define_insn_and_split "*ior_scc_scc"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (ior:SI (match_operator:SI 3 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "arm_add_operand" "rIL")])
+ (match_operator:SI 6 "arm_comparison_operator"
+ [(match_operand:SI 4 "s_register_operand" "r")
+ (match_operand:SI 5 "arm_add_operand" "rIL")])))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM
+ && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y)
+ != CCmode)"
+ "#"
+ "TARGET_ARM && reload_completed"
+ [(set (match_dup 7)
+ (compare
+ (ior:SI
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
+ (const_int 0)))
+ (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
+ "operands[7]
+ = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
+ DOM_CC_X_OR_Y),
+ CC_REGNUM);"
+ [(set_attr "conds" "clob")
+ (set_attr "length" "16")])
+
+; If the above pattern is followed by a CMP insn, then the compare is
+; redundant, since we can rework the conditional instruction that follows.
+(define_insn_and_split "*ior_scc_scc_cmp"
+ [(set (match_operand 0 "dominant_cc_register" "")
+ (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "arm_add_operand" "rIL")])
+ (match_operator:SI 6 "arm_comparison_operator"
+ [(match_operand:SI 4 "s_register_operand" "r")
+ (match_operand:SI 5 "arm_add_operand" "rIL")]))
+ (const_int 0)))
+ (set (match_operand:SI 7 "s_register_operand" "=r")
+ (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
+ "TARGET_ARM"
+ "#"
+ "TARGET_ARM && reload_completed"
+ [(set (match_dup 0)
+ (compare
+ (ior:SI
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
+ (const_int 0)))
+ (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
+ ""
+ [(set_attr "conds" "set")
+ (set_attr "length" "16")])
+
+(define_insn_and_split "*and_scc_scc"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (and:SI (match_operator:SI 3 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "arm_add_operand" "rIL")])
+ (match_operator:SI 6 "arm_comparison_operator"
+ [(match_operand:SI 4 "s_register_operand" "r")
+ (match_operand:SI 5 "arm_add_operand" "rIL")])))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM
+ && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
+ != CCmode)"
+ "#"
+ "TARGET_ARM && reload_completed
+ && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
+ != CCmode)"
+ [(set (match_dup 7)
+ (compare
+ (and:SI
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
+ (const_int 0)))
+ (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))]
+ "operands[7]
+ = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6],
+ DOM_CC_X_AND_Y),
+ CC_REGNUM);"
+ [(set_attr "conds" "clob")
+ (set_attr "length" "16")])
+
+; If the above pattern is followed by a CMP insn, then the compare is
+; redundant, since we can rework the conditional instruction that follows.
+(define_insn_and_split "*and_scc_scc_cmp"
+ [(set (match_operand 0 "dominant_cc_register" "")
+ (compare (and:SI (match_operator:SI 3 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "arm_add_operand" "rIL")])
+ (match_operator:SI 6 "arm_comparison_operator"
+ [(match_operand:SI 4 "s_register_operand" "r")
+ (match_operand:SI 5 "arm_add_operand" "rIL")]))
+ (const_int 0)))
+ (set (match_operand:SI 7 "s_register_operand" "=r")
+ (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (match_op_dup 6 [(match_dup 4) (match_dup 5)])))]
+ "TARGET_ARM"
+ "#"
+ "TARGET_ARM && reload_completed"
+ [(set (match_dup 0)
+ (compare
+ (and:SI
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (match_op_dup 6 [(match_dup 4) (match_dup 5)]))
+ (const_int 0)))
+ (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
+ ""
+ [(set_attr "conds" "set")
+ (set_attr "length" "16")])
+
+;; If there is no dominance in the comparison, then we can still save an
+;; instruction in the AND case, since we can know that the second compare
+;; need only zero the value if false (if true, then the value is already
+;; correct).
+(define_insn_and_split "*and_scc_scc_nodom"
+ [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r")
+ (and:SI (match_operator:SI 3 "arm_comparison_operator"
+ [(match_operand:SI 1 "s_register_operand" "r,r,0")
+ (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")])
+ (match_operator:SI 6 "arm_comparison_operator"
+ [(match_operand:SI 4 "s_register_operand" "r,r,r")
+ (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")])))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM
+ && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y)
+ == CCmode)"
+ "#"
+ "TARGET_ARM && reload_completed"
+ [(parallel [(set (match_dup 0)
+ (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
+ (clobber (reg:CC CC_REGNUM))])
+ (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)]))
+ (set (match_dup 0)
+ (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)])
+ (match_dup 0)
+ (const_int 0)))]
+ "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]),
+ operands[4], operands[5]),
+ CC_REGNUM);
+ operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
+ operands[5]);"
+ [(set_attr "conds" "clob")
+ (set_attr "length" "20")])
+
+(define_split
+ [(set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV (ior:SI
+ (and:SI (match_operand:SI 0 "s_register_operand" "")
+ (const_int 1))
+ (match_operator:SI 1 "comparison_operator"
+ [(match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "arm_add_operand" "")]))
+ (const_int 0)))
+ (clobber (match_operand:SI 4 "s_register_operand" ""))]
+ "TARGET_ARM"
+ [(set (match_dup 4)
+ (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
+ (match_dup 0)))
+ (set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
+ (const_int 0)))]
+ "")
+
+(define_split
+ [(set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV (ior:SI
+ (match_operator:SI 1 "comparison_operator"
+ [(match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "arm_add_operand" "")])
+ (and:SI (match_operand:SI 0 "s_register_operand" "")
+ (const_int 1)))
+ (const_int 0)))
+ (clobber (match_operand:SI 4 "s_register_operand" ""))]
+ "TARGET_ARM"
+ [(set (match_dup 4)
+ (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
+ (match_dup 0)))
+ (set (reg:CC_NOOV CC_REGNUM)
+ (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1))
+ (const_int 0)))]
+ "")
+
(define_insn "*negscc"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(neg:SI (match_operator 3 "arm_comparison_operator"
@@ -7399,7 +8251,7 @@
return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\";
}
/* The only case that falls through to here is when both ops 1 & 2
- are constants */
+ are constants. */
}
if (GET_CODE (operands[5]) == GE
@@ -7418,7 +8270,7 @@
return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\";
}
/* The only case that falls through to here is when both ops 1 & 2
- are constants */
+ are constants. */
}
if (GET_CODE (operands[4]) == CONST_INT
&& !const_ok_for_arm (INTVAL (operands[4])))
@@ -7555,7 +8407,7 @@
"*
/* If we have an operation where (op x 0) is the identity operation and
the conditional operator is LT or GE and we are comparing against zero and
- everything is in registers then we can do this in two instructions */
+ everything is in registers then we can do this in two instructions. */
if (operands[3] == const0_rtx
&& GET_CODE (operands[7]) != AND
&& GET_CODE (operands[5]) == REG
@@ -8536,6 +9388,9 @@
(set (reg:CC CC_REGNUM)
(compare:CC (match_dup 1) (const_int 0)))]
"TARGET_ARM
+ && (!TARGET_CIRRUS
+ || (!cirrus_fp_register (operands[0], SImode)
+ && !cirrus_fp_register (operands[1], SImode)))
"
[(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0)))
(set (match_dup 0) (match_dup 1))])]
@@ -8699,9 +9554,9 @@
(unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
"TARGET_ARM"
"*
- if (USE_RETURN_INSN (FALSE))
+ if (use_return_insn (FALSE, next_nonnote_insn (insn)))
return output_return_instruction (const_true_rtx, FALSE, FALSE);
- return arm_output_epilogue (FALSE);
+ return arm_output_epilogue (next_nonnote_insn (insn));
"
;; Length is absolute worst case
[(set_attr "length" "44")
@@ -8717,7 +9572,7 @@
"TARGET_EITHER"
"*
if (TARGET_ARM)
- return arm_output_epilogue (TRUE);
+ return arm_output_epilogue (NULL);
else /* TARGET_THUMB */
return thumb_unexpanded_epilogue ();
"
@@ -8731,9 +9586,9 @@
)
(define_expand "eh_epilogue"
- [(use (match_operand:SI 0 "register_operand" "r"))
- (use (match_operand:SI 1 "register_operand" "r"))
- (use (match_operand:SI 2 "register_operand" "r"))]
+ [(use (match_operand:SI 0 "register_operand" ""))
+ (use (match_operand:SI 1 "register_operand" ""))
+ (use (match_operand:SI 2 "register_operand" ""))]
"TARGET_EITHER"
"
{
@@ -9000,6 +9855,15 @@
"
)
+(define_insn "align_8"
+ [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)]
+ "TARGET_REALLY_IWMMXT"
+ "*
+ assemble_align (64);
+ return \"\";
+ "
+)
+
(define_insn "consttable_end"
[(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
"TARGET_EITHER"
@@ -9084,7 +9948,7 @@
;; Miscellaneous Thumb patterns
(define_expand "tablejump"
- [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "l*r"))
+ [(parallel [(set (pc) (match_operand:SI 0 "register_operand" ""))
(use (label_ref (match_operand 1 "" "")))])]
"TARGET_THUMB"
"
@@ -9110,12 +9974,12 @@
;; V5 Instructions,
-(define_insn "clz"
- [(set (match_operand:SI 0 "s_register_operand" "=r")
- (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")]
- UNSPEC_CLZ))]
+(define_insn "clzsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (clz:SI (match_operand:SI 1 "s_register_operand" "r")))]
"TARGET_ARM && arm_arch5"
- "clz\\t%0, %1")
+ "clz%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
(define_expand "ffssi2"
[(set (match_operand:SI 0 "s_register_operand" "")
@@ -9131,12 +9995,32 @@
emit_insn (gen_negsi2 (t1, operands[1]));
emit_insn (gen_andsi3 (t2, operands[1], t1));
- emit_insn (gen_clz (t3, t2));
+ emit_insn (gen_clzsi2 (t3, t2));
emit_insn (gen_subsi3 (operands[0], GEN_INT (32), t3));
DONE;
}"
)
+(define_expand "ctzsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (ctz:SI (match_operand:SI 1 "s_register_operand" "")))]
+ "TARGET_ARM && arm_arch5"
+ "
+ {
+ rtx t1, t2, t3;
+
+ t1 = gen_reg_rtx (SImode);
+ t2 = gen_reg_rtx (SImode);
+ t3 = gen_reg_rtx (SImode);
+
+ emit_insn (gen_negsi2 (t1, operands[1]));
+ emit_insn (gen_andsi3 (t2, operands[1], t1));
+ emit_insn (gen_clzsi2 (t3, t2));
+ emit_insn (gen_subsi3 (operands[0], GEN_INT (31), t3));
+ DONE;
+ }"
+)
+
;; V5E instructions.
(define_insn "prefetch"
@@ -9161,3 +10045,10 @@
""
"%@ %0 needed for prologue"
)
+
+;; Load the FPA co-processor patterns
+(include "fpa.md")
+;; Load the Maverick co-processor patterns
+(include "cirrus.md")
+;; Load the Intel Wireless Multimedia Extension patterns
+(include "iwmmxt.md")
diff --git a/contrib/gcc/config/arm/cirrus.md b/contrib/gcc/config/arm/cirrus.md
new file mode 100644
index 000000000000..0da8469ddd2a
--- /dev/null
+++ b/contrib/gcc/config/arm/cirrus.md
@@ -0,0 +1,478 @@
+;; Cirrus EP9312 "Maverick" ARM floating point co-processor description.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Contributed by Red Hat.
+;; Written by Aldy Hernandez (aldyh@redhat.com)
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+
+; Cirrus types for invalid insn combinations
+; not Not a cirrus insn
+; normal Any Cirrus insn not covered by the special cases below
+; double cfldrd, cfldr64, cfstrd, cfstr64
+; compare cfcmps, cfcmpd, cfcmp32, cfcmp64
+; move cfmvdlr, cfmvdhr, cfmvsr, cfmv64lr, cfmv64hr
+(define_attr "cirrus" "not,normal,double,compare,move" (const_string "not"))
+
+
+(define_insn "cirrus_adddi3"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (plus:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:DI 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfadd64%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_addsi3"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (plus:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfadd32%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_addsf3"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (plus:SF (match_operand:SF 1 "cirrus_fp_register" "v")
+ (match_operand:SF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfadds%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_adddf3"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (plus:DF (match_operand:DF 1 "cirrus_fp_register" "v")
+ (match_operand:DF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfaddd%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_subdi3"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (minus:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:DI 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsub64%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_subsi3_insn"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (minus:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfsub32%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_subsf3"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (minus:SF (match_operand:SF 1 "cirrus_fp_register" "v")
+ (match_operand:SF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsubs%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_subdf3"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (minus:DF (match_operand:DF 1 "cirrus_fp_register" "v")
+ (match_operand:DF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsubd%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_mulsi3"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (mult:SI (match_operand:SI 2 "cirrus_fp_register" "v")
+ (match_operand:SI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfmul32%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "muldi3"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (mult:DI (match_operand:DI 2 "cirrus_fp_register" "v")
+ (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmul64%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_dmult")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_mulsi3addsi"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (plus:SI
+ (mult:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_fp_register" "v"))
+ (match_operand:SI 3 "cirrus_fp_register" "0")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfmac32%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+;; Cirrus SI multiply-subtract
+(define_insn "*cirrus_mulsi3subsi"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (minus:SI
+ (match_operand:SI 1 "cirrus_fp_register" "0")
+ (mult:SI (match_operand:SI 2 "cirrus_fp_register" "v")
+ (match_operand:SI 3 "cirrus_fp_register" "v"))))]
+ "0 && TARGET_ARM && TARGET_CIRRUS"
+ "cfmsc32%?\\t%V0, %V2, %V3"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_mulsf3"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (mult:SF (match_operand:SF 1 "cirrus_fp_register" "v")
+ (match_operand:SF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmuls%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_farith")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_muldf3"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (mult:DF (match_operand:DF 1 "cirrus_fp_register" "v")
+ (match_operand:DF 2 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmuld%?\\t%V0, %V1, %V2"
+ [(set_attr "type" "mav_dmult")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_ashl_const"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (ashift:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_shift_const" "")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfsh32%?\\t%V0, %V1, #%s2"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_ashiftrt_const"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (ashiftrt:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_shift_const" "")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfsh32%?\\t%V0, %V1, #-%s2"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_ashlsi3"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (ashift:SI (match_operand:SI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "register_operand" "r")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfrshl32%?\\t%V1, %V0, %s2"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "ashldi3_cirrus"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (ashift:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "register_operand" "r")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfrshl64%?\\t%V1, %V0, %s2"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_ashldi_const"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (ashift:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_shift_const" "")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsh64%?\\t%V0, %V1, #%s2"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_ashiftrtdi_const"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (ashiftrt:DI (match_operand:DI 1 "cirrus_fp_register" "v")
+ (match_operand:SI 2 "cirrus_shift_const" "")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfsh64%?\\t%V0, %V1, #-%s2"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_absdi2"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (abs:DI (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfabs64%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+;; This doesn't really clobber ``cc''. Fixme: aldyh.
+(define_insn "*cirrus_negdi2"
+ [(set (match_operand:DI 0 "cirrus_fp_register" "=v")
+ (neg:DI (match_operand:DI 1 "cirrus_fp_register" "v")))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfneg64%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_negsi2"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (neg:SI (match_operand:SI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfneg32%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_negsf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (neg:SF (match_operand:SF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfnegs%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_negdf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (neg:DF (match_operand:DF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfnegd%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+;; This doesn't really clobber the condition codes either.
+(define_insn "*cirrus_abssi2"
+ [(set (match_operand:SI 0 "cirrus_fp_register" "=v")
+ (abs:SI (match_operand:SI 1 "cirrus_fp_register" "v")))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_ARM && TARGET_CIRRUS && 0"
+ "cfabs32%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_abssf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (abs:SF (match_operand:SF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfabss%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_absdf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (abs:DF (match_operand:DF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfabsd%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+;; Convert Cirrus-SI to Cirrus-SF
+(define_insn "cirrus_floatsisf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (float:SF (match_operand:SI 1 "s_register_operand" "r")))
+ (clobber (match_scratch:DF 2 "=v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmv64lr%?\\t%Z2, %1\;cfcvt32s%?\\t%V0, %Y2"
+ [(set_attr "length" "8")
+ (set_attr "cirrus" "move")]
+)
+
+(define_insn "cirrus_floatsidf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (float:DF (match_operand:SI 1 "s_register_operand" "r")))
+ (clobber (match_scratch:DF 2 "=v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfmv64lr%?\\t%Z2, %1\;cfcvt32d%?\\t%V0, %Y2"
+ [(set_attr "length" "8")
+ (set_attr "cirrus" "move")]
+)
+
+(define_insn "floatdisf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (float:SF (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcvt64s%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")])
+
+(define_insn "floatdidf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (float:DF (match_operand:DI 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcvt64d%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")])
+
+(define_insn "cirrus_truncsfsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (fix:SI (fix:SF (match_operand:SF 1 "cirrus_fp_register" "v"))))
+ (clobber (match_scratch:DF 2 "=v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cftruncs32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2"
+ [(set_attr "length" "8")
+ (set_attr "cirrus" "normal")]
+)
+
+(define_insn "cirrus_truncdfsi2"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (fix:SI (fix:DF (match_operand:DF 1 "cirrus_fp_register" "v"))))
+ (clobber (match_scratch:DF 2 "=v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cftruncd32%?\\t%Y2, %V1\;cfmvr64l%?\\t%0, %Z2"
+ [(set_attr "length" "8")]
+)
+
+(define_insn "*cirrus_truncdfsf2"
+ [(set (match_operand:SF 0 "cirrus_fp_register" "=v")
+ (float_truncate:SF
+ (match_operand:DF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcvtds%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_extendsfdf2"
+ [(set (match_operand:DF 0 "cirrus_fp_register" "=v")
+ (float_extend:DF (match_operand:SF 1 "cirrus_fp_register" "v")))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "cfcvtsd%?\\t%V0, %V1"
+ [(set_attr "cirrus" "normal")]
+)
+
+(define_insn "*cirrus_arm_movdi"
+ [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,o<>,v,r,v,m,v")
+ (match_operand:DI 1 "di_operand" "rIK,mi,r,r,v,m,v,v"))]
+ "TARGET_ARM && TARGET_CIRRUS"
+ "*
+ {
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ case 2:
+ return (output_move_double (operands));
+
+ case 3: return \"cfmv64lr%?\\t%V0, %Q1\;cfmv64hr%?\\t%V0, %R1\";
+ case 4: return \"cfmvr64l%?\\t%Q0, %V1\;cfmvr64h%?\\t%R0, %V1\";
+
+ case 5: return \"cfldr64%?\\t%V0, %1\";
+ case 6: return \"cfstr64%?\\t%V1, %0\";
+
+ /* Shifting by 0 will just copy %1 into %0. */
+ case 7: return \"cfsh64%?\\t%V0, %V1, #0\";
+
+ default: abort ();
+ }
+ }"
+ [(set_attr "length" " 8, 8, 8, 8, 8, 4, 4, 4")
+ (set_attr "type" " *,load,store2, *, *, load,store2, *")
+ (set_attr "pool_range" " *,1020, *, *, *, *, *, *")
+ (set_attr "neg_pool_range" " *,1012, *, *, *, *, *, *")
+ (set_attr "cirrus" "not, not, not,move,normal,double,double,normal")]
+)
+
+;; Cirrus SI values have been outlawed. Look in arm.h for the comment
+;; on HARD_REGNO_MODE_OK.
+
+(define_insn "*cirrus_arm_movsi_insn"
+ [(set (match_operand:SI 0 "general_operand" "=r,r,r,m,*v,r,*v,T,*v")
+ (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,*v,T,*v,*v"))]
+ "TARGET_ARM && TARGET_CIRRUS && 0
+ && (register_operand (operands[0], SImode)
+ || register_operand (operands[1], SImode))"
+ "@
+ mov%?\\t%0, %1
+ mvn%?\\t%0, #%B1
+ ldr%?\\t%0, %1
+ str%?\\t%1, %0
+ cfmv64lr%?\\t%Z0, %1
+ cfmvr64l%?\\t%0, %Z1
+ cfldr32%?\\t%V0, %1
+ cfstr32%?\\t%V1, %0
+ cfsh32%?\\t%V0, %V1, #0"
+ [(set_attr "type" "*, *, load,store1, *, *, load,store1, *")
+ (set_attr "pool_range" "*, *, 4096, *, *, *, 1024, *, *")
+ (set_attr "neg_pool_range" "*, *, 4084, *, *, *, 1012, *, *")
+ (set_attr "cirrus" "not,not, not, not,move,normal,normal,normal,normal")]
+)
+
+(define_insn "*cirrus_movsf_hard_insn"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=v,v,v,r,m,r,r,m")
+ (match_operand:SF 1 "general_operand" "v,m,r,v,v,r,mE,r"))]
+ "TARGET_ARM && TARGET_CIRRUS
+ && (GET_CODE (operands[0]) != MEM
+ || register_operand (operands[1], SFmode))"
+ "@
+ cfcpys%?\\t%V0, %V1
+ cfldrs%?\\t%V0, %1
+ cfmvsr%?\\t%V0, %1
+ cfmvrs%?\\t%0, %V1
+ cfstrs%?\\t%V1, %0
+ mov%?\\t%0, %1
+ ldr%?\\t%0, %1\\t%@ float
+ str%?\\t%1, %0\\t%@ float"
+ [(set_attr "length" " *, *, *, *, *, 4, 4, 4")
+ (set_attr "type" " *, load, *, *,store1, *,load,store1")
+ (set_attr "pool_range" " *, *, *, *, *, *,4096, *")
+ (set_attr "neg_pool_range" " *, *, *, *, *, *,4084, *")
+ (set_attr "cirrus" "normal,normal,move,normal,normal,not, not, not")]
+)
+
+(define_insn "*cirrus_movdf_hard_insn"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Q,r,m,r,v,v,v,r,m")
+ (match_operand:DF 1 "general_operand" "Q,r,r,r,mF,v,m,r,v,v"))]
+ "TARGET_ARM
+ && TARGET_CIRRUS
+ && (GET_CODE (operands[0]) != MEM
+ || register_operand (operands[1], DFmode))"
+ "*
+ {
+ switch (which_alternative)
+ {
+ case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
+ case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
+ case 2: case 3: case 4: return output_move_double (operands);
+ case 5: return \"cfcpyd%?\\t%V0, %V1\";
+ case 6: return \"cfldrd%?\\t%V0, %1\";
+ case 7: return \"cfmvdlr\\t%V0, %Q1\;cfmvdhr%?\\t%V0, %R1\";
+ case 8: return \"cfmvrdl%?\\t%Q0, %V1\;cfmvrdh%?\\t%R0, %V1\";
+ case 9: return \"cfstrd%?\\t%V1, %0\";
+ default: abort ();
+ }
+ }"
+ [(set_attr "type" "load,store2, *,store2,load, *, load, *, *,store2")
+ (set_attr "length" " 4, 4, 8, 8, 8, 4, 4, 8, 8, 4")
+ (set_attr "pool_range" " *, *, *, *, 252, *, *, *, *, *")
+ (set_attr "neg_pool_range" " *, *, *, *, 244, *, *, *, *, *")
+ (set_attr "cirrus" " not, not,not, not, not,normal,double,move,normal,double")]
+)
+
diff --git a/contrib/gcc/config/arm/coff.h b/contrib/gcc/config/arm/coff.h
index 0a78268949e2..d6a6651ba90a 100644
--- a/contrib/gcc/config/arm/coff.h
+++ b/contrib/gcc/config/arm/coff.h
@@ -1,28 +1,27 @@
/* Definitions of target machine for GNU compiler.
For ARM with COFF object format.
- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003
Free Software Foundation, Inc.
Contributed by Doug Evans (devans@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
-
-/* Note - it is important that this definition matches the one in tcoff.h */
+/* Note - it is important that this definition matches the one in tcoff.h. */
#undef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX "_"
@@ -32,7 +31,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_VERSION fputs (" (ARM/coff)", stderr)
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME)
+#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
#ifndef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS \
@@ -44,23 +43,8 @@ Boston, MA 02111-1307, USA. */
#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-#include "dbxcoff.h"
-/* A C statement to output assembler commands which will identify the
- object file as having been compiled with GNU CC (or another GNU
- compiler). */
-
-/* This outputs a lot of .req's to define alias for various registers.
- Let's try to avoid this. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(STREAM) \
- do \
- { \
- fprintf (STREAM, "%s Generated by gcc %s for ARM/coff\n", \
- ASM_COMMENT_START, version_string); \
- fprintf (STREAM, ASM_APP_OFF); \
- } \
- while (0)
+#define TARGET_ASM_FILE_START_APP_OFF true
/* Switch into a generic section. */
#define TARGET_ASM_NAMED_SECTION default_coff_asm_named_section
diff --git a/contrib/gcc/config/arm/crtn.asm b/contrib/gcc/config/arm/crtn.asm
index 2f4b5422eb24..9ad75e3f2aab 100644
--- a/contrib/gcc/config/arm/crtn.asm
+++ b/contrib/gcc/config/arm/crtn.asm
@@ -39,7 +39,7 @@
# in crti.asm. If you change this macro you must also change
# that macro match.
#
- # Note - we do not try any fancy optimisations of the return
+ # Note - we do not try any fancy optimizations of the return
# sequences here, it is just not worth it. Instead keep things
# simple. Restore all the save resgisters, including the link
# register and then perform the correct function return instruction.
diff --git a/contrib/gcc/config/arm/ecos-elf.h b/contrib/gcc/config/arm/ecos-elf.h
index f1377a9eca24..d57fe8bb809d 100644
--- a/contrib/gcc/config/arm/ecos-elf.h
+++ b/contrib/gcc/config/arm/ecos-elf.h
@@ -1,22 +1,22 @@
/* Definitions for ecos based ARM systems using ELF
Copyright (C) 1998, 2001 Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#undef TARGET_VERSION
diff --git a/contrib/gcc/config/arm/elf.h b/contrib/gcc/config/arm/elf.h
index 0ad23f8f5d03..cb38264181dc 100644
--- a/contrib/gcc/config/arm/elf.h
+++ b/contrib/gcc/config/arm/elf.h
@@ -5,22 +5,22 @@
Contributed by Philip Blundell <philb@gnu.org> and
Catherine Moore <clm@cygnus.com>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#ifndef OBJECT_FORMAT_ELF
#error elf.h included before elfos.h
@@ -46,7 +46,7 @@ Boston, MA 02111-1307, USA. */
#ifndef SUBTARGET_ASM_FLOAT_SPEC
#define SUBTARGET_ASM_FLOAT_SPEC "\
-%{mapcs-float:-mfloat} %{msoft-float:-mno-fpu}"
+%{mapcs-float:-mfloat} %{msoft-float:-mfpu=softfpa}"
#endif
#ifndef ASM_SPEC
@@ -106,7 +106,7 @@ Boston, MA 02111-1307, USA. */
#endif
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME)
+#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
#endif
#ifndef MULTILIB_DEFAULTS
@@ -114,53 +114,12 @@ Boston, MA 02111-1307, USA. */
{ "marm", "mlittle-endian", "msoft-float", "mapcs-32", "mno-thumb-interwork", "fno-leading-underscore" }
#endif
-
-/* This outputs a lot of .req's to define alias for various registers.
- Let's try to avoid this. */
-#ifndef ASM_FILE_START
-#define ASM_FILE_START(STREAM) \
- do \
- { \
- fprintf (STREAM, "%s Generated by gcc %s for ARM/elf\n", \
- ASM_COMMENT_START, version_string); \
- output_file_directive (STREAM, main_input_filename); \
- fprintf (STREAM, ASM_APP_OFF); \
- } \
- while (0)
-#endif
-
-/* Output an internal label definition. */
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) \
- do \
- { \
- char * s = (char *) alloca (40 + strlen (PREFIX)); \
- extern int arm_target_label, arm_ccfsm_state; \
- extern rtx arm_target_insn; \
- \
- if (arm_ccfsm_state == 3 && arm_target_label == (NUM) \
- && !strcmp (PREFIX, "L")) \
- { \
- arm_ccfsm_state = 0; \
- arm_target_insn = NULL; \
- } \
- ASM_GENERATE_INTERNAL_LABEL (s, (PREFIX), (NUM)); \
- ASM_OUTPUT_LABEL (STREAM, s); \
- } \
- while (0)
+#define TARGET_ASM_FILE_START_APP_OFF true
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
#undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION arm_elf_asm_named_section
-#undef ASM_OUTPUT_ALIGNED_COMMON
-#define ASM_OUTPUT_ALIGNED_COMMON(STREAM, NAME, SIZE, ALIGN) \
- do \
- { \
- fprintf (STREAM, "\t.comm\t"); \
- assemble_name (STREAM, NAME); \
- fprintf (STREAM, ", %d, %d\n", SIZE, ALIGN); \
- } \
- while (0)
/* For PIC code we need to explicitly specify (PLT) and (GOT) relocs. */
#define NEED_PLT_RELOC flag_pic
diff --git a/contrib/gcc/config/arm/fpa.md b/contrib/gcc/config/arm/fpa.md
new file mode 100644
index 000000000000..3b6efbfbbda3
--- /dev/null
+++ b/contrib/gcc/config/arm/fpa.md
@@ -0,0 +1,752 @@
+;;- Machine description for FPA co-processor for ARM cpus.
+;; Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
+;; 2001, 2002, 2003 Free Software Foundation, Inc.
+;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
+;; and Martin Simmons (@harleqn.co.uk).
+;; More major hacks by Richard Earnshaw (rearnsha@arm.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 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; FPA automaton.
+(define_automaton "armfp")
+
+;; Floating point unit (FPA)
+(define_cpu_unit "fpa" "armfp")
+
+; The fpa10 doesn't really have a memory read unit, but it can start
+; to speculatively execute the instruction in the pipeline, provided
+; the data is already loaded, so pretend reads have a delay of 2 (and
+; that the pipeline is infinite).
+(define_cpu_unit "fpa_mem" "arm")
+
+(define_insn_reservation "fdivx" 71
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "fdivx"))
+ "core+fpa*69")
+
+(define_insn_reservation "fdivd" 59
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "fdivd"))
+ "core+fpa*57")
+
+(define_insn_reservation "fdivs" 31
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "fdivs"))
+ "core+fpa*29")
+
+(define_insn_reservation "fmul" 9
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "fmul"))
+ "core+fpa*7")
+
+(define_insn_reservation "ffmul" 6
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "ffmul"))
+ "core+fpa*4")
+
+(define_insn_reservation "farith" 4
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "farith"))
+ "core+fpa*2")
+
+(define_insn_reservation "ffarith" 2
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "ffarith"))
+ "core+fpa*2")
+
+(define_insn_reservation "r_2_f" 5
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "r_2_f"))
+ "core+fpa*3")
+
+(define_insn_reservation "f_2_r" 1
+ (and (eq_attr "fpu" "fpa")
+ (eq_attr "type" "f_2_r"))
+ "core+fpa*2")
+
+(define_insn_reservation "f_load" 3
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_load"))
+ "fpa_mem+core*3")
+
+(define_insn_reservation "f_store" 4
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_store"))
+ "core*4")
+
+(define_insn_reservation "r_mem_f" 6
+ (and (eq_attr "model_wbuf" "no")
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "r_mem_f")))
+ "core*6")
+
+(define_insn_reservation "f_mem_r" 7
+ (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r"))
+ "core*7")
+
+
+(define_insn "*addsf3_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f,f")
+ (plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
+ (match_operand:SF 2 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ adf%?s\\t%0, %1, %2
+ suf%?s\\t%0, %1, #%N2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*adddf3_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f,f")
+ (plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
+ (match_operand:DF 2 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ adf%?d\\t%0, %1, %2
+ suf%?d\\t%0, %1, #%N2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*adddf_esfdf_df_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f,f")
+ (plus:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f,f"))
+ (match_operand:DF 2 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ adf%?d\\t%0, %1, %2
+ suf%?d\\t%0, %1, #%N2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*adddf_df_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (plus:DF (match_operand:DF 1 "s_register_operand" "f")
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "adf%?d\\t%0, %1, %2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*adddf_esfdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (plus:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "adf%?d\\t%0, %1, %2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*subsf3_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f,f")
+ (minus:SF (match_operand:SF 1 "fpa_rhs_operand" "f,G")
+ (match_operand:SF 2 "fpa_rhs_operand" "fG,f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ suf%?s\\t%0, %1, %2
+ rsf%?s\\t%0, %2, %1"
+ [(set_attr "type" "farith")]
+)
+
+(define_insn "*subdf3_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f,f")
+ (minus:DF (match_operand:DF 1 "fpa_rhs_operand" "f,G")
+ (match_operand:DF 2 "fpa_rhs_operand" "fG,f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ suf%?d\\t%0, %1, %2
+ rsf%?d\\t%0, %2, %1"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*subdf_esfdf_df_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (minus:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "suf%?d\\t%0, %1, %2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*subdf_df_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f,f")
+ (minus:DF (match_operand:DF 1 "fpa_rhs_operand" "f,G")
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f,f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ suf%?d\\t%0, %1, %2
+ rsf%?d\\t%0, %2, %1"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*subdf_esfdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (minus:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "suf%?d\\t%0, %1, %2"
+ [(set_attr "type" "farith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*mulsf3_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (mult:SF (match_operand:SF 1 "s_register_operand" "f")
+ (match_operand:SF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "fml%?s\\t%0, %1, %2"
+ [(set_attr "type" "ffmul")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*muldf3_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mult:DF (match_operand:DF 1 "s_register_operand" "f")
+ (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "muf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fmul")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*muldf_esfdf_df_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mult:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "muf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fmul")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*muldf_df_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mult:DF (match_operand:DF 1 "s_register_operand" "f")
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "muf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fmul")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*muldf_esfdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mult:DF
+ (float_extend:DF (match_operand:SF 1 "s_register_operand" "f"))
+ (float_extend:DF (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "muf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fmul")
+ (set_attr "predicable" "yes")]
+)
+
+;; Division insns
+
+(define_insn "*divsf3_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f,f")
+ (div:SF (match_operand:SF 1 "fpa_rhs_operand" "f,G")
+ (match_operand:SF 2 "fpa_rhs_operand" "fG,f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ fdv%?s\\t%0, %1, %2
+ frd%?s\\t%0, %2, %1"
+ [(set_attr "type" "fdivs")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*divdf3_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f,f")
+ (div:DF (match_operand:DF 1 "fpa_rhs_operand" "f,G")
+ (match_operand:DF 2 "fpa_rhs_operand" "fG,f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ dvf%?d\\t%0, %1, %2
+ rdf%?d\\t%0, %2, %1"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*divdf_esfdf_df_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (div:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "dvf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*divdf_df_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (div:DF (match_operand:DF 1 "fpa_rhs_operand" "fG")
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "rdf%?d\\t%0, %2, %1"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*divdf_esfdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (div:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "dvf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*modsf3_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (mod:SF (match_operand:SF 1 "s_register_operand" "f")
+ (match_operand:SF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "rmf%?s\\t%0, %1, %2"
+ [(set_attr "type" "fdivs")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*moddf3_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mod:DF (match_operand:DF 1 "s_register_operand" "f")
+ (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "rmf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*moddf_esfdf_df_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mod:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "rmf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*moddf_df_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mod:DF (match_operand:DF 1 "s_register_operand" "f")
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "rmf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*moddf_esfdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (mod:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))
+ (float_extend:DF
+ (match_operand:SF 2 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "rmf%?d\\t%0, %1, %2"
+ [(set_attr "type" "fdivd")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*negsf2_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "mnf%?s\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*negdf2_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "mnf%?d\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*negdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (neg:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "mnf%?d\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*abssf2_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "abs%?s\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*absdf2_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "abs%?d\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*absdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (abs:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "abs%?d\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*sqrtsf2_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "sqt%?s\\t%0, %1"
+ [(set_attr "type" "float_em")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*sqrtdf2_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "sqt%?d\\t%0, %1"
+ [(set_attr "type" "float_em")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*sqrtdf_esfdf_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (sqrt:DF (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "sqt%?d\\t%0, %1"
+ [(set_attr "type" "float_em")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*floatsisf2_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "flt%?s\\t%0, %1"
+ [(set_attr "type" "r_2_f")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*floatsidf2_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "flt%?d\\t%0, %1"
+ [(set_attr "type" "r_2_f")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*fix_truncsfsi2_fpa"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "fix%?z\\t%0, %1"
+ [(set_attr "type" "f_2_r")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*fix_truncdfsi2_fpa"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "fix%?z\\t%0, %1"
+ [(set_attr "type" "f_2_r")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*truncdfsf2_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f")
+ (float_truncate:SF
+ (match_operand:DF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "mvf%?s\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*extendsfdf2_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f")
+ (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "mvf%?d\\t%0, %1"
+ [(set_attr "type" "ffarith")
+ (set_attr "predicable" "yes")]
+)
+
+(define_insn "*movsf_fpa"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f, m,f,r,r,r, m")
+ (match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))]
+ "TARGET_ARM
+ && TARGET_HARD_FLOAT
+ && (GET_CODE (operands[0]) != MEM
+ || register_operand (operands[1], SFmode))"
+ "@
+ mvf%?s\\t%0, %1
+ mnf%?s\\t%0, #%N1
+ ldf%?s\\t%0, %1
+ stf%?s\\t%1, %0
+ str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
+ stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
+ mov%?\\t%0, %1
+ ldr%?\\t%0, %1\\t%@ float
+ str%?\\t%1, %0\\t%@ float"
+ [(set_attr "length" "4,4,4,4,8,8,4,4,4")
+ (set_attr "predicable" "yes")
+ (set_attr "type"
+ "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")
+ (set_attr "pool_range" "*,*,1024,*,*,*,*,4096,*")
+ (set_attr "neg_pool_range" "*,*,1012,*,*,*,*,4084,*")]
+)
+
+(define_insn "*movdf_fpa"
+ [(set (match_operand:DF 0 "nonimmediate_operand"
+ "=r,Q,r,m,r, f, f,f, m,!f,!r")
+ (match_operand:DF 1 "general_operand"
+ "Q, r,r,r,mF,fG,H,mF,f,r, f"))]
+ "TARGET_ARM
+ && TARGET_HARD_FLOAT
+ && (GET_CODE (operands[0]) != MEM
+ || register_operand (operands[1], DFmode))"
+ "*
+ {
+ switch (which_alternative)
+ {
+ default:
+ case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
+ case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
+ case 2: case 3: case 4: return output_move_double (operands);
+ case 5: return \"mvf%?d\\t%0, %1\";
+ case 6: return \"mnf%?d\\t%0, #%N1\";
+ case 7: return \"ldf%?d\\t%0, %1\";
+ case 8: return \"stf%?d\\t%1, %0\";
+ case 9: return output_mov_double_fpa_from_arm (operands);
+ case 10: return output_mov_double_arm_from_fpa (operands);
+ }
+ }
+ "
+ [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
+ (set_attr "predicable" "yes")
+ (set_attr "type"
+ "load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
+ (set_attr "pool_range" "*,*,*,*,1020,*,*,1024,*,*,*")
+ (set_attr "neg_pool_range" "*,*,*,*,1008,*,*,1008,*,*,*")]
+)
+
+;; Saving and restoring the floating point registers in the prologue should
+;; be done in XFmode, even though we don't support that for anything else
+;; (Well, strictly it's 'internal representation', but that's effectively
+;; XFmode).
+
+(define_insn "*movxf_fpa"
+ [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,f,m,f,r,r")
+ (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
+ "TARGET_ARM && TARGET_HARD_FLOAT && reload_completed"
+ "*
+ switch (which_alternative)
+ {
+ default:
+ case 0: return \"mvf%?e\\t%0, %1\";
+ case 1: return \"mnf%?e\\t%0, #%N1\";
+ case 2: return \"ldf%?e\\t%0, %1\";
+ case 3: return \"stf%?e\\t%1, %0\";
+ case 4: return output_mov_long_double_fpa_from_arm (operands);
+ case 5: return output_mov_long_double_arm_from_fpa (operands);
+ case 6: return output_mov_long_double_arm_from_arm (operands);
+ }
+ "
+ [(set_attr "length" "4,4,4,4,8,8,12")
+ (set_attr "predicable" "yes")
+ (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")
+ (set_attr "pool_range" "*,*,1024,*,*,*,*")
+ (set_attr "neg_pool_range" "*,*,1004,*,*,*,*")]
+)
+
+(define_insn "*cmpsf_fpa"
+ [(set (reg:CCFP CC_REGNUM)
+ (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
+ (match_operand:SF 1 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ cmf%?\\t%0, %1
+ cnf%?\\t%0, #%N1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmpdf_fpa"
+ [(set (reg:CCFP CC_REGNUM)
+ (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
+ (match_operand:DF 1 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ cmf%?\\t%0, %1
+ cnf%?\\t%0, #%N1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmpesfdf_df_fpa"
+ [(set (reg:CCFP CC_REGNUM)
+ (compare:CCFP (float_extend:DF
+ (match_operand:SF 0 "s_register_operand" "f,f"))
+ (match_operand:DF 1 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ cmf%?\\t%0, %1
+ cnf%?\\t%0, #%N1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmpdf_esfdf_fpa"
+ [(set (reg:CCFP CC_REGNUM)
+ (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
+ (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "cmf%?\\t%0, %1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmpsf_trap_fpa"
+ [(set (reg:CCFPE CC_REGNUM)
+ (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
+ (match_operand:SF 1 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ cmf%?e\\t%0, %1
+ cnf%?e\\t%0, #%N1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmpdf_trap_fpa"
+ [(set (reg:CCFPE CC_REGNUM)
+ (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
+ (match_operand:DF 1 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ cmf%?e\\t%0, %1
+ cnf%?e\\t%0, #%N1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmp_esfdf_df_trap_fpa"
+ [(set (reg:CCFPE CC_REGNUM)
+ (compare:CCFPE (float_extend:DF
+ (match_operand:SF 0 "s_register_operand" "f,f"))
+ (match_operand:DF 1 "fpa_add_operand" "fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ cmf%?e\\t%0, %1
+ cnf%?e\\t%0, #%N1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*cmp_df_esfdf_trap_fpa"
+ [(set (reg:CCFPE CC_REGNUM)
+ (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
+ (float_extend:DF
+ (match_operand:SF 1 "s_register_operand" "f"))))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "cmf%?e\\t%0, %1"
+ [(set_attr "conds" "set")
+ (set_attr "type" "f_2_r")]
+)
+
+(define_insn "*movsfcc_fpa"
+ [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
+ (if_then_else:SF
+ (match_operator 3 "arm_comparison_operator"
+ [(match_operand 4 "cc_register" "") (const_int 0)])
+ (match_operand:SF 1 "fpa_add_operand" "0,0,fG,H,fG,fG,H,H")
+ (match_operand:SF 2 "fpa_add_operand" "fG,H,0,0,fG,H,fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ mvf%D3s\\t%0, %2
+ mnf%D3s\\t%0, #%N2
+ mvf%d3s\\t%0, %1
+ mnf%d3s\\t%0, #%N1
+ mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
+ mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
+ mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
+ mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
+ [(set_attr "length" "4,4,4,4,8,8,8,8")
+ (set_attr "type" "ffarith")
+ (set_attr "conds" "use")]
+)
+
+(define_insn "*movdfcc_fpa"
+ [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
+ (if_then_else:DF
+ (match_operator 3 "arm_comparison_operator"
+ [(match_operand 4 "cc_register" "") (const_int 0)])
+ (match_operand:DF 1 "fpa_add_operand" "0,0,fG,H,fG,fG,H,H")
+ (match_operand:DF 2 "fpa_add_operand" "fG,H,0,0,fG,H,fG,H")))]
+ "TARGET_ARM && TARGET_HARD_FLOAT"
+ "@
+ mvf%D3d\\t%0, %2
+ mnf%D3d\\t%0, #%N2
+ mvf%d3d\\t%0, %1
+ mnf%d3d\\t%0, #%N1
+ mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
+ mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
+ mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
+ mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
+ [(set_attr "length" "4,4,4,4,8,8,8,8")
+ (set_attr "type" "ffarith")
+ (set_attr "conds" "use")]
+)
+
diff --git a/contrib/gcc/config/arm/freebsd.h b/contrib/gcc/config/arm/freebsd.h
index 0d417a22ded0..cc3f72725b6f 100644
--- a/contrib/gcc/config/arm/freebsd.h
+++ b/contrib/gcc/config/arm/freebsd.h
@@ -1,28 +1,46 @@
/* Definitions for StrongARM running FreeBSD using the ELF format
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
+
#undef SUBTARGET_CPP_SPEC
#define SUBTARGET_CPP_SPEC FBSD_CPP_SPEC
+#undef LINK_SPEC
+#define LINK_SPEC " \
+ %{p:%nconsider using `-pg' instead of `-p' with gprof(1) } \
+ %{Wl,*:%*} \
+ %{v:-V} \
+ %{assert*} %{R*} %{rpath*} %{defsym*} \
+ %{shared:-Bshareable %{h*} %{soname*}} \
+ %{!shared: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }} \
+ %{static:-Bstatic}} \
+ %{symbolic:-Bsymbolic}"
+
/************************[ Target stuff ]***********************************/
@@ -47,8 +65,5 @@ Boston, MA 02111-1307, USA. */
#undef SUBTARGET_CPU_DEFAULT
#define SUBTARGET_CPU_DEFAULT TARGET_CPU_strongarm
-#undef ARM_OS_NAME
-#define ARM_OS_NAME "FreeBSD"
-
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (FreeBSD/StrongARM ELF)");
diff --git a/contrib/gcc/config/arm/ieee754-df.S b/contrib/gcc/config/arm/ieee754-df.S
new file mode 100644
index 000000000000..6a7aab859385
--- /dev/null
+++ b/contrib/gcc/config/arm/ieee754-df.S
@@ -0,0 +1,1224 @@
+/* ieee754-df.S double-precision floating point support for ARM
+
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Nicolas Pitre (nico@cam.org)
+
+ 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 2, or (at your option) any
+ later version.
+
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+ compiled version of this file into combinations with other programs,
+ and to distribute those combinations without any restriction coming
+ from the use of this file. (The General Public License restrictions
+ do apply in other respects; for example, they cover modification of
+ the file, and distribution when not linked into a combine
+ executable.)
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/*
+ * Notes:
+ *
+ * The goal of this code is to be as fast as possible. This is
+ * not meant to be easy to understand for the casual reader.
+ * For slightly simpler code please see the single precision version
+ * of this file.
+ *
+ * Only the default rounding mode is intended for best performances.
+ * Exceptions aren't supported yet, but that can be added quite easily
+ * if necessary without impacting performances.
+ */
+
+
+@ For FPA, float words are always big-endian.
+@ For VFP, floats words follow the memory system mode.
+#if defined(__VFP_FP__) && !defined(__ARMEB__)
+#define xl r0
+#define xh r1
+#define yl r2
+#define yh r3
+#else
+#define xh r0
+#define xl r1
+#define yh r2
+#define yl r3
+#endif
+
+
+#ifdef L_negdf2
+
+ARM_FUNC_START negdf2
+ @ flip sign bit
+ eor xh, xh, #0x80000000
+ RET
+
+ FUNC_END negdf2
+
+#endif
+
+#ifdef L_addsubdf3
+
+ARM_FUNC_START subdf3
+ @ flip sign bit of second arg
+ eor yh, yh, #0x80000000
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+ b 1f @ Skip Thumb-code prologue
+#endif
+
+ARM_FUNC_START adddf3
+
+1: @ Compare both args, return zero if equal but the sign.
+ teq xl, yl
+ eoreq ip, xh, yh
+ teqeq ip, #0x80000000
+ beq LSYM(Lad_z)
+
+ @ If first arg is 0 or -0, return second arg.
+ @ If second arg is 0 or -0, return first arg.
+ orrs ip, xl, xh, lsl #1
+ moveq xl, yl
+ moveq xh, yh
+ orrnes ip, yl, yh, lsl #1
+ RETc(eq)
+
+ stmfd sp!, {r4, r5, lr}
+
+ @ Mask out exponents.
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and r4, xh, ip
+ and r5, yh, ip
+
+ @ If either of them is 0x7ff, result will be INF or NAN
+ teq r4, ip
+ teqne r5, ip
+ beq LSYM(Lad_i)
+
+ @ Compute exponent difference. Make largest exponent in r4,
+ @ corresponding arg in xh-xl, and positive exponent difference in r5.
+ subs r5, r5, r4
+ rsblt r5, r5, #0
+ ble 1f
+ add r4, r4, r5
+ eor yl, xl, yl
+ eor yh, xh, yh
+ eor xl, yl, xl
+ eor xh, yh, xh
+ eor yl, xl, yl
+ eor yh, xh, yh
+1:
+
+ @ If exponent difference is too large, return largest argument
+ @ already in xh-xl. We need up to 54 bit to handle proper rounding
+ @ of 0x1p54 - 1.1.
+ cmp r5, #(54 << 20)
+ RETLDM "r4, r5" hi
+
+ @ Convert mantissa to signed integer.
+ tst xh, #0x80000000
+ bic xh, xh, ip, lsl #1
+ orr xh, xh, #0x00100000
+ beq 1f
+ rsbs xl, xl, #0
+ rsc xh, xh, #0
+1:
+ tst yh, #0x80000000
+ bic yh, yh, ip, lsl #1
+ orr yh, yh, #0x00100000
+ beq 1f
+ rsbs yl, yl, #0
+ rsc yh, yh, #0
+1:
+ @ If exponent == difference, one or both args were denormalized.
+ @ Since this is not common case, rescale them off line.
+ teq r4, r5
+ beq LSYM(Lad_d)
+LSYM(Lad_x):
+ @ Scale down second arg with exponent difference.
+ @ Apply shift one bit left to first arg and the rest to second arg
+ @ to simplify things later, but only if exponent does not become 0.
+ mov ip, #0
+ movs r5, r5, lsr #20
+ beq 3f
+ teq r4, #(1 << 20)
+ beq 1f
+ movs xl, xl, lsl #1
+ adc xh, ip, xh, lsl #1
+ sub r4, r4, #(1 << 20)
+ subs r5, r5, #1
+ beq 3f
+
+ @ Shift yh-yl right per r5, keep leftover bits into ip.
+1: rsbs lr, r5, #32
+ blt 2f
+ mov ip, yl, lsl lr
+ mov yl, yl, lsr r5
+ orr yl, yl, yh, lsl lr
+ mov yh, yh, asr r5
+ b 3f
+2: sub r5, r5, #32
+ add lr, lr, #32
+ cmp yl, #1
+ adc ip, ip, yh, lsl lr
+ mov yl, yh, asr r5
+ mov yh, yh, asr #32
+3:
+ @ the actual addition
+ adds xl, xl, yl
+ adc xh, xh, yh
+
+ @ We now have a result in xh-xl-ip.
+ @ Keep absolute value in xh-xl-ip, sign in r5.
+ ands r5, xh, #0x80000000
+ bpl LSYM(Lad_p)
+ rsbs ip, ip, #0
+ rscs xl, xl, #0
+ rsc xh, xh, #0
+
+ @ Determine how to normalize the result.
+LSYM(Lad_p):
+ cmp xh, #0x00100000
+ bcc LSYM(Lad_l)
+ cmp xh, #0x00200000
+ bcc LSYM(Lad_r0)
+ cmp xh, #0x00400000
+ bcc LSYM(Lad_r1)
+
+ @ Result needs to be shifted right.
+ movs xh, xh, lsr #1
+ movs xl, xl, rrx
+ movs ip, ip, rrx
+ orrcs ip, ip, #1
+ add r4, r4, #(1 << 20)
+LSYM(Lad_r1):
+ movs xh, xh, lsr #1
+ movs xl, xl, rrx
+ movs ip, ip, rrx
+ orrcs ip, ip, #1
+ add r4, r4, #(1 << 20)
+
+ @ Our result is now properly aligned into xh-xl, remaining bits in ip.
+ @ Round with MSB of ip. If halfway between two numbers, round towards
+ @ LSB of xl = 0.
+LSYM(Lad_r0):
+ adds xl, xl, ip, lsr #31
+ adc xh, xh, #0
+ teq ip, #0x80000000
+ biceq xl, xl, #1
+
+ @ One extreme rounding case may add a new MSB. Adjust exponent.
+ @ That MSB will be cleared when exponent is merged below.
+ tst xh, #0x00200000
+ addne r4, r4, #(1 << 20)
+
+ @ Make sure we did not bust our exponent.
+ adds ip, r4, #(1 << 20)
+ bmi LSYM(Lad_o)
+
+ @ Pack final result together.
+LSYM(Lad_e):
+ bic xh, xh, #0x00300000
+ orr xh, xh, r4
+ orr xh, xh, r5
+ RETLDM "r4, r5"
+
+LSYM(Lad_l):
+ @ Result must be shifted left and exponent adjusted.
+ @ No rounding necessary since ip will always be 0.
+#if __ARM_ARCH__ < 5
+
+ teq xh, #0
+ movne r3, #-11
+ moveq r3, #21
+ moveq xh, xl
+ moveq xl, #0
+ mov r2, xh
+ movs ip, xh, lsr #16
+ moveq r2, r2, lsl #16
+ addeq r3, r3, #16
+ tst r2, #0xff000000
+ moveq r2, r2, lsl #8
+ addeq r3, r3, #8
+ tst r2, #0xf0000000
+ moveq r2, r2, lsl #4
+ addeq r3, r3, #4
+ tst r2, #0xc0000000
+ moveq r2, r2, lsl #2
+ addeq r3, r3, #2
+ tst r2, #0x80000000
+ addeq r3, r3, #1
+
+#else
+
+ teq xh, #0
+ moveq xh, xl
+ moveq xl, #0
+ clz r3, xh
+ addeq r3, r3, #32
+ sub r3, r3, #11
+
+#endif
+
+ @ determine how to shift the value.
+ subs r2, r3, #32
+ bge 2f
+ adds r2, r2, #12
+ ble 1f
+
+ @ shift value left 21 to 31 bits, or actually right 11 to 1 bits
+ @ since a register switch happened above.
+ add ip, r2, #20
+ rsb r2, r2, #12
+ mov xl, xh, lsl ip
+ mov xh, xh, lsr r2
+ b 3f
+
+ @ actually shift value left 1 to 20 bits, which might also represent
+ @ 32 to 52 bits if counting the register switch that happened earlier.
+1: add r2, r2, #20
+2: rsble ip, r2, #32
+ mov xh, xh, lsl r2
+ orrle xh, xh, xl, lsr ip
+ movle xl, xl, lsl r2
+
+ @ adjust exponent accordingly.
+3: subs r4, r4, r3, lsl #20
+ bgt LSYM(Lad_e)
+
+ @ Exponent too small, denormalize result.
+ @ Find out proper shift value.
+ mvn r4, r4, asr #20
+ subs r4, r4, #30
+ bge 2f
+ adds r4, r4, #12
+ bgt 1f
+
+ @ shift result right of 1 to 20 bits, sign is in r5.
+ add r4, r4, #20
+ rsb r2, r4, #32
+ mov xl, xl, lsr r4
+ orr xl, xl, xh, lsl r2
+ orr xh, r5, xh, lsr r4
+ RETLDM "r4, r5"
+
+ @ shift result right of 21 to 31 bits, or left 11 to 1 bits after
+ @ a register switch from xh to xl.
+1: rsb r4, r4, #12
+ rsb r2, r4, #32
+ mov xl, xl, lsr r2
+ orr xl, xl, xh, lsl r4
+ mov xh, r5
+ RETLDM "r4, r5"
+
+ @ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch
+ @ from xh to xl.
+2: mov xl, xh, lsr r4
+ mov xh, r5
+ RETLDM "r4, r5"
+
+ @ Adjust exponents for denormalized arguments.
+LSYM(Lad_d):
+ teq r4, #0
+ eoreq xh, xh, #0x00100000
+ addeq r4, r4, #(1 << 20)
+ eor yh, yh, #0x00100000
+ subne r5, r5, #(1 << 20)
+ b LSYM(Lad_x)
+
+ @ Result is x - x = 0, unless x = INF or NAN.
+LSYM(Lad_z):
+ sub ip, ip, #0x00100000 @ ip becomes 0x7ff00000
+ and r2, xh, ip
+ teq r2, ip
+ orreq xh, ip, #0x00080000
+ movne xh, #0
+ mov xl, #0
+ RET
+
+ @ Overflow: return INF.
+LSYM(Lad_o):
+ orr xh, r5, #0x7f000000
+ orr xh, xh, #0x00f00000
+ mov xl, #0
+ RETLDM "r4, r5"
+
+ @ At least one of x or y is INF/NAN.
+ @ if xh-xl != INF/NAN: return yh-yl (which is INF/NAN)
+ @ if yh-yl != INF/NAN: return xh-xl (which is INF/NAN)
+ @ if either is NAN: return NAN
+ @ if opposite sign: return NAN
+ @ return xh-xl (which is INF or -INF)
+LSYM(Lad_i):
+ teq r4, ip
+ movne xh, yh
+ movne xl, yl
+ teqeq r5, ip
+ RETLDM "r4, r5" ne
+
+ orrs r4, xl, xh, lsl #12
+ orreqs r4, yl, yh, lsl #12
+ teqeq xh, yh
+ orrne xh, r5, #0x00080000
+ movne xl, #0
+ RETLDM "r4, r5"
+
+ FUNC_END subdf3
+ FUNC_END adddf3
+
+ARM_FUNC_START floatunsidf
+ teq r0, #0
+ moveq r1, #0
+ RETc(eq)
+ stmfd sp!, {r4, r5, lr}
+ mov r4, #(0x400 << 20) @ initial exponent
+ add r4, r4, #((52-1) << 20)
+ mov r5, #0 @ sign bit is 0
+ mov xl, r0
+ mov xh, #0
+ b LSYM(Lad_l)
+
+ FUNC_END floatunsidf
+
+ARM_FUNC_START floatsidf
+ teq r0, #0
+ moveq r1, #0
+ RETc(eq)
+ stmfd sp!, {r4, r5, lr}
+ mov r4, #(0x400 << 20) @ initial exponent
+ add r4, r4, #((52-1) << 20)
+ ands r5, r0, #0x80000000 @ sign bit in r5
+ rsbmi r0, r0, #0 @ absolute value
+ mov xl, r0
+ mov xh, #0
+ b LSYM(Lad_l)
+
+ FUNC_END floatsidf
+
+ARM_FUNC_START extendsfdf2
+ movs r2, r0, lsl #1
+ beq 1f @ value is 0.0 or -0.0
+ mov xh, r2, asr #3 @ stretch exponent
+ mov xh, xh, rrx @ retrieve sign bit
+ mov xl, r2, lsl #28 @ retrieve remaining bits
+ ands r2, r2, #0xff000000 @ isolate exponent
+ beq 2f @ exponent was 0 but not mantissa
+ teq r2, #0xff000000 @ check if INF or NAN
+ eorne xh, xh, #0x38000000 @ fixup exponent otherwise.
+ RET
+
+1: mov xh, r0
+ mov xl, #0
+ RET
+
+2: @ value was denormalized. We can normalize it now.
+ stmfd sp!, {r4, r5, lr}
+ mov r4, #(0x380 << 20) @ setup corresponding exponent
+ add r4, r4, #(1 << 20)
+ and r5, xh, #0x80000000 @ move sign bit in r5
+ bic xh, xh, #0x80000000
+ b LSYM(Lad_l)
+
+ FUNC_END extendsfdf2
+
+#endif /* L_addsubdf3 */
+
+#ifdef L_muldivdf3
+
+ARM_FUNC_START muldf3
+
+ stmfd sp!, {r4, r5, r6, lr}
+
+ @ Mask out exponents.
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and r4, xh, ip
+ and r5, yh, ip
+
+ @ Trap any INF/NAN.
+ teq r4, ip
+ teqne r5, ip
+ beq LSYM(Lml_s)
+
+ @ Trap any multiplication by 0.
+ orrs r6, xl, xh, lsl #1
+ orrnes r6, yl, yh, lsl #1
+ beq LSYM(Lml_z)
+
+ @ Shift exponents right one bit to make room for overflow bit.
+ @ If either of them is 0, scale denormalized arguments off line.
+ @ Then add both exponents together.
+ movs r4, r4, lsr #1
+ teqne r5, #0
+ beq LSYM(Lml_d)
+LSYM(Lml_x):
+ add r4, r4, r5, asr #1
+
+ @ Preserve final sign in r4 along with exponent for now.
+ teq xh, yh
+ orrmi r4, r4, #0x8000
+
+ @ Convert mantissa to unsigned integer.
+ bic xh, xh, ip, lsl #1
+ bic yh, yh, ip, lsl #1
+ orr xh, xh, #0x00100000
+ orr yh, yh, #0x00100000
+
+#if __ARM_ARCH__ < 4
+
+ @ Well, no way to make it shorter without the umull instruction.
+ @ We must perform that 53 x 53 bit multiplication by hand.
+ stmfd sp!, {r7, r8, r9, sl, fp}
+ mov r7, xl, lsr #16
+ mov r8, yl, lsr #16
+ mov r9, xh, lsr #16
+ mov sl, yh, lsr #16
+ bic xl, xl, r7, lsl #16
+ bic yl, yl, r8, lsl #16
+ bic xh, xh, r9, lsl #16
+ bic yh, yh, sl, lsl #16
+ mul ip, xl, yl
+ mul fp, xl, r8
+ mov lr, #0
+ adds ip, ip, fp, lsl #16
+ adc lr, lr, fp, lsr #16
+ mul fp, r7, yl
+ adds ip, ip, fp, lsl #16
+ adc lr, lr, fp, lsr #16
+ mul fp, xl, sl
+ mov r5, #0
+ adds lr, lr, fp, lsl #16
+ adc r5, r5, fp, lsr #16
+ mul fp, r7, yh
+ adds lr, lr, fp, lsl #16
+ adc r5, r5, fp, lsr #16
+ mul fp, xh, r8
+ adds lr, lr, fp, lsl #16
+ adc r5, r5, fp, lsr #16
+ mul fp, r9, yl
+ adds lr, lr, fp, lsl #16
+ adc r5, r5, fp, lsr #16
+ mul fp, xh, sl
+ mul r6, r9, sl
+ adds r5, r5, fp, lsl #16
+ adc r6, r6, fp, lsr #16
+ mul fp, r9, yh
+ adds r5, r5, fp, lsl #16
+ adc r6, r6, fp, lsr #16
+ mul fp, xl, yh
+ adds lr, lr, fp
+ mul fp, r7, sl
+ adcs r5, r5, fp
+ mul fp, xh, yl
+ adc r6, r6, #0
+ adds lr, lr, fp
+ mul fp, r9, r8
+ adcs r5, r5, fp
+ mul fp, r7, r8
+ adc r6, r6, #0
+ adds lr, lr, fp
+ mul fp, xh, yh
+ adcs r5, r5, fp
+ adc r6, r6, #0
+ ldmfd sp!, {r7, r8, r9, sl, fp}
+
+#else
+
+ @ Here is the actual multiplication: 53 bits * 53 bits -> 106 bits.
+ umull ip, lr, xl, yl
+ mov r5, #0
+ umlal lr, r5, xl, yh
+ umlal lr, r5, xh, yl
+ mov r6, #0
+ umlal r5, r6, xh, yh
+
+#endif
+
+ @ The LSBs in ip are only significant for the final rounding.
+ @ Fold them into one bit of lr.
+ teq ip, #0
+ orrne lr, lr, #1
+
+ @ Put final sign in xh.
+ mov xh, r4, lsl #16
+ bic r4, r4, #0x8000
+
+ @ Adjust result if one extra MSB appeared (one of four times).
+ tst r6, #(1 << 9)
+ beq 1f
+ add r4, r4, #(1 << 19)
+ movs r6, r6, lsr #1
+ movs r5, r5, rrx
+ movs lr, lr, rrx
+ orrcs lr, lr, #1
+1:
+ @ Scale back to 53 bits.
+ @ xh contains sign bit already.
+ orr xh, xh, r6, lsl #12
+ orr xh, xh, r5, lsr #20
+ mov xl, r5, lsl #12
+ orr xl, xl, lr, lsr #20
+
+ @ Apply exponent bias, check range for underflow.
+ sub r4, r4, #0x00f80000
+ subs r4, r4, #0x1f000000
+ ble LSYM(Lml_u)
+
+ @ Round the result.
+ movs lr, lr, lsl #12
+ bpl 1f
+ adds xl, xl, #1
+ adc xh, xh, #0
+ teq lr, #0x80000000
+ biceq xl, xl, #1
+
+ @ Rounding may have produced an extra MSB here.
+ @ The extra bit is cleared before merging the exponent below.
+ tst xh, #0x00200000
+ addne r4, r4, #(1 << 19)
+1:
+ @ Check exponent for overflow.
+ adds ip, r4, #(1 << 19)
+ tst ip, #(1 << 30)
+ bne LSYM(Lml_o)
+
+ @ Add final exponent.
+ bic xh, xh, #0x00300000
+ orr xh, xh, r4, lsl #1
+ RETLDM "r4, r5, r6"
+
+ @ Result is 0, but determine sign anyway.
+LSYM(Lml_z):
+ eor xh, xh, yh
+LSYM(Ldv_z):
+ bic xh, xh, #0x7fffffff
+ mov xl, #0
+ RETLDM "r4, r5, r6"
+
+ @ Check if denormalized result is possible, otherwise return signed 0.
+LSYM(Lml_u):
+ cmn r4, #(53 << 19)
+ movle xl, #0
+ bicle xh, xh, #0x7fffffff
+ RETLDM "r4, r5, r6" le
+
+ @ Find out proper shift value.
+LSYM(Lml_r):
+ mvn r4, r4, asr #19
+ subs r4, r4, #30
+ bge 2f
+ adds r4, r4, #12
+ bgt 1f
+
+ @ shift result right of 1 to 20 bits, preserve sign bit, round, etc.
+ add r4, r4, #20
+ rsb r5, r4, #32
+ mov r3, xl, lsl r5
+ mov xl, xl, lsr r4
+ orr xl, xl, xh, lsl r5
+ movs xh, xh, lsl #1
+ mov xh, xh, lsr r4
+ mov xh, xh, rrx
+ adds xl, xl, r3, lsr #31
+ adc xh, xh, #0
+ teq lr, #0
+ teqeq r3, #0x80000000
+ biceq xl, xl, #1
+ RETLDM "r4, r5, r6"
+
+ @ shift result right of 21 to 31 bits, or left 11 to 1 bits after
+ @ a register switch from xh to xl. Then round.
+1: rsb r4, r4, #12
+ rsb r5, r4, #32
+ mov r3, xl, lsl r4
+ mov xl, xl, lsr r5
+ orr xl, xl, xh, lsl r4
+ bic xh, xh, #0x7fffffff
+ adds xl, xl, r3, lsr #31
+ adc xh, xh, #0
+ teq lr, #0
+ teqeq r3, #0x80000000
+ biceq xl, xl, #1
+ RETLDM "r4, r5, r6"
+
+ @ Shift value right of 32 to 64 bits, or 0 to 32 bits after a switch
+ @ from xh to xl. Leftover bits are in r3-r6-lr for rounding.
+2: rsb r5, r4, #32
+ mov r6, xl, lsl r5
+ mov r3, xl, lsr r4
+ orr r3, r3, xh, lsl r5
+ mov xl, xh, lsr r4
+ bic xh, xh, #0x7fffffff
+ bic xl, xl, xh, lsr r4
+ add xl, xl, r3, lsr #31
+ orrs r6, r6, lr
+ teqeq r3, #0x80000000
+ biceq xl, xl, #1
+ RETLDM "r4, r5, r6"
+
+ @ One or both arguments are denormalized.
+ @ Scale them leftwards and preserve sign bit.
+LSYM(Lml_d):
+ mov lr, #0
+ teq r4, #0
+ bne 2f
+ and r6, xh, #0x80000000
+1: movs xl, xl, lsl #1
+ adc xh, lr, xh, lsl #1
+ tst xh, #0x00100000
+ subeq r4, r4, #(1 << 19)
+ beq 1b
+ orr xh, xh, r6
+ teq r5, #0
+ bne LSYM(Lml_x)
+2: and r6, yh, #0x80000000
+3: movs yl, yl, lsl #1
+ adc yh, lr, yh, lsl #1
+ tst yh, #0x00100000
+ subeq r5, r5, #(1 << 20)
+ beq 3b
+ orr yh, yh, r6
+ b LSYM(Lml_x)
+
+ @ One or both args are INF or NAN.
+LSYM(Lml_s):
+ orrs r6, xl, xh, lsl #1
+ orrnes r6, yl, yh, lsl #1
+ beq LSYM(Lml_n) @ 0 * INF or INF * 0 -> NAN
+ teq r4, ip
+ bne 1f
+ orrs r6, xl, xh, lsl #12
+ bne LSYM(Lml_n) @ NAN * <anything> -> NAN
+1: teq r5, ip
+ bne LSYM(Lml_i)
+ orrs r6, yl, yh, lsl #12
+ bne LSYM(Lml_n) @ <anything> * NAN -> NAN
+
+ @ Result is INF, but we need to determine its sign.
+LSYM(Lml_i):
+ eor xh, xh, yh
+
+ @ Overflow: return INF (sign already in xh).
+LSYM(Lml_o):
+ and xh, xh, #0x80000000
+ orr xh, xh, #0x7f000000
+ orr xh, xh, #0x00f00000
+ mov xl, #0
+ RETLDM "r4, r5, r6"
+
+ @ Return NAN.
+LSYM(Lml_n):
+ mov xh, #0x7f000000
+ orr xh, xh, #0x00f80000
+ RETLDM "r4, r5, r6"
+
+ FUNC_END muldf3
+
+ARM_FUNC_START divdf3
+
+ stmfd sp!, {r4, r5, r6, lr}
+
+ @ Mask out exponents.
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and r4, xh, ip
+ and r5, yh, ip
+
+ @ Trap any INF/NAN or zeroes.
+ teq r4, ip
+ teqne r5, ip
+ orrnes r6, xl, xh, lsl #1
+ orrnes r6, yl, yh, lsl #1
+ beq LSYM(Ldv_s)
+
+ @ Shift exponents right one bit to make room for overflow bit.
+ @ If either of them is 0, scale denormalized arguments off line.
+ @ Then substract divisor exponent from dividend''s.
+ movs r4, r4, lsr #1
+ teqne r5, #0
+ beq LSYM(Ldv_d)
+LSYM(Ldv_x):
+ sub r4, r4, r5, asr #1
+
+ @ Preserve final sign into lr.
+ eor lr, xh, yh
+
+ @ Convert mantissa to unsigned integer.
+ @ Dividend -> r5-r6, divisor -> yh-yl.
+ mov r5, #0x10000000
+ mov yh, yh, lsl #12
+ orr yh, r5, yh, lsr #4
+ orr yh, yh, yl, lsr #24
+ movs yl, yl, lsl #8
+ mov xh, xh, lsl #12
+ teqeq yh, r5
+ beq LSYM(Ldv_1)
+ orr r5, r5, xh, lsr #4
+ orr r5, r5, xl, lsr #24
+ mov r6, xl, lsl #8
+
+ @ Initialize xh with final sign bit.
+ and xh, lr, #0x80000000
+
+ @ Ensure result will land to known bit position.
+ cmp r5, yh
+ cmpeq r6, yl
+ bcs 1f
+ sub r4, r4, #(1 << 19)
+ movs yh, yh, lsr #1
+ mov yl, yl, rrx
+1:
+ @ Apply exponent bias, check range for over/underflow.
+ add r4, r4, #0x1f000000
+ add r4, r4, #0x00f80000
+ cmn r4, #(53 << 19)
+ ble LSYM(Ldv_z)
+ cmp r4, ip, lsr #1
+ bge LSYM(Lml_o)
+
+ @ Perform first substraction to align result to a nibble.
+ subs r6, r6, yl
+ sbc r5, r5, yh
+ movs yh, yh, lsr #1
+ mov yl, yl, rrx
+ mov xl, #0x00100000
+ mov ip, #0x00080000
+
+ @ The actual division loop.
+1: subs lr, r6, yl
+ sbcs lr, r5, yh
+ subcs r6, r6, yl
+ movcs r5, lr
+ orrcs xl, xl, ip
+ movs yh, yh, lsr #1
+ mov yl, yl, rrx
+ subs lr, r6, yl
+ sbcs lr, r5, yh
+ subcs r6, r6, yl
+ movcs r5, lr
+ orrcs xl, xl, ip, lsr #1
+ movs yh, yh, lsr #1
+ mov yl, yl, rrx
+ subs lr, r6, yl
+ sbcs lr, r5, yh
+ subcs r6, r6, yl
+ movcs r5, lr
+ orrcs xl, xl, ip, lsr #2
+ movs yh, yh, lsr #1
+ mov yl, yl, rrx
+ subs lr, r6, yl
+ sbcs lr, r5, yh
+ subcs r6, r6, yl
+ movcs r5, lr
+ orrcs xl, xl, ip, lsr #3
+
+ orrs lr, r5, r6
+ beq 2f
+ mov r5, r5, lsl #4
+ orr r5, r5, r6, lsr #28
+ mov r6, r6, lsl #4
+ mov yh, yh, lsl #3
+ orr yh, yh, yl, lsr #29
+ mov yl, yl, lsl #3
+ movs ip, ip, lsr #4
+ bne 1b
+
+ @ We are done with a word of the result.
+ @ Loop again for the low word if this pass was for the high word.
+ tst xh, #0x00100000
+ bne 3f
+ orr xh, xh, xl
+ mov xl, #0
+ mov ip, #0x80000000
+ b 1b
+2:
+ @ Be sure result starts in the high word.
+ tst xh, #0x00100000
+ orreq xh, xh, xl
+ moveq xl, #0
+3:
+ @ Check if denormalized result is needed.
+ cmp r4, #0
+ ble LSYM(Ldv_u)
+
+ @ Apply proper rounding.
+ subs ip, r5, yh
+ subeqs ip, r6, yl
+ adcs xl, xl, #0
+ adc xh, xh, #0
+ teq ip, #0
+ biceq xl, xl, #1
+
+ @ Add exponent to result.
+ bic xh, xh, #0x00100000
+ orr xh, xh, r4, lsl #1
+ RETLDM "r4, r5, r6"
+
+ @ Division by 0x1p*: shortcut a lot of code.
+LSYM(Ldv_1):
+ and lr, lr, #0x80000000
+ orr xh, lr, xh, lsr #12
+ add r4, r4, #0x1f000000
+ add r4, r4, #0x00f80000
+ cmp r4, ip, lsr #1
+ bge LSYM(Lml_o)
+ cmp r4, #0
+ orrgt xh, xh, r4, lsl #1
+ RETLDM "r4, r5, r6" gt
+
+ cmn r4, #(53 << 19)
+ ble LSYM(Ldv_z)
+ orr xh, xh, #0x00100000
+ mov lr, #0
+ b LSYM(Lml_r)
+
+ @ Result must be denormalized: put remainder in lr for
+ @ rounding considerations.
+LSYM(Ldv_u):
+ orr lr, r5, r6
+ b LSYM(Lml_r)
+
+ @ One or both arguments are denormalized.
+ @ Scale them leftwards and preserve sign bit.
+LSYM(Ldv_d):
+ mov lr, #0
+ teq r4, #0
+ bne 2f
+ and r6, xh, #0x80000000
+1: movs xl, xl, lsl #1
+ adc xh, lr, xh, lsl #1
+ tst xh, #0x00100000
+ subeq r4, r4, #(1 << 19)
+ beq 1b
+ orr xh, xh, r6
+ teq r5, #0
+ bne LSYM(Ldv_x)
+2: and r6, yh, #0x80000000
+3: movs yl, yl, lsl #1
+ adc yh, lr, yh, lsl #1
+ tst yh, #0x00100000
+ subeq r5, r5, #(1 << 20)
+ beq 3b
+ orr yh, yh, r6
+ b LSYM(Ldv_x)
+
+ @ One or both arguments is either INF, NAN or zero.
+LSYM(Ldv_s):
+ teq r4, ip
+ teqeq r5, ip
+ beq LSYM(Lml_n) @ INF/NAN / INF/NAN -> NAN
+ teq r4, ip
+ bne 1f
+ orrs r4, xl, xh, lsl #12
+ bne LSYM(Lml_n) @ NAN / <anything> -> NAN
+ b LSYM(Lml_i) @ INF / <anything> -> INF
+1: teq r5, ip
+ bne 2f
+ orrs r5, yl, yh, lsl #12
+ bne LSYM(Lml_n) @ <anything> / NAN -> NAN
+ b LSYM(Lml_z) @ <anything> / INF -> 0
+2: @ One or both arguments are 0.
+ orrs r4, xl, xh, lsl #1
+ bne LSYM(Lml_i) @ <non_zero> / 0 -> INF
+ orrs r5, yl, yh, lsl #1
+ bne LSYM(Lml_z) @ 0 / <non_zero> -> 0
+ b LSYM(Lml_n) @ 0 / 0 -> NAN
+
+ FUNC_END divdf3
+
+#endif /* L_muldivdf3 */
+
+#ifdef L_cmpdf2
+
+ARM_FUNC_START gtdf2
+ARM_FUNC_ALIAS gedf2 gtdf2
+ mov ip, #-1
+ b 1f
+
+ARM_FUNC_START ltdf2
+ARM_FUNC_ALIAS ledf2 ltdf2
+ mov ip, #1
+ b 1f
+
+ARM_FUNC_START cmpdf2
+ARM_FUNC_ALIAS nedf2 cmpdf2
+ARM_FUNC_ALIAS eqdf2 cmpdf2
+ mov ip, #1 @ how should we specify unordered here?
+
+1: stmfd sp!, {r4, r5, lr}
+
+ @ Trap any INF/NAN first.
+ mov lr, #0x7f000000
+ orr lr, lr, #0x00f00000
+ and r4, xh, lr
+ and r5, yh, lr
+ teq r4, lr
+ teqne r5, lr
+ beq 3f
+
+ @ 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
+ orreqs ip, yl, yh, lsl #1 @ and y == 0.0 or -0.0
+ teqne xh, yh @ or xh == yh
+ teqeq xl, yl @ and xl == yl
+ moveq r0, #0 @ then equal.
+ RETLDM "r4, r5" eq
+
+ @ Check for sign difference.
+ teq xh, yh
+ movmi r0, xh, asr #31
+ orrmi r0, r0, #1
+ RETLDM "r4, r5" mi
+
+ @ Compare exponents.
+ cmp r4, r5
+
+ @ Compare mantissa if exponents are equal.
+ moveq xh, xh, lsl #12
+ cmpeq xh, yh, lsl #12
+ cmpeq xl, yl
+ movcs r0, yh, asr #31
+ mvncc r0, yh, asr #31
+ orr r0, r0, #1
+ RETLDM "r4, r5"
+
+ @ Look for a NAN.
+3: teq r4, lr
+ bne 4f
+ orrs xl, xl, xh, lsl #12
+ bne 5f @ x is NAN
+4: teq r5, lr
+ bne 2b
+ orrs yl, yl, yh, lsl #12
+ beq 2b @ y is not NAN
+5: mov r0, ip @ return unordered code from ip
+ RETLDM "r4, r5"
+
+ FUNC_END gedf2
+ FUNC_END gtdf2
+ FUNC_END ledf2
+ FUNC_END ltdf2
+ FUNC_END nedf2
+ FUNC_END eqdf2
+ FUNC_END cmpdf2
+
+#endif /* L_cmpdf2 */
+
+#ifdef L_unorddf2
+
+ARM_FUNC_START unorddf2
+ str lr, [sp, #-4]!
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and lr, xh, ip
+ teq lr, ip
+ bne 1f
+ orrs xl, xl, xh, lsl #12
+ bne 3f @ x is NAN
+1: and lr, yh, ip
+ teq lr, ip
+ bne 2f
+ orrs yl, yl, yh, lsl #12
+ bne 3f @ y is NAN
+2: mov r0, #0 @ arguments are ordered.
+ RETLDM
+
+3: mov r0, #1 @ arguments are unordered.
+ RETLDM
+
+ FUNC_END unorddf2
+
+#endif /* L_unorddf2 */
+
+#ifdef L_fixdfsi
+
+ARM_FUNC_START fixdfsi
+ orrs ip, xl, xh, lsl #1
+ beq 1f @ value is 0.
+
+ mov r3, r3, rrx @ preserve C flag (the actual sign)
+
+ @ check exponent range.
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and r2, xh, ip
+ teq r2, ip
+ beq 2f @ value is INF or NAN
+ bic ip, ip, #0x40000000
+ cmp r2, ip
+ bcc 1f @ value is too small
+ add ip, ip, #(31 << 20)
+ cmp r2, ip
+ bcs 3f @ value is too large
+
+ rsb r2, r2, ip
+ mov ip, xh, lsl #11
+ orr ip, ip, #0x80000000
+ orr ip, ip, xl, lsr #21
+ mov r2, r2, lsr #20
+ tst r3, #0x80000000 @ the sign bit
+ mov r0, ip, lsr r2
+ rsbne r0, r0, #0
+ RET
+
+1: mov r0, #0
+ RET
+
+2: orrs xl, xl, xh, lsl #12
+ bne 4f @ r0 is NAN.
+3: ands r0, r3, #0x80000000 @ the sign bit
+ moveq r0, #0x7fffffff @ maximum signed positive si
+ RET
+
+4: mov r0, #0 @ How should we convert NAN?
+ RET
+
+ FUNC_END fixdfsi
+
+#endif /* L_fixdfsi */
+
+#ifdef L_fixunsdfsi
+
+ARM_FUNC_START fixunsdfsi
+ orrs ip, xl, xh, lsl #1
+ movcss r0, #0 @ value is negative
+ RETc(eq) @ or 0 (xl, xh overlap r0)
+
+ @ check exponent range.
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and r2, xh, ip
+ teq r2, ip
+ beq 2f @ value is INF or NAN
+ bic ip, ip, #0x40000000
+ cmp r2, ip
+ bcc 1f @ value is too small
+ add ip, ip, #(31 << 20)
+ cmp r2, ip
+ bhi 3f @ value is too large
+
+ rsb r2, r2, ip
+ mov ip, xh, lsl #11
+ orr ip, ip, #0x80000000
+ orr ip, ip, xl, lsr #21
+ mov r2, r2, lsr #20
+ mov r0, ip, lsr r2
+ RET
+
+1: mov r0, #0
+ RET
+
+2: orrs xl, xl, xh, lsl #12
+ bne 4f @ value is NAN.
+3: mov r0, #0xffffffff @ maximum unsigned si
+ RET
+
+4: mov r0, #0 @ How should we convert NAN?
+ RET
+
+ FUNC_END fixunsdfsi
+
+#endif /* L_fixunsdfsi */
+
+#ifdef L_truncdfsf2
+
+ARM_FUNC_START truncdfsf2
+ orrs r2, xl, xh, lsl #1
+ moveq r0, r2, rrx
+ RETc(eq) @ value is 0.0 or -0.0
+
+ @ check exponent range.
+ mov ip, #0x7f000000
+ orr ip, ip, #0x00f00000
+ and r2, ip, xh
+ teq r2, ip
+ beq 2f @ value is INF or NAN
+ bic xh, xh, ip
+ cmp r2, #(0x380 << 20)
+ bls 4f @ value is too small
+
+ @ shift and round mantissa
+1: movs r3, xl, lsr #29
+ adc r3, r3, xh, lsl #3
+
+ @ if halfway between two numbers, round towards LSB = 0.
+ mov xl, xl, lsl #3
+ teq xl, #0x80000000
+ biceq r3, r3, #1
+
+ @ rounding might have created an extra MSB. If so adjust exponent.
+ tst r3, #0x00800000
+ addne r2, r2, #(1 << 20)
+ bicne r3, r3, #0x00800000
+
+ @ check exponent for overflow
+ mov ip, #(0x400 << 20)
+ orr ip, ip, #(0x07f << 20)
+ cmp r2, ip
+ bcs 3f @ overflow
+
+ @ adjust exponent, merge with sign bit and mantissa.
+ movs xh, xh, lsl #1
+ mov r2, r2, lsl #4
+ orr r0, r3, r2, rrx
+ eor r0, r0, #0x40000000
+ RET
+
+2: @ chech for NAN
+ orrs xl, xl, xh, lsl #12
+ movne r0, #0x7f000000
+ orrne r0, r0, #0x00c00000
+ RETc(ne) @ return NAN
+
+3: @ return INF with sign
+ and r0, xh, #0x80000000
+ orr r0, r0, #0x7f000000
+ orr r0, r0, #0x00800000
+ RET
+
+4: @ check if denormalized value is possible
+ subs r2, r2, #((0x380 - 24) << 20)
+ andle r0, xh, #0x80000000 @ too small, return signed 0.
+ RETc(le)
+
+ @ denormalize value so we can resume with the code above afterwards.
+ orr xh, xh, #0x00100000
+ mov r2, r2, lsr #20
+ rsb r2, r2, #25
+ cmp r2, #20
+ bgt 6f
+
+ rsb ip, r2, #32
+ mov r3, xl, lsl ip
+ mov xl, xl, lsr r2
+ orr xl, xl, xh, lsl ip
+ movs xh, xh, lsl #1
+ mov xh, xh, lsr r2
+ mov xh, xh, rrx
+5: teq r3, #0 @ fold r3 bits into the LSB
+ orrne xl, xl, #1 @ for rounding considerations.
+ mov r2, #(0x380 << 20) @ equivalent to the 0 float exponent
+ b 1b
+
+6: rsb r2, r2, #(12 + 20)
+ rsb ip, r2, #32
+ mov r3, xl, lsl r2
+ mov xl, xl, lsr ip
+ orr xl, xl, xh, lsl r2
+ and xh, xh, #0x80000000
+ b 5b
+
+ FUNC_END truncdfsf2
+
+#endif /* L_truncdfsf2 */
diff --git a/contrib/gcc/config/arm/ieee754-sf.S b/contrib/gcc/config/arm/ieee754-sf.S
new file mode 100644
index 000000000000..5c972452954b
--- /dev/null
+++ b/contrib/gcc/config/arm/ieee754-sf.S
@@ -0,0 +1,816 @@
+/* ieee754-sf.S single-precision floating point support for ARM
+
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Nicolas Pitre (nico@cam.org)
+
+ 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 2, or (at your option) any
+ later version.
+
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+ compiled version of this file into combinations with other programs,
+ and to distribute those combinations without any restriction coming
+ from the use of this file. (The General Public License restrictions
+ do apply in other respects; for example, they cover modification of
+ the file, and distribution when not linked into a combine
+ executable.)
+
+ 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.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/*
+ * Notes:
+ *
+ * The goal of this code is to be as fast as possible. This is
+ * not meant to be easy to understand for the casual reader.
+ *
+ * Only the default rounding mode is intended for best performances.
+ * Exceptions aren't supported yet, but that can be added quite easily
+ * if necessary without impacting performances.
+ */
+
+#ifdef L_negsf2
+
+ARM_FUNC_START negsf2
+ eor r0, r0, #0x80000000 @ flip sign bit
+ RET
+
+ FUNC_END negsf2
+
+#endif
+
+#ifdef L_addsubsf3
+
+ARM_FUNC_START subsf3
+ eor r1, r1, #0x80000000 @ flip sign bit of second arg
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+ b 1f @ Skip Thumb-code prologue
+#endif
+
+ARM_FUNC_START addsf3
+
+1: @ Compare both args, return zero if equal but the sign.
+ eor r2, r0, r1
+ teq r2, #0x80000000
+ beq LSYM(Lad_z)
+
+ @ If first arg is 0 or -0, return second arg.
+ @ If second arg is 0 or -0, return first arg.
+ bics r2, r0, #0x80000000
+ moveq r0, r1
+ bicnes r2, r1, #0x80000000
+ RETc(eq)
+
+ @ Mask out exponents.
+ mov ip, #0xff000000
+ and r2, r0, ip, lsr #1
+ and r3, r1, ip, lsr #1
+
+ @ If either of them is 255, result will be INF or NAN
+ teq r2, ip, lsr #1
+ teqne r3, ip, lsr #1
+ beq LSYM(Lad_i)
+
+ @ Compute exponent difference. Make largest exponent in r2,
+ @ corresponding arg in r0, and positive exponent difference in r3.
+ subs r3, r3, r2
+ addgt r2, r2, r3
+ eorgt r1, r0, r1
+ eorgt r0, r1, r0
+ eorgt r1, r0, r1
+ rsblt r3, r3, #0
+
+ @ If exponent difference is too large, return largest argument
+ @ already in r0. We need up to 25 bit to handle proper rounding
+ @ of 0x1p25 - 1.1.
+ cmp r3, #(25 << 23)
+ RETc(hi)
+
+ @ Convert mantissa to signed integer.
+ tst r0, #0x80000000
+ orr r0, r0, #0x00800000
+ bic r0, r0, #0xff000000
+ rsbne r0, r0, #0
+ tst r1, #0x80000000
+ orr r1, r1, #0x00800000
+ bic r1, r1, #0xff000000
+ rsbne r1, r1, #0
+
+ @ If exponent == difference, one or both args were denormalized.
+ @ Since this is not common case, rescale them off line.
+ teq r2, r3
+ beq LSYM(Lad_d)
+LSYM(Lad_x):
+
+ @ Scale down second arg with exponent difference.
+ @ Apply shift one bit left to first arg and the rest to second arg
+ @ to simplify things later, but only if exponent does not become 0.
+ movs r3, r3, lsr #23
+ teqne r2, #(1 << 23)
+ movne r0, r0, lsl #1
+ subne r2, r2, #(1 << 23)
+ subne r3, r3, #1
+
+ @ Shift second arg into ip, keep leftover bits into r1.
+ mov ip, r1, asr r3
+ rsb r3, r3, #32
+ mov r1, r1, lsl r3
+
+ add r0, r0, ip @ the actual addition
+
+ @ We now have a 64 bit result in r0-r1.
+ @ Keep absolute value in r0-r1, sign in r3.
+ ands r3, r0, #0x80000000
+ bpl LSYM(Lad_p)
+ rsbs r1, r1, #0
+ rsc r0, r0, #0
+
+ @ Determine how to normalize the result.
+LSYM(Lad_p):
+ cmp r0, #0x00800000
+ bcc LSYM(Lad_l)
+ cmp r0, #0x01000000
+ bcc LSYM(Lad_r0)
+ cmp r0, #0x02000000
+ bcc LSYM(Lad_r1)
+
+ @ Result needs to be shifted right.
+ movs r0, r0, lsr #1
+ mov r1, r1, rrx
+ add r2, r2, #(1 << 23)
+LSYM(Lad_r1):
+ movs r0, r0, lsr #1
+ mov r1, r1, rrx
+ add r2, r2, #(1 << 23)
+
+ @ Our result is now properly aligned into r0, remaining bits in r1.
+ @ Round with MSB of r1. If halfway between two numbers, round towards
+ @ LSB of r0 = 0.
+LSYM(Lad_r0):
+ add r0, r0, r1, lsr #31
+ teq r1, #0x80000000
+ biceq r0, r0, #1
+
+ @ Rounding may have added a new MSB. Adjust exponent.
+ @ That MSB will be cleared when exponent is merged below.
+ tst r0, #0x01000000
+ addne r2, r2, #(1 << 23)
+
+ @ Make sure we did not bust our exponent.
+ cmp r2, #(254 << 23)
+ bhi LSYM(Lad_o)
+
+ @ Pack final result together.
+LSYM(Lad_e):
+ bic r0, r0, #0x01800000
+ orr r0, r0, r2
+ orr r0, r0, r3
+ RET
+
+ @ Result must be shifted left.
+ @ No rounding necessary since r1 will always be 0.
+LSYM(Lad_l):
+
+#if __ARM_ARCH__ < 5
+
+ movs ip, r0, lsr #12
+ moveq r0, r0, lsl #12
+ subeq r2, r2, #(12 << 23)
+ tst r0, #0x00ff0000
+ moveq r0, r0, lsl #8
+ subeq r2, r2, #(8 << 23)
+ tst r0, #0x00f00000
+ moveq r0, r0, lsl #4
+ subeq r2, r2, #(4 << 23)
+ tst r0, #0x00c00000
+ moveq r0, r0, lsl #2
+ subeq r2, r2, #(2 << 23)
+ tst r0, #0x00800000
+ moveq r0, r0, lsl #1
+ subeq r2, r2, #(1 << 23)
+ cmp r2, #0
+ bgt LSYM(Lad_e)
+
+#else
+
+ clz ip, r0
+ sub ip, ip, #8
+ mov r0, r0, lsl ip
+ subs r2, r2, ip, lsl #23
+ bgt LSYM(Lad_e)
+
+#endif
+
+ @ Exponent too small, denormalize result.
+ mvn r2, r2, asr #23
+ add r2, r2, #2
+ orr r0, r3, r0, lsr r2
+ RET
+
+ @ Fixup and adjust bit position for denormalized arguments.
+ @ Note that r2 must not remain equal to 0.
+LSYM(Lad_d):
+ teq r2, #0
+ eoreq r0, r0, #0x00800000
+ addeq r2, r2, #(1 << 23)
+ eor r1, r1, #0x00800000
+ subne r3, r3, #(1 << 23)
+ b LSYM(Lad_x)
+
+ @ Result is x - x = 0, unless x is INF or NAN.
+LSYM(Lad_z):
+ mov ip, #0xff000000
+ and r2, r0, ip, lsr #1
+ teq r2, ip, lsr #1
+ moveq r0, ip, asr #2
+ movne r0, #0
+ RET
+
+ @ Overflow: return INF.
+LSYM(Lad_o):
+ orr r0, r3, #0x7f000000
+ orr r0, r0, #0x00800000
+ RET
+
+ @ At least one of r0/r1 is INF/NAN.
+ @ if r0 != INF/NAN: return r1 (which is INF/NAN)
+ @ if r1 != INF/NAN: return r0 (which is INF/NAN)
+ @ if r0 or r1 is NAN: return NAN
+ @ if opposite sign: return NAN
+ @ return r0 (which is INF or -INF)
+LSYM(Lad_i):
+ teq r2, ip, lsr #1
+ movne r0, r1
+ teqeq r3, ip, lsr #1
+ RETc(ne)
+ movs r2, r0, lsl #9
+ moveqs r2, r1, lsl #9
+ teqeq r0, r1
+ orrne r0, r3, #0x00400000 @ NAN
+ RET
+
+ FUNC_END addsf3
+ FUNC_END subsf3
+
+ARM_FUNC_START floatunsisf
+ mov r3, #0
+ b 1f
+
+ARM_FUNC_START floatsisf
+ ands r3, r0, #0x80000000
+ rsbmi r0, r0, #0
+
+1: teq r0, #0
+ RETc(eq)
+
+ mov r1, #0
+ mov r2, #((127 + 23) << 23)
+ tst r0, #0xfc000000
+ beq LSYM(Lad_p)
+
+ @ We need to scale the value a little before branching to code above.
+ tst r0, #0xf0000000
+ movne r1, r0, lsl #28
+ movne r0, r0, lsr #4
+ addne r2, r2, #(4 << 23)
+ tst r0, #0x0c000000
+ beq LSYM(Lad_p)
+ mov r1, r1, lsr #2
+ orr r1, r1, r0, lsl #30
+ mov r0, r0, lsr #2
+ add r2, r2, #(2 << 23)
+ b LSYM(Lad_p)
+
+ FUNC_END floatsisf
+ FUNC_END floatunsisf
+
+#endif /* L_addsubsf3 */
+
+#ifdef L_muldivsf3
+
+ARM_FUNC_START mulsf3
+
+ @ Mask out exponents.
+ mov ip, #0xff000000
+ and r2, r0, ip, lsr #1
+ and r3, r1, ip, lsr #1
+
+ @ Trap any INF/NAN.
+ teq r2, ip, lsr #1
+ teqne r3, ip, lsr #1
+ beq LSYM(Lml_s)
+
+ @ Trap any multiplication by 0.
+ bics ip, r0, #0x80000000
+ bicnes ip, r1, #0x80000000
+ beq LSYM(Lml_z)
+
+ @ Shift exponents right one bit to make room for overflow bit.
+ @ If either of them is 0, scale denormalized arguments off line.
+ @ Then add both exponents together.
+ movs r2, r2, lsr #1
+ teqne r3, #0
+ beq LSYM(Lml_d)
+LSYM(Lml_x):
+ add r2, r2, r3, asr #1
+
+ @ Preserve final sign in r2 along with exponent for now.
+ teq r0, r1
+ orrmi r2, r2, #0x8000
+
+ @ Convert mantissa to unsigned integer.
+ bic r0, r0, #0xff000000
+ bic r1, r1, #0xff000000
+ orr r0, r0, #0x00800000
+ orr r1, r1, #0x00800000
+
+#if __ARM_ARCH__ < 4
+
+ @ Well, no way to make it shorter without the umull instruction.
+ @ We must perform that 24 x 24 -> 48 bit multiplication by hand.
+ stmfd sp!, {r4, r5}
+ mov r4, r0, lsr #16
+ mov r5, r1, lsr #16
+ bic r0, r0, #0x00ff0000
+ bic r1, r1, #0x00ff0000
+ mul ip, r4, r5
+ mul r3, r0, r1
+ mul r0, r5, r0
+ mla r0, r4, r1, r0
+ adds r3, r3, r0, lsl #16
+ adc ip, ip, r0, lsr #16
+ ldmfd sp!, {r4, r5}
+
+#else
+
+ umull r3, ip, r0, r1 @ The actual multiplication.
+
+#endif
+
+ @ Put final sign in r0.
+ mov r0, r2, lsl #16
+ bic r2, r2, #0x8000
+
+ @ Adjust result if one extra MSB appeared.
+ @ The LSB may be lost but this never changes the result in this case.
+ tst ip, #(1 << 15)
+ addne r2, r2, #(1 << 22)
+ movnes ip, ip, lsr #1
+ movne r3, r3, rrx
+
+ @ Apply exponent bias, check range for underflow.
+ subs r2, r2, #(127 << 22)
+ ble LSYM(Lml_u)
+
+ @ Scale back to 24 bits with rounding.
+ @ r0 contains sign bit already.
+ orrs r0, r0, r3, lsr #23
+ adc r0, r0, ip, lsl #9
+
+ @ If halfway between two numbers, rounding should be towards LSB = 0.
+ mov r3, r3, lsl #9
+ teq r3, #0x80000000
+ biceq r0, r0, #1
+
+ @ Note: rounding may have produced an extra MSB here.
+ @ The extra bit is cleared before merging the exponent below.
+ tst r0, #0x01000000
+ addne r2, r2, #(1 << 22)
+
+ @ Check for exponent overflow
+ cmp r2, #(255 << 22)
+ bge LSYM(Lml_o)
+
+ @ Add final exponent.
+ bic r0, r0, #0x01800000
+ orr r0, r0, r2, lsl #1
+ RET
+
+ @ Result is 0, but determine sign anyway.
+LSYM(Lml_z):
+ eor r0, r0, r1
+ bic r0, r0, #0x7fffffff
+ RET
+
+ @ Check if denormalized result is possible, otherwise return signed 0.
+LSYM(Lml_u):
+ cmn r2, #(24 << 22)
+ RETc(le)
+
+ @ Find out proper shift value.
+ mvn r1, r2, asr #22
+ subs r1, r1, #7
+ bgt LSYM(Lml_ur)
+
+ @ Shift value left, round, etc.
+ add r1, r1, #32
+ orrs r0, r0, r3, lsr r1
+ rsb r1, r1, #32
+ adc r0, r0, ip, lsl r1
+ mov ip, r3, lsl r1
+ teq ip, #0x80000000
+ biceq r0, r0, #1
+ RET
+
+ @ Shift value right, round, etc.
+ @ Note: r1 must not be 0 otherwise carry does not get set.
+LSYM(Lml_ur):
+ orrs r0, r0, ip, lsr r1
+ adc r0, r0, #0
+ rsb r1, r1, #32
+ mov ip, ip, lsl r1
+ teq r3, #0
+ teqeq ip, #0x80000000
+ biceq r0, r0, #1
+ RET
+
+ @ One or both arguments are denormalized.
+ @ Scale them leftwards and preserve sign bit.
+LSYM(Lml_d):
+ teq r2, #0
+ and ip, r0, #0x80000000
+1: moveq r0, r0, lsl #1
+ tsteq r0, #0x00800000
+ subeq r2, r2, #(1 << 22)
+ beq 1b
+ orr r0, r0, ip
+ teq r3, #0
+ and ip, r1, #0x80000000
+2: moveq r1, r1, lsl #1
+ tsteq r1, #0x00800000
+ subeq r3, r3, #(1 << 23)
+ beq 2b
+ orr r1, r1, ip
+ b LSYM(Lml_x)
+
+ @ One or both args are INF or NAN.
+LSYM(Lml_s):
+ teq r0, #0x0
+ teqne r1, #0x0
+ teqne r0, #0x80000000
+ teqne r1, #0x80000000
+ beq LSYM(Lml_n) @ 0 * INF or INF * 0 -> NAN
+ teq r2, ip, lsr #1
+ bne 1f
+ movs r2, r0, lsl #9
+ bne LSYM(Lml_n) @ NAN * <anything> -> NAN
+1: teq r3, ip, lsr #1
+ bne LSYM(Lml_i)
+ movs r3, r1, lsl #9
+ bne LSYM(Lml_n) @ <anything> * NAN -> NAN
+
+ @ Result is INF, but we need to determine its sign.
+LSYM(Lml_i):
+ eor r0, r0, r1
+
+ @ Overflow: return INF (sign already in r0).
+LSYM(Lml_o):
+ and r0, r0, #0x80000000
+ orr r0, r0, #0x7f000000
+ orr r0, r0, #0x00800000
+ RET
+
+ @ Return NAN.
+LSYM(Lml_n):
+ mov r0, #0x7f000000
+ orr r0, r0, #0x00c00000
+ RET
+
+ FUNC_END mulsf3
+
+ARM_FUNC_START divsf3
+
+ @ Mask out exponents.
+ mov ip, #0xff000000
+ and r2, r0, ip, lsr #1
+ and r3, r1, ip, lsr #1
+
+ @ Trap any INF/NAN or zeroes.
+ teq r2, ip, lsr #1
+ teqne r3, ip, lsr #1
+ bicnes ip, r0, #0x80000000
+ bicnes ip, r1, #0x80000000
+ beq LSYM(Ldv_s)
+
+ @ Shift exponents right one bit to make room for overflow bit.
+ @ If either of them is 0, scale denormalized arguments off line.
+ @ Then substract divisor exponent from dividend''s.
+ movs r2, r2, lsr #1
+ teqne r3, #0
+ beq LSYM(Ldv_d)
+LSYM(Ldv_x):
+ sub r2, r2, r3, asr #1
+
+ @ Preserve final sign into ip.
+ eor ip, r0, r1
+
+ @ Convert mantissa to unsigned integer.
+ @ Dividend -> r3, divisor -> r1.
+ mov r3, #0x10000000
+ movs r1, r1, lsl #9
+ mov r0, r0, lsl #9
+ beq LSYM(Ldv_1)
+ orr r1, r3, r1, lsr #4
+ orr r3, r3, r0, lsr #4
+
+ @ Initialize r0 (result) with final sign bit.
+ and r0, ip, #0x80000000
+
+ @ Ensure result will land to known bit position.
+ cmp r3, r1
+ subcc r2, r2, #(1 << 22)
+ movcc r3, r3, lsl #1
+
+ @ Apply exponent bias, check range for over/underflow.
+ add r2, r2, #(127 << 22)
+ cmn r2, #(24 << 22)
+ RETc(le)
+ cmp r2, #(255 << 22)
+ bge LSYM(Lml_o)
+
+ @ The actual division loop.
+ mov ip, #0x00800000
+1: cmp r3, r1
+ subcs r3, r3, r1
+ orrcs r0, r0, ip
+ cmp r3, r1, lsr #1
+ subcs r3, r3, r1, lsr #1
+ orrcs r0, r0, ip, lsr #1
+ cmp r3, r1, lsr #2
+ subcs r3, r3, r1, lsr #2
+ orrcs r0, r0, ip, lsr #2
+ cmp r3, r1, lsr #3
+ subcs r3, r3, r1, lsr #3
+ orrcs r0, r0, ip, lsr #3
+ movs r3, r3, lsl #4
+ movnes ip, ip, lsr #4
+ bne 1b
+
+ @ Check if denormalized result is needed.
+ cmp r2, #0
+ ble LSYM(Ldv_u)
+
+ @ Apply proper rounding.
+ cmp r3, r1
+ addcs r0, r0, #1
+ biceq r0, r0, #1
+
+ @ Add exponent to result.
+ bic r0, r0, #0x00800000
+ orr r0, r0, r2, lsl #1
+ RET
+
+ @ Division by 0x1p*: let''s shortcut a lot of code.
+LSYM(Ldv_1):
+ and ip, ip, #0x80000000
+ orr r0, ip, r0, lsr #9
+ add r2, r2, #(127 << 22)
+ cmp r2, #(255 << 22)
+ bge LSYM(Lml_o)
+ cmp r2, #0
+ orrgt r0, r0, r2, lsl #1
+ RETc(gt)
+ cmn r2, #(24 << 22)
+ movle r0, ip
+ RETc(le)
+ orr r0, r0, #0x00800000
+ mov r3, #0
+
+ @ Result must be denormalized: prepare parameters to use code above.
+ @ r3 already contains remainder for rounding considerations.
+LSYM(Ldv_u):
+ bic ip, r0, #0x80000000
+ and r0, r0, #0x80000000
+ mvn r1, r2, asr #22
+ add r1, r1, #2
+ b LSYM(Lml_ur)
+
+ @ One or both arguments are denormalized.
+ @ Scale them leftwards and preserve sign bit.
+LSYM(Ldv_d):
+ teq r2, #0
+ and ip, r0, #0x80000000
+1: moveq r0, r0, lsl #1
+ tsteq r0, #0x00800000
+ subeq r2, r2, #(1 << 22)
+ beq 1b
+ orr r0, r0, ip
+ teq r3, #0
+ and ip, r1, #0x80000000
+2: moveq r1, r1, lsl #1
+ tsteq r1, #0x00800000
+ subeq r3, r3, #(1 << 23)
+ beq 2b
+ orr r1, r1, ip
+ b LSYM(Ldv_x)
+
+ @ One or both arguments is either INF, NAN or zero.
+LSYM(Ldv_s):
+ mov ip, #0xff000000
+ teq r2, ip, lsr #1
+ teqeq r3, ip, lsr #1
+ beq LSYM(Lml_n) @ INF/NAN / INF/NAN -> NAN
+ teq r2, ip, lsr #1
+ bne 1f
+ movs r2, r0, lsl #9
+ bne LSYM(Lml_n) @ NAN / <anything> -> NAN
+ b LSYM(Lml_i) @ INF / <anything> -> INF
+1: teq r3, ip, lsr #1
+ bne 2f
+ movs r3, r1, lsl #9
+ bne LSYM(Lml_n) @ <anything> / NAN -> NAN
+ b LSYM(Lml_z) @ <anything> / INF -> 0
+2: @ One or both arguments are 0.
+ bics r2, r0, #0x80000000
+ bne LSYM(Lml_i) @ <non_zero> / 0 -> INF
+ bics r3, r1, #0x80000000
+ bne LSYM(Lml_z) @ 0 / <non_zero> -> 0
+ b LSYM(Lml_n) @ 0 / 0 -> NAN
+
+ FUNC_END divsf3
+
+#endif /* L_muldivsf3 */
+
+#ifdef L_cmpsf2
+
+ARM_FUNC_START gtsf2
+ARM_FUNC_ALIAS gesf2 gtsf2
+ mov r3, #-1
+ b 1f
+
+ARM_FUNC_START ltsf2
+ARM_FUNC_ALIAS lesf2 ltsf2
+ mov r3, #1
+ b 1f
+
+ARM_FUNC_START cmpsf2
+ARM_FUNC_ALIAS nesf2 cmpsf2
+ARM_FUNC_ALIAS eqsf2 cmpsf2
+ mov r3, #1 @ how should we specify unordered here?
+
+1: @ Trap any INF/NAN first.
+ mov ip, #0xff000000
+ and r2, r1, ip, lsr #1
+ teq r2, ip, lsr #1
+ and r2, r0, ip, lsr #1
+ teqne r2, ip, lsr #1
+ beq 3f
+
+ @ Test for equality.
+ @ Note that 0.0 is equal to -0.0.
+2: orr r3, r0, r1
+ bics r3, r3, #0x80000000 @ either 0.0 or -0.0
+ teqne r0, r1 @ or both the same
+ moveq r0, #0
+ RETc(eq)
+
+ @ Check for sign difference. The N flag is set if it is the case.
+ @ If so, return sign of r0.
+ movmi r0, r0, asr #31
+ orrmi r0, r0, #1
+ RETc(mi)
+
+ @ Compare exponents.
+ and r3, r1, ip, lsr #1
+ cmp r2, r3
+
+ @ Compare mantissa if exponents are equal
+ moveq r0, r0, lsl #9
+ cmpeq r0, r1, lsl #9
+ movcs r0, r1, asr #31
+ mvncc r0, r1, asr #31
+ orr r0, r0, #1
+ RET
+
+ @ Look for a NAN.
+3: and r2, r1, ip, lsr #1
+ teq r2, ip, lsr #1
+ bne 4f
+ movs r2, r1, lsl #9
+ bne 5f @ r1 is NAN
+4: and r2, r0, ip, lsr #1
+ teq r2, ip, lsr #1
+ bne 2b
+ movs ip, r0, lsl #9
+ beq 2b @ r0 is not NAN
+5: mov r0, r3 @ return unordered code from r3.
+ RET
+
+ FUNC_END gesf2
+ FUNC_END gtsf2
+ FUNC_END lesf2
+ FUNC_END ltsf2
+ FUNC_END nesf2
+ FUNC_END eqsf2
+ FUNC_END cmpsf2
+
+#endif /* L_cmpsf2 */
+
+#ifdef L_unordsf2
+
+ARM_FUNC_START unordsf2
+ mov ip, #0xff000000
+ and r2, r1, ip, lsr #1
+ teq r2, ip, lsr #1
+ bne 1f
+ movs r2, r1, lsl #9
+ bne 3f @ r1 is NAN
+1: and r2, r0, ip, lsr #1
+ teq r2, ip, lsr #1
+ bne 2f
+ movs r2, r0, lsl #9
+ bne 3f @ r0 is NAN
+2: mov r0, #0 @ arguments are ordered.
+ RET
+3: mov r0, #1 @ arguments are unordered.
+ RET
+
+ FUNC_END unordsf2
+
+#endif /* L_unordsf2 */
+
+#ifdef L_fixsfsi
+
+ARM_FUNC_START fixsfsi
+ movs r0, r0, lsl #1
+ RETc(eq) @ value is 0.
+
+ mov r1, r1, rrx @ preserve C flag (the actual sign)
+
+ @ check exponent range.
+ and r2, r0, #0xff000000
+ cmp r2, #(127 << 24)
+ movcc r0, #0 @ value is too small
+ RETc(cc)
+ cmp r2, #((127 + 31) << 24)
+ bcs 1f @ value is too large
+
+ mov r0, r0, lsl #7
+ orr r0, r0, #0x80000000
+ mov r2, r2, lsr #24
+ rsb r2, r2, #(127 + 31)
+ tst r1, #0x80000000 @ the sign bit
+ mov r0, r0, lsr r2
+ rsbne r0, r0, #0
+ RET
+
+1: teq r2, #0xff000000
+ bne 2f
+ movs r0, r0, lsl #8
+ bne 3f @ r0 is NAN.
+2: ands r0, r1, #0x80000000 @ the sign bit
+ moveq r0, #0x7fffffff @ the maximum signed positive si
+ RET
+
+3: mov r0, #0 @ What should we convert NAN to?
+ RET
+
+ FUNC_END fixsfsi
+
+#endif /* L_fixsfsi */
+
+#ifdef L_fixunssfsi
+
+ARM_FUNC_START fixunssfsi
+ movs r0, r0, lsl #1
+ movcss r0, #0 @ value is negative...
+ RETc(eq) @ ... or 0.
+
+
+ @ check exponent range.
+ and r2, r0, #0xff000000
+ cmp r2, #(127 << 24)
+ movcc r0, #0 @ value is too small
+ RETc(cc)
+ cmp r2, #((127 + 32) << 24)
+ bcs 1f @ value is too large
+
+ mov r0, r0, lsl #7
+ orr r0, r0, #0x80000000
+ mov r2, r2, lsr #24
+ rsb r2, r2, #(127 + 31)
+ mov r0, r0, lsr r2
+ RET
+
+1: teq r2, #0xff000000
+ bne 2f
+ movs r0, r0, lsl #8
+ bne 3f @ r0 is NAN.
+2: mov r0, #0xffffffff @ maximum unsigned si
+ RET
+
+3: mov r0, #0 @ What should we convert NAN to?
+ RET
+
+ FUNC_END fixunssfsi
+
+#endif /* L_fixunssfsi */
diff --git a/contrib/gcc/config/arm/iwmmxt.md b/contrib/gcc/config/arm/iwmmxt.md
new file mode 100644
index 000000000000..f8070a885947
--- /dev/null
+++ b/contrib/gcc/config/arm/iwmmxt.md
@@ -0,0 +1,1524 @@
+;; Patterns for the Intel Wireless MMX technology architecture.
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Contributed by Red Hat.
+
+;; 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 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+(define_insn "iwmmxt_iordi3"
+ [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
+ (ior:DI (match_operand:DI 1 "register_operand" "%y,0,r")
+ (match_operand:DI 2 "register_operand" "y,r,r")))]
+ "TARGET_REALLY_IWMMXT"
+ "@
+ wor%?\\t%0, %1, %2
+ #
+ #"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4,8,8")])
+
+(define_insn "iwmmxt_xordi3"
+ [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
+ (xor:DI (match_operand:DI 1 "register_operand" "%y,0,r")
+ (match_operand:DI 2 "register_operand" "y,r,r")))]
+ "TARGET_REALLY_IWMMXT"
+ "@
+ wxor%?\\t%0, %1, %2
+ #
+ #"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4,8,8")])
+
+(define_insn "iwmmxt_anddi3"
+ [(set (match_operand:DI 0 "register_operand" "=y,?&r,?&r")
+ (and:DI (match_operand:DI 1 "register_operand" "%y,0,r")
+ (match_operand:DI 2 "register_operand" "y,r,r")))]
+ "TARGET_REALLY_IWMMXT"
+ "@
+ wand%?\\t%0, %1, %2
+ #
+ #"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4,8,8")])
+
+(define_insn "iwmmxt_nanddi3"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (and:DI (match_operand:DI 1 "register_operand" "y")
+ (not:DI (match_operand:DI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wandn%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "*iwmmxt_arm_movdi"
+ [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>,y,y,yr,y,yrm")
+ (match_operand:DI 1 "di_operand" "rIK,mi,r ,y,yr,y,yrm,y"))]
+ "TARGET_REALLY_IWMMXT"
+ "*
+{
+ switch (which_alternative)
+ {
+ default:
+ return output_move_double (operands);
+ case 3:
+ return \"wmov%?\\t%0,%1\";
+ case 4:
+ return \"tmcrr%?\\t%0,%Q1,%R1\";
+ case 5:
+ return \"tmrrc%?\\t%Q0,%R0,%1\";
+ case 6:
+ return \"wldrd%?\\t%0,%1\";
+ case 7:
+ return \"wstrd%?\\t%1,%0\";
+ }
+}"
+ [(set_attr "length" "8,8,8,4,4,4,4,4")
+ (set_attr "type" "*,load,store2,*,*,*,*,*")
+ (set_attr "pool_range" "*,1020,*,*,*,*,*,*")
+ (set_attr "neg_pool_range" "*,1012,*,*,*,*,*,*")]
+)
+
+(define_insn "*iwmmxt_movsi_insn"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,z,r,?z,m,z")
+ (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,z,m,z,z"))]
+ "TARGET_REALLY_IWMMXT
+ && ( register_operand (operands[0], SImode)
+ || register_operand (operands[1], SImode))"
+ "*
+ switch (which_alternative)
+ {
+ case 0: return \"mov\\t%0, %1\";
+ case 1: return \"mvn\\t%0, #%B1\";
+ case 2: return \"ldr\\t%0, %1\";
+ case 3: return \"str\\t%1, %0\";
+ case 4: return \"tmcr\\t%0, %1\";
+ case 5: return \"tmrc\\t%0, %1\";
+ case 6: return arm_output_load_gr (operands);
+ case 7: return \"wstrw\\t%1, %0\";
+ default:return \"wstrw\\t%1, [sp, #-4]!\;wldrw\\t%0, [sp], #4\\t@move CG reg\";
+ }"
+ [(set_attr "type" "*,*,load,store1,*,*,load,store1,*")
+ (set_attr "length" "*,*,*, *,*,*, 16, *,8")
+ (set_attr "pool_range" "*,*,4096, *,*,*,1024, *,*")
+ (set_attr "neg_pool_range" "*,*,4084, *,*,*, *, 1012,*")
+ ;; Note - the "predicable" attribute is not allowed to have alternatives.
+ ;; Since the wSTRw wCx instruction is not predicable, we cannot support
+ ;; predicating any of the alternatives in this template. Instead,
+ ;; we do the predication ourselves, in cond_iwmmxt_movsi_insn.
+ (set_attr "predicable" "no")
+ ;; Also - we have to pretend that these insns clobber the condition code
+ ;; bits as otherwise arm_final_prescan_insn() will try to conditionalize
+ ;; them.
+ (set_attr "conds" "clob")]
+)
+
+;; Because iwmmxt_movsi_insn is not predicable, we provide the
+;; cond_exec version explicitly, with appropriate constraints.
+
+(define_insn "*cond_iwmmxt_movsi_insn"
+ [(cond_exec
+ (match_operator 2 "arm_comparison_operator"
+ [(match_operand 3 "cc_register" "")
+ (const_int 0)])
+ (set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m,z,r")
+ (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,z")))]
+ "TARGET_REALLY_IWMMXT
+ && ( register_operand (operands[0], SImode)
+ || register_operand (operands[1], SImode))"
+ "*
+ switch (which_alternative)
+ {
+ case 0: return \"mov%?\\t%0, %1\";
+ case 1: return \"mvn%?\\t%0, #%B1\";
+ case 2: return \"ldr%?\\t%0, %1\";
+ case 3: return \"str%?\\t%1, %0\";
+ case 4: return \"tmcr%?\\t%0, %1\";
+ default: return \"tmrc%?\\t%0, %1\";
+ }"
+ [(set_attr "type" "*,*,load,store1,*,*")
+ (set_attr "pool_range" "*,*,4096, *,*,*")
+ (set_attr "neg_pool_range" "*,*,4084, *,*,*")]
+)
+
+(define_insn "movv8qi_internal"
+ [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r")
+ (match_operand:V8QI 1 "general_operand" "y,y,m,y,r,i"))]
+ "TARGET_REALLY_IWMMXT"
+ "*
+ switch (which_alternative)
+ {
+ case 0: return \"wmov%?\\t%0, %1\";
+ case 1: return \"wstrd%?\\t%1, %0\";
+ case 2: return \"wldrd%?\\t%0, %1\";
+ case 3: return \"tmrrc%?\\t%Q0, %R0, %1\";
+ case 4: return \"tmcrr%?\\t%0, %Q1, %R1\";
+ default: return output_move_double (operands);
+ }"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4, 4, 4,4,4, 8")
+ (set_attr "type" "*,store1,load,*,*,load")
+ (set_attr "pool_range" "*, *, 256,*,*, 256")
+ (set_attr "neg_pool_range" "*, *, 244,*,*, 244")])
+
+(define_insn "movv4hi_internal"
+ [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r")
+ (match_operand:V4HI 1 "general_operand" "y,y,m,y,r,i"))]
+ "TARGET_REALLY_IWMMXT"
+ "*
+ switch (which_alternative)
+ {
+ case 0: return \"wmov%?\\t%0, %1\";
+ case 1: return \"wstrd%?\\t%1, %0\";
+ case 2: return \"wldrd%?\\t%0, %1\";
+ case 3: return \"tmrrc%?\\t%Q0, %R0, %1\";
+ case 4: return \"tmcrr%?\\t%0, %Q1, %R1\";
+ default: return output_move_double (operands);
+ }"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4, 4, 4,4,4, 8")
+ (set_attr "type" "*,store1,load,*,*,load")
+ (set_attr "pool_range" "*, *, 256,*,*, 256")
+ (set_attr "neg_pool_range" "*, *, 244,*,*, 244")])
+
+(define_insn "movv2si_internal"
+ [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,m,y,?r,?y,?r")
+ (match_operand:V2SI 1 "general_operand" "y,y,m,y,r,i"))]
+ "TARGET_REALLY_IWMMXT"
+ "*
+ switch (which_alternative)
+ {
+ case 0: return \"wmov%?\\t%0, %1\";
+ case 1: return \"wstrd%?\\t%1, %0\";
+ case 2: return \"wldrd%?\\t%0, %1\";
+ case 3: return \"tmrrc%?\\t%Q0, %R0, %1\";
+ case 4: return \"tmcrr%?\\t%0, %Q1, %R1\";
+ default: return output_move_double (operands);
+ }"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "4, 4, 4,4,4, 24")
+ (set_attr "type" "*,store1,load,*,*,load")
+ (set_attr "pool_range" "*, *, 256,*,*, 256")
+ (set_attr "neg_pool_range" "*, *, 244,*,*, 244")])
+
+;; This pattern should not be needed. It is to match a
+;; wierd case generated by GCC when no optimizations are
+;; enabled. (Try compiling gcc/testsuite/gcc.c-torture/
+;; compile/simd-5.c at -O0). The mode for operands[1] is
+;; deliberately omitted.
+(define_insn "movv2si_internal_2"
+ [(set (match_operand:V2SI 0 "nonimmediate_operand" "=?r")
+ (match_operand 1 "immediate_operand" "i"))]
+ "TARGET_REALLY_IWMMXT"
+ "* return output_move_double (operands);"
+ [(set_attr "predicable" "yes")
+ (set_attr "length" "8")
+ (set_attr "type" "load")
+ (set_attr "pool_range" "256")
+ (set_attr "neg_pool_range" "244")])
+
+;; Vector add/subtract
+
+(define_insn "addv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (plus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "addv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (plus:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "addv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (plus:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ssaddv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddbss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ssaddv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddhss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ssaddv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (ss_plus:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddwss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "usaddv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddbus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "usaddv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddhus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "usaddv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (us_plus:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "waddwus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "subv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (minus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "subv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (minus:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "subv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (minus:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "sssubv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubbss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "sssubv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubhss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "sssubv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (ss_minus:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubwss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ussubv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubbus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ussubv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubhus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ussubv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (us_minus:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsubwus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "mulv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (mult:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmulul%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "smulv4hi3_highpart"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (truncate:V4HI
+ (lshiftrt:V4SI
+ (mult:V4SI (sign_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+ (sign_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")))
+ (const_int 16))))]
+ "TARGET_REALLY_IWMMXT"
+ "wmulsm%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "umulv4hi3_highpart"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (truncate:V4HI
+ (lshiftrt:V4SI
+ (mult:V4SI (zero_extend:V4SI (match_operand:V4HI 1 "register_operand" "y"))
+ (zero_extend:V4SI (match_operand:V4HI 2 "register_operand" "y")))
+ (const_int 16))))]
+ "TARGET_REALLY_IWMMXT"
+ "wmulum%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wmacs"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "0")
+ (match_operand:V4HI 2 "register_operand" "y")
+ (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WMACS))]
+ "TARGET_REALLY_IWMMXT"
+ "wmacs%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wmacsz"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMACSZ))]
+ "TARGET_REALLY_IWMMXT"
+ "wmacsz%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wmacu"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "0")
+ (match_operand:V4HI 2 "register_operand" "y")
+ (match_operand:V4HI 3 "register_operand" "y")] UNSPEC_WMACU))]
+ "TARGET_REALLY_IWMMXT"
+ "wmacu%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wmacuz"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMACUZ))]
+ "TARGET_REALLY_IWMMXT"
+ "wmacuz%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+;; Same as xordi3, but don't show input operands so that we don't think
+;; they are live.
+(define_insn "iwmmxt_clrdi"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(const_int 0)] UNSPEC_CLRDI))]
+ "TARGET_REALLY_IWMMXT"
+ "wxor%?\\t%0, %0, %0"
+ [(set_attr "predicable" "yes")])
+
+;; Seems like cse likes to generate these, so we have to support them.
+
+(define_insn "*iwmmxt_clrv8qi"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (const_vector:V8QI [(const_int 0) (const_int 0)
+ (const_int 0) (const_int 0)
+ (const_int 0) (const_int 0)
+ (const_int 0) (const_int 0)]))]
+ "TARGET_REALLY_IWMMXT"
+ "wxor%?\\t%0, %0, %0"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "*iwmmxt_clrv4hi"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (const_vector:V4HI [(const_int 0) (const_int 0)
+ (const_int 0) (const_int 0)]))]
+ "TARGET_REALLY_IWMMXT"
+ "wxor%?\\t%0, %0, %0"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "*iwmmxt_clrv2si"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (const_vector:V2SI [(const_int 0) (const_int 0)]))]
+ "TARGET_REALLY_IWMMXT"
+ "wxor%?\\t%0, %0, %0"
+ [(set_attr "predicable" "yes")])
+
+;; Unsigned averages/sum of absolute differences
+
+(define_insn "iwmmxt_uavgrndv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (ashiftrt:V8QI
+ (plus:V8QI (plus:V8QI
+ (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y"))
+ (const_vector:V8QI [(const_int 1)
+ (const_int 1)
+ (const_int 1)
+ (const_int 1)
+ (const_int 1)
+ (const_int 1)
+ (const_int 1)
+ (const_int 1)]))
+ (const_int 1)))]
+ "TARGET_REALLY_IWMMXT"
+ "wavg2br%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_uavgrndv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ashiftrt:V4HI
+ (plus:V4HI (plus:V4HI
+ (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y"))
+ (const_vector:V4HI [(const_int 1)
+ (const_int 1)
+ (const_int 1)
+ (const_int 1)]))
+ (const_int 1)))]
+ "TARGET_REALLY_IWMMXT"
+ "wavg2hr%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+
+(define_insn "iwmmxt_uavgv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (ashiftrt:V8QI (plus:V8QI
+ (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y"))
+ (const_int 1)))]
+ "TARGET_REALLY_IWMMXT"
+ "wavg2b%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_uavgv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ashiftrt:V4HI (plus:V4HI
+ (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y"))
+ (const_int 1)))]
+ "TARGET_REALLY_IWMMXT"
+ "wavg2h%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_psadbw"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (abs:V8QI (minus:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "psadbw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+
+;; Insert/extract/shuffle
+
+(define_insn "iwmmxt_tinsrb"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (vec_merge:V8QI (match_operand:V8QI 1 "register_operand" "0")
+ (vec_duplicate:V8QI
+ (truncate:QI (match_operand:SI 2 "nonimmediate_operand" "r")))
+ (match_operand:SI 3 "immediate_operand" "i")))]
+ "TARGET_REALLY_IWMMXT"
+ "tinsrb%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tinsrh"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
+ (vec_duplicate:V4HI
+ (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "r")))
+ (match_operand:SI 3 "immediate_operand" "i")))]
+ "TARGET_REALLY_IWMMXT"
+ "tinsrh%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tinsrw"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (vec_merge:V2SI (match_operand:V2SI 1 "register_operand" "0")
+ (vec_duplicate:V2SI
+ (match_operand:SI 2 "nonimmediate_operand" "r"))
+ (match_operand:SI 3 "immediate_operand" "i")))]
+ "TARGET_REALLY_IWMMXT"
+ "tinsrw%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_textrmub"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (vec_select:QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel
+ [(match_operand:SI 2 "immediate_operand" "i")]))))]
+ "TARGET_REALLY_IWMMXT"
+ "textrmub%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_textrmsb"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (vec_select:QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel
+ [(match_operand:SI 2 "immediate_operand" "i")]))))]
+ "TARGET_REALLY_IWMMXT"
+ "textrmsb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_textrmuh"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel
+ [(match_operand:SI 2 "immediate_operand" "i")]))))]
+ "TARGET_REALLY_IWMMXT"
+ "textrmuh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_textrmsh"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel
+ [(match_operand:SI 2 "immediate_operand" "i")]))))]
+ "TARGET_REALLY_IWMMXT"
+ "textrmsh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+;; There are signed/unsigned variants of this instruction, but they are
+;; pointless.
+(define_insn "iwmmxt_textrmw"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
+ "TARGET_REALLY_IWMMXT"
+ "textrmsw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wshufh"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:SI 2 "immediate_operand" "i")] UNSPEC_WSHUFH))]
+ "TARGET_REALLY_IWMMXT"
+ "wshufh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+;; Mask-generating comparisons
+;;
+;; Note - you cannot use patterns like these here:
+;;
+;; (set:<vector> (match:<vector>) (<comparator>:<vector> (match:<vector>) (match:<vector>)))
+;;
+;; Because GCC will assume that the truth value (1 or 0) is installed
+;; into the entire destination vector, (with the '1' going into the least
+;; significant element of the vector). This is not how these instructions
+;; behave.
+;;
+;; Unfortunately the current patterns are illegal. They are SET insns
+;; without a SET in them. They work in most cases for ordinary code
+;; generation, but there are circumstances where they can cause gcc to fail.
+;; XXX - FIXME.
+
+(define_insn "eqv8qi3"
+ [(unspec_volatile [(match_operand:V8QI 0 "register_operand" "=y")
+ (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_EQ)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpeqb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "eqv4hi3"
+ [(unspec_volatile [(match_operand:V4HI 0 "register_operand" "=y")
+ (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_EQ)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpeqh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "eqv2si3"
+ [(unspec_volatile:V2SI [(match_operand:V2SI 0 "register_operand" "=y")
+ (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_EQ)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpeqw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "gtuv8qi3"
+ [(unspec_volatile [(match_operand:V8QI 0 "register_operand" "=y")
+ (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_GTU)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpgtub%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "gtuv4hi3"
+ [(unspec_volatile [(match_operand:V4HI 0 "register_operand" "=y")
+ (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_GTU)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpgtuh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "gtuv2si3"
+ [(unspec_volatile [(match_operand:V2SI 0 "register_operand" "=y")
+ (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_GTU)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpgtuw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "gtv8qi3"
+ [(unspec_volatile [(match_operand:V8QI 0 "register_operand" "=y")
+ (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_GT)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpgtsb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "gtv4hi3"
+ [(unspec_volatile [(match_operand:V4HI 0 "register_operand" "=y")
+ (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_GT)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpgtsh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "gtv2si3"
+ [(unspec_volatile [(match_operand:V2SI 0 "register_operand" "=y")
+ (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")]
+ VUNSPEC_WCMP_GT)]
+ "TARGET_REALLY_IWMMXT"
+ "wcmpgtsw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+;; Max/min insns
+
+(define_insn "smaxv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (smax:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaxsb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "umaxv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (umax:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaxub%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "smaxv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (smax:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaxsh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "umaxv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (umax:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaxuh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "smaxv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (smax:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaxsw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "umaxv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (umax:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaxuw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "sminv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (smin:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wminsb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "uminv8qi3"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (umin:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wminub%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "sminv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (smin:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wminsh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "uminv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (umin:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wminuh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "sminv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (smin:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wminsw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "uminv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (umin:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:V2SI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wminuw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+;; Pack/unpack insns.
+
+(define_insn "iwmmxt_wpackhss"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (vec_concat:V8QI
+ (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "y"))
+ (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wpackhss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wpackwss"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (vec_concat:V4HI
+ (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "y"))
+ (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wpackwss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wpackdss"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (vec_concat:V2SI
+ (ss_truncate:SI (match_operand:DI 1 "register_operand" "y"))
+ (ss_truncate:SI (match_operand:DI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wpackdss%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wpackhus"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (vec_concat:V8QI
+ (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "y"))
+ (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wpackhus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wpackwus"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (vec_concat:V4HI
+ (us_truncate:V2HI (match_operand:V2SI 1 "register_operand" "y"))
+ (us_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wpackwus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wpackdus"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (vec_concat:V2SI
+ (us_truncate:SI (match_operand:DI 1 "register_operand" "y"))
+ (us_truncate:SI (match_operand:DI 2 "register_operand" "y"))))]
+ "TARGET_REALLY_IWMMXT"
+ "wpackdus%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+
+(define_insn "iwmmxt_wunpckihb"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (vec_merge:V8QI
+ (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel [(const_int 4)
+ (const_int 0)
+ (const_int 5)
+ (const_int 1)
+ (const_int 6)
+ (const_int 2)
+ (const_int 7)
+ (const_int 3)]))
+ (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
+ (parallel [(const_int 0)
+ (const_int 4)
+ (const_int 1)
+ (const_int 5)
+ (const_int 2)
+ (const_int 6)
+ (const_int 3)
+ (const_int 7)]))
+ (const_int 85)))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckihb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckihh"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (vec_merge:V4HI
+ (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel [(const_int 0)
+ (const_int 2)
+ (const_int 1)
+ (const_int 3)]))
+ (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
+ (parallel [(const_int 2)
+ (const_int 0)
+ (const_int 3)
+ (const_int 1)]))
+ (const_int 5)))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckihh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckihw"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (vec_merge:V2SI
+ (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(const_int 0)
+ (const_int 1)]))
+ (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
+ (parallel [(const_int 1)
+ (const_int 0)]))
+ (const_int 1)))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckihw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckilb"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (vec_merge:V8QI
+ (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel [(const_int 0)
+ (const_int 4)
+ (const_int 1)
+ (const_int 5)
+ (const_int 2)
+ (const_int 6)
+ (const_int 3)
+ (const_int 7)]))
+ (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
+ (parallel [(const_int 4)
+ (const_int 0)
+ (const_int 5)
+ (const_int 1)
+ (const_int 6)
+ (const_int 2)
+ (const_int 7)
+ (const_int 3)]))
+ (const_int 85)))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckilb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckilh"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (vec_merge:V4HI
+ (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel [(const_int 2)
+ (const_int 0)
+ (const_int 3)
+ (const_int 1)]))
+ (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
+ (parallel [(const_int 0)
+ (const_int 2)
+ (const_int 1)
+ (const_int 3)]))
+ (const_int 5)))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckilh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckilw"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (vec_merge:V2SI
+ (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(const_int 1)
+ (const_int 0)]))
+ (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
+ (parallel [(const_int 0)
+ (const_int 1)]))
+ (const_int 1)))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckilw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckehub"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (zero_extend:V4HI
+ (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel [(const_int 4) (const_int 5)
+ (const_int 6) (const_int 7)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckehub%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckehuh"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (zero_extend:V2SI
+ (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel [(const_int 2) (const_int 3)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckehuh%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckehuw"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (zero_extend:DI
+ (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(const_int 1)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckehuw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckehsb"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (sign_extend:V4HI
+ (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel [(const_int 4) (const_int 5)
+ (const_int 6) (const_int 7)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckehsb%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckehsh"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (sign_extend:V2SI
+ (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel [(const_int 2) (const_int 3)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckehsh%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckehsw"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (sign_extend:DI
+ (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(const_int 1)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckehsw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckelub"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (zero_extend:V4HI
+ (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel [(const_int 0) (const_int 1)
+ (const_int 2) (const_int 3)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckelub%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckeluh"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (zero_extend:V2SI
+ (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel [(const_int 0) (const_int 1)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckeluh%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckeluw"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (zero_extend:DI
+ (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(const_int 0)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckeluw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckelsb"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (sign_extend:V4HI
+ (vec_select:V4QI (match_operand:V8QI 1 "register_operand" "y")
+ (parallel [(const_int 0) (const_int 1)
+ (const_int 2) (const_int 3)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckelsb%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckelsh"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (sign_extend:V2SI
+ (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "y")
+ (parallel [(const_int 0) (const_int 1)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckelsh%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wunpckelsw"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (sign_extend:DI
+ (vec_select:SI (match_operand:V2SI 1 "register_operand" "y")
+ (parallel [(const_int 0)]))))]
+ "TARGET_REALLY_IWMMXT"
+ "wunpckelsw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+;; Shifts
+
+(define_insn "rorv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (rotatert:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wrorhg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "rorv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (rotatert:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wrorwg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "rordi3"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (rotatert:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wrordg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashrv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrahg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashrv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrawg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashrdi3"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsradg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "lshrv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrlhg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "lshrv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrlwg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "lshrdi3"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrldg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashlv4hi3"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ashift:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsllhg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashlv2si3"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (ashift:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsllwg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashldi3_iwmmxt"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (ashift:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:SI 2 "register_operand" "z")))]
+ "TARGET_REALLY_IWMMXT"
+ "wslldg%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "rorv4hi3_di"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (rotatert:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wrorh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "rorv2si3_di"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (rotatert:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wrorw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "rordi3_di"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (rotatert:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wrord%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashrv4hi3_di"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrah%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashrv2si3_di"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsraw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashrdi3_di"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrad%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "lshrv4hi3_di"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrlh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "lshrv2si3_di"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrlw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "lshrdi3_di"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsrld%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashlv4hi3_di"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (ashift:V4HI (match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsllh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashlv2si3_di"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (ashift:V2SI (match_operand:V2SI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wsllw%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "ashldi3_di"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (ashift:DI (match_operand:DI 1 "register_operand" "y")
+ (match_operand:DI 2 "register_operand" "y")))]
+ "TARGET_REALLY_IWMMXT"
+ "wslld%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wmadds"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMADDS))]
+ "TARGET_REALLY_IWMMXT"
+ "wmadds%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wmaddu"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WMADDU))]
+ "TARGET_REALLY_IWMMXT"
+ "wmaddu%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmia"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (plus:DI (match_operand:DI 1 "register_operand" "0")
+ (mult:DI (sign_extend:DI
+ (match_operand:SI 2 "register_operand" "r"))
+ (sign_extend:DI
+ (match_operand:SI 3 "register_operand" "r")))))]
+ "TARGET_REALLY_IWMMXT"
+ "tmia%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmiaph"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (plus:DI (match_operand:DI 1 "register_operand" "0")
+ (plus:DI
+ (mult:DI (sign_extend:DI
+ (truncate:HI (match_operand:SI 2 "register_operand" "r")))
+ (sign_extend:DI
+ (truncate:HI (match_operand:SI 3 "register_operand" "r"))))
+ (mult:DI (sign_extend:DI
+ (truncate:HI (ashiftrt:SI (match_dup 2) (const_int 16))))
+ (sign_extend:DI
+ (truncate:HI (ashiftrt:SI (match_dup 3) (const_int 16))))))))]
+ "TARGET_REALLY_IWMMXT"
+ "tmiaph%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmiabb"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (plus:DI (match_operand:DI 1 "register_operand" "0")
+ (mult:DI (sign_extend:DI
+ (truncate:HI (match_operand:SI 2 "register_operand" "r")))
+ (sign_extend:DI
+ (truncate:HI (match_operand:SI 3 "register_operand" "r"))))))]
+ "TARGET_REALLY_IWMMXT"
+ "tmiabb%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmiatb"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (plus:DI (match_operand:DI 1 "register_operand" "0")
+ (mult:DI (sign_extend:DI
+ (truncate:HI (ashiftrt:SI
+ (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))))
+ (sign_extend:DI
+ (truncate:HI (match_operand:SI 3 "register_operand" "r"))))))]
+ "TARGET_REALLY_IWMMXT"
+ "tmiatb%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmiabt"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (plus:DI (match_operand:DI 1 "register_operand" "0")
+ (mult:DI (sign_extend:DI
+ (truncate:HI (match_operand:SI 2 "register_operand" "r")))
+ (sign_extend:DI
+ (truncate:HI (ashiftrt:SI
+ (match_operand:SI 3 "register_operand" "r")
+ (const_int 16)))))))]
+ "TARGET_REALLY_IWMMXT"
+ "tmiabt%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmiatt"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (plus:DI (match_operand:DI 1 "register_operand" "0")
+ (mult:DI (sign_extend:DI
+ (truncate:HI (ashiftrt:SI
+ (match_operand:SI 2 "register_operand" "r")
+ (const_int 16))))
+ (sign_extend:DI
+ (truncate:HI (ashiftrt:SI
+ (match_operand:SI 3 "register_operand" "r")
+ (const_int 16)))))))]
+ "TARGET_REALLY_IWMMXT"
+ "tmiatt%?\\t%0, %2, %3"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tbcstqi"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (vec_duplicate:V8QI (match_operand:QI 1 "register_operand" "r")))]
+ "TARGET_REALLY_IWMMXT"
+ "tbcstb%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tbcsthi"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (vec_duplicate:V4HI (match_operand:HI 1 "register_operand" "r")))]
+ "TARGET_REALLY_IWMMXT"
+ "tbcsth%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tbcstsi"
+ [(set (match_operand:V2SI 0 "register_operand" "=y")
+ (vec_duplicate:V2SI (match_operand:SI 1 "register_operand" "r")))]
+ "TARGET_REALLY_IWMMXT"
+ "tbcstw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmovmskb"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] UNSPEC_TMOVMSK))]
+ "TARGET_REALLY_IWMMXT"
+ "tmovmskb%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmovmskh"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:V4HI 1 "register_operand" "y")] UNSPEC_TMOVMSK))]
+ "TARGET_REALLY_IWMMXT"
+ "tmovmskh%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmovmskw"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:V2SI 1 "register_operand" "y")] UNSPEC_TMOVMSK))]
+ "TARGET_REALLY_IWMMXT"
+ "tmovmskw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_waccb"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:V8QI 1 "register_operand" "y")] UNSPEC_WACC))]
+ "TARGET_REALLY_IWMMXT"
+ "waccb%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wacch"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:V4HI 1 "register_operand" "y")] UNSPEC_WACC))]
+ "TARGET_REALLY_IWMMXT"
+ "wacch%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_waccw"
+ [(set (match_operand:DI 0 "register_operand" "=y")
+ (unspec:DI [(match_operand:V2SI 1 "register_operand" "y")] UNSPEC_WACC))]
+ "TARGET_REALLY_IWMMXT"
+ "waccw%?\\t%0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_walign"
+ [(set (match_operand:V8QI 0 "register_operand" "=y,y")
+ (subreg:V8QI (ashiftrt:TI
+ (subreg:TI (vec_concat:V16QI
+ (match_operand:V8QI 1 "register_operand" "y,y")
+ (match_operand:V8QI 2 "register_operand" "y,y")) 0)
+ (mult:SI
+ (match_operand:SI 3 "nonmemory_operand" "i,z")
+ (const_int 8))) 0))]
+ "TARGET_REALLY_IWMMXT"
+ "@
+ waligni%?\\t%0, %1, %2, %3
+ walignr%U3%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmrc"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "i")]
+ VUNSPEC_TMRC))]
+ "TARGET_REALLY_IWMMXT"
+ "tmrc%?\\t%0, %w1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_tmcr"
+ [(unspec_volatile:SI [(match_operand:SI 0 "immediate_operand" "i")
+ (match_operand:SI 1 "register_operand" "r")]
+ VUNSPEC_TMCR)]
+ "TARGET_REALLY_IWMMXT"
+ "tmcr%?\\t%w0, %1"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wsadb"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")] UNSPEC_WSAD))]
+ "TARGET_REALLY_IWMMXT"
+ "wsadb%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wsadh"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WSAD))]
+ "TARGET_REALLY_IWMMXT"
+ "wsadh%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wsadbz"
+ [(set (match_operand:V8QI 0 "register_operand" "=y")
+ (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
+ (match_operand:V8QI 2 "register_operand" "y")] UNSPEC_WSADZ))]
+ "TARGET_REALLY_IWMMXT"
+ "wsadbz%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
+(define_insn "iwmmxt_wsadhz"
+ [(set (match_operand:V4HI 0 "register_operand" "=y")
+ (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "y")
+ (match_operand:V4HI 2 "register_operand" "y")] UNSPEC_WSADZ))]
+ "TARGET_REALLY_IWMMXT"
+ "wsadhz%?\\t%0, %1, %2"
+ [(set_attr "predicable" "yes")])
+
diff --git a/contrib/gcc/config/arm/kaos-arm.h b/contrib/gcc/config/arm/kaos-arm.h
new file mode 100644
index 000000000000..0d3bf2d10303
--- /dev/null
+++ b/contrib/gcc/config/arm/kaos-arm.h
@@ -0,0 +1,24 @@
+/* Definitions of target machine for GNU compiler.
+ kaOS on arm architecture version.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fputs (" (ARM/kaOS[ELF])", stderr);
+
diff --git a/contrib/gcc/config/arm/kaos-strongarm.h b/contrib/gcc/config/arm/kaos-strongarm.h
new file mode 100644
index 000000000000..8eb9473bf2b0
--- /dev/null
+++ b/contrib/gcc/config/arm/kaos-strongarm.h
@@ -0,0 +1,24 @@
+/* Definitions of target machine for GNU compiler.
+ kaOS on strongarm architecture version.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fputs (" (StrongARM/kaOS[ELF])", stderr);
+
diff --git a/contrib/gcc/config/arm/lib1funcs.asm b/contrib/gcc/config/arm/lib1funcs.asm
index ec706ece127c..e72af6cca512 100644
--- a/contrib/gcc/config/arm/lib1funcs.asm
+++ b/contrib/gcc/config/arm/lib1funcs.asm
@@ -1,7 +1,8 @@
@ libgcc routines for ARM cpu.
@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
-/* Copyright 1995, 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004
+ 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
@@ -51,74 +52,117 @@ Boston, MA 02111-1307, USA. */
#endif
#define TYPE(x) .type SYM(x),function
#define SIZE(x) .size SYM(x), . - SYM(x)
+#define LSYM(x) .x
#else
#define __PLT__
#define TYPE(x)
#define SIZE(x)
+#define LSYM(x) x
#endif
/* Function end macros. Variants for 26 bit APCS and interworking. */
+@ This selects the minimum architecture level required.
+#define __ARM_ARCH__ 3
+
+#if defined(__ARM_ARCH_3M__) || defined(__ARM_ARCH_4__) \
+ || defined(__ARM_ARCH_4T__)
+/* We use __ARM_ARCH__ set to 4 here, but in reality it's any processor with
+ long multiply instructions. That includes v3M. */
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 4
+#endif
+
+#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+ || defined(__ARM_ARCH_5TE__)
+# undef __ARM_ARCH__
+# define __ARM_ARCH__ 5
+#endif
+
+/* How to return from a function call depends on the architecture variant. */
+
#ifdef __APCS_26__
+
# define RET movs pc, lr
# define RETc(x) mov##x##s pc, lr
-# define RETCOND ^
+
+#elif (__ARM_ARCH__ > 4) || defined(__ARM_ARCH_4T__)
+
+# define RET bx lr
+# define RETc(x) bx##x lr
+
+# if (__ARM_ARCH__ == 4) \
+ && (defined(__thumb__) || defined(__THUMB_INTERWORK__))
+# define __INTERWORKING__
+# endif
+
+#else
+
+# define RET mov pc, lr
+# define RETc(x) mov##x pc, lr
+
+#endif
+
+/* Don't pass dirn, it's there just to get token pasting right. */
+
+.macro RETLDM regs=, cond=, dirn=ia
+#ifdef __APCS_26__
+ .ifc "\regs",""
+ ldm\cond\dirn sp!, {pc}^
+ .else
+ ldm\cond\dirn sp!, {\regs, pc}^
+ .endif
+#elif defined (__INTERWORKING__)
+ .ifc "\regs",""
+ ldr\cond lr, [sp], #4
+ .else
+ ldm\cond\dirn sp!, {\regs, lr}
+ .endif
+ bx\cond lr
+#else
+ .ifc "\regs",""
+ ldr\cond pc, [sp], #4
+ .else
+ ldm\cond\dirn sp!, {\regs, pc}
+ .endif
+#endif
+.endm
+
+
.macro ARM_LDIV0
-Ldiv0:
+LSYM(Ldiv0):
str lr, [sp, #-4]!
bl SYM (__div0) __PLT__
mov r0, #0 @ About as wrong as it could be.
- ldmia sp!, {pc}^
+ RETLDM
.endm
-#else
-# ifdef __THUMB_INTERWORK__
-# define RET bx lr
-# define RETc(x) bx##x lr
+
+
.macro THUMB_LDIV0
-Ldiv0:
+LSYM(Ldiv0):
push { lr }
bl SYM (__div0)
mov r0, #0 @ About as wrong as it could be.
+#if defined (__INTERWORKING__)
pop { r1 }
bx r1
-.endm
-.macro ARM_LDIV0
-Ldiv0:
- str lr, [sp, #-4]!
- bl SYM (__div0) __PLT__
- mov r0, #0 @ About as wrong as it could be.
- ldr lr, [sp], #4
- bx lr
-.endm
-# else
-# define RET mov pc, lr
-# define RETc(x) mov##x pc, lr
-.macro THUMB_LDIV0
-Ldiv0:
- push { lr }
- bl SYM (__div0)
- mov r0, #0 @ About as wrong as it could be.
+#else
pop { pc }
-.endm
-.macro ARM_LDIV0
-Ldiv0:
- str lr, [sp, #-4]!
- bl SYM (__div0) __PLT__
- mov r0, #0 @ About as wrong as it could be.
- ldmia sp!, {pc}
-.endm
-# endif
-# define RETCOND
#endif
+.endm
.macro FUNC_END name
-Ldiv0:
+ SIZE (__\name)
+.endm
+
+.macro DIV_FUNC_END name
+LSYM(Ldiv0):
#ifdef __thumb__
THUMB_LDIV0
#else
ARM_LDIV0
#endif
- SIZE (__\name)
+ FUNC_END \name
.endm
.macro THUMB_FUNC_START name
@@ -147,7 +191,37 @@ SYM (\name):
THUMB_FUNC
SYM (__\name):
.endm
-
+
+/* Special function that will always be coded in ARM assembly, even if
+ in Thumb-only compilation. */
+
+#if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
+.macro ARM_FUNC_START name
+ FUNC_START \name
+ bx pc
+ nop
+ .arm
+_L__\name: /* A hook to tell gdb that we've switched to ARM */
+.endm
+#define EQUIV .thumb_set
+#else
+.macro ARM_FUNC_START name
+ .text
+ .globl SYM (__\name)
+ TYPE (__\name)
+ .align 0
+ .arm
+SYM (__\name):
+.endm
+#define EQUIV .set
+#endif
+
+.macro ARM_FUNC_ALIAS new old
+ .globl SYM (__\new)
+ EQUIV SYM (__\new), SYM (__\old)
+.endm
+
+#ifdef __thumb__
/* Register aliases. */
work .req r4 @ XXXX is this safe ?
@@ -156,133 +230,212 @@ divisor .req r1
overdone .req r2
result .req r2
curbit .req r3
+#endif
+#if 0
ip .req r12
sp .req r13
lr .req r14
pc .req r15
+#endif
/* ------------------------------------------------------------------------ */
-/* Bodies of the divsion and modulo routines. */
+/* Bodies of the division and modulo routines. */
/* ------------------------------------------------------------------------ */
-.macro ARM_DIV_MOD_BODY modulo
-Loop1:
+.macro ARM_DIV_BODY dividend, divisor, result, curbit
+
+#if __ARM_ARCH__ >= 5
+
+ clz \curbit, \divisor
+ clz \result, \dividend
+ sub \result, \curbit, \result
+ mov \curbit, #1
+ mov \divisor, \divisor, lsl \result
+ mov \curbit, \curbit, lsl \result
+ mov \result, #0
+
+#else
+
+ @ Initially shift the divisor left 3 bits if possible,
+ @ set curbit accordingly. This allows for curbit to be located
+ @ at the left end of each 4 bit nibbles in the division loop
+ @ to save one loop in most cases.
+ tst \divisor, #0xe0000000
+ moveq \divisor, \divisor, lsl #3
+ moveq \curbit, #8
+ movne \curbit, #1
+
@ Unless the divisor is very big, shift it up in multiples of
@ four bits, since this is the amount of unwinding in the main
@ division loop. Continue shifting until the divisor is
@ larger than the dividend.
- cmp divisor, #0x10000000
- cmplo divisor, dividend
- movlo divisor, divisor, lsl #4
- movlo curbit, curbit, lsl #4
- blo Loop1
+1: cmp \divisor, #0x10000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #4
+ movlo \curbit, \curbit, lsl #4
+ blo 1b
-Lbignum:
@ For very big divisors, we must shift it a bit at a time, or
@ we will be in danger of overflowing.
- cmp divisor, #0x80000000
- cmplo divisor, dividend
- movlo divisor, divisor, lsl #1
- movlo curbit, curbit, lsl #1
- blo Lbignum
+1: cmp \divisor, #0x80000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #1
+ movlo \curbit, \curbit, lsl #1
+ blo 1b
+
+ mov \result, #0
+
+#endif
+
+ @ Division loop
+1: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ orrhs \result, \result, \curbit
+ cmp \dividend, \divisor, lsr #1
+ subhs \dividend, \dividend, \divisor, lsr #1
+ orrhs \result, \result, \curbit, lsr #1
+ cmp \dividend, \divisor, lsr #2
+ subhs \dividend, \dividend, \divisor, lsr #2
+ orrhs \result, \result, \curbit, lsr #2
+ cmp \dividend, \divisor, lsr #3
+ subhs \dividend, \dividend, \divisor, lsr #3
+ orrhs \result, \result, \curbit, lsr #3
+ cmp \dividend, #0 @ Early termination?
+ movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
+ movne \divisor, \divisor, lsr #4
+ bne 1b
+
+.endm
+/* ------------------------------------------------------------------------ */
+.macro ARM_DIV2_ORDER divisor, order
+
+#if __ARM_ARCH__ >= 5
+
+ clz \order, \divisor
+ rsb \order, \order, #31
+
+#else
-Loop3:
- @ Test for possible subtractions. On the final pass, this may
- @ subtract too much from the dividend ...
+ cmp \divisor, #(1 << 16)
+ movhs \divisor, \divisor, lsr #16
+ movhs \order, #16
+ movlo \order, #0
+
+ cmp \divisor, #(1 << 8)
+ movhs \divisor, \divisor, lsr #8
+ addhs \order, \order, #8
+
+ cmp \divisor, #(1 << 4)
+ movhs \divisor, \divisor, lsr #4
+ addhs \order, \order, #4
+
+ cmp \divisor, #(1 << 2)
+ addhi \order, \order, #3
+ addls \order, \order, \divisor, lsr #1
+
+#endif
+
+.endm
+/* ------------------------------------------------------------------------ */
+.macro ARM_MOD_BODY dividend, divisor, order, spare
+
+#if __ARM_ARCH__ >= 5
+
+ clz \order, \divisor
+ clz \spare, \dividend
+ sub \order, \order, \spare
+ mov \divisor, \divisor, lsl \order
- .if \modulo
- @ ... so keep track of which subtractions are done in OVERDONE.
- @ We can fix them up afterwards.
- mov overdone, #0
- cmp dividend, divisor
- subhs dividend, dividend, divisor
- cmp dividend, divisor, lsr #1
- subhs dividend, dividend, divisor, lsr #1
- orrhs overdone, overdone, curbit, ror #1
- cmp dividend, divisor, lsr #2
- subhs dividend, dividend, divisor, lsr #2
- orrhs overdone, overdone, curbit, ror #2
- cmp dividend, divisor, lsr #3
- subhs dividend, dividend, divisor, lsr #3
- orrhs overdone, overdone, curbit, ror #3
- mov ip, curbit
- .else
- @ ... so keep track of which subtractions are done in RESULT.
- @ The result will be ok, since the "bit" will have been
- @ shifted out at the bottom.
- cmp dividend, divisor
- subhs dividend, dividend, divisor
- orrhs result, result, curbit
- cmp dividend, divisor, lsr #1
- subhs dividend, dividend, divisor, lsr #1
- orrhs result, result, curbit, lsr #1
- cmp dividend, divisor, lsr #2
- subhs dividend, dividend, divisor, lsr #2
- orrhs result, result, curbit, lsr #2
- cmp dividend, divisor, lsr #3
- subhs dividend, dividend, divisor, lsr #3
- orrhs result, result, curbit, lsr #3
- .endif
+#else
- cmp dividend, #0 @ Early termination?
- movnes curbit, curbit, lsr #4 @ No, any more bits to do?
- movne divisor, divisor, lsr #4
- bne Loop3
+ mov \order, #0
- .if \modulo
-Lfixup_dividend:
- @ Any subtractions that we should not have done will be recorded in
- @ the top three bits of OVERDONE. Exactly which were not needed
- @ are governed by the position of the bit, stored in IP.
- ands overdone, overdone, #0xe0000000
- @ If we terminated early, because dividend became zero, then the
- @ bit in ip will not be in the bottom nibble, and we should not
- @ perform the additions below. We must test for this though
- @ (rather relying upon the TSTs to prevent the additions) since
- @ the bit in ip could be in the top two bits which might then match
- @ with one of the smaller RORs.
- tstne ip, #0x7
- beq Lgot_result
- tst overdone, ip, ror #3
- addne dividend, dividend, divisor, lsr #3
- tst overdone, ip, ror #2
- addne dividend, dividend, divisor, lsr #2
- tst overdone, ip, ror #1
- addne dividend, dividend, divisor, lsr #1
- .endif
+ @ Unless the divisor is very big, shift it up in multiples of
+ @ four bits, since this is the amount of unwinding in the main
+ @ division loop. Continue shifting until the divisor is
+ @ larger than the dividend.
+1: cmp \divisor, #0x10000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #4
+ addlo \order, \order, #4
+ blo 1b
-Lgot_result:
+ @ For very big divisors, we must shift it a bit at a time, or
+ @ we will be in danger of overflowing.
+1: cmp \divisor, #0x80000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #1
+ addlo \order, \order, #1
+ blo 1b
+
+#endif
+
+ @ Perform all needed substractions to keep only the reminder.
+ @ Do comparisons in batch of 4 first.
+ subs \order, \order, #3 @ yes, 3 is intended here
+ blt 2f
+
+1: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ cmp \dividend, \divisor, lsr #1
+ subhs \dividend, \dividend, \divisor, lsr #1
+ cmp \dividend, \divisor, lsr #2
+ subhs \dividend, \dividend, \divisor, lsr #2
+ cmp \dividend, \divisor, lsr #3
+ subhs \dividend, \dividend, \divisor, lsr #3
+ cmp \dividend, #1
+ mov \divisor, \divisor, lsr #4
+ subges \order, \order, #4
+ bge 1b
+
+ tst \order, #3
+ teqne \dividend, #0
+ beq 5f
+
+ @ Either 1, 2 or 3 comparison/substractions are left.
+2: cmn \order, #2
+ blt 4f
+ beq 3f
+ cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ mov \divisor, \divisor, lsr #1
+3: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ mov \divisor, \divisor, lsr #1
+4: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+5:
.endm
/* ------------------------------------------------------------------------ */
.macro THUMB_DIV_MOD_BODY modulo
@ Load the constant 0x10000000 into our work register.
mov work, #1
lsl work, #28
-Loop1:
+LSYM(Loop1):
@ Unless the divisor is very big, shift it up in multiples of
@ four bits, since this is the amount of unwinding in the main
@ division loop. Continue shifting until the divisor is
@ larger than the dividend.
cmp divisor, work
- bhs Lbignum
+ bhs LSYM(Lbignum)
cmp divisor, dividend
- bhs Lbignum
+ bhs LSYM(Lbignum)
lsl divisor, #4
lsl curbit, #4
- b Loop1
-Lbignum:
+ b LSYM(Loop1)
+LSYM(Lbignum):
@ Set work to 0x80000000
lsl work, #3
-Loop2:
+LSYM(Loop2):
@ For very big divisors, we must shift it a bit at a time, or
@ we will be in danger of overflowing.
cmp divisor, work
- bhs Loop3
+ bhs LSYM(Loop3)
cmp divisor, dividend
- bhs Loop3
+ bhs LSYM(Loop3)
lsl divisor, #1
lsl curbit, #1
- b Loop2
-Loop3:
+ b LSYM(Loop2)
+LSYM(Loop3):
@ Test for possible subtractions ...
.if \modulo
@ ... On the final pass, this may subtract too much from the dividend,
@@ -290,79 +443,79 @@ Loop3:
@ afterwards.
mov overdone, #0
cmp dividend, divisor
- blo Lover1
+ blo LSYM(Lover1)
sub dividend, dividend, divisor
-Lover1:
+LSYM(Lover1):
lsr work, divisor, #1
cmp dividend, work
- blo Lover2
+ blo LSYM(Lover2)
sub dividend, dividend, work
mov ip, curbit
mov work, #1
ror curbit, work
orr overdone, curbit
mov curbit, ip
-Lover2:
+LSYM(Lover2):
lsr work, divisor, #2
cmp dividend, work
- blo Lover3
+ blo LSYM(Lover3)
sub dividend, dividend, work
mov ip, curbit
mov work, #2
ror curbit, work
orr overdone, curbit
mov curbit, ip
-Lover3:
+LSYM(Lover3):
lsr work, divisor, #3
cmp dividend, work
- blo Lover4
+ blo LSYM(Lover4)
sub dividend, dividend, work
mov ip, curbit
mov work, #3
ror curbit, work
orr overdone, curbit
mov curbit, ip
-Lover4:
+LSYM(Lover4):
mov ip, curbit
.else
@ ... and note which bits are done in the result. On the final pass,
@ this may subtract too much from the dividend, but the result will be ok,
@ since the "bit" will have been shifted out at the bottom.
cmp dividend, divisor
- blo Lover1
+ blo LSYM(Lover1)
sub dividend, dividend, divisor
orr result, result, curbit
-Lover1:
+LSYM(Lover1):
lsr work, divisor, #1
cmp dividend, work
- blo Lover2
+ blo LSYM(Lover2)
sub dividend, dividend, work
lsr work, curbit, #1
orr result, work
-Lover2:
+LSYM(Lover2):
lsr work, divisor, #2
cmp dividend, work
- blo Lover3
+ blo LSYM(Lover3)
sub dividend, dividend, work
lsr work, curbit, #2
orr result, work
-Lover3:
+LSYM(Lover3):
lsr work, divisor, #3
cmp dividend, work
- blo Lover4
+ blo LSYM(Lover4)
sub dividend, dividend, work
lsr work, curbit, #3
orr result, work
-Lover4:
+LSYM(Lover4):
.endif
cmp dividend, #0 @ Early termination?
- beq Lover5
+ beq LSYM(Lover5)
lsr curbit, #4 @ No, any more bits to do?
- beq Lover5
+ beq LSYM(Lover5)
lsr divisor, #4
- b Loop3
-Lover5:
+ b LSYM(Loop3)
+LSYM(Lover5):
.if \modulo
@ Any subtractions that we should not have done will be recorded in
@ the top three bits of "overdone". Exactly which were not needed
@@ -370,7 +523,7 @@ Lover5:
mov work, #0xe
lsl work, #28
and overdone, work
- beq Lgot_result
+ beq LSYM(Lgot_result)
@ If we terminated early, because dividend became zero, then the
@ bit in ip will not be in the bottom nibble, and we should not
@@ -381,33 +534,33 @@ Lover5:
mov curbit, ip
mov work, #0x7
tst curbit, work
- beq Lgot_result
+ beq LSYM(Lgot_result)
mov curbit, ip
mov work, #3
ror curbit, work
tst overdone, curbit
- beq Lover6
+ beq LSYM(Lover6)
lsr work, divisor, #3
add dividend, work
-Lover6:
+LSYM(Lover6):
mov curbit, ip
mov work, #2
ror curbit, work
tst overdone, curbit
- beq Lover7
+ beq LSYM(Lover7)
lsr work, divisor, #2
add dividend, work
-Lover7:
+LSYM(Lover7):
mov curbit, ip
mov work, #1
ror curbit, work
tst overdone, curbit
- beq Lgot_result
+ beq LSYM(Lgot_result)
lsr work, divisor, #1
add dividend, work
.endif
-Lgot_result:
+LSYM(Lgot_result):
.endm
/* ------------------------------------------------------------------------ */
/* Start of the Real Functions */
@@ -419,13 +572,13 @@ Lgot_result:
#ifdef __thumb__
cmp divisor, #0
- beq Ldiv0
+ beq LSYM(Ldiv0)
mov curbit, #1
mov result, #0
push { work }
cmp dividend, divisor
- blo Lgot_result
+ blo LSYM(Lgot_result)
THUMB_DIV_MOD_BODY 0
@@ -434,22 +587,32 @@ Lgot_result:
RET
#else /* ARM version. */
+
+ subs r2, r1, #1
+ RETc(eq)
+ bcc LSYM(Ldiv0)
+ cmp r0, r1
+ bls 11f
+ tst r1, r2
+ beq 12f
- cmp divisor, #0
- beq Ldiv0
- mov curbit, #1
- mov result, #0
- cmp dividend, divisor
- blo Lgot_result
-
- ARM_DIV_MOD_BODY 0
+ ARM_DIV_BODY r0, r1, r2, r3
- mov r0, result
+ mov r0, r2
RET
+11: moveq r0, #1
+ movne r0, #0
+ RET
+
+12: ARM_DIV2_ORDER r1, r2
+
+ mov r0, r0, lsr r2
+ RET
+
#endif /* ARM version */
- FUNC_END udivsi3
+ DIV_FUNC_END udivsi3
#endif /* L_udivsi3 */
/* ------------------------------------------------------------------------ */
@@ -460,13 +623,13 @@ Lgot_result:
#ifdef __thumb__
cmp divisor, #0
- beq Ldiv0
+ beq LSYM(Ldiv0)
mov curbit, #1
cmp dividend, divisor
- bhs Lover10
+ bhs LSYM(Lover10)
RET
-Lover10:
+LSYM(Lover10):
push { work }
THUMB_DIV_MOD_BODY 1
@@ -476,21 +639,21 @@ Lover10:
#else /* ARM version. */
- cmp divisor, #0
- beq Ldiv0
- cmp divisor, #1
- cmpne dividend, divisor
- moveq dividend, #0
- RETc(lo)
- mov curbit, #1
+ subs r2, r1, #1 @ compare divisor with 1
+ bcc LSYM(Ldiv0)
+ cmpne r0, r1 @ compare dividend with divisor
+ moveq r0, #0
+ tsthi r1, r2 @ see if divisor is power of 2
+ andeq r0, r0, r2
+ RETc(ls)
- ARM_DIV_MOD_BODY 1
+ ARM_MOD_BODY r0, r1, r2, r3
RET
#endif /* ARM version. */
- FUNC_END umodsi3
+ DIV_FUNC_END umodsi3
#endif /* L_umodsi3 */
/* ------------------------------------------------------------------------ */
@@ -500,7 +663,7 @@ Lover10:
#ifdef __thumb__
cmp divisor, #0
- beq Ldiv0
+ beq LSYM(Ldiv0)
push { work }
mov work, dividend
@@ -509,50 +672,67 @@ Lover10:
mov curbit, #1
mov result, #0
cmp divisor, #0
- bpl Lover10
+ bpl LSYM(Lover10)
neg divisor, divisor @ Loops below use unsigned.
-Lover10:
+LSYM(Lover10):
cmp dividend, #0
- bpl Lover11
+ bpl LSYM(Lover11)
neg dividend, dividend
-Lover11:
+LSYM(Lover11):
cmp dividend, divisor
- blo Lgot_result
+ blo LSYM(Lgot_result)
THUMB_DIV_MOD_BODY 0
mov r0, result
mov work, ip
cmp work, #0
- bpl Lover12
+ bpl LSYM(Lover12)
neg r0, r0
-Lover12:
+LSYM(Lover12):
pop { work }
RET
#else /* ARM version. */
- eor ip, dividend, divisor @ Save the sign of the result.
- mov curbit, #1
- mov result, #0
- cmp divisor, #0
- rsbmi divisor, divisor, #0 @ Loops below use unsigned.
- beq Ldiv0
- cmp dividend, #0
- rsbmi dividend, dividend, #0
- cmp dividend, divisor
- blo Lgot_result
-
- ARM_DIV_MOD_BODY 0
+ cmp r1, #0
+ eor ip, r0, r1 @ save the sign of the result.
+ beq LSYM(Ldiv0)
+ rsbmi r1, r1, #0 @ loops below use unsigned.
+ subs r2, r1, #1 @ division by 1 or -1 ?
+ beq 10f
+ movs r3, r0
+ rsbmi r3, r0, #0 @ positive dividend value
+ cmp r3, r1
+ bls 11f
+ tst r1, r2 @ divisor is power of 2 ?
+ beq 12f
+
+ ARM_DIV_BODY r3, r1, r0, r2
- mov r0, result
cmp ip, #0
rsbmi r0, r0, #0
RET
+10: teq ip, r0 @ same sign ?
+ rsbmi r0, r0, #0
+ RET
+
+11: movlo r0, #0
+ moveq r0, ip, asr #31
+ orreq r0, r0, #1
+ RET
+
+12: ARM_DIV2_ORDER r1, r2
+
+ cmp ip, #0
+ mov r0, r3, lsr r2
+ rsbmi r0, r0, #0
+ RET
+
#endif /* ARM version */
- FUNC_END divsi3
+ DIV_FUNC_END divsi3
#endif /* L_divsi3 */
/* ------------------------------------------------------------------------ */
@@ -564,56 +744,55 @@ Lover12:
mov curbit, #1
cmp divisor, #0
- beq Ldiv0
- bpl Lover10
+ beq LSYM(Ldiv0)
+ bpl LSYM(Lover10)
neg divisor, divisor @ Loops below use unsigned.
-Lover10:
+LSYM(Lover10):
push { work }
@ Need to save the sign of the dividend, unfortunately, we need
@ work later on. Must do this after saving the original value of
@ the work register, because we will pop this value off first.
push { dividend }
cmp dividend, #0
- bpl Lover11
+ bpl LSYM(Lover11)
neg dividend, dividend
-Lover11:
+LSYM(Lover11):
cmp dividend, divisor
- blo Lgot_result
+ blo LSYM(Lgot_result)
THUMB_DIV_MOD_BODY 1
pop { work }
cmp work, #0
- bpl Lover12
+ bpl LSYM(Lover12)
neg dividend, dividend
-Lover12:
+LSYM(Lover12):
pop { work }
RET
#else /* ARM version. */
- cmp divisor, #0
- rsbmi divisor, divisor, #0 @ Loops below use unsigned.
- beq Ldiv0
- @ Need to save the sign of the dividend, unfortunately, we need
- @ ip later on; this is faster than pushing lr and using that.
- str dividend, [sp, #-4]!
- cmp dividend, #0 @ Test dividend against zero
- rsbmi dividend, dividend, #0 @ If negative make positive
- cmp dividend, divisor @ else if zero return zero
- blo Lgot_result @ if smaller return dividend
- mov curbit, #1
-
- ARM_DIV_MOD_BODY 1
-
- ldr ip, [sp], #4
- cmp ip, #0
- rsbmi dividend, dividend, #0
+ cmp r1, #0
+ beq LSYM(Ldiv0)
+ rsbmi r1, r1, #0 @ loops below use unsigned.
+ movs ip, r0 @ preserve sign of dividend
+ rsbmi r0, r0, #0 @ if negative make positive
+ subs r2, r1, #1 @ compare divisor with 1
+ cmpne r0, r1 @ compare dividend with divisor
+ moveq r0, #0
+ tsthi r1, r2 @ see if divisor is power of 2
+ andeq r0, r0, r2
+ bls 10f
+
+ ARM_MOD_BODY r0, r1, r2, r3
+
+10: cmp ip, #0
+ rsbmi r0, r0, #0
RET
#endif /* ARM version */
- FUNC_END modsi3
+ DIV_FUNC_END modsi3
#endif /* L_modsi3 */
/* ------------------------------------------------------------------------ */
@@ -623,7 +802,7 @@ Lover12:
RET
- SIZE (__div0)
+ FUNC_END div0
#endif /* L_divmodsi_tools */
/* ------------------------------------------------------------------------ */
@@ -636,22 +815,18 @@ Lover12:
#define __NR_getpid (__NR_SYSCALL_BASE+ 20)
#define __NR_kill (__NR_SYSCALL_BASE+ 37)
+ .code 32
FUNC_START div0
stmfd sp!, {r1, lr}
swi __NR_getpid
cmn r0, #1000
- ldmhsfd sp!, {r1, pc}RETCOND @ not much we can do
+ RETLDM r1 hs
mov r1, #SIGFPE
swi __NR_kill
-#ifdef __THUMB_INTERWORK__
- ldmfd sp!, {r1, lr}
- bx lr
-#else
- ldmfd sp!, {r1, pc}RETCOND
-#endif
+ RETLDM r1
- SIZE (__div0)
+ FUNC_END div0
#endif /* L_dvmd_lnx */
/* ------------------------------------------------------------------------ */
@@ -720,24 +895,23 @@ Lover12:
.code 32
.globl _arm_return
-_arm_return:
- ldmia r13!, {r12}
- bx r12
+_arm_return:
+ RETLDM
.code 16
-.macro interwork register
- .code 16
+.macro interwork register
+ .code 16
THUMB_FUNC_START _interwork_call_via_\register
- bx pc
+ bx pc
nop
-
- .code 32
- .globl .Lchange_\register
-.Lchange_\register:
+
+ .code 32
+ .globl LSYM(Lchange_\register)
+LSYM(Lchange_\register):
tst \register, #1
- stmeqdb r13!, {lr}
+ streq lr, [sp, #-4]!
adreq lr, _arm_return
bx \register
@@ -779,3 +953,7 @@ _arm_return:
SIZE (_interwork_call_via_lr)
#endif /* L_interwork_call_via_rX */
+
+#include "ieee754-df.S"
+#include "ieee754-sf.S"
+
diff --git a/contrib/gcc/config/arm/linux-elf.h b/contrib/gcc/config/arm/linux-elf.h
index 8cc812f763f6..9f291c0b49f1 100644
--- a/contrib/gcc/config/arm/linux-elf.h
+++ b/contrib/gcc/config/arm/linux-elf.h
@@ -1,24 +1,24 @@
/* Definitions for ARM running Linux-based GNU systems using ELF
- Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1993, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by Philip Blundell <philb@gnu.org>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* elfos.h should have already been included. Now just override
any conflicting definitions and add any extras. */
@@ -34,6 +34,8 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS)
+#define SUBTARGET_CPU_DEFAULT TARGET_CPU_arm6
+
#define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux -p"
#undef MULTILIB_DEFAULTS
@@ -47,6 +49,7 @@ Boston, MA 02111-1307, USA. */
#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
/* Now we define the strings used to build the spec file. */
+#undef LIB_SPEC
#define LIB_SPEC \
"%{pthread:-lpthread} \
%{shared:-lc} \
@@ -57,7 +60,7 @@ Boston, MA 02111-1307, USA. */
/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add
the GNU/Linux magical crtbegin.o file (see crtstuff.c) which
provides part of the support for getting C++ file-scope static
- object constructed before entering `main'. */
+ object constructed before entering `main'. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
@@ -89,15 +92,7 @@ Boston, MA 02111-1307, USA. */
%{mbig-endian:-EB}" \
SUBTARGET_EXTRA_LINK_SPEC
-#define TARGET_OS_CPP_BUILTINS() \
- do { \
- builtin_define_std ("unix"); \
- builtin_define_std ("linux"); \
- builtin_define ("__gnu_linux__"); \
- builtin_define ("__ELF__"); \
- builtin_assert ("system=unix"); \
- builtin_assert ("system=posix"); \
- } while (0)
+#define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS()
/* This is how we tell the assembler that two symbols have the same value. */
#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \
@@ -111,8 +106,8 @@ Boston, MA 02111-1307, USA. */
while (0)
/* NWFPE always understands FPA instructions. */
-#undef FP_DEFAULT
-#define FP_DEFAULT FP_SOFT3
+#undef FPUTYPE_DEFAULT
+#define FPUTYPE_DEFAULT FPUTYPE_FPA_EMU3
/* Call the function profiler with a given profile label. */
#undef ARM_FUNCTION_PROFILER
@@ -121,6 +116,11 @@ Boston, MA 02111-1307, USA. */
fprintf (STREAM, "\tbl\tmcount%s\n", NEED_PLT_RELOC ? "(PLT)" : ""); \
}
+/* The linux profiler clobbers the link register. Make sure the
+ prologue knows to save it. */
+#define PROFILE_HOOK(X) \
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, LR_REGNUM)))
+
#undef CC1_SPEC
#define CC1_SPEC "%{profile:-p}"
diff --git a/contrib/gcc/config/arm/linux-gas.h b/contrib/gcc/config/arm/linux-gas.h
index 5e8ddf91ca28..69112841893e 100644
--- a/contrib/gcc/config/arm/linux-gas.h
+++ b/contrib/gcc/config/arm/linux-gas.h
@@ -3,35 +3,31 @@
Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Russell King <rmk92@ecs.soton.ac.uk>.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* This is how we tell the assembler that a symbol is weak.
GAS always supports weak symbols. */
-/* This is used in ASM_FILE_START. */
-#undef ARM_OS_NAME
-#define ARM_OS_NAME "Linux"
-
/* Unsigned chars produces much better code than signed. */
#define DEFAULT_SIGNED_CHAR 0
#undef SUBTARGET_CPP_SPEC
-#define SUBTARGET_CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__}"
+#define SUBTARGET_CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{fPIC|fPIE:-D__PIC__ -D__pic__} %{fpic|fpie:-D__PIC__ -D__pic__}"
#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
diff --git a/contrib/gcc/config/arm/mmintrin.h b/contrib/gcc/config/arm/mmintrin.h
new file mode 100644
index 000000000000..4dc1d455ce75
--- /dev/null
+++ b/contrib/gcc/config/arm/mmintrin.h
@@ -0,0 +1,1257 @@
+/* Copyright (C) 2002, 2003 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 2, 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 COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+/* As a special exception, if you include this header file into source
+ files compiled by GCC, this header file does not by itself cause
+ the resulting executable to be covered by the GNU General Public
+ License. This exception does not however invalidate any other
+ reasons why the executable file might be covered by the GNU General
+ Public License. */
+
+#ifndef _MMINTRIN_H_INCLUDED
+#define _MMINTRIN_H_INCLUDED
+
+/* The data type intended for user use. */
+typedef unsigned long long __m64, __int64;
+
+/* Internal data types for implementing the intrinsics. */
+typedef int __v2si __attribute__ ((__mode__ (__V2SI__)));
+typedef int __v4hi __attribute__ ((__mode__ (__V4HI__)));
+typedef int __v8qi __attribute__ ((__mode__ (__V8QI__)));
+
+/* "Convert" __m64 and __int64 into each other. */
+static __inline __m64
+_mm_cvtsi64_m64 (__int64 __i)
+{
+ return __i;
+}
+
+static __inline __int64
+_mm_cvtm64_si64 (__m64 __i)
+{
+ return __i;
+}
+
+static __inline int
+_mm_cvtsi64_si32 (__int64 __i)
+{
+ return __i;
+}
+
+static __inline __int64
+_mm_cvtsi32_si64 (int __i)
+{
+ return __i;
+}
+
+/* Pack the four 16-bit values from M1 into the lower four 8-bit values of
+ the result, and the four 16-bit values from M2 into the upper four 8-bit
+ values of the result, all with signed saturation. */
+static __inline __m64
+_mm_packs_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wpackhss ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Pack the two 32-bit values from M1 in to the lower two 16-bit values of
+ the result, and the two 32-bit values from M2 into the upper two 16-bit
+ values of the result, all with signed saturation. */
+static __inline __m64
+_mm_packs_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wpackwss ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Copy the 64-bit value from M1 into the lower 32-bits of the result, and
+ the 64-bit value from M2 into the upper 32-bits of the result, all with
+ signed saturation for values that do not fit exactly into 32-bits. */
+static __inline __m64
+_mm_packs_pi64 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wpackdss ((long long)__m1, (long long)__m2);
+}
+
+/* Pack the four 16-bit values from M1 into the lower four 8-bit values of
+ the result, and the four 16-bit values from M2 into the upper four 8-bit
+ values of the result, all with unsigned saturation. */
+static __inline __m64
+_mm_packs_pu16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wpackhus ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Pack the two 32-bit values from M1 into the lower two 16-bit values of
+ the result, and the two 32-bit values from M2 into the upper two 16-bit
+ values of the result, all with unsigned saturation. */
+static __inline __m64
+_mm_packs_pu32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wpackwus ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Copy the 64-bit value from M1 into the lower 32-bits of the result, and
+ the 64-bit value from M2 into the upper 32-bits of the result, all with
+ unsigned saturation for values that do not fit exactly into 32-bits. */
+static __inline __m64
+_mm_packs_pu64 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wpackdus ((long long)__m1, (long long)__m2);
+}
+
+/* Interleave the four 8-bit values from the high half of M1 with the four
+ 8-bit values from the high half of M2. */
+static __inline __m64
+_mm_unpackhi_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wunpckihb ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Interleave the two 16-bit values from the high half of M1 with the two
+ 16-bit values from the high half of M2. */
+static __inline __m64
+_mm_unpackhi_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wunpckihh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Interleave the 32-bit value from the high half of M1 with the 32-bit
+ value from the high half of M2. */
+static __inline __m64
+_mm_unpackhi_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wunpckihw ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Interleave the four 8-bit values from the low half of M1 with the four
+ 8-bit values from the low half of M2. */
+static __inline __m64
+_mm_unpacklo_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wunpckilb ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Interleave the two 16-bit values from the low half of M1 with the two
+ 16-bit values from the low half of M2. */
+static __inline __m64
+_mm_unpacklo_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wunpckilh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Interleave the 32-bit value from the low half of M1 with the 32-bit
+ value from the low half of M2. */
+static __inline __m64
+_mm_unpacklo_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wunpckilw ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Take the four 8-bit values from the low half of M1, sign extend them,
+ and return the result as a vector of four 16-bit quantities. */
+static __inline __m64
+_mm_unpackel_pi8 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckelsb ((__v8qi)__m1);
+}
+
+/* Take the two 16-bit values from the low half of M1, sign extend them,
+ and return the result as a vector of two 32-bit quantities. */
+static __inline __m64
+_mm_unpackel_pi16 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckelsh ((__v4hi)__m1);
+}
+
+/* Take the 32-bit value from the low half of M1, and return it sign extended
+ to 64 bits. */
+static __inline __m64
+_mm_unpackel_pi32 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckelsw ((__v2si)__m1);
+}
+
+/* Take the four 8-bit values from the high half of M1, sign extend them,
+ and return the result as a vector of four 16-bit quantities. */
+static __inline __m64
+_mm_unpackeh_pi8 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckehsb ((__v8qi)__m1);
+}
+
+/* Take the two 16-bit values from the high half of M1, sign extend them,
+ and return the result as a vector of two 32-bit quantities. */
+static __inline __m64
+_mm_unpackeh_pi16 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckehsh ((__v4hi)__m1);
+}
+
+/* Take the 32-bit value from the high half of M1, and return it sign extended
+ to 64 bits. */
+static __inline __m64
+_mm_unpackeh_pi32 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckehsw ((__v2si)__m1);
+}
+
+/* Take the four 8-bit values from the low half of M1, zero extend them,
+ and return the result as a vector of four 16-bit quantities. */
+static __inline __m64
+_mm_unpackel_pu8 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckelub ((__v8qi)__m1);
+}
+
+/* Take the two 16-bit values from the low half of M1, zero extend them,
+ and return the result as a vector of two 32-bit quantities. */
+static __inline __m64
+_mm_unpackel_pu16 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckeluh ((__v4hi)__m1);
+}
+
+/* Take the 32-bit value from the low half of M1, and return it zero extended
+ to 64 bits. */
+static __inline __m64
+_mm_unpackel_pu32 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckeluw ((__v2si)__m1);
+}
+
+/* Take the four 8-bit values from the high half of M1, zero extend them,
+ and return the result as a vector of four 16-bit quantities. */
+static __inline __m64
+_mm_unpackeh_pu8 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckehub ((__v8qi)__m1);
+}
+
+/* Take the two 16-bit values from the high half of M1, zero extend them,
+ and return the result as a vector of two 32-bit quantities. */
+static __inline __m64
+_mm_unpackeh_pu16 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckehuh ((__v4hi)__m1);
+}
+
+/* Take the 32-bit value from the high half of M1, and return it zero extended
+ to 64 bits. */
+static __inline __m64
+_mm_unpackeh_pu32 (__m64 __m1)
+{
+ return (__m64) __builtin_arm_wunpckehuw ((__v2si)__m1);
+}
+
+/* Add the 8-bit values in M1 to the 8-bit values in M2. */
+static __inline __m64
+_mm_add_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddb ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Add the 16-bit values in M1 to the 16-bit values in M2. */
+static __inline __m64
+_mm_add_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Add the 32-bit values in M1 to the 32-bit values in M2. */
+static __inline __m64
+_mm_add_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddw ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Add the 8-bit values in M1 to the 8-bit values in M2 using signed
+ saturated arithmetic. */
+static __inline __m64
+_mm_adds_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddbss ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Add the 16-bit values in M1 to the 16-bit values in M2 using signed
+ saturated arithmetic. */
+static __inline __m64
+_mm_adds_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddhss ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Add the 32-bit values in M1 to the 32-bit values in M2 using signed
+ saturated arithmetic. */
+static __inline __m64
+_mm_adds_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddwss ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Add the 8-bit values in M1 to the 8-bit values in M2 using unsigned
+ saturated arithmetic. */
+static __inline __m64
+_mm_adds_pu8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddbus ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Add the 16-bit values in M1 to the 16-bit values in M2 using unsigned
+ saturated arithmetic. */
+static __inline __m64
+_mm_adds_pu16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddhus ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Add the 32-bit values in M1 to the 32-bit values in M2 using unsigned
+ saturated arithmetic. */
+static __inline __m64
+_mm_adds_pu32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_waddwus ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Subtract the 8-bit values in M2 from the 8-bit values in M1. */
+static __inline __m64
+_mm_sub_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubb ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Subtract the 16-bit values in M2 from the 16-bit values in M1. */
+static __inline __m64
+_mm_sub_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Subtract the 32-bit values in M2 from the 32-bit values in M1. */
+static __inline __m64
+_mm_sub_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubw ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Subtract the 8-bit values in M2 from the 8-bit values in M1 using signed
+ saturating arithmetic. */
+static __inline __m64
+_mm_subs_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubbss ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Subtract the 16-bit values in M2 from the 16-bit values in M1 using
+ signed saturating arithmetic. */
+static __inline __m64
+_mm_subs_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubhss ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Subtract the 32-bit values in M2 from the 32-bit values in M1 using
+ signed saturating arithmetic. */
+static __inline __m64
+_mm_subs_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubwss ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Subtract the 8-bit values in M2 from the 8-bit values in M1 using
+ unsigned saturating arithmetic. */
+static __inline __m64
+_mm_subs_pu8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubbus ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Subtract the 16-bit values in M2 from the 16-bit values in M1 using
+ unsigned saturating arithmetic. */
+static __inline __m64
+_mm_subs_pu16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubhus ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Subtract the 32-bit values in M2 from the 32-bit values in M1 using
+ unsigned saturating arithmetic. */
+static __inline __m64
+_mm_subs_pu32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wsubwus ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Multiply four 16-bit values in M1 by four 16-bit values in M2 producing
+ four 32-bit intermediate results, which are then summed by pairs to
+ produce two 32-bit results. */
+static __inline __m64
+_mm_madd_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wmadds ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Multiply four 16-bit values in M1 by four 16-bit values in M2 producing
+ four 32-bit intermediate results, which are then summed by pairs to
+ produce two 32-bit results. */
+static __inline __m64
+_mm_madd_pu16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wmaddu ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Multiply four signed 16-bit values in M1 by four signed 16-bit values in
+ M2 and produce the high 16 bits of the 32-bit results. */
+static __inline __m64
+_mm_mulhi_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wmulsh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Multiply four signed 16-bit values in M1 by four signed 16-bit values in
+ M2 and produce the high 16 bits of the 32-bit results. */
+static __inline __m64
+_mm_mulhi_pu16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wmuluh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Multiply four 16-bit values in M1 by four 16-bit values in M2 and produce
+ the low 16 bits of the results. */
+static __inline __m64
+_mm_mullo_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wmulul ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Shift four 16-bit values in M left by COUNT. */
+static __inline __m64
+_mm_sll_pi16 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsllh ((__v4hi)__m, __count);
+}
+
+static __inline __m64
+_mm_slli_pi16 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsllhi ((__v4hi)__m, __count);
+}
+
+/* Shift two 32-bit values in M left by COUNT. */
+static __inline __m64
+_mm_sll_pi32 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsllw ((__v2si)__m, __count);
+}
+
+static __inline __m64
+_mm_slli_pi32 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsllwi ((__v2si)__m, __count);
+}
+
+/* Shift the 64-bit value in M left by COUNT. */
+static __inline __m64
+_mm_sll_si64 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wslld (__m, __count);
+}
+
+static __inline __m64
+_mm_slli_si64 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wslldi (__m, __count);
+}
+
+/* Shift four 16-bit values in M right by COUNT; shift in the sign bit. */
+static __inline __m64
+_mm_sra_pi16 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsrah ((__v4hi)__m, __count);
+}
+
+static __inline __m64
+_mm_srai_pi16 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsrahi ((__v4hi)__m, __count);
+}
+
+/* Shift two 32-bit values in M right by COUNT; shift in the sign bit. */
+static __inline __m64
+_mm_sra_pi32 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsraw ((__v2si)__m, __count);
+}
+
+static __inline __m64
+_mm_srai_pi32 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsrawi ((__v2si)__m, __count);
+}
+
+/* Shift the 64-bit value in M right by COUNT; shift in the sign bit. */
+static __inline __m64
+_mm_sra_si64 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsrad (__m, __count);
+}
+
+static __inline __m64
+_mm_srai_si64 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsradi (__m, __count);
+}
+
+/* Shift four 16-bit values in M right by COUNT; shift in zeros. */
+static __inline __m64
+_mm_srl_pi16 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsrlh ((__v4hi)__m, __count);
+}
+
+static __inline __m64
+_mm_srli_pi16 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsrlhi ((__v4hi)__m, __count);
+}
+
+/* Shift two 32-bit values in M right by COUNT; shift in zeros. */
+static __inline __m64
+_mm_srl_pi32 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsrlw ((__v2si)__m, __count);
+}
+
+static __inline __m64
+_mm_srli_pi32 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsrlwi ((__v2si)__m, __count);
+}
+
+/* Shift the 64-bit value in M left by COUNT; shift in zeros. */
+static __inline __m64
+_mm_srl_si64 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wsrld (__m, __count);
+}
+
+static __inline __m64
+_mm_srli_si64 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wsrldi (__m, __count);
+}
+
+/* Rotate four 16-bit values in M right by COUNT. */
+static __inline __m64
+_mm_ror_pi16 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wrorh ((__v4hi)__m, __count);
+}
+
+static __inline __m64
+_mm_rori_pi16 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wrorhi ((__v4hi)__m, __count);
+}
+
+/* Rotate two 32-bit values in M right by COUNT. */
+static __inline __m64
+_mm_ror_pi32 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wrorw ((__v2si)__m, __count);
+}
+
+static __inline __m64
+_mm_rori_pi32 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wrorwi ((__v2si)__m, __count);
+}
+
+/* Rotate two 64-bit values in M right by COUNT. */
+static __inline __m64
+_mm_ror_si64 (__m64 __m, __m64 __count)
+{
+ return (__m64) __builtin_arm_wrord (__m, __count);
+}
+
+static __inline __m64
+_mm_rori_si64 (__m64 __m, int __count)
+{
+ return (__m64) __builtin_arm_wrordi (__m, __count);
+}
+
+/* Bit-wise AND the 64-bit values in M1 and M2. */
+static __inline __m64
+_mm_and_si64 (__m64 __m1, __m64 __m2)
+{
+ return __builtin_arm_wand (__m1, __m2);
+}
+
+/* Bit-wise complement the 64-bit value in M1 and bit-wise AND it with the
+ 64-bit value in M2. */
+static __inline __m64
+_mm_andnot_si64 (__m64 __m1, __m64 __m2)
+{
+ return __builtin_arm_wandn (__m1, __m2);
+}
+
+/* Bit-wise inclusive OR the 64-bit values in M1 and M2. */
+static __inline __m64
+_mm_or_si64 (__m64 __m1, __m64 __m2)
+{
+ return __builtin_arm_wor (__m1, __m2);
+}
+
+/* Bit-wise exclusive OR the 64-bit values in M1 and M2. */
+static __inline __m64
+_mm_xor_si64 (__m64 __m1, __m64 __m2)
+{
+ return __builtin_arm_wxor (__m1, __m2);
+}
+
+/* Compare eight 8-bit values. The result of the comparison is 0xFF if the
+ test is true and zero if false. */
+static __inline __m64
+_mm_cmpeq_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpeqb ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline __m64
+_mm_cmpgt_pi8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpgtsb ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+static __inline __m64
+_mm_cmpgt_pu8 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpgtub ((__v8qi)__m1, (__v8qi)__m2);
+}
+
+/* Compare four 16-bit values. The result of the comparison is 0xFFFF if
+ the test is true and zero if false. */
+static __inline __m64
+_mm_cmpeq_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpeqh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline __m64
+_mm_cmpgt_pi16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpgtsh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+static __inline __m64
+_mm_cmpgt_pu16 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpgtuh ((__v4hi)__m1, (__v4hi)__m2);
+}
+
+/* Compare two 32-bit values. The result of the comparison is 0xFFFFFFFF if
+ the test is true and zero if false. */
+static __inline __m64
+_mm_cmpeq_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpeqw ((__v2si)__m1, (__v2si)__m2);
+}
+
+static __inline __m64
+_mm_cmpgt_pi32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpgtsw ((__v2si)__m1, (__v2si)__m2);
+}
+
+static __inline __m64
+_mm_cmpgt_pu32 (__m64 __m1, __m64 __m2)
+{
+ return (__m64) __builtin_arm_wcmpgtuw ((__v2si)__m1, (__v2si)__m2);
+}
+
+/* Element-wise multiplication of unsigned 16-bit values __B and __C, followed
+ by accumulate across all elements and __A. */
+static __inline __m64
+_mm_mac_pu16 (__m64 __A, __m64 __B, __m64 __C)
+{
+ return __builtin_arm_wmacu (__A, (__v4hi)__B, (__v4hi)__C);
+}
+
+/* Element-wise multiplication of signed 16-bit values __B and __C, followed
+ by accumulate across all elements and __A. */
+static __inline __m64
+_mm_mac_pi16 (__m64 __A, __m64 __B, __m64 __C)
+{
+ return __builtin_arm_wmacs (__A, (__v4hi)__B, (__v4hi)__C);
+}
+
+/* Element-wise multiplication of unsigned 16-bit values __B and __C, followed
+ by accumulate across all elements. */
+static __inline __m64
+_mm_macz_pu16 (__m64 __A, __m64 __B)
+{
+ return __builtin_arm_wmacuz ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Element-wise multiplication of signed 16-bit values __B and __C, followed
+ by accumulate across all elements. */
+static __inline __m64
+_mm_macz_pi16 (__m64 __A, __m64 __B)
+{
+ return __builtin_arm_wmacsz ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Accumulate across all unsigned 8-bit values in __A. */
+static __inline __m64
+_mm_acc_pu8 (__m64 __A)
+{
+ return __builtin_arm_waccb ((__v8qi)__A);
+}
+
+/* Accumulate across all unsigned 16-bit values in __A. */
+static __inline __m64
+_mm_acc_pu16 (__m64 __A)
+{
+ return __builtin_arm_wacch ((__v4hi)__A);
+}
+
+/* Accumulate across all unsigned 32-bit values in __A. */
+static __inline __m64
+_mm_acc_pu32 (__m64 __A)
+{
+ return __builtin_arm_waccw ((__v2si)__A);
+}
+
+static __inline __m64
+_mm_mia_si64 (__m64 __A, int __B, int __C)
+{
+ return __builtin_arm_tmia (__A, __B, __C);
+}
+
+static __inline __m64
+_mm_miaph_si64 (__m64 __A, int __B, int __C)
+{
+ return __builtin_arm_tmiaph (__A, __B, __C);
+}
+
+static __inline __m64
+_mm_miabb_si64 (__m64 __A, int __B, int __C)
+{
+ return __builtin_arm_tmiabb (__A, __B, __C);
+}
+
+static __inline __m64
+_mm_miabt_si64 (__m64 __A, int __B, int __C)
+{
+ return __builtin_arm_tmiabt (__A, __B, __C);
+}
+
+static __inline __m64
+_mm_miatb_si64 (__m64 __A, int __B, int __C)
+{
+ return __builtin_arm_tmiatb (__A, __B, __C);
+}
+
+static __inline __m64
+_mm_miatt_si64 (__m64 __A, int __B, int __C)
+{
+ return __builtin_arm_tmiatt (__A, __B, __C);
+}
+
+/* Extract one of the elements of A and sign extend. The selector N must
+ be immediate. */
+#define _mm_extract_pi8(A, N) __builtin_arm_textrmsb ((__v8qi)(A), (N))
+#define _mm_extract_pi16(A, N) __builtin_arm_textrmsh ((__v4hi)(A), (N))
+#define _mm_extract_pi32(A, N) __builtin_arm_textrmsw ((__v2si)(A), (N))
+
+/* Extract one of the elements of A and zero extend. The selector N must
+ be immediate. */
+#define _mm_extract_pu8(A, N) __builtin_arm_textrmub ((__v8qi)(A), (N))
+#define _mm_extract_pu16(A, N) __builtin_arm_textrmuh ((__v4hi)(A), (N))
+#define _mm_extract_pu32(A, N) __builtin_arm_textrmuw ((__v2si)(A), (N))
+
+/* Inserts word D into one of the elements of A. The selector N must be
+ immediate. */
+#define _mm_insert_pi8(A, D, N) \
+ ((__m64) __builtin_arm_tinsrb ((__v8qi)(A), (D), (N)))
+#define _mm_insert_pi16(A, D, N) \
+ ((__m64) __builtin_arm_tinsrh ((__v4hi)(A), (D), (N)))
+#define _mm_insert_pi32(A, D, N) \
+ ((__m64) __builtin_arm_tinsrw ((__v2si)(A), (D), (N)))
+
+/* Compute the element-wise maximum of signed 8-bit values. */
+static __inline __m64
+_mm_max_pi8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wmaxsb ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the element-wise maximum of signed 16-bit values. */
+static __inline __m64
+_mm_max_pi16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wmaxsh ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the element-wise maximum of signed 32-bit values. */
+static __inline __m64
+_mm_max_pi32 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wmaxsw ((__v2si)__A, (__v2si)__B);
+}
+
+/* Compute the element-wise maximum of unsigned 8-bit values. */
+static __inline __m64
+_mm_max_pu8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wmaxub ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the element-wise maximum of unsigned 16-bit values. */
+static __inline __m64
+_mm_max_pu16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wmaxuh ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the element-wise maximum of unsigned 32-bit values. */
+static __inline __m64
+_mm_max_pu32 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wmaxuw ((__v2si)__A, (__v2si)__B);
+}
+
+/* Compute the element-wise minimum of signed 16-bit values. */
+static __inline __m64
+_mm_min_pi8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wminsb ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the element-wise minimum of signed 16-bit values. */
+static __inline __m64
+_mm_min_pi16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wminsh ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the element-wise minimum of signed 32-bit values. */
+static __inline __m64
+_mm_min_pi32 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wminsw ((__v2si)__A, (__v2si)__B);
+}
+
+/* Compute the element-wise minimum of unsigned 16-bit values. */
+static __inline __m64
+_mm_min_pu8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wminub ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the element-wise minimum of unsigned 16-bit values. */
+static __inline __m64
+_mm_min_pu16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wminuh ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the element-wise minimum of unsigned 32-bit values. */
+static __inline __m64
+_mm_min_pu32 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wminuw ((__v2si)__A, (__v2si)__B);
+}
+
+/* Create an 8-bit mask of the signs of 8-bit values. */
+static __inline int
+_mm_movemask_pi8 (__m64 __A)
+{
+ return __builtin_arm_tmovmskb ((__v8qi)__A);
+}
+
+/* Create an 8-bit mask of the signs of 16-bit values. */
+static __inline int
+_mm_movemask_pi16 (__m64 __A)
+{
+ return __builtin_arm_tmovmskh ((__v4hi)__A);
+}
+
+/* Create an 8-bit mask of the signs of 32-bit values. */
+static __inline int
+_mm_movemask_pi32 (__m64 __A)
+{
+ return __builtin_arm_tmovmskw ((__v2si)__A);
+}
+
+/* Return a combination of the four 16-bit values in A. The selector
+ must be an immediate. */
+#define _mm_shuffle_pi16(A, N) \
+ ((__m64) __builtin_arm_wshufh ((__v4hi)(A), (N)))
+
+
+/* Compute the rounded averages of the unsigned 8-bit values in A and B. */
+static __inline __m64
+_mm_avg_pu8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wavg2br ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the rounded averages of the unsigned 16-bit values in A and B. */
+static __inline __m64
+_mm_avg_pu16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wavg2hr ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the averages of the unsigned 8-bit values in A and B. */
+static __inline __m64
+_mm_avg2_pu8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wavg2b ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the averages of the unsigned 16-bit values in A and B. */
+static __inline __m64
+_mm_avg2_pu16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wavg2h ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the sum of the absolute differences of the unsigned 8-bit
+ values in A and B. Return the value in the lower 16-bit word; the
+ upper words are cleared. */
+static __inline __m64
+_mm_sad_pu8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wsadb ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the sum of the absolute differences of the unsigned 16-bit
+ values in A and B. Return the value in the lower 32-bit word; the
+ upper words are cleared. */
+static __inline __m64
+_mm_sad_pu16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wsadh ((__v4hi)__A, (__v4hi)__B);
+}
+
+/* Compute the sum of the absolute differences of the unsigned 8-bit
+ values in A and B. Return the value in the lower 16-bit word; the
+ upper words are cleared. */
+static __inline __m64
+_mm_sadz_pu8 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wsadbz ((__v8qi)__A, (__v8qi)__B);
+}
+
+/* Compute the sum of the absolute differences of the unsigned 16-bit
+ values in A and B. Return the value in the lower 32-bit word; the
+ upper words are cleared. */
+static __inline __m64
+_mm_sadz_pu16 (__m64 __A, __m64 __B)
+{
+ return (__m64) __builtin_arm_wsadhz ((__v4hi)__A, (__v4hi)__B);
+}
+
+static __inline __m64
+_mm_align_si64 (__m64 __A, __m64 __B, int __C)
+{
+ return (__m64) __builtin_arm_walign ((__v8qi)__A, (__v8qi)__B, __C);
+}
+
+/* Creates a 64-bit zero. */
+static __inline __m64
+_mm_setzero_si64 (void)
+{
+ return __builtin_arm_wzero ();
+}
+
+/* Set and Get arbitrary iWMMXt Control registers.
+ Note only registers 0-3 and 8-11 are currently defined,
+ the rest are reserved. */
+
+static __inline void
+_mm_setwcx (const int __regno, const int __value)
+{
+ switch (__regno)
+ {
+ case 0: __builtin_arm_setwcx (0, __value); break;
+ case 1: __builtin_arm_setwcx (1, __value); break;
+ case 2: __builtin_arm_setwcx (2, __value); break;
+ case 3: __builtin_arm_setwcx (3, __value); break;
+ case 8: __builtin_arm_setwcx (8, __value); break;
+ case 9: __builtin_arm_setwcx (9, __value); break;
+ case 10: __builtin_arm_setwcx (10, __value); break;
+ case 11: __builtin_arm_setwcx (11, __value); break;
+ default: break;
+ }
+}
+
+static __inline int
+_mm_getwcx (const int __regno)
+{
+ switch (__regno)
+ {
+ case 0: return __builtin_arm_getwcx (0);
+ case 1: return __builtin_arm_getwcx (1);
+ case 2: return __builtin_arm_getwcx (2);
+ case 3: return __builtin_arm_getwcx (3);
+ case 8: return __builtin_arm_getwcx (8);
+ case 9: return __builtin_arm_getwcx (9);
+ case 10: return __builtin_arm_getwcx (10);
+ case 11: return __builtin_arm_getwcx (11);
+ default: return 0;
+ }
+}
+
+/* Creates a vector of two 32-bit values; I0 is least significant. */
+static __inline __m64
+_mm_set_pi32 (int __i1, int __i0)
+{
+ union {
+ __m64 __q;
+ struct {
+ unsigned int __i0;
+ unsigned int __i1;
+ } __s;
+ } __u;
+
+ __u.__s.__i0 = __i0;
+ __u.__s.__i1 = __i1;
+
+ return __u.__q;
+}
+
+/* Creates a vector of four 16-bit values; W0 is least significant. */
+static __inline __m64
+_mm_set_pi16 (short __w3, short __w2, short __w1, short __w0)
+{
+ unsigned int __i1 = (unsigned short)__w3 << 16 | (unsigned short)__w2;
+ unsigned int __i0 = (unsigned short)__w1 << 16 | (unsigned short)__w0;
+ return _mm_set_pi32 (__i1, __i0);
+
+}
+
+/* Creates a vector of eight 8-bit values; B0 is least significant. */
+static __inline __m64
+_mm_set_pi8 (char __b7, char __b6, char __b5, char __b4,
+ char __b3, char __b2, char __b1, char __b0)
+{
+ unsigned int __i1, __i0;
+
+ __i1 = (unsigned char)__b7;
+ __i1 = __i1 << 8 | (unsigned char)__b6;
+ __i1 = __i1 << 8 | (unsigned char)__b5;
+ __i1 = __i1 << 8 | (unsigned char)__b4;
+
+ __i0 = (unsigned char)__b3;
+ __i0 = __i0 << 8 | (unsigned char)__b2;
+ __i0 = __i0 << 8 | (unsigned char)__b1;
+ __i0 = __i0 << 8 | (unsigned char)__b0;
+
+ return _mm_set_pi32 (__i1, __i0);
+}
+
+/* Similar, but with the arguments in reverse order. */
+static __inline __m64
+_mm_setr_pi32 (int __i0, int __i1)
+{
+ return _mm_set_pi32 (__i1, __i0);
+}
+
+static __inline __m64
+_mm_setr_pi16 (short __w0, short __w1, short __w2, short __w3)
+{
+ return _mm_set_pi16 (__w3, __w2, __w1, __w0);
+}
+
+static __inline __m64
+_mm_setr_pi8 (char __b0, char __b1, char __b2, char __b3,
+ char __b4, char __b5, char __b6, char __b7)
+{
+ return _mm_set_pi8 (__b7, __b6, __b5, __b4, __b3, __b2, __b1, __b0);
+}
+
+/* Creates a vector of two 32-bit values, both elements containing I. */
+static __inline __m64
+_mm_set1_pi32 (int __i)
+{
+ return _mm_set_pi32 (__i, __i);
+}
+
+/* Creates a vector of four 16-bit values, all elements containing W. */
+static __inline __m64
+_mm_set1_pi16 (short __w)
+{
+ unsigned int __i = (unsigned short)__w << 16 | (unsigned short)__w;
+ return _mm_set1_pi32 (__i);
+}
+
+/* Creates a vector of four 16-bit values, all elements containing B. */
+static __inline __m64
+_mm_set1_pi8 (char __b)
+{
+ unsigned int __w = (unsigned char)__b << 8 | (unsigned char)__b;
+ unsigned int __i = __w << 16 | __w;
+ return _mm_set1_pi32 (__i);
+}
+
+/* Convert an integer to a __m64 object. */
+static __inline __m64
+_m_from_int (int __a)
+{
+ return (__m64)__a;
+}
+
+#define _m_packsswb _mm_packs_pi16
+#define _m_packssdw _mm_packs_pi32
+#define _m_packuswb _mm_packs_pu16
+#define _m_packusdw _mm_packs_pu32
+#define _m_packssqd _mm_packs_pi64
+#define _m_packusqd _mm_packs_pu64
+#define _mm_packs_si64 _mm_packs_pi64
+#define _mm_packs_su64 _mm_packs_pu64
+#define _m_punpckhbw _mm_unpackhi_pi8
+#define _m_punpckhwd _mm_unpackhi_pi16
+#define _m_punpckhdq _mm_unpackhi_pi32
+#define _m_punpcklbw _mm_unpacklo_pi8
+#define _m_punpcklwd _mm_unpacklo_pi16
+#define _m_punpckldq _mm_unpacklo_pi32
+#define _m_punpckehsbw _mm_unpackeh_pi8
+#define _m_punpckehswd _mm_unpackeh_pi16
+#define _m_punpckehsdq _mm_unpackeh_pi32
+#define _m_punpckehubw _mm_unpackeh_pu8
+#define _m_punpckehuwd _mm_unpackeh_pu16
+#define _m_punpckehudq _mm_unpackeh_pu32
+#define _m_punpckelsbw _mm_unpackel_pi8
+#define _m_punpckelswd _mm_unpackel_pi16
+#define _m_punpckelsdq _mm_unpackel_pi32
+#define _m_punpckelubw _mm_unpackel_pu8
+#define _m_punpckeluwd _mm_unpackel_pu16
+#define _m_punpckeludq _mm_unpackel_pu32
+#define _m_paddb _mm_add_pi8
+#define _m_paddw _mm_add_pi16
+#define _m_paddd _mm_add_pi32
+#define _m_paddsb _mm_adds_pi8
+#define _m_paddsw _mm_adds_pi16
+#define _m_paddsd _mm_adds_pi32
+#define _m_paddusb _mm_adds_pu8
+#define _m_paddusw _mm_adds_pu16
+#define _m_paddusd _mm_adds_pu32
+#define _m_psubb _mm_sub_pi8
+#define _m_psubw _mm_sub_pi16
+#define _m_psubd _mm_sub_pi32
+#define _m_psubsb _mm_subs_pi8
+#define _m_psubsw _mm_subs_pi16
+#define _m_psubuw _mm_subs_pi32
+#define _m_psubusb _mm_subs_pu8
+#define _m_psubusw _mm_subs_pu16
+#define _m_psubusd _mm_subs_pu32
+#define _m_pmaddwd _mm_madd_pi16
+#define _m_pmadduwd _mm_madd_pu16
+#define _m_pmulhw _mm_mulhi_pi16
+#define _m_pmulhuw _mm_mulhi_pu16
+#define _m_pmullw _mm_mullo_pi16
+#define _m_pmacsw _mm_mac_pi16
+#define _m_pmacuw _mm_mac_pu16
+#define _m_pmacszw _mm_macz_pi16
+#define _m_pmacuzw _mm_macz_pu16
+#define _m_paccb _mm_acc_pu8
+#define _m_paccw _mm_acc_pu16
+#define _m_paccd _mm_acc_pu32
+#define _m_pmia _mm_mia_si64
+#define _m_pmiaph _mm_miaph_si64
+#define _m_pmiabb _mm_miabb_si64
+#define _m_pmiabt _mm_miabt_si64
+#define _m_pmiatb _mm_miatb_si64
+#define _m_pmiatt _mm_miatt_si64
+#define _m_psllw _mm_sll_pi16
+#define _m_psllwi _mm_slli_pi16
+#define _m_pslld _mm_sll_pi32
+#define _m_pslldi _mm_slli_pi32
+#define _m_psllq _mm_sll_si64
+#define _m_psllqi _mm_slli_si64
+#define _m_psraw _mm_sra_pi16
+#define _m_psrawi _mm_srai_pi16
+#define _m_psrad _mm_sra_pi32
+#define _m_psradi _mm_srai_pi32
+#define _m_psraq _mm_sra_si64
+#define _m_psraqi _mm_srai_si64
+#define _m_psrlw _mm_srl_pi16
+#define _m_psrlwi _mm_srli_pi16
+#define _m_psrld _mm_srl_pi32
+#define _m_psrldi _mm_srli_pi32
+#define _m_psrlq _mm_srl_si64
+#define _m_psrlqi _mm_srli_si64
+#define _m_prorw _mm_ror_pi16
+#define _m_prorwi _mm_rori_pi16
+#define _m_prord _mm_ror_pi32
+#define _m_prordi _mm_rori_pi32
+#define _m_prorq _mm_ror_si64
+#define _m_prorqi _mm_rori_si64
+#define _m_pand _mm_and_si64
+#define _m_pandn _mm_andnot_si64
+#define _m_por _mm_or_si64
+#define _m_pxor _mm_xor_si64
+#define _m_pcmpeqb _mm_cmpeq_pi8
+#define _m_pcmpeqw _mm_cmpeq_pi16
+#define _m_pcmpeqd _mm_cmpeq_pi32
+#define _m_pcmpgtb _mm_cmpgt_pi8
+#define _m_pcmpgtub _mm_cmpgt_pu8
+#define _m_pcmpgtw _mm_cmpgt_pi16
+#define _m_pcmpgtuw _mm_cmpgt_pu16
+#define _m_pcmpgtd _mm_cmpgt_pi32
+#define _m_pcmpgtud _mm_cmpgt_pu32
+#define _m_pextrb _mm_extract_pi8
+#define _m_pextrw _mm_extract_pi16
+#define _m_pextrd _mm_extract_pi32
+#define _m_pextrub _mm_extract_pu8
+#define _m_pextruw _mm_extract_pu16
+#define _m_pextrud _mm_extract_pu32
+#define _m_pinsrb _mm_insert_pi8
+#define _m_pinsrw _mm_insert_pi16
+#define _m_pinsrd _mm_insert_pi32
+#define _m_pmaxsb _mm_max_pi8
+#define _m_pmaxsw _mm_max_pi16
+#define _m_pmaxsd _mm_max_pi32
+#define _m_pmaxub _mm_max_pu8
+#define _m_pmaxuw _mm_max_pu16
+#define _m_pmaxud _mm_max_pu32
+#define _m_pminsb _mm_min_pi8
+#define _m_pminsw _mm_min_pi16
+#define _m_pminsd _mm_min_pi32
+#define _m_pminub _mm_min_pu8
+#define _m_pminuw _mm_min_pu16
+#define _m_pminud _mm_min_pu32
+#define _m_pmovmskb _mm_movemask_pi8
+#define _m_pmovmskw _mm_movemask_pi16
+#define _m_pmovmskd _mm_movemask_pi32
+#define _m_pshufw _mm_shuffle_pi16
+#define _m_pavgb _mm_avg_pu8
+#define _m_pavgw _mm_avg_pu16
+#define _m_pavg2b _mm_avg2_pu8
+#define _m_pavg2w _mm_avg2_pu16
+#define _m_psadbw _mm_sad_pu8
+#define _m_psadwd _mm_sad_pu16
+#define _m_psadzbw _mm_sadz_pu8
+#define _m_psadzwd _mm_sadz_pu16
+#define _m_paligniq _mm_align_si64
+#define _m_cvt_si2pi _mm_cvtsi64_m64
+#define _m_cvt_pi2si _mm_cvtm64_si64
+
+#endif /* _MMINTRIN_H_INCLUDED */
diff --git a/contrib/gcc/config/arm/netbsd-elf.h b/contrib/gcc/config/arm/netbsd-elf.h
index 0d5b7984914b..a8b43f645d35 100644
--- a/contrib/gcc/config/arm/netbsd-elf.h
+++ b/contrib/gcc/config/arm/netbsd-elf.h
@@ -1,32 +1,28 @@
/* Definitions of target machine for GNU compiler, NetBSD/arm ELF version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (NetBSD/arm ELF)", stderr);
-/* This is used in ASM_FILE_START. */
-#undef ARM_OS_NAME
-#define ARM_OS_NAME "NetBSD"
-
/* arm.h defaults to ARM6 CPU. */
/* This defaults us to little-endian. */
@@ -59,7 +55,7 @@ Boston, MA 02111-1307, USA. */
#undef SUBTARGET_EXTRA_ASM_SPEC
#define SUBTARGET_EXTRA_ASM_SPEC \
- "-matpcs %{fpic:-k} %{fPIC:-k}"
+ "-matpcs %{fpic|fpie:-k} %{fPIC|fPIE:-k}"
/* Default floating point model is soft-VFP.
FIXME: -mhard-float currently implies FPA. */
@@ -127,7 +123,7 @@ Boston, MA 02111-1307, USA. */
This has several side effects that should be considered.
1. Structures will only be aligned to the size of the largest member.
i.e. structures containing only bytes will be byte aligned.
- structures containing shorts will be half word alinged.
+ structures containing shorts will be half word aligned.
structures containing ints will be word aligned.
This means structures should be padded to a word boundary if
diff --git a/contrib/gcc/config/arm/netbsd.h b/contrib/gcc/config/arm/netbsd.h
index 38ccc3f171d7..71763e61ea85 100644
--- a/contrib/gcc/config/arm/netbsd.h
+++ b/contrib/gcc/config/arm/netbsd.h
@@ -1,32 +1,28 @@
/* NetBSD/arm a.out version.
- Copyright (C) 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1997, 1998, 2003 Free Software Foundation, Inc.
Contributed by Mark Brinicombe (amb@physig.ph.kcl.ac.uk)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (ARM/NetBSD)", stderr);
-/* This is used in ASM_FILE_START. */
-#undef ARM_OS_NAME
-#define ARM_OS_NAME "NetBSD"
-
/* Unsigned chars produces much better code than signed. */
#define DEFAULT_SIGNED_CHAR 0
@@ -40,7 +36,7 @@ Boston, MA 02111-1307, USA. */
/* Default is to use APCS-32 mode. */
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_FRAME)
+#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
/* Some defines for CPP.
arm32 is the NetBSD port name, so we always define arm32 and __arm32__. */
@@ -103,7 +99,7 @@ Boston, MA 02111-1307, USA. */
#undef TYPE_OPERAND_FMT
#define TYPE_OPERAND_FMT "%%%s"
-/* NetBSD uses the old PCC style aggregate returning conventions. */
+/* NetBSD uses the old PCC style aggregate returning conventions. */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 1
@@ -130,7 +126,7 @@ Boston, MA 02111-1307, USA. */
This has several side effects that should be considered.
1. Structures will only be aligned to the size of the largest member.
i.e. structures containing only bytes will be byte aligned.
- structures containing shorts will be half word alinged.
+ structures containing shorts will be half word aligned.
structures containing ints will be word aligned.
This means structures should be padded to a word boundary if
diff --git a/contrib/gcc/config/arm/pe.c b/contrib/gcc/config/arm/pe.c
index ee3da8fd4110..d25fd0da977f 100644
--- a/contrib/gcc/config/arm/pe.c
+++ b/contrib/gcc/config/arm/pe.c
@@ -2,25 +2,27 @@
Copyright (C) 1995, 1996, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "output.h"
#include "flags.h"
@@ -165,7 +167,7 @@ arm_mark_dllimport (decl)
&& !DECL_VIRTUAL_P (decl)
&& DECL_INITIAL (decl))
{
- error_with_decl (decl, "initialized variable `%s' is marked dllimport");
+ error ("%Jinitialized variable '%D' is marked dllimport", decl, decl);
return;
}
/* Nor can they be static. */
@@ -174,7 +176,7 @@ arm_mark_dllimport (decl)
&& !DECL_VIRTUAL_P (decl)
&& 0 /*???*/)
{
- error_with_decl (decl, "static variable `%s' is marked dllimport");
+ error ("%Jstatic variable '%D' is marked dllimport", decl, decl);
return;
}
@@ -205,18 +207,15 @@ arm_mark_dllimport (decl)
}
void
-arm_pe_encode_section_info (decl, first)
+arm_pe_encode_section_info (decl, rtl, first)
tree decl;
+ rtx rtl;
int first ATTRIBUTE_UNUSED;
{
/* This bit is copied from arm_encode_section_info. */
if (optimize > 0 && TREE_CONSTANT (decl)
&& (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
- {
- rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
- ? TREE_CST_RTL (decl) : DECL_RTL (decl));
- SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
- }
+ SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
/* Mark the decl so we can tell from the rtl whether the object is
dllexport'd or dllimport'd. */
diff --git a/contrib/gcc/config/arm/pe.h b/contrib/gcc/config/arm/pe.h
index 38727dad8ed9..e83f97baae02 100644
--- a/contrib/gcc/config/arm/pe.h
+++ b/contrib/gcc/config/arm/pe.h
@@ -1,23 +1,23 @@
/* Definitions of target machine for GNU compiler, for ARM with PE obj format.
- Copyright (C) 1995, 1996, 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Enable PE specific code. */
#define ARM_PE 1
@@ -65,34 +65,30 @@ Boston, MA 02111-1307, USA. */
N_("Ignore dllimport attribute for functions") }, \
{ "no-nop-fun-dllimport", - TARGET_FLAG_NOP_FUN, "" },
+/* Defaulting to APCS-26 support is a legacy issue. It has been done
+ that way for a long time, so changing it will probably break some
+ people's worlds. Support for APCS-32 is now enabled as a multilib,
+ and at some point in the future APCS-32 may become the default.
+ Possibly when chips that support APCS-26 are no longer made. */
+
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | TARGET_FLAG_NOP_FUN)
+#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | TARGET_FLAG_NOP_FUN | ARM_FLAG_MMU_TRAPS)
+#undef MULTILIB_DEFAULTS
+#define MULTILIB_DEFAULTS \
+ { "marm", "mlittle-endian", "msoft-float", "mapcs-26", "mno-thumb-interwork" }
#undef WCHAR_TYPE
#define WCHAR_TYPE "short unsigned int"
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 16
-/* Same as arm.h except r10 is call-saved, not fixed. */
-#undef FIXED_REGISTERS
-#define FIXED_REGISTERS \
-{ \
- 0,0,0,0,0,0,0,0, \
- 0,0,0,1,0,1,0,1, \
- 0,0,0,0,0,0,0,0, \
- 1,1,1 \
-}
+/* r11 is fixed. */
+#undef SUBTARGET_CONDITIONAL_REGISTER_USAGE
+#define SUBTARGET_CONDITIONAL_REGISTER_USAGE \
+ fixed_regs [11] = 1; \
+ call_used_regs [11] = 1;
-/* Same as arm.h except r10 is call-saved, not fixed. */
-#undef CALL_USED_REGISTERS
-#define CALL_USED_REGISTERS \
-{ \
- 1,1,1,1,0,0,0,0, \
- 0,0,0,1,1,1,1,1, \
- 1,1,1,1,0,0,0,0, \
- 1,1,1 \
-}
/* Define this macro if in some cases global symbols from one translation
unit may not be bound to undefined symbols in another translation unit
@@ -105,20 +101,10 @@ Boston, MA 02111-1307, USA. */
#define SUPPORTS_ONE_ONLY 1
/* Switch into a generic section. */
-#undef TARGET_ASM_NAMED_SECTION
+#undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION default_pe_asm_named_section
-/* This outputs a lot of .req's to define alias for various registers.
- Let's try to avoid this. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(STREAM) \
- do \
- { \
- asm_fprintf (STREAM, "%@ Generated by gcc %s for ARM/pe\n",\
- version_string); \
- output_file_directive ((STREAM), main_input_filename); \
- } \
- while (0)
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
/* Output a reference to a label. */
#undef ASM_OUTPUT_LABELREF
@@ -160,7 +146,7 @@ Boston, MA 02111-1307, USA. */
fprintf ((STREAM), "\t.comm\t"); \
assemble_name ((STREAM), (NAME)); \
asm_fprintf ((STREAM), ", %d\t%@ %d\n", \
- (ROUNDED), (SIZE)); \
+ (int)(ROUNDED), (int)(SIZE)); \
} \
} \
while (0)
@@ -201,7 +187,7 @@ Boston, MA 02111-1307, USA. */
#define DRECTVE_SECTION_FUNCTION \
void \
-drectve_section () \
+drectve_section (void) \
{ \
if (in_section != in_drectve) \
{ \
@@ -217,11 +203,8 @@ drectve_section () \
ASM_DECLARE_OBJECT_NAME and then switch back to the original section
afterwards. */
#define SWITCH_TO_SECTION_FUNCTION \
-static void switch_to_section PARAMS ((enum in_section, tree)); \
static void \
-switch_to_section (section, decl) \
- enum in_section section; \
- tree decl; \
+switch_to_section (enum in_section section, tree decl) \
{ \
switch (section) \
{ \
@@ -235,3 +218,4 @@ switch_to_section (section, decl) \
default: abort (); break; \
} \
}
+
diff --git a/contrib/gcc/config/arm/rtems-elf.h b/contrib/gcc/config/arm/rtems-elf.h
index 27928db54896..a736ee1ea10c 100644
--- a/contrib/gcc/config/arm/rtems-elf.h
+++ b/contrib/gcc/config/arm/rtems-elf.h
@@ -1,22 +1,22 @@
/* Definitions for RTEMS based ARM systems using ELF
Copyright (C) 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#undef TARGET_VERSION
@@ -27,6 +27,5 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
builtin_define ("__rtems__"); \
- builtin_define ("__ELF__"); \
builtin_assert ("system=rtems"); \
} while (0)
diff --git a/contrib/gcc/config/arm/semi.h b/contrib/gcc/config/arm/semi.h
index 2e1abd40d24a..2ab06cbcc3f0 100644
--- a/contrib/gcc/config/arm/semi.h
+++ b/contrib/gcc/config/arm/semi.h
@@ -2,22 +2,22 @@
Copyright (C) 1994, 1995, 1996, 1997, 2001 Free Software Foundation, Inc.
Contributed by Richard Earnshaw (richard.earnshaw@arm.com)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#define STARTFILE_SPEC "crt0.o%s"
@@ -38,7 +38,7 @@ Boston, MA 02111-1307, USA. */
#endif
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME)
+#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
#endif
#ifndef SUBTARGET_EXTRA_SPECS
@@ -59,12 +59,12 @@ Boston, MA 02111-1307, USA. */
binutils can't. */
#ifndef ASM_SPEC
#define ASM_SPEC "\
-%{fpic: -k} %{fPIC: -k} \
+%{fpic|fpie: -k} %{fPIC|fPIE: -k} \
%{mbig-endian:-EB} \
%{mcpu=*:-mcpu=%*} \
%{march=*:-march=%*} \
%{mapcs-float:-mfloat} \
-%{msoft-float:-mno-fpu} \
+%{msoft-float:-mfpu=softfpa} \
%{mthumb-interwork:-mthumb-interwork} \
%(subtarget_extra_asm_spec)"
#endif
diff --git a/contrib/gcc/config/arm/semiaof.h b/contrib/gcc/config/arm/semiaof.h
index 6ee17ef01ce6..19a6cf8ea503 100644
--- a/contrib/gcc/config/arm/semiaof.h
+++ b/contrib/gcc/config/arm/semiaof.h
@@ -3,22 +3,22 @@
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by Richard Earnshaw (richard.earnshaw@armltd.co.uk)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
@@ -33,9 +33,9 @@ Boston, MA 02111-1307, USA. */
#define TARGET_VERSION fputs (" (ARM/semi-hosted)", stderr);
-#define TARGET_DEFAULT ARM_FLAG_APCS_32
+#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_MMU_TRAPS)
-/* The Norcroft C library defines size_t as "unsigned int" */
+/* The Norcroft C library defines size_t as "unsigned int". */
#define SIZE_TYPE "unsigned int"
#undef CPP_APCS_PC_DEFAULT_SPEC
diff --git a/contrib/gcc/config/arm/strongarm-coff.h b/contrib/gcc/config/arm/strongarm-coff.h
index 4d2f29212b5a..77dab37ee160 100644
--- a/contrib/gcc/config/arm/strongarm-coff.h
+++ b/contrib/gcc/config/arm/strongarm-coff.h
@@ -2,22 +2,22 @@
Copyright (C) 1999 Free Software Foundation, Inc.
Contributed by Catherine Moore <clm@cygnus.com>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#ifndef SUBTARGET_CPU_DEFAULT
diff --git a/contrib/gcc/config/arm/strongarm-elf.h b/contrib/gcc/config/arm/strongarm-elf.h
index 3fc848718bcc..476b2e4f5eb1 100644
--- a/contrib/gcc/config/arm/strongarm-elf.h
+++ b/contrib/gcc/config/arm/strongarm-elf.h
@@ -2,22 +2,22 @@
Copyright (C) 1999, 2001 Free Software Foundation, Inc.
Contributed by Catherine Moore <clm@cygnus.com>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#ifndef TARGET_VERSION
diff --git a/contrib/gcc/config/arm/strongarm-pe.h b/contrib/gcc/config/arm/strongarm-pe.h
index 2938d3e55ac6..bb123e54ce2e 100644
--- a/contrib/gcc/config/arm/strongarm-pe.h
+++ b/contrib/gcc/config/arm/strongarm-pe.h
@@ -2,22 +2,22 @@
Copyright (C) 1999 Free Software Foundation, Inc.
Contributed by Doug Evans (dje@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fputs (" (StrongARM/PE)", stderr);
diff --git a/contrib/gcc/config/arm/t-arm-coff b/contrib/gcc/config/arm/t-arm-coff
index bf37a37d4ddc..8eef976aaee3 100644
--- a/contrib/gcc/config/arm/t-arm-coff
+++ b/contrib/gcc/config/arm/t-arm-coff
@@ -28,7 +28,7 @@ EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
-# Currently there is a bug somwehere in GCC's alias analysis
+# Currently there is a bug somewhere in GCC's alias analysis
# or scheduling code that is breaking _fpmul_parts in fp-bit.c.
# Disabling function inlining is a workaround for this problem.
TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc -fno-inline
diff --git a/contrib/gcc/config/arm/t-arm-elf b/contrib/gcc/config/arm/t-arm-elf
index 0011b2a8d025..3f48f8b81e9e 100644
--- a/contrib/gcc/config/arm/t-arm-elf
+++ b/contrib/gcc/config/arm/t-arm-elf
@@ -1,34 +1,22 @@
LIB1ASMSRC = arm/lib1funcs.asm
-LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func _call_via_rX _interwork_call_via_rX
+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _bb_init_func \
+ _call_via_rX _interwork_call_via_rX \
+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
+ _fixsfsi _fixunssfsi
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- echo '#ifndef __ARMEB__' >> fp-bit.c
- echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
- echo '#endif' >> fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#ifndef __ARMEB__' > dp-bit.c
- echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
- echo '#define FLOAT_WORD_ORDER_MISMATCH' >> dp-bit.c
- echo '#endif' >> dp-bit.c
- cat $(srcdir)/config/fp-bit.c >> dp-bit.c
-
-
MULTILIB_OPTIONS = marm/mthumb
MULTILIB_DIRNAMES = arm thumb
MULTILIB_EXCEPTIONS =
+MULTILIB_MATCHES =
+
+# MULTILIB_OPTIONS += mcpu=ep9312
+# MULTILIB_DIRNAMES += ep9312
+# MULTILIB_EXCEPTIONS += *mthumb/*mcpu=ep9312*
# MULTILIB_OPTIONS += mlittle-endian/mbig-endian
# MULTILIB_DIRNAMES += le be
-# MULTILIB_EXCEPTIONS =
-# MULTILIB_MATCHES = mbig-endian=mbe mlittle-endian=mle
+# MULTILIB_MATCHES += mbig-endian=mbe mlittle-endian=mle
#
# MULTILIB_OPTIONS += mhard-float/msoft-float
# MULTILIB_DIRNAMES += fpu soft
@@ -93,3 +81,4 @@ $(T)crti.o: $(srcdir)/config/arm/crti.asm $(GCC_PASSES)
$(T)crtn.o: $(srcdir)/config/arm/crtn.asm $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/arm/crtn.asm
+
diff --git a/contrib/gcc/config/arm/t-linux b/contrib/gcc/config/arm/t-linux
index 7dbd0c0e2776..1c5f48ae6f58 100644
--- a/contrib/gcc/config/arm/t-linux
+++ b/contrib/gcc/config/arm/t-linux
@@ -3,9 +3,6 @@
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC
LIBGCC2_DEBUG_CFLAGS = -g0
-# Don't build enquire
-ENQUIRE=
-
LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx
diff --git a/contrib/gcc/config/arm/t-netbsd b/contrib/gcc/config/arm/t-netbsd
index 76e431bfb112..77e622716f25 100644
--- a/contrib/gcc/config/arm/t-netbsd
+++ b/contrib/gcc/config/arm/t-netbsd
@@ -19,8 +19,3 @@ SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
SHLIB_INSTALL = $(INSTALL_DATA) $(SHLIB_NAME) $$(DESTDIR)$$(slibdir)/$(SHLIB_SONAME); \
rm -f $$(DESTDIR)$$(slibdir)/$(SHLIB_NAME); \
$(LN_S) $(SHLIB_SONAME) $$(DESTDIR)$$(slibdir)/$(SHLIB_NAME)
-
-# Don't build enquire
-ENQUIRE=
-
-
diff --git a/contrib/gcc/config/arm/t-pe b/contrib/gcc/config/arm/t-pe
index f559bd20cff9..4c20b3179735 100644
--- a/contrib/gcc/config/arm/t-pe
+++ b/contrib/gcc/config/arm/t-pe
@@ -20,12 +20,12 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
-pe.o: $(srcdir)/config/arm/pe.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) output.h \
- flags.h $(TREE_H) $(EXPR_H) toplev.h $(TM_P_H)
+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
-MULTILIB_OPTIONS = mhard-float mthumb
-MULTILIB_DIRNAMES = fpu thumb
+MULTILIB_OPTIONS = mhard-float mthumb mapcs-32
+MULTILIB_DIRNAMES = fpu thumb apcs32
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
diff --git a/contrib/gcc/config/arm/t-semi b/contrib/gcc/config/arm/t-semi
index ce3946063864..abd642cb02bc 100644
--- a/contrib/gcc/config/arm/t-semi
+++ b/contrib/gcc/config/arm/t-semi
@@ -3,15 +3,9 @@
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer
LIBGCC2_DEBUG_CFLAGS = -g0
-# Don't build enquire
-ENQUIRE=
-
LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _call_via_rX _interwork_call_via_rX
-#Don't try to run fixproto
-STMP_FIXPROTO =
-
# We want fine grained libraries, so use the new code to build the
# floating point emulation libraries.
FPBIT = fp-bit.c
diff --git a/contrib/gcc/config/arm/t-strongarm-pe b/contrib/gcc/config/arm/t-strongarm-pe
index 6a44132bd07d..e401666654a6 100644
--- a/contrib/gcc/config/arm/t-strongarm-pe
+++ b/contrib/gcc/config/arm/t-strongarm-pe
@@ -20,7 +20,8 @@ dp-bit.c: $(srcdir)/config/fp-bit.c
echo '#endif' >> dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
-pe.o: $(srcdir)/config/arm/pe.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
MULTILIB_OPTIONS = mhard-float/msoft-float
@@ -31,7 +32,7 @@ EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
-# Currently there is a bug somwehere in GCC's alias analysis
+# Currently there is a bug somewhere in GCC's alias analysis
# or scheduling code that is breaking _fpmul_parts in fp-bit.c.
# Disabling function inlining is a workaround for this problem.
TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc -fno-inline
diff --git a/contrib/gcc/config/arm/t-vxworks b/contrib/gcc/config/arm/t-vxworks
new file mode 100644
index 000000000000..e620cfdf8ee9
--- /dev/null
+++ b/contrib/gcc/config/arm/t-vxworks
@@ -0,0 +1,10 @@
+# Multilibs for VxWorks.
+
+MULTILIB_OPTIONS = \
+ t4/t4be/t4t/t4tbe/t5/t5be/t5t/t5tbe/txscale/txscalebe
+
+MULTILIB_DIRNAMES = \
+ ARMARCH4gnu ARMARCH4gnube ARMARCH4_Tgnu ARMARCH4_Tgnube \
+ ARMARCH5gnu ARMARCH5gnube ARMARCH5_Tgnu ARMARCH5_Tgnube \
+ XSCALEgnu XSCALEgnube
+
diff --git a/contrib/gcc/config/arm/t-wince-pe b/contrib/gcc/config/arm/t-wince-pe
new file mode 100644
index 000000000000..9537a7f75eda
--- /dev/null
+++ b/contrib/gcc/config/arm/t-wince-pe
@@ -0,0 +1,37 @@
+LIB1ASMSRC = arm/lib1funcs.asm
+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _call_via_rX _interwork_call_via_rX
+
+# We want fine grained libraries, so use the new code to build the
+# floating point emulation libraries.
+FPBIT = fp-bit.c
+DPBIT = dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ echo '#ifndef __ARMEB__' >> fp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >> fp-bit.c
+ echo '#endif' >> fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#ifndef __ARMEB__' > dp-bit.c
+ echo '#define FLOAT_BIT_ORDER_MISMATCH' >> dp-bit.c
+ echo '#define FLOAT_WORD_ORDER_MISMATCH' >> dp-bit.c
+ echo '#endif' >> dp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> dp-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
+
+MULTILIB_OPTIONS = mhard-float mapcs-26
+MULTILIB_DIRNAMES = fpu apcs26
+# Note - Thumb multilib omitted because Thumb apcs32 support for
+# arm-wince-pe target does not appear to be working in binutils
+# yet...
+# MULTILIB_OPTIONS += thumb
+# MULTILIB_DIRNAMES += thumb
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc
diff --git a/contrib/gcc/config/arm/t-xscale-elf b/contrib/gcc/config/arm/t-xscale-elf
index 0efc1d547788..b72c21ce9803 100644
--- a/contrib/gcc/config/arm/t-xscale-elf
+++ b/contrib/gcc/config/arm/t-xscale-elf
@@ -37,6 +37,10 @@ MULTILIB_EXCEPTIONS += *mhard-float/*mthumb*
MULTILIB_REDUNDANT_DIRS = interwork/thumb=thumb
+MULTILIB_OPTIONS += mcpu=iwmmxt
+MULTILIB_DIRNAMES += iwmmxt
+MULTILIB_REDUNDANT_DIRS += interwork/thumb/iwmmxt=thumb
+
EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o
LIBGCC = stmp-multilib
diff --git a/contrib/gcc/config/arm/uclinux-elf.h b/contrib/gcc/config/arm/uclinux-elf.h
index cad61b70bd4f..e3cd48d44479 100644
--- a/contrib/gcc/config/arm/uclinux-elf.h
+++ b/contrib/gcc/config/arm/uclinux-elf.h
@@ -2,22 +2,22 @@
Copyright (C) 1999, 2001 Free Software Foundation, Inc.
Contributed by Philip Blundell <pb@nexus.co.uk>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* We don't want a PLT. */
#undef NEED_PLT_RELOC
diff --git a/contrib/gcc/config/arm/unknown-elf.h b/contrib/gcc/config/arm/unknown-elf.h
index 7f9211b18c0a..1af799482b4e 100644
--- a/contrib/gcc/config/arm/unknown-elf.h
+++ b/contrib/gcc/config/arm/unknown-elf.h
@@ -1,23 +1,24 @@
/* Definitions for non-Linux based ARM systems using ELF
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
Contributed by Catherine Moore <clm@cygnus.com>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* elfos.h should have already been included. Now just override
any conflicting definitions and add any extras. */
@@ -29,7 +30,7 @@ Boston, MA 02111-1307, USA. */
/* Default to using APCS-32 and software floating point. */
#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME)
+#define TARGET_DEFAULT (ARM_FLAG_SOFT_FLOAT | ARM_FLAG_APCS_32 | ARM_FLAG_APCS_FRAME | ARM_FLAG_MMU_TRAPS)
#endif
/* Now we define the strings used to build the spec file. */
@@ -42,7 +43,7 @@ Boston, MA 02111-1307, USA. */
/* The __USES_INITFINI__ define is tested in newlib/libc/sys/arm/crt0.S
to see if it needs to invoked _init() and _fini(). */
#undef SUBTARGET_CPP_SPEC
-#define SUBTARGET_CPP_SPEC "-D__ELF__ -D__USES_INITFINI__"
+#define SUBTARGET_CPP_SPEC "-D__USES_INITFINI__"
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
@@ -61,13 +62,11 @@ Boston, MA 02111-1307, USA. */
else \
bss_section (); \
\
- (*targetm.asm_out.globalize_label) (FILE, NAME); \
- \
ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT)); \
\
last_assemble_variable_decl = DECL; \
ASM_DECLARE_OBJECT_NAME (FILE, NAME, DECL); \
- ASM_OUTPUT_SKIP (FILE, SIZE ? SIZE : 1); \
+ ASM_OUTPUT_SKIP (FILE, SIZE ? (int)(SIZE) : 1); \
} \
while (0)
@@ -82,7 +81,7 @@ Boston, MA 02111-1307, USA. */
\
ASM_OUTPUT_ALIGN (FILE, floor_log2 (ALIGN / BITS_PER_UNIT)); \
ASM_OUTPUT_LABEL (FILE, NAME); \
- fprintf (FILE, "\t.space\t%d\n", SIZE ? SIZE : 1); \
+ fprintf (FILE, "\t.space\t%d\n", SIZE ? (int)(SIZE) : 1); \
} \
while (0)
diff --git a/contrib/gcc/config/arm/vxworks.h b/contrib/gcc/config/arm/vxworks.h
new file mode 100644
index 000000000000..afe6b7043bea
--- /dev/null
+++ b/contrib/gcc/config/arm/vxworks.h
@@ -0,0 +1,95 @@
+/* Definitions of target machine for GCC,
+ for ARM with targetting the VXWorks run time environment.
+ Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
+
+ Contributed by: Mike Stump <mrs@wrs.com>
+ Brought up to date by CodeSourcery, LLC.
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#define TARGET_OS_CPP_BUILTINS() \
+ do { \
+ builtin_define ("__vxworks"); \
+ if (TARGET_BIG_END) \
+ builtin_define ("ARMEB"); \
+ else \
+ builtin_define ("ARMEL"); \
+ \
+ if (arm_is_xscale) \
+ builtin_define ("CPU=XSCALE"); \
+ else if (arm_arch5) \
+ builtin_define ("CPU=ARMARCH5"); \
+ else if (arm_arch4) \
+ { \
+ if (thumb_code) \
+ builtin_define ("CPU=ARMARCH4_T"); \
+ else \
+ builtin_define ("CPU=ARMARCH4"); \
+ } \
+ } while (0)
+
+#undef CC1_SPEC
+#define CC1_SPEC \
+"%{t4: -mapcs-32 -mlittle-endian -march=armv4 ; \
+ t4be: -mapcs-32 -mbig-endian -march=armv4 ; \
+ t4t: -mthumb -mthumb-interwork -mlittle-endian -march=armv4t ; \
+ t4tbe: -mthumb -mthumb-interwork -mbig-endian -march=armv4t ; \
+ t5: -mapcs-32 -mlittle-endian -march=armv5 ; \
+ t5be: -mapcs-32 -mbig-endian -march=armv5 ; \
+ t5t: -mthumb -mthumb-interwork -mlittle-endian -march=armv5 ; \
+ t5tbe: -mthumb -mthumb-interwork -mbig-endian -march=armv5 ; \
+ txscale: -mapcs-32 -mlittle-endian -mcpu=xscale ; \
+ txscalebe: -mapcs-32 -mbig-endian -mcpu=xscale ; \
+ : -march=armv4}"
+
+/* The -Q options from svr4.h aren't understood and must be removed. */
+#undef ASM_SPEC
+#define ASM_SPEC \
+ "%{v:-V} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
+
+/* VxWorks does all the library stuff itself. */
+#undef LIB_SPEC
+#define LIB_SPEC ""
+
+/* VxWorks uses object files, not loadable images. make linker just
+ combine objects. */
+#undef LINK_SPEC
+#define LINK_SPEC "-r"
+
+/* VxWorks provides the functionality of crt0.o and friends itself. */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC ""
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC ""
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fputs (" (ARM/VxWorks)", stderr);
+
+/* There is no default multilib. */
+#undef MULTILIB_DEFAULTS
+
+#undef ASM_FILE_START
+#define ASM_FILE_START(STREAM) \
+ do \
+ { \
+ fprintf (STREAM, "%s Generated by GCC %s for ARM/VxWorks\n", \
+ ASM_COMMENT_START, version_string); \
+ } \
+ while (0)
diff --git a/contrib/gcc/config/arm/wince-pe.h b/contrib/gcc/config/arm/wince-pe.h
new file mode 100644
index 000000000000..fb474853fdb0
--- /dev/null
+++ b/contrib/gcc/config/arm/wince-pe.h
@@ -0,0 +1,29 @@
+/* Definitions of target machine for GNU compiler, for ARM with WINCE-PE obj format.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by Nick Clifton <nickc@redhat.com>
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Override arm/pe.h's default apcs26 support. */
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (ARM_FLAG_APCS_32 | ARM_FLAG_SOFT_FLOAT | TARGET_FLAG_NOP_FUN | ARM_FLAG_MMU_TRAPS)
+
+#undef MULTILIB_DEFAULTS
+#define MULTILIB_DEFAULTS \
+ { "marm", "mlittle-endian", "msoft-float", "mapcs-32", "mno-thumb-interwork" }
diff --git a/contrib/gcc/config/arm/xscale-elf.h b/contrib/gcc/config/arm/xscale-elf.h
index 8ea35885b6d1..aea8360dba8b 100644
--- a/contrib/gcc/config/arm/xscale-elf.h
+++ b/contrib/gcc/config/arm/xscale-elf.h
@@ -2,22 +2,22 @@
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
Contributed by Catherine Moore <clm@cygnus.com>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 this program; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Run-time Target Specification. */
#ifndef TARGET_VERSION
@@ -28,7 +28,30 @@ Boston, MA 02111-1307, USA. */
#define SUBTARGET_CPU_DEFAULT TARGET_CPU_xscale
#endif
-#define SUBTARGET_EXTRA_ASM_SPEC "%{!mcpu=*:-mcpu=xscale} %{!mhard-float:-mno-fpu}"
+/* Note - there are three possible -mfpu= arguments that can be passed to
+ the assembler:
+
+ -mfpu=softvfp This is the default. It indicates thats doubles are
+ stored in a format compatible with the VFP
+ specification. This is the newer double format, whereby
+ the endian-ness of the doubles matches the endian-ness
+ of the memory architecture.
+
+ -mfpu=fpa This is when -mhard-float is specified.
+ [It is not known if any XScale's have been made with
+ hardware floating point support, but nevertheless this
+ is what happens].
+
+ -mfpu=softfpa This is when -msoft-float is specified.
+ This is the normal behavior of other arm configurations,
+ which for backwards compatibility purposes default to
+ supporting the old FPA format which was always big
+ endian, regardless of the endian-ness of the memory
+ system. */
+
+#define SUBTARGET_EXTRA_ASM_SPEC "%{!mcpu=*:-mcpu=xscale} \
+ %{mhard-float:-mfpu=fpa} \
+ %{!mhard-float: %{msoft-float:-mfpu=softfpa;:-mfpu=softvfp}}"
#ifndef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS \
diff --git a/contrib/gcc/config/darwin-c.c b/contrib/gcc/config/darwin-c.c
index c04c2b576076..fb51455ae624 100644
--- a/contrib/gcc/config/darwin-c.c
+++ b/contrib/gcc/config/darwin-c.c
@@ -1,27 +1,28 @@
/* Darwin support needed only by C/C++ frontends.
- Copyright (C) 2001
- Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "cpplib.h"
#include "tree.h"
#include "c-pragma.h"
@@ -36,8 +37,8 @@ Boston, MA 02111-1307, USA. */
/* Maintain a small stack of alignments. This is similar to pragma
pack's stack, but simpler. */
-static void push_field_alignment PARAMS ((int));
-static void pop_field_alignment PARAMS ((void));
+static void push_field_alignment (int);
+static void pop_field_alignment (void);
typedef struct align_stack
{
@@ -48,8 +49,7 @@ typedef struct align_stack
static struct align_stack * field_align_stack = NULL;
static void
-push_field_alignment (bit_alignment)
- int bit_alignment;
+push_field_alignment (int bit_alignment)
{
align_stack *entry = (align_stack *) xmalloc (sizeof (align_stack));
@@ -61,7 +61,7 @@ push_field_alignment (bit_alignment)
}
static void
-pop_field_alignment ()
+pop_field_alignment (void)
{
if (field_align_stack)
{
@@ -78,8 +78,7 @@ pop_field_alignment ()
/* Handlers for Darwin-specific pragmas. */
void
-darwin_pragma_ignore (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+darwin_pragma_ignore (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
/* Do nothing. */
}
@@ -87,8 +86,7 @@ darwin_pragma_ignore (pfile)
/* #pragma options align={mac68k|power|reset} */
void
-darwin_pragma_options (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+darwin_pragma_options (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
const char *arg;
tree t, x;
@@ -120,8 +118,7 @@ darwin_pragma_options (pfile)
/* #pragma unused ([var {, var}*]) */
void
-darwin_pragma_unused (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+darwin_pragma_unused (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
tree decl, x;
int tok;
@@ -134,7 +131,7 @@ darwin_pragma_unused (pfile)
tok = c_lex (&decl);
if (tok == CPP_NAME && decl)
{
- tree local = IDENTIFIER_LOCAL_VALUE (decl);
+ tree local = lookup_name (decl);
if (local && (TREE_CODE (local) == PARM_DECL
|| TREE_CODE (local) == VAR_DECL))
TREE_USED (local) = 1;
diff --git a/contrib/gcc/config/darwin-protos.h b/contrib/gcc/config/darwin-protos.h
index 5fea152eeb91..41bad646ce1a 100644
--- a/contrib/gcc/config/darwin-protos.h
+++ b/contrib/gcc/config/darwin-protos.h
@@ -1,119 +1,123 @@
/* Prototypes.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-extern int name_needs_quotes PARAMS ((const char *));
+extern int name_needs_quotes (const char *);
-extern void machopic_validate_stub_or_non_lazy_ptr PARAMS ((const char *, int));
+extern void machopic_validate_stub_or_non_lazy_ptr (const char *, int);
-extern const char *machopic_function_base_name PARAMS ((void));
-extern const char *machopic_non_lazy_ptr_name PARAMS ((const char*));
-extern const char *machopic_stub_name PARAMS ((const char*));
+extern const char *machopic_function_base_name (void);
+extern void machopic_output_function_base_name (FILE *);
+extern const char *machopic_stub_name (const char*);
-extern void machopic_picsymbol_stub_section PARAMS ((void));
-extern void machopic_symbol_stub_section PARAMS ((void));
-extern void machopic_lazy_symbol_ptr_section PARAMS ((void));
-extern void machopic_nl_symbol_ptr_section PARAMS ((void));
+extern void machopic_picsymbol_stub_section (void);
+extern void machopic_picsymbol_stub1_section (void);
+extern void machopic_symbol_stub_section (void);
+extern void machopic_symbol_stub1_section (void);
+extern void machopic_lazy_symbol_ptr_section (void);
+extern void machopic_nl_symbol_ptr_section (void);
-extern void constructor_section PARAMS ((void));
-extern void destructor_section PARAMS ((void));
-extern void mod_init_section PARAMS ((void));
-extern void mod_term_section PARAMS ((void));
+extern void constructor_section (void);
+extern void destructor_section (void);
+extern void mod_init_section (void);
+extern void mod_term_section (void);
#ifdef RTX_CODE
-extern int machopic_operand_p PARAMS ((rtx));
-extern enum machopic_addr_class machopic_classify_name PARAMS ((const char*));
+extern int machopic_operand_p (rtx);
+extern enum machopic_addr_class machopic_classify_name (const char*);
-extern rtx machopic_indirect_data_reference PARAMS ((rtx, rtx));
-extern rtx machopic_indirect_call_target PARAMS ((rtx));
-extern rtx machopic_legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
+extern rtx machopic_indirect_data_reference (rtx, rtx);
+extern rtx machopic_indirect_call_target (rtx);
+extern rtx machopic_legitimize_pic_address (rtx, enum machine_mode, rtx);
-extern void machopic_asm_out_constructor PARAMS ((rtx, int));
-extern void machopic_asm_out_destructor PARAMS ((rtx, int));
+extern void machopic_asm_out_constructor (rtx, int);
+extern void machopic_asm_out_destructor (rtx, int);
#endif /* RTX_CODE */
#ifdef TREE_CODE
-extern enum machopic_addr_class machopic_classify_ident PARAMS ((tree));
-extern void machopic_define_ident PARAMS ((tree));
-extern void machopic_define_name PARAMS ((const char*));
-extern int machopic_name_defined_p PARAMS ((const char*));
-extern int machopic_ident_defined_p PARAMS ((tree));
-extern void darwin_encode_section_info PARAMS ((tree, int));
-extern const char *darwin_strip_name_encoding PARAMS ((const char *));
+extern enum machopic_addr_class machopic_classify_ident (tree);
+extern void machopic_define_ident (tree);
+extern void machopic_define_name (const char*);
+extern int machopic_name_defined_p (const char*);
+extern int machopic_ident_defined_p (tree);
+extern void darwin_encode_section_info (tree, rtx, int);
+extern const char *darwin_strip_name_encoding (const char *);
#endif /* TREE_CODE */
-extern void machopic_finish PARAMS ((FILE *));
+extern void machopic_finish (FILE *);
-extern void machopic_output_possible_stub_label PARAMS ((FILE *, const char*));
+extern void machopic_output_possible_stub_label (FILE *, const char*);
-extern void darwin_exception_section PARAMS ((void));
-extern void darwin_eh_frame_section PARAMS ((void));
-extern void machopic_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT));
-extern void machopic_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
+extern void darwin_exception_section (void);
+extern void darwin_eh_frame_section (void);
+extern void machopic_select_section (tree, int, unsigned HOST_WIDE_INT);
+extern void machopic_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
-#ifdef GCC_C_PRAGMA_H
-extern void darwin_pragma_ignore PARAMS ((cpp_reader *));
-extern void darwin_pragma_options PARAMS ((cpp_reader *));
-extern void darwin_pragma_unused PARAMS ((cpp_reader *));
-#endif
+extern void darwin_pragma_ignore (struct cpp_reader *);
+extern void darwin_pragma_options (struct cpp_reader *);
+extern void darwin_pragma_unused (struct cpp_reader *);
+
+extern void darwin_file_end (void);
/* Expanded by EXTRA_SECTION_FUNCTIONS into varasm.o. */
-extern void const_section PARAMS ((void));
-extern void const_data_section PARAMS ((void));
-extern void cstring_section PARAMS ((void));
-extern void literal4_section PARAMS ((void));
-extern void literal8_section PARAMS ((void));
-extern void constructor_section PARAMS ((void));
-extern void mod_init_section PARAMS ((void));
-extern void mod_term_section PARAMS ((void));
-extern void destructor_section PARAMS ((void));
-extern void objc_class_section PARAMS ((void));
-extern void objc_meta_class_section PARAMS ((void));
-extern void objc_category_section PARAMS ((void));
-extern void objc_class_vars_section PARAMS ((void));
-extern void objc_instance_vars_section PARAMS ((void));
-extern void objc_cls_meth_section PARAMS ((void));
-extern void objc_inst_meth_section PARAMS ((void));
-extern void objc_cat_cls_meth_section PARAMS ((void));
-extern void objc_cat_inst_meth_section PARAMS ((void));
-extern void objc_selector_refs_section PARAMS ((void));
-extern void objc_selector_fixup_section PARAMS ((void));
-extern void objc_symbols_section PARAMS ((void));
-extern void objc_module_info_section PARAMS ((void));
-extern void objc_protocol_section PARAMS ((void));
-extern void objc_string_object_section PARAMS ((void));
-extern void objc_constant_string_object_section PARAMS ((void));
-extern void objc_class_names_section PARAMS ((void));
-extern void objc_meth_var_names_section PARAMS ((void));
-extern void objc_meth_var_types_section PARAMS ((void));
-extern void objc_cls_refs_section PARAMS ((void));
-extern void machopic_lazy_symbol_ptr_section PARAMS ((void));
-extern void machopic_nl_symbol_ptr_section PARAMS ((void));
-extern void machopic_symbol_stub_section PARAMS ((void));
-extern void machopic_picsymbol_stub_section PARAMS ((void));
-extern void machopic_output_stub PARAMS ((FILE *, const char *, const char *));
-extern void darwin_exception_section PARAMS ((void));
-extern void darwin_eh_frame_section PARAMS ((void));
-extern void darwin_globalize_label PARAMS ((FILE *, const char *));
-extern void darwin_asm_output_dwarf_delta PARAMS ((FILE *, int, const char *, const char *));
+extern void const_section (void);
+extern void const_data_section (void);
+extern void cstring_section (void);
+extern void literal4_section (void);
+extern void literal8_section (void);
+extern void constructor_section (void);
+extern void mod_init_section (void);
+extern void mod_term_section (void);
+extern void destructor_section (void);
+extern void objc_class_section (void);
+extern void objc_meta_class_section (void);
+extern void objc_category_section (void);
+extern void objc_class_vars_section (void);
+extern void objc_instance_vars_section (void);
+extern void objc_cls_meth_section (void);
+extern void objc_inst_meth_section (void);
+extern void objc_cat_cls_meth_section (void);
+extern void objc_cat_inst_meth_section (void);
+extern void objc_selector_refs_section (void);
+extern void objc_selector_fixup_section (void);
+extern void objc_symbols_section (void);
+extern void objc_module_info_section (void);
+extern void objc_image_info_section (void);
+extern void objc_protocol_section (void);
+extern void objc_string_object_section (void);
+extern void objc_constant_string_object_section (void);
+extern void objc_class_names_section (void);
+extern void objc_meth_var_names_section (void);
+extern void objc_meth_var_types_section (void);
+extern void objc_cls_refs_section (void);
+extern void machopic_lazy_symbol_ptr_section (void);
+extern void machopic_nl_symbol_ptr_section (void);
+extern void machopic_symbol_stub_section (void);
+extern void machopic_picsymbol_stub_section (void);
+extern void machopic_output_stub (FILE *, const char *, const char *);
+extern void darwin_exception_section (void);
+extern void darwin_eh_frame_section (void);
+extern void darwin_globalize_label (FILE *, const char *);
+extern void darwin_assemble_visibility (tree, int);
+extern void darwin_asm_output_dwarf_delta (FILE *, int, const char *,
+ const char *);
diff --git a/contrib/gcc/config/darwin.c b/contrib/gcc/config/darwin.c
index 8efd8cd26122..8005ecd1e1d6 100644
--- a/contrib/gcc/config/darwin.c
+++ b/contrib/gcc/config/darwin.c
@@ -1,27 +1,29 @@
/* Functions for generic Darwin as target machine for GNU C compiler.
- Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -39,23 +41,24 @@ Boston, MA 02111-1307, USA. */
#include "ggc.h"
#include "langhooks.h"
#include "tm_p.h"
+#include "errors.h"
-static int machopic_data_defined_p PARAMS ((const char *));
-static void update_non_lazy_ptrs PARAMS ((const char *));
-static void update_stubs PARAMS ((const char *));
+static int machopic_data_defined_p (const char *);
+static void update_non_lazy_ptrs (const char *);
+static void update_stubs (const char *);
+static const char *machopic_non_lazy_ptr_name (const char*);
int
-name_needs_quotes (name)
- const char *name;
+name_needs_quotes (const char *name)
{
int c;
while ((c = *name++) != '\0')
- if (! ISIDNUM (c))
+ if (! ISIDNUM (c) && c != '.' && c != '$')
return 1;
return 0;
}
-/*
+/*
* flag_pic = 1 ... generate only indirections
* flag_pic = 2 ... generate indirections and pure code
*/
@@ -66,20 +69,23 @@ name_needs_quotes (name)
static GTY(()) tree machopic_defined_list;
enum machopic_addr_class
-machopic_classify_ident (ident)
- tree ident;
+machopic_classify_ident (tree ident)
{
const char *name = IDENTIFIER_POINTER (ident);
int lprefix = (((name[0] == '*' || name[0] == '&')
&& (name[1] == 'L' || (name[1] == '"' && name[2] == 'L')))
- || ( name[0] == '_'
- && name[1] == 'O'
- && name[2] == 'B'
+ || ( name[0] == '_'
+ && name[1] == 'O'
+ && name[2] == 'B'
&& name[3] == 'J'
&& name[4] == 'C'
&& name[5] == '_'));
tree temp;
+ /* The PIC base symbol is always defined. */
+ if (! strcmp (name, "<pic base>"))
+ return MACHOPIC_DEFINED_DATA;
+
if (name[0] != '!')
{
/* Here if no special encoding to be found. */
@@ -140,7 +146,7 @@ machopic_classify_ident (ident)
return MACHOPIC_DEFINED_DATA;
}
}
-
+
if (name[1] == 't' || name[1] == 'T')
{
if (lprefix)
@@ -157,17 +163,15 @@ machopic_classify_ident (ident)
}
}
-
+
enum machopic_addr_class
-machopic_classify_name (name)
- const char *name;
+machopic_classify_name (const char *name)
{
return machopic_classify_ident (get_identifier (name));
}
int
-machopic_ident_defined_p (ident)
- tree ident;
+machopic_ident_defined_p (tree ident)
{
switch (machopic_classify_ident (ident))
{
@@ -181,8 +185,7 @@ machopic_ident_defined_p (ident)
}
static int
-machopic_data_defined_p (name)
- const char *name;
+machopic_data_defined_p (const char *name)
{
switch (machopic_classify_ident (get_identifier (name)))
{
@@ -194,63 +197,65 @@ machopic_data_defined_p (name)
}
int
-machopic_name_defined_p (name)
- const char *name;
+machopic_name_defined_p (const char *name)
{
return machopic_ident_defined_p (get_identifier (name));
}
void
-machopic_define_ident (ident)
- tree ident;
+machopic_define_ident (tree ident)
{
if (!machopic_ident_defined_p (ident))
- machopic_defined_list =
+ machopic_defined_list =
tree_cons (NULL_TREE, ident, machopic_defined_list);
}
void
-machopic_define_name (name)
- const char *name;
+machopic_define_name (const char *name)
{
machopic_define_ident (get_identifier (name));
}
-/* This is a static to make inline functions work. The rtx
- representing the PIC base symbol always points to here. */
-
-static char function_base[32];
-
-static int current_pic_label_num;
+static GTY(()) char * function_base;
const char *
-machopic_function_base_name ()
+machopic_function_base_name (void)
{
- static const char *name = NULL;
- static const char *current_name;
+ const char *current_name;
+ /* if dynamic-no-pic is on, we should not get here */
+ if (MACHO_DYNAMIC_NO_PIC_P)
+ abort ();
+ current_name =
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
+
+ if (function_base == NULL)
+ function_base =
+ (char *) ggc_alloc_string ("<pic base>", sizeof ("<pic base>"));
+
+ current_function_uses_pic_offset_table = 1;
+
+ return function_base;
+}
- current_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
+static GTY(()) const char * function_base_func_name;
+static GTY(()) int current_pic_label_num;
- if (name != current_name)
+void
+machopic_output_function_base_name (FILE *file)
+{
+ const char *current_name;
+
+ /* If dynamic-no-pic is on, we should not get here. */
+ if (MACHO_DYNAMIC_NO_PIC_P)
+ abort ();
+ current_name =
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
+ if (function_base_func_name != current_name)
{
- current_function_uses_pic_offset_table = 1;
-
- /* Save mucho space and time. Some of the C++ mangled names are over
- 700 characters long! Note that we produce a label containing a '-'
- if the function we're compiling is an Objective-C method, as evinced
- by the incredibly scientific test below. This is because code in
- rs6000.c makes the same ugly test when loading the PIC reg. */
-
++current_pic_label_num;
- if (*current_name == '+' || *current_name == '-')
- sprintf (function_base, "*\"L-%d$pb\"", current_pic_label_num);
- else
- sprintf (function_base, "*L%d$pb", current_pic_label_num);
-
- name = current_name;
+ function_base_func_name = current_name;
}
-
- return function_base;
+ fprintf (file, "\"L%011d$pb\"", current_pic_label_num);
}
static GTY(()) tree machopic_non_lazy_pointers;
@@ -259,15 +264,14 @@ static GTY(()) tree machopic_non_lazy_pointers;
either by finding it in our list of pointer names, or by generating
a new one. */
-const char *
-machopic_non_lazy_ptr_name (name)
- const char *name;
+static const char *
+machopic_non_lazy_ptr_name (const char *name)
{
const char *temp_name;
tree temp, ident = get_identifier (name);
-
+
for (temp = machopic_non_lazy_pointers;
- temp != NULL_TREE;
+ temp != NULL_TREE;
temp = TREE_CHAIN (temp))
{
if (ident == TREE_VALUE (temp))
@@ -278,7 +282,7 @@ machopic_non_lazy_ptr_name (name)
/* Try again, but comparing names this time. */
for (temp = machopic_non_lazy_pointers;
- temp != NULL_TREE;
+ temp != NULL_TREE;
temp = TREE_CHAIN (temp))
{
if (TREE_VALUE (temp))
@@ -292,23 +296,31 @@ machopic_non_lazy_ptr_name (name)
{
char *buffer;
+ int namelen = strlen (name);
+ int bufferlen = 0;
tree ptr_name;
- buffer = alloca (strlen (name) + 20);
+ buffer = alloca (namelen + strlen("$non_lazy_ptr") + 5);
strcpy (buffer, "&L");
+ bufferlen = 2;
if (name[0] == '*')
- strcat (buffer, name+1);
+ {
+ memcpy (buffer + bufferlen, name+1, namelen-1+1);
+ bufferlen += namelen-1;
+ }
else
{
- strcat (buffer, "_");
- strcat (buffer, name);
+ buffer[bufferlen] = '_';
+ memcpy (buffer + bufferlen +1, name, namelen+1);
+ bufferlen += namelen +1;
}
-
- strcat (buffer, "$non_lazy_ptr");
+
+ memcpy (buffer + bufferlen, "$non_lazy_ptr", strlen("$non_lazy_ptr")+1);
+ bufferlen += strlen("$non_lazy_ptr");
ptr_name = get_identifier (buffer);
- machopic_non_lazy_pointers
+ machopic_non_lazy_pointers
= tree_cons (ptr_name, ident, machopic_non_lazy_pointers);
TREE_USED (machopic_non_lazy_pointers) = 0;
@@ -322,15 +334,14 @@ static GTY(()) tree machopic_stubs;
/* Return the name of the stub corresponding to the given name,
generating a new stub name if necessary. */
-const char *
-machopic_stub_name (name)
- const char *name;
+const char *
+machopic_stub_name (const char *name)
{
tree temp, ident = get_identifier (name);
const char *tname;
for (temp = machopic_stubs;
- temp != NULL_TREE;
+ temp != NULL_TREE;
temp = TREE_CHAIN (temp))
{
if (ident == TREE_VALUE (temp))
@@ -350,29 +361,46 @@ machopic_stub_name (name)
{
char *buffer;
+ int bufferlen = 0;
+ int namelen = strlen (name);
tree ptr_name;
int needs_quotes = name_needs_quotes (name);
- buffer = alloca (strlen (name) + 20);
+ buffer = alloca (namelen + 20);
if (needs_quotes)
- strcpy (buffer, "&\"L");
+ {
+ strcpy (buffer, "&\"L");
+ bufferlen = strlen("&\"L");
+ }
else
- strcpy (buffer, "&L");
+ {
+ strcpy (buffer, "&L");
+ bufferlen = strlen("&L");
+ }
+
if (name[0] == '*')
{
- strcat (buffer, name+1);
+ memcpy (buffer + bufferlen, name+1, namelen - 1 +1);
+ bufferlen += namelen - 1;
}
else
{
- strcat (buffer, "_");
- strcat (buffer, name);
+ buffer[bufferlen] = '_';
+ memcpy (buffer + bufferlen +1, name, namelen+1);
+ bufferlen += namelen +1;
}
if (needs_quotes)
- strcat (buffer, "$stub\"");
+ {
+ memcpy (buffer + bufferlen, "$stub\"", strlen("$stub\"")+1);
+ bufferlen += strlen("$stub\"");
+ }
else
- strcat (buffer, "$stub");
+ {
+ memcpy (buffer + bufferlen, "$stub", strlen("$stub")+1);
+ bufferlen += strlen("$stub");
+ }
ptr_name = get_identifier (buffer);
machopic_stubs = tree_cons (ptr_name, ident, machopic_stubs);
@@ -383,9 +411,7 @@ machopic_stub_name (name)
}
void
-machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
- const char *name;
- int validate_stub;
+machopic_validate_stub_or_non_lazy_ptr (const char *name, int validate_stub)
{
const char *real_name;
tree temp, ident = get_identifier (name), id2;
@@ -399,12 +425,12 @@ machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
original symbol as being referenced. */
TREE_USED (temp) = 1;
if (TREE_CODE (TREE_VALUE (temp)) == IDENTIFIER_NODE)
- TREE_SYMBOL_REFERENCED (TREE_VALUE (temp)) = 1;
+ mark_referenced (TREE_VALUE (temp));
real_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
real_name = darwin_strip_name_encoding (real_name);
id2 = maybe_get_identifier (real_name);
if (id2)
- TREE_SYMBOL_REFERENCED (id2) = 1;
+ mark_referenced (id2);
}
}
@@ -412,59 +438,69 @@ machopic_validate_stub_or_non_lazy_ptr (name, validate_stub)
source using indirections. */
rtx
-machopic_indirect_data_reference (orig, reg)
- rtx orig, reg;
+machopic_indirect_data_reference (rtx orig, rtx reg)
{
rtx ptr_ref = orig;
-
+
if (! MACHOPIC_INDIRECT)
return orig;
if (GET_CODE (orig) == SYMBOL_REF)
{
const char *name = XSTR (orig, 0);
+ int defined = machopic_data_defined_p (name);
- if (machopic_data_defined_p (name))
+ if (defined && MACHO_DYNAMIC_NO_PIC_P)
+ {
+#if defined (TARGET_TOC)
+ emit_insn (gen_macho_high (reg, orig));
+ emit_insn (gen_macho_low (reg, reg, orig));
+#else
+ /* some other cpu -- writeme! */
+ abort ();
+#endif
+ return reg;
+ }
+ else if (defined)
{
#if defined (TARGET_TOC) || defined (HAVE_lo_sum)
- rtx pic_base = gen_rtx (SYMBOL_REF, Pmode,
- machopic_function_base_name ());
- rtx offset = gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode, orig, pic_base));
+ rtx pic_base = gen_rtx_SYMBOL_REF (Pmode,
+ machopic_function_base_name ());
+ rtx offset = gen_rtx_CONST (Pmode,
+ gen_rtx_MINUS (Pmode, orig, pic_base));
#endif
#if defined (TARGET_TOC) /* i.e., PowerPC */
- rtx hi_sum_reg = reg;
+ rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
if (reg == NULL)
abort ();
- emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
- gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
- gen_rtx (HIGH, Pmode, offset))));
- emit_insn (gen_rtx (SET, Pmode, reg,
- gen_rtx (LO_SUM, Pmode, hi_sum_reg, offset)));
+ emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
+ gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
+ gen_rtx_HIGH (Pmode, offset))));
+ emit_insn (gen_rtx_SET (Pmode, reg,
+ gen_rtx_LO_SUM (Pmode, hi_sum_reg, offset)));
orig = reg;
#else
#if defined (HAVE_lo_sum)
if (reg == 0) abort ();
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (HIGH, Pmode, offset)));
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (LO_SUM, Pmode, reg, offset)));
- emit_insn (gen_rtx (USE, VOIDmode,
- gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_HIGH (Pmode, offset)));
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_LO_SUM (Pmode, reg, offset)));
+ emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
- orig = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, reg);
+ orig = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, reg);
#endif
#endif
return orig;
}
- ptr_ref = gen_rtx (SYMBOL_REF, Pmode,
- machopic_non_lazy_ptr_name (name));
+ ptr_ref = gen_rtx_SYMBOL_REF (Pmode,
+ machopic_non_lazy_ptr_name (name));
ptr_ref = gen_rtx_MEM (Pmode, ptr_ref);
RTX_UNCHANGING_P (ptr_ref) = 1;
@@ -483,13 +519,13 @@ machopic_indirect_data_reference (orig, reg)
orig = machopic_indirect_data_reference (XEXP (XEXP (orig, 0), 1),
(base == reg ? 0 : reg));
}
- else
+ else
return orig;
if (MACHOPIC_PURE && GET_CODE (orig) == CONST_INT)
result = plus_constant (base, INTVAL (orig));
else
- result = gen_rtx (PLUS, Pmode, base, orig);
+ result = gen_rtx_PLUS (Pmode, base, orig);
if (MACHOPIC_JUST_INDIRECT && GET_CODE (base) == MEM)
{
@@ -533,14 +569,13 @@ machopic_indirect_data_reference (orig, reg)
corresponding symbol_stub if necessary. Return a new MEM. */
rtx
-machopic_indirect_call_target (target)
- rtx target;
+machopic_indirect_call_target (rtx target)
{
if (GET_CODE (target) != MEM)
return target;
if (MACHOPIC_INDIRECT && GET_CODE (XEXP (target, 0)) == SYMBOL_REF)
- {
+ {
enum machine_mode mode = GET_MODE (XEXP (target, 0));
const char *name = XSTR (XEXP (target, 0), 0);
@@ -552,22 +587,20 @@ machopic_indirect_call_target (target)
{
const char *stub_name = machopic_stub_name (name);
- XEXP (target, 0) = gen_rtx (SYMBOL_REF, mode, stub_name);
+ XEXP (target, 0) = gen_rtx_SYMBOL_REF (mode, stub_name);
RTX_UNCHANGING_P (target) = 1;
- }
+ }
}
return target;
}
rtx
-machopic_legitimize_pic_address (orig, mode, reg)
- rtx orig, reg;
- enum machine_mode mode;
+machopic_legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
{
rtx pic_ref = orig;
- if (! MACHOPIC_PURE)
+ if (! MACHOPIC_INDIRECT)
return orig;
/* First handle a simple SYMBOL_REF or LABEL_REF */
@@ -580,7 +613,7 @@ machopic_legitimize_pic_address (orig, mode, reg)
orig = machopic_indirect_data_reference (orig, reg);
- if (GET_CODE (orig) == PLUS
+ if (GET_CODE (orig) == PLUS
&& GET_CODE (XEXP (orig, 0)) == REG)
{
if (reg == 0)
@@ -588,9 +621,13 @@ machopic_legitimize_pic_address (orig, mode, reg)
emit_move_insn (reg, orig);
return reg;
- }
+ }
- pic_base = gen_rtx (SYMBOL_REF, Pmode, machopic_function_base_name ());
+ /* if dynamic-no-pic then use 0 as the pic base */
+ if (MACHO_DYNAMIC_NO_PIC_P)
+ pic_base = CONST0_RTX (Pmode);
+ else
+ pic_base = gen_rtx_SYMBOL_REF (Pmode, machopic_function_base_name ());
if (GET_CODE (orig) == MEM)
{
@@ -601,42 +638,73 @@ machopic_legitimize_pic_address (orig, mode, reg)
else
reg = gen_reg_rtx (Pmode);
}
-
+
#ifdef HAVE_lo_sum
- if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
+ if (MACHO_DYNAMIC_NO_PIC_P
+ && (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (orig, 0)) == LABEL_REF))
+ {
+#if defined (TARGET_TOC) /* ppc */
+ rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
+ rtx asym = XEXP (orig, 0);
+ rtx mem;
+
+ emit_insn (gen_macho_high (temp_reg, asym));
+ mem = gen_rtx_MEM (GET_MODE (orig),
+ gen_rtx_LO_SUM (Pmode, temp_reg, asym));
+ RTX_UNCHANGING_P (mem) = 1;
+ emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
+#else
+ /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
+ abort ();
+#endif
+ pic_ref = reg;
+ }
+ else
+ if (GET_CODE (XEXP (orig, 0)) == SYMBOL_REF
|| GET_CODE (XEXP (orig, 0)) == LABEL_REF)
{
- rtx offset = gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode,
- XEXP (orig, 0), pic_base));
+ rtx offset = gen_rtx_CONST (Pmode,
+ gen_rtx_MINUS (Pmode,
+ XEXP (orig, 0),
+ pic_base));
#if defined (TARGET_TOC) /* i.e., PowerPC */
/* Generating a new reg may expose opportunities for
common subexpression elimination. */
- rtx hi_sum_reg =
- (reload_in_progress ? reg : gen_reg_rtx (SImode));
-
- emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
- gen_rtx (PLUS, Pmode,
- pic_offset_table_rtx,
- gen_rtx (HIGH, Pmode, offset))));
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (MEM, GET_MODE (orig),
- gen_rtx (LO_SUM, Pmode,
- hi_sum_reg, offset))));
- pic_ref = reg;
+ rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (SImode);
+ rtx mem;
+ rtx insn;
+ rtx sum;
+
+ sum = gen_rtx_HIGH (Pmode, offset);
+ if (! MACHO_DYNAMIC_NO_PIC_P)
+ sum = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, sum);
+
+ emit_insn (gen_rtx_SET (Pmode, hi_sum_reg, sum));
+
+ mem = gen_rtx_MEM (GET_MODE (orig),
+ gen_rtx_LO_SUM (Pmode,
+ hi_sum_reg, offset));
+ RTX_UNCHANGING_P (mem) = 1;
+ insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
+ REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
+ REG_NOTES (insn));
+ pic_ref = reg;
#else
- emit_insn (gen_rtx (USE, VOIDmode,
- gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM)));
-
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (HIGH, Pmode,
- gen_rtx (CONST, Pmode, offset))));
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (LO_SUM, Pmode, reg,
- gen_rtx (CONST, Pmode, offset))));
- pic_ref = gen_rtx (PLUS, Pmode,
- pic_offset_table_rtx, reg);
+ emit_insn (gen_rtx_USE (VOIDmode,
+ gen_rtx_REG (Pmode,
+ PIC_OFFSET_TABLE_REGNUM)));
+
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_HIGH (Pmode,
+ gen_rtx_CONST (Pmode,
+ offset))));
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_LO_SUM (Pmode, reg,
+ gen_rtx_CONST (Pmode, offset))));
+ pic_ref = gen_rtx_PLUS (Pmode,
+ pic_offset_table_rtx, reg);
#endif
}
else
@@ -649,21 +717,22 @@ machopic_legitimize_pic_address (orig, mode, reg)
pic = reg;
}
#if 0
- emit_insn (gen_rtx (USE, VOIDmode,
- gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM)));
+ emit_insn (gen_rtx_USE (VOIDmode,
+ gen_rtx_REG (Pmode,
+ PIC_OFFSET_TABLE_REGNUM)));
#endif
- pic_ref = gen_rtx (PLUS, Pmode,
- pic,
- gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode,
- XEXP (orig, 0),
- pic_base)));
+ pic_ref = gen_rtx_PLUS (Pmode,
+ pic,
+ gen_rtx_CONST (Pmode,
+ gen_rtx_MINUS (Pmode,
+ XEXP (orig, 0),
+ pic_base)));
}
-
+
#if !defined (TARGET_TOC)
emit_move_insn (reg, pic_ref);
- pic_ref = gen_rtx (MEM, GET_MODE (orig), reg);
+ pic_ref = gen_rtx_MEM (GET_MODE (orig), reg);
#endif
RTX_UNCHANGING_P (pic_ref) = 1;
}
@@ -671,11 +740,12 @@ machopic_legitimize_pic_address (orig, mode, reg)
{
#ifdef HAVE_lo_sum
- if (GET_CODE (orig) == SYMBOL_REF
+ if (GET_CODE (orig) == SYMBOL_REF
|| GET_CODE (orig) == LABEL_REF)
{
- rtx offset = gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode, orig, pic_base));
+ rtx offset = gen_rtx_CONST (Pmode,
+ gen_rtx_MINUS (Pmode,
+ orig, pic_base));
#if defined (TARGET_TOC) /* i.e., PowerPC */
rtx hi_sum_reg;
@@ -686,25 +756,28 @@ machopic_legitimize_pic_address (orig, mode, reg)
else
reg = gen_reg_rtx (SImode);
}
-
+
hi_sum_reg = reg;
- emit_insn (gen_rtx (SET, Pmode, hi_sum_reg,
- gen_rtx (PLUS, Pmode,
- pic_offset_table_rtx,
- gen_rtx (HIGH, Pmode, offset))));
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (LO_SUM, Pmode,
- hi_sum_reg, offset)));
+ emit_insn (gen_rtx_SET (Pmode, hi_sum_reg,
+ (MACHO_DYNAMIC_NO_PIC_P)
+ ? gen_rtx_HIGH (Pmode, offset)
+ : gen_rtx_PLUS (Pmode,
+ pic_offset_table_rtx,
+ gen_rtx_HIGH (Pmode,
+ offset))));
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_LO_SUM (Pmode,
+ hi_sum_reg, offset)));
pic_ref = reg;
RTX_UNCHANGING_P (pic_ref) = 1;
#else
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (HIGH, Pmode, offset)));
- emit_insn (gen_rtx (SET, VOIDmode, reg,
- gen_rtx (LO_SUM, Pmode, reg, offset)));
- pic_ref = gen_rtx (PLUS, Pmode,
- pic_offset_table_rtx, reg);
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_HIGH (Pmode, offset)));
+ emit_insn (gen_rtx_SET (VOIDmode, reg,
+ gen_rtx_LO_SUM (Pmode, reg, offset)));
+ pic_ref = gen_rtx_PLUS (Pmode,
+ pic_offset_table_rtx, reg);
RTX_UNCHANGING_P (pic_ref) = 1;
#endif
}
@@ -724,14 +797,14 @@ machopic_legitimize_pic_address (orig, mode, reg)
pic = reg;
}
#if 0
- emit_insn (gen_rtx (USE, VOIDmode,
- pic_offset_table_rtx));
+ emit_insn (gen_rtx_USE (VOIDmode,
+ pic_offset_table_rtx));
#endif
- pic_ref = gen_rtx (PLUS, Pmode,
- pic,
- gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode,
- orig, pic_base)));
+ pic_ref = gen_rtx_PLUS (Pmode,
+ pic,
+ gen_rtx_CONST (Pmode,
+ gen_rtx_MINUS (Pmode,
+ orig, pic_base)));
}
}
}
@@ -763,7 +836,7 @@ machopic_legitimize_pic_address (orig, mode, reg)
|| GET_CODE (XEXP (orig, 0)) == LABEL_REF)
&& XEXP (orig, 0) != pic_offset_table_rtx
&& GET_CODE (XEXP (orig, 1)) != REG)
-
+
{
rtx base;
int is_complex = (GET_CODE (XEXP (orig, 0)) == MEM);
@@ -777,7 +850,7 @@ machopic_legitimize_pic_address (orig, mode, reg)
is_complex = 1;
}
else
- pic_ref = gen_rtx (PLUS, Pmode, base, orig);
+ pic_ref = gen_rtx_PLUS (Pmode, base, orig);
if (RTX_UNCHANGING_P (base) && RTX_UNCHANGING_P (orig))
RTX_UNCHANGING_P (pic_ref) = 1;
@@ -800,7 +873,7 @@ machopic_legitimize_pic_address (orig, mode, reg)
{
rtx addr = machopic_legitimize_pic_address (XEXP (orig, 0), Pmode, reg);
- addr = gen_rtx (MEM, GET_MODE (orig), addr);
+ addr = gen_rtx_MEM (GET_MODE (orig), addr);
RTX_UNCHANGING_P (addr) = RTX_UNCHANGING_P (orig);
emit_move_insn (reg, addr);
pic_ref = reg;
@@ -811,8 +884,7 @@ machopic_legitimize_pic_address (orig, mode, reg)
void
-machopic_finish (asm_out_file)
- FILE *asm_out_file;
+machopic_finish (FILE *asm_out_file)
{
tree temp;
@@ -838,7 +910,7 @@ machopic_finish (asm_out_file)
if (sym_name[0] == '*' || sym_name[0] == '&')
strcpy (sym, sym_name + 1);
else if (sym_name[0] == '-' || sym_name[0] == '+')
- strcpy (sym, sym_name);
+ strcpy (sym, sym_name);
else
sym[0] = '_', strcpy (sym + 1, sym_name);
@@ -852,7 +924,7 @@ machopic_finish (asm_out_file)
}
for (temp = machopic_non_lazy_pointers;
- temp != NULL_TREE;
+ temp != NULL_TREE;
temp = TREE_CHAIN (temp))
{
const char *const sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
@@ -866,18 +938,18 @@ machopic_finish (asm_out_file)
data_section ();
assemble_align (GET_MODE_ALIGNMENT (Pmode));
assemble_label (lazy_name);
- assemble_integer (gen_rtx (SYMBOL_REF, Pmode, sym_name),
+ assemble_integer (gen_rtx_SYMBOL_REF (Pmode, sym_name),
GET_MODE_SIZE (Pmode),
GET_MODE_ALIGNMENT (Pmode), 1);
}
else
{
machopic_nl_symbol_ptr_section ();
- assemble_name (asm_out_file, lazy_name);
+ assemble_name (asm_out_file, lazy_name);
fprintf (asm_out_file, ":\n");
fprintf (asm_out_file, "\t.indirect_symbol ");
- assemble_name (asm_out_file, sym_name);
+ assemble_name (asm_out_file, sym_name);
fprintf (asm_out_file, "\n");
assemble_integer (const0_rtx, GET_MODE_SIZE (Pmode),
@@ -886,9 +958,8 @@ machopic_finish (asm_out_file)
}
}
-int
-machopic_operand_p (op)
- rtx op;
+int
+machopic_operand_p (rtx op)
{
if (MACHOPIC_JUST_INDIRECT)
{
@@ -919,9 +990,7 @@ machopic_operand_p (op)
use later. */
void
-darwin_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
+darwin_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
{
char code = '\0';
int defined = 0;
@@ -930,12 +999,18 @@ darwin_encode_section_info (decl, first)
char *new_str;
size_t len, new_len;
+ /* Do the standard encoding things first. */
+ default_encode_section_info (decl, rtl, first);
+
+ /* With the introduction of symbol_ref flags, some of the following
+ code has become redundant and should be removed at some point. */
+
if ((TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& !DECL_EXTERNAL (decl)
&& ((TREE_STATIC (decl)
&& (!DECL_COMMON (decl) || !TREE_PUBLIC (decl)))
- || (DECL_INITIAL (decl)
+ || (!DECL_COMMON (decl) && DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node)))
defined = 1;
@@ -947,7 +1022,7 @@ darwin_encode_section_info (decl, first)
if (code == '\0')
return;
- sym_ref = XEXP (DECL_RTL (decl), 0);
+ sym_ref = XEXP (rtl, 0);
orig_str = XSTR (sym_ref, 0);
len = strlen (orig_str) + 1;
@@ -985,8 +1060,7 @@ darwin_encode_section_info (decl, first)
/* Undo the effects of the above. */
const char *
-darwin_strip_name_encoding (str)
- const char *str;
+darwin_strip_name_encoding (const char *str)
{
return str[0] == '!' ? str + 4 : str;
}
@@ -995,8 +1069,7 @@ darwin_strip_name_encoding (str)
stripped name matches the argument. */
static void
-update_non_lazy_ptrs (name)
- const char *name;
+update_non_lazy_ptrs (const char *name)
{
const char *name1, *name2;
tree temp;
@@ -1004,7 +1077,7 @@ update_non_lazy_ptrs (name)
name1 = darwin_strip_name_encoding (name);
for (temp = machopic_non_lazy_pointers;
- temp != NULL_TREE;
+ temp != NULL_TREE;
temp = TREE_CHAIN (temp))
{
const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
@@ -1014,7 +1087,9 @@ update_non_lazy_ptrs (name)
name2 = darwin_strip_name_encoding (sym_name);
if (strcmp (name1, name2) == 0)
{
- IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
+ /* FIXME: This breaks the identifier hash table. */
+ IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
+ = (unsigned char *) name;
break;
}
}
@@ -1026,13 +1101,10 @@ update_non_lazy_ptrs (name)
just emit the stub label now and we don't bother emitting the stub later. */
void
-machopic_output_possible_stub_label (file, name)
- FILE *file;
- const char *name;
+machopic_output_possible_stub_label (FILE *file, const char *name)
{
tree temp;
-
/* Ensure we're looking at a section-encoded name. */
if (name[0] != '!' || (name[1] != 't' && name[1] != 'T'))
return;
@@ -1044,7 +1116,7 @@ machopic_output_possible_stub_label (file, name)
const char *sym_name;
sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
- if (sym_name[0] == '!' && sym_name[1] == 'T'
+ if (sym_name[0] == '!' && (sym_name[1] == 'T' || sym_name[1] == 't')
&& ! strcmp (name+2, sym_name+2))
{
ASM_OUTPUT_LABEL (file, IDENTIFIER_POINTER (TREE_PURPOSE (temp)));
@@ -1059,8 +1131,7 @@ machopic_output_possible_stub_label (file, name)
stripped name matches the argument. */
static void
-update_stubs (name)
- const char *name;
+update_stubs (const char *name)
{
const char *name1, *name2;
tree temp;
@@ -1068,7 +1139,7 @@ update_stubs (name)
name1 = darwin_strip_name_encoding (name);
for (temp = machopic_stubs;
- temp != NULL_TREE;
+ temp != NULL_TREE;
temp = TREE_CHAIN (temp))
{
const char *sym_name = IDENTIFIER_POINTER (TREE_VALUE (temp));
@@ -1078,7 +1149,9 @@ update_stubs (name)
name2 = darwin_strip_name_encoding (sym_name);
if (strcmp (name1, name2) == 0)
{
- IDENTIFIER_POINTER (TREE_VALUE (temp)) = name;
+ /* FIXME: This breaks the identifier hash table. */
+ IDENTIFIER_NODE_CHECK (TREE_VALUE (temp))->identifier.id.str
+ = (unsigned char *) name;
break;
}
}
@@ -1086,14 +1159,12 @@ update_stubs (name)
}
void
-machopic_select_section (exp, reloc, align)
- tree exp;
- int reloc;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+machopic_select_section (tree exp, int reloc,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
void (*base_function)(void);
-
- if (decl_readonly_section (exp, reloc))
+
+ if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
base_function = readonly_data_section;
else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
base_function = const_data_section;
@@ -1101,7 +1172,8 @@ machopic_select_section (exp, reloc, align)
base_function = data_section;
if (TREE_CODE (exp) == STRING_CST
- && TREE_STRING_LENGTH (exp) == strlen (TREE_STRING_POINTER (exp)) + 1
+ && ((size_t) TREE_STRING_LENGTH (exp)
+ == strlen (TREE_STRING_POINTER (exp)) + 1)
&& ! flag_writable_strings)
cstring_section ();
else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
@@ -1132,7 +1204,7 @@ machopic_select_section (exp, reloc, align)
objc_constant_string_object_section ();
else if (!strcmp (IDENTIFIER_POINTER (name), "NXConstantString"))
objc_string_object_section ();
- else
+ else
base_function ();
}
else if (TREE_CODE (exp) == VAR_DECL &&
@@ -1179,6 +1251,8 @@ machopic_select_section (exp, reloc, align)
objc_symbols_section ();
else if (!strncmp (name, "_OBJC_MODULES", 13))
objc_module_info_section ();
+ else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
+ objc_image_info_section ();
else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
objc_cat_inst_meth_section ();
else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
@@ -1187,10 +1261,10 @@ machopic_select_section (exp, reloc, align)
objc_cat_cls_meth_section ();
else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
objc_protocol_section ();
- else
+ else
base_function ();
}
- else
+ else
base_function ();
}
@@ -1198,10 +1272,8 @@ machopic_select_section (exp, reloc, align)
They must go in "const". */
void
-machopic_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+machopic_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
if (GET_MODE_SIZE (mode) == 8)
literal8_section ();
@@ -1209,51 +1281,73 @@ machopic_select_rtx_section (mode, x, align)
&& (GET_CODE (x) == CONST_INT
|| GET_CODE (x) == CONST_DOUBLE))
literal4_section ();
+ else if (MACHOPIC_INDIRECT
+ && (GET_CODE (x) == SYMBOL_REF
+ || GET_CODE (x) == CONST
+ || GET_CODE (x) == LABEL_REF))
+ const_data_section ();
else
const_section ();
}
void
-machopic_asm_out_constructor (symbol, priority)
- rtx symbol;
- int priority ATTRIBUTE_UNUSED;
+machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
mod_init_section ();
else
constructor_section ();
assemble_align (POINTER_SIZE);
assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
- if (!flag_pic)
+ if (! MACHOPIC_INDIRECT)
fprintf (asm_out_file, ".reference .constructors_used\n");
}
void
-machopic_asm_out_destructor (symbol, priority)
- rtx symbol;
- int priority ATTRIBUTE_UNUSED;
+machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
mod_term_section ();
else
destructor_section ();
assemble_align (POINTER_SIZE);
assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
- if (!flag_pic)
+ if (! MACHOPIC_INDIRECT)
fprintf (asm_out_file, ".reference .destructors_used\n");
}
void
-darwin_globalize_label (stream, name)
- FILE *stream;
- const char *name;
+darwin_globalize_label (FILE *stream, const char *name)
{
if (!!strncmp (name, "_OBJC_", 6))
default_globalize_label (stream, name);
}
+/* Emit an assembler directive to set visibility for a symbol. The
+ only supported visibilities are VISIBILITY_DEFAULT and
+ VISIBILITY_HIDDEN; the latter corresponds to Darwin's "private
+ extern". There is no MACH-O equivalent of ELF's
+ VISIBILITY_INTERNAL or VISIBILITY_PROTECTED. */
+
+void
+darwin_assemble_visibility (tree decl, int vis)
+{
+ if (vis == VISIBILITY_DEFAULT)
+ ;
+ else if (vis == VISIBILITY_HIDDEN)
+ {
+ fputs ("\t.private_extern ", asm_out_file);
+ assemble_name (asm_out_file,
+ (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
+ fputs ("\n", asm_out_file);
+ }
+ else
+ warning ("internal and protected visibility attributes not supported"
+ "in this configuration; ignored");
+}
+
/* Output a difference of two labels that will be an assembly time
constant if the two labels are local. (.long lab1-lab2 will be
very different if lab1 is at the boundary between two sections; it
@@ -1264,10 +1358,8 @@ darwin_globalize_label (stream, name)
static int darwin_dwarf_label_counter;
void
-darwin_asm_output_dwarf_delta (file, size, lab1, lab2)
- FILE *file;
- int size ATTRIBUTE_UNUSED;
- const char *lab1, *lab2;
+darwin_asm_output_dwarf_delta (FILE *file, int size ATTRIBUTE_UNUSED,
+ const char *lab1, const char *lab2)
{
const char *p = lab1 + (lab1[0] == '*');
int islocaldiff = (p[0] == 'L');
@@ -1283,5 +1375,16 @@ darwin_asm_output_dwarf_delta (file, size, lab1, lab2)
fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
}
-#include "gt-darwin.h"
+void
+darwin_file_end (void)
+{
+ machopic_finish (asm_out_file);
+ if (strcmp (lang_hooks.name, "GNU C++") == 0)
+ {
+ constructor_section ();
+ destructor_section ();
+ ASM_OUTPUT_ALIGN (asm_out_file, 1);
+ }
+}
+#include "gt-darwin.h"
diff --git a/contrib/gcc/config/darwin.h b/contrib/gcc/config/darwin.h
index c4b752696021..045091aff5e0 100644
--- a/contrib/gcc/config/darwin.h
+++ b/contrib/gcc/config/darwin.h
@@ -1,22 +1,22 @@
/* Target definitions for Darwin (Mac OS X) systems.
- Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -186,13 +186,16 @@ Boston, MA 02111-1307, USA. */
#define LINK_COMMAND_SPEC "\
%{!fdump=*:%{!fsyntax-only:%{!precomp:%{!c:%{!M:%{!MM:%{!E:%{!S:\
%{!Zdynamiclib:%(linker)}%{Zdynamiclib:/usr/bin/libtool} \
+ %{!Zdynamiclib:-arch %(darwin_arch)} \
+ %{Zdynamiclib:-arch_only %(darwin_arch)} \
%l %X %{d} %{s} %{t} %{Z} \
%{!Zdynamiclib:%{A} %{e*} %{m} %{N} %{n} %{r} %{u*} %{x} %{z}} \
%{@:-o %f%u.out}%{!@:%{o*}%{!o:-o a.out}} \
%{!Zdynamiclib:%{!A:%{!nostdlib:%{!nostartfiles:%S}}}} \
- %{L*} %(link_libgcc) %o %{!nostdlib:%{!nodefaultlibs:%G %L}} \
+ %{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate:-lgcov} \
+ %{!nostdlib:%{!nodefaultlibs:%G %L}} \
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} %{F*} \
- %{!--help:%{!no-c++filt|c++filt:| c++filt3 }} }}}}}}}}"
+ %{!--help:%{!no-c++filt|c++filt:| c++filt }} }}}}}}}}"
/* Please keep the random linker options in alphabetical order (modulo
'Z' and 'no' prefixes). Options that can only go to one of libtool
@@ -243,7 +246,7 @@ Boston, MA 02111-1307, USA. */
%{Zmulti_module:-multi_module} %{Zsingle_module:-single_module} \
%{Zmultiply_defined*:-multiply_defined %*} \
%{Zmultiplydefinedunused*:-multiply_defined_unused %*} \
- %{prebind} %{noprebind} %{prebind_all_twolevel_modules} \
+ %{prebind} %{noprebind} %{nofixprebinding} %{prebind_all_twolevel_modules} \
%{read_only_relocs} \
%{sectcreate*} %{sectorder*} %{seg1addr*} %{segprot*} %{seg_addr_table*} \
%{Zseg_addr_table_filename*:-seg_addr_table_filename %*} \
@@ -286,9 +289,6 @@ Boston, MA 02111-1307, USA. */
to put anything in ENDFILE_SPEC. */
/* #define ENDFILE_SPEC "" */
-#undef DOLLARS_IN_IDENTIFIERS
-#define DOLLARS_IN_IDENTIFIERS 2
-
/* We use Dbx symbol format. */
#define DBX_DEBUGGING_INFO 1
@@ -312,7 +312,7 @@ do { text_section (); \
/* Our profiling scheme doesn't LP labels and counter words. */
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS 1
#undef INIT_SECTION_ASM_OP
#define INIT_SECTION_ASM_OP
@@ -328,24 +328,14 @@ do { text_section (); \
/* Don't output a .file directive. That is only used by the assembler for
error reporting. */
+#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE false
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE)
-
-#undef ASM_FILE_END
-#define ASM_FILE_END(FILE) \
- do { \
- machopic_finish (asm_out_file); \
- if (strcmp (lang_hooks.name, "GNU C++") == 0) \
- { \
- constructor_section (); \
- destructor_section (); \
- ASM_OUTPUT_ALIGN (FILE, 1); \
- } \
- } while (0)
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END darwin_file_end
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.space %d\n", SIZE)
+ fprintf (FILE, "\t.space "HOST_WIDE_INT_PRINT_UNSIGNED"\n", SIZE)
/* Give ObjC methods pretty symbol names. */
@@ -368,19 +358,19 @@ do { text_section (); \
#undef ASM_DECLARE_OBJECT_NAME
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
do { \
- const char *xname = NAME; \
- if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF) \
- xname = IDENTIFIER_POINTER (DECL_NAME (DECL)); \
- if ((TREE_STATIC (DECL) \
- && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
- || DECL_INITIAL (DECL)) \
- machopic_define_name (xname); \
- if ((TREE_STATIC (DECL) \
- && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
- || DECL_INITIAL (DECL)) \
- (* targetm.encode_section_info) (DECL, false); \
- ASM_OUTPUT_LABEL (FILE, xname); \
- /* Darwin doesn't support zero-size objects, so give them a \
+ const char *xname = NAME; \
+ if (GET_CODE (XEXP (DECL_RTL (DECL), 0)) != SYMBOL_REF) \
+ xname = IDENTIFIER_POINTER (DECL_NAME (DECL)); \
+ if ((TREE_STATIC (DECL) \
+ && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
+ || DECL_INITIAL (DECL)) \
+ machopic_define_name (xname); \
+ if ((TREE_STATIC (DECL) \
+ && (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
+ || DECL_INITIAL (DECL)) \
+ (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false); \
+ ASM_OUTPUT_LABEL (FILE, xname); \
+ /* Darwin doesn't support zero-size objects, so give them a \
byte. */ \
if (tree_low_cst (DECL_SIZE_UNIT (DECL), 1) == 0) \
assemble_zeros (1); \
@@ -398,7 +388,7 @@ do { text_section (); \
if ((TREE_STATIC (DECL) \
&& (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
|| DECL_INITIAL (DECL)) \
- (* targetm.encode_section_info) (DECL, false); \
+ (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false); \
ASM_OUTPUT_LABEL (FILE, xname); \
/* Avoid generating stubs for functions we've just defined by \
outputting any required stub name label now. */ \
@@ -421,7 +411,9 @@ do { text_section (); \
#define ASM_OUTPUT_LABELREF(FILE,NAME) \
do { \
const char *xname = darwin_strip_name_encoding (NAME); \
- if (xname[0] == '&' || xname[0] == '*') \
+ if (! strcmp (xname, "<pic base>")) \
+ machopic_output_function_base_name(FILE); \
+ else if (xname[0] == '&' || xname[0] == '*') \
{ \
int len = strlen (xname); \
if (len > 6 && !strcmp ("$stub", xname + len - 5)) \
@@ -466,12 +458,12 @@ do { text_section (); \
do { \
fputs (".lcomm ", (FILE)); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u,%u\n", (SIZE), \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), \
floor_log2 ((ALIGN) / BITS_PER_UNIT)); \
if ((DECL) && ((TREE_STATIC (DECL) \
&& (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
|| DECL_INITIAL (DECL))) \
- (* targetm.encode_section_info) (DECL, false); \
+ (* targetm.encode_section_info) (DECL, DECL_RTL (DECL), false); \
if ((DECL) && ((TREE_STATIC (DECL) \
&& (!DECL_COMMON (DECL) || !TREE_PUBLIC (DECL))) \
|| DECL_INITIAL (DECL))) \
@@ -488,9 +480,9 @@ do { text_section (); \
#undef SECTION_FUNCTION
#define SECTION_FUNCTION(FUNCTION, SECTION, DIRECTIVE, OBJC) \
-extern void FUNCTION PARAMS ((void)); \
+extern void FUNCTION (void); \
void \
-FUNCTION () \
+FUNCTION (void) \
{ \
if (in_section != SECTION) \
{ \
@@ -518,18 +510,21 @@ FUNCTION () \
in_objc_symbols, in_objc_module_info, \
in_objc_protocol, in_objc_string_object, \
in_objc_constant_string_object, \
+ in_objc_image_info, \
in_objc_class_names, in_objc_meth_var_names, \
- in_objc_meth_var_types, in_objc_cls_refs, \
+ in_objc_meth_var_types, in_objc_cls_refs, \
in_machopic_nl_symbol_ptr, \
in_machopic_lazy_symbol_ptr, \
in_machopic_symbol_stub, \
+ in_machopic_symbol_stub1, \
in_machopic_picsymbol_stub, \
+ in_machopic_picsymbol_stub1, \
in_darwin_exception, in_darwin_eh_frame, \
num_sections
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
-static void objc_section_init PARAMS ((void)); \
+static void objc_section_init (void); \
SECTION_FUNCTION (const_section, \
in_const, \
".const", 0) \
@@ -605,6 +600,10 @@ SECTION_FUNCTION (objc_string_object_section, \
SECTION_FUNCTION (objc_constant_string_object_section, \
in_objc_constant_string_object, \
".section __OBJC, __cstring_object", 1) \
+/* Fix-and-Continue image marker. */ \
+SECTION_FUNCTION (objc_image_info_section, \
+ in_objc_image_info, \
+ ".section __OBJC, __image_info", 1) \
SECTION_FUNCTION (objc_class_names_section, \
in_objc_class_names, \
".objc_class_names", 1) \
@@ -620,16 +619,22 @@ SECTION_FUNCTION (objc_cls_refs_section, \
\
SECTION_FUNCTION (machopic_lazy_symbol_ptr_section, \
in_machopic_lazy_symbol_ptr, \
- ".lazy_symbol_pointer", 0) \
+ ".lazy_symbol_pointer", 0) \
SECTION_FUNCTION (machopic_nl_symbol_ptr_section, \
in_machopic_nl_symbol_ptr, \
- ".non_lazy_symbol_pointer", 0) \
+ ".non_lazy_symbol_pointer", 0) \
SECTION_FUNCTION (machopic_symbol_stub_section, \
in_machopic_symbol_stub, \
- ".symbol_stub", 0) \
+ ".symbol_stub", 0) \
+SECTION_FUNCTION (machopic_symbol_stub1_section, \
+ in_machopic_symbol_stub1, \
+ ".section __TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16", 0)\
SECTION_FUNCTION (machopic_picsymbol_stub_section, \
in_machopic_picsymbol_stub, \
- ".picsymbol_stub", 0) \
+ ".picsymbol_stub", 0) \
+SECTION_FUNCTION (machopic_picsymbol_stub1_section, \
+ in_machopic_picsymbol_stub1, \
+ ".section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32", 0)\
SECTION_FUNCTION (darwin_exception_section, \
in_darwin_exception, \
".section __DATA,__gcc_except_tab", 0) \
@@ -638,7 +643,7 @@ SECTION_FUNCTION (darwin_eh_frame_section, \
".section __TEXT,__eh_frame", 0) \
\
static void \
-objc_section_init () \
+objc_section_init (void) \
{ \
static int been_here = 0; \
\
@@ -655,7 +660,7 @@ objc_section_init () \
objc_cls_refs_section (); \
objc_class_section (); \
objc_meta_class_section (); \
- /* shared, hot -> cold */ \
+ /* shared, hot -> cold */ \
objc_cls_meth_section (); \
objc_inst_meth_section (); \
objc_protocol_section (); \
@@ -678,9 +683,9 @@ objc_section_init () \
#define TARGET_ASM_SELECT_RTX_SECTION machopic_select_rtx_section
#define ASM_DECLARE_UNRESOLVED_REFERENCE(FILE,NAME) \
- do { \
+ do { \
if (FILE) { \
- if (flag_pic) \
+ if (MACHOPIC_INDIRECT) \
fprintf (FILE, "\t.lazy_reference "); \
else \
fprintf (FILE, "\t.reference "); \
@@ -693,7 +698,7 @@ objc_section_init () \
do { \
if (FILE) { \
fprintf (FILE, "\t"); \
- assemble_name (FILE, NAME); \
+ assemble_name (FILE, NAME); \
fprintf (FILE, "=0\n"); \
(*targetm.asm_out.globalize_label) (FILE, NAME); \
} \
@@ -703,17 +708,17 @@ objc_section_init () \
#define GLOBAL_ASM_OP ".globl "
#define TARGET_ASM_GLOBALIZE_LABEL darwin_globalize_label
+/* Emit an assembler directive to set visibility for a symbol. Used
+ to support visibility attribute and Darwin's private extern
+ feature. */
+#undef TARGET_ASM_ASSEMBLE_VISIBILITY
+#define TARGET_ASM_ASSEMBLE_VISIBILITY darwin_assemble_visibility
+
+
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
sprintf (LABEL, "*%s%ld", PREFIX, (long)(NUM))
-/* This is how to output an internal numbered label where PREFIX is
- the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, "%s%d:\n", PREFIX, NUM)
-
/* Since we have a separate readonly data section, define this so that
jump tables end up in text rather than data. */
@@ -733,9 +738,10 @@ enum machopic_addr_class {
/* Macros defining the various PIC cases. */
-#define MACHOPIC_INDIRECT (flag_pic)
-#define MACHOPIC_JUST_INDIRECT (flag_pic == 1)
-#define MACHOPIC_PURE (flag_pic == 2)
+#define MACHO_DYNAMIC_NO_PIC_P (TARGET_DYNAMIC_NO_PIC)
+#define MACHOPIC_INDIRECT (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
+#define MACHOPIC_JUST_INDIRECT (flag_pic == 1 || MACHO_DYNAMIC_NO_PIC_P)
+#define MACHOPIC_PURE (flag_pic == 2 && ! MACHO_DYNAMIC_NO_PIC_P)
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO darwin_encode_section_info
@@ -801,7 +807,7 @@ enum machopic_addr_class {
#define TARGET_ASM_EXCEPTION_SECTION darwin_exception_section
#define TARGET_ASM_EH_FRAME_SECTION darwin_eh_frame_section
-
+
#undef ASM_PREFERRED_EH_DATA_FORMAT
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
(((CODE) == 2 && (GLOBAL) == 1) \
@@ -813,12 +819,12 @@ enum machopic_addr_class {
#define TARGET_TERMINATE_DW2_EH_FRAME_INFO false
-#define DARWIN_REGISTER_TARGET_PRAGMAS(PFILE) \
- do { \
- cpp_register_pragma (PFILE, 0, "mark", darwin_pragma_ignore); \
- cpp_register_pragma (PFILE, 0, "options", darwin_pragma_options); \
- cpp_register_pragma (PFILE, 0, "segment", darwin_pragma_ignore); \
- cpp_register_pragma (PFILE, 0, "unused", darwin_pragma_unused); \
+#define DARWIN_REGISTER_TARGET_PRAGMAS() \
+ do { \
+ c_register_pragma (0, "mark", darwin_pragma_ignore); \
+ c_register_pragma (0, "options", darwin_pragma_options); \
+ c_register_pragma (0, "segment", darwin_pragma_ignore); \
+ c_register_pragma (0, "unused", darwin_pragma_unused); \
} while (0)
#undef ASM_APP_ON
diff --git a/contrib/gcc/config/dbx.h b/contrib/gcc/config/dbx.h
index a9fededbc393..eb20452f48df 100644
--- a/contrib/gcc/config/dbx.h
+++ b/contrib/gcc/config/dbx.h
@@ -1,20 +1,20 @@
/* Prefer DBX (stabs) debugging information.
Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/dbxcoff.h b/contrib/gcc/config/dbxcoff.h
index b955932797c7..76a910f3225f 100644
--- a/contrib/gcc/config/dbxcoff.h
+++ b/contrib/gcc/config/dbxcoff.h
@@ -1,20 +1,20 @@
/* Definitions needed when using stabs embedded in COFF sections.
Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -55,23 +55,21 @@ Boston, MA 02111-1307, USA. */
current function. */
#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
+#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE, COUNTER) \
{ if (write_symbols == SDB_DEBUG) { \
fprintf ((FILE), "\t.ln\t%d\n", \
((sdb_begin_function_line > -1) \
? (LINE) - sdb_begin_function_line : 1)); \
} else if (write_symbols == DBX_DEBUG) { \
- static int sym_lineno = 1; \
char buffer[256]; \
- ASM_GENERATE_INTERNAL_LABEL (buffer, "LM", sym_lineno); \
+ ASM_GENERATE_INTERNAL_LABEL (buffer, "LM", COUNTER); \
fprintf (FILE, ".stabn 68,0,%d,", LINE); \
assemble_name (FILE, buffer); \
putc ('-', FILE); \
assemble_name (FILE, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
putc ('\n', FILE); \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, "LM", sym_lineno); \
- sym_lineno++; \
+ (*targetm.asm_out.internal_label) (FILE, "LM", COUNTER); \
} }
/* When generating stabs debugging, use N_BINCL entries. */
diff --git a/contrib/gcc/config/dbxelf.h b/contrib/gcc/config/dbxelf.h
index 9f8f56a1b016..e636daddc874 100644
--- a/contrib/gcc/config/dbxelf.h
+++ b/contrib/gcc/config/dbxelf.h
@@ -1,20 +1,20 @@
/* Definitions needed when using stabs embedded in ELF sections.
Copyright (C) 1999 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -57,20 +57,18 @@ Boston, MA 02111-1307, USA. */
current function. */
#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
+#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE, COUNTER) \
do \
{ \
- static int sym_lineno = 1; \
char temp[256]; \
- ASM_GENERATE_INTERNAL_LABEL (temp, "LM", sym_lineno); \
+ ASM_GENERATE_INTERNAL_LABEL (temp, "LM", COUNTER); \
fprintf (FILE, "\t.stabn 68,0,%d,", LINE); \
assemble_name (FILE, temp); \
putc ('-', FILE); \
assemble_name (FILE, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
putc ('\n', FILE); \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, "LM", sym_lineno); \
- sym_lineno += 1; \
+ (*targetm.asm_out.internal_label) (FILE, "LM", COUNTER); \
} \
while (0)
diff --git a/contrib/gcc/config/elfos.h b/contrib/gcc/config/elfos.h
index 25a44afe344b..6a138f9f76f8 100644
--- a/contrib/gcc/config/elfos.h
+++ b/contrib/gcc/config/elfos.h
@@ -1,26 +1,32 @@
/* elfos.h -- operating system specific defines to be used when
targeting GCC for some generic ELF system
- Copyright (C) 1991, 1994, 1995, 1999, 2000, 2001, 2002
+ Copyright (C) 1991, 1994, 1995, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Based on svr4.h contributed by Ron Guilmette (rfg@netcom.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#define TARGET_OBJFMT_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__ELF__"); \
+ } \
+ while (0)
/* Define a symbol indicating that we are using elfos.h.
Some CPU specific configuration files use this. */
@@ -60,10 +66,6 @@ Boston, MA 02111-1307, USA. */
#define HANDLE_SYSV_PRAGMA 1
-/* System V Release 4 uses DWARF debugging info. */
-
-#define DWARF_DEBUGGING_INFO 1
-
/* All ELF targets can support DWARF-2. */
#define DWARF2_DEBUGGING_INFO 1
@@ -90,16 +92,9 @@ Boston, MA 02111-1307, USA. */
#undef SET_ASM_OP
#define SET_ASM_OP "\t.set\t"
-/* This is how to begin an assembly language file. Most svr4 assemblers want
- at least a .file directive to come first, and some want to see a .version
- directive come right after that. Here we just establish a default
- which generates only the .file directive. If you need a .version
- directive for any specific target, you should override this definition
- in the target-specific file which includes this one. */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- output_file_directive ((FILE), main_input_filename)
+/* Most svr4 assemblers want a .file directive at the beginning of
+ their input file. */
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
/* This is how to allocate empty space in some section. The .zero
pseudo-op is used for this on most svr4 assemblers. */
@@ -108,21 +103,8 @@ Boston, MA 02111-1307, USA. */
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(FILE, SIZE) \
- fprintf (FILE, "%s%u\n", SKIP_ASM_OP, (SIZE))
-
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class.
-
- For most svr4 systems, the convention is that any symbol which begins
- with a period is not put into the linker symbol table by the assembler. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE, PREFIX, NUM) \
- do \
- { \
- fprintf (FILE, ".%s%u:\n", PREFIX, (unsigned) (NUM)); \
- } \
- while (0)
+ fprintf ((FILE), "%s"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
+ SKIP_ASM_OP, (SIZE))
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
@@ -161,7 +143,7 @@ Boston, MA 02111-1307, USA. */
do \
{ \
ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \
+ (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); \
} \
while (0)
@@ -185,7 +167,8 @@ Boston, MA 02111-1307, USA. */
{ \
fprintf ((FILE), "%s", COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \
+ (SIZE), (ALIGN) / BITS_PER_UNIT); \
} \
while (0)
@@ -234,7 +217,7 @@ Boston, MA 02111-1307, USA. */
#endif
#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1)
-
+
/* Switch into a generic section. */
#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
@@ -254,11 +237,11 @@ Boston, MA 02111-1307, USA. */
/* This is how we tell the assembler that a symbol is weak. */
-#define ASM_WEAKEN_LABEL(FILE, NAME) \
+#define ASM_WEAKEN_LABEL(FILE, NAME) \
do \
{ \
fputs ("\t.weak\t", (FILE)); \
- assemble_name ((FILE), (NAME)); \
+ assemble_name ((FILE), (NAME)); \
fputc ('\n', (FILE)); \
} \
while (0)
@@ -327,12 +310,13 @@ Boston, MA 02111-1307, USA. */
size_directive_output was set
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
+#undef ASM_FINISH_DECLARE_OBJECT
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)\
do \
{ \
const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
HOST_WIDE_INT size; \
- \
+ \
if (!flag_inhibit_size_directive \
&& DECL_SIZE (DECL) \
&& ! AT_END && TOP_LEVEL \
@@ -410,13 +394,13 @@ Boston, MA 02111-1307, USA. */
register const unsigned char *_limited_str = \
(const unsigned char *) (STR); \
register unsigned ch; \
- \
+ \
fprintf ((FILE), "%s\"", STRING_ASM_OP); \
- \
+ \
for (; (ch = *_limited_str); _limited_str++) \
{ \
register int escape; \
- \
+ \
switch (escape = ESCAPES[ch]) \
{ \
case 0: \
@@ -431,7 +415,7 @@ Boston, MA 02111-1307, USA. */
break; \
} \
} \
- \
+ \
fprintf ((FILE), "\"\n"); \
} \
while (0)
@@ -455,16 +439,16 @@ Boston, MA 02111-1307, USA. */
for (; _ascii_bytes < limit; _ascii_bytes++) \
{ \
register const unsigned char *p; \
- \
+ \
if (bytes_in_chunk >= 60) \
{ \
fprintf ((FILE), "\"\n"); \
bytes_in_chunk = 0; \
} \
- \
+ \
for (p = _ascii_bytes; p < limit && *p != '\0'; p++) \
continue; \
- \
+ \
if (p < limit && (p - _ascii_bytes) <= (long)STRING_LIMIT) \
{ \
if (bytes_in_chunk > 0) \
@@ -472,7 +456,7 @@ Boston, MA 02111-1307, USA. */
fprintf ((FILE), "\"\n"); \
bytes_in_chunk = 0; \
} \
- \
+ \
ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes); \
_ascii_bytes = p; \
} \
@@ -480,10 +464,10 @@ Boston, MA 02111-1307, USA. */
{ \
register int escape; \
register unsigned ch; \
- \
+ \
if (bytes_in_chunk == 0) \
fprintf ((FILE), "%s\"", ASCII_DATA_ASM_OP); \
- \
+ \
switch (escape = ESCAPES[ch = *_ascii_bytes]) \
{ \
case 0: \
@@ -502,7 +486,7 @@ Boston, MA 02111-1307, USA. */
} \
} \
} \
- \
+ \
if (bytes_in_chunk > 0) \
fprintf ((FILE), "\"\n"); \
} \
diff --git a/contrib/gcc/config/fp-bit.c b/contrib/gcc/config/fp-bit.c
index e609760c59ce..e7556c4f849a 100644
--- a/contrib/gcc/config/fp-bit.c
+++ b/contrib/gcc/config/fp-bit.c
@@ -1,6 +1,6 @@
/* This is a software floating point library which can be used
for targets without hardware floating point.
- Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is free software; you can redistribute it and/or modify it
@@ -44,7 +44,9 @@ Boston, MA 02111-1307, USA. */
to one copy, then compile both copies and add them to libgcc.a. */
#include "tconfig.h"
-#include "fp-bit.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "config/fp-bit.h"
/* The following macros can be defined to change the behavior of this file:
FLOAT: Implement a `float', aka SFmode, fp library. If this is not
@@ -208,7 +210,11 @@ pack_d ( fp_number_type * src)
exp = EXPMAX;
if (src->class == CLASS_QNAN || 1)
{
+#ifdef QUIET_NAN_NEGATED
+ fraction |= QUIET_NAN - 1;
+#else
fraction |= QUIET_NAN;
+#endif
}
}
else if (isinf (src))
@@ -324,58 +330,76 @@ pack_d ( fp_number_type * src)
#else
# if defined TFLOAT && defined HALFFRACBITS
{
- halffractype high, low;
-
- high = (fraction >> (FRACBITS - HALFFRACBITS));
- high &= (((fractype)1) << HALFFRACBITS) - 1;
- high |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS;
- high |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS);
-
- low = (halffractype)fraction &
- ((((halffractype)1) << (FRACBITS - HALFFRACBITS)) - 1);
+ halffractype high, low, unity;
+ int lowsign, lowexp;
+
+ unity = (halffractype) 1 << HALFFRACBITS;
+
+ /* Set HIGH to the high double's significand, masking out the implicit 1.
+ Set LOW to the low double's full significand. */
+ high = (fraction >> (FRACBITS - HALFFRACBITS)) & (unity - 1);
+ low = fraction & (unity * 2 - 1);
+
+ /* Get the initial sign and exponent of the low double. */
+ lowexp = exp - HALFFRACBITS - 1;
+ lowsign = sign;
+
+ /* HIGH should be rounded like a normal double, making |LOW| <=
+ 0.5 ULP of HIGH. Assume round-to-nearest. */
+ if (exp < EXPMAX)
+ if (low > unity || (low == unity && (high & 1) == 1))
+ {
+ /* Round HIGH up and adjust LOW to match. */
+ high++;
+ if (high == unity)
+ {
+ /* May make it infinite, but that's OK. */
+ high = 0;
+ exp++;
+ }
+ low = unity * 2 - low;
+ lowsign ^= 1;
+ }
+
+ high |= (halffractype) exp << HALFFRACBITS;
+ high |= (halffractype) sign << (HALFFRACBITS + EXPBITS);
if (exp == EXPMAX || exp == 0 || low == 0)
low = 0;
else
{
- exp -= HALFFRACBITS + 1;
-
- while (exp > 0
- && low < ((halffractype)1 << HALFFRACBITS))
+ while (lowexp > 0 && low < unity)
{
low <<= 1;
- exp--;
+ lowexp--;
}
- if (exp <= 0)
+ if (lowexp <= 0)
{
halffractype roundmsb, round;
+ int shift;
- exp = -exp + 1;
-
- roundmsb = (1 << (exp - 1));
+ shift = 1 - lowexp;
+ roundmsb = (1 << (shift - 1));
round = low & ((roundmsb << 1) - 1);
- low >>= exp;
- exp = 0;
+ low >>= shift;
+ lowexp = 0;
- if (round > roundmsb || (round == roundmsb && (low & 1)))
+ if (round > roundmsb || (round == roundmsb && (low & 1) == 1))
{
low++;
- if (low >= ((halffractype)1 << HALFFRACBITS))
- /* We don't shift left, since it has just become the
- smallest normal number, whose implicit 1 bit is
- now indicated by the non-zero exponent. */
- exp++;
+ if (low == unity)
+ /* LOW rounds up to the smallest normal number. */
+ lowexp++;
}
}
- low &= ((halffractype)1 << HALFFRACBITS) - 1;
- low |= ((fractype) (exp & ((1 << EXPBITS) - 1))) << HALFFRACBITS;
- low |= ((fractype) (sign & 1)) << (HALFFRACBITS | EXPBITS);
+ low &= unity - 1;
+ low |= (halffractype) lowexp << HALFFRACBITS;
+ low |= (halffractype) lowsign << (HALFFRACBITS + EXPBITS);
}
-
- dst.value_raw = (((fractype) high) << HALFSHIFT) | low;
+ dst.value_raw = ((fractype) high << HALFSHIFT) | low;
}
# else
dst.value_raw = fraction & ((((fractype)1) << FRACBITS) - (fractype)1);
@@ -469,8 +493,16 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
xlow >>= -shift;
if (sign == lowsign)
fraction += xlow;
- else
+ else if (fraction >= xlow)
fraction -= xlow;
+ else
+ {
+ /* The high part is a power of two but the full number is lower.
+ This code will leave the implicit 1 in FRACTION, but we'd
+ have added that below anyway. */
+ fraction = (((fractype) 1 << FRACBITS) - xlow) << 1;
+ exp--;
+ }
}
}
# else
@@ -523,7 +555,11 @@ unpack_d (FLO_union_type * src, fp_number_type * dst)
else
{
/* Nonzero fraction, means nan */
+#ifdef QUIET_NAN_NEGATED
+ if ((fraction & QUIET_NAN) == 0)
+#else
if (fraction & QUIET_NAN)
+#endif
{
dst->class = CLASS_QNAN;
}
diff --git a/contrib/gcc/config/fp-bit.h b/contrib/gcc/config/fp-bit.h
index 0e8509eedf92..6221c9ede071 100644
--- a/contrib/gcc/config/fp-bit.h
+++ b/contrib/gcc/config/fp-bit.h
@@ -2,20 +2,20 @@
/* Copyright (C) 2000, 2002, 2003
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/freebsd-nthr.h b/contrib/gcc/config/freebsd-nthr.h
index 2f1d65f4b248..65add9b175e4 100644
--- a/contrib/gcc/config/freebsd-nthr.h
+++ b/contrib/gcc/config/freebsd-nthr.h
@@ -2,20 +2,20 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Loren J. Rittle <ljrittle@acm.org>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/freebsd-spec.h b/contrib/gcc/config/freebsd-spec.h
index 4d81d80c4431..e4459ba6aa6c 100644
--- a/contrib/gcc/config/freebsd-spec.h
+++ b/contrib/gcc/config/freebsd-spec.h
@@ -1,20 +1,20 @@
/* Base configuration file for all FreeBSD targets.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -62,7 +62,6 @@ Boston, MA 02111-1307, USA. */
else \
builtin_define ("__FreeBSD__"); \
builtin_define_std ("unix"); \
- builtin_define ("__ELF__"); \
builtin_define ("__KPRINTF_ATTRIBUTE__"); \
builtin_assert ("system=unix"); \
builtin_assert ("system=bsd"); \
@@ -79,7 +78,7 @@ Boston, MA 02111-1307, USA. */
#define FBSD_CPP_SPEC " \
%(cpp_cpu) \
- %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} \
+ %{fPIC|fpic|fPIE|fpie:-D__PIC__ -D__pic__} \
%{posix:-D_POSIX_SOURCE}"
/* Provide a STARTFILE_SPEC appropriate for FreeBSD. Here we add
@@ -148,3 +147,9 @@ is built with the --enable-threads configure-time option.} \
}"
#endif
#endif
+
+#if FBSD_MAJOR < 6
+#define FBSD_DYNAMIC_LINKER "/usr/libexec/ld-elf.so.1"
+#else
+#define FBSD_DYNAMIC_LINKER "/libexec/ld-elf.so.1"
+#endif
diff --git a/contrib/gcc/config/freebsd.h b/contrib/gcc/config/freebsd.h
index f71bd8b42d5c..542fd0ba61ff 100644
--- a/contrib/gcc/config/freebsd.h
+++ b/contrib/gcc/config/freebsd.h
@@ -1,20 +1,20 @@
/* Base configuration file for all FreeBSD targets.
Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -41,9 +41,6 @@ Boston, MA 02111-1307, USA. */
#undef WORD_SWITCH_TAKES_ARG
#define WORD_SWITCH_TAKES_ARG(STR) (FBSD_WORD_SWITCH_TAKES_ARG(STR))
-#undef CPP_PREDEFINES
-/* Obsolete, do not define it. */
-
#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() FBSD_TARGET_OS_CPP_BUILTINS()
diff --git a/contrib/gcc/config/frv/cmovd.c b/contrib/gcc/config/frv/cmovd.c
index 11b50ba0dcc4..8ce986e4b866 100644
--- a/contrib/gcc/config/frv/cmovd.c
+++ b/contrib/gcc/config/frv/cmovd.c
@@ -1,24 +1,31 @@
/* Move double-word library function.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software ; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
void
__cmovd (long long *dest, const long long *src, unsigned len)
{
diff --git a/contrib/gcc/config/frv/cmovh.c b/contrib/gcc/config/frv/cmovh.c
index 018a0b448ac1..97e1f11fede2 100644
--- a/contrib/gcc/config/frv/cmovh.c
+++ b/contrib/gcc/config/frv/cmovh.c
@@ -1,24 +1,31 @@
/* Move half-word library function.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software ; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
void
__cmovh (short *dest, const short *src, unsigned len)
{
diff --git a/contrib/gcc/config/frv/cmovw.c b/contrib/gcc/config/frv/cmovw.c
index 5509e068e411..8bc58014a2ef 100644
--- a/contrib/gcc/config/frv/cmovw.c
+++ b/contrib/gcc/config/frv/cmovw.c
@@ -1,24 +1,31 @@
/* Move word library function.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software ; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
void
__cmovw (int *dest, const int *src, unsigned len)
{
diff --git a/contrib/gcc/config/frv/frv-abi.h b/contrib/gcc/config/frv/frv-abi.h
index 68fd32fb128e..a38dd16d07eb 100644
--- a/contrib/gcc/config/frv/frv-abi.h
+++ b/contrib/gcc/config/frv/frv-abi.h
@@ -2,20 +2,20 @@
Copyright (C) 2000 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/frv/frv-asm.h b/contrib/gcc/config/frv/frv-asm.h
index e8447a6093d2..b4305a42b022 100644
--- a/contrib/gcc/config/frv/frv-asm.h
+++ b/contrib/gcc/config/frv/frv-asm.h
@@ -1,21 +1,21 @@
/* Assembler Support.
Copyright (C) 2000 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
-
- This file is part of GNU CC.
-
- GNU CC is free software ; you can redistribute it and/or modify
+
+ 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 2, or (at your option)
any later version.
-
- GNU CC is distributed in the hope that it will be useful,
+
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -23,7 +23,7 @@
P2(INSN): Emit INSN.P on the FR500 and above, otherwise emit plain INSN. */
#ifdef __FRV_VLIW__
#ifdef __STDC__
-#define P(A) A##.p
+#define P(A) A.p
#else
#define P(A) A/**/.p
#endif
diff --git a/contrib/gcc/config/frv/frv-modes.def b/contrib/gcc/config/frv/frv-modes.def
index ca7818c1d602..3985099a91c4 100644
--- a/contrib/gcc/config/frv/frv-modes.def
+++ b/contrib/gcc/config/frv/frv-modes.def
@@ -1,20 +1,20 @@
/* Definitions of target machine for GNU compiler for FRV.
Copyright (C) 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,6 +25,6 @@ Boston, MA 02111-1307, USA. */
CC_FPmode set FCC's from comparing floating point
CC_CCRmode set CCR's to do conditional execution */
-CC (CC_UNS)
-CC (CC_FP)
-CC (CC_CCR)
+CC_MODE (CC_UNS);
+CC_MODE (CC_FP);
+CC_MODE (CC_CCR);
diff --git a/contrib/gcc/config/frv/frv-protos.h b/contrib/gcc/config/frv/frv-protos.h
index 4f5a422cbae3..90292b17d6e2 100644
--- a/contrib/gcc/config/frv/frv-protos.h
+++ b/contrib/gcc/config/frv/frv-protos.h
@@ -1,21 +1,21 @@
/* Frv prototypes.
- Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -23,7 +23,7 @@ Boston, MA 02111-1307, USA. */
stored from the compare operation. Note that we can't use "rtx" here
since it hasn't been defined! */
-/* Define global data defined in frv.c */
+/* Define global data defined in frv.c. */
extern const char *frv_branch_cost_string; /* -mbranch-cost option */
extern int frv_branch_cost_int; /* value of -mbranch_cost */
@@ -52,196 +52,187 @@ typedef enum frv_cpu
extern frv_cpu_t frv_cpu_type; /* value of -mcpu= */
/* Define functions defined in frv.c */
-extern void frv_expand_prologue PARAMS ((void));
-extern void frv_expand_epilogue PARAMS ((int));
-extern void frv_override_options PARAMS ((void));
-extern void frv_optimization_options PARAMS ((int, int));
-extern void frv_conditional_register_usage PARAMS ((void));
-extern frv_stack_t *frv_stack_info PARAMS ((void));
-extern void frv_debug_stack PARAMS ((frv_stack_t *));
-extern int frv_frame_pointer_required PARAMS ((void));
-extern int frv_initial_elimination_offset PARAMS ((int, int));
+extern void frv_expand_prologue (void);
+extern void frv_expand_epilogue (int);
+extern void frv_override_options (void);
+extern void frv_optimization_options (int, int);
+extern void frv_conditional_register_usage (void);
+extern frv_stack_t *frv_stack_info (void);
+extern void frv_debug_stack (frv_stack_t *);
+extern int frv_frame_pointer_required (void);
+extern int frv_initial_elimination_offset (int, int);
#ifdef RTX_CODE
-extern int frv_legitimate_address_p PARAMS ((enum machine_mode, rtx,
- int, int));
-extern rtx frv_legitimize_address PARAMS ((rtx, rtx,
- enum machine_mode));
+extern int frv_legitimate_address_p (enum machine_mode, rtx,
+ int, int);
+extern rtx frv_legitimize_address (rtx, rtx, enum machine_mode);
#ifdef TREE_CODE
-extern void frv_init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree,
- rtx, int, int));
+extern void frv_init_cumulative_args (CUMULATIVE_ARGS *, tree,
+ rtx, tree, int);
-extern int frv_function_arg_boundary PARAMS ((enum machine_mode, tree));
-extern rtx frv_function_arg PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int, int));
+extern int frv_function_arg_boundary (enum machine_mode, tree);
+extern rtx frv_function_arg (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int, int);
-extern void frv_function_arg_advance PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
+extern void frv_function_arg_advance (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int);
-extern int frv_function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
+extern int frv_function_arg_partial_nregs (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int);
-extern int frv_function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
+extern int frv_function_arg_pass_by_reference (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int);
-extern int frv_function_arg_callee_copies PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
+extern int frv_function_arg_callee_copies (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int);
-extern int frv_function_arg_keep_as_reference PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
+extern int frv_function_arg_keep_as_reference (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int);
-extern rtx frv_expand_builtin_saveregs PARAMS ((void));
-extern void frv_setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int *, int));
+extern rtx frv_expand_builtin_saveregs (void);
+extern void frv_setup_incoming_varargs (CUMULATIVE_ARGS *,
+ enum machine_mode,
+ tree, int *, int);
-extern void frv_expand_builtin_va_start PARAMS ((tree, rtx));
-extern rtx frv_expand_builtin_va_arg PARAMS ((tree, tree));
+extern void frv_expand_builtin_va_start (tree, rtx);
+extern rtx frv_expand_builtin_va_arg (tree, tree);
#endif /* TREE_CODE */
-extern int frv_expand_block_move PARAMS ((rtx *));
-extern int frv_expand_block_clear PARAMS ((rtx *));
-extern rtx frv_dynamic_chain_address PARAMS ((rtx));
-extern rtx frv_return_addr_rtx PARAMS ((int, rtx));
-extern rtx frv_index_memory PARAMS ((rtx,
- enum machine_mode,
- int));
+extern int frv_expand_block_move (rtx *);
+extern int frv_expand_block_clear (rtx *);
+extern rtx frv_dynamic_chain_address (rtx);
+extern rtx frv_return_addr_rtx (int, rtx);
+extern rtx frv_index_memory (rtx, enum machine_mode, int);
extern const char *frv_asm_output_opcode
- PARAMS ((FILE *, const char *));
-extern void frv_final_prescan_insn PARAMS ((rtx, rtx *, int));
-extern void frv_print_operand PARAMS ((FILE *, rtx, int));
-extern void frv_print_operand_address PARAMS ((FILE *, rtx));
-extern int frv_emit_movsi PARAMS ((rtx, rtx));
-extern const char *output_move_single PARAMS ((rtx *, rtx));
-extern const char *output_move_double PARAMS ((rtx *, rtx));
+ (FILE *, const char *);
+extern void frv_final_prescan_insn (rtx, rtx *, int);
+extern void frv_print_operand (FILE *, rtx, int);
+extern void frv_print_operand_address (FILE *, rtx);
+extern int frv_emit_movsi (rtx, rtx);
+extern const char *output_move_single (rtx *, rtx);
+extern const char *output_move_double (rtx *, rtx);
extern const char *output_condmove_single
- PARAMS ((rtx *, rtx));
-extern int frv_emit_cond_branch PARAMS ((enum rtx_code, rtx));
-extern int frv_emit_scc PARAMS ((enum rtx_code, rtx));
-extern rtx frv_split_scc PARAMS ((rtx, rtx, rtx, rtx,
- HOST_WIDE_INT));
-extern int frv_emit_cond_move PARAMS ((rtx, rtx, rtx, rtx));
-extern rtx frv_split_cond_move PARAMS ((rtx *));
-extern rtx frv_split_minmax PARAMS ((rtx *));
-extern rtx frv_split_abs PARAMS ((rtx *));
-extern void frv_split_double_load PARAMS ((rtx, rtx));
-extern void frv_split_double_store PARAMS ((rtx, rtx));
+ (rtx *, rtx);
+extern int frv_emit_cond_branch (enum rtx_code, rtx);
+extern int frv_emit_scc (enum rtx_code, 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 *);
+extern rtx frv_split_minmax (rtx *);
+extern rtx frv_split_abs (rtx *);
+extern void frv_split_double_load (rtx, rtx);
+extern void frv_split_double_store (rtx, rtx);
#ifdef BLOCK_HEAD
-extern void frv_ifcvt_init_extra_fields PARAMS ((ce_if_block_t *));
-extern void frv_ifcvt_modify_tests PARAMS ((ce_if_block_t *,
- rtx *, rtx *));
+extern void frv_ifcvt_init_extra_fields (ce_if_block_t *);
+extern void frv_ifcvt_modify_tests (ce_if_block_t *, rtx *, rtx *);
extern void frv_ifcvt_modify_multiple_tests
- PARAMS ((ce_if_block_t *,
- basic_block,
- rtx *, rtx *));
-extern rtx frv_ifcvt_modify_insn PARAMS ((ce_if_block_t *,
- rtx, rtx));
-extern void frv_ifcvt_modify_final PARAMS ((ce_if_block_t *));
-extern void frv_ifcvt_modify_cancel PARAMS ((ce_if_block_t *));
+ (ce_if_block_t *, basic_block,
+ rtx *, rtx *);
+extern rtx frv_ifcvt_modify_insn (ce_if_block_t *, rtx, rtx);
+extern void frv_ifcvt_modify_final (ce_if_block_t *);
+extern void frv_ifcvt_modify_cancel (ce_if_block_t *);
#endif
-extern int frv_trampoline_size PARAMS ((void));
-extern void frv_initialize_trampoline PARAMS ((rtx, rtx, rtx));
+extern int frv_trampoline_size (void);
+extern void frv_initialize_trampoline (rtx, rtx, rtx);
extern enum reg_class frv_secondary_reload_class
- PARAMS ((enum reg_class class,
- enum machine_mode mode,
- rtx x, int));
-extern int frv_class_likely_spilled_p PARAMS ((enum reg_class class));
-extern int frv_hard_regno_mode_ok PARAMS ((int, enum machine_mode));
-extern int frv_hard_regno_nregs PARAMS ((int, enum machine_mode));
-extern int frv_class_max_nregs PARAMS ((enum reg_class class,
- enum machine_mode mode));
-extern int frv_legitimate_constant_p PARAMS ((rtx));
+ (enum reg_class class,
+ enum machine_mode mode,
+ rtx x, int);
+extern int frv_class_likely_spilled_p (enum reg_class class);
+extern int frv_hard_regno_mode_ok (int, enum machine_mode);
+extern int frv_hard_regno_nregs (int, enum machine_mode);
+extern int frv_class_max_nregs (enum reg_class class,
+ enum machine_mode mode);
+extern int frv_legitimate_constant_p (rtx);
#endif /* RTX_CODE */
-extern int direct_return_p PARAMS ((void));
-extern int frv_register_move_cost PARAMS ((enum reg_class, enum reg_class));
+extern int direct_return_p (void);
+extern int frv_register_move_cost (enum reg_class, enum reg_class);
#ifdef TREE_CODE
-extern int frv_adjust_field_align PARAMS ((tree, int));
+extern int frv_adjust_field_align (tree, int);
#endif
-extern void fixup_section PARAMS ((void));
-extern void sdata_section PARAMS ((void));
-extern void sbss_section PARAMS ((void));
-extern void const_section PARAMS ((void));
-extern void data_section PARAMS ((void));
+extern void fixup_section (void);
+extern void sdata_section (void);
+extern void sbss_section (void);
+extern void data_section (void);
#ifdef RTX_CODE
-extern int integer_register_operand PARAMS ((rtx, enum machine_mode));
-extern int frv_load_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_or_fpr_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_no_subreg_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_or_int6_operand PARAMS ((rtx, enum machine_mode));
-extern int fpr_or_int6_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_or_int_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_or_int12_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_fpr_or_int12_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_or_int10_operand PARAMS ((rtx, enum machine_mode));
-extern int move_source_operand PARAMS ((rtx, enum machine_mode));
-extern int move_destination_operand PARAMS ((rtx, enum machine_mode));
-extern int condexec_source_operand PARAMS ((rtx, enum machine_mode));
-extern int condexec_dest_operand PARAMS ((rtx, enum machine_mode));
-extern int lr_operand PARAMS ((rtx, enum machine_mode));
-extern int gpr_or_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int fpr_or_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_0_operand PARAMS ((rtx, enum machine_mode));
-extern int fcc_operand PARAMS ((rtx, enum machine_mode));
-extern int icc_operand PARAMS ((rtx, enum machine_mode));
-extern int cc_operand PARAMS ((rtx, enum machine_mode));
-extern int fcr_operand PARAMS ((rtx, enum machine_mode));
-extern int icr_operand PARAMS ((rtx, enum machine_mode));
-extern int cr_operand PARAMS ((rtx, enum machine_mode));
-extern int call_operand PARAMS ((rtx, enum machine_mode));
-extern int fpr_operand PARAMS ((rtx, enum machine_mode));
-extern int even_reg_operand PARAMS ((rtx, enum machine_mode));
-extern int odd_reg_operand PARAMS ((rtx, enum machine_mode));
-extern int even_gpr_operand PARAMS ((rtx, enum machine_mode));
-extern int odd_gpr_operand PARAMS ((rtx, enum machine_mode));
-extern int quad_fpr_operand PARAMS ((rtx, enum machine_mode));
-extern int even_fpr_operand PARAMS ((rtx, enum machine_mode));
-extern int odd_fpr_operand PARAMS ((rtx, enum machine_mode));
-extern int dbl_memory_one_insn_operand PARAMS ((rtx, enum machine_mode));
-extern int dbl_memory_two_insn_operand PARAMS ((rtx, enum machine_mode));
-extern int int12_operand PARAMS ((rtx, enum machine_mode));
-extern int int6_operand PARAMS ((rtx, enum machine_mode));
-extern int int5_operand PARAMS ((rtx, enum machine_mode));
-extern int uint5_operand PARAMS ((rtx, enum machine_mode));
-extern int uint4_operand PARAMS ((rtx, enum machine_mode));
-extern int uint1_operand PARAMS ((rtx, enum machine_mode));
-extern int int_2word_operand PARAMS ((rtx, enum machine_mode));
-extern int pic_register_operand PARAMS ((rtx, enum machine_mode));
-extern int pic_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int small_data_register_operand PARAMS ((rtx, enum machine_mode));
-extern int small_data_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int upper_int16_operand PARAMS ((rtx, enum machine_mode));
-extern int uint16_operand PARAMS ((rtx, enum machine_mode));
-extern int relational_operator PARAMS ((rtx, enum machine_mode));
-extern int signed_relational_operator PARAMS ((rtx, enum machine_mode));
-extern int unsigned_relational_operator PARAMS ((rtx, enum machine_mode));
-extern int float_relational_operator PARAMS ((rtx, enum machine_mode));
-extern int ccr_eqne_operator PARAMS ((rtx, enum machine_mode));
-extern int minmax_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_si_binary_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_si_media_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_si_divide_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_si_unary_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_sf_conv_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_sf_add_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int intop_compare_operator PARAMS ((rtx, enum machine_mode));
-extern int condexec_intop_cmp_operator PARAMS ((rtx, enum machine_mode));
-extern int acc_operand PARAMS ((rtx, enum machine_mode));
-extern int even_acc_operand PARAMS ((rtx, enum machine_mode));
-extern int quad_acc_operand PARAMS ((rtx, enum machine_mode));
-extern int accg_operand PARAMS ((rtx, enum machine_mode));
-extern rtx frv_matching_accg_for_acc PARAMS ((rtx));
-extern void frv_machine_dependent_reorg PARAMS ((rtx));
+extern int integer_register_operand (rtx, enum machine_mode);
+extern int frv_load_operand (rtx, enum machine_mode);
+extern int gpr_or_fpr_operand (rtx, enum machine_mode);
+extern int gpr_no_subreg_operand (rtx, enum machine_mode);
+extern int gpr_or_int6_operand (rtx, enum machine_mode);
+extern int fpr_or_int6_operand (rtx, enum machine_mode);
+extern int gpr_or_int_operand (rtx, enum machine_mode);
+extern int gpr_or_int12_operand (rtx, enum machine_mode);
+extern int gpr_fpr_or_int12_operand (rtx, enum machine_mode);
+extern int gpr_or_int10_operand (rtx, enum machine_mode);
+extern int move_source_operand (rtx, enum machine_mode);
+extern int move_destination_operand (rtx, enum machine_mode);
+extern int condexec_source_operand (rtx, enum machine_mode);
+extern int condexec_dest_operand (rtx, enum machine_mode);
+extern int lr_operand (rtx, enum machine_mode);
+extern int gpr_or_memory_operand (rtx, enum machine_mode);
+extern int fpr_or_memory_operand (rtx, enum machine_mode);
+extern int reg_or_0_operand (rtx, enum machine_mode);
+extern int fcc_operand (rtx, enum machine_mode);
+extern int icc_operand (rtx, enum machine_mode);
+extern int cc_operand (rtx, enum machine_mode);
+extern int fcr_operand (rtx, enum machine_mode);
+extern int icr_operand (rtx, enum machine_mode);
+extern int cr_operand (rtx, enum machine_mode);
+extern int call_operand (rtx, enum machine_mode);
+extern int fpr_operand (rtx, enum machine_mode);
+extern int even_reg_operand (rtx, enum machine_mode);
+extern int odd_reg_operand (rtx, enum machine_mode);
+extern int even_gpr_operand (rtx, enum machine_mode);
+extern int odd_gpr_operand (rtx, enum machine_mode);
+extern int quad_fpr_operand (rtx, enum machine_mode);
+extern int even_fpr_operand (rtx, enum machine_mode);
+extern int odd_fpr_operand (rtx, enum machine_mode);
+extern int dbl_memory_one_insn_operand (rtx, enum machine_mode);
+extern int dbl_memory_two_insn_operand (rtx, enum machine_mode);
+extern int int12_operand (rtx, enum machine_mode);
+extern int int6_operand (rtx, enum machine_mode);
+extern int int5_operand (rtx, enum machine_mode);
+extern int uint5_operand (rtx, enum machine_mode);
+extern int uint4_operand (rtx, enum machine_mode);
+extern int uint1_operand (rtx, enum machine_mode);
+extern int int_2word_operand (rtx, enum machine_mode);
+extern int pic_register_operand (rtx, enum machine_mode);
+extern int pic_symbolic_operand (rtx, enum machine_mode);
+extern int small_data_register_operand (rtx, enum machine_mode);
+extern int small_data_symbolic_operand (rtx, enum machine_mode);
+extern int upper_int16_operand (rtx, enum machine_mode);
+extern int uint16_operand (rtx, enum machine_mode);
+extern int relational_operator (rtx, enum machine_mode);
+extern int signed_relational_operator (rtx, enum machine_mode);
+extern int unsigned_relational_operator (rtx, enum machine_mode);
+extern int float_relational_operator (rtx, enum machine_mode);
+extern int ccr_eqne_operator (rtx, enum machine_mode);
+extern int minmax_operator (rtx, enum machine_mode);
+extern int condexec_si_binary_operator (rtx, enum machine_mode);
+extern int condexec_si_media_operator (rtx, enum machine_mode);
+extern int condexec_si_divide_operator (rtx, enum machine_mode);
+extern int condexec_si_unary_operator (rtx, enum machine_mode);
+extern int condexec_sf_conv_operator (rtx, enum machine_mode);
+extern int condexec_sf_add_operator (rtx, enum machine_mode);
+extern int condexec_memory_operand (rtx, enum machine_mode);
+extern int intop_compare_operator (rtx, enum machine_mode);
+extern int condexec_intop_cmp_operator (rtx, enum machine_mode);
+extern int acc_operand (rtx, enum machine_mode);
+extern int even_acc_operand (rtx, enum machine_mode);
+extern int quad_acc_operand (rtx, enum machine_mode);
+extern int accg_operand (rtx, enum machine_mode);
+extern rtx frv_matching_accg_for_acc (rtx);
#endif
diff --git a/contrib/gcc/config/frv/frv.c b/contrib/gcc/config/frv/frv.c
index d09533a5f154..1a750427fac8 100644
--- a/contrib/gcc/config/frv/frv.c
+++ b/contrib/gcc/config/frv/frv.c
@@ -1,25 +1,28 @@
-/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2004
+ Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "regs.h"
@@ -72,7 +75,7 @@ frv_tmp_reg_t;
/* conditional expression used */
#define REGSTATE_IF_EITHER (REGSTATE_IF_TRUE | REGSTATE_IF_FALSE)
-/* the following is not sure in the reg_state bytes, so can have a larger value
+/* The following is not sure in the reg_state bytes, so can have a larger value
than 0xff. */
#define REGSTATE_CONDJUMP 0x100 /* conditional jump done in VLIW insn */
@@ -108,7 +111,7 @@ typedef struct
rtx frv_compare_op0;
rtx frv_compare_op1;
-/* Conditional execution support gathered together in one structure */
+/* Conditional execution support gathered together in one structure. */
typedef struct
{
/* Linked list of insns to add if the conditional execution conversion was
@@ -136,20 +139,20 @@ typedef struct
/* Current number of temp registers available. */
int cur_scratch_regs;
- /* Number of nested conditional execution blocks */
+ /* Number of nested conditional execution blocks. */
int num_nested_cond_exec;
/* Map of insns that set up constants in scratch registers. */
bitmap scratch_insns_bitmap;
- /* Conditional execution test register (CC0..CC7) */
+ /* Conditional execution test register (CC0..CC7). */
rtx cr_reg;
/* Conditional execution compare register that is paired with cr_reg, so that
nested compares can be done. The csubcc and caddcc instructions don't
have enough bits to specify both a CC register to be set and a CR register
to do the test on, so the same bit number is used for both. Needless to
- say, this is rather inconvient for GCC. */
+ say, this is rather inconvenient for GCC. */
rtx nested_cc_reg;
/* Extra CR registers used for &&, ||. */
@@ -157,7 +160,7 @@ typedef struct
rtx extra_fp_cr;
/* Previous CR used in nested if, to make sure we are dealing with the same
- nested if as the previous statement. */
+ nested if as the previous statement. */
rtx last_nested_if_cr;
}
frv_ifcvt_t;
@@ -167,10 +170,10 @@ static /* GTY(()) */ frv_ifcvt_t frv_ifcvt;
/* Map register number to smallest register class. */
enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
-/* Map class letter into register class */
+/* Map class letter into register class. */
enum reg_class reg_class_from_letter[256];
-/* Cached value of frv_stack_info */
+/* Cached value of frv_stack_info. */
static frv_stack_t *frv_stack_cache = (frv_stack_t *)0;
/* -mbranch-cost= support */
@@ -194,93 +197,75 @@ const char *frv_sched_lookahead_str; /* -msched-lookahead=n */
int frv_sched_lookahead = 4; /* -msched-lookahead=n */
/* Forward references */
-static int frv_default_flags_for_cpu PARAMS ((void));
-static int frv_string_begins_with PARAMS ((tree, const char *));
-static FRV_INLINE int symbol_ref_small_data_p PARAMS ((rtx));
-static FRV_INLINE int const_small_data_p PARAMS ((rtx));
-static FRV_INLINE int plus_small_data_p PARAMS ((rtx, rtx));
+static int frv_default_flags_for_cpu (void);
+static int frv_string_begins_with (tree, const char *);
+static FRV_INLINE int const_small_data_p (rtx);
+static FRV_INLINE int plus_small_data_p (rtx, rtx);
static void frv_print_operand_memory_reference_reg
- PARAMS ((FILE *, rtx));
-static void frv_print_operand_memory_reference PARAMS ((FILE *, rtx, int));
-static int frv_print_operand_jump_hint PARAMS ((rtx));
-static FRV_INLINE int frv_regno_ok_for_base_p PARAMS ((int, int));
-static rtx single_set_pattern PARAMS ((rtx));
-static int frv_function_contains_far_jump PARAMS ((void));
-static rtx frv_alloc_temp_reg PARAMS ((frv_tmp_reg_t *,
- enum reg_class,
- enum machine_mode,
- int, int));
-static rtx frv_frame_offset_rtx PARAMS ((int));
-static rtx frv_frame_mem PARAMS ((enum machine_mode,
- rtx, int));
-static rtx frv_dwarf_store PARAMS ((rtx, int));
-static void frv_frame_insn PARAMS ((rtx, rtx));
-static void frv_frame_access PARAMS ((frv_frame_accessor_t*,
- rtx, int));
-static void frv_frame_access_multi PARAMS ((frv_frame_accessor_t*,
- frv_stack_t *, int));
-static void frv_frame_access_standard_regs PARAMS ((enum frv_stack_op,
- frv_stack_t *));
-static struct machine_function *frv_init_machine_status PARAMS ((void));
-static int frv_legitimate_memory_operand PARAMS ((rtx,
- enum machine_mode,
- int));
-static rtx frv_int_to_acc PARAMS ((enum insn_code,
- int, rtx));
-static enum machine_mode frv_matching_accg_mode PARAMS ((enum machine_mode));
-static rtx frv_read_argument PARAMS ((tree *));
-static int frv_check_constant_argument PARAMS ((enum insn_code,
- int, rtx));
-static rtx frv_legitimize_target PARAMS ((enum insn_code, rtx));
-static rtx frv_legitimize_argument PARAMS ((enum insn_code,
- int, rtx));
-static rtx frv_expand_set_builtin PARAMS ((enum insn_code,
- tree, rtx));
-static rtx frv_expand_unop_builtin PARAMS ((enum insn_code,
- tree, rtx));
-static rtx frv_expand_binop_builtin PARAMS ((enum insn_code,
- tree, rtx));
-static rtx frv_expand_cut_builtin PARAMS ((enum insn_code,
- tree, rtx));
-static rtx frv_expand_binopimm_builtin PARAMS ((enum insn_code,
- tree, rtx));
-static rtx frv_expand_voidbinop_builtin PARAMS ((enum insn_code,
- tree));
-static rtx frv_expand_voidtriop_builtin PARAMS ((enum insn_code,
- tree));
-static rtx frv_expand_voidaccop_builtin PARAMS ((enum insn_code,
- tree));
-static rtx frv_expand_mclracc_builtin PARAMS ((tree));
-static rtx frv_expand_mrdacc_builtin PARAMS ((enum insn_code,
- tree));
-static rtx frv_expand_mwtacc_builtin PARAMS ((enum insn_code,
- tree));
-static rtx frv_expand_noargs_builtin PARAMS ((enum insn_code));
-static rtx frv_emit_comparison PARAMS ((enum rtx_code, rtx,
- rtx));
-static int frv_clear_registers_used PARAMS ((rtx *, void *));
-static void frv_ifcvt_add_insn PARAMS ((rtx, rtx, int));
-static rtx frv_ifcvt_rewrite_mem PARAMS ((rtx,
- enum machine_mode,
- rtx));
-static rtx frv_ifcvt_load_value PARAMS ((rtx, rtx));
-static void frv_registers_update PARAMS ((rtx, unsigned char [],
- int [], int *, int));
-static int frv_registers_used_p PARAMS ((rtx, unsigned char [],
- int));
-static int frv_registers_set_p PARAMS ((rtx, unsigned char [],
- int));
-static void frv_pack_insns PARAMS ((void));
-static void frv_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void frv_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-static bool frv_assemble_integer PARAMS ((rtx, unsigned, int));
-static const char * frv_strip_name_encoding PARAMS ((const char *));
-static void frv_encode_section_info PARAMS ((tree, int));
-static void frv_init_builtins PARAMS ((void));
-static rtx frv_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
-static bool frv_in_small_data_p PARAMS ((tree));
+ (FILE *, rtx);
+static void frv_print_operand_memory_reference (FILE *, rtx, int);
+static int frv_print_operand_jump_hint (rtx);
+static FRV_INLINE int frv_regno_ok_for_base_p (int, int);
+static rtx single_set_pattern (rtx);
+static int frv_function_contains_far_jump (void);
+static rtx frv_alloc_temp_reg (frv_tmp_reg_t *,
+ enum reg_class,
+ enum machine_mode,
+ int, int);
+static rtx frv_frame_offset_rtx (int);
+static rtx frv_frame_mem (enum machine_mode, rtx, int);
+static rtx frv_dwarf_store (rtx, int);
+static void frv_frame_insn (rtx, rtx);
+static void frv_frame_access (frv_frame_accessor_t*,
+ rtx, int);
+static void frv_frame_access_multi (frv_frame_accessor_t*,
+ frv_stack_t *, int);
+static void frv_frame_access_standard_regs (enum frv_stack_op,
+ frv_stack_t *);
+static struct machine_function *frv_init_machine_status (void);
+static int frv_legitimate_memory_operand (rtx, enum machine_mode, int);
+static rtx frv_int_to_acc (enum insn_code, int, rtx);
+static enum machine_mode frv_matching_accg_mode (enum machine_mode);
+static rtx frv_read_argument (tree *);
+static int frv_check_constant_argument (enum insn_code, int, rtx);
+static rtx frv_legitimize_target (enum insn_code, rtx);
+static rtx frv_legitimize_argument (enum insn_code, int, rtx);
+static rtx frv_expand_set_builtin (enum insn_code, tree, rtx);
+static rtx frv_expand_unop_builtin (enum insn_code, tree, rtx);
+static rtx frv_expand_binop_builtin (enum insn_code, tree, rtx);
+static rtx frv_expand_cut_builtin (enum insn_code, tree, rtx);
+static rtx frv_expand_binopimm_builtin (enum insn_code, tree, rtx);
+static rtx frv_expand_voidbinop_builtin (enum insn_code, tree);
+static rtx frv_expand_voidtriop_builtin (enum insn_code, tree);
+static rtx frv_expand_voidaccop_builtin (enum insn_code, tree);
+static rtx frv_expand_mclracc_builtin (tree);
+static rtx frv_expand_mrdacc_builtin (enum insn_code, tree);
+static rtx frv_expand_mwtacc_builtin (enum insn_code, tree);
+static rtx frv_expand_noargs_builtin (enum insn_code);
+static rtx frv_emit_comparison (enum rtx_code, rtx, rtx);
+static int frv_clear_registers_used (rtx *, void *);
+static void frv_ifcvt_add_insn (rtx, rtx, int);
+static rtx frv_ifcvt_rewrite_mem (rtx, enum machine_mode, rtx);
+static rtx frv_ifcvt_load_value (rtx, rtx);
+static void frv_registers_update (rtx, unsigned char [],
+ int [], int *, int);
+static int frv_registers_used_p (rtx, unsigned char [], int);
+static int frv_registers_set_p (rtx, unsigned char [], int);
+static int frv_issue_rate (void);
+static int frv_use_dfa_pipeline_interface (void);
+static void frv_pack_insns (void);
+static void frv_function_prologue (FILE *, HOST_WIDE_INT);
+static void frv_function_epilogue (FILE *, HOST_WIDE_INT);
+static bool frv_assemble_integer (rtx, unsigned, int);
+static void frv_init_builtins (void);
+static rtx frv_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+static void frv_init_libfuncs (void);
+static bool frv_in_small_data_p (tree);
static void frv_asm_output_mi_thunk
- PARAMS ((FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
+ (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
+static bool frv_rtx_costs (rtx, int, int, int*);
+static void frv_asm_out_constructor (rtx, int);
+static void frv_asm_out_destructor (rtx, int);
/* Initialize the GCC target structure. */
#undef TARGET_ASM_FUNCTION_PROLOGUE
@@ -289,38 +274,37 @@ static void frv_asm_output_mi_thunk
#define TARGET_ASM_FUNCTION_EPILOGUE frv_function_epilogue
#undef TARGET_ASM_INTEGER
#define TARGET_ASM_INTEGER frv_assemble_integer
-#undef TARGET_STRIP_NAME_ENCODING
-#define TARGET_STRIP_NAME_ENCODING frv_strip_name_encoding
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO frv_encode_section_info
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS frv_init_builtins
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN frv_expand_builtin
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS frv_init_libfuncs
#undef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P frv_in_small_data_p
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS frv_rtx_costs
+#undef TARGET_ASM_CONSTRUCTOR
+#define TARGET_ASM_CONSTRUCTOR frv_asm_out_constructor
+#undef TARGET_ASM_DESTRUCTOR
+#define TARGET_ASM_DESTRUCTOR frv_asm_out_destructor
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK frv_asm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE frv_issue_rate
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE frv_use_dfa_pipeline_interface
+
struct gcc_target targetm = TARGET_INITIALIZER;
-/* Given a SYMBOL_REF, return true if it points to small data. */
-
-static FRV_INLINE int
-symbol_ref_small_data_p (x)
- rtx x;
-{
- return SDATA_NAME_P (XSTR (x, 0));
-}
-
/* Given a CONST, return true if the symbol_ref points to small data. */
static FRV_INLINE int
-const_small_data_p (x)
- rtx x;
+const_small_data_p (rtx x)
{
rtx x0, x1;
@@ -328,7 +312,7 @@ const_small_data_p (x)
return FALSE;
x0 = XEXP (XEXP (x, 0), 0);
- if (GET_CODE (x0) != SYMBOL_REF || !SDATA_NAME_P (XSTR (x0, 0)))
+ if (GET_CODE (x0) != SYMBOL_REF || !SYMBOL_REF_SMALL_P (x0))
return FALSE;
x1 = XEXP (XEXP (x, 0), 1);
@@ -342,16 +326,14 @@ const_small_data_p (x)
/* Given a PLUS, return true if this is a small data reference. */
static FRV_INLINE int
-plus_small_data_p (op0, op1)
- rtx op0;
- rtx op1;
+plus_small_data_p (rtx op0, rtx op1)
{
if (GET_MODE (op0) == SImode
&& GET_CODE (op0) == REG
&& REGNO (op0) == SDA_BASE_REG)
{
if (GET_CODE (op1) == SYMBOL_REF)
- return symbol_ref_small_data_p (op1);
+ return SYMBOL_REF_SMALL_P (op1);
if (GET_CODE (op1) == CONST)
return const_small_data_p (op1);
@@ -362,7 +344,7 @@ plus_small_data_p (op0, op1)
static int
-frv_default_flags_for_cpu ()
+frv_default_flags_for_cpu (void)
{
switch (frv_cpu_type)
{
@@ -393,11 +375,11 @@ frv_default_flags_for_cpu ()
`-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
void
-frv_override_options ()
+frv_override_options (void)
{
int regno, i;
- /* Set the cpu type */
+ /* Set the cpu type. */
if (frv_cpu_string)
{
if (strcmp (frv_cpu_string, "simple") == 0)
@@ -450,26 +432,26 @@ frv_override_options ()
if (write_symbols == DWARF_DEBUG && flag_pic)
error ("-fpic and -gdwarf are incompatible (-fpic and -g/-gdwarf-2 are fine)");
- /* Change the branch cost value */
+ /* Change the branch cost value. */
if (frv_branch_cost_string)
frv_branch_cost_int = atoi (frv_branch_cost_string);
- /* Change the # of insns to be converted to conditional execution */
+ /* Change the # of insns to be converted to conditional execution. */
if (frv_condexec_insns_str)
frv_condexec_insns = atoi (frv_condexec_insns_str);
- /* Change # of temporary registers used to hold integer constants */
+ /* Change # of temporary registers used to hold integer constants. */
if (frv_condexec_temps_str)
frv_condexec_temps = atoi (frv_condexec_temps_str);
- /* Change scheduling look ahead. */
+ /* Change scheduling look ahead. */
if (frv_sched_lookahead_str)
frv_sched_lookahead = atoi (frv_sched_lookahead_str);
/* A C expression whose value is a register class containing hard
register REGNO. In general there is more than one such class;
choose a class which is "minimal", meaning that no smaller class
- also contains the register. */
+ also contains the register. */
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
{
@@ -615,9 +597,7 @@ frv_override_options ()
/* On the FRV, possibly disable VLIW packing which is done by the 2nd
scheduling pass at the current time. */
void
-frv_optimization_options (level, size)
- int level;
- int size ATTRIBUTE_UNUSED;
+frv_optimization_options (int level, int size ATTRIBUTE_UNUSED)
{
if (level >= 2)
{
@@ -634,9 +614,7 @@ frv_optimization_options (level, size)
/* Return true if NAME (a STRING_CST node) begins with PREFIX. */
static int
-frv_string_begins_with (name, prefix)
- tree name;
- const char *prefix;
+frv_string_begins_with (tree name, const char *prefix)
{
int prefix_len = strlen (prefix);
@@ -644,64 +622,6 @@ frv_string_begins_with (name, prefix)
return (TREE_STRING_LENGTH (name) > prefix_len
&& strncmp (TREE_STRING_POINTER (name), prefix, prefix_len) == 0);
}
-
-/* Encode section information of DECL, which is either a VAR_DECL,
- FUNCTION_DECL, STRING_CST, CONSTRUCTOR, or ???.
-
- For the FRV we want to record:
-
- - whether the object lives in .sdata/.sbss.
- objects living in .sdata/.sbss are prefixed with SDATA_FLAG_CHAR
-
-*/
-
-static void
-frv_encode_section_info (decl, first)
- tree decl;
- int first;
-{
- if (! first)
- return;
- if (TREE_CODE (decl) == VAR_DECL)
- {
- int size = int_size_in_bytes (TREE_TYPE (decl));
- tree section_name = DECL_SECTION_NAME (decl);
- int is_small = 0;
-
- /* Don't apply the -G flag to internal compiler structures. We
- should leave such structures in the main data section, partly
- for efficiency and partly because the size of some of them
- (such as C++ typeinfos) is not known until later. */
- if (!DECL_ARTIFICIAL (decl) && size > 0 && size <= g_switch_value)
- is_small = 1;
-
- /* If we already know which section the decl should be in, see if
- it's a small data section. */
- if (section_name)
- {
- if (TREE_CODE (section_name) == STRING_CST)
- {
- if (frv_string_begins_with (section_name, ".sdata"))
- is_small = 1;
- if (frv_string_begins_with (section_name, ".sbss"))
- is_small = 1;
- }
- else
- abort ();
- }
-
- if (is_small)
- {
- rtx sym_ref = XEXP (DECL_RTL (decl), 0);
- char * str = xmalloc (2 + strlen (XSTR (sym_ref, 0)));
-
- str[0] = SDATA_FLAG_CHAR;
- strcpy (&str[1], XSTR (sym_ref, 0));
- XSTR (sym_ref, 0) = str;
- }
- }
-}
-
/* Zero or more C statements that may conditionally modify two variables
`fixed_regs' and `call_used_regs' (both of type `char []') after they have
@@ -724,7 +644,7 @@ frv_encode_section_info (decl, first)
target switches are opposed to them.) */
void
-frv_conditional_register_usage ()
+frv_conditional_register_usage (void)
{
int i;
@@ -931,7 +851,7 @@ frv_conditional_register_usage ()
*/
frv_stack_t *
-frv_stack_info ()
+frv_stack_info (void)
{
static frv_stack_t info, zero_info;
frv_stack_t *info_ptr = &info;
@@ -943,14 +863,15 @@ frv_stack_info ()
int alignment;
int offset;
- /* If we've already calculated the values and reload is complete, just return now */
+ /* If we've already calculated the values and reload is complete,
+ just return now. */
if (frv_stack_cache)
return frv_stack_cache;
- /* Zero all fields */
+ /* Zero all fields. */
info = zero_info;
- /* Set up the register range information */
+ /* Set up the register range information. */
info_ptr->regs[STACK_REGS_GPR].name = "gpr";
info_ptr->regs[STACK_REGS_GPR].first = LAST_ARG_REGNUM + 1;
info_ptr->regs[STACK_REGS_GPR].last = GPR_LAST;
@@ -1013,7 +934,7 @@ frv_stack_info ()
}
}
- /* Iterate over all of the register ranges */
+ /* Iterate over all of the register ranges. */
for (range = 0; range < STACK_REGS_MAX; range++)
{
frv_stack_regs_t *reg_ptr = &(info_ptr->regs[range]);
@@ -1023,7 +944,7 @@ frv_stack_info ()
int size_2words = 0;
int regno;
- /* Calculate which registers need to be saved & save area size */
+ /* Calculate which registers need to be saved & save area size. */
switch (range)
{
default:
@@ -1059,9 +980,9 @@ frv_stack_info ()
case STACK_REGS_STDARG:
if (varargs_p)
{
- /* If this is a stdarg function with an non varardic argument split
- between registers and the stack, adjust the saved registers
- downward */
+ /* If this is a stdarg function with a non varardic
+ argument split between registers and the stack,
+ adjust the saved registers downward. */
last -= (ADDR_ALIGN (cfun->pretend_args_size, UNITS_PER_WORD)
/ UNITS_PER_WORD);
@@ -1087,11 +1008,11 @@ frv_stack_info ()
if (size_1word)
{
- /* If this is a field, it only takes one word */
+ /* If this is a field, it only takes one word. */
if (reg_ptr->field_p)
size_1word = UNITS_PER_WORD;
- /* Determine which register pairs can be saved together */
+ /* Determine which register pairs can be saved together. */
else if (reg_ptr->dword_p && TARGET_DWORD)
{
for (regno = first; regno < last; regno += 2)
@@ -1150,7 +1071,7 @@ frv_stack_info ()
info_ptr->header_size = 4 * UNITS_PER_WORD;
info_ptr->total_size += 4 * UNITS_PER_WORD;
- /* Calculate the offsets to save normal register pairs */
+ /* Calculate the offsets to save normal register pairs. */
for (range = 0; range < STACK_REGS_MAX; range++)
{
frv_stack_regs_t *reg_ptr = &(info_ptr->regs[range]);
@@ -1172,7 +1093,7 @@ frv_stack_info ()
}
}
- /* Calculate the offsets to save normal single registers */
+ /* Calculate the offsets to save normal single registers. */
for (range = 0; range < STACK_REGS_MAX; range++)
{
frv_stack_regs_t *reg_ptr = &(info_ptr->regs[range]);
@@ -1256,11 +1177,10 @@ frv_stack_info ()
}
-/* Print the information about the frv stack offsets, etc. when debugging. */
+/* Print the information about the frv stack offsets, etc. when debugging. */
void
-frv_debug_stack (info)
- frv_stack_t *info;
+frv_debug_stack (frv_stack_t *info)
{
int range;
@@ -1319,14 +1239,14 @@ frv_debug_stack (info)
/* The following variable value is TRUE if the next output insn should
finish cpu cycle. In order words the insn will have packing bit
- (which means absence of asm code suffix `.p' on assembler. */
+ (which means absence of asm code suffix `.p' on assembler. */
static int frv_insn_packing_flag;
/* True if the current function contains a far jump. */
static int
-frv_function_contains_far_jump ()
+frv_function_contains_far_jump (void)
{
rtx insn = get_insns ();
while (insn != NULL
@@ -1343,9 +1263,7 @@ frv_function_contains_far_jump ()
will return correctly. It also does the VLIW packing. */
static void
-frv_function_prologue (file, size)
- FILE *file;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+frv_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
/* If no frame was created, check whether the function uses a call
instruction to implement a far jump. If so, save the link in gr3 and
@@ -1392,12 +1310,12 @@ frv_function_prologue (file, size)
/* Return the next available temporary register in a given class. */
static rtx
-frv_alloc_temp_reg (info, class, mode, mark_as_used, no_abort)
- frv_tmp_reg_t *info; /* which registers are available */
- enum reg_class class; /* register class desired */
- enum machine_mode mode; /* mode to allocate register with */
- int mark_as_used; /* register not available after allocation */
- int no_abort; /* return NULL instead of aborting */
+frv_alloc_temp_reg (
+ frv_tmp_reg_t *info, /* which registers are available */
+ enum reg_class class, /* register class desired */
+ enum machine_mode mode, /* mode to allocate register with */
+ int mark_as_used, /* register not available after allocation */
+ int no_abort) /* return NULL instead of aborting */
{
int regno = info->next_reg[ (int)class ];
int orig_regno = regno;
@@ -1439,8 +1357,7 @@ frv_alloc_temp_reg (info, class, mode, mark_as_used, no_abort)
The function returns a constant rtx if OFFSET is small enough, otherwise
it loads the constant into register OFFSET_REGNO and returns that. */
static rtx
-frv_frame_offset_rtx (offset)
- int offset;
+frv_frame_offset_rtx (int offset)
{
rtx offset_rtx = GEN_INT (offset);
if (IN_RANGE_P (offset, -2048, 2047))
@@ -1462,10 +1379,7 @@ frv_frame_offset_rtx (offset)
/* Generate (mem:MODE (plus:Pmode BASE (frv_frame_offset OFFSET)))). The
prologue and epilogue uses such expressions to access the stack. */
static rtx
-frv_frame_mem (mode, base, offset)
- enum machine_mode mode;
- rtx base;
- int offset;
+frv_frame_mem (enum machine_mode mode, rtx base, int offset)
{
return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode,
base,
@@ -1482,9 +1396,7 @@ frv_frame_mem (mode, base, offset)
or SEQUENCE that has several sets, each set must be individually marked
as frame-related. */
static rtx
-frv_dwarf_store (reg, offset)
- rtx reg;
- int offset;
+frv_dwarf_store (rtx reg, int offset)
{
rtx set = gen_rtx_SET (VOIDmode,
gen_rtx_MEM (GET_MODE (reg),
@@ -1501,9 +1413,7 @@ frv_dwarf_store (reg, offset)
frame-related and has a REG_FRAME_RELATED_EXPR note containing
DWARF_PATTERN. */
static void
-frv_frame_insn (pattern, dwarf_pattern)
- rtx pattern;
- rtx dwarf_pattern;
+frv_frame_insn (rtx pattern, rtx dwarf_pattern)
{
rtx insn = emit_insn (pattern);
RTX_FRAME_RELATED_P (insn) = 1;
@@ -1522,7 +1432,7 @@ frv_frame_insn (pattern, dwarf_pattern)
simply be the stack pointer, but if several accesses are being made to a
region far away from the stack pointer, it may be more efficient to set
up a temporary instead.
-
+
Store instructions will be frame-related and will be annotated with the
overall effect of the store. Load instructions will be followed by a
(use) to prevent later optimizations from zapping them.
@@ -1530,10 +1440,7 @@ frv_frame_insn (pattern, dwarf_pattern)
The function takes care of the moves to and from SPRs, using TEMP_REGNO
as a temporary in such cases. */
static void
-frv_frame_access (accessor, reg, stack_offset)
- frv_frame_accessor_t *accessor;
- rtx reg;
- int stack_offset;
+frv_frame_access (frv_frame_accessor_t *accessor, rtx reg, int stack_offset)
{
enum machine_mode mode = GET_MODE (reg);
rtx mem = frv_frame_mem (mode,
@@ -1584,10 +1491,9 @@ frv_frame_access (accessor, reg, stack_offset)
is the stack information generated by frv_stack_info, and REG_SET is the
number of the register set to transfer. */
static void
-frv_frame_access_multi (accessor, info, reg_set)
- frv_frame_accessor_t *accessor;
- frv_stack_t *info;
- int reg_set;
+frv_frame_access_multi (frv_frame_accessor_t *accessor,
+ frv_stack_t *info,
+ int reg_set)
{
frv_stack_regs_t *regs_info;
int regno;
@@ -1607,9 +1513,7 @@ frv_frame_access_multi (accessor, info, reg_set)
them if OP is FRV_LOAD. INFO is the stack information generated by
frv_stack_info. */
static void
-frv_frame_access_standard_regs (op, info)
- enum frv_stack_op op;
- frv_stack_t *info;
+frv_frame_access_standard_regs (enum frv_stack_op op, frv_stack_t *info)
{
frv_frame_accessor_t accessor;
@@ -1619,7 +1523,7 @@ frv_frame_access_standard_regs (op, info)
frv_frame_access_multi (&accessor, info, STACK_REGS_GPR);
frv_frame_access_multi (&accessor, info, STACK_REGS_FPR);
frv_frame_access_multi (&accessor, info, STACK_REGS_LCR);
-}
+}
/* Called after register allocation to add any instructions needed for the
@@ -1632,7 +1536,7 @@ frv_frame_access_standard_regs (op, info)
Also any insns generated here should have RTX_FRAME_RELATED_P(insn) = 1
so that the debug info generation code can handle them properly. */
void
-frv_expand_prologue ()
+frv_expand_prologue (void)
{
frv_stack_t *info = frv_stack_info ();
rtx sp = stack_pointer_rtx;
@@ -1733,7 +1637,7 @@ frv_expand_prologue ()
if (info->stdarg_size > 0)
emit_insn (gen_blockage ());
- /* Set up pic register/small data register for this function. */
+ /* Set up pic register/small data register for this function. */
if (flag_pic && cfun->uses_pic_offset_table)
emit_insn (gen_pic_prologue (gen_rtx_REG (Pmode, PIC_REGNO),
gen_rtx_REG (Pmode, LR_REGNO),
@@ -1742,19 +1646,18 @@ frv_expand_prologue ()
/* Under frv, all of the work is done via frv_expand_epilogue, but
- this function provides a convient place to do cleanup. */
+ this function provides a convenient place to do cleanup. */
static void
-frv_function_epilogue (file, size)
- FILE *file ATTRIBUTE_UNUSED;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+frv_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
frv_stack_cache = (frv_stack_t *)0;
- /* zap last used registers for conditional execution. */
- memset ((PTR) &frv_ifcvt.tmp_reg, 0, sizeof (frv_ifcvt.tmp_reg));
+ /* Zap last used registers for conditional execution. */
+ memset (&frv_ifcvt.tmp_reg, 0, sizeof (frv_ifcvt.tmp_reg));
- /* release the bitmap of created insns. */
+ /* Release the bitmap of created insns. */
BITMAP_XFREE (frv_ifcvt.scratch_insns_bitmap);
}
@@ -1772,8 +1675,7 @@ frv_function_epilogue (file, size)
slots for arguments passed to the current function. */
void
-frv_expand_epilogue (sibcall_p)
- int sibcall_p;
+frv_expand_epilogue (int sibcall_p)
{
frv_stack_t *info = frv_stack_info ();
rtx fp = frame_pointer_rtx;
@@ -1874,30 +1776,27 @@ frv_expand_epilogue (sibcall_p)
varargs. */
static void
-frv_asm_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
- FILE *file;
- tree thunk_fndecl ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
- tree function;
+frv_asm_output_mi_thunk (FILE *file,
+ tree thunk_fndecl ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
+ tree function)
{
const char *name_func = XSTR (XEXP (DECL_RTL (function), 0), 0);
const char *name_arg0 = reg_names[FIRST_ARG_REGNUM];
const char *name_jmp = reg_names[JUMP_REGNO];
const char *parallel = ((PACKING_FLAG_USED_P ()) ? ".p" : "");
- /* Do the add using an addi if possible */
+ /* Do the add using an addi if possible. */
if (IN_RANGE_P (delta, -2048, 2047))
fprintf (file, "\taddi %s,#%d,%s\n", name_arg0, (int) delta, name_arg0);
else
{
- const char *name_add = reg_names[TEMP_REGNO];
- fprintf (file, "\tsethi%s #hi(", parallel);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta);
- fprintf (file, "),%s\n", name_add);
- fprintf (file, "\tsetlo #lo(");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta);
- fprintf (file, "),%s\n", name_add);
+ const char *const name_add = reg_names[TEMP_REGNO];
+ fprintf (file, "\tsethi%s #hi(" HOST_WIDE_INT_PRINT_DEC "),%s\n",
+ parallel, delta, name_add);
+ fprintf (file, "\tsetlo #lo(" HOST_WIDE_INT_PRINT_DEC "),%s\n",
+ delta, name_add);
fprintf (file, "\tadd %s,%s,%s\n", name_add, name_arg0, name_arg0);
}
@@ -1937,7 +1836,7 @@ frv_asm_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
fprintf (file, "\tadd %s,%s,%s\n", name_gppic, name_tmp, name_jmp);
}
- /* Jump to the function address */
+ /* Jump to the function address. */
fprintf (file, "\tjmpl @(%s,%s)\n", name_jmp, reg_names[GPR_FIRST+0]);
}
@@ -1961,10 +1860,10 @@ frv_asm_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
register can be allocated for ordinary usage, unless you mark it as a fixed
register. See `FIXED_REGISTERS' for more information. */
-/* On frv, create a frame whenever we need to create stack */
+/* On frv, create a frame whenever we need to create stack. */
int
-frv_frame_pointer_required ()
+frv_frame_pointer_required (void)
{
if (! current_function_is_leaf)
return TRUE;
@@ -1998,9 +1897,7 @@ frv_frame_pointer_required ()
/* See frv_stack_info for more details on the frv stack frame. */
int
-frv_initial_elimination_offset (from, to)
- int from;
- int to;
+frv_initial_elimination_offset (int from, int to)
{
frv_stack_t *info = frv_stack_info ();
int ret = 0;
@@ -2009,7 +1906,7 @@ frv_initial_elimination_offset (from, to)
ret = info->total_size - info->pretend_size;
else if (to == STACK_POINTER_REGNUM && from == FRAME_POINTER_REGNUM)
- ret = - info->reg_offset[FRAME_POINTER_REGNUM];
+ ret = info->reg_offset[FRAME_POINTER_REGNUM];
else if (to == FRAME_POINTER_REGNUM && from == ARG_POINTER_REGNUM)
ret = (info->total_size
@@ -2057,12 +1954,11 @@ frv_initial_elimination_offset (from, to)
this case. */
void
-frv_setup_incoming_varargs (cum, mode, type, pretend_size, second_time)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type ATTRIBUTE_UNUSED;
- int *pretend_size;
- int second_time;
+frv_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
+ enum machine_mode mode,
+ tree type ATTRIBUTE_UNUSED,
+ int *pretend_size,
+ int second_time)
{
if (TARGET_DEBUG_ARG)
fprintf (stderr,
@@ -2081,7 +1977,7 @@ frv_setup_incoming_varargs (cum, mode, type, pretend_size, second_time)
the library function `__builtin_saveregs'. */
rtx
-frv_expand_builtin_saveregs ()
+frv_expand_builtin_saveregs (void)
{
int offset = UNITS_PER_WORD * FRV_NUM_ARG_REGS;
@@ -2096,9 +1992,7 @@ frv_expand_builtin_saveregs ()
/* Expand __builtin_va_start to do the va_start macro. */
void
-frv_expand_builtin_va_start (valist, nextarg)
- tree valist;
- rtx nextarg;
+frv_expand_builtin_va_start (tree valist, rtx nextarg)
{
tree t;
int num = cfun->args_info - FIRST_ARG_REGNUM - FRV_NUM_ARG_REGS;
@@ -2125,9 +2019,7 @@ frv_expand_builtin_va_start (valist, nextarg)
/* Expand __builtin_va_arg to do the va_arg macro. */
rtx
-frv_expand_builtin_va_arg(valist, type)
- tree valist;
- tree type;
+frv_expand_builtin_va_arg (tree valist, tree type)
{
rtx addr;
rtx mem;
@@ -2172,8 +2064,7 @@ frv_expand_builtin_va_arg(valist, type)
#endif
int
-frv_expand_block_move (operands)
- rtx operands[];
+frv_expand_block_move (rtx operands[])
{
rtx orig_dest = operands[0];
rtx orig_src = operands[1];
@@ -2196,11 +2087,11 @@ frv_expand_block_move (operands)
int move_bytes;
enum machine_mode mode;
- /* If this is not a fixed size move, just call memcpy */
+ /* If this is not a fixed size move, just call memcpy. */
if (! constp)
return FALSE;
- /* If this is not a fixed size alignment, abort */
+ /* If this is not a fixed size alignment, abort. */
if (GET_CODE (align_rtx) != CONST_INT)
abort ();
@@ -2222,7 +2113,7 @@ frv_expand_block_move (operands)
num_reg = offset = 0;
for ( ; bytes > 0; (bytes -= move_bytes), (offset += move_bytes))
{
- /* Calculate the correct offset for src/dest */
+ /* Calculate the correct offset for src/dest. */
if (offset == 0)
{
src_addr = src_reg;
@@ -2273,8 +2164,7 @@ frv_expand_block_move (operands)
operands[2] is the alignment */
int
-frv_expand_block_clear (operands)
- rtx operands[];
+frv_expand_block_clear (rtx operands[])
{
rtx orig_dest = operands[0];
rtx bytes_rtx = operands[1];
@@ -2290,11 +2180,11 @@ frv_expand_block_clear (operands)
int clear_bytes;
enum machine_mode mode;
- /* If this is not a fixed size move, just call memcpy */
+ /* If this is not a fixed size move, just call memcpy. */
if (! constp)
return FALSE;
- /* If this is not a fixed size alignment, abort */
+ /* If this is not a fixed size alignment, abort. */
if (GET_CODE (align_rtx) != CONST_INT)
abort ();
@@ -2315,12 +2205,12 @@ frv_expand_block_clear (operands)
num_reg = offset = 0;
for ( ; bytes > 0; (bytes -= clear_bytes), (offset += clear_bytes))
{
- /* Calculate the correct offset for src/dest */
+ /* Calculate the correct offset for src/dest. */
dest_addr = ((offset == 0)
? dest_reg
: plus_constant (dest_reg, offset));
- /* Generate the appropriate store of gr0 */
+ /* Generate the appropriate store of gr0. */
if (bytes >= 4 && align >= 4)
mode = SImode;
else if (bytes >= 2 && align >= 2)
@@ -2338,17 +2228,15 @@ frv_expand_block_clear (operands)
/* The following variable is used to output modifiers of assembler
- code of the current output insn.. */
+ code of the current output insn. */
static rtx *frv_insn_operands;
/* The following function is used to add assembler insn code suffix .p
- if it is necessary. */
+ if it is necessary. */
const char *
-frv_asm_output_opcode (f, ptr)
- FILE *f;
- const char *ptr;
+frv_asm_output_opcode (FILE *f, const char *ptr)
{
int c;
@@ -2380,18 +2268,15 @@ frv_asm_output_opcode (f, ptr)
/* The following function sets up the packing bit for the current
output insn. Remember that the function is not called for asm
- insns. */
+ insns. */
void
-frv_final_prescan_insn (insn, opvec, noperands)
- rtx insn;
- rtx *opvec;
- int noperands ATTRIBUTE_UNUSED;
+frv_final_prescan_insn (rtx insn, rtx *opvec, int noperands ATTRIBUTE_UNUSED)
{
if (! PACKING_FLAG_USED_P())
return;
- if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
+ if (!INSN_P (insn))
return;
frv_insn_operands = opvec;
@@ -2403,8 +2288,8 @@ frv_final_prescan_insn (insn, opvec, noperands)
Printable instructions will be asm_operands or match one of the .md
patterns. Since asm instructions cannot be packed -- and will
- therefore have TImode -- this loop terminates on any recognisable
- instruction, and on any unrecognisable instruction with TImode. */
+ therefore have TImode -- this loop terminates on any recognizable
+ instruction, and on any unrecognizable instruction with TImode. */
for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
{
if (NOTE_P (insn))
@@ -2417,7 +2302,7 @@ frv_final_prescan_insn (insn, opvec, noperands)
/* Set frv_insn_packing_flag to FALSE if the next instruction should
be packed with this one. Set it to TRUE otherwise. If the next
- instruction is an asm insntruction, this statement will set the
+ instruction is an asm instruction, this statement will set the
flag to TRUE, and that value will still hold when the asm operands
themselves are printed. */
frv_insn_packing_flag = ! (insn && INSN_P (insn)
@@ -2436,8 +2321,7 @@ frv_final_prescan_insn (insn, opvec, noperands)
/* The default is correct, but we need to make sure the frame gets created. */
rtx
-frv_dynamic_chain_address (frame)
- rtx frame;
+frv_dynamic_chain_address (rtx frame)
{
cfun->machine->frame_needed = 1;
return frame;
@@ -2455,9 +2339,7 @@ frv_dynamic_chain_address (frame)
address of other frames. */
rtx
-frv_return_addr_rtx (count, frame)
- int count ATTRIBUTE_UNUSED;
- rtx frame;
+frv_return_addr_rtx (int count ATTRIBUTE_UNUSED, rtx frame)
{
cfun->machine->frame_needed = 1;
return gen_rtx_MEM (Pmode, plus_constant (frame, 8));
@@ -2472,10 +2354,7 @@ frv_return_addr_rtx (count, frame)
GO_IF_LEGITIMATE_ADDRESS forbids register+register addresses, which
this function cannot handle. */
rtx
-frv_index_memory (memref, mode, index)
- rtx memref;
- enum machine_mode mode;
- int index;
+frv_index_memory (rtx memref, enum machine_mode mode, int index)
{
rtx base = XEXP (memref, 0);
if (GET_CODE (base) == PRE_MODIFY)
@@ -2487,9 +2366,7 @@ frv_index_memory (memref, mode, index)
/* Print a memory address as an operand to reference that memory location. */
void
-frv_print_operand_address (stream, x)
- FILE * stream;
- rtx x;
+frv_print_operand_address (FILE * stream, rtx x)
{
if (GET_CODE (x) == MEM)
x = XEXP (x, 0);
@@ -2522,9 +2399,7 @@ frv_print_operand_address (stream, x)
static void
-frv_print_operand_memory_reference_reg (stream, x)
- FILE *stream;
- rtx x;
+frv_print_operand_memory_reference_reg (FILE * stream, rtx x)
{
int regno = true_regnum (x);
if (GPR_P (regno))
@@ -2536,10 +2411,7 @@ frv_print_operand_memory_reference_reg (stream, x)
/* Print a memory reference suitable for the ld/st instructions. */
static void
-frv_print_operand_memory_reference (stream, x, addr_offset)
- FILE *stream;
- rtx x;
- int addr_offset;
+frv_print_operand_memory_reference (FILE * stream, rtx x, int addr_offset)
{
rtx x0 = NULL_RTX;
rtx x1 = NULL_RTX;
@@ -2611,7 +2483,7 @@ frv_print_operand_memory_reference (stream, x, addr_offset)
case SYMBOL_REF:
if (x0 && GET_CODE (x0) == REG && REGNO (x0) == SDA_BASE_REG
- && symbol_ref_small_data_p (x1))
+ && SYMBOL_REF_SMALL_P (x1))
{
fputs ("#gprel12(", stream);
assemble_name (stream, XSTR (x1, 0));
@@ -2627,7 +2499,8 @@ frv_print_operand_memory_reference (stream, x, addr_offset)
{
fputs ("#gprel12(", stream);
assemble_name (stream, XSTR (XEXP (XEXP (x1, 0), 0), 0));
- fprintf (stream, "+%d)", INTVAL (XEXP (XEXP (x1, 0), 1)));
+ fprintf (stream, "+"HOST_WIDE_INT_PRINT_DEC")",
+ INTVAL (XEXP (XEXP (x1, 0), 1)));
}
else
fatal_insn ("Bad insn to frv_print_operand_memory_reference:", x);
@@ -2648,8 +2521,7 @@ frv_print_operand_memory_reference (stream, x, addr_offset)
#define FRV_JUMP_NOT_LIKELY 0
static int
-frv_print_operand_jump_hint (insn)
- rtx insn;
+frv_print_operand_jump_hint (rtx insn)
{
rtx note;
rtx labelref;
@@ -2746,10 +2618,7 @@ frv_print_operand_jump_hint (insn)
are valid with the `PRINT_OPERAND_PUNCT_VALID_P' macro. */
void
-frv_print_operand (file, x, code)
- FILE * file;
- rtx x;
- int code;
+frv_print_operand (FILE * file, rtx x, int code)
{
HOST_WIDE_INT value;
int offset;
@@ -2786,7 +2655,7 @@ frv_print_operand (file, x, code)
{
case '.':
- /* Output r0 */
+ /* Output r0. */
fputs (reg_names[GPR_R0], file);
break;
@@ -2794,30 +2663,30 @@ frv_print_operand (file, x, code)
fprintf (file, "%d", frv_print_operand_jump_hint (current_output_insn));
break;
- case SDATA_FLAG_CHAR:
- /* Output small data area base register (gr16). */
+ case '@':
+ /* Output small data area base register (gr16). */
fputs (reg_names[SDA_BASE_REG], file);
break;
case '~':
- /* Output pic register (gr17). */
+ /* Output pic register (gr17). */
fputs (reg_names[PIC_REGNO], file);
break;
case '*':
- /* Output the temporary integer CCR register */
+ /* Output the temporary integer CCR register. */
fputs (reg_names[ICR_TEMP], file);
break;
case '&':
- /* Output the temporary integer CC register */
+ /* Output the temporary integer CC register. */
fputs (reg_names[ICC_TEMP], file);
break;
- /* case 'a': print an address */
+ /* case 'a': print an address. */
case 'C':
- /* Print appropriate test for integer branch false operation */
+ /* Print appropriate test for integer branch false operation. */
switch (GET_CODE (x))
{
default:
@@ -2840,7 +2709,7 @@ frv_print_operand (file, x, code)
CONSTANT_ADDRESS_P(x) is not true, PRINT_OPERAND is called. */
case 'c':
- /* Print appropriate test for integer branch true operation */
+ /* Print appropriate test for integer branch true operation. */
switch (GET_CODE (x))
{
default:
@@ -2873,7 +2742,7 @@ frv_print_operand (file, x, code)
break;
case 'F':
- /* Print appropriate test for floating point branch false operation */
+ /* Print appropriate test for floating point branch false operation. */
switch (GET_CODE (x))
{
default:
@@ -2889,7 +2758,7 @@ frv_print_operand (file, x, code)
break;
case 'f':
- /* Print appropriate test for floating point branch true operation */
+ /* Print appropriate test for floating point branch true operation. */
switch (GET_CODE (x))
{
default:
@@ -2906,7 +2775,7 @@ frv_print_operand (file, x, code)
case 'I':
/* Print 'i' if the operand is a constant, or is a memory reference that
- adds a constant */
+ adds a constant. */
if (GET_CODE (x) == MEM)
x = ((GET_CODE (XEXP (x, 0)) == PLUS)
? XEXP (XEXP (x, 0), 1)
@@ -2927,7 +2796,7 @@ frv_print_operand (file, x, code)
case 'i':
/* For jump instructions, print 'i' if the operand is a constant or
- is an expression that adds a constant */
+ is an expression that adds a constant. */
if (GET_CODE (x) == CONST_INT)
fputs ("i", file);
@@ -2949,7 +2818,7 @@ frv_print_operand (file, x, code)
fatal_insn ("Bad insn to frv_print_operand, 'L' modifier:", x);
break;
- /* case 'l': print a LABEL_REF */
+ /* case 'l': print a LABEL_REF. */
case 'M':
case 'N':
@@ -2993,7 +2862,7 @@ frv_print_operand (file, x, code)
}
break;
- /* case 'n': negate and print a constant int */
+ /* case 'n': negate and print a constant int. */
case 'P':
/* Print PIC label using operand as the number. */
@@ -3004,13 +2873,13 @@ frv_print_operand (file, x, code)
break;
case 'U':
- /* Print 'u' if the operand is a update load/store */
+ /* Print 'u' if the operand is a update load/store. */
if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
fputs ("u", file);
break;
case 'z':
- /* If value is 0, print gr0, otherwise it must be a register */
+ /* If value is 0, print gr0, otherwise it must be a register. */
if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0)
fputs (reg_names[GPR_R0], file);
@@ -3022,14 +2891,14 @@ frv_print_operand (file, x, code)
break;
case 'x':
- /* Print constant in hex */
+ /* Print constant in hex. */
if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
{
fprintf (file, "%s0x%.4lx", IMMEDIATE_PREFIX, (long) value);
break;
}
- /* fall through */
+ /* Fall through. */
case '\0':
if (GET_CODE (x) == REG)
@@ -3076,19 +2945,18 @@ frv_print_operand (file, x, code)
FNTYPE is nonzero, but never both of them at once. */
void
-frv_init_cumulative_args (cum, fntype, libname, indirect, incoming)
- CUMULATIVE_ARGS *cum;
- tree fntype;
- rtx libname;
- int indirect;
- int incoming;
+frv_init_cumulative_args (CUMULATIVE_ARGS *cum,
+ tree fntype,
+ rtx libname,
+ tree fndecl,
+ int incoming)
{
*cum = FIRST_ARG_REGNUM;
if (TARGET_DEBUG_ARG)
{
fprintf (stderr, "\ninit_cumulative_args:");
- if (indirect)
+ if (!fndecl && fntype)
fputs (" indirect", stderr);
if (incoming)
@@ -3117,9 +2985,8 @@ frv_init_cumulative_args (cum, fntype, libname, indirect, incoming)
`PARM_BOUNDARY' is used for all arguments. */
int
-frv_function_arg_boundary (mode, type)
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type ATTRIBUTE_UNUSED;
+frv_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED)
{
return BITS_PER_WORD;
}
@@ -3156,12 +3023,11 @@ frv_function_arg_boundary (mode, type)
stack and then loaded into a register. */
rtx
-frv_function_arg (cum, mode, type, named, incoming)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type ATTRIBUTE_UNUSED;
- int named;
- int incoming ATTRIBUTE_UNUSED;
+frv_function_arg (CUMULATIVE_ARGS *cum,
+ enum machine_mode mode,
+ tree type ATTRIBUTE_UNUSED,
+ int named,
+ int incoming ATTRIBUTE_UNUSED)
{
enum machine_mode xmode = (mode == BLKmode) ? SImode : mode;
int arg_num = *cum;
@@ -3206,11 +3072,10 @@ frv_function_arg (cum, mode, type, named, incoming)
for arguments without any special help. */
void
-frv_function_arg_advance (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type ATTRIBUTE_UNUSED;
- int named;
+frv_function_arg_advance (CUMULATIVE_ARGS *cum,
+ enum machine_mode mode,
+ tree type ATTRIBUTE_UNUSED,
+ int named)
{
enum machine_mode xmode = (mode == BLKmode) ? SImode : mode;
int bytes = GET_MODE_SIZE (xmode);
@@ -3243,11 +3108,10 @@ frv_function_arg_advance (cum, mode, type, named)
the called function. */
int
-frv_function_arg_partial_nregs (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type ATTRIBUTE_UNUSED;
- int named ATTRIBUTE_UNUSED;
+frv_function_arg_partial_nregs (CUMULATIVE_ARGS *cum,
+ enum machine_mode mode,
+ tree type ATTRIBUTE_UNUSED,
+ int named ATTRIBUTE_UNUSED)
{
enum machine_mode xmode = (mode == BLKmode) ? SImode : mode;
int bytes = GET_MODE_SIZE (xmode);
@@ -3280,11 +3144,10 @@ frv_function_arg_partial_nregs (cum, mode, type, named)
MUST_PASS_IN_STACK (MODE, TYPE) */
int
-frv_function_arg_pass_by_reference (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
+frv_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode,
+ tree type,
+ int named ATTRIBUTE_UNUSED)
{
return MUST_PASS_IN_STACK (mode, type);
}
@@ -3299,11 +3162,10 @@ frv_function_arg_pass_by_reference (cum, mode, type, named)
otherwise a copy must be made. */
int
-frv_function_arg_callee_copies (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type ATTRIBUTE_UNUSED;
- int named ATTRIBUTE_UNUSED;
+frv_function_arg_callee_copies (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED,
+ int named ATTRIBUTE_UNUSED)
{
return 0;
}
@@ -3313,11 +3175,10 @@ frv_function_arg_callee_copies (cum, mode, type, named)
copying it to a pseudo register. */
int
-frv_function_arg_keep_as_reference (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type ATTRIBUTE_UNUSED;
- int named ATTRIBUTE_UNUSED;
+frv_function_arg_keep_as_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED,
+ int named ATTRIBUTE_UNUSED)
{
return 0;
}
@@ -3326,9 +3187,7 @@ frv_function_arg_keep_as_reference (cum, mode, type, named)
/* Return true if a register is ok to use as a base or index register. */
static FRV_INLINE int
-frv_regno_ok_for_base_p (regno, strict_p)
- int regno;
- int strict_p;
+frv_regno_ok_for_base_p (int regno, int strict_p)
{
if (GPR_P (regno))
return TRUE;
@@ -3400,11 +3259,10 @@ frv_regno_ok_for_base_p (regno, strict_p)
`PRINT_OPERAND_ADDRESS'. */
int
-frv_legitimate_address_p (mode, x, strict_p, condexec_p)
- enum machine_mode mode;
- rtx x;
- int strict_p;
- int condexec_p;
+frv_legitimate_address_p (enum machine_mode mode,
+ rtx x,
+ int strict_p,
+ int condexec_p)
{
rtx x0, x1;
int ret = 0;
@@ -3421,7 +3279,7 @@ frv_legitimate_address_p (mode, x, strict_p, condexec_p)
if (GET_CODE (x) != REG)
break;
- /* fall through */
+ /* Fall through. */
case REG:
ret = frv_regno_ok_for_base_p (REGNO (x), strict_p);
@@ -3481,11 +3339,11 @@ frv_legitimate_address_p (mode, x, strict_p, condexec_p)
if (GET_CODE (x1) != REG)
break;
- /* fall through */
+ /* Fall through. */
case REG:
- /* Do not allow reg+reg addressing for modes > 1 word if we can't depend
- on having move double instructions */
+ /* Do not allow reg+reg addressing for modes > 1 word if we
+ can't depend on having move double instructions. */
if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
ret = FALSE;
else
@@ -3511,7 +3369,7 @@ frv_legitimate_address_p (mode, x, strict_p, condexec_p)
case SYMBOL_REF:
if (!condexec_p
&& regno0 == SDA_BASE_REG
- && symbol_ref_small_data_p (x1))
+ && SYMBOL_REF_SMALL_P (x1))
ret = TRUE;
break;
@@ -3557,10 +3415,9 @@ frv_legitimate_address_p (mode, x, strict_p, condexec_p)
can generate better code. */
rtx
-frv_legitimize_address (x, oldx, mode)
- rtx x;
- rtx oldx ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+frv_legitimize_address (rtx x,
+ rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
rtx ret = NULL_RTX;
@@ -3569,7 +3426,7 @@ frv_legitimize_address (x, oldx, mode)
things up when force_reg is called to try and put it in a register because
we aren't optimizing. */
if (optimize
- && ((GET_CODE (x) == SYMBOL_REF && symbol_ref_small_data_p (x))
+ && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
|| (GET_CODE (x) == CONST && const_small_data_p (x))))
{
ret = gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, SDA_BASE_REG), x);
@@ -3591,10 +3448,7 @@ frv_legitimize_address (x, oldx, mode)
the operand is used by a predicated instruction. */
static int
-frv_legitimate_memory_operand (op, mode, condexec_p)
- rtx op;
- enum machine_mode mode;
- int condexec_p;
+frv_legitimate_memory_operand (rtx op, enum machine_mode mode, int condexec_p)
{
return ((GET_MODE (op) == mode || mode == VOIDmode)
&& GET_CODE (op) == MEM
@@ -3606,9 +3460,8 @@ frv_legitimate_memory_operand (op, mode, condexec_p)
/* Return 1 is OP is a memory operand, or will be turned into one by
reload. */
-int frv_load_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+frv_load_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return FALSE;
@@ -3629,9 +3482,8 @@ int frv_load_operand (op, mode)
/* Return 1 if operand is a GPR register or a FPR register. */
-int gpr_or_fpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+gpr_or_fpr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -3658,9 +3510,8 @@ int gpr_or_fpr_operand (op, mode)
/* Return 1 if operand is a GPR register or 12 bit signed immediate. */
-int gpr_or_int12_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+gpr_or_int12_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return IN_RANGE_P (INTVAL (op), -2048, 2047);
@@ -3685,9 +3536,8 @@ int gpr_or_int12_operand (op, mode)
/* Return 1 if operand is a GPR register, or a FPR register, or a 12 bit
signed immediate. */
-int gpr_fpr_or_int12_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+gpr_fpr_or_int12_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -3717,9 +3567,8 @@ int gpr_fpr_or_int12_operand (op, mode)
/* Return 1 if operand is a register or 6 bit signed immediate. */
-int fpr_or_int6_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+fpr_or_int6_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return IN_RANGE_P (INTVAL (op), -32, 31);
@@ -3743,9 +3592,8 @@ int fpr_or_int6_operand (op, mode)
/* Return 1 if operand is a register or 10 bit signed immediate. */
-int gpr_or_int10_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+gpr_or_int10_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return IN_RANGE_P (INTVAL (op), -512, 511);
@@ -3769,9 +3617,8 @@ int gpr_or_int10_operand (op, mode)
/* Return 1 if operand is a register or an integer immediate. */
-int gpr_or_int_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+int
+gpr_or_int_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return TRUE;
@@ -3795,9 +3642,8 @@ int gpr_or_int_operand (op, mode)
/* Return 1 if operand is a 12 bit signed immediate. */
-int int12_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+int12_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return FALSE;
@@ -3807,9 +3653,8 @@ int int12_operand (op, mode)
/* Return 1 if operand is a 6 bit signed immediate. */
-int int6_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+int6_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return FALSE;
@@ -3819,36 +3664,32 @@ int int6_operand (op, mode)
/* Return 1 if operand is a 5 bit signed immediate. */
-int int5_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+int5_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), -16, 15);
}
/* Return 1 if operand is a 5 bit unsigned immediate. */
-int uint5_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+uint5_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 31);
}
/* Return 1 if operand is a 4 bit unsigned immediate. */
-int uint4_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+uint4_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 15);
}
/* Return 1 if operand is a 1 bit unsigned immediate (0 or 1). */
-int uint1_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+uint1_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == CONST_INT && IN_RANGE_P (INTVAL (op), 0, 1);
}
@@ -3856,9 +3697,8 @@ int uint1_operand (op, mode)
/* Return 1 if operand is an integer constant that takes 2 instructions
to load up and can be split into sethi/setlo instructions.. */
-int int_2word_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+int_2word_operand(rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT value;
REAL_VALUE_TYPE rv;
@@ -3878,7 +3718,7 @@ int int_2word_operand (op, mode)
case SYMBOL_REF:
/* small data references are already 1 word */
- return (flag_pic == 0) && (! symbol_ref_small_data_p (op));
+ return (flag_pic == 0) && (! SYMBOL_REF_SMALL_P (op));
case CONST_INT:
return ! IN_RANGE_P (INTVAL (op), -32768, 32767);
@@ -3904,9 +3744,7 @@ int int_2word_operand (op, mode)
/* Return 1 if operand is the pic address register. */
int
-pic_register_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+pic_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (! flag_pic)
return FALSE;
@@ -3921,11 +3759,10 @@ pic_register_operand (op, mode)
}
/* Return 1 if operand is a symbolic reference when a PIC option is specified
- that takes 3 seperate instructions to form. */
+ that takes 3 separate instructions to form. */
-int pic_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+pic_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (! flag_pic)
return FALSE;
@@ -3940,7 +3777,7 @@ int pic_symbolic_operand (op, mode)
case SYMBOL_REF:
/* small data references are already 1 word */
- return ! symbol_ref_small_data_p (op);
+ return ! SYMBOL_REF_SMALL_P (op);
case CONST:
/* small data references are already 1 word */
@@ -3952,9 +3789,7 @@ int pic_symbolic_operand (op, mode)
/* Return 1 if operand is the small data register. */
int
-small_data_register_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+small_data_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != REG)
return FALSE;
@@ -3968,9 +3803,8 @@ small_data_register_operand (op, mode)
/* Return 1 if operand is a symbolic reference to a small data area static or
global object. */
-int small_data_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+small_data_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
@@ -3981,17 +3815,16 @@ int small_data_symbolic_operand (op, mode)
return const_small_data_p (op);
case SYMBOL_REF:
- return symbol_ref_small_data_p (op);
+ return SYMBOL_REF_SMALL_P (op);
}
return FALSE;
}
-/* Return 1 if operand is a 16 bit unsigned immediate */
+/* Return 1 if operand is a 16 bit unsigned immediate. */
-int uint16_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+uint16_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return FALSE;
@@ -3999,11 +3832,11 @@ int uint16_operand (op, mode)
return IN_RANGE_P (INTVAL (op), 0, 0xffff);
}
-/* Return 1 if operand is an integer constant with the bottom 16 bits clear */
+/* Return 1 if operand is an integer constant with the bottom 16 bits
+ clear. */
-int upper_int16_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+int
+upper_int16_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return FALSE;
@@ -4011,12 +3844,10 @@ int upper_int16_operand (op, mode)
return ((INTVAL (op) & 0xffff) == 0);
}
-/* Return true if operand is a GPR register. */
+/* Return true if operand is a GPR register. */
int
-integer_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+integer_register_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return FALSE;
@@ -4039,9 +3870,7 @@ integer_register_operand (op, mode)
here, in order to prevent a combine bug. */
int
-gpr_no_subreg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gpr_no_subreg_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return FALSE;
@@ -4052,12 +3881,10 @@ gpr_no_subreg_operand (op, mode)
return GPR_OR_PSEUDO_P (REGNO (op));
}
-/* Return true if operand is a FPR register. */
+/* Return true if operand is a FPR register. */
int
-fpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fpr_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return FALSE;
@@ -4076,12 +3903,10 @@ fpr_operand (op, mode)
return FPR_OR_PSEUDO_P (REGNO (op));
}
-/* Return true if operand is an even GPR or FPR register. */
+/* Return true if operand is an even GPR or FPR register. */
int
-even_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+even_reg_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4112,12 +3937,10 @@ even_reg_operand (op, mode)
return FALSE;
}
-/* Return true if operand is an odd GPR register. */
+/* Return true if operand is an odd GPR register. */
int
-odd_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+odd_reg_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4136,7 +3959,7 @@ odd_reg_operand (op, mode)
return FALSE;
regno = REGNO (op);
- /* assume that reload will give us an even register */
+ /* Assume that reload will give us an even register. */
if (regno >= FIRST_PSEUDO_REGISTER)
return FALSE;
@@ -4149,12 +3972,10 @@ odd_reg_operand (op, mode)
return FALSE;
}
-/* Return true if operand is an even GPR register. */
+/* Return true if operand is an even GPR register. */
int
-even_gpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+even_gpr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4182,12 +4003,10 @@ even_gpr_operand (op, mode)
return (((regno - GPR_FIRST) & 1) == 0);
}
-/* Return true if operand is an odd GPR register. */
+/* Return true if operand is an odd GPR register. */
int
-odd_gpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+odd_gpr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4206,7 +4025,7 @@ odd_gpr_operand (op, mode)
return FALSE;
regno = REGNO (op);
- /* assume that reload will give us an even register */
+ /* Assume that reload will give us an even register. */
if (regno >= FIRST_PSEUDO_REGISTER)
return FALSE;
@@ -4216,12 +4035,10 @@ odd_gpr_operand (op, mode)
return (((regno - GPR_FIRST) & 1) != 0);
}
-/* Return true if operand is a quad aligned FPR register. */
+/* Return true if operand is a quad aligned FPR register. */
int
-quad_fpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+quad_fpr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4249,12 +4066,10 @@ quad_fpr_operand (op, mode)
return (((regno - FPR_FIRST) & 3) == 0);
}
-/* Return true if operand is an even FPR register. */
+/* Return true if operand is an even FPR register. */
int
-even_fpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+even_fpr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4282,12 +4097,10 @@ even_fpr_operand (op, mode)
return (((regno - FPR_FIRST) & 1) == 0);
}
-/* Return true if operand is an odd FPR register. */
+/* Return true if operand is an odd FPR register. */
int
-odd_fpr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+odd_fpr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4306,7 +4119,7 @@ odd_fpr_operand (op, mode)
return FALSE;
regno = REGNO (op);
- /* assume that reload will give us an even register */
+ /* Assume that reload will give us an even register. */
if (regno >= FIRST_PSEUDO_REGISTER)
return FALSE;
@@ -4324,9 +4137,7 @@ odd_fpr_operand (op, mode)
the stack and the address taken and passed through to another function. */
int
-dbl_memory_one_insn_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+dbl_memory_one_insn_operand (rtx op, enum machine_mode mode)
{
rtx addr;
rtx addr_reg;
@@ -4377,9 +4188,7 @@ dbl_memory_one_insn_operand (op, mode)
use two instructions to load or store. */
int
-dbl_memory_two_insn_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+dbl_memory_two_insn_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != MEM)
return FALSE;
@@ -4397,9 +4206,7 @@ dbl_memory_two_insn_operand (op, mode)
operation. */
int
-move_destination_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+move_destination_operand (rtx op, enum machine_mode mode)
{
rtx subreg;
enum rtx_code code;
@@ -4441,9 +4248,7 @@ move_destination_operand (op, mode)
operation. */
int
-move_source_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+move_source_operand (rtx op, enum machine_mode mode)
{
rtx subreg;
enum rtx_code code;
@@ -4492,9 +4297,7 @@ move_source_operand (op, mode)
move operation. */
int
-condexec_dest_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_dest_operand (rtx op, enum machine_mode mode)
{
rtx subreg;
enum rtx_code code;
@@ -4536,9 +4339,7 @@ condexec_dest_operand (op, mode)
move operation. */
int
-condexec_source_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_source_operand (rtx op, enum machine_mode mode)
{
rtx subreg;
enum rtx_code code;
@@ -4584,9 +4385,7 @@ condexec_source_operand (op, mode)
appropriate type. */
int
-reg_or_0_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_0_operand (rtx op, enum machine_mode mode)
{
switch (GET_CODE (op))
{
@@ -4608,12 +4407,10 @@ reg_or_0_operand (op, mode)
return FALSE;
}
-/* Return true if operand is the link register */
+/* Return true if operand is the link register. */
int
-lr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+lr_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != REG)
return FALSE;
@@ -4630,9 +4427,7 @@ lr_operand (op, mode)
/* Return true if operand is a gpr register or a valid memory operation. */
int
-gpr_or_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gpr_or_memory_operand (rtx op, enum machine_mode mode)
{
return (integer_register_operand (op, mode)
|| frv_legitimate_memory_operand (op, mode, FALSE));
@@ -4641,20 +4436,16 @@ gpr_or_memory_operand (op, mode)
/* Return true if operand is a fpr register or a valid memory operation. */
int
-fpr_or_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fpr_or_memory_operand (rtx op, enum machine_mode mode)
{
return (fpr_operand (op, mode)
|| frv_legitimate_memory_operand (op, mode, FALSE));
}
-/* Return true if operand is an icc register */
+/* Return true if operand is an icc register. */
int
-icc_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+icc_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4668,12 +4459,10 @@ icc_operand (op, mode)
return ICC_OR_PSEUDO_P (regno);
}
-/* Return true if operand is an fcc register */
+/* Return true if operand is an fcc register. */
int
-fcc_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fcc_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4687,12 +4476,10 @@ fcc_operand (op, mode)
return FCC_OR_PSEUDO_P (regno);
}
-/* Return true if operand is either an fcc or icc register */
+/* Return true if operand is either an fcc or icc register. */
int
-cc_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+cc_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4709,12 +4496,10 @@ cc_operand (op, mode)
return FALSE;
}
-/* Return true if operand is an integer CCR register */
+/* Return true if operand is an integer CCR register. */
int
-icr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+icr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4728,12 +4513,10 @@ icr_operand (op, mode)
return ICR_OR_PSEUDO_P (regno);
}
-/* Return true if operand is an fcc register */
+/* Return true if operand is an fcc register. */
int
-fcr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fcr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4747,12 +4530,10 @@ fcr_operand (op, mode)
return FCR_OR_PSEUDO_P (regno);
}
-/* Return true if operand is either an fcc or icc register */
+/* Return true if operand is either an fcc or icc register. */
int
-cr_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+cr_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -4772,9 +4553,7 @@ cr_operand (op, mode)
/* Return true if operand is a memory reference suitable for a call. */
int
-call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+call_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode && GET_CODE (op) != CONST_INT)
return FALSE;
@@ -4789,12 +4568,10 @@ call_operand (op, mode)
return gpr_or_int12_operand (op, mode);
}
-/* Return true if operator is an kind of relational operator */
+/* Return true if operator is a kind of relational operator. */
int
-relational_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+relational_operator (rtx op, enum machine_mode mode)
{
rtx op0;
rtx op1;
@@ -4849,12 +4626,10 @@ relational_operator (op, mode)
return FALSE;
}
-/* Return true if operator is a signed integer relational operator */
+/* Return true if operator is a signed integer relational operator. */
int
-signed_relational_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+signed_relational_operator (rtx op, enum machine_mode mode)
{
rtx op0;
rtx op1;
@@ -4895,12 +4670,10 @@ signed_relational_operator (op, mode)
return FALSE;
}
-/* Return true if operator is a signed integer relational operator */
+/* Return true if operator is a signed integer relational operator. */
int
-unsigned_relational_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+unsigned_relational_operator (rtx op, enum machine_mode mode)
{
rtx op0;
rtx op1;
@@ -4939,12 +4712,10 @@ unsigned_relational_operator (op, mode)
return FALSE;
}
-/* Return true if operator is a floating point relational operator */
+/* Return true if operator is a floating point relational operator. */
int
-float_relational_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+float_relational_operator (rtx op, enum machine_mode mode)
{
rtx op0;
rtx op1;
@@ -4992,9 +4763,7 @@ float_relational_operator (op, mode)
/* Return true if operator is EQ/NE of a conditional execution register. */
int
-ccr_eqne_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+ccr_eqne_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
rtx op0;
@@ -5033,9 +4802,7 @@ ccr_eqne_operator (op, mode)
unsigned). */
int
-minmax_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+minmax_operator (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && mode != GET_MODE (op))
return FALSE;
@@ -5065,9 +4832,7 @@ minmax_operator (op, mode)
conditionally and takes 1 cycle. */
int
-condexec_si_binary_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_si_binary_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5095,9 +4860,7 @@ condexec_si_binary_operator (op, mode)
executed conditionally by a media instruction. */
int
-condexec_si_media_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_si_media_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5120,9 +4883,7 @@ condexec_si_media_operator (op, mode)
conditionally. */
int
-condexec_si_divide_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_si_divide_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5144,9 +4905,7 @@ condexec_si_divide_operator (op, mode)
conditionally. */
int
-condexec_si_unary_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_si_unary_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5168,9 +4927,7 @@ condexec_si_unary_operator (op, mode)
evaluated conditionally by floating-point instructions. */
int
-condexec_sf_conv_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_sf_conv_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5193,9 +4950,7 @@ condexec_sf_conv_operator (op, mode)
instructions. */
int
-condexec_sf_add_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_sf_add_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5217,9 +4972,7 @@ condexec_sf_add_operator (op, mode)
executed. */
int
-condexec_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_memory_operand (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
rtx addr;
@@ -5256,9 +5009,7 @@ condexec_memory_operand (op, mode)
register. */
int
-intop_compare_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+intop_compare_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5291,9 +5042,7 @@ intop_compare_operator (op, mode)
with a setcc operation inside of a conditional execution. */
int
-condexec_intop_cmp_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+condexec_intop_cmp_operator (rtx op, enum machine_mode mode)
{
enum machine_mode op_mode = GET_MODE (op);
@@ -5322,12 +5071,10 @@ condexec_intop_cmp_operator (op, mode)
return TRUE;
}
-/* Return 1 if operand is a valid ACC register number */
+/* Return 1 if operand is a valid ACC register number. */
int
-acc_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+acc_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -5349,12 +5096,10 @@ acc_operand (op, mode)
return ACC_OR_PSEUDO_P (regno);
}
-/* Return 1 if operand is a valid even ACC register number */
+/* Return 1 if operand is a valid even ACC register number. */
int
-even_acc_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+even_acc_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -5376,12 +5121,10 @@ even_acc_operand (op, mode)
return (ACC_OR_PSEUDO_P (regno) && ((regno - ACC_FIRST) & 1) == 0);
}
-/* Return 1 if operand is zero or four */
+/* Return 1 if operand is zero or four. */
int
-quad_acc_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+quad_acc_operand (rtx op, enum machine_mode mode)
{
int regno;
@@ -5403,12 +5146,10 @@ quad_acc_operand (op, mode)
return (ACC_OR_PSEUDO_P (regno) && ((regno - ACC_FIRST) & 3) == 0);
}
-/* Return 1 if operand is a valid ACCG register number */
+/* Return 1 if operand is a valid ACCG register number. */
int
-accg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+accg_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return FALSE;
@@ -5432,7 +5173,7 @@ accg_operand (op, mode)
epilog code. For frv, we only do it if there was no stack allocation. */
int
-direct_return_p ()
+direct_return_p (void)
{
frv_stack_t *info;
@@ -5449,9 +5190,7 @@ direct_return_p ()
instructions are emitted. */
int
-frv_emit_movsi (dest, src)
- rtx dest;
- rtx src;
+frv_emit_movsi (rtx dest, rtx src)
{
int base_regno = -1;
@@ -5461,7 +5200,7 @@ frv_emit_movsi (dest, src)
&& (!reg_or_0_operand (src, SImode)
/* Virtual registers will almost always be replaced by an
add instruction, so expose this to CSE by copying to
- an intermediate register */
+ an intermediate register. */
|| (GET_CODE (src) == REG
&& IN_RANGE_P (REGNO (src),
FIRST_VIRTUAL_REGISTER,
@@ -5493,7 +5232,7 @@ frv_emit_movsi (dest, src)
break;
case SYMBOL_REF:
- if (symbol_ref_small_data_p (src))
+ if (SYMBOL_REF_SMALL_P (src))
base_regno = SDA_BASE_REG;
else if (flag_pic)
@@ -5522,9 +5261,7 @@ frv_emit_movsi (dest, src)
/* Return a string to output a single word move. */
const char *
-output_move_single (operands, insn)
- rtx operands[];
- rtx insn;
+output_move_single (rtx operands[], rtx insn)
{
rtx dest = operands[0];
rtx src = operands[1];
@@ -5742,9 +5479,7 @@ output_move_single (operands, insn)
/* Return a string to output a double word move. */
const char *
-output_move_double (operands, insn)
- rtx operands[];
- rtx insn;
+output_move_double (rtx operands[], rtx insn)
{
rtx dest = operands[0];
rtx src = operands[1];
@@ -5875,9 +5610,7 @@ output_move_double (operands, insn)
Operand3 -- source */
const char *
-output_condmove_single (operands, insn)
- rtx operands[];
- rtx insn;
+output_condmove_single (rtx operands[], rtx insn)
{
rtx dest = operands[2];
rtx src = operands[3];
@@ -6016,15 +5749,12 @@ output_condmove_single (operands, insn)
comparison was done it. */
static rtx
-frv_emit_comparison (test, op0, op1)
- enum rtx_code test;
- rtx op0;
- rtx op1;
+frv_emit_comparison (enum rtx_code test, rtx op0, rtx op1)
{
enum machine_mode cc_mode;
rtx cc_reg;
- /* Floating point doesn't have comparison against a constant */
+ /* Floating point doesn't have comparison against a constant. */
if (GET_MODE (op0) == CC_FPmode && GET_CODE (op1) != REG)
op1 = force_reg (GET_MODE (op0), op1);
@@ -6050,9 +5780,7 @@ frv_emit_comparison (test, op0, op1)
conditional execution, but that confuses the rest of the compiler. */
int
-frv_emit_cond_branch (test, label)
- enum rtx_code test;
- rtx label;
+frv_emit_cond_branch (enum rtx_code test, rtx label)
{
rtx test_rtx;
rtx label_ref;
@@ -6077,9 +5805,7 @@ frv_emit_cond_branch (test, label)
operands were previously stored in frv_compare_op0 and frv_compare_op1. */
int
-frv_emit_scc (test, target)
- enum rtx_code test;
- rtx target;
+frv_emit_scc (enum rtx_code test, rtx target)
{
rtx set;
rtx test_rtx;
@@ -6107,15 +5833,10 @@ frv_emit_scc (test, target)
/* Split a SCC instruction into component parts, returning a SEQUENCE to hold
- the seperate insns. */
+ the separate insns. */
rtx
-frv_split_scc (dest, test, cc_reg, cr_reg, value)
- rtx dest;
- rtx test;
- rtx cc_reg;
- rtx cr_reg;
- HOST_WIDE_INT value;
+frv_split_scc (rtx dest, rtx test, rtx cc_reg, rtx cr_reg, HOST_WIDE_INT value)
{
rtx ret;
@@ -6150,11 +5871,7 @@ frv_split_scc (dest, test, cc_reg, cr_reg, value)
move. */
int
-frv_emit_cond_move (dest, test_rtx, src1, src2)
- rtx dest;
- rtx test_rtx;
- rtx src1;
- rtx src2;
+frv_emit_cond_move (rtx dest, rtx test_rtx, rtx src1, rtx src2)
{
rtx set;
rtx clobber_cc;
@@ -6178,7 +5895,7 @@ frv_emit_cond_move (dest, test_rtx, src1, src2)
HOST_WIDE_INT value1 = INTVAL (src1);
HOST_WIDE_INT value2 = INTVAL (src2);
- /* having 0 as one of the constants can be done by loading the other
+ /* Having 0 as one of the constants can be done by loading the other
constant, and optionally moving in gr0. */
if (value1 == 0 || value2 == 0)
;
@@ -6227,12 +5944,11 @@ frv_emit_cond_move (dest, test_rtx, src1, src2)
}
-/* Split a conditonal move into constituent parts, returning a SEQUENCE
+/* Split a conditional move into constituent parts, returning a SEQUENCE
containing all of the insns. */
rtx
-frv_split_cond_move (operands)
- rtx operands[];
+frv_split_cond_move (rtx operands[])
{
rtx dest = operands[0];
rtx test = operands[1];
@@ -6259,7 +5975,7 @@ frv_split_cond_move (operands)
HOST_WIDE_INT value1 = INTVAL (src1);
HOST_WIDE_INT value2 = INTVAL (src2);
- /* having 0 as one of the constants can be done by loading the other
+ /* Having 0 as one of the constants can be done by loading the other
constant, and optionally moving in gr0. */
if (value1 == 0)
{
@@ -6327,9 +6043,7 @@ frv_split_cond_move (operands)
/* Split (set DEST SOURCE), where DEST is a double register and SOURCE is a
memory location that is not known to be dword-aligned. */
void
-frv_split_double_load (dest, source)
- rtx dest;
- rtx source;
+frv_split_double_load (rtx dest, rtx source)
{
int regno = REGNO (dest);
rtx dest1 = gen_highpart (SImode, dest);
@@ -6365,9 +6079,7 @@ frv_split_double_load (dest, source)
/* Split (set DEST SOURCE), where DEST refers to a dword memory location
and SOURCE is either a double register or the constant zero. */
void
-frv_split_double_store (dest, source)
- rtx dest;
- rtx source;
+frv_split_double_store (rtx dest, rtx source)
{
rtx dest1 = change_address (dest, SImode, NULL);
rtx dest2 = frv_index_memory (dest, SImode, 1);
@@ -6388,8 +6100,7 @@ frv_split_double_store (dest, source)
insns. */
rtx
-frv_split_minmax (operands)
- rtx operands[];
+frv_split_minmax (rtx operands[])
{
rtx dest = operands[0];
rtx minmax = operands[1];
@@ -6403,7 +6114,7 @@ frv_split_minmax (operands)
start_sequence ();
- /* Figure out which test to use */
+ /* Figure out which test to use. */
switch (GET_CODE (minmax))
{
default:
@@ -6469,8 +6180,7 @@ frv_split_minmax (operands)
insns. */
rtx
-frv_split_abs (operands)
- rtx operands[];
+frv_split_abs (rtx operands[])
{
rtx dest = operands[0];
rtx src = operands[1];
@@ -6490,7 +6200,7 @@ frv_split_abs (operands)
cr_reg,
gen_rtx_fmt_ee (LT, CC_CCRmode, cc_reg, const0_rtx)));
- /* Emit the conditional negate if the value is negative */
+ /* Emit the conditional negate if the value is negative. */
emit_insn (gen_rtx_COND_EXEC (VOIDmode,
gen_rtx_NE (CC_CCRmode, cr_reg, const0_rtx),
gen_negsi2 (dest, src)));
@@ -6512,9 +6222,7 @@ frv_split_abs (operands)
register used in an insn. */
static int
-frv_clear_registers_used (ptr, data)
- rtx *ptr;
- void *data;
+frv_clear_registers_used (rtx *ptr, void *data)
{
if (GET_CODE (*ptr) == REG)
{
@@ -6542,8 +6250,7 @@ frv_clear_registers_used (ptr, data)
/* On the FR-V, we don't have any extra fields per se, but it is useful hook to
initialize the static storage. */
void
-frv_ifcvt_init_extra_fields (ce_info)
- ce_if_block_t *ce_info ATTRIBUTE_UNUSED;
+frv_ifcvt_init_extra_fields (ce_if_block_t *ce_info ATTRIBUTE_UNUSED)
{
frv_ifcvt.added_insns_list = NULL_RTX;
frv_ifcvt.cur_scratch_regs = 0;
@@ -6560,14 +6267,11 @@ frv_ifcvt_init_extra_fields (ce_info)
if the conditional execution conversion is successful. */
static void
-frv_ifcvt_add_insn (pattern, insn, before_p)
- rtx pattern;
- rtx insn;
- int before_p;
+frv_ifcvt_add_insn (rtx pattern, rtx insn, int before_p)
{
rtx link = alloc_EXPR_LIST (VOIDmode, pattern, insn);
- link->jump = before_p; /* mark to add this before or after insn */
+ link->jump = before_p; /* Mark to add this before or after insn. */
frv_ifcvt.added_insns_list = alloc_EXPR_LIST (VOIDmode, link,
frv_ifcvt.added_insns_list);
@@ -6590,10 +6294,7 @@ frv_ifcvt_add_insn (pattern, insn, before_p)
tests cannot be converted. */
void
-frv_ifcvt_modify_tests (ce_info, p_true, p_false)
- ce_if_block_t *ce_info;
- rtx *p_true;
- rtx *p_false;
+frv_ifcvt_modify_tests (ce_if_block_t *ce_info, rtx *p_true, rtx *p_false)
{
basic_block test_bb = ce_info->test_bb; /* test basic block */
basic_block then_bb = ce_info->then_bb; /* THEN */
@@ -6628,8 +6329,8 @@ frv_ifcvt_modify_tests (ce_info, p_true, p_false)
/* Figure out which registers we can allocate for our own purposes. Only
consider registers that are not preserved across function calls and are
not fixed. However, allow the ICC/ICR temporary registers to be allocated
- if we did not need to use them in reloading other registers. */
- memset ((PTR) &tmp_reg->regs, 0, sizeof (tmp_reg->regs));
+ if we did not need to use them in reloading other registers. */
+ memset (&tmp_reg->regs, 0, sizeof (tmp_reg->regs));
COPY_HARD_REG_SET (tmp_reg->regs, call_used_reg_set);
AND_COMPL_HARD_REG_SET (tmp_reg->regs, fixed_reg_set);
SET_HARD_REG_BIT (tmp_reg->regs, ICC_TEMP);
@@ -6704,16 +6405,16 @@ frv_ifcvt_modify_tests (ce_info, p_true, p_false)
/* Scan all of the blocks for registers that must not be allocated. */
for (j = 0; j < num_bb; j++)
{
- rtx last_insn = bb[j]->end;
- rtx insn = bb[j]->head;
+ rtx last_insn = BB_END (bb[j]);
+ rtx insn = BB_HEAD (bb[j]);
int regno;
if (rtl_dump_file)
fprintf (rtl_dump_file, "Scanning %s block %d, start %d, end %d\n",
(bb[j] == else_bb) ? "else" : ((bb[j] == then_bb) ? "then" : "test"),
(int) bb[j]->index,
- (int) INSN_UID (bb[j]->head),
- (int) INSN_UID (bb[j]->end));
+ (int) INSN_UID (BB_HEAD (bb[j])),
+ (int) INSN_UID (BB_END (bb[j])));
/* Anything live at the beginning of the block is obviously unavailable
for allocation. */
@@ -6723,7 +6424,7 @@ frv_ifcvt_modify_tests (ce_info, p_true, p_false)
CLEAR_HARD_REG_BIT (tmp_reg->regs, regno);
});
- /* loop through the insns in the block. */
+ /* Loop through the insns in the block. */
for (;;)
{
/* Mark any new registers that are created as being unavailable for
@@ -6913,7 +6614,7 @@ frv_ifcvt_modify_tests (ce_info, p_true, p_false)
gen_rtx_fmt_ee (code, CC_CCRmode, cc, const0_rtx));
/* Record the check insn to be inserted later. */
- frv_ifcvt_add_insn (check_insn, test_bb->end, TRUE);
+ frv_ifcvt_add_insn (check_insn, BB_END (test_bb), TRUE);
/* Update the tests. */
frv_ifcvt.cr_reg = cr;
@@ -6947,11 +6648,10 @@ frv_ifcvt_modify_tests (ce_info, p_true, p_false)
(const_int 0))) */
void
-frv_ifcvt_modify_multiple_tests (ce_info, bb, p_true, p_false)
- ce_if_block_t *ce_info;
- basic_block bb;
- rtx *p_true;
- rtx *p_false;
+frv_ifcvt_modify_multiple_tests (ce_if_block_t *ce_info,
+ basic_block bb,
+ rtx *p_true,
+ rtx *p_false)
{
rtx old_true = XEXP (*p_true, 0);
rtx old_false = XEXP (*p_false, 0);
@@ -6987,7 +6687,7 @@ frv_ifcvt_modify_multiple_tests (ce_info, bb, p_true, p_false)
if (GET_CODE (cr) != REG)
goto fail;
-
+
if (mode == CCmode || mode == CC_UNSmode)
{
cr_class = ICR_REGS;
@@ -7032,7 +6732,7 @@ frv_ifcvt_modify_multiple_tests (ce_info, bb, p_true, p_false)
/* First add the andcr/andncr/orcr/orncr, which will be added after the
conditional check instruction, due to frv_ifcvt_add_insn being a LIFO
stack. */
- frv_ifcvt_add_insn ((*logical_func) (cr, cr, new_cr), bb->end, TRUE);
+ frv_ifcvt_add_insn ((*logical_func) (cr, cr, new_cr), BB_END (bb), TRUE);
/* Now add the conditional check insn. */
cc = XEXP (test_expr, 0);
@@ -7041,9 +6741,9 @@ frv_ifcvt_modify_multiple_tests (ce_info, bb, p_true, p_false)
check_insn = gen_rtx_SET (VOIDmode, new_cr, if_else);
- /* add the new check insn to the list of check insns that need to be
+ /* Add the new check insn to the list of check insns that need to be
inserted. */
- frv_ifcvt_add_insn (check_insn, bb->end, TRUE);
+ frv_ifcvt_add_insn (check_insn, BB_END (bb), TRUE);
if (TARGET_DEBUG_COND_EXEC)
{
@@ -7061,7 +6761,7 @@ frv_ifcvt_modify_multiple_tests (ce_info, bb, p_true, p_false)
fail:
*p_true = *p_false = NULL_RTX;
- /* If we allocated a CR register, release it. */
+ /* If we allocated a CR register, release it. */
if (new_cr)
{
CLEAR_HARD_REG_BIT (frv_ifcvt.tmp_reg.regs, REGNO (new_cr));
@@ -7080,9 +6780,7 @@ frv_ifcvt_modify_multiple_tests (ce_info, bb, p_true, p_false)
that use constants to ones that just use registers. */
static rtx
-frv_ifcvt_load_value (value, insn)
- rtx value;
- rtx insn ATTRIBUTE_UNUSED;
+frv_ifcvt_load_value (rtx value, rtx insn ATTRIBUTE_UNUSED)
{
int num_alloc = frv_ifcvt.cur_scratch_regs;
int i;
@@ -7104,7 +6802,7 @@ frv_ifcvt_load_value (value, insn)
}
}
- /* Have we exhausted the number of registers available? */
+ /* Have we exhausted the number of registers available? */
if (num_alloc >= GPR_TEMP_NUM)
{
if (rtl_dump_file)
@@ -7152,10 +6850,7 @@ frv_ifcvt_load_value (value, insn)
into a temporary register, or the new MEM if we were successful. */
static rtx
-frv_ifcvt_rewrite_mem (mem, mode, insn)
- rtx mem;
- enum machine_mode mode;
- rtx insn;
+frv_ifcvt_rewrite_mem (rtx mem, enum machine_mode mode, rtx insn)
{
rtx addr = XEXP (mem, 0);
@@ -7203,8 +6898,7 @@ frv_ifcvt_rewrite_mem (mem, mode, insn)
SET, possibly conditionally executed. It may also have CLOBBERs, USEs. */
static rtx
-single_set_pattern (pattern)
- rtx pattern;
+single_set_pattern (rtx pattern)
{
rtx set;
int i;
@@ -7251,10 +6945,9 @@ single_set_pattern (pattern)
insn cannot be converted to be executed conditionally. */
rtx
-frv_ifcvt_modify_insn (ce_info, pattern, insn)
- ce_if_block_t *ce_info ATTRIBUTE_UNUSED;
- rtx pattern;
- rtx insn;
+frv_ifcvt_modify_insn (ce_if_block_t *ce_info,
+ rtx pattern,
+ rtx insn)
{
rtx orig_ce_pattern = pattern;
rtx set;
@@ -7316,7 +7009,7 @@ frv_ifcvt_modify_insn (ce_info, pattern, insn)
rtx src = SET_SRC (set);
enum machine_mode mode = GET_MODE (dest);
- /* Check for normal binary operators */
+ /* Check for normal binary operators. */
if (mode == SImode
&& (GET_RTX_CLASS (GET_CODE (src)) == '2'
|| GET_RTX_CLASS (GET_CODE (src)) == 'c'))
@@ -7378,7 +7071,16 @@ frv_ifcvt_modify_insn (ce_info, pattern, insn)
other registers. */
else if (frv_ifcvt.scratch_insns_bitmap
&& bitmap_bit_p (frv_ifcvt.scratch_insns_bitmap,
- INSN_UID (insn)))
+ INSN_UID (insn))
+ /* We must not unconditionally set a reg set used as
+ scratch in the THEN branch if the same reg is live
+ in the ELSE branch. */
+ && REG_P (SET_DEST (set))
+ && (! ce_info->else_bb
+ || BLOCK_FOR_INSN (insn) == ce_info->else_bb
+ || ! (REGNO_REG_SET_P
+ (ce_info->else_bb->global_live_at_start,
+ REGNO (SET_DEST (set))))))
pattern = set;
else if (mode == QImode || mode == HImode || mode == SImode
@@ -7506,8 +7208,7 @@ frv_ifcvt_modify_insn (ce_info, pattern, insn)
conditional if information CE_INFO. */
void
-frv_ifcvt_modify_final (ce_info)
- ce_if_block_t *ce_info ATTRIBUTE_UNUSED;
+frv_ifcvt_modify_final (ce_if_block_t *ce_info ATTRIBUTE_UNUSED)
{
rtx existing_insn;
rtx check_insn;
@@ -7563,8 +7264,7 @@ frv_ifcvt_modify_final (ce_info)
information CE_INFO. */
void
-frv_ifcvt_modify_cancel (ce_info)
- ce_if_block_t *ce_info ATTRIBUTE_UNUSED;
+frv_ifcvt_modify_cancel (ce_if_block_t *ce_info ATTRIBUTE_UNUSED)
{
int i;
rtx p = frv_ifcvt.added_insns_list;
@@ -7599,7 +7299,7 @@ frv_ifcvt_modify_cancel (ce_info)
jmpl @(gr0,<jmp_reg>) */
int
-frv_trampoline_size ()
+frv_trampoline_size (void)
{
return 5 /* instructions */ * 4 /* instruction size */;
}
@@ -7619,10 +7319,7 @@ frv_trampoline_size ()
jmpl @(gr0,<jmp_reg>) */
void
-frv_initialize_trampoline (addr, fnaddr, static_chain)
- rtx addr;
- rtx fnaddr;
- rtx static_chain;
+frv_initialize_trampoline (rtx addr, rtx fnaddr, rtx static_chain)
{
rtx sc_reg = force_reg (Pmode, static_chain);
@@ -7688,11 +7385,10 @@ frv_initialize_trampoline (addr, fnaddr, static_chain)
This case often occurs between floating-point and general registers. */
enum reg_class
-frv_secondary_reload_class (class, mode, x, in_p)
- enum reg_class class;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx x;
- int in_p ATTRIBUTE_UNUSED;
+frv_secondary_reload_class (enum reg_class class,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx x,
+ int in_p ATTRIBUTE_UNUSED)
{
enum reg_class ret;
@@ -7768,8 +7464,7 @@ frv_secondary_reload_class (class, mode, x, in_p)
register allocation. */
int
-frv_class_likely_spilled_p (class)
- enum reg_class class;
+frv_class_likely_spilled_p (enum reg_class class)
{
switch (class)
{
@@ -7797,7 +7492,7 @@ frv_class_likely_spilled_p (class)
/* An expression for the alignment of a structure field FIELD if the
- alignment computed in the usual way is COMPUTED. GNU CC uses this
+ alignment computed in the usual way is COMPUTED. GCC uses this
value instead of the value in `BIGGEST_ALIGNMENT' or
`BIGGEST_FIELD_ALIGNMENT', if defined, for structure fields only. */
@@ -7844,19 +7539,16 @@ frv_class_likely_spilled_p (class)
*/
int
-frv_adjust_field_align (field, computed)
- tree field;
- int computed;
+frv_adjust_field_align (tree field, int computed)
{
- /* C++ provides a null DECL_CONTEXT if the bit field is wider than its
- type. */
- if (DECL_BIT_FIELD (field) && DECL_CONTEXT (field))
+ /* Make sure that the bitfield is not wider than the type. */
+ if (DECL_BIT_FIELD (field)
+ && !DECL_ARTIFICIAL (field))
{
tree parent = DECL_CONTEXT (field);
tree prev = NULL_TREE;
tree cur;
- /* Loop finding the previous field to the current one */
for (cur = TYPE_FIELDS (parent); cur && cur != field; cur = TREE_CHAIN (cur))
{
if (TREE_CODE (cur) != FIELD_DECL)
@@ -7870,7 +7562,7 @@ frv_adjust_field_align (field, computed)
/* If this isn't a :0 field and if the previous element is a bitfield
also, see if the type is different, if so, we will need to align the
- bit-field to the next boundary */
+ bit-field to the next boundary. */
if (prev
&& ! DECL_PACKED (field)
&& ! integer_zerop (DECL_SIZE (field))
@@ -7941,9 +7633,7 @@ frv_adjust_field_align (field, computed)
pattern's constraint asks for one. */
int
-frv_hard_regno_mode_ok (regno, mode)
- int regno;
- enum machine_mode mode;
+frv_hard_regno_mode_ok (int regno, enum machine_mode mode)
{
int base;
int mask;
@@ -7979,8 +7669,8 @@ frv_hard_regno_mode_ok (regno, mode)
}
else
{
- /* The other registers store one word. */
- if (GPR_P (regno))
+ /* The other registers store one word. */
+ if (GPR_P (regno) || regno == AP_FIRST)
base = GPR_FIRST;
else if (FPR_P (regno))
@@ -7989,6 +7679,10 @@ frv_hard_regno_mode_ok (regno, mode)
else if (ACC_P (regno))
base = ACC_FIRST;
+ else if (SPR_P (regno))
+ return mode == SImode;
+
+ /* Fill in the table. */
else
return 0;
@@ -8021,9 +7715,7 @@ frv_hard_regno_mode_ok (regno, mode)
for each byte. */
int
-frv_hard_regno_nregs (regno, mode)
- int regno;
- enum machine_mode mode;
+frv_hard_regno_nregs (int regno, enum machine_mode mode)
{
if (ACCG_P (regno))
return GET_MODE_SIZE (mode);
@@ -8045,9 +7737,7 @@ frv_hard_regno_nregs (regno, mode)
This declaration is required. */
int
-frv_class_max_nregs (class, mode)
- enum reg_class class;
- enum machine_mode mode;
+frv_class_max_nregs (enum reg_class class, enum machine_mode mode)
{
if (class == ACCG_REGS)
/* An N-byte value requires N accumulator guards. */
@@ -8063,25 +7753,24 @@ frv_class_max_nregs (class, mode)
definition for this macro on machines where anything `CONSTANT_P' is valid. */
int
-frv_legitimate_constant_p (x)
- rtx x;
+frv_legitimate_constant_p (rtx x)
{
enum machine_mode mode = GET_MODE (x);
- /* All of the integer constants are ok */
+ /* All of the integer constants are ok. */
if (GET_CODE (x) != CONST_DOUBLE)
return TRUE;
- /* double integer constants are ok */
+ /* double integer constants are ok. */
if (mode == VOIDmode || mode == DImode)
return TRUE;
- /* 0 is always ok */
+ /* 0 is always ok. */
if (x == CONST0_RTX (mode))
return TRUE;
/* If floating point is just emulated, allow any constant, since it will be
- constructed in the GPRs */
+ constructed in the GPRs. */
if (!TARGET_HAS_FPRS)
return TRUE;
@@ -8113,9 +7802,7 @@ frv_legitimate_constant_p (x)
#define LOW_COST 1
int
-frv_register_move_cost (from, to)
- enum reg_class from;
- enum reg_class to;
+frv_register_move_cost (enum reg_class from, enum reg_class to)
{
switch (from)
{
@@ -8204,10 +7891,7 @@ frv_register_move_cost (from, to)
need a fixup entry for aligned (non-debugging) code. */
static bool
-frv_assemble_integer (value, size, aligned_p)
- rtx value;
- unsigned int size;
- int aligned_p;
+frv_assemble_integer (rtx value, unsigned int size, int aligned_p)
{
if (flag_pic && size == UNITS_PER_WORD)
{
@@ -8246,22 +7930,54 @@ frv_assemble_integer (value, size, aligned_p)
/* Function to set up the backend function structure. */
static struct machine_function *
-frv_init_machine_status ()
+frv_init_machine_status (void)
{
return ggc_alloc_cleared (sizeof (struct machine_function));
}
+
+/* Implement TARGET_SCHED_ISSUE_RATE. */
+
+static int
+frv_issue_rate (void)
+{
+ if (!TARGET_PACK)
+ return 1;
+
+ switch (frv_cpu_type)
+ {
+ default:
+ case FRV_CPU_FR300:
+ case FRV_CPU_SIMPLE:
+ return 1;
+
+ case FRV_CPU_FR400:
+ return 2;
+
+ case FRV_CPU_GENERIC:
+ case FRV_CPU_FR500:
+ case FRV_CPU_TOMCAT:
+ return 4;
+ }
+}
+
+/* Implement TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE. */
+
+static int
+frv_use_dfa_pipeline_interface (void)
+{
+ return true;
+}
/* Update the register state information, to know about which registers are set
or clobbered. */
static void
-frv_registers_update (x, reg_state, modified, p_num_mod, flag)
- rtx x;
- unsigned char reg_state[];
- int modified[];
- int *p_num_mod;
- int flag;
+frv_registers_update (rtx x,
+ unsigned char reg_state[],
+ int modified[],
+ int *p_num_mod,
+ int flag)
{
int regno, reg_max;
rtx reg;
@@ -8333,7 +8049,7 @@ frv_registers_update (x, reg_state, modified, p_num_mod, flag)
case REG:
regno = REGNO (x);
reg_max = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- /* fall through */
+ /* Fall through. */
reg_common:
if (flag & REGSTATE_MODIFIED)
@@ -8404,10 +8120,7 @@ frv_registers_update (x, reg_state, modified, p_num_mod, flag)
/* Return if any registers in a hard register set were used an insn. */
static int
-frv_registers_used_p (x, reg_state, flag)
- rtx x;
- unsigned char reg_state[];
- int flag;
+frv_registers_used_p (rtx x, unsigned char reg_state[], int flag)
{
int regno, reg_max;
rtx reg;
@@ -8423,7 +8136,7 @@ frv_registers_used_p (x, reg_state, flag)
default:
break;
- /* Skip clobber, that doesn't use the previous value */
+ /* Skip clobber, that doesn't use the previous value. */
case CLOBBER:
return FALSE;
@@ -8488,7 +8201,7 @@ frv_registers_used_p (x, reg_state, flag)
case REG:
regno = REGNO (x);
reg_max = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- /* fall through */
+ /* Fall through. */
reg_common:
while (regno < reg_max)
@@ -8509,7 +8222,7 @@ frv_registers_used_p (x, reg_state, flag)
expression that governs this expression (ie, true vs. false
for the same CC register). If this isn't two halves of the
same conditional expression, consider the register
- modified. */
+ modified. */
if (((rs_if == REGSTATE_IF_TRUE && flag_if == REGSTATE_IF_FALSE)
|| (rs_if == REGSTATE_IF_FALSE && flag_if == REGSTATE_IF_TRUE))
&& ((rs & REGSTATE_CC_MASK) == (flag & REGSTATE_CC_MASK)))
@@ -8564,10 +8277,7 @@ frv_registers_used_p (x, reg_state, flag)
/* Return if any registers in a hard register set were set in an insn. */
static int
-frv_registers_set_p (x, reg_state, modify_p)
- rtx x;
- unsigned char reg_state[];
- int modify_p;
+frv_registers_set_p (rtx x, unsigned char reg_state[], int modify_p)
{
int regno, reg_max;
rtx reg;
@@ -8591,7 +8301,7 @@ frv_registers_set_p (x, reg_state, modify_p)
case COND_EXEC:
cond = XEXP (x, 0);
- /* just to be sure, make sure it is the type of cond_exec we
+ /* Just to be sure, make sure it is the type of cond_exec we
expect. */
if ((GET_CODE (cond) == EQ || GET_CODE (cond) == NE)
&& GET_CODE (XEXP (cond, 0)) == REG
@@ -8622,7 +8332,7 @@ frv_registers_set_p (x, reg_state, modify_p)
case REG:
regno = REGNO (x);
reg_max = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- /* fall through */
+ /* Fall through. */
reg_common:
if (modify_p)
@@ -8672,18 +8382,13 @@ frv_registers_set_p (x, reg_state, modify_p)
}
-/* In rare cases, correct code generation requires extra machine dependent
- processing between the second jump optimization pass and delayed branch
- scheduling. On those machines, define this macro as a C statement to act on
- the code starting at INSN. */
-
/* On the FR-V, this pass is used to rescan the insn chain, and pack
conditional branches/calls/jumps, etc. with previous insns where it can. It
does not reorder the instructions. We assume the scheduler left the flow
information in a reasonable state. */
static void
-frv_pack_insns ()
+frv_pack_insns (void)
{
state_t frv_state; /* frv state machine */
int cur_start_vliw_p; /* current insn starts a VLIW insn */
@@ -8699,27 +8404,16 @@ frv_pack_insns ()
unsigned char reg_state[FIRST_PSEUDO_REGISTER];
/* If we weren't going to pack the insns, don't bother with this pass. */
- if (!optimize || !flag_schedule_insns_after_reload || TARGET_NO_VLIW_BRANCH)
+ if (!optimize
+ || !flag_schedule_insns_after_reload
+ || TARGET_NO_VLIW_BRANCH
+ || frv_issue_rate () == 1)
return;
- switch (frv_cpu_type)
- {
- default:
- case FRV_CPU_FR300: /* FR300/simple are single issue */
- case FRV_CPU_SIMPLE:
- return;
-
- case FRV_CPU_GENERIC: /* FR-V and FR500 are multi-issue */
- case FRV_CPU_FR400:
- case FRV_CPU_FR500:
- case FRV_CPU_TOMCAT:
- break;
- }
-
/* Set up the instruction and register states. */
dfa_start ();
frv_state = (state_t) xmalloc (state_size ());
- memset ((PTR) reg_state, REGSTATE_DEAD, sizeof (reg_state));
+ memset (reg_state, REGSTATE_DEAD, sizeof (reg_state));
/* Go through the insns, and repack the insns. */
state_reset (frv_state);
@@ -8754,7 +8448,7 @@ frv_pack_insns ()
continue;
}
- /* things like labels reset everything. */
+ /* Things like labels reset everything. */
if (GET_RTX_CLASS (code) != 'i')
{
next_start_vliw_p = TRUE;
@@ -8762,7 +8456,7 @@ frv_pack_insns ()
}
/* Clear the VLIW start flag on random USE and CLOBBER insns, which is
- set on the USE insn that preceeds the return, and potentially on
+ set on the USE insn that precedes the return, and potentially on
CLOBBERs for setting multiword variables. Also skip the ADDR_VEC
holding the case table labels. */
pattern_code = GET_CODE (PATTERN (insn));
@@ -8808,7 +8502,7 @@ frv_pack_insns ()
partnering sethi instruction, with which it can be packed.
Although output dependencies are rare they are still
- possible. So check output dependencies in VLIW insn. */
+ possible. So check output dependencies in VLIW insn. */
|| (get_attr_type (insn) != TYPE_SETLO
&& (frv_registers_used_p (PATTERN (insn),
reg_state,
@@ -8835,7 +8529,7 @@ frv_pack_insns ()
/* Record which registers are modified. */
frv_registers_update (PATTERN (insn), reg_state, modified, &num_mod, 0);
- /* Process the death notices */
+ /* Process the death notices. */
for (link = REG_NOTES (insn);
link != NULL_RTX;
link = XEXP (link, 1))
@@ -8852,7 +8546,7 @@ frv_pack_insns ()
}
}
- free ((PTR) frv_state);
+ free (frv_state);
dfa_finish ();
return;
}
@@ -8877,7 +8571,7 @@ static struct builtin_description bdesc_set[] =
{ CODE_FOR_mhdsets, "__MHDSETS", FRV_BUILTIN_MHDSETS, 0, 0 }
};
-/* Media intrinsics that take just one argument. */
+/* Media intrinsics that take just one argument. */
static struct builtin_description bdesc_1arg[] =
{
@@ -8888,7 +8582,7 @@ static struct builtin_description bdesc_1arg[] =
{ CODE_FOR_mabshs, "__MABSHS", FRV_BUILTIN_MABSHS, 0, 0 }
};
-/* Media intrinsics that take two arguments. */
+/* Media intrinsics that take two arguments. */
static struct builtin_description bdesc_2arg[] =
{
@@ -8923,7 +8617,7 @@ static struct builtin_description bdesc_cut[] =
{ CODE_FOR_mdcutssi, "__MDCUTSSI", FRV_BUILTIN_MDCUTSSI, 0, 0 }
};
-/* Two-argument media intrinsics with an immediate second argument. */
+/* Two-argument media intrinsics with an immediate second argument. */
static struct builtin_description bdesc_2argimm[] =
{
@@ -8945,7 +8639,7 @@ static struct builtin_description bdesc_2argimm[] =
};
/* Media intrinsics that take two arguments and return void, the first argument
- being a pointer to 4 words in memory. */
+ being a pointer to 4 words in memory. */
static struct builtin_description bdesc_void2arg[] =
{
@@ -8954,7 +8648,7 @@ static struct builtin_description bdesc_void2arg[] =
};
/* Media intrinsics that take three arguments, the first being a const_int that
- denotes an accumulator, and that return void. */
+ denotes an accumulator, and that return void. */
static struct builtin_description bdesc_void3arg[] =
{
@@ -8998,10 +8692,10 @@ static struct builtin_description bdesc_voidacc[] =
{ CODE_FOR_mdasaccs, "__MDASACCS", FRV_BUILTIN_MDASACCS, 0, 0 }
};
-/* Initialize media builtins. */
+/* Initialize media builtins. */
static void
-frv_init_builtins ()
+frv_init_builtins (void)
{
tree endlink = void_list_node;
tree accumulator = integer_type_node;
@@ -9112,7 +8806,7 @@ frv_init_builtins ()
def_builtin ("__MPACKH", uw1_ftype_uh_uh, FRV_BUILTIN_MPACKH);
def_builtin ("__MUNPACKH", uw2_ftype_uw1, FRV_BUILTIN_MUNPACKH);
def_builtin ("__MDPACKH", uw2_ftype_uw2_uw2, FRV_BUILTIN_MDPACKH);
- def_builtin ("__MDUNPACKH", void_ftype_uw4_uw2, FRV_BUILTIN_MDUNPACKH);
+ def_builtin ("__MDUNPACKH", void_ftype_uw4_uw2, FRV_BUILTIN_MDUNPACKH);
def_builtin ("__MBTOH", uw2_ftype_uw1, FRV_BUILTIN_MBTOH);
def_builtin ("__MHTOB", uw1_ftype_uw2, FRV_BUILTIN_MHTOB);
def_builtin ("__MBTOHE", void_ftype_uw4_uw1, FRV_BUILTIN_MBTOHE);
@@ -9152,6 +8846,54 @@ frv_init_builtins ()
#undef TRINARY
}
+/* Set the names for various arithmetic operations according to the
+ FRV ABI. */
+static void
+frv_init_libfuncs (void)
+{
+ set_optab_libfunc (smod_optab, SImode, "__modi");
+ set_optab_libfunc (umod_optab, SImode, "__umodi");
+
+ set_optab_libfunc (add_optab, DImode, "__addll");
+ set_optab_libfunc (sub_optab, DImode, "__subll");
+ set_optab_libfunc (smul_optab, DImode, "__mulll");
+ set_optab_libfunc (sdiv_optab, DImode, "__divll");
+ set_optab_libfunc (smod_optab, DImode, "__modll");
+ set_optab_libfunc (umod_optab, DImode, "__umodll");
+ set_optab_libfunc (and_optab, DImode, "__andll");
+ set_optab_libfunc (ior_optab, DImode, "__orll");
+ set_optab_libfunc (xor_optab, DImode, "__xorll");
+ set_optab_libfunc (one_cmpl_optab, DImode, "__notll");
+
+ set_optab_libfunc (add_optab, SFmode, "__addf");
+ set_optab_libfunc (sub_optab, SFmode, "__subf");
+ set_optab_libfunc (smul_optab, SFmode, "__mulf");
+ set_optab_libfunc (sdiv_optab, SFmode, "__divf");
+
+ set_optab_libfunc (add_optab, DFmode, "__addd");
+ set_optab_libfunc (sub_optab, DFmode, "__subd");
+ set_optab_libfunc (smul_optab, DFmode, "__muld");
+ set_optab_libfunc (sdiv_optab, DFmode, "__divd");
+
+ set_conv_libfunc (sext_optab, DFmode, SFmode, "__ftod");
+ set_conv_libfunc (trunc_optab, SFmode, DFmode, "__dtof");
+
+ set_conv_libfunc (sfix_optab, SImode, SFmode, "__ftoi");
+ set_conv_libfunc (sfix_optab, DImode, SFmode, "__ftoll");
+ set_conv_libfunc (sfix_optab, SImode, DFmode, "__dtoi");
+ set_conv_libfunc (sfix_optab, DImode, DFmode, "__dtoll");
+
+ set_conv_libfunc (ufix_optab, SImode, SFmode, "__ftoui");
+ set_conv_libfunc (ufix_optab, DImode, SFmode, "__ftoull");
+ set_conv_libfunc (ufix_optab, SImode, DFmode, "__dtoui");
+ set_conv_libfunc (ufix_optab, DImode, DFmode, "__dtoull");
+
+ set_conv_libfunc (sfloat_optab, SFmode, SImode, "__itof");
+ set_conv_libfunc (sfloat_optab, SFmode, DImode, "__lltof");
+ set_conv_libfunc (sfloat_optab, DFmode, SImode, "__itod");
+ set_conv_libfunc (sfloat_optab, DFmode, DImode, "__lltod");
+}
+
/* Convert an integer constant to an accumulator register. ICODE is the
code of the target instruction, OPNUM is the number of the
accumulator operand and OPVAL is the constant integer. Try both
@@ -9159,10 +8901,7 @@ frv_init_builtins ()
instruction. */
static rtx
-frv_int_to_acc (icode, opnum, opval)
- enum insn_code icode;
- int opnum;
- rtx opval;
+frv_int_to_acc (enum insn_code icode, int opnum, rtx opval)
{
rtx reg;
@@ -9194,8 +8933,7 @@ frv_int_to_acc (icode, opnum, opval)
should have. */
static enum machine_mode
-frv_matching_accg_mode (mode)
- enum machine_mode mode;
+frv_matching_accg_mode (enum machine_mode mode)
{
switch (mode)
{
@@ -9218,8 +8956,7 @@ frv_matching_accg_mode (mode)
class as ACC, but is four times smaller. */
rtx
-frv_matching_accg_for_acc (acc)
- rtx acc;
+frv_matching_accg_for_acc (rtx acc)
{
return gen_rtx_REG (frv_matching_accg_mode (GET_MODE (acc)),
REGNO (acc) - ACC_FIRST + ACCG_FIRST);
@@ -9230,8 +8967,7 @@ frv_matching_accg_for_acc (acc)
list. */
static rtx
-frv_read_argument (arglistptr)
- tree *arglistptr;
+frv_read_argument (tree *arglistptr)
{
tree next = TREE_VALUE (*arglistptr);
*arglistptr = TREE_CHAIN (*arglistptr);
@@ -9243,10 +8979,7 @@ frv_read_argument (arglistptr)
function prints an error if OPVAL is not valid. */
static int
-frv_check_constant_argument (icode, opnum, opval)
- enum insn_code icode;
- int opnum;
- rtx opval;
+frv_check_constant_argument (enum insn_code icode, int opnum, rtx opval)
{
if (GET_CODE (opval) != CONST_INT)
{
@@ -9266,9 +8999,7 @@ frv_check_constant_argument (icode, opnum, opval)
predicate. */
static rtx
-frv_legitimize_target (icode, target)
- enum insn_code icode;
- rtx target;
+frv_legitimize_target (enum insn_code icode, rtx target)
{
enum machine_mode mode = insn_data[icode].operand[0].mode;
@@ -9281,15 +9012,12 @@ frv_legitimize_target (icode, target)
}
/* Given that ARG is being passed as operand OPNUM to instruction ICODE,
- check whether ARG satisfies the operand's contraints. If it doesn't,
+ check whether ARG satisfies the operand's constraints. If it doesn't,
copy ARG to a temporary register and return that. Otherwise return ARG
itself. */
static rtx
-frv_legitimize_argument (icode, opnum, arg)
- enum insn_code icode;
- int opnum;
- rtx arg;
+frv_legitimize_argument (enum insn_code icode, int opnum, rtx arg)
{
enum machine_mode mode = insn_data[icode].operand[opnum].mode;
@@ -9303,10 +9031,7 @@ frv_legitimize_argument (icode, opnum, arg)
only MHDSETS falls into this category. */
static rtx
-frv_expand_set_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+frv_expand_set_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9323,13 +9048,10 @@ frv_expand_set_builtin (icode, arglist, target)
return target;
}
-/* Expand builtins that take one operand. */
+/* Expand builtins that take one operand. */
static rtx
-frv_expand_unop_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+frv_expand_unop_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9344,13 +9066,10 @@ frv_expand_unop_builtin (icode, arglist, target)
return target;
}
-/* Expand builtins that take two operands. */
+/* Expand builtins that take two operands. */
static rtx
-frv_expand_binop_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+frv_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9368,13 +9087,10 @@ frv_expand_binop_builtin (icode, arglist, target)
}
/* Expand cut-style builtins, which take two operands and an implicit ACCG
- one. */
+ one. */
static rtx
-frv_expand_cut_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+frv_expand_cut_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9403,13 +9119,10 @@ frv_expand_cut_builtin (icode, arglist, target)
return target;
}
-/* Expand builtins that take two operands and the second is immediate. */
+/* Expand builtins that take two operands and the second is immediate. */
static rtx
-frv_expand_binopimm_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+frv_expand_binopimm_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9429,12 +9142,10 @@ frv_expand_binopimm_builtin (icode, arglist, target)
}
/* Expand builtins that take two operands, the first operand being a pointer to
- ints and return void. */
+ ints and return void. */
static rtx
-frv_expand_voidbinop_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+frv_expand_voidbinop_builtin (enum insn_code icode, tree arglist)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9475,9 +9186,7 @@ frv_expand_voidbinop_builtin (icode, arglist)
corresponds to the accumulator. */
static rtx
-frv_expand_voidtriop_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+frv_expand_voidtriop_builtin (enum insn_code icode, tree arglist)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9505,9 +9214,7 @@ frv_expand_voidtriop_builtin (icode, arglist)
void. */
static rtx
-frv_expand_voidaccop_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+frv_expand_voidaccop_builtin (enum insn_code icode, tree arglist)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9537,8 +9244,7 @@ frv_expand_voidaccop_builtin (icode, arglist)
number as argument. */
static rtx
-frv_expand_mclracc_builtin (arglist)
- tree arglist;
+frv_expand_mclracc_builtin (tree arglist)
{
enum insn_code icode = CODE_FOR_mclracc;
rtx pat;
@@ -9558,8 +9264,7 @@ frv_expand_mclracc_builtin (arglist)
/* Expand builtins that take no arguments. */
static rtx
-frv_expand_noargs_builtin (icode)
- enum insn_code icode;
+frv_expand_noargs_builtin (enum insn_code icode)
{
rtx pat = GEN_FCN (icode) (GEN_INT (0));
if (pat)
@@ -9572,9 +9277,7 @@ frv_expand_noargs_builtin (icode)
number or accumulator guard number as argument and return an SI integer. */
static rtx
-frv_expand_mrdacc_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+frv_expand_mrdacc_builtin (enum insn_code icode, tree arglist)
{
rtx pat;
rtx target = gen_reg_rtx (SImode);
@@ -9597,9 +9300,7 @@ frv_expand_mrdacc_builtin (icode, arglist)
second. */
static rtx
-frv_expand_mwtacc_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+frv_expand_mwtacc_builtin (enum insn_code icode, tree arglist)
{
rtx pat;
rtx op0 = frv_read_argument (&arglist);
@@ -9617,15 +9318,14 @@ frv_expand_mwtacc_builtin (icode, arglist)
return NULL_RTX;
}
-/* Expand builtins. */
+/* Expand builtins. */
static rtx
-frv_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
+frv_expand_builtin (tree exp,
+ rtx target,
+ rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
{
tree arglist = TREE_OPERAND (exp, 1);
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
@@ -9684,7 +9384,7 @@ frv_expand_builtin (exp, target, subtarget, mode, ignore)
break;
}
- /* Expand unique builtins. */
+ /* Expand unique builtins. */
switch (fcode)
{
@@ -9716,73 +9416,151 @@ frv_expand_builtin (exp, target, subtarget, mode, ignore)
break;
}
- /* Expand groups of builtins. */
+ /* Expand groups of builtins. */
- for (i = 0, d = bdesc_set; i < sizeof (bdesc_set) / sizeof *d; i++, d++)
+ for (i = 0, d = bdesc_set; i < ARRAY_SIZE (bdesc_set); i++, d++)
if (d->code == fcode)
return frv_expand_set_builtin (d->icode, arglist, target);
- for (i = 0, d = bdesc_1arg; i < sizeof (bdesc_1arg) / sizeof *d; i++, d++)
+ for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
if (d->code == fcode)
return frv_expand_unop_builtin (d->icode, arglist, target);
- for (i = 0, d = bdesc_2arg; i < sizeof (bdesc_2arg) / sizeof *d; i++, d++)
+ for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
if (d->code == fcode)
return frv_expand_binop_builtin (d->icode, arglist, target);
- for (i = 0, d = bdesc_cut; i < sizeof (bdesc_cut) / sizeof *d; i++, d++)
+ for (i = 0, d = bdesc_cut; i < ARRAY_SIZE (bdesc_cut); i++, d++)
if (d->code == fcode)
return frv_expand_cut_builtin (d->icode, arglist, target);
- for (i = 0, d = bdesc_2argimm;
- i < sizeof (bdesc_2argimm) / sizeof *d;
- i++, d++)
- {
- if (d->code == fcode)
- return frv_expand_binopimm_builtin (d->icode, arglist, target);
- }
+ for (i = 0, d = bdesc_2argimm; i < ARRAY_SIZE (bdesc_2argimm); i++, d++)
+ if (d->code == fcode)
+ return frv_expand_binopimm_builtin (d->icode, arglist, target);
- for (i = 0, d = bdesc_void2arg;
- i < sizeof (bdesc_void2arg) / sizeof *d;
- i++, d++)
- {
- if (d->code == fcode)
- return frv_expand_voidbinop_builtin (d->icode, arglist);
- }
+ for (i = 0, d = bdesc_void2arg; i < ARRAY_SIZE (bdesc_void2arg); i++, d++)
+ if (d->code == fcode)
+ return frv_expand_voidbinop_builtin (d->icode, arglist);
+
+ for (i = 0, d = bdesc_void3arg; i < ARRAY_SIZE (bdesc_void3arg); i++, d++)
+ if (d->code == fcode)
+ return frv_expand_voidtriop_builtin (d->icode, arglist);
+
+ for (i = 0, d = bdesc_voidacc; i < ARRAY_SIZE (bdesc_voidacc); i++, d++)
+ if (d->code == fcode)
+ return frv_expand_voidaccop_builtin (d->icode, arglist);
+
+ return 0;
+}
- for (i = 0, d = bdesc_void3arg;
- i < sizeof (bdesc_void3arg) / sizeof *d;
- i++, d++)
+static bool
+frv_in_small_data_p (tree decl)
+{
+ HOST_WIDE_INT size;
+ tree section_name;
+
+ /* Don't apply the -G flag to internal compiler structures. We
+ should leave such structures in the main data section, partly
+ for efficiency and partly because the size of some of them
+ (such as C++ typeinfos) is not known until later. */
+ if (TREE_CODE (decl) != VAR_DECL || DECL_ARTIFICIAL (decl))
+ return false;
+
+ /* If we already know which section the decl should be in, see if
+ it's a small data section. */
+ section_name = DECL_SECTION_NAME (decl);
+ if (section_name)
{
- if (d->code == fcode)
- return frv_expand_voidtriop_builtin (d->icode, arglist);
+ if (TREE_CODE (section_name) != STRING_CST)
+ abort ();
+ if (frv_string_begins_with (section_name, ".sdata"))
+ return true;
+ if (frv_string_begins_with (section_name, ".sbss"))
+ return true;
+ return false;
}
- for (i = 0, d = bdesc_voidacc;
- i < sizeof (bdesc_voidacc) / sizeof *d;
- i++, d++)
+ size = int_size_in_bytes (TREE_TYPE (decl));
+ if (size > 0 && (unsigned HOST_WIDE_INT) size <= g_switch_value)
+ return true;
+
+ return false;
+}
+
+static bool
+frv_rtx_costs (rtx x,
+ int code ATTRIBUTE_UNUSED,
+ int outer_code ATTRIBUTE_UNUSED,
+ int *total)
+{
+ switch (code)
{
- if (d->code == fcode)
- return frv_expand_voidaccop_builtin (d->icode, arglist);
+ case CONST_INT:
+ /* Make 12 bit integers really cheap. */
+ if (IN_RANGE_P (INTVAL (x), -2048, 2047))
+ {
+ *total = 0;
+ return true;
+ }
+ /* Fall through. */
+
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_DOUBLE:
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case PLUS:
+ case MINUS:
+ case AND:
+ case IOR:
+ case XOR:
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ case NOT:
+ case NEG:
+ case COMPARE:
+ if (GET_MODE (x) == SImode)
+ *total = COSTS_N_INSNS (1);
+ else if (GET_MODE (x) == DImode)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (3);
+ return true;
+
+ case MULT:
+ if (GET_MODE (x) == SImode)
+ *total = COSTS_N_INSNS (2);
+ else
+ *total = COSTS_N_INSNS (6); /* guess */
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ *total = COSTS_N_INSNS (18);
+ return true;
+
+ default:
+ return false;
}
- return 0;
}
-
-static const char *
-frv_strip_name_encoding (str)
- const char *str;
+
+static void
+frv_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
- while (*str == '*' || *str == SDATA_FLAG_CHAR)
- str++;
- return str;
+ ctors_section ();
+ assemble_align (POINTER_SIZE);
+ assemble_integer_with_op ("\t.picptr\t", symbol);
}
-static bool
-frv_in_small_data_p (decl)
- tree decl;
+static void
+frv_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
- HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
-
- return symbol_ref_small_data_p (XEXP (DECL_RTL (decl), 0))
- && size > 0 && size <= g_switch_value;
+ dtors_section ();
+ assemble_align (POINTER_SIZE);
+ assemble_integer_with_op ("\t.picptr\t", symbol);
}
diff --git a/contrib/gcc/config/frv/frv.h b/contrib/gcc/config/frv/frv.h
index f9900b2f2bc6..0b8740428e2d 100644
--- a/contrib/gcc/config/frv/frv.h
+++ b/contrib/gcc/config/frv/frv.h
@@ -1,5 +1,6 @@
/* Target macros for the FRV port of GCC.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Red Hat Inc.
This file is part of GCC.
@@ -22,10 +23,6 @@
#ifndef __FRV_H__
#define __FRV_H__
-/* Set up System V.4 (aka ELF) defaults. */
-#include "svr4.h"
-
-
/* Frv general purpose macros. */
/* Align an address. */
#define ADDR_ALIGN(addr,align) (((addr) + (align) - 1) & ~((align) - 1))
@@ -65,9 +62,9 @@
Defined in svr4.h. */
#undef WORD_SWITCH_TAKES_ARG
-/* A C string constant that tells the GNU CC driver program options to pass to
+/* A C string constant that tells the GCC driver program options to pass to
the assembler. It can also specify how to translate options you give to GNU
- CC into options for GNU CC to pass to the assembler. See the file `sun3.h'
+ CC into options for GCC to pass to the assembler. See the file `sun3.h'
for an example of this.
Do not define this macro if it does not need to do anything.
@@ -86,7 +83,7 @@
%{mmedia} %{mno-media} \
%{mmuladd} %{mno-muladd} \
%{mpack} %{mno-pack} \
- %{fpic: -mpic} %{fPIC: -mPIC} %{mlibrary-pic}}"
+ %{fpic|fpie: -mpic} %{fPIC|fPIE: -mPIC} %{mlibrary-pic}}"
/* 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
@@ -109,9 +106,9 @@
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "frvend%O%s"
-/* A C string constant that tells the GNU CC driver program options to pass to
- CPP. It can also specify how to translate options you give to GNU CC into
- options for GNU CC to pass to the CPP.
+/* A C string constant that tells the GCC driver program options to pass to
+ CPP. It can also specify how to translate options you give to GCC into
+ options for GCC to pass to the CPP.
Do not define this macro if it does not need to do anything. */
@@ -204,17 +201,17 @@
#define MASK_DEFAULT_SIMPLE \
(MASK_GPR_32 | MASK_SOFT_FLOAT)
-/* A C string constant that tells the GNU CC driver program options to pass to
- `cc1'. It can also specify how to translate options you give to GNU CC into
- options for GNU CC to pass to the `cc1'.
+/* A C string constant that tells the GCC driver program options to pass to
+ `cc1'. It can also specify how to translate options you give to GCC into
+ options for GCC to pass to the `cc1'.
Do not define this macro if it does not need to do anything. */
/* For ABI compliance, we need to put bss data into the normal data section. */
#define CC1_SPEC "%{G*}"
-/* A C string constant that tells the GNU CC driver program options to pass to
- the linker. It can also specify how to translate options you give to GNU CC
- into options for GNU CC to pass to the linker.
+/* A C string constant that tells the GCC driver program options to pass to
+ the linker. It can also specify how to translate options you give to GCC
+ into options for GCC to pass to the linker.
Do not define this macro if it does not need to do anything.
@@ -249,7 +246,7 @@
is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
+ specification name, and a string constant that used by the GCC driver
program.
Do not define this macro if it does not need to do anything. */
@@ -280,16 +277,13 @@
/* Run-time target specifications */
-/* Define this to be a string constant containing `-D' options to define the
- predefined macros that identify this machine and system. These macros will
- be predefined unless the `-ansi' option is specified.
-
- In addition, a parallel set of macros are predefined, whose names are made
- by appending `__' at the beginning and at the end. These `__' macros are
- permitted by the ANSI standard, so they are predefined regardless of whether
- `-ansi' is specified. */
-
-#define CPP_PREDEFINES "-D__frv__ -Amachine(frv)"
+#define TARGET_CPU_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__frv__"); \
+ builtin_assert ("machine=frv"); \
+ } \
+ while (0)
/* This declaration should be present. */
@@ -489,13 +483,13 @@ extern int target_flags;
"Specify the size of the short data section" } }
This declaration is optional. */
-#define TARGET_OPTIONS \
-{ \
- { "cpu=", &frv_cpu_string, "Set cpu type" }, \
- { "branch-cost=", &frv_branch_cost_string, "Internal debug switch" }, \
- { "cond-exec-insns=", &frv_condexec_insns_str, "Internal debug switch" }, \
- { "cond-exec-temps=", &frv_condexec_temps_str, "Internal debug switch" }, \
- { "sched-lookahead=", &frv_sched_lookahead_str,"Internal debug switch" }, \
+#define TARGET_OPTIONS \
+{ \
+ { "cpu=", &frv_cpu_string, "Set cpu type", 0}, \
+ { "branch-cost=", &frv_branch_cost_string, "Internal debug switch", 0}, \
+ { "cond-exec-insns=", &frv_condexec_insns_str, "Internal debug switch", 0}, \
+ { "cond-exec-temps=", &frv_condexec_temps_str, "Internal debug switch", 0}, \
+ { "sched-lookahead=", &frv_sched_lookahead_str,"Internal debug switch", 0}, \
}
/* This macro is a C statement to print on `stderr' a string describing the
@@ -543,9 +537,9 @@ extern int target_flags;
/* Define this macro if debugging can be performed even without a frame
- pointer. If this macro is defined, GNU CC will turn on the
+ pointer. If this macro is defined, GCC will turn on the
`-fomit-frame-pointer' option whenever `-O' is specified. */
-/* Frv needs a specific frame layout that includes the frame pointer */
+/* Frv needs a specific frame layout that includes the frame pointer. */
#define CAN_DEBUG_WITHOUT_FP
@@ -557,9 +551,6 @@ extern int target_flags;
#define SDATA_DEFAULT_SIZE 8
#endif
-extern int g_switch_value; /* value of the -G xx switch */
-extern int g_switch_set; /* whether -G xx was passed. */
-
/* Storage Layout */
@@ -580,7 +571,7 @@ extern int g_switch_set; /* whether -G xx was passed. */
/* Define this macro to have the value 1 if, in a multiword object, the most
significant word has the lowest number. This applies to both memory
- locations and registers; GNU CC fundamentally assumes that the order of
+ locations and registers; GCC fundamentally assumes that the order of
words in memory is the same as the order in registers. This macro need not
be a constant. */
#define WORDS_BIG_ENDIAN 1
@@ -643,7 +634,7 @@ extern int g_switch_set; /* whether -G xx was passed. */
#define BIGGEST_FIELD_ALIGNMENT 64
#else
/* An expression for the alignment of a structure field FIELD if the
- alignment computed in the usual way is COMPUTED. GNU CC uses this
+ alignment computed in the usual way is COMPUTED. GCC uses this
value instead of the value in `BIGGEST_ALIGNMENT' or
`BIGGEST_FIELD_ALIGNMENT', if defined, for structure fields only. */
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
@@ -715,7 +706,7 @@ extern int g_switch_set; /* whether -G xx was passed. */
`STRUCTURE_SIZE_BOUNDARY' that way, you must define
`PCC_BITFIELD_TYPE_MATTERS' to have a nonzero value.
- If your aim is to make GNU CC use the same conventions for laying out
+ If your aim is to make GCC use the same conventions for laying out
bitfields as are used by another compiler, here is how to investigate what
the other compiler does. Compile and run this program:
@@ -1045,7 +1036,7 @@ extern int g_switch_set; /* whether -G xx was passed. */
/* Order of allocation of registers. */
/* If defined, an initializer for a vector of integers, containing the numbers
- of hard registers in the order in which GNU CC should prefer to use them
+ of hard registers in the order in which GCC should prefer to use them
(from most preferred to least).
If this macro is not defined, registers are used lowest numbered first (all
@@ -1895,7 +1886,7 @@ struct machine_function GTY(())
#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \
frv_function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED)
-/* extern int frv_function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS, int, Tree, int)); */
+/* extern int frv_function_arg_partial_nregs (CUMULATIVE_ARGS, int, Tree, int); */
/* A C expression that indicates when an argument must be passed by reference.
If nonzero for an argument, a copy of that argument is made in memory and a
@@ -1955,19 +1946,19 @@ struct machine_function GTY(())
being processed. Thus, each time this macro is called, either LIBNAME or
FNTYPE is nonzero, but never both of them at once. */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
- frv_init_cumulative_args (&CUM, FNTYPE, LIBNAME, INDIRECT, FALSE)
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
+ frv_init_cumulative_args (&CUM, FNTYPE, LIBNAME, FNDECL, FALSE)
/* Like `INIT_CUMULATIVE_ARGS' but overrides it for the purposes of finding the
arguments for the function being compiled. If this macro is undefined,
`INIT_CUMULATIVE_ARGS' is used instead.
The value passed for LIBNAME is always 0, since library routines with
- special calling conventions are never compiled with GNU CC. The argument
+ special calling conventions are never compiled with GCC. The argument
LIBNAME exists for symmetry with `INIT_CUMULATIVE_ARGS'. */
#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
- frv_init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE, TRUE)
+ frv_init_cumulative_args (&CUM, FNTYPE, LIBNAME, NULL, TRUE)
/* A C statement (sans semicolon) to update the summarizer variable CUM to
advance past an argument in the argument list. The values MODE, TYPE and
@@ -2079,14 +2070,14 @@ struct machine_function GTY(())
`fprintf'.
The details of how the address should be passed to `mcount' are determined
- by your operating system environment, not by GNU CC. To figure them out,
+ by your operating system environment, not by GCC. To figure them out,
compile a small program for profiling using the system's installed C
compiler and look at the assembler code that results.
This declaration must be present, but it can be an abort if profiling is
not implemented. */
-#define FUNCTION_PROFILER(FILE, LABELNO) abort ()
+#define FUNCTION_PROFILER(FILE, LABELNO)
/* Implementing the Varargs Macros. */
@@ -2170,7 +2161,7 @@ struct machine_function GTY(())
/* Define this macro if trampolines need a special subroutine to do their work.
The macro should expand to a series of `asm' statements which will be
- compiled with GNU CC. They go in a library function named
+ compiled with GCC. They go in a library function named
`__transfer_from_trampoline'.
If you need to avoid executing the ordinary prologue code of a compiled C
@@ -2190,11 +2181,7 @@ struct machine_function GTY(())
extern int _write (int, const void *, unsigned); \
\
void \
-__trampoline_setup (addr, size, fnaddr, sc) \
- short * addr; \
- int size; \
- int fnaddr; \
- int sc; \
+__trampoline_setup (short * addr, int size, int fnaddr, int sc) \
{ \
extern short __trampoline_template[]; \
short * to = addr; \
@@ -2234,101 +2221,6 @@ __asm__("\n" \
"\tjmpl @(gr0,gr6)\n");
-/* Implicit Calls to Library Routines. */
-
-/* A C string constant giving the name of the function to call for the
- remainder in division of one signed full-word by another. If you do not
- define this macro, the default name is used, which is `__modsi3', a function
- defined in `libgcc.a'. */
-#define MODSI3_LIBCALL "__modi"
-
-/* A C string constant giving the name of the function to call for the
- remainder in division of one unsigned full-word by another. If you do not
- define this macro, the default name is used, which is `__umodsi3', a
- function defined in `libgcc.a'. */
-#define UMODSI3_LIBCALL "__umodi"
-
-/* A C string constant giving the name of the function to call for
- multiplication of one signed double-word by another. If you do not define
- this macro, the default name is used, which is `__muldi3', a function
- defined in `libgcc.a'. */
-#define MULDI3_LIBCALL "__mulll"
-
-/* A C string constant giving the name of the function to call for division of
- one signed double-word by another. If you do not define this macro, the
- default name is used, which is `__divdi3', a function defined in `libgcc.a'. */
-#define DIVDI3_LIBCALL "__divll"
-
-/* A C string constant giving the name of the function to call for division of
- one unsigned full-word by another. If you do not define this macro, the
- default name is used, which is `__udivdi3', a function defined in
- `libgcc.a'. */
-#define UDIVDI3_LIBCALL "__udivll"
-
-/* A C string constant giving the name of the function to call for the
- remainder in division of one signed double-word by another. If you do not
- define this macro, the default name is used, which is `__moddi3', a function
- defined in `libgcc.a'. */
-#define MODDI3_LIBCALL "__modll"
-
-/* A C string constant giving the name of the function to call for the
- remainder in division of one unsigned full-word by another. If you do not
- define this macro, the default name is used, which is `__umoddi3', a
- function defined in `libgcc.a'. */
-#define UMODDI3_LIBCALL "__umodll"
-
-/* Define this macro as a C statement that declares additional library routines
- renames existing ones. `init_optabs' calls this macro after initializing all
- the normal library routines. */
-#define INIT_TARGET_OPTABS \
- do \
- { \
- add_optab->handlers [(int) DImode].libfunc \
- = init_one_libfunc ("__addll"); \
- sub_optab->handlers [(int) DImode].libfunc \
- = init_one_libfunc ("__subll"); \
- and_optab->handlers [(int) DImode].libfunc \
- = init_one_libfunc ("__andll"); \
- ior_optab->handlers [(int) DImode].libfunc \
- = init_one_libfunc ("__orll"); \
- xor_optab->handlers [(int) DImode].libfunc \
- = init_one_libfunc ("__xorll"); \
- one_cmpl_optab->handlers [(int) DImode].libfunc \
- = init_one_libfunc ("__notll"); \
- add_optab->handlers [(int) SFmode].libfunc \
- = init_one_libfunc ("__addf"); \
- sub_optab->handlers [(int) SFmode].libfunc \
- = init_one_libfunc ("__subf"); \
- smul_optab->handlers [(int) SFmode].libfunc \
- = init_one_libfunc ("__mulf"); \
- sdiv_optab->handlers [(int) SFmode].libfunc \
- = init_one_libfunc ("__divf"); \
- add_optab->handlers [(int) DFmode].libfunc \
- = init_one_libfunc ("__addd"); \
- sub_optab->handlers [(int) DFmode].libfunc \
- = init_one_libfunc ("__subd"); \
- smul_optab->handlers [(int) DFmode].libfunc \
- = init_one_libfunc ("__muld"); \
- sdiv_optab->handlers [(int) DFmode].libfunc \
- = init_one_libfunc ("__divd"); \
- fixsfsi_libfunc = init_one_libfunc ("__ftoi"); \
- fixunssfsi_libfunc = init_one_libfunc ("__ftoui"); \
- fixsfdi_libfunc = init_one_libfunc ("__ftoll"); \
- fixunssfdi_libfunc = init_one_libfunc ("__ftoull"); \
- fixdfsi_libfunc = init_one_libfunc ("__dtoi"); \
- fixunsdfsi_libfunc = init_one_libfunc ("__dtoui"); \
- fixdfdi_libfunc = init_one_libfunc ("__dtoll"); \
- fixunsdfdi_libfunc = init_one_libfunc ("__dtoull"); \
- floatsisf_libfunc = init_one_libfunc ("__itof"); \
- floatdisf_libfunc = init_one_libfunc ("__lltof"); \
- floatsidf_libfunc = init_one_libfunc ("__itod"); \
- floatdidf_libfunc = init_one_libfunc ("__lltod"); \
- extendsfdf2_libfunc = init_one_libfunc ("__ftod"); \
- truncdfsf2_libfunc = init_one_libfunc ("__dtof"); \
- } \
- while (0)
-
-
/* Addressing Modes. */
/* A C expression that is 1 if the RTX X is a constant which is a valid
@@ -2532,7 +2424,7 @@ __asm__("\n" \
#define REVERSIBLE_CC_MODE(MODE) ((MODE) != CCFPEmode) */
/* On frv, don't consider floating point comparisons to be reversible. In
- theory, fp equality comparisons can be reversible */
+ theory, fp equality comparisons can be reversible. */
#define REVERSIBLE_CC_MODE(MODE) ((MODE) == CCmode || (MODE) == CC_UNSmode)
/* Frv CCR_MODE's are not reversible. */
@@ -2541,65 +2433,6 @@ __asm__("\n" \
/* Describing Relative Costs of Operations. */
-/* A part of a C `switch' statement that describes the relative costs of
- constant RTL expressions. It must contain `case' labels for expression
- codes `const_int', `const', `symbol_ref', `label_ref' and `const_double'.
- Each case must ultimately reach a `return' statement to return the relative
- cost of the use of that kind of constant value in an expression. The cost
- may depend on the precise value of the constant, which is available for
- examination in X, and the rtx code of the expression in which it is
- contained, found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained with
- `GET_CODE (X)'. */
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- case CONST_DOUBLE: \
- return COSTS_N_INSNS (2); \
- \
- case CONST_INT: \
- /* Make 12 bit integers really cheap */ \
- return IN_RANGE_P (INTVAL (X), -2048, 2047) ? 0 : COSTS_N_INSNS (2); \
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions. This can be
- used, for example, to indicate how costly a multiply instruction is. In
- writing this macro, you can use the construct `COSTS_N_INSNS (N)' to specify
- a cost equal to N fast instructions. OUTER_CODE is the code of the
- expression in which X is contained.
-
- This macro is optional; do not define it if the default cost assumptions are
- adequate for the target machine. */
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case PLUS: \
- case MINUS: \
- case AND: \
- case IOR: \
- case XOR: \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- case NOT: \
- case NEG: \
- case COMPARE: \
- if (GET_MODE (X) == SImode) \
- return COSTS_N_INSNS (1); \
- else if (GET_MODE (X) == DImode) \
- return COSTS_N_INSNS (2); \
- else \
- return COSTS_N_INSNS (3); /* guess */ \
- \
- case MULT: \
- if (GET_MODE (X) == SImode) \
- return COSTS_N_INSNS (2); \
- else \
- return COSTS_N_INSNS (6); /* guess */ \
- \
- case DIV: \
- case UDIV: \
- return COSTS_N_INSNS (18);
-
/* A C expression for the cost of moving data from a register in class FROM to
one in class TO. The classes are expressed using the enumeration values
such as `GENERAL_REGS'. A value of 4 is the default; other values are
@@ -2629,7 +2462,7 @@ __asm__("\n" \
default; other values are interpreted relative to that. */
/* Here are additional macros which do not specify precise relative costs, but
- only that certain actions are more expensive than GNU CC would ordinarily
+ only that certain actions are more expensive than GCC would ordinarily
expect. */
/* We used to default the branch cost to 2, but I changed it to 1, to avoid
@@ -2686,7 +2519,6 @@ __asm__("\n" \
/* Short Data Support */
#define SDATA_SECTION_ASM_OP "\t.section .sdata,\"aw\""
-#define SBSS_SECTION_ASM_OP "\t.section .sbss,\"aw\""
/* On svr4, we *do* have support for the .init and .fini sections, and we
can put stuff in there to be executed before and after `main'. We let
@@ -2702,6 +2534,11 @@ __asm__("\n" \
#define INIT_SECTION_ASM_OP "\t.section .init,\"ax\""
#define FINI_SECTION_ASM_OP "\t.section .fini,\"ax\""
+#undef CTORS_SECTION_ASM_OP
+#undef DTORS_SECTION_ASM_OP
+#define CTORS_SECTION_ASM_OP "\t.section\t.ctors,\"a\""
+#define DTORS_SECTION_ASM_OP "\t.section\t.dtors,\"a\""
+
/* A C expression whose value is a string containing the assembler operation to
switch to the fixup section that records all initialized pointers in a -fpic
program so they can be changed program startup time if the program is loaded
@@ -2712,7 +2549,7 @@ __asm__("\n" \
`in_text' and `in_data'. You need not define this macro
on a system with no other sections (that GCC needs to use). */
#undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_sdata, in_sbss, in_const, in_fixup
+#define EXTRA_SECTIONS in_sdata, in_const, in_fixup
/* One or more functions to be defined in "varasm.c". These
functions should do jobs analogous to those of `text_section' and
@@ -2720,47 +2557,30 @@ __asm__("\n" \
macro if you do not define `EXTRA_SECTIONS'. */
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTION_FUNCTIONS \
-SDATA_SECTION_FUNCTION \
-SBSS_SECTION_FUNCTION \
-FIXUP_SECTION_FUNCTION
-
+ SDATA_SECTION_FUNCTION \
+ FIXUP_SECTION_FUNCTION
#define SDATA_SECTION_FUNCTION \
void \
-sdata_section () \
+sdata_section (void) \
{ \
if (in_section != in_sdata) \
{ \
fprintf (asm_out_file, "%s\n", SDATA_SECTION_ASM_OP); \
in_section = in_sdata; \
} \
-} \
-
-#define SBSS_SECTION_FUNCTION \
-void \
-sbss_section () \
-{ \
- if (in_section != in_sbss) \
- { \
- fprintf (asm_out_file, "%s\n", SBSS_SECTION_ASM_OP); \
- in_section = in_sbss; \
- } \
-} \
+}
#define FIXUP_SECTION_FUNCTION \
void \
-fixup_section () \
+fixup_section (void) \
{ \
if (in_section != in_fixup) \
{ \
fprintf (asm_out_file, "%s\n", FIXUP_SECTION_ASM_OP); \
in_section = in_fixup; \
} \
-} \
-
-#define SDATA_FLAG_CHAR '@'
-
-#define SDATA_NAME_P(NAME) (*(NAME) == SDATA_FLAG_CHAR)
+}
/* Position Independent Code. */
@@ -2845,10 +2665,10 @@ extern int size_directive_output;
#undef ASM_OUTPUT_ALIGNED_DECL_LOCAL
#define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGN) \
do { \
- if (SDATA_NAME_P (NAME)) \
- sbss_section (); \
+ if ((SIZE) > 0 && (SIZE) <= g_switch_value) \
+ named_section (0, ".sbss", 0); \
else \
- bss_section (); \
+ bss_section (); \
ASM_OUTPUT_ALIGN (STREAM, floor_log2 ((ALIGN) / BITS_PER_UNIT)); \
ASM_DECLARE_OBJECT_NAME (STREAM, NAME, DECL); \
ASM_OUTPUT_SKIP (STREAM, (SIZE) ? (SIZE) : 1); \
@@ -2871,24 +2691,11 @@ do { \
/* Globalizing directive for a label. */
#define GLOBAL_ASM_OP "\t.globl "
-/* A C statement (sans semicolon) to output to the stdio stream STREAM a
- reference in assembler syntax to a label named NAME. This should add `_' to
- the front of the name, if that is customary on your operating system, as it
- is in most Berkeley Unix systems. This macro is used in `assemble_name'. */
-#undef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
-do { \
- const char *_name = (NAME); \
- while (*_name == '*' || *_name == SDATA_FLAG_CHAR) \
- _name++; \
- asm_fprintf (STREAM, "%U%s", _name); \
-} while (0)
-
/* A C statement to store into the string STRING a label whose name is made
from the string PREFIX and the number NUM.
This string, when output subsequently by `assemble_name', should produce the
- output that `ASM_OUTPUT_INTERNAL_LABEL' would produce with the same PREFIX
+ output that `(*targetm.asm_out.internal_label)' would produce with the same PREFIX
and NUM.
If the string begins with `*', then `assemble_name' will output the rest of
@@ -2905,32 +2712,11 @@ do { \
sprintf (LABEL, "*.%s%ld", PREFIX, (long)NUM); \
} while (0)
-/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
- newly allocated string made from the string NAME and the number NUMBER, with
- some suitable punctuation added. Use `alloca' to get space for the string.
-
- The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
- an assembler label for an internal static variable whose name is NAME.
- Therefore, the string must be such as to result in valid assembler code.
- The argument NUMBER is different each time this macro is executed; it
- prevents conflicts between similarly-named internal static variables in
- different scopes.
-
- Ideally this string should not be a valid C identifier, to prevent any
- conflict with the user's own symbols. Most assemblers allow periods or
- percent signs in assembler symbols; putting at least one of these between
- the name and the number will suffice. */
-#define ASM_FORMAT_PRIVATE_NAME(OUTVAR, NAME, NUMBER) \
-do { \
- (OUTVAR) = (char *) alloca (strlen ((NAME)) + 12); \
- sprintf ((OUTVAR), "%s.%ld", (NAME), (long)(NUMBER)); \
-} while (0)
-
/* Macros Controlling Initialization Routines. */
/* If defined, a C string constant for the assembler operation to identify the
- following data as initialization code. If not defined, GNU CC will assume
+ following data as initialization code. If not defined, GCC will assume
such a section does not exist. When you are using special sections for
initialization and termination functions, this macro also controls how
`crtstuff.c' and `libgcc2.c' arrange to run the initialization functions.
@@ -2943,27 +2729,6 @@ do { \
init section is not actually run automatically, but is still useful for
collecting the lists of constructors and destructors. */
#define INVOKE__main
-
-/* Output appropriate code tp call a static constructor. */
-#undef ASM_OUTPUT_CONSTRUCTOR
-#define ASM_OUTPUT_CONSTRUCTOR(STREAM,NAME) \
-do { \
- ctors_section (); \
- fprintf (STREAM, "\t.picptr\t"); \
- assemble_name (STREAM, NAME); \
- fprintf (STREAM, "\n"); \
-} while (0)
-
-/* Output appropriate code tp call a static destructor. */
-#undef ASM_OUTPUT_DESTRUCTOR
-#define ASM_OUTPUT_DESTRUCTOR(STREAM,NAME) \
-do { \
- dtors_section (); \
- fprintf (STREAM, "\t.picptr\t"); \
- assemble_name (STREAM, NAME); \
- fprintf (STREAM, "\n"); \
-} while (0)
-
/* Output of Assembler Instructions. */
@@ -3079,7 +2844,7 @@ do { \
* == temporary integer CCR register (cr3)
& == temporary integer ICC register (icc3) */
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
-((CODE) == '.' || (CODE) == '#' || (CODE) == SDATA_FLAG_CHAR || (CODE) == '~' \
+((CODE) == '.' || (CODE) == '#' || (CODE) == '@' || (CODE) == '~' \
|| (CODE) == '*' || (CODE) == '&')
/* A C compound statement to output to stdio stream STREAM the assembler syntax
@@ -3115,7 +2880,7 @@ do { \
The definition should be a C statement to output to the stdio stream STREAM
an assembler pseudo-instruction to generate a difference between two labels.
VALUE and REL are the numbers of two internal labels. The definitions of
- these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
+ these labels are output using `(*targetm.asm_out.internal_label)', and they must be
printed in the same way here. For example,
fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL) */
@@ -3128,14 +2893,14 @@ fprintf (STREAM, "\t.word .L%d-.L%d\n", VALUE, REL)
The definition should be a C statement to output to the stdio stream STREAM
an assembler pseudo-instruction to generate a reference to a label. VALUE
is the number of an internal label whose definition is output using
- `ASM_OUTPUT_INTERNAL_LABEL'. For example,
+ `(*targetm.asm_out.internal_label)'. For example,
fprintf (STREAM, "\t.word L%d\n", VALUE) */
#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
fprintf (STREAM, "\t.word .L%d\n", VALUE)
/* Define this if the label before a jump-table needs to be output specially.
- The first three arguments are the same as for `ASM_OUTPUT_INTERNAL_LABEL';
+ The first three arguments are the same as for `(*targetm.asm_out.internal_label)';
the fourth argument is the jump-table which follows (a `jump_insn'
containing an `addr_vec' or `addr_diff_vec').
@@ -3143,7 +2908,7 @@ fprintf (STREAM, "\t.word .L%d\n", VALUE)
table.
If this macro is not defined, these labels are output with
- `ASM_OUTPUT_INTERNAL_LABEL'.
+ `(*targetm.asm_out.internal_label)'.
Defined in svr4.h. */
/* When generating embedded PIC or mips16 code we want to put the jump
@@ -3158,7 +2923,7 @@ fprintf (STREAM, "\t.word .L%d\n", VALUE)
do { \
if (flag_pic) \
function_section (current_function_decl); \
- ASM_OUTPUT_INTERNAL_LABEL (STREAM, PREFIX, NUM); \
+ (*targetm.asm_out.internal_label) (STREAM, PREFIX, NUM); \
} while (0)
/* Define this to determine whether case statement labels are relative to
@@ -3194,7 +2959,7 @@ do { \
Defined in svr4.h. */
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(STREAM, NBYTES) \
- fprintf (STREAM, "\t.zero\t%u\n", (NBYTES))
+ fprintf (STREAM, "\t.zero\t%u\n", (int)(NBYTES))
/* A C statement to output to the stdio stream STREAM an assembler command to
advance the location counter to a multiple of 2 to the POWER bytes. POWER
@@ -3202,6 +2967,9 @@ do { \
#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
fprintf ((STREAM), "\t.p2align %d\n", (POWER))
+/* Inside the text section, align with unpacked nops rather than zeros. */
+#define ASM_OUTPUT_ALIGN_WITH_NOP(STREAM, POWER) \
+ fprintf ((STREAM), "\t.p2alignl %d,0x80880000\n", (POWER))
/* Macros Affecting all Debug Formats. */
@@ -3211,7 +2979,7 @@ do { \
knows about and DBX does not, or vice versa. In such cases, some register
may need to have one number in the compiler and another for DBX.
- If two registers have consecutive numbers inside GNU CC, and they can be
+ If two registers have consecutive numbers inside GCC, and they can be
used as a pair to hold a multiword value, then they *must* have consecutive
numbers after renumbering with `DBX_REGISTER_NUMBER'. Otherwise, debuggers
will be unable to access such a pair, because they expect register pairs to
@@ -3224,9 +2992,9 @@ do { \
This declaration is required. */
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
-/* A C expression that returns the type of debugging output GNU CC produces
+/* A C expression that returns the type of debugging output GCC produces
when the user specifies `-g' or `-ggdb'. Define this if you have arranged
- for GNU CC to support more than one format of debugging output. Currently,
+ for GCC to support more than one format of debugging output. Currently,
the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
`DWARF2_DEBUG', and `XCOFF_DEBUG'.
@@ -3314,10 +3082,11 @@ do { \
{ "minmax_operator", { SMIN, SMAX, UMIN, UMAX }}, \
{ "condexec_si_binary_operator", { PLUS, MINUS, AND, IOR, XOR, \
ASHIFT, ASHIFTRT, LSHIFTRT }}, \
+ { "condexec_si_media_operator", { AND, IOR, XOR }}, \
{ "condexec_si_divide_operator", { DIV, UDIV }}, \
{ "condexec_si_unary_operator", { NOT, NEG }}, \
- { "condexec_sf_binary_operator", { PLUS, MINUS, MULT, DIV }}, \
- { "condexec_sf_unary_operator", { ABS, NEG, SQRT }}, \
+ { "condexec_sf_add_operator", { PLUS, MINUS }}, \
+ { "condexec_sf_conv_operator", { ABS, NEG }}, \
{ "intop_compare_operator", { PLUS, MINUS, AND, IOR, XOR, \
ASHIFT, ASHIFTRT, LSHIFTRT }}, \
{ "condexec_intop_cmp_operator", { PLUS, MINUS, AND, IOR, XOR, \
@@ -3492,9 +3261,6 @@ frv_ifcvt_modify_multiple_tests (CE_INFO, BB, &TRUE_EXPR, &FALSE_EXPR)
scheduling. */
#define FIRST_CYCLE_MULTIPASS_SCHEDULING_LOOKAHEAD frv_sched_lookahead
-/* Return true if a function is ok to be called as a sibcall. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) 0
-
enum frv_builtins
{
FRV_BUILTIN_MAND,
diff --git a/contrib/gcc/config/frv/frv.md b/contrib/gcc/config/frv/frv.md
index a5e82ee65a9d..aef10bc9d43b 100644
--- a/contrib/gcc/config/frv/frv.md
+++ b/contrib/gcc/config/frv/frv.md
@@ -1,21 +1,21 @@
;; Frv Machine Description
-;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
;; Contributed by Red Hat, Inc.
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
@@ -304,7 +304,7 @@
;; Instruction type
-;; The table below summarises the types of media instruction and their
+;; The table below summarizes the types of media instruction and their
;; scheduling classification. Headings are:
;; Type: the name of the define_attr type
@@ -463,7 +463,7 @@
first regular expression *and* the reservation described by
the second regular expression *and* etc.
- 4. "*" is used for convinience and simply means sequence in
+ 4. "*" is used for convenience and simply means sequence in
which the regular expression are repeated NUMBER times with
cycle advancing (see ",").
@@ -1118,7 +1118,7 @@
;; Note - it is the backend's responsibility to fill any unfilled delay slots
;; at assembler generation time. This is usually done by adding a special print
-;; operand to the delayed insrtuction, and then in the PRINT_OPERAND function
+;; operand to the delayed instruction, and then in the PRINT_OPERAND function
;; calling dbr_sequence_length() to determine how many delay slots were filled.
;; For example:
;;
@@ -1364,7 +1364,7 @@
;; Note - it is best to only have one movsi pattern and to handle
;; all the various contingencies by the use of alternatives. This
-;; allows reload the greatest amount of flexability (since reload will
+;; allows reload the greatest amount of flexibility (since reload will
;; only choose amoungst alternatives for a selected insn, it will not
;; replace the insn with another one).
@@ -1374,7 +1374,7 @@
;; constants into memory when the destination is a floating-point register.
;; That may make a function use a PIC pointer when it didn't before, and we
;; cannot change PIC usage (and hence stack layout) so late in the game.
-;; The resulting sequences for loading cosntants into FPRs are preferable
+;; The resulting sequences for loading constants into FPRs are preferable
;; even when we're not generating PIC code.
(define_insn "*movsi_load"
@@ -2754,22 +2754,11 @@
;; Subtraction No need to worry about constants, since the compiler
;; canonicalizes them into adddi3's.
-(define_expand "subdi3"
- [(parallel [(set (match_operand:DI 0 "integer_register_operand" "")
- (minus:DI (match_operand:DI 1 "integer_register_operand" "")
- (match_operand:DI 2 "integer_register_operand" "")))
- (clobber (match_dup 3))])]
- ""
- "
-{
- operands[3] = gen_reg_rtx (CCmode);
-}")
-
-(define_insn_and_split "*subdi3_internal"
+(define_insn_and_split "subdi3"
[(set (match_operand:DI 0 "integer_register_operand" "=&e,e,e")
(minus:DI (match_operand:DI 1 "integer_register_operand" "e,0,e")
(match_operand:DI 2 "integer_register_operand" "e,e,0")))
- (clobber (match_operand:CC 3 "icc_operand" "=t,t,t"))]
+ (clobber (match_scratch:CC 3 "=t,t,t"))]
""
"#"
"reload_completed"
@@ -2842,6 +2831,31 @@
[(set_attr "length" "4")
(set_attr "type" "int")])
+(define_insn_and_split "negdi2"
+ [(set (match_operand:DI 0 "integer_register_operand" "=&e,e")
+ (neg:DI (match_operand:DI 1 "integer_register_operand" "e,0")))
+ (clobber (match_scratch:CC 2 "=t,t"))]
+ ""
+ "#"
+ "reload_completed"
+ [(match_dup 3)
+ (match_dup 4)]
+ "
+{
+ rtx op0_high = gen_highpart (SImode, operands[0]);
+ rtx op1_high = gen_rtx_REG (SImode, GPR_FIRST);
+ rtx op2_high = gen_highpart (SImode, operands[1]);
+ rtx op0_low = gen_lowpart (SImode, operands[0]);
+ rtx op1_low = op1_high;
+ rtx op2_low = gen_lowpart (SImode, operands[1]);
+ rtx op3 = operands[2];
+
+ operands[3] = gen_subdi3_lower (op0_low, op1_low, op2_low, op3);
+ operands[4] = gen_subdi3_upper (op0_high, op1_high, op2_high, op3);
+}"
+ [(set_attr "length" "8")
+ (set_attr "type" "multi")])
+
;; Multiplication (same size)
;; (define_insn "muldi3"
;; [(set (match_operand:DI 0 "register_operand" "=r")
@@ -3314,7 +3328,7 @@
;; "anddi3 %0,%1,%2"
;; [(set_attr "length" "4")])
-;; Includive OR, 64 bit integers
+;; Inclusive OR, 64 bit integers
;; (define_insn "iordi3"
;; [(set (match_operand:DI 0 "register_operand" "=r")
;; (ior:DI (match_operand:DI 1 "register_operand" "%r")
@@ -5456,7 +5470,7 @@
if (GET_CODE (operands[2]) != CONST_INT)
abort ();
- /* If we can't generate an immediate instruction, promote to register */
+ /* If we can't generate an immediate instruction, promote to register. */
if (! IN_RANGE_P (INTVAL (range), -2048, 2047))
range = force_reg (SImode, range);
@@ -5482,11 +5496,11 @@
emit_cmp_and_jump_insns (indx, range, GTU, NULL_RTX, SImode, 1, fail);
- /* Move the table address to a register */
+ /* Move the table address to a register. */
treg = gen_reg_rtx (Pmode);
emit_insn (gen_movsi (treg, gen_rtx_LABEL_REF (VOIDmode, table)));
- /* scale index-low by wordsize */
+ /* Scale index-low by wordsize. */
scale = gen_reg_rtx (SImode);
emit_insn (gen_ashlsi3 (scale, indx, GEN_INT (2)));
@@ -7379,7 +7393,7 @@
[(set_attr "length" "4")
(set_attr "type" "mqsath")])
-;; Set hi/lo instrctions: type "mset"
+;; Set hi/lo instructions: type "mset"
(define_insn "mhsetlos"
[(set (match_operand:SI 0 "fpr_operand" "=f")
diff --git a/contrib/gcc/config/frv/frvbegin.c b/contrib/gcc/config/frv/frvbegin.c
index a5f5b1fa93e7..d021b3540a5e 100644
--- a/contrib/gcc/config/frv/frvbegin.c
+++ b/contrib/gcc/config/frv/frvbegin.c
@@ -1,26 +1,33 @@
/* Frv initialization file linked before all user modules
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software ; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
This file was originally taken from the file crtstuff.c in the
- main compiler directory, and simplified. */
+ main compiler directory, and simplified. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
#include "defaults.h"
#include <stddef.h>
@@ -74,7 +81,7 @@ extern void __frv_deregister_eh(void) __attribute__((__destructor__));
extern func_ptr __EH_FRAME_BEGIN__[];
-/* Register the exeception handling table as the first constructor */
+/* Register the exception handling table as the first constructor. */
void
__frv_register_eh (void)
{
@@ -86,7 +93,7 @@ __frv_register_eh (void)
/* Note, do not declare __{,de}register_frame_info weak as it seems
to interfere with the pic support. */
-/* Unregister the exeception handling table as a deconstructor */
+/* Unregister the exception handling table as a deconstructor. */
void
__frv_deregister_eh (void)
{
@@ -101,9 +108,9 @@ __frv_deregister_eh (void)
completed = 1;
}
-/* Run the global destructors */
+/* Run the global destructors. */
void
-__do_global_dtors ()
+__do_global_dtors (void)
{
static func_ptr *p = __DTOR_LIST__ + 1;
while (*p)
@@ -113,9 +120,9 @@ __do_global_dtors ()
}
}
-/* Run the global constructors */
+/* Run the global constructors. */
void
-__do_global_ctors ()
+__do_global_ctors (void)
{
unsigned long nptrs = (unsigned long) __CTOR_LIST__[0];
unsigned i;
@@ -138,7 +145,7 @@ __do_global_ctors ()
to run __do_global_ctors, so we need not do anything here. */
void
-__main ()
+__main (void)
{
/* Support recursive calls to `main': run initializers just once. */
static int initialized;
diff --git a/contrib/gcc/config/frv/frvend.c b/contrib/gcc/config/frv/frvend.c
index f1635cc10497..6709cdba0781 100644
--- a/contrib/gcc/config/frv/frvend.c
+++ b/contrib/gcc/config/frv/frvend.c
@@ -1,23 +1,30 @@
/* Frv initialization file linked after all user modules
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software ; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Boston, MA 02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
#include "defaults.h"
#include <stddef.h>
diff --git a/contrib/gcc/config/frv/lib1funcs.asm b/contrib/gcc/config/frv/lib1funcs.asm
index 18a814235e02..87666f48dc06 100644
--- a/contrib/gcc/config/frv/lib1funcs.asm
+++ b/contrib/gcc/config/frv/lib1funcs.asm
@@ -1,24 +1,31 @@
/* Library functions.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
Contributed by Red Hat, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software ; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
#include <frv-asm.h>
diff --git a/contrib/gcc/config/frv/t-frv b/contrib/gcc/config/frv/t-frv
index a92f63bb8dad..a9130ff0604b 100644
--- a/contrib/gcc/config/frv/t-frv
+++ b/contrib/gcc/config/frv/t-frv
@@ -19,11 +19,11 @@ TARGET_LIBGCC2_CFLAGS =
fp-bit.c: $(srcdir)/config/fp-bit.c
echo '#define FLOAT' > fp-bit.c
- echo '#include "frv/frv-abi.h"' >> fp-bit.c
+ echo '#include "config/frv/frv-abi.h"' >> fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
dp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#include "frv/frv-abi.h"' > dp-bit.c
+ echo '#include "config/frv/frv-abi.h"' > dp-bit.c
cat $(srcdir)/config/fp-bit.c >> dp-bit.c
cmovh.c: $(srcdir)/config/frv/cmovh.c
@@ -90,4 +90,4 @@ MULTILIB_EXCEPTIONS = mcpu=frv/mno-pack* mcpu=simple/mno-pack*
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
-EXTRA_HEADERS = $(srcdir)/config/frv/frv-asm.h $(srcdir)/config/frv/media.h
+EXTRA_HEADERS = $(srcdir)/config/frv/frv-asm.h
diff --git a/contrib/gcc/config/gnu.h b/contrib/gcc/config/gnu.h
index f5f4184e8d30..23a8a730ec98 100644
--- a/contrib/gcc/config/gnu.h
+++ b/contrib/gcc/config/gnu.h
@@ -18,3 +18,15 @@
/* The system headers under GNU are C++-aware. */
#define NO_IMPLICIT_EXTERN_C
+
+#define HURD_TARGET_OS_CPP_BUILTINS() \
+ do { \
+ builtin_define ("__gnu_hurd__"); \
+ builtin_define ("__GNU__"); \
+ builtin_define_std ("unix"); \
+ builtin_define_std ("MACH"); \
+ builtin_assert ("system=gnu"); \
+ builtin_assert ("system=mach"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=posix"); \
+ } while (0)
diff --git a/contrib/gcc/config/gofast.h b/contrib/gcc/config/gofast.h
index 84e9018784f8..81dd9f61b664 100644
--- a/contrib/gcc/config/gofast.h
+++ b/contrib/gcc/config/gofast.h
@@ -1,108 +1,80 @@
/* US Software GOFAST floating point library support.
- Copyright (C) 1994, 1998, 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1994, 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* This is used by fp-bit.c. */
-#define US_SOFTWARE_GOFAST
-
/* The US Software GOFAST library requires special optabs support.
- There is no negation libcall, and several others have names different
- from gcc. This file consolidates the support in one place.
+ This file is intended to be included by config/ARCH/ARCH.c. It
+ defines one function, gofast_maybe_init_libfuncs, which should be
+ called from the TARGET_INIT_LIBFUNCS hook. When tm.h has defined
+ US_SOFTWARE_GOFAST, this function will adjust all the optabs and
+ libfuncs appropriately. Otherwise it will do nothing. */
+
+static void
+gofast_maybe_init_libfuncs (void)
+{
+#ifdef US_SOFTWARE_GOFAST
+ int mode;
+
+ set_optab_libfunc (add_optab, SFmode, "fpadd");
+ set_optab_libfunc (add_optab, DFmode, "dpadd");
+ set_optab_libfunc (sub_optab, SFmode, "fpsub");
+ set_optab_libfunc (sub_optab, DFmode, "dpsub");
+ set_optab_libfunc (smul_optab, SFmode, "fpmul");
+ set_optab_libfunc (smul_optab, DFmode, "dpmul");
+ set_optab_libfunc (sdiv_optab, SFmode, "fpdiv");
+ set_optab_libfunc (sdiv_optab, DFmode, "dpdiv");
+ set_optab_libfunc (cmp_optab, SFmode, "fpcmp");
+ set_optab_libfunc (cmp_optab, DFmode, "dpcmp");
+
+ /* GOFAST does not provide libfuncs for negation, so we use the
+ standard names. */
+
+ /* GCC does not use fpcmp/dpcmp for gt or ge because its own
+ FP-emulation library returns +1 for both > and unord. So we
+ leave gt and ge unset, such that, instead of fpcmp(a,b) >[=], we
+ generate fpcmp(b,a) <[=] 0, which is unambiguous. For unord
+ libfuncs, we use our own functions, since GOFAST doesn't supply
+ them. */
- The basic plan is to leave gcc proper alone and via some hook fix things
- after the optabs have been set up. Our main entry point is
- INIT_GOFAST_OPTABS. */
+ set_optab_libfunc (eq_optab, SFmode, "fpcmp");
+ set_optab_libfunc (ne_optab, SFmode, "fpcmp");
+ set_optab_libfunc (gt_optab, SFmode, 0);
+ set_optab_libfunc (ge_optab, SFmode, 0);
+ set_optab_libfunc (lt_optab, SFmode, "fpcmp");
+ set_optab_libfunc (le_optab, SFmode, "fpcmp");
-#define INIT_GOFAST_OPTABS \
- do { \
- GOFAST_CLEAR_NEG_FLOAT_OPTAB; \
- GOFAST_RENAME_LIBCALLS; \
- } while (0)
+ set_optab_libfunc (eq_optab, DFmode, "dpcmp");
+ set_optab_libfunc (ne_optab, DFmode, "dpcmp");
+ set_optab_libfunc (gt_optab, DFmode, 0);
+ set_optab_libfunc (ge_optab, DFmode, 0);
+ set_optab_libfunc (lt_optab, DFmode, "dpcmp");
+ set_optab_libfunc (le_optab, DFmode, "dpcmp");
-#define GOFAST_CLEAR_NEG_FLOAT_OPTAB \
- do { \
- int mode; \
- for (mode = SFmode; (int) mode <= (int) TFmode; \
- mode = (enum machine_mode) ((int) mode + 1)) \
- neg_optab->handlers[(int) mode].libfunc = NULL_RTX; \
- } while (0)
+ set_conv_libfunc (sext_optab, DFmode, SFmode, "fptodp");
+ set_conv_libfunc (trunc_optab, SFmode, DFmode, "dptofp");
-/* GCC does not use fpcmp/dpcmp for gt or ge because its own
- FP-emulation library returns +1 for both > and unord. So we leave
- gt and ge unset, such that, instead of fpcmp(a,b) >[=], we generate
- fpcmp(b,a) <[=] 0, which is unambiguous. For unord libfuncs, we
- use our own functions, since GOFAST doesn't supply them. */
-#define GOFAST_RENAME_LIBCALLS \
- add_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpadd"); \
- add_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpadd"); \
- sub_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpsub"); \
- sub_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpsub"); \
- smul_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpmul"); \
- smul_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpmul"); \
- sdiv_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpdiv"); \
- sdiv_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpdiv"); \
- cmp_optab->handlers[(int) SFmode].libfunc = init_one_libfunc ("fpcmp"); \
- cmp_optab->handlers[(int) DFmode].libfunc = init_one_libfunc ("dpcmp"); \
-\
- extendsfdf2_libfunc = init_one_libfunc ("fptodp"); \
- truncdfsf2_libfunc = init_one_libfunc ("dptofp"); \
-\
- eqhf2_libfunc = NULL_RTX; \
- nehf2_libfunc = NULL_RTX; \
- gthf2_libfunc = NULL_RTX; \
- gehf2_libfunc = NULL_RTX; \
- lthf2_libfunc = NULL_RTX; \
- lehf2_libfunc = NULL_RTX; \
-\
- eqsf2_libfunc = init_one_libfunc ("fpcmp"); \
- nesf2_libfunc = init_one_libfunc ("fpcmp"); \
- gtsf2_libfunc = NULL_RTX; \
- gesf2_libfunc = NULL_RTX; \
- ltsf2_libfunc = init_one_libfunc ("fpcmp"); \
- lesf2_libfunc = init_one_libfunc ("fpcmp"); \
-\
- eqdf2_libfunc = init_one_libfunc ("dpcmp"); \
- nedf2_libfunc = init_one_libfunc ("dpcmp"); \
- gtdf2_libfunc = NULL_RTX; \
- gedf2_libfunc = NULL_RTX; \
- ltdf2_libfunc = init_one_libfunc ("dpcmp"); \
- ledf2_libfunc = init_one_libfunc ("dpcmp"); \
-\
- eqxf2_libfunc = NULL_RTX; \
- nexf2_libfunc = NULL_RTX; \
- gtxf2_libfunc = NULL_RTX; \
- gexf2_libfunc = NULL_RTX; \
- ltxf2_libfunc = NULL_RTX; \
- lexf2_libfunc = NULL_RTX; \
-\
- eqtf2_libfunc = NULL_RTX; \
- netf2_libfunc = NULL_RTX; \
- gttf2_libfunc = NULL_RTX; \
- getf2_libfunc = NULL_RTX; \
- lttf2_libfunc = NULL_RTX; \
- letf2_libfunc = NULL_RTX; \
-\
- floatsisf_libfunc = init_one_libfunc ("sitofp"); \
- floatsidf_libfunc = init_one_libfunc ("litodp"); \
- fixsfsi_libfunc = init_one_libfunc ("fptosi"); \
- fixdfsi_libfunc = init_one_libfunc ("dptoli"); \
- fixunssfsi_libfunc = init_one_libfunc ("fptoui"); \
- fixunsdfsi_libfunc = init_one_libfunc ("dptoul"); \
+ set_conv_libfunc (sfix_optab, SImode, SFmode, "fptosi");
+ set_conv_libfunc (sfix_optab, SImode, DFmode, "dptoli");
+ set_conv_libfunc (ufix_optab, SImode, SFmode, "fptoui");
+ set_conv_libfunc (ufix_optab, SImode, DFmode, "dptoul");
-/* End of GOFAST_RENAME_LIBCALLS */
+ set_conv_libfunc (sfloat_optab, SFmode, SImode, "sitofp");
+ set_conv_libfunc (sfloat_optab, DFmode, SImode, "litodp");
+#endif
+}
diff --git a/contrib/gcc/config/i386/athlon.md b/contrib/gcc/config/i386/athlon.md
index 548f2adf4221..4ce9a3812d8c 100644
--- a/contrib/gcc/config/i386/athlon.md
+++ b/contrib/gcc/config/i386/athlon.md
@@ -1,34 +1,5 @@
;; AMD Athlon Scheduling
-;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
-;;
-;; GNU CC 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.
-;;
-;; GNU CC 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 GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA. */
-(define_attr "athlon_decode" "direct,vector"
- (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,fcmov")
- (const_string "vector")
- (and (eq_attr "type" "push")
- (match_operand 1 "memory_operand" ""))
- (const_string "vector")
- (and (eq_attr "type" "fmov")
- (and (eq_attr "memory" "load,store")
- (eq_attr "mode" "XF")))
- (const_string "vector")]
- (const_string "direct")))
-
;; The Athlon does contain three pipelined FP units, three integer units and
;; three address generation units.
;;
@@ -46,161 +17,853 @@
;; The load/store queue unit is not attached to the schedulers but
;; communicates with all the execution units separately instead.
-(define_function_unit "athlon_vectordec" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_decode" "vector"))
- 1 1)
-
-(define_function_unit "athlon_directdec" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_decode" "direct"))
- 1 1)
-
-(define_function_unit "athlon_vectordec" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_decode" "direct"))
- 1 1 [(eq_attr "athlon_decode" "vector")])
-
-(define_function_unit "athlon_ieu" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,ishift1,rotate,rotate1,ibr,call,callv,icmov,cld,pop,setcc,push,pop"))
- 1 1)
-
-(define_function_unit "athlon_ieu" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "str"))
- 15 15)
-
-(define_function_unit "athlon_ieu" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "imul"))
- 5 0)
-
-(define_function_unit "athlon_ieu" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "idiv"))
- 42 0)
-
-(define_function_unit "athlon_muldiv" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "imul"))
- 5 0)
-
-(define_function_unit "athlon_muldiv" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "idiv"))
- 42 42)
-
-(define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
- (cond [(eq_attr "type" "fop,fcmp,fistp")
- (const_string "add")
- (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
- (const_string "mul")
- (and (eq_attr "type" "fmov") (eq_attr "memory" "store,both"))
- (const_string "store")
- (and (eq_attr "type" "fmov") (eq_attr "memory" "load"))
- (const_string "any")
+(define_attr "athlon_decode" "direct,vector,double"
+ (cond [(eq_attr "type" "call,imul,idiv,other,multi,fcmov,fpspc,str,pop,cld,leave")
+ (const_string "vector")
+ (and (eq_attr "type" "push")
+ (match_operand 1 "memory_operand" ""))
+ (const_string "vector")
(and (eq_attr "type" "fmov")
- (ior (match_operand:SI 1 "register_operand" "")
- (match_operand 1 "immediate_operand" "")))
- (const_string "store")
- (eq_attr "type" "fmov")
- (const_string "muladd")]
- (const_string "none")))
-
-;; We use latencies 1 for definitions. This is OK to model colisions
-;; in execution units. The real latencies are modeled in the "fp" pipeline.
-
-;; fsin, fcos: 96-192
-;; fsincos: 107-211
-;; fsqrt: 19 for SFmode, 27 for DFmode, 35 for XFmode.
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "fpspc"))
- 100 1)
-
-;; 16 cycles for SFmode, 20 for DFmode and 24 for XFmode.
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "fdiv"))
- 24 1)
-
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "fop,fmul,fistp"))
- 4 1)
-
-;; XFmode loads are slow.
-;; XFmode store is slow too (8 cycles), but we don't need to model it, because
-;; there are no dependent instructions.
-
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (and (eq_attr "type" "fmov")
- (and (eq_attr "memory" "load")
- (eq_attr "mode" "XF"))))
- 10 1)
-
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "fmov,fsgn"))
- 2 1)
-
-;; fcmp and ftst instructions
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (and (eq_attr "type" "fcmp")
- (eq_attr "athlon_decode" "direct")))
- 3 1)
-
-;; fcmpi instructions.
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (and (eq_attr "type" "fcmp")
- (eq_attr "athlon_decode" "vector")))
- 3 1)
-
-(define_function_unit "athlon_fp" 3 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "type" "fcmov"))
- 7 1)
-
-(define_function_unit "athlon_fp_mul" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_fpunits" "mul"))
- 1 1)
-
-(define_function_unit "athlon_fp_add" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_fpunits" "add"))
- 1 1)
-
-(define_function_unit "athlon_fp_muladd" 2 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_fpunits" "muladd,mul,add"))
- 1 1)
-
-(define_function_unit "athlon_fp_store" 1 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "athlon_fpunits" "store"))
- 1 1)
-
-;; We don't need to model the Address Generation Unit, since we don't model
-;; the re-order buffer yet and thus we never schedule more than three operations
-;; at time. Later we may want to experiment with MD_SCHED macros modeling the
-;; decoders independently on the functional units.
-
-;(define_function_unit "athlon_agu" 3 0
-; (and (eq_attr "cpu" "athlon")
-; (and (eq_attr "memory" "!none")
-; (eq_attr "athlon_fpunits" "none")))
-; 1 1)
-
-;; Model load unit to avoid too long sequences of loads. We don't need to
-;; model store queue, since it is hardly going to be bottleneck.
-
-(define_function_unit "athlon_load" 2 0
- (and (eq_attr "cpu" "athlon")
- (eq_attr "memory" "load,both"))
- 1 1)
+ (and (eq_attr "memory" "load,store")
+ (eq_attr "mode" "XF")))
+ (const_string "vector")]
+ (const_string "direct")))
+
+;;
+;; decode0 decode1 decode2
+;; \ | /
+;; instruction control unit (72 entry scheduler)
+;; | |
+;; integer scheduler (18) stack map
+;; / | | | | \ stack rename
+;; ieu0 agu0 ieu1 agu1 ieu2 agu2 scheduler
+;; | agu0 | agu1 agu2 register file
+;; | \ | | / | | |
+;; \ /\ | / fadd fmul fstore
+;; \ / \ | / fadd fmul fstore
+;; imul load/store (2x) fadd fmul fstore
+
+(define_automaton "athlon,athlon_load,athlon_mult,athlon_fp")
+(define_cpu_unit "athlon-decode0" "athlon")
+(define_cpu_unit "athlon-decode1" "athlon")
+(define_cpu_unit "athlon-decode2" "athlon")
+(define_cpu_unit "athlon-decodev" "athlon")
+;; Model the fact that double decoded instruction may take 2 cycles
+;; to decode when decoder2 and decoder0 in next cycle
+;; is used (this is needed to allow troughput of 1.5 double decoded
+;; instructions per cycle).
+;;
+;; In order to avoid dependence between reservation of decoder
+;; and other units, we model decoder as two stage fully pipelined unit
+;; and only double decoded instruction may occupy unit in the first cycle.
+;; With this scheme however two double instructions can be issued cycle0.
+;;
+;; Avoid this by using presence set requiring decoder0 to be allocated
+;; too. Vector decoded instructions then can't be issued when
+;; modeled as consuming decoder0+decoder1+decoder2.
+;; We solve that by specialized vector decoder unit and exclusion set.
+(presence_set "athlon-decode2" "athlon-decode0")
+(exclusion_set "athlon-decodev" "athlon-decode0,athlon-decode1,athlon-decode2")
+(define_reservation "athlon-vector" "nothing,athlon-decodev")
+(define_reservation "athlon-direct0" "nothing,athlon-decode0")
+(define_reservation "athlon-direct" "nothing,
+ (athlon-decode0 | athlon-decode1
+ | athlon-decode2)")
+;; Double instructions behaves like two direct instructions.
+(define_reservation "athlon-double" "((athlon-decode2, athlon-decode0)
+ | (nothing,(athlon-decode0 + athlon-decode1))
+ | (nothing,(athlon-decode1 + athlon-decode2)))")
+
+;; Agu and ieu unit results in extremely large automatons and
+;; in our approximation they are hardly filled in. Only ieu
+;; unit can, as issue rate is 3 and agu unit is always used
+;; first in the insn reservations. Skip the models.
+
+;(define_cpu_unit "athlon-ieu0" "athlon_ieu")
+;(define_cpu_unit "athlon-ieu1" "athlon_ieu")
+;(define_cpu_unit "athlon-ieu2" "athlon_ieu")
+;(define_reservation "athlon-ieu" "(athlon-ieu0 | athlon-ieu1 | athlon-ieu2)")
+(define_reservation "athlon-ieu" "nothing")
+(define_cpu_unit "athlon-ieu0" "athlon")
+;(define_cpu_unit "athlon-agu0" "athlon_agu")
+;(define_cpu_unit "athlon-agu1" "athlon_agu")
+;(define_cpu_unit "athlon-agu2" "athlon_agu")
+;(define_reservation "athlon-agu" "(athlon-agu0 | athlon-agu1 | athlon-agu2)")
+(define_reservation "athlon-agu" "nothing")
+
+(define_cpu_unit "athlon-mult" "athlon_mult")
+
+(define_cpu_unit "athlon-load0" "athlon_load")
+(define_cpu_unit "athlon-load1" "athlon_load")
+(define_reservation "athlon-load" "athlon-agu,
+ (athlon-load0 | athlon-load1),nothing")
+;; 128bit SSE instructions issue two loads at once
+(define_reservation "athlon-load2" "athlon-agu,
+ (athlon-load0 + athlon-load1),nothing")
+
+(define_reservation "athlon-store" "(athlon-load0 | athlon-load1)")
+;; 128bit SSE instructions issue two stores at once
+(define_reservation "athlon-store2" "(athlon-load0 + athlon-load1)")
+
+
+;; The FP operations start to execute at stage 12 in the pipeline, while
+;; integer operations start to execute at stage 9 for Athlon and 11 for K8
+;; Compensate the difference for Athlon because it results in significantly
+;; smaller automata.
+(define_reservation "athlon-fpsched" "nothing,nothing,nothing")
+;; The floating point loads.
+(define_reservation "athlon-fpload" "(athlon-fpsched + athlon-load)")
+(define_reservation "athlon-fpload2" "(athlon-fpsched + athlon-load2)")
+(define_reservation "athlon-fploadk8" "(athlon-fpsched + athlon-load)")
+(define_reservation "athlon-fpload2k8" "(athlon-fpsched + athlon-load2)")
+
+
+;; The three fp units are fully pipelined with latency of 3
+(define_cpu_unit "athlon-fadd" "athlon_fp")
+(define_cpu_unit "athlon-fmul" "athlon_fp")
+(define_cpu_unit "athlon-fstore" "athlon_fp")
+(define_reservation "athlon-fany" "(athlon-fstore | athlon-fmul | athlon-fadd)")
+(define_reservation "athlon-faddmul" "(athlon-fmul | athlon-fadd)")
+
+;; Vector operations usually consume many of pipes.
+(define_reservation "athlon-fvector" "(athlon-fadd + athlon-fmul + athlon-fstore)")
+
+
+;; Jump instructions are executed in the branch unit completely transparent to us
+(define_insn_reservation "athlon_branch" 0
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "ibr"))
+ "athlon-direct,athlon-ieu")
+(define_insn_reservation "athlon_call" 0
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "call,callv"))
+ "athlon-vector,athlon-ieu")
+
+;; Latency of push operation is 3 cycles, but ESP value is available
+;; earlier
+(define_insn_reservation "athlon_push" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "push"))
+ "athlon-direct,athlon-agu,athlon-store")
+(define_insn_reservation "athlon_pop" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "pop"))
+ "athlon-vector,athlon-load,athlon-ieu")
+(define_insn_reservation "athlon_pop_k8" 3
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "pop"))
+ "athlon-double,(athlon-ieu+athlon-load)")
+(define_insn_reservation "athlon_leave" 3
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "leave"))
+ "athlon-vector,(athlon-ieu+athlon-load)")
+(define_insn_reservation "athlon_leave_k8" 3
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "leave"))
+ "athlon-double,(athlon-ieu+athlon-load)")
+
+;; Lea executes in AGU unit with 2 cycles latency.
+(define_insn_reservation "athlon_lea" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "lea"))
+ "athlon-direct,athlon-agu,nothing")
+
+;; Mul executes in special multiplier unit attached to IEU0
+(define_insn_reservation "athlon_imul" 5
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "imul")
+ (eq_attr "memory" "none,unknown")))
+ "athlon-vector,athlon-ieu0,athlon-mult,nothing,nothing,athlon-ieu0")
+;; ??? Widening multiply is vector or double.
+(define_insn_reservation "athlon_imul_k8_DI" 4
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "imul")
+ (and (eq_attr "mode" "DI")
+ (eq_attr "memory" "none,unknown"))))
+ "athlon-direct0,athlon-ieu0,athlon-mult,nothing,athlon-ieu0")
+(define_insn_reservation "athlon_imul_k8" 3
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "imul")
+ (eq_attr "memory" "none,unknown")))
+ "athlon-direct0,athlon-ieu0,athlon-mult,athlon-ieu0")
+(define_insn_reservation "athlon_imul_mem" 8
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "imul")
+ (eq_attr "memory" "load,both")))
+ "athlon-vector,athlon-load,athlon-ieu,athlon-mult,nothing,nothing,athlon-ieu")
+(define_insn_reservation "athlon_imul_mem_k8_DI" 7
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "imul")
+ (and (eq_attr "mode" "DI")
+ (eq_attr "memory" "load,both"))))
+ "athlon-vector,athlon-load,athlon-ieu,athlon-mult,nothing,athlon-ieu")
+(define_insn_reservation "athlon_imul_mem_k8" 6
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "imul")
+ (eq_attr "memory" "load,both")))
+ "athlon-vector,athlon-load,athlon-ieu,athlon-mult,athlon-ieu")
+
+;; Idiv can not execute in parallel with other instructions. Dealing with it
+;; as with short latency vector instruction is good approximation avoiding
+;; scheduler from trying too hard to can hide it's latency by overlap with
+;; other instructions.
+;; ??? Experiments show that the idiv can overlap with roughly 6 cycles
+;; of the other code
+
+(define_insn_reservation "athlon_idiv" 6
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "idiv")
+ (eq_attr "memory" "none,unknown")))
+ "athlon-vector,(athlon-ieu0*6+(athlon-fpsched,athlon-fvector))")
+(define_insn_reservation "athlon_idiv_mem" 9
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "idiv")
+ (eq_attr "memory" "load,both")))
+ "athlon-vector,((athlon-load,athlon-ieu0*6)+(athlon-fpsched,athlon-fvector))")
+;; The parallelism of string instructions is not documented. Model it same way
+;; as idiv to create smaller automata. This probably does not matter much.
+(define_insn_reservation "athlon_str" 6
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "str")
+ (eq_attr "memory" "load,both,store")))
+ "athlon-vector,athlon-load,athlon-ieu0*6")
+
+(define_insn_reservation "athlon_idirect" 1
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "direct")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "none,unknown"))))
+ "athlon-direct,athlon-ieu")
+(define_insn_reservation "athlon_ivector" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "none,unknown"))))
+ "athlon-vector,athlon-ieu,athlon-ieu")
+(define_insn_reservation "athlon_idirect_loadmov" 3
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "imov")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-load")
+(define_insn_reservation "athlon_idirect_load" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "direct")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-load,athlon-ieu")
+(define_insn_reservation "athlon_ivector_load" 6
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "load"))))
+ "athlon-vector,athlon-load,athlon-ieu,athlon-ieu")
+(define_insn_reservation "athlon_idirect_movstore" 1
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "imov")
+ (eq_attr "memory" "store")))
+ "athlon-direct,athlon-agu,athlon-store")
+(define_insn_reservation "athlon_idirect_both" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "direct")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "both"))))
+ "athlon-direct,athlon-load,
+ athlon-ieu,athlon-store,
+ athlon-store")
+(define_insn_reservation "athlon_ivector_both" 6
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "both"))))
+ "athlon-vector,athlon-load,
+ athlon-ieu,
+ athlon-ieu,
+ athlon-store")
+(define_insn_reservation "athlon_idirect_store" 1
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "direct")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "store"))))
+ "athlon-direct,(athlon-ieu+athlon-agu),
+ athlon-store")
+(define_insn_reservation "athlon_ivector_store" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "unit" "integer,unknown")
+ (eq_attr "memory" "store"))))
+ "athlon-vector,(athlon-ieu+athlon-agu),athlon-ieu,
+ athlon-store")
+
+;; Athlon floatin point unit
+(define_insn_reservation "athlon_fldxf" 12
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fmov")
+ (and (eq_attr "memory" "load")
+ (eq_attr "mode" "XF"))))
+ "athlon-vector,athlon-fpload2,athlon-fvector*9")
+(define_insn_reservation "athlon_fldxf_k8" 13
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fmov")
+ (and (eq_attr "memory" "load")
+ (eq_attr "mode" "XF"))))
+ "athlon-vector,athlon-fpload2k8,athlon-fvector*9")
+;; Assume superforwarding to take place so effective latency of fany op is 0.
+(define_insn_reservation "athlon_fld" 0
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fany")
+(define_insn_reservation "athlon_fld_k8" 2
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fploadk8,athlon-fstore")
+
+(define_insn_reservation "athlon_fstxf" 10
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fmov")
+ (and (eq_attr "memory" "store,both")
+ (eq_attr "mode" "XF"))))
+ "athlon-vector,(athlon-fpsched+athlon-agu),(athlon-store2+(athlon-fvector*7))")
+(define_insn_reservation "athlon_fstxf_k8" 8
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fmov")
+ (and (eq_attr "memory" "store,both")
+ (eq_attr "mode" "XF"))))
+ "athlon-vector,(athlon-fpsched+athlon-agu),(athlon-store2+(athlon-fvector*6))")
+(define_insn_reservation "athlon_fst" 4
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "store,both")))
+ "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)")
+(define_insn_reservation "athlon_fst_k8" 2
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fmov")
+ (eq_attr "memory" "store,both")))
+ "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)")
+(define_insn_reservation "athlon_fist" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fistp"))
+ "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)")
+(define_insn_reservation "athlon_fmov" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fmov"))
+ "athlon-direct,athlon-fpsched,athlon-faddmul")
+(define_insn_reservation "athlon_fadd_load" 4
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fop")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fadd")
+(define_insn_reservation "athlon_fadd_load_k8" 6
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fop")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fploadk8,athlon-fadd")
+(define_insn_reservation "athlon_fadd" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fop"))
+ "athlon-direct,athlon-fpsched,athlon-fadd")
+(define_insn_reservation "athlon_fmul_load" 4
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fmul")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fmul")
+(define_insn_reservation "athlon_fmul_load_k8" 6
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fmul")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fploadk8,athlon-fmul")
+(define_insn_reservation "athlon_fmul" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fmul"))
+ "athlon-direct,athlon-fpsched,athlon-fmul")
+(define_insn_reservation "athlon_fsgn" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fsgn"))
+ "athlon-direct,athlon-fpsched,athlon-fmul")
+(define_insn_reservation "athlon_fdiv_load" 24
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fdiv")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fmul")
+(define_insn_reservation "athlon_fdiv_load_k8" 13
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fdiv")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fploadk8,athlon-fmul")
+(define_insn_reservation "athlon_fdiv" 24
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "fdiv"))
+ "athlon-direct,athlon-fpsched,athlon-fmul")
+(define_insn_reservation "athlon_fdiv_k8" 11
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "fdiv"))
+ "athlon-direct,athlon-fpsched,athlon-fmul")
+(define_insn_reservation "athlon_fpspc_load" 103
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "fpspc")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload,athlon-fvector")
+(define_insn_reservation "athlon_fpspc" 100
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fpspc"))
+ "athlon-vector,athlon-fpsched,athlon-fvector")
+(define_insn_reservation "athlon_fcmov_load" 7
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fcmov")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload,athlon-fvector")
+(define_insn_reservation "athlon_fcmov" 7
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "fcmov"))
+ "athlon-vector,athlon-fpsched,athlon-fvector")
+(define_insn_reservation "athlon_fcmov_load_k8" 17
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fcmov")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fploadk8,athlon-fvector")
+(define_insn_reservation "athlon_fcmov_k8" 15
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "fcmov"))
+ "athlon-vector,athlon-fpsched,athlon-fvector")
+;; fcomi is vector decoded by uses only one pipe.
+(define_insn_reservation "athlon_fcomi_load" 3
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fcmp")
+ (and (eq_attr "athlon_decode" "vector")
+ (eq_attr "memory" "load"))))
+ "athlon-vector,athlon-fpload,athlon-fadd")
+(define_insn_reservation "athlon_fcomi_load_k8" 5
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fcmp")
+ (and (eq_attr "athlon_decode" "vector")
+ (eq_attr "memory" "load"))))
+ "athlon-vector,athlon-fploadk8,athlon-fadd")
+(define_insn_reservation "athlon_fcomi" 3
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "athlon_decode" "vector")
+ (eq_attr "type" "fcmp")))
+ "athlon-vector,athlon-fpsched,athlon-fadd")
+(define_insn_reservation "athlon_fcom_load" 2
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "fcmp")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fadd")
+(define_insn_reservation "athlon_fcom_load_k8" 4
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "fcmp")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fploadk8,athlon-fadd")
+(define_insn_reservation "athlon_fcom" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "fcmp"))
+ "athlon-direct,athlon-fpsched,athlon-fadd")
+;; Never seen by the scheduler because we still don't do post reg-stack
+;; scheduling.
+;(define_insn_reservation "athlon_fxch" 2
+; (and (eq_attr "cpu" "athlon,k8")
+; (eq_attr "type" "fxch"))
+; "athlon-direct,athlon-fpsched,athlon-fany")
+
+;; Athlon handle MMX operations in the FPU unit with shorter latencies
+
+(define_insn_reservation "athlon_movlpd_load" 0
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssemov")
+ (match_operand:DF 1 "memory_operand" "")))
+ "athlon-direct,athlon-fpload,athlon-fany")
+(define_insn_reservation "athlon_movlpd_load_k8" 2
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssemov")
+ (match_operand:DF 1 "memory_operand" "")))
+ "athlon-direct,athlon-fploadk8,athlon-fstore")
+(define_insn_reservation "athlon_movaps_load_k8" 2
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssemov")
+ (and (eq_attr "mode" "V4SF,V2DF,TI")
+ (eq_attr "memory" "load"))))
+ "athlon-double,athlon-fpload2k8,athlon-fstore,athlon-fstore")
+(define_insn_reservation "athlon_movaps_load" 0
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssemov")
+ (and (eq_attr "mode" "V4SF,V2DF,TI")
+ (eq_attr "memory" "load"))))
+ "athlon-vector,athlon-fpload2,(athlon-fany+athlon-fany)")
+(define_insn_reservation "athlon_movss_load" 1
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssemov")
+ (and (eq_attr "mode" "SF,DI")
+ (eq_attr "memory" "load"))))
+ "athlon-vector,athlon-fpload,(athlon-fany*2)")
+(define_insn_reservation "athlon_movss_load_k8" 1
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssemov")
+ (and (eq_attr "mode" "SF,DI")
+ (eq_attr "memory" "load"))))
+ "athlon-double,athlon-fploadk8,(athlon-fstore+athlon-fany)")
+(define_insn_reservation "athlon_mmxsseld" 0
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "mmxmov,ssemov")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fany")
+(define_insn_reservation "athlon_mmxsseld_k8" 2
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "mmxmov,ssemov")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fploadk8,athlon-fstore")
+(define_insn_reservation "athlon_mmxssest" 3
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "mmxmov,ssemov")
+ (and (eq_attr "mode" "V4SF,V2DF,TI")
+ (eq_attr "memory" "store,both"))))
+ "athlon-vector,(athlon-fpsched+athlon-agu),((athlon-fstore+athlon-store2)*2)")
+(define_insn_reservation "athlon_mmxssest_k8" 3
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "mmxmov,ssemov")
+ (and (eq_attr "mode" "V4SF,V2DF,TI")
+ (eq_attr "memory" "store,both"))))
+ "athlon-double,(athlon-fpsched+athlon-agu),((athlon-fstore+athlon-store2)*2)")
+(define_insn_reservation "athlon_mmxssest_short" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "mmxmov,ssemov")
+ (eq_attr "memory" "store,both")))
+ "athlon-direct,(athlon-fpsched+athlon-agu),(athlon-fstore+athlon-store)")
+(define_insn_reservation "athlon_movaps" 2
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssemov")
+ (eq_attr "mode" "V4SF,V2DF,TI")))
+ "athlon-double,athlon-fpsched,(athlon-faddmul+athlon-faddmul)")
+(define_insn_reservation "athlon_movaps_k8" 2
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssemov")
+ (eq_attr "mode" "V4SF,V2DF,TI")))
+ "athlon-vector,athlon-fpsched,(athlon-faddmul+athlon-faddmul)")
+(define_insn_reservation "athlon_mmxssemov" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "mmxmov,ssemov"))
+ "athlon-direct,athlon-fpsched,athlon-faddmul")
+(define_insn_reservation "athlon_mmxmul_load" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "mmxmul")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-fmul")
+(define_insn_reservation "athlon_mmxmul" 3
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "mmxmul"))
+ "athlon-direct,athlon-fpsched,athlon-fmul")
+(define_insn_reservation "athlon_mmx_load" 3
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "unit" "mmx")
+ (eq_attr "memory" "load")))
+ "athlon-direct,athlon-fpload,athlon-faddmul")
+(define_insn_reservation "athlon_mmx" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "unit" "mmx"))
+ "athlon-direct,athlon-fpsched,athlon-faddmul")
+;; SSE operations are handled by the i387 unit as well. The latency
+;; is same as for i387 operations for scalar operations
+
+(define_insn_reservation "athlon_sselog_load" 3
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "sselog")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload2,(athlon-fmul*2)")
+(define_insn_reservation "athlon_sselog_load_k8" 5
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "sselog")
+ (eq_attr "memory" "load")))
+ "athlon-double,athlon-fpload2k8,(athlon-fmul*2)")
+(define_insn_reservation "athlon_sselog" 3
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "sselog"))
+ "athlon-vector,athlon-fpsched,athlon-fmul*2")
+(define_insn_reservation "athlon_sselog_k8" 3
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "sselog"))
+ "athlon-double,athlon-fpsched,athlon-fmul")
+;; ??? pcmp executes in addmul, probably not wortwhile to brother about that.
+(define_insn_reservation "athlon_ssecmp_load" 2
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssecmp")
+ (and (eq_attr "mode" "SF,DF,DI")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fpload,athlon-fadd")
+(define_insn_reservation "athlon_ssecmp_load_k8" 4
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssecmp")
+ (and (eq_attr "mode" "SF,DF,DI,TI")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fploadk8,athlon-fadd")
+(define_insn_reservation "athlon_ssecmp" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssecmp")
+ (eq_attr "mode" "SF,DF,DI,TI")))
+ "athlon-direct,athlon-fpsched,athlon-fadd")
+(define_insn_reservation "athlon_ssecmpvector_load" 3
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssecmp")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload2,(athlon-fadd*2)")
+(define_insn_reservation "athlon_ssecmpvector_load_k8" 5
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssecmp")
+ (eq_attr "memory" "load")))
+ "athlon-double,athlon-fpload2k8,(athlon-fadd*2)")
+(define_insn_reservation "athlon_ssecmpvector" 3
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "ssecmp"))
+ "athlon-vector,athlon-fpsched,(athlon-fadd*2)")
+(define_insn_reservation "athlon_ssecmpvector_k8" 3
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "ssecmp"))
+ "athlon-double,athlon-fpsched,(athlon-fadd*2)")
+(define_insn_reservation "athlon_ssecomi_load" 4
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssecomi")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload,athlon-fadd")
+(define_insn_reservation "athlon_ssecomi_load_k8" 6
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssecomi")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fploadk8,athlon-fadd")
+(define_insn_reservation "athlon_ssecomi" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (eq_attr "type" "ssecmp"))
+ "athlon-vector,athlon-fpsched,athlon-fadd")
+(define_insn_reservation "athlon_sseadd_load" 4
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "sseadd")
+ (and (eq_attr "mode" "SF,DF,DI")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fpload,athlon-fadd")
+(define_insn_reservation "athlon_sseadd_load_k8" 6
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "sseadd")
+ (and (eq_attr "mode" "SF,DF,DI")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fploadk8,athlon-fadd")
+(define_insn_reservation "athlon_sseadd" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "sseadd")
+ (eq_attr "mode" "SF,DF,DI")))
+ "athlon-direct,athlon-fpsched,athlon-fadd")
+(define_insn_reservation "athlon_sseaddvector_load" 5
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "sseadd")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload2,(athlon-fadd*2)")
+(define_insn_reservation "athlon_sseaddvector_load_k8" 7
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "sseadd")
+ (eq_attr "memory" "load")))
+ "athlon-double,athlon-fpload2k8,(athlon-fadd*2)")
+(define_insn_reservation "athlon_sseaddvector" 5
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "sseadd"))
+ "athlon-vector,athlon-fpsched,(athlon-fadd*2)")
+(define_insn_reservation "athlon_sseaddvector_k8" 5
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "sseadd"))
+ "athlon-double,athlon-fpsched,(athlon-fadd*2)")
+
+;; Conversions behaves very irregularly and the scheduling is critical here.
+;; Take each instruction separately. Assume that the mode is always set to the
+;; destination one and athlon_decode is set to the K8 versions.
+
+;; cvtss2sd
+(define_insn_reservation "athlon_ssecvt_cvtss2sd_load_k8" 4
+ (and (eq_attr "cpu" "k8,athlon")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "direct")
+ (and (eq_attr "mode" "DF")
+ (eq_attr "memory" "load")))))
+ "athlon-direct,athlon-fploadk8,athlon-fstore")
+(define_insn_reservation "athlon_ssecvt_cvtss2sd" 2
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "direct")
+ (eq_attr "mode" "DF"))))
+ "athlon-direct,athlon-fpsched,athlon-fstore")
+;; cvtps2pd. Model same way the other double decoded FP conversions.
+(define_insn_reservation "athlon_ssecvt_cvtps2pd_load_k8" 5
+ (and (eq_attr "cpu" "k8,athlon")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "V2DF,V4SF,TI")
+ (eq_attr "memory" "load")))))
+ "athlon-double,athlon-fpload2k8,(athlon-fstore*2)")
+(define_insn_reservation "athlon_ssecvt_cvtps2pd_k8" 3
+ (and (eq_attr "cpu" "k8,athlon")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "double")
+ (eq_attr "mode" "V2DF,V4SF,TI"))))
+ "athlon-double,athlon-fpsched,athlon-fstore,athlon-fstore")
+;; cvtsi2sd mem,reg is directpath path (cvtsi2sd reg,reg is doublepath)
+;; cvtsi2sd has troughput 1 and is executed in store unit with latency of 6
+(define_insn_reservation "athlon_sseicvt_cvtsi2sd_load" 6
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "direct")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load")))))
+ "athlon-direct,athlon-fploadk8,athlon-fstore")
+;; cvtsi2ss mem, reg is doublepath
+(define_insn_reservation "athlon_sseicvt_cvtsi2ss_load" 9
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load")))))
+ "athlon-vector,athlon-fpload,(athlon-fstore*2)")
+(define_insn_reservation "athlon_sseicvt_cvtsi2ss_load_k8" 9
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load")))))
+ "athlon-double,athlon-fploadk8,(athlon-fstore*2)")
+;; cvtsi2sd reg,reg is double decoded (vector on Athlon)
+(define_insn_reservation "athlon_sseicvt_cvtsi2sd_k8" 11
+ (and (eq_attr "cpu" "k8,athlon")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "none")))))
+ "athlon-double,athlon-fploadk8,athlon-fstore")
+;; cvtsi2ss reg, reg is doublepath
+(define_insn_reservation "athlon_sseicvt_cvtsi2ss" 14
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "none")))))
+ "athlon-vector,athlon-fploadk8,(athlon-fvector*2)")
+;; cvtsd2ss mem,reg is doublepath, troughput unknown, latency 9
+(define_insn_reservation "athlon_ssecvt_cvtsd2ss_load_k8" 9
+ (and (eq_attr "cpu" "k8,athlon")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "SF")
+ (eq_attr "memory" "load")))))
+ "athlon-double,athlon-fploadk8,(athlon-fstore*3)")
+;; cvtsd2ss reg,reg is vectorpath, troughput unknown, latency 12
+(define_insn_reservation "athlon_ssecvt_cvtsd2ss" 12
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "mode" "SF")
+ (eq_attr "memory" "none")))))
+ "athlon-vector,athlon-fpsched,(athlon-fvector*3)")
+(define_insn_reservation "athlon_ssecvt_cvtpd2ps_load_k8" 8
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "mode" "V4SF,V2DF,TI")
+ (eq_attr "memory" "load")))))
+ "athlon-double,athlon-fpload2k8,(athlon-fstore*3)")
+;; cvtpd2ps mem,reg is vectorpath, troughput unknown, latency 10
+;; ??? Why it is fater than cvtsd2ss?
+(define_insn_reservation "athlon_ssecvt_cvtpd2ps" 8
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssecvt")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "mode" "V4SF,V2DF,TI")
+ (eq_attr "memory" "none")))))
+ "athlon-vector,athlon-fpsched,athlon-fvector*2")
+;; cvtsd2si mem,reg is doublepath, troughput 1, latency 9
+(define_insn_reservation "athlon_secvt_cvtsX2si_load" 9
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "vector")
+ (and (eq_attr "mode" "SI,DI")
+ (eq_attr "memory" "load")))))
+ "athlon-vector,athlon-fploadk8,athlon-fvector")
+;; cvtsd2si reg,reg is doublepath, troughput 1, latency 9
+(define_insn_reservation "athlon_ssecvt_cvtsX2si" 9
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "SI,DI")
+ (eq_attr "memory" "none")))))
+ "athlon-vector,athlon-fpsched,athlon-fvector")
+(define_insn_reservation "athlon_ssecvt_cvtsX2si_k8" 9
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "sseicvt")
+ (and (eq_attr "athlon_decode" "double")
+ (and (eq_attr "mode" "SI,DI")
+ (eq_attr "memory" "none")))))
+ "athlon-double,athlon-fpsched,athlon-fstore")
+
+(define_insn_reservation "athlon_ssemul_load" 4
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssemul")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fpload,athlon-fmul")
+(define_insn_reservation "athlon_ssemul_load_k8" 6
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssemul")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fploadk8,athlon-fmul")
+(define_insn_reservation "athlon_ssemul" 4
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "mode" "SF,DF")))
+ "athlon-direct,athlon-fpsched,athlon-fmul")
+(define_insn_reservation "athlon_ssemulvector_load" 5
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload2,(athlon-fmul*2)")
+(define_insn_reservation "athlon_ssemulvector_load_k8" 7
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssemul")
+ (eq_attr "memory" "load")))
+ "athlon-double,athlon-fpload2k8,(athlon-fmul*2)")
+(define_insn_reservation "athlon_ssemulvector" 5
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "ssemul"))
+ "athlon-vector,athlon-fpsched,(athlon-fmul*2)")
+(define_insn_reservation "athlon_ssemulvector_k8" 5
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "ssemul"))
+ "athlon-double,athlon-fpsched,(athlon-fmul*2)")
+;; divsd timings. divss is faster
+(define_insn_reservation "athlon_ssediv_load" 20
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssediv")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fpload,athlon-fmul*17")
+(define_insn_reservation "athlon_ssediv_load_k8" 22
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssediv")
+ (and (eq_attr "mode" "SF,DF")
+ (eq_attr "memory" "load"))))
+ "athlon-direct,athlon-fploadk8,athlon-fmul*17")
+(define_insn_reservation "athlon_ssediv" 20
+ (and (eq_attr "cpu" "athlon,k8")
+ (and (eq_attr "type" "ssediv")
+ (eq_attr "mode" "SF,DF")))
+ "athlon-direct,athlon-fpsched,athlon-fmul*17")
+(define_insn_reservation "athlon_ssedivvector_load" 39
+ (and (eq_attr "cpu" "athlon")
+ (and (eq_attr "type" "ssediv")
+ (eq_attr "memory" "load")))
+ "athlon-vector,athlon-fpload2,athlon-fmul*34")
+(define_insn_reservation "athlon_ssedivvector_load_k8" 35
+ (and (eq_attr "cpu" "k8")
+ (and (eq_attr "type" "ssediv")
+ (eq_attr "memory" "load")))
+ "athlon-double,athlon-fpload2k8,athlon-fmul*34")
+(define_insn_reservation "athlon_ssedivvector" 39
+ (and (eq_attr "cpu" "athlon")
+ (eq_attr "type" "ssediv"))
+ "athlon-vector,athlon-fmul*34")
+(define_insn_reservation "athlon_ssedivvector_k8" 39
+ (and (eq_attr "cpu" "k8")
+ (eq_attr "type" "ssediv"))
+ "athlon-double,athlon-fmul*34")
diff --git a/contrib/gcc/config/i386/att.h b/contrib/gcc/config/i386/att.h
index 70ae16413653..4ee85ae63059 100644
--- a/contrib/gcc/config/i386/att.h
+++ b/contrib/gcc/config/i386/att.h
@@ -2,20 +2,20 @@
Copyright (C) 1988, 1996, 2000, 2001, 2002
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -45,18 +45,7 @@ do \
} while (0)
/* Output at beginning of assembler file. */
-/* The .file command should always begin the output. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { \
- output_file_directive (FILE, main_input_filename); \
- if (ix86_asm_dialect == ASM_INTEL) \
- fputs ("\t.intel_syntax\n", FILE); \
- } while (0)
-
-/* Do use .optim by default on this machine. */
-#undef ASM_FILE_START_1
-#define ASM_FILE_START_1(FILE) fprintf (FILE, "\t.optim\n")
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
/* This is how to output an assembler line
that says to advance the location counter
@@ -69,7 +58,7 @@ do \
that says to advance the location counter by SIZE bytes. */
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf ((FILE), "\t.set .,.+%u\n", (SIZE))
+ fprintf ((FILE), "\t.set .,.+%u\n", (int)(SIZE))
/* Can't use ASM_OUTPUT_SKIP in text section; it doesn't leave 0s. */
@@ -90,13 +79,6 @@ do \
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
sprintf ((BUF), "%s%s%ld", LOCAL_LABEL_PREFIX, (PREFIX), (long)(NUMBER))
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, "%s%s%d:\n", LOCAL_LABEL_PREFIX, PREFIX, NUM)
-
/* The prefix to add to user-visible assembler symbols. */
#undef USER_LABEL_PREFIX
diff --git a/contrib/gcc/config/i386/beos-elf.h b/contrib/gcc/config/i386/beos-elf.h
index b84519f4d67a..50c39264bc0c 100644
--- a/contrib/gcc/config/i386/beos-elf.h
+++ b/contrib/gcc/config/i386/beos-elf.h
@@ -1,20 +1,20 @@
/* Definitions for Intel x86 running BeOS
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -58,7 +58,6 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- builtin_define ("__ELF__"); \
builtin_define ("__BEOS__"); \
builtin_define ("__INTEL__"); \
builtin_define ("_X86_"); \
@@ -79,7 +78,7 @@ Boston, MA 02111-1307, USA. */
CC1_SPEC is used for both cc1 and cc1plus. */
#undef CC1_SPEC
-#define CC1_SPEC "%{!no-fpic:%{!fPIC:-fpic}} %{!Wmultichar: -Wno-multichar} %(cc1_cpu) %{profile:-p}"
+#define CC1_SPEC "%{!no-fpic:%{!fno-pic:%{!fno-pie:%{!fpie:%{!fPIC:%{!fPIE:-fpic}}}}}} %{!Wmultichar: -Wno-multichar} %(cc1_cpu) %{profile:-p}"
#undef CC1PLUS_SPEC
#define CC1PLUS_SPEC "%{!Wctor-dtor-privacy:-Wno-ctor-dtor-privacy}"
diff --git a/contrib/gcc/config/i386/biarch64.h b/contrib/gcc/config/i386/biarch64.h
index 2d3469833b81..532cfe7013ba 100644
--- a/contrib/gcc/config/i386/biarch64.h
+++ b/contrib/gcc/config/i386/biarch64.h
@@ -4,20 +4,20 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Bo Thorsen <bo@suse.de>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/bsd.h b/contrib/gcc/config/i386/bsd.h
index 69ad1688bfb7..905b232e3e42 100644
--- a/contrib/gcc/config/i386/bsd.h
+++ b/contrib/gcc/config/i386/bsd.h
@@ -3,20 +3,20 @@
adapted to BSD conventions for symbol names and debugging.)
Copyright (C) 1988, 1996, 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -36,13 +36,6 @@ Boston, MA 02111-1307, USA. */
#define ASM_LONG "\t.long\t"
#define ASM_QUAD "\t.quad\t" /* Should not be used for 32bit compilation. */
-/* Output at beginning of assembler file.
- ??? I am skeptical of this -- RMS. */
-
-#define ASM_FILE_START(FILE) \
- do { output_file_directive (FILE, main_input_filename); \
- } while (0)
-
/* This was suggested, but it shouldn't be right for DBX output. -- RMS
#define ASM_OUTPUT_SOURCE_FILENAME(FILE, NAME) */
@@ -53,7 +46,7 @@ Boston, MA 02111-1307, USA. */
that says to advance the location counter by SIZE bytes. */
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.space %u\n", (SIZE))
+ fprintf (FILE, "\t.space "HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
/* Define the syntax of labels and symbol definitions/declarations. */
@@ -63,7 +56,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs (".comm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (ROUNDED)))
+ fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
/* This says how to output an assembler line
to define a local common symbol. */
@@ -71,7 +64,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
( fputs (".lcomm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (ROUNDED)))
+ fprintf ((FILE), ",%u\n", (int)(ROUNDED)))
/* This is how to output an assembler line
that says to advance the location counter
@@ -88,12 +81,6 @@ Boston, MA 02111-1307, USA. */
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
sprintf ((BUF), "*%s%ld", (PREFIX), (long)(NUMBER))
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, "%s%d:\n", PREFIX, NUM)
-
/* The prefix to add to user-visible assembler symbols. */
#define USER_LABEL_PREFIX "_"
diff --git a/contrib/gcc/config/i386/crtdll.h b/contrib/gcc/config/i386/crtdll.h
index dab60c19ca23..afdae5826b64 100644
--- a/contrib/gcc/config/i386/crtdll.h
+++ b/contrib/gcc/config/i386/crtdll.h
@@ -1,34 +1,43 @@
/* Operating system specific defines to be used when targeting GCC for
hosting on Windows32, using GNU tools and the Windows32 API Library.
- This variant uses CRTDLL.DLL insted of MSVCRTDLL.DLL.
+ This variant uses CRTDLL.DLL instead of MSVCRTDLL.DLL.
Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef EXTRA_OS_CPP_BUILTINS
-#define EXTRA_OS_CPP_BUILTINS() \
- do { builtin_define ("__MINGW32__=0.2"); } while (0)
+#define EXTRA_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__CRTDLL__"); \
+ builtin_define ("__MINGW32__"); \
+ builtin_define ("_WIN32"); \
+ builtin_define_std ("WIN32"); \
+ builtin_define_std ("WINNT"); \
+ } \
+ while (0)
#undef LIBGCC_SPEC
#define LIBGCC_SPEC \
- "%{mthreads:-lmingwthrd} -lmingw32 -lgcc -lmoldname -lcrtdll"
+ "%{mthreads:-lmingwthrd} -lmingw32 -lgcc -lcoldname -libmingwex -lcrtdll"
/* Specify a different entry point when linking a DLL */
#undef STARTFILE_SPEC
-#define STARTFILE_SPEC "%{mdll:dllcrt1%O%s} %{!mdll:crt1%O%s} %{pg:gcrt1%O%s}"
+#define STARTFILE_SPEC "%{shared|mdll:dllcrt1%O%s} \
+ %{!shared:%{!mdll:crt1%O%s}} %{pg:gcrt1%O%s}"
diff --git a/contrib/gcc/config/i386/cygming.h b/contrib/gcc/config/i386/cygming.h
new file mode 100644
index 000000000000..f67e0483ad58
--- /dev/null
+++ b/contrib/gcc/config/i386/cygming.h
@@ -0,0 +1,391 @@
+/* Operating system specific defines to be used when targeting GCC for
+ hosting on Windows32, using a Unix style C library and tools.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#define DBX_DEBUGGING_INFO 1
+#define SDB_DEBUGGING_INFO 1
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+
+#define TARGET_EXECUTABLE_SUFFIX ".exe"
+
+#define TARGET_IS_PE_COFF 1
+
+#include <stdio.h>
+
+/* Masks for subtarget switches used by other files. */
+#define MASK_NOP_FUN_DLLIMPORT 0x08000000 /* Ignore dllimport for functions */
+
+/* Used in winnt.c. */
+#define TARGET_NOP_FUN_DLLIMPORT (target_flags & MASK_NOP_FUN_DLLIMPORT)
+
+#undef SUBTARGET_SWITCHES
+#define SUBTARGET_SWITCHES \
+{ "cygwin", 0, N_("Use the Cygwin interface") }, \
+{ "no-cygwin", 0, N_("Use the Mingw32 interface") }, \
+{ "windows", 0, N_("Create GUI application") }, \
+{ "no-win32", 0, N_("Don't set Windows defines") }, \
+{ "win32", 0, N_("Set Windows defines") }, \
+{ "console", 0, N_("Create console application") },\
+{ "dll", 0, N_("Generate code for a DLL") }, \
+{ "nop-fun-dllimport", MASK_NOP_FUN_DLLIMPORT, \
+ N_("Ignore dllimport for functions") }, \
+{ "no-nop-fun-dllimport", -MASK_NOP_FUN_DLLIMPORT, "" }, \
+{ "threads", 0, N_("Use Mingw-specific thread support") },
+
+#define MAYBE_UWIN_CPP_BUILTINS() /* Nothing. */
+
+/* Support the __declspec keyword by turning them into attributes.
+ We currently only support: dllimport and dllexport.
+ Note that the current way we do this may result in a collision with
+ predefined attributes later on. This can be solved by using one attribute,
+ say __declspec__, and passing args to it. The problem with that approach
+ is that args are not accumulated: each new appearance would clobber any
+ existing args. */
+
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("_X86_=1"); \
+ builtin_assert ("system=winnt"); \
+ builtin_define ("__stdcall=__attribute__((__stdcall__))"); \
+ builtin_define ("__fastcall=__attribute__((__fastcall__))"); \
+ builtin_define ("__cdecl=__attribute__((__cdecl__))"); \
+ builtin_define ("__declspec(x)=__attribute__((x))"); \
+ if (!flag_iso) \
+ { \
+ builtin_define ("_stdcall=__attribute__((__stdcall__))"); \
+ builtin_define ("_fastcall=__attribute__((__fastcall__))"); \
+ builtin_define ("_cdecl=__attribute__((__cdecl__))"); \
+ } \
+ MAYBE_UWIN_CPP_BUILTINS (); \
+ EXTRA_OS_CPP_BUILTINS (); \
+ } \
+ while (0)
+
+/* Get tree.c to declare a target-specific specialization of
+ merge_decl_attributes. */
+#define TARGET_DLLIMPORT_DECL_ATTRIBUTES
+
+/* This macro defines names of additional specifications to put in the specs
+ that can be used in various specifications like CC1_SPEC. Its definition
+ is an initializer with a subgrouping for each command option.
+
+ Each subgrouping contains a string constant, that defines the
+ specification name, and a string constant that used by the GCC driver
+ program.
+
+ Do not define this macro if it does not need to do anything. */
+
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "mingw_include_path", DEFAULT_TARGET_MACHINE }
+
+#undef MATH_LIBRARY
+#define MATH_LIBRARY ""
+
+#define SIZE_TYPE "unsigned int"
+#define PTRDIFF_TYPE "int"
+#define WCHAR_TYPE_SIZE 16
+#define WCHAR_TYPE "short unsigned int"
+
+
+/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
+#define HANDLE_PRAGMA_PACK_PUSH_POP 1
+
+union tree_node;
+#define TREE union tree_node *
+
+#undef EXTRA_SECTIONS
+#define EXTRA_SECTIONS in_drectve
+
+#undef EXTRA_SECTION_FUNCTIONS
+#define EXTRA_SECTION_FUNCTIONS \
+ DRECTVE_SECTION_FUNCTION \
+ SWITCH_TO_SECTION_FUNCTION
+
+#define DRECTVE_SECTION_FUNCTION \
+void \
+drectve_section (void) \
+{ \
+ if (in_section != in_drectve) \
+ { \
+ fprintf (asm_out_file, "%s\n", "\t.section .drectve\n"); \
+ in_section = in_drectve; \
+ } \
+}
+void drectve_section (void);
+
+/* Older versions of gas don't handle 'r' as data.
+ Explicitly set data flag with 'd'. */
+#define READONLY_DATA_SECTION_ASM_OP "\t.section .rdata,\"dr\""
+
+/* Switch to SECTION (an `enum in_section').
+
+ ??? This facility should be provided by GCC proper.
+ The problem is that we want to temporarily switch sections in
+ ASM_DECLARE_OBJECT_NAME and then switch back to the original section
+ afterwards. */
+#define SWITCH_TO_SECTION_FUNCTION \
+void switch_to_section (enum in_section, tree); \
+void \
+switch_to_section (enum in_section section, tree decl) \
+{ \
+ switch (section) \
+ { \
+ case in_text: text_section (); break; \
+ case in_data: data_section (); break; \
+ case in_readonly_data: readonly_data_section (); break; \
+ case in_named: named_section (decl, NULL, 0); break; \
+ case in_drectve: drectve_section (); break; \
+ default: abort (); break; \
+ } \
+}
+
+/* Don't allow flag_pic to propagate since gas may produce invalid code
+ otherwise. */
+
+#undef SUBTARGET_OVERRIDE_OPTIONS
+#define SUBTARGET_OVERRIDE_OPTIONS \
+do { \
+ if (flag_pic) \
+ { \
+ warning ("-f%s ignored for target (all code is position independent)",\
+ (flag_pic > 1) ? "PIC" : "pic"); \
+ flag_pic = 0; \
+ } \
+} while (0) \
+
+/* Define this macro if references to a symbol must be treated
+ differently depending on something about the variable or
+ function named by the symbol (such as what section it is in).
+
+ On i386 running Windows NT, modify the assembler name with a suffix
+ consisting of an atsign (@) followed by string of digits that represents
+ the number of bytes of arguments passed to the function, if it has the
+ attribute STDCALL.
+
+ In addition, we must mark dll symbols specially. Definitions of
+ dllexport'd objects install some info in the .drectve section.
+ References to dllimport'd objects are fetched indirectly via
+ _imp__. If both are declared, dllexport overrides. This is also
+ needed to implement one-only vtables: they go into their own
+ section and we need to set DECL_SECTION_NAME so we do that here.
+ Note that we can be called twice on the same decl. */
+
+#undef TARGET_ENCODE_SECTION_INFO
+#define TARGET_ENCODE_SECTION_INFO i386_pe_encode_section_info
+#undef TARGET_STRIP_NAME_ENCODING
+#define TARGET_STRIP_NAME_ENCODING i386_pe_strip_name_encoding_full
+
+/* Output a reference to a label. */
+#undef ASM_OUTPUT_LABELREF
+#define ASM_OUTPUT_LABELREF i386_pe_output_labelref
+
+/* Output a common block. */
+#undef ASM_OUTPUT_COMMON
+#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
+do { \
+ if (i386_pe_dllexport_name_p (NAME)) \
+ i386_pe_record_exported_symbol (NAME, 1); \
+ if (! i386_pe_dllimport_name_p (NAME)) \
+ { \
+ fprintf ((STREAM), "\t.comm\t"); \
+ assemble_name ((STREAM), (NAME)); \
+ fprintf ((STREAM), ", %d\t%s %d\n", \
+ (int)(ROUNDED), ASM_COMMENT_START, (int)(SIZE)); \
+ } \
+} while (0)
+
+/* Output the label for an initialized variable. */
+#undef ASM_DECLARE_OBJECT_NAME
+#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
+do { \
+ if (i386_pe_dllexport_name_p (NAME)) \
+ i386_pe_record_exported_symbol (NAME, 1); \
+ ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
+} while (0)
+
+
+/* Emit code to check the stack when allocating more that 4000
+ bytes in one go. */
+
+#define CHECK_STACK_LIMIT 4000
+
+/* By default, target has a 80387, uses IEEE compatible arithmetic,
+ returns float values in the 387 and needs stack probes.
+ We also align doubles to 64-bits for MSVC default compatibility. */
+
+#undef TARGET_SUBTARGET_DEFAULT
+#define TARGET_SUBTARGET_DEFAULT \
+ (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE \
+ | MASK_ALIGN_DOUBLE)
+
+/* This is how to output an assembler line
+ that says to advance the location counter
+ to a multiple of 2**LOG bytes. */
+
+#undef ASM_OUTPUT_ALIGN
+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
+ if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
+
+/* Define this macro if in some cases global symbols from one translation
+ unit may not be bound to undefined symbols in another translation unit
+ without user intervention. For instance, under Microsoft Windows
+ symbols must be explicitly imported from shared libraries (DLLs). */
+#define MULTIPLE_SYMBOL_SPACES
+
+extern void i386_pe_unique_section (TREE, int);
+#define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
+
+#define SUPPORTS_ONE_ONLY 1
+
+/* Switch into a generic section. */
+#define TARGET_ASM_NAMED_SECTION i386_pe_asm_named_section
+
+/* Select attributes for named sections. */
+#define TARGET_SECTION_TYPE_FLAGS i386_pe_section_type_flags
+
+/* Write the extra assembler code needed to declare a function
+ properly. If we are generating SDB debugging information, this
+ will happen automatically, so we only need to handle other cases. */
+#undef ASM_DECLARE_FUNCTION_NAME
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
+ do \
+ { \
+ if (i386_pe_dllexport_name_p (NAME)) \
+ i386_pe_record_exported_symbol (NAME, 0); \
+ if (write_symbols != SDB_DEBUG) \
+ i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL)); \
+ ASM_OUTPUT_LABEL (FILE, NAME); \
+ } \
+ while (0)
+
+/* Add an external function to the list of functions to be declared at
+ the end of the file. */
+#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
+ do \
+ { \
+ if (TREE_CODE (DECL) == FUNCTION_DECL) \
+ i386_pe_record_external_function (NAME); \
+ } \
+ while (0)
+
+/* Declare the type properly for any external libcall. */
+#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
+ i386_pe_declare_function_type (FILE, XSTR (FUN, 0), 1)
+
+/* This says out to put a global symbol in the BSS section. */
+#undef ASM_OUTPUT_ALIGNED_BSS
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+ asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
+
+/* Output function declarations at the end of the file. */
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END i386_pe_file_end
+
+#undef ASM_COMMENT_START
+#define ASM_COMMENT_START " #"
+
+/* DWARF2 Unwinding doesn't work with exception handling yet. To make
+ it work, we need to build a libgcc_s.dll, and dcrt0.o should be
+ changed to call __register_frame_info/__deregister_frame_info. */
+#define DWARF2_UNWIND_INFO 0
+
+/* Don't assume anything about the header files. */
+#define NO_IMPLICIT_EXTERN_C
+
+#undef PROFILE_HOOK
+#define PROFILE_HOOK(LABEL) \
+ if (MAIN_NAME_P (DECL_NAME (current_function_decl))) \
+ { \
+ emit_call_insn (gen_rtx (CALL, VOIDmode, \
+ gen_rtx_MEM (FUNCTION_MODE, \
+ gen_rtx_SYMBOL_REF (Pmode, "_monstartup")), \
+ const0_rtx)); \
+ }
+
+/* Java Native Interface (JNI) methods on Win32 are invoked using the
+ stdcall calling convention. */
+#undef MODIFY_JNI_METHOD_CALL
+#define MODIFY_JNI_METHOD_CALL(MDECL) \
+ build_type_attribute_variant ((MDECL), \
+ build_tree_list (get_identifier ("stdcall"), \
+ NULL))
+
+/* External function declarations. */
+
+extern void i386_pe_record_external_function (const char *);
+extern void i386_pe_declare_function_type (FILE *, const char *, int);
+extern void i386_pe_record_exported_symbol (const char *, int);
+extern void i386_pe_file_end (void);
+extern int i386_pe_dllexport_name_p (const char *);
+extern int i386_pe_dllimport_name_p (const char *);
+
+/* For Win32 ABI compatibility */
+#undef DEFAULT_PCC_STRUCT_RETURN
+#define DEFAULT_PCC_STRUCT_RETURN 0
+
+/* MSVC returns aggregate types of up to 8 bytes via registers.
+ See i386.c:ix86_return_in_memory. */
+#undef MS_AGGREGATE_RETURN
+#define MS_AGGREGATE_RETURN 1
+
+/* No data type wants to be aligned rounder than this. */
+#undef BIGGEST_ALIGNMENT
+#define BIGGEST_ALIGNMENT 128
+
+/* Native complier aligns internal doubles in structures on dword boundaries. */
+#undef BIGGEST_FIELD_ALIGNMENT
+#define BIGGEST_FIELD_ALIGNMENT 64
+
+/* A bit-field declared as `int' forces `int' alignment for the struct. */
+#undef PCC_BITFIELD_TYPE_MATTERS
+#define PCC_BITFIELD_TYPE_MATTERS 1
+#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec)
+
+/* Enable alias attribute support. */
+#ifndef SET_ASM_OP
+#define SET_ASM_OP "\t.set\t"
+#endif
+/* This implements the `alias' attribute, keeping any stdcall or
+ fastcall decoration. */
+#undef ASM_OUTPUT_DEF_FROM_DECLS
+#define ASM_OUTPUT_DEF_FROM_DECLS(STREAM, DECL, TARGET) \
+ do \
+ { \
+ const char *alias; \
+ rtx rtlname = XEXP (DECL_RTL (DECL), 0); \
+ if (GET_CODE (rtlname) == SYMBOL_REF) \
+ alias = XSTR (rtlname, 0); \
+ else \
+ abort (); \
+ if (TREE_CODE (DECL) == FUNCTION_DECL) \
+ i386_pe_declare_function_type (STREAM, alias, \
+ TREE_PUBLIC (DECL)); \
+ ASM_OUTPUT_DEF (STREAM, alias, IDENTIFIER_POINTER (TARGET)); \
+ } while (0)
+
+#undef TREE
+
+#ifndef BUFSIZ
+# undef FILE
+#endif
diff --git a/contrib/gcc/config/i386/cygwin.asm b/contrib/gcc/config/i386/cygwin.asm
index a27af31f599c..c8378fa575fb 100644
--- a/contrib/gcc/config/i386/cygwin.asm
+++ b/contrib/gcc/config/i386/cygwin.asm
@@ -1,7 +1,45 @@
-/* stuff needed for libgcc on win32. */
+/* stuff needed for libgcc on win32.
+ *
+ * Copyright (C) 1996, 1998, 2001, 2003 Free Software Foundation, Inc.
+ * Written By Steve Chamberlain
+ *
+ * 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 2, or (at your option) any
+ * later version.
+ *
+ * In addition to the permissions in the GNU General Public License, the
+ * Free Software Foundation gives you unlimited permission to link the
+ * compiled version of this file with other programs, and to distribute
+ * those programs without any restriction coming from the use of this
+ * file. (The General Public License restrictions do apply in other
+ * respects; for example, they cover modification of the file, and
+ * distribution when not linked into another program.)
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * As a special exception, if you link this library with files
+ * compiled with GCC to produce an executable, this does not cause
+ * the resulting executable to be covered by the GNU General Public License.
+ * This exception does not however invalidate any other reasons why
+ * the executable file might be covered by the GNU General Public License.
+ */
#ifdef L_chkstk
+/* Function prologue calls _alloca to probe the stack when allocating more
+ than CHECK_STACK_LIMIT bytes in one go. Touching the stack at 4K
+ increments is necessary to ensure that the guard pages used
+ by the OS virtual memory manger are allocated in correct sequence. */
+
.global ___chkstk
.global __alloca
___chkstk:
@@ -27,6 +65,4 @@ done: subl %eax,%ecx
movl (%eax),%ecx /* recover saved temp */
movl 4(%eax),%eax /* get return address */
jmp *%eax
-
-
#endif
diff --git a/contrib/gcc/config/i386/cygwin.h b/contrib/gcc/config/i386/cygwin.h
index 03e372e04fa3..def39f4d3f59 100644
--- a/contrib/gcc/config/i386/cygwin.h
+++ b/contrib/gcc/config/i386/cygwin.h
@@ -3,153 +3,52 @@
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define DBX_DEBUGGING_INFO 1
-#define SDB_DEBUGGING_INFO 1
-#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-
-#define TARGET_VERSION fprintf (stderr, " (x86 Cygwin)");
-#define TARGET_EXECUTABLE_SUFFIX ".exe"
-
-#include <stdio.h>
-#include "i386/i386.h"
-#include "i386/unix.h"
-#include "i386/bsd.h"
-#include "i386/gas.h"
-#include "dbxcoff.h"
-
-/* Masks for subtarget switches used by other files. */
-#define MASK_NOP_FUN_DLLIMPORT 0x08000000 /* Ignore dllimport for functions */
-
-/* Used in winnt.c. */
-#define TARGET_NOP_FUN_DLLIMPORT (target_flags & MASK_NOP_FUN_DLLIMPORT)
-
-#undef SUBTARGET_SWITCHES
-#define SUBTARGET_SWITCHES \
-{ "cygwin", 0, N_("Use the Cygwin interface") }, \
-{ "no-cygwin", 0, N_("Use the Mingw32 interface") }, \
-{ "windows", 0, N_("Create GUI application") }, \
-{ "no-win32", 0, N_("Don't set Windows defines") }, \
-{ "win32", 0, N_("Set Windows defines") }, \
-{ "console", 0, N_("Create console application") },\
-{ "dll", 0, N_("Generate code for a DLL") }, \
-{ "nop-fun-dllimport", MASK_NOP_FUN_DLLIMPORT, \
- N_("Ignore dllimport for functions") }, \
-{ "no-nop-fun-dllimport", -MASK_NOP_FUN_DLLIMPORT, "" }, \
-{ "threads", 0, N_("Use Mingw-specific thread support") },
-
-#define MAYBE_UWIN_CPP_BUILTINS() /* Nothing. */
-#define TARGET_OS_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("_X86_=1"); \
- builtin_assert ("system=winnt"); \
- builtin_define ("__stdcall=__attribute__((__stdcall__))"); \
- builtin_define ("__cdecl=__attribute__((__cdecl__))"); \
- builtin_define ("__declspec(x)=__attribute__((x))"); \
- if (!flag_iso) \
- { \
- builtin_define ("_stdcall=__attribute__((__stdcall__))"); \
- builtin_define ("_cdecl=__attribute__((__cdecl__))"); \
- } \
- MAYBE_UWIN_CPP_BUILTINS (); \
- } \
- while (0)
-
-#ifdef CROSS_COMPILE
-#define CYGWIN_INCLUDES "%{!nostdinc:-idirafter " CYGWIN_CROSS_DIR "/include}"
-#define W32API_INC "%{!nostdinc:-idirafter " CYGWIN_CROSS_DIR "/include/w32api}"
-#define W32API_LIB "-L" CYGWIN_CROSS_DIR "/lib/w32api/"
-#define CYGWIN_LIB CYGWIN_CROSS_DIR "/lib"
-#define MINGW_LIBS "-L" CYGWIN_CROSS_DIR "/lib/mingw"
-#define MINGW_INCLUDES "%{!nostdinc:-isystem " CYGWIN_CROSS_DIR "/include/mingw/g++-3 "\
- "-isystem " CYGWIN_CROSS_DIR "/include/mingw/g++ "\
- "-idirafter " CYGWIN_CROSS_DIR "/include/mingw}"
-#else
-#define CYGWIN_INCLUDES "%{!nostdinc:-isystem /usr/local/include "\
- "-idirafter " CYGWIN_CROSS_DIR "/include "\
- "-idirafter /usr/include}"
-#define W32API_INC "%{!nostdinc:"\
- "-idirafter " CYGWIN_CROSS_DIR "/include/w32api "\
- "-idirafter /usr/include/w32api}"
-#define W32API_LIB "-L" CYGWIN_CROSS_DIR "/lib/w32api/ -L/usr/lib/w32api/"
-#define CYGWIN_LIB "/usr/lib"
-#define MINGW_LIBS "-L/usr/local/lib/mingw -L/usr/lib/mingw"
-#define MINGW_INCLUDES "%{!nostdinc:-isystem /usr/include/mingw/g++-3 "\
- "-isystem /usr/include/mingw/g++ "\
- "-isystem /usr/local/include/mingw "\
- "-idirafter " CYGWIN_CROSS_DIR "/include/mingw "\
- "-idirafter /usr/include/mingw}"
-#endif
-
-/* Get tree.c to declare a target-specific specialization of
- merge_decl_attributes. */
-#define TARGET_DLLIMPORT_DECL_ATTRIBUTES
+#define TARGET_VERSION fprintf (stderr, " (x86 Cygwin)");
-/* Support the __declspec keyword by turning them into attributes.
- We currently only support: dllimport and dllexport.
- Note that the current way we do this may result in a collision with
- predefined attributes later on. This can be solved by using one attribute,
- say __declspec__, and passing args to it. The problem with that approach
- is that args are not accumulated: each new appearance would clobber any
- existing args. */
+#define EXTRA_OS_CPP_BUILTINS() /* Nothing. */
#undef CPP_SPEC
-#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} \
+#define CPP_SPEC "%(cpp_cpu) %{posix:-D_POSIX_SOURCE} \
%{mno-win32:%{mno-cygwin: %emno-cygwin and mno-win32 are not compatible}} \
- %{mno-cygwin:-D__MSVCRT__ -D__MINGW32__ %{mthreads:-D_MT} "\
- MINGW_INCLUDES "} \
- %{!mno-cygwin:-D__CYGWIN32__ -D__CYGWIN__ %{!ansi:-Dunix} -D__unix__ -D__unix "\
- CYGWIN_INCLUDES "}\
+ %{mno-cygwin:-D__MSVCRT__ -D__MINGW32__ %{!ansi:%{mthreads:-D_MT}}}\
+ %{!mno-cygwin:-D__CYGWIN32__ -D__CYGWIN__ %{!ansi:-Dunix} -D__unix__ -D__unix }\
%{mwin32|mno-cygwin:-DWIN32 -D_WIN32 -D__WIN32 -D__WIN32__ %{!ansi:-DWINNT}}\
- %{!mno-win32:" W32API_INC "}\
+ %{!nostdinc:%{!mno-win32|mno-cygwin:-idirafter ../include/w32api%s -idirafter ../../include/w32api%s}}\
"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "\
- %{shared|mdll: %{mno-cygwin:" MINGW_LIBS " dllcrt2%O%s}}\
- %{!shared: %{!mdll: %{!mno-cygwin:crt0%O%s} %{mno-cygwin:" MINGW_LIBS " crt2%O%s}\
+ %{shared|mdll: %{mno-cygwin:dllcrt2%O%s}}\
+ %{!shared: %{!mdll: %{!mno-cygwin:crt0%O%s} %{mno-cygwin:crt2%O%s}\
%{pg:gcrt0%O%s}}}\
"
/* Normally, -lgcc is not needed since everything in it is in the DLL, but we
want to allow things to be added to it when installing new versions of
GCC without making a new CYGWIN.DLL, so we leave it. Profiling is handled
- by calling the init function from the prologue. */
+ by calling the init function from main. */
#undef LIBGCC_SPEC
-#define LIBGCC_SPEC "%{mno-cygwin: %{mthreads:-lmingwthrd} -lmingw32} \
- -lgcc %{mno-cygwin:-lmoldname -lmingwex -lmsvcrt}"
-
-/* This macro defines names of additional specifications to put in the specs
- that can be used in various specifications like CC1_SPEC. Its definition
- is an initializer with a subgrouping for each command option.
-
- Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
- program.
-
- Do not define this macro if it does not need to do anything. */
-
-#undef SUBTARGET_EXTRA_SPECS
-#define SUBTARGET_EXTRA_SPECS \
- { "mingw_include_path", DEFAULT_TARGET_MACHINE }
+#define LIBGCC_SPEC \
+ "%{mno-cygwin: %{mthreads:-lmingwthrd} -lmingw32} -lgcc \
+ %{mno-cygwin:-lmoldname -lmingwex -lmsvcrt}"
/* We have to dynamic link to get to the system DLLs. All of libc, libm and
the Unix stuff is in cygwin.dll. The import library is called
@@ -165,7 +64,7 @@ Boston, MA 02111-1307, USA. */
%{mwindows:-lgdi32 -lcomdlg32} \
-luser32 -lkernel32 -ladvapi32 -lshell32"
-#define LINK_SPEC W32API_LIB "\
+#define LINK_SPEC "\
%{mwindows:--subsystem windows} \
%{mconsole:--subsystem console} \
%{shared: %{mdll: %eshared and mdll are not compatible}} \
@@ -174,293 +73,158 @@ Boston, MA 02111-1307, USA. */
%{shared|mdll: -e \
%{mno-cygwin:_DllMainCRTStartup@12} \
%{!mno-cygwin:__cygwin_dll_entry@12}}\
- --dll-search-prefix=cyg"
-
-#undef MATH_LIBRARY
-#define MATH_LIBRARY ""
-
-#define SIZE_TYPE "unsigned int"
-#define PTRDIFF_TYPE "int"
-#define WCHAR_TYPE_SIZE 16
-#define WCHAR_TYPE "short unsigned int"
-
-
-/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
-#define HANDLE_PRAGMA_PACK_PUSH_POP 1
-
-union tree_node;
-#define TREE union tree_node *
-
-#undef EXTRA_SECTIONS
-#define EXTRA_SECTIONS in_drectve
-
-#undef EXTRA_SECTION_FUNCTIONS
-#define EXTRA_SECTION_FUNCTIONS \
- DRECTVE_SECTION_FUNCTION \
- SWITCH_TO_SECTION_FUNCTION
-
-#define DRECTVE_SECTION_FUNCTION \
-void \
-drectve_section () \
-{ \
- if (in_section != in_drectve) \
- { \
- fprintf (asm_out_file, "%s\n", "\t.section .drectve\n"); \
- in_section = in_drectve; \
- } \
-}
-void drectve_section PARAMS ((void));
-
-/* Switch to SECTION (an `enum in_section').
-
- ??? This facility should be provided by GCC proper.
- The problem is that we want to temporarily switch sections in
- ASM_DECLARE_OBJECT_NAME and then switch back to the original section
- afterwards. */
-#define SWITCH_TO_SECTION_FUNCTION \
-void switch_to_section PARAMS ((enum in_section, tree)); \
-void \
-switch_to_section (section, decl) \
- enum in_section section; \
- tree decl; \
-{ \
- switch (section) \
- { \
- case in_text: text_section (); break; \
- case in_data: data_section (); break; \
- case in_named: named_section (decl, NULL, 0); break; \
- case in_drectve: drectve_section (); break; \
- default: abort (); break; \
- } \
-}
-
-/* Don't allow flag_pic to propagate since gas may produce invalid code
- otherwise. */
-
-#undef SUBTARGET_OVERRIDE_OPTIONS
-#define SUBTARGET_OVERRIDE_OPTIONS \
-do { \
- if (flag_pic) \
- { \
- warning ("-f%s ignored for target (all code is position independent)",\
- (flag_pic > 1) ? "PIC" : "pic"); \
- flag_pic = 0; \
- } \
-} while (0) \
-
-/* Define this macro if references to a symbol must be treated
- differently depending on something about the variable or
- function named by the symbol (such as what section it is in).
-
- On i386 running Windows NT, modify the assembler name with a suffix
- consisting of an atsign (@) followed by string of digits that represents
- the number of bytes of arguments passed to the function, if it has the
- attribute STDCALL.
-
- In addition, we must mark dll symbols specially. Definitions of
- dllexport'd objects install some info in the .drectve section.
- References to dllimport'd objects are fetched indirectly via
- _imp__. If both are declared, dllexport overrides. This is also
- needed to implement one-only vtables: they go into their own
- section and we need to set DECL_SECTION_NAME so we do that here.
- Note that we can be called twice on the same decl. */
-
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO i386_pe_encode_section_info
-#undef TARGET_STRIP_NAME_ENCODING
-#define TARGET_STRIP_NAME_ENCODING i386_pe_strip_name_encoding_full
-
-/* Output a reference to a label. */
-#undef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
- fprintf (STREAM, "%s%s", USER_LABEL_PREFIX, \
- i386_pe_strip_name_encoding (NAME)) \
-
-/* Output a common block. */
-#undef ASM_OUTPUT_COMMON
-#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
-do { \
- if (i386_pe_dllexport_name_p (NAME)) \
- i386_pe_record_exported_symbol (NAME, 1); \
- if (! i386_pe_dllimport_name_p (NAME)) \
- { \
- fprintf ((STREAM), "\t.comm\t"); \
- assemble_name ((STREAM), (NAME)); \
- fprintf ((STREAM), ", %d\t%s %d\n", \
- (ROUNDED), ASM_COMMENT_START, (SIZE)); \
- } \
-} while (0)
-
-/* Output the label for an initialized variable. */
-#undef ASM_DECLARE_OBJECT_NAME
-#define ASM_DECLARE_OBJECT_NAME(STREAM, NAME, DECL) \
-do { \
- if (i386_pe_dllexport_name_p (NAME)) \
- i386_pe_record_exported_symbol (NAME, 1); \
- ASM_OUTPUT_LABEL ((STREAM), (NAME)); \
-} while (0)
-
-
-/* Emit code to check the stack when allocating more that 4000
- bytes in one go. */
-
-#define CHECK_STACK_LIMIT 4000
-
-/* By default, target has a 80387, uses IEEE compatible arithmetic,
- returns float values in the 387 and needs stack probes.
- We also align doubles to 64-bits for MSVC default compatibility. */
-
-#undef TARGET_SUBTARGET_DEFAULT
-#define TARGET_SUBTARGET_DEFAULT \
- (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE \
- | MASK_ALIGN_DOUBLE)
-
-/* This is how to output an assembler line
- that says to advance the location counter
- to a multiple of 2**LOG bytes. */
-
-#undef ASM_OUTPUT_ALIGN
-#define ASM_OUTPUT_ALIGN(FILE,LOG) \
- if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG))
-
-/* Define this macro if in some cases global symbols from one translation
- unit may not be bound to undefined symbols in another translation unit
- without user intervention. For instance, under Microsoft Windows
- symbols must be explicitly imported from shared libraries (DLLs). */
-#define MULTIPLE_SYMBOL_SPACES
-
-extern void i386_pe_unique_section PARAMS ((TREE, int));
-#define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
-
-#define SUPPORTS_ONE_ONLY 1
-
-/* Switch into a generic section. */
-#define TARGET_ASM_NAMED_SECTION i386_pe_asm_named_section
-
-/* Select attributes for named sections. */
-#define TARGET_SECTION_TYPE_FLAGS i386_pe_section_type_flags
-
-/* Write the extra assembler code needed to declare a function
- properly. If we are generating SDB debugging information, this
- will happen automatically, so we only need to handle other cases. */
-#undef ASM_DECLARE_FUNCTION_NAME
-#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
- do \
- { \
- if (i386_pe_dllexport_name_p (NAME)) \
- i386_pe_record_exported_symbol (NAME, 0); \
- if (write_symbols != SDB_DEBUG) \
- i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL)); \
- ASM_OUTPUT_LABEL (FILE, NAME); \
- } \
- while (0)
-
-/* Add an external function to the list of functions to be declared at
- the end of the file. */
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
- do \
- { \
- if (TREE_CODE (DECL) == FUNCTION_DECL) \
- i386_pe_record_external_function (NAME); \
- } \
- while (0)
-
-/* Declare the type properly for any external libcall. */
-#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
- i386_pe_declare_function_type (FILE, XSTR (FUN, 0), 1)
-
-/* This says out to put a global symbol in the BSS section. */
-#undef ASM_OUTPUT_ALIGNED_BSS
-#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
- asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
-
-/* Output function declarations at the end of the file. */
-#undef ASM_FILE_END
-#define ASM_FILE_END(FILE) \
- i386_pe_asm_file_end (FILE)
-
-#undef ASM_COMMENT_START
-#define ASM_COMMENT_START " #"
-
-/* DWARF2 Unwinding doesn't work with exception handling yet. To make
- it work, we need to build a libgcc_s.dll, and dcrt0.o should be
- changed to call __register_frame_info/__deregister_frame_info. */
-#define DWARF2_UNWIND_INFO 0
-
-/* Don't assume anything about the header files. */
-#define NO_IMPLICIT_EXTERN_C
-
-#undef PROFILE_HOOK
-#define PROFILE_HOOK(LABEL) \
- if (MAIN_NAME_P (DECL_NAME (current_function_decl))) \
- { \
- emit_call_insn (gen_rtx (CALL, VOIDmode, \
- gen_rtx_MEM (FUNCTION_MODE, \
- gen_rtx_SYMBOL_REF (Pmode, "_monstartup")), \
- const0_rtx)); \
- }
-
-/* Java Native Interface (JNI) methods on Win32 are invoked using the
- stdcall calling convention. */
-#undef MODIFY_JNI_METHOD_CALL
-#define MODIFY_JNI_METHOD_CALL(MDECL) \
- build_type_attribute_variant ((MDECL), \
- build_tree_list (get_identifier ("stdcall"), \
- NULL))
-
-
-/* External function declarations. */
-
-extern void i386_pe_record_external_function PARAMS ((const char *));
-extern void i386_pe_declare_function_type PARAMS ((FILE *, const char *, int));
-extern void i386_pe_record_exported_symbol PARAMS ((const char *, int));
-extern void i386_pe_asm_file_end PARAMS ((FILE *));
-extern int i386_pe_dllexport_name_p PARAMS ((const char *));
-extern int i386_pe_dllimport_name_p PARAMS ((const char *));
-
-/* For Win32 ABI compatibility */
-#undef DEFAULT_PCC_STRUCT_RETURN
-#define DEFAULT_PCC_STRUCT_RETURN 0
-
-/* No data type wants to be aligned rounder than this. */
-#undef BIGGEST_ALIGNMENT
-#define BIGGEST_ALIGNMENT 128
-
-/* Native complier aligns internal doubles in structures on dword boundaries. */
-#undef BIGGEST_FIELD_ALIGNMENT
-#define BIGGEST_FIELD_ALIGNMENT 64
-
-/* A bit-field declared as `int' forces `int' alignment for the struct. */
-#undef PCC_BITFIELD_TYPE_MATTERS
-#define PCC_BITFIELD_TYPE_MATTERS 1
-#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec)
-
-
-/* Enable alias attribute support. */
-#ifndef SET_ASM_OP
-#define SET_ASM_OP "\t.set\t"
+ %{!mno-cygwin:--dll-search-prefix=cyg}"
+
+/* Allocate space for all of the machine-spec-specific stuff.
+ Allocate enough space for cygwin -> mingw32 munging plus
+ possible addition of "/mingw". */
+
+#ifndef CYGWIN_MINGW_SUBDIR
+#define CYGWIN_MINGW_SUBDIR "/mingw"
+#endif
+#define CYGWIN_MINGW_SUBDIR_LEN (sizeof (CYGWIN_MINGW_SUBDIR) - 1)
+
+#ifdef GPLUSPLUS_INCLUDE_DIR
+char cygwin_gplusplus_include_dir[sizeof (GPLUSPLUS_INCLUDE_DIR) + 1
+ + (CYGWIN_MINGW_SUBDIR_LEN)]
+ = GPLUSPLUS_INCLUDE_DIR;
+#undef GPLUSPLUS_INCLUDE_DIR
+#define GPLUSPLUS_INCLUDE_DIR ((const char *) cygwin_gplusplus_include_dir)
+#ifndef GEN_CVT_ARRAY
+#define GEN_CVT_ARRAY
+#endif
#endif
-/* Override GCC's relative pathname lookup (ie., relocatability) unless
- otherwise told by other subtargets. */
-#ifndef WIN32_NO_ABSOLUTE_INST_DIRS
-#undef MD_STARTFILE_PREFIX
-#define MD_STARTFILE_PREFIX "/usr/lib/"
+#ifdef GPLUSPLUS_TOOL_INCLUDE_DIR
+char cygwin_gplusplus_tool_include_dir[sizeof (GPLUSPLUS_TOOL_INCLUDE_DIR) + 1
+ + CYGWIN_MINGW_SUBDIR_LEN]
+ = GPLUSPLUS_TOOL_INCLUDE_DIR;
+#undef GPLUSPLUS_TOOL_INCLUDE_DIR
+#define GPLUSPLUS_TOOL_INCLUDE_DIR ((const char *) cygwin_gplusplus_tool_include_dir)
+#ifndef GEN_CVT_ARRAY
+#define GEN_CVT_ARRAY
+#endif
+#endif
-#undef STANDARD_STARTFILE_PREFIX
-#define STANDARD_STARTFILE_PREFIX "/usr/lib/mingw/"
+#ifdef GPLUSPLUS_BACKWARD_INCLUDE_DIR
+char cygwin_gplusplus_backward_include_dir[sizeof (GPLUSPLUS_BACKWARD_INCLUDE_DIR) + 1
+ + CYGWIN_MINGW_SUBDIR_LEN]
+ = GPLUSPLUS_BACKWARD_INCLUDE_DIR;
+#undef GPLUSPLUS_BACKWARD_INCLUDE_DIR
+#define GPLUSPLUS_BACKWARD_INCLUDE_DIR ((const char *) cygwin_gplusplus_backward_include_dir)
+#ifndef GEN_CVT_ARRAY
+#define GEN_CVT_ARRAY
+#endif
+#endif
-#ifndef CROSS_COMPILE
+#ifdef LOCAL_INCLUDE_DIR
+char cygwin_local_include_dir[sizeof (LOCAL_INCLUDE_DIR) + 1
+ + CYGWIN_MINGW_SUBDIR_LEN]
+ = LOCAL_INCLUDE_DIR;
#undef LOCAL_INCLUDE_DIR
+#define LOCAL_INCLUDE_DIR ((const char *) cygwin_local_include_dir)
+#ifndef GEN_CVT_ARRAY
+#define GEN_CVT_ARRAY
+#endif
+#endif
+
+#ifdef CROSS_INCLUDE_DIR
+char cygwin_cross_include_dir[sizeof (CROSS_INCLUDE_DIR) + 1
+ + CYGWIN_MINGW_SUBDIR_LEN]
+ = CROSS_INCLUDE_DIR;
+#undef CROSS_INCLUDE_DIR
+#define CROSS_INCLUDE_DIR ((const char *) cygwin_cross_include_dir)
+#ifndef GEN_CVT_ARRAY
+#define GEN_CVT_ARRAY
+#endif
+#endif
+
+#ifdef TOOL_INCLUDE_DIR
+char cygwin_tool_include_dir[sizeof (TOOL_INCLUDE_DIR) + 1
+ + CYGWIN_MINGW_SUBDIR_LEN]
+ = TOOL_INCLUDE_DIR;
#undef TOOL_INCLUDE_DIR
-#undef SYSTEM_INCLUDE_DIR
+#define TOOL_INCLUDE_DIR ((const char *) cygwin_tool_include_dir)
+
+#ifndef CROSS_COMPILE
+#undef STANDARD_INCLUDE_DIR
+#define STANDARD_INCLUDE_DIR "/usr/include"
+char cygwin_standard_include_dir[sizeof (STANDARD_INCLUDE_DIR) + 1
+ + CYGWIN_MINGW_SUBDIR_LEN]
+ = STANDARD_INCLUDE_DIR;
#undef STANDARD_INCLUDE_DIR
-#define STANDARD_INCLUDE_DIR 0
-#endif /* not CROSS_COMPILE */
-#endif /* not WIN32_NO_ABSOLUTE_INST_DIRS */
+#define STANDARD_INCLUDE_DIR ((const char *) cygwin_standard_include_dir)
+#endif
+
+#ifndef GEN_CVT_ARRAY
+#define GEN_CVT_ARRAY
+#endif
+#endif
+
+#ifndef GEN_CVT_ARRAY
+extern char *cvt_to_mingw[];
+#else
+char *cvt_to_mingw[] =
+ {
+#ifdef GPLUSPLUS_INCLUDE_DIR
+ cygwin_gplusplus_include_dir,
+#endif
+
+#ifdef GPLUSPLUS_TOOL_INCLUDE_DIR
+ cygwin_gplusplus_tool_include_dir,
+#endif
+
+#ifdef GPLUSPLUS_BACKWARD_INCLUDE_DIR
+ cygwin_gplusplus_backward_include_dir,
+#endif
-#undef TREE
+#ifdef LOCAL_INCLUDE_DIR
+ cygwin_local_include_dir,
+#endif
+
+#ifdef CROSS_INCLUDE_DIR
+ cygwin_cross_include_dir,
+#endif
-#ifndef BUFSIZ
-# undef FILE
+#ifdef TOOL_INCLUDE_DIR
+ cygwin_tool_include_dir,
+#endif
+
+#ifdef STANDARD_INCLUDE_DIR
+ cygwin_standard_include_dir,
+#endif
+
+ NULL
+ };
+#undef GEN_CVT_ARRAY
+#endif /*GEN_CVT_ARRAY*/
+
+void mingw_scan (int, const char * const *, char **);
+#if 1
+#define GCC_DRIVER_HOST_INITIALIZATION \
+do \
+{ \
+ mingw_scan(argc, argv, (char **) &spec_machine); \
+ } \
+while (0)
+#else
+#define GCC_DRIVER_HOST_INITIALIZATION \
+do \
+{ \
+ char *cprefix = concat (tooldir_base_prefix, spec_machine, \
+ dir_separator_str, NULL); \
+ if (!IS_ABSOLUTE_PATH (cprefix)) \
+ cprefix = concat (standard_exec_prefix, spec_machine, dir_separator_str, \
+ spec_version, dir_separator_str, tooldir_prefix, NULL); \
+ add_prefix (&exec_prefixes,\
+ concat (cprefix, "../../../../", spec_machine, "/bin/", NULL), \
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); \
+ add_prefix (&exec_prefixes, cprefix, \
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL); \
+ add_prefix (&startfile_prefixes,\
+ concat (standard_startfile_prefix, "w32api", NULL),\
+ "GCC", PREFIX_PRIORITY_LAST, 0, NULL);\
+ mingw_scan(argc, argv, &spec_machine); \
+ } \
+while (0)
#endif
diff --git a/contrib/gcc/config/i386/cygwin1.c b/contrib/gcc/config/i386/cygwin1.c
new file mode 100644
index 000000000000..2cab96c195c6
--- /dev/null
+++ b/contrib/gcc/config/i386/cygwin1.c
@@ -0,0 +1,54 @@
+/* Helper routines for cygwin-specific command-line parsing.
+ Contributed by Christopher Faylor (cgf@redhat.com)
+ Copyright 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include <string.h>
+
+void
+mingw_scan (int argc ATTRIBUTE_UNUSED,
+ const char *const *argv,
+ char **spec_machine)
+{
+ putenv ("GCC_CYGWIN_MINGW=0");
+
+ while (*++argv)
+ if (strcmp (*argv, "-mno-win32") == 0)
+ putenv ("GCC_CYGWIN_WIN32=0");
+ else if (strcmp (*argv, "-mwin32") == 0)
+ putenv ("GCC_CYGWIN_WIN32=1");
+ else if (strcmp (*argv, "-mno-cygwin") == 0)
+ {
+ char *p = strstr (*spec_machine, "-cygwin");
+ if (p)
+ {
+ int len = p - *spec_machine;
+ char *s = xmalloc (strlen (*spec_machine) + 3);
+ memcpy (s, *spec_machine, len);
+ strcpy (s + len, "-mingw32");
+ *spec_machine = s;
+ }
+ putenv ("GCC_CYGWIN_MINGW=1");
+ }
+ return;
+}
diff --git a/contrib/gcc/config/i386/cygwin2.c b/contrib/gcc/config/i386/cygwin2.c
new file mode 100644
index 000000000000..2947f5af4547
--- /dev/null
+++ b/contrib/gcc/config/i386/cygwin2.c
@@ -0,0 +1,67 @@
+/* Helper routines for cygwin-specific command-line parsing.
+ Contributed by Christopher Faylor (cgf@redhat.com)
+ Copyright 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+
+#include "safe-ctype.h"
+#include <string.h>
+
+/*
+static void remove_w32api (void);
+*/
+static void add_mingw (void);
+static void set_mingw (void) __attribute__ ((constructor));
+
+static void
+add_mingw (void)
+{
+ char **av;
+ char *p;
+ for (av = cvt_to_mingw; *av; av++)
+ {
+ int sawcygwin = 0;
+ while ((p = strstr (*av, "-cygwin")))
+ {
+ char *over = p + sizeof ("-cygwin") - 1;
+ memmove (over + 1, over, strlen (over));
+ memcpy (p, "-mingw32", sizeof("-mingw32") - 1);
+ p = ++over;
+ while (ISALNUM (*p))
+ p++;
+ strcpy (over, p);
+ sawcygwin = 1;
+ }
+ if (!sawcygwin && !strstr (*av, "mingw"))
+ strcat (*av, CYGWIN_MINGW_SUBDIR);
+ }
+}
+
+
+static void
+set_mingw (void)
+{
+ char *env = getenv ("GCC_CYGWIN_MINGW");
+ if (env && *env == '1')
+ add_mingw ();
+}
diff --git a/contrib/gcc/config/i386/darwin.h b/contrib/gcc/config/i386/darwin.h
index 55c29fd945f0..fd501bf6a8b6 100644
--- a/contrib/gcc/config/i386/darwin.h
+++ b/contrib/gcc/config/i386/darwin.h
@@ -2,20 +2,20 @@
Copyright (C) 2001, 2002 Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -41,6 +41,16 @@ Boston, MA 02111-1307, USA. */
#undef CC1_SPEC
#define CC1_SPEC "%{!static:-fPIC}"
+#define ASM_SPEC "-arch i386 \
+ %{Zforce_cpusubtype_ALL:-force_cpusubtype_ALL} \
+ %{!Zforce_cpusubtype_ALL:%{mmmx:-force_cpusubtype_ALL}\
+ %{msse:-force_cpusubtype_ALL}\
+ %{msse2:-force_cpusubtype_ALL}}"
+
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "darwin_arch", "i386" },
+
/* The Darwin assembler mostly follows AT&T syntax. */
#undef ASSEMBLER_DIALECT
#define ASSEMBLER_DIALECT ASM_ATT
@@ -68,6 +78,11 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEEP_BRANCH_PREDICTION
#define TARGET_DEEP_BRANCH_PREDICTION 0
+/* For now, disable dynamic-no-pic. We'll need to go through i386.c
+ with a fine-tooth comb looking for refs to flag_pic! */
+#define MASK_MACHO_DYNAMIC_NO_PIC 0
+#define TARGET_DYNAMIC_NO_PIC (target_flags & MASK_MACHO_DYNAMIC_NO_PIC)
+
/* Define the syntax of pseudo-ops, labels and comments. */
#define LPREFIX "L"
@@ -96,7 +111,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs (".comm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (ROUNDED)))
+ fprintf ((FILE), ",%lu\n", (unsigned long)(ROUNDED)))
/* This says how to output an assembler line
to define a local common symbol. */
@@ -104,7 +119,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
( fputs (".lcomm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (ROUNDED)))
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (ROUNDED)))
/* Darwin profiling -- call mcount. */
#undef FUNCTION_PROFILER
diff --git a/contrib/gcc/config/i386/djgpp.h b/contrib/gcc/config/i386/djgpp.h
index 67807804501a..cee9480d69ce 100644
--- a/contrib/gcc/config/i386/djgpp.h
+++ b/contrib/gcc/config/i386/djgpp.h
@@ -1,21 +1,21 @@
/* Configuration for an i386 running MS-DOS with DJGPP.
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -30,10 +30,6 @@ Boston, MA 02111-1307, USA. */
/* Enable parsing of #pragma pack(push,<n>) and #pragma pack(pop). */
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
-#include "i386/unix.h"
-#include "i386/bsd.h"
-#include "i386/gas.h"
-
/* If defined, a C expression whose value is a string containing the
assembler operation to identify the following data as
uninitialized global data. If not defined, and neither
@@ -61,9 +57,9 @@ Boston, MA 02111-1307, USA. */
#undef TEXT_SECTION_ASM_OP
#define TEXT_SECTION_ASM_OP "\t.section .text"
-/* Define standard DJGPP installation paths. */
+/* Define standard DJGPP installation paths. */
/* We override default /usr or /usr/local part with /dev/env/DJDIR which */
-/* points to actual DJGPP instalation directory. */
+/* points to actual DJGPP installation directory. */
/* Standard include directory */
#undef STANDARD_INCLUDE_DIR
@@ -130,17 +126,6 @@ Boston, MA 02111-1307, USA. */
/* Switch into a generic section. */
#define TARGET_ASM_NAMED_SECTION default_coff_asm_named_section
-/* Output at beginning of assembler file. */
-/* The .file command should always begin the output. */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { \
- if (ix86_asm_dialect == ASM_INTEL) \
- fputs ("\t.intel_syntax\n", FILE); \
- output_file_directive (FILE, main_input_filename); \
- } while (0)
-
/* This is how to output an assembler line
that says to advance the location counter
to a multiple of 2**LOG bytes. */
diff --git a/contrib/gcc/config/i386/emmintrin.h b/contrib/gcc/config/i386/emmintrin.h
index 7007fc5864a2..abe450a8f334 100644
--- a/contrib/gcc/config/i386/emmintrin.h
+++ b/contrib/gcc/config/i386/emmintrin.h
@@ -1,19 +1,19 @@
-/* Copyright (C) 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -115,15 +115,7 @@ _mm_set_pd1 (double __F)
static __inline __m128d
_mm_set_pd (double __Z, double __Y)
{
- union {
- double __a[2];
- __m128d __v;
- } __u;
-
- __u.__a[0] = __Y;
- __u.__a[1] = __Z;
-
- return __u.__v;
+ return (__v2df) {__Y, __Z};
}
/* Create the vector [Y Z]. */
@@ -147,7 +139,7 @@ _mm_store_sd (double *__P, __m128d __A)
__builtin_ia32_storesd (__P, (__v2df)__A);
}
-/* Store the lower DPFP value acrosd two words. */
+/* Store the lower DPFP value across two words. */
static __inline void
_mm_store1_pd (double *__P, __m128d __A)
{
diff --git a/contrib/gcc/config/i386/freebsd-aout.h b/contrib/gcc/config/i386/freebsd-aout.h
index 85e2703f42cd..663ed8dac09c 100644
--- a/contrib/gcc/config/i386/freebsd-aout.h
+++ b/contrib/gcc/config/i386/freebsd-aout.h
@@ -5,20 +5,20 @@
Contributed by Poul-Henning Kamp <phk@login.dkuug.dk>
Continued development by David O'Brien <obrien@NUXI.org>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -185,6 +185,7 @@ Boston, MA 02111-1307, USA. */
size_directive_output was set
by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */
+#undef ASM_FINISH_DECLARE_OBJECT
#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \
do { \
const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \
@@ -208,7 +209,8 @@ do { \
ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \
} while (0)
-#define ASM_SPEC " %| %{fpic:-k} %{fPIC:-k}"
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
+#define ASM_SPEC "%{fpic|fpie|fPIC|fPIE:-k}"
#define LINK_SPEC \
"%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
%{shared:-Bshareable} \
diff --git a/contrib/gcc/config/i386/freebsd.h b/contrib/gcc/config/i386/freebsd.h
index 92f7fceb79a8..9e538e916a27 100644
--- a/contrib/gcc/config/i386/freebsd.h
+++ b/contrib/gcc/config/i386/freebsd.h
@@ -5,20 +5,20 @@
Adapted from GNU/Linux version by John Polstra.
Continued development by David O'Brien <obrien@freebsd.org>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -40,7 +40,7 @@ Boston, MA 02111-1307, USA. */
(TARGET_64BIT ? dbx64_register_map[n] : svr4_dbx_register_map[n])
#undef NO_PROFILE_COUNTERS
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS 1
/* Tell final.c that we don't need a label passed to mcount. */
@@ -50,13 +50,17 @@ Boston, MA 02111-1307, USA. */
/* Make gcc agree with <machine/ansi.h>. */
#undef SIZE_TYPE
-#define SIZE_TYPE "unsigned int"
+#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
#undef PTRDIFF_TYPE
-#define PTRDIFF_TYPE "int"
+#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
#undef WCHAR_TYPE_SIZE
-#define WCHAR_TYPE_SIZE BITS_PER_WORD
+#define WCHAR_TYPE_SIZE (TARGET_64BIT ? 32 : BITS_PER_WORD)
+
+#undef SUBTARGET_EXTRA_SPECS /* i386.h bogusly defines it. */
+#define SUBTARGET_EXTRA_SPECS \
+ { "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
/* Provide a STARTFILE_SPEC appropriate for FreeBSD. Here we add
the magical crtbegin.o file (see crtstuff.c) which provides part
@@ -97,6 +101,7 @@ Boston, MA 02111-1307, USA. */
#undef LINK_SPEC
#define LINK_SPEC "\
+ %{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \
%{Wl,*:%*} \
%{v:-V} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
@@ -104,7 +109,7 @@ Boston, MA 02111-1307, USA. */
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
+ %{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }} \
%{static:-Bstatic}} \
%{symbolic:-Bsymbolic}"
@@ -115,6 +120,7 @@ Boston, MA 02111-1307, USA. */
This is used to align code labels according to Intel recommendations. */
#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
+#undef ASM_OUTPUT_MAX_SKIP_ALIGN
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE, LOG, MAX_SKIP) \
if ((LOG) != 0) { \
if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
@@ -135,9 +141,9 @@ Boston, MA 02111-1307, USA. */
#define SUBTARGET_OVERRIDE_OPTIONS \
do { \
if (!TARGET_64BIT) { \
- real_format_for_mode[XFmode - QFmode] \
+ REAL_MODE_FORMAT (XFmode) \
= &ieee_extended_intel_96_round_53_format; \
- real_format_for_mode[TFmode - QFmode] \
+ REAL_MODE_FORMAT (TFmode) \
= &ieee_extended_intel_96_round_53_format; \
} \
} while (0)
diff --git a/contrib/gcc/config/i386/freebsd64.h b/contrib/gcc/config/i386/freebsd64.h
index 12ca062301d0..19e9bc25adba 100644
--- a/contrib/gcc/config/i386/freebsd64.h
+++ b/contrib/gcc/config/i386/freebsd64.h
@@ -2,20 +2,20 @@
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by David O'Brien <obrien@FreeBSD.org>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -23,6 +23,9 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (FreeBSD/x86-64 ELF)");
+#define SUBTARGET_EXTRA_SPECS \
+ { "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
+
/* Provide a LINK_SPEC appropriate for the FreeBSD/x86-64 ELF target.
This is a copy of LINK_SPEC from <i386/freebsd.h> tweaked for
the x86-64 target. */
@@ -37,6 +40,6 @@ Boston, MA 02111-1307, USA. */
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
+ %{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }} \
%{static:-Bstatic}} \
%{symbolic:-Bsymbolic}"
diff --git a/contrib/gcc/config/i386/gas.h b/contrib/gcc/config/i386/gas.h
index 075d7498f3e0..78195b97a854 100644
--- a/contrib/gcc/config/i386/gas.h
+++ b/contrib/gcc/config/i386/gas.h
@@ -1,20 +1,20 @@
/* Definitions for Intel 386 using GAS.
Copyright (C) 1988, 1993, 1994, 1996, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -121,12 +121,4 @@ Boston, MA 02111-1307, USA. */
/* Print opcodes the way that GAS expects them. */
#define GAS_MNEMONICS 1
-/* Output at beginning of assembler file. */
-/* The .file command should always begin the output. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { \
- if (ix86_asm_dialect == ASM_INTEL) \
- fputs ("\t.intel_syntax\n", FILE); \
- output_file_directive (FILE, main_input_filename); \
- } while (0)
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
diff --git a/contrib/gcc/config/i386/gnu.h b/contrib/gcc/config/i386/gnu.h
index acf2d3fdac82..cc9994bcaed8 100644
--- a/contrib/gcc/config/i386/gnu.h
+++ b/contrib/gcc/config/i386/gnu.h
@@ -7,15 +7,7 @@
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- builtin_define_std ("MACH"); \
- builtin_define_std ("unix"); \
- builtin_define ("__ELF__"); \
- builtin_define ("__GNU__"); \
- builtin_define ("__gnu_hurd__"); \
- builtin_assert ("system=gnu"); \
- builtin_assert ("system=mach"); \
- builtin_assert ("system=posix"); \
- builtin_assert ("system=unix"); \
+ HURD_TARGET_OS_CPP_BUILTINS(); \
if (flag_pic) \
{ \
builtin_define ("__PIC__"); \
diff --git a/contrib/gcc/config/i386/gthr-win32.c b/contrib/gcc/config/i386/gthr-win32.c
index 5510f108ca41..4e2b282251d8 100644
--- a/contrib/gcc/config/i386/gthr-win32.c
+++ b/contrib/gcc/config/i386/gthr-win32.c
@@ -1,7 +1,7 @@
/* Implementation of W32-specific threads compatibility routines for
- libgcc2. */
+ libgcc2. */
-/* Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
Contributed by Mumit Khan <khan@xraylith.wisc.edu>.
Modified and moved to separate file by Danny Smith
<dannysmith@users.sourceforge.net>.
diff --git a/contrib/gcc/config/i386/i386-aout.h b/contrib/gcc/config/i386/i386-aout.h
index ca0cb2569ce5..3b8978879d11 100644
--- a/contrib/gcc/config/i386/i386-aout.h
+++ b/contrib/gcc/config/i386/i386-aout.h
@@ -3,20 +3,20 @@
Copyright (C) 1994, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/i386-coff.h b/contrib/gcc/config/i386/i386-coff.h
index e8c5de9c65c4..85a519310b40 100644
--- a/contrib/gcc/config/i386/i386-coff.h
+++ b/contrib/gcc/config/i386/i386-coff.h
@@ -3,20 +3,20 @@
Copyright (C) 1994, 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -60,11 +60,4 @@ Boston, MA 02111-1307, USA. */
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
sprintf ((BUF), ".%s%ld", (PREFIX), (long)(NUMBER))
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
-
/* end of i386-coff.h */
diff --git a/contrib/gcc/config/i386/i386-interix.h b/contrib/gcc/config/i386/i386-interix.h
index d309087217de..2a99ce549a7c 100644
--- a/contrib/gcc/config/i386/i386-interix.h
+++ b/contrib/gcc/config/i386/i386-interix.h
@@ -1,5 +1,6 @@
-/* Target definitions for GNU compiler for Intel 80386 running Interix
- Parts Copyright (C) 1991, 1999, 2000, 2002 Free Software Foundation, Inc.
+/* Target definitions for GCC for Intel 80386 running Interix
+ Parts Copyright (C) 1991, 1999, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Parts:
by Douglas B. Rupp (drupp@cs.washington.edu).
@@ -7,20 +8,20 @@
by Donn Terry (donn@softway.com).
by Mumit Khan (khan@xraylith.wisc.edu).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -35,11 +36,12 @@ Boston, MA 02111-1307, USA. */
/* By default, target has a 80387, uses IEEE compatible arithmetic,
and returns float values in the 387 and needs stack probes
- We also align doubles to 64-bits for MSVC default compatibility */
+ We also align doubles to 64-bits for MSVC default compatibility
+ We do bitfields MSVC-compatibly by default, too. */
#undef TARGET_SUBTARGET_DEFAULT
#define TARGET_SUBTARGET_DEFAULT \
(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE | \
- MASK_ALIGN_DOUBLE)
+ MASK_ALIGN_DOUBLE | MASK_MS_BITFIELD_LAYOUT)
#undef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT 2 /* 486 */
@@ -70,9 +72,9 @@ Boston, MA 02111-1307, USA. */
else \
{ \
builtin_define_std ("LANGUAGE_C"); \
- if (c_language == clk_cplusplus) \
+ if (c_dialect_cxx ()) \
builtin_define_std ("LANGUAGE_C_PLUS_PLUS"); \
- if (flag_objc) \
+ if (c_dialect_objc ()) \
builtin_define_std ("LANGUAGE_OBJECTIVE_C"); \
} \
} \
@@ -91,16 +93,8 @@ Boston, MA 02111-1307, USA. */
/* The global __fltused is necessary to cause the printf/scanf routines
for outputting/inputting floating point numbers to be loaded. Since this
is kind of hard to detect, we just do it all the time. */
-
-#ifdef ASM_FILE_START
-#undef ASM_FILE_START
-#endif
-#define ASM_FILE_START(FILE) \
- do { fprintf (FILE, "\t.file\t"); \
- output_quoted_string (FILE, dump_base_name); \
- fprintf (FILE, "\n"); \
- fprintf (FILE, ".global\t__fltused\n"); \
- } while (0)
+#undef X86_FILE_START_FLTUSED
+#define X86_FILE_START_FLTUSED 1
/* A table of bytes codes used by the ASM_OUTPUT_ASCII and
ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table
@@ -147,18 +141,18 @@ Boston, MA 02111-1307, USA. */
generated assembly code more compact (and thus faster to assemble)
as well as more readable, especially for targets like the i386
(where the only alternative is to output character sequences as
- comma separated lists of numbers). */
+ comma separated lists of numbers). */
#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \
do \
{ \
- register const unsigned char *_limited_str = \
+ const unsigned char *_limited_str = \
(const unsigned char *) (STR); \
- register unsigned ch; \
+ unsigned ch; \
fprintf ((FILE), "%s\"", STRING_ASM_OP); \
for (; (ch = *_limited_str); _limited_str++) \
{ \
- register int escape = ESCAPES[ch]; \
+ int escape = ESCAPES[ch]; \
switch (escape) \
{ \
case 0: \
@@ -188,13 +182,13 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
do \
{ \
- register const unsigned char *_ascii_bytes = \
+ const unsigned char *_ascii_bytes = \
(const unsigned char *) (STR); \
- register const unsigned char *limit = _ascii_bytes + (LENGTH); \
- register unsigned bytes_in_chunk = 0; \
+ const unsigned char *limit = _ascii_bytes + (LENGTH); \
+ unsigned bytes_in_chunk = 0; \
for (; _ascii_bytes < limit; _ascii_bytes++) \
{ \
- register const unsigned char *p; \
+ const unsigned char *p; \
if (bytes_in_chunk >= 64) \
{ \
fputc ('\n', (FILE)); \
@@ -243,6 +237,28 @@ Boston, MA 02111-1307, USA. */
#define TARGET_NOP_FUN_DLLIMPORT 1
#define drectve_section() /* nothing */
+/* Objective-C has its own packing rules...
+ Objc tries to parallel the code in stor-layout.c at runtime
+ (see libobjc/encoding.c). This (compile-time) packing info isn't
+ available at runtime, so it's hopeless to try.
+
+ And if the user tries to set the flag for objc, give an error
+ so he has some clue. */
+
+#undef SUBTARGET_OVERRIDE_OPTIONS
+#define SUBTARGET_OVERRIDE_OPTIONS \
+do { \
+ if (strcmp (lang_hooks.name, "GNU Objective-C") == 0) \
+ { \
+ if ((target_flags & MASK_MS_BITFIELD_LAYOUT) != 0 \
+ && (target_flags_explicit & MASK_MS_BITFIELD_LAYOUT) != 0) \
+ { \
+ error ("ms-bitfields not supported for objc"); \
+ } \
+ target_flags &= ~MASK_MS_BITFIELD_LAYOUT; \
+ } \
+} while (0)
+
#define EH_FRAME_IN_DATA_SECTION
#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rdata,\"r\""
@@ -273,8 +289,6 @@ while (0)
#define HOST_PTR_AS_INT unsigned long
#define PCC_BITFIELD_TYPE_MATTERS 1
-#define PCC_BITFIELD_TYPE_TEST TYPE_NATIVE(rec)
-#define GROUP_BITFIELDS_BY_ALIGN TYPE_NATIVE(rec)
/* The following two flags are usually "off" for i386, because some non-gnu
tools (for the i386) don't handle them. However, we don't have that
@@ -328,7 +342,7 @@ while (0)
symbols must be explicitly imported from shared libraries (DLLs). */
#define MULTIPLE_SYMBOL_SPACES
-extern void i386_pe_unique_section PARAMS ((tree, int));
+extern void i386_pe_unique_section (tree, int);
#define TARGET_ASM_UNIQUE_SECTION i386_pe_unique_section
#define SUPPORTS_ONE_ONLY 1
@@ -343,7 +357,7 @@ extern void i386_pe_unique_section PARAMS ((tree, int));
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
-/* MSVC returns structs of up to 8 bytes via registers. */
+/* MSVC returns structs of up to 8 bytes via registers. */
#define DEFAULT_PCC_STRUCT_RETURN 0
diff --git a/contrib/gcc/config/i386/i386-interix3.h b/contrib/gcc/config/i386/i386-interix3.h
index aafe57fa24d9..7ade70a2c229 100644
--- a/contrib/gcc/config/i386/i386-interix3.h
+++ b/contrib/gcc/config/i386/i386-interix3.h
@@ -1,21 +1,21 @@
-/* Target definitions for GNU compiler for Intel 80386 running Interix V3.
+/* Target definitions for GCC for Intel 80386 running Interix V3.
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/i386-modes.def b/contrib/gcc/config/i386/i386-modes.def
index 5ef800ffcf5e..89c83c441872 100644
--- a/contrib/gcc/config/i386/i386-modes.def
+++ b/contrib/gcc/config/i386/i386-modes.def
@@ -1,23 +1,39 @@
-/* Definitions of target machine for GNU compiler for IA-32.
+/* Definitions of target machine for GCC for IA-32.
Copyright (C) 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* x86_64 ABI specifies both XF and TF modes.
+ XFmode is __float80 is IEEE extended; TFmode is __float128
+ is IEEE quad.
+
+ IEEE extended is 128 bits wide, except in ILP32 mode, but we
+ have to say it's 12 bytes so that the bitsize and wider_mode
+ tables are correctly set up. We correct its size below. */
+
+FLOAT_MODE (XF, 12, ieee_extended_intel_96_format);
+ADJUST_FLOAT_FORMAT (XF, (TARGET_128BIT_LONG_DOUBLE
+ ? &ieee_extended_intel_128_format
+ : &ieee_extended_intel_96_format));
+ADJUST_BYTESIZE (XF, TARGET_128BIT_LONG_DOUBLE ? 16 : 12);
+ADJUST_ALIGNMENT (XF, TARGET_128BIT_LONG_DOUBLE ? 16 : 4);
+FLOAT_MODE (TF, 16, ieee_quad_format);
+
/* Add any extra modes needed to represent the condition code.
For the i386, we need separate modes when floating-point
@@ -27,20 +43,20 @@ Boston, MA 02111-1307, USA. */
Overflow flag to be unset. Sign bit test is used instead and
thus can be used to form "a&b>0" type of tests.
- Add CCGC to indicate comparisons agains zero that allows
+ Add CCGC to indicate comparisons against zero that allows
unspecified garbage in the Carry flag. This mode is used
by inc/dec instructions.
- Add CCGOC to indicate comparisons agains zero that allows
+ Add CCGOC to indicate comparisons against zero that allows
unspecified garbage in the Carry and Overflow flag. This
mode is used to simulate comparisons of (a-b) and (a+b)
against zero using sub/cmp/add operations.
Add CCZ to indicate that only the Zero flag is valid. */
-CC (CCGC)
-CC (CCGOC)
-CC (CCNO)
-CC (CCZ)
-CC (CCFP)
-CC (CCFPU)
+CC_MODE (CCGC);
+CC_MODE (CCGOC);
+CC_MODE (CCNO);
+CC_MODE (CCZ);
+CC_MODE (CCFP);
+CC_MODE (CCFPU);
diff --git a/contrib/gcc/config/i386/i386-protos.h b/contrib/gcc/config/i386/i386-protos.h
index b5ddb37bb2a5..cc1bb813afe5 100644
--- a/contrib/gcc/config/i386/i386-protos.h
+++ b/contrib/gcc/config/i386/i386-protos.h
@@ -1,235 +1,231 @@
-/* Definitions of target machine for GNU compiler for IA-32.
+/* Definitions of target machine for GCC for IA-32.
Copyright (C) 1988, 1992, 1994, 1995, 1996, 1996, 1997, 1998, 1999,
- 2000, 2001 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Functions in i386.c */
-extern void override_options PARAMS ((void));
-extern void optimization_options PARAMS ((int, int));
+extern void override_options (void);
+extern void optimization_options (int, int);
-extern int ix86_can_use_return_insn_p PARAMS ((void));
-extern int ix86_frame_pointer_required PARAMS ((void));
-extern void ix86_setup_frame_addresses PARAMS ((void));
+extern int ix86_can_use_return_insn_p (void);
+extern int ix86_frame_pointer_required (void);
+extern void ix86_setup_frame_addresses (void);
-extern void ix86_asm_file_end PARAMS ((FILE *));
-extern HOST_WIDE_INT ix86_initial_elimination_offset PARAMS((int, int));
-extern void ix86_expand_prologue PARAMS ((void));
-extern void ix86_expand_epilogue PARAMS ((int));
+extern void ix86_file_end (void);
+extern HOST_WIDE_INT ix86_initial_elimination_offset (int, int);
+extern void ix86_expand_prologue (void);
+extern void ix86_expand_epilogue (int);
-extern void ix86_output_addr_vec_elt PARAMS ((FILE *, int));
-extern void ix86_output_addr_diff_elt PARAMS ((FILE *, int, int));
+extern void ix86_output_addr_vec_elt (FILE *, int);
+extern void ix86_output_addr_diff_elt (FILE *, int, int);
#ifdef RTX_CODE
-extern int ix86_aligned_p PARAMS ((rtx));
-
-extern int standard_80387_constant_p PARAMS ((rtx));
-extern int standard_sse_constant_p PARAMS ((rtx));
-extern int symbolic_reference_mentioned_p PARAMS ((rtx));
-
-extern int any_fp_register_operand PARAMS ((rtx, enum machine_mode));
-extern int register_and_not_any_fp_reg_operand PARAMS ((rtx, enum machine_mode));
-
-extern int fp_register_operand PARAMS ((rtx, enum machine_mode));
-extern int register_and_not_fp_reg_operand PARAMS ((rtx, enum machine_mode));
-
-extern int x86_64_general_operand PARAMS ((rtx, enum machine_mode));
-extern int x86_64_szext_general_operand PARAMS ((rtx, enum machine_mode));
-extern int x86_64_nonmemory_operand PARAMS ((rtx, enum machine_mode));
-extern int x86_64_szext_nonmemory_operand PARAMS ((rtx, enum machine_mode));
-extern int x86_64_immediate_operand PARAMS ((rtx, enum machine_mode));
-extern int x86_64_zext_immediate_operand PARAMS ((rtx, enum machine_mode));
-extern int const_int_1_operand PARAMS ((rtx, enum machine_mode));
-extern int symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int tls_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int global_dynamic_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int local_dynamic_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int initial_exec_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int local_exec_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int pic_symbolic_operand PARAMS ((rtx, enum machine_mode));
-extern int call_insn_operand PARAMS ((rtx, enum machine_mode));
-extern int constant_call_address_operand PARAMS ((rtx, enum machine_mode));
-extern int const0_operand PARAMS ((rtx, enum machine_mode));
-extern int const1_operand PARAMS ((rtx, enum machine_mode));
-extern int const248_operand PARAMS ((rtx, enum machine_mode));
-extern int incdec_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_no_sp_operand PARAMS ((rtx, enum machine_mode));
-extern int mmx_reg_operand PARAMS ((rtx, enum machine_mode));
-extern int general_no_elim_operand PARAMS ((rtx, enum machine_mode));
-extern int nonmemory_no_elim_operand PARAMS ((rtx, enum machine_mode));
-extern int q_regs_operand PARAMS ((rtx, enum machine_mode));
-extern int non_q_regs_operand PARAMS ((rtx, enum machine_mode));
-extern int sse_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int fcmov_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int cmp_fp_expander_operand PARAMS ((rtx, enum machine_mode));
-extern int ix86_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int ext_register_operand PARAMS ((rtx, enum machine_mode));
-extern int binary_fp_operator PARAMS ((rtx, enum machine_mode));
-extern int mult_operator PARAMS ((rtx, enum machine_mode));
-extern int div_operator PARAMS ((rtx, enum machine_mode));
-extern int arith_or_logical_operator PARAMS ((rtx, enum machine_mode));
-extern int promotable_binary_operator PARAMS ((rtx, enum machine_mode));
-extern int memory_displacement_operand PARAMS ((rtx, enum machine_mode));
-extern int cmpsi_operand PARAMS ((rtx, enum machine_mode));
-extern int long_memory_operand PARAMS ((rtx, enum machine_mode));
-extern int aligned_operand PARAMS ((rtx, enum machine_mode));
-extern enum machine_mode ix86_cc_mode PARAMS ((enum rtx_code, rtx, rtx));
-
-extern int ix86_expand_movstr PARAMS ((rtx, rtx, rtx, rtx));
-extern int ix86_expand_clrstr PARAMS ((rtx, rtx, rtx));
-extern int ix86_expand_strlen PARAMS ((rtx, rtx, rtx, rtx));
-
-extern bool legitimate_constant_p PARAMS ((rtx));
-extern bool constant_address_p PARAMS ((rtx));
-extern bool legitimate_pic_operand_p PARAMS ((rtx));
-extern int legitimate_pic_address_disp_p PARAMS ((rtx));
-extern int legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
-extern rtx legitimize_pic_address PARAMS ((rtx, rtx));
-extern rtx legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
-
-extern void print_reg PARAMS ((rtx, int, FILE*));
-extern void print_operand PARAMS ((FILE*, rtx, int));
-extern void print_operand_address PARAMS ((FILE*, rtx));
-extern bool output_addr_const_extra PARAMS ((FILE*, rtx));
-
-extern void split_di PARAMS ((rtx[], int, rtx[], rtx[]));
-extern void split_ti PARAMS ((rtx[], int, rtx[], rtx[]));
-
-extern const char *output_set_got PARAMS ((rtx));
-extern const char *output_387_binary_op PARAMS ((rtx, rtx*));
-extern const char *output_fix_trunc PARAMS ((rtx, rtx*));
-extern const char *output_fp_compare PARAMS ((rtx, rtx*, int, int));
-
-extern void i386_dwarf_output_addr_const PARAMS ((FILE*, rtx));
-extern void i386_output_dwarf_dtprel PARAMS ((FILE*, int, rtx));
-extern rtx i386_simplify_dwarf_addr PARAMS ((rtx));
-
-extern void ix86_expand_clear PARAMS ((rtx));
-extern void ix86_expand_move PARAMS ((enum machine_mode, rtx[]));
-extern void ix86_expand_vector_move PARAMS ((enum machine_mode, rtx[]));
-extern void ix86_expand_binary_operator PARAMS ((enum rtx_code,
- enum machine_mode, rtx[]));
-extern int ix86_binary_operator_ok PARAMS ((enum rtx_code, enum machine_mode,
- rtx[]));
-extern void ix86_expand_unary_operator PARAMS ((enum rtx_code, enum machine_mode,
- rtx[]));
-extern int ix86_unary_operator_ok PARAMS ((enum rtx_code, enum machine_mode,
- rtx[]));
-extern int ix86_match_ccmode PARAMS ((rtx, enum machine_mode));
-extern rtx ix86_expand_compare PARAMS ((enum rtx_code, rtx *, rtx *));
-extern int ix86_use_fcomi_compare PARAMS ((enum rtx_code));
-extern void ix86_expand_branch PARAMS ((enum rtx_code, rtx));
-extern int ix86_expand_setcc PARAMS ((enum rtx_code, rtx));
-extern int ix86_expand_int_movcc PARAMS ((rtx[]));
-extern int ix86_expand_fp_movcc PARAMS ((rtx[]));
-extern void ix86_expand_call PARAMS ((rtx, rtx, rtx, rtx, rtx));
-extern void x86_initialize_trampoline PARAMS ((rtx, rtx, rtx));
-extern rtx ix86_zero_extend_to_Pmode PARAMS ((rtx));
-extern void ix86_split_long_move PARAMS ((rtx[]));
-extern void ix86_split_ashldi PARAMS ((rtx *, rtx));
-extern void ix86_split_ashrdi PARAMS ((rtx *, rtx));
-extern void ix86_split_lshrdi PARAMS ((rtx *, rtx));
-extern int ix86_address_cost PARAMS ((rtx));
-extern rtx ix86_find_base_term PARAMS ((rtx));
-extern int ix86_check_movabs PARAMS ((rtx, int));
-
-extern rtx assign_386_stack_local PARAMS ((enum machine_mode, int));
-extern int ix86_attr_length_immediate_default PARAMS ((rtx, int));
-extern int ix86_attr_length_address_default PARAMS ((rtx));
-
-extern enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code));
-
-extern int x86_64_sign_extended_value PARAMS ((rtx));
-extern int x86_64_zero_extended_value PARAMS ((rtx));
-extern rtx ix86_libcall_value PARAMS ((enum machine_mode));
-extern bool ix86_function_value_regno_p PARAMS ((int));
-extern bool ix86_function_arg_regno_p PARAMS ((int));
-extern int ix86_function_arg_boundary PARAMS ((enum machine_mode, tree));
-extern int ix86_return_in_memory PARAMS ((tree));
-extern void ix86_va_start PARAMS ((tree, rtx));
-extern rtx ix86_va_arg PARAMS ((tree, tree));
-extern void ix86_setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int *, int));
-
-extern rtx ix86_force_to_memory PARAMS ((enum machine_mode, rtx));
-extern void ix86_free_from_memory PARAMS ((enum machine_mode));
-extern void ix86_split_fp_branch PARAMS ((enum rtx_code code, rtx,
- rtx, rtx, rtx, rtx));
-extern int ix86_hard_regno_mode_ok PARAMS ((int, enum machine_mode));
-extern int ix86_register_move_cost PARAMS ((enum machine_mode, enum reg_class,
- enum reg_class));
-extern int ix86_secondary_memory_needed PARAMS ((enum reg_class,
- enum reg_class,
- enum machine_mode, int));
-extern enum reg_class ix86_preferred_reload_class PARAMS ((rtx,
- enum reg_class));
-extern int ix86_memory_move_cost PARAMS ((enum machine_mode, enum reg_class,
- int));
-extern void ix86_set_move_mem_attrs PARAMS ((rtx, rtx, rtx, rtx, rtx));
-extern void emit_i387_cw_initialization PARAMS ((rtx, rtx));
-extern bool ix86_fp_jump_nontrivial_p PARAMS ((enum rtx_code));
-extern void x86_order_regs_for_local_alloc PARAMS ((void));
-extern void x86_function_profiler PARAMS ((FILE *, int));
+extern int ix86_aligned_p (rtx);
+
+extern int standard_80387_constant_p (rtx);
+extern const char *standard_80387_constant_opcode (rtx);
+extern rtx standard_80387_constant_rtx (int);
+extern int standard_sse_constant_p (rtx);
+extern int symbolic_reference_mentioned_p (rtx);
+extern bool extended_reg_mentioned_p (rtx);
+extern bool x86_extended_QIreg_mentioned_p (rtx);
+extern bool x86_extended_reg_mentioned_p (rtx);
+
+extern int any_fp_register_operand (rtx, enum machine_mode);
+extern int register_and_not_any_fp_reg_operand (rtx, enum machine_mode);
+
+extern int fp_register_operand (rtx, enum machine_mode);
+extern int register_and_not_fp_reg_operand (rtx, enum machine_mode);
+
+extern int x86_64_general_operand (rtx, enum machine_mode);
+extern int x86_64_szext_general_operand (rtx, enum machine_mode);
+extern int x86_64_nonmemory_operand (rtx, enum machine_mode);
+extern int x86_64_szext_nonmemory_operand (rtx, enum machine_mode);
+extern int x86_64_immediate_operand (rtx, enum machine_mode);
+extern int x86_64_zext_immediate_operand (rtx, enum machine_mode);
+extern int symbolic_operand (rtx, enum machine_mode);
+extern int tls_symbolic_operand (rtx, enum machine_mode);
+extern int global_dynamic_symbolic_operand (rtx, enum machine_mode);
+extern int local_dynamic_symbolic_operand (rtx, enum machine_mode);
+extern int initial_exec_symbolic_operand (rtx, enum machine_mode);
+extern int local_exec_symbolic_operand (rtx, enum machine_mode);
+extern int pic_symbolic_operand (rtx, enum machine_mode);
+extern int call_insn_operand (rtx, enum machine_mode);
+extern int sibcall_insn_operand (rtx, enum machine_mode);
+extern int constant_call_address_operand (rtx, enum machine_mode);
+extern int const0_operand (rtx, enum machine_mode);
+extern int const1_operand (rtx, enum machine_mode);
+extern int const248_operand (rtx, enum machine_mode);
+extern int incdec_operand (rtx, enum machine_mode);
+extern int reg_no_sp_operand (rtx, enum machine_mode);
+extern int mmx_reg_operand (rtx, enum machine_mode);
+extern int general_no_elim_operand (rtx, enum machine_mode);
+extern int nonmemory_no_elim_operand (rtx, enum machine_mode);
+extern int q_regs_operand (rtx, enum machine_mode);
+extern int non_q_regs_operand (rtx, enum machine_mode);
+extern int sse_comparison_operator (rtx, enum machine_mode);
+extern int fcmov_comparison_operator (rtx, enum machine_mode);
+extern int cmp_fp_expander_operand (rtx, enum machine_mode);
+extern int ix86_comparison_operator (rtx, enum machine_mode);
+extern int ext_register_operand (rtx, enum machine_mode);
+extern int binary_fp_operator (rtx, enum machine_mode);
+extern int mult_operator (rtx, enum machine_mode);
+extern int div_operator (rtx, enum machine_mode);
+extern int arith_or_logical_operator (rtx, enum machine_mode);
+extern int promotable_binary_operator (rtx, enum machine_mode);
+extern int memory_displacement_operand (rtx, enum machine_mode);
+extern int cmpsi_operand (rtx, enum machine_mode);
+extern int long_memory_operand (rtx, enum machine_mode);
+extern int aligned_operand (rtx, enum machine_mode);
+extern enum machine_mode ix86_cc_mode (enum rtx_code, rtx, rtx);
+
+extern int ix86_expand_movstr (rtx, rtx, rtx, rtx);
+extern int ix86_expand_clrstr (rtx, rtx, rtx);
+extern int ix86_expand_strlen (rtx, 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_pic_address_disp_p (rtx);
+extern int legitimate_address_p (enum machine_mode, rtx, int);
+extern rtx legitimize_pic_address (rtx, rtx);
+extern rtx legitimize_address (rtx, rtx, enum machine_mode);
+
+extern void print_reg (rtx, int, FILE*);
+extern void print_operand (FILE*, rtx, int);
+extern void print_operand_address (FILE*, rtx);
+extern bool output_addr_const_extra (FILE*, rtx);
+
+extern void split_di (rtx[], int, rtx[], rtx[]);
+extern void split_ti (rtx[], int, rtx[], rtx[]);
+
+extern const char *output_set_got (rtx);
+extern const char *output_387_binary_op (rtx, rtx*);
+extern const char *output_fix_trunc (rtx, rtx*);
+extern const char *output_fp_compare (rtx, rtx*, int, int);
+
+extern void i386_dwarf_output_addr_const (FILE*, rtx);
+extern void i386_output_dwarf_dtprel (FILE*, int, rtx);
+
+extern void ix86_expand_clear (rtx);
+extern void ix86_expand_move (enum machine_mode, rtx[]);
+extern void ix86_expand_vector_move (enum machine_mode, rtx[]);
+extern void ix86_expand_binary_operator (enum rtx_code,
+ enum machine_mode, rtx[]);
+extern int ix86_binary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
+extern void ix86_expand_unary_operator (enum rtx_code, enum machine_mode,
+ rtx[]);
+extern int ix86_unary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
+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 int ix86_expand_int_movcc (rtx[]);
+extern int ix86_expand_fp_movcc (rtx[]);
+extern int ix86_expand_int_addcc (rtx[]);
+extern void ix86_expand_call (rtx, rtx, rtx, rtx, rtx, int);
+extern void x86_initialize_trampoline (rtx, rtx, rtx);
+extern rtx ix86_zero_extend_to_Pmode (rtx);
+extern void ix86_split_long_move (rtx[]);
+extern void ix86_split_ashldi (rtx *, rtx);
+extern void ix86_split_ashrdi (rtx *, rtx);
+extern void ix86_split_lshrdi (rtx *, rtx);
+extern rtx ix86_find_base_term (rtx);
+extern int ix86_check_movabs (rtx, int);
+
+extern rtx assign_386_stack_local (enum machine_mode, int);
+extern int ix86_attr_length_immediate_default (rtx, int);
+extern int ix86_attr_length_address_default (rtx);
+
+extern enum machine_mode ix86_fp_compare_mode (enum rtx_code);
+
+extern int x86_64_sign_extended_value (rtx);
+extern int x86_64_zero_extended_value (rtx);
+extern rtx ix86_libcall_value (enum machine_mode);
+extern bool ix86_function_value_regno_p (int);
+extern bool ix86_function_arg_regno_p (int);
+extern int ix86_function_arg_boundary (enum machine_mode, tree);
+extern int ix86_return_in_memory (tree);
+extern void ix86_va_start (tree, rtx);
+extern rtx ix86_va_arg (tree, tree);
+extern void ix86_setup_incoming_varargs (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int *, int);
+
+extern rtx ix86_force_to_memory (enum machine_mode, rtx);
+extern void ix86_free_from_memory (enum machine_mode);
+extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx, rtx, rtx, rtx);
+extern int ix86_hard_regno_mode_ok (int, enum machine_mode);
+extern int ix86_register_move_cost (enum machine_mode, enum reg_class,
+ enum reg_class);
+extern int ix86_secondary_memory_needed (enum reg_class, enum reg_class,
+ enum machine_mode, int);
+extern enum reg_class ix86_preferred_reload_class (rtx, enum reg_class);
+extern int ix86_memory_move_cost (enum machine_mode, enum reg_class, int);
+extern void emit_i387_cw_initialization (rtx, rtx);
+extern bool ix86_fp_jump_nontrivial_p (enum rtx_code);
+extern void x86_order_regs_for_local_alloc (void);
+extern void x86_function_profiler (FILE *, int);
+extern void x86_emit_floatuns (rtx [2]);
#ifdef TREE_CODE
-extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx));
-extern rtx function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
-extern int function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-extern void function_arg_advance PARAMS ((CUMULATIVE_ARGS *, enum machine_mode,
- tree, int));
-extern rtx ix86_function_value PARAMS ((tree));
-extern void ix86_init_builtins PARAMS ((void));
-extern rtx ix86_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
+extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
+extern rtx function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
+extern int function_arg_pass_by_reference (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, int);
+extern rtx ix86_function_value (tree);
+extern void ix86_init_builtins (void);
+extern rtx ix86_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
#endif
#endif
#ifdef TREE_CODE
-extern int ix86_return_pops_args PARAMS ((tree, tree, int));
-extern tree ix86_build_va_list PARAMS ((void));
-
-extern int ix86_data_alignment PARAMS ((tree, int));
-extern int ix86_local_alignment PARAMS ((tree, int));
-extern int ix86_constant_alignment PARAMS ((tree, int));
-extern tree ix86_handle_dll_attribute PARAMS ((tree *, tree, tree, int, bool *));
-extern tree ix86_handle_shared_attribute PARAMS ((tree *, tree, tree, int, bool *));
-
-extern unsigned int i386_pe_section_type_flags PARAMS ((tree, const char *,
- int));
-extern void i386_pe_asm_named_section PARAMS ((const char *, unsigned int));
-extern int x86_field_alignment PARAMS ((tree, int));
+extern int ix86_return_pops_args (tree, tree, int);
+
+extern int ix86_data_alignment (tree, int);
+extern int ix86_local_alignment (tree, int);
+extern int ix86_constant_alignment (tree, int);
+extern tree ix86_handle_dll_attribute (tree *, tree, tree, int, bool *);
+extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
+
+extern unsigned int i386_pe_section_type_flags (tree, const char *, int);
+extern void i386_pe_asm_named_section (const char *, unsigned int);
+extern int x86_field_alignment (tree, int);
#endif
-extern rtx ix86_tls_get_addr PARAMS ((void));
-extern void x86_machine_dependent_reorg PARAMS ((rtx));
+extern rtx ix86_tls_get_addr (void);
+extern bool ix86_must_pass_in_stack (enum machine_mode mode, tree);
+extern void ix86_expand_vector_init (rtx, rtx);
/* In winnt.c */
-extern int i386_pe_dllexport_name_p PARAMS ((const char *));
-extern int i386_pe_dllimport_name_p PARAMS ((const char *));
-extern void i386_pe_unique_section PARAMS ((tree, int));
-extern void i386_pe_declare_function_type PARAMS ((FILE *, const char *, int));
-extern void i386_pe_record_external_function PARAMS ((const char *));
-extern void i386_pe_record_exported_symbol PARAMS ((const char *, int));
-extern void i386_pe_asm_file_end PARAMS ((FILE *));
-extern void i386_pe_encode_section_info PARAMS ((tree, int));
-extern const char *i386_pe_strip_name_encoding PARAMS ((const char *));
-extern const char *i386_pe_strip_name_encoding_full PARAMS ((const char *));
+extern int i386_pe_dllexport_name_p (const char *);
+extern int i386_pe_dllimport_name_p (const char *);
+extern void i386_pe_unique_section (tree, int);
+extern void i386_pe_declare_function_type (FILE *, const char *, int);
+extern void i386_pe_record_external_function (const char *);
+extern void i386_pe_record_exported_symbol (const char *, int);
+extern void i386_pe_asm_file_end (FILE *);
+extern void i386_pe_encode_section_info (tree, rtx, int);
+extern const char *i386_pe_strip_name_encoding (const char *);
+extern const char *i386_pe_strip_name_encoding_full (const char *);
+extern void i386_pe_output_labelref (FILE *, const char *);
diff --git a/contrib/gcc/config/i386/i386.c b/contrib/gcc/config/i386/i386.c
index 3abae59ec53f..c2f59c9cb15b 100644
--- a/contrib/gcc/config/i386/i386.c
+++ b/contrib/gcc/config/i386/i386.c
@@ -1,26 +1,28 @@
/* Subroutines used for code generation on IA-32.
Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003 Free Software Foundation, Inc.
+ 2002, 2003, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
@@ -43,11 +45,20 @@ Boston, MA 02111-1307, USA. */
#include "target.h"
#include "target-def.h"
#include "langhooks.h"
+#include "cgraph.h"
#ifndef CHECK_STACK_LIMIT
#define CHECK_STACK_LIMIT (-1)
#endif
+/* Return index of given mode in mult and division cost tables. */
+#define MODE_INDEX(mode) \
+ ((mode) == QImode ? 0 \
+ : (mode) == HImode ? 1 \
+ : (mode) == SImode ? 2 \
+ : (mode) == DImode ? 3 \
+ : 4)
+
/* Processor costs (relative to an add) */
static const
struct processor_costs size_cost = { /* costs for tunning for size */
@@ -55,9 +66,9 @@ struct processor_costs size_cost = { /* costs for tunning for size */
3, /* cost of a lea instruction */
2, /* variable shift costs */
3, /* constant shift costs */
- 3, /* cost of starting a multiply */
+ {3, 3, 3, 3, 5}, /* cost of starting a multiply */
0, /* cost of multiply per each bit set */
- 3, /* cost of a divide/mod */
+ {3, 3, 3, 3, 5}, /* cost of a divide/mod */
3, /* cost of movsx */
3, /* cost of movzx */
0, /* "large" insn */
@@ -84,6 +95,7 @@ struct processor_costs size_cost = { /* costs for tunning for size */
3, /* MMX or SSE register to integer */
0, /* size of prefetch block */
0, /* number of parallel prefetches */
+ 1, /* Branch cost */
2, /* cost of FADD and FSUB insns. */
2, /* cost of FMUL instruction. */
2, /* cost of FDIV instruction. */
@@ -99,9 +111,9 @@ struct processor_costs i386_cost = { /* 386 specific costs */
1, /* cost of a lea instruction */
3, /* variable shift costs */
2, /* constant shift costs */
- 6, /* cost of starting a multiply */
+ {6, 6, 6, 6, 6}, /* cost of starting a multiply */
1, /* cost of multiply per each bit set */
- 23, /* cost of a divide/mod */
+ {23, 23, 23, 23, 23}, /* cost of a divide/mod */
3, /* cost of movsx */
2, /* cost of movzx */
15, /* "large" insn */
@@ -128,6 +140,7 @@ struct processor_costs i386_cost = { /* 386 specific costs */
3, /* MMX or SSE register to integer */
0, /* size of prefetch block */
0, /* number of parallel prefetches */
+ 1, /* Branch cost */
23, /* cost of FADD and FSUB insns. */
27, /* cost of FMUL instruction. */
88, /* cost of FDIV instruction. */
@@ -142,9 +155,9 @@ struct processor_costs i486_cost = { /* 486 specific costs */
1, /* cost of a lea instruction */
3, /* variable shift costs */
2, /* constant shift costs */
- 12, /* cost of starting a multiply */
+ {12, 12, 12, 12, 12}, /* cost of starting a multiply */
1, /* cost of multiply per each bit set */
- 40, /* cost of a divide/mod */
+ {40, 40, 40, 40, 40}, /* cost of a divide/mod */
3, /* cost of movsx */
2, /* cost of movzx */
15, /* "large" insn */
@@ -171,6 +184,7 @@ struct processor_costs i486_cost = { /* 486 specific costs */
3, /* MMX or SSE register to integer */
0, /* size of prefetch block */
0, /* number of parallel prefetches */
+ 1, /* Branch cost */
8, /* cost of FADD and FSUB insns. */
16, /* cost of FMUL instruction. */
73, /* cost of FDIV instruction. */
@@ -185,9 +199,9 @@ struct processor_costs pentium_cost = {
1, /* cost of a lea instruction */
4, /* variable shift costs */
1, /* constant shift costs */
- 11, /* cost of starting a multiply */
+ {11, 11, 11, 11, 11}, /* cost of starting a multiply */
0, /* cost of multiply per each bit set */
- 25, /* cost of a divide/mod */
+ {25, 25, 25, 25, 25}, /* cost of a divide/mod */
3, /* cost of movsx */
2, /* cost of movzx */
8, /* "large" insn */
@@ -214,6 +228,7 @@ struct processor_costs pentium_cost = {
3, /* MMX or SSE register to integer */
0, /* size of prefetch block */
0, /* number of parallel prefetches */
+ 2, /* Branch cost */
3, /* cost of FADD and FSUB insns. */
3, /* cost of FMUL instruction. */
39, /* cost of FDIV instruction. */
@@ -228,9 +243,9 @@ struct processor_costs pentiumpro_cost = {
1, /* cost of a lea instruction */
1, /* variable shift costs */
1, /* constant shift costs */
- 4, /* cost of starting a multiply */
+ {4, 4, 4, 4, 4}, /* cost of starting a multiply */
0, /* cost of multiply per each bit set */
- 17, /* cost of a divide/mod */
+ {17, 17, 17, 17, 17}, /* cost of a divide/mod */
1, /* cost of movsx */
1, /* cost of movzx */
8, /* "large" insn */
@@ -257,6 +272,7 @@ struct processor_costs pentiumpro_cost = {
3, /* MMX or SSE register to integer */
32, /* size of prefetch block */
6, /* number of parallel prefetches */
+ 2, /* Branch cost */
3, /* cost of FADD and FSUB insns. */
5, /* cost of FMUL instruction. */
56, /* cost of FDIV instruction. */
@@ -271,9 +287,9 @@ struct processor_costs k6_cost = {
2, /* cost of a lea instruction */
1, /* variable shift costs */
1, /* constant shift costs */
- 3, /* cost of starting a multiply */
+ {3, 3, 3, 3, 3}, /* cost of starting a multiply */
0, /* cost of multiply per each bit set */
- 18, /* cost of a divide/mod */
+ {18, 18, 18, 18, 18}, /* cost of a divide/mod */
2, /* cost of movsx */
2, /* cost of movzx */
8, /* "large" insn */
@@ -300,6 +316,7 @@ struct processor_costs k6_cost = {
6, /* MMX or SSE register to integer */
32, /* size of prefetch block */
1, /* number of parallel prefetches */
+ 1, /* Branch cost */
2, /* cost of FADD and FSUB insns. */
2, /* cost of FMUL instruction. */
56, /* cost of FDIV instruction. */
@@ -314,9 +331,9 @@ struct processor_costs athlon_cost = {
2, /* cost of a lea instruction */
1, /* variable shift costs */
1, /* constant shift costs */
- 5, /* cost of starting a multiply */
+ {5, 5, 5, 5, 5}, /* cost of starting a multiply */
0, /* cost of multiply per each bit set */
- 42, /* cost of a divide/mod */
+ {18, 26, 42, 74, 74}, /* cost of a divide/mod */
1, /* cost of movsx */
1, /* cost of movzx */
8, /* "large" insn */
@@ -343,6 +360,7 @@ struct processor_costs athlon_cost = {
5, /* MMX or SSE register to integer */
64, /* size of prefetch block */
6, /* number of parallel prefetches */
+ 2, /* Branch cost */
4, /* cost of FADD and FSUB insns. */
4, /* cost of FMUL instruction. */
24, /* cost of FDIV instruction. */
@@ -352,14 +370,58 @@ struct processor_costs athlon_cost = {
};
static const
+struct processor_costs k8_cost = {
+ 1, /* cost of an add instruction */
+ 2, /* cost of a lea instruction */
+ 1, /* variable shift costs */
+ 1, /* constant shift costs */
+ {3, 4, 3, 4, 5}, /* cost of starting a multiply */
+ 0, /* cost of multiply per each bit set */
+ {18, 26, 42, 74, 74}, /* cost of a divide/mod */
+ 1, /* cost of movsx */
+ 1, /* cost of movzx */
+ 8, /* "large" insn */
+ 9, /* MOVE_RATIO */
+ 4, /* cost for loading QImode using movzbl */
+ {3, 4, 3}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {3, 4, 3}, /* cost of storing integer registers */
+ 4, /* cost of reg,reg fld/fst */
+ {4, 4, 12}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {6, 6, 8}, /* cost of loading integer registers */
+ 2, /* cost of moving MMX register */
+ {3, 3}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {4, 4}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, /* cost of moving SSE register */
+ {4, 3, 6}, /* cost of loading SSE registers
+ in SImode, DImode and TImode */
+ {4, 4, 5}, /* cost of storing SSE registers
+ in SImode, DImode and TImode */
+ 5, /* MMX or SSE register to integer */
+ 64, /* size of prefetch block */
+ 6, /* number of parallel prefetches */
+ 2, /* Branch cost */
+ 4, /* cost of FADD and FSUB insns. */
+ 4, /* cost of FMUL instruction. */
+ 19, /* cost of FDIV instruction. */
+ 2, /* cost of FABS instruction. */
+ 2, /* cost of FCHS instruction. */
+ 35, /* cost of FSQRT instruction. */
+};
+
+static const
struct processor_costs pentium4_cost = {
1, /* cost of an add instruction */
1, /* cost of a lea instruction */
- 8, /* variable shift costs */
- 8, /* constant shift costs */
- 30, /* cost of starting a multiply */
+ 4, /* variable shift costs */
+ 4, /* constant shift costs */
+ {15, 15, 15, 15, 15}, /* cost of starting a multiply */
0, /* cost of multiply per each bit set */
- 112, /* cost of a divide/mod */
+ {56, 56, 56, 56, 56}, /* cost of a divide/mod */
1, /* cost of movsx */
1, /* cost of movzx */
16, /* "large" insn */
@@ -386,6 +448,7 @@ struct processor_costs pentium4_cost = {
10, /* MMX or SSE register to integer */
64, /* size of prefetch block */
6, /* number of parallel prefetches */
+ 2, /* Branch cost */
5, /* cost of FADD and FSUB insns. */
7, /* cost of FMUL instruction. */
43, /* cost of FDIV instruction. */
@@ -404,56 +467,68 @@ const struct processor_costs *ix86_cost = &pentium_cost;
#define m_K6 (1<<PROCESSOR_K6)
#define m_ATHLON (1<<PROCESSOR_ATHLON)
#define m_PENT4 (1<<PROCESSOR_PENTIUM4)
+#define m_K8 (1<<PROCESSOR_K8)
+#define m_ATHLON_K8 (m_K8 | m_ATHLON)
-const int x86_use_leave = m_386 | m_K6 | m_ATHLON;
-const int x86_push_memory = m_386 | m_K6 | m_ATHLON | m_PENT4;
+const int x86_use_leave = m_386 | m_K6 | m_ATHLON_K8;
+const int x86_push_memory = m_386 | m_K6 | m_ATHLON_K8 | m_PENT4;
const int x86_zero_extend_with_and = m_486 | m_PENT;
-const int x86_movx = m_ATHLON | m_PPRO | m_PENT4 /* m_386 | m_K6 */;
+const int x86_movx = m_ATHLON_K8 | m_PPRO | m_PENT4 /* m_386 | m_K6 */;
const int x86_double_with_add = ~m_386;
const int x86_use_bit_test = m_386;
-const int x86_unroll_strlen = m_486 | m_PENT | m_PPRO | m_ATHLON | m_K6;
-const int x86_cmove = m_PPRO | m_ATHLON | m_PENT4;
-const int x86_3dnow_a = m_ATHLON;
-const int x86_deep_branch = m_PPRO | m_K6 | m_ATHLON | m_PENT4;
+const int x86_unroll_strlen = m_486 | m_PENT | m_PPRO | m_ATHLON_K8 | m_K6;
+const int x86_cmove = m_PPRO | m_ATHLON_K8 | m_PENT4;
+const int x86_3dnow_a = m_ATHLON_K8;
+const int x86_deep_branch = m_PPRO | m_K6 | m_ATHLON_K8 | m_PENT4;
const int x86_branch_hints = m_PENT4;
const int x86_use_sahf = m_PPRO | m_K6 | m_PENT4;
const int x86_partial_reg_stall = m_PPRO;
const int x86_use_loop = m_K6;
-const int x86_use_fiop = ~(m_PPRO | m_ATHLON | m_PENT);
+const int x86_use_fiop = ~(m_PPRO | m_ATHLON_K8 | m_PENT);
const int x86_use_mov0 = m_K6;
const int x86_use_cltd = ~(m_PENT | m_K6);
const int x86_read_modify_write = ~m_PENT;
const int x86_read_modify = ~(m_PENT | m_PPRO);
const int x86_split_long_moves = m_PPRO;
-const int x86_promote_QImode = m_K6 | m_PENT | m_386 | m_486 | m_ATHLON;
+const int x86_promote_QImode = m_K6 | m_PENT | m_386 | m_486 | m_ATHLON_K8;
const int x86_fast_prefix = ~(m_PENT | m_486 | m_386);
const int x86_single_stringop = m_386 | m_PENT4;
const int x86_qimode_math = ~(0);
const int x86_promote_qi_regs = 0;
const int x86_himode_math = ~(m_PPRO);
const int x86_promote_hi_regs = m_PPRO;
-const int x86_sub_esp_4 = m_ATHLON | m_PPRO | m_PENT4;
-const int x86_sub_esp_8 = m_ATHLON | m_PPRO | m_386 | m_486 | m_PENT4;
-const int x86_add_esp_4 = m_ATHLON | m_K6 | m_PENT4;
-const int x86_add_esp_8 = m_ATHLON | m_PPRO | m_K6 | m_386 | m_486 | m_PENT4;
-const int x86_integer_DFmode_moves = ~(m_ATHLON | m_PENT4 | m_PPRO);
-const int x86_partial_reg_dependency = m_ATHLON | m_PENT4;
-const int x86_memory_mismatch_stall = m_ATHLON | m_PENT4;
-const int x86_accumulate_outgoing_args = m_ATHLON | m_PENT4 | m_PPRO;
-const int x86_prologue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
-const int x86_epilogue_using_move = m_ATHLON | m_PENT4 | m_PPRO;
+const int x86_sub_esp_4 = m_ATHLON_K8 | m_PPRO | m_PENT4;
+const int x86_sub_esp_8 = m_ATHLON_K8 | m_PPRO | m_386 | m_486 | m_PENT4;
+const int x86_add_esp_4 = m_ATHLON_K8 | m_K6 | m_PENT4;
+const int x86_add_esp_8 = m_ATHLON_K8 | m_PPRO | m_K6 | m_386 | m_486 | m_PENT4;
+const int x86_integer_DFmode_moves = ~(m_ATHLON_K8 | m_PENT4 | m_PPRO);
+const int x86_partial_reg_dependency = m_ATHLON_K8 | m_PENT4;
+const int x86_memory_mismatch_stall = m_ATHLON_K8 | m_PENT4;
+const int x86_accumulate_outgoing_args = m_ATHLON_K8 | m_PENT4 | m_PPRO;
+const int x86_prologue_using_move = m_ATHLON_K8 | m_PENT4 | m_PPRO;
+const int x86_epilogue_using_move = m_ATHLON_K8 | m_PENT4 | m_PPRO;
const int x86_decompose_lea = m_PENT4;
const int x86_shift1 = ~m_486;
-const int x86_arch_always_fancy_math_387 = m_PENT | m_PPRO | m_ATHLON | m_PENT4;
-
-/* In case the avreage insn count for single function invocation is
+const int x86_arch_always_fancy_math_387 = m_PENT | m_PPRO | m_ATHLON_K8 | m_PENT4;
+const int x86_sse_partial_reg_dependency = m_PENT4 | m_PPRO;
+/* Set for machines where the type and dependencies are resolved on SSE register
+ parts instead of whole registers, so we may maintain just lower part of
+ scalar values in proper format leaving the upper part undefined. */
+const int x86_sse_partial_regs = m_ATHLON_K8;
+/* Athlon optimizes partial-register FPS special case, thus avoiding the
+ need for extra instructions beforehand */
+const int x86_sse_partial_regs_for_cvtsd2ss = 0;
+const int x86_sse_typeless_stores = m_ATHLON_K8;
+const int x86_sse_load0_by_pxor = m_PPRO | m_PENT4;
+const int x86_use_ffreep = m_ATHLON_K8;
+const int x86_rep_movl_optimal = m_386 | m_PENT | m_PPRO | m_K6;
+const int x86_inter_unit_moves = ~(m_ATHLON_K8);
+const int x86_ext_80387_constants = m_K6 | m_ATHLON | m_PENT4 | m_PPRO;
+
+/* In case the average insn count for single function invocation is
lower than this constant, emit fast (but longer) prologue and
epilogue code. */
-#define FAST_PROLOGUE_INSN_COUNT 30
-
-/* Set by prologue expander and used by epilogue expander to determine
- the style used. */
-static int use_fast_prologue_epilogue;
+#define FAST_PROLOGUE_INSN_COUNT 20
/* Names for 8 (low), 8 (high), and 16-bit registers, respectively. */
static const char *const qi_reg_name[] = QI_REGISTER_NAMES;
@@ -583,8 +658,8 @@ int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
-1, 9, -1, -1, -1, /* arg, flags, fpsr, dir, frame */
21, 22, 23, 24, 25, 26, 27, 28, /* SSE registers */
29, 30, 31, 32, 33, 34, 35, 36, /* MMX registers */
- -1, -1, -1, -1, -1, -1, -1, -1, /* extemded integer registers */
- -1, -1, -1, -1, -1, -1, -1, -1, /* extemded SSE registers */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* extended integer registers */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */
};
/* Test and compare insns in i386.md store the information needed to
@@ -593,26 +668,20 @@ int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
rtx ix86_compare_op0 = NULL_RTX;
rtx ix86_compare_op1 = NULL_RTX;
-/* The encoding characters for the four TLS models present in ELF. */
-
-static char const tls_model_chars[] = " GLil";
-
#define MAX_386_STACK_LOCALS 3
/* Size of the register save area. */
#define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
/* Define the structure for the machine field in struct function. */
-struct machine_function GTY(())
+
+struct stack_local_entry GTY(())
{
- rtx stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
- const char *some_ld_name;
- int save_varrargs_registers;
- int accesses_prev_frame;
+ unsigned short mode;
+ unsigned short n;
+ rtx rtl;
+ struct stack_local_entry *next;
};
-#define ix86_stack_locals (cfun->machine->stack_locals)
-#define ix86_save_varrargs_registers (cfun->machine->save_varrargs_registers)
-
/* Structure describing stack frame layout.
Stack grows downward:
@@ -647,6 +716,10 @@ struct ix86_frame
HOST_WIDE_INT frame_pointer_offset;
HOST_WIDE_INT hard_frame_pointer_offset;
HOST_WIDE_INT stack_pointer_offset;
+
+ /* When save_regs_using_mov is set, emit prologue using
+ move instead of push instructions. */
+ bool save_regs_using_mov;
};
/* Used to enable/disable debugging features. */
@@ -666,12 +739,12 @@ enum tls_dialect ix86_tls_dialect = TLS_DIALECT_GNU;
enum fpmath_unit ix86_fpmath;
/* Which cpu are we scheduling for. */
-enum processor_type ix86_cpu;
+enum processor_type ix86_tune;
/* Which instruction set architecture to use. */
enum processor_type ix86_arch;
/* Strings to hold which cpu and instruction set architecture to use. */
-const char *ix86_cpu_string; /* for -mcpu=<xxx> */
+const char *ix86_tune_string; /* for -mtune=<xxx> */
const char *ix86_arch_string; /* for -march=<xxx> */
const char *ix86_fpmath_string; /* for -mfpmath=<xxx> */
@@ -709,108 +782,117 @@ const char *ix86_align_funcs_string;
static char internal_label_prefix[16];
static int internal_label_prefix_len;
-static int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
-static int tls_symbolic_operand_1 PARAMS ((rtx, enum tls_model));
-static void output_pic_addr_const PARAMS ((FILE *, rtx, int));
-static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode,
- int, int, FILE *));
-static const char *get_some_local_dynamic_name PARAMS ((void));
-static int get_some_local_dynamic_name_1 PARAMS ((rtx *, void *));
-static rtx maybe_get_pool_constant PARAMS ((rtx));
-static rtx ix86_expand_int_compare PARAMS ((enum rtx_code, rtx, rtx));
-static enum rtx_code ix86_prepare_fp_compare_args PARAMS ((enum rtx_code,
- rtx *, rtx *));
-static rtx get_thread_pointer PARAMS ((void));
-static void get_pc_thunk_name PARAMS ((char [32], unsigned int));
-static rtx gen_push PARAMS ((rtx));
-static int memory_address_length PARAMS ((rtx addr));
-static int ix86_flags_dependant PARAMS ((rtx, rtx, enum attr_type));
-static int ix86_agi_dependant PARAMS ((rtx, rtx, enum attr_type));
-static enum attr_ppro_uops ix86_safe_ppro_uops PARAMS ((rtx));
-static void ix86_dump_ppro_packet PARAMS ((FILE *));
-static void ix86_reorder_insn PARAMS ((rtx *, rtx *));
-static struct machine_function * ix86_init_machine_status PARAMS ((void));
-static int ix86_split_to_parts PARAMS ((rtx, rtx *, enum machine_mode));
-static int ix86_nsaved_regs PARAMS ((void));
-static void ix86_emit_save_regs PARAMS ((void));
-static void ix86_emit_save_regs_using_mov PARAMS ((rtx, HOST_WIDE_INT));
-static void ix86_emit_restore_regs_using_mov PARAMS ((rtx, int, int));
-static void ix86_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-static void ix86_set_move_mem_attrs_1 PARAMS ((rtx, rtx, rtx, rtx, rtx));
-static void ix86_sched_reorder_ppro PARAMS ((rtx *, rtx *));
-static HOST_WIDE_INT ix86_GOT_alias_set PARAMS ((void));
-static void ix86_adjust_counter PARAMS ((rtx, HOST_WIDE_INT));
-static rtx ix86_expand_aligntest PARAMS ((rtx, int));
-static void ix86_expand_strlensi_unroll_1 PARAMS ((rtx, rtx));
-static int ix86_issue_rate PARAMS ((void));
-static int ix86_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static void ix86_sched_init PARAMS ((FILE *, int, int));
-static int ix86_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
-static int ix86_variable_issue PARAMS ((FILE *, int, rtx, int));
-static int ia32_use_dfa_pipeline_interface PARAMS ((void));
-static int ia32_multipass_dfa_lookahead PARAMS ((void));
-static void ix86_init_mmx_sse_builtins PARAMS ((void));
-static rtx x86_this_parameter PARAMS ((tree));
-static void x86_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
- HOST_WIDE_INT, tree));
-static bool x86_can_output_mi_thunk PARAMS ((tree, HOST_WIDE_INT,
- HOST_WIDE_INT, tree));
+static int local_symbolic_operand (rtx, enum machine_mode);
+static int tls_symbolic_operand_1 (rtx, enum tls_model);
+static void output_pic_addr_const (FILE *, rtx, int);
+static void put_condition_code (enum rtx_code, enum machine_mode,
+ int, int, FILE *);
+static const char *get_some_local_dynamic_name (void);
+static int get_some_local_dynamic_name_1 (rtx *, void *);
+static rtx maybe_get_pool_constant (rtx);
+static rtx ix86_expand_int_compare (enum rtx_code, rtx, rtx);
+static enum rtx_code ix86_prepare_fp_compare_args (enum rtx_code, rtx *,
+ rtx *);
+static bool ix86_fixed_condition_code_regs (unsigned int *, unsigned int *);
+static enum machine_mode ix86_cc_modes_compatible (enum machine_mode,
+ enum machine_mode);
+static rtx get_thread_pointer (int);
+static rtx legitimize_tls_address (rtx, enum tls_model, int);
+static void get_pc_thunk_name (char [32], unsigned int);
+static rtx gen_push (rtx);
+static int memory_address_length (rtx addr);
+static int ix86_flags_dependant (rtx, rtx, enum attr_type);
+static int ix86_agi_dependant (rtx, rtx, enum attr_type);
+static enum attr_ppro_uops ix86_safe_ppro_uops (rtx);
+static void ix86_dump_ppro_packet (FILE *);
+static void ix86_reorder_insn (rtx *, rtx *);
+static struct machine_function * ix86_init_machine_status (void);
+static int ix86_split_to_parts (rtx, rtx *, enum machine_mode);
+static int ix86_nsaved_regs (void);
+static void ix86_emit_save_regs (void);
+static void ix86_emit_save_regs_using_mov (rtx, HOST_WIDE_INT);
+static void ix86_emit_restore_regs_using_mov (rtx, HOST_WIDE_INT, int);
+static void ix86_output_function_epilogue (FILE *, HOST_WIDE_INT);
+static void ix86_sched_reorder_ppro (rtx *, rtx *);
+static HOST_WIDE_INT ix86_GOT_alias_set (void);
+static void ix86_adjust_counter (rtx, HOST_WIDE_INT);
+static rtx ix86_expand_aligntest (rtx, int);
+static void ix86_expand_strlensi_unroll_1 (rtx, rtx, rtx);
+static int ix86_issue_rate (void);
+static int ix86_adjust_cost (rtx, rtx, rtx, int);
+static void ix86_sched_init (FILE *, int, int);
+static int ix86_sched_reorder (FILE *, int, rtx *, int *, int);
+static int ix86_variable_issue (FILE *, int, rtx, int);
+static int ia32_use_dfa_pipeline_interface (void);
+static int ia32_multipass_dfa_lookahead (void);
+static void ix86_init_mmx_sse_builtins (void);
+static rtx x86_this_parameter (tree);
+static void x86_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
+ HOST_WIDE_INT, tree);
+static bool x86_can_output_mi_thunk (tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
+static void x86_file_start (void);
+static void ix86_reorg (void);
+static bool ix86_expand_carry_flag_compare (enum rtx_code, rtx, rtx, rtx*);
+static tree ix86_build_builtin_va_list (void);
struct ix86_address
{
rtx base, index, disp;
HOST_WIDE_INT scale;
+ enum ix86_address_seg { SEG_DEFAULT, SEG_FS, SEG_GS } seg;
};
-static int ix86_decompose_address PARAMS ((rtx, struct ix86_address *));
-static bool ix86_cannot_force_const_mem PARAMS ((rtx));
-
-static void ix86_encode_section_info PARAMS ((tree, int)) ATTRIBUTE_UNUSED;
-static const char *ix86_strip_name_encoding PARAMS ((const char *))
- ATTRIBUTE_UNUSED;
+static int ix86_decompose_address (rtx, struct ix86_address *);
+static int ix86_address_cost (rtx);
+static bool ix86_cannot_force_const_mem (rtx);
+static rtx ix86_delegitimize_address (rtx);
struct builtin_description;
-static rtx ix86_expand_sse_comi PARAMS ((const struct builtin_description *,
- tree, rtx));
-static rtx ix86_expand_sse_compare PARAMS ((const struct builtin_description *,
- tree, rtx));
-static rtx ix86_expand_unop1_builtin PARAMS ((enum insn_code, tree, rtx));
-static rtx ix86_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx, int));
-static rtx ix86_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
-static rtx ix86_expand_store_builtin PARAMS ((enum insn_code, tree));
-static rtx safe_vector_operand PARAMS ((rtx, enum machine_mode));
-static enum rtx_code ix86_fp_compare_code_to_integer PARAMS ((enum rtx_code));
-static void ix86_fp_comparison_codes PARAMS ((enum rtx_code code,
- enum rtx_code *,
- enum rtx_code *,
- enum rtx_code *));
-static rtx ix86_expand_fp_compare PARAMS ((enum rtx_code, rtx, rtx, rtx,
- rtx *, rtx *));
-static int ix86_fp_comparison_arithmetics_cost PARAMS ((enum rtx_code code));
-static int ix86_fp_comparison_fcomi_cost PARAMS ((enum rtx_code code));
-static int ix86_fp_comparison_sahf_cost PARAMS ((enum rtx_code code));
-static int ix86_fp_comparison_cost PARAMS ((enum rtx_code code));
-static unsigned int ix86_select_alt_pic_regnum PARAMS ((void));
-static int ix86_save_reg PARAMS ((unsigned int, int));
-static void ix86_compute_frame_layout PARAMS ((struct ix86_frame *));
-static int ix86_comp_type_attributes PARAMS ((tree, tree));
-static int ix86_fntype_regparm PARAMS ((tree));
+static rtx ix86_expand_sse_comi (const struct builtin_description *,
+ tree, rtx);
+static rtx ix86_expand_sse_compare (const struct builtin_description *,
+ tree, rtx);
+static rtx ix86_expand_unop1_builtin (enum insn_code, tree, rtx);
+static rtx ix86_expand_unop_builtin (enum insn_code, tree, rtx, int);
+static rtx ix86_expand_binop_builtin (enum insn_code, tree, rtx);
+static rtx ix86_expand_store_builtin (enum insn_code, tree);
+static rtx safe_vector_operand (rtx, enum machine_mode);
+static enum rtx_code ix86_fp_compare_code_to_integer (enum rtx_code);
+static void ix86_fp_comparison_codes (enum rtx_code code, enum rtx_code *,
+ enum rtx_code *, enum rtx_code *);
+static rtx ix86_expand_fp_compare (enum rtx_code, rtx, rtx, rtx, rtx *, rtx *);
+static int ix86_fp_comparison_arithmetics_cost (enum rtx_code code);
+static int ix86_fp_comparison_fcomi_cost (enum rtx_code code);
+static int ix86_fp_comparison_sahf_cost (enum rtx_code code);
+static int ix86_fp_comparison_cost (enum rtx_code code);
+static unsigned int ix86_select_alt_pic_regnum (void);
+static int ix86_save_reg (unsigned int, int);
+static void ix86_compute_frame_layout (struct ix86_frame *);
+static int ix86_comp_type_attributes (tree, tree);
+static int ix86_function_regparm (tree, tree);
const struct attribute_spec ix86_attribute_table[];
-static tree ix86_handle_cdecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
-static tree ix86_handle_regparm_attribute PARAMS ((tree *, tree, tree, int, bool *));
-static int ix86_value_regno PARAMS ((enum machine_mode));
-static bool contains_128bit_aligned_vector_p PARAMS ((tree));
+static bool ix86_function_ok_for_sibcall (tree, tree);
+static tree ix86_handle_cdecl_attribute (tree *, tree, tree, int, bool *);
+static tree ix86_handle_regparm_attribute (tree *, tree, tree, int, bool *);
+static int ix86_value_regno (enum machine_mode);
+static bool contains_128bit_aligned_vector_p (tree);
+static bool ix86_ms_bitfield_layout_p (tree);
+static tree ix86_handle_struct_attribute (tree *, tree, tree, int, bool *);
+static int extended_reg_mentioned_1 (rtx *, void *);
+static bool ix86_rtx_costs (rtx, int, int, int *);
+static int min_insn_size (rtx);
+static void k8_avoid_jump_misspredicts (void);
#if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION)
-static void ix86_svr3_asm_out_constructor PARAMS ((rtx, int));
+static void ix86_svr3_asm_out_constructor (rtx, int);
#endif
/* Register class used for passing given 64bit part of the argument.
These represent classes as documented by the PS ABI, with the exception
of SSESF, SSEDF classes, that are basically SSE class, just gcc will
- use SF or DFmode move instead of DImode to avoid reformating penalties.
+ use SF or DFmode move instead of DImode to avoid reformatting penalties.
- Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
+ Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves
whenever possible (upper half does contain padding).
*/
enum x86_64_reg_class
@@ -830,15 +912,18 @@ static const char * const x86_64_reg_class_name[] =
{"no", "integer", "integerSI", "sse", "sseSF", "sseDF", "sseup", "x87", "x87up", "no"};
#define MAX_CLASSES 4
-static int classify_argument PARAMS ((enum machine_mode, tree,
- enum x86_64_reg_class [MAX_CLASSES],
- int));
-static int examine_argument PARAMS ((enum machine_mode, tree, int, int *,
- int *));
-static rtx construct_container PARAMS ((enum machine_mode, tree, int, int, int,
- const int *, int));
-static enum x86_64_reg_class merge_classes PARAMS ((enum x86_64_reg_class,
- enum x86_64_reg_class));
+static int classify_argument (enum machine_mode, tree,
+ enum x86_64_reg_class [MAX_CLASSES], int);
+static int examine_argument (enum machine_mode, tree, int, int *, int *);
+static rtx construct_container (enum machine_mode, tree, int, int, int,
+ const int *, int);
+static enum x86_64_reg_class merge_classes (enum x86_64_reg_class,
+ enum x86_64_reg_class);
+
+/* Table of constants used by fldpi, fldln2, etc.... */
+static REAL_VALUE_TYPE ext_80387_constants_table [5];
+static bool ext_80387_constants_init = 0;
+static void init_ext_80387_constants (void);
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
@@ -898,6 +983,9 @@ static enum x86_64_reg_class merge_classes PARAMS ((enum x86_64_reg_class,
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
ia32_multipass_dfa_lookahead
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL ix86_function_ok_for_sibcall
+
#ifdef HAVE_AS_TLS
#undef TARGET_HAVE_TLS
#define TARGET_HAVE_TLS true
@@ -905,11 +993,36 @@ static enum x86_64_reg_class merge_classes PARAMS ((enum x86_64_reg_class,
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM ix86_cannot_force_const_mem
+#undef TARGET_DELEGITIMIZE_ADDRESS
+#define TARGET_DELEGITIMIZE_ADDRESS ix86_delegitimize_address
+
+#undef TARGET_MS_BITFIELD_LAYOUT_P
+#define TARGET_MS_BITFIELD_LAYOUT_P ix86_ms_bitfield_layout_p
+
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK x86_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK x86_can_output_mi_thunk
+#undef TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START x86_file_start
+
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS ix86_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST ix86_address_cost
+
+#undef TARGET_FIXED_CONDITION_CODE_REGS
+#define TARGET_FIXED_CONDITION_CODE_REGS ix86_fixed_condition_code_regs
+#undef TARGET_CC_MODES_COMPATIBLE
+#define TARGET_CC_MODES_COMPATIBLE ix86_cc_modes_compatible
+
+#undef TARGET_MACHINE_DEPENDENT_REORG
+#define TARGET_MACHINE_DEPENDENT_REORG ix86_reorg
+
+#undef TARGET_BUILD_BUILTIN_VA_LIST
+#define TARGET_BUILD_BUILTIN_VA_LIST ix86_build_builtin_va_list
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* The svr4 ABI for the i386 says that records and unions are returned
@@ -928,7 +1041,7 @@ struct gcc_target targetm = TARGET_INITIALIZER;
`-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
void
-override_options ()
+override_options (void)
{
int i;
/* Comes from final.c -- no real reason to change it. */
@@ -944,17 +1057,17 @@ override_options ()
const int align_jump;
const int align_jump_max_skip;
const int align_func;
- const int branch_cost;
}
const processor_target_table[PROCESSOR_max] =
{
- {&i386_cost, 0, 0, 4, 3, 4, 3, 4, 1},
- {&i486_cost, 0, 0, 16, 15, 16, 15, 16, 1},
- {&pentium_cost, 0, 0, 16, 7, 16, 7, 16, 1},
- {&pentiumpro_cost, 0, 0, 16, 15, 16, 7, 16, 1},
- {&k6_cost, 0, 0, 32, 7, 32, 7, 32, 1},
- {&athlon_cost, 0, 0, 16, 7, 64, 7, 16, 1},
- {&pentium4_cost, 0, 0, 0, 0, 0, 0, 0, 1}
+ {&i386_cost, 0, 0, 4, 3, 4, 3, 4},
+ {&i486_cost, 0, 0, 16, 15, 16, 15, 16},
+ {&pentium_cost, 0, 0, 16, 7, 16, 7, 16},
+ {&pentiumpro_cost, 0, 0, 16, 15, 16, 7, 16},
+ {&k6_cost, 0, 0, 32, 7, 32, 7, 32},
+ {&athlon_cost, 0, 0, 16, 7, 16, 7, 16},
+ {&pentium4_cost, 0, 0, 0, 0, 0, 0, 0},
+ {&k8_cost, 0, 0, 16, 7, 16, 7, 16}
};
static const char * const cpu_names[] = TARGET_CPU_DEFAULT_NAMES;
@@ -966,10 +1079,12 @@ override_options ()
{
PTA_SSE = 1,
PTA_SSE2 = 2,
- PTA_MMX = 4,
- PTA_PREFETCH_SSE = 8,
- PTA_3DNOW = 16,
- PTA_3DNOW_A = 64
+ PTA_SSE3 = 4,
+ PTA_MMX = 8,
+ PTA_PREFETCH_SSE = 16,
+ PTA_3DNOW = 32,
+ PTA_3DNOW_A = 64,
+ PTA_64BIT = 128
} flags;
}
const processor_alias_table[] =
@@ -982,12 +1097,21 @@ override_options ()
{"winchip-c6", PROCESSOR_I486, PTA_MMX},
{"winchip2", PROCESSOR_I486, PTA_MMX | PTA_3DNOW},
{"c3", PROCESSOR_I486, PTA_MMX | PTA_3DNOW},
+ {"c3-2", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_PREFETCH_SSE | PTA_SSE},
{"i686", PROCESSOR_PENTIUMPRO, 0},
{"pentiumpro", PROCESSOR_PENTIUMPRO, 0},
{"pentium2", PROCESSOR_PENTIUMPRO, PTA_MMX},
{"pentium3", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_SSE | PTA_PREFETCH_SSE},
- {"pentium4", PROCESSOR_PENTIUM4, PTA_SSE | PTA_SSE2 |
- PTA_MMX | PTA_PREFETCH_SSE},
+ {"pentium3m", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_SSE | PTA_PREFETCH_SSE},
+ {"pentium-m", PROCESSOR_PENTIUMPRO, PTA_MMX | PTA_SSE | PTA_PREFETCH_SSE | PTA_SSE2},
+ {"pentium4", PROCESSOR_PENTIUM4, PTA_SSE | PTA_SSE2
+ | PTA_MMX | PTA_PREFETCH_SSE},
+ {"pentium4m", PROCESSOR_PENTIUM4, PTA_SSE | PTA_SSE2
+ | PTA_MMX | PTA_PREFETCH_SSE},
+ {"prescott", PROCESSOR_PENTIUM4, PTA_SSE | PTA_SSE2 | PTA_SSE3
+ | PTA_MMX | PTA_PREFETCH_SSE},
+ {"nocona", PROCESSOR_PENTIUM4, PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_64BIT
+ | PTA_MMX | PTA_PREFETCH_SSE},
{"k6", PROCESSOR_K6, PTA_MMX},
{"k6-2", PROCESSOR_K6, PTA_MMX | PTA_3DNOW},
{"k6-3", PROCESSOR_K6, PTA_MMX | PTA_3DNOW},
@@ -1001,17 +1125,22 @@ override_options ()
| PTA_3DNOW_A | PTA_SSE},
{"athlon-mp", PROCESSOR_ATHLON, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW
| PTA_3DNOW_A | PTA_SSE},
+ {"x86-64", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_64BIT
+ | PTA_SSE | PTA_SSE2 },
+ {"k8", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW | PTA_64BIT
+ | PTA_3DNOW_A | PTA_SSE | PTA_SSE2},
+ {"opteron", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW | PTA_64BIT
+ | PTA_3DNOW_A | PTA_SSE | PTA_SSE2},
+ {"athlon64", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW | PTA_64BIT
+ | PTA_3DNOW_A | PTA_SSE | PTA_SSE2},
+ {"athlon-fx", PROCESSOR_K8, PTA_MMX | PTA_PREFETCH_SSE | PTA_3DNOW | PTA_64BIT
+ | PTA_3DNOW_A | PTA_SSE | PTA_SSE2},
};
int const pta_size = ARRAY_SIZE (processor_alias_table);
- /* By default our XFmode is the 80-bit extended format. If we have
- use TFmode instead, it's also the 80-bit format, but with padding. */
- real_format_for_mode[XFmode - QFmode] = &ieee_extended_intel_96_format;
- real_format_for_mode[TFmode - QFmode] = &ieee_extended_intel_128_format;
-
/* Set the default values for switches whose default depends on TARGET_64BIT
- in case they weren't overwriten by command line options. */
+ in case they weren't overwritten by command line options. */
if (TARGET_64BIT)
{
if (flag_omit_frame_pointer == 2)
@@ -1035,12 +1164,12 @@ override_options ()
SUBTARGET_OVERRIDE_OPTIONS;
#endif
- if (!ix86_cpu_string && ix86_arch_string)
- ix86_cpu_string = ix86_arch_string;
- if (!ix86_cpu_string)
- ix86_cpu_string = cpu_names [TARGET_CPU_DEFAULT];
+ if (!ix86_tune_string && ix86_arch_string)
+ ix86_tune_string = ix86_arch_string;
+ if (!ix86_tune_string)
+ ix86_tune_string = cpu_names [TARGET_CPU_DEFAULT];
if (!ix86_arch_string)
- ix86_arch_string = TARGET_64BIT ? "athlon-4" : "i386";
+ ix86_arch_string = TARGET_64BIT ? "x86-64" : "i386";
if (ix86_cmodel_string != 0)
{
@@ -1088,7 +1217,7 @@ override_options ()
{
ix86_arch = processor_alias_table[i].processor;
/* Default cpu tuning to the architecture. */
- ix86_cpu = ix86_arch;
+ ix86_tune = ix86_arch;
if (processor_alias_table[i].flags & PTA_MMX
&& !(target_flags_explicit & MASK_MMX))
target_flags |= MASK_MMX;
@@ -1104,8 +1233,13 @@ override_options ()
if (processor_alias_table[i].flags & PTA_SSE2
&& !(target_flags_explicit & MASK_SSE2))
target_flags |= MASK_SSE2;
+ if (processor_alias_table[i].flags & PTA_SSE3
+ && !(target_flags_explicit & MASK_SSE3))
+ target_flags |= MASK_SSE3;
if (processor_alias_table[i].flags & PTA_PREFETCH_SSE)
x86_prefetch_sse = true;
+ if (TARGET_64BIT && !(processor_alias_table[i].flags & PTA_64BIT))
+ error ("CPU you selected does not support x86-64 instruction set");
break;
}
@@ -1113,22 +1247,30 @@ override_options ()
error ("bad value (%s) for -march= switch", ix86_arch_string);
for (i = 0; i < pta_size; i++)
- if (! strcmp (ix86_cpu_string, processor_alias_table[i].name))
+ if (! strcmp (ix86_tune_string, processor_alias_table[i].name))
{
- ix86_cpu = processor_alias_table[i].processor;
+ ix86_tune = processor_alias_table[i].processor;
+ if (TARGET_64BIT && !(processor_alias_table[i].flags & PTA_64BIT))
+ error ("CPU you selected does not support x86-64 instruction set");
+
+ /* Intel CPUs have always interpreted SSE prefetch instructions as
+ NOPs; so, we can enable SSE prefetch instructions even when
+ -mtune (rather than -march) points us to a processor that has them.
+ However, the VIA C3 gives a SIGILL, so we only do that for i686 and
+ higher processors. */
+ if (TARGET_CMOVE && (processor_alias_table[i].flags & PTA_PREFETCH_SSE))
+ x86_prefetch_sse = true;
break;
}
- if (processor_alias_table[i].flags & PTA_PREFETCH_SSE)
- x86_prefetch_sse = true;
if (i == pta_size)
- error ("bad value (%s) for -mcpu= switch", ix86_cpu_string);
+ error ("bad value (%s) for -mtune= switch", ix86_tune_string);
if (optimize_size)
ix86_cost = &size_cost;
else
- ix86_cost = processor_target_table[ix86_cpu].cost;
- target_flags |= processor_target_table[ix86_cpu].target_enable;
- target_flags &= ~processor_target_table[ix86_cpu].target_disable;
+ ix86_cost = processor_target_table[ix86_tune].cost;
+ target_flags |= processor_target_table[ix86_tune].target_enable;
+ target_flags &= ~processor_target_table[ix86_tune].target_disable;
/* Arrange to set up i386_stack_locals for all functions. */
init_machine_status = ix86_init_machine_status;
@@ -1191,17 +1333,17 @@ override_options ()
/* Default align_* from the processor table. */
if (align_loops == 0)
{
- align_loops = processor_target_table[ix86_cpu].align_loop;
- align_loops_max_skip = processor_target_table[ix86_cpu].align_loop_max_skip;
+ align_loops = processor_target_table[ix86_tune].align_loop;
+ align_loops_max_skip = processor_target_table[ix86_tune].align_loop_max_skip;
}
if (align_jumps == 0)
{
- align_jumps = processor_target_table[ix86_cpu].align_jump;
- align_jumps_max_skip = processor_target_table[ix86_cpu].align_jump_max_skip;
+ align_jumps = processor_target_table[ix86_tune].align_jump;
+ align_jumps_max_skip = processor_target_table[ix86_tune].align_jump_max_skip;
}
if (align_functions == 0)
{
- align_functions = processor_target_table[ix86_cpu].align_func;
+ align_functions = processor_target_table[ix86_tune].align_func;
}
/* Validate -mpreferred-stack-boundary= value, or provide default.
@@ -1222,7 +1364,7 @@ override_options ()
}
/* Validate -mbranch-cost= value, or provide default. */
- ix86_branch_cost = processor_target_table[ix86_cpu].branch_cost;
+ ix86_branch_cost = processor_target_table[ix86_tune].cost->branch_cost;
if (ix86_branch_cost_string)
{
i = atoi (ix86_branch_cost_string);
@@ -1257,8 +1399,8 @@ override_options ()
if (x86_arch_always_fancy_math_387 & (1 << ix86_arch))
target_flags &= ~MASK_NO_FANCY_MATH_387;
- /* Turn on SSE2 builtins for -mpni. */
- if (TARGET_PNI)
+ /* Turn on SSE2 builtins for -msse3. */
+ if (TARGET_SSE3)
target_flags |= MASK_SSE2;
/* Turn on SSE builtins for -msse2. */
@@ -1276,7 +1418,13 @@ override_options ()
ix86_fpmath = FPMATH_SSE;
}
else
- ix86_fpmath = FPMATH_387;
+ {
+ ix86_fpmath = FPMATH_387;
+ /* i386 ABI does not specify red zone. It still makes sense to use it
+ when programmer takes care to stack from being destroyed. */
+ if (!(target_flags_explicit & MASK_NO_RED_ZONE))
+ target_flags |= MASK_NO_RED_ZONE;
+ }
if (ix86_fpmath_string != 0)
{
@@ -1324,12 +1472,12 @@ override_options ()
if (TARGET_3DNOW)
{
target_flags |= MASK_MMX;
- /* If we are targetting the Athlon architecture, enable the 3Dnow/MMX
+ /* If we are targeting the Athlon architecture, enable the 3Dnow/MMX
extensions it adds. */
if (x86_3dnow_a & (1 << ix86_arch))
target_flags |= MASK_3DNOW_A;
}
- if ((x86_accumulate_outgoing_args & CPUMASK)
+ if ((x86_accumulate_outgoing_args & TUNEMASK)
&& !(target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS)
&& !optimize_size)
target_flags |= MASK_ACCUMULATE_OUTGOING_ARGS;
@@ -1345,9 +1493,7 @@ override_options ()
}
void
-optimization_options (level, size)
- int level;
- int size ATTRIBUTE_UNUSED;
+optimization_options (int level, int size ATTRIBUTE_UNUSED)
{
/* For -O2 and beyond, turn off -fschedule-insns by default. It tends to
make the problem with not enough registers even worse. */
@@ -1373,6 +1519,9 @@ const struct attribute_spec ix86_attribute_table[] =
/* Stdcall attribute says callee is responsible for popping arguments
if they are not variable. */
{ "stdcall", 0, 0, false, true, true, ix86_handle_cdecl_attribute },
+ /* Fastcall attribute says callee is responsible for popping arguments
+ if they are not variable. */
+ { "fastcall", 0, 0, false, true, true, ix86_handle_cdecl_attribute },
/* Cdecl attribute says the callee is a normal C declaration */
{ "cdecl", 0, 0, false, true, true, ix86_handle_cdecl_attribute },
/* Regparm attribute specifies how many integer arguments are to be
@@ -1383,18 +1532,63 @@ const struct attribute_spec ix86_attribute_table[] =
{ "dllexport", 0, 0, false, false, false, ix86_handle_dll_attribute },
{ "shared", 0, 0, true, false, false, ix86_handle_shared_attribute },
#endif
+ { "ms_struct", 0, 0, false, false, false, ix86_handle_struct_attribute },
+ { "gcc_struct", 0, 0, false, false, false, ix86_handle_struct_attribute },
{ NULL, 0, 0, false, false, false, NULL }
};
-/* Handle a "cdecl" or "stdcall" attribute;
+/* Decide whether we can make a sibling call to a function. DECL is the
+ declaration of the function being targeted by the call and EXP is the
+ CALL_EXPR representing the call. */
+
+static bool
+ix86_function_ok_for_sibcall (tree decl, tree exp)
+{
+ /* If we are generating position-independent code, we cannot sibcall
+ optimize any indirect call, or a direct call to a global function,
+ as the PLT requires %ebx be live. */
+ if (!TARGET_64BIT && flag_pic && (!decl || TREE_PUBLIC (decl)))
+ return false;
+
+ /* If we are returning floats on the 80387 register stack, we cannot
+ make a sibcall from a function that doesn't return a float to a
+ function that does or, conversely, from a function that does return
+ a float to a function that doesn't; the necessary stack adjustment
+ would not be executed. */
+ if (STACK_REG_P (ix86_function_value (TREE_TYPE (exp)))
+ != STACK_REG_P (ix86_function_value (TREE_TYPE (DECL_RESULT (cfun->decl)))))
+ return false;
+
+ /* If this call is indirect, we'll need to be able to use a call-clobbered
+ register for the address of the target function. Make sure that all
+ such registers are not used for passing parameters. */
+ if (!decl && !TARGET_64BIT)
+ {
+ tree type;
+
+ /* We're looking at the CALL_EXPR, we need the type of the function. */
+ type = TREE_OPERAND (exp, 0); /* pointer expression */
+ type = TREE_TYPE (type); /* pointer type */
+ type = TREE_TYPE (type); /* function type */
+
+ if (ix86_function_regparm (type, NULL) >= 3)
+ {
+ /* ??? Need to count the actual number of registers to be used,
+ not the possible number of registers. Fix later. */
+ return false;
+ }
+ }
+
+ /* Otherwise okay. That also includes certain types of indirect calls. */
+ return true;
+}
+
+/* Handle a "cdecl", "stdcall", or "fastcall" attribute;
arguments as in struct attribute_spec.handler. */
static tree
-ix86_handle_cdecl_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+ix86_handle_cdecl_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) != FUNCTION_TYPE
&& TREE_CODE (*node) != METHOD_TYPE
@@ -1405,6 +1599,27 @@ ix86_handle_cdecl_attribute (node, name, args, flags, no_add_attrs)
IDENTIFIER_POINTER (name));
*no_add_attrs = true;
}
+ else
+ {
+ if (is_attribute_p ("fastcall", name))
+ {
+ if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))
+ {
+ error ("fastcall and stdcall attributes are not compatible");
+ }
+ else if (lookup_attribute ("regparm", TYPE_ATTRIBUTES (*node)))
+ {
+ error ("fastcall and regparm attributes are not compatible");
+ }
+ }
+ else if (is_attribute_p ("stdcall", name))
+ {
+ if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
+ {
+ error ("fastcall and stdcall attributes are not compatible");
+ }
+ }
+ }
if (TARGET_64BIT)
{
@@ -1418,12 +1633,8 @@ ix86_handle_cdecl_attribute (node, name, args, flags, no_add_attrs)
/* Handle a "regparm" attribute;
arguments as in struct attribute_spec.handler. */
static tree
-ix86_handle_regparm_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+ix86_handle_regparm_attribute (tree *node, tree name, tree args,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) != FUNCTION_TYPE
&& TREE_CODE (*node) != METHOD_TYPE
@@ -1451,6 +1662,11 @@ ix86_handle_regparm_attribute (node, name, args, flags, no_add_attrs)
IDENTIFIER_POINTER (name), REGPARM_MAX);
*no_add_attrs = true;
}
+
+ if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (*node)))
+ {
+ error ("fastcall and regparm attributes are not compatible");
+ }
}
return NULL_TREE;
@@ -1461,9 +1677,7 @@ ix86_handle_regparm_attribute (node, name, args, flags, no_add_attrs)
warning to be generated). */
static int
-ix86_comp_type_attributes (type1, type2)
- tree type1;
- tree type2;
+ix86_comp_type_attributes (tree type1, tree type2)
{
/* Check for mismatch of non-default calling convention. */
const char *const rtdstr = TARGET_RTD ? "cdecl" : "stdcall";
@@ -1471,26 +1685,80 @@ ix86_comp_type_attributes (type1, type2)
if (TREE_CODE (type1) != FUNCTION_TYPE)
return 1;
+ /* Check for mismatched fastcall types */
+ if (!lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type1))
+ != !lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type2)))
+ return 0;
+
/* Check for mismatched return types (cdecl vs stdcall). */
if (!lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type1))
!= !lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type2)))
return 0;
+ if (ix86_function_regparm (type1, NULL)
+ != ix86_function_regparm (type2, NULL))
+ return 0;
return 1;
}
-/* Return the regparm value for a fuctio with the indicated TYPE. */
+/* Return the regparm value for a fuctio with the indicated TYPE and DECL.
+ DECL may be NULL when calling function indirectly
+ or considering a libcall. */
static int
-ix86_fntype_regparm (type)
- tree type;
+ix86_function_regparm (tree type, tree decl)
{
tree attr;
+ int regparm = ix86_regparm;
+ bool user_convention = false;
- attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
- if (attr)
- return TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
- else
- return ix86_regparm;
+ if (!TARGET_64BIT)
+ {
+ attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (type));
+ if (attr)
+ {
+ regparm = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
+ user_convention = true;
+ }
+
+ if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
+ {
+ regparm = 2;
+ user_convention = true;
+ }
+
+ /* Use register calling convention for local functions when possible. */
+ if (!TARGET_64BIT && !user_convention && decl
+ && flag_unit_at_a_time && !profile_flag)
+ {
+ struct cgraph_local_info *i = cgraph_local_info (decl);
+ if (i && i->local)
+ {
+ /* We can't use regparm(3) for nested functions as these use
+ static chain pointer in third argument. */
+ if (DECL_CONTEXT (decl) && !DECL_NO_STATIC_CHAIN (decl))
+ regparm = 2;
+ else
+ regparm = 3;
+ }
+ }
+ }
+ return regparm;
+}
+
+/* Return true if EAX is live at the start of the function. Used by
+ ix86_expand_prologue to determine if we need special help before
+ calling allocate_stack_worker. */
+
+static bool
+ix86_eax_live_at_start_p (void)
+{
+ /* Cheat. Don't bother working forward from ix86_function_regparm
+ to the function type to whether an actual argument is located in
+ eax. Instead just look at cfg info, which is still close enough
+ to correct at this point. This gives false positives for broken
+ functions that might use uninitialized data that happens to be
+ allocated in eax, but who cares? */
+ return REGNO_REG_SET_P (ENTRY_BLOCK_PTR->global_live_at_end, 0);
}
/* Value is the number of bytes of arguments automatically
@@ -1511,18 +1779,17 @@ ix86_fntype_regparm (type)
The attribute stdcall is equivalent to RTD on a per module basis. */
int
-ix86_return_pops_args (fundecl, funtype, size)
- tree fundecl;
- tree funtype;
- int size;
+ix86_return_pops_args (tree fundecl, tree funtype, int size)
{
int rtd = TARGET_RTD && (!fundecl || TREE_CODE (fundecl) != IDENTIFIER_NODE);
- /* Cdecl functions override -mrtd, and never pop the stack. */
+ /* Cdecl functions override -mrtd, and never pop the stack. */
if (! lookup_attribute ("cdecl", TYPE_ATTRIBUTES (funtype))) {
- /* Stdcall functions will pop the stack if not variable args. */
- if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype)))
+ /* Stdcall and fastcall functions will pop the stack if not
+ variable args. */
+ if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (funtype))
+ || lookup_attribute ("fastcall", TYPE_ATTRIBUTES (funtype)))
rtd = 1;
if (rtd
@@ -1533,10 +1800,10 @@ ix86_return_pops_args (fundecl, funtype, size)
}
/* Lose any fake structure return argument if it is passed on the stack. */
- if (aggregate_value_p (TREE_TYPE (funtype))
+ if (aggregate_value_p (TREE_TYPE (funtype), fundecl)
&& !TARGET_64BIT)
{
- int nregs = ix86_fntype_regparm (funtype);
+ int nregs = ix86_function_regparm (funtype, fundecl);
if (!nregs)
return GET_MODE_SIZE (Pmode);
@@ -1549,8 +1816,7 @@ ix86_return_pops_args (fundecl, funtype, size)
/* Return true when register may be used to pass function parameters. */
bool
-ix86_function_arg_regno_p (regno)
- int regno;
+ix86_function_arg_regno_p (int regno)
{
int i;
if (!TARGET_64BIT)
@@ -1572,10 +1838,10 @@ ix86_function_arg_regno_p (regno)
For a library call, FNTYPE is 0. */
void
-init_cumulative_args (cum, fntype, libname)
- CUMULATIVE_ARGS *cum; /* Argument info to initialize */
- tree fntype; /* tree ptr for function decl */
- rtx libname; /* SYMBOL_REF of library name or 0 */
+init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
+ tree fntype, /* tree ptr for function decl */
+ rtx libname, /* SYMBOL_REF of library name or 0 */
+ tree fndecl)
{
static CUMULATIVE_ARGS zero_cum;
tree param, next_param;
@@ -1597,23 +1863,33 @@ init_cumulative_args (cum, fntype, libname)
*cum = zero_cum;
/* Set up the number of registers to use for passing arguments. */
- cum->nregs = ix86_regparm;
+ if (fntype)
+ cum->nregs = ix86_function_regparm (fntype, fndecl);
+ else
+ cum->nregs = ix86_regparm;
cum->sse_nregs = SSE_REGPARM_MAX;
+ cum->mmx_nregs = MMX_REGPARM_MAX;
+ cum->warn_sse = true;
+ cum->warn_mmx = true;
+ cum->maybe_vaarg = false;
+
+ /* Use ecx and edx registers if function has fastcall attribute */
if (fntype && !TARGET_64BIT)
{
- tree attr = lookup_attribute ("regparm", TYPE_ATTRIBUTES (fntype));
-
- if (attr)
- cum->nregs = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr)));
+ if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (fntype)))
+ {
+ cum->nregs = 2;
+ cum->fastcall = 1;
+ }
}
- cum->maybe_vaarg = false;
+
/* Determine if this function has variable arguments. This is
indicated by the last argument being 'void_type_mode' if there
are no variable arguments. If there are variable arguments, then
we won't pass anything in registers */
- if (cum->nregs)
+ if (cum->nregs || !TARGET_MMX || !TARGET_SSE)
{
for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
param != 0; param = next_param)
@@ -1622,7 +1898,14 @@ init_cumulative_args (cum, fntype, libname)
if (next_param == 0 && TREE_VALUE (param) != void_type_node)
{
if (!TARGET_64BIT)
- cum->nregs = 0;
+ {
+ cum->nregs = 0;
+ cum->sse_nregs = 0;
+ cum->mmx_nregs = 0;
+ cum->warn_sse = 0;
+ cum->warn_mmx = 0;
+ cum->fastcall = 0;
+ }
cum->maybe_vaarg = true;
}
}
@@ -1637,7 +1920,7 @@ init_cumulative_args (cum, fntype, libname)
return;
}
-/* x86-64 register passing impleemntation. See x86-64 ABI for details. Goal
+/* x86-64 register passing implementation. See x86-64 ABI for details. Goal
of this code is to classify each 8bytes of incoming argument by the register
class and assign registers accordingly. */
@@ -1645,8 +1928,7 @@ init_cumulative_args (cum, fntype, libname)
See the x86-64 PS ABI for details. */
static enum x86_64_reg_class
-merge_classes (class1, class2)
- enum x86_64_reg_class class1, class2;
+merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
{
/* Rule #1: If both classes are equal, this is the resulting class. */
if (class1 == class2)
@@ -1693,13 +1975,10 @@ merge_classes (class1, class2)
*/
static int
-classify_argument (mode, type, classes, bit_offset)
- enum machine_mode mode;
- tree type;
- enum x86_64_reg_class classes[MAX_CLASSES];
- int bit_offset;
+classify_argument (enum machine_mode mode, tree type,
+ enum x86_64_reg_class classes[MAX_CLASSES], int bit_offset)
{
- int bytes =
+ HOST_WIDE_INT bytes =
(mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
int words = (bytes + (bit_offset % 64) / 8 + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
@@ -1707,6 +1986,10 @@ classify_argument (mode, type, classes, bit_offset)
if (bytes < 0)
return 0;
+ if (mode != VOIDmode
+ && MUST_PASS_IN_STACK (mode, type))
+ return 0;
+
if (type && AGGREGATE_TYPE_P (type))
{
int i;
@@ -1758,7 +2041,7 @@ classify_argument (mode, type, classes, bit_offset)
}
}
}
- /* And now merge the fields of structure. */
+ /* And now merge the fields of structure. */
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{
if (TREE_CODE (field) == FIELD_DECL)
@@ -1773,7 +2056,7 @@ classify_argument (mode, type, classes, bit_offset)
for (i = int_bit_position (field) / 8 / 8;
i < (int_bit_position (field)
+ tree_low_cst (DECL_SIZE (field), 0)
- + 63) / 8 / 8; i++)
+ + 63) / 8 / 8; i++)
classes[i] =
merge_classes (X86_64_INTEGER_CLASS,
classes[i]);
@@ -1861,6 +2144,31 @@ classify_argument (mode, type, classes, bit_offset)
}
}
}
+ else if (TREE_CODE (type) == SET_TYPE)
+ {
+ if (bytes <= 4)
+ {
+ classes[0] = X86_64_INTEGERSI_CLASS;
+ return 1;
+ }
+ else if (bytes <= 8)
+ {
+ classes[0] = X86_64_INTEGER_CLASS;
+ return 1;
+ }
+ else if (bytes <= 12)
+ {
+ classes[0] = X86_64_INTEGER_CLASS;
+ classes[1] = X86_64_INTEGERSI_CLASS;
+ return 2;
+ }
+ else
+ {
+ classes[0] = X86_64_INTEGER_CLASS;
+ classes[1] = X86_64_INTEGER_CLASS;
+ return 2;
+ }
+ }
else
abort ();
@@ -1896,6 +2204,8 @@ classify_argument (mode, type, classes, bit_offset)
mode_alignment = 128;
else if (mode == XCmode)
mode_alignment = 256;
+ if (COMPLEX_MODE_P (mode))
+ mode_alignment /= 2;
/* Misaligned fields are always returned in memory. */
if (bit_offset % mode_alignment)
return 0;
@@ -1933,11 +2243,14 @@ classify_argument (mode, type, classes, bit_offset)
case DFmode:
classes[0] = X86_64_SSEDF_CLASS;
return 1;
- case TFmode:
+ case XFmode:
classes[0] = X86_64_X87_CLASS;
classes[1] = X86_64_X87UP_CLASS;
return 2;
+ case TFmode:
case TCmode:
+ return 0;
+ case XCmode:
classes[0] = X86_64_X87_CLASS;
classes[1] = X86_64_X87UP_CLASS;
classes[2] = X86_64_X87_CLASS;
@@ -1975,11 +2288,8 @@ classify_argument (mode, type, classes, bit_offset)
/* Examine the argument and return set number of register required in each
class. Return 0 iff parameter should be passed in memory. */
static int
-examine_argument (mode, type, in_return, int_nregs, sse_nregs)
- enum machine_mode mode;
- tree type;
- int *int_nregs, *sse_nregs;
- int in_return;
+examine_argument (enum machine_mode mode, tree type, int in_return,
+ int *int_nregs, int *sse_nregs)
{
enum x86_64_reg_class class[MAX_CLASSES];
int n = classify_argument (mode, type, class, 0);
@@ -2016,13 +2326,9 @@ examine_argument (mode, type, in_return, int_nregs, sse_nregs)
/* Construct container for the argument used by GCC interface. See
FUNCTION_ARG for the detailed description. */
static rtx
-construct_container (mode, type, in_return, nintregs, nsseregs, intreg, sse_regno)
- enum machine_mode mode;
- tree type;
- int in_return;
- int nintregs, nsseregs;
- const int * intreg;
- int sse_regno;
+construct_container (enum machine_mode mode, tree type, int in_return,
+ int nintregs, int nsseregs, const int * intreg,
+ int sse_regno)
{
enum machine_mode tmpmode;
int bytes =
@@ -2077,20 +2383,22 @@ construct_container (mode, type, in_return, nintregs, nsseregs, intreg, sse_regn
default:
abort ();
}
- if (n == 2 && class[0] == X86_64_SSE_CLASS && class[1] == X86_64_SSEUP_CLASS)
+ if (n == 2 && class[0] == X86_64_SSE_CLASS && class[1] == X86_64_SSEUP_CLASS
+ && mode != BLKmode)
return gen_rtx_REG (mode, SSE_REGNO (sse_regno));
if (n == 2
&& class[0] == X86_64_X87_CLASS && class[1] == X86_64_X87UP_CLASS)
- return gen_rtx_REG (TFmode, FIRST_STACK_REG);
+ return gen_rtx_REG (XFmode, FIRST_STACK_REG);
if (n == 2 && class[0] == X86_64_INTEGER_CLASS
&& class[1] == X86_64_INTEGER_CLASS
- && (mode == CDImode || mode == TImode)
+ && (mode == CDImode || mode == TImode || mode == TFmode)
&& intreg[0] + 1 == intreg[1])
return gen_rtx_REG (mode, intreg[0]);
if (n == 4
&& class[0] == X86_64_X87_CLASS && class[1] == X86_64_X87UP_CLASS
- && class[2] == X86_64_X87_CLASS && class[3] == X86_64_X87UP_CLASS)
- return gen_rtx_REG (TCmode, FIRST_STACK_REG);
+ && class[2] == X86_64_X87_CLASS && class[3] == X86_64_X87UP_CLASS
+ && mode != BLKmode)
+ return gen_rtx_REG (XCmode, FIRST_STACK_REG);
/* Otherwise figure out the entries of the PARALLEL. */
for (i = 0; i < n; i++)
@@ -2101,7 +2409,7 @@ construct_container (mode, type, in_return, nintregs, nsseregs, intreg, sse_regn
break;
case X86_64_INTEGER_CLASS:
case X86_64_INTEGERSI_CLASS:
- /* Merge TImodes on aligned occassions here too. */
+ /* Merge TImodes on aligned occasions here too. */
if (i * 8 + 8 > bytes)
tmpmode = mode_for_size ((bytes - i * 8) * BITS_PER_UNIT, MODE_INT, 0);
else if (class[i] == X86_64_INTEGERSI_CLASS)
@@ -2158,11 +2466,10 @@ construct_container (mode, type, in_return, nintregs, nsseregs, intreg, sse_regn
(TYPE is null for libcalls where that information may not be available.) */
void
-function_arg_advance (cum, mode, type, named)
- CUMULATIVE_ARGS *cum; /* current arg information */
- enum machine_mode mode; /* current arg mode */
- tree type; /* type of the argument or 0 if lib support */
- int named; /* whether or not the argument was named */
+function_arg_advance (CUMULATIVE_ARGS *cum, /* current arg information */
+ enum machine_mode mode, /* current arg mode */
+ tree type, /* type of the argument or 0 if lib support */
+ int named) /* whether or not the argument was named */
{
int bytes =
(mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
@@ -2170,8 +2477,8 @@ function_arg_advance (cum, mode, type, named)
if (TARGET_DEBUG_ARG)
fprintf (stderr,
- "function_adv (sz=%d, wds=%2d, nregs=%d, mode=%s, named=%d)\n\n",
- words, cum->words, cum->nregs, GET_MODE_NAME (mode), named);
+ "function_adv (sz=%d, wds=%2d, nregs=%d, ssenregs=%d, mode=%s, named=%d)\n\n",
+ words, cum->words, cum->nregs, cum->sse_nregs, GET_MODE_NAME (mode), named);
if (TARGET_64BIT)
{
int int_nregs, sse_nregs;
@@ -2189,7 +2496,8 @@ function_arg_advance (cum, mode, type, named)
}
else
{
- if (TARGET_SSE && mode == TImode)
+ if (TARGET_SSE && SSE_REG_MODE_P (mode)
+ && (!type || !AGGREGATE_TYPE_P (type)))
{
cum->sse_words += words;
cum->sse_nregs -= 1;
@@ -2200,6 +2508,18 @@ function_arg_advance (cum, mode, type, named)
cum->sse_regno = 0;
}
}
+ else if (TARGET_MMX && MMX_REG_MODE_P (mode)
+ && (!type || !AGGREGATE_TYPE_P (type)))
+ {
+ cum->mmx_words += words;
+ cum->mmx_nregs -= 1;
+ cum->mmx_regno += 1;
+ if (cum->mmx_nregs <= 0)
+ {
+ cum->mmx_nregs = 0;
+ cum->mmx_regno = 0;
+ }
+ }
else
{
cum->words += words;
@@ -2230,18 +2550,18 @@ function_arg_advance (cum, mode, type, named)
(otherwise it is an extra parameter matching an ellipsis). */
rtx
-function_arg (cum, mode, type, named)
- CUMULATIVE_ARGS *cum; /* current arg information */
- enum machine_mode mode; /* current arg mode */
- tree type; /* type of the argument or 0 if lib support */
- int named; /* != 0 for normal args, == 0 for ... args */
+function_arg (CUMULATIVE_ARGS *cum, /* current arg information */
+ enum machine_mode mode, /* current arg mode */
+ tree type, /* type of the argument or 0 if lib support */
+ int named) /* != 0 for normal args, == 0 for ... args */
{
rtx ret = NULL_RTX;
int bytes =
(mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode);
int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ static bool warnedsse, warnedmmx;
- /* Handle an hidden AL argument containing number of registers for varargs
+ /* Handle a hidden AL argument containing number of registers for varargs
x86-64 functions. For i386 ABI just return constm1_rtx to avoid
any AL settings. */
if (mode == VOIDmode)
@@ -2275,11 +2595,57 @@ function_arg (cum, mode, type, named)
case HImode:
case QImode:
if (words <= cum->nregs)
- ret = gen_rtx_REG (mode, cum->regno);
+ {
+ int regno = cum->regno;
+
+ /* Fastcall allocates the first two DWORD (SImode) or
+ smaller arguments to ECX and EDX. */
+ if (cum->fastcall)
+ {
+ if (mode == BLKmode || mode == DImode)
+ break;
+
+ /* ECX not EAX is the first allocated register. */
+ if (regno == 0)
+ regno = 2;
+ }
+ ret = gen_rtx_REG (mode, regno);
+ }
break;
case TImode:
- if (cum->sse_nregs)
- ret = gen_rtx_REG (mode, cum->sse_regno);
+ case V16QImode:
+ case V8HImode:
+ case V4SImode:
+ case V2DImode:
+ case V4SFmode:
+ case V2DFmode:
+ if (!type || !AGGREGATE_TYPE_P (type))
+ {
+ if (!TARGET_SSE && !warnedmmx && cum->warn_sse)
+ {
+ warnedsse = true;
+ warning ("SSE vector argument without SSE enabled "
+ "changes the ABI");
+ }
+ if (cum->sse_nregs)
+ ret = gen_rtx_REG (mode, cum->sse_regno + FIRST_SSE_REG);
+ }
+ break;
+ case V8QImode:
+ case V4HImode:
+ case V2SImode:
+ case V2SFmode:
+ if (!type || !AGGREGATE_TYPE_P (type))
+ {
+ if (!TARGET_MMX && !warnedmmx && cum->warn_mmx)
+ {
+ warnedmmx = true;
+ warning ("MMX vector argument without MMX enabled "
+ "changes the ABI");
+ }
+ if (cum->mmx_nregs)
+ ret = gen_rtx_REG (mode, cum->mmx_regno + FIRST_MMX_REG);
+ }
break;
}
@@ -2300,11 +2666,34 @@ function_arg (cum, mode, type, named)
return ret;
}
+/* A C expression that indicates when an argument must be passed by
+ reference. If nonzero for an argument, a copy of that argument is
+ made in memory and a pointer to the argument is passed instead of
+ the argument itself. The pointer is passed in whatever way is
+ appropriate for passing a pointer to that type. */
+
+int
+function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type, int named ATTRIBUTE_UNUSED)
+{
+ if (!TARGET_64BIT)
+ return 0;
+
+ if (type && int_size_in_bytes (type) == -1)
+ {
+ if (TARGET_DEBUG_ARG)
+ fprintf (stderr, "function_arg_pass_by_reference\n");
+ return 1;
+ }
+
+ return 0;
+}
+
/* Return true when TYPE should be 128bit aligned for 32bit argument passing
ABI */
static bool
-contains_128bit_aligned_vector_p (type)
- tree type;
+contains_128bit_aligned_vector_p (tree type)
{
enum machine_mode mode = TYPE_MODE (type);
if (SSE_REG_MODE_P (mode)
@@ -2315,7 +2704,7 @@ contains_128bit_aligned_vector_p (type)
if (AGGREGATE_TYPE_P (type))
{
- /* Walk the agregates recursivly. */
+ /* Walk the aggregates recursively. */
if (TREE_CODE (type) == RECORD_TYPE
|| TREE_CODE (type) == UNION_TYPE
|| TREE_CODE (type) == QUAL_UNION_TYPE)
@@ -2338,7 +2727,7 @@ contains_128bit_aligned_vector_p (type)
return true;
}
}
- /* And now merge the fields of structure. */
+ /* And now merge the fields of structure. */
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{
if (TREE_CODE (field) == FIELD_DECL
@@ -2358,39 +2747,11 @@ contains_128bit_aligned_vector_p (type)
return false;
}
-/* A C expression that indicates when an argument must be passed by
- reference. If nonzero for an argument, a copy of that argument is
- made in memory and a pointer to the argument is passed instead of
- the argument itself. The pointer is passed in whatever way is
- appropriate for passing a pointer to that type. */
-
-int
-function_arg_pass_by_reference (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type;
- int named ATTRIBUTE_UNUSED;
-{
- if (!TARGET_64BIT)
- return 0;
-
- if (type && int_size_in_bytes (type) == -1)
- {
- if (TARGET_DEBUG_ARG)
- fprintf (stderr, "function_arg_pass_by_reference\n");
- return 1;
- }
-
- return 0;
-}
-
-/* Gives the alignment boundary, in bits, of an argument with the specified mode
- and type. */
+/* Gives the alignment boundary, in bits, of an argument with the
+ specified mode and type. */
int
-ix86_function_arg_boundary (mode, type)
- enum machine_mode mode;
- tree type;
+ix86_function_arg_boundary (enum machine_mode mode, tree type)
{
int align;
if (type)
@@ -2403,7 +2764,7 @@ ix86_function_arg_boundary (mode, type)
{
/* i386 ABI defines all arguments to be 4 byte aligned. We have to
make an exception for SSE modes since these require 128bit
- alignment.
+ alignment.
The handling here differs from field_alignment. ICC aligns MMX
arguments to 4 byte boundaries, while structure fields are aligned
@@ -2418,8 +2779,6 @@ ix86_function_arg_boundary (mode, type)
if (!contains_128bit_aligned_vector_p (type))
align = PARM_BOUNDARY;
}
- if (align != PARM_BOUNDARY && !TARGET_SSE)
- abort();
}
if (align > 128)
align = 128;
@@ -2428,8 +2787,7 @@ ix86_function_arg_boundary (mode, type)
/* Return true if N is a possible register number of function value. */
bool
-ix86_function_value_regno_p (regno)
- int regno;
+ix86_function_value_regno_p (int regno)
{
if (!TARGET_64BIT)
{
@@ -2447,16 +2805,15 @@ ix86_function_value_regno_p (regno)
If the precise function being called is known, FUNC is its FUNCTION_DECL;
otherwise, FUNC is 0. */
rtx
-ix86_function_value (valtype)
- tree valtype;
+ix86_function_value (tree valtype)
{
if (TARGET_64BIT)
{
rtx ret = construct_container (TYPE_MODE (valtype), valtype, 1,
REGPARM_MAX, SSE_REGPARM_MAX,
x86_64_int_return_registers, 0);
- /* For zero sized structures, construct_continer return NULL, but we need
- to keep rest of compiler happy by returning meaningfull value. */
+ /* For zero sized structures, construct_container return NULL, but we need
+ to keep rest of compiler happy by returning meaningful value. */
if (!ret)
ret = gen_rtx_REG (TYPE_MODE (valtype), 0);
return ret;
@@ -2468,8 +2825,7 @@ ix86_function_value (valtype)
/* Return false iff type is returned in memory. */
int
-ix86_return_in_memory (type)
- tree type;
+ix86_return_in_memory (tree type)
{
int needed_intregs, needed_sseregs, size;
enum machine_mode mode = TYPE_MODE (type);
@@ -2482,6 +2838,9 @@ ix86_return_in_memory (type)
size = int_size_in_bytes (type);
+ if (MS_AGGREGATE_RETURN && AGGREGATE_TYPE_P (type) && size <= 8)
+ return 0;
+
if (VECTOR_MODE_P (mode) || mode == TImode)
{
/* User-created vectors small enough to fit in EAX. */
@@ -2498,7 +2857,7 @@ ix86_return_in_memory (type)
either (1) being abi incompatible with a -march switch,
or (2) generating an error here. Given no good solution,
I think the safest thing is one warning. The user won't
- be able to use -Werror, but... */
+ be able to use -Werror, but.... */
if (size == 16)
{
static bool warned;
@@ -2509,14 +2868,16 @@ ix86_return_in_memory (type)
if (!warned)
{
warned = true;
- warning ("SSE vector return without SSE enabled changes the ABI");
+ warning ("SSE vector return without SSE enabled "
+ "changes the ABI");
}
return 1;
}
}
- if (mode == TFmode)
+ if (mode == XFmode)
return 0;
+
if (size > 12)
return 1;
return 0;
@@ -2525,34 +2886,35 @@ ix86_return_in_memory (type)
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
rtx
-ix86_libcall_value (mode)
- enum machine_mode mode;
+ix86_libcall_value (enum machine_mode mode)
{
if (TARGET_64BIT)
{
switch (mode)
{
- case SFmode:
- case SCmode:
- case DFmode:
- case DCmode:
- return gen_rtx_REG (mode, FIRST_SSE_REG);
- case TFmode:
- case TCmode:
- return gen_rtx_REG (mode, FIRST_FLOAT_REG);
- default:
- return gen_rtx_REG (mode, 0);
+ case SFmode:
+ case SCmode:
+ case DFmode:
+ case DCmode:
+ return gen_rtx_REG (mode, FIRST_SSE_REG);
+ case XFmode:
+ case XCmode:
+ return gen_rtx_REG (mode, FIRST_FLOAT_REG);
+ case TFmode:
+ case TCmode:
+ return NULL;
+ default:
+ return gen_rtx_REG (mode, 0);
}
}
else
- return gen_rtx_REG (mode, ix86_value_regno (mode));
+ return gen_rtx_REG (mode, ix86_value_regno (mode));
}
/* Given a mode, return the register to use for a return value. */
static int
-ix86_value_regno (mode)
- enum machine_mode mode;
+ix86_value_regno (enum machine_mode mode)
{
/* Floating point return values in %st(0). */
if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_FLOAT_RETURNS_IN_80387)
@@ -2567,8 +2929,8 @@ ix86_value_regno (mode)
/* Create the va_list data type. */
-tree
-ix86_build_va_list ()
+static tree
+ix86_build_builtin_va_list (void)
{
tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
@@ -2621,13 +2983,9 @@ ix86_build_va_list ()
stack and set PRETEND_SIZE to the length of the registers pushed. */
void
-ix86_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int *pretend_size ATTRIBUTE_UNUSED;
- int no_rtl;
-
+ix86_setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int *pretend_size ATTRIBUTE_UNUSED,
+ int no_rtl)
{
CUMULATIVE_ARGS next_cum;
rtx save_area = NULL_RTX, mem;
@@ -2676,7 +3034,7 @@ ix86_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
if (next_cum.sse_nregs)
{
/* Now emit code to save SSE registers. The AX parameter contains number
- of SSE parameter regsiters used to call this function. We use
+ of SSE parameter registers used to call this function. We use
sse_prologue_save insn template that produces computed jump across
SSE saves. We need some preparation work to get this working. */
@@ -2723,9 +3081,7 @@ ix86_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
/* Implement va_start. */
void
-ix86_va_start (valist, nextarg)
- tree valist;
- rtx nextarg;
+ix86_va_start (tree valist, rtx nextarg)
{
HOST_WIDE_INT words, n_gpr, n_fpr;
tree f_gpr, f_fpr, f_ovf, f_sav;
@@ -2787,8 +3143,7 @@ ix86_va_start (valist, nextarg)
/* Implement va_arg. */
rtx
-ix86_va_arg (valist, type)
- tree valist, type;
+ix86_va_arg (tree valist, tree type)
{
static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
tree f_gpr, f_fpr, f_ovf, f_sav;
@@ -2850,11 +3205,11 @@ ix86_va_arg (valist, type)
need_temp = ((needed_intregs && TYPE_ALIGN (type) > 64)
|| TYPE_ALIGN (type) > 128);
- /* In case we are passing structure, verify that it is consetuctive block
+ /* In case we are passing structure, verify that it is consecutive block
on the register save area. If not we need to do moves. */
if (!need_temp && !REG_P (container))
{
- /* Verify that all registers are strictly consetuctive */
+ /* Verify that all registers are strictly consecutive */
if (SSE_REGNO_P (REGNO (XEXP (XVECEXP (container, 0, 0), 0))))
{
int i;
@@ -3028,37 +3383,29 @@ ix86_va_arg (valist, type)
/* Return nonzero if OP is either a i387 or SSE fp register. */
int
-any_fp_register_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+any_fp_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return ANY_FP_REG_P (op);
}
/* Return nonzero if OP is an i387 fp register. */
int
-fp_register_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+fp_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return FP_REG_P (op);
}
/* Return nonzero if OP is a non-fp register_operand. */
int
-register_and_not_any_fp_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+register_and_not_any_fp_reg_operand (rtx op, enum machine_mode mode)
{
return register_operand (op, mode) && !ANY_FP_REG_P (op);
}
-/* Return nonzero of OP is a register operand other than an
+/* Return nonzero if OP is a register operand other than an
i387 fp register. */
int
-register_and_not_fp_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+register_and_not_fp_reg_operand (rtx op, enum machine_mode mode)
{
return register_operand (op, mode) && !FP_REG_P (op);
}
@@ -3066,9 +3413,7 @@ register_and_not_fp_reg_operand (op, mode)
/* Return nonzero if OP is general operand representable on x86_64. */
int
-x86_64_general_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+x86_64_general_operand (rtx op, enum machine_mode mode)
{
if (!TARGET_64BIT)
return general_operand (op, mode);
@@ -3081,9 +3426,7 @@ x86_64_general_operand (op, mode)
as either sign extended or zero extended constant. */
int
-x86_64_szext_general_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+x86_64_szext_general_operand (rtx op, enum machine_mode mode)
{
if (!TARGET_64BIT)
return general_operand (op, mode);
@@ -3095,9 +3438,7 @@ x86_64_szext_general_operand (op, mode)
/* Return nonzero if OP is nonmemory operand representable on x86_64. */
int
-x86_64_nonmemory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+x86_64_nonmemory_operand (rtx op, enum machine_mode mode)
{
if (!TARGET_64BIT)
return nonmemory_operand (op, mode);
@@ -3109,9 +3450,7 @@ x86_64_nonmemory_operand (op, mode)
/* Return nonzero if OP is nonmemory operand acceptable by movabs patterns. */
int
-x86_64_movabs_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+x86_64_movabs_operand (rtx op, enum machine_mode mode)
{
if (!TARGET_64BIT || !flag_pic)
return nonmemory_operand (op, mode);
@@ -3126,9 +3465,7 @@ x86_64_movabs_operand (op, mode)
in movabs* patterns. */
int
-ix86_check_movabs (insn, opnum)
- rtx insn;
- int opnum;
+ix86_check_movabs (rtx insn, int opnum)
{
rtx set, mem;
@@ -3148,9 +3485,7 @@ ix86_check_movabs (insn, opnum)
/* Return nonzero if OP is nonmemory operand representable on x86_64. */
int
-x86_64_szext_nonmemory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+x86_64_szext_nonmemory_operand (rtx op, enum machine_mode mode)
{
if (!TARGET_64BIT)
return nonmemory_operand (op, mode);
@@ -3162,9 +3497,7 @@ x86_64_szext_nonmemory_operand (op, mode)
/* Return nonzero if OP is immediate operand representable on x86_64. */
int
-x86_64_immediate_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+x86_64_immediate_operand (rtx op, enum machine_mode mode)
{
if (!TARGET_64BIT)
return immediate_operand (op, mode);
@@ -3174,31 +3507,17 @@ x86_64_immediate_operand (op, mode)
/* Return nonzero if OP is immediate operand representable on x86_64. */
int
-x86_64_zext_immediate_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+x86_64_zext_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return x86_64_zero_extended_value (op);
}
-/* Return nonzero if OP is (const_int 1), else return zero. */
-
-int
-const_int_1_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (GET_CODE (op) == CONST_INT && INTVAL (op) == 1);
-}
-
/* Return nonzero if OP is CONST_INT >= 1 and <= 31 (a valid operand
for shift & compare patterns, as shifting by 0 does not change flags),
else return zero. */
int
-const_int_1_31_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+const_int_1_31_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT && INTVAL (op) >= 1 && INTVAL (op) <= 31);
}
@@ -3207,9 +3526,7 @@ const_int_1_31_operand (op, mode)
reference and a constant. */
int
-symbolic_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
@@ -3253,16 +3570,19 @@ symbolic_operand (op, mode)
/* Return true if the operand contains a @GOT or @GOTOFF reference. */
int
-pic_symbolic_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+pic_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST)
return 0;
op = XEXP (op, 0);
if (TARGET_64BIT)
{
- if (GET_CODE (XEXP (op, 0)) == UNSPEC)
+ if (GET_CODE (op) == UNSPEC
+ && XINT (op, 1) == UNSPEC_GOTPCREL)
+ return 1;
+ if (GET_CODE (op) == PLUS
+ && GET_CODE (XEXP (op, 0)) == UNSPEC
+ && XINT (XEXP (op, 0), 1) == UNSPEC_GOTPCREL)
return 1;
}
else
@@ -3282,9 +3602,7 @@ pic_symbolic_operand (op, mode)
/* Return true if OP is a symbolic operand that resolves locally. */
static int
-local_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+local_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == CONST
&& GET_CODE (XEXP (op, 0)) == PLUS
@@ -3297,9 +3615,7 @@ local_symbolic_operand (op, mode)
if (GET_CODE (op) != SYMBOL_REF)
return 0;
- /* These we've been told are local by varasm and encode_section_info
- respectively. */
- if (CONSTANT_POOL_ADDRESS_P (op) || SYMBOL_REF_FLAG (op))
+ if (SYMBOL_REF_LOCAL_P (op))
return 1;
/* There is, however, a not insubstantial body of code in the rest of
@@ -3314,66 +3630,46 @@ local_symbolic_operand (op, mode)
return 0;
}
-/* Test for various thread-local symbols. See ix86_encode_section_info. */
+/* Test for various thread-local symbols. */
int
-tls_symbolic_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+tls_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- const char *symbol_str;
-
if (GET_CODE (op) != SYMBOL_REF)
return 0;
- symbol_str = XSTR (op, 0);
-
- if (symbol_str[0] != '%')
- return 0;
- return strchr (tls_model_chars, symbol_str[1]) - tls_model_chars;
+ return SYMBOL_REF_TLS_MODEL (op);
}
-static int
-tls_symbolic_operand_1 (op, kind)
- rtx op;
- enum tls_model kind;
+static inline int
+tls_symbolic_operand_1 (rtx op, enum tls_model kind)
{
- const char *symbol_str;
-
if (GET_CODE (op) != SYMBOL_REF)
return 0;
- symbol_str = XSTR (op, 0);
-
- return symbol_str[0] == '%' && symbol_str[1] == tls_model_chars[kind];
+ return SYMBOL_REF_TLS_MODEL (op) == kind;
}
int
-global_dynamic_symbolic_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+global_dynamic_symbolic_operand (rtx op,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
return tls_symbolic_operand_1 (op, TLS_MODEL_GLOBAL_DYNAMIC);
}
int
-local_dynamic_symbolic_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+local_dynamic_symbolic_operand (rtx op,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
return tls_symbolic_operand_1 (op, TLS_MODEL_LOCAL_DYNAMIC);
}
int
-initial_exec_symbolic_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+initial_exec_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return tls_symbolic_operand_1 (op, TLS_MODEL_INITIAL_EXEC);
}
int
-local_exec_symbolic_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+local_exec_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return tls_symbolic_operand_1 (op, TLS_MODEL_LOCAL_EXEC);
}
@@ -3383,9 +3679,7 @@ local_exec_symbolic_operand (op, mode)
reg + const, which the patterns can't handle. */
int
-call_insn_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
/* Disallow indirect through a virtual register. This leads to
compiler aborts when trying to eliminate them. */
@@ -3409,10 +3703,32 @@ call_insn_operand (op, mode)
return general_operand (op, Pmode);
}
+/* Test for a valid operand for a call instruction. Don't allow the
+ arg pointer register or virtual regs since they may decay into
+ reg + const, which the patterns can't handle. */
+
+int
+sibcall_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ /* Disallow indirect through a virtual register. This leads to
+ compiler aborts when trying to eliminate them. */
+ if (GET_CODE (op) == REG
+ && (op == arg_pointer_rtx
+ || op == frame_pointer_rtx
+ || (REGNO (op) >= FIRST_PSEUDO_REGISTER
+ && REGNO (op) <= LAST_VIRTUAL_REGISTER)))
+ return 0;
+
+ /* Explicitly allow SYMBOL_REF even if pic. */
+ if (GET_CODE (op) == SYMBOL_REF)
+ return 1;
+
+ /* Otherwise we can only allow register operands. */
+ return register_operand (op, Pmode);
+}
+
int
-constant_call_address_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+constant_call_address_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == CONST
&& GET_CODE (XEXP (op, 0)) == PLUS
@@ -3424,17 +3740,13 @@ constant_call_address_operand (op, mode)
/* Match exactly zero and one. */
int
-const0_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+const0_operand (rtx op, enum machine_mode mode)
{
return op == CONST0_RTX (mode);
}
int
-const1_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+const1_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return op == const1_rtx;
}
@@ -3442,20 +3754,41 @@ const1_operand (op, mode)
/* Match 2, 4, or 8. Used for leal multiplicands. */
int
-const248_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+const248_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& (INTVAL (op) == 2 || INTVAL (op) == 4 || INTVAL (op) == 8));
}
-/* True if this is a constant appropriate for an increment or decremenmt. */
+int
+const_0_to_3_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) < 4);
+}
int
-incdec_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+const_0_to_7_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) < 8);
+}
+
+int
+const_0_to_15_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) < 16);
+}
+
+int
+const_0_to_255_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) < 256);
+}
+
+
+/* True if this is a constant appropriate for an increment or decrement. */
+
+int
+incdec_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
/* On Pentium4, the inc and dec operations causes extra dependency on flag
registers, since carry flag is not set. */
@@ -3468,9 +3801,7 @@ incdec_operand (op, mode)
expander. */
int
-shiftdi_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+shiftdi_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (TARGET_64BIT)
return nonimmediate_operand (op, mode);
@@ -3486,9 +3817,7 @@ shiftdi_operand (op, mode)
Which would only happen in pathological cases. */
int
-reg_no_sp_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+reg_no_sp_operand (rtx op, enum machine_mode mode)
{
rtx t = op;
if (GET_CODE (t) == SUBREG)
@@ -3500,9 +3829,7 @@ reg_no_sp_operand (op, mode)
}
int
-mmx_reg_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mmx_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return MMX_REG_P (op);
}
@@ -3511,9 +3838,7 @@ mmx_reg_operand (op, mode)
general_operand. */
int
-general_no_elim_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+general_no_elim_operand (rtx op, enum machine_mode mode)
{
rtx t = op;
if (GET_CODE (t) == SUBREG)
@@ -3534,9 +3859,7 @@ general_no_elim_operand (op, mode)
register_operand or const_int. */
int
-nonmemory_no_elim_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+nonmemory_no_elim_operand (rtx op, enum machine_mode mode)
{
rtx t = op;
if (GET_CODE (t) == SUBREG)
@@ -3553,9 +3876,7 @@ nonmemory_no_elim_operand (op, mode)
otherwise work like register_operand. */
int
-index_register_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+index_register_operand (rtx op, enum machine_mode mode)
{
rtx t = op;
if (GET_CODE (t) == SUBREG)
@@ -3576,9 +3897,7 @@ index_register_operand (op, mode)
/* Return true if op is a Q_REGS class register. */
int
-q_regs_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+q_regs_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
@@ -3587,12 +3906,20 @@ q_regs_operand (op, mode)
return ANY_QI_REG_P (op);
}
+/* Return true if op is an flags register. */
+
+int
+flags_reg_operand (rtx op, enum machine_mode mode)
+{
+ if (mode != VOIDmode && GET_MODE (op) != mode)
+ return 0;
+ return REG_P (op) && REGNO (op) == FLAGS_REG && GET_MODE (op) != VOIDmode;
+}
+
/* Return true if op is a NON_Q_REGS class register. */
int
-non_q_regs_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+non_q_regs_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
@@ -3601,11 +3928,33 @@ non_q_regs_operand (op, mode)
return NON_QI_REG_P (op);
}
+int
+zero_extended_scalar_load_operand (rtx op,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ unsigned n_elts;
+ if (GET_CODE (op) != MEM)
+ return 0;
+ op = maybe_get_pool_constant (op);
+ if (!op)
+ return 0;
+ if (GET_CODE (op) != CONST_VECTOR)
+ return 0;
+ n_elts =
+ (GET_MODE_SIZE (GET_MODE (op)) /
+ GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (op))));
+ for (n_elts--; n_elts > 0; n_elts--)
+ {
+ rtx elt = CONST_VECTOR_ELT (op, n_elts);
+ if (elt != CONST0_RTX (GET_MODE_INNER (GET_MODE (op))))
+ return 0;
+ }
+ return 1;
+}
+
/* Return 1 when OP is operand acceptable for standard SSE move. */
int
-vector_move_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+vector_move_operand (rtx op, enum machine_mode mode)
{
if (nonimmediate_operand (op, mode))
return 1;
@@ -3614,12 +3963,27 @@ vector_move_operand (op, mode)
return (op == CONST0_RTX (GET_MODE (op)));
}
+/* Return true if op if a valid address, and does not contain
+ a segment override. */
+
+int
+no_seg_address_operand (rtx op, enum machine_mode mode)
+{
+ struct ix86_address parts;
+
+ if (! address_operand (op, mode))
+ return 0;
+
+ if (! ix86_decompose_address (op, &parts))
+ abort ();
+
+ return parts.seg == SEG_DEFAULT;
+}
+
/* Return 1 if OP is a comparison that can be used in the CMPSS/CMPPS
insns. */
int
-sse_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+sse_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
switch (code)
@@ -3648,9 +4012,7 @@ sse_comparison_operator (op, mode)
}
/* Return 1 if OP is a valid comparison operator in valid mode. */
int
-ix86_comparison_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+ix86_comparison_operator (rtx op, enum machine_mode mode)
{
enum machine_mode inmode;
enum rtx_code code = GET_CODE (op);
@@ -3688,15 +4050,46 @@ ix86_comparison_operator (op, mode)
}
}
+/* Return 1 if OP is a valid comparison operator testing carry flag
+ to be set. */
+int
+ix86_carry_flag_operator (rtx op, enum machine_mode mode)
+{
+ enum machine_mode inmode;
+ enum rtx_code code = GET_CODE (op);
+
+ if (mode != VOIDmode && GET_MODE (op) != mode)
+ return 0;
+ if (GET_RTX_CLASS (code) != '<')
+ return 0;
+ inmode = GET_MODE (XEXP (op, 0));
+ if (GET_CODE (XEXP (op, 0)) != REG
+ || REGNO (XEXP (op, 0)) != 17
+ || XEXP (op, 1) != const0_rtx)
+ return 0;
+
+ if (inmode == CCFPmode || inmode == CCFPUmode)
+ {
+ enum rtx_code second_code, bypass_code;
+
+ ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
+ if (bypass_code != NIL || second_code != NIL)
+ return 0;
+ code = ix86_fp_compare_code_to_integer (code);
+ }
+ else if (inmode != CCmode)
+ return 0;
+ return code == LTU;
+}
+
/* Return 1 if OP is a comparison operator that can be issued by fcmov. */
int
-fcmov_comparison_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+fcmov_comparison_operator (rtx op, enum machine_mode mode)
{
enum machine_mode inmode;
enum rtx_code code = GET_CODE (op);
+
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
if (GET_RTX_CLASS (code) != '<')
@@ -3705,6 +4098,7 @@ fcmov_comparison_operator (op, mode)
if (inmode == CCFPmode || inmode == CCFPUmode)
{
enum rtx_code second_code, bypass_code;
+
ix86_fp_comparison_codes (code, &bypass_code, &code, &second_code);
if (bypass_code != NIL || second_code != NIL)
return 0;
@@ -3728,16 +4122,14 @@ fcmov_comparison_operator (op, mode)
/* Return 1 if OP is a binary operator that can be promoted to wider mode. */
int
-promotable_binary_operator (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+promotable_binary_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
case MULT:
/* Modern CPUs have same latency for HImode and SImode multiply,
but 386 and 486 do HImode multiply faster. */
- return ix86_cpu > PROCESSOR_I486;
+ return ix86_tune > PROCESSOR_I486;
case PLUS:
case AND:
case IOR:
@@ -3754,9 +4146,7 @@ promotable_binary_operator (op, mode)
into registers. */
int
-cmp_fp_expander_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+cmp_fp_expander_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && mode != GET_MODE (op))
return 0;
@@ -3768,9 +4158,7 @@ cmp_fp_expander_operand (op, mode)
/* Match an SI or HImode register for a zero_extract. */
int
-ext_register_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+ext_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int regno;
if ((!TARGET_64BIT || GET_MODE (op) != DImode)
@@ -3780,7 +4168,7 @@ ext_register_operand (op, mode)
if (!register_operand (op, VOIDmode))
return 0;
- /* Be curefull to accept only registers having upper parts. */
+ /* Be careful to accept only registers having upper parts. */
regno = REG_P (op) ? REGNO (op) : REGNO (SUBREG_REG (op));
return (regno > LAST_VIRTUAL_REGISTER || regno < 4);
}
@@ -3789,9 +4177,7 @@ ext_register_operand (op, mode)
OP is the expression matched, and MODE is its mode. */
int
-binary_fp_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+binary_fp_operator (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && mode != GET_MODE (op))
return 0;
@@ -3810,25 +4196,19 @@ binary_fp_operator (op, mode)
}
int
-mult_operator (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mult_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == MULT;
}
int
-div_operator (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+div_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == DIV;
}
int
-arith_or_logical_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+arith_or_logical_operator (rtx op, enum machine_mode mode)
{
return ((mode == VOIDmode || GET_MODE (op) == mode)
&& (GET_RTX_CLASS (GET_CODE (op)) == 'c'
@@ -3838,9 +4218,7 @@ arith_or_logical_operator (op, mode)
/* Returns 1 if OP is memory operand with a displacement. */
int
-memory_displacement_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+memory_displacement_operand (rtx op, enum machine_mode mode)
{
struct ix86_address parts;
@@ -3860,9 +4238,7 @@ memory_displacement_operand (op, mode)
expander, and no actual insns use this. */
int
-cmpsi_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+cmpsi_operand (rtx op, enum machine_mode mode)
{
if (nonimmediate_operand (op, mode))
return 1;
@@ -3884,9 +4260,7 @@ cmpsi_operand (op, mode)
modRM array. */
int
-long_memory_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+long_memory_operand (rtx op, enum machine_mode mode)
{
if (! memory_operand (op, mode))
return 0;
@@ -3897,9 +4271,7 @@ long_memory_operand (op, mode)
/* Return nonzero if the rtx is known aligned. */
int
-aligned_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+aligned_operand (rtx op, enum machine_mode mode)
{
struct ix86_address parts;
@@ -3925,11 +4297,6 @@ aligned_operand (op, mode)
if (! ix86_decompose_address (op, &parts))
abort ();
- if (parts.base && GET_CODE (parts.base) == SUBREG)
- parts.base = SUBREG_REG (parts.base);
- if (parts.index && GET_CODE (parts.index) == SUBREG)
- parts.index = SUBREG_REG (parts.index);
-
/* Look for some component that isn't known to be aligned. */
if (parts.index)
{
@@ -3953,31 +4320,126 @@ aligned_operand (op, mode)
return 1;
}
+/* Initialize the table of extra 80387 mathematical constants. */
+
+static void
+init_ext_80387_constants (void)
+{
+ static const char * cst[5] =
+ {
+ "0.3010299956639811952256464283594894482", /* 0: fldlg2 */
+ "0.6931471805599453094286904741849753009", /* 1: fldln2 */
+ "1.4426950408889634073876517827983434472", /* 2: fldl2e */
+ "3.3219280948873623478083405569094566090", /* 3: fldl2t */
+ "3.1415926535897932385128089594061862044", /* 4: fldpi */
+ };
+ int i;
+
+ for (i = 0; i < 5; i++)
+ {
+ real_from_string (&ext_80387_constants_table[i], cst[i]);
+ /* Ensure each constant is rounded to XFmode precision. */
+ real_convert (&ext_80387_constants_table[i],
+ XFmode, &ext_80387_constants_table[i]);
+ }
+
+ ext_80387_constants_init = 1;
+}
+
/* Return true if the constant is something that can be loaded with
- a special instruction. Only handle 0.0 and 1.0; others are less
- worthwhile. */
+ a special instruction. */
int
-standard_80387_constant_p (x)
- rtx x;
+standard_80387_constant_p (rtx x)
{
if (GET_CODE (x) != CONST_DOUBLE || !FLOAT_MODE_P (GET_MODE (x)))
return -1;
- /* Note that on the 80387, other constants, such as pi, that we should support
- too. On some machines, these are much slower to load as standard constant,
- than to load from doubles in memory. */
+
if (x == CONST0_RTX (GET_MODE (x)))
return 1;
if (x == CONST1_RTX (GET_MODE (x)))
return 2;
+
+ /* For XFmode constants, try to find a special 80387 instruction on
+ those CPUs that benefit from them. */
+ if (GET_MODE (x) == XFmode
+ && x86_ext_80387_constants & TUNEMASK)
+ {
+ REAL_VALUE_TYPE r;
+ int i;
+
+ if (! ext_80387_constants_init)
+ init_ext_80387_constants ();
+
+ REAL_VALUE_FROM_CONST_DOUBLE (r, x);
+ for (i = 0; i < 5; i++)
+ if (real_identical (&r, &ext_80387_constants_table[i]))
+ return i + 3;
+ }
+
return 0;
}
+/* Return the opcode of the special instruction to be used to load
+ the constant X. */
+
+const char *
+standard_80387_constant_opcode (rtx x)
+{
+ switch (standard_80387_constant_p (x))
+ {
+ case 1:
+ return "fldz";
+ case 2:
+ return "fld1";
+ case 3:
+ return "fldlg2";
+ case 4:
+ return "fldln2";
+ case 5:
+ return "fldl2e";
+ case 6:
+ return "fldl2t";
+ case 7:
+ return "fldpi";
+ }
+ abort ();
+}
+
+/* Return the CONST_DOUBLE representing the 80387 constant that is
+ loaded by the specified special instruction. The argument IDX
+ matches the return value from standard_80387_constant_p. */
+
+rtx
+standard_80387_constant_rtx (int idx)
+{
+ int i;
+
+ if (! ext_80387_constants_init)
+ init_ext_80387_constants ();
+
+ switch (idx)
+ {
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ i = idx - 3;
+ break;
+
+ default:
+ abort ();
+ }
+
+ return CONST_DOUBLE_FROM_REAL_VALUE (ext_80387_constants_table[i],
+ XFmode);
+}
+
/* Return 1 if X is FP constant we can load to SSE register w/o using memory.
*/
int
-standard_sse_constant_p (x)
- rtx x;
+standard_sse_constant_p (rtx x)
{
if (x == const0_rtx)
return 1;
@@ -3987,11 +4449,10 @@ standard_sse_constant_p (x)
/* Returns 1 if OP contains a symbol reference */
int
-symbolic_reference_mentioned_p (op)
- rtx op;
+symbolic_reference_mentioned_p (rtx op)
{
- register const char *fmt;
- register int i;
+ const char *fmt;
+ int i;
if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
return 1;
@@ -4001,7 +4462,7 @@ symbolic_reference_mentioned_p (op)
{
if (fmt[i] == 'E')
{
- register int j;
+ int j;
for (j = XVECLEN (op, i) - 1; j >= 0; j--)
if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
@@ -4028,7 +4489,7 @@ symbolic_reference_mentioned_p (op)
`return' is OK. */
int
-ix86_can_use_return_insn_p ()
+ix86_can_use_return_insn_p (void)
{
struct ix86_frame frame;
@@ -4052,8 +4513,7 @@ ix86_can_use_return_insn_p ()
/* Return 1 if VALUE can be stored in the sign extended immediate field. */
int
-x86_64_sign_extended_value (value)
- rtx value;
+x86_64_sign_extended_value (rtx value)
{
switch (GET_CODE (value))
{
@@ -4075,6 +4535,9 @@ x86_64_sign_extended_value (value)
library. Don't count TLS SYMBOL_REFs here, since they should fit
only if inside of UNSPEC handled below. */
case SYMBOL_REF:
+ /* TLS symbols are not constant. */
+ if (tls_symbolic_operand (value, Pmode))
+ return false;
return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL);
/* For certain code models, the code is near as well. */
@@ -4161,8 +4624,7 @@ x86_64_sign_extended_value (value)
/* Return 1 if VALUE can be stored in the zero extended immediate field. */
int
-x86_64_zero_extended_value (value)
- rtx value;
+x86_64_zero_extended_value (rtx value)
{
switch (GET_CODE (value))
{
@@ -4181,6 +4643,9 @@ x86_64_zero_extended_value (value)
/* For certain code models, the symbolic references are known to fit. */
case SYMBOL_REF:
+ /* TLS symbols are not constant. */
+ if (tls_symbolic_operand (value, Pmode))
+ return false;
return ix86_cmodel == CM_SMALL;
/* For certain code models, the code is near as well. */
@@ -4241,7 +4706,7 @@ x86_64_zero_extended_value (value)
be accessed via the stack pointer) in functions that seem suitable. */
int
-ix86_frame_pointer_required ()
+ix86_frame_pointer_required (void)
{
/* If we accessed previous frames, then the generated code expects
to be able to access the saved ebp value in our frame. */
@@ -4269,12 +4734,12 @@ ix86_frame_pointer_required ()
/* Record that the current function accesses previous call frames. */
void
-ix86_setup_frame_addresses ()
+ix86_setup_frame_addresses (void)
{
cfun->machine->accesses_prev_frame = 1;
}
-#if defined(HAVE_GAS_HIDDEN) && (defined(SUPPORTS_ONE_ONLY) && SUPPORTS_ONE_ONLY)
+#if defined(HAVE_GAS_HIDDEN) && defined(SUPPORTS_ONE_ONLY)
# define USE_HIDDEN_LINKONCE 1
#else
# define USE_HIDDEN_LINKONCE 0
@@ -4286,9 +4751,7 @@ static int pic_labels_used;
the given register. */
static void
-get_pc_thunk_name (name, regno)
- char name[32];
- unsigned int regno;
+get_pc_thunk_name (char name[32], unsigned int regno)
{
if (USE_HIDDEN_LINKONCE)
sprintf (name, "__i686.get_pc_thunk.%s", reg_names[regno]);
@@ -4301,8 +4764,7 @@ get_pc_thunk_name (name, regno)
the return address of the caller and then returns. */
void
-ix86_asm_file_end (file)
- FILE *file;
+ix86_file_end (void)
{
rtx xops[2];
int regno;
@@ -4329,16 +4791,16 @@ ix86_asm_file_end (file)
(*targetm.asm_out.unique_section) (decl, 0);
named_section (decl, NULL, 0);
- (*targetm.asm_out.globalize_label) (file, name);
- fputs ("\t.hidden\t", file);
- assemble_name (file, name);
- fputc ('\n', file);
- ASM_DECLARE_FUNCTION_NAME (file, name, decl);
+ (*targetm.asm_out.globalize_label) (asm_out_file, name);
+ fputs ("\t.hidden\t", asm_out_file);
+ assemble_name (asm_out_file, name);
+ fputc ('\n', asm_out_file);
+ ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
}
else
{
text_section ();
- ASM_OUTPUT_LABEL (file, name);
+ ASM_OUTPUT_LABEL (asm_out_file, name);
}
xops[0] = gen_rtx_REG (SImode, regno);
@@ -4346,13 +4808,15 @@ ix86_asm_file_end (file)
output_asm_insn ("mov{l}\t{%1, %0|%0, %1}", xops);
output_asm_insn ("ret", xops);
}
+
+ if (NEED_INDICATE_EXEC_STACK)
+ file_end_indicate_exec_stack ();
}
/* Emit code for the SET_GOT patterns. */
const char *
-output_set_got (dest)
- rtx dest;
+output_set_got (rtx dest)
{
rtx xops[3];
@@ -4373,7 +4837,7 @@ output_set_got (dest)
is what will be referred to by the Mach-O PIC subsystem. */
ASM_OUTPUT_LABEL (asm_out_file, machopic_function_base_name ());
#endif
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
+ (*targetm.asm_out.internal_label) (asm_out_file, "L",
CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
if (flag_pic)
@@ -4401,8 +4865,7 @@ output_set_got (dest)
/* Generate an "push" pattern for input ARG. */
static rtx
-gen_push (arg)
- rtx arg;
+gen_push (rtx arg)
{
return gen_rtx_SET (VOIDmode,
gen_rtx_MEM (Pmode,
@@ -4415,7 +4878,7 @@ gen_push (arg)
for the entire function. */
static unsigned int
-ix86_select_alt_pic_regnum ()
+ix86_select_alt_pic_regnum (void)
{
if (current_function_is_leaf && !current_function_profile)
{
@@ -4430,9 +4893,7 @@ ix86_select_alt_pic_regnum ()
/* Return 1 if we need to save REGNO. */
static int
-ix86_save_reg (regno, maybe_eh_return)
- unsigned int regno;
- int maybe_eh_return;
+ix86_save_reg (unsigned int regno, int maybe_eh_return)
{
if (pic_offset_table_rtx
&& regno == REAL_PIC_OFFSET_TABLE_REGNUM
@@ -4468,7 +4929,7 @@ ix86_save_reg (regno, maybe_eh_return)
/* Return number of registers to be saved on the stack. */
static int
-ix86_nsaved_regs ()
+ix86_nsaved_regs (void)
{
int nregs = 0;
int regno;
@@ -4483,9 +4944,7 @@ ix86_nsaved_regs ()
its replacement, at the start of a routine. */
HOST_WIDE_INT
-ix86_initial_elimination_offset (from, to)
- int from;
- int to;
+ix86_initial_elimination_offset (int from, int to)
{
struct ix86_frame frame;
ix86_compute_frame_layout (&frame);
@@ -4511,18 +4970,54 @@ ix86_initial_elimination_offset (from, to)
/* Fill structure ix86_frame about frame of currently computed function. */
static void
-ix86_compute_frame_layout (frame)
- struct ix86_frame *frame;
+ix86_compute_frame_layout (struct ix86_frame *frame)
{
HOST_WIDE_INT total_size;
int stack_alignment_needed = cfun->stack_alignment_needed / BITS_PER_UNIT;
- int offset;
+ HOST_WIDE_INT offset;
int preferred_alignment = cfun->preferred_stack_boundary / BITS_PER_UNIT;
HOST_WIDE_INT size = get_frame_size ();
frame->nregs = ix86_nsaved_regs ();
total_size = size;
+ /* During reload iteration the amount of registers saved can change.
+ Recompute the value as needed. Do not recompute when amount of registers
+ didn't change as reload does mutiple calls to the function and does not
+ expect the decision to change within single iteration. */
+ if (!optimize_size
+ && cfun->machine->use_fast_prologue_epilogue_nregs != frame->nregs)
+ {
+ int count = frame->nregs;
+
+ cfun->machine->use_fast_prologue_epilogue_nregs = count;
+ /* The fast prologue uses move instead of push to save registers. This
+ is significantly longer, but also executes faster as modern hardware
+ can execute the moves in parallel, but can't do that for push/pop.
+
+ Be careful about choosing what prologue to emit: When function takes
+ many instructions to execute we may use slow version as well as in
+ case function is known to be outside hot spot (this is known with
+ feedback only). Weight the size of function by number of registers
+ to save as it is cheap to use one or two push instructions but very
+ slow to use many of them. */
+ if (count)
+ count = (count - 1) * FAST_PROLOGUE_INSN_COUNT;
+ if (cfun->function_frequency < FUNCTION_FREQUENCY_NORMAL
+ || (flag_branch_probabilities
+ && cfun->function_frequency < FUNCTION_FREQUENCY_HOT))
+ cfun->machine->use_fast_prologue_epilogue = false;
+ else
+ cfun->machine->use_fast_prologue_epilogue
+ = !expensive_function_p (count);
+ }
+ if (TARGET_PROLOGUE_USING_MOVE
+ && cfun->machine->use_fast_prologue_epilogue)
+ frame->save_regs_using_mov = true;
+ else
+ frame->save_regs_using_mov = false;
+
+
/* Skip return address and saved base pointer. */
offset = frame_pointer_needed ? UNITS_PER_WORD * 2 : UNITS_PER_WORD;
@@ -4568,8 +5063,12 @@ ix86_compute_frame_layout (frame)
offset += size;
/* Add outgoing arguments area. Can be skipped if we eliminated
- all the function calls as dead code. */
- if (ACCUMULATE_OUTGOING_ARGS && !current_function_is_leaf)
+ all the function calls as dead code.
+ Skipping is however impossible when function calls alloca. Alloca
+ expander assumes that last current_function_outgoing_args_size
+ of stack frame are unused. */
+ if (ACCUMULATE_OUTGOING_ARGS
+ && (!current_function_is_leaf || current_function_calls_alloca))
{
offset += current_function_outgoing_args_size;
frame->outgoing_arguments_size = current_function_outgoing_args_size;
@@ -4595,10 +5094,16 @@ ix86_compute_frame_layout (frame)
(size + frame->padding1 + frame->padding2
+ frame->outgoing_arguments_size + frame->va_arg_size);
- if (TARGET_64BIT && TARGET_RED_ZONE && current_function_sp_is_unchanging
+ if ((!frame->to_allocate && frame->nregs <= 1)
+ || (TARGET_64BIT && frame->to_allocate >= (HOST_WIDE_INT) 0x80000000))
+ frame->save_regs_using_mov = false;
+
+ if (TARGET_RED_ZONE && current_function_sp_is_unchanging
&& current_function_is_leaf)
{
frame->red_zone_size = frame->to_allocate;
+ if (frame->save_regs_using_mov)
+ frame->red_zone_size += frame->nregs * UNITS_PER_WORD;
if (frame->red_zone_size > RED_ZONE_SIZE - RED_ZONE_RESERVE)
frame->red_zone_size = RED_ZONE_SIZE - RED_ZONE_RESERVE;
}
@@ -4625,9 +5130,9 @@ ix86_compute_frame_layout (frame)
/* Emit code to save registers in the prologue. */
static void
-ix86_emit_save_regs ()
+ix86_emit_save_regs (void)
{
- register int regno;
+ int regno;
rtx insn;
for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
@@ -4641,9 +5146,7 @@ ix86_emit_save_regs ()
/* Emit code to save registers using MOV insns. First register
is restored from POINTER + OFFSET. */
static void
-ix86_emit_save_regs_using_mov (pointer, offset)
- rtx pointer;
- HOST_WIDE_INT offset;
+ix86_emit_save_regs_using_mov (rtx pointer, HOST_WIDE_INT offset)
{
int regno;
rtx insn;
@@ -4659,24 +5162,51 @@ ix86_emit_save_regs_using_mov (pointer, offset)
}
}
+/* 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,
+ zero if %r11 register is live and cannot be freely used and positive
+ otherwise. */
+
+static void
+pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, int style)
+{
+ rtx insn;
+
+ if (! TARGET_64BIT)
+ insn = emit_insn (gen_pro_epilogue_adjust_stack_1 (dest, src, offset));
+ else if (x86_64_immediate_operand (offset, DImode))
+ insn = emit_insn (gen_pro_epilogue_adjust_stack_rex64 (dest, src, offset));
+ else
+ {
+ rtx r11;
+ /* r11 is used by indirect sibcall return as well, set before the
+ epilogue and used after the epilogue. ATM indirect sibcall
+ shouldn't be used together with huge frame sizes in one
+ function because of the frame_size check in sibcall.c. */
+ if (style == 0)
+ abort ();
+ r11 = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 3 /* R11 */);
+ insn = emit_insn (gen_rtx_SET (DImode, r11, offset));
+ if (style < 0)
+ RTX_FRAME_RELATED_P (insn) = 1;
+ insn = emit_insn (gen_pro_epilogue_adjust_stack_rex64_2 (dest, src, r11,
+ offset));
+ }
+ if (style < 0)
+ RTX_FRAME_RELATED_P (insn) = 1;
+}
+
/* Expand the prologue into a bunch of separate insns. */
void
-ix86_expand_prologue ()
+ix86_expand_prologue (void)
{
rtx insn;
bool pic_reg_used;
struct ix86_frame frame;
- int use_mov = 0;
HOST_WIDE_INT allocate;
- if (!optimize_size)
- {
- use_fast_prologue_epilogue
- = !expensive_function_p (FAST_PROLOGUE_INSN_COUNT);
- if (TARGET_PROLOGUE_USING_MOVE)
- use_mov = use_fast_prologue_epilogue;
- }
ix86_compute_frame_layout (&frame);
/* Note: AT&T enter does NOT have reversed args. Enter is probably
@@ -4692,50 +5222,53 @@ ix86_expand_prologue ()
}
allocate = frame.to_allocate;
- /* In case we are dealing only with single register and empty frame,
- push is equivalent of the mov+add sequence. */
- if (allocate == 0 && frame.nregs <= 1)
- use_mov = 0;
- if (!use_mov)
+ if (!frame.save_regs_using_mov)
ix86_emit_save_regs ();
else
allocate += frame.nregs * UNITS_PER_WORD;
+ /* When using red zone we may start register saving before allocating
+ the stack frame saving one cycle of the prologue. */
+ if (TARGET_RED_ZONE && frame.save_regs_using_mov)
+ ix86_emit_save_regs_using_mov (frame_pointer_needed ? hard_frame_pointer_rtx
+ : stack_pointer_rtx,
+ -frame.nregs * UNITS_PER_WORD);
+
if (allocate == 0)
;
else if (! TARGET_STACK_PROBE || allocate < CHECK_STACK_LIMIT)
- {
- insn = emit_insn (gen_pro_epilogue_adjust_stack
- (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (-allocate)));
- RTX_FRAME_RELATED_P (insn) = 1;
- }
+ pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (-allocate), -1);
else
{
- /* ??? Is this only valid for Win32? */
-
- rtx arg0, sym;
+ /* Only valid for Win32. */
+ rtx eax = gen_rtx_REG (SImode, 0);
+ bool eax_live = ix86_eax_live_at_start_p ();
if (TARGET_64BIT)
- abort ();
+ abort ();
- arg0 = gen_rtx_REG (SImode, 0);
- emit_move_insn (arg0, GEN_INT (allocate));
+ if (eax_live)
+ {
+ emit_insn (gen_push (eax));
+ allocate -= 4;
+ }
- sym = gen_rtx_MEM (FUNCTION_MODE,
- gen_rtx_SYMBOL_REF (Pmode, "_alloca"));
- insn = emit_call_insn (gen_call (sym, const0_rtx, constm1_rtx));
+ insn = emit_move_insn (eax, GEN_INT (allocate));
+ RTX_FRAME_RELATED_P (insn) = 1;
- CALL_INSN_FUNCTION_USAGE (insn)
- = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, arg0),
- CALL_INSN_FUNCTION_USAGE (insn));
+ insn = emit_insn (gen_allocate_stack_worker (eax));
+ RTX_FRAME_RELATED_P (insn) = 1;
- /* Don't allow scheduling pass to move insns across __alloca
- call. */
- emit_insn (gen_blockage (const0_rtx));
+ if (eax_live)
+ {
+ rtx t = plus_constant (stack_pointer_rtx, allocate);
+ emit_move_insn (eax, gen_rtx_MEM (SImode, t));
+ }
}
- if (use_mov)
+
+ if (frame.save_regs_using_mov && !TARGET_RED_ZONE)
{
if (!frame_pointer_needed || !frame.to_allocate)
ix86_emit_save_regs_using_mov (stack_pointer_rtx, frame.to_allocate);
@@ -4744,10 +5277,6 @@ ix86_expand_prologue ()
-frame.nregs * UNITS_PER_WORD);
}
-#ifdef SUBTARGET_PROLOGUE
- SUBTARGET_PROLOGUE;
-#endif
-
pic_reg_used = false;
if (pic_offset_table_rtx
&& (regs_ever_live[REAL_PIC_OFFSET_TABLE_REGNUM]
@@ -4768,7 +5297,7 @@ ix86_expand_prologue ()
/* Even with accurate pre-reload life analysis, we can wind up
deleting all references to the pic register after reload.
Consider if cross-jumping unifies two sides of a branch
- controled by a comparison vs the only read from a global.
+ controlled by a comparison vs the only read from a global.
In which case, allow the set_got to be deleted, though we're
too late to do anything about the ebx save in the prologue. */
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx, NULL);
@@ -4783,19 +5312,29 @@ ix86_expand_prologue ()
/* Emit code to restore saved registers using MOV insns. First register
is restored from POINTER + OFFSET. */
static void
-ix86_emit_restore_regs_using_mov (pointer, offset, maybe_eh_return)
- rtx pointer;
- int offset;
- int maybe_eh_return;
+ix86_emit_restore_regs_using_mov (rtx pointer, HOST_WIDE_INT offset,
+ int maybe_eh_return)
{
int regno;
+ rtx base_address = gen_rtx_MEM (Pmode, pointer);
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (ix86_save_reg (regno, maybe_eh_return))
{
+ /* 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))
+ {
+ rtx r11;
+
+ r11 = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 3 /* R11 */);
+ emit_move_insn (r11, GEN_INT (offset));
+ emit_insn (gen_adddi3 (r11, r11, pointer));
+ base_address = gen_rtx_MEM (Pmode, r11);
+ offset = 0;
+ }
emit_move_insn (gen_rtx_REG (Pmode, regno),
- adjust_address (gen_rtx_MEM (Pmode, pointer),
- Pmode, offset));
+ adjust_address (base_address, Pmode, offset));
offset += UNITS_PER_WORD;
}
}
@@ -4803,8 +5342,7 @@ ix86_emit_restore_regs_using_mov (pointer, offset, maybe_eh_return)
/* Restore function stack, frame, and registers. */
void
-ix86_expand_epilogue (style)
- int style;
+ix86_expand_epilogue (int style)
{
int regno;
int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging;
@@ -4830,15 +5368,16 @@ ix86_expand_epilogue (style)
while this code results in LEAVE instruction (or discrete equivalent),
so it is profitable in some other cases as well. Especially when there
are no registers to restore. We also use this code when TARGET_USE_LEAVE
- and there is exactly one register to pop. This heruistic may need some
+ and there is exactly one register to pop. This heuristic may need some
tuning in future. */
if ((!sp_valid && frame.nregs <= 1)
|| (TARGET_EPILOGUE_USING_MOVE
- && use_fast_prologue_epilogue
+ && cfun->machine->use_fast_prologue_epilogue
&& (frame.nregs > 1 || frame.to_allocate))
|| (frame_pointer_needed && !frame.nregs && frame.to_allocate)
|| (frame_pointer_needed && TARGET_USE_LEAVE
- && use_fast_prologue_epilogue && frame.nregs == 1)
+ && cfun->machine->use_fast_prologue_epilogue
+ && frame.nregs == 1)
|| current_function_calls_eh_return)
{
/* Restore registers. We can use ebp or esp to address the memory
@@ -4868,8 +5407,8 @@ ix86_expand_epilogue (style)
tmp = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
emit_move_insn (hard_frame_pointer_rtx, tmp);
- emit_insn (gen_pro_epilogue_adjust_stack
- (stack_pointer_rtx, sa, const0_rtx));
+ pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
+ const0_rtx, style);
}
else
{
@@ -4880,18 +5419,19 @@ ix86_expand_epilogue (style)
}
}
else if (!frame_pointer_needed)
- emit_insn (gen_pro_epilogue_adjust_stack
- (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (frame.to_allocate
- + frame.nregs * UNITS_PER_WORD)));
+ pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (frame.to_allocate
+ + frame.nregs * UNITS_PER_WORD),
+ style);
/* If not an i386, mov & pop is faster than "leave". */
- else if (TARGET_USE_LEAVE || optimize_size || !use_fast_prologue_epilogue)
+ else if (TARGET_USE_LEAVE || optimize_size
+ || !cfun->machine->use_fast_prologue_epilogue)
emit_insn (TARGET_64BIT ? gen_leave_rex64 () : gen_leave ());
else
{
- emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
- hard_frame_pointer_rtx,
- const0_rtx));
+ pro_epilogue_adjust_stack (stack_pointer_rtx,
+ hard_frame_pointer_rtx,
+ const0_rtx, style);
if (TARGET_64BIT)
emit_insn (gen_popdi1 (hard_frame_pointer_rtx));
else
@@ -4906,14 +5446,13 @@ ix86_expand_epilogue (style)
{
if (!frame_pointer_needed)
abort ();
- emit_insn (gen_pro_epilogue_adjust_stack (stack_pointer_rtx,
- hard_frame_pointer_rtx,
- GEN_INT (offset)));
+ pro_epilogue_adjust_stack (stack_pointer_rtx,
+ hard_frame_pointer_rtx,
+ GEN_INT (offset), style);
}
else if (frame.to_allocate)
- emit_insn (gen_pro_epilogue_adjust_stack
- (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (frame.to_allocate)));
+ pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (frame.to_allocate), style);
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (ix86_save_reg (regno, false))
@@ -4952,7 +5491,7 @@ ix86_expand_epilogue (style)
{
rtx ecx = gen_rtx_REG (SImode, 2);
- /* There are is no "pascal" calling convention in 64bit ABI. */
+ /* There is no "pascal" calling convention in 64bit ABI. */
if (TARGET_64BIT)
abort ();
@@ -4970,9 +5509,8 @@ ix86_expand_epilogue (style)
/* Reset from the function's potential modifications. */
static void
-ix86_output_function_epilogue (file, size)
- FILE *file ATTRIBUTE_UNUSED;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+ix86_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
if (pic_offset_table_rtx)
REGNO (pic_offset_table_rtx) = REAL_PIC_OFFSET_TABLE_REGNUM;
@@ -4981,13 +5519,10 @@ ix86_output_function_epilogue (file, size)
/* Extract the parts of an RTL expression that is a valid memory address
for an instruction. Return 0 if the structure of the address is
grossly off. Return -1 if the address contains ASHIFT, so it is not
- strictly valid, but still used for computing length of lea instruction.
- */
+ strictly valid, but still used for computing length of lea instruction. */
static int
-ix86_decompose_address (addr, out)
- register rtx addr;
- struct ix86_address *out;
+ix86_decompose_address (rtx addr, struct ix86_address *out)
{
rtx base = NULL_RTX;
rtx index = NULL_RTX;
@@ -4995,47 +5530,72 @@ ix86_decompose_address (addr, out)
HOST_WIDE_INT scale = 1;
rtx scale_rtx = NULL_RTX;
int retval = 1;
+ enum ix86_address_seg seg = SEG_DEFAULT;
- if (REG_P (addr) || GET_CODE (addr) == SUBREG)
+ if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
base = addr;
else if (GET_CODE (addr) == PLUS)
{
- rtx op0 = XEXP (addr, 0);
- rtx op1 = XEXP (addr, 1);
- enum rtx_code code0 = GET_CODE (op0);
- enum rtx_code code1 = GET_CODE (op1);
+ rtx addends[4], op;
+ int n = 0, i;
- if (code0 == REG || code0 == SUBREG)
- {
- if (code1 == REG || code1 == SUBREG)
- index = op0, base = op1; /* index + base */
- else
- base = op0, disp = op1; /* base + displacement */
- }
- else if (code0 == MULT)
- {
- index = XEXP (op0, 0);
- scale_rtx = XEXP (op0, 1);
- if (code1 == REG || code1 == SUBREG)
- base = op1; /* index*scale + base */
- else
- disp = op1; /* index*scale + disp */
- }
- else if (code0 == PLUS && GET_CODE (XEXP (op0, 0)) == MULT)
+ op = addr;
+ do
{
- index = XEXP (XEXP (op0, 0), 0); /* index*scale + base + disp */
- scale_rtx = XEXP (XEXP (op0, 0), 1);
- base = XEXP (op0, 1);
- disp = op1;
+ if (n >= 4)
+ return 0;
+ addends[n++] = XEXP (op, 1);
+ op = XEXP (op, 0);
}
- else if (code0 == PLUS)
+ while (GET_CODE (op) == PLUS);
+ if (n >= 4)
+ return 0;
+ addends[n] = op;
+
+ for (i = n; i >= 0; --i)
{
- index = XEXP (op0, 0); /* index + base + disp */
- base = XEXP (op0, 1);
- disp = op1;
+ op = addends[i];
+ switch (GET_CODE (op))
+ {
+ case MULT:
+ if (index)
+ return 0;
+ index = XEXP (op, 0);
+ scale_rtx = XEXP (op, 1);
+ break;
+
+ case UNSPEC:
+ if (XINT (op, 1) == UNSPEC_TP
+ && TARGET_TLS_DIRECT_SEG_REFS
+ && seg == SEG_DEFAULT)
+ seg = TARGET_64BIT ? SEG_FS : SEG_GS;
+ else
+ return 0;
+ break;
+
+ case REG:
+ case SUBREG:
+ if (!base)
+ base = op;
+ else if (!index)
+ index = op;
+ else
+ return 0;
+ break;
+
+ case CONST:
+ case CONST_INT:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ if (disp)
+ return 0;
+ disp = op;
+ break;
+
+ default:
+ return 0;
+ }
}
- else
- return 0;
}
else if (GET_CODE (addr) == MULT)
{
@@ -5068,10 +5628,11 @@ ix86_decompose_address (addr, out)
scale = INTVAL (scale_rtx);
}
- /* Allow arg pointer and stack pointer as index if there is not scaling */
+ /* Allow arg pointer and stack pointer as index if there is not scaling. */
if (base && index && scale == 1
- && (index == arg_pointer_rtx || index == frame_pointer_rtx
- || index == stack_pointer_rtx))
+ && (index == arg_pointer_rtx
+ || index == frame_pointer_rtx
+ || (REG_P (index) && REGNO (index) == STACK_POINTER_REGNUM)))
{
rtx tmp = base;
base = index;
@@ -5086,7 +5647,7 @@ ix86_decompose_address (addr, out)
/* Special case: on K6, [%esi] makes the instruction vector decoded.
Avoid this by transforming to [%esi+0]. */
- if (ix86_cpu == PROCESSOR_K6 && !optimize_size
+ if (ix86_tune == PROCESSOR_K6 && !optimize_size
&& base && !index && !disp
&& REG_P (base)
&& REGNO_REG_CLASS (REGNO (base)) == SIREG)
@@ -5104,6 +5665,7 @@ ix86_decompose_address (addr, out)
out->index = index;
out->disp = disp;
out->scale = scale;
+ out->seg = seg;
return retval;
}
@@ -5113,9 +5675,8 @@ ix86_decompose_address (addr, out)
the address into a reg and make a new pseudo. But not if the address
requires to two regs - that would mean more pseudos with longer
lifetimes. */
-int
-ix86_address_cost (x)
- rtx x;
+static int
+ix86_address_cost (rtx x)
{
struct ix86_address parts;
int cost = 1;
@@ -5123,14 +5684,11 @@ ix86_address_cost (x)
if (!ix86_decompose_address (x, &parts))
abort ();
- if (parts.base && GET_CODE (parts.base) == SUBREG)
- parts.base = SUBREG_REG (parts.base);
- if (parts.index && GET_CODE (parts.index) == SUBREG)
- parts.index = SUBREG_REG (parts.index);
-
/* More complex memory references are better. */
if (parts.disp && parts.disp != const0_rtx)
cost--;
+ if (parts.seg != SEG_DEFAULT)
+ cost--;
/* Attempt to minimize number of registers in the address. */
if ((parts.base
@@ -5176,8 +5734,7 @@ ix86_address_cost (x)
UNSPEC), then return the base term. Otherwise return X. */
rtx
-ix86_find_base_term (x)
- rtx x;
+ix86_find_base_term (rtx x)
{
rtx term;
@@ -5203,21 +5760,7 @@ ix86_find_base_term (x)
return term;
}
- if (GET_CODE (x) != PLUS
- || XEXP (x, 0) != pic_offset_table_rtx
- || GET_CODE (XEXP (x, 1)) != CONST)
- return x;
-
- term = XEXP (XEXP (x, 1), 0);
-
- if (GET_CODE (term) == PLUS && GET_CODE (XEXP (term, 1)) == CONST_INT)
- term = XEXP (term, 0);
-
- if (GET_CODE (term) != UNSPEC
- || XINT (term, 1) != UNSPEC_GOTOFF)
- return x;
-
- term = XVECEXP (term, 0, 0);
+ term = ix86_delegitimize_address (x);
if (GET_CODE (term) != SYMBOL_REF
&& GET_CODE (term) != LABEL_REF)
@@ -5230,8 +5773,7 @@ ix86_find_base_term (x)
satisfies CONSTANT_P. */
bool
-legitimate_constant_p (x)
- rtx x;
+legitimate_constant_p (rtx x)
{
rtx inner;
@@ -5252,12 +5794,23 @@ legitimate_constant_p (x)
&& tls_symbolic_operand (XEXP (inner, 0), Pmode))
return false;
+ if (GET_CODE (inner) == PLUS
+ || GET_CODE (inner) == MINUS)
+ {
+ if (GET_CODE (XEXP (inner, 1)) != CONST_INT)
+ return false;
+ inner = XEXP (inner, 0);
+ }
+
/* Only some unspecs are valid as "constants". */
if (GET_CODE (inner) == UNSPEC)
switch (XINT (inner, 1))
{
case UNSPEC_TPOFF:
+ case UNSPEC_NTPOFF:
return local_exec_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
+ case UNSPEC_DTPOFF:
+ return local_dynamic_symbolic_operand (XVECEXP (inner, 0, 0), Pmode);
default:
return false;
}
@@ -5276,8 +5829,7 @@ legitimate_constant_p (x)
is checked above. */
static bool
-ix86_cannot_force_const_mem (x)
- rtx x;
+ix86_cannot_force_const_mem (rtx x)
{
return !legitimate_constant_p (x);
}
@@ -5285,29 +5837,9 @@ ix86_cannot_force_const_mem (x)
/* Determine if a given RTX is a valid constant address. */
bool
-constant_address_p (x)
- rtx x;
+constant_address_p (rtx x)
{
- switch (GET_CODE (x))
- {
- case LABEL_REF:
- case CONST_INT:
- return true;
-
- case CONST_DOUBLE:
- return TARGET_64BIT;
-
- case CONST:
- /* For Mach-O, really believe the CONST. */
- if (TARGET_MACHO)
- return true;
- /* Otherwise fall through. */
- case SYMBOL_REF:
- return !flag_pic && legitimate_constant_p (x);
-
- default:
- return false;
- }
+ return CONSTANT_P (x) && legitimate_address_p (Pmode, x, 1);
}
/* Nonzero if the constant value X is a legitimate general operand
@@ -5315,8 +5847,7 @@ constant_address_p (x)
that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
bool
-legitimate_pic_operand_p (x)
- rtx x;
+legitimate_pic_operand_p (rtx x)
{
rtx inner;
@@ -5349,8 +5880,7 @@ legitimate_pic_operand_p (x)
in PIC mode. */
int
-legitimate_pic_address_disp_p (disp)
- register rtx disp;
+legitimate_pic_address_disp_p (rtx disp)
{
bool saw_plus;
@@ -5363,22 +5893,28 @@ legitimate_pic_address_disp_p (disp)
return 0;
if (GET_CODE (disp) == SYMBOL_REF
&& ix86_cmodel == CM_SMALL_PIC
- && (CONSTANT_POOL_ADDRESS_P (disp)
- || SYMBOL_REF_FLAG (disp)))
+ && SYMBOL_REF_LOCAL_P (disp))
return 1;
if (GET_CODE (disp) == LABEL_REF)
return 1;
if (GET_CODE (disp) == CONST
- && GET_CODE (XEXP (disp, 0)) == PLUS
- && ((GET_CODE (XEXP (XEXP (disp, 0), 0)) == SYMBOL_REF
- && ix86_cmodel == CM_SMALL_PIC
- && (CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (disp, 0), 0))
- || SYMBOL_REF_FLAG (XEXP (XEXP (disp, 0), 0))))
- || GET_CODE (XEXP (XEXP (disp, 0), 0)) == LABEL_REF)
- && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT
- && INTVAL (XEXP (XEXP (disp, 0), 1)) < 16*1024*1024
- && INTVAL (XEXP (XEXP (disp, 0), 1)) >= -16*1024*1024)
- return 1;
+ && GET_CODE (XEXP (disp, 0)) == PLUS)
+ {
+ rtx op0 = XEXP (XEXP (disp, 0), 0);
+ rtx op1 = XEXP (XEXP (disp, 0), 1);
+
+ /* TLS references should always be enclosed in UNSPEC. */
+ if (tls_symbolic_operand (op0, GET_MODE (op0)))
+ return 0;
+ if (((GET_CODE (op0) == SYMBOL_REF
+ && ix86_cmodel == CM_SMALL_PIC
+ && SYMBOL_REF_LOCAL_P (op0))
+ || GET_CODE (op0) == LABEL_REF)
+ && GET_CODE (op1) == CONST_INT
+ && INTVAL (op1) < 16*1024*1024
+ && INTVAL (op1) >= -16*1024*1024)
+ return 1;
+ }
}
if (GET_CODE (disp) != CONST)
return 0;
@@ -5415,7 +5951,7 @@ legitimate_pic_address_disp_p (disp)
if (GET_CODE (XEXP (disp, 1)) == SYMBOL_REF)
{
const char *sym_name = XSTR (XEXP (disp, 1), 0);
- if (strstr (sym_name, "$pb") != 0)
+ if (! strcmp (sym_name, "<pic base>"))
return 1;
}
}
@@ -5430,7 +5966,10 @@ legitimate_pic_address_disp_p (disp)
return false;
return GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF;
case UNSPEC_GOTOFF:
- return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
+ if (GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF
+ || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF)
+ return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
+ return false;
case UNSPEC_GOTTPOFF:
case UNSPEC_GOTNTPOFF:
case UNSPEC_INDNTPOFF:
@@ -5455,10 +5994,7 @@ legitimate_pic_address_disp_p (disp)
be recognized. */
int
-legitimate_address_p (mode, addr, strict)
- enum machine_mode mode;
- register rtx addr;
- int strict;
+legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
{
struct ix86_address parts;
rtx base, index, disp;
@@ -5474,13 +6010,6 @@ legitimate_address_p (mode, addr, strict)
debug_rtx (addr);
}
- if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_TP)
- {
- if (TARGET_DEBUG_ADDR)
- fprintf (stderr, "Success.\n");
- return TRUE;
- }
-
if (ix86_decompose_address (addr, &parts) <= 0)
{
reason = "decomposition failed";
@@ -5500,15 +6029,9 @@ legitimate_address_p (mode, addr, strict)
if (base)
{
- rtx reg;
reason_rtx = base;
- if (GET_CODE (base) == SUBREG)
- reg = SUBREG_REG (base);
- else
- reg = base;
-
- if (GET_CODE (reg) != REG)
+ if (GET_CODE (base) != REG)
{
reason = "base is not a register";
goto report_error;
@@ -5520,8 +6043,8 @@ legitimate_address_p (mode, addr, strict)
goto report_error;
}
- if ((strict && ! REG_OK_FOR_BASE_STRICT_P (reg))
- || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (reg)))
+ if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base))
+ || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base)))
{
reason = "base is not valid";
goto report_error;
@@ -5536,15 +6059,9 @@ legitimate_address_p (mode, addr, strict)
if (index)
{
- rtx reg;
reason_rtx = index;
- if (GET_CODE (index) == SUBREG)
- reg = SUBREG_REG (index);
- else
- reg = index;
-
- if (GET_CODE (reg) != REG)
+ if (GET_CODE (index) != REG)
{
reason = "index is not a register";
goto report_error;
@@ -5556,8 +6073,8 @@ legitimate_address_p (mode, addr, strict)
goto report_error;
}
- if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (reg))
- || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (reg)))
+ if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (index))
+ || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (index)))
{
reason = "index is not valid";
goto report_error;
@@ -5658,7 +6175,12 @@ legitimate_address_p (mode, addr, strict)
that never results in lea, this seems to be easier and
correct fix for crash to disable this test. */
}
- else if (!CONSTANT_ADDRESS_P (disp))
+ else if (GET_CODE (disp) != LABEL_REF
+ && GET_CODE (disp) != CONST_INT
+ && (GET_CODE (disp) != CONST
+ || !legitimate_constant_p (disp))
+ && (GET_CODE (disp) != SYMBOL_REF
+ || !legitimate_constant_p (disp)))
{
reason = "displacement is not constant";
goto report_error;
@@ -5668,11 +6190,6 @@ legitimate_address_p (mode, addr, strict)
reason = "displacement is out of range";
goto report_error;
}
- else if (!TARGET_64BIT && GET_CODE (disp) == CONST_DOUBLE)
- {
- reason = "displacement is a const_double";
- goto report_error;
- }
}
/* Everything looks valid. */
@@ -5692,7 +6209,7 @@ legitimate_address_p (mode, addr, strict)
/* Return an unique alias set for the GOT. */
static HOST_WIDE_INT
-ix86_GOT_alias_set ()
+ix86_GOT_alias_set (void)
{
static HOST_WIDE_INT set = -1;
if (set == -1)
@@ -5711,7 +6228,7 @@ ix86_GOT_alias_set ()
2. Static data references, constant pool addresses, and code labels
compute the address as an offset from the GOT, whose base is in
- the PIC reg. Static data objects have SYMBOL_REF_FLAG set to
+ the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
differentiate them from global data objects. The returned
address is the PIC reg + an unspec constant.
@@ -5719,9 +6236,7 @@ ix86_GOT_alias_set ()
reg also appears in the address. */
rtx
-legitimize_pic_address (orig, reg)
- rtx orig;
- rtx reg;
+legitimize_pic_address (rtx orig, rtx reg)
{
rtx addr = orig;
rtx new = orig;
@@ -5743,7 +6258,15 @@ legitimize_pic_address (orig, reg)
if (reload_in_progress)
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
- new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
+ if (GET_CODE (addr) == CONST)
+ addr = XEXP (addr, 0);
+ if (GET_CODE (addr) == PLUS)
+ {
+ new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)), UNSPEC_GOTOFF);
+ new = gen_rtx_PLUS (Pmode, new, XEXP (addr, 1));
+ }
+ else
+ new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
new = gen_rtx_CONST (Pmode, new);
new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
@@ -5799,7 +6322,7 @@ legitimize_pic_address (orig, reg)
/* We must match stuff we generate before. Assume the only
unspecs that can get here are ours. Not that we could do
- anything with them anyway... */
+ anything with them anyway.... */
if (GET_CODE (addr) == UNSPEC
|| (GET_CODE (addr) == PLUS
&& GET_CODE (XEXP (addr, 0)) == UNSPEC))
@@ -5861,100 +6384,148 @@ legitimize_pic_address (orig, reg)
}
return new;
}
+
+/* Load the thread pointer. If TO_REG is true, force it into a register. */
-static void
-ix86_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
+static rtx
+get_thread_pointer (int to_reg)
{
- bool local_p = (*targetm.binds_local_p) (decl);
- rtx rtl, symbol;
+ rtx tp, reg, insn;
- rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
- if (GET_CODE (rtl) != MEM)
- return;
- symbol = XEXP (rtl, 0);
- if (GET_CODE (symbol) != SYMBOL_REF)
- return;
+ tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
+ if (!to_reg)
+ return tp;
- /* For basic x86, if using PIC, mark a SYMBOL_REF for a non-global
- symbol so that we may access it directly in the GOT. */
+ reg = gen_reg_rtx (Pmode);
+ insn = gen_rtx_SET (VOIDmode, reg, tp);
+ insn = emit_insn (insn);
- if (flag_pic)
- SYMBOL_REF_FLAG (symbol) = local_p;
+ return reg;
+}
- /* For ELF, encode thread-local data with %[GLil] for "global dynamic",
- "local dynamic", "initial exec" or "local exec" TLS models
- respectively. */
+/* A subroutine of legitimize_address and ix86_expand_move. FOR_MOV is
+ false if we expect this to be used for a memory address and true if
+ we expect to load the address into a register. */
- if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
+static rtx
+legitimize_tls_address (rtx x, enum tls_model model, int for_mov)
+{
+ rtx dest, base, off, pic;
+ int type;
+
+ switch (model)
{
- const char *symbol_str;
- char *newstr;
- size_t len;
- enum tls_model kind = decl_tls_model (decl);
+ case TLS_MODEL_GLOBAL_DYNAMIC:
+ dest = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ {
+ rtx rax = gen_rtx_REG (Pmode, 0), insns;
+
+ start_sequence ();
+ emit_call_insn (gen_tls_global_dynamic_64 (rax, x));
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_libcall_block (insns, dest, rax, x);
+ }
+ else
+ emit_insn (gen_tls_global_dynamic_32 (dest, x));
+ break;
- if (TARGET_64BIT && ! flag_pic)
+ case TLS_MODEL_LOCAL_DYNAMIC:
+ base = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
{
- /* x86-64 doesn't allow non-pic code for shared libraries,
- so don't generate GD/LD TLS models for non-pic code. */
- switch (kind)
- {
- case TLS_MODEL_GLOBAL_DYNAMIC:
- kind = TLS_MODEL_INITIAL_EXEC; break;
- case TLS_MODEL_LOCAL_DYNAMIC:
- kind = TLS_MODEL_LOCAL_EXEC; break;
- default:
- break;
- }
+ rtx rax = gen_rtx_REG (Pmode, 0), insns, note;
+
+ start_sequence ();
+ emit_call_insn (gen_tls_local_dynamic_base_64 (rax));
+ insns = get_insns ();
+ end_sequence ();
+
+ note = gen_rtx_EXPR_LIST (VOIDmode, const0_rtx, NULL);
+ note = gen_rtx_EXPR_LIST (VOIDmode, ix86_tls_get_addr (), note);
+ emit_libcall_block (insns, base, rax, note);
}
+ else
+ emit_insn (gen_tls_local_dynamic_base_32 (base));
+
+ off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
+ off = gen_rtx_CONST (Pmode, off);
- symbol_str = XSTR (symbol, 0);
+ return gen_rtx_PLUS (Pmode, base, off);
- if (symbol_str[0] == '%')
+ case TLS_MODEL_INITIAL_EXEC:
+ if (TARGET_64BIT)
{
- if (symbol_str[1] == tls_model_chars[kind])
- return;
- symbol_str += 2;
+ pic = NULL;
+ type = UNSPEC_GOTNTPOFF;
+ }
+ else if (flag_pic)
+ {
+ if (reload_in_progress)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+ pic = pic_offset_table_rtx;
+ type = TARGET_GNU_TLS ? UNSPEC_GOTNTPOFF : UNSPEC_GOTTPOFF;
+ }
+ else if (!TARGET_GNU_TLS)
+ {
+ pic = gen_reg_rtx (Pmode);
+ emit_insn (gen_set_got (pic));
+ type = UNSPEC_GOTTPOFF;
+ }
+ else
+ {
+ pic = NULL;
+ type = UNSPEC_INDNTPOFF;
}
- len = strlen (symbol_str) + 1;
- newstr = alloca (len + 2);
-
- newstr[0] = '%';
- newstr[1] = tls_model_chars[kind];
- memcpy (newstr + 2, symbol_str, len);
- XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2 - 1);
- }
-}
+ off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), type);
+ off = gen_rtx_CONST (Pmode, off);
+ if (pic)
+ off = gen_rtx_PLUS (Pmode, pic, off);
+ off = gen_rtx_MEM (Pmode, off);
+ RTX_UNCHANGING_P (off) = 1;
+ set_mem_alias_set (off, ix86_GOT_alias_set ());
-/* Undo the above when printing symbol names. */
+ if (TARGET_64BIT || TARGET_GNU_TLS)
+ {
+ base = get_thread_pointer (for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
+ off = force_reg (Pmode, off);
+ return gen_rtx_PLUS (Pmode, base, off);
+ }
+ else
+ {
+ base = get_thread_pointer (true);
+ dest = gen_reg_rtx (Pmode);
+ emit_insn (gen_subsi3 (dest, base, off));
+ }
+ break;
-static const char *
-ix86_strip_name_encoding (str)
- const char *str;
-{
- if (str[0] == '%')
- str += 2;
- if (str [0] == '*')
- str += 1;
- return str;
-}
-
-/* Load the thread pointer into a register. */
+ case TLS_MODEL_LOCAL_EXEC:
+ off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
+ (TARGET_64BIT || TARGET_GNU_TLS)
+ ? UNSPEC_NTPOFF : UNSPEC_TPOFF);
+ off = gen_rtx_CONST (Pmode, off);
-static rtx
-get_thread_pointer ()
-{
- rtx tp;
+ if (TARGET_64BIT || TARGET_GNU_TLS)
+ {
+ base = get_thread_pointer (for_mov || !TARGET_TLS_DIRECT_SEG_REFS);
+ return gen_rtx_PLUS (Pmode, base, off);
+ }
+ else
+ {
+ base = get_thread_pointer (true);
+ dest = gen_reg_rtx (Pmode);
+ emit_insn (gen_subsi3 (dest, base, off));
+ }
+ break;
- tp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_TP);
- tp = gen_rtx_MEM (Pmode, tp);
- RTX_UNCHANGING_P (tp) = 1;
- set_mem_alias_set (tp, ix86_GOT_alias_set ());
- tp = force_reg (Pmode, tp);
+ default:
+ abort ();
+ }
- return tp;
+ return dest;
}
/* Try machine-dependent ways of modifying an illegitimate address
@@ -5979,10 +6550,7 @@ get_thread_pointer ()
See comments by legitimize_pic_address in i386.c for details. */
rtx
-legitimize_address (x, oldx, mode)
- register rtx x;
- register rtx oldx ATTRIBUTE_UNUSED;
- enum machine_mode mode;
+legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode)
{
int changed = 0;
unsigned log;
@@ -5996,120 +6564,7 @@ legitimize_address (x, oldx, mode)
log = tls_symbolic_operand (x, mode);
if (log)
- {
- rtx dest, base, off, pic;
- int type;
-
- switch (log)
- {
- case TLS_MODEL_GLOBAL_DYNAMIC:
- dest = gen_reg_rtx (Pmode);
- if (TARGET_64BIT)
- {
- rtx rax = gen_rtx_REG (Pmode, 0), insns;
-
- start_sequence ();
- emit_call_insn (gen_tls_global_dynamic_64 (rax, x));
- insns = get_insns ();
- end_sequence ();
-
- emit_libcall_block (insns, dest, rax, x);
- }
- else
- emit_insn (gen_tls_global_dynamic_32 (dest, x));
- break;
-
- case TLS_MODEL_LOCAL_DYNAMIC:
- base = gen_reg_rtx (Pmode);
- if (TARGET_64BIT)
- {
- rtx rax = gen_rtx_REG (Pmode, 0), insns, note;
-
- start_sequence ();
- emit_call_insn (gen_tls_local_dynamic_base_64 (rax));
- insns = get_insns ();
- end_sequence ();
-
- note = gen_rtx_EXPR_LIST (VOIDmode, const0_rtx, NULL);
- note = gen_rtx_EXPR_LIST (VOIDmode, ix86_tls_get_addr (), note);
- emit_libcall_block (insns, base, rax, note);
- }
- else
- emit_insn (gen_tls_local_dynamic_base_32 (base));
-
- off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
- off = gen_rtx_CONST (Pmode, off);
-
- return gen_rtx_PLUS (Pmode, base, off);
-
- case TLS_MODEL_INITIAL_EXEC:
- if (TARGET_64BIT)
- {
- pic = NULL;
- type = UNSPEC_GOTNTPOFF;
- }
- else if (flag_pic)
- {
- if (reload_in_progress)
- regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
- pic = pic_offset_table_rtx;
- type = TARGET_GNU_TLS ? UNSPEC_GOTNTPOFF : UNSPEC_GOTTPOFF;
- }
- else if (!TARGET_GNU_TLS)
- {
- pic = gen_reg_rtx (Pmode);
- emit_insn (gen_set_got (pic));
- type = UNSPEC_GOTTPOFF;
- }
- else
- {
- pic = NULL;
- type = UNSPEC_INDNTPOFF;
- }
-
- base = get_thread_pointer ();
-
- off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), type);
- off = gen_rtx_CONST (Pmode, off);
- if (pic)
- off = gen_rtx_PLUS (Pmode, pic, off);
- off = gen_rtx_MEM (Pmode, off);
- RTX_UNCHANGING_P (off) = 1;
- set_mem_alias_set (off, ix86_GOT_alias_set ());
- dest = gen_reg_rtx (Pmode);
-
- if (TARGET_64BIT || TARGET_GNU_TLS)
- {
- emit_move_insn (dest, off);
- return gen_rtx_PLUS (Pmode, base, dest);
- }
- else
- emit_insn (gen_subsi3 (dest, base, off));
- break;
-
- case TLS_MODEL_LOCAL_EXEC:
- base = get_thread_pointer ();
-
- off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
- (TARGET_64BIT || TARGET_GNU_TLS)
- ? UNSPEC_NTPOFF : UNSPEC_TPOFF);
- off = gen_rtx_CONST (Pmode, off);
-
- if (TARGET_64BIT || TARGET_GNU_TLS)
- return gen_rtx_PLUS (Pmode, base, off);
- else
- {
- dest = gen_reg_rtx (Pmode);
- emit_insn (gen_subsi3 (dest, base, off));
- }
- break;
-
- default:
- abort ();
- }
-
- return dest;
- }
+ return legitimize_tls_address (x, log, false);
if (flag_pic && SYMBOLIC_CONST (x))
return legitimize_pic_address (x, 0);
@@ -6235,8 +6690,8 @@ legitimize_address (x, oldx, mode)
if (GET_CODE (XEXP (x, 0)) == REG)
{
- register rtx temp = gen_reg_rtx (Pmode);
- register rtx val = force_operand (XEXP (x, 1), temp);
+ rtx temp = gen_reg_rtx (Pmode);
+ rtx val = force_operand (XEXP (x, 1), temp);
if (val != temp)
emit_move_insn (temp, val);
@@ -6246,8 +6701,8 @@ legitimize_address (x, oldx, mode)
else if (GET_CODE (XEXP (x, 1)) == REG)
{
- register rtx temp = gen_reg_rtx (Pmode);
- register rtx val = force_operand (XEXP (x, 0), temp);
+ rtx temp = gen_reg_rtx (Pmode);
+ rtx val = force_operand (XEXP (x, 0), temp);
if (val != temp)
emit_move_insn (temp, val);
@@ -6265,10 +6720,7 @@ legitimize_address (x, oldx, mode)
CODE is the operand print code from the output string. */
static void
-output_pic_addr_const (file, x, code)
- FILE *file;
- rtx x;
- int code;
+output_pic_addr_const (FILE *file, rtx x, int code)
{
char buf[256];
@@ -6283,7 +6735,7 @@ output_pic_addr_const (file, x, code)
case SYMBOL_REF:
assemble_name (file, XSTR (x, 0));
- if (!TARGET_MACHO && code == 'P' && ! SYMBOL_REF_FLAG (x))
+ if (!TARGET_MACHO && code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
fputs ("@PLT", file);
break;
@@ -6405,9 +6857,7 @@ output_pic_addr_const (file, x, code)
We need to handle our special PIC relocations. */
void
-i386_dwarf_output_addr_const (file, x)
- FILE *file;
- rtx x;
+i386_dwarf_output_addr_const (FILE *file, rtx x)
{
#ifdef ASM_QUAD
fprintf (file, "%s", TARGET_64BIT ? ASM_QUAD : ASM_LONG);
@@ -6427,10 +6877,7 @@ i386_dwarf_output_addr_const (file, x)
We need to emit DTP-relative relocations. */
void
-i386_output_dwarf_dtprel (file, size, x)
- FILE *file;
- int size;
- rtx x;
+i386_output_dwarf_dtprel (FILE *file, int size, rtx x)
{
fputs (ASM_LONG, file);
output_addr_const (file, x);
@@ -6451,9 +6898,8 @@ i386_output_dwarf_dtprel (file, size, x)
general assembler losage, recognize PIC+GOTOFF and turn it back
into a direct symbol reference. */
-rtx
-i386_simplify_dwarf_addr (orig_x)
- rtx orig_x;
+static rtx
+ix86_delegitimize_address (rtx orig_x)
{
rtx x = orig_x, y;
@@ -6525,11 +6971,8 @@ i386_simplify_dwarf_addr (orig_x)
}
static void
-put_condition_code (code, mode, reverse, fp, file)
- enum rtx_code code;
- enum machine_mode mode;
- int reverse, fp;
- FILE *file;
+put_condition_code (enum rtx_code code, enum machine_mode mode, int reverse,
+ int fp, FILE *file)
{
const char *suffix;
@@ -6614,11 +7057,16 @@ put_condition_code (code, mode, reverse, fp, file)
fputs (suffix, file);
}
+/* Print the name of register X to FILE based on its machine mode and number.
+ If CODE is 'w', pretend the mode is HImode.
+ If CODE is 'b', pretend the mode is QImode.
+ If CODE is 'k', pretend the mode is SImode.
+ If CODE is 'q', pretend the mode is DImode.
+ If CODE is 'h', pretend the reg is the `high' byte register.
+ If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op. */
+
void
-print_reg (x, code, file)
- rtx x;
- int code;
- FILE *file;
+print_reg (rtx x, int code, FILE *file)
{
if (REGNO (x) == ARG_POINTER_REGNUM
|| REGNO (x) == FRAME_POINTER_REGNUM
@@ -6690,12 +7138,17 @@ print_reg (x, code, file)
/* FALLTHRU */
case 16:
case 2:
+ normal:
fputs (hi_reg_name[REGNO (x)], file);
break;
case 1:
+ if (REGNO (x) >= ARRAY_SIZE (qi_reg_name))
+ goto normal;
fputs (qi_reg_name[REGNO (x)], file);
break;
case 0:
+ if (REGNO (x) >= ARRAY_SIZE (qi_high_reg_name))
+ goto normal;
fputs (qi_high_reg_name[REGNO (x)], file);
break;
default:
@@ -6708,7 +7161,7 @@ print_reg (x, code, file)
pattern. */
static const char *
-get_some_local_dynamic_name ()
+get_some_local_dynamic_name (void)
{
rtx insn;
@@ -6724,9 +7177,7 @@ get_some_local_dynamic_name ()
}
static int
-get_some_local_dynamic_name_1 (px, data)
- rtx *px;
- void *data ATTRIBUTE_UNUSED;
+get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
{
rtx x = *px;
@@ -6768,10 +7219,7 @@ get_some_local_dynamic_name_1 (px, data)
*/
void
-print_operand (file, x, code)
- FILE *file;
- rtx x;
- int code;
+print_operand (FILE *file, rtx x, int code)
{
if (code)
{
@@ -7014,7 +7462,7 @@ print_operand (file, x, code)
int cputaken = final_forward_branch_p (current_output_insn) == 0;
/* Emit hints only in the case default branch prediction
- heruistics would fail. */
+ heuristics would fail. */
if (taken != cputaken)
{
/* We use 3e (DS) prefix for taken branches and
@@ -7034,9 +7482,7 @@ print_operand (file, x, code)
}
if (GET_CODE (x) == REG)
- {
- PRINT_REG (x, code, file);
- }
+ print_reg (x, code, file);
else if (GET_CODE (x) == MEM)
{
@@ -7069,10 +7515,8 @@ print_operand (file, x, code)
}
x = XEXP (x, 0);
- if (flag_pic && CONSTANT_ADDRESS_P (x))
- output_pic_addr_const (file, x, code);
/* Avoid (%rip) for call operands. */
- else if (CONSTANT_ADDRESS_P (x) && code == 'P'
+ if (CONSTANT_ADDRESS_P (x) && code == 'P'
&& GET_CODE (x) != CONST_INT)
output_addr_const (file, x);
else if (this_is_asm_operands && ! address_operand (x, VOIDmode))
@@ -7091,11 +7535,11 @@ print_operand (file, x, code)
if (ASSEMBLER_DIALECT == ASM_ATT)
putc ('$', file);
- fprintf (file, "0x%lx", l);
+ fprintf (file, "0x%08lx", l);
}
- /* These float cases don't actually occur as immediate operands. */
- else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
+ /* These float cases don't actually occur as immediate operands. */
+ else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
{
char dstr[30];
@@ -7104,7 +7548,7 @@ print_operand (file, x, code)
}
else if (GET_CODE (x) == CONST_DOUBLE
- && (GET_MODE (x) == XFmode || GET_MODE (x) == TFmode))
+ && GET_MODE (x) == XFmode)
{
char dstr[30];
@@ -7142,27 +7586,12 @@ print_operand (file, x, code)
/* Print a memory operand whose address is ADDR. */
void
-print_operand_address (file, addr)
- FILE *file;
- register rtx addr;
+print_operand_address (FILE *file, rtx addr)
{
struct ix86_address parts;
rtx base, index, disp;
int scale;
- if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_TP)
- {
- if (ASSEMBLER_DIALECT == ASM_INTEL)
- fputs ("DWORD PTR ", file);
- if (ASSEMBLER_DIALECT == ASM_ATT || USER_LABEL_PREFIX[0] == 0)
- putc ('%', file);
- if (TARGET_64BIT)
- fputs ("fs:0", file);
- else
- fputs ("gs:0", file);
- return;
- }
-
if (! ix86_decompose_address (addr, &parts))
abort ();
@@ -7171,35 +7600,49 @@ print_operand_address (file, addr)
disp = parts.disp;
scale = parts.scale;
+ switch (parts.seg)
+ {
+ case SEG_DEFAULT:
+ break;
+ case SEG_FS:
+ case SEG_GS:
+ if (USER_LABEL_PREFIX[0] == 0)
+ putc ('%', file);
+ fputs ((parts.seg == SEG_FS ? "fs:" : "gs:"), file);
+ break;
+ default:
+ abort ();
+ }
+
if (!base && !index)
{
/* Displacement only requires special attention. */
if (GET_CODE (disp) == CONST_INT)
{
- if (ASSEMBLER_DIALECT == ASM_INTEL)
+ if (ASSEMBLER_DIALECT == ASM_INTEL && parts.seg == SEG_DEFAULT)
{
if (USER_LABEL_PREFIX[0] == 0)
putc ('%', file);
fputs ("ds:", file);
}
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (addr));
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (disp));
}
else if (flag_pic)
- output_pic_addr_const (file, addr, 0);
+ output_pic_addr_const (file, disp, 0);
else
- output_addr_const (file, addr);
+ output_addr_const (file, disp);
/* Use one byte shorter RIP relative addressing for 64bit mode. */
if (TARGET_64BIT
- && ((GET_CODE (addr) == SYMBOL_REF
- && ! tls_symbolic_operand (addr, GET_MODE (addr)))
- || GET_CODE (addr) == LABEL_REF
- || (GET_CODE (addr) == CONST
- && GET_CODE (XEXP (addr, 0)) == PLUS
- && (GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF
- || GET_CODE (XEXP (XEXP (addr, 0), 0)) == LABEL_REF)
- && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)))
+ && ((GET_CODE (disp) == SYMBOL_REF
+ && ! tls_symbolic_operand (disp, GET_MODE (disp)))
+ || GET_CODE (disp) == LABEL_REF
+ || (GET_CODE (disp) == CONST
+ && GET_CODE (XEXP (disp, 0)) == PLUS
+ && (GET_CODE (XEXP (XEXP (disp, 0), 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (XEXP (disp, 0), 0)) == LABEL_REF)
+ && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT)))
fputs ("(%rip)", file);
}
else
@@ -7218,11 +7661,11 @@ print_operand_address (file, addr)
putc ('(', file);
if (base)
- PRINT_REG (base, 0, file);
+ print_reg (base, 0, file);
if (index)
{
putc (',', file);
- PRINT_REG (index, 0, file);
+ print_reg (index, 0, file);
if (scale != 1)
fprintf (file, ",%d", scale);
}
@@ -7257,7 +7700,7 @@ print_operand_address (file, addr)
putc ('[', file);
if (base)
{
- PRINT_REG (base, 0, file);
+ print_reg (base, 0, file);
if (offset)
{
if (INTVAL (offset) >= 0)
@@ -7273,7 +7716,7 @@ print_operand_address (file, addr)
if (index)
{
putc ('+', file);
- PRINT_REG (index, 0, file);
+ print_reg (index, 0, file);
if (scale != 1)
fprintf (file, "*%d", scale);
}
@@ -7283,9 +7726,7 @@ print_operand_address (file, addr)
}
bool
-output_addr_const_extra (file, x)
- FILE *file;
- rtx x;
+output_addr_const_extra (FILE *file, rtx x)
{
rtx op;
@@ -7341,10 +7782,7 @@ output_addr_const_extra (file, x)
that parallel "operands". */
void
-split_di (operands, num, lo_half, hi_half)
- rtx operands[];
- int num;
- rtx lo_half[], hi_half[];
+split_di (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
{
while (num--)
{
@@ -7375,10 +7813,7 @@ split_di (operands, num, lo_half, hi_half)
that parallel "operands". */
void
-split_ti (operands, num, lo_half, hi_half)
- rtx operands[];
- int num;
- rtx lo_half[], hi_half[];
+split_ti (rtx operands[], int num, rtx lo_half[], rtx hi_half[])
{
while (num--)
{
@@ -7417,9 +7852,7 @@ split_ti (operands, num, lo_half, hi_half)
#endif
const char *
-output_387_binary_op (insn, operands)
- rtx insn;
- rtx *operands;
+output_387_binary_op (rtx insn, rtx *operands)
{
static char buf[30];
const char *p;
@@ -7627,8 +8060,7 @@ output_387_binary_op (insn, operands)
trunc?f?i patterns. NORMAL is set to current control word, while ROUND_DOWN
is set to control word rounding downwards. */
void
-emit_i387_cw_initialization (normal, round_down)
- rtx normal, round_down;
+emit_i387_cw_initialization (rtx normal, rtx round_down)
{
rtx reg = gen_reg_rtx (HImode);
@@ -7647,9 +8079,7 @@ emit_i387_cw_initialization (normal, round_down)
operand may be [SDX]Fmode. */
const char *
-output_fix_trunc (insn, operands)
- rtx insn;
- rtx *operands;
+output_fix_trunc (rtx insn, rtx *operands)
{
int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
int dimode_p = GET_MODE (operands[0]) == DImode;
@@ -7681,10 +8111,7 @@ output_fix_trunc (insn, operands)
when fucom should be used. */
const char *
-output_fp_compare (insn, operands, eflags_p, unordered_p)
- rtx insn;
- rtx *operands;
- int eflags_p, unordered_p;
+output_fp_compare (rtx insn, rtx *operands, int eflags_p, int unordered_p)
{
int stack_top_dies;
rtx cmp_op0 = operands[0];
@@ -7808,9 +8235,7 @@ output_fp_compare (insn, operands, eflags_p, unordered_p)
}
void
-ix86_output_addr_vec_elt (file, value)
- FILE *file;
- int value;
+ix86_output_addr_vec_elt (FILE *file, int value)
{
const char *directive = ASM_LONG;
@@ -7827,9 +8252,7 @@ ix86_output_addr_vec_elt (file, value)
}
void
-ix86_output_addr_diff_elt (file, value, rel)
- FILE *file;
- int value, rel;
+ix86_output_addr_diff_elt (FILE *file, int value, int rel)
{
if (TARGET_64BIT)
fprintf (file, "%s%s%d-%s%d\n",
@@ -7838,8 +8261,11 @@ ix86_output_addr_diff_elt (file, value, rel)
fprintf (file, "%s%s%d@GOTOFF\n", ASM_LONG, LPREFIX, value);
#if TARGET_MACHO
else if (TARGET_MACHO)
- fprintf (file, "%s%s%d-%s\n", ASM_LONG, LPREFIX, value,
- machopic_function_base_name () + 1);
+ {
+ fprintf (file, "%s%s%d-", ASM_LONG, LPREFIX, value);
+ machopic_output_function_base_name (file);
+ fprintf(file, "\n");
+ }
#endif
else
asm_fprintf (file, "%s%U%s+[.-%s%d]\n",
@@ -7850,8 +8276,7 @@ ix86_output_addr_diff_elt (file, value, rel)
for the target. */
void
-ix86_expand_clear (dest)
- rtx dest;
+ix86_expand_clear (rtx dest)
{
rtx tmp;
@@ -7879,27 +8304,9 @@ ix86_expand_clear (dest)
the constant pool rtx, else NULL. */
static rtx
-maybe_get_pool_constant (x)
- rtx x;
+maybe_get_pool_constant (rtx x)
{
- x = XEXP (x, 0);
-
- if (flag_pic && ! TARGET_64BIT)
- {
- if (GET_CODE (x) != PLUS)
- return NULL_RTX;
- if (XEXP (x, 0) != pic_offset_table_rtx)
- return NULL_RTX;
- x = XEXP (x, 1);
- if (GET_CODE (x) != CONST)
- return NULL_RTX;
- x = XEXP (x, 0);
- if (GET_CODE (x) != UNSPEC)
- return NULL_RTX;
- if (XINT (x, 1) != UNSPEC_GOTOFF)
- return NULL_RTX;
- x = XVECEXP (x, 0, 0);
- }
+ x = ix86_delegitimize_address (XEXP (x, 0));
if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
return get_pool_constant (x);
@@ -7908,27 +8315,25 @@ maybe_get_pool_constant (x)
}
void
-ix86_expand_move (mode, operands)
- enum machine_mode mode;
- rtx operands[];
+ix86_expand_move (enum machine_mode mode, rtx operands[])
{
int strict = (reload_in_progress || reload_completed);
- rtx insn, op0, op1, tmp;
+ rtx op0, op1;
+ enum tls_model model;
op0 = operands[0];
op1 = operands[1];
- if (tls_symbolic_operand (op1, Pmode))
+ model = tls_symbolic_operand (op1, Pmode);
+ if (model)
{
- op1 = legitimize_address (op1, op1, VOIDmode);
- if (GET_CODE (op0) == MEM)
- {
- tmp = gen_reg_rtx (mode);
- emit_insn (gen_rtx_SET (VOIDmode, tmp, op1));
- op1 = tmp;
- }
+ op1 = legitimize_tls_address (op1, model, true);
+ op1 = force_operand (op1, op0);
+ if (op1 == op0)
+ return;
}
- else if (flag_pic && mode == Pmode && symbolic_operand (op1, Pmode))
+
+ if (flag_pic && mode == Pmode && symbolic_operand (op1, Pmode))
{
#if TARGET_MACHO
if (MACHOPIC_PURE)
@@ -7941,18 +8346,11 @@ ix86_expand_move (mode, operands)
op1 = machopic_legitimize_pic_address (op1, mode,
temp == op1 ? 0 : temp);
}
- else
- {
- if (MACHOPIC_INDIRECT)
- op1 = machopic_indirect_data_reference (op1, 0);
- }
- if (op0 != op1)
- {
- insn = gen_rtx_SET (VOIDmode, op0, op1);
- emit_insn (insn);
- }
- return;
-#endif /* TARGET_MACHO */
+ else if (MACHOPIC_INDIRECT)
+ op1 = machopic_indirect_data_reference (op1, 0);
+ if (op0 == op1)
+ return;
+#else
if (GET_CODE (op0) == MEM)
op1 = force_reg (Pmode, op1);
else
@@ -7965,6 +8363,7 @@ ix86_expand_move (mode, operands)
return;
op1 = temp;
}
+#endif /* TARGET_MACHO */
}
else
{
@@ -8009,15 +8408,11 @@ ix86_expand_move (mode, operands)
}
}
- insn = gen_rtx_SET (VOIDmode, op0, op1);
-
- emit_insn (insn);
+ emit_insn (gen_rtx_SET (VOIDmode, op0, op1));
}
void
-ix86_expand_vector_move (mode, operands)
- enum machine_mode mode;
- rtx operands[];
+ix86_expand_vector_move (enum machine_mode mode, rtx operands[])
{
/* Force constants other than zero into memory. We do not know how
the instructions used to build constants modify the upper 64 bits
@@ -8026,11 +8421,7 @@ ix86_expand_vector_move (mode, operands)
if ((reload_in_progress | reload_completed) == 0
&& register_operand (operands[0], mode)
&& CONSTANT_P (operands[1]) && operands[1] != CONST0_RTX (mode))
- {
- operands[1] = force_const_mem (mode, operands[1]);
- emit_move_insn (operands[0], operands[1]);
- return;
- }
+ operands[1] = validize_mem (force_const_mem (mode, operands[1]));
/* Make operand1 a register if it isn't already. */
if (!no_new_pseudos
@@ -8050,10 +8441,8 @@ ix86_expand_vector_move (mode, operands)
memory references (one output, two input) in a single insn. */
void
-ix86_expand_binary_operator (code, mode, operands)
- enum rtx_code code;
- enum machine_mode mode;
- rtx operands[];
+ix86_expand_binary_operator (enum rtx_code code, enum machine_mode mode,
+ rtx operands[])
{
int matching_memory;
rtx src1, src2, dst, op, clob;
@@ -8139,10 +8528,9 @@ ix86_expand_binary_operator (code, mode, operands)
appropriate constraints. */
int
-ix86_binary_operator_ok (code, mode, operands)
- enum rtx_code code;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx operands[3];
+ix86_binary_operator_ok (enum rtx_code code,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx operands[3])
{
/* Both source operands cannot be in memory. */
if (GET_CODE (operands[1]) == MEM && GET_CODE (operands[2]) == MEM)
@@ -8170,10 +8558,8 @@ ix86_binary_operator_ok (code, mode, operands)
memory references (one output, one input) in a single insn. */
void
-ix86_expand_unary_operator (code, mode, operands)
- enum rtx_code code;
- enum machine_mode mode;
- rtx operands[];
+ix86_expand_unary_operator (enum rtx_code code, enum machine_mode mode,
+ rtx operands[])
{
int matching_memory;
rtx src, dst, op, clob;
@@ -8231,10 +8617,9 @@ ix86_expand_unary_operator (code, mode, operands)
appropriate constraints. */
int
-ix86_unary_operator_ok (code, mode, operands)
- enum rtx_code code ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx operands[2] ATTRIBUTE_UNUSED;
+ix86_unary_operator_ok (enum rtx_code code ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx operands[2] ATTRIBUTE_UNUSED)
{
/* If one of operands is memory, source and destination must match. */
if ((GET_CODE (operands[0]) == MEM
@@ -8249,9 +8634,7 @@ ix86_unary_operator_ok (code, mode, operands)
CC mode is at least as constrained as REQ_MODE. */
int
-ix86_match_ccmode (insn, req_mode)
- rtx insn;
- enum machine_mode req_mode;
+ix86_match_ccmode (rtx insn, enum machine_mode req_mode)
{
rtx set;
enum machine_mode set_mode;
@@ -8298,9 +8681,7 @@ ix86_match_ccmode (insn, req_mode)
/* Generate insn patterns to do an integer compare of OPERANDS. */
static rtx
-ix86_expand_int_compare (code, op0, op1)
- enum rtx_code code;
- rtx op0, op1;
+ix86_expand_int_compare (enum rtx_code code, rtx op0, rtx op1)
{
enum machine_mode cmpmode;
rtx tmp, flags;
@@ -8322,8 +8703,7 @@ ix86_expand_int_compare (code, op0, op1)
Return the appropriate mode to use. */
enum machine_mode
-ix86_fp_compare_mode (code)
- enum rtx_code code ATTRIBUTE_UNUSED;
+ix86_fp_compare_mode (enum rtx_code code ATTRIBUTE_UNUSED)
{
/* ??? In order to make all comparisons reversible, we do all comparisons
non-trapping when compiling for IEEE. Once gcc is able to distinguish
@@ -8334,9 +8714,7 @@ ix86_fp_compare_mode (code)
}
enum machine_mode
-ix86_cc_mode (code, op0, op1)
- enum rtx_code code;
- rtx op0, op1;
+ix86_cc_mode (enum rtx_code code, rtx op0, rtx op1)
{
if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
return ix86_fp_compare_mode (code);
@@ -8363,7 +8741,7 @@ ix86_cc_mode (code, op0, op1)
return CCGCmode;
/* Codes doable only with sign flag when comparing
against zero, but we miss jump instruction for it
- so we need to use relational tests agains overflow
+ so we need to use relational tests against overflow
that thus needs to be zero. */
case GT: /* ZF=0 & SF=OF */
case LE: /* ZF=1 | SF<>OF */
@@ -8380,11 +8758,68 @@ ix86_cc_mode (code, op0, op1)
}
}
+/* Return the fixed registers used for condition codes. */
+
+static bool
+ix86_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
+{
+ *p1 = FLAGS_REG;
+ *p2 = FPSR_REG;
+ return true;
+}
+
+/* If two condition code modes are compatible, return a condition code
+ mode which is compatible with both. Otherwise, return
+ VOIDmode. */
+
+static enum machine_mode
+ix86_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
+{
+ if (m1 == m2)
+ return m1;
+
+ if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
+ return VOIDmode;
+
+ if ((m1 == CCGCmode && m2 == CCGOCmode)
+ || (m1 == CCGOCmode && m2 == CCGCmode))
+ return CCGCmode;
+
+ switch (m1)
+ {
+ default:
+ abort ();
+
+ case CCmode:
+ case CCGCmode:
+ case CCGOCmode:
+ case CCNOmode:
+ case CCZmode:
+ switch (m2)
+ {
+ default:
+ return VOIDmode;
+
+ case CCmode:
+ case CCGCmode:
+ case CCGOCmode:
+ case CCNOmode:
+ case CCZmode:
+ return CCmode;
+ }
+
+ case CCFPmode:
+ case CCFPUmode:
+ /* These are only compatible with themselves, which we already
+ checked above. */
+ return VOIDmode;
+ }
+}
+
/* Return true if we should use an FCOMI instruction for this fp comparison. */
int
-ix86_use_fcomi_compare (code)
- enum rtx_code code ATTRIBUTE_UNUSED;
+ix86_use_fcomi_compare (enum rtx_code code ATTRIBUTE_UNUSED)
{
enum rtx_code swapped_code = swap_condition (code);
return ((ix86_fp_comparison_cost (code) == ix86_fp_comparison_fcomi_cost (code))
@@ -8394,12 +8829,10 @@ ix86_use_fcomi_compare (code)
/* Swap, force into registers, or otherwise massage the two operands
to a fp comparison. The operands are updated in place; the new
- comparsion code is returned. */
+ comparison code is returned. */
static enum rtx_code
-ix86_prepare_fp_compare_args (code, pop0, pop1)
- enum rtx_code code;
- rtx *pop0, *pop1;
+ix86_prepare_fp_compare_args (enum rtx_code code, rtx *pop0, rtx *pop1)
{
enum machine_mode fpcmp_mode = ix86_fp_compare_mode (code);
rtx op0 = *pop0, op1 = *pop1;
@@ -8413,7 +8846,6 @@ ix86_prepare_fp_compare_args (code, pop0, pop1)
if (!is_sse
&& (fpcmp_mode == CCFPUmode
|| op_mode == XFmode
- || op_mode == TFmode
|| ix86_use_fcomi_compare (code)))
{
op0 = force_reg (op_mode, op0);
@@ -8468,8 +8900,7 @@ ix86_prepare_fp_compare_args (code, pop0, pop1)
code that will result in proper branch. Return UNKNOWN if no such code
is available. */
static enum rtx_code
-ix86_fp_compare_code_to_integer (code)
- enum rtx_code code;
+ix86_fp_compare_code_to_integer (enum rtx_code code)
{
switch (code)
{
@@ -8504,8 +8935,9 @@ ix86_fp_compare_code_to_integer (code)
is not required, set value to NIL.
We never require more than two branches. */
static void
-ix86_fp_comparison_codes (code, bypass_code, first_code, second_code)
- enum rtx_code code, *bypass_code, *first_code, *second_code;
+ix86_fp_comparison_codes (enum rtx_code code, enum rtx_code *bypass_code,
+ enum rtx_code *first_code,
+ enum rtx_code *second_code)
{
*first_code = code;
*bypass_code = NIL;
@@ -8565,12 +8997,11 @@ ix86_fp_comparison_codes (code, bypass_code, first_code, second_code)
}
/* Return cost of comparison done fcom + arithmetics operations on AX.
- All following functions do use number of instructions as an cost metrics.
+ All following functions do use number of instructions as a cost metrics.
In future this should be tweaked to compute bytes for optimize_size and
take into account performance of various instructions on various CPUs. */
static int
-ix86_fp_comparison_arithmetics_cost (code)
- enum rtx_code code;
+ix86_fp_comparison_arithmetics_cost (enum rtx_code code)
{
if (!TARGET_IEEE_FP)
return 4;
@@ -8605,11 +9036,10 @@ ix86_fp_comparison_arithmetics_cost (code)
/* Return cost of comparison done using fcomi operation.
See ix86_fp_comparison_arithmetics_cost for the metrics. */
static int
-ix86_fp_comparison_fcomi_cost (code)
- enum rtx_code code;
+ix86_fp_comparison_fcomi_cost (enum rtx_code code)
{
enum rtx_code bypass_code, first_code, second_code;
- /* Return arbitarily high cost when instruction is not supported - this
+ /* Return arbitrarily high cost when instruction is not supported - this
prevents gcc from using it. */
if (!TARGET_CMOVE)
return 1024;
@@ -8620,11 +9050,10 @@ ix86_fp_comparison_fcomi_cost (code)
/* Return cost of comparison done using sahf operation.
See ix86_fp_comparison_arithmetics_cost for the metrics. */
static int
-ix86_fp_comparison_sahf_cost (code)
- enum rtx_code code;
+ix86_fp_comparison_sahf_cost (enum rtx_code code)
{
enum rtx_code bypass_code, first_code, second_code;
- /* Return arbitarily high cost when instruction is not preferred - this
+ /* Return arbitrarily high cost when instruction is not preferred - this
avoids gcc from using it. */
if (!TARGET_USE_SAHF && !optimize_size)
return 1024;
@@ -8635,8 +9064,7 @@ ix86_fp_comparison_sahf_cost (code)
/* Compute cost of the comparison done using any method.
See ix86_fp_comparison_arithmetics_cost for the metrics. */
static int
-ix86_fp_comparison_cost (code)
- enum rtx_code code;
+ix86_fp_comparison_cost (enum rtx_code code)
{
int fcomi_cost, sahf_cost, arithmetics_cost = 1024;
int min;
@@ -8655,11 +9083,8 @@ ix86_fp_comparison_cost (code)
/* Generate insn patterns to do a floating point compare of OPERANDS. */
static rtx
-ix86_expand_fp_compare (code, op0, op1, scratch, second_test, bypass_test)
- enum rtx_code code;
- rtx op0, op1, scratch;
- rtx *second_test;
- rtx *bypass_test;
+ix86_expand_fp_compare (enum rtx_code code, rtx op0, rtx op1, rtx scratch,
+ rtx *second_test, rtx *bypass_test)
{
enum machine_mode fpcmp_mode, intcmp_mode;
rtx tmp, tmp2;
@@ -8843,9 +9268,7 @@ ix86_expand_fp_compare (code, op0, op1, scratch, second_test, bypass_test)
}
rtx
-ix86_expand_compare (code, second_test, bypass_test)
- enum rtx_code code;
- rtx *second_test, *bypass_test;
+ix86_expand_compare (enum rtx_code code, rtx *second_test, rtx *bypass_test)
{
rtx op0, op1, ret;
op0 = ix86_compare_op0;
@@ -8867,8 +9290,7 @@ ix86_expand_compare (code, second_test, bypass_test)
/* Return true if the CODE will result in nontrivial jump sequence. */
bool
-ix86_fp_jump_nontrivial_p (code)
- enum rtx_code code;
+ix86_fp_jump_nontrivial_p (enum rtx_code code)
{
enum rtx_code bypass_code, first_code, second_code;
if (!TARGET_CMOVE)
@@ -8878,9 +9300,7 @@ ix86_fp_jump_nontrivial_p (code)
}
void
-ix86_expand_branch (code, label)
- enum rtx_code code;
- rtx label;
+ix86_expand_branch (enum rtx_code code, rtx label)
{
rtx tmp;
@@ -8900,7 +9320,6 @@ ix86_expand_branch (code, label)
case SFmode:
case DFmode:
case XFmode:
- case TFmode:
{
rtvec vec;
int use_fcomi;
@@ -9066,9 +9485,8 @@ ix86_expand_branch (code, label)
/* Split branch based on floating point condition. */
void
-ix86_split_fp_branch (code, op1, op2, target1, target2, tmp)
- enum rtx_code code;
- rtx op1, op2, target1, target2, tmp;
+ix86_split_fp_branch (enum rtx_code code, rtx op1, rtx op2,
+ rtx target1, rtx target2, rtx tmp)
{
rtx second, bypass;
rtx label = NULL_RTX;
@@ -9144,11 +9562,9 @@ ix86_split_fp_branch (code, op1, op2, target1, target2, tmp)
}
int
-ix86_expand_setcc (code, dest)
- enum rtx_code code;
- rtx dest;
+ix86_expand_setcc (enum rtx_code code, rtx dest)
{
- rtx ret, tmp, tmpreg;
+ rtx ret, tmp, tmpreg, equiv;
rtx second_test, bypass_test;
if (GET_MODE (ix86_compare_op0) == DImode
@@ -9187,41 +9603,150 @@ ix86_expand_setcc (code, dest)
emit_insn (gen_iorqi3 (tmp, tmpreg, tmp2));
}
+ /* Attach a REG_EQUAL note describing the comparison result. */
+ equiv = simplify_gen_relational (code, QImode,
+ GET_MODE (ix86_compare_op0),
+ 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
+ successful and set pop for the operation. */
+static bool
+ix86_expand_carry_flag_compare (enum rtx_code code, rtx op0, rtx op1, rtx *pop)
+{
+ enum machine_mode mode =
+ GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
+
+ /* Do not handle DImode compares that go trought special path. Also we can't
+ deal with FP compares yet. This is possible to add. */
+ if ((mode == DImode && !TARGET_64BIT))
+ return false;
+ if (FLOAT_MODE_P (mode))
+ {
+ rtx second_test = NULL, bypass_test = NULL;
+ rtx compare_op, compare_seq;
+
+ /* Shortcut: following common codes never translate into carry flag compares. */
+ if (code == EQ || code == NE || code == UNEQ || code == LTGT
+ || code == ORDERED || code == UNORDERED)
+ return false;
+
+ /* These comparisons require zero flag; swap operands so they won't. */
+ if ((code == GT || code == UNLE || code == LE || code == UNGT)
+ && !TARGET_IEEE_FP)
+ {
+ rtx tmp = op0;
+ op0 = op1;
+ op1 = tmp;
+ code = swap_condition (code);
+ }
+
+ /* Try to expand the comparison and verify that we end up with carry flag
+ based comparison. This is fails to be true only when we decide to expand
+ comparison using arithmetic that is not too common scenario. */
+ start_sequence ();
+ compare_op = ix86_expand_fp_compare (code, op0, op1, NULL_RTX,
+ &second_test, &bypass_test);
+ compare_seq = get_insns ();
+ end_sequence ();
+
+ if (second_test || bypass_test)
+ return false;
+ if (GET_MODE (XEXP (compare_op, 0)) == CCFPmode
+ || GET_MODE (XEXP (compare_op, 0)) == CCFPUmode)
+ code = ix86_fp_compare_code_to_integer (GET_CODE (compare_op));
+ else
+ code = GET_CODE (compare_op);
+ if (code != LTU && code != GEU)
+ return false;
+ emit_insn (compare_seq);
+ *pop = compare_op;
+ return true;
+ }
+ if (!INTEGRAL_MODE_P (mode))
+ return false;
+ switch (code)
+ {
+ case LTU:
+ case GEU:
+ break;
+
+ /* Convert a==0 into (unsigned)a<1. */
+ case EQ:
+ case NE:
+ if (op1 != const0_rtx)
+ return false;
+ op1 = const1_rtx;
+ code = (code == EQ ? LTU : GEU);
+ break;
+
+ /* Convert a>b into b<a or a>=b-1. */
+ case GTU:
+ case LEU:
+ if (GET_CODE (op1) == CONST_INT)
+ {
+ op1 = gen_int_mode (INTVAL (op1) + 1, GET_MODE (op0));
+ /* Bail out on overflow. We still can swap operands but that
+ would force loading of the constant into register. */
+ if (op1 == const0_rtx
+ || !x86_64_immediate_operand (op1, GET_MODE (op1)))
+ return false;
+ code = (code == GTU ? GEU : LTU);
+ }
+ else
+ {
+ rtx tmp = op1;
+ op1 = op0;
+ op0 = tmp;
+ code = (code == GTU ? LTU : GEU);
+ }
+ break;
+
+ /* Convert a>=0 into (unsigned)a<0x80000000. */
+ case LT:
+ case GE:
+ if (mode == DImode || op1 != const0_rtx)
+ return false;
+ op1 = gen_int_mode (1 << (GET_MODE_BITSIZE (mode) - 1), mode);
+ code = (code == LT ? GEU : LTU);
+ break;
+ case LE:
+ case GT:
+ if (mode == DImode || op1 != constm1_rtx)
+ return false;
+ op1 = gen_int_mode (1 << (GET_MODE_BITSIZE (mode) - 1), mode);
+ code = (code == LE ? GEU : LTU);
+ break;
+
+ default:
+ return false;
+ }
+ /* Swapping operands may cause constant to appear as first operand. */
+ if (!nonimmediate_operand (op0, VOIDmode))
+ {
+ if (no_new_pseudos)
+ return false;
+ op0 = force_reg (mode, op0);
+ }
+ ix86_compare_op0 = op0;
+ ix86_compare_op1 = op1;
+ *pop = ix86_expand_compare (code, NULL, NULL);
+ if (GET_CODE (*pop) != LTU && GET_CODE (*pop) != GEU)
+ abort ();
+ return true;
+}
+
int
-ix86_expand_int_movcc (operands)
- rtx operands[];
+ix86_expand_int_movcc (rtx operands[])
{
enum rtx_code code = GET_CODE (operands[1]), compare_code;
rtx compare_seq, compare_op;
rtx second_test, bypass_test;
enum machine_mode mode = GET_MODE (operands[0]);
-
- /* When the compare code is not LTU or GEU, we can not use sbbl case.
- In case comparsion is done with immediate, we can convert it to LTU or
- GEU by altering the integer. */
-
- if ((code == LEU || code == GTU)
- && GET_CODE (ix86_compare_op1) == CONST_INT
- && mode != HImode
- && INTVAL (ix86_compare_op1) != -1
- /* For x86-64, the immediate field in the instruction is 32-bit
- signed, so we can't increment a DImode value above 0x7fffffff. */
- && (!TARGET_64BIT
- || GET_MODE (ix86_compare_op0) != DImode
- || INTVAL (ix86_compare_op1) != 0x7fffffff)
- && GET_CODE (operands[2]) == CONST_INT
- && GET_CODE (operands[3]) == CONST_INT)
- {
- if (code == LEU)
- code = LTU;
- else
- code = GEU;
- ix86_compare_op1 = gen_int_mode (INTVAL (ix86_compare_op1) + 1,
- GET_MODE (ix86_compare_op0));
- }
+ bool sign_bit_compare_p = false;;
start_sequence ();
compare_op = ix86_expand_compare (code, &second_test, &bypass_test);
@@ -9230,10 +9755,14 @@ ix86_expand_int_movcc (operands)
compare_code = GET_CODE (compare_op);
+ if ((ix86_compare_op1 == const0_rtx && (code == GE || code == LT))
+ || (ix86_compare_op1 == constm1_rtx && (code == GT || code == LE)))
+ sign_bit_compare_p = true;
+
/* Don't attempt mode expansion here -- if we had to expand 5 or 6
HImode insns, we'd be swallowed in word prefix ops. */
- if (mode != HImode
+ if ((mode != HImode || TARGET_FAST_PREFIX)
&& (mode != DImode || TARGET_64BIT)
&& GET_CODE (operands[2]) == CONST_INT
&& GET_CODE (operands[3]) == CONST_INT)
@@ -9243,32 +9772,72 @@ ix86_expand_int_movcc (operands)
HOST_WIDE_INT cf = INTVAL (operands[3]);
HOST_WIDE_INT diff;
- if ((compare_code == LTU || compare_code == GEU)
- && !second_test && !bypass_test)
+ diff = ct - cf;
+ /* Sign bit compares are better done using shifts than we do by using
+ sbb. */
+ if (sign_bit_compare_p
+ || ix86_expand_carry_flag_compare (code, ix86_compare_op0,
+ ix86_compare_op1, &compare_op))
{
/* Detect overlap between destination and compare sources. */
rtx tmp = out;
- /* To simplify rest of code, restrict to the GEU case. */
- if (compare_code == LTU)
+ if (!sign_bit_compare_p)
{
- HOST_WIDE_INT tmp = ct;
- ct = cf;
- cf = tmp;
- compare_code = reverse_condition (compare_code);
- code = reverse_condition (code);
- }
- diff = ct - cf;
+ bool fpcmp = false;
- if (reg_overlap_mentioned_p (out, ix86_compare_op0)
- || reg_overlap_mentioned_p (out, ix86_compare_op1))
- tmp = gen_reg_rtx (mode);
+ compare_code = GET_CODE (compare_op);
- emit_insn (compare_seq);
- if (mode == DImode)
- emit_insn (gen_x86_movdicc_0_m1_rex64 (tmp));
+ if (GET_MODE (XEXP (compare_op, 0)) == CCFPmode
+ || GET_MODE (XEXP (compare_op, 0)) == CCFPUmode)
+ {
+ fpcmp = true;
+ compare_code = ix86_fp_compare_code_to_integer (compare_code);
+ }
+
+ /* To simplify rest of code, restrict to the GEU case. */
+ if (compare_code == LTU)
+ {
+ HOST_WIDE_INT tmp = ct;
+ ct = cf;
+ cf = tmp;
+ compare_code = reverse_condition (compare_code);
+ code = reverse_condition (code);
+ }
+ else
+ {
+ if (fpcmp)
+ PUT_CODE (compare_op,
+ reverse_condition_maybe_unordered
+ (GET_CODE (compare_op)));
+ else
+ PUT_CODE (compare_op, reverse_condition (GET_CODE (compare_op)));
+ }
+ diff = ct - cf;
+
+ if (reg_overlap_mentioned_p (out, ix86_compare_op0)
+ || reg_overlap_mentioned_p (out, ix86_compare_op1))
+ tmp = gen_reg_rtx (mode);
+
+ if (mode == DImode)
+ emit_insn (gen_x86_movdicc_0_m1_rex64 (tmp, compare_op));
+ else
+ emit_insn (gen_x86_movsicc_0_m1 (gen_lowpart (SImode, tmp), compare_op));
+ }
else
- emit_insn (gen_x86_movsicc_0_m1 (tmp));
+ {
+ if (code == GT || code == GE)
+ code = reverse_condition (code);
+ else
+ {
+ HOST_WIDE_INT tmp = ct;
+ ct = cf;
+ cf = tmp;
+ diff = ct - cf;
+ }
+ tmp = emit_store_flag (tmp, code, ix86_compare_op0,
+ ix86_compare_op1, VOIDmode, 0, -1);
+ }
if (diff == 1)
{
@@ -9280,9 +9849,9 @@ ix86_expand_int_movcc (operands)
* Size 5 - 8.
*/
if (ct)
- tmp = expand_simple_binop (mode, PLUS,
+ tmp = expand_simple_binop (mode, PLUS,
tmp, GEN_INT (ct),
- tmp, 1, OPTAB_DIRECT);
+ copy_rtx (tmp), 1, OPTAB_DIRECT);
}
else if (cf == -1)
{
@@ -9295,7 +9864,7 @@ ix86_expand_int_movcc (operands)
*/
tmp = expand_simple_binop (mode, IOR,
tmp, GEN_INT (ct),
- tmp, 1, OPTAB_DIRECT);
+ copy_rtx (tmp), 1, OPTAB_DIRECT);
}
else if (diff == -1 && ct)
{
@@ -9307,11 +9876,11 @@ ix86_expand_int_movcc (operands)
*
* Size 8 - 11.
*/
- tmp = expand_simple_unop (mode, NOT, tmp, tmp, 1);
+ tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1);
if (cf)
- tmp = expand_simple_binop (mode, PLUS,
- tmp, GEN_INT (cf),
- tmp, 1, OPTAB_DIRECT);
+ tmp = expand_simple_binop (mode, PLUS,
+ copy_rtx (tmp), GEN_INT (cf),
+ copy_rtx (tmp), 1, OPTAB_DIRECT);
}
else
{
@@ -9329,26 +9898,25 @@ ix86_expand_int_movcc (operands)
{
cf = ct;
ct = 0;
- tmp = expand_simple_unop (mode, NOT, tmp, tmp, 1);
+ tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1);
}
tmp = expand_simple_binop (mode, AND,
- tmp,
+ copy_rtx (tmp),
gen_int_mode (cf - ct, mode),
- tmp, 1, OPTAB_DIRECT);
+ copy_rtx (tmp), 1, OPTAB_DIRECT);
if (ct)
- tmp = expand_simple_binop (mode, PLUS,
- tmp, GEN_INT (ct),
- tmp, 1, OPTAB_DIRECT);
+ tmp = expand_simple_binop (mode, PLUS,
+ copy_rtx (tmp), GEN_INT (ct),
+ copy_rtx (tmp), 1, OPTAB_DIRECT);
}
- if (tmp != out)
- emit_move_insn (out, tmp);
+ if (!rtx_equal_p (tmp, out))
+ emit_move_insn (copy_rtx (out), copy_rtx (tmp));
return 1; /* DONE */
}
- diff = ct - cf;
if (diff < 0)
{
HOST_WIDE_INT tmp;
@@ -9407,7 +9975,7 @@ ix86_expand_int_movcc (operands)
if (ct != -1)
{
cf = ct;
- ct = -1;
+ ct = -1;
code = reverse_condition (code);
}
@@ -9424,8 +9992,10 @@ ix86_expand_int_movcc (operands)
}
}
+
if ((diff == 1 || diff == 2 || diff == 4 || diff == 8
|| diff == 3 || diff == 5 || diff == 9)
+ && ((mode != QImode && mode != HImode) || !TARGET_PARTIAL_REG_STALL)
&& (mode != DImode || x86_64_sign_extended_value (GEN_INT (cf))))
{
/*
@@ -9467,15 +10037,14 @@ ix86_expand_int_movcc (operands)
tmp = gen_rtx_PLUS (mode, tmp, GEN_INT (cf));
nops++;
}
- if (tmp != out
- && (GET_CODE (tmp) != SUBREG || SUBREG_REG (tmp) != out))
+ if (!rtx_equal_p (tmp, out))
{
if (nops == 1)
out = force_operand (tmp, copy_rtx (out));
else
emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (out), copy_rtx (tmp)));
}
- if (out != operands[0])
+ if (!rtx_equal_p (out, operands[0]))
emit_move_insn (operands[0], copy_rtx (out));
return 1; /* DONE */
@@ -9495,12 +10064,10 @@ ix86_expand_int_movcc (operands)
* This is reasonably steep, but branch mispredict costs are
* high on modern cpus, so consider failing only if optimizing
* for space.
- *
- * %%% Parameterize branch_cost on the tuning architecture, then
- * use that. The 80386 couldn't care less about mispredicts.
*/
- if (!optimize_size && !TARGET_CMOVE)
+ if ((!TARGET_CMOVE || (mode == QImode && TARGET_PARTIAL_REG_STALL))
+ && BRANCH_COST >= 2)
{
if (cf == 0)
{
@@ -9525,7 +10092,7 @@ ix86_expand_int_movcc (operands)
/* notl op1 (if needed)
sarl $31, op1
andl (cf-ct), op1
- addl ct, op1
+ addl ct, op1
For x < 0 (resp. x <= -1) there will be no notl,
so if possible swap the constants to get rid of the
@@ -9536,13 +10103,13 @@ ix86_expand_int_movcc (operands)
if (compare_code == GE || !cf)
{
- code = reverse_condition (code);
+ code = reverse_condition (code);
compare_code = LT;
}
else
{
HOST_WIDE_INT tmp = cf;
- cf = ct;
+ cf = ct;
ct = tmp;
}
@@ -9554,31 +10121,31 @@ ix86_expand_int_movcc (operands)
out = emit_store_flag (out, code, ix86_compare_op0,
ix86_compare_op1, VOIDmode, 0, 1);
- out = expand_simple_binop (mode, PLUS, out, constm1_rtx,
- out, 1, OPTAB_DIRECT);
+ out = expand_simple_binop (mode, PLUS, copy_rtx (out), constm1_rtx,
+ copy_rtx (out), 1, OPTAB_DIRECT);
}
- out = expand_simple_binop (mode, AND, out,
+ out = expand_simple_binop (mode, AND, copy_rtx (out),
gen_int_mode (cf - ct, mode),
- out, 1, OPTAB_DIRECT);
+ copy_rtx (out), 1, OPTAB_DIRECT);
if (ct)
- out = expand_simple_binop (mode, PLUS, out, GEN_INT (ct),
- out, 1, OPTAB_DIRECT);
- if (out != operands[0])
- emit_move_insn (operands[0], out);
+ out = expand_simple_binop (mode, PLUS, copy_rtx (out), GEN_INT (ct),
+ copy_rtx (out), 1, OPTAB_DIRECT);
+ if (!rtx_equal_p (out, operands[0]))
+ emit_move_insn (operands[0], copy_rtx (out));
return 1; /* DONE */
}
}
- if (!TARGET_CMOVE)
+ if (!TARGET_CMOVE || (mode == QImode && TARGET_PARTIAL_REG_STALL))
{
/* Try a few things more with specific constants and a variable. */
optab op;
rtx var, orig_out, out, tmp;
- if (optimize_size)
+ if (BRANCH_COST <= 2)
return 0; /* FAIL */
/* If one of the two operands is an interesting constant, load a
@@ -9587,9 +10154,9 @@ ix86_expand_int_movcc (operands)
if (GET_CODE (operands[2]) == CONST_INT)
{
var = operands[3];
- if (INTVAL (operands[2]) == 0)
+ if (INTVAL (operands[2]) == 0 && operands[3] != constm1_rtx)
operands[3] = constm1_rtx, op = and_optab;
- else if (INTVAL (operands[2]) == -1)
+ else if (INTVAL (operands[2]) == -1 && operands[3] != const0_rtx)
operands[3] = const0_rtx, op = ior_optab;
else
return 0; /* FAIL */
@@ -9597,9 +10164,9 @@ ix86_expand_int_movcc (operands)
else if (GET_CODE (operands[3]) == CONST_INT)
{
var = operands[2];
- if (INTVAL (operands[3]) == 0)
+ if (INTVAL (operands[3]) == 0 && operands[2] != constm1_rtx)
operands[2] = constm1_rtx, op = and_optab;
- else if (INTVAL (operands[3]) == -1)
+ else if (INTVAL (operands[3]) == -1 && operands[3] != const0_rtx)
operands[2] = const0_rtx, op = ior_optab;
else
return 0; /* FAIL */
@@ -9618,8 +10185,8 @@ ix86_expand_int_movcc (operands)
/* Mask in the interesting variable. */
out = expand_binop (mode, op, var, tmp, orig_out, 0,
OPTAB_WIDEN);
- if (out != orig_out)
- emit_move_insn (orig_out, out);
+ if (!rtx_equal_p (out, orig_out))
+ emit_move_insn (copy_rtx (orig_out), copy_rtx (out));
return 1; /* DONE */
}
@@ -9652,34 +10219,39 @@ ix86_expand_int_movcc (operands)
emit_move_insn (tmp, operands[2]);
operands[2] = tmp;
}
+
if (! register_operand (operands[2], VOIDmode)
- && ! register_operand (operands[3], VOIDmode))
+ && (mode == QImode
+ || ! register_operand (operands[3], VOIDmode)))
operands[2] = force_reg (mode, operands[2]);
+ if (mode == QImode
+ && ! register_operand (operands[3], VOIDmode))
+ operands[3] = force_reg (mode, operands[3]);
+
emit_insn (compare_seq);
emit_insn (gen_rtx_SET (VOIDmode, operands[0],
gen_rtx_IF_THEN_ELSE (mode,
compare_op, operands[2],
operands[3])));
if (bypass_test)
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (operands[0]),
gen_rtx_IF_THEN_ELSE (mode,
bypass_test,
- operands[3],
- operands[0])));
+ copy_rtx (operands[3]),
+ copy_rtx (operands[0]))));
if (second_test)
- emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (operands[0]),
gen_rtx_IF_THEN_ELSE (mode,
second_test,
- operands[2],
- operands[0])));
+ copy_rtx (operands[2]),
+ copy_rtx (operands[0]))));
return 1; /* DONE */
}
int
-ix86_expand_fp_movcc (operands)
- rtx operands[];
+ix86_expand_fp_movcc (rtx operands[])
{
enum rtx_code code;
rtx tmp;
@@ -9713,8 +10285,14 @@ ix86_expand_fp_movcc (operands)
if (rtx_equal_p (operands[2], op0) && rtx_equal_p (operands[3], op1))
{
/* Check for min operation. */
- if (code == LT)
+ if (code == LT || code == UNLE)
{
+ if (code == UNLE)
+ {
+ rtx tmp = op0;
+ op0 = op1;
+ op1 = tmp;
+ }
operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
if (memory_operand (op0, VOIDmode))
op0 = force_reg (GET_MODE (operands[0]), op0);
@@ -9725,8 +10303,14 @@ ix86_expand_fp_movcc (operands)
return 1;
}
/* Check for max operation. */
- if (code == GT)
+ if (code == GT || code == UNGE)
{
+ if (code == UNGE)
+ {
+ rtx tmp = op0;
+ op0 = op1;
+ op1 = tmp;
+ }
operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
if (memory_operand (op0, VOIDmode))
op0 = force_reg (GET_MODE (operands[0]), op0);
@@ -9751,7 +10335,7 @@ ix86_expand_fp_movcc (operands)
VOIDmode, ix86_compare_op0,
ix86_compare_op1);
}
- /* Similary try to manage result to be first operand of conditional
+ /* Similarly try to manage result to be first operand of conditional
move. We also don't support the NE comparison on SSE, so try to
avoid it. */
if ((rtx_equal_p (operands[0], operands[3])
@@ -9831,21 +10415,102 @@ ix86_expand_fp_movcc (operands)
return 1;
}
+/* Expand conditional increment or decrement using adb/sbb instructions.
+ The default case using setcc followed by the conditional move can be
+ done by generic code. */
+int
+ix86_expand_int_addcc (rtx operands[])
+{
+ enum rtx_code code = GET_CODE (operands[1]);
+ rtx compare_op;
+ rtx val = const0_rtx;
+ bool fpcmp = false;
+ enum machine_mode mode = GET_MODE (operands[0]);
+
+ if (operands[3] != const1_rtx
+ && operands[3] != constm1_rtx)
+ return 0;
+ if (!ix86_expand_carry_flag_compare (code, ix86_compare_op0,
+ ix86_compare_op1, &compare_op))
+ return 0;
+ code = GET_CODE (compare_op);
+
+ if (GET_MODE (XEXP (compare_op, 0)) == CCFPmode
+ || GET_MODE (XEXP (compare_op, 0)) == CCFPUmode)
+ {
+ fpcmp = true;
+ code = ix86_fp_compare_code_to_integer (code);
+ }
+
+ if (code != LTU)
+ {
+ val = constm1_rtx;
+ if (fpcmp)
+ PUT_CODE (compare_op,
+ reverse_condition_maybe_unordered
+ (GET_CODE (compare_op)));
+ else
+ PUT_CODE (compare_op, reverse_condition (GET_CODE (compare_op)));
+ }
+ PUT_MODE (compare_op, mode);
+
+ /* Construct either adc or sbb insn. */
+ if ((code == LTU) == (operands[3] == constm1_rtx))
+ {
+ switch (GET_MODE (operands[0]))
+ {
+ case QImode:
+ emit_insn (gen_subqi3_carry (operands[0], operands[2], val, compare_op));
+ break;
+ case HImode:
+ emit_insn (gen_subhi3_carry (operands[0], operands[2], val, compare_op));
+ break;
+ case SImode:
+ emit_insn (gen_subsi3_carry (operands[0], operands[2], val, compare_op));
+ break;
+ case DImode:
+ emit_insn (gen_subdi3_carry_rex64 (operands[0], operands[2], val, compare_op));
+ break;
+ default:
+ abort ();
+ }
+ }
+ else
+ {
+ switch (GET_MODE (operands[0]))
+ {
+ case QImode:
+ emit_insn (gen_addqi3_carry (operands[0], operands[2], val, compare_op));
+ break;
+ case HImode:
+ emit_insn (gen_addhi3_carry (operands[0], operands[2], val, compare_op));
+ break;
+ case SImode:
+ emit_insn (gen_addsi3_carry (operands[0], operands[2], val, compare_op));
+ break;
+ case DImode:
+ emit_insn (gen_adddi3_carry_rex64 (operands[0], operands[2], val, compare_op));
+ break;
+ default:
+ abort ();
+ }
+ }
+ return 1; /* DONE */
+}
+
+
/* Split operands 0 and 1 into SImode parts. Similar to split_di, but
works for floating pointer parameters and nonoffsetable memories.
For pushes, it returns just stack offsets; the values will be saved
in the right order. Maximally three parts are generated. */
static int
-ix86_split_to_parts (operand, parts, mode)
- rtx operand;
- rtx *parts;
- enum machine_mode mode;
+ix86_split_to_parts (rtx operand, rtx *parts, enum machine_mode mode)
{
int size;
if (!TARGET_64BIT)
- size = mode == TFmode ? 3 : (GET_MODE_SIZE (mode) / 4);
+ size = mode==XFmode ? 3 : GET_MODE_SIZE (mode) / 4;
else
size = (GET_MODE_SIZE (mode) + 4) / 8;
@@ -9905,7 +10570,6 @@ ix86_split_to_parts (operand, parts, mode)
switch (mode)
{
case XFmode:
- case TFmode:
REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
parts[2] = gen_int_mode (l[2], SImode);
break;
@@ -9928,18 +10592,19 @@ ix86_split_to_parts (operand, parts, mode)
split_ti (&operand, 1, &parts[0], &parts[1]);
if (mode == XFmode || mode == TFmode)
{
+ enum machine_mode upper_mode = mode==XFmode ? SImode : DImode;
if (REG_P (operand))
{
if (!reload_completed)
abort ();
parts[0] = gen_rtx_REG (DImode, REGNO (operand) + 0);
- parts[1] = gen_rtx_REG (SImode, REGNO (operand) + 1);
+ parts[1] = gen_rtx_REG (upper_mode, REGNO (operand) + 1);
}
else if (offsettable_memref_p (operand))
{
operand = adjust_address (operand, DImode, 0);
parts[0] = operand;
- parts[1] = adjust_address (operand, SImode, 8);
+ parts[1] = adjust_address (operand, upper_mode, 8);
}
else if (GET_CODE (operand) == CONST_DOUBLE)
{
@@ -9947,7 +10612,7 @@ ix86_split_to_parts (operand, parts, mode)
long l[3];
REAL_VALUE_FROM_CONST_DOUBLE (r, operand);
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l);
+ real_to_target (l, &r, mode);
/* Do not use shift by 32 to avoid warning on 32bit systems. */
if (HOST_BITS_PER_WIDE_INT >= 64)
parts[0]
@@ -9957,7 +10622,16 @@ ix86_split_to_parts (operand, parts, mode)
DImode);
else
parts[0] = immed_double_const (l[0], l[1], DImode);
- parts[1] = gen_int_mode (l[2], SImode);
+ if (upper_mode == SImode)
+ parts[1] = gen_int_mode (l[2], SImode);
+ else if (HOST_BITS_PER_WIDE_INT >= 64)
+ parts[1]
+ = gen_int_mode
+ ((l[2] & (((HOST_WIDE_INT) 2 << 31) - 1))
+ + ((((HOST_WIDE_INT) l[3]) << 31) << 1),
+ DImode);
+ else
+ parts[1] = immed_double_const (l[2], l[3], DImode);
}
else
abort ();
@@ -9973,8 +10647,7 @@ ix86_split_to_parts (operand, parts, mode)
int the correct order; operands 5-7 contain the output values. */
void
-ix86_split_long_move (operands)
- rtx operands[];
+ix86_split_long_move (rtx operands[])
{
rtx part[2][3];
int nparts;
@@ -10079,12 +10752,8 @@ ix86_split_long_move (operands)
{
if (nparts == 3)
{
- /* We use only first 12 bytes of TFmode value, but for pushing we
- are required to adjust stack as if we were pushing real 16byte
- value. */
- if (mode == TFmode && !TARGET_64BIT)
- emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
- GEN_INT (-4)));
+ if (TARGET_128BIT_LONG_DOUBLE && mode == XFmode)
+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4)));
emit_move_insn (part[0][2], part[1][2]);
}
}
@@ -10165,8 +10834,7 @@ ix86_split_long_move (operands)
}
void
-ix86_split_ashldi (operands, scratch)
- rtx *operands, scratch;
+ix86_split_ashldi (rtx *operands, rtx scratch)
{
rtx low[2], high[2];
int count;
@@ -10218,8 +10886,7 @@ ix86_split_ashldi (operands, scratch)
}
void
-ix86_split_ashrdi (operands, scratch)
- rtx *operands, scratch;
+ix86_split_ashrdi (rtx *operands, rtx scratch)
{
rtx low[2], high[2];
int count;
@@ -10277,8 +10944,7 @@ ix86_split_ashrdi (operands, scratch)
}
void
-ix86_split_lshrdi (operands, scratch)
- rtx *operands, scratch;
+ix86_split_lshrdi (rtx *operands, rtx scratch)
{
rtx low[2], high[2];
int count;
@@ -10333,9 +10999,7 @@ ix86_split_lshrdi (operands, scratch)
/* Helper function for the string operations below. Dest VARIABLE whether
it is aligned to VALUE bytes. If true, jump to the label. */
static rtx
-ix86_expand_aligntest (variable, value)
- rtx variable;
- int value;
+ix86_expand_aligntest (rtx variable, int value)
{
rtx label = gen_label_rtx ();
rtx tmpcount = gen_reg_rtx (GET_MODE (variable));
@@ -10350,9 +11014,7 @@ ix86_expand_aligntest (variable, value)
/* Adjust COUNTER by the VALUE. */
static void
-ix86_adjust_counter (countreg, value)
- rtx countreg;
- HOST_WIDE_INT value;
+ix86_adjust_counter (rtx countreg, HOST_WIDE_INT value)
{
if (GET_MODE (countreg) == DImode)
emit_insn (gen_adddi3 (countreg, countreg, GEN_INT (-value)));
@@ -10362,8 +11024,7 @@ ix86_adjust_counter (countreg, value)
/* Zero extend possibly SImode EXP to Pmode register. */
rtx
-ix86_zero_extend_to_Pmode (exp)
- rtx exp;
+ix86_zero_extend_to_Pmode (rtx exp)
{
rtx r;
if (GET_MODE (exp) == VOIDmode)
@@ -10378,26 +11039,30 @@ ix86_zero_extend_to_Pmode (exp)
/* Expand string move (memcpy) operation. Use i386 string operations when
profitable. expand_clrstr contains similar code. */
int
-ix86_expand_movstr (dst, src, count_exp, align_exp)
- rtx dst, src, count_exp, align_exp;
+ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp)
{
- rtx srcreg, destreg, countreg;
+ rtx srcreg, destreg, countreg, srcexp, destexp;
enum machine_mode counter_mode;
HOST_WIDE_INT align = 0;
unsigned HOST_WIDE_INT count = 0;
- rtx insns;
-
- start_sequence ();
if (GET_CODE (align_exp) == CONST_INT)
align = INTVAL (align_exp);
+ /* Can't use any of this if the user has appropriated esi or edi. */
+ if (global_regs[4] || global_regs[5])
+ return 0;
+
/* This simple hack avoids all inlining code and simplifies code below. */
if (!TARGET_ALIGN_STRINGOPS)
align = 64;
if (GET_CODE (count_exp) == CONST_INT)
- count = INTVAL (count_exp);
+ {
+ count = INTVAL (count_exp);
+ if (!TARGET_INLINE_ALL_STRINGOPS && count > 64)
+ return 0;
+ }
/* Figure out proper mode for counter. For 32bits it is always SImode,
for 64bits use SImode when possible, otherwise DImode.
@@ -10412,22 +11077,23 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
abort ();
destreg = copy_to_mode_reg (Pmode, XEXP (dst, 0));
+ if (destreg != XEXP (dst, 0))
+ dst = replace_equiv_address_nv (dst, destreg);
srcreg = copy_to_mode_reg (Pmode, XEXP (src, 0));
-
- emit_insn (gen_cld ());
+ if (srcreg != XEXP (src, 0))
+ src = replace_equiv_address_nv (src, srcreg);
/* When optimizing for size emit simple rep ; movsb instruction for
counts not divisible by 4. */
if ((!optimize || optimize_size) && (count == 0 || (count & 0x03)))
{
+ emit_insn (gen_cld ());
countreg = ix86_zero_extend_to_Pmode (count_exp);
- if (TARGET_64BIT)
- emit_insn (gen_rep_movqi_rex64 (destreg, srcreg, countreg,
- destreg, srcreg, countreg));
- else
- emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
- destreg, srcreg, countreg));
+ destexp = gen_rtx_PLUS (Pmode, destreg, countreg);
+ srcexp = gen_rtx_PLUS (Pmode, srcreg, countreg);
+ emit_insn (gen_rep_mov (destreg, dst, srcreg, src, countreg,
+ destexp, srcexp));
}
/* For constant aligned (or small unaligned) copies use rep movsl
@@ -10439,32 +11105,53 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
|| (!TARGET_PENTIUMPRO && !TARGET_64BIT && align >= 4)
|| optimize_size || count < (unsigned int) 64))
{
+ unsigned HOST_WIDE_INT offset = 0;
int size = TARGET_64BIT && !optimize_size ? 8 : 4;
+ rtx srcmem, dstmem;
+
+ emit_insn (gen_cld ());
if (count & ~(size - 1))
{
countreg = copy_to_mode_reg (counter_mode,
GEN_INT ((count >> (size == 4 ? 2 : 3))
& (TARGET_64BIT ? -1 : 0x3fffffff)));
countreg = ix86_zero_extend_to_Pmode (countreg);
- if (size == 4)
- {
- if (TARGET_64BIT)
- emit_insn (gen_rep_movsi_rex64 (destreg, srcreg, countreg,
- destreg, srcreg, countreg));
- else
- emit_insn (gen_rep_movsi (destreg, srcreg, countreg,
- destreg, srcreg, countreg));
- }
- else
- emit_insn (gen_rep_movdi_rex64 (destreg, srcreg, countreg,
- destreg, srcreg, countreg));
+
+ destexp = gen_rtx_ASHIFT (Pmode, countreg,
+ GEN_INT (size == 4 ? 2 : 3));
+ srcexp = gen_rtx_PLUS (Pmode, destexp, srcreg);
+ destexp = gen_rtx_PLUS (Pmode, destexp, destreg);
+
+ emit_insn (gen_rep_mov (destreg, dst, srcreg, src,
+ countreg, destexp, srcexp));
+ offset = count & ~(size - 1);
}
if (size == 8 && (count & 0x04))
- emit_insn (gen_strmovsi (destreg, srcreg));
+ {
+ srcmem = adjust_automodify_address_nv (src, SImode, srcreg,
+ offset);
+ dstmem = adjust_automodify_address_nv (dst, SImode, destreg,
+ offset);
+ emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
+ offset += 4;
+ }
if (count & 0x02)
- emit_insn (gen_strmovhi (destreg, srcreg));
+ {
+ srcmem = adjust_automodify_address_nv (src, HImode, srcreg,
+ offset);
+ dstmem = adjust_automodify_address_nv (dst, HImode, destreg,
+ offset);
+ emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
+ offset += 2;
+ }
if (count & 0x01)
- emit_insn (gen_strmovqi (destreg, srcreg));
+ {
+ srcmem = adjust_automodify_address_nv (src, QImode, srcreg,
+ offset);
+ dstmem = adjust_automodify_address_nv (dst, QImode, destreg,
+ offset);
+ emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
+ }
}
/* The generic code based on the glibc implementation:
- align destination to 4 bytes (8 byte alignment is used for PentiumPro
@@ -10475,18 +11162,23 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
{
rtx countreg2;
rtx label = NULL;
+ rtx srcmem, dstmem;
int desired_alignment = (TARGET_PENTIUMPRO
&& (count == 0 || count >= (unsigned int) 260)
? 8 : UNITS_PER_WORD);
+ /* Get rid of MEM_OFFSETs, they won't be accurate. */
+ dst = change_address (dst, BLKmode, destreg);
+ src = change_address (src, BLKmode, srcreg);
/* In case we don't know anything about the alignment, default to
library version, since it is usually equally fast and result in
- shorter code. */
- if (!TARGET_INLINE_ALL_STRINGOPS && align < UNITS_PER_WORD)
- {
- end_sequence ();
- return 0;
- }
+ shorter code.
+
+ Also emit call when we know that the count is large and call overhead
+ will not be important. */
+ if (!TARGET_INLINE_ALL_STRINGOPS
+ && (align < UNITS_PER_WORD || !TARGET_REP_MOVL_OPTIMAL))
+ return 0;
if (TARGET_SINGLE_STRINGOP)
emit_insn (gen_cld ());
@@ -10500,11 +11192,11 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
able to predict the branches) and also it is friendlier to the
hardware branch prediction.
- Using loops is benefical for generic case, because we can
+ Using loops is beneficial for generic case, because we can
handle small counts using the loops. Many CPUs (such as Athlon)
have large REP prefix setup costs.
- This is quite costy. Maybe we can revisit this decision later or
+ This is quite costly. Maybe we can revisit this decision later or
add some customizability to this code. */
if (count == 0 && align < desired_alignment)
@@ -10516,7 +11208,9 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
if (align <= 1)
{
rtx label = ix86_expand_aligntest (destreg, 1);
- emit_insn (gen_strmovqi (destreg, srcreg));
+ srcmem = change_address (src, QImode, srcreg);
+ dstmem = change_address (dst, QImode, destreg);
+ emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
ix86_adjust_counter (countreg, 1);
emit_label (label);
LABEL_NUSES (label) = 1;
@@ -10524,7 +11218,9 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
if (align <= 2)
{
rtx label = ix86_expand_aligntest (destreg, 2);
- emit_insn (gen_strmovhi (destreg, srcreg));
+ srcmem = change_address (src, HImode, srcreg);
+ dstmem = change_address (dst, HImode, destreg);
+ emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
ix86_adjust_counter (countreg, 2);
emit_label (label);
LABEL_NUSES (label) = 1;
@@ -10532,7 +11228,9 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
if (align <= 4 && desired_alignment > 4)
{
rtx label = ix86_expand_aligntest (destreg, 4);
- emit_insn (gen_strmovsi (destreg, srcreg));
+ srcmem = change_address (src, SImode, srcreg);
+ dstmem = change_address (dst, SImode, destreg);
+ emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
ix86_adjust_counter (countreg, 4);
emit_label (label);
LABEL_NUSES (label) = 1;
@@ -10550,15 +11248,17 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
{
emit_insn (gen_lshrdi3 (countreg2, ix86_zero_extend_to_Pmode (countreg),
GEN_INT (3)));
- emit_insn (gen_rep_movdi_rex64 (destreg, srcreg, countreg2,
- destreg, srcreg, countreg2));
+ destexp = gen_rtx_ASHIFT (Pmode, countreg2, GEN_INT (3));
}
else
{
- emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
- emit_insn (gen_rep_movsi (destreg, srcreg, countreg2,
- destreg, srcreg, countreg2));
+ emit_insn (gen_lshrsi3 (countreg2, countreg, const2_rtx));
+ destexp = gen_rtx_ASHIFT (Pmode, countreg2, const2_rtx);
}
+ srcexp = gen_rtx_PLUS (Pmode, destexp, srcreg);
+ destexp = gen_rtx_PLUS (Pmode, destexp, destreg);
+ emit_insn (gen_rep_mov (destreg, dst, srcreg, src,
+ countreg2, destexp, srcexp));
if (label)
{
@@ -10566,49 +11266,61 @@ ix86_expand_movstr (dst, src, count_exp, align_exp)
LABEL_NUSES (label) = 1;
}
if (TARGET_64BIT && align > 4 && count != 0 && (count & 4))
- emit_insn (gen_strmovsi (destreg, srcreg));
+ {
+ srcmem = change_address (src, SImode, srcreg);
+ dstmem = change_address (dst, SImode, destreg);
+ emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
+ }
if ((align <= 4 || count == 0) && TARGET_64BIT)
{
rtx label = ix86_expand_aligntest (countreg, 4);
- emit_insn (gen_strmovsi (destreg, srcreg));
+ srcmem = change_address (src, SImode, srcreg);
+ dstmem = change_address (dst, SImode, destreg);
+ emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
emit_label (label);
LABEL_NUSES (label) = 1;
}
if (align > 2 && count != 0 && (count & 2))
- emit_insn (gen_strmovhi (destreg, srcreg));
+ {
+ srcmem = change_address (src, HImode, srcreg);
+ dstmem = change_address (dst, HImode, destreg);
+ emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
+ }
if (align <= 2 || count == 0)
{
rtx label = ix86_expand_aligntest (countreg, 2);
- emit_insn (gen_strmovhi (destreg, srcreg));
+ srcmem = change_address (src, HImode, srcreg);
+ dstmem = change_address (dst, HImode, destreg);
+ emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
emit_label (label);
LABEL_NUSES (label) = 1;
}
if (align > 1 && count != 0 && (count & 1))
- emit_insn (gen_strmovqi (destreg, srcreg));
+ {
+ srcmem = change_address (src, QImode, srcreg);
+ dstmem = change_address (dst, QImode, destreg);
+ emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
+ }
if (align <= 1 || count == 0)
{
rtx label = ix86_expand_aligntest (countreg, 1);
- emit_insn (gen_strmovqi (destreg, srcreg));
+ srcmem = change_address (src, QImode, srcreg);
+ dstmem = change_address (dst, QImode, destreg);
+ emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
emit_label (label);
LABEL_NUSES (label) = 1;
}
}
- insns = get_insns ();
- end_sequence ();
-
- ix86_set_move_mem_attrs (insns, dst, src, destreg, srcreg);
- emit_insn (insns);
return 1;
}
/* Expand string clear operation (bzero). Use i386 string operations when
profitable. expand_movstr contains similar code. */
int
-ix86_expand_clrstr (src, count_exp, align_exp)
- rtx src, count_exp, align_exp;
+ix86_expand_clrstr (rtx dst, rtx count_exp, rtx align_exp)
{
- rtx destreg, zeroreg, countreg;
+ rtx destreg, zeroreg, countreg, destexp;
enum machine_mode counter_mode;
HOST_WIDE_INT align = 0;
unsigned HOST_WIDE_INT count = 0;
@@ -10616,12 +11328,20 @@ ix86_expand_clrstr (src, count_exp, align_exp)
if (GET_CODE (align_exp) == CONST_INT)
align = INTVAL (align_exp);
+ /* Can't use any of this if the user has appropriated esi. */
+ if (global_regs[4])
+ return 0;
+
/* This simple hack avoids all inlining code and simplifies code below. */
if (!TARGET_ALIGN_STRINGOPS)
align = 32;
if (GET_CODE (count_exp) == CONST_INT)
- count = INTVAL (count_exp);
+ {
+ count = INTVAL (count_exp);
+ if (!TARGET_INLINE_ALL_STRINGOPS && count > 64)
+ return 0;
+ }
/* Figure out proper mode for counter. For 32bits it is always SImode,
for 64bits use SImode when possible, otherwise DImode.
Set count to number of bytes copied when known at compile time. */
@@ -10631,7 +11351,9 @@ ix86_expand_clrstr (src, count_exp, align_exp)
else
counter_mode = DImode;
- destreg = copy_to_mode_reg (Pmode, XEXP (src, 0));
+ destreg = copy_to_mode_reg (Pmode, XEXP (dst, 0));
+ if (destreg != XEXP (dst, 0))
+ dst = replace_equiv_address_nv (dst, destreg);
emit_insn (gen_cld ());
@@ -10642,12 +11364,8 @@ ix86_expand_clrstr (src, count_exp, align_exp)
{
countreg = ix86_zero_extend_to_Pmode (count_exp);
zeroreg = copy_to_mode_reg (QImode, const0_rtx);
- if (TARGET_64BIT)
- emit_insn (gen_rep_stosqi_rex64 (destreg, countreg, zeroreg,
- destreg, countreg));
- else
- emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg,
- destreg, countreg));
+ destexp = gen_rtx_PLUS (Pmode, destreg, countreg);
+ emit_insn (gen_rep_stos (destreg, countreg, dst, zeroreg, destexp));
}
else if (count != 0
&& (align >= 8
@@ -10655,6 +11373,8 @@ ix86_expand_clrstr (src, count_exp, align_exp)
|| optimize_size || count < (unsigned int) 64))
{
int size = TARGET_64BIT && !optimize_size ? 8 : 4;
+ unsigned HOST_WIDE_INT offset = 0;
+
zeroreg = copy_to_mode_reg (size == 4 ? SImode : DImode, const0_rtx);
if (count & ~(size - 1))
{
@@ -10662,28 +11382,34 @@ ix86_expand_clrstr (src, count_exp, align_exp)
GEN_INT ((count >> (size == 4 ? 2 : 3))
& (TARGET_64BIT ? -1 : 0x3fffffff)));
countreg = ix86_zero_extend_to_Pmode (countreg);
- if (size == 4)
- {
- if (TARGET_64BIT)
- emit_insn (gen_rep_stossi_rex64 (destreg, countreg, zeroreg,
- destreg, countreg));
- else
- emit_insn (gen_rep_stossi (destreg, countreg, zeroreg,
- destreg, countreg));
- }
- else
- emit_insn (gen_rep_stosdi_rex64 (destreg, countreg, zeroreg,
- destreg, countreg));
+ destexp = gen_rtx_ASHIFT (Pmode, countreg, GEN_INT (size == 4 ? 2 : 3));
+ destexp = gen_rtx_PLUS (Pmode, destexp, destreg);
+ emit_insn (gen_rep_stos (destreg, countreg, dst, zeroreg, destexp));
+ offset = count & ~(size - 1);
}
if (size == 8 && (count & 0x04))
- emit_insn (gen_strsetsi (destreg,
+ {
+ rtx mem = adjust_automodify_address_nv (dst, SImode, destreg,
+ offset);
+ emit_insn (gen_strset (destreg, mem,
gen_rtx_SUBREG (SImode, zeroreg, 0)));
+ offset += 4;
+ }
if (count & 0x02)
- emit_insn (gen_strsethi (destreg,
+ {
+ rtx mem = adjust_automodify_address_nv (dst, HImode, destreg,
+ offset);
+ emit_insn (gen_strset (destreg, mem,
gen_rtx_SUBREG (HImode, zeroreg, 0)));
+ offset += 2;
+ }
if (count & 0x01)
- emit_insn (gen_strsetqi (destreg,
+ {
+ rtx mem = adjust_automodify_address_nv (dst, QImode, destreg,
+ offset);
+ emit_insn (gen_strset (destreg, mem,
gen_rtx_SUBREG (QImode, zeroreg, 0)));
+ }
}
else
{
@@ -10696,8 +11422,12 @@ ix86_expand_clrstr (src, count_exp, align_exp)
/* In case we don't know anything about the alignment, default to
library version, since it is usually equally fast and result in
- shorter code. */
- if (!TARGET_INLINE_ALL_STRINGOPS && align < UNITS_PER_WORD)
+ shorter code.
+
+ Also emit call when we know that the count is large and call overhead
+ will not be important. */
+ if (!TARGET_INLINE_ALL_STRINGOPS
+ && (align < UNITS_PER_WORD || !TARGET_REP_MOVL_OPTIMAL))
return 0;
if (TARGET_SINGLE_STRINGOP)
@@ -10706,6 +11436,8 @@ ix86_expand_clrstr (src, count_exp, align_exp)
countreg2 = gen_reg_rtx (Pmode);
countreg = copy_to_mode_reg (counter_mode, count_exp);
zeroreg = copy_to_mode_reg (Pmode, const0_rtx);
+ /* Get rid of MEM_OFFSET, it won't be accurate. */
+ dst = change_address (dst, BLKmode, destreg);
if (count == 0 && align < desired_alignment)
{
@@ -10716,8 +11448,8 @@ ix86_expand_clrstr (src, count_exp, align_exp)
if (align <= 1)
{
rtx label = ix86_expand_aligntest (destreg, 1);
- emit_insn (gen_strsetqi (destreg,
- gen_rtx_SUBREG (QImode, zeroreg, 0)));
+ emit_insn (gen_strset (destreg, dst,
+ gen_rtx_SUBREG (QImode, zeroreg, 0)));
ix86_adjust_counter (countreg, 1);
emit_label (label);
LABEL_NUSES (label) = 1;
@@ -10725,8 +11457,8 @@ ix86_expand_clrstr (src, count_exp, align_exp)
if (align <= 2)
{
rtx label = ix86_expand_aligntest (destreg, 2);
- emit_insn (gen_strsethi (destreg,
- gen_rtx_SUBREG (HImode, zeroreg, 0)));
+ emit_insn (gen_strset (destreg, dst,
+ gen_rtx_SUBREG (HImode, zeroreg, 0)));
ix86_adjust_counter (countreg, 2);
emit_label (label);
LABEL_NUSES (label) = 1;
@@ -10734,9 +11466,10 @@ ix86_expand_clrstr (src, count_exp, align_exp)
if (align <= 4 && desired_alignment > 4)
{
rtx label = ix86_expand_aligntest (destreg, 4);
- emit_insn (gen_strsetsi (destreg, (TARGET_64BIT
- ? gen_rtx_SUBREG (SImode, zeroreg, 0)
- : zeroreg)));
+ emit_insn (gen_strset (destreg, dst,
+ (TARGET_64BIT
+ ? gen_rtx_SUBREG (SImode, zeroreg, 0)
+ : zeroreg)));
ix86_adjust_counter (countreg, 4);
emit_label (label);
LABEL_NUSES (label) = 1;
@@ -10755,15 +11488,16 @@ ix86_expand_clrstr (src, count_exp, align_exp)
{
emit_insn (gen_lshrdi3 (countreg2, ix86_zero_extend_to_Pmode (countreg),
GEN_INT (3)));
- emit_insn (gen_rep_stosdi_rex64 (destreg, countreg2, zeroreg,
- destreg, countreg2));
+ destexp = gen_rtx_ASHIFT (Pmode, countreg2, GEN_INT (3));
}
else
{
- emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2)));
- emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg,
- destreg, countreg2));
+ emit_insn (gen_lshrsi3 (countreg2, countreg, const2_rtx));
+ destexp = gen_rtx_ASHIFT (Pmode, countreg2, const2_rtx);
}
+ destexp = gen_rtx_PLUS (Pmode, destexp, destreg);
+ emit_insn (gen_rep_stos (destreg, countreg2, dst, zeroreg, destexp));
+
if (label)
{
emit_label (label);
@@ -10771,45 +11505,45 @@ ix86_expand_clrstr (src, count_exp, align_exp)
}
if (TARGET_64BIT && align > 4 && count != 0 && (count & 4))
- emit_insn (gen_strsetsi (destreg,
- gen_rtx_SUBREG (SImode, zeroreg, 0)));
+ emit_insn (gen_strset (destreg, dst,
+ gen_rtx_SUBREG (SImode, zeroreg, 0)));
if (TARGET_64BIT && (align <= 4 || count == 0))
{
rtx label = ix86_expand_aligntest (countreg, 4);
- emit_insn (gen_strsetsi (destreg,
- gen_rtx_SUBREG (SImode, zeroreg, 0)));
+ emit_insn (gen_strset (destreg, dst,
+ gen_rtx_SUBREG (SImode, zeroreg, 0)));
emit_label (label);
LABEL_NUSES (label) = 1;
}
if (align > 2 && count != 0 && (count & 2))
- emit_insn (gen_strsethi (destreg,
- gen_rtx_SUBREG (HImode, zeroreg, 0)));
+ emit_insn (gen_strset (destreg, dst,
+ gen_rtx_SUBREG (HImode, zeroreg, 0)));
if (align <= 2 || count == 0)
{
rtx label = ix86_expand_aligntest (countreg, 2);
- emit_insn (gen_strsethi (destreg,
- gen_rtx_SUBREG (HImode, zeroreg, 0)));
+ emit_insn (gen_strset (destreg, dst,
+ gen_rtx_SUBREG (HImode, zeroreg, 0)));
emit_label (label);
LABEL_NUSES (label) = 1;
}
if (align > 1 && count != 0 && (count & 1))
- emit_insn (gen_strsetqi (destreg,
- gen_rtx_SUBREG (QImode, zeroreg, 0)));
+ emit_insn (gen_strset (destreg, dst,
+ gen_rtx_SUBREG (QImode, zeroreg, 0)));
if (align <= 1 || count == 0)
{
rtx label = ix86_expand_aligntest (countreg, 1);
- emit_insn (gen_strsetqi (destreg,
- gen_rtx_SUBREG (QImode, zeroreg, 0)));
+ emit_insn (gen_strset (destreg, dst,
+ gen_rtx_SUBREG (QImode, zeroreg, 0)));
emit_label (label);
LABEL_NUSES (label) = 1;
}
}
return 1;
}
+
/* Expand strlen. */
int
-ix86_expand_strlen (out, src, eoschar, align)
- rtx out, src, eoschar, align;
+ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align)
{
rtx addr, scratch1, scratch2, scratch3, scratch4;
@@ -10838,7 +11572,7 @@ ix86_expand_strlen (out, src, eoschar, align)
emit_move_insn (out, addr);
- ix86_expand_strlensi_unroll_1 (out, align);
+ ix86_expand_strlensi_unroll_1 (out, src, align);
/* strlensi_unroll_1 returns the address of the zero at the end of
the string, like memchr(), so compute the length by subtracting
@@ -10850,6 +11584,7 @@ ix86_expand_strlen (out, src, eoschar, align)
}
else
{
+ rtx unspec;
scratch2 = gen_reg_rtx (Pmode);
scratch3 = gen_reg_rtx (Pmode);
scratch4 = force_reg (Pmode, constm1_rtx);
@@ -10858,17 +11593,19 @@ ix86_expand_strlen (out, src, eoschar, align)
eoschar = force_reg (QImode, eoschar);
emit_insn (gen_cld ());
+ src = replace_equiv_address_nv (src, scratch3);
+
+ /* If .md starts supporting :P, this can be done in .md. */
+ unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (4, src, eoschar, align,
+ scratch4), UNSPEC_SCAS);
+ emit_insn (gen_strlenqi_1 (scratch1, scratch3, unspec));
if (TARGET_64BIT)
{
- emit_insn (gen_strlenqi_rex_1 (scratch1, scratch3, eoschar,
- align, scratch4, scratch3));
emit_insn (gen_one_cmpldi2 (scratch2, scratch1));
emit_insn (gen_adddi3 (out, scratch2, constm1_rtx));
}
else
{
- emit_insn (gen_strlenqi_1 (scratch1, scratch3, eoschar,
- align, scratch4, scratch3));
emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
}
@@ -10884,12 +11621,11 @@ ix86_expand_strlen (out, src, eoschar, align)
scratch = scratch register, initialized with the startaddress when
not aligned, otherwise undefined
- This is just the body. It needs the initialisations mentioned above and
+ This is just the body. It needs the initializations mentioned above and
some address computing at the end. These things are done in i386.md. */
static void
-ix86_expand_strlensi_unroll_1 (out, align_rtx)
- rtx out, align_rtx;
+ix86_expand_strlensi_unroll_1 (rtx out, rtx src, rtx align_rtx)
{
int align;
rtx tmp;
@@ -10900,6 +11636,7 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx)
rtx mem;
rtx tmpreg = gen_reg_rtx (SImode);
rtx scratch = gen_reg_rtx (SImode);
+ rtx cmp;
align = 0;
if (GET_CODE (align_rtx) == CONST_INT)
@@ -10941,7 +11678,7 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx)
Pmode, 1, align_4_label);
}
- mem = gen_rtx_MEM (QImode, out);
+ mem = change_address (src, QImode, out);
/* Now compare the bytes. */
@@ -10985,7 +11722,7 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx)
speed up. */
emit_label (align_4_label);
- mem = gen_rtx_MEM (SImode, out);
+ mem = change_address (src, SImode, out);
emit_move_insn (scratch, mem);
if (TARGET_64BIT)
emit_insn (gen_adddi3 (out, out, GEN_INT (4)));
@@ -11058,17 +11795,19 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx)
/* Avoid branch in fixing the byte. */
tmpreg = gen_lowpart (QImode, tmpreg);
emit_insn (gen_addqi3_cc (tmpreg, tmpreg, tmpreg));
+ cmp = gen_rtx_LTU (Pmode, gen_rtx_REG (CCmode, 17), const0_rtx);
if (TARGET_64BIT)
- emit_insn (gen_subdi3_carry_rex64 (out, out, GEN_INT (3)));
+ emit_insn (gen_subdi3_carry_rex64 (out, out, GEN_INT (3), cmp));
else
- emit_insn (gen_subsi3_carry (out, out, GEN_INT (3)));
+ emit_insn (gen_subsi3_carry (out, out, GEN_INT (3), cmp));
emit_label (end_0_label);
}
void
-ix86_expand_call (retval, fnaddr, callarg1, callarg2, pop)
- rtx retval, fnaddr, callarg1, callarg2, pop;
+ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1,
+ rtx callarg2 ATTRIBUTE_UNUSED,
+ rtx pop, int sibcall)
{
rtx use = NULL, call;
@@ -11084,7 +11823,7 @@ ix86_expand_call (retval, fnaddr, callarg1, callarg2, pop)
/* Static functions and indirect calls don't need the pic register. */
if (! TARGET_64BIT && flag_pic
&& GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
- && ! SYMBOL_REF_FLAG (XEXP (fnaddr, 0)))
+ && ! SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
use_reg (&use, pic_offset_table_rtx);
if (TARGET_64BIT && INTVAL (callarg2) >= 0)
@@ -11100,6 +11839,15 @@ ix86_expand_call (retval, fnaddr, callarg1, callarg2, pop)
fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
fnaddr = gen_rtx_MEM (QImode, fnaddr);
}
+ if (sibcall && TARGET_64BIT
+ && !constant_call_address_operand (XEXP (fnaddr, 0), Pmode))
+ {
+ rtx addr;
+ addr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
+ fnaddr = gen_rtx_REG (Pmode, FIRST_REX_INT_REG + 3 /* R11 */);
+ emit_move_insn (fnaddr, addr);
+ fnaddr = gen_rtx_MEM (QImode, fnaddr);
+ }
call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
if (retval)
@@ -11122,9 +11870,14 @@ ix86_expand_call (retval, fnaddr, callarg1, callarg2, pop)
function. */
static struct machine_function *
-ix86_init_machine_status ()
+ix86_init_machine_status (void)
{
- return ggc_alloc_cleared (sizeof (struct machine_function));
+ struct machine_function *f;
+
+ f = ggc_alloc_cleared (sizeof (struct machine_function));
+ f->use_fast_prologue_epilogue_nregs = -1;
+
+ return f;
}
/* Return a MEM corresponding to a stack slot with mode MODE.
@@ -11134,25 +11887,33 @@ ix86_init_machine_status ()
which slot to use. */
rtx
-assign_386_stack_local (mode, n)
- enum machine_mode mode;
- int n;
+assign_386_stack_local (enum machine_mode mode, int n)
{
+ struct stack_local_entry *s;
+
if (n < 0 || n >= MAX_386_STACK_LOCALS)
abort ();
- if (ix86_stack_locals[(int) mode][n] == NULL_RTX)
- ix86_stack_locals[(int) mode][n]
- = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
+ for (s = ix86_stack_locals; s; s = s->next)
+ if (s->mode == mode && s->n == n)
+ return s->rtl;
- return ix86_stack_locals[(int) mode][n];
+ s = (struct stack_local_entry *)
+ ggc_alloc (sizeof (struct stack_local_entry));
+ s->n = n;
+ s->mode = mode;
+ s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
+
+ s->next = ix86_stack_locals;
+ ix86_stack_locals = s;
+ return s->rtl;
}
/* Construct the SYMBOL_REF for the tls_get_addr function. */
static GTY(()) rtx ix86_tls_symbol;
rtx
-ix86_tls_get_addr ()
+ix86_tls_get_addr (void)
{
if (!ix86_tls_symbol)
@@ -11170,8 +11931,7 @@ ix86_tls_get_addr ()
encoding. Does not include the one-byte modrm, opcode, or prefix. */
static int
-memory_address_length (addr)
- rtx addr;
+memory_address_length (rtx addr)
{
struct ix86_address parts;
rtx base, index, disp;
@@ -11227,7 +11987,7 @@ memory_address_length (addr)
else if (base == hard_frame_pointer_rtx)
len = 1;
- /* An index requires the two-byte modrm form... */
+ /* An index requires the two-byte modrm form.... */
if (index
/* ...like esp, which always wants an index. */
|| base == stack_pointer_rtx
@@ -11242,9 +12002,7 @@ memory_address_length (addr)
/* Compute default value for "length_immediate" attribute. When SHORTFORM
is set, expect that insn have 8bit immediate alternative. */
int
-ix86_attr_length_immediate_default (insn, shortform)
- rtx insn;
- int shortform;
+ix86_attr_length_immediate_default (rtx insn, int shortform)
{
int len = 0;
int i;
@@ -11284,8 +12042,7 @@ ix86_attr_length_immediate_default (insn, shortform)
}
/* Compute default value for "length_address" attribute. */
int
-ix86_attr_length_address_default (insn)
- rtx insn;
+ix86_attr_length_address_default (rtx insn)
{
int i;
@@ -11321,9 +12078,9 @@ ix86_attr_length_address_default (insn)
/* Return the maximum number of instructions a cpu can issue. */
static int
-ix86_issue_rate ()
+ix86_issue_rate (void)
{
- switch (ix86_cpu)
+ switch (ix86_tune)
{
case PROCESSOR_PENTIUM:
case PROCESSOR_K6:
@@ -11332,6 +12089,7 @@ ix86_issue_rate ()
case PROCESSOR_PENTIUMPRO:
case PROCESSOR_PENTIUM4:
case PROCESSOR_ATHLON:
+ case PROCESSOR_K8:
return 3;
default:
@@ -11343,9 +12101,7 @@ ix86_issue_rate ()
by DEP_INSN and nothing set by DEP_INSN. */
static int
-ix86_flags_dependant (insn, dep_insn, insn_type)
- rtx insn, dep_insn;
- enum attr_type insn_type;
+ix86_flags_dependant (rtx insn, rtx dep_insn, enum attr_type insn_type)
{
rtx set, set2;
@@ -11390,9 +12146,7 @@ ix86_flags_dependant (insn, dep_insn, insn_type)
address with operands set by DEP_INSN. */
static int
-ix86_agi_dependant (insn, dep_insn, insn_type)
- rtx insn, dep_insn;
- enum attr_type insn_type;
+ix86_agi_dependant (rtx insn, rtx dep_insn, enum attr_type insn_type)
{
rtx addr;
@@ -11427,16 +12181,14 @@ ix86_agi_dependant (insn, dep_insn, insn_type)
}
static int
-ix86_adjust_cost (insn, link, dep_insn, cost)
- rtx insn, link, dep_insn;
- int cost;
+ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
enum attr_type insn_type, dep_insn_type;
enum attr_memory memory, dep_memory;
rtx set, set2;
int dep_insn_code_number;
- /* Anti and output depenancies have zero cost on all CPUs. */
+ /* Anti and output dependencies have zero cost on all CPUs. */
if (REG_NOTE_KIND (link) != 0)
return 0;
@@ -11449,7 +12201,7 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
insn_type = get_attr_type (insn);
dep_insn_type = get_attr_type (dep_insn);
- switch (ix86_cpu)
+ switch (ix86_tune)
{
case PROCESSOR_PENTIUM:
/* Address Generation Interlock adds a cycle of latency. */
@@ -11460,7 +12212,7 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
if (ix86_flags_dependant (insn, dep_insn, insn_type))
cost = 0;
- /* Floating point stores require value to be ready one cycle ealier. */
+ /* Floating point stores require value to be ready one cycle earlier. */
if (insn_type == TYPE_FMOV
&& get_attr_memory (insn) == MEMORY_STORE
&& !ix86_agi_dependant (insn, dep_insn, insn_type))
@@ -11495,7 +12247,7 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
previous instruction is not needed to compute the address. */
if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
&& !ix86_agi_dependant (insn, dep_insn, insn_type))
- {
+ {
/* Claim moves to take one cycle, as core can issue one load
at time and the next load can start cycle later. */
if (dep_insn_type == TYPE_IMOV
@@ -11529,7 +12281,7 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
previous instruction is not needed to compute the address. */
if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
&& !ix86_agi_dependant (insn, dep_insn, insn_type))
- {
+ {
/* Claim moves to take one cycle, as core can issue one load
at time and the next load can start cycle later. */
if (dep_insn_type == TYPE_IMOV
@@ -11543,29 +12295,31 @@ ix86_adjust_cost (insn, link, dep_insn, cost)
break;
case PROCESSOR_ATHLON:
+ case PROCESSOR_K8:
memory = get_attr_memory (insn);
dep_memory = get_attr_memory (dep_insn);
- if (dep_memory == MEMORY_LOAD || dep_memory == MEMORY_BOTH)
- {
- if (dep_insn_type == TYPE_IMOV || dep_insn_type == TYPE_FMOV)
- cost += 2;
- else
- cost += 3;
- }
/* Show ability of reorder buffer to hide latency of load by executing
in parallel with previous instruction in case
previous instruction is not needed to compute the address. */
if ((memory == MEMORY_LOAD || memory == MEMORY_BOTH)
&& !ix86_agi_dependant (insn, dep_insn, insn_type))
- {
- /* Claim moves to take one cycle, as core can issue one load
- at time and the next load can start cycle later. */
- if (dep_insn_type == TYPE_IMOV
- || dep_insn_type == TYPE_FMOV)
- cost = 0;
- else if (cost >= 3)
- cost -= 3;
+ {
+ enum attr_unit unit = get_attr_unit (insn);
+ int loadcost = 3;
+
+ /* Because of the difference between the length of integer and
+ floating unit pipeline preparation stages, the memory operands
+ for floating point are cheaper.
+
+ ??? For Athlon it the difference is most probably 2. */
+ if (unit == UNIT_INTEGER || unit == UNIT_UNKNOWN)
+ loadcost = 3;
+ else
+ loadcost = TARGET_ATHLON ? 2 : 0;
+
+ if (cost >= loadcost)
+ cost -= loadcost;
else
cost = 0;
}
@@ -11587,8 +12341,7 @@ static union
} ix86_sched_data;
static enum attr_ppro_uops
-ix86_safe_ppro_uops (insn)
- rtx insn;
+ix86_safe_ppro_uops (rtx insn)
{
if (recog_memoized (insn) >= 0)
return get_attr_ppro_uops (insn);
@@ -11597,8 +12350,7 @@ ix86_safe_ppro_uops (insn)
}
static void
-ix86_dump_ppro_packet (dump)
- FILE *dump;
+ix86_dump_ppro_packet (FILE *dump)
{
if (ix86_sched_data.ppro.decode[0])
{
@@ -11615,10 +12367,9 @@ ix86_dump_ppro_packet (dump)
/* We're beginning a new block. Initialize data structures as necessary. */
static void
-ix86_sched_init (dump, sched_verbose, veclen)
- FILE *dump ATTRIBUTE_UNUSED;
- int sched_verbose ATTRIBUTE_UNUSED;
- int veclen ATTRIBUTE_UNUSED;
+ix86_sched_init (FILE *dump ATTRIBUTE_UNUSED,
+ int sched_verbose ATTRIBUTE_UNUSED,
+ int veclen ATTRIBUTE_UNUSED)
{
memset (&ix86_sched_data, 0, sizeof (ix86_sched_data));
}
@@ -11626,8 +12377,7 @@ ix86_sched_init (dump, sched_verbose, veclen)
/* Shift INSN to SLOT, and shift everything else down. */
static void
-ix86_reorder_insn (insnp, slot)
- rtx *insnp, *slot;
+ix86_reorder_insn (rtx *insnp, rtx *slot)
{
if (insnp != slot)
{
@@ -11640,9 +12390,7 @@ ix86_reorder_insn (insnp, slot)
}
static void
-ix86_sched_reorder_ppro (ready, e_ready)
- rtx *ready;
- rtx *e_ready;
+ix86_sched_reorder_ppro (rtx *ready, rtx *e_ready)
{
rtx decode[3];
enum attr_ppro_uops cur_uops;
@@ -11727,12 +12475,9 @@ ix86_sched_reorder_ppro (ready, e_ready)
/* We are about to being issuing insns for this clock cycle.
Override the default sort algorithm to better slot instructions. */
static int
-ix86_sched_reorder (dump, sched_verbose, ready, n_readyp, clock_var)
- FILE *dump ATTRIBUTE_UNUSED;
- int sched_verbose ATTRIBUTE_UNUSED;
- rtx *ready;
- int *n_readyp;
- int clock_var ATTRIBUTE_UNUSED;
+ix86_sched_reorder (FILE *dump ATTRIBUTE_UNUSED,
+ int sched_verbose ATTRIBUTE_UNUSED, rtx *ready,
+ int *n_readyp, int clock_var ATTRIBUTE_UNUSED)
{
int n_ready = *n_readyp;
rtx *e_ready = ready + n_ready - 1;
@@ -11746,7 +12491,7 @@ ix86_sched_reorder (dump, sched_verbose, ready, n_readyp, clock_var)
goto out;
}
- switch (ix86_cpu)
+ switch (ix86_tune)
{
default:
break;
@@ -11764,14 +12509,11 @@ out:
ready queue that can be issued this cycle. */
static int
-ix86_variable_issue (dump, sched_verbose, insn, can_issue_more)
- FILE *dump;
- int sched_verbose;
- rtx insn;
- int can_issue_more;
+ix86_variable_issue (FILE *dump, int sched_verbose, rtx insn,
+ int can_issue_more)
{
int i;
- switch (ix86_cpu)
+ switch (ix86_tune)
{
default:
return can_issue_more - 1;
@@ -11824,9 +12566,9 @@ ix86_variable_issue (dump, sched_verbose, insn, can_issue_more)
}
static int
-ia32_use_dfa_pipeline_interface ()
+ia32_use_dfa_pipeline_interface (void)
{
- if (ix86_cpu == PROCESSOR_PENTIUM)
+ if (TARGET_PENTIUM || TARGET_ATHLON_K8)
return 1;
return 0;
}
@@ -11836,61 +12578,15 @@ ia32_use_dfa_pipeline_interface ()
large results extra work for the scheduler. */
static int
-ia32_multipass_dfa_lookahead ()
+ia32_multipass_dfa_lookahead (void)
{
- if (ix86_cpu == PROCESSOR_PENTIUM)
+ if (ix86_tune == PROCESSOR_PENTIUM)
return 2;
else
return 0;
}
-/* Walk through INSNS and look for MEM references whose address is DSTREG or
- SRCREG and set the memory attribute to those of DSTREF and SRCREF, as
- appropriate. */
-
-void
-ix86_set_move_mem_attrs (insns, dstref, srcref, dstreg, srcreg)
- rtx insns;
- rtx dstref, srcref, dstreg, srcreg;
-{
- rtx insn;
-
- for (insn = insns; insn != 0 ; insn = NEXT_INSN (insn))
- if (INSN_P (insn))
- ix86_set_move_mem_attrs_1 (PATTERN (insn), dstref, srcref,
- dstreg, srcreg);
-}
-
-/* Subroutine of above to actually do the updating by recursively walking
- the rtx. */
-
-static void
-ix86_set_move_mem_attrs_1 (x, dstref, srcref, dstreg, srcreg)
- rtx x;
- rtx dstref, srcref, dstreg, srcreg;
-{
- enum rtx_code code = GET_CODE (x);
- const char *format_ptr = GET_RTX_FORMAT (code);
- int i, j;
-
- if (code == MEM && XEXP (x, 0) == dstreg)
- MEM_COPY_ATTRIBUTES (x, dstref);
- else if (code == MEM && XEXP (x, 0) == srcreg)
- MEM_COPY_ATTRIBUTES (x, srcref);
-
- for (i = 0; i < GET_RTX_LENGTH (code); i++, format_ptr++)
- {
- if (*format_ptr == 'e')
- ix86_set_move_mem_attrs_1 (XEXP (x, i), dstref, srcref,
- dstreg, srcreg);
- else if (*format_ptr == 'E')
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- ix86_set_move_mem_attrs_1 (XVECEXP (x, i, j), dstref, srcref,
- dstreg, srcreg);
- }
-}
-
/* Compute the alignment given to a constant that is being placed in memory.
EXP is the constant and ALIGN is the alignment that the object would
ordinarily have.
@@ -11898,9 +12594,7 @@ ix86_set_move_mem_attrs_1 (x, dstref, srcref, dstreg, srcreg)
the object. */
int
-ix86_constant_alignment (exp, align)
- tree exp;
- int align;
+ix86_constant_alignment (tree exp, int align)
{
if (TREE_CODE (exp) == REAL_CST)
{
@@ -11909,9 +12603,9 @@ ix86_constant_alignment (exp, align)
else if (ALIGN_MODE_128 (TYPE_MODE (TREE_TYPE (exp))) && align < 128)
return 128;
}
- else if (TREE_CODE (exp) == STRING_CST && TREE_STRING_LENGTH (exp) >= 31
- && align < 256)
- return 256;
+ else if (!optimize_size && TREE_CODE (exp) == STRING_CST
+ && TREE_STRING_LENGTH (exp) >= 31 && align < BITS_PER_WORD)
+ return BITS_PER_WORD;
return align;
}
@@ -11922,9 +12616,7 @@ ix86_constant_alignment (exp, align)
instead of that alignment to align the object. */
int
-ix86_data_alignment (type, align)
- tree type;
- int align;
+ix86_data_alignment (tree type, int align)
{
if (AGGREGATE_TYPE_P (type)
&& TYPE_SIZE (type)
@@ -11988,9 +12680,7 @@ ix86_data_alignment (type, align)
instead of that alignment to align the object. */
int
-ix86_local_alignment (type, align)
- tree type;
- int align;
+ix86_local_alignment (tree type, int align)
{
/* x86-64 ABI requires arrays greater than 16 bytes to be aligned
to 16byte boundary. */
@@ -12043,8 +12733,7 @@ ix86_local_alignment (type, align)
FNADDR is an RTX for the address of the function's pure code.
CXT is an RTX for the static chain value for the function. */
void
-x86_initialize_trampoline (tramp, fnaddr, cxt)
- rtx tramp, fnaddr, cxt;
+x86_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt)
{
if (!TARGET_64BIT)
{
@@ -12098,7 +12787,7 @@ x86_initialize_trampoline (tramp, fnaddr, cxt)
abort ();
}
-#ifdef TRANSFER_FROM_TRAMPOLINE
+#ifdef ENABLE_EXECUTE_STACK
emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
#endif
@@ -12411,13 +13100,13 @@ static const struct builtin_description bdesc_2arg[] =
{ MASK_SSE2, CODE_FOR_cvtsd2ss, 0, IX86_BUILTIN_CVTSD2SS, 0, 0 },
{ MASK_SSE2, CODE_FOR_cvtss2sd, 0, IX86_BUILTIN_CVTSS2SD, 0, 0 },
- /* PNI MMX */
- { MASK_PNI, CODE_FOR_addsubv4sf3, "__builtin_ia32_addsubps", IX86_BUILTIN_ADDSUBPS, 0, 0 },
- { MASK_PNI, CODE_FOR_addsubv2df3, "__builtin_ia32_addsubpd", IX86_BUILTIN_ADDSUBPD, 0, 0 },
- { MASK_PNI, CODE_FOR_haddv4sf3, "__builtin_ia32_haddps", IX86_BUILTIN_HADDPS, 0, 0 },
- { MASK_PNI, CODE_FOR_haddv2df3, "__builtin_ia32_haddpd", IX86_BUILTIN_HADDPD, 0, 0 },
- { MASK_PNI, CODE_FOR_hsubv4sf3, "__builtin_ia32_hsubps", IX86_BUILTIN_HSUBPS, 0, 0 },
- { MASK_PNI, CODE_FOR_hsubv2df3, "__builtin_ia32_hsubpd", IX86_BUILTIN_HSUBPD, 0, 0 }
+ /* SSE3 MMX */
+ { MASK_SSE3, CODE_FOR_addsubv4sf3, "__builtin_ia32_addsubps", IX86_BUILTIN_ADDSUBPS, 0, 0 },
+ { MASK_SSE3, CODE_FOR_addsubv2df3, "__builtin_ia32_addsubpd", IX86_BUILTIN_ADDSUBPD, 0, 0 },
+ { MASK_SSE3, CODE_FOR_haddv4sf3, "__builtin_ia32_haddps", IX86_BUILTIN_HADDPS, 0, 0 },
+ { MASK_SSE3, CODE_FOR_haddv2df3, "__builtin_ia32_haddpd", IX86_BUILTIN_HADDPD, 0, 0 },
+ { MASK_SSE3, CODE_FOR_hsubv4sf3, "__builtin_ia32_hsubps", IX86_BUILTIN_HSUBPS, 0, 0 },
+ { MASK_SSE3, CODE_FOR_hsubv2df3, "__builtin_ia32_hsubpd", IX86_BUILTIN_HSUBPD, 0, 0 }
};
static const struct builtin_description bdesc_1arg[] =
@@ -12465,14 +13154,14 @@ static const struct builtin_description bdesc_1arg[] =
{ MASK_SSE2, CODE_FOR_sse2_movq, 0, IX86_BUILTIN_MOVQ, 0, 0 },
- /* PNI */
- { MASK_PNI, CODE_FOR_movshdup, 0, IX86_BUILTIN_MOVSHDUP, 0, 0 },
- { MASK_PNI, CODE_FOR_movsldup, 0, IX86_BUILTIN_MOVSLDUP, 0, 0 },
- { MASK_PNI, CODE_FOR_movddup, 0, IX86_BUILTIN_MOVDDUP, 0, 0 }
+ /* SSE3 */
+ { MASK_SSE3, CODE_FOR_movshdup, 0, IX86_BUILTIN_MOVSHDUP, 0, 0 },
+ { MASK_SSE3, CODE_FOR_movsldup, 0, IX86_BUILTIN_MOVSLDUP, 0, 0 },
+ { MASK_SSE3, CODE_FOR_movddup, 0, IX86_BUILTIN_MOVDDUP, 0, 0 }
};
void
-ix86_init_builtins ()
+ix86_init_builtins (void)
{
if (TARGET_MMX)
ix86_init_mmx_sse_builtins ();
@@ -12482,7 +13171,7 @@ ix86_init_builtins ()
is zero. Otherwise, if TARGET_SSE is not set, only expand the MMX
builtins. */
static void
-ix86_init_mmx_sse_builtins ()
+ix86_init_mmx_sse_builtins (void)
{
const struct builtin_description * d;
size_t i;
@@ -12679,7 +13368,7 @@ ix86_init_mmx_sse_builtins ()
= build_function_type_list (integer_type_node, V2DF_type_node, NULL_TREE);
tree int64_ftype_v2df
= build_function_type_list (long_long_integer_type_node,
- V2DF_type_node, NULL_TREE);
+ V2DF_type_node, NULL_TREE);
tree v2df_ftype_v2df_int
= build_function_type_list (V2DF_type_node,
V2DF_type_node, integer_type_node, NULL_TREE);
@@ -12787,6 +13476,27 @@ ix86_init_mmx_sse_builtins ()
tree v2di_ftype_v2di
= build_function_type_list (V2DI_type_node, V2DI_type_node, NULL_TREE);
+ tree float80_type;
+ tree float128_type;
+
+ /* The __float80 type. */
+ if (TYPE_MODE (long_double_type_node) == XFmode)
+ (*lang_hooks.types.register_builtin_type) (long_double_type_node,
+ "__float80");
+ else
+ {
+ /* The __float80 type. */
+ float80_type = make_node (REAL_TYPE);
+ TYPE_PRECISION (float80_type) = 96;
+ layout_type (float80_type);
+ (*lang_hooks.types.register_builtin_type) (float80_type, "__float80");
+ }
+
+ float128_type = make_node (REAL_TYPE);
+ TYPE_PRECISION (float128_type) = 128;
+ layout_type (float128_type);
+ (*lang_hooks.types.register_builtin_type) (float128_type, "__float128");
+
/* Add all builtins that are more or less simple operations on two
operands. */
for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
@@ -13073,23 +13783,23 @@ ix86_init_mmx_sse_builtins ()
def_builtin (MASK_SSE2, "__builtin_ia32_pmaddwd128", v4si_ftype_v8hi_v8hi, IX86_BUILTIN_PMADDWD128);
/* Prescott New Instructions. */
- def_builtin (MASK_PNI, "__builtin_ia32_monitor",
+ def_builtin (MASK_SSE3, "__builtin_ia32_monitor",
void_ftype_pcvoid_unsigned_unsigned,
IX86_BUILTIN_MONITOR);
- def_builtin (MASK_PNI, "__builtin_ia32_mwait",
+ def_builtin (MASK_SSE3, "__builtin_ia32_mwait",
void_ftype_unsigned_unsigned,
IX86_BUILTIN_MWAIT);
- def_builtin (MASK_PNI, "__builtin_ia32_movshdup",
+ def_builtin (MASK_SSE3, "__builtin_ia32_movshdup",
v4sf_ftype_v4sf,
IX86_BUILTIN_MOVSHDUP);
- def_builtin (MASK_PNI, "__builtin_ia32_movsldup",
+ def_builtin (MASK_SSE3, "__builtin_ia32_movsldup",
v4sf_ftype_v4sf,
IX86_BUILTIN_MOVSLDUP);
- def_builtin (MASK_PNI, "__builtin_ia32_lddqu",
+ def_builtin (MASK_SSE3, "__builtin_ia32_lddqu",
v16qi_ftype_pcchar, IX86_BUILTIN_LDDQU);
- def_builtin (MASK_PNI, "__builtin_ia32_loadddup",
+ def_builtin (MASK_SSE3, "__builtin_ia32_loadddup",
v2df_ftype_pcdouble, IX86_BUILTIN_LOADDDUP);
- def_builtin (MASK_PNI, "__builtin_ia32_movddup",
+ def_builtin (MASK_SSE3, "__builtin_ia32_movddup",
v2df_ftype_v2df, IX86_BUILTIN_MOVDDUP);
}
@@ -13097,9 +13807,7 @@ ix86_init_mmx_sse_builtins ()
where we expect a vector. To avoid crashing, use one of the vector
clear instructions. */
static rtx
-safe_vector_operand (x, mode)
- rtx x;
- enum machine_mode mode;
+safe_vector_operand (rtx x, enum machine_mode mode)
{
if (x != const0_rtx)
return x;
@@ -13110,17 +13818,15 @@ safe_vector_operand (x, mode)
: gen_rtx_SUBREG (DImode, x, 0)));
else
emit_insn (gen_sse_clrv4sf (mode == V4SFmode ? x
- : gen_rtx_SUBREG (V4SFmode, x, 0)));
+ : gen_rtx_SUBREG (V4SFmode, x, 0),
+ CONST0_RTX (V4SFmode)));
return x;
}
/* Subroutine of ix86_expand_builtin to take care of binop insns. */
static rtx
-ix86_expand_binop_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+ix86_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
@@ -13150,7 +13856,8 @@ ix86_expand_binop_builtin (icode, arglist, target)
/* In case the insn wants input operands in modes different from
the result, abort. */
- if (GET_MODE (op0) != mode0 || GET_MODE (op1) != mode1)
+ if ((GET_MODE (op0) != mode0 && GET_MODE (op0) != VOIDmode)
+ || (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode))
abort ();
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
@@ -13174,9 +13881,7 @@ ix86_expand_binop_builtin (icode, arglist, target)
/* Subroutine of ix86_expand_builtin to take care of stores. */
static rtx
-ix86_expand_store_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+ix86_expand_store_builtin (enum insn_code icode, tree arglist)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
@@ -13201,11 +13906,8 @@ ix86_expand_store_builtin (icode, arglist)
/* Subroutine of ix86_expand_builtin to take care of unop insns. */
static rtx
-ix86_expand_unop_builtin (icode, arglist, target, do_load)
- enum insn_code icode;
- tree arglist;
- rtx target;
- int do_load;
+ix86_expand_unop_builtin (enum insn_code icode, tree arglist,
+ rtx target, int do_load)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
@@ -13239,10 +13941,7 @@ ix86_expand_unop_builtin (icode, arglist, target, do_load)
sqrtss, rsqrtss, rcpss. */
static rtx
-ix86_expand_unop1_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+ix86_expand_unop1_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
@@ -13275,10 +13974,8 @@ ix86_expand_unop1_builtin (icode, arglist, target)
/* Subroutine of ix86_expand_builtin to take care of comparison insns. */
static rtx
-ix86_expand_sse_compare (d, arglist, target)
- const struct builtin_description *d;
- tree arglist;
- rtx target;
+ix86_expand_sse_compare (const struct builtin_description *d, tree arglist,
+ rtx target)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
@@ -13327,10 +14024,8 @@ ix86_expand_sse_compare (d, arglist, target)
/* Subroutine of ix86_expand_builtin to take care of comi insns. */
static rtx
-ix86_expand_sse_comi (d, arglist, target)
- const struct builtin_description *d;
- tree arglist;
- rtx target;
+ix86_expand_sse_comi (const struct builtin_description *d, tree arglist,
+ rtx target)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
@@ -13386,12 +14081,9 @@ ix86_expand_sse_comi (d, arglist, target)
IGNORE is nonzero if the value is to be ignored. */
rtx
-ix86_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
+ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
{
const struct builtin_description *d;
size_t i;
@@ -13430,8 +14122,8 @@ ix86_expand_builtin (exp, target, subtarget, mode, ignore)
op0 = copy_to_mode_reg (mode0, op0);
if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
{
- /* @@@ better error message */
- error ("selector must be an immediate");
+ error ("selector must be an integer constant in the range 0..%i",
+ fcode == IX86_BUILTIN_PEXTRW ? 3:7);
return gen_reg_rtx (tmode);
}
if (target == 0
@@ -13466,8 +14158,8 @@ ix86_expand_builtin (exp, target, subtarget, mode, ignore)
op1 = copy_to_mode_reg (mode1, op1);
if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
{
- /* @@@ better error message */
- error ("selector must be an immediate");
+ error ("selector must be an integer constant in the range 0..%i",
+ fcode == IX86_BUILTIN_PINSRW ? 15:255);
return const0_rtx;
}
if (target == 0
@@ -13541,7 +14233,7 @@ ix86_expand_builtin (exp, target, subtarget, mode, ignore)
icode = (fcode == IX86_BUILTIN_LOADHPS ? CODE_FOR_sse_movhps
: fcode == IX86_BUILTIN_LOADLPS ? CODE_FOR_sse_movlps
: fcode == IX86_BUILTIN_LOADHPD ? CODE_FOR_sse2_movhpd
- : CODE_FOR_sse2_movlpd);
+ : CODE_FOR_sse2_movsd);
arg0 = TREE_VALUE (arglist);
arg1 = TREE_VALUE (TREE_CHAIN (arglist));
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
@@ -13570,7 +14262,7 @@ ix86_expand_builtin (exp, target, subtarget, mode, ignore)
icode = (fcode == IX86_BUILTIN_STOREHPS ? CODE_FOR_sse_movhps
: fcode == IX86_BUILTIN_STORELPS ? CODE_FOR_sse_movlps
: fcode == IX86_BUILTIN_STOREHPD ? CODE_FOR_sse2_movhpd
- : CODE_FOR_sse2_movlpd);
+ : CODE_FOR_sse2_movsd);
arg0 = TREE_VALUE (arglist);
arg1 = TREE_VALUE (TREE_CHAIN (arglist));
op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
@@ -13785,7 +14477,7 @@ ix86_expand_builtin (exp, target, subtarget, mode, ignore)
case IX86_BUILTIN_SSE_ZERO:
target = gen_reg_rtx (V4SFmode);
- emit_insn (gen_sse_clrv4sf (target));
+ emit_insn (gen_sse_clrv4sf (target, CONST0_RTX (V4SFmode)));
return target;
case IX86_BUILTIN_MMX_ZERO:
@@ -13970,14 +14662,12 @@ ix86_expand_builtin (exp, target, subtarget, mode, ignore)
/* Store OPERAND to the memory after reload is completed. This means
that we can't easily use assign_stack_local. */
rtx
-ix86_force_to_memory (mode, operand)
- enum machine_mode mode;
- rtx operand;
+ix86_force_to_memory (enum machine_mode mode, rtx operand)
{
rtx result;
if (!reload_completed)
abort ();
- if (TARGET_64BIT && TARGET_RED_ZONE)
+ if (TARGET_RED_ZONE)
{
result = gen_rtx_MEM (mode,
gen_rtx_PLUS (Pmode,
@@ -13985,7 +14675,7 @@ ix86_force_to_memory (mode, operand)
GEN_INT (-RED_ZONE_SIZE)));
emit_move_insn (result, operand);
}
- else if (TARGET_64BIT && !TARGET_RED_ZONE)
+ else if (!TARGET_RED_ZONE && TARGET_64BIT)
{
switch (mode)
{
@@ -14051,10 +14741,9 @@ ix86_force_to_memory (mode, operand)
/* Free operand from the memory. */
void
-ix86_free_from_memory (mode)
- enum machine_mode mode;
+ix86_free_from_memory (enum machine_mode mode)
{
- if (!TARGET_64BIT || !TARGET_RED_ZONE)
+ if (!TARGET_RED_ZONE)
{
int size;
@@ -14077,9 +14766,7 @@ ix86_free_from_memory (mode)
Narrow ALL_REGS to GENERAL_REGS. This supports allowing movsf and
movdf to do mem-to-mem moves through integer regs. */
enum reg_class
-ix86_preferred_reload_class (x, class)
- rtx x;
- enum reg_class class;
+ix86_preferred_reload_class (rtx x, enum reg_class class)
{
if (GET_CODE (x) == CONST_VECTOR && x != CONST0_RTX (GET_MODE (x)))
return NO_REGS;
@@ -14123,10 +14810,8 @@ ix86_preferred_reload_class (x, class)
When STRICT is false, we are being called from REGISTER_MOVE_COST, so do not
enforce these sanity checks. */
int
-ix86_secondary_memory_needed (class1, class2, mode, strict)
- enum reg_class class1, class2;
- enum machine_mode mode;
- int strict;
+ix86_secondary_memory_needed (enum reg_class class1, enum reg_class class2,
+ enum machine_mode mode, int strict)
{
if (MAYBE_FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class1)
|| MAYBE_FLOAT_CLASS_P (class2) != FLOAT_CLASS_P (class2)
@@ -14141,10 +14826,10 @@ ix86_secondary_memory_needed (class1, class2, mode, strict)
return 1;
}
return (FLOAT_CLASS_P (class1) != FLOAT_CLASS_P (class2)
- || (SSE_CLASS_P (class1) != SSE_CLASS_P (class2)
- && (mode) != SImode)
- || (MMX_CLASS_P (class1) != MMX_CLASS_P (class2)
- && (mode) != SImode));
+ || ((SSE_CLASS_P (class1) != SSE_CLASS_P (class2)
+ || MMX_CLASS_P (class1) != MMX_CLASS_P (class2))
+ && ((mode != SImode && (mode != DImode || !TARGET_64BIT))
+ || (!TARGET_INTER_UNIT_MOVES && !optimize_size))));
}
/* Return the cost of moving data from a register in class CLASS1 to
one in class CLASS2.
@@ -14153,12 +14838,11 @@ ix86_secondary_memory_needed (class1, class2, mode, strict)
on some machines it is expensive to move between registers if they are not
general registers. */
int
-ix86_register_move_cost (mode, class1, class2)
- enum machine_mode mode;
- enum reg_class class1, class2;
+ix86_register_move_cost (enum machine_mode mode, enum reg_class class1,
+ enum reg_class class2)
{
/* In case we require secondary memory, compute cost of the store followed
- by load. In order to avoid bad register allocation choices, we need
+ by load. In order to avoid bad register allocation choices, we need
for this to be *at least* as high as the symmetric MEMORY_MOVE_COST. */
if (ix86_secondary_memory_needed (class1, class2, mode, 0))
@@ -14169,10 +14853,10 @@ ix86_register_move_cost (mode, class1, class2)
MEMORY_MOVE_COST (mode, class1, 1));
cost += MAX (MEMORY_MOVE_COST (mode, class2, 0),
MEMORY_MOVE_COST (mode, class2, 1));
-
+
/* In case of copying from general_purpose_register we may emit multiple
stores followed by single load causing memory size mismatch stall.
- Count this as arbitarily high cost of 20. */
+ Count this as arbitrarily high cost of 20. */
if (CLASS_MAX_NREGS (class1, mode) > CLASS_MAX_NREGS (class2, mode))
cost += 20;
@@ -14200,9 +14884,7 @@ ix86_register_move_cost (mode, class1, class2)
/* Return 1 if hard register REGNO can hold a value of machine-mode MODE. */
int
-ix86_hard_regno_mode_ok (regno, mode)
- int regno;
- enum machine_mode mode;
+ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
{
/* Flags and only flags can only hold CCmode values. */
if (CC_REGNO_P (regno))
@@ -14241,10 +14923,7 @@ ix86_hard_regno_mode_ok (regno, mode)
Q_REGS classes.
*/
int
-ix86_memory_move_cost (mode, class, in)
- enum machine_mode mode;
- enum reg_class class;
- int in;
+ix86_memory_move_cost (enum machine_mode mode, enum reg_class class, int in)
{
if (FLOAT_CLASS_P (class))
{
@@ -14258,7 +14937,6 @@ ix86_memory_move_cost (mode, class, in)
index = 1;
break;
case XFmode:
- case TFmode:
index = 2;
break;
default:
@@ -14318,16 +14996,272 @@ ix86_memory_move_cost (mode, class, in)
if (mode == TFmode)
mode = XFmode;
return ((in ? ix86_cost->int_load[2] : ix86_cost->int_store[2])
- * ((int) GET_MODE_SIZE (mode)
- + UNITS_PER_WORD -1 ) / UNITS_PER_WORD);
+ * (((int) GET_MODE_SIZE (mode)
+ + UNITS_PER_WORD - 1) / UNITS_PER_WORD));
+ }
+}
+
+/* Compute a (partial) cost for rtx X. Return true if the complete
+ cost has been computed, and false if subexpressions should be
+ scanned. In either case, *TOTAL contains the cost result. */
+
+static bool
+ix86_rtx_costs (rtx x, int code, int outer_code, int *total)
+{
+ enum machine_mode mode = GET_MODE (x);
+
+ switch (code)
+ {
+ case CONST_INT:
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ if (TARGET_64BIT && !x86_64_sign_extended_value (x))
+ *total = 3;
+ else if (TARGET_64BIT && !x86_64_zero_extended_value (x))
+ *total = 2;
+ else if (flag_pic && SYMBOLIC_CONST (x)
+ && (!TARGET_64BIT
+ || (!GET_CODE (x) != LABEL_REF
+ && (GET_CODE (x) != SYMBOL_REF
+ || !SYMBOL_REF_LOCAL_P (x)))))
+ *total = 1;
+ else
+ *total = 0;
+ return true;
+
+ case CONST_DOUBLE:
+ if (mode == VOIDmode)
+ *total = 0;
+ else
+ switch (standard_80387_constant_p (x))
+ {
+ case 1: /* 0.0 */
+ *total = 1;
+ break;
+ default: /* Other constants */
+ *total = 2;
+ break;
+ case 0:
+ case -1:
+ /* Start with (MEM (SYMBOL_REF)), since that's where
+ it'll probably end up. Add a penalty for size. */
+ *total = (COSTS_N_INSNS (1)
+ + (flag_pic != 0 && !TARGET_64BIT)
+ + (mode == SFmode ? 0 : mode == DFmode ? 1 : 2));
+ break;
+ }
+ return true;
+
+ case ZERO_EXTEND:
+ /* The zero extensions is often completely free on x86_64, so make
+ it as cheap as possible. */
+ if (TARGET_64BIT && mode == DImode
+ && GET_MODE (XEXP (x, 0)) == SImode)
+ *total = 1;
+ else if (TARGET_ZERO_EXTEND_WITH_AND)
+ *total = COSTS_N_INSNS (ix86_cost->add);
+ else
+ *total = COSTS_N_INSNS (ix86_cost->movzx);
+ return false;
+
+ case SIGN_EXTEND:
+ *total = COSTS_N_INSNS (ix86_cost->movsx);
+ return false;
+
+ case ASHIFT:
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (GET_MODE (XEXP (x, 0)) != DImode || TARGET_64BIT))
+ {
+ HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
+ if (value == 1)
+ {
+ *total = COSTS_N_INSNS (ix86_cost->add);
+ return false;
+ }
+ if ((value == 2 || value == 3)
+ && !TARGET_DECOMPOSE_LEA
+ && ix86_cost->lea <= ix86_cost->shift_const)
+ {
+ *total = COSTS_N_INSNS (ix86_cost->lea);
+ return false;
+ }
+ }
+ /* FALLTHRU */
+
+ case ROTATE:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ case ROTATERT:
+ if (!TARGET_64BIT && GET_MODE (XEXP (x, 0)) == DImode)
+ {
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ if (INTVAL (XEXP (x, 1)) > 32)
+ *total = COSTS_N_INSNS(ix86_cost->shift_const + 2);
+ else
+ *total = COSTS_N_INSNS(ix86_cost->shift_const * 2);
+ }
+ else
+ {
+ if (GET_CODE (XEXP (x, 1)) == AND)
+ *total = COSTS_N_INSNS(ix86_cost->shift_var * 2);
+ else
+ *total = COSTS_N_INSNS(ix86_cost->shift_var * 6 + 2);
+ }
+ }
+ else
+ {
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ *total = COSTS_N_INSNS (ix86_cost->shift_const);
+ else
+ *total = COSTS_N_INSNS (ix86_cost->shift_var);
+ }
+ return false;
+
+ case MULT:
+ if (FLOAT_MODE_P (mode))
+ *total = COSTS_N_INSNS (ix86_cost->fmul);
+ else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ unsigned HOST_WIDE_INT value = INTVAL (XEXP (x, 1));
+ int nbits;
+
+ for (nbits = 0; value != 0; value >>= 1)
+ nbits++;
+
+ *total = COSTS_N_INSNS (ix86_cost->mult_init[MODE_INDEX (mode)]
+ + nbits * ix86_cost->mult_bit);
+ }
+ else
+ {
+ /* This is arbitrary */
+ *total = COSTS_N_INSNS (ix86_cost->mult_init[MODE_INDEX (mode)]
+ + 7 * ix86_cost->mult_bit);
+ }
+ return false;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ if (FLOAT_MODE_P (mode))
+ *total = COSTS_N_INSNS (ix86_cost->fdiv);
+ else
+ *total = COSTS_N_INSNS (ix86_cost->divide[MODE_INDEX (mode)]);
+ return false;
+
+ case PLUS:
+ if (FLOAT_MODE_P (mode))
+ *total = COSTS_N_INSNS (ix86_cost->fadd);
+ else if (!TARGET_DECOMPOSE_LEA
+ && GET_MODE_CLASS (mode) == MODE_INT
+ && GET_MODE_BITSIZE (mode) <= GET_MODE_BITSIZE (Pmode))
+ {
+ if (GET_CODE (XEXP (x, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
+ && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
+ && CONSTANT_P (XEXP (x, 1)))
+ {
+ HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));
+ if (val == 2 || val == 4 || val == 8)
+ {
+ *total = COSTS_N_INSNS (ix86_cost->lea);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 1), outer_code);
+ *total += rtx_cost (XEXP (XEXP (XEXP (x, 0), 0), 0),
+ outer_code);
+ *total += rtx_cost (XEXP (x, 1), outer_code);
+ return true;
+ }
+ }
+ else if (GET_CODE (XEXP (x, 0)) == MULT
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
+ {
+ HOST_WIDE_INT val = INTVAL (XEXP (XEXP (x, 0), 1));
+ if (val == 2 || val == 4 || val == 8)
+ {
+ *total = COSTS_N_INSNS (ix86_cost->lea);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), outer_code);
+ *total += rtx_cost (XEXP (x, 1), outer_code);
+ return true;
+ }
+ }
+ else if (GET_CODE (XEXP (x, 0)) == PLUS)
+ {
+ *total = COSTS_N_INSNS (ix86_cost->lea);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), outer_code);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 1), outer_code);
+ *total += rtx_cost (XEXP (x, 1), outer_code);
+ return true;
+ }
+ }
+ /* FALLTHRU */
+
+ case MINUS:
+ if (FLOAT_MODE_P (mode))
+ {
+ *total = COSTS_N_INSNS (ix86_cost->fadd);
+ return false;
+ }
+ /* FALLTHRU */
+
+ case AND:
+ case IOR:
+ case XOR:
+ if (!TARGET_64BIT && mode == DImode)
+ {
+ *total = (COSTS_N_INSNS (ix86_cost->add) * 2
+ + (rtx_cost (XEXP (x, 0), outer_code)
+ << (GET_MODE (XEXP (x, 0)) != DImode))
+ + (rtx_cost (XEXP (x, 1), outer_code)
+ << (GET_MODE (XEXP (x, 1)) != DImode)));
+ return true;
+ }
+ /* FALLTHRU */
+
+ case NEG:
+ if (FLOAT_MODE_P (mode))
+ {
+ *total = COSTS_N_INSNS (ix86_cost->fchs);
+ return false;
+ }
+ /* FALLTHRU */
+
+ case NOT:
+ if (!TARGET_64BIT && mode == DImode)
+ *total = COSTS_N_INSNS (ix86_cost->add * 2);
+ else
+ *total = COSTS_N_INSNS (ix86_cost->add);
+ return false;
+
+ case FLOAT_EXTEND:
+ if (!TARGET_SSE_MATH || !VALID_SSE_REG_MODE (mode))
+ *total = 0;
+ return false;
+
+ case ABS:
+ if (FLOAT_MODE_P (mode))
+ *total = COSTS_N_INSNS (ix86_cost->fabs);
+ return false;
+
+ case SQRT:
+ if (FLOAT_MODE_P (mode))
+ *total = COSTS_N_INSNS (ix86_cost->fsqrt);
+ return false;
+
+ case UNSPEC:
+ if (XINT (x, 1) == UNSPEC_TP)
+ *total = 0;
+ return false;
+
+ default:
+ return false;
}
}
#if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION)
static void
-ix86_svr3_asm_out_constructor (symbol, priority)
- rtx symbol;
- int priority ATTRIBUTE_UNUSED;
+ix86_svr3_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
init_section ();
fputs ("\tpushl $", asm_out_file);
@@ -14344,9 +15278,7 @@ static int current_machopic_label_num;
definition of the stub. */
void
-machopic_output_stub (file, symb, stub)
- FILE *file;
- const char *symb, *stub;
+machopic_output_stub (FILE *file, const char *symb, const char *stub)
{
unsigned int length;
char *binder_name, *symbol_name, lazy_ptr_name[32];
@@ -14381,9 +15313,9 @@ machopic_output_stub (file, symb, stub)
}
else
fprintf (file, "\tjmp *%s\n", lazy_ptr_name);
-
+
fprintf (file, "%s:\n", binder_name);
-
+
if (MACHOPIC_PURE)
{
fprintf (file, "\tlea %s-LPC$%d(%%eax),%%eax\n", lazy_ptr_name, label);
@@ -14404,7 +15336,7 @@ machopic_output_stub (file, symb, stub)
/* Order the registers for register allocator. */
void
-x86_order_regs_for_local_alloc ()
+x86_order_regs_for_local_alloc (void)
{
int pos = 0;
int i;
@@ -14431,7 +15363,7 @@ x86_order_regs_for_local_alloc ()
for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
reg_alloc_order [pos++] = i;
- /* x87 registerts. */
+ /* x87 registers. */
if (TARGET_SSE_MATH)
for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
reg_alloc_order [pos++] = i;
@@ -14445,22 +15377,69 @@ x86_order_regs_for_local_alloc ()
reg_alloc_order [pos++] = 0;
}
+#ifndef TARGET_USE_MS_BITFIELD_LAYOUT
+#define TARGET_USE_MS_BITFIELD_LAYOUT 0
+#endif
+
+/* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
+ struct attribute_spec.handler. */
+static tree
+ix86_handle_struct_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+ tree *type = NULL;
+ if (DECL_P (*node))
+ {
+ if (TREE_CODE (*node) == TYPE_DECL)
+ type = &TREE_TYPE (*node);
+ }
+ else
+ type = node;
+
+ if (!(type && (TREE_CODE (*type) == RECORD_TYPE
+ || TREE_CODE (*type) == UNION_TYPE)))
+ {
+ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+
+ else if ((is_attribute_p ("ms_struct", name)
+ && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
+ || ((is_attribute_p ("gcc_struct", name)
+ && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
+ {
+ warning ("`%s' incompatible attribute ignored",
+ IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
+
+static bool
+ix86_ms_bitfield_layout_p (tree record_type)
+{
+ return (TARGET_USE_MS_BITFIELD_LAYOUT &&
+ !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
+ || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
+}
+
/* Returns an expression indicating where the this parameter is
located on entry to the FUNCTION. */
static rtx
-x86_this_parameter (function)
- tree function;
+x86_this_parameter (tree function)
{
tree type = TREE_TYPE (function);
if (TARGET_64BIT)
{
- int n = aggregate_value_p (TREE_TYPE (type)) != 0;
+ int n = aggregate_value_p (TREE_TYPE (type), type) != 0;
return gen_rtx_REG (DImode, x86_64_int_parameter_registers[n]);
}
- if (ix86_fntype_regparm (type) > 0)
+ if (ix86_function_regparm (type, function) > 0)
{
tree parm;
@@ -14470,12 +15449,17 @@ x86_this_parameter (function)
for (; parm; parm = TREE_CHAIN (parm))
if (TREE_VALUE (parm) == void_type_node)
break;
- /* If not, the this parameter is in %eax. */
+ /* If not, the this parameter is in the first argument. */
if (parm)
- return gen_rtx_REG (SImode, 0);
+ {
+ int regno = 0;
+ if (lookup_attribute ("fastcall", TYPE_ATTRIBUTES (type)))
+ regno = 2;
+ return gen_rtx_REG (SImode, regno);
+ }
}
- if (aggregate_value_p (TREE_TYPE (type)))
+ if (aggregate_value_p (TREE_TYPE (type), type))
return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 8));
else
return gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, 4));
@@ -14484,18 +15468,16 @@ x86_this_parameter (function)
/* Determine whether x86_output_mi_thunk can succeed. */
static bool
-x86_can_output_mi_thunk (thunk, delta, vcall_offset, function)
- tree thunk ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta ATTRIBUTE_UNUSED;
- HOST_WIDE_INT vcall_offset;
- tree function;
+x86_can_output_mi_thunk (tree thunk ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT vcall_offset, tree function)
{
/* 64-bit can handle anything. */
if (TARGET_64BIT)
return true;
/* For 32-bit, everything's fine if we have one free register. */
- if (ix86_fntype_regparm (TREE_TYPE (function)) < 3)
+ if (ix86_function_regparm (TREE_TYPE (function), function) < 3)
return true;
/* Need a free register for vcall_offset. */
@@ -14513,16 +15495,13 @@ x86_can_output_mi_thunk (thunk, delta, vcall_offset, function)
/* Output the assembler code for a thunk function. THUNK_DECL is the
declaration for the thunk function itself, FUNCTION is the decl for
the target function. DELTA is an immediate constant offset to be
- added to THIS. If VCALL_OFFSET is non-zero, the word at
+ added to THIS. If VCALL_OFFSET is nonzero, the word at
*(*this + vcall_offset) should be added to THIS. */
static void
-x86_output_mi_thunk (file, thunk, delta, vcall_offset, function)
- FILE *file ATTRIBUTE_UNUSED;
- tree thunk ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset;
- tree function;
+x86_output_mi_thunk (FILE *file ATTRIBUTE_UNUSED,
+ tree thunk ATTRIBUTE_UNUSED, HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset, tree function)
{
rtx xops[3];
rtx this = x86_this_parameter (function);
@@ -14569,7 +15548,13 @@ x86_output_mi_thunk (file, thunk, delta, vcall_offset, function)
if (TARGET_64BIT)
tmp = gen_rtx_REG (DImode, FIRST_REX_INT_REG + 2 /* R10 */);
else
- tmp = gen_rtx_REG (SImode, 2 /* ECX */);
+ {
+ int tmp_regno = 2 /* ECX */;
+ if (lookup_attribute ("fastcall",
+ TYPE_ATTRIBUTES (TREE_TYPE (function))))
+ tmp_regno = 0 /* EAX */;
+ tmp = gen_rtx_REG (SImode, tmp_regno);
+ }
xops[0] = gen_rtx_MEM (Pmode, this_reg);
xops[1] = tmp;
@@ -14603,15 +15588,14 @@ x86_output_mi_thunk (file, thunk, delta, vcall_offset, function)
output_asm_insn ("mov{l}\t{%0, %1|%1, %0}", xops);
}
- xops[0] = DECL_RTL (function);
+ xops[0] = XEXP (DECL_RTL (function), 0);
if (TARGET_64BIT)
{
if (!flag_pic || (*targetm.binds_local_p) (function))
output_asm_insn ("jmp\t%P0", xops);
else
{
- tmp = XEXP (xops[0], 0);
- tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, tmp), UNSPEC_GOTPCREL);
+ tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, xops[0]), UNSPEC_GOTPCREL);
tmp = gen_rtx_CONST (Pmode, tmp);
tmp = gen_rtx_MEM (QImode, tmp);
xops[0] = tmp;
@@ -14623,6 +15607,17 @@ x86_output_mi_thunk (file, thunk, delta, vcall_offset, function)
if (!flag_pic || (*targetm.binds_local_p) (function))
output_asm_insn ("jmp\t%P0", xops);
else
+#if TARGET_MACHO
+ if (TARGET_MACHO)
+ {
+ const char *ip = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function));
+ tmp = gen_rtx_SYMBOL_REF (Pmode, machopic_stub_name (ip));
+ tmp = gen_rtx_MEM (QImode, tmp);
+ xops[0] = tmp;
+ output_asm_insn ("jmp\t%0", xops);
+ }
+ else
+#endif /* TARGET_MACHO */
{
tmp = gen_rtx_REG (SImode, 2 /* ECX */);
output_set_got (tmp);
@@ -14634,10 +15629,20 @@ x86_output_mi_thunk (file, thunk, delta, vcall_offset, function)
}
}
+static void
+x86_file_start (void)
+{
+ default_file_start ();
+ if (X86_FILE_START_VERSION_DIRECTIVE)
+ fputs ("\t.version\t\"01.01\"\n", asm_out_file);
+ if (X86_FILE_START_FLTUSED)
+ fputs ("\t.global\t__fltused\n", asm_out_file);
+ if (ix86_asm_dialect == ASM_INTEL)
+ fputs ("\t.intel_syntax\n", asm_out_file);
+}
+
int
-x86_field_alignment (field, computed)
- tree field;
- int computed;
+x86_field_alignment (tree field, int computed)
{
enum machine_mode mode;
tree type = TREE_TYPE (field);
@@ -14656,9 +15661,7 @@ x86_field_alignment (field, computed)
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
void
-x86_function_profiler (file, labelno)
- FILE *file;
- int labelno;
+x86_function_profiler (FILE *file, int labelno ATTRIBUTE_UNUSED)
{
if (TARGET_64BIT)
if (flag_pic)
@@ -14693,47 +15696,338 @@ x86_function_profiler (file, labelno)
}
}
-/* Implement machine specific optimizations.
+/* 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
+ 99% of cases. */
+
+static int
+min_insn_size (rtx insn)
+{
+ int l = 0;
+
+ if (!INSN_P (insn) || !active_insn_p (insn))
+ return 0;
+
+ /* Discard alignments we've emit and jump instructions. */
+ if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
+ && XINT (PATTERN (insn), 1) == UNSPECV_ALIGN)
+ return 0;
+ if (GET_CODE (insn) == JUMP_INSN
+ && (GET_CODE (PATTERN (insn)) == ADDR_VEC
+ || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC))
+ return 0;
+
+ /* Important case - calls are always 5 bytes.
+ It is common to have many calls in the row. */
+ if (GET_CODE (insn) == CALL_INSN
+ && symbolic_reference_mentioned_p (PATTERN (insn))
+ && !SIBLING_CALL_P (insn))
+ return 5;
+ if (get_attr_length (insn) <= 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. */
+ if (GET_CODE (insn) != JUMP_INSN)
+ {
+ l = get_attr_length_address (insn);
+ if (l < 4 && symbolic_reference_mentioned_p (PATTERN (insn)))
+ l = 4;
+ }
+ if (l)
+ return 1+l;
+ else
+ return 2;
+}
+
+/* AMD K8 core mispredicts jumps when there are more than 3 jumps in 16 byte
+ window. */
+
+static void
+k8_avoid_jump_misspredicts (void)
+{
+ rtx insn, start = get_insns ();
+ int nbytes = 0, njumps = 0;
+ int isjump = 0;
+
+ /* Look for all minimal intervals of instructions containing 4 jumps.
+ The intervals are bounded by START and INSN. NBYTES is the total
+ size of instructions in the interval including INSN and not including
+ START. When the NBYTES is smaller than 16 bytes, it is possible
+ that the end of START and INSN ends up in the same 16byte page.
+
+ 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).
+ */
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+
+ nbytes += min_insn_size (insn);
+ if (rtl_dump_file)
+ fprintf(rtl_dump_file, "Insn %i estimated to %i bytes\n",
+ INSN_UID (insn), min_insn_size (insn));
+ if ((GET_CODE (insn) == JUMP_INSN
+ && GET_CODE (PATTERN (insn)) != ADDR_VEC
+ && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
+ || GET_CODE (insn) == CALL_INSN)
+ njumps++;
+ else
+ continue;
+
+ while (njumps > 3)
+ {
+ start = NEXT_INSN (start);
+ if ((GET_CODE (start) == JUMP_INSN
+ && GET_CODE (PATTERN (start)) != ADDR_VEC
+ && GET_CODE (PATTERN (start)) != ADDR_DIFF_VEC)
+ || GET_CODE (start) == CALL_INSN)
+ njumps--, isjump = 1;
+ else
+ isjump = 0;
+ nbytes -= min_insn_size (start);
+ }
+ if (njumps < 0)
+ abort ();
+ if (rtl_dump_file)
+ fprintf(rtl_dump_file, "Interval %i to %i has %i bytes\n",
+ INSN_UID (start), INSN_UID (insn), nbytes);
+
+ if (njumps == 3 && isjump && nbytes < 16)
+ {
+ int padsize = 15 - nbytes + min_insn_size (insn);
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Padding insn %i by %i bytes!\n", INSN_UID (insn), padsize);
+ emit_insn_before (gen_align (GEN_INT (padsize)), insn);
+ }
+ }
+}
+
+/* Implement machine specific optimizations.
At the moment we implement single transformation: AMD Athlon works faster
- when RET is not destination of conditional jump or directly preceeded
+ when RET is not destination of conditional jump or directly preceded
by other jump instruction. We avoid the penalty by inserting NOP just
before the RET instructions in such cases. */
-void
-x86_machine_dependent_reorg (first)
- rtx first ATTRIBUTE_UNUSED;
+static void
+ix86_reorg (void)
{
edge e;
- if (!TARGET_ATHLON || !optimize || optimize_size)
+ if (!TARGET_ATHLON_K8 || !optimize || optimize_size)
return;
for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
{
basic_block bb = e->src;
- rtx ret = bb->end;
+ rtx ret = BB_END (bb);
rtx prev;
- bool insert = false;
+ bool replace = false;
- if (!returnjump_p (ret) || !maybe_hot_bb_p (bb))
+ if (GET_CODE (ret) != JUMP_INSN || GET_CODE (PATTERN (ret)) != RETURN
+ || !maybe_hot_bb_p (bb))
continue;
- prev = prev_nonnote_insn (ret);
+ for (prev = PREV_INSN (ret); prev; prev = PREV_INSN (prev))
+ if (active_insn_p (prev) || GET_CODE (prev) == CODE_LABEL)
+ break;
if (prev && GET_CODE (prev) == CODE_LABEL)
{
edge e;
for (e = bb->pred; e; e = e->pred_next)
- if (EDGE_FREQUENCY (e) && e->src->index > 0
+ if (EDGE_FREQUENCY (e) && e->src->index >= 0
&& !(e->flags & EDGE_FALLTHRU))
- insert = 1;
+ replace = true;
+ }
+ if (!replace)
+ {
+ prev = prev_active_insn (ret);
+ if (prev
+ && ((GET_CODE (prev) == JUMP_INSN && any_condjump_p (prev))
+ || GET_CODE (prev) == CALL_INSN))
+ replace = true;
+ /* Empty functions get branch mispredict even when the jump destination
+ is not visible to us. */
+ if (!prev && cfun->function_frequency > FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
+ replace = true;
}
- if (!insert)
+ if (replace)
{
- prev = prev_real_insn (ret);
- if (prev && GET_CODE (prev) == JUMP_INSN
- && any_condjump_p (prev))
- insert = 1;
+ emit_insn_before (gen_return_internal_long (), ret);
+ delete_insn (ret);
}
- if (insert)
- emit_insn_before (gen_nop (), ret);
}
+ k8_avoid_jump_misspredicts ();
+}
+
+/* Return nonzero when QImode register that must be represented via REX prefix
+ is used. */
+bool
+x86_extended_QIreg_mentioned_p (rtx insn)
+{
+ int i;
+ extract_insn_cached (insn);
+ for (i = 0; i < recog_data.n_operands; i++)
+ if (REG_P (recog_data.operand[i])
+ && REGNO (recog_data.operand[i]) >= 4)
+ return true;
+ return false;
+}
+
+/* Return nonzero when P points to register encoded via REX prefix.
+ Called via for_each_rtx. */
+static int
+extended_reg_mentioned_1 (rtx *p, void *data ATTRIBUTE_UNUSED)
+{
+ unsigned int regno;
+ if (!REG_P (*p))
+ return 0;
+ regno = REGNO (*p);
+ return REX_INT_REGNO_P (regno) || REX_SSE_REGNO_P (regno);
+}
+
+/* Return true when INSN mentions register that must be encoded using REX
+ prefix. */
+bool
+x86_extended_reg_mentioned_p (rtx insn)
+{
+ return for_each_rtx (&PATTERN (insn), extended_reg_mentioned_1, NULL);
+}
+
+/* Generate an unsigned DImode/SImode to FP conversion. This is the same code
+ optabs would emit if we didn't have TFmode patterns. */
+
+void
+x86_emit_floatuns (rtx operands[2])
+{
+ rtx neglab, donelab, i0, i1, f0, in, out;
+ enum machine_mode mode, inmode;
+
+ inmode = GET_MODE (operands[1]);
+ if (inmode != SImode
+ && inmode != DImode)
+ abort ();
+
+ out = operands[0];
+ in = force_reg (inmode, operands[1]);
+ mode = GET_MODE (out);
+ neglab = gen_label_rtx ();
+ donelab = gen_label_rtx ();
+ i1 = gen_reg_rtx (Pmode);
+ f0 = gen_reg_rtx (mode);
+
+ emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, Pmode, 0, neglab);
+
+ emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_FLOAT (mode, in)));
+ emit_jump_insn (gen_jump (donelab));
+ emit_barrier ();
+
+ emit_label (neglab);
+
+ i0 = expand_simple_binop (Pmode, LSHIFTRT, in, const1_rtx, NULL, 1, OPTAB_DIRECT);
+ i1 = expand_simple_binop (Pmode, AND, in, const1_rtx, NULL, 1, OPTAB_DIRECT);
+ i0 = expand_simple_binop (Pmode, IOR, i0, i1, i0, 1, OPTAB_DIRECT);
+ expand_float (f0, i0, 0);
+ emit_insn (gen_rtx_SET (VOIDmode, out, gen_rtx_PLUS (mode, f0, f0)));
+
+ emit_label (donelab);
+}
+
+/* Return if we do not know how to pass TYPE solely in registers. */
+bool
+ix86_must_pass_in_stack (enum machine_mode mode, tree type)
+{
+ if (default_must_pass_in_stack (mode, type))
+ return true;
+ return (!TARGET_64BIT && type && mode == TImode);
+}
+
+/* Initialize vector TARGET via VALS. */
+void
+ix86_expand_vector_init (rtx target, rtx vals)
+{
+ enum machine_mode mode = GET_MODE (target);
+ int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
+ int n_elts = (GET_MODE_SIZE (mode) / elt_size);
+ int i;
+
+ for (i = n_elts - 1; i >= 0; i--)
+ if (GET_CODE (XVECEXP (vals, 0, i)) != CONST_INT
+ && GET_CODE (XVECEXP (vals, 0, i)) != CONST_DOUBLE)
+ break;
+
+ /* Few special cases first...
+ ... constants are best loaded from constant pool. */
+ if (i < 0)
+ {
+ emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
+ return;
+ }
+
+ /* ... values where only first field is non-constant are best loaded
+ from the pool and overwriten via move later. */
+ if (!i)
+ {
+ rtx op = simplify_gen_subreg (mode, XVECEXP (vals, 0, 0),
+ GET_MODE_INNER (mode), 0);
+
+ op = force_reg (mode, op);
+ XVECEXP (vals, 0, 0) = CONST0_RTX (GET_MODE_INNER (mode));
+ emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
+ switch (GET_MODE (target))
+ {
+ case V2DFmode:
+ emit_insn (gen_sse2_movsd (target, target, op));
+ break;
+ case V4SFmode:
+ emit_insn (gen_sse_movss (target, target, op));
+ break;
+ default:
+ break;
+ }
+ return;
+ }
+
+ /* And the busy sequence doing rotations. */
+ switch (GET_MODE (target))
+ {
+ case V2DFmode:
+ {
+ rtx vecop0 =
+ simplify_gen_subreg (V2DFmode, XVECEXP (vals, 0, 0), DFmode, 0);
+ rtx vecop1 =
+ simplify_gen_subreg (V2DFmode, XVECEXP (vals, 0, 1), DFmode, 0);
+
+ vecop0 = force_reg (V2DFmode, vecop0);
+ vecop1 = force_reg (V2DFmode, vecop1);
+ emit_insn (gen_sse2_unpcklpd (target, vecop0, vecop1));
+ }
+ break;
+ case V4SFmode:
+ {
+ rtx vecop0 =
+ simplify_gen_subreg (V4SFmode, XVECEXP (vals, 0, 0), SFmode, 0);
+ rtx vecop1 =
+ simplify_gen_subreg (V4SFmode, XVECEXP (vals, 0, 1), SFmode, 0);
+ rtx vecop2 =
+ simplify_gen_subreg (V4SFmode, XVECEXP (vals, 0, 2), SFmode, 0);
+ rtx vecop3 =
+ simplify_gen_subreg (V4SFmode, XVECEXP (vals, 0, 3), SFmode, 0);
+ rtx tmp1 = gen_reg_rtx (V4SFmode);
+ rtx tmp2 = gen_reg_rtx (V4SFmode);
+
+ vecop0 = force_reg (V4SFmode, vecop0);
+ vecop1 = force_reg (V4SFmode, vecop1);
+ vecop2 = force_reg (V4SFmode, vecop2);
+ vecop3 = force_reg (V4SFmode, vecop3);
+ emit_insn (gen_sse_unpcklps (tmp1, vecop1, vecop3));
+ emit_insn (gen_sse_unpcklps (tmp2, vecop0, vecop2));
+ emit_insn (gen_sse_unpcklps (target, tmp2, tmp1));
+ }
+ break;
+ default:
+ abort ();
+ }
}
#include "gt-i386.h"
diff --git a/contrib/gcc/config/i386/i386.h b/contrib/gcc/config/i386/i386.h
index 32bc5d0252ee..f5be3409c705 100644
--- a/contrib/gcc/config/i386/i386.h
+++ b/contrib/gcc/config/i386/i386.h
@@ -1,21 +1,21 @@
-/* Definitions of target machine for GNU compiler for IA-32.
+/* Definitions of target machine for GCC for IA-32.
Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -41,9 +41,11 @@ struct processor_costs {
const int lea; /* cost of a lea instruction */
const int shift_var; /* variable shift costs */
const int shift_const; /* constant shift costs */
- const int mult_init; /* cost of starting a multiply */
+ const int mult_init[5]; /* cost of starting a multiply
+ in QImode, HImode, SImode, DImode, TImode*/
const int mult_bit; /* cost of multiply per each bit set */
- const int divide; /* cost of a divide/mod */
+ const int divide[5]; /* cost of a divide/mod
+ in QImode, HImode, SImode, DImode, TImode*/
int movsx; /* The cost of movsx operation. */
int movzx; /* The cost of movzx operation. */
const int large_insn; /* insns larger than this cost more */
@@ -75,6 +77,7 @@ struct processor_costs {
const int prefetch_block; /* bytes moved to cache for prefetch. */
const int simultaneous_prefetches; /* number of parallel prefetch
operations. */
+ const int branch_cost; /* Default value for BRANCH_COST. */
const int fadd; /* cost of FADD and FSUB instructions. */
const int fmul; /* cost of FMUL instruction. */
const int fdiv; /* cost of FDIV instruction. */
@@ -94,8 +97,12 @@ extern int target_flags;
/* configure can arrange to make this 2, to force a 486. */
#ifndef TARGET_CPU_DEFAULT
+#ifdef TARGET_64BIT_DEFAULT
+#define TARGET_CPU_DEFAULT TARGET_CPU_DEFAULT_k8
+#else
#define TARGET_CPU_DEFAULT 0
#endif
+#endif
/* Masks for the -m switches */
#define MASK_80387 0x00000001 /* Hardware floating point */
@@ -114,13 +121,15 @@ extern int target_flags;
#define MASK_MMX 0x00002000 /* Support MMX regs/builtins */
#define MASK_SSE 0x00004000 /* Support SSE regs/builtins */
#define MASK_SSE2 0x00008000 /* Support SSE2 regs/builtins */
-#define MASK_PNI 0x00010000 /* Support PNI builtins */
+#define MASK_SSE3 0x00010000 /* Support SSE3 regs/builtins */
#define MASK_3DNOW 0x00020000 /* Support 3Dnow builtins */
#define MASK_3DNOW_A 0x00040000 /* Support Athlon 3Dnow builtins */
#define MASK_128BIT_LONG_DOUBLE 0x00080000 /* long double size is 128bit */
#define MASK_64BIT 0x00100000 /* Produce 64bit code */
+#define MASK_MS_BITFIELD_LAYOUT 0x00200000 /* Use native (MS) bitfield layout */
+#define MASK_TLS_DIRECT_SEG_REFS 0x00400000 /* Avoid adding %gs:0 */
-/* Unused: 0x03f0000 */
+/* Unused: 0x03e0000 */
/* ... overlap with subtarget options starts by 0x04000000. */
#define MASK_NO_RED_ZONE 0x04000000 /* Do not use red zone */
@@ -198,15 +207,20 @@ extern int target_flags;
#endif
#endif
-#define TARGET_386 (ix86_cpu == PROCESSOR_I386)
-#define TARGET_486 (ix86_cpu == PROCESSOR_I486)
-#define TARGET_PENTIUM (ix86_cpu == PROCESSOR_PENTIUM)
-#define TARGET_PENTIUMPRO (ix86_cpu == PROCESSOR_PENTIUMPRO)
-#define TARGET_K6 (ix86_cpu == PROCESSOR_K6)
-#define TARGET_ATHLON (ix86_cpu == PROCESSOR_ATHLON)
-#define TARGET_PENTIUM4 (ix86_cpu == PROCESSOR_PENTIUM4)
+/* Avoid adding %gs:0 in TLS references; use %gs:address directly. */
+#define TARGET_TLS_DIRECT_SEG_REFS (target_flags & MASK_TLS_DIRECT_SEG_REFS)
-#define CPUMASK (1 << ix86_cpu)
+#define TARGET_386 (ix86_tune == PROCESSOR_I386)
+#define TARGET_486 (ix86_tune == PROCESSOR_I486)
+#define TARGET_PENTIUM (ix86_tune == PROCESSOR_PENTIUM)
+#define TARGET_PENTIUMPRO (ix86_tune == PROCESSOR_PENTIUMPRO)
+#define TARGET_K6 (ix86_tune == PROCESSOR_K6)
+#define TARGET_ATHLON (ix86_tune == PROCESSOR_ATHLON)
+#define TARGET_PENTIUM4 (ix86_tune == PROCESSOR_PENTIUM4)
+#define TARGET_K8 (ix86_tune == PROCESSOR_K8)
+#define TARGET_ATHLON_K8 (TARGET_K8 || TARGET_ATHLON)
+
+#define TUNEMASK (1 << ix86_tune)
extern const int x86_use_leave, x86_push_memory, x86_zero_extend_with_and;
extern const int x86_use_bit_test, x86_cmove, x86_deep_branch;
extern const int x86_branch_hints, x86_unroll_strlen;
@@ -222,48 +236,63 @@ extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
extern const int x86_accumulate_outgoing_args, x86_prologue_using_move;
extern const int x86_epilogue_using_move, x86_decompose_lea;
extern const int x86_arch_always_fancy_math_387, x86_shift1;
+extern const int x86_sse_partial_reg_dependency, x86_sse_partial_regs;
+extern const int x86_sse_typeless_stores, x86_sse_load0_by_pxor;
+extern const int x86_use_ffreep, x86_sse_partial_regs_for_cvtsd2ss;
+extern const int x86_inter_unit_moves;
extern int x86_prefetch_sse;
-#define TARGET_USE_LEAVE (x86_use_leave & CPUMASK)
-#define TARGET_PUSH_MEMORY (x86_push_memory & CPUMASK)
-#define TARGET_ZERO_EXTEND_WITH_AND (x86_zero_extend_with_and & CPUMASK)
-#define TARGET_USE_BIT_TEST (x86_use_bit_test & CPUMASK)
-#define TARGET_UNROLL_STRLEN (x86_unroll_strlen & CPUMASK)
+#define TARGET_USE_LEAVE (x86_use_leave & TUNEMASK)
+#define TARGET_PUSH_MEMORY (x86_push_memory & TUNEMASK)
+#define TARGET_ZERO_EXTEND_WITH_AND (x86_zero_extend_with_and & TUNEMASK)
+#define TARGET_USE_BIT_TEST (x86_use_bit_test & TUNEMASK)
+#define TARGET_UNROLL_STRLEN (x86_unroll_strlen & TUNEMASK)
/* For sane SSE instruction set generation we need fcomi instruction. It is
safe to enable all CMOVE instructions. */
#define TARGET_CMOVE ((x86_cmove & (1 << ix86_arch)) || TARGET_SSE)
-#define TARGET_DEEP_BRANCH_PREDICTION (x86_deep_branch & CPUMASK)
-#define TARGET_BRANCH_PREDICTION_HINTS (x86_branch_hints & CPUMASK)
-#define TARGET_DOUBLE_WITH_ADD (x86_double_with_add & CPUMASK)
-#define TARGET_USE_SAHF ((x86_use_sahf & CPUMASK) && !TARGET_64BIT)
-#define TARGET_MOVX (x86_movx & CPUMASK)
-#define TARGET_PARTIAL_REG_STALL (x86_partial_reg_stall & CPUMASK)
-#define TARGET_USE_LOOP (x86_use_loop & CPUMASK)
-#define TARGET_USE_FIOP (x86_use_fiop & CPUMASK)
-#define TARGET_USE_MOV0 (x86_use_mov0 & CPUMASK)
-#define TARGET_USE_CLTD (x86_use_cltd & CPUMASK)
-#define TARGET_SPLIT_LONG_MOVES (x86_split_long_moves & CPUMASK)
-#define TARGET_READ_MODIFY_WRITE (x86_read_modify_write & CPUMASK)
-#define TARGET_READ_MODIFY (x86_read_modify & CPUMASK)
-#define TARGET_PROMOTE_QImode (x86_promote_QImode & CPUMASK)
-#define TARGET_FAST_PREFIX (x86_fast_prefix & CPUMASK)
-#define TARGET_SINGLE_STRINGOP (x86_single_stringop & CPUMASK)
-#define TARGET_QIMODE_MATH (x86_qimode_math & CPUMASK)
-#define TARGET_HIMODE_MATH (x86_himode_math & CPUMASK)
-#define TARGET_PROMOTE_QI_REGS (x86_promote_qi_regs & CPUMASK)
-#define TARGET_PROMOTE_HI_REGS (x86_promote_hi_regs & CPUMASK)
-#define TARGET_ADD_ESP_4 (x86_add_esp_4 & CPUMASK)
-#define TARGET_ADD_ESP_8 (x86_add_esp_8 & CPUMASK)
-#define TARGET_SUB_ESP_4 (x86_sub_esp_4 & CPUMASK)
-#define TARGET_SUB_ESP_8 (x86_sub_esp_8 & CPUMASK)
-#define TARGET_INTEGER_DFMODE_MOVES (x86_integer_DFmode_moves & CPUMASK)
-#define TARGET_PARTIAL_REG_DEPENDENCY (x86_partial_reg_dependency & CPUMASK)
-#define TARGET_MEMORY_MISMATCH_STALL (x86_memory_mismatch_stall & CPUMASK)
-#define TARGET_PROLOGUE_USING_MOVE (x86_prologue_using_move & CPUMASK)
-#define TARGET_EPILOGUE_USING_MOVE (x86_epilogue_using_move & CPUMASK)
-#define TARGET_DECOMPOSE_LEA (x86_decompose_lea & CPUMASK)
+#define TARGET_DEEP_BRANCH_PREDICTION (x86_deep_branch & TUNEMASK)
+#define TARGET_BRANCH_PREDICTION_HINTS (x86_branch_hints & TUNEMASK)
+#define TARGET_DOUBLE_WITH_ADD (x86_double_with_add & TUNEMASK)
+#define TARGET_USE_SAHF ((x86_use_sahf & TUNEMASK) && !TARGET_64BIT)
+#define TARGET_MOVX (x86_movx & TUNEMASK)
+#define TARGET_PARTIAL_REG_STALL (x86_partial_reg_stall & TUNEMASK)
+#define TARGET_USE_LOOP (x86_use_loop & TUNEMASK)
+#define TARGET_USE_FIOP (x86_use_fiop & TUNEMASK)
+#define TARGET_USE_MOV0 (x86_use_mov0 & TUNEMASK)
+#define TARGET_USE_CLTD (x86_use_cltd & TUNEMASK)
+#define TARGET_SPLIT_LONG_MOVES (x86_split_long_moves & TUNEMASK)
+#define TARGET_READ_MODIFY_WRITE (x86_read_modify_write & TUNEMASK)
+#define TARGET_READ_MODIFY (x86_read_modify & TUNEMASK)
+#define TARGET_PROMOTE_QImode (x86_promote_QImode & TUNEMASK)
+#define TARGET_FAST_PREFIX (x86_fast_prefix & TUNEMASK)
+#define TARGET_SINGLE_STRINGOP (x86_single_stringop & TUNEMASK)
+#define TARGET_QIMODE_MATH (x86_qimode_math & TUNEMASK)
+#define TARGET_HIMODE_MATH (x86_himode_math & TUNEMASK)
+#define TARGET_PROMOTE_QI_REGS (x86_promote_qi_regs & TUNEMASK)
+#define TARGET_PROMOTE_HI_REGS (x86_promote_hi_regs & TUNEMASK)
+#define TARGET_ADD_ESP_4 (x86_add_esp_4 & TUNEMASK)
+#define TARGET_ADD_ESP_8 (x86_add_esp_8 & TUNEMASK)
+#define TARGET_SUB_ESP_4 (x86_sub_esp_4 & TUNEMASK)
+#define TARGET_SUB_ESP_8 (x86_sub_esp_8 & TUNEMASK)
+#define TARGET_INTEGER_DFMODE_MOVES (x86_integer_DFmode_moves & TUNEMASK)
+#define TARGET_PARTIAL_REG_DEPENDENCY (x86_partial_reg_dependency & TUNEMASK)
+#define TARGET_SSE_PARTIAL_REG_DEPENDENCY \
+ (x86_sse_partial_reg_dependency & TUNEMASK)
+#define TARGET_SSE_PARTIAL_REGS (x86_sse_partial_regs & TUNEMASK)
+#define TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS \
+ (x86_sse_partial_regs_for_cvtsd2ss & TUNEMASK)
+#define TARGET_SSE_TYPELESS_STORES (x86_sse_typeless_stores & TUNEMASK)
+#define TARGET_SSE_TYPELESS_LOAD0 (x86_sse_typeless_load0 & TUNEMASK)
+#define TARGET_SSE_LOAD0_BY_PXOR (x86_sse_load0_by_pxor & TUNEMASK)
+#define TARGET_MEMORY_MISMATCH_STALL (x86_memory_mismatch_stall & TUNEMASK)
+#define TARGET_PROLOGUE_USING_MOVE (x86_prologue_using_move & TUNEMASK)
+#define TARGET_EPILOGUE_USING_MOVE (x86_epilogue_using_move & TUNEMASK)
+#define TARGET_DECOMPOSE_LEA (x86_decompose_lea & TUNEMASK)
#define TARGET_PREFETCH_SSE (x86_prefetch_sse)
-#define TARGET_SHIFT1 (x86_shift1 & CPUMASK)
+#define TARGET_SHIFT1 (x86_shift1 & TUNEMASK)
+#define TARGET_USE_FFREEP (x86_use_ffreep & TUNEMASK)
+#define TARGET_REP_MOVL_OPTIMAL (x86_rep_movl_optimal & TUNEMASK)
+#define TARGET_INTER_UNIT_MOVES (x86_inter_unit_moves & TUNEMASK)
#define TARGET_STACK_PROBE (target_flags & MASK_STACK_PROBE)
@@ -274,7 +303,7 @@ extern int x86_prefetch_sse;
#define TARGET_SSE ((target_flags & MASK_SSE) != 0)
#define TARGET_SSE2 ((target_flags & MASK_SSE2) != 0)
-#define TARGET_PNI ((target_flags & MASK_PNI) != 0)
+#define TARGET_SSE3 ((target_flags & MASK_SSE3) != 0)
#define TARGET_SSE_MATH ((ix86_fpmath & FPMATH_SSE) != 0)
#define TARGET_MIX_SSE_I387 ((ix86_fpmath & FPMATH_SSE) \
&& (ix86_fpmath & FPMATH_387))
@@ -284,12 +313,14 @@ extern int x86_prefetch_sse;
#define TARGET_RED_ZONE (!(target_flags & MASK_NO_RED_ZONE))
+#define TARGET_USE_MS_BITFIELD_LAYOUT (target_flags & MASK_MS_BITFIELD_LAYOUT)
+
#define TARGET_GNU_TLS (ix86_tls_dialect == TLS_DIALECT_GNU)
#define TARGET_SUN_TLS (ix86_tls_dialect == TLS_DIALECT_SUN)
/* WARNING: Do not mark empty strings for translation, as calling
gettext on an empty string does NOT return an empty
- string. */
+ string. */
#define TARGET_SWITCHES \
@@ -302,6 +333,8 @@ extern int x86_prefetch_sse;
{ "486", 0, "" /*Deprecated.*/}, \
{ "pentium", 0, "" /*Deprecated.*/}, \
{ "pentiumpro", 0, "" /*Deprecated.*/}, \
+ { "pni", 0, "" /*Deprecated.*/}, \
+ { "no-pni", 0, "" /*Deprecated.*/}, \
{ "intel-syntax", 0, "" /*Deprecated.*/}, \
{ "no-intel-syntax", 0, "" /*Deprecated.*/}, \
{ "rtd", MASK_RTD, \
@@ -368,10 +401,10 @@ extern int x86_prefetch_sse;
N_("Support MMX, SSE and SSE2 built-in functions and code generation") }, \
{ "no-sse2", -MASK_SSE2, \
N_("Do not support MMX, SSE and SSE2 built-in functions and code generation") }, \
- { "pni", MASK_PNI, \
- N_("Support MMX, SSE, SSE2 and PNI built-in functions and code generation") }, \
- { "no-pni", -MASK_PNI, \
- N_("Do not support MMX, SSE, SSE2 and PNI built-in functions and code generation") }, \
+ { "sse3", MASK_SSE3, \
+ N_("Support MMX, SSE, SSE2 and SSE3 built-in functions and code generation") },\
+ { "no-sse3", -MASK_SSE3, \
+ N_("Do not support MMX, SSE, SSE2 and SSE3 built-in functions and code generation") },\
{ "128bit-long-double", MASK_128BIT_LONG_DOUBLE, \
N_("sizeof(long double) is 16") }, \
{ "96bit-long-double", -MASK_128BIT_LONG_DOUBLE, \
@@ -380,16 +413,29 @@ extern int x86_prefetch_sse;
N_("Generate 64bit x86-64 code") }, \
{ "32", -MASK_64BIT, \
N_("Generate 32bit i386 code") }, \
+ { "ms-bitfields", MASK_MS_BITFIELD_LAYOUT, \
+ N_("Use native (MS) bitfield layout") }, \
+ { "no-ms-bitfields", -MASK_MS_BITFIELD_LAYOUT, \
+ N_("Use gcc default bitfield layout") }, \
{ "red-zone", -MASK_NO_RED_ZONE, \
N_("Use red-zone in the x86-64 code") }, \
{ "no-red-zone", MASK_NO_RED_ZONE, \
N_("Do not use red-zone in the x86-64 code") }, \
+ { "tls-direct-seg-refs", MASK_TLS_DIRECT_SEG_REFS, \
+ N_("Use direct references against %gs when accessing tls data") }, \
+ { "no-tls-direct-seg-refs", -MASK_TLS_DIRECT_SEG_REFS, \
+ N_("Do not use direct references against %gs when accessing tls data") }, \
SUBTARGET_SWITCHES \
- { "", TARGET_DEFAULT | TARGET_64BIT_DEFAULT | TARGET_SUBTARGET_DEFAULT, 0 }}
+ { "", \
+ TARGET_DEFAULT | TARGET_64BIT_DEFAULT | TARGET_SUBTARGET_DEFAULT \
+ | TARGET_TLS_DIRECT_SEG_REFS_DEFAULT, 0 }}
#ifndef TARGET_64BIT_DEFAULT
#define TARGET_64BIT_DEFAULT 0
#endif
+#ifndef TARGET_TLS_DIRECT_SEG_REFS_DEFAULT
+#define TARGET_TLS_DIRECT_SEG_REFS_DEFAULT 0
+#endif
/* Once GDB has been enhanced to deal with functions without frame
pointers, we can change this to allow for elimination of
@@ -411,35 +457,35 @@ extern int x86_prefetch_sse;
option if the fixed part matches. The actual option name is made
by appending `-m' to the specified name. */
#define TARGET_OPTIONS \
-{ { "cpu=", &ix86_cpu_string, \
- N_("Schedule code for given CPU")}, \
+{ { "tune=", &ix86_tune_string, \
+ N_("Schedule code for given CPU"), 0}, \
{ "fpmath=", &ix86_fpmath_string, \
- N_("Generate floating point mathematics using given instruction set")},\
+ N_("Generate floating point mathematics using given instruction set"), 0},\
{ "arch=", &ix86_arch_string, \
- N_("Generate code for given CPU")}, \
+ N_("Generate code for given CPU"), 0}, \
{ "regparm=", &ix86_regparm_string, \
- N_("Number of registers used to pass integer arguments") }, \
+ N_("Number of registers used to pass integer arguments"), 0},\
{ "align-loops=", &ix86_align_loops_string, \
- N_("Loop code aligned to this power of 2") }, \
+ N_("Loop code aligned to this power of 2"), 0}, \
{ "align-jumps=", &ix86_align_jumps_string, \
- N_("Jump targets are aligned to this power of 2") }, \
+ N_("Jump targets are aligned to this power of 2"), 0}, \
{ "align-functions=", &ix86_align_funcs_string, \
- N_("Function starts are aligned to this power of 2") }, \
+ N_("Function starts are aligned to this power of 2"), 0}, \
{ "preferred-stack-boundary=", \
&ix86_preferred_stack_boundary_string, \
- N_("Attempt to keep stack aligned to this power of 2") }, \
+ N_("Attempt to keep stack aligned to this power of 2"), 0}, \
{ "branch-cost=", &ix86_branch_cost_string, \
- N_("Branches are this expensive (1-5, arbitrary units)") }, \
+ N_("Branches are this expensive (1-5, arbitrary units)"), 0},\
{ "cmodel=", &ix86_cmodel_string, \
- N_("Use given x86-64 code model") }, \
+ N_("Use given x86-64 code model"), 0}, \
{ "debug-arg", &ix86_debug_arg_string, \
- "" /* Undocumented. */ }, \
+ "" /* Undocumented. */, 0}, \
{ "debug-addr", &ix86_debug_addr_string, \
- "" /* Undocumented. */ }, \
+ "" /* Undocumented. */, 0}, \
{ "asm=", &ix86_asm_string, \
- N_("Use given assembler dialect") }, \
+ N_("Use given assembler dialect"), 0}, \
{ "tls-dialect=", &ix86_tls_dialect_string, \
- N_("Use given thread-local storage dialect") }, \
+ N_("Use given thread-local storage dialect"), 0}, \
SUBTARGET_OPTIONS \
}
@@ -462,19 +508,32 @@ extern int x86_prefetch_sse;
#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
optimization_options ((LEVEL), (SIZE))
+/* Support for configure-time defaults of some command line options. */
+#define OPTION_DEFAULT_SPECS \
+ {"arch", "%{!march=*:-march=%(VALUE)}"}, \
+ {"tune", "%{!mtune=*:%{!mcpu=*:%{!march=*:-mtune=%(VALUE)}}}" }, \
+ {"cpu", "%{!mtune=*:%{!mcpu=*:%{!march=*:-mtune=%(VALUE)}}}" }
+
/* Specs for the compiler proper */
#ifndef CC1_CPU_SPEC
#define CC1_CPU_SPEC "\
-%{!mcpu*: \
-%{m386:-mcpu=i386 \
-%n`-m386' is deprecated. Use `-march=i386' or `-mcpu=i386' instead.\n} \
-%{m486:-mcpu=i486 \
-%n`-m486' is deprecated. Use `-march=i486' or `-mcpu=i486' instead.\n} \
-%{mpentium:-mcpu=pentium \
-%n`-mpentium' is deprecated. Use `-march=pentium' or `-mcpu=pentium' instead.\n} \
-%{mpentiumpro:-mcpu=pentiumpro \
-%n`-mpentiumpro' is deprecated. Use `-march=pentiumpro' or `-mcpu=pentiumpro' instead.\n}} \
+%{!mtune*: \
+%{m386:mtune=i386 \
+%n`-m386' is deprecated. Use `-march=i386' or `-mtune=i386' instead.\n} \
+%{m486:-mtune=i486 \
+%n`-m486' is deprecated. Use `-march=i486' or `-mtune=i486' instead.\n} \
+%{mpentium:-mtune=pentium \
+%n`-mpentium' is deprecated. Use `-march=pentium' or `-mtune=pentium' instead.\n} \
+%{mpentiumpro:-mtune=pentiumpro \
+%n`-mpentiumpro' is deprecated. Use `-march=pentiumpro' or `-mtune=pentiumpro' instead.\n} \
+%{mcpu=*:-mtune=%* \
+%n`-mcpu=' is deprecated. Use `-mtune=' or '-march=' instead.\n}} \
+%<mcpu=* \
+%{mpni:-msse3 \
+%n`-mpni' is deprecated. Use `-msse3' instead.\n} \
+%{mno-pni:-mno-sse3 \
+%n`-mno-pni' is deprecated. Use `-mno-sse3' instead.\n} \
%{mintel-syntax:-masm=intel \
%n`-mintel-syntax' is deprecated. Use `-masm=intel' instead.\n} \
%{mno-intel-syntax:-masm=att \
@@ -486,17 +545,18 @@ extern int x86_prefetch_sse;
do \
{ \
size_t arch_len = strlen (ix86_arch_string); \
- size_t cpu_len = strlen (ix86_cpu_string); \
+ size_t tune_len = strlen (ix86_tune_string); \
int last_arch_char = ix86_arch_string[arch_len - 1]; \
- int last_cpu_char = ix86_cpu_string[cpu_len - 1]; \
+ int last_tune_char = ix86_tune_string[tune_len - 1]; \
\
if (TARGET_64BIT) \
{ \
builtin_assert ("cpu=x86_64"); \
- builtin_define ("__x86_64"); \
- builtin_define ("__x86_64__"); \
+ builtin_assert ("machine=x86_64"); \
builtin_define ("__amd64"); \
builtin_define ("__amd64__"); \
+ builtin_define ("__x86_64"); \
+ builtin_define ("__x86_64__"); \
} \
else \
{ \
@@ -505,8 +565,8 @@ extern int x86_prefetch_sse;
builtin_define_std ("i386"); \
} \
\
- /* Built-ins based on -mcpu= (or -march= if no \
- CPU given). */ \
+ /* Built-ins based on -mtune= (or -march= if no \
+ -mtune= given). */ \
if (TARGET_386) \
builtin_define ("__tune_i386__"); \
else if (TARGET_486) \
@@ -515,14 +575,14 @@ extern int x86_prefetch_sse;
{ \
builtin_define ("__tune_i586__"); \
builtin_define ("__tune_pentium__"); \
- if (last_cpu_char == 'x') \
+ if (last_tune_char == 'x') \
builtin_define ("__tune_pentium_mmx__"); \
} \
else if (TARGET_PENTIUMPRO) \
{ \
builtin_define ("__tune_i686__"); \
builtin_define ("__tune_pentiumpro__"); \
- switch (last_cpu_char) \
+ switch (last_tune_char) \
{ \
case '3': \
builtin_define ("__tune_pentium3__"); \
@@ -535,18 +595,20 @@ extern int x86_prefetch_sse;
else if (TARGET_K6) \
{ \
builtin_define ("__tune_k6__"); \
- if (last_cpu_char == '2') \
+ if (last_tune_char == '2') \
builtin_define ("__tune_k6_2__"); \
- else if (last_cpu_char == '3') \
+ else if (last_tune_char == '3') \
builtin_define ("__tune_k6_3__"); \
} \
else if (TARGET_ATHLON) \
{ \
builtin_define ("__tune_athlon__"); \
/* Only plain "athlon" lacks SSE. */ \
- if (last_cpu_char != 'n') \
+ if (last_tune_char != 'n') \
builtin_define ("__tune_athlon_sse__"); \
} \
+ else if (TARGET_K8) \
+ builtin_define ("__tune_k8__"); \
else if (TARGET_PENTIUM4) \
builtin_define ("__tune_pentium4__"); \
\
@@ -560,8 +622,11 @@ extern int x86_prefetch_sse;
builtin_define ("__SSE__"); \
if (TARGET_SSE2) \
builtin_define ("__SSE2__"); \
- if (TARGET_PNI) \
- builtin_define ("__PNI__"); \
+ if (TARGET_SSE3) \
+ { \
+ builtin_define ("__SSE3__"); \
+ builtin_define ("__PNI__"); \
+ } \
if (TARGET_SSE_MATH && TARGET_SSE) \
builtin_define ("__SSE_MATH__"); \
if (TARGET_SSE_MATH && TARGET_SSE2) \
@@ -607,6 +672,11 @@ extern int x86_prefetch_sse;
if (last_arch_char != 'n') \
builtin_define ("__athlon_sse__"); \
} \
+ else if (ix86_arch == PROCESSOR_K8) \
+ { \
+ builtin_define ("__k8"); \
+ builtin_define ("__k8__"); \
+ } \
else if (ix86_arch == PROCESSOR_PENTIUM4) \
{ \
builtin_define ("__pentium4"); \
@@ -628,11 +698,16 @@ extern int x86_prefetch_sse;
#define TARGET_CPU_DEFAULT_k6_3 10
#define TARGET_CPU_DEFAULT_athlon 11
#define TARGET_CPU_DEFAULT_athlon_sse 12
+#define TARGET_CPU_DEFAULT_k8 13
+#define TARGET_CPU_DEFAULT_pentium_m 14
+#define TARGET_CPU_DEFAULT_prescott 15
+#define TARGET_CPU_DEFAULT_nocona 16
#define TARGET_CPU_DEFAULT_NAMES {"i386", "i486", "pentium", "pentium-mmx",\
"pentiumpro", "pentium2", "pentium3", \
"pentium4", "k6", "k6-2", "k6-3",\
- "athlon", "athlon-4"}
+ "athlon", "athlon-4", "k8", \
+ "pentium-m", "prescott", "nocona"}
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
@@ -643,7 +718,7 @@ extern int x86_prefetch_sse;
definition is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
+ specification name, and a string constant that used by the GCC driver
program.
Do not define this macro if it does not need to do anything. */
@@ -658,16 +733,7 @@ extern int x86_prefetch_sse;
/* target machine storage layout */
-/* Define for XFmode or TFmode extended real floating point support.
- The XFmode is specified by i386 ABI, while TFmode may be faster
- due to alignment and simplifications in the address calculations. */
-#define LONG_DOUBLE_TYPE_SIZE (TARGET_128BIT_LONG_DOUBLE ? 128 : 96)
-#define MAX_LONG_DOUBLE_TYPE_SIZE 128
-#ifdef __x86_64__
-#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 128
-#else
-#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 96
-#endif
+#define LONG_DOUBLE_TYPE_SIZE 96
/* Set the value of FLT_EVAL_METHOD in float.h. When using only the
FPU, assume that the fpcw is set to extended precision; when using
@@ -675,7 +741,7 @@ extern int x86_prefetch_sse;
the rounding precision is indeterminate, since either may be chosen
apparently at random. */
#define TARGET_FLT_EVAL_METHOD \
- (TARGET_MIX_SSE_I387 ? -1 : TARGET_SSE_MATH ? 1 : 2)
+ (TARGET_MIX_SSE_I387 ? -1 : TARGET_SSE_MATH ? 0 : 2)
#define SHORT_TYPE_SIZE 16
#define INT_TYPE_SIZE 32
@@ -721,12 +787,12 @@ extern int x86_prefetch_sse;
/* Boundary (in *bits*) on which stack pointer should be aligned. */
#define STACK_BOUNDARY BITS_PER_WORD
-/* Boundary (in *bits*) on which the stack pointer preferrs to be
+/* Boundary (in *bits*) on which the stack pointer prefers to be
aligned; the compiler cannot rely on having this alignment. */
#define PREFERRED_STACK_BOUNDARY ix86_preferred_stack_boundary
/* As of July 2001, many runtimes to not align the stack properly when
- entering main. This causes expand_main_function to forcably align
+ entering main. This causes expand_main_function to forcibly align
the stack, which results in aligned frames for functions called from
main, though it does nothing for the alignment of main itself. */
#define FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN \
@@ -747,7 +813,7 @@ extern int x86_prefetch_sse;
might need to be aligned. No data type wants to be aligned
rounder than this.
- Pentium+ preferrs DFmode values to be aligned to 64 bit boundary
+ Pentium+ prefers DFmode values to be aligned to 64 bit boundary
and Pentium Pro XFmode values at 128 bit boundaries. */
#define BIGGEST_ALIGNMENT 128
@@ -757,7 +823,7 @@ extern int x86_prefetch_sse;
((MODE) == XFmode || (MODE) == TFmode || SSE_REG_MODE_P (MODE))
/* The published ABIs say that doubles should be aligned on word
- boundaries, so lower the aligment for structure fields unless
+ boundaries, so lower the alignment for structure fields unless
-malign-double is set. */
/* ??? Blah -- this macro is used directly by libobjc. Since it
@@ -837,8 +903,7 @@ extern int x86_prefetch_sse;
#define STACK_REGS
#define IS_STACK_MODE(MODE) \
- ((MODE) == DFmode || (MODE) == SFmode || (MODE) == XFmode \
- || (MODE) == TFmode)
+ ((MODE) == DFmode || (MODE) == SFmode || (MODE) == XFmode) \
/* Number of actual hardware registers.
The hardware registers are assigned numbers for the compiler
@@ -867,7 +932,7 @@ extern int x86_prefetch_sse;
and are not available for the register allocator.
On the 80386, the stack pointer is such, as is the arg pointer.
- The value is an mask - bit 1 is set for fixed registers
+ The value is a mask - bit 1 is set for fixed registers
for 32bit target, while 2 is set for fixed registers for 64bit.
Proper value is computed in the CONDITIONAL_REGISTER_USAGE.
*/
@@ -893,7 +958,7 @@ extern int x86_prefetch_sse;
and the register where structure-value addresses are passed.
Aside from that, you can include as many other registers as you like.
- The value is an mask - bit 1 is set for call used
+ The value is a mask - bit 1 is set for call used
for 32bit target, while 2 is set for call used for 64bit.
Proper value is computed in the CONDITIONAL_REGISTER_USAGE.
*/
@@ -928,7 +993,7 @@ extern int x86_prefetch_sse;
/* ORDER_REGS_FOR_LOCAL_ALLOC is a macro which permits reg_alloc_order
to be rearranged based on a particular function. When using sse math,
- we want to allocase SSE before x87 registers and vice vera. */
+ we want to allocate SSE before x87 registers and vice vera. */
#define ORDER_REGS_FOR_LOCAL_ALLOC x86_order_regs_for_local_alloc ()
@@ -986,9 +1051,9 @@ do { \
#define HARD_REGNO_NREGS(REGNO, MODE) \
(FP_REGNO_P (REGNO) || SSE_REGNO_P (REGNO) || MMX_REGNO_P (REGNO) \
? (COMPLEX_MODE_P (MODE) ? 2 : 1) \
- : ((MODE) == TFmode \
+ : ((MODE) == XFmode \
? (TARGET_64BIT ? 2 : 3) \
- : (MODE) == TCmode \
+ : (MODE) == XCmode \
? (TARGET_64BIT ? 4 : 6) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
@@ -998,7 +1063,7 @@ do { \
#define VALID_SSE_REG_MODE(MODE) \
((MODE) == TImode || (MODE) == V4SFmode || (MODE) == V4SImode \
- || (MODE) == SFmode \
+ || (MODE) == SFmode || (MODE) == TFmode \
/* Always accept SSE2 modes so that xmmintrin.h compiles. */ \
|| VALID_SSE2_REG_MODE (MODE) \
|| (TARGET_SSE2 && ((MODE) == DFmode || VALID_MMX_REG_MODE (MODE))))
@@ -1016,21 +1081,20 @@ do { \
: VALID_MMX_REG_MODE_3DNOW (MODE) && TARGET_3DNOW ? 1 : 0)
#define VALID_FP_MODE_P(MODE) \
- ((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode \
- || (!TARGET_64BIT && (MODE) == XFmode) \
- || (MODE) == SCmode || (MODE) == DCmode || (MODE) == TCmode \
- || (!TARGET_64BIT && (MODE) == XCmode))
+ ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode \
+ || (MODE) == SCmode || (MODE) == DCmode || (MODE) == XCmode) \
#define VALID_INT_MODE_P(MODE) \
((MODE) == QImode || (MODE) == HImode || (MODE) == SImode \
|| (MODE) == DImode \
|| (MODE) == CQImode || (MODE) == CHImode || (MODE) == CSImode \
|| (MODE) == CDImode \
- || (TARGET_64BIT && ((MODE) == TImode || (MODE) == CTImode)))
+ || (TARGET_64BIT && ((MODE) == TImode || (MODE) == CTImode \
+ || (MODE) == TFmode || (MODE) == TCmode)))
/* Return true for modes passed in SSE registers. */
#define SSE_REG_MODE_P(MODE) \
- ((MODE) == TImode || (MODE) == V16QImode \
+ ((MODE) == TImode || (MODE) == V16QImode || (MODE) == TFmode \
|| (MODE) == V8HImode || (MODE) == V2DFmode || (MODE) == V2DImode \
|| (MODE) == V4SFmode || (MODE) == V4SImode)
@@ -1060,6 +1124,9 @@ do { \
&& (TARGET_64BIT || !TARGET_PARTIAL_REG_STALL)) \
|| ((MODE2) == DImode && TARGET_64BIT))))
+/* It is possible to write patterns to move flags; but until someone
+ does it, */
+#define AVOID_CCMODE_COPIES
/* Specify the modes required to caller save a given hard regno.
We do this on i386 to prevent flags from being saved at all.
@@ -1069,7 +1136,7 @@ do { \
#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
(CC_REGNO_P (REGNO) ? VOIDmode \
: (MODE) == VOIDmode && (NREGS) != 1 ? VOIDmode \
- : (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS)) \
+ : (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS), false)\
: (MODE) == HImode && !TARGET_PARTIAL_REG_STALL ? SImode \
: (MODE) == QImode && (REGNO) >= 4 && !TARGET_64BIT ? SImode \
: (MODE))
@@ -1182,6 +1249,9 @@ do { \
#define RETURN_IN_MEMORY(TYPE) \
ix86_return_in_memory (TYPE)
+/* This is overridden by <cygwin.h>. */
+#define MS_AGGREGATE_RETURN 0
+
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.
@@ -1254,7 +1324,7 @@ enum reg_class
#define Q_CLASS_P(CLASS) \
reg_class_subset_p ((CLASS), Q_REGS)
-/* Give names of register classes as strings for dump file. */
+/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
{ "NO_REGS", \
@@ -1344,6 +1414,9 @@ enum reg_class
(((N) >= FIRST_SSE_REG && (N) <= LAST_SSE_REG) \
|| ((N) >= FIRST_REX_SSE_REG && (N) <= LAST_REX_SSE_REG))
+#define REX_SSE_REGNO_P(N) \
+ ((N) >= FIRST_REX_SSE_REG && (N) <= LAST_REX_SSE_REG)
+
#define SSE_REGNO(N) \
((N) < 8 ? FIRST_SSE_REG + (N) : FIRST_REX_SSE_REG + (N) - 8)
#define SSE_REG_P(N) (REG_P (N) && SSE_REGNO_P (REGNO (N)))
@@ -1366,11 +1439,6 @@ enum reg_class
#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
#define CC_REGNO_P(X) ((X) == FLAGS_REG || (X) == FPSR_REG)
-/* Indicate whether hard register numbered REG_NO should be converted
- to SSA form. */
-#define CONVERT_HARD_REGISTER_TO_SSA_P(REG_NO) \
- ((REG_NO) == FLAGS_REG || (REG_NO) == ARG_POINTER_REGNUM)
-
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS INDEX_REGS
@@ -1414,7 +1482,7 @@ enum reg_class
K is for signed imm8 operands.
L is for andsi as zero-extending move.
M is for shifts that can be executed by the "lea" opcode.
- N is for immedaite operands for out/in instructions (0-255)
+ N is for immediate operands for out/in instructions (0-255)
*/
#define CONST_OK_FOR_LETTER_P(VALUE, C) \
@@ -1496,15 +1564,12 @@ enum reg_class
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS. */
/* On the 80386, this is the size of MODE in words,
- except in the FP regs, where a single reg is always enough.
- The TFmodes are really just 80bit values, so we use only 3 registers
- to hold them, instead of 4, as the size would suggest.
- */
+ except in the FP regs, where a single reg is always enough. */
#define CLASS_MAX_NREGS(CLASS, MODE) \
(!MAYBE_INTEGER_CLASS_P (CLASS) \
? (COMPLEX_MODE_P (MODE) ? 2 : 1) \
- : ((GET_MODE_SIZE ((MODE) == TFmode ? XFmode : (MODE)) \
- + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+ : (((((MODE) == XFmode ? 12 : GET_MODE_SIZE (MODE))) \
+ + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
/* A C expression whose value is nonzero if pseudos that have been
assigned to registers of class CLASS would likely be spilled
@@ -1529,7 +1594,9 @@ enum reg_class
|| ((CLASS) == BREG) \
|| ((CLASS) == AD_REGS) \
|| ((CLASS) == SIREG) \
- || ((CLASS) == DIREG))
+ || ((CLASS) == DIREG) \
+ || ((CLASS) == FP_TOP_REG) \
+ || ((CLASS) == FP_SECOND_REG))
/* Return a class of registers that cannot change FROM mode to TO mode.
@@ -1629,18 +1696,7 @@ enum reg_class
definition that is usually appropriate, refer to expr.h for additional
documentation. If `REG_PARM_STACK_SPACE' is defined, the argument will be
computed in the stack and then loaded into a register. */
-#define MUST_PASS_IN_STACK(MODE, TYPE) \
- ((TYPE) != 0 \
- && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
- || TREE_ADDRESSABLE (TYPE) \
- || ((MODE) == TImode) \
- || ((MODE) == BLKmode \
- && ! ((TYPE) != 0 \
- && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
- && 0 == (int_size_in_bytes (TYPE) \
- % (PARM_BOUNDARY / BITS_PER_UNIT))) \
- && (FUNCTION_ARG_PADDING (MODE, TYPE) \
- == (BYTES_BIG_ENDIAN ? upward : downward)))))
+#define MUST_PASS_IN_STACK(MODE, TYPE) ix86_must_pass_in_stack ((MODE), (TYPE))
/* Value is the number of bytes of arguments automatically
popped when returning from a subroutine call.
@@ -1697,9 +1753,15 @@ typedef struct ix86_args {
int words; /* # words passed so far */
int nregs; /* # registers available for passing */
int regno; /* next available register number */
+ int fastcall; /* fastcall calling convention is used */
int sse_words; /* # sse words passed so far */
int sse_nregs; /* # sse registers available for passing */
+ int warn_sse; /* True when we want to warn about SSE ABI. */
+ int warn_mmx; /* True when we want to warn about MMX ABI. */
int sse_regno; /* next available sse register number */
+ int mmx_words; /* # mmx words passed so far */
+ int mmx_nregs; /* # mmx registers available for passing */
+ int mmx_regno; /* next available mmx register number */
int maybe_vaarg; /* true for calls to possibly vardic fncts. */
} CUMULATIVE_ARGS;
@@ -1707,8 +1769,8 @@ typedef struct ix86_args {
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
- init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME))
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
+ init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL))
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
@@ -1744,24 +1806,10 @@ typedef struct ix86_args {
made in memory and a pointer to the argument is passed instead of
the argument itself. The pointer is passed in whatever way is
appropriate for passing a pointer to that type. */
-
+
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
function_arg_pass_by_reference(&CUM, MODE, TYPE, NAMED)
-
-/* If PIC, we cannot make sibling calls to global functions
- because the PLT requires %ebx live.
- If we are returning floats on the 80387 register stack, we cannot
- make a sibcall from a function that doesn't return a float to a
- function that does or, conversely, from a function that does return
- a float to a function that doesn't; the necessary stack adjustment
- would not be executed. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) \
- ((DECL) \
- && (! flag_pic || ! TREE_PUBLIC (DECL)) \
- && (! TARGET_FLOAT_RETURNS_IN_80387 \
- || (FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (DECL)))) \
- == FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (TREE_TYPE (cfun->decl)))))))
-
+
/* Perform any needed actions needed for a function that is receiving a
variable number of arguments.
@@ -1780,10 +1828,6 @@ typedef struct ix86_args {
ix86_setup_incoming_varargs (&(CUM), (MODE), (TYPE), &(PRETEND_SIZE), \
(NO_RTL))
-/* Define the `__builtin_va_list' type for the ABI. */
-#define BUILD_VA_LIST_TYPE(VALIST) \
- ((VALIST) = ix86_build_va_list ())
-
/* Implement `va_start' for varargs and stdarg. */
#define EXPAND_BUILTIN_VA_START(VALIST, NEXTARG) \
ix86_va_start (VALIST, NEXTARG)
@@ -1792,11 +1836,8 @@ typedef struct ix86_args {
#define EXPAND_BUILTIN_VA_ARG(VALIST, TYPE) \
ix86_va_arg ((VALIST), (TYPE))
-/* This macro is invoked at the end of compilation. It is used here to
- output code for -fpic that will load the return address into %ebx. */
-
-#undef ASM_FILE_END
-#define ASM_FILE_END(FILE) ix86_asm_file_end (FILE)
+#define TARGET_ASM_FILE_END ix86_file_end
+#define NEED_INDICATE_EXEC_STACK 0
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
@@ -1873,12 +1914,6 @@ typedef struct ix86_args {
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT 0 */
-/* #define HAVE_POST_DECREMENT 0 */
-
-/* #define HAVE_PRE_DECREMENT 0 */
-/* #define HAVE_PRE_INCREMENT 0 */
-
/* Macros to check register numbers against specific register classes. */
/* These assume that REGNO is a hard or pseudo reg number.
@@ -2507,21 +2542,6 @@ enum ix86_builtins
IX86_BUILTIN_MAX
};
-#define TARGET_ENCODE_SECTION_INFO ix86_encode_section_info
-#define TARGET_STRIP_NAME_ENCODING ix86_strip_name_encoding
-
-#define ASM_OUTPUT_LABELREF(FILE,NAME) \
- do { \
- const char *xname = (NAME); \
- if (xname[0] == '%') \
- xname += 2; \
- if (xname[0] == '*') \
- xname += 1; \
- else \
- fputs (user_label_prefix, FILE); \
- fputs (xname, FILE); \
- } while (0)
-
/* Max number of args passed in registers. If this is more than 3, we will
have problems with ebx (register #4), since it is a caller save register and
is also used as the pic register in ELF. So for now, don't allow more than
@@ -2529,7 +2549,9 @@ enum ix86_builtins
#define REGPARM_MAX (TARGET_64BIT ? 6 : 3)
-#define SSE_REGPARM_MAX (TARGET_64BIT ? 8 : 0)
+#define SSE_REGPARM_MAX (TARGET_64BIT ? 8 : (TARGET_SSE ? 3 : 0))
+
+#define MMX_REGPARM_MAX (TARGET_64BIT ? 0 : (TARGET_MMX ? 3 : 0))
/* Specify the machine mode that this machine uses
@@ -2580,11 +2602,6 @@ enum ix86_builtins
is done just by pretending it is already truncated. */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-/* We assume that the store-condition-codes instructions store 0 for false
- and some other value for true. This is the value stored for true. */
-
-#define STORE_FLAG_VALUE 1
-
/* When a prototype says `char' or `short', really pass an `int'.
(The 386 can't easily push less than an int.) */
@@ -2615,292 +2632,6 @@ do { \
so give the MEM rtx a byte's mode. */
#define FUNCTION_MODE QImode
-/* A part of a C `switch' statement that describes the relative costs
- of constant RTL expressions. It must contain `case' labels for
- expression codes `const_int', `const', `symbol_ref', `label_ref'
- and `const_double'. Each case must ultimately reach a `return'
- statement to return the relative cost of the use of that kind of
- constant value in an expression. The cost may depend on the
- precise value of the constant, which is available for examination
- in X, and the rtx code of the expression in which it is contained,
- found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained
- with `GET_CODE (X)'. */
-
-#define CONST_COSTS(RTX, CODE, OUTER_CODE) \
- case CONST_INT: \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- if (TARGET_64BIT && !x86_64_sign_extended_value (RTX)) \
- return 3; \
- if (TARGET_64BIT && !x86_64_zero_extended_value (RTX)) \
- return 2; \
- return flag_pic && SYMBOLIC_CONST (RTX) ? 1 : 0; \
- \
- case CONST_DOUBLE: \
- if (GET_MODE (RTX) == VOIDmode) \
- return 0; \
- switch (standard_80387_constant_p (RTX)) \
- { \
- case 1: /* 0.0 */ \
- return 1; \
- case 2: /* 1.0 */ \
- return 2; \
- default: \
- /* Start with (MEM (SYMBOL_REF)), since that's where \
- it'll probably end up. Add a penalty for size. */ \
- return (COSTS_N_INSNS (1) + (flag_pic != 0) \
- + (GET_MODE (RTX) == SFmode ? 0 \
- : GET_MODE (RTX) == DFmode ? 1 : 2)); \
- }
-
-/* Delete the definition here when TOPLEVEL_COSTS_N_INSNS gets added to cse.c */
-#define TOPLEVEL_COSTS_N_INSNS(N) \
- do { total = COSTS_N_INSNS (N); goto egress_rtx_costs; } while (0)
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
- This can be used, for example, to indicate how costly a multiply
- instruction is. In writing this macro, you can use the construct
- `COSTS_N_INSNS (N)' to specify a cost equal to N fast
- instructions. OUTER_CODE is the code of the expression in which X
- is contained.
-
- This macro is optional; do not define it if the default cost
- assumptions are adequate for the target machine. */
-
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case ZERO_EXTEND: \
- /* The zero extensions is often completely free on x86_64, so make \
- it as cheap as possible. */ \
- if (TARGET_64BIT && GET_MODE (X) == DImode \
- && GET_MODE (XEXP (X, 0)) == SImode) \
- { \
- total = 1; goto egress_rtx_costs; \
- } \
- else \
- TOPLEVEL_COSTS_N_INSNS (TARGET_ZERO_EXTEND_WITH_AND ? \
- ix86_cost->add : ix86_cost->movzx); \
- break; \
- case SIGN_EXTEND: \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->movsx); \
- break; \
- case ASHIFT: \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (GET_MODE (XEXP (X, 0)) != DImode || TARGET_64BIT)) \
- { \
- HOST_WIDE_INT value = INTVAL (XEXP (X, 1)); \
- if (value == 1) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->add); \
- if ((value == 2 || value == 3) \
- && !TARGET_DECOMPOSE_LEA \
- && ix86_cost->lea <= ix86_cost->shift_const) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->lea); \
- } \
- /* fall through */ \
- \
- case ROTATE: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- case ROTATERT: \
- if (!TARGET_64BIT && GET_MODE (XEXP (X, 0)) == DImode) \
- { \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
- { \
- if (INTVAL (XEXP (X, 1)) > 32) \
- TOPLEVEL_COSTS_N_INSNS(ix86_cost->shift_const + 2); \
- else \
- TOPLEVEL_COSTS_N_INSNS(ix86_cost->shift_const * 2); \
- } \
- else \
- { \
- if (GET_CODE (XEXP (X, 1)) == AND) \
- TOPLEVEL_COSTS_N_INSNS(ix86_cost->shift_var * 2); \
- else \
- TOPLEVEL_COSTS_N_INSNS(ix86_cost->shift_var * 6 + 2); \
- } \
- } \
- else \
- { \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->shift_const); \
- else \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->shift_var); \
- } \
- break; \
- \
- case MULT: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fmul); \
- else if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
- { \
- unsigned HOST_WIDE_INT value = INTVAL (XEXP (X, 1)); \
- int nbits = 0; \
- \
- while (value != 0) \
- { \
- nbits++; \
- value >>= 1; \
- } \
- \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->mult_init \
- + nbits * ix86_cost->mult_bit); \
- } \
- else /* This is arbitrary */ \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->mult_init \
- + 7 * ix86_cost->mult_bit); \
- \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fdiv); \
- else \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->divide); \
- break; \
- \
- case PLUS: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fadd); \
- else if (!TARGET_DECOMPOSE_LEA \
- && INTEGRAL_MODE_P (GET_MODE (X)) \
- && GET_MODE_BITSIZE (GET_MODE (X)) <= GET_MODE_BITSIZE (Pmode)) \
- { \
- if (GET_CODE (XEXP (X, 0)) == PLUS \
- && GET_CODE (XEXP (XEXP (X, 0), 0)) == MULT \
- && GET_CODE (XEXP (XEXP (XEXP (X, 0), 0), 1)) == CONST_INT \
- && CONSTANT_P (XEXP (X, 1))) \
- { \
- HOST_WIDE_INT val = INTVAL (XEXP (XEXP (XEXP (X, 0), 0), 1));\
- if (val == 2 || val == 4 || val == 8) \
- { \
- return (COSTS_N_INSNS (ix86_cost->lea) \
- + rtx_cost (XEXP (XEXP (X, 0), 1), \
- (OUTER_CODE)) \
- + rtx_cost (XEXP (XEXP (XEXP (X, 0), 0), 0), \
- (OUTER_CODE)) \
- + rtx_cost (XEXP (X, 1), (OUTER_CODE))); \
- } \
- } \
- else if (GET_CODE (XEXP (X, 0)) == MULT \
- && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT) \
- { \
- HOST_WIDE_INT val = INTVAL (XEXP (XEXP (X, 0), 1)); \
- if (val == 2 || val == 4 || val == 8) \
- { \
- return (COSTS_N_INSNS (ix86_cost->lea) \
- + rtx_cost (XEXP (XEXP (X, 0), 0), \
- (OUTER_CODE)) \
- + rtx_cost (XEXP (X, 1), (OUTER_CODE))); \
- } \
- } \
- else if (GET_CODE (XEXP (X, 0)) == PLUS) \
- { \
- return (COSTS_N_INSNS (ix86_cost->lea) \
- + rtx_cost (XEXP (XEXP (X, 0), 0), (OUTER_CODE)) \
- + rtx_cost (XEXP (XEXP (X, 0), 1), (OUTER_CODE)) \
- + rtx_cost (XEXP (X, 1), (OUTER_CODE))); \
- } \
- } \
- /* fall through */ \
- \
- case MINUS: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fadd); \
- /* fall through */ \
- \
- case AND: \
- case IOR: \
- case XOR: \
- if (!TARGET_64BIT && GET_MODE (X) == DImode) \
- return (COSTS_N_INSNS (ix86_cost->add) * 2 \
- + (rtx_cost (XEXP (X, 0), (OUTER_CODE)) \
- << (GET_MODE (XEXP (X, 0)) != DImode)) \
- + (rtx_cost (XEXP (X, 1), (OUTER_CODE)) \
- << (GET_MODE (XEXP (X, 1)) != DImode))); \
- /* fall through */ \
- \
- case NEG: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fchs); \
- /* fall through */ \
- \
- case NOT: \
- if (!TARGET_64BIT && GET_MODE (X) == DImode) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->add * 2); \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->add); \
- \
- case FLOAT_EXTEND: \
- if (!TARGET_SSE_MATH \
- || !VALID_SSE_REG_MODE (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (0); \
- break; \
- \
- case ABS: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fabs); \
- break; \
- \
- case SQRT: \
- if (FLOAT_MODE_P (GET_MODE (X))) \
- TOPLEVEL_COSTS_N_INSNS (ix86_cost->fsqrt); \
- break; \
- \
- egress_rtx_costs: \
- break;
-
-
-/* An expression giving the cost of an addressing mode that contains
- ADDRESS. If not defined, the cost is computed from the ADDRESS
- expression and the `CONST_COSTS' values.
-
- For most CISC machines, the default cost is a good approximation
- of the true cost of the addressing mode. However, on RISC
- machines, all instructions normally have the same length and
- execution time. Hence all addresses will have equal costs.
-
- In cases where more than one form of an address is known, the form
- with the lowest cost will be used. If multiple forms have the
- same, lowest, cost, the one that is the most complex will be used.
-
- For example, suppose an address that is equal to the sum of a
- register and a constant is used twice in the same basic block.
- When this macro is not defined, the address will be computed in a
- register and memory references will be indirect through that
- register. On machines where the cost of the addressing mode
- containing the sum is no higher than that of a simple indirect
- reference, this will produce an additional instruction and
- possibly require an additional register. Proper specification of
- this macro eliminates this overhead for such machines.
-
- Similar use of this macro is made in strength reduction of loops.
-
- ADDRESS need not be valid as an address. In such a case, the cost
- is not relevant and can be any value; invalid addresses need not be
- assigned a different cost.
-
- On machines where an address involving more than one register is as
- cheap as an address computation involving only one register,
- defining `ADDRESS_COST' to reflect this can cause two registers to
- be live over a region of code where only one would have been if
- `ADDRESS_COST' were not defined in that manner. This effect should
- be considered in the definition of this macro. Equivalent costs
- should probably only be given to addresses with different numbers
- of registers on machines with lots of registers.
-
- This macro will normally either not be defined or be defined as a
- constant.
-
- For i386, it is better to use a complex address than let gcc copy
- the address into a reg and make a new pseudo. But not if the address
- requires to two regs - that would mean more pseudos with longer
- lifetimes. */
-
-#define ADDRESS_COST(RTX) \
- ix86_address_cost (RTX)
-
/* A C expression for the cost of moving data from a register in class FROM to
one in class TO. The classes are expressed using the enumeration values
such as `GENERAL_REGS'. A value of 2 is the default; other values are
@@ -2962,12 +2693,6 @@ do { \
/* #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) 0 */
-/* Define this macro to inhibit strength reduction of memory
- addresses. (On some machines, such strength reduction seems to do
- harm rather than good.) */
-
-/* #define DONT_REDUCE_ADDR */
-
/* Define this macro if it is as good or better to call a constant
function address than to call an address kept in a register.
@@ -3015,13 +2740,12 @@ do { \
For non floating point regs, the following are the HImode names.
For float regs, the stack top is sometimes referred to as "%st(0)"
- instead of just "%st". PRINT_REG handles this with the "y" code. */
+ instead of just "%st". PRINT_OPERAND handles this with the "y" code. */
-#undef HI_REGISTER_NAMES
#define HI_REGISTER_NAMES \
{"ax","dx","cx","bx","si","di","bp","sp", \
- "st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)","", \
- "flags","fpsr", "dirflag", "frame", \
+ "st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)", \
+ "argp", "flags", "fpsr", "dirflag", "frame", \
"xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7", \
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" , \
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
@@ -3098,14 +2822,6 @@ extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER];
? ((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4\
: DW_EH_PE_absptr)
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable named NAME.
- LABELNO is an integer which is different for each call. */
-
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
-
/* This is how to output an insn to push a register on the stack.
It need not be very fast code. */
@@ -3152,11 +2868,6 @@ do { \
#define ASM_OUTPUT_DWARF_ADDR_CONST(FILE, X) \
i386_dwarf_output_addr_const ((FILE), (X))
-/* Either simplify a location expression, or return the original. */
-
-#define ASM_SIMPLIFY_DWARF_ADDR(X) \
- i386_simplify_dwarf_addr (X)
-
/* Emit a dtp-relative reference to a TLS variable. */
#ifdef HAVE_AS_TLS
@@ -3180,17 +2891,6 @@ do { \
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
((CODE) == '*' || (CODE) == '+' || (CODE) == '&')
-/* Print the name of a register based on its machine mode and number.
- If CODE is 'w', pretend the mode is HImode.
- If CODE is 'b', pretend the mode is QImode.
- If CODE is 'k', pretend the mode is SImode.
- If CODE is 'q', pretend the mode is DImode.
- If CODE is 'h', pretend the reg is the `high' byte register.
- If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op. */
-
-#define PRINT_REG(X, CODE, FILE) \
- print_reg ((X), (CODE), (FILE))
-
#define PRINT_OPERAND(FILE, X, CODE) \
print_operand ((FILE), (X), (CODE))
@@ -3203,70 +2903,6 @@ do { \
goto FAIL; \
} while (0);
-/* Print the name of a register for based on its machine mode and number.
- This macro is used to print debugging output.
- This macro is different from PRINT_REG in that it may be used in
- programs that are not linked with aux-output.o. */
-
-#define DEBUG_PRINT_REG(X, CODE, FILE) \
- do { static const char * const hi_name[] = HI_REGISTER_NAMES; \
- static const char * const qi_name[] = QI_REGISTER_NAMES; \
- fprintf ((FILE), "%d ", REGNO (X)); \
- if (REGNO (X) == FLAGS_REG) \
- { fputs ("flags", (FILE)); break; } \
- if (REGNO (X) == DIRFLAG_REG) \
- { fputs ("dirflag", (FILE)); break; } \
- if (REGNO (X) == FPSR_REG) \
- { fputs ("fpsr", (FILE)); break; } \
- if (REGNO (X) == ARG_POINTER_REGNUM) \
- { fputs ("argp", (FILE)); break; } \
- if (REGNO (X) == FRAME_POINTER_REGNUM) \
- { fputs ("frame", (FILE)); break; } \
- if (STACK_TOP_P (X)) \
- { fputs ("st(0)", (FILE)); break; } \
- if (FP_REG_P (X)) \
- { fputs (hi_name[REGNO(X)], (FILE)); break; } \
- if (REX_INT_REG_P (X)) \
- { \
- switch (GET_MODE_SIZE (GET_MODE (X))) \
- { \
- default: \
- case 8: \
- fprintf ((FILE), "r%i", REGNO (X) \
- - FIRST_REX_INT_REG + 8); \
- break; \
- case 4: \
- fprintf ((FILE), "r%id", REGNO (X) \
- - FIRST_REX_INT_REG + 8); \
- break; \
- case 2: \
- fprintf ((FILE), "r%iw", REGNO (X) \
- - FIRST_REX_INT_REG + 8); \
- break; \
- case 1: \
- fprintf ((FILE), "r%ib", REGNO (X) \
- - FIRST_REX_INT_REG + 8); \
- break; \
- } \
- break; \
- } \
- switch (GET_MODE_SIZE (GET_MODE (X))) \
- { \
- case 8: \
- fputs ("r", (FILE)); \
- fputs (hi_name[REGNO (X)], (FILE)); \
- break; \
- default: \
- fputs ("e", (FILE)); \
- case 2: \
- fputs (hi_name[REGNO (X)], (FILE)); \
- break; \
- case 1: \
- fputs (qi_name[REGNO (X)], (FILE)); \
- break; \
- } \
- } while (0)
-
/* a letter which is not needed by the normal asm syntax, which
we can use for operand syntax in the extended asm */
@@ -3292,17 +2928,21 @@ do { \
{"x86_64_zext_immediate_operand", {CONST_INT, CONST_DOUBLE, CONST, \
SYMBOL_REF, LABEL_REF}}, \
{"shiftdi_operand", {SUBREG, REG, MEM}}, \
- {"const_int_1_operand", {CONST_INT}}, \
{"const_int_1_31_operand", {CONST_INT}}, \
{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}}, \
{"aligned_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
LABEL_REF, SUBREG, REG, MEM}}, \
{"pic_symbolic_operand", {CONST}}, \
{"call_insn_operand", {REG, SUBREG, MEM, SYMBOL_REF}}, \
+ {"sibcall_insn_operand", {REG, SUBREG, SYMBOL_REF}}, \
{"constant_call_address_operand", {SYMBOL_REF, CONST}}, \
{"const0_operand", {CONST_INT, CONST_DOUBLE}}, \
{"const1_operand", {CONST_INT}}, \
{"const248_operand", {CONST_INT}}, \
+ {"const_0_to_3_operand", {CONST_INT}}, \
+ {"const_0_to_7_operand", {CONST_INT}}, \
+ {"const_0_to_15_operand", {CONST_INT}}, \
+ {"const_0_to_255_operand", {CONST_INT}}, \
{"incdec_operand", {CONST_INT}}, \
{"mmx_reg_operand", {REG}}, \
{"reg_no_sp_operand", {SUBREG, REG}}, \
@@ -3310,6 +2950,7 @@ do { \
SYMBOL_REF, LABEL_REF, SUBREG, REG, MEM}}, \
{"nonmemory_no_elim_operand", {CONST_INT, REG, SUBREG}}, \
{"index_register_operand", {SUBREG, REG}}, \
+ {"flags_reg_operand", {REG}}, \
{"q_regs_operand", {SUBREG, REG}}, \
{"non_q_regs_operand", {SUBREG, REG}}, \
{"fcmov_comparison_operator", {EQ, NE, LTU, GTU, LEU, GEU, UNORDERED, \
@@ -3321,6 +2962,8 @@ do { \
{"ix86_comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, \
GTU, UNORDERED, ORDERED, UNLE, UNLT, \
UNGE, UNGT, LTGT, UNEQ }}, \
+ {"ix86_carry_flag_operator", {LTU, LT, UNLT, GT, UNGT, LE, UNLE, \
+ GE, UNGE, LTGT, UNEQ}}, \
{"cmp_fp_expander_operand", {CONST_DOUBLE, SUBREG, REG, MEM}}, \
{"ext_register_operand", {SUBREG, REG}}, \
{"binary_fp_operator", {PLUS, MINUS, MULT, DIV}}, \
@@ -3344,7 +2987,10 @@ do { \
{"register_and_not_any_fp_reg_operand", {REG}}, \
{"fp_register_operand", {REG}}, \
{"register_and_not_fp_reg_operand", {REG}}, \
+ {"zero_extended_scalar_load_operand", {MEM}}, \
{"vector_move_operand", {CONST_VECTOR, SUBREG, REG, MEM}}, \
+ {"no_seg_address_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
+ LABEL_REF, SUBREG, REG, MEM, PLUS, MULT}},
/* A list of predicates that do special things with modes, and so
should not elicit warnings for VOIDmode match_operand. */
@@ -3364,11 +3010,12 @@ enum processor_type
PROCESSOR_K6,
PROCESSOR_ATHLON,
PROCESSOR_PENTIUM4,
+ PROCESSOR_K8,
PROCESSOR_max
};
-extern enum processor_type ix86_cpu;
-extern const char *ix86_cpu_string;
+extern enum processor_type ix86_tune;
+extern const char *ix86_tune_string;
extern enum processor_type ix86_arch;
extern const char *ix86_arch_string;
@@ -3459,7 +3106,7 @@ enum fp_cw_mode {FP_CW_STORED, FP_CW_UNINITIALIZED, FP_CW_ANY};
/* Define this macro if the port needs extra instructions inserted
for mode switching in an optimizing compilation. */
-#define OPTIMIZE_MODE_SWITCHING(ENTITY) 1
+#define OPTIMIZE_MODE_SWITCHING(ENTITY) ix86_optimize_mode_switching
/* If you define `OPTIMIZE_MODE_SWITCHING', you have to define this as
initializer for an array of integers. Each initializer element N
@@ -3505,15 +3152,38 @@ enum fp_cw_mode {FP_CW_STORED, FP_CW_UNINITIALIZED, FP_CW_ANY};
scheduling just increases amount of live registers at time and in
the turn amount of fxch instructions needed.
- ??? Maybe Pentium chips benefits from renaming, someone can try... */
+ ??? Maybe Pentium chips benefits from renaming, someone can try.... */
#define HARD_REGNO_RENAME_OK(SRC, TARGET) \
((SRC) < FIRST_STACK_REG || (SRC) > LAST_STACK_REG)
-#define MACHINE_DEPENDENT_REORG(X) x86_machine_dependent_reorg(X)
+#define DLL_IMPORT_EXPORT_PREFIX '#'
+
+#define FASTCALL_PREFIX '@'
+
+struct machine_function GTY(())
+{
+ struct stack_local_entry *stack_locals;
+ const char *some_ld_name;
+ int save_varrargs_registers;
+ int accesses_prev_frame;
+ int optimize_mode_switching;
+ /* Set by ix86_compute_frame_layout and used by prologue/epilogue expander to
+ determine the style used. */
+ int use_fast_prologue_epilogue;
+ /* Number of saved registers USE_FAST_PROLOGUE_EPILOGUE has been computed
+ for. */
+ int use_fast_prologue_epilogue_nregs;
+};
+
+#define ix86_stack_locals (cfun->machine->stack_locals)
+#define ix86_save_varrargs_registers (cfun->machine->save_varrargs_registers)
+#define ix86_optimize_mode_switching (cfun->machine->optimize_mode_switching)
-#define DLL_IMPORT_EXPORT_PREFIX '@'
+/* Control behavior of x86_file_start. */
+#define X86_FILE_START_VERSION_DIRECTIVE false
+#define X86_FILE_START_FLTUSED false
/*
Local variables:
diff --git a/contrib/gcc/config/i386/i386.md b/contrib/gcc/config/i386/i386.md
index e4377a5b0a57..a190d23378f0 100644
--- a/contrib/gcc/config/i386/i386.md
+++ b/contrib/gcc/config/i386/i386.md
@@ -1,24 +1,24 @@
;; GCC machine description for IA-32 and x86-64.
;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-;; 2001, 2002, 2003
+;; 2001, 2002, 2003, 2004
;; Free Software Foundation, Inc.
;; Mostly by William Schelter.
;; x86_64 support added by Jan Hubicka
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA. */
;;
@@ -27,9 +27,6 @@
;;
;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
;;
-;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
-;; updates for most instructions.
-;;
;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
;; constraint letters.
;;
@@ -66,7 +63,6 @@
(UNSPEC_INDNTPOFF 8)
; Prologue support
- (UNSPEC_STACK_PROBE 10)
(UNSPEC_STACK_ALLOC 11)
(UNSPEC_SET_GOT 12)
(UNSPEC_SSE_PROLOGUE_SAVE 13)
@@ -80,7 +76,6 @@
(UNSPEC_SCAS 20)
(UNSPEC_SIN 21)
(UNSPEC_COS 22)
- (UNSPEC_BSF 23)
(UNSPEC_FNSTSW 24)
(UNSPEC_SAHF 25)
(UNSPEC_FSTCW 26)
@@ -117,16 +112,28 @@
(UNSPEC_MOVSLDUP 75)
(UNSPEC_LDQQU 76)
(UNSPEC_MOVDDUP 77)
+
+ ; x87 Floating point
+ (UNSPEC_FPATAN 65)
+ (UNSPEC_FYL2X 66)
+ (UNSPEC_FSCALE 67)
+ (UNSPEC_FRNDINT 68)
+ (UNSPEC_F2XM1 69)
+
+ ; REP instruction
+ (UNSPEC_REP 75)
])
(define_constants
[(UNSPECV_BLOCKAGE 0)
+ (UNSPECV_STACK_PROBE 10)
(UNSPECV_EH_RETURN 13)
(UNSPECV_EMMS 31)
(UNSPECV_LDMXCSR 37)
(UNSPECV_STMXCSR 40)
(UNSPECV_FEMMS 46)
(UNSPECV_CLFLUSH 57)
+ (UNSPECV_ALIGN 68)
(UNSPECV_MONITOR 69)
(UNSPECV_MWAIT 70)
])
@@ -142,8 +149,8 @@
;; Processor type. This attribute must exactly match the processor_type
;; enumeration in i386.h.
-(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4"
- (const (symbol_ref "ix86_cpu")))
+(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
+ (const (symbol_ref "ix86_tune")))
;; A basic instruction type. Refinements due to arguments to be
;; provided in other attributes.
@@ -152,17 +159,17 @@
alu,alu1,negnot,imov,imovx,lea,
incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
icmp,test,ibr,setcc,icmov,
- push,pop,call,callv,
+ push,pop,call,callv,leave,
str,cld,
fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
sselog,sseiadd,sseishft,sseimul,
- sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv,
+ sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
(const_string "other"))
;; Main data type used by the insn
(define_attr "mode"
- "unknown,none,QI,HI,SI,DI,unknownfp,SF,DF,XF,TI,V4SF,V2DF,V2SF"
+ "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
(const_string "unknown"))
;; The CPU unit operations uses.
@@ -170,7 +177,7 @@
(cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
(const_string "i387")
(eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
- sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv")
+ sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
(const_string "sse")
(eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
(const_string "mmx")
@@ -180,7 +187,7 @@
;; The (bounding maximum) length of an instruction immediate.
(define_attr "length_immediate" ""
- (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv")
+ (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
(const_int 0)
(eq_attr "unit" "i387,sse,mmx")
(const_int 0)
@@ -234,17 +241,29 @@
;; Set when 0f opcode prefix is used.
(define_attr "prefix_0f" ""
(if_then_else
- (eq_attr "type"
- "imovx,setcc,icmov,
- sselog,sseiadd,sseishft,sseimul,
- sse,ssemov,sseadd,ssemul,ssecmp,ssecvt,ssediv,
- mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
+ (ior (eq_attr "type" "imovx,setcc,icmov")
+ (eq_attr "unit" "sse,mmx"))
(const_int 1)
(const_int 0)))
+;; Set when 0f opcode prefix is used.
+(define_attr "prefix_rex" ""
+ (cond [(and (eq_attr "mode" "DI")
+ (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
+ (const_int 1)
+ (and (eq_attr "mode" "QI")
+ (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
+ (const_int 0)))
+ (const_int 1)
+ (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
+ (const_int 0))
+ (const_int 1)
+ ]
+ (const_int 0)))
+
;; Set when modrm byte is used.
(define_attr "modrm" ""
- (cond [(eq_attr "type" "str,cld")
+ (cond [(eq_attr "type" "str,cld,leave")
(const_int 0)
(eq_attr "unit" "i387")
(const_int 0)
@@ -285,7 +304,8 @@
(attr "length_address")))]
(plus (plus (attr "modrm")
(plus (attr "prefix_0f")
- (const_int 1)))
+ (plus (attr "prefix_rex")
+ (const_int 1))))
(plus (attr "prefix_rep")
(plus (attr "prefix_data16")
(plus (attr "length_immediate")
@@ -300,17 +320,21 @@
(const_string "unknown")
(eq_attr "type" "lea,fcmov,fpspc,cld")
(const_string "none")
- (eq_attr "type" "fistp")
+ (eq_attr "type" "fistp,leave")
(const_string "both")
(eq_attr "type" "push")
(if_then_else (match_operand 1 "memory_operand" "")
(const_string "both")
(const_string "store"))
- (eq_attr "type" "pop,setcc")
+ (eq_attr "type" "pop")
(if_then_else (match_operand 0 "memory_operand" "")
(const_string "both")
(const_string "load"))
- (eq_attr "type" "icmp,test,ssecmp,mmxcmp,fcmp")
+ (eq_attr "type" "setcc")
+ (if_then_else (match_operand 0 "memory_operand" "")
+ (const_string "store")
+ (const_string "none"))
+ (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
(if_then_else (ior (match_operand 0 "memory_operand" "")
(match_operand 1 "memory_operand" ""))
(const_string "load")
@@ -327,7 +351,7 @@
(if_then_else (match_operand 1 "constant_call_address_operand" "")
(const_string "none")
(const_string "load"))
- (and (eq_attr "type" "alu1,negnot")
+ (and (eq_attr "type" "alu1,negnot,ishift1")
(match_operand 1 "memory_operand" ""))
(const_string "both")
(and (match_operand 0 "memory_operand" "")
@@ -338,10 +362,10 @@
(match_operand 1 "memory_operand" "")
(const_string "load")
(and (eq_attr "type"
- "!alu1,negnot,
+ "!alu1,negnot,ishift1,
imov,imovx,icmp,test,
fmov,fcmp,fsgn,
- sse,ssemov,ssecmp,ssecvt,
+ sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
mmx,mmxmov,mmxcmp,mmxcvt")
(match_operand 2 "memory_operand" ""))
(const_string "load")
@@ -692,17 +716,6 @@
[(set (reg:CC 17)
(compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
(match_operand:XF 1 "cmp_fp_expander_operand" "")))]
- "!TARGET_64BIT && TARGET_80387"
-{
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
- DONE;
-})
-
-(define_expand "cmptf"
- [(set (reg:CC 17)
- (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
- (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
"TARGET_80387"
{
ix86_compare_op0 = operands[0];
@@ -766,7 +779,13 @@
return "ftst\;fnstsw\t%0";
}
[(set_attr "type" "multi")
- (set_attr "mode" "unknownfp")])
+ (set (attr "mode")
+ (cond [(match_operand:SF 1 "" "")
+ (const_string "SF")
+ (match_operand:DF 1 "" "")
+ (const_string "DF")
+ ]
+ (const_string "XF")))])
;; We may not use "#" to split and emit these, since the REG_DEAD notes
;; used to manage the reg stack popping would not be preserved.
@@ -820,16 +839,6 @@
(compare:CCFP
(match_operand:XF 0 "register_operand" "f")
(match_operand:XF 1 "register_operand" "f")))]
- "!TARGET_64BIT && TARGET_80387"
- "* return output_fp_compare (insn, operands, 0, 0);"
- [(set_attr "type" "fcmp")
- (set_attr "mode" "XF")])
-
-(define_insn "*cmpfp_2_tf"
- [(set (reg:CCFP 18)
- (compare:CCFP
- (match_operand:TF 0 "register_operand" "f")
- (match_operand:TF 1 "register_operand" "f")))]
"TARGET_80387"
"* return output_fp_compare (insn, operands, 0, 0);"
[(set_attr "type" "fcmp")
@@ -842,18 +851,6 @@
(match_operand:XF 1 "register_operand" "f")
(match_operand:XF 2 "register_operand" "f"))]
UNSPEC_FNSTSW))]
- "!TARGET_64BIT && TARGET_80387"
- "* return output_fp_compare (insn, operands, 2, 0);"
- [(set_attr "type" "multi")
- (set_attr "mode" "XF")])
-
-(define_insn "*cmpfp_2_tf_1"
- [(set (match_operand:HI 0 "register_operand" "=a")
- (unspec:HI
- [(compare:CCFP
- (match_operand:TF 1 "register_operand" "f")
- (match_operand:TF 2 "register_operand" "f"))]
- UNSPEC_FNSTSW))]
"TARGET_80387"
"* return output_fp_compare (insn, operands, 2, 0);"
[(set_attr "type" "multi")
@@ -869,7 +866,13 @@
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
"* return output_fp_compare (insn, operands, 0, 1);"
[(set_attr "type" "fcmp")
- (set_attr "mode" "unknownfp")])
+ (set (attr "mode")
+ (cond [(match_operand:SF 1 "" "")
+ (const_string "SF")
+ (match_operand:DF 1 "" "")
+ (const_string "DF")
+ ]
+ (const_string "XF")))])
(define_insn "*cmpfp_2u_1"
[(set (match_operand:HI 0 "register_operand" "=a")
@@ -883,7 +886,13 @@
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
"* return output_fp_compare (insn, operands, 2, 1);"
[(set_attr "type" "multi")
- (set_attr "mode" "unknownfp")])
+ (set (attr "mode")
+ (cond [(match_operand:SF 1 "" "")
+ (const_string "SF")
+ (match_operand:DF 1 "" "")
+ (const_string "DF")
+ ]
+ (const_string "XF")))])
;; Patterns to match the SImode-in-memory ficom instructions.
;;
@@ -923,7 +932,7 @@
;; FP compares, step 2
;; Move the fpsw to ax.
-(define_insn "x86_fnstsw_1"
+(define_insn "*x86_fnstsw_1"
[(set (match_operand:HI 0 "register_operand" "=a")
(unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
"TARGET_80387"
@@ -958,7 +967,13 @@
&& GET_MODE (operands[0]) == GET_MODE (operands[0])"
"* return output_fp_compare (insn, operands, 1, 0);"
[(set_attr "type" "fcmp")
- (set_attr "mode" "unknownfp")
+ (set (attr "mode")
+ (cond [(match_operand:SF 1 "" "")
+ (const_string "SF")
+ (match_operand:DF 1 "" "")
+ (const_string "DF")
+ ]
+ (const_string "XF")))
(set_attr "athlon_decode" "vector")])
(define_insn "*cmpfp_i_sse"
@@ -969,8 +984,11 @@
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[0])"
"* return output_fp_compare (insn, operands, 1, 0);"
- [(set_attr "type" "fcmp,ssecmp")
- (set_attr "mode" "unknownfp")
+ [(set_attr "type" "fcmp,ssecomi")
+ (set (attr "mode")
+ (if_then_else (match_operand:SF 1 "" "")
+ (const_string "SF")
+ (const_string "DF")))
(set_attr "athlon_decode" "vector")])
(define_insn "*cmpfp_i_sse_only"
@@ -980,8 +998,11 @@
"SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[0])"
"* return output_fp_compare (insn, operands, 1, 0);"
- [(set_attr "type" "ssecmp")
- (set_attr "mode" "unknownfp")
+ [(set_attr "type" "ssecomi")
+ (set (attr "mode")
+ (if_then_else (match_operand:SF 1 "" "")
+ (const_string "SF")
+ (const_string "DF")))
(set_attr "athlon_decode" "vector")])
(define_insn "*cmpfp_iu"
@@ -994,7 +1015,13 @@
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
"* return output_fp_compare (insn, operands, 1, 1);"
[(set_attr "type" "fcmp")
- (set_attr "mode" "unknownfp")
+ (set (attr "mode")
+ (cond [(match_operand:SF 1 "" "")
+ (const_string "SF")
+ (match_operand:DF 1 "" "")
+ (const_string "DF")
+ ]
+ (const_string "XF")))
(set_attr "athlon_decode" "vector")])
(define_insn "*cmpfp_iu_sse"
@@ -1005,8 +1032,11 @@
&& SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
"* return output_fp_compare (insn, operands, 1, 1);"
- [(set_attr "type" "fcmp,ssecmp")
- (set_attr "mode" "unknownfp")
+ [(set_attr "type" "fcmp,ssecomi")
+ (set (attr "mode")
+ (if_then_else (match_operand:SF 1 "" "")
+ (const_string "SF")
+ (const_string "DF")))
(set_attr "athlon_decode" "vector")])
(define_insn "*cmpfp_iu_sse_only"
@@ -1016,8 +1046,11 @@
"SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
"* return output_fp_compare (insn, operands, 1, 1);"
- [(set_attr "type" "ssecmp")
- (set_attr "mode" "unknownfp")
+ [(set_attr "type" "ssecomi")
+ (set (attr "mode")
+ (if_then_else (match_operand:SF 1 "" "")
+ (const_string "SF")
+ (const_string "DF")))
(set_attr "athlon_decode" "vector")])
;; Move instructions.
@@ -1095,13 +1128,13 @@
[(set_attr "type" "alu1")
(set_attr "mode" "SI")
(set_attr "length_immediate" "0")])
-
+
(define_insn "*movsi_or"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 1 "immediate_operand" "i"))
(clobber (reg:CC 17))]
- "reload_completed && GET_CODE (operands[1]) == CONST_INT
- && INTVAL (operands[1]) == -1
+ "reload_completed
+ && operands[1] == constm1_rtx
&& (TARGET_PENTIUM || optimize_size)"
{
operands[1] = constm1_rtx;
@@ -1112,9 +1145,49 @@
(set_attr "length_immediate" "1")])
(define_insn "*movsi_1"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!*Y,!rm")
- (match_operand:SI 1 "general_operand" "rinm,rin,rm,*y,*y,*Y,rm,*Y"))]
- "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
+ (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
+ "(TARGET_INTER_UNIT_MOVES || optimize_size)
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
+{
+ switch (get_attr_type (insn))
+ {
+ case TYPE_SSEMOV:
+ if (get_attr_mode (insn) == MODE_TI)
+ return "movdqa\t{%1, %0|%0, %1}";
+ return "movd\t{%1, %0|%0, %1}";
+
+ case TYPE_MMXMOV:
+ if (get_attr_mode (insn) == MODE_DI)
+ return "movq\t{%1, %0|%0, %1}";
+ return "movd\t{%1, %0|%0, %1}";
+
+ case TYPE_LEA:
+ return "lea{l}\t{%1, %0|%0, %1}";
+
+ default:
+ if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
+ abort();
+ return "mov{l}\t{%1, %0|%0, %1}";
+ }
+}
+ [(set (attr "type")
+ (cond [(eq_attr "alternative" "2,3,4")
+ (const_string "mmxmov")
+ (eq_attr "alternative" "5,6,7")
+ (const_string "ssemov")
+ (and (ne (symbol_ref "flag_pic") (const_int 0))
+ (match_operand:SI 1 "symbolic_operand" ""))
+ (const_string "lea")
+ ]
+ (const_string "imov")))
+ (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
+
+(define_insn "*movsi_1_nointernunit"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
+ (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
+ "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
switch (get_attr_type (insn))
{
@@ -1147,9 +1220,9 @@
(const_string "lea")
]
(const_string "imov")))
- (set_attr "mode" "SI,SI,SI,SI,DI,TI,SI,SI")])
+ (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
-;; Stores and loads of ax to arbitary constant address.
+;; Stores and loads of ax to arbitrary constant address.
;; We fake an second form of instruction to force reload to load address
;; into register when rax is not available
(define_insn "*movabssi_1_rex64"
@@ -1268,7 +1341,7 @@
]
(const_string "HI")))])
-;; Stores and loads of ax to arbitary constant address.
+;; Stores and loads of ax to arbitrary constant address.
;; We fake an second form of instruction to force reload to load address
;; into register when rax is not available
(define_insn "*movabshi_1_rex64"
@@ -1586,7 +1659,7 @@
(const_string "SI")
(const_string "QI")))])
-;; Stores and loads of ax to arbitary constant address.
+;; Stores and loads of ax to arbitrary constant address.
;; We fake an second form of instruction to force reload to load address
;; into register when rax is not available
(define_insn "*movabsqi_1_rex64"
@@ -1690,11 +1763,11 @@
[(set_attr "type" "imov")
(set_attr "mode" "QI")])
-(define_insn "*movsi_insv_1_rex64"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
+(define_insn "movdi_insv_1_rex64"
+ [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
(const_int 8)
(const_int 8))
- (match_operand:SI 1 "nonmemory_operand" "Qn"))]
+ (match_operand:DI 1 "nonmemory_operand" "Qn"))]
"TARGET_64BIT"
"mov{b}\t{%b1, %h0|%h0, %b1}"
[(set_attr "type" "imov")
@@ -1704,9 +1777,8 @@
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
(const_int 8)
(const_int 8))
- (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
- (const_int 8))
- (const_int 255)))]
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
+ (const_int 8)))]
""
"mov{b}\t{%h1, %h0|%h0, %h1}"
[(set_attr "type" "imov")
@@ -1824,8 +1896,7 @@
(clobber (reg:CC 17))]
"TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
&& reload_completed
- && GET_CODE (operands[1]) == CONST_INT
- && INTVAL (operands[1]) == -1"
+ && operands[1] == constm1_rtx"
{
operands[1] = constm1_rtx;
return "or{q}\t{%1, %0|%0, %1}";
@@ -1869,19 +1940,23 @@
"ix86_split_long_move (operands); DONE;")
(define_insn "*movdi_1_rex64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!m*y,!*y,!*Y,!m,!*Y")
- (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,m,*Y,*Y,*m"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
+ (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
"TARGET_64BIT
+ && (TARGET_INTER_UNIT_MOVES || optimize_size)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
switch (get_attr_type (insn))
{
case TYPE_SSEMOV:
- if (register_operand (operands[0], DImode)
- && register_operand (operands[1], DImode))
+ if (get_attr_mode (insn) == MODE_TI)
return "movdqa\t{%1, %0|%0, %1}";
/* FALLTHRU */
case TYPE_MMXMOV:
+ /* Moves from and into integer register is done using movd opcode with
+ REX prefix. */
+ if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
+ return "movd\t{%1, %0|%0, %1}";
return "movq\t{%1, %0|%0, %1}";
case TYPE_MULTI:
return "#";
@@ -1899,9 +1974,9 @@
}
}
[(set (attr "type")
- (cond [(eq_attr "alternative" "5,6")
+ (cond [(eq_attr "alternative" "5,6,7")
(const_string "mmxmov")
- (eq_attr "alternative" "7,8,9")
+ (eq_attr "alternative" "8,9,10")
(const_string "ssemov")
(eq_attr "alternative" "4")
(const_string "multi")
@@ -1910,11 +1985,57 @@
(const_string "lea")
]
(const_string "imov")))
- (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*")
- (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*")
- (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI")])
+ (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
+ (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
+ (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
-;; Stores and loads of ax to arbitary constant address.
+(define_insn "*movdi_1_rex64_nointerunit"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
+ (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
+ "TARGET_64BIT
+ && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
+{
+ switch (get_attr_type (insn))
+ {
+ case TYPE_SSEMOV:
+ if (get_attr_mode (insn) == MODE_TI)
+ return "movdqa\t{%1, %0|%0, %1}";
+ /* FALLTHRU */
+ case TYPE_MMXMOV:
+ return "movq\t{%1, %0|%0, %1}";
+ case TYPE_MULTI:
+ return "#";
+ case TYPE_LEA:
+ return "lea{q}\t{%a1, %0|%0, %a1}";
+ default:
+ if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
+ abort ();
+ if (get_attr_mode (insn) == MODE_SI)
+ return "mov{l}\t{%k1, %k0|%k0, %k1}";
+ else if (which_alternative == 2)
+ return "movabs{q}\t{%1, %0|%0, %1}";
+ else
+ return "mov{q}\t{%1, %0|%0, %1}";
+ }
+}
+ [(set (attr "type")
+ (cond [(eq_attr "alternative" "5,6,7")
+ (const_string "mmxmov")
+ (eq_attr "alternative" "8,9,10")
+ (const_string "ssemov")
+ (eq_attr "alternative" "4")
+ (const_string "multi")
+ (and (ne (symbol_ref "flag_pic") (const_int 0))
+ (match_operand:DI 1 "symbolic_operand" ""))
+ (const_string "lea")
+ ]
+ (const_string "imov")))
+ (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
+ (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
+ (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
+
+;; Stores and loads of ax to arbitrary constant address.
;; We fake an second form of instruction to force reload to load address
;; into register when rax is not available
(define_insn "*movabsdi_1_rex64"
@@ -2007,22 +2128,11 @@
{
switch (which_alternative)
{
- case 0:
- /* %%% We loose REG_DEAD notes for controling pops if we split late. */
- operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
- operands[2] = stack_pointer_rtx;
- operands[3] = GEN_INT (4);
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- else
- return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
-
case 1:
return "push{l}\t%1";
- case 2:
- return "#";
default:
+ /* This insn should be already split before reg-stack. */
abort ();
}
}
@@ -2036,23 +2146,11 @@
{
switch (which_alternative)
{
- case 0:
- /* %%% We loose REG_DEAD notes for controling pops if we split late. */
- operands[0] = gen_rtx_MEM (SFmode, stack_pointer_rtx);
- operands[2] = stack_pointer_rtx;
- operands[3] = GEN_INT (8);
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- else
- return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
-
case 1:
return "push{q}\t%q1";
- case 2:
- return "#";
-
default:
+ /* This insn should be already split before reg-stack. */
abort ();
}
}
@@ -2089,7 +2187,8 @@
(define_insn "*movsf_1"
[(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
(match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
- "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
+ "(TARGET_INTER_UNIT_MOVES || optimize_size)
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& (reload_in_progress || reload_completed
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| GET_CODE (operands[1]) != CONST_DOUBLE
@@ -2113,25 +2212,117 @@
return "fst%z0\t%y0";
case 2:
- switch (standard_80387_constant_p (operands[1]))
- {
- case 1:
- return "fldz";
- case 2:
- return "fld1";
- }
+ return standard_80387_constant_opcode (operands[1]);
+
+ case 3:
+ case 4:
+ return "mov{l}\t{%1, %0|%0, %1}";
+ case 5:
+ if (get_attr_mode (insn) == MODE_TI)
+ return "pxor\t%0, %0";
+ else
+ return "xorps\t%0, %0";
+ case 6:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movss\t{%1, %0|%0, %1}";
+ case 7:
+ case 8:
+ return "movss\t{%1, %0|%0, %1}";
+
+ case 9:
+ case 10:
+ return "movd\t{%1, %0|%0, %1}";
+
+ case 11:
+ return "movq\t{%1, %0|%0, %1}";
+
+ default:
abort();
+ }
+}
+ [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "3,4,9,10")
+ (const_string "SI")
+ (eq_attr "alternative" "5")
+ (if_then_else
+ (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
+ (const_int 0))
+ (ne (symbol_ref "TARGET_SSE2")
+ (const_int 0)))
+ (eq (symbol_ref "optimize_size")
+ (const_int 0)))
+ (const_string "TI")
+ (const_string "V4SF"))
+ /* For architectures resolving dependencies on
+ whole SSE registers use APS move to break dependency
+ chains, otherwise use short move to avoid extra work.
+
+ Do the same for architectures resolving dependencies on
+ the parts. While in DF mode it is better to always handle
+ just register parts, the SF mode is different due to lack
+ of instructions to load just part of the register. It is
+ better to maintain the whole registers in single format
+ to avoid problems on using packed logical operations. */
+ (eq_attr "alternative" "6")
+ (if_then_else
+ (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
+ (const_int 0))
+ (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
+ (const_int 0)))
+ (const_string "V4SF")
+ (const_string "SF"))
+ (eq_attr "alternative" "11")
+ (const_string "DI")]
+ (const_string "SF")))])
+
+(define_insn "*movsf_1_nointerunit"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
+ (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
+ "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
+ && (reload_in_progress || reload_completed
+ || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
+ || GET_CODE (operands[1]) != CONST_DOUBLE
+ || memory_operand (operands[0], SFmode))"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (REG_P (operands[1])
+ && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ {
+ if (REGNO (operands[0]) == FIRST_STACK_REG
+ && TARGET_USE_FFREEP)
+ return "ffreep\t%y0";
+ return "fstp\t%y0";
+ }
+ else if (STACK_TOP_P (operands[0]))
+ return "fld%z1\t%y1";
+ else
+ return "fst\t%y0";
+
+ case 1:
+ if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return "fstp%z0\t%y0";
+ else
+ return "fst%z0\t%y0";
+
+ case 2:
+ return standard_80387_constant_opcode (operands[1]);
case 3:
case 4:
return "mov{l}\t{%1, %0|%0, %1}";
case 5:
- if (TARGET_SSE2 && !TARGET_ATHLON)
+ if (get_attr_mode (insn) == MODE_TI)
return "pxor\t%0, %0";
else
return "xorps\t%0, %0";
case 6:
- if (TARGET_PARTIAL_REG_DEPENDENCY)
+ if (get_attr_mode (insn) == MODE_V4SF)
return "movaps\t{%1, %0|%0, %1}";
else
return "movss\t{%1, %0|%0, %1}";
@@ -2151,7 +2342,40 @@
}
}
[(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
- (set_attr "mode" "SF,SF,SF,SI,SI,TI,SF,SF,SF,SI,SI,DI")])
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "3,4,9,10")
+ (const_string "SI")
+ (eq_attr "alternative" "5")
+ (if_then_else
+ (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
+ (const_int 0))
+ (ne (symbol_ref "TARGET_SSE2")
+ (const_int 0)))
+ (eq (symbol_ref "optimize_size")
+ (const_int 0)))
+ (const_string "TI")
+ (const_string "V4SF"))
+ /* For architectures resolving dependencies on
+ whole SSE registers use APS move to break dependency
+ chains, otherwise use short move to avoid extra work.
+
+ Do the same for architectures resolving dependencies on
+ the parts. While in DF mode it is better to always handle
+ just register parts, the SF mode is different due to lack
+ of instructions to load just part of the register. It is
+ better to maintain the whole registers in single format
+ to avoid problems on using packed logical operations. */
+ (eq_attr "alternative" "6")
+ (if_then_else
+ (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
+ (const_int 0))
+ (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
+ (const_int 0)))
+ (const_string "V4SF")
+ (const_string "SF"))
+ (eq_attr "alternative" "11")
+ (const_string "DI")]
+ (const_string "SF")))])
(define_insn "*swapsf"
[(set (match_operand:SF 0 "register_operand" "+f")
@@ -2175,7 +2399,7 @@
"ix86_expand_move (DFmode, operands); DONE;")
;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
-;; Size of pushdf using integer insturctions is 2+2*memory operand size
+;; Size of pushdf using integer instructions is 2+2*memory operand size
;; On the average, pushdf using integers can be still shorter. Allow this
;; pattern for optimize_size too.
@@ -2184,26 +2408,8 @@
(match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
"!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
{
- switch (which_alternative)
- {
- case 0:
- /* %%% We loose REG_DEAD notes for controling pops if we split late. */
- operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
- operands[2] = stack_pointer_rtx;
- operands[3] = GEN_INT (8);
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- else
- return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
-
- case 1:
- case 2:
- case 3:
- return "#";
-
- default:
- abort ();
- }
+ /* This insn should be already split before reg-stack. */
+ abort ();
}
[(set_attr "type" "multi")
(set_attr "mode" "DF,SI,SI,DF")])
@@ -2213,32 +2419,8 @@
(match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
"TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
{
- switch (which_alternative)
- {
- case 0:
- /* %%% We loose REG_DEAD notes for controling pops if we split late. */
- operands[0] = gen_rtx_MEM (DFmode, stack_pointer_rtx);
- operands[2] = stack_pointer_rtx;
- operands[3] = GEN_INT (8);
- if (TARGET_64BIT)
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- else
- return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
- else
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- else
- return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
-
-
- case 1:
- case 2:
- return "#";
-
- default:
- abort ();
- }
+ /* This insn should be already split before reg-stack. */
+ abort ();
}
[(set_attr "type" "multi")
(set_attr "mode" "DF,SI,DF")])
@@ -2275,7 +2457,7 @@
[(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
(match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
- && (optimize_size || !TARGET_INTEGER_DFMODE_MOVES)
+ && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
&& (reload_in_progress || reload_completed
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| GET_CODE (operands[1]) != CONST_DOUBLE
@@ -2286,7 +2468,12 @@
case 0:
if (REG_P (operands[1])
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp\t%y0";
+ {
+ if (REGNO (operands[0]) == FIRST_STACK_REG
+ && TARGET_USE_FFREEP)
+ return "ffreep\t%y0";
+ return "fstp\t%y0";
+ }
else if (STACK_TOP_P (operands[0]))
return "fld%z1\t%y1";
else
@@ -2299,44 +2486,90 @@
return "fst%z0\t%y0";
case 2:
- switch (standard_80387_constant_p (operands[1]))
- {
- case 1:
- return "fldz";
- case 2:
- return "fld1";
- }
- abort();
+ return standard_80387_constant_opcode (operands[1]);
case 3:
case 4:
return "#";
case 5:
- if (TARGET_ATHLON)
- return "xorpd\t%0, %0";
- else
- return "pxor\t%0, %0";
+ switch (get_attr_mode (insn))
+ {
+ case MODE_V4SF:
+ return "xorps\t%0, %0";
+ case MODE_V2DF:
+ return "xorpd\t%0, %0";
+ case MODE_TI:
+ return "pxor\t%0, %0";
+ default:
+ abort ();
+ }
case 6:
- if (TARGET_PARTIAL_REG_DEPENDENCY)
- return "movapd\t{%1, %0|%0, %1}";
+ switch (get_attr_mode (insn))
+ {
+ case MODE_V4SF:
+ return "movaps\t{%1, %0|%0, %1}";
+ case MODE_V2DF:
+ return "movapd\t{%1, %0|%0, %1}";
+ case MODE_DF:
+ return "movsd\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
+ case 7:
+ if (get_attr_mode (insn) == MODE_V2DF)
+ return "movlpd\t{%1, %0|%0, %1}";
else
return "movsd\t{%1, %0|%0, %1}";
- case 7:
case 8:
- return "movsd\t{%1, %0|%0, %1}";
+ return "movsd\t{%1, %0|%0, %1}";
default:
abort();
}
}
[(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
- (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "3,4")
+ (const_string "SI")
+ /* xorps is one byte shorter. */
+ (eq_attr "alternative" "5")
+ (cond [(ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
+ (const_int 0))
+ (const_string "TI")]
+ (const_string "V2DF"))
+ /* For architectures resolving dependencies on
+ whole SSE registers use APD move to break dependency
+ chains, otherwise use short move to avoid extra work.
+
+ movaps encodes one byte shorter. */
+ (eq_attr "alternative" "6")
+ (cond
+ [(ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
+ (const_int 0))
+ (const_string "V2DF")]
+ (const_string "DF"))
+ /* For architectures resolving dependencies on register
+ parts we may avoid extra work to zero out upper part
+ of register. */
+ (eq_attr "alternative" "7")
+ (if_then_else
+ (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
+ (const_int 0))
+ (const_string "V2DF")
+ (const_string "DF"))]
+ (const_string "DF")))])
(define_insn "*movdf_integer"
[(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
(match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
"(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
- && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
+ && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
&& (reload_in_progress || reload_completed
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| GET_CODE (operands[1]) != CONST_DOUBLE
@@ -2347,7 +2580,12 @@
case 0:
if (REG_P (operands[1])
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp\t%y0";
+ {
+ if (REGNO (operands[0]) == FIRST_STACK_REG
+ && TARGET_USE_FFREEP)
+ return "ffreep\t%y0";
+ return "fstp\t%y0";
+ }
else if (STACK_TOP_P (operands[0]))
return "fld%z1\t%y1";
else
@@ -2360,30 +2598,41 @@
return "fst%z0\t%y0";
case 2:
- switch (standard_80387_constant_p (operands[1]))
- {
- case 1:
- return "fldz";
- case 2:
- return "fld1";
- }
- abort();
+ return standard_80387_constant_opcode (operands[1]);
case 3:
case 4:
return "#";
case 5:
- if (TARGET_ATHLON)
- return "xorpd\t%0, %0";
- else
- return "pxor\t%0, %0";
+ switch (get_attr_mode (insn))
+ {
+ case MODE_V4SF:
+ return "xorps\t%0, %0";
+ case MODE_V2DF:
+ return "xorpd\t%0, %0";
+ case MODE_TI:
+ return "pxor\t%0, %0";
+ default:
+ abort ();
+ }
case 6:
- if (TARGET_PARTIAL_REG_DEPENDENCY)
- return "movapd\t{%1, %0|%0, %1}";
+ switch (get_attr_mode (insn))
+ {
+ case MODE_V4SF:
+ return "movaps\t{%1, %0|%0, %1}";
+ case MODE_V2DF:
+ return "movapd\t{%1, %0|%0, %1}";
+ case MODE_DF:
+ return "movsd\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
+ case 7:
+ if (get_attr_mode (insn) == MODE_V2DF)
+ return "movlpd\t{%1, %0|%0, %1}";
else
return "movsd\t{%1, %0|%0, %1}";
- case 7:
case 8:
return "movsd\t{%1, %0|%0, %1}";
@@ -2392,7 +2641,42 @@
}
}
[(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
- (set_attr "mode" "DF,DF,DF,SI,SI,TI,DF,DF,DF")])
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "3,4")
+ (const_string "SI")
+ /* xorps is one byte shorter. */
+ (eq_attr "alternative" "5")
+ (cond [(ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
+ (const_int 0))
+ (const_string "TI")]
+ (const_string "V2DF"))
+ /* For architectures resolving dependencies on
+ whole SSE registers use APD move to break dependency
+ chains, otherwise use short move to avoid extra work.
+
+ movaps encodes one byte shorter. */
+ (eq_attr "alternative" "6")
+ (cond
+ [(ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
+ (const_int 0))
+ (const_string "V2DF")]
+ (const_string "DF"))
+ /* For architectures resolving dependencies on register
+ parts we may avoid extra work to zero out upper part
+ of register. */
+ (eq_attr "alternative" "7")
+ (if_then_else
+ (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
+ (const_int 0))
+ (const_string "V2DF")
+ (const_string "DF"))]
+ (const_string "DF")))])
(define_split
[(set (match_operand:DF 0 "nonimmediate_operand" "")
@@ -2426,17 +2710,11 @@
(define_expand "movxf"
[(set (match_operand:XF 0 "nonimmediate_operand" "")
(match_operand:XF 1 "general_operand" ""))]
- "!TARGET_64BIT"
- "ix86_expand_move (XFmode, operands); DONE;")
-
-(define_expand "movtf"
- [(set (match_operand:TF 0 "nonimmediate_operand" "")
- (match_operand:TF 1 "general_operand" ""))]
""
- "ix86_expand_move (TFmode, operands); DONE;")
+ "ix86_expand_move (XFmode, operands); DONE;")
;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
-;; Size of pushdf using integer insturctions is 3+3*memory operand size
+;; Size of pushdf using integer instructions is 3+3*memory operand size
;; Pushing using integer instructions is longer except for constants
;; and direct memory references.
;; (assuming that any given constant is pushed only once, but this ought to be
@@ -2445,55 +2723,10 @@
(define_insn "*pushxf_nointeger"
[(set (match_operand:XF 0 "push_operand" "=X,X,X")
(match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
- "!TARGET_64BIT && optimize_size"
-{
- switch (which_alternative)
- {
- case 0:
- /* %%% We loose REG_DEAD notes for controling pops if we split late. */
- operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
- operands[2] = stack_pointer_rtx;
- operands[3] = GEN_INT (12);
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- else
- return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
-
- case 1:
- case 2:
- return "#";
-
- default:
- abort ();
- }
-}
- [(set_attr "type" "multi")
- (set_attr "mode" "XF,SI,SI")])
-
-(define_insn "*pushtf_nointeger"
- [(set (match_operand:TF 0 "push_operand" "=<,<,<")
- (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
"optimize_size"
{
- switch (which_alternative)
- {
- case 0:
- /* %%% We loose REG_DEAD notes for controling pops if we split late. */
- operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
- operands[2] = stack_pointer_rtx;
- operands[3] = GEN_INT (16);
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- else
- return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
-
- case 1:
- case 2:
- return "#";
-
- default:
- abort ();
- }
+ /* This insn should be already split before reg-stack. */
+ abort ();
}
[(set_attr "type" "multi")
(set_attr "mode" "XF,SI,SI")])
@@ -2501,59 +2734,10 @@
(define_insn "*pushxf_integer"
[(set (match_operand:XF 0 "push_operand" "=<,<")
(match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
- "!TARGET_64BIT && !optimize_size"
-{
- switch (which_alternative)
- {
- case 0:
- /* %%% We loose REG_DEAD notes for controling pops if we split late. */
- operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
- operands[2] = stack_pointer_rtx;
- operands[3] = GEN_INT (12);
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- else
- return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
-
- case 1:
- return "#";
-
- default:
- abort ();
- }
-}
- [(set_attr "type" "multi")
- (set_attr "mode" "XF,SI")])
-
-(define_insn "*pushtf_integer"
- [(set (match_operand:TF 0 "push_operand" "=<,<")
- (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
"!optimize_size"
{
- switch (which_alternative)
- {
- case 0:
- /* %%% We loose REG_DEAD notes for controling pops if we split late. */
- operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
- operands[2] = stack_pointer_rtx;
- operands[3] = GEN_INT (16);
- if (TARGET_64BIT)
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "sub{q}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- else
- return "sub{q}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
- else
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "sub{l}\t{%3, %2|%2, %3}\;fstp%z0\t%y0";
- else
- return "sub{l}\t{%3, %2|%2, %3}\;fst%z0\t%y0";
-
- case 1:
- return "#";
-
- default:
- abort ();
- }
+ /* This insn should be already split before reg-stack. */
+ abort ();
}
[(set_attr "type" "multi")
(set_attr "mode" "XF,SI")])
@@ -2563,7 +2747,6 @@
(match_operand 1 "general_operand" ""))]
"reload_completed
&& (GET_MODE (operands[0]) == XFmode
- || GET_MODE (operands[0]) == TFmode
|| GET_MODE (operands[0]) == DFmode)
&& !ANY_FP_REG_P (operands[1])"
[(const_int 0)]
@@ -2573,29 +2756,23 @@
[(set (match_operand:XF 0 "push_operand" "")
(match_operand:XF 1 "any_fp_register_operand" ""))]
"!TARGET_64BIT"
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
- (set (mem:XF (reg:SI 7)) (match_dup 1))])
-
-(define_split
- [(set (match_operand:TF 0 "push_operand" "")
- (match_operand:TF 1 "any_fp_register_operand" ""))]
- "!TARGET_64BIT"
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
- (set (mem:TF (reg:SI 7)) (match_dup 1))])
+ [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
+ (set (mem:XF (reg:SI 7)) (match_dup 1))]
+ "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
(define_split
- [(set (match_operand:TF 0 "push_operand" "")
- (match_operand:TF 1 "any_fp_register_operand" ""))]
+ [(set (match_operand:XF 0 "push_operand" "")
+ (match_operand:XF 1 "any_fp_register_operand" ""))]
"TARGET_64BIT"
- [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
- (set (mem:TF (reg:DI 7)) (match_dup 1))])
+ [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
+ (set (mem:XF (reg:DI 7)) (match_dup 1))]
+ "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
;; Do not use integer registers when optimizing for size
(define_insn "*movxf_nointeger"
[(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
(match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
- "!TARGET_64BIT
- && optimize_size
+ "optimize_size
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& (reload_in_progress || reload_completed
|| GET_CODE (operands[1]) != CONST_DOUBLE
@@ -2606,54 +2783,12 @@
case 0:
if (REG_P (operands[1])
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp\t%y0";
- else if (STACK_TOP_P (operands[0]))
- return "fld%z1\t%y1";
- else
- return "fst\t%y0";
-
- case 1:
- /* There is no non-popping store to memory for XFmode. So if
- we need one, follow the store with a load. */
- if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp%z0\t%y0\;fld%z0\t%y0";
- else
- return "fstp%z0\t%y0";
-
- case 2:
- switch (standard_80387_constant_p (operands[1]))
- {
- case 1:
- return "fldz";
- case 2:
- return "fld1";
+ {
+ if (REGNO (operands[0]) == FIRST_STACK_REG
+ && TARGET_USE_FFREEP)
+ return "ffreep\t%y0";
+ return "fstp\t%y0";
}
- break;
-
- case 3: case 4:
- return "#";
- }
- abort();
-}
- [(set_attr "type" "fmov,fmov,fmov,multi,multi")
- (set_attr "mode" "XF,XF,XF,SI,SI")])
-
-(define_insn "*movtf_nointeger"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
- (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
- "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
- && optimize_size
- && (reload_in_progress || reload_completed
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || memory_operand (operands[0], TFmode))"
-{
- switch (which_alternative)
- {
- case 0:
- if (REG_P (operands[1])
- && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp\t%y0";
else if (STACK_TOP_P (operands[0]))
return "fld%z1\t%y1";
else
@@ -2668,14 +2803,7 @@
return "fstp%z0\t%y0";
case 2:
- switch (standard_80387_constant_p (operands[1]))
- {
- case 1:
- return "fldz";
- case 2:
- return "fld1";
- }
- break;
+ return standard_80387_constant_opcode (operands[1]);
case 3: case 4:
return "#";
@@ -2688,8 +2816,7 @@
(define_insn "*movxf_integer"
[(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
- "!TARGET_64BIT
- && !optimize_size
+ "!optimize_size
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
&& (reload_in_progress || reload_completed
|| GET_CODE (operands[1]) != CONST_DOUBLE
@@ -2700,54 +2827,12 @@
case 0:
if (REG_P (operands[1])
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp\t%y0";
- else if (STACK_TOP_P (operands[0]))
- return "fld%z1\t%y1";
- else
- return "fst\t%y0";
-
- case 1:
- /* There is no non-popping store to memory for XFmode. So if
- we need one, follow the store with a load. */
- if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp%z0\t%y0\;fld%z0\t%y0";
- else
- return "fstp%z0\t%y0";
-
- case 2:
- switch (standard_80387_constant_p (operands[1]))
- {
- case 1:
- return "fldz";
- case 2:
- return "fld1";
+ {
+ if (REGNO (operands[0]) == FIRST_STACK_REG
+ && TARGET_USE_FFREEP)
+ return "ffreep\t%y0";
+ return "fstp\t%y0";
}
- break;
-
- case 3: case 4:
- return "#";
- }
- abort();
-}
- [(set_attr "type" "fmov,fmov,fmov,multi,multi")
- (set_attr "mode" "XF,XF,XF,SI,SI")])
-
-(define_insn "*movtf_integer"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
- (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
- "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
- && !optimize_size
- && (reload_in_progress || reload_completed
- || GET_CODE (operands[1]) != CONST_DOUBLE
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
- || memory_operand (operands[0], TFmode))"
-{
- switch (which_alternative)
- {
- case 0:
- if (REG_P (operands[1])
- && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp\t%y0";
else if (STACK_TOP_P (operands[0]))
return "fld%z1\t%y1";
else
@@ -2762,14 +2847,7 @@
return "fstp%z0\t%y0";
case 2:
- switch (standard_80387_constant_p (operands[1]))
- {
- case 1:
- return "fldz";
- case 2:
- return "fld1";
- }
- break;
+ return standard_80387_constant_opcode (operands[1]);
case 3: case 4:
return "#";
@@ -2784,7 +2862,7 @@
(match_operand 1 "general_operand" ""))]
"reload_completed
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
- && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
+ && GET_MODE (operands[0]) == XFmode
&& ! (ANY_FP_REG_P (operands[0]) ||
(GET_CODE (operands[0]) == SUBREG
&& ANY_FP_REG_P (SUBREG_REG (operands[0]))))
@@ -2799,21 +2877,33 @@
(match_operand 1 "memory_operand" ""))]
"reload_completed
&& GET_CODE (operands[1]) == MEM
- && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
+ && (GET_MODE (operands[0]) == XFmode
|| GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
- && (!(SSE_REG_P (operands[0]) ||
- (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))
- || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
- && (!(FP_REG_P (operands[0]) ||
- (GET_CODE (operands[0]) == SUBREG
- && FP_REG_P (SUBREG_REG (operands[0]))))
- || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
- [(set (match_dup 0)
- (match_dup 1))]
- "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
+ && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
+ [(set (match_dup 0) (match_dup 1))]
+{
+ rtx c = get_pool_constant (XEXP (operands[1], 0));
+ rtx r = operands[0];
+
+ if (GET_CODE (r) == SUBREG)
+ r = SUBREG_REG (r);
+
+ if (SSE_REG_P (r))
+ {
+ if (!standard_sse_constant_p (c))
+ FAIL;
+ }
+ else if (FP_REG_P (r))
+ {
+ if (!standard_80387_constant_p (c))
+ FAIL;
+ }
+ else if (MMX_REG_P (r))
+ FAIL;
+
+ operands[1] = c;
+})
(define_insn "swapxf"
[(set (match_operand:XF 0 "register_operand" "+f")
@@ -2829,21 +2919,6 @@
}
[(set_attr "type" "fxch")
(set_attr "mode" "XF")])
-
-(define_insn "swaptf"
- [(set (match_operand:TF 0 "register_operand" "+f")
- (match_operand:TF 1 "register_operand" "+f"))
- (set (match_dup 1)
- (match_dup 0))]
- ""
-{
- if (STACK_TOP_P (operands[0]))
- return "fxch\t%1";
- else
- return "fxch\t%0";
-}
- [(set_attr "type" "fxch")
- (set_attr "mode" "XF")])
;; Zero extension instructions
@@ -3040,22 +3115,56 @@
")
(define_insn "zero_extendsidi2_32"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
- (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
(clobber (reg:CC 17))]
- "!TARGET_64BIT"
- "#"
- [(set_attr "mode" "SI")])
+ "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
+ "@
+ #
+ #
+ #
+ movd\t{%1, %0|%0, %1}
+ movd\t{%1, %0|%0, %1}"
+ [(set_attr "mode" "SI,SI,SI,DI,TI")
+ (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
+
+(define_insn "*zero_extendsidi2_32_1"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
+ (clobber (reg:CC 17))]
+ "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
+ "@
+ #
+ #
+ #
+ movd\t{%1, %0|%0, %1}
+ movd\t{%1, %0|%0, %1}"
+ [(set_attr "mode" "SI,SI,SI,DI,TI")
+ (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
(define_insn "zero_extendsidi2_rex64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
- (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
- "TARGET_64BIT"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
+ "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
"@
mov\t{%k1, %k0|%k0, %k1}
- #"
- [(set_attr "type" "imovx,imov")
- (set_attr "mode" "SI,DI")])
+ #
+ movd\t{%1, %0|%0, %1}
+ movd\t{%1, %0|%0, %1}"
+ [(set_attr "type" "imovx,imov,mmxmov,ssemov")
+ (set_attr "mode" "SI,DI,DI,TI")])
+
+(define_insn "*zero_extendsidi2_rex64_1"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
+ "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
+ "@
+ mov\t{%k1, %k0|%k0, %k1}
+ #
+ movd\t{%1, %0|%0, %1}
+ movd\t{%1, %0|%0, %1}"
+ [(set_attr "type" "imovx,imov,mmxmov,ssemov")
+ (set_attr "mode" "SI,DI,SI,SI")])
(define_split
[(set (match_operand:DI 0 "memory_operand" "")
@@ -3077,7 +3186,8 @@
[(set (match_operand:DI 0 "nonimmediate_operand" "")
(zero_extend:DI (match_operand:SI 1 "general_operand" "")))
(clobber (reg:CC 17))]
- "!TARGET_64BIT && reload_completed"
+ "!TARGET_64BIT && reload_completed
+ && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
[(set (match_dup 3) (match_dup 1))
(set (match_dup 4) (const_int 0))]
"split_di (&operands[0], 1, &operands[3], &operands[4]);")
@@ -3359,62 +3469,34 @@
(define_split
[(set (match_operand:XF 0 "push_operand" "")
(float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
- "!TARGET_64BIT"
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
- (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
-
-(define_insn "*dummy_extendsftf2"
- [(set (match_operand:TF 0 "push_operand" "=<")
- (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
- "0"
- "#")
-
-(define_split
- [(set (match_operand:TF 0 "push_operand" "")
- (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
- "!TARGET_64BIT"
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
- (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
+ ""
+ [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
+ (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
+ "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
(define_split
- [(set (match_operand:TF 0 "push_operand" "")
- (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
+ [(set (match_operand:XF 0 "push_operand" "")
+ (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
"TARGET_64BIT"
- [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
- (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
-
-(define_insn "*dummy_extenddfxf2"
- [(set (match_operand:XF 0 "push_operand" "=<")
- (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
- "0"
- "#")
+ [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
+ (set (mem:DF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
+ "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
(define_split
[(set (match_operand:XF 0 "push_operand" "")
(float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
- "!TARGET_64BIT"
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
- (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
-
-(define_insn "*dummy_extenddftf2"
- [(set (match_operand:TF 0 "push_operand" "=<")
- (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
- "0"
- "#")
-
-(define_split
- [(set (match_operand:TF 0 "push_operand" "")
- (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
- "!TARGET_64BIT"
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
- (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
+ ""
+ [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 2)))
+ (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))]
+ "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
(define_split
- [(set (match_operand:TF 0 "push_operand" "")
- (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
+ [(set (match_operand:XF 0 "push_operand" "")
+ (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
"TARGET_64BIT"
- [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
- (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
+ [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 2)))
+ (set (mem:XF (reg:DI 7)) (float_extend:XF (match_dup 1)))]
+ "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "nonimmediate_operand" "")
@@ -3474,7 +3556,7 @@
(define_expand "extendsfxf2"
[(set (match_operand:XF 0 "nonimmediate_operand" "")
(float_extend:XF (match_operand:SF 1 "general_operand" "")))]
- "!TARGET_64BIT && TARGET_80387"
+ "TARGET_80387"
{
/* ??? Needed for compress_float_constant since all fp constants
are LEGITIMATE_CONSTANT_P. */
@@ -3487,51 +3569,6 @@
(define_insn "*extendsfxf2_1"
[(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
- "!TARGET_64BIT && TARGET_80387
- && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
-{
- switch (which_alternative)
- {
- case 0:
- if (REG_P (operands[1])
- && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp\t%y0";
- else if (STACK_TOP_P (operands[0]))
- return "fld%z1\t%y1";
- else
- return "fst\t%y0";
-
- case 1:
- /* There is no non-popping store to memory for XFmode. So if
- we need one, follow the store with a load. */
- if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp%z0\t%y0\n\tfld%z0\t%y0";
- else
- return "fstp%z0\t%y0";
-
- default:
- abort ();
- }
-}
- [(set_attr "type" "fmov")
- (set_attr "mode" "SF,XF")])
-
-(define_expand "extendsftf2"
- [(set (match_operand:TF 0 "nonimmediate_operand" "")
- (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
- "TARGET_80387"
-{
- /* ??? Needed for compress_float_constant since all fp constants
- are LEGITIMATE_CONSTANT_P. */
- if (GET_CODE (operands[1]) == CONST_DOUBLE)
- operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
- if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
- operands[1] = force_reg (SFmode, operands[1]);
-})
-
-(define_insn "*extendsftf2_1"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
- (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
"TARGET_80387
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
@@ -3564,7 +3601,7 @@
(define_expand "extenddfxf2"
[(set (match_operand:XF 0 "nonimmediate_operand" "")
(float_extend:XF (match_operand:DF 1 "general_operand" "")))]
- "!TARGET_64BIT && TARGET_80387"
+ "TARGET_80387"
{
/* ??? Needed for compress_float_constant since all fp constants
are LEGITIMATE_CONSTANT_P. */
@@ -3577,51 +3614,6 @@
(define_insn "*extenddfxf2_1"
[(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
- "!TARGET_64BIT && TARGET_80387
- && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
-{
- switch (which_alternative)
- {
- case 0:
- if (REG_P (operands[1])
- && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp\t%y0";
- else if (STACK_TOP_P (operands[0]))
- return "fld%z1\t%y1";
- else
- return "fst\t%y0";
-
- case 1:
- /* There is no non-popping store to memory for XFmode. So if
- we need one, follow the store with a load. */
- if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp%z0\t%y0\n\tfld%z0\t%y0";
- else
- return "fstp%z0\t%y0";
-
- default:
- abort ();
- }
-}
- [(set_attr "type" "fmov")
- (set_attr "mode" "DF,XF")])
-
-(define_expand "extenddftf2"
- [(set (match_operand:TF 0 "nonimmediate_operand" "")
- (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
- "TARGET_80387"
-{
- /* ??? Needed for compress_float_constant since all fp constants
- are LEGITIMATE_CONSTANT_P. */
- if (GET_CODE (operands[1]) == CONST_DOUBLE)
- operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
- if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
- operands[1] = force_reg (DFmode, operands[1]);
-})
-
-(define_insn "*extenddftf2_1"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
- (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
"TARGET_80387
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
@@ -3695,11 +3687,11 @@
(set_attr "mode" "SF,SF,SF,SF")])
(define_insn "*truncdfsf2_1_sse"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
(float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
+ (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
(clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
- "TARGET_80387 && TARGET_SSE2"
+ "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
{
switch (which_alternative)
{
@@ -3709,7 +3701,30 @@
else
return "fst%z0\t%y0";
case 4:
- return "cvtsd2ss\t{%1, %0|%0, %1}";
+ return "#";
+ default:
+ abort ();
+ }
+}
+ [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
+ (set_attr "mode" "SF,SF,SF,SF,DF")])
+
+(define_insn "*truncdfsf2_1_sse_nooverlap"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
+ (float_truncate:SF
+ (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
+ (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
+ "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return "fstp%z0\t%y0";
+ else
+ return "fst%z0\t%y0";
+ case 4:
+ return "#";
default:
abort ();
}
@@ -3718,16 +3733,41 @@
(set_attr "mode" "SF,SF,SF,SF,DF")])
(define_insn "*truncdfsf2_2"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
(float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
- "TARGET_80387 && TARGET_SSE2
+ (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
+ "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
switch (which_alternative)
{
case 0:
+ case 1:
return "cvtsd2ss\t{%1, %0|%0, %1}";
+ case 2:
+ if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return "fstp%z0\t%y0";
+ else
+ return "fst%z0\t%y0";
+ default:
+ abort ();
+ }
+}
+ [(set_attr "type" "ssecvt,ssecvt,fmov")
+ (set_attr "athlon_decode" "vector,double,*")
+ (set_attr "mode" "SF,SF,SF")])
+
+(define_insn "*truncdfsf2_2_nooverlap"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
+ (float_truncate:SF
+ (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
+ "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "#";
case 1:
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
return "fstp%z0\t%y0";
@@ -3740,7 +3780,7 @@
[(set_attr "type" "ssecvt,fmov")
(set_attr "mode" "DF,SF")])
-(define_insn "truncdfsf2_3"
+(define_insn "*truncdfsf2_3"
[(set (match_operand:SF 0 "memory_operand" "=m")
(float_truncate:SF
(match_operand:DF 1 "register_operand" "f")))]
@@ -3755,12 +3795,22 @@
(set_attr "mode" "SF")])
(define_insn "truncdfsf2_sse_only"
- [(set (match_operand:SF 0 "register_operand" "=Y")
+ [(set (match_operand:SF 0 "register_operand" "=Y,Y")
(float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "mY")))]
- "!TARGET_80387 && TARGET_SSE2"
+ (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
+ "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
"cvtsd2ss\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecvt")
+ (set_attr "athlon_decode" "vector,double")
+ (set_attr "mode" "SF")])
+
+(define_insn "*truncdfsf2_sse_only_nooverlap"
+ [(set (match_operand:SF 0 "register_operand" "=&Y")
+ (float_truncate:SF
+ (match_operand:DF 1 "nonimmediate_operand" "mY")))]
+ "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
+ "#"
+ [(set_attr "type" "ssecvt")
(set_attr "mode" "DF")])
(define_split
@@ -3772,100 +3822,79 @@
[(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
"")
+; Avoid possible reformatting penalty on the destination by first
+; zeroing it out
(define_split
- [(set (match_operand:SF 0 "nonimmediate_operand" "")
+ [(set (match_operand:SF 0 "register_operand" "")
(float_truncate:SF
(match_operand:DF 1 "nonimmediate_operand" "")))
(clobber (match_operand 2 "" ""))]
"TARGET_80387 && reload_completed
- && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
- [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
- "")
-
-(define_split
- [(set (match_operand:SF 0 "register_operand" "")
- (float_truncate:SF
- (match_operand:DF 1 "fp_register_operand" "")))
- (clobber (match_operand:SF 2 "memory_operand" ""))]
- "TARGET_80387 && reload_completed"
- [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
- (set (match_dup 0) (match_dup 2))]
- "")
-
-(define_expand "truncxfsf2"
- [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
- (float_truncate:SF
- (match_operand:XF 1 "register_operand" "")))
- (clobber (match_dup 2))])]
- "!TARGET_64BIT && TARGET_80387"
- "operands[2] = assign_386_stack_local (SFmode, 0);")
-
-(define_insn "*truncxfsf2_1"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
- (float_truncate:SF
- (match_operand:XF 1 "register_operand" "f,f,f,f")))
- (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
- "!TARGET_64BIT && TARGET_80387"
+ && SSE_REG_P (operands[0])
+ && !STACK_REG_P (operands[1])"
+ [(const_int 0)]
{
- switch (which_alternative)
+ rtx src, dest;
+ if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
+ emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
+ else
{
- case 0:
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp%z0\t%y0";
- else
- return "fst%z0\t%y0";
- default:
- abort();
+ dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
+ src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
+ /* simplify_gen_subreg refuses to widen memory references. */
+ if (GET_CODE (src) == SUBREG)
+ alter_subreg (&src);
+ if (reg_overlap_mentioned_p (operands[0], operands[1]))
+ abort ();
+ emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
+ emit_insn (gen_cvtsd2ss (dest, dest, src));
}
-}
- [(set_attr "type" "fmov,multi,multi,multi")
- (set_attr "mode" "SF")])
-
-(define_insn "*truncxfsf2_2"
- [(set (match_operand:SF 0 "memory_operand" "=m")
- (float_truncate:SF
- (match_operand:XF 1 "register_operand" "f")))]
- "!TARGET_64BIT && TARGET_80387"
-{
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp%z0\t%y0";
- else
- return "fst%z0\t%y0";
-}
- [(set_attr "type" "fmov")
- (set_attr "mode" "SF")])
+ DONE;
+})
(define_split
- [(set (match_operand:SF 0 "memory_operand" "")
+ [(set (match_operand:SF 0 "register_operand" "")
(float_truncate:SF
- (match_operand:XF 1 "register_operand" "")))
- (clobber (match_operand:SF 2 "memory_operand" ""))]
- "TARGET_80387"
- [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
- "")
+ (match_operand:DF 1 "nonimmediate_operand" "")))]
+ "TARGET_80387 && reload_completed
+ && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
+ [(const_int 0)]
+{
+ rtx src, dest;
+ dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
+ src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
+ /* simplify_gen_subreg refuses to widen memory references. */
+ if (GET_CODE (src) == SUBREG)
+ alter_subreg (&src);
+ if (reg_overlap_mentioned_p (operands[0], operands[1]))
+ abort ();
+ emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
+ emit_insn (gen_cvtsd2ss (dest, dest, src));
+ DONE;
+})
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(float_truncate:SF
- (match_operand:XF 1 "register_operand" "")))
+ (match_operand:DF 1 "fp_register_operand" "")))
(clobber (match_operand:SF 2 "memory_operand" ""))]
"TARGET_80387 && reload_completed"
[(set (match_dup 2) (float_truncate:SF (match_dup 1)))
(set (match_dup 0) (match_dup 2))]
"")
-(define_expand "trunctfsf2"
+(define_expand "truncxfsf2"
[(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
(float_truncate:SF
- (match_operand:TF 1 "register_operand" "")))
+ (match_operand:XF 1 "register_operand" "")))
(clobber (match_dup 2))])]
"TARGET_80387"
"operands[2] = assign_386_stack_local (SFmode, 0);")
-(define_insn "*trunctfsf2_1"
+(define_insn "*truncxfsf2_1"
[(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
(float_truncate:SF
- (match_operand:TF 1 "register_operand" "f,f,f,f")))
+ (match_operand:XF 1 "register_operand" "f,f,f,f")))
(clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
"TARGET_80387"
{
@@ -3883,10 +3912,10 @@
[(set_attr "type" "fmov,multi,multi,multi")
(set_attr "mode" "SF")])
-(define_insn "*trunctfsf2_2"
+(define_insn "*truncxfsf2_2"
[(set (match_operand:SF 0 "memory_operand" "=m")
(float_truncate:SF
- (match_operand:TF 1 "register_operand" "f")))]
+ (match_operand:XF 1 "register_operand" "f")))]
"TARGET_80387"
{
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
@@ -3900,7 +3929,7 @@
(define_split
[(set (match_operand:SF 0 "memory_operand" "")
(float_truncate:SF
- (match_operand:TF 1 "register_operand" "")))
+ (match_operand:XF 1 "register_operand" "")))
(clobber (match_operand:SF 2 "memory_operand" ""))]
"TARGET_80387"
[(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
@@ -3909,20 +3938,19 @@
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(float_truncate:SF
- (match_operand:TF 1 "register_operand" "")))
+ (match_operand:XF 1 "register_operand" "")))
(clobber (match_operand:SF 2 "memory_operand" ""))]
"TARGET_80387 && reload_completed"
[(set (match_dup 2) (float_truncate:SF (match_dup 1)))
(set (match_dup 0) (match_dup 2))]
"")
-
(define_expand "truncxfdf2"
[(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
(float_truncate:DF
(match_operand:XF 1 "register_operand" "")))
(clobber (match_dup 2))])]
- "!TARGET_64BIT && TARGET_80387"
+ "TARGET_80387"
"operands[2] = assign_386_stack_local (DFmode, 0);")
(define_insn "*truncxfdf2_1"
@@ -3930,7 +3958,7 @@
(float_truncate:DF
(match_operand:XF 1 "register_operand" "f,f,f,f")))
(clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
- "!TARGET_64BIT && TARGET_80387"
+ "TARGET_80387"
{
switch (which_alternative)
{
@@ -3951,7 +3979,7 @@
[(set (match_operand:DF 0 "memory_operand" "=m")
(float_truncate:DF
(match_operand:XF 1 "register_operand" "f")))]
- "!TARGET_64BIT && TARGET_80387"
+ "TARGET_80387"
{
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
return "fstp%z0\t%y0";
@@ -3980,69 +4008,6 @@
(set (match_dup 0) (match_dup 2))]
"")
-(define_expand "trunctfdf2"
- [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
- (float_truncate:DF
- (match_operand:TF 1 "register_operand" "")))
- (clobber (match_dup 2))])]
- "TARGET_80387"
- "operands[2] = assign_386_stack_local (DFmode, 0);")
-
-(define_insn "*trunctfdf2_1"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
- (float_truncate:DF
- (match_operand:TF 1 "register_operand" "f,f,f,f")))
- (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
- "TARGET_80387"
-{
- switch (which_alternative)
- {
- case 0:
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp%z0\t%y0";
- else
- return "fst%z0\t%y0";
- default:
- abort();
- }
- abort ();
-}
- [(set_attr "type" "fmov,multi,multi,multi")
- (set_attr "mode" "DF")])
-
- (define_insn "*trunctfdf2_2"
- [(set (match_operand:DF 0 "memory_operand" "=m")
- (float_truncate:DF
- (match_operand:TF 1 "register_operand" "f")))]
- "TARGET_80387"
-{
- if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
- return "fstp%z0\t%y0";
- else
- return "fst%z0\t%y0";
-}
- [(set_attr "type" "fmov")
- (set_attr "mode" "DF")])
-
-(define_split
- [(set (match_operand:DF 0 "memory_operand" "")
- (float_truncate:DF
- (match_operand:TF 1 "register_operand" "")))
- (clobber (match_operand:DF 2 "memory_operand" ""))]
- "TARGET_80387"
- [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
- "")
-
-(define_split
- [(set (match_operand:DF 0 "register_operand" "")
- (float_truncate:DF
- (match_operand:TF 1 "register_operand" "")))
- (clobber (match_operand:DF 2 "memory_operand" ""))]
- "TARGET_80387 && reload_completed"
- [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
- (set (match_dup 0) (match_dup 2))]
- "")
-
;; %%% Break up all these bad boys.
@@ -4051,12 +4016,6 @@
(define_expand "fix_truncxfdi2"
[(set (match_operand:DI 0 "nonimmediate_operand" "")
(fix:DI (match_operand:XF 1 "register_operand" "")))]
- "!TARGET_64BIT && TARGET_80387"
- "")
-
-(define_expand "fix_trunctfdi2"
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (fix:DI (match_operand:TF 1 "register_operand" "")))]
"TARGET_80387"
"")
@@ -4102,6 +4061,7 @@
"&& 1"
[(const_int 0)]
{
+ ix86_optimize_mode_switching = 1;
operands[2] = assign_386_stack_local (HImode, 1);
operands[3] = assign_386_stack_local (HImode, 2);
if (memory_operand (operands[0], VOIDmode))
@@ -4116,7 +4076,8 @@
}
DONE;
}
- [(set_attr "type" "fistp")])
+ [(set_attr "type" "fistp")
+ (set_attr "mode" "DI")])
(define_insn "fix_truncdi_nomemory"
[(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
@@ -4128,7 +4089,8 @@
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
"#"
- [(set_attr "type" "fistp")])
+ [(set_attr "type" "fistp")
+ (set_attr "mode" "DI")])
(define_insn "fix_truncdi_memory"
[(set (match_operand:DI 0 "memory_operand" "=m")
@@ -4139,7 +4101,8 @@
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
"* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
- [(set_attr "type" "fistp")])
+ [(set_attr "type" "fistp")
+ (set_attr "mode" "DI")])
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -4172,30 +4135,48 @@
;; When SSE available, it is always faster to use it!
(define_insn "fix_truncsfdi_sse"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
"TARGET_64BIT && TARGET_SSE"
"cvttss2si{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")])
+ [(set_attr "type" "sseicvt")
+ (set_attr "mode" "SF")
+ (set_attr "athlon_decode" "double,vector")])
+
+;; Avoid vector decoded form of the instruction.
+(define_peephole2
+ [(match_scratch:SF 2 "x")
+ (set (match_operand:DI 0 "register_operand" "")
+ (fix:DI (match_operand:SF 1 "memory_operand" "")))]
+ "TARGET_K8 && !optimize_size"
+ [(set (match_dup 2) (match_dup 1))
+ (set (match_dup 0) (fix:DI (match_dup 2)))]
+ "")
(define_insn "fix_truncdfdi_sse"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
"TARGET_64BIT && TARGET_SSE2"
"cvttsd2si{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")])
+ [(set_attr "type" "sseicvt,sseicvt")
+ (set_attr "mode" "DF")
+ (set_attr "athlon_decode" "double,vector")])
+
+;; Avoid vector decoded form of the instruction.
+(define_peephole2
+ [(match_scratch:DF 2 "Y")
+ (set (match_operand:DI 0 "register_operand" "")
+ (fix:DI (match_operand:DF 1 "memory_operand" "")))]
+ "TARGET_K8 && !optimize_size"
+ [(set (match_dup 2) (match_dup 1))
+ (set (match_dup 0) (fix:DI (match_dup 2)))]
+ "")
;; Signed conversion to SImode.
(define_expand "fix_truncxfsi2"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(fix:SI (match_operand:XF 1 "register_operand" "")))]
- "!TARGET_64BIT && TARGET_80387"
- "")
-
-(define_expand "fix_trunctfsi2"
- [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (fix:SI (match_operand:TF 1 "register_operand" "")))]
"TARGET_80387"
"")
@@ -4241,6 +4222,7 @@
"&& 1"
[(const_int 0)]
{
+ ix86_optimize_mode_switching = 1;
operands[2] = assign_386_stack_local (HImode, 1);
operands[3] = assign_386_stack_local (HImode, 2);
if (memory_operand (operands[0], VOIDmode))
@@ -4255,7 +4237,8 @@
}
DONE;
}
- [(set_attr "type" "fistp")])
+ [(set_attr "type" "fistp")
+ (set_attr "mode" "SI")])
(define_insn "fix_truncsi_nomemory"
[(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
@@ -4266,7 +4249,8 @@
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
"#"
- [(set_attr "type" "fistp")])
+ [(set_attr "type" "fistp")
+ (set_attr "mode" "SI")])
(define_insn "fix_truncsi_memory"
[(set (match_operand:SI 0 "memory_operand" "=m")
@@ -4276,22 +4260,47 @@
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
"* return output_fix_trunc (insn, operands);"
- [(set_attr "type" "fistp")])
+ [(set_attr "type" "fistp")
+ (set_attr "mode" "SI")])
;; When SSE available, it is always faster to use it!
(define_insn "fix_truncsfsi_sse"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
"TARGET_SSE"
"cvttss2si\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")])
+ [(set_attr "type" "sseicvt")
+ (set_attr "mode" "DF")
+ (set_attr "athlon_decode" "double,vector")])
+
+;; Avoid vector decoded form of the instruction.
+(define_peephole2
+ [(match_scratch:SF 2 "x")
+ (set (match_operand:SI 0 "register_operand" "")
+ (fix:SI (match_operand:SF 1 "memory_operand" "")))]
+ "TARGET_K8 && !optimize_size"
+ [(set (match_dup 2) (match_dup 1))
+ (set (match_dup 0) (fix:SI (match_dup 2)))]
+ "")
(define_insn "fix_truncdfsi_sse"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
"TARGET_SSE2"
"cvttsd2si\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")])
+ [(set_attr "type" "sseicvt")
+ (set_attr "mode" "DF")
+ (set_attr "athlon_decode" "double,vector")])
+
+;; Avoid vector decoded form of the instruction.
+(define_peephole2
+ [(match_scratch:DF 2 "Y")
+ (set (match_operand:SI 0 "register_operand" "")
+ (fix:SI (match_operand:DF 1 "memory_operand" "")))]
+ "TARGET_K8 && !optimize_size"
+ [(set (match_dup 2) (match_dup 1))
+ (set (match_dup 0) (fix:SI (match_dup 2)))]
+ "")
(define_split
[(set (match_operand:SI 0 "register_operand" "")
@@ -4323,12 +4332,6 @@
(define_expand "fix_truncxfhi2"
[(set (match_operand:HI 0 "nonimmediate_operand" "")
(fix:HI (match_operand:XF 1 "register_operand" "")))]
- "!TARGET_64BIT && TARGET_80387"
- "")
-
-(define_expand "fix_trunctfhi2"
- [(set (match_operand:HI 0 "nonimmediate_operand" "")
- (fix:HI (match_operand:TF 1 "register_operand" "")))]
"TARGET_80387"
"")
@@ -4356,6 +4359,7 @@
""
[(const_int 0)]
{
+ ix86_optimize_mode_switching = 1;
operands[2] = assign_386_stack_local (HImode, 1);
operands[3] = assign_386_stack_local (HImode, 2);
if (memory_operand (operands[0], VOIDmode))
@@ -4370,7 +4374,8 @@
}
DONE;
}
- [(set_attr "type" "fistp")])
+ [(set_attr "type" "fistp")
+ (set_attr "mode" "HI")])
(define_insn "fix_trunchi_nomemory"
[(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
@@ -4381,7 +4386,8 @@
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
"#"
- [(set_attr "type" "fistp")])
+ [(set_attr "type" "fistp")
+ (set_attr "mode" "HI")])
(define_insn "fix_trunchi_memory"
[(set (match_operand:HI 0 "memory_operand" "=m")
@@ -4391,7 +4397,8 @@
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
"* return output_fix_trunc (insn, operands);"
- [(set_attr "type" "fistp")])
+ [(set_attr "type" "fistp")
+ (set_attr "mode" "HI")])
(define_split
[(set (match_operand:HI 0 "memory_operand" "")
@@ -4446,10 +4453,23 @@
;; Even though we only accept memory inputs, the backend _really_
;; wants to be able to do this between registers.
-(define_insn "floathisf2"
+(define_expand "floathisf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
+ "TARGET_SSE || TARGET_80387"
+{
+ if (TARGET_SSE && TARGET_SSE_MATH)
+ {
+ emit_insn (gen_floatsisf2 (operands[0],
+ convert_to_mode (SImode, operands[1], 0)));
+ DONE;
+ }
+})
+
+(define_insn "*floathisf2_1"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
- "TARGET_80387 && !TARGET_SSE"
+ "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
"@
fild%z1\t%1
#"
@@ -4464,26 +4484,45 @@
"")
(define_insn "*floatsisf2_i387"
- [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
- (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
+ [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
+ (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
"TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
"@
fild%z1\t%1
#
+ cvtsi2ss\t{%1, %0|%0, %1}
cvtsi2ss\t{%1, %0|%0, %1}"
- [(set_attr "type" "fmov,multi,ssecvt")
+ [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
(set_attr "mode" "SF")
+ (set_attr "athlon_decode" "*,*,vector,double")
(set_attr "fp_int_src" "true")])
(define_insn "*floatsisf2_sse"
- [(set (match_operand:SF 0 "register_operand" "=x")
- (float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
+ [(set (match_operand:SF 0 "register_operand" "=x,x")
+ (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
"TARGET_SSE"
"cvtsi2ss\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "sseicvt")
(set_attr "mode" "SF")
+ (set_attr "athlon_decode" "vector,double")
(set_attr "fp_int_src" "true")])
+; Avoid possible reformatting penalty on the destination by first
+; zeroing it out
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
+ "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
+ && SSE_REG_P (operands[0])"
+ [(const_int 0)]
+{
+ rtx dest;
+ dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
+ emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
+ emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
+ DONE;
+})
+
(define_expand "floatdisf2"
[(set (match_operand:SF 0 "register_operand" "")
(float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
@@ -4502,30 +4541,62 @@
(set_attr "fp_int_src" "true")])
(define_insn "*floatdisf2_i387"
- [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
- (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
+ [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
+ (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
"TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
"@
fild%z1\t%1
#
+ cvtsi2ss{q}\t{%1, %0|%0, %1}
cvtsi2ss{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "fmov,multi,ssecvt")
+ [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
(set_attr "mode" "SF")
+ (set_attr "athlon_decode" "*,*,vector,double")
(set_attr "fp_int_src" "true")])
(define_insn "*floatdisf2_sse"
- [(set (match_operand:SF 0 "register_operand" "=x")
- (float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
+ [(set (match_operand:SF 0 "register_operand" "=x,x")
+ (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
"TARGET_64BIT && TARGET_SSE"
"cvtsi2ss{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "sseicvt")
(set_attr "mode" "SF")
+ (set_attr "athlon_decode" "vector,double")
(set_attr "fp_int_src" "true")])
-(define_insn "floathidf2"
+; Avoid possible reformatting penalty on the destination by first
+; zeroing it out
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
+ "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
+ && SSE_REG_P (operands[0])"
+ [(const_int 0)]
+{
+ rtx dest;
+ dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
+ emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
+ emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
+ DONE;
+})
+
+(define_expand "floathidf2"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
+ "TARGET_SSE2 || TARGET_80387"
+{
+ if (TARGET_SSE && TARGET_SSE_MATH)
+ {
+ emit_insn (gen_floatsidf2 (operands[0],
+ convert_to_mode (SImode, operands[1], 0)));
+ DONE;
+ }
+})
+
+(define_insn "*floathidf2_1"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
- "TARGET_80387 && !TARGET_SSE2"
+ "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
"@
fild%z1\t%1
#"
@@ -4540,24 +4611,27 @@
"")
(define_insn "*floatsidf2_i387"
- [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
- (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
+ [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
+ (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
"TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
"@
fild%z1\t%1
#
+ cvtsi2sd\t{%1, %0|%0, %1}
cvtsi2sd\t{%1, %0|%0, %1}"
- [(set_attr "type" "fmov,multi,ssecvt")
+ [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
(set_attr "mode" "DF")
+ (set_attr "athlon_decode" "*,*,double,direct")
(set_attr "fp_int_src" "true")])
(define_insn "*floatsidf2_sse"
- [(set (match_operand:DF 0 "register_operand" "=Y")
- (float:DF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
+ [(set (match_operand:DF 0 "register_operand" "=Y,Y")
+ (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
"TARGET_SSE2"
"cvtsi2sd\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "sseicvt")
(set_attr "mode" "DF")
+ (set_attr "athlon_decode" "double,direct")
(set_attr "fp_int_src" "true")])
(define_expand "floatdidf2"
@@ -4578,40 +4652,32 @@
(set_attr "fp_int_src" "true")])
(define_insn "*floatdidf2_i387"
- [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
- (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
+ [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
+ (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
"TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
"@
fild%z1\t%1
#
+ cvtsi2sd{q}\t{%1, %0|%0, %1}
cvtsi2sd{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "fmov,multi,ssecvt")
+ [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
(set_attr "mode" "DF")
+ (set_attr "athlon_decode" "*,*,double,direct")
(set_attr "fp_int_src" "true")])
(define_insn "*floatdidf2_sse"
- [(set (match_operand:DF 0 "register_operand" "=Y")
- (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
+ [(set (match_operand:DF 0 "register_operand" "=Y,Y")
+ (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
"TARGET_SSE2"
"cvtsi2sd{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "sseicvt")
(set_attr "mode" "DF")
+ (set_attr "athlon_decode" "double,direct")
(set_attr "fp_int_src" "true")])
(define_insn "floathixf2"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
- "!TARGET_64BIT && TARGET_80387"
- "@
- fild%z1\t%1
- #"
- [(set_attr "type" "fmov,multi")
- (set_attr "mode" "XF")
- (set_attr "fp_int_src" "true")])
-
-(define_insn "floathitf2"
- [(set (match_operand:TF 0 "register_operand" "=f,f")
- (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
"TARGET_80387"
"@
fild%z1\t%1
@@ -4623,17 +4689,6 @@
(define_insn "floatsixf2"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
- "!TARGET_64BIT && TARGET_80387"
- "@
- fild%z1\t%1
- #"
- [(set_attr "type" "fmov,multi")
- (set_attr "mode" "XF")
- (set_attr "fp_int_src" "true")])
-
-(define_insn "floatsitf2"
- [(set (match_operand:TF 0 "register_operand" "=f,f")
- (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
"TARGET_80387"
"@
fild%z1\t%1
@@ -4645,17 +4700,6 @@
(define_insn "floatdixf2"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
- "!TARGET_64BIT && TARGET_80387"
- "@
- fild%z1\t%1
- #"
- [(set_attr "type" "fmov,multi")
- (set_attr "mode" "XF")
- (set_attr "fp_int_src" "true")])
-
-(define_insn "floatditf2"
- [(set (match_operand:TF 0 "register_operand" "=f,f")
- (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
"TARGET_80387"
"@
fild%z1\t%1
@@ -4677,6 +4721,189 @@
ix86_free_from_memory (GET_MODE (operands[1]));
DONE;
})
+
+(define_expand "floatunssisf2"
+ [(use (match_operand:SF 0 "register_operand" ""))
+ (use (match_operand:SI 1 "register_operand" ""))]
+ "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
+ "x86_emit_floatuns (operands); DONE;")
+
+(define_expand "floatunsdisf2"
+ [(use (match_operand:SF 0 "register_operand" ""))
+ (use (match_operand:DI 1 "register_operand" ""))]
+ "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
+ "x86_emit_floatuns (operands); DONE;")
+
+(define_expand "floatunsdidf2"
+ [(use (match_operand:DF 0 "register_operand" ""))
+ (use (match_operand:DI 1 "register_operand" ""))]
+ "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
+ "x86_emit_floatuns (operands); DONE;")
+
+;; SSE extract/set expanders
+
+(define_expand "vec_setv2df"
+ [(match_operand:V2DF 0 "register_operand" "")
+ (match_operand:DF 1 "register_operand" "")
+ (match_operand 2 "const_int_operand" "")]
+ "TARGET_SSE2"
+{
+ switch (INTVAL (operands[2]))
+ {
+ case 0:
+ emit_insn (gen_sse2_movsd (operands[0], operands[0],
+ simplify_gen_subreg (V2DFmode, operands[1],
+ DFmode, 0)));
+ break;
+ case 1:
+ {
+ rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
+
+ emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
+ }
+ break;
+ default:
+ abort ();
+ }
+ DONE;
+})
+
+(define_expand "vec_extractv2df"
+ [(match_operand:DF 0 "register_operand" "")
+ (match_operand:V2DF 1 "register_operand" "")
+ (match_operand 2 "const_int_operand" "")]
+ "TARGET_SSE2"
+{
+ switch (INTVAL (operands[2]))
+ {
+ case 0:
+ emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
+ break;
+ case 1:
+ {
+ rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
+
+ emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
+ }
+ break;
+ default:
+ abort ();
+ }
+ DONE;
+})
+
+(define_expand "vec_initv2df"
+ [(match_operand:V2DF 0 "register_operand" "")
+ (match_operand 1 "" "")]
+ "TARGET_SSE2"
+{
+ ix86_expand_vector_init (operands[0], operands[1]);
+ DONE;
+})
+
+(define_expand "vec_setv4sf"
+ [(match_operand:V4SF 0 "register_operand" "")
+ (match_operand:SF 1 "register_operand" "")
+ (match_operand 2 "const_int_operand" "")]
+ "TARGET_SSE"
+{
+ switch (INTVAL (operands[2]))
+ {
+ case 0:
+ emit_insn (gen_sse_movss (operands[0], operands[0],
+ simplify_gen_subreg (V4SFmode, operands[1],
+ SFmode, 0)));
+ break;
+ case 1:
+ {
+ rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
+ rtx tmp = gen_reg_rtx (V4SFmode);
+
+ emit_move_insn (tmp, operands[0]);
+ emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
+ emit_insn (gen_sse_movss (operands[0], operands[0], op1));
+ emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
+ GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
+ }
+ case 2:
+ {
+ rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
+ rtx tmp = gen_reg_rtx (V4SFmode);
+
+ emit_move_insn (tmp, operands[0]);
+ emit_insn (gen_sse_movss (tmp, tmp, op1));
+ emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
+ GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
+ }
+ break;
+ case 3:
+ {
+ rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
+ rtx tmp = gen_reg_rtx (V4SFmode);
+
+ emit_move_insn (tmp, operands[0]);
+ emit_insn (gen_sse_movss (tmp, tmp, op1));
+ emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
+ GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
+ }
+ break;
+ default:
+ abort ();
+ }
+ DONE;
+})
+
+(define_expand "vec_extractv4sf"
+ [(match_operand:SF 0 "register_operand" "")
+ (match_operand:V4SF 1 "register_operand" "")
+ (match_operand 2 "const_int_operand" "")]
+ "TARGET_SSE"
+{
+ switch (INTVAL (operands[2]))
+ {
+ case 0:
+ emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
+ break;
+ case 1:
+ {
+ rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
+ rtx tmp = gen_reg_rtx (V4SFmode);
+
+ emit_move_insn (tmp, operands[1]);
+ emit_insn (gen_sse_shufps (op0, tmp, tmp,
+ GEN_INT (1)));
+ }
+ case 2:
+ {
+ rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
+ rtx tmp = gen_reg_rtx (V4SFmode);
+
+ emit_move_insn (tmp, operands[1]);
+ emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
+ }
+ case 3:
+ {
+ rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
+ rtx tmp = gen_reg_rtx (V4SFmode);
+
+ emit_move_insn (tmp, operands[1]);
+ emit_insn (gen_sse_shufps (op0, tmp, tmp,
+ GEN_INT (3)));
+ }
+ default:
+ abort ();
+ }
+ DONE;
+})
+
+(define_expand "vec_initv4sf"
+ [(match_operand:V4SF 0 "register_operand" "")
+ (match_operand 1 "" "")]
+ "TARGET_SSE"
+{
+ ix86_expand_vector_init (operands[0], operands[1]);
+ DONE;
+})
;; Add instructions
@@ -4719,9 +4946,9 @@
split_di (operands+1, 1, operands+1, operands+4);
split_di (operands+2, 1, operands+2, operands+5);")
-(define_insn "*adddi3_carry_rex64"
+(define_insn "adddi3_carry_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
- (plus:DI (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
+ (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
(match_operand:DI 1 "nonimmediate_operand" "%0,0"))
(match_operand:DI 2 "x86_64_general_operand" "re,rm")))
(clobber (reg:CC 17))]
@@ -4744,9 +4971,35 @@
[(set_attr "type" "alu")
(set_attr "mode" "DI")])
-(define_insn "*addsi3_carry"
+(define_insn "addqi3_carry"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
+ (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
+ (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
+ (match_operand:QI 2 "general_operand" "qi,qm")))
+ (clobber (reg:CC 17))]
+ "ix86_binary_operator_ok (PLUS, QImode, operands)"
+ "adc{b}\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "pent_pair" "pu")
+ (set_attr "mode" "QI")
+ (set_attr "ppro_uops" "few")])
+
+(define_insn "addhi3_carry"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
+ (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
+ (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
+ (match_operand:HI 2 "general_operand" "ri,rm")))
+ (clobber (reg:CC 17))]
+ "ix86_binary_operator_ok (PLUS, HImode, operands)"
+ "adc{w}\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "pent_pair" "pu")
+ (set_attr "mode" "HI")
+ (set_attr "ppro_uops" "few")])
+
+(define_insn "addsi3_carry"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
- (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
+ (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
(match_operand:SI 1 "nonimmediate_operand" "%0,0"))
(match_operand:SI 2 "general_operand" "ri,rm")))
(clobber (reg:CC 17))]
@@ -4760,7 +5013,7 @@
(define_insn "*addsi3_carry_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
- (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
+ (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
(match_operand:SI 1 "nonimmediate_operand" "%0"))
(match_operand:SI 2 "general_operand" "rim"))))
(clobber (reg:CC 17))]
@@ -4805,7 +5058,7 @@
(define_insn "*lea_1"
[(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "address_operand" "p"))]
+ (match_operand:SI 1 "no_seg_address_operand" "p"))]
"!TARGET_64BIT"
"lea{l}\t{%a1, %0|%0, %a1}"
[(set_attr "type" "lea")
@@ -4813,7 +5066,7 @@
(define_insn "*lea_1_rex64"
[(set (match_operand:SI 0 "register_operand" "=r")
- (subreg:SI (match_operand:DI 1 "address_operand" "p") 0))]
+ (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
"TARGET_64BIT"
"lea{l}\t{%a1, %0|%0, %a1}"
[(set_attr "type" "lea")
@@ -4821,7 +5074,8 @@
(define_insn "*lea_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI (subreg:SI (match_operand:DI 1 "address_operand" "p") 0)))]
+ (zero_extend:DI
+ (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
"TARGET_64BIT"
"lea{l}\t{%a1, %k0|%k0, %a1}"
[(set_attr "type" "lea")
@@ -4829,7 +5083,7 @@
(define_insn "*lea_2_rex64"
[(set (match_operand:DI 0 "register_operand" "=r")
- (match_operand:DI 1 "address_operand" "p"))]
+ (match_operand:DI 1 "no_seg_address_operand" "p"))]
"TARGET_64BIT"
"lea{q}\t{%a1, %0|%0, %a1}"
[(set_attr "type" "lea")
@@ -5093,7 +5347,7 @@
if (! rtx_equal_p (operands[0], operands[1]))
abort ();
/* ???? We ought to handle there the 32bit case too
- - do we need new constrant? */
+ - do we need new constraint? */
/* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (GET_CODE (operands[2]) == CONST_INT
@@ -5143,7 +5397,7 @@
if (! rtx_equal_p (operands[0], operands[1]))
abort ();
/* ???? We ought to handle there the 32bit case too
- - do we need new constrant? */
+ - do we need new constraint? */
/* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
Exceptions: -128 encodes smaller than 128, so swap sign and op. */
if (GET_CODE (operands[2]) == CONST_INT
@@ -5403,7 +5657,7 @@
(plus:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" ""))))
(clobber (reg:CC 17))]
- "reload_completed
+ "TARGET_64BIT && reload_completed
&& true_regnum (operands[0]) != true_regnum (operands[1])"
[(set (match_dup 0)
(zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
@@ -5593,7 +5847,7 @@
(const_string "alu")))
(set_attr "mode" "SI")])
-; For comparisons agains 1, -1 and 128, we may generate better code
+; For comparisons against 1, -1 and 128, we may generate better code
; by converting cmp to add, inc or dec as done by peephole2. This pattern
; is matched then. We can't accept general immediate, because for
; case of overflows, the result is messed up.
@@ -6053,7 +6307,7 @@
if (GET_CODE (operands[1]) == CONST_INT
&& INTVAL (operands[1]) < 0)
{
- operands[2] = GEN_INT (-INTVAL (operands[2]));
+ operands[1] = GEN_INT (-INTVAL (operands[1]));
return "sub{b}\t{%1, %0|%0, %1}";
}
return "add{b}\t{%1, %0|%0, %1}";
@@ -6311,13 +6565,6 @@
[(set (match_operand:XF 0 "register_operand" "")
(plus:XF (match_operand:XF 1 "register_operand" "")
(match_operand:XF 2 "register_operand" "")))]
- "!TARGET_64BIT && TARGET_80387"
- "")
-
-(define_expand "addtf3"
- [(set (match_operand:TF 0 "register_operand" "")
- (plus:TF (match_operand:TF 1 "register_operand" "")
- (match_operand:TF 2 "register_operand" "")))]
"TARGET_80387"
"")
@@ -6375,7 +6622,7 @@
(define_insn "subdi3_carry_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
(minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
- (plus:DI (ltu:DI (reg:CC 17) (const_int 0))
+ (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
(match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
(clobber (reg:CC 17))]
"TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
@@ -6421,11 +6668,36 @@
[(set_attr "type" "alu")
(set_attr "mode" "DI")])
+(define_insn "subqi3_carry"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
+ (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
+ (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
+ (match_operand:QI 2 "general_operand" "qi,qm"))))
+ (clobber (reg:CC 17))]
+ "ix86_binary_operator_ok (MINUS, QImode, operands)"
+ "sbb{b}\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "pent_pair" "pu")
+ (set_attr "ppro_uops" "few")
+ (set_attr "mode" "QI")])
+
+(define_insn "subhi3_carry"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
+ (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
+ (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
+ (match_operand:HI 2 "general_operand" "ri,rm"))))
+ (clobber (reg:CC 17))]
+ "ix86_binary_operator_ok (MINUS, HImode, operands)"
+ "sbb{w}\t{%2, %0|%0, %2}"
+ [(set_attr "type" "alu")
+ (set_attr "pent_pair" "pu")
+ (set_attr "ppro_uops" "few")
+ (set_attr "mode" "HI")])
(define_insn "subsi3_carry"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
- (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
+ (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
(match_operand:SI 2 "general_operand" "ri,rm"))))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (MINUS, SImode, operands)"
@@ -6439,7 +6711,7 @@
[(set (match_operand:DI 0 "register_operand" "=rm,r")
(zero_extend:DI
(minus:SI (match_operand:SI 1 "register_operand" "0,0")
- (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
+ (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
(match_operand:SI 2 "general_operand" "ri,rm")))))
(clobber (reg:CC 17))]
"TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
@@ -6522,7 +6794,7 @@
(define_insn "*subsi_3_zext"
[(set (reg 17)
- (compare (match_operand:SI 1 "nonimmediate_operand" "0")
+ (compare (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "general_operand" "rim")))
(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
@@ -6639,13 +6911,6 @@
[(set (match_operand:XF 0 "register_operand" "")
(minus:XF (match_operand:XF 1 "register_operand" "")
(match_operand:XF 2 "register_operand" "")))]
- "!TARGET_64BIT && TARGET_80387"
- "")
-
-(define_expand "subtf3"
- [(set (match_operand:TF 0 "register_operand" "")
- (minus:TF (match_operand:TF 1 "register_operand" "")
- (match_operand:TF 2 "register_operand" "")))]
"TARGET_80387"
"")
@@ -6675,7 +6940,7 @@
(define_insn "*muldi3_1_rex64"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
- (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,0,0")
+ (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
(match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
(clobber (reg:CC 17))]
"TARGET_64BIT
@@ -6686,6 +6951,15 @@
imul{q}\t{%2, %0|%0, %2}"
[(set_attr "type" "imul")
(set_attr "prefix_0f" "0,0,1")
+ (set (attr "athlon_decode")
+ (cond [(eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (eq_attr "alternative" "1")
+ (const_string "vector")
+ (and (eq_attr "alternative" "2")
+ (match_operand 1 "memory_operand" ""))
+ (const_string "vector")]
+ (const_string "direct")))
(set_attr "mode" "DI")])
(define_expand "mulsi3"
@@ -6698,56 +6972,50 @@
(define_insn "*mulsi3_1"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
- (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
+ (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
(match_operand:SI 2 "general_operand" "K,i,mr")))
(clobber (reg:CC 17))]
"GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
- ; For the {r,0,i} alternative (i.e., register <- register * immediate),
- ; there are two ways of writing the exact same machine instruction
- ; in assembly language. One, for example, is:
- ;
- ; imul $12, %eax
- ;
- ; while the other is:
- ;
- ; imul $12, %eax, %eax
- ;
- ; The first is simply short-hand for the latter. But, some assemblers,
- ; like the SCO OSR5 COFF assembler, don't handle the first form.
"@
imul{l}\t{%2, %1, %0|%0, %1, %2}
imul{l}\t{%2, %1, %0|%0, %1, %2}
imul{l}\t{%2, %0|%0, %2}"
[(set_attr "type" "imul")
(set_attr "prefix_0f" "0,0,1")
+ (set (attr "athlon_decode")
+ (cond [(eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (eq_attr "alternative" "1")
+ (const_string "vector")
+ (and (eq_attr "alternative" "2")
+ (match_operand 1 "memory_operand" ""))
+ (const_string "vector")]
+ (const_string "direct")))
(set_attr "mode" "SI")])
(define_insn "*mulsi3_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(zero_extend:DI
- (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,0,0")
+ (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
(match_operand:SI 2 "general_operand" "K,i,mr"))))
(clobber (reg:CC 17))]
"TARGET_64BIT
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
- ; For the {r,0,i} alternative (i.e., register <- register * immediate),
- ; there are two ways of writing the exact same machine instruction
- ; in assembly language. One, for example, is:
- ;
- ; imul $12, %eax
- ;
- ; while the other is:
- ;
- ; imul $12, %eax, %eax
- ;
- ; The first is simply short-hand for the latter. But, some assemblers,
- ; like the SCO OSR5 COFF assembler, don't handle the first form.
"@
imul{l}\t{%2, %1, %k0|%k0, %1, %2}
imul{l}\t{%2, %1, %k0|%k0, %1, %2}
imul{l}\t{%2, %k0|%k0, %2}"
[(set_attr "type" "imul")
(set_attr "prefix_0f" "0,0,1")
+ (set (attr "athlon_decode")
+ (cond [(eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (eq_attr "alternative" "1")
+ (const_string "vector")
+ (and (eq_attr "alternative" "2")
+ (match_operand 1 "memory_operand" ""))
+ (const_string "vector")]
+ (const_string "direct")))
(set_attr "mode" "SI")])
(define_expand "mulhi3"
@@ -6760,18 +7028,22 @@
(define_insn "*mulhi3_1"
[(set (match_operand:HI 0 "register_operand" "=r,r,r")
- (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,0,0")
+ (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
(match_operand:HI 2 "general_operand" "K,i,mr")))
(clobber (reg:CC 17))]
"GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
- ; %%% There was a note about "Assembler has weird restrictions",
- ; concerning alternative 1 when op1 == op0. True?
"@
imul{w}\t{%2, %1, %0|%0, %1, %2}
imul{w}\t{%2, %1, %0|%0, %1, %2}
imul{w}\t{%2, %0|%0, %2}"
[(set_attr "type" "imul")
(set_attr "prefix_0f" "0,0,1")
+ (set (attr "athlon_decode")
+ (cond [(eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (eq_attr "alternative" "1,2")
+ (const_string "vector")]
+ (const_string "direct")))
(set_attr "mode" "HI")])
(define_expand "mulqi3"
@@ -6792,6 +7064,10 @@
"mul{b}\t%2"
[(set_attr "type" "imul")
(set_attr "length_immediate" "0")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "direct")))
(set_attr "mode" "QI")])
(define_expand "umulqihi3"
@@ -6814,6 +7090,10 @@
"mul{b}\t%2"
[(set_attr "type" "imul")
(set_attr "length_immediate" "0")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "direct")))
(set_attr "mode" "QI")])
(define_expand "mulqihi3"
@@ -6834,6 +7114,10 @@
"imul{b}\t%2"
[(set_attr "type" "imul")
(set_attr "length_immediate" "0")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "direct")))
(set_attr "mode" "QI")])
(define_expand "umulditi3"
@@ -6857,6 +7141,10 @@
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
(set_attr "length_immediate" "0")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "double")))
(set_attr "mode" "DI")])
;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
@@ -6881,6 +7169,10 @@
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
(set_attr "length_immediate" "0")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "double")))
(set_attr "mode" "SI")])
(define_expand "mulditi3"
@@ -6903,6 +7195,10 @@
"imul{q}\t%2"
[(set_attr "type" "imul")
(set_attr "length_immediate" "0")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "double")))
(set_attr "mode" "DI")])
(define_expand "mulsidi3"
@@ -6925,6 +7221,10 @@
"imul{l}\t%2"
[(set_attr "type" "imul")
(set_attr "length_immediate" "0")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "double")))
(set_attr "mode" "SI")])
(define_expand "umuldi3_highpart"
@@ -6958,6 +7258,10 @@
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
(set_attr "length_immediate" "0")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "double")))
(set_attr "mode" "DI")])
(define_expand "umulsi3_highpart"
@@ -6990,6 +7294,10 @@
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
(set_attr "length_immediate" "0")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "double")))
(set_attr "mode" "SI")])
(define_insn "*umulsi3_highpart_zext"
@@ -7009,6 +7317,10 @@
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
(set_attr "length_immediate" "0")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "double")))
(set_attr "mode" "SI")])
(define_expand "smuldi3_highpart"
@@ -7041,6 +7353,10 @@
"imul{q}\t%2"
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "double")))
(set_attr "mode" "DI")])
(define_expand "smulsi3_highpart"
@@ -7072,6 +7388,10 @@
"imul{l}\t%2"
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "double")))
(set_attr "mode" "SI")])
(define_insn "*smulsi3_highpart_zext"
@@ -7090,6 +7410,10 @@
"imul{l}\t%2"
[(set_attr "type" "imul")
(set_attr "ppro_uops" "few")
+ (set (attr "athlon_decode")
+ (if_then_else (eq_attr "cpu" "athlon")
+ (const_string "vector")
+ (const_string "double")))
(set_attr "mode" "SI")])
;; The patterns that match these are at the end of this file.
@@ -7098,13 +7422,6 @@
[(set (match_operand:XF 0 "register_operand" "")
(mult:XF (match_operand:XF 1 "register_operand" "")
(match_operand:XF 2 "register_operand" "")))]
- "!TARGET_64BIT && TARGET_80387"
- "")
-
-(define_expand "multf3"
- [(set (match_operand:TF 0 "register_operand" "")
- (mult:TF (match_operand:TF 1 "register_operand" "")
- (match_operand:TF 2 "register_operand" "")))]
"TARGET_80387"
"")
@@ -7152,13 +7469,6 @@
[(set (match_operand:XF 0 "register_operand" "")
(div:XF (match_operand:XF 1 "register_operand" "")
(match_operand:XF 2 "register_operand" "")))]
- "!TARGET_64BIT && TARGET_80387"
- "")
-
-(define_expand "divtf3"
- [(set (match_operand:TF 0 "register_operand" "")
- (div:TF (match_operand:TF 1 "register_operand" "")
- (match_operand:TF 2 "register_operand" "")))]
"TARGET_80387"
"")
@@ -7189,7 +7499,7 @@
"")
;; Allow to come the parameter in eax or edx to avoid extra moves.
-;; Penalize eax case sligthly because it results in worse scheduling
+;; Penalize eax case slightly because it results in worse scheduling
;; of code.
(define_insn "*divmoddi4_nocltd_rex64"
[(set (match_operand:DI 0 "register_operand" "=&a,?a")
@@ -7274,7 +7584,7 @@
"")
;; Allow to come the parameter in eax or edx to avoid extra moves.
-;; Penalize eax case sligthly because it results in worse scheduling
+;; Penalize eax case slightly because it results in worse scheduling
;; of code.
(define_insn "*divmodsi4_nocltd"
[(set (match_operand:SI 0 "register_operand" "=&a,?a")
@@ -7502,10 +7812,11 @@
(define_insn "*testdi_1_rex64"
[(set (reg 17)
(compare
- (and:DI (match_operand:DI 0 "nonimmediate_operand" "%*a,r,*a,r,rm")
- (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,Z,e,e,re"))
+ (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
+ (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
(const_int 0)))]
- "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
+ "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"@
test{l}\t{%k1, %k0|%k0, %k1}
test{l}\t{%k1, %k0|%k0, %k1}
@@ -7520,10 +7831,11 @@
(define_insn "testsi_1"
[(set (reg 17)
(compare
- (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
- (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
+ (match_operand:SI 1 "general_operand" "in,in,rin"))
(const_int 0)))]
- "ix86_match_ccmode (insn, CCNOmode)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"test{l}\t{%1, %0|%0, %1}"
[(set_attr "type" "test")
(set_attr "modrm" "0,1,1")
@@ -7541,10 +7853,11 @@
(define_insn "*testhi_1"
[(set (reg 17)
- (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
- (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
+ (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
+ (match_operand:HI 1 "general_operand" "n,n,rn"))
(const_int 0)))]
- "ix86_match_ccmode (insn, CCNOmode)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"test{w}\t{%1, %0|%0, %1}"
[(set_attr "type" "test")
(set_attr "modrm" "0,1,1")
@@ -7561,10 +7874,11 @@
(define_insn "*testqi_1"
[(set (reg 17)
- (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm,r")
- (match_operand:QI 1 "nonmemory_operand" "n,n,qn,n"))
+ (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
+ (match_operand:QI 1 "general_operand" "n,n,qn,n"))
(const_int 0)))]
- "ix86_match_ccmode (insn, CCNOmode)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
{
if (which_alternative == 3)
{
@@ -7619,9 +7933,10 @@
(const_int 8)
(const_int 8))
(zero_extend:SI
- (match_operand:QI 1 "nonimmediate_operand" "Qm")))
+ (match_operand:QI 1 "general_operand" "Qm")))
(const_int 0)))]
- "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
+ "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"test{b}\t{%1, %h0|%h0, %1}"
[(set_attr "type" "test")
(set_attr "mode" "QI")])
@@ -7747,7 +8062,7 @@
;; Convert HImode/SImode test instructions with immediate to QImode ones.
;; i386 does not allow to encode test with 8bit sign extended immediate, so
;; this is relatively important trick.
-;; Do the converison only post-reload to avoid limiting of the register class
+;; Do the conversion only post-reload to avoid limiting of the register class
;; to QI regs.
(define_split
[(set (reg 17)
@@ -8211,7 +8526,7 @@
;; Convert wide AND instructions with immediate operand to shorter QImode
;; equivalents when possible.
-;; Don't do the splitting with memory operands, since it intoduces risc
+;; Don't do the splitting with memory operands, since it introduces risk
;; of memory mismatch stalls. We may want to do the splitting for optimizing
;; for size, but that can (should?) be handled by generic code instead.
(define_split
@@ -9265,12 +9580,15 @@
in register. */
rtx reg = gen_reg_rtx (SFmode);
rtx dest = operands[0];
+ rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
operands[1] = force_reg (SFmode, operands[1]);
operands[0] = force_reg (SFmode, operands[0]);
- emit_move_insn (reg,
- gen_lowpart (SFmode,
- gen_int_mode (0x80000000, SImode)));
+ reg = force_reg (V4SFmode,
+ gen_rtx_CONST_VECTOR (V4SFmode,
+ gen_rtvec (4, imm, CONST0_RTX (SFmode),
+ CONST0_RTX (SFmode),
+ CONST0_RTX (SFmode))));
emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
if (dest != operands[0])
emit_move_insn (dest, operands[0]);
@@ -9289,7 +9607,7 @@
(define_insn "negsf2_ifs"
[(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
- (use (match_operand:SF 2 "nonmemory_operand" "x,0#x,*g#x,*g#x"))
+ (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
(clobber (reg:CC 17))]
"TARGET_SSE
&& (reload_in_progress || reload_completed
@@ -9310,7 +9628,7 @@
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(neg:SF (match_operand:SF 1 "register_operand" "")))
- (use (match_operand:SF 2 "" ""))
+ (use (match_operand:V4SF 2 "" ""))
(clobber (reg:CC 17))]
"reload_completed && !SSE_REG_P (operands[0])"
[(parallel [(set (match_dup 0)
@@ -9320,13 +9638,15 @@
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(neg:SF (match_operand:SF 1 "register_operand" "")))
- (use (match_operand:SF 2 "register_operand" ""))
+ (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
(clobber (reg:CC 17))]
"reload_completed && SSE_REG_P (operands[0])"
[(set (subreg:TI (match_dup 0) 0)
- (xor:TI (subreg:TI (match_dup 1) 0)
- (subreg:TI (match_dup 2) 0)))]
+ (xor:TI (match_dup 1)
+ (match_dup 2)))]
{
+ operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
+ operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
if (operands_match_p (operands[0], operands[2]))
{
rtx tmp;
@@ -9365,7 +9685,7 @@
[(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
(clobber (reg:CC 17))])]
"operands[1] = gen_int_mode (0x80000000, SImode);
- operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
+ operands[0] = gen_lowpart (SImode, operands[0]);")
(define_split
[(set (match_operand 0 "memory_operand" "")
@@ -9377,8 +9697,7 @@
{
int size = GET_MODE_SIZE (GET_MODE (operands[1]));
- /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
- if (size >= 12)
+ if (GET_MODE (operands[1]) == XFmode)
size = 10;
operands[0] = adjust_address (operands[0], QImode, size - 1);
operands[1] = gen_int_mode (0x80, QImode);
@@ -9399,7 +9718,7 @@
{
/* Using SSE is tricky, since we need bitwise negation of -0
in register. */
- rtx reg = gen_reg_rtx (DFmode);
+ rtx reg;
#if HOST_BITS_PER_WIDE_INT >= 64
rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
#else
@@ -9409,7 +9728,10 @@
operands[1] = force_reg (DFmode, operands[1]);
operands[0] = force_reg (DFmode, operands[0]);
- emit_move_insn (reg, gen_lowpart (DFmode, imm));
+ imm = gen_lowpart (DFmode, imm);
+ reg = force_reg (V2DFmode,
+ gen_rtx_CONST_VECTOR (V2DFmode,
+ gen_rtvec (2, imm, CONST0_RTX (DFmode))));
emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
if (dest != operands[0])
emit_move_insn (dest, operands[0]);
@@ -9428,7 +9750,7 @@
(define_insn "negdf2_ifs"
[(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
- (use (match_operand:DF 2 "nonmemory_operand" "Y,0,*g#Y,*g#Y"))
+ (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
(clobber (reg:CC 17))]
"!TARGET_64BIT && TARGET_SSE2
&& (reload_in_progress || reload_completed
@@ -9438,8 +9760,8 @@
(define_insn "*negdf2_ifs_rex64"
[(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
- (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#f,0")))
- (use (match_operand:DF 2 "general_operand" "Y,0,*g#Y*r"))
+ (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
+ (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
(clobber (reg:CC 17))]
"TARGET_64BIT && TARGET_SSE2
&& (reload_in_progress || reload_completed
@@ -9450,7 +9772,7 @@
(define_split
[(set (match_operand:DF 0 "memory_operand" "")
(neg:DF (match_operand:DF 1 "memory_operand" "")))
- (use (match_operand:DF 2 "" ""))
+ (use (match_operand:V2DF 2 "" ""))
(clobber (reg:CC 17))]
""
[(parallel [(set (match_dup 0)
@@ -9460,7 +9782,7 @@
(define_split
[(set (match_operand:DF 0 "register_operand" "")
(neg:DF (match_operand:DF 1 "register_operand" "")))
- (use (match_operand:DF 2 "" ""))
+ (use (match_operand:V2DF 2 "" ""))
(clobber (reg:CC 17))]
"reload_completed && !SSE_REG_P (operands[0])
&& (!TARGET_64BIT || FP_REG_P (operands[0]))"
@@ -9471,7 +9793,7 @@
(define_split
[(set (match_operand:DF 0 "register_operand" "")
(neg:DF (match_operand:DF 1 "register_operand" "")))
- (use (match_operand:DF 2 "" ""))
+ (use (match_operand:V2DF 2 "" ""))
(clobber (reg:CC 17))]
"TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
[(parallel [(set (match_dup 0)
@@ -9484,13 +9806,19 @@
(define_split
[(set (match_operand:DF 0 "register_operand" "")
(neg:DF (match_operand:DF 1 "register_operand" "")))
- (use (match_operand:DF 2 "register_operand" ""))
+ (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
(clobber (reg:CC 17))]
"reload_completed && SSE_REG_P (operands[0])"
[(set (subreg:TI (match_dup 0) 0)
- (xor:TI (subreg:TI (match_dup 1) 0)
- (subreg:TI (match_dup 2) 0)))]
+ (xor:TI (match_dup 1)
+ (match_dup 2)))]
{
+ operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
+ operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
+ operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
+ /* Avoid possible reformatting on the operands. */
+ if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
+ emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
if (operands_match_p (operands[0], operands[2]))
{
rtx tmp;
@@ -9546,15 +9874,8 @@
[(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
(neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
(clobber (reg:CC 17))])]
- "!TARGET_64BIT && TARGET_80387"
- "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
-
-(define_expand "negtf2"
- [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
- (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
- (clobber (reg:CC 17))])]
"TARGET_80387"
- "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
+ "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
;; because of secondary memory needed to reload from class FLOAT_INT_REGS
@@ -9563,7 +9884,7 @@
[(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
(neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
(clobber (reg:CC 17))]
- "!TARGET_64BIT && TARGET_80387
+ "TARGET_80387
&& ix86_unary_operator_ok (NEG, XFmode, operands)"
"#")
@@ -9587,37 +9908,7 @@
operands[0] = gen_rtx_REG (SImode,
true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
-;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
-;; because of secondary memory needed to reload from class FLOAT_INT_REGS
-;; to itself.
-(define_insn "*negtf2_if"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
- (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
- (clobber (reg:CC 17))]
- "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
- "#")
-
-(define_split
- [(set (match_operand:TF 0 "fp_register_operand" "")
- (neg:TF (match_operand:TF 1 "register_operand" "")))
- (clobber (reg:CC 17))]
- "TARGET_80387 && reload_completed"
- [(set (match_dup 0)
- (neg:TF (match_dup 1)))]
- "")
-
-(define_split
- [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
- (neg:TF (match_operand:TF 1 "register_operand" "")))
- (clobber (reg:CC 17))]
- "TARGET_80387 && reload_completed"
- [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
- (clobber (reg:CC 17))])]
- "operands[1] = GEN_INT (0x8000);
- operands[0] = gen_rtx_REG (SImode,
- true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
-
-;; Conditionize these after reload. If they matches before reload, we
+;; Conditionalize these after reload. If they matches before reload, we
;; lose the clobber and ability to use integer instructions.
(define_insn "*negsf2_1"
@@ -9651,7 +9942,7 @@
(define_insn "*negxf2_1"
[(set (match_operand:XF 0 "register_operand" "=f")
(neg:XF (match_operand:XF 1 "register_operand" "0")))]
- "!TARGET_64BIT && TARGET_80387 && reload_completed"
+ "TARGET_80387 && reload_completed"
"fchs"
[(set_attr "type" "fsgn")
(set_attr "mode" "XF")
@@ -9661,7 +9952,7 @@
[(set (match_operand:XF 0 "register_operand" "=f")
(neg:XF (float_extend:XF
(match_operand:DF 1 "register_operand" "0"))))]
- "!TARGET_64BIT && TARGET_80387"
+ "TARGET_80387"
"fchs"
[(set_attr "type" "fsgn")
(set_attr "mode" "XF")
@@ -9671,35 +9962,6 @@
[(set (match_operand:XF 0 "register_operand" "=f")
(neg:XF (float_extend:XF
(match_operand:SF 1 "register_operand" "0"))))]
- "!TARGET_64BIT && TARGET_80387"
- "fchs"
- [(set_attr "type" "fsgn")
- (set_attr "mode" "XF")
- (set_attr "ppro_uops" "few")])
-
-(define_insn "*negtf2_1"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (neg:TF (match_operand:TF 1 "register_operand" "0")))]
- "TARGET_80387 && reload_completed"
- "fchs"
- [(set_attr "type" "fsgn")
- (set_attr "mode" "XF")
- (set_attr "ppro_uops" "few")])
-
-(define_insn "*negextenddftf2"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (neg:TF (float_extend:TF
- (match_operand:DF 1 "register_operand" "0"))))]
- "TARGET_80387"
- "fchs"
- [(set_attr "type" "fsgn")
- (set_attr "mode" "XF")
- (set_attr "ppro_uops" "few")])
-
-(define_insn "*negextendsftf2"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (neg:TF (float_extend:TF
- (match_operand:SF 1 "register_operand" "0"))))]
"TARGET_80387"
"fchs"
[(set_attr "type" "fsgn")
@@ -9723,14 +9985,18 @@
{
/* Using SSE is tricky, since we need bitwise negation of -0
in register. */
- rtx reg = gen_reg_rtx (SFmode);
+ rtx reg = gen_reg_rtx (V4SFmode);
rtx dest = operands[0];
+ rtx imm;
operands[1] = force_reg (SFmode, operands[1]);
operands[0] = force_reg (SFmode, operands[0]);
- emit_move_insn (reg,
- gen_lowpart (SFmode,
- gen_int_mode (0x80000000, SImode)));
+ imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
+ reg = force_reg (V4SFmode,
+ gen_rtx_CONST_VECTOR (V4SFmode,
+ gen_rtvec (4, imm, CONST0_RTX (SFmode),
+ CONST0_RTX (SFmode),
+ CONST0_RTX (SFmode))));
emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
if (dest != operands[0])
emit_move_insn (dest, operands[0]);
@@ -9747,20 +10013,20 @@
"#")
(define_insn "abssf2_ifs"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,f#xr,rm#xf")
- (abs:SF (match_operand:SF 1 "nonimmediate_operand" "x,0,0")))
- (use (match_operand:SF 2 "nonmemory_operand" "*0#x,*g#x,*g#x"))
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
+ (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
+ (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
(clobber (reg:CC 17))]
"TARGET_SSE
&& (reload_in_progress || reload_completed
|| (register_operand (operands[0], VOIDmode)
- && register_operand (operands[1], VOIDmode)))"
+ && register_operand (operands[1], VOIDmode)))"
"#")
(define_split
[(set (match_operand:SF 0 "memory_operand" "")
(abs:SF (match_operand:SF 1 "memory_operand" "")))
- (use (match_operand:SF 2 "" ""))
+ (use (match_operand:V4SF 2 "" ""))
(clobber (reg:CC 17))]
""
[(parallel [(set (match_dup 0)
@@ -9770,7 +10036,7 @@
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(abs:SF (match_operand:SF 1 "register_operand" "")))
- (use (match_operand:SF 2 "" ""))
+ (use (match_operand:V4SF 2 "" ""))
(clobber (reg:CC 17))]
"reload_completed && !SSE_REG_P (operands[0])"
[(parallel [(set (match_dup 0)
@@ -9780,12 +10046,23 @@
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(abs:SF (match_operand:SF 1 "register_operand" "")))
- (use (match_operand:SF 2 "register_operand" ""))
+ (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
(clobber (reg:CC 17))]
"reload_completed && SSE_REG_P (operands[0])"
[(set (subreg:TI (match_dup 0) 0)
- (and:TI (not:TI (subreg:TI (match_dup 2) 0))
- (subreg:TI (match_dup 1) 0)))])
+ (and:TI (match_dup 1)
+ (match_dup 2)))]
+{
+ operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
+ operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
+ if (operands_match_p (operands[0], operands[2]))
+ {
+ rtx tmp;
+ tmp = operands[1];
+ operands[1] = operands[2];
+ operands[2] = tmp;
+ }
+})
;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
;; because of secondary memory needed to reload from class FLOAT_INT_REGS
@@ -9801,7 +10078,7 @@
[(set (match_operand:SF 0 "fp_register_operand" "")
(abs:SF (match_operand:SF 1 "register_operand" "")))
(clobber (reg:CC 17))]
- "TARGET_80387"
+ "TARGET_80387 && reload_completed"
[(set (match_dup 0)
(abs:SF (match_dup 1)))]
"")
@@ -9814,7 +10091,7 @@
[(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
(clobber (reg:CC 17))])]
"operands[1] = gen_int_mode (~0x80000000, SImode);
- operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));")
+ operands[0] = gen_lowpart (SImode, operands[0]);")
(define_split
[(set (match_operand 0 "memory_operand" "")
@@ -9826,8 +10103,7 @@
{
int size = GET_MODE_SIZE (GET_MODE (operands[1]));
- /* XFmode's size is 12, TFmode 16, but only 10 bytes are used. */
- if (size >= 12)
+ if (GET_MODE (operands[1]) == XFmode)
size = 10;
operands[0] = adjust_address (operands[0], QImode, size - 1);
operands[1] = gen_int_mode (~0x80, QImode);
@@ -9848,17 +10124,22 @@
{
/* Using SSE is tricky, since we need bitwise negation of -0
in register. */
- rtx reg = gen_reg_rtx (DFmode);
+ rtx reg = gen_reg_rtx (V2DFmode);
#if HOST_BITS_PER_WIDE_INT >= 64
- rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
+ rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
#else
- rtx imm = immed_double_const (0, 0x80000000, DImode);
+ rtx imm = immed_double_const (~0, ~0x80000000, DImode);
#endif
rtx dest = operands[0];
operands[1] = force_reg (DFmode, operands[1]);
operands[0] = force_reg (DFmode, operands[0]);
- emit_move_insn (reg, gen_lowpart (DFmode, imm));
+
+ /* Produce LONG_DOUBLE with the proper immediate argument. */
+ imm = gen_lowpart (DFmode, imm);
+ reg = force_reg (V2DFmode,
+ gen_rtx_CONST_VECTOR (V2DFmode,
+ gen_rtvec (2, imm, CONST0_RTX (DFmode))));
emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
if (dest != operands[0])
emit_move_insn (dest, operands[0]);
@@ -9875,9 +10156,9 @@
"#")
(define_insn "absdf2_ifs"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr,mr#Yf")
- (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0,0")))
- (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y,*g#Y"))
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
+ (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
+ (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
(clobber (reg:CC 17))]
"!TARGET_64BIT && TARGET_SSE2
&& (reload_in_progress || reload_completed
@@ -9886,9 +10167,9 @@
"#")
(define_insn "*absdf2_ifs_rex64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,mf#Yr")
- (abs:DF (match_operand:DF 1 "nonimmediate_operand" "Y,0")))
- (use (match_operand:DF 2 "nonmemory_operand" "*0#Y,*g#Y"))
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
+ (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
+ (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
(clobber (reg:CC 17))]
"TARGET_64BIT && TARGET_SSE2
&& (reload_in_progress || reload_completed
@@ -9899,7 +10180,7 @@
(define_split
[(set (match_operand:DF 0 "memory_operand" "")
(abs:DF (match_operand:DF 1 "memory_operand" "")))
- (use (match_operand:DF 2 "" ""))
+ (use (match_operand:V2DF 2 "" ""))
(clobber (reg:CC 17))]
""
[(parallel [(set (match_dup 0)
@@ -9909,7 +10190,7 @@
(define_split
[(set (match_operand:DF 0 "register_operand" "")
(abs:DF (match_operand:DF 1 "register_operand" "")))
- (use (match_operand:DF 2 "" ""))
+ (use (match_operand:V2DF 2 "" ""))
(clobber (reg:CC 17))]
"reload_completed && !SSE_REG_P (operands[0])"
[(parallel [(set (match_dup 0)
@@ -9919,12 +10200,27 @@
(define_split
[(set (match_operand:DF 0 "register_operand" "")
(abs:DF (match_operand:DF 1 "register_operand" "")))
- (use (match_operand:DF 2 "register_operand" ""))
+ (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
(clobber (reg:CC 17))]
"reload_completed && SSE_REG_P (operands[0])"
[(set (subreg:TI (match_dup 0) 0)
- (and:TI (not:TI (subreg:TI (match_dup 2) 0))
- (subreg:TI (match_dup 1) 0)))])
+ (and:TI (match_dup 1)
+ (match_dup 2)))]
+{
+ operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
+ operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
+ operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
+ /* Avoid possible reformatting on the operands. */
+ if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
+ emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
+ if (operands_match_p (operands[0], operands[2]))
+ {
+ rtx tmp;
+ tmp = operands[1];
+ operands[1] = operands[2];
+ operands[2] = tmp;
+ }
+})
;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
@@ -9973,15 +10269,8 @@
[(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
(neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
(clobber (reg:CC 17))])]
- "!TARGET_64BIT && TARGET_80387"
- "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
-
-(define_expand "abstf2"
- [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
- (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
- (clobber (reg:CC 17))])]
"TARGET_80387"
- "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
+ "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
;; because of secondary memory needed to reload from class FLOAT_INT_REGS
@@ -9990,7 +10279,7 @@
[(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
(abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
(clobber (reg:CC 17))]
- "!TARGET_64BIT && TARGET_80387
+ "TARGET_80387
&& ix86_unary_operator_ok (ABS, XFmode, operands)"
"#")
@@ -10014,33 +10303,6 @@
operands[0] = gen_rtx_REG (SImode,
true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
-(define_insn "*abstf2_if"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
- (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
- (clobber (reg:CC 17))]
- "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
- "#")
-
-(define_split
- [(set (match_operand:TF 0 "fp_register_operand" "")
- (abs:TF (match_operand:TF 1 "register_operand" "")))
- (clobber (reg:CC 17))]
- "TARGET_80387 && reload_completed"
- [(set (match_dup 0)
- (abs:TF (match_dup 1)))]
- "")
-
-(define_split
- [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
- (abs:TF (match_operand:TF 1 "register_operand" "")))
- (clobber (reg:CC 17))]
- "TARGET_80387 && reload_completed"
- [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
- (clobber (reg:CC 17))])]
- "operands[1] = GEN_INT (~0x8000);
- operands[0] = gen_rtx_REG (SImode,
- true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
-
(define_insn "*abssf2_1"
[(set (match_operand:SF 0 "register_operand" "=f")
(abs:SF (match_operand:SF 1 "register_operand" "0")))]
@@ -10069,7 +10331,7 @@
(define_insn "*absxf2_1"
[(set (match_operand:XF 0 "register_operand" "=f")
(abs:XF (match_operand:XF 1 "register_operand" "0")))]
- "!TARGET_64BIT && TARGET_80387 && reload_completed"
+ "TARGET_80387 && reload_completed"
"fabs"
[(set_attr "type" "fsgn")
(set_attr "mode" "DF")])
@@ -10078,7 +10340,7 @@
[(set (match_operand:XF 0 "register_operand" "=f")
(abs:XF (float_extend:XF
(match_operand:DF 1 "register_operand" "0"))))]
- "!TARGET_64BIT && TARGET_80387"
+ "TARGET_80387"
"fabs"
[(set_attr "type" "fsgn")
(set_attr "mode" "XF")])
@@ -10087,32 +10349,6 @@
[(set (match_operand:XF 0 "register_operand" "=f")
(abs:XF (float_extend:XF
(match_operand:SF 1 "register_operand" "0"))))]
- "!TARGET_64BIT && TARGET_80387"
- "fabs"
- [(set_attr "type" "fsgn")
- (set_attr "mode" "XF")])
-
-(define_insn "*abstf2_1"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (abs:TF (match_operand:TF 1 "register_operand" "0")))]
- "TARGET_80387 && reload_completed"
- "fabs"
- [(set_attr "type" "fsgn")
- (set_attr "mode" "DF")])
-
-(define_insn "*absextenddftf2"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (abs:TF (float_extend:TF
- (match_operand:DF 1 "register_operand" "0"))))]
- "TARGET_80387"
- "fabs"
- [(set_attr "type" "fsgn")
- (set_attr "mode" "XF")])
-
-(define_insn "*absextendsftf2"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (abs:TF (float_extend:TF
- (match_operand:SF 1 "register_operand" "0"))))]
"TARGET_80387"
"fabs"
[(set_attr "type" "fsgn")
@@ -10697,9 +10933,11 @@
(zero_extend:DI (ashift (match_operand 1 "register_operand" "")
(match_operand:QI 2 "const_int_operand" ""))))
(clobber (reg:CC 17))]
- "reload_completed
+ "TARGET_64BIT && reload_completed
&& true_regnum (operands[0]) != true_regnum (operands[1])"
- [(set (match_dup 0) (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
+ [(set (match_dup 0) (zero_extend:DI
+ (subreg:SI (mult:SI (match_dup 1)
+ (match_dup 2)) 0)))]
{
operands[1] = gen_lowpart (Pmode, operands[1]);
operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
@@ -11112,7 +11350,7 @@
(define_insn "*ashrdi3_1_one_bit_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -11142,7 +11380,7 @@
[(set (reg 17)
(compare
(ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" ""))
+ (match_operand:QI 2 "const1_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
@@ -11301,7 +11539,7 @@
(define_insn "*ashrsi3_1_one_bit"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -11315,7 +11553,7 @@
(define_insn "*ashrsi3_1_one_bit_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" ""))))
+ (match_operand:QI 2 "const1_operand" ""))))
(clobber (reg:CC 17))]
"TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -11354,7 +11592,7 @@
[(set (reg 17)
(compare
(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" ""))
+ (match_operand:QI 2 "const1_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(ashiftrt:SI (match_dup 1) (match_dup 2)))]
@@ -11372,7 +11610,7 @@
[(set (reg 17)
(compare
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" ""))
+ (match_operand:QI 2 "const1_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
@@ -11425,7 +11663,7 @@
(define_insn "*ashrhi3_1_one_bit"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -11455,7 +11693,7 @@
[(set (reg 17)
(compare
(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" ""))
+ (match_operand:QI 2 "const1_operand" ""))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(ashiftrt:HI (match_dup 1) (match_dup 2)))]
@@ -11497,7 +11735,7 @@
(define_insn "*ashrqi3_1_one_bit"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -11511,7 +11749,7 @@
(define_insn "*ashrqi3_1_one_bit_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
(ashiftrt:QI (match_dup 0)
- (match_operand:QI 1 "const_int_1_operand" "")))
+ (match_operand:QI 1 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
&& (! TARGET_PARTIAL_REG_STALL || optimize_size)
@@ -11555,7 +11793,7 @@
[(set (reg 17)
(compare
(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "I"))
+ (match_operand:QI 2 "const1_operand" "I"))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(ashiftrt:QI (match_dup 1) (match_dup 2)))]
@@ -11609,7 +11847,7 @@
(define_insn "*lshrdi3_1_one_bit_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -11639,7 +11877,7 @@
[(set (reg 17)
(compare
(lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" ""))
+ (match_operand:QI 2 "const1_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
(lshiftrt:DI (match_dup 1) (match_dup 2)))]
@@ -11719,7 +11957,7 @@
(define_insn "*lshrsi3_1_one_bit"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -11733,7 +11971,7 @@
(define_insn "*lshrsi3_1_one_bit_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -11773,7 +12011,7 @@
[(set (reg 17)
(compare
(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" ""))
+ (match_operand:QI 2 "const1_operand" ""))
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(lshiftrt:SI (match_dup 1) (match_dup 2)))]
@@ -11791,7 +12029,7 @@
[(set (reg 17)
(compare
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" ""))
+ (match_operand:QI 2 "const1_operand" ""))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=r")
(lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
@@ -11844,7 +12082,7 @@
(define_insn "*lshrhi3_1_one_bit"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -11874,7 +12112,7 @@
[(set (reg 17)
(compare
(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" ""))
+ (match_operand:QI 2 "const1_operand" ""))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(lshiftrt:HI (match_dup 1) (match_dup 2)))]
@@ -11916,7 +12154,7 @@
(define_insn "*lshrqi3_1_one_bit"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -11930,7 +12168,7 @@
(define_insn "*lshrqi3_1_one_bit_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
(lshiftrt:QI (match_dup 0)
- (match_operand:QI 1 "const_int_1_operand" "")))
+ (match_operand:QI 1 "const1_operand" "")))
(clobber (reg:CC 17))]
"(! TARGET_PARTIAL_REG_STALL || optimize_size)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -11973,7 +12211,7 @@
[(set (reg 17)
(compare
(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" ""))
+ (match_operand:QI 2 "const1_operand" ""))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(lshiftrt:QI (match_dup 1) (match_dup 2)))]
@@ -12017,7 +12255,7 @@
(define_insn "*rotlsi3_1_one_bit_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
(rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -12051,7 +12289,7 @@
(define_insn "*rotlsi3_1_one_bit"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (ROTATE, SImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -12066,7 +12304,7 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
(rotate:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" ""))))
+ (match_operand:QI 2 "const1_operand" ""))))
(clobber (reg:CC 17))]
"TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -12110,7 +12348,7 @@
(define_insn "*rotlhi3_1_one_bit"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (ROTATE, HImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -12144,7 +12382,7 @@
(define_insn "*rotlqi3_1_one_bit_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
(rotate:QI (match_dup 0)
- (match_operand:QI 1 "const_int_1_operand" "")))
+ (match_operand:QI 1 "const1_operand" "")))
(clobber (reg:CC 17))]
"(! TARGET_PARTIAL_REG_STALL || optimize_size)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -12158,7 +12396,7 @@
(define_insn "*rotlqi3_1_one_bit"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (ROTATE, QImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -12205,7 +12443,7 @@
(define_insn "*rotrdi3_1_one_bit_rex64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
(rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -12239,7 +12477,7 @@
(define_insn "*rotrsi3_1_one_bit"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (ROTATERT, SImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -12254,7 +12492,7 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
(rotatert:SI (match_operand:SI 1 "register_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" ""))))
+ (match_operand:QI 2 "const1_operand" ""))))
(clobber (reg:CC 17))]
"TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -12301,7 +12539,7 @@
(define_insn "*rotrhi3_one_bit"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (ROTATERT, HImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -12335,7 +12573,7 @@
(define_insn "*rotrqi3_1_one_bit"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
- (match_operand:QI 2 "const_int_1_operand" "")))
+ (match_operand:QI 2 "const1_operand" "")))
(clobber (reg:CC 17))]
"ix86_binary_operator_ok (ROTATERT, QImode, operands)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -12349,7 +12587,7 @@
(define_insn "*rotrqi3_1_one_bit_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
(rotatert:QI (match_dup 0)
- (match_operand:QI 1 "const_int_1_operand" "")))
+ (match_operand:QI 1 "const1_operand" "")))
(clobber (reg:CC 17))]
"(! TARGET_PARTIAL_REG_STALL || optimize_size)
&& (TARGET_SHIFT1 || optimize_size)"
@@ -12422,10 +12660,10 @@
})
(define_expand "insv"
- [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
- (match_operand:SI 1 "immediate_operand" "")
- (match_operand:SI 2 "immediate_operand" ""))
- (match_operand:SI 3 "register_operand" ""))]
+ [(set (zero_extract (match_operand 0 "ext_register_operand" "")
+ (match_operand 1 "immediate_operand" "")
+ (match_operand 2 "immediate_operand" ""))
+ (match_operand 3 "register_operand" ""))]
""
{
/* Handle extractions from %ah et al. */
@@ -12436,6 +12674,13 @@
matches the predicate, so check it again here. */
if (! register_operand (operands[0], VOIDmode))
FAIL;
+
+ if (TARGET_64BIT)
+ emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
+ else
+ emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
+
+ DONE;
})
;; %%% bts, btr, btc, bt.
@@ -12648,7 +12893,7 @@
;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
;; subsequent logical operations are used to imitate conditional moves.
;; 0xffffffff is NaN, but not in normalized form, so we can't represent
-;; it directly. Futher holding this value in pseudo register might bring
+;; it directly. Further holding this value in pseudo register might bring
;; problem in implicit normalization in spill code.
;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
;; instructions after reload by splitting the conditional move patterns.
@@ -13321,7 +13566,7 @@
(match_dup 2))]
{
operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
- operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
+ operands[5] = gen_lowpart (QImode, operands[3]);
ix86_expand_clear (operands[3]);
})
@@ -13343,7 +13588,7 @@
(match_dup 2))]
{
operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
- operands[5] = gen_rtx_REG (QImode, REGNO (operands[3]));
+ operands[5] = gen_lowpart (QImode, operands[3]);
ix86_expand_clear (operands[3]);
})
@@ -13363,7 +13608,7 @@
(match_operand:SI 3 "" "")))])]
"!TARGET_64BIT"
{
- ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3]);
+ ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
DONE;
})
@@ -13408,7 +13653,17 @@
(use (match_operand 2 "" ""))]
""
{
- ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL);
+ ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
+ DONE;
+})
+
+(define_expand "sibcall"
+ [(call (match_operand:QI 0 "" "")
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))]
+ ""
+{
+ ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
DONE;
})
@@ -13427,41 +13682,51 @@
(define_insn "*call_1"
[(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
(match_operand 1 "" ""))]
- "!TARGET_64BIT"
+ "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
{
if (constant_call_address_operand (operands[0], QImode))
- {
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P0";
- else
- return "call\t%P0";
- }
- if (SIBLING_CALL_P (insn))
- return "jmp\t%A0";
- else
- return "call\t%A0";
+ return "call\t%P0";
+ return "call\t%A0";
+}
+ [(set_attr "type" "call")])
+
+(define_insn "*sibcall_1"
+ [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
+ (match_operand 1 "" ""))]
+ "SIBLING_CALL_P (insn) && !TARGET_64BIT"
+{
+ if (constant_call_address_operand (operands[0], QImode))
+ return "jmp\t%P0";
+ return "jmp\t%A0";
}
[(set_attr "type" "call")])
(define_insn "*call_1_rex64"
[(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
(match_operand 1 "" ""))]
- "TARGET_64BIT"
+ "!SIBLING_CALL_P (insn) && TARGET_64BIT"
{
if (constant_call_address_operand (operands[0], QImode))
- {
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P0";
- else
- return "call\t%P0";
- }
- if (SIBLING_CALL_P (insn))
- return "jmp\t%A0";
- else
- return "call\t%A0";
+ return "call\t%P0";
+ return "call\t%A0";
}
[(set_attr "type" "call")])
+(define_insn "*sibcall_1_rex64"
+ [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
+ (match_operand 1 "" ""))]
+ "SIBLING_CALL_P (insn) && TARGET_64BIT"
+ "jmp\t%P0"
+ [(set_attr "type" "call")])
+
+(define_insn "*sibcall_1_rex64_v"
+ [(call (mem:QI (reg:DI 40))
+ (match_operand 0 "" ""))]
+ "SIBLING_CALL_P (insn) && TARGET_64BIT"
+ "jmp\t*%%r11"
+ [(set_attr "type" "call")])
+
+
;; Call subroutine, returning value in operand 0
(define_expand "call_value_pop"
@@ -13474,7 +13739,7 @@
"!TARGET_64BIT"
{
ix86_expand_call (operands[0], operands[1], operands[2],
- operands[3], operands[4]);
+ operands[3], operands[4], 0);
DONE;
})
@@ -13486,7 +13751,19 @@
;; Operand 2 not used on the i386.
""
{
- ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL);
+ ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
+ DONE;
+})
+
+(define_expand "sibcall_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "" "")
+ (match_operand:SI 2 "" "")))
+ (use (match_operand:SI 3 "" ""))]
+ ;; Operand 2 not used on the i386.
+ ""
+{
+ ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
DONE;
})
@@ -13509,7 +13786,7 @@
ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
- NULL);
+ NULL, 0);
for (i = 0; i < XVECLEN (operands[2], 0); i++)
{
@@ -13561,6 +13838,19 @@
(set_attr "length_immediate" "0")
(set_attr "modrm" "0")])
+;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
+;; instruction Athlon and K8 have.
+
+(define_insn "return_internal_long"
+ [(return)
+ (unspec [(const_int 0)] UNSPEC_REP)]
+ "reload_completed"
+ "rep {;} ret"
+ [(set_attr "length" "1")
+ (set_attr "length_immediate" "0")
+ (set_attr "prefix_rep" "1")
+ (set_attr "modrm" "0")])
+
(define_insn "return_pop_internal"
[(return)
(use (match_operand:SI 0 "const_int_operand" ""))]
@@ -13587,6 +13877,26 @@
(set_attr "modrm" "0")
(set_attr "ppro_uops" "one")])
+;; Align 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"
+ [(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]));
+#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
+ branch prediction and the benefits hardly outweight the cost of extra 8
+ nops on the average inserted by full alignment pseudo operation. */
+#endif
+ return "";
+}
+ [(set_attr "length" "16")])
+
(define_expand "prologue"
[(const_int 1)]
""
@@ -13657,11 +13967,7 @@
(clobber (mem:BLK (scratch)))]
"!TARGET_64BIT"
"leave"
- [(set_attr "length_immediate" "0")
- (set_attr "length" "1")
- (set_attr "modrm" "0")
- (set_attr "athlon_decode" "vector")
- (set_attr "ppro_uops" "few")])
+ [(set_attr "type" "leave")])
(define_insn "leave_rex64"
[(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
@@ -13669,111 +13975,100 @@
(clobber (mem:BLK (scratch)))]
"TARGET_64BIT"
"leave"
- [(set_attr "length_immediate" "0")
- (set_attr "length" "1")
- (set_attr "modrm" "0")
- (set_attr "athlon_decode" "vector")
- (set_attr "ppro_uops" "few")])
+ [(set_attr "type" "leave")])
(define_expand "ffssi2"
- [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
+ (clobber (match_scratch:SI 2 ""))
+ (clobber (reg:CC 17))])]
""
-{
- rtx out = gen_reg_rtx (SImode), tmp = gen_reg_rtx (SImode);
- rtx in = operands[1];
+ "")
- if (TARGET_CMOVE)
- {
- emit_move_insn (tmp, constm1_rtx);
- emit_insn (gen_ffssi_1 (out, in));
- emit_insn (gen_rtx_SET (VOIDmode, out,
- gen_rtx_IF_THEN_ELSE (SImode,
- gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
- const0_rtx),
- tmp,
- out)));
- emit_insn (gen_addsi3 (out, out, const1_rtx));
- emit_move_insn (operands[0], out);
- }
+(define_insn_and_split "*ffs_cmove"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
+ (clobber (match_scratch:SI 2 "=&r"))
+ (clobber (reg:CC 17))]
+ "TARGET_CMOVE"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 2) (const_int -1))
+ (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
+ (set (match_dup 0) (ctz:SI (match_dup 1)))])
+ (set (match_dup 0) (if_then_else:SI
+ (eq (reg:CCZ 17) (const_int 0))
+ (match_dup 2)
+ (match_dup 0)))
+ (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
+ (clobber (reg:CC 17))])]
+ "")
- /* Pentium bsf instruction is extremly slow. The following code is
- recommended by the Intel Optimizing Manual as a reasonable replacement:
- TEST EAX,EAX
- JZ SHORT BS2
- XOR ECX,ECX
- MOV DWORD PTR [TEMP+4],ECX
- SUB ECX,EAX
- AND EAX,ECX
- MOV DWORD PTR [TEMP],EAX
- FILD QWORD PTR [TEMP]
- FSTP QWORD PTR [TEMP]
- WAIT ; WAIT only needed for compatibility with
- ; earlier processors
- MOV ECX, DWORD PTR [TEMP+4]
- SHR ECX,20
- SUB ECX,3FFH
- TEST EAX,EAX ; clear zero flag
- BS2:
- Following piece of code expand ffs to similar beast.
- */
-
- else if (TARGET_PENTIUM && !optimize_size && TARGET_80387)
- {
- rtx label = gen_label_rtx ();
- rtx lo, hi;
- rtx mem = assign_386_stack_local (DImode, 0);
- rtx fptmp = gen_reg_rtx (DFmode);
- split_di (&mem, 1, &lo, &hi);
-
- emit_move_insn (out, const0_rtx);
-
- emit_cmp_and_jump_insns (in, const0_rtx, EQ, 0, SImode, 1, label);
-
- emit_move_insn (hi, out);
- emit_insn (gen_subsi3 (out, out, in));
- emit_insn (gen_andsi3 (out, out, in));
- emit_move_insn (lo, out);
- emit_insn (gen_floatdidf2 (fptmp,mem));
- emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
- emit_move_insn (out, hi);
- emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
- emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
-
- emit_label (label);
- LABEL_NUSES (label) = 1;
-
- emit_move_insn (operands[0], out);
- }
- else
- {
- emit_move_insn (tmp, const0_rtx);
- emit_insn (gen_ffssi_1 (out, in));
- emit_insn (gen_rtx_SET (VOIDmode,
- gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
- gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
- const0_rtx)));
- emit_insn (gen_negsi2 (tmp, tmp));
- emit_insn (gen_iorsi3 (out, out, tmp));
- emit_insn (gen_addsi3 (out, out, const1_rtx));
- emit_move_insn (operands[0], out);
- }
- DONE;
+(define_insn_and_split "*ffs_no_cmove"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
+ (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
+ (clobber (match_scratch:SI 2 "=&q"))
+ (clobber (reg:CC 17))]
+ ""
+ "#"
+ "reload_completed"
+ [(parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
+ (set (match_dup 0) (ctz:SI (match_dup 1)))])
+ (set (strict_low_part (match_dup 3))
+ (eq:QI (reg:CCZ 17) (const_int 0)))
+ (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
+ (clobber (reg:CC 17))])
+ (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
+ (clobber (reg:CC 17))])
+ (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
+ (clobber (reg:CC 17))])]
+{
+ operands[3] = gen_lowpart (QImode, operands[2]);
+ ix86_expand_clear (operands[2]);
})
-(define_insn "ffssi_1"
+(define_insn "*ffssi_1"
[(set (reg:CCZ 17)
- (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
+ (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
(const_int 0)))
(set (match_operand:SI 0 "register_operand" "=r")
- (unspec:SI [(match_dup 1)] UNSPEC_BSF))]
+ (ctz:SI (match_dup 1)))]
+ ""
+ "bsf{l}\t{%1, %0|%0, %1}"
+ [(set_attr "prefix_0f" "1")
+ (set_attr "ppro_uops" "few")])
+
+(define_insn "ctzsi2"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
+ (clobber (reg:CC 17))]
""
"bsf{l}\t{%1, %0|%0, %1}"
[(set_attr "prefix_0f" "1")
(set_attr "ppro_uops" "few")])
-;; ffshi2 is not useful -- 4 word prefix ops are needed, which is larger
-;; and slower than the two-byte movzx insn needed to do the work in SImode.
+(define_expand "clzsi2"
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (minus:SI (const_int 31)
+ (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
+ (clobber (reg:CC 17))])
+ (parallel
+ [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
+ (clobber (reg:CC 17))])]
+ ""
+ "")
+
+(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 17))]
+ ""
+ "bsr{l}\t{%1, %0|%0, %1}"
+ [(set_attr "prefix_0f" "1")
+ (set_attr "ppro_uops" "few")])
;; Thread-local storage patterns for ELF.
;;
@@ -13941,6 +14236,56 @@
(clobber (match_dup 5))
(clobber (reg:CC 17))])]
"")
+
+;; Load and add the thread base pointer from %gs:0.
+
+(define_insn "*load_tp_si"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(const_int 0)] UNSPEC_TP))]
+ "!TARGET_64BIT"
+ "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
+ [(set_attr "type" "imov")
+ (set_attr "modrm" "0")
+ (set_attr "length" "7")
+ (set_attr "memory" "load")
+ (set_attr "imm_disp" "false")])
+
+(define_insn "*add_tp_si"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
+ (match_operand:SI 1 "register_operand" "0")))
+ (clobber (reg:CC 17))]
+ "!TARGET_64BIT"
+ "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
+ [(set_attr "type" "alu")
+ (set_attr "modrm" "0")
+ (set_attr "length" "7")
+ (set_attr "memory" "load")
+ (set_attr "imm_disp" "false")])
+
+(define_insn "*load_tp_di"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(const_int 0)] UNSPEC_TP))]
+ "TARGET_64BIT"
+ "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
+ [(set_attr "type" "imov")
+ (set_attr "modrm" "0")
+ (set_attr "length" "7")
+ (set_attr "memory" "load")
+ (set_attr "imm_disp" "false")])
+
+(define_insn "*add_tp_di"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
+ (match_operand:DI 1 "register_operand" "0")))
+ (clobber (reg:CC 17))]
+ "TARGET_64BIT"
+ "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
+ [(set_attr "type" "alu")
+ (set_attr "modrm" "0")
+ (set_attr "length" "7")
+ (set_attr "memory" "load")
+ (set_attr "imm_disp" "false")])
;; These patterns match the binary 387 instructions for addM3, subM3,
;; mulM3 and divM3. There are three patterns for each of DFmode and
@@ -14054,7 +14399,7 @@
(match_operator:XF 3 "binary_fp_operator"
[(match_operand:XF 1 "register_operand" "%0")
(match_operand:XF 2 "register_operand" "f")]))]
- "!TARGET_64BIT && TARGET_80387
+ "TARGET_80387
&& GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
@@ -14063,19 +14408,6 @@
(const_string "fop")))
(set_attr "mode" "XF")])
-(define_insn "*fop_tf_comm"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (match_operator:TF 3 "binary_fp_operator"
- [(match_operand:TF 1 "register_operand" "%0")
- (match_operand:TF 2 "register_operand" "f")]))]
- "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (if_then_else (match_operand:TF 3 "mult_operator" "")
- (const_string "fmul")
- (const_string "fop")))
- (set_attr "mode" "XF")])
-
(define_insn "*fop_sf_1_nosse"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(match_operator:SF 3 "binary_fp_operator"
@@ -14307,35 +14639,36 @@
(const_string "fop")))
(set_attr "mode" "SF")])
-(define_insn "*fop_xf_1"
- [(set (match_operand:XF 0 "register_operand" "=f,f")
- (match_operator:XF 3 "binary_fp_operator"
- [(match_operand:XF 1 "register_operand" "0,f")
- (match_operand:XF 2 "register_operand" "f,0")]))]
- "!TARGET_64BIT && TARGET_80387
- && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
+(define_insn "*fop_df_6"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (match_operator:DF 3 "binary_fp_operator"
+ [(float_extend:DF
+ (match_operand:SF 1 "register_operand" "0,f"))
+ (float_extend:DF
+ (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
+ "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
- (cond [(match_operand:XF 3 "mult_operator" "")
+ (cond [(match_operand:DF 3 "mult_operator" "")
(const_string "fmul")
- (match_operand:XF 3 "div_operator" "")
+ (match_operand:DF 3 "div_operator" "")
(const_string "fdiv")
]
(const_string "fop")))
- (set_attr "mode" "XF")])
+ (set_attr "mode" "SF")])
-(define_insn "*fop_tf_1"
- [(set (match_operand:TF 0 "register_operand" "=f,f")
- (match_operator:TF 3 "binary_fp_operator"
- [(match_operand:TF 1 "register_operand" "0,f")
- (match_operand:TF 2 "register_operand" "f,0")]))]
+(define_insn "*fop_xf_1"
+ [(set (match_operand:XF 0 "register_operand" "=f,f")
+ (match_operator:XF 3 "binary_fp_operator"
+ [(match_operand:XF 1 "register_operand" "0,f")
+ (match_operand:XF 2 "register_operand" "f,0")]))]
"TARGET_80387
&& GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
- (cond [(match_operand:TF 3 "mult_operator" "")
+ (cond [(match_operand:XF 3 "mult_operator" "")
(const_string "fmul")
- (match_operand:TF 3 "div_operator" "")
+ (match_operand:XF 3 "div_operator" "")
(const_string "fdiv")
]
(const_string "fop")))
@@ -14346,7 +14679,7 @@
(match_operator:XF 3 "binary_fp_operator"
[(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
(match_operand:XF 2 "register_operand" "0,0")]))]
- "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
+ "TARGET_80387 && TARGET_USE_FIOP"
"* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
[(set (attr "type")
(cond [(match_operand:XF 3 "mult_operator" "")
@@ -14359,30 +14692,12 @@
(set_attr "mode" "SI")
(set_attr "ppro_uops" "many")])
-(define_insn "*fop_tf_2"
- [(set (match_operand:TF 0 "register_operand" "=f,f")
- (match_operator:TF 3 "binary_fp_operator"
- [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
- (match_operand:TF 2 "register_operand" "0,0")]))]
- "TARGET_80387 && TARGET_USE_FIOP"
- "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:TF 3 "mult_operator" "")
- (const_string "fmul")
- (match_operand:TF 3 "div_operator" "")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "fp_int_src" "true")
- (set_attr "mode" "SI")
- (set_attr "ppro_uops" "many")])
-
(define_insn "*fop_xf_3"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_fp_operator"
[(match_operand:XF 1 "register_operand" "0,0")
(float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
- "!TARGET_64BIT && TARGET_80387 && TARGET_USE_FIOP"
+ "TARGET_80387 && TARGET_USE_FIOP"
"* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
[(set (attr "type")
(cond [(match_operand:XF 3 "mult_operator" "")
@@ -14395,30 +14710,12 @@
(set_attr "mode" "SI")
(set_attr "ppro_uops" "many")])
-(define_insn "*fop_tf_3"
- [(set (match_operand:TF 0 "register_operand" "=f,f")
- (match_operator:TF 3 "binary_fp_operator"
- [(match_operand:TF 1 "register_operand" "0,0")
- (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
- "TARGET_80387 && TARGET_USE_FIOP"
- "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:TF 3 "mult_operator" "")
- (const_string "fmul")
- (match_operand:TF 3 "div_operator" "")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "fp_int_src" "true")
- (set_attr "mode" "SI")
- (set_attr "ppro_uops" "many")])
-
(define_insn "*fop_xf_4"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_fp_operator"
- [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
+ [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
(match_operand:XF 2 "register_operand" "0,f")]))]
- "!TARGET_64BIT && TARGET_80387"
+ "TARGET_80387"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(cond [(match_operand:XF 3 "mult_operator" "")
@@ -14429,29 +14726,13 @@
(const_string "fop")))
(set_attr "mode" "SF")])
-(define_insn "*fop_tf_4"
- [(set (match_operand:TF 0 "register_operand" "=f,f")
- (match_operator:TF 3 "binary_fp_operator"
- [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
- (match_operand:TF 2 "register_operand" "0,f")]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:TF 3 "mult_operator" "")
- (const_string "fmul")
- (match_operand:TF 3 "div_operator" "")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "SF")])
-
(define_insn "*fop_xf_5"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_fp_operator"
[(match_operand:XF 1 "register_operand" "0,f")
(float_extend:XF
- (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
- "!TARGET_64BIT && TARGET_80387"
+ (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
+ "TARGET_80387"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(cond [(match_operand:XF 3 "mult_operator" "")
@@ -14462,62 +14743,14 @@
(const_string "fop")))
(set_attr "mode" "SF")])
-(define_insn "*fop_tf_5"
- [(set (match_operand:TF 0 "register_operand" "=f,f")
- (match_operator:TF 3 "binary_fp_operator"
- [(match_operand:TF 1 "register_operand" "0,f")
- (float_extend:TF
- (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:TF 3 "mult_operator" "")
- (const_string "fmul")
- (match_operand:TF 3 "div_operator" "")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "SF")])
-
(define_insn "*fop_xf_6"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_fp_operator"
- [(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
- (match_operand:XF 2 "register_operand" "0,f")]))]
- "!TARGET_64BIT && TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:XF 3 "mult_operator" "")
- (const_string "fmul")
- (match_operand:XF 3 "div_operator" "")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "DF")])
-
-(define_insn "*fop_tf_6"
- [(set (match_operand:TF 0 "register_operand" "=f,f")
- (match_operator:TF 3 "binary_fp_operator"
- [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
- (match_operand:TF 2 "register_operand" "0,f")]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:TF 3 "mult_operator" "")
- (const_string "fmul")
- (match_operand:TF 3 "div_operator" "")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "DF")])
-
-(define_insn "*fop_xf_7"
- [(set (match_operand:XF 0 "register_operand" "=f,f")
- (match_operator:XF 3 "binary_fp_operator"
- [(match_operand:XF 1 "register_operand" "0,f")
+ [(float_extend:XF
+ (match_operand 1 "register_operand" "0,f"))
(float_extend:XF
- (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
- "!TARGET_64BIT && TARGET_80387"
+ (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
+ "TARGET_80387"
"* return output_387_binary_op (insn, operands);"
[(set (attr "type")
(cond [(match_operand:XF 3 "mult_operator" "")
@@ -14526,24 +14759,7 @@
(const_string "fdiv")
]
(const_string "fop")))
- (set_attr "mode" "DF")])
-
-(define_insn "*fop_tf_7"
- [(set (match_operand:TF 0 "register_operand" "=f,f")
- (match_operator:TF 3 "binary_fp_operator"
- [(match_operand:TF 1 "register_operand" "0,f")
- (float_extend:TF
- (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
- "TARGET_80387"
- "* return output_387_binary_op (insn, operands);"
- [(set (attr "type")
- (cond [(match_operand:TF 3 "mult_operator" "")
- (const_string "fmul")
- (match_operand:TF 3 "div_operator" "")
- (const_string "fdiv")
- ]
- (const_string "fop")))
- (set_attr "mode" "DF")])
+ (set_attr "mode" "SF")])
(define_split
[(set (match_operand 0 "register_operand" "")
@@ -14682,17 +14898,7 @@
(define_insn "sqrtxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
(sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
- "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
- && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
- "fsqrt"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")
- (set_attr "athlon_decode" "direct")])
-
-(define_insn "sqrttf2"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
- "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
&& (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
"fsqrt"
[(set_attr "type" "fpspc")
@@ -14703,17 +14909,7 @@
[(set (match_operand:XF 0 "register_operand" "=f")
(sqrt:XF (float_extend:XF
(match_operand:DF 1 "register_operand" "0"))))]
- "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
- "fsqrt"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")
- (set_attr "athlon_decode" "direct")])
-
-(define_insn "*sqrtextenddftf2"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (sqrt:TF (float_extend:TF
- (match_operand:DF 1 "register_operand" "0"))))]
- "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
+ "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
"fsqrt"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")
@@ -14723,17 +14919,7 @@
[(set (match_operand:XF 0 "register_operand" "=f")
(sqrt:XF (float_extend:XF
(match_operand:SF 1 "register_operand" "0"))))]
- "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
- "fsqrt"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")
- (set_attr "athlon_decode" "direct")])
-
-(define_insn "*sqrtextendsftf2"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (sqrt:TF (float_extend:TF
- (match_operand:SF 1 "register_operand" "0"))))]
- "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
+ "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
"fsqrt"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")
@@ -14771,16 +14957,7 @@
(define_insn "sinxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
- "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
- "fsin"
- [(set_attr "type" "fpspc")
- (set_attr "mode" "XF")])
-
-(define_insn "sintf2"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
- "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
"fsin"
[(set_attr "type" "fpspc")
@@ -14818,20 +14995,333 @@
(define_insn "cosxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
- "!TARGET_64BIT && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
"fcos"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")])
-(define_insn "costf2"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
- "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+(define_insn "atan2df3_1"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (unspec:DF [(match_operand:DF 2 "register_operand" "0")
+ (match_operand:DF 1 "register_operand" "u")]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:DF 3 "=1"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
&& flag_unsafe_math_optimizations"
- "fcos"
+ "fpatan"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "DF")])
+
+(define_expand "atan2df3"
+ [(use (match_operand:DF 0 "register_operand" "=f"))
+ (use (match_operand:DF 2 "register_operand" "0"))
+ (use (match_operand:DF 1 "register_operand" "u"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx copy = gen_reg_rtx (DFmode);
+ emit_move_insn (copy, operands[1]);
+ emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
+ DONE;
+})
+
+(define_insn "atan2sf3_1"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (unspec:SF [(match_operand:SF 2 "register_operand" "0")
+ (match_operand:SF 1 "register_operand" "u")]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:SF 3 "=1"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fpatan"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "SF")])
+
+(define_expand "atan2sf3"
+ [(use (match_operand:SF 0 "register_operand" "=f"))
+ (use (match_operand:SF 2 "register_operand" "0"))
+ (use (match_operand:SF 1 "register_operand" "u"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx copy = gen_reg_rtx (SFmode);
+ emit_move_insn (copy, operands[1]);
+ emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
+ DONE;
+})
+
+(define_insn "atan2xf3_1"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")
+ (match_operand:XF 1 "register_operand" "u")]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:XF 3 "=1"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fpatan"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+(define_expand "atan2xf3"
+ [(use (match_operand:XF 0 "register_operand" "=f"))
+ (use (match_operand:XF 2 "register_operand" "0"))
+ (use (match_operand:XF 1 "register_operand" "u"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx copy = gen_reg_rtx (XFmode);
+ emit_move_insn (copy, operands[1]);
+ emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
+ DONE;
+})
+
+(define_insn "*fyl2x_sfxf3"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (unspec:SF [(match_operand:SF 2 "register_operand" "0")
+ (match_operand:XF 1 "register_operand" "u")]
+ UNSPEC_FYL2X))
+ (clobber (match_scratch:SF 3 "=1"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fyl2x"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "SF")])
+
+(define_insn "*fyl2x_dfxf3"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (unspec:DF [(match_operand:DF 2 "register_operand" "0")
+ (match_operand:XF 1 "register_operand" "u")]
+ UNSPEC_FYL2X))
+ (clobber (match_scratch:DF 3 "=1"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fyl2x"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "DF")])
+
+(define_insn "*fyl2x_xf3"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")
+ (match_operand:XF 1 "register_operand" "u")]
+ UNSPEC_FYL2X))
+ (clobber (match_scratch:XF 3 "=1"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fyl2x"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+(define_expand "logsf2"
+ [(parallel [(set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_operand:SF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:SF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+
+ operands[2] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (4); /* fldln2 */
+ emit_move_insn (operands[2], temp);
+})
+
+(define_expand "logdf2"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_operand:DF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:DF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+
+ operands[2] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (4); /* fldln2 */
+ emit_move_insn (operands[2], temp);
+})
+
+(define_expand "logxf2"
+ [(parallel [(set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:XF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+
+ operands[2] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (4); /* fldln2 */
+ emit_move_insn (operands[2], temp);
+})
+
+(define_insn "*fscale_sfxf3"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (unspec:SF [(match_operand:XF 2 "register_operand" "0")
+ (match_operand:XF 1 "register_operand" "u")]
+ UNSPEC_FSCALE))
+ (clobber (match_scratch:SF 3 "=1"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fscale\;fstp\t%y1"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "SF")])
+
+(define_insn "*fscale_dfxf3"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (unspec:DF [(match_operand:XF 2 "register_operand" "0")
+ (match_operand:XF 1 "register_operand" "u")]
+ UNSPEC_FSCALE))
+ (clobber (match_scratch:DF 3 "=1"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fscale\;fstp\t%y1"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "DF")])
+
+(define_insn "*fscale_xf3"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")
+ (match_operand:XF 1 "register_operand" "u")]
+ UNSPEC_FSCALE))
+ (clobber (match_scratch:XF 3 "=1"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fscale\;fstp\t%y1"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")])
+
+(define_insn "*frndintxf2"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+ UNSPEC_FRNDINT))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "frndint"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+(define_insn "*f2xm1xf2"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+ UNSPEC_F2XM1))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "f2xm1"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+(define_expand "expsf2"
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+ (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
+ (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
+ (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
+ (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
+ (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
+ (parallel [(set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
+ (clobber (match_scratch:SF 5 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+ int i;
+
+ for (i=2; i<10; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (5); /* fldl2e */
+ emit_move_insn (operands[3], temp);
+ emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_expand "expdf2"
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+ (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
+ (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
+ (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
+ (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
+ (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
+ (parallel [(set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_dup 9) (match_dup 5)] UNSPEC_FSCALE))
+ (clobber (match_scratch:DF 5 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+ int i;
+
+ for (i=2; i<10; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (5); /* fldl2e */
+ emit_move_insn (operands[3], temp);
+ emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_expand "expxf2"
+ [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
+ (match_dup 2)))
+ (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
+ (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
+ (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
+ (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
+ (parallel [(set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_dup 8) (match_dup 4)] UNSPEC_FSCALE))
+ (clobber (match_scratch:XF 5 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+ int i;
+
+ for (i=2; i<9; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (5); /* fldl2e */
+ emit_move_insn (operands[2], temp);
+ emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_expand "atansf2"
+ [(parallel [(set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_dup 2)
+ (match_operand:SF 1 "register_operand" "")]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:SF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (SFmode);
+ emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
+})
+
+(define_expand "atandf2"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_dup 2)
+ (match_operand:DF 1 "register_operand" "")]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:DF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (DFmode);
+ emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
+})
+
+(define_expand "atanxf2"
+ [(parallel [(set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_dup 2)
+ (match_operand:XF 1 "register_operand" "")]
+ UNSPEC_FPATAN))
+ (clobber (match_scratch:XF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
+})
;; Block operation instructions
@@ -14846,7 +15336,7 @@
(use (match_operand:BLK 1 "memory_operand" ""))
(use (match_operand:SI 2 "nonmemory_operand" ""))
(use (match_operand:SI 3 "const_int_operand" ""))]
- ""
+ "! optimize_size"
{
if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
DONE;
@@ -14870,170 +15360,45 @@
;; Most CPUs don't like single string operations
;; Handle this case here to simplify previous expander.
-(define_expand "strmovdi_rex64"
- [(set (match_dup 2)
- (mem:DI (match_operand:DI 1 "register_operand" "")))
- (set (mem:DI (match_operand:DI 0 "register_operand" ""))
- (match_dup 2))
- (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
+(define_expand "strmov"
+ [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
+ (set (match_operand 1 "memory_operand" "") (match_dup 4))
+ (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
(clobber (reg:CC 17))])
- (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
- (clobber (reg:CC 17))])]
- "TARGET_64BIT"
-{
- if (TARGET_SINGLE_STRINGOP || optimize_size)
- {
- emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
- operands[1]));
- DONE;
- }
- else
- operands[2] = gen_reg_rtx (DImode);
-})
-
-
-(define_expand "strmovsi"
- [(set (match_dup 2)
- (mem:SI (match_operand:SI 1 "register_operand" "")))
- (set (mem:SI (match_operand:SI 0 "register_operand" ""))
- (match_dup 2))
- (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
- (clobber (reg:CC 17))])
- (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
+ (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
(clobber (reg:CC 17))])]
""
{
- if (TARGET_64BIT)
- {
- emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
- DONE;
- }
- if (TARGET_SINGLE_STRINGOP || optimize_size)
- {
- emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
- operands[1]));
- DONE;
- }
- else
- operands[2] = gen_reg_rtx (SImode);
-})
+ rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
-(define_expand "strmovsi_rex64"
- [(set (match_dup 2)
- (mem:SI (match_operand:DI 1 "register_operand" "")))
- (set (mem:SI (match_operand:DI 0 "register_operand" ""))
- (match_dup 2))
- (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
- (clobber (reg:CC 17))])
- (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
- (clobber (reg:CC 17))])]
- "TARGET_64BIT"
-{
- if (TARGET_SINGLE_STRINGOP || optimize_size)
- {
- emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
- operands[1]));
- DONE;
- }
- else
- operands[2] = gen_reg_rtx (SImode);
-})
+ /* If .md ever supports :P for Pmode, these can be directly
+ in the pattern above. */
+ operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
+ operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
-(define_expand "strmovhi"
- [(set (match_dup 2)
- (mem:HI (match_operand:SI 1 "register_operand" "")))
- (set (mem:HI (match_operand:SI 0 "register_operand" ""))
- (match_dup 2))
- (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
- (clobber (reg:CC 17))])
- (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
- (clobber (reg:CC 17))])]
- ""
-{
- if (TARGET_64BIT)
- {
- emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
- DONE;
- }
if (TARGET_SINGLE_STRINGOP || optimize_size)
{
- emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
- operands[1]));
+ emit_insn (gen_strmov_singleop (operands[0], operands[1],
+ operands[2], operands[3],
+ operands[5], operands[6]));
DONE;
}
- else
- operands[2] = gen_reg_rtx (HImode);
-})
-(define_expand "strmovhi_rex64"
- [(set (match_dup 2)
- (mem:HI (match_operand:DI 1 "register_operand" "")))
- (set (mem:HI (match_operand:DI 0 "register_operand" ""))
- (match_dup 2))
- (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
- (clobber (reg:CC 17))])
- (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
- (clobber (reg:CC 17))])]
- "TARGET_64BIT"
-{
- if (TARGET_SINGLE_STRINGOP || optimize_size)
- {
- emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
- operands[1]));
- DONE;
- }
- else
- operands[2] = gen_reg_rtx (HImode);
+ operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
})
-(define_expand "strmovqi"
- [(set (match_dup 2)
- (mem:QI (match_operand:SI 1 "register_operand" "")))
- (set (mem:QI (match_operand:SI 0 "register_operand" ""))
- (match_dup 2))
- (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
- (clobber (reg:CC 17))])
- (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
- (clobber (reg:CC 17))])]
- ""
-{
- if (TARGET_64BIT)
- {
- emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
- DONE;
- }
- if (TARGET_SINGLE_STRINGOP || optimize_size)
- {
- emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
- operands[1]));
- DONE;
- }
- else
- operands[2] = gen_reg_rtx (QImode);
-})
-
-(define_expand "strmovqi_rex64"
- [(set (match_dup 2)
- (mem:QI (match_operand:DI 1 "register_operand" "")))
- (set (mem:QI (match_operand:DI 0 "register_operand" ""))
- (match_dup 2))
- (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
- (clobber (reg:CC 17))])
- (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
- (clobber (reg:CC 17))])]
- "TARGET_64BIT"
-{
- if (TARGET_SINGLE_STRINGOP || optimize_size)
- {
- emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
- operands[1]));
- DONE;
- }
- else
- operands[2] = gen_reg_rtx (QImode);
-})
+(define_expand "strmov_singleop"
+ [(parallel [(set (match_operand 1 "memory_operand" "")
+ (match_operand 3 "memory_operand" ""))
+ (set (match_operand 0 "register_operand" "")
+ (match_operand 4 "" ""))
+ (set (match_operand 2 "register_operand" "")
+ (match_operand 5 "" ""))
+ (use (reg:SI 19))])]
+ "TARGET_SINGLE_STRINGOP || optimize_size"
+ "")
-(define_insn "strmovdi_rex_1"
+(define_insn "*strmovdi_rex_1"
[(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
(mem:DI (match_operand:DI 3 "register_operand" "1")))
(set (match_operand:DI 0 "register_operand" "=D")
@@ -15049,7 +15414,7 @@
(set_attr "mode" "DI")
(set_attr "memory" "both")])
-(define_insn "strmovsi_1"
+(define_insn "*strmovsi_1"
[(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
(mem:SI (match_operand:SI 3 "register_operand" "1")))
(set (match_operand:SI 0 "register_operand" "=D")
@@ -15065,7 +15430,7 @@
(set_attr "mode" "SI")
(set_attr "memory" "both")])
-(define_insn "strmovsi_rex_1"
+(define_insn "*strmovsi_rex_1"
[(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
(mem:SI (match_operand:DI 3 "register_operand" "1")))
(set (match_operand:DI 0 "register_operand" "=D")
@@ -15081,7 +15446,7 @@
(set_attr "mode" "SI")
(set_attr "memory" "both")])
-(define_insn "strmovhi_1"
+(define_insn "*strmovhi_1"
[(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
(mem:HI (match_operand:SI 3 "register_operand" "1")))
(set (match_operand:SI 0 "register_operand" "=D")
@@ -15097,7 +15462,7 @@
(set_attr "memory" "both")
(set_attr "mode" "HI")])
-(define_insn "strmovhi_rex_1"
+(define_insn "*strmovhi_rex_1"
[(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
(mem:HI (match_operand:DI 3 "register_operand" "1")))
(set (match_operand:DI 0 "register_operand" "=D")
@@ -15113,7 +15478,7 @@
(set_attr "memory" "both")
(set_attr "mode" "HI")])
-(define_insn "strmovqi_1"
+(define_insn "*strmovqi_1"
[(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
(mem:QI (match_operand:SI 3 "register_operand" "1")))
(set (match_operand:SI 0 "register_operand" "=D")
@@ -15129,7 +15494,7 @@
(set_attr "memory" "both")
(set_attr "mode" "QI")])
-(define_insn "strmovqi_rex_1"
+(define_insn "*strmovqi_rex_1"
[(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
(mem:QI (match_operand:DI 3 "register_operand" "1")))
(set (match_operand:DI 0 "register_operand" "=D")
@@ -15145,7 +15510,20 @@
(set_attr "memory" "both")
(set_attr "mode" "QI")])
-(define_insn "rep_movdi_rex64"
+(define_expand "rep_mov"
+ [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
+ (set (match_operand 0 "register_operand" "")
+ (match_operand 5 "" ""))
+ (set (match_operand 2 "register_operand" "")
+ (match_operand 6 "" ""))
+ (set (match_operand 1 "memory_operand" "")
+ (match_operand 3 "memory_operand" ""))
+ (use (match_dup 4))
+ (use (reg:SI 19))])]
+ ""
+ "")
+
+(define_insn "*rep_movdi_rex64"
[(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
(set (match_operand:DI 0 "register_operand" "=D")
(plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
@@ -15165,7 +15543,7 @@
(set_attr "memory" "both")
(set_attr "mode" "DI")])
-(define_insn "rep_movsi"
+(define_insn "*rep_movsi"
[(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
@@ -15185,7 +15563,7 @@
(set_attr "memory" "both")
(set_attr "mode" "SI")])
-(define_insn "rep_movsi_rex64"
+(define_insn "*rep_movsi_rex64"
[(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
(set (match_operand:DI 0 "register_operand" "=D")
(plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
@@ -15205,7 +15583,7 @@
(set_attr "memory" "both")
(set_attr "mode" "SI")])
-(define_insn "rep_movqi"
+(define_insn "*rep_movqi"
[(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_operand:SI 3 "register_operand" "0")
@@ -15223,7 +15601,7 @@
(set_attr "memory" "both")
(set_attr "mode" "SI")])
-(define_insn "rep_movqi_rex64"
+(define_insn "*rep_movqi_rex64"
[(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
(set (match_operand:DI 0 "register_operand" "=D")
(plus:DI (match_operand:DI 3 "register_operand" "0")
@@ -15268,120 +15646,40 @@
;; Most CPUs don't like single string operations
;; Handle this case here to simplify previous expander.
-(define_expand "strsetdi_rex64"
- [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
- (match_operand:DI 1 "register_operand" ""))
- (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
- (clobber (reg:CC 17))])]
- "TARGET_64BIT"
-{
- if (TARGET_SINGLE_STRINGOP || optimize_size)
- {
- emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
- DONE;
- }
-})
-
-(define_expand "strsetsi"
- [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
- (match_operand:SI 1 "register_operand" ""))
- (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
- (clobber (reg:CC 17))])]
- ""
-{
- if (TARGET_64BIT)
- {
- emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
- DONE;
- }
- else if (TARGET_SINGLE_STRINGOP || optimize_size)
- {
- emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
- DONE;
- }
-})
-
-(define_expand "strsetsi_rex64"
- [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
- (match_operand:SI 1 "register_operand" ""))
- (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
- (clobber (reg:CC 17))])]
- "TARGET_64BIT"
-{
- if (TARGET_SINGLE_STRINGOP || optimize_size)
- {
- emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
- DONE;
- }
-})
-
-(define_expand "strsethi"
- [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
- (match_operand:HI 1 "register_operand" ""))
- (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
+(define_expand "strset"
+ [(set (match_operand 1 "memory_operand" "")
+ (match_operand 2 "register_operand" ""))
+ (parallel [(set (match_operand 0 "register_operand" "")
+ (match_dup 3))
(clobber (reg:CC 17))])]
""
{
- if (TARGET_64BIT)
- {
- emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
- DONE;
- }
- else if (TARGET_SINGLE_STRINGOP || optimize_size)
- {
- emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
- DONE;
- }
-})
-
-(define_expand "strsethi_rex64"
- [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
- (match_operand:HI 1 "register_operand" ""))
- (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
- (clobber (reg:CC 17))])]
- "TARGET_64BIT"
-{
+ if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
+ operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
+
+ /* If .md ever supports :P for Pmode, this can be directly
+ in the pattern above. */
+ operands[3] = gen_rtx_PLUS (Pmode, operands[0],
+ GEN_INT (GET_MODE_SIZE (GET_MODE
+ (operands[2]))));
if (TARGET_SINGLE_STRINGOP || optimize_size)
{
- emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
- DONE;
- }
-})
-
-(define_expand "strsetqi"
- [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
- (match_operand:QI 1 "register_operand" ""))
- (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
- (clobber (reg:CC 17))])]
- ""
-{
- if (TARGET_64BIT)
- {
- emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
- DONE;
- }
- else if (TARGET_SINGLE_STRINGOP || optimize_size)
- {
- emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
+ emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
+ operands[3]));
DONE;
}
})
-(define_expand "strsetqi_rex64"
- [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
- (match_operand:QI 1 "register_operand" ""))
- (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
- (clobber (reg:CC 17))])]
- "TARGET_64BIT"
-{
- if (TARGET_SINGLE_STRINGOP || optimize_size)
- {
- emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
- DONE;
- }
-})
+(define_expand "strset_singleop"
+ [(parallel [(set (match_operand 1 "memory_operand" "")
+ (match_operand 2 "register_operand" ""))
+ (set (match_operand 0 "register_operand" "")
+ (match_operand 3 "" ""))
+ (use (reg:SI 19))])]
+ "TARGET_SINGLE_STRINGOP || optimize_size"
+ "")
-(define_insn "strsetdi_rex_1"
+(define_insn "*strsetdi_rex_1"
[(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
(match_operand:SI 2 "register_operand" "a"))
(set (match_operand:DI 0 "register_operand" "=D")
@@ -15394,7 +15692,7 @@
(set_attr "memory" "store")
(set_attr "mode" "DI")])
-(define_insn "strsetsi_1"
+(define_insn "*strsetsi_1"
[(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
(match_operand:SI 2 "register_operand" "a"))
(set (match_operand:SI 0 "register_operand" "=D")
@@ -15407,7 +15705,7 @@
(set_attr "memory" "store")
(set_attr "mode" "SI")])
-(define_insn "strsetsi_rex_1"
+(define_insn "*strsetsi_rex_1"
[(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
(match_operand:SI 2 "register_operand" "a"))
(set (match_operand:DI 0 "register_operand" "=D")
@@ -15420,7 +15718,7 @@
(set_attr "memory" "store")
(set_attr "mode" "SI")])
-(define_insn "strsethi_1"
+(define_insn "*strsethi_1"
[(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
(match_operand:HI 2 "register_operand" "a"))
(set (match_operand:SI 0 "register_operand" "=D")
@@ -15433,7 +15731,7 @@
(set_attr "memory" "store")
(set_attr "mode" "HI")])
-(define_insn "strsethi_rex_1"
+(define_insn "*strsethi_rex_1"
[(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
(match_operand:HI 2 "register_operand" "a"))
(set (match_operand:DI 0 "register_operand" "=D")
@@ -15446,7 +15744,7 @@
(set_attr "memory" "store")
(set_attr "mode" "HI")])
-(define_insn "strsetqi_1"
+(define_insn "*strsetqi_1"
[(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
(match_operand:QI 2 "register_operand" "a"))
(set (match_operand:SI 0 "register_operand" "=D")
@@ -15459,7 +15757,7 @@
(set_attr "memory" "store")
(set_attr "mode" "QI")])
-(define_insn "strsetqi_rex_1"
+(define_insn "*strsetqi_rex_1"
[(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
(match_operand:QI 2 "register_operand" "a"))
(set (match_operand:DI 0 "register_operand" "=D")
@@ -15472,7 +15770,18 @@
(set_attr "memory" "store")
(set_attr "mode" "QI")])
-(define_insn "rep_stosdi_rex64"
+(define_expand "rep_stos"
+ [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
+ (set (match_operand 0 "register_operand" "")
+ (match_operand 4 "" ""))
+ (set (match_operand 2 "memory_operand" "") (const_int 0))
+ (use (match_operand 3 "register_operand" ""))
+ (use (match_dup 1))
+ (use (reg:SI 19))])]
+ ""
+ "")
+
+(define_insn "*rep_stosdi_rex64"
[(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
(set (match_operand:DI 0 "register_operand" "=D")
(plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
@@ -15490,7 +15799,7 @@
(set_attr "memory" "store")
(set_attr "mode" "DI")])
-(define_insn "rep_stossi"
+(define_insn "*rep_stossi"
[(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
@@ -15508,7 +15817,7 @@
(set_attr "memory" "store")
(set_attr "mode" "SI")])
-(define_insn "rep_stossi_rex64"
+(define_insn "*rep_stossi_rex64"
[(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
(set (match_operand:DI 0 "register_operand" "=D")
(plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
@@ -15526,7 +15835,7 @@
(set_attr "memory" "store")
(set_attr "mode" "SI")])
-(define_insn "rep_stosqi"
+(define_insn "*rep_stosqi"
[(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_operand:SI 3 "register_operand" "0")
@@ -15543,7 +15852,7 @@
(set_attr "memory" "store")
(set_attr "mode" "QI")])
-(define_insn "rep_stosqi_rex64"
+(define_insn "*rep_stosqi_rex64"
[(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
(set (match_operand:DI 0 "register_operand" "=D")
(plus:DI (match_operand:DI 3 "register_operand" "0")
@@ -15552,7 +15861,7 @@
(const_int 0))
(use (match_operand:QI 2 "register_operand" "a"))
(use (match_dup 4))
- (use (reg:DI 19))]
+ (use (reg:SI 19))]
"TARGET_64BIT"
"{rep\;stosb|rep stosb}"
[(set_attr "type" "str")
@@ -15566,17 +15875,25 @@
(match_operand:BLK 2 "general_operand" "")))
(use (match_operand 3 "general_operand" ""))
(use (match_operand 4 "immediate_operand" ""))]
- ""
+ "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
{
rtx addr1, addr2, out, outlow, count, countreg, align;
+ /* Can't use this if the user has appropriated esi or edi. */
+ if (global_regs[4] || global_regs[5])
+ FAIL;
+
out = operands[0];
if (GET_CODE (out) != REG)
out = gen_reg_rtx (SImode);
addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
-
+ if (addr1 != XEXP (operands[1], 0))
+ operands[1] = replace_equiv_address_nv (operands[1], addr1);
+ if (addr2 != XEXP (operands[2], 0))
+ operands[2] = replace_equiv_address_nv (operands[2], addr2);
+
count = operands[3];
countreg = ix86_zero_extend_to_Pmode (count);
@@ -15593,27 +15910,17 @@
emit_move_insn (operands[0], const0_rtx);
DONE;
}
- if (TARGET_64BIT)
- emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
- addr1, addr2, countreg));
- else
- emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
- addr1, addr2, countreg));
+ emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
+ operands[1], operands[2]));
}
else
{
if (TARGET_64BIT)
- {
- emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
- emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
- addr1, addr2, countreg));
- }
+ emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
else
- {
- emit_insn (gen_cmpsi_1 (countreg, countreg));
- emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
- addr1, addr2, countreg));
- }
+ emit_insn (gen_cmpsi_1 (countreg, countreg));
+ emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
+ operands[1], operands[2]));
}
outlow = gen_lowpart (QImode, out);
@@ -15644,7 +15951,20 @@
;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
;; zero. Emit extra code to make sure that a zero-length compare is EQ.
-(define_insn "cmpstrqi_nz_1"
+(define_expand "cmpstrqi_nz_1"
+ [(parallel [(set (reg:CC 17)
+ (compare:CC (match_operand 4 "memory_operand" "")
+ (match_operand 5 "memory_operand" "")))
+ (use (match_operand 2 "register_operand" ""))
+ (use (match_operand:SI 3 "immediate_operand" ""))
+ (use (reg:SI 19))
+ (clobber (match_operand 0 "register_operand" ""))
+ (clobber (match_operand 1 "register_operand" ""))
+ (clobber (match_dup 2))])]
+ ""
+ "")
+
+(define_insn "*cmpstrqi_nz_1"
[(set (reg:CC 17)
(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
(mem:BLK (match_operand:SI 5 "register_operand" "1"))))
@@ -15660,7 +15980,7 @@
(set_attr "mode" "QI")
(set_attr "prefix_rep" "1")])
-(define_insn "cmpstrqi_nz_rex_1"
+(define_insn "*cmpstrqi_nz_rex_1"
[(set (reg:CC 17)
(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
(mem:BLK (match_operand:DI 5 "register_operand" "1"))))
@@ -15678,7 +15998,23 @@
;; The same, but the count is not known to not be zero.
-(define_insn "cmpstrqi_1"
+(define_expand "cmpstrqi_1"
+ [(parallel [(set (reg:CC 17)
+ (if_then_else:CC (ne (match_operand 2 "register_operand" "")
+ (const_int 0))
+ (compare:CC (match_operand 4 "memory_operand" "")
+ (match_operand 5 "memory_operand" ""))
+ (const_int 0)))
+ (use (match_operand:SI 3 "immediate_operand" ""))
+ (use (reg:CC 17))
+ (use (reg:SI 19))
+ (clobber (match_operand 0 "register_operand" ""))
+ (clobber (match_operand 1 "register_operand" ""))
+ (clobber (match_dup 2))])]
+ ""
+ "")
+
+(define_insn "*cmpstrqi_1"
[(set (reg:CC 17)
(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
(const_int 0))
@@ -15697,7 +16033,7 @@
(set_attr "mode" "QI")
(set_attr "prefix_rep" "1")])
-(define_insn "cmpstrqi_rex_1"
+(define_insn "*cmpstrqi_rex_1"
[(set (reg:CC 17)
(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
(const_int 0))
@@ -15742,7 +16078,15 @@
FAIL;
})
-(define_insn "strlenqi_1"
+(define_expand "strlenqi_1"
+ [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
+ (use (reg:SI 19))
+ (clobber (match_operand 1 "register_operand" ""))
+ (clobber (reg:CC 17))])]
+ ""
+ "")
+
+(define_insn "*strlenqi_1"
[(set (match_operand:SI 0 "register_operand" "=&c")
(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
(match_operand:QI 2 "register_operand" "a")
@@ -15757,7 +16101,7 @@
(set_attr "mode" "QI")
(set_attr "prefix_rep" "1")])
-(define_insn "strlenqi_rex_1"
+(define_insn "*strlenqi_rex_1"
[(set (match_operand:DI 0 "register_operand" "=&c")
(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
(match_operand:QI 2 "register_operand" "a")
@@ -15869,7 +16213,7 @@
(define_insn "x86_movdicc_0_m1_rex64"
[(set (match_operand:DI 0 "register_operand" "=r")
- (if_then_else:DI (ltu (reg:CC 17) (const_int 0))
+ (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
(const_int -1)
(const_int 0)))
(clobber (reg:CC 17))]
@@ -15884,7 +16228,7 @@
(set_attr "mode" "DI")
(set_attr "length_immediate" "0")])
-(define_insn "*movdicc_c_rex64"
+(define_insn "movdicc_c_rex64"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(if_then_else:DI (match_operator 1 "ix86_comparison_operator"
[(reg 17) (const_int 0)])
@@ -15912,7 +16256,7 @@
(define_insn "x86_movsicc_0_m1"
[(set (match_operand:SI 0 "register_operand" "=r")
- (if_then_else:SI (ltu (reg:CC 17) (const_int 0))
+ (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
(const_int -1)
(const_int 0)))
(clobber (reg:CC 17))]
@@ -15944,9 +16288,9 @@
(define_expand "movhicc"
[(set (match_operand:HI 0 "register_operand" "")
(if_then_else:HI (match_operand 1 "comparison_operator" "")
- (match_operand:HI 2 "nonimmediate_operand" "")
- (match_operand:HI 3 "nonimmediate_operand" "")))]
- "TARGET_CMOVE && TARGET_HIMODE_MATH"
+ (match_operand:HI 2 "general_operand" "")
+ (match_operand:HI 3 "general_operand" "")))]
+ "TARGET_HIMODE_MATH"
"if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
(define_insn "*movhicc_noc"
@@ -15963,6 +16307,33 @@
[(set_attr "type" "icmov")
(set_attr "mode" "HI")])
+(define_expand "movqicc"
+ [(set (match_operand:QI 0 "register_operand" "")
+ (if_then_else:QI (match_operand 1 "comparison_operator" "")
+ (match_operand:QI 2 "general_operand" "")
+ (match_operand:QI 3 "general_operand" "")))]
+ "TARGET_QIMODE_MATH"
+ "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
+
+(define_insn_and_split "*movqicc_noc"
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
+ [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
+ (match_operand:QI 2 "register_operand" "r,0")
+ (match_operand:QI 3 "register_operand" "0,r")))]
+ "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0)
+ (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
+ (match_dup 2)
+ (match_dup 3)))]
+ "operands[0] = gen_lowpart (SImode, operands[0]);
+ operands[2] = gen_lowpart (SImode, operands[2]);
+ operands[3] = gen_lowpart (SImode, operands[3]);"
+ [(set_attr "type" "icmov")
+ (set_attr "mode" "SI")])
+
(define_expand "movsfcc"
[(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (match_operand 1 "comparison_operator" "")
@@ -15972,11 +16343,11 @@
"if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
(define_insn "*movsfcc_1"
- [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
+ [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
(if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
[(reg 17) (const_int 0)])
- (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
- (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
+ (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
+ (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
"TARGET_CMOVE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"@
@@ -15996,11 +16367,11 @@
"if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
(define_insn "*movdfcc_1"
- [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
+ [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
[(reg 17) (const_int 0)])
- (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
- (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
+ (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
+ (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
"!TARGET_64BIT && TARGET_CMOVE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"@
@@ -16012,11 +16383,11 @@
(set_attr "mode" "DF")])
(define_insn "*movdfcc_1_rex64"
- [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
+ [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
[(reg 17) (const_int 0)])
- (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
- (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
+ (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
+ (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
"TARGET_64BIT && TARGET_CMOVE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"@
@@ -16030,7 +16401,7 @@
(define_split
[(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
- [(match_operand 4 "" "") (const_int 0)])
+ [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
(match_operand:DF 2 "nonimmediate_operand" "")
(match_operand:DF 3 "nonimmediate_operand" "")))]
"!TARGET_64BIT && reload_completed"
@@ -16051,14 +16422,6 @@
(if_then_else:XF (match_operand 1 "comparison_operator" "")
(match_operand:XF 2 "register_operand" "")
(match_operand:XF 3 "register_operand" "")))]
- "!TARGET_64BIT && TARGET_CMOVE"
- "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
-
-(define_expand "movtfcc"
- [(set (match_operand:TF 0 "register_operand" "")
- (if_then_else:TF (match_operand 1 "comparison_operator" "")
- (match_operand:TF 2 "register_operand" "")
- (match_operand:TF 3 "register_operand" "")))]
"TARGET_CMOVE"
"if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
@@ -16068,19 +16431,6 @@
[(reg 17) (const_int 0)])
(match_operand:XF 2 "register_operand" "f,0")
(match_operand:XF 3 "register_operand" "0,f")))]
- "!TARGET_64BIT && TARGET_CMOVE"
- "@
- fcmov%F1\t{%2, %0|%0, %2}
- fcmov%f1\t{%3, %0|%0, %3}"
- [(set_attr "type" "fcmov")
- (set_attr "mode" "XF")])
-
-(define_insn "*movtfcc_1"
- [(set (match_operand:TF 0 "register_operand" "=f,f")
- (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
- [(reg 17) (const_int 0)])
- (match_operand:TF 2 "register_operand" "f,0")
- (match_operand:TF 3 "register_operand" "0,f")))]
"TARGET_CMOVE"
"@
fcmov%F1\t{%2, %0|%0, %2}
@@ -16138,6 +16488,39 @@
(match_dup 1)
(match_dup 2)))])
+;; Conditional addition patterns
+(define_expand "addqicc"
+ [(match_operand:QI 0 "register_operand" "")
+ (match_operand 1 "comparison_operator" "")
+ (match_operand:QI 2 "register_operand" "")
+ (match_operand:QI 3 "const_int_operand" "")]
+ ""
+ "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
+
+(define_expand "addhicc"
+ [(match_operand:HI 0 "register_operand" "")
+ (match_operand 1 "comparison_operator" "")
+ (match_operand:HI 2 "register_operand" "")
+ (match_operand:HI 3 "const_int_operand" "")]
+ ""
+ "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
+
+(define_expand "addsicc"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand 1 "comparison_operator" "")
+ (match_operand:SI 2 "register_operand" "")
+ (match_operand:SI 3 "const_int_operand" "")]
+ ""
+ "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
+
+(define_expand "adddicc"
+ [(match_operand:DI 0 "register_operand" "")
+ (match_operand 1 "comparison_operator" "")
+ (match_operand:DI 2 "register_operand" "")
+ (match_operand:DI 3 "const_int_operand" "")]
+ "TARGET_64BIT"
+ "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
+
;; We can't represent the LT test directly. Do this by swapping the operands.
(define_split
@@ -16236,7 +16619,7 @@
&& operands_match_p (operands[2], operands[3])))"
[(set (reg:CCFP 17)
(compare:CCFP (match_dup 2)
- (match_dup 2)))
+ (match_dup 1)))
(set (match_dup 0)
(if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
(match_dup 1)
@@ -16426,23 +16809,7 @@
;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
;;
;; in proper program order.
-(define_expand "pro_epilogue_adjust_stack"
- [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_operand:SI 1 "register_operand" "0,r")
- (match_operand:SI 2 "immediate_operand" "i,i")))
- (clobber (reg:CC 17))
- (clobber (mem:BLK (scratch)))])]
- ""
-{
- if (TARGET_64BIT)
- {
- emit_insn (gen_pro_epilogue_adjust_stack_rex64
- (operands[0], operands[1], operands[2]));
- DONE;
- }
-})
-
-(define_insn "*pro_epilogue_adjust_stack_1"
+(define_insn "pro_epilogue_adjust_stack_1"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (match_operand:SI 1 "register_operand" "0,r")
(match_operand:SI 2 "immediate_operand" "i,i")))
@@ -16498,6 +16865,8 @@
case TYPE_ALU:
if (GET_CODE (operands[2]) == CONST_INT
+ /* Avoid overflows. */
+ && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
&& (INTVAL (operands[2]) == 128
|| (INTVAL (operands[2]) < 0
&& INTVAL (operands[2]) != -128)))
@@ -16524,6 +16893,30 @@
(const_string "lea")))
(set_attr "mode" "DI")])
+(define_insn "pro_epilogue_adjust_stack_rex64_2"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (plus:DI (match_operand:DI 1 "register_operand" "0,r")
+ (match_operand:DI 3 "immediate_operand" "i,i")))
+ (use (match_operand:DI 2 "register_operand" "r,r"))
+ (clobber (reg:CC 17))
+ (clobber (mem:BLK (scratch)))]
+ "TARGET_64BIT"
+{
+ switch (get_attr_type (insn))
+ {
+ case TYPE_ALU:
+ return "add{q}\t{%2, %0|%0, %2}";
+
+ case TYPE_LEA:
+ operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
+ return "lea{q}\t{%a2, %0|%0, %a2}";
+
+ default:
+ abort ();
+ }
+}
+ [(set_attr "type" "alu,lea")
+ (set_attr "mode" "DI")])
;; Placeholder for the conditional moves. This one is split either to SSE
;; based moves emulation or to usual cmove sequence. Little bit unfortunate
@@ -16544,6 +16937,12 @@
(clobber (reg:CC 17))]
"TARGET_SSE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
+ /* Avoid combine from being smart and converting min/max
+ instruction patterns into conditional moves. */
+ && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
+ && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
+ || !rtx_equal_p (operands[4], operands[2])
+ || !rtx_equal_p (operands[5], operands[3]))
&& (!TARGET_IEEE_FP
|| (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
"#")
@@ -16571,6 +16970,12 @@
(clobber (reg:CC 17))]
"TARGET_SSE2
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
+ /* Avoid combine from being smart and converting min/max
+ instruction patterns into conditional moves. */
+ && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
+ && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
+ || !rtx_equal_p (operands[4], operands[2])
+ || !rtx_equal_p (operands[5], operands[3]))
&& (!TARGET_IEEE_FP
|| (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
"#")
@@ -16609,7 +17014,7 @@
DONE;
})
-;; Split SSE based conditional move into seqence:
+;; Split SSE based conditional move into sequence:
;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
;; and op2, op0 - zero op2 if comparison was false
;; nand op0, op3 - load op3 to op0 if comparison was false
@@ -16632,10 +17037,22 @@
(set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
(subreg:TI (match_dup 7) 0)))]
{
- /* If op2 == op3, op3 will be clobbered before it is used.
- This should be optimized out though. */
+ if (GET_MODE (operands[2]) == DFmode
+ && TARGET_SSE_PARTIAL_REGS && !optimize_size)
+ {
+ rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
+ emit_insn (gen_sse2_unpcklpd (op, op, op));
+ op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
+ emit_insn (gen_sse2_unpcklpd (op, op, op));
+ }
+
+ /* If op2 == op3, op3 would be clobbered before it is used. */
if (operands_match_p (operands[2], operands[3]))
- abort ();
+ {
+ emit_move_insn (operands[0], operands[2]);
+ DONE;
+ }
+
PUT_MODE (operands[1], GET_MODE (operands[0]));
if (operands_match_p (operands[0], operands[4]))
operands[6] = operands[4], operands[7] = operands[2];
@@ -16643,7 +17060,7 @@
operands[6] = operands[2], operands[7] = operands[4];
})
-;; Special case of conditional move we can handle effectivly.
+;; Special case of conditional move we can handle effectively.
;; Do not brother with the integer/floating point case, since these are
;; bot considerably slower, unlike in the generic case.
(define_insn "*sse_movsfcc_const0_1"
@@ -16738,8 +17155,22 @@
|| const0_operand (operands[3], GET_MODE (operands[0])))"
[(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
(set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
- (subreg:TI (match_dup 7) 0)))]
+ (match_dup 7)))]
{
+ if (TARGET_SSE_PARTIAL_REGS && !optimize_size
+ && GET_MODE (operands[2]) == DFmode)
+ {
+ if (REG_P (operands[2]))
+ {
+ rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
+ emit_insn (gen_sse2_unpcklpd (op, op, op));
+ }
+ if (REG_P (operands[3]))
+ {
+ rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
+ emit_insn (gen_sse2_unpcklpd (op, op, op));
+ }
+ }
PUT_MODE (operands[1], GET_MODE (operands[0]));
if (!sse_comparison_operator (operands[1], VOIDmode)
|| !rtx_equal_p (operands[0], operands[4]))
@@ -16762,39 +17193,71 @@
operands[7] = operands[2];
operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
}
+ operands[7] = simplify_gen_subreg (TImode, operands[7],
+ GET_MODE (operands[7]), 0);
})
(define_expand "allocate_stack_worker"
[(match_operand:SI 0 "register_operand" "")]
"TARGET_STACK_PROBE"
{
- if (TARGET_64BIT)
- emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
+ if (reload_completed)
+ {
+ if (TARGET_64BIT)
+ emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
+ else
+ emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
+ }
else
- emit_insn (gen_allocate_stack_worker_1 (operands[0]));
+ {
+ if (TARGET_64BIT)
+ emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
+ else
+ emit_insn (gen_allocate_stack_worker_1 (operands[0]));
+ }
DONE;
})
(define_insn "allocate_stack_worker_1"
- [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
+ [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
+ UNSPECV_STACK_PROBE)
(set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
- (clobber (match_dup 0))
+ (clobber (match_scratch:SI 1 "=0"))
(clobber (reg:CC 17))]
"!TARGET_64BIT && TARGET_STACK_PROBE"
"call\t__alloca"
[(set_attr "type" "multi")
(set_attr "length" "5")])
+(define_expand "allocate_stack_worker_postreload"
+ [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
+ UNSPECV_STACK_PROBE)
+ (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
+ (clobber (match_dup 0))
+ (clobber (reg:CC 17))])]
+ ""
+ "")
+
(define_insn "allocate_stack_worker_rex64"
- [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
+ [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
+ UNSPECV_STACK_PROBE)
(set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
- (clobber (match_dup 0))
+ (clobber (match_scratch:DI 1 "=0"))
(clobber (reg:CC 17))]
"TARGET_64BIT && TARGET_STACK_PROBE"
"call\t__alloca"
[(set_attr "type" "multi")
(set_attr "length" "5")])
+(define_expand "allocate_stack_worker_rex64_postreload"
+ [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
+ UNSPECV_STACK_PROBE)
+ (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
+ (clobber (match_dup 0))
+ (clobber (reg:CC 17))])]
+ ""
+ "")
+
(define_expand "allocate_stack"
[(parallel [(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (reg:SI 7)
@@ -17025,7 +17488,7 @@
[(parallel [(set (match_dup 2) (const_int 0))
(clobber (reg:CC 17))])
(set (match_dup 0) (match_dup 1))]
- "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
+ "operands[2] = gen_lowpart (SImode, operands[1]);")
(define_peephole2
[(match_scratch:QI 1 "q")
@@ -17039,7 +17502,7 @@
[(parallel [(set (match_dup 2) (const_int 0))
(clobber (reg:CC 17))])
(set (match_dup 0) (match_dup 1))]
- "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
+ "operands[2] = gen_lowpart (SImode, operands[1]);")
(define_peephole2
[(match_scratch:SI 2 "r")
@@ -17085,7 +17548,7 @@
;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
;; Don't split NOTs with a displacement operand, because resulting XOR
-;; will not be pariable anyway.
+;; will not be pairable anyway.
;;
;; On AMD K6, NOT is vector decoded with memory operand that can not be
;; represented using a modRM byte. The XOR replacement is long decoded,
@@ -17294,8 +17757,8 @@
&& peep2_regno_dead_p (0, FLAGS_REG)"
[(parallel [(set (match_dup 0) (const_int 0))
(clobber (reg:CC 17))])]
- "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
- true_regnum (operands[0]));")
+ "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
+ operands[0]);")
(define_peephole2
[(set (strict_low_part (match_operand 0 "register_operand" ""))
@@ -17318,8 +17781,8 @@
&& peep2_regno_dead_p (0, FLAGS_REG)"
[(parallel [(set (match_dup 0) (const_int -1))
(clobber (reg:CC 17))])]
- "operands[0] = gen_rtx_REG (GET_MODE (operands[0]) == DImode ? DImode : SImode,
- true_regnum (operands[0]));")
+ "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
+ operands[0]);")
;; Attempt to convert simple leas to adds. These can be created by
;; move expanders.
@@ -17693,6 +18156,102 @@
(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
"")
+;; Imul $32bit_imm, mem, reg is vector decoded, while
+;; imul $32bit_imm, reg, reg is direct decoded.
+(define_peephole2
+ [(match_scratch:DI 3 "r")
+ (parallel [(set (match_operand:DI 0 "register_operand" "")
+ (mult:DI (match_operand:DI 1 "memory_operand" "")
+ (match_operand:DI 2 "immediate_operand" "")))
+ (clobber (reg:CC 17))])]
+ "TARGET_K8 && !optimize_size
+ && (GET_CODE (operands[2]) != CONST_INT
+ || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
+ [(set (match_dup 3) (match_dup 1))
+ (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
+ (clobber (reg:CC 17))])]
+"")
+
+(define_peephole2
+ [(match_scratch:SI 3 "r")
+ (parallel [(set (match_operand:SI 0 "register_operand" "")
+ (mult:SI (match_operand:SI 1 "memory_operand" "")
+ (match_operand:SI 2 "immediate_operand" "")))
+ (clobber (reg:CC 17))])]
+ "TARGET_K8 && !optimize_size
+ && (GET_CODE (operands[2]) != CONST_INT
+ || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
+ [(set (match_dup 3) (match_dup 1))
+ (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
+ (clobber (reg:CC 17))])]
+"")
+
+(define_peephole2
+ [(match_scratch:SI 3 "r")
+ (parallel [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI
+ (mult:SI (match_operand:SI 1 "memory_operand" "")
+ (match_operand:SI 2 "immediate_operand" ""))))
+ (clobber (reg:CC 17))])]
+ "TARGET_K8 && !optimize_size
+ && (GET_CODE (operands[2]) != CONST_INT
+ || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
+ [(set (match_dup 3) (match_dup 1))
+ (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
+ (clobber (reg:CC 17))])]
+"")
+
+;; imul $8/16bit_imm, regmem, reg is vector decoded.
+;; Convert it into imul reg, reg
+;; It would be better to force assembler to encode instruction using long
+;; immediate, but there is apparently no way to do so.
+(define_peephole2
+ [(parallel [(set (match_operand:DI 0 "register_operand" "")
+ (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
+ (match_operand:DI 2 "const_int_operand" "")))
+ (clobber (reg:CC 17))])
+ (match_scratch:DI 3 "r")]
+ "TARGET_K8 && !optimize_size
+ && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
+ [(set (match_dup 3) (match_dup 2))
+ (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
+ (clobber (reg:CC 17))])]
+{
+ if (!rtx_equal_p (operands[0], operands[1]))
+ emit_move_insn (operands[0], operands[1]);
+})
+
+(define_peephole2
+ [(parallel [(set (match_operand:SI 0 "register_operand" "")
+ (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "const_int_operand" "")))
+ (clobber (reg:CC 17))])
+ (match_scratch:SI 3 "r")]
+ "TARGET_K8 && !optimize_size
+ && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
+ [(set (match_dup 3) (match_dup 2))
+ (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
+ (clobber (reg:CC 17))])]
+{
+ if (!rtx_equal_p (operands[0], operands[1]))
+ emit_move_insn (operands[0], operands[1]);
+})
+
+(define_peephole2
+ [(parallel [(set (match_operand:HI 0 "register_operand" "")
+ (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
+ (match_operand:HI 2 "immediate_operand" "")))
+ (clobber (reg:CC 17))])
+ (match_scratch:HI 3 "r")]
+ "TARGET_K8 && !optimize_size"
+ [(set (match_dup 3) (match_dup 2))
+ (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
+ (clobber (reg:CC 17))])]
+{
+ if (!rtx_equal_p (operands[0], operands[1]))
+ emit_move_insn (operands[0], operands[1]);
+})
+
;; Call-value patterns last so that the wildcard operand does not
;; disrupt insn-recog's switch tables.
@@ -17763,19 +18322,23 @@
[(set (match_operand 0 "" "")
(call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
(match_operand:SI 2 "" "")))]
- "!TARGET_64BIT"
+ "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
{
if (constant_call_address_operand (operands[1], QImode))
- {
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P1";
- else
- return "call\t%P1";
- }
- if (SIBLING_CALL_P (insn))
- return "jmp\t%*%1";
- else
- return "call\t%*%1";
+ return "call\t%P1";
+ return "call\t%*%1";
+}
+ [(set_attr "type" "callv")])
+
+(define_insn "*sibcall_value_1"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
+ (match_operand:SI 2 "" "")))]
+ "SIBLING_CALL_P (insn) && !TARGET_64BIT"
+{
+ if (constant_call_address_operand (operands[1], QImode))
+ return "jmp\t%P1";
+ return "jmp\t%*%1";
}
[(set_attr "type" "callv")])
@@ -17783,21 +18346,29 @@
[(set (match_operand 0 "" "")
(call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
(match_operand:DI 2 "" "")))]
- "TARGET_64BIT"
+ "!SIBLING_CALL_P (insn) && TARGET_64BIT"
{
if (constant_call_address_operand (operands[1], QImode))
- {
- if (SIBLING_CALL_P (insn))
- return "jmp\t%P1";
- else
- return "call\t%P1";
- }
- if (SIBLING_CALL_P (insn))
- return "jmp\t%A1";
- else
- return "call\t%A1";
+ return "call\t%P1";
+ return "call\t%A1";
}
[(set_attr "type" "callv")])
+
+(define_insn "*sibcall_value_1_rex64"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
+ (match_operand:DI 2 "" "")))]
+ "SIBLING_CALL_P (insn) && TARGET_64BIT"
+ "jmp\t%P1"
+ [(set_attr "type" "callv")])
+
+(define_insn "*sibcall_value_1_rex64_v"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (reg:DI 40))
+ (match_operand:DI 1 "" "")))]
+ "SIBLING_CALL_P (insn) && TARGET_64BIT"
+ "jmp\t*%%r11"
+ [(set_attr "type" "callv")])
(define_insn "trap"
[(trap_if (const_int 1) (const_int 5))]
@@ -17842,7 +18413,7 @@
{
operands[2] = gen_label_rtx ();
output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
+ (*targetm.asm_out.internal_label) (asm_out_file, "L",
CODE_LABEL_NUMBER (operands[2]));
RET;
})
@@ -17855,37 +18426,120 @@
[(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE"
- ;; @@@ let's try to use movaps here.
"@
- xorps\t%0, %0
- movaps\t{%1, %0|%0, %1}
- movaps\t{%1, %0|%0, %1}"
+ xorps\t%0, %0
+ movaps\t{%1, %0|%0, %1}
+ movaps\t{%1, %0|%0, %1}"
[(set_attr "type" "ssemov")
(set_attr "mode" "V4SF")])
+(define_split
+ [(set (match_operand:V4SF 0 "register_operand" "")
+ (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
+ "TARGET_SSE"
+ [(set (match_dup 0)
+ (vec_merge:V4SF
+ (vec_duplicate:V4SF (match_dup 1))
+ (match_dup 2)
+ (const_int 1)))]
+{
+ operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
+ operands[2] = CONST0_RTX (V4SFmode);
+})
+
(define_insn "movv4si_internal"
[(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE"
- ;; @@@ let's try to use movaps here.
- "@
- xorps\t%0, %0
- movaps\t{%1, %0|%0, %1}
- movaps\t{%1, %0|%0, %1}"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "pxor\t%0, %0";
+ case 1:
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movdqa\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
+}
[(set_attr "type" "ssemov")
- (set_attr "mode" "V4SF")])
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "0,1")
+ (if_then_else
+ (ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (const_string "TI"))
+ (eq_attr "alternative" "2")
+ (if_then_else
+ (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
+ (const_int 0))
+ (ne (symbol_ref "optimize_size")
+ (const_int 0)))
+ (const_string "V4SF")
+ (const_string "TI"))]
+ (const_string "TI")))])
(define_insn "movv2di_internal"
[(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE"
- ;; @@@ let's try to use movaps here.
- "@
- pxor\t%0, %0
- movdqa\t{%1, %0|%0, %1}
- movdqa\t{%1, %0|%0, %1}"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "pxor\t%0, %0";
+ case 1:
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movdqa\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
+}
[(set_attr "type" "ssemov")
- (set_attr "mode" "V4SF")])
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "0,1")
+ (if_then_else
+ (ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (const_string "TI"))
+ (eq_attr "alternative" "2")
+ (if_then_else
+ (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
+ (const_int 0))
+ (ne (symbol_ref "optimize_size")
+ (const_int 0)))
+ (const_string "V4SF")
+ (const_string "TI"))]
+ (const_string "TI")))])
+
+(define_split
+ [(set (match_operand:V2DF 0 "register_operand" "")
+ (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
+ "TARGET_SSE2"
+ [(set (match_dup 0)
+ (vec_merge:V2DF
+ (vec_duplicate:V2DF (match_dup 1))
+ (match_dup 2)
+ (const_int 1)))]
+{
+ operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
+ operands[2] = CONST0_RTX (V2DFmode);
+})
(define_insn "movv8qi_internal"
[(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
@@ -17947,41 +18601,140 @@
DONE;
})
+(define_expand "movtf"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (match_operand:TF 1 "nonimmediate_operand" ""))]
+ "TARGET_64BIT"
+{
+ if (TARGET_64BIT)
+ ix86_expand_move (TFmode, operands);
+ else
+ ix86_expand_vector_move (TFmode, operands);
+ DONE;
+})
+
(define_insn "movv2df_internal"
[(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE2
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
- "@
- xorpd\t%0, %0
- movapd\t{%1, %0|%0, %1}
- movapd\t{%1, %0|%0, %1}"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "xorpd\t%0, %0";
+ case 1:
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movapd\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
+}
[(set_attr "type" "ssemov")
- (set_attr "mode" "V2DF")])
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "0,1")
+ (if_then_else
+ (ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (const_string "V2DF"))
+ (eq_attr "alternative" "2")
+ (if_then_else
+ (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
+ (const_int 0))
+ (ne (symbol_ref "optimize_size")
+ (const_int 0)))
+ (const_string "V4SF")
+ (const_string "V2DF"))]
+ (const_string "V2DF")))])
(define_insn "movv8hi_internal"
[(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
(match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE2
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
- "@
- xorps\t%0, %0
- movaps\t{%1, %0|%0, %1}
- movaps\t{%1, %0|%0, %1}"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "pxor\t%0, %0";
+ case 1:
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movdqa\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
+}
[(set_attr "type" "ssemov")
- (set_attr "mode" "V4SF")])
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "0,1")
+ (if_then_else
+ (ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (const_string "TI"))
+ (eq_attr "alternative" "2")
+ (if_then_else
+ (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
+ (const_int 0))
+ (ne (symbol_ref "optimize_size")
+ (const_int 0)))
+ (const_string "V4SF")
+ (const_string "TI"))]
+ (const_string "TI")))])
(define_insn "movv16qi_internal"
[(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
- (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
+ (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
"TARGET_SSE2
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
- "@
- xorps\t%0, %0
- movaps\t{%1, %0|%0, %1}
- movaps\t{%1, %0|%0, %1}"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "pxor\t%0, %0";
+ case 1:
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movdqa\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
+}
[(set_attr "type" "ssemov")
- (set_attr "mode" "V4SF")])
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "0,1")
+ (if_then_else
+ (ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (const_string "TI"))
+ (eq_attr "alternative" "2")
+ (if_then_else
+ (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
+ (const_int 0))
+ (ne (symbol_ref "optimize_size")
+ (const_int 0)))
+ (const_string "V4SF")
+ (const_string "TI"))]
+ (const_string "TI")))])
(define_expand "movv2df"
[(set (match_operand:V2DF 0 "nonimmediate_operand" "")
@@ -18073,6 +18826,12 @@
DONE;
})
+(define_insn "*pushti"
+ [(set (match_operand:TI 0 "push_operand" "=<")
+ (match_operand:TI 1 "register_operand" "x"))]
+ "TARGET_SSE"
+ "#")
+
(define_insn "*pushv2df"
[(set (match_operand:V2DF 0 "push_operand" "=<")
(match_operand:V2DF 1 "register_operand" "x"))]
@@ -18156,152 +18915,132 @@
operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
-(define_insn_and_split "*pushti"
- [(set (match_operand:TI 0 "push_operand" "=<")
- (match_operand:TI 1 "nonmemory_operand" "x"))]
- "TARGET_SSE"
- "#"
- ""
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
- (set (mem:TI (reg:SI 7)) (match_dup 1))]
- ""
- [(set_attr "type" "multi")])
-
-(define_insn_and_split "*pushv2df"
- [(set (match_operand:V2DF 0 "push_operand" "=<")
- (match_operand:V2DF 1 "nonmemory_operand" "x"))]
- "TARGET_SSE2"
- "#"
- ""
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
- (set (mem:V2DF (reg:SI 7)) (match_dup 1))]
- ""
- [(set_attr "type" "multi")])
-
-(define_insn_and_split "*pushv2di"
- [(set (match_operand:V2DI 0 "push_operand" "=<")
- (match_operand:V2DI 1 "nonmemory_operand" "x"))]
- "TARGET_SSE2"
- "#"
- ""
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
- (set (mem:V2DI (reg:SI 7)) (match_dup 1))]
- ""
- [(set_attr "type" "multi")])
-
-(define_insn_and_split "*pushv8hi"
- [(set (match_operand:V8HI 0 "push_operand" "=<")
- (match_operand:V8HI 1 "nonmemory_operand" "x"))]
- "TARGET_SSE2"
- "#"
- ""
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
- (set (mem:V8HI (reg:SI 7)) (match_dup 1))]
- ""
- [(set_attr "type" "multi")])
-
-(define_insn_and_split "*pushv16qi"
- [(set (match_operand:V16QI 0 "push_operand" "=<")
- (match_operand:V16QI 1 "nonmemory_operand" "x"))]
- "TARGET_SSE2"
- "#"
- ""
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
- (set (mem:V16QI (reg:SI 7)) (match_dup 1))]
- ""
- [(set_attr "type" "multi")])
-
-(define_insn_and_split "*pushv4sf"
- [(set (match_operand:V4SF 0 "push_operand" "=<")
- (match_operand:V4SF 1 "nonmemory_operand" "x"))]
- "TARGET_SSE"
- "#"
- ""
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
- (set (mem:V4SF (reg:SI 7)) (match_dup 1))]
- ""
- [(set_attr "type" "multi")])
-
-(define_insn_and_split "*pushv4si"
- [(set (match_operand:V4SI 0 "push_operand" "=<")
- (match_operand:V4SI 1 "nonmemory_operand" "x"))]
- "TARGET_SSE"
- "#"
- ""
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
- (set (mem:V4SI (reg:SI 7)) (match_dup 1))]
- ""
- [(set_attr "type" "multi")])
-
-(define_insn_and_split "*pushv2si"
- [(set (match_operand:V2SI 0 "push_operand" "=<")
- (match_operand:V2SI 1 "nonmemory_operand" "y"))]
- "TARGET_MMX"
- "#"
- ""
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
- (set (mem:V2SI (reg:SI 7)) (match_dup 1))]
- ""
- [(set_attr "type" "mmx")])
-
-(define_insn_and_split "*pushv4hi"
- [(set (match_operand:V4HI 0 "push_operand" "=<")
- (match_operand:V4HI 1 "nonmemory_operand" "y"))]
- "TARGET_MMX"
- "#"
- ""
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
- (set (mem:V4HI (reg:SI 7)) (match_dup 1))]
- ""
- [(set_attr "type" "mmx")])
-
-(define_insn_and_split "*pushv8qi"
- [(set (match_operand:V8QI 0 "push_operand" "=<")
- (match_operand:V8QI 1 "nonmemory_operand" "y"))]
- "TARGET_MMX"
- "#"
- ""
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
- (set (mem:V8QI (reg:SI 7)) (match_dup 1))]
- ""
- [(set_attr "type" "mmx")])
-
-(define_insn_and_split "*pushv2sf"
- [(set (match_operand:V2SF 0 "push_operand" "=<")
- (match_operand:V2SF 1 "nonmemory_operand" "y"))]
- "TARGET_3DNOW"
- "#"
- ""
- [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
- (set (mem:V2SF (reg:SI 7)) (match_dup 1))]
- ""
- [(set_attr "type" "mmx")])
-
(define_insn "movti_internal"
[(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
(match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
"TARGET_SSE && !TARGET_64BIT
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
- "@
- xorps\t%0, %0
- movaps\t{%1, %0|%0, %1}
- movaps\t{%1, %0|%0, %1}"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "pxor\t%0, %0";
+ case 1:
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movdqa\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
+}
[(set_attr "type" "ssemov,ssemov,ssemov")
- (set_attr "mode" "V4SF")])
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "0,1")
+ (if_then_else
+ (ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (const_string "TI"))
+ (eq_attr "alternative" "2")
+ (if_then_else
+ (ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (const_string "TI"))]
+ (const_string "TI")))])
(define_insn "*movti_rex64"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,mx,x")
- (match_operand:TI 1 "general_operand" "riFo,riF,C,x,m"))]
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
+ (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
"TARGET_64BIT
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
- "@
- #
- #
- xorps\t%0, %0
- movaps\\t{%1, %0|%0, %1}
- movaps\\t{%1, %0|%0, %1}"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ return "#";
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "pxor\t%0, %0";
+ case 3:
+ case 4:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movdqa\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
+}
[(set_attr "type" "*,*,ssemov,ssemov,ssemov")
- (set_attr "mode" "V4SF")])
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "2,3")
+ (if_then_else
+ (ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (const_string "TI"))
+ (eq_attr "alternative" "4")
+ (if_then_else
+ (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
+ (const_int 0))
+ (ne (symbol_ref "optimize_size")
+ (const_int 0)))
+ (const_string "V4SF")
+ (const_string "TI"))]
+ (const_string "DI")))])
+
+(define_insn "*movtf_rex64"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
+ (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
+ "TARGET_64BIT
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ case 1:
+ return "#";
+ case 2:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "xorps\t%0, %0";
+ else
+ return "pxor\t%0, %0";
+ case 3:
+ case 4:
+ if (get_attr_mode (insn) == MODE_V4SF)
+ return "movaps\t{%1, %0|%0, %1}";
+ else
+ return "movdqa\t{%1, %0|%0, %1}";
+ default:
+ abort ();
+ }
+}
+ [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
+ (set (attr "mode")
+ (cond [(eq_attr "alternative" "2,3")
+ (if_then_else
+ (ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (const_string "TI"))
+ (eq_attr "alternative" "4")
+ (if_then_else
+ (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
+ (const_int 0))
+ (ne (symbol_ref "optimize_size")
+ (const_int 0)))
+ (const_string "V4SF")
+ (const_string "TI"))]
+ (const_string "DI")))])
(define_split
[(set (match_operand:TI 0 "nonimmediate_operand" "")
@@ -18311,6 +19050,14 @@
[(const_int 0)]
"ix86_split_long_move (operands); DONE;")
+(define_split
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (match_operand:TF 1 "general_operand" ""))]
+ "reload_completed && !SSE_REG_P (operands[0])
+ && !SSE_REG_P (operands[1])"
+ [(const_int 0)]
+ "ix86_split_long_move (operands); DONE;")
+
;; These two patterns are useful for specifying exactly whether to use
;; movaps or movups
(define_expand "sse_movaps"
@@ -18690,14 +19437,14 @@
;; on integral types. We deal with this by representing the floating point
;; logical as logical on arguments casted to TImode as this is what hardware
;; really does. Unfortunately hardware requires the type information to be
-;; present and thus we must avoid subregs from being simplified and elliminated
+;; present and thus we must avoid subregs from being simplified and eliminated
;; in later compilation phases.
;;
;; We have following variants from each instruction:
;; sse_andsf3 - the operation taking V4SF vector operands
;; and doing TImode cast on them
;; *sse_andsf3_memory - the operation taking one memory operand casted to
-;; TImode, since backend insist on elliminating casts
+;; TImode, since backend insist on eliminating casts
;; on memory operands
;; sse_andti3_sf_1 - the operation taking SF scalar operands.
;; We can not accept memory operand here as instruction reads
@@ -18705,7 +19452,7 @@
;; scalar float operations that expands to logicals (fabs)
;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
;; memory operand. Eventually combine can be able
-;; to synthetize these using splitter.
+;; to synthesize these using splitter.
;; sse2_anddf3, *sse2_anddf3_memory
;;
;;
@@ -18963,7 +19710,7 @@
(define_insn "sse2_nandv2di3"
[(set (match_operand:V2DI 0 "register_operand" "=x")
- (and:V2DI (not:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "0"))
+ (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
(match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
"TARGET_SSE2
&& (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
@@ -19015,12 +19762,26 @@
;; this insn.
(define_insn "sse_clrv4sf"
[(set (match_operand:V4SF 0 "register_operand" "=x")
- (unspec:V4SF [(const_int 0)] UNSPEC_NOP))]
+ (match_operand:V4SF 1 "const0_operand" "X"))]
"TARGET_SSE"
- "xorps\t{%0, %0|%0, %0}"
+{
+ if (get_attr_mode (insn) == MODE_TI)
+ return "pxor\t{%0, %0|%0, %0}";
+ else
+ return "xorps\t{%0, %0|%0, %0}";
+}
[(set_attr "type" "sselog")
(set_attr "memory" "none")
- (set_attr "mode" "V4SF")])
+ (set (attr "mode")
+ (if_then_else
+ (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
+ (const_int 0))
+ (ne (symbol_ref "TARGET_SSE2")
+ (const_int 0)))
+ (eq (symbol_ref "optimize_size")
+ (const_int 0)))
+ (const_string "TI")
+ (const_string "V4SF")))])
;; Use xor, but don't show input operands so they aren't live before
;; this insn.
@@ -19103,7 +19864,7 @@
(parallel [(const_int 0)]))))]
"TARGET_SSE"
"comiss\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecmp")
+ [(set_attr "type" "ssecomi")
(set_attr "mode" "SF")])
(define_insn "sse_ucomi"
@@ -19116,7 +19877,7 @@
(parallel [(const_int 0)]))))]
"TARGET_SSE"
"ucomiss\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecmp")
+ [(set_attr "type" "ssecomi")
(set_attr "mode" "SF")])
@@ -19241,15 +20002,16 @@
(set_attr "mode" "SF")])
(define_insn "cvtsi2ss"
- [(set (match_operand:V4SF 0 "register_operand" "=x")
+ [(set (match_operand:V4SF 0 "register_operand" "=x,x")
(vec_merge:V4SF
- (match_operand:V4SF 1 "register_operand" "0")
+ (match_operand:V4SF 1 "register_operand" "0,0")
(vec_duplicate:V4SF
- (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm")))
+ (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
(const_int 14)))]
"TARGET_SSE"
"cvtsi2ss\t{%2, %0|%0, %2}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "sseicvt")
+ (set_attr "athlon_decode" "vector,double")
(set_attr "mode" "SF")])
(define_insn "cvtsi2ssq"
@@ -19261,19 +20023,20 @@
(const_int 14)))]
"TARGET_SSE && TARGET_64BIT"
"cvtsi2ssq\t{%2, %0|%0, %2}"
- [(set_attr "type" "ssecvt")
- (set_attr "athlon_decode" "vector,vector")
+ [(set_attr "type" "sseicvt")
+ (set_attr "athlon_decode" "vector,double")
(set_attr "mode" "SF")])
(define_insn "cvtss2si"
- [(set (match_operand:SI 0 "register_operand" "=r")
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
(vec_select:SI
- (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
+ (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
(parallel [(const_int 0)])))]
"TARGET_SSE"
"cvtss2si\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
- (set_attr "mode" "SF")])
+ [(set_attr "type" "sseicvt")
+ (set_attr "athlon_decode" "double,vector")
+ (set_attr "mode" "SI")])
(define_insn "cvtss2siq"
[(set (match_operand:DI 0 "register_operand" "=r,r")
@@ -19282,20 +20045,21 @@
(parallel [(const_int 0)])))]
"TARGET_SSE"
"cvtss2siq\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
- (set_attr "athlon_decode" "vector,vector")
- (set_attr "mode" "SF")])
+ [(set_attr "type" "sseicvt")
+ (set_attr "athlon_decode" "double,vector")
+ (set_attr "mode" "DI")])
(define_insn "cvttss2si"
- [(set (match_operand:SI 0 "register_operand" "=r")
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
(vec_select:SI
- (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
+ (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
UNSPEC_FIX)
(parallel [(const_int 0)])))]
"TARGET_SSE"
"cvttss2si\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
- (set_attr "mode" "SF")])
+ [(set_attr "type" "sseicvt")
+ (set_attr "mode" "SF")
+ (set_attr "athlon_decode" "double,vector")])
(define_insn "cvttss2siq"
[(set (match_operand:DI 0 "register_operand" "=r,r")
@@ -19305,9 +20069,9 @@
(parallel [(const_int 0)])))]
"TARGET_SSE && TARGET_64BIT"
"cvttss2siq\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "sseicvt")
(set_attr "mode" "SF")
- (set_attr "athlon_decode" "vector,vector")])
+ (set_attr "athlon_decode" "double,vector")])
;; MMX insns
@@ -19639,7 +20403,7 @@
(vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
(vec_duplicate:V4HI
(truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
- (match_operand:SI 3 "immediate_operand" "i")))]
+ (match_operand:SI 3 "const_0_to_15_operand" "N")))]
"TARGET_SSE || TARGET_3DNOW_A"
"pinsrw\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "mmxcvt")
@@ -19649,7 +20413,7 @@
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
(parallel
- [(match_operand:SI 2 "immediate_operand" "i")]))))]
+ [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
"TARGET_SSE || TARGET_3DNOW_A"
"pextrw\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "mmxcvt")
@@ -20100,7 +20864,7 @@
output_asm_insn (\"rex\", operands);
output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
}
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
CODE_LABEL_NUMBER (operands[3]));
RET;
}
@@ -20330,7 +21094,7 @@
[(set_attr "type" "mmxshft")
(set_attr "mode" "TI")])
-;; 3DNow reciprical and sqrt
+;; 3DNow reciprocal and sqrt
(define_insn "pfrcpv2sf2"
[(set (match_operand:V2SF 0 "register_operand" "=y")
@@ -20724,7 +21488,7 @@
(parallel [(const_int 0)]))))]
"TARGET_SSE2"
"comisd\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecmp")
+ [(set_attr "type" "ssecomi")
(set_attr "mode" "DF")])
(define_insn "sse2_ucomi"
@@ -20737,7 +21501,7 @@
(parallel [(const_int 0)]))))]
"TARGET_SSE2"
"ucomisd\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecmp")
+ [(set_attr "type" "ssecomi")
(set_attr "mode" "DF")])
;; SSE Strange Moves.
@@ -20901,31 +21665,34 @@
;; Conversions between SI and DF
(define_insn "cvtsd2si"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
(parallel [(const_int 0)]))))]
"TARGET_SSE2"
"cvtsd2si\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "sseicvt")
+ (set_attr "athlon_decode" "double,vector")
(set_attr "mode" "SI")])
(define_insn "cvtsd2siq"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
(parallel [(const_int 0)]))))]
"TARGET_SSE2 && TARGET_64BIT"
"cvtsd2siq\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
- (set_attr "mode" "SI")])
+ [(set_attr "type" "sseicvt")
+ (set_attr "athlon_decode" "double,vector")
+ (set_attr "mode" "DI")])
(define_insn "cvttsd2si"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "xm")
+ [(set (match_operand:SI 0 "register_operand" "=r,r")
+ (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
(parallel [(const_int 0)]))] UNSPEC_FIX))]
"TARGET_SSE2"
"cvttsd2si\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
- (set_attr "mode" "SI")])
+ [(set_attr "type" "sseicvt")
+ (set_attr "mode" "SI")
+ (set_attr "athlon_decode" "double,vector")])
(define_insn "cvttsd2siq"
[(set (match_operand:DI 0 "register_operand" "=r,r")
@@ -20933,21 +21700,22 @@
(parallel [(const_int 0)]))] UNSPEC_FIX))]
"TARGET_SSE2 && TARGET_64BIT"
"cvttsd2siq\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "sseicvt")
(set_attr "mode" "DI")
- (set_attr "athlon_decode" "vector,vector")])
+ (set_attr "athlon_decode" "double,vector")])
(define_insn "cvtsi2sd"
- [(set (match_operand:V2DF 0 "register_operand" "=x")
- (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
+ [(set (match_operand:V2DF 0 "register_operand" "=x,x")
+ (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
(vec_duplicate:V2DF
(float:DF
- (match_operand:SI 2 "nonimmediate_operand" "rm")))
+ (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
(const_int 2)))]
"TARGET_SSE2"
"cvtsi2sd\t{%2, %0|%0, %2}"
- [(set_attr "type" "ssecvt")
- (set_attr "mode" "DF")])
+ [(set_attr "type" "sseicvt")
+ (set_attr "mode" "DF")
+ (set_attr "athlon_decode" "double,direct")])
(define_insn "cvtsi2sdq"
[(set (match_operand:V2DF 0 "register_operand" "=x,x")
@@ -20958,22 +21726,23 @@
(const_int 2)))]
"TARGET_SSE2 && TARGET_64BIT"
"cvtsi2sdq\t{%2, %0|%0, %2}"
- [(set_attr "type" "ssecvt")
+ [(set_attr "type" "sseicvt")
(set_attr "mode" "DF")
- (set_attr "athlon_decode" "vector,direct")])
+ (set_attr "athlon_decode" "double,direct")])
;; Conversions between SF and DF
(define_insn "cvtsd2ss"
- [(set (match_operand:V4SF 0 "register_operand" "=x")
- (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0")
+ [(set (match_operand:V4SF 0 "register_operand" "=x,x")
+ (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
(vec_duplicate:V4SF
(float_truncate:V2SF
- (match_operand:V2DF 2 "register_operand" "xm")))
+ (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
(const_int 14)))]
"TARGET_SSE2"
"cvtsd2ss\t{%2, %0|%0, %2}"
[(set_attr "type" "ssecvt")
+ (set_attr "athlon_decode" "vector,double")
(set_attr "mode" "SF")])
(define_insn "cvtss2sd"
@@ -20981,7 +21750,7 @@
(vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
(float_extend:V2DF
(vec_select:V2SF
- (match_operand:V4SF 2 "register_operand" "xm")
+ (match_operand:V4SF 2 "nonimmediate_operand" "xm")
(parallel [(const_int 0)
(const_int 1)])))
(const_int 2)))]
@@ -21257,10 +22026,20 @@
(define_insn "sse2_clrti"
[(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
"TARGET_SSE2"
- "pxor\t{%0, %0|%0, %0}"
- [(set_attr "type" "sseiadd")
+{
+ if (get_attr_mode (insn) == MODE_TI)
+ return "pxor\t%0, %0";
+ else
+ return "xorps\t%0, %0";
+}
+ [(set_attr "type" "ssemov")
(set_attr "memory" "none")
- (set_attr "mode" "TI")])
+ (set (attr "mode")
+ (if_then_else
+ (ne (symbol_ref "optimize_size")
+ (const_int 0))
+ (const_string "V4SF")
+ (const_string "TI")))])
;; MMX unsigned averages/sum of absolute differences
@@ -21320,7 +22099,7 @@
(vec_duplicate:V8HI
(truncate:HI
(match_operand:SI 2 "nonimmediate_operand" "rm")))
- (match_operand:SI 3 "immediate_operand" "i")))]
+ (match_operand:SI 3 "const_0_to_255_operand" "N")))]
"TARGET_SSE2"
"pinsrw\t{%3, %2, %0|%0, %2, %3}"
[(set_attr "type" "ssecvt")
@@ -21331,7 +22110,7 @@
(zero_extend:SI
(vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
(parallel
- [(match_operand:SI 2 "immediate_operand" "i")]))))]
+ [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
"TARGET_SSE2"
"pextrw\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "ssecvt")
@@ -21468,7 +22247,7 @@
(define_insn "ashrv8hi3"
[(set (match_operand:V8HI 0 "register_operand" "=x")
(ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
- (match_operand:TI 2 "nonmemory_operand" "xi")))]
+ (match_operand:SI 2 "nonmemory_operand" "xi")))]
"TARGET_SSE2"
"psraw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21477,7 +22256,7 @@
(define_insn "ashrv4si3"
[(set (match_operand:V4SI 0 "register_operand" "=x")
(ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
- (match_operand:TI 2 "nonmemory_operand" "xi")))]
+ (match_operand:SI 2 "nonmemory_operand" "xi")))]
"TARGET_SSE2"
"psrad\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21486,7 +22265,7 @@
(define_insn "lshrv8hi3"
[(set (match_operand:V8HI 0 "register_operand" "=x")
(lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
- (match_operand:TI 2 "nonmemory_operand" "xi")))]
+ (match_operand:SI 2 "nonmemory_operand" "xi")))]
"TARGET_SSE2"
"psrlw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21495,7 +22274,7 @@
(define_insn "lshrv4si3"
[(set (match_operand:V4SI 0 "register_operand" "=x")
(lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
- (match_operand:TI 2 "nonmemory_operand" "xi")))]
+ (match_operand:SI 2 "nonmemory_operand" "xi")))]
"TARGET_SSE2"
"psrld\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21504,7 +22283,7 @@
(define_insn "lshrv2di3"
[(set (match_operand:V2DI 0 "register_operand" "=x")
(lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
- (match_operand:TI 2 "nonmemory_operand" "xi")))]
+ (match_operand:SI 2 "nonmemory_operand" "xi")))]
"TARGET_SSE2"
"psrlq\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21513,7 +22292,7 @@
(define_insn "ashlv8hi3"
[(set (match_operand:V8HI 0 "register_operand" "=x")
(ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
- (match_operand:TI 2 "nonmemory_operand" "xi")))]
+ (match_operand:SI 2 "nonmemory_operand" "xi")))]
"TARGET_SSE2"
"psllw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21522,7 +22301,7 @@
(define_insn "ashlv4si3"
[(set (match_operand:V4SI 0 "register_operand" "=x")
(ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
- (match_operand:TI 2 "nonmemory_operand" "xi")))]
+ (match_operand:SI 2 "nonmemory_operand" "xi")))]
"TARGET_SSE2"
"pslld\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21531,7 +22310,7 @@
(define_insn "ashlv2di3"
[(set (match_operand:V2DI 0 "register_operand" "=x")
(ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
- (match_operand:TI 2 "nonmemory_operand" "xi")))]
+ (match_operand:SI 2 "nonmemory_operand" "xi")))]
"TARGET_SSE2"
"psllq\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21540,7 +22319,7 @@
(define_insn "ashrv8hi3_ti"
[(set (match_operand:V8HI 0 "register_operand" "=x")
(ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
- (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
+ (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
"TARGET_SSE2"
"psraw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21549,7 +22328,7 @@
(define_insn "ashrv4si3_ti"
[(set (match_operand:V4SI 0 "register_operand" "=x")
(ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
- (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
+ (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
"TARGET_SSE2"
"psrad\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21558,7 +22337,7 @@
(define_insn "lshrv8hi3_ti"
[(set (match_operand:V8HI 0 "register_operand" "=x")
(lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
- (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
+ (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
"TARGET_SSE2"
"psrlw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21567,7 +22346,7 @@
(define_insn "lshrv4si3_ti"
[(set (match_operand:V4SI 0 "register_operand" "=x")
(lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
- (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
+ (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
"TARGET_SSE2"
"psrld\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21576,7 +22355,7 @@
(define_insn "lshrv2di3_ti"
[(set (match_operand:V2DI 0 "register_operand" "=x")
(lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
- (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
+ (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
"TARGET_SSE2"
"psrlq\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21585,7 +22364,7 @@
(define_insn "ashlv8hi3_ti"
[(set (match_operand:V8HI 0 "register_operand" "=x")
(ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
- (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
+ (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
"TARGET_SSE2"
"psllw\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21594,7 +22373,7 @@
(define_insn "ashlv4si3_ti"
[(set (match_operand:V4SI 0 "register_operand" "=x")
(ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
- (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
+ (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
"TARGET_SSE2"
"pslld\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21603,7 +22382,7 @@
(define_insn "ashlv2di3_ti"
[(set (match_operand:V2DI 0 "register_operand" "=x")
(ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
- (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
+ (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
"TARGET_SSE2"
"psllq\t{%2, %0|%0, %2}"
[(set_attr "type" "sseishft")
@@ -21640,26 +22419,26 @@
(define_insn "sse2_unpckhpd"
[(set (match_operand:V2DF 0 "register_operand" "=x")
(vec_concat:V2DF
- (vec_select:V2DF (match_operand:V2DF 1 "register_operand" "0")
- (parallel [(const_int 1)]))
- (vec_select:V2DF (match_operand:V2DF 2 "register_operand" "x")
- (parallel [(const_int 0)]))))]
+ (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
+ (parallel [(const_int 1)]))
+ (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
+ (parallel [(const_int 1)]))))]
"TARGET_SSE2"
"unpckhpd\t{%2, %0|%0, %2}"
[(set_attr "type" "ssecvt")
- (set_attr "mode" "TI")])
+ (set_attr "mode" "V2DF")])
(define_insn "sse2_unpcklpd"
[(set (match_operand:V2DF 0 "register_operand" "=x")
(vec_concat:V2DF
- (vec_select:V2DF (match_operand:V2DF 1 "register_operand" "0")
- (parallel [(const_int 0)]))
- (vec_select:V2DF (match_operand:V2DF 2 "register_operand" "x")
- (parallel [(const_int 1)]))))]
+ (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
+ (parallel [(const_int 0)]))
+ (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
+ (parallel [(const_int 0)]))))]
"TARGET_SSE2"
"unpcklpd\t{%2, %0|%0, %2}"
[(set_attr "type" "ssecvt")
- (set_attr "mode" "TI")])
+ (set_attr "mode" "V2DF")])
;; MMX pack/unpack insns.
@@ -21975,17 +22754,6 @@
[(set_attr "type" "ssecvt")
(set_attr "mode" "V2DF")])
-(define_insn "sse2_movlpd"
- [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
- (vec_merge:V2DF
- (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
- (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
- (const_int 1)))]
- "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
- "movlpd\t{%2, %0|%0, %2}"
- [(set_attr "type" "ssecvt")
- (set_attr "mode" "V2DF")])
-
(define_expand "sse2_loadsd"
[(match_operand:V2DF 0 "register_operand" "")
(match_operand:DF 1 "memory_operand" "")]
@@ -22008,15 +22776,17 @@
(set_attr "mode" "DF")])
(define_insn "sse2_movsd"
- [(set (match_operand:V2DF 0 "register_operand" "=x")
+ [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
(vec_merge:V2DF
- (match_operand:V2DF 1 "register_operand" "0")
- (match_operand:V2DF 2 "register_operand" "x")
+ (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
+ (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
(const_int 1)))]
- "TARGET_SSE2"
- "movsd\t{%2, %0|%0, %2}"
+ "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
+ "@movsd\t{%2, %0|%0, %2}
+ movlpd\t{%2, %0|%0, %2}
+ movlpd\t{%2, %0|%0, %2}"
[(set_attr "type" "ssecvt")
- (set_attr "mode" "DF")])
+ (set_attr "mode" "DF,V2DF,V2DF")])
(define_insn "sse2_storesd"
[(set (match_operand:DF 0 "memory_operand" "=m")
@@ -22082,13 +22852,13 @@
[(set_attr "type" "sse")
(set_attr "memory" "unknown")])
-;; PNI
+;; SSE3
(define_insn "mwait"
[(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
(match_operand:SI 1 "register_operand" "c")]
UNSPECV_MWAIT)]
- "TARGET_PNI"
+ "TARGET_SSE3"
"mwait\t%0, %1"
[(set_attr "length" "3")])
@@ -22097,18 +22867,18 @@
(match_operand:SI 1 "register_operand" "c")
(match_operand:SI 2 "register_operand" "d")]
UNSPECV_MONITOR)]
- "TARGET_PNI"
+ "TARGET_SSE3"
"monitor\t%0, %1, %2"
[(set_attr "length" "3")])
-;; PNI arithmetic
+;; SSE3 arithmetic
(define_insn "addsubv4sf3"
[(set (match_operand:V4SF 0 "register_operand" "=x")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm")]
UNSPEC_ADDSUB))]
- "TARGET_PNI"
+ "TARGET_SSE3"
"addsubps\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "V4SF")])
@@ -22118,7 +22888,7 @@
(unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
(match_operand:V2DF 2 "nonimmediate_operand" "xm")]
UNSPEC_ADDSUB))]
- "TARGET_PNI"
+ "TARGET_SSE3"
"addsubpd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "V2DF")])
@@ -22128,7 +22898,7 @@
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm")]
UNSPEC_HADD))]
- "TARGET_PNI"
+ "TARGET_SSE3"
"haddps\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "V4SF")])
@@ -22138,7 +22908,7 @@
(unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
(match_operand:V2DF 2 "nonimmediate_operand" "xm")]
UNSPEC_HADD))]
- "TARGET_PNI"
+ "TARGET_SSE3"
"haddpd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "V2DF")])
@@ -22148,7 +22918,7 @@
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
(match_operand:V4SF 2 "nonimmediate_operand" "xm")]
UNSPEC_HSUB))]
- "TARGET_PNI"
+ "TARGET_SSE3"
"hsubps\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "V4SF")])
@@ -22158,7 +22928,7 @@
(unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
(match_operand:V2DF 2 "nonimmediate_operand" "xm")]
UNSPEC_HSUB))]
- "TARGET_PNI"
+ "TARGET_SSE3"
"hsubpd\t{%2, %0|%0, %2}"
[(set_attr "type" "sseadd")
(set_attr "mode" "V2DF")])
@@ -22167,7 +22937,7 @@
[(set (match_operand:V4SF 0 "register_operand" "=x")
(unspec:V4SF
[(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
- "TARGET_PNI"
+ "TARGET_SSE3"
"movshdup\t{%1, %0|%0, %1}"
[(set_attr "type" "sse")
(set_attr "mode" "V4SF")])
@@ -22176,7 +22946,7 @@
[(set (match_operand:V4SF 0 "register_operand" "=x")
(unspec:V4SF
[(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
- "TARGET_PNI"
+ "TARGET_SSE3"
"movsldup\t{%1, %0|%0, %1}"
[(set_attr "type" "sse")
(set_attr "mode" "V4SF")])
@@ -22185,7 +22955,7 @@
[(set (match_operand:V16QI 0 "register_operand" "=x")
(unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
UNSPEC_LDQQU))]
- "TARGET_PNI"
+ "TARGET_SSE3"
"lddqu\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecvt")
(set_attr "mode" "TI")])
@@ -22193,7 +22963,7 @@
(define_insn "loadddup"
[(set (match_operand:V2DF 0 "register_operand" "=x")
(vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
- "TARGET_PNI"
+ "TARGET_SSE3"
"movddup\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecvt")
(set_attr "mode" "DF")])
@@ -22203,7 +22973,7 @@
(vec_duplicate:V2DF
(vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
(parallel [(const_int 0)]))))]
- "TARGET_PNI"
+ "TARGET_SSE3"
"movddup\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecvt")
(set_attr "mode" "DF")])
diff --git a/contrib/gcc/config/i386/i386elf.h b/contrib/gcc/config/i386/i386elf.h
index cd01db2a54ea..ed6b41aa9b3f 100644
--- a/contrib/gcc/config/i386/i386elf.h
+++ b/contrib/gcc/config/i386/i386elf.h
@@ -1,23 +1,23 @@
-/* Target definitions for GNU compiler for Intel 80386 using ELF
+/* Target definitions for GCC for Intel 80386 using ELF
Copyright (C) 1988, 1991, 1995, 2000, 2001, 2002
Free Software Foundation, Inc.
Derived from sysv4.h written by Ron Guilmette (rfg@netcom.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -65,13 +65,13 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
do \
{ \
- register const unsigned char *_ascii_bytes = \
+ const unsigned char *_ascii_bytes = \
(const unsigned char *) (STR); \
- register const unsigned char *limit = _ascii_bytes + (LENGTH); \
- register unsigned bytes_in_chunk = 0; \
+ const unsigned char *limit = _ascii_bytes + (LENGTH); \
+ unsigned bytes_in_chunk = 0; \
for (; _ascii_bytes < limit; _ascii_bytes++) \
{ \
- register const unsigned char *p; \
+ const unsigned char *p; \
if (bytes_in_chunk >= 64) \
{ \
fputc ('\n', (FILE)); \
diff --git a/contrib/gcc/config/i386/k6.md b/contrib/gcc/config/i386/k6.md
index af128bfe0376..edd12f63c5c2 100644
--- a/contrib/gcc/config/i386/k6.md
+++ b/contrib/gcc/config/i386/k6.md
@@ -1,20 +1,20 @@
;; AMD K6/K6-2 Scheduling
;; Copyright (C) 2002 ;; Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA. */
;;
@@ -31,7 +31,7 @@
;; fpu describes FPU unit
;; load describes load unit.
;; branch describes branch unit.
-;; store decsribes store unit. This unit is not modelled completely and only
+;; store describes store unit. This unit is not modelled completely and only
;; used to model lea operation. Otherwise it lie outside of the critical
;; path.
;;
@@ -49,7 +49,7 @@
(define_function_unit "k6_alux" 1 0
(and (eq_attr "cpu" "k6")
(and (eq_attr "type" "alu,alu1,negnot,icmp,test,imovx,incdec")
- (match_operand:QI 0 "general_operand" "")))
+ (eq_attr "mode" "QI")))
1 1)
(define_function_unit "k6_alu" 2 0
@@ -71,7 +71,7 @@
;; Load unit have two cycle latency, but we take care for it in adjust_cost
(define_function_unit "k6_load" 1 0
(and (eq_attr "cpu" "k6")
- (ior (eq_attr "type" "pop")
+ (ior (eq_attr "type" "pop,leave")
(eq_attr "memory" "load,both")))
1 1)
diff --git a/contrib/gcc/config/i386/kaos-i386.h b/contrib/gcc/config/i386/kaos-i386.h
new file mode 100644
index 000000000000..3fdf883101aa
--- /dev/null
+++ b/contrib/gcc/config/i386/kaos-i386.h
@@ -0,0 +1,24 @@
+/* Definitions of target machine for GCC.
+ kaOS on ia32 architecture version.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fputs (" (i386/kaOS[ELF])", stderr);
+
diff --git a/contrib/gcc/config/i386/kfreebsdgnu.h b/contrib/gcc/config/i386/kfreebsdgnu.h
new file mode 100644
index 000000000000..66b231dc809f
--- /dev/null
+++ b/contrib/gcc/config/i386/kfreebsdgnu.h
@@ -0,0 +1,35 @@
+/* Definitions for Intel 386 running GNU/KFreeBSD systems with ELF format.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Bruno Haible.
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (i386 KFreeBSD/ELF)");
+
+/* FIXME: Is a KFreeBSD-specific fallback mechanism necessary? */
+#undef MD_FALLBACK_FRAME_STATE_FOR
+
+#undef LINK_SPEC
+#define LINK_SPEC "-m elf_i386_fbsd %{shared:-shared} \
+ %{!shared: \
+ %{!ibcs: \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}} \
+ %{static:-static}}}"
diff --git a/contrib/gcc/config/i386/linux-aout.h b/contrib/gcc/config/i386/linux-aout.h
index 783b8a946edb..d7be93c73128 100644
--- a/contrib/gcc/config/i386/linux-aout.h
+++ b/contrib/gcc/config/i386/linux-aout.h
@@ -3,20 +3,20 @@
Free Software Foundation, Inc.
Contributed by H.J. Lu (hjl@nynexst.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -26,10 +26,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- builtin_define_std ("linux"); \
- builtin_define_std ("unix"); \
- builtin_define ("__gnu_linux__"); \
- builtin_assert ("system=posix"); \
+ LINUX_TARGET_OS_CPP_BUILTINS(); \
if (flag_pic) \
{ \
builtin_define ("__PIC__"); \
diff --git a/contrib/gcc/config/i386/linux.h b/contrib/gcc/config/i386/linux.h
index 6b553cd4cb57..e7d19ec181a2 100644
--- a/contrib/gcc/config/i386/linux.h
+++ b/contrib/gcc/config/i386/linux.h
@@ -4,34 +4,26 @@
Contributed by Eric Youngdale.
Modified for stabs-in-ELF by H.J. Lu.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define LINUX_DEFAULT_ELF
-
/* Output at beginning of assembler file. */
/* The .file command should always begin the output. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { \
- output_file_directive (FILE, main_input_filename); \
- if (ix86_asm_dialect == ASM_INTEL) \
- fputs ("\t.intel_syntax\n", FILE); \
- } while (0)
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
#define TARGET_VERSION fprintf (stderr, " (i386 Linux/ELF)");
@@ -40,6 +32,10 @@ Boston, MA 02111-1307, USA. */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 1
+/* We arrange for the whole %gs segment to map the tls area. */
+#undef TARGET_TLS_DIRECT_SEG_REFS_DEFAULT
+#define TARGET_TLS_DIRECT_SEG_REFS_DEFAULT MASK_TLS_DIRECT_SEG_REFS
+
#undef ASM_COMMENT_START
#define ASM_COMMENT_START "#"
@@ -51,7 +47,7 @@ Boston, MA 02111-1307, USA. */
To the best of my knowledge, no Linux libc has required the label
argument to mcount. */
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS 1
#undef MCOUNT_NAME
#define MCOUNT_NAME "mcount"
@@ -77,11 +73,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- builtin_define_std ("linux"); \
- builtin_define_std ("unix"); \
- builtin_define ("__ELF__"); \
- builtin_define ("__gnu_linux__"); \
- builtin_assert ("system=posix"); \
+ LINUX_TARGET_OS_CPP_BUILTINS(); \
if (flag_pic) \
{ \
builtin_define ("__PIC__"); \
@@ -118,15 +110,6 @@ Boston, MA 02111-1307, USA. */
#undef LINK_SPEC
#ifdef USE_GNULIBC_1
-#ifndef LINUX_DEFAULT_ELF
-#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
- %{!shared: \
- %{!ibcs: \
- %{!static: \
- %{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /lib/elf/ld-linux.so.1} \
- %{!rpath:-rpath /lib/elf/}} %{static:-static}}}"
-#else
#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
%{!shared: \
%{!ibcs: \
@@ -134,7 +117,6 @@ Boston, MA 02111-1307, USA. */
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.1}} \
%{static:-static}}}"
-#endif
#else
#define LINK_SPEC "-m elf_i386 %{shared:-shared} \
%{!shared: \
@@ -220,6 +202,9 @@ Boston, MA 02111-1307, USA. */
: "=d"(BASE))
#endif
+#undef NEED_INDICATE_EXEC_STACK
+#define NEED_INDICATE_EXEC_STACK 1
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
@@ -228,7 +213,7 @@ Boston, MA 02111-1307, USA. */
signal-turned-exceptions for them. There's also no configure-run for
the target, so we can't check on (e.g.) HAVE_SYS_UCONTEXT_H. Using the
target libc1 macro should be enough. */
-#ifndef USE_GNULIBC_1
+#if !(defined (USE_GNULIBC_1) || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0))
#include <signal.h>
#include <sys/ucontext.h>
diff --git a/contrib/gcc/config/i386/linux64.h b/contrib/gcc/config/i386/linux64.h
index 7a9e0ba989f0..98536c19bd37 100644
--- a/contrib/gcc/config/i386/linux64.h
+++ b/contrib/gcc/config/i386/linux64.h
@@ -1,46 +1,35 @@
/* Definitions for AMD x86-64 running Linux-based GNU systems with ELF format.
- Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002 Free Software Foundation, Inc.
Contributed by Jan Hubicka <jh@suse.cz>, based on linux.h.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define LINUX_DEFAULT_ELF
-
#define TARGET_VERSION fprintf (stderr, " (x86-64 Linux/ELF)");
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- builtin_define_std ("linux"); \
- builtin_define_std ("unix"); \
- builtin_define ("__gnu_linux__"); \
- builtin_define ("__ELF__"); \
- builtin_assert ("system=posix"); \
+ LINUX_TARGET_OS_CPP_BUILTINS(); \
if (flag_pic) \
{ \
builtin_define ("__PIC__"); \
builtin_define ("__pic__"); \
} \
- if (TARGET_64BIT) \
- { \
- builtin_define ("__LP64__"); \
- builtin_define ("_LP64"); \
- } \
} \
while (0)
@@ -53,6 +42,10 @@ Boston, MA 02111-1307, USA. */
#undef DEFAULT_PCC_STRUCT_RETURN
#define DEFAULT_PCC_STRUCT_RETURN 1
+/* We arrange for the whole %fs segment to map the tls area. */
+#undef TARGET_TLS_DIRECT_SEG_REFS_DEFAULT
+#define TARGET_TLS_DIRECT_SEG_REFS_DEFAULT MASK_TLS_DIRECT_SEG_REFS
+
/* Provide a LINK_SPEC. Here we provide support for the special GCC
options -static and -shared, which allow us to link things in one
of these three modes by applying the appropriate combinations of
@@ -71,19 +64,11 @@ Boston, MA 02111-1307, USA. */
%{!m32:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} \
%{static:-static}}"
-#undef STARTFILE_SPEC
-#define STARTFILE_SPEC \
- "%{!shared: \
- %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
- %{!p:%{profile:gcrt1.o%s} %{!profile:crt1.o%s}}}} \
- crti.o%s %{static:crtbeginT.o%s} \
- %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
-
-#undef ENDFILE_SPEC
-#define ENDFILE_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
-
#define MULTILIB_DEFAULTS { "m64" }
+#undef NEED_INDICATE_EXEC_STACK
+#define NEED_INDICATE_EXEC_STACK 1
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs.
Don't use this at all if inhibit_libc is used. */
diff --git a/contrib/gcc/config/i386/lynx-ng.h b/contrib/gcc/config/i386/lynx-ng.h
index 08fa60f430ca..536aa7af2035 100644
--- a/contrib/gcc/config/i386/lynx-ng.h
+++ b/contrib/gcc/config/i386/lynx-ng.h
@@ -1,20 +1,20 @@
/* Definitions for Intel 386 running LynxOS, using Lynx's old as and ld.
Copyright (C) 1993, 1995, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -68,10 +68,3 @@ Boston, MA 02111-1307, USA. */
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
sprintf ((BUF), ".%s%ld", (PREFIX), (long)(NUMBER))
-
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
diff --git a/contrib/gcc/config/i386/lynx.h b/contrib/gcc/config/i386/lynx.h
index 7835f2713f27..a926d14067c4 100644
--- a/contrib/gcc/config/i386/lynx.h
+++ b/contrib/gcc/config/i386/lynx.h
@@ -1,20 +1,20 @@
/* Definitions for Intel 386 running LynxOS.
Copyright (C) 1993, 1995, 1996, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -69,10 +69,3 @@ Boston, MA 02111-1307, USA. */
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
sprintf ((BUF), ".%s%ld", (PREFIX), (long)(NUMBER))
-
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
diff --git a/contrib/gcc/config/i386/mingw32.h b/contrib/gcc/config/i386/mingw32.h
index 7f62fbd5624a..4bf0dda1d98d 100644
--- a/contrib/gcc/config/i386/mingw32.h
+++ b/contrib/gcc/config/i386/mingw32.h
@@ -3,69 +3,42 @@
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Most of this is the same as for cygwin, except for changing some
- specs. */
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (x86 MinGW)");
-/* Mingw GCC, unlike Cygwin's, must be relocatable. This macro must
- be defined before any other files are included. */
-#ifndef WIN32_NO_ABSOLUTE_INST_DIRS
-#define WIN32_NO_ABSOLUTE_INST_DIRS 1
-#endif
-
-#include "i386/cygwin.h"
-
-#define TARGET_EXECUTABLE_SUFFIX ".exe"
-
-/* See i386/crtdll.h for an altervative definition. */
+/* See i386/crtdll.h for an alternative definition. */
#define EXTRA_OS_CPP_BUILTINS() \
do \
{ \
builtin_define ("__MSVCRT__"); \
builtin_define ("__MINGW32__"); \
+ builtin_define ("_WIN32"); \
+ builtin_define_std ("WIN32"); \
+ builtin_define_std ("WINNT"); \
} \
while (0)
-#undef TARGET_OS_CPP_BUILTINS /* From cygwin.h. */
-#define TARGET_OS_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("_WIN32"); \
- builtin_define_std ("WIN32"); \
- builtin_define_std ("WINNT"); \
- builtin_define ("_X86_=1"); \
- builtin_define ("__stdcall=__attribute__((__stdcall__))"); \
- builtin_define ("__cdecl=__attribute__((__cdecl__))"); \
- builtin_define ("__declspec(x)=__attribute__((x))"); \
- if (!flag_iso) \
- { \
- builtin_define ("_stdcall=__attribute__((__stdcall__))"); \
- builtin_define ("_cdecl=__attribute__((__cdecl__))"); \
- } \
- EXTRA_OS_CPP_BUILTINS (); \
- builtin_assert ("system=winnt"); \
- } \
- while (0)
-
-/* Specific a different directory for the standard include files. */
+/* Override the standard choice of /usr/include as the default prefix
+ to try when searching for header files. */
#undef STANDARD_INCLUDE_DIR
-#define STANDARD_INCLUDE_DIR "/usr/local/mingw32/include"
+#define STANDARD_INCLUDE_DIR "/mingw/include"
#undef STANDARD_INCLUDE_COMPONENT
#define STANDARD_INCLUDE_COMPONENT "MINGW"
@@ -96,12 +69,12 @@ Boston, MA 02111-1307, USA. */
#define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
%{!shared:%{!mdll:crt2%O%s}} %{pg:gcrt2%O%s}"
-/* MS runtime does not need a separate math library. */
-#undef MATH_LIBRARY
-#define MATH_LIBRARY ""
+/* An additional prefix to try after the standard prefixes. */
+#undef MD_STARTFILE_PREFIX
+#define MD_STARTFILE_PREFIX "/mingw/lib/"
/* Output STRING, a string representing a filename, to FILE.
- We canonicalize it to be in Unix format (backslashe are replaced
+ We canonicalize it to be in Unix format (backslashes are replaced
forward slashes. */
#undef OUTPUT_QUOTED_STRING
#define OUTPUT_QUOTED_STRING(FILE, STRING) \
@@ -128,6 +101,6 @@ do { \
putc ('\"', asm_file); \
} while (0)
-/* Define as short unsigned for compatability with MS runtime. */
+/* Define as short unsigned for compatibility with MS runtime. */
#undef WINT_TYPE
#define WINT_TYPE "short unsigned int"
diff --git a/contrib/gcc/config/i386/mmintrin.h b/contrib/gcc/config/i386/mmintrin.h
index 00e77e454a47..bd775e8e3a63 100644
--- a/contrib/gcc/config/i386/mmintrin.h
+++ b/contrib/gcc/config/i386/mmintrin.h
@@ -1,19 +1,19 @@
/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/moss.h b/contrib/gcc/config/i386/moss.h
index 642c625a3950..3b748cfe1d9f 100644
--- a/contrib/gcc/config/i386/moss.h
+++ b/contrib/gcc/config/i386/moss.h
@@ -2,20 +2,20 @@
Copyright (C) 1996, 2001 Free Software Foundation, Inc.
Contributed by Bryan Ford <baford@cs.utah.edu>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -24,7 +24,6 @@ Boston, MA 02111-1307, USA. */
do \
{ \
builtin_define_std ("moss"); \
- builtin_define ("__ELF__"); \
builtin_assert ("system=posix"); \
if (flag_pic) \
{ \
diff --git a/contrib/gcc/config/i386/netbsd-elf.h b/contrib/gcc/config/i386/netbsd-elf.h
index 4f49bd3e84fc..bd2e9de55e77 100644
--- a/contrib/gcc/config/i386/netbsd-elf.h
+++ b/contrib/gcc/config/i386/netbsd-elf.h
@@ -1,22 +1,22 @@
-/* Definitions of target machine for GNU compiler,
+/* Definitions of target machine for GCC,
for i386/ELF NetBSD systems.
Copyright (C) 2001, 2002 Free Software Foundation, Inc.
Contributed by matthew green <mrg@eterna.com.au>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -64,8 +64,6 @@ Boston, MA 02111-1307, USA. */
#undef ASM_APP_OFF
#define ASM_APP_OFF "#NO_APP\n"
-#undef ASM_FINAL_SPEC
-
#undef ASM_COMMENT_START
#define ASM_COMMENT_START "#"
@@ -76,7 +74,7 @@ Boston, MA 02111-1307, USA. */
/* Output assembler code to FILE to call the profiler. */
#undef NO_PROFILE_COUNTERS
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS 1
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(FILE, LABELNO) \
@@ -122,6 +120,6 @@ Boston, MA 02111-1307, USA. */
#define DEFAULT_PCC_STRUCT_RETURN 1
/* Attempt to enable execute permissions on the stack. */
-#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
+#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
#define TARGET_VERSION fprintf (stderr, " (NetBSD/i386 ELF)");
diff --git a/contrib/gcc/config/i386/netbsd.h b/contrib/gcc/config/i386/netbsd.h
index 45ae893595e6..dd7eae1a8478 100644
--- a/contrib/gcc/config/i386/netbsd.h
+++ b/contrib/gcc/config/i386/netbsd.h
@@ -69,4 +69,4 @@
#define GOT_SYMBOL_NAME "GLOBAL_OFFSET_TABLE_"
/* Attempt to enable execute permissions on the stack. */
-#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
+#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
diff --git a/contrib/gcc/config/i386/netbsd64.h b/contrib/gcc/config/i386/netbsd64.h
index 341b6d1189b9..66f31e03290f 100644
--- a/contrib/gcc/config/i386/netbsd64.h
+++ b/contrib/gcc/config/i386/netbsd64.h
@@ -1,22 +1,22 @@
-/* Definitions of target machine for GNU compiler,
+/* Definitions of target machine for GCC,
for x86-64/ELF NetBSD systems.
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -24,8 +24,6 @@ Boston, MA 02111-1307, USA. */
do \
{ \
NETBSD_OS_CPP_BUILTINS_ELF(); \
- if (TARGET_64BIT) \
- NETBSD_OS_CPP_BUILTINS_LP64(); \
} \
while (0)
@@ -70,6 +68,6 @@ Boston, MA 02111-1307, USA. */
}
/* Attempt to enable execute permissions on the stack. */
-#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
+#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
#define TARGET_VERSION fprintf (stderr, " (NetBSD/x86_64 ELF)");
diff --git a/contrib/gcc/config/i386/nto.h b/contrib/gcc/config/i386/nto.h
new file mode 100644
index 000000000000..8860c8becf59
--- /dev/null
+++ b/contrib/gcc/config/i386/nto.h
@@ -0,0 +1,99 @@
+/* Definitions for Intel 386 running QNX/Neutrino.
+ Copyright (C) 2002, 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef DEFAULT_PCC_STRUCT_RETURN
+#define DEFAULT_PCC_STRUCT_RETURN 1
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (QNX/Neutrino/i386 ELF)");
+
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("__X86__"); \
+ builtin_define_std ("__QNXNTO__"); \
+ builtin_define_std ("__QNX__"); \
+ builtin_define_std ("__ELF__"); \
+ builtin_define_std ("__LITTLEENDIAN__");\
+ builtin_assert ("system=qnx"); \
+ builtin_assert ("system=qnxnto"); \
+ builtin_assert ("system=nto"); \
+ builtin_assert ("system=unix"); \
+ if (flag_pic) \
+ { \
+ builtin_define ("__PIC__"); \
+ builtin_define ("__pic__"); \
+ } \
+ } \
+ while (0)
+
+#undef THREAD_MODEL_SPEC
+#define THREAD_MODEL_SPEC "posix"
+
+#ifdef CROSS_COMPILE
+#define SYSROOT_SUFFIX_SPEC "x86"
+#endif
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+"%{!shared: \
+ %{!symbolic: \
+ %{pg:mcrt1.o%s} \
+ %{!pg:%{p:mcrt1.o%s} \
+ %{!p:crt1.o%s}}}} \
+crti.o%s \
+%{fexceptions: crtbegin.o%s} \
+%{!fexceptions: %R/lib/crtbegin.o}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+ "crtend.o%s crtn.o%s"
+
+#undef LINK_SPEC
+#define LINK_SPEC \
+ "%{h*} %{v:-V} \
+ %{b} \
+ %{static:-dn -Bstatic} \
+ %{shared:-G -dy -z text} \
+ %{symbolic:-Bsymbolic -G -dy -z text} \
+ %{G:-G} \
+ %{YP,*} \
+ %{!YP,*:%{p:-Y P,%R/lib} \
+ %{!p:-Y P,%R/lib}} \
+ %{Qy:} %{!Qn:-Qy} \
+ -m i386nto \
+ %{!shared: --dynamic-linker /usr/lib/ldqnx.so.2}"
+
+
+#undef SIZE_TYPE
+#define SIZE_TYPE "unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "int"
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "long unsigned int"
+
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
+
+#define NO_IMPLICIT_EXTERN_C 1
+
diff --git a/contrib/gcc/config/i386/openbsd.h b/contrib/gcc/config/i386/openbsd.h
index 60f16575e21d..14de0188c801 100644
--- a/contrib/gcc/config/i386/openbsd.h
+++ b/contrib/gcc/config/i386/openbsd.h
@@ -1,20 +1,20 @@
/* Configuration for an OpenBSD i386 target.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -90,8 +90,7 @@ Boston, MA 02111-1307, USA. */
/* Assembler format: exception region output. */
/* All configurations that don't use elf must be explicit about not using
- dwarf unwind information. egcs doesn't try too hard to check internal
- configuration files... */
+ dwarf unwind information. */
#define DWARF2_UNWIND_INFO 0
#undef ASM_PREFERRED_EH_DATA_FORMAT
diff --git a/contrib/gcc/config/i386/pentium.md b/contrib/gcc/config/i386/pentium.md
index b4c5ece3678a..5fec8113b737 100644
--- a/contrib/gcc/config/i386/pentium.md
+++ b/contrib/gcc/config/i386/pentium.md
@@ -1,20 +1,20 @@
;; Pentium Scheduling
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA. */
;;
@@ -34,7 +34,7 @@
;; while MMX Pentium can slot it on either U or V. Model non-MMX Pentium
;; rules, because it results in noticeably better code on non-MMX Pentium
;; and doesn't hurt much on MMX. (Prefixed instructions are not very
-;; common, so the scheduler usualy has a non-prefixed insn to pair).
+;; common, so the scheduler usually has a non-prefixed insn to pair).
(define_attr "pent_pair" "uv,pu,pv,np"
(cond [(eq_attr "imm_disp" "true")
@@ -51,13 +51,13 @@
(match_operand 2 "const_int_operand" ""))
(const_string "pu")
(and (eq_attr "type" "rotate")
- (match_operand 2 "const_int_1_operand" ""))
+ (match_operand 2 "const1_operand" ""))
(const_string "pu")
(and (eq_attr "type" "ishift1")
(match_operand 1 "const_int_operand" ""))
(const_string "pu")
(and (eq_attr "type" "rotate1")
- (match_operand 1 "const_int_1_operand" ""))
+ (match_operand 1 "const1_operand" ""))
(const_string "pu")
(and (eq_attr "type" "call")
(match_operand 0 "constant_call_address_operand" ""))
@@ -71,7 +71,7 @@
(define_automaton "pentium,pentium_fpu")
;; Pentium do have U and V pipes. Instruction to both pipes
-;; are alwyas issued together, much like on VLIW.
+;; are always issued together, much like on VLIW.
;;
;; predecode
;; / \
@@ -194,7 +194,7 @@
(define_insn_reservation "pent_pop" 1
(and (eq_attr "cpu" "pentium")
- (eq_attr "type" "pop"))
+ (eq_attr "type" "pop,leave"))
"pentium-firstuv")
;; Call and branch instruction can execute in either pipe, but
@@ -210,7 +210,7 @@
"pentium-firstv")
;; Floating point instruction dispatch in U pipe, but continue
-;; in FP pipeline allowing other isntructions to be executed.
+;; in FP pipeline allowing other instructions to be executed.
(define_insn_reservation "pent_fp" 3
(and (eq_attr "cpu" "pentium")
(eq_attr "type" "fop,fistp"))
diff --git a/contrib/gcc/config/i386/pmmintrin.h b/contrib/gcc/config/i386/pmmintrin.h
index 5649c00d6730..3b18e2a11bd2 100644
--- a/contrib/gcc/config/i386/pmmintrin.h
+++ b/contrib/gcc/config/i386/pmmintrin.h
@@ -1,19 +1,19 @@
/* Copyright (C) 2003 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -30,7 +30,7 @@
#ifndef _PMMINTRIN_H_INCLUDED
#define _PMMINTRIN_H_INCLUDED
-#ifdef __PNI__
+#ifdef __SSE3__
#include <xmmintrin.h>
#include <emmintrin.h>
@@ -127,6 +127,6 @@ _mm_mwait (unsigned int __E, unsigned int __H)
#define _mm_mwait(E, H) __builtin_ia32_mwait ((E), (H))
#endif
-#endif /* __PNI__ */
+#endif /* __SSE3__ */
#endif /* _PMMINTRIN_H_INCLUDED */
diff --git a/contrib/gcc/config/i386/ppro.md b/contrib/gcc/config/i386/ppro.md
index 869068564691..911bf3bd92d1 100644
--- a/contrib/gcc/config/i386/ppro.md
+++ b/contrib/gcc/config/i386/ppro.md
@@ -1,20 +1,20 @@
;; Pentium Pro/PII Scheduling
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA. */
@@ -29,7 +29,7 @@
(define_attr "ppro_uops" "one,few,many"
(cond [(eq_attr "type" "other,multi,call,callv,fpspc,str")
(const_string "many")
- (eq_attr "type" "icmov,fcmov,str,cld")
+ (eq_attr "type" "icmov,fcmov,str,cld,leave")
(const_string "few")
(eq_attr "type" "imov")
(if_then_else (eq_attr "memory" "store,both")
@@ -118,7 +118,7 @@
(define_function_unit "ppro_p2" 1 0
(and (eq_attr "cpu" "pentiumpro")
- (ior (eq_attr "type" "pop")
+ (ior (eq_attr "type" "pop,leave")
(eq_attr "memory" "load,both")))
3 1)
diff --git a/contrib/gcc/config/i386/ptx4-i.h b/contrib/gcc/config/i386/ptx4-i.h
index a7d571067628..5fcd074f48b3 100644
--- a/contrib/gcc/config/i386/ptx4-i.h
+++ b/contrib/gcc/config/i386/ptx4-i.h
@@ -1,24 +1,24 @@
-/* Target definitions for GNU compiler for Intel 80386 running Dynix/ptx v4
+/* Target definitions for GCC for Intel 80386 running Dynix/ptx v4
Copyright (C) 1996, 2002 Free Software Foundation, Inc.
Modified from sysv4.h
Originally written by Ron Guilmette (rfg@netcom.com).
Modified by Tim Wright (timw@sequent.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -57,13 +57,13 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
do \
{ \
- register const unsigned char *_ascii_bytes = \
+ const unsigned char *_ascii_bytes = \
(const unsigned char *) (STR); \
- register const unsigned char *limit = _ascii_bytes + (LENGTH); \
- register unsigned bytes_in_chunk = 0; \
+ const unsigned char *limit = _ascii_bytes + (LENGTH); \
+ unsigned bytes_in_chunk = 0; \
for (; _ascii_bytes < limit; _ascii_bytes++) \
{ \
- register const unsigned char *p; \
+ const unsigned char *p; \
if (bytes_in_chunk >= 64) \
{ \
fputc ('\n', (FILE)); \
diff --git a/contrib/gcc/config/i386/rtemself.h b/contrib/gcc/config/i386/rtemself.h
index 096717816f2c..6f5299dc0508 100644
--- a/contrib/gcc/config/i386/rtemself.h
+++ b/contrib/gcc/config/i386/rtemself.h
@@ -2,20 +2,20 @@
Copyright (C) 1996, 1997, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by Joel Sherrill (joel@OARcorp.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,7 +25,6 @@ Boston, MA 02111-1307, USA. */
do \
{ \
builtin_define ("__rtems__"); \
- builtin_define ("__ELF__"); \
builtin_define ("__USE_INIT_FINI__"); \
builtin_assert ("system=rtems"); \
if (!TARGET_80387) \
diff --git a/contrib/gcc/config/i386/sco5.h b/contrib/gcc/config/i386/sco5.h
index 2a28e5459f38..bb872d5ec156 100644
--- a/contrib/gcc/config/i386/sco5.h
+++ b/contrib/gcc/config/i386/sco5.h
@@ -3,29 +3,26 @@
Free Software Foundation, Inc.
Contributed by Kean Johnston (jkj@sco.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (i386, SCO OpenServer 5 Syntax)");
-/* The native link editor does not support linkonce stuff */
-#define SUPPORTS_ONE_ONLY 0
-
#undef ASM_QUAD
#undef GLOBAL_ASM_OP
@@ -63,7 +60,6 @@ Boston, MA 02111-1307, USA. */
#define DBX_REGISTER_NUMBER(n) svr4_dbx_register_map[n]
#define DWARF2_DEBUGGING_INFO 1
-#define DWARF_DEBUGGING_INFO 1
#define DBX_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
@@ -149,7 +145,7 @@ Boston, MA 02111-1307, USA. */
assume that /usr/gnu is the prefix for the GNU tools, because thats
where the SCO provided ones go. This is especially important for
include and library search path ordering. We want to look in /usr/gnu
- first, becuase frequently people are linking against -lintl, and they
+ first because frequently people are linking against -lintl, and they
MEAN to link with gettext. What they get is the SCO intl library. Its
a REAL pity that GNU gettext chose that name; perhaps in a future
version they can be persuaded to change it to -lgnuintl and have a
@@ -238,7 +234,6 @@ Boston, MA 02111-1307, USA. */
#undef CPP_SPEC
#define CPP_SPEC "\
-isystem /usr/gnu/include \
- %{pthread:-D_REENTRANT} \
%{!Xods30:-D_STRICT_NAMES} \
%{!ansi:%{!posix:%{!Xods30:-D_SCO_XPG_VERS=4}}} \
%{ansi:-isystem include/ansi%s -isystem /usr/include/ansi} \
@@ -282,7 +277,7 @@ Boston, MA 02111-1307, USA. */
%{G:%{!shared:pic/libgcc.a%s}} \
%{shared:%{G:pic/libgcc.a%s}} \
%{p:%{!pp:-lelfprof -lelf}} %{pp:%{!p:-lelfprof -lelf}} \
- %{!shared:%{!symbolic:%{!G:-lcrypt -lgen -lc %{pthread:-lpthread}}}}"
+ %{!shared:%{!symbolic:%{!G:-lcrypt -lgen -lc}}}"
#undef LIBGCC_SPEC
#define LIBGCC_SPEC \
diff --git a/contrib/gcc/config/i386/sol2.h b/contrib/gcc/config/i386/sol2.h
index 9089a1dce6c4..78b2985cb7a5 100644
--- a/contrib/gcc/config/i386/sol2.h
+++ b/contrib/gcc/config/i386/sol2.h
@@ -1,22 +1,22 @@
-/* Target definitions for GNU compiler for Intel 80386 running Solaris 2
+/* Target definitions for GCC for Intel 80386 running Solaris 2
Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Fred Fish (fnf@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -64,3 +64,18 @@ Boston, MA 02111-1307, USA. */
/* The Solaris assembler does not support .quad. Do not use it. */
#undef ASM_QUAD
+
+/* The Solaris assembler wants a .local for non-exported aliases. */
+#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET) \
+ do { \
+ const char *declname = \
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \
+ ASM_OUTPUT_DEF ((FILE), declname, \
+ IDENTIFIER_POINTER (TARGET)); \
+ if (! TREE_PUBLIC (DECL)) \
+ { \
+ fprintf ((FILE), "%s", LOCAL_ASM_OP); \
+ assemble_name ((FILE), declname); \
+ fprintf ((FILE), "\n"); \
+ } \
+ } while (0)
diff --git a/contrib/gcc/config/i386/svr3dbx.h b/contrib/gcc/config/i386/svr3dbx.h
index 4be7a70d06b4..d06d9117d413 100644
--- a/contrib/gcc/config/i386/svr3dbx.h
+++ b/contrib/gcc/config/i386/svr3dbx.h
@@ -1,20 +1,20 @@
-/* Definitions for Intel 385 running system V, using dbx-in-coff encapsulation.
+/* Definitions for Intel 386 running system V, using dbx-in-coff encapsulation.
Copyright (C) 1992, 1995, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/svr3gas.h b/contrib/gcc/config/i386/svr3gas.h
index b9d94b788cb9..81428aeb9e4e 100644
--- a/contrib/gcc/config/i386/svr3gas.h
+++ b/contrib/gcc/config/i386/svr3gas.h
@@ -1,20 +1,20 @@
/* Definitions for Intel 386 running system V, using gas.
Copyright (C) 1992, 1996, 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -52,13 +52,13 @@ Boston, MA 02111-1307, USA. */
data_section (); \
ASM_OUTPUT_ALIGN ((FILE), align == -1 ? 2 : align); \
ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- fprintf ((FILE), "\t.set .,.+%u\n", (ROUNDED)); \
+ fprintf ((FILE), "\t.set .,.+%u\n", (int)(ROUNDED)); \
} \
else \
{ \
fputs (".lcomm ", (FILE)); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u\n", (ROUNDED)); \
+ fprintf ((FILE), ",%u\n", (int)(ROUNDED)); \
} \
} while (0)
diff --git a/contrib/gcc/config/i386/sysv3.h b/contrib/gcc/config/i386/sysv3.h
index 93f944501243..b2643b14eb37 100644
--- a/contrib/gcc/config/i386/sysv3.h
+++ b/contrib/gcc/config/i386/sysv3.h
@@ -1,20 +1,20 @@
/* Definitions for Intel 386 running system V.
Copyright (C) 1988, 1996, 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -46,11 +46,6 @@ Boston, MA 02111-1307, USA. */
#define PCC_BITFIELD_TYPE_MATTERS 1
-/* Don't write a `.optim' pseudo; this assembler doesn't handle them. */
-
-#undef ASM_FILE_START_1
-#define ASM_FILE_START_1(FILE)
-
/* We want to be able to get DBX debugging information via -gstabs. */
#define DBX_DEBUGGING_INFO 1
@@ -89,7 +84,7 @@ Boston, MA 02111-1307, USA. */
bss_section (); \
ASM_OUTPUT_ALIGN ((FILE), align == -1 ? 2 : align); \
ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- fprintf ((FILE), "\t.set .,.+%u\n", (ROUNDED)); \
+ fprintf ((FILE), "\t.set .,.+%u\n", (int)(ROUNDED));\
} while (0)
/* Define a few machine-specific details of the implementation of
diff --git a/contrib/gcc/config/i386/sysv4-cpp.h b/contrib/gcc/config/i386/sysv4-cpp.h
index 5b46bf1d945b..6ec751af0f76 100644
--- a/contrib/gcc/config/i386/sysv4-cpp.h
+++ b/contrib/gcc/config/i386/sysv4-cpp.h
@@ -1,22 +1,22 @@
-/* Target definitions for GNU compiler for Intel 80386 running System V.4
+/* Target definitions for GCC for Intel 80386 running System V.4
Copyright (C) 1991, 2001, 2002 Free Software Foundation, Inc.
Written by Ron Guilmette (rfg@netcom.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/sysv4.h b/contrib/gcc/config/i386/sysv4.h
index 6b3335e89231..244700637ece 100644
--- a/contrib/gcc/config/i386/sysv4.h
+++ b/contrib/gcc/config/i386/sysv4.h
@@ -1,22 +1,22 @@
-/* Target definitions for GNU compiler for Intel 80386 running System V.4
+/* Target definitions for GCC for Intel 80386 running System V.4
Copyright (C) 1991, 2001, 2002 Free Software Foundation, Inc.
Written by Ron Guilmette (rfg@netcom.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -34,12 +34,9 @@ Boston, MA 02111-1307, USA. */
/* Output at beginning of assembler file. */
/* The .file command should always begin the output. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { \
- output_file_directive (FILE, main_input_filename); \
- fprintf (FILE, "\t.version\t\"01.01\"\n"); \
- } while (0)
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
+#undef X86_FILE_START_VERSION_DIRECTIVE
+#define X86_FILE_START_VERSION_DIRECTIVE true
#undef DBX_REGISTER_NUMBER
#define DBX_REGISTER_NUMBER(n) svr4_dbx_register_map[n]
@@ -55,13 +52,13 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \
do \
{ \
- register const unsigned char *_ascii_bytes = \
+ const unsigned char *_ascii_bytes = \
(const unsigned char *) (STR); \
- register const unsigned char *limit = _ascii_bytes + (LENGTH); \
- register unsigned bytes_in_chunk = 0; \
+ const unsigned char *limit = _ascii_bytes + (LENGTH); \
+ unsigned bytes_in_chunk = 0; \
for (; _ascii_bytes < limit; _ascii_bytes++) \
{ \
- register const unsigned char *p; \
+ const unsigned char *p; \
if (bytes_in_chunk >= 64) \
{ \
fputc ('\n', (FILE)); \
diff --git a/contrib/gcc/config/i386/sysv5.h b/contrib/gcc/config/i386/sysv5.h
index 9b759f407be7..c4edd7123a3b 100644
--- a/contrib/gcc/config/i386/sysv5.h
+++ b/contrib/gcc/config/i386/sysv5.h
@@ -2,20 +2,20 @@
Copyright (C) 1999 Free Software Foundation, Inc.
Contributed by Robert Lipe (robertlipe@usa.net)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/t-beos b/contrib/gcc/config/i386/t-beos
index e545abd7d070..b5c8ec208716 100644
--- a/contrib/gcc/config/i386/t-beos
+++ b/contrib/gcc/config/i386/t-beos
@@ -2,6 +2,3 @@
# we are most likely to want to apply any fixes to.
SYSTEM_HEADER_DIR = /boot/develop/headers/posix
CROSS_SYSTEM_HEADER_DIR = $(tooldir)/sys-include/posix
-
-# Don't run fixproto
-STMP_FIXPROTO =
diff --git a/contrib/gcc/config/i386/t-cygming b/contrib/gcc/config/i386/t-cygming
new file mode 100644
index 000000000000..aa6ff61ca03e
--- /dev/null
+++ b/contrib/gcc/config/i386/t-cygming
@@ -0,0 +1,19 @@
+LIB1ASMSRC = i386/cygwin.asm
+LIB1ASMFUNCS = _chkstk
+
+# cygwin and mingw always have a limits.h, but, depending upon how we are
+# doing the build, it may not be installed yet.
+LIMITS_H_TEST = true
+
+# If we are building next to winsup, this will let us find the real
+# limits.h when building libgcc2. Otherwise, winsup must be installed
+# first.
+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) \
+ $(srcdir)/config/i386/winnt.c
+
+STMP_FIXINC=stmp-fixinc
diff --git a/contrib/gcc/config/i386/t-cygwin b/contrib/gcc/config/i386/t-cygwin
index 6fcb8340ddcb..c6e77731b1ad 100644
--- a/contrib/gcc/config/i386/t-cygwin
+++ b/contrib/gcc/config/i386/t-cygwin
@@ -1,21 +1,16 @@
-LIB1ASMSRC = i386/cygwin.asm
-LIB1ASMFUNCS = _chkstk
-
-# cygwin always has a limits.h, but, depending upon how we are doing
-# the build, it may not be installed yet.
-LIMITS_H_TEST = true
-
-T_CPPFLAGS=-DCYGWIN_CROSS_DIR=\"$(build_tooldir)\"
-
# If we are building next to winsup, this will let us find the real
# limits.h when building libgcc2. Otherwise, winsup must be installed
# first.
-LIBGCC2_INCLUDES = -I$(srcdir)/../winsup/include \
- -I$(srcdir)/../winsup/cygwin/include \
- -I$(srcdir)/../winsup/w32api/include
+LIBGCC2_INCLUDES += -I$(srcdir)/../winsup/include \
+ -I$(srcdir)/../winsup/cygwin/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) \
+ $(srcdir)/config/i386/cygwin1.c
-winnt.o: $(srcdir)/config/i386/winnt.c $(RTL_H) $(TREE_H) $(CONFIG_H) $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/winnt.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) \
+ $(srcdir)/config/i386/cygwin2.c
-# Don't run fixproto
-STMP_FIXPROTO =
diff --git a/contrib/gcc/config/i386/t-interix b/contrib/gcc/config/i386/t-interix
index 710de8b08811..d5fff6167b77 100644
--- a/contrib/gcc/config/i386/t-interix
+++ b/contrib/gcc/config/i386/t-interix
@@ -1,6 +1,7 @@
LIB1ASMSRC = i386/cygwin.asm
LIB1ASMFUNCS = _chkstk
-winnt.o: $(srcdir)/config/i386/winnt.c $(TM_P_H)
+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
-
diff --git a/contrib/gcc/config/i386/t-nto b/contrib/gcc/config/i386/t-nto
new file mode 100644
index 000000000000..b80ff802927a
--- /dev/null
+++ b/contrib/gcc/config/i386/t-nto
@@ -0,0 +1,4 @@
+CRTSTUFF_T_CFLAGS = -fno-omit-frame-pointer -fPIC
+TARGET_LIBGCC2_CFLAGS = -fPIC -fexceptions
+
+EXTRA_PARTS = crtbegin.o
diff --git a/contrib/gcc/config/i386/t-sco5 b/contrib/gcc/config/i386/t-sco5
index f92a62430cc8..c6155930e547 100644
--- a/contrib/gcc/config/i386/t-sco5
+++ b/contrib/gcc/config/i386/t-sco5
@@ -5,7 +5,6 @@ CRTSTUFF_T_CFLAGS = -fPIC -fno-omit-frame-pointer
MULTILIB_OPTIONS = fPIC
MULTILIB_DIRNAMES = pic
-MUTLILIB_EXCEPTIONS =
MULTILIB_MATCHES = fPIC=fpic
MULTILIB_EXTRA_OPTS =
diff --git a/contrib/gcc/config/i386/t-vxworks b/contrib/gcc/config/i386/t-vxworks
new file mode 100644
index 000000000000..609399502e79
--- /dev/null
+++ b/contrib/gcc/config/i386/t-vxworks
@@ -0,0 +1,8 @@
+# Multilibs for VxWorks.
+
+#GCC does not have an arch=pentium3 setting, so we cannot build PENTIUM3gnu
+MULTILIB_OPTIONS = \
+ march=i486/march=pentium/march=pentiumpro/march=pentium4
+MULTILIB_DIRNAMES = \
+ I80486 PENTIUMgnu PENTIUM2gnu PENTIUM4gnu
+
diff --git a/contrib/gcc/config/i386/unix.h b/contrib/gcc/config/i386/unix.h
index e69f26d7490c..102afe0da30c 100644
--- a/contrib/gcc/config/i386/unix.h
+++ b/contrib/gcc/config/i386/unix.h
@@ -1,20 +1,20 @@
/* Definitions for Unix assembler syntax for the Intel 80386.
Copyright (C) 1988, 1994, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -22,8 +22,6 @@ Boston, MA 02111-1307, USA. */
that are the same for all the i386 Unix systems
(though they may differ in non-Unix systems). */
-#define DEFAULT_ASSEMBLER_DIALECT 0
-
/* Define macro used to output shift-double opcodes when the shift
count is in %cl. Some assemblers require %cl as an argument;
some don't. This macro controls what to do: by default, don't
diff --git a/contrib/gcc/config/i386/uwin.h b/contrib/gcc/config/i386/uwin.h
index 121051064e4f..d2553c92f5f2 100644
--- a/contrib/gcc/config/i386/uwin.h
+++ b/contrib/gcc/config/i386/uwin.h
@@ -2,23 +2,23 @@
hosting on U/WIN (Windows32), using GNU tools and the Windows32 API
Library, as distinct from winnt.h, which is used to build GCC for use
with a windows style library and tool set and uses the Microsoft tools.
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
Contributed by Mumit Khan <khan@xraylith.wisc.edu>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -92,7 +92,3 @@ Boston, MA 02111-1307, USA. */
#undef ASM_OUTPUT_EXTERNAL
#undef ASM_OUTPUT_EXTERNAL_LIBCALL
-/* Override Cygwin's definition. This is necessary now due to the way
- Cygwin profiling code is written. Once "fixed", we can remove this. */
-#undef SUBTARGET_PROLOGUE
-
diff --git a/contrib/gcc/config/i386/vsta.h b/contrib/gcc/config/i386/vsta.h
index 93883295eb0b..f9c4710c6ffa 100644
--- a/contrib/gcc/config/i386/vsta.h
+++ b/contrib/gcc/config/i386/vsta.h
@@ -2,20 +2,20 @@
Copyright (C) 1994, 2002 Free Software Foundation, Inc.
Contributed by Rob Savoye (rob@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/i386/vxworks.h b/contrib/gcc/config/i386/vxworks.h
new file mode 100644
index 000000000000..5ded098b9d31
--- /dev/null
+++ b/contrib/gcc/config/i386/vxworks.h
@@ -0,0 +1,74 @@
+/* Definitions of target machine for GCC. VxWorks i586 version.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#define HANDLE_SYSV_PRAGMA 1
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (80586, VxWorks syntax)");
+
+/* Prefix for internally generated assembler labels. If we aren't using
+ underscores, we are using prefix `.'s to identify labels that should
+ be ignored, as in `i386/gas.h' --karl@cs.umb.edu */
+
+#define LPREFIX "L"
+
+/* Assembler pseudos to introduce constants of various size. */
+
+#define ASM_SHORT "\t.word\t"
+#define ASM_LONG "\t.long\t"
+#define ASM_QUAD "\t.quad\t" /* Should not be used for 32bit compilation. */
+
+
+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
+ if ((LOG)!=0) fprintf ((FILE), "\t.balign %d\n", 1<<(LOG))
+
+#undef ASM_SPEC
+#define ASM_SPEC "%{v:-V} %{Qy:} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
+
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__vxworks"); \
+ builtin_assert ("system=unix"); \
+ \
+ if (TARGET_386) \
+ builtin_define ("CPU=I80386"); \
+ else if (TARGET_486) \
+ builtin_define ("CPU=I80486"); \
+ else if (TARGET_PENTIUM) \
+ { \
+ builtin_define ("CPU=PENTIUM"); \
+ builtin_define ("CPU_VARIANT=PENTIUM"); \
+ } \
+ else if (TARGET_PENTIUMPRO) \
+ { \
+ builtin_define ("CPU=PENTIUM2"); \
+ builtin_define ("CPU_VARIANT=PENTIUMPRO"); \
+ } \
+ else if (TARGET_PENTIUM4) \
+ { \
+ builtin_define ("CPU=PENTIUM4"); \
+ builtin_define ("CPU_VARIANT=PENTIUM4"); \
+ } \
+ } \
+ while (0)
+
+
diff --git a/contrib/gcc/config/i386/winnt.c b/contrib/gcc/config/i386/winnt.c
index 01493a2d3cf2..f8621b4f8f05 100644
--- a/contrib/gcc/config/i386/winnt.c
+++ b/contrib/gcc/config/i386/winnt.c
@@ -1,6 +1,6 @@
/* Subroutines for insn-output.c for Windows NT.
Contributed by Douglas Rupp (drupp@cs.washington.edu)
- Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -44,22 +46,28 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
multiple times.
*/
-static tree associated_type PARAMS ((tree));
-const char * gen_stdcall_suffix PARAMS ((tree));
-int i386_pe_dllexport_p PARAMS ((tree));
-int i386_pe_dllimport_p PARAMS ((tree));
-void i386_pe_mark_dllexport PARAMS ((tree));
-void i386_pe_mark_dllimport PARAMS ((tree));
+static tree associated_type (tree);
+static const char * gen_stdcall_suffix (tree);
+static const char * gen_fastcall_suffix (tree);
+static int i386_pe_dllexport_p (tree);
+static int i386_pe_dllimport_p (tree);
+static void i386_pe_mark_dllexport (tree);
+static void i386_pe_mark_dllimport (tree);
+
+/* This is we how mark internal identifiers with dllimport or dllexport
+ attributes. */
+#ifndef DLL_IMPORT_PREFIX
+#define DLL_IMPORT_PREFIX "#i."
+#endif
+#ifndef DLL_EXPORT_PREFIX
+#define DLL_EXPORT_PREFIX "#e."
+#endif
/* Handle a "dllimport" or "dllexport" attribute;
arguments as in struct attribute_spec.handler. */
tree
-ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
- tree * pnode;
- tree name;
- tree args;
- int flags;
- bool *no_add_attrs;
+ix86_handle_dll_attribute (tree * pnode, tree name, tree args, int flags,
+ bool *no_add_attrs)
{
tree node = *pnode;
@@ -93,7 +101,7 @@ ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
if (TREE_CODE (node) == FUNCTION_DECL && DECL_INITIAL (node)
&& !DECL_INLINE (node))
{
- error_with_decl (node, "function `%s' definition is marked dllimport.");
+ error ("%Jfunction `%D' definition is marked dllimport.", node, node);
*no_add_attrs = true;
}
@@ -101,27 +109,28 @@ ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
{
if (DECL_INITIAL (node))
{
- error_with_decl (node,"variable `%s' definition is marked dllimport.");
+ error ("%Jvariable `%D' definition is marked dllimport.",
+ node, node);
*no_add_attrs = true;
}
/* `extern' needn't be specified with dllimport.
Specify `extern' now and hope for the best. Sigh. */
- DECL_EXTERNAL (node) = 1;
+ DECL_EXTERNAL (node) = 1;
/* Also, implicitly give dllimport'd variables declared within
a function global scope, unless declared static. */
if (current_function_decl != NULL_TREE && !TREE_STATIC (node))
- TREE_PUBLIC (node) = 1;
+ TREE_PUBLIC (node) = 1;
}
}
- /* Report error if symbol is not accessible at global scope. */
+ /* Report error if symbol is not accessible at global scope. */
if (!TREE_PUBLIC (node)
&& (TREE_CODE (node) == VAR_DECL
- || TREE_CODE (node) == FUNCTION_DECL))
+ || TREE_CODE (node) == FUNCTION_DECL))
{
- error_with_decl (node, "external linkage required for symbol '%s' because of '%s' attribute.",
- IDENTIFIER_POINTER (name));
+ error ("%Jexternal linkage required for symbol '%D' because of "
+ "'%s' attribute.", node, node, IDENTIFIER_POINTER (name));
*no_add_attrs = true;
}
@@ -131,12 +140,9 @@ ix86_handle_dll_attribute (pnode, name, args, flags, no_add_attrs)
/* Handle a "shared" attribute;
arguments as in struct attribute_spec.handler. */
tree
-ix86_handle_shared_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+ix86_handle_shared_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) != VAR_DECL)
{
@@ -152,8 +158,7 @@ ix86_handle_shared_attribute (node, name, args, flags, no_add_attrs)
imported or exported. */
static tree
-associated_type (decl)
- tree decl;
+associated_type (tree decl)
{
tree t = NULL_TREE;
@@ -161,10 +166,13 @@ associated_type (decl)
to the containing class. So we look at the 'this' arg. */
if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
{
- /* Artificial methods are not affected by the import/export status of
- their class unless they are virtual. */
- if (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl))
- t = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))));
+ /* Artificial methods are not affected by the import/export status
+ of their class unless they are COMDAT. Implicit copy ctor's and
+ dtor's are not affected by class status but virtual and
+ non-virtual thunks are. */
+ if (!DECL_ARTIFICIAL (decl) || DECL_COMDAT (decl))
+ t = TYPE_MAIN_VARIANT
+ (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))));
}
else if (DECL_CONTEXT (decl)
&& TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
@@ -175,9 +183,8 @@ associated_type (decl)
/* Return nonzero if DECL is a dllexport'd object. */
-int
-i386_pe_dllexport_p (decl)
- tree decl;
+static int
+i386_pe_dllexport_p (tree decl)
{
tree exp;
@@ -202,9 +209,8 @@ i386_pe_dllexport_p (decl)
/* Return nonzero if DECL is a dllimport'd object. */
-int
-i386_pe_dllimport_p (decl)
- tree decl;
+static int
+i386_pe_dllimport_p (tree decl)
{
tree imp;
int context_imp = 0;
@@ -239,17 +245,19 @@ i386_pe_dllimport_p (decl)
{
/* Don't warn about artificial methods. */
if (!DECL_ARTIFICIAL (decl))
- warning_with_decl (decl,"function '%s' is defined after prior declaration as dllimport: attribute ignored.");
+ warning ("%Jfunction '%D' is defined after prior declaration "
+ "as dllimport: attribute ignored", decl, decl);
return 0;
}
/* We ignore the dllimport attribute for inline member functions.
- This differs from MSVC behaviour which treats it like GNUC
- 'extern inline' extension. */
+ This differs from MSVC behavior which treats it like GNUC
+ 'extern inline' extension. */
else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
{
if (extra_warnings)
- warning_with_decl (decl, "inline function '%s' is declared as dllimport: attribute ignored.");
+ warning ("%Jinline function '%D' is declared as dllimport: "
+ "attribute ignored.", decl, decl);
return 0;
}
@@ -260,16 +268,19 @@ i386_pe_dllimport_p (decl)
&& !DECL_EXTERNAL (decl) && context_imp)
{
if (!DECL_VIRTUAL_P (decl))
- error_with_decl (decl, "definition of static data member '%s' of dllimport'd class.");
- return 0;
+ error ("%Jdefinition of static data member '%D' of "
+ "dllimport'd class.", decl, decl);
+ return 0;
}
/* Since we can't treat a pointer to a dllimport'd symbol as a
constant address, we turn off the attribute on C++ virtual
- methods to allow creation of vtables using thunks. */
+ methods to allow creation of vtables using thunks. Don't mark
+ artificial methods either (in associated_type, only COMDAT
+ artificial method get import status from class context). */
else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
- && (DECL_VIRTUAL_P (decl)))
- return 0;
+ && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl)))
+ return 0;
return 1;
}
@@ -280,29 +291,26 @@ i386_pe_dllimport_p (decl)
/* Return nonzero if SYMBOL is marked as being dllexport'd. */
int
-i386_pe_dllexport_name_p (symbol)
- const char *symbol;
+i386_pe_dllexport_name_p (const char *symbol)
{
- return symbol[0] == DLL_IMPORT_EXPORT_PREFIX
- && symbol[1] == 'e' && symbol[2] == '.';
+ return (strncmp (DLL_EXPORT_PREFIX, symbol,
+ strlen (DLL_EXPORT_PREFIX)) == 0);
}
/* Return nonzero if SYMBOL is marked as being dllimport'd. */
int
-i386_pe_dllimport_name_p (symbol)
- const char *symbol;
+i386_pe_dllimport_name_p (const char *symbol)
{
- return symbol[0] == DLL_IMPORT_EXPORT_PREFIX
- && symbol[1] == 'i' && symbol[2] == '.';
+ return (strncmp (DLL_IMPORT_PREFIX, symbol,
+ strlen (DLL_IMPORT_PREFIX)) == 0);
}
/* Mark a DECL as being dllexport'd.
Note that we override the previous setting (eg: dllimport). */
-void
-i386_pe_mark_dllexport (decl)
- tree decl;
+static void
+i386_pe_mark_dllexport (tree decl)
{
const char *oldname;
char *newname;
@@ -319,16 +327,17 @@ i386_pe_mark_dllexport (decl)
abort ();
if (i386_pe_dllimport_name_p (oldname))
{
- warning_with_decl (decl,"inconsistent dll linkage for '%s': dllexport assumed.");
+ warning ("%Jinconsistent dll linkage for '%D', dllexport assumed.",
+ decl, decl);
/* Remove DLL_IMPORT_PREFIX. */
- oldname += 9;
+ oldname += strlen (DLL_IMPORT_PREFIX);
DECL_NON_ADDR_CONST_P (decl) = 0;
}
else if (i386_pe_dllexport_name_p (oldname))
- return; /* already done */
+ return; /* already done */
- newname = alloca (strlen (oldname) + 4);
- sprintf (newname, "%ce.%s", DLL_IMPORT_EXPORT_PREFIX, oldname);
+ newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
+ sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
/* We pass newname through get_identifier to ensure it has a unique
address. RTL processing can sometimes peek inside the symbol ref
@@ -342,9 +351,8 @@ i386_pe_mark_dllexport (decl)
/* Mark a DECL as being dllimport'd. */
-void
-i386_pe_mark_dllimport (decl)
- tree decl;
+static void
+i386_pe_mark_dllimport (tree decl)
{
const char *oldname;
char *newname;
@@ -367,17 +375,18 @@ i386_pe_mark_dllimport (decl)
}
else if (i386_pe_dllimport_name_p (oldname))
{
- /* Already done, but do a sanity check to prevent assembler errors. */
+ /* Already done, but do a sanity check to prevent assembler errors. */
if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
{
- error_with_decl (decl, "failure in redeclaration of '%s': dllimport'd symbol lacks external linkage.");
+ error ("%Jfailure in redeclaration of '%D': dllimport'd "
+ "symbol lacks external linkage.", decl, decl);
abort();
}
- return;
+ return;
}
- newname = alloca (strlen (oldname) + 11);
- sprintf (newname, "%ci._imp__%s", DLL_IMPORT_EXPORT_PREFIX, oldname);
+ newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
+ sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
/* We pass newname through get_identifier to ensure it has a unique
address. RTL processing can sometimes peek inside the symbol ref
@@ -394,13 +403,51 @@ i386_pe_mark_dllimport (decl)
DECL_NON_ADDR_CONST_P (decl) = 1;
}
-/* Return string which is the former assembler name modified with a
- suffix consisting of an atsign (@) followed by the number of bytes of
+/* Return string which is the former assembler name modified with a
+ prefix consisting of FASTCALL_PREFIX and a suffix consisting of an
+ atsign (@) followed by the number of bytes of arguments. */
+
+static const char *
+gen_fastcall_suffix (tree decl)
+{
+ int total = 0;
+ const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ char *newsym;
+
+ if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
+ if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
+ == void_type_node)
+ {
+ tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
+
+ /* Quit if we hit an incomplete type. Error is reported
+ by convert_arguments in c-typeck.c or cp/typeck.c. */
+ while (TREE_VALUE (formal_type) != void_type_node
+ && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
+ {
+ int parm_size
+ = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
+ /* Must round up to include padding. This is done the same
+ way as in store_one_arg. */
+ parm_size = ((parm_size + PARM_BOUNDARY - 1)
+ / PARM_BOUNDARY * PARM_BOUNDARY);
+ total += parm_size;
+ formal_type = TREE_CHAIN (formal_type);
+ }
+ }
+
+ /* Assume max of 8 base 10 digits in the suffix. */
+ newsym = xmalloc (1 + strlen (asmname) + 1 + 8 + 1);
+ sprintf (newsym, "%c%s@%d", FASTCALL_PREFIX, asmname, total/BITS_PER_UNIT);
+ return IDENTIFIER_POINTER (get_identifier (newsym));
+}
+
+/* Return string which is the former assembler name modified with a
+ suffix consisting of an atsign (@) followed by the number of bytes of
arguments */
-const char *
-gen_stdcall_suffix (decl)
- tree decl;
+static const char *
+gen_stdcall_suffix (tree decl)
{
int total = 0;
/* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
@@ -409,12 +456,15 @@ gen_stdcall_suffix (decl)
char *newsym;
if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
- if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
+ if (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (decl))))
== void_type_node)
{
tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));
- while (TREE_VALUE (formal_type) != void_type_node)
+ /* Quit if we hit an incomplete type. Error is reported
+ by convert_arguments in c-typeck.c or cp/typeck.c. */
+ while (TREE_VALUE (formal_type) != void_type_node
+ && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))
{
int parm_size
= TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));
@@ -427,30 +477,28 @@ gen_stdcall_suffix (decl)
}
}
- newsym = xmalloc (strlen (asmname) + 10);
+ /* Assume max of 8 base 10 digits in the suffix. */
+ newsym = xmalloc (strlen (asmname) + 1 + 8 + 1);
sprintf (newsym, "%s@%d", asmname, total/BITS_PER_UNIT);
return IDENTIFIER_POINTER (get_identifier (newsym));
}
void
-i386_pe_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
+i386_pe_encode_section_info (tree decl, rtx rtl, int first)
{
- /* This bit is copied from i386.h. */
- if (optimize > 0 && TREE_CONSTANT (decl)
- && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
- {
- rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd'
- ? TREE_CST_RTL (decl) : DECL_RTL (decl));
- SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
- }
+ default_encode_section_info (decl, rtl, first);
if (TREE_CODE (decl) == FUNCTION_DECL)
- if (lookup_attribute ("stdcall",
- TYPE_ATTRIBUTES (TREE_TYPE (decl))))
- XEXP (DECL_RTL (decl), 0) =
- gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));
+ {
+ if (lookup_attribute ("stdcall",
+ TYPE_ATTRIBUTES (TREE_TYPE (decl))))
+ XEXP (DECL_RTL (decl), 0) =
+ gen_rtx (SYMBOL_REF, Pmode, gen_stdcall_suffix (decl));
+ else if (lookup_attribute ("fastcall",
+ TYPE_ATTRIBUTES (TREE_TYPE (decl))))
+ XEXP (DECL_RTL (decl), 0) =
+ gen_rtx (SYMBOL_REF, Pmode, gen_fastcall_suffix (decl));
+ }
/* Mark the decl so we can tell from the rtl whether the object is
dllexport'd or dllimport'd. This also handles dllexport/dllimport
@@ -462,8 +510,8 @@ i386_pe_encode_section_info (decl, first)
i386_pe_mark_dllimport (decl);
/* It might be that DECL has already been marked as dllimport, but a
subsequent definition nullified that. The attribute is gone but
- DECL_RTL still has (DLL_IMPORT_EXPORT_PREFIX)i._imp__foo. We need
- to remove that. Ditto for the DECL_NON_ADDR_CONST_P flag. */
+ DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
+ that. Ditto for the DECL_NON_ADDR_CONST_P flag. */
else if ((TREE_CODE (decl) == FUNCTION_DECL
|| TREE_CODE (decl) == VAR_DECL)
&& DECL_RTL (decl) != NULL_RTX
@@ -473,12 +521,17 @@ i386_pe_encode_section_info (decl, first)
&& i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
{
const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
- tree idp = get_identifier (oldname + 9);
+
+ /* Remove DLL_IMPORT_PREFIX. */
+ tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
rtx newrtl = gen_rtx (SYMBOL_REF, Pmode, IDENTIFIER_POINTER (idp));
- warning_with_decl (decl, "'%s' %s after being referenced with dllimport linkage.",
- (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
- ? "defined locally" : "redeclared without dllimport attribute");
+ if (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
+ warning ("%J'%D' defined locally after being "
+ "referenced with dllimport linkage", decl, decl);
+ else
+ warning ("%J'%D' redeclared without dllimport attribute "
+ "after being referenced with dllimport linkage", decl, decl);
XEXP (DECL_RTL (decl), 0) = newrtl;
@@ -489,14 +542,18 @@ i386_pe_encode_section_info (decl, first)
}
}
-/* Strip only the leading encoding, leaving the stdcall suffix. */
+/* Strip only the leading encoding, leaving the stdcall suffix and fastcall
+ prefix if it exists. */
const char *
-i386_pe_strip_name_encoding (str)
- const char *str;
+i386_pe_strip_name_encoding (const char *str)
{
- if (*str == DLL_IMPORT_EXPORT_PREFIX)
- str += 3;
+ if (strncmp (str, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
+ == 0)
+ str += strlen (DLL_IMPORT_PREFIX);
+ else if (strncmp (str, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX))
+ == 0)
+ str += strlen (DLL_EXPORT_PREFIX);
if (*str == '*')
str += 1;
return str;
@@ -505,12 +562,11 @@ i386_pe_strip_name_encoding (str)
/* Also strip the stdcall suffix. */
const char *
-i386_pe_strip_name_encoding_full (str)
- const char *str;
+i386_pe_strip_name_encoding_full (const char *str)
{
const char *p;
const char *name = i386_pe_strip_name_encoding (str);
-
+
p = strchr (name, '@');
if (p)
return ggc_alloc_string (name, p - name);
@@ -518,10 +574,48 @@ i386_pe_strip_name_encoding_full (str)
return name;
}
+/* Output a reference to a label. Fastcall symbols are prefixed with @,
+ whereas symbols for functions using other calling conventions don't
+ have a prefix (unless they are marked dllimport or dllexport). */
+
+void i386_pe_output_labelref (FILE *stream, const char *name)
+{
+ if (strncmp (name, DLL_IMPORT_PREFIX, strlen (DLL_IMPORT_PREFIX))
+ == 0)
+ /* A dll import */
+ {
+ if (name[strlen (DLL_IMPORT_PREFIX)] == FASTCALL_PREFIX)
+ /* A dllimport fastcall symbol. */
+ {
+ fprintf (stream, "__imp_%s",
+ i386_pe_strip_name_encoding (name));
+ }
+ else
+ /* A dllimport non-fastcall symbol. */
+ {
+ fprintf (stream, "__imp__%s",
+ i386_pe_strip_name_encoding (name));
+ }
+ }
+ else if ((name[0] == FASTCALL_PREFIX)
+ || (strncmp (name, DLL_EXPORT_PREFIX, strlen (DLL_EXPORT_PREFIX)
+ == 0
+ && name[strlen (DLL_EXPORT_PREFIX)] == FASTCALL_PREFIX)))
+ /* A fastcall symbol. */
+ {
+ fprintf (stream, "%s",
+ i386_pe_strip_name_encoding (name));
+ }
+ else
+ /* Everything else. */
+ {
+ fprintf (stream, "%s%s", USER_LABEL_PREFIX,
+ i386_pe_strip_name_encoding (name));
+ }
+}
+
void
-i386_pe_unique_section (decl, reloc)
- tree decl;
- int reloc;
+i386_pe_unique_section (tree decl, int reloc)
{
int len;
const char *name, *prefix;
@@ -533,7 +627,7 @@ i386_pe_unique_section (decl, reloc)
/* The object is put in, for example, section .text$foo.
The linker will then ultimately place them in .text
(everything from the $ on is stripped). Don't put
- read-only data in .rdata section to avoid a PE linker
+ read-only data in .rdata section to avoid a PE linker
bug when .rdata$* grouped sections are used in code
without a .rdata section. */
if (TREE_CODE (decl) == FUNCTION_DECL)
@@ -559,7 +653,7 @@ i386_pe_unique_section (decl, reloc)
If the section has already been defined, to not allow it to have
different attributes, as (1) this is ambiguous since we're not seeing
all the declarations up front and (2) some assemblers (e.g. SVR4)
- do not recoginize section redefinitions. */
+ do not recognize section redefinitions. */
/* ??? This differs from the "standard" PE implementation in that we
handle the SHARED variable attribute. Should this be done for all
PE targets? */
@@ -567,10 +661,7 @@ i386_pe_unique_section (decl, reloc)
#define SECTION_PE_SHARED SECTION_MACH_DEP
unsigned int
-i386_pe_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
+i386_pe_section_type_flags (tree decl, const char *name, int reloc)
{
static htab_t htab;
unsigned int flags;
@@ -608,25 +699,33 @@ i386_pe_section_type_flags (decl, name, reloc)
else
{
if (decl && **slot != flags)
- error_with_decl (decl, "%s causes a section type conflict");
+ error ("%J'%D' causes a section type conflict", decl, decl);
}
return flags;
}
void
-i386_pe_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+i386_pe_asm_named_section (const char *name, unsigned int flags)
{
char flagchars[8], *f = flagchars;
- if (flags & SECTION_CODE)
- *f++ = 'x';
- if (flags & SECTION_WRITE)
- *f++ = 'w';
- if (flags & SECTION_PE_SHARED)
- *f++ = 's';
+ if ((flags & (SECTION_CODE | SECTION_WRITE)) == 0)
+ /* readonly data */
+ {
+ *f++ ='d'; /* This is necessary for older versions of gas. */
+ *f++ ='r';
+ }
+ else
+ {
+ if (flags & SECTION_CODE)
+ *f++ = 'x';
+ if (flags & SECTION_WRITE)
+ *f++ = 'w';
+ if (flags & SECTION_PE_SHARED)
+ *f++ = 's';
+ }
+
*f = '\0';
fprintf (asm_out_file, "\t.section\t%s,\"%s\"\n", name, flagchars);
@@ -654,10 +753,7 @@ i386_pe_asm_named_section (name, flags)
visible. */
void
-i386_pe_declare_function_type (file, name, public)
- FILE *file;
- const char *name;
- int public;
+i386_pe_declare_function_type (FILE *file, const char *name, int public)
{
fprintf (file, "\t.def\t");
assemble_name (file, name);
@@ -683,8 +779,7 @@ static struct extern_list *extern_head;
for it then. */
void
-i386_pe_record_external_function (name)
- const char *name;
+i386_pe_record_external_function (const char *name)
{
struct extern_list *p;
@@ -708,13 +803,11 @@ static struct export_list *export_head;
/* Assemble an export symbol entry. We need to keep a list of
these, so that we can output the export list at the end of the
assembly. We used to output these export symbols in each function,
- but that causes problems with GNU ld when the sections are
+ but that causes problems with GNU ld when the sections are
linkonce. */
void
-i386_pe_record_exported_symbol (name, is_data)
- const char *name;
- int is_data;
+i386_pe_record_exported_symbol (const char *name, int is_data)
{
struct export_list *p;
@@ -730,12 +823,11 @@ i386_pe_record_exported_symbol (name, is_data)
output the .drectve section. */
void
-i386_pe_asm_file_end (file)
- FILE *file;
+i386_pe_file_end (void)
{
struct extern_list *p;
- ix86_asm_file_end (file);
+ ix86_file_end ();
for (p = extern_head; p != NULL; p = p->next)
{
@@ -747,7 +839,8 @@ i386_pe_asm_file_end (file)
if (! TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (decl))
{
TREE_ASM_WRITTEN (decl) = 1;
- i386_pe_declare_function_type (file, p->name, TREE_PUBLIC (decl));
+ i386_pe_declare_function_type (asm_out_file, p->name,
+ TREE_PUBLIC (decl));
}
}
@@ -757,7 +850,7 @@ i386_pe_asm_file_end (file)
drectve_section ();
for (q = export_head; q != NULL; q = q->next)
{
- fprintf (file, "\t.ascii \" -export:%s%s\"\n",
+ fprintf (asm_out_file, "\t.ascii \" -export:%s%s\"\n",
i386_pe_strip_name_encoding (q->name),
(q->is_data) ? ",data" : "");
}
diff --git a/contrib/gcc/config/i386/x-mingw32 b/contrib/gcc/config/i386/x-mingw32
new file mode 100644
index 000000000000..04593aa727fd
--- /dev/null
+++ b/contrib/gcc/config/i386/x-mingw32
@@ -0,0 +1,4 @@
+#
+# Make local_includedir relative to EXEC_PREFIX
+#
+local_includedir=$(libsubdir)/$(unlibsubdir)/..`echo $(exec_prefix) | sed -e 's|^$(prefix)||' -e 's|/[^/]*|/..|g'`/include
diff --git a/contrib/gcc/config/i386/x86-64.h b/contrib/gcc/config/i386/x86-64.h
index 37a2a30216f1..16b06331b980 100644
--- a/contrib/gcc/config/i386/x86-64.h
+++ b/contrib/gcc/config/i386/x86-64.h
@@ -2,20 +2,20 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Bo Thorsen <bo@suse.de>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -27,7 +27,7 @@ Boston, MA 02111-1307, USA. */
(TARGET_64BIT ? dbx64_register_map[n] : svr4_dbx_register_map[n])
/* Output assembler code to FILE to call the profiler. */
-#define NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS 1
#undef MCOUNT_NAME
#define MCOUNT_NAME "mcount"
@@ -51,19 +51,10 @@ Boston, MA 02111-1307, USA. */
#define ASM_SPEC "%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} \
%{Wa,*:%*} %{m32:--32}"
-/* A C statement (sans semicolon) to output to the stdio stream
- FILE the assembler definition of uninitialized global DECL named
- NAME whose size is SIZE bytes and alignment is ALIGN bytes.
- Try to use asm_output_aligned_bss to implement this macro. */
-
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
-/* A C statement to output to the stdio stream FILE an assembler
- command to advance the location counter to a multiple of 1<<LOG
- bytes if it is within MAX_SKIP bytes.
-
- This is used to align code labels according to Intel recommendations. */
+/* This is used to align code labels according to Intel recommendations. */
#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
do { \
@@ -77,12 +68,11 @@ Boston, MA 02111-1307, USA. */
/* i386 System V Release 4 uses DWARF debugging info.
x86-64 ABI specifies DWARF2. */
-#undef DWARF_DEBUGGING_INFO
#define DWARF2_DEBUGGING_INFO 1
#define DWARF2_UNWIND_INFO 1
/* Incorrectly autodetected in cross compilation. */
#undef HAVE_AS_DWARF2_DEBUG_LINE
-#define HAVE_AS_DWARF2_DEBUG_LINE
+#define HAVE_AS_DWARF2_DEBUG_LINE 1
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
diff --git a/contrib/gcc/config/i386/xm-cygwin.h b/contrib/gcc/config/i386/xm-cygwin.h
index 721c435189f4..1ecb00cfbe1d 100644
--- a/contrib/gcc/config/i386/xm-cygwin.h
+++ b/contrib/gcc/config/i386/xm-cygwin.h
@@ -1,35 +1,22 @@
-/* Configuration for GNU C-compiler for hosting on Windows NT.
+/* Configuration for GCC for hosting on Windows NT.
using a unix style C library.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define HOST_EXECUTABLE_SUFFIX ".exe"
-
-/* Even though Cygwin tries to hide the DOS based filesystem, it
- still shows though at times. */
-#define HAVE_DOS_BASED_FILE_SYSTEM
-
-/* We support both "/" and "\" since everybody tests both but we
- default to "/". This is important because if gcc produces Win32
- paths containing backslashes, make and configure may treat the
- backslashes as escape characters. Many Win32 programs use forward
- slashes so using a forward slash shouldn't be problematic from the
- perspective of wanting gcc to produce native Win32 paths. */
-#undef DIR_SEPARATOR_2
-#define DIR_SEPARATOR_2 '\\'
diff --git a/contrib/gcc/config/i386/xm-djgpp.h b/contrib/gcc/config/i386/xm-djgpp.h
index 71cb1160faab..9bb520da8ef0 100644
--- a/contrib/gcc/config/i386/xm-djgpp.h
+++ b/contrib/gcc/config/i386/xm-djgpp.h
@@ -1,20 +1,20 @@
-/* Configuration for GNU C-compiler for Intel 80386 running DJGPP.
+/* Configuration for GCC for Intel 80386 running DJGPP.
Copyright (C) 1988, 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -23,13 +23,6 @@ Boston, MA 02111-1307, USA. */
#define HOST_EXECUTABLE_SUFFIX ".exe"
-/* Even though we support "/", allow "\" since everybody tests both. */
-#define DIR_SEPARATOR '/'
-#define DIR_SEPARATOR_2 '\\'
-
-/* Allow test for DOS drive names. */
-#define HAVE_DOS_BASED_FILE_SYSTEM
-
/* System dependent initialization for collect2
to tell system() to act like Unix. */
#define COLLECT2_HOST_INITIALIZATION \
@@ -50,9 +43,6 @@ Boston, MA 02111-1307, USA. */
strcat (xref_file, xref_ext); \
} while (0)
-/* Change /dev/env/DJDIR/prefix/dir/ to canonical form so gcc_exec_prefix
- is set properly in 'gcc.c'. It also helps to cut down the number of times
- the value of the DJGPP environment variable 'DJDIR' is evaluated. */
#undef GCC_DRIVER_HOST_INITIALIZATION
#define GCC_DRIVER_HOST_INITIALIZATION \
do { \
@@ -76,9 +66,6 @@ Boston, MA 02111-1307, USA. */
fatal ("environment variable DJGPP points to corrupt file '%s'", \
djgpp); \
} \
- standard_exec_prefix = update_path (standard_exec_prefix, NULL); \
- standard_bindir_prefix = update_path (standard_bindir_prefix, NULL); \
- standard_startfile_prefix = update_path (standard_startfile_prefix, NULL); \
} while (0)
/* Canonicalize paths containing '/dev/env/'; used in prefix.c.
diff --git a/contrib/gcc/config/i386/xm-mingw32.h b/contrib/gcc/config/i386/xm-mingw32.h
index 19b102dda005..888196697be9 100644
--- a/contrib/gcc/config/i386/xm-mingw32.h
+++ b/contrib/gcc/config/i386/xm-mingw32.h
@@ -1,33 +1,29 @@
-/* Configuration for GNU C-compiler for hosting on Windows32.
+/* Configuration for GCC for hosting on Windows32.
using GNU tools and the Windows32 API Library.
- Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999, 2001, 2002, 2003, 2004 Free Software
+ Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC 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.
+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 2, or (at your option) any later
+version.
-GNU CC 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.
+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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* Even though we support "/", allow "\" since everybody tests both. */
-#define DIR_SEPARATOR '\\'
-#define DIR_SEPARATOR_2 '/'
-
-/* Mingw32 does not try to hide the underlying DOS-based file system
- like Cygwin does. */
-#define HAVE_DOS_BASED_FILE_SYSTEM
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#define HOST_EXECUTABLE_SUFFIX ".exe"
#undef PATH_SEPARATOR
#define PATH_SEPARATOR ';'
+
+/* This is the name of the null device on windows. */
+#define HOST_BIT_BUCKET "nul"
diff --git a/contrib/gcc/config/i386/xmmintrin.h b/contrib/gcc/config/i386/xmmintrin.h
index 1829ab04b6be..1bc887830de7 100644
--- a/contrib/gcc/config/i386/xmmintrin.h
+++ b/contrib/gcc/config/i386/xmmintrin.h
@@ -1,19 +1,19 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -37,12 +37,11 @@
/* We need type definitions from the MMX header file. */
#include <mmintrin.h>
-/* The data type indended for user use. */
+/* The data type intended for user use. */
typedef int __m128 __attribute__ ((__mode__(__V4SF__)));
-/* Internal data types for implementing the instrinsics. */
+/* Internal data types for implementing the intrinsics. */
typedef int __v4sf __attribute__ ((__mode__(__V4SF__)));
-typedef int __v4si __attribute__ ((__mode__(__V4SI__)));
/* Create a selector for use with the SHUFPS instruction. */
#define _MM_SHUFFLE(fp3,fp2,fp1,fp0) \
@@ -890,19 +889,9 @@ _mm_set_ps1 (float __F)
/* Create the vector [Z Y X W]. */
static __inline __m128
-_mm_set_ps (float __Z, float __Y, float __X, float __W)
+_mm_set_ps (const float __Z, const float __Y, const float __X, const float __W)
{
- union {
- float __a[4];
- __m128 __v;
- } __u;
-
- __u.__a[0] = __W;
- __u.__a[1] = __X;
- __u.__a[2] = __Y;
- __u.__a[3] = __Z;
-
- return __u.__v;
+ return (__v4sf) {__W, __X, __Y, __Z};
}
/* Create the vector [W X Y Z]. */
@@ -1192,7 +1181,7 @@ _mm_stream_ps (float *__P, __m128 __A)
__builtin_ia32_movntps (__P, (__v4sf)__A);
}
-/* Guarantees that every preceeding store is globally visible before
+/* Guarantees that every preceding store is globally visible before
any subsequent store. */
static __inline void
_mm_sfence (void)
diff --git a/contrib/gcc/config/ia64/crtbegin.asm b/contrib/gcc/config/ia64/crtbegin.asm
index cb49e10bc56c..494def7fd815 100644
--- a/contrib/gcc/config/ia64/crtbegin.asm
+++ b/contrib/gcc/config/ia64/crtbegin.asm
@@ -33,33 +33,34 @@ __DTOR_LIST__:
__JCR_LIST__:
.section .sdata
- .type dtor_ptr#,@object
- .size dtor_ptr#,8
+ .type dtor_ptr,@object
+ .size dtor_ptr,8
dtor_ptr:
- data8 @gprel(__DTOR_LIST__# + 8)
+ data8 @gprel(__DTOR_LIST__ + 8)
/* A handle for __cxa_finalize to manage c++ local destructors. */
- .global __dso_handle#
- .type __dso_handle#,@object
- .size __dso_handle#,8
+ .global __dso_handle
+ .type __dso_handle,@object
+ .size __dso_handle,8
#ifdef SHARED
.section .data
__dso_handle:
- data8 __dso_handle#
+ data8 __dso_handle
#else
.section .bss
+ .align 8
__dso_handle:
- data8 0
+ .skip 8
#endif
- .hidden __dso_handle#
+ .hidden __dso_handle
#ifdef HAVE_INITFINI_ARRAY
-.section .fini_array,"a","progbits"
+.section .fini_array, "a"
data8 @fptr(__do_global_dtors_aux)
-.section .init_array,"a","progbits"
+.section .init_array, "a"
data8 @fptr(__do_jv_register_classes)
data8 @fptr(__do_global_ctors_aux)
@@ -79,7 +80,7 @@ __dso_handle:
*/
.section .fini,"ax","progbits"
{ .mlx
- movl r2 = @pcrel(__do_global_dtors_aux# - 16)
+ movl r2 = @pcrel(__do_global_dtors_aux - 16)
}
{ .mii
mov r3 = ip
@@ -88,16 +89,16 @@ __dso_handle:
;;
}
{ .mib
+ nop 0
mov b6 = r2
br.call.sptk.many b0 = b6
- ;;
}
/* Likewise for _init. */
.section .init,"ax","progbits"
{ .mlx
- movl r2 = @pcrel(__do_jv_register_classes# - 16)
+ movl r2 = @pcrel(__do_jv_register_classes - 16)
}
{ .mii
mov r3 = ip
@@ -106,63 +107,64 @@ __dso_handle:
;;
}
{ .mib
+ nop 0
mov b6 = r2
br.call.sptk.many b0 = b6
- ;;
}
#endif /* !HAVE_INITFINI_ARRAY */
.section .text
- .align 16
- .proc __do_global_dtors_aux#
+ .align 32
+ .proc __do_global_dtors_aux
__do_global_dtors_aux:
+ .prologue
#ifndef SHARED
- { .mii
- alloc loc3 = ar.pfs, 0, 4, 1, 0
- addl loc0 = @gprel(dtor_ptr#), gp
- mov loc1 = b0
- }
- { .mib
- mov loc2 = gp
- br.sptk.few 1f
- ;;
- }
+ .save ar.pfs, r35
+ alloc loc3 = ar.pfs, 0, 4, 1, 0
+ addl loc0 = @gprel(dtor_ptr), gp
+ .save rp, loc1
+ mov loc1 = rp
+ .body
+
+ mov loc2 = gp
+ nop 0
+ br.sptk.many .entry
#else
/*
if (__cxa_finalize)
__cxa_finalize(__dso_handle)
*/
- { .mii
- alloc loc3 = ar.pfs, 0, 4, 1, 0
- addl loc0 = @gprel(dtor_ptr#), gp
- addl r16 = @ltoff(@fptr(__cxa_finalize#)), gp
- ;;
- }
- { .mmi
- ld8 r16 = [r16]
- ;;
- addl out0 = @ltoff(__dso_handle#), gp
- cmp.ne p7, p0 = r0, r16
- ;;
- }
- { .mmi
- ld8 out0 = [out0]
-(p7) ld8 r18 = [r16], 8
- mov loc1 = b0
- ;;
- }
- { .mfi
- mov loc2 = gp
-(p7) mov b6 = r18
- }
- {
- .mfb
-(p7) ld8 gp = [r16]
-(p7) br.call.sptk.many b0 = b6
- }
- { .mfb
- br.sptk.few 1f
- }
+ .save ar.pfs, r35
+ alloc loc3 = ar.pfs, 0, 4, 1, 0
+ addl loc0 = @gprel(dtor_ptr), gp
+ addl r16 = @ltoff(@fptr(__cxa_finalize)), gp
+ ;;
+
+ ld8 r16 = [r16]
+ ;;
+ addl out0 = @ltoff(__dso_handle), gp
+ cmp.ne p7, p0 = r0, r16
+ ;;
+
+ ld8 out0 = [out0]
+(p7) ld8 r18 = [r16], 8
+ .save rp, loc1
+ mov loc1 = rp
+ .body
+ ;;
+
+ mov loc2 = gp
+(p7) ld8 gp = [r16]
+(p7) mov b6 = r18
+
+ nop 0
+ nop 0
+(p7) br.call.sptk.many rp = b6
+ ;;
+
+ nop 0
+ nop 0
+ br.sptk.many .entry
#endif
/*
do {
@@ -170,90 +172,77 @@ __do_global_dtors_aux:
(*(dtor_ptr-1)) ();
} while (dtor_ptr);
*/
-0:
- { .mmi
- st8 [loc0] = r15
- ld8 r17 = [r16], 8
- ;;
- }
- { .mib
- ld8 gp = [r16]
- mov b6 = r17
- br.call.sptk.many b0 = b6
- }
-1:
- { .mmi
- ld8 r15 = [loc0]
- ;;
- add r16 = r15, loc2
- adds r15 = 8, r15
- ;;
- }
- { .mmi
- ld8 r16 = [r16]
- mov gp = loc2
- mov b0 = loc1
- ;;
- }
- { .mib
- cmp.ne p6, p0 = r0, r16
- mov ar.pfs = loc3
-(p6) br.cond.sptk.few 0b
- }
- { .bbb
- br.ret.sptk.many b0
- ;;
- }
- .endp __do_global_dtors_aux#
-
- .align 16
- .proc __do_jv_register_classes#
+.loop:
+ st8 [loc0] = r15 // update dtor_ptr (in memory)
+ ld8 r17 = [r16], 8 // r17 <- dtor's entry-point
+ nop 0
+ ;;
+
+ ld8 gp = [r16] // gp <- dtor's gp
+ mov b6 = r17
+ br.call.sptk.many rp = b6
+
+.entry: ld8 r15 = [loc0] // r15 <- dtor_ptr (gp-relative)
+ ;;
+ add r16 = r15, loc2 // r16 <- dtor_ptr (absolute)
+ adds r15 = 8, r15
+ ;;
+
+ ld8 r16 = [r16] // r16 <- pointer to dtor's fdesc
+ mov rp = loc1
+ mov ar.pfs = loc3
+ ;;
+
+ cmp.ne p6, p0 = r0, r16
+(p6) br.cond.sptk.few .loop
+ br.ret.sptk.many rp
+ .endp __do_global_dtors_aux
+
+ .align 32
+ .proc __do_jv_register_classes
__do_jv_register_classes:
- { .mlx
- alloc loc2 = ar.pfs, 0, 3, 1, 0
- movl out0 = @gprel(__JCR_LIST__)
- ;;
- }
- { .mmi
- addl r14 = @ltoff(@fptr(_Jv_RegisterClasses)), gp
- add out0 = out0, gp
- ;;
- }
- { .mmi
- ld8 r14 = [r14]
- ld8 r15 = [out0]
- cmp.ne p6, p0 = r0, r0
- ;;
- }
- { .mib
- cmp.eq.or p6, p0 = r0, r14
- cmp.eq.or p6, p0 = r0, r15
-(p6) br.ret.sptk.many b0
- }
- { .mii
- ld8 r15 = [r14], 8
- mov loc0 = b0
- mov loc1 = gp
- ;;
- }
- { .mib
- ld8 gp = [r14]
- mov b6 = r15
- br.call.sptk.many b0 = b6
- ;;
- }
- { .mii
- mov gp = loc1
- mov b0 = loc0
- mov ar.pfs = loc2
- }
- { .bbb
- br.ret.sptk.many b0
- ;;
- }
- .endp __do_jv_register_classes#
+ .prologue
+ .save ar.pfs, r33
+ alloc loc1 = ar.pfs, 0, 3, 1, 0
+ movl out0 = @gprel(__JCR_LIST__)
+ ;;
+
+ addl r14 = @ltoff(@fptr(_Jv_RegisterClasses)), gp
+ add out0 = out0, gp
+ .save rp, loc0
+ mov loc0 = rp
+ .body
+ ;;
+
+ ld8 r14 = [r14]
+ ld8 r15 = [out0]
+ cmp.ne p6, p0 = r0, r0
+ ;;
+
+ cmp.eq.or p6, p0 = r0, r14
+ cmp.eq.or p6, p0 = r0, r15
+(p6) br.ret.sptk.many rp
+
+ ld8 r15 = [r14], 8
+ ;;
+ nop 0
+ mov b6 = r15
+
+ mov loc2 = gp
+ ld8 gp = [r14]
+ br.call.sptk.many rp = b6
+ ;;
+
+ mov gp = loc2
+ mov rp = loc0
+ mov ar.pfs = loc1
+
+ nop 0
+ nop 0
+ br.ret.sptk.many rp
+ .endp __do_jv_register_classes
#ifdef SHARED
-.weak __cxa_finalize#
+.weak __cxa_finalize
#endif
.weak _Jv_RegisterClasses
diff --git a/contrib/gcc/config/ia64/crtend.asm b/contrib/gcc/config/ia64/crtend.asm
index 303f30cbce87..8984d88f3d68 100644
--- a/contrib/gcc/config/ia64/crtend.asm
+++ b/contrib/gcc/config/ia64/crtend.asm
@@ -33,7 +33,10 @@ __DTOR_END__:
__JCR_END__:
data8 0
-#ifndef HAVE_INITFINI_ARRAY
+#ifdef HAVE_INITFINI_ARRAY
+ .global __do_global_ctors_aux
+ .hidden __do_global_ctors_aux
+#else /* !HAVE_INITFINI_ARRAY */
/*
* Fragment of the ELF _init routine that invokes our dtor cleanup.
*
@@ -49,7 +52,7 @@ __JCR_END__:
*/
.section .init,"ax","progbits"
{ .mlx
- movl r2 = @pcrel(__do_global_ctors_aux# - 16)
+ movl r2 = @pcrel(__do_global_ctors_aux - 16)
}
{ .mii
mov r3 = ip
@@ -65,63 +68,48 @@ __JCR_END__:
#endif /* !HAVE_INITFINI_ARRAY */
.text
- .align 16
-#ifdef HAVE_INITFINI_ARRAY
- /* This is referenced from crtbegin.o. */
- .globl __do_global_ctors_aux#
- .type __do_global_ctors_aux#,@function
- .hidden __do_global_ctors_aux#
-#endif
- .proc __do_global_ctors_aux#
+ .align 32
+ .proc __do_global_ctors_aux
__do_global_ctors_aux:
+ .prologue
/*
for (loc0 = __CTOR_END__-1; *p != -1; --p)
(*p) ();
*/
- { .mlx
- alloc loc4 = ar.pfs, 0, 5, 0, 0
- movl loc0 = @gprel(__CTOR_END__# - 8)
- ;;
- }
- { .mmi
- add loc0 = loc0, gp
- mov loc1 = b0
- ;;
- }
- {
- .mmi
- ld8 loc3 = [loc0], -8
- mov loc2 = gp
- ;;
- }
- { .mfb
- cmp.eq p6, p0 = -1, loc3
-(p6) br.cond.spnt.few 2f
- }
-0:
- { .mmi
- ld8 r15 = [loc3], 8
- ;;
- ld8 gp = [loc3]
- mov b6 = r15
- }
- { .mfb
- ld8 loc3 = [loc0], -8
- br.call.sptk.many b0 = b6
- ;;
- }
- { .mfb
- cmp.ne p6, p0 = -1, loc3
-(p6) br.cond.sptk.few 0b
- }
-2:
- { .mii
- mov gp = loc2
- mov b0 = loc1
- mov ar.pfs = loc4
- }
- { .bbb
- br.ret.sptk.many b0
- ;;
- }
- .endp __do_global_ctors_aux#
+ .save ar.pfs, r34
+ alloc loc2 = ar.pfs, 0, 5, 0, 0
+ movl loc0 = @gprel(__CTOR_END__ - 8)
+ ;;
+
+ add loc0 = loc0, gp
+ ;;
+ ld8 loc3 = [loc0], -8
+ .save rp, loc1
+ mov loc1 = rp
+ .body
+ ;;
+
+ cmp.eq p6, p0 = -1, loc3
+ mov loc4 = gp
+(p6) br.cond.spnt.few .exit
+
+.loop: ld8 r15 = [loc3], 8
+ ;;
+ ld8 gp = [loc3]
+ mov b6 = r15
+
+ ld8 loc3 = [loc0], -8
+ nop 0
+ br.call.sptk.many rp = b6
+ ;;
+
+ cmp.ne p6, p0 = -1, loc3
+ nop 0
+(p6) br.cond.sptk.few .loop
+
+.exit: mov gp = loc3
+ mov rp = loc1
+ mov ar.pfs = loc2
+
+ br.ret.sptk.many rp
+ .endp __do_global_ctors_aux
diff --git a/contrib/gcc/config/ia64/crti.asm b/contrib/gcc/config/ia64/crti.asm
index 4b94b7f69533..4b48e3d40e80 100644
--- a/contrib/gcc/config/ia64/crti.asm
+++ b/contrib/gcc/config/ia64/crti.asm
@@ -1,11 +1,11 @@
# Copyright (C) 2000, 2001 Free Software Foundation, Inc.
# Written By Timothy Wall
-#
+#
# 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 2, or (at your option) any
# later version.
-#
+#
# In addition to the permissions in the GNU General Public License, the
# Free Software Foundation gives you unlimited permission to link the
# compiled version of this file with other programs, and to distribute
@@ -13,23 +13,23 @@
# file. (The General Public License restrictions do apply in other
# respects; for example, they cover modification of the file, and
# distribution when not linked into another program.)
-#
+#
# 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.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-#
+#
# As a special exception, if you link this library with files
# compiled with GCC to produce an executable, this does not cause
# the resulting executable to be covered by the GNU General Public License.
# This exception does not however invalidate any other reasons why
# the executable file might be covered by the GNU General Public License.
-#
+#
# This file just make a stack frame for the contents of the .fini and
# .init sections. Users may put any desired instructions in those
@@ -39,7 +39,7 @@
.section ".init"
.align 16
- .global _init#
+ .global _init
_init:
.prologue 14, 33
.save ar.pfs, r34
@@ -49,10 +49,10 @@ _init:
.save rp, r33
mov r33 = b0
.body
-
+
.section ".fini"
.align 16
- .global _fini#
+ .global _fini
_fini:
.prologue 14, 33
.save ar.pfs, r34
@@ -62,5 +62,5 @@ _fini:
.save rp, r33
mov r33 = b0
.body
-
+
# end of crti.asm
diff --git a/contrib/gcc/config/ia64/crtn.asm b/contrib/gcc/config/ia64/crtn.asm
index 0b45d380aad9..48a9a03fdc61 100644
--- a/contrib/gcc/config/ia64/crtn.asm
+++ b/contrib/gcc/config/ia64/crtn.asm
@@ -1,11 +1,11 @@
# Copyright (C) 2000, 2001 Free Software Foundation, Inc.
# Written By Timothy Wall
-#
+#
# 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 2, or (at your option) any
# later version.
-#
+#
# In addition to the permissions in the GNU General Public License, the
# Free Software Foundation gives you unlimited permission to link the
# compiled version of this file with other programs, and to distribute
@@ -13,23 +13,23 @@
# file. (The General Public License restrictions do apply in other
# respects; for example, they cover modification of the file, and
# distribution when not linked into another program.)
-#
+#
# 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.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
-#
+#
# As a special exception, if you link this library with files
# compiled with GCC to produce an executable, this does not cause
# the resulting executable to be covered by the GNU General Public License.
# This exception does not however invalidate any other reasons why
# the executable file might be covered by the GNU General Public License.
-#
+#
# This file just makes sure that the .fini and .init sections do in
# fact return. Users may put any desired instructions in those sections.
@@ -44,7 +44,7 @@
.restore sp
mov r12 = r35
br.ret.sptk.many b0
-
+
.section ".fini"
;;
mov ar.pfs = r34
diff --git a/contrib/gcc/config/ia64/elf.h b/contrib/gcc/config/ia64/elf.h
index e30090d9c27d..6886ea00a463 100644
--- a/contrib/gcc/config/ia64/elf.h
+++ b/contrib/gcc/config/ia64/elf.h
@@ -5,9 +5,9 @@
#define TARGET_VERSION fprintf (stderr, " (IA-64) ELF");
-/* A C string constant that tells the GNU CC driver program options to pass to
+/* A C string constant that tells the GCC driver program options to pass to
the assembler. It can also specify how to translate options you give to GNU
- CC into options for GNU CC to pass to the assembler. */
+ CC into options for GCC to pass to the assembler. */
#if ((TARGET_CPU_DEFAULT | TARGET_DEFAULT) & MASK_GNU_AS) != 0
/* GNU AS. */
@@ -22,9 +22,9 @@
%{mauto-pic:-M no_plabel}"
#endif
-/* A C string constant that tells the GNU CC driver program options to pass to
- the linker. It can also specify how to translate options you give to GNU CC
- into options for GNU CC to pass to the linker. */
+/* A C string constant that tells the GCC driver program options to pass to
+ the linker. It can also specify how to translate options you give to GCC
+ into options for GCC to pass to the linker. */
/* The Intel linker does not support dynamic linking, so we need -dn.
The Intel linker gives annoying messages unless -N so is used. */
diff --git a/contrib/gcc/config/ia64/fde-glibc.c b/contrib/gcc/config/ia64/fde-glibc.c
index 83cc93a92563..15e19270f03b 100644
--- a/contrib/gcc/config/ia64/fde-glibc.c
+++ b/contrib/gcc/config/ia64/fde-glibc.c
@@ -1,20 +1,20 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@cygnus.com>.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -29,7 +29,7 @@
to avoid register/deregister calls at DSO load/unload. */
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
#endif
#include "config.h"
#include <stddef.h>
@@ -121,7 +121,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
if (p_dynamic)
{
- /* For dynamicly linked executables and shared libraries,
+ /* For dynamically linked executables and shared libraries,
DT_PLTGOT is the gp value for that object. */
Elf64_Dyn *dyn = (Elf64_Dyn *)(p_dynamic->p_vaddr + load_base);
for (; dyn->d_tag != DT_NULL ; dyn++)
diff --git a/contrib/gcc/config/ia64/freebsd.h b/contrib/gcc/config/ia64/freebsd.h
index 34dc885905b2..d5977ff4661a 100644
--- a/contrib/gcc/config/ia64/freebsd.h
+++ b/contrib/gcc/config/ia64/freebsd.h
@@ -1,26 +1,29 @@
/* Definitions for Intel IA-64 running FreeBSD using the ELF format
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2004 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
-#define LINK_SPEC \
- "%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
+#define LINK_SPEC " \
+ %{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \
%{Wl,*:%*} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
%{shared:-Bshareable %{h*} %{soname*}} \
@@ -28,7 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
+ %{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }} \
%{static:-Bstatic}}"
diff --git a/contrib/gcc/config/ia64/hpux.h b/contrib/gcc/config/ia64/hpux.h
index 90303eace1fc..f76cbd232163 100644
--- a/contrib/gcc/config/ia64/hpux.h
+++ b/contrib/gcc/config/ia64/hpux.h
@@ -1,22 +1,22 @@
/* Definitions of target machine GNU compiler. IA-64 version.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Steve Ellcey <sje@cup.hp.com> and
Reva Cuthbertson <reva@cup.hp.com>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,10 +25,11 @@ Boston, MA 02111-1307, USA. */
#define TARGET_VERSION fprintf (stderr, " (IA-64) HP-UX");
+/* Enable HPUX ABI quirks. */
+#undef TARGET_HPUX
+#define TARGET_HPUX 1
+
/* Target OS builtins. */
-/* -D__fpreg=long double is needed to compensate for
- the lack of __fpreg which is a primative type in
- HP C but does not exist in GNU C. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
builtin_assert("system=hpux"); \
@@ -38,15 +39,16 @@ do { \
builtin_define_std("unix"); \
builtin_define("__IA64__"); \
builtin_define("_LONGLONG"); \
+ builtin_define("_INCLUDE_LONGLONG"); \
builtin_define("_UINT128_T"); \
- builtin_define("__fpreg=long double"); \
- builtin_define("__float80=long double"); \
- builtin_define("__float128=long double"); \
- if (c_language == clk_cplusplus || !flag_iso) \
+ if (c_dialect_cxx () || !flag_iso) \
{ \
builtin_define("_HPUX_SOURCE"); \
builtin_define("__STDC_EXT__"); \
+ builtin_define("__STDCPP__"); \
} \
+ if (TARGET_ILP32) \
+ builtin_define("_ILP32"); \
} while (0)
#undef CPP_SPEC
@@ -85,7 +87,7 @@ do { \
#ifndef CROSS_COMPILE
#undef LIBGCC_SPEC
#define LIBGCC_SPEC \
- "%{shared-libgcc:%{!mlp64:-lgcc_s_hpux32}%{mlp64:-lgcc_s_hpux64} -lgcc} \
+ "%{shared-libgcc:%{!mlp64:-lgcc_s}%{mlp64:-lgcc_s_hpux64} -lgcc} \
%{!shared-libgcc:-lgcc}"
#endif
@@ -94,6 +96,8 @@ do { \
{ "ilp32", MASK_ILP32, "Generate ILP32 code" }, \
{ "lp64", -MASK_ILP32, "Generate LP64 code" },
+#define MULTILIB_DEFAULTS { "milp32" }
+
/* A C expression whose value is zero if pointers that need to be extended
from being `POINTER_SIZE' bits wide to `Pmode' are sign-extended and
greater then zero if they are zero-extended and less then zero if the
@@ -107,12 +111,13 @@ do { \
#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_BIG_ENDIAN | MASK_ILP32)
/* This needs to be set to force structure arguments with a single
- field to be treated as structures and not as the type of their
- field. Without this a structure with a single char will be
- returned just like a char variable and that is wrong on HP-UX
- IA64. */
+ integer field to be treated as structures and not as the type of
+ their field. Without this a structure with a single char will be
+ returned just like a char variable, instead of being returned at the
+ top of the register as specified for big-endian IA64. */
-#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) (TREE_CODE (TREE_TYPE (FIELD)) != REAL_TYPE || (MODE == TFmode && !INTEL_EXTENDED_IEEE_FORMAT))
+#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \
+ (!FLOAT_MODE_P (MODE) || (MODE) == TFmode)
/* ASM_OUTPUT_EXTERNAL_LIBCALL defaults to just a globalize_label call,
but that doesn't put out the @function type information which causes
@@ -132,8 +137,8 @@ do { \
#undef PAD_VARARGS_DOWN
#define PAD_VARARGS_DOWN (!AGGREGATE_TYPE_P (type))
-#define REGISTER_TARGET_PRAGMAS(PFILE) \
- cpp_register_pragma (PFILE, 0, "builtin", ia64_hpux_handle_builtin_pragma)
+#define REGISTER_TARGET_PRAGMAS() \
+ c_register_pragma (0, "builtin", ia64_hpux_handle_builtin_pragma)
/* Tell ia64.c that we are using the HP linker and we should delay output of
function extern declarations so that we don't output them for functions
@@ -148,7 +153,7 @@ do { \
/* Put out the needed function declarations at the end. */
-#define ASM_FILE_END(STREAM) ia64_hpux_asm_file_end(STREAM)
+#define TARGET_ASM_FILE_END ia64_hpux_file_end
#undef CTORS_SECTION_ASM_OP
#define CTORS_SECTION_ASM_OP "\t.section\t.init_array,\t\"aw\",\"init_array\""
@@ -188,3 +193,11 @@ do { \
#define TARGET_ASM_SELECT_RTX_SECTION ia64_rwreloc_select_rtx_section
#undef TARGET_SECTION_TYPE_FLAGS
#define TARGET_SECTION_TYPE_FLAGS ia64_rwreloc_section_type_flags
+
+/* ia64 HPUX has the float and long double forms of math functions. */
+#undef TARGET_C99_FUNCTIONS
+#define TARGET_C99_FUNCTIONS 1
+
+#define TARGET_INIT_LIBFUNCS ia64_hpux_init_libfuncs
+
+#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode)
diff --git a/contrib/gcc/config/ia64/ia64-c.c b/contrib/gcc/config/ia64/ia64-c.c
index e44c80b25a5f..422fc865b2a2 100644
--- a/contrib/gcc/config/ia64/ia64-c.c
+++ b/contrib/gcc/config/ia64/ia64-c.c
@@ -1,26 +1,28 @@
/* Definitions of C specific functions for GNU compiler.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Steve Ellcey <sje@cup.hp.com>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cpplib.h"
#include "c-common.h"
@@ -28,11 +30,10 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "tm_p.h"
-static void ia64_hpux_add_pragma_builtin PARAMS ((tree func));
+static void ia64_hpux_add_pragma_builtin (tree func);
void
-ia64_hpux_handle_builtin_pragma (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+ia64_hpux_handle_builtin_pragma (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
/* #pragma builtin name, name, name */
@@ -171,8 +172,7 @@ static const c89_mathlib_names c89_mathlib_name_list [] =
};
static void
-ia64_hpux_add_pragma_builtin (func)
- tree func;
+ia64_hpux_add_pragma_builtin (tree func)
{
size_t i;
diff --git a/contrib/gcc/config/ia64/ia64-modes.def b/contrib/gcc/config/ia64/ia64-modes.def
index 0c3eb127674c..17688bd9b85d 100644
--- a/contrib/gcc/config/ia64/ia64-modes.def
+++ b/contrib/gcc/config/ia64/ia64-modes.def
@@ -1,29 +1,68 @@
/* Definitions of target machine GNU compiler. IA-64 version.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by James E. Wilson <wilson@cygnus.com> and
David Mosberger <davidm@hpl.hp.com>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* IA64 requires both XF and TF modes.
+ XFmode is __float80 is IEEE extended; TFmode is __float128
+ is IEEE quad.
+
+ IEEE extended is 128 bits wide, except in ILP32 mode, but we
+ have to say it's 12 bytes so that the bitsize and wider_mode
+ tables are correctly set up. We correct its size below. */
+
+FLOAT_MODE (XF, 12, ieee_extended_intel_128_format);
+FLOAT_MODE (TF, 16, ieee_quad_format);
+
+/* The above produces:
+
+ mode ILP32 size/align LP64 size/align
+ XF 12/4 12/4
+ TF 16/16 16/16
+
+ psABI expectations:
+
+ mode ILP32 size/align LP64 size/align
+ XF - 16/16
+ TF - -
+
+ HPUX expectations:
+
+ mode ILP32 size/align LP64 size/align
+ XF 16/16 16/16
+ TF 16/8 -
+
+ We fix this up here. */
+
+ADJUST_BYTESIZE (XF, (TARGET_ILP32 && !TARGET_HPUX) ? 12 : 16);
+ADJUST_ALIGNMENT (XF, (TARGET_ILP32 && !TARGET_HPUX) ? 4 : 16);
+
+ADJUST_ALIGNMENT (TF, (TARGET_ILP32 && TARGET_HPUX) ? 8 : 16);
+
+/* 256-bit integer mode is needed for STACK_SAVEAREA_MODE. */
+INT_MODE (OI, 32);
+
/* Add any extra modes needed to represent the condition code.
CCImode is used to mark a single predicate register instead
of a register pair. This is currently only used in reg_raw_mode
so that flow doesn't do something stupid. */
-CC (CCI)
+CC_MODE (CCI);
diff --git a/contrib/gcc/config/ia64/ia64-protos.h b/contrib/gcc/config/ia64/ia64-protos.h
index f25bb02133d2..7825616491e4 100644
--- a/contrib/gcc/config/ia64/ia64-protos.h
+++ b/contrib/gcc/config/ia64/ia64-protos.h
@@ -1,20 +1,21 @@
/* Definitions of target machine for GNU compiler for IA-64.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -27,132 +28,127 @@ extern GTY(()) rtx ia64_compare_op1;
/* Functions defined in ia64.c */
+extern int bundling_p;
#ifdef RTX_CODE
-extern int call_operand PARAMS((rtx, enum machine_mode));
-extern int sdata_symbolic_operand PARAMS((rtx, enum machine_mode));
-extern int got_symbolic_operand PARAMS((rtx, enum machine_mode));
-extern int symbolic_operand PARAMS((rtx, enum machine_mode));
-extern int tls_symbolic_operand PARAMS((rtx, enum machine_mode));
-extern int function_operand PARAMS((rtx, enum machine_mode));
-extern int setjmp_operand PARAMS((rtx, enum machine_mode));
-extern int move_operand PARAMS((rtx, enum machine_mode));
-extern int gr_register_operand PARAMS((rtx, enum machine_mode));
-extern int fr_register_operand PARAMS((rtx, enum machine_mode));
-extern int grfr_register_operand PARAMS((rtx, enum machine_mode));
-extern int gr_nonimmediate_operand PARAMS((rtx, enum machine_mode));
-extern int fr_nonimmediate_operand PARAMS((rtx, enum machine_mode));
-extern int grfr_nonimmediate_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_0_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_5bit_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_6bit_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_8bit_operand PARAMS((rtx, enum machine_mode));
-extern int grfr_reg_or_8bit_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_8bit_adjusted_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_8bit_and_adjusted_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_14bit_operand PARAMS((rtx, enum machine_mode));
-extern int gr_reg_or_22bit_operand PARAMS((rtx, enum machine_mode));
-extern int shift_count_operand PARAMS((rtx, enum machine_mode));
-extern int shift_32bit_count_operand PARAMS((rtx, enum machine_mode));
-extern int shladd_operand PARAMS((rtx, enum machine_mode));
-extern int fetchadd_operand PARAMS((rtx, enum machine_mode));
-extern int fr_reg_or_fp01_operand PARAMS((rtx, enum machine_mode));
-extern int normal_comparison_operator PARAMS((rtx, enum machine_mode));
-extern int adjusted_comparison_operator PARAMS((rtx, enum machine_mode));
-extern int signed_inequality_operator PARAMS((rtx, enum machine_mode));
-extern int destination_operand PARAMS((rtx, enum machine_mode));
-extern int not_postinc_memory_operand PARAMS((rtx, enum machine_mode));
-extern int predicate_operator PARAMS((rtx, enum machine_mode));
-extern int ar_lc_reg_operand PARAMS((rtx, enum machine_mode));
-extern int ar_ccv_reg_operand PARAMS((rtx, enum machine_mode));
-extern int ar_pfs_reg_operand PARAMS((rtx, enum machine_mode));
-extern int general_tfmode_operand PARAMS((rtx, enum machine_mode));
-extern int destination_tfmode_operand PARAMS((rtx, enum machine_mode));
-extern int tfreg_or_fp01_operand PARAMS((rtx, enum machine_mode));
-extern int basereg_operand PARAMS((rtx, enum machine_mode));
-
-extern rtx ia64_expand_move PARAMS ((rtx, rtx));
-extern int ia64_move_ok PARAMS((rtx, rtx));
-extern int addp4_optimize_ok PARAMS((rtx, rtx));
-extern int ia64_depz_field_mask PARAMS((rtx, rtx));
-extern rtx ia64_split_timode PARAMS((rtx[], rtx, rtx));
-extern rtx spill_tfmode_operand PARAMS((rtx, int));
-extern rtx ia64_expand_compare PARAMS((enum rtx_code, enum machine_mode));
-extern void ia64_expand_call PARAMS((rtx, rtx, rtx, int));
-extern void ia64_split_call PARAMS((rtx, rtx, rtx, rtx, rtx, int, int));
-extern void ia64_reload_gp PARAMS((void));
-
-extern HOST_WIDE_INT ia64_initial_elimination_offset PARAMS((int, int));
-extern void ia64_expand_prologue PARAMS((void));
-extern void ia64_expand_epilogue PARAMS((int));
-
-extern int ia64_direct_return PARAMS((void));
-extern void ia64_expand_load_address PARAMS((rtx, rtx, rtx));
-extern int ia64_hard_regno_rename_ok PARAMS((int, int));
-
-extern void ia64_initialize_trampoline PARAMS((rtx, rtx, rtx));
-extern void ia64_print_operand_address PARAMS((FILE *, rtx));
-extern void ia64_print_operand PARAMS((FILE *, rtx, int));
-extern enum reg_class ia64_secondary_reload_class PARAMS((enum reg_class,
- enum machine_mode,
- rtx));
-extern void ia64_reorg PARAMS((rtx));
-extern void process_for_unwind_directive PARAMS ((FILE *, rtx));
-extern const char *get_bundle_name PARAMS ((int));
+extern int ia64_st_address_bypass_p (rtx, rtx);
+extern int ia64_ld_address_bypass_p (rtx, rtx);
+extern int ia64_produce_address_p (rtx);
+extern int call_operand (rtx, enum machine_mode);
+extern int sdata_symbolic_operand (rtx, enum machine_mode);
+extern int got_symbolic_operand (rtx, enum machine_mode);
+extern int symbolic_operand (rtx, enum machine_mode);
+extern int tls_symbolic_operand (rtx, enum machine_mode);
+extern int function_operand (rtx, enum machine_mode);
+extern int setjmp_operand (rtx, enum machine_mode);
+extern int move_operand (rtx, enum machine_mode);
+extern int gr_register_operand (rtx, enum machine_mode);
+extern int fr_register_operand (rtx, enum machine_mode);
+extern int grfr_register_operand (rtx, enum machine_mode);
+extern int gr_nonimmediate_operand (rtx, enum machine_mode);
+extern int fr_nonimmediate_operand (rtx, enum machine_mode);
+extern int grfr_nonimmediate_operand (rtx, enum machine_mode);
+extern int gr_reg_or_0_operand (rtx, enum machine_mode);
+extern int gr_reg_or_5bit_operand (rtx, enum machine_mode);
+extern int gr_reg_or_6bit_operand (rtx, enum machine_mode);
+extern int gr_reg_or_8bit_operand (rtx, enum machine_mode);
+extern int grfr_reg_or_8bit_operand (rtx, enum machine_mode);
+extern int gr_reg_or_8bit_adjusted_operand (rtx, enum machine_mode);
+extern int gr_reg_or_8bit_and_adjusted_operand (rtx, enum machine_mode);
+extern int gr_reg_or_14bit_operand (rtx, enum machine_mode);
+extern int gr_reg_or_22bit_operand (rtx, enum machine_mode);
+extern int shift_count_operand (rtx, enum machine_mode);
+extern int shift_32bit_count_operand (rtx, enum machine_mode);
+extern int shladd_operand (rtx, enum machine_mode);
+extern int fetchadd_operand (rtx, enum machine_mode);
+extern int fr_reg_or_fp01_operand (rtx, enum machine_mode);
+extern int normal_comparison_operator (rtx, enum machine_mode);
+extern int adjusted_comparison_operator (rtx, enum machine_mode);
+extern int signed_inequality_operator (rtx, enum machine_mode);
+extern int destination_operand (rtx, enum machine_mode);
+extern int not_postinc_memory_operand (rtx, enum machine_mode);
+extern int predicate_operator (rtx, enum machine_mode);
+extern int ar_lc_reg_operand (rtx, enum machine_mode);
+extern int ar_ccv_reg_operand (rtx, enum machine_mode);
+extern int ar_pfs_reg_operand (rtx, enum machine_mode);
+extern int general_xfmode_operand (rtx, enum machine_mode);
+extern int destination_xfmode_operand (rtx, enum machine_mode);
+extern int xfreg_or_fp01_operand (rtx, enum machine_mode);
+extern int basereg_operand (rtx, enum machine_mode);
+
+extern rtx ia64_expand_move (rtx, rtx);
+extern int ia64_move_ok (rtx, rtx);
+extern int addp4_optimize_ok (rtx, rtx);
+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 rtx spill_xfmode_operand (rtx, int);
+extern rtx ia64_expand_compare (enum rtx_code, enum machine_mode);
+extern void ia64_expand_call (rtx, rtx, rtx, int);
+extern void ia64_split_call (rtx, rtx, rtx, rtx, rtx, int, int);
+extern void ia64_reload_gp (void);
+
+extern HOST_WIDE_INT ia64_initial_elimination_offset (int, int);
+extern void ia64_expand_prologue (void);
+extern void ia64_expand_epilogue (int);
+
+extern int ia64_direct_return (void);
+extern void ia64_expand_load_address (rtx, rtx);
+extern int ia64_hard_regno_rename_ok (int, int);
+
+extern void ia64_initialize_trampoline (rtx, rtx, rtx);
+extern void ia64_print_operand_address (FILE *, rtx);
+extern void ia64_print_operand (FILE *, rtx, int);
+extern enum reg_class ia64_secondary_reload_class (enum reg_class,
+ enum machine_mode, rtx);
+extern void ia64_output_dwarf_dtprel (FILE*, int, rtx);
+extern void process_for_unwind_directive (FILE *, rtx);
+extern const char *get_bundle_name (int);
#endif /* RTX_CODE */
#ifdef TREE_CODE
#ifdef RTX_CODE
-extern rtx ia64_function_arg PARAMS((CUMULATIVE_ARGS *, enum machine_mode,
- tree, int, int));
-extern rtx ia64_expand_builtin PARAMS((tree, rtx, rtx,
- enum machine_mode, int));
-extern rtx ia64_va_arg PARAMS((tree, tree));
-extern rtx ia64_function_value PARAMS((tree, tree));
+extern rtx ia64_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, int, int);
+extern rtx ia64_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+extern rtx ia64_va_arg (tree, tree);
+extern rtx ia64_function_value (tree, tree);
#endif /* RTX_CODE */
-extern void ia64_setup_incoming_varargs PARAMS((CUMULATIVE_ARGS, int, tree,
- int *, int));
-extern int ia64_function_arg_partial_nregs PARAMS((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-extern void ia64_function_arg_advance PARAMS((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-extern int ia64_function_arg_pass_by_reference PARAMS((CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-extern int ia64_return_in_memory PARAMS((tree));
-extern void ia64_asm_output_external PARAMS((FILE *, tree, const char *));
+extern void ia64_setup_incoming_varargs (CUMULATIVE_ARGS, int, tree,
+ int *, int);
+extern int ia64_function_arg_partial_nregs (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern void ia64_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, int);
+extern int ia64_function_arg_pass_by_reference (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern int ia64_return_in_memory (tree);
+extern void ia64_asm_output_external (FILE *, tree, const char *);
#endif /* TREE_CODE */
-extern int ia64_register_move_cost PARAMS((enum machine_mode, enum reg_class,
- enum reg_class));
-extern int ia64_epilogue_uses PARAMS((int));
-extern int ia64_eh_uses PARAMS((int));
-extern void emit_safe_across_calls PARAMS((FILE *));
-extern void ia64_init_builtins PARAMS((void));
-extern void ia64_override_options PARAMS((void));
-extern int ia64_dbx_register_number PARAMS((int));
-extern bool ia64_function_ok_for_sibcall PARAMS ((tree));
+extern int ia64_register_move_cost (enum machine_mode, enum reg_class,
+ enum reg_class);
+extern int ia64_epilogue_uses (int);
+extern int ia64_eh_uses (int);
+extern void emit_safe_across_calls (void);
+extern void ia64_init_builtins (void);
+extern void ia64_override_options (void);
+extern int ia64_dbx_register_number (int);
-extern rtx ia64_return_addr_rtx PARAMS ((HOST_WIDE_INT, rtx));
-extern void ia64_split_return_addr_rtx PARAMS ((rtx));
+extern rtx ia64_return_addr_rtx (HOST_WIDE_INT, rtx);
+extern void ia64_split_return_addr_rtx (rtx);
#ifdef SDATA_SECTION_ASM_OP
-extern void sdata_section PARAMS ((void));
+extern void sdata_section (void);
#endif
#ifdef SBSS_SECTION_ASM_OP
-extern void sbss_section PARAMS ((void));
+extern void sbss_section (void);
#endif
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction'. */
-extern enum direction ia64_hpux_function_arg_padding PARAMS ((enum machine_mode, tree));
+extern enum direction ia64_hpux_function_arg_padding (enum machine_mode, tree);
#endif /* ARGS_SIZE_RTX */
-#ifdef GCC_C_PRAGMA_H
-extern void ia64_hpux_handle_builtin_pragma PARAMS ((cpp_reader *));
-#endif
-
-extern void ia64_hpux_asm_file_end PARAMS ((FILE *));
+extern void ia64_hpux_handle_builtin_pragma (struct cpp_reader *);
diff --git a/contrib/gcc/config/ia64/ia64.c b/contrib/gcc/config/ia64/ia64.c
index 12f3204d95d2..19c5e92b161f 100644
--- a/contrib/gcc/config/ia64/ia64.c
+++ b/contrib/gcc/config/ia64/ia64.c
@@ -1,27 +1,30 @@
/* Definitions of target machine for GNU compiler.
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by James E. Wilson <wilson@cygnus.com> and
- David Mosberger <davidm@hpl.hp.com>.
+ David Mosberger <davidm@hpl.hp.com>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "regs.h"
@@ -45,7 +48,9 @@ Boston, MA 02111-1307, USA. */
#include "target.h"
#include "target-def.h"
#include "tm_p.h"
+#include "hashtab.h"
#include "langhooks.h"
+#include "cfglayout.h"
/* This is used for communication between ASM_OUTPUT_LABEL and
ASM_OUTPUT_LABELREF. */
@@ -102,6 +107,12 @@ int ia64_tls_size = 22;
/* String used with the -mtls-size= option. */
const char *ia64_tls_size_string;
+/* Which cpu are we scheduling for. */
+enum processor_type ia64_tune;
+
+/* String used with the -tune= option. */
+const char *ia64_tune_string;
+
/* Determines whether we run our final scheduling pass or not. We always
avoid the normal second scheduling pass. */
static int ia64_flag_schedule_insns2;
@@ -111,6 +122,10 @@ static int ia64_flag_schedule_insns2;
unsigned int ia64_section_threshold;
+/* The following variable is used by the DFA insn scheduler. The value is
+ TRUE if we do insn bundling instead of insn scheduling. */
+int bundling_p = 0;
+
/* Structure to be filled in by ia64_compute_frame_size with register
save masks and offsets for the current function. */
@@ -122,7 +137,7 @@ struct ia64_frame_info
HOST_WIDE_INT spill_size; /* size of the gr/br/fr spill area. */
HOST_WIDE_INT extra_spill_size; /* size of spill area for others. */
HARD_REG_SET mask; /* mask of saved registers. */
- unsigned int gr_used_mask; /* mask of registers in use as gr spill
+ unsigned int gr_used_mask; /* mask of registers in use as gr spill
registers or long-term scratches. */
int n_spilled; /* number of spilled registers. */
int reg_fp; /* register for fp. */
@@ -144,84 +159,118 @@ struct ia64_frame_info
/* Current frame information calculated by ia64_compute_frame_size. */
static struct ia64_frame_info current_frame_info;
-static rtx gen_tls_get_addr PARAMS ((void));
-static rtx gen_thread_pointer PARAMS ((void));
-static int find_gr_spill PARAMS ((int));
-static int next_scratch_gr_reg PARAMS ((void));
-static void mark_reg_gr_used_mask PARAMS ((rtx, void *));
-static void ia64_compute_frame_size PARAMS ((HOST_WIDE_INT));
-static void setup_spill_pointers PARAMS ((int, rtx, HOST_WIDE_INT));
-static void finish_spill_pointers PARAMS ((void));
-static rtx spill_restore_mem PARAMS ((rtx, HOST_WIDE_INT));
-static void do_spill PARAMS ((rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT, rtx));
-static void do_restore PARAMS ((rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT));
-static rtx gen_movdi_x PARAMS ((rtx, rtx, rtx));
-static rtx gen_fr_spill_x PARAMS ((rtx, rtx, rtx));
-static rtx gen_fr_restore_x PARAMS ((rtx, rtx, rtx));
-
-static enum machine_mode hfa_element_mode PARAMS ((tree, int));
-static void fix_range PARAMS ((const char *));
-static struct machine_function * ia64_init_machine_status PARAMS ((void));
-static void emit_insn_group_barriers PARAMS ((FILE *, rtx));
-static void emit_all_insn_group_barriers PARAMS ((FILE *, rtx));
-static void emit_predicate_relation_info PARAMS ((void));
-static bool ia64_in_small_data_p PARAMS ((tree));
-static void ia64_encode_section_info PARAMS ((tree, int));
-static const char *ia64_strip_name_encoding PARAMS ((const char *));
-static void process_epilogue PARAMS ((void));
-static int process_set PARAMS ((FILE *, rtx));
-
-static rtx ia64_expand_fetch_and_op PARAMS ((optab, enum machine_mode,
- tree, rtx));
-static rtx ia64_expand_op_and_fetch PARAMS ((optab, enum machine_mode,
- tree, rtx));
-static rtx ia64_expand_compare_and_swap PARAMS ((enum machine_mode,
- enum machine_mode,
- int, tree, rtx));
-static rtx ia64_expand_lock_test_and_set PARAMS ((enum machine_mode,
- tree, rtx));
-static rtx ia64_expand_lock_release PARAMS ((enum machine_mode, tree, rtx));
-static bool ia64_assemble_integer PARAMS ((rtx, unsigned int, int));
-static void ia64_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void ia64_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-static void ia64_output_function_end_prologue PARAMS ((FILE *));
-
-static int ia64_issue_rate PARAMS ((void));
-static int ia64_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static void ia64_sched_init PARAMS ((FILE *, int, int));
-static void ia64_sched_finish PARAMS ((FILE *, int));
-static int ia64_internal_sched_reorder PARAMS ((FILE *, int, rtx *,
- int *, int, int));
-static int ia64_sched_reorder PARAMS ((FILE *, int, rtx *, int *, int));
-static int ia64_sched_reorder2 PARAMS ((FILE *, int, rtx *, int *, int));
-static int ia64_variable_issue PARAMS ((FILE *, int, rtx, int));
-
-static void ia64_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
- HOST_WIDE_INT, tree));
-
-static void ia64_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
-static void ia64_rwreloc_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT))
+static int ia64_use_dfa_pipeline_interface (void);
+static int ia64_first_cycle_multipass_dfa_lookahead (void);
+static void ia64_dependencies_evaluation_hook (rtx, rtx);
+static void ia64_init_dfa_pre_cycle_insn (void);
+static rtx ia64_dfa_pre_cycle_insn (void);
+static int ia64_first_cycle_multipass_dfa_lookahead_guard (rtx);
+static int ia64_dfa_new_cycle (FILE *, int, rtx, int, int, int *);
+static rtx gen_tls_get_addr (void);
+static rtx gen_thread_pointer (void);
+static rtx ia64_expand_tls_address (enum tls_model, rtx, rtx);
+static int find_gr_spill (int);
+static int next_scratch_gr_reg (void);
+static void mark_reg_gr_used_mask (rtx, void *);
+static void ia64_compute_frame_size (HOST_WIDE_INT);
+static void setup_spill_pointers (int, rtx, HOST_WIDE_INT);
+static void finish_spill_pointers (void);
+static rtx spill_restore_mem (rtx, HOST_WIDE_INT);
+static void do_spill (rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT, rtx);
+static void do_restore (rtx (*)(rtx, rtx, rtx), rtx, HOST_WIDE_INT);
+static rtx gen_movdi_x (rtx, rtx, rtx);
+static rtx gen_fr_spill_x (rtx, rtx, rtx);
+static rtx gen_fr_restore_x (rtx, rtx, rtx);
+
+static enum machine_mode hfa_element_mode (tree, int);
+static bool ia64_function_ok_for_sibcall (tree, tree);
+static bool ia64_rtx_costs (rtx, int, int, int *);
+static void fix_range (const char *);
+static struct machine_function * ia64_init_machine_status (void);
+static void emit_insn_group_barriers (FILE *);
+static void emit_all_insn_group_barriers (FILE *);
+static void final_emit_insn_group_barriers (FILE *);
+static void emit_predicate_relation_info (void);
+static void ia64_reorg (void);
+static bool ia64_in_small_data_p (tree);
+static void process_epilogue (void);
+static int process_set (FILE *, rtx);
+
+static rtx ia64_expand_fetch_and_op (optab, enum machine_mode, tree, rtx);
+static rtx ia64_expand_op_and_fetch (optab, enum machine_mode, tree, rtx);
+static rtx ia64_expand_compare_and_swap (enum machine_mode, enum machine_mode,
+ int, tree, rtx);
+static rtx ia64_expand_lock_test_and_set (enum machine_mode, tree, rtx);
+static rtx ia64_expand_lock_release (enum machine_mode, tree, rtx);
+static bool ia64_assemble_integer (rtx, unsigned int, int);
+static void ia64_output_function_prologue (FILE *, HOST_WIDE_INT);
+static void ia64_output_function_epilogue (FILE *, HOST_WIDE_INT);
+static void ia64_output_function_end_prologue (FILE *);
+
+static int ia64_issue_rate (void);
+static int ia64_adjust_cost (rtx, rtx, rtx, int);
+static void ia64_sched_init (FILE *, int, int);
+static void ia64_sched_finish (FILE *, int);
+static int ia64_dfa_sched_reorder (FILE *, int, rtx *, int *, int, int);
+static int ia64_sched_reorder (FILE *, int, rtx *, int *, int);
+static int ia64_sched_reorder2 (FILE *, int, rtx *, int *, int);
+static int ia64_variable_issue (FILE *, int, rtx, int);
+
+static struct bundle_state *get_free_bundle_state (void);
+static void free_bundle_state (struct bundle_state *);
+static void initiate_bundle_states (void);
+static void finish_bundle_states (void);
+static unsigned bundle_state_hash (const void *);
+static int bundle_state_eq_p (const void *, const void *);
+static int insert_bundle_state (struct bundle_state *);
+static void initiate_bundle_state_table (void);
+static void finish_bundle_state_table (void);
+static int try_issue_nops (struct bundle_state *, int);
+static int try_issue_insn (struct bundle_state *, rtx);
+static void issue_nops_and_insn (struct bundle_state *, int, rtx, int, int);
+static int get_max_pos (state_t);
+static int get_template (state_t, int);
+
+static rtx get_next_important_insn (rtx, rtx);
+static void bundling (FILE *, int, rtx, rtx);
+
+static void ia64_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
+ HOST_WIDE_INT, tree);
+static void ia64_file_start (void);
+
+static void ia64_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
+static void ia64_rwreloc_select_section (tree, int, unsigned HOST_WIDE_INT)
ATTRIBUTE_UNUSED;
-static void ia64_rwreloc_unique_section PARAMS ((tree, int))
+static void ia64_rwreloc_unique_section (tree, int)
ATTRIBUTE_UNUSED;
-static void ia64_rwreloc_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT))
+static void ia64_rwreloc_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT)
ATTRIBUTE_UNUSED;
-static unsigned int ia64_rwreloc_section_type_flags
- PARAMS ((tree, const char *, int))
+static unsigned int ia64_rwreloc_section_type_flags (tree, const char *, int)
ATTRIBUTE_UNUSED;
-static void ia64_hpux_add_extern_decl PARAMS ((const char *name))
+static void ia64_hpux_add_extern_decl (tree decl)
+ ATTRIBUTE_UNUSED;
+static void ia64_hpux_file_end (void)
+ ATTRIBUTE_UNUSED;
+static void ia64_hpux_init_libfuncs (void)
ATTRIBUTE_UNUSED;
+static void ia64_vms_init_libfuncs (void)
+ ATTRIBUTE_UNUSED;
+
+static tree ia64_handle_model_attribute (tree *, tree, tree, int, bool *);
+static void ia64_encode_section_info (tree, rtx, int);
+static rtx ia64_struct_value_rtx (tree, int);
+
/* Table of valid machine attributes. */
static const struct attribute_spec ia64_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
{ "syscall_linkage", 0, 0, false, true, true, NULL },
- { NULL, 0, 0, false, false, false, NULL }
+ { "model", 1, 1, true, false, false, ia64_handle_model_attribute },
+ { NULL, 0, 0, false, false, false, NULL }
};
/* Initialize the GCC target structure. */
@@ -260,10 +309,6 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P ia64_in_small_data_p
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO ia64_encode_section_info
-#undef TARGET_STRIP_NAME_ENCODING
-#define TARGET_STRIP_NAME_ENCODING ia64_strip_name_encoding
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST ia64_adjust_cost
@@ -280,24 +325,58 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_SCHED_REORDER2
#define TARGET_SCHED_REORDER2 ia64_sched_reorder2
-#ifdef HAVE_AS_TLS
-#undef TARGET_HAVE_TLS
-#define TARGET_HAVE_TLS true
-#endif
+#undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
+#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK ia64_dependencies_evaluation_hook
+
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE ia64_use_dfa_pipeline_interface
+
+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD ia64_first_cycle_multipass_dfa_lookahead
+
+#undef TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN
+#define TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN ia64_init_dfa_pre_cycle_insn
+#undef TARGET_SCHED_DFA_PRE_CYCLE_INSN
+#define TARGET_SCHED_DFA_PRE_CYCLE_INSN ia64_dfa_pre_cycle_insn
+
+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD\
+ ia64_first_cycle_multipass_dfa_lookahead_guard
+
+#undef TARGET_SCHED_DFA_NEW_CYCLE
+#define TARGET_SCHED_DFA_NEW_CYCLE ia64_dfa_new_cycle
+
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL ia64_function_ok_for_sibcall
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK ia64_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
+#undef TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START ia64_file_start
+
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS ia64_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
+
+#undef TARGET_MACHINE_DEPENDENT_REORG
+#define TARGET_MACHINE_DEPENDENT_REORG ia64_reorg
+
+#undef TARGET_ENCODE_SECTION_INFO
+#define TARGET_ENCODE_SECTION_INFO ia64_encode_section_info
+
+#undef TARGET_STRUCT_VALUE_RTX
+#define TARGET_STRUCT_VALUE_RTX ia64_struct_value_rtx
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Return 1 if OP is a valid operand for the MEM of a CALL insn. */
int
-call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+call_operand (rtx op, enum machine_mode mode)
{
if (mode != GET_MODE (op) && mode != VOIDmode)
return 0;
@@ -309,9 +388,7 @@ call_operand (op, mode)
/* Return 1 if OP refers to a symbol in the sdata section. */
int
-sdata_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+sdata_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
@@ -326,10 +403,7 @@ sdata_symbolic_operand (op, mode)
if (CONSTANT_POOL_ADDRESS_P (op))
return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold;
else
- {
- const char *str = XSTR (op, 0);
- return (str[0] == ENCODE_SECTION_INFO_CHAR && str[1] == 's');
- }
+ return SYMBOL_REF_LOCAL_P (op) && SYMBOL_REF_SMALL_P (op);
default:
break;
@@ -338,12 +412,16 @@ sdata_symbolic_operand (op, mode)
return 0;
}
+int
+small_addr_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return SYMBOL_REF_SMALL_ADDR_P (op);
+}
+
/* Return 1 if OP refers to a symbol, and is appropriate for a GOT load. */
int
-got_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+got_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
@@ -374,6 +452,8 @@ got_symbolic_operand (op, mode)
return (INTVAL (op) & 0x3fff) == 0;
case SYMBOL_REF:
+ if (SYMBOL_REF_SMALL_ADDR_P (op))
+ return 0;
case LABEL_REF:
return 1;
@@ -386,9 +466,7 @@ got_symbolic_operand (op, mode)
/* Return 1 if OP refers to a symbol. */
int
-symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
@@ -406,40 +484,20 @@ symbolic_operand (op, mode)
/* Return tls_model if OP refers to a TLS symbol. */
int
-tls_symbolic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+tls_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- const char *str;
-
if (GET_CODE (op) != SYMBOL_REF)
return 0;
- str = XSTR (op, 0);
- if (str[0] != ENCODE_SECTION_INFO_CHAR)
- return 0;
- switch (str[1])
- {
- case 'G':
- return TLS_MODEL_GLOBAL_DYNAMIC;
- case 'L':
- return TLS_MODEL_LOCAL_DYNAMIC;
- case 'i':
- return TLS_MODEL_INITIAL_EXEC;
- case 'l':
- return TLS_MODEL_LOCAL_EXEC;
- }
- return 0;
+ return SYMBOL_REF_TLS_MODEL (op);
}
/* Return 1 if OP refers to a function. */
int
-function_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+function_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
- if (GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_FLAG (op))
+ if (GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (op))
return 1;
else
return 0;
@@ -450,9 +508,7 @@ function_operand (op, mode)
/* ??? This is an unsatisfying solution. Should rethink. */
int
-setjmp_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+setjmp_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
const char *name;
int retval = 0;
@@ -495,29 +551,18 @@ setjmp_operand (op, mode)
return retval;
}
-/* Return 1 if OP is a general operand, but when pic exclude symbolic
- operands. */
-
-/* ??? If we drop no-pic support, can delete SYMBOL_REF, CONST, and LABEL_REF
- from PREDICATE_CODES. */
+/* Return 1 if OP is a general operand, excluding tls symbolic operands. */
int
-move_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+move_operand (rtx op, enum machine_mode mode)
{
- if (! TARGET_NO_PIC && symbolic_operand (op, mode))
- return 0;
-
- return general_operand (op, mode);
+ return general_operand (op, mode) && !tls_symbolic_operand (op, mode);
}
/* Return 1 if OP is a register operand that is (or could be) a GR reg. */
int
-gr_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_register_operand (rtx op, enum machine_mode mode)
{
if (! register_operand (op, mode))
return 0;
@@ -535,9 +580,7 @@ gr_register_operand (op, mode)
/* Return 1 if OP is a register operand that is (or could be) an FR reg. */
int
-fr_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fr_register_operand (rtx op, enum machine_mode mode)
{
if (! register_operand (op, mode))
return 0;
@@ -555,9 +598,7 @@ fr_register_operand (op, mode)
/* Return 1 if OP is a register operand that is (or could be) a GR/FR reg. */
int
-grfr_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+grfr_register_operand (rtx op, enum machine_mode mode)
{
if (! register_operand (op, mode))
return 0;
@@ -575,9 +616,7 @@ grfr_register_operand (op, mode)
/* Return 1 if OP is a nonimmediate operand that is (or could be) a GR reg. */
int
-gr_nonimmediate_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_nonimmediate_operand (rtx op, enum machine_mode mode)
{
if (! nonimmediate_operand (op, mode))
return 0;
@@ -595,9 +634,7 @@ gr_nonimmediate_operand (op, mode)
/* Return 1 if OP is a nonimmediate operand that is (or could be) a FR reg. */
int
-fr_nonimmediate_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fr_nonimmediate_operand (rtx op, enum machine_mode mode)
{
if (! nonimmediate_operand (op, mode))
return 0;
@@ -615,9 +652,7 @@ fr_nonimmediate_operand (op, mode)
/* Return 1 if OP is a nonimmediate operand that is a GR/FR reg. */
int
-grfr_nonimmediate_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+grfr_nonimmediate_operand (rtx op, enum machine_mode mode)
{
if (! nonimmediate_operand (op, mode))
return 0;
@@ -635,9 +670,7 @@ grfr_nonimmediate_operand (op, mode)
/* Return 1 if OP is a GR register operand, or zero. */
int
-gr_reg_or_0_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_0_operand (rtx op, enum machine_mode mode)
{
return (op == const0_rtx || gr_register_operand (op, mode));
}
@@ -645,9 +678,7 @@ gr_reg_or_0_operand (op, mode)
/* Return 1 if OP is a GR register operand, or a 5 bit immediate operand. */
int
-gr_reg_or_5bit_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_5bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) < 32)
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -657,9 +688,7 @@ gr_reg_or_5bit_operand (op, mode)
/* Return 1 if OP is a GR register operand, or a 6 bit immediate operand. */
int
-gr_reg_or_6bit_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_6bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -669,9 +698,7 @@ gr_reg_or_6bit_operand (op, mode)
/* Return 1 if OP is a GR register operand, or an 8 bit immediate operand. */
int
-gr_reg_or_8bit_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_8bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -681,9 +708,7 @@ gr_reg_or_8bit_operand (op, mode)
/* Return 1 if OP is a GR/FR register operand, or an 8 bit immediate. */
int
-grfr_reg_or_8bit_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+grfr_reg_or_8bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -694,9 +719,7 @@ grfr_reg_or_8bit_operand (op, mode)
operand. */
int
-gr_reg_or_8bit_adjusted_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_8bit_adjusted_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_L (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -709,9 +732,7 @@ gr_reg_or_8bit_adjusted_operand (op, mode)
so we need the union of the immediates accepted by GT and LT. */
int
-gr_reg_or_8bit_and_adjusted_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_8bit_and_adjusted_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_K (INTVAL (op))
&& CONST_OK_FOR_L (INTVAL (op)))
@@ -722,9 +743,7 @@ gr_reg_or_8bit_and_adjusted_operand (op, mode)
/* Return 1 if OP is a register operand, or a 14 bit immediate operand. */
int
-gr_reg_or_14bit_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_14bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_I (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -734,9 +753,7 @@ gr_reg_or_14bit_operand (op, mode)
/* Return 1 if OP is a register operand, or a 22 bit immediate operand. */
int
-gr_reg_or_22bit_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gr_reg_or_22bit_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_J (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX
@@ -746,9 +763,7 @@ gr_reg_or_22bit_operand (op, mode)
/* Return 1 if OP is a 6 bit immediate operand. */
int
-shift_count_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+shift_count_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return ((GET_CODE (op) == CONST_INT && CONST_OK_FOR_M (INTVAL (op)))
|| GET_CODE (op) == CONSTANT_P_RTX);
@@ -757,9 +772,7 @@ shift_count_operand (op, mode)
/* Return 1 if OP is a 5 bit immediate operand. */
int
-shift_32bit_count_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+shift_32bit_count_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return ((GET_CODE (op) == CONST_INT
&& (INTVAL (op) >= 0 && INTVAL (op) < 32))
@@ -769,9 +782,7 @@ shift_32bit_count_operand (op, mode)
/* Return 1 if OP is a 2, 4, 8, or 16 immediate operand. */
int
-shladd_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+shladd_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& (INTVAL (op) == 2 || INTVAL (op) == 4
@@ -781,9 +792,7 @@ shladd_operand (op, mode)
/* Return 1 if OP is a -16, -8, -4, -1, 1, 4, 8, or 16 immediate operand. */
int
-fetchadd_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+fetchadd_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& (INTVAL (op) == -16 || INTVAL (op) == -8 ||
@@ -795,9 +804,7 @@ fetchadd_operand (op, mode)
/* Return 1 if OP is a floating-point constant zero, one, or a register. */
int
-fr_reg_or_fp01_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fr_reg_or_fp01_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_OK_FOR_G (op))
|| fr_register_operand (op, mode));
@@ -807,9 +814,7 @@ fr_reg_or_fp01_operand (op, mode)
POST_MODIFY with a REG as displacement. */
int
-destination_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+destination_operand (rtx op, enum machine_mode mode)
{
if (! nonimmediate_operand (op, mode))
return 0;
@@ -823,21 +828,17 @@ destination_operand (op, mode)
/* Like memory_operand, but don't allow post-increments. */
int
-not_postinc_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+not_postinc_memory_operand (rtx op, enum machine_mode mode)
{
return (memory_operand (op, mode)
&& GET_RTX_CLASS (GET_CODE (XEXP (op, 0))) != 'a');
}
-/* Return 1 if this is a comparison operator, which accepts an normal 8-bit
+/* Return 1 if this is a comparison operator, which accepts a normal 8-bit
signed immediate operand. */
int
-normal_comparison_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+normal_comparison_operator (register rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
return ((mode == VOIDmode || GET_MODE (op) == mode)
@@ -849,9 +850,7 @@ normal_comparison_operator (op, mode)
signed immediate operand. */
int
-adjusted_comparison_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+adjusted_comparison_operator (register rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
return ((mode == VOIDmode || GET_MODE (op) == mode)
@@ -861,9 +860,7 @@ adjusted_comparison_operator (op, mode)
/* Return 1 if this is a signed inequality operator. */
int
-signed_inequality_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+signed_inequality_operator (register rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
return ((mode == VOIDmode || GET_MODE (op) == mode)
@@ -874,9 +871,7 @@ signed_inequality_operator (op, mode)
/* Return 1 if this operator is valid for predication. */
int
-predicate_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+predicate_operator (register rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
return ((GET_MODE (op) == mode || mode == VOIDmode)
@@ -886,9 +881,7 @@ predicate_operator (op, mode)
/* Return 1 if this operator can be used in a conditional operation. */
int
-condop_operator (op, mode)
- register rtx op;
- enum machine_mode mode;
+condop_operator (register rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
return ((GET_MODE (op) == mode || mode == VOIDmode)
@@ -899,9 +892,7 @@ condop_operator (op, mode)
/* Return 1 if this is the ar.lc register. */
int
-ar_lc_reg_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+ar_lc_reg_operand (register rtx op, enum machine_mode mode)
{
return (GET_MODE (op) == DImode
&& (mode == DImode || mode == VOIDmode)
@@ -912,9 +903,7 @@ ar_lc_reg_operand (op, mode)
/* Return 1 if this is the ar.ccv register. */
int
-ar_ccv_reg_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+ar_ccv_reg_operand (register rtx op, enum machine_mode mode)
{
return ((GET_MODE (op) == mode || mode == VOIDmode)
&& GET_CODE (op) == REG
@@ -924,9 +913,7 @@ ar_ccv_reg_operand (op, mode)
/* Return 1 if this is the ar.pfs register. */
int
-ar_pfs_reg_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+ar_pfs_reg_operand (register rtx op, enum machine_mode mode)
{
return ((GET_MODE (op) == mode || mode == VOIDmode)
&& GET_CODE (op) == REG
@@ -936,9 +923,7 @@ ar_pfs_reg_operand (op, mode)
/* Like general_operand, but don't allow (mem (addressof)). */
int
-general_tfmode_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+general_xfmode_operand (rtx op, enum machine_mode mode)
{
if (! general_operand (op, mode))
return 0;
@@ -950,9 +935,7 @@ general_tfmode_operand (op, mode)
/* Similarly. */
int
-destination_tfmode_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+destination_xfmode_operand (rtx op, enum machine_mode mode)
{
if (! destination_operand (op, mode))
return 0;
@@ -964,9 +947,7 @@ destination_tfmode_operand (op, mode)
/* Similarly. */
int
-tfreg_or_fp01_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+xfreg_or_fp01_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == SUBREG)
return 0;
@@ -976,9 +957,7 @@ tfreg_or_fp01_operand (op, mode)
/* Return 1 if OP is valid as a base register in a reg + offset address. */
int
-basereg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+basereg_operand (rtx op, enum machine_mode mode)
{
/* ??? Should I copy the flag_omit_frame_pointer and cse_not_expected
checks from pa.c basereg_operand as well? Seems to be OK without them
@@ -988,11 +967,133 @@ basereg_operand (op, mode)
REG_POINTER ((GET_CODE (op) == SUBREG) ? SUBREG_REG (op) : op));
}
+typedef enum
+ {
+ ADDR_AREA_NORMAL, /* normal address area */
+ ADDR_AREA_SMALL /* addressable by "addl" (-2MB < addr < 2MB) */
+ }
+ia64_addr_area;
+
+static GTY(()) tree small_ident1;
+static GTY(()) tree small_ident2;
+
+static void
+init_idents (void)
+{
+ if (small_ident1 == 0)
+ {
+ small_ident1 = get_identifier ("small");
+ small_ident2 = get_identifier ("__small__");
+ }
+}
+
+/* Retrieve the address area that has been chosen for the given decl. */
+
+static ia64_addr_area
+ia64_get_addr_area (tree decl)
+{
+ tree model_attr;
+
+ model_attr = lookup_attribute ("model", DECL_ATTRIBUTES (decl));
+ if (model_attr)
+ {
+ tree id;
+
+ init_idents ();
+ id = TREE_VALUE (TREE_VALUE (model_attr));
+ if (id == small_ident1 || id == small_ident2)
+ return ADDR_AREA_SMALL;
+ }
+ return ADDR_AREA_NORMAL;
+}
+
+static tree
+ia64_handle_model_attribute (tree *node, tree name, tree args, int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+{
+ ia64_addr_area addr_area = ADDR_AREA_NORMAL;
+ ia64_addr_area area;
+ tree arg, decl = *node;
+
+ init_idents ();
+ arg = TREE_VALUE (args);
+ if (arg == small_ident1 || arg == small_ident2)
+ {
+ addr_area = ADDR_AREA_SMALL;
+ }
+ else
+ {
+ warning ("invalid argument of `%s' attribute",
+ IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ }
+
+ switch (TREE_CODE (decl))
+ {
+ case VAR_DECL:
+ if ((DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl))
+ == FUNCTION_DECL)
+ && !TREE_STATIC (decl))
+ {
+ error ("%Jan address area attribute cannot be specified for "
+ "local variables", decl, decl);
+ *no_add_attrs = true;
+ }
+ area = ia64_get_addr_area (decl);
+ if (area != ADDR_AREA_NORMAL && addr_area != area)
+ {
+ error ("%Jaddress area of '%s' conflicts with previous "
+ "declaration", decl, decl);
+ *no_add_attrs = true;
+ }
+ break;
+
+ case FUNCTION_DECL:
+ error ("%Jaddress area attribute cannot be specified for functions",
+ decl, decl);
+ *no_add_attrs = true;
+ break;
+
+ default:
+ warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+ *no_add_attrs = true;
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+static void
+ia64_encode_addr_area (tree decl, rtx symbol)
+{
+ int flags;
+
+ flags = SYMBOL_REF_FLAGS (symbol);
+ switch (ia64_get_addr_area (decl))
+ {
+ case ADDR_AREA_NORMAL: break;
+ case ADDR_AREA_SMALL: flags |= SYMBOL_FLAG_SMALL_ADDR; break;
+ default: abort ();
+ }
+ SYMBOL_REF_FLAGS (symbol) = flags;
+}
+
+static void
+ia64_encode_section_info (tree decl, rtx rtl, int first)
+{
+ default_encode_section_info (decl, rtl, first);
+
+ /* Careful not to prod global register variables. */
+ if (TREE_CODE (decl) == VAR_DECL
+ && GET_CODE (DECL_RTL (decl)) == MEM
+ && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF
+ && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
+ ia64_encode_addr_area (decl, XEXP (rtl, 0));
+}
+
/* Return 1 if the operands of a move are ok. */
int
-ia64_move_ok (dst, src)
- rtx dst, src;
+ia64_move_ok (rtx dst, rtx src)
{
/* If we're under init_recog_no_volatile, we'll not be able to use
memory_operand. So check the code directly and don't worry about
@@ -1012,27 +1113,18 @@ ia64_move_ok (dst, src)
return GET_CODE (src) == CONST_DOUBLE && CONST_DOUBLE_OK_FOR_G (src);
}
-/* Return 0 if we are doing C++ code. This optimization fails with
- C++ because of GNAT c++/6685. */
-
int
-addp4_optimize_ok (op1, op2)
- rtx op1, op2;
+addp4_optimize_ok (rtx op1, rtx op2)
{
-
- if (!strcmp (lang_hooks.name, "GNU C++"))
- return 0;
-
return (basereg_operand (op1, GET_MODE(op1)) !=
basereg_operand (op2, GET_MODE(op2)));
}
-/* Check if OP is a mask suitible for use with SHIFT in a dep.z instruction.
+/* Check if OP is a mask suitable for use with SHIFT in a dep.z instruction.
Return the length of the field, or <= 0 on failure. */
int
-ia64_depz_field_mask (rop, rshift)
- rtx rop, rshift;
+ia64_depz_field_mask (rtx rop, rtx rshift)
{
unsigned HOST_WIDE_INT op = INTVAL (rop);
unsigned HOST_WIDE_INT shift = INTVAL (rshift);
@@ -1045,40 +1137,48 @@ ia64_depz_field_mask (rop, rshift)
}
/* Expand a symbolic constant load. */
-/* ??? Should generalize this, so that we can also support 32 bit pointers. */
void
-ia64_expand_load_address (dest, src, scratch)
- rtx dest, src, scratch;
-{
- rtx temp;
-
- /* The destination could be a MEM during initial rtl generation,
- which isn't a valid destination for the PIC load address patterns. */
- if (! register_operand (dest, DImode))
- if (! scratch || ! register_operand (scratch, DImode))
- temp = gen_reg_rtx (DImode);
- else
- temp = scratch;
- else
- temp = dest;
-
- if (tls_symbolic_operand (src, Pmode))
+ia64_expand_load_address (rtx dest, rtx src)
+{
+ if (tls_symbolic_operand (src, VOIDmode))
+ abort ();
+ if (GET_CODE (dest) != REG)
abort ();
- if (TARGET_AUTO_PIC)
- emit_insn (gen_load_gprel64 (temp, src));
- else if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_FLAG (src))
- emit_insn (gen_load_fptr (temp, src));
- else if ((GET_MODE (src) == Pmode || GET_MODE (src) == ptr_mode)
- && sdata_symbolic_operand (src, VOIDmode))
- emit_insn (gen_load_gprel (temp, src));
- else if (GET_CODE (src) == CONST
- && GET_CODE (XEXP (src, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (src, 0), 1)) == CONST_INT
- && (INTVAL (XEXP (XEXP (src, 0), 1)) & 0x1fff) != 0)
- {
- rtx subtarget = no_new_pseudos ? temp : gen_reg_rtx (DImode);
+ /* ILP32 mode still loads 64-bits of data from the GOT. This avoids
+ having to pointer-extend the value afterward. Other forms of address
+ computation below are also more natural to compute as 64-bit quantities.
+ If we've been given an SImode destination register, change it. */
+ if (GET_MODE (dest) != Pmode)
+ dest = gen_rtx_REG (Pmode, REGNO (dest));
+
+ if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_SMALL_ADDR_P (src))
+ {
+ emit_insn (gen_rtx_SET (VOIDmode, dest, src));
+ return;
+ }
+ else if (TARGET_AUTO_PIC)
+ {
+ emit_insn (gen_load_gprel64 (dest, src));
+ return;
+ }
+ else if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (src))
+ {
+ emit_insn (gen_load_fptr (dest, src));
+ return;
+ }
+ else if (sdata_symbolic_operand (src, VOIDmode))
+ {
+ emit_insn (gen_load_gprel (dest, src));
+ return;
+ }
+
+ if (GET_CODE (src) == CONST
+ && GET_CODE (XEXP (src, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (src, 0), 1)) == CONST_INT
+ && (INTVAL (XEXP (XEXP (src, 0), 1)) & 0x1fff) != 0)
+ {
rtx sym = XEXP (XEXP (src, 0), 0);
HOST_WIDE_INT ofs, hi, lo;
@@ -1088,49 +1188,34 @@ ia64_expand_load_address (dest, src, scratch)
lo = ((ofs & 0x3fff) ^ 0x2000) - 0x2000;
hi = ofs - lo;
- if (! scratch)
- scratch = no_new_pseudos ? subtarget : gen_reg_rtx (DImode);
-
- emit_insn (gen_load_symptr (subtarget, plus_constant (sym, hi),
- scratch));
- emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (lo)));
+ ia64_expand_load_address (dest, plus_constant (sym, hi));
+ emit_insn (gen_adddi3 (dest, dest, GEN_INT (lo)));
}
else
{
- rtx insn;
- if (! scratch)
- scratch = no_new_pseudos ? temp : gen_reg_rtx (DImode);
+ rtx tmp;
- insn = emit_insn (gen_load_symptr (temp, src, scratch));
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (temp) != GET_MODE (src))
- src = convert_memory_address (GET_MODE (temp), src);
-#endif
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, src, REG_NOTES (insn));
- }
+ tmp = gen_rtx_HIGH (Pmode, src);
+ tmp = gen_rtx_PLUS (Pmode, tmp, pic_offset_table_rtx);
+ emit_insn (gen_rtx_SET (VOIDmode, dest, tmp));
- if (temp != dest)
- {
- if (GET_MODE (dest) != GET_MODE (temp))
- temp = convert_to_mode (GET_MODE (dest), temp, 0);
- emit_move_insn (dest, temp);
+ tmp = gen_rtx_LO_SUM (GET_MODE (dest), dest, src);
+ emit_insn (gen_rtx_SET (VOIDmode, dest, tmp));
}
}
static GTY(()) rtx gen_tls_tga;
static rtx
-gen_tls_get_addr ()
+gen_tls_get_addr (void)
{
if (!gen_tls_tga)
- {
- gen_tls_tga = init_one_libfunc ("__tls_get_addr");
- }
+ gen_tls_tga = init_one_libfunc ("__tls_get_addr");
return gen_tls_tga;
}
static GTY(()) rtx thread_pointer_rtx;
static rtx
-gen_thread_pointer ()
+gen_thread_pointer (void)
{
if (!thread_pointer_rtx)
{
@@ -1140,153 +1225,128 @@ gen_thread_pointer ()
return thread_pointer_rtx;
}
-rtx
-ia64_expand_move (op0, op1)
- rtx op0, op1;
+static rtx
+ia64_expand_tls_address (enum tls_model tls_kind, rtx op0, rtx op1)
{
- enum machine_mode mode = GET_MODE (op0);
+ rtx tga_op1, tga_op2, tga_ret, tga_eqv, tmp, insns;
+ rtx orig_op0 = op0;
- if (!reload_in_progress && !reload_completed && !ia64_move_ok (op0, op1))
- op1 = force_reg (mode, op1);
-
- if (mode == Pmode || mode == ptr_mode)
+ switch (tls_kind)
{
- enum tls_model tls_kind;
- if ((tls_kind = tls_symbolic_operand (op1, Pmode)))
- {
- rtx tga_op1, tga_op2, tga_ret, tga_eqv, tmp, insns;
- rtx orig_op0 = op0;
+ case TLS_MODEL_GLOBAL_DYNAMIC:
+ start_sequence ();
- switch (tls_kind)
- {
- case TLS_MODEL_GLOBAL_DYNAMIC:
- start_sequence ();
-
- tga_op1 = gen_reg_rtx (Pmode);
- emit_insn (gen_load_ltoff_dtpmod (tga_op1, op1));
- tga_op1 = gen_rtx_MEM (Pmode, tga_op1);
- RTX_UNCHANGING_P (tga_op1) = 1;
-
- tga_op2 = gen_reg_rtx (Pmode);
- emit_insn (gen_load_ltoff_dtprel (tga_op2, op1));
- tga_op2 = gen_rtx_MEM (Pmode, tga_op2);
- RTX_UNCHANGING_P (tga_op2) = 1;
-
- tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
- LCT_CONST, Pmode, 2, tga_op1,
- Pmode, tga_op2, Pmode);
-
- insns = get_insns ();
- end_sequence ();
-
- if (GET_MODE (op0) != Pmode)
- op0 = tga_ret;
- emit_libcall_block (insns, op0, tga_ret, op1);
- break;
+ tga_op1 = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_ltoff_dtpmod (tga_op1, op1));
+ tga_op1 = gen_rtx_MEM (Pmode, tga_op1);
+ RTX_UNCHANGING_P (tga_op1) = 1;
- case TLS_MODEL_LOCAL_DYNAMIC:
- /* ??? This isn't the completely proper way to do local-dynamic
- If the call to __tls_get_addr is used only by a single symbol,
- then we should (somehow) move the dtprel to the second arg
- to avoid the extra add. */
- start_sequence ();
+ tga_op2 = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_ltoff_dtprel (tga_op2, op1));
+ tga_op2 = gen_rtx_MEM (Pmode, tga_op2);
+ RTX_UNCHANGING_P (tga_op2) = 1;
- tga_op1 = gen_reg_rtx (Pmode);
- emit_insn (gen_load_ltoff_dtpmod (tga_op1, op1));
- tga_op1 = gen_rtx_MEM (Pmode, tga_op1);
- RTX_UNCHANGING_P (tga_op1) = 1;
+ tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
+ LCT_CONST, Pmode, 2, tga_op1,
+ Pmode, tga_op2, Pmode);
- tga_op2 = const0_rtx;
+ insns = get_insns ();
+ end_sequence ();
- tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
- LCT_CONST, Pmode, 2, tga_op1,
- Pmode, tga_op2, Pmode);
+ if (GET_MODE (op0) != Pmode)
+ op0 = tga_ret;
+ emit_libcall_block (insns, op0, tga_ret, op1);
+ break;
- insns = get_insns ();
- end_sequence ();
+ case TLS_MODEL_LOCAL_DYNAMIC:
+ /* ??? This isn't the completely proper way to do local-dynamic
+ If the call to __tls_get_addr is used only by a single symbol,
+ then we should (somehow) move the dtprel to the second arg
+ to avoid the extra add. */
+ start_sequence ();
- tga_eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
- UNSPEC_LD_BASE);
- tmp = gen_reg_rtx (Pmode);
- emit_libcall_block (insns, tmp, tga_ret, tga_eqv);
+ tga_op1 = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_ltoff_dtpmod (tga_op1, op1));
+ tga_op1 = gen_rtx_MEM (Pmode, tga_op1);
+ RTX_UNCHANGING_P (tga_op1) = 1;
- if (!register_operand (op0, Pmode))
- op0 = gen_reg_rtx (Pmode);
- if (TARGET_TLS64)
- {
- emit_insn (gen_load_dtprel (op0, op1));
- emit_insn (gen_adddi3 (op0, tmp, op0));
- }
- else
- emit_insn (gen_add_dtprel (op0, tmp, op1));
- break;
+ tga_op2 = const0_rtx;
- case TLS_MODEL_INITIAL_EXEC:
- tmp = gen_reg_rtx (Pmode);
- emit_insn (gen_load_ltoff_tprel (tmp, op1));
- tmp = gen_rtx_MEM (Pmode, tmp);
- RTX_UNCHANGING_P (tmp) = 1;
- tmp = force_reg (Pmode, tmp);
+ tga_ret = emit_library_call_value (gen_tls_get_addr (), NULL_RTX,
+ LCT_CONST, Pmode, 2, tga_op1,
+ Pmode, tga_op2, Pmode);
- if (!register_operand (op0, Pmode))
- op0 = gen_reg_rtx (Pmode);
- emit_insn (gen_adddi3 (op0, tmp, gen_thread_pointer ()));
- break;
+ insns = get_insns ();
+ end_sequence ();
- case TLS_MODEL_LOCAL_EXEC:
- if (!register_operand (op0, Pmode))
- op0 = gen_reg_rtx (Pmode);
- if (TARGET_TLS64)
- {
- emit_insn (gen_load_tprel (op0, op1));
- emit_insn (gen_adddi3 (op0, gen_thread_pointer (), op0));
- }
- else
- emit_insn (gen_add_tprel (op0, gen_thread_pointer (), op1));
- break;
+ tga_eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_LD_BASE);
+ tmp = gen_reg_rtx (Pmode);
+ emit_libcall_block (insns, tmp, tga_ret, tga_eqv);
- default:
- abort ();
- }
+ if (!register_operand (op0, Pmode))
+ op0 = gen_reg_rtx (Pmode);
+ if (TARGET_TLS64)
+ {
+ emit_insn (gen_load_dtprel (op0, op1));
+ emit_insn (gen_adddi3 (op0, tmp, op0));
+ }
+ else
+ emit_insn (gen_add_dtprel (op0, tmp, op1));
+ break;
- if (orig_op0 == op0)
- return NULL_RTX;
- if (GET_MODE (orig_op0) == Pmode)
- return op0;
- return gen_lowpart (GET_MODE (orig_op0), op0);
+ case TLS_MODEL_INITIAL_EXEC:
+ tmp = gen_reg_rtx (Pmode);
+ emit_insn (gen_load_ltoff_tprel (tmp, op1));
+ tmp = gen_rtx_MEM (Pmode, tmp);
+ RTX_UNCHANGING_P (tmp) = 1;
+ tmp = force_reg (Pmode, tmp);
+
+ if (!register_operand (op0, Pmode))
+ op0 = gen_reg_rtx (Pmode);
+ emit_insn (gen_adddi3 (op0, tmp, gen_thread_pointer ()));
+ break;
+
+ case TLS_MODEL_LOCAL_EXEC:
+ if (!register_operand (op0, Pmode))
+ op0 = gen_reg_rtx (Pmode);
+ if (TARGET_TLS64)
+ {
+ emit_insn (gen_load_tprel (op0, op1));
+ emit_insn (gen_adddi3 (op0, gen_thread_pointer (), op0));
}
- else if (!TARGET_NO_PIC &&
- (symbolic_operand (op1, Pmode) ||
- symbolic_operand (op1, ptr_mode)))
+ else
+ emit_insn (gen_add_tprel (op0, gen_thread_pointer (), op1));
+ break;
+
+ default:
+ abort ();
+ }
+
+ if (orig_op0 == op0)
+ return NULL_RTX;
+ if (GET_MODE (orig_op0) == Pmode)
+ return op0;
+ return gen_lowpart (GET_MODE (orig_op0), op0);
+}
+
+rtx
+ia64_expand_move (rtx op0, rtx op1)
+{
+ enum machine_mode mode = GET_MODE (op0);
+
+ if (!reload_in_progress && !reload_completed && !ia64_move_ok (op0, op1))
+ op1 = force_reg (mode, op1);
+
+ if ((mode == Pmode || mode == ptr_mode) && symbolic_operand (op1, VOIDmode))
+ {
+ enum tls_model tls_kind;
+ if ((tls_kind = tls_symbolic_operand (op1, VOIDmode)))
+ return ia64_expand_tls_address (tls_kind, op0, op1);
+
+ if (!TARGET_NO_PIC && reload_completed)
{
- /* Before optimization starts, delay committing to any particular
- type of PIC address load. If this function gets deferred, we
- may acquire information that changes the value of the
- sdata_symbolic_operand predicate.
-
- But don't delay for function pointers. Loading a function address
- actually loads the address of the descriptor not the function.
- If we represent these as SYMBOL_REFs, then they get cse'd with
- calls, and we end up with calls to the descriptor address instead
- of calls to the function address. Functions are not candidates
- for sdata anyways.
-
- Don't delay for LABEL_REF because the splitter loses REG_LABEL
- notes. Don't delay for pool addresses on general principals;
- they'll never become non-local behind our back. */
-
- if (rtx_equal_function_value_matters
- && GET_CODE (op1) != LABEL_REF
- && ! (GET_CODE (op1) == SYMBOL_REF
- && (SYMBOL_REF_FLAG (op1)
- || CONSTANT_POOL_ADDRESS_P (op1)
- || STRING_POOL_ADDRESS_P (op1))))
- if (GET_MODE (op1) == DImode)
- emit_insn (gen_movdi_symbolic (op0, op1));
- else
- emit_insn (gen_movsi_symbolic (op0, op1));
- else
- ia64_expand_load_address (op0, op1, NULL_RTX);
+ ia64_expand_load_address (op0, op1);
return NULL_RTX;
}
}
@@ -1294,102 +1354,272 @@ ia64_expand_move (op0, op1)
return op1;
}
-/* Split a post-reload TImode reference into two DImode components. */
+/* Split a move from OP1 to OP0 conditional on COND. */
-rtx
-ia64_split_timode (out, in, scratch)
- rtx out[2];
- rtx in, scratch;
+void
+ia64_emit_cond_move (rtx op0, rtx op1, rtx cond)
+{
+ rtx insn, first = get_last_insn ();
+
+ emit_move_insn (op0, op1);
+
+ for (insn = get_last_insn (); insn != first; insn = PREV_INSN (insn))
+ if (INSN_P (insn))
+ PATTERN (insn) = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (cond),
+ PATTERN (insn));
+}
+
+/* Split a post-reload TImode or TFmode reference into two DImode
+ components. This is made extra difficult by the fact that we do
+ not get any scratch registers to work with, because reload cannot
+ be prevented from giving us a scratch that overlaps the register
+ pair involved. So instead, when addressing memory, we tweak the
+ pointer register up and back down with POST_INCs. Or up and not
+ back down when we can get away with it.
+
+ REVERSED is true when the loads must be done in reversed order
+ (high word first) for correctness. DEAD is true when the pointer
+ dies with the second insn we generate and therefore the second
+ address must not carry a postmodify.
+
+ May return an insn which is to be emitted after the moves. */
+
+static rtx
+ia64_split_tmode (rtx out[2], rtx in, bool reversed, bool dead)
{
+ rtx fixup = 0;
+
switch (GET_CODE (in))
{
case REG:
- out[0] = gen_rtx_REG (DImode, REGNO (in));
- out[1] = gen_rtx_REG (DImode, REGNO (in) + 1);
- return NULL_RTX;
+ out[reversed] = gen_rtx_REG (DImode, REGNO (in));
+ out[!reversed] = gen_rtx_REG (DImode, REGNO (in) + 1);
+ break;
+
+ case CONST_INT:
+ case CONST_DOUBLE:
+ /* Cannot occur reversed. */
+ if (reversed) abort ();
+
+ if (GET_MODE (in) != TFmode)
+ split_double (in, &out[0], &out[1]);
+ else
+ /* split_double does not understand how to split a TFmode
+ quantity into a pair of DImode constants. */
+ {
+ REAL_VALUE_TYPE r;
+ unsigned HOST_WIDE_INT p[2];
+ long l[4]; /* TFmode is 128 bits */
+
+ REAL_VALUE_FROM_CONST_DOUBLE (r, in);
+ real_to_target (l, &r, TFmode);
+
+ if (FLOAT_WORDS_BIG_ENDIAN)
+ {
+ p[0] = (((unsigned HOST_WIDE_INT) l[0]) << 32) + l[1];
+ p[1] = (((unsigned HOST_WIDE_INT) l[2]) << 32) + l[3];
+ }
+ else
+ {
+ p[0] = (((unsigned HOST_WIDE_INT) l[3]) << 32) + l[2];
+ p[1] = (((unsigned HOST_WIDE_INT) l[1]) << 32) + l[0];
+ }
+ out[0] = GEN_INT (p[0]);
+ out[1] = GEN_INT (p[1]);
+ }
+ break;
case MEM:
{
rtx base = XEXP (in, 0);
+ rtx offset;
switch (GET_CODE (base))
{
case REG:
- out[0] = adjust_address (in, DImode, 0);
- break;
- case POST_MODIFY:
- base = XEXP (base, 0);
- out[0] = adjust_address (in, DImode, 0);
+ if (!reversed)
+ {
+ out[0] = adjust_automodify_address
+ (in, DImode, gen_rtx_POST_INC (Pmode, base), 0);
+ out[1] = adjust_automodify_address
+ (in, DImode, dead ? 0 : gen_rtx_POST_DEC (Pmode, base), 8);
+ }
+ else
+ {
+ /* Reversal requires a pre-increment, which can only
+ be done as a separate insn. */
+ emit_insn (gen_adddi3 (base, base, GEN_INT (8)));
+ out[0] = adjust_automodify_address
+ (in, DImode, gen_rtx_POST_DEC (Pmode, base), 8);
+ out[1] = adjust_address (in, DImode, 0);
+ }
break;
- /* Since we're changing the mode, we need to change to POST_MODIFY
- as well to preserve the size of the increment. Either that or
- do the update in two steps, but we've already got this scratch
- register handy so let's use it. */
case POST_INC:
- base = XEXP (base, 0);
- out[0]
- = change_address (in, DImode,
- gen_rtx_POST_MODIFY
- (Pmode, base, plus_constant (base, 16)));
+ if (reversed || dead) abort ();
+ /* Just do the increment in two steps. */
+ out[0] = adjust_automodify_address (in, DImode, 0, 0);
+ out[1] = adjust_automodify_address (in, DImode, 0, 8);
break;
+
case POST_DEC:
+ if (reversed || dead) abort ();
+ /* Add 8, subtract 24. */
base = XEXP (base, 0);
- out[0]
- = change_address (in, DImode,
- gen_rtx_POST_MODIFY
- (Pmode, base, plus_constant (base, -16)));
+ out[0] = adjust_automodify_address
+ (in, DImode, gen_rtx_POST_INC (Pmode, base), 0);
+ out[1] = adjust_automodify_address
+ (in, DImode,
+ gen_rtx_POST_MODIFY (Pmode, base, plus_constant (base, -24)),
+ 8);
+ break;
+
+ case POST_MODIFY:
+ if (reversed || dead) abort ();
+ /* Extract and adjust the modification. This case is
+ trickier than the others, because we might have an
+ index register, or we might have a combined offset that
+ doesn't fit a signed 9-bit displacement field. We can
+ assume the incoming expression is already legitimate. */
+ offset = XEXP (base, 1);
+ base = XEXP (base, 0);
+
+ out[0] = adjust_automodify_address
+ (in, DImode, gen_rtx_POST_INC (Pmode, base), 0);
+
+ if (GET_CODE (XEXP (offset, 1)) == REG)
+ {
+ /* Can't adjust the postmodify to match. Emit the
+ original, then a separate addition insn. */
+ out[1] = adjust_automodify_address (in, DImode, 0, 8);
+ fixup = gen_adddi3 (base, base, GEN_INT (-8));
+ }
+ else if (GET_CODE (XEXP (offset, 1)) != CONST_INT)
+ abort ();
+ else if (INTVAL (XEXP (offset, 1)) < -256 + 8)
+ {
+ /* Again the postmodify cannot be made to match, but
+ in this case it's more efficient to get rid of the
+ postmodify entirely and fix up with an add insn. */
+ out[1] = adjust_automodify_address (in, DImode, base, 8);
+ fixup = gen_adddi3 (base, base,
+ GEN_INT (INTVAL (XEXP (offset, 1)) - 8));
+ }
+ else
+ {
+ /* Combined offset still fits in the displacement field.
+ (We cannot overflow it at the high end.) */
+ out[1] = adjust_automodify_address
+ (in, DImode,
+ gen_rtx_POST_MODIFY (Pmode, base,
+ gen_rtx_PLUS (Pmode, base,
+ GEN_INT (INTVAL (XEXP (offset, 1)) - 8))),
+ 8);
+ }
break;
+
default:
abort ();
}
-
- if (scratch == NULL_RTX)
- abort ();
- out[1] = change_address (in, DImode, scratch);
- return gen_adddi3 (scratch, base, GEN_INT (8));
+ break;
}
- case CONST_INT:
- case CONST_DOUBLE:
- split_double (in, &out[0], &out[1]);
- return NULL_RTX;
-
default:
abort ();
}
+
+ return fixup;
}
-/* ??? Fixing GR->FR TFmode moves during reload is hard. You need to go
+/* Split a TImode or TFmode move instruction after reload.
+ This is used by *movtf_internal and *movti_internal. */
+void
+ia64_split_tmode_move (rtx operands[])
+{
+ rtx in[2], out[2], insn;
+ rtx fixup[2];
+ bool dead = false;
+ bool reversed = false;
+
+ /* It is possible for reload to decide to overwrite a pointer with
+ the value it points to. In that case we have to do the loads in
+ the appropriate order so that the pointer is not destroyed too
+ early. Also we must not generate a postmodify for that second
+ load, or rws_access_regno will abort. */
+ if (GET_CODE (operands[1]) == MEM
+ && reg_overlap_mentioned_p (operands[0], operands[1]))
+ {
+ rtx base = XEXP (operands[1], 0);
+ while (GET_CODE (base) != REG)
+ base = XEXP (base, 0);
+
+ if (REGNO (base) == REGNO (operands[0]))
+ reversed = true;
+ dead = true;
+ }
+ /* Another reason to do the moves in reversed order is if the first
+ element of the target register pair is also the second element of
+ the source register pair. */
+ if (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG
+ && REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ reversed = true;
+
+ fixup[0] = ia64_split_tmode (in, operands[1], reversed, dead);
+ fixup[1] = ia64_split_tmode (out, operands[0], reversed, dead);
+
+#define MAYBE_ADD_REG_INC_NOTE(INSN, EXP) \
+ if (GET_CODE (EXP) == MEM \
+ && (GET_CODE (XEXP (EXP, 0)) == POST_MODIFY \
+ || GET_CODE (XEXP (EXP, 0)) == POST_INC \
+ || GET_CODE (XEXP (EXP, 0)) == POST_DEC)) \
+ REG_NOTES (INSN) = gen_rtx_EXPR_LIST (REG_INC, \
+ XEXP (XEXP (EXP, 0), 0), \
+ REG_NOTES (INSN))
+
+ insn = emit_insn (gen_rtx_SET (VOIDmode, out[0], in[0]));
+ MAYBE_ADD_REG_INC_NOTE (insn, in[0]);
+ MAYBE_ADD_REG_INC_NOTE (insn, out[0]);
+
+ insn = emit_insn (gen_rtx_SET (VOIDmode, out[1], in[1]));
+ MAYBE_ADD_REG_INC_NOTE (insn, in[1]);
+ MAYBE_ADD_REG_INC_NOTE (insn, out[1]);
+
+ if (fixup[0])
+ emit_insn (fixup[0]);
+ if (fixup[1])
+ emit_insn (fixup[1]);
+
+#undef MAYBE_ADD_REG_INC_NOTE
+}
+
+/* ??? Fixing GR->FR XFmode moves during reload is hard. You need to go
through memory plus an extra GR scratch register. Except that you can
either get the first from SECONDARY_MEMORY_NEEDED or the second from
SECONDARY_RELOAD_CLASS, but not both.
We got into problems in the first place by allowing a construct like
- (subreg:TF (reg:TI)), which we got from a union containing a long double.
+ (subreg:XF (reg:TI)), which we got from a union containing a long double.
This solution attempts to prevent this situation from occurring. When
we see something like the above, we spill the inner register to memory. */
rtx
-spill_tfmode_operand (in, force)
- rtx in;
- int force;
+spill_xfmode_operand (rtx in, int force)
{
if (GET_CODE (in) == SUBREG
&& GET_MODE (SUBREG_REG (in)) == TImode
&& GET_CODE (SUBREG_REG (in)) == REG)
{
- rtx mem = gen_mem_addressof (SUBREG_REG (in), NULL_TREE, true);
- return gen_rtx_MEM (TFmode, copy_to_reg (XEXP (mem, 0)));
+ rtx mem = gen_mem_addressof (SUBREG_REG (in), NULL_TREE, /*rescan=*/true);
+ return gen_rtx_MEM (XFmode, copy_to_reg (XEXP (mem, 0)));
}
else if (force && GET_CODE (in) == REG)
{
- rtx mem = gen_mem_addressof (in, NULL_TREE, true);
- return gen_rtx_MEM (TFmode, copy_to_reg (XEXP (mem, 0)));
+ rtx mem = gen_mem_addressof (in, NULL_TREE, /*rescan=*/true);
+ return gen_rtx_MEM (XFmode, copy_to_reg (XEXP (mem, 0)));
}
else if (GET_CODE (in) == MEM
&& GET_CODE (XEXP (in, 0)) == ADDRESSOF)
- return change_address (in, TFmode, copy_to_reg (XEXP (in, 0)));
+ return change_address (in, XFmode, copy_to_reg (XEXP (in, 0)));
else
return in;
}
@@ -1397,10 +1627,10 @@ spill_tfmode_operand (in, force)
/* Emit comparison instruction if necessary, returning the expression
that holds the compare result in the proper mode. */
+static GTY(()) rtx cmptf_libfunc;
+
rtx
-ia64_expand_compare (code, mode)
- enum rtx_code code;
- enum machine_mode mode;
+ia64_expand_compare (enum rtx_code code, enum machine_mode mode)
{
rtx op0 = ia64_compare_op0, op1 = ia64_compare_op1;
rtx cmp;
@@ -1414,6 +1644,59 @@ ia64_expand_compare (code, mode)
else
abort ();
}
+ /* 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)
+ {
+ enum qfcmp_magic {
+ QCMP_INV = 1, /* Raise FP_INVALID on SNaN as a side effect. */
+ QCMP_UNORD = 2,
+ QCMP_EQ = 4,
+ QCMP_LT = 8,
+ QCMP_GT = 16
+ } magic;
+ enum rtx_code ncode;
+ rtx ret, insns;
+ if (GET_MODE (op1) != TFmode)
+ abort ();
+ switch (code)
+ {
+ /* 1 = equal, 0 = not equal. Equality operators do
+ not raise FP_INVALID when given an SNaN operand. */
+ case EQ: magic = QCMP_EQ; ncode = NE; break;
+ case NE: magic = QCMP_EQ; ncode = EQ; break;
+ /* isunordered() from C99. */
+ case UNORDERED: magic = QCMP_UNORD; ncode = NE; break;
+ /* Relational operators raise FP_INVALID when given
+ an SNaN operand. */
+ case LT: magic = QCMP_LT |QCMP_INV; ncode = NE; break;
+ case LE: magic = QCMP_LT|QCMP_EQ|QCMP_INV; ncode = NE; break;
+ case GT: magic = QCMP_GT |QCMP_INV; ncode = NE; break;
+ case GE: magic = QCMP_GT|QCMP_EQ|QCMP_INV; ncode = NE; break;
+ /* FUTURE: Implement UNEQ, UNLT, UNLE, UNGT, UNGE, LTGT.
+ Expanders for buneq etc. weuld have to be added to ia64.md
+ for this to be useful. */
+ default: abort ();
+ }
+
+ start_sequence ();
+
+ ret = emit_library_call_value (cmptf_libfunc, 0, LCT_CONST, DImode, 3,
+ op0, TFmode, op1, TFmode,
+ GEN_INT (magic), DImode);
+ cmp = gen_reg_rtx (BImode);
+ emit_insn (gen_rtx_SET (VOIDmode, cmp,
+ gen_rtx_fmt_ee (ncode, BImode,
+ ret, const0_rtx)));
+
+ insns = get_insns ();
+ end_sequence ();
+
+ emit_libcall_block (insns, cmp, cmp,
+ gen_rtx_fmt_ee (code, BImode, op0, op1));
+ code = NE;
+ }
else
{
cmp = gen_reg_rtx (BImode);
@@ -1426,16 +1709,15 @@ ia64_expand_compare (code, mode)
}
/* Emit the appropriate sequence for a call. */
+
void
-ia64_expand_call (retval, addr, nextarg, sibcall_p)
- rtx retval;
- rtx addr;
- rtx nextarg ATTRIBUTE_UNUSED;
- int sibcall_p;
+ia64_expand_call (rtx retval, rtx addr, rtx nextarg ATTRIBUTE_UNUSED,
+ int sibcall_p)
{
rtx insn, b0;
addr = XEXP (addr, 0);
+ addr = convert_memory_address (DImode, addr);
b0 = gen_rtx_REG (DImode, R_BR (0));
/* ??? Should do this for functions known to bind local too. */
@@ -1465,8 +1747,9 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p)
if (sibcall_p)
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), b0);
}
+
void
-ia64_reload_gp ()
+ia64_reload_gp (void)
{
rtx tmp;
@@ -1506,10 +1789,8 @@ ia64_reload_gp ()
}
void
-ia64_split_call (retval, addr, retaddr, scratch_r, scratch_b,
- noreturn_p, sibcall_p)
- rtx retval, addr, retaddr, scratch_r, scratch_b;
- int noreturn_p, sibcall_p;
+ia64_split_call (rtx retval, rtx addr, rtx retaddr, rtx scratch_r,
+ rtx scratch_b, int noreturn_p, int sibcall_p)
{
rtx insn;
bool is_desc = false;
@@ -1522,8 +1803,8 @@ ia64_split_call (retval, addr, retaddr, scratch_r, scratch_b,
bool addr_dead_p;
/* ??? We are currently constrained to *not* use peep2, because
- we can legitimiately change the global lifetime of the GP
- (in the form of killing where previously live). This is
+ we can legitimately change the global lifetime of the GP
+ (in the form of killing where previously live). This is
because a call through a descriptor doesn't use the previous
value of the GP, while a direct call does, and we do not
commit to either form until the split here.
@@ -1571,9 +1852,15 @@ ia64_split_call (retval, addr, retaddr, scratch_r, scratch_b,
/* Begin the assembly file. */
+static void
+ia64_file_start (void)
+{
+ default_file_start ();
+ emit_safe_across_calls ();
+}
+
void
-emit_safe_across_calls (f)
- FILE *f;
+emit_safe_across_calls (void)
{
unsigned int rs, re;
int out_state;
@@ -1590,19 +1877,19 @@ emit_safe_across_calls (f)
continue;
if (out_state == 0)
{
- fputs ("\t.pred.safe_across_calls ", f);
+ fputs ("\t.pred.safe_across_calls ", asm_out_file);
out_state = 1;
}
else
- fputc (',', f);
+ fputc (',', asm_out_file);
if (re == rs + 1)
- fprintf (f, "p%u", rs);
+ fprintf (asm_out_file, "p%u", rs);
else
- fprintf (f, "p%u-p%u", rs, re - 1);
+ fprintf (asm_out_file, "p%u-p%u", rs, re - 1);
rs = re + 1;
}
if (out_state)
- fputc ('\n', f);
+ fputc ('\n', asm_out_file);
}
/* Helper function for ia64_compute_frame_size: find an appropriate general
@@ -1611,8 +1898,7 @@ emit_safe_across_calls (f)
TRY_LOCALS is true if we should attempt to locate a local regnum. */
static int
-find_gr_spill (try_locals)
- int try_locals;
+find_gr_spill (int try_locals)
{
int regno;
@@ -1661,7 +1947,7 @@ find_gr_spill (try_locals)
static int last_scratch_gr_reg;
static int
-next_scratch_gr_reg ()
+next_scratch_gr_reg (void)
{
int i, regno;
@@ -1686,9 +1972,7 @@ next_scratch_gr_reg ()
diddle_return_value. Mark REG in current_frame_info.gr_used_mask. */
static void
-mark_reg_gr_used_mask (reg, data)
- rtx reg;
- void *data ATTRIBUTE_UNUSED;
+mark_reg_gr_used_mask (rtx reg, void *data ATTRIBUTE_UNUSED)
{
unsigned int regno = REGNO (reg);
if (regno < 32)
@@ -1704,8 +1988,7 @@ mark_reg_gr_used_mask (reg, data)
needed for local variables. */
static void
-ia64_compute_frame_size (size)
- HOST_WIDE_INT size;
+ia64_compute_frame_size (HOST_WIDE_INT size)
{
HOST_WIDE_INT total_size;
HOST_WIDE_INT spill_size = 0;
@@ -1767,7 +2050,7 @@ ia64_compute_frame_size (size)
i = regno - OUT_REG (0) + 1;
/* When -p profiling, we need one output register for the mcount argument.
- Likwise for -a profiling for the bb_init_func argument. For -ax
+ Likewise for -a profiling for the bb_init_func argument. For -ax
profiling, we need two output registers for the two bb_init_trace_func
arguments. */
if (current_function_profile)
@@ -1778,7 +2061,7 @@ ia64_compute_frame_size (size)
current_frame_info.n_rotate_regs = 0;
/* Discover which registers need spilling, and how much room that
- will take. Begin with floating point and general registers,
+ will take. Begin with floating point and general registers,
which will always wind up on the stack. */
for (regno = FR_REG (2); regno <= FR_REG (127); regno++)
@@ -1809,7 +2092,7 @@ ia64_compute_frame_size (size)
/* Now come all special registers that might get saved in other
general registers. */
-
+
if (frame_pointer_needed)
{
current_frame_info.reg_fp = find_gr_spill (1);
@@ -1971,8 +2254,7 @@ ia64_compute_frame_size (size)
/* Compute the initial difference between the specified pair of registers. */
HOST_WIDE_INT
-ia64_initial_elimination_offset (from, to)
- int from, to;
+ia64_initial_elimination_offset (int from, int to)
{
HOST_WIDE_INT offset;
@@ -2044,10 +2326,7 @@ struct spill_fill_data
static struct spill_fill_data spill_fill_data;
static void
-setup_spill_pointers (n_spills, init_reg, cfa_off)
- int n_spills;
- rtx init_reg;
- HOST_WIDE_INT cfa_off;
+setup_spill_pointers (int n_spills, rtx init_reg, HOST_WIDE_INT cfa_off)
{
int i;
@@ -2073,15 +2352,13 @@ setup_spill_pointers (n_spills, init_reg, cfa_off)
}
static void
-finish_spill_pointers ()
+finish_spill_pointers (void)
{
current_frame_info.gr_used_mask = spill_fill_data.save_gr_used_mask;
}
static rtx
-spill_restore_mem (reg, cfa_off)
- rtx reg;
- HOST_WIDE_INT cfa_off;
+spill_restore_mem (rtx reg, HOST_WIDE_INT cfa_off)
{
int iter = spill_fill_data.next_iter;
HOST_WIDE_INT disp = spill_fill_data.prev_off[iter] - cfa_off;
@@ -2194,10 +2471,8 @@ spill_restore_mem (reg, cfa_off)
}
static void
-do_spill (move_fn, reg, cfa_off, frame_reg)
- rtx (*move_fn) PARAMS ((rtx, rtx, rtx));
- rtx reg, frame_reg;
- HOST_WIDE_INT cfa_off;
+do_spill (rtx (*move_fn) (rtx, rtx, rtx), rtx reg, HOST_WIDE_INT cfa_off,
+ rtx frame_reg)
{
int iter = spill_fill_data.next_iter;
rtx mem, insn;
@@ -2213,7 +2488,7 @@ do_spill (move_fn, reg, cfa_off, frame_reg)
RTX_FRAME_RELATED_P (insn) = 1;
- /* Don't even pretend that the unwind code can intuit its way
+ /* Don't even pretend that the unwind code can intuit its way
through a pair of interleaved post_modify iterators. Just
provide the correct answer. */
@@ -2239,10 +2514,7 @@ do_spill (move_fn, reg, cfa_off, frame_reg)
}
static void
-do_restore (move_fn, reg, cfa_off)
- rtx (*move_fn) PARAMS ((rtx, rtx, rtx));
- rtx reg;
- HOST_WIDE_INT cfa_off;
+do_restore (rtx (*move_fn) (rtx, rtx, rtx), rtx reg, HOST_WIDE_INT cfa_off)
{
int iter = spill_fill_data.next_iter;
rtx insn;
@@ -2254,28 +2526,22 @@ do_restore (move_fn, reg, cfa_off)
/* Wrapper functions that discards the CONST_INT spill offset. These
exist so that we can give gr_spill/gr_fill the offset they need and
- use a consistant function interface. */
+ use a consistent function interface. */
static rtx
-gen_movdi_x (dest, src, offset)
- rtx dest, src;
- rtx offset ATTRIBUTE_UNUSED;
+gen_movdi_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
{
return gen_movdi (dest, src);
}
static rtx
-gen_fr_spill_x (dest, src, offset)
- rtx dest, src;
- rtx offset ATTRIBUTE_UNUSED;
+gen_fr_spill_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
{
return gen_fr_spill (dest, src);
}
static rtx
-gen_fr_restore_x (dest, src, offset)
- rtx dest, src;
- rtx offset ATTRIBUTE_UNUSED;
+gen_fr_restore_x (rtx dest, rtx src, rtx offset ATTRIBUTE_UNUSED)
{
return gen_fr_restore (dest, src);
}
@@ -2303,7 +2569,7 @@ gen_fr_restore_x (dest, src, offset)
adds instruction. */
void
-ia64_expand_prologue ()
+ia64_expand_prologue (void)
{
rtx insn, ar_pfs_save_reg, ar_unat_save_reg;
int i, epilogue_p, regno, alt_regno, cfa_off, n_varargs;
@@ -2382,7 +2648,7 @@ ia64_expand_prologue ()
regno = next_scratch_gr_reg ();
ar_pfs_save_reg = gen_rtx_REG (DImode, regno);
- insn = emit_insn (gen_alloc (ar_pfs_save_reg,
+ insn = emit_insn (gen_alloc (ar_pfs_save_reg,
GEN_INT (current_frame_info.n_input_regs),
GEN_INT (current_frame_info.n_local_regs),
GEN_INT (current_frame_info.n_output_regs),
@@ -2412,7 +2678,7 @@ ia64_expand_prologue ()
else
{
regno = next_scratch_gr_reg ();
- offset = gen_rtx_REG (DImode, regno);
+ offset = gen_rtx_REG (DImode, regno);
emit_move_insn (offset, frame_size_rtx);
}
@@ -2630,7 +2896,7 @@ ia64_expand_prologue ()
{
if (cfa_off & 15)
abort ();
- reg = gen_rtx_REG (TFmode, regno);
+ reg = gen_rtx_REG (XFmode, regno);
do_spill (gen_fr_spill_x, reg, cfa_off, reg);
cfa_off -= 16;
}
@@ -2649,8 +2915,7 @@ ia64_expand_prologue ()
insn to prevent such scheduling. */
void
-ia64_expand_epilogue (sibcall_p)
- int sibcall_p;
+ia64_expand_epilogue (int sibcall_p)
{
rtx insn, reg, alt_reg, ar_unat_save_reg;
int regno, alt_regno, cfa_off;
@@ -2664,7 +2929,7 @@ ia64_expand_epilogue (sibcall_p)
setup_spill_pointers (current_frame_info.n_spilled,
hard_frame_pointer_rtx, 0);
else
- setup_spill_pointers (current_frame_info.n_spilled, stack_pointer_rtx,
+ setup_spill_pointers (current_frame_info.n_spilled, stack_pointer_rtx,
current_frame_info.total_size);
if (current_frame_info.total_size != 0)
@@ -2716,7 +2981,7 @@ ia64_expand_epilogue (sibcall_p)
}
else
ar_unat_save_reg = NULL_RTX;
-
+
if (current_frame_info.reg_save_ar_pfs != 0)
{
alt_reg = gen_rtx_REG (DImode, current_frame_info.reg_save_ar_pfs);
@@ -2766,7 +3031,7 @@ ia64_expand_epilogue (sibcall_p)
do_restore (gen_gr_restore, reg, cfa_off);
cfa_off -= 8;
}
-
+
/* Restore the branch registers. Handle B0 specially, as it may
have gotten stored in some GR register. */
if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
@@ -2783,7 +3048,7 @@ ia64_expand_epilogue (sibcall_p)
reg = gen_rtx_REG (DImode, BR_REG (0));
emit_move_insn (reg, alt_reg);
}
-
+
for (regno = BR_REG (1); regno <= BR_REG (7); ++regno)
if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
{
@@ -2801,7 +3066,7 @@ ia64_expand_epilogue (sibcall_p)
{
if (cfa_off & 15)
abort ();
- reg = gen_rtx_REG (TFmode, regno);
+ reg = gen_rtx_REG (XFmode, regno);
do_restore (gen_fr_restore_x, reg, cfa_off);
cfa_off -= 16;
}
@@ -2867,17 +3132,17 @@ ia64_expand_epilogue (sibcall_p)
if (cfun->machine->ia64_eh_epilogue_bsp)
emit_insn (gen_set_bsp (cfun->machine->ia64_eh_epilogue_bsp));
-
+
if (! sibcall_p)
emit_jump_insn (gen_return_internal (gen_rtx_REG (DImode, BR_REG (0))));
else
{
int fp = GR_REG (2);
/* We need a throw away register here, r0 and r1 are reserved, so r2 is the
- first available call clobbered register. If there was a frame_pointer
- register, we may have swapped the names of r2 and HARD_FRAME_POINTER_REGNUM,
+ first available call clobbered register. If there was a frame_pointer
+ register, we may have swapped the names of r2 and HARD_FRAME_POINTER_REGNUM,
so we have to make sure we're using the string "r2" when emitting
- the register name for the assmbler. */
+ the register name for the assembler. */
if (current_frame_info.reg_fp && current_frame_info.reg_fp == GR_REG (2))
fp = HARD_FRAME_POINTER_REGNUM;
@@ -2900,7 +3165,7 @@ ia64_expand_epilogue (sibcall_p)
function. */
int
-ia64_direct_return ()
+ia64_direct_return (void)
{
if (reload_completed && ! frame_pointer_needed)
{
@@ -2921,9 +3186,7 @@ ia64_direct_return ()
during early compilation. */
rtx
-ia64_return_addr_rtx (count, frame)
- HOST_WIDE_INT count;
- rtx frame ATTRIBUTE_UNUSED;
+ia64_return_addr_rtx (HOST_WIDE_INT count, rtx frame ATTRIBUTE_UNUSED)
{
if (count != 0)
return NULL;
@@ -2934,8 +3197,7 @@ ia64_return_addr_rtx (count, frame)
address is saved. */
void
-ia64_split_return_addr_rtx (dest)
- rtx dest;
+ia64_split_return_addr_rtx (rtx dest)
{
rtx src;
@@ -2984,9 +3246,7 @@ ia64_split_return_addr_rtx (dest)
}
int
-ia64_hard_regno_rename_ok (from, to)
- int from;
- int to;
+ia64_hard_regno_rename_ok (int from, int to)
{
/* Don't clobber any of the registers we reserved for the prologue. */
if (to == current_frame_info.reg_fp
@@ -3020,18 +3280,15 @@ ia64_hard_regno_rename_ok (from, to)
aligned objects and detect the cases when @fptr is needed. */
static bool
-ia64_assemble_integer (x, size, aligned_p)
- rtx x;
- unsigned int size;
- int aligned_p;
+ia64_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
- if (size == (TARGET_ILP32 ? 4 : 8)
+ if (size == POINTER_SIZE / BITS_PER_UNIT
&& aligned_p
&& !(TARGET_NO_PIC || TARGET_AUTO_PIC)
&& GET_CODE (x) == SYMBOL_REF
- && SYMBOL_REF_FLAG (x))
+ && SYMBOL_REF_FUNCTION_P (x))
{
- if (TARGET_ILP32)
+ if (POINTER_SIZE == 32)
fputs ("\tdata4\t@fptr(", asm_out_file);
else
fputs ("\tdata8\t@fptr(", asm_out_file);
@@ -3045,9 +3302,7 @@ ia64_assemble_integer (x, size, aligned_p)
/* Emit the function prologue. */
static void
-ia64_output_function_prologue (file, size)
- FILE *file;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+ia64_output_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
int mask, grsave, grsave_prev;
@@ -3097,7 +3352,7 @@ ia64_output_function_prologue (file, size)
grsave = current_frame_info.reg_save_pr;
}
- if (mask)
+ if (mask && TARGET_GNU_AS)
fprintf (file, "\t.prologue %d, %d\n", mask,
ia64_dbx_register_number (grsave));
else
@@ -3114,8 +3369,7 @@ ia64_output_function_prologue (file, size)
/* Emit the .body directive at the scheduled end of the prologue. */
static void
-ia64_output_function_end_prologue (file)
- FILE *file;
+ia64_output_function_end_prologue (FILE *file)
{
if (!flag_unwind_tables && (!flag_exceptions || USING_SJLJ_EXCEPTIONS))
return;
@@ -3126,9 +3380,8 @@ ia64_output_function_end_prologue (file)
/* Emit the function epilogue. */
static void
-ia64_output_function_epilogue (file, size)
- FILE *file ATTRIBUTE_UNUSED;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+ia64_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
int i;
@@ -3153,8 +3406,7 @@ ia64_output_function_epilogue (file, size)
}
int
-ia64_dbx_register_number (regno)
- int regno;
+ia64_dbx_register_number (int regno)
{
/* In ia64_expand_prologue we quite literally renamed the frame pointer
from its home at loc79 to something inside the register frame. We
@@ -3179,11 +3431,24 @@ ia64_dbx_register_number (regno)
}
void
-ia64_initialize_trampoline (addr, fnaddr, static_chain)
- rtx addr, fnaddr, static_chain;
+ia64_initialize_trampoline (rtx addr, rtx fnaddr, rtx static_chain)
{
rtx addr_reg, eight = GEN_INT (8);
+ /* The Intel assembler requires that the global __ia64_trampoline symbol
+ be declared explicitly */
+ if (!TARGET_GNU_AS)
+ {
+ static bool declared_ia64_trampoline = false;
+
+ if (!declared_ia64_trampoline)
+ {
+ declared_ia64_trampoline = true;
+ (*targetm.asm_out.globalize_label) (asm_out_file,
+ "__ia64_trampoline");
+ }
+ }
+
/* Load up our iterator. */
addr_reg = gen_reg_rtx (Pmode);
emit_move_insn (addr_reg, addr);
@@ -3212,12 +3477,9 @@ ia64_initialize_trampoline (addr, fnaddr, static_chain)
We generate the actual spill instructions during prologue generation. */
void
-ia64_setup_incoming_varargs (cum, int_mode, type, pretend_size, second_time)
- CUMULATIVE_ARGS cum;
- int int_mode;
- tree type;
- int * pretend_size;
- int second_time ATTRIBUTE_UNUSED;
+ia64_setup_incoming_varargs (CUMULATIVE_ARGS cum, int int_mode, tree type,
+ int * pretend_size,
+ int second_time ATTRIBUTE_UNUSED)
{
/* Skip the current argument. */
ia64_function_arg_advance (&cum, int_mode, type, 1);
@@ -3239,9 +3501,7 @@ ia64_setup_incoming_varargs (cum, int_mode, type, pretend_size, second_time)
SFmode). 128-bit quad-precision floats are excluded. */
static enum machine_mode
-hfa_element_mode (type, nested)
- tree type;
- int nested;
+hfa_element_mode (tree type, int nested)
{
enum machine_mode element_mode = VOIDmode;
enum machine_mode mode;
@@ -3263,16 +3523,15 @@ hfa_element_mode (type, nested)
types though. */
case COMPLEX_TYPE:
if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_FLOAT
- && (TYPE_MODE (type) != TCmode || INTEL_EXTENDED_IEEE_FORMAT))
- return mode_for_size (GET_MODE_UNIT_SIZE (TYPE_MODE (type))
- * BITS_PER_UNIT, MODE_FLOAT, 0);
+ && TYPE_MODE (type) != TCmode)
+ return GET_MODE_INNER (TYPE_MODE (type));
else
return VOIDmode;
case REAL_TYPE:
/* We want to return VOIDmode for raw REAL_TYPEs, but the actual
mode if this is contained within an aggregate. */
- if (nested && (TYPE_MODE (type) != TFmode || INTEL_EXTENDED_IEEE_FORMAT))
+ if (nested && TYPE_MODE (type) != TFmode)
return TYPE_MODE (type);
else
return VOIDmode;
@@ -3315,40 +3574,62 @@ hfa_element_mode (type, nested)
return VOIDmode;
}
+/* Return the number of words required to hold a quantity of TYPE and MODE
+ when passed as an argument. */
+static int
+ia64_function_arg_words (tree type, enum machine_mode mode)
+{
+ int words;
+
+ if (mode == BLKmode)
+ words = int_size_in_bytes (type);
+ else
+ words = GET_MODE_SIZE (mode);
+
+ return (words + UNITS_PER_WORD - 1) / UNITS_PER_WORD; /* round up */
+}
+
+/* Return the number of registers that should be skipped so the current
+ argument (described by TYPE and WORDS) will be properly aligned.
+
+ Integer and float arguments larger than 8 bytes start at the next
+ even boundary. Aggregates larger than 8 bytes start at the next
+ even boundary if the aggregate has 16 byte alignment. Note that
+ in the 32-bit ABI, TImode and TFmode have only 8-byte alignment
+ but are still to be aligned in registers.
+
+ ??? The ABI does not specify how to handle aggregates with
+ alignment from 9 to 15 bytes, or greater than 16. We handle them
+ all as if they had 16 byte alignment. Such aggregates can occur
+ only if gcc extensions are used. */
+static int
+ia64_function_arg_offset (CUMULATIVE_ARGS *cum, tree type, int words)
+{
+ if ((cum->words & 1) == 0)
+ return 0;
+
+ if (type
+ && TREE_CODE (type) != INTEGER_TYPE
+ && TREE_CODE (type) != REAL_TYPE)
+ return TYPE_ALIGN (type) > 8 * BITS_PER_UNIT;
+ else
+ return words > 1;
+}
+
/* Return rtx for register where argument is passed, or zero if it is passed
on the stack. */
-
/* ??? 128-bit quad-precision floats are always passed in general
registers. */
rtx
-ia64_function_arg (cum, mode, type, named, incoming)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
- int incoming;
+ia64_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
+ int named, int incoming)
{
int basereg = (incoming ? GR_ARG_FIRST : AR_ARG_FIRST);
- int words = (((mode == BLKmode ? int_size_in_bytes (type)
- : GET_MODE_SIZE (mode)) + UNITS_PER_WORD - 1)
- / UNITS_PER_WORD);
- int offset = 0;
+ int words = ia64_function_arg_words (type, mode);
+ int offset = ia64_function_arg_offset (cum, type, words);
enum machine_mode hfa_mode = VOIDmode;
- /* Integer and float arguments larger than 8 bytes start at the next even
- boundary. Aggregates larger than 8 bytes start at the next even boundary
- if the aggregate has 16 byte alignment. Net effect is that types with
- alignment greater than 8 start at the next even boundary. */
- /* ??? The ABI does not specify how to handle aggregates with alignment from
- 9 to 15 bytes, or greater than 16. We handle them all as if they had
- 16 byte alignment. Such aggregates can occur only if gcc extensions are
- used. */
- if ((type ? (TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
- : (words > 1))
- && (cum->words & 1))
- offset = 1;
-
/* If all argument slots are used, then it must go on the stack. */
if (cum->words + offset >= MAX_ARGUMENT_SLOTS)
return 0;
@@ -3408,6 +3689,7 @@ ia64_function_arg (cum, mode, type, named, incoming)
for (; offset < byte_size && int_regs < MAX_ARGUMENT_SLOTS; i++)
{
enum machine_mode gr_mode = DImode;
+ unsigned int gr_size;
/* If we have an odd 4 byte hunk because we ran out of FR regs,
then this goes in a GR reg left adjusted/little endian, right
@@ -3421,22 +3703,25 @@ ia64_function_arg (cum, mode, type, named, incoming)
adjusted/little endian. */
else if (byte_size - offset == 4)
gr_mode = SImode;
- /* Complex floats need to have float mode. */
- if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
- gr_mode = hfa_mode;
loc[i] = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (gr_mode, (basereg
+ int_regs)),
GEN_INT (offset));
- offset += GET_MODE_SIZE (gr_mode);
- int_regs += GET_MODE_SIZE (gr_mode) <= UNITS_PER_WORD
- ? 1 : GET_MODE_SIZE (gr_mode) / UNITS_PER_WORD;
+
+ gr_size = GET_MODE_SIZE (gr_mode);
+ offset += gr_size;
+ if (gr_size == UNITS_PER_WORD
+ || (gr_size < UNITS_PER_WORD && offset % UNITS_PER_WORD == 0))
+ int_regs++;
+ else if (gr_size > UNITS_PER_WORD)
+ int_regs += gr_size / UNITS_PER_WORD;
}
- /* If we ended up using just one location, just return that one loc. */
+ /* If we ended up using just one location, just return that one loc, but
+ change the mode back to the argument mode. */
if (i == 1)
- return XEXP (loc[0], 0);
+ return gen_rtx_REG (mode, REGNO (XEXP (loc[0], 0)));
else
return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
}
@@ -3444,8 +3729,8 @@ ia64_function_arg (cum, mode, type, named, incoming)
/* Integral and aggregates go in general registers. If we have run out of
FR registers, then FP values must also go in general registers. This can
happen when we have a SFmode HFA. */
- else if (((mode == TFmode) && ! INTEL_EXTENDED_IEEE_FORMAT)
- || (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS))
+ else if (mode == TFmode || mode == TCmode
+ || (! FLOAT_MODE_P (mode) || cum->fp_regs == MAX_ARGUMENT_SLOTS))
{
int byte_size = ((mode == BLKmode)
? int_size_in_bytes (type) : GET_MODE_SIZE (mode));
@@ -3467,24 +3752,37 @@ ia64_function_arg (cum, mode, type, named, incoming)
}
/* If there is a prototype, then FP values go in a FR register when
- named, and in a GR registeer when unnamed. */
+ named, and in a GR register when unnamed. */
else if (cum->prototype)
{
- if (! named)
- return gen_rtx_REG (mode, basereg + cum->words + offset);
- else
+ if (named)
return gen_rtx_REG (mode, FR_ARG_FIRST + cum->fp_regs);
+ /* In big-endian mode, an anonymous SFmode value must be represented
+ as (parallel:SF [(expr_list (reg:DI n) (const_int 0))]) to force
+ the value into the high half of the general register. */
+ else if (BYTES_BIG_ENDIAN && mode == SFmode)
+ return gen_rtx_PARALLEL (mode,
+ gen_rtvec (1,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (DImode, basereg + cum->words + offset),
+ const0_rtx)));
+ else
+ return gen_rtx_REG (mode, basereg + cum->words + offset);
}
/* If there is no prototype, then FP values go in both FR and GR
registers. */
else
{
+ /* See comment above. */
+ enum machine_mode inner_mode =
+ (BYTES_BIG_ENDIAN && mode == SFmode) ? DImode : mode;
+
rtx fp_reg = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (mode, (FR_ARG_FIRST
+ cum->fp_regs)),
const0_rtx);
rtx gr_reg = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (mode,
+ gen_rtx_REG (inner_mode,
(basereg + cum->words
+ offset)),
const0_rtx);
@@ -3498,23 +3796,11 @@ ia64_function_arg (cum, mode, type, named, incoming)
in memory. */
int
-ia64_function_arg_partial_nregs (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
-{
- int words = (((mode == BLKmode ? int_size_in_bytes (type)
- : GET_MODE_SIZE (mode)) + UNITS_PER_WORD - 1)
- / UNITS_PER_WORD);
- int offset = 0;
-
- /* Arguments with alignment larger than 8 bytes start at the next even
- boundary. */
- if ((type ? (TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
- : (words > 1))
- && (cum->words & 1))
- offset = 1;
+ia64_function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named ATTRIBUTE_UNUSED)
+{
+ int words = ia64_function_arg_words (type, mode);
+ int offset = ia64_function_arg_offset (cum, type, words);
/* If all argument slots are used, then it must go on the stack. */
if (cum->words + offset >= MAX_ARGUMENT_SLOTS)
@@ -3535,29 +3821,17 @@ ia64_function_arg_partial_nregs (cum, mode, type, named)
ia64_function_arg. */
void
-ia64_function_arg_advance (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
-{
- int words = (((mode == BLKmode ? int_size_in_bytes (type)
- : GET_MODE_SIZE (mode)) + UNITS_PER_WORD - 1)
- / UNITS_PER_WORD);
- int offset = 0;
+ia64_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named)
+{
+ int words = ia64_function_arg_words (type, mode);
+ int offset = ia64_function_arg_offset (cum, type, words);
enum machine_mode hfa_mode = VOIDmode;
/* If all arg slots are already full, then there is nothing to do. */
if (cum->words >= MAX_ARGUMENT_SLOTS)
return;
- /* Arguments with alignment larger than 8 bytes start at the next even
- boundary. */
- if ((type ? (TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
- : (words > 1))
- && (cum->words & 1))
- offset = 1;
-
cum->words += words + offset;
/* Check for and handle homogeneous FP aggregates. */
@@ -3607,7 +3881,7 @@ ia64_function_arg_advance (cum, mode, type, named)
cum->int_regs = cum->words;
/* If there is a prototype, then FP values go in a FR register when
- named, and in a GR registeer when unnamed. */
+ named, and in a GR register when unnamed. */
else if (cum->prototype)
{
if (! named)
@@ -3619,7 +3893,7 @@ ia64_function_arg_advance (cum, mode, type, named)
/* If there is no prototype, then FP values go in both FR and GR
registers. */
else
- {
+ {
/* ??? Complex types should not reach here. */
cum->fp_regs += (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT ? 2 : 1);
cum->int_regs = cum->words;
@@ -3630,34 +3904,49 @@ ia64_function_arg_advance (cum, mode, type, named)
/* ??? At present this is a GCC extension to the IA-64 ABI. */
int
-ia64_function_arg_pass_by_reference (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type;
- int named ATTRIBUTE_UNUSED;
+ia64_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type, int named ATTRIBUTE_UNUSED)
{
return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
}
+
+/* True if it is OK to do sibling call optimization for the specified
+ call expression EXP. DECL will be the called function, or NULL if
+ this is an indirect call. */
+static bool
+ia64_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
+{
+ /* We must always return with our current GP. This means we can
+ only sibcall to functions defined in the current module. */
+ return decl && (*targetm.binds_local_p) (decl);
+}
/* Implement va_arg. */
rtx
-ia64_va_arg (valist, type)
- tree valist, type;
+ia64_va_arg (tree valist, tree type)
{
tree t;
/* Variable sized types are passed by reference. */
if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
{
- rtx addr = std_expand_builtin_va_arg (valist, build_pointer_type (type));
- return gen_rtx_MEM (ptr_mode, force_reg (Pmode, addr));
+ rtx addr = force_reg (ptr_mode,
+ std_expand_builtin_va_arg (valist, build_pointer_type (type)));
+#ifdef POINTERS_EXTEND_UNSIGNED
+ addr = convert_memory_address (Pmode, addr);
+#endif
+ return gen_rtx_MEM (ptr_mode, addr);
}
- /* Arguments with alignment larger than 8 bytes start at the next even
- boundary. */
- if (TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
+ /* Aggregate arguments with alignment larger than 8 bytes start at
+ the next even boundary. Integer and floating point arguments
+ do so if they are larger than 8 bytes, whether or not they are
+ also aligned larger than 8 bytes. */
+ if ((TREE_CODE (type) == REAL_TYPE || TREE_CODE (type) == INTEGER_TYPE)
+ ? int_size_in_bytes (type) > 8 : TYPE_ALIGN (type) > 8 * BITS_PER_UNIT)
{
t = build (PLUS_EXPR, TREE_TYPE (valist), valist,
build_int_2 (2 * UNITS_PER_WORD - 1, 0));
@@ -3675,8 +3964,7 @@ ia64_va_arg (valist, type)
in a register. */
int
-ia64_return_in_memory (valtype)
- tree valtype;
+ia64_return_in_memory (tree valtype)
{
enum machine_mode mode;
enum machine_mode hfa_mode;
@@ -3712,9 +4000,7 @@ ia64_return_in_memory (valtype)
/* Return rtx for register that holds the function return value. */
rtx
-ia64_function_value (valtype, func)
- tree valtype;
- tree func ATTRIBUTE_UNUSED;
+ia64_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
{
enum machine_mode mode;
enum machine_mode hfa_mode;
@@ -3747,8 +4033,7 @@ ia64_function_value (valtype, func)
else
return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
}
- else if (FLOAT_TYPE_P (valtype) &&
- ((mode != TFmode) || INTEL_EXTENDED_IEEE_FORMAT))
+ else if (FLOAT_TYPE_P (valtype) && mode != TFmode && mode != TCmode)
return gen_rtx_REG (mode, FR_ARG_FIRST);
else
{
@@ -3777,15 +4062,27 @@ ia64_function_value (valtype, func)
}
}
+/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
+ We need to emit DTP-relative relocations. */
+
+void
+ia64_output_dwarf_dtprel (FILE *file, int size, rtx x)
+{
+ if (size != 8)
+ abort ();
+ fputs ("\tdata8.ua\t@dtprel(", file);
+ output_addr_const (file, x);
+ fputs (")", file);
+}
+
/* Print a memory address as an operand to reference that memory location. */
/* ??? Do we need this? It gets used only for 'a' operands. We could perhaps
also call this from ia64_print_operand for memory addresses. */
void
-ia64_print_operand_address (stream, address)
- FILE * stream ATTRIBUTE_UNUSED;
- rtx address ATTRIBUTE_UNUSED;
+ia64_print_operand_address (FILE * stream ATTRIBUTE_UNUSED,
+ rtx address ATTRIBUTE_UNUSED)
{
}
@@ -3810,10 +4107,7 @@ ia64_print_operand_address (stream, address)
r Print register name, or constant 0 as r0. HP compatibility for
Linux kernel. */
void
-ia64_print_operand (file, x, code)
- FILE * file;
- rtx x;
- int code;
+ia64_print_operand (FILE * file, rtx x, int code)
{
const char *str;
@@ -3921,9 +4215,7 @@ ia64_print_operand (file, x, code)
break;
}
- putc (',', file);
- putc (' ', file);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, value);
+ fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC, value);
return;
}
@@ -3974,7 +4266,7 @@ ia64_print_operand (file, x, code)
case '+':
{
const char *which;
-
+
/* For conditional branches, returns or calls, substitute
sptk, dptk, dpnt, or spnt for %s. */
x = find_reg_note (current_output_insn, REG_BR_PROB, 0);
@@ -4047,13 +4339,88 @@ ia64_print_operand (file, x, code)
return;
}
-/* Calulate the cost of moving data from a register in class FROM to
+/* 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. */
+/* ??? This is incomplete. */
+
+static bool
+ia64_rtx_costs (rtx x, int code, int outer_code, int *total)
+{
+ switch (code)
+ {
+ case CONST_INT:
+ switch (outer_code)
+ {
+ case SET:
+ *total = CONST_OK_FOR_J (INTVAL (x)) ? 0 : COSTS_N_INSNS (1);
+ return true;
+ case PLUS:
+ if (CONST_OK_FOR_I (INTVAL (x)))
+ *total = 0;
+ else if (CONST_OK_FOR_J (INTVAL (x)))
+ *total = 1;
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+ default:
+ if (CONST_OK_FOR_K (INTVAL (x)) || CONST_OK_FOR_L (INTVAL (x)))
+ *total = 0;
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
+
+ case CONST_DOUBLE:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case CONST:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ *total = COSTS_N_INSNS (3);
+ return true;
+
+ case MULT:
+ /* For multiplies wider than HImode, we have to go to the FPU,
+ which normally involves copies. Plus there's the latency
+ of the multiply itself, and the latency of the instructions to
+ transfer integer regs to FP regs. */
+ /* ??? Check for FP mode. */
+ if (GET_MODE_SIZE (GET_MODE (x)) > 2)
+ *total = COSTS_N_INSNS (10);
+ else
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case PLUS:
+ case MINUS:
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ /* We make divide expensive, so that divide-by-constant will be
+ optimized to a multiply. */
+ *total = COSTS_N_INSNS (60);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Calculate the cost of moving data from a register in class FROM to
one in class TO, using MODE. */
int
-ia64_register_move_cost (mode, from, to)
- enum machine_mode mode;
- enum reg_class from, to;
+ia64_register_move_cost (enum machine_mode mode, enum reg_class from,
+ enum reg_class to)
{
/* ADDL_REGS is the same as GR_REGS for movement purposes. */
if (to == ADDL_REGS)
@@ -4069,11 +4436,11 @@ ia64_register_move_cost (mode, from, to)
to = from, from = tmp;
}
- /* Moving from FR<->GR in TFmode must be more expensive than 2,
+ /* Moving from FR<->GR in XFmode must be more expensive than 2,
so that we get secondary memory reloads. Between FR_REGS,
we have to make this at least as expensive as MEMORY_MOVE_COST
to avoid spectacularly poor register class preferencing. */
- if (mode == TFmode)
+ if (mode == XFmode)
{
if (to != GR_REGS || from != GR_REGS)
return MEMORY_MOVE_COST (mode, to, 0);
@@ -4125,10 +4492,8 @@ ia64_register_move_cost (mode, from, to)
is required. */
enum reg_class
-ia64_secondary_reload_class (class, mode, x)
- enum reg_class class;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx x;
+ia64_secondary_reload_class (enum reg_class class,
+ enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
{
int regno = -1;
@@ -4162,10 +4527,10 @@ ia64_secondary_reload_class (class, mode, x)
break;
case FR_REGS:
- /* Need to go through general regsters to get to other class regs. */
+ /* Need to go through general registers to get to other class regs. */
if (regno >= 0 && ! (FR_REGNO_P (regno) || GENERAL_REGNO_P (regno)))
return GR_REGS;
-
+
/* This can happen when a paradoxical subreg is an operand to the
muldi3 pattern. */
/* ??? This shouldn't be necessary after instruction scheduling is
@@ -4206,28 +4571,19 @@ ia64_secondary_reload_class (class, mode, x)
return GR_REGS;
break;
- case GR_REGS:
- /* Since we have no offsettable memory addresses, we need a temporary
- to hold the address of the second word. */
- if (mode == TImode)
- return GR_REGS;
- break;
-
default:
break;
}
return NO_REGS;
}
+
/* Emit text to declare externally defined variables and functions, because
the Intel assembler does not support undefined externals. */
void
-ia64_asm_output_external (file, decl, name)
- FILE *file;
- tree decl;
- const char *name;
+ia64_asm_output_external (FILE *file, tree decl, const char *name)
{
int save_referenced;
@@ -4237,7 +4593,7 @@ ia64_asm_output_external (file, decl, name)
if (TARGET_GNU_AS
&& (!TARGET_HPUX_LD
|| TREE_CODE (decl) != FUNCTION_DECL
- || strstr(name, "__builtin_") == name))
+ || strstr (name, "__builtin_") == name))
return;
/* ??? The Intel assembler creates a reference that needs to be satisfied by
@@ -4253,7 +4609,7 @@ ia64_asm_output_external (file, decl, name)
return;
if (TARGET_HPUX_LD)
- ia64_hpux_add_extern_decl (name);
+ ia64_hpux_add_extern_decl (decl);
else
{
/* assemble_name will set TREE_SYMBOL_REFERENCED, so we must save and
@@ -4269,8 +4625,7 @@ ia64_asm_output_external (file, decl, name)
/* Parse the -mfixed-range= option string. */
static void
-fix_range (const_str)
- const char *const_str;
+fix_range (const char *const_str)
{
int i, first, last;
char *str, *dash, *comma;
@@ -4333,7 +4688,7 @@ fix_range (const_str)
}
static struct machine_function *
-ia64_init_machine_status ()
+ia64_init_machine_status (void)
{
return ggc_alloc_cleared (sizeof (struct machine_function));
}
@@ -4341,8 +4696,25 @@ ia64_init_machine_status ()
/* Handle TARGET_OPTIONS switches. */
void
-ia64_override_options ()
+ia64_override_options (void)
{
+ static struct pta
+ {
+ const char *const name; /* processor name or nickname. */
+ const enum processor_type processor;
+ }
+ const processor_alias_table[] =
+ {
+ {"itanium", PROCESSOR_ITANIUM},
+ {"itanium1", PROCESSOR_ITANIUM},
+ {"merced", PROCESSOR_ITANIUM},
+ {"itanium2", PROCESSOR_ITANIUM2},
+ {"mckinley", PROCESSOR_ITANIUM2},
+ };
+
+ int const pta_size = ARRAY_SIZE (processor_alias_table);
+ int i;
+
if (TARGET_AUTO_PIC)
target_flags |= MASK_CONST_GP;
@@ -4358,6 +4730,18 @@ ia64_override_options ()
target_flags &= ~MASK_INLINE_INT_DIV_THR;
}
+ if (TARGET_INLINE_SQRT_LAT && TARGET_INLINE_SQRT_THR)
+ {
+ warning ("cannot optimize square root for both latency and throughput");
+ target_flags &= ~MASK_INLINE_SQRT_THR;
+ }
+
+ if (TARGET_INLINE_SQRT_LAT)
+ {
+ warning ("not yet implemented: latency-optimized inline square root");
+ target_flags &= ~MASK_INLINE_SQRT_LAT;
+ }
+
if (ia64_fixed_range_string)
fix_range (ia64_fixed_range_string);
@@ -4371,35 +4755,32 @@ ia64_override_options ()
ia64_tls_size = tmp;
}
+ if (!ia64_tune_string)
+ ia64_tune_string = "itanium2";
+
+ for (i = 0; i < pta_size; i++)
+ if (! strcmp (ia64_tune_string, processor_alias_table[i].name))
+ {
+ ia64_tune = processor_alias_table[i].processor;
+ break;
+ }
+
+ if (i == pta_size)
+ error ("bad value (%s) for -tune= switch", ia64_tune_string);
+
ia64_flag_schedule_insns2 = flag_schedule_insns_after_reload;
flag_schedule_insns_after_reload = 0;
ia64_section_threshold = g_switch_set ? g_switch_value : IA64_DEFAULT_GVALUE;
init_machine_status = ia64_init_machine_status;
-
- /* Tell the compiler which flavor of TFmode we're using. */
- if (INTEL_EXTENDED_IEEE_FORMAT)
- real_format_for_mode[TFmode - QFmode] = &ieee_extended_intel_128_format;
}
-static enum attr_itanium_requires_unit0 ia64_safe_itanium_requires_unit0 PARAMS((rtx));
-static enum attr_itanium_class ia64_safe_itanium_class PARAMS((rtx));
-static enum attr_type ia64_safe_type PARAMS((rtx));
-
-static enum attr_itanium_requires_unit0
-ia64_safe_itanium_requires_unit0 (insn)
- rtx insn;
-{
- if (recog_memoized (insn) >= 0)
- return get_attr_itanium_requires_unit0 (insn);
- else
- return ITANIUM_REQUIRES_UNIT0_NO;
-}
+static enum attr_itanium_class ia64_safe_itanium_class (rtx);
+static enum attr_type ia64_safe_type (rtx);
static enum attr_itanium_class
-ia64_safe_itanium_class (insn)
- rtx insn;
+ia64_safe_itanium_class (rtx insn)
{
if (recog_memoized (insn) >= 0)
return get_attr_itanium_class (insn);
@@ -4408,8 +4789,7 @@ ia64_safe_itanium_class (insn)
}
static enum attr_type
-ia64_safe_type (insn)
- rtx insn;
+ia64_safe_type (rtx insn)
{
if (recog_memoized (insn) >= 0)
return get_attr_type (insn);
@@ -4487,26 +4867,21 @@ struct reg_flags
unsigned int is_sibcall : 1; /* Is this a sibling or normal call? */
};
-static void rws_update PARAMS ((struct reg_write_state *, int,
- struct reg_flags, int));
-static int rws_access_regno PARAMS ((int, struct reg_flags, int));
-static int rws_access_reg PARAMS ((rtx, struct reg_flags, int));
-static void update_set_flags PARAMS ((rtx, struct reg_flags *, int *, rtx *));
-static int set_src_needs_barrier PARAMS ((rtx, struct reg_flags, int, rtx));
-static int rtx_needs_barrier PARAMS ((rtx, struct reg_flags, int));
-static void init_insn_group_barriers PARAMS ((void));
-static int group_barrier_needed_p PARAMS ((rtx));
-static int safe_group_barrier_needed_p PARAMS ((rtx));
+static void rws_update (struct reg_write_state *, int, struct reg_flags, int);
+static int rws_access_regno (int, struct reg_flags, int);
+static int rws_access_reg (rtx, struct reg_flags, int);
+static void update_set_flags (rtx, struct reg_flags *, int *, rtx *);
+static int set_src_needs_barrier (rtx, struct reg_flags, int, rtx);
+static int rtx_needs_barrier (rtx, struct reg_flags, int);
+static void init_insn_group_barriers (void);
+static int group_barrier_needed_p (rtx);
+static int safe_group_barrier_needed_p (rtx);
/* Update *RWS for REGNO, which is being written by the current instruction,
with predicate PRED, and associated register flags in FLAGS. */
static void
-rws_update (rws, regno, flags, pred)
- struct reg_write_state *rws;
- int regno;
- struct reg_flags flags;
- int pred;
+rws_update (struct reg_write_state *rws, int regno, struct reg_flags flags, int pred)
{
if (pred)
rws[regno].write_count++;
@@ -4524,10 +4899,7 @@ rws_update (rws, regno, flags, pred)
a dependency with an earlier instruction in the same group. */
static int
-rws_access_regno (regno, flags, pred)
- int regno;
- struct reg_flags flags;
- int pred;
+rws_access_regno (int regno, struct reg_flags flags, int pred)
{
int need_barrier = 0;
@@ -4562,7 +4934,7 @@ rws_access_regno (regno, flags, pred)
/* ??? This assumes that P and P+1 are always complementary
predicates for P even. */
if (flags.is_and && rws_sum[regno].written_by_and)
- ;
+ ;
else if (flags.is_or && rws_sum[regno].written_by_or)
;
else if ((rws_sum[regno].first_pred ^ 1) != pred)
@@ -4645,10 +5017,7 @@ rws_access_regno (regno, flags, pred)
}
static int
-rws_access_reg (reg, flags, pred)
- rtx reg;
- struct reg_flags flags;
- int pred;
+rws_access_reg (rtx reg, struct reg_flags flags, int pred)
{
int regno = REGNO (reg);
int n = HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg));
@@ -4668,11 +5037,7 @@ rws_access_reg (reg, flags, pred)
the condition, stored in *PFLAGS, *PPRED and *PCOND. */
static void
-update_set_flags (x, pflags, ppred, pcond)
- rtx x;
- struct reg_flags *pflags;
- int *ppred;
- rtx *pcond;
+update_set_flags (rtx x, struct reg_flags *pflags, int *ppred, rtx *pcond)
{
rtx src = SET_SRC (x);
@@ -4686,7 +5051,7 @@ update_set_flags (x, pflags, ppred, pcond)
case IF_THEN_ELSE:
if (SET_DEST (x) == pc_rtx)
/* X is a conditional branch. */
- return;
+ return;
else
{
int is_complemented = 0;
@@ -4749,13 +5114,9 @@ update_set_flags (x, pflags, ppred, pcond)
source of a given SET rtx found in X needs a barrier. FLAGS and PRED
are as in rtx_needs_barrier. COND is an rtx that holds the condition
for this insn. */
-
+
static int
-set_src_needs_barrier (x, flags, pred, cond)
- rtx x;
- struct reg_flags flags;
- int pred;
- rtx cond;
+set_src_needs_barrier (rtx x, struct reg_flags flags, int pred, rtx cond)
{
int need_barrier = 0;
rtx dst;
@@ -4790,15 +5151,12 @@ set_src_needs_barrier (x, flags, pred, cond)
return need_barrier;
}
-/* Handle an access to rtx X of type FLAGS using predicate register PRED.
- Return 1 is this access creates a dependency with an earlier instruction
- in the same group. */
+/* Handle an access to rtx X of type FLAGS using predicate register
+ PRED. Return 1 if this access creates a dependency with an earlier
+ instruction in the same group. */
static int
-rtx_needs_barrier (x, flags, pred)
- rtx x;
- struct reg_flags flags;
- int pred;
+rtx_needs_barrier (rtx x, struct reg_flags flags, int pred)
{
int i, j;
int is_complemented = 0;
@@ -4814,7 +5172,7 @@ rtx_needs_barrier (x, flags, pred)
switch (GET_CODE (x))
{
- case SET:
+ case SET:
update_set_flags (x, &new_flags, &pred, &cond);
need_barrier = set_src_needs_barrier (x, new_flags, pred, cond);
if (GET_CODE (SET_SRC (x)) != CALL)
@@ -4984,7 +5342,7 @@ rtx_needs_barrier (x, flags, pred)
case NEG: case NOT: case SIGN_EXTEND: case ZERO_EXTEND:
case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: case FLOAT:
case FIX: case UNSIGNED_FLOAT: case UNSIGNED_FIX: case ABS:
- case SQRT: case FFS:
+ case SQRT: case FFS: case POPCOUNT:
need_barrier = rtx_needs_barrier (XEXP (x, 0), flags, pred);
break;
@@ -5017,14 +5375,13 @@ rtx_needs_barrier (x, flags, pred)
new_flags, pred);
break;
}
-
+
case UNSPEC_FR_SPILL:
case UNSPEC_FR_RESTORE:
- case UNSPEC_POPCNT:
- need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
- break;
-
+ case UNSPEC_GETF_EXP:
+ case UNSPEC_SETF_EXP:
case UNSPEC_ADDP4:
+ case UNSPEC_FR_SQRT_RECIP_APPROX:
need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 0), flags, pred);
break;
@@ -5122,7 +5479,7 @@ rtx_needs_barrier (x, flags, pred)
sequence of insns. */
static void
-init_insn_group_barriers ()
+init_insn_group_barriers (void)
{
memset (rws_sum, 0, sizeof (rws_sum));
first_instruction = 1;
@@ -5133,8 +5490,7 @@ init_insn_group_barriers ()
Return nonzero if so. */
static int
-group_barrier_needed_p (insn)
- rtx insn;
+group_barrier_needed_p (rtx insn)
{
rtx pat;
int need_barrier = 0;
@@ -5230,7 +5586,10 @@ group_barrier_needed_p (insn)
abort ();
}
- if (first_instruction)
+ if (first_instruction && INSN_P (insn)
+ && ia64_safe_itanium_class (insn) != ITANIUM_CLASS_IGNORE
+ && GET_CODE (PATTERN (insn)) != USE
+ && GET_CODE (PATTERN (insn)) != CLOBBER)
{
need_barrier = 0;
first_instruction = 0;
@@ -5242,8 +5601,7 @@ group_barrier_needed_p (insn)
/* Like group_barrier_needed_p, but do not clobber the current state. */
static int
-safe_group_barrier_needed_p (insn)
- rtx insn;
+safe_group_barrier_needed_p (rtx insn)
{
struct reg_write_state rws_saved[NUM_REGS];
int saved_first_instruction;
@@ -5260,17 +5618,15 @@ safe_group_barrier_needed_p (insn)
return t;
}
-/* INSNS is an chain of instructions. Scan the chain, and insert stop bits
- as necessary to eliminate dependendencies. This function assumes that
- a final instruction scheduling pass has been run which has already
- inserted most of the necessary stop bits. This function only inserts
- new ones at basic block boundaries, since these are invisible to the
- scheduler. */
+/* Scan the current function and insert stop bits as necessary to
+ eliminate dependencies. This function assumes that a final
+ instruction scheduling pass has been run which has already
+ inserted most of the necessary stop bits. This function only
+ inserts new ones at basic block boundaries, since these are
+ invisible to the scheduler. */
static void
-emit_insn_group_barriers (dump, insns)
- FILE *dump;
- rtx insns;
+emit_insn_group_barriers (FILE *dump)
{
rtx insn;
rtx last_label = 0;
@@ -5278,7 +5634,7 @@ emit_insn_group_barriers (dump, insns)
init_insn_group_barriers ();
- for (insn = insns; insn; insn = NEXT_INSN (insn))
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
if (GET_CODE (insn) == CODE_LABEL)
{
@@ -5326,15 +5682,13 @@ emit_insn_group_barriers (dump, insns)
This function has to emit all necessary group barriers. */
static void
-emit_all_insn_group_barriers (dump, insns)
- FILE *dump ATTRIBUTE_UNUSED;
- rtx insns;
+emit_all_insn_group_barriers (FILE *dump ATTRIBUTE_UNUSED)
{
rtx insn;
init_insn_group_barriers ();
- for (insn = insns; insn; insn = NEXT_INSN (insn))
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
if (GET_CODE (insn) == BARRIER)
{
@@ -5363,10 +5717,11 @@ emit_all_insn_group_barriers (dump, insns)
}
}
}
+
-static int errata_find_address_regs PARAMS ((rtx *, void *));
-static void errata_emit_nops PARAMS ((rtx));
-static void fixup_errata PARAMS ((void));
+static int errata_find_address_regs (rtx *, void *);
+static void errata_emit_nops (rtx);
+static void fixup_errata (void);
/* This structure is used to track some details about the previous insns
groups so we can determine if it may be necessary to insert NOPs to
@@ -5384,9 +5739,7 @@ static int group_idx;
conditionally set in the previous group is used as an address register.
It ensures that for_each_rtx returns 1 in that case. */
static int
-errata_find_address_regs (xp, data)
- rtx *xp;
- void *data ATTRIBUTE_UNUSED;
+errata_find_address_regs (rtx *xp, void *data ATTRIBUTE_UNUSED)
{
rtx x = *xp;
if (GET_CODE (x) != MEM)
@@ -5409,8 +5762,7 @@ errata_find_address_regs (xp, data)
last_group and emits additional NOPs if necessary to work around
an Itanium A/B step erratum. */
static void
-errata_emit_nops (insn)
- rtx insn;
+errata_emit_nops (rtx insn)
{
struct group *this_group = last_group + group_idx;
struct group *prev_group = last_group + (group_idx ^ 1);
@@ -5483,7 +5835,7 @@ errata_emit_nops (insn)
/* Emit extra nops if they are required to work around hardware errata. */
static void
-fixup_errata ()
+fixup_errata (void)
{
rtx insn;
@@ -5508,153 +5860,106 @@ fixup_errata ()
}
}
-/* Instruction scheduling support. */
-/* Describe one bundle. */
-struct bundle
-{
- /* Zero if there's no possibility of a stop in this bundle other than
- at the end, otherwise the position of the optional stop bit. */
- int possible_stop;
- /* The types of the three slots. */
- enum attr_type t[3];
- /* The pseudo op to be emitted into the assembler output. */
- const char *name;
-};
+/* Instruction scheduling support. */
#define NR_BUNDLES 10
-/* A list of all available bundles. */
+/* A list of names of all available bundles. */
-static const struct bundle bundle[NR_BUNDLES] =
+static const char *bundle_name [NR_BUNDLES] =
{
- { 2, { TYPE_M, TYPE_I, TYPE_I }, ".mii" },
- { 1, { TYPE_M, TYPE_M, TYPE_I }, ".mmi" },
- { 0, { TYPE_M, TYPE_F, TYPE_I }, ".mfi" },
- { 0, { TYPE_M, TYPE_M, TYPE_F }, ".mmf" },
+ ".mii",
+ ".mmi",
+ ".mfi",
+ ".mmf",
#if NR_BUNDLES == 10
- { 0, { TYPE_B, TYPE_B, TYPE_B }, ".bbb" },
- { 0, { TYPE_M, TYPE_B, TYPE_B }, ".mbb" },
+ ".bbb",
+ ".mbb",
#endif
- { 0, { TYPE_M, TYPE_I, TYPE_B }, ".mib" },
- { 0, { TYPE_M, TYPE_M, TYPE_B }, ".mmb" },
- { 0, { TYPE_M, TYPE_F, TYPE_B }, ".mfb" },
- /* .mfi needs to occur earlier than .mlx, so that we only generate it if
- it matches an L type insn. Otherwise we'll try to generate L type
- nops. */
- { 0, { TYPE_M, TYPE_L, TYPE_X }, ".mlx" }
+ ".mib",
+ ".mmb",
+ ".mfb",
+ ".mlx"
};
-/* Describe a packet of instructions. Packets consist of two bundles that
- are visible to the hardware in one scheduling window. */
+/* Nonzero if we should insert stop bits into the schedule. */
-struct ia64_packet
-{
- const struct bundle *t1, *t2;
- /* Precomputed value of the first split issue in this packet if a cycle
- starts at its beginning. */
- int first_split;
- /* For convenience, the insn types are replicated here so we don't have
- to go through T1 and T2 all the time. */
- enum attr_type t[6];
-};
+int ia64_final_schedule = 0;
-/* An array containing all possible packets. */
-#define NR_PACKETS (NR_BUNDLES * NR_BUNDLES)
-static struct ia64_packet packets[NR_PACKETS];
+/* Codes of the corresponding quieryied units: */
-/* Map attr_type to a string with the name. */
+static int _0mii_, _0mmi_, _0mfi_, _0mmf_;
+static int _0bbb_, _0mbb_, _0mib_, _0mmb_, _0mfb_, _0mlx_;
-static const char *const type_names[] =
-{
- "UNKNOWN", "A", "I", "M", "F", "B", "L", "X", "S"
-};
+static int _1mii_, _1mmi_, _1mfi_, _1mmf_;
+static int _1bbb_, _1mbb_, _1mib_, _1mmb_, _1mfb_, _1mlx_;
-/* Nonzero if we should insert stop bits into the schedule. */
-int ia64_final_schedule = 0;
+static int pos_1, pos_2, pos_3, pos_4, pos_5, pos_6;
-static int itanium_split_issue PARAMS ((const struct ia64_packet *, int));
-static rtx ia64_single_set PARAMS ((rtx));
-static int insn_matches_slot PARAMS ((const struct ia64_packet *, enum attr_type, int, rtx));
-static void ia64_emit_insn_before PARAMS ((rtx, rtx));
-static void maybe_rotate PARAMS ((FILE *));
-static void finish_last_head PARAMS ((FILE *, int));
-static void rotate_one_bundle PARAMS ((FILE *));
-static void rotate_two_bundles PARAMS ((FILE *));
-static void nop_cycles_until PARAMS ((int, FILE *));
-static void cycle_end_fill_slots PARAMS ((FILE *));
-static int packet_matches_p PARAMS ((const struct ia64_packet *, int, int *));
-static int get_split PARAMS ((const struct ia64_packet *, int));
-static int find_best_insn PARAMS ((rtx *, enum attr_type *, int,
- const struct ia64_packet *, int));
-static void find_best_packet PARAMS ((int *, const struct ia64_packet **,
- rtx *, enum attr_type *, int));
-static int itanium_reorder PARAMS ((FILE *, rtx *, rtx *, int));
-static void dump_current_packet PARAMS ((FILE *));
-static void schedule_stop PARAMS ((FILE *));
-static rtx gen_nop_type PARAMS ((enum attr_type));
-static void ia64_emit_nops PARAMS ((void));
+/* The following variable value is an insn group barrier. */
-/* Map a bundle number to its pseudo-op. */
+static rtx dfa_stop_insn;
-const char *
-get_bundle_name (b)
- int b;
-{
- return bundle[b].name;
-}
+/* The following variable value is the last issued insn. */
-/* Compute the slot which will cause a split issue in packet P if the
- current cycle begins at slot BEGIN. */
+static rtx last_scheduled_insn;
-static int
-itanium_split_issue (p, begin)
- const struct ia64_packet *p;
- int begin;
-{
- int type_count[TYPE_S];
- int i;
- int split = 6;
+/* The following variable value is size of the DFA state. */
- if (begin < 3)
- {
- /* Always split before and after MMF. */
- if (p->t[0] == TYPE_M && p->t[1] == TYPE_M && p->t[2] == TYPE_F)
- return 3;
- if (p->t[3] == TYPE_M && p->t[4] == TYPE_M && p->t[5] == TYPE_F)
- return 3;
- /* Always split after MBB and BBB. */
- if (p->t[1] == TYPE_B)
- return 3;
- /* Split after first bundle in MIB BBB combination. */
- if (p->t[2] == TYPE_B && p->t[3] == TYPE_B)
- return 3;
- }
+static size_t dfa_state_size;
- memset (type_count, 0, sizeof type_count);
- for (i = begin; i < split; i++)
- {
- enum attr_type t0 = p->t[i];
- /* An MLX bundle reserves the same units as an MFI bundle. */
- enum attr_type t = (t0 == TYPE_L ? TYPE_F
- : t0 == TYPE_X ? TYPE_I
- : t0);
+/* The following variable value is pointer to a DFA state used as
+ temporary variable. */
- /* Itanium can execute up to 3 branches, 2 floating point, 2 memory, and
- 2 integer per cycle. */
- int max = (t == TYPE_B ? 3 : 2);
- if (type_count[t] == max)
- return i;
+static state_t temp_dfa_state = NULL;
- type_count[t]++;
- }
- return split;
+/* The following variable value is DFA state after issuing the last
+ insn. */
+
+static state_t prev_cycle_state = NULL;
+
+/* The following array element values are TRUE if the corresponding
+ insn requires to add stop bits before it. */
+
+static char *stops_p;
+
+/* The following variable is used to set up the mentioned above array. */
+
+static int stop_before_p = 0;
+
+/* The following variable value is length of the arrays `clocks' and
+ `add_cycles'. */
+
+static int clocks_length;
+
+/* The following array element values are cycles on which the
+ corresponding insn will be issued. The array is used only for
+ Itanium1. */
+
+static int *clocks;
+
+/* The following array element values are numbers of cycles should be
+ added to improve insn scheduling for MM_insns for Itanium1. */
+
+static int *add_cycles;
+
+static rtx ia64_single_set (rtx);
+static void ia64_emit_insn_before (rtx, rtx);
+
+/* Map a bundle number to its pseudo-op. */
+
+const char *
+get_bundle_name (int b)
+{
+ return bundle_name[b];
}
+
/* Return the maximum number of instructions a cpu can issue. */
static int
-ia64_issue_rate ()
+ia64_issue_rate (void)
{
return 6;
}
@@ -5662,8 +5967,7 @@ ia64_issue_rate ()
/* Helper function - like single_set, but look inside COND_EXEC. */
static rtx
-ia64_single_set (insn)
- rtx insn;
+ia64_single_set (rtx insn)
{
rtx x = PATTERN (insn), ret;
if (GET_CODE (x) == COND_EXEC)
@@ -5693,1273 +5997,1438 @@ ia64_single_set (insn)
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
static int
-ia64_adjust_cost (insn, link, dep_insn, cost)
- rtx insn, link, dep_insn;
- int cost;
+ia64_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
- enum attr_type dep_type;
enum attr_itanium_class dep_class;
enum attr_itanium_class insn_class;
- rtx dep_set, set, src, addr;
-
- if (GET_CODE (PATTERN (insn)) == CLOBBER
- || GET_CODE (PATTERN (insn)) == USE
- || GET_CODE (PATTERN (dep_insn)) == CLOBBER
- || GET_CODE (PATTERN (dep_insn)) == USE
- /* @@@ Not accurate for indirect calls. */
- || GET_CODE (insn) == CALL_INSN
- || ia64_safe_type (insn) == TYPE_S)
- return 0;
- if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT
- || REG_NOTE_KIND (link) == REG_DEP_ANTI)
- return 0;
+ if (REG_NOTE_KIND (link) != REG_DEP_OUTPUT)
+ return cost;
- dep_type = ia64_safe_type (dep_insn);
- dep_class = ia64_safe_itanium_class (dep_insn);
insn_class = ia64_safe_itanium_class (insn);
-
- /* Compares that feed a conditional branch can execute in the same
- cycle. */
- dep_set = ia64_single_set (dep_insn);
- set = ia64_single_set (insn);
-
- if (dep_type != TYPE_F
- && dep_set
- && GET_CODE (SET_DEST (dep_set)) == REG
- && PR_REG (REGNO (SET_DEST (dep_set)))
- && GET_CODE (insn) == JUMP_INSN)
+ dep_class = ia64_safe_itanium_class (dep_insn);
+ if (dep_class == ITANIUM_CLASS_ST || dep_class == ITANIUM_CLASS_STF
+ || insn_class == ITANIUM_CLASS_ST || insn_class == ITANIUM_CLASS_STF)
return 0;
- if (dep_set && GET_CODE (SET_DEST (dep_set)) == MEM)
- {
- /* ??? Can't find any information in the documenation about whether
- a sequence
- st [rx] = ra
- ld rb = [ry]
- splits issue. Assume it doesn't. */
- return 0;
- }
-
- src = set ? SET_SRC (set) : 0;
- addr = 0;
- if (set)
- {
- if (GET_CODE (SET_DEST (set)) == MEM)
- addr = XEXP (SET_DEST (set), 0);
- else if (GET_CODE (SET_DEST (set)) == SUBREG
- && GET_CODE (SUBREG_REG (SET_DEST (set))) == MEM)
- addr = XEXP (SUBREG_REG (SET_DEST (set)), 0);
- else
- {
- addr = src;
- if (GET_CODE (addr) == UNSPEC && XVECLEN (addr, 0) > 0)
- addr = XVECEXP (addr, 0, 0);
- while (GET_CODE (addr) == SUBREG || GET_CODE (addr) == ZERO_EXTEND)
- addr = XEXP (addr, 0);
-
- /* Note that LO_SUM is used for GOT loads. */
- if (GET_CODE (addr) == MEM || GET_CODE (addr) == LO_SUM)
- addr = XEXP (addr, 0);
- else
- addr = 0;
- }
- }
-
- if (addr && GET_CODE (addr) == POST_MODIFY)
- addr = XEXP (addr, 0);
-
- set = ia64_single_set (dep_insn);
-
- if ((dep_class == ITANIUM_CLASS_IALU
- || dep_class == ITANIUM_CLASS_ILOG
- || dep_class == ITANIUM_CLASS_LD)
- && (insn_class == ITANIUM_CLASS_LD
- || insn_class == ITANIUM_CLASS_ST))
- {
- if (! addr || ! set)
- abort ();
- /* This isn't completely correct - an IALU that feeds an address has
- a latency of 1 cycle if it's issued in an M slot, but 2 cycles
- otherwise. Unfortunately there's no good way to describe this. */
- if (reg_overlap_mentioned_p (SET_DEST (set), addr))
- return cost + 1;
- }
-
- if ((dep_class == ITANIUM_CLASS_IALU
- || dep_class == ITANIUM_CLASS_ILOG
- || dep_class == ITANIUM_CLASS_LD)
- && (insn_class == ITANIUM_CLASS_MMMUL
- || insn_class == ITANIUM_CLASS_MMSHF
- || insn_class == ITANIUM_CLASS_MMSHFI))
- return 3;
-
- if (dep_class == ITANIUM_CLASS_FMAC
- && (insn_class == ITANIUM_CLASS_FMISC
- || insn_class == ITANIUM_CLASS_FCVTFX
- || insn_class == ITANIUM_CLASS_XMPY))
- return 7;
-
- if ((dep_class == ITANIUM_CLASS_FMAC
- || dep_class == ITANIUM_CLASS_FMISC
- || dep_class == ITANIUM_CLASS_FCVTFX
- || dep_class == ITANIUM_CLASS_XMPY)
- && insn_class == ITANIUM_CLASS_STF)
- return 8;
-
- /* Intel docs say only LD, ST, IALU, ILOG, ISHF consumers have latency 4,
- but HP engineers say any non-MM operation. */
- if ((dep_class == ITANIUM_CLASS_MMMUL
- || dep_class == ITANIUM_CLASS_MMSHF
- || dep_class == ITANIUM_CLASS_MMSHFI)
- && insn_class != ITANIUM_CLASS_MMMUL
- && insn_class != ITANIUM_CLASS_MMSHF
- && insn_class != ITANIUM_CLASS_MMSHFI)
- return 4;
-
return cost;
}
-/* Describe the current state of the Itanium pipeline. */
-static struct
-{
- /* The first slot that is used in the current cycle. */
- int first_slot;
- /* The next slot to fill. */
- int cur;
- /* The packet we have selected for the current issue window. */
- const struct ia64_packet *packet;
- /* The position of the split issue that occurs due to issue width
- limitations (6 if there's no split issue). */
- int split;
- /* Record data about the insns scheduled so far in the same issue
- window. The elements up to but not including FIRST_SLOT belong
- to the previous cycle, the ones starting with FIRST_SLOT belong
- to the current cycle. */
- enum attr_type types[6];
- rtx insns[6];
- int stopbit[6];
- /* Nonzero if we decided to schedule a stop bit. */
- int last_was_stop;
-} sched_data;
-
-/* Temporary arrays; they have enough elements to hold all insns that
- can be ready at the same time while scheduling of the current block.
- SCHED_READY can hold ready insns, SCHED_TYPES their types. */
-static rtx *sched_ready;
-static enum attr_type *sched_types;
-
-/* Determine whether an insn INSN of type ITYPE can fit into slot SLOT
- of packet P. */
-
-static int
-insn_matches_slot (p, itype, slot, insn)
- const struct ia64_packet *p;
- enum attr_type itype;
- int slot;
- rtx insn;
-{
- enum attr_itanium_requires_unit0 u0;
- enum attr_type stype = p->t[slot];
-
- if (insn)
- {
- u0 = ia64_safe_itanium_requires_unit0 (insn);
- if (u0 == ITANIUM_REQUIRES_UNIT0_YES)
- {
- int i;
- for (i = sched_data.first_slot; i < slot; i++)
- if (p->t[i] == stype
- || (stype == TYPE_F && p->t[i] == TYPE_L)
- || (stype == TYPE_I && p->t[i] == TYPE_X))
- return 0;
- }
- if (GET_CODE (insn) == CALL_INSN)
- {
- /* Reject calls in multiway branch packets. We want to limit
- the number of multiway branches we generate (since the branch
- predictor is limited), and this seems to work fairly well.
- (If we didn't do this, we'd have to add another test here to
- force calls into the third slot of the bundle.) */
- if (slot < 3)
- {
- if (p->t[1] == TYPE_B)
- return 0;
- }
- else
- {
- if (p->t[4] == TYPE_B)
- return 0;
- }
- }
- }
-
- if (itype == stype)
- return 1;
- if (itype == TYPE_A)
- return stype == TYPE_M || stype == TYPE_I;
- return 0;
-}
-
/* Like emit_insn_before, but skip cycle_display notes.
??? When cycle display notes are implemented, update this. */
static void
-ia64_emit_insn_before (insn, before)
- rtx insn, before;
+ia64_emit_insn_before (rtx insn, rtx before)
{
emit_insn_before (insn, before);
}
-/* When rotating a bundle out of the issue window, insert a bundle selector
- insn in front of it. DUMP is the scheduling dump file or NULL. START
- is either 0 or 3, depending on whether we want to emit a bundle selector
- for the first bundle or the second bundle in the current issue window.
-
- The selector insns are emitted this late because the selected packet can
- be changed until parts of it get rotated out. */
+/* The following function marks insns who produce addresses for load
+ and store insns. Such insns will be placed into M slots because it
+ decrease latency time for Itanium1 (see function
+ `ia64_produce_address_p' and the DFA descriptions). */
static void
-finish_last_head (dump, start)
- FILE *dump;
- int start;
+ia64_dependencies_evaluation_hook (rtx head, rtx tail)
{
- const struct ia64_packet *p = sched_data.packet;
- const struct bundle *b = start == 0 ? p->t1 : p->t2;
- int bundle_type = b - bundle;
- rtx insn;
- int i;
-
- if (! ia64_final_schedule)
- return;
-
- for (i = start; sched_data.insns[i] == 0; i++)
- if (i == start + 3)
- abort ();
- insn = sched_data.insns[i];
-
- if (dump)
- fprintf (dump, "// Emitting template before %d: %s\n",
- INSN_UID (insn), b->name);
+ rtx insn, link, next, next_tail;
- ia64_emit_insn_before (gen_bundle_selector (GEN_INT (bundle_type)), insn);
+ next_tail = NEXT_INSN (tail);
+ for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ insn->call = 0;
+ for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
+ if (INSN_P (insn)
+ && ia64_safe_itanium_class (insn) == ITANIUM_CLASS_IALU)
+ {
+ for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
+ {
+ next = XEXP (link, 0);
+ if ((ia64_safe_itanium_class (next) == ITANIUM_CLASS_ST
+ || ia64_safe_itanium_class (next) == ITANIUM_CLASS_STF)
+ && ia64_st_address_bypass_p (insn, next))
+ break;
+ else if ((ia64_safe_itanium_class (next) == ITANIUM_CLASS_LD
+ || ia64_safe_itanium_class (next)
+ == ITANIUM_CLASS_FLD)
+ && ia64_ld_address_bypass_p (insn, next))
+ break;
+ }
+ insn->call = link != 0;
+ }
}
-/* We can't schedule more insns this cycle. Fix up the scheduling state
- and advance FIRST_SLOT and CUR.
- We have to distribute the insns that are currently found between
- FIRST_SLOT and CUR into the slots of the packet we have selected. So
- far, they are stored successively in the fields starting at FIRST_SLOT;
- now they must be moved to the correct slots.
- DUMP is the current scheduling dump file, or NULL. */
+/* We're beginning a new block. Initialize data structures as necessary. */
static void
-cycle_end_fill_slots (dump)
- FILE *dump;
+ia64_sched_init (FILE *dump ATTRIBUTE_UNUSED,
+ int sched_verbose ATTRIBUTE_UNUSED,
+ int max_ready ATTRIBUTE_UNUSED)
{
- const struct ia64_packet *packet = sched_data.packet;
- int slot, i;
- enum attr_type tmp_types[6];
- rtx tmp_insns[6];
-
- memcpy (tmp_types, sched_data.types, 6 * sizeof (enum attr_type));
- memcpy (tmp_insns, sched_data.insns, 6 * sizeof (rtx));
+#ifdef ENABLE_CHECKING
+ rtx insn;
- for (i = slot = sched_data.first_slot; i < sched_data.cur; i++)
- {
- enum attr_type t = tmp_types[i];
- if (t != ia64_safe_type (tmp_insns[i]))
+ if (reload_completed)
+ for (insn = NEXT_INSN (current_sched_info->prev_head);
+ insn != current_sched_info->next_tail;
+ insn = NEXT_INSN (insn))
+ if (SCHED_GROUP_P (insn))
abort ();
- while (! insn_matches_slot (packet, t, slot, tmp_insns[i]))
- {
- if (slot > sched_data.split)
- abort ();
- if (dump)
- fprintf (dump, "// Packet needs %s, have %s\n",
- type_names[packet->t[slot]], type_names[t]);
- sched_data.types[slot] = packet->t[slot];
- sched_data.insns[slot] = 0;
- sched_data.stopbit[slot] = 0;
-
- /* ??? TYPE_L instructions always fill up two slots, but we don't
- support TYPE_L nops. */
- if (packet->t[slot] == TYPE_L)
- abort ();
-
- slot++;
- }
-
- /* Do _not_ use T here. If T == TYPE_A, then we'd risk changing the
- actual slot type later. */
- sched_data.types[slot] = packet->t[slot];
- sched_data.insns[slot] = tmp_insns[i];
- sched_data.stopbit[slot] = 0;
- slot++;
-
- /* TYPE_L instructions always fill up two slots. */
- if (t == TYPE_L)
- {
- sched_data.types[slot] = packet->t[slot];
- sched_data.insns[slot] = 0;
- sched_data.stopbit[slot] = 0;
- slot++;
- }
- }
-
- /* This isn't right - there's no need to pad out until the forced split;
- the CPU will automatically split if an insn isn't ready. */
-#if 0
- while (slot < sched_data.split)
- {
- sched_data.types[slot] = packet->t[slot];
- sched_data.insns[slot] = 0;
- sched_data.stopbit[slot] = 0;
- slot++;
- }
#endif
-
- sched_data.first_slot = sched_data.cur = slot;
+ last_scheduled_insn = NULL_RTX;
+ init_insn_group_barriers ();
}
-/* Bundle rotations, as described in the Itanium optimization manual.
- We can rotate either one or both bundles out of the issue window.
- DUMP is the current scheduling dump file, or NULL. */
-
-static void
-rotate_one_bundle (dump)
- FILE *dump;
-{
- if (dump)
- fprintf (dump, "// Rotating one bundle.\n");
-
- finish_last_head (dump, 0);
- if (sched_data.cur > 3)
- {
- sched_data.cur -= 3;
- sched_data.first_slot -= 3;
- memmove (sched_data.types,
- sched_data.types + 3,
- sched_data.cur * sizeof *sched_data.types);
- memmove (sched_data.stopbit,
- sched_data.stopbit + 3,
- sched_data.cur * sizeof *sched_data.stopbit);
- memmove (sched_data.insns,
- sched_data.insns + 3,
- sched_data.cur * sizeof *sched_data.insns);
- sched_data.packet
- = &packets[(sched_data.packet->t2 - bundle) * NR_BUNDLES];
- }
- else
- {
- sched_data.cur = 0;
- sched_data.first_slot = 0;
- }
-}
+/* We are about to being issuing insns for this clock cycle.
+ Override the default sort algorithm to better slot instructions. */
-static void
-rotate_two_bundles (dump)
- FILE *dump;
+static int
+ia64_dfa_sched_reorder (FILE *dump, int sched_verbose, rtx *ready,
+ int *pn_ready, int clock_var ATTRIBUTE_UNUSED,
+ int reorder_type)
{
- if (dump)
- fprintf (dump, "// Rotating two bundles.\n");
-
- if (sched_data.cur == 0)
- return;
-
- finish_last_head (dump, 0);
- if (sched_data.cur > 3)
- finish_last_head (dump, 3);
- sched_data.cur = 0;
- sched_data.first_slot = 0;
-}
-
-/* We're beginning a new block. Initialize data structures as necessary. */
+ int n_asms;
+ int n_ready = *pn_ready;
+ rtx *e_ready = ready + n_ready;
+ rtx *insnp;
-static void
-ia64_sched_init (dump, sched_verbose, max_ready)
- FILE *dump ATTRIBUTE_UNUSED;
- int sched_verbose ATTRIBUTE_UNUSED;
- int max_ready;
-{
- static int initialized = 0;
+ if (sched_verbose)
+ fprintf (dump, "// ia64_dfa_sched_reorder (type %d):\n", reorder_type);
- if (! initialized)
+ if (reorder_type == 0)
{
- int b1, b2, i;
-
- initialized = 1;
-
- for (i = b1 = 0; b1 < NR_BUNDLES; b1++)
- {
- const struct bundle *t1 = bundle + b1;
- for (b2 = 0; b2 < NR_BUNDLES; b2++, i++)
- {
- const struct bundle *t2 = bundle + b2;
+ /* First, move all USEs, CLOBBERs and other crud out of the way. */
+ n_asms = 0;
+ for (insnp = ready; insnp < e_ready; insnp++)
+ if (insnp < e_ready)
+ {
+ rtx insn = *insnp;
+ enum attr_type t = ia64_safe_type (insn);
+ if (t == TYPE_UNKNOWN)
+ {
+ if (GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0)
+ {
+ rtx lowest = ready[n_asms];
+ ready[n_asms] = insn;
+ *insnp = lowest;
+ n_asms++;
+ }
+ else
+ {
+ rtx highest = ready[n_ready - 1];
+ ready[n_ready - 1] = insn;
+ *insnp = highest;
+ return 1;
+ }
+ }
+ }
- packets[i].t1 = t1;
- packets[i].t2 = t2;
- }
- }
- for (i = 0; i < NR_PACKETS; i++)
+ if (n_asms < n_ready)
{
- int j;
- for (j = 0; j < 3; j++)
- packets[i].t[j] = packets[i].t1->t[j];
- for (j = 0; j < 3; j++)
- packets[i].t[j + 3] = packets[i].t2->t[j];
- packets[i].first_split = itanium_split_issue (packets + i, 0);
+ /* Some normal insns to process. Skip the asms. */
+ ready += n_asms;
+ n_ready -= n_asms;
}
-
+ else if (n_ready > 0)
+ return 1;
}
- init_insn_group_barriers ();
-
- memset (&sched_data, 0, sizeof sched_data);
- sched_types = (enum attr_type *) xmalloc (max_ready
- * sizeof (enum attr_type));
- sched_ready = (rtx *) xmalloc (max_ready * sizeof (rtx));
-}
-
-/* See if the packet P can match the insns we have already scheduled. Return
- nonzero if so. In *PSLOT, we store the first slot that is available for
- more instructions if we choose this packet.
- SPLIT holds the last slot we can use, there's a split issue after it so
- scheduling beyond it would cause us to use more than one cycle. */
+ if (ia64_final_schedule)
+ {
+ int deleted = 0;
+ int nr_need_stop = 0;
-static int
-packet_matches_p (p, split, pslot)
- const struct ia64_packet *p;
- int split;
- int *pslot;
-{
- int filled = sched_data.cur;
- int first = sched_data.first_slot;
- int i, slot;
-
- /* First, check if the first of the two bundles must be a specific one (due
- to stop bits). */
- if (first > 0 && sched_data.stopbit[0] && p->t1->possible_stop != 1)
- return 0;
- if (first > 1 && sched_data.stopbit[1] && p->t1->possible_stop != 2)
- return 0;
+ for (insnp = ready; insnp < e_ready; insnp++)
+ if (safe_group_barrier_needed_p (*insnp))
+ nr_need_stop++;
- for (i = 0; i < first; i++)
- if (! insn_matches_slot (p, sched_data.types[i], i,
- sched_data.insns[i]))
- return 0;
- for (i = slot = first; i < filled; i++)
- {
- while (slot < split)
- {
- if (insn_matches_slot (p, sched_data.types[i], slot,
- sched_data.insns[i]))
- break;
- slot++;
- }
- if (slot == split)
+ if (reorder_type == 1 && n_ready == nr_need_stop)
return 0;
- slot++;
+ if (reorder_type == 0)
+ return 1;
+ insnp = e_ready;
+ /* Move down everything that needs a stop bit, preserving
+ relative order. */
+ while (insnp-- > ready + deleted)
+ while (insnp >= ready + deleted)
+ {
+ rtx insn = *insnp;
+ if (! safe_group_barrier_needed_p (insn))
+ break;
+ memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
+ *ready = insn;
+ deleted++;
+ }
+ n_ready -= deleted;
+ ready += deleted;
}
- if (pslot)
- *pslot = slot;
return 1;
}
-/* A frontend for itanium_split_issue. For a packet P and a slot
- number FIRST that describes the start of the current clock cycle,
- return the slot number of the first split issue. This function
- uses the cached number found in P if possible. */
+/* We are about to being issuing insns for this clock cycle. Override
+ the default sort algorithm to better slot instructions. */
static int
-get_split (p, first)
- const struct ia64_packet *p;
- int first;
+ia64_sched_reorder (FILE *dump, int sched_verbose, rtx *ready, int *pn_ready,
+ int clock_var)
{
- if (first == 0)
- return p->first_split;
- return itanium_split_issue (p, first);
+ return ia64_dfa_sched_reorder (dump, sched_verbose, ready,
+ pn_ready, clock_var, 0);
}
-/* Given N_READY insns in the array READY, whose types are found in the
- corresponding array TYPES, return the insn that is best suited to be
- scheduled in slot SLOT of packet P. */
+/* Like ia64_sched_reorder, but called after issuing each insn.
+ Override the default sort algorithm to better slot instructions. */
static int
-find_best_insn (ready, types, n_ready, p, slot)
- rtx *ready;
- enum attr_type *types;
- int n_ready;
- const struct ia64_packet *p;
- int slot;
-{
- int best = -1;
- int best_pri = 0;
- while (n_ready-- > 0)
- {
- rtx insn = ready[n_ready];
- if (! insn)
- continue;
- if (best >= 0 && INSN_PRIORITY (ready[n_ready]) < best_pri)
- break;
- /* If we have equally good insns, one of which has a stricter
- slot requirement, prefer the one with the stricter requirement. */
- if (best >= 0 && types[n_ready] == TYPE_A)
- continue;
- if (insn_matches_slot (p, types[n_ready], slot, insn))
- {
- best = n_ready;
- best_pri = INSN_PRIORITY (ready[best]);
+ia64_sched_reorder2 (FILE *dump ATTRIBUTE_UNUSED,
+ int sched_verbose ATTRIBUTE_UNUSED, rtx *ready,
+ int *pn_ready, int clock_var)
+{
+ if (ia64_tune == PROCESSOR_ITANIUM && reload_completed && last_scheduled_insn)
+ clocks [INSN_UID (last_scheduled_insn)] = clock_var;
+ return ia64_dfa_sched_reorder (dump, sched_verbose, ready, pn_ready,
+ clock_var, 1);
+}
- /* If there's no way we could get a stricter requirement, stop
- looking now. */
- if (types[n_ready] != TYPE_A
- && ia64_safe_itanium_requires_unit0 (ready[n_ready]))
- break;
- break;
- }
+/* We are about to issue INSN. Return the number of insns left on the
+ ready queue that can be issued this cycle. */
+
+static int
+ia64_variable_issue (FILE *dump ATTRIBUTE_UNUSED,
+ int sched_verbose ATTRIBUTE_UNUSED,
+ rtx insn ATTRIBUTE_UNUSED,
+ int can_issue_more ATTRIBUTE_UNUSED)
+{
+ last_scheduled_insn = insn;
+ memcpy (prev_cycle_state, curr_state, dfa_state_size);
+ if (reload_completed)
+ {
+ if (group_barrier_needed_p (insn))
+ abort ();
+ if (GET_CODE (insn) == CALL_INSN)
+ init_insn_group_barriers ();
+ stops_p [INSN_UID (insn)] = stop_before_p;
+ stop_before_p = 0;
}
- return best;
+ return 1;
}
-/* Select the best packet to use given the current scheduler state and the
- current ready list.
- READY is an array holding N_READY ready insns; TYPES is a corresponding
- array that holds their types. Store the best packet in *PPACKET and the
- number of insns that can be scheduled in the current cycle in *PBEST. */
+/* We are choosing insn from the ready queue. Return nonzero if INSN
+ can be chosen. */
-static void
-find_best_packet (pbest, ppacket, ready, types, n_ready)
- int *pbest;
- const struct ia64_packet **ppacket;
- rtx *ready;
- enum attr_type *types;
- int n_ready;
-{
- int first = sched_data.first_slot;
- int best = 0;
- int lowest_end = 6;
- const struct ia64_packet *best_packet = NULL;
- int i;
-
- for (i = 0; i < NR_PACKETS; i++)
- {
- const struct ia64_packet *p = packets + i;
- int slot;
- int split = get_split (p, first);
- int win = 0;
- int first_slot, last_slot;
- int b_nops = 0;
+static int
+ia64_first_cycle_multipass_dfa_lookahead_guard (rtx insn)
+{
+ if (insn == NULL_RTX || !INSN_P (insn))
+ abort ();
+ return (!reload_completed
+ || !safe_group_barrier_needed_p (insn));
+}
- if (! packet_matches_p (p, split, &first_slot))
- continue;
+/* The following variable value is pseudo-insn used by the DFA insn
+ scheduler to change the DFA state when the simulated clock is
+ increased. */
- memcpy (sched_ready, ready, n_ready * sizeof (rtx));
+static rtx dfa_pre_cycle_insn;
- win = 0;
- last_slot = 6;
- for (slot = first_slot; slot < split; slot++)
- {
- int insn_nr;
+/* We are about to being issuing INSN. Return nonzero if we can not
+ issue it on given cycle CLOCK and return zero if we should not sort
+ the ready queue on the next clock start. */
- /* Disallow a degenerate case where the first bundle doesn't
- contain anything but NOPs! */
- if (first_slot == 0 && win == 0 && slot == 3)
- {
- win = -1;
- break;
- }
+static int
+ia64_dfa_new_cycle (FILE *dump, int verbose, rtx insn, int last_clock,
+ int clock, int *sort_p)
+{
+ int setup_clocks_p = FALSE;
- insn_nr = find_best_insn (sched_ready, types, n_ready, p, slot);
- if (insn_nr >= 0)
- {
- sched_ready[insn_nr] = 0;
- last_slot = slot;
- win++;
- }
- else if (p->t[slot] == TYPE_B)
- b_nops++;
- }
- /* We must disallow MBB/BBB packets if any of their B slots would be
- filled with nops. */
- if (last_slot < 3)
+ if (insn == NULL_RTX || !INSN_P (insn))
+ abort ();
+ if ((reload_completed && safe_group_barrier_needed_p (insn))
+ || (last_scheduled_insn
+ && (GET_CODE (last_scheduled_insn) == CALL_INSN
+ || GET_CODE (PATTERN (last_scheduled_insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (last_scheduled_insn)) >= 0)))
+ {
+ init_insn_group_barriers ();
+ if (verbose && dump)
+ fprintf (dump, "// Stop should be before %d%s\n", INSN_UID (insn),
+ last_clock == clock ? " + cycle advance" : "");
+ stop_before_p = 1;
+ if (last_clock == clock)
{
- if (p->t[1] == TYPE_B && (b_nops || last_slot < 2))
- win = -1;
+ state_transition (curr_state, dfa_stop_insn);
+ if (TARGET_EARLY_STOP_BITS)
+ *sort_p = (last_scheduled_insn == NULL_RTX
+ || GET_CODE (last_scheduled_insn) != CALL_INSN);
+ else
+ *sort_p = 0;
+ return 1;
}
+ else if (reload_completed)
+ setup_clocks_p = TRUE;
+ if (GET_CODE (PATTERN (last_scheduled_insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (last_scheduled_insn)) >= 0)
+ state_reset (curr_state);
else
{
- if (p->t[4] == TYPE_B && (b_nops || last_slot < 5))
- win = -1;
+ memcpy (curr_state, prev_cycle_state, dfa_state_size);
+ state_transition (curr_state, dfa_stop_insn);
+ state_transition (curr_state, dfa_pre_cycle_insn);
+ state_transition (curr_state, NULL);
}
+ }
+ else if (reload_completed)
+ setup_clocks_p = TRUE;
+ if (setup_clocks_p && ia64_tune == PROCESSOR_ITANIUM
+ && GET_CODE (PATTERN (insn)) != ASM_INPUT
+ && asm_noperands (PATTERN (insn)) < 0)
+ {
+ enum attr_itanium_class c = ia64_safe_itanium_class (insn);
- if (win > best
- || (win == best && last_slot < lowest_end))
+ if (c != ITANIUM_CLASS_MMMUL && c != ITANIUM_CLASS_MMSHF)
{
- best = win;
- lowest_end = last_slot;
- best_packet = p;
+ rtx link;
+ int d = -1;
+
+ for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
+ if (REG_NOTE_KIND (link) == 0)
+ {
+ enum attr_itanium_class dep_class;
+ rtx dep_insn = XEXP (link, 0);
+
+ dep_class = ia64_safe_itanium_class (dep_insn);
+ if ((dep_class == ITANIUM_CLASS_MMMUL
+ || dep_class == ITANIUM_CLASS_MMSHF)
+ && last_clock - clocks [INSN_UID (dep_insn)] < 4
+ && (d < 0
+ || last_clock - clocks [INSN_UID (dep_insn)] < d))
+ d = last_clock - clocks [INSN_UID (dep_insn)];
+ }
+ if (d >= 0)
+ add_cycles [INSN_UID (insn)] = 3 - d;
}
}
- *pbest = best;
- *ppacket = best_packet;
+ return 0;
}
-/* Reorder the ready list so that the insns that can be issued in this cycle
- are found in the correct order at the end of the list.
- DUMP is the scheduling dump file, or NULL. READY points to the start,
- E_READY to the end of the ready list. MAY_FAIL determines what should be
- done if no insns can be scheduled in this cycle: if it is zero, we abort,
- otherwise we return 0.
- Return 1 if any insns can be scheduled in this cycle. */
+
-static int
-itanium_reorder (dump, ready, e_ready, may_fail)
- FILE *dump;
- rtx *ready;
- rtx *e_ready;
- int may_fail;
-{
- const struct ia64_packet *best_packet;
- int n_ready = e_ready - ready;
- int first = sched_data.first_slot;
- int i, best, best_split, filled;
+/* The following page contains abstract data `bundle states' which are
+ used for bundling insns (inserting nops and template generation). */
+
+/* The following describes state of insn bundling. */
+
+struct bundle_state
+{
+ /* Unique bundle state number to identify them in the debugging
+ output */
+ int unique_num;
+ rtx insn; /* corresponding insn, NULL for the 1st and the last state */
+ /* number nops before and after the insn */
+ short before_nops_num, after_nops_num;
+ int insn_num; /* insn number (0 - for initial state, 1 - for the 1st
+ insn */
+ int cost; /* cost of the state in cycles */
+ int accumulated_insns_num; /* number of all previous insns including
+ nops. L is considered as 2 insns */
+ int branch_deviation; /* deviation of previous branches from 3rd slots */
+ struct bundle_state *next; /* next state with the same insn_num */
+ struct bundle_state *originator; /* originator (previous insn state) */
+ /* All bundle states are in the following chain. */
+ struct bundle_state *allocated_states_chain;
+ /* The DFA State after issuing the insn and the nops. */
+ state_t dfa_state;
+};
- for (i = 0; i < n_ready; i++)
- sched_types[i] = ia64_safe_type (ready[i]);
+/* The following is map insn number to the corresponding bundle state. */
- find_best_packet (&best, &best_packet, ready, sched_types, n_ready);
+static struct bundle_state **index_to_bundle_states;
- if (best == 0)
- {
- if (may_fail)
- return 0;
- abort ();
- }
+/* The unique number of next bundle state. */
- if (dump)
- {
- fprintf (dump, "// Selected bundles: %s %s (%d insns)\n",
- best_packet->t1->name,
- best_packet->t2 ? best_packet->t2->name : NULL, best);
- }
+static int bundle_states_num;
- best_split = itanium_split_issue (best_packet, first);
- packet_matches_p (best_packet, best_split, &filled);
+/* All allocated bundle states are in the following chain. */
- for (i = filled; i < best_split; i++)
- {
- int insn_nr;
+static struct bundle_state *allocated_bundle_states_chain;
- insn_nr = find_best_insn (ready, sched_types, n_ready, best_packet, i);
- if (insn_nr >= 0)
- {
- rtx insn = ready[insn_nr];
- memmove (ready + insn_nr, ready + insn_nr + 1,
- (n_ready - insn_nr - 1) * sizeof (rtx));
- memmove (sched_types + insn_nr, sched_types + insn_nr + 1,
- (n_ready - insn_nr - 1) * sizeof (enum attr_type));
- ready[--n_ready] = insn;
- }
- }
+/* All allocated but not used bundle states are in the following
+ chain. */
- sched_data.packet = best_packet;
- sched_data.split = best_split;
- return 1;
-}
+static struct bundle_state *free_bundle_state_chain;
-/* Dump information about the current scheduling state to file DUMP. */
-static void
-dump_current_packet (dump)
- FILE *dump;
+/* The following function returns a free bundle state. */
+
+static struct bundle_state *
+get_free_bundle_state (void)
{
- int i;
- fprintf (dump, "// %d slots filled:", sched_data.cur);
- for (i = 0; i < sched_data.first_slot; i++)
+ struct bundle_state *result;
+
+ if (free_bundle_state_chain != NULL)
{
- rtx insn = sched_data.insns[i];
- fprintf (dump, " %s", type_names[sched_data.types[i]]);
- if (insn)
- fprintf (dump, "/%s", type_names[ia64_safe_type (insn)]);
- if (sched_data.stopbit[i])
- fprintf (dump, " ;;");
+ result = free_bundle_state_chain;
+ free_bundle_state_chain = result->next;
}
- fprintf (dump, " :::");
- for (i = sched_data.first_slot; i < sched_data.cur; i++)
+ else
{
- rtx insn = sched_data.insns[i];
- enum attr_type t = ia64_safe_type (insn);
- fprintf (dump, " (%d) %s", INSN_UID (insn), type_names[t]);
+ result = xmalloc (sizeof (struct bundle_state));
+ result->dfa_state = xmalloc (dfa_state_size);
+ result->allocated_states_chain = allocated_bundle_states_chain;
+ allocated_bundle_states_chain = result;
}
- fprintf (dump, "\n");
+ result->unique_num = bundle_states_num++;
+ return result;
+
}
-/* Schedule a stop bit. DUMP is the current scheduling dump file, or
- NULL. */
+/* The following function frees given bundle state. */
static void
-schedule_stop (dump)
- FILE *dump;
+free_bundle_state (struct bundle_state *state)
{
- const struct ia64_packet *best = sched_data.packet;
- int i;
- int best_stop = 6;
+ state->next = free_bundle_state_chain;
+ free_bundle_state_chain = state;
+}
- if (dump)
- fprintf (dump, "// Stop bit, cur = %d.\n", sched_data.cur);
+/* Start work with abstract data `bundle states'. */
- if (sched_data.cur == 0)
- {
- if (dump)
- fprintf (dump, "// At start of bundle, so nothing to do.\n");
+static void
+initiate_bundle_states (void)
+{
+ bundle_states_num = 0;
+ free_bundle_state_chain = NULL;
+ allocated_bundle_states_chain = NULL;
+}
- rotate_two_bundles (NULL);
- return;
- }
+/* Finish work with abstract data `bundle states'. */
- for (i = -1; i < NR_PACKETS; i++)
+static void
+finish_bundle_states (void)
+{
+ struct bundle_state *curr_state, *next_state;
+
+ for (curr_state = allocated_bundle_states_chain;
+ curr_state != NULL;
+ curr_state = next_state)
{
- /* This is a slight hack to give the current packet the first chance.
- This is done to avoid e.g. switching from MIB to MBB bundles. */
- const struct ia64_packet *p = (i >= 0 ? packets + i : sched_data.packet);
- int split = get_split (p, sched_data.first_slot);
- const struct bundle *compare;
- int next, stoppos;
+ next_state = curr_state->allocated_states_chain;
+ free (curr_state->dfa_state);
+ free (curr_state);
+ }
+}
- if (! packet_matches_p (p, split, &next))
- continue;
+/* Hash table of the bundle states. The key is dfa_state and insn_num
+ of the bundle states. */
- compare = next > 3 ? p->t2 : p->t1;
+static htab_t bundle_state_table;
- stoppos = 3;
- if (compare->possible_stop)
- stoppos = compare->possible_stop;
- if (next > 3)
- stoppos += 3;
+/* The function returns hash of BUNDLE_STATE. */
- if (stoppos < next || stoppos >= best_stop)
- {
- if (compare->possible_stop == 0)
- continue;
- stoppos = (next > 3 ? 6 : 3);
- }
- if (stoppos < next || stoppos >= best_stop)
- continue;
+static unsigned
+bundle_state_hash (const void *bundle_state)
+{
+ const struct bundle_state *state = (struct bundle_state *) bundle_state;
+ unsigned result, i;
+
+ for (result = i = 0; i < dfa_state_size; i++)
+ result += (((unsigned char *) state->dfa_state) [i]
+ << ((i % CHAR_BIT) * 3 + CHAR_BIT));
+ return result + state->insn_num;
+}
+
+/* The function returns nonzero if the bundle state keys are equal. */
+
+static int
+bundle_state_eq_p (const void *bundle_state_1, const void *bundle_state_2)
+{
+ const struct bundle_state * state1 = (struct bundle_state *) bundle_state_1;
+ const struct bundle_state * state2 = (struct bundle_state *) bundle_state_2;
+
+ return (state1->insn_num == state2->insn_num
+ && memcmp (state1->dfa_state, state2->dfa_state,
+ dfa_state_size) == 0);
+}
- if (dump)
- fprintf (dump, "// switching from %s %s to %s %s (stop at %d)\n",
- best->t1->name, best->t2->name, p->t1->name, p->t2->name,
- stoppos);
+/* The function inserts the BUNDLE_STATE into the hash table. The
+ function returns nonzero if the bundle has been inserted into the
+ table. The table contains the best bundle state with given key. */
- best_stop = stoppos;
- best = p;
+static int
+insert_bundle_state (struct bundle_state *bundle_state)
+{
+ void **entry_ptr;
+
+ entry_ptr = htab_find_slot (bundle_state_table, bundle_state, 1);
+ if (*entry_ptr == NULL)
+ {
+ bundle_state->next = index_to_bundle_states [bundle_state->insn_num];
+ index_to_bundle_states [bundle_state->insn_num] = bundle_state;
+ *entry_ptr = (void *) bundle_state;
+ return TRUE;
}
+ else if (bundle_state->cost < ((struct bundle_state *) *entry_ptr)->cost
+ || (bundle_state->cost == ((struct bundle_state *) *entry_ptr)->cost
+ && (((struct bundle_state *)*entry_ptr)->accumulated_insns_num
+ > bundle_state->accumulated_insns_num
+ || (((struct bundle_state *)
+ *entry_ptr)->accumulated_insns_num
+ == bundle_state->accumulated_insns_num
+ && ((struct bundle_state *)
+ *entry_ptr)->branch_deviation
+ > bundle_state->branch_deviation))))
- sched_data.packet = best;
- cycle_end_fill_slots (dump);
- while (sched_data.cur < best_stop)
{
- sched_data.types[sched_data.cur] = best->t[sched_data.cur];
- sched_data.insns[sched_data.cur] = 0;
- sched_data.stopbit[sched_data.cur] = 0;
- sched_data.cur++;
+ struct bundle_state temp;
+
+ temp = *(struct bundle_state *) *entry_ptr;
+ *(struct bundle_state *) *entry_ptr = *bundle_state;
+ ((struct bundle_state *) *entry_ptr)->next = temp.next;
+ *bundle_state = temp;
}
- sched_data.stopbit[sched_data.cur - 1] = 1;
- sched_data.first_slot = best_stop;
+ return FALSE;
+}
- if (dump)
- dump_current_packet (dump);
+/* Start work with the hash table. */
+
+static void
+initiate_bundle_state_table (void)
+{
+ bundle_state_table = htab_create (50, bundle_state_hash, bundle_state_eq_p,
+ (htab_del) 0);
}
-/* If necessary, perform one or two rotations on the scheduling state.
- This should only be called if we are starting a new cycle. */
+/* Finish work with the hash table. */
static void
-maybe_rotate (dump)
- FILE *dump;
+finish_bundle_state_table (void)
{
- cycle_end_fill_slots (dump);
- if (sched_data.cur == 6)
- rotate_two_bundles (dump);
- else if (sched_data.cur >= 3)
- rotate_one_bundle (dump);
- sched_data.first_slot = sched_data.cur;
+ htab_delete (bundle_state_table);
}
-/* The clock cycle when ia64_sched_reorder was last called. */
-static int prev_cycle;
+
-/* The first insn scheduled in the previous cycle. This is the saved
- value of sched_data.first_slot. */
-static int prev_first;
+/* The following variable is a insn `nop' used to check bundle states
+ with different number of inserted nops. */
-/* Emit NOPs to fill the delay between PREV_CYCLE and CLOCK_VAR. Used to
- pad out the delay between MM (shifts, etc.) and integer operations. */
+static rtx ia64_nop;
-static void
-nop_cycles_until (clock_var, dump)
- int clock_var;
- FILE *dump;
+/* The following function tries to issue NOPS_NUM nops for the current
+ state without advancing processor cycle. If it failed, the
+ function returns FALSE and frees the current state. */
+
+static int
+try_issue_nops (struct bundle_state *curr_state, int nops_num)
{
- int prev_clock = prev_cycle;
- int cycles_left = clock_var - prev_clock;
- bool did_stop = false;
+ int i;
- /* Finish the previous cycle; pad it out with NOPs. */
- if (sched_data.cur == 3)
+ for (i = 0; i < nops_num; i++)
+ if (state_transition (curr_state->dfa_state, ia64_nop) >= 0)
+ {
+ free_bundle_state (curr_state);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* The following function tries to issue INSN for the current
+ state without advancing processor cycle. If it failed, the
+ function returns FALSE and frees the current state. */
+
+static int
+try_issue_insn (struct bundle_state *curr_state, rtx insn)
+{
+ if (insn && state_transition (curr_state->dfa_state, insn) >= 0)
{
- sched_emit_insn (gen_insn_group_barrier (GEN_INT (3)));
- did_stop = true;
- maybe_rotate (dump);
+ free_bundle_state (curr_state);
+ return FALSE;
}
- else if (sched_data.cur > 0)
- {
- int need_stop = 0;
- int split = itanium_split_issue (sched_data.packet, prev_first);
-
- if (sched_data.cur < 3 && split > 3)
- {
- split = 3;
- need_stop = 1;
- }
+ return TRUE;
+}
- if (split > sched_data.cur)
- {
- int i;
- for (i = sched_data.cur; i < split; i++)
- {
- rtx t = sched_emit_insn (gen_nop_type (sched_data.packet->t[i]));
- sched_data.types[i] = sched_data.packet->t[i];
- sched_data.insns[i] = t;
- sched_data.stopbit[i] = 0;
- }
- sched_data.cur = split;
- }
+/* The following function tries to issue BEFORE_NOPS_NUM nops and INSN
+ starting with ORIGINATOR without advancing processor cycle. If
+ TRY_BUNDLE_END_P is TRUE, the function also/only (if
+ ONLY_BUNDLE_END_P is TRUE) tries to issue nops to fill all bundle.
+ If it was successful, the function creates new bundle state and
+ insert into the hash table and into `index_to_bundle_states'. */
- if (! need_stop && sched_data.cur > 0 && sched_data.cur < 6
- && cycles_left > 1)
+static void
+issue_nops_and_insn (struct bundle_state *originator, int before_nops_num,
+ rtx insn, int try_bundle_end_p, int only_bundle_end_p)
+{
+ struct bundle_state *curr_state;
+
+ curr_state = get_free_bundle_state ();
+ memcpy (curr_state->dfa_state, originator->dfa_state, dfa_state_size);
+ curr_state->insn = insn;
+ curr_state->insn_num = originator->insn_num + 1;
+ curr_state->cost = originator->cost;
+ curr_state->originator = originator;
+ curr_state->before_nops_num = before_nops_num;
+ curr_state->after_nops_num = 0;
+ curr_state->accumulated_insns_num
+ = originator->accumulated_insns_num + before_nops_num;
+ curr_state->branch_deviation = originator->branch_deviation;
+ if (insn == NULL_RTX)
+ abort ();
+ else if (INSN_CODE (insn) == CODE_FOR_insn_group_barrier)
+ {
+ if (GET_MODE (insn) == TImode)
+ abort ();
+ if (!try_issue_nops (curr_state, before_nops_num))
+ return;
+ if (!try_issue_insn (curr_state, insn))
+ return;
+ memcpy (temp_dfa_state, curr_state->dfa_state, dfa_state_size);
+ if (state_transition (temp_dfa_state, dfa_pre_cycle_insn) >= 0
+ && curr_state->accumulated_insns_num % 3 != 0)
{
- int i;
- for (i = sched_data.cur; i < 6; i++)
- {
- rtx t = sched_emit_insn (gen_nop_type (sched_data.packet->t[i]));
- sched_data.types[i] = sched_data.packet->t[i];
- sched_data.insns[i] = t;
- sched_data.stopbit[i] = 0;
- }
- sched_data.cur = 6;
- cycles_left--;
- need_stop = 1;
+ free_bundle_state (curr_state);
+ return;
}
-
- if (need_stop || sched_data.cur == 6)
+ }
+ else if (GET_MODE (insn) != TImode)
+ {
+ if (!try_issue_nops (curr_state, before_nops_num))
+ return;
+ if (!try_issue_insn (curr_state, insn))
+ return;
+ curr_state->accumulated_insns_num++;
+ if (GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0)
+ abort ();
+ if (ia64_safe_type (insn) == TYPE_L)
+ curr_state->accumulated_insns_num++;
+ }
+ else
+ {
+ state_transition (curr_state->dfa_state, dfa_pre_cycle_insn);
+ state_transition (curr_state->dfa_state, NULL);
+ curr_state->cost++;
+ if (!try_issue_nops (curr_state, before_nops_num))
+ return;
+ if (!try_issue_insn (curr_state, insn))
+ return;
+ curr_state->accumulated_insns_num++;
+ if (GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0)
{
- sched_emit_insn (gen_insn_group_barrier (GEN_INT (3)));
- did_stop = true;
+ /* Finish bundle containing asm insn. */
+ curr_state->after_nops_num
+ = 3 - curr_state->accumulated_insns_num % 3;
+ curr_state->accumulated_insns_num
+ += 3 - curr_state->accumulated_insns_num % 3;
}
- maybe_rotate (dump);
+ else if (ia64_safe_type (insn) == TYPE_L)
+ curr_state->accumulated_insns_num++;
}
-
- cycles_left--;
- while (cycles_left > 0)
+ if (ia64_safe_type (insn) == TYPE_B)
+ curr_state->branch_deviation
+ += 2 - (curr_state->accumulated_insns_num - 1) % 3;
+ if (try_bundle_end_p && curr_state->accumulated_insns_num % 3 != 0)
{
- sched_emit_insn (gen_bundle_selector (GEN_INT (0)));
- sched_emit_insn (gen_nop_type (TYPE_M));
- sched_emit_insn (gen_nop_type (TYPE_I));
- if (cycles_left > 1)
+ if (!only_bundle_end_p && insert_bundle_state (curr_state))
{
- sched_emit_insn (gen_insn_group_barrier (GEN_INT (2)));
- cycles_left--;
+ state_t dfa_state;
+ struct bundle_state *curr_state1;
+ struct bundle_state *allocated_states_chain;
+
+ curr_state1 = get_free_bundle_state ();
+ dfa_state = curr_state1->dfa_state;
+ allocated_states_chain = curr_state1->allocated_states_chain;
+ *curr_state1 = *curr_state;
+ curr_state1->dfa_state = dfa_state;
+ curr_state1->allocated_states_chain = allocated_states_chain;
+ memcpy (curr_state1->dfa_state, curr_state->dfa_state,
+ dfa_state_size);
+ curr_state = curr_state1;
}
- sched_emit_insn (gen_nop_type (TYPE_I));
- sched_emit_insn (gen_insn_group_barrier (GEN_INT (3)));
- did_stop = true;
- cycles_left--;
+ if (!try_issue_nops (curr_state,
+ 3 - curr_state->accumulated_insns_num % 3))
+ return;
+ curr_state->after_nops_num
+ = 3 - curr_state->accumulated_insns_num % 3;
+ curr_state->accumulated_insns_num
+ += 3 - curr_state->accumulated_insns_num % 3;
}
-
- if (did_stop)
- init_insn_group_barriers ();
+ if (!insert_bundle_state (curr_state))
+ free_bundle_state (curr_state);
+ return;
}
-/* We are about to being issuing insns for this clock cycle.
- Override the default sort algorithm to better slot instructions. */
+/* The following function returns position in the two window bundle
+ for given STATE. */
static int
-ia64_internal_sched_reorder (dump, sched_verbose, ready, pn_ready,
- reorder_type, clock_var)
- FILE *dump ATTRIBUTE_UNUSED;
- int sched_verbose ATTRIBUTE_UNUSED;
- rtx *ready;
- int *pn_ready;
- int reorder_type, clock_var;
+get_max_pos (state_t state)
{
- int n_asms;
- int n_ready = *pn_ready;
- rtx *e_ready = ready + n_ready;
- rtx *insnp;
+ if (cpu_unit_reservation_p (state, pos_6))
+ return 6;
+ else if (cpu_unit_reservation_p (state, pos_5))
+ return 5;
+ else if (cpu_unit_reservation_p (state, pos_4))
+ return 4;
+ else if (cpu_unit_reservation_p (state, pos_3))
+ return 3;
+ else if (cpu_unit_reservation_p (state, pos_2))
+ return 2;
+ else if (cpu_unit_reservation_p (state, pos_1))
+ return 1;
+ else
+ return 0;
+}
- if (sched_verbose)
- {
- fprintf (dump, "// ia64_sched_reorder (type %d):\n", reorder_type);
- dump_current_packet (dump);
- }
+/* The function returns code of a possible template for given position
+ and state. The function should be called only with 2 values of
+ position equal to 3 or 6. */
- /* Work around the pipeline flush that will occurr if the results of
- an MM instruction are accessed before the result is ready. Intel
- documentation says this only happens with IALU, ISHF, ILOG, LD,
- and ST consumers, but experimental evidence shows that *any* non-MM
- type instruction will incurr the flush. */
- if (reorder_type == 0 && clock_var > 0 && ia64_final_schedule)
+static int
+get_template (state_t state, int pos)
+{
+ switch (pos)
{
- for (insnp = ready; insnp < e_ready; insnp++)
- {
- rtx insn = *insnp, link;
- enum attr_itanium_class t = ia64_safe_itanium_class (insn);
+ case 3:
+ if (cpu_unit_reservation_p (state, _0mii_))
+ return 0;
+ else if (cpu_unit_reservation_p (state, _0mmi_))
+ return 1;
+ else if (cpu_unit_reservation_p (state, _0mfi_))
+ return 2;
+ else if (cpu_unit_reservation_p (state, _0mmf_))
+ return 3;
+ else if (cpu_unit_reservation_p (state, _0bbb_))
+ return 4;
+ else if (cpu_unit_reservation_p (state, _0mbb_))
+ return 5;
+ else if (cpu_unit_reservation_p (state, _0mib_))
+ return 6;
+ else if (cpu_unit_reservation_p (state, _0mmb_))
+ return 7;
+ else if (cpu_unit_reservation_p (state, _0mfb_))
+ return 8;
+ else if (cpu_unit_reservation_p (state, _0mlx_))
+ return 9;
+ else
+ abort ();
+ case 6:
+ if (cpu_unit_reservation_p (state, _1mii_))
+ return 0;
+ else if (cpu_unit_reservation_p (state, _1mmi_))
+ return 1;
+ else if (cpu_unit_reservation_p (state, _1mfi_))
+ return 2;
+ else if (_1mmf_ >= 0 && cpu_unit_reservation_p (state, _1mmf_))
+ return 3;
+ else if (cpu_unit_reservation_p (state, _1bbb_))
+ return 4;
+ else if (cpu_unit_reservation_p (state, _1mbb_))
+ return 5;
+ else if (cpu_unit_reservation_p (state, _1mib_))
+ return 6;
+ else if (cpu_unit_reservation_p (state, _1mmb_))
+ return 7;
+ else if (cpu_unit_reservation_p (state, _1mfb_))
+ return 8;
+ else if (cpu_unit_reservation_p (state, _1mlx_))
+ return 9;
+ else
+ abort ();
+ default:
+ abort ();
+ }
+}
- if (t == ITANIUM_CLASS_MMMUL
- || t == ITANIUM_CLASS_MMSHF
- || t == ITANIUM_CLASS_MMSHFI)
- continue;
+/* The following function returns an insn important for insn bundling
+ followed by INSN and before TAIL. */
- for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
- if (REG_NOTE_KIND (link) == 0)
- {
- rtx other = XEXP (link, 0);
- enum attr_itanium_class t0 = ia64_safe_itanium_class (other);
- if (t0 == ITANIUM_CLASS_MMSHF || t0 == ITANIUM_CLASS_MMMUL)
- {
- nop_cycles_until (clock_var, sched_verbose ? dump : NULL);
- goto out;
- }
- }
- }
- }
- out:
+static rtx
+get_next_important_insn (rtx insn, rtx tail)
+{
+ for (; insn && insn != tail; insn = NEXT_INSN (insn))
+ if (INSN_P (insn)
+ && ia64_safe_itanium_class (insn) != ITANIUM_CLASS_IGNORE
+ && GET_CODE (PATTERN (insn)) != USE
+ && GET_CODE (PATTERN (insn)) != CLOBBER)
+ return insn;
+ return NULL_RTX;
+}
- prev_first = sched_data.first_slot;
- prev_cycle = clock_var;
+/* The following function does insn bundling. Bundling means
+ inserting templates and nop insns to fit insn groups into permitted
+ templates. Instruction scheduling uses NDFA (non-deterministic
+ finite automata) encoding informations about the templates and the
+ inserted nops. Nondeterminism of the automata permits follows
+ all possible insn sequences very fast.
+
+ Unfortunately it is not possible to get information about inserting
+ nop insns and used templates from the automata states. The
+ automata only says that we can issue an insn possibly inserting
+ some nops before it and using some template. Therefore insn
+ bundling in this function is implemented by using DFA
+ (deterministic finite automata). We follows all possible insn
+ sequences by inserting 0-2 nops (that is what the NDFA describe for
+ insn scheduling) before/after each insn being bundled. We know the
+ start of simulated processor cycle from insn scheduling (insn
+ starting a new cycle has TImode).
+
+ Simple implementation of insn bundling would create enormous
+ number of possible insn sequences satisfying information about new
+ cycle ticks taken from the insn scheduling. To make the algorithm
+ practical we use dynamic programming. Each decision (about
+ inserting nops and implicitly about previous decisions) is described
+ by structure bundle_state (see above). If we generate the same
+ bundle state (key is automaton state after issuing the insns and
+ nops for it), we reuse already generated one. As consequence we
+ reject some decisions which can not improve the solution and
+ reduce memory for the algorithm.
+
+ When we reach the end of EBB (extended basic block), we choose the
+ best sequence and then, moving back in EBB, insert templates for
+ the best alternative. The templates are taken from querying
+ automaton state for each insn in chosen bundle states.
+
+ So the algorithm makes two (forward and backward) passes through
+ EBB. There is an additional forward pass through EBB for Itanium1
+ processor. This pass inserts more nops to make dependency between
+ a producer insn and MMMUL/MMSHF at least 4 cycles long. */
- if (reorder_type == 0)
- maybe_rotate (sched_verbose ? dump : NULL);
+static void
+bundling (FILE *dump, int verbose, rtx prev_head_insn, rtx tail)
+{
+ struct bundle_state *curr_state, *next_state, *best_state;
+ rtx insn, next_insn;
+ int insn_num;
+ int i, bundle_end_p, only_bundle_end_p, asm_p;
+ int pos = 0, max_pos, template0, template1;
+ rtx b;
+ rtx nop;
+ enum attr_type type;
- /* First, move all USEs, CLOBBERs and other crud out of the way. */
- n_asms = 0;
- for (insnp = ready; insnp < e_ready; insnp++)
- if (insnp < e_ready)
+ insn_num = 0;
+ /* Count insns in the EBB. */
+ for (insn = NEXT_INSN (prev_head_insn);
+ insn && insn != tail;
+ insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ insn_num++;
+ if (insn_num == 0)
+ return;
+ bundling_p = 1;
+ dfa_clean_insn_cache ();
+ initiate_bundle_state_table ();
+ index_to_bundle_states = xmalloc ((insn_num + 2)
+ * sizeof (struct bundle_state *));
+ /* First (forward) pass -- generation of bundle states. */
+ curr_state = get_free_bundle_state ();
+ curr_state->insn = NULL;
+ curr_state->before_nops_num = 0;
+ curr_state->after_nops_num = 0;
+ curr_state->insn_num = 0;
+ curr_state->cost = 0;
+ curr_state->accumulated_insns_num = 0;
+ curr_state->branch_deviation = 0;
+ curr_state->next = NULL;
+ curr_state->originator = NULL;
+ state_reset (curr_state->dfa_state);
+ index_to_bundle_states [0] = curr_state;
+ insn_num = 0;
+ /* Shift cycle mark if it is put on insn which could be ignored. */
+ for (insn = NEXT_INSN (prev_head_insn);
+ insn != tail;
+ insn = NEXT_INSN (insn))
+ if (INSN_P (insn)
+ && (ia64_safe_itanium_class (insn) == ITANIUM_CLASS_IGNORE
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ && GET_MODE (insn) == TImode)
{
- rtx insn = *insnp;
- enum attr_type t = ia64_safe_type (insn);
- if (t == TYPE_UNKNOWN)
+ PUT_MODE (insn, VOIDmode);
+ for (next_insn = NEXT_INSN (insn);
+ next_insn != tail;
+ next_insn = NEXT_INSN (next_insn))
+ if (INSN_P (next_insn)
+ && ia64_safe_itanium_class (next_insn) != ITANIUM_CLASS_IGNORE
+ && GET_CODE (PATTERN (next_insn)) != USE
+ && GET_CODE (PATTERN (next_insn)) != CLOBBER)
+ {
+ PUT_MODE (next_insn, TImode);
+ break;
+ }
+ }
+ /* Froward pass: generation of bundle states. */
+ for (insn = get_next_important_insn (NEXT_INSN (prev_head_insn), tail);
+ insn != NULL_RTX;
+ insn = next_insn)
+ {
+ if (!INSN_P (insn)
+ || ia64_safe_itanium_class (insn) == ITANIUM_CLASS_IGNORE
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ abort ();
+ type = ia64_safe_type (insn);
+ next_insn = get_next_important_insn (NEXT_INSN (insn), tail);
+ insn_num++;
+ index_to_bundle_states [insn_num] = NULL;
+ for (curr_state = index_to_bundle_states [insn_num - 1];
+ curr_state != NULL;
+ curr_state = next_state)
+ {
+ pos = curr_state->accumulated_insns_num % 3;
+ next_state = curr_state->next;
+ /* We must fill up the current bundle in order to start a
+ subsequent asm insn in a new bundle. Asm insn is always
+ placed in a separate bundle. */
+ only_bundle_end_p
+ = (next_insn != NULL_RTX
+ && INSN_CODE (insn) == CODE_FOR_insn_group_barrier
+ && ia64_safe_type (next_insn) == TYPE_UNKNOWN);
+ /* We may fill up the current bundle if it is the cycle end
+ without a group barrier. */
+ bundle_end_p
+ = (only_bundle_end_p || next_insn == NULL_RTX
+ || (GET_MODE (next_insn) == TImode
+ && INSN_CODE (insn) != CODE_FOR_insn_group_barrier));
+ if (type == TYPE_F || type == TYPE_B || type == TYPE_L
+ || type == TYPE_S
+ /* We need to insert 2 nops for cases like M_MII. To
+ guarantee issuing all insns on the same cycle for
+ Itanium 1, we need to issue 2 nops after the first M
+ insn (MnnMII where n is a nop insn). */
+ || ((type == TYPE_M || type == TYPE_A)
+ && ia64_tune == PROCESSOR_ITANIUM
+ && !bundle_end_p && pos == 1))
+ issue_nops_and_insn (curr_state, 2, insn, bundle_end_p,
+ only_bundle_end_p);
+ issue_nops_and_insn (curr_state, 1, insn, bundle_end_p,
+ only_bundle_end_p);
+ issue_nops_and_insn (curr_state, 0, insn, bundle_end_p,
+ only_bundle_end_p);
+ }
+ if (index_to_bundle_states [insn_num] == NULL)
+ abort ();
+ for (curr_state = index_to_bundle_states [insn_num];
+ curr_state != NULL;
+ curr_state = curr_state->next)
+ if (verbose >= 2 && dump)
{
- if (GET_CODE (PATTERN (insn)) == ASM_INPUT
- || asm_noperands (PATTERN (insn)) >= 0)
- {
- rtx lowest = ready[n_asms];
- ready[n_asms] = insn;
- *insnp = lowest;
- n_asms++;
- }
- else
- {
- rtx highest = ready[n_ready - 1];
- ready[n_ready - 1] = insn;
- *insnp = highest;
- if (ia64_final_schedule && group_barrier_needed_p (insn))
- {
- schedule_stop (sched_verbose ? dump : NULL);
- sched_data.last_was_stop = 1;
- maybe_rotate (sched_verbose ? dump : NULL);
- }
-
- return 1;
- }
+ /* This structure is taken from generated code of the
+ pipeline hazard recognizer (see file insn-attrtab.c).
+ Please don't forget to change the structure if a new
+ automaton is added to .md file. */
+ struct DFA_chip
+ {
+ unsigned short one_automaton_state;
+ unsigned short oneb_automaton_state;
+ unsigned short two_automaton_state;
+ unsigned short twob_automaton_state;
+ };
+
+ fprintf
+ (dump,
+ "// Bundle state %d (orig %d, cost %d, nops %d/%d, insns %d, branch %d, state %d) for %d\n",
+ curr_state->unique_num,
+ (curr_state->originator == NULL
+ ? -1 : curr_state->originator->unique_num),
+ curr_state->cost,
+ curr_state->before_nops_num, curr_state->after_nops_num,
+ curr_state->accumulated_insns_num, curr_state->branch_deviation,
+ (ia64_tune == PROCESSOR_ITANIUM
+ ? ((struct DFA_chip *) curr_state->dfa_state)->oneb_automaton_state
+ : ((struct DFA_chip *) curr_state->dfa_state)->twob_automaton_state),
+ INSN_UID (insn));
}
- }
- if (n_asms < n_ready)
- {
- /* Some normal insns to process. Skip the asms. */
- ready += n_asms;
- n_ready -= n_asms;
}
- else if (n_ready > 0)
- {
- /* Only asm insns left. */
- if (ia64_final_schedule && group_barrier_needed_p (ready[n_ready - 1]))
+ if (index_to_bundle_states [insn_num] == NULL)
+ /* We should find a solution because the 2nd insn scheduling has
+ found one. */
+ abort ();
+ /* Find a state corresponding to the best insn sequence. */
+ best_state = NULL;
+ for (curr_state = index_to_bundle_states [insn_num];
+ curr_state != NULL;
+ curr_state = curr_state->next)
+ /* We are just looking at the states with fully filled up last
+ bundle. The first we prefer insn sequences with minimal cost
+ then with minimal inserted nops and finally with branch insns
+ placed in the 3rd slots. */
+ if (curr_state->accumulated_insns_num % 3 == 0
+ && (best_state == NULL || best_state->cost > curr_state->cost
+ || (best_state->cost == curr_state->cost
+ && (curr_state->accumulated_insns_num
+ < best_state->accumulated_insns_num
+ || (curr_state->accumulated_insns_num
+ == best_state->accumulated_insns_num
+ && curr_state->branch_deviation
+ < best_state->branch_deviation)))))
+ best_state = curr_state;
+ /* Second (backward) pass: adding nops and templates. */
+ insn_num = best_state->before_nops_num;
+ template0 = template1 = -1;
+ for (curr_state = best_state;
+ curr_state->originator != NULL;
+ curr_state = curr_state->originator)
+ {
+ insn = curr_state->insn;
+ asm_p = (GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0);
+ insn_num++;
+ if (verbose >= 2 && dump)
{
- schedule_stop (sched_verbose ? dump : NULL);
- sched_data.last_was_stop = 1;
- maybe_rotate (sched_verbose ? dump : NULL);
+ struct DFA_chip
+ {
+ unsigned short one_automaton_state;
+ unsigned short oneb_automaton_state;
+ unsigned short two_automaton_state;
+ unsigned short twob_automaton_state;
+ };
+
+ fprintf
+ (dump,
+ "// Best %d (orig %d, cost %d, nops %d/%d, insns %d, branch %d, state %d) for %d\n",
+ curr_state->unique_num,
+ (curr_state->originator == NULL
+ ? -1 : curr_state->originator->unique_num),
+ curr_state->cost,
+ curr_state->before_nops_num, curr_state->after_nops_num,
+ curr_state->accumulated_insns_num, curr_state->branch_deviation,
+ (ia64_tune == PROCESSOR_ITANIUM
+ ? ((struct DFA_chip *) curr_state->dfa_state)->oneb_automaton_state
+ : ((struct DFA_chip *) curr_state->dfa_state)->twob_automaton_state),
+ INSN_UID (insn));
}
- cycle_end_fill_slots (sched_verbose ? dump : NULL);
- return 1;
- }
-
- if (ia64_final_schedule)
- {
- int nr_need_stop = 0;
-
- for (insnp = ready; insnp < e_ready; insnp++)
- if (safe_group_barrier_needed_p (*insnp))
- nr_need_stop++;
-
- /* Schedule a stop bit if
- - all insns require a stop bit, or
- - we are starting a new cycle and _any_ insns require a stop bit.
- The reason for the latter is that if our schedule is accurate, then
- the additional stop won't decrease performance at this point (since
- there's a split issue at this point anyway), but it gives us more
- freedom when scheduling the currently ready insns. */
- if ((reorder_type == 0 && nr_need_stop)
- || (reorder_type == 1 && n_ready == nr_need_stop))
+ /* Find the position in the current bundle window. The window can
+ contain at most two bundles. Two bundle window means that
+ the processor will make two bundle rotation. */
+ max_pos = get_max_pos (curr_state->dfa_state);
+ if (max_pos == 6
+ /* The following (negative template number) means that the
+ processor did one bundle rotation. */
+ || (max_pos == 3 && template0 < 0))
{
- schedule_stop (sched_verbose ? dump : NULL);
- sched_data.last_was_stop = 1;
- maybe_rotate (sched_verbose ? dump : NULL);
- if (reorder_type == 1)
- return 0;
+ /* We are at the end of the window -- find template(s) for
+ its bundle(s). */
+ pos = max_pos;
+ if (max_pos == 3)
+ template0 = get_template (curr_state->dfa_state, 3);
+ else
+ {
+ template1 = get_template (curr_state->dfa_state, 3);
+ template0 = get_template (curr_state->dfa_state, 6);
+ }
}
- else
+ if (max_pos > 3 && template1 < 0)
+ /* It may happen when we have the stop inside a bundle. */
{
- int deleted = 0;
- insnp = e_ready;
- /* Move down everything that needs a stop bit, preserving relative
- order. */
- while (insnp-- > ready + deleted)
- while (insnp >= ready + deleted)
+ if (pos > 3)
+ abort ();
+ template1 = get_template (curr_state->dfa_state, 3);
+ pos += 3;
+ }
+ if (!asm_p)
+ /* Emit nops after the current insn. */
+ for (i = 0; i < curr_state->after_nops_num; i++)
+ {
+ nop = gen_nop ();
+ emit_insn_after (nop, insn);
+ pos--;
+ if (pos < 0)
+ abort ();
+ if (pos % 3 == 0)
{
- rtx insn = *insnp;
- if (! safe_group_barrier_needed_p (insn))
- break;
- memmove (ready + 1, ready, (insnp - ready) * sizeof (rtx));
- *ready = insn;
- deleted++;
+ /* We are at the start of a bundle: emit the template
+ (it should be defined). */
+ if (template0 < 0)
+ abort ();
+ b = gen_bundle_selector (GEN_INT (template0));
+ ia64_emit_insn_before (b, nop);
+ /* If we have two bundle window, we make one bundle
+ rotation. Otherwise template0 will be undefined
+ (negative value). */
+ template0 = template1;
+ template1 = -1;
}
- n_ready -= deleted;
- ready += deleted;
- if (deleted != nr_need_stop)
+ }
+ /* Move the position backward in the window. Group barrier has
+ no slot. Asm insn takes all bundle. */
+ if (INSN_CODE (insn) != CODE_FOR_insn_group_barrier
+ && GET_CODE (PATTERN (insn)) != ASM_INPUT
+ && asm_noperands (PATTERN (insn)) < 0)
+ pos--;
+ /* Long insn takes 2 slots. */
+ if (ia64_safe_type (insn) == TYPE_L)
+ pos--;
+ if (pos < 0)
+ abort ();
+ if (pos % 3 == 0
+ && INSN_CODE (insn) != CODE_FOR_insn_group_barrier
+ && GET_CODE (PATTERN (insn)) != ASM_INPUT
+ && asm_noperands (PATTERN (insn)) < 0)
+ {
+ /* The current insn is at the bundle start: emit the
+ template. */
+ if (template0 < 0)
abort ();
+ b = gen_bundle_selector (GEN_INT (template0));
+ ia64_emit_insn_before (b, insn);
+ b = PREV_INSN (insn);
+ insn = b;
+ /* See comment above in analogous place for emiting nops
+ after the insn. */
+ template0 = template1;
+ template1 = -1;
+ }
+ /* Emit nops after the current insn. */
+ for (i = 0; i < curr_state->before_nops_num; i++)
+ {
+ nop = gen_nop ();
+ ia64_emit_insn_before (nop, insn);
+ nop = PREV_INSN (insn);
+ insn = nop;
+ pos--;
+ if (pos < 0)
+ abort ();
+ if (pos % 3 == 0)
+ {
+ /* See comment above in analogous place for emiting nops
+ after the insn. */
+ if (template0 < 0)
+ abort ();
+ b = gen_bundle_selector (GEN_INT (template0));
+ ia64_emit_insn_before (b, insn);
+ b = PREV_INSN (insn);
+ insn = b;
+ template0 = template1;
+ template1 = -1;
+ }
}
}
-
- return itanium_reorder (sched_verbose ? dump : NULL,
- ready, e_ready, reorder_type == 1);
+ if (ia64_tune == PROCESSOR_ITANIUM)
+ /* Insert additional cycles for MM-insns (MMMUL and MMSHF).
+ Itanium1 has a strange design, if the distance between an insn
+ and dependent MM-insn is less 4 then we have a 6 additional
+ cycles stall. So we make the distance equal to 4 cycles if it
+ is less. */
+ for (insn = get_next_important_insn (NEXT_INSN (prev_head_insn), tail);
+ insn != NULL_RTX;
+ insn = next_insn)
+ {
+ if (!INSN_P (insn)
+ || ia64_safe_itanium_class (insn) == ITANIUM_CLASS_IGNORE
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ abort ();
+ next_insn = get_next_important_insn (NEXT_INSN (insn), tail);
+ if (INSN_UID (insn) < clocks_length && add_cycles [INSN_UID (insn)])
+ /* We found a MM-insn which needs additional cycles. */
+ {
+ rtx last;
+ int i, j, n;
+ int pred_stop_p;
+
+ /* Now we are searching for a template of the bundle in
+ which the MM-insn is placed and the position of the
+ insn in the bundle (0, 1, 2). Also we are searching
+ for that there is a stop before the insn. */
+ last = prev_active_insn (insn);
+ pred_stop_p = recog_memoized (last) == CODE_FOR_insn_group_barrier;
+ if (pred_stop_p)
+ last = prev_active_insn (last);
+ n = 0;
+ for (;; last = prev_active_insn (last))
+ if (recog_memoized (last) == CODE_FOR_bundle_selector)
+ {
+ template0 = XINT (XVECEXP (PATTERN (last), 0, 0), 0);
+ if (template0 == 9)
+ /* The insn is in MLX bundle. Change the template
+ onto MFI because we will add nops before the
+ insn. It simplifies subsequent code a lot. */
+ PATTERN (last)
+ = gen_bundle_selector (GEN_INT (2)); /* -> MFI */
+ break;
+ }
+ else if (recog_memoized (last) != CODE_FOR_insn_group_barrier
+ && (ia64_safe_itanium_class (last)
+ != ITANIUM_CLASS_IGNORE))
+ n++;
+ /* Some check of correctness: the stop is not at the
+ bundle start, there are no more 3 insns in the bundle,
+ and the MM-insn is not at the start of bundle with
+ template MLX. */
+ if ((pred_stop_p && n == 0) || n > 2
+ || (template0 == 9 && n != 0))
+ abort ();
+ /* Put nops after the insn in the bundle. */
+ for (j = 3 - n; j > 0; j --)
+ ia64_emit_insn_before (gen_nop (), insn);
+ /* It takes into account that we will add more N nops
+ before the insn lately -- please see code below. */
+ add_cycles [INSN_UID (insn)]--;
+ if (!pred_stop_p || add_cycles [INSN_UID (insn)])
+ ia64_emit_insn_before (gen_insn_group_barrier (GEN_INT (3)),
+ insn);
+ if (pred_stop_p)
+ add_cycles [INSN_UID (insn)]--;
+ for (i = add_cycles [INSN_UID (insn)]; i > 0; i--)
+ {
+ /* Insert "MII;" template. */
+ ia64_emit_insn_before (gen_bundle_selector (GEN_INT (0)),
+ insn);
+ ia64_emit_insn_before (gen_nop (), insn);
+ ia64_emit_insn_before (gen_nop (), insn);
+ if (i > 1)
+ {
+ /* To decrease code size, we use "MI;I;"
+ template. */
+ ia64_emit_insn_before
+ (gen_insn_group_barrier (GEN_INT (3)), insn);
+ i--;
+ }
+ ia64_emit_insn_before (gen_nop (), insn);
+ ia64_emit_insn_before (gen_insn_group_barrier (GEN_INT (3)),
+ insn);
+ }
+ /* Put the MM-insn in the same slot of a bundle with the
+ same template as the original one. */
+ ia64_emit_insn_before (gen_bundle_selector (GEN_INT (template0)),
+ insn);
+ /* To put the insn in the same slot, add necessary number
+ of nops. */
+ for (j = n; j > 0; j --)
+ ia64_emit_insn_before (gen_nop (), insn);
+ /* Put the stop if the original bundle had it. */
+ if (pred_stop_p)
+ ia64_emit_insn_before (gen_insn_group_barrier (GEN_INT (3)),
+ insn);
+ }
+ }
+ free (index_to_bundle_states);
+ finish_bundle_state_table ();
+ bundling_p = 0;
+ dfa_clean_insn_cache ();
}
-static int
-ia64_sched_reorder (dump, sched_verbose, ready, pn_ready, clock_var)
- FILE *dump;
- int sched_verbose;
- rtx *ready;
- int *pn_ready;
- int clock_var;
+/* The following function is called at the end of scheduling BB or
+ EBB. After reload, it inserts stop bits and does insn bundling. */
+
+static void
+ia64_sched_finish (FILE *dump, int sched_verbose)
{
- return ia64_internal_sched_reorder (dump, sched_verbose, ready,
- pn_ready, 0, clock_var);
+ if (sched_verbose)
+ fprintf (dump, "// Finishing schedule.\n");
+ if (!reload_completed)
+ return;
+ if (reload_completed)
+ {
+ final_emit_insn_group_barriers (dump);
+ bundling (dump, sched_verbose, current_sched_info->prev_head,
+ current_sched_info->next_tail);
+ if (sched_verbose && dump)
+ fprintf (dump, "// finishing %d-%d\n",
+ INSN_UID (NEXT_INSN (current_sched_info->prev_head)),
+ INSN_UID (PREV_INSN (current_sched_info->next_tail)));
+
+ return;
+ }
}
-/* Like ia64_sched_reorder, but called after issuing each insn.
- Override the default sort algorithm to better slot instructions. */
+/* The following function inserts stop bits in scheduled BB or EBB. */
-static int
-ia64_sched_reorder2 (dump, sched_verbose, ready, pn_ready, clock_var)
- FILE *dump ATTRIBUTE_UNUSED;
- int sched_verbose ATTRIBUTE_UNUSED;
- rtx *ready;
- int *pn_ready;
- int clock_var;
-{
- if (sched_data.last_was_stop)
- return 0;
+static void
+final_emit_insn_group_barriers (FILE *dump ATTRIBUTE_UNUSED)
+{
+ rtx insn;
+ int need_barrier_p = 0;
+ rtx prev_insn = NULL_RTX;
- /* Detect one special case and try to optimize it.
- If we have 1.M;;MI 2.MIx, and slots 2.1 (M) and 2.2 (I) are both NOPs,
- then we can get better code by transforming this to 1.MFB;; 2.MIx. */
- if (sched_data.first_slot == 1
- && sched_data.stopbit[0]
- && ((sched_data.cur == 4
- && (sched_data.types[1] == TYPE_M || sched_data.types[1] == TYPE_A)
- && (sched_data.types[2] == TYPE_I || sched_data.types[2] == TYPE_A)
- && (sched_data.types[3] != TYPE_M && sched_data.types[3] != TYPE_A))
- || (sched_data.cur == 3
- && (sched_data.types[1] == TYPE_M
- || sched_data.types[1] == TYPE_A)
- && (sched_data.types[2] != TYPE_M
- && sched_data.types[2] != TYPE_I
- && sched_data.types[2] != TYPE_A))))
-
- {
- int i, best;
- rtx stop = sched_data.insns[1];
+ init_insn_group_barriers ();
- /* Search backward for the stop bit that must be there. */
- while (1)
+ for (insn = NEXT_INSN (current_sched_info->prev_head);
+ insn != current_sched_info->next_tail;
+ insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == BARRIER)
{
- int insn_code;
-
- stop = PREV_INSN (stop);
- if (GET_CODE (stop) != INSN)
- abort ();
- insn_code = recog_memoized (stop);
-
- /* Ignore .pred.rel.mutex.
+ rtx last = prev_active_insn (insn);
- ??? Update this to ignore cycle display notes too
- ??? once those are implemented */
- if (insn_code == CODE_FOR_pred_rel_mutex
- || insn_code == CODE_FOR_prologue_use)
+ if (! last)
continue;
+ if (GET_CODE (last) == JUMP_INSN
+ && GET_CODE (PATTERN (last)) == ADDR_DIFF_VEC)
+ last = prev_active_insn (last);
+ if (recog_memoized (last) != CODE_FOR_insn_group_barrier)
+ emit_insn_after (gen_insn_group_barrier (GEN_INT (3)), last);
- if (insn_code == CODE_FOR_insn_group_barrier)
- break;
- abort ();
+ init_insn_group_barriers ();
+ need_barrier_p = 0;
+ prev_insn = NULL_RTX;
}
-
- /* Adjust the stop bit's slot selector. */
- if (INTVAL (XVECEXP (PATTERN (stop), 0, 0)) != 1)
- abort ();
- XVECEXP (PATTERN (stop), 0, 0) = GEN_INT (3);
-
- sched_data.stopbit[0] = 0;
- sched_data.stopbit[2] = 1;
-
- sched_data.types[5] = sched_data.types[3];
- sched_data.types[4] = sched_data.types[2];
- sched_data.types[3] = sched_data.types[1];
- sched_data.insns[5] = sched_data.insns[3];
- sched_data.insns[4] = sched_data.insns[2];
- sched_data.insns[3] = sched_data.insns[1];
- sched_data.stopbit[5] = sched_data.stopbit[4] = sched_data.stopbit[3] = 0;
- sched_data.cur += 2;
- sched_data.first_slot = 3;
- for (i = 0; i < NR_PACKETS; i++)
+ else if (INSN_P (insn))
{
- const struct ia64_packet *p = packets + i;
- if (p->t[0] == TYPE_M && p->t[1] == TYPE_F && p->t[2] == TYPE_B)
+ if (recog_memoized (insn) == CODE_FOR_insn_group_barrier)
{
- sched_data.packet = p;
- break;
+ init_insn_group_barriers ();
+ need_barrier_p = 0;
+ prev_insn = NULL_RTX;
}
- }
- rotate_one_bundle (sched_verbose ? dump : NULL);
-
- best = 6;
- for (i = 0; i < NR_PACKETS; i++)
- {
- const struct ia64_packet *p = packets + i;
- int split = get_split (p, sched_data.first_slot);
- int next;
-
- /* Disallow multiway branches here. */
- if (p->t[1] == TYPE_B)
- continue;
-
- if (packet_matches_p (p, split, &next) && next < best)
+ else if (need_barrier_p || group_barrier_needed_p (insn))
{
- best = next;
- sched_data.packet = p;
- sched_data.split = split;
+ if (TARGET_EARLY_STOP_BITS)
+ {
+ rtx last;
+
+ for (last = insn;
+ last != current_sched_info->prev_head;
+ last = PREV_INSN (last))
+ if (INSN_P (last) && GET_MODE (last) == TImode
+ && stops_p [INSN_UID (last)])
+ break;
+ if (last == current_sched_info->prev_head)
+ last = insn;
+ last = prev_active_insn (last);
+ if (last
+ && recog_memoized (last) != CODE_FOR_insn_group_barrier)
+ emit_insn_after (gen_insn_group_barrier (GEN_INT (3)),
+ last);
+ init_insn_group_barriers ();
+ for (last = NEXT_INSN (last);
+ last != insn;
+ last = NEXT_INSN (last))
+ if (INSN_P (last))
+ group_barrier_needed_p (last);
+ }
+ else
+ {
+ emit_insn_before (gen_insn_group_barrier (GEN_INT (3)),
+ insn);
+ init_insn_group_barriers ();
+ }
+ group_barrier_needed_p (insn);
+ prev_insn = NULL_RTX;
}
+ else if (recog_memoized (insn) >= 0)
+ prev_insn = insn;
+ need_barrier_p = (GET_CODE (insn) == CALL_INSN
+ || GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0);
}
- if (best == 6)
- abort ();
}
+}
- if (*pn_ready > 0)
- {
- int more = ia64_internal_sched_reorder (dump, sched_verbose,
- ready, pn_ready, 1,
- clock_var);
- if (more)
- return more;
- /* Did we schedule a stop? If so, finish this cycle. */
- if (sched_data.cur == sched_data.first_slot)
- return 0;
- }
+
- if (sched_verbose)
- fprintf (dump, "// Can't issue more this cycle; updating type array.\n");
+/* If the following function returns TRUE, we will use the the DFA
+ insn scheduler. */
- cycle_end_fill_slots (sched_verbose ? dump : NULL);
- if (sched_verbose)
- dump_current_packet (dump);
- return 0;
+static int
+ia64_use_dfa_pipeline_interface (void)
+{
+ return 1;
}
-/* We are about to issue INSN. Return the number of insns left on the
- ready queue that can be issued this cycle. */
+/* If the following function returns TRUE, we will use the the DFA
+ insn scheduler. */
static int
-ia64_variable_issue (dump, sched_verbose, insn, can_issue_more)
- FILE *dump;
- int sched_verbose;
- rtx insn;
- int can_issue_more ATTRIBUTE_UNUSED;
+ia64_first_cycle_multipass_dfa_lookahead (void)
{
- enum attr_type t = ia64_safe_type (insn);
+ return (reload_completed ? 6 : 4);
+}
- if (sched_data.last_was_stop)
- {
- int t = sched_data.first_slot;
- if (t == 0)
- t = 3;
- ia64_emit_insn_before (gen_insn_group_barrier (GEN_INT (t)), insn);
- init_insn_group_barriers ();
- sched_data.last_was_stop = 0;
- }
+/* The following function initiates variable `dfa_pre_cycle_insn'. */
- if (t == TYPE_UNKNOWN)
+static void
+ia64_init_dfa_pre_cycle_insn (void)
+{
+ if (temp_dfa_state == NULL)
{
- if (sched_verbose)
- fprintf (dump, "// Ignoring type %s\n", type_names[t]);
- if (GET_CODE (PATTERN (insn)) == ASM_INPUT
- || asm_noperands (PATTERN (insn)) >= 0)
- {
- /* This must be some kind of asm. Clear the scheduling state. */
- rotate_two_bundles (sched_verbose ? dump : NULL);
- if (ia64_final_schedule)
- group_barrier_needed_p (insn);
- }
- return 1;
+ dfa_state_size = state_size ();
+ temp_dfa_state = xmalloc (dfa_state_size);
+ prev_cycle_state = xmalloc (dfa_state_size);
}
+ dfa_pre_cycle_insn = make_insn_raw (gen_pre_cycle ());
+ PREV_INSN (dfa_pre_cycle_insn) = NEXT_INSN (dfa_pre_cycle_insn) = NULL_RTX;
+ recog_memoized (dfa_pre_cycle_insn);
+ dfa_stop_insn = make_insn_raw (gen_insn_group_barrier (GEN_INT (3)));
+ PREV_INSN (dfa_stop_insn) = NEXT_INSN (dfa_stop_insn) = NULL_RTX;
+ recog_memoized (dfa_stop_insn);
+}
+
+/* The following function returns the pseudo insn DFA_PRE_CYCLE_INSN
+ used by the DFA insn scheduler. */
+
+static rtx
+ia64_dfa_pre_cycle_insn (void)
+{
+ return dfa_pre_cycle_insn;
+}
+
+/* The following function returns TRUE if PRODUCER (of type ilog or
+ ld) produces address for CONSUMER (of type st or stf). */
- /* This is _not_ just a sanity check. group_barrier_needed_p will update
- important state info. Don't delete this test. */
- if (ia64_final_schedule
- && group_barrier_needed_p (insn))
+int
+ia64_st_address_bypass_p (rtx producer, rtx consumer)
+{
+ rtx dest, reg, mem;
+
+ if (producer == NULL_RTX || consumer == NULL_RTX)
+ abort ();
+ dest = ia64_single_set (producer);
+ if (dest == NULL_RTX || (reg = SET_DEST (dest)) == NULL_RTX
+ || (GET_CODE (reg) != REG && GET_CODE (reg) != SUBREG))
abort ();
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+ dest = ia64_single_set (consumer);
+ if (dest == NULL_RTX || (mem = SET_DEST (dest)) == NULL_RTX
+ || GET_CODE (mem) != MEM)
+ abort ();
+ return reg_mentioned_p (reg, mem);
+}
- sched_data.stopbit[sched_data.cur] = 0;
- sched_data.insns[sched_data.cur] = insn;
- sched_data.types[sched_data.cur] = t;
+/* The following function returns TRUE if PRODUCER (of type ilog or
+ ld) produces address for CONSUMER (of type ld or fld). */
- sched_data.cur++;
- if (sched_verbose)
- fprintf (dump, "// Scheduling insn %d of type %s\n",
- INSN_UID (insn), type_names[t]);
+int
+ia64_ld_address_bypass_p (rtx producer, rtx consumer)
+{
+ rtx dest, src, reg, mem;
- if (GET_CODE (insn) == CALL_INSN && ia64_final_schedule)
- {
- schedule_stop (sched_verbose ? dump : NULL);
- sched_data.last_was_stop = 1;
- }
+ if (producer == NULL_RTX || consumer == NULL_RTX)
+ abort ();
+ dest = ia64_single_set (producer);
+ if (dest == NULL_RTX || (reg = SET_DEST (dest)) == NULL_RTX
+ || (GET_CODE (reg) != REG && GET_CODE (reg) != SUBREG))
+ abort ();
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+ src = ia64_single_set (consumer);
+ if (src == NULL_RTX || (mem = SET_SRC (src)) == NULL_RTX)
+ abort ();
+ if (GET_CODE (mem) == UNSPEC && XVECLEN (mem, 0) > 0)
+ mem = XVECEXP (mem, 0, 0);
+ while (GET_CODE (mem) == SUBREG || GET_CODE (mem) == ZERO_EXTEND)
+ mem = XEXP (mem, 0);
- return 1;
+ /* Note that LO_SUM is used for GOT loads. */
+ if (GET_CODE (mem) != LO_SUM && GET_CODE (mem) != MEM)
+ abort ();
+
+ return reg_mentioned_p (reg, mem);
}
-/* Free data allocated by ia64_sched_init. */
+/* The following function returns TRUE if INSN produces address for a
+ load/store insn. We will place such insns into M slot because it
+ decreases its latency time. */
-static void
-ia64_sched_finish (dump, sched_verbose)
- FILE *dump;
- int sched_verbose;
+int
+ia64_produce_address_p (rtx insn)
{
- if (sched_verbose)
- fprintf (dump, "// Finishing schedule.\n");
- rotate_two_bundles (NULL);
- free (sched_types);
- free (sched_ready);
+ return insn->call;
}
+
/* Emit pseudo-ops for the assembler to describe predicate relations.
At present this assumes that we only consider predicate pairs to
@@ -6967,14 +7436,14 @@ ia64_sched_finish (dump, sched_verbose)
straight-line code. */
static void
-emit_predicate_relation_info ()
+emit_predicate_relation_info (void)
{
basic_block bb;
FOR_EACH_BB_REVERSE (bb)
{
int r;
- rtx head = bb->head;
+ rtx head = BB_HEAD (bb);
/* We only need such notes at code labels. */
if (GET_CODE (head) != CODE_LABEL)
@@ -6988,8 +7457,8 @@ emit_predicate_relation_info ()
{
rtx p = gen_rtx_REG (BImode, r);
rtx n = emit_insn_after (gen_pred_rel_mutex (p), head);
- if (head == bb->end)
- bb->end = n;
+ if (head == BB_END (bb))
+ BB_END (bb) = n;
head = n;
}
}
@@ -7000,8 +7469,8 @@ emit_predicate_relation_info ()
the call. */
FOR_EACH_BB_REVERSE (bb)
{
- rtx insn = bb->head;
-
+ rtx insn = BB_HEAD (bb);
+
while (1)
{
if (GET_CODE (insn) == CALL_INSN
@@ -7010,130 +7479,23 @@ emit_predicate_relation_info ()
{
rtx b = emit_insn_before (gen_safe_across_calls_all (), insn);
rtx a = emit_insn_after (gen_safe_across_calls_normal (), insn);
- if (bb->head == insn)
- bb->head = b;
- if (bb->end == insn)
- bb->end = a;
+ if (BB_HEAD (bb) == insn)
+ BB_HEAD (bb) = b;
+ if (BB_END (bb) == insn)
+ BB_END (bb) = a;
}
-
- if (insn == bb->end)
+
+ if (insn == BB_END (bb))
break;
insn = NEXT_INSN (insn);
}
}
}
-/* Generate a NOP instruction of type T. We will never generate L type
- nops. */
-
-static rtx
-gen_nop_type (t)
- enum attr_type t;
-{
- switch (t)
- {
- case TYPE_M:
- return gen_nop_m ();
- case TYPE_I:
- return gen_nop_i ();
- case TYPE_B:
- return gen_nop_b ();
- case TYPE_F:
- return gen_nop_f ();
- case TYPE_X:
- return gen_nop_x ();
- default:
- abort ();
- }
-}
-
-/* After the last scheduling pass, fill in NOPs. It's easier to do this
- here than while scheduling. */
-
-static void
-ia64_emit_nops ()
-{
- rtx insn;
- const struct bundle *b = 0;
- int bundle_pos = 0;
-
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- {
- rtx pat;
- enum attr_type t;
- pat = INSN_P (insn) ? PATTERN (insn) : const0_rtx;
- if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
- continue;
- if ((GET_CODE (pat) == UNSPEC && XINT (pat, 1) == UNSPEC_BUNDLE_SELECTOR)
- || GET_CODE (insn) == CODE_LABEL)
- {
- if (b)
- while (bundle_pos < 3)
- {
- emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
- bundle_pos++;
- }
- if (GET_CODE (insn) != CODE_LABEL)
- b = bundle + INTVAL (XVECEXP (pat, 0, 0));
- else
- b = 0;
- bundle_pos = 0;
- continue;
- }
- else if (GET_CODE (pat) == UNSPEC_VOLATILE
- && XINT (pat, 1) == UNSPECV_INSN_GROUP_BARRIER)
- {
- int t = INTVAL (XVECEXP (pat, 0, 0));
- if (b)
- while (bundle_pos < t)
- {
- emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
- bundle_pos++;
- }
- continue;
- }
-
- if (bundle_pos == 3)
- b = 0;
-
- if (b && INSN_P (insn))
- {
- t = ia64_safe_type (insn);
- if (asm_noperands (PATTERN (insn)) >= 0
- || GET_CODE (PATTERN (insn)) == ASM_INPUT)
- {
- while (bundle_pos < 3)
- {
- if (b->t[bundle_pos] != TYPE_L)
- emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
- bundle_pos++;
- }
- continue;
- }
-
- if (t == TYPE_UNKNOWN)
- continue;
- while (bundle_pos < 3)
- {
- if (t == b->t[bundle_pos]
- || (t == TYPE_A && (b->t[bundle_pos] == TYPE_M
- || b->t[bundle_pos] == TYPE_I)))
- break;
-
- emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
- bundle_pos++;
- }
- if (bundle_pos < 3)
- bundle_pos++;
- }
- }
-}
-
/* Perform machine dependent operations on the rtl chain INSNS. */
-void
-ia64_reorg (insns)
- rtx insns;
+static void
+ia64_reorg (void)
{
/* We are freeing block_for_insn in the toplev to keep compatibility
with old MDEP_REORGS that are not CFG based. Recompute it now. */
@@ -7151,17 +7513,91 @@ ia64_reorg (insns)
{
timevar_push (TV_SCHED2);
ia64_final_schedule = 1;
+
+ initiate_bundle_states ();
+ ia64_nop = make_insn_raw (gen_nop ());
+ PREV_INSN (ia64_nop) = NEXT_INSN (ia64_nop) = NULL_RTX;
+ recog_memoized (ia64_nop);
+ clocks_length = get_max_uid () + 1;
+ stops_p = xcalloc (1, clocks_length);
+ if (ia64_tune == PROCESSOR_ITANIUM)
+ {
+ clocks = xcalloc (clocks_length, sizeof (int));
+ add_cycles = xcalloc (clocks_length, sizeof (int));
+ }
+ if (ia64_tune == PROCESSOR_ITANIUM2)
+ {
+ pos_1 = get_cpu_unit_code ("2_1");
+ pos_2 = get_cpu_unit_code ("2_2");
+ pos_3 = get_cpu_unit_code ("2_3");
+ pos_4 = get_cpu_unit_code ("2_4");
+ pos_5 = get_cpu_unit_code ("2_5");
+ pos_6 = get_cpu_unit_code ("2_6");
+ _0mii_ = get_cpu_unit_code ("2b_0mii.");
+ _0mmi_ = get_cpu_unit_code ("2b_0mmi.");
+ _0mfi_ = get_cpu_unit_code ("2b_0mfi.");
+ _0mmf_ = get_cpu_unit_code ("2b_0mmf.");
+ _0bbb_ = get_cpu_unit_code ("2b_0bbb.");
+ _0mbb_ = get_cpu_unit_code ("2b_0mbb.");
+ _0mib_ = get_cpu_unit_code ("2b_0mib.");
+ _0mmb_ = get_cpu_unit_code ("2b_0mmb.");
+ _0mfb_ = get_cpu_unit_code ("2b_0mfb.");
+ _0mlx_ = get_cpu_unit_code ("2b_0mlx.");
+ _1mii_ = get_cpu_unit_code ("2b_1mii.");
+ _1mmi_ = get_cpu_unit_code ("2b_1mmi.");
+ _1mfi_ = get_cpu_unit_code ("2b_1mfi.");
+ _1mmf_ = get_cpu_unit_code ("2b_1mmf.");
+ _1bbb_ = get_cpu_unit_code ("2b_1bbb.");
+ _1mbb_ = get_cpu_unit_code ("2b_1mbb.");
+ _1mib_ = get_cpu_unit_code ("2b_1mib.");
+ _1mmb_ = get_cpu_unit_code ("2b_1mmb.");
+ _1mfb_ = get_cpu_unit_code ("2b_1mfb.");
+ _1mlx_ = get_cpu_unit_code ("2b_1mlx.");
+ }
+ else
+ {
+ pos_1 = get_cpu_unit_code ("1_1");
+ pos_2 = get_cpu_unit_code ("1_2");
+ pos_3 = get_cpu_unit_code ("1_3");
+ pos_4 = get_cpu_unit_code ("1_4");
+ pos_5 = get_cpu_unit_code ("1_5");
+ pos_6 = get_cpu_unit_code ("1_6");
+ _0mii_ = get_cpu_unit_code ("1b_0mii.");
+ _0mmi_ = get_cpu_unit_code ("1b_0mmi.");
+ _0mfi_ = get_cpu_unit_code ("1b_0mfi.");
+ _0mmf_ = get_cpu_unit_code ("1b_0mmf.");
+ _0bbb_ = get_cpu_unit_code ("1b_0bbb.");
+ _0mbb_ = get_cpu_unit_code ("1b_0mbb.");
+ _0mib_ = get_cpu_unit_code ("1b_0mib.");
+ _0mmb_ = get_cpu_unit_code ("1b_0mmb.");
+ _0mfb_ = get_cpu_unit_code ("1b_0mfb.");
+ _0mlx_ = get_cpu_unit_code ("1b_0mlx.");
+ _1mii_ = get_cpu_unit_code ("1b_1mii.");
+ _1mmi_ = get_cpu_unit_code ("1b_1mmi.");
+ _1mfi_ = get_cpu_unit_code ("1b_1mfi.");
+ _1mmf_ = get_cpu_unit_code ("1b_1mmf.");
+ _1bbb_ = get_cpu_unit_code ("1b_1bbb.");
+ _1mbb_ = get_cpu_unit_code ("1b_1mbb.");
+ _1mib_ = get_cpu_unit_code ("1b_1mib.");
+ _1mmb_ = get_cpu_unit_code ("1b_1mmb.");
+ _1mfb_ = get_cpu_unit_code ("1b_1mfb.");
+ _1mlx_ = get_cpu_unit_code ("1b_1mlx.");
+ }
schedule_ebbs (rtl_dump_file);
+ finish_bundle_states ();
+ if (ia64_tune == PROCESSOR_ITANIUM)
+ {
+ free (add_cycles);
+ free (clocks);
+ }
+ free (stops_p);
+ emit_insn_group_barriers (rtl_dump_file);
+
ia64_final_schedule = 0;
timevar_pop (TV_SCHED2);
-
- /* This relies on the NOTE_INSN_BASIC_BLOCK notes to be in the same
- place as they were during scheduling. */
- emit_insn_group_barriers (rtl_dump_file, insns);
- ia64_emit_nops ();
}
else
- emit_all_insn_group_barriers (rtl_dump_file, insns);
+ emit_all_insn_group_barriers (rtl_dump_file);
/* A call must not be the last instruction in a function, so that the
return address is still within the function, so that unwinding works
@@ -7174,11 +7610,12 @@ ia64_reorg (insns)
insn = get_last_insn ();
if (! INSN_P (insn))
insn = prev_active_insn (insn);
- if (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
- && XINT (PATTERN (insn), 1) == UNSPECV_INSN_GROUP_BARRIER)
- {
- saw_stop = 1;
+ /* Skip over insns that expand to nothing. */
+ while (GET_CODE (insn) == INSN && get_attr_empty (insn) == EMPTY_YES)
+ {
+ if (GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
+ && XINT (PATTERN (insn), 1) == UNSPECV_INSN_GROUP_BARRIER)
+ saw_stop = 1;
insn = prev_active_insn (insn);
}
if (GET_CODE (insn) == CALL_INSN)
@@ -7197,8 +7634,7 @@ ia64_reorg (insns)
/* Return true if REGNO is used by the epilogue. */
int
-ia64_epilogue_uses (regno)
- int regno;
+ia64_epilogue_uses (int regno)
{
switch (regno)
{
@@ -7237,8 +7673,7 @@ ia64_epilogue_uses (regno)
/* Return true if REGNO is used by the frame unwinder. */
int
-ia64_eh_uses (regno)
- int regno;
+ia64_eh_uses (int regno)
{
if (! reload_completed)
return 0;
@@ -7262,18 +7697,7 @@ ia64_eh_uses (regno)
return 0;
}
-/* For ia64, SYMBOL_REF_FLAG set means that it is a function.
-
- We add @ to the name if this goes in small data/bss. We can only put
- a variable in small data/bss if it is defined in this module or a module
- that we are statically linked with. We can't check the second condition,
- but TREE_STATIC gives us the first one. */
-
-/* ??? If we had IPA, we could check the second condition. We could support
- programmer added section attributes if the variable is not defined in this
- module. */
-
-/* ??? See the v850 port for a cleaner way to do this. */
+/* Return true if this goes in small data/bss. */
/* ??? We could also support own long data here. Generating movl/add/ld8
instead of addl,ld8/ld8. This makes the code bigger, but should make the
@@ -7281,12 +7705,19 @@ ia64_eh_uses (regno)
types which can't go in sdata/sbss. */
static bool
-ia64_in_small_data_p (exp)
- tree exp;
+ia64_in_small_data_p (tree exp)
{
if (TARGET_NO_SDATA)
return false;
+ /* We want to merge strings, so we never consider them small data. */
+ if (TREE_CODE (exp) == STRING_CST)
+ return false;
+
+ /* Functions are never small data. */
+ if (TREE_CODE (exp) == FUNCTION_DECL)
+ return false;
+
if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
{
const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
@@ -7306,93 +7737,6 @@ ia64_in_small_data_p (exp)
return false;
}
-
-static void
-ia64_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
-{
- const char *symbol_str;
- bool is_local;
- rtx symbol;
- char encoding = 0;
-
- if (TREE_CODE (decl) == FUNCTION_DECL)
- {
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
- return;
- }
-
- /* Careful not to prod global register variables. */
- if (TREE_CODE (decl) != VAR_DECL
- || GET_CODE (DECL_RTL (decl)) != MEM
- || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
- return;
-
- symbol = XEXP (DECL_RTL (decl), 0);
- symbol_str = XSTR (symbol, 0);
-
- is_local = (*targetm.binds_local_p) (decl);
-
- if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
- encoding = " GLil"[decl_tls_model (decl)];
- /* Determine if DECL will wind up in .sdata/.sbss. */
- else if (is_local && ia64_in_small_data_p (decl))
- encoding = 's';
-
- /* Finally, encode this into the symbol string. */
- if (encoding)
- {
- char *newstr;
- size_t len;
-
- if (symbol_str[0] == ENCODE_SECTION_INFO_CHAR)
- {
- if (encoding == symbol_str[1])
- return;
- /* ??? Sdata became thread or thread becaome not thread. Lose. */
- abort ();
- }
-
- len = strlen (symbol_str);
- newstr = alloca (len + 3);
- newstr[0] = ENCODE_SECTION_INFO_CHAR;
- newstr[1] = encoding;
- memcpy (newstr + 2, symbol_str, len + 1);
-
- XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2);
- }
-
- /* This decl is marked as being in small data/bss but it shouldn't be;
- one likely explanation for this is that the decl has been moved into
- a different section from the one it was in when encode_section_info
- was first called. Remove the encoding. */
- else if (symbol_str[0] == ENCODE_SECTION_INFO_CHAR)
- XSTR (symbol, 0) = ggc_strdup (symbol_str + 2);
-}
-
-static const char *
-ia64_strip_name_encoding (str)
- const char *str;
-{
- if (str[0] == ENCODE_SECTION_INFO_CHAR)
- str += 2;
- if (str[0] == '*')
- str++;
- return str;
-}
-
-/* True if it is OK to do sibling call optimization for the specified
- call expression EXP. DECL will be the called function, or NULL if
- this is an indirect call. */
-bool
-ia64_function_ok_for_sibcall (decl)
- tree decl;
-{
- /* We must always return with our current GP. This means we can
- only sibcall to functions defined in the current module. */
- return decl && (*targetm.binds_local_p) (decl);
-}
/* Output assembly directives for prologue regions. */
@@ -7407,7 +7751,7 @@ static bool need_copy_state;
/* The function emits unwind directives for the start of an epilogue. */
static void
-process_epilogue ()
+process_epilogue (void)
{
/* If this isn't the last block of the function, then we need to label the
current state, and copy it back in at the start of the next block. */
@@ -7425,9 +7769,7 @@ process_epilogue ()
which result in emitting an assembly directive required for unwinding. */
static int
-process_set (asm_out_file, pat)
- FILE *asm_out_file;
- rtx pat;
+process_set (FILE *asm_out_file, rtx pat)
{
rtx src = SET_SRC (pat);
rtx dest = SET_DEST (pat);
@@ -7460,12 +7802,8 @@ process_set (asm_out_file, pat)
if (op0 == dest && GET_CODE (op1) == CONST_INT)
{
if (INTVAL (op1) < 0)
- {
- fputs ("\t.fframe ", asm_out_file);
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC,
- -INTVAL (op1));
- fputc ('\n', asm_out_file);
- }
+ fprintf (asm_out_file, "\t.fframe "HOST_WIDE_INT_PRINT_DEC"\n",
+ -INTVAL (op1));
else
process_epilogue ();
}
@@ -7641,9 +7979,7 @@ process_set (asm_out_file, pat)
/* This function looks at a single insn and emits any directives
required to unwind this insn. */
void
-process_for_unwind_directive (asm_out_file, insn)
- FILE *asm_out_file;
- rtx insn;
+process_for_unwind_directive (FILE *asm_out_file, rtx insn)
{
if (flag_unwind_tables
|| (flag_exceptions && !USING_SJLJ_EXCEPTIONS))
@@ -7700,7 +8036,7 @@ process_for_unwind_directive (asm_out_file, insn)
void
-ia64_init_builtins ()
+ia64_init_builtins (void)
{
tree psi_type_node = build_pointer_type (integer_type_node);
tree pdi_type_node = build_pointer_type (long_integer_type_node);
@@ -7744,6 +8080,36 @@ ia64_init_builtins ()
tree void_ftype_pdi
= build_function_type_list (void_type_node, pdi_type_node, NULL_TREE);
+ tree fpreg_type;
+ tree float80_type;
+
+ /* The __fpreg type. */
+ fpreg_type = make_node (REAL_TYPE);
+ /* ??? The back end should know to load/save __fpreg variables using
+ the ldf.fill and stf.spill instructions. */
+ TYPE_PRECISION (fpreg_type) = 96;
+ layout_type (fpreg_type);
+ (*lang_hooks.types.register_builtin_type) (fpreg_type, "__fpreg");
+
+ /* The __float80 type. */
+ float80_type = make_node (REAL_TYPE);
+ TYPE_PRECISION (float80_type) = 96;
+ layout_type (float80_type);
+ (*lang_hooks.types.register_builtin_type) (float80_type, "__float80");
+
+ /* The __float128 type. */
+ if (!TARGET_HPUX)
+ {
+ tree float128_type = make_node (REAL_TYPE);
+ TYPE_PRECISION (float128_type) = 128;
+ layout_type (float128_type);
+ (*lang_hooks.types.register_builtin_type) (float128_type, "__float128");
+ }
+ else
+ /* Under HPUX, this is a synonym for "long double". */
+ (*lang_hooks.types.register_builtin_type) (long_double_type_node,
+ "__float128");
+
#define def_builtin(name, type, code) \
builtin_function ((name), (type), (code), BUILT_IN_MD, NULL, NULL_TREE)
@@ -7772,8 +8138,8 @@ ia64_init_builtins ()
build_function_type (ptr_type_node, void_list_node),
IA64_BUILTIN_BSP);
- def_builtin ("__builtin_ia64_flushrs",
- build_function_type (void_type_node, void_list_node),
+ def_builtin ("__builtin_ia64_flushrs",
+ build_function_type (void_type_node, void_list_node),
IA64_BUILTIN_FLUSHRS);
def_builtin ("__sync_fetch_and_add_si", si_ftype_psi_si,
@@ -7844,11 +8210,8 @@ ia64_init_builtins ()
*/
static rtx
-ia64_expand_fetch_and_op (binoptab, mode, arglist, target)
- optab binoptab;
- enum machine_mode mode;
- tree arglist;
- rtx target;
+ia64_expand_fetch_and_op (optab binoptab, enum machine_mode mode,
+ tree arglist, rtx target)
{
rtx ret, label, tmp, ccv, insn, mem, value;
tree arg0, arg1;
@@ -7884,13 +8247,14 @@ ia64_expand_fetch_and_op (binoptab, mode, arglist, target)
}
tmp = gen_reg_rtx (mode);
- ccv = gen_rtx_REG (mode, AR_CCV_REGNUM);
+ /* ar.ccv must always be loaded with a zero-extended DImode value. */
+ ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
emit_move_insn (tmp, mem);
label = gen_label_rtx ();
emit_label (label);
emit_move_insn (ret, tmp);
- emit_move_insn (ccv, tmp);
+ convert_move (ccv, tmp, /*unsignedp=*/1);
/* Perform the specific operation. Special case NAND by noticing
one_cmpl_optab instead. */
@@ -7925,11 +8289,8 @@ ia64_expand_fetch_and_op (binoptab, mode, arglist, target)
*/
static rtx
-ia64_expand_op_and_fetch (binoptab, mode, arglist, target)
- optab binoptab;
- enum machine_mode mode;
- tree arglist;
- rtx target;
+ia64_expand_op_and_fetch (optab binoptab, enum machine_mode mode,
+ tree arglist, rtx target)
{
rtx old, label, tmp, ret, ccv, insn, mem, value;
tree arg0, arg1;
@@ -7953,14 +8314,15 @@ ia64_expand_op_and_fetch (binoptab, mode, arglist, target)
emit_insn (gen_mf ());
tmp = gen_reg_rtx (mode);
old = gen_reg_rtx (mode);
- ccv = gen_rtx_REG (mode, AR_CCV_REGNUM);
+ /* ar.ccv must always be loaded with a zero-extended DImode value. */
+ ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
emit_move_insn (tmp, mem);
label = gen_label_rtx ();
emit_label (label);
emit_move_insn (old, tmp);
- emit_move_insn (ccv, tmp);
+ convert_move (ccv, tmp, /*unsignedp=*/1);
/* Perform the specific operation. Special case NAND by noticing
one_cmpl_optab instead. */
@@ -7993,12 +8355,8 @@ ia64_expand_op_and_fetch (binoptab, mode, arglist, target)
*/
static rtx
-ia64_expand_compare_and_swap (rmode, mode, boolp, arglist, target)
- enum machine_mode rmode;
- enum machine_mode mode;
- int boolp;
- tree arglist;
- rtx target;
+ia64_expand_compare_and_swap (enum machine_mode rmode, enum machine_mode mode,
+ int boolp, tree arglist, rtx target)
{
tree arg0, arg1, arg2;
rtx mem, old, new, ccv, tmp, insn;
@@ -8013,6 +8371,11 @@ ia64_expand_compare_and_swap (rmode, mode, boolp, arglist, target)
mem = gen_rtx_MEM (mode, force_reg (ptr_mode, mem));
MEM_VOLATILE_P (mem) = 1;
+ if (GET_MODE (old) != mode)
+ old = convert_to_mode (mode, old, /*unsignedp=*/1);
+ if (GET_MODE (new) != mode)
+ new = convert_to_mode (mode, new, /*unsignedp=*/1);
+
if (! register_operand (old, mode))
old = copy_to_mode_reg (mode, old);
if (! register_operand (new, mode))
@@ -8024,14 +8387,7 @@ ia64_expand_compare_and_swap (rmode, mode, boolp, arglist, target)
tmp = gen_reg_rtx (mode);
ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM);
- if (mode == DImode)
- emit_move_insn (ccv, old);
- else
- {
- rtx ccvtmp = gen_reg_rtx (DImode);
- emit_insn (gen_zero_extendsidi2 (ccvtmp, old));
- emit_move_insn (ccv, ccvtmp);
- }
+ convert_move (ccv, old, /*unsignedp=*/1);
emit_insn (gen_mf ());
if (mode == SImode)
insn = gen_cmpxchg_acq_si (tmp, mem, new, ccv);
@@ -8052,10 +8408,8 @@ ia64_expand_compare_and_swap (rmode, mode, boolp, arglist, target)
/* Expand lock_test_and_set. I.e. `xchgsz ret = [ptr], new'. */
static rtx
-ia64_expand_lock_test_and_set (mode, arglist, target)
- enum machine_mode mode;
- tree arglist;
- rtx target;
+ia64_expand_lock_test_and_set (enum machine_mode mode, tree arglist,
+ rtx target)
{
tree arg0, arg1;
rtx mem, new, ret, insn;
@@ -8087,10 +8441,8 @@ ia64_expand_lock_test_and_set (mode, arglist, target)
/* Expand lock_release. I.e. `stsz.rel [ptr] = r0'. */
static rtx
-ia64_expand_lock_release (mode, arglist, target)
- enum machine_mode mode;
- tree arglist;
- rtx target ATTRIBUTE_UNUSED;
+ia64_expand_lock_release (enum machine_mode mode, tree arglist,
+ rtx target ATTRIBUTE_UNUSED)
{
tree arg0;
rtx mem;
@@ -8107,12 +8459,9 @@ ia64_expand_lock_release (mode, arglist, target)
}
rtx
-ia64_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
+ia64_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
@@ -8203,6 +8552,9 @@ ia64_expand_builtin (exp, target, subtarget, mode, ignore)
if (! target || ! register_operand (target, DImode))
target = gen_reg_rtx (DImode);
emit_insn (gen_bsp_value (target));
+#ifdef POINTERS_EXTEND_UNSIGNED
+ target = convert_memory_address (ptr_mode, target);
+#endif
return target;
case IA64_BUILTIN_FLUSHRS:
@@ -8268,9 +8620,7 @@ ia64_expand_builtin (exp, target, subtarget, mode, ignore)
most significant bits of the stack slot. */
enum direction
-ia64_hpux_function_arg_padding (mode, type)
- enum machine_mode mode;
- tree type;
+ia64_hpux_function_arg_padding (enum machine_mode mode, tree type)
{
/* Exception to normal case for structures/unions/etc. */
@@ -8278,78 +8628,124 @@ ia64_hpux_function_arg_padding (mode, type)
&& int_size_in_bytes (type) < UNITS_PER_WORD)
return upward;
- /* This is the standard FUNCTION_ARG_PADDING with !BYTES_BIG_ENDIAN
- hardwired to be true. */
-
- return((mode == BLKmode
- ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
- : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
- ? downward : upward);
+ /* Fall back to the default. */
+ return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
}
/* Linked list of all external functions that are to be emitted by GCC.
We output the name if and only if TREE_SYMBOL_REFERENCED is set in
order to avoid putting out names that are never really used. */
-struct extern_func_list
+struct extern_func_list GTY(())
{
- struct extern_func_list *next; /* next external */
- char *name; /* name of the external */
-} *extern_func_head = 0;
+ struct extern_func_list *next;
+ tree decl;
+};
+
+static GTY(()) struct extern_func_list *extern_func_head;
static void
-ia64_hpux_add_extern_decl (name)
- const char *name;
+ia64_hpux_add_extern_decl (tree decl)
{
- struct extern_func_list *p;
+ struct extern_func_list *p = ggc_alloc (sizeof (struct extern_func_list));
- p = (struct extern_func_list *) xmalloc (sizeof (struct extern_func_list));
- p->name = xmalloc (strlen (name) + 1);
- strcpy(p->name, name);
+ p->decl = decl;
p->next = extern_func_head;
extern_func_head = p;
}
/* Print out the list of used global functions. */
-void
-ia64_hpux_asm_file_end (file)
- FILE *file;
+static void
+ia64_hpux_file_end (void)
{
- while (extern_func_head)
+ struct extern_func_list *p;
+
+ for (p = extern_func_head; p; p = p->next)
{
- const char *real_name;
- tree decl;
+ tree decl = p->decl;
+ tree id = DECL_ASSEMBLER_NAME (decl);
- real_name = (* targetm.strip_name_encoding) (extern_func_head->name);
- decl = maybe_get_identifier (real_name);
+ if (!id)
+ abort ();
- if (!decl
- || (! TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (decl)))
+ if (!TREE_ASM_WRITTEN (decl) && TREE_SYMBOL_REFERENCED (id))
{
- if (decl)
- TREE_ASM_WRITTEN (decl) = 1;
- (*targetm.asm_out.globalize_label) (file, extern_func_head->name);
- fprintf (file, "%s", TYPE_ASM_OP);
- assemble_name (file, extern_func_head->name);
- putc (',', file);
- fprintf (file, TYPE_OPERAND_FMT, "function");
- putc ('\n', file);
+ const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+
+ TREE_ASM_WRITTEN (decl) = 1;
+ (*targetm.asm_out.globalize_label) (asm_out_file, name);
+ fputs (TYPE_ASM_OP, asm_out_file);
+ assemble_name (asm_out_file, name);
+ fprintf (asm_out_file, "," TYPE_OPERAND_FMT "\n", "function");
}
- extern_func_head = extern_func_head->next;
}
+
+ extern_func_head = 0;
}
+/* Rename all the TFmode libfuncs using the HPUX conventions. */
+
+static void
+ia64_hpux_init_libfuncs (void)
+{
+ set_optab_libfunc (add_optab, TFmode, "_U_Qfadd");
+ set_optab_libfunc (sub_optab, TFmode, "_U_Qfsub");
+ set_optab_libfunc (smul_optab, TFmode, "_U_Qfmpy");
+ set_optab_libfunc (sdiv_optab, TFmode, "_U_Qfdiv");
+ set_optab_libfunc (smin_optab, TFmode, "_U_Qfmin");
+ set_optab_libfunc (smax_optab, TFmode, "_U_Qfmax");
+ set_optab_libfunc (abs_optab, TFmode, "_U_Qfabs");
+ set_optab_libfunc (neg_optab, TFmode, "_U_Qfneg");
+
+ /* ia64_expand_compare uses this. */
+ cmptf_libfunc = init_one_libfunc ("_U_Qfcmp");
+
+ /* These should never be used. */
+ set_optab_libfunc (eq_optab, TFmode, 0);
+ set_optab_libfunc (ne_optab, TFmode, 0);
+ set_optab_libfunc (gt_optab, TFmode, 0);
+ set_optab_libfunc (ge_optab, TFmode, 0);
+ set_optab_libfunc (lt_optab, TFmode, 0);
+ set_optab_libfunc (le_optab, TFmode, 0);
+
+ set_conv_libfunc (sext_optab, TFmode, SFmode, "_U_Qfcnvff_sgl_to_quad");
+ set_conv_libfunc (sext_optab, TFmode, DFmode, "_U_Qfcnvff_dbl_to_quad");
+ set_conv_libfunc (sext_optab, TFmode, XFmode, "_U_Qfcnvff_f80_to_quad");
+ set_conv_libfunc (trunc_optab, SFmode, TFmode, "_U_Qfcnvff_quad_to_sgl");
+ set_conv_libfunc (trunc_optab, DFmode, TFmode, "_U_Qfcnvff_quad_to_dbl");
+ set_conv_libfunc (trunc_optab, XFmode, TFmode, "_U_Qfcnvff_quad_to_f80");
+
+ set_conv_libfunc (sfix_optab, SImode, TFmode, "_U_Qfcnvfxt_quad_to_sgl");
+ set_conv_libfunc (sfix_optab, DImode, TFmode, "_U_Qfcnvfxt_quad_to_dbl");
+ set_conv_libfunc (ufix_optab, SImode, TFmode, "_U_Qfcnvfxut_quad_to_sgl");
+ set_conv_libfunc (ufix_optab, DImode, TFmode, "_U_Qfcnvfxut_quad_to_dbl");
+
+ set_conv_libfunc (sfloat_optab, TFmode, SImode, "_U_Qfcnvxf_sgl_to_quad");
+ set_conv_libfunc (sfloat_optab, TFmode, DImode, "_U_Qfcnvxf_dbl_to_quad");
+}
+
+/* Rename the division and modulus functions in VMS. */
+
+static void
+ia64_vms_init_libfuncs (void)
+{
+ set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
+ set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
+ set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
+ set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
+ set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
+ set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
+ set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
+ set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
+}
/* Switch to the section to which we should output X. The only thing
special we do here is to honor small data. */
static void
-ia64_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align;
+ia64_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align)
{
if (GET_MODE_SIZE (mode) > 0
&& GET_MODE_SIZE (mode) <= ia64_section_threshold)
@@ -8362,27 +8758,20 @@ ia64_select_rtx_section (mode, x, align)
Pretend flag_pic is always set. */
static void
-ia64_rwreloc_select_section (exp, reloc, align)
- tree exp;
- int reloc;
- unsigned HOST_WIDE_INT align;
+ia64_rwreloc_select_section (tree exp, int reloc, unsigned HOST_WIDE_INT align)
{
default_elf_select_section_1 (exp, reloc, align, true);
}
static void
-ia64_rwreloc_unique_section (decl, reloc)
- tree decl;
- int reloc;
+ia64_rwreloc_unique_section (tree decl, int reloc)
{
default_unique_section_1 (decl, reloc, true);
}
static void
-ia64_rwreloc_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align;
+ia64_rwreloc_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align)
{
int save_pic = flag_pic;
flag_pic = 1;
@@ -8391,32 +8780,50 @@ ia64_rwreloc_select_rtx_section (mode, x, align)
}
static unsigned int
-ia64_rwreloc_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
+ia64_rwreloc_section_type_flags (tree decl, const char *name, int reloc)
{
return default_section_type_flags_1 (decl, name, reloc, true);
}
+/* Returns true if FNTYPE (a FUNCTION_TYPE or a METHOD_TYPE) returns a
+ structure type and that the address of that type should be passed
+ in out0, rather than in r8. */
+
+static bool
+ia64_struct_retval_addr_is_first_parm_p (tree fntype)
+{
+ tree ret_type = TREE_TYPE (fntype);
+
+ /* The Itanium C++ ABI requires that out0, rather than r8, be used
+ as the structure return address parameter, if the return value
+ type has a non-trivial copy constructor or destructor. It is not
+ clear if this same convention should be used for other
+ programming languages. Until G++ 3.4, we incorrectly used r8 for
+ these return values. */
+ return (abi_version_at_least (2)
+ && ret_type
+ && TYPE_MODE (ret_type) == BLKmode
+ && TREE_ADDRESSABLE (ret_type)
+ && strcmp (lang_hooks.name, "GNU C++") == 0);
+}
/* Output the assembler code for a thunk function. THUNK_DECL is the
declaration for the thunk function itself, FUNCTION is the decl for
the target function. DELTA is an immediate constant offset to be
- added to THIS. If VCALL_OFFSET is non-zero, the word at
+ added to THIS. If VCALL_OFFSET is nonzero, the word at
*(*this + vcall_offset) should be added to THIS. */
static void
-ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function)
- FILE *file;
- tree thunk ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset;
- tree function;
+ia64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
+ tree function)
{
rtx this, insn, funexp;
+ unsigned int this_parmno;
+ unsigned int this_regno;
reload_completed = 1;
+ epilogue_completed = 1;
no_new_pseudos = 1;
/* Set things up as ia64_expand_prologue might. */
@@ -8427,16 +8834,32 @@ ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function)
current_frame_info.n_input_regs = 1;
current_frame_info.need_regstk = (TARGET_REG_NAMES != 0);
- if (!TARGET_REG_NAMES)
- reg_names[IN_REG (0)] = ia64_reg_numbers[0];
-
/* Mark the end of the (empty) prologue. */
- emit_note (NULL, NOTE_INSN_PROLOGUE_END);
+ emit_note (NOTE_INSN_PROLOGUE_END);
+
+ /* Figure out whether "this" will be the first parameter (the
+ typical case) or the second parameter (as happens when the
+ virtual function returns certain class objects). */
+ this_parmno
+ = (ia64_struct_retval_addr_is_first_parm_p (TREE_TYPE (thunk))
+ ? 1 : 0);
+ this_regno = IN_REG (this_parmno);
+ if (!TARGET_REG_NAMES)
+ reg_names[this_regno] = ia64_reg_numbers[this_parmno];
- this = gen_rtx_REG (Pmode, IN_REG (0));
+ this = gen_rtx_REG (Pmode, this_regno);
if (TARGET_ILP32)
- emit_insn (gen_ptr_extend (this,
- gen_rtx_REG (ptr_mode, IN_REG (0))));
+ {
+ rtx tmp = gen_rtx_REG (ptr_mode, this_regno);
+ REG_POINTER (tmp) = 1;
+ if (delta && CONST_OK_FOR_I (delta))
+ {
+ emit_insn (gen_ptr_extend_plus_imm (this, tmp, GEN_INT (delta)));
+ delta = 0;
+ }
+ else
+ emit_insn (gen_ptr_extend (this, tmp));
+ }
/* Apply the constant offset, if required. */
if (delta)
@@ -8461,19 +8884,30 @@ ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function)
if (TARGET_ILP32)
{
rtx t = gen_rtx_REG (ptr_mode, 2);
+ REG_POINTER (t) = 1;
emit_move_insn (t, gen_rtx_MEM (ptr_mode, this));
- emit_insn (gen_ptr_extend (tmp, t));
+ if (CONST_OK_FOR_I (vcall_offset))
+ {
+ emit_insn (gen_ptr_extend_plus_imm (tmp, t,
+ vcall_offset_rtx));
+ vcall_offset = 0;
+ }
+ else
+ emit_insn (gen_ptr_extend (tmp, t));
}
else
emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
- if (!CONST_OK_FOR_J (vcall_offset))
+ if (vcall_offset)
{
- rtx tmp2 = gen_rtx_REG (Pmode, next_scratch_gr_reg ());
- emit_move_insn (tmp2, vcall_offset_rtx);
- vcall_offset_rtx = tmp2;
+ if (!CONST_OK_FOR_J (vcall_offset))
+ {
+ rtx tmp2 = gen_rtx_REG (Pmode, next_scratch_gr_reg ());
+ emit_move_insn (tmp2, vcall_offset_rtx);
+ vcall_offset_rtx = tmp2;
+ }
+ emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx));
}
- emit_insn (gen_adddi3 (tmp, tmp, vcall_offset_rtx));
if (TARGET_ILP32)
emit_move_insn (gen_rtx_REG (ptr_mode, 2),
@@ -8498,6 +8932,7 @@ ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function)
/* Code generation for calls relies on splitting. */
reload_completed = 1;
+ epilogue_completed = 1;
try_split (PATTERN (insn), insn, 0);
emit_barrier ();
@@ -8507,15 +8942,28 @@ ia64_output_mi_thunk (file, thunk, delta, vcall_offset, function)
instruction scheduling worth while. Note that use_thunk calls
assemble_start_function and assemble_end_function. */
+ insn_locators_initialize ();
+ emit_all_insn_group_barriers (NULL);
insn = get_insns ();
- emit_all_insn_group_barriers (NULL, insn);
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1, 0);
final_end_function ();
reload_completed = 0;
+ epilogue_completed = 0;
no_new_pseudos = 0;
}
+/* Worker function for TARGET_STRUCT_VALUE_RTX. */
+
+static rtx
+ia64_struct_value_rtx (tree fntype,
+ int incoming ATTRIBUTE_UNUSED)
+{
+ if (fntype && ia64_struct_retval_addr_is_first_parm_p (fntype))
+ return NULL_RTX;
+ return gen_rtx_REG (Pmode, GR_REG (8));
+}
+
#include "gt-ia64.h"
diff --git a/contrib/gcc/config/ia64/ia64.h b/contrib/gcc/config/ia64/ia64.h
index 60d014363c1e..9f7dd055df6b 100644
--- a/contrib/gcc/config/ia64/ia64.h
+++ b/contrib/gcc/config/ia64/ia64.h
@@ -1,22 +1,22 @@
/* Definitions of target machine GNU compiler. IA-64 version.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by James E. Wilson <wilson@cygnus.com> and
David Mosberger <davidm@hpl.hp.com>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -39,18 +39,17 @@ do { \
builtin_define("__ia64"); \
builtin_define("__ia64__"); \
builtin_define("__itanium__"); \
- builtin_define("__ELF__"); \
- if (!TARGET_ILP32) \
- { \
- builtin_define("_LP64"); \
- builtin_define("__LP64__"); \
- } \
if (TARGET_BIG_ENDIAN) \
builtin_define("__BIG_ENDIAN__"); \
} while (0)
+#ifndef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS
+#endif
+
#define EXTRA_SPECS \
- { "asm_extra", ASM_EXTRA_SPEC },
+ { "asm_extra", ASM_EXTRA_SPEC }, \
+ SUBTARGET_EXTRA_SPECS
#define CC1_SPEC "%(cc1_cpu) "
@@ -93,8 +92,14 @@ extern int target_flags;
#define MASK_INLINE_INT_DIV_THR 0x00001000 /* inline div, max throughput. */
+#define MASK_INLINE_SQRT_LAT 0x00002000 /* inline sqrt, min latency. */
+
+#define MASK_INLINE_SQRT_THR 0x00004000 /* inline sqrt, max throughput. */
+
#define MASK_DWARF2_ASM 0x40000000 /* test dwarf2 line info via gas. */
+#define MASK_EARLY_STOP_BITS 0x00002000 /* tune stop bits for the model. */
+
#define TARGET_BIG_ENDIAN (target_flags & MASK_BIG_ENDIAN)
#define TARGET_GNU_AS (target_flags & MASK_GNU_AS)
@@ -131,13 +136,31 @@ extern int target_flags;
#define TARGET_INLINE_INT_DIV \
(target_flags & (MASK_INLINE_INT_DIV_LAT | MASK_INLINE_INT_DIV_THR))
+#define TARGET_INLINE_SQRT_LAT (target_flags & MASK_INLINE_SQRT_LAT)
+
+#define TARGET_INLINE_SQRT_THR (target_flags & MASK_INLINE_SQRT_THR)
+
+#define TARGET_INLINE_SQRT \
+ (target_flags & (MASK_INLINE_SQRT_LAT | MASK_INLINE_SQRT_THR))
+
#define TARGET_DWARF2_ASM (target_flags & MASK_DWARF2_ASM)
+/* If the assembler supports thread-local storage, assume that the
+ system does as well. If a particular target system has an
+ assembler that supports TLS -- but the rest of the system does not
+ support TLS -- that system should explicit define TARGET_HAVE_TLS
+ to false in its own configuration file. */
+#if !defined(TARGET_HAVE_TLS) && defined(HAVE_AS_TLS)
+#define TARGET_HAVE_TLS true
+#endif
+
extern int ia64_tls_size;
#define TARGET_TLS14 (ia64_tls_size == 14)
#define TARGET_TLS22 (ia64_tls_size == 22)
#define TARGET_TLS64 (ia64_tls_size == 64)
+#define TARGET_EARLY_STOP_BITS (target_flags & MASK_EARLY_STOP_BITS)
+#define TARGET_HPUX 0
#define TARGET_HPUX_LD 0
#ifndef HAVE_AS_LTOFFX_LDXMOV_RELOCS
@@ -188,10 +211,18 @@ extern int ia64_tls_size;
N_("Generate inline integer division, optimize for latency") }, \
{ "inline-int-divide-max-throughput", MASK_INLINE_INT_DIV_THR, \
N_("Generate inline integer division, optimize for throughput") },\
+ { "inline-sqrt-min-latency", MASK_INLINE_SQRT_LAT, \
+ N_("Generate inline square root, optimize for latency") }, \
+ { "inline-sqrt-max-throughput", MASK_INLINE_SQRT_THR, \
+ N_("Generate inline square root, optimize for throughput") }, \
{ "dwarf2-asm", MASK_DWARF2_ASM, \
N_("Enable Dwarf 2 line debug info via GNU as")}, \
{ "no-dwarf2-asm", -MASK_DWARF2_ASM, \
N_("Disable Dwarf 2 line debug info via GNU as")}, \
+ { "early-stop-bits", MASK_EARLY_STOP_BITS, \
+ N_("Enable earlier placing stop bits for better scheduling")}, \
+ { "no-early-stop-bits", -MASK_EARLY_STOP_BITS, \
+ N_("Disable earlier placing stop bits")}, \
SUBTARGET_SWITCHES \
{ "", TARGET_DEFAULT | TARGET_CPU_DEFAULT, \
NULL } \
@@ -217,12 +248,30 @@ extern int ia64_tls_size;
extern const char *ia64_fixed_range_string;
extern const char *ia64_tls_size_string;
+
+/* Which processor to schedule for. The cpu attribute defines a list
+ that mirrors this list, so changes to i64.md must be made at the
+ same time. */
+
+enum processor_type
+{
+ PROCESSOR_ITANIUM, /* Original Itanium. */
+ PROCESSOR_ITANIUM2,
+ PROCESSOR_max
+};
+
+extern enum processor_type ia64_tune;
+
+extern const char *ia64_tune_string;
+
#define TARGET_OPTIONS \
{ \
{ "fixed-range=", &ia64_fixed_range_string, \
- N_("Specify range of registers to make fixed")}, \
+ N_("Specify range of registers to make fixed"), 0}, \
{ "tls-size=", &ia64_tls_size_string, \
- N_("Specify bit size of immediate TLS offsets")}, \
+ N_("Specify bit size of immediate TLS offsets"), 0}, \
+ { "tune=", &ia64_tune_string, \
+ N_("Schedule code for given CPU"), 0}, \
}
/* Sometimes certain combinations of command options do not make sense on a
@@ -242,16 +291,16 @@ extern const char *ia64_tls_size_string;
/* Driver configuration */
-/* A C string constant that tells the GNU CC driver program options to pass to
- `cc1'. It can also specify how to translate options you give to GNU CC into
- options for GNU CC to pass to the `cc1'. */
+/* A C string constant that tells the GCC driver program options to pass to
+ `cc1'. It can also specify how to translate options you give to GCC into
+ options for GCC to pass to the `cc1'. */
#undef CC1_SPEC
#define CC1_SPEC "%{G*}"
-/* A C string constant that tells the GNU CC driver program options to pass to
- `cc1plus'. It can also specify how to translate options you give to GNU CC
- into options for GNU CC to pass to the `cc1plus'. */
+/* A C string constant that tells the GCC driver program options to pass to
+ `cc1plus'. It can also specify how to translate options you give to GCC
+ into options for GCC to pass to the `cc1plus'. */
/* #define CC1PLUS_SPEC "" */
@@ -281,7 +330,7 @@ extern const char *ia64_tls_size_string;
/* A C expression whose value is zero if pointers that need to be extended
from being `POINTER_SIZE' bits wide to `Pmode' are sign-extended and one if
- they are zero-extended and negative one if there is an ptr_extend operation.
+ they are zero-extended and negative one if there is a ptr_extend operation.
You need not define this macro if the `POINTER_SIZE' is equal to the width
of `Pmode'. */
@@ -398,11 +447,11 @@ while (0)
#define DOUBLE_TYPE_SIZE 64
-#define LONG_DOUBLE_TYPE_SIZE 128
+/* long double is XFmode normally, TFmode for HPUX. */
+#define LONG_DOUBLE_TYPE_SIZE (TARGET_HPUX ? 128 : 96)
-/* By default we use the 80-bit Intel extended float format packaged
- in a 128-bit entity. */
-#define INTEL_EXTENDED_IEEE_FORMAT 1
+/* We always want the XFmode operations from libgcc2.c. */
+#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 96
#define DEFAULT_SIGNED_CHAR 1
@@ -566,7 +615,7 @@ while (0)
all the FIXED_REGISTERS. Until this problem has been
resolved this macro can be used to overcome this situation.
In particular, block_propagate() requires this list
- be acurate, or we can remove registers which should be live.
+ be accurate, or we can remove registers which should be live.
This macro is used in regs_invalidated_by_call. */
#define CALL_REALLY_USED_REGISTERS \
@@ -632,7 +681,7 @@ while (0)
/* Order of allocation of registers */
/* If defined, an initializer for a vector of integers, containing the numbers
- of hard registers in the order in which GNU CC should prefer to use them
+ of hard registers in the order in which GCC should prefer to use them
(from most preferred to least).
If this macro is not defined, registers are used lowest numbered first (all
@@ -760,7 +809,7 @@ while (0)
((REGNO) == PR_REG (0) && (MODE) == DImode ? 64 \
: PR_REGNO_P (REGNO) && (MODE) == BImode ? 2 \
: PR_REGNO_P (REGNO) && (MODE) == CCImode ? 1 \
- : FR_REGNO_P (REGNO) && (MODE) == TFmode && INTEL_EXTENDED_IEEE_FORMAT ? 1 \
+ : FR_REGNO_P (REGNO) && (MODE) == XFmode ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* A C expression that is nonzero if it is permissible to store a value of mode
@@ -772,10 +821,10 @@ while (0)
GET_MODE_CLASS (MODE) != MODE_CC && \
(MODE) != TImode && \
(MODE) != BImode && \
- ((MODE) != TFmode || INTEL_EXTENDED_IEEE_FORMAT) \
+ (MODE) != TFmode \
: PR_REGNO_P (REGNO) ? \
(MODE) == BImode || GET_MODE_CLASS (MODE) == MODE_CC \
- : GR_REGNO_P (REGNO) ? (MODE) != CCImode && (MODE) != TFmode \
+ : GR_REGNO_P (REGNO) ? (MODE) != CCImode && (MODE) != XFmode \
: AR_REGNO_P (REGNO) ? (MODE) == DImode \
: BR_REGNO_P (REGNO) ? (MODE) == DImode \
: 0)
@@ -788,12 +837,19 @@ while (0)
ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
zero. */
/* Don't tie integer and FP modes, as that causes us to get integer registers
- allocated for FP instructions. TFmode only supported in FP registers so
+ allocated for FP instructions. XFmode only supported in FP registers so
we can't tie it with any other modes. */
#define MODES_TIEABLE_P(MODE1, MODE2) \
(GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2) \
- && (((MODE1) == TFmode) == ((MODE2) == TFmode)) \
+ && (((MODE1) == XFmode) == ((MODE2) == XFmode)) \
&& (((MODE1) == BImode) == ((MODE2) == BImode)))
+
+/* Specify the modes required to caller save a given hard regno.
+ We need to ensure floating pt regs are not saved as DImode. */
+
+#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
+ ((FR_REGNO_P (REGNO) && (NREGS) == 1) ? XFmode \
+ : choose_hard_reg_mode ((REGNO), (NREGS), false))
/* Handling Leaf Functions */
@@ -992,12 +1048,12 @@ enum reg_class
into a register of CLASS2. */
#if 0
-/* ??? May need this, but since we've disallowed TFmode in GR_REGS,
+/* ??? May need this, but since we've disallowed XFmode in GR_REGS,
I'm not quite sure how it could be invoked. The normal problems
with unions should be solved with the addressof fiddling done by
- movtf and friends. */
+ movxf and friends. */
#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
- ((MODE) == TFmode && (((CLASS1) == GR_REGS && (CLASS2) == FR_REGS) \
+ ((MODE) == XFmode && (((CLASS1) == GR_REGS && (CLASS2) == FR_REGS) \
|| ((CLASS1) == FR_REGS && (CLASS2) == GR_REGS)))
#endif
@@ -1007,7 +1063,7 @@ enum reg_class
#define CLASS_MAX_NREGS(CLASS, MODE) \
((MODE) == BImode && (CLASS) == PR_REGS ? 2 \
- : ((CLASS) == FR_REGS && (MODE) == TFmode) ? 1 \
+ : ((CLASS) == FR_REGS && (MODE) == XFmode) ? 1 \
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
/* In FP regs, we can't change FP values to integer values and vice
@@ -1077,11 +1133,15 @@ enum reg_class
(GET_CODE (VALUE) == MEM \
&& GET_RTX_CLASS (GET_CODE (XEXP ((VALUE), 0))) != 'a' \
&& (reload_in_progress || memory_operand ((VALUE), VOIDmode)))
+/* Symbol ref to small-address-area: */
+#define CONSTRAINT_OK_FOR_T(VALUE) \
+ (GET_CODE (VALUE) == SYMBOL_REF && SYMBOL_REF_SMALL_ADDR_P (VALUE))
#define EXTRA_CONSTRAINT(VALUE, C) \
((C) == 'Q' ? CONSTRAINT_OK_FOR_Q (VALUE) \
: (C) == 'R' ? CONSTRAINT_OK_FOR_R (VALUE) \
: (C) == 'S' ? CONSTRAINT_OK_FOR_S (VALUE) \
+ : (C) == 'T' ? CONSTRAINT_OK_FOR_T (VALUE) \
: 0)
/* Basic Stack Layout */
@@ -1280,6 +1340,13 @@ enum reg_class
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
ia64_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
+/* Nonzero if we do not know how to pass TYPE solely in registers. */
+
+#define MUST_PASS_IN_STACK(MODE, TYPE) \
+ ((TYPE) != 0 \
+ && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
+ || TREE_ADDRESSABLE (TYPE)))
+
/* A C type for declaring a variable that is used as the first argument of
`FUNCTION_ARG' and other related values. For some target machines, the type
`int' suffices and can hold the number of bytes of argument so far. */
@@ -1295,7 +1362,7 @@ typedef struct ia64_args
/* A C statement (sans semicolon) for initializing the variable CUM for the
state at the beginning of the argument list. */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
do { \
(CUM).words = 0; \
(CUM).int_regs = 0; \
@@ -1344,7 +1411,7 @@ do { \
On many machines, no registers can be used for this purpose since all
function arguments are pushed on the stack. */
#define FUNCTION_ARG_REGNO_P(REGNO) \
-(((REGNO) >= GR_ARG_FIRST && (REGNO) < (GR_ARG_FIRST + MAX_ARGUMENT_SLOTS)) \
+(((REGNO) >= AR_ARG_FIRST && (REGNO) < (AR_ARG_FIRST + MAX_ARGUMENT_SLOTS)) \
|| ((REGNO) >= FR_ARG_FIRST && (REGNO) < (FR_ARG_FIRST + MAX_ARGUMENT_SLOTS)))
/* Implement `va_arg'. */
@@ -1366,7 +1433,7 @@ do { \
gen_rtx_REG (MODE, \
(((GET_MODE_CLASS (MODE) == MODE_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) && \
- ((MODE) != TFmode || INTEL_EXTENDED_IEEE_FORMAT)) \
+ (MODE) != TFmode) \
? FR_RET_FIRST : GR_RET_FIRST))
/* A C expression that is nonzero if REGNO is the number of a hard register in
@@ -1390,11 +1457,6 @@ do { \
#define DEFAULT_PCC_STRUCT_RETURN 0
-/* If the structure value address is passed in a register, then
- `STRUCT_VALUE_REGNUM' should be the number of that register. */
-
-#define STRUCT_VALUE_REGNUM GR_REG (8)
-
/* Caller-Saves Register Allocation */
@@ -1427,11 +1489,6 @@ do { \
#define EH_USES(REGNO) ia64_eh_uses (REGNO)
-/* Output at beginning of assembler file. */
-
-#define ASM_FILE_START(FILE) \
- emit_safe_across_calls (FILE)
-
/* Output part N of a function descriptor for DECL. For ia64, both
words are emitted with a single relocation, so ignore N > 0. */
#define ASM_OUTPUT_FDESC(FILE, DECL, PART) \
@@ -1537,7 +1594,7 @@ do { \
/* Implicit Calls to Library Routines */
-/* Define this macro if GNU CC should generate calls to the System V (and ANSI
+/* Define this macro if GCC should generate calls to the System V (and ANSI
C) library functions `memcpy' and `memset' rather than the BSD functions
`bcopy' and `bzero'. */
@@ -1643,68 +1700,6 @@ do { \
/* Describing Relative Costs of Operations */
-/* A part of a C `switch' statement that describes the relative costs of
- constant RTL expressions. */
-
-/* ??? This is incomplete. */
-
-#define CONST_COSTS(X, CODE, OUTER_CODE) \
- case CONST_INT: \
- if ((X) == const0_rtx) \
- return 0; \
- switch (OUTER_CODE) \
- { \
- case SET: \
- return CONST_OK_FOR_J (INTVAL (X)) ? 0 : COSTS_N_INSNS (1); \
- case PLUS: \
- if (CONST_OK_FOR_I (INTVAL (X))) \
- return 0; \
- if (CONST_OK_FOR_J (INTVAL (X))) \
- return 1; \
- return COSTS_N_INSNS (1); \
- default: \
- if (CONST_OK_FOR_K (INTVAL (X)) || CONST_OK_FOR_L (INTVAL (X))) \
- return 0; \
- return COSTS_N_INSNS (1); \
- } \
- case CONST_DOUBLE: \
- return COSTS_N_INSNS (1); \
- case CONST: \
- case SYMBOL_REF: \
- case LABEL_REF: \
- return COSTS_N_INSNS (3);
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions. */
-
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case MULT: \
- /* For multiplies wider than HImode, we have to go to the FPU, \
- which normally involves copies. Plus there's the latency \
- of the multiply itself, and the latency of the instructions to \
- transfer integer regs to FP regs. */ \
- if (GET_MODE_SIZE (GET_MODE (X)) > 2) \
- return COSTS_N_INSNS (10); \
- return COSTS_N_INSNS (2); \
- case PLUS: \
- case MINUS: \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- return COSTS_N_INSNS (1); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- /* We make divide expensive, so that divide-by-constant will be \
- optimized to a multiply. */ \
- return COSTS_N_INSNS (60);
-
-/* An expression giving the cost of an addressing mode that contains ADDRESS.
- If not defined, the cost is computed from the ADDRESS expression and the
- `CONST_COSTS' values. */
-
-#define ADDRESS_COST(ADDRESS) 0
-
/* A C expression for the cost of moving data from a register in class FROM to
one in class TO, using MODE. */
@@ -1757,8 +1752,6 @@ do { \
#define BSS_SECTION_ASM_OP "\t.bss"
-#define ENCODE_SECTION_INFO_CHAR '@'
-
#define IA64_DEFAULT_GVALUE 8
/* Position Independent Code. */
@@ -1791,17 +1784,12 @@ do { \
/* A C string constant for text to be output before each `asm' statement or
group of consecutive ones. */
-/* ??? This won't work with the Intel assembler, because it does not accept
- # as a comment start character. However, //APP does not work in gas, so we
- can't use that either. Same problem for ASM_APP_OFF below. */
-
-#define ASM_APP_ON "#APP\n"
+#define ASM_APP_ON (TARGET_GNU_AS ? "#APP\n" : "//APP\n")
/* A C string constant for text to be output after each `asm' statement or
group of consecutive ones. */
-#define ASM_APP_OFF "#NO_APP\n"
-
+#define ASM_APP_OFF (TARGET_GNU_AS ? "#NO_APP\n" : "//NO_APP\n")
/* Output of Uninitialized Variables. */
@@ -1843,18 +1831,9 @@ do { \
sprintf (LABEL, "*.%s%d", PREFIX, NUM); \
} while (0)
-/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
- newly allocated string made from the string NAME and the number NUMBER, with
- some suitable punctuation added. */
-
/* ??? Not sure if using a ? in the name for Intel as is safe. */
-#define ASM_FORMAT_PRIVATE_NAME(OUTVAR, NAME, NUMBER) \
-do { \
- (OUTVAR) = (char *) alloca (strlen (NAME) + 12); \
- sprintf (OUTVAR, "%s%c%ld", (NAME), (TARGET_GNU_AS ? '.' : '?'), \
- (long)(NUMBER)); \
-} while (0)
+#define ASM_PN_FORMAT (TARGET_GNU_AS ? "%s.%lu" : "%s?%lu")
/* A C statement to output to the stdio stream STREAM assembler code which
defines (equates) the symbol NAME to have the value VALUE. */
@@ -1881,7 +1860,7 @@ do { \
#define REGISTER_NAMES \
{ \
/* General registers. */ \
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", \
+ "ap", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", \
"r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", \
"r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", \
"r30", "r31", \
@@ -2035,6 +2014,13 @@ do { \
{ "loc79", LOC_REG (79) }, \
}
+/* Emit a dtp-relative reference to a TLS variable. */
+
+#ifdef HAVE_AS_TLS
+#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
+ ia64_output_dwarf_dtprel (FILE, SIZE, X)
+#endif
+
/* A C compound statement to output to stdio stream STREAM the assembler syntax
for an instruction operand X. X is an RTL expression. */
@@ -2168,7 +2154,7 @@ do { \
/* Macros for SDB and Dwarf Output. */
-/* Define this macro if GNU CC should produce dwarf version 2 format debugging
+/* Define this macro if GCC should produce dwarf version 2 format debugging
output in response to the `-g' option. */
#define DWARF2_DEBUGGING_INFO 1
@@ -2177,11 +2163,11 @@ do { \
/* Use tags for debug info labels, so that they don't break instruction
bundles. This also avoids getting spurious DV warnings from the
- assembler. This is similar to ASM_OUTPUT_INTERNAL_LABEL, except that we
+ assembler. This is similar to (*targetm.asm_out.internal_label), except that we
add brackets around the label. */
#define ASM_OUTPUT_DEBUG_LABEL(FILE, PREFIX, NUM) \
- fprintf (FILE, "[.%s%d:]\n", PREFIX, NUM)
+ fprintf (FILE, TARGET_GNU_AS ? "[.%s%d:]\n" : ".%s%d:\n", PREFIX, NUM)
/* Use section-relative relocations for debugging offsets. Unlike other
targets that fake this by putting the section VMA at 0, IA-64 has
@@ -2214,6 +2200,12 @@ do { \
/* Miscellaneous Parameters. */
+/* Flag to mark data that is in the small address area (addressable
+ via "addl", that is, within a 2MByte offset of 0. */
+#define SYMBOL_FLAG_SMALL_ADDR (SYMBOL_FLAG_MACH_DEP << 0)
+#define SYMBOL_REF_SMALL_ADDR_P(X) \
+ ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_SMALL_ADDR) != 0)
+
/* Define this if you have defined special-purpose predicates in the file
`MACHINE.c'. For each predicate, list all rtl codes that can be in
expressions matched by the predicate. */
@@ -2222,6 +2214,7 @@ do { \
{ "call_operand", {SUBREG, REG, SYMBOL_REF}}, \
{ "got_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{ "sdata_symbolic_operand", {SYMBOL_REF, CONST}}, \
+{ "small_addr_symbolic_operand", {SYMBOL_REF}}, \
{ "symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{ "function_operand", {SYMBOL_REF}}, \
{ "setjmp_operand", {SYMBOL_REF}}, \
@@ -2260,9 +2253,9 @@ do { \
{ "ar_lc_reg_operand", {REG}}, \
{ "ar_ccv_reg_operand", {REG}}, \
{ "ar_pfs_reg_operand", {REG}}, \
-{ "general_tfmode_operand", {SUBREG, REG, CONST_DOUBLE, MEM}}, \
-{ "destination_tfmode_operand", {SUBREG, REG, MEM}}, \
-{ "tfreg_or_fp01_operand", {REG, CONST_DOUBLE}}, \
+{ "general_xfmode_operand", {SUBREG, REG, CONST_DOUBLE, MEM}}, \
+{ "destination_xfmode_operand", {SUBREG, REG, MEM}}, \
+{ "xfreg_or_fp01_operand", {REG, CONST_DOUBLE}}, \
{ "basereg_operand", {SUBREG, REG}},
/* An alias for a machine mode name. This is the machine mode that elements of
@@ -2302,9 +2295,7 @@ do { \
an integral mode and stored by a store-flag instruction (`sCOND') when the
condition is true. */
-/* ??? Investigate using -1 instead of 1. */
-
-#define STORE_FLAG_VALUE 1
+/* ??? Investigate using STORE_FLAG_VALUE of -1 instead of 1. */
/* An alias for the machine mode for pointers. */
@@ -2336,13 +2327,6 @@ do { \
#define HANDLE_SYSV_PRAGMA 1
-/* In rare cases, correct code generation requires extra machine dependent
- processing between the second jump optimization pass and delayed branch
- scheduling. On those machines, define this macro as a C statement to act on
- the code starting at INSN. */
-
-#define MACHINE_DEPENDENT_REORG(INSN) ia64_reorg (INSN)
-
/* A C expression for the maximum number of instructions to execute via
conditional execution instructions instead of a branch. A value of
BRANCH_COST+1 is the default if the machine does not use
@@ -2440,5 +2424,9 @@ enum fetchop_code {
#undef PROFILE_BEFORE_PROLOGUE
#define PROFILE_BEFORE_PROLOGUE 1
-#define FUNCTION_OK_FOR_SIBCALL(DECL) ia64_function_ok_for_sibcall (DECL)
+
+
+/* Switch on code for querying unit reservations. */
+#define CPU_UNITS_QUERY 1
+
/* End of ia64.h */
diff --git a/contrib/gcc/config/ia64/ia64.md b/contrib/gcc/config/ia64/ia64.md
index 3b88d9f81c36..4bda8f4d3d0c 100644
--- a/contrib/gcc/config/ia64/ia64.md
+++ b/contrib/gcc/config/ia64/ia64.md
@@ -1,22 +1,23 @@
;; IA-64 Machine description template
-;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+;; Free Software Foundation, Inc.
;; Contributed by James E. Wilson <wilson@cygnus.com> and
;; David Mosberger <davidm@hpl.hp.com>.
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
@@ -63,7 +64,7 @@
(UNSPEC_FR_RESTORE 13)
(UNSPEC_FR_RECIP_APPROX 14)
(UNSPEC_PRED_REL_MUTEX 15)
- (UNSPEC_POPCNT 16)
+ (UNSPEC_GETF_EXP 16)
(UNSPEC_PIC_CALL 17)
(UNSPEC_MF 18)
(UNSPEC_CMPXCHG_ACQ 19)
@@ -74,6 +75,8 @@
(UNSPEC_ADDP4 24)
(UNSPEC_PROLOGUE_USE 25)
(UNSPEC_RET_ADDR 26)
+ (UNSPEC_SETF_EXP 27)
+ (UNSPEC_FR_SQRT_RECIP_APPROX 28)
])
(define_constants
@@ -93,6 +96,10 @@
;; ::
;; ::::::::::::::::::::
+;; Processor type. This attribute must exactly match the processor_type
+;; enumeration in ia64.h.
+(define_attr "cpu" "itanium,itanium2" (const (symbol_ref "ia64_tune")))
+
;; Instruction type. This primarily determines how instructions can be
;; packed in bundles, and secondarily affects scheduling to function units.
@@ -112,8 +119,8 @@
(define_attr "itanium_class" "unknown,ignore,stop_bit,br,fcmp,fcvtfx,fld,
fmac,fmisc,frar_i,frar_m,frbr,frfr,frpr,ialu,icmp,ilog,ishf,ld,
chk_s,long_i,mmmul,mmshf,mmshfi,rse_m,scall,sem,stf,st,syst_m0,
- syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop_b,nop_f,
- nop_i,nop_m,nop_x,lfetch"
+ syst_m,tbit,toar_i,toar_m,tobr,tofr,topr,xmpy,xtd,nop,nop_b,nop_f,
+ nop_i,nop_m,nop_x,lfetch,pre_cycle"
(const_string "unknown"))
;; chk_s has an I and an M form; use type A for convenience.
@@ -147,77 +154,28 @@
(define_attr "predicable" "no,yes" (const_string "yes"))
+;; Empty. True iff this insn does not generate any code.
+
+(define_attr "empty" "no,yes" (const_string "no"))
+
-;; ::::::::::::::::::::
-;; ::
-;; :: Function Units
-;; ::
-;; ::::::::::::::::::::
-;; We define 6 "dummy" functional units. All the real work to decide which
-;; insn uses which unit is done by our MD_SCHED_REORDER hooks. We only
-;; have to ensure here that there are enough copies of the dummy unit so
-;; that the scheduler doesn't get confused by MD_SCHED_REORDER.
-;; Other than the 6 dummies for normal insns, we also add a single dummy unit
-;; for stop bits.
-
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "br") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "scall") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcmp") 2 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fcvtfx") 7 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fld") 9 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmac") 5 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "fmisc") 5 0)
-
-;; There is only one insn `mov = ar.bsp' for frar_i:
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_i") 13 0)
-;; There is only ony insn `mov = ar.unat' for frar_m:
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frar_m") 6 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frbr") 2 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frfr") 2 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "frpr") 2 0)
-
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ialu") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "icmp") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ilog") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ishf") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ld") 2 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "long_i") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmmul") 2 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshf") 2 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "mmshfi") 2 0)
-
-;; Now we have only one insn (flushrs) of such class. We assume that flushrs
-;; is the 1st syllable of the bundle after stop bit.
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "rse_m") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "sem") 11 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "stf") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "st") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m0") 1 0)
-;; Now we use only one insn `mf'. Therfore latency time is set up to 0.
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "syst_m") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tbit") 1 0)
-
-;; There is only one insn `mov ar.pfs =' for toar_i therefore we use
-;; latency time equal to 0:
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_i") 0 0)
-;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m:
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "toar_m") 5 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tobr") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "tofr") 9 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "topr") 1 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xmpy") 7 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "xtd") 1 0)
-
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_m") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_i") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_f") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_b") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "nop_x") 0 0)
-
-(define_function_unit "stop_bit" 1 1 (eq_attr "itanium_class" "stop_bit") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "ignore") 0 0)
-(define_function_unit "dummy" 6 1 (eq_attr "itanium_class" "unknown") 0 0)
+;; DFA descriptions of ia64 processors used for insn scheduling and
+;; bundling.
+
+(automata_option "ndfa")
+
+;; Uncomment the following line to output automata for debugging.
+;; (automata_option "v")
+
+(automata_option "w")
+
+;;(automata_option "no-minimization")
+
+
+(include "itanium1.md")
+(include "itanium2.md")
+
;; ::::::::::::::::::::
;; ::
@@ -342,29 +300,6 @@
operands[1] = op1;
})
-;; This is used during early compilation to delay the decision on
-;; how to refer to a variable as long as possible. This is especially
-;; important between initial rtl generation and optimization for
-;; deferred functions, since we may acquire additional information
-;; on the variables used in the meantime.
-
-(define_insn_and_split "movsi_symbolic"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "symbolic_operand" "s"))
- (clobber (match_scratch:DI 2 "=r"))
- (use (reg:DI 1))]
- ""
- "* abort ();"
- "!no_new_pseudos || reload_completed"
- [(const_int 0)]
-{
- rtx scratch = operands[2];
- if (!reload_completed)
- scratch = gen_reg_rtx (Pmode);
- ia64_expand_load_address (operands[0], operands[1], scratch);
- DONE;
-})
-
(define_insn "*movsi_internal"
[(set (match_operand:SI 0 "destination_operand" "=r,r,r,r, m, r,*f,*f, r,*d")
(match_operand:SI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,*d,rK"))]
@@ -394,53 +329,11 @@
operands[1] = op1;
})
-;; This is used during early compilation to delay the decision on
-;; how to refer to a variable as long as possible. This is especially
-;; important between initial rtl generation and optimization for
-;; deferred functions, since we may acquire additional information
-;; on the variables used in the meantime.
-
-(define_insn_and_split "movdi_symbolic"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (match_operand:DI 1 "symbolic_operand" "s"))
- (clobber (match_scratch:DI 2 "=r"))
- (use (reg:DI 1))]
- ""
- "* abort ();"
- "!no_new_pseudos || reload_completed"
- [(const_int 0)]
-{
- rtx scratch = operands[2];
- if (!reload_completed)
- scratch = gen_reg_rtx (Pmode);
- ia64_expand_load_address (operands[0], operands[1], scratch);
- DONE;
-})
-
-;; This is used as a placeholder for the return address during early
-;; compilation. We won't know where we've placed this until during
-;; reload, at which point it can wind up in b0, a general register,
-;; or memory. The only safe destination under these conditions is a
-;; general register.
-
-(define_insn_and_split "*movdi_ret_addr"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))]
- ""
- "#"
- "reload_completed"
- [(const_int 0)]
-{
- ia64_split_return_addr_rtx (operands[0]);
- DONE;
-}
- [(set_attr "itanium_class" "ialu")])
-
(define_insn "*movdi_internal"
[(set (match_operand:DI 0 "destination_operand"
"=r,r,r,r, m, r,*f,*f,*f, Q, r,*b, r,*e, r,*d, r,*c")
(match_operand:DI 1 "move_operand"
- "rO,J,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
+ "rO,JT,i,m,rO,*f,rO,*f, Q,*f,*b,rO,*e,rK,*d,rK,*c,rO"))]
"ia64_move_ok (operands[0], operands[1])"
{
static const char * const alt[] = {
@@ -473,12 +366,12 @@
[(set_attr "itanium_class" "ialu,ialu,long_i,ld,st,frfr,tofr,fmisc,fld,stf,frbr,tobr,frar_i,toar_i,frar_m,toar_m,frpr,topr")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "symbolic_operand" ""))]
+ [(set (match_operand 0 "register_operand" "")
+ (match_operand 1 "symbolic_operand" ""))]
"reload_completed && ! TARGET_NO_PIC"
[(const_int 0)]
{
- ia64_expand_load_address (operands[0], operands[1], NULL_RTX);
+ ia64_expand_load_address (operands[0], operands[1]);
DONE;
})
@@ -525,16 +418,24 @@
operands[3] = pic_offset_table_rtx;
})
-(define_expand "load_symptr"
- [(set (match_operand:DI 2 "register_operand" "")
- (plus:DI (high:DI (match_operand:DI 1 "got_symbolic_operand" ""))
- (match_dup 3)))
- (set (match_operand:DI 0 "register_operand" "")
- (lo_sum:DI (match_dup 2) (match_dup 1)))]
+;; This is used as a placeholder for the return address during early
+;; compilation. We won't know where we've placed this until during
+;; reload, at which point it can wind up in b0, a general register,
+;; or memory. The only safe destination under these conditions is a
+;; general register.
+
+(define_insn_and_split "*movdi_ret_addr"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))]
""
+ "#"
+ "reload_completed"
+ [(const_int 0)]
{
- operands[3] = pic_offset_table_rtx;
-})
+ ia64_split_return_addr_rtx (operands[0]);
+ DONE;
+}
+ [(set_attr "itanium_class" "ialu")])
(define_insn "*load_symptr_high"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -688,11 +589,12 @@
[(set_attr "itanium_class" "ialu")])
;; With no offsettable memory references, we've got to have a scratch
-;; around to play with the second word.
+;; around to play with the second word. However, in order to avoid a
+;; reload nightmare we lie, claim we don't need one, and fix it up
+;; in ia64_split_tmode_move.
(define_expand "movti"
- [(parallel [(set (match_operand:TI 0 "general_operand" "")
- (match_operand:TI 1 "general_operand" ""))
- (clobber (match_scratch:DI 2 ""))])]
+ [(set (match_operand:TI 0 "general_operand" "")
+ (match_operand:TI 1 "general_operand" ""))]
""
{
rtx op1 = ia64_expand_move (operands[0], operands[1]);
@@ -703,106 +605,18 @@
(define_insn_and_split "*movti_internal"
[(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
- (match_operand:TI 1 "general_operand" "ri,m,r"))
- (clobber (match_scratch:DI 2 "=X,&r,&r"))]
+ (match_operand:TI 1 "general_operand" "ri,m,r"))]
"ia64_move_ok (operands[0], operands[1])"
"#"
"reload_completed"
[(const_int 0)]
{
- rtx adj1, adj2, in[2], out[2], insn;
- int first;
-
- adj1 = ia64_split_timode (in, operands[1], operands[2]);
- adj2 = ia64_split_timode (out, operands[0], operands[2]);
-
- first = 0;
- if (reg_overlap_mentioned_p (out[0], in[1]))
- {
- if (reg_overlap_mentioned_p (out[1], in[0]))
- abort ();
- first = 1;
- }
-
- if (adj1 && adj2)
- abort ();
- if (adj1)
- emit_insn (adj1);
- if (adj2)
- emit_insn (adj2);
- insn = emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
- if (GET_CODE (out[first]) == MEM
- && GET_CODE (XEXP (out[first], 0)) == POST_MODIFY)
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
- XEXP (XEXP (out[first], 0), 0),
- REG_NOTES (insn));
- insn = emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
- if (GET_CODE (out[!first]) == MEM
- && GET_CODE (XEXP (out[!first], 0)) == POST_MODIFY)
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_INC,
- XEXP (XEXP (out[!first], 0), 0),
- REG_NOTES (insn));
- DONE;
-}
- [(set_attr "itanium_class" "unknown")
- (set_attr "predicable" "no")])
-
-;; ??? SSA creates these. Can't allow memories since we don't have
-;; the scratch register. Fortunately combine will know how to add
-;; the clobber and scratch.
-(define_insn_and_split "*movti_internal_reg"
- [(set (match_operand:TI 0 "register_operand" "=r")
- (match_operand:TI 1 "nonmemory_operand" "ri"))]
- ""
- "#"
- "reload_completed"
- [(const_int 0)]
-{
- rtx in[2], out[2];
- int first;
-
- ia64_split_timode (in, operands[1], NULL_RTX);
- ia64_split_timode (out, operands[0], NULL_RTX);
-
- first = 0;
- if (reg_overlap_mentioned_p (out[0], in[1]))
- {
- if (reg_overlap_mentioned_p (out[1], in[0]))
- abort ();
- first = 1;
- }
-
- emit_insn (gen_rtx_SET (VOIDmode, out[first], in[first]));
- emit_insn (gen_rtx_SET (VOIDmode, out[!first], in[!first]));
+ ia64_split_tmode_move (operands);
DONE;
}
[(set_attr "itanium_class" "unknown")
(set_attr "predicable" "no")])
-(define_expand "reload_inti"
- [(parallel [(set (match_operand:TI 0 "register_operand" "=r")
- (match_operand:TI 1 "" "m"))
- (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
- ""
-{
- unsigned int s_regno = REGNO (operands[2]);
- if (s_regno == REGNO (operands[0]))
- s_regno += 1;
- operands[2] = gen_rtx_REG (DImode, s_regno);
-})
-
-(define_expand "reload_outti"
- [(parallel [(set (match_operand:TI 0 "" "=m")
- (match_operand:TI 1 "register_operand" "r"))
- (clobber (match_operand:TI 2 "register_operand" "=&r"))])]
- ""
-{
- unsigned int s_regno = REGNO (operands[2]);
- if (s_regno == REGNO (operands[1]))
- s_regno += 1;
- operands[2] = gen_rtx_REG (DImode, s_regno);
-})
-
;; Floating Point Moves
;;
;; Note - Patterns for SF mode moves are compulsory, but
@@ -862,19 +676,19 @@
;; With no offsettable memory references, we've got to have a scratch
;; around to play with the second word if the variable winds up in GRs.
-(define_expand "movtf"
- [(set (match_operand:TF 0 "general_operand" "")
- (match_operand:TF 1 "general_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_expand "movxf"
+ [(set (match_operand:XF 0 "general_operand" "")
+ (match_operand:XF 1 "general_operand" ""))]
+ ""
{
- /* We must support TFmode loads into general registers for stdarg/vararg
+ /* We must support XFmode loads into general registers for stdarg/vararg
and unprototyped calls. We split them into DImode loads for convenience.
- We don't need TFmode stores from general regs, because a stdarg/vararg
+ We don't need XFmode stores from general regs, because a stdarg/vararg
routine does a block store to memory of unnamed arguments. */
if (GET_CODE (operands[0]) == REG
&& GR_REGNO_P (REGNO (operands[0])))
{
- /* We're hoping to transform everything that deals with TFmode
+ /* We're hoping to transform everything that deals with XFmode
quantities and GR registers early in the compiler. */
if (no_new_pseudos)
abort ();
@@ -893,15 +707,15 @@
if (GET_CODE (operands[1]) == CONST_DOUBLE)
{
emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0])),
- operand_subword (operands[1], 0, 0, TFmode));
+ operand_subword (operands[1], 0, 0, XFmode));
emit_move_insn (gen_rtx_REG (DImode, REGNO (operands[0]) + 1),
- operand_subword (operands[1], 1, 0, TFmode));
+ operand_subword (operands[1], 1, 0, XFmode));
DONE;
}
/* If the quantity is in a register not known to be GR, spill it. */
- if (register_operand (operands[1], TFmode))
- operands[1] = spill_tfmode_operand (operands[1], 1);
+ if (register_operand (operands[1], XFmode))
+ operands[1] = spill_xfmode_operand (operands[1], 1);
if (GET_CODE (operands[1]) == MEM)
{
@@ -920,25 +734,53 @@
if (! reload_in_progress && ! reload_completed)
{
- operands[0] = spill_tfmode_operand (operands[0], 0);
- operands[1] = spill_tfmode_operand (operands[1], 0);
+ operands[0] = spill_xfmode_operand (operands[0], 0);
+ operands[1] = spill_xfmode_operand (operands[1], 0);
if (! ia64_move_ok (operands[0], operands[1]))
- operands[1] = force_reg (TFmode, operands[1]);
+ operands[1] = force_reg (XFmode, operands[1]);
}
})
;; ??? There's no easy way to mind volatile acquire/release semantics.
-(define_insn "*movtf_internal"
- [(set (match_operand:TF 0 "destination_tfmode_operand" "=f,f, m")
- (match_operand:TF 1 "general_tfmode_operand" "fG,m,fG"))]
- "INTEL_EXTENDED_IEEE_FORMAT && ia64_move_ok (operands[0], operands[1])"
+(define_insn "*movxf_internal"
+ [(set (match_operand:XF 0 "destination_xfmode_operand" "=f,f, m")
+ (match_operand:XF 1 "general_xfmode_operand" "fG,m,fG"))]
+ "ia64_move_ok (operands[0], operands[1])"
"@
mov %0 = %F1
ldfe %0 = %1%P1
stfe %0 = %F1%P0"
[(set_attr "itanium_class" "fmisc,fld,stf")])
+
+;; Better code generation via insns that deal with TFmode register pairs
+;; directly. Same concerns apply as for TImode.
+(define_expand "movtf"
+ [(set (match_operand:TF 0 "general_operand" "")
+ (match_operand:TF 1 "general_operand" ""))]
+ ""
+{
+ rtx op1 = ia64_expand_move (operands[0], operands[1]);
+ if (!op1)
+ DONE;
+ operands[1] = op1;
+})
+
+(define_insn_and_split "*movtf_internal"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=r,r,m")
+ (match_operand:TF 1 "general_operand" "ri,m,r"))]
+ "ia64_move_ok (operands[0], operands[1])"
+ "#"
+ "reload_completed"
+ [(const_int 0)]
+{
+ ia64_split_tmode_move (operands);
+ DONE;
+}
+ [(set_attr "itanium_class" "unknown")
+ (set_attr "predicable" "no")])
+
;; ::::::::::::::::::::
;; ::
@@ -1025,17 +867,17 @@
"fnorm.d %0 = %1"
[(set_attr "itanium_class" "fmac")])
-(define_insn "extendsftf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (float_extend:TF (match_operand:SF 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "extendsfxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (float_extend:XF (match_operand:SF 1 "fr_register_operand" "f")))]
+ ""
"fnorm %0 = %1"
[(set_attr "itanium_class" "fmac")])
-(define_insn "extenddftf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (float_extend:TF (match_operand:DF 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "extenddfxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (float_extend:XF (match_operand:DF 1 "fr_register_operand" "f")))]
+ ""
"fnorm %0 = %1"
[(set_attr "itanium_class" "fmac")])
@@ -1046,45 +888,29 @@
"fnorm.s %0 = %1"
[(set_attr "itanium_class" "fmac")])
-(define_insn "trunctfsf2"
+(define_insn "truncxfsf2"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
- (float_truncate:SF (match_operand:TF 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (float_truncate:SF (match_operand:XF 1 "fr_register_operand" "f")))]
+ ""
"fnorm.s %0 = %1"
[(set_attr "itanium_class" "fmac")])
-(define_insn "trunctfdf2"
+(define_insn "truncxfdf2"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
- (float_truncate:DF (match_operand:TF 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (float_truncate:DF (match_operand:XF 1 "fr_register_operand" "f")))]
+ ""
"fnorm.d %0 = %1"
[(set_attr "itanium_class" "fmac")])
;; Convert between signed integer types and floating point.
-(define_insn "floatditf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "floatdixf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
+ ""
"fcvt.xf %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
-;; ??? Suboptimal. This should be split somehow.
-(define_insn "floatdidf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (float:DF (match_operand:DI 1 "register_operand" "f")))]
- "!INTEL_EXTENDED_IEEE_FORMAT"
- "fcvt.xf %0 = %1\;;;\;%,fnorm.d %0 = %0"
- [(set_attr "itanium_class" "fcvtfx")])
-
-;; ??? Suboptimal. This should be split somehow.
-(define_insn "floatdisf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (float:SF (match_operand:DI 1 "register_operand" "f")))]
- "!INTEL_EXTENDED_IEEE_FORMAT"
- "fcvt.xf %0 = %1\;;;\;%,fnorm.s %0 = %0"
- [(set_attr "itanium_class" "fcvtfx")])
-
(define_insn "fix_truncsfdi2"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
(fix:DI (match_operand:SF 1 "fr_register_operand" "f")))]
@@ -1099,18 +925,18 @@
"fcvt.fx.trunc %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
-(define_insn "fix_trunctfdi2"
+(define_insn "fix_truncxfdi2"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
- (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
+ ""
"fcvt.fx.trunc %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
-(define_insn "fix_trunctfdi2_alts"
+(define_insn "fix_truncxfdi2_alts"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
- (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
+ (fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
(use (match_operand:SI 2 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fcvt.fx.trunc.s%2 %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
@@ -1130,10 +956,10 @@
"fcvt.xuf.d %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
-(define_insn "floatunsditf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (unsigned_float:TF (match_operand:DI 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "floatunsdixf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "f")))]
+ ""
"fcvt.xuf %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
@@ -1151,18 +977,18 @@
"fcvt.fxu.trunc %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
-(define_insn "fixuns_trunctfdi2"
+(define_insn "fixuns_truncxfdi2"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
- (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))]
+ ""
"fcvt.fxu.trunc %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
-(define_insn "fixuns_trunctfdi2_alts"
+(define_insn "fixuns_truncxfdi2_alts"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
- (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
+ (unsigned_fix:DI (match_operand:XF 1 "fr_register_operand" "f")))
(use (match_operand:SI 2 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fcvt.fxu.trunc.s%2 %0 = %1"
[(set_attr "itanium_class" "fcvtfx")])
@@ -2027,32 +1853,32 @@
[(set (match_operand:SI 0 "register_operand" "")
(div:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
- rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
+ rtx op1_xf, op2_xf, op0_xf, op0_di, twon34;
REAL_VALUE_TYPE twon34_r;
- op0_tf = gen_reg_rtx (TFmode);
+ 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_tf = gen_reg_rtx (TFmode);
- expand_float (op1_tf, operands[1], 0);
+ 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_tf = gen_reg_rtx (TFmode);
- expand_float (op2_tf, operands[2], 0);
+ op2_xf = gen_reg_rtx (XFmode);
+ expand_float (op2_xf, operands[2], 0);
/* 2^-34 */
real_2expN (&twon34_r, -34);
- twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode);
- twon34 = force_reg (TFmode, twon34);
+ twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode);
+ twon34 = force_reg (XFmode, twon34);
- emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
+ emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
- emit_insn (gen_fix_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
+ emit_insn (gen_fix_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
DONE;
})
@@ -2061,7 +1887,7 @@
[(set (match_operand:SI 0 "register_operand" "")
(mod:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
rtx op2_neg, op1_di, div;
@@ -2084,32 +1910,32 @@
[(set (match_operand:SI 0 "register_operand" "")
(udiv:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
- rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
+ rtx op1_xf, op2_xf, op0_xf, op0_di, twon34;
REAL_VALUE_TYPE twon34_r;
- op0_tf = gen_reg_rtx (TFmode);
+ 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_tf = gen_reg_rtx (TFmode);
- expand_float (op1_tf, operands[1], 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_tf = gen_reg_rtx (TFmode);
- expand_float (op2_tf, operands[2], 1);
+ op2_xf = gen_reg_rtx (XFmode);
+ expand_float (op2_xf, operands[2], 1);
/* 2^-34 */
real_2expN (&twon34_r, -34);
- twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, TFmode);
- twon34 = force_reg (TFmode, twon34);
+ twon34 = CONST_DOUBLE_FROM_REAL_VALUE (twon34_r, XFmode);
+ twon34 = force_reg (XFmode, twon34);
- emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
+ emit_insn (gen_divsi3_internal (op0_xf, op1_xf, op2_xf, twon34));
- emit_insn (gen_fixuns_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
+ emit_insn (gen_fixuns_truncxfdi2_alts (op0_di, op0_xf, const1_rtx));
emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
DONE;
})
@@ -2118,7 +1944,7 @@
[(set (match_operand:SI 0 "register_operand" "")
(umod:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
rtx op2_neg, op1_di, div;
@@ -2138,45 +1964,45 @@
})
(define_insn_and_split "divsi3_internal"
- [(set (match_operand:TF 0 "fr_register_operand" "=&f")
- (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
- (match_operand:TF 2 "fr_register_operand" "f"))))
- (clobber (match_scratch:TF 4 "=&f"))
- (clobber (match_scratch:TF 5 "=&f"))
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
+ (match_operand:XF 2 "fr_register_operand" "f"))))
+ (clobber (match_scratch:XF 4 "=&f"))
+ (clobber (match_scratch:XF 5 "=&f"))
(clobber (match_scratch:BI 6 "=c"))
- (use (match_operand:TF 3 "fr_register_operand" "f"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ (use (match_operand:XF 3 "fr_register_operand" "f"))]
+ "TARGET_INLINE_INT_DIV"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
(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:TF (match_dup 1) (match_dup 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)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (mult:TF (match_dup 5) (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:TF (mult:TF (match_dup 5) (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:TF (mult:TF (match_dup 5) (match_dup 4))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 4))
(match_dup 4)))
(use (const_int 1))]))
]
- "operands[7] = CONST1_RTX (TFmode);"
+ "operands[7] = CONST1_RTX (XFmode);"
[(set_attr "predicable" "no")])
;; ::::::::::::::::::::
@@ -2390,7 +2216,7 @@
(set (match_dup 2) (plus:DI (match_dup 1) (const_int -1)))
(set (match_dup 5) (const_int 0))
(set (match_dup 3) (xor:DI (match_dup 1) (match_dup 2)))
- (set (match_dup 4) (unspec:DI [(match_dup 3)] UNSPEC_POPCNT))
+ (set (match_dup 4) (popcount:DI (match_dup 3)))
(set (match_operand:DI 0 "gr_register_operand" "")
(if_then_else:DI (ne (match_dup 6) (const_int 0))
(match_dup 5) (match_dup 4)))]
@@ -2403,40 +2229,77 @@
operands[6] = gen_reg_rtx (BImode);
})
-(define_insn "*popcnt"
+(define_expand "ctzdi2"
+ [(set (match_dup 2) (plus:DI (match_operand:DI 1 "gr_register_operand" "")
+ (const_int -1)))
+ (set (match_dup 3) (not:DI (match_dup 1)))
+ (set (match_dup 4) (and:DI (match_dup 2) (match_dup 3)))
+ (set (match_operand:DI 0 "gr_register_operand" "")
+ (popcount:DI (match_dup 4)))]
+ ""
+{
+ operands[2] = gen_reg_rtx (DImode);
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+})
+
+;; Note the computation here is op0 = 63 - (exp - 0xffff).
+(define_expand "clzdi2"
+ [(set (match_dup 2)
+ (unsigned_float:XF (match_operand:DI 1 "fr_register_operand" "")))
+ (set (match_dup 3)
+ (unspec:DI [(match_dup 2)] UNSPEC_GETF_EXP))
+ (set (match_dup 4) (const_int 65598))
+ (set (match_operand:DI 0 "gr_register_operand" "")
+ (minus:DI (match_dup 4) (match_dup 3)))]
+ ""
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+})
+
+(define_insn "popcountdi2"
[(set (match_operand:DI 0 "gr_register_operand" "=r")
- (unspec:DI [(match_operand:DI 1 "gr_register_operand" "r")]
- UNSPEC_POPCNT))]
+ (popcount:DI (match_operand:DI 1 "gr_register_operand" "r")))]
""
"popcnt %0 = %1"
[(set_attr "itanium_class" "mmmul")])
+(define_insn "*getf_exp_xf"
+ [(set (match_operand:DI 0 "gr_register_operand" "=r")
+ (unspec:DI [(match_operand:XF 1 "fr_register_operand" "f")]
+ UNSPEC_GETF_EXP))]
+ ""
+ "getf.exp %0 = %1"
+ [(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" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
- rtx op1_tf, op2_tf, op0_tf;
+ rtx op1_xf, op2_xf, op0_xf;
- op0_tf = gen_reg_rtx (TFmode);
+ op0_xf = gen_reg_rtx (XFmode);
if (CONSTANT_P (operands[1]))
operands[1] = force_reg (DImode, operands[1]);
- op1_tf = gen_reg_rtx (TFmode);
- expand_float (op1_tf, operands[1], 0);
+ 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_tf = gen_reg_rtx (TFmode);
- expand_float (op2_tf, operands[2], 0);
+ op2_xf = gen_reg_rtx (XFmode);
+ expand_float (op2_xf, operands[2], 0);
if (TARGET_INLINE_INT_DIV_LAT)
- emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
+ emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
else
- emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
+ emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
- emit_insn (gen_fix_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
+ emit_insn (gen_fix_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
DONE;
})
@@ -2444,7 +2307,7 @@
[(set (match_operand:DI 0 "register_operand" "")
(mod:SI (match_operand:DI 1 "general_operand" "")
(match_operand:DI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
rtx op2_neg, div;
@@ -2461,28 +2324,28 @@
[(set (match_operand:DI 0 "register_operand" "")
(udiv:DI (match_operand:DI 1 "general_operand" "")
(match_operand:DI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
- rtx op1_tf, op2_tf, op0_tf;
+ rtx op1_xf, op2_xf, op0_xf;
- op0_tf = gen_reg_rtx (TFmode);
+ op0_xf = gen_reg_rtx (XFmode);
if (CONSTANT_P (operands[1]))
operands[1] = force_reg (DImode, operands[1]);
- op1_tf = gen_reg_rtx (TFmode);
- expand_float (op1_tf, operands[1], 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_tf = gen_reg_rtx (TFmode);
- expand_float (op2_tf, operands[2], 1);
+ op2_xf = gen_reg_rtx (XFmode);
+ expand_float (op2_xf, operands[2], 1);
if (TARGET_INLINE_INT_DIV_LAT)
- emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
+ emit_insn (gen_divdi3_internal_lat (op0_xf, op1_xf, op2_xf));
else
- emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
+ emit_insn (gen_divdi3_internal_thr (op0_xf, op1_xf, op2_xf));
- emit_insn (gen_fixuns_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
+ emit_insn (gen_fixuns_truncxfdi2_alts (operands[0], op0_xf, const1_rtx));
DONE;
})
@@ -2490,7 +2353,7 @@
[(set (match_operand:DI 0 "register_operand" "")
(umod:DI (match_operand:DI 1 "general_operand" "")
(match_operand:DI 2 "general_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV"
+ "TARGET_INLINE_INT_DIV"
{
rtx op2_neg, div;
@@ -2504,112 +2367,112 @@
})
(define_insn_and_split "divdi3_internal_lat"
- [(set (match_operand:TF 0 "fr_register_operand" "=&f")
- (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
- (match_operand:TF 2 "fr_register_operand" "f"))))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=&f"))
- (clobber (match_scratch:TF 5 "=&f"))
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
+ (match_operand:XF 2 "fr_register_operand" "f"))))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=&f"))
+ (clobber (match_scratch:XF 5 "=&f"))
(clobber (match_scratch:BI 6 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_LAT"
+ "TARGET_INLINE_INT_DIV_LAT"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
(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)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 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:TF (match_dup 3) (match_dup 3)))
+ (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:TF (mult:TF (match_dup 3) (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:TF (mult:TF (match_dup 3) (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:TF (mult:TF (match_dup 5) (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 0)
- (plus:TF (mult:TF (match_dup 5) (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)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
(match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 0))
(match_dup 3)))
(use (const_int 1))]))
]
- "operands[7] = CONST1_RTX (TFmode);"
+ "operands[7] = CONST1_RTX (XFmode);"
[(set_attr "predicable" "no")])
(define_insn_and_split "divdi3_internal_thr"
- [(set (match_operand:TF 0 "fr_register_operand" "=&f")
- (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
- (match_operand:TF 2 "fr_register_operand" "f"))))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=f"))
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (float:XF (div:SI (match_operand:XF 1 "fr_register_operand" "f")
+ (match_operand:XF 2 "fr_register_operand" "f"))))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=f"))
(clobber (match_scratch:BI 5 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_INT_DIV_THR"
+ "TARGET_INLINE_INT_DIV_THR"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
(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)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 3) (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:TF (match_dup 3) (match_dup 3)))
+ (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:TF (mult:TF (match_dup 3) (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:TF (match_dup 0) (match_dup 1)))
+ (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)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
(match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 0))
(match_dup 3)))
(use (const_int 1))]))
]
- "operands[6] = CONST1_RTX (TFmode);"
+ "operands[6] = CONST1_RTX (XFmode);"
[(set_attr "predicable" "no")])
;; ::::::::::::::::::::
@@ -2721,7 +2584,7 @@
[(set (match_operand:SF 0 "fr_register_operand" "")
(div:SF (match_operand:SF 1 "fr_register_operand" "")
(match_operand:SF 2 "fr_register_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
+ "TARGET_INLINE_FLOAT_DIV"
{
rtx insn;
if (TARGET_INLINE_FLOAT_DIV_LAT)
@@ -2736,44 +2599,44 @@
[(set (match_operand:SF 0 "fr_register_operand" "=&f")
(div:SF (match_operand:SF 1 "fr_register_operand" "f")
(match_operand:SF 2 "fr_register_operand" "f")))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=f"))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=f"))
(clobber (match_scratch:BI 5 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
+ "TARGET_INLINE_FLOAT_DIV_LAT"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
+ [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
(set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 3) (mult:TF (match_dup 7) (match_dup 6)))
+ (parallel [(set (match_dup 3) (mult:XF (match_dup 7) (match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
(match_dup 10)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 4) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
+ (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 4) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 4) (match_dup 4)))
+ (parallel [(set (match_dup 4) (mult:XF (match_dup 4) (match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 9)
(float_truncate:DF
- (plus:TF (mult:TF (match_dup 4) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
(match_dup 3))))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
@@ -2781,11 +2644,11 @@
(float_truncate:SF (match_dup 6))))
]
{
- operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
- operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
- operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
+ operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
+ operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
+ operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
operands[9] = gen_rtx_REG (DFmode, REGNO (operands[0]));
- operands[10] = CONST1_RTX (TFmode);
+ operands[10] = CONST1_RTX (XFmode);
}
[(set_attr "predicable" "no")])
@@ -2793,53 +2656,202 @@
[(set (match_operand:SF 0 "fr_register_operand" "=&f")
(div:SF (match_operand:SF 1 "fr_register_operand" "f")
(match_operand:SF 2 "fr_register_operand" "f")))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=f"))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=f"))
(clobber (match_scratch:BI 5 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
+ "TARGET_INLINE_FLOAT_DIV_THR"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
+ [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
(set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
(match_dup 10)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 3) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 6)
- (plus:TF (mult:TF (match_dup 3) (match_dup 6))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 6))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 9)
(float_truncate:SF
- (mult:TF (match_dup 7) (match_dup 6))))
+ (mult:XF (match_dup 7) (match_dup 6))))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 3)))
(match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(set (match_dup 0)
(float_truncate:SF
- (plus:TF (mult:TF (match_dup 4) (match_dup 6))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 6))
(match_dup 3)))))
]
{
- operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
- operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
- operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
+ operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
+ operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
+ operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
operands[9] = gen_rtx_REG (SFmode, REGNO (operands[3]));
- operands[10] = CONST1_RTX (TFmode);
+ operands[10] = CONST1_RTX (XFmode);
+}
+ [(set_attr "predicable" "no")])
+
+;; Inline square root.
+
+(define_insn "*sqrt_approx"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (div:XF (const_int 1)
+ (sqrt:XF (match_operand:XF 2 "fr_register_operand" "f"))))
+ (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_register_operand" "f")))]
+ "TARGET_INLINE_SQRT"
+{
+ rtx insn;
+ if (TARGET_INLINE_SQRT_LAT)
+#if 0
+ insn = gen_sqrtsf2_internal_lat (operands[0], operands[1]);
+#else
+ abort ();
+#endif
+ else
+ 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_register_operand" "f")))
+ ;; 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_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)
+ (sqrt:XF (match_dup 8))))
+ (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)
+ (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 4)))
+ (match_dup 3)))
+ (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)
+ (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
+ (match_dup 8)))
+ (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")])
@@ -3030,7 +3042,7 @@
[(set (match_operand:DF 0 "fr_register_operand" "")
(div:DF (match_operand:DF 1 "fr_register_operand" "")
(match_operand:DF 2 "fr_register_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
+ "TARGET_INLINE_FLOAT_DIV"
{
rtx insn;
if (TARGET_INLINE_FLOAT_DIV_LAT)
@@ -3045,80 +3057,80 @@
[(set (match_operand:DF 0 "fr_register_operand" "=&f")
(div:DF (match_operand:DF 1 "fr_register_operand" "f")
(match_operand:DF 2 "fr_register_operand" "f")))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=&f"))
- (clobber (match_scratch:TF 5 "=&f"))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=&f"))
+ (clobber (match_scratch:XF 5 "=&f"))
(clobber (match_scratch:BI 6 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
+ "TARGET_INLINE_FLOAT_DIV_LAT"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 7) (div:TF (const_int 1) (match_dup 9)))
+ [(parallel [(set (match_dup 7) (div:XF (const_int 1) (match_dup 9)))
(set (match_dup 6) (unspec:BI [(match_dup 8) (match_dup 9)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 3) (mult:TF (match_dup 8) (match_dup 7)))
+ (parallel [(set (match_dup 3) (mult:XF (match_dup 8) (match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 7)))
+ (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 7)))
(match_dup 12)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 4) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 5) (mult:TF (match_dup 4) (match_dup 4)))
+ (parallel [(set (match_dup 5) (mult:XF (match_dup 4) (match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 7)
- (plus:TF (mult:TF (match_dup 4) (match_dup 7))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 7))
(match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 5) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 5) (match_dup 5)))
+ (parallel [(set (match_dup 4) (mult:XF (match_dup 5) (match_dup 5)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 7)
- (plus:TF (mult:TF (match_dup 5) (match_dup 7))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 7))
(match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 10)
(float_truncate:DF
- (plus:TF (mult:TF (match_dup 4) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 3))
(match_dup 3))))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 7)
- (plus:TF (mult:TF (match_dup 4) (match_dup 7))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 7))
(match_dup 7)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(parallel [(set (match_dup 11)
(float_truncate:DF
- (plus:TF (neg:TF (mult:TF (match_dup 9) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 9) (match_dup 3)))
(match_dup 8))))
(use (const_int 1))]))
(cond_exec (ne (match_dup 6) (const_int 0))
(set (match_dup 0)
- (float_truncate:DF (plus:TF (mult:TF (match_dup 5) (match_dup 7))
+ (float_truncate:DF (plus:XF (mult:XF (match_dup 5) (match_dup 7))
(match_dup 3)))))
]
{
- operands[7] = gen_rtx_REG (TFmode, REGNO (operands[0]));
- operands[8] = gen_rtx_REG (TFmode, REGNO (operands[1]));
- operands[9] = gen_rtx_REG (TFmode, REGNO (operands[2]));
+ operands[7] = gen_rtx_REG (XFmode, REGNO (operands[0]));
+ operands[8] = gen_rtx_REG (XFmode, REGNO (operands[1]));
+ operands[9] = gen_rtx_REG (XFmode, REGNO (operands[2]));
operands[10] = gen_rtx_REG (DFmode, REGNO (operands[3]));
operands[11] = gen_rtx_REG (DFmode, REGNO (operands[5]));
- operands[12] = CONST1_RTX (TFmode);
+ operands[12] = CONST1_RTX (XFmode);
}
[(set_attr "predicable" "no")])
@@ -3126,48 +3138,48 @@
[(set (match_operand:DF 0 "fr_register_operand" "=&f")
(div:DF (match_operand:DF 1 "fr_register_operand" "f")
(match_operand:DF 2 "fr_register_operand" "f")))
- (clobber (match_scratch:TF 3 "=&f"))
+ (clobber (match_scratch:XF 3 "=&f"))
(clobber (match_scratch:DF 4 "=f"))
(clobber (match_scratch:BI 5 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
+ "TARGET_INLINE_FLOAT_DIV_THR"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 6) (div:TF (const_int 1) (match_dup 8)))
+ [(parallel [(set (match_dup 6) (div:XF (const_int 1) (match_dup 8)))
(set (match_dup 5) (unspec:BI [(match_dup 7) (match_dup 8)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (neg:TF (mult:TF (match_dup 8) (match_dup 6)))
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 6)))
(match_dup 10)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 6)
- (plus:TF (mult:TF (match_dup 3) (match_dup 6))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 6))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (mult:TF (match_dup 3) (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 6)
- (plus:TF (mult:TF (match_dup 3) (match_dup 6))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 6))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (mult:TF (match_dup 3) (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 6)
- (plus:TF (mult:TF (match_dup 3) (match_dup 6))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 6))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 9)
(float_truncate:DF
- (mult:TF (match_dup 7) (match_dup 3))))
+ (mult:XF (match_dup 7) (match_dup 3))))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
@@ -3180,11 +3192,160 @@
(match_dup 9))))
]
{
- operands[6] = gen_rtx_REG (TFmode, REGNO (operands[0]));
- operands[7] = gen_rtx_REG (TFmode, REGNO (operands[1]));
- operands[8] = gen_rtx_REG (TFmode, REGNO (operands[2]));
+ operands[6] = gen_rtx_REG (XFmode, REGNO (operands[0]));
+ operands[7] = gen_rtx_REG (XFmode, REGNO (operands[1]));
+ operands[8] = gen_rtx_REG (XFmode, REGNO (operands[2]));
operands[9] = gen_rtx_REG (DFmode, REGNO (operands[3]));
- operands[10] = CONST1_RTX (TFmode);
+ operands[10] = CONST1_RTX (XFmode);
+}
+ [(set_attr "predicable" "no")])
+
+;; Inline square root.
+
+(define_expand "sqrtdf2"
+ [(set (match_operand:DF 0 "fr_register_operand" "=&f")
+ (sqrt:DF (match_operand:DF 1 "fr_register_operand" "f")))]
+ "TARGET_INLINE_SQRT"
+{
+ rtx insn;
+ if (TARGET_INLINE_SQRT_LAT)
+#if 0
+ insn = gen_sqrtdf2_internal_lat (operands[0], operands[1]);
+#else
+ abort ();
+#endif
+ else
+ 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_register_operand" "f")))
+ ;; 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_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)
+ (sqrt:XF (match_dup 8))))
+ (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)
+ (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3)))
+ (match_dup 5)))
+ (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)
+ (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 3)))
+ (match_dup 5)))
+ (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)
+ (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
+ (match_dup 8)))
+ (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)
+ (plus:XF (neg:XF (mult:XF (match_dup 7) (match_dup 7)))
+ (match_dup 8)))
+ (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")])
@@ -3194,499 +3355,674 @@
;; ::
;; ::::::::::::::::::::
-(define_insn "addtf3"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "addxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fadd %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*addtf3_truncsf"
+(define_insn "*addxf3_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fadd.s %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*addtf3_truncdf"
+(define_insn "*addxf3_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (plus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (plus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fadd.d %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "subtf3"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "subxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fsub %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*subtf3_truncsf"
+(define_insn "*subxf3_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fsub.s %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*subtf3_truncdf"
+(define_insn "*subxf3_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (minus:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (minus:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fsub.d %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "multf3"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "mulxf3"
+ [(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")))]
+ ""
"fmpy %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*multf3_truncsf"
+(define_insn "*mulxf3_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fmpy.s %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*multf3_truncdf"
+(define_insn "*mulxf3_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fmpy.d %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*multf3_alts"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
+(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" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fmpy.s%3 %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*multf3_truncsf_alts"
+(define_insn "*mulxf3_truncsf_alts"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_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 3 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fmpy.s.s%3 %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*multf3_truncdf_alts"
+(define_insn "*mulxf3_truncdf_alts"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_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 3 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fmpy.d.s%3 %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "abstf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "absxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fabs %0 = %F1"
[(set_attr "itanium_class" "fmisc")])
-(define_insn "negtf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (neg:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "negxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (neg:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fneg %0 = %F1"
[(set_attr "itanium_class" "fmisc")])
-(define_insn "*nabstf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (neg:TF (abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "*nabsxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (neg:XF (abs:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fnegabs %0 = %F1"
[(set_attr "itanium_class" "fmisc")])
-(define_insn "mintf3"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (smin:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "minxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (smin:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fmin %0 = %F1, %F2"
[(set_attr "itanium_class" "fmisc")])
-(define_insn "maxtf3"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (smax:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "maxxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (smax:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))]
+ ""
"fmax %0 = %F1, %F2"
[(set_attr "itanium_class" "fmisc")])
-(define_insn "*maddtf4"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "*maddxf4"
+ [(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")))]
+ ""
"fma %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*maddtf4_truncsf"
+(define_insn "*maddxf4_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (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"))))]
+ ""
"fma.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*maddtf4_truncdf"
+(define_insn "*maddxf4_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (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"))))]
+ ""
"fma.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*maddtf4_alts"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
+(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" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fma.s%4 %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*maddtf4_alts_truncdf"
+(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:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
+ (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" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fma.d.s%4 %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*msubtf4"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(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")))]
+ ""
"fms %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*msubtf4_truncsf"
+(define_insn "*msubxf4_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (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"))))]
+ ""
"fms.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*msubtf4_truncdf"
+(define_insn "*msubxf4_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (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"))))]
+ ""
"fms.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmultf3"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (neg:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "*nmulxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))))]
+ ""
"fnmpy %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmultf3_truncsf"
+(define_insn "*nmulxf3_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (neg:TF (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (neg:XF (mult:XF
+ (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
+ ""
"fnmpy.s %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmultf3_truncdf"
+(define_insn "*nmulxf3_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (neg:TF (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (neg:XF (mult:XF
+ (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")))))]
+ ""
"fnmpy.d %0 = %F1, %F2"
[(set_attr "itanium_class" "fmac")])
;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
-(define_insn "*nmaddtf4"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (plus:TF (neg:TF (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+(define_insn "*nmaddxf4"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (plus:XF (neg: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")))]
+ ""
"fnma %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmaddtf4_truncsf"
+(define_insn "*nmaddxf4_truncsf"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(float_truncate:SF
- (plus:TF (neg:TF (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (plus:XF (neg: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"))))]
+ ""
"fnma.s %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmaddtf4_truncdf"
+(define_insn "*nmaddxf4_truncdf"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (plus:TF (neg:TF (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (plus:XF (neg: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"))))]
+ ""
"fnma.d %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmaddtf4_alts"
- [(set (match_operand:TF 0 "fr_register_operand" "=f")
- (plus:TF (neg:TF (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
+(define_insn "*nmaddxf4_alts"
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (plus:XF (neg: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" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fnma.s%4 %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_insn "*nmaddtf4_truncdf_alts"
+(define_insn "*nmaddxf4_truncdf_alts"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(float_truncate:DF
- (plus:TF (neg:TF
- (mult:TF
- (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG"))))
+ (plus:XF (neg: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" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"fnma.d.s%4 %0 = %F1, %F2, %F3"
[(set_attr "itanium_class" "fmac")])
-(define_expand "divtf3"
- [(set (match_operand:TF 0 "fr_register_operand" "")
- (div:TF (match_operand:TF 1 "fr_register_operand" "")
- (match_operand:TF 2 "fr_register_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV"
+(define_expand "divxf3"
+ [(set (match_operand:XF 0 "fr_register_operand" "")
+ (div:XF (match_operand:XF 1 "fr_register_operand" "")
+ (match_operand:XF 2 "fr_register_operand" "")))]
+ "TARGET_INLINE_FLOAT_DIV"
{
rtx insn;
if (TARGET_INLINE_FLOAT_DIV_LAT)
- insn = gen_divtf3_internal_lat (operands[0], operands[1], operands[2]);
+ insn = gen_divxf3_internal_lat (operands[0], operands[1], operands[2]);
else
- insn = gen_divtf3_internal_thr (operands[0], operands[1], operands[2]);
+ insn = gen_divxf3_internal_thr (operands[0], operands[1], operands[2]);
emit_insn (insn);
DONE;
})
-(define_insn_and_split "divtf3_internal_lat"
- [(set (match_operand:TF 0 "fr_register_operand" "=&f")
- (div:TF (match_operand:TF 1 "fr_register_operand" "f")
- (match_operand:TF 2 "fr_register_operand" "f")))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=&f"))
- (clobber (match_scratch:TF 5 "=&f"))
- (clobber (match_scratch:TF 6 "=&f"))
+(define_insn_and_split "divxf3_internal_lat"
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (div:XF (match_operand:XF 1 "fr_register_operand" "f")
+ (match_operand:XF 2 "fr_register_operand" "f")))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=&f"))
+ (clobber (match_scratch:XF 5 "=&f"))
+ (clobber (match_scratch:XF 6 "=&f"))
(clobber (match_scratch:BI 7 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_LAT"
+ "TARGET_INLINE_FLOAT_DIV_LAT"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
(set (match_dup 7) (unspec:BI [(match_dup 1) (match_dup 2)]
UNSPEC_FR_RECIP_APPROX))
(use (const_int 1))])
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 8)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
+ (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
- (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
+ (parallel [(set (match_dup 5) (mult:XF (match_dup 3) (match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 6)
- (plus:TF (mult:TF (match_dup 3) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 5) (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 7) (const_int 0))
(parallel [(set (match_dup 5)
- (plus:TF (mult:TF (match_dup 6) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 6) (match_dup 0))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 5) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 5) (match_dup 3))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4)))
(match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 3) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 0))
(match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 5)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 8)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 0))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
(match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 7) (const_int 0))
(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 0))
(match_dup 3))))
]
- "operands[8] = CONST1_RTX (TFmode);"
+ "operands[8] = CONST1_RTX (XFmode);"
[(set_attr "predicable" "no")])
-(define_insn_and_split "divtf3_internal_thr"
- [(set (match_operand:TF 0 "fr_register_operand" "=&f")
- (div:TF (match_operand:TF 1 "fr_register_operand" "f")
- (match_operand:TF 2 "fr_register_operand" "f")))
- (clobber (match_scratch:TF 3 "=&f"))
- (clobber (match_scratch:TF 4 "=&f"))
+(define_insn_and_split "divxf3_internal_thr"
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (div:XF (match_operand:XF 1 "fr_register_operand" "f")
+ (match_operand:XF 2 "fr_register_operand" "f")))
+ (clobber (match_scratch:XF 3 "=&f"))
+ (clobber (match_scratch:XF 4 "=&f"))
(clobber (match_scratch:BI 5 "=c"))]
- "INTEL_EXTENDED_IEEE_FORMAT && TARGET_INLINE_FLOAT_DIV_THR"
+ "TARGET_INLINE_FLOAT_DIV_THR"
"#"
"&& reload_completed"
- [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ [(parallel [(set (match_dup 0) (div:XF (const_int 1) (match_dup 2)))
(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)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (mult:TF (match_dup 3) (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:TF (match_dup 3) (match_dup 3)))
+ (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 3)
- (plus:TF (mult:TF (match_dup 3) (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 5) (const_int 0))
- (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
+ (parallel [(set (match_dup 4) (mult:XF (match_dup 1) (match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 0) (match_dup 3))
+ (plus:XF (mult:XF (match_dup 0) (match_dup 3))
(match_dup 3)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 4)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 4)))
(match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 3)
- (plus:TF (mult:TF (match_dup 3) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 3) (match_dup 0))
(match_dup 4)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 0)))
(match_dup 6)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 0))
(match_dup 0)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(parallel [(set (match_dup 4)
- (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
+ (plus:XF (neg:XF (mult:XF (match_dup 2) (match_dup 3)))
(match_dup 1)))
(use (const_int 1))]))
(cond_exec (ne (match_dup 5) (const_int 0))
(set (match_dup 0)
- (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (plus:XF (mult:XF (match_dup 4) (match_dup 0))
(match_dup 3))))
]
- "operands[6] = CONST1_RTX (TFmode);"
+ "operands[6] = CONST1_RTX (XFmode);"
+ [(set_attr "predicable" "no")])
+
+;; Inline square root.
+
+(define_expand "sqrtxf2"
+ [(set (match_operand:XF 0 "fr_register_operand" "=&f")
+ (sqrt:XF (match_operand:XF 1 "fr_register_operand" "f")))]
+ "TARGET_INLINE_SQRT"
+{
+ rtx insn;
+ if (TARGET_INLINE_SQRT_LAT)
+#if 0
+ insn = gen_sqrtxf2_internal_lat (operands[0], operands[1]);
+#else
+ abort ();
+#endif
+ else
+ 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_register_operand" "f")))
+ ;; 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_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)
+ (sqrt:XF (match_dup 9))))
+ (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)
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
+ (match_dup 3)))
+ (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)
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
+ (match_dup 3)))
+ (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)
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 4)))
+ (match_dup 3)))
+ (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)
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8)))
+ (match_dup 9)))
+ (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)
+ (plus:XF (neg:XF (mult:XF (match_dup 8) (match_dup 8)))
+ (match_dup 9)))
+ (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:TF 0 "fr_register_operand" "=f")
- (div:TF (const_int 1)
- (match_operand:TF 3 "fr_register_operand" "f")))
+ [(set (match_operand:XF 0 "fr_register_operand" "=f")
+ (div:XF (const_int 1)
+ (match_operand:XF 3 "fr_register_operand" "f")))
(set (match_operand:BI 1 "register_operand" "=c")
- (unspec:BI [(match_operand:TF 2 "fr_register_operand" "f")
+ (unspec:BI [(match_operand:XF 2 "fr_register_operand" "f")
(match_dup 3)] UNSPEC_FR_RECIP_APPROX))
(use (match_operand:SI 4 "const_int_operand" ""))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ ""
"frcpa.s%4 %0, %1 = %2, %3"
[(set_attr "itanium_class" "fmisc")
(set_attr "predicable" "no")])
@@ -4083,11 +4419,22 @@
DONE;
})
+(define_expand "cmpxf"
+ [(set (cc0)
+ (compare (match_operand:XF 0 "xfreg_or_fp01_operand" "")
+ (match_operand:XF 1 "xfreg_or_fp01_operand" "")))]
+ ""
+{
+ ia64_compare_op0 = operands[0];
+ ia64_compare_op1 = operands[1];
+ DONE;
+})
+
(define_expand "cmptf"
[(set (cc0)
- (compare (match_operand:TF 0 "tfreg_or_fp01_operand" "")
- (match_operand:TF 1 "tfreg_or_fp01_operand" "")))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ (compare (match_operand:TF 0 "gr_register_operand" "")
+ (match_operand:TF 1 "gr_register_operand" "")))]
+ "TARGET_HPUX"
{
ia64_compare_op0 = operands[0];
ia64_compare_op1 = operands[1];
@@ -4154,12 +4501,12 @@
"fcmp.%D1 %0, %I0 = %F2, %F3"
[(set_attr "itanium_class" "fcmp")])
-(define_insn "*cmptf_internal"
+(define_insn "*cmpxf_internal"
[(set (match_operand:BI 0 "register_operand" "=c")
(match_operator:BI 1 "comparison_operator"
- [(match_operand:TF 2 "tfreg_or_fp01_operand" "fG")
- (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")]))]
- "INTEL_EXTENDED_IEEE_FORMAT"
+ [(match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
+ (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")]))]
+ ""
"fcmp.%D1 %0, %I0 = %F2, %F3"
[(set_attr "itanium_class" "fcmp")])
@@ -4464,9 +4811,9 @@
"c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")
(const_int 0)])
(match_operand:DI 2 "move_operand"
- "rnm, *f, *b,*d*e,rnm,rnm, rnm,*f,*b,*d*e,rO,*f,rOQ,rO, rK")
+ "rim, *f, *b,*d*e,rim,rim, rim,*f,*b,*d*e,rO,*f,rOQ,rO, rK")
(match_operand:DI 3 "move_operand"
- "rnm,rnm,rnm, rnm, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))]
+ "rim,rim,rim, rim, *f, *b,*d*e,*f,*b,*d*e,rO,*f,rOQ,rO, rK")))]
"ia64_move_ok (operands[0], operands[2])
&& ia64_move_ok (operands[0], operands[3])"
{ abort (); }
@@ -4483,29 +4830,26 @@
"reload_completed"
[(const_int 0)]
{
- rtx tmp;
- int emitted_something;
+ bool emitted_something = false;
+ rtx dest = operands[0];
+ rtx srct = operands[2];
+ rtx srcf = operands[3];
+ rtx cond = operands[4];
- emitted_something = 0;
- if (! rtx_equal_p (operands[0], operands[2]))
+ if (! rtx_equal_p (dest, srct))
{
- tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]);
- tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp);
- emit_insn (tmp);
- emitted_something = 1;
+ ia64_emit_cond_move (dest, srct, cond);
+ emitted_something = true;
}
- if (! rtx_equal_p (operands[0], operands[3]))
+ if (! rtx_equal_p (dest, srcf))
{
- tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE,
- VOIDmode, operands[1], const0_rtx);
- tmp = gen_rtx_COND_EXEC (VOIDmode, tmp,
- gen_rtx_SET (VOIDmode, operands[0],
- operands[3]));
- emit_insn (tmp);
- emitted_something = 1;
+ cond = gen_rtx_fmt_ee (GET_CODE (cond) == NE ? EQ : NE,
+ VOIDmode, operands[1], const0_rtx);
+ ia64_emit_cond_move (dest, srcf, cond);
+ emitted_something = true;
}
if (! emitted_something)
- emit_note (NULL, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
DONE;
})
@@ -4570,9 +4914,9 @@
[(match_operand:BI 1 "register_operand" "c,c,c,c,c,c,c,c,c")
(const_int 0)])
(match_operand:SI 2 "move_operand"
- "0,0,0,rnm*f,rO,rO,rnm*f,rO,rO")
+ "0,0,0,rim*f,rO,rO,rim*f,rO,rO")
(match_operand:SI 3 "move_operand"
- "rnm*f,rO,rO,0,0,0,rnm*f,rO,rO")))]
+ "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))]
"ia64_move_ok (operands[0], operands[2])
&& ia64_move_ok (operands[0], operands[3])"
{ abort (); }
@@ -4786,7 +5130,7 @@
[(set_attr "itanium_class" "br,scall")])
(define_insn "call_value_nogp"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0 "" "=X,X")
(call (mem:DI (match_operand:DI 1 "call_operand" "?b,i"))
(const_int 0)))
(clobber (match_operand:DI 2 "register_operand" "=b,b"))]
@@ -4802,7 +5146,7 @@
[(set_attr "itanium_class" "br,scall")])
(define_insn "call_gp"
- [(call (mem (match_operand 0 "call_operand" "?r,i"))
+ [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i"))
(const_int 1))
(clobber (match_operand:DI 1 "register_operand" "=b,b"))
(clobber (match_scratch:DI 2 "=&r,X"))
@@ -4842,7 +5186,7 @@
})
(define_insn "call_value_gp"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0 "" "=X,X")
(call (mem:DI (match_operand:DI 1 "call_operand" "?r,i"))
(const_int 1)))
(clobber (match_operand:DI 2 "register_operand" "=b,b"))
@@ -5062,7 +5406,8 @@
""
""
[(set_attr "itanium_class" "ignore")
- (set_attr "predicable" "no")])
+ (set_attr "predicable" "no")
+ (set_attr "empty" "yes")])
;; Allocate a new register frame.
@@ -5123,16 +5468,16 @@
[(set_attr "itanium_class" "ld")])
(define_insn "fr_spill"
- [(set (match_operand:TF 0 "memory_operand" "=m")
- (unspec:TF [(match_operand:TF 1 "register_operand" "f")]
+ [(set (match_operand:XF 0 "memory_operand" "=m")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "f")]
UNSPEC_FR_SPILL))]
""
"stf.spill %0 = %1%P0"
[(set_attr "itanium_class" "stf")])
(define_insn "fr_restore"
- [(set (match_operand:TF 0 "register_operand" "=f")
- (unspec:TF [(match_operand:TF 1 "memory_operand" "m")]
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 1 "memory_operand" "m")]
UNSPEC_FR_RESTORE))]
""
"ldf.fill %0 = %1%P1"
@@ -5191,7 +5536,7 @@
;; ::
;; ::::::::::::::::::::
-;; ??? Emiting a NOP instruction isn't very useful. This should probably
+;; ??? Emitting a NOP instruction isn't very useful. This should probably
;; be emitting ";;" to force a break in the instruction packing.
;; No operation, needed in case the user uses -g but not -O.
@@ -5199,7 +5544,7 @@
[(const_int 0)]
""
"nop 0"
- [(set_attr "itanium_class" "unknown")])
+ [(set_attr "itanium_class" "nop")])
(define_insn "nop_m"
[(const_int 1)]
@@ -5229,7 +5574,16 @@
[(const_int 5)]
""
""
- [(set_attr "itanium_class" "nop_x")])
+ [(set_attr "itanium_class" "nop_x")
+ (set_attr "empty" "yes")])
+
+;; The following insn will be never generated. It is used only by
+;; insn scheduler to change state before advancing cycle.
+(define_insn "pre_cycle"
+ [(const_int 6)]
+ ""
+ ""
+ [(set_attr "itanium_class" "pre_cycle")])
(define_insn "bundle_selector"
[(unspec [(match_operand 0 "const_int_operand" "")] UNSPEC_BUNDLE_SELECTOR)]
@@ -5253,7 +5607,8 @@
""
";;"
[(set_attr "itanium_class" "stop_bit")
- (set_attr "predicable" "no")])
+ (set_attr "predicable" "no")
+ (set_attr "empty" "yes")])
(define_expand "trap"
[(trap_if (const_int 1) (const_int 0))]
@@ -5425,8 +5780,8 @@
(define_insn "fetchadd_acq_si"
[(set (match_operand:SI 0 "gr_register_operand" "=r")
- (match_dup 1))
- (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
+ (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
+ (set (match_dup 1)
(unspec:SI [(match_dup 1)
(match_operand:SI 2 "fetchadd_operand" "n")]
UNSPEC_FETCHADD_ACQ))]
@@ -5436,8 +5791,8 @@
(define_insn "fetchadd_acq_di"
[(set (match_operand:DI 0 "gr_register_operand" "=r")
- (match_dup 1))
- (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
+ (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
+ (set (match_dup 1)
(unspec:DI [(match_dup 1)
(match_operand:DI 2 "fetchadd_operand" "n")]
UNSPEC_FETCHADD_ACQ))]
@@ -5447,11 +5802,11 @@
(define_insn "cmpxchg_acq_si"
[(set (match_operand:SI 0 "gr_register_operand" "=r")
- (match_dup 1))
- (set (match_operand:SI 1 "not_postinc_memory_operand" "+S")
+ (match_operand:SI 1 "not_postinc_memory_operand" "+S"))
+ (set (match_dup 1)
(unspec:SI [(match_dup 1)
(match_operand:SI 2 "gr_register_operand" "r")
- (match_operand 3 "ar_ccv_reg_operand" "")]
+ (match_operand:DI 3 "ar_ccv_reg_operand" "")]
UNSPEC_CMPXCHG_ACQ))]
""
"cmpxchg4.acq %0 = %1, %2, %3"
@@ -5459,8 +5814,8 @@
(define_insn "cmpxchg_acq_di"
[(set (match_operand:DI 0 "gr_register_operand" "=r")
- (match_dup 1))
- (set (match_operand:DI 1 "not_postinc_memory_operand" "+S")
+ (match_operand:DI 1 "not_postinc_memory_operand" "+S"))
+ (set (match_dup 1)
(unspec:DI [(match_dup 1)
(match_operand:DI 2 "gr_register_operand" "r")
(match_operand:DI 3 "ar_ccv_reg_operand" "")]
@@ -5515,7 +5870,7 @@
[(unspec_volatile [(const_int 0)] UNSPECV_PSAC_NORMAL)]
""
{
- emit_safe_across_calls (asm_out_file);
+ emit_safe_across_calls ();
return "";
}
[(set_attr "itanium_class" "ignore")
@@ -5535,7 +5890,7 @@
;;
;; Optimizations for ptr_extend
-(define_insn "*ptr_extend_plus_1"
+(define_insn "ptr_extend_plus_imm"
[(set (match_operand:DI 0 "gr_register_operand" "=r")
(unspec:DI
[(plus:SI (match_operand:SI 1 "basereg_operand" "r")
diff --git a/contrib/gcc/config/ia64/itanium1.md b/contrib/gcc/config/ia64/itanium1.md
new file mode 100644
index 000000000000..2b844115160b
--- /dev/null
+++ b/contrib/gcc/config/ia64/itanium1.md
@@ -0,0 +1,1616 @@
+;; Itanium1 (original Itanium) DFA descriptions for insn scheduling
+;; and bundling.
+;; Copyright (C) 2002 Free Software Foundation, Inc.
+;; Contributed by Vladimir Makarov <vmakarov@redhat.com>.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA. */
+;;
+
+
+/* This is description of pipeline hazards based on DFA. The
+ following constructions can be used for this:
+
+ o define_cpu_unit string [string]) describes a cpu functional unit
+ (separated by comma).
+
+ 1st operand: Names of cpu function units.
+ 2nd operand: Name of automaton (see comments for
+ DEFINE_AUTOMATON).
+
+ All define_reservations and define_cpu_units should have unique
+ names which can not be "nothing".
+
+ o (exclusion_set string string) means that each CPU function unit
+ in the first string can not be reserved simultaneously with each
+ unit whose name is in the second string and vise versa. CPU
+ units in the string are separated by commas. For example, it is
+ useful for description CPU with fully pipelined floating point
+ functional unit which can execute simultaneously only single
+ floating point insns or only double floating point insns.
+
+ o (presence_set string string) means that each CPU function unit in
+ the first string can not be reserved unless at least one of
+ pattern of units whose names are in the second string is
+ reserved. This is an asymmetric relation. CPU units or unit
+ patterns in the strings are separated by commas. Pattern is one
+ unit name or unit names separated by white-spaces.
+
+ For example, it is useful for description that slot1 is reserved
+ after slot0 reservation for a VLIW processor. We could describe
+ it by the following construction
+
+ (presence_set "slot1" "slot0")
+
+ Or slot1 is reserved only after slot0 and unit b0 reservation.
+ In this case we could write
+
+ (presence_set "slot1" "slot0 b0")
+
+ All CPU functional units in a set should belong to the same
+ automaton.
+
+ o (final_presence_set string string) is analogous to
+ `presence_set'. The difference between them is when checking is
+ done. When an instruction is issued in given automaton state
+ reflecting all current and planned unit reservations, the
+ automaton state is changed. The first state is a source state,
+ the second one is a result state. Checking for `presence_set' is
+ done on the source state reservation, checking for
+ `final_presence_set' is done on the result reservation. This
+ construction is useful to describe a reservation which is
+ actually two subsequent reservations. For example, if we use
+
+ (presence_set "slot1" "slot0")
+
+ the following insn will be never issued (because slot1 requires
+ slot0 which is absent in the source state).
+
+ (define_reservation "insn_and_nop" "slot0 + slot1")
+
+ but it can be issued if we use analogous `final_presence_set'.
+
+ o (absence_set string string) means that each CPU function unit in
+ the first string can be reserved only if each pattern of units
+ whose names are in the second string is not reserved. This is an
+ asymmetric relation (actually exclusion set is analogous to this
+ one but it is symmetric). CPU units or unit patterns in the
+ string are separated by commas. Pattern is one unit name or unit
+ names separated by white-spaces.
+
+ For example, it is useful for description that slot0 can not be
+ reserved after slot1 or slot2 reservation for a VLIW processor.
+ We could describe it by the following construction
+
+ (absence_set "slot2" "slot0, slot1")
+
+ Or slot2 can not be reserved if slot0 and unit b0 are reserved or
+ slot1 and unit b1 are reserved . In this case we could write
+
+ (absence_set "slot2" "slot0 b0, slot1 b1")
+
+ All CPU functional units in a set should to belong the same
+ automaton.
+
+ o (final_absence_set string string) is analogous to `absence_set' but
+ checking is done on the result (state) reservation. See comments
+ for final_presence_set.
+
+ o (define_bypass number out_insn_names in_insn_names) names bypass with
+ given latency (the first number) from insns given by the first
+ string (see define_insn_reservation) into insns given by the
+ second string. Insn names in the strings are separated by
+ commas.
+
+ o (define_automaton string) describes names of an automaton
+ generated and used for pipeline hazards recognition. The names
+ are separated by comma. Actually it is possibly to generate the
+ single automaton but unfortunately it can be very large. If we
+ use more one automata, the summary size of the automata usually
+ is less than the single one. The automaton name is used in
+ define_cpu_unit. All automata should have unique names.
+
+ o (automata_option string) describes option for generation of
+ automata. Currently there are the following options:
+
+ o "no-minimization" which makes no minimization of automata.
+ This is only worth to do when we are debugging the description
+ and need to look more accurately at reservations of states.
+
+ o "ndfa" which makes automata with nondetermenistic reservation
+ by insns.
+
+ o (define_reservation string string) names reservation (the first
+ string) of cpu functional units (the 2nd string). Sometimes unit
+ reservations for different insns contain common parts. In such
+ case, you describe common part and use one its name (the 1st
+ parameter) in regular expression in define_insn_reservation. All
+ define_reservations, define results and define_cpu_units should
+ have unique names which can not be "nothing".
+
+ o (define_insn_reservation name default_latency condition regexpr)
+ describes reservation of cpu functional units (the 3nd operand)
+ for instruction which is selected by the condition (the 2nd
+ parameter). The first parameter is used for output of debugging
+ information. The reservations are described by a regular
+ expression according the following syntax:
+
+ regexp = regexp "," oneof
+ | oneof
+
+ oneof = oneof "|" allof
+ | allof
+
+ allof = allof "+" repeat
+ | repeat
+
+ repeat = element "*" number
+ | element
+
+ element = cpu_function_name
+ | reservation_name
+ | result_name
+ | "nothing"
+ | "(" regexp ")"
+
+ 1. "," is used for describing start of the next cycle in
+ reservation.
+
+ 2. "|" is used for describing the reservation described by the
+ first regular expression *or* the reservation described by
+ the second regular expression *or* etc.
+
+ 3. "+" is used for describing the reservation described by the
+ first regular expression *and* the reservation described by
+ the second regular expression *and* etc.
+
+ 4. "*" is used for convenience and simply means sequence in
+ which the regular expression are repeated NUMBER times with
+ cycle advancing (see ",").
+
+ 5. cpu function unit name which means reservation.
+
+ 6. reservation name -- see define_reservation.
+
+ 7. string "nothing" means no units reservation.
+
+*/
+
+(define_automaton "one")
+
+;; All possible combinations of bundles/syllables
+(define_cpu_unit "1_0m.ii, 1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb,\
+ 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx" "one")
+(define_cpu_unit "1_0mi.i, 1_0mm.i, 1_0mf.i, 1_0mm.f, 1_0bb.b, 1_0mb.b,\
+ 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx." "one")
+(define_cpu_unit "1_0mii., 1_0mmi., 1_0mfi., 1_0mmf., 1_0bbb., 1_0mbb.,\
+ 1_0mib., 1_0mmb., 1_0mfb." "one")
+
+(define_cpu_unit "1_1m.ii, 1_1m.mi, 1_1m.fi, 1_1b.bb, 1_1m.bb,\
+ 1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx" "one")
+(define_cpu_unit "1_1mi.i, 1_1mm.i, 1_1mf.i, 1_1bb.b, 1_1mb.b,\
+ 1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx." "one")
+(define_cpu_unit "1_1mii., 1_1mmi., 1_1mfi., 1_1bbb., 1_1mbb.,\
+ 1_1mib., 1_1mmb., 1_1mfb." "one")
+
+;; Slot 1
+(exclusion_set "1_0m.ii"
+ "1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb,\
+ 1_0m.lx")
+(exclusion_set "1_0m.mi"
+ "1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0m.fi"
+ "1_0m.mf, 1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0m.mf"
+ "1_0b.bb, 1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0b.bb" "1_0m.bb, 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0m.bb" "1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0m.ib" "1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0m.mb" "1_0m.fb, 1_0m.lx")
+(exclusion_set "1_0m.fb" "1_0m.lx")
+
+;; Slot 2
+(exclusion_set "1_0mi.i"
+ "1_0mm.i, 1_0mf.i, 1_0mm.f, 1_0bb.b, 1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b,\
+ 1_0mlx.")
+(exclusion_set "1_0mm.i"
+ "1_0mf.i, 1_0mm.f, 1_0bb.b, 1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0mf.i"
+ "1_0mm.f, 1_0bb.b, 1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0mm.f"
+ "1_0bb.b, 1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0bb.b" "1_0mb.b, 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0mb.b" "1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0mi.b" "1_0mm.b, 1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0mm.b" "1_0mf.b, 1_0mlx.")
+(exclusion_set "1_0mf.b" "1_0mlx.")
+
+;; Slot 3
+(exclusion_set "1_0mii."
+ "1_0mmi., 1_0mfi., 1_0mmf., 1_0bbb., 1_0mbb., 1_0mib., 1_0mmb., 1_0mfb.,\
+ 1_0mlx.")
+(exclusion_set "1_0mmi."
+ "1_0mfi., 1_0mmf., 1_0bbb., 1_0mbb., 1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+(exclusion_set "1_0mfi."
+ "1_0mmf., 1_0bbb., 1_0mbb., 1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+(exclusion_set "1_0mmf."
+ "1_0bbb., 1_0mbb., 1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+(exclusion_set "1_0bbb." "1_0mbb., 1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+(exclusion_set "1_0mbb." "1_0mib., 1_0mmb., 1_0mfb., 1_0mlx.")
+(exclusion_set "1_0mib." "1_0mmb., 1_0mfb., 1_0mlx.")
+(exclusion_set "1_0mmb." "1_0mfb., 1_0mlx.")
+(exclusion_set "1_0mfb." "1_0mlx.")
+
+;; Slot 4
+(exclusion_set "1_1m.ii"
+ "1_1m.mi, 1_1m.fi, 1_1b.bb, 1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1m.mi"
+ "1_1m.fi, 1_1b.bb, 1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1m.fi"
+ "1_1b.bb, 1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1b.bb" "1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1m.bb" "1_1m.ib, 1_1m.mb, 1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1m.ib" "1_1m.mb, 1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1m.mb" "1_1m.fb, 1_1m.lx")
+(exclusion_set "1_1m.fb" "1_1m.lx")
+
+;; Slot 5
+(exclusion_set "1_1mi.i"
+ "1_1mm.i, 1_1mf.i, 1_1bb.b, 1_1mb.b, 1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1mm.i"
+ "1_1mf.i, 1_1bb.b, 1_1mb.b, 1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1mf.i"
+ "1_1bb.b, 1_1mb.b, 1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1bb.b" "1_1mb.b, 1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1mb.b" "1_1mi.b, 1_1mm.b, 1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1mi.b" "1_1mm.b, 1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1mm.b" "1_1mf.b, 1_1mlx.")
+(exclusion_set "1_1mf.b" "1_1mlx.")
+
+;; Slot 6
+(exclusion_set "1_1mii."
+ "1_1mmi., 1_1mfi., 1_1bbb., 1_1mbb., 1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+(exclusion_set "1_1mmi."
+ "1_1mfi., 1_1bbb., 1_1mbb., 1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+(exclusion_set "1_1mfi."
+ "1_1bbb., 1_1mbb., 1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+(exclusion_set "1_1bbb." "1_1mbb., 1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+(exclusion_set "1_1mbb." "1_1mib., 1_1mmb., 1_1mfb., 1_1mlx.")
+(exclusion_set "1_1mib." "1_1mmb., 1_1mfb., 1_1mlx.")
+(exclusion_set "1_1mmb." "1_1mfb., 1_1mlx.")
+(exclusion_set "1_1mfb." "1_1mlx.")
+
+(final_presence_set "1_0mi.i" "1_0m.ii")
+(final_presence_set "1_0mii." "1_0mi.i")
+(final_presence_set "1_1mi.i" "1_1m.ii")
+(final_presence_set "1_1mii." "1_1mi.i")
+
+(final_presence_set "1_0mm.i" "1_0m.mi")
+(final_presence_set "1_0mmi." "1_0mm.i")
+(final_presence_set "1_1mm.i" "1_1m.mi")
+(final_presence_set "1_1mmi." "1_1mm.i")
+
+(final_presence_set "1_0mf.i" "1_0m.fi")
+(final_presence_set "1_0mfi." "1_0mf.i")
+(final_presence_set "1_1mf.i" "1_1m.fi")
+(final_presence_set "1_1mfi." "1_1mf.i")
+
+(final_presence_set "1_0mm.f" "1_0m.mf")
+(final_presence_set "1_0mmf." "1_0mm.f")
+
+(final_presence_set "1_0bb.b" "1_0b.bb")
+(final_presence_set "1_0bbb." "1_0bb.b")
+(final_presence_set "1_1bb.b" "1_1b.bb")
+(final_presence_set "1_1bbb." "1_1bb.b")
+
+(final_presence_set "1_0mb.b" "1_0m.bb")
+(final_presence_set "1_0mbb." "1_0mb.b")
+(final_presence_set "1_1mb.b" "1_1m.bb")
+(final_presence_set "1_1mbb." "1_1mb.b")
+
+(final_presence_set "1_0mi.b" "1_0m.ib")
+(final_presence_set "1_0mib." "1_0mi.b")
+(final_presence_set "1_1mi.b" "1_1m.ib")
+(final_presence_set "1_1mib." "1_1mi.b")
+
+(final_presence_set "1_0mm.b" "1_0m.mb")
+(final_presence_set "1_0mmb." "1_0mm.b")
+(final_presence_set "1_1mm.b" "1_1m.mb")
+(final_presence_set "1_1mmb." "1_1mm.b")
+
+(final_presence_set "1_0mf.b" "1_0m.fb")
+(final_presence_set "1_0mfb." "1_0mf.b")
+(final_presence_set "1_1mf.b" "1_1m.fb")
+(final_presence_set "1_1mfb." "1_1mf.b")
+
+(final_presence_set "1_0mlx." "1_0m.lx")
+(final_presence_set "1_1mlx." "1_1m.lx")
+
+(final_presence_set
+ "1_1m.ii,1_1m.mi,1_1m.fi,1_1b.bb,1_1m.bb,1_1m.ib,1_1m.mb,1_1m.fb,1_1m.lx"
+ "1_0mii.,1_0mmi.,1_0mfi.,1_0mmf.,1_0bbb.,1_0mbb.,1_0mib.,1_0mmb.,1_0mfb.,\
+ 1_0mlx.")
+
+;; Microarchitecture units:
+(define_cpu_unit
+ "1_um0, 1_um1, 1_ui0, 1_ui1, 1_uf0, 1_uf1, 1_ub0, 1_ub1, 1_ub2,\
+ 1_unb0, 1_unb1, 1_unb2" "one")
+
+(exclusion_set "1_ub0" "1_unb0")
+(exclusion_set "1_ub1" "1_unb1")
+(exclusion_set "1_ub2" "1_unb2")
+
+;; The following rules are used to decrease number of alternatives.
+;; They are consequences of Itanium microarchitecture. They also
+;; describe the following rules mentioned in Itanium
+;; microarchitecture: rules mentioned in Itanium microarchitecture:
+;; o "MMF: Always splits issue before the first M and after F regardless
+;; of surrounding bundles and stops".
+;; o "BBB/MBB: Always splits issue after either of these bundles".
+;; o "MIB BBB: Split issue after the first bundle in this pair".
+
+(exclusion_set "1_0m.mf,1_0mm.f,1_0mmf."
+ "1_1m.ii,1_1m.mi,1_1m.fi,1_1b.bb,1_1m.bb,1_1m.ib,1_1m.mb,1_1m.fb,1_1m.lx")
+(exclusion_set "1_0b.bb,1_0bb.b,1_0bbb.,1_0m.bb,1_0mb.b,1_0mbb."
+ "1_1m.ii,1_1m.mi,1_1m.fi,1_1b.bb,1_1m.bb,1_1m.ib,1_1m.mb,1_1m.fb,1_1m.lx")
+(exclusion_set "1_0m.ib,1_0mi.b,1_0mib." "1_1b.bb")
+
+;; For exceptions of M, I, B, F insns:
+(define_cpu_unit "1_not_um1, 1_not_ui1, 1_not_uf1" "one")
+
+(final_absence_set "1_not_um1" "1_um1")
+(final_absence_set "1_not_ui1" "1_ui1")
+(final_absence_set "1_not_uf1" "1_uf1")
+
+;;; "MIB/MFB/MMB: Splits issue after any of these bundles unless the
+;;; B-slot contains a nop.b or a brp instruction".
+;;; "The B in an MIB/MFB/MMB bundle disperses to B0 if it is a brp or
+;;; nop.b, otherwise it disperses to B2".
+(final_absence_set
+ "1_1m.ii, 1_1m.mi, 1_1m.fi, 1_1b.bb, 1_1m.bb, 1_1m.ib, 1_1m.mb, 1_1m.fb,\
+ 1_1m.lx"
+ "1_0mib. 1_ub2, 1_0mfb. 1_ub2, 1_0mmb. 1_ub2")
+
+;; This is necessary to start new processor cycle when we meet stop bit.
+(define_cpu_unit "1_stop" "one")
+(final_absence_set
+ "1_0m.ii,1_0mi.i,1_0mii.,1_0m.mi,1_0mm.i,1_0mmi.,1_0m.fi,1_0mf.i,1_0mfi.,\
+ 1_0m.mf,1_0mm.f,1_0mmf.,1_0b.bb,1_0bb.b,1_0bbb.,1_0m.bb,1_0mb.b,1_0mbb.,\
+ 1_0m.ib,1_0mi.b,1_0mib.,1_0m.mb,1_0mm.b,1_0mmb.,1_0m.fb,1_0mf.b,1_0mfb.,\
+ 1_0m.lx,1_0mlx., \
+ 1_1m.ii,1_1mi.i,1_1mii.,1_1m.mi,1_1mm.i,1_1mmi.,1_1m.fi,1_1mf.i,1_1mfi.,\
+ 1_1b.bb,1_1bb.b,1_1bbb.,1_1m.bb,1_1mb.b,1_1mbb.,1_1m.ib,1_1mi.b,1_1mib.,\
+ 1_1m.mb,1_1mm.b,1_1mmb.,1_1m.fb,1_1mf.b,1_1mfb.,1_1m.lx,1_1mlx."
+ "1_stop")
+
+;; M and I instruction is dispersed to the lowest numbered M or I unit
+;; not already in use. An I slot in the 3rd position of 2nd bundle is
+;; always dispersed to I1
+(final_presence_set "1_um1" "1_um0")
+(final_presence_set "1_ui1" "1_ui0, 1_1mii., 1_1mmi., 1_1mfi.")
+
+;; Insns
+
+;; M and I instruction is dispersed to the lowest numbered M or I unit
+;; not already in use. An I slot in the 3rd position of 2nd bundle is
+;; always dispersed to I1
+(define_reservation "1_M0"
+ "1_0m.ii+1_um0|1_0m.mi+1_um0|1_0mm.i+(1_um0|1_um1)\
+ |1_0m.fi+1_um0|1_0m.mf+1_um0|1_0mm.f+1_um1\
+ |1_0m.bb+1_um0|1_0m.ib+1_um0|1_0m.mb+1_um0\
+ |1_0mm.b+1_um1|1_0m.fb+1_um0|1_0m.lx+1_um0\
+ |1_1mm.i+1_um1|1_1mm.b+1_um1\
+ |(1_1m.ii|1_1m.mi|1_1m.fi|1_1m.bb|1_1m.ib|1_1m.mb|1_1m.fb|1_1m.lx)\
+ +(1_um0|1_um1)")
+
+(define_reservation "1_M1"
+ "(1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0\
+ |1_0mib.+1_unb0|1_0mfb.+1_unb0|1_0mmb.+1_unb0)\
+ +(1_1m.ii|1_1m.mi|1_1m.fi|1_1m.bb|1_1m.ib|1_1m.mb|1_1m.fb|1_1m.lx)\
+ +(1_um0|1_um1)")
+
+(define_reservation "1_M" "1_M0|1_M1")
+
+;; Exceptions for dispersal rules.
+;; "An I slot in the 3rd position of 2nd bundle is always dispersed to I1".
+(define_reservation "1_I0"
+ "1_0mi.i+1_ui0|1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0\
+ |1_0mi.b+1_ui0|(1_1mi.i|1_1mi.b)+(1_ui0|1_ui1)\
+ |1_1mii.+1_ui1|1_1mmi.+1_ui1|1_1mfi.+1_ui1")
+
+(define_reservation "1_I1"
+ "1_0m.ii+1_um0+1_0mi.i+1_ui0|1_0mm.i+(1_um0|1_um1)+1_0mmi.+1_ui0\
+ |1_0mf.i+1_uf0+1_0mfi.+1_ui0|1_0m.ib+1_um0+1_0mi.b+1_ui0\
+ |(1_1m.ii+(1_um0|1_um1)+1_1mi.i\
+ |1_1m.ib+(1_um0|1_um1)+1_1mi.b)+(1_ui0|1_ui1)\
+ |1_1mm.i+1_um1+1_1mmi.+1_ui1|1_1mf.i+1_uf1+1_1mfi.+1_ui1")
+
+(define_reservation "1_I" "1_I0|1_I1")
+
+;; "An F slot in the 1st bundle disperses to F0".
+;; "An F slot in the 2st bundle disperses to F1".
+(define_reservation "1_F0"
+ "1_0mf.i+1_uf0|1_0mmf.+1_uf0|1_0mf.b+1_uf0|1_1mf.i+1_uf1|1_1mf.b+1_uf1")
+
+(define_reservation "1_F1"
+ "1_0m.fi+1_um0+1_0mf.i+1_uf0|1_0mm.f+(1_um0|1_um1)+1_0mmf.+1_uf0\
+ |1_0m.fb+1_um0+1_0mf.b+1_uf0|1_1m.fi+(1_um0|1_um1)+1_1mf.i+1_uf1\
+ |1_1m.fb+(1_um0|1_um1)+1_1mf.b+1_uf1")
+
+(define_reservation "1_F2"
+ "1_0m.mf+1_um0+1_0mm.f+1_um1+1_0mmf.+1_uf0\
+ |(1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0\
+ |1_0mib.+1_unb0|1_0mmb.+1_unb0|1_0mfb.+1_unb0)\
+ +(1_1m.fi+(1_um0|1_um1)+1_1mf.i+1_uf1\
+ |1_1m.fb+(1_um0|1_um1)+1_1mf.b+1_uf1)")
+
+(define_reservation "1_F" "1_F0|1_F1|1_F2")
+
+;;; "Each B slot in MBB or BBB bundle disperses to the corresponding B
+;;; unit. That is, a B slot in 1st position is dispersed to B0. In the
+;;; 2nd position it is dispersed to B2".
+(define_reservation "1_NB"
+ "1_0b.bb+1_unb0|1_0bb.b+1_unb1|1_0bbb.+1_unb2\
+ |1_0mb.b+1_unb1|1_0mbb.+1_unb2\
+ |1_0mib.+1_unb0|1_0mmb.+1_unb0|1_0mfb.+1_unb0\
+ |1_1b.bb+1_unb0|1_1bb.b+1_unb1\
+ |1_1bbb.+1_unb2|1_1mb.b+1_unb1|1_1mbb.+1_unb2|1_1mib.+1_unb0\
+ |1_1mmb.+1_unb0|1_1mfb.+1_unb0")
+
+(define_reservation "1_B0"
+ "1_0b.bb+1_ub0|1_0bb.b+1_ub1|1_0bbb.+1_ub2\
+ |1_0mb.b+1_ub1|1_0mbb.+1_ub2|1_0mib.+1_ub2\
+ |1_0mfb.+1_ub2|1_1b.bb+1_ub0|1_1bb.b+1_ub1\
+ |1_1bbb.+1_ub2|1_1mb.b+1_ub1\
+ |1_1mib.+1_ub2|1_1mmb.+1_ub2|1_1mfb.+1_ub2")
+
+(define_reservation "1_B1"
+ "1_0m.bb+1_um0+1_0mb.b+1_ub1|1_0mi.b+1_ui0+1_0mib.+1_ub2\
+ |1_0mf.b+1_uf0+1_0mfb.+1_ub2\
+ |(1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0)+1_1b.bb+1_ub0\
+ |1_1m.bb+(1_um0|1_um1)+1_1mb.b+1_ub1\
+ |1_1mi.b+(1_ui0|1_ui1)+1_1mib.+1_ub2\
+ |1_1mm.b+1_um1+1_1mmb.+1_ub2\
+ |1_1mf.b+1_uf1+1_1mfb.+1_ub2")
+
+(define_reservation "1_B" "1_B0|1_B1")
+
+;; MLX bunlde uses ports equivalent to MFI bundles.
+(define_reservation "1_L0" "1_0mlx.+1_ui0+1_uf0|1_1mlx.+(1_ui0|1_ui1)+1_uf1")
+(define_reservation "1_L1"
+ "1_0m.lx+1_um0+1_0mlx.+1_ui0+1_uf0\
+ |1_1m.lx+(1_um0|1_um1)+1_1mlx.+(1_ui0|1_ui1)+1_uf1")
+(define_reservation "1_L2"
+ "(1_0mii.+(1_ui0|1_ui1)|1_0mmi.+1_ui0|1_0mfi.+1_ui0\
+ |1_0mib.+1_unb0|1_0mmb.+1_unb0|1_0mfb.+1_unb0)
+ +1_1m.lx+(1_um0|1_um1)+1_1mlx.+1_ui1+1_uf1")
+(define_reservation "1_L" "1_L0|1_L1|1_L2")
+
+(define_reservation "1_A" "1_M|1_I")
+
+(define_insn_reservation "1_stop_bit" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "stop_bit"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_stop|1_m0_stop|1_m1_stop|1_mi0_stop|1_mi1_stop")
+
+(define_insn_reservation "1_br" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "br"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_B")
+(define_insn_reservation "1_scall" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "scall"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_B")
+(define_insn_reservation "1_fcmp" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fcmp"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_F+1_not_uf1")
+(define_insn_reservation "1_fcvtfx" 7
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fcvtfx"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_F")
+(define_insn_reservation "1_fld" 9
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fld"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_fmac" 5
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fmac"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_F")
+(define_insn_reservation "1_fmisc" 5
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fmisc"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_F+1_not_uf1")
+
+;; There is only one insn `mov = ar.bsp' for frar_i:
+(define_insn_reservation "1_frar_i" 13
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frar_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+;; There is only two insns `mov = ar.unat' or `mov = ar.ccv' for frar_m:
+(define_insn_reservation "1_frar_m" 6
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frar_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_M+1_not_um1")
+(define_insn_reservation "1_frbr" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frbr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+(define_insn_reservation "1_frfr" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frfr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_M+1_not_um1")
+(define_insn_reservation "1_frpr" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frpr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+
+(define_insn_reservation "1_ialu" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ialu"))
+ (eq (symbol_ref
+ "bundling_p || ia64_produce_address_p (insn)")
+ (const_int 0)))
+ "1_A")
+(define_insn_reservation "1_ialu_addr" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ialu"))
+ (eq (symbol_ref
+ "!bundling_p && ia64_produce_address_p (insn)")
+ (const_int 1)))
+ "1_M")
+(define_insn_reservation "1_icmp" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "icmp"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_A")
+(define_insn_reservation "1_ilog" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ilog"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_A")
+(define_insn_reservation "1_ishf" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ishf"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+(define_insn_reservation "1_ld" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ld"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_long_i" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "long_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_L")
+(define_insn_reservation "1_mmmul" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "mmmul"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+(define_insn_reservation "1_mmshf" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "mmshf"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_I")
+(define_insn_reservation "1_mmshfi" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "mmshfi"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_I")
+
+;; Now we have only one insn (flushrs) of such class. We assume that flushrs
+;; is the 1st syllable of the bundle after stop bit.
+(define_insn_reservation "1_rse_m" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "rse_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "(1_0m.ii|1_0m.mi|1_0m.fi|1_0m.mf|1_0b.bb|1_0m.bb\
+ |1_0m.ib|1_0m.mb|1_0m.fb|1_0m.lx)+1_um0")
+(define_insn_reservation "1_sem" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "sem"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_M+1_not_um1")
+(define_insn_reservation "1_stf" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "stf"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_st" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "st"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_syst_m0" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "syst_m0"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_M+1_not_um1")
+(define_insn_reservation "1_syst_m" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "syst_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_tbit" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "tbit"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+
+;; There is only ony insn `mov ar.pfs =' for toar_i:
+(define_insn_reservation "1_toar_i" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "toar_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m:
+(define_insn_reservation "1_toar_m" 5
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "toar_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_M+1_not_um1")
+(define_insn_reservation "1_tobr" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "tobr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+(define_insn_reservation "1_tofr" 9
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "tofr"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+(define_insn_reservation "1_topr" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "topr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_I+1_not_ui1")
+(define_insn_reservation "1_xmpy" 7
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "xmpy"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_F")
+(define_insn_reservation "1_xtd" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "xtd"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_I")
+
+(define_insn_reservation "1_chk_s" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "chk_s"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_A")
+(define_insn_reservation "1_lfetch" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "lfetch"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M")
+
+(define_insn_reservation "1_nop_m" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_M0")
+(define_insn_reservation "1_nop_b" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_b"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_NB")
+(define_insn_reservation "1_nop_i" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_I0")
+(define_insn_reservation "1_nop_f" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_f"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_F0")
+(define_insn_reservation "1_nop_x" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_x"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_L0")
+
+;; We assume that there is no insn issued on the same cycle as unknown insn.
+(define_cpu_unit "1_empty" "one")
+(exclusion_set "1_empty"
+ "1_0m.ii,1_0m.mi,1_0m.fi,1_0m.mf,1_0b.bb,1_0m.bb,1_0m.ib,1_0m.mb,1_0m.fb,\
+ 1_0m.lx")
+
+(define_insn_reservation "1_unknown" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "unknown"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "1_empty")
+
+(define_insn_reservation "1_nop" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "1_M0|1_NB|1_I0|1_F0")
+
+(define_insn_reservation "1_ignore" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ignore"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "nothing")
+
+
+(define_cpu_unit
+ "1_0m_bs, 1_0mi_bs, 1_0mm_bs, 1_0mf_bs, 1_0b_bs, 1_0bb_bs, 1_0mb_bs"
+ "one")
+(define_cpu_unit
+ "1_1m_bs, 1_1mi_bs, 1_1mm_bs, 1_1mf_bs, 1_1b_bs, 1_1bb_bs, 1_1mb_bs"
+ "one")
+
+(define_cpu_unit "1_m_cont, 1_mi_cont, 1_mm_cont, 1_mf_cont, 1_mb_cont,\
+ 1_b_cont, 1_bb_cont" "one")
+
+;; For stop in the middle of the bundles.
+(define_cpu_unit "1_m_stop, 1_m0_stop, 1_m1_stop, 1_0mmi_cont" "one")
+(define_cpu_unit "1_mi_stop, 1_mi0_stop, 1_mi1_stop, 1_0mii_cont" "one")
+
+(final_presence_set "1_0m_bs"
+ "1_0m.ii, 1_0m.mi, 1_0m.mf, 1_0m.fi, 1_0m.bb,\
+ 1_0m.ib, 1_0m.fb, 1_0m.mb, 1_0m.lx")
+(final_presence_set "1_1m_bs"
+ "1_1m.ii, 1_1m.mi, 1_1m.fi, 1_1m.bb, 1_1m.ib, 1_1m.fb, 1_1m.mb,\
+ 1_1m.lx")
+(final_presence_set "1_0mi_bs" "1_0mi.i, 1_0mi.i")
+(final_presence_set "1_1mi_bs" "1_1mi.i, 1_1mi.i")
+(final_presence_set "1_0mm_bs" "1_0mm.i, 1_0mm.f, 1_0mm.b")
+(final_presence_set "1_1mm_bs" "1_1mm.i, 1_1mm.b")
+(final_presence_set "1_0mf_bs" "1_0mf.i, 1_0mf.b")
+(final_presence_set "1_1mf_bs" "1_1mf.i, 1_1mf.b")
+(final_presence_set "1_0b_bs" "1_0b.bb")
+(final_presence_set "1_1b_bs" "1_1b.bb")
+(final_presence_set "1_0bb_bs" "1_0bb.b")
+(final_presence_set "1_1bb_bs" "1_1bb.b")
+(final_presence_set "1_0mb_bs" "1_0mb.b")
+(final_presence_set "1_1mb_bs" "1_1mb.b")
+
+(exclusion_set "1_0m_bs"
+ "1_0mi.i, 1_0mm.i, 1_0mm.f, 1_0mf.i, 1_0mb.b,\
+ 1_0mi.b, 1_0mf.b, 1_0mm.b, 1_0mlx., 1_m0_stop")
+(exclusion_set "1_1m_bs"
+ "1_1mi.i, 1_1mm.i, 1_1mf.i, 1_1mb.b, 1_1mi.b, 1_1mf.b, 1_1mm.b,\
+ 1_1mlx., 1_m1_stop")
+(exclusion_set "1_0mi_bs" "1_0mii., 1_0mib., 1_mi0_stop")
+(exclusion_set "1_1mi_bs" "1_1mii., 1_1mib., 1_mi1_stop")
+(exclusion_set "1_0mm_bs" "1_0mmi., 1_0mmf., 1_0mmb.")
+(exclusion_set "1_1mm_bs" "1_1mmi., 1_1mmb.")
+(exclusion_set "1_0mf_bs" "1_0mfi., 1_0mfb.")
+(exclusion_set "1_1mf_bs" "1_1mfi., 1_1mfb.")
+(exclusion_set "1_0b_bs" "1_0bb.b")
+(exclusion_set "1_1b_bs" "1_1bb.b")
+(exclusion_set "1_0bb_bs" "1_0bbb.")
+(exclusion_set "1_1bb_bs" "1_1bbb.")
+(exclusion_set "1_0mb_bs" "1_0mbb.")
+(exclusion_set "1_1mb_bs" "1_1mbb.")
+
+(exclusion_set
+ "1_0m_bs, 1_0mi_bs, 1_0mm_bs, 1_0mf_bs, 1_0b_bs, 1_0bb_bs, 1_0mb_bs,
+ 1_1m_bs, 1_1mi_bs, 1_1mm_bs, 1_1mf_bs, 1_1b_bs, 1_1bb_bs, 1_1mb_bs"
+ "1_stop")
+
+(final_presence_set
+ "1_0mi.i, 1_0mm.i, 1_0mf.i, 1_0mm.f, 1_0mb.b,\
+ 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx."
+ "1_m_cont")
+(final_presence_set "1_0mii., 1_0mib." "1_mi_cont")
+(final_presence_set "1_0mmi., 1_0mmf., 1_0mmb." "1_mm_cont")
+(final_presence_set "1_0mfi., 1_0mfb." "1_mf_cont")
+(final_presence_set "1_0bb.b" "1_b_cont")
+(final_presence_set "1_0bbb." "1_bb_cont")
+(final_presence_set "1_0mbb." "1_mb_cont")
+
+(exclusion_set
+ "1_0m.ii, 1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb,\
+ 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx"
+ "1_m_cont, 1_mi_cont, 1_mm_cont, 1_mf_cont,\
+ 1_mb_cont, 1_b_cont, 1_bb_cont")
+
+(exclusion_set "1_empty"
+ "1_m_cont,1_mi_cont,1_mm_cont,1_mf_cont,\
+ 1_mb_cont,1_b_cont,1_bb_cont")
+
+;; For m;mi bundle
+(final_presence_set "1_m0_stop" "1_0m.mi")
+(final_presence_set "1_0mm.i" "1_0mmi_cont")
+(exclusion_set "1_0mmi_cont"
+ "1_0m.ii, 1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb,\
+ 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_m0_stop" "1_0mm.i")
+(final_presence_set "1_m1_stop" "1_1m.mi")
+(exclusion_set "1_m1_stop" "1_1mm.i")
+(final_presence_set "1_m_stop" "1_m0_stop, 1_m1_stop")
+
+;; For mi;i bundle
+(final_presence_set "1_mi0_stop" "1_0mi.i")
+(final_presence_set "1_0mii." "1_0mii_cont")
+(exclusion_set "1_0mii_cont"
+ "1_0m.ii, 1_0m.mi, 1_0m.fi, 1_0m.mf, 1_0b.bb, 1_0m.bb,\
+ 1_0m.ib, 1_0m.mb, 1_0m.fb, 1_0m.lx")
+(exclusion_set "1_mi0_stop" "1_0mii.")
+(final_presence_set "1_mi1_stop" "1_1mi.i")
+(exclusion_set "1_mi1_stop" "1_1mii.")
+(final_presence_set "1_mi_stop" "1_mi0_stop, 1_mi1_stop")
+
+(final_absence_set
+ "1_0m.ii,1_0mi.i,1_0mii.,1_0m.mi,1_0mm.i,1_0mmi.,1_0m.fi,1_0mf.i,1_0mfi.,\
+ 1_0m.mf,1_0mm.f,1_0mmf.,1_0b.bb,1_0bb.b,1_0bbb.,1_0m.bb,1_0mb.b,1_0mbb.,\
+ 1_0m.ib,1_0mi.b,1_0mib.,1_0m.mb,1_0mm.b,1_0mmb.,1_0m.fb,1_0mf.b,1_0mfb.,\
+ 1_0m.lx,1_0mlx., \
+ 1_1m.ii,1_1mi.i,1_1mii.,1_1m.mi,1_1mm.i,1_1mmi.,1_1m.fi,1_1mf.i,1_1mfi.,\
+ 1_1b.bb,1_1bb.b,1_1bbb.,1_1m.bb,1_1mb.b,1_1mbb.,\
+ 1_1m.ib,1_1mi.b,1_1mib.,1_1m.mb,1_1mm.b,1_1mmb.,1_1m.fb,1_1mf.b,1_1mfb.,\
+ 1_1m.lx,1_1mlx."
+ "1_m0_stop,1_m1_stop,1_mi0_stop,1_mi1_stop")
+
+(define_cpu_unit "1_m_cont_only, 1_b_cont_only" "one")
+(define_cpu_unit "1_mi_cont_only, 1_mm_cont_only, 1_mf_cont_only" "one")
+(define_cpu_unit "1_mb_cont_only, 1_bb_cont_only" "one")
+
+(final_presence_set "1_m_cont_only" "1_m_cont")
+(exclusion_set "1_m_cont_only"
+ "1_0mi.i, 1_0mm.i, 1_0mf.i, 1_0mm.f, 1_0mb.b,\
+ 1_0mi.b, 1_0mm.b, 1_0mf.b, 1_0mlx.")
+
+(final_presence_set "1_b_cont_only" "1_b_cont")
+(exclusion_set "1_b_cont_only" "1_0bb.b")
+
+(final_presence_set "1_mi_cont_only" "1_mi_cont")
+(exclusion_set "1_mi_cont_only" "1_0mii., 1_0mib.")
+
+(final_presence_set "1_mm_cont_only" "1_mm_cont")
+(exclusion_set "1_mm_cont_only" "1_0mmi., 1_0mmf., 1_0mmb.")
+
+(final_presence_set "1_mf_cont_only" "1_mf_cont")
+(exclusion_set "1_mf_cont_only" "1_0mfi., 1_0mfb.")
+
+(final_presence_set "1_mb_cont_only" "1_mb_cont")
+(exclusion_set "1_mb_cont_only" "1_0mbb.")
+
+(final_presence_set "1_bb_cont_only" "1_bb_cont")
+(exclusion_set "1_bb_cont_only" "1_0bbb.")
+
+(define_insn_reservation "1_pre_cycle" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "pre_cycle"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "(1_0m_bs, 1_m_cont) \
+ | (1_0mi_bs, (1_mi_cont|nothing)) \
+ | (1_0mm_bs, 1_mm_cont) \
+ | (1_0mf_bs, (1_mf_cont|nothing)) \
+ | (1_0b_bs, (1_b_cont|nothing)) \
+ | (1_0bb_bs, (1_bb_cont|nothing)) \
+ | (1_0mb_bs, (1_mb_cont|nothing)) \
+ | (1_1m_bs, 1_m_cont) \
+ | (1_1mi_bs, (1_mi_cont|nothing)) \
+ | (1_1mm_bs, 1_mm_cont) \
+ | (1_1mf_bs, (1_mf_cont|nothing)) \
+ | (1_1b_bs, (1_b_cont|nothing)) \
+ | (1_1bb_bs, (1_bb_cont|nothing)) \
+ | (1_1mb_bs, (1_mb_cont|nothing)) \
+ | (1_m_cont_only, (1_m_cont|nothing)) \
+ | (1_b_cont_only, (1_b_cont|nothing)) \
+ | (1_mi_cont_only, (1_mi_cont|nothing)) \
+ | (1_mm_cont_only, (1_mm_cont|nothing)) \
+ | (1_mf_cont_only, (1_mf_cont|nothing)) \
+ | (1_mb_cont_only, (1_mb_cont|nothing)) \
+ | (1_bb_cont_only, (1_bb_cont|nothing)) \
+ | (1_m_stop, (1_0mmi_cont|nothing)) \
+ | (1_mi_stop, (1_0mii_cont|nothing))")
+
+;; Bypasses:
+(define_bypass 1 "1_fcmp" "1_br,1_scall")
+;; ??? I found 7 cycle delay for 1_fmac -> 1_fcmp for Itanium1
+(define_bypass 7 "1_fmac" "1_fmisc,1_fcvtfx,1_xmpy,1_fcmp")
+
+;; ???
+(define_bypass 3 "1_frbr" "1_mmmul,1_mmshf")
+(define_bypass 14 "1_frar_i" "1_mmmul,1_mmshf")
+(define_bypass 7 "1_frar_m" "1_mmmul,1_mmshf")
+
+;; ????
+;; There is only one insn `mov ar.pfs =' for toar_i.
+(define_bypass 0 "1_tobr,1_topr,1_toar_i" "1_br,1_scall")
+
+(define_bypass 3 "1_ialu,1_ialu_addr" "1_mmmul,1_mmshf")
+;; ??? howto describe ialu for I slot only. We use ialu_addr for that
+;;(define_bypass 2 "1_ialu" "1_ld" "ia64_ld_address_bypass_p")
+;; ??? howto describe ialu st/address for I slot only. We use ialu_addr
+;; for that.
+;;(define_bypass 2 "1_ialu" "1_st" "ia64_st_address_bypass_p")
+
+(define_bypass 0 "1_icmp" "1_br,1_scall")
+
+(define_bypass 3 "1_ilog" "1_mmmul,1_mmshf")
+
+(define_bypass 2 "1_ilog,1_xtd" "1_ld" "ia64_ld_address_bypass_p")
+(define_bypass 2 "1_ilog,1_xtd" "1_st" "ia64_st_address_bypass_p")
+
+(define_bypass 3 "1_ld" "1_mmmul,1_mmshf")
+(define_bypass 3 "1_ld" "1_ld" "ia64_ld_address_bypass_p")
+(define_bypass 3 "1_ld" "1_st" "ia64_st_address_bypass_p")
+
+;; Intel docs say only LD, ST, IALU, ILOG, ISHF consumers have latency 4,
+;; but HP engineers say any non-MM operation.
+(define_bypass 4 "1_mmmul,1_mmshf"
+ "1_br,1_fcmp,1_fcvtfx,1_fld,1_fmac,1_fmisc,1_frar_i,1_frar_m,\
+ 1_frbr,1_frfr,1_frpr,1_ialu,1_icmp,1_ilog,1_ishf,1_ld,1_chk_s,\
+ 1_long_i,1_rse_m,1_sem,1_stf,1_st,1_syst_m0,1_syst_m,\
+ 1_tbit,1_toar_i,1_toar_m,1_tobr,1_tofr,1_topr,1_xmpy,1_xtd")
+
+;; ??? how to describe that if scheduled < 4 cycle then latency is 10 cycles.
+;; (define_bypass 10 "1_mmmul,1_mmshf" "1_ialu,1_ilog,1_ishf,1_st,1_ld")
+
+(define_bypass 0 "1_tbit" "1_br,1_scall")
+
+(define_bypass 8 "1_tofr" "1_frfr,1_stf")
+(define_bypass 7 "1_fmisc,1_fcvtfx,1_fmac,1_xmpy" "1_frfr")
+(define_bypass 8 "1_fmisc,1_fcvtfx,1_fmac,1_xmpy" "1_stf")
+
+;; We don't use here fcmp because scall may be predicated.
+(define_bypass 0 "1_fcvtfx,1_fld,1_fmac,1_fmisc,1_frar_i,1_frar_m,\
+ 1_frbr,1_frfr,1_frpr,1_ialu,1_ialu_addr,1_ilog,1_ishf,\
+ 1_ld,1_long_i,1_mmmul,1_mmshf,1_mmshfi,1_toar_m,1_tofr,\
+ 1_xmpy,1_xtd" "1_scall")
+
+(define_bypass 0 "1_unknown,1_ignore,1_stop_bit,1_br,1_fcmp,1_fcvtfx,\
+ 1_fld,1_fmac,1_fmisc,1_frar_i,1_frar_m,1_frbr,1_frfr,\
+ 1_frpr,1_ialu,1_ialu_addr,1_icmp,1_ilog,1_ishf,1_ld,\
+ 1_chk_s,1_long_i,1_mmmul,1_mmshf,1_mmshfi,1_nop,\
+ 1_nop_b,1_nop_f,1_nop_i,1_nop_m,1_nop_x,1_rse_m,1_scall,\
+ 1_sem,1_stf,1_st,1_syst_m0,1_syst_m,1_tbit,1_toar_i,\
+ 1_toar_m,1_tobr,1_tofr,1_topr,1_xmpy,1_xtd,1_lfetch"
+ "1_ignore")
+
+
+;; Bundling
+
+(define_automaton "oneb")
+
+;; Pseudo units for quicker searching for position in two packet window. */
+(define_query_cpu_unit "1_1,1_2,1_3,1_4,1_5,1_6" "oneb")
+
+;; All possible combinations of bundles/syllables
+(define_cpu_unit
+ "1b_0m.ii, 1b_0m.mi, 1b_0m.fi, 1b_0m.mf, 1b_0b.bb, 1b_0m.bb,\
+ 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx" "oneb")
+(define_cpu_unit
+ "1b_0mi.i, 1b_0mm.i, 1b_0mf.i, 1b_0mm.f, 1b_0bb.b, 1b_0mb.b,\
+ 1b_0mi.b, 1b_0mm.b, 1b_0mf.b" "oneb")
+(define_query_cpu_unit
+ "1b_0mii., 1b_0mmi., 1b_0mfi., 1b_0mmf., 1b_0bbb., 1b_0mbb.,\
+ 1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx." "oneb")
+
+(define_cpu_unit "1b_1m.ii, 1b_1m.mi, 1b_1m.fi, 1b_1b.bb, 1b_1m.bb,\
+ 1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx" "oneb")
+(define_cpu_unit "1b_1mi.i, 1b_1mm.i, 1b_1mf.i, 1b_1bb.b, 1b_1mb.b,\
+ 1b_1mi.b, 1b_1mm.b, 1b_1mf.b" "oneb")
+(define_query_cpu_unit "1b_1mii., 1b_1mmi., 1b_1mfi., 1b_1bbb., 1b_1mbb.,\
+ 1b_1mib., 1b_1mmb., 1b_1mfb., 1b_1mlx." "oneb")
+
+;; Slot 1
+(exclusion_set "1b_0m.ii"
+ "1b_0m.mi, 1b_0m.fi, 1b_0m.mf, 1b_0b.bb, 1b_0m.bb,\
+ 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.mi"
+ "1b_0m.fi, 1b_0m.mf, 1b_0b.bb, 1b_0m.bb, 1b_0m.ib,\
+ 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.fi"
+ "1b_0m.mf, 1b_0b.bb, 1b_0m.bb, 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.mf"
+ "1b_0b.bb, 1b_0m.bb, 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0b.bb" "1b_0m.bb, 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.bb" "1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.ib" "1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.mb" "1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_0m.fb" "1b_0m.lx")
+
+;; Slot 2
+(exclusion_set "1b_0mi.i"
+ "1b_0mm.i, 1b_0mf.i, 1b_0mm.f, 1b_0bb.b, 1b_0mb.b,\
+ 1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mm.i"
+ "1b_0mf.i, 1b_0mm.f, 1b_0bb.b, 1b_0mb.b,\
+ 1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mf.i"
+ "1b_0mm.f, 1b_0bb.b, 1b_0mb.b, 1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mm.f"
+ "1b_0bb.b, 1b_0mb.b, 1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0bb.b" "1b_0mb.b, 1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mb.b" "1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mi.b" "1b_0mm.b, 1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mm.b" "1b_0mf.b, 1b_0mlx.")
+(exclusion_set "1b_0mf.b" "1b_0mlx.")
+
+;; Slot 3
+(exclusion_set "1b_0mii."
+ "1b_0mmi., 1b_0mfi., 1b_0mmf., 1b_0bbb., 1b_0mbb.,\
+ 1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mmi."
+ "1b_0mfi., 1b_0mmf., 1b_0bbb., 1b_0mbb.,\
+ 1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mfi."
+ "1b_0mmf., 1b_0bbb., 1b_0mbb., 1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mmf."
+ "1b_0bbb., 1b_0mbb., 1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0bbb." "1b_0mbb., 1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mbb." "1b_0mib., 1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mib." "1b_0mmb., 1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mmb." "1b_0mfb., 1b_0mlx.")
+(exclusion_set "1b_0mfb." "1b_0mlx.")
+
+;; Slot 4
+(exclusion_set "1b_1m.ii"
+ "1b_1m.mi, 1b_1m.fi, 1b_1b.bb, 1b_1m.bb,\
+ 1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1m.mi"
+ "1b_1m.fi, 1b_1b.bb, 1b_1m.bb, 1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1m.fi"
+ "1b_1b.bb, 1b_1m.bb, 1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1b.bb" "1b_1m.bb, 1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1m.bb" "1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1m.ib" "1b_1m.mb, 1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1m.mb" "1b_1m.fb, 1b_1m.lx")
+(exclusion_set "1b_1m.fb" "1b_1m.lx")
+
+;; Slot 5
+(exclusion_set "1b_1mi.i"
+ "1b_1mm.i, 1b_1mf.i, 1b_1bb.b, 1b_1mb.b,\
+ 1b_1mi.b, 1b_1mm.b, 1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1mm.i"
+ "1b_1mf.i, 1b_1bb.b, 1b_1mb.b, 1b_1mi.b, 1b_1mm.b, 1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1mf.i"
+ "1b_1bb.b, 1b_1mb.b, 1b_1mi.b, 1b_1mm.b, 1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1bb.b" "1b_1mb.b, 1b_1mi.b, 1b_1mm.b, 1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1mb.b" "1b_1mi.b, 1b_1mm.b, 1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1mi.b" "1b_1mm.b, 1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1mm.b" "1b_1mf.b, 1b_1mlx.")
+(exclusion_set "1b_1mf.b" "1b_1mlx.")
+
+;; Slot 6
+(exclusion_set "1b_1mii."
+ "1b_1mmi., 1b_1mfi., 1b_1bbb., 1b_1mbb.,\
+ 1b_1mib., 1b_1mmb., 1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1mmi."
+ "1b_1mfi., 1b_1bbb., 1b_1mbb., 1b_1mib., 1b_1mmb., 1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1mfi."
+ "1b_1bbb., 1b_1mbb., 1b_1mib., 1b_1mmb., 1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1bbb." "1b_1mbb., 1b_1mib., 1b_1mmb., 1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1mbb." "1b_1mib., 1b_1mmb., 1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1mib." "1b_1mmb., 1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1mmb." "1b_1mfb., 1b_1mlx.")
+(exclusion_set "1b_1mfb." "1b_1mlx.")
+
+(final_presence_set "1b_0mi.i" "1b_0m.ii")
+(final_presence_set "1b_0mii." "1b_0mi.i")
+(final_presence_set "1b_1mi.i" "1b_1m.ii")
+(final_presence_set "1b_1mii." "1b_1mi.i")
+
+(final_presence_set "1b_0mm.i" "1b_0m.mi")
+(final_presence_set "1b_0mmi." "1b_0mm.i")
+(final_presence_set "1b_1mm.i" "1b_1m.mi")
+(final_presence_set "1b_1mmi." "1b_1mm.i")
+
+(final_presence_set "1b_0mf.i" "1b_0m.fi")
+(final_presence_set "1b_0mfi." "1b_0mf.i")
+(final_presence_set "1b_1mf.i" "1b_1m.fi")
+(final_presence_set "1b_1mfi." "1b_1mf.i")
+
+(final_presence_set "1b_0mm.f" "1b_0m.mf")
+(final_presence_set "1b_0mmf." "1b_0mm.f")
+
+(final_presence_set "1b_0bb.b" "1b_0b.bb")
+(final_presence_set "1b_0bbb." "1b_0bb.b")
+(final_presence_set "1b_1bb.b" "1b_1b.bb")
+(final_presence_set "1b_1bbb." "1b_1bb.b")
+
+(final_presence_set "1b_0mb.b" "1b_0m.bb")
+(final_presence_set "1b_0mbb." "1b_0mb.b")
+(final_presence_set "1b_1mb.b" "1b_1m.bb")
+(final_presence_set "1b_1mbb." "1b_1mb.b")
+
+(final_presence_set "1b_0mi.b" "1b_0m.ib")
+(final_presence_set "1b_0mib." "1b_0mi.b")
+(final_presence_set "1b_1mi.b" "1b_1m.ib")
+(final_presence_set "1b_1mib." "1b_1mi.b")
+
+(final_presence_set "1b_0mm.b" "1b_0m.mb")
+(final_presence_set "1b_0mmb." "1b_0mm.b")
+(final_presence_set "1b_1mm.b" "1b_1m.mb")
+(final_presence_set "1b_1mmb." "1b_1mm.b")
+
+(final_presence_set "1b_0mf.b" "1b_0m.fb")
+(final_presence_set "1b_0mfb." "1b_0mf.b")
+(final_presence_set "1b_1mf.b" "1b_1m.fb")
+(final_presence_set "1b_1mfb." "1b_1mf.b")
+
+(final_presence_set "1b_0mlx." "1b_0m.lx")
+(final_presence_set "1b_1mlx." "1b_1m.lx")
+
+(final_presence_set
+ "1b_1m.ii,1b_1m.mi,1b_1m.fi,1b_1b.bb,1b_1m.bb,\
+ 1b_1m.ib,1b_1m.mb,1b_1m.fb,1b_1m.lx"
+ "1b_0mii.,1b_0mmi.,1b_0mfi.,1b_0mmf.,1b_0bbb.,1b_0mbb.,\
+ 1b_0mib.,1b_0mmb.,1b_0mfb.,1b_0mlx.")
+
+;; Microarchitecture units:
+(define_cpu_unit
+ "1b_um0, 1b_um1, 1b_ui0, 1b_ui1, 1b_uf0, 1b_uf1, 1b_ub0, 1b_ub1, 1b_ub2,\
+ 1b_unb0, 1b_unb1, 1b_unb2" "oneb")
+
+(exclusion_set "1b_ub0" "1b_unb0")
+(exclusion_set "1b_ub1" "1b_unb1")
+(exclusion_set "1b_ub2" "1b_unb2")
+
+;; The following rules are used to decrease number of alternatives.
+;; They are consequences of Itanium microarchitecture. They also
+;; describe the following rules mentioned in Itanium
+;; microarchitecture: rules mentioned in Itanium microarchitecture:
+;; o "MMF: Always splits issue before the first M and after F regardless
+;; of surrounding bundles and stops".
+;; o "BBB/MBB: Always splits issue after either of these bundles".
+;; o "MIB BBB: Split issue after the first bundle in this pair".
+
+(exclusion_set "1b_0m.mf,1b_0mm.f,1b_0mmf."
+ "1b_1m.ii,1b_1m.mi,1b_1m.fi,1b_1b.bb,1b_1m.bb,\
+ 1b_1m.ib,1b_1m.mb,1b_1m.fb,1b_1m.lx")
+(exclusion_set "1b_0b.bb,1b_0bb.b,1b_0bbb.,1b_0m.bb,1b_0mb.b,1b_0mbb."
+ "1b_1m.ii,1b_1m.mi,1b_1m.fi,1b_1b.bb,1b_1m.bb,\
+ 1b_1m.ib,1b_1m.mb,1b_1m.fb,1b_1m.lx")
+(exclusion_set "1b_0m.ib,1b_0mi.b,1b_0mib." "1b_1b.bb")
+
+;; For exceptions of M, I, B, F insns:
+(define_cpu_unit "1b_not_um1, 1b_not_ui1, 1b_not_uf1" "oneb")
+
+(final_absence_set "1b_not_um1" "1b_um1")
+(final_absence_set "1b_not_ui1" "1b_ui1")
+(final_absence_set "1b_not_uf1" "1b_uf1")
+
+;;; "MIB/MFB/MMB: Splits issue after any of these bundles unless the
+;;; B-slot contains a nop.b or a brp instruction".
+;;; "The B in an MIB/MFB/MMB bundle disperses to B0 if it is a brp or
+;;; nop.b, otherwise it disperses to B2".
+(final_absence_set
+ "1b_1m.ii, 1b_1m.mi, 1b_1m.fi, 1b_1b.bb, 1b_1m.bb,\
+ 1b_1m.ib, 1b_1m.mb, 1b_1m.fb, 1b_1m.lx"
+ "1b_0mib. 1b_ub2, 1b_0mfb. 1b_ub2, 1b_0mmb. 1b_ub2")
+
+;; This is necessary to start new processor cycle when we meet stop bit.
+(define_cpu_unit "1b_stop" "oneb")
+(final_absence_set
+ "1b_0m.ii,1b_0mi.i,1b_0mii.,1b_0m.mi,1b_0mm.i,1b_0mmi.,\
+ 1b_0m.fi,1b_0mf.i,1b_0mfi.,\
+ 1b_0m.mf,1b_0mm.f,1b_0mmf.,1b_0b.bb,1b_0bb.b,1b_0bbb.,\
+ 1b_0m.bb,1b_0mb.b,1b_0mbb.,\
+ 1b_0m.ib,1b_0mi.b,1b_0mib.,1b_0m.mb,1b_0mm.b,1b_0mmb.,\
+ 1b_0m.fb,1b_0mf.b,1b_0mfb.,1b_0m.lx,1b_0mlx., \
+ 1b_1m.ii,1b_1mi.i,1b_1mii.,1b_1m.mi,1b_1mm.i,1b_1mmi.,\
+ 1b_1m.fi,1b_1mf.i,1b_1mfi.,\
+ 1b_1b.bb,1b_1bb.b,1b_1bbb.,1b_1m.bb,1b_1mb.b,1b_1mbb.,\
+ 1b_1m.ib,1b_1mi.b,1b_1mib.,\
+ 1b_1m.mb,1b_1mm.b,1b_1mmb.,1b_1m.fb,1b_1mf.b,1b_1mfb.,1b_1m.lx,1b_1mlx."
+ "1b_stop")
+
+;; M and I instruction is dispersed to the lowest numbered M or I unit
+;; not already in use. An I slot in the 3rd position of 2nd bundle is
+;; always dispersed to I1
+(final_presence_set "1b_um1" "1b_um0")
+(final_presence_set "1b_ui1" "1b_ui0, 1b_1mii., 1b_1mmi., 1b_1mfi.")
+
+;; Insns
+
+;; M and I instruction is dispersed to the lowest numbered M or I unit
+;; not already in use. An I slot in the 3rd position of 2nd bundle is
+;; always dispersed to I1
+(define_reservation "1b_M"
+ "1b_0m.ii+1_1+1b_um0|1b_0m.mi+1_1+1b_um0|1b_0mm.i+1_2+(1b_um0|1b_um1)\
+ |1b_0m.fi+1_1+1b_um0|1b_0m.mf+1_1+1b_um0|1b_0mm.f+1_2+1b_um1\
+ |1b_0m.bb+1_1+1b_um0|1b_0m.ib+1_1+1b_um0|1b_0m.mb+1_1+1b_um0\
+ |1b_0mm.b+1_2+1b_um1|1b_0m.fb+1_1+1b_um0|1b_0m.lx+1_1+1b_um0\
+ |1b_1mm.i+1_5+1b_um1|1b_1mm.b+1_5+1b_um1\
+ |(1b_1m.ii+1_4|1b_1m.mi+1_4|1b_1m.fi+1_4|1b_1m.bb+1_4|1b_1m.ib+1_4\
+ |1b_1m.mb+1_4|1b_1m.fb+1_4|1b_1m.lx+1_4)\
+ +(1b_um0|1b_um1)")
+
+;; Exceptions for dispersal rules.
+;; "An I slot in the 3rd position of 2nd bundle is always dispersed to I1".
+(define_reservation "1b_I"
+ "1b_0mi.i+1_2+1b_ui0|1b_0mii.+1_3+(1b_ui0|1b_ui1)|1b_0mmi.+1_3+1b_ui0\
+ |1b_0mfi.+1_3+1b_ui0|1b_0mi.b+1_2+1b_ui0\
+ |(1b_1mi.i+1_5|1b_1mi.b+1_5)+(1b_ui0|1b_ui1)\
+ |1b_1mii.+1_6+1b_ui1|1b_1mmi.+1_6+1b_ui1|1b_1mfi.+1_6+1b_ui1")
+
+;; "An F slot in the 1st bundle disperses to F0".
+;; "An F slot in the 2st bundle disperses to F1".
+(define_reservation "1b_F"
+ "1b_0mf.i+1_2+1b_uf0|1b_0mmf.+1_3+1b_uf0|1b_0mf.b+1_2+1b_uf0\
+ |1b_1mf.i+1_5+1b_uf1|1b_1mf.b+1_5+1b_uf1")
+
+;;; "Each B slot in MBB or BBB bundle disperses to the corresponding B
+;;; unit. That is, a B slot in 1st position is dispersed to B0. In the
+;;; 2nd position it is dispersed to B2".
+(define_reservation "1b_NB"
+ "1b_0b.bb+1_1+1b_unb0|1b_0bb.b+1_2+1b_unb1|1b_0bbb.+1_3+1b_unb2\
+ |1b_0mb.b+1_2+1b_unb1|1b_0mbb.+1_3+1b_unb2\
+ |1b_0mib.+1_3+1b_unb0|1b_0mmb.+1_3+1b_unb0|1b_0mfb.+1_3+1b_unb0\
+ |1b_1b.bb+1_4+1b_unb0|1b_1bb.b+1_5+1b_unb1\
+ |1b_1bbb.+1_6+1b_unb2|1b_1mb.b+1_5+1b_unb1|1b_1mbb.+1_6+1b_unb2\
+ |1b_1mib.+1_6+1b_unb0|1b_1mmb.+1_6+1b_unb0|1b_1mfb.+1_6+1b_unb0")
+
+(define_reservation "1b_B"
+ "1b_0b.bb+1_1+1b_ub0|1b_0bb.b+1_2+1b_ub1|1b_0bbb.+1_3+1b_ub2\
+ |1b_0mb.b+1_2+1b_ub1|1b_0mbb.+1_3+1b_ub2|1b_0mib.+1_3+1b_ub2\
+ |1b_0mfb.+1_3+1b_ub2|1b_1b.bb+1_4+1b_ub0|1b_1bb.b+1_5+1b_ub1\
+ |1b_1bbb.+1_6+1b_ub2|1b_1mb.b+1_5+1b_ub1\
+ |1b_1mib.+1_6+1b_ub2|1b_1mmb.+1_6+1b_ub2|1b_1mfb.+1_6+1b_ub2")
+
+(define_reservation "1b_L" "1b_0mlx.+1_3+1b_ui0+1b_uf0\
+ |1b_1mlx.+1_6+(1b_ui0|1b_ui1)+1b_uf1")
+
+;; We assume that there is no insn issued on the same cycle as unknown insn.
+(define_cpu_unit "1b_empty" "oneb")
+(exclusion_set "1b_empty"
+ "1b_0m.ii,1b_0m.mi,1b_0m.fi,1b_0m.mf,1b_0b.bb,1b_0m.bb,\
+ 1b_0m.ib,1b_0m.mb,1b_0m.fb,1b_0m.lx")
+
+(define_cpu_unit
+ "1b_0m_bs, 1b_0mi_bs, 1b_0mm_bs, 1b_0mf_bs, 1b_0b_bs, 1b_0bb_bs, 1b_0mb_bs"
+ "oneb")
+(define_cpu_unit
+ "1b_1m_bs, 1b_1mi_bs, 1b_1mm_bs, 1b_1mf_bs, 1b_1b_bs, 1b_1bb_bs, 1b_1mb_bs"
+ "oneb")
+
+(define_cpu_unit "1b_m_cont, 1b_mi_cont, 1b_mm_cont, 1b_mf_cont, 1b_mb_cont,\
+ 1b_b_cont, 1b_bb_cont" "oneb")
+
+;; For stop in the middle of the bundles.
+(define_cpu_unit "1b_m_stop, 1b_m0_stop, 1b_m1_stop, 1b_0mmi_cont" "oneb")
+(define_cpu_unit "1b_mi_stop, 1b_mi0_stop, 1b_mi1_stop, 1b_0mii_cont" "oneb")
+
+(final_presence_set "1b_0m_bs"
+ "1b_0m.ii, 1b_0m.mi, 1b_0m.mf, 1b_0m.fi, 1b_0m.bb,\
+ 1b_0m.ib, 1b_0m.fb, 1b_0m.mb, 1b_0m.lx")
+(final_presence_set "1b_1m_bs"
+ "1b_1m.ii, 1b_1m.mi, 1b_1m.fi, 1b_1m.bb, 1b_1m.ib, 1b_1m.fb, 1b_1m.mb,\
+ 1b_1m.lx")
+(final_presence_set "1b_0mi_bs" "1b_0mi.i, 1b_0mi.i")
+(final_presence_set "1b_1mi_bs" "1b_1mi.i, 1b_1mi.i")
+(final_presence_set "1b_0mm_bs" "1b_0mm.i, 1b_0mm.f, 1b_0mm.b")
+(final_presence_set "1b_1mm_bs" "1b_1mm.i, 1b_1mm.b")
+(final_presence_set "1b_0mf_bs" "1b_0mf.i, 1b_0mf.b")
+(final_presence_set "1b_1mf_bs" "1b_1mf.i, 1b_1mf.b")
+(final_presence_set "1b_0b_bs" "1b_0b.bb")
+(final_presence_set "1b_1b_bs" "1b_1b.bb")
+(final_presence_set "1b_0bb_bs" "1b_0bb.b")
+(final_presence_set "1b_1bb_bs" "1b_1bb.b")
+(final_presence_set "1b_0mb_bs" "1b_0mb.b")
+(final_presence_set "1b_1mb_bs" "1b_1mb.b")
+
+(exclusion_set "1b_0m_bs"
+ "1b_0mi.i, 1b_0mm.i, 1b_0mm.f, 1b_0mf.i, 1b_0mb.b,\
+ 1b_0mi.b, 1b_0mf.b, 1b_0mm.b, 1b_0mlx., 1b_m0_stop")
+(exclusion_set "1b_1m_bs"
+ "1b_1mi.i, 1b_1mm.i, 1b_1mf.i, 1b_1mb.b, 1b_1mi.b, 1b_1mf.b, 1b_1mm.b,\
+ 1b_1mlx., 1b_m1_stop")
+(exclusion_set "1b_0mi_bs" "1b_0mii., 1b_0mib., 1b_mi0_stop")
+(exclusion_set "1b_1mi_bs" "1b_1mii., 1b_1mib., 1b_mi1_stop")
+(exclusion_set "1b_0mm_bs" "1b_0mmi., 1b_0mmf., 1b_0mmb.")
+(exclusion_set "1b_1mm_bs" "1b_1mmi., 1b_1mmb.")
+(exclusion_set "1b_0mf_bs" "1b_0mfi., 1b_0mfb.")
+(exclusion_set "1b_1mf_bs" "1b_1mfi., 1b_1mfb.")
+(exclusion_set "1b_0b_bs" "1b_0bb.b")
+(exclusion_set "1b_1b_bs" "1b_1bb.b")
+(exclusion_set "1b_0bb_bs" "1b_0bbb.")
+(exclusion_set "1b_1bb_bs" "1b_1bbb.")
+(exclusion_set "1b_0mb_bs" "1b_0mbb.")
+(exclusion_set "1b_1mb_bs" "1b_1mbb.")
+
+(exclusion_set
+ "1b_0m_bs, 1b_0mi_bs, 1b_0mm_bs, 1b_0mf_bs, 1b_0b_bs, 1b_0bb_bs, 1b_0mb_bs,
+ 1b_1m_bs, 1b_1mi_bs, 1b_1mm_bs, 1b_1mf_bs, 1b_1b_bs, 1b_1bb_bs, 1b_1mb_bs"
+ "1b_stop")
+
+(final_presence_set
+ "1b_0mi.i, 1b_0mm.i, 1b_0mf.i, 1b_0mm.f, 1b_0mb.b,\
+ 1b_0mi.b, 1b_0mm.b, 1b_0mf.b, 1b_0mlx."
+ "1b_m_cont")
+(final_presence_set "1b_0mii., 1b_0mib." "1b_mi_cont")
+(final_presence_set "1b_0mmi., 1b_0mmf., 1b_0mmb." "1b_mm_cont")
+(final_presence_set "1b_0mfi., 1b_0mfb." "1b_mf_cont")
+(final_presence_set "1b_0bb.b" "1b_b_cont")
+(final_presence_set "1b_0bbb." "1b_bb_cont")
+(final_presence_set "1b_0mbb." "1b_mb_cont")
+
+(exclusion_set
+ "1b_0m.ii, 1b_0m.mi, 1b_0m.fi, 1b_0m.mf, 1b_0b.bb, 1b_0m.bb,\
+ 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx"
+ "1b_m_cont, 1b_mi_cont, 1b_mm_cont, 1b_mf_cont,\
+ 1b_mb_cont, 1b_b_cont, 1b_bb_cont")
+
+(exclusion_set "1b_empty"
+ "1b_m_cont,1b_mi_cont,1b_mm_cont,1b_mf_cont,\
+ 1b_mb_cont,1b_b_cont,1b_bb_cont")
+
+;; For m;mi bundle
+(final_presence_set "1b_m0_stop" "1b_0m.mi")
+(final_presence_set "1b_0mm.i" "1b_0mmi_cont")
+(exclusion_set "1b_0mmi_cont"
+ "1b_0m.ii, 1b_0m.mi, 1b_0m.fi, 1b_0m.mf, 1b_0b.bb, 1b_0m.bb,\
+ 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_m0_stop" "1b_0mm.i")
+(final_presence_set "1b_m1_stop" "1b_1m.mi")
+(exclusion_set "1b_m1_stop" "1b_1mm.i")
+(final_presence_set "1b_m_stop" "1b_m0_stop, 1b_m1_stop")
+
+;; For mi;i bundle
+(final_presence_set "1b_mi0_stop" "1b_0mi.i")
+(final_presence_set "1b_0mii." "1b_0mii_cont")
+(exclusion_set "1b_0mii_cont"
+ "1b_0m.ii, 1b_0m.mi, 1b_0m.fi, 1b_0m.mf, 1b_0b.bb, 1b_0m.bb,\
+ 1b_0m.ib, 1b_0m.mb, 1b_0m.fb, 1b_0m.lx")
+(exclusion_set "1b_mi0_stop" "1b_0mii.")
+(final_presence_set "1b_mi1_stop" "1b_1mi.i")
+(exclusion_set "1b_mi1_stop" "1b_1mii.")
+(final_presence_set "1b_mi_stop" "1b_mi0_stop, 1b_mi1_stop")
+
+(final_absence_set
+ "1b_0m.ii,1b_0mi.i,1b_0mii.,1b_0m.mi,1b_0mm.i,1b_0mmi.,\
+ 1b_0m.fi,1b_0mf.i,1b_0mfi.,1b_0m.mf,1b_0mm.f,1b_0mmf.,\
+ 1b_0b.bb,1b_0bb.b,1b_0bbb.,1b_0m.bb,1b_0mb.b,1b_0mbb.,\
+ 1b_0m.ib,1b_0mi.b,1b_0mib.,1b_0m.mb,1b_0mm.b,1b_0mmb.,\
+ 1b_0m.fb,1b_0mf.b,1b_0mfb.,1b_0m.lx,1b_0mlx., \
+ 1b_1m.ii,1b_1mi.i,1b_1mii.,1b_1m.mi,1b_1mm.i,1b_1mmi.,\
+ 1b_1m.fi,1b_1mf.i,1b_1mfi.,\
+ 1b_1b.bb,1b_1bb.b,1b_1bbb.,1b_1m.bb,1b_1mb.b,1b_1mbb.,\
+ 1b_1m.ib,1b_1mi.b,1b_1mib.,1b_1m.mb,1b_1mm.b,1b_1mmb.,\
+ 1b_1m.fb,1b_1mf.b,1b_1mfb.,1b_1m.lx,1b_1mlx."
+ "1b_m0_stop,1b_m1_stop,1b_mi0_stop,1b_mi1_stop")
+
+(define_reservation "1b_A" "1b_M|1b_I")
+
+(define_insn_reservation "1b_stop_bit" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "stop_bit"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_stop|1b_m0_stop|1b_m1_stop|1b_mi0_stop|1b_mi1_stop")
+(define_insn_reservation "1b_br" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "br"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_B")
+(define_insn_reservation "1b_scall" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "scall"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_B")
+(define_insn_reservation "1b_fcmp" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fcmp"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_F+1b_not_uf1")
+(define_insn_reservation "1b_fcvtfx" 7
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fcvtfx"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_F")
+(define_insn_reservation "1b_fld" 9
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fld"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_fmac" 5
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fmac"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_F")
+(define_insn_reservation "1b_fmisc" 5
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "fmisc"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_F+1b_not_uf1")
+(define_insn_reservation "1b_frar_i" 13
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frar_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_frar_m" 6
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frar_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_M+1b_not_um1")
+(define_insn_reservation "1b_frbr" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frbr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_frfr" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frfr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_M+1b_not_um1")
+(define_insn_reservation "1b_frpr" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "frpr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_ialu" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ialu"))
+ (ne (symbol_ref
+ "bundling_p && !ia64_produce_address_p (insn)")
+ (const_int 0)))
+ "1b_A")
+(define_insn_reservation "1b_ialu_addr" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ialu"))
+ (eq (symbol_ref
+ "bundling_p && ia64_produce_address_p (insn)")
+ (const_int 1)))
+ "1b_M")
+(define_insn_reservation "1b_icmp" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "icmp"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_A")
+(define_insn_reservation "1b_ilog" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ilog"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_A")
+(define_insn_reservation "1b_ishf" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ishf"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_ld" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ld"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_long_i" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "long_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_L")
+(define_insn_reservation "1b_mmmul" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "mmmul"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_mmshf" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "mmshf"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_I")
+(define_insn_reservation "1b_mmshfi" 2
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "mmshfi"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_I")
+(define_insn_reservation "1b_rse_m" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "rse_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "(1b_0m.ii|1b_0m.mi|1b_0m.fi|1b_0m.mf|1b_0b.bb|1b_0m.bb\
+ |1b_0m.ib|1b_0m.mb|1b_0m.fb|1b_0m.lx)+1_1+1b_um0")
+(define_insn_reservation "1b_sem" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "sem"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_M+1b_not_um1")
+(define_insn_reservation "1b_stf" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "stf"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_st" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "st"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_syst_m0" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "syst_m0"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_M+1b_not_um1")
+(define_insn_reservation "1b_syst_m" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "syst_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_tbit" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "tbit"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_toar_i" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "toar_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_toar_m" 5
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "toar_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_M+1b_not_um1")
+(define_insn_reservation "1b_tobr" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "tobr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_tofr" 9
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "tofr"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_topr" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "topr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_I+1b_not_ui1")
+(define_insn_reservation "1b_xmpy" 7
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "xmpy"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_F")
+(define_insn_reservation "1b_xtd" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "xtd"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_I")
+(define_insn_reservation "1b_chk_s" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "chk_s"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_A")
+(define_insn_reservation "1b_lfetch" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "lfetch"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_nop_m" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_M")
+(define_insn_reservation "1b_nop_b" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_b"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_NB")
+(define_insn_reservation "1b_nop_i" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_I")
+(define_insn_reservation "1b_nop_f" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_f"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_F")
+(define_insn_reservation "1b_nop_x" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop_x"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "1b_L")
+(define_insn_reservation "1b_unknown" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "unknown"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_empty")
+(define_insn_reservation "1b_nop" 1
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "nop"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "1b_M|1b_NB|1b_I|1b_F")
+(define_insn_reservation "1b_ignore" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "ignore"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "nothing")
+
+(define_insn_reservation "1b_pre_cycle" 0
+ (and (and (eq_attr "cpu" "itanium")
+ (eq_attr "itanium_class" "pre_cycle"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "(1b_0m_bs, 1b_m_cont) \
+ | (1b_0mi_bs, 1b_mi_cont) \
+ | (1b_0mm_bs, 1b_mm_cont) \
+ | (1b_0mf_bs, 1b_mf_cont) \
+ | (1b_0b_bs, 1b_b_cont) \
+ | (1b_0bb_bs, 1b_bb_cont) \
+ | (1b_0mb_bs, 1b_mb_cont) \
+ | (1b_1m_bs, 1b_m_cont) \
+ | (1b_1mi_bs, 1b_mi_cont) \
+ | (1b_1mm_bs, 1b_mm_cont) \
+ | (1b_1mf_bs, 1b_mf_cont) \
+ | (1b_1b_bs, 1b_b_cont) \
+ | (1b_1bb_bs, 1b_bb_cont) \
+ | (1b_1mb_bs, 1b_mb_cont) \
+ | (1b_m_stop, 1b_0mmi_cont) \
+ | (1b_mi_stop, 1b_0mii_cont)")
+
diff --git a/contrib/gcc/config/ia64/itanium2.md b/contrib/gcc/config/ia64/itanium2.md
new file mode 100644
index 000000000000..0cdb07013467
--- /dev/null
+++ b/contrib/gcc/config/ia64/itanium2.md
@@ -0,0 +1,1762 @@
+;; Itanium2 DFA descriptions for insn scheduling and bundling.
+;; Copyright (C) 2002 Free Software Foundation, Inc.
+;; Contributed by Vladimir Makarov <vmakarov@redhat.com>.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA. */
+;;
+
+/* This is description of pipeline hazards based on DFA. The
+ following constructions can be used for this:
+
+ o define_cpu_unit string [string]) describes a cpu functional unit
+ (separated by comma).
+
+ 1st operand: Names of cpu function units.
+ 2nd operand: Name of automaton (see comments for
+ DEFINE_AUTOMATON).
+
+ All define_reservations and define_cpu_units should have unique
+ names which can not be "nothing".
+
+ o (exclusion_set string string) means that each CPU function unit
+ in the first string can not be reserved simultaneously with each
+ unit whose name is in the second string and vise versa. CPU
+ units in the string are separated by commas. For example, it is
+ useful for description CPU with fully pipelined floating point
+ functional unit which can execute simultaneously only single
+ floating point insns or only double floating point insns.
+
+ o (presence_set string string) means that each CPU function unit in
+ the first string can not be reserved unless at least one of
+ pattern of units whose names are in the second string is
+ reserved. This is an asymmetric relation. CPU units or unit
+ patterns in the strings are separated by commas. Pattern is one
+ unit name or unit names separated by white-spaces.
+
+ For example, it is useful for description that slot1 is reserved
+ after slot0 reservation for a VLIW processor. We could describe
+ it by the following construction
+
+ (presence_set "slot1" "slot0")
+
+ Or slot1 is reserved only after slot0 and unit b0 reservation.
+ In this case we could write
+
+ (presence_set "slot1" "slot0 b0")
+
+ All CPU functional units in a set should belong to the same
+ automaton.
+
+ o (final_presence_set string string) is analogous to
+ `presence_set'. The difference between them is when checking is
+ done. When an instruction is issued in given automaton state
+ reflecting all current and planned unit reservations, the
+ automaton state is changed. The first state is a source state,
+ the second one is a result state. Checking for `presence_set' is
+ done on the source state reservation, checking for
+ `final_presence_set' is done on the result reservation. This
+ construction is useful to describe a reservation which is
+ actually two subsequent reservations. For example, if we use
+
+ (presence_set "slot1" "slot0")
+
+ the following insn will be never issued (because slot1 requires
+ slot0 which is absent in the source state).
+
+ (define_reservation "insn_and_nop" "slot0 + slot1")
+
+ but it can be issued if we use analogous `final_presence_set'.
+
+ o (absence_set string string) means that each CPU function unit in
+ the first string can be reserved only if each pattern of units
+ whose names are in the second string is not reserved. This is an
+ asymmetric relation (actually exclusion set is analogous to this
+ one but it is symmetric). CPU units or unit patterns in the
+ string are separated by commas. Pattern is one unit name or unit
+ names separated by white-spaces.
+
+ For example, it is useful for description that slot0 can not be
+ reserved after slot1 or slot2 reservation for a VLIW processor.
+ We could describe it by the following construction
+
+ (absence_set "slot2" "slot0, slot1")
+
+ Or slot2 can not be reserved if slot0 and unit b0 are reserved or
+ slot1 and unit b1 are reserved . In this case we could write
+
+ (absence_set "slot2" "slot0 b0, slot1 b1")
+
+ All CPU functional units in a set should to belong the same
+ automaton.
+
+ o (final_absence_set string string) is analogous to `absence_set' but
+ checking is done on the result (state) reservation. See comments
+ for final_presence_set.
+
+ o (define_bypass number out_insn_names in_insn_names) names bypass with
+ given latency (the first number) from insns given by the first
+ string (see define_insn_reservation) into insns given by the
+ second string. Insn names in the strings are separated by
+ commas.
+
+ o (define_automaton string) describes names of an automaton
+ generated and used for pipeline hazards recognition. The names
+ are separated by comma. Actually it is possibly to generate the
+ single automaton but unfortunately it can be very large. If we
+ use more one automata, the summary size of the automata usually
+ is less than the single one. The automaton name is used in
+ define_cpu_unit. All automata should have unique names.
+
+ o (automata_option string) describes option for generation of
+ automata. Currently there are the following options:
+
+ o "no-minimization" which makes no minimization of automata.
+ This is only worth to do when we are debugging the description
+ and need to look more accurately at reservations of states.
+
+ o "ndfa" which makes automata with nondetermenistic reservation
+ by insns.
+
+ o (define_reservation string string) names reservation (the first
+ string) of cpu functional units (the 2nd string). Sometimes unit
+ reservations for different insns contain common parts. In such
+ case, you describe common part and use one its name (the 1st
+ parameter) in regular expression in define_insn_reservation. All
+ define_reservations, define results and define_cpu_units should
+ have unique names which can not be "nothing".
+
+ o (define_insn_reservation name default_latency condition regexpr)
+ describes reservation of cpu functional units (the 3nd operand)
+ for instruction which is selected by the condition (the 2nd
+ parameter). The first parameter is used for output of debugging
+ information. The reservations are described by a regular
+ expression according the following syntax:
+
+ regexp = regexp "," oneof
+ | oneof
+
+ oneof = oneof "|" allof
+ | allof
+
+ allof = allof "+" repeat
+ | repeat
+
+ repeat = element "*" number
+ | element
+
+ element = cpu_function_name
+ | reservation_name
+ | result_name
+ | "nothing"
+ | "(" regexp ")"
+
+ 1. "," is used for describing start of the next cycle in
+ reservation.
+
+ 2. "|" is used for describing the reservation described by the
+ first regular expression *or* the reservation described by
+ the second regular expression *or* etc.
+
+ 3. "+" is used for describing the reservation described by the
+ first regular expression *and* the reservation described by
+ the second regular expression *and* etc.
+
+ 4. "*" is used for convenience and simply means sequence in
+ which the regular expression are repeated NUMBER times with
+ cycle advancing (see ",").
+
+ 5. cpu function unit name which means reservation.
+
+ 6. reservation name -- see define_reservation.
+
+ 7. string "nothing" means no units reservation.
+
+*/
+
+(define_automaton "two")
+
+;; All possible combinations of bundles/syllables
+(define_cpu_unit "2_0m.ii, 2_0m.mi, 2_0m.fi, 2_0m.mf, 2_0b.bb, 2_0m.bb,\
+ 2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx" "two")
+(define_cpu_unit "2_0mi.i, 2_0mm.i, 2_0mf.i, 2_0mm.f, 2_0bb.b, 2_0mb.b,\
+ 2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx." "two")
+(define_cpu_unit "2_0mii., 2_0mmi., 2_0mfi., 2_0mmf., 2_0bbb., 2_0mbb.,\
+ 2_0mib., 2_0mmb., 2_0mfb." "two")
+
+(define_cpu_unit "2_1m.ii, 2_1m.mi, 2_1m.fi, 2_1m.mf, 2_1b.bb, 2_1m.bb,\
+ 2_1m.ib, 2_1m.mb, 2_1m.fb, 2_1m.lx" "two")
+(define_cpu_unit "2_1mi.i, 2_1mm.i, 2_1mf.i, 2_1mm.f, 2_1bb.b, 2_1mb.b,\
+ 2_1mi.b, 2_1mm.b, 2_1mf.b, 2_1mlx." "two")
+(define_cpu_unit "2_1mii., 2_1mmi., 2_1mfi., 2_1mmf., 2_1bbb., 2_1mbb.,\
+ 2_1mib., 2_1mmb., 2_1mfb." "two")
+
+;; Slot 1
+(exclusion_set "2_0m.ii" "2_0m.mi, 2_0m.fi, 2_0m.mf, 2_0b.bb, 2_0m.bb,\
+ 2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.mi" "2_0m.fi, 2_0m.mf, 2_0b.bb, 2_0m.bb, 2_0m.ib,\
+ 2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.fi" "2_0m.mf, 2_0b.bb, 2_0m.bb, 2_0m.ib, 2_0m.mb,\
+ 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.mf" "2_0b.bb, 2_0m.bb, 2_0m.ib, 2_0m.mb, 2_0m.fb,\
+ 2_0m.lx")
+(exclusion_set "2_0b.bb" "2_0m.bb, 2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.bb" "2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.ib" "2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.mb" "2_0m.fb, 2_0m.lx")
+(exclusion_set "2_0m.fb" "2_0m.lx")
+
+;; Slot 2
+(exclusion_set "2_0mi.i" "2_0mm.i, 2_0mf.i, 2_0mm.f, 2_0bb.b, 2_0mb.b,\
+ 2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mm.i" "2_0mf.i, 2_0mm.f, 2_0bb.b, 2_0mb.b,\
+ 2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mf.i" "2_0mm.f, 2_0bb.b, 2_0mb.b, 2_0mi.b, 2_0mm.b,\
+ 2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mm.f" "2_0bb.b, 2_0mb.b, 2_0mi.b, 2_0mm.b, 2_0mf.b,\
+ 2_0mlx.")
+(exclusion_set "2_0bb.b" "2_0mb.b, 2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mb.b" "2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mi.b" "2_0mm.b, 2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mm.b" "2_0mf.b, 2_0mlx.")
+(exclusion_set "2_0mf.b" "2_0mlx.")
+
+;; Slot 3
+(exclusion_set "2_0mii." "2_0mmi., 2_0mfi., 2_0mmf., 2_0bbb., 2_0mbb.,\
+ 2_0mib., 2_0mmb., 2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mmi." "2_0mfi., 2_0mmf., 2_0bbb., 2_0mbb.,\
+ 2_0mib., 2_0mmb., 2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mfi." "2_0mmf., 2_0bbb., 2_0mbb., 2_0mib., 2_0mmb.,\
+ 2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mmf." "2_0bbb., 2_0mbb., 2_0mib., 2_0mmb., 2_0mfb.,\
+ 2_0mlx.")
+(exclusion_set "2_0bbb." "2_0mbb., 2_0mib., 2_0mmb., 2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mbb." "2_0mib., 2_0mmb., 2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mib." "2_0mmb., 2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mmb." "2_0mfb., 2_0mlx.")
+(exclusion_set "2_0mfb." "2_0mlx.")
+
+;; Slot 4
+(exclusion_set "2_1m.ii" "2_1m.mi, 2_1m.fi, 2_1m.mf, 2_1b.bb, 2_1m.bb,\
+ 2_1m.ib, 2_1m.mb, 2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.mi" "2_1m.fi, 2_1m.mf, 2_1b.bb, 2_1m.bb, 2_1m.ib,\
+ 2_1m.mb, 2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.fi" "2_1m.mf, 2_1b.bb, 2_1m.bb, 2_1m.ib, 2_1m.mb,\
+ 2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.mf" "2_1b.bb, 2_1m.bb, 2_1m.ib, 2_1m.mb, 2_1m.fb,\
+ 2_1m.lx")
+(exclusion_set "2_1b.bb" "2_1m.bb, 2_1m.ib, 2_1m.mb, 2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.bb" "2_1m.ib, 2_1m.mb, 2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.ib" "2_1m.mb, 2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.mb" "2_1m.fb, 2_1m.lx")
+(exclusion_set "2_1m.fb" "2_1m.lx")
+
+;; Slot 5
+(exclusion_set "2_1mi.i" "2_1mm.i, 2_1mf.i, 2_1mm.f, 2_1bb.b, 2_1mb.b,\
+ 2_1mi.b, 2_1mm.b, 2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mm.i" "2_1mf.i, 2_1mm.f, 2_1bb.b, 2_1mb.b,\
+ 2_1mi.b, 2_1mm.b, 2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mf.i" "2_1mm.f, 2_1bb.b, 2_1mb.b, 2_1mi.b, 2_1mm.b,\
+ 2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mm.f" "2_1bb.b, 2_1mb.b, 2_1mi.b, 2_1mm.b, 2_1mf.b,\
+ 2_1mlx.")
+(exclusion_set "2_1bb.b" "2_1mb.b, 2_1mi.b, 2_1mm.b, 2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mb.b" "2_1mi.b, 2_1mm.b, 2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mi.b" "2_1mm.b, 2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mm.b" "2_1mf.b, 2_1mlx.")
+(exclusion_set "2_1mf.b" "2_1mlx.")
+
+;; Slot 6
+(exclusion_set "2_1mii." "2_1mmi., 2_1mfi., 2_1mmf., 2_1bbb., 2_1mbb.,\
+ 2_1mib., 2_1mmb., 2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mmi." "2_1mfi., 2_1mmf., 2_1bbb., 2_1mbb.,\
+ 2_1mib., 2_1mmb., 2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mfi." "2_1mmf., 2_1bbb., 2_1mbb., 2_1mib., 2_1mmb.,\
+ 2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mmf." "2_1bbb., 2_1mbb., 2_1mib., 2_1mmb., 2_1mfb.,\
+ 2_1mlx.")
+(exclusion_set "2_1bbb." "2_1mbb., 2_1mib., 2_1mmb., 2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mbb." "2_1mib., 2_1mmb., 2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mib." "2_1mmb., 2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mmb." "2_1mfb., 2_1mlx.")
+(exclusion_set "2_1mfb." "2_1mlx.")
+
+(final_presence_set "2_0mi.i" "2_0m.ii")
+(final_presence_set "2_0mii." "2_0mi.i")
+(final_presence_set "2_1mi.i" "2_1m.ii")
+(final_presence_set "2_1mii." "2_1mi.i")
+
+(final_presence_set "2_0mm.i" "2_0m.mi")
+(final_presence_set "2_0mmi." "2_0mm.i")
+(final_presence_set "2_1mm.i" "2_1m.mi")
+(final_presence_set "2_1mmi." "2_1mm.i")
+
+(final_presence_set "2_0mf.i" "2_0m.fi")
+(final_presence_set "2_0mfi." "2_0mf.i")
+(final_presence_set "2_1mf.i" "2_1m.fi")
+(final_presence_set "2_1mfi." "2_1mf.i")
+
+(final_presence_set "2_0mm.f" "2_0m.mf")
+(final_presence_set "2_0mmf." "2_0mm.f")
+(final_presence_set "2_1mm.f" "2_1m.mf")
+(final_presence_set "2_1mmf." "2_1mm.f")
+
+(final_presence_set "2_0bb.b" "2_0b.bb")
+(final_presence_set "2_0bbb." "2_0bb.b")
+(final_presence_set "2_1bb.b" "2_1b.bb")
+(final_presence_set "2_1bbb." "2_1bb.b")
+
+(final_presence_set "2_0mb.b" "2_0m.bb")
+(final_presence_set "2_0mbb." "2_0mb.b")
+(final_presence_set "2_1mb.b" "2_1m.bb")
+(final_presence_set "2_1mbb." "2_1mb.b")
+
+(final_presence_set "2_0mi.b" "2_0m.ib")
+(final_presence_set "2_0mib." "2_0mi.b")
+(final_presence_set "2_1mi.b" "2_1m.ib")
+(final_presence_set "2_1mib." "2_1mi.b")
+
+(final_presence_set "2_0mm.b" "2_0m.mb")
+(final_presence_set "2_0mmb." "2_0mm.b")
+(final_presence_set "2_1mm.b" "2_1m.mb")
+(final_presence_set "2_1mmb." "2_1mm.b")
+
+(final_presence_set "2_0mf.b" "2_0m.fb")
+(final_presence_set "2_0mfb." "2_0mf.b")
+(final_presence_set "2_1mf.b" "2_1m.fb")
+(final_presence_set "2_1mfb." "2_1mf.b")
+
+(final_presence_set "2_0mlx." "2_0m.lx")
+(final_presence_set "2_1mlx." "2_1m.lx")
+
+;; The following reflects the dual issue bundle types table.
+;; We could place all possible combinations here because impossible
+;; combinations would go away by the subsequent constrains.
+(final_presence_set
+ "2_1m.lx"
+ "2_0mmi.,2_0mfi.,2_0mmf.,2_0mib.,2_0mmb.,2_0mfb.,2_0mlx.")
+(final_presence_set "2_1b.bb" "2_0mii.,2_0mmi.,2_0mfi.,2_0mmf.,2_0mlx.")
+(final_presence_set
+ "2_1m.ii,2_1m.mi,2_1m.fi,2_1m.mf,2_1m.bb,2_1m.ib,2_1m.mb,2_1m.fb"
+ "2_0mii.,2_0mmi.,2_0mfi.,2_0mmf.,2_0mib.,2_0mmb.,2_0mfb.,2_0mlx.")
+
+;; Ports/units (nb means nop.b insn issued into given port):
+(define_cpu_unit
+ "2_um0, 2_um1, 2_um2, 2_um3, 2_ui0, 2_ui1, 2_uf0, 2_uf1,\
+ 2_ub0, 2_ub1, 2_ub2, 2_unb0, 2_unb1, 2_unb2" "two")
+
+(exclusion_set "2_ub0" "2_unb0")
+(exclusion_set "2_ub1" "2_unb1")
+(exclusion_set "2_ub2" "2_unb2")
+
+;; The following rules are used to decrease number of alternatives.
+;; They are consequences of Itanium2 microarchitecture. They also
+;; describe the following rules mentioned in Itanium2
+;; microarchitecture: rules mentioned in Itanium2 microarchitecture:
+;; o "BBB/MBB: Always splits issue after either of these bundles".
+;; o "MIB BBB: Split issue after the first bundle in this pair".
+(exclusion_set
+ "2_0b.bb,2_0bb.b,2_0bbb.,2_0m.bb,2_0mb.b,2_0mbb."
+ "2_1m.ii,2_1m.mi,2_1m.fi,2_1m.mf,2_1b.bb,2_1m.bb,\
+ 2_1m.ib,2_1m.mb,2_1m.fb,2_1m.lx")
+(exclusion_set "2_0m.ib,2_0mi.b,2_0mib." "2_1b.bb")
+
+;;; "MIB/MFB/MMB: Splits issue after any of these bundles unless the
+;;; B-slot contains a nop.b or a brp instruction".
+;;; "The B in an MIB/MFB/MMB bundle disperses to B0 if it is a brp or
+;;; nop.b, otherwise it disperses to B2".
+(final_absence_set
+ "2_1m.ii, 2_1m.mi, 2_1m.fi, 2_1m.mf, 2_1b.bb, 2_1m.bb,\
+ 2_1m.ib, 2_1m.mb, 2_1m.fb, 2_1m.lx"
+ "2_0mib. 2_ub2, 2_0mfb. 2_ub2, 2_0mmb. 2_ub2")
+
+;; This is necessary to start new processor cycle when we meet stop bit.
+(define_cpu_unit "2_stop" "two")
+(final_absence_set
+ "2_0m.ii,2_0mi.i,2_0mii.,2_0m.mi,2_0mm.i,2_0mmi.,2_0m.fi,2_0mf.i,2_0mfi.,\
+ 2_0m.mf,2_0mm.f,2_0mmf.,2_0b.bb,2_0bb.b,2_0bbb.,2_0m.bb,2_0mb.b,2_0mbb.,\
+ 2_0m.ib,2_0mi.b,2_0mib.,2_0m.mb,2_0mm.b,2_0mmb.,2_0m.fb,2_0mf.b,2_0mfb.,\
+ 2_0m.lx,2_0mlx., \
+ 2_1m.ii,2_1mi.i,2_1mii.,2_1m.mi,2_1mm.i,2_1mmi.,2_1m.fi,2_1mf.i,2_1mfi.,\
+ 2_1m.mf,2_1mm.f,2_1mmf.,2_1b.bb,2_1bb.b,2_1bbb.,2_1m.bb,2_1mb.b,2_1mbb.,\
+ 2_1m.ib,2_1mi.b,2_1mib.,2_1m.mb,2_1mm.b,2_1mmb.,2_1m.fb,2_1mf.b,2_1mfb.,\
+ 2_1m.lx,2_1mlx."
+ "2_stop")
+
+;; The issue logic can reorder M slot insns between different subtypes
+;; but can not reorder insn within the same subtypes. The following
+;; constraint is enough to describe this.
+(final_presence_set "2_um1" "2_um0")
+(final_presence_set "2_um3" "2_um2")
+
+;; The insn in the 1st I slot of the two bundle issue group will issue
+;; to I0. The second I slot insn will issue to I1.
+(final_presence_set "2_ui1" "2_ui0")
+
+;; For exceptions of I insns:
+(define_cpu_unit "2_only_ui0" "two")
+(final_absence_set "2_only_ui0" "2_ui1")
+
+;; Insns
+
+(define_reservation "2_M0"
+ "(2_0m.ii|2_0m.mi|2_0m.fi|2_0m.mf|2_0m.bb|2_0m.ib|2_0m.mb|2_0m.fb|2_0m.lx\
+ |2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx\
+ |2_0mm.i|2_0mm.f|2_0mm.b|2_1mm.i|2_1mm.f|2_1mm.b)\
+ +(2_um0|2_um1|2_um2|2_um3)")
+
+(define_reservation "2_M1"
+ "(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0\
+ |2_0mib.+2_unb0|2_0mfb.+2_unb0|2_0mmb.+2_unb0)\
+ +(2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx)\
+ +(2_um0|2_um1|2_um2|2_um3)")
+
+(define_reservation "2_M" "2_M0|2_M1")
+
+(define_reservation "2_M0_only_um0"
+ "(2_0m.ii|2_0m.mi|2_0m.fi|2_0m.mf|2_0m.bb|2_0m.ib|2_0m.mb|2_0m.fb|2_0m.lx\
+ |2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx\
+ |2_0mm.i|2_0mm.f|2_0mm.b|2_1mm.i|2_1mm.f|2_1mm.b)\
+ +2_um0")
+
+(define_reservation "2_M1_only_um0"
+ "(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0\
+ |2_0mib.+2_unb0|2_0mfb.+2_unb0|2_0mmb.+2_unb0)\
+ +(2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx)\
+ +2_um0")
+
+(define_reservation "2_M_only_um0" "2_M0_only_um0|2_M1_only_um0")
+
+(define_reservation "2_M0_only_um2"
+ "(2_0m.ii|2_0m.mi|2_0m.fi|2_0m.mf|2_0m.bb|2_0m.ib|2_0m.mb|2_0m.fb|2_0m.lx\
+ |2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx\
+ |2_0mm.i|2_0mm.f|2_0mm.b|2_1mm.i|2_1mm.f|2_1mm.b)\
+ +2_um2")
+
+(define_reservation "2_M1_only_um2"
+ "(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0\
+ |2_0mib.+2_unb0|2_0mfb.+2_unb0|2_0mmb.+2_unb0)\
+ +(2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx)\
+ +2_um2")
+
+(define_reservation "2_M_only_um2" "2_M0_only_um2|2_M1_only_um2")
+
+(define_reservation "2_M0_only_um23"
+ "(2_0m.ii|2_0m.mi|2_0m.fi|2_0m.mf|2_0m.bb|2_0m.ib|2_0m.mb|2_0m.fb|2_0m.lx\
+ |2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx\
+ |2_0mm.i|2_0mm.f|2_0mm.b|2_1mm.i|2_1mm.f|2_1mm.b)\
+ +(2_um2|2_um3)")
+
+(define_reservation "2_M1_only_um23"
+ "(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0\
+ |2_0mib.+2_unb0|2_0mfb.+2_unb0|2_0mmb.+2_unb0)\
+ +(2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx)\
+ +(2_um2|2_um3)")
+
+(define_reservation "2_M_only_um23" "2_M0_only_um23|2_M1_only_um23")
+
+(define_reservation "2_M0_only_um01"
+ "(2_0m.ii|2_0m.mi|2_0m.fi|2_0m.mf|2_0m.bb|2_0m.ib|2_0m.mb|2_0m.fb|2_0m.lx\
+ |2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx\
+ |2_0mm.i|2_0mm.f|2_0mm.b|2_1mm.i|2_1mm.f|2_1mm.b)\
+ +(2_um0|2_um1)")
+
+(define_reservation "2_M1_only_um01"
+ "(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0\
+ |2_0mib.+2_unb0|2_0mfb.+2_unb0|2_0mmb.+2_unb0)\
+ +(2_1m.ii|2_1m.mi|2_1m.fi|2_1m.mf|2_1m.bb|2_1m.ib|2_1m.mb|2_1m.fb|2_1m.lx)\
+ +(2_um0|2_um1)")
+
+(define_reservation "2_M_only_um01" "2_M0_only_um01|2_M1_only_um01")
+
+;; I instruction is dispersed to the lowest numbered I unit
+;; not already in use. Remeber about possible splitting.
+(define_reservation "2_I0"
+ "2_0mi.i+2_ui0|2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0\
+ |2_0mfi.+2_ui0|2_0mi.b+2_ui0|(2_1mi.i|2_1mi.b)+(2_ui0|2_ui1)\
+ |(2_1mii.|2_1mmi.|2_1mfi.)+(2_ui0|2_ui1)")
+
+(define_reservation "2_I1"
+ "2_0m.ii+(2_um0|2_um1|2_um2|2_um3)+2_0mi.i+2_ui0\
+ |2_0mm.i+(2_um0|2_um1|2_um2|2_um3)+2_0mmi.+2_ui0\
+ |2_0mf.i+2_uf0+2_0mfi.+2_ui0\
+ |2_0m.ib+(2_um0|2_um1|2_um2|2_um3)+2_0mi.b+2_ui0\
+ |(2_1m.ii+2_1mi.i|2_1m.ib+2_1mi.b)+(2_um0|2_um1|2_um2|2_um3)+(2_ui0|2_ui1)\
+ |2_1mm.i+(2_um0|2_um1|2_um2|2_um3)+2_1mmi.+(2_ui0|2_ui1)\
+ |2_1mf.i+2_uf1+2_1mfi.+(2_ui0|2_ui1)")
+
+(define_reservation "2_I" "2_I0|2_I1")
+
+;; "An F slot in the 1st bundle disperses to F0".
+;; "An F slot in the 2st bundle disperses to F1".
+(define_reservation "2_F0"
+ "2_0mf.i+2_uf0|2_0mmf.+2_uf0|2_0mf.b+2_uf0\
+ |2_1mf.i+2_uf1|2_1mmf.+2_uf1|2_1mf.b+2_uf1")
+
+(define_reservation "2_F1"
+ "(2_0m.fi+2_0mf.i|2_0mm.f+2_0mmf.|2_0m.fb+2_0mf.b)\
+ +(2_um0|2_um1|2_um2|2_um3)+2_uf0\
+ |(2_1m.fi+2_1mf.i|2_1mm.f+2_1mmf.|2_1m.fb+2_1mf.b)\
+ +(2_um0|2_um1|2_um2|2_um3)+2_uf1")
+
+(define_reservation "2_F2"
+ "(2_0m.mf+2_0mm.f+2_0mmf.+2_uf0|2_1m.mf+2_1mm.f+2_1mmf.+2_uf1)\
+ +(2_um0|2_um1|2_um2|2_um3)+(2_um0|2_um1|2_um2|2_um3)\
+ |(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0\
+ |2_0mmf.+(2_um0|2_um1|2_um2|2_um3)\
+ |2_0mib.+2_unb0|2_0mmb.+2_unb0|2_0mfb.+2_unb0)\
+ +(2_1m.fi+2_1mf.i|2_1m.fb+2_1mf.b)+(2_um0|2_um1|2_um2|2_um3)+2_uf1")
+
+(define_reservation "2_F" "2_F0|2_F1|2_F2")
+
+;;; "Each B slot in MBB or BBB bundle disperses to the corresponding B
+;;; unit. That is, a B slot in 1st position is dispersed to B0. In the
+;;; 2nd position it is dispersed to B2".
+(define_reservation "2_NB"
+ "2_0b.bb+2_unb0|2_0bb.b+2_unb1|2_0bbb.+2_unb2\
+ |2_0mb.b+2_unb1|2_0mbb.+2_unb2|2_0mib.+2_unb0\
+ |2_0mmb.+2_unb0|2_0mfb.+2_unb0\
+ |2_1b.bb+2_unb0|2_1bb.b+2_unb1
+ |2_1bbb.+2_unb2|2_1mb.b+2_unb1|2_1mbb.+2_unb2\
+ |2_1mib.+2_unb0|2_1mmb.+2_unb0|2_1mfb.+2_unb0")
+
+(define_reservation "2_B0"
+ "2_0b.bb+2_ub0|2_0bb.b+2_ub1|2_0bbb.+2_ub2\
+ |2_0mb.b+2_ub1|2_0mbb.+2_ub2|2_0mib.+2_ub2\
+ |2_0mfb.+2_ub2|2_1b.bb+2_ub0|2_1bb.b+2_ub1\
+ |2_1bbb.+2_ub2|2_1mb.b+2_ub1\
+ |2_1mib.+2_ub2|2_1mmb.+2_ub2|2_1mfb.+2_ub2")
+
+(define_reservation "2_B1"
+ "2_0m.bb+(2_um0|2_um1|2_um2|2_um3)+2_0mb.b+2_ub1\
+ |2_0mi.b+2_ui0+2_0mib.+2_ub2\
+ |2_0mm.b+(2_um0|2_um1|2_um2|2_um3)+2_0mmb.+2_ub2\
+ |2_0mf.b+2_uf0+2_0mfb.+2_ub2\
+ |(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0)\
+ +2_1b.bb+2_ub0\
+ |2_1m.bb+(2_um0|2_um1|2_um2|2_um3)+2_1mb.b+2_ub1\
+ |2_1mi.b+(2_ui0|2_ui1)+2_1mib.+2_ub2\
+ |2_1mm.b+(2_um0|2_um1|2_um2|2_um3)+2_1mmb.+2_ub2\
+ |2_1mf.b+2_uf1+2_1mfb.+2_ub2")
+
+(define_reservation "2_B" "2_B0|2_B1")
+
+;; MLX bunlde uses ports equivalent to MFI bundles.
+
+;; For the MLI template, the I slot insn is always assigned to port I0
+;; if it is in the first bundle or it is assigned to port I1 if it is in
+;; the second bundle.
+(define_reservation "2_L0" "2_0mlx.+2_ui0+2_uf0|2_1mlx.+2_ui1+2_uf1")
+
+(define_reservation "2_L1"
+ "2_0m.lx+(2_um0|2_um1|2_um2|2_um3)+2_0mlx.+2_ui0+2_uf0\
+ |2_1m.lx+(2_um0|2_um1|2_um2|2_um3)+2_1mlx.+2_ui1+2_uf1")
+
+(define_reservation "2_L2"
+ "(2_0mii.+(2_ui0|2_ui1)|2_0mmi.+2_ui0|2_0mfi.+2_ui0|2_0mmf.+2_uf0\
+ |2_0mib.+2_unb0|2_0mmb.+2_unb0|2_0mfb.+2_unb0)
+ +2_1m.lx+(2_um0|2_um1|2_um2|2_um3)+2_1mlx.+2_ui1+2_uf1")
+
+(define_reservation "2_L" "2_L0|2_L1|2_L2")
+
+;; Should we describe that A insn in I slot can be issued into M
+;; ports? I think it is not necessary because of multipass
+;; scheduling. For example, the multipass scheduling could use
+;; MMI-MMI instead of MII-MII where the two last I slots contain A
+;; insns (even if the case is complicated by use-def conflicts).
+;;
+;; In any case we could describe it as
+;; (define_cpu_unit "2_ui1_0pres,2_ui1_1pres,2_ui1_2pres,2_ui1_3pres" "two")
+;; (final_presence_set "2_ui1_0pres,2_ui1_1pres,2_ui1_2pres,2_ui1_3pres"
+;; "2_ui1")
+;; (define_reservation "b_A"
+;; "b_M|b_I\
+;; |(2_1mi.i|2_1mii.|2_1mmi.|2_1mfi.|2_1mi.b)+(2_um0|2_um1|2_um2|2_um3)\
+;; +(2_ui1_0pres|2_ui1_1pres|2_ui1_2pres|2_ui1_3pres)")
+
+(define_reservation "2_A" "2_M|2_I")
+
+;; We assume that there is no insn issued on the same cycle as the
+;; unknown insn.
+(define_cpu_unit "2_empty" "two")
+(exclusion_set "2_empty"
+ "2_0m.ii,2_0m.mi,2_0m.fi,2_0m.mf,2_0b.bb,2_0m.bb,2_0m.ib,2_0m.mb,2_0m.fb,\
+ 2_0m.lx")
+
+(define_cpu_unit
+ "2_0m_bs, 2_0mi_bs, 2_0mm_bs, 2_0mf_bs, 2_0b_bs, 2_0bb_bs, 2_0mb_bs"
+ "two")
+(define_cpu_unit
+ "2_1m_bs, 2_1mi_bs, 2_1mm_bs, 2_1mf_bs, 2_1b_bs, 2_1bb_bs, 2_1mb_bs"
+ "two")
+
+(define_cpu_unit "2_m_cont, 2_mi_cont, 2_mm_cont, 2_mf_cont, 2_mb_cont,\
+ 2_b_cont, 2_bb_cont" "two")
+
+;; For stop in the middle of the bundles.
+(define_cpu_unit "2_m_stop, 2_m0_stop, 2_m1_stop, 2_0mmi_cont" "two")
+(define_cpu_unit "2_mi_stop, 2_mi0_stop, 2_mi1_stop, 2_0mii_cont" "two")
+
+(final_presence_set "2_0m_bs"
+ "2_0m.ii, 2_0m.mi, 2_0m.mf, 2_0m.fi, 2_0m.bb,\
+ 2_0m.ib, 2_0m.fb, 2_0m.mb, 2_0m.lx")
+(final_presence_set "2_1m_bs"
+ "2_1m.ii, 2_1m.mi, 2_1m.mf, 2_1m.fi, 2_1m.bb,\
+ 2_1m.ib, 2_1m.fb, 2_1m.mb, 2_1m.lx")
+(final_presence_set "2_0mi_bs" "2_0mi.i, 2_0mi.i")
+(final_presence_set "2_1mi_bs" "2_1mi.i, 2_1mi.i")
+(final_presence_set "2_0mm_bs" "2_0mm.i, 2_0mm.f, 2_0mm.b")
+(final_presence_set "2_1mm_bs" "2_1mm.i, 2_1mm.f, 2_1mm.b")
+(final_presence_set "2_0mf_bs" "2_0mf.i, 2_0mf.b")
+(final_presence_set "2_1mf_bs" "2_1mf.i, 2_1mf.b")
+(final_presence_set "2_0b_bs" "2_0b.bb")
+(final_presence_set "2_1b_bs" "2_1b.bb")
+(final_presence_set "2_0bb_bs" "2_0bb.b")
+(final_presence_set "2_1bb_bs" "2_1bb.b")
+(final_presence_set "2_0mb_bs" "2_0mb.b")
+(final_presence_set "2_1mb_bs" "2_1mb.b")
+
+(exclusion_set "2_0m_bs"
+ "2_0mi.i, 2_0mm.i, 2_0mm.f, 2_0mf.i, 2_0mb.b,\
+ 2_0mi.b, 2_0mf.b, 2_0mm.b, 2_0mlx., 2_m0_stop")
+(exclusion_set "2_1m_bs"
+ "2_1mi.i, 2_1mm.i, 2_1mm.f, 2_1mf.i, 2_1mb.b,\
+ 2_1mi.b, 2_1mf.b, 2_1mm.b, 2_1mlx., 2_m1_stop")
+(exclusion_set "2_0mi_bs" "2_0mii., 2_0mib., 2_mi0_stop")
+(exclusion_set "2_1mi_bs" "2_1mii., 2_1mib., 2_mi1_stop")
+(exclusion_set "2_0mm_bs" "2_0mmi., 2_0mmf., 2_0mmb.")
+(exclusion_set "2_1mm_bs" "2_1mmi., 2_1mmf., 2_1mmb.")
+(exclusion_set "2_0mf_bs" "2_0mfi., 2_0mfb.")
+(exclusion_set "2_1mf_bs" "2_1mfi., 2_1mfb.")
+(exclusion_set "2_0b_bs" "2_0bb.b")
+(exclusion_set "2_1b_bs" "2_1bb.b")
+(exclusion_set "2_0bb_bs" "2_0bbb.")
+(exclusion_set "2_1bb_bs" "2_1bbb.")
+(exclusion_set "2_0mb_bs" "2_0mbb.")
+(exclusion_set "2_1mb_bs" "2_1mbb.")
+
+(exclusion_set
+ "2_0m_bs, 2_0mi_bs, 2_0mm_bs, 2_0mf_bs, 2_0b_bs, 2_0bb_bs, 2_0mb_bs,
+ 2_1m_bs, 2_1mi_bs, 2_1mm_bs, 2_1mf_bs, 2_1b_bs, 2_1bb_bs, 2_1mb_bs"
+ "2_stop")
+
+(final_presence_set
+ "2_0mi.i, 2_0mm.i, 2_0mf.i, 2_0mm.f, 2_0mb.b,\
+ 2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx."
+ "2_m_cont")
+(final_presence_set "2_0mii., 2_0mib." "2_mi_cont")
+(final_presence_set "2_0mmi., 2_0mmf., 2_0mmb." "2_mm_cont")
+(final_presence_set "2_0mfi., 2_0mfb." "2_mf_cont")
+(final_presence_set "2_0bb.b" "2_b_cont")
+(final_presence_set "2_0bbb." "2_bb_cont")
+(final_presence_set "2_0mbb." "2_mb_cont")
+
+(exclusion_set
+ "2_0m.ii, 2_0m.mi, 2_0m.fi, 2_0m.mf, 2_0b.bb, 2_0m.bb,\
+ 2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx"
+ "2_m_cont, 2_mi_cont, 2_mm_cont, 2_mf_cont,\
+ 2_mb_cont, 2_b_cont, 2_bb_cont")
+
+(exclusion_set "2_empty"
+ "2_m_cont,2_mi_cont,2_mm_cont,2_mf_cont,\
+ 2_mb_cont,2_b_cont,2_bb_cont")
+
+;; For m;mi bundle
+(final_presence_set "2_m0_stop" "2_0m.mi")
+(final_presence_set "2_0mm.i" "2_0mmi_cont")
+(exclusion_set "2_0mmi_cont"
+ "2_0m.ii, 2_0m.mi, 2_0m.fi, 2_0m.mf, 2_0b.bb, 2_0m.bb,\
+ 2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_m0_stop" "2_0mm.i")
+(final_presence_set "2_m1_stop" "2_1m.mi")
+(exclusion_set "2_m1_stop" "2_1mm.i")
+(final_presence_set "2_m_stop" "2_m0_stop, 2_m1_stop")
+
+;; For mi;i bundle
+(final_presence_set "2_mi0_stop" "2_0mi.i")
+(final_presence_set "2_0mii." "2_0mii_cont")
+(exclusion_set "2_0mii_cont"
+ "2_0m.ii, 2_0m.mi, 2_0m.fi, 2_0m.mf, 2_0b.bb, 2_0m.bb,\
+ 2_0m.ib, 2_0m.mb, 2_0m.fb, 2_0m.lx")
+(exclusion_set "2_mi0_stop" "2_0mii.")
+(final_presence_set "2_mi1_stop" "2_1mi.i")
+(exclusion_set "2_mi1_stop" "2_1mii.")
+(final_presence_set "2_mi_stop" "2_mi0_stop, 2_mi1_stop")
+
+(final_absence_set
+ "2_0m.ii,2_0mi.i,2_0mii.,2_0m.mi,2_0mm.i,2_0mmi.,2_0m.fi,2_0mf.i,2_0mfi.,\
+ 2_0m.mf,2_0mm.f,2_0mmf.,2_0b.bb,2_0bb.b,2_0bbb.,2_0m.bb,2_0mb.b,2_0mbb.,\
+ 2_0m.ib,2_0mi.b,2_0mib.,2_0m.mb,2_0mm.b,2_0mmb.,2_0m.fb,2_0mf.b,2_0mfb.,\
+ 2_0m.lx,2_0mlx., \
+ 2_1m.ii,2_1mi.i,2_1mii.,2_1m.mi,2_1mm.i,2_1mmi.,2_1m.fi,2_1mf.i,2_1mfi.,\
+ 2_1m.mf,2_1mm.f,2_1mmf.,2_1b.bb,2_1bb.b,2_1bbb.,2_1m.bb,2_1mb.b,2_1mbb.,\
+ 2_1m.ib,2_1mi.b,2_1mib.,2_1m.mb,2_1mm.b,2_1mmb.,2_1m.fb,2_1mf.b,2_1mfb.,\
+ 2_1m.lx,2_1mlx."
+ "2_m0_stop,2_m1_stop,2_mi0_stop,2_mi1_stop")
+
+(define_insn_reservation "2_stop_bit" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "stop_bit"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_stop|2_m0_stop|2_m1_stop|2_mi0_stop|2_mi1_stop")
+
+(define_insn_reservation "2_br" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "br"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_B")
+(define_insn_reservation "2_scall" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "scall"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_B")
+(define_insn_reservation "2_fcmp" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fcmp"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_F")
+(define_insn_reservation "2_fcvtfx" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fcvtfx"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_F")
+(define_insn_reservation "2_fld" 6
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fld"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_M")
+(define_insn_reservation "2_fmac" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fmac"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_F")
+(define_insn_reservation "2_fmisc" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fmisc"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_F")
+
+;; There is only one insn `mov = ar.bsp' for frar_i:
+;; Latency time ???
+(define_insn_reservation "2_frar_i" 13
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frar_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+;; There is only two insns `mov = ar.unat' or `mov = ar.ccv' for frar_m:
+;; Latency time ???
+(define_insn_reservation "2_frar_m" 6
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frar_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um2")
+(define_insn_reservation "2_frbr" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frbr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+(define_insn_reservation "2_frfr" 5
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frfr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um2")
+(define_insn_reservation "2_frpr" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frpr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+
+(define_insn_reservation "2_ialu" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ialu"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_A")
+(define_insn_reservation "2_icmp" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "icmp"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_A")
+(define_insn_reservation "2_ilog" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ilog"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_A")
+;; Latency time ???
+(define_insn_reservation "2_ishf" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ishf"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+(define_insn_reservation "2_ld" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ld"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um01")
+(define_insn_reservation "2_long_i" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "long_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_L")
+
+(define_insn_reservation "2_mmmul" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "mmmul"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+;; Latency time ???
+(define_insn_reservation "2_mmshf" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "mmshf"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_I")
+;; Latency time ???
+(define_insn_reservation "2_mmshfi" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "mmshfi"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_I")
+
+;; Now we have only one insn (flushrs) of such class. We assume that flushrs
+;; is the 1st syllable of the bundle after stop bit.
+(define_insn_reservation "2_rse_m" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "rse_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "(2_0m.ii|2_0m.mi|2_0m.fi|2_0m.mf|2_0m.bb\
+ |2_0m.ib|2_0m.mb|2_0m.fb|2_0m.lx)+2_um0")
+(define_insn_reservation "2_sem" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "sem"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um23")
+
+(define_insn_reservation "2_stf" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "stf"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um23")
+(define_insn_reservation "2_st" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "st"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um23")
+(define_insn_reservation "2_syst_m0" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "syst_m0"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um2")
+(define_insn_reservation "2_syst_m" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "syst_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um0")
+;; Reservation???
+(define_insn_reservation "2_tbit" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "tbit"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+
+;; There is only ony insn `mov ar.pfs =' for toar_i:
+(define_insn_reservation "2_toar_i" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "toar_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+;; There are only ony 2 insns `mov ar.ccv =' and `mov ar.unat =' for toar_m:
+;; Latency time ???
+(define_insn_reservation "2_toar_m" 5
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "toar_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um2")
+;; Latency time ???
+(define_insn_reservation "2_tobr" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "tobr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+(define_insn_reservation "2_tofr" 5
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "tofr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um23")
+;; Latency time ???
+(define_insn_reservation "2_topr" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "topr"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I+2_only_ui0")
+
+(define_insn_reservation "2_xmpy" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "xmpy"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_F")
+;; Latency time ???
+(define_insn_reservation "2_xtd" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "xtd"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_I")
+
+(define_insn_reservation "2_chk_s" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "chk_s"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_I|2_M_only_um23")
+(define_insn_reservation "2_lfetch" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "lfetch"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M_only_um01")
+
+(define_insn_reservation "2_nop_m" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_m"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_M0")
+(define_insn_reservation "2_nop_b" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_b"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_NB")
+(define_insn_reservation "2_nop_i" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_i"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_I0")
+(define_insn_reservation "2_nop_f" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_f"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_F0")
+(define_insn_reservation "2_nop_x" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_x"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_L0")
+
+(define_insn_reservation "2_unknown" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "unknown"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "2_empty")
+
+(define_insn_reservation "2_nop" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "2_M0|2_NB|2_I0|2_F0")
+
+(define_insn_reservation "2_ignore" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ignore"))
+ (eq (symbol_ref "bundling_p") (const_int 0))) "nothing")
+
+(define_cpu_unit "2_m_cont_only, 2_b_cont_only" "two")
+(define_cpu_unit "2_mi_cont_only, 2_mm_cont_only, 2_mf_cont_only" "two")
+(define_cpu_unit "2_mb_cont_only, 2_bb_cont_only" "two")
+
+(final_presence_set "2_m_cont_only" "2_m_cont")
+(exclusion_set "2_m_cont_only"
+ "2_0mi.i, 2_0mm.i, 2_0mf.i, 2_0mm.f, 2_0mb.b,\
+ 2_0mi.b, 2_0mm.b, 2_0mf.b, 2_0mlx.")
+
+(final_presence_set "2_b_cont_only" "2_b_cont")
+(exclusion_set "2_b_cont_only" "2_0bb.b")
+
+(final_presence_set "2_mi_cont_only" "2_mi_cont")
+(exclusion_set "2_mi_cont_only" "2_0mii., 2_0mib.")
+
+(final_presence_set "2_mm_cont_only" "2_mm_cont")
+(exclusion_set "2_mm_cont_only" "2_0mmi., 2_0mmf., 2_0mmb.")
+
+(final_presence_set "2_mf_cont_only" "2_mf_cont")
+(exclusion_set "2_mf_cont_only" "2_0mfi., 2_0mfb.")
+
+(final_presence_set "2_mb_cont_only" "2_mb_cont")
+(exclusion_set "2_mb_cont_only" "2_0mbb.")
+
+(final_presence_set "2_bb_cont_only" "2_bb_cont")
+(exclusion_set "2_bb_cont_only" "2_0bbb.")
+
+(define_insn_reservation "2_pre_cycle" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "pre_cycle"))
+ (eq (symbol_ref "bundling_p") (const_int 0)))
+ "nothing")
+
+;;(define_insn_reservation "2_pre_cycle" 0
+;; (and (and (eq_attr "cpu" "itanium2")
+;; (eq_attr "itanium_class" "pre_cycle"))
+;; (eq (symbol_ref "bundling_p") (const_int 0)))
+;; "(2_0m_bs, 2_m_cont) \
+;; | (2_0mi_bs, (2_mi_cont|nothing)) \
+;; | (2_0mm_bs, 2_mm_cont) \
+;; | (2_0mf_bs, (2_mf_cont|nothing)) \
+;; | (2_0b_bs, (2_b_cont|nothing)) \
+;; | (2_0bb_bs, (2_bb_cont|nothing)) \
+;; | (2_0mb_bs, (2_mb_cont|nothing)) \
+;; | (2_1m_bs, 2_m_cont) \
+;; | (2_1mi_bs, (2_mi_cont|nothing)) \
+;; | (2_1mm_bs, 2_mm_cont) \
+;; | (2_1mf_bs, (2_mf_cont|nothing)) \
+;; | (2_1b_bs, (2_b_cont|nothing)) \
+;; | (2_1bb_bs, (2_bb_cont|nothing)) \
+;; | (2_1mb_bs, (2_mb_cont|nothing)) \
+;; | (2_m_cont_only, (2_m_cont|nothing)) \
+;; | (2_b_cont_only, (2_b_cont|nothing)) \
+;; | (2_mi_cont_only, (2_mi_cont|nothing)) \
+;; | (2_mm_cont_only, (2_mm_cont|nothing)) \
+;; | (2_mf_cont_only, (2_mf_cont|nothing)) \
+;; | (2_mb_cont_only, (2_mb_cont|nothing)) \
+;; | (2_bb_cont_only, (2_bb_cont|nothing)) \
+;; | (2_m_stop, (2_0mmi_cont|nothing)) \
+;; | (2_mi_stop, (2_0mii_cont|nothing))")
+
+;; Bypasses:
+
+(define_bypass 1 "2_fcmp" "2_br,2_scall")
+(define_bypass 0 "2_icmp" "2_br,2_scall")
+(define_bypass 0 "2_tbit" "2_br,2_scall")
+(define_bypass 2 "2_ld" "2_ld" "ia64_ld_address_bypass_p")
+(define_bypass 2 "2_ld" "2_st" "ia64_st_address_bypass_p")
+(define_bypass 2 "2_ld" "2_mmmul,2_mmshf")
+(define_bypass 3 "2_ilog" "2_mmmul,2_mmshf")
+(define_bypass 3 "2_ialu" "2_mmmul,2_mmshf")
+(define_bypass 3 "2_mmmul,2_mmshf" "2_ialu,2_ilog,2_ishf,2_st,2_ld")
+(define_bypass 6 "2_tofr" "2_frfr,2_stf")
+(define_bypass 7 "2_fmac" "2_frfr,2_stf")
+
+;; We don't use here fcmp because scall may be predicated.
+(define_bypass 0 "2_fcvtfx,2_fld,2_fmac,2_fmisc,2_frar_i,2_frar_m,\
+ 2_frbr,2_frfr,2_frpr,2_ialu,2_ilog,2_ishf,2_ld,2_long_i,\
+ 2_mmmul,2_mmshf,2_mmshfi,2_toar_m,2_tofr,2_xmpy,2_xtd"
+ "2_scall")
+
+(define_bypass 0 "2_unknown,2_ignore,2_stop_bit,2_br,2_fcmp,2_fcvtfx,2_fld,\
+ 2_fmac,2_fmisc,2_frar_i,2_frar_m,2_frbr,2_frfr,2_frpr,\
+ 2_ialu,2_icmp,2_ilog,2_ishf,2_ld,2_chk_s,\
+ 2_long_i,2_mmmul,2_mmshf,2_mmshfi,2_nop,2_nop_b,2_nop_f,\
+ 2_nop_i,2_nop_m,2_nop_x,2_rse_m,2_scall,2_sem,2_stf,2_st,\
+ 2_syst_m0,2_syst_m,2_tbit,2_toar_i,2_toar_m,2_tobr,2_tofr,\
+ 2_topr,2_xmpy,2_xtd,2_lfetch" "2_ignore")
+
+
+
+;; Bundling
+
+(define_automaton "twob")
+
+;; Pseudo units for quicker searching for position in two packet window. */
+(define_query_cpu_unit "2_1,2_2,2_3,2_4,2_5,2_6" "twob")
+
+;; All possible combinations of bundles/syllables
+(define_cpu_unit
+ "2b_0m.ii, 2b_0m.mi, 2b_0m.fi, 2b_0m.mf, 2b_0b.bb, 2b_0m.bb,\
+ 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx" "twob")
+(define_cpu_unit
+ "2b_0mi.i, 2b_0mm.i, 2b_0mf.i, 2b_0mm.f, 2b_0bb.b, 2b_0mb.b,\
+ 2b_0mi.b, 2b_0mm.b, 2b_0mf.b" "twob")
+(define_query_cpu_unit
+ "2b_0mii., 2b_0mmi., 2b_0mfi., 2b_0mmf., 2b_0bbb., 2b_0mbb.,\
+ 2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx." "twob")
+
+(define_cpu_unit
+ "2b_1m.ii, 2b_1m.mi, 2b_1m.fi, 2b_1m.mf, 2b_1b.bb, 2b_1m.bb,\
+ 2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx" "twob")
+(define_cpu_unit
+ "2b_1mi.i, 2b_1mm.i, 2b_1mf.i, 2b_1mm.f, 2b_1bb.b, 2b_1mb.b,\
+ 2b_1mi.b, 2b_1mm.b, 2b_1mf.b" "twob")
+(define_query_cpu_unit
+ "2b_1mii., 2b_1mmi., 2b_1mfi., 2b_1mmf., 2b_1bbb., 2b_1mbb.,\
+ 2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx." "twob")
+
+;; Slot 1
+(exclusion_set "2b_0m.ii"
+ "2b_0m.mi, 2b_0m.fi, 2b_0m.mf, 2b_0b.bb, 2b_0m.bb,\
+ 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.mi"
+ "2b_0m.fi, 2b_0m.mf, 2b_0b.bb, 2b_0m.bb, 2b_0m.ib,\
+ 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.fi"
+ "2b_0m.mf, 2b_0b.bb, 2b_0m.bb, 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.mf"
+ "2b_0b.bb, 2b_0m.bb, 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0b.bb" "2b_0m.bb, 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.bb" "2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.ib" "2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.mb" "2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_0m.fb" "2b_0m.lx")
+
+;; Slot 2
+(exclusion_set "2b_0mi.i"
+ "2b_0mm.i, 2b_0mf.i, 2b_0mm.f, 2b_0bb.b, 2b_0mb.b,\
+ 2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mm.i"
+ "2b_0mf.i, 2b_0mm.f, 2b_0bb.b, 2b_0mb.b,\
+ 2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mf.i"
+ "2b_0mm.f, 2b_0bb.b, 2b_0mb.b, 2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mm.f"
+ "2b_0bb.b, 2b_0mb.b, 2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0bb.b" "2b_0mb.b, 2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mb.b" "2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mi.b" "2b_0mm.b, 2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mm.b" "2b_0mf.b, 2b_0mlx.")
+(exclusion_set "2b_0mf.b" "2b_0mlx.")
+
+;; Slot 3
+(exclusion_set "2b_0mii."
+ "2b_0mmi., 2b_0mfi., 2b_0mmf., 2b_0bbb., 2b_0mbb.,\
+ 2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mmi."
+ "2b_0mfi., 2b_0mmf., 2b_0bbb., 2b_0mbb.,\
+ 2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mfi."
+ "2b_0mmf., 2b_0bbb., 2b_0mbb., 2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mmf."
+ "2b_0bbb., 2b_0mbb., 2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0bbb." "2b_0mbb., 2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mbb." "2b_0mib., 2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mib." "2b_0mmb., 2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mmb." "2b_0mfb., 2b_0mlx.")
+(exclusion_set "2b_0mfb." "2b_0mlx.")
+
+;; Slot 4
+(exclusion_set "2b_1m.ii"
+ "2b_1m.mi, 2b_1m.fi, 2b_1m.mf, 2b_1b.bb, 2b_1m.bb,\
+ 2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.mi"
+ "2b_1m.fi, 2b_1m.mf, 2b_1b.bb, 2b_1m.bb, 2b_1m.ib,\
+ 2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.fi"
+ "2b_1m.mf, 2b_1b.bb, 2b_1m.bb, 2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.mf"
+ "2b_1b.bb, 2b_1m.bb, 2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1b.bb" "2b_1m.bb, 2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.bb" "2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.ib" "2b_1m.mb, 2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.mb" "2b_1m.fb, 2b_1m.lx")
+(exclusion_set "2b_1m.fb" "2b_1m.lx")
+
+;; Slot 5
+(exclusion_set "2b_1mi.i"
+ "2b_1mm.i, 2b_1mf.i, 2b_1mm.f, 2b_1bb.b, 2b_1mb.b,\
+ 2b_1mi.b, 2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mm.i"
+ "2b_1mf.i, 2b_1mm.f, 2b_1bb.b, 2b_1mb.b,\
+ 2b_1mi.b, 2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mf.i"
+ "2b_1mm.f, 2b_1bb.b, 2b_1mb.b, 2b_1mi.b, 2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mm.f"
+ "2b_1bb.b, 2b_1mb.b, 2b_1mi.b, 2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1bb.b" "2b_1mb.b, 2b_1mi.b, 2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mb.b" "2b_1mi.b, 2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mi.b" "2b_1mm.b, 2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mm.b" "2b_1mf.b, 2b_1mlx.")
+(exclusion_set "2b_1mf.b" "2b_1mlx.")
+
+;; Slot 6
+(exclusion_set "2b_1mii."
+ "2b_1mmi., 2b_1mfi., 2b_1mmf., 2b_1bbb., 2b_1mbb.,\
+ 2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mmi."
+ "2b_1mfi., 2b_1mmf., 2b_1bbb., 2b_1mbb.,\
+ 2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mfi."
+ "2b_1mmf., 2b_1bbb., 2b_1mbb., 2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mmf."
+ "2b_1bbb., 2b_1mbb., 2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1bbb." "2b_1mbb., 2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mbb." "2b_1mib., 2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mib." "2b_1mmb., 2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mmb." "2b_1mfb., 2b_1mlx.")
+(exclusion_set "2b_1mfb." "2b_1mlx.")
+
+(final_presence_set "2b_0mi.i" "2b_0m.ii")
+(final_presence_set "2b_0mii." "2b_0mi.i")
+(final_presence_set "2b_1mi.i" "2b_1m.ii")
+(final_presence_set "2b_1mii." "2b_1mi.i")
+
+(final_presence_set "2b_0mm.i" "2b_0m.mi")
+(final_presence_set "2b_0mmi." "2b_0mm.i")
+(final_presence_set "2b_1mm.i" "2b_1m.mi")
+(final_presence_set "2b_1mmi." "2b_1mm.i")
+
+(final_presence_set "2b_0mf.i" "2b_0m.fi")
+(final_presence_set "2b_0mfi." "2b_0mf.i")
+(final_presence_set "2b_1mf.i" "2b_1m.fi")
+(final_presence_set "2b_1mfi." "2b_1mf.i")
+
+(final_presence_set "2b_0mm.f" "2b_0m.mf")
+(final_presence_set "2b_0mmf." "2b_0mm.f")
+(final_presence_set "2b_1mm.f" "2b_1m.mf")
+(final_presence_set "2b_1mmf." "2b_1mm.f")
+
+(final_presence_set "2b_0bb.b" "2b_0b.bb")
+(final_presence_set "2b_0bbb." "2b_0bb.b")
+(final_presence_set "2b_1bb.b" "2b_1b.bb")
+(final_presence_set "2b_1bbb." "2b_1bb.b")
+
+(final_presence_set "2b_0mb.b" "2b_0m.bb")
+(final_presence_set "2b_0mbb." "2b_0mb.b")
+(final_presence_set "2b_1mb.b" "2b_1m.bb")
+(final_presence_set "2b_1mbb." "2b_1mb.b")
+
+(final_presence_set "2b_0mi.b" "2b_0m.ib")
+(final_presence_set "2b_0mib." "2b_0mi.b")
+(final_presence_set "2b_1mi.b" "2b_1m.ib")
+(final_presence_set "2b_1mib." "2b_1mi.b")
+
+(final_presence_set "2b_0mm.b" "2b_0m.mb")
+(final_presence_set "2b_0mmb." "2b_0mm.b")
+(final_presence_set "2b_1mm.b" "2b_1m.mb")
+(final_presence_set "2b_1mmb." "2b_1mm.b")
+
+(final_presence_set "2b_0mf.b" "2b_0m.fb")
+(final_presence_set "2b_0mfb." "2b_0mf.b")
+(final_presence_set "2b_1mf.b" "2b_1m.fb")
+(final_presence_set "2b_1mfb." "2b_1mf.b")
+
+(final_presence_set "2b_0mlx." "2b_0m.lx")
+(final_presence_set "2b_1mlx." "2b_1m.lx")
+
+;; See the corresponding comment in non-bundling section above.
+(final_presence_set
+ "2b_1m.lx"
+ "2b_0mmi.,2b_0mfi.,2b_0mmf.,2b_0mib.,2b_0mmb.,2b_0mfb.,2b_0mlx.")
+(final_presence_set "2b_1b.bb" "2b_0mii.,2b_0mmi.,2b_0mfi.,2b_0mmf.,2b_0mlx.")
+(final_presence_set
+ "2b_1m.ii,2b_1m.mi,2b_1m.fi,2b_1m.mf,2b_1m.bb,2b_1m.ib,2b_1m.mb,2b_1m.fb"
+ "2b_0mii.,2b_0mmi.,2b_0mfi.,2b_0mmf.,2b_0mib.,2b_0mmb.,2b_0mfb.,2b_0mlx.")
+
+;; Ports/units (nb means nop.b insn issued into given port):
+(define_cpu_unit
+ "2b_um0, 2b_um1, 2b_um2, 2b_um3, 2b_ui0, 2b_ui1, 2b_uf0, 2b_uf1,\
+ 2b_ub0, 2b_ub1, 2b_ub2, 2b_unb0, 2b_unb1, 2b_unb2" "twob")
+
+(exclusion_set "2b_ub0" "2b_unb0")
+(exclusion_set "2b_ub1" "2b_unb1")
+(exclusion_set "2b_ub2" "2b_unb2")
+
+;; The following rules are used to decrease number of alternatives.
+;; They are consequences of Itanium2 microarchitecture. They also
+;; describe the following rules mentioned in Itanium2
+;; microarchitecture: rules mentioned in Itanium2 microarchitecture:
+;; o "BBB/MBB: Always splits issue after either of these bundles".
+;; o "MIB BBB: Split issue after the first bundle in this pair".
+(exclusion_set
+ "2b_0b.bb,2b_0bb.b,2b_0bbb.,2b_0m.bb,2b_0mb.b,2b_0mbb."
+ "2b_1m.ii,2b_1m.mi,2b_1m.fi,2b_1m.mf,2b_1b.bb,2b_1m.bb,\
+ 2b_1m.ib,2b_1m.mb,2b_1m.fb,2b_1m.lx")
+(exclusion_set "2b_0m.ib,2b_0mi.b,2b_0mib." "2b_1b.bb")
+
+;;; "MIB/MFB/MMB: Splits issue after any of these bundles unless the
+;;; B-slot contains a nop.b or a brp instruction".
+;;; "The B in an MIB/MFB/MMB bundle disperses to B0 if it is a brp or
+;;; nop.b, otherwise it disperses to B2".
+(final_absence_set
+ "2b_1m.ii, 2b_1m.mi, 2b_1m.fi, 2b_1m.mf, 2b_1b.bb, 2b_1m.bb,\
+ 2b_1m.ib, 2b_1m.mb, 2b_1m.fb, 2b_1m.lx"
+ "2b_0mib. 2b_ub2, 2b_0mfb. 2b_ub2, 2b_0mmb. 2b_ub2")
+
+;; This is necessary to start new processor cycle when we meet stop bit.
+(define_cpu_unit "2b_stop" "twob")
+(final_absence_set
+ "2b_0m.ii,2b_0mi.i,2b_0mii.,2b_0m.mi,2b_0mm.i,2b_0mmi.,\
+ 2b_0m.fi,2b_0mf.i,2b_0mfi.,\
+ 2b_0m.mf,2b_0mm.f,2b_0mmf.,2b_0b.bb,2b_0bb.b,2b_0bbb.,\
+ 2b_0m.bb,2b_0mb.b,2b_0mbb.,\
+ 2b_0m.ib,2b_0mi.b,2b_0mib.,2b_0m.mb,2b_0mm.b,2b_0mmb.,\
+ 2b_0m.fb,2b_0mf.b,2b_0mfb.,2b_0m.lx,2b_0mlx., \
+ 2b_1m.ii,2b_1mi.i,2b_1mii.,2b_1m.mi,2b_1mm.i,2b_1mmi.,\
+ 2b_1m.fi,2b_1mf.i,2b_1mfi.,\
+ 2b_1m.mf,2b_1mm.f,2b_1mmf.,2b_1b.bb,2b_1bb.b,2b_1bbb.,\
+ 2b_1m.bb,2b_1mb.b,2b_1mbb.,\
+ 2b_1m.ib,2b_1mi.b,2b_1mib.,2b_1m.mb,2b_1mm.b,2b_1mmb.,\
+ 2b_1m.fb,2b_1mf.b,2b_1mfb.,2b_1m.lx,2b_1mlx."
+ "2b_stop")
+
+;; The issue logic can reorder M slot insns between different subtypes
+;; but can not reorder insn within the same subtypes. The following
+;; constraint is enough to describe this.
+(final_presence_set "2b_um1" "2b_um0")
+(final_presence_set "2b_um3" "2b_um2")
+
+;; The insn in the 1st I slot of the two bundle issue group will issue
+;; to I0. The second I slot insn will issue to I1.
+(final_presence_set "2b_ui1" "2b_ui0")
+
+;; For exceptions of I insns:
+(define_cpu_unit "2b_only_ui0" "twob")
+(final_absence_set "2b_only_ui0" "2b_ui1")
+
+;; Insns
+
+(define_reservation "2b_M"
+ "((2b_0m.ii|2b_0m.mi|2b_0m.fi|2b_0m.mf|2b_0m.bb\
+ |2b_0m.ib|2b_0m.mb|2b_0m.fb|2b_0m.lx)+2_1\
+ |(2b_1m.ii|2b_1m.mi|2b_1m.fi|2b_1m.mf|2b_1m.bb\
+ |2b_1m.ib|2b_1m.mb|2b_1m.fb|2b_1m.lx)+2_4\
+ |(2b_0mm.i|2b_0mm.f|2b_0mm.b)+2_2\
+ |(2b_1mm.i|2b_1mm.f|2b_1mm.b)+2_5)\
+ +(2b_um0|2b_um1|2b_um2|2b_um3)")
+
+(define_reservation "2b_M_only_um0"
+ "((2b_0m.ii|2b_0m.mi|2b_0m.fi|2b_0m.mf|2b_0m.bb\
+ |2b_0m.ib|2b_0m.mb|2b_0m.fb|2b_0m.lx)+2_1\
+ |(2b_1m.ii|2b_1m.mi|2b_1m.fi|2b_1m.mf|2b_1m.bb\
+ |2b_1m.ib|2b_1m.mb|2b_1m.fb|2b_1m.lx)+2_4\
+ |(2b_0mm.i|2b_0mm.f|2b_0mm.b)+2_2\
+ |(2b_1mm.i|2b_1mm.f|2b_1mm.b)+2_5)\
+ +2b_um0")
+
+(define_reservation "2b_M_only_um2"
+ "((2b_0m.ii|2b_0m.mi|2b_0m.fi|2b_0m.mf|2b_0m.bb\
+ |2b_0m.ib|2b_0m.mb|2b_0m.fb|2b_0m.lx)+2_1\
+ |(2b_1m.ii|2b_1m.mi|2b_1m.fi|2b_1m.mf|2b_1m.bb\
+ |2b_1m.ib|2b_1m.mb|2b_1m.fb|2b_1m.lx)+2_4\
+ |(2b_0mm.i|2b_0mm.f|2b_0mm.b)+2_2\
+ |(2b_1mm.i|2b_1mm.f|2b_1mm.b)+2_5)\
+ +2b_um2")
+
+(define_reservation "2b_M_only_um01"
+ "((2b_0m.ii|2b_0m.mi|2b_0m.fi|2b_0m.mf|2b_0m.bb\
+ |2b_0m.ib|2b_0m.mb|2b_0m.fb|2b_0m.lx)+2_1\
+ |(2b_1m.ii|2b_1m.mi|2b_1m.fi|2b_1m.mf|2b_1m.bb\
+ |2b_1m.ib|2b_1m.mb|2b_1m.fb|2b_1m.lx)+2_4\
+ |(2b_0mm.i|2b_0mm.f|2b_0mm.b)+2_2\
+ |(2b_1mm.i|2b_1mm.f|2b_1mm.b)+2_5)\
+ +(2b_um0|2b_um1)")
+
+(define_reservation "2b_M_only_um23"
+ "((2b_0m.ii|2b_0m.mi|2b_0m.fi|2b_0m.mf|2b_0m.bb\
+ |2b_0m.ib|2b_0m.mb|2b_0m.fb|2b_0m.lx)+2_1\
+ |(2b_1m.ii|2b_1m.mi|2b_1m.fi|2b_1m.mf|2b_1m.bb\
+ |2b_1m.ib|2b_1m.mb|2b_1m.fb|2b_1m.lx)+2_4\
+ |(2b_0mm.i|2b_0mm.f|2b_0mm.b)+2_2\
+ |(2b_1mm.i|2b_1mm.f|2b_1mm.b)+2_5)\
+ +(2b_um2|2b_um3)")
+
+;; I instruction is dispersed to the lowest numbered I unit
+;; not already in use. Remeber about possible splitting.
+(define_reservation "2b_I"
+ "2b_0mi.i+2_2+2b_ui0|2b_0mii.+2_3+(2b_ui0|2b_ui1)|2b_0mmi.+2_3+2b_ui0\
+ |2b_0mfi.+2_3+2b_ui0|2b_0mi.b+2_2+2b_ui0\
+ |(2b_1mi.i+2_5|2b_1mi.b+2_5)+(2b_ui0|2b_ui1)\
+ |(2b_1mii.|2b_1mmi.|2b_1mfi.)+2_6+(2b_ui0|2b_ui1)")
+
+;; "An F slot in the 1st bundle disperses to F0".
+;; "An F slot in the 2st bundle disperses to F1".
+(define_reservation "2b_F"
+ "2b_0mf.i+2_2+2b_uf0|2b_0mmf.+2_3+2b_uf0|2b_0mf.b+2_2+2b_uf0\
+ |2b_1mf.i+2_5+2b_uf1|2b_1mmf.+2_6+2b_uf1|2b_1mf.b+2_5+2b_uf1")
+
+;;; "Each B slot in MBB or BBB bundle disperses to the corresponding B
+;;; unit. That is, a B slot in 1st position is dispersed to B0. In the
+;;; 2nd position it is dispersed to B2".
+(define_reservation "2b_NB"
+ "2b_0b.bb+2_1+2b_unb0|2b_0bb.b+2_2+2b_unb1|2b_0bbb.+2_3+2b_unb2\
+ |2b_0mb.b+2_2+2b_unb1|2b_0mbb.+2_3+2b_unb2\
+ |2b_0mib.+2_3+2b_unb0|2b_0mmb.+2_3+2b_unb0|2b_0mfb.+2_3+2b_unb0\
+ |2b_1b.bb+2_4+2b_unb0|2b_1bb.b+2_5+2b_unb1\
+ |2b_1bbb.+2_6+2b_unb2|2b_1mb.b+2_5+2b_unb1|2b_1mbb.+2_6+2b_unb2\
+ |2b_1mib.+2_6+2b_unb0|2b_1mmb.+2_6+2b_unb0|2b_1mfb.+2_6+2b_unb0")
+
+(define_reservation "2b_B"
+ "2b_0b.bb+2_1+2b_ub0|2b_0bb.b+2_2+2b_ub1|2b_0bbb.+2_3+2b_ub2\
+ |2b_0mb.b+2_2+2b_ub1|2b_0mbb.+2_3+2b_ub2|2b_0mib.+2_3+2b_ub2\
+ |2b_0mfb.+2_3+2b_ub2|2b_1b.bb+2_4+2b_ub0|2b_1bb.b+2_5+2b_ub1\
+ |2b_1bbb.+2_6+2b_ub2|2b_1mb.b+2_5+2b_ub1\
+ |2b_1mib.+2_6+2b_ub2|2b_1mmb.+2_6+2b_ub2|2b_1mfb.+2_6+2b_ub2")
+
+;; For the MLI template, the I slot insn is always assigned to port I0
+;; if it is in the first bundle or it is assigned to port I1 if it is in
+;; the second bundle.
+(define_reservation "2b_L"
+ "2b_0mlx.+2_3+2b_ui0+2b_uf0|2b_1mlx.+2_6+2b_ui1+2b_uf1")
+
+;; Should we describe that A insn in I slot can be issued into M
+;; ports? I think it is not necessary because of multipass
+;; scheduling. For example, the multipass scheduling could use
+;; MMI-MMI instead of MII-MII where the two last I slots contain A
+;; insns (even if the case is complicated by use-def conflicts).
+;;
+;; In any case we could describe it as
+;; (define_cpu_unit "2b_ui1_0pres,2b_ui1_1pres,2b_ui1_2pres,2b_ui1_3pres"
+;; "twob")
+;; (final_presence_set "2b_ui1_0pres,2b_ui1_1pres,2b_ui1_2pres,2b_ui1_3pres"
+;; "2b_ui1")
+;; (define_reservation "b_A"
+;; "b_M|b_I\
+;; |(2b_1mi.i+2_5|2b_1mii.+2_6|2b_1mmi.+2_6|2b_1mfi.+2_6|2b_1mi.b+2_5)\
+;; +(2b_um0|2b_um1|2b_um2|2b_um3)\
+;; +(2b_ui1_0pres|2b_ui1_1pres|2b_ui1_2pres|2b_ui1_3pres)")
+
+(define_reservation "2b_A" "2b_M|2b_I")
+
+;; We assume that there is no insn issued on the same cycle as the
+;; unknown insn.
+(define_cpu_unit "2b_empty" "twob")
+(exclusion_set "2b_empty"
+ "2b_0m.ii,2b_0m.mi,2b_0m.fi,2b_0m.mf,2b_0b.bb,2b_0m.bb,\
+ 2b_0m.ib,2b_0m.mb,2b_0m.fb,2b_0m.lx,2b_0mm.i")
+
+(define_cpu_unit
+ "2b_0m_bs, 2b_0mi_bs, 2b_0mm_bs, 2b_0mf_bs, 2b_0b_bs, 2b_0bb_bs, 2b_0mb_bs"
+ "twob")
+(define_cpu_unit
+ "2b_1m_bs, 2b_1mi_bs, 2b_1mm_bs, 2b_1mf_bs, 2b_1b_bs, 2b_1bb_bs, 2b_1mb_bs"
+ "twob")
+
+(define_cpu_unit "2b_m_cont, 2b_mi_cont, 2b_mm_cont, 2b_mf_cont, 2b_mb_cont,\
+ 2b_b_cont, 2b_bb_cont" "twob")
+
+;; For stop in the middle of the bundles.
+(define_cpu_unit "2b_m_stop, 2b_m0_stop, 2b_m1_stop, 2b_0mmi_cont" "twob")
+(define_cpu_unit "2b_mi_stop, 2b_mi0_stop, 2b_mi1_stop, 2b_0mii_cont" "twob")
+
+(final_presence_set "2b_0m_bs"
+ "2b_0m.ii, 2b_0m.mi, 2b_0m.mf, 2b_0m.fi, 2b_0m.bb,\
+ 2b_0m.ib, 2b_0m.fb, 2b_0m.mb, 2b_0m.lx")
+(final_presence_set "2b_1m_bs"
+ "2b_1m.ii, 2b_1m.mi, 2b_1m.mf, 2b_1m.fi, 2b_1m.bb,\
+ 2b_1m.ib, 2b_1m.fb, 2b_1m.mb, 2b_1m.lx")
+(final_presence_set "2b_0mi_bs" "2b_0mi.i, 2b_0mi.i")
+(final_presence_set "2b_1mi_bs" "2b_1mi.i, 2b_1mi.i")
+(final_presence_set "2b_0mm_bs" "2b_0mm.i, 2b_0mm.f, 2b_0mm.b")
+(final_presence_set "2b_1mm_bs" "2b_1mm.i, 2b_1mm.f, 2b_1mm.b")
+(final_presence_set "2b_0mf_bs" "2b_0mf.i, 2b_0mf.b")
+(final_presence_set "2b_1mf_bs" "2b_1mf.i, 2b_1mf.b")
+(final_presence_set "2b_0b_bs" "2b_0b.bb")
+(final_presence_set "2b_1b_bs" "2b_1b.bb")
+(final_presence_set "2b_0bb_bs" "2b_0bb.b")
+(final_presence_set "2b_1bb_bs" "2b_1bb.b")
+(final_presence_set "2b_0mb_bs" "2b_0mb.b")
+(final_presence_set "2b_1mb_bs" "2b_1mb.b")
+
+(exclusion_set "2b_0m_bs"
+ "2b_0mi.i, 2b_0mm.i, 2b_0mm.f, 2b_0mf.i, 2b_0mb.b,\
+ 2b_0mi.b, 2b_0mf.b, 2b_0mm.b, 2b_0mlx., 2b_m0_stop")
+(exclusion_set "2b_1m_bs"
+ "2b_1mi.i, 2b_1mm.i, 2b_1mm.f, 2b_1mf.i, 2b_1mb.b,\
+ 2b_1mi.b, 2b_1mf.b, 2b_1mm.b, 2b_1mlx., 2b_m1_stop")
+(exclusion_set "2b_0mi_bs" "2b_0mii., 2b_0mib., 2b_mi0_stop")
+(exclusion_set "2b_1mi_bs" "2b_1mii., 2b_1mib., 2b_mi1_stop")
+(exclusion_set "2b_0mm_bs" "2b_0mmi., 2b_0mmf., 2b_0mmb.")
+(exclusion_set "2b_1mm_bs" "2b_1mmi., 2b_1mmf., 2b_1mmb.")
+(exclusion_set "2b_0mf_bs" "2b_0mfi., 2b_0mfb.")
+(exclusion_set "2b_1mf_bs" "2b_1mfi., 2b_1mfb.")
+(exclusion_set "2b_0b_bs" "2b_0bb.b")
+(exclusion_set "2b_1b_bs" "2b_1bb.b")
+(exclusion_set "2b_0bb_bs" "2b_0bbb.")
+(exclusion_set "2b_1bb_bs" "2b_1bbb.")
+(exclusion_set "2b_0mb_bs" "2b_0mbb.")
+(exclusion_set "2b_1mb_bs" "2b_1mbb.")
+
+(exclusion_set
+ "2b_0m_bs, 2b_0mi_bs, 2b_0mm_bs, 2b_0mf_bs, 2b_0b_bs, 2b_0bb_bs, 2b_0mb_bs,
+ 2b_1m_bs, 2b_1mi_bs, 2b_1mm_bs, 2b_1mf_bs, 2b_1b_bs, 2b_1bb_bs, 2b_1mb_bs"
+ "2b_stop")
+
+(final_presence_set
+ "2b_0mi.i, 2b_0mm.i, 2b_0mf.i, 2b_0mm.f, 2b_0mb.b,\
+ 2b_0mi.b, 2b_0mm.b, 2b_0mf.b, 2b_0mlx."
+ "2b_m_cont")
+(final_presence_set "2b_0mii., 2b_0mib." "2b_mi_cont")
+(final_presence_set "2b_0mmi., 2b_0mmf., 2b_0mmb." "2b_mm_cont")
+(final_presence_set "2b_0mfi., 2b_0mfb." "2b_mf_cont")
+(final_presence_set "2b_0bb.b" "2b_b_cont")
+(final_presence_set "2b_0bbb." "2b_bb_cont")
+(final_presence_set "2b_0mbb." "2b_mb_cont")
+
+(exclusion_set
+ "2b_0m.ii, 2b_0m.mi, 2b_0m.fi, 2b_0m.mf, 2b_0b.bb, 2b_0m.bb,\
+ 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx"
+ "2b_m_cont, 2b_mi_cont, 2b_mm_cont, 2b_mf_cont,\
+ 2b_mb_cont, 2b_b_cont, 2b_bb_cont")
+
+(exclusion_set "2b_empty"
+ "2b_m_cont,2b_mi_cont,2b_mm_cont,2b_mf_cont,\
+ 2b_mb_cont,2b_b_cont,2b_bb_cont")
+
+;; For m;mi bundle
+(final_presence_set "2b_m0_stop" "2b_0m.mi")
+(final_presence_set "2b_0mm.i" "2b_0mmi_cont")
+(exclusion_set "2b_0mmi_cont"
+ "2b_0m.ii, 2b_0m.mi, 2b_0m.fi, 2b_0m.mf, 2b_0b.bb, 2b_0m.bb,\
+ 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_m0_stop" "2b_0mm.i")
+(final_presence_set "2b_m1_stop" "2b_1m.mi")
+(exclusion_set "2b_m1_stop" "2b_1mm.i")
+(final_presence_set "2b_m_stop" "2b_m0_stop, 2b_m1_stop")
+
+;; For mi;i bundle
+(final_presence_set "2b_mi0_stop" "2b_0mi.i")
+(final_presence_set "2b_0mii." "2b_0mii_cont")
+(exclusion_set "2b_0mii_cont"
+ "2b_0m.ii, 2b_0m.mi, 2b_0m.fi, 2b_0m.mf, 2b_0b.bb, 2b_0m.bb,\
+ 2b_0m.ib, 2b_0m.mb, 2b_0m.fb, 2b_0m.lx")
+(exclusion_set "2b_mi0_stop" "2b_0mii.")
+(final_presence_set "2b_mi1_stop" "2b_1mi.i")
+(exclusion_set "2b_mi1_stop" "2b_1mii.")
+(final_presence_set "2b_mi_stop" "2b_mi0_stop, 2b_mi1_stop")
+
+(final_absence_set
+ "2b_0m.ii,2b_0mi.i,2b_0mii.,2b_0m.mi,2b_0mm.i,2b_0mmi.,\
+ 2b_0m.fi,2b_0mf.i,2b_0mfi.,2b_0m.mf,2b_0mm.f,2b_0mmf.,\
+ 2b_0b.bb,2b_0bb.b,2b_0bbb.,2b_0m.bb,2b_0mb.b,2b_0mbb.,\
+ 2b_0m.ib,2b_0mi.b,2b_0mib.,2b_0m.mb,2b_0mm.b,2b_0mmb.,\
+ 2b_0m.fb,2b_0mf.b,2b_0mfb.,2b_0m.lx,2b_0mlx., \
+ 2b_1m.ii,2b_1mi.i,2b_1mii.,2b_1m.mi,2b_1mm.i,2b_1mmi.,\
+ 2b_1m.fi,2b_1mf.i,2b_1mfi.,2b_1m.mf,2b_1mm.f,2b_1mmf.,\
+ 2b_1b.bb,2b_1bb.b,2b_1bbb.,2b_1m.bb,2b_1mb.b,2b_1mbb.,\
+ 2b_1m.ib,2b_1mi.b,2b_1mib.,2b_1m.mb,2b_1mm.b,2b_1mmb.,\
+ 2b_1m.fb,2b_1mf.b,2b_1mfb.,2b_1m.lx,2b_1mlx."
+ "2b_m0_stop,2b_m1_stop,2b_mi0_stop,2b_mi1_stop")
+
+(define_insn_reservation "2b_stop_bit" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "stop_bit"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_stop|2b_m0_stop|2b_m1_stop|2b_mi0_stop|2b_mi1_stop")
+(define_insn_reservation "2b_br" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "br"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_B")
+(define_insn_reservation "2b_scall" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "scall"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_B")
+(define_insn_reservation "2b_fcmp" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fcmp"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_F")
+(define_insn_reservation "2b_fcvtfx" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fcvtfx"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_F")
+(define_insn_reservation "2b_fld" 6
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fld"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_M")
+(define_insn_reservation "2b_fmac" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fmac"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_F")
+(define_insn_reservation "2b_fmisc" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "fmisc"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_F")
+
+;; Latency time ???
+(define_insn_reservation "2b_frar_i" 13
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frar_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+;; Latency time ???
+(define_insn_reservation "2b_frar_m" 6
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frar_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um2")
+(define_insn_reservation "2b_frbr" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frbr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+(define_insn_reservation "2b_frfr" 5
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frfr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um2")
+(define_insn_reservation "2b_frpr" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "frpr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+
+(define_insn_reservation "2b_ialu" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ialu"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_A")
+(define_insn_reservation "2b_icmp" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "icmp"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_A")
+(define_insn_reservation "2b_ilog" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ilog"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_A")
+;; Latency time ???
+(define_insn_reservation "2b_ishf" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ishf"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+(define_insn_reservation "2b_ld" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ld"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um01")
+(define_insn_reservation "2b_long_i" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "long_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_L")
+
+;; Latency time ???
+(define_insn_reservation "2b_mmmul" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "mmmul"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+;; Latency time ???
+(define_insn_reservation "2b_mmshf" 2
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "mmshf"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_I")
+;; Latency time ???
+(define_insn_reservation "2b_mmshfi" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "mmshfi"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_I")
+
+(define_insn_reservation "2b_rse_m" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "rse_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "(2b_0m.ii|2b_0m.mi|2b_0m.fi|2b_0m.mf|2b_0m.bb\
+ |2b_0m.ib|2b_0m.mb|2b_0m.fb|2b_0m.lx)+2_1+2b_um0")
+(define_insn_reservation "2b_sem" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "sem"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um23")
+
+(define_insn_reservation "2b_stf" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "stf"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um23")
+(define_insn_reservation "2b_st" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "st"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um23")
+(define_insn_reservation "2b_syst_m0" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "syst_m0"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um2")
+(define_insn_reservation "2b_syst_m" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "syst_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um0")
+;; Reservation???
+(define_insn_reservation "2b_tbit" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "tbit"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+(define_insn_reservation "2b_toar_i" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "toar_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+;; Latency time ???
+(define_insn_reservation "2b_toar_m" 5
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "toar_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um2")
+;; Latency time ???
+(define_insn_reservation "2b_tobr" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "tobr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+(define_insn_reservation "2b_tofr" 5
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "tofr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um23")
+;; Latency time ???
+(define_insn_reservation "2b_topr" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "topr"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I+2b_only_ui0")
+
+(define_insn_reservation "2b_xmpy" 4
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "xmpy"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_F")
+;; Latency time ???
+(define_insn_reservation "2b_xtd" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "xtd"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_I")
+(define_insn_reservation "2b_chk_s" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "chk_s"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_I|2b_M_only_um23")
+(define_insn_reservation "2b_lfetch" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "lfetch"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M_only_um01")
+(define_insn_reservation "2b_nop_m" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_m"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_M")
+(define_insn_reservation "2b_nop_b" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_b"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_NB")
+(define_insn_reservation "2b_nop_i" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_i"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_I")
+(define_insn_reservation "2b_nop_f" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_f"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_F")
+(define_insn_reservation "2b_nop_x" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop_x"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_L")
+(define_insn_reservation "2b_unknown" 1
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "unknown"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "2b_empty")
+(define_insn_reservation "2b_nop" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "nop"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "2b_M|2b_NB|2b_I|2b_F")
+(define_insn_reservation "2b_ignore" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "ignore"))
+ (ne (symbol_ref "bundling_p") (const_int 0))) "nothing")
+
+(define_insn_reservation "2b_pre_cycle" 0
+ (and (and (eq_attr "cpu" "itanium2")
+ (eq_attr "itanium_class" "pre_cycle"))
+ (ne (symbol_ref "bundling_p") (const_int 0)))
+ "(2b_0m_bs, 2b_m_cont) \
+ | (2b_0mi_bs, 2b_mi_cont) \
+ | (2b_0mm_bs, 2b_mm_cont) \
+ | (2b_0mf_bs, 2b_mf_cont) \
+ | (2b_0b_bs, 2b_b_cont) \
+ | (2b_0bb_bs, 2b_bb_cont) \
+ | (2b_0mb_bs, 2b_mb_cont) \
+ | (2b_1m_bs, 2b_m_cont) \
+ | (2b_1mi_bs, 2b_mi_cont) \
+ | (2b_1mm_bs, 2b_mm_cont) \
+ | (2b_1mf_bs, 2b_mf_cont) \
+ | (2b_1b_bs, 2b_b_cont) \
+ | (2b_1bb_bs, 2b_bb_cont) \
+ | (2b_1mb_bs, 2b_mb_cont) \
+ | (2b_m_stop, 2b_0mmi_cont) \
+ | (2b_mi_stop, 2b_0mii_cont)")
+
diff --git a/contrib/gcc/config/ia64/lib1funcs.asm b/contrib/gcc/config/ia64/lib1funcs.asm
index 75e79b0a0f73..e3d348ba7227 100644
--- a/contrib/gcc/config/ia64/lib1funcs.asm
+++ b/contrib/gcc/config/ia64/lib1funcs.asm
@@ -1,15 +1,19 @@
-#ifdef L__divtf3
+#ifdef L__divxf3
// Compute a 80-bit IEEE double-extended quotient.
//
// From the Intel IA-64 Optimization Guide, choose the minimum latency
// alternative.
//
// farg0 holds the dividend. farg1 holds the divisor.
+//
+// __divtf3 is an alternate symbol name for backward compatibility.
.text
.align 16
+ .global __divxf3
.global __divtf3
- .proc __divtf3
+ .proc __divxf3
+__divxf3:
__divtf3:
cmp.eq p7, p0 = r0, r0
frcpa.s0 f10, p6 = farg0, farg1
@@ -37,7 +41,7 @@ __divtf3:
(p6) fma.s0 fret0 = f12, f10, f11
(p7) mov fret0 = f10
br.ret.sptk rp
- .endp __divtf3
+ .endp __divxf3
#endif
#ifdef L__divdf3
@@ -701,3 +705,39 @@ __ia64_trampoline:
}
.endp __ia64_trampoline
#endif
+
+#ifdef L__compat
+// Thunks for backward compatibility.
+
+ .text
+ .align 16
+ .global __fixtfti
+ .proc __fixtfti
+__fixtfti:
+ { .bbb
+ br.sptk.many __fixxfti
+ ;;
+ }
+ .endp __fixtfti
+
+ .align 16
+ .global __fixunstfti
+ .proc __fixunstfti
+__fixunstfti:
+ { .bbb
+ br.sptk.many __fixunsxfti
+ ;;
+ }
+ .endp __fixunstfti
+
+ .align 16
+ .global __floattitf
+ .proc __floattitf
+__floattitf:
+ { .bbb
+ br.sptk.many __floattixf
+ ;;
+ }
+ .endp __floattitf
+
+#endif
diff --git a/contrib/gcc/config/ia64/linux.h b/contrib/gcc/config/ia64/linux.h
index e1d60f7d8c48..5c73b0c25ef4 100644
--- a/contrib/gcc/config/ia64/linux.h
+++ b/contrib/gcc/config/ia64/linux.h
@@ -12,27 +12,27 @@
/* Target OS builtins. */
#define TARGET_OS_CPP_BUILTINS() \
do { \
- builtin_assert("system=linux"); \
- builtin_define_std("linux"); \
- builtin_define_std("unix"); \
- builtin_define("__gnu_linux__"); \
+ LINUX_TARGET_OS_CPP_BUILTINS(); \
builtin_define("_LONGLONG"); \
} while (0)
/* Need to override linux.h STARTFILE_SPEC, since it has crtbeginT.o in. */
#undef STARTFILE_SPEC
+#ifdef HAVE_LD_PIE
#define STARTFILE_SPEC \
- "%{!shared: \
- %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
- %{!p:%{profile:gcrt1.o%s} \
- %{!profile:crt1.o%s}}}} \
- crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+ "%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+#else
+#define STARTFILE_SPEC \
+ "%{!shared: %{pg|p|profile:gcrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+#endif
/* Similar to standard Linux, but adding -ffast-math support. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
- %{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+ %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
/* Define this for shared library support because it isn't in the main
linux.h file. */
@@ -58,12 +58,17 @@ do { \
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
+/* This works only for glibc-2.3 and later, because sigcontext is different
+ in glibc-2.2.4. */
+
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
+
#ifdef IN_LIBGCC2
#include <signal.h>
#include <sys/ucontext.h>
#define IA64_GATE_AREA_START 0xa000000000000100LL
-#define IA64_GATE_AREA_END 0xa000000000020000LL
+#define IA64_GATE_AREA_END 0xa000000000030000LL
#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
if ((CONTEXT)->rp >= IA64_GATE_AREA_START \
@@ -90,11 +95,13 @@ do { \
(CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
} \
\
+ (CONTEXT)->fpsr_loc = &(sc_->sc_ar_fpsr); \
(CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs); \
(CONTEXT)->lc_loc = &(sc_->sc_ar_lc); \
(CONTEXT)->unat_loc = &(sc_->sc_ar_unat); \
(CONTEXT)->br_loc[0] = &(sc_->sc_br[0]); \
- (CONTEXT)->bsp = sc_->sc_ar_bsp; \
+ (CONTEXT)->br_loc[6] = &(sc_->sc_br[6]); \
+ (CONTEXT)->br_loc[7] = &(sc_->sc_br[7]); \
(CONTEXT)->pr = sc_->sc_pr; \
(CONTEXT)->psp = sc_->sc_gr[12]; \
(CONTEXT)->gp = sc_->sc_gr[1]; \
@@ -102,11 +109,26 @@ do { \
other than what we adjust for below. */ \
(FS) -> no_reg_stack_frame = 1; \
\
- /* Don't touch the branch registers o.t. b0. The kernel doesn't \
- pass the preserved branch registers in the sigcontext but \
- leaves them intact, so there's no need to do anything \
- with them here. */ \
+ if (sc_->sc_rbs_base) \
+ { \
+ /* Need to switch from alternate register backing store. */ \
+ long ndirty, loadrs = sc_->sc_loadrs >> 16; \
+ unsigned long alt_bspstore = (CONTEXT)->bsp - loadrs; \
+ unsigned long bspstore; \
+ unsigned long *ar_bsp = (unsigned long *)(sc_->sc_ar_bsp); \
\
+ ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore, \
+ (unsigned long *) (CONTEXT)->bsp);\
+ bspstore = (unsigned long) \
+ ia64_rse_skip_regs (ar_bsp, -ndirty); \
+ ia64_copy_rbs ((CONTEXT), bspstore, alt_bspstore, loadrs, \
+ sc_->sc_ar_rnat); \
+ } \
+ \
+ /* Don't touch the branch registers o.t. b0, b6 and b7. \
+ The kernel doesn't pass the preserved branch registers \
+ in the sigcontext but leaves them intact, so there's no \
+ need to do anything with them here. */ \
{ \
unsigned long sof = sc_->sc_cfm & 0x7f; \
(CONTEXT)->bsp = (unsigned long) \
@@ -120,4 +142,74 @@ do { \
\
goto SUCCESS; \
}
+
+#define MD_HANDLE_UNWABI(CONTEXT, FS) \
+ if ((FS)->unwabi == ((3 << 8) | 's') \
+ || (FS)->unwabi == ((0 << 8) | 's')) \
+ { \
+ struct sigframe { \
+ char scratch[16]; \
+ unsigned long sig_number; \
+ struct siginfo *info; \
+ struct sigcontext *sc; \
+ } *frame_ = (struct sigframe *)(CONTEXT)->psp; \
+ struct sigcontext *sc_ = frame_->sc; \
+ \
+ /* Restore scratch registers in case the unwinder needs to \
+ refer to a value stored in one of them. */ \
+ { \
+ int i_; \
+ \
+ for (i_ = 2; i_ < 4; i_++) \
+ (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
+ for (i_ = 8; i_ < 12; i_++) \
+ (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
+ for (i_ = 14; i_ < 32; i_++) \
+ (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_]; \
+ } \
+ \
+ (CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs); \
+ (CONTEXT)->lc_loc = &(sc_->sc_ar_lc); \
+ (CONTEXT)->unat_loc = &(sc_->sc_ar_unat); \
+ (CONTEXT)->br_loc[0] = &(sc_->sc_br[0]); \
+ (CONTEXT)->br_loc[6] = &(sc_->sc_br[6]); \
+ (CONTEXT)->br_loc[7] = &(sc_->sc_br[7]); \
+ (CONTEXT)->pr = sc_->sc_pr; \
+ (CONTEXT)->gp = sc_->sc_gr[1]; \
+ /* Signal frame doesn't have an associated reg. stack frame \
+ other than what we adjust for below. */ \
+ (FS) -> no_reg_stack_frame = 1; \
+ \
+ if (sc_->sc_rbs_base) \
+ { \
+ /* Need to switch from alternate register backing store. */ \
+ long ndirty, loadrs = sc_->sc_loadrs >> 16; \
+ unsigned long alt_bspstore = (CONTEXT)->bsp - loadrs; \
+ unsigned long bspstore; \
+ unsigned long *ar_bsp = (unsigned long *)(sc_->sc_ar_bsp); \
+ \
+ ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore, \
+ (unsigned long *) (CONTEXT)->bsp);\
+ bspstore = (unsigned long) \
+ ia64_rse_skip_regs (ar_bsp, -ndirty); \
+ ia64_copy_rbs ((CONTEXT), bspstore, alt_bspstore, loadrs, \
+ sc_->sc_ar_rnat); \
+ } \
+ \
+ /* Don't touch the branch registers o.t. b0, b6 and b7. \
+ The kernel doesn't pass the preserved branch registers \
+ in the sigcontext but leaves them intact, so there's no \
+ need to do anything with them here. */ \
+ { \
+ unsigned long sof = sc_->sc_cfm & 0x7f; \
+ (CONTEXT)->bsp = (unsigned long) \
+ ia64_rse_skip_regs ((unsigned long *)(sc_->sc_ar_bsp), -sof); \
+ } \
+ \
+ /* pfs_loc already set above. Without this pfs_loc would point \
+ incorrectly to sc_cfm instead of sc_ar_pfs. */ \
+ (FS)->curr.reg[UNW_REG_PFS].where = UNW_WHERE_NONE; \
+ }
+
#endif /* IN_LIBGCC2 */
+#endif /* glibc-2.3 or better */
diff --git a/contrib/gcc/config/ia64/quadlib.c b/contrib/gcc/config/ia64/quadlib.c
index e55c97d2be97..cc367ea03cfb 100644
--- a/contrib/gcc/config/ia64/quadlib.c
+++ b/contrib/gcc/config/ia64/quadlib.c
@@ -1,9 +1,9 @@
/* Subroutines for long double support.
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
@@ -17,13 +17,13 @@ do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/ia64/sysv4.h b/contrib/gcc/config/ia64/sysv4.h
index 3254fa5e2fd6..15a57d924cd3 100644
--- a/contrib/gcc/config/ia64/sysv4.h
+++ b/contrib/gcc/config/ia64/sysv4.h
@@ -61,8 +61,6 @@ do { \
#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
do { \
const char *name_ = NAME; \
- if (*name_ == ENCODE_SECTION_INFO_CHAR) \
- name_ += 2; \
if (*name_ == '*') \
name_++; \
else \
@@ -119,26 +117,6 @@ do { \
fputc ('\n', FILE); \
} while (0)
-/* A C expression which outputs to the stdio stream STREAM some appropriate
- text to go at the start of an assembler file. */
-
-/* ??? Looks like almost every port, except for a few original ones, get this
- wrong. Must emit #NO_APP as first line of file to turn of special assembler
- preprocessing of files. */
-
-/* ??? Even worse, it doesn't work, because gas does not accept the tab chars
- that dwarf2out.c emits when #NO_APP. */
-
-/* ??? Unrelated, but dwarf2out.c emits unnecessary newlines after strings,
- may as well fix at the same time. */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(STREAM) \
-do { \
- output_file_directive (STREAM, main_input_filename); \
- emit_safe_across_calls (STREAM); \
-} while (0)
-
/* Override default elf definition. */
#undef TARGET_ASM_SELECT_RTX_SECTION
#define TARGET_ASM_SELECT_RTX_SECTION ia64_select_rtx_section
@@ -155,7 +133,7 @@ do { \
#define SDATA_SECTION_FUNCTION \
void \
-sdata_section () \
+sdata_section (void) \
{ \
if (in_section != in_sdata) \
{ \
@@ -168,7 +146,7 @@ sdata_section () \
#define SBSS_SECTION_FUNCTION \
void \
-sbss_section () \
+sbss_section (void) \
{ \
if (in_section != in_sbss) \
{ \
diff --git a/contrib/gcc/config/ia64/t-hpux b/contrib/gcc/config/ia64/t-hpux
index 7b42fe519a25..597c2acbe2ae 100644
--- a/contrib/gcc/config/ia64/t-hpux
+++ b/contrib/gcc/config/ia64/t-hpux
@@ -20,22 +20,17 @@ quadlib.c: $(srcdir)/config/ia64/quadlib.c
LIBGCC1_TEST =
-# Don't run fix-headers. HP-UX headers are standards conformant
-# and don't need to be fixed up in this way.
-# If we remove this (and run fix-headers) we should define FIXPROTO_DEFINES
-# and also fix the definition of putenv in sys-protos.h (const char not char).
-
-STMP_FIXPROTO =
-
# We do not want to include the EH stuff that linux uses, we want to use
# the HP-UX libunwind library.
LIB2ADDEH =
SHLIB_EXT = .so
+# Must include -lunwind in the link, so that libgcc_s.so has the necessary
+# DT_NEEDED entry for libunwind.
SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
-Wl,+h,@shlib_base_name@.so.0 \
- -o @shlib_base_name@.so @multilib_flags@ @shlib_objs@ -lc && \
+ -o @shlib_base_name@.so @multilib_flags@ @shlib_objs@ -lunwind -lc && \
rm -f @shlib_base_name@.so.0 && \
$(LN_S) @shlib_base_name@.so @shlib_base_name@.so.0
# $(slibdir) double quoted to protect it from expansion while building
diff --git a/contrib/gcc/config/ia64/t-ia64 b/contrib/gcc/config/ia64/t-ia64
index 7c63b31e6287..21d37a79a92a 100644
--- a/contrib/gcc/config/ia64/t-ia64
+++ b/contrib/gcc/config/ia64/t-ia64
@@ -5,10 +5,10 @@ LIB1ASMSRC = ia64/lib1funcs.asm
# we use __ as the prefix. Note that L_divdi3 in libgcc2.c actually defines
# a TImode divide function, so there is no actual overlap here between
# libgcc2.c and lib1funcs.asm.
-LIB1ASMFUNCS = __divtf3 __divdf3 __divsf3 \
+LIB1ASMFUNCS = __divxf3 __divdf3 __divsf3 \
__divdi3 __moddi3 __udivdi3 __umoddi3 \
__divsi3 __modsi3 __udivsi3 __umodsi3 __save_stack_nonlocal \
- __nonlocal_goto __restore_stack_nonlocal __trampoline
+ __nonlocal_goto __restore_stack_nonlocal __trampoline __compat
# ??? Hack to get -P option used when compiling lib1funcs.asm, because Intel
# assembler does not accept # line number as a comment.
@@ -41,8 +41,11 @@ crtfastmath.o: $(srcdir)/config/ia64/crtfastmath.c $(GCC_PASSES)
$(srcdir)/config/ia64/crtfastmath.c
LIB2ADDEH = $(srcdir)/config/ia64/unwind-ia64.c $(srcdir)/unwind-sjlj.c \
- $(srcdir)/unwind-c.c
+ $(srcdir)/unwind-c.c $(srcdir)/gthr-gnat.c
ia64-c.o: $(srcdir)/config/ia64/ia64-c.c $(CONFIG_H) $(SYSTEM_H) \
- $(TREE_H) $(CPPLIB_H) $(C_COMMON_H) c-pragma.h toplev.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+ 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
+
+# genattrtab generates very long string literals.
+insn-attrtab.o-warn = -Wno-error
diff --git a/contrib/gcc/config/ia64/unwind-ia64.c b/contrib/gcc/config/ia64/unwind-ia64.c
index 88d236b141cd..d981d8c3e91a 100644
--- a/contrib/gcc/config/ia64/unwind-ia64.c
+++ b/contrib/gcc/config/ia64/unwind-ia64.c
@@ -6,20 +6,20 @@
Andrew Haley <aph@cygnus.com>
David Mosberger-Tang <davidm@hpl.hp.com>
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -33,6 +33,8 @@
#include "tconfig.h"
#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
#include "unwind.h"
#include "unwind-ia64.h"
#include "ia64intrin.h"
@@ -155,6 +157,7 @@ typedef struct unw_state_record
unsigned char gr_save_loc; /* next general register to use for saving */
unsigned char return_link_reg; /* branch register for return link */
+ unsigned short unwabi;
struct unw_labeled_state *labeled_states; /* list of all labeled states */
struct unw_reg_state curr; /* current state */
@@ -181,7 +184,8 @@ struct _Unwind_Context
{
/* Initial frame info. */
unsigned long rnat; /* rse nat collection */
- unsigned long regstk_top; /* bsp for first frame */
+ unsigned long regstk_top; /* lowest address of rbs stored register
+ which uses context->rnat collection */
/* Current frame info. */
unsigned long bsp; /* backing store pointer value
@@ -219,7 +223,7 @@ struct _Unwind_Context
} nat;
} ireg[32 - 2]; /* Indexed by <register number> - 2 */
- unsigned long *br_loc[7];
+ unsigned long *br_loc[8];
void *fr_loc[32 - 2];
/* ??? We initially point pri_unat_loc here. The entire NAT bit
@@ -619,11 +623,11 @@ desc_prologue (int body, unw_word rlen, unsigned char mask,
*/
static inline void
-desc_abi (unsigned char abi __attribute__((unused)),
- unsigned char context __attribute__((unused)),
- struct unw_state_record *sr __attribute__((unused)))
+desc_abi (unsigned char abi,
+ unsigned char context,
+ struct unw_state_record *sr)
{
- /* Anything to do? */
+ sr->unwabi = (abi << 8) | context;
}
static inline void
@@ -1465,7 +1469,7 @@ ia64_rse_rnat_addr (unsigned long *slot_addr)
return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3));
}
-/* Calcuate the number of registers in the dirty partition starting at
+/* Calculate the number of registers in the dirty partition starting at
BSPSTORE with a size of DIRTY bytes. This isn't simply DIRTY
divided by eight because the 64th slot is used to store ar.rnat. */
static inline unsigned long
@@ -1489,6 +1493,80 @@ ia64_rse_skip_regs (unsigned long *addr, long num_regs)
}
+/* Copy register backing store from SRC to DST, LEN words
+ (which include both saved registers and nat collections).
+ DST_RNAT is a partial nat collection for DST. SRC and DST
+ don't have to be equal modulo 64 slots, so it cannot be
+ done with a simple memcpy as the nat collections will be
+ at different relative offsets and need to be combined together. */
+static void
+ia64_copy_rbs (struct _Unwind_Context *info, unsigned long dst,
+ unsigned long src, long len, unsigned long dst_rnat)
+{
+ long count;
+ unsigned long src_rnat;
+ unsigned long shift1, shift2;
+
+ len <<= 3;
+ dst_rnat &= (1UL << ((dst >> 3) & 0x3f)) - 1;
+ src_rnat = src >= info->regstk_top
+ ? info->rnat : *(unsigned long *) (src | 0x1f8);
+ src_rnat &= ~((1UL << ((src >> 3) & 0x3f)) - 1);
+ /* Just to make sure. */
+ src_rnat &= ~(1UL << 63);
+ shift1 = ((dst - src) >> 3) & 0x3f;
+ if ((dst & 0x1f8) < (src & 0x1f8))
+ shift1--;
+ shift2 = 0x3f - shift1;
+ if ((dst & 0x1f8) >= (src & 0x1f8))
+ {
+ count = ~dst & 0x1f8;
+ goto first;
+ }
+ count = ~src & 0x1f8;
+ goto second;
+ while (len > 0)
+ {
+ src_rnat = src >= info->regstk_top
+ ? info->rnat : *(unsigned long *) (src | 0x1f8);
+ /* Just to make sure. */
+ src_rnat &= ~(1UL << 63);
+ count = shift2 << 3;
+first:
+ if (count > len)
+ count = len;
+ memcpy ((char *) dst, (char *) src, count);
+ dst += count;
+ src += count;
+ len -= count;
+ dst_rnat |= (src_rnat << shift1) & ~(1UL << 63);
+ if (len <= 0)
+ break;
+ *(long *) dst = dst_rnat;
+ dst += 8;
+ dst_rnat = 0;
+ count = shift1 << 3;
+second:
+ if (count > len)
+ count = len;
+ memcpy ((char *) dst, (char *) src, count);
+ dst += count;
+ src += count + 8;
+ len -= count + 8;
+ dst_rnat |= (src_rnat >> shift2);
+ }
+ if ((dst & 0x1f8) == 0x1f8)
+ {
+ *(long *) dst = dst_rnat;
+ dst += 8;
+ dst_rnat = 0;
+ }
+ /* Set info->regstk_top to lowest rbs address which will use
+ info->rnat collection. */
+ info->regstk_top = dst & ~0x1ffUL;
+ info->rnat = dst_rnat;
+}
+
/* Unwind accessors. */
static void
@@ -1548,9 +1626,10 @@ unw_access_gr (struct _Unwind_Context *info, int regnum,
break;
case UNW_NAT_REGSTK:
- nat_addr = ia64_rse_rnat_addr (addr);
- if ((unsigned long) nat_addr >= info->regstk_top)
+ if ((unsigned long) addr >= info->regstk_top)
nat_addr = &info->rnat;
+ else
+ nat_addr = ia64_rse_rnat_addr (addr);
nat_mask = 1UL << ia64_rse_slot_num (addr);
break;
}
@@ -1560,9 +1639,10 @@ unw_access_gr (struct _Unwind_Context *info, int regnum,
{
/* Access a stacked register. */
addr = ia64_rse_skip_regs ((unsigned long *) info->bsp, regnum - 32);
- nat_addr = ia64_rse_rnat_addr (addr);
- if ((unsigned long) nat_addr >= info->regstk_top)
+ if ((unsigned long) addr >= info->regstk_top)
nat_addr = &info->rnat;
+ else
+ nat_addr = ia64_rse_rnat_addr (addr);
nat_mask = 1UL << ia64_rse_slot_num (addr);
}
@@ -1703,8 +1783,10 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
an unwind table entry.
This can only happen in the frame after unwinding through a signal
- handler. Avoid infinite looping by requiring that B0 != RP. */
- if (context->br_loc[0] && *context->br_loc[0] != context->rp)
+ handler. Avoid infinite looping by requiring that B0 != RP.
+ RP == 0 terminates the chain. */
+ if (context->br_loc[0] && *context->br_loc[0] != context->rp
+ && context->rp != 0)
{
fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
fs->curr.reg[UNW_REG_RP].when = -1;
@@ -1721,7 +1803,8 @@ uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
}
context->region_start = ent->start_offset + segment_base;
- fs->when_target = (context->rp - context->region_start) / 16 * 3;
+ fs->when_target = ((context->rp & -16) - context->region_start) / 16 * 3
+ + (context->rp & 15);
unw = (unsigned long *) (ent->info_offset + segment_base);
header = *unw;
@@ -1812,9 +1895,9 @@ uw_update_reg_address (struct _Unwind_Context *context,
case UNW_WHERE_BR:
/* Note that while RVAL can only be 1-5 from normal descriptors,
- we can want to look at B0 due to having manually unwound a
+ we can want to look at B0, B6 and B7 due to having manually unwound a
signal frame. */
- if (rval <= 5)
+ if (rval < 8)
addr = context->br_loc[rval];
else
abort ();
@@ -1928,6 +2011,10 @@ uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
long i;
+#ifdef MD_HANDLE_UNWABI
+ MD_HANDLE_UNWABI (context, fs);
+#endif
+
context->sp = context->psp;
/* First, set PSP. Subsequent instructions may depend on this value. */
@@ -1991,18 +2078,31 @@ uw_init_context_1 (struct _Unwind_Context *context, void *bsp)
/* Set psp to the caller's stack pointer. */
void *psp = __builtin_dwarf_cfa () - 16;
_Unwind_FrameState fs;
-
- /* Flush the register stack to memory so that we can access it. */
- __builtin_ia64_flushrs ();
+ unsigned long rnat, tmp1, tmp2;
+
+ /* Flush the register stack to memory so that we can access it.
+ Get rse nat collection for the last incomplete rbs chunk of
+ registers at the same time. For this RSE needs to be turned
+ into the mandatory only mode. */
+ asm ("mov.m %1 = ar.rsc;;\n\t"
+ "and %2 = 0x1c, %1;;\n\t"
+ "mov.m ar.rsc = %2;;\n\t"
+ "flushrs;;\n\t"
+ "mov.m %0 = ar.rnat;;\n\t"
+ "mov.m ar.rsc = %1\n\t"
+ : "=r" (rnat), "=r" (tmp1), "=r" (tmp2));
memset (context, 0, sizeof (struct _Unwind_Context));
- context->bsp = context->regstk_top = (unsigned long) bsp;
+ context->bsp = (unsigned long) bsp;
+ /* Set context->regstk_top to lowest rbs address which will use
+ context->rnat collection. */
+ context->regstk_top = context->bsp & ~0x1ffULL;
+ context->rnat = rnat;
context->psp = (unsigned long) psp;
context->rp = (unsigned long) rp;
asm ("mov %0 = sp" : "=r" (context->sp));
asm ("mov %0 = pr" : "=r" (context->pr));
context->pri_unat_loc = &context->initial_unat; /* ??? */
- /* ??? Get rnat. Don't we have to turn off the rse for that? */
if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
abort ();
@@ -2043,6 +2143,9 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
ia64_rse_skip_regs ((unsigned long *)target->bsp,
(*target->pfs_loc >> 7) & 0x7f);
+ if (target->bsp < target->regstk_top)
+ target->rnat = *ia64_rse_rnat_addr ((unsigned long *) target->bsp);
+
/* Provide assembly with the offsets into the _Unwind_Context. */
asm volatile ("uc_rnat = %0"
: : "i"(offsetof (struct _Unwind_Context, rnat)));
@@ -2079,22 +2182,22 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
";; \n\t"
"(p6) ld8.fill r4 = [%1] \n\t"
"(p7) ld8.fill r5 = [r20] \n\t"
- "add r21 = uc_br_loc + 8, %0 \n\t"
+ "add r21 = uc_br_loc + 16, %0 \n\t"
"adds %1 = 16, %1 \n\t"
"adds r20 = 16, r20 \n\t"
";; \n\t"
"(p8) ld8.fill r6 = [%1] \n\t"
"(p9) ld8.fill r7 = [r20] \n\t"
- "add r20 = uc_br_loc, %0 \n\t"
+ "add r20 = uc_br_loc + 8, %0 \n\t"
";; \n\t"
/* Load up call-saved branch registers. */
"ld8 r22 = [r20], 16 \n\t"
"ld8 r23 = [r21], 16 \n\t"
";; \n\t"
"ld8 r24 = [r20], 16 \n\t"
- "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 24)\n\t"
+ "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 32)\n\t"
";; \n\t"
- "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 32)\n\t"
+ "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 40)\n\t"
"ld8 r27 = [r21], 24 \n\t"
"cmp.ne p6, p0 = r0, r22 \n\t"
";; \n\t"
@@ -2242,12 +2345,12 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
"(p9) mov.i ar.lc = r29 \n\t"
";; \n\t"
"mov.m r25 = ar.rsc \n\t"
- "(p6) mov.i ar.fpsr = r30 \n\t"
+ "(p6) mov.m ar.fpsr = r30 \n\t"
";; \n\t"
- "and r25 = 0x1c, r25 \n\t"
+ "and r29 = 0x1c, r25 \n\t"
"mov b0 = r26 \n\t"
";; \n\t"
- "mov.m ar.rsc = r25 \n\t"
+ "mov.m ar.rsc = r29 \n\t"
";; \n\t"
/* This must be done before setting AR.BSPSTORE, otherwise
AR.BSP will be initialized with a random displacement
@@ -2258,7 +2361,6 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
";; \n\t"
"mov.m ar.bspstore = r23 \n\t"
";; \n\t"
- "or r25 = 0x3, r25 \n\t"
"mov.m ar.rnat = r22 \n\t"
";; \n\t"
"mov.m ar.rsc = r25 \n\t"
diff --git a/contrib/gcc/config/ia64/unwind-ia64.h b/contrib/gcc/config/ia64/unwind-ia64.h
index a6b850df80a8..b56b38c45c41 100644
--- a/contrib/gcc/config/ia64/unwind-ia64.h
+++ b/contrib/gcc/config/ia64/unwind-ia64.h
@@ -2,20 +2,20 @@
Contributed by Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/interix.h b/contrib/gcc/config/interix.h
index 8d9f58f8b5b3..9d05f1bcc0ad 100644
--- a/contrib/gcc/config/interix.h
+++ b/contrib/gcc/config/interix.h
@@ -5,20 +5,20 @@
Modified from code
Contributed by Douglas B. Rupp (drupp@cs.washington.edu).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -70,19 +70,6 @@ for windows/multi thread */
&& strcmp (STR, "Tbss"))
-#if 0
-/* don't do this until we can sort out the default path issues. MK */
-#undef STANDARD_EXEC_PREFIX
-#define STANDARD_EXEC_PREFIX ""
-
-#undef STANDARD_STARTFILE_PREFIX
-#define STANDARD_STARTFILE_PREFIX ""
-
-#undef TOOLDIR_BASE_PREFIX
-#define TOOLDIR_BASE_PREFIX ""
-
-#endif /* 0 */
-
#define STDC_0_IN_SYSTEM_HEADERS 1
#define HANDLE_SYSV_PRAGMA 1
diff --git a/contrib/gcc/config/interix3.h b/contrib/gcc/config/interix3.h
index 4d4e85c2f13f..9e2cc35a4efe 100644
--- a/contrib/gcc/config/interix3.h
+++ b/contrib/gcc/config/interix3.h
@@ -3,20 +3,20 @@
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/kaos.h b/contrib/gcc/config/kaos.h
new file mode 100644
index 000000000000..45938da75c1b
--- /dev/null
+++ b/contrib/gcc/config/kaos.h
@@ -0,0 +1,31 @@
+/* Definitions of target machine for GCC.
+ common kaOS definitions for all architectures.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Specify predefined symbols in preprocessor. */
+#define TARGET_OS_CPP_BUILTINS() \
+ do { \
+ builtin_define ("__kaOS__"); \
+ } while (0)
+
+
+/* do not link any library implicitly for kaOS target. */
+#undef LIB_SPEC
+#define LIB_SPEC ""
diff --git a/contrib/gcc/config/kfreebsdgnu.h b/contrib/gcc/config/kfreebsdgnu.h
new file mode 100644
index 000000000000..ad8d68c3f21f
--- /dev/null
+++ b/contrib/gcc/config/kfreebsdgnu.h
@@ -0,0 +1,41 @@
+/* Definitions for GNU/KFreeBSD systems with ELF format.
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Bruno Haible.
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ builtin_define ("__GNU_KFreeBSD__=0"); \
+ builtin_define ("__gnu_kfreebsd__=0"); \
+ builtin_define ("__FreeBSD_kernel__=5"); \
+ builtin_define ("__ELF__"); \
+ builtin_define_std ("unix"); \
+ builtin_assert ("system=posix");
+
+#undef TARGET_CPU_CPP_BUILTINS
+#define TARGET_CPU_CPP_BUILTINS() \
+ builtin_define ("__i386__"); \
+ builtin_define_std ("i386"); \
+ builtin_assert ("cpu=i386"); \
+ builtin_assert ("machine=i386");
+
+/* do {} while (0) */
diff --git a/contrib/gcc/config/libgloss.h b/contrib/gcc/config/libgloss.h
index f73982b8634f..3f9bf6c9ef24 100644
--- a/contrib/gcc/config/libgloss.h
+++ b/contrib/gcc/config/libgloss.h
@@ -2,20 +2,20 @@
targeting GCC for Libgloss supported targets.
Copyright (C) 1996 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/linux-aout.h b/contrib/gcc/config/linux-aout.h
index 13d9bfd6e83a..5701fd94ded6 100644
--- a/contrib/gcc/config/linux-aout.h
+++ b/contrib/gcc/config/linux-aout.h
@@ -1,35 +1,27 @@
-/* Definitions for Linux-based GNU systems.
+/* Definitions for Linux-based GNU systems with a.out binaries.
Copyright (C) 1995, 1997, 1999, 2000 Free Software Foundation, Inc.
Contributed by H.J. Lu (hjl@nynexst.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
-/* GNU/Linux uses ctype from glibc.a. I am not sure how complete it is.
- For now, we play safe. It may change later. */
-
-#if 0
-#undef MULTIBYTE_CHARS
-#define MULTIBYTE_CHARS 1
-#endif
-
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{pg:gcrt0.o%s} %{!pg:%{p:gcrt0.o%s} %{!p:crt0.o%s}} %{static:-static}"
diff --git a/contrib/gcc/config/linux.h b/contrib/gcc/config/linux.h
index 297fa92f7460..0f7ba1777e8b 100644
--- a/contrib/gcc/config/linux.h
+++ b/contrib/gcc/config/linux.h
@@ -1,36 +1,29 @@
/* Definitions for Linux-based GNU systems with ELF format
- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003
+ Free Software Foundation, Inc.
Contributed by Eric Youngdale.
Modified for stabs-in-ELF by H.J. Lu (hjl@lucon.org).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
-/* GNU/Linux uses ctype from glibc.a. I am not sure how complete it is.
- For now, we play safe. It may change later. */
-
-#if 0
-#undef MULTIBYTE_CHARS
-#define MULTIBYTE_CHARS 1
-#endif
-
#undef ASM_APP_ON
#define ASM_APP_ON "#APP\n"
@@ -53,14 +46,14 @@ Boston, MA 02111-1307, USA. */
%{!p:%{profile:gcrt1.o%s} \
%{!profile:crt1.o%s}}}} \
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+#elif defined HAVE_LD_PIE
+#define STARTFILE_SPEC \
+ "%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#else
#define STARTFILE_SPEC \
- "%{!shared: \
- %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
- %{!p:%{profile:gcrt1.o%s} \
- %{!profile:crt1.o%s}}}} \
- crti.o%s %{static:crtbeginT.o%s}\
- %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
+ "%{!shared: %{pg|p|profile:gcrt1.o%s;:crt1.o%s}} \
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#endif
/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
@@ -71,7 +64,7 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
- "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+ "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
/* This is for -profile to use -lc_p instead of -lc. */
#ifndef CC1_SPEC
@@ -104,14 +97,30 @@ Boston, MA 02111-1307, USA. */
%{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}}"
#endif
+#define LINUX_TARGET_OS_CPP_BUILTINS() \
+ do { \
+ builtin_define ("__gnu_linux__"); \
+ builtin_define_std ("linux"); \
+ builtin_define_std ("unix"); \
+ builtin_assert ("system=linux"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=posix"); \
+ } while (0)
+
#if !defined(USE_GNULIBC_1) && defined(HAVE_LD_EH_FRAME_HDR)
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
#endif
+/* Define this so we can compile MS code for use with WINE. */
+#define HANDLE_PRAGMA_PACK_PUSH_POP
+
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
-/* Define this so we can compile MS code for use with WINE. */
-#define HANDLE_PRAGMA_PACK_PUSH_POP
+/* Determine whether the the entire c99 runtime
+ is present in the runtime library. */
+#ifndef USE_GNULIBC_1
+#define TARGET_C99_FUNCTIONS 1
+#endif
#define TARGET_HAS_F_SETLKW
diff --git a/contrib/gcc/config/lynx-ng.h b/contrib/gcc/config/lynx-ng.h
index 7c257c7982e3..c23ad39a77f8 100644
--- a/contrib/gcc/config/lynx-ng.h
+++ b/contrib/gcc/config/lynx-ng.h
@@ -1,20 +1,20 @@
/* Target independent definitions for LynxOS, using Lynx's old as and ld.
Copyright (C) 1993, 1999 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/lynx.h b/contrib/gcc/config/lynx.h
index e060675a7ce8..a2366d106da3 100644
--- a/contrib/gcc/config/lynx.h
+++ b/contrib/gcc/config/lynx.h
@@ -1,28 +1,25 @@
-/* Target independent definitions for LynxOS.
- Copyright (C) 1993, 1994, 1995, 1996, 1999, 2000, 2002
+/* Target independent definitions for LynxOS using gas and gnu ld.
+ Copyright (C) 1993, 1994, 1995, 1996, 1999, 2000, 2002, 2003
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* LynxOS is a multi-platform Unix, similar to SVR3, but not identical.
- We can get quite a bit from generic svr3, but have to do some overrides. */
-
-#include "svr3.h"
+/* LynxOS is a multi-platform Unix, similar to SVR3, but not identical. */
/* Define various macros, depending on the combination of flags. */
@@ -84,14 +81,12 @@ Boston, MA 02111-1307, USA. */
"\t.text\n\t.stabs \"\",%d,0,0,Letext\nLetext:\n", N_SO)
#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(file, line) \
- { static int sym_lineno = 1; \
- fprintf (file, ".stabn 68,0,%d,.LM%d-", \
- line, sym_lineno); \
+#define ASM_OUTPUT_SOURCE_LINE(file, line, counter) \
+ { fprintf (file, ".stabn 68,0,%d,.LM%d-", \
+ line, counter); \
assemble_name (file, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); \
- fprintf (file, "\n.LM%d:\n", sym_lineno); \
- sym_lineno += 1; }
+ fprintf (file, "\n.LM%d:\n", counter); }
/* Handle #pragma pack and sometimes #pragma weak. */
diff --git a/contrib/gcc/config/netbsd-aout.h b/contrib/gcc/config/netbsd-aout.h
index 7c2f86573ce0..53e657077649 100644
--- a/contrib/gcc/config/netbsd-aout.h
+++ b/contrib/gcc/config/netbsd-aout.h
@@ -2,20 +2,20 @@
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -39,7 +39,9 @@ Boston, MA 02111-1307, USA. */
with the options for generating PIC code. */
#undef ASM_SPEC
-#define ASM_SPEC " %| %{fpic:-k} %{fPIC:-k -K}"
+#define ASM_SPEC "%{fpic|fpie:-k} %{fPIC|fPIE:-k -K}"
+
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
/* Provide a STARTFILE_SPEC appropriate for NetBSD a.out. Here we
diff --git a/contrib/gcc/config/netbsd-elf.h b/contrib/gcc/config/netbsd-elf.h
index cb38b93ba0a1..a87699c34a21 100644
--- a/contrib/gcc/config/netbsd-elf.h
+++ b/contrib/gcc/config/netbsd-elf.h
@@ -2,20 +2,20 @@
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -24,7 +24,6 @@ Boston, MA 02111-1307, USA. */
do \
{ \
NETBSD_OS_CPP_BUILTINS_COMMON(); \
- builtin_define ("__ELF__"); \
} \
while (0)
diff --git a/contrib/gcc/config/netbsd.h b/contrib/gcc/config/netbsd.h
index 044138996212..121dda2fb482 100644
--- a/contrib/gcc/config/netbsd.h
+++ b/contrib/gcc/config/netbsd.h
@@ -2,20 +2,20 @@
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -29,14 +29,6 @@ Boston, MA 02111-1307, USA. */
} \
while (0)
-/* TARGET_OS_CPP_BUILTINS() common to all LP64 NetBSD targets. */
-#define NETBSD_OS_CPP_BUILTINS_LP64() \
- do \
- { \
- builtin_define ("_LP64"); \
- } \
- while (0)
-
/* CPP_SPEC parts common to all NetBSD targets. */
#define NETBSD_CPP_SPEC \
"%{posix:-D_POSIX_SOURCE} \
@@ -189,7 +181,7 @@ Boston, MA 02111-1307, USA. */
/* Attempt to turn on execute permission for the stack. This may be
- used by TRANSFER_FROM_TRAMPOLINE of the target needs it (that is,
+ used by INITIALIZE_TRAMPOLINE of the target needs it (that is,
if the target machine can change execute permissions on a page).
There is no way to query the execute permission of the stack, so
@@ -204,8 +196,7 @@ Boston, MA 02111-1307, USA. */
#define NETBSD_ENABLE_EXECUTE_STACK \
extern void __enable_execute_stack (void *); \
void \
-__enable_execute_stack (addr) \
- void *addr; \
+__enable_execute_stack (void *addr) \
{ \
extern int mprotect (void *, size_t, int); \
extern int __sysctl (int *, unsigned int, void *, size_t *, \
diff --git a/contrib/gcc/config/openbsd-oldgas.h b/contrib/gcc/config/openbsd-oldgas.h
index 823db703e720..423a15c727ae 100644
--- a/contrib/gcc/config/openbsd-oldgas.h
+++ b/contrib/gcc/config/openbsd-oldgas.h
@@ -2,20 +2,20 @@
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/openbsd.h b/contrib/gcc/config/openbsd.h
index 1c215ebbf2d0..670a0a08aa15 100644
--- a/contrib/gcc/config/openbsd.h
+++ b/contrib/gcc/config/openbsd.h
@@ -1,20 +1,20 @@
/* Base configuration file for all OpenBSD targets.
Copyright (C) 1999, 2000 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -106,16 +106,12 @@ Boston, MA 02111-1307, USA. */
still uses a special flavor of gas that needs to be told when generating
pic code. */
#undef ASM_SPEC
-#define ASM_SPEC "%{fpic:-k} %{fPIC:-k -K} %|"
-
-#else
-/* Since we use gas, stdin -> - is a good idea, but we don't want to
- override native specs just for that. */
-#ifndef ASM_SPEC
-#define ASM_SPEC "%|"
-#endif
+#define ASM_SPEC "%{fpic|fpie:-k} %{fPIC|fPIE:-k -K}"
#endif
+/* Since we use gas, stdin -> - is a good idea. */
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
+
/* LINK_SPEC appropriate for OpenBSD. Support for GCC options
-static, -assert, and -nostdlib. */
#undef LINK_SPEC
@@ -134,9 +130,6 @@ Boston, MA 02111-1307, USA. */
/* Runtime target specification. */
-/* You must redefine CPP_PREDEFINES in any arch specific file. */
-#undef CPP_PREDEFINES
-
/* Implicit calls to library routines. */
/* Use memcpy and memset instead of bcopy and bzero. */
diff --git a/contrib/gcc/config/ptx4.h b/contrib/gcc/config/ptx4.h
index 3d8e52785672..33e91d151351 100644
--- a/contrib/gcc/config/ptx4.h
+++ b/contrib/gcc/config/ptx4.h
@@ -1,25 +1,25 @@
-/* Operating system specific defines to be used when targeting GCC for some
- generic System V Release 4 system.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
- Contributed by Ron Guilmette (rfg@monkeys.com).
+/* Operating system specific defines to be used when targeting GCC for
+ Sequent's Dynix/ptx v4 and later.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+ Generic SysV4 file Contributed by Ron Guilmette (rfg@monkeys.com).
Renamed and changed to suit Dynix/ptx v4 and later.
Modified by Tim Wright (timw@sequent.com).
Modified by Janis Johnson (janis@us.ibm.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
@@ -28,11 +28,12 @@ Boston, MA 02111-1307, USA.
/* Define a symbol indicating that we are using svr4.h. */
#define USING_SVR4_H
-/* Use DWARF debugging info by default. */
+/* Use DWARF 2 debugging info by default. */
#undef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+#define DWARF2_DEBUGGING_INFO 1
/* Cpp, assembler, linker, library, and startfile spec's. */
@@ -62,12 +63,6 @@ Boston, MA 02111-1307, USA.
&& strcmp (STR, "Tdata") && strcmp (STR, "Ttext") \
&& strcmp (STR, "Tbss"))
-/* You should redefine CPP_PREDEFINES in any file which includes this one.
- The definition should be appropriate for the type of target system
- involved, and it should include any -A (assertion) options which are
- appropriate for the given target system. */
-#undef CPP_PREDEFINES
-
/* Provide an ASM_SPEC appropriate for svr4. Here we try to support as
many of the specialized svr4 assembler options as seems reasonable,
given that there are certain options which we can't (or shouldn't)
@@ -93,16 +88,7 @@ Boston, MA 02111-1307, USA.
"-no_0f_fix -no_eflags_chk %{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
#endif
-/* svr4 assemblers need the `-' (indicating input from stdin) to come after
- the -o option (and its argument) for some reason. If we try to put it
- before the -o option, the assembler will try to read the file named as
- the output file in the -o option as an input file (after it has already
- written some stuff to it) and the binary stuff contained therein will
- cause totally confuse the assembler, resulting in many spurious error
- messages. */
-
-#undef ASM_FINAL_SPEC
-#define ASM_FINAL_SPEC "%{pipe:-}"
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
/* Provide a LIB_SPEC appropriate for svr4. Here we tack on the default
standard C library (unless we are building a shared library). */
@@ -199,16 +185,14 @@ Boston, MA 02111-1307, USA.
current function. */
#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(file, line) \
+#define ASM_OUTPUT_SOURCE_LINE(file, line, counter) \
do \
{ \
- static int sym_lineno = 1; \
fprintf (file, ".stabn 68,0,%d,.LM%d-", \
- line, sym_lineno); \
+ line, counter); \
assemble_name (file, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
- fprintf (file, "\n.LM%d:\n", sym_lineno); \
- sym_lineno += 1; \
+ fprintf (file, "\n.LM%d:\n", counter); \
} \
while (0)
@@ -246,5 +230,6 @@ while (0)
do { \
fprintf ((FILE), "%s", COMMON_ASM_OP); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u\n", (SIZE)); \
+ fprintf ((FILE), ",%lu\n", (unsigned long)(SIZE)); \
} while (0)
+
diff --git a/contrib/gcc/config/rs6000/40x.md b/contrib/gcc/config/rs6000/40x.md
new file mode 100644
index 000000000000..9d229b4c8d7e
--- /dev/null
+++ b/contrib/gcc/config/rs6000/40x.md
@@ -0,0 +1,107 @@
+;; Scheduling description for IBM PowerPC 403 and PowerPC 405 processors.
+;; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "ppc40x")
+(define_cpu_unit "iu_40x,bpu_40x,fpu_405" "ppc40x")
+
+;; PPC401 / PPC403 / PPC405 32-bit integer only IU BPU
+;; Embedded PowerPC controller
+;; In-order execution
+;; Max issue two insns/cycle (includes one branch)
+(define_insn_reservation "ppc403-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-compare" 3
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x,nothing,bpu_40x")
+
+(define_insn_reservation "ppc403-imul" 4
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "ppc403"))
+ "iu_40x*4")
+
+(define_insn_reservation "ppc405-imul" 5
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "ppc405"))
+ "iu_40x*4")
+
+(define_insn_reservation "ppc405-imul2" 3
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "ppc405"))
+ "iu_40x*2")
+
+(define_insn_reservation "ppc405-imul3" 2
+ (and (eq_attr "type" "imul3")
+ (eq_attr "cpu" "ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-idiv" 33
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x*33")
+
+(define_insn_reservation "ppc403-mfcr" 2
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-mtcr" 3
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-mtjmpr" 4
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "iu_40x")
+
+(define_insn_reservation "ppc403-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "bpu_40x")
+
+(define_insn_reservation "ppc403-cr" 2
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "ppc403,ppc405"))
+ "bpu_40x")
+
+(define_insn_reservation "ppc405-float" 11
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,fpcompare,fp,dmul,sdiv,ddiv")
+ (eq_attr "cpu" "ppc405"))
+ "fpu_405*10")
+
diff --git a/contrib/gcc/config/rs6000/440.md b/contrib/gcc/config/rs6000/440.md
new file mode 100644
index 000000000000..e98d5be782d1
--- /dev/null
+++ b/contrib/gcc/config/rs6000/440.md
@@ -0,0 +1,120 @@
+;; Scheduling description for IBM PowerPC 440 processor.
+;; Copyright (C) 2003 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 2, 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 COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; PPC440 Embedded PowerPC controller
+;; dual issue
+;; i_pipe - complex integer / compare / branch
+;; j_pipe - simple integer arithmetic
+;; l_pipe - load-store
+;; f_pipe - floating point arithmetic
+
+(define_automaton "ppc440_core,ppc440_apu")
+(define_cpu_unit "ppc440_i_pipe,ppc440_j_pipe,ppc440_l_pipe" "ppc440_core")
+(define_cpu_unit "ppc440_f_pipe" "ppc440_apu")
+(define_cpu_unit "ppc440_issue_0,ppc440_issue_1" "ppc440_core")
+
+(define_reservation "ppc440_issue" "ppc440_issue_0|ppc440_issue_1")
+
+
+(define_insn_reservation "ppc440-load" 3
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_l_pipe")
+
+(define_insn_reservation "ppc440-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_l_pipe")
+
+(define_insn_reservation "ppc440-fpload" 4
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_l_pipe")
+
+(define_insn_reservation "ppc440-fpstore" 3
+ (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_l_pipe")
+
+(define_insn_reservation "ppc440-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe|ppc440_j_pipe")
+
+(define_insn_reservation "ppc440-imul" 3
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-imul2" 2
+ (and (eq_attr "type" "imul2,imul3")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-idiv" 34
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe*33")
+
+(define_insn_reservation "ppc440-branch" 1
+ (and (eq_attr "type" "branch,jmpreg")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-compare" 2
+ (and (eq_attr "type" "cmp,fast_compare,compare,cr_logical,delayed_cr,mfcr")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-fpcompare" 3 ; 2
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_f_pipe+ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-fp" 5
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_f_pipe")
+
+(define_insn_reservation "ppc440-sdiv" 19
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_f_pipe*15")
+
+(define_insn_reservation "ppc440-ddiv" 33
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_f_pipe*29")
+
+(define_insn_reservation "ppc440-mtcr" 3
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-mtjmpr" 4
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
+(define_insn_reservation "ppc440-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc440"))
+ "ppc440_issue,ppc440_i_pipe")
+
diff --git a/contrib/gcc/config/rs6000/603.md b/contrib/gcc/config/rs6000/603.md
new file mode 100644
index 000000000000..7ae038e33e08
--- /dev/null
+++ b/contrib/gcc/config/rs6000/603.md
@@ -0,0 +1,127 @@
+;; Scheduling description for PowerPC 603 processor.
+;; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "ppc603,ppc603fp")
+(define_cpu_unit "iu_603" "ppc603")
+(define_cpu_unit "fpu_603" "ppc603fp")
+(define_cpu_unit "lsu_603,bpu_603,sru_603" "ppc603")
+
+;; PPC603/PPC603e 32-bit IU, LSU, FPU, BPU, SRU
+;; Max issue 3 insns/clock cycle (includes 1 branch)
+
+;; Branches go straight to the BPU. All other insns are handled
+;; by a dispatch unit which can issue a max of 2 insns per cycle.
+
+;; The PPC603e user's manual recommends that to reduce branch mispredictions,
+;; the insn that sets CR bits should be separated from the branch insn
+;; that evaluates them; separation by more than 9 insns ensures that the CR
+;; bits will be immediately available for execution.
+;; This could be artificially achieved by exaggerating the latency of
+;; compare insns but at the expense of a poorer schedule.
+
+;; CR insns get executed in the SRU. Not modelled.
+
+(define_insn_reservation "ppc603-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ux,load_u")
+ (eq_attr "cpu" "ppc603"))
+ "lsu_603")
+
+(define_insn_reservation "ppc603-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u,fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "ppc603"))
+ "lsu_603")
+
+(define_insn_reservation "ppc603-fpload" 2
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "ppc603"))
+ "lsu_603")
+
+(define_insn_reservation "ppc603-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "ppc603"))
+ "iu_603")
+
+; This takes 2 or 3 cycles
+(define_insn_reservation "ppc603-imul" 3
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "ppc603"))
+ "iu_603*2")
+
+(define_insn_reservation "ppc603-imul2" 2
+ (and (eq_attr "type" "imul2,imul3")
+ (eq_attr "cpu" "ppc603"))
+ "iu_603*2")
+
+(define_insn_reservation "ppc603-idiv" 37
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc603"))
+ "iu_603*37")
+
+(define_insn_reservation "ppc603-compare" 3
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "ppc603"))
+ "iu_603,nothing,bpu_603")
+
+(define_insn_reservation "ppc603-fpcompare" 3
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc603"))
+ "(fpu_603+iu_603*2),bpu_603")
+
+(define_insn_reservation "ppc603-fp" 3
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "ppc603"))
+ "fpu_603")
+
+(define_insn_reservation "ppc603-dmul" 4
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "ppc603"))
+ "fpu_603*2")
+
+; Divides are not pipelined
+(define_insn_reservation "ppc603-sdiv" 18
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc603"))
+ "fpu_603*18")
+
+(define_insn_reservation "ppc603-ddiv" 33
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc603"))
+ "fpu_603*33")
+
+(define_insn_reservation "ppc603-crlogical" 2
+ (and (eq_attr "type" "cr_logical,delayed_cr,mfcr,mtcr")
+ (eq_attr "cpu" "ppc603"))
+ "sru_603")
+
+(define_insn_reservation "ppc603-mtjmpr" 4
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc603"))
+ "sru_603")
+
+(define_insn_reservation "ppc603-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc603"))
+ "sru_603")
+
+(define_insn_reservation "ppc603-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "ppc603"))
+ "bpu_603")
+
diff --git a/contrib/gcc/config/rs6000/6xx.md b/contrib/gcc/config/rs6000/6xx.md
new file mode 100644
index 000000000000..d28d3738bb79
--- /dev/null
+++ b/contrib/gcc/config/rs6000/6xx.md
@@ -0,0 +1,234 @@
+;; Scheduling description for PowerPC 604, PowerPC 604e, PowerPC 620,
+;; and PowerPC 630 processors.
+;; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "ppc6xx,ppc6xxfp,ppc6xxfp2")
+(define_cpu_unit "iu1_6xx,iu2_6xx,mciu_6xx" "ppc6xx")
+(define_cpu_unit "fpu_6xx" "ppc6xxfp")
+(define_cpu_unit "fpu1_6xx,fpu2_6xx" "ppc6xxfp2")
+(define_cpu_unit "lsu_6xx,bpu_6xx,cru_6xx" "ppc6xx")
+
+;; PPC604 32-bit 2xSCIU, MCIU, LSU, FPU, BPU
+;; PPC604e 32-bit 2xSCIU, MCIU, LSU, FPU, BPU, CRU
+;; MCIU used for imul/idiv and moves from/to spr
+;; LSU 2 stage pipelined
+;; FPU 3 stage pipelined
+;; Max issue 4 insns/clock cycle
+
+;; PPC604e is PPC604 with larger caches and a CRU. In the 604
+;; the CR logical operations are handled in the BPU.
+;; In the 604e, the CRU shares bus with BPU so only one condition
+;; register or branch insn can be issued per clock. Not modelled.
+
+;; PPC620 64-bit 2xSCIU, MCIU, LSU, FPU, BPU, CRU
+;; PPC630 64-bit 2xSCIU, MCIU, LSU, 2xFPU, BPU, CRU
+;; Max issue 4 insns/clock cycle
+;; Out-of-order execution, in-order completion
+
+;; No following instruction can dispatch in the same cycle as a branch
+;; instruction. Not modelled. This is no problem if RCSP is not
+;; enabled since the scheduler stops a schedule when it gets to a branch.
+
+;; Four insns can be dispatched per cycle.
+
+(define_insn_reservation "ppc604-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "lsu_6xx")
+
+(define_insn_reservation "ppc604-fpload" 3
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "lsu_6xx")
+
+(define_insn_reservation "ppc604-store" 1
+ (and (eq_attr "type" "store,fpstore,store_ux,store_u,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "lsu_6xx")
+
+(define_insn_reservation "ppc604-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "iu1_6xx|iu2_6xx")
+
+(define_insn_reservation "ppc604-imul" 4
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "ppc604"))
+ "mciu_6xx*2")
+
+(define_insn_reservation "ppc604e-imul" 2
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "ppc604e"))
+ "mciu_6xx")
+
+(define_insn_reservation "ppc620-imul" 5
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "mciu_6xx*3")
+
+(define_insn_reservation "ppc620-imul2" 4
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "mciu_6xx*3")
+
+(define_insn_reservation "ppc620-imul3" 3
+ (and (eq_attr "type" "imul3")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "mciu_6xx*3")
+
+(define_insn_reservation "ppc620-lmul" 7
+ (and (eq_attr "type" "lmul,lmul_compare")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "mciu_6xx*5")
+
+(define_insn_reservation "ppc604-idiv" 20
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc604,ppc604e"))
+ "mciu_6xx*19")
+
+(define_insn_reservation "ppc620-idiv" 37
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc620"))
+ "mciu_6xx*36")
+
+(define_insn_reservation "ppc630-idiv" 21
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc630"))
+ "mciu_6xx*20")
+
+(define_insn_reservation "ppc620-ldiv" 37
+ (and (eq_attr "type" "ldiv")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "mciu_6xx*36")
+
+(define_insn_reservation "ppc604-compare" 3
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "(iu1_6xx|iu2_6xx)")
+
+; FPU PPC604{,e},PPC620
+(define_insn_reservation "ppc604-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ "fpu_6xx")
+
+(define_insn_reservation "ppc604-fp" 3
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ "fpu_6xx")
+
+(define_insn_reservation "ppc604-dmul" 3
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ "fpu_6xx")
+
+; Divides are not pipelined
+(define_insn_reservation "ppc604-sdiv" 18
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ "fpu_6xx*18")
+
+(define_insn_reservation "ppc604-ddiv" 32
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ "fpu_6xx*32")
+
+(define_insn_reservation "ppc620-ssqrt" 31
+ (and (eq_attr "type" "ssqrt")
+ (eq_attr "cpu" "ppc620"))
+ "fpu_6xx*31")
+
+(define_insn_reservation "ppc620-dsqrt" 31
+ (and (eq_attr "type" "dsqrt")
+ (eq_attr "cpu" "ppc620"))
+ "fpu_6xx*31")
+
+
+; 2xFPU PPC630
+(define_insn_reservation "ppc630-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc630"))
+ "fpu1_6xx|fpu2_6xx")
+
+(define_insn_reservation "ppc630-fp" 3
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "ppc630"))
+ "fpu1_6xx|fpu2_6xx")
+
+(define_insn_reservation "ppc630-sdiv" 17
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc630"))
+ "fpu1_6xx*17|fpu2_6xx*17")
+
+(define_insn_reservation "ppc630-ddiv" 21
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc630"))
+ "fpu1_6xx*21|fpu2_6xx*21")
+
+(define_insn_reservation "ppc630-ssqrt" 18
+ (and (eq_attr "type" "ssqrt")
+ (eq_attr "cpu" "ppc630"))
+ "fpu1_6xx*18|fpu2_6xx*18")
+
+(define_insn_reservation "ppc630-dsqrt" 25
+ (and (eq_attr "type" "dsqrt")
+ (eq_attr "cpu" "ppc630"))
+ "fpu1_6xx*25|fpu2_6xx*25")
+
+(define_insn_reservation "ppc604-mfcr" 3
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "mciu_6xx")
+
+(define_insn_reservation "ppc604-mtcr" 2
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "iu1_6xx|iu2_6xx")
+
+(define_insn_reservation "ppc604-crlogical" 2
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "ppc604"))
+ "bpu_6xx")
+
+(define_insn_reservation "ppc604e-crlogical" 2
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "ppc604e,ppc620,ppc630"))
+ "cru_6xx")
+
+(define_insn_reservation "ppc604-mtjmpr" 2
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "mciu_6xx")
+
+(define_insn_reservation "ppc604-mfjmpr" 3
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620"))
+ "mciu_6xx")
+
+(define_insn_reservation "ppc630-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc630"))
+ "mciu_6xx")
+
+(define_insn_reservation "ppc604-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
+ "bpu_6xx")
+
diff --git a/contrib/gcc/config/rs6000/7450.md b/contrib/gcc/config/rs6000/7450.md
new file mode 100644
index 000000000000..55bd4d863686
--- /dev/null
+++ b/contrib/gcc/config/rs6000/7450.md
@@ -0,0 +1,162 @@
+;; Scheduling description for Motorola PowerPC 7450 processor.
+;; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "ppc7450,ppc7450fp,ppc7450vec")
+(define_cpu_unit "iu1_7450,iu2_7450,iu3_7450,mciu_7450" "ppc7450")
+(define_cpu_unit "fpu_7450" "ppc7450fp")
+(define_cpu_unit "lsu_7450,bpu_7450" "ppc7450")
+(define_cpu_unit "du1_7450,du2_7450,du3_7450" "ppc7450")
+(define_cpu_unit "vecsmpl_7450,veccmplx_7450,vecflt_7450,vecperm_7450" "ppc7450vec")
+(define_cpu_unit "vdu1_7450,vdu2_7450" "ppc7450vec")
+
+
+;; PPC7450 32-bit 3xIU, MCIU, LSU, SRU, FPU, BPU, 4xVEC
+;; IU1,IU2,IU3 can perform all integer operations
+;; MCIU performs imul and idiv, cr logical, SPR moves
+;; LSU 2 stage pipelined
+;; FPU 3 stage pipelined
+;; It also has 4 vector units, one for each type of vector instruction.
+;; However, we can only dispatch 2 instructions per cycle.
+;; Max issue 3 insns/clock cycle (includes 1 branch)
+;; In-order execution
+
+;; Branches go straight to the BPU. All other insns are handled
+;; by a dispatch unit which can issue a max of 3 insns per cycle.
+(define_reservation "ppc7450_du" "du1_7450|du2_7450|du3_7450")
+(define_reservation "ppc7450_vec_du" "vdu1_7450|vdu2_7450")
+
+(define_insn_reservation "ppc7450-load" 3
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,\
+ load_ux,load_u,vecload")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,lsu_7450")
+
+(define_insn_reservation "ppc7450-store" 3
+ (and (eq_attr "type" "store,store_ux,store_u,vecstore")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,lsu_7450")
+
+(define_insn_reservation "ppc7450-fpload" 4
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,lsu_7450")
+
+(define_insn_reservation "ppc7450-fpstore" 3
+ (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,lsu_7450*3")
+
+(define_insn_reservation "ppc7450-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,(iu1_7450|iu2_7450|iu3_7450)")
+
+(define_insn_reservation "ppc7450-imul" 4
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,mciu_7450*2")
+
+(define_insn_reservation "ppc7450-imul2" 3
+ (and (eq_attr "type" "imul2,imul3")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,mciu_7450")
+
+(define_insn_reservation "ppc7450-idiv" 23
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,mciu_7450*23")
+
+(define_insn_reservation "ppc7450-compare" 2
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,(iu1_7450|iu2_7450|iu3_7450)")
+
+(define_insn_reservation "ppc7450-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,fpu_7450")
+
+(define_insn_reservation "ppc7450-fp" 5
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,fpu_7450")
+
+; Divides are not pipelined
+(define_insn_reservation "ppc7450-sdiv" 21
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,fpu_7450*21")
+
+(define_insn_reservation "ppc7450-ddiv" 35
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,fpu_7450*35")
+
+(define_insn_reservation "ppc7450-mfcr" 2
+ (and (eq_attr "type" "mfcr,mtcr")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,mciu_7450")
+
+(define_insn_reservation "ppc7450-crlogical" 1
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,mciu_7450")
+
+(define_insn_reservation "ppc7450-mtjmpr" 2
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc7450"))
+ "nothing,mciu_7450*2")
+
+(define_insn_reservation "ppc7450-mfjmpr" 3
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc7450"))
+ "nothing,mciu_7450*2")
+
+(define_insn_reservation "ppc7450-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "ppc7450"))
+ "nothing,bpu_7450")
+
+;; Altivec
+(define_insn_reservation "ppc7450-vecsimple" 1
+ (and (eq_attr "type" "vecsimple")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,ppc7450_vec_du,vecsmpl_7450")
+
+(define_insn_reservation "ppc7450-veccomplex" 4
+ (and (eq_attr "type" "veccomplex")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,ppc7450_vec_du,veccmplx_7450")
+
+(define_insn_reservation "ppc7450-veccmp" 2
+ (and (eq_attr "type" "veccmp")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,ppc7450_vec_du,veccmplx_7450")
+
+(define_insn_reservation "ppc7450-vecfloat" 4
+ (and (eq_attr "type" "vecfloat")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,ppc7450_vec_du,vecflt_7450")
+
+(define_insn_reservation "ppc7450-vecperm" 2
+ (and (eq_attr "type" "vecperm")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,ppc7450_vec_du,vecperm_7450")
+
diff --git a/contrib/gcc/config/rs6000/7xx.md b/contrib/gcc/config/rs6000/7xx.md
new file mode 100644
index 000000000000..de8a7b7552de
--- /dev/null
+++ b/contrib/gcc/config/rs6000/7xx.md
@@ -0,0 +1,167 @@
+;; Scheduling description for Motorola PowerPC 750 and PowerPC 7400 processors.
+;; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "ppc7xx,ppc7xxfp")
+(define_cpu_unit "iu1_7xx,iu2_7xx" "ppc7xx")
+(define_cpu_unit "fpu_7xx" "ppc7xxfp")
+(define_cpu_unit "lsu_7xx,bpu_7xx,sru_7xx" "ppc7xx")
+(define_cpu_unit "du1_7xx,du2_7xx" "ppc7xx")
+(define_cpu_unit "veccmplx_7xx,vecperm_7xx,vdu_7xx" "ppc7xx")
+
+;; PPC740/PPC750/PPC7400 32-bit 2xIU, LSU, SRU, FPU, BPU
+;; IU1 can perform all integer operations
+;; IU2 can perform all integer operations except imul and idiv
+;; LSU 2 stage pipelined
+;; FPU 3 stage pipelined
+;; Max issue 3 insns/clock cycle (includes 1 branch)
+;; In-order execution
+
+
+;; The PPC750 user's manual recommends that to reduce branch mispredictions,
+;; the insn that sets CR bits should be separated from the branch insn
+;; that evaluates them. There is no advantage have more than 10 cycles
+;; of separation.
+;; This could be artificially achieved by exaggerating the latency of
+;; compare insns but at the expense of a poorer schedule.
+
+;; Branches go straight to the BPU. All other insns are handled
+;; by a dispatch unit which can issue a max of 2 insns per cycle.
+(define_reservation "ppc750_du" "du1_7xx|du2_7xx")
+(define_reservation "ppc7400_vec_du" "vdu_7xx")
+
+(define_insn_reservation "ppc750-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,\
+ load_ux,load_u,fpload,fpload_ux,fpload_u,vecload")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,lsu_7xx")
+
+(define_insn_reservation "ppc750-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u,\
+ fpstore,fpstore_ux,fpstore_u,vecstore")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,lsu_7xx")
+
+(define_insn_reservation "ppc750-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,(iu1_7xx|iu2_7xx)")
+
+(define_insn_reservation "ppc750-imul" 4
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,iu1_7xx*4")
+
+(define_insn_reservation "ppc750-imul2" 3
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,iu1_7xx*2")
+
+(define_insn_reservation "ppc750-imul3" 2
+ (and (eq_attr "type" "imul3")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,iu1_7xx")
+
+(define_insn_reservation "ppc750-idiv" 19
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,iu1_7xx*19")
+
+(define_insn_reservation "ppc750-compare" 2
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,(iu1_7xx|iu2_7xx)")
+
+(define_insn_reservation "ppc750-fpcompare" 2
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,fpu_7xx")
+
+(define_insn_reservation "ppc750-fp" 3
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,fpu_7xx")
+
+(define_insn_reservation "ppc750-dmul" 4
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "ppc750"))
+ "ppc750_du,fpu_7xx*2")
+
+(define_insn_reservation "ppc7400-dmul" 3
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "ppc7400"))
+ "ppc750_du,fpu_7xx")
+
+; Divides are not pipelined
+(define_insn_reservation "ppc750-sdiv" 17
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,fpu_7xx*17")
+
+(define_insn_reservation "ppc750-ddiv" 31
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,fpu_7xx*31")
+
+(define_insn_reservation "ppc750-mfcr" 2
+ (and (eq_attr "type" "mfcr,mtcr")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,iu1_7xx")
+
+(define_insn_reservation "ppc750-crlogical" 3
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,sru_7xx*2")
+
+(define_insn_reservation "ppc750-mtjmpr" 2
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "nothing,sru_7xx*2")
+
+(define_insn_reservation "ppc750-mfjmpr" 3
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "nothing,sru_7xx*2")
+
+(define_insn_reservation "ppc750-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "nothing,bpu_7xx")
+
+;; Altivec
+(define_insn_reservation "ppc7400-vecsimple" 1
+ (and (eq_attr "type" "vecsimple,veccmp")
+ (eq_attr "cpu" "ppc7400"))
+ "ppc750_du,ppc7400_vec_du,veccmplx_7xx")
+
+(define_insn_reservation "ppc7400-veccomplex" 4
+ (and (eq_attr "type" "veccomplex")
+ (eq_attr "cpu" "ppc7400"))
+ "ppc750_du,ppc7400_vec_du,veccmplx_7xx")
+
+(define_insn_reservation "ppc7400-vecfloat" 4
+ (and (eq_attr "type" "vecfloat")
+ (eq_attr "cpu" "ppc7400"))
+ "ppc750_du,ppc7400_vec_du,veccmplx_7xx")
+
+(define_insn_reservation "ppc7400-vecperm" 2
+ (and (eq_attr "type" "vecperm")
+ (eq_attr "cpu" "ppc7400"))
+ "ppc750_du,ppc7400_vec_du,vecperm_7xx")
+
diff --git a/contrib/gcc/config/rs6000/8540.md b/contrib/gcc/config/rs6000/8540.md
new file mode 100644
index 000000000000..737c39958978
--- /dev/null
+++ b/contrib/gcc/config/rs6000/8540.md
@@ -0,0 +1,235 @@
+;; Pipeline description for Motorola PowerPC 8540 processor.
+;; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "ppc8540_most,ppc8540_long,ppc8540_retire")
+(define_cpu_unit "ppc8540_decode_0,ppc8540_decode_1" "ppc8540_most")
+
+;; We don't simulate general issue queue (GIC). If we have SU insn
+;; and then SU1 insn, they can not be issued on the same cycle
+;; (although SU1 insn and then SU insn can be issued) because the SU
+;; insn will go to SU1 from GIC0 entry. Fortunately, the first cycle
+;; multipass insn scheduling will find the situation and issue the SU1
+;; insn and then the SU insn.
+(define_cpu_unit "ppc8540_issue_0,ppc8540_issue_1" "ppc8540_most")
+
+;; We could describe completion buffers slots in combination with the
+;; retirement units and the order of completion but the result
+;; automaton would behave in the same way because we can not describe
+;; real latency time with taking in order completion into account.
+;; Actually we could define the real latency time by querying reserved
+;; automaton units but the current scheduler uses latency time before
+;; issuing insns and making any reservations.
+;;
+;; So our description is aimed to achieve a insn schedule in which the
+;; insns would not wait in the completion buffer.
+(define_cpu_unit "ppc8540_retire_0,ppc8540_retire_1" "ppc8540_retire")
+
+;; Branch unit:
+(define_cpu_unit "ppc8540_bu" "ppc8540_most")
+
+;; SU:
+(define_cpu_unit "ppc8540_su0_stage0,ppc8540_su1_stage0" "ppc8540_most")
+
+;; We could describe here MU subunits for float multiply, float add
+;; etc. But the result automaton would behave the same way as the
+;; described one pipeline below because MU can start only one insn
+;; per cycle. Actually we could simplify the automaton more not
+;; describing stages 1-3, the result automata would be the same.
+(define_cpu_unit "ppc8540_mu_stage0,ppc8540_mu_stage1" "ppc8540_most")
+(define_cpu_unit "ppc8540_mu_stage2,ppc8540_mu_stage3" "ppc8540_most")
+
+;; The following unit is used to describe non-pipelined division.
+(define_cpu_unit "ppc8540_mu_div" "ppc8540_long")
+
+;; Here we simplified LSU unit description not describing the stages.
+(define_cpu_unit "ppc8540_lsu" "ppc8540_most")
+
+;; The following units are used to make automata deterministic
+(define_cpu_unit "present_ppc8540_decode_0" "ppc8540_most")
+(define_cpu_unit "present_ppc8540_issue_0" "ppc8540_most")
+(define_cpu_unit "present_ppc8540_retire_0" "ppc8540_retire")
+(define_cpu_unit "present_ppc8540_su0_stage0" "ppc8540_most")
+
+;; The following sets to make automata deterministic when option ndfa is used.
+(presence_set "present_ppc8540_decode_0" "ppc8540_decode_0")
+(presence_set "present_ppc8540_issue_0" "ppc8540_issue_0")
+(presence_set "present_ppc8540_retire_0" "ppc8540_retire_0")
+(presence_set "present_ppc8540_su0_stage0" "ppc8540_su0_stage0")
+
+;; Some useful abbreviations.
+(define_reservation "ppc8540_decode"
+ "ppc8540_decode_0|ppc8540_decode_1+present_ppc8540_decode_0")
+(define_reservation "ppc8540_issue"
+ "ppc8540_issue_0|ppc8540_issue_1+present_ppc8540_issue_0")
+(define_reservation "ppc8540_retire"
+ "ppc8540_retire_0|ppc8540_retire_1+present_ppc8540_retire_0")
+(define_reservation "ppc8540_su_stage0"
+ "ppc8540_su0_stage0|ppc8540_su1_stage0+present_ppc8540_su0_stage0")
+
+;; Simple SU insns
+(define_insn_reservation "ppc8540_su" 1
+ (and (eq_attr "type" "integer,insert_word,cmp,compare,delayed_compare,fast_compare")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
+
+;; Branch. Actually this latency time is not used by the scheduler.
+(define_insn_reservation "ppc8540_branch" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_bu,ppc8540_retire")
+
+;; Multiply
+(define_insn_reservation "ppc8540_multiply" 4
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\
+ ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire")
+
+;; Divide. We use the average latency time here. We omit reserving a
+;; retire unit because of the result automata will be huge. We ignore
+;; reservation of miu_stage3 here because we use the average latency
+;; time.
+(define_insn_reservation "ppc8540_divide" 14
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0+ppc8540_mu_div,\
+ ppc8540_mu_div*13")
+
+;; CR logical
+(define_insn_reservation "ppc8540_cr_logical" 1
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_bu,ppc8540_retire")
+
+;; Mfcr
+(define_insn_reservation "ppc8540_mfcr" 1
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
+
+;; Mtcrf
+(define_insn_reservation "ppc8540_mtcrf" 1
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
+
+;; Mtjmpr
+(define_insn_reservation "ppc8540_mtjmpr" 1
+ (and (eq_attr "type" "mtjmpr,mfjmpr")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
+
+;; Loads
+(define_insn_reservation "ppc8540_load" 3
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
+
+;; Stores.
+(define_insn_reservation "ppc8540_store" 3
+ (and (eq_attr "type" "store,store_ux,store_u")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
+
+;; Simple FP
+(define_insn_reservation "ppc8540_simple_float" 1
+ (and (eq_attr "type" "fpsimple")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
+
+;; FP
+(define_insn_reservation "ppc8540_float" 4
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\
+ ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire")
+
+;; float divides. We omit reserving a retire unit and miu_stage3
+;; because of the result automata will be huge.
+(define_insn_reservation "ppc8540_float_vector_divide" 29
+ (and (eq_attr "type" "vecfdiv")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0+ppc8540_mu_div,\
+ ppc8540_mu_div*28")
+
+;; Brinc
+(define_insn_reservation "ppc8540_brinc" 1
+ (and (eq_attr "type" "brinc")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
+
+;; Simple vector
+(define_insn_reservation "ppc8540_simple_vector" 1
+ (and (eq_attr "type" "vecsimple")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
+
+;; Simple vector compare
+(define_insn_reservation "ppc8540_simple_vector_compare" 1
+ (and (eq_attr "type" "veccmpsimple")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su_stage0+ppc8540_retire")
+
+;; Vector compare
+(define_insn_reservation "ppc8540_vector_compare" 1
+ (and (eq_attr "type" "veccmp")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
+
+;; evsplatfi evsplati
+(define_insn_reservation "ppc8540_vector_perm" 1
+ (and (eq_attr "type" "vecperm")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_su1_stage0+ppc8540_retire")
+
+;; Vector float
+(define_insn_reservation "ppc8540_float_vector" 4
+ (and (eq_attr "type" "vecfloat")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\
+ ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire")
+
+;; Vector divides: Use the average. We omit reserving a retire unit
+;; because of the result automata will be huge. We ignore reservation
+;; of miu_stage3 here because we use the average latency time.
+(define_insn_reservation "ppc8540_vector_divide" 14
+ (and (eq_attr "type" "vecdiv")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0+ppc8540_mu_div,\
+ ppc8540_mu_div*13")
+
+;; Complex vector.
+(define_insn_reservation "ppc8540_complex_vector" 4
+ (and (eq_attr "type" "veccomplex")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_mu_stage0,ppc8540_mu_stage1,\
+ ppc8540_mu_stage2,ppc8540_mu_stage3+ppc8540_retire")
+
+;; Vector load
+(define_insn_reservation "ppc8540_vector_load" 3
+ (and (eq_attr "type" "vecload")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
+
+;; Vector store
+(define_insn_reservation "ppc8540_vector_store" 3
+ (and (eq_attr "type" "vecstore")
+ (eq_attr "cpu" "ppc8540"))
+ "ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
diff --git a/contrib/gcc/config/rs6000/aix.h b/contrib/gcc/config/rs6000/aix.h
index 505d758c612d..f189407b3f48 100644
--- a/contrib/gcc/config/rs6000/aix.h
+++ b/contrib/gcc/config/rs6000/aix.h
@@ -1,23 +1,23 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Yes! We are AIX! */
#define DEFAULT_ABI ABI_AIX
@@ -87,8 +87,8 @@ Boston, MA 02111-1307, USA. */
Don't do this until the fixed IBM assembler is more generally available.
When this becomes permanently defined, the ASM_OUTPUT_EXTERNAL,
ASM_OUTPUT_EXTERNAL_LIBCALL, and RS6000_OUTPUT_BASENAME macros will no
- longer be needed. Also, the extern declaration of mcount in ASM_FILE_START
- will no longer be needed. */
+ longer be needed. Also, the extern declaration of mcount in
+ rs6000_xcoff_file_start will no longer be needed. */
/* #define ASM_SPEC "-u %(asm_cpu)" */
@@ -128,24 +128,48 @@ Boston, MA 02111-1307, USA. */
#define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
%{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
+/* This now supports a natural alignment mode. */
/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
+ (TARGET_ALIGN_NATURAL ? (COMPUTED) : \
(TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
? get_inner_array_type (FIELD) \
: TREE_TYPE (FIELD)) == DFmode \
- ? MIN ((COMPUTED), 32) : (COMPUTED))
+ ? MIN ((COMPUTED), 32) : (COMPUTED)))
/* AIX increases natural record alignment to doubleword if the first
field is an FP double while the FP fields remain word aligned. */
-#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
- ((TREE_CODE (STRUCT) == RECORD_TYPE \
- || TREE_CODE (STRUCT) == UNION_TYPE \
- || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
- && TYPE_FIELDS (STRUCT) != 0 \
- && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
+#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
+ ((TREE_CODE (STRUCT) == RECORD_TYPE \
+ || TREE_CODE (STRUCT) == UNION_TYPE \
+ || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
+ && TARGET_ALIGN_NATURAL == 0 \
+ ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \
: MAX ((COMPUTED), (SPECIFIED)))
+/* The AIX ABI isn't explicit on whether aggregates smaller than a
+ word/doubleword should be padded upward or downward. One could
+ reasonably assume that they follow the normal rules for structure
+ layout treating the parameter area as any other block of memory,
+ then map the reg param area to registers, i.e., pad upward, which
+ is the way IBM Compilers for AIX behave.
+ Setting both of the following defines results in this behavior. */
+#define AGGREGATE_PADDING_FIXED 1
+#define AGGREGATES_PAD_UPWARD_ALWAYS 1
+
+/* We don't want anything in the reg parm area being passed on the
+ stack. */
+#define MUST_PASS_IN_STACK(MODE, TYPE) \
+ ((TYPE) != 0 \
+ && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
+ || TREE_ADDRESSABLE (TYPE)))
+
+/* Specify padding for the last element of a block move between
+ registers and memory. FIRST is nonzero if this is the only
+ element. */
+#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
+ (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
+
/* Indicate that jump tables go in the text section. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
@@ -172,41 +196,51 @@ Boston, MA 02111-1307, USA. */
/* Define cutoff for using external functions to save floating point. */
#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
-/* Optabs entries for the int->float routines and quad FP operations
- using the standard AIX names. */
-#define ADDTF3_LIBCALL "_xlqadd"
-#define DIVTF3_LIBCALL "_xlqdiv"
-#define MULTF3_LIBCALL "_xlqmul"
-#define SUBTF3_LIBCALL "_xlqsub"
+/* __throw will restore its own return address to be the same as the
+ return address of the function that the throw is being made to.
+ This is unfortunate, because we want to check the original
+ return address to see if we need to restore the TOC.
+ So we have to squirrel it away with this. */
+#define SETUP_FRAME_ADDRESSES() rs6000_aix_emit_builtin_unwind_init ()
+
+/* If the current unwind info (FS) does not contain explicit info
+ saving R2, then we have to do a minor amount of code reading to
+ figure out if it was saved. The big problem here is that the
+ code that does the save/restore is generated by the linker, so
+ we have no good way to determine at compile time what to do. */
-#define INIT_TARGET_OPTABS \
+#ifdef __powerpc64__
+#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \
do { \
- if (! TARGET_POWER2 && ! TARGET_POWERPC && TARGET_HARD_FLOAT) \
+ if ((FS)->regs.reg[2].how == REG_UNSAVED) \
{ \
- fixdfsi_libfunc = init_one_libfunc (RS6000_ITRUNC); \
- fixunsdfsi_libfunc = init_one_libfunc (RS6000_UITRUNC); \
+ unsigned int *insn \
+ = (unsigned int *) \
+ _Unwind_GetGR ((CTX), LINK_REGISTER_REGNUM); \
+ if (*insn == 0xE8410028) \
+ _Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 40); \
} \
- if (TARGET_HARD_FLOAT) \
+ } while (0)
+#else
+#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \
+ do { \
+ if ((FS)->regs.reg[2].how == REG_UNSAVED) \
{ \
- add_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (ADDTF3_LIBCALL); \
- sub_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (SUBTF3_LIBCALL); \
- smul_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (MULTF3_LIBCALL); \
- sdiv_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (DIVTF3_LIBCALL); \
+ unsigned int *insn \
+ = (unsigned int *) \
+ _Unwind_GetGR ((CTX), LINK_REGISTER_REGNUM); \
+ if (*insn == 0x80410014) \
+ _Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 20); \
} \
} while (0)
-
-/* __throw will restore its own return address to be the same as the
- return address of the function that the throw is being made to.
- This is unfortunate, because we want to check the original
- return address to see if we need to restore the TOC.
- So we have to squirrel it away with this. */
-#define SETUP_FRAME_ADDRESSES() rs6000_aix_emit_builtin_unwind_init ()
+#endif
#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL)
/* Print subsidiary information on the compiler version in use. */
#define TARGET_VERSION ;
+
+/* No version of AIX fully supports AltiVec or 64-bit instructions in
+ 32-bit mode. */
+#define OS_MISSING_POWERPC64 1
+#define OS_MISSING_ALTIVEC 1
diff --git a/contrib/gcc/config/rs6000/aix41.h b/contrib/gcc/config/rs6000/aix41.h
index 7f23a48a4a9b..373c10c22ffa 100644
--- a/contrib/gcc/config/rs6000/aix41.h
+++ b/contrib/gcc/config/rs6000/aix41.h
@@ -1,26 +1,25 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX version 4.1.
- Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003
Free Software Foundation, Inc.
Contributed by David Edelsohn (edelsohn@gnu.org).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#undef SUBSUBTARGET_SWITCHES
#define SUBSUBTARGET_SWITCHES \
diff --git a/contrib/gcc/config/rs6000/aix43.h b/contrib/gcc/config/rs6000/aix43.h
index bcbfcf2b2574..a76e694c1ee7 100644
--- a/contrib/gcc/config/rs6000/aix43.h
+++ b/contrib/gcc/config/rs6000/aix43.h
@@ -1,25 +1,24 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX version 4.3.
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by David Edelsohn (edelsohn@gnu.org).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* AIX 4.3 and above support 64-bit executables. */
#undef SUBSUBTARGET_SWITCHES
@@ -60,9 +59,9 @@ do { \
} while (0);
#undef ASM_SPEC
-#define ASM_SPEC "-u %{maix64:-a64 -mppc64} %(asm_cpu)"
+#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)"
-/* Common ASM definitions used by ASM_SPEC amonst the various targets
+/* Common ASM definitions used by ASM_SPEC amongst the various targets
for handling -mcpu=xxx switches. */
#undef ASM_CPU_SPEC
#define ASM_CPU_SPEC \
@@ -75,8 +74,8 @@ do { \
%{mcpu=common: -mcom} \
%{mcpu=power: -mpwr} \
%{mcpu=power2: -mpwr2} \
-%{mcpu=power3: -m604} \
-%{mcpu=power4: -m604} \
+%{mcpu=power3: -m620} \
+%{mcpu=power4: -m620} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
@@ -90,8 +89,8 @@ do { \
%{mcpu=603e: -m603} \
%{mcpu=604: -m604} \
%{mcpu=604e: -m604} \
-%{mcpu=620: -mppc} \
-%{mcpu=630: -m604}"
+%{mcpu=620: -m620} \
+%{mcpu=630: -m620}"
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
diff --git a/contrib/gcc/config/rs6000/aix51.h b/contrib/gcc/config/rs6000/aix51.h
index 552394e2635c..278b6a4c32a8 100644
--- a/contrib/gcc/config/rs6000/aix51.h
+++ b/contrib/gcc/config/rs6000/aix51.h
@@ -1,25 +1,24 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX V5.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by David Edelsohn (edelsohn@gnu.org).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* AIX V5 and above support 64-bit executables. */
#undef SUBSUBTARGET_SWITCHES
@@ -60,9 +59,9 @@ do { \
} while (0);
#undef ASM_SPEC
-#define ASM_SPEC "-u %{maix64:-a64 -mppc64} %(asm_cpu)"
+#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)"
-/* Common ASM definitions used by ASM_SPEC amonst the various targets
+/* Common ASM definitions used by ASM_SPEC amongst the various targets
for handling -mcpu=xxx switches. */
#undef ASM_CPU_SPEC
#define ASM_CPU_SPEC \
@@ -75,8 +74,8 @@ do { \
%{mcpu=common: -mcom} \
%{mcpu=power: -mpwr} \
%{mcpu=power2: -mpwr2} \
-%{mcpu=power3: -m604} \
-%{mcpu=power4: -m604} \
+%{mcpu=power3: -m620} \
+%{mcpu=power4: -m620} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
@@ -90,8 +89,8 @@ do { \
%{mcpu=603e: -m603} \
%{mcpu=604: -m604} \
%{mcpu=604e: -m604} \
-%{mcpu=620: -mppc} \
-%{mcpu=630: -m604}"
+%{mcpu=620: -m620} \
+%{mcpu=630: -m620}"
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mcom"
@@ -197,3 +196,8 @@ do { \
#undef LD_INIT_SWITCH
#define LD_INIT_SWITCH "-binitfini"
+
+/* AIX 5.1 has the float and long double forms of math functions. */
+#undef TARGET_C99_FUNCTIONS
+#define TARGET_C99_FUNCTIONS 1
+
diff --git a/contrib/gcc/config/rs6000/aix52.h b/contrib/gcc/config/rs6000/aix52.h
index b61cc3057e25..c06665066b31 100644
--- a/contrib/gcc/config/rs6000/aix52.h
+++ b/contrib/gcc/config/rs6000/aix52.h
@@ -1,25 +1,24 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 POWER running AIX V5.2.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by David Edelsohn (edelsohn@gnu.org).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* AIX V5 and above support 64-bit executables. */
#undef SUBSUBTARGET_SWITCHES
@@ -60,25 +59,25 @@ do { \
} while (0);
#undef ASM_SPEC
-#define ASM_SPEC "-u %{maix64:-a64 -mppc64} %(asm_cpu)"
+#define ASM_SPEC "-u %{maix64:-a64 %{!mcpu*:-mppc64}} %(asm_cpu)"
-/* Common ASM definitions used by ASM_SPEC amonst the various targets
+/* Common ASM definitions used by ASM_SPEC amongst the various targets
for handling -mcpu=xxx switches. */
#undef ASM_CPU_SPEC
#define ASM_CPU_SPEC \
"%{!mcpu*: %{!maix64: \
%{mpowerpc64: -mppc64} \
%{!mpower64: %(asm_default)}}} \
-%{mcpu=power3: -m604} \
-%{mcpu=power4: -m604} \
+%{mcpu=power3: -m620} \
+%{mcpu=power4: -m620} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rs64a: -mppc} \
%{mcpu=603: -m603} \
%{mcpu=603e: -m603} \
%{mcpu=604: -m604} \
%{mcpu=604e: -m604} \
-%{mcpu=620: -mppc} \
-%{mcpu=630: -m604}"
+%{mcpu=620: -m620} \
+%{mcpu=630: -m620}"
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mppc"
@@ -189,3 +188,8 @@ do { \
#undef LD_INIT_SWITCH
#define LD_INIT_SWITCH "-binitfini"
+
+/* AIX 5.2 has the float and long double forms of math functions. */
+#undef TARGET_C99_FUNCTIONS
+#define TARGET_C99_FUNCTIONS 1
+
diff --git a/contrib/gcc/config/rs6000/altivec-defs.h b/contrib/gcc/config/rs6000/altivec-defs.h
index 123e1c836edc..4fa1e0d463b8 100644
--- a/contrib/gcc/config/rs6000/altivec-defs.h
+++ b/contrib/gcc/config/rs6000/altivec-defs.h
@@ -1,25 +1,25 @@
/* Target definitions for GNU compiler for PowerPC with AltiVec.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS \
do { \
rs6000_altivec_abi = 1; \
diff --git a/contrib/gcc/config/rs6000/altivec.h b/contrib/gcc/config/rs6000/altivec.h
index 1e2d8c8d408d..04d120dd901d 100644
--- a/contrib/gcc/config/rs6000/altivec.h
+++ b/contrib/gcc/config/rs6000/altivec.h
@@ -1,23 +1,23 @@
/* PowerPC AltiVec include file.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* As a special exception, if you include this header file into source
files compiled by GCC, this header file does not by itself cause
@@ -41,7 +41,7 @@ Boston, MA 02111-1307, USA. */
#define __vector __attribute__((vector_size(16)))
-/* You are allowed to undef this for C++ compatability. */
+/* You are allowed to undef this for C++ compatibility. */
#define vector __vector
#define bool signed
@@ -118,6 +118,8 @@ extern int __altivec_link_error_invalid_argument ();
#ifdef __cplusplus
+extern "C++" {
+
/* Prototypes for builtins that take literals and must always be
inlined. */
inline vector float vec_ctf (vector unsigned int, const char) __attribute__ ((always_inline));
@@ -1094,7 +1096,7 @@ vec_vcmpgtub (vector unsigned char a1, vector unsigned char a2)
inline vector signed int
vec_cmple (vector float a1, vector float a2)
{
- return (vector signed int) __builtin_altivec_vcmpgefp ((vector float) a1, (vector float) a2);
+ return (vector signed int) __builtin_altivec_vcmpgefp ((vector float) a2, (vector float) a1);
}
/* vec_cmplt */
@@ -1198,7 +1200,7 @@ vec_dss (const char a1)
/* vec_dssall */
inline void
-vec_dssall ()
+vec_dssall (void)
{
__builtin_altivec_dssall ();
}
@@ -2419,7 +2421,7 @@ vec_vmrglb (vector unsigned char a1, vector unsigned char a2)
/* vec_mfvscr */
inline vector unsigned short
-vec_mfvscr ()
+vec_mfvscr (void)
{
return (vector unsigned short) __builtin_altivec_mfvscr ();
}
@@ -4697,22 +4699,8 @@ vec_vsubuhs (vector unsigned short a1, vector signed short a2)
return (vector unsigned short) __builtin_altivec_vsubuhs ((vector signed short) a1, (vector signed short) a2);
}
-/* vec_vsubuhs */
-
-inline vector unsigned short
-vec_vsubsuhs (vector signed short a1, vector unsigned short a2)
-{
- return (vector unsigned short) __builtin_altivec_vsubuhs ((vector signed short) a1, (vector signed short) a2);
-}
-
inline vector unsigned short
-vec_vsubsuhs (vector unsigned short a1, vector signed short a2)
-{
- return (vector unsigned short) __builtin_altivec_vsubuhs ((vector signed short) a1, (vector signed short) a2);
-}
-
-inline vector unsigned short
-vec_vsubsuhs (vector unsigned short a1, vector unsigned short a2)
+vec_vsubuhs (vector unsigned short a1, vector unsigned short a2)
{
return (vector unsigned short) __builtin_altivec_vsubuhs ((vector signed short) a1, (vector signed short) a2);
}
@@ -4728,19 +4716,19 @@ vec_vsubsbs (vector signed char a1, vector signed char a2)
/* vec_vsububs */
inline vector unsigned char
-vec_vsubsubs (vector signed char a1, vector unsigned char a2)
+vec_vsububs (vector signed char a1, vector unsigned char a2)
{
return (vector unsigned char) __builtin_altivec_vsububs ((vector signed char) a1, (vector signed char) a2);
}
inline vector unsigned char
-vec_vsubsubs (vector unsigned char a1, vector signed char a2)
+vec_vsububs (vector unsigned char a1, vector signed char a2)
{
return (vector unsigned char) __builtin_altivec_vsububs ((vector signed char) a1, (vector signed char) a2);
}
inline vector unsigned char
-vec_vsubsubs (vector unsigned char a1, vector unsigned char a2)
+vec_vsububs (vector unsigned char a1, vector unsigned char a2)
{
return (vector unsigned char) __builtin_altivec_vsububs ((vector signed char) a1, (vector signed char) a2);
}
@@ -5526,7 +5514,7 @@ vec_all_nlt (vector float a1, vector float a2)
inline int
vec_all_numeric (vector float a1)
{
- return __builtin_altivec_vcmpeqfp_p (__CR6_EQ, a1, a1);
+ return __builtin_altivec_vcmpeqfp_p (__CR6_LT, a1, a1);
}
/* vec_any_eq */
@@ -6117,6 +6105,8 @@ struct __vec_step_help<vector float>
#define vec_step(t) __vec_step_help<typeof(t)>::_S_elem
+}//extern "C++"
+
#else /* not C++ */
/* "... and so I think no man in a century will suffer as greatly as
@@ -6521,7 +6511,7 @@ __ch (__bin_args_eq (vector unsigned char, (a1), vector unsigned char, (a2)), \
((vector signed char) __builtin_altivec_vcmpgtub ((vector signed char) (a1), (vector signed char) (a2))), \
__altivec_link_error_invalid_argument ())
-#define vec_cmple(a1, a2) __builtin_altivec_vcmpgefp ((a1), (a2))
+#define vec_cmple(a1, a2) __builtin_altivec_vcmpgefp ((a2), (a1))
#define vec_cmplt(a2, a1) \
__ch (__bin_args_eq (vector unsigned char, (a1), vector unsigned char, (a2)), \
@@ -8343,7 +8333,7 @@ __ch (__bin_args_eq (vector float, (a1), vector float, (a2)), \
#define vec_all_nlt(a1, a2) __builtin_altivec_vcmpgtfp_p (__CR6_EQ, (a2), (a1))
-#define vec_all_numeric(a1) __builtin_altivec_vcmpeqfp_p (__CR6_EQ, (a1), (a1))
+#define vec_all_numeric(a1) __builtin_altivec_vcmpeqfp_p (__CR6_LT, (a1), (a1))
#define vec_any_eq(a1, a2) \
__ch (__bin_args_eq (vector signed char, (a1), vector unsigned char, (a2)), \
@@ -8533,6 +8523,7 @@ __ch (__bin_args_eq (vector float, (a1), vector float, (a2)), \
#define vec_any_out(a1, a2) __builtin_altivec_vcmpbfp_p (__CR6_EQ_REV, (a1), (a2))
+
#endif /* __cplusplus */
#endif /* _ALTIVEC_H */
diff --git a/contrib/gcc/config/rs6000/altivec.md b/contrib/gcc/config/rs6000/altivec.md
index 25e4b084433a..db341cbd13ac 100644
--- a/contrib/gcc/config/rs6000/altivec.md
+++ b/contrib/gcc/config/rs6000/altivec.md
@@ -1,23 +1,29 @@
;; AltiVec patterns.
-;; Copyright (C) 2002 Free Software Foundation, Inc.
+;; Copyright (C) 2002, 2003 Free Software Foundation, Inc.
;; Contributed by Aldy Hernandez (aldy@quesejoda.com)
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC 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.
+;; 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 2, or (at your
+;; option) any later version.
-;; GNU CC 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.
+;; 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 GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_constants
+ [(UNSPEC_VSPLTISW 141)
+ (UNSPEC_VSPLTISH 140)
+ (UNSPEC_VSPLTISB 139)
+ ])
;; Generic LVX load instruction.
(define_insn "altivec_lvx_4si"
@@ -85,18 +91,47 @@
"{ rs6000_emit_move (operands[0], operands[1], V4SImode); DONE; }")
(define_insn "*movv4si_internal"
- [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v,v,o,r,r")
- (match_operand:V4SI 1 "input_operand" "v,m,v,r,o,r"))]
- "TARGET_ALTIVEC"
- "@
- stvx %1,%y0
- lvx %0,%y1
- vor %0,%1,%1
- stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0
- lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1
- mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1"
- [(set_attr "type" "altivec")
- (set_attr "length" "*,*,*,16,16,16")])
+ [(set (match_operand:V4SI 0 "nonimmediate_operand" "=m,v,v,o,r,r,v")
+ (match_operand:V4SI 1 "input_operand" "v,m,v,r,o,r,W"))]
+ "TARGET_ALTIVEC
+ && (register_operand (operands[0], V4SImode)
+ || register_operand (operands[1], V4SImode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: return \"stvx %1,%y0\";
+ case 1: return \"lvx %0,%y1\";
+ case 2: return \"vor %0,%1,%1\";
+ case 3: return \"#\";
+ case 4: return \"#\";
+ case 5: return \"#\";
+ case 6: return output_vec_const_move (operands);
+ default: abort();
+ }
+}"
+ [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,*")])
+
+(define_split
+ [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
+ (match_operand:V4SI 1 "input_operand" ""))]
+ "TARGET_ALTIVEC && reload_completed
+ && gpr_or_gpr_p (operands[0], operands[1])"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
+
+(define_split
+ [(set (match_operand:V4SI 0 "altivec_register_operand" "")
+ (match_operand:V4SI 1 "easy_vector_constant_add_self" ""))]
+ "TARGET_ALTIVEC && reload_completed"
+ [(set (match_dup 0) (match_dup 3))
+ (set (match_dup 0)
+ (plus:V4SI (match_dup 0)
+ (match_dup 0)))]
+ "
+{
+ operands[3] = gen_easy_vector_constant_add_self (operands[1]);
+}")
(define_expand "movv8hi"
[(set (match_operand:V8HI 0 "nonimmediate_operand" "")
@@ -105,18 +140,47 @@
"{ rs6000_emit_move (operands[0], operands[1], V8HImode); DONE; }")
(define_insn "*movv8hi_internal1"
- [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v,v,o,r,r")
- (match_operand:V8HI 1 "input_operand" "v,m,v,r,o,r"))]
- "TARGET_ALTIVEC"
- "@
- stvx %1,%y0
- lvx %0,%y1
- vor %0,%1,%1
- stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0
- lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1
- mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1"
- [(set_attr "type" "altivec")
- (set_attr "length" "*,*,*,16,16,16")])
+ [(set (match_operand:V8HI 0 "nonimmediate_operand" "=m,v,v,o,r,r,v")
+ (match_operand:V8HI 1 "input_operand" "v,m,v,r,o,r,W"))]
+ "TARGET_ALTIVEC
+ && (register_operand (operands[0], V8HImode)
+ || register_operand (operands[1], V8HImode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: return \"stvx %1,%y0\";
+ case 1: return \"lvx %0,%y1\";
+ case 2: return \"vor %0,%1,%1\";
+ case 3: return \"#\";
+ case 4: return \"#\";
+ case 5: return \"#\";
+ case 6: return output_vec_const_move (operands);
+ default: abort ();
+ }
+}"
+ [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,*")])
+
+(define_split
+ [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
+ (match_operand:V8HI 1 "input_operand" ""))]
+ "TARGET_ALTIVEC && reload_completed
+ && gpr_or_gpr_p (operands[0], operands[1])"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
+
+(define_split
+ [(set (match_operand:V8HI 0 "altivec_register_operand" "")
+ (match_operand:V8HI 1 "easy_vector_constant_add_self" ""))]
+ "TARGET_ALTIVEC && reload_completed"
+ [(set (match_dup 0) (match_dup 3))
+ (set (match_dup 0)
+ (plus:V8HI (match_dup 0)
+ (match_dup 0)))]
+ "
+{
+ operands[3] = gen_easy_vector_constant_add_self (operands[1]);
+}")
(define_expand "movv16qi"
[(set (match_operand:V16QI 0 "nonimmediate_operand" "")
@@ -125,18 +189,47 @@
"{ rs6000_emit_move (operands[0], operands[1], V16QImode); DONE; }")
(define_insn "*movv16qi_internal1"
- [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v,v,o,r,r")
- (match_operand:V16QI 1 "input_operand" "v,m,v,r,o,r"))]
- "TARGET_ALTIVEC"
- "@
- stvx %1,%y0
- lvx %0,%y1
- vor %0,%1,%1
- stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0
- lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1
- mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1"
- [(set_attr "type" "altivec")
- (set_attr "length" "*,*,*,16,16,16")])
+ [(set (match_operand:V16QI 0 "nonimmediate_operand" "=m,v,v,o,r,r,v")
+ (match_operand:V16QI 1 "input_operand" "v,m,v,r,o,r,W"))]
+ "TARGET_ALTIVEC
+ && (register_operand (operands[0], V16QImode)
+ || register_operand (operands[1], V16QImode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: return \"stvx %1,%y0\";
+ case 1: return \"lvx %0,%y1\";
+ case 2: return \"vor %0,%1,%1\";
+ case 3: return \"#\";
+ case 4: return \"#\";
+ case 5: return \"#\";
+ case 6: return output_vec_const_move (operands);
+ default: abort ();
+ }
+}"
+ [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,*")])
+
+(define_split
+ [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
+ (match_operand:V16QI 1 "input_operand" ""))]
+ "TARGET_ALTIVEC && reload_completed
+ && gpr_or_gpr_p (operands[0], operands[1])"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
+
+(define_split
+ [(set (match_operand:V16QI 0 "altivec_register_operand" "")
+ (match_operand:V16QI 1 "easy_vector_constant_add_self" ""))]
+ "TARGET_ALTIVEC && reload_completed"
+ [(set (match_dup 0) (match_dup 3))
+ (set (match_dup 0)
+ (plus:V16QI (match_dup 0)
+ (match_dup 0)))]
+ "
+{
+ operands[3] = gen_easy_vector_constant_add_self (operands[1]);
+}")
(define_expand "movv4sf"
[(set (match_operand:V4SF 0 "nonimmediate_operand" "")
@@ -145,18 +238,34 @@
"{ rs6000_emit_move (operands[0], operands[1], V4SFmode); DONE; }")
(define_insn "*movv4sf_internal1"
- [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v,v,o,r,r")
- (match_operand:V4SF 1 "input_operand" "v,m,v,r,o,r"))]
- "TARGET_ALTIVEC"
- "@
- stvx %1,%y0
- lvx %0,%y1
- vor %0,%1,%1
- stw%U0 %1,%0\;stw %L1,%L0\;stw %Y1,%Y0\;stw %Z1,%Z0
- lwz%U1 %0,%1\;lwz %L0,%L1\;lwz %Y0,%Y1\;lwz %Z0,%Z1
- mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1"
- [(set_attr "type" "altivec")
- (set_attr "length" "*,*,*,16,16,16")])
+ [(set (match_operand:V4SF 0 "nonimmediate_operand" "=m,v,v,o,r,r,v")
+ (match_operand:V4SF 1 "input_operand" "v,m,v,r,o,r,W"))]
+ "TARGET_ALTIVEC
+ && (register_operand (operands[0], V4SFmode)
+ || register_operand (operands[1], V4SFmode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: return \"stvx %1,%y0\";
+ case 1: return \"lvx %0,%y1\";
+ case 2: return \"vor %0,%1,%1\";
+ case 3: return \"#\";
+ case 4: return \"#\";
+ case 5: return \"#\";
+ case 6: return output_vec_const_move (operands);
+ default: abort ();
+ }
+}"
+ [(set_attr "type" "vecstore,vecload,vecsimple,store,load,*,*")])
+
+(define_split
+ [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
+ (match_operand:V4SF 1 "input_operand" ""))]
+ "TARGET_ALTIVEC && reload_completed
+ && gpr_or_gpr_p (operands[0], operands[1])"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
(define_insn "get_vrsave_internal"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -169,7 +278,7 @@
else
return \"mfvrsave %0\";
}"
- [(set_attr "type" "altivec")])
+ [(set_attr "type" "*")])
(define_insn "*set_vrsave_internal"
[(match_parallel 0 "vrsave_operation"
@@ -184,37 +293,7 @@
else
return \"mtvrsave %1\";
}"
- [(set_attr "type" "altivec")])
-
-;; Vector clears
-(define_insn "*movv4si_const0"
- [(set (match_operand:V4SI 0 "altivec_register_operand" "=v")
- (match_operand:V4SI 1 "zero_constant" ""))]
- "TARGET_ALTIVEC"
- "vxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
-(define_insn "*movv4sf_const0"
- [(set (match_operand:V4SF 0 "altivec_register_operand" "=v")
- (match_operand:V4SF 1 "zero_constant" ""))]
-
- "TARGET_ALTIVEC"
- "vxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
-(define_insn "*movv8hi_const0"
- [(set (match_operand:V8HI 0 "altivec_register_operand" "=v")
- (match_operand:V8HI 1 "zero_constant" ""))]
- "TARGET_ALTIVEC"
- "vxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
-(define_insn "*movv16qi_const0"
- [(set (match_operand:V16QI 0 "altivec_register_operand" "=v")
- (match_operand:V16QI 1 "zero_constant" ""))]
- "TARGET_ALTIVEC"
- "vxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
+ [(set_attr "type" "*")])
;; Simple binary operations.
@@ -529,7 +608,7 @@
(match_operand:V16QI 2 "register_operand" "v")
(match_operand:V4SI 3 "register_operand" "v")] 65))]
"TARGET_ALTIVEC"
- "vmsumubm %0, %1, %2, %3"
+ "vmsumubm %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmsummbm"
@@ -538,7 +617,7 @@
(match_operand:V16QI 2 "register_operand" "v")
(match_operand:V4SI 3 "register_operand" "v")] 66))]
"TARGET_ALTIVEC"
- "vmsumubm %0, %1, %2, %3"
+ "vmsummbm %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmsumuhm"
@@ -547,7 +626,7 @@
(match_operand:V8HI 2 "register_operand" "v")
(match_operand:V4SI 3 "register_operand" "v")] 67))]
"TARGET_ALTIVEC"
- "vmsumuhm %0, %1, %2, %3"
+ "vmsumuhm %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmsumshm"
@@ -556,7 +635,7 @@
(match_operand:V8HI 2 "register_operand" "v")
(match_operand:V4SI 3 "register_operand" "v")] 68))]
"TARGET_ALTIVEC"
- "vmsumshm %0, %1, %2, %3"
+ "vmsumshm %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmsumuhs"
@@ -566,7 +645,7 @@
(match_operand:V4SI 3 "register_operand" "v")] 69))
(set (reg:SI 110) (unspec:SI [(const_int 0)] 213))]
"TARGET_ALTIVEC"
- "vmsumuhs %0, %1, %2, %3"
+ "vmsumuhs %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmsumshs"
@@ -576,7 +655,7 @@
(match_operand:V4SI 3 "register_operand" "v")] 70))
(set (reg:SI 110) (unspec:SI [(const_int 0)] 213))]
"TARGET_ALTIVEC"
- "vmsumshs %0, %1, %2, %3"
+ "vmsumshs %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "umaxv16qi3"
@@ -642,7 +721,7 @@
(match_operand:V8HI 3 "register_operand" "v")] 71))
(set (reg:SI 110) (unspec:SI [(const_int 0)] 213))]
"TARGET_ALTIVEC"
- "vmhaddshs %0, %1, %2, %3"
+ "vmhaddshs %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmhraddshs"
[(set (match_operand:V8HI 0 "register_operand" "=v")
@@ -651,7 +730,7 @@
(match_operand:V8HI 3 "register_operand" "v")] 72))
(set (reg:SI 110) (unspec:SI [(const_int 0)] 213))]
"TARGET_ALTIVEC"
- "vmhraddshs %0, %1, %2, %3"
+ "vmhraddshs %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmladduhm"
[(set (match_operand:V8HI 0 "register_operand" "=v")
@@ -659,7 +738,7 @@
(match_operand:V8HI 2 "register_operand" "v")
(match_operand:V8HI 3 "register_operand" "v")] 73))]
"TARGET_ALTIVEC"
- "vmladduhm %0, %1, %2, %3"
+ "vmladduhm %0,%1,%2,%3"
[(set_attr "type" "veccomplex")])
(define_insn "altivec_vmrghb"
@@ -1279,6 +1358,7 @@
"vsumsws %0,%1,%2"
[(set_attr "type" "veccomplex")])
+;; Vector xor's
(define_insn "xorv4si3"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(xor:V4SI (match_operand:V4SI 1 "register_operand" "v")
@@ -1287,6 +1367,22 @@
"vxor %0,%1,%2"
[(set_attr "type" "vecsimple")])
+(define_insn "xorv8hi3"
+ [(set (match_operand:V8HI 0 "register_operand" "=v")
+ (xor:V8HI (match_operand:V8HI 1 "register_operand" "v")
+ (match_operand:V8HI 2 "register_operand" "v")))]
+ "TARGET_ALTIVEC"
+ "vxor %0,%1,%2"
+ [(set_attr "type" "vecsimple")])
+
+(define_insn "xorv16qi3"
+ [(set (match_operand:V16QI 0 "register_operand" "=v")
+ (xor:V16QI (match_operand:V16QI 1 "register_operand" "v")
+ (match_operand:V16QI 2 "register_operand" "v")))]
+ "TARGET_ALTIVEC"
+ "vxor %0,%1,%2"
+ [(set_attr "type" "vecsimple")])
+
(define_insn "altivec_vspltb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
(unspec:V16QI [(match_operand:V16QI 1 "register_operand" "v")
@@ -1294,6 +1390,7 @@
"TARGET_ALTIVEC"
"vspltb %0,%1,%2"
[(set_attr "type" "vecperm")])
+;; End of vector xor's
(define_insn "altivec_vsplth"
[(set (match_operand:V8HI 0 "register_operand" "=v")
@@ -1313,38 +1410,40 @@
(define_insn "altivec_vspltisb"
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand:QI 1 "immediate_operand" "i")] 139))]
+ (unspec:V16QI [(match_operand:QI 1 "immediate_operand" "i")]
+ UNSPEC_VSPLTISB))]
"TARGET_ALTIVEC"
- "vspltisb %0, %1"
- [(set_attr "type" "vecsimple")])
-
+ "vspltisb %0,%1"
+ [(set_attr "type" "vecperm")])
(define_insn "altivec_vspltish"
[(set (match_operand:V8HI 0 "register_operand" "=v")
- (unspec:V8HI [(match_operand:QI 1 "immediate_operand" "i")] 140))]
+ (unspec:V8HI [(match_operand:QI 1 "immediate_operand" "i")]
+ UNSPEC_VSPLTISH))]
"TARGET_ALTIVEC"
- "vspltish %0, %1"
- [(set_attr "type" "vecsimple")])
+ "vspltish %0,%1"
+ [(set_attr "type" "vecperm")])
(define_insn "altivec_vspltisw"
[(set (match_operand:V4SI 0 "register_operand" "=v")
- (unspec:V4SI [(match_operand:QI 1 "immediate_operand" "i")] 141))]
+ (unspec:V4SI [(match_operand:QI 1 "immediate_operand" "i")]
+ UNSPEC_VSPLTISW))]
"TARGET_ALTIVEC"
- "vspltisw %0, %1"
- [(set_attr "type" "vecsimple")])
+ "vspltisw %0,%1"
+ [(set_attr "type" "vecperm")])
(define_insn "altivec_vspltisw_v4sf"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:QI 1 "immediate_operand" "i")] 142))]
"TARGET_ALTIVEC"
- "vspltisw %0, %1"
- [(set_attr "type" "vecsimple")])
+ "vspltisw %0,%1"
+ [(set_attr "type" "vecperm")])
(define_insn "ftruncv4sf2"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(fix:V4SF (match_operand:V4SF 1 "register_operand" "v")))]
"TARGET_ALTIVEC"
- "vrfiz %0, %1"
+ "vrfiz %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vperm_4si"
@@ -1387,21 +1486,21 @@
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 148))]
"TARGET_ALTIVEC"
- "vrfip %0, %1"
+ "vrfip %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vrfin"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 149))]
"TARGET_ALTIVEC"
- "vrfin %0, %1"
+ "vrfin %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vrfim"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 150))]
"TARGET_ALTIVEC"
- "vrfim %0, %1"
+ "vrfim %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vcfux"
@@ -1409,7 +1508,7 @@
(unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:QI 2 "immediate_operand" "i")] 151))]
"TARGET_ALTIVEC"
- "vcfux %0, %1, %2"
+ "vcfux %0,%1,%2"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vcfsx"
@@ -1417,7 +1516,7 @@
(unspec:V4SF [(match_operand:V4SI 1 "register_operand" "v")
(match_operand:QI 2 "immediate_operand" "i")] 152))]
"TARGET_ALTIVEC"
- "vcfsx %0, %1, %2"
+ "vcfsx %0,%1,%2"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vctuxs"
@@ -1426,7 +1525,7 @@
(match_operand:QI 2 "immediate_operand" "i")] 153))
(set (reg:SI 110) (unspec:SI [(const_int 0)] 213))]
"TARGET_ALTIVEC"
- "vctuxs %0, %1, %2"
+ "vctuxs %0,%1,%2"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vctsxs"
@@ -1435,35 +1534,35 @@
(match_operand:QI 2 "immediate_operand" "i")] 154))
(set (reg:SI 110) (unspec:SI [(const_int 0)] 213))]
"TARGET_ALTIVEC"
- "vctsxs %0, %1, %2"
+ "vctsxs %0,%1,%2"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vlogefp"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 155))]
"TARGET_ALTIVEC"
- "vlogefp %0, %1"
+ "vlogefp %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vexptefp"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 156))]
"TARGET_ALTIVEC"
- "vexptefp %0, %1"
+ "vexptefp %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vrsqrtefp"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 157))]
"TARGET_ALTIVEC"
- "vrsqrtefp %0, %1"
+ "vrsqrtefp %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vrefp"
[(set (match_operand:V4SF 0 "register_operand" "=v")
(unspec:V4SF [(match_operand:V4SF 1 "register_operand" "v")] 158))]
"TARGET_ALTIVEC"
- "vrefp %0, %1"
+ "vrefp %0,%1"
[(set_attr "type" "vecfloat")])
(define_insn "altivec_vsel_4si"
@@ -1508,7 +1607,7 @@
(match_operand:V4SI 2 "register_operand" "v")
(match_operand:QI 3 "immediate_operand" "i")] 163))]
"TARGET_ALTIVEC"
- "vsldoi %0, %1, %2, %3"
+ "vsldoi %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vsldoi_4sf"
@@ -1517,7 +1616,7 @@
(match_operand:V4SF 2 "register_operand" "v")
(match_operand:QI 3 "immediate_operand" "i")] 164))]
"TARGET_ALTIVEC"
- "vsldoi %0, %1, %2, %3"
+ "vsldoi %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vsldoi_8hi"
@@ -1526,7 +1625,7 @@
(match_operand:V8HI 2 "register_operand" "v")
(match_operand:QI 3 "immediate_operand" "i")] 165))]
"TARGET_ALTIVEC"
- "vsldoi %0, %1, %2, %3"
+ "vsldoi %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vsldoi_16qi"
@@ -1535,49 +1634,49 @@
(match_operand:V16QI 2 "register_operand" "v")
(match_operand:QI 3 "immediate_operand" "i")] 166))]
"TARGET_ALTIVEC"
- "vsldoi %0, %1, %2, %3"
+ "vsldoi %0,%1,%2,%3"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupkhsb"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 167))]
"TARGET_ALTIVEC"
- "vupkhsb %0, %1"
+ "vupkhsb %0,%1"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupkhpx"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 168))]
"TARGET_ALTIVEC"
- "vupkhpx %0, %1"
+ "vupkhpx %0,%1"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupkhsh"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 169))]
"TARGET_ALTIVEC"
- "vupkhsh %0, %1"
+ "vupkhsh %0,%1"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupklsb"
[(set (match_operand:V8HI 0 "register_operand" "=v")
(unspec:V8HI [(match_operand:V16QI 1 "register_operand" "v")] 170))]
"TARGET_ALTIVEC"
- "vupklsb %0, %1"
+ "vupklsb %0,%1"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupklpx"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 171))]
"TARGET_ALTIVEC"
- "vupklpx %0, %1"
+ "vupklpx %0,%1"
[(set_attr "type" "vecperm")])
(define_insn "altivec_vupklsh"
[(set (match_operand:V4SI 0 "register_operand" "=v")
(unspec:V4SI [(match_operand:V8HI 1 "register_operand" "v")] 172))]
"TARGET_ALTIVEC"
- "vupklsh %0, %1"
+ "vupklsh %0,%1"
[(set_attr "type" "vecperm")])
;; AltiVec predicates.
@@ -1683,51 +1782,49 @@
[(set_attr "type" "vecsimple")])
(define_insn "altivec_dst"
- [(unspec [(match_operand:SI 0 "register_operand" "b")
+ [(unspec [(match_operand:V4SI 0 "memory_operand" "Q")
(match_operand:SI 1 "register_operand" "r")
(match_operand:QI 2 "immediate_operand" "i")] 190)]
"TARGET_ALTIVEC"
- "dst %0,%1,%2"
+ "dst %P0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_dstt"
- [(unspec [(match_operand:SI 0 "register_operand" "b")
+ [(unspec [(match_operand:V4SI 0 "memory_operand" "Q")
(match_operand:SI 1 "register_operand" "r")
(match_operand:QI 2 "immediate_operand" "i")] 191)]
"TARGET_ALTIVEC"
- "dstt %0,%1,%2"
+ "dstt %P0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_dstst"
- [(unspec [(match_operand:SI 0 "register_operand" "b")
+ [(unspec [(match_operand:V4SI 0 "memory_operand" "Q")
(match_operand:SI 1 "register_operand" "r")
(match_operand:QI 2 "immediate_operand" "i")] 192)]
"TARGET_ALTIVEC"
- "dstst %0,%1,%2"
+ "dstst %P0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_dststt"
- [(unspec [(match_operand:SI 0 "register_operand" "b")
+ [(unspec [(match_operand:V4SI 0 "memory_operand" "Q")
(match_operand:SI 1 "register_operand" "r")
(match_operand:QI 2 "immediate_operand" "i")] 193)]
"TARGET_ALTIVEC"
- "dststt %0,%1,%2"
+ "dststt %P0,%1,%2"
[(set_attr "type" "vecsimple")])
(define_insn "altivec_lvsl"
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r")] 194))]
+ (unspec:V16QI [(match_operand 1 "memory_operand" "m")] 194))]
"TARGET_ALTIVEC"
- "lvsl %0,%1,%2"
+ "lvsl %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvsr"
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (unspec:V16QI [(match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r")] 195))]
+ (unspec:V16QI [(match_operand 1 "memory_operand" "m")] 195))]
"TARGET_ALTIVEC"
- "lvsr %0,%1,%2"
+ "lvsr %0,%y1"
[(set_attr "type" "vecload")])
;; Parallel some of the LVE* and STV*'s with unspecs because some have
@@ -1736,112 +1833,89 @@
(define_insn "altivec_lvebx"
[(parallel
[(set (match_operand:V16QI 0 "register_operand" "=v")
- (mem:V16QI (plus:SI (match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r"))))
+ (match_operand:V16QI 1 "memory_operand" "m"))
(unspec [(const_int 0)] 196)])]
"TARGET_ALTIVEC"
- "lvebx %0,%1,%2"
+ "lvebx %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvehx"
[(parallel
[(set (match_operand:V8HI 0 "register_operand" "=v")
- (mem:V8HI
- (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r"))
- (const_int -2))))
+ (match_operand:V8HI 1 "memory_operand" "m"))
(unspec [(const_int 0)] 197)])]
"TARGET_ALTIVEC"
- "lvehx %0,%1,%2"
+ "lvehx %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvewx"
[(parallel
[(set (match_operand:V4SI 0 "register_operand" "=v")
- (mem:V4SI
- (and:SI (plus:SI (match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r"))
- (const_int -4))))
+ (match_operand:V4SI 1 "memory_operand" "m"))
(unspec [(const_int 0)] 198)])]
"TARGET_ALTIVEC"
- "lvewx %0,%1,%2"
+ "lvewx %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvxl"
[(parallel
[(set (match_operand:V4SI 0 "register_operand" "=v")
- (mem:V4SI (plus:SI (match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r"))))
+ (match_operand:V4SI 1 "memory_operand" "m"))
(unspec [(const_int 0)] 213)])]
"TARGET_ALTIVEC"
- "lvxl %0,%1,%2"
+ "lvxl %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_lvx"
[(set (match_operand:V4SI 0 "register_operand" "=v")
- (mem:V4SI (plus:SI (match_operand:SI 1 "register_operand" "b")
- (match_operand:SI 2 "register_operand" "r"))))]
+ (match_operand:V4SI 1 "memory_operand" "m"))]
"TARGET_ALTIVEC"
- "lvx %0,%1,%2"
+ "lvx %0,%y1"
[(set_attr "type" "vecload")])
(define_insn "altivec_stvx"
[(parallel
- [(set (mem:V4SI
- (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b")
- (match_operand:SI 1 "register_operand" "r"))
- (const_int -16)))
- (match_operand:V4SI 2 "register_operand" "v"))
+ [(set (match_operand:V4SI 0 "memory_operand" "=m")
+ (match_operand:V4SI 1 "register_operand" "v"))
(unspec [(const_int 0)] 201)])]
"TARGET_ALTIVEC"
- "stvx %2,%0,%1"
+ "stvx %1,%y0"
[(set_attr "type" "vecstore")])
(define_insn "altivec_stvxl"
[(parallel
- [(set (mem:V4SI
- (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b")
- (match_operand:SI 1 "register_operand" "r"))
- (const_int -16)))
- (match_operand:V4SI 2 "register_operand" "v"))
+ [(set (match_operand:V4SI 0 "memory_operand" "=m")
+ (match_operand:V4SI 1 "register_operand" "v"))
(unspec [(const_int 0)] 202)])]
"TARGET_ALTIVEC"
- "stvxl %2,%0,%1"
+ "stvxl %1,%y0"
[(set_attr "type" "vecstore")])
(define_insn "altivec_stvebx"
[(parallel
- [(set (mem:V16QI
- (plus:SI (match_operand:SI 0 "register_operand" "b")
- (match_operand:SI 1 "register_operand" "r")))
- (match_operand:V16QI 2 "register_operand" "v"))
+ [(set (match_operand:V16QI 0 "memory_operand" "=m")
+ (match_operand:V16QI 1 "register_operand" "v"))
(unspec [(const_int 0)] 203)])]
"TARGET_ALTIVEC"
- "stvebx %2,%0,%1"
+ "stvebx %1,%y0"
[(set_attr "type" "vecstore")])
(define_insn "altivec_stvehx"
[(parallel
- [(set (mem:V8HI
- (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b")
- (match_operand:SI 1 "register_operand" "r"))
- (const_int -2)))
- (match_operand:V8HI 2 "register_operand" "v"))
+ [(set (match_operand:V8HI 0 "memory_operand" "=m")
+ (match_operand:V8HI 1 "register_operand" "v"))
(unspec [(const_int 0)] 204)])]
"TARGET_ALTIVEC"
- "stvehx %2,%0,%1"
+ "stvehx %1,%y0"
[(set_attr "type" "vecstore")])
(define_insn "altivec_stvewx"
[(parallel
- [(set (mem:V4SI
- (and:SI (plus:SI (match_operand:SI 0 "register_operand" "b")
- (match_operand:SI 1 "register_operand" "r"))
- (const_int -4)))
- (match_operand:V4SI 2 "register_operand" "v"))
+ [(set (match_operand:V4SI 0 "memory_operand" "=m")
+ (match_operand:V4SI 1 "register_operand" "v"))
(unspec [(const_int 0)] 205)])]
"TARGET_ALTIVEC"
- "stvewx %2,%0,%1"
+ "stvewx %1,%y0"
[(set_attr "type" "vecstore")])
(define_insn "absv16qi2"
@@ -1851,7 +1925,7 @@
(clobber (match_scratch:V16QI 3 "=&v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsububm %3,%2,%1\;vmaxsb %0,%1,%3"
- [(set_attr "type" "altivec")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
(define_insn "absv8hi2"
@@ -1861,7 +1935,7 @@
(clobber (match_scratch:V8HI 3 "=&v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubuhm %3,%2,%1\;vmaxsh %0,%1,%3"
- [(set_attr "type" "altivec")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
(define_insn "absv4si2"
@@ -1871,7 +1945,7 @@
(clobber (match_scratch:V4SI 3 "=&v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubuwm %3,%2,%1\;vmaxsw %0,%1,%3"
- [(set_attr "type" "altivec")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
(define_insn "absv4sf2"
@@ -1880,8 +1954,8 @@
(clobber (match_scratch:V4SF 2 "=&v"))
(clobber (match_scratch:V4SF 3 "=&v"))]
"TARGET_ALTIVEC"
- "vspltisw %2, -1\;vslw %3,%2,%2\;vandc %0,%1,%3"
- [(set_attr "type" "altivec")
+ "vspltisw %2,-1\;vslw %3,%2,%2\;vandc %0,%1,%3"
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
(define_insn "altivec_abss_v16qi"
@@ -1891,7 +1965,7 @@
(clobber (match_scratch:V16QI 3 "=&v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubsbs %3,%2,%1\;vmaxsb %0,%1,%3"
- [(set_attr "type" "altivec")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
(define_insn "altivec_abss_v8hi"
@@ -1901,7 +1975,7 @@
(clobber (match_scratch:V8HI 3 "=&v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubshs %3,%2,%1\;vmaxsh %0,%1,%3"
- [(set_attr "type" "altivec")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
(define_insn "altivec_abss_v4si"
@@ -1911,5 +1985,5 @@
(clobber (match_scratch:V4SI 3 "=&v"))]
"TARGET_ALTIVEC"
"vspltisb %2,0\;vsubsws %3,%2,%1\;vmaxsw %0,%1,%3"
- [(set_attr "type" "altivec")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "12")])
diff --git a/contrib/gcc/config/rs6000/beos.h b/contrib/gcc/config/rs6000/beos.h
index 1f788c31c25c..1ce36bf70aab 100644
--- a/contrib/gcc/config/rs6000/beos.h
+++ b/contrib/gcc/config/rs6000/beos.h
@@ -1,24 +1,24 @@
/* Definitions of target machine for GNU compiler, for BeOS.
- Copyright (C) 1997, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1997, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Fred Fish (fnf@cygnus.com), based on aix41.h
from David Edelsohn (edelsohn@npac.syr.edu).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (BeOS/PowerPC)");
@@ -39,7 +39,7 @@ Boston, MA 02111-1307, USA. */
#define ASM_SPEC "-u %(asm_cpu)"
#undef TARGET_OS_CPP_BUILTINS
-/* __POWERPC__ must be defined for some header files */
+/* __POWERPC__ must be defined for some header files. */
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
diff --git a/contrib/gcc/config/rs6000/biarch64.h b/contrib/gcc/config/rs6000/biarch64.h
new file mode 100644
index 000000000000..3f8addd5ac98
--- /dev/null
+++ b/contrib/gcc/config/rs6000/biarch64.h
@@ -0,0 +1,22 @@
+/* Definitions of target machine for GNU compiler, for 32/64 bit powerpc.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Specify this in a cover file to provide bi-architecture (32/64) support. */
+#define RS6000_BI_ARCH 1
diff --git a/contrib/gcc/config/rs6000/crtsavres.asm b/contrib/gcc/config/rs6000/crtsavres.asm
index 0c65182584db..327048eb287f 100644
--- a/contrib/gcc/config/rs6000/crtsavres.asm
+++ b/contrib/gcc/config/rs6000/crtsavres.asm
@@ -41,6 +41,7 @@
.section ".text"
#include "ppc-asm.h"
+/* On PowerPC64 Linux, these functions are provided by the linker. */
#ifndef __powerpc64__
/* Routines for saving floating point registers, called by the compiler. */
@@ -303,105 +304,4 @@ FUNC_END(_restgpr_16_x)
FUNC_END(_restgpr_15_x)
FUNC_END(_restgpr_14_x)
-#else /* __powerpc64__ */
-
- .section ".text"
- .align 2
-
-/* Routines for saving floating point registers, called by the compiler. */
-
-.fsav:
-FUNC_START(_savef14) stfd 14,-144(1) /* save fp registers */
-FUNC_START(_savef15) stfd 15,-136(1)
-FUNC_START(_savef16) stfd 16,-128(1)
-FUNC_START(_savef17) stfd 17,-120(1)
-FUNC_START(_savef18) stfd 18,-112(1)
-FUNC_START(_savef19) stfd 19,-104(1)
-FUNC_START(_savef20) stfd 20,-96(1)
-FUNC_START(_savef21) stfd 21,-88(1)
-FUNC_START(_savef22) stfd 22,-80(1)
-FUNC_START(_savef23) stfd 23,-72(1)
-FUNC_START(_savef24) stfd 24,-64(1)
-FUNC_START(_savef25) stfd 25,-56(1)
-FUNC_START(_savef26) stfd 26,-48(1)
-FUNC_START(_savef27) stfd 27,-40(1)
-FUNC_START(_savef28) stfd 28,-32(1)
-FUNC_START(_savef29) stfd 29,-24(1)
-FUNC_START(_savef30) stfd 30,-16(1)
-FUNC_START(_savef31) stfd 31,-8(1)
- blr
-.LTfsav:
- .long 0
- .byte 0,12,0,0,0,0,0,0
- .long 0
- .long .LTfsav-.fsav
- .short 4
- .ascii "fsav"
-FUNC_END(_savef31)
-FUNC_END(_savef30)
-FUNC_END(_savef29)
-FUNC_END(_savef28)
-FUNC_END(_savef27)
-FUNC_END(_savef26)
-FUNC_END(_savef25)
-FUNC_END(_savef24)
-FUNC_END(_savef23)
-FUNC_END(_savef22)
-FUNC_END(_savef21)
-FUNC_END(_savef20)
-FUNC_END(_savef19)
-FUNC_END(_savef18)
-FUNC_END(_savef17)
-FUNC_END(_savef16)
-FUNC_END(_savef15)
-FUNC_END(_savef14)
-
-/* Routines for restoring floating point registers, called by the compiler. */
-
-.fres:
-FUNC_START(_restf14) lfd 14,-144(1) /* restore fp registers */
-FUNC_START(_restf15) lfd 15,-136(1)
-FUNC_START(_restf16) lfd 16,-128(1)
-FUNC_START(_restf17) lfd 17,-120(1)
-FUNC_START(_restf18) lfd 18,-112(1)
-FUNC_START(_restf19) lfd 19,-104(1)
-FUNC_START(_restf20) lfd 20,-96(1)
-FUNC_START(_restf21) lfd 21,-88(1)
-FUNC_START(_restf22) lfd 22,-80(1)
-FUNC_START(_restf23) lfd 23,-72(1)
-FUNC_START(_restf24) lfd 24,-64(1)
-FUNC_START(_restf25) lfd 25,-56(1)
-FUNC_START(_restf26) lfd 26,-48(1)
-FUNC_START(_restf27) lfd 27,-40(1)
-FUNC_START(_restf28) lfd 28,-32(1)
-FUNC_START(_restf29) lfd 29,-24(1)
-FUNC_START(_restf30) lfd 30,-16(1)
-FUNC_START(_restf31) lfd 31,-8(1)
- blr
-.LTfres:
- .long 0
- .byte 0,12,0,0,0,0,0,0
- .long 0
- .long .LTfres-.fres
- .short 4
- .ascii "fres"
-FUNC_END(_restf31)
-FUNC_END(_restf30)
-FUNC_END(_restf29)
-FUNC_END(_restf28)
-FUNC_END(_restf27)
-FUNC_END(_restf26)
-FUNC_END(_restf25)
-FUNC_END(_restf24)
-FUNC_END(_restf23)
-FUNC_END(_restf22)
-FUNC_END(_restf21)
-FUNC_END(_restf20)
-FUNC_END(_restf19)
-FUNC_END(_restf18)
-FUNC_END(_restf17)
-FUNC_END(_restf16)
-FUNC_END(_restf15)
-FUNC_END(_restf14)
-
#endif
diff --git a/contrib/gcc/config/rs6000/darwin-ldouble.c b/contrib/gcc/config/rs6000/darwin-ldouble.c
new file mode 100644
index 000000000000..3174ebbcc5bc
--- /dev/null
+++ b/contrib/gcc/config/rs6000/darwin-ldouble.c
@@ -0,0 +1,205 @@
+/* 128-bit long double support routines for Darwin.
+ Copyright (C) 1993, 2003, 2004 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 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Implementations of floating-point long double basic arithmetic
+ functions called by the IBM C compiler when generating code for
+ PowerPC platforms. In particular, the following functions are
+ implemented: _xlqadd, _xlqsub, _xlqmul, and _xlqdiv. Double-double
+ algorithms are based on the paper "Doubled-Precision IEEE Standard
+ 754 Floating-Point Arithmetic" by W. Kahan, February 26, 1987. An
+ alternative published reference is "Software for Doubled-Precision
+ Floating-Point Computations", by Seppo Linnainmaa, ACM TOMS vol 7
+ no 3, September 1961, pages 272-283. */
+
+/* Each long double is made up of two IEEE doubles. The value of the
+ long double is the sum of the values of the two parts. The most
+ significant part is required to be the value of the long double
+ rounded to the nearest double, as specified by IEEE. For Inf
+ values, the least significant part is required to be one of +0.0 or
+ -0.0. No other requirements are made; so, for example, 1.0 may be
+ represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a
+ NaN is don't-care.
+
+ This code currently assumes big-endian. */
+
+#if !_SOFT_FLOAT && (defined (__MACH__) || defined (__powerpc64__))
+
+#define fabs(x) __builtin_fabs(x)
+
+#define unlikely(x) __builtin_expect ((x), 0)
+
+/* All these routines actually take two long doubles as parameters,
+ but GCC currently generates poor code when a union is used to turn
+ a long double into a pair of doubles. */
+
+extern long double _xlqadd (double, double, double, double);
+extern long double _xlqsub (double, double, double, double);
+extern long double _xlqmul (double, double, double, double);
+extern long double _xlqdiv (double, double, double, double);
+
+typedef union
+{
+ long double ldval;
+ double dval[2];
+} longDblUnion;
+
+static const double FPKINF = 1.0/0.0;
+
+/* Add two 'long double' values and return the result. */
+long double
+_xlqadd (double a, double b, double c, double d)
+{
+ longDblUnion z;
+ double t, tau, u, FPR_zero, FPR_PosInf;
+
+ FPR_zero = 0.0;
+ FPR_PosInf = FPKINF;
+
+ if (unlikely (a != a) || unlikely (c != c))
+ return a + c; /* NaN result. */
+
+ /* Ordered operands are arranged in order of their magnitudes. */
+
+ /* Switch inputs if |(c,d)| > |(a,b)|. */
+ if (fabs (c) > fabs (a))
+ {
+ t = a;
+ tau = b;
+ a = c;
+ b = d;
+ c = t;
+ d = tau;
+ }
+
+ /* b <- second largest magnitude double. */
+ if (fabs (c) > fabs (b))
+ {
+ t = b;
+ b = c;
+ c = t;
+ }
+
+ /* Thanks to commutivity, sum is invariant w.r.t. the next
+ conditional exchange. */
+ tau = d + c;
+
+ /* Order the smallest magnitude doubles. */
+ if (fabs (d) > fabs (c))
+ {
+ t = c;
+ c = d;
+ d = t;
+ }
+
+ t = (tau + b) + a; /* Sum values in ascending magnitude order. */
+
+ /* Infinite or zero result. */
+ if (unlikely (t == FPR_zero) || unlikely (fabs (t) == FPR_PosInf))
+ return t;
+
+ /* Usual case. */
+ tau = (((a-t) + b) + c) + d;
+ u = t + tau;
+ z.dval[0] = u; /* Final fixup for long double result. */
+ z.dval[1] = (t - u) + tau;
+ return z.ldval;
+}
+
+long double
+_xlqsub (double a, double b, double c, double d)
+{
+ return _xlqadd (a, b, -c, -d);
+}
+
+long double
+_xlqmul (double a, double b, double c, double d)
+{
+ longDblUnion z;
+ double t, tau, u, v, w, FPR_zero, FPR_PosInf;
+
+ FPR_zero = 0.0;
+ FPR_PosInf = FPKINF;
+
+ t = a * c; /* Highest order double term. */
+
+ if (unlikely (t != t) || unlikely (t == FPR_zero)
+ || unlikely (fabs (t) == FPR_PosInf))
+ return t;
+
+ /* Finite nonzero result requires summing of terms of two highest
+ orders. */
+
+ /* Use fused multiply-add to get low part of a * c. */
+ asm ("fmsub %0,%1,%2,%3" : "=f"(tau) : "f"(a), "f"(c), "f"(t));
+ v = a*d;
+ w = b*c;
+ tau += v + w; /* Add in other second-order terms. */
+ u = t + tau;
+
+ /* Construct long double result. */
+ z.dval[0] = u;
+ z.dval[1] = (t - u) + tau;
+ return z.ldval;
+}
+
+long double
+_xlqdiv (double a, double b, double c, double d)
+{
+ longDblUnion z;
+ double s, sigma, t, tau, u, v, w, FPR_zero, FPR_PosInf;
+
+ FPR_zero = 0.0;
+ FPR_PosInf = FPKINF;
+
+ t = a / c; /* highest order double term */
+
+ if (unlikely (t != t) || unlikely (t == FPR_zero)
+ || unlikely (fabs (t) == FPR_PosInf))
+ return t;
+
+ /* Finite nonzero result requires corrections to the highest order term. */
+
+ s = c * t; /* (s,sigma) = c*t exactly. */
+ w = -(-b + d * t); /* Written to get fnmsub for speed, but not
+ numerically necessary. */
+
+ /* Use fused multiply-add to get low part of c * t. */
+ asm ("fmsub %0,%1,%2,%3" : "=f"(sigma) : "f"(c), "f"(t), "f"(s));
+ v = a - s;
+
+ tau = ((v-sigma)+w)/c; /* Correction to t. */
+ u = t + tau;
+
+ /* Construct long double result. */
+ z.dval[0] = u;
+ z.dval[1] = (t - u) + tau;
+ return z.ldval;
+}
+
+#endif
diff --git a/contrib/gcc/config/rs6000/darwin.h b/contrib/gcc/config/rs6000/darwin.h
index b3468f2b66b6..62ed74c00d83 100644
--- a/contrib/gcc/config/rs6000/darwin.h
+++ b/contrib/gcc/config/rs6000/darwin.h
@@ -1,23 +1,23 @@
/* Target definitions for PowerPC running Darwin (Mac OS X).
- Copyright (C) 1997, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (Darwin/PowerPC)");
@@ -35,14 +35,15 @@ Boston, MA 02111-1307, USA. */
#define TARGET_TOC 0
#define TARGET_NO_TOC 1
+/* Darwin switches. */
+/* Use dynamic-no-pic codegen (no picbase reg; not suitable for shlibs.) */
+#define MASK_MACHO_DYNAMIC_NO_PIC 0x00800000
+
+#define TARGET_DYNAMIC_NO_PIC (target_flags & MASK_MACHO_DYNAMIC_NO_PIC)
+
/* Handle #pragma weak and #pragma pack. */
#define HANDLE_SYSV_PRAGMA 1
-/* The Darwin ABI always includes AltiVec, can't be (validly) turned
- off. */
-
-#define SUBTARGET_OVERRIDE_OPTIONS \
- rs6000_altivec_abi = 1;
#define TARGET_OS_CPP_BUILTINS() \
do \
@@ -55,12 +56,60 @@ Boston, MA 02111-1307, USA. */
} \
while (0)
+
+/* */
+#undef SUBTARGET_SWITCHES
+#define SUBTARGET_SWITCHES \
+ {"dynamic-no-pic", MASK_MACHO_DYNAMIC_NO_PIC, \
+ N_("Generate code suitable for executables (NOT shared libs)")}, \
+ {"no-dynamic-no-pic", -MASK_MACHO_DYNAMIC_NO_PIC, ""},
+
+
+/* The Darwin ABI always includes AltiVec, can't be (validly) turned
+ off. */
+
+#define SUBTARGET_OVERRIDE_OPTIONS \
+do { \
+ rs6000_altivec_abi = 1; \
+ rs6000_altivec_vrsave = 1; \
+ if (DEFAULT_ABI == ABI_DARWIN) \
+ { \
+ if (MACHO_DYNAMIC_NO_PIC_P) \
+ { \
+ if (flag_pic) \
+ warning ("-mdynamic-no-pic overrides -fpic or -fPIC"); \
+ flag_pic = 0; \
+ } \
+ else if (flag_pic == 1) \
+ { \
+ /* Darwin doesn't support -fpic. */ \
+ warning ("-fpic is not supported; -fPIC assumed"); \
+ flag_pic = 2; \
+ } \
+ } \
+}while(0)
+
/* We want -fPIC by default, unless we're using -static to compile for
the kernel or some such. */
+
#define CC1_SPEC "\
+%{gused: -feliminate-unused-debug-symbols %<gused }\
%{static: %{Zdynamic: %e conflicting code gen style switches are used}}\
-%{!static:-fPIC}"
+%{!static:%{!mdynamic-no-pic:-fPIC}}"
+
+/* It's virtually impossible to predict all the possible combinations
+ of -mcpu and -maltivec and whatnot, so just supply
+ -force_cpusubtype_ALL if any are seen. Radar 3492132 against the
+ assembler is asking for a .machine directive so we could get this
+ really right. */
+#define ASM_SPEC "-arch ppc \
+ %{Zforce_cpusubtype_ALL:-force_cpusubtype_ALL} \
+ %{!Zforce_cpusubtype_ALL:%{maltivec|mcpu=*|mpowerpc64:-force_cpusubtype_ALL}}"
+
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "darwin_arch", "ppc" },
/* Make both r2 and r3 available for allocation. */
#define FIXED_R2 0
@@ -87,23 +136,46 @@ Boston, MA 02111-1307, USA. */
(RS6000_ALIGN (current_function_outgoing_args_size, 16) \
+ (STACK_POINTER_OFFSET))
+/* These are used by -fbranch-probabilities */
+#define HOT_TEXT_SECTION_NAME "__TEXT,__text,regular,pure_instructions"
+#define UNLIKELY_EXECUTED_TEXT_SECTION_NAME \
+ "__TEXT,__text2,regular,pure_instructions"
+
/* Define cutoff for using external functions to save floating point.
Currently on Darwin, always use inline stores. */
#undef FP_SAVE_INLINE
#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 64)
-/* Always use the "debug" register names, they're what the assembler
- wants to see. */
-
+/* The assembler wants the alternate register names, but without
+ leading percent sign. */
#undef REGISTER_NAMES
-#define REGISTER_NAMES DEBUG_REGISTER_NAMES
+#define REGISTER_NAMES \
+{ \
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
+ "mq", "lr", "ctr", "ap", \
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
+ "xer", \
+ "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", \
+ "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", \
+ "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", \
+ "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", \
+ "vrsave", "vscr", \
+ "spe_acc", "spefscr" \
+}
/* This outputs NAME to FILE. */
#undef RS6000_OUTPUT_BASENAME
#define RS6000_OUTPUT_BASENAME(FILE, NAME) \
- assemble_name (FILE, NAME);
+ assemble_name (FILE, NAME)
/* Globalizing directive for a label. */
#undef GLOBAL_ASM_OP
@@ -125,7 +197,8 @@ Boston, MA 02111-1307, USA. */
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
do { fputs (".comm ", (FILE)); \
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
- fprintf ((FILE), ",%d\n", (SIZE)); } while (0)
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n",\
+ (SIZE)); } while (0)
/* Override the standard rs6000 definition. */
@@ -167,7 +240,7 @@ Boston, MA 02111-1307, USA. */
#define PROCESSOR_DEFAULT PROCESSOR_PPC7400
/* Default target flag settings. Despite the fact that STMW/LMW
- serializes, it's still a big codesize win to use them. Use FSEL by
+ serializes, it's still a big code size win to use them. Use FSEL by
default as well. */
#undef TARGET_DEFAULT
@@ -196,38 +269,40 @@ Boston, MA 02111-1307, USA. */
a SYMBOL_REF. */
#undef PREFERRED_RELOAD_CLASS
-#define PREFERRED_RELOAD_CLASS(X,CLASS) \
- (((GET_CODE (X) == CONST_DOUBLE \
- && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
- ? NO_REGS \
- : (GET_MODE_CLASS (GET_MODE (X)) == MODE_INT \
- && (CLASS) == NON_SPECIAL_REGS) \
- ? GENERAL_REGS \
- : (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == HIGH) \
- ? BASE_REGS \
- : (CLASS)))
+#define PREFERRED_RELOAD_CLASS(X,CLASS) \
+ ((GET_CODE (X) == CONST_DOUBLE \
+ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
+ ? NO_REGS \
+ : ((GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == HIGH) \
+ && reg_class_subset_p (BASE_REGS, (CLASS))) \
+ ? BASE_REGS \
+ : (GET_MODE_CLASS (GET_MODE (X)) == MODE_INT \
+ && (CLASS) == NON_SPECIAL_REGS) \
+ ? GENERAL_REGS \
+ : (CLASS))
/* Fix for emit_group_load (): force large constants to be pushed via regs. */
#define ALWAYS_PUSH_CONSTS_USING_REGS_P 1
+/* This now supports a natural alignment mode */
/* Darwin word-aligns FP doubles but doubleword-aligns 64-bit ints. */
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
+ (TARGET_ALIGN_NATURAL ? (COMPUTED) : \
(TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
? get_inner_array_type (FIELD) \
: TREE_TYPE (FIELD)) == DFmode \
- ? MIN ((COMPUTED), 32) : (COMPUTED))
+ ? MIN ((COMPUTED), 32) : (COMPUTED)))
/* Darwin increases natural record alignment to doubleword if the first
field is an FP double while the FP fields remain word aligned. */
-#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
- ((TREE_CODE (STRUCT) == RECORD_TYPE \
- || TREE_CODE (STRUCT) == UNION_TYPE \
- || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
- && TYPE_FIELDS (STRUCT) != 0 \
- && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
- : (TARGET_ALTIVEC && TREE_CODE (STRUCT) == VECTOR_TYPE) \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \
+#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
+ ((TREE_CODE (STRUCT) == RECORD_TYPE \
+ || TREE_CODE (STRUCT) == UNION_TYPE \
+ || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
+ && TARGET_ALIGN_NATURAL == 0 \
+ ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \
+ : (TARGET_ALTIVEC && TREE_CODE (STRUCT) == VECTOR_TYPE) \
+ ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \
: MAX ((COMPUTED), (SPECIFIED)))
/* XXX: Darwin supports neither .quad, or .llong, but it also doesn't
@@ -245,3 +320,4 @@ Boston, MA 02111-1307, USA. */
#undef REGISTER_TARGET_PRAGMAS
#define REGISTER_TARGET_PRAGMAS DARWIN_REGISTER_TARGET_PRAGMAS
+
diff --git a/contrib/gcc/config/rs6000/default64.h b/contrib/gcc/config/rs6000/default64.h
new file mode 100644
index 000000000000..c6ed142d69b5
--- /dev/null
+++ b/contrib/gcc/config/rs6000/default64.h
@@ -0,0 +1,24 @@
+/* Definitions of target machine for GNU compiler,
+ for 64 bit powerpc linux defaulting to -m64.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT \
+ (MASK_POWERPC | MASK_POWERPC64 | MASK_64BIT | MASK_NEW_MNEMONICS)
diff --git a/contrib/gcc/config/rs6000/eabi-ci.asm b/contrib/gcc/config/rs6000/eabi-ci.asm
index 64ffbfc8725e..447b4e2378ca 100644
--- a/contrib/gcc/config/rs6000/eabi-ci.asm
+++ b/contrib/gcc/config/rs6000/eabi-ci.asm
@@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA.
#include <ppc-asm.h>
+#ifndef __powerpc64__
.section ".got","aw"
.globl __GOT_START__
.type __GOT_START__,@object
@@ -122,3 +123,4 @@ FUNC_START(__fini)
stwu 1,-16(1)
mflr 0
stw 0,20(1)
+#endif
diff --git a/contrib/gcc/config/rs6000/eabi-cn.asm b/contrib/gcc/config/rs6000/eabi-cn.asm
index 4a01dc634548..b2c609532ce3 100644
--- a/contrib/gcc/config/rs6000/eabi-cn.asm
+++ b/contrib/gcc/config/rs6000/eabi-cn.asm
@@ -39,6 +39,7 @@ Boston, MA 02111-1307, USA.
.file "crtn.s"
.ident "GNU C crtn.s"
+#ifndef __powerpc64__
.section ".got","aw"
.globl __GOT_END__
.type __GOT_END__,@object
@@ -113,3 +114,4 @@ __EH_FRAME_END__:
mtlr 0
addi 1,1,16
blr
+#endif
diff --git a/contrib/gcc/config/rs6000/eabi.h b/contrib/gcc/config/rs6000/eabi.h
index 373dd2b6fc70..ff8df2c3e417 100644
--- a/contrib/gcc/config/rs6000/eabi.h
+++ b/contrib/gcc/config/rs6000/eabi.h
@@ -1,30 +1,30 @@
/* Core target definitions for GNU compiler
for IBM RS/6000 PowerPC targeted to embedded ELF systems.
- Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2000, 2003 Free Software Foundation, Inc.
Contributed by Cygnus Support.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-/* Add -meabi to target flags */
+/* Add -meabi to target flags. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI)
-/* Invoke an initializer function to set up the GOT */
+/* Invoke an initializer function to set up the GOT. */
#define NAME__MAIN "__eabi"
#define INVOKE__main
@@ -40,15 +40,18 @@ Boston, MA 02111-1307, USA. */
builtin_assert ("system=embedded"); \
builtin_assert ("cpu=powerpc"); \
builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
} \
while (0)
#undef TARGET_SPE_ABI
#undef TARGET_SPE
+#undef TARGET_E500
#undef TARGET_ISEL
#undef TARGET_FPRS
#define TARGET_SPE_ABI rs6000_spe_abi
-#define TARGET_SPE (rs6000_cpu == PROCESSOR_PPC8540)
+#define TARGET_SPE rs6000_spe
+#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
#define TARGET_ISEL rs6000_isel
-#define TARGET_FPRS rs6000_fprs
+#define TARGET_FPRS (!rs6000_float_gprs)
diff --git a/contrib/gcc/config/rs6000/eabialtivec.h b/contrib/gcc/config/rs6000/eabialtivec.h
index 23ec8c95a329..e407e3bc7cfa 100644
--- a/contrib/gcc/config/rs6000/eabialtivec.h
+++ b/contrib/gcc/config/rs6000/eabialtivec.h
@@ -1,31 +1,31 @@
/* Core target definitions for GNU compiler
for PowerPC targeted systems with AltiVec support.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Add -meabi and -maltivec to target flags. */
-#undef TARGET_DEFAULT
+#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI | MASK_ALTIVEC)
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded with AltiVec)");
-#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS rs6000_altivec_abi = 1
diff --git a/contrib/gcc/config/rs6000/eabisim.h b/contrib/gcc/config/rs6000/eabisim.h
index 00f710e5cb4a..5e0900d9c1e7 100644
--- a/contrib/gcc/config/rs6000/eabisim.h
+++ b/contrib/gcc/config/rs6000/eabisim.h
@@ -1,29 +1,29 @@
/* Support for GCC on simulated PowerPC systems targeted to embedded ELF
systems.
- Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2000, 2003 Free Software Foundation, Inc.
Contributed by Cygnus Support.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Simulated)");
-#undef TARGET_OS_CPP_BUILTINS
+#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA. */
builtin_assert ("system=simulator"); \
builtin_assert ("cpu=powerpc"); \
builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
} \
while (0)
diff --git a/contrib/gcc/config/rs6000/eabispe.h b/contrib/gcc/config/rs6000/eabispe.h
index b0047cd0c8a2..1551dc1305da 100644
--- a/contrib/gcc/config/rs6000/eabispe.h
+++ b/contrib/gcc/config/rs6000/eabispe.h
@@ -1,51 +1,57 @@
/* Core target definitions for GNU compiler
for PowerPC embedded targeted systems with SPE support.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef TARGET_DEFAULT
+#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI)
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Embedded SPE)");
-#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS \
- rs6000_cpu = PROCESSOR_PPC8540; \
- rs6000_spe_abi = 1; \
- rs6000_fprs = 0; \
+ if (rs6000_select[1].string == NULL) \
+ rs6000_cpu = PROCESSOR_PPC8540; \
+ if (rs6000_abi_string == NULL) \
+ rs6000_spe_abi = 1; \
+ if (rs6000_float_gprs_string == NULL) \
+ rs6000_float_gprs = 1; \
/* See note below. */ \
- /*rs6000_long_double_type_size = 128;*/ \
- rs6000_isel = 1
-
-/*
- The e500 ABI says that either long doubles are 128 bits, or if
- implemented in any other size, the compiler/linker should error out.
- We have no emulation libraries for 128 bit long doubles, and I hate
- the dozens of failures on the regression suite. So I'm breaking ABI
- specifications, until I properly fix the emulation.
-
- Enable these later.
+ /*if (rs6000_long_double_size_string == NULL)*/ \
+ /* rs6000_long_double_type_size = 128;*/ \
+ if (rs6000_spe_string == NULL) \
+ rs6000_spe = 1; \
+ if (rs6000_isel_string == NULL) \
+ rs6000_isel = 1
+
+/* The e500 ABI says that either long doubles are 128 bits, or if
+ implemented in any other size, the compiler/linker should error out.
+ We have no emulation libraries for 128 bit long doubles, and I hate
+ the dozens of failures on the regression suite. So I'm breaking ABI
+ specifications, until I properly fix the emulation.
+
+ Enable these later.
#undef CPP_LONGDOUBLE_DEFAULT_SPEC
#define CPP_LONGDOUBLE_DEFAULT_SPEC "-D__LONG_DOUBLE_128__=1"
*/
-#undef ASM_DEFAULT_SPEC
+#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mppc -mspe -me500"
diff --git a/contrib/gcc/config/rs6000/freebsd.h b/contrib/gcc/config/rs6000/freebsd.h
index 699d2adbda8b..fe6a801bb2cb 100644
--- a/contrib/gcc/config/rs6000/freebsd.h
+++ b/contrib/gcc/config/rs6000/freebsd.h
@@ -1,22 +1,23 @@
/* Definitions for PowerPC running FreeBSD using the ELF format
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Override the defaults, which exist to force the proper definition. */
@@ -39,7 +40,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define LINK_OS_DEFAULT_SPEC "%(link_os_freebsd)"
/* XXX: This is wrong for many platforms in sysv4.h.
- We should work on getting that defination fixed. */
+ We should work on getting that definition fixed. */
#undef LINK_SHLIB_SPEC
#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}"
diff --git a/contrib/gcc/config/rs6000/gnu.h b/contrib/gcc/config/rs6000/gnu.h
index 9aeb696db2fe..658a6d60193f 100644
--- a/contrib/gcc/config/rs6000/gnu.h
+++ b/contrib/gcc/config/rs6000/gnu.h
@@ -1,23 +1,23 @@
/* Definitions of target machine for GNU compiler,
for PowerPC machines running GNU.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_gnu)"
@@ -34,5 +34,5 @@ Boston, MA 02111-1307, USA. */
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_gnu)"
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU)");
diff --git a/contrib/gcc/config/rs6000/host-darwin.c b/contrib/gcc/config/rs6000/host-darwin.c
new file mode 100644
index 000000000000..7e8055690e42
--- /dev/null
+++ b/contrib/gcc/config/rs6000/host-darwin.c
@@ -0,0 +1,189 @@
+/* Darwin/powerpc host-specific hook definitions.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include <signal.h>
+#include <sys/ucontext.h>
+#include <sys/mman.h>
+#include "hosthooks.h"
+#include "hosthooks-def.h"
+#include "toplev.h"
+#include "diagnostic.h"
+
+static void segv_crash_handler (int);
+static void segv_handler (int, siginfo_t *, void *);
+static void darwin_rs6000_extra_signals (void);
+
+/* This doesn't have a prototype in signal.h in 10.2.x and earlier,
+ fixed in later releases. */
+extern int sigaltstack(const struct sigaltstack *, struct sigaltstack *);
+
+#undef HOST_HOOKS_EXTRA_SIGNALS
+#define HOST_HOOKS_EXTRA_SIGNALS darwin_rs6000_extra_signals
+
+/* On Darwin/powerpc, hitting the stack limit turns into a SIGSEGV.
+ This code detects the difference between hitting the stack limit and
+ a true wild pointer dereference by looking at the instruction that
+ faulted; only a few kinds of instruction are used to access below
+ the previous bottom of the stack. */
+
+static void
+segv_crash_handler (int sig ATTRIBUTE_UNUSED)
+{
+ internal_error ("Segmentation Fault (code)");
+}
+
+static void
+segv_handler (int sig ATTRIBUTE_UNUSED,
+ siginfo_t *sip ATTRIBUTE_UNUSED,
+ void *scp)
+{
+ ucontext_t *uc = (ucontext_t *)scp;
+ unsigned faulting_insn;
+
+ /* The fault might have happened when trying to run some instruction, in
+ which case the next line will segfault _again_. Handle this case. */
+ signal (SIGSEGV, segv_crash_handler);
+
+ faulting_insn = *(unsigned *)uc->uc_mcontext->ss.srr0;
+
+ /* Note that this only has to work for GCC, so we don't have to deal
+ with all the possible cases (GCC has no AltiVec code, for
+ instance). It's complicated because Darwin allows stores to
+ below the stack pointer, and the prologue code takes advantage of
+ this. */
+
+ if ((faulting_insn & 0xFFFF8000) == 0x94218000 /* stwu %r1, -xxx(%r1) */
+ || (faulting_insn & 0xFFFF03FF) == 0x7C21016E /* stwux %r1, xxx, %r1 */
+ || (faulting_insn & 0xFC1F8000) == 0x90018000 /* stw xxx, -yyy(%r1) */
+ || (faulting_insn & 0xFC1F8000) == 0xD8018000 /* stfd xxx, -yyy(%r1) */
+ || (faulting_insn & 0xFC1F8000) == 0xBC018000 /* stmw xxx, -yyy(%r1) */)
+ {
+ char *shell_name;
+
+ fnotice (stderr, "Out of stack space.\n");
+ shell_name = getenv ("SHELL");
+ if (shell_name != NULL)
+ shell_name = strrchr (shell_name, '/');
+ if (shell_name != NULL)
+ {
+ static const char * shell_commands[][2] = {
+ { "sh", "ulimit -S -s unlimited" },
+ { "bash", "ulimit -S -s unlimited" },
+ { "tcsh", "limit stacksize unlimited" },
+ { "csh", "limit stacksize unlimited" },
+ /* zsh doesn't have "unlimited", this will work under the
+ default configuration. */
+ { "zsh", "limit stacksize 32m" }
+ };
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE (shell_commands); i++)
+ if (strcmp (shell_commands[i][0], shell_name + 1) == 0)
+ {
+ fnotice (stderr,
+ "Try running `%s' in the shell to raise its limit.\n",
+ shell_commands[i][1]);
+ }
+ }
+
+ if (global_dc->abort_on_error)
+ abort ();
+
+ exit (FATAL_EXIT_CODE);
+ }
+
+ fprintf (stderr, "[address=%08lx pc=%08x]\n",
+ uc->uc_mcontext->es.dar, uc->uc_mcontext->ss.srr0);
+ internal_error ("Segmentation Fault");
+ exit (FATAL_EXIT_CODE);
+}
+
+static void
+darwin_rs6000_extra_signals (void)
+{
+ struct sigaction sact;
+ stack_t sigstk;
+
+ sigstk.ss_sp = xmalloc (SIGSTKSZ);
+ sigstk.ss_size = SIGSTKSZ;
+ sigstk.ss_flags = 0;
+ if (sigaltstack (&sigstk, NULL) < 0)
+ fatal_error ("While setting up signal stack: %m");
+
+ sigemptyset(&sact.sa_mask);
+ sact.sa_flags = SA_ONSTACK | SA_SIGINFO;
+ sact.sa_sigaction = segv_handler;
+ if (sigaction (SIGSEGV, &sact, 0) < 0)
+ fatal_error ("While setting up signal handler: %m");
+}
+
+static void * darwin_rs6000_gt_pch_get_address (size_t);
+static bool darwin_rs6000_gt_pch_use_address (void *, size_t);
+
+#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
+#define HOST_HOOKS_GT_PCH_GET_ADDRESS darwin_rs6000_gt_pch_get_address
+#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
+#define HOST_HOOKS_GT_PCH_USE_ADDRESS darwin_rs6000_gt_pch_use_address
+
+
+/* Yes, this is really supposed to work. */
+static char pch_address_space[1024*1024*1024] __attribute__((aligned (4096)));
+
+/* Return the address of the PCH address space, if the PCH will fit in it. */
+
+static void *
+darwin_rs6000_gt_pch_get_address (size_t sz)
+{
+ if (sz <= sizeof (pch_address_space))
+ return pch_address_space;
+ else
+ return NULL;
+}
+
+/* Check ADDR and SZ for validity, and deallocate (using munmap) that part of
+ pch_address_space beyond SZ. */
+
+static bool
+darwin_rs6000_gt_pch_use_address (void *addr, size_t sz)
+{
+ const size_t pagesize = getpagesize();
+ bool result;
+
+ if ((size_t)pch_address_space % pagesize != 0
+ || sizeof (pch_address_space) % pagesize != 0)
+ abort ();
+
+ result = (addr == pch_address_space && sz <= sizeof (pch_address_space));
+ if (! result)
+ sz = 0;
+
+ /* Round the size to a whole page size. Normally this is a no-op. */
+ sz = (sz + pagesize - 1) / pagesize * pagesize;
+
+ if (munmap (pch_address_space + sz, sizeof (pch_address_space) - sz) != 0)
+ fatal_error ("couldn't unmap pch_address_space: %m\n");
+
+ return result;
+}
+
+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
diff --git a/contrib/gcc/config/rs6000/kaos-ppc.h b/contrib/gcc/config/rs6000/kaos-ppc.h
new file mode 100644
index 000000000000..d6b92e73e6a8
--- /dev/null
+++ b/contrib/gcc/config/rs6000/kaos-ppc.h
@@ -0,0 +1,24 @@
+/* Definitions of target machine for GNU compiler.
+ kaOS on PowerPC architecture version.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fputs (" (PowerPC/kaOS[ELF])", stderr);
+
diff --git a/contrib/gcc/config/rs6000/libgcc-ppc64.ver b/contrib/gcc/config/rs6000/libgcc-ppc64.ver
new file mode 100644
index 000000000000..116d5e73fa07
--- /dev/null
+++ b/contrib/gcc/config/rs6000/libgcc-ppc64.ver
@@ -0,0 +1,7 @@
+GCC_3.4 {
+ # long double support
+ _xlqadd
+ _xlqsub
+ _xlqmul
+ _xlqdiv
+}
diff --git a/contrib/gcc/config/rs6000/linux.h b/contrib/gcc/config/rs6000/linux.h
index 15db88a9e6e5..009ac6637bb9 100644
--- a/contrib/gcc/config/rs6000/linux.h
+++ b/contrib/gcc/config/rs6000/linux.h
@@ -4,35 +4,35 @@
Free Software Foundation, Inc.
Contributed by Michael Meissner (meissner@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
-#undef TARGET_OS_CPP_BUILTINS
+#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
builtin_define_std ("PPC"); \
- builtin_define ("__ELF__"); \
builtin_define_std ("powerpc"); \
builtin_assert ("cpu=powerpc"); \
builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
} \
while (0)
@@ -42,15 +42,12 @@ Boston, MA 02111-1307, USA. */
/* The GNU C++ standard library currently requires _GNU_SOURCE being
defined on glibc-based systems. This temporary hack accomplishes this,
it should go away as soon as libstdc++-v3 has a real fix. */
-#undef CPLUSPLUS_CPP_SPEC
+#undef CPLUSPLUS_CPP_SPEC
#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-#undef LINK_SHLIB_SPEC
+#undef LINK_SHLIB_SPEC
#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}"
-#define LINK_GCC_C_SEQUENCE_SPEC \
- "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
-
#undef LIB_DEFAULT_SPEC
#define LIB_DEFAULT_SPEC "%(lib_linux)"
@@ -66,22 +63,36 @@ Boston, MA 02111-1307, USA. */
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
-#undef TARGET_VERSION
+#define LINK_GCC_C_SEQUENCE_SPEC \
+ "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU/Linux)");
/* Override rs6000.h definition. */
-#undef ASM_APP_ON
+#undef ASM_APP_ON
#define ASM_APP_ON "#APP\n"
/* Override rs6000.h definition. */
-#undef ASM_APP_OFF
+#undef ASM_APP_OFF
#define ASM_APP_OFF "#NO_APP\n"
/* For backward compatibility, we must continue to use the AIX
structure return convention. */
-#undef DRAFT_V4_STRUCT_RET
+#undef DRAFT_V4_STRUCT_RET
#define DRAFT_V4_STRUCT_RET 1
+/* We are 32-bit all the time, so optimize a little. */
+#undef TARGET_64BIT
+#define TARGET_64BIT 0
+
+/* We don't need to generate entries in .fixup. */
+#undef RELOCATABLE_NEEDS_FIXUP
+
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
+
+#define TARGET_HAS_F_SETLKW
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
@@ -165,3 +176,4 @@ enum { SIGNAL_FRAMESIZE = 64 };
goto SUCCESS; \
} while (0)
+#define OS_MISSING_POWERPC64 1
diff --git a/contrib/gcc/config/rs6000/linux64.h b/contrib/gcc/config/rs6000/linux64.h
index a538d02b955d..4fe419911c8c 100644
--- a/contrib/gcc/config/rs6000/linux64.h
+++ b/contrib/gcc/config/rs6000/linux64.h
@@ -1,128 +1,315 @@
/* Definitions of target machine for GNU compiler,
for 64 bit PowerPC linux.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-/* Yes! We are AIX! Err. Wait. We're Linux!. No, wait, we're a
- combo of both!*/
-#undef DEFAULT_ABI
-#define DEFAULT_ABI ABI_AIX
+#ifndef RS6000_BI_ARCH
-#undef TARGET_AIX
-#define TARGET_AIX 1
+#undef DEFAULT_ABI
+#define DEFAULT_ABI ABI_AIX
-#undef TARGET_DEFAULT
-#define TARGET_DEFAULT \
- (MASK_POWERPC | MASK_POWERPC64 | MASK_64BIT | MASK_NEW_MNEMONICS)
+#undef TARGET_64BIT
+#define TARGET_64BIT 1
+
+#define DEFAULT_ARCH64_P 1
+#define RS6000_BI_ARCH_P 0
+
+#else
+
+#define DEFAULT_ARCH64_P (TARGET_DEFAULT & MASK_64BIT)
+#define RS6000_BI_ARCH_P 1
+
+#endif
+
+#ifdef IN_LIBGCC2
+#undef TARGET_64BIT
+#ifdef __powerpc64__
+#define TARGET_64BIT 1
+#else
+#define TARGET_64BIT 0
+#endif
+#endif
+
+#undef TARGET_AIX
+#define TARGET_AIX TARGET_64BIT
-#undef PROCESSOR_DEFAULT
-#define PROCESSOR_DEFAULT PROCESSOR_PPC630
#undef PROCESSOR_DEFAULT64
#define PROCESSOR_DEFAULT64 PROCESSOR_PPC630
-#undef ASM_DEFAULT_SPEC
-#define ASM_DEFAULT_SPEC "-mppc64"
+#undef TARGET_RELOCATABLE
+#define TARGET_RELOCATABLE (!TARGET_64BIT && (target_flags & MASK_RELOCATABLE))
+
+#undef RS6000_ABI_NAME
+#define RS6000_ABI_NAME (TARGET_64BIT ? "aixdesc" : "sysv")
+
+#define INVALID_64BIT "-m%s not supported in this configuration"
+#define INVALID_32BIT INVALID_64BIT
+
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#define SUBSUBTARGET_OVERRIDE_OPTIONS \
+ do \
+ { \
+ if (rs6000_alignment_string == 0) \
+ rs6000_alignment_flags = MASK_ALIGN_NATURAL; \
+ if (TARGET_64BIT) \
+ { \
+ if (DEFAULT_ABI != ABI_AIX) \
+ { \
+ rs6000_current_abi = ABI_AIX; \
+ error (INVALID_64BIT, "call"); \
+ } \
+ if (target_flags & MASK_RELOCATABLE) \
+ { \
+ target_flags &= ~MASK_RELOCATABLE; \
+ error (INVALID_64BIT, "relocatable"); \
+ } \
+ if (target_flags & MASK_EABI) \
+ { \
+ target_flags &= ~MASK_EABI; \
+ error (INVALID_64BIT, "eabi"); \
+ } \
+ if (target_flags & MASK_PROTOTYPE) \
+ { \
+ target_flags &= ~MASK_PROTOTYPE; \
+ error (INVALID_64BIT, "prototype"); \
+ } \
+ if ((target_flags & MASK_POWERPC64) == 0) \
+ { \
+ target_flags |= MASK_POWERPC64; \
+ error ("-m64 requires a PowerPC64 cpu"); \
+ } \
+ } \
+ else \
+ { \
+ if (!RS6000_BI_ARCH_P) \
+ error (INVALID_32BIT, "32"); \
+ if (TARGET_PROFILE_KERNEL) \
+ { \
+ target_flags &= ~MASK_PROFILE_KERNEL; \
+ error (INVALID_32BIT, "profile-kernel"); \
+ } \
+ } \
+ } \
+ while (0)
+
+#ifdef RS6000_BI_ARCH
+
+#undef OVERRIDE_OPTIONS
+#define OVERRIDE_OPTIONS \
+ rs6000_override_options (((TARGET_DEFAULT ^ target_flags) & MASK_64BIT) \
+ ? (char *) 0 : TARGET_CPU_DEFAULT)
+
+#endif
+#undef ASM_DEFAULT_SPEC
#undef ASM_SPEC
-#define ASM_SPEC "%{.s: %{mregnames} %{mno-regnames}} \
-%{.S: %{mregnames} %{mno-regnames}} \
-%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian} \
-%{v:-V} %{Qy:} %{!Qn:-Qy} -a64 %(asm_cpu) %{Wa,*:%*}"
+#undef LINK_OS_LINUX_SPEC
+
+#ifndef RS6000_BI_ARCH
+#define ASM_DEFAULT_SPEC "-mppc64"
+#define ASM_SPEC "%(asm_spec64) %(asm_spec_common)"
+#define LINK_OS_LINUX_SPEC "%(link_os_linux_spec64)"
+#else
+#if DEFAULT_ARCH64_P
+#define ASM_DEFAULT_SPEC "-mppc%{!m32:64}"
+#define ASM_SPEC "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)"
+#define LINK_OS_LINUX_SPEC "%{m32:%(link_os_linux_spec32)}%{!m32:%(link_os_linux_spec64)}"
+#else
+#define ASM_DEFAULT_SPEC "-mppc%{m64:64}"
+#define ASM_SPEC "%{!m64:%(asm_spec32)}%{m64:%(asm_spec64)} %(asm_spec_common)"
+#define LINK_OS_LINUX_SPEC "%{!m64:%(link_os_linux_spec32)}%{m64:%(link_os_linux_spec64)}"
+#endif
+#endif
+
+#define ASM_SPEC32 "-a32 %{n} %{T} %{Ym,*} %{Yd,*} \
+%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
+%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \
+%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
+ %{mcall-freebsd: -mbig} \
+ %{mcall-i960-old: -mlittle} \
+ %{mcall-linux: -mbig} \
+ %{mcall-gnu: -mbig} \
+ %{mcall-netbsd: -mbig} \
+}}}}"
+
+#define ASM_SPEC64 "-a64"
+
+#define ASM_SPEC_COMMON "%(asm_cpu) \
+%{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \
+%{v:-V} %{Qy:} %{!Qn:-Qy} %{Wa,*:%*} \
+%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}"
+
+#undef SUBSUBTARGET_EXTRA_SPECS
+#define SUBSUBTARGET_EXTRA_SPECS \
+ { "asm_spec_common", ASM_SPEC_COMMON }, \
+ { "asm_spec32", ASM_SPEC32 }, \
+ { "asm_spec64", ASM_SPEC64 }, \
+ { "link_os_linux_spec32", LINK_OS_LINUX_SPEC32 }, \
+ { "link_os_linux_spec64", LINK_OS_LINUX_SPEC64 },
+
+#undef MULTILIB_DEFAULTS
+#if DEFAULT_ARCH64_P
+#define MULTILIB_DEFAULTS { "m64" }
+#else
+#define MULTILIB_DEFAULTS { "m32" }
+#endif
+
+#ifndef RS6000_BI_ARCH
+
+/* 64-bit PowerPC Linux is always big-endian. */
+#undef TARGET_LITTLE_ENDIAN
+#define TARGET_LITTLE_ENDIAN 0
/* 64-bit PowerPC Linux always has a TOC. */
-#undef TARGET_NO_TOC
-#define TARGET_NO_TOC 0
#undef TARGET_TOC
#define TARGET_TOC 1
-/* We use glibc _mcount for profiling. */
-#define NO_PROFILE_COUNTERS 1
-#undef PROFILE_BEFORE_PROLOGUE
+/* Some things from sysv4.h we don't do when 64 bit. */
+#undef TARGET_RELOCATABLE
+#define TARGET_RELOCATABLE 0
+#undef TARGET_EABI
+#define TARGET_EABI 0
+#undef TARGET_PROTOTYPE
+#define TARGET_PROTOTYPE 0
+
+#endif
-/* Define this for kernel profiling, which just saves LR then calls
+#define MASK_PROFILE_KERNEL 0x00100000
+
+/* Non-standard profiling for kernels, which just saves LR then calls
_mcount without worrying about arg saves. The idea is to change
the function prologue as little as possible as it isn't easy to
account for arg save/restore code added just for _mcount. */
-/* #define PROFILE_KERNEL 1 */
-#if PROFILE_KERNEL
-#define PROFILE_BEFORE_PROLOGUE 1
-#undef PROFILE_HOOK
-#else
-#define PROFILE_HOOK(LABEL) output_profile_hook (LABEL)
-#endif
+#define TARGET_PROFILE_KERNEL (target_flags & MASK_PROFILE_KERNEL)
+
+/* Override sysv4.h. */
+#undef EXTRA_SUBTARGET_SWITCHES
+#define EXTRA_SUBTARGET_SWITCHES \
+ {"profile-kernel", MASK_PROFILE_KERNEL, \
+ N_("Call mcount for profiling before a function prologue") }, \
+ {"no-profile-kernel", -MASK_PROFILE_KERNEL, \
+ N_("Call mcount for profiling after a function prologue") },
+
+/* We use glibc _mcount for profiling. */
+#define NO_PROFILE_COUNTERS TARGET_64BIT
+#define PROFILE_HOOK(LABEL) \
+ do { if (TARGET_64BIT) output_profile_hook (LABEL); } while (0)
/* We don't need to generate entries in .fixup. */
#undef RELOCATABLE_NEEDS_FIXUP
-#define USER_LABEL_PREFIX ""
-
-/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */
+/* PowerPC64 Linux word-aligns FP doubles when -malign-power is given. */
#undef ADJUST_FIELD_ALIGN
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
- (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
- ? get_inner_array_type (FIELD) \
- : TREE_TYPE (FIELD)) == DFmode \
- ? MIN ((COMPUTED), 32) : (COMPUTED))
-
-/* AIX increases natural record alignment to doubleword if the first
- field is an FP double while the FP fields remain word aligned. */
-#undef ROUND_TYPE_ALIGN
-#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
- ((TREE_CODE (STRUCT) == RECORD_TYPE \
- || TREE_CODE (STRUCT) == UNION_TYPE \
- || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
- && TYPE_FIELDS (STRUCT) != 0 \
- && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
+ ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
+ ? 128 \
+ : (TARGET_64BIT \
+ && TARGET_ALIGN_NATURAL == 0 \
+ && TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
+ ? get_inner_array_type (FIELD) \
+ : TREE_TYPE (FIELD)) == DFmode) \
+ ? MIN ((COMPUTED), 32) \
+ : (COMPUTED))
+
+/* PowerPC64 Linux increases natural record alignment to doubleword if
+ the first field is an FP double, only if in power alignment mode. */
+#undef ROUND_TYPE_ALIGN
+#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
+ ((TARGET_ALTIVEC && TREE_CODE (STRUCT) == VECTOR_TYPE) \
+ ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \
+ : (TARGET_64BIT \
+ && (TREE_CODE (STRUCT) == RECORD_TYPE \
+ || TREE_CODE (STRUCT) == UNION_TYPE \
+ || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
+ && TARGET_ALIGN_NATURAL == 0) \
+ ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \
: MAX ((COMPUTED), (SPECIFIED)))
/* Indicate that jump tables go in the text section. */
#undef JUMP_TABLES_IN_TEXT_SECTION
-#define JUMP_TABLES_IN_TEXT_SECTION 1
-
-/* 64-bit PowerPC Linux always has GPR13 fixed. */
-#define FIXED_R13 1
+#define JUMP_TABLES_IN_TEXT_SECTION TARGET_64BIT
+
+/* The linux ppc64 ABI isn't explicit on whether aggregates smaller
+ than a doubleword should be padded upward or downward. You could
+ reasonably assume that they follow the normal rules for structure
+ layout treating the parameter area as any other block of memory,
+ then map the reg param area to registers. ie. pad updard.
+ Setting both of the following defines results in this behavior.
+ Setting just the first one will result in aggregates that fit in a
+ doubleword being padded downward, and others being padded upward.
+ Not a bad idea as this results in struct { int x; } being passed
+ the same way as an int. */
+#define AGGREGATE_PADDING_FIXED TARGET_64BIT
+#define AGGREGATES_PAD_UPWARD_ALWAYS 0
+
+/* We don't want anything in the reg parm area being passed on the
+ stack. */
+#define MUST_PASS_IN_STACK(MODE, TYPE) \
+ ((TARGET_64BIT \
+ && (TYPE) != 0 \
+ && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
+ || TREE_ADDRESSABLE (TYPE))) \
+ || (!TARGET_64BIT \
+ && default_must_pass_in_stack ((MODE), (TYPE))))
+
+/* Specify padding for the last element of a block move between
+ registers and memory. FIRST is nonzero if this is the only
+ element. */
+#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
+ (!(FIRST) ? upward : FUNCTION_ARG_PADDING (MODE, TYPE))
/* __throw will restore its own return address to be the same as the
return address of the function that the throw is being made to.
This is unfortunate, because we want to check the original
return address to see if we need to restore the TOC.
So we have to squirrel it away with this. */
-#define SETUP_FRAME_ADDRESSES() rs6000_aix_emit_builtin_unwind_init ()
+#define SETUP_FRAME_ADDRESSES() \
+ do { if (TARGET_64BIT) rs6000_aix_emit_builtin_unwind_init (); } while (0)
/* Override svr4.h */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
-#undef TARGET_OS_CPP_BUILTINS
-#define TARGET_OS_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("__PPC__"); \
- builtin_define ("__PPC64__"); \
- builtin_define ("__powerpc__"); \
- builtin_define ("__powerpc64__"); \
- builtin_define ("__PIC__"); \
- builtin_define ("__ELF__"); \
- builtin_assert ("cpu=powerpc64"); \
- builtin_assert ("machine=powerpc64"); \
- } \
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ if (TARGET_64BIT) \
+ { \
+ builtin_define ("__PPC__"); \
+ builtin_define ("__PPC64__"); \
+ builtin_define ("__powerpc__"); \
+ builtin_define ("__powerpc64__"); \
+ builtin_define ("__PIC__"); \
+ builtin_assert ("cpu=powerpc64"); \
+ builtin_assert ("machine=powerpc64"); \
+ } \
+ else \
+ { \
+ builtin_define_std ("PPC"); \
+ builtin_define_std ("powerpc"); \
+ builtin_assert ("cpu=powerpc"); \
+ builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
+ } \
+ } \
while (0)
#undef CPP_OS_DEFAULT_SPEC
@@ -137,9 +324,6 @@ Boston, MA 02111-1307, USA. */
#undef LINK_SHLIB_SPEC
#define LINK_SHLIB_SPEC "%{shared:-shared} %{!shared: %{static:-static}}"
-#define LINK_GCC_C_SEQUENCE_SPEC \
- "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
-
#undef LIB_DEFAULT_SPEC
#define LIB_DEFAULT_SPEC "%(lib_linux)"
@@ -155,43 +339,40 @@ Boston, MA 02111-1307, USA. */
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_linux)"
-#undef LINK_OS_LINUX_SPEC
-#define LINK_OS_LINUX_SPEC "-m elf64ppc %{!shared: %{!static: \
+#define LINK_OS_LINUX_SPEC32 "-m elf32ppclinux %{!shared: %{!static: \
%{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /lib64/ld64.so.1}}}"
+ %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}"
-#ifdef NATIVE_CROSS
-#define STARTFILE_PREFIX_SPEC "/usr/local/lib64/ /lib64/ /usr/lib64/"
-#endif
-
-#undef STARTFILE_LINUX_SPEC
-#define STARTFILE_LINUX_SPEC "\
-%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} crti.o%s \
-%{static:crtbeginT.o%s} \
-%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
-
-#undef ENDFILE_LINUX_SPEC
-#define ENDFILE_LINUX_SPEC "\
-%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+#define LINK_OS_LINUX_SPEC64 "-m elf64ppc %{!shared: %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib64/ld64.so.1}}}"
#undef TOC_SECTION_ASM_OP
-#define TOC_SECTION_ASM_OP "\t.section\t\".toc\",\"aw\""
+#define TOC_SECTION_ASM_OP \
+ (TARGET_64BIT \
+ ? "\t.section\t\".toc\",\"aw\"" \
+ : "\t.section\t\".got\",\"aw\"")
#undef MINIMAL_TOC_SECTION_ASM_OP
-#define MINIMAL_TOC_SECTION_ASM_OP "\t.section\t\".toc1\",\"aw\""
+#define MINIMAL_TOC_SECTION_ASM_OP \
+ (TARGET_64BIT \
+ ? "\t.section\t\".toc1\",\"aw\"" \
+ : ((TARGET_RELOCATABLE || flag_pic) \
+ ? "\t.section\t\".got2\",\"aw\"" \
+ : "\t.section\t\".got1\",\"aw\""))
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC64 GNU/Linux)");
/* Must be at least as big as our pointer type. */
-#undef SIZE_TYPE
-#define SIZE_TYPE "long unsigned int"
+#undef SIZE_TYPE
+#define SIZE_TYPE (TARGET_64BIT ? "long unsigned int" : "unsigned int")
-#undef PTRDIFF_TYPE
-#define PTRDIFF_TYPE "long int"
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
-#undef WCHAR_TYPE
-#define WCHAR_TYPE "int"
+#undef WCHAR_TYPE
+#define WCHAR_TYPE (TARGET_64BIT ? "int" : "long int")
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
@@ -205,7 +386,7 @@ Boston, MA 02111-1307, USA. */
/* PowerPC no-op instruction. */
#undef RS6000_CALL_GLUE
-#define RS6000_CALL_GLUE "nop"
+#define RS6000_CALL_GLUE (TARGET_64BIT ? "nop" : "cror 31,31,31")
#undef RS6000_MCOUNT
#define RS6000_MCOUNT "_mcount"
@@ -224,64 +405,18 @@ Boston, MA 02111-1307, USA. */
/* FP save and restore routines. */
#undef SAVE_FP_PREFIX
-#define SAVE_FP_PREFIX "._savef"
+#define SAVE_FP_PREFIX (TARGET_64BIT ? "._savef" : "_savefpr_")
#undef SAVE_FP_SUFFIX
-#define SAVE_FP_SUFFIX ""
+#define SAVE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
#undef RESTORE_FP_PREFIX
-#define RESTORE_FP_PREFIX "._restf"
+#define RESTORE_FP_PREFIX (TARGET_64BIT ? "._restf" : "_restfpr_")
#undef RESTORE_FP_SUFFIX
-#define RESTORE_FP_SUFFIX ""
+#define RESTORE_FP_SUFFIX (TARGET_64BIT ? "" : "_l")
/* Dwarf2 debugging. */
#undef PREFERRED_DEBUGGING_TYPE
#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO rs6000_xcoff_encode_section_info
-
-/* This is how to output a reference to a user-level label named NAME.
- `assemble_name' uses this. */
-
-/* Override elfos.h definition. */
-#undef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(FILE,NAME) \
-do { \
- const char *_name = NAME; \
- if (*_name == '@') \
- _name++; \
- \
- if (*_name == '*') \
- fprintf (FILE, "%s", _name + 1); \
- else \
- asm_fprintf (FILE, "%U%s", _name); \
-} while (0)
-
-#undef ASM_DECLARE_FUNCTION_NAME
-#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
- do \
- { \
- fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", (FILE)); \
- ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- fputs (DOUBLE_INT_ASM_OP, (FILE)); \
- putc ('.', (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputs (",.TOC.@tocbase,0\n\t.previous\n\t.size\t", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputs (",24\n\t.type\t.", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputs (",@function\n", (FILE)); \
- if (TREE_PUBLIC (DECL) && ! DECL_WEAK (DECL)) \
- { \
- fputs ("\t.globl\t.", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- putc ('\n', (FILE)); \
- } \
- ASM_DECLARE_RESULT ((FILE), DECL_RESULT (DECL)); \
- putc ('.', (FILE)); \
- ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- } \
- while (0)
-
/* This is how to declare the size of a function. */
#undef ASM_DECLARE_FUNCTION_SIZE
#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \
@@ -289,9 +424,13 @@ do { \
{ \
if (!flag_inhibit_size_directive) \
{ \
- fputs ("\t.size\t.", (FILE)); \
+ fputs ("\t.size\t", (FILE)); \
+ if (TARGET_64BIT) \
+ putc ('.', (FILE)); \
assemble_name ((FILE), (FNAME)); \
- fputs (",.-.", (FILE)); \
+ fputs (",.-", (FILE)); \
+ if (TARGET_64BIT) \
+ putc ('.', (FILE)); \
assemble_name ((FILE), (FNAME)); \
putc ('\n', (FILE)); \
} \
@@ -318,28 +457,34 @@ do { \
|| (GET_CODE (X) == CONST_INT \
&& GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode)) \
|| (GET_CODE (X) == CONST_DOUBLE \
- && (TARGET_POWERPC64 \
- || TARGET_MINIMAL_TOC \
- || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
- && ! TARGET_NO_FP_IN_TOC)))))
+ && ((TARGET_64BIT \
+ && (TARGET_POWERPC64 \
+ || TARGET_MINIMAL_TOC \
+ || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
+ && ! TARGET_NO_FP_IN_TOC))) \
+ || (!TARGET_64BIT \
+ && !TARGET_NO_FP_IN_TOC \
+ && !TARGET_RELOCATABLE \
+ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
+ && BITS_PER_WORD == HOST_BITS_PER_INT)))))
/* This is the same as the dbxelf.h version, except that we need to
use the function code label, not the function descriptor. */
#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \
+#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE, COUNTER) \
do \
{ \
- static int sym_lineno = 1; \
char temp[256]; \
- ASM_GENERATE_INTERNAL_LABEL (temp, "LM", sym_lineno); \
+ ASM_GENERATE_INTERNAL_LABEL (temp, "LM", COUNTER); \
fprintf (FILE, "\t.stabn 68,0,%d,", LINE); \
assemble_name (FILE, temp); \
- fputs ("-.", FILE); \
+ putc ('-', FILE); \
+ if (TARGET_64BIT) \
+ putc ('.', FILE); \
assemble_name (FILE, \
XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\
putc ('\n', FILE); \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, "LM", sym_lineno); \
- sym_lineno += 1; \
+ (*targetm.asm_out.internal_label) (FILE, "LM", COUNTER); \
} \
while (0)
@@ -355,7 +500,8 @@ while (0)
flab = IDENTIFIER_POINTER (current_function_func_begin_label); \
else \
{ \
- putc ('.', FILE); \
+ if (TARGET_64BIT) \
+ putc ('.', FILE); \
flab = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); \
} \
assemble_name (FILE, flab); \
@@ -372,19 +518,205 @@ while (0)
{ \
fprintf (FILE, "%s\"\",%d,0,0,", ASM_STABS_OP, N_FUN); \
assemble_name (FILE, LSCOPE); \
- fputs ("-.", FILE); \
+ putc ('-', FILE); \
+ if (TARGET_64BIT) \
+ putc ('.', FILE); \
assemble_name (FILE, XSTR (XEXP (DECL_RTL (DECL), 0), 0)); \
putc ('\n', FILE); \
} \
while (0)
-/* Override sysv4.h as these are ABI_V4 only. */
-#undef ASM_OUTPUT_REG_PUSH
-#undef ASM_OUTPUT_REG_POP
-
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations. */
#undef ASM_PREFERRED_EH_DATA_FORMAT
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
- (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_udata8)
+ ((TARGET_64BIT || flag_pic || TARGET_RELOCATABLE) \
+ ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel \
+ | (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4)) \
+ : DW_EH_PE_absptr)
+
+/* For backward compatibility, we must continue to use the AIX
+ structure return convention. */
+#undef DRAFT_V4_STRUCT_RET
+#define DRAFT_V4_STRUCT_RET (!TARGET_64BIT)
+
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
+
+#define TARGET_HAS_F_SETLKW
+
+#define LINK_GCC_C_SEQUENCE_SPEC \
+ "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+
+/* Do code reading to identify a signal frame, and set the frame
+ state data appropriately. See unwind-dw2.c for the structs. */
+
+#ifdef IN_LIBGCC2
+#include <signal.h>
+#ifdef __powerpc64__
+#include <sys/ucontext.h>
+
+enum { SIGNAL_FRAMESIZE = 128 };
+
+#else
+
+/* During the 2.5 kernel series the kernel ucontext was changed, but
+ the new layout is compatible with the old one, so we just define
+ and use the old one here for simplicity and compatibility. */
+
+struct kernel_old_ucontext {
+ unsigned long uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ struct sigcontext_struct uc_mcontext;
+ sigset_t uc_sigmask;
+};
+enum { SIGNAL_FRAMESIZE = 64 };
+#endif
+
+#endif
+
+#ifdef __powerpc64__
+
+/* If the current unwind info (FS) does not contain explicit info
+ saving R2, then we have to do a minor amount of code reading to
+ figure out if it was saved. The big problem here is that the
+ code that does the save/restore is generated by the linker, so
+ we have no good way to determine at compile time what to do. */
+
+#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \
+ do { \
+ if ((FS)->regs.reg[2].how == REG_UNSAVED) \
+ { \
+ unsigned int *insn \
+ = (unsigned int *) \
+ _Unwind_GetGR ((CTX), LINK_REGISTER_REGNUM); \
+ if (*insn == 0xE8410028) \
+ _Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 40); \
+ } \
+ } while (0)
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
+ do { \
+ unsigned char *pc_ = (CONTEXT)->ra; \
+ struct sigcontext *sc_; \
+ long new_cfa_; \
+ int i_; \
+ \
+ /* addi r1, r1, 128; li r0, 0x0077; sc (sigreturn) */ \
+ /* addi r1, r1, 128; li r0, 0x00AC; sc (rt_sigreturn) */ \
+ if (*(unsigned int *) (pc_+0) != 0x38210000 + SIGNAL_FRAMESIZE \
+ || *(unsigned int *) (pc_+8) != 0x44000002) \
+ break; \
+ if (*(unsigned int *) (pc_+4) == 0x38000077) \
+ { \
+ struct sigframe { \
+ char gap[SIGNAL_FRAMESIZE]; \
+ struct sigcontext sigctx; \
+ } *rt_ = (CONTEXT)->cfa; \
+ sc_ = &rt_->sigctx; \
+ } \
+ else if (*(unsigned int *) (pc_+4) == 0x380000AC) \
+ { \
+ struct rt_sigframe { \
+ int tramp[6]; \
+ struct siginfo *pinfo; \
+ struct ucontext *puc; \
+ } *rt_ = (struct rt_sigframe *) pc_; \
+ sc_ = &rt_->puc->uc_mcontext; \
+ } \
+ else \
+ break; \
+ \
+ new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->cfa_reg = STACK_POINTER_REGNUM; \
+ (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
+ \
+ for (i_ = 0; i_ < 32; i_++) \
+ if (i_ != STACK_POINTER_REGNUM) \
+ { \
+ (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_].loc.offset \
+ = (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
+ } \
+ \
+ (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
+ = (long)&(sc_->regs->link) - new_cfa_; \
+ \
+ (FS)->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[ARG_POINTER_REGNUM].loc.offset \
+ = (long)&(sc_->regs->nip) - new_cfa_; \
+ (FS)->retaddr_column = ARG_POINTER_REGNUM; \
+ goto SUCCESS; \
+ } while (0)
+
+#else
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS) \
+ do { \
+ unsigned char *pc_ = (CONTEXT)->ra; \
+ struct sigcontext *sc_; \
+ long new_cfa_; \
+ int i_; \
+ \
+ /* li r0, 0x7777; sc (sigreturn old) */ \
+ /* li r0, 0x0077; sc (sigreturn new) */ \
+ /* li r0, 0x6666; sc (rt_sigreturn old) */ \
+ /* li r0, 0x00AC; sc (rt_sigreturn new) */ \
+ if (*(unsigned int *) (pc_+4) != 0x44000002) \
+ break; \
+ if (*(unsigned int *) (pc_+0) == 0x38007777 \
+ || *(unsigned int *) (pc_+0) == 0x38000077) \
+ { \
+ struct sigframe { \
+ char gap[SIGNAL_FRAMESIZE]; \
+ struct sigcontext sigctx; \
+ } *rt_ = (CONTEXT)->cfa; \
+ sc_ = &rt_->sigctx; \
+ } \
+ else if (*(unsigned int *) (pc_+0) == 0x38006666 \
+ || *(unsigned int *) (pc_+0) == 0x380000AC) \
+ { \
+ struct rt_sigframe { \
+ char gap[SIGNAL_FRAMESIZE]; \
+ unsigned long _unused[2]; \
+ struct siginfo *pinfo; \
+ void *puc; \
+ struct siginfo info; \
+ struct kernel_old_ucontext uc; \
+ } *rt_ = (CONTEXT)->cfa; \
+ sc_ = &rt_->uc.uc_mcontext; \
+ } \
+ else \
+ break; \
+ \
+ new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM]; \
+ (FS)->cfa_how = CFA_REG_OFFSET; \
+ (FS)->cfa_reg = STACK_POINTER_REGNUM; \
+ (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa; \
+ \
+ for (i_ = 0; i_ < 32; i_++) \
+ if (i_ != STACK_POINTER_REGNUM) \
+ { \
+ (FS)->regs.reg[i_].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[i_].loc.offset \
+ = (long)&(sc_->regs->gpr[i_]) - new_cfa_; \
+ } \
+ \
+ (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset \
+ = (long)&(sc_->regs->link) - new_cfa_; \
+ \
+ (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[CR0_REGNO].loc.offset \
+ = (long)&(sc_->regs->nip) - new_cfa_; \
+ (FS)->retaddr_column = CR0_REGNO; \
+ goto SUCCESS; \
+ } while (0)
+
+#endif
+
+
+#define OS_MISSING_POWERPC64 !TARGET_64BIT
diff --git a/contrib/gcc/config/rs6000/linuxaltivec.h b/contrib/gcc/config/rs6000/linuxaltivec.h
index d2f184f196a4..73ac8646141e 100644
--- a/contrib/gcc/config/rs6000/linuxaltivec.h
+++ b/contrib/gcc/config/rs6000/linuxaltivec.h
@@ -1,31 +1,31 @@
/* Definitions of target machine for GNU compiler,
for AltiVec enhanced PowerPC machines running GNU/Linux.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC AltiVec GNU/Linux)");
/* Override rs6000.h and sysv4.h definition. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_ALTIVEC)
-#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS rs6000_altivec_abi = 1
diff --git a/contrib/gcc/config/rs6000/linuxspe.h b/contrib/gcc/config/rs6000/linuxspe.h
new file mode 100644
index 000000000000..59eb8316f04b
--- /dev/null
+++ b/contrib/gcc/config/rs6000/linuxspe.h
@@ -0,0 +1,70 @@
+/* Definitions of target machine for GNU compiler,
+ for PowerPC e500 machines running GNU/Linux.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez (aldy@quesejoda.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 2, 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (PowerPC E500 GNU/Linux)");
+
+/* Override rs6000.h and sysv4.h definition. */
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS)
+
+#undef TARGET_SPE_ABI
+#undef TARGET_SPE
+#undef TARGET_E500
+#undef TARGET_ISEL
+#undef TARGET_FPRS
+
+#define TARGET_SPE_ABI rs6000_spe_abi
+#define TARGET_SPE rs6000_spe
+#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
+#define TARGET_ISEL rs6000_isel
+#define TARGET_FPRS (!rs6000_float_gprs)
+
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#define SUBSUBTARGET_OVERRIDE_OPTIONS \
+ if (rs6000_select[1].string == NULL) \
+ rs6000_cpu = PROCESSOR_PPC8540; \
+ if (rs6000_abi_string == NULL || strstr (rs6000_abi_string, "spe") == NULL) \
+ rs6000_spe_abi = 1; \
+ if (rs6000_float_gprs_string == NULL) \
+ rs6000_float_gprs = 1; \
+ /* See note below. */ \
+ /*if (rs6000_long_double_size_string == NULL)*/ \
+ /* rs6000_long_double_type_size = 128;*/ \
+ if (rs6000_spe_string == NULL) \
+ rs6000_spe = 1; \
+ if (rs6000_isel_string == NULL) \
+ rs6000_isel = 1
+
+/* The e500 ABI says that either long doubles are 128 bits, or if
+ implemented in any other size, the compiler/linker should error out.
+ We have no emulation libraries for 128 bit long doubles, and I hate
+ the dozens of failures on the regression suite. So I'm breaking ABI
+ specifications, until I properly fix the emulation.
+
+ Enable these later.
+#undef CPP_LONGDOUBLE_DEFAULT_SPEC
+#define CPP_LONGDOUBLE_DEFAULT_SPEC "-D__LONG_DOUBLE_128__=1"
+*/
+
+#undef ASM_DEFAULT_SPEC
+#define ASM_DEFAULT_SPEC "-mppc -mspe -me500"
diff --git a/contrib/gcc/config/rs6000/lynx.h b/contrib/gcc/config/rs6000/lynx.h
index 7878ef94a175..b32b07890ae4 100644
--- a/contrib/gcc/config/rs6000/lynx.h
+++ b/contrib/gcc/config/rs6000/lynx.h
@@ -1,59 +1,32 @@
/* Definitions for Rs6000 running LynxOS.
- Copyright (C) 1995, 1996, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2000, 2002, 2003 Free Software Foundation, Inc.
Contributed by David Henkel-Wallace, Cygnus Support (gumby@cygnus.com)
-This file is part of GNU CC.
-
-GNU CC 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.
-
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* Definitions we want to override with those from rs6000.h: */
-#undef LIB_SPEC
-#undef PTRDIFF_TYPE
-#undef WCHAR_TYPE
-#undef WCHAR_TYPE_SIZE
-#undef ASM_FILE_START
-#undef EXTRA_SECTIONS
-#undef READONLY_DATA_SECTION
-#undef READONLY_DATA_SECTION_ASM_OP
-#undef EXTRA_SECTION_FUNCTIONS
-#undef TARGET_ASM_SELECT_RTX_SECTION
-#undef TARGET_ASM_SELECT_SECTION
-#undef USER_LABEL_PREFIX
-#undef ASM_OUTPUT_LABELREF
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#undef ASM_GENERATE_INTERNAL_LABEL
-#undef ASM_OUTPUT_COMMON
-#undef ASM_OUTPUT_LOCAL
-
-#undef SDB_DEBUGGING_INFO
-#undef DBX_DEBUGGING_INFO
-#undef PREFERRED_DEBUGGING_TYPE
-
-#undef FUNCTION_PROFILER
-
-#include <rs6000/rs6000.h>
+ 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 2, 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Print subsidiary information on the compiler version in use. */
#define TARGET_VERSION fprintf (stderr, " (LynxOS-RS/6000)");
/* LynxOS has signed chars, regardless of what most R/S 6000 systems do */
-#undef DEFAULT_SIGNED_CHAR
+#undef DEFAULT_SIGNED_CHAR
#define DEFAULT_SIGNED_CHAR 1
-#undef TARGET_OS_CPP_BUILTINS
+#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
@@ -70,30 +43,30 @@ Boston, MA 02111-1307, USA. */
} \
while (0)
-#undef LINK_SPEC
+#undef LINK_SPEC
#define LINK_SPEC "-T0x10001000 -H0x1000 -D0x20000000 -btextro -bhalt:4 -bnodelcsect -bnso -bro -bnoglink %{v} %{b*}"
-#undef LIB_SPEC
+#undef LIB_SPEC
#define LIB_SPEC "%{mthreads:-L/lib/thread/} \
%{msystem-v:-lc_v -lm.v} \
%{!msystem-v:%{mposix:-lc_p} -lc -lm}"
-#undef STARTFILE_SPEC
+#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{p:%{mthreads:thread/pinit.o%s}%{!mthreads:pinit.o%s}}%{!p:%{msystem-v:vinit.o%s -e_start}%{!msystem-v:%{mthreads:thread/init.o%s}%{!mthreads:init.o%s}}}"
#undef ENDFILE_SPEC
/* This can become more refined as we have more powerpc options. */
-#undef ASM_SPEC
+#undef ASM_SPEC
#define ASM_SPEC "-u %(asm_cpu)"
-#undef SUBTARGET_SWITCHES
+#undef SUBTARGET_SWITCHES
#define SUBTARGET_SWITCHES \
{"threads", MASK_THREADS}, \
{"posix", MASK_POSIX}, \
{"system-v", MASK_SYSTEM_V},
-#undef SUBTARGET_OVERRIDE_OPTIONS
+#undef SUBTARGET_OVERRIDE_OPTIONS
#define SUBTARGET_OVERRIDE_OPTIONS \
do { \
if (TARGET_SYSTEM_V && profile_flag) \
@@ -105,11 +78,10 @@ do { \
/* For collect2 */
#define OBJECT_FORMAT_NONE
#undef OBJECT_FORMAT_COFF
-#undef OBJECT_FORMAT_ROSE
#undef MD_EXEC_PREFIX
#undef REAL_LD_FILE_NAME
#undef REAL_STRIP_FILE_NAME
/* LynxOS doesn't have mcount. */
-#undef FUNCTION_PROFILER
+#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(file, profile_label_no)
diff --git a/contrib/gcc/config/rs6000/lynxbase.h b/contrib/gcc/config/rs6000/lynxbase.h
new file mode 100644
index 000000000000..02a255254a51
--- /dev/null
+++ b/contrib/gcc/config/rs6000/lynxbase.h
@@ -0,0 +1,45 @@
+/* Definitions for Rs6000 running LynxOS.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by David Henkel-Wallace, Cygnus Support (gumby@cygnus.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 2, 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+/* Definitions we want to override with those from rs6000.h: */
+#undef LIB_SPEC
+#undef PTRDIFF_TYPE
+#undef SIZE_TYPE
+#undef WCHAR_TYPE
+#undef WCHAR_TYPE_SIZE
+#undef EXTRA_SECTIONS
+#undef READONLY_DATA_SECTION
+#undef READONLY_DATA_SECTION_ASM_OP
+#undef EXTRA_SECTION_FUNCTIONS
+#undef TARGET_ASM_SELECT_RTX_SECTION
+#undef TARGET_ASM_SELECT_SECTION
+#undef USER_LABEL_PREFIX
+#undef ASM_OUTPUT_LABELREF
+#undef ASM_GENERATE_INTERNAL_LABEL
+#undef ASM_OUTPUT_COMMON
+#undef ASM_OUTPUT_LOCAL
+
+#undef SDB_DEBUGGING_INFO
+#undef DBX_DEBUGGING_INFO
+#undef PREFERRED_DEBUGGING_TYPE
+
+#undef FUNCTION_PROFILER
+#undef SUBTARGET_SWITCHES
diff --git a/contrib/gcc/config/rs6000/mpc.md b/contrib/gcc/config/rs6000/mpc.md
new file mode 100644
index 000000000000..b95bba5c33a0
--- /dev/null
+++ b/contrib/gcc/config/rs6000/mpc.md
@@ -0,0 +1,99 @@
+;; Scheduling description for Motorola PowerPC processor cores.
+;; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "mpc,mpcfp")
+(define_cpu_unit "iu_mpc,mciu_mpc" "mpc")
+(define_cpu_unit "fpu_mpc" "mpcfp")
+(define_cpu_unit "lsu_mpc,bpu_mpc" "mpc")
+
+;; MPCCORE 32-bit SCIU, MCIU, LSU, FPU, BPU
+;; 505/801/821/823
+
+(define_insn_reservation "mpccore-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "mpccore"))
+ "lsu_mpc")
+
+(define_insn_reservation "mpccore-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u,fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "mpccore"))
+ "lsu_mpc")
+
+(define_insn_reservation "mpccore-fpload" 2
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "mpccore"))
+ "lsu_mpc")
+
+(define_insn_reservation "mpccore-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "mpccore"))
+ "iu_mpc")
+
+(define_insn_reservation "mpccore-imul" 2
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "mpccore"))
+ "mciu_mpc")
+
+; Divide latency varies greatly from 2-11, use 6 as average
+(define_insn_reservation "mpccore-idiv" 6
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "mpccore"))
+ "mciu_mpc*6")
+
+(define_insn_reservation "mpccore-compare" 3
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "mpccore"))
+ "iu_mpc,nothing,bpu_mpc")
+
+(define_insn_reservation "mpccore-fpcompare" 2
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "mpccore"))
+ "fpu_mpc,bpu_mpc")
+
+(define_insn_reservation "mpccore-fp" 4
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "mpccore"))
+ "fpu_mpc*2")
+
+(define_insn_reservation "mpccore-dmul" 5
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "mpccore"))
+ "fpu_mpc*5")
+
+(define_insn_reservation "mpccore-sdiv" 10
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "mpccore"))
+ "fpu_mpc*10")
+
+(define_insn_reservation "mpccore-ddiv" 17
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "mpccore"))
+ "fpu_mpc*17")
+
+(define_insn_reservation "mpccore-mtjmpr" 4
+ (and (eq_attr "type" "mtjmpr,mfjmpr")
+ (eq_attr "cpu" "mpccore"))
+ "bpu_mpc")
+
+(define_insn_reservation "mpccore-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch,cr_logical,delayed_cr,mfcr,mtcr")
+ (eq_attr "cpu" "mpccore"))
+ "bpu_mpc")
+
diff --git a/contrib/gcc/config/rs6000/netbsd.h b/contrib/gcc/config/rs6000/netbsd.h
index b473a8a868fe..e0c519654d3b 100644
--- a/contrib/gcc/config/rs6000/netbsd.h
+++ b/contrib/gcc/config/rs6000/netbsd.h
@@ -1,26 +1,26 @@
/* Definitions of target machine for GNU compiler,
for PowerPC NetBSD systems.
- Copyright 2002 Free Software Foundation, Inc.
+ Copyright 2002, 2003 Free Software Foundation, Inc.
Contributed by Wasabi Systems, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef TARGET_OS_CPP_BUILTINS /* FIXME: sysv4.h should not define this! */
+#undef TARGET_OS_CPP_BUILTINS /* FIXME: sysv4.h should not define this! */
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
@@ -34,7 +34,7 @@ Boston, MA 02111-1307, USA. */
/* Override the default from rs6000.h to avoid conflicts with macros
defined in NetBSD header files. */
-#undef RS6000_CPU_CPP_ENDIAN_BUILTINS
+#undef RS6000_CPU_CPP_ENDIAN_BUILTINS
#define RS6000_CPU_CPP_ENDIAN_BUILTINS() \
do \
{ \
@@ -53,41 +53,41 @@ Boston, MA 02111-1307, USA. */
/* Make GCC agree with <machine/ansi.h>. */
-#undef SIZE_TYPE
+#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
-#undef PTRDIFF_TYPE
+#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "int"
/* Undo the spec mess from sysv4.h, and just define the specs
the way NetBSD systems actually expect. */
-#undef CPP_SPEC
+#undef CPP_SPEC
#define CPP_SPEC NETBSD_CPP_SPEC
-#undef LINK_SPEC
+#undef LINK_SPEC
#define LINK_SPEC \
"%{!msdata=none:%{G*}} %{msdata=none:-G0} \
%(netbsd_link_spec)"
#define NETBSD_ENTRY_POINT "_start"
-#undef STARTFILE_SPEC
+#undef STARTFILE_SPEC
#define STARTFILE_SPEC NETBSD_STARTFILE_SPEC
-#undef ENDFILE_SPEC
+#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"crtsavres%O%s %(netbsd_endfile_spec)"
-#undef LIB_SPEC
+#undef LIB_SPEC
#define LIB_SPEC NETBSD_LIB_SPEC
-#undef SUBTARGET_EXTRA_SPECS
+#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
{ "netbsd_link_spec", NETBSD_LINK_SPEC_ELF }, \
{ "netbsd_entry_point", NETBSD_ENTRY_POINT }, \
{ "netbsd_endfile_spec", NETBSD_ENDFILE_SPEC },
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (NetBSD/powerpc ELF)");
diff --git a/contrib/gcc/config/rs6000/power4.md b/contrib/gcc/config/rs6000/power4.md
new file mode 100644
index 000000000000..fabc1de34aab
--- /dev/null
+++ b/contrib/gcc/config/rs6000/power4.md
@@ -0,0 +1,392 @@
+;; Scheduling description for IBM Power4 and PowerPC 970 processors.
+;; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+;; Sources: IBM Red Book and White Paper on POWER4
+
+;; The POWER4 has 2 iu, 2 fpu, 2 lsu per engine (2 engines per chip).
+;; Instructions that update more than one register get broken into two
+;; (split) or more internal ops. The chip can issue up to 5
+;; internal ops per cycle.
+
+(define_automaton "power4iu,power4fpu,power4vec,power4misc")
+
+(define_cpu_unit "iu1_power4,iu2_power4" "power4iu")
+(define_cpu_unit "lsu1_power4,lsu2_power4" "power4misc")
+(define_cpu_unit "fpu1_power4,fpu2_power4" "power4fpu")
+(define_cpu_unit "bpu_power4,cru_power4" "power4misc")
+(define_cpu_unit "vec_power4,vecperm_power4" "power4vec")
+(define_cpu_unit "du1_power4,du2_power4,du3_power4,du4_power4,du5_power4"
+ "power4misc")
+
+(define_reservation "lsq_power4"
+ "(du1_power4,lsu1_power4)\
+ |(du2_power4,lsu2_power4)\
+ |(du3_power4,nothing,lsu2_power4)\
+ |(du4_power4,nothing,lsu1_power4)")
+
+(define_reservation "lsuq_power4"
+ "(du1_power4+du2_power4,lsu1_power4+iu2_power4)\
+ |(du2_power4+du3_power4,lsu2_power4+iu2_power4)\
+ |(du3_power4+du4_power4,lsu2_power4+iu1_power4)")
+; |(du2_power4+du3_power4,nothing,lsu2_power4,iu2_power4)
+
+(define_reservation "iq_power4"
+ "(du1_power4,iu1_power4)\
+ |(du2_power4,iu2_power4)\
+ |(du3_power4,nothing,iu2_power4)\
+ |(du4_power4,nothing,iu1_power4)")
+
+(define_reservation "fpq_power4"
+ "(du1_power4,fpu1_power4)\
+ |(du2_power4,fpu2_power4)\
+ |(du3_power4,nothing,fpu2_power4)\
+ |(du4_power4,nothing,fpu1_power4)")
+
+(define_reservation "vq_power4"
+ "(du1_power4,vec_power4)\
+ |(du2_power4,vec_power4)\
+ |(du3_power4,nothing,vec_power4)\
+ |(du4_power4,nothing,vec_power4)")
+
+(define_reservation "vpq_power4"
+ "(du1_power4,vecperm_power4)\
+ |(du2_power4,vecperm_power4)\
+ |(du3_power4,nothing,vecperm_power4)\
+ |(du4_power4,nothing,vecperm_power4)")
+
+
+; Dispatch slots are allocated in order conforming to program order.
+(absence_set "du1_power4" "du2_power4,du3_power4,du4_power4,du5_power4")
+(absence_set "du2_power4" "du3_power4,du4_power4,du5_power4")
+(absence_set "du3_power4" "du4_power4,du5_power4")
+(absence_set "du4_power4" "du5_power4")
+
+
+; Load/store
+(define_insn_reservation "power4-load" 4 ; 3
+ (and (eq_attr "type" "load")
+ (eq_attr "cpu" "power4"))
+ "lsq_power4")
+
+(define_insn_reservation "power4-load-ext" 5
+ (and (eq_attr "type" "load_ext")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,lsu1_power4,nothing,nothing,iu2_power4)\
+ |(du2_power4+du3_power4,lsu2_power4,nothing,nothing,iu2_power4)\
+ |(du3_power4+du4_power4,lsu2_power4,nothing,nothing,iu1_power4)")
+
+(define_insn_reservation "power4-load-ext-update" 5
+ (and (eq_attr "type" "load_ext_u")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4+du3_power4+du4_power4,\
+ lsu1_power4+iu2_power4,nothing,nothing,iu2_power4")
+
+(define_insn_reservation "power4-load-ext-update-indexed" 5
+ (and (eq_attr "type" "load_ext_ux")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4+du3_power4+du4_power4,\
+ iu1_power4,lsu2_power4+iu1_power4,nothing,nothing,iu2_power4")
+
+(define_insn_reservation "power4-load-update-indexed" 3
+ (and (eq_attr "type" "load_ux")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4+du3_power4+du4_power4,\
+ iu1_power4,lsu2_power4+iu2_power4")
+
+(define_insn_reservation "power4-load-update" 4 ; 3
+ (and (eq_attr "type" "load_u")
+ (eq_attr "cpu" "power4"))
+ "lsuq_power4")
+
+(define_insn_reservation "power4-fpload" 6 ; 5
+ (and (eq_attr "type" "fpload")
+ (eq_attr "cpu" "power4"))
+ "lsq_power4")
+
+(define_insn_reservation "power4-fpload-update" 6 ; 5
+ (and (eq_attr "type" "fpload_u,fpload_ux")
+ (eq_attr "cpu" "power4"))
+ "lsuq_power4")
+
+(define_insn_reservation "power4-vecload" 6 ; 5
+ (and (eq_attr "type" "vecload")
+ (eq_attr "cpu" "power4"))
+ "lsq_power4")
+
+(define_insn_reservation "power4-store" 1
+ (and (eq_attr "type" "store")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,lsu1_power4,iu1_power4)\
+ |(du2_power4,lsu2_power4,iu2_power4)\
+ |(du3_power4,lsu2_power4,nothing,iu2_power4)\
+ |(du4_power4,lsu1_power4,nothing,iu1_power4)")
+
+(define_insn_reservation "power4-store-update" 1
+ (and (eq_attr "type" "store_u")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,lsu1_power4+iu2_power4,iu1_power4)\
+ |(du2_power4+du3_power4,lsu2_power4+iu2_power4,iu2_power4)\
+ |(du3_power4+du4_power4,lsu2_power4+iu1_power4,iu2_power4)\
+ |(du3_power4+du4_power4,lsu2_power4,iu1_power4,iu2_power4)")
+
+(define_insn_reservation "power4-store-update-indexed" 1
+ (and (eq_attr "type" "store_ux")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4+du3_power4+du4_power4,\
+ iu1_power4,lsu2_power4+iu2_power4,iu2_power4")
+
+(define_insn_reservation "power4-fpstore" 1
+ (and (eq_attr "type" "fpstore")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,lsu1_power4,fpu1_power4)\
+ |(du2_power4,lsu2_power4,fpu2_power4)\
+ |(du3_power4,lsu2_power4,nothing,fpu2_power4)\
+ |(du4_power4,lsu1_power4,nothing,fpu1_power4)")
+
+(define_insn_reservation "power4-fpstore-update" 1
+ (and (eq_attr "type" "fpstore_u,fpstore_ux")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,lsu1_power4+iu2_power4,fpu1_power4)\
+ |(du2_power4+du3_power4,lsu2_power4+iu2_power4,fpu2_power4)\
+ |(du3_power4+du4_power4,lsu2_power4+iu1_power4,fpu2_power4)")
+; |(du3_power4+du4_power4,nothing,lsu2_power4+iu1_power4,fpu2_power4)")
+
+(define_insn_reservation "power4-vecstore" 1
+ (and (eq_attr "type" "vecstore")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,lsu1_power4,vec_power4)\
+ |(du2_power4,lsu2_power4,vec_power4)\
+ |(du3_power4,lsu2_power4,nothing,vec_power4)\
+ |(du4_power4,lsu1_power4,nothing,vec_power4)")
+
+
+; Integer latency is 2 cycles
+(define_insn_reservation "power4-integer" 2
+ (and (eq_attr "type" "integer")
+ (eq_attr "cpu" "power4"))
+ "iq_power4")
+
+(define_insn_reservation "power4-insert" 4
+ (and (eq_attr "type" "insert_word")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,iu1_power4,nothing,iu2_power4)\
+ |(du2_power4+du3_power4,iu2_power4,nothing,iu2_power4)\
+ |(du3_power4+du4_power4,iu2_power4,nothing,iu1_power4)")
+
+(define_insn_reservation "power4-cmp" 3
+ (and (eq_attr "type" "cmp,fast_compare")
+ (eq_attr "cpu" "power4"))
+ "iq_power4")
+
+(define_insn_reservation "power4-compare" 2
+ (and (eq_attr "type" "compare,delayed_compare")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,iu1_power4,iu2_power4)\
+ |(du2_power4+du3_power4,iu2_power4,iu2_power4)\
+ |(du3_power4+du4_power4,nothing,iu2_power4,iu1_power4)")
+
+(define_bypass 4 "power4-compare" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf")
+
+(define_insn_reservation "power4-lmul-cmp" 7
+ (and (eq_attr "type" "lmul_compare")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,iu1_power4*6,iu2_power4)\
+ |(du2_power4+du3_power4,iu2_power4*6,iu2_power4)\
+ |(du3_power4+du4_power4,iu2_power4*6,iu1_power4)")
+; |(du3_power4+du4_power4,nothing,iu2_power4*6,iu1_power4)")
+
+(define_bypass 10 "power4-lmul-cmp" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf")
+
+(define_insn_reservation "power4-imul-cmp" 5
+ (and (eq_attr "type" "imul_compare")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4+du2_power4,iu1_power4*4,iu2_power4)\
+ |(du2_power4+du3_power4,iu2_power4*4,iu2_power4)\
+ |(du3_power4+du4_power4,iu2_power4*4,iu1_power4)")
+; |(du3_power4+du4_power4,nothing,iu2_power4*4,iu1_power4)")
+
+(define_bypass 8 "power4-imul-cmp" "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf")
+
+(define_insn_reservation "power4-lmul" 7
+ (and (eq_attr "type" "lmul")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,iu1_power4*6)\
+ |(du2_power4,iu2_power4*6)\
+ |(du3_power4,iu2_power4*6)\
+ |(du4_power4,iu2_power4*6)")
+; |(du3_power4,nothing,iu2_power4*6)\
+; |(du4_power4,nothing,iu2_power4*6)")
+
+(define_insn_reservation "power4-imul" 5
+ (and (eq_attr "type" "imul")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,iu1_power4*4)\
+ |(du2_power4,iu2_power4*4)\
+ |(du3_power4,iu2_power4*4)\
+ |(du4_power4,iu1_power4*4)")
+; |(du3_power4,nothing,iu2_power4*4)\
+; |(du4_power4,nothing,iu1_power4*4)")
+
+(define_insn_reservation "power4-imul3" 4
+ (and (eq_attr "type" "imul2,imul3")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,iu1_power4*3)\
+ |(du2_power4,iu2_power4*3)\
+ |(du3_power4,iu2_power4*3)\
+ |(du4_power4,iu1_power4*3)")
+; |(du3_power4,nothing,iu2_power4*3)\
+; |(du4_power4,nothing,iu1_power4*3)")
+
+
+; SPR move only executes in first IU.
+; Integer division only executes in second IU.
+(define_insn_reservation "power4-idiv" 36
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4,iu2_power4*35")
+
+(define_insn_reservation "power4-ldiv" 68
+ (and (eq_attr "type" "ldiv")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4,iu2_power4*67")
+
+
+(define_insn_reservation "power4-mtjmpr" 3
+ (and (eq_attr "type" "mtjmpr,mfjmpr")
+ (eq_attr "cpu" "power4"))
+ "du1_power4,bpu_power4")
+
+
+; Branches take dispatch Slot 4. The presence_sets prevent other insn from
+; grabbing previous dispatch slots once this is assigned.
+(define_insn_reservation "power4-branch" 2
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "power4"))
+ "(du5_power4\
+ |du4_power4+du5_power4\
+ |du3_power4+du4_power4+du5_power4\
+ |du2_power4+du3_power4+du4_power4+du5_power4\
+ |du1_power4+du2_power4+du3_power4+du4_power4+du5_power4),bpu_power4")
+
+
+; Condition Register logical ops are split if non-destructive (RT != RB)
+(define_insn_reservation "power4-crlogical" 2
+ (and (eq_attr "type" "cr_logical")
+ (eq_attr "cpu" "power4"))
+ "du1_power4,cru_power4")
+
+(define_insn_reservation "power4-delayedcr" 4
+ (and (eq_attr "type" "delayed_cr")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4,cru_power4,cru_power4")
+
+; 4 mfcrf (each 3 cyc, 1/cyc) + 3 fxu
+(define_insn_reservation "power4-mfcr" 6
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4+du3_power4+du4_power4,\
+ du1_power4+du2_power4+du3_power4+du4_power4+cru_power4,\
+ cru_power4,cru_power4,cru_power4")
+
+; mfcrf (1 field)
+(define_insn_reservation "power4-mfcrf" 3
+ (and (eq_attr "type" "mfcrf")
+ (eq_attr "cpu" "power4"))
+ "du1_power4,cru_power4")
+
+; mtcrf (1 field)
+(define_insn_reservation "power4-mtcr" 4
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "power4"))
+ "du1_power4,iu1_power4")
+
+; Basic FP latency is 6 cycles
+(define_insn_reservation "power4-fp" 6
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "power4"))
+ "fpq_power4")
+
+(define_insn_reservation "power4-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "power4"))
+ "fpq_power4")
+
+(define_insn_reservation "power4-sdiv" 33
+ (and (eq_attr "type" "sdiv,ddiv")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,fpu1_power4*28)\
+ |(du2_power4,fpu2_power4*28)\
+ |(du3_power4,fpu2_power4*28)\
+ |(du4_power4,fpu1_power4*28)")
+; |(du3_power4,nothing,fpu2_power4*28)\
+; |(du4_power4,nothing,fpu1_power4*28)")
+
+(define_insn_reservation "power4-sqrt" 40
+ (and (eq_attr "type" "ssqrt,dsqrt")
+ (eq_attr "cpu" "power4"))
+ "(du1_power4,fpu1_power4*35)\
+ |(du2_power4,fpu2_power4*35)\
+ |(du3_power4,fpu2_power4*35)\
+ |(du4_power4,fpu2_power4*35)")
+; |(du3_power4,nothing,fpu2_power4*35)\
+; |(du4_power4,nothing,fpu2_power4*35)")
+
+
+; VMX
+(define_insn_reservation "power4-vecsimple" 2
+ (and (eq_attr "type" "vecsimple")
+ (eq_attr "cpu" "power4"))
+ "vq_power4")
+
+(define_insn_reservation "power4-veccomplex" 5
+ (and (eq_attr "type" "veccomplex")
+ (eq_attr "cpu" "power4"))
+ "vq_power4")
+
+; vecfp compare
+(define_insn_reservation "power4-veccmp" 8
+ (and (eq_attr "type" "veccmp")
+ (eq_attr "cpu" "power4"))
+ "vq_power4")
+
+(define_insn_reservation "power4-vecfloat" 8
+ (and (eq_attr "type" "vecfloat")
+ (eq_attr "cpu" "power4"))
+ "vq_power4")
+
+(define_insn_reservation "power4-vecperm" 2
+ (and (eq_attr "type" "vecperm")
+ (eq_attr "cpu" "power4"))
+ "vpq_power4")
+
+(define_bypass 4 "power4-vecload" "power4-vecperm")
+
+(define_bypass 3 "power4-vecsimple" "power4-vecperm")
+(define_bypass 6 "power4-veccomplex" "power4-vecperm")
+(define_bypass 3 "power4-vecperm"
+ "power4-vecsimple,power4-veccomplex,power4-vecfloat")
+(define_bypass 9 "power4-vecfloat" "power4-vecperm")
+
+(define_bypass 5 "power4-vecsimple,power4-veccomplex"
+ "power4-branch,power4-crlogical,power4-delayedcr,power4-mfcr,power4-mfcrf")
+
+(define_bypass 4 "power4-vecsimple,power4-vecperm" "power4-vecstore")
+(define_bypass 7 "power4-veccomplex" "power4-vecstore")
+(define_bypass 10 "power4-vecfloat" "power4-vecstore")
diff --git a/contrib/gcc/config/rs6000/power5.md b/contrib/gcc/config/rs6000/power5.md
new file mode 100644
index 000000000000..59baa79c30c4
--- /dev/null
+++ b/contrib/gcc/config/rs6000/power5.md
@@ -0,0 +1,299 @@
+;; Scheduling description for IBM POWER5 processor.
+;; Copyright (C) 2003, 2004 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 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+;; Sources: IBM Red Book and White Paper on POWER5
+
+;; The POWER5 has 2 iu, 2 fpu, 2 lsu per engine (2 engines per chip).
+;; Instructions that update more than one register get broken into two
+;; (split) or more internal ops. The chip can issue up to 5
+;; internal ops per cycle.
+
+(define_automaton "power5iu,power5fpu,power5misc")
+
+(define_cpu_unit "iu1_power5,iu2_power5" "power5iu")
+(define_cpu_unit "lsu1_power5,lsu2_power5" "power5misc")
+(define_cpu_unit "fpu1_power5,fpu2_power5" "power5fpu")
+(define_cpu_unit "bpu_power5,cru_power5" "power5misc")
+(define_cpu_unit "du1_power5,du2_power5,du3_power5,du4_power5,du5_power5"
+ "power5misc")
+
+(define_reservation "lsq_power5"
+ "(du1_power5,lsu1_power5)\
+ |(du2_power5,lsu2_power5)\
+ |(du3_power5,nothing,lsu2_power5)\
+ |(du4_power5,nothing,lsu1_power5)")
+
+(define_reservation "iq_power5"
+ "(du1_power5,iu1_power5)\
+ |(du2_power5,iu2_power5)\
+ |(du3_power5,nothing,iu2_power5)\
+ |(du4_power5,nothing,iu1_power5)")
+
+(define_reservation "fpq_power5"
+ "(du1_power5,fpu1_power5)\
+ |(du2_power5,fpu2_power5)\
+ |(du3_power5,nothing,fpu2_power5)\
+ |(du4_power5,nothing,fpu1_power5)")
+
+; Dispatch slots are allocated in order conforming to program order.
+(absence_set "du1_power5" "du2_power5,du3_power5,du4_power5,du5_power5")
+(absence_set "du2_power5" "du3_power5,du4_power5,du5_power5")
+(absence_set "du3_power5" "du4_power5,du5_power5")
+(absence_set "du4_power5" "du5_power5")
+
+
+; Load/store
+(define_insn_reservation "power5-load" 4 ; 3
+ (and (eq_attr "type" "load")
+ (eq_attr "cpu" "power5"))
+ "lsq_power5")
+
+(define_insn_reservation "power5-load-ext" 5
+ (and (eq_attr "type" "load_ext")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5,nothing,nothing,iu2_power5")
+
+(define_insn_reservation "power5-load-ext-update" 5
+ (and (eq_attr "type" "load_ext_u")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ lsu1_power5+iu2_power5,nothing,nothing,iu2_power5")
+
+(define_insn_reservation "power5-load-ext-update-indexed" 5
+ (and (eq_attr "type" "load_ext_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ iu1_power5,lsu2_power5+iu1_power5,nothing,nothing,iu2_power5")
+
+(define_insn_reservation "power5-load-update-indexed" 3
+ (and (eq_attr "type" "load_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ iu1_power5,lsu2_power5+iu2_power5")
+
+(define_insn_reservation "power5-load-update" 4 ; 3
+ (and (eq_attr "type" "load_u")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5+iu2_power5")
+
+(define_insn_reservation "power5-fpload" 6 ; 5
+ (and (eq_attr "type" "fpload")
+ (eq_attr "cpu" "power5"))
+ "lsq_power5")
+
+(define_insn_reservation "power5-fpload-update" 6 ; 5
+ (and (eq_attr "type" "fpload_u,fpload_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5+iu2_power5")
+
+(define_insn_reservation "power5-store" 1
+ (and (eq_attr "type" "store")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,lsu1_power5,iu1_power5)\
+ |(du2_power5,lsu2_power5,iu2_power5)\
+ |(du3_power5,lsu2_power5,nothing,iu2_power5)\
+ |(du4_power5,lsu1_power5,nothing,iu1_power5)")
+
+(define_insn_reservation "power5-store-update" 1
+ (and (eq_attr "type" "store_u")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5+iu2_power5,iu1_power5")
+
+(define_insn_reservation "power5-store-update-indexed" 1
+ (and (eq_attr "type" "store_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ iu1_power5,lsu2_power5+iu2_power5,iu2_power5")
+
+(define_insn_reservation "power5-fpstore" 1
+ (and (eq_attr "type" "fpstore")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,lsu1_power5,fpu1_power5)\
+ |(du2_power5,lsu2_power5,fpu2_power5)\
+ |(du3_power5,lsu2_power5,nothing,fpu2_power5)\
+ |(du4_power5,lsu1_power5,nothing,fpu1_power5)")
+
+(define_insn_reservation "power5-fpstore-update" 1
+ (and (eq_attr "type" "fpstore_u,fpstore_ux")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,lsu1_power5+iu2_power5,fpu1_power5")
+
+
+; Integer latency is 2 cycles
+(define_insn_reservation "power5-integer" 2
+ (and (eq_attr "type" "integer")
+ (eq_attr "cpu" "power5"))
+ "iq_power5")
+
+(define_insn_reservation "power5-insert" 4
+ (and (eq_attr "type" "insert_word")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu1_power5,nothing,iu2_power5")
+
+(define_insn_reservation "power5-cmp" 3
+ (and (eq_attr "type" "cmp,fast_compare")
+ (eq_attr "cpu" "power5"))
+ "iq_power5")
+
+(define_insn_reservation "power5-compare" 2
+ (and (eq_attr "type" "compare,delayed_compare")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu1_power5,iu2_power5")
+
+(define_bypass 4 "power5-compare" "power5-branch,power5-crlogical,power5-delayedcr,power5-mfcr,power5-mfcrf")
+
+(define_insn_reservation "power5-lmul-cmp" 7
+ (and (eq_attr "type" "lmul_compare")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu1_power5*6,iu2_power5")
+
+(define_bypass 10 "power5-lmul-cmp" "power5-branch,power5-crlogical,power5-delayedcr,power5-mfcr,power5-mfcrf")
+
+(define_insn_reservation "power5-imul-cmp" 5
+ (and (eq_attr "type" "imul_compare")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu1_power5*4,iu2_power5")
+
+(define_bypass 8 "power5-imul-cmp" "power5-branch,power5-crlogical,power5-delayedcr,power5-mfcr,power5-mfcrf")
+
+(define_insn_reservation "power5-lmul" 7
+ (and (eq_attr "type" "lmul")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,iu1_power5*6)\
+ |(du2_power5,iu2_power5*6)\
+ |(du3_power5,iu2_power5*6)\
+ |(du4_power5,iu2_power5*6)")
+; |(du3_power5,nothing,iu2_power5*6)\
+; |(du4_power5,nothing,iu2_power5*6)")
+
+(define_insn_reservation "power5-imul" 5
+ (and (eq_attr "type" "imul")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,iu1_power5*4)\
+ |(du2_power5,iu2_power5*4)\
+ |(du3_power5,iu2_power5*4)\
+ |(du4_power5,iu1_power5*4)")
+; |(du3_power5,nothing,iu2_power5*4)\
+; |(du4_power5,nothing,iu1_power5*4)")
+
+(define_insn_reservation "power5-imul3" 4
+ (and (eq_attr "type" "imul2,imul3")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,iu1_power5*3)\
+ |(du2_power5,iu2_power5*3)\
+ |(du3_power5,iu2_power5*3)\
+ |(du4_power5,iu1_power5*3)")
+; |(du3_power5,nothing,iu2_power5*3)\
+; |(du4_power5,nothing,iu1_power5*3)")
+
+
+; SPR move only executes in first IU.
+; Integer division only executes in second IU.
+(define_insn_reservation "power5-idiv" 36
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu2_power5*35")
+
+(define_insn_reservation "power5-ldiv" 68
+ (and (eq_attr "type" "ldiv")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,iu2_power5*67")
+
+
+(define_insn_reservation "power5-mtjmpr" 3
+ (and (eq_attr "type" "mtjmpr,mfjmpr")
+ (eq_attr "cpu" "power5"))
+ "du1_power5,bpu_power5")
+
+
+; Branches take dispatch Slot 4. The presence_sets prevent other insn from
+; grabbing previous dispatch slots once this is assigned.
+(define_insn_reservation "power5-branch" 2
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "power5"))
+ "(du5_power5\
+ |du4_power5+du5_power5\
+ |du3_power5+du4_power5+du5_power5\
+ |du2_power5+du3_power5+du4_power5+du5_power5\
+ |du1_power5+du2_power5+du3_power5+du4_power5+du5_power5),bpu_power5")
+
+
+; Condition Register logical ops are split if non-destructive (RT != RB)
+(define_insn_reservation "power5-crlogical" 2
+ (and (eq_attr "type" "cr_logical")
+ (eq_attr "cpu" "power5"))
+ "du1_power5,cru_power5")
+
+(define_insn_reservation "power5-delayedcr" 4
+ (and (eq_attr "type" "delayed_cr")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5,cru_power5,cru_power5")
+
+; 4 mfcrf (each 3 cyc, 1/cyc) + 3 fxu
+(define_insn_reservation "power5-mfcr" 6
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ du1_power5+du2_power5+du3_power5+du4_power5+cru_power5,\
+ cru_power5,cru_power5,cru_power5")
+
+; mfcrf (1 field)
+(define_insn_reservation "power5-mfcrf" 3
+ (and (eq_attr "type" "mfcrf")
+ (eq_attr "cpu" "power5"))
+ "du1_power5,cru_power5")
+
+; mtcrf (1 field)
+(define_insn_reservation "power5-mtcr" 4
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "power5"))
+ "du1_power5,iu1_power5")
+
+; Basic FP latency is 6 cycles
+(define_insn_reservation "power5-fp" 6
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "power5"))
+ "fpq_power5")
+
+(define_insn_reservation "power5-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "power5"))
+ "fpq_power5")
+
+(define_insn_reservation "power5-sdiv" 33
+ (and (eq_attr "type" "sdiv,ddiv")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,fpu1_power5*28)\
+ |(du2_power5,fpu2_power5*28)\
+ |(du3_power5,fpu2_power5*28)\
+ |(du4_power5,fpu1_power5*28)")
+; |(du3_power5,nothing,fpu2_power5*28)\
+; |(du4_power5,nothing,fpu1_power5*28)")
+
+(define_insn_reservation "power5-sqrt" 40
+ (and (eq_attr "type" "ssqrt,dsqrt")
+ (eq_attr "cpu" "power5"))
+ "(du1_power5,fpu1_power5*35)\
+ |(du2_power5,fpu2_power5*35)\
+ |(du3_power5,fpu2_power5*35)\
+ |(du4_power5,fpu2_power5*35)")
+; |(du3_power5,nothing,fpu2_power5*35)\
+; |(du4_power5,nothing,fpu2_power5*35)")
+
diff --git a/contrib/gcc/config/rs6000/ppc-asm.h b/contrib/gcc/config/rs6000/ppc-asm.h
index 2822e18a31ad..74e14836286f 100644
--- a/contrib/gcc/config/rs6000/ppc-asm.h
+++ b/contrib/gcc/config/rs6000/ppc-asm.h
@@ -95,21 +95,15 @@
* the real function with one or two leading periods respectively.
*/
-#ifdef _RELOCATABLE
-#define DESC_SECTION ".got2"
-#else
-#define DESC_SECTION ".got1"
-#endif
-
-#if defined(_CALL_AIXDESC)
+#if defined (__powerpc64__)
#define FUNC_NAME(name) GLUE(.,name)
#define JUMP_TARGET(name) FUNC_NAME(name)
#define FUNC_START(name) \
- .section DESC_SECTION,"aw"; \
+ .section ".opd","aw"; \
name: \
- .long GLUE(.,name); \
- .long _GLOBAL_OFFSET_TABLE_; \
- .long 0; \
+ .quad GLUE(.,name); \
+ .quad .TOC.@tocbase; \
+ .quad 0; \
.previous; \
.type GLUE(.,name),@function; \
.globl name; \
@@ -120,15 +114,22 @@ GLUE(.,name):
GLUE(.L,name): \
.size GLUE(.,name),GLUE(.L,name)-GLUE(.,name)
-#elif defined (__powerpc64__)
+#elif defined(_CALL_AIXDESC)
+
+#ifdef _RELOCATABLE
+#define DESC_SECTION ".got2"
+#else
+#define DESC_SECTION ".got1"
+#endif
+
#define FUNC_NAME(name) GLUE(.,name)
#define JUMP_TARGET(name) FUNC_NAME(name)
#define FUNC_START(name) \
- .section ".opd","aw"; \
+ .section DESC_SECTION,"aw"; \
name: \
- .quad GLUE(.,name); \
- .quad .TOC.@tocbase; \
- .quad 0; \
+ .long GLUE(.,name); \
+ .long _GLOBAL_OFFSET_TABLE_; \
+ .long 0; \
.previous; \
.type GLUE(.,name),@function; \
.globl name; \
@@ -140,6 +141,7 @@ GLUE(.L,name): \
.size GLUE(.,name),GLUE(.L,name)-GLUE(.,name)
#else
+
#define FUNC_NAME(name) GLUE(__USER_LABEL_PREFIX__,name)
#if defined __PIC__ || defined __pic__
#define JUMP_TARGET(name) FUNC_NAME(name@plt)
@@ -156,3 +158,7 @@ GLUE(.L,name): \
.size FUNC_NAME(name),GLUE(.L,name)-FUNC_NAME(name)
#endif
+#if defined __linux__ && !defined __powerpc64__
+ .section .note.GNU-stack
+ .previous
+#endif
diff --git a/contrib/gcc/config/rs6000/ppc64-fp.c b/contrib/gcc/config/rs6000/ppc64-fp.c
index 3f6d7cd1bb0c..c736d9ad7c86 100644
--- a/contrib/gcc/config/rs6000/ppc64-fp.c
+++ b/contrib/gcc/config/rs6000/ppc64-fp.c
@@ -31,19 +31,30 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#if defined(__powerpc64__)
-#include "fp-bit.h"
+#include "config/fp-bit.h"
+extern DItype __fixtfdi (TFtype);
extern DItype __fixdfdi (DFtype);
extern DItype __fixsfdi (SFtype);
extern USItype __fixunsdfsi (DFtype);
extern USItype __fixunssfsi (SFtype);
+extern TFtype __floatditf (DItype);
extern DFtype __floatdidf (DItype);
extern SFtype __floatdisf (DItype);
+extern DItype __fixunstfdi (TFtype);
static DItype local_fixunssfdi (SFtype);
static DItype local_fixunsdfdi (DFtype);
DItype
+__fixtfdi (TFtype a)
+{
+ if (a < 0)
+ return - __fixunstfdi (-a);
+ return __fixunstfdi (a);
+}
+
+DItype
__fixdfdi (DFtype a)
{
if (a < 0)
@@ -77,14 +88,25 @@ __fixunssfsi (SFtype a)
return (SItype) a;
}
+TFtype
+__floatditf (DItype u)
+{
+ DFtype dh, dl;
+
+ dh = (SItype) (u >> (sizeof (SItype) * 8));
+ dh *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
+ dl = (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
+
+ return (TFtype) dh + (TFtype) dl;
+}
+
DFtype
__floatdidf (DItype u)
{
DFtype d;
d = (SItype) (u >> (sizeof (SItype) * 8));
- d *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
- d *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
+ d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return d;
@@ -109,13 +131,36 @@ __floatdisf (DItype u)
}
}
f = (SItype) (u >> (sizeof (SItype) * 8));
- f *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
- f *= (((UDItype) 1) << ((sizeof (SItype) * 8) / 2));
+ f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return (SFtype) f;
}
+DItype
+__fixunstfdi (TFtype a)
+{
+ if (a < 0)
+ return 0;
+
+ /* Compute high word of result, as a flonum. */
+ const TFtype b = (a / (((UDItype) 1) << (sizeof (SItype) * 8)));
+ /* Convert that to fixed (but not to DItype!),
+ and shift it into the high word. */
+ UDItype v = (USItype) b;
+ v <<= (sizeof (SItype) * 8);
+ /* Remove high part from the TFtype, leaving the low part as flonum. */
+ a -= (TFtype) v;
+ /* Convert that to fixed (but not to DItype!) and add it in.
+ Sometimes A comes out negative. This is significant, since
+ A has more bits than a long int does. */
+ if (a < 0)
+ v -= (USItype) (-a);
+ else
+ v += (USItype) a;
+ return v;
+}
+
/* This version is needed to prevent recursion; fixunsdfdi in libgcc
calls fixdfdi, which in turn calls calls fixunsdfdi. */
diff --git a/contrib/gcc/config/rs6000/rios1.md b/contrib/gcc/config/rs6000/rios1.md
new file mode 100644
index 000000000000..5e77a67fe2c9
--- /dev/null
+++ b/contrib/gcc/config/rs6000/rios1.md
@@ -0,0 +1,179 @@
+;; Scheduling description for IBM POWER processor.
+;; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "rios1,rios1fp")
+(define_cpu_unit "iu_rios1" "rios1")
+(define_cpu_unit "fpu_rios1" "rios1fp")
+(define_cpu_unit "bpu_rios1" "rios1")
+
+;; RIOS1 32-bit IU, FPU, BPU
+
+(define_insn_reservation "rios1-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1")
+
+(define_insn_reservation "rios1-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1")
+
+(define_insn_reservation "rios1-fpload" 2
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1")
+
+(define_insn_reservation "ppc601-fpload" 3
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "ppc601"))
+ "iu_rios1")
+
+(define_insn_reservation "rios1-fpstore" 1
+ (and (eq_attr "type" "fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1+fpu_rios1")
+
+(define_insn_reservation "rios1-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1")
+
+(define_insn_reservation "rios1-imul" 5
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1*5")
+
+(define_insn_reservation "rios1-imul2" 4
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1*4")
+
+(define_insn_reservation "rios1-imul3" 3
+ (and (eq_attr "type" "imul")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1*3")
+
+(define_insn_reservation "ppc601-imul" 5
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "ppc601"))
+ "iu_rios1*5")
+
+(define_insn_reservation "rios1-idiv" 19
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1*19")
+
+(define_insn_reservation "ppc601-idiv" 36
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "ppc601"))
+ "iu_rios1*36")
+
+; compare executes on integer unit, but feeds insns which
+; execute on the branch unit.
+(define_insn_reservation "rios1-compare" 4
+ (and (eq_attr "type" "cmp,fast_compare,compare")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1,nothing*2,bpu_rios1")
+
+(define_insn_reservation "rios1-delayed_compare" 5
+ (and (eq_attr "type" "delayed_compare")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1,nothing*3,bpu_rios1")
+
+(define_insn_reservation "ppc601-compare" 3
+ (and (eq_attr "type" "cmp,compare,delayed_compare")
+ (eq_attr "cpu" "ppc601"))
+ "iu_rios1,nothing,bpu_rios1")
+
+(define_insn_reservation "rios1-fpcompare" 9
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "rios1"))
+ "fpu_rios1,nothing*3,bpu_rios1")
+
+(define_insn_reservation "ppc601-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "ppc601"))
+ "(fpu_rios1+iu_rios1*2),nothing*2,bpu_rios1")
+
+(define_insn_reservation "rios1-fp" 2
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "rios1"))
+ "fpu_rios1")
+
+(define_insn_reservation "ppc601-fp" 4
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "ppc601"))
+ "fpu_rios1")
+
+(define_insn_reservation "rios1-dmul" 5
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "ppc601"))
+ "fpu_rios1*2")
+
+(define_insn_reservation "rios1-sdiv" 19
+ (and (eq_attr "type" "sdiv,ddiv")
+ (eq_attr "cpu" "rios1"))
+ "fpu_rios1*19")
+
+(define_insn_reservation "ppc601-sdiv" 17
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "ppc601"))
+ "fpu_rios1*17")
+
+(define_insn_reservation "ppc601-ddiv" 31
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "ppc601"))
+ "fpu_rios1*31")
+
+(define_insn_reservation "rios1-mfcr" 2
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1,bpu_rios1")
+
+(define_insn_reservation "rios1-mtcr" 4
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1,bpu_rios1")
+
+(define_insn_reservation "rios1-crlogical" 4
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "bpu_rios1")
+
+(define_insn_reservation "rios1-mtjmpr" 5
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "rios1"))
+ "iu_rios1,bpu_rios1")
+
+(define_insn_reservation "ppc601-mtjmpr" 4
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "ppc601"))
+ "iu_rios1,bpu_rios1")
+
+(define_insn_reservation "rios1-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "iu_rios1,bpu_rios1")
+
+(define_insn_reservation "rios1-branch" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "rios1,ppc601"))
+ "bpu_rios1")
+
diff --git a/contrib/gcc/config/rs6000/rios2.md b/contrib/gcc/config/rs6000/rios2.md
new file mode 100644
index 000000000000..36690acf06e7
--- /dev/null
+++ b/contrib/gcc/config/rs6000/rios2.md
@@ -0,0 +1,117 @@
+;; Scheduling description for IBM Power2 processor.
+;; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "rios2,rios2fp")
+(define_cpu_unit "iu1_rios2,iu2_rios2" "rios2")
+(define_cpu_unit "fpu1_rios2,fpu2_rios2" "rios2fp")
+(define_cpu_unit "bpu_rios2" "rios2")
+
+;; RIOS2 32-bit 2xIU, 2xFPU, BPU
+;; IU1 can perform all integer operations
+;; IU2 can perform all integer operations except imul and idiv
+
+(define_insn_reservation "rios2-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,\
+ load_ux,load_u,fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2|iu2_rios2")
+
+(define_insn_reservation "rios2-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u,fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2|iu2_rios2")
+
+(define_insn_reservation "rios2-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2|iu2_rios2")
+
+(define_insn_reservation "rios2-imul" 2
+ (and (eq_attr "type" "imul,imul2,imul3,imul_compare")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2*2")
+
+(define_insn_reservation "rios2-idiv" 13
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2*13")
+
+; compare executes on integer unit, but feeds insns which
+; execute on the branch unit.
+(define_insn_reservation "rios2-compare" 3
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "rios2"))
+ "(iu1_rios2|iu2_rios2),nothing,bpu_rios2")
+
+(define_insn_reservation "rios2-fp" 2
+ (and (eq_attr "type" "fp")
+ (eq_attr "cpu" "rios2"))
+ "fpu1_rios2|fpu2_rios2")
+
+(define_insn_reservation "rios2-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "rios2"))
+ "(fpu1_rios2|fpu2_rios2),nothing*3,bpu_rios2")
+
+(define_insn_reservation "rios2-dmul" 2
+ (and (eq_attr "type" "dmul")
+ (eq_attr "cpu" "rios2"))
+ "fpu1_rios2|fpu2_rios2")
+
+(define_insn_reservation "rios2-sdiv" 17
+ (and (eq_attr "type" "sdiv,ddiv")
+ (eq_attr "cpu" "rios2"))
+ "(fpu1_rios2*17)|(fpu2_rios2*17)")
+
+(define_insn_reservation "rios2-ssqrt" 26
+ (and (eq_attr "type" "ssqrt,dsqrt")
+ (eq_attr "cpu" "rios2"))
+ "(fpu1_rios2*26)|(fpu2_rios2*26)")
+
+(define_insn_reservation "rios2-mfcr" 2
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2,bpu_rios2")
+
+(define_insn_reservation "rios2-mtcr" 3
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2,bpu_rios2")
+
+(define_insn_reservation "rios2-crlogical" 3
+ (and (eq_attr "type" "cr_logical,delayed_cr")
+ (eq_attr "cpu" "rios2"))
+ "bpu_rios2")
+
+(define_insn_reservation "rios2-mtjmpr" 5
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2,bpu_rios2")
+
+(define_insn_reservation "rios2-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "rios2"))
+ "iu1_rios2,bpu_rios2")
+
+(define_insn_reservation "rios2-branch" 1
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "rios2"))
+ "bpu_rios2")
+
diff --git a/contrib/gcc/config/rs6000/rs6000-c.c b/contrib/gcc/config/rs6000/rs6000-c.c
index 03f91baf2c7e..a47afee59b38 100644
--- a/contrib/gcc/config/rs6000/rs6000-c.c
+++ b/contrib/gcc/config/rs6000/rs6000-c.c
@@ -1,28 +1,30 @@
/* Subroutines for the C front end on the POWER and PowerPC architectures.
- Copyright (C) 2002
+ Copyright (C) 2002, 2003
Free Software Foundation, Inc.
Contributed by Zack Weinberg <zack@codesourcery.com>
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "cpplib.h"
#include "tree.h"
#include "c-pragma.h"
@@ -39,15 +41,14 @@ Boston, MA 02111-1307, USA. */
whether or not new function declarations receive a longcall
attribute by default. */
-#define SYNTAX_ERROR(msgid) do { \
+#define SYNTAX_ERROR(msgid) do { \
warning (msgid); \
warning ("ignoring malformed #pragma longcall"); \
return; \
} while (0)
void
-rs6000_pragma_longcall (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+rs6000_pragma_longcall (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
tree x, n;
@@ -78,8 +79,7 @@ rs6000_pragma_longcall (pfile)
#define builtin_assert(TXT) cpp_assert (pfile, TXT)
void
-rs6000_cpu_cpp_builtins (pfile)
- cpp_reader *pfile;
+rs6000_cpu_cpp_builtins (cpp_reader *pfile)
{
if (TARGET_POWER2)
builtin_define ("_ARCH_PWR2");
@@ -112,9 +112,6 @@ rs6000_cpu_cpp_builtins (pfile)
case ABI_V4:
builtin_define ("_CALL_SYSV");
break;
- case ABI_AIX_NODESC:
- builtin_define ("_CALL_AIX");
- break;
case ABI_AIX:
builtin_define ("_CALL_AIXDESC");
builtin_define ("_CALL_AIX");
diff --git a/contrib/gcc/config/rs6000/rs6000-modes.def b/contrib/gcc/config/rs6000/rs6000-modes.def
index ac4112ca8edc..6f17f1a7acc2 100644
--- a/contrib/gcc/config/rs6000/rs6000-modes.def
+++ b/contrib/gcc/config/rs6000/rs6000-modes.def
@@ -1,23 +1,32 @@
/* Definitions of target machine for GNU compiler, for IBM RS/6000.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+/* 128-bit floating point. ABI_V4 uses IEEE quad, AIX/Darwin
+ adjust this in rs6000_override_options. */
+FLOAT_MODE (TF, 16, ieee_quad_format);
+
+/* PSImode is used for the XER register. The XER register
+ is not used for anything; perhaps it should be deleted,
+ except that that would change register numbers. */
+PARTIAL_INT_MODE (SI);
/* Add any extra modes needed to represent the condition code.
@@ -26,6 +35,6 @@ Boston, MA 02111-1307, USA. */
use a mode for the case when we are comparing the results of two
comparisons, as then only the EQ bit is valid in the register. */
-CC (CCUNS)
-CC (CCFP)
-CC (CCEQ)
+CC_MODE (CCUNS);
+CC_MODE (CCFP);
+CC_MODE (CCEQ);
diff --git a/contrib/gcc/config/rs6000/rs6000-protos.h b/contrib/gcc/config/rs6000/rs6000-protos.h
index 4d6daa533e71..acac75ada3f0 100644
--- a/contrib/gcc/config/rs6000/rs6000-protos.h
+++ b/contrib/gcc/config/rs6000/rs6000-protos.h
@@ -1,23 +1,24 @@
/* Definitions of target machine for GNU compiler, for IBM RS/6000.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#ifndef GCC_RS6000_PROTOS_H
#define GCC_RS6000_PROTOS_H
@@ -27,178 +28,187 @@ Boston, MA 02111-1307, USA. */
#ifdef RTX_CODE
#ifdef TREE_CODE
-extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx, int, int));
-extern void rs6000_va_start PARAMS ((tree, rtx));
+extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, int, int, int);
+extern void rs6000_va_start (tree, rtx);
#endif /* TREE_CODE */
-extern struct rtx_def *rs6000_got_register PARAMS ((rtx));
-extern struct rtx_def *find_addr_reg PARAMS ((rtx));
-extern int any_operand PARAMS ((rtx, enum machine_mode));
-extern int short_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int u_short_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int non_short_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int exact_log2_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int gpc_reg_operand PARAMS ((rtx, enum machine_mode));
-extern int cc_reg_operand PARAMS ((rtx, enum machine_mode));
-extern int cc_reg_not_cr0_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_short_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_neg_short_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_aligned_short_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_u_short_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_arith_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_add_cint64_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_sub_cint64_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_logical_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int got_operand PARAMS ((rtx, enum machine_mode));
-extern int got_no_const_operand PARAMS ((rtx, enum machine_mode));
-extern int num_insns_constant PARAMS ((rtx, enum machine_mode));
-extern int easy_fp_constant PARAMS ((rtx, enum machine_mode));
-extern int zero_fp_constant PARAMS ((rtx, enum machine_mode));
-extern int zero_constant PARAMS ((rtx, enum machine_mode));
-extern int volatile_mem_operand PARAMS ((rtx, enum machine_mode));
-extern int offsettable_mem_operand PARAMS ((rtx, enum machine_mode));
-extern int mem_or_easy_const_operand PARAMS ((rtx, enum machine_mode));
-extern int add_operand PARAMS ((rtx, enum machine_mode));
-extern int non_add_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int non_logical_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int logical_operand PARAMS ((rtx, enum machine_mode));
-extern int mask_operand PARAMS ((rtx, enum machine_mode));
-extern int mask_operand_wrap PARAMS ((rtx, enum machine_mode));
-extern int mask64_operand PARAMS ((rtx, enum machine_mode));
-extern int mask64_2_operand PARAMS ((rtx, enum machine_mode));
-extern void build_mask64_2_operands PARAMS ((rtx, rtx *));
-extern int and64_operand PARAMS ((rtx, enum machine_mode));
-extern int and64_2_operand PARAMS ((rtx, enum machine_mode));
-extern int and_operand PARAMS ((rtx, enum machine_mode));
-extern int count_register_operand PARAMS ((rtx, enum machine_mode));
-extern int xer_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_mem_operand PARAMS ((rtx, enum machine_mode));
-extern int lwa_operand PARAMS ((rtx, enum machine_mode));
-extern int call_operand PARAMS ((rtx, enum machine_mode));
-extern int current_file_function_operand PARAMS ((rtx, enum machine_mode));
-extern int input_operand PARAMS ((rtx, enum machine_mode));
-extern int small_data_operand PARAMS ((rtx, enum machine_mode));
-extern int s8bit_cint_operand PARAMS ((rtx, enum machine_mode));
-extern int constant_pool_expr_p PARAMS ((rtx));
-extern int toc_relative_expr_p PARAMS ((rtx));
-extern int expand_block_move PARAMS ((rtx[]));
-extern int load_multiple_operation PARAMS ((rtx, enum machine_mode));
-extern const char * rs6000_output_load_multiple PARAMS ((rtx[]));
-extern int store_multiple_operation PARAMS ((rtx, enum machine_mode));
-extern int branch_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int branch_positive_comparison_operator
- PARAMS ((rtx, enum machine_mode));
-extern int scc_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int trap_comparison_operator PARAMS ((rtx, enum machine_mode));
-extern int boolean_operator PARAMS ((rtx, enum machine_mode));
-extern int boolean_or_operator PARAMS ((rtx, enum machine_mode));
-extern int min_max_operator PARAMS ((rtx, enum machine_mode));
-extern int includes_lshift_p PARAMS ((rtx, rtx));
-extern int includes_rshift_p PARAMS ((rtx, rtx));
-extern int includes_rldic_lshift_p PARAMS ((rtx, rtx));
-extern int includes_rldicr_lshift_p PARAMS ((rtx, rtx));
-extern int registers_ok_for_quad_peep PARAMS ((rtx, rtx));
-extern int addrs_ok_for_quad_peep PARAMS ((rtx, rtx));
-extern enum reg_class secondary_reload_class PARAMS ((enum reg_class,
- enum machine_mode, rtx));
-extern int ccr_bit PARAMS ((rtx, int));
-extern int extract_MB PARAMS ((rtx));
-extern int extract_ME PARAMS ((rtx));
-extern void print_operand PARAMS ((FILE *, rtx, int));
-extern void print_operand_address PARAMS ((FILE *, rtx));
-extern enum rtx_code rs6000_reverse_condition PARAMS ((enum machine_mode,
- enum rtx_code));
-extern void rs6000_emit_sCOND PARAMS ((enum rtx_code, rtx));
-extern void rs6000_emit_cbranch PARAMS ((enum rtx_code, rtx));
-extern char * output_cbranch PARAMS ((rtx, const char *, int, rtx));
-extern rtx rs6000_emit_set_const PARAMS ((rtx, enum machine_mode, rtx, int));
-extern int rs6000_emit_cmove PARAMS ((rtx, rtx, rtx, rtx));
-extern void rs6000_emit_minmax PARAMS ((rtx, enum rtx_code, rtx, rtx));
-extern void output_toc PARAMS ((FILE *, rtx, int, enum machine_mode));
-extern void rs6000_initialize_trampoline PARAMS ((rtx, rtx, rtx));
-extern struct rtx_def *rs6000_longcall_ref PARAMS ((rtx));
-extern void rs6000_fatal_bad_address PARAMS ((rtx));
-extern int stmw_operation PARAMS ((rtx, enum machine_mode));
-extern int mtcrf_operation PARAMS ((rtx, enum machine_mode));
-extern int lmw_operation PARAMS ((rtx, enum machine_mode));
-extern struct rtx_def *create_TOC_reference PARAMS ((rtx));
-extern void rs6000_emit_eh_toc_restore PARAMS ((rtx));
-extern void rs6000_emit_move PARAMS ((rtx, rtx, enum machine_mode));
-extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
-extern rtx rs6000_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
- int, int, int, int *));
-extern int rs6000_legitimate_address PARAMS ((enum machine_mode, rtx, int));
-extern rtx rs6000_return_addr PARAMS ((int, rtx));
-extern void rs6000_output_symbol_ref PARAMS ((FILE*, rtx));
-
-extern rtx rs6000_machopic_legitimize_pic_address PARAMS ((rtx orig, enum machine_mode mode, rtx reg));
+extern struct rtx_def *rs6000_got_register (rtx);
+extern struct rtx_def *find_addr_reg (rtx);
+extern int any_operand (rtx, enum machine_mode);
+extern int short_cint_operand (rtx, enum machine_mode);
+extern int u_short_cint_operand (rtx, enum machine_mode);
+extern int non_short_cint_operand (rtx, enum machine_mode);
+extern int exact_log2_cint_operand (rtx, enum machine_mode);
+extern int gpc_reg_operand (rtx, enum machine_mode);
+extern int cc_reg_operand (rtx, enum machine_mode);
+extern int cc_reg_not_cr0_operand (rtx, enum machine_mode);
+extern int reg_or_short_operand (rtx, enum machine_mode);
+extern int reg_or_neg_short_operand (rtx, enum machine_mode);
+extern int reg_or_aligned_short_operand (rtx, enum machine_mode);
+extern int reg_or_u_short_operand (rtx, enum machine_mode);
+extern int reg_or_cint_operand (rtx, enum machine_mode);
+extern int reg_or_arith_cint_operand (rtx, enum machine_mode);
+extern int reg_or_add_cint64_operand (rtx, enum machine_mode);
+extern int reg_or_sub_cint64_operand (rtx, enum machine_mode);
+extern int reg_or_logical_cint_operand (rtx, enum machine_mode);
+extern int got_operand (rtx, enum machine_mode);
+extern int word_offset_memref_operand (rtx, enum machine_mode);
+extern int got_no_const_operand (rtx, enum machine_mode);
+extern int num_insns_constant (rtx, enum machine_mode);
+extern int easy_fp_constant (rtx, enum machine_mode);
+extern int easy_vector_constant (rtx, enum machine_mode);
+extern rtx gen_easy_vector_constant_add_self (rtx);
+extern const char *output_vec_const_move (rtx *);
+extern int zero_fp_constant (rtx, enum machine_mode);
+extern int zero_constant (rtx, enum machine_mode);
+extern int volatile_mem_operand (rtx, enum machine_mode);
+extern int offsettable_mem_operand (rtx, enum machine_mode);
+extern int mem_or_easy_const_operand (rtx, enum machine_mode);
+extern int add_operand (rtx, enum machine_mode);
+extern int non_add_cint_operand (rtx, enum machine_mode);
+extern int non_logical_cint_operand (rtx, enum machine_mode);
+extern int logical_operand (rtx, enum machine_mode);
+extern int mask_operand (rtx, enum machine_mode);
+extern int mask_operand_wrap (rtx, enum machine_mode);
+extern int mask64_operand (rtx, enum machine_mode);
+extern int mask64_2_operand (rtx, enum machine_mode);
+extern void build_mask64_2_operands (rtx, rtx *);
+extern int and64_operand (rtx, enum machine_mode);
+extern int and64_2_operand (rtx, enum machine_mode);
+extern int and_operand (rtx, enum machine_mode);
+extern int count_register_operand (rtx, enum machine_mode);
+extern int xer_operand (rtx, enum machine_mode);
+extern int reg_or_mem_operand (rtx, enum machine_mode);
+extern int lwa_operand (rtx, enum machine_mode);
+extern int call_operand (rtx, enum machine_mode);
+extern int current_file_function_operand (rtx, enum machine_mode);
+extern int input_operand (rtx, enum machine_mode);
+extern int small_data_operand (rtx, enum machine_mode);
+extern int s8bit_cint_operand (rtx, enum machine_mode);
+extern bool legitimate_constant_pool_address_p (rtx);
+extern int expand_block_move (rtx[]);
+extern int load_multiple_operation (rtx, enum machine_mode);
+extern const char * rs6000_output_load_multiple (rtx[]);
+extern int store_multiple_operation (rtx, enum machine_mode);
+extern int branch_comparison_operator (rtx, enum machine_mode);
+extern int branch_positive_comparison_operator (rtx, enum machine_mode);
+extern int scc_comparison_operator (rtx, enum machine_mode);
+extern int trap_comparison_operator (rtx, enum machine_mode);
+extern int boolean_operator (rtx, enum machine_mode);
+extern int boolean_or_operator (rtx, enum machine_mode);
+extern int min_max_operator (rtx, enum machine_mode);
+extern int includes_lshift_p (rtx, rtx);
+extern int includes_rshift_p (rtx, rtx);
+extern int includes_rldic_lshift_p (rtx, rtx);
+extern int includes_rldicr_lshift_p (rtx, rtx);
+extern int registers_ok_for_quad_peep (rtx, rtx);
+extern int addrs_ok_for_quad_peep (rtx, rtx);
+extern bool gpr_or_gpr_p (rtx, rtx);
+extern enum reg_class secondary_reload_class (enum reg_class,
+ enum machine_mode, rtx, int);
+extern int ccr_bit (rtx, int);
+extern int extract_MB (rtx);
+extern int extract_ME (rtx);
+extern void print_operand (FILE *, rtx, int);
+extern void print_operand_address (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 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);
+extern int rs6000_emit_cmove (rtx, rtx, rtx, rtx);
+extern void rs6000_emit_minmax (rtx, enum rtx_code, rtx, rtx);
+extern void output_toc (FILE *, rtx, int, enum machine_mode);
+extern void rs6000_initialize_trampoline (rtx, rtx, rtx);
+extern struct rtx_def *rs6000_longcall_ref (rtx);
+extern void rs6000_fatal_bad_address (rtx);
+extern int stmw_operation (rtx, enum machine_mode);
+extern int mfcr_operation (rtx, enum machine_mode);
+extern int mtcrf_operation (rtx, enum machine_mode);
+extern int lmw_operation (rtx, enum machine_mode);
+extern struct rtx_def *create_TOC_reference (rtx);
+extern void rs6000_split_multireg_move (rtx, rtx);
+extern void rs6000_emit_move (rtx, rtx, enum machine_mode);
+extern rtx rs6000_legitimize_address (rtx, 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_mode_dependent_address (rtx);
+extern rtx rs6000_return_addr (int, rtx);
+extern void rs6000_output_symbol_ref (FILE*, rtx);
+extern HOST_WIDE_INT rs6000_initial_elimination_offset (int, int);
+
+extern rtx rs6000_machopic_legitimize_pic_address (rtx orig,
+ enum machine_mode mode, rtx reg);
#endif /* RTX_CODE */
#ifdef TREE_CODE
-extern void function_arg_advance PARAMS ((CUMULATIVE_ARGS *, enum machine_mode,
- tree, int));
-extern int function_arg_boundary PARAMS ((enum machine_mode, tree));
-extern struct rtx_def *function_arg PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode, tree, int));
-extern int function_arg_partial_nregs PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode, tree, int));
-extern int function_arg_pass_by_reference PARAMS ((CUMULATIVE_ARGS *,
+extern unsigned int rs6000_special_round_type_align (tree, int, int);
+extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, int);
+extern int function_arg_boundary (enum machine_mode, tree);
+extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern int function_arg_pass_by_reference (CUMULATIVE_ARGS *,
enum machine_mode,
- tree, int));
-extern void setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode, tree,
- int *, int));
-extern struct rtx_def *rs6000_va_arg PARAMS ((tree, tree));
-extern int function_ok_for_sibcall PARAMS ((tree));
+ tree, int);
+extern rtx rs6000_function_value (tree, tree);
+extern rtx rs6000_libcall_value (enum machine_mode);
+extern struct rtx_def *rs6000_va_arg (tree, tree);
+extern int function_ok_for_sibcall (tree);
+extern void rs6000_elf_declare_function_name (FILE *, const char *, tree);
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
-extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree));
+extern enum direction function_arg_padding (enum machine_mode, tree);
#endif /* ARGS_SIZE_RTX */
#endif /* TREE_CODE */
-extern void optimization_options PARAMS ((int, int));
-extern void rs6000_override_options PARAMS ((const char *));
-extern void rs6000_file_start PARAMS ((FILE *, const char *));
-extern int direct_return PARAMS ((void));
-extern union tree_node *rs6000_build_va_list PARAMS ((void));
-extern int first_reg_to_save PARAMS ((void));
-extern int first_fp_reg_to_save PARAMS ((void));
-extern rs6000_stack_t *rs6000_stack_info PARAMS ((void));
-extern void output_ascii PARAMS ((FILE *, const char *, int));
-extern void rs6000_gen_section_name PARAMS ((char **, const char *,
- const char *));
-extern void output_function_profiler PARAMS ((FILE *, int));
-extern void output_profile_hook PARAMS ((int));
-extern int rs6000_trampoline_size PARAMS ((void));
-extern void toc_section PARAMS ((void));
-extern void sdata_section PARAMS ((void));
-extern void sdata2_section PARAMS ((void));
-extern void sbss_section PARAMS ((void));
-extern void private_data_section PARAMS ((void));
-extern void read_only_data_section PARAMS ((void));
-extern void read_only_private_data_section PARAMS ((void));
-extern int get_TOC_alias_set PARAMS ((void));
-extern int uses_TOC PARAMS ((void));
-extern void rs6000_emit_prologue PARAMS ((void));
-extern void rs6000_emit_load_toc_table PARAMS ((int));
-extern void rs6000_aix_emit_builtin_unwind_init PARAMS ((void));
-extern void rs6000_emit_epilogue PARAMS ((int));
-extern void debug_stack_info PARAMS ((rs6000_stack_t *));
-extern const char * output_isel PARAMS ((rtx *));
-extern int vrsave_operation PARAMS ((rtx, enum machine_mode));
-extern int rs6000_register_move_cost PARAMS ((enum machine_mode,
- enum reg_class, enum reg_class));
-extern int rs6000_memory_move_cost PARAMS ((enum machine_mode,
- enum reg_class, int));
+extern void optimization_options (int, int);
+extern void rs6000_override_options (const char *);
+extern int direct_return (void);
+extern int first_reg_to_save (void);
+extern int first_fp_reg_to_save (void);
+extern void output_ascii (FILE *, const char *, int);
+extern void rs6000_gen_section_name (char **, const char *, const char *);
+extern void output_function_profiler (FILE *, int);
+extern void output_profile_hook (int);
+extern int rs6000_trampoline_size (void);
+extern void toc_section (void);
+extern void sdata_section (void);
+extern void sdata2_section (void);
+extern void sbss_section (void);
+extern void private_data_section (void);
+extern void read_only_data_section (void);
+extern void read_only_private_data_section (void);
+extern int get_TOC_alias_set (void);
+extern void rs6000_emit_prologue (void);
+extern void rs6000_emit_load_toc_table (int);
+extern void rs6000_aix_emit_builtin_unwind_init (void);
+extern unsigned int rs6000_dbx_register_number (unsigned int);
+extern void rs6000_emit_epilogue (int);
+extern void rs6000_emit_eh_reg_restore (rtx, rtx);
+extern const char * output_isel (rtx *);
+extern int vrsave_operation (rtx, enum machine_mode);
+extern int rs6000_register_move_cost (enum machine_mode,
+ enum reg_class, enum reg_class);
+extern int rs6000_memory_move_cost (enum machine_mode, enum reg_class, int);
+extern bool rs6000_tls_referenced_p (rtx);
+extern int rs6000_tls_symbol_ref (rtx, enum machine_mode);
+extern void rs6000_output_dwarf_dtprel (FILE*, int, rtx);
/* Declare functions in rs6000-c.c */
-#ifdef GCC_CPPLIB_H
-extern void rs6000_pragma_longcall PARAMS ((cpp_reader *));
-extern void rs6000_cpu_cpp_builtins PARAMS ((cpp_reader *));
+extern void rs6000_pragma_longcall (struct cpp_reader *);
+extern void rs6000_cpu_cpp_builtins (struct cpp_reader *);
+
+#if TARGET_MACHO
+char *output_call (rtx, rtx *, int, int);
#endif
#endif /* rs6000-protos.h */
diff --git a/contrib/gcc/config/rs6000/rs6000.c b/contrib/gcc/config/rs6000/rs6000.c
index 13f4ed3dab10..33f47cef3f31 100644
--- a/contrib/gcc/config/rs6000/rs6000.c
+++ b/contrib/gcc/config/rs6000/rs6000.c
@@ -1,27 +1,29 @@
/* Subroutines used for code generation on IBM RS/6000.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -48,14 +50,66 @@ Boston, MA 02111-1307, USA. */
#include "target-def.h"
#include "langhooks.h"
#include "reload.h"
+#include "cfglayout.h"
+#include "sched-int.h"
+#if TARGET_XCOFF
+#include "xcoffout.h" /* get declarations of xcoff_*_section_name */
+#endif
#ifndef TARGET_NO_PROTOTYPE
#define TARGET_NO_PROTOTYPE 0
#endif
+#define EASY_VECTOR_15(n) ((n) >= -16 && (n) <= 15)
+#define EASY_VECTOR_15_ADD_SELF(n) ((n) >= 0x10 && (n) <= 0x1e \
+ && !((n) & 1))
+
#define min(A,B) ((A) < (B) ? (A) : (B))
#define max(A,B) ((A) > (B) ? (A) : (B))
+/* Structure used to define the rs6000 stack */
+typedef struct rs6000_stack {
+ int first_gp_reg_save; /* first callee saved GP register used */
+ int first_fp_reg_save; /* first callee saved FP register used */
+ int first_altivec_reg_save; /* first callee saved AltiVec register used */
+ int lr_save_p; /* true if the link reg needs to be saved */
+ int cr_save_p; /* true if the CR reg needs to be saved */
+ unsigned int vrsave_mask; /* mask of vec registers to save */
+ int toc_save_p; /* true if the TOC needs to be saved */
+ int push_p; /* true if we need to allocate stack space */
+ int calls_p; /* true if the function makes any calls */
+ enum rs6000_abi abi; /* which ABI to use */
+ int gp_save_offset; /* offset to save GP regs from initial SP */
+ int fp_save_offset; /* offset to save FP regs from initial SP */
+ int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
+ int lr_save_offset; /* offset to save LR from initial SP */
+ int cr_save_offset; /* offset to save CR from initial SP */
+ int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
+ int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
+ int toc_save_offset; /* offset to save the TOC pointer */
+ int varargs_save_offset; /* offset to save the varargs registers */
+ int ehrd_offset; /* offset to EH return data */
+ int reg_size; /* register size (4 or 8) */
+ int varargs_size; /* size to hold V.4 args passed in regs */
+ HOST_WIDE_INT vars_size; /* variable save area size */
+ int parm_size; /* outgoing parameter size */
+ int save_size; /* save area size */
+ int fixed_size; /* fixed size of stack frame */
+ int gp_size; /* size of saved GP registers */
+ int fp_size; /* size of saved FP registers */
+ int altivec_size; /* size of saved AltiVec registers */
+ int cr_size; /* size to hold CR if not in save_size */
+ int lr_size; /* size to hold LR if not in save_size */
+ int vrsave_size; /* size to hold VRSAVE if not in save_size */
+ int altivec_padding_size; /* size of altivec alignment padding if
+ not in save_size */
+ int spe_gp_size; /* size of 64-bit GPR save size for SPE */
+ int spe_padding_size;
+ int toc_size; /* size to hold TOC if not in save_size */
+ HOST_WIDE_INT total_size; /* total bytes allocated for stack */
+ int spe_64bit_regs_used;
+} rs6000_stack_t;
+
/* Target cpu type */
enum processor_type rs6000_cpu;
@@ -67,6 +121,25 @@ struct rs6000_cpu_select rs6000_select[3] =
{ (const char *)0, "-mtune=", 1, 0 },
};
+/* Always emit branch hint bits. */
+static GTY(()) bool rs6000_always_hint;
+
+/* Schedule instructions for group formation. */
+static GTY(()) bool rs6000_sched_groups;
+
+/* Support adjust_priority scheduler hook
+ and -mprioritize-restricted-insns= option. */
+const char *rs6000_sched_restricted_insns_priority_str;
+int rs6000_sched_restricted_insns_priority;
+
+/* Support for -msched-costly-dep option. */
+const char *rs6000_sched_costly_dep_str;
+enum rs6000_dependence_cost rs6000_sched_costly_dep;
+
+/* Support for -minsert-sched-nops option. */
+const char *rs6000_sched_insert_nops_str;
+enum rs6000_nop_insertion rs6000_sched_insert_nops;
+
/* Size of long double */
const char *rs6000_long_double_size_string;
int rs6000_long_double_type_size;
@@ -86,17 +159,23 @@ int rs6000_spe_abi;
/* Whether isel instructions should be generated. */
int rs6000_isel;
-/* Nonzero if we have FPRs. */
-int rs6000_fprs = 1;
+/* Whether SPE simd instructions should be generated. */
+int rs6000_spe;
+
+/* Nonzero if floating point operations are done in the GPRs. */
+int rs6000_float_gprs = 0;
+
+/* String from -mfloat-gprs=. */
+const char *rs6000_float_gprs_string;
/* String from -misel=. */
const char *rs6000_isel_string;
-/* Set to nonzero once AIX common-mode calls have been defined. */
-static int common_mode_defined;
+/* String from -mspe=. */
+const char *rs6000_spe_string;
-/* Private copy of original value of flag_pic for ABI_AIX. */
-static int rs6000_flag_pic;
+/* 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. */
@@ -109,7 +188,7 @@ int rs6000_pic_labelno;
#ifdef USING_ELFOS_H
/* Which abi to adhere to */
-const char *rs6000_abi_name = RS6000_ABI_NAME;
+const char *rs6000_abi_name;
/* Semantics of the small data area */
enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
@@ -121,6 +200,10 @@ const char *rs6000_sdata_name = (char *)0;
int fixuplabelno = 0;
#endif
+/* Bit size of immediate TLS offsets and string from which it is decoded. */
+int rs6000_tls_size = 32;
+const char *rs6000_tls_size_string;
+
/* ABI enumeration available for subtarget to use. */
enum rs6000_abi rs6000_current_abi;
@@ -132,6 +215,11 @@ const char *rs6000_debug_name;
int rs6000_debug_stack; /* debug stack applications */
int rs6000_debug_arg; /* debug argument handling */
+/* Opaque types. */
+static GTY(()) tree opaque_V2SI_type_node;
+static GTY(()) tree opaque_V2SF_type_node;
+static GTY(()) tree opaque_p_V2SI_type_node;
+
const char *rs6000_traceback_name;
static enum {
traceback_default = 0,
@@ -145,7 +233,7 @@ int toc_initialized;
char toc_label_name[10];
/* Alias set for saves and restores from the rs6000 stack. */
-static int rs6000_sr_alias_set;
+static GTY(()) int rs6000_sr_alias_set;
/* Call distance, overridden by -mlongcall and #pragma longcall(1).
The only place that looks at this is rs6000_set_default_type_attributes;
@@ -154,6 +242,11 @@ static int rs6000_sr_alias_set;
int rs6000_default_long_calls;
const char *rs6000_longcall_switch;
+/* Control alignment for fields within structures. */
+/* String from -malign-XXXXX. */
+const char *rs6000_alignment_string;
+int rs6000_alignment_flags;
+
struct builtin_description
{
/* mask is not const because we're going to alter it below. This
@@ -165,105 +258,173 @@ struct builtin_description
const enum rs6000_builtins code;
};
-static void rs6000_add_gc_roots PARAMS ((void));
-static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
-static void validate_condition_mode
- PARAMS ((enum rtx_code, enum machine_mode));
-static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
-static void rs6000_maybe_dead PARAMS ((rtx));
-static void rs6000_emit_stack_tie PARAMS ((void));
-static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
-static void emit_frame_save PARAMS ((rtx, rtx, enum machine_mode,
- unsigned int, int, int));
-static rtx gen_frame_mem_offset PARAMS ((enum machine_mode, rtx, int));
-static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
-static unsigned rs6000_hash_constant PARAMS ((rtx));
-static unsigned toc_hash_function PARAMS ((const void *));
-static int toc_hash_eq PARAMS ((const void *, const void *));
-static int toc_hash_mark_entry PARAMS ((void **, void *));
-static void toc_hash_mark_table PARAMS ((void *));
-static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
-static struct machine_function * rs6000_init_machine_status PARAMS ((void));
-static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
+static bool rs6000_function_ok_for_sibcall (tree, tree);
+static int num_insns_constant_wide (HOST_WIDE_INT);
+static void validate_condition_mode (enum rtx_code, enum machine_mode);
+static rtx rs6000_generate_compare (enum rtx_code);
+static void rs6000_maybe_dead (rtx);
+static void rs6000_emit_stack_tie (void);
+static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
+static rtx spe_synthesize_frame_save (rtx);
+static bool spe_func_has_64bit_regs_p (void);
+static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
+ int, HOST_WIDE_INT);
+static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
+static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int);
+static unsigned rs6000_hash_constant (rtx);
+static unsigned toc_hash_function (const void *);
+static int toc_hash_eq (const void *, const void *);
+static int constant_pool_expr_1 (rtx, int *, int *);
+static bool constant_pool_expr_p (rtx);
+static bool toc_relative_expr_p (rtx);
+static bool legitimate_small_data_p (enum machine_mode, rtx);
+static bool legitimate_offset_address_p (enum machine_mode, rtx, int);
+static bool legitimate_indexed_address_p (rtx, int);
+static bool legitimate_indirect_address_p (rtx, int);
+static bool macho_lo_sum_memory_operand (rtx x, enum machine_mode mode);
+static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
+static struct machine_function * rs6000_init_machine_status (void);
+static bool rs6000_assemble_integer (rtx, unsigned int, int);
#ifdef HAVE_GAS_HIDDEN
-static void rs6000_assemble_visibility PARAMS ((tree, int));
+static void rs6000_assemble_visibility (tree, int);
#endif
-static int rs6000_ra_ever_killed PARAMS ((void));
-static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
-const struct attribute_spec rs6000_attribute_table[];
-static void rs6000_set_default_type_attributes PARAMS ((tree));
-static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-static void rs6000_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
- HOST_WIDE_INT, tree));
-static rtx rs6000_emit_set_long_const PARAMS ((rtx,
- HOST_WIDE_INT, HOST_WIDE_INT));
+static int rs6000_ra_ever_killed (void);
+static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
+extern const struct attribute_spec rs6000_attribute_table[];
+static void rs6000_set_default_type_attributes (tree);
+static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
+static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
+static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
+ tree);
+static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
+static bool rs6000_return_in_memory (tree, tree);
+static void rs6000_file_start (void);
#if TARGET_ELF
-static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
- int));
-static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
-static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
-static void rs6000_elf_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT));
-static void rs6000_elf_unique_section PARAMS ((tree, int));
-static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
-static void rs6000_elf_encode_section_info PARAMS ((tree, int))
+static unsigned int rs6000_elf_section_type_flags (tree, const char *, int);
+static void rs6000_elf_asm_out_constructor (rtx, int);
+static void rs6000_elf_asm_out_destructor (rtx, int);
+static void rs6000_elf_select_section (tree, int, unsigned HOST_WIDE_INT);
+static void rs6000_elf_unique_section (tree, int);
+static void rs6000_elf_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
+static void rs6000_elf_encode_section_info (tree, rtx, int)
ATTRIBUTE_UNUSED;
-static const char *rs6000_elf_strip_name_encoding PARAMS ((const char *));
-static bool rs6000_elf_in_small_data_p PARAMS ((tree));
+static bool rs6000_elf_in_small_data_p (tree);
#endif
#if TARGET_XCOFF
-static void rs6000_xcoff_asm_globalize_label PARAMS ((FILE *, const char *));
-static void rs6000_xcoff_asm_named_section PARAMS ((const char *, unsigned int));
-static void rs6000_xcoff_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT));
-static void rs6000_xcoff_unique_section PARAMS ((tree, int));
-static void rs6000_xcoff_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
-static const char * rs6000_xcoff_strip_name_encoding PARAMS ((const char *));
-static unsigned int rs6000_xcoff_section_type_flags PARAMS ((tree, const char *, int));
+static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
+static void rs6000_xcoff_asm_named_section (const char *, unsigned int);
+static void rs6000_xcoff_select_section (tree, int, unsigned HOST_WIDE_INT);
+static void rs6000_xcoff_unique_section (tree, int);
+static void rs6000_xcoff_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
+static const char * rs6000_xcoff_strip_name_encoding (const char *);
+static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
+static void rs6000_xcoff_file_start (void);
+static void rs6000_xcoff_file_end (void);
#endif
-static void rs6000_xcoff_encode_section_info PARAMS ((tree, int))
- ATTRIBUTE_UNUSED;
-static bool rs6000_binds_local_p PARAMS ((tree));
-static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static int rs6000_adjust_priority PARAMS ((rtx, int));
-static int rs6000_issue_rate PARAMS ((void));
-
-static void rs6000_init_builtins PARAMS ((void));
-static rtx rs6000_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
-static rtx rs6000_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
-static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
-static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
-static void altivec_init_builtins PARAMS ((void));
-static void rs6000_common_init_builtins PARAMS ((void));
-
-static void enable_mask_for_builtins PARAMS ((struct builtin_description *,
- int, enum rs6000_builtins,
- enum rs6000_builtins));
-static void spe_init_builtins PARAMS ((void));
-static rtx spe_expand_builtin PARAMS ((tree, rtx, bool *));
-static rtx spe_expand_predicate_builtin PARAMS ((enum insn_code, tree, rtx));
-static rtx spe_expand_evsel_builtin PARAMS ((enum insn_code, tree, rtx));
-static int rs6000_emit_int_cmove PARAMS ((rtx, rtx, rtx, rtx));
-
-static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *));
-static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *));
-static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *));
-static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *));
-static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));
-static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
-static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
-static void rs6000_parse_abi_options PARAMS ((void));
-static void rs6000_parse_vrsave_option PARAMS ((void));
-static void rs6000_parse_isel_option PARAMS ((void));
-static int first_altivec_reg_to_save PARAMS ((void));
-static unsigned int compute_vrsave_mask PARAMS ((void));
-static void is_altivec_return_reg PARAMS ((rtx, void *));
-static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
-static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
-static int easy_vector_constant PARAMS ((rtx));
+#if TARGET_MACHO
+static bool rs6000_binds_local_p (tree);
+#endif
+static int rs6000_use_dfa_pipeline_interface (void);
+static int rs6000_variable_issue (FILE *, int, rtx, int);
+static bool rs6000_rtx_costs (rtx, int, int, int *);
+static int rs6000_adjust_cost (rtx, rtx, rtx, int);
+static bool is_microcoded_insn (rtx);
+static int is_dispatch_slot_restricted (rtx);
+static bool is_cracked_insn (rtx);
+static bool is_branch_slot_insn (rtx);
+static int rs6000_adjust_priority (rtx, int);
+static int rs6000_issue_rate (void);
+static bool rs6000_is_costly_dependence (rtx, rtx, rtx, int, int);
+static rtx get_next_active_insn (rtx, rtx);
+static bool insn_terminates_group_p (rtx , enum group_termination);
+static bool is_costly_group (rtx *, rtx);
+static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
+static int redefine_groups (FILE *, int, rtx, rtx);
+static int pad_groups (FILE *, int, rtx, rtx);
+static void rs6000_sched_finish (FILE *, int);
+static int rs6000_use_sched_lookahead (void);
+
+static void rs6000_init_builtins (void);
+static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
+static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
+static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
+static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+static void altivec_init_builtins (void);
+static void rs6000_common_init_builtins (void);
+static void rs6000_init_libfuncs (void);
+
+static void enable_mask_for_builtins (struct builtin_description *, int,
+ enum rs6000_builtins,
+ enum rs6000_builtins);
+static void spe_init_builtins (void);
+static rtx spe_expand_builtin (tree, rtx, bool *);
+static rtx spe_expand_stv_builtin (enum insn_code, tree);
+static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
+static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
+static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
+static rs6000_stack_t *rs6000_stack_info (void);
+static void debug_stack_info (rs6000_stack_t *);
+
+static rtx altivec_expand_builtin (tree, rtx, bool *);
+static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
+static rtx altivec_expand_st_builtin (tree, rtx, bool *);
+static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
+static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
+static rtx altivec_expand_predicate_builtin (enum insn_code,
+ const char *, tree, rtx);
+static rtx altivec_expand_lv_builtin (enum insn_code, tree, rtx);
+static rtx altivec_expand_stv_builtin (enum insn_code, tree);
+static void rs6000_parse_abi_options (void);
+static void rs6000_parse_alignment_option (void);
+static void rs6000_parse_tls_size_option (void);
+static void rs6000_parse_yes_no_option (const char *, const char *, int *);
+static int first_altivec_reg_to_save (void);
+static unsigned int compute_vrsave_mask (void);
+static void is_altivec_return_reg (rtx, void *);
+static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
+int easy_vector_constant (rtx, enum machine_mode);
+static int easy_vector_same (rtx, enum machine_mode);
+static int easy_vector_splat_const (int, enum machine_mode);
+static bool is_ev64_opaque_type (tree);
+static rtx rs6000_dwarf_register_span (rtx);
+static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
+static rtx rs6000_tls_get_addr (void);
+static rtx rs6000_got_sym (void);
+static inline int rs6000_tls_symbol_ref_1 (rtx *, void *);
+static const char *rs6000_get_some_local_dynamic_name (void);
+static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
+static rtx rs6000_complex_function_value (enum machine_mode);
+static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
+ enum machine_mode, tree);
+static rtx rs6000_mixed_function_arg (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
+static void setup_incoming_varargs (CUMULATIVE_ARGS *,
+ enum machine_mode, tree,
+ int *, int);
+#if TARGET_MACHO
+static void macho_branch_islands (void);
+static void add_compiler_branch_island (tree, tree, int);
+static int no_previous_def (tree function_name);
+static tree get_prev_label (tree function_name);
+#endif
+
+static tree rs6000_build_builtin_va_list (void);
+
+/* Hash table stuff for keeping track of TOC entries. */
+
+struct toc_hash_struct GTY(())
+{
+ /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
+ ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
+ rtx key;
+ enum machine_mode key_mode;
+ int labelno;
+};
+
+static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
/* Default register names. */
char rs6000_reg_names[][8] =
@@ -317,9 +478,16 @@ static const char alt_reg_names[][8] =
#ifndef MASK_STRICT_ALIGN
#define MASK_STRICT_ALIGN 0
#endif
+#ifndef TARGET_PROFILE_KERNEL
+#define TARGET_PROFILE_KERNEL 0
+#endif
/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
+
+/* Return 1 for a symbol ref for a thread-local storage symbol. */
+#define RS6000_SYMBOL_REF_TLS_P(RTX) \
+ (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
@@ -361,17 +529,35 @@ static const char alt_reg_names[][8] =
#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
#endif
+#undef TARGET_HAVE_TLS
+#define TARGET_HAVE_TLS HAVE_AS_TLS
+
+#undef TARGET_CANNOT_FORCE_CONST_MEM
+#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
+
#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE rs6000_use_dfa_pipeline_interface
+#undef TARGET_SCHED_VARIABLE_ISSUE
+#define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
+
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
#undef TARGET_SCHED_ADJUST_PRIORITY
#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
+#undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
+#define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
+#undef TARGET_SCHED_FINISH
+#define TARGET_SCHED_FINISH rs6000_sched_finish
+
+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS rs6000_init_builtins
@@ -379,18 +565,61 @@ static const char alt_reg_names[][8] =
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
+
+#if TARGET_MACHO
#undef TARGET_BINDS_LOCAL_P
#define TARGET_BINDS_LOCAL_P rs6000_binds_local_p
+#endif
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
-/* ??? Should work everywhere, but ask dje@watson.ibm.com before
- enabling for AIX. */
-#if TARGET_OBJECT_FORMAT != OBJECT_XCOFF
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
-#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
-#endif
+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
+
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
+
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS rs6000_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
+
+#undef TARGET_VECTOR_OPAQUE_P
+#define TARGET_VECTOR_OPAQUE_P is_ev64_opaque_type
+
+#undef TARGET_DWARF_REGISTER_SPAN
+#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
+
+/* On rs6000, function arguments are promoted, as are function return
+ values. */
+#undef TARGET_PROMOTE_FUNCTION_ARGS
+#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
+#undef TARGET_PROMOTE_FUNCTION_RETURN
+#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
+
+/* Structure return values are passed as an extra parameter. */
+#undef TARGET_STRUCT_VALUE_RTX
+#define TARGET_STRUCT_VALUE_RTX hook_rtx_tree_int_null
+
+#undef TARGET_RETURN_IN_MEMORY
+#define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
+
+#undef TARGET_SETUP_INCOMING_VARARGS
+#define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
+
+/* Always strict argument naming on rs6000. */
+#undef TARGET_STRICT_ARGUMENT_NAMING
+#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
+#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
+#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
+#undef TARGET_SPLIT_COMPLEX_ARG
+#define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
+
+#undef TARGET_BUILD_BUILTIN_VA_LIST
+#define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -398,138 +627,117 @@ struct gcc_target targetm = TARGET_INITIALIZER;
type and sometimes adjust other TARGET_ options. */
void
-rs6000_override_options (default_cpu)
- const char *default_cpu;
+rs6000_override_options (const char *default_cpu)
{
size_t i, j;
struct rs6000_cpu_select *ptr;
+ int set_masks;
+
+ /* Simplifications for entries below. */
- /* Simplify the entries below by making a mask for any POWER
- variant and any PowerPC variant. */
+ enum {
+ POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
+ POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
+ };
-#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)
-#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
- | MASK_PPC_GFXOPT | MASK_POWERPC64)
-#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
+ /* This table occasionally claims that a processor does not support
+ a particular feature even though it does, but the feature is slower
+ than the alternative. Thus, it shouldn't be relied on as a
+ complete description of the processor's support.
+ Please keep this list in order, and don't forget to update the
+ documentation in invoke.texi when adding a new processor or
+ flag. */
static struct ptt
{
const char *const name; /* Canonical processor name. */
const enum processor_type processor; /* Processor type enum value. */
const int target_enable; /* Target flags to enable. */
- const int target_disable; /* Target flags to disable. */
} const processor_target_table[]
- = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_MASKS},
- {"power", PROCESSOR_POWER,
- MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"403", PROCESSOR_PPC403,
+ POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
+ {"405", PROCESSOR_PPC405, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"405fp", PROCESSOR_PPC405, POWERPC_BASE_MASK},
+ {"440", PROCESSOR_PPC440, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"440fp", PROCESSOR_PPC440, POWERPC_BASE_MASK},
+ {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
+ {"601", PROCESSOR_PPC601,
+ MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
+ {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"620", PROCESSOR_PPC620,
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
+ {"630", PROCESSOR_PPC630,
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
+ {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
+ {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
+ {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"970", PROCESSOR_POWER4,
+ POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
+ {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
+ {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
+ {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
+ {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
+ {"G5", PROCESSOR_POWER4,
+ POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
+ {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
{"power2", PROCESSOR_POWER,
- MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
- POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
{"power3", PROCESSOR_PPC630,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
{"power4", PROCESSOR_POWER4,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT},
- {"powerpc", PROCESSOR_POWERPC,
- MASK_POWERPC | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
+ {"power5", PROCESSOR_POWER5,
+ POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
+ {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
{"powerpc64", PROCESSOR_POWERPC64,
- MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS},
- {"rios", PROCESSOR_RIOS1,
- MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
- {"rios1", PROCESSOR_RIOS1,
- MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
- {"rsc", PROCESSOR_PPC601,
- MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
- {"rsc1", PROCESSOR_PPC601,
- MASK_POWER | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
+ POWERPC_BASE_MASK | MASK_POWERPC64},
+ {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
+ {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
{"rios2", PROCESSOR_RIOS2,
- MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,
- POWERPC_MASKS | MASK_NEW_MNEMONICS},
- {"rs64a", PROCESSOR_RS64A,
- MASK_POWERPC | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS},
- {"401", PROCESSOR_PPC403,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"403", PROCESSOR_PPC403,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"405", PROCESSOR_PPC405,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"505", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"601", PROCESSOR_PPC601,
- MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,
- MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"602", PROCESSOR_PPC603,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"603", PROCESSOR_PPC603,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"603e", PROCESSOR_PPC603,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"ec603e", PROCESSOR_PPC603,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"604", PROCESSOR_PPC604,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"604e", PROCESSOR_PPC604e,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"620", PROCESSOR_PPC620,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT},
- {"630", PROCESSOR_PPC630,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT},
- {"740", PROCESSOR_PPC750,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"750", PROCESSOR_PPC750,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"7400", PROCESSOR_PPC7400,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"7450", PROCESSOR_PPC7450,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"8540", PROCESSOR_PPC8540,
- MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
- POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
- {"801", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"821", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"823", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
- {"860", PROCESSOR_MPCCORE,
- MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
- POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}};
+ MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
+ {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
+ {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
+ {"rs64a", PROCESSOR_RS64A, POWERPC_BASE_MASK | MASK_POWERPC64},
+ };
const size_t ptt_size = ARRAY_SIZE (processor_target_table);
- /* Save current -mmultiple/-mno-multiple status. */
- int multiple = TARGET_MULTIPLE;
- /* Save current -mstring/-mno-string status. */
- int string = TARGET_STRING;
+ /* Some OSs don't support saving the high part of 64-bit registers on
+ context switch. Other OSs don't support saving Altivec registers.
+ On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
+ settings; if the user wants either, the user must explicitly specify
+ them and we won't interfere with the user's specification. */
+
+ enum {
+ POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
+ POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT
+ | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
+ | MASK_MFCRF)
+ };
+ set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
+#ifdef OS_MISSING_POWERPC64
+ if (OS_MISSING_POWERPC64)
+ set_masks &= ~MASK_POWERPC64;
+#endif
+#ifdef OS_MISSING_ALTIVEC
+ if (OS_MISSING_ALTIVEC)
+ set_masks &= ~MASK_ALTIVEC;
+#endif
+
+ /* Don't override these by the processor default if given explicitly. */
+ set_masks &= ~(target_flags_explicit
+ & (MASK_MULTIPLE | MASK_STRING | MASK_SOFT_FLOAT));
/* Identify the processor type. */
rs6000_select[0].string = default_cpu;
@@ -548,8 +756,9 @@ rs6000_override_options (default_cpu)
if (ptr->set_arch_p)
{
- target_flags |= processor_target_table[j].target_enable;
- target_flags &= ~processor_target_table[j].target_disable;
+ target_flags &= ~set_masks;
+ target_flags |= (processor_target_table[j].target_enable
+ & set_masks);
}
break;
}
@@ -559,23 +768,13 @@ rs6000_override_options (default_cpu)
}
}
- if (rs6000_cpu == PROCESSOR_PPC8540)
+ if (TARGET_E500)
rs6000_isel = 1;
/* If we are optimizing big endian systems for space, use the load/store
multiple and string instructions. */
if (BYTES_BIG_ENDIAN && optimize_size)
- target_flags |= MASK_MULTIPLE | MASK_STRING;
-
- /* If -mmultiple or -mno-multiple was explicitly used, don't
- override with the processor default */
- if (TARGET_MULTIPLE_SET)
- target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;
-
- /* If -mstring or -mno-string was explicitly used, don't override
- with the processor default. */
- if (TARGET_STRING_SET)
- target_flags = (target_flags & ~MASK_STRING) | string;
+ target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
/* Don't allow -mmultiple or -mstring on little endian systems
unless the cpu is a 750, because the hardware doesn't support the
@@ -583,33 +782,23 @@ rs6000_override_options (default_cpu)
trap. The 750 does not cause an alignment trap (except when the
target is unaligned). */
- if (! BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
+ if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
{
if (TARGET_MULTIPLE)
{
target_flags &= ~MASK_MULTIPLE;
- if (TARGET_MULTIPLE_SET)
+ if ((target_flags_explicit & MASK_MULTIPLE) != 0)
warning ("-mmultiple is not supported on little endian systems");
}
if (TARGET_STRING)
{
target_flags &= ~MASK_STRING;
- if (TARGET_STRING_SET)
+ if ((target_flags_explicit & MASK_STRING) != 0)
warning ("-mstring is not supported on little endian systems");
}
}
- if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX)
- {
- rs6000_flag_pic = flag_pic;
- flag_pic = 0;
- }
-
- /* For Darwin, always silently make -fpic and -fPIC identical. */
- if (flag_pic == 1 && DEFAULT_ABI == ABI_DARWIN)
- flag_pic = 2;
-
/* Set debug flags */
if (rs6000_debug_name)
{
@@ -649,14 +838,30 @@ rs6000_override_options (default_cpu)
rs6000_long_double_type_size = size;
}
+ /* Set Altivec ABI as default for powerpc64 linux. */
+ if (TARGET_ELF && TARGET_64BIT)
+ {
+ rs6000_altivec_abi = 1;
+ rs6000_altivec_vrsave = 1;
+ }
+
/* Handle -mabi= options. */
rs6000_parse_abi_options ();
- /* Handle -mvrsave= option. */
- rs6000_parse_vrsave_option ();
+ /* Handle -malign-XXXXX option. */
+ rs6000_parse_alignment_option ();
+
+ /* Handle generic -mFOO=YES/NO options. */
+ rs6000_parse_yes_no_option ("vrsave", rs6000_altivec_vrsave_string,
+ &rs6000_altivec_vrsave);
+ rs6000_parse_yes_no_option ("isel", rs6000_isel_string,
+ &rs6000_isel);
+ rs6000_parse_yes_no_option ("spe", rs6000_spe_string, &rs6000_spe);
+ rs6000_parse_yes_no_option ("float-gprs", rs6000_float_gprs_string,
+ &rs6000_float_gprs);
- /* Handle -misel= option. */
- rs6000_parse_isel_option ();
+ /* Handle -mtls-size option. */
+ rs6000_parse_tls_size_option ();
#ifdef SUBTARGET_OVERRIDE_OPTIONS
SUBTARGET_OVERRIDE_OPTIONS;
@@ -665,6 +870,43 @@ rs6000_override_options (default_cpu)
SUBSUBTARGET_OVERRIDE_OPTIONS;
#endif
+ if (TARGET_E500)
+ {
+ if (TARGET_ALTIVEC)
+ error ("AltiVec and E500 instructions cannot coexist");
+
+ /* The e500 does not have string instructions, and we set
+ MASK_STRING above when optimizing for size. */
+ if ((target_flags & MASK_STRING) != 0)
+ target_flags = target_flags & ~MASK_STRING;
+
+ /* No SPE means 64-bit long doubles, even if an E500. */
+ if (rs6000_spe_string != 0
+ && !strcmp (rs6000_spe_string, "no"))
+ rs6000_long_double_type_size = 64;
+ }
+ else if (rs6000_select[1].string != NULL)
+ {
+ /* For the powerpc-eabispe configuration, we set all these by
+ default, so let's unset them if we manually set another
+ CPU that is not the E500. */
+ if (rs6000_abi_string == 0)
+ rs6000_spe_abi = 0;
+ if (rs6000_spe_string == 0)
+ rs6000_spe = 0;
+ if (rs6000_float_gprs_string == 0)
+ rs6000_float_gprs = 0;
+ if (rs6000_isel_string == 0)
+ rs6000_isel = 0;
+ if (rs6000_long_double_size_string == 0)
+ rs6000_long_double_type_size = 64;
+ }
+
+ rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
+ && rs6000_cpu != PROCESSOR_POWER5);
+ rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
+ || rs6000_cpu == PROCESSOR_POWER5);
+
/* Handle -m(no-)longcall option. This is a bit of a cheap hack,
using TARGET_OPTIONS to handle a toggle switch, but we're out of
bits in target_flags so TARGET_SWITCHES cannot be used.
@@ -681,6 +923,45 @@ rs6000_override_options (default_cpu)
rs6000_default_long_calls = (base[0] != 'n');
}
+ /* Handle -mprioritize-restricted-insns option. */
+ rs6000_sched_restricted_insns_priority
+ = (rs6000_sched_groups ? 1 : 0);
+ if (rs6000_sched_restricted_insns_priority_str)
+ rs6000_sched_restricted_insns_priority =
+ atoi (rs6000_sched_restricted_insns_priority_str);
+
+ /* Handle -msched-costly-dep option. */
+ rs6000_sched_costly_dep
+ = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
+ if (rs6000_sched_costly_dep_str)
+ {
+ if (! strcmp (rs6000_sched_costly_dep_str, "no"))
+ rs6000_sched_costly_dep = no_dep_costly;
+ else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
+ rs6000_sched_costly_dep = all_deps_costly;
+ else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
+ rs6000_sched_costly_dep = true_store_to_load_dep_costly;
+ else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
+ rs6000_sched_costly_dep = store_to_load_dep_costly;
+ else
+ rs6000_sched_costly_dep = atoi (rs6000_sched_costly_dep_str);
+ }
+
+ /* Handle -minsert-sched-nops option. */
+ rs6000_sched_insert_nops
+ = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
+ if (rs6000_sched_insert_nops_str)
+ {
+ if (! strcmp (rs6000_sched_insert_nops_str, "no"))
+ rs6000_sched_insert_nops = sched_finish_none;
+ else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
+ rs6000_sched_insert_nops = sched_finish_pad_groups;
+ else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
+ rs6000_sched_insert_nops = sched_finish_regroup_exact;
+ else
+ rs6000_sched_insert_nops = atoi (rs6000_sched_insert_nops_str);
+ }
+
#ifdef TARGET_REGNAMES
/* If the user desires alternate register names, copy in the
alternate names now. */
@@ -691,7 +972,7 @@ rs6000_override_options (default_cpu)
/* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined.
If -maix-struct-return or -msvr4-struct-return was explicitly
used, don't override with the ABI default. */
- if (!(target_flags & MASK_AIX_STRUCT_RET_SET))
+ if ((target_flags_explicit & MASK_AIX_STRUCT_RET) == 0)
{
if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET)
target_flags = (target_flags & ~MASK_AIX_STRUCT_RET);
@@ -701,10 +982,7 @@ rs6000_override_options (default_cpu)
if (TARGET_LONG_DOUBLE_128
&& (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
- real_format_for_mode[TFmode - QFmode] = &ibm_extended_format;
-
- /* Register global variables with the garbage collector. */
- rs6000_add_gc_roots ();
+ REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
/* Allocate an alias set for register saves & restores from stack. */
rs6000_sr_alias_set = new_alias_set ();
@@ -720,76 +998,119 @@ rs6000_override_options (default_cpu)
targetm.asm_out.unaligned_op.di = NULL;
}
+ /* Set maximum branch target alignment at two instructions, eight bytes. */
+ align_jumps_max_skip = 8;
+ align_loops_max_skip = 8;
+
/* Arrange to save and restore machine status around nested functions. */
init_machine_status = rs6000_init_machine_status;
+
+ /* We should always be splitting complex arguments, but we can't break
+ Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
+ if (DEFAULT_ABI != ABI_AIX)
+ targetm.calls.split_complex_arg = NULL;
}
-/* Handle -misel= option. */
+/* Handle generic options of the form -mfoo=yes/no.
+ NAME is the option name.
+ VALUE is the option value.
+ FLAG is the pointer to the flag where to store a 1 or 0, depending on
+ whether the option value is 'yes' or 'no' respectively. */
static void
-rs6000_parse_isel_option ()
+rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
{
- if (rs6000_isel_string == 0)
+ if (value == 0)
return;
- else if (! strcmp (rs6000_isel_string, "yes"))
- rs6000_isel = 1;
- else if (! strcmp (rs6000_isel_string, "no"))
- rs6000_isel = 0;
+ else if (!strcmp (value, "yes"))
+ *flag = 1;
+ else if (!strcmp (value, "no"))
+ *flag = 0;
else
- error ("unknown -misel= option specified: '%s'",
- rs6000_isel_string);
-}
-
-/* Handle -mvrsave= options. */
-static void
-rs6000_parse_vrsave_option ()
-{
- /* Generate VRSAVE instructions by default. */
- if (rs6000_altivec_vrsave_string == 0
- || ! strcmp (rs6000_altivec_vrsave_string, "yes"))
- rs6000_altivec_vrsave = 1;
- else if (! strcmp (rs6000_altivec_vrsave_string, "no"))
- rs6000_altivec_vrsave = 0;
- else
- error ("unknown -mvrsave= option specified: '%s'",
- rs6000_altivec_vrsave_string);
+ error ("unknown -m%s= option specified: '%s'", name, value);
}
/* Handle -mabi= options. */
static void
-rs6000_parse_abi_options ()
+rs6000_parse_abi_options (void)
{
if (rs6000_abi_string == 0)
return;
else if (! strcmp (rs6000_abi_string, "altivec"))
- rs6000_altivec_abi = 1;
+ {
+ rs6000_altivec_abi = 1;
+ rs6000_spe_abi = 0;
+ }
else if (! strcmp (rs6000_abi_string, "no-altivec"))
rs6000_altivec_abi = 0;
else if (! strcmp (rs6000_abi_string, "spe"))
- rs6000_spe_abi = 1;
+ {
+ rs6000_spe_abi = 1;
+ rs6000_altivec_abi = 0;
+ if (!TARGET_SPE_ABI)
+ error ("not configured for ABI: '%s'", rs6000_abi_string);
+ }
+
else if (! strcmp (rs6000_abi_string, "no-spe"))
rs6000_spe_abi = 0;
else
error ("unknown ABI specified: '%s'", rs6000_abi_string);
}
+/* Handle -malign-XXXXXX options. */
+static void
+rs6000_parse_alignment_option (void)
+{
+ if (rs6000_alignment_string == 0)
+ return;
+ else if (! strcmp (rs6000_alignment_string, "power"))
+ rs6000_alignment_flags = MASK_ALIGN_POWER;
+ else if (! strcmp (rs6000_alignment_string, "natural"))
+ rs6000_alignment_flags = MASK_ALIGN_NATURAL;
+ else
+ error ("unknown -malign-XXXXX option specified: '%s'",
+ rs6000_alignment_string);
+}
+
+/* Validate and record the size specified with the -mtls-size option. */
+
+static void
+rs6000_parse_tls_size_option (void)
+{
+ if (rs6000_tls_size_string == 0)
+ return;
+ else if (strcmp (rs6000_tls_size_string, "16") == 0)
+ rs6000_tls_size = 16;
+ else if (strcmp (rs6000_tls_size_string, "32") == 0)
+ rs6000_tls_size = 32;
+ else if (strcmp (rs6000_tls_size_string, "64") == 0)
+ rs6000_tls_size = 64;
+ else
+ error ("bad value `%s' for -mtls-size switch", rs6000_tls_size_string);
+}
+
void
-optimization_options (level, size)
- int level ATTRIBUTE_UNUSED;
- int size ATTRIBUTE_UNUSED;
+optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
{
}
/* Do anything needed at the start of the asm file. */
-void
-rs6000_file_start (file, default_cpu)
- FILE *file;
- const char *default_cpu;
+static void
+rs6000_file_start (void)
{
size_t i;
char buffer[80];
const char *start = buffer;
struct rs6000_cpu_select *ptr;
+ const char *default_cpu = TARGET_CPU_DEFAULT;
+ FILE *file = asm_out_file;
+
+ default_file_start ();
+
+#ifdef TARGET_BI_ARCH
+ if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
+ default_cpu = 0;
+#endif
if (flag_verbose_asm)
{
@@ -817,7 +1138,8 @@ rs6000_file_start (file, default_cpu)
if (rs6000_sdata && g_switch_value)
{
- fprintf (file, "%s -G %d", start, g_switch_value);
+ fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
+ g_switch_value);
start = "";
}
#endif
@@ -830,7 +1152,7 @@ rs6000_file_start (file, default_cpu)
/* Return nonzero if this function is known to have a null epilogue. */
int
-direct_return ()
+direct_return (void)
{
if (reload_completed)
{
@@ -852,18 +1174,15 @@ direct_return ()
/* Returns 1 always. */
int
-any_operand (op, mode)
- rtx op ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+any_operand (rtx op ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
return 1;
}
/* Returns 1 if op is the count register. */
int
-count_register_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+count_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != REG)
return 0;
@@ -879,9 +1198,7 @@ count_register_operand (op, mode)
/* Returns 1 if op is an altivec register. */
int
-altivec_register_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+altivec_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (register_operand (op, mode)
@@ -891,9 +1208,7 @@ altivec_register_operand (op, mode)
}
int
-xer_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+xer_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != REG)
return 0;
@@ -908,9 +1223,7 @@ xer_operand (op, mode)
by such constants completes more quickly. */
int
-s8bit_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+s8bit_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return ( GET_CODE (op) == CONST_INT
&& (INTVAL (op) >= -128 && INTVAL (op) <= 127));
@@ -919,9 +1232,7 @@ s8bit_cint_operand (op, mode)
/* Return 1 if OP is a constant that can fit in a D field. */
int
-short_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+short_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
@@ -930,9 +1241,7 @@ short_cint_operand (op, mode)
/* Similar for an unsigned D field. */
int
-u_short_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+u_short_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& CONST_OK_FOR_LETTER_P (INTVAL (op) & GET_MODE_MASK (mode), 'K'));
@@ -941,9 +1250,7 @@ u_short_cint_operand (op, mode)
/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
int
-non_short_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+non_short_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
@@ -953,9 +1260,7 @@ non_short_cint_operand (op, mode)
and an exact power of 2. */
int
-exact_log2_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+exact_log2_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& INTVAL (op) > 0
@@ -966,9 +1271,7 @@ exact_log2_cint_operand (op, mode)
ctr, or lr). */
int
-gpc_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+gpc_reg_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
&& (GET_CODE (op) != REG
@@ -981,9 +1284,7 @@ gpc_reg_operand (op, mode)
CR field. */
int
-cc_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+cc_reg_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
&& (GET_CODE (op) != REG
@@ -995,9 +1296,7 @@ cc_reg_operand (op, mode)
CR field that isn't CR0. */
int
-cc_reg_not_cr0_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+cc_reg_not_cr0_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
&& (GET_CODE (op) != REG
@@ -1010,23 +1309,22 @@ cc_reg_not_cr0_operand (op, mode)
mode unless MODE is VOIDmode. */
int
-reg_or_short_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_short_operand (rtx op, enum machine_mode mode)
{
return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
}
/* Similar, except check if the negation of the constant would be
- valid for a D-field. */
+ valid for a D-field. Don't allow a constant zero, since all the
+ patterns that call this predicate use "addic r1,r2,-constant" on
+ a constant value to set a carry when r2 is greater or equal to
+ "constant". That doesn't work for zero. */
int
-reg_or_neg_short_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_neg_short_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
- return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
+ return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P') && INTVAL (op) != 0;
return gpc_reg_operand (op, mode);
}
@@ -1036,9 +1334,7 @@ reg_or_neg_short_operand (op, mode)
mode unless MODE is VOIDmode. */
int
-reg_or_aligned_short_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_aligned_short_operand (rtx op, enum machine_mode mode)
{
if (gpc_reg_operand (op, mode))
return 1;
@@ -1053,9 +1349,7 @@ reg_or_aligned_short_operand (op, mode)
high-order 16 bits are zero. */
int
-reg_or_u_short_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_u_short_operand (rtx op, enum machine_mode mode)
{
return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
}
@@ -1064,9 +1358,7 @@ reg_or_u_short_operand (op, mode)
constant integer. */
int
-reg_or_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_cint_operand (rtx op, enum machine_mode mode)
{
return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));
}
@@ -1075,9 +1367,7 @@ reg_or_cint_operand (op, mode)
32-bit signed constant integer. */
int
-reg_or_arith_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_arith_cint_operand (rtx op, enum machine_mode mode)
{
return (gpc_reg_operand (op, mode)
|| (GET_CODE (op) == CONST_INT
@@ -1092,9 +1382,7 @@ reg_or_arith_cint_operand (op, mode)
signed constant integer valid for 64-bit addition. */
int
-reg_or_add_cint64_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_add_cint64_operand (rtx op, enum machine_mode mode)
{
return (gpc_reg_operand (op, mode)
|| (GET_CODE (op) == CONST_INT
@@ -1111,9 +1399,7 @@ reg_or_add_cint64_operand (op, mode)
signed constant integer valid for 64-bit subtraction. */
int
-reg_or_sub_cint64_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_sub_cint64_operand (rtx op, enum machine_mode mode)
{
return (gpc_reg_operand (op, mode)
|| (GET_CODE (op) == CONST_INT
@@ -1130,9 +1416,7 @@ reg_or_sub_cint64_operand (op, mode)
32-bit unsigned constant integer. */
int
-reg_or_logical_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_logical_cint_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
{
@@ -1163,9 +1447,7 @@ reg_or_logical_cint_operand (op, mode)
/* Return 1 if the operand is an operand that can be loaded via the GOT. */
int
-got_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+got_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == SYMBOL_REF
|| GET_CODE (op) == CONST
@@ -1176,9 +1458,7 @@ got_operand (op, mode)
the GOT (labels involving addition aren't allowed). */
int
-got_no_const_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+got_no_const_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
}
@@ -1187,8 +1467,7 @@ got_no_const_operand (op, mode)
integer register. */
static int
-num_insns_constant_wide (value)
- HOST_WIDE_INT value;
+num_insns_constant_wide (HOST_WIDE_INT value)
{
/* signed constant loadable with {cal|addi} */
if (CONST_OK_FOR_LETTER_P (value, 'I'))
@@ -1222,9 +1501,7 @@ num_insns_constant_wide (value)
}
int
-num_insns_constant (op, mode)
- rtx op;
- enum machine_mode mode;
+num_insns_constant (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
{
@@ -1301,9 +1578,7 @@ num_insns_constant (op, mode)
safely read CONST_DOUBLE_{LOW,HIGH}. */
int
-easy_fp_constant (op, mode)
- rtx op;
- enum machine_mode mode;
+easy_fp_constant (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != CONST_DOUBLE
|| GET_MODE (op) != mode
@@ -1374,65 +1649,228 @@ easy_fp_constant (op, mode)
abort ();
}
-/* Return 1 if the operand is a CONST_INT and can be put into a
- register with one instruction. */
+/* Returns the constant for the splat instrunction, if exists. */
static int
-easy_vector_constant (op)
- rtx op;
+easy_vector_splat_const (int cst, enum machine_mode mode)
{
- rtx elt;
- int units, i;
+ switch (mode)
+ {
+ case V4SImode:
+ if (EASY_VECTOR_15 (cst)
+ || EASY_VECTOR_15_ADD_SELF (cst))
+ return cst;
+ if ((cst & 0xffff) != ((cst >> 16) & 0xffff))
+ break;
+ cst = cst >> 16;
+ case V8HImode:
+ if (EASY_VECTOR_15 (cst)
+ || EASY_VECTOR_15_ADD_SELF (cst))
+ return cst;
+ if ((cst & 0xff) != ((cst >> 8) & 0xff))
+ break;
+ cst = cst >> 8;
+ case V16QImode:
+ if (EASY_VECTOR_15 (cst)
+ || EASY_VECTOR_15_ADD_SELF (cst))
+ return cst;
+ default:
+ break;
+ }
+ return 0;
+}
- if (GET_CODE (op) != CONST_VECTOR)
- return 0;
+
+/* Return nonzero if all elements of a vector have the same value. */
+
+static int
+easy_vector_same (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ int units, i, cst;
units = CONST_VECTOR_NUNITS (op);
- /* We can generate 0 easily. Look for that. */
- for (i = 0; i < units; ++i)
+ cst = INTVAL (CONST_VECTOR_ELT (op, 0));
+ for (i = 1; i < units; ++i)
+ if (INTVAL (CONST_VECTOR_ELT (op, i)) != cst)
+ break;
+ if (i == units && easy_vector_splat_const (cst, mode))
+ return 1;
+ return 0;
+}
+
+/* Return 1 if the operand is a CONST_INT and can be put into a
+ register without using memory. */
+
+int
+easy_vector_constant (rtx op, enum machine_mode mode)
+{
+ int cst, cst2;
+
+ if (GET_CODE (op) != CONST_VECTOR
+ || (!TARGET_ALTIVEC
+ && !TARGET_SPE))
+ return 0;
+
+ if (zero_constant (op, mode)
+ && ((TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
+ || (TARGET_SPE && SPE_VECTOR_MODE (mode))))
+ return 1;
+
+ if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
+ return 0;
+
+ if (TARGET_SPE && mode == V1DImode)
+ return 0;
+
+ cst = INTVAL (CONST_VECTOR_ELT (op, 0));
+ cst2 = INTVAL (CONST_VECTOR_ELT (op, 1));
+
+ /* Limit SPE vectors to 15 bits signed. These we can generate with:
+ li r0, CONSTANT1
+ evmergelo r0, r0, r0
+ li r0, CONSTANT2
+
+ I don't know how efficient it would be to allow bigger constants,
+ considering we'll have an extra 'ori' for every 'li'. I doubt 5
+ instructions is better than a 64-bit memory load, but I don't
+ have the e500 timing specs. */
+ if (TARGET_SPE && mode == V2SImode
+ && cst >= -0x7fff && cst <= 0x7fff
+ && cst2 >= -0x7fff && cst2 <= 0x7fff)
+ return 1;
+
+ if (TARGET_ALTIVEC
+ && easy_vector_same (op, mode))
{
- elt = CONST_VECTOR_ELT (op, i);
+ cst = easy_vector_splat_const (cst, mode);
+ if (EASY_VECTOR_15_ADD_SELF (cst)
+ || EASY_VECTOR_15 (cst))
+ return 1;
+ }
+ return 0;
+}
+
+/* Same as easy_vector_constant but only for EASY_VECTOR_15_ADD_SELF. */
- /* We could probably simplify this by just checking for equality
- with CONST0_RTX for the current mode, but let's be safe
- instead. */
+int
+easy_vector_constant_add_self (rtx op, enum machine_mode mode)
+{
+ int cst;
+ if (TARGET_ALTIVEC
+ && GET_CODE (op) == CONST_VECTOR
+ && easy_vector_same (op, mode))
+ {
+ cst = easy_vector_splat_const (INTVAL (CONST_VECTOR_ELT (op, 0)), mode);
+ if (EASY_VECTOR_15_ADD_SELF (cst))
+ return 1;
+ }
+ return 0;
+}
+
+/* Generate easy_vector_constant out of a easy_vector_constant_add_self. */
+
+rtx
+gen_easy_vector_constant_add_self (rtx op)
+{
+ int i, units;
+ rtvec v;
+ units = GET_MODE_NUNITS (GET_MODE (op));
+ v = rtvec_alloc (units);
+
+ for (i = 0; i < units; i++)
+ RTVEC_ELT (v, i) =
+ GEN_INT (INTVAL (CONST_VECTOR_ELT (op, i)) >> 1);
+ return gen_rtx_raw_CONST_VECTOR (GET_MODE (op), v);
+}
+
+const char *
+output_vec_const_move (rtx *operands)
+{
+ int cst, cst2;
+ enum machine_mode mode;
+ rtx dest, vec;
- switch (GET_CODE (elt))
+ dest = operands[0];
+ vec = operands[1];
+
+ cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
+ cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
+ mode = GET_MODE (dest);
+
+ if (TARGET_ALTIVEC)
+ {
+ if (zero_constant (vec, mode))
+ return "vxor %0,%0,%0";
+ else if (easy_vector_constant (vec, mode))
{
- case CONST_INT:
- if (INTVAL (elt) != 0)
- return 0;
- break;
- case CONST_DOUBLE:
- if (CONST_DOUBLE_LOW (elt) != 0 || CONST_DOUBLE_HIGH (elt) != 0)
- return 0;
- break;
- default:
- return 0;
+ operands[1] = GEN_INT (cst);
+ switch (mode)
+ {
+ case V4SImode:
+ if (EASY_VECTOR_15 (cst))
+ {
+ operands[1] = GEN_INT (cst);
+ return "vspltisw %0,%1";
+ }
+ else if (EASY_VECTOR_15_ADD_SELF (cst))
+ return "#";
+ cst = cst >> 16;
+ case V8HImode:
+ if (EASY_VECTOR_15 (cst))
+ {
+ operands[1] = GEN_INT (cst);
+ return "vspltish %0,%1";
+ }
+ else if (EASY_VECTOR_15_ADD_SELF (cst))
+ return "#";
+ cst = cst >> 8;
+ case V16QImode:
+ if (EASY_VECTOR_15 (cst))
+ {
+ operands[1] = GEN_INT (cst);
+ return "vspltisb %0,%1";
+ }
+ else if (EASY_VECTOR_15_ADD_SELF (cst))
+ return "#";
+ default:
+ abort ();
+ }
}
+ else
+ abort ();
}
- /* We could probably generate a few other constants trivially, but
- gcc doesn't generate them yet. FIXME later. */
- return 1;
+ if (TARGET_SPE)
+ {
+ /* Vector constant 0 is handled as a splitter of V2SI, and in the
+ pattern of V1DI, V4HI, and V2SF.
+
+ FIXME: We should probably return # and add post reload
+ splitters for these, but this way is so easy ;-).
+ */
+ operands[1] = GEN_INT (cst);
+ operands[2] = GEN_INT (cst2);
+ if (cst == cst2)
+ return "li %0,%1\n\tevmergelo %0,%0,%0";
+ else
+ return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
+ }
+
+ abort ();
}
/* Return 1 if the operand is the constant 0. This works for scalars
as well as vectors. */
int
-zero_constant (op, mode)
- rtx op;
- enum machine_mode mode;
+zero_constant (rtx op, enum machine_mode mode)
{
return op == CONST0_RTX (mode);
}
/* Return 1 if the operand is 0.0. */
int
-zero_fp_constant (op, mode)
- rtx op;
- enum machine_mode mode;
+zero_fp_constant (rtx op, enum machine_mode mode)
{
return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
}
@@ -1443,9 +1881,7 @@ zero_fp_constant (op, mode)
recognize volatile references where its safe. */
int
-volatile_mem_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+volatile_mem_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != MEM)
return 0;
@@ -1468,9 +1904,7 @@ volatile_mem_operand (op, mode)
/* Return 1 if the operand is an offsettable memory operand. */
int
-offsettable_mem_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+offsettable_mem_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == MEM)
&& offsettable_address_p (reload_completed || reload_in_progress,
@@ -1481,9 +1915,7 @@ offsettable_mem_operand (op, mode)
memory. */
int
-mem_or_easy_const_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+mem_or_easy_const_operand (rtx op, enum machine_mode mode)
{
return memory_operand (op, mode) || easy_fp_constant (op, mode);
}
@@ -1492,9 +1924,7 @@ mem_or_easy_const_operand (op, mode)
that can be used as the operand of a `mode' add insn. */
int
-add_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+add_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == CONST_INT)
return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
@@ -1506,9 +1936,7 @@ add_operand (op, mode)
/* Return 1 if OP is a constant but not a valid add_operand. */
int
-non_add_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+non_add_cint_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
@@ -1519,9 +1947,7 @@ non_add_cint_operand (op, mode)
can be used as the operand of an OR or XOR insn on the RS/6000. */
int
-logical_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+logical_operand (rtx op, enum machine_mode mode)
{
HOST_WIDE_INT opl, oph;
@@ -1558,9 +1984,7 @@ logical_operand (op, mode)
above), but could be split into one. */
int
-non_logical_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+non_logical_cint_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
&& ! logical_operand (op, mode)
@@ -1573,9 +1997,7 @@ non_logical_cint_operand (op, mode)
away and confuse the making of MB and ME. */
int
-mask_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mask_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT c, lsb;
@@ -1617,9 +2039,7 @@ mask_operand (op, mode)
/* Return 1 for the PowerPC64 rlwinm corner case. */
int
-mask_operand_wrap (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mask_operand_wrap (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT c, lsb;
@@ -1648,9 +2068,7 @@ mask_operand_wrap (op, mode)
confuses the making of MB and ME. */
int
-mask64_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mask64_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == CONST_INT)
{
@@ -1669,6 +2087,8 @@ mask64_operand (op, mode)
/* Find the transition, and check that all bits above are 1's. */
lsb = c & -c;
+
+ /* Match if all the bits above are 1's (or c is zero). */
return c == -lsb;
}
return 0;
@@ -1679,9 +2099,7 @@ mask64_operand (op, mode)
rldicr machine insns. */
int
-mask64_2_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mask64_2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == CONST_INT)
{
@@ -1728,9 +2146,7 @@ mask64_2_operand (op, mode)
/* Generates shifts and masks for a pair of rldicl or rldicr insns to
implement ANDing by the mask IN. */
void
-build_mask64_2_operands (in, out)
- rtx in;
- rtx *out;
+build_mask64_2_operands (rtx in, rtx *out)
{
#if HOST_BITS_PER_WIDE_INT >= 64
unsigned HOST_WIDE_INT c, lsb, m1, m2;
@@ -1801,9 +2217,7 @@ build_mask64_2_operands (in, out)
that can be used as the operand of a PowerPC64 logical AND insn. */
int
-and64_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+and64_operand (rtx op, enum machine_mode mode)
{
if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
@@ -1815,11 +2229,9 @@ and64_operand (op, mode)
with two rldicl or rldicr insns. */
int
-and64_2_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+and64_2_operand (rtx op, enum machine_mode mode)
{
- if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
+ if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
return logical_operand (op, mode) || mask64_2_operand (op, mode);
@@ -1829,9 +2241,7 @@ and64_2_operand (op, mode)
constant that can be used as the operand of an RS/6000 logical AND insn. */
int
-and_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+and_operand (rtx op, enum machine_mode mode)
{
if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
@@ -1842,12 +2252,11 @@ and_operand (op, mode)
/* Return 1 if the operand is a general register or memory operand. */
int
-reg_or_mem_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_mem_operand (rtx op, enum machine_mode mode)
{
return (gpc_reg_operand (op, mode)
|| memory_operand (op, mode)
+ || macho_lo_sum_memory_operand (op, mode)
|| volatile_mem_operand (op, mode));
}
@@ -1856,9 +2265,7 @@ reg_or_mem_operand (op, mode)
instruction. */
int
-lwa_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+lwa_operand (rtx op, enum machine_mode mode)
{
rtx inner = op;
@@ -1877,23 +2284,20 @@ lwa_operand (op, mode)
/* Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. */
int
-symbol_ref_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+symbol_ref_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
- return (GET_CODE (op) == SYMBOL_REF);
+ return (GET_CODE (op) == SYMBOL_REF
+ && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op)));
}
/* Return 1 if the operand, used inside a MEM, is a valid first argument
to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. */
int
-call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+call_operand (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && GET_MODE (op) != mode)
return 0;
@@ -1906,25 +2310,22 @@ call_operand (op, mode)
}
/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
- this file and the function is not weakly defined. */
+ this file. */
int
-current_file_function_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+current_file_function_operand (rtx op,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == SYMBOL_REF
- && (SYMBOL_REF_FLAG (op)
- || (op == XEXP (DECL_RTL (current_function_decl), 0)
- && ! DECL_WEAK (current_function_decl))));
+ && (DEFAULT_ABI != ABI_AIX || SYMBOL_REF_FUNCTION_P (op))
+ && (SYMBOL_REF_LOCAL_P (op)
+ || (op == XEXP (DECL_RTL (current_function_decl), 0))));
}
/* Return 1 if this operand is a valid input for a move insn. */
int
-input_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+input_operand (rtx op, enum machine_mode mode)
{
/* Memory is always valid. */
if (memory_operand (op, mode))
@@ -1946,6 +2347,11 @@ input_operand (op, mode)
|| GET_CODE (op) == CONST_DOUBLE))
return 1;
+ /* Allow easy vector constants. */
+ if (GET_CODE (op) == CONST_VECTOR
+ && easy_vector_constant (op, mode))
+ return 1;
+
/* For floating-point or multi-word mode, the only remaining valid type
is a register. */
if (GET_MODE_CLASS (mode) == MODE_FLOAT
@@ -1959,11 +2365,11 @@ input_operand (op, mode)
return 1;
/* A SYMBOL_REF referring to the TOC is valid. */
- if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
+ if (legitimate_constant_pool_address_p (op))
return 1;
/* A constant pool expression (relative to the TOC) is valid */
- if (TOC_RELATIVE_EXPR_P (op))
+ if (toc_relative_expr_p (op))
return 1;
/* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
@@ -1976,12 +2382,31 @@ input_operand (op, mode)
return 0;
}
+
+/* Darwin, AIX increases natural record alignment to doubleword if the first
+ field is an FP double while the FP fields remain word aligned. */
+
+unsigned int
+rs6000_special_round_type_align (tree type, int computed, int specified)
+{
+ tree field = TYPE_FIELDS (type);
+
+ /* Skip all the static variables only if ABI is greater than
+ 1 or equal to 0. */
+ while (field != NULL && TREE_CODE (field) == VAR_DECL)
+ field = TREE_CHAIN (field);
+
+ if (field == NULL || field == type || DECL_MODE (field) != DFmode)
+ return MAX (computed, specified);
+
+ return MAX (MAX (computed, specified), 64);
+}
+
/* Return 1 for an operand in small memory on V.4/eabi. */
int
-small_data_operand (op, mode)
- rtx op ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+small_data_operand (rtx op ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
#if TARGET_ELF
rtx sym_ref;
@@ -2009,32 +2434,97 @@ small_data_operand (op, mode)
/* We have to be careful here, because it is the referenced address
that must be 32k from _SDA_BASE_, not just the symbol. */
summand = INTVAL (XEXP (sum, 1));
- if (summand < 0 || summand > g_switch_value)
+ if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
return 0;
sym_ref = XEXP (sum, 0);
}
- if (*XSTR (sym_ref, 0) != '@')
- return 0;
-
- return 1;
-
+ return SYMBOL_REF_SMALL_P (sym_ref);
#else
return 0;
#endif
}
+
+/* Return true, if operand is a memory operand and has a
+ displacement divisible by 4. */
+
+int
+word_offset_memref_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ rtx addr;
+ int off = 0;
+
+ if (!memory_operand (op, mode))
+ return 0;
+
+ addr = XEXP (op, 0);
+ if (GET_CODE (addr) == PLUS
+ && GET_CODE (XEXP (addr, 0)) == REG
+ && GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ off = INTVAL (XEXP (addr, 1));
+
+ return (off % 4) == 0;
+}
+
+/* Return true if operand is a (MEM (PLUS (REG) (offset))) where offset
+ is not divisible by four. */
+
+int
+invalid_gpr_mem (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ rtx addr;
+ long off;
+
+ if (GET_CODE (op) != MEM)
+ return 0;
+
+ addr = XEXP (op, 0);
+ if (GET_CODE (addr) != PLUS
+ || GET_CODE (XEXP (addr, 0)) != REG
+ || GET_CODE (XEXP (addr, 1)) != CONST_INT)
+ return 0;
+
+ off = INTVAL (XEXP (addr, 1));
+ return (off & 3) != 0;
+}
+
+/* Return true if operand is a hard register that can be used as a base
+ register. */
+
+int
+base_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ unsigned int regno;
+
+ if (!REG_P (op))
+ return 0;
+
+ regno = REGNO (op);
+ return regno != 0 && regno <= 31;
+}
+
+/* Return true if either operand is a general purpose register. */
+
+bool
+gpr_or_gpr_p (rtx op0, rtx op1)
+{
+ return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
+ || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
+}
+
+/* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
+
static int
-constant_pool_expr_1 (op, have_sym, have_toc)
- rtx op;
- int *have_sym;
- int *have_toc;
+constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
{
switch (GET_CODE(op))
{
case SYMBOL_REF:
- if (CONSTANT_POOL_ADDRESS_P (op))
+ if (RS6000_SYMBOL_REF_TLS_P (op))
+ return 0;
+ else if (CONSTANT_POOL_ADDRESS_P (op))
{
if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
{
@@ -2064,24 +2554,176 @@ constant_pool_expr_1 (op, have_sym, have_toc)
}
}
-int
-constant_pool_expr_p (op)
- rtx op;
+static bool
+constant_pool_expr_p (rtx op)
{
int have_sym = 0;
int have_toc = 0;
return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
}
-int
-toc_relative_expr_p (op)
- rtx op;
+static bool
+toc_relative_expr_p (rtx op)
+{
+ int have_sym = 0;
+ int have_toc = 0;
+ return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
+}
+
+/* SPE offset addressing is limited to 5-bits worth of double words. */
+#define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
+
+bool
+legitimate_constant_pool_address_p (rtx x)
+{
+ return (TARGET_TOC
+ && GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 0)) == REG
+ && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
+ && constant_pool_expr_p (XEXP (x, 1)));
+}
+
+static bool
+legitimate_small_data_p (enum machine_mode mode, rtx x)
+{
+ return (DEFAULT_ABI == ABI_V4
+ && !flag_pic && !TARGET_TOC
+ && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
+ && small_data_operand (x, mode));
+}
+
+static bool
+legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
+{
+ unsigned HOST_WIDE_INT offset, extra;
+
+ if (GET_CODE (x) != PLUS)
+ return false;
+ if (GET_CODE (XEXP (x, 0)) != REG)
+ return false;
+ if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
+ return false;
+ if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+ return false;
+
+ offset = INTVAL (XEXP (x, 1));
+ extra = 0;
+ switch (mode)
+ {
+ case V16QImode:
+ case V8HImode:
+ case V4SFmode:
+ case V4SImode:
+ /* AltiVec vector modes. Only reg+reg addressing is valid here,
+ which leaves the only valid constant offset of zero, which by
+ canonicalization rules is also invalid. */
+ return false;
+
+ case V4HImode:
+ case V2SImode:
+ case V1DImode:
+ case V2SFmode:
+ /* SPE vector modes. */
+ return SPE_CONST_OFFSET_OK (offset);
+
+ case DFmode:
+ case DImode:
+ /* Both DFmode and DImode may end up in gprs. If gprs are 32-bit,
+ then we need to load/store at both offset and offset+4. */
+ if (!TARGET_POWERPC64)
+ extra = 4;
+ break;
+
+ case TFmode:
+ case TImode:
+ if (!TARGET_POWERPC64)
+ extra = 12;
+ else
+ extra = 8;
+ break;
+
+ default:
+ break;
+ }
+
+ offset += 0x8000;
+ return (offset < 0x10000) && (offset + extra < 0x10000);
+}
+
+static bool
+legitimate_indexed_address_p (rtx x, int strict)
{
- int have_sym = 0;
- int have_toc = 0;
- return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
+ rtx op0, op1;
+
+ if (GET_CODE (x) != PLUS)
+ return false;
+ op0 = XEXP (x, 0);
+ op1 = XEXP (x, 1);
+
+ if (!REG_P (op0) || !REG_P (op1))
+ return false;
+
+ return ((INT_REG_OK_FOR_BASE_P (op0, strict)
+ && INT_REG_OK_FOR_INDEX_P (op1, strict))
+ || (INT_REG_OK_FOR_BASE_P (op1, strict)
+ && INT_REG_OK_FOR_INDEX_P (op0, strict)));
}
+static inline bool
+legitimate_indirect_address_p (rtx x, int strict)
+{
+ return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
+}
+
+static bool
+macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
+{
+ if (!TARGET_MACHO || !flag_pic
+ || mode != SImode || GET_CODE(x) != MEM)
+ return false;
+ x = XEXP (x, 0);
+
+ if (GET_CODE (x) != LO_SUM)
+ return false;
+ if (GET_CODE (XEXP (x, 0)) != REG)
+ return false;
+ if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
+ return false;
+ x = XEXP (x, 1);
+
+ return CONSTANT_P (x);
+}
+
+static bool
+legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
+{
+ if (GET_CODE (x) != LO_SUM)
+ return false;
+ if (GET_CODE (XEXP (x, 0)) != REG)
+ return false;
+ if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
+ return false;
+ x = XEXP (x, 1);
+
+ if (TARGET_ELF || TARGET_MACHO)
+ {
+ if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
+ return false;
+ if (TARGET_TOC)
+ return false;
+ if (GET_MODE_NUNITS (mode) != 1)
+ return false;
+ if (GET_MODE_BITSIZE (mode) > 32
+ && !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode))
+ return false;
+
+ return CONSTANT_P (x);
+ }
+
+ return false;
+}
+
+
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address.
This is used from only one place: `memory_address' in explow.c.
@@ -2104,12 +2746,18 @@ toc_relative_expr_p (op)
Then check for the sum of a register and something not constant, try to
load the other things into a register and return the sum. */
+
rtx
-rs6000_legitimize_address (x, oldx, mode)
- rtx x;
- rtx oldx ATTRIBUTE_UNUSED;
- enum machine_mode mode;
+rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode)
{
+ if (GET_CODE (x) == SYMBOL_REF)
+ {
+ enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
+ if (model != 0)
+ return rs6000_legitimize_tls_address (x, model);
+ }
+
if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
&& GET_CODE (XEXP (x, 1)) == CONST_INT
@@ -2169,7 +2817,10 @@ rs6000_legitimize_address (x, oldx, mode)
return force_reg (Pmode, x);
}
- else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
+ else if (TARGET_ELF
+ && TARGET_32BIT
+ && TARGET_NO_TOC
+ && ! flag_pic
&& GET_CODE (x) != CONST_INT
&& GET_CODE (x) != CONST_DOUBLE
&& CONSTANT_P (x)
@@ -2178,11 +2829,14 @@ rs6000_legitimize_address (x, oldx, mode)
|| ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
{
rtx reg = gen_reg_rtx (Pmode);
- emit_insn (gen_elf_high (reg, (x)));
- return gen_rtx_LO_SUM (Pmode, reg, (x));
+ emit_insn (gen_elf_high (reg, x));
+ return gen_rtx_LO_SUM (Pmode, reg, x);
}
else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
&& ! flag_pic
+#if TARGET_MACHO
+ && ! MACHO_DYNAMIC_NO_PIC_P
+#endif
&& GET_CODE (x) != CONST_INT
&& GET_CODE (x) != CONST_DOUBLE
&& CONSTANT_P (x)
@@ -2191,11 +2845,11 @@ rs6000_legitimize_address (x, oldx, mode)
&& mode != TImode)
{
rtx reg = gen_reg_rtx (Pmode);
- emit_insn (gen_macho_high (reg, (x)));
- return gen_rtx_LO_SUM (Pmode, reg, (x));
+ emit_insn (gen_macho_high (reg, x));
+ return gen_rtx_LO_SUM (Pmode, reg, x);
}
else if (TARGET_TOC
- && CONSTANT_POOL_EXPR_P (x)
+ && constant_pool_expr_p (x)
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
{
return create_TOC_reference (x);
@@ -2204,6 +2858,270 @@ rs6000_legitimize_address (x, oldx, mode)
return NULL_RTX;
}
+/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
+ We need to emit DTP-relative relocations. */
+
+void
+rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
+{
+ switch (size)
+ {
+ case 4:
+ fputs ("\t.long\t", file);
+ break;
+ case 8:
+ fputs (DOUBLE_INT_ASM_OP, file);
+ break;
+ default:
+ abort ();
+ }
+ output_addr_const (file, x);
+ fputs ("@dtprel+0x8000", file);
+}
+
+/* Construct the SYMBOL_REF for the tls_get_addr function. */
+
+static GTY(()) rtx rs6000_tls_symbol;
+static rtx
+rs6000_tls_get_addr (void)
+{
+ if (!rs6000_tls_symbol)
+ rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
+
+ return rs6000_tls_symbol;
+}
+
+/* Construct the SYMBOL_REF for TLS GOT references. */
+
+static GTY(()) rtx rs6000_got_symbol;
+static rtx
+rs6000_got_sym (void)
+{
+ if (!rs6000_got_symbol)
+ {
+ rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+ SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
+ SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
+ }
+
+ return rs6000_got_symbol;
+}
+
+/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
+ this (thread-local) address. */
+
+static rtx
+rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
+{
+ rtx dest, insn;
+
+ dest = gen_reg_rtx (Pmode);
+ if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
+ {
+ rtx tlsreg;
+
+ if (TARGET_64BIT)
+ {
+ tlsreg = gen_rtx_REG (Pmode, 13);
+ insn = gen_tls_tprel_64 (dest, tlsreg, addr);
+ }
+ else
+ {
+ tlsreg = gen_rtx_REG (Pmode, 2);
+ insn = gen_tls_tprel_32 (dest, tlsreg, addr);
+ }
+ emit_insn (insn);
+ }
+ else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
+ {
+ rtx tlsreg, tmp;
+
+ tmp = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ {
+ tlsreg = gen_rtx_REG (Pmode, 13);
+ insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
+ }
+ else
+ {
+ tlsreg = gen_rtx_REG (Pmode, 2);
+ insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
+ }
+ emit_insn (insn);
+ if (TARGET_64BIT)
+ insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
+ else
+ insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
+ emit_insn (insn);
+ }
+ else
+ {
+ rtx r3, got, tga, tmp1, tmp2, eqv;
+
+ if (TARGET_64BIT)
+ got = gen_rtx_REG (Pmode, TOC_REGISTER);
+ else
+ {
+ if (flag_pic == 1)
+ got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
+ else
+ {
+ rtx gsym = rs6000_got_sym ();
+ got = gen_reg_rtx (Pmode);
+ if (flag_pic == 0)
+ rs6000_emit_move (got, gsym, Pmode);
+ else
+ {
+ char buf[30];
+ static int tls_got_labelno = 0;
+ rtx tempLR, lab, tmp3, mem;
+ rtx first, last;
+
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LTLS", tls_got_labelno++);
+ lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
+ tempLR = gen_reg_rtx (Pmode);
+ tmp1 = gen_reg_rtx (Pmode);
+ tmp2 = gen_reg_rtx (Pmode);
+ tmp3 = gen_reg_rtx (Pmode);
+ mem = gen_rtx_MEM (Pmode, tmp1);
+ RTX_UNCHANGING_P (mem) = 1;
+
+ first = emit_insn (gen_load_toc_v4_PIC_1b (tempLR, lab,
+ gsym));
+ emit_move_insn (tmp1, tempLR);
+ emit_move_insn (tmp2, mem);
+ emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
+ last = emit_move_insn (got, tmp3);
+ REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, gsym,
+ REG_NOTES (last));
+ REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
+ REG_NOTES (first));
+ REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
+ REG_NOTES (last));
+ }
+ }
+ }
+
+ if (model == TLS_MODEL_GLOBAL_DYNAMIC)
+ {
+ r3 = gen_rtx_REG (Pmode, 3);
+ if (TARGET_64BIT)
+ insn = gen_tls_gd_64 (r3, got, addr);
+ else
+ insn = gen_tls_gd_32 (r3, got, addr);
+ start_sequence ();
+ emit_insn (insn);
+ tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
+ insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
+ insn = emit_call_insn (insn);
+ CONST_OR_PURE_CALL_P (insn) = 1;
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
+ insn = get_insns ();
+ end_sequence ();
+ emit_libcall_block (insn, dest, r3, addr);
+ }
+ else if (model == TLS_MODEL_LOCAL_DYNAMIC)
+ {
+ r3 = gen_rtx_REG (Pmode, 3);
+ if (TARGET_64BIT)
+ insn = gen_tls_ld_64 (r3, got);
+ else
+ insn = gen_tls_ld_32 (r3, got);
+ start_sequence ();
+ emit_insn (insn);
+ tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
+ insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
+ insn = emit_call_insn (insn);
+ CONST_OR_PURE_CALL_P (insn) = 1;
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
+ insn = get_insns ();
+ end_sequence ();
+ tmp1 = gen_reg_rtx (Pmode);
+ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_TLSLD);
+ emit_libcall_block (insn, tmp1, r3, eqv);
+ if (rs6000_tls_size == 16)
+ {
+ if (TARGET_64BIT)
+ insn = gen_tls_dtprel_64 (dest, tmp1, addr);
+ else
+ insn = gen_tls_dtprel_32 (dest, tmp1, addr);
+ }
+ else if (rs6000_tls_size == 32)
+ {
+ tmp2 = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
+ else
+ insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
+ emit_insn (insn);
+ if (TARGET_64BIT)
+ insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
+ else
+ insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
+ }
+ else
+ {
+ tmp2 = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
+ else
+ insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
+ emit_insn (insn);
+ insn = gen_rtx_SET (Pmode, dest,
+ gen_rtx_PLUS (Pmode, tmp2, tmp1));
+ }
+ emit_insn (insn);
+ }
+ else
+ {
+ /* IE, or 64 bit offset LE. */
+ tmp2 = gen_reg_rtx (Pmode);
+ if (TARGET_64BIT)
+ insn = gen_tls_got_tprel_64 (tmp2, got, addr);
+ else
+ insn = gen_tls_got_tprel_32 (tmp2, got, addr);
+ emit_insn (insn);
+ if (TARGET_64BIT)
+ insn = gen_tls_tls_64 (dest, tmp2, addr);
+ else
+ insn = gen_tls_tls_32 (dest, tmp2, addr);
+ emit_insn (insn);
+ }
+ }
+
+ return dest;
+}
+
+/* Return 1 if X is a SYMBOL_REF for a TLS symbol. This is used in
+ instruction definitions. */
+
+int
+rs6000_tls_symbol_ref (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return RS6000_SYMBOL_REF_TLS_P (x);
+}
+
+/* Return 1 if X contains a thread-local symbol. */
+
+bool
+rs6000_tls_referenced_p (rtx x)
+{
+ if (! TARGET_HAVE_TLS)
+ return false;
+
+ return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
+}
+
+/* Return 1 if *X is a thread-local symbol. This is the same as
+ rs6000_tls_symbol_ref except for the type of the unused argument. */
+
+static inline int
+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. */
@@ -2225,13 +3143,8 @@ rs6000_legitimize_address (x, oldx, mode)
The Darwin code is inside #if TARGET_MACHO because only then is
machopic_function_base_name() defined. */
rtx
-rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
- rtx x;
- enum machine_mode mode;
- int opnum;
- int type;
- int ind_levels ATTRIBUTE_UNUSED;
- int *win;
+rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
+ int opnum, int type, int ind_levels ATTRIBUTE_UNUSED, int *win)
{
/* We must recognize output that we have already generated ourselves. */
if (GET_CODE (x) == PLUS
@@ -2306,25 +3219,33 @@ rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
if (GET_CODE (x) == SYMBOL_REF
&& DEFAULT_ABI == ABI_DARWIN
&& !ALTIVEC_VECTOR_MODE (mode)
- && flag_pic)
- {
- /* Darwin load of floating point constant. */
- rtx offset = gen_rtx (CONST, Pmode,
- gen_rtx (MINUS, Pmode, x,
- gen_rtx (SYMBOL_REF, Pmode,
- machopic_function_base_name ())));
- x = gen_rtx (LO_SUM, GET_MODE (x),
- gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
- gen_rtx (HIGH, Pmode, offset)), offset);
+ && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
+ /* Don't do this for TFmode, since the result isn't offsettable. */
+ && mode != TFmode)
+ {
+ if (flag_pic)
+ {
+ rtx offset = gen_rtx_CONST (Pmode,
+ gen_rtx_MINUS (Pmode, x,
+ gen_rtx_SYMBOL_REF (Pmode,
+ machopic_function_base_name ())));
+ x = gen_rtx_LO_SUM (GET_MODE (x),
+ gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
+ gen_rtx_HIGH (Pmode, offset)), offset);
+ }
+ else
+ x = gen_rtx_LO_SUM (GET_MODE (x),
+ gen_rtx_HIGH (Pmode, x), x);
+
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
- BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
- opnum, (enum reload_type)type);
+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
+ opnum, (enum reload_type)type);
*win = 1;
return x;
}
#endif
if (TARGET_TOC
- && CONSTANT_POOL_EXPR_P (x)
+ && constant_pool_expr_p (x)
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
{
(x) = create_TOC_reference (x);
@@ -2344,7 +3265,7 @@ rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
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 and DImode with an constant plus register,
+ auto-increment. For DFmode and DImode with a constant plus register,
we must ensure that both words are addressable or PowerPC64 with offset
word aligned.
@@ -2353,43 +3274,81 @@ rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
adjacent memory cells are accessed by adding word-sized offsets
during assembly output. */
int
-rs6000_legitimate_address (mode, x, reg_ok_strict)
- enum machine_mode mode;
- rtx x;
- int reg_ok_strict;
+rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
{
- if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
+ if (RS6000_SYMBOL_REF_TLS_P (x))
+ return 0;
+ if (legitimate_indirect_address_p (x, reg_ok_strict))
return 1;
if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
&& !ALTIVEC_VECTOR_MODE (mode)
&& !SPE_VECTOR_MODE (mode)
&& TARGET_UPDATE
- && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
+ && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
return 1;
- if (LEGITIMATE_SMALL_DATA_P (mode, x))
+ if (legitimate_small_data_p (mode, x))
return 1;
- if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
+ if (legitimate_constant_pool_address_p (x))
return 1;
/* If not REG_OK_STRICT (before reload) let pass any stack offset. */
if (! reg_ok_strict
&& GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
- && XEXP (x, 0) == virtual_stack_vars_rtx
+ && (XEXP (x, 0) == virtual_stack_vars_rtx
+ || XEXP (x, 0) == arg_pointer_rtx)
&& GET_CODE (XEXP (x, 1)) == CONST_INT)
return 1;
- if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
+ if (legitimate_offset_address_p (mode, x, reg_ok_strict))
return 1;
if (mode != TImode
&& ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64
|| (mode != DFmode && mode != TFmode))
&& (TARGET_POWERPC64 || mode != DImode)
- && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
+ && legitimate_indexed_address_p (x, reg_ok_strict))
return 1;
- if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
+ if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
return 1;
return 0;
}
+
+/* Go to LABEL if ADDR (a legitimate address expression)
+ has an effect that depends on the machine mode it is used for.
+
+ On the RS/6000 this is true of all integral offsets (since AltiVec
+ modes don't allow them) or is a pre-increment or decrement.
+
+ ??? Except that due to conceptual problems in offsettable_address_p
+ we can't really report the problems of integral offsets. So leave
+ this assuming that the adjustable offset must be valid for the
+ sub-words of a TFmode operand, which is what we had before. */
+
+bool
+rs6000_mode_dependent_address (rtx addr)
+{
+ switch (GET_CODE (addr))
+ {
+ case PLUS:
+ if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
+ {
+ unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
+ return val + 12 + 0x8000 >= 0x10000;
+ }
+ break;
+
+ case LO_SUM:
+ return true;
+
+ case PRE_INC:
+ case PRE_DEC:
+ return TARGET_UPDATE;
+
+ default:
+ break;
+ }
+
+ return false;
+}
/* 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.
@@ -2398,10 +3357,8 @@ rs6000_legitimate_address (mode, x, reg_ok_strict)
insns, zero is returned and no insns and emitted. */
rtx
-rs6000_emit_set_const (dest, mode, source, n)
- rtx dest, source;
- enum machine_mode mode;
- int n ATTRIBUTE_UNUSED;
+rs6000_emit_set_const (rtx dest, enum machine_mode mode,
+ rtx source, int n ATTRIBUTE_UNUSED)
{
rtx result, insn, set;
HOST_WIDE_INT c0, c1;
@@ -2463,9 +3420,7 @@ rs6000_emit_set_const (dest, mode, source, n)
exponential run times encountered when looking for longer sequences
with rs6000_emit_set_const. */
static rtx
-rs6000_emit_set_long_const (dest, c1, c2)
- rtx dest;
- HOST_WIDE_INT c1, c2;
+rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
{
if (!TARGET_POWERPC64)
{
@@ -2494,7 +3449,7 @@ rs6000_emit_set_long_const (dest, c1, c2)
|| (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
{
if (ud1 & 0x8000)
- emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
+ emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
else
emit_move_insn (dest, GEN_INT (ud1));
}
@@ -2549,10 +3504,7 @@ rs6000_emit_set_long_const (dest, c1, c2)
/* Emit a move from SOURCE to DEST in mode MODE. */
void
-rs6000_emit_move (dest, source, mode)
- rtx dest;
- rtx source;
- enum machine_mode mode;
+rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
{
rtx operands[2];
operands[0] = dest;
@@ -2640,6 +3592,15 @@ rs6000_emit_move (dest, source, mode)
}
}
+ /* Recognize the case where operand[1] is a reference to thread-local
+ data and load its address to a register. */
+ if (GET_CODE (operands[1]) == SYMBOL_REF)
+ {
+ enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]);
+ if (model != 0)
+ operands[1] = rs6000_legitimize_tls_address (operands[1], model);
+ }
+
/* Handle the case where reload calls us with an invalid address. */
if (reload_in_progress && mode == Pmode
&& (! general_operand (operands[1], mode)
@@ -2649,7 +3610,26 @@ rs6000_emit_move (dest, source, mode)
/* Handle the case of CONSTANT_P_RTX. */
if (GET_CODE (operands[1]) == CONSTANT_P_RTX)
goto emit_set;
-
+
+ /* 128-bit constant floating-point values on Darwin should really be
+ loaded as two parts. */
+ if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
+ && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
+ {
+ /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
+ know how to get a DFmode SUBREG of a TFmode. */
+ rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, 0),
+ simplify_gen_subreg (DImode, operands[1], mode, 0),
+ DImode);
+ rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode,
+ GET_MODE_SIZE (DImode)),
+ simplify_gen_subreg (DImode, operands[1], mode,
+ GET_MODE_SIZE (DImode)),
+ DImode);
+ return;
+ }
+
/* FIXME: In the long term, this switch statement should go away
and be replaced by a sequence of tests based on things like
mode == Pmode. */
@@ -2679,7 +3659,7 @@ rs6000_emit_move (dest, source, mode)
case V2SImode:
case V1DImode:
if (CONSTANT_P (operands[1])
- && !easy_vector_constant (operands[1]))
+ && !easy_vector_constant (operands[1], mode))
operands[1] = force_const_mem (mode, operands[1]);
break;
@@ -2706,7 +3686,8 @@ rs6000_emit_move (dest, source, mode)
}
if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
- && TARGET_NO_TOC && ! flag_pic
+ && TARGET_NO_TOC
+ && ! flag_pic
&& mode == Pmode
&& CONSTANT_P (operands[1])
&& GET_CODE (operands[1]) != HIGH
@@ -2727,13 +3708,26 @@ rs6000_emit_move (dest, source, mode)
new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
CONSTANT_POOL_ADDRESS_P (new_ref)
= CONSTANT_POOL_ADDRESS_P (operands[1]);
- SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
+ SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
+ SYMBOL_REF_DECL (new_ref) = SYMBOL_REF_DECL (operands[1]);
operands[1] = new_ref;
}
if (DEFAULT_ABI == ABI_DARWIN)
{
+#if TARGET_MACHO
+ if (MACHO_DYNAMIC_NO_PIC_P)
+ {
+ /* Take care of any required data indirection. */
+ operands[1] = rs6000_machopic_legitimize_pic_address (
+ operands[1], mode, operands[0]);
+ if (operands[0] != operands[1])
+ emit_insn (gen_rtx_SET (VOIDmode,
+ operands[0], operands[1]));
+ return;
+ }
+#endif
emit_insn (gen_macho_high (target, operands[1]));
emit_insn (gen_macho_low (operands[0], target, operands[1]));
return;
@@ -2749,7 +3743,7 @@ rs6000_emit_move (dest, source, mode)
reference to it. */
if (TARGET_TOC
&& GET_CODE (operands[1]) == SYMBOL_REF
- && CONSTANT_POOL_EXPR_P (operands[1])
+ && constant_pool_expr_p (operands[1])
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
get_pool_mode (operands[1])))
{
@@ -2764,8 +3758,8 @@ rs6000_emit_move (dest, source, mode)
|| (GET_CODE (operands[0]) == REG
&& FP_REGNO_P (REGNO (operands[0]))))
&& GET_CODE (operands[1]) != HIGH
- && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
- && ! TOC_RELATIVE_EXPR_P (operands[1]))
+ && ! 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
@@ -2778,7 +3772,7 @@ rs6000_emit_move (dest, source, mode)
#if TARGET_MACHO
/* Darwin uses a special PIC legitimizer. */
- if (DEFAULT_ABI == ABI_DARWIN && flag_pic)
+ if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
{
operands[1] =
rs6000_machopic_legitimize_pic_address (operands[1], mode,
@@ -2816,7 +3810,7 @@ rs6000_emit_move (dest, source, mode)
operands[1] = force_const_mem (mode, operands[1]);
if (TARGET_TOC
- && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
+ && constant_pool_expr_p (XEXP (operands[1], 0))
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
get_pool_constant (XEXP (operands[1], 0)),
get_pool_mode (XEXP (operands[1], 0))))
@@ -2845,7 +3839,7 @@ rs6000_emit_move (dest, source, mode)
= replace_equiv_address (operands[1],
copy_addr_to_reg (XEXP (operands[1], 0)));
if (TARGET_POWER)
- {
+ {
emit_insn (gen_rtx_PARALLEL (VOIDmode,
gen_rtvec (2,
gen_rtx_SET (VOIDmode,
@@ -2870,6 +3864,52 @@ rs6000_emit_move (dest, source, mode)
emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
}
+/* Nonzero if we can use a floating-point register to pass this arg. */
+#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
+ (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ && (CUM)->fregno <= FP_ARG_MAX_REG \
+ && TARGET_HARD_FLOAT && TARGET_FPRS)
+
+/* Nonzero if we can use an AltiVec register to pass this arg. */
+#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
+ (ALTIVEC_VECTOR_MODE (MODE) \
+ && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
+ && TARGET_ALTIVEC_ABI \
+ && (NAMED))
+
+/* Return a nonzero value to say to return the function value in
+ memory, just as large structures are always returned. TYPE will be
+ the data type of the value, and FNTYPE will be the type of the
+ function doing the returning, or @code{NULL} for libcalls.
+
+ The AIX ABI for the RS/6000 specifies that all structures are
+ returned in memory. The Darwin ABI does the same. The SVR4 ABI
+ specifies that structures <= 8 bytes are returned in r3/r4, but a
+ draft put them in memory, and GCC used to implement the draft
+ instead of the final standard. Therefore, TARGET_AIX_STRUCT_RET
+ controls this instead of DEFAULT_ABI; V.4 targets needing backward
+ compatibility can change DRAFT_V4_STRUCT_RET to override the
+ default, and -m switches get the final word. See
+ rs6000_override_options for more details.
+
+ The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
+ long double support is enabled. These values are returned in memory.
+
+ int_size_in_bytes returns -1 for variable size objects, which go in
+ memory always. The cast to unsigned makes -1 > 8. */
+
+static bool
+rs6000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
+{
+ if (AGGREGATE_TYPE_P (type)
+ && (TARGET_AIX_STRUCT_RET
+ || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
+ return true;
+ if (DEFAULT_ABI == ABI_V4 && TYPE_MODE (type) == TFmode)
+ return true;
+ return false;
+}
+
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0.
@@ -2878,12 +3918,9 @@ rs6000_emit_move (dest, source, mode)
so we never return a PARALLEL. */
void
-init_cumulative_args (cum, fntype, libname, incoming, libcall)
- CUMULATIVE_ARGS *cum;
- tree fntype;
- rtx libname ATTRIBUTE_UNUSED;
- int incoming;
- int libcall;
+init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
+ rtx libname ATTRIBUTE_UNUSED, int incoming,
+ int libcall, int n_named_args)
{
static CUMULATIVE_ARGS zero_cumulative;
@@ -2895,19 +3932,14 @@ init_cumulative_args (cum, fntype, libname, incoming, libcall)
cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
? CALL_LIBCALL : CALL_NORMAL);
cum->sysv_gregno = GP_ARG_MIN_REG;
+ cum->stdarg = fntype
+ && (TYPE_ARG_TYPES (fntype) != 0
+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
+ != void_type_node));
- if (incoming)
- cum->nargs_prototype = 1000; /* don't return a PARALLEL */
-
- else if (cum->prototype)
- cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
- + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
- || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
-
- else
- cum->nargs_prototype = 0;
-
- cum->orig_nargs = cum->nargs_prototype;
+ cum->nargs_prototype = 0;
+ if (incoming || cum->prototype)
+ cum->nargs_prototype = n_named_args;
/* Check for a longcall attribute. */
if (fntype
@@ -2931,6 +3963,16 @@ init_cumulative_args (cum, fntype, libname, incoming, libcall)
fprintf (stderr, " proto = %d, nargs = %d\n",
cum->prototype, cum->nargs_prototype);
}
+
+ if (fntype
+ && !TARGET_ALTIVEC
+ && TARGET_ALTIVEC_ABI
+ && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
+ {
+ error ("Cannot return value in vector register because"
+ " altivec instructions are disabled, use -maltivec"
+ " to enable them.");
+ }
}
/* If defined, a C expression which determines whether, and in which
@@ -2943,21 +3985,52 @@ init_cumulative_args (cum, fntype, libname, incoming, libcall)
argument slot. */
enum direction
-function_arg_padding (mode, type)
- enum machine_mode mode;
- tree type;
+function_arg_padding (enum machine_mode mode, tree type)
{
- if (type != 0 && AGGREGATE_TYPE_P (type))
- return upward;
+#ifndef AGGREGATE_PADDING_FIXED
+#define AGGREGATE_PADDING_FIXED 0
+#endif
+#ifndef AGGREGATES_PAD_UPWARD_ALWAYS
+#define AGGREGATES_PAD_UPWARD_ALWAYS 0
+#endif
+
+ if (!AGGREGATE_PADDING_FIXED)
+ {
+ /* GCC used to pass structures of the same size as integer types as
+ if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
+ ie. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
+ passed padded downward, except that -mstrict-align further
+ muddied the water in that multi-component structures of 2 and 4
+ bytes in size were passed padded upward.
+
+ The following arranges for best compatibility with previous
+ versions of gcc, but removes the -mstrict-align dependency. */
+ if (BYTES_BIG_ENDIAN)
+ {
+ HOST_WIDE_INT size = 0;
+
+ if (mode == BLKmode)
+ {
+ if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
+ size = int_size_in_bytes (type);
+ }
+ else
+ size = GET_MODE_SIZE (mode);
+
+ if (size == 1 || size == 2 || size == 4)
+ return downward;
+ }
+ return upward;
+ }
+
+ if (AGGREGATES_PAD_UPWARD_ALWAYS)
+ {
+ if (type != 0 && AGGREGATE_TYPE_P (type))
+ return upward;
+ }
- /* This is the default definition. */
- return (! BYTES_BIG_ENDIAN
- ? upward
- : ((mode == BLKmode
- ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
- : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
- ? downward : upward));
+ /* Fall back to the default. */
+ return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
}
/* If defined, a C expression that gives the alignment boundary, in bits,
@@ -2967,42 +4040,102 @@ function_arg_padding (mode, type)
V.4 wants long longs to be double word aligned. */
int
-function_arg_boundary (mode, type)
- enum machine_mode mode;
- tree type ATTRIBUTE_UNUSED;
+function_arg_boundary (enum machine_mode mode, tree type ATTRIBUTE_UNUSED)
{
- if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
+ if (DEFAULT_ABI == ABI_V4 && GET_MODE_SIZE (mode) == 8)
return 64;
- else if (SPE_VECTOR_MODE (mode))
- return 64;
- else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+ else if (SPE_VECTOR_MODE (mode))
+ return 64;
+ else if (ALTIVEC_VECTOR_MODE (mode))
return 128;
else
return PARM_BOUNDARY;
}
+
+/* Compute the size (in words) of a function argument. */
+
+static unsigned long
+rs6000_arg_size (enum machine_mode mode, tree type)
+{
+ unsigned long size;
+
+ if (mode != BLKmode)
+ size = GET_MODE_SIZE (mode);
+ else
+ size = int_size_in_bytes (type);
+
+ if (TARGET_32BIT)
+ return (size + 3) >> 2;
+ else
+ return (size + 7) >> 3;
+}
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
- (TYPE is null for libcalls where that information may not be available.) */
+ (TYPE is null for libcalls where that information may not be available.)
+
+ Note that for args passed by reference, function_arg will be called
+ with MODE and TYPE set to that of the pointer to the arg, not the arg
+ itself. */
void
-function_arg_advance (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
+function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named)
{
cum->nargs_prototype--;
if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
{
- if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
- cum->vregno++;
+ bool stack = false;
+
+ if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
+ {
+ cum->vregno++;
+ if (!TARGET_ALTIVEC)
+ error ("Cannot pass argument in vector register because"
+ " altivec instructions are disabled, use -maltivec"
+ " to enable them.");
+
+ /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
+ even if it is going to be passed in a vector register.
+ Darwin does the same for variable-argument functions. */
+ if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
+ || (cum->stdarg && DEFAULT_ABI != ABI_V4))
+ stack = true;
+ }
else
- cum->words += RS6000_ARG_SIZE (mode, type);
+ stack = true;
+
+ if (stack)
+ {
+ int align;
+
+ /* Vector parameters must be 16-byte aligned. This places
+ them at 2 mod 4 in terms of words in 32-bit mode, since
+ the parameter save area starts at offset 24 from the
+ stack. In 64-bit mode, they just have to start on an
+ even word, since the parameter save area is 16-byte
+ aligned. Space for GPRs is reserved even if the argument
+ will be passed in memory. */
+ if (TARGET_32BIT)
+ align = (2 - cum->words) & 3;
+ else
+ align = cum->words & 1;
+ cum->words += align + rs6000_arg_size (mode, type);
+
+ if (TARGET_DEBUG_ARG)
+ {
+ fprintf (stderr, "function_adv: words = %2d, align=%d, ",
+ cum->words, align);
+ fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
+ cum->nargs_prototype, cum->prototype,
+ GET_MODE_NAME (mode));
+ }
+ }
}
else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
- && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
+ && !cum->stdarg
+ && cum->sysv_gregno <= GP_ARG_MAX_REG)
cum->sysv_gregno++;
else if (DEFAULT_ABI == ABI_V4)
{
@@ -3015,30 +4148,26 @@ function_arg_advance (cum, mode, type, named)
{
if (mode == DFmode)
cum->words += cum->words & 1;
- cum->words += RS6000_ARG_SIZE (mode, type);
+ cum->words += rs6000_arg_size (mode, type);
}
}
else
{
- int n_words;
+ int n_words = rs6000_arg_size (mode, type);
int gregno = cum->sysv_gregno;
- /* Aggregates and IEEE quad get passed by reference. */
- if ((type && AGGREGATE_TYPE_P (type))
- || mode == TFmode)
- n_words = 1;
- else
- n_words = RS6000_ARG_SIZE (mode, type);
-
- /* Long long and SPE vectors are put in odd registers. */
- if (n_words == 2 && (gregno & 1) == 0)
- gregno += 1;
+ /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
+ (r7,r8) or (r9,r10). As does any other 2 word item such
+ as complex int due to a historical mistake. */
+ if (n_words == 2)
+ gregno += (1 - gregno) & 1;
- /* Long long and SPE vectors are not split between registers
- and stack. */
+ /* Multi-reg args are not split between registers and stack. */
if (gregno + n_words - 1 > GP_ARG_MAX_REG)
{
- /* Long long is aligned on the stack. */
+ /* Long long and SPE vectors are aligned on the stack.
+ So are other 2 word items such as complex int due to
+ a historical mistake. */
if (n_words == 2)
cum->words += cum->words & 1;
cum->words += n_words;
@@ -3062,14 +4191,20 @@ function_arg_advance (cum, mode, type, named)
}
else
{
- int align = (TARGET_32BIT && (cum->words & 1) != 0
- && function_arg_boundary (mode, type) == 64) ? 1 : 0;
+ int n_words = rs6000_arg_size (mode, type);
+ int align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
- cum->words += align + RS6000_ARG_SIZE (mode, type);
+ /* The simple alignment calculation here works because
+ function_arg_boundary / PARM_BOUNDARY will only be 1 or 2.
+ If we ever want to handle alignments larger than 8 bytes for
+ 32-bit or 16 bytes for 64-bit, then we'll need to take into
+ account the offset to the start of the parm save area. */
+ align &= cum->words;
+ cum->words += align + n_words;
if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& TARGET_HARD_FLOAT && TARGET_FPRS)
- cum->fregno += (mode == TFmode ? 2 : 1);
+ cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
if (TARGET_DEBUG_ARG)
{
@@ -3081,7 +4216,149 @@ function_arg_advance (cum, mode, type, named)
}
}
}
-
+
+/* Determine where to put a SIMD argument on the SPE. */
+
+static rtx
+rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type)
+{
+ if (cum->stdarg)
+ {
+ int gregno = cum->sysv_gregno;
+ int n_words = rs6000_arg_size (mode, type);
+
+ /* SPE vectors are put in odd registers. */
+ if (n_words == 2 && (gregno & 1) == 0)
+ gregno += 1;
+
+ if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
+ {
+ rtx r1, r2;
+ enum machine_mode m = SImode;
+
+ r1 = gen_rtx_REG (m, gregno);
+ r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
+ r2 = gen_rtx_REG (m, gregno + 1);
+ r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
+ return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
+ }
+ else
+ return NULL_RTX;
+ }
+ else
+ {
+ if (cum->sysv_gregno <= GP_ARG_MAX_REG)
+ return gen_rtx_REG (mode, cum->sysv_gregno);
+ else
+ return NULL_RTX;
+ }
+}
+
+/* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
+
+static rtx
+rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int align_words)
+{
+ if (mode == DFmode)
+ {
+ /* -mpowerpc64 with 32bit ABI splits up a DFmode argument
+ in vararg list into zero, one or two GPRs */
+ if (align_words >= GP_ARG_NUM_REG)
+ return gen_rtx_PARALLEL (DFmode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ NULL_RTX, const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode,
+ cum->fregno),
+ const0_rtx)));
+ else if (align_words + rs6000_arg_size (mode, type)
+ > GP_ARG_NUM_REG)
+ /* If this is partially on the stack, then we only
+ include the portion actually in registers here. */
+ return gen_rtx_PARALLEL (DFmode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode,
+ cum->fregno),
+ const0_rtx)));
+
+ /* split a DFmode arg into two GPRs */
+ return gen_rtx_PARALLEL (DFmode,
+ gen_rtvec (3,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words + 1),
+ GEN_INT (4)),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode, cum->fregno),
+ const0_rtx)));
+ }
+ /* -mpowerpc64 with 32bit ABI splits up a DImode argument into one
+ or two GPRs */
+ else if (mode == DImode)
+ {
+ if (align_words < GP_ARG_NUM_REG - 1)
+ return gen_rtx_PARALLEL (DImode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words + 1),
+ GEN_INT (4))));
+ else if (align_words == GP_ARG_NUM_REG - 1)
+ return gen_rtx_PARALLEL (DImode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ NULL_RTX, const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx)));
+ }
+ else if (mode == BLKmode && align_words <= (GP_ARG_NUM_REG - 1))
+ {
+ int k;
+ int size = int_size_in_bytes (type);
+ int no_units = ((size - 1) / 4) + 1;
+ int max_no_words = GP_ARG_NUM_REG - align_words;
+ int rtlvec_len = no_units < max_no_words ? no_units : max_no_words;
+ rtx *rtlvec = (rtx *) alloca (rtlvec_len * sizeof (rtx));
+
+ memset ((char *) rtlvec, 0, rtlvec_len * sizeof (rtx));
+
+ for (k=0; k < rtlvec_len; k++)
+ rtlvec[k] = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words + k),
+ k == 0 ? const0_rtx : GEN_INT (k*4));
+
+ return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k, rtlvec));
+ }
+
+ return NULL_RTX;
+}
+
/* Determine where to put an argument to a function.
Value is zero to push the argument on the stack,
or a hard register in which to store the argument.
@@ -3103,14 +4380,15 @@ function_arg_advance (cum, mode, type, named)
both an FP and integer register (or possibly FP reg and stack). Library
functions (when CALL_LIBCALL is set) always have the proper types for args,
so we can pass the FP value just in one register. emit_library_function
- doesn't support PARALLEL anyway. */
+ doesn't support PARALLEL anyway.
+
+ Note that for args passed by reference, function_arg will be called
+ with MODE and TYPE set to that of the pointer to the arg, not the arg
+ itself. */
struct rtx_def *
-function_arg (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
+function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named)
{
enum rs6000_abi abi = DEFAULT_ABI;
@@ -3138,20 +4416,72 @@ function_arg (cum, mode, type, named)
return GEN_INT (cum->call_cookie);
}
- if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
- {
- if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
- return gen_rtx_REG (mode, cum->vregno);
- else
- return NULL;
- }
- else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
+ if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
+ if (TARGET_64BIT && ! cum->prototype)
+ {
+ /* Vector parameters get passed in vector register
+ and also in GPRs or memory, in absence of prototype. */
+ int align_words;
+ rtx slot;
+ align_words = (cum->words + 1) & ~1;
+
+ if (align_words >= GP_ARG_NUM_REG)
+ {
+ slot = NULL_RTX;
+ }
+ else
+ {
+ slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+ }
+ return gen_rtx_PARALLEL (mode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ slot, const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode, cum->vregno),
+ const0_rtx)));
+ }
+ else
+ return gen_rtx_REG (mode, cum->vregno);
+ else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
{
- if (cum->sysv_gregno <= GP_ARG_MAX_REG)
- return gen_rtx_REG (mode, cum->sysv_gregno);
+ if (named || abi == ABI_V4)
+ return NULL_RTX;
else
- return NULL;
+ {
+ /* Vector parameters to varargs functions under AIX or Darwin
+ get passed in memory and possibly also in GPRs. */
+ int align, align_words;
+ enum machine_mode part_mode = mode;
+
+ /* Vector parameters must be 16-byte aligned. This places them at
+ 2 mod 4 in terms of words in 32-bit mode, since the parameter
+ save area starts at offset 24 from the stack. In 64-bit mode,
+ they just have to start on an even word, since the parameter
+ save area is 16-byte aligned. */
+ if (TARGET_32BIT)
+ align = (2 - cum->words) & 3;
+ else
+ align = cum->words & 1;
+ align_words = cum->words + align;
+
+ /* Out of registers? Memory, then. */
+ if (align_words >= GP_ARG_NUM_REG)
+ return NULL_RTX;
+
+ /* The vector value goes in GPRs. Only the part of the
+ value in GPRs is reported here. */
+ if (align_words + CLASS_MAX_NREGS (mode, GENERAL_REGS)
+ > GP_ARG_NUM_REG)
+ /* Fortunately, there are only two possibilities, the value
+ is either wholly in GPRs or half in GPRs and half not. */
+ part_mode = DImode;
+
+ return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
+ }
}
+ else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode))
+ return rs6000_spe_function_arg (cum, mode, type);
else if (abi == ABI_V4)
{
if (TARGET_HARD_FLOAT && TARGET_FPRS
@@ -3160,90 +4490,105 @@ function_arg (cum, mode, type, named)
if (cum->fregno <= FP_ARG_V4_MAX_REG)
return gen_rtx_REG (mode, cum->fregno);
else
- return NULL;
+ return NULL_RTX;
}
else
{
- int n_words;
+ int n_words = rs6000_arg_size (mode, type);
int gregno = cum->sysv_gregno;
- /* Aggregates and IEEE quad get passed by reference. */
- if ((type && AGGREGATE_TYPE_P (type))
- || mode == TFmode)
- n_words = 1;
- else
- n_words = RS6000_ARG_SIZE (mode, type);
+ /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
+ (r7,r8) or (r9,r10). As does any other 2 word item such
+ as complex int due to a historical mistake. */
+ if (n_words == 2)
+ gregno += (1 - gregno) & 1;
- /* Long long and SPE vectors are put in odd registers. */
- if (n_words == 2 && (gregno & 1) == 0)
- gregno += 1;
-
- /* Long long and SPE vectors are not split between registers
- and stack. */
+ /* Multi-reg args are not split between registers and stack. */
if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
- {
- /* SPE vectors in ... get split into 2 registers. */
- if (TARGET_SPE && TARGET_SPE_ABI
- && SPE_VECTOR_MODE (mode) && !named)
- {
- rtx r1, r2;
- enum machine_mode m = SImode;
-
- r1 = gen_rtx_REG (m, gregno);
- r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
- r2 = gen_rtx_REG (m, gregno + 1);
- r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
- return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
- }
- return gen_rtx_REG (mode, gregno);
- }
+ return gen_rtx_REG (mode, gregno);
else
- return NULL;
+ return NULL_RTX;
}
}
else
{
- int align = (TARGET_32BIT && (cum->words & 1) != 0
- && function_arg_boundary (mode, type) == 64) ? 1 : 0;
- int align_words = cum->words + align;
-
- if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
- return NULL_RTX;
+ int align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
+ int align_words = cum->words + (cum->words & align);
- if (USE_FP_FOR_ARG_P (*cum, mode, type))
+ if (USE_FP_FOR_ARG_P (cum, mode, type))
{
- if (! type
- || ((cum->nargs_prototype > 0)
- /* IBM AIX extended its linkage convention definition always
- to require FP args after register save area hole on the
- stack. */
- && (DEFAULT_ABI != ABI_AIX
- || ! TARGET_XL_CALL
- || (align_words < GP_ARG_NUM_REG))))
- return gen_rtx_REG (mode, cum->fregno);
+ rtx fpr[2];
+ rtx *r;
+ bool needs_psave;
+ enum machine_mode fmode = mode;
+ int n;
+ unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
+
+ if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
+ {
+ /* Long double split over regs and memory. */
+ if (fmode == TFmode)
+ fmode = DFmode;
+
+ /* Currently, we only ever need one reg here because complex
+ doubles are split. */
+ if (cum->fregno != FP_ARG_MAX_REG - 1)
+ abort ();
+ }
+ fpr[1] = gen_rtx_REG (fmode, cum->fregno);
+
+ /* Do we also need to pass this arg in the parameter save
+ area? */
+ needs_psave = (type
+ && (cum->nargs_prototype <= 0
+ || (DEFAULT_ABI == ABI_AIX
+ && TARGET_XL_CALL
+ && align_words >= GP_ARG_NUM_REG)));
- return gen_rtx_PARALLEL (mode,
- gen_rtvec (2,
- gen_rtx_EXPR_LIST (VOIDmode,
- ((align_words >= GP_ARG_NUM_REG)
- ? NULL_RTX
- : (align_words
- + RS6000_ARG_SIZE (mode, type)
- > GP_ARG_NUM_REG
- /* If this is partially on the stack, then
- we only include the portion actually
- in registers here. */
- ? gen_rtx_REG (SImode,
- GP_ARG_MIN_REG + align_words)
- : gen_rtx_REG (mode,
- GP_ARG_MIN_REG + align_words))),
- const0_rtx),
- gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (mode, cum->fregno),
- const0_rtx)));
+ if (!needs_psave && mode == fmode)
+ return fpr[1];
+
+ if (TARGET_32BIT && TARGET_POWERPC64
+ && mode == DFmode && cum->stdarg)
+ return rs6000_mixed_function_arg (cum, mode, type, align_words);
+
+ /* Describe where this piece goes. */
+ r = fpr + 1;
+ *r = gen_rtx_EXPR_LIST (VOIDmode, *r, const0_rtx);
+ n = 1;
+
+ if (needs_psave)
+ {
+ /* Now describe the part that goes in gprs or the stack.
+ This piece must come first, before the fprs. */
+ rtx reg = NULL_RTX;
+ if (align_words < GP_ARG_NUM_REG)
+ {
+ unsigned long n_words = rs6000_arg_size (mode, type);
+ enum machine_mode rmode = mode;
+
+ if (align_words + n_words > GP_ARG_NUM_REG)
+ /* If this is partially on the stack, then we only
+ include the portion actually in registers here.
+ We know this can only be one register because
+ complex doubles are splt. */
+ rmode = Pmode;
+ reg = gen_rtx_REG (rmode, GP_ARG_MIN_REG + align_words);
+ }
+ *--r = gen_rtx_EXPR_LIST (VOIDmode, reg, const0_rtx);
+ ++n;
+ }
+
+ return gen_rtx_PARALLEL (mode, gen_rtvec_v (n, r));
}
else if (align_words < GP_ARG_NUM_REG)
- return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+ {
+ if (TARGET_32BIT && TARGET_POWERPC64
+ && (mode == DImode || mode == BLKmode))
+ return rs6000_mixed_function_arg (cum, mode, type, align_words);
+
+ return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
+ }
else
return NULL_RTX;
}
@@ -3254,33 +4599,34 @@ function_arg (cum, mode, type, named)
For args passed entirely in registers or entirely in memory, zero. */
int
-function_arg_partial_nregs (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
+function_arg_partial_nregs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named)
{
+ int ret = 0;
+
if (DEFAULT_ABI == ABI_V4)
return 0;
- if (USE_FP_FOR_ARG_P (*cum, mode, type)
- || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
+ if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
+ && cum->nargs_prototype >= 0)
+ return 0;
+
+ if (USE_FP_FOR_ARG_P (cum, mode, type))
{
- if (cum->nargs_prototype >= 0)
+ if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3) > FP_ARG_MAX_REG + 1)
+ ret = FP_ARG_MAX_REG - cum->fregno;
+ else if (cum->nargs_prototype >= 0)
return 0;
}
if (cum->words < GP_ARG_NUM_REG
- && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type)))
- {
- int ret = GP_ARG_NUM_REG - cum->words;
- if (ret && TARGET_DEBUG_ARG)
- fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
+ && GP_ARG_NUM_REG < cum->words + rs6000_arg_size (mode, type))
+ ret = GP_ARG_NUM_REG - cum->words;
- return ret;
- }
+ if (ret != 0 && TARGET_DEBUG_ARG)
+ fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
- return 0;
+ return ret;
}
/* A C expression that indicates when an argument must be passed by
@@ -3289,29 +4635,63 @@ function_arg_partial_nregs (cum, mode, type, named)
the argument itself. The pointer is passed in whatever way is
appropriate for passing a pointer to that type.
- Under V.4, structures and unions are passed by reference.
+ Under V.4, aggregates and long double are passed by reference.
+
+ As an extension to all 32-bit ABIs, AltiVec vectors are passed by
+ reference unless the AltiVec vector extension ABI is in force.
As an extension to all ABIs, variable sized types are passed by
reference. */
int
-function_arg_pass_by_reference (cum, mode, type, named)
- CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- tree type;
- int named ATTRIBUTE_UNUSED;
+function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type, int named ATTRIBUTE_UNUSED)
{
- if (DEFAULT_ABI == ABI_V4
- && ((type && AGGREGATE_TYPE_P (type))
- || mode == TFmode))
+ if ((DEFAULT_ABI == ABI_V4
+ && ((type && AGGREGATE_TYPE_P (type))
+ || mode == TFmode))
+ || (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+ || (type && int_size_in_bytes (type) < 0))
{
if (TARGET_DEBUG_ARG)
- fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
+ fprintf (stderr, "function_arg_pass_by_reference\n");
return 1;
}
- return type && int_size_in_bytes (type) < 0;
+ return 0;
}
+
+static void
+rs6000_move_block_from_reg (int regno, rtx x, int nregs)
+{
+ int i;
+ enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
+
+ if (nregs == 0)
+ return;
+
+ for (i = 0; i < nregs; i++)
+ {
+ rtx tem = adjust_address_nv (x, reg_mode, i*GET_MODE_SIZE(reg_mode));
+ if (reload_completed)
+ {
+ if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
+ tem = NULL_RTX;
+ else
+ tem = simplify_gen_subreg (reg_mode, x, BLKmode,
+ i * GET_MODE_SIZE(reg_mode));
+ }
+ else
+ tem = replace_equiv_address (tem, XEXP (tem, 0));
+
+ if (tem == NULL_RTX)
+ abort ();
+
+ emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
+ }
+}
+
/* Perform any needed actions needed for a function that is receiving a
variable number of arguments.
@@ -3327,32 +4707,18 @@ function_arg_pass_by_reference (cum, mode, type, named)
Normally, this macro will push all remaining incoming registers on the
stack and set PRETEND_SIZE to the length of the registers pushed. */
-void
-setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int *pretend_size;
- int no_rtl;
-
+static void
+setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int *pretend_size ATTRIBUTE_UNUSED, int no_rtl)
{
CUMULATIVE_ARGS next_cum;
int reg_size = TARGET_32BIT ? 4 : 8;
rtx save_area = NULL_RTX, mem;
int first_reg_offset, set;
- tree fntype;
- int stdarg_p;
-
- fntype = TREE_TYPE (current_function_decl);
- stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
- && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
- != void_type_node));
- /* For varargs, we do not want to skip the dummy va_dcl argument.
- For stdargs, we do want to skip the last named argument. */
+ /* Skip the last named argument. */
next_cum = *cum;
- if (stdarg_p)
- function_arg_advance (&next_cum, mode, type, 1);
+ function_arg_advance (&next_cum, mode, type, 1);
if (DEFAULT_ABI == ABI_V4)
{
@@ -3371,7 +4737,7 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
cfun->machine->sysv_varargs_p = 0;
if (MUST_PASS_IN_STACK (mode, type))
- first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type);
+ first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
}
set = get_varargs_alias_set ();
@@ -3383,13 +4749,8 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
set_mem_alias_set (mem, set);
set_mem_align (mem, BITS_PER_WORD);
- move_block_from_reg
- (GP_ARG_MIN_REG + first_reg_offset, mem,
- GP_ARG_NUM_REG - first_reg_offset,
- (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
-
- /* ??? Does ABI_V4 need this at all? */
- *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD;
+ rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
+ GP_ARG_NUM_REG - first_reg_offset);
}
/* Save FP registers if needed. */
@@ -3426,10 +4787,10 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
/* Create the va_list data type. */
-tree
-rs6000_build_va_list ()
+static tree
+rs6000_build_builtin_va_list (void)
{
- tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
+ tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
/* For AIX, prefer 'char *' because that's what the system
header files like. */
@@ -3443,6 +4804,10 @@ rs6000_build_va_list ()
unsigned_char_type_node);
f_fpr = build_decl (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"),
ptr_type_node);
f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
@@ -3450,6 +4815,7 @@ rs6000_build_va_list ()
DECL_FIELD_CONTEXT (f_gpr) = record;
DECL_FIELD_CONTEXT (f_fpr) = record;
+ DECL_FIELD_CONTEXT (f_res) = record;
DECL_FIELD_CONTEXT (f_ovf) = record;
DECL_FIELD_CONTEXT (f_sav) = record;
@@ -3457,7 +4823,8 @@ rs6000_build_va_list ()
TYPE_NAME (record) = type_decl;
TYPE_FIELDS (record) = f_gpr;
TREE_CHAIN (f_gpr) = f_fpr;
- TREE_CHAIN (f_fpr) = f_ovf;
+ TREE_CHAIN (f_fpr) = f_res;
+ TREE_CHAIN (f_res) = f_ovf;
TREE_CHAIN (f_ovf) = f_sav;
layout_type (record);
@@ -3469,12 +4836,10 @@ rs6000_build_va_list ()
/* Implement va_start. */
void
-rs6000_va_start (valist, nextarg)
- tree valist;
- rtx nextarg;
+rs6000_va_start (tree valist, rtx nextarg)
{
HOST_WIDE_INT words, n_gpr, n_fpr;
- tree f_gpr, f_fpr, f_ovf, f_sav;
+ tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
tree gpr, fpr, ovf, sav, t;
/* Only SVR4 needs something special. */
@@ -3486,7 +4851,8 @@ rs6000_va_start (valist, nextarg)
f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
- f_ovf = TREE_CHAIN (f_fpr);
+ f_res = TREE_CHAIN (f_fpr);
+ f_ovf = TREE_CHAIN (f_res);
f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
@@ -3501,15 +4867,9 @@ rs6000_va_start (valist, nextarg)
n_fpr = current_function_args_info.fregno - FP_ARG_MIN_REG;
if (TARGET_DEBUG_ARG)
- {
- fputs ("va_start: words = ", stderr);
- fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, words);
- fputs (", n_gpr = ", stderr);
- fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_gpr);
- fputs (", n_fpr = ", stderr);
- fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_fpr);
- putc ('\n', stderr);
- }
+ fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
+ HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
+ words, n_gpr, n_fpr);
t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
TREE_SIDE_EFFECTS (t) = 1;
@@ -3540,18 +4900,22 @@ rs6000_va_start (valist, nextarg)
/* Implement va_arg. */
rtx
-rs6000_va_arg (valist, type)
- tree valist, type;
+rs6000_va_arg (tree valist, tree type)
{
- tree f_gpr, f_fpr, f_ovf, f_sav;
+ tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
tree gpr, fpr, ovf, sav, reg, t, u;
int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
rtx lab_false, lab_over, addr_rtx, r;
+ int align;
if (DEFAULT_ABI != ABI_V4)
{
- /* Variable sized types are passed by reference. */
- if (int_size_in_bytes (type) < 0)
+ /* Variable sized types are passed by reference, as are AltiVec
+ vectors when 32-bit and not using the AltiVec ABI extension. */
+ if (int_size_in_bytes (type) < 0
+ || (TARGET_32BIT
+ && !TARGET_ALTIVEC_ABI
+ && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))))
{
u = build_pointer_type (type);
@@ -3568,13 +4932,48 @@ rs6000_va_arg (valist, type)
return expand_expr (t, NULL_RTX, VOIDmode, EXPAND_NORMAL);
}
- else
- return std_expand_builtin_va_arg (valist, type);
+ if (targetm.calls.split_complex_arg
+ && TREE_CODE (type) == COMPLEX_TYPE)
+ {
+ tree elem_type = TREE_TYPE (type);
+ enum machine_mode elem_mode = TYPE_MODE (elem_type);
+ int elem_size = GET_MODE_SIZE (elem_mode);
+
+ if (elem_size < UNITS_PER_WORD)
+ {
+ rtx real_part, imag_part, dest_real, rr;
+
+ real_part = rs6000_va_arg (valist, elem_type);
+ imag_part = rs6000_va_arg (valist, elem_type);
+
+ /* We're not returning the value here, but the address.
+ real_part and imag_part are not contiguous, and we know
+ there is space available to pack real_part next to
+ imag_part. float _Complex is not promoted to
+ double _Complex by the default promotion rules that
+ promote float to double. */
+ if (2 * elem_size > UNITS_PER_WORD)
+ abort ();
+
+ real_part = gen_rtx_MEM (elem_mode, real_part);
+ imag_part = gen_rtx_MEM (elem_mode, imag_part);
+
+ dest_real = adjust_address (imag_part, elem_mode, -elem_size);
+ rr = gen_reg_rtx (elem_mode);
+ emit_move_insn (rr, real_part);
+ emit_move_insn (dest_real, rr);
+
+ return XEXP (dest_real, 0);
+ }
+ }
+
+ return std_expand_builtin_va_arg (valist, type);
}
f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
f_fpr = TREE_CHAIN (f_gpr);
- f_ovf = TREE_CHAIN (f_fpr);
+ f_res = TREE_CHAIN (f_fpr);
+ f_ovf = TREE_CHAIN (f_res);
f_sav = TREE_CHAIN (f_ovf);
valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
@@ -3584,20 +4983,25 @@ rs6000_va_arg (valist, type)
sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
size = int_size_in_bytes (type);
- rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+ rsize = (size + 3) / 4;
+ align = 1;
- if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
+ if (AGGREGATE_TYPE_P (type)
+ || TYPE_MODE (type) == TFmode
+ || (!TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type))))
{
- /* Aggregates and long doubles are passed by reference. */
+ /* Aggregates, long doubles, and AltiVec vectors are passed by
+ reference. */
indirect_p = 1;
reg = gpr;
n_reg = 1;
sav_ofs = 0;
sav_scale = 4;
- size = UNITS_PER_WORD;
+ size = 4;
rsize = 1;
}
- else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
+ else if (TARGET_HARD_FLOAT && TARGET_FPRS
+ && (TYPE_MODE (type) == SFmode || TYPE_MODE (type) == DFmode))
{
/* FP args go in FP registers, if present. */
indirect_p = 0;
@@ -3605,6 +5009,8 @@ rs6000_va_arg (valist, type)
n_reg = 1;
sav_ofs = 8*4;
sav_scale = 8;
+ if (TYPE_MODE (type) == DFmode)
+ align = 8;
}
else
{
@@ -3614,38 +5020,43 @@ rs6000_va_arg (valist, type)
n_reg = rsize;
sav_ofs = 0;
sav_scale = 4;
+ if (n_reg == 2)
+ align = 8;
}
- /* Pull the value out of the saved registers ... */
+ /* Pull the value out of the saved registers.... */
- lab_false = gen_label_rtx ();
- lab_over = gen_label_rtx ();
+ lab_over = NULL_RTX;
addr_rtx = gen_reg_rtx (Pmode);
- /* AltiVec vectors never go in registers. */
- if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
+ /* AltiVec vectors never go in registers when -mabi=altivec. */
+ if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
+ align = 16;
+ else
{
- TREE_THIS_VOLATILE (reg) = 1;
- emit_cmp_and_jump_insns
- (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
- GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
- lab_false);
+ lab_false = gen_label_rtx ();
+ lab_over = gen_label_rtx ();
- /* Long long is aligned in the registers. */
- if (n_reg > 1)
+ /* Long long and SPE vectors are aligned in the registers.
+ As are any other 2 gpr item such as complex int due to a
+ historical mistake. */
+ u = reg;
+ if (n_reg == 2)
{
u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
build_int_2 (n_reg - 1, 0));
- u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
- u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
+ u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
TREE_SIDE_EFFECTS (u) = 1;
- expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
+ emit_cmp_and_jump_insns
+ (expand_expr (u, NULL_RTX, QImode, EXPAND_NORMAL),
+ GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
+ lab_false);
+
+ t = sav;
if (sav_ofs)
t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
- else
- t = sav;
u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
build_int_2 (n_reg, 0));
@@ -3666,40 +5077,26 @@ rs6000_va_arg (valist, type)
emit_jump_insn (gen_jump (lab_over));
emit_barrier ();
- }
- emit_label (lab_false);
+ emit_label (lab_false);
+ if (n_reg > 2)
+ {
+ /* Ensure that we don't find any more args in regs.
+ Alignment has taken care of the n_reg == 2 case. */
+ t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
+ TREE_SIDE_EFFECTS (t) = 1;
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+ }
+ }
/* ... otherwise out of the overflow area. */
- /* Make sure we don't find reg 7 for the next int arg.
-
- All AltiVec vectors go in the overflow area. So in the AltiVec
- case we need to get the vectors from the overflow area, but
- remember where the GPRs and FPRs are. */
- if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
- || !TARGET_ALTIVEC))
- {
- t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
- TREE_SIDE_EFFECTS (t) = 1;
- expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- }
-
/* Care for on-stack alignment if needed. */
- if (rsize <= 1)
- t = ovf;
- else
+ t = ovf;
+ if (align != 1)
{
- int align;
-
- /* AltiVec vectors are 16 byte aligned. */
- if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
- align = 15;
- else
- align = 7;
-
- t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
- t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
+ t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (align - 1, 0));
+ t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align, -1));
}
t = save_expr (t);
@@ -3712,7 +5109,8 @@ rs6000_va_arg (valist, type)
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
- emit_label (lab_over);
+ if (lab_over)
+ emit_label (lab_over);
if (indirect_p)
{
@@ -4032,7 +5430,7 @@ static struct builtin_description bdesc_2arg[] =
{ 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
/* Place-holder. Leave as last binary SPE builtin. */
- { 0, CODE_FOR_spe_evxor, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
+ { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
};
/* AltiVec predicates. */
@@ -4099,7 +5497,7 @@ static struct builtin_description bdesc_spe_evsel[] =
{ 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
};
-/* ABS* opreations. */
+/* ABS* operations. */
static const struct builtin_description bdesc_abs[] =
{
@@ -4160,23 +5558,18 @@ static struct builtin_description bdesc_1arg[] =
{ 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
{ 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
{ 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
- { 0, CODE_FOR_spe_evneg, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
+ { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
{ 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
{ 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
{ 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
{ 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
- { 0, CODE_FOR_spe_evsplatfi, "__builtin_spe_evsplatfi", SPE_BUILTIN_EVSPLATFI },
- { 0, CODE_FOR_spe_evsplati, "__builtin_spe_evsplati", SPE_BUILTIN_EVSPLATI },
/* Place-holder. Leave as last unary SPE builtin. */
{ 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
};
static rtx
-rs6000_expand_unop_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+rs6000_expand_unop_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
@@ -4225,10 +5618,7 @@ rs6000_expand_unop_builtin (icode, arglist, target)
}
static rtx
-altivec_expand_abs_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+altivec_expand_abs_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat, scratch1, scratch2;
tree arg0 = TREE_VALUE (arglist);
@@ -4260,10 +5650,7 @@ altivec_expand_abs_builtin (icode, arglist, target)
}
static rtx
-rs6000_expand_binop_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+rs6000_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
@@ -4304,6 +5691,7 @@ rs6000_expand_binop_builtin (icode, arglist, target)
|| icode == CODE_FOR_spe_evrlwi
|| icode == CODE_FOR_spe_evslwi
|| icode == CODE_FOR_spe_evsrwis
+ || icode == CODE_FOR_spe_evsubifw
|| icode == CODE_FOR_spe_evsrwiu)
{
/* Only allow 5-bit unsigned literals. */
@@ -4334,11 +5722,8 @@ rs6000_expand_binop_builtin (icode, arglist, target)
}
static rtx
-altivec_expand_predicate_builtin (icode, opcode, arglist, target)
- enum insn_code icode;
- const char *opcode;
- tree arglist;
- rtx target;
+altivec_expand_predicate_builtin (enum insn_code icode, const char *opcode,
+ tree arglist, rtx target)
{
rtx pat, scratch;
tree cr6_form = TREE_VALUE (arglist);
@@ -4415,9 +5800,53 @@ altivec_expand_predicate_builtin (icode, opcode, arglist, target)
}
static rtx
-altivec_expand_stv_builtin (icode, arglist)
- enum insn_code icode;
- tree arglist;
+altivec_expand_lv_builtin (enum insn_code icode, tree arglist, rtx target)
+{
+ rtx pat, addr;
+ tree arg0 = TREE_VALUE (arglist);
+ tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ enum machine_mode tmode = insn_data[icode].operand[0].mode;
+ enum machine_mode mode0 = Pmode;
+ enum machine_mode mode1 = Pmode;
+ rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+
+ if (icode == CODE_FOR_nothing)
+ /* Builtin not supported on this processor. */
+ return 0;
+
+ /* If we got invalid arguments bail out before generating bad rtl. */
+ if (arg0 == error_mark_node || arg1 == error_mark_node)
+ return const0_rtx;
+
+ if (target == 0
+ || GET_MODE (target) != tmode
+ || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+ target = gen_reg_rtx (tmode);
+
+ op1 = copy_to_mode_reg (mode1, op1);
+
+ if (op0 == const0_rtx)
+ {
+ addr = gen_rtx_MEM (tmode, op1);
+ }
+ else
+ {
+ op0 = copy_to_mode_reg (mode0, op0);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
+ }
+
+ pat = GEN_FCN (icode) (target, addr);
+
+ if (! pat)
+ return 0;
+ emit_insn (pat);
+
+ return target;
+}
+
+static rtx
+spe_expand_stv_builtin (enum insn_code icode, tree arglist)
{
tree arg0 = TREE_VALUE (arglist);
tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
@@ -4450,10 +5879,48 @@ altivec_expand_stv_builtin (icode, arglist)
}
static rtx
-rs6000_expand_ternop_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+altivec_expand_stv_builtin (enum insn_code icode, tree arglist)
+{
+ tree arg0 = TREE_VALUE (arglist);
+ tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
+ tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
+ rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
+ rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
+ rtx pat, addr;
+ enum machine_mode tmode = insn_data[icode].operand[0].mode;
+ enum machine_mode mode1 = Pmode;
+ enum machine_mode mode2 = Pmode;
+
+ /* Invalid arguments. Bail before doing anything stoopid! */
+ if (arg0 == error_mark_node
+ || arg1 == error_mark_node
+ || arg2 == error_mark_node)
+ return const0_rtx;
+
+ if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
+ op0 = copy_to_mode_reg (tmode, op0);
+
+ op2 = copy_to_mode_reg (mode2, op2);
+
+ if (op1 == const0_rtx)
+ {
+ addr = gen_rtx_MEM (tmode, op2);
+ }
+ else
+ {
+ op1 = copy_to_mode_reg (mode1, op1);
+ addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
+ }
+
+ pat = GEN_FCN (icode) (addr, op0);
+ if (pat)
+ emit_insn (pat);
+ return NULL_RTX;
+}
+
+static rtx
+rs6000_expand_ternop_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat;
tree arg0 = TREE_VALUE (arglist);
@@ -4513,10 +5980,7 @@ rs6000_expand_ternop_builtin (icode, arglist, target)
/* Expand the lvx builtins. */
static rtx
-altivec_expand_ld_builtin (exp, target, expandedp)
- tree exp;
- rtx target;
- bool *expandedp;
+altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1);
@@ -4569,10 +6033,8 @@ altivec_expand_ld_builtin (exp, target, expandedp)
/* Expand the stvx builtins. */
static rtx
-altivec_expand_st_builtin (exp, target, expandedp)
- tree exp;
- rtx target ATTRIBUTE_UNUSED;
- bool *expandedp;
+altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
+ bool *expandedp)
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1);
@@ -4623,10 +6085,8 @@ altivec_expand_st_builtin (exp, target, expandedp)
/* Expand the dst builtins. */
static rtx
-altivec_expand_dst_builtin (exp, target, expandedp)
- tree exp;
- rtx target ATTRIBUTE_UNUSED;
- bool *expandedp;
+altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
+ bool *expandedp)
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1);
@@ -4668,7 +6128,7 @@ altivec_expand_dst_builtin (exp, target, expandedp)
}
if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
- op0 = copy_to_mode_reg (mode0, op0);
+ op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
op1 = copy_to_mode_reg (mode1, op1);
@@ -4686,10 +6146,7 @@ altivec_expand_dst_builtin (exp, target, expandedp)
/* Expand the builtin in EXP and store the result in TARGET. Store
true in *EXPANDEDP if we found a builtin to expand. */
static rtx
-altivec_expand_builtin (exp, target, expandedp)
- tree exp;
- rtx target;
- bool *expandedp;
+altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
{
struct builtin_description *d;
struct builtin_description_predicates *dp;
@@ -4806,25 +6263,25 @@ altivec_expand_builtin (exp, target, expandedp)
switch (fcode)
{
case ALTIVEC_BUILTIN_LVSL:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsl,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
arglist, target);
case ALTIVEC_BUILTIN_LVSR:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsr,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
arglist, target);
case ALTIVEC_BUILTIN_LVEBX:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvebx,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
arglist, target);
case ALTIVEC_BUILTIN_LVEHX:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvehx,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
arglist, target);
case ALTIVEC_BUILTIN_LVEWX:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvewx,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
arglist, target);
case ALTIVEC_BUILTIN_LVXL:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvxl,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
arglist, target);
case ALTIVEC_BUILTIN_LVX:
- return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvx,
+ return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
arglist, target);
default:
break;
@@ -4869,10 +6326,7 @@ static struct builtin_description bdesc_2arg_spe[] =
This expands the SPE builtins that are not simple unary and binary
operations. */
static rtx
-spe_expand_builtin (exp, target, expandedp)
- tree exp;
- rtx target;
- bool *expandedp;
+spe_expand_builtin (tree exp, rtx target, bool *expandedp)
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1);
@@ -4908,6 +6362,19 @@ spe_expand_builtin (exp, target, expandedp)
break;
}
+ /* The evsplat*i instructions are not quite generic. */
+ switch (fcode)
+ {
+ case SPE_BUILTIN_EVSPLATFI:
+ return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
+ arglist, target);
+ case SPE_BUILTIN_EVSPLATI:
+ return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
+ arglist, target);
+ default:
+ break;
+ }
+
d = (struct builtin_description *) bdesc_2arg_spe;
for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
if (d->code == fcode)
@@ -4926,33 +6393,33 @@ spe_expand_builtin (exp, target, expandedp)
switch (fcode)
{
case SPE_BUILTIN_EVSTDDX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
case SPE_BUILTIN_EVSTDHX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
case SPE_BUILTIN_EVSTDWX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
case SPE_BUILTIN_EVSTWHEX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
case SPE_BUILTIN_EVSTWHOX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
case SPE_BUILTIN_EVSTWWEX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
case SPE_BUILTIN_EVSTWWOX:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
case SPE_BUILTIN_EVSTDD:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
case SPE_BUILTIN_EVSTDH:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
case SPE_BUILTIN_EVSTDW:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
case SPE_BUILTIN_EVSTWHE:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
case SPE_BUILTIN_EVSTWHO:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
case SPE_BUILTIN_EVSTWWE:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
case SPE_BUILTIN_EVSTWWO:
- return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
+ return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
case SPE_BUILTIN_MFSPEFSCR:
icode = CODE_FOR_spe_mfspefscr;
tmode = insn_data[icode].operand[0].mode;
@@ -4992,10 +6459,7 @@ spe_expand_builtin (exp, target, expandedp)
}
static rtx
-spe_expand_predicate_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+spe_expand_predicate_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat, scratch, tmp;
tree form = TREE_VALUE (arglist);
@@ -5104,10 +6568,7 @@ spe_expand_predicate_builtin (icode, arglist, target)
*/
static rtx
-spe_expand_evsel_builtin (icode, arglist, target)
- enum insn_code icode;
- tree arglist;
- rtx target;
+spe_expand_evsel_builtin (enum insn_code icode, tree arglist, rtx target)
{
rtx pat, scratch;
tree arg0 = TREE_VALUE (arglist);
@@ -5164,12 +6625,9 @@ spe_expand_evsel_builtin (icode, arglist, target)
IGNORE is nonzero if the value is to be ignored. */
static rtx
-rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
+rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1);
@@ -5220,8 +6678,12 @@ rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
}
static void
-rs6000_init_builtins ()
+rs6000_init_builtins (void)
{
+ opaque_V2SI_type_node = copy_node (V2SI_type_node);
+ opaque_V2SF_type_node = copy_node (V2SF_type_node);
+ opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
+
if (TARGET_SPE)
spe_init_builtins ();
if (TARGET_ALTIVEC)
@@ -5232,14 +6694,13 @@ rs6000_init_builtins ()
/* Search through a set of builtins and enable the mask bits.
DESC is an array of builtins.
- SIZE is the totaly number of builtins.
+ SIZE is the total number of builtins.
START is the builtin enum at which to start.
END is the builtin enum at which to end. */
static void
-enable_mask_for_builtins (desc, size, start, end)
- struct builtin_description *desc;
- int size;
- enum rs6000_builtins start, end;
+enable_mask_for_builtins (struct builtin_description *desc, int size,
+ enum rs6000_builtins start,
+ enum rs6000_builtins end)
{
int i;
@@ -5260,52 +6721,51 @@ enable_mask_for_builtins (desc, size, start, end)
}
static void
-spe_init_builtins ()
+spe_init_builtins (void)
{
tree endlink = void_list_node;
tree puint_type_node = build_pointer_type (unsigned_type_node);
tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
- tree pv2si_type_node = build_pointer_type (V2SI_type_node);
struct builtin_description *d;
size_t i;
tree v2si_ftype_4_v2si
= build_function_type
- (V2SI_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
+ (opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
endlink)))));
tree v2sf_ftype_4_v2sf
= build_function_type
- (V2SF_type_node,
- tree_cons (NULL_TREE, V2SF_type_node,
- tree_cons (NULL_TREE, V2SF_type_node,
- tree_cons (NULL_TREE, V2SF_type_node,
- tree_cons (NULL_TREE, V2SF_type_node,
+ (opaque_V2SF_type_node,
+ tree_cons (NULL_TREE, opaque_V2SF_type_node,
+ tree_cons (NULL_TREE, opaque_V2SF_type_node,
+ tree_cons (NULL_TREE, opaque_V2SF_type_node,
+ tree_cons (NULL_TREE, opaque_V2SF_type_node,
endlink)))));
tree int_ftype_int_v2si_v2si
= build_function_type
(integer_type_node,
tree_cons (NULL_TREE, integer_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
endlink))));
tree int_ftype_int_v2sf_v2sf
= build_function_type
(integer_type_node,
tree_cons (NULL_TREE, integer_type_node,
- tree_cons (NULL_TREE, V2SF_type_node,
- tree_cons (NULL_TREE, V2SF_type_node,
+ tree_cons (NULL_TREE, opaque_V2SF_type_node,
+ tree_cons (NULL_TREE, opaque_V2SF_type_node,
endlink))));
tree void_ftype_v2si_puint_int
= build_function_type (void_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
tree_cons (NULL_TREE, puint_type_node,
tree_cons (NULL_TREE,
integer_type_node,
@@ -5313,7 +6773,7 @@ spe_init_builtins ()
tree void_ftype_v2si_puint_char
= build_function_type (void_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
tree_cons (NULL_TREE, puint_type_node,
tree_cons (NULL_TREE,
char_type_node,
@@ -5321,16 +6781,16 @@ spe_init_builtins ()
tree void_ftype_v2si_pv2si_int
= build_function_type (void_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, pv2si_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
tree_cons (NULL_TREE,
integer_type_node,
endlink))));
tree void_ftype_v2si_pv2si_char
= build_function_type (void_type_node,
- tree_cons (NULL_TREE, V2SI_type_node,
- tree_cons (NULL_TREE, pv2si_type_node,
+ tree_cons (NULL_TREE, opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
tree_cons (NULL_TREE,
char_type_node,
endlink))));
@@ -5340,27 +6800,31 @@ spe_init_builtins ()
tree_cons (NULL_TREE, integer_type_node, endlink));
tree int_ftype_void
- = build_function_type (integer_type_node,
- tree_cons (NULL_TREE, void_type_node, endlink));
+ = build_function_type (integer_type_node, endlink);
tree v2si_ftype_pv2si_int
- = build_function_type (V2SI_type_node,
- tree_cons (NULL_TREE, pv2si_type_node,
+ = build_function_type (opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree v2si_ftype_puint_int
- = build_function_type (V2SI_type_node,
+ = build_function_type (opaque_V2SI_type_node,
tree_cons (NULL_TREE, puint_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
tree v2si_ftype_pushort_int
- = build_function_type (V2SI_type_node,
+ = build_function_type (opaque_V2SI_type_node,
tree_cons (NULL_TREE, pushort_type_node,
tree_cons (NULL_TREE, integer_type_node,
endlink)));
+ tree v2si_ftype_signed_char
+ = build_function_type (opaque_V2SI_type_node,
+ tree_cons (NULL_TREE, signed_char_type_node,
+ endlink));
+
/* The initialization of the simple binary and unary builtins is
done in rs6000_common_init_builtins, but we have to enable the
mask bits here manually because we have run out of `target_flags'
@@ -5383,6 +6847,10 @@ spe_init_builtins ()
SPE_BUILTIN_EVSEL_CMPGTS,
SPE_BUILTIN_EVSEL_FSTSTEQ);
+ (*lang_hooks.decls.pushdecl)
+ (build_decl (TYPE_DECL, get_identifier ("__ev64_opaque__"),
+ opaque_V2SI_type_node));
+
/* Initialize irregular SPE builtins. */
def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
@@ -5401,6 +6869,8 @@ spe_init_builtins ()
def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
+ def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
+ def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
/* Loads. */
def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
@@ -5470,7 +6940,7 @@ spe_init_builtins ()
}
static void
-altivec_init_builtins ()
+altivec_init_builtins (void)
{
struct builtin_description *d;
struct builtin_description_predicates *dp;
@@ -5522,27 +6992,27 @@ altivec_init_builtins ()
tree void_ftype_qi
= build_function_type_list (void_type_node, char_type_node, NULL_TREE);
- tree v16qi_ftype_int_pcvoid
+ tree v16qi_ftype_long_pcvoid
= build_function_type_list (V16QI_type_node,
- integer_type_node, pcvoid_type_node, NULL_TREE);
- tree v8hi_ftype_int_pcvoid
+ long_integer_type_node, pcvoid_type_node, NULL_TREE);
+ tree v8hi_ftype_long_pcvoid
= build_function_type_list (V8HI_type_node,
- integer_type_node, pcvoid_type_node, NULL_TREE);
- tree v4si_ftype_int_pcvoid
+ long_integer_type_node, pcvoid_type_node, NULL_TREE);
+ tree v4si_ftype_long_pcvoid
= build_function_type_list (V4SI_type_node,
- integer_type_node, pcvoid_type_node, NULL_TREE);
+ long_integer_type_node, pcvoid_type_node, NULL_TREE);
- tree void_ftype_v4si_int_pvoid
+ tree void_ftype_v4si_long_pvoid
= build_function_type_list (void_type_node,
- V4SI_type_node, integer_type_node,
+ V4SI_type_node, long_integer_type_node,
pvoid_type_node, NULL_TREE);
- tree void_ftype_v16qi_int_pvoid
+ tree void_ftype_v16qi_long_pvoid
= build_function_type_list (void_type_node,
- V16QI_type_node, integer_type_node,
+ V16QI_type_node, long_integer_type_node,
pvoid_type_node, NULL_TREE);
- tree void_ftype_v8hi_int_pvoid
+ tree void_ftype_v8hi_long_pvoid
= build_function_type_list (void_type_node,
- V8HI_type_node, integer_type_node,
+ V8HI_type_node, long_integer_type_node,
pvoid_type_node, NULL_TREE);
tree int_ftype_int_v8hi_v8hi
= build_function_type_list (integer_type_node,
@@ -5589,18 +7059,18 @@ altivec_init_builtins ()
def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVSL);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVSR);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEBX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEHX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEWX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVXL);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
- def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
+ def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
/* Add the DST variants. */
d = (struct builtin_description *) bdesc_dst;
@@ -5669,7 +7139,7 @@ altivec_init_builtins ()
}
static void
-rs6000_common_init_builtins ()
+rs6000_common_init_builtins (void)
{
struct builtin_description *d;
size_t i;
@@ -5702,43 +7172,48 @@ rs6000_common_init_builtins ()
= build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
tree v2si_ftype_v2si_v2si
- = build_function_type_list (V2SI_type_node,
- V2SI_type_node, V2SI_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SI_type_node,
+ opaque_V2SI_type_node,
+ opaque_V2SI_type_node, NULL_TREE);
tree v2sf_ftype_v2sf_v2sf
- = build_function_type_list (V2SF_type_node,
- V2SF_type_node, V2SF_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SF_type_node,
+ opaque_V2SF_type_node,
+ opaque_V2SF_type_node, NULL_TREE);
tree v2si_ftype_int_int
- = build_function_type_list (V2SI_type_node,
+ = build_function_type_list (opaque_V2SI_type_node,
integer_type_node, integer_type_node,
NULL_TREE);
tree v2si_ftype_v2si
- = build_function_type_list (V2SI_type_node, V2SI_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SI_type_node,
+ opaque_V2SI_type_node, NULL_TREE);
tree v2sf_ftype_v2sf
- = build_function_type_list (V2SF_type_node,
- V2SF_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SF_type_node,
+ opaque_V2SF_type_node, NULL_TREE);
tree v2sf_ftype_v2si
- = build_function_type_list (V2SF_type_node,
- V2SI_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SF_type_node,
+ opaque_V2SI_type_node, NULL_TREE);
tree v2si_ftype_v2sf
- = build_function_type_list (V2SI_type_node,
- V2SF_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SI_type_node,
+ opaque_V2SF_type_node, NULL_TREE);
tree v2si_ftype_v2si_char
- = build_function_type_list (V2SI_type_node,
- V2SI_type_node, char_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SI_type_node,
+ opaque_V2SI_type_node,
+ char_type_node, NULL_TREE);
tree v2si_ftype_int_char
- = build_function_type_list (V2SI_type_node,
+ = build_function_type_list (opaque_V2SI_type_node,
integer_type_node, char_type_node, NULL_TREE);
tree v2si_ftype_char
- = build_function_type_list (V2SI_type_node, char_type_node, NULL_TREE);
+ = build_function_type_list (opaque_V2SI_type_node,
+ char_type_node, NULL_TREE);
tree int_ftype_int_int
= build_function_type_list (integer_type_node,
@@ -6122,6 +7597,57 @@ rs6000_common_init_builtins ()
}
}
+static void
+rs6000_init_libfuncs (void)
+{
+ if (!TARGET_HARD_FLOAT)
+ return;
+
+ if (DEFAULT_ABI != ABI_V4)
+ {
+ if (TARGET_XCOFF && ! TARGET_POWER2 && ! TARGET_POWERPC)
+ {
+ /* AIX library routines for float->int conversion. */
+ set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
+ set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
+ set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
+ set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
+ }
+
+ /* Standard AIX/Darwin/64-bit SVR4 quad floating point routines. */
+ set_optab_libfunc (add_optab, TFmode, "_xlqadd");
+ set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
+ set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
+ set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
+ }
+ else
+ {
+ /* 32-bit SVR4 quad floating point routines. */
+
+ set_optab_libfunc (add_optab, TFmode, "_q_add");
+ set_optab_libfunc (sub_optab, TFmode, "_q_sub");
+ set_optab_libfunc (neg_optab, TFmode, "_q_neg");
+ set_optab_libfunc (smul_optab, TFmode, "_q_mul");
+ set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
+ if (TARGET_PPC_GPOPT || TARGET_POWER2)
+ set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
+
+ set_optab_libfunc (eq_optab, TFmode, "_q_feq");
+ set_optab_libfunc (ne_optab, TFmode, "_q_fne");
+ set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
+ set_optab_libfunc (ge_optab, TFmode, "_q_fge");
+ set_optab_libfunc (lt_optab, TFmode, "_q_flt");
+ set_optab_libfunc (le_optab, TFmode, "_q_fle");
+
+ set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
+ set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
+ set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
+ set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
+ set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
+ set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
+ set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
+ }
+}
/* Expand a block move operation, and return 1 if successful. Return 0
if we should let the compiler generate normal code.
@@ -6134,8 +7660,7 @@ rs6000_common_init_builtins ()
#define MAX_MOVE_REG 4
int
-expand_block_move (operands)
- rtx operands[];
+expand_block_move (rtx operands[])
{
rtx orig_dest = operands[0];
rtx orig_src = operands[1];
@@ -6146,6 +7671,8 @@ expand_block_move (operands)
int bytes;
int offset;
int move_bytes;
+ rtx stores[MAX_MOVE_REG];
+ int num_reg = 0;
/* If this is not a fixed size move, just call memcpy */
if (! constp)
@@ -6166,182 +7693,130 @@ expand_block_move (operands)
if (bytes > (TARGET_POWERPC64 ? 64 : 32))
return 0;
- if (TARGET_STRING) /* string instructions are available */
- {
- for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
- {
- union {
- rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx));
- rtx (*mov) PARAMS ((rtx, rtx));
- } gen_func;
- enum machine_mode mode = BLKmode;
- rtx src, dest;
-
- if (bytes > 24 /* move up to 32 bytes at a time */
- && ! fixed_regs[5]
- && ! fixed_regs[6]
- && ! fixed_regs[7]
- && ! fixed_regs[8]
- && ! fixed_regs[9]
- && ! fixed_regs[10]
- && ! fixed_regs[11]
- && ! fixed_regs[12])
- {
- move_bytes = (bytes > 32) ? 32 : bytes;
- gen_func.movstrsi = gen_movstrsi_8reg;
- }
- else if (bytes > 16 /* move up to 24 bytes at a time */
- && ! fixed_regs[5]
- && ! fixed_regs[6]
- && ! fixed_regs[7]
- && ! fixed_regs[8]
- && ! fixed_regs[9]
- && ! fixed_regs[10])
- {
- move_bytes = (bytes > 24) ? 24 : bytes;
- gen_func.movstrsi = gen_movstrsi_6reg;
- }
- else if (bytes > 8 /* move up to 16 bytes at a time */
- && ! fixed_regs[5]
- && ! fixed_regs[6]
- && ! fixed_regs[7]
- && ! fixed_regs[8])
- {
- move_bytes = (bytes > 16) ? 16 : bytes;
- gen_func.movstrsi = gen_movstrsi_4reg;
- }
- else if (bytes >= 8 && TARGET_POWERPC64
- /* 64-bit loads and stores require word-aligned
- displacements. */
- && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
- {
- move_bytes = 8;
- mode = DImode;
- gen_func.mov = gen_movdi;
- }
- else if (bytes > 4 && !TARGET_POWERPC64)
- { /* move up to 8 bytes at a time */
- move_bytes = (bytes > 8) ? 8 : bytes;
- gen_func.movstrsi = gen_movstrsi_2reg;
- }
- else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
- { /* move 4 bytes */
- move_bytes = 4;
- mode = SImode;
- gen_func.mov = gen_movsi;
- }
- else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
- { /* move 2 bytes */
- move_bytes = 2;
- mode = HImode;
- gen_func.mov = gen_movhi;
- }
- else if (bytes == 1) /* move 1 byte */
- {
- move_bytes = 1;
- mode = QImode;
- gen_func.mov = gen_movqi;
- }
- else
- { /* move up to 4 bytes at a time */
- move_bytes = (bytes > 4) ? 4 : bytes;
- gen_func.movstrsi = gen_movstrsi_1reg;
- }
-
- src = adjust_address (orig_src, mode, offset);
- dest = adjust_address (orig_dest, mode, offset);
-
- if (mode == BLKmode)
- {
- /* Move the address into scratch registers. The movstrsi
- patterns require zero offset. */
- if (!REG_P (XEXP (src, 0)))
- {
- rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
- src = replace_equiv_address (src, src_reg);
- }
- set_mem_size (src, GEN_INT (move_bytes));
-
- if (!REG_P (XEXP (dest, 0)))
- {
- rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
- dest = replace_equiv_address (dest, dest_reg);
- }
- set_mem_size (dest, GEN_INT (move_bytes));
-
- emit_insn ((*gen_func.movstrsi) (dest, src,
- GEN_INT (move_bytes & 31),
- align_rtx));
- }
- else
- {
- rtx tmp_reg = gen_reg_rtx (mode);
-
- emit_insn ((*gen_func.mov) (tmp_reg, src));
- emit_insn ((*gen_func.mov) (dest, tmp_reg));
- }
- }
- }
-
- else /* string instructions not available */
+ for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
{
- rtx stores[MAX_MOVE_REG];
- int num_reg = 0;
- int i;
+ union {
+ rtx (*movstrsi) (rtx, rtx, rtx, rtx);
+ rtx (*mov) (rtx, rtx);
+ } gen_func;
+ enum machine_mode mode = BLKmode;
+ rtx src, dest;
+
+ if (TARGET_STRING
+ && bytes > 24 /* move up to 32 bytes at a time */
+ && ! fixed_regs[5]
+ && ! fixed_regs[6]
+ && ! fixed_regs[7]
+ && ! fixed_regs[8]
+ && ! fixed_regs[9]
+ && ! fixed_regs[10]
+ && ! fixed_regs[11]
+ && ! fixed_regs[12])
+ {
+ move_bytes = (bytes > 32) ? 32 : bytes;
+ gen_func.movstrsi = gen_movstrsi_8reg;
+ }
+ else if (TARGET_STRING
+ && bytes > 16 /* move up to 24 bytes at a time */
+ && ! fixed_regs[5]
+ && ! fixed_regs[6]
+ && ! fixed_regs[7]
+ && ! fixed_regs[8]
+ && ! fixed_regs[9]
+ && ! fixed_regs[10])
+ {
+ move_bytes = (bytes > 24) ? 24 : bytes;
+ gen_func.movstrsi = gen_movstrsi_6reg;
+ }
+ else if (TARGET_STRING
+ && bytes > 8 /* move up to 16 bytes at a time */
+ && ! fixed_regs[5]
+ && ! fixed_regs[6]
+ && ! fixed_regs[7]
+ && ! fixed_regs[8])
+ {
+ move_bytes = (bytes > 16) ? 16 : bytes;
+ gen_func.movstrsi = gen_movstrsi_4reg;
+ }
+ else if (bytes >= 8 && TARGET_POWERPC64
+ /* 64-bit loads and stores require word-aligned
+ displacements. */
+ && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
+ {
+ move_bytes = 8;
+ mode = DImode;
+ gen_func.mov = gen_movdi;
+ }
+ else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
+ { /* move up to 8 bytes at a time */
+ move_bytes = (bytes > 8) ? 8 : bytes;
+ gen_func.movstrsi = gen_movstrsi_2reg;
+ }
+ else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
+ { /* move 4 bytes */
+ move_bytes = 4;
+ mode = SImode;
+ gen_func.mov = gen_movsi;
+ }
+ else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
+ { /* move 2 bytes */
+ move_bytes = 2;
+ mode = HImode;
+ gen_func.mov = gen_movhi;
+ }
+ else if (TARGET_STRING && bytes > 1)
+ { /* move up to 4 bytes at a time */
+ move_bytes = (bytes > 4) ? 4 : bytes;
+ gen_func.movstrsi = gen_movstrsi_1reg;
+ }
+ else /* move 1 byte at a time */
+ {
+ move_bytes = 1;
+ mode = QImode;
+ gen_func.mov = gen_movqi;
+ }
+
+ src = adjust_address (orig_src, mode, offset);
+ dest = adjust_address (orig_dest, mode, offset);
+
+ if (mode != BLKmode)
+ {
+ rtx tmp_reg = gen_reg_rtx (mode);
+
+ emit_insn ((*gen_func.mov) (tmp_reg, src));
+ stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
+ }
- for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
+ if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
{
- rtx (*gen_mov_func) PARAMS ((rtx, rtx));
- enum machine_mode mode;
- rtx src, dest, tmp_reg;
+ int i;
+ for (i = 0; i < num_reg; i++)
+ emit_insn (stores[i]);
+ num_reg = 0;
+ }
- /* Generate the appropriate load and store, saving the stores
- for later. */
- if (bytes >= 8 && TARGET_POWERPC64
- /* 64-bit loads and stores require word-aligned
- displacements. */
- && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
- {
- move_bytes = 8;
- mode = DImode;
- gen_mov_func = gen_movdi;
- }
- else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
- {
- move_bytes = 4;
- mode = SImode;
- gen_mov_func = gen_movsi;
- }
- else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
- {
- move_bytes = 2;
- mode = HImode;
- gen_mov_func = gen_movhi;
- }
- else
+ if (mode == BLKmode)
+ {
+ /* Move the address into scratch registers. The movstrsi
+ patterns require zero offset. */
+ if (!REG_P (XEXP (src, 0)))
{
- move_bytes = 1;
- mode = QImode;
- gen_mov_func = gen_movqi;
+ rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
+ src = replace_equiv_address (src, src_reg);
}
-
- src = adjust_address (orig_src, mode, offset);
- dest = adjust_address (orig_dest, mode, offset);
- tmp_reg = gen_reg_rtx (mode);
-
- emit_insn ((*gen_mov_func) (tmp_reg, src));
- stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg);
-
- if (num_reg >= MAX_MOVE_REG)
+ set_mem_size (src, GEN_INT (move_bytes));
+
+ if (!REG_P (XEXP (dest, 0)))
{
- for (i = 0; i < num_reg; i++)
- emit_insn (stores[i]);
- num_reg = 0;
+ rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
+ dest = replace_equiv_address (dest, dest_reg);
}
+ set_mem_size (dest, GEN_INT (move_bytes));
+
+ emit_insn ((*gen_func.movstrsi) (dest, src,
+ GEN_INT (move_bytes & 31),
+ align_rtx));
}
-
- for (i = 0; i < num_reg; i++)
- emit_insn (stores[i]);
}
return 1;
@@ -6352,9 +7827,7 @@ expand_block_move (operands)
PARALLEL and the first section will be tested. */
int
-load_multiple_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int count = XVECLEN (op, 0);
unsigned int dest_regno;
@@ -6395,9 +7868,7 @@ load_multiple_operation (op, mode)
is a CLOBBER. It will be tested later. */
int
-store_multiple_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int count = XVECLEN (op, 0) - 1;
unsigned int src_regno;
@@ -6440,8 +7911,7 @@ store_multiple_operation (op, mode)
operands[2] is the first destination register. */
const char *
-rs6000_output_load_multiple (operands)
- rtx operands[3];
+rs6000_output_load_multiple (rtx operands[3])
{
/* We have to handle the case where the pseudo used to contain the address
is assigned to one of the output registers. */
@@ -6495,9 +7965,7 @@ rs6000_output_load_multiple (operands)
/* Return 1 for a parallel vrsave operation. */
int
-vrsave_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+vrsave_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int count = XVECLEN (op, 0);
unsigned int dest_regno, src_regno;
@@ -6528,12 +7996,58 @@ vrsave_operation (op, mode)
return 1;
}
+/* Return 1 for an PARALLEL suitable for mfcr. */
+
+int
+mfcr_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ int count = XVECLEN (op, 0);
+ int i;
+
+ /* Perform a quick check so we don't blow up below. */
+ if (count < 1
+ || GET_CODE (XVECEXP (op, 0, 0)) != SET
+ || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
+ || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
+ return 0;
+
+ for (i = 0; i < count; i++)
+ {
+ rtx exp = XVECEXP (op, 0, i);
+ rtx unspec;
+ int maskval;
+ rtx src_reg;
+
+ src_reg = XVECEXP (SET_SRC (exp), 0, 0);
+
+ if (GET_CODE (src_reg) != REG
+ || GET_MODE (src_reg) != CCmode
+ || ! CR_REGNO_P (REGNO (src_reg)))
+ return 0;
+
+ if (GET_CODE (exp) != SET
+ || GET_CODE (SET_DEST (exp)) != REG
+ || GET_MODE (SET_DEST (exp)) != SImode
+ || ! INT_REGNO_P (REGNO (SET_DEST (exp))))
+ return 0;
+ unspec = SET_SRC (exp);
+ maskval = 1 << (MAX_CR_REGNO - REGNO (src_reg));
+
+ if (GET_CODE (unspec) != UNSPEC
+ || XINT (unspec, 1) != UNSPEC_MOVESI_FROM_CR
+ || XVECLEN (unspec, 0) != 2
+ || XVECEXP (unspec, 0, 0) != src_reg
+ || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
+ || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
+ return 0;
+ }
+ return 1;
+}
+
/* Return 1 for an PARALLEL suitable for mtcrf. */
int
-mtcrf_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+mtcrf_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int count = XVECLEN (op, 0);
int i;
@@ -6567,7 +8081,7 @@ mtcrf_operation (op, mode)
maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
if (GET_CODE (unspec) != UNSPEC
- || XINT (unspec, 1) != 20
+ || XINT (unspec, 1) != UNSPEC_MOVESI_TO_CR
|| XVECLEN (unspec, 0) != 2
|| XVECEXP (unspec, 0, 0) != src_reg
|| GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
@@ -6580,9 +8094,7 @@ mtcrf_operation (op, mode)
/* Return 1 for an PARALLEL suitable for lmw. */
int
-lmw_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+lmw_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int count = XVECLEN (op, 0);
unsigned int dest_regno;
@@ -6605,14 +8117,14 @@ lmw_operation (op, mode)
|| count != 32 - (int) dest_regno)
return 0;
- if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
+ if (legitimate_indirect_address_p (src_addr, 0))
{
offset = 0;
base_regno = REGNO (src_addr);
if (base_regno == 0)
return 0;
}
- else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
+ else if (legitimate_offset_address_p (SImode, src_addr, 0))
{
offset = INTVAL (XEXP (src_addr, 1));
base_regno = REGNO (XEXP (src_addr, 0));
@@ -6635,12 +8147,12 @@ lmw_operation (op, mode)
|| GET_MODE (SET_SRC (elt)) != SImode)
return 0;
newaddr = XEXP (SET_SRC (elt), 0);
- if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
+ if (legitimate_indirect_address_p (newaddr, 0))
{
newoffset = 0;
addr_reg = newaddr;
}
- else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
+ else if (legitimate_offset_address_p (SImode, newaddr, 0))
{
addr_reg = XEXP (newaddr, 0);
newoffset = INTVAL (XEXP (newaddr, 1));
@@ -6658,9 +8170,7 @@ lmw_operation (op, mode)
/* Return 1 for an PARALLEL suitable for stmw. */
int
-stmw_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+stmw_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
int count = XVECLEN (op, 0);
unsigned int src_regno;
@@ -6683,14 +8193,14 @@ stmw_operation (op, mode)
|| count != 32 - (int) src_regno)
return 0;
- if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
+ if (legitimate_indirect_address_p (dest_addr, 0))
{
offset = 0;
base_regno = REGNO (dest_addr);
if (base_regno == 0)
return 0;
}
- else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
+ else if (legitimate_offset_address_p (SImode, dest_addr, 0))
{
offset = INTVAL (XEXP (dest_addr, 1));
base_regno = REGNO (XEXP (dest_addr, 0));
@@ -6713,12 +8223,12 @@ stmw_operation (op, mode)
|| GET_MODE (SET_DEST (elt)) != SImode)
return 0;
newaddr = XEXP (SET_DEST (elt), 0);
- if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
+ if (legitimate_indirect_address_p (newaddr, 0))
{
newoffset = 0;
addr_reg = newaddr;
}
- else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
+ else if (legitimate_offset_address_p (SImode, newaddr, 0))
{
addr_reg = XEXP (newaddr, 0);
newoffset = INTVAL (XEXP (newaddr, 1));
@@ -6738,9 +8248,7 @@ stmw_operation (op, mode)
never be generated. */
static void
-validate_condition_mode (code, mode)
- enum rtx_code code;
- enum machine_mode mode;
+validate_condition_mode (enum rtx_code code, enum machine_mode mode)
{
if (GET_RTX_CLASS (code) != '<'
|| GET_MODE_CLASS (mode) != MODE_CC)
@@ -6763,9 +8271,8 @@ validate_condition_mode (code, mode)
abort ();
/* These should never be generated except for
- flag_unsafe_math_optimizations and flag_finite_math_only. */
+ flag_finite_math_only. */
if (mode == CCFPmode
- && ! flag_unsafe_math_optimizations
&& ! flag_finite_math_only
&& (code == LE || code == GE
|| code == UNEQ || code == LTGT
@@ -6782,9 +8289,7 @@ validate_condition_mode (code, mode)
We only check the opcode against the mode of the CC value here. */
int
-branch_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+branch_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
enum machine_mode cc_mode;
@@ -6806,9 +8311,7 @@ branch_comparison_operator (op, mode)
is set. */
int
-branch_positive_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+branch_positive_comparison_operator (rtx op, enum machine_mode mode)
{
enum rtx_code code;
@@ -6817,45 +8320,21 @@ branch_positive_comparison_operator (op, mode)
code = GET_CODE (op);
return (code == EQ || code == LT || code == GT
- || (TARGET_SPE && TARGET_HARD_FLOAT && !TARGET_FPRS && code == NE)
|| code == LTU || code == GTU
|| code == UNORDERED);
}
-/* Return 1 if OP is a comparison operation that is valid for an scc insn.
- We check the opcode against the mode of the CC value and disallow EQ or
- NE comparisons for integers. */
+/* Return 1 if OP is a comparison operation that is valid for an scc
+ insn: it must be a positive comparison. */
int
-scc_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+scc_comparison_operator (rtx op, enum machine_mode mode)
{
- enum rtx_code code = GET_CODE (op);
- enum machine_mode cc_mode;
-
- if (GET_MODE (op) != mode && mode != VOIDmode)
- return 0;
-
- if (GET_RTX_CLASS (code) != '<')
- return 0;
-
- cc_mode = GET_MODE (XEXP (op, 0));
- if (GET_MODE_CLASS (cc_mode) != MODE_CC)
- return 0;
-
- validate_condition_mode (code, cc_mode);
-
- if (code == NE && cc_mode != CCFPmode)
- return 0;
-
- return 1;
+ return branch_positive_comparison_operator (op, mode);
}
int
-trap_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+trap_comparison_operator (rtx op, enum machine_mode mode)
{
if (mode != VOIDmode && mode != GET_MODE (op))
return 0;
@@ -6863,27 +8342,21 @@ trap_comparison_operator (op, mode)
}
int
-boolean_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+boolean_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
return (code == AND || code == IOR || code == XOR);
}
int
-boolean_or_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+boolean_or_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
return (code == IOR || code == XOR);
}
int
-min_max_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+min_max_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
return (code == SMIN || code == SMAX || code == UMIN || code == UMAX);
@@ -6894,9 +8367,7 @@ min_max_operator (op, mode)
left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
int
-includes_lshift_p (shiftop, andop)
- rtx shiftop;
- rtx andop;
+includes_lshift_p (rtx shiftop, rtx andop)
{
unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
@@ -6908,9 +8379,7 @@ includes_lshift_p (shiftop, andop)
/* Similar, but for right shift. */
int
-includes_rshift_p (shiftop, andop)
- rtx shiftop;
- rtx andop;
+includes_rshift_p (rtx shiftop, rtx andop)
{
unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
@@ -6921,12 +8390,10 @@ includes_rshift_p (shiftop, andop)
/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
to perform a left shift. It must have exactly SHIFTOP least
- signifigant 0's, then one or more 1's, then zero or more 0's. */
+ significant 0's, then one or more 1's, then zero or more 0's. */
int
-includes_rldic_lshift_p (shiftop, andop)
- rtx shiftop;
- rtx andop;
+includes_rldic_lshift_p (rtx shiftop, rtx andop)
{
if (GET_CODE (andop) == CONST_INT)
{
@@ -6939,7 +8406,7 @@ includes_rldic_lshift_p (shiftop, andop)
shift_mask = ~0;
shift_mask <<= INTVAL (shiftop);
- /* Find the least signifigant one bit. */
+ /* Find the least significant one bit. */
lsb = c & -c;
/* It must coincide with the LSB of the shift mask. */
@@ -7016,12 +8483,10 @@ includes_rldic_lshift_p (shiftop, andop)
/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
to perform a left shift. It must have SHIFTOP or more least
- signifigant 0's, with the remainder of the word 1's. */
+ significant 0's, with the remainder of the word 1's. */
int
-includes_rldicr_lshift_p (shiftop, andop)
- rtx shiftop;
- rtx andop;
+includes_rldicr_lshift_p (rtx shiftop, rtx andop)
{
if (GET_CODE (andop) == CONST_INT)
{
@@ -7031,7 +8496,7 @@ includes_rldicr_lshift_p (shiftop, andop)
shift_mask <<= INTVAL (shiftop);
c = INTVAL (andop);
- /* Find the least signifigant one bit. */
+ /* Find the least significant one bit. */
lsb = c & -c;
/* It must be covered by the shift mask.
@@ -7093,8 +8558,7 @@ includes_rldicr_lshift_p (shiftop, andop)
abort if we are passed pseudo registers. */
int
-registers_ok_for_quad_peep (reg1, reg2)
- rtx reg1, reg2;
+registers_ok_for_quad_peep (rtx reg1, rtx reg2)
{
/* We might have been passed a SUBREG. */
if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
@@ -7108,9 +8572,7 @@ registers_ok_for_quad_peep (reg1, reg2)
(addr2 == addr1 + 8). */
int
-addrs_ok_for_quad_peep (addr1, addr2)
- rtx addr1;
- rtx addr2;
+addrs_ok_for_quad_peep (rtx addr1, rtx addr2)
{
unsigned int reg1;
int offset1;
@@ -7139,7 +8601,11 @@ addrs_ok_for_quad_peep (addr1, addr2)
offset1 = 0;
}
- /* Make sure the second address is a (mem (plus (reg) (const_int))). */
+ /* Make sure the second address is a (mem (plus (reg) (const_int)))
+ or if it is (mem (reg)) then make sure that offset1 is -8 and the same
+ register as addr1. */
+ if (offset1 == -8 && GET_CODE (addr2) == REG && reg1 == REGNO (addr2))
+ return 1;
if (GET_CODE (addr2) != PLUS)
return 0;
@@ -7161,17 +8627,22 @@ addrs_ok_for_quad_peep (addr1, addr2)
/* Return the register class of a scratch register needed to copy IN into
or out of a register in CLASS in MODE. If it can be done directly,
- NO_REGS is returned. */
+ NO_REGS is returned. INP is nonzero if we are loading the reg, zero
+ for storing. */
enum reg_class
-secondary_reload_class (class, mode, in)
- enum reg_class class;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx in;
+secondary_reload_class (enum reg_class class,
+ enum machine_mode mode,
+ rtx in,
+ int inp)
{
int regno;
- if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN && flag_pic))
+ if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
+#if TARGET_MACHO
+ && MACHOPIC_INDIRECT
+#endif
+ ))
{
/* We cannot copy a symbolic operand directly into anything
other than BASE_REGS for TARGET_ELF. So indicate that a
@@ -7188,6 +8659,14 @@ secondary_reload_class (class, mode, in)
return BASE_REGS;
}
+ /* A 64-bit gpr load or store using an offset that isn't a multiple of
+ four needs a secondary reload. */
+ if (TARGET_POWERPC64
+ && GET_MODE_UNIT_SIZE (mode) >= 8
+ && (!inp || class != BASE_REGS)
+ && invalid_gpr_mem (in, mode))
+ return BASE_REGS;
+
if (GET_CODE (in) == REG)
{
regno = REGNO (in);
@@ -7241,9 +8720,7 @@ secondary_reload_class (class, mode, in)
Return -1 if OP isn't a valid comparison for some reason. */
int
-ccr_bit (op, scc_p)
- rtx op;
- int scc_p;
+ccr_bit (rtx op, int scc_p)
{
enum rtx_code code = GET_CODE (op);
enum machine_mode cc_mode;
@@ -7266,15 +8743,17 @@ ccr_bit (op, scc_p)
validate_condition_mode (code, cc_mode);
+ /* When generating a sCOND operation, only positive conditions are
+ allowed. */
+ if (scc_p && code != EQ && code != GT && code != LT && code != UNORDERED
+ && code != GTU && code != LTU)
+ abort ();
+
switch (code)
{
case NE:
- if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
- return base_bit + 1;
return scc_p ? base_bit + 3 : base_bit + 2;
case EQ:
- if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
- return base_bit + 1;
return base_bit + 2;
case GT: case GTU: case UNLE:
return base_bit + 1;
@@ -7300,8 +8779,7 @@ ccr_bit (op, scc_p)
/* Return the GOT register. */
struct rtx_def *
-rs6000_got_register (value)
- rtx value ATTRIBUTE_UNUSED;
+rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
{
/* The second flow pass currently (June 1999) can't update
regs_ever_live without disturbing other parts of the compiler, so
@@ -7319,7 +8797,7 @@ rs6000_got_register (value)
from push_function_context. */
static struct machine_function *
-rs6000_init_machine_status ()
+rs6000_init_machine_status (void)
{
return ggc_alloc_cleared (sizeof (machine_function));
}
@@ -7333,8 +8811,7 @@ rs6000_init_machine_status ()
(GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
int
-extract_MB (op)
- rtx op;
+extract_MB (rtx op)
{
int i;
unsigned long val = INT_LOWPART (op);
@@ -7367,8 +8844,7 @@ extract_MB (op)
}
int
-extract_ME (op)
- rtx op;
+extract_ME (rtx op)
{
int i;
unsigned long val = INT_LOWPART (op);
@@ -7401,6 +8877,46 @@ extract_ME (op)
return i;
}
+/* Locate some local-dynamic symbol still in use by this function
+ so that we can print its name in some tls_ld pattern. */
+
+static const char *
+rs6000_get_some_local_dynamic_name (void)
+{
+ rtx insn;
+
+ if (cfun->machine->some_ld_name)
+ return cfun->machine->some_ld_name;
+
+ for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
+ if (INSN_P (insn)
+ && for_each_rtx (&PATTERN (insn),
+ rs6000_get_some_local_dynamic_name_1, 0))
+ return cfun->machine->some_ld_name;
+
+ abort ();
+}
+
+/* Helper function for rs6000_get_some_local_dynamic_name. */
+
+static int
+rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
+{
+ rtx x = *px;
+
+ if (GET_CODE (x) == SYMBOL_REF)
+ {
+ const char *str = XSTR (x, 0);
+ if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
+ {
+ cfun->machine->some_ld_name = str;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/* Print an operand. Recognize special options, documented below. */
#if TARGET_ELF
@@ -7412,10 +8928,7 @@ extract_ME (op)
#endif
void
-print_operand (file, x, code)
- FILE *file;
- rtx x;
- int code;
+print_operand (FILE *file, rtx x, int code)
{
int i;
HOST_WIDE_INT val;
@@ -7460,40 +8973,24 @@ print_operand (file, x, code)
/* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
output_operand. */
- case 'D':
- /* There used to be a comment for 'C' reading "This is an
- optional cror needed for certain floating-point
- comparisons. Otherwise write nothing." */
-
- /* Similar, except that this is for an scc, so we must be able to
- encode the test in a single bit that is one. We do the above
- for any LE, GE, GEU, or LEU and invert the bit for NE. */
- if (GET_CODE (x) == LE || GET_CODE (x) == GE
- || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
- {
- int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
-
- fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
- base_bit + 2,
- base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
- }
+ case 'c':
+ /* X is a CR register. Print the number of the GT bit of the CR. */
+ if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
+ output_operand_lossage ("invalid %%E value");
+ else
+ fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
+ return;
- else if (GET_CODE (x) == NE)
- {
- int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
+ case 'D':
+ /* Like 'J' but get to the GT bit. */
+ if (GET_CODE (x) != REG)
+ abort ();
- fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
- base_bit + 2, base_bit + 2);
- }
- else if (TARGET_SPE && TARGET_HARD_FLOAT
- && GET_CODE (x) == EQ
- && GET_MODE (XEXP (x, 0)) == CCFPmode)
- {
- int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
+ /* Bit 1 is GT bit. */
+ i = 4 * (REGNO (x) - CR0_REGNO) + 1;
- fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 1,
- base_bit + 1, base_bit + 1);
- }
+ /* If we want bit 31, write a shift count of zero, not 32. */
+ fprintf (file, "%d", i == 31 ? 0 : i + 1);
return;
case 'E':
@@ -7731,6 +9228,13 @@ print_operand (file, x, code)
}
return;
+ case 'Q':
+ if (TARGET_MFCRF)
+ fputc (',',file);
+ /* FALLTHRU */
+ else
+ return;
+
case 'R':
/* X is a CR register. Print the mask for `mtcrf'. */
if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
@@ -7758,13 +9262,17 @@ print_operand (file, x, code)
if (uval & 1) /* Clear Left */
{
- uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
+#if HOST_BITS_PER_WIDE_INT > 64
+ uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
+#endif
i = 64;
}
else /* Clear Right */
{
uval = ~uval;
- uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
+#if HOST_BITS_PER_WIDE_INT > 64
+ uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
+#endif
i = 63;
}
while (uval != 0)
@@ -7907,7 +9415,7 @@ print_operand (file, x, code)
case 'X':
if (GET_CODE (x) == MEM
- && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
+ && legitimate_indexed_address_p (XEXP (x, 0), 0))
putc ('x', file);
return;
@@ -7949,16 +9457,14 @@ print_operand (file, x, code)
break;
case ABI_V4:
- case ABI_AIX_NODESC:
case ABI_DARWIN:
break;
}
}
-#if TARGET_AIX
- RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
-#else
- assemble_name (file, XSTR (x, 0));
-#endif
+ if (TARGET_AIX)
+ RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
+ else
+ assemble_name (file, XSTR (x, 0));
return;
case 'Z':
@@ -7988,7 +9494,7 @@ print_operand (file, x, code)
tmp = XEXP (x, 0);
- if (TARGET_SPE)
+ if (TARGET_E500)
{
/* Handle [reg]. */
if (GET_CODE (tmp) == REG)
@@ -8048,6 +9554,10 @@ print_operand (file, x, code)
output_addr_const (file, x);
return;
+ case '&':
+ assemble_name (file, rs6000_get_some_local_dynamic_name ());
+ return;
+
default:
output_operand_lossage ("invalid %%xn code");
}
@@ -8056,9 +9566,7 @@ print_operand (file, x, code)
/* Print the address of an operand. */
void
-print_operand_address (file, x)
- FILE *file;
- rtx x;
+print_operand_address (FILE *file, rtx x)
{
if (GET_CODE (x) == REG)
fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
@@ -8082,10 +9590,8 @@ print_operand_address (file, x)
reg_names[ REGNO (XEXP (x, 1)) ]);
}
else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
- {
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (x, 1)));
- fprintf (file, "(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
- }
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
+ INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
#if TARGET_ELF
else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
&& CONSTANT_P (XEXP (x, 1)))
@@ -8103,7 +9609,7 @@ print_operand_address (file, x)
fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
}
#endif
- else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
+ else if (legitimate_constant_pool_address_p (x))
{
if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
{
@@ -8149,16 +9655,13 @@ print_operand_address (file, x)
targets. */
static bool
-rs6000_assemble_integer (x, size, aligned_p)
- rtx x;
- unsigned int size;
- int aligned_p;
+rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
#ifdef RELOCATABLE_NEEDS_FIXUP
/* Special handling for SI values. */
if (size == 4 && aligned_p)
{
- extern int in_toc_section PARAMS ((void));
+ extern int in_toc_section (void);
static int recurse = 0;
/* For -mrelocatable, we mark all addresses that need to be fixed up
@@ -8212,9 +9715,7 @@ rs6000_assemble_integer (x, size, aligned_p)
VISIBILITY_TYPE. */
static void
-rs6000_assemble_visibility (decl, vis)
- tree decl;
- int vis;
+rs6000_assemble_visibility (tree decl, int vis)
{
/* Functions need to have their entry point symbol visibility set as
well as their descriptor symbol visibility. */
@@ -8239,13 +9740,14 @@ rs6000_assemble_visibility (decl, vis)
#endif
enum rtx_code
-rs6000_reverse_condition (mode, code)
- enum machine_mode mode;
- enum rtx_code code;
+rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
{
/* Reversal of FP compares takes care -- an ordered compare
becomes an unordered compare and vice versa. */
- if (mode == CCFPmode && !flag_unsafe_math_optimizations)
+ if (mode == CCFPmode
+ && (!flag_finite_math_only
+ || code == UNLT || code == UNLE || code == UNGT || code == UNGE
+ || code == UNEQ || code == LTGT))
return reverse_condition_maybe_unordered (code);
else
return reverse_condition (code);
@@ -8255,8 +9757,7 @@ rs6000_reverse_condition (mode, code)
represents the result of the compare. */
static rtx
-rs6000_generate_compare (code)
- enum rtx_code code;
+rs6000_generate_compare (enum rtx_code code)
{
enum machine_mode comp_mode;
rtx compare_result;
@@ -8273,41 +9774,32 @@ rs6000_generate_compare (code)
compare_result = gen_reg_rtx (comp_mode);
/* SPE FP compare instructions on the GPRs. Yuck! */
- if ((TARGET_SPE && TARGET_HARD_FLOAT) && rs6000_compare_fp_p)
+ if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT)
+ && rs6000_compare_fp_p)
{
rtx cmp, or1, or2, or_result, compare_result2;
+ /* Note: The E500 comparison instructions set the GT bit (x +
+ 1), on success. This explains the mess. */
+
switch (code)
{
- case EQ:
- case UNEQ:
- case NE:
- case LTGT:
- cmp = flag_unsafe_math_optimizations
+ case EQ: case UNEQ: case NE: case LTGT:
+ cmp = flag_finite_math_only
? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
break;
- case GT:
- case GTU:
- case UNGT:
- case UNGE:
- case GE:
- case GEU:
- cmp = flag_unsafe_math_optimizations
+ case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
+ cmp = flag_finite_math_only
? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
break;
- case LT:
- case LTU:
- case UNLT:
- case UNLE:
- case LE:
- case LEU:
- cmp = flag_unsafe_math_optimizations
+ case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
+ cmp = flag_finite_math_only
? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
@@ -8320,8 +9812,6 @@ rs6000_generate_compare (code)
/* Synthesize LE and GE from LT/GT || EQ. */
if (code == LE || code == GE || code == LEU || code == GEU)
{
- /* Synthesize GE/LE frome GT/LT || EQ. */
-
emit_insn (cmp);
switch (code)
@@ -8339,30 +9829,15 @@ rs6000_generate_compare (code)
compare_result2 = gen_reg_rtx (CCFPmode);
/* Do the EQ. */
- cmp = flag_unsafe_math_optimizations
+ cmp = flag_finite_math_only
? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
rs6000_compare_op1)
: gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
rs6000_compare_op1);
emit_insn (cmp);
- /* The MC8540 FP compare instructions set the CR bits
- differently than other PPC compare instructions. For
- that matter, there is no generic test instruction, but a
- testgt, testlt, and testeq. For a true condition, bit 2
- is set (x1xx) in the CR. Following the traditional CR
- values:
-
- LT GT EQ OV
- bit3 bit2 bit1 bit0
-
- ... bit 2 would be a GT CR alias, so later on we
- look in the GT bits for the branch instructins.
- However, we must be careful to emit correct RTL in
- the meantime, so optimizations don't get confused. */
-
- or1 = gen_rtx (NE, SImode, compare_result, const0_rtx);
- or2 = gen_rtx (NE, SImode, compare_result2, const0_rtx);
+ or1 = gen_rtx_GT (SImode, compare_result, const0_rtx);
+ or2 = gen_rtx_GT (SImode, compare_result2, const0_rtx);
/* OR them together. */
cmp = gen_rtx_SET (VOIDmode, or_result,
@@ -8374,16 +9849,10 @@ rs6000_generate_compare (code)
}
else
{
- /* We only care about 1 bit (x1xx), so map everything to NE to
- maintain rtl sanity. We'll get to the right bit (x1xx) at
- code output time. */
if (code == NE || code == LTGT)
- /* Do the inverse here because we have no cmpne
- instruction. We use the cmpeq instruction and expect
- to get a 0 instead. */
- code = EQ;
- else
code = NE;
+ else
+ code = EQ;
}
emit_insn (cmp);
@@ -8395,10 +9864,10 @@ rs6000_generate_compare (code)
rs6000_compare_op1)));
/* Some kinds of FP comparisons need an OR operation;
- except for flag_unsafe_math_optimizations we don't bother. */
+ under flag_finite_math_only we don't bother. */
if (rs6000_compare_fp_p
- && ! flag_unsafe_math_optimizations
- && ! (TARGET_HARD_FLOAT && TARGET_SPE)
+ && ! flag_finite_math_only
+ && ! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)
&& (code == LE || code == GE
|| code == UNEQ || code == LTGT
|| code == UNGT || code == UNLT))
@@ -8439,14 +9908,50 @@ rs6000_generate_compare (code)
/* Emit the RTL for an sCOND pattern. */
void
-rs6000_emit_sCOND (code, result)
- enum rtx_code code;
- rtx result;
+rs6000_emit_sCOND (enum rtx_code code, rtx result)
{
rtx condition_rtx;
enum machine_mode op_mode;
+ enum rtx_code cond_code;
condition_rtx = rs6000_generate_compare (code);
+ cond_code = GET_CODE (condition_rtx);
+
+ if (TARGET_E500 && rs6000_compare_fp_p
+ && !TARGET_FPRS && TARGET_HARD_FLOAT)
+ {
+ rtx t;
+
+ PUT_MODE (condition_rtx, SImode);
+ t = XEXP (condition_rtx, 0);
+
+ if (cond_code != NE && cond_code != EQ)
+ abort ();
+
+ if (cond_code == NE)
+ emit_insn (gen_e500_flip_gt_bit (t, t));
+
+ emit_insn (gen_move_from_CR_gt_bit (result, t));
+ return;
+ }
+
+ if (cond_code == NE
+ || cond_code == GE || cond_code == LE
+ || cond_code == GEU || cond_code == LEU
+ || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
+ {
+ rtx not_result = gen_reg_rtx (CCEQmode);
+ rtx not_op, rev_cond_rtx;
+ enum machine_mode cc_mode;
+
+ cc_mode = GET_MODE (XEXP (condition_rtx, 0));
+
+ rev_cond_rtx = gen_rtx (rs6000_reverse_condition (cc_mode, cond_code),
+ SImode, XEXP (condition_rtx, 0), const0_rtx);
+ not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
+ emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
+ condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
+ }
op_mode = GET_MODE (rs6000_compare_op0);
if (op_mode == VOIDmode)
@@ -8467,9 +9972,7 @@ rs6000_emit_sCOND (code, result)
/* Emit a branch of kind CODE to location LOC. */
void
-rs6000_emit_cbranch (code, loc)
- enum rtx_code code;
- rtx loc;
+rs6000_emit_cbranch (enum rtx_code code, rtx loc)
{
rtx condition_rtx, loc_ref;
@@ -8493,11 +9996,7 @@ rs6000_emit_cbranch (code, loc)
INSN is the insn. */
char *
-output_cbranch (op, label, reversed, insn)
- rtx op;
- const char * label;
- int reversed;
- rtx insn;
+output_cbranch (rtx op, const char *label, int reversed, rtx insn)
{
static char string[64];
enum rtx_code code = GET_CODE (op);
@@ -8526,15 +10025,15 @@ output_cbranch (op, label, reversed, insn)
code = reverse_condition (code);
}
- if ((TARGET_SPE && TARGET_HARD_FLOAT) && mode == CCFPmode)
+ if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
{
/* The efscmp/tst* instructions twiddle bit 2, which maps nicely
to the GT bit. */
if (code == EQ)
/* Opposite of GT. */
- code = UNLE;
- else if (code == NE)
code = GT;
+ else if (code == NE)
+ code = UNLE;
else
abort ();
}
@@ -8571,7 +10070,6 @@ output_cbranch (op, label, reversed, insn)
{
/* PROB is the difference from 50%. */
int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
- bool always_hint = rs6000_cpu != PROCESSOR_POWER4;
/* Only hint for highly probable/improbable branches on newer
cpus as static prediction overrides processor dynamic
@@ -8579,12 +10077,12 @@ output_cbranch (op, label, reversed, insn)
assume not taken for branches that are very close to 50% as a
mispredicted taken branch is more expensive than a
mispredicted not-taken branch. */
- if (always_hint
+ if (rs6000_always_hint
|| abs (prob) > REG_BR_PROB_BASE / 100 * 48)
{
if (abs (prob) > REG_BR_PROB_BASE / 20
&& ((prob > 0) ^ need_longbranch))
- pred = "+";
+ pred = "+";
else
pred = "-";
}
@@ -8596,7 +10094,7 @@ output_cbranch (op, label, reversed, insn)
s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
/* We need to escape any '%' characters in the reg_names string.
- Assume they'd only be the first character... */
+ Assume they'd only be the first character.... */
if (reg_names[cc_regno + CR0_REGNO][0] == '%')
*s++ = '%';
s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
@@ -8614,16 +10112,31 @@ output_cbranch (op, label, reversed, insn)
return string;
}
+/* Return the string to flip the GT bit on a CR. */
+char *
+output_e500_flip_gt_bit (rtx dst, rtx src)
+{
+ static char string[64];
+ int a, b;
+
+ if (GET_CODE (dst) != REG || ! CR_REGNO_P (REGNO (dst))
+ || GET_CODE (src) != REG || ! CR_REGNO_P (REGNO (src)))
+ abort ();
+
+ /* GT bit. */
+ a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
+ b = 4 * (REGNO (src) - CR0_REGNO) + 1;
+
+ sprintf (string, "crnot %d,%d", a, b);
+ return string;
+}
+
/* Emit a conditional move: move TRUE_COND to DEST if OP of the
operands of the last comparison is nonzero/true, FALSE_COND if it
is zero/false. Return 0 if the hardware has no such operation. */
int
-rs6000_emit_cmove (dest, op, true_cond, false_cond)
- rtx dest;
- rtx op;
- rtx true_cond;
- rtx false_cond;
+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;
@@ -8633,7 +10146,7 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
enum machine_mode result_mode = GET_MODE (dest);
rtx temp;
- /* These modes should always match. */
+ /* These modes should always match. */
if (GET_MODE (op1) != compare_mode
/* In the isel case however, we can use a compare immediate, so
op1 may be a small constant. */
@@ -8645,18 +10158,21 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
return 0;
/* First, work out if the hardware can do this at all, or
- if it's too slow... */
+ if it's too slow.... */
if (! rs6000_compare_fp_p)
{
if (TARGET_ISEL)
return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
return 0;
}
+ else if (TARGET_E500 && TARGET_HARD_FLOAT && !TARGET_FPRS
+ && GET_MODE_CLASS (compare_mode) == MODE_FLOAT)
+ return 0;
/* Eliminate half of the comparisons by switching operands, this
makes the remaining code simpler. */
if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
- || code == LTGT || code == LT)
+ || code == LTGT || code == LT || code == UNLE)
{
code = reverse_condition_maybe_unordered (code);
temp = true_cond;
@@ -8666,18 +10182,18 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
/* UNEQ and LTGT take four instructions for a comparison with zero,
it'll probably be faster to use a branch here too. */
- if (code == UNEQ)
+ if (code == UNEQ && HONOR_NANS (compare_mode))
return 0;
if (GET_CODE (op1) == CONST_DOUBLE)
REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
- /* We're going to try to implement comparions by performing
+ /* We're going to try to implement comparisons by performing
a subtract, then comparing against zero. Unfortunately,
Inf - Inf is NaN which is not zero, and so if we don't
know that the operand is finite and the comparison
would treat EQ different to UNORDERED, we can't do it. */
- if (! flag_unsafe_math_optimizations
+ if (HONOR_INFINITIES (compare_mode)
&& code != GT && code != UNGE
&& (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
/* Constructs of the form (a OP b ? a : b) are safe. */
@@ -8696,7 +10212,7 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
/* If we don't care about NaNs we can reduce some of the comparisons
down to faster ones. */
- if (flag_unsafe_math_optimizations)
+ if (! HONOR_NANS (compare_mode))
switch (code)
{
case GT:
@@ -8742,14 +10258,15 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
break;
case UNGE:
+ /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
temp = gen_reg_rtx (result_mode);
emit_insn (gen_rtx_SET (VOIDmode, temp,
gen_rtx_IF_THEN_ELSE (result_mode,
gen_rtx_GE (VOIDmode,
op0, op1),
true_cond, false_cond)));
- false_cond = temp;
- true_cond = false_cond;
+ false_cond = true_cond;
+ true_cond = temp;
temp = gen_reg_rtx (compare_mode);
emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
@@ -8757,14 +10274,15 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
break;
case GT:
+ /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
temp = gen_reg_rtx (result_mode);
emit_insn (gen_rtx_SET (VOIDmode, temp,
gen_rtx_IF_THEN_ELSE (result_mode,
gen_rtx_GE (VOIDmode,
op0, op1),
true_cond, false_cond)));
- true_cond = temp;
- false_cond = true_cond;
+ true_cond = false_cond;
+ false_cond = temp;
temp = gen_reg_rtx (compare_mode);
emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
@@ -8786,11 +10304,7 @@ rs6000_emit_cmove (dest, op, true_cond, false_cond)
/* Same as above, but for ints (isel). */
static int
-rs6000_emit_int_cmove (dest, op, true_cond, false_cond)
- rtx dest;
- rtx op;
- rtx true_cond;
- rtx false_cond;
+rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
{
rtx condition_rtx, cr;
@@ -8815,8 +10329,7 @@ rs6000_emit_int_cmove (dest, op, true_cond, false_cond)
}
const char *
-output_isel (operands)
- rtx *operands;
+output_isel (rtx *operands)
{
enum rtx_code code;
@@ -8831,11 +10344,7 @@ output_isel (operands)
}
void
-rs6000_emit_minmax (dest, code, op0, op1)
- rtx dest;
- enum rtx_code code;
- rtx op0;
- rtx op1;
+rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
{
enum machine_mode mode = GET_MODE (op0);
enum rtx_code c;
@@ -8857,6 +10366,145 @@ rs6000_emit_minmax (dest, code, op0, op1)
if (target != dest)
emit_move_insn (dest, target);
}
+
+/* Emit instructions to move SRC to DST. Called by splitters for
+ multi-register moves. It will emit at most one instruction for
+ each register that is accessed; that is, it won't emit li/lis pairs
+ (or equivalent for 64-bit code). One of SRC or DST must be a hard
+ register. */
+
+void
+rs6000_split_multireg_move (rtx dst, rtx src)
+{
+ /* The register number of the first register being moved. */
+ int reg;
+ /* The mode that is to be moved. */
+ enum machine_mode mode;
+ /* The mode that the move is being done in, and its size. */
+ enum machine_mode reg_mode;
+ int reg_mode_size;
+ /* The number of registers that will be moved. */
+ int nregs;
+
+ reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
+ mode = GET_MODE (dst);
+ nregs = HARD_REGNO_NREGS (reg, mode);
+ if (FP_REGNO_P (reg))
+ reg_mode = DFmode;
+ else if (ALTIVEC_REGNO_P (reg))
+ reg_mode = V16QImode;
+ else
+ reg_mode = word_mode;
+ reg_mode_size = GET_MODE_SIZE (reg_mode);
+
+ if (reg_mode_size * nregs != GET_MODE_SIZE (mode))
+ abort ();
+
+ if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
+ {
+ /* Move register range backwards, if we might have destructive
+ overlap. */
+ int i;
+ for (i = nregs - 1; i >= 0; i--)
+ emit_insn (gen_rtx_SET (VOIDmode,
+ simplify_gen_subreg (reg_mode, dst, mode,
+ i * reg_mode_size),
+ simplify_gen_subreg (reg_mode, src, mode,
+ i * reg_mode_size)));
+ }
+ else
+ {
+ int i;
+ int j = -1;
+ bool used_update = false;
+
+ if (GET_CODE (src) == MEM && INT_REGNO_P (reg))
+ {
+ rtx breg;
+
+ if (GET_CODE (XEXP (src, 0)) == PRE_INC
+ || GET_CODE (XEXP (src, 0)) == PRE_DEC)
+ {
+ rtx delta_rtx;
+ breg = XEXP (XEXP (src, 0), 0);
+ delta_rtx = GET_CODE (XEXP (src, 0)) == PRE_INC
+ ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
+ : GEN_INT (-GET_MODE_SIZE (GET_MODE (src)));
+ emit_insn (TARGET_32BIT
+ ? gen_addsi3 (breg, breg, delta_rtx)
+ : gen_adddi3 (breg, breg, delta_rtx));
+ src = gen_rtx_MEM (mode, breg);
+ }
+
+ /* We have now address involving an base register only.
+ If we use one of the registers to address memory,
+ we have change that register last. */
+
+ breg = (GET_CODE (XEXP (src, 0)) == PLUS
+ ? XEXP (XEXP (src, 0), 0)
+ : XEXP (src, 0));
+
+ if (!REG_P (breg))
+ abort();
+
+ if (REGNO (breg) >= REGNO (dst)
+ && REGNO (breg) < REGNO (dst) + nregs)
+ j = REGNO (breg) - REGNO (dst);
+ }
+
+ if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
+ {
+ rtx breg;
+
+ if (GET_CODE (XEXP (dst, 0)) == PRE_INC
+ || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
+ {
+ rtx delta_rtx;
+ breg = XEXP (XEXP (dst, 0), 0);
+ delta_rtx = GET_CODE (XEXP (dst, 0)) == PRE_INC
+ ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
+ : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst)));
+
+ /* We have to update the breg before doing the store.
+ Use store with update, if available. */
+
+ if (TARGET_UPDATE)
+ {
+ rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
+ emit_insn (TARGET_32BIT
+ ? gen_movsi_update (breg, breg, delta_rtx, nsrc)
+ : gen_movdi_update (breg, breg, delta_rtx, nsrc));
+ used_update = true;
+ }
+ else
+ emit_insn (TARGET_32BIT
+ ? gen_addsi3 (breg, breg, delta_rtx)
+ : gen_adddi3 (breg, breg, delta_rtx));
+ dst = gen_rtx_MEM (mode, breg);
+ }
+ }
+
+ for (i = 0; i < nregs; i++)
+ {
+ /* Calculate index to next subword. */
+ ++j;
+ if (j == nregs)
+ j = 0;
+
+ /* If compiler already emited move of first word by
+ store with update, no need to do anything. */
+ if (j == 0 && used_update)
+ continue;
+
+ emit_insn (gen_rtx_SET (VOIDmode,
+ simplify_gen_subreg (reg_mode, dst, mode,
+ j * reg_mode_size),
+ simplify_gen_subreg (reg_mode, src, mode,
+ j * reg_mode_size)));
+ }
+ }
+}
+
/* This page contains routines that are used to determine what the
function prologue and epilogue code will do and write them out. */
@@ -8865,7 +10513,7 @@ rs6000_emit_minmax (dest, code, op0, op1)
saved. 32 if none. */
int
-first_reg_to_save ()
+first_reg_to_save (void)
{
int first_reg;
@@ -8891,7 +10539,7 @@ first_reg_to_save ()
/* Similar, for FP regs. */
int
-first_fp_reg_to_save ()
+first_fp_reg_to_save (void)
{
int first_reg;
@@ -8906,7 +10554,7 @@ first_fp_reg_to_save ()
/* Similar, for AltiVec regs. */
static int
-first_altivec_reg_to_save ()
+first_altivec_reg_to_save (void)
{
int i;
@@ -8927,7 +10575,7 @@ first_altivec_reg_to_save ()
the 32-bit word is 0. */
static unsigned int
-compute_vrsave_mask ()
+compute_vrsave_mask (void)
{
unsigned int i, mask = 0;
@@ -8939,25 +10587,12 @@ compute_vrsave_mask ()
if (mask == 0)
return mask;
- /* Next, add all registers that are call-clobbered. We do this
- because post-reload register optimizers such as regrename_optimize
- may choose to use them. They never change the register class
- chosen by reload, so cannot create new uses of altivec registers
- if there were none before, so the early exit above is safe. */
- /* ??? Alternately, we could define HARD_REGNO_RENAME_OK to disallow
- altivec registers not saved in the mask, which might well make the
- adjustments below more effective in eliding the save/restore of
- VRSAVE in small functions. */
- for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
- if (call_used_regs[i])
- mask |= ALTIVEC_REG_BIT (i);
-
/* Next, remove the argument registers from the set. These must
be in the VRSAVE mask set by the caller, so we don't need to add
them in again. More importantly, the mask we compute here is
used to generate CLOBBERs in the set_vrsave insn, and we do not
wish the argument registers to die. */
- for (i = cfun->args_info.vregno; i >= ALTIVEC_ARG_MIN_REG; --i)
+ for (i = cfun->args_info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
mask &= ~ALTIVEC_REG_BIT (i);
/* Similarly, remove the return value from the set. */
@@ -8972,9 +10607,7 @@ compute_vrsave_mask ()
}
static void
-is_altivec_return_reg (reg, xyes)
- rtx reg;
- void *xyes;
+is_altivec_return_reg (rtx reg, void *xyes)
{
bool *yes = (bool *) xyes;
if (REGNO (reg) == ALTIVEC_ARG_RETURN)
@@ -9069,8 +10702,7 @@ is_altivec_return_reg (reg, xyes)
align the stack at program startup. A happy side-effect is that
-mno-eabi libraries can be used with -meabi programs.)
- The EABI configuration defaults to the V.4 layout, unless
- -mcall-aix is used, in which case the AIX layout is used. However,
+ The EABI configuration defaults to the V.4 layout. However,
the stack alignment requirements may differ. If -mno-eabi is not
given, the required stack alignment is 8 bytes; if -mno-eabi is
given, the required alignment is 16 bytes. (But see V.4 comment
@@ -9080,29 +10712,38 @@ is_altivec_return_reg (reg, xyes)
#define ABI_STACK_BOUNDARY STACK_BOUNDARY
#endif
-rs6000_stack_t *
-rs6000_stack_info ()
+static rs6000_stack_t *
+rs6000_stack_info (void)
{
static rs6000_stack_t info, zero_info;
rs6000_stack_t *info_ptr = &info;
- int reg_size = TARGET_POWERPC64 ? 8 : 4;
- enum rs6000_abi abi;
+ int reg_size = TARGET_32BIT ? 4 : 8;
int ehrd_size;
- int total_raw_size;
+ HOST_WIDE_INT non_fixed_size;
/* Zero all fields portably. */
info = zero_info;
+ if (TARGET_SPE)
+ {
+ /* Cache value so we don't rescan instruction chain over and over. */
+ if (cfun->machine->insn_chain_scanned_p == 0)
+ {
+ cfun->machine->insn_chain_scanned_p = 1;
+ info_ptr->spe_64bit_regs_used = (int) spe_func_has_64bit_regs_p ();
+ }
+ }
+
/* Select which calling sequence. */
- info_ptr->abi = abi = DEFAULT_ABI;
+ info_ptr->abi = DEFAULT_ABI;
/* Calculate which registers need to be saved & save area size. */
info_ptr->first_gp_reg_save = first_reg_to_save ();
/* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
even if it currently looks like we won't. */
if (((TARGET_TOC && TARGET_MINIMAL_TOC)
- || (flag_pic == 1 && abi == ABI_V4)
- || (flag_pic && abi == ABI_DARWIN))
+ || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
+ || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
&& info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
else
@@ -9114,12 +10755,13 @@ rs6000_stack_info ()
registers live (not the size they are used in), this proves
difficult because we'd have to traverse the instruction chain at
the right time, taking reload into account. This is a real pain,
- so we opt to save the GPRs in 64-bits always. Anyone overly
- concerned with frame size can fix this. ;-).
+ so we opt to save the GPRs in 64-bits always if but one register
+ gets used in 64-bits. Otherwise, all the registers in the frame
+ get saved in 32-bits.
- So... since we save all GPRs (except the SP) in 64-bits, the
+ So... since when we save all GPRs (except the SP) in 64-bits, the
traditional GP save area will be empty. */
- if (TARGET_SPE_ABI)
+ if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
info_ptr->gp_size = 0;
info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
@@ -9135,14 +10777,16 @@ rs6000_stack_info ()
/* Determine if we need to save the link register. */
if (rs6000_ra_ever_killed ()
- || (DEFAULT_ABI == ABI_AIX && current_function_profile)
+ || (DEFAULT_ABI == ABI_AIX
+ && current_function_profile
+ && !TARGET_PROFILE_KERNEL)
#ifdef TARGET_RELOCATABLE
|| (TARGET_RELOCATABLE && (get_pool_size () != 0))
#endif
|| (info_ptr->first_fp_reg_save != 64
&& !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
|| info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
- || (abi == ABI_V4 && current_function_calls_alloca)
+ || (DEFAULT_ABI == ABI_V4 && current_function_calls_alloca)
|| (DEFAULT_ABI == ABI_DARWIN
&& flag_pic
&& current_function_uses_pic_offset_table)
@@ -9158,7 +10802,7 @@ rs6000_stack_info ()
|| regs_ever_live[CR4_REGNO])
{
info_ptr->cr_save_p = 1;
- if (abi == ABI_V4)
+ if (DEFAULT_ABI == ABI_V4)
info_ptr->cr_size = reg_size;
}
@@ -9172,7 +10816,9 @@ rs6000_stack_info ()
continue;
/* SPE saves EH registers in 64-bits. */
- ehrd_size = i * (TARGET_SPE_ABI ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
+ ehrd_size = i * (TARGET_SPE_ABI
+ && info_ptr->spe_64bit_regs_used != 0
+ ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
}
else
ehrd_size = 0;
@@ -9183,33 +10829,31 @@ rs6000_stack_info ()
info_ptr->varargs_size = RS6000_VARARGS_AREA;
info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
- 8);
+ TARGET_ALTIVEC ? 16 : 8);
- if (TARGET_SPE_ABI)
+ if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
else
info_ptr->spe_gp_size = 0;
- if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE)
- {
- info_ptr->vrsave_mask = compute_vrsave_mask ();
- info_ptr->vrsave_size = info_ptr->vrsave_mask ? 4 : 0;
- }
+ if (TARGET_ALTIVEC_ABI)
+ info_ptr->vrsave_mask = compute_vrsave_mask ();
else
- {
- info_ptr->vrsave_mask = 0;
- info_ptr->vrsave_size = 0;
- }
+ info_ptr->vrsave_mask = 0;
+
+ if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
+ info_ptr->vrsave_size = 4;
+ else
+ info_ptr->vrsave_size = 0;
/* Calculate the offsets. */
- switch (abi)
+ switch (DEFAULT_ABI)
{
case ABI_NONE:
default:
abort ();
case ABI_AIX:
- case ABI_AIX_NODESC:
case ABI_DARWIN:
info_ptr->fp_save_offset = - info_ptr->fp_size;
info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
@@ -9245,7 +10889,7 @@ rs6000_stack_info ()
info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
- if (TARGET_SPE_ABI)
+ if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
{
/* Align stack so SPE GPR save area is aligned on a
double-word boundary. */
@@ -9296,24 +10940,23 @@ rs6000_stack_info ()
+ info_ptr->gp_size
+ info_ptr->altivec_size
+ info_ptr->altivec_padding_size
- + info_ptr->vrsave_size
+ info_ptr->spe_gp_size
+ info_ptr->spe_padding_size
+ ehrd_size
+ info_ptr->cr_size
+ info_ptr->lr_size
+ + info_ptr->vrsave_size
+ info_ptr->toc_size,
(TARGET_ALTIVEC_ABI || ABI_DARWIN)
? 16 : 8);
- total_raw_size = (info_ptr->vars_size
+ non_fixed_size = (info_ptr->vars_size
+ info_ptr->parm_size
+ info_ptr->save_size
- + info_ptr->varargs_size
- + info_ptr->fixed_size);
+ + info_ptr->varargs_size);
- info_ptr->total_size =
- RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
+ info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
+ ABI_STACK_BOUNDARY / BITS_PER_UNIT);
/* Determine if we need to allocate any stack frame:
@@ -9330,14 +10973,17 @@ rs6000_stack_info ()
if (info_ptr->calls_p)
info_ptr->push_p = 1;
- else if (abi == ABI_V4)
- info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
+ else if (DEFAULT_ABI == ABI_V4)
+ info_ptr->push_p = non_fixed_size != 0;
+
+ else if (frame_pointer_needed)
+ info_ptr->push_p = 1;
+
+ else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
+ info_ptr->push_p = 1;
else
- info_ptr->push_p = (frame_pointer_needed
- || (abi != ABI_DARWIN && write_symbols != NO_DEBUG)
- || ((total_raw_size - info_ptr->fixed_size)
- > (TARGET_32BIT ? 220 : 288)));
+ info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
/* Zero offsets if we're not saving those registers. */
if (info_ptr->fp_size == 0)
@@ -9352,7 +10998,9 @@ rs6000_stack_info ()
if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
info_ptr->vrsave_save_offset = 0;
- if (! TARGET_SPE_ABI || info_ptr->spe_gp_size == 0)
+ if (! TARGET_SPE_ABI
+ || info_ptr->spe_64bit_regs_used == 0
+ || info_ptr->spe_gp_size == 0)
info_ptr->spe_gp_save_offset = 0;
if (! info_ptr->lr_save_p)
@@ -9367,9 +11015,41 @@ rs6000_stack_info ()
return info_ptr;
}
-void
-debug_stack_info (info)
- rs6000_stack_t *info;
+/* Return true if the current function uses any GPRs in 64-bit SIMD
+ mode. */
+
+static bool
+spe_func_has_64bit_regs_p (void)
+{
+ rtx insns, insn;
+
+ /* Functions that save and restore all the call-saved registers will
+ need to save/restore the registers in 64-bits. */
+ if (current_function_calls_eh_return
+ || current_function_calls_setjmp
+ || current_function_has_nonlocal_goto)
+ return true;
+
+ insns = get_insns ();
+
+ for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
+ {
+ rtx i;
+
+ i = PATTERN (insn);
+ if (GET_CODE (i) == SET
+ && SPE_VECTOR_MODE (GET_MODE (SET_SRC (i))))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void
+debug_stack_info (rs6000_stack_t *info)
{
const char *abi_string;
@@ -9385,8 +11065,7 @@ debug_stack_info (info)
{
default: abi_string = "Unknown"; break;
case ABI_NONE: abi_string = "NONE"; break;
- case ABI_AIX:
- case ABI_AIX_NODESC: abi_string = "AIX"; break;
+ case ABI_AIX: abi_string = "AIX"; break;
case ABI_DARWIN: abi_string = "Darwin"; break;
case ABI_V4: abi_string = "V.4"; break;
}
@@ -9458,13 +11137,15 @@ debug_stack_info (info)
fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
if (info->total_size)
- fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
+ fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
+ info->total_size);
if (info->varargs_size)
fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
if (info->vars_size)
- fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
+ fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
+ info->vars_size);
if (info->parm_size)
fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
@@ -9514,14 +11195,12 @@ debug_stack_info (info)
}
rtx
-rs6000_return_addr (count, frame)
- int count;
- rtx frame;
+rs6000_return_addr (int count, rtx frame)
{
/* Currently we don't optimize very well between prolog and body
code and for PIC code the code can be actually quite bad, so
don't try to be too clever here. */
- if (count != 0 || flag_pic != 0)
+ if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
{
cfun->machine->ra_needs_full_frame = 1;
@@ -9536,6 +11215,7 @@ rs6000_return_addr (count, frame)
RETURN_ADDRESS_OFFSET)));
}
+ cfun->machine->ra_need_lr = 1;
return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
}
@@ -9546,53 +11226,48 @@ rs6000_return_addr (count, frame)
vector parameters are required to have a prototype, so the argument
type info must be available here. (The tail recursion case can work
with vector parameters, but there's no way to distinguish here.) */
-int
-function_ok_for_sibcall (fndecl)
- tree fndecl;
+static bool
+rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
{
tree type;
- if (fndecl)
+ if (decl)
{
if (TARGET_ALTIVEC_VRSAVE)
{
- for (type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
+ for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
type; type = TREE_CHAIN (type))
{
if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
- return 0;
+ return false;
}
}
if (DEFAULT_ABI == ABI_DARWIN
- || (*targetm.binds_local_p) (fndecl))
+ || (*targetm.binds_local_p) (decl))
{
- tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (fndecl));
+ tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
if (!lookup_attribute ("longcall", attr_list)
|| lookup_attribute ("shortcall", attr_list))
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
static int
-rs6000_ra_ever_killed ()
+rs6000_ra_ever_killed (void)
{
rtx top;
rtx reg;
rtx insn;
- /* Irritatingly, there are two kinds of thunks -- those created with
- TARGET_ASM_OUTPUT_MI_THUNK and those with DECL_THUNK_P that go
- through the regular part of the compiler. This is a very hacky
- way to tell them apart. */
- if (current_function_is_thunk && !no_new_pseudos)
+ if (current_function_is_thunk)
return 0;
/* regs_ever_live has LR marked as used if any sibcalls are present,
but this should not force saving and restoring in the
pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
- clobbers LR, so that is inappropriate. */
+ clobbers LR, so that is inappropriate. */
/* Also, the prologue can generate a store into LR that
doesn't really count, like this:
@@ -9629,8 +11304,7 @@ rs6000_ra_ever_killed ()
/* Add a REG_MAYBE_DEAD note to the insn. */
static void
-rs6000_maybe_dead (insn)
- rtx insn;
+rs6000_maybe_dead (rtx insn)
{
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
const0_rtx,
@@ -9642,8 +11316,7 @@ rs6000_maybe_dead (insn)
a constant pool; or for SVR4 -fpic. */
void
-rs6000_emit_load_toc_table (fromprolog)
- int fromprolog;
+rs6000_emit_load_toc_table (int fromprolog)
{
rtx dest, insn;
dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
@@ -9741,42 +11414,86 @@ rs6000_emit_load_toc_table (fromprolog)
abort ();
}
+/* Emit instructions to restore the link register after determining where
+ its value has been stored. */
+
+void
+rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
+{
+ rs6000_stack_t *info = rs6000_stack_info ();
+ rtx operands[2];
+
+ operands[0] = source;
+ operands[1] = scratch;
+
+ if (info->lr_save_p)
+ {
+ rtx frame_rtx = stack_pointer_rtx;
+ HOST_WIDE_INT sp_offset = 0;
+ rtx tmp;
+
+ if (frame_pointer_needed
+ || current_function_calls_alloca
+ || info->total_size > 32767)
+ {
+ emit_move_insn (operands[1], gen_rtx_MEM (Pmode, frame_rtx));
+ frame_rtx = operands[1];
+ }
+ else if (info->push_p)
+ sp_offset = info->total_size;
+
+ tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
+ tmp = gen_rtx_MEM (Pmode, tmp);
+ emit_move_insn (tmp, operands[0]);
+ }
+ else
+ emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
+}
+
+static GTY(()) int set = -1;
+
int
-get_TOC_alias_set ()
+get_TOC_alias_set (void)
{
- static int set = -1;
- if (set == -1)
- set = new_alias_set ();
- return set;
+ if (set == -1)
+ set = new_alias_set ();
+ return set;
}
-/* This retuns nonzero if the current function uses the TOC. This is
- determined by the presence of (unspec ... 7), which is generated by
- the various load_toc_* patterns. */
-
-int
-uses_TOC ()
+/* This returns nonzero if the current function uses the TOC. This is
+ determined by the presence of (use (unspec ... UNSPEC_TOC)), which
+ is generated by the ABI_V4 load_toc_* patterns. */
+#if TARGET_ELF
+static int
+uses_TOC (void)
{
- rtx insn;
+ rtx insn;
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (INSN_P (insn))
- {
- rtx pat = PATTERN (insn);
- int i;
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ {
+ rtx pat = PATTERN (insn);
+ int i;
- if (GET_CODE (pat) == PARALLEL)
- for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
- if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
- && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
- return 1;
- }
- return 0;
+ if (GET_CODE (pat) == PARALLEL)
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ {
+ rtx sub = XVECEXP (pat, 0, i);
+ if (GET_CODE (sub) == USE)
+ {
+ sub = XEXP (sub, 0);
+ if (GET_CODE (sub) == UNSPEC
+ && XINT (sub, 1) == UNSPEC_TOC)
+ return 1;
+ }
+ }
+ }
+ return 0;
}
+#endif
rtx
-create_TOC_reference (symbol)
- rtx symbol;
+create_TOC_reference (rtx symbol)
{
return gen_rtx_PLUS (Pmode,
gen_rtx_REG (Pmode, TOC_REGISTER),
@@ -9785,141 +11502,47 @@ create_TOC_reference (symbol)
gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
}
-#if TARGET_AIX
-/* __throw will restore its own return address to be the same as the
- return address of the function that the throw is being made to.
- This is unfortunate, because we want to check the original
- return address to see if we need to restore the TOC.
- So we have to squirrel it away here.
- This is used only in compiling __throw and __rethrow.
-
- Most of this code should be removed by CSE. */
-static rtx insn_after_throw;
+/* If _Unwind_* has been called from within the same module,
+ toc register is not guaranteed to be saved to 40(1) on function
+ entry. Save it there in that case. */
-/* This does the saving... */
void
-rs6000_aix_emit_builtin_unwind_init ()
+rs6000_aix_emit_builtin_unwind_init (void)
{
rtx mem;
rtx stack_top = gen_reg_rtx (Pmode);
rtx opcode_addr = gen_reg_rtx (Pmode);
-
- insn_after_throw = gen_reg_rtx (SImode);
+ rtx opcode = gen_reg_rtx (SImode);
+ rtx tocompare = gen_reg_rtx (SImode);
+ rtx no_toc_save_needed = gen_label_rtx ();
mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
emit_move_insn (stack_top, mem);
- mem = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode, stack_top,
+ mem = gen_rtx_MEM (Pmode,
+ gen_rtx_PLUS (Pmode, stack_top,
GEN_INT (2 * GET_MODE_SIZE (Pmode))));
emit_move_insn (opcode_addr, mem);
- emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
-}
-
-/* Emit insns to _restore_ the TOC register, at runtime (specifically
- in _eh.o). Only used on AIX.
-
- The idea is that on AIX, function calls look like this:
- bl somefunction-trampoline
- lwz r2,20(sp)
-
- and later,
- somefunction-trampoline:
- stw r2,20(sp)
- ... load function address in the count register ...
- bctr
- or like this, if the linker determines that this is not a cross-module call
- and so the TOC need not be restored:
- bl somefunction
- nop
- or like this, if the compiler could determine that this is not a
- cross-module call:
- bl somefunction
- now, the tricky bit here is that register 2 is saved and restored
- by the _linker_, so we can't readily generate debugging information
- for it. So we need to go back up the call chain looking at the
- insns at return addresses to see which calls saved the TOC register
- and so see where it gets restored from.
-
- Oh, and all this gets done in RTL inside the eh_epilogue pattern,
- just before the actual epilogue.
-
- On the bright side, this incurs no space or time overhead unless an
- exception is thrown, except for the extra code in libgcc.a.
-
- The parameter STACKSIZE is a register containing (at runtime)
- the amount to be popped off the stack in addition to the stack frame
- of this routine (which will be __throw or __rethrow, and so is
- guaranteed to have a stack frame). */
-
-void
-rs6000_emit_eh_toc_restore (stacksize)
- rtx stacksize;
-{
- rtx top_of_stack;
- rtx bottom_of_stack = gen_reg_rtx (Pmode);
- rtx tocompare = gen_reg_rtx (SImode);
- rtx opcode = gen_reg_rtx (SImode);
- rtx opcode_addr = gen_reg_rtx (Pmode);
- rtx mem;
- rtx loop_start = gen_label_rtx ();
- rtx no_toc_restore_needed = gen_label_rtx ();
- rtx loop_exit = gen_label_rtx ();
-
- mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
- set_mem_alias_set (mem, rs6000_sr_alias_set);
- emit_move_insn (bottom_of_stack, mem);
-
- top_of_stack = expand_binop (Pmode, add_optab,
- bottom_of_stack, stacksize,
- NULL_RTX, 1, OPTAB_WIDEN);
-
- emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
+ emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
+ emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
: 0xE8410028, SImode));
- if (insn_after_throw == NULL_RTX)
- abort ();
- emit_move_insn (opcode, insn_after_throw);
-
- emit_note (NULL, NOTE_INSN_LOOP_BEG);
- emit_label (loop_start);
-
- do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
+ do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
SImode, NULL_RTX, NULL_RTX,
- no_toc_restore_needed);
-
- mem = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode, bottom_of_stack,
- GEN_INT (5 * GET_MODE_SIZE (Pmode))));
- emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
-
- emit_label (no_toc_restore_needed);
- do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
- Pmode, NULL_RTX, NULL_RTX,
- loop_exit);
+ no_toc_save_needed);
- mem = gen_rtx_MEM (Pmode, bottom_of_stack);
- set_mem_alias_set (mem, rs6000_sr_alias_set);
- emit_move_insn (bottom_of_stack, mem);
-
- mem = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode, bottom_of_stack,
- GEN_INT (2 * GET_MODE_SIZE (Pmode))));
- emit_move_insn (opcode_addr, mem);
- emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
-
- emit_note (NULL, NOTE_INSN_LOOP_CONT);
- emit_jump (loop_start);
- emit_note (NULL, NOTE_INSN_LOOP_END);
- emit_label (loop_exit);
+ mem = gen_rtx_MEM (Pmode,
+ gen_rtx_PLUS (Pmode, stack_top,
+ GEN_INT (5 * GET_MODE_SIZE (Pmode))));
+ emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
+ emit_label (no_toc_save_needed);
}
-#endif /* TARGET_AIX */
/* This ties together stack memory (MEM with an alias set of
rs6000_sr_alias_set) and the change to the stack pointer. */
static void
-rs6000_emit_stack_tie ()
+rs6000_emit_stack_tie (void)
{
rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
@@ -9932,9 +11555,7 @@ rs6000_emit_stack_tie ()
The generated code may use hard register 0 as a temporary. */
static void
-rs6000_emit_allocate_stack (size, copy_r12)
- HOST_WIDE_INT size;
- int copy_r12;
+rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
{
rtx insn;
rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
@@ -9947,14 +11568,14 @@ rs6000_emit_allocate_stack (size, copy_r12)
&& REGNO (stack_limit_rtx) > 1
&& REGNO (stack_limit_rtx) <= 31)
{
- emit_insn (Pmode == SImode
+ emit_insn (TARGET_32BIT
? gen_addsi3 (tmp_reg,
stack_limit_rtx,
GEN_INT (size))
: gen_adddi3 (tmp_reg,
stack_limit_rtx,
GEN_INT (size)));
-
+
emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
const0_rtx));
}
@@ -9966,7 +11587,7 @@ rs6000_emit_allocate_stack (size, copy_r12)
gen_rtx_PLUS (Pmode,
stack_limit_rtx,
GEN_INT (size)));
-
+
emit_insn (gen_elf_high (tmp_reg, toload));
emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
@@ -9985,29 +11606,27 @@ rs6000_emit_allocate_stack (size, copy_r12)
{
/* Need a note here so that try_split doesn't get confused. */
if (get_last_insn() == NULL_RTX)
- emit_note (0, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
insn = emit_move_insn (tmp_reg, todec);
try_split (PATTERN (insn), insn, 0);
todec = tmp_reg;
}
-
- if (Pmode == SImode)
- insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
- todec, stack_reg));
- else
- insn = emit_insn (gen_movdi_update (stack_reg, stack_reg,
+
+ insn = emit_insn (TARGET_32BIT
+ ? gen_movsi_update (stack_reg, stack_reg,
+ todec, stack_reg)
+ : gen_movdi_update (stack_reg, stack_reg,
todec, stack_reg));
}
else
{
- if (Pmode == SImode)
- insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
- else
- insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
+ insn = emit_insn (TARGET_32BIT
+ ? gen_addsi3 (stack_reg, stack_reg, todec)
+ : gen_adddi3 (stack_reg, stack_reg, todec));
emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
gen_rtx_REG (Pmode, 12));
}
-
+
RTX_FRAME_RELATED_P (insn) = 1;
REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
@@ -10017,32 +11636,6 @@ rs6000_emit_allocate_stack (size, copy_r12)
REG_NOTES (insn));
}
-/* Add a RTX_FRAME_RELATED note so that dwarf2out_frame_debug_expr
- knows that:
-
- (mem (plus (blah) (regXX)))
-
- is really:
-
- (mem (plus (blah) (const VALUE_OF_REGXX))). */
-
-static void
-altivec_frame_fixup (insn, reg, val)
- rtx insn, reg;
- HOST_WIDE_INT val;
-{
- rtx real;
-
- real = copy_rtx (PATTERN (insn));
-
- real = replace_rtx (real, reg, GEN_INT (val));
-
- RTX_FRAME_RELATED_P (insn) = 1;
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
- real,
- REG_NOTES (insn));
-}
-
/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
is not NULL. It would be nice if dwarf2out_frame_debug_expr could
@@ -10050,12 +11643,8 @@ altivec_frame_fixup (insn, reg, val)
its hand so much. */
static void
-rs6000_frame_related (insn, reg, val, reg2, rreg)
- rtx insn;
- rtx reg;
- HOST_WIDE_INT val;
- rtx reg2;
- rtx rreg;
+rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
+ rtx reg2, rtx rreg)
{
rtx real, temp;
@@ -10123,21 +11712,84 @@ rs6000_frame_related (insn, reg, val, reg2, rreg)
}
else
abort ();
-
+
+ if (TARGET_SPE)
+ real = spe_synthesize_frame_save (real);
+
RTX_FRAME_RELATED_P (insn) = 1;
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
real,
REG_NOTES (insn));
}
+/* Given an SPE frame note, return a PARALLEL of SETs with the
+ original note, plus a synthetic register save. */
+
+static rtx
+spe_synthesize_frame_save (rtx real)
+{
+ rtx synth, offset, reg, real2;
+
+ if (GET_CODE (real) != SET
+ || GET_MODE (SET_SRC (real)) != V2SImode)
+ return real;
+
+ /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
+ frame related note. The parallel contains a set of the register
+ being saved, and another set to a synthetic register (n+1200).
+ This is so we can differentiate between 64-bit and 32-bit saves.
+ Words cannot describe this nastiness. */
+
+ if (GET_CODE (SET_DEST (real)) != MEM
+ || GET_CODE (XEXP (SET_DEST (real), 0)) != PLUS
+ || GET_CODE (SET_SRC (real)) != REG)
+ abort ();
+
+ /* Transform:
+ (set (mem (plus (reg x) (const y)))
+ (reg z))
+ into:
+ (set (mem (plus (reg x) (const y+4)))
+ (reg z+1200))
+ */
+
+ real2 = copy_rtx (real);
+ PUT_MODE (SET_DEST (real2), SImode);
+ reg = SET_SRC (real2);
+ real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg)));
+ synth = copy_rtx (real2);
+
+ if (BYTES_BIG_ENDIAN)
+ {
+ offset = XEXP (XEXP (SET_DEST (real2), 0), 1);
+ real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4));
+ }
+
+ reg = SET_SRC (synth);
+
+ synth = replace_rtx (synth, reg,
+ gen_rtx_REG (SImode, REGNO (reg) + 1200));
+
+ offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
+ synth = replace_rtx (synth, offset,
+ GEN_INT (INTVAL (offset)
+ + (BYTES_BIG_ENDIAN ? 0 : 4)));
+
+ RTX_FRAME_RELATED_P (synth) = 1;
+ RTX_FRAME_RELATED_P (real2) = 1;
+ if (BYTES_BIG_ENDIAN)
+ real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2));
+ else
+ real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth));
+
+ return real;
+}
+
/* Returns an insn that has a vrsave set operation with the
appropriate CLOBBERs. */
static rtx
-generate_set_vrsave (reg, info, epiloguep)
- rtx reg;
- rs6000_stack_t *info;
- int epiloguep;
+generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
{
int nclobs, i;
rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
@@ -10167,7 +11819,7 @@ generate_set_vrsave (reg, info, epiloguep)
need an unspec use/set of the register. */
for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
- if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
+ if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
{
if (!epiloguep || call_used_regs [i])
clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
@@ -10196,13 +11848,8 @@ generate_set_vrsave (reg, info, epiloguep)
Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
static void
-emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
- rtx frame_reg;
- rtx frame_ptr;
- enum machine_mode mode;
- unsigned int regno;
- int offset;
- int total_size;
+emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
+ unsigned int regno, int offset, HOST_WIDE_INT total_size)
{
rtx reg, offset_rtx, insn, mem, addr, int_rtx;
rtx replacea, replaceb;
@@ -10244,10 +11891,7 @@ emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
converting to a valid addressing mode. */
static rtx
-gen_frame_mem_offset (mode, reg, offset)
- enum machine_mode mode;
- rtx reg;
- int offset;
+gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
{
rtx int_rtx, offset_rtx;
@@ -10267,34 +11911,39 @@ gen_frame_mem_offset (mode, reg, offset)
/* Emit function prologue as insns. */
void
-rs6000_emit_prologue ()
+rs6000_emit_prologue (void)
{
rs6000_stack_t *info = rs6000_stack_info ();
- enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
- int reg_size = TARGET_POWERPC64 ? 8 : 4;
+ enum machine_mode reg_mode = Pmode;
+ int reg_size = TARGET_32BIT ? 4 : 8;
rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
rtx frame_reg_rtx = sp_reg_rtx;
- rtx cr_save_rtx = NULL;
+ rtx cr_save_rtx = NULL_RTX;
rtx insn;
int saving_FPRs_inline;
int using_store_multiple;
HOST_WIDE_INT sp_offset = 0;
- if (TARGET_SPE_ABI)
+ if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
{
reg_mode = V2SImode;
reg_size = 8;
}
using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
- && !TARGET_SPE_ABI
+ && (!TARGET_SPE_ABI
+ || info->spe_64bit_regs_used == 0)
&& info->first_gp_reg_save < 31);
saving_FPRs_inline = (info->first_fp_reg_save == 64
- || FP_SAVE_INLINE (info->first_fp_reg_save));
+ || FP_SAVE_INLINE (info->first_fp_reg_save)
+ || current_function_calls_eh_return
+ || cfun->machine->ra_need_lr);
/* For V.4, update stack before we do any saving and set back pointer. */
- if (info->push_p && DEFAULT_ABI == ABI_V4)
+ if (info->push_p
+ && (DEFAULT_ABI == ABI_V4
+ || current_function_calls_eh_return))
{
if (info->total_size < 32767)
sp_offset = info->total_size;
@@ -10340,7 +11989,8 @@ rs6000_emit_prologue ()
insn = emit_move_insn (mem, savereg);
- altivec_frame_fixup (insn, areg, offset);
+ rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+ areg, GEN_INT (offset));
}
}
@@ -10351,7 +12001,8 @@ rs6000_emit_prologue ()
used in this function, and do the corresponding magic in the
epilogue. */
- if (TARGET_ALTIVEC && info->vrsave_mask != 0)
+ if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
+ && info->vrsave_mask != 0)
{
rtx reg, mem, vrsave;
int offset;
@@ -10474,7 +12125,7 @@ rs6000_emit_prologue ()
rtx addr, reg, mem;
reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
- if (TARGET_SPE_ABI)
+ if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
{
int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
rtx b;
@@ -10521,6 +12172,23 @@ rs6000_emit_prologue ()
{
unsigned int i, regno;
+ /* In AIX ABI we need to pretend we save r2 here. */
+ if (TARGET_AIX)
+ {
+ rtx addr, reg, mem;
+
+ reg = gen_rtx_REG (reg_mode, 2);
+ addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (sp_offset + 5 * reg_size));
+ mem = gen_rtx_MEM (reg_mode, addr);
+ set_mem_alias_set (mem, rs6000_sr_alias_set);
+
+ insn = emit_move_insn (mem, reg);
+ rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+ NULL_RTX, NULL_RTX);
+ PATTERN (insn) = gen_blockage ();
+ }
+
for (i = 0; ; ++i)
{
regno = EH_RETURN_DATA_REGNO (i);
@@ -10568,9 +12236,9 @@ rs6000_emit_prologue ()
insn = emit_move_insn (mem, cr_save_rtx);
/* Now, there's no way that dwarf2out_frame_debug_expr is going
- to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's
- OK. All we have to do is specify that _one_ condition code
- register is saved in this stack slot. The thrower's epilogue
+ to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
+ But that's OK. All we have to do is specify that _one_ condition
+ code register is saved in this stack slot. The thrower's epilogue
will then restore all the call-saved registers.
We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
@@ -10579,7 +12247,8 @@ rs6000_emit_prologue ()
/* Update stack and set back pointer unless this is V.4,
for which it was done previously. */
- if (info->push_p && DEFAULT_ABI != ABI_V4)
+ if (info->push_p
+ && !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
rs6000_emit_allocate_stack (info->total_size, FALSE);
/* Set frame pointer, if needed. */
@@ -10596,21 +12265,23 @@ rs6000_emit_prologue ()
&& regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
{
/* If emit_load_toc_table will use the link register, we need to save
- it. We use R11 for this purpose because emit_load_toc_table
+ it. We use R12 for this purpose because emit_load_toc_table
can use register 0. This allows us to use a plain 'blr' to return
from the procedure more often. */
- int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0
+ int save_LR_around_toc_setup = (TARGET_ELF
+ && DEFAULT_ABI != ABI_AIX
+ && flag_pic
&& ! info->lr_save_p
&& EXIT_BLOCK_PTR->pred != NULL);
if (save_LR_around_toc_setup)
- emit_move_insn (gen_rtx_REG (Pmode, 11),
- gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
-
- rs6000_emit_load_toc_table (TRUE);
-
- if (save_LR_around_toc_setup)
- emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
- gen_rtx_REG (Pmode, 11));
+ {
+ rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
+ rs6000_maybe_dead (emit_move_insn (frame_ptr_rtx, lr));
+ rs6000_emit_load_toc_table (TRUE);
+ rs6000_maybe_dead (emit_move_insn (lr, frame_ptr_rtx));
+ }
+ else
+ rs6000_emit_load_toc_table (TRUE);
}
#if TARGET_MACHO
@@ -10618,8 +12289,8 @@ rs6000_emit_prologue ()
&& flag_pic && current_function_uses_pic_offset_table)
{
rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
- char *picbase = machopic_function_base_name ();
- rtx src = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
+ const char *picbase = machopic_function_base_name ();
+ rtx src = gen_rtx_SYMBOL_REF (Pmode, picbase);
rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest, src)));
@@ -10633,9 +12304,8 @@ rs6000_emit_prologue ()
/* Write function prologue. */
static void
-rs6000_output_function_prologue (file, size)
- FILE *file;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+rs6000_output_function_prologue (FILE *file,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
rs6000_stack_t *info = rs6000_stack_info ();
@@ -10669,11 +12339,11 @@ rs6000_output_function_prologue (file, size)
/* A NOTE_INSN_DELETED is supposed to be at the start and end of
the "toplevel" insn chain. */
- emit_note (0, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
rs6000_emit_prologue ();
- emit_note (0, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
- /* Expand INSN_ADDRESSES so final() doesn't crash. */
+ /* Expand INSN_ADDRESSES so final() doesn't crash. */
{
rtx insn;
unsigned addr = 0;
@@ -10701,8 +12371,7 @@ rs6000_output_function_prologue (file, size)
need special notes to explain where r11 is in relation to the stack. */
void
-rs6000_emit_epilogue (sibcall)
- int sibcall;
+rs6000_emit_epilogue (int sibcall)
{
rs6000_stack_t *info;
int restoring_FPRs_inline;
@@ -10712,19 +12381,21 @@ rs6000_emit_epilogue (sibcall)
int sp_offset = 0;
rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
rtx frame_reg_rtx = sp_reg_rtx;
- enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
- int reg_size = TARGET_POWERPC64 ? 8 : 4;
+ enum machine_mode reg_mode = Pmode;
+ int reg_size = TARGET_32BIT ? 4 : 8;
int i;
- if (TARGET_SPE_ABI)
+ info = rs6000_stack_info ();
+
+ if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
{
reg_mode = V2SImode;
reg_size = 8;
}
- info = rs6000_stack_info ();
using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
- && !TARGET_SPE_ABI
+ && (!TARGET_SPE_ABI
+ || info->spe_64bit_regs_used == 0)
&& info->first_gp_reg_save < 31);
restoring_FPRs_inline = (sibcall
|| current_function_calls_eh_return
@@ -10754,7 +12425,8 @@ rs6000_emit_epilogue (sibcall)
}
else if (info->push_p)
{
- if (DEFAULT_ABI == ABI_V4)
+ if (DEFAULT_ABI == ABI_V4
+ || current_function_calls_eh_return)
sp_offset = info->total_size;
else
{
@@ -10792,7 +12464,8 @@ rs6000_emit_epilogue (sibcall)
}
/* Restore VRSAVE if needed. */
- if (TARGET_ALTIVEC_ABI && info->vrsave_mask != 0)
+ if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
+ && info->vrsave_mask != 0)
{
rtx addr, mem, reg;
@@ -10839,6 +12512,17 @@ rs6000_emit_epilogue (sibcall)
{
unsigned int i, regno;
+ if (TARGET_AIX)
+ {
+ rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (sp_offset + 5 * reg_size));
+ rtx mem = gen_rtx_MEM (reg_mode, addr);
+
+ set_mem_alias_set (mem, rs6000_sr_alias_set);
+
+ emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
+ }
+
for (i = 0; ; ++i)
{
rtx mem;
@@ -10894,7 +12578,7 @@ rs6000_emit_epilogue (sibcall)
rtx mem = gen_rtx_MEM (reg_mode, addr);
/* Restore 64-bit quantities for SPE. */
- if (TARGET_SPE_ABI)
+ if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
{
int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
rtx b;
@@ -10967,7 +12651,7 @@ rs6000_emit_epilogue (sibcall)
RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
RTVEC_ELT (p, ndx) =
gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
- gen_rtx_UNSPEC (CCmode, r, 20));
+ gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
ndx++;
}
emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
@@ -10990,7 +12674,8 @@ rs6000_emit_epilogue (sibcall)
(which may not have any obvious dependency on the stack). This
doesn't hurt performance, because there is no scheduling that can
be done after this point. */
- if (DEFAULT_ABI == ABI_V4)
+ if (DEFAULT_ABI == ABI_V4
+ || current_function_calls_eh_return)
{
if (frame_reg_rtx != sp_reg_rtx)
rs6000_emit_stack_tie ();
@@ -11001,7 +12686,7 @@ rs6000_emit_epilogue (sibcall)
}
else if (sp_offset != 0)
{
- emit_insn (Pmode == SImode
+ emit_insn (TARGET_32BIT
? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
GEN_INT (sp_offset))
: gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
@@ -11012,7 +12697,7 @@ rs6000_emit_epilogue (sibcall)
if (current_function_calls_eh_return)
{
rtx sa = EH_RETURN_STACKADJ_RTX;
- emit_insn (Pmode == SImode
+ emit_insn (TARGET_32BIT
? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
: gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
}
@@ -11067,9 +12752,8 @@ rs6000_emit_epilogue (sibcall)
/* Write function epilogue. */
static void
-rs6000_output_function_epilogue (file, size)
- FILE *file;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+rs6000_output_function_epilogue (FILE *file,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
rs6000_stack_t *info = rs6000_stack_info ();
@@ -11088,11 +12772,11 @@ rs6000_output_function_epilogue (file, size)
/* A NOTE_INSN_DELETED is supposed to be at the start
and end of the "toplevel" insn chain. */
- emit_note (0, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
rs6000_emit_epilogue (FALSE);
- emit_note (0, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
- /* Expand INSN_ADDRESSES so final() doesn't crash. */
+ /* Expand INSN_ADDRESSES so final() doesn't crash. */
{
rtx insn;
unsigned addr = 0;
@@ -11110,7 +12794,8 @@ rs6000_output_function_epilogue (file, size)
}
}
-#if TARGET_OBJECT_FORMAT == OBJECT_MACHO
+#if TARGET_MACHO
+ macho_branch_islands ();
/* Mach-O doesn't support labels at the end of objects, so if
it looks like we might want one, insert a NOP. */
{
@@ -11185,27 +12870,25 @@ rs6000_output_function_epilogue (file, size)
/* Tbtab format type. Use format type 0. */
fputs ("\t.byte 0,", file);
- /* Language type. Unfortunately, there doesn't seem to be any
- official way to get this info, so we use language_string. C
- is 0. C++ is 9. No number defined for Obj-C, so use the
- value for C for now. There is no official value for Java,
- although IBM appears to be using 13. There is no official value
- for Chill, so we've chosen 44 pseudo-randomly. */
- if (! strcmp (language_string, "GNU C")
- || ! strcmp (language_string, "GNU Objective-C"))
+ /* Language type. Unfortunately, there does not seem to be any
+ official way to discover the language being compiled, so we
+ use language_string.
+ C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
+ Java is 13. Objective-C is 14. */
+ if (! strcmp (language_string, "GNU C"))
i = 0;
else if (! strcmp (language_string, "GNU F77"))
i = 1;
- else if (! strcmp (language_string, "GNU Ada"))
- i = 3;
else if (! strcmp (language_string, "GNU Pascal"))
i = 2;
+ else if (! strcmp (language_string, "GNU Ada"))
+ i = 3;
else if (! strcmp (language_string, "GNU C++"))
i = 9;
else if (! strcmp (language_string, "GNU Java"))
i = 13;
- else if (! strcmp (language_string, "GNU CHILL"))
- i = 44;
+ else if (! strcmp (language_string, "GNU Objective-C"))
+ i = 14;
else
abort ();
fprintf (file, "%d,", i);
@@ -11388,163 +13071,103 @@ rs6000_output_function_epilogue (file, size)
not support varargs. */
static void
-rs6000_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
- FILE *file;
- tree thunk_fndecl ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
- tree function;
-{
- const char *this_reg =
- reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
- const char *prefix;
- const char *fname;
- const char *r0 = reg_names[0];
- const char *toc = reg_names[2];
- const char *schain = reg_names[11];
- const char *r12 = reg_names[12];
- char buf[512];
- static int labelno = 0;
-
- /* Small constants that can be done by one add instruction. */
- if (delta >= -32768 && delta <= 32767)
- {
- if (! TARGET_NEW_MNEMONICS)
- fprintf (file, "\tcal %s,%d(%s)\n", this_reg, (int) delta, this_reg);
- else
- fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, (int) delta);
- }
+rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
+ tree function)
+{
+ rtx this, insn, funexp;
- /* 64-bit constants. If "int" is 32 bits, we'll never hit this abort. */
- else if (TARGET_64BIT && (delta < -2147483647 - 1 || delta > 2147483647))
- abort ();
+ reload_completed = 1;
+ epilogue_completed = 1;
+ no_new_pseudos = 1;
- /* Large constants that can be done by one addis instruction. */
- else if ((delta & 0xffff) == 0)
- asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
- (int) (delta >> 16));
+ /* Mark the end of the (empty) prologue. */
+ emit_note (NOTE_INSN_PROLOGUE_END);
- /* 32-bit constants that can be done by an add and addis instruction. */
+ /* Find the "this" pointer. If the function returns a structure,
+ the structure return pointer is in r3. */
+ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
+ this = gen_rtx_REG (Pmode, 4);
else
- {
- /* Break into two pieces, propagating the sign bit from the low
- word to the upper word. */
- int delta_low = ((delta & 0xffff) ^ 0x8000) - 0x8000;
- int delta_high = (delta - delta_low) >> 16;
-
- asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
- delta_high);
+ this = gen_rtx_REG (Pmode, 3);
- if (! TARGET_NEW_MNEMONICS)
- fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg);
- else
- fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
+ /* Apply the constant offset, if required. */
+ if (delta)
+ {
+ rtx delta_rtx = GEN_INT (delta);
+ emit_insn (TARGET_32BIT
+ ? gen_addsi3 (this, this, delta_rtx)
+ : gen_adddi3 (this, this, delta_rtx));
}
- /* Get the prefix in front of the names. */
- switch (DEFAULT_ABI)
+ /* Apply the offset from the vtable, if required. */
+ if (vcall_offset)
{
- default:
- abort ();
+ rtx vcall_offset_rtx = GEN_INT (vcall_offset);
+ rtx tmp = gen_rtx_REG (Pmode, 12);
- case ABI_AIX:
- prefix = ".";
- break;
+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
+ if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
+ {
+ emit_insn (TARGET_32BIT
+ ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
+ : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
+ }
+ else
+ {
+ rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
- case ABI_V4:
- case ABI_AIX_NODESC:
- case ABI_DARWIN:
- prefix = "";
- break;
+ emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
+ }
+ emit_insn (TARGET_32BIT
+ ? gen_addsi3 (this, this, tmp)
+ : gen_adddi3 (this, this, tmp));
}
- /* If the function is compiled in this module, jump to it directly.
- Otherwise, load up its address and jump to it. */
-
- fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
-
- if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
- && (! lookup_attribute ("longcall",
- TYPE_ATTRIBUTES (TREE_TYPE (function)))
- || lookup_attribute ("shortcall",
- TYPE_ATTRIBUTES (TREE_TYPE (function)))))
+ /* Generate a tail call to the target function. */
+ if (!TREE_USED (function))
{
- fprintf (file, "\tb %s", prefix);
- assemble_name (file, fname);
- if (DEFAULT_ABI == ABI_V4 && flag_pic) fputs ("@local", file);
- putc ('\n', file);
+ assemble_external (function);
+ TREE_USED (function) = 1;
}
-
- else
- {
- switch (DEFAULT_ABI)
- {
- default:
- abort ();
-
- case ABI_AIX:
- /* Set up a TOC entry for the function. */
- ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
- toc_section ();
- ASM_OUTPUT_INTERNAL_LABEL (file, "Lthunk", labelno);
- labelno++;
-
- if (TARGET_MINIMAL_TOC)
- fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
- else
- {
- fputs ("\t.tc ", file);
- assemble_name (file, fname);
- fputs ("[TC],", file);
- }
- assemble_name (file, fname);
- putc ('\n', file);
- function_section (current_function_decl);
- if (TARGET_MINIMAL_TOC)
- asm_fprintf (file, (TARGET_32BIT)
- ? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
- TARGET_ELF ? ".LCTOC0@toc" : ".LCTOC..1", toc);
- asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s,", r12);
- assemble_name (file, buf);
- if (TARGET_ELF && TARGET_MINIMAL_TOC)
- fputs ("-(.LCTOC1)", file);
- asm_fprintf (file, "(%s)\n", TARGET_MINIMAL_TOC ? r12 : toc);
- asm_fprintf (file,
- (TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n",
- r0, r12);
-
- asm_fprintf (file,
- (TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n",
- toc, r12);
-
- asm_fprintf (file, "\tmtctr %s\n", r0);
- asm_fprintf (file,
- (TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n",
- schain, r12);
-
- asm_fprintf (file, "\tbctr\n");
- break;
-
- case ABI_AIX_NODESC:
- case ABI_V4:
- fprintf (file, "\tb %s", prefix);
- assemble_name (file, fname);
- if (flag_pic) fputs ("@plt", file);
- putc ('\n', file);
- break;
+ funexp = XEXP (DECL_RTL (function), 0);
+ funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
#if TARGET_MACHO
- case ABI_DARWIN:
- fprintf (file, "\tb %s", prefix);
- if (flag_pic && !machopic_name_defined_p (fname))
- assemble_name (file, machopic_stub_name (fname));
- else
- assemble_name (file, fname);
- putc ('\n', file);
- break;
+ if (MACHOPIC_INDIRECT)
+ funexp = machopic_indirect_call_target (funexp);
#endif
- }
- }
+
+ /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
+ generate sibcall RTL explicitly to avoid constraint abort. */
+ insn = emit_call_insn (
+ gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (4,
+ gen_rtx_CALL (VOIDmode,
+ funexp, const0_rtx),
+ gen_rtx_USE (VOIDmode, const0_rtx),
+ gen_rtx_USE (VOIDmode,
+ gen_rtx_REG (SImode,
+ LINK_REGISTER_REGNUM)),
+ gen_rtx_RETURN (VOIDmode))));
+ SIBLING_CALL_P (insn) = 1;
+ emit_barrier ();
+
+ /* Run just enough of rest_of_compilation to get the insns emitted.
+ There's not really enough bulk here to make other passes such as
+ instruction scheduling worth while. Note that use_thunk calls
+ assemble_start_function and assemble_end_function. */
+ insn = get_insns ();
+ insn_locators_initialize ();
+ shorten_branches (insn);
+ final_start_function (insn, file, 1);
+ final (insn, file, 1, 0);
+ final_end_function ();
+
+ reload_completed = 0;
+ epilogue_completed = 0;
+ no_new_pseudos = 0;
}
/* A quick summary of the various types of 'constant-pool tables'
@@ -11574,24 +13197,10 @@ rs6000_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
*/
-/* Hash table stuff for keeping track of TOC entries. */
-
-struct toc_hash_struct
-{
- /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
- ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
- rtx key;
- enum machine_mode key_mode;
- int labelno;
-};
-
-static htab_t toc_hash_table;
-
/* Hash functions for the hash table. */
static unsigned
-rs6000_hash_constant (k)
- rtx k;
+rs6000_hash_constant (rtx k)
{
enum rtx_code code = GET_CODE (k);
enum machine_mode mode = GET_MODE (k);
@@ -11654,6 +13263,8 @@ rs6000_hash_constant (k)
>> CHAR_BIT * i);
}
break;
+ case '0':
+ break;
default:
abort ();
}
@@ -11662,8 +13273,7 @@ rs6000_hash_constant (k)
}
static unsigned
-toc_hash_function (hash_entry)
- const void * hash_entry;
+toc_hash_function (const void *hash_entry)
{
const struct toc_hash_struct *thc =
(const struct toc_hash_struct *) hash_entry;
@@ -11673,9 +13283,7 @@ toc_hash_function (hash_entry)
/* Compare H1 and H2 for equivalence. */
static int
-toc_hash_eq (h1, h2)
- const void * h1;
- const void * h2;
+toc_hash_eq (const void *h1, const void *h2)
{
rtx r1 = ((const struct toc_hash_struct *) h1)->key;
rtx r2 = ((const struct toc_hash_struct *) h2)->key;
@@ -11687,39 +13295,6 @@ toc_hash_eq (h1, h2)
return rtx_equal_p (r1, r2);
}
-/* Mark the hash table-entry HASH_ENTRY. */
-
-static int
-toc_hash_mark_entry (hash_slot, unused)
- void ** hash_slot;
- void * unused ATTRIBUTE_UNUSED;
-{
- const struct toc_hash_struct * hash_entry =
- *(const struct toc_hash_struct **) hash_slot;
- rtx r = hash_entry->key;
- ggc_set_mark (hash_entry);
- /* For CODE_LABELS, we don't want to drag in the whole insn chain... */
- if (GET_CODE (r) == LABEL_REF)
- {
- ggc_set_mark (r);
- ggc_set_mark (XEXP (r, 0));
- }
- else
- ggc_mark_rtx (r);
- return 1;
-}
-
-/* Mark all the elements of the TOC hash-table *HT. */
-
-static void
-toc_hash_mark_table (vht)
- void *vht;
-{
- htab_t *ht = vht;
-
- htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
-}
-
/* These are the names given by the C++ front-end to vtables, and
vtable-like objects. Ideally, this logic should not be here;
instead, there should be some programmatic way of inquiring as
@@ -11729,12 +13304,11 @@ toc_hash_mark_table (vht)
(strncmp ("_vt.", name, strlen("_vt.")) == 0 \
|| strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
|| strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
+ || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
|| strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
void
-rs6000_output_symbol_ref (file, x)
- FILE *file;
- rtx x;
+rs6000_output_symbol_ref (FILE *file, rtx x)
{
/* Currently C++ toc references to vtables can be emitted before it
is decided whether the vtable is public or private. If this is
@@ -11756,11 +13330,7 @@ rs6000_output_symbol_ref (file, x)
written. */
void
-output_toc (file, x, labelno, mode)
- FILE *file;
- rtx x;
- int labelno;
- enum machine_mode mode;
+output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
{
char buf[256];
const char *name = buf;
@@ -11773,12 +13343,19 @@ output_toc (file, x, labelno, mode)
/* When the linker won't eliminate them, don't output duplicate
TOC entries (this happens on AIX if there is any kind of TOC,
- and on SVR4 under -fPIC or -mrelocatable). */
- if (TARGET_TOC)
+ and on SVR4 under -fPIC or -mrelocatable). Don't do this for
+ CODE_LABELs. */
+ if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
{
struct toc_hash_struct *h;
void * * found;
+ /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
+ time because GGC is not initialized at that point. */
+ if (toc_hash_table == NULL)
+ toc_hash_table = htab_create_ggc (1021, toc_hash_function,
+ toc_hash_eq, NULL);
+
h = ggc_alloc (sizeof (*h));
h->key = x;
h->key_mode = mode;
@@ -11809,7 +13386,7 @@ output_toc (file, x, labelno, mode)
ASM_OUTPUT_ALIGN (file, 3);
}
- ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
+ (*targetm.asm_out.internal_label) (file, "LC", labelno);
/* Handle FP constants specially. Note that if we have a minimal
TOC, things we put here aren't actually in the TOC, so we can allow
@@ -12053,10 +13630,7 @@ output_toc (file, x, labelno, mode)
so we must artificially break them up early. */
void
-output_ascii (file, p, n)
- FILE *file;
- const char *p;
- int n;
+output_ascii (FILE *file, const char *p, int n)
{
char c;
int i, count_string;
@@ -12127,10 +13701,8 @@ output_ascii (file, p, n)
the name. */
void
-rs6000_gen_section_name (buf, filename, section_desc)
- char **buf;
- const char *filename;
- const char *section_desc;
+rs6000_gen_section_name (char **buf, const char *filename,
+ const char *section_desc)
{
const char *q, *after_last_slash, *last_period = 0;
char *p;
@@ -12157,6 +13729,7 @@ rs6000_gen_section_name (buf, filename, section_desc)
{
strcpy (p, section_desc);
p += strlen (section_desc);
+ break;
}
else if (ISALNUM (*q))
@@ -12172,25 +13745,31 @@ rs6000_gen_section_name (buf, filename, section_desc)
/* Emit profile function. */
void
-output_profile_hook (labelno)
- int labelno ATTRIBUTE_UNUSED;
+output_profile_hook (int labelno ATTRIBUTE_UNUSED)
{
+ if (TARGET_PROFILE_KERNEL)
+ return;
+
if (DEFAULT_ABI == ABI_AIX)
{
-#ifdef NO_PROFILE_COUNTERS
- emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
-#else
- char buf[30];
- const char *label_name;
- rtx fun;
+#ifndef NO_PROFILE_COUNTERS
+# define NO_PROFILE_COUNTERS 0
+#endif
+ if (NO_PROFILE_COUNTERS)
+ emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
+ else
+ {
+ char buf[30];
+ const char *label_name;
+ rtx fun;
- ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
- label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
- fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
+ label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
+ fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
- emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
- fun, Pmode);
-#endif
+ emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
+ fun, Pmode);
+ }
}
else if (DEFAULT_ABI == ABI_DARWIN)
{
@@ -12203,7 +13782,7 @@ output_profile_hook (labelno)
#if TARGET_MACHO
/* For PIC code, set up a stub and collect the caller's address
from r0, which is where the prologue puts it. */
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
{
mcount_name = machopic_stub_name (mcount_name);
if (current_function_uses_pic_offset_table)
@@ -12219,14 +13798,11 @@ output_profile_hook (labelno)
/* Write function profiler code. */
void
-output_function_profiler (file, labelno)
- FILE *file;
- int labelno;
+output_function_profiler (FILE *file, int labelno)
{
char buf[100];
int save_lr = 8;
- ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
switch (DEFAULT_ABI)
{
default:
@@ -12234,14 +13810,12 @@ output_function_profiler (file, labelno)
case ABI_V4:
save_lr = 4;
- /* Fall through. */
-
- case ABI_AIX_NODESC:
if (!TARGET_32BIT)
{
warning ("no profiling of 64-bit code for this ABI");
return;
}
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
fprintf (file, "\tmflr %s\n", reg_names[0]);
if (flag_pic == 1)
{
@@ -12279,37 +13853,80 @@ output_function_profiler (file, labelno)
asm_fprintf (file, "@l(%s)\n", reg_names[12]);
}
- if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC)
- {
- asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
- reg_names[STATIC_CHAIN_REGNUM],
- 12, reg_names[1]);
- fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
- asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
- reg_names[STATIC_CHAIN_REGNUM],
- 12, reg_names[1]);
- }
- else
- /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
- fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
+ /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
+ fprintf (file, "\tbl %s%s\n",
+ RS6000_MCOUNT, flag_pic ? "@plt" : "");
+
break;
case ABI_AIX:
case ABI_DARWIN:
- /* Don't do anything, done in output_profile_hook (). */
+ if (!TARGET_PROFILE_KERNEL)
+ {
+ /* Don't do anything, done in output_profile_hook (). */
+ }
+ else
+ {
+ if (TARGET_32BIT)
+ abort ();
+
+ asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
+ asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
+
+ if (current_function_needs_context)
+ {
+ asm_fprintf (file, "\tstd %s,24(%s)\n",
+ reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
+ fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
+ asm_fprintf (file, "\tld %s,24(%s)\n",
+ reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
+ }
+ else
+ fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
+ }
break;
}
}
+
+static int
+rs6000_use_dfa_pipeline_interface (void)
+{
+ return 1;
+}
+
+/* Power4 load update and store update instructions are cracked into a
+ load or store and an integer insn which are executed in the same cycle.
+ Branches have their own dispatch slot which does not count against the
+ GCC issue rate, but it changes the program flow so there are no other
+ instructions to issue in this cycle. */
+
+static int
+rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
+ int verbose ATTRIBUTE_UNUSED,
+ rtx insn, int more)
+{
+ if (GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return more;
+
+ if (rs6000_sched_groups)
+ {
+ if (is_microcoded_insn (insn))
+ return 0;
+ else if (is_cracked_insn (insn))
+ return more > 2 ? more - 2 : 0;
+ }
+
+ return more - 1;
+}
+
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
static int
-rs6000_adjust_cost (insn, link, dep_insn, cost)
- rtx insn;
- rtx link;
- rtx dep_insn ATTRIBUTE_UNUSED;
- int cost;
+rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn ATTRIBUTE_UNUSED,
+ int cost)
{
if (! recog_memoized (insn))
return 0;
@@ -12341,13 +13958,18 @@ rs6000_adjust_cost (insn, link, dep_insn, cost)
|| rs6000_cpu_attr == CPU_PPC750
|| rs6000_cpu_attr == CPU_PPC7400
|| rs6000_cpu_attr == CPU_PPC7450
- || rs6000_cpu_attr == CPU_POWER4)
+ || rs6000_cpu_attr == CPU_POWER4
+ || rs6000_cpu_attr == CPU_POWER5)
&& recog_memoized (dep_insn)
&& (INSN_CODE (dep_insn) >= 0)
- && (get_attr_type (dep_insn) == TYPE_COMPARE
+ && (get_attr_type (dep_insn) == TYPE_CMP
+ || get_attr_type (dep_insn) == TYPE_COMPARE
|| get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
+ || get_attr_type (dep_insn) == TYPE_IMUL_COMPARE
+ || get_attr_type (dep_insn) == TYPE_LMUL_COMPARE
|| get_attr_type (dep_insn) == TYPE_FPCOMPARE
- || get_attr_type (dep_insn) == TYPE_CR_LOGICAL))
+ || get_attr_type (dep_insn) == TYPE_CR_LOGICAL
+ || get_attr_type (dep_insn) == TYPE_DELAYED_CR))
return cost + 2;
default:
break;
@@ -12358,16 +13980,133 @@ rs6000_adjust_cost (insn, link, dep_insn, cost)
return cost;
}
+/* The function returns a true if INSN is microcoded.
+ Return false otherwise. */
+
+static bool
+is_microcoded_insn (rtx insn)
+{
+ if (!insn || !INSN_P (insn)
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return false;
+
+ if (rs6000_sched_groups)
+ {
+ enum attr_type type = get_attr_type (insn);
+ if (type == TYPE_LOAD_EXT_U
+ || type == TYPE_LOAD_EXT_UX
+ || type == TYPE_LOAD_UX
+ || type == TYPE_STORE_UX
+ || type == TYPE_MFCR)
+ return true;
+ }
+
+ return false;
+}
+
+/* The function returns a nonzero value if INSN can be scheduled only
+ as the first insn in a dispatch group ("dispatch-slot restricted").
+ In this case, the returned value indicates how many dispatch slots
+ the insn occupies (at the beginning of the group).
+ Return 0 otherwise. */
+
+static int
+is_dispatch_slot_restricted (rtx insn)
+{
+ enum attr_type type;
+
+ if (!rs6000_sched_groups)
+ return 0;
+
+ if (!insn
+ || insn == NULL_RTX
+ || GET_CODE (insn) == NOTE
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return 0;
+
+ type = get_attr_type (insn);
+
+ switch (type)
+ {
+ case TYPE_MFCR:
+ case TYPE_MFCRF:
+ case TYPE_MTCR:
+ case TYPE_DELAYED_CR:
+ case TYPE_CR_LOGICAL:
+ case TYPE_MTJMPR:
+ case TYPE_MFJMPR:
+ return 1;
+ case TYPE_IDIV:
+ case TYPE_LDIV:
+ return 2;
+ default:
+ if (rs6000_cpu == PROCESSOR_POWER5
+ && is_cracked_insn (insn))
+ return 2;
+ return 0;
+ }
+}
+
+/* The function returns true if INSN is cracked into 2 instructions
+ by the processor (and therefore occupies 2 issue slots). */
+
+static bool
+is_cracked_insn (rtx insn)
+{
+ if (!insn || !INSN_P (insn)
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return false;
+
+ if (rs6000_sched_groups)
+ {
+ enum attr_type type = get_attr_type (insn);
+ if (type == TYPE_LOAD_U || type == TYPE_STORE_U
+ || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
+ || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
+ || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
+ || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
+ || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
+ || type == TYPE_IDIV || type == TYPE_LDIV
+ || type == TYPE_INSERT_WORD)
+ return true;
+ }
+
+ return false;
+}
+
+/* The function returns true if INSN can be issued only from
+ the branch slot. */
+
+static bool
+is_branch_slot_insn (rtx insn)
+{
+ if (!insn || !INSN_P (insn)
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return false;
+
+ if (rs6000_sched_groups)
+ {
+ enum attr_type type = get_attr_type (insn);
+ if (type == TYPE_BRANCH || type == TYPE_JMPREG)
+ return true;
+ return false;
+ }
+
+ return false;
+}
+
/* A C statement (sans semicolon) to update the integer scheduling
- priority INSN_PRIORITY (INSN). Reduce the priority to execute the
- INSN earlier, increase the priority to execute INSN later. Do not
+ priority INSN_PRIORITY (INSN). Increase the priority to execute the
+ INSN earlier, reduce the priority to execute INSN later. Do not
define this macro if you do not need to adjust the scheduling
priorities of insns. */
static int
-rs6000_adjust_priority (insn, priority)
- rtx insn ATTRIBUTE_UNUSED;
- int priority;
+rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
{
/* On machines (like the 750) which have asymmetric integer units,
where one integer unit can do multiply and divides and the other
@@ -12399,41 +14138,637 @@ rs6000_adjust_priority (insn, priority)
}
#endif
+ if (is_dispatch_slot_restricted (insn)
+ && reload_completed
+ && current_sched_info->sched_max_insns_priority
+ && rs6000_sched_restricted_insns_priority)
+ {
+
+ /* Prioritize insns that can be dispatched only in the first dispatch slot. */
+ if (rs6000_sched_restricted_insns_priority == 1)
+ /* Attach highest priority to insn. This means that in
+ haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
+ precede 'priority' (critical path) considerations. */
+ return current_sched_info->sched_max_insns_priority;
+ else if (rs6000_sched_restricted_insns_priority == 2)
+ /* Increase priority of insn by a minimal amount. This means that in
+ haifa-sched.c:ready_sort(), only 'priority' (critical path) considerations
+ precede dispatch-slot restriction considerations. */
+ return (priority + 1);
+ }
+
return priority;
}
/* Return how many instructions the machine can issue per cycle. */
static int
-rs6000_issue_rate ()
+rs6000_issue_rate (void)
{
+ /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
+ if (!reload_completed)
+ return 1;
+
switch (rs6000_cpu_attr) {
case CPU_RIOS1: /* ? */
case CPU_RS64A:
case CPU_PPC601: /* ? */
case CPU_PPC7450:
return 3;
+ case CPU_PPC440:
case CPU_PPC603:
case CPU_PPC750:
case CPU_PPC7400:
+ case CPU_PPC8540:
return 2;
case CPU_RIOS2:
case CPU_PPC604:
case CPU_PPC604E:
case CPU_PPC620:
case CPU_PPC630:
- case CPU_POWER4:
return 4;
+ case CPU_POWER4:
+ case CPU_POWER5:
+ return 5;
default:
return 1;
}
}
+/* Return how many instructions to look ahead for better insn
+ scheduling. */
+
+static int
+rs6000_use_sched_lookahead (void)
+{
+ if (rs6000_cpu_attr == CPU_PPC8540)
+ return 4;
+ return 0;
+}
+
+/* Determine is PAT refers to memory. */
+
+static bool
+is_mem_ref (rtx pat)
+{
+ const char * fmt;
+ int i, j;
+ bool ret = false;
+
+ if (GET_CODE (pat) == MEM)
+ return true;
+
+ /* Recursively process the pattern. */
+ fmt = GET_RTX_FORMAT (GET_CODE (pat));
+
+ for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
+ {
+ if (fmt[i] == 'e')
+ ret |= is_mem_ref (XEXP (pat, i));
+ else if (fmt[i] == 'E')
+ for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
+ ret |= is_mem_ref (XVECEXP (pat, i, j));
+ }
+
+ return ret;
+}
+
+/* Determine if PAT is a PATTERN of a load insn. */
+
+static bool
+is_load_insn1 (rtx pat)
+{
+ if (!pat || pat == NULL_RTX)
+ return false;
+
+ if (GET_CODE (pat) == SET)
+ return is_mem_ref (SET_SRC (pat));
+
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ int i;
+
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ if (is_load_insn1 (XVECEXP (pat, 0, i)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Determine if INSN loads from memory. */
+
+static bool
+is_load_insn (rtx insn)
+{
+ if (!insn || !INSN_P (insn))
+ return false;
+
+ if (GET_CODE (insn) == CALL_INSN)
+ return false;
+
+ return is_load_insn1 (PATTERN (insn));
+}
+
+/* Determine if PAT is a PATTERN of a store insn. */
+
+static bool
+is_store_insn1 (rtx pat)
+{
+ if (!pat || pat == NULL_RTX)
+ return false;
+
+ if (GET_CODE (pat) == SET)
+ return is_mem_ref (SET_DEST (pat));
+
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ int i;
+
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ if (is_store_insn1 (XVECEXP (pat, 0, i)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Determine if INSN stores to memory. */
+
+static bool
+is_store_insn (rtx insn)
+{
+ if (!insn || !INSN_P (insn))
+ return false;
+
+ return is_store_insn1 (PATTERN (insn));
+}
+
+/* Returns whether the dependence between INSN and NEXT is considered
+ costly by the given target. */
+
+static bool
+rs6000_is_costly_dependence (rtx insn, rtx next, rtx link, int cost, int distance)
+{
+ /* If the flag is not enbled - no dependence is considered costly;
+ allow all dependent insns in the same group.
+ This is the most aggressive option. */
+ if (rs6000_sched_costly_dep == no_dep_costly)
+ return false;
+
+ /* If the flag is set to 1 - a dependence is always considered costly;
+ do not allow dependent instructions in the same group.
+ This is the most conservative option. */
+ if (rs6000_sched_costly_dep == all_deps_costly)
+ return true;
+
+ if (rs6000_sched_costly_dep == store_to_load_dep_costly
+ && is_load_insn (next)
+ && is_store_insn (insn))
+ /* Prevent load after store in the same group. */
+ return true;
+
+ if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
+ && is_load_insn (next)
+ && is_store_insn (insn)
+ && (!link || (int) REG_NOTE_KIND (link) == 0))
+ /* Prevent load after store in the same group if it is a true dependence. */
+ return true;
+
+ /* The flag is set to X; dependences with latency >= X are considered costly,
+ and will not be scheduled in the same group. */
+ if (rs6000_sched_costly_dep <= max_dep_latency
+ && ((cost - distance) >= (int)rs6000_sched_costly_dep))
+ return true;
+
+ return false;
+}
+
+/* Return the next insn after INSN that is found before TAIL is reached,
+ skipping any "non-active" insns - insns that will not actually occupy
+ an issue slot. Return NULL_RTX if such an insn is not found. */
+
+static rtx
+get_next_active_insn (rtx insn, rtx tail)
+{
+ rtx next_insn;
+
+ if (!insn || insn == tail)
+ return NULL_RTX;
+
+ next_insn = NEXT_INSN (insn);
+
+ while (next_insn
+ && next_insn != tail
+ && (GET_CODE(next_insn) == NOTE
+ || GET_CODE (PATTERN (next_insn)) == USE
+ || GET_CODE (PATTERN (next_insn)) == CLOBBER))
+ {
+ next_insn = NEXT_INSN (next_insn);
+ }
+
+ if (!next_insn || next_insn == tail)
+ return NULL_RTX;
+
+ return next_insn;
+}
+
+/* Return whether the presence of INSN causes a dispatch group termination
+ of group WHICH_GROUP.
+
+ If WHICH_GROUP == current_group, this function will return true if INSN
+ causes the termination of the current group (i.e, the dispatch group to
+ which INSN belongs). This means that INSN will be the last insn in the
+ group it belongs to.
+
+ If WHICH_GROUP == previous_group, this function will return true if INSN
+ causes the termination of the previous group (i.e, the dispatch group that
+ precedes the group to which INSN belongs). This means that INSN will be
+ the first insn in the group it belongs to). */
+
+static bool
+insn_terminates_group_p (rtx insn, enum group_termination which_group)
+{
+ enum attr_type type;
+
+ if (! insn)
+ return false;
+
+ type = get_attr_type (insn);
+
+ if (is_microcoded_insn (insn))
+ return true;
+
+ if (which_group == current_group)
+ {
+ if (is_branch_slot_insn (insn))
+ return true;
+ return false;
+ }
+ else if (which_group == previous_group)
+ {
+ if (is_dispatch_slot_restricted (insn))
+ return true;
+ return false;
+ }
+
+ return false;
+}
+
+/* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
+ dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
+
+static bool
+is_costly_group (rtx *group_insns, rtx next_insn)
+{
+ int i;
+ rtx link;
+ int cost;
+ int issue_rate = rs6000_issue_rate ();
+
+ for (i = 0; i < issue_rate; i++)
+ {
+ rtx insn = group_insns[i];
+ if (!insn)
+ continue;
+ for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
+ {
+ rtx next = XEXP (link, 0);
+ if (next == next_insn)
+ {
+ cost = insn_cost (insn, link, next_insn);
+ if (rs6000_is_costly_dependence (insn, next_insn, link, cost, 0))
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/* Utility of the function redefine_groups.
+ Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
+ in the same dispatch group. If so, insert nops before NEXT_INSN, in order
+ to keep it "far" (in a separate group) from GROUP_INSNS, following
+ one of the following schemes, depending on the value of the flag
+ -minsert_sched_nops = X:
+ (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
+ in order to force NEXT_INSN into a separate group.
+ (2) X < sched_finish_regroup_exact: insert exactly X nops.
+ GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
+ insertion (has a group just ended, how many vacant issue slots remain in the
+ last group, and how many dispatch groups were encountered so far). */
+
+static int
+force_new_group (int sched_verbose, FILE *dump, rtx *group_insns, rtx next_insn,
+ bool *group_end, int can_issue_more, int *group_count)
+{
+ rtx nop;
+ bool force;
+ int issue_rate = rs6000_issue_rate ();
+ bool end = *group_end;
+ int i;
+
+ if (next_insn == NULL_RTX)
+ return can_issue_more;
+
+ if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
+ return can_issue_more;
+
+ force = is_costly_group (group_insns, next_insn);
+ if (!force)
+ return can_issue_more;
+
+ if (sched_verbose > 6)
+ fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
+ *group_count ,can_issue_more);
+
+ if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
+ {
+ if (*group_end)
+ can_issue_more = 0;
+
+ /* Since only a branch can be issued in the last issue_slot, it is
+ sufficient to insert 'can_issue_more - 1' nops if next_insn is not
+ a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
+ in this case the last nop will start a new group and the branch will be
+ forced to the new group. */
+ if (can_issue_more && !is_branch_slot_insn (next_insn))
+ can_issue_more--;
+
+ while (can_issue_more > 0)
+ {
+ nop = gen_nop();
+ emit_insn_before (nop, next_insn);
+ can_issue_more--;
+ }
+
+ *group_end = true;
+ return 0;
+ }
+
+ if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
+ {
+ int n_nops = rs6000_sched_insert_nops;
+
+ /* Nops can't be issued from the branch slot, so the effective
+ issue_rate for nops is 'issue_rate - 1'. */
+ if (can_issue_more == 0)
+ can_issue_more = issue_rate;
+ can_issue_more--;
+ if (can_issue_more == 0)
+ {
+ can_issue_more = issue_rate - 1;
+ (*group_count)++;
+ end = true;
+ for (i = 0; i < issue_rate; i++)
+ {
+ group_insns[i] = 0;
+ }
+ }
+
+ while (n_nops > 0)
+ {
+ nop = gen_nop ();
+ emit_insn_before (nop, next_insn);
+ if (can_issue_more == issue_rate - 1) /* new group begins */
+ end = false;
+ can_issue_more--;
+ if (can_issue_more == 0)
+ {
+ can_issue_more = issue_rate - 1;
+ (*group_count)++;
+ end = true;
+ for (i = 0; i < issue_rate; i++)
+ {
+ group_insns[i] = 0;
+ }
+ }
+ n_nops--;
+ }
+
+ /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
+ can_issue_more++;
+
+ *group_end = /* Is next_insn going to start a new group? */
+ (end
+ || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
+ || (can_issue_more <= 2 && is_cracked_insn (next_insn))
+ || (can_issue_more < issue_rate &&
+ insn_terminates_group_p (next_insn, previous_group)));
+ if (*group_end && end)
+ (*group_count)--;
+
+ if (sched_verbose > 6)
+ fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
+ *group_count, can_issue_more);
+ return can_issue_more;
+ }
+
+ return can_issue_more;
+}
+
+/* This function tries to synch the dispatch groups that the compiler "sees"
+ with the dispatch groups that the processor dispatcher is expected to
+ form in practice. It tries to achieve this synchronization by forcing the
+ estimated processor grouping on the compiler (as opposed to the function
+ 'pad_goups' which tries to force the scheduler's grouping on the processor).
+
+ The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
+ examines the (estimated) dispatch groups that will be formed by the processor
+ dispatcher. It marks these group boundaries to reflect the estimated
+ processor grouping, overriding the grouping that the scheduler had marked.
+ Depending on the value of the flag '-minsert-sched-nops' this function can
+ force certain insns into separate groups or force a certain distance between
+ them by inserting nops, for example, if there exists a "costly dependence"
+ between the insns.
+
+ The function estimates the group boundaries that the processor will form as
+ folllows: It keeps track of how many vacant issue slots are available after
+ each insn. A subsequent insn will start a new group if one of the following
+ 4 cases applies:
+ - no more vacant issue slots remain in the current dispatch group.
+ - only the last issue slot, which is the branch slot, is vacant, but the next
+ insn is not a branch.
+ - only the last 2 or less issue slots, including the branch slot, are vacant,
+ which means that a cracked insn (which occupies two issue slots) can't be
+ issued in this group.
+ - less than 'issue_rate' slots are vacant, and the next insn always needs to
+ start a new group. */
+
+static int
+redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
+{
+ rtx insn, next_insn;
+ int issue_rate;
+ int can_issue_more;
+ int slot, i;
+ bool group_end;
+ int group_count = 0;
+ rtx *group_insns;
+
+ /* Initialize. */
+ issue_rate = rs6000_issue_rate ();
+ group_insns = alloca (issue_rate * sizeof (rtx));
+ for (i = 0; i < issue_rate; i++)
+ {
+ group_insns[i] = 0;
+ }
+ can_issue_more = issue_rate;
+ slot = 0;
+ insn = get_next_active_insn (prev_head_insn, tail);
+ group_end = false;
+
+ while (insn != NULL_RTX)
+ {
+ slot = (issue_rate - can_issue_more);
+ group_insns[slot] = insn;
+ can_issue_more =
+ rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
+ if (insn_terminates_group_p (insn, current_group))
+ can_issue_more = 0;
+
+ next_insn = get_next_active_insn (insn, tail);
+ if (next_insn == NULL_RTX)
+ return group_count + 1;
+
+ group_end = /* Is next_insn going to start a new group? */
+ (can_issue_more == 0
+ || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
+ || (can_issue_more <= 2 && is_cracked_insn (next_insn))
+ || (can_issue_more < issue_rate &&
+ insn_terminates_group_p (next_insn, previous_group)));
+
+ can_issue_more = force_new_group (sched_verbose, dump, group_insns,
+ next_insn, &group_end, can_issue_more, &group_count);
+
+ if (group_end)
+ {
+ group_count++;
+ can_issue_more = 0;
+ for (i = 0; i < issue_rate; i++)
+ {
+ group_insns[i] = 0;
+ }
+ }
+
+ if (GET_MODE (next_insn) == TImode && can_issue_more)
+ PUT_MODE(next_insn, VOIDmode);
+ else if (!can_issue_more && GET_MODE (next_insn) != TImode)
+ PUT_MODE (next_insn, TImode);
+
+ insn = next_insn;
+ if (can_issue_more == 0)
+ can_issue_more = issue_rate;
+ } /* while */
+
+ return group_count;
+}
+
+/* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
+ dispatch group boundaries that the scheduler had marked. Pad with nops
+ any dispatch groups which have vacant issue slots, in order to force the
+ scheduler's grouping on the processor dispatcher. The function
+ returns the number of dispatch groups found. */
+
+static int
+pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
+{
+ rtx insn, next_insn;
+ rtx nop;
+ int issue_rate;
+ int can_issue_more;
+ int group_end;
+ int group_count = 0;
+
+ /* Initialize issue_rate. */
+ issue_rate = rs6000_issue_rate ();
+ can_issue_more = issue_rate;
+
+ insn = get_next_active_insn (prev_head_insn, tail);
+ next_insn = get_next_active_insn (insn, tail);
+
+ while (insn != NULL_RTX)
+ {
+ can_issue_more =
+ rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
+
+ group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
+
+ if (next_insn == NULL_RTX)
+ break;
+
+ if (group_end)
+ {
+ /* If the scheduler had marked group termination at this location
+ (between insn and next_indn), and neither insn nor next_insn will
+ force group termination, pad the group with nops to force group
+ termination. */
+ if (can_issue_more
+ && (rs6000_sched_insert_nops == sched_finish_pad_groups)
+ && !insn_terminates_group_p (insn, current_group)
+ && !insn_terminates_group_p (next_insn, previous_group))
+ {
+ if (!is_branch_slot_insn(next_insn))
+ can_issue_more--;
+
+ while (can_issue_more)
+ {
+ nop = gen_nop ();
+ emit_insn_before (nop, next_insn);
+ can_issue_more--;
+ }
+ }
+
+ can_issue_more = issue_rate;
+ group_count++;
+ }
+
+ insn = next_insn;
+ next_insn = get_next_active_insn (insn, tail);
+ }
+
+ return group_count;
+}
+
+/* The following function is called at the end of scheduling BB.
+ After reload, it inserts nops at insn group bundling. */
+
+static void
+rs6000_sched_finish (FILE *dump, int sched_verbose)
+{
+ int n_groups;
+
+ if (sched_verbose)
+ fprintf (dump, "=== Finishing schedule.\n");
+
+ if (reload_completed && rs6000_sched_groups)
+ {
+ if (rs6000_sched_insert_nops == sched_finish_none)
+ return;
+
+ if (rs6000_sched_insert_nops == sched_finish_pad_groups)
+ n_groups = pad_groups (dump, sched_verbose,
+ current_sched_info->prev_head,
+ current_sched_info->next_tail);
+ else
+ n_groups = redefine_groups (dump, sched_verbose,
+ current_sched_info->prev_head,
+ current_sched_info->next_tail);
+
+ if (sched_verbose >= 6)
+ {
+ fprintf (dump, "ngroups = %d\n", n_groups);
+ print_rtl (dump, current_sched_info->prev_head);
+ fprintf (dump, "Done finish_sched\n");
+ }
+ }
+}
/* Length in units of the trampoline for entering a nested function. */
int
-rs6000_trampoline_size ()
+rs6000_trampoline_size (void)
{
int ret = 0;
@@ -12448,7 +14783,6 @@ rs6000_trampoline_size ()
case ABI_DARWIN:
case ABI_V4:
- case ABI_AIX_NODESC:
ret = (TARGET_32BIT) ? 40 : 48;
break;
}
@@ -12461,10 +14795,7 @@ rs6000_trampoline_size ()
CXT is an RTX for the static chain value for the function. */
void
-rs6000_initialize_trampoline (addr, fnaddr, cxt)
- rtx addr;
- rtx fnaddr;
- rtx cxt;
+rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
{
enum machine_mode pmode = Pmode;
int regsize = (TARGET_32BIT) ? 4 : 8;
@@ -12496,7 +14827,6 @@ rs6000_initialize_trampoline (addr, fnaddr, cxt)
/* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
case ABI_DARWIN:
case ABI_V4:
- case ABI_AIX_NODESC:
emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
FALSE, VOIDmode, 4,
addr, pmode,
@@ -12524,12 +14854,10 @@ const struct attribute_spec rs6000_attribute_table[] =
struct attribute_spec.handler. */
static tree
-rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+rs6000_handle_longcall_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
{
if (TREE_CODE (*node) != FUNCTION_TYPE
&& TREE_CODE (*node) != FIELD_DECL
@@ -12546,8 +14874,7 @@ rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
/* Set longcall attributes on all functions declared when
rs6000_default_long_calls is true. */
static void
-rs6000_set_default_type_attributes (type)
- tree type;
+rs6000_set_default_type_attributes (tree type)
{
if (rs6000_default_long_calls
&& (TREE_CODE (type) == FUNCTION_TYPE
@@ -12561,8 +14888,7 @@ rs6000_set_default_type_attributes (type)
longcall attribute. */
struct rtx_def *
-rs6000_longcall_ref (call_ref)
- rtx call_ref;
+rs6000_longcall_ref (rtx call_ref)
{
const char *call_name;
tree node;
@@ -12583,7 +14909,6 @@ rs6000_longcall_ref (call_ref)
return force_reg (Pmode, call_ref);
}
-
#ifdef USING_ELFOS_H
@@ -12597,10 +14922,8 @@ rs6000_longcall_ref (call_ref)
data section. */
static void
-rs6000_elf_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align;
+rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align)
{
if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
toc_section ();
@@ -12614,11 +14937,13 @@ rs6000_elf_select_rtx_section (mode, x, align)
the initial value of DECL requires link-time relocations. */
static void
-rs6000_elf_select_section (decl, reloc, align)
- tree decl;
- int reloc;
- unsigned HOST_WIDE_INT align;
+rs6000_elf_select_section (tree decl, int reloc,
+ unsigned HOST_WIDE_INT align)
{
+ /* Pretend that we're always building for a shared library when
+ ABI_AIX, because otherwise we end up with dynamic relocations
+ in read-only sections. This happens for function pointers,
+ references to vtables in typeinfo, and probably other cases. */
default_elf_select_section_1 (decl, reloc, align,
flag_pic || DEFAULT_ABI == ABI_AIX);
}
@@ -12632,110 +14957,43 @@ rs6000_elf_select_section (decl, reloc, align)
initialized data and functions. */
static void
-rs6000_elf_unique_section (decl, reloc)
- tree decl;
- int reloc;
+rs6000_elf_unique_section (tree decl, int reloc)
{
+ /* As above, pretend that we're always building for a shared library
+ when ABI_AIX, to avoid dynamic relocations in read-only sections. */
default_unique_section_1 (decl, reloc,
flag_pic || DEFAULT_ABI == ABI_AIX);
}
-
-/* If we are referencing a function that is static or is known to be
- in this file, make the SYMBOL_REF special. We can use this to indicate
- that we can branch to this function without emitting a no-op after the
- call. For real AIX calling sequences, we also replace the
- function name with the real name (1 or 2 leading .'s), rather than
- the function descriptor name. This saves a lot of overriding code
- to read the prefixes. */
+/* For a SYMBOL_REF, set generic flags and then perform some
+ target-specific processing.
+
+ When the AIX ABI is requested on a non-AIX system, replace the
+ function name with the real name (with a leading .) rather than the
+ function descriptor name. This saves a lot of overriding code to
+ read the prefixes. */
static void
-rs6000_elf_encode_section_info (decl, first)
- tree decl;
- int first;
+rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
{
- if (!first)
- return;
+ default_encode_section_info (decl, rtl, first);
- if (TREE_CODE (decl) == FUNCTION_DECL)
+ if (first
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && !TARGET_AIX
+ && DEFAULT_ABI == ABI_AIX)
{
- rtx sym_ref = XEXP (DECL_RTL (decl), 0);
- if ((*targetm.binds_local_p) (decl))
- SYMBOL_REF_FLAG (sym_ref) = 1;
-
- if (DEFAULT_ABI == ABI_AIX)
- {
- size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
- size_t len2 = strlen (XSTR (sym_ref, 0));
- char *str = alloca (len1 + len2 + 1);
- str[0] = '.';
- str[1] = '.';
- memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
-
- XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
- }
+ rtx sym_ref = XEXP (rtl, 0);
+ size_t len = strlen (XSTR (sym_ref, 0));
+ char *str = alloca (len + 2);
+ str[0] = '.';
+ memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
+ XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
}
- else if (rs6000_sdata != SDATA_NONE
- && DEFAULT_ABI == ABI_V4
- && TREE_CODE (decl) == VAR_DECL)
- {
- rtx sym_ref = XEXP (DECL_RTL (decl), 0);
- int size = int_size_in_bytes (TREE_TYPE (decl));
- tree section_name = DECL_SECTION_NAME (decl);
- const char *name = (char *)0;
- int len = 0;
-
- if ((*targetm.binds_local_p) (decl))
- SYMBOL_REF_FLAG (sym_ref) = 1;
-
- if (section_name)
- {
- if (TREE_CODE (section_name) == STRING_CST)
- {
- name = TREE_STRING_POINTER (section_name);
- len = TREE_STRING_LENGTH (section_name);
- }
- else
- abort ();
- }
-
- if ((size > 0 && size <= g_switch_value)
- || (name
- && ((len == sizeof (".sdata") - 1
- && strcmp (name, ".sdata") == 0)
- || (len == sizeof (".sdata2") - 1
- && strcmp (name, ".sdata2") == 0)
- || (len == sizeof (".sbss") - 1
- && strcmp (name, ".sbss") == 0)
- || (len == sizeof (".sbss2") - 1
- && strcmp (name, ".sbss2") == 0)
- || (len == sizeof (".PPC.EMB.sdata0") - 1
- && strcmp (name, ".PPC.EMB.sdata0") == 0)
- || (len == sizeof (".PPC.EMB.sbss0") - 1
- && strcmp (name, ".PPC.EMB.sbss0") == 0))))
- {
- size_t len = strlen (XSTR (sym_ref, 0));
- char *str = alloca (len + 2);
-
- str[0] = '@';
- memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
- XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
- }
- }
-}
-
-static const char *
-rs6000_elf_strip_name_encoding (str)
- const char *str;
-{
- while (*str == '*' || *str == '@')
- str++;
- return str;
}
static bool
-rs6000_elf_in_small_data_p (decl)
- tree decl;
+rs6000_elf_in_small_data_p (tree decl)
{
if (rs6000_sdata == SDATA_NONE)
return false;
@@ -12745,7 +15003,10 @@ rs6000_elf_in_small_data_p (decl)
const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
if (strcmp (section, ".sdata") == 0
|| strcmp (section, ".sdata2") == 0
- || strcmp (section, ".sbss") == 0)
+ || strcmp (section, ".sbss") == 0
+ || strcmp (section, ".sbss2") == 0
+ || strcmp (section, ".PPC.EMB.sdata0") == 0
+ || strcmp (section, ".PPC.EMB.sbss0") == 0)
return true;
}
else
@@ -12753,7 +15014,9 @@ rs6000_elf_in_small_data_p (decl)
HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
if (size > 0
- && size <= g_switch_value
+ && (unsigned HOST_WIDE_INT) size <= g_switch_value
+ /* If it's not public, and we're not going to reference it there,
+ there's no need to put it in the small data section. */
&& (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
return true;
}
@@ -12772,8 +15035,7 @@ rs6000_elf_in_small_data_p (decl)
increment the returned register via an "la" instruction. */
struct rtx_def *
-find_addr_reg (addr)
- rtx addr;
+find_addr_reg (rtx addr)
{
while (GET_CODE (addr) == PLUS)
{
@@ -12796,23 +15058,11 @@ find_addr_reg (addr)
}
void
-rs6000_fatal_bad_address (op)
- rtx op;
+rs6000_fatal_bad_address (rtx op)
{
fatal_insn ("bad address", op);
}
-/* Called to register all of our global variables with the garbage
- collector. */
-
-static void
-rs6000_add_gc_roots ()
-{
- toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
- ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table),
- toc_hash_mark_table);
-}
-
#if TARGET_MACHO
#if 0
@@ -12820,8 +15070,7 @@ rs6000_add_gc_roots ()
reference and a constant. */
int
-symbolic_operand (op)
- rtx op;
+symbolic_operand (rtx op)
{
switch (GET_CODE (op))
{
@@ -12840,87 +15089,118 @@ symbolic_operand (op)
}
#endif
-#ifdef RS6000_LONG_BRANCH
+#if TARGET_MACHO
-static tree stub_list = 0;
+static tree branch_island_list = 0;
-/* ADD_COMPILER_STUB adds the compiler generated stub for handling
- procedure calls to the linked list. */
+/* Remember to generate a branch island for far calls to the given
+ function. */
-void
-add_compiler_stub (label_name, function_name, line_number)
- tree label_name;
- tree function_name;
- int line_number;
+static void
+add_compiler_branch_island (tree label_name, tree function_name, int line_number)
{
- tree stub = build_tree_list (function_name, label_name);
- TREE_TYPE (stub) = build_int_2 (line_number, 0);
- TREE_CHAIN (stub) = stub_list;
- stub_list = stub;
+ tree branch_island = build_tree_list (function_name, label_name);
+ TREE_TYPE (branch_island) = build_int_2 (line_number, 0);
+ TREE_CHAIN (branch_island) = branch_island_list;
+ branch_island_list = branch_island;
}
-#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
-#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
-#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
-
-/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for
- handling procedure calls from the linked list and initializes the
- linked list. */
+#define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
+#define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
+#define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
+ TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
-void
-output_compiler_stub ()
-{
- char tmp_buf[256];
- char label_buf[256];
- tree stub;
-
- if (!flag_pic)
- for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
- {
- fprintf (asm_out_file,
- "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
+/* Generate far-jump branch islands for everything on the
+ branch_island_list. Invoked immediately after the last instruction
+ of the epilogue has been emitted; the branch-islands must be
+ appended to, and contiguous with, the function body. Mach-O stubs
+ are generated in machopic_output_stub(). */
+static void
+macho_branch_islands (void)
+{
+ char tmp_buf[512];
+ tree branch_island;
+
+ for (branch_island = branch_island_list;
+ branch_island;
+ branch_island = TREE_CHAIN (branch_island))
+ {
+ const char *label =
+ IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
+ const char *name =
+ darwin_strip_name_encoding (
+ IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island)));
+ char name_buf[512];
+ /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
+ if (name[0] == '*' || name[0] == '&')
+ strcpy (name_buf, name+1);
+ else
+ {
+ name_buf[0] = '_';
+ strcpy (name_buf+1, name);
+ }
+ strcpy (tmp_buf, "\n");
+ strcat (tmp_buf, label);
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
- if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
- fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
+ if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
+ fprintf (asm_out_file, "\t.stabd 68,0," HOST_WIDE_INT_PRINT_UNSIGNED "\n",
+ BRANCH_ISLAND_LINE_NUMBER(branch_island));
#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
-
- if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
- strcpy (label_buf,
- IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
- else
- {
- label_buf[0] = '_';
- strcpy (label_buf+1,
- IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
- }
-
- strcpy (tmp_buf, "lis r12,hi16(");
- strcat (tmp_buf, label_buf);
- strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
- strcat (tmp_buf, label_buf);
- strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
- output_asm_insn (tmp_buf, 0);
-
+ if (flag_pic)
+ {
+ strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
+ strcat (tmp_buf, label);
+ strcat (tmp_buf, "_pic\n");
+ strcat (tmp_buf, label);
+ strcat (tmp_buf, "_pic:\n\tmflr r11\n");
+
+ strcat (tmp_buf, "\taddis r11,r11,ha16(");
+ strcat (tmp_buf, name_buf);
+ strcat (tmp_buf, " - ");
+ strcat (tmp_buf, label);
+ strcat (tmp_buf, "_pic)\n");
+
+ strcat (tmp_buf, "\tmtlr r0\n");
+
+ strcat (tmp_buf, "\taddi r12,r11,lo16(");
+ strcat (tmp_buf, name_buf);
+ strcat (tmp_buf, " - ");
+ strcat (tmp_buf, label);
+ strcat (tmp_buf, "_pic)\n");
+
+ strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
+ }
+ else
+ {
+ strcat (tmp_buf, ":\nlis r12,hi16(");
+ strcat (tmp_buf, name_buf);
+ strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
+ strcat (tmp_buf, name_buf);
+ strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
+ }
+ output_asm_insn (tmp_buf, 0);
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
- if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
- fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
+ if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
+ fprintf(asm_out_file, "\t.stabd 68,0," HOST_WIDE_INT_PRINT_UNSIGNED "\n",
+ BRANCH_ISLAND_LINE_NUMBER (branch_island));
#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
- }
+ }
- stub_list = 0;
+ branch_island_list = 0;
}
/* NO_PREVIOUS_DEF checks in the link list whether the function name is
already there or not. */
-int
-no_previous_def (function_name)
- tree function_name;
+static int
+no_previous_def (tree function_name)
{
- tree stub;
- for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
- if (function_name == STUB_FUNCTION_NAME (stub))
+ tree branch_island;
+ for (branch_island = branch_island_list;
+ branch_island;
+ branch_island = TREE_CHAIN (branch_island))
+ if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
return 0;
return 1;
}
@@ -12928,14 +15208,15 @@ no_previous_def (function_name)
/* GET_PREV_LABEL gets the label name from the previous definition of
the function. */
-tree
-get_prev_label (function_name)
- tree function_name;
-{
- tree stub;
- for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
- if (function_name == STUB_FUNCTION_NAME (stub))
- return STUB_LABEL_NAME (stub);
+static tree
+get_prev_label (tree function_name)
+{
+ tree branch_island;
+ for (branch_island = branch_island_list;
+ branch_island;
+ branch_island = TREE_CHAIN (branch_island))
+ if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
+ return BRANCH_ISLAND_LABEL_NAME (branch_island);
return 0;
}
@@ -12945,16 +15226,14 @@ get_prev_label (function_name)
CALL_DEST is the routine we are calling. */
char *
-output_call (insn, call_dest, operand_number)
- rtx insn;
- rtx call_dest;
- int operand_number;
+output_call (rtx insn, rtx *operands, int dest_operand_number, int cookie_operand_number)
{
static char buf[256];
- if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
+ if (GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
+ && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
{
tree labelname;
- tree funname = get_identifier (XSTR (call_dest, 0));
+ tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
if (no_previous_def (funname))
{
@@ -12968,49 +15247,30 @@ output_call (insn, call_dest, operand_number)
for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
if (insn)
line_number = NOTE_LINE_NUMBER (insn);
- add_compiler_stub (labelname, funname, line_number);
+ add_compiler_branch_island (labelname, funname, line_number);
}
else
labelname = get_prev_label (funname);
+ /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
+ instruction will reach 'foo', otherwise link as 'bl L42'".
+ "L42" should be a 'branch island', that will do a far jump to
+ 'foo'. Branch islands are generated in
+ macho_branch_islands(). */
sprintf (buf, "jbsr %%z%d,%.246s",
- operand_number, IDENTIFIER_POINTER (labelname));
- return buf;
+ dest_operand_number, IDENTIFIER_POINTER (labelname));
}
else
- {
- sprintf (buf, "bl %%z%d", operand_number);
- return buf;
- }
+ sprintf (buf, "bl %%z%d", dest_operand_number);
+ return buf;
}
-#endif /* RS6000_LONG_BRANCH */
-
-#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
- do { \
- const char *const symbol_ = (SYMBOL); \
- char *buffer_ = (BUF); \
- if (symbol_[0] == '"') \
- { \
- sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
- } \
- else if (name_needs_quotes(symbol_)) \
- { \
- sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
- } \
- else \
- { \
- sprintf(buffer_, "L%d$%s", (N), symbol_); \
- } \
- } while (0)
-
+#endif /* TARGET_MACHO */
/* Generate PIC and indirect symbol stubs. */
void
-machopic_output_stub (file, symb, stub)
- FILE *file;
- const char *symb, *stub;
+machopic_output_stub (FILE *file, const char *symb, const char *stub)
{
unsigned int length;
char *symbol_name, *lazy_ptr_name;
@@ -13020,7 +15280,6 @@ machopic_output_stub (file, symb, stub)
/* Lose our funky encoding stuff so it doesn't contaminate the stub. */
symb = (*targetm.strip_name_encoding) (symb);
- label += 1;
length = strlen (symb);
symbol_name = alloca (length + 32);
@@ -13029,34 +15288,39 @@ machopic_output_stub (file, symb, stub)
lazy_ptr_name = alloca (length + 32);
GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
- local_label_0 = alloca (length + 32);
- GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
-
if (flag_pic == 2)
- machopic_picsymbol_stub_section ();
+ machopic_picsymbol_stub1_section ();
else
- machopic_symbol_stub_section ();
+ machopic_symbol_stub1_section ();
+ fprintf (file, "\t.align 2\n");
fprintf (file, "%s:\n", stub);
fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
if (flag_pic == 2)
{
+ label++;
+ local_label_0 = alloca (sizeof("\"L0000000000$spb\""));
+ sprintf (local_label_0, "\"L%011d$spb\"", label);
+
fprintf (file, "\tmflr r0\n");
fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
lazy_ptr_name, local_label_0);
fprintf (file, "\tmtlr r0\n");
- fprintf (file, "\tlwz r12,lo16(%s-%s)(r11)\n",
+ fprintf (file, "\tlwzu r12,lo16(%s-%s)(r11)\n",
lazy_ptr_name, local_label_0);
fprintf (file, "\tmtctr r12\n");
- fprintf (file, "\taddi r11,r11,lo16(%s-%s)\n",
- lazy_ptr_name, local_label_0);
fprintf (file, "\tbctr\n");
}
else
- fprintf (file, "non-pure not supported\n");
+ {
+ fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
+ fprintf (file, "\tlwzu r12,lo16(%s)(r11)\n", lazy_ptr_name);
+ fprintf (file, "\tmtctr r12\n");
+ fprintf (file, "\tbctr\n");
+ }
machopic_lazy_symbol_ptr_section ();
fprintf (file, "%s:\n", lazy_ptr_name);
@@ -13072,10 +15336,8 @@ machopic_output_stub (file, symb, stub)
#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
rtx
-rs6000_machopic_legitimize_pic_address (orig, mode, reg)
- rtx orig;
- enum machine_mode mode;
- rtx reg;
+rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
+ rtx reg)
{
rtx base, offset;
@@ -13090,9 +15352,13 @@ rs6000_machopic_legitimize_pic_address (orig, mode, reg)
if (GET_CODE (XEXP (orig, 0)) == PLUS)
{
+ /* Use a different reg for the intermediate value, as
+ it will be marked UNCHANGING. */
+ rtx reg_temp = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
+
base =
rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
- Pmode, reg);
+ Pmode, reg_temp);
offset =
rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
Pmode, reg);
@@ -13125,7 +15391,7 @@ rs6000_machopic_legitimize_pic_address (orig, mode, reg)
real definition. */
void
-toc_section ()
+toc_section (void)
{
}
@@ -13133,19 +15399,10 @@ toc_section ()
#if TARGET_ELF
static unsigned int
-rs6000_elf_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
+rs6000_elf_section_type_flags (tree decl, const char *name, int reloc)
{
- unsigned int flags
- = default_section_type_flags_1 (decl, name, reloc,
- flag_pic || DEFAULT_ABI == ABI_AIX);
-
- if (TARGET_RELOCATABLE)
- flags |= SECTION_WRITE;
-
- return flags;
+ return default_section_type_flags_1 (decl, name, reloc,
+ flag_pic || DEFAULT_ABI == ABI_AIX);
}
/* Record an element in the table of global constructors. SYMBOL is
@@ -13156,9 +15413,7 @@ rs6000_elf_section_type_flags (decl, name, reloc)
that we have special handling for -mrelocatable. */
static void
-rs6000_elf_asm_out_constructor (symbol, priority)
- rtx symbol;
- int priority;
+rs6000_elf_asm_out_constructor (rtx symbol, int priority)
{
const char *section = ".ctors";
char buf[16];
@@ -13187,9 +15442,7 @@ rs6000_elf_asm_out_constructor (symbol, priority)
}
static void
-rs6000_elf_asm_out_destructor (symbol, priority)
- rtx symbol;
- int priority;
+rs6000_elf_asm_out_destructor (rtx symbol, int priority)
{
const char *section = ".dtors";
char buf[16];
@@ -13216,13 +15469,81 @@ rs6000_elf_asm_out_destructor (symbol, priority)
else
assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
}
+
+void
+rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
+{
+ if (TARGET_64BIT)
+ {
+ fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
+ ASM_OUTPUT_LABEL (file, name);
+ fputs (DOUBLE_INT_ASM_OP, file);
+ putc ('.', file);
+ assemble_name (file, name);
+ fputs (",.TOC.@tocbase,0\n\t.previous\n\t.size\t", file);
+ assemble_name (file, name);
+ fputs (",24\n\t.type\t.", file);
+ assemble_name (file, name);
+ fputs (",@function\n", file);
+ if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
+ {
+ fputs ("\t.globl\t.", file);
+ assemble_name (file, name);
+ putc ('\n', file);
+ }
+ ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
+ putc ('.', file);
+ ASM_OUTPUT_LABEL (file, name);
+ return;
+ }
+
+ if (TARGET_RELOCATABLE
+ && (get_pool_size () != 0 || current_function_profile)
+ && uses_TOC ())
+ {
+ char buf[256];
+
+ (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
+
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
+ fprintf (file, "\t.long ");
+ assemble_name (file, buf);
+ putc ('-', file);
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
+ assemble_name (file, buf);
+ putc ('\n', file);
+ }
+
+ ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
+ ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
+
+ if (DEFAULT_ABI == ABI_AIX)
+ {
+ const char *desc_name, *orig_name;
+
+ orig_name = (*targetm.strip_name_encoding) (name);
+ desc_name = orig_name;
+ while (*desc_name == '.')
+ desc_name++;
+
+ if (TREE_PUBLIC (decl))
+ fprintf (file, "\t.globl %s\n", desc_name);
+
+ fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
+ fprintf (file, "%s:\n", desc_name);
+ fprintf (file, "\t.long %s\n", orig_name);
+ fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
+ if (DEFAULT_ABI == ABI_AIX)
+ fputs ("\t.long 0\n", file);
+ fprintf (file, "\t.previous\n");
+ }
+ ASM_OUTPUT_LABEL (file, name);
+}
#endif
#if TARGET_XCOFF
static void
-rs6000_xcoff_asm_globalize_label (stream, name)
- FILE *stream;
- const char *name;
+rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
{
fputs (GLOBAL_ASM_OP, stream);
RS6000_OUTPUT_BASENAME (stream, name);
@@ -13230,9 +15551,7 @@ rs6000_xcoff_asm_globalize_label (stream, name)
}
static void
-rs6000_xcoff_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+rs6000_xcoff_asm_named_section (const char *name, unsigned int flags)
{
int smclass;
static const char * const suffix[3] = { "PR", "RO", "RW" };
@@ -13250,10 +15569,8 @@ rs6000_xcoff_asm_named_section (name, flags)
}
static void
-rs6000_xcoff_select_section (decl, reloc, align)
- tree decl;
- int reloc;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+rs6000_xcoff_select_section (tree decl, int reloc,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
if (decl_readonly_section_1 (decl, reloc, 1))
{
@@ -13272,9 +15589,7 @@ rs6000_xcoff_select_section (decl, reloc, align)
}
static void
-rs6000_xcoff_unique_section (decl, reloc)
- tree decl;
- int reloc ATTRIBUTE_UNUSED;
+rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
{
const char *name;
@@ -13299,10 +15614,8 @@ rs6000_xcoff_unique_section (decl, reloc)
toc entry. */
static void
-rs6000_xcoff_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
toc_section ();
@@ -13313,8 +15626,7 @@ rs6000_xcoff_select_rtx_section (mode, x, align)
/* Remove any trailing [DS] or the like from the symbol name. */
static const char *
-rs6000_xcoff_strip_name_encoding (name)
- const char *name;
+rs6000_xcoff_strip_name_encoding (const char *name)
{
size_t len;
if (*name == '*')
@@ -13329,10 +15641,7 @@ rs6000_xcoff_strip_name_encoding (name)
/* Section attributes. AIX is always PIC. */
static unsigned int
-rs6000_xcoff_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
+rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
{
unsigned int align;
unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
@@ -13349,37 +15658,297 @@ rs6000_xcoff_section_type_flags (decl, name, reloc)
return flags | (exact_log2 (align) & SECTION_ENTSIZE);
}
-#endif /* TARGET_XCOFF */
+/* Output at beginning of assembler file.
+
+ Initialize the section names for the RS/6000 at this point.
+
+ Specify filename, including full path, to assembler.
-/* Note that this is also used for PPC64 Linux. */
+ We want to go into the TOC section so at least one .toc will be emitted.
+ Also, in order to output proper .bs/.es pairs, we need at least one static
+ [RW] section emitted.
+
+ Finally, declare mcount when profiling to make the assembler happy. */
+
+static void
+rs6000_xcoff_file_start (void)
+{
+ rs6000_gen_section_name (&xcoff_bss_section_name,
+ main_input_filename, ".bss_");
+ rs6000_gen_section_name (&xcoff_private_data_section_name,
+ main_input_filename, ".rw_");
+ rs6000_gen_section_name (&xcoff_read_only_section_name,
+ main_input_filename, ".ro_");
+
+ fputs ("\t.file\t", asm_out_file);
+ output_quoted_string (asm_out_file, main_input_filename);
+ fputc ('\n', asm_out_file);
+ toc_section ();
+ if (write_symbols != NO_DEBUG)
+ private_data_section ();
+ text_section ();
+ if (profile_flag)
+ fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
+ rs6000_file_start ();
+}
+
+/* Output at end of assembler file.
+ On the RS/6000, referencing data should automatically pull in text. */
static void
-rs6000_xcoff_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
+rs6000_xcoff_file_end (void)
{
- if (TREE_CODE (decl) == FUNCTION_DECL
- && (*targetm.binds_local_p) (decl))
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
+ text_section ();
+ fputs ("_section_.text:\n", asm_out_file);
+ data_section ();
+ fputs (TARGET_32BIT
+ ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
+ asm_out_file);
}
+#endif /* TARGET_XCOFF */
+
+#if TARGET_MACHO
+/* Cross-module name binding. Darwin does not support overriding
+ functions at dynamic-link time. */
+
+static bool
+rs6000_binds_local_p (tree decl)
+{
+ return default_binds_local_p_1 (decl, 0);
+}
+#endif
-/* Cross-module name binding. For AIX and PPC64 Linux, which always are
- PIC, use private copy of flag_pic. */
+/* Compute a (partial) cost for rtx X. Return true if the complete
+ cost has been computed, and false if subexpressions should be
+ scanned. In either case, *TOTAL contains the cost result. */
static bool
-rs6000_binds_local_p (decl)
- tree decl;
+rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
+ int *total)
{
- return default_binds_local_p_1 (decl, flag_pic || rs6000_flag_pic);
+ switch (code)
+ {
+ /* On the RS/6000, if it is valid in the insn, it is free.
+ So this always returns 0. */
+ case CONST_INT:
+ case CONST:
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_DOUBLE:
+ case HIGH:
+ *total = 0;
+ return true;
+
+ case PLUS:
+ *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
+ && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1))
+ + 0x8000) >= 0x10000)
+ && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
+ ? COSTS_N_INSNS (2)
+ : COSTS_N_INSNS (1));
+ return true;
+
+ case AND:
+ case IOR:
+ case XOR:
+ *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (INTVAL (XEXP (x, 1)) & (~ (HOST_WIDE_INT) 0xffff)) != 0
+ && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
+ ? COSTS_N_INSNS (2)
+ : COSTS_N_INSNS (1));
+ return true;
+
+ case MULT:
+ if (optimize_size)
+ {
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
+ switch (rs6000_cpu)
+ {
+ case PROCESSOR_RIOS1:
+ case PROCESSOR_PPC405:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? COSTS_N_INSNS (5)
+ : (INTVAL (XEXP (x, 1)) >= -256
+ && INTVAL (XEXP (x, 1)) <= 255)
+ ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4));
+ return true;
+
+ case PROCESSOR_PPC440:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? COSTS_N_INSNS (3)
+ : COSTS_N_INSNS (2));
+ return true;
+
+ case PROCESSOR_RS64A:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (20) : COSTS_N_INSNS (34)
+ : (INTVAL (XEXP (x, 1)) >= -256
+ && INTVAL (XEXP (x, 1)) <= 255)
+ ? COSTS_N_INSNS (8) : COSTS_N_INSNS (12));
+ return true;
+
+ case PROCESSOR_RIOS2:
+ case PROCESSOR_MPCCORE:
+ case PROCESSOR_PPC604e:
+ *total = COSTS_N_INSNS (2);
+ return true;
+
+ case PROCESSOR_PPC601:
+ *total = COSTS_N_INSNS (5);
+ return true;
+
+ case PROCESSOR_PPC603:
+ case PROCESSOR_PPC7400:
+ case PROCESSOR_PPC750:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? COSTS_N_INSNS (5)
+ : (INTVAL (XEXP (x, 1)) >= -256
+ && INTVAL (XEXP (x, 1)) <= 255)
+ ? COSTS_N_INSNS (2) : COSTS_N_INSNS (3));
+ return true;
+
+ case PROCESSOR_PPC7450:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? COSTS_N_INSNS (4)
+ : COSTS_N_INSNS (3));
+ return true;
+
+ case PROCESSOR_PPC403:
+ case PROCESSOR_PPC604:
+ case PROCESSOR_PPC8540:
+ *total = COSTS_N_INSNS (4);
+ return true;
+
+ case PROCESSOR_PPC620:
+ case PROCESSOR_PPC630:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (5) : COSTS_N_INSNS (7)
+ : (INTVAL (XEXP (x, 1)) >= -256
+ && INTVAL (XEXP (x, 1)) <= 255)
+ ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4));
+ return true;
+
+ case PROCESSOR_POWER4:
+ case PROCESSOR_POWER5:
+ *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
+ ? GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)
+ : COSTS_N_INSNS (2));
+ return true;
+
+ default:
+ abort ();
+ }
+
+ case DIV:
+ case MOD:
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
+ {
+ *total = COSTS_N_INSNS (2);
+ return true;
+ }
+ /* FALLTHRU */
+
+ case UDIV:
+ case UMOD:
+ switch (rs6000_cpu)
+ {
+ case PROCESSOR_RIOS1:
+ *total = COSTS_N_INSNS (19);
+ return true;
+
+ case PROCESSOR_RIOS2:
+ *total = COSTS_N_INSNS (13);
+ return true;
+
+ case PROCESSOR_RS64A:
+ *total = (GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (65)
+ : COSTS_N_INSNS (67));
+ return true;
+
+ case PROCESSOR_MPCCORE:
+ *total = COSTS_N_INSNS (6);
+ return true;
+
+ case PROCESSOR_PPC403:
+ *total = COSTS_N_INSNS (33);
+ return true;
+
+ case PROCESSOR_PPC405:
+ *total = COSTS_N_INSNS (35);
+ return true;
+
+ case PROCESSOR_PPC440:
+ *total = COSTS_N_INSNS (34);
+ return true;
+
+ case PROCESSOR_PPC601:
+ *total = COSTS_N_INSNS (36);
+ return true;
+
+ case PROCESSOR_PPC603:
+ *total = COSTS_N_INSNS (37);
+ return true;
+
+ case PROCESSOR_PPC604:
+ case PROCESSOR_PPC604e:
+ *total = COSTS_N_INSNS (20);
+ return true;
+
+ case PROCESSOR_PPC620:
+ case PROCESSOR_PPC630:
+ *total = (GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (21)
+ : COSTS_N_INSNS (37));
+ return true;
+
+ case PROCESSOR_PPC750:
+ case PROCESSOR_PPC8540:
+ case PROCESSOR_PPC7400:
+ *total = COSTS_N_INSNS (19);
+ return true;
+
+ case PROCESSOR_PPC7450:
+ *total = COSTS_N_INSNS (23);
+ return true;
+
+ case PROCESSOR_POWER4:
+ case PROCESSOR_POWER5:
+ *total = (GET_MODE (XEXP (x, 1)) != DImode
+ ? COSTS_N_INSNS (18)
+ : COSTS_N_INSNS (34));
+ return true;
+
+ default:
+ abort ();
+ }
+
+ case FFS:
+ *total = COSTS_N_INSNS (4);
+ return true;
+
+ case MEM:
+ /* MEM should be slightly more expensive than (plus (reg) (const)). */
+ *total = 5;
+ return true;
+
+ default:
+ return false;
+ }
}
/* A C expression returning the cost of moving data from a register of class
CLASS1 to one of CLASS2. */
int
-rs6000_register_move_cost (mode, from, to)
- enum machine_mode mode;
- enum reg_class from, to;
+rs6000_register_move_cost (enum machine_mode mode,
+ enum reg_class from, enum reg_class to)
{
/* Moves from/to GENERAL_REGS. */
if (reg_classes_intersect_p (to, GENERAL_REGS)
@@ -13392,7 +15961,7 @@ rs6000_register_move_cost (mode, from, to)
return (rs6000_memory_move_cost (mode, from, 0)
+ rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
-/* It's more expensive to move CR_REGS than CR0_REGS because of the shift...*/
+/* It's more expensive to move CR_REGS than CR0_REGS because of the shift.... */
else if (from == CR_REGS)
return 4;
@@ -13415,10 +15984,8 @@ rs6000_register_move_cost (mode, from, to)
or from memory. */
int
-rs6000_memory_move_cost (mode, class, in)
- enum machine_mode mode;
- enum reg_class class;
- int in ATTRIBUTE_UNUSED;
+rs6000_memory_move_cost (enum machine_mode mode, enum reg_class class,
+ int in ATTRIBUTE_UNUSED)
{
if (reg_classes_intersect_p (class, GENERAL_REGS))
return 4 * HARD_REGNO_NREGS (0, mode);
@@ -13430,3 +15997,199 @@ rs6000_memory_move_cost (mode, class, in)
return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
}
+/* Return an RTX representing where to find the function value of a
+ function returning MODE. */
+static rtx
+rs6000_complex_function_value (enum machine_mode mode)
+{
+ unsigned int regno;
+ rtx r1, r2;
+ enum machine_mode inner = GET_MODE_INNER (mode);
+ unsigned int inner_bytes = GET_MODE_SIZE (inner);
+
+ if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
+ regno = FP_ARG_RETURN;
+ else
+ {
+ regno = GP_ARG_RETURN;
+
+ /* 32-bit is OK since it'll go in r3/r4. */
+ if (TARGET_32BIT && inner_bytes >= 4)
+ return gen_rtx_REG (mode, regno);
+ }
+
+ if (inner_bytes >= 8)
+ return gen_rtx_REG (mode, regno);
+
+ r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
+ const0_rtx);
+ r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
+ GEN_INT (inner_bytes));
+ return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
+}
+
+/* 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.
+
+ On the SPE, both FPs and vectors are returned in r3.
+
+ On RS/6000 an integer value is in r3 and a floating-point value is in
+ fp1, unless -msoft-float. */
+
+rtx
+rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
+{
+ enum machine_mode mode;
+ unsigned int regno;
+
+ if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
+ {
+ /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
+ return gen_rtx_PARALLEL (DImode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode, GP_ARG_RETURN),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_RETURN + 1),
+ GEN_INT (4))));
+ }
+
+ if ((INTEGRAL_TYPE_P (valtype)
+ && TYPE_PRECISION (valtype) < BITS_PER_WORD)
+ || POINTER_TYPE_P (valtype))
+ mode = TARGET_32BIT ? SImode : DImode;
+ else
+ mode = TYPE_MODE (valtype);
+
+ if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
+ regno = FP_ARG_RETURN;
+ else if (TREE_CODE (valtype) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg)
+ return rs6000_complex_function_value (mode);
+ else if (TREE_CODE (valtype) == VECTOR_TYPE
+ && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
+ regno = ALTIVEC_ARG_RETURN;
+ else
+ regno = GP_ARG_RETURN;
+
+ return gen_rtx_REG (mode, regno);
+}
+
+/* Define how to find the value returned by a library function
+ assuming the value has mode MODE. */
+rtx
+rs6000_libcall_value (enum machine_mode mode)
+{
+ unsigned int regno;
+
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT
+ && TARGET_HARD_FLOAT && TARGET_FPRS)
+ regno = FP_ARG_RETURN;
+ else if (ALTIVEC_VECTOR_MODE (mode)
+ && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
+ regno = ALTIVEC_ARG_RETURN;
+ else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
+ return rs6000_complex_function_value (mode);
+ else
+ regno = GP_ARG_RETURN;
+
+ return gen_rtx_REG (mode, regno);
+}
+
+/* Define the offset between two registers, FROM to be eliminated and its
+ replacement TO, at the start of a routine. */
+HOST_WIDE_INT
+rs6000_initial_elimination_offset (int from, int to)
+{
+ rs6000_stack_t *info = rs6000_stack_info ();
+ HOST_WIDE_INT offset;
+
+ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+ offset = info->push_p ? 0 : -info->total_size;
+ else if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
+ offset = info->total_size;
+ else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
+ offset = info->push_p ? info->total_size : 0;
+ else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
+ offset = 0;
+ else
+ abort ();
+
+ return offset;
+}
+
+/* Return true if TYPE is of type __ev64_opaque__. */
+
+static bool
+is_ev64_opaque_type (tree type)
+{
+ return (TARGET_SPE
+ && (type == opaque_V2SI_type_node
+ || type == opaque_V2SF_type_node
+ || type == opaque_p_V2SI_type_node));
+}
+
+static rtx
+rs6000_dwarf_register_span (rtx reg)
+{
+ unsigned regno;
+
+ if (!TARGET_SPE || !SPE_VECTOR_MODE (GET_MODE (reg)))
+ return NULL_RTX;
+
+ regno = REGNO (reg);
+
+ /* The duality of the SPE register size wreaks all kinds of havoc.
+ This is a way of distinguishing r0 in 32-bits from r0 in
+ 64-bits. */
+ return
+ gen_rtx_PARALLEL (VOIDmode,
+ BYTES_BIG_ENDIAN
+ ? gen_rtvec (2,
+ gen_rtx_REG (SImode, regno + 1200),
+ gen_rtx_REG (SImode, regno))
+ : gen_rtvec (2,
+ gen_rtx_REG (SImode, regno),
+ gen_rtx_REG (SImode, regno + 1200)));
+}
+
+/* Map internal gcc register numbers to DWARF2 register numbers. */
+
+unsigned int
+rs6000_dbx_register_number (unsigned int regno)
+{
+ if (regno <= 63 || write_symbols != DWARF2_DEBUG)
+ return regno;
+ if (regno == MQ_REGNO)
+ return 100;
+ if (regno == LINK_REGISTER_REGNUM)
+ return 108;
+ if (regno == COUNT_REGISTER_REGNUM)
+ return 109;
+ if (CR_REGNO_P (regno))
+ return regno - CR0_REGNO + 86;
+ if (regno == XER_REGNO)
+ return 101;
+ if (ALTIVEC_REGNO_P (regno))
+ return regno - FIRST_ALTIVEC_REGNO + 1124;
+ if (regno == VRSAVE_REGNO)
+ return 356;
+ if (regno == VSCR_REGNO)
+ return 67;
+ if (regno == SPE_ACC_REGNO)
+ return 99;
+ if (regno == SPEFSCR_REGNO)
+ return 612;
+ /* SPE high reg number. We get these values of regno from
+ rs6000_dwarf_register_span. */
+ if (regno >= 1200 && regno < 1232)
+ return regno;
+
+ abort ();
+}
+
+#include "gt-rs6000.h"
diff --git a/contrib/gcc/config/rs6000/rs6000.h b/contrib/gcc/config/rs6000/rs6000.h
index 957fcecfe1e2..d3a66ddb759e 100644
--- a/contrib/gcc/config/rs6000/rs6000.h
+++ b/contrib/gcc/config/rs6000/rs6000.h
@@ -1,25 +1,24 @@
/* Definitions of target machine for GNU compiler, for IBM RS/6000.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Note that some other tm.h files include this one and then override
many of the definitions. */
@@ -52,23 +51,29 @@ Boston, MA 02111-1307, USA. */
"%{!mcpu*: \
%{mpower: %{!mpower2: -mpwr}} \
%{mpower2: -mpwrx} \
- %{mpowerpc*: -mppc} \
+ %{mpowerpc64*: -mppc64} \
+ %{!mpowerpc64*: %{mpowerpc*: -mppc}} \
%{mno-power: %{!mpowerpc*: -mcom}} \
- %{!mno-power: %{!mpower2: %(asm_default)}}} \
+ %{!mno-power: %{!mpower*: %(asm_default)}}} \
%{mcpu=common: -mcom} \
%{mcpu=power: -mpwr} \
%{mcpu=power2: -mpwrx} \
-%{mcpu=power3: -m604} \
+%{mcpu=power3: -mppc64} \
%{mcpu=power4: -mpower4} \
+%{mcpu=power5: -mpower4} \
%{mcpu=powerpc: -mppc} \
%{mcpu=rios: -mpwr} \
%{mcpu=rios1: -mpwr} \
%{mcpu=rios2: -mpwrx} \
%{mcpu=rsc: -mpwr} \
%{mcpu=rsc1: -mpwr} \
+%{mcpu=rs64a: -mppc64} \
%{mcpu=401: -mppc} \
%{mcpu=403: -m403} \
%{mcpu=405: -m405} \
+%{mcpu=405fp: -m405} \
+%{mcpu=440: -m440} \
+%{mcpu=440fp: -m440} \
%{mcpu=505: -mppc} \
%{mcpu=601: -m601} \
%{mcpu=602: -mppc} \
@@ -77,18 +82,23 @@ Boston, MA 02111-1307, USA. */
%{mcpu=ec603e: -mppc} \
%{mcpu=604: -mppc} \
%{mcpu=604e: -mppc} \
-%{mcpu=620: -mppc} \
-%{mcpu=630: -m604} \
+%{mcpu=620: -mppc64} \
+%{mcpu=630: -mppc64} \
%{mcpu=740: -mppc} \
-%{mcpu=7400: -mppc} \
-%{mcpu=7450: -mppc} \
%{mcpu=750: -mppc} \
+%{mcpu=G3: -mppc} \
+%{mcpu=7400: -mppc -maltivec} \
+%{mcpu=7450: -mppc -maltivec} \
+%{mcpu=G4: -mppc -maltivec} \
%{mcpu=801: -mppc} \
%{mcpu=821: -mppc} \
%{mcpu=823: -mppc} \
%{mcpu=860: -mppc} \
+%{mcpu=970: -mpower4 -maltivec} \
+%{mcpu=G5: -mpower4 -maltivec} \
%{mcpu=8540: -me500} \
-%{maltivec: -maltivec}"
+%{maltivec: -maltivec} \
+-many"
#define CPP_DEFAULT_SPEC ""
@@ -99,7 +109,7 @@ Boston, MA 02111-1307, USA. */
is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
+ specification name, and a string constant that used by the GCC driver
program.
Do not define this macro if it does not need to do anything. */
@@ -154,39 +164,42 @@ extern int target_flags;
function, and one less allocable register. */
#define MASK_MINIMAL_TOC 0x00000200
-/* Nonzero for the 64bit model: longs and pointers are 64 bits. */
+/* Nonzero for the 64 bit ABIs: longs and pointers are 64 bits. The
+ chip is running in "64-bit mode", in which CR0 is set in dot
+ operations based on all 64 bits of the register, bdnz works on 64-bit
+ ctr, lr is 64 bits, and so on. Requires MASK_POWERPC64. */
#define MASK_64BIT 0x00000400
/* Disable use of FPRs. */
#define MASK_SOFT_FLOAT 0x00000800
/* Enable load/store multiple, even on PowerPC */
-#define MASK_MULTIPLE 0x00001000
-#define MASK_MULTIPLE_SET 0x00002000
+#define MASK_MULTIPLE 0x00001000
/* Use string instructions for block moves */
-#define MASK_STRING 0x00004000
-#define MASK_STRING_SET 0x00008000
+#define MASK_STRING 0x00002000
/* Disable update form of load/store */
-#define MASK_NO_UPDATE 0x00010000
+#define MASK_NO_UPDATE 0x00004000
/* Disable fused multiply/add operations */
-#define MASK_NO_FUSED_MADD 0x00020000
+#define MASK_NO_FUSED_MADD 0x00008000
/* Nonzero if we need to schedule the prolog and epilog. */
-#define MASK_SCHED_PROLOG 0x00040000
+#define MASK_SCHED_PROLOG 0x00010000
/* Use AltiVec instructions. */
-#define MASK_ALTIVEC 0x00080000
+#define MASK_ALTIVEC 0x00020000
/* Return small structures in memory (as the AIX ABI requires). */
-#define MASK_AIX_STRUCT_RET 0x00100000
-#define MASK_AIX_STRUCT_RET_SET 0x00200000
+#define MASK_AIX_STRUCT_RET 0x00040000
+
+/* Use single field mfcr instruction. */
+#define MASK_MFCRF 0x00080000
-/* The only remaining free bit is 0x00400000. sysv4.h uses
- 0x00800000 -> 0x40000000, and 0x80000000 is not available
- because target_flags is signed. */
+/* The only remaining free bits are 0x00600000. linux64.h uses
+ 0x00100000, and sysv4.h uses 0x00800000 -> 0x40000000.
+ 0x80000000 is not available because target_flags is signed. */
#define TARGET_POWER (target_flags & MASK_POWER)
#define TARGET_POWER2 (target_flags & MASK_POWER2)
@@ -199,21 +212,41 @@ extern int target_flags;
#define TARGET_MINIMAL_TOC (target_flags & MASK_MINIMAL_TOC)
#define TARGET_64BIT (target_flags & MASK_64BIT)
#define TARGET_SOFT_FLOAT (target_flags & MASK_SOFT_FLOAT)
-#define TARGET_MULTIPLE (target_flags & MASK_MULTIPLE)
-#define TARGET_MULTIPLE_SET (target_flags & MASK_MULTIPLE_SET)
+#define TARGET_MULTIPLE (target_flags & MASK_MULTIPLE)
#define TARGET_STRING (target_flags & MASK_STRING)
-#define TARGET_STRING_SET (target_flags & MASK_STRING_SET)
#define TARGET_NO_UPDATE (target_flags & MASK_NO_UPDATE)
#define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD)
#define TARGET_SCHED_PROLOG (target_flags & MASK_SCHED_PROLOG)
#define TARGET_ALTIVEC (target_flags & MASK_ALTIVEC)
#define TARGET_AIX_STRUCT_RET (target_flags & MASK_AIX_STRUCT_RET)
+/* Define TARGET_MFCRF if the target assembler supports the optional
+ field operand for mfcr and the target processor supports the
+ instruction. */
+
+#ifdef HAVE_AS_MFCRF
+#define TARGET_MFCRF (target_flags & MASK_MFCRF)
+#else
+#define TARGET_MFCRF 0
+#endif
+
+
#define TARGET_32BIT (! TARGET_64BIT)
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
#define TARGET_UPDATE (! TARGET_NO_UPDATE)
#define TARGET_FUSED_MADD (! TARGET_NO_FUSED_MADD)
+/* Emit a dtp-relative reference to a TLS variable. */
+
+#ifdef HAVE_AS_TLS
+#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
+ rs6000_output_dwarf_dtprel (FILE, SIZE, X)
+#endif
+
+#ifndef HAVE_AS_TLS
+#define HAVE_AS_TLS 0
+#endif
+
#ifdef IN_LIBGCC2
/* For libgcc2 we make sure this is a compile time constant */
#if defined (__64BIT__) || defined (__powerpc64__)
@@ -254,19 +287,19 @@ extern int target_flags;
{"powerpc-gpopt", MASK_POWERPC | MASK_PPC_GPOPT, \
N_("Use PowerPC General Purpose group optional instructions")},\
{"no-powerpc-gpopt", - MASK_PPC_GPOPT, \
- N_("Don't use PowerPC General Purpose group optional instructions")},\
+ N_("Do not use PowerPC General Purpose group optional instructions")},\
{"powerpc-gfxopt", MASK_POWERPC | MASK_PPC_GFXOPT, \
N_("Use PowerPC Graphics group optional instructions")},\
{"no-powerpc-gfxopt", - MASK_PPC_GFXOPT, \
- N_("Don't use PowerPC Graphics group optional instructions")},\
+ N_("Do not use PowerPC Graphics group optional instructions")},\
{"powerpc64", MASK_POWERPC64, \
N_("Use PowerPC-64 instruction set")}, \
{"no-powerpc64", - MASK_POWERPC64, \
- N_("Don't use PowerPC-64 instruction set")}, \
+ N_("Do not use PowerPC-64 instruction set")}, \
{"altivec", MASK_ALTIVEC , \
N_("Use AltiVec instructions")}, \
{"no-altivec", - MASK_ALTIVEC , \
- N_("Don't use AltiVec instructions")}, \
+ N_("Do not use AltiVec instructions")}, \
{"new-mnemonics", MASK_NEW_MNEMONICS, \
N_("Use new mnemonics for PowerPC architecture")},\
{"old-mnemonics", -MASK_NEW_MNEMONICS, \
@@ -277,11 +310,11 @@ extern int target_flags;
{"fp-in-toc", - MASK_NO_FP_IN_TOC, \
N_("Place floating point constants in TOC")}, \
{"no-fp-in-toc", MASK_NO_FP_IN_TOC, \
- N_("Don't place floating point constants in TOC")},\
+ N_("Do not place floating point constants in TOC")},\
{"sum-in-toc", - MASK_NO_SUM_IN_TOC, \
N_("Place symbol+offset constants in TOC")}, \
{"no-sum-in-toc", MASK_NO_SUM_IN_TOC, \
- N_("Don't place symbol+offset constants in TOC")},\
+ N_("Do not place symbol+offset constants in TOC")},\
{"minimal-toc", MASK_MINIMAL_TOC, \
"Use only one TOC entry per procedure"}, \
{"minimal-toc", - (MASK_NO_FP_IN_TOC | MASK_NO_SUM_IN_TOC), \
@@ -289,21 +322,17 @@ extern int target_flags;
{"no-minimal-toc", - MASK_MINIMAL_TOC, \
N_("Place variable addresses in the regular TOC")},\
{"hard-float", - MASK_SOFT_FLOAT, \
- N_("Use hardware fp")}, \
+ N_("Use hardware floating point")}, \
{"soft-float", MASK_SOFT_FLOAT, \
- N_("Do not use hardware fp")}, \
- {"multiple", MASK_MULTIPLE | MASK_MULTIPLE_SET, \
+ N_("Do not use hardware floating point")}, \
+ {"multiple", MASK_MULTIPLE, \
N_("Generate load/store multiple instructions")}, \
{"no-multiple", - MASK_MULTIPLE, \
N_("Do not generate load/store multiple instructions")},\
- {"no-multiple", MASK_MULTIPLE_SET, \
- ""}, \
- {"string", MASK_STRING | MASK_STRING_SET, \
+ {"string", MASK_STRING, \
N_("Generate string instructions for block moves")},\
{"no-string", - MASK_STRING, \
N_("Do not generate string instructions for block moves")},\
- {"no-string", MASK_STRING_SET, \
- ""}, \
{"update", - MASK_NO_UPDATE, \
N_("Generate load/store with update instructions")},\
{"no-update", MASK_NO_UPDATE, \
@@ -311,27 +340,27 @@ extern int target_flags;
{"fused-madd", - MASK_NO_FUSED_MADD, \
N_("Generate fused multiply/add instructions")},\
{"no-fused-madd", MASK_NO_FUSED_MADD, \
- N_("Don't generate fused multiply/add instructions")},\
+ N_("Do not generate fused multiply/add instructions")},\
{"sched-prolog", MASK_SCHED_PROLOG, \
""}, \
{"no-sched-prolog", -MASK_SCHED_PROLOG, \
- N_("Don't schedule the start and end of the procedure")},\
+ N_("Do not schedule the start and end of the procedure")},\
{"sched-epilog", MASK_SCHED_PROLOG, \
""}, \
{"no-sched-epilog", -MASK_SCHED_PROLOG, \
""}, \
- {"aix-struct-return", MASK_AIX_STRUCT_RET | MASK_AIX_STRUCT_RET_SET, \
+ {"aix-struct-return", MASK_AIX_STRUCT_RET, \
N_("Return all structures in memory (AIX default)")},\
- {"svr4-struct-return", - MASK_AIX_STRUCT_RET,\
+ {"svr4-struct-return", - MASK_AIX_STRUCT_RET, \
N_("Return small structures in registers (SVR4 default)")},\
- {"svr4-struct-return",MASK_AIX_STRUCT_RET_SET,\
- ""},\
- {"no-aix-struct-return", - MASK_AIX_STRUCT_RET,\
- ""},\
- {"no-aix-struct-return", MASK_AIX_STRUCT_RET_SET,\
- ""},\
- {"no-svr4-struct-return", MASK_AIX_STRUCT_RET | MASK_AIX_STRUCT_RET_SET,\
- ""},\
+ {"no-aix-struct-return", - MASK_AIX_STRUCT_RET, \
+ ""}, \
+ {"no-svr4-struct-return", MASK_AIX_STRUCT_RET, \
+ ""}, \
+ {"mfcrf", MASK_MFCRF, \
+ N_("Generate single field mfcr instruction")}, \
+ {"no-mfcrf", - MASK_MFCRF, \
+ N_("Do not generate single field mfcr instruction")},\
SUBTARGET_SWITCHES \
{"", TARGET_DEFAULT | MASK_SCHED_PROLOG, \
""}}
@@ -350,6 +379,7 @@ enum processor_type
PROCESSOR_MPCCORE,
PROCESSOR_PPC403,
PROCESSOR_PPC405,
+ PROCESSOR_PPC440,
PROCESSOR_PPC601,
PROCESSOR_PPC603,
PROCESSOR_PPC604,
@@ -360,7 +390,8 @@ enum processor_type
PROCESSOR_PPC7400,
PROCESSOR_PPC7450,
PROCESSOR_PPC8540,
- PROCESSOR_POWER4
+ PROCESSOR_POWER4,
+ PROCESSOR_POWER5
};
extern enum processor_type rs6000_cpu;
@@ -382,31 +413,78 @@ extern enum processor_type rs6000_cpu;
and the old mnemonics are dialect zero. */
#define ASSEMBLER_DIALECT (TARGET_NEW_MNEMONICS ? 1 : 0)
+/* Types of costly dependences. */
+enum rs6000_dependence_cost
+ {
+ max_dep_latency = 1000,
+ no_dep_costly,
+ all_deps_costly,
+ true_store_to_load_dep_costly,
+ store_to_load_dep_costly
+ };
+
+/* Types of nop insertion schemes in sched target hook sched_finish. */
+enum rs6000_nop_insertion
+ {
+ sched_finish_regroup_exact = 1000,
+ sched_finish_pad_groups,
+ sched_finish_none
+ };
+
+/* Dispatch group termination caused by an insn. */
+enum group_termination
+ {
+ current_group,
+ previous_group
+ };
+
/* This is meant to be overridden in target specific files. */
#define SUBTARGET_OPTIONS
#define TARGET_OPTIONS \
{ \
{"cpu=", &rs6000_select[1].string, \
- N_("Use features of and schedule code for given CPU") }, \
+ N_("Use features of and schedule code for given CPU"), 0}, \
{"tune=", &rs6000_select[2].string, \
- N_("Schedule code for given CPU") }, \
- {"debug=", &rs6000_debug_name, N_("Enable debug output") }, \
+ N_("Schedule code for given CPU"), 0}, \
+ {"debug=", &rs6000_debug_name, N_("Enable debug output"), 0}, \
{"traceback=", &rs6000_traceback_name, \
- N_("Select full, part, or no traceback table") }, \
- {"abi=", &rs6000_abi_string, N_("Specify ABI to use") }, \
+ N_("Select full, part, or no traceback table"), 0}, \
+ {"abi=", &rs6000_abi_string, N_("Specify ABI to use"), 0}, \
{"long-double-", &rs6000_long_double_size_string, \
- N_("Specify size of long double (64 or 128 bits)") }, \
+ N_("Specify size of long double (64 or 128 bits)"), 0}, \
{"isel=", &rs6000_isel_string, \
- N_("Specify yes/no if isel instructions should be generated") }, \
- {"vrsave=", &rs6000_altivec_vrsave_string, \
- N_("Specify yes/no if VRSAVE instructions should be generated for AltiVec") }, \
+ N_("Specify yes/no if isel instructions should be generated"), 0}, \
+ {"spe=", &rs6000_spe_string, \
+ N_("Specify yes/no if SPE SIMD instructions should be generated"), 0},\
+ {"float-gprs=", &rs6000_float_gprs_string, \
+ N_("Specify yes/no if using floating point in the GPRs"), 0}, \
+ {"vrsave=", &rs6000_altivec_vrsave_string, \
+ N_("Specify yes/no if VRSAVE instructions should be generated for AltiVec"), 0}, \
{"longcall", &rs6000_longcall_switch, \
- N_("Avoid all range limits on call instructions") }, \
- {"no-longcall", &rs6000_longcall_switch, "" }, \
+ N_("Avoid all range limits on call instructions"), 0}, \
+ {"no-longcall", &rs6000_longcall_switch, "", 0}, \
+ {"sched-costly-dep=", &rs6000_sched_costly_dep_str, \
+ N_("Determine which dependences between insns are considered costly"), 0}, \
+ {"insert-sched-nops=", &rs6000_sched_insert_nops_str, \
+ N_("Specify which post scheduling nop insertion scheme to apply"), 0}, \
+ {"align-", &rs6000_alignment_string, \
+ N_("Specify alignment of structure fields default/natural"), 0}, \
+ {"prioritize-restricted-insns=", &rs6000_sched_restricted_insns_priority_str, \
+ N_("Specify scheduling priority for dispatch slot restricted insns"), 0}, \
SUBTARGET_OPTIONS \
}
+/* Support for a compile-time default CPU, et cetera. The rules are:
+ --with-cpu is ignored if -mcpu is specified.
+ --with-tune is ignored if -mtune is specified.
+ --with-float is ignored if -mhard-float or -msoft-float are
+ specified. */
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }
+
/* rs6000_select[0] is reserved for the default cpu defined via --with-cpu */
struct rs6000_cpu_select
{
@@ -436,12 +514,40 @@ extern int rs6000_long_double_type_size;
extern int rs6000_altivec_abi;
extern int rs6000_spe_abi;
extern int rs6000_isel;
-extern int rs6000_fprs;
+extern int rs6000_spe;
+extern int rs6000_float_gprs;
+extern const char *rs6000_float_gprs_string;
extern const char *rs6000_isel_string;
+extern const char *rs6000_spe_string;
extern const char *rs6000_altivec_vrsave_string;
extern int rs6000_altivec_vrsave;
extern const char *rs6000_longcall_switch;
extern int rs6000_default_long_calls;
+extern const char* rs6000_alignment_string;
+extern int rs6000_alignment_flags;
+extern const char *rs6000_sched_restricted_insns_priority_str;
+extern int rs6000_sched_restricted_insns_priority;
+extern const char *rs6000_sched_costly_dep_str;
+extern enum rs6000_dependence_cost rs6000_sched_costly_dep;
+extern const char *rs6000_sched_insert_nops_str;
+extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
+
+/* Alignment options for fields in structures for sub-targets following
+ AIX-like ABI.
+ ALIGN_POWER word-aligns FP doubles (default AIX ABI).
+ ALIGN_NATURAL doubleword-aligns FP doubles (align to object size).
+
+ Override the macro definitions when compiling libobjc to avoid undefined
+ reference to rs6000_alignment_flags due to library's use of GCC alignment
+ macros which use the macros below. */
+
+#ifndef IN_TARGET_LIBS
+#define MASK_ALIGN_POWER 0x00000000
+#define MASK_ALIGN_NATURAL 0x00000001
+#define TARGET_ALIGN_NATURAL (rs6000_alignment_flags & MASK_ALIGN_NATURAL)
+#else
+#define TARGET_ALIGN_NATURAL 0
+#endif
#define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size == 128)
#define TARGET_ALTIVEC_ABI rs6000_altivec_abi
@@ -449,6 +555,7 @@ extern int rs6000_default_long_calls;
#define TARGET_SPE_ABI 0
#define TARGET_SPE 0
+#define TARGET_E500 0
#define TARGET_ISEL 0
#define TARGET_FPRS 1
@@ -458,7 +565,7 @@ extern int rs6000_default_long_calls;
defined, is executed once just after all the command options have
been parsed.
- Don't use this macro to turn on various extra optimizations for
+ Do not use this macro to turn on various extra optimizations for
`-O'. That is what `OPTIMIZATION_OPTIONS' is for.
On the RS/6000 this is used to define the target cpu type. */
@@ -472,8 +579,8 @@ extern int rs6000_default_long_calls;
#define CAN_DEBUG_WITHOUT_FP
/* Target pragma. */
-#define REGISTER_TARGET_PRAGMAS(PFILE) do { \
- cpp_register_pragma (PFILE, 0, "longcall", rs6000_pragma_longcall); \
+#define REGISTER_TARGET_PRAGMAS() do { \
+ c_register_pragma (0, "longcall", rs6000_pragma_longcall); \
} while (0)
/* Target #defines. */
@@ -511,16 +618,7 @@ extern int rs6000_default_long_calls;
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
if (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
- (MODE) = word_mode;
-
-/* Define this if function arguments should also be promoted using the above
- procedure. */
-
-#define PROMOTE_FUNCTION_ARGS
-
-/* Likewise, if the function return value is promoted. */
-
-#define PROMOTE_FUNCTION_RETURN
+ (MODE) = TARGET_32BIT ? SImode : DImode;
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */
@@ -622,7 +720,8 @@ extern int rs6000_default_long_calls;
#define PARM_BOUNDARY (TARGET_32BIT ? 32 : 64)
/* Boundary (in *bits*) on which stack pointer should be aligned. */
-#define STACK_BOUNDARY ((TARGET_32BIT && !TARGET_ALTIVEC_ABI) ? 64 : 128)
+#define STACK_BOUNDARY \
+ ((TARGET_32BIT && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI) ? 64 : 128)
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32
@@ -697,7 +796,8 @@ extern int rs6000_default_long_calls;
RS/6000 has 32 fixed-point registers, 32 floating-point registers,
an MQ register, a count register, a link register, and 8 condition
- register fields, which we view here as separate registers.
+ register fields, which we view here as separate registers. AltiVec
+ adds 32 vector registers and a VRsave register.
In addition, the difference between the frame and argument pointers is
a function of the number of registers saved, so we need to have a
@@ -714,6 +814,28 @@ extern int rs6000_default_long_calls;
/* This must be included for pre gcc 3.0 glibc compatibility. */
#define PRE_GCC3_DWARF_FRAME_REGISTERS 77
+/* Add 32 dwarf columns for synthetic SPE registers. */
+#define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER + 32)
+
+/* The SPE has an additional 32 synthetic registers, with DWARF debug
+ info numbering for these registers starting at 1200. While eh_frame
+ register numbering need not be the same as the debug info numbering,
+ we choose to number these regs for eh_frame at 1200 too. This allows
+ future versions of the rs6000 backend to add hard registers and
+ continue to use the gcc hard register numbering for eh_frame. If the
+ extra SPE registers in eh_frame were numbered starting from the
+ current value of FIRST_PSEUDO_REGISTER, then if FIRST_PSEUDO_REGISTER
+ changed we'd need to introduce a mapping in DWARF_FRAME_REGNUM to
+ avoid invalidating older SPE eh_frame info.
+
+ We must map them here to avoid huge unwinder tables mostly consisting
+ of unused space. */
+#define DWARF_REG_TO_UNWIND_COLUMN(r) \
+ ((r) > 1200 ? ((r) - 1200 + FIRST_PSEUDO_REGISTER) : (r))
+
+/* Use gcc hard register numbering for eh_frame. */
+#define DWARF_FRAME_REGNUM(REGNO) (REGNO)
+
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
@@ -824,6 +946,13 @@ extern int rs6000_default_long_calls;
v31 - v20 (saved; order given to save least number)
*/
+#if FIXED_R2 == 1
+#define MAYBE_R2_AVAILABLE
+#define MAYBE_R2_FIXED 2,
+#else
+#define MAYBE_R2_AVAILABLE 2,
+#define MAYBE_R2_FIXED
+#endif
#define REG_ALLOC_ORDER \
{32, \
@@ -832,13 +961,13 @@ extern int rs6000_default_long_calls;
63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
50, 49, 48, 47, 46, \
75, 74, 69, 68, 72, 71, 70, \
- 0, \
+ 0, MAYBE_R2_AVAILABLE \
9, 11, 10, 8, 7, 6, 5, 4, \
3, \
31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, \
18, 17, 16, 15, 14, 13, 12, \
64, 66, 65, \
- 73, 1, 2, 67, 76, \
+ 73, 1, MAYBE_R2_FIXED 67, 76, \
/* AltiVec registers. */ \
77, 78, \
90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \
@@ -891,6 +1020,11 @@ extern int rs6000_default_long_calls;
? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
+ ((TARGET_32BIT && TARGET_POWERPC64 \
+ && (MODE == DImode || MODE == DFmode) \
+ && INT_REGNO_P (REGNO)) ? 1 : 0)
+
#define ALTIVEC_VECTOR_MODE(MODE) \
((MODE) == V16QImode \
|| (MODE) == V8HImode \
@@ -912,22 +1046,25 @@ extern int rs6000_default_long_calls;
|| (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (MODE)))
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
- For POWER and PowerPC, the GPRs can hold any mode, but the float
+ For POWER and PowerPC, the GPRs can hold any mode, but values bigger
+ than one register cannot go past R31. The float
registers only can hold floating modes and DImode, and CR register only
can hold CC modes. We cannot put TImode anywhere except general
register and it must be able to fit within the register set. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
- (FP_REGNO_P (REGNO) ? \
- (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- || (GET_MODE_CLASS (MODE) == MODE_INT \
- && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD)) \
+ (INT_REGNO_P (REGNO) ? \
+ INT_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1) \
+ : FP_REGNO_P (REGNO) ? \
+ ((GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ && FP_REGNO_P (REGNO + HARD_REGNO_NREGS (REGNO, MODE) - 1)) \
+ || (GET_MODE_CLASS (MODE) == MODE_INT \
+ && GET_MODE_SIZE (MODE) == UNITS_PER_FP_WORD)) \
: ALTIVEC_REGNO_P (REGNO) ? ALTIVEC_VECTOR_MODE (MODE) \
: SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \
: CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \
: XER_REGNO_P (REGNO) ? (MODE) == PSImode \
- : ! INT_REGNO_P (REGNO) ? GET_MODE_SIZE (MODE) <= UNITS_PER_WORD \
- : 1)
+ : GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
/* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2.
@@ -942,12 +1079,22 @@ extern int rs6000_default_long_calls;
? GET_MODE_CLASS (MODE2) == MODE_CC \
: GET_MODE_CLASS (MODE2) == MODE_CC \
? GET_MODE_CLASS (MODE1) == MODE_CC \
+ : SPE_VECTOR_MODE (MODE1) \
+ ? SPE_VECTOR_MODE (MODE2) \
+ : SPE_VECTOR_MODE (MODE2) \
+ ? SPE_VECTOR_MODE (MODE1) \
: ALTIVEC_VECTOR_MODE (MODE1) \
? ALTIVEC_VECTOR_MODE (MODE2) \
: ALTIVEC_VECTOR_MODE (MODE2) \
? ALTIVEC_VECTOR_MODE (MODE1) \
: 1)
+/* Post-reload, we can't use any new AltiVec registers, as we already
+ emitted the vrsave mask. */
+
+#define HARD_REGNO_RENAME_OK(SRC, DST) \
+ (! ALTIVEC_REGNO_P (DST) || regs_ever_live[DST])
+
/* A C expression returning the cost of moving data from a register of class
CLASS1 to one of CLASS2. */
@@ -966,6 +1113,10 @@ extern int rs6000_default_long_calls;
#define BRANCH_COST 3
+/* Override BRANCH_COST heuristic which empirically produces worse
+ performance for fold_range_test(). */
+
+#define RANGE_TEST_NON_SHORT_CIRCUIT 0
/* A fixed register used at prologue and epilogue generation to fix
addressing modes. The SPE needs heavy addressing fixes at the last
@@ -976,7 +1127,7 @@ extern int rs6000_default_long_calls;
we end up clobbering r11.
The AltiVec case needs to be fixed. Dunno if we should break ABI
- compatability and reserve a register for it as well.. */
+ compatibility and reserve a register for it as well.. */
#define FIXED_SCRATCH (TARGET_SPE ? 14 : 11)
@@ -1063,11 +1214,6 @@ extern int rs6000_default_long_calls;
/* Count register number. */
#define COUNT_REGISTER_REGNUM 66
-
-/* Place that structure value return address is placed.
-
- On the RS/6000, it is passed as an extra parameter. */
-#define STRUCT_VALUE 0
/* Define the classes of registers for register constraints in the
machine description. Also define ranges of constants.
@@ -1091,7 +1237,7 @@ extern int rs6000_default_long_calls;
/* The RS/6000 has three types of registers, fixed-point, floating-point,
and condition registers, plus three special registers, MQ, CTR, and the
- link register.
+ link register. AltiVec adds a vector register class.
However, r0 is special in that it cannot be used as a base register.
So make a class for registers valid as base registers.
@@ -1273,11 +1419,13 @@ enum reg_class
'S' is a constant that can be placed into a 64-bit mask operand
'T' is a constant that can be placed into a 32-bit mask operand
'U' is for V.4 small data references.
+ 'W' is a vector constant that can be easily generated (no mem refs).
+ 'Y' is a indexed or word-aligned displacement memory operand.
't' is for AND masks that can be performed by two rldic{l,r} insns. */
#define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
- : (C) == 'R' ? LEGITIMATE_CONSTANT_POOL_ADDRESS_P (OP) \
+ : (C) == 'R' ? legitimate_constant_pool_address_p (OP) \
: (C) == 'S' ? mask64_operand (OP, DImode) \
: (C) == 'T' ? mask_operand (OP, SImode) \
: (C) == 'U' ? (DEFAULT_ABI == ABI_V4 \
@@ -1286,8 +1434,17 @@ enum reg_class
&& (fixed_regs[CR0_REGNO] \
|| !logical_operand (OP, DImode)) \
&& !mask64_operand (OP, DImode)) \
+ : (C) == 'W' ? (easy_vector_constant (OP, GET_MODE (OP))) \
+ : (C) == 'Y' ? (word_offset_memref_operand (OP, GET_MODE (OP))) \
: 0)
+/* Defining, which contraints are memory contraints. Tells reload,
+ that any memory address can be reloaded by copying the
+ memory address into a base register if required. */
+
+#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
+ ((C) == 'Q' || (C) == 'Y')
+
/* Given an rtx X being reloaded into a reg required to be
in class CLASS, return the class of reg to actually use.
In general this is just CLASS; but on some machines
@@ -1315,12 +1472,22 @@ enum reg_class
? GENERAL_REGS \
: (CLASS)))
+#define DISPARAGE_RELOAD_CLASS(X, CLASS) \
+ (GET_CODE (X) == REG \
+ && REGNO (X) < FIRST_PSEUDO_REGISTER \
+ && SECONDARY_MEMORY_NEEDED (GET_MODE_CLASS (GET_MODE (X)), \
+ CLASS, GET_MODE (X)) \
+ ? 6 : 0)
+
/* Return the register class of a scratch register needed to copy IN into
or out of a register in CLASS in MODE. If it can be done directly,
NO_REGS is returned. */
-#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
- secondary_reload_class (CLASS, MODE, IN)
+#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \
+ secondary_reload_class (CLASS, MODE, IN, 1)
+
+#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, IN) \
+ secondary_reload_class (CLASS, MODE, IN, 0)
/* If we are copying between FP or AltiVec registers and anything
else, we need a memory location. */
@@ -1344,11 +1511,14 @@ enum reg_class
/* Return a class of registers that cannot change FROM mode to TO mode. */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
- ? reg_classes_intersect_p (FLOAT_REGS, CLASS) \
- : (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1 \
- ? reg_classes_intersect_p (GENERAL_REGS, CLASS) \
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) \
+ && GET_MODE_SIZE (FROM) >= 8 && GET_MODE_SIZE (TO) >= 8) \
+ ? 0 \
+ : GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (FLOAT_REGS, CLASS) \
+ : (TARGET_SPE && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1) \
+ ? reg_classes_intersect_p (GENERAL_REGS, CLASS) \
: 0)
/* Stack layout; function entry, exit and calling. */
@@ -1357,60 +1527,19 @@ enum reg_class
enum rs6000_abi {
ABI_NONE,
ABI_AIX, /* IBM's AIX */
- ABI_AIX_NODESC, /* AIX calling sequence minus
- function descriptors */
ABI_V4, /* System V.4/eabi */
ABI_DARWIN /* Apple's Darwin (OS X kernel) */
};
extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */
-/* Structure used to define the rs6000 stack */
-typedef struct rs6000_stack {
- int first_gp_reg_save; /* first callee saved GP register used */
- int first_fp_reg_save; /* first callee saved FP register used */
- int first_altivec_reg_save; /* first callee saved AltiVec register used */
- int lr_save_p; /* true if the link reg needs to be saved */
- int cr_save_p; /* true if the CR reg needs to be saved */
- unsigned int vrsave_mask; /* mask of vec registers to save */
- int toc_save_p; /* true if the TOC needs to be saved */
- int push_p; /* true if we need to allocate stack space */
- int calls_p; /* true if the function makes any calls */
- enum rs6000_abi abi; /* which ABI to use */
- int gp_save_offset; /* offset to save GP regs from initial SP */
- int fp_save_offset; /* offset to save FP regs from initial SP */
- int altivec_save_offset; /* offset to save AltiVec regs from inital SP */
- int lr_save_offset; /* offset to save LR from initial SP */
- int cr_save_offset; /* offset to save CR from initial SP */
- int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
- int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
- int toc_save_offset; /* offset to save the TOC pointer */
- int varargs_save_offset; /* offset to save the varargs registers */
- int ehrd_offset; /* offset to EH return data */
- int reg_size; /* register size (4 or 8) */
- int varargs_size; /* size to hold V.4 args passed in regs */
- int vars_size; /* variable save area size */
- int parm_size; /* outgoing parameter size */
- int save_size; /* save area size */
- int fixed_size; /* fixed size of stack frame */
- int gp_size; /* size of saved GP registers */
- int fp_size; /* size of saved FP registers */
- int altivec_size; /* size of saved AltiVec registers */
- int cr_size; /* size to hold CR if not in save_size */
- int lr_size; /* size to hold LR if not in save_size */
- int vrsave_size; /* size to hold VRSAVE if not in save_size */
- int altivec_padding_size; /* size of altivec alignment padding if
- not in save_size */
- int spe_gp_size; /* size of 64-bit GPR save size for SPE */
- int spe_padding_size;
- int toc_size; /* size to hold TOC if not in save_size */
- int total_size; /* total bytes allocated for stack */
-} rs6000_stack_t;
-
/* Define this if pushing a word on the stack
makes the stack pointer a smaller address. */
#define STACK_GROWS_DOWNWARD
+/* Offsets recorded in opcodes are a multiple of this alignment factor. */
+#define DWARF_CIE_DATA_ALIGNMENT (-((int) (TARGET_32BIT ? 4 : 8)))
+
/* Define this if the nominal address of the stack frame
is at the high-address end of the local variables;
that is, each additional local variable allocated
@@ -1422,14 +1551,13 @@ typedef struct rs6000_stack {
/* Size of the outgoing register save area */
#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \
- || DEFAULT_ABI == ABI_AIX_NODESC \
|| DEFAULT_ABI == ABI_DARWIN) \
? (TARGET_64BIT ? 64 : 32) \
: 0)
/* Size of the fixed area on the stack */
#define RS6000_SAVE_AREA \
- (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_DARWIN) ? 24 : 8) \
+ (((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) ? 24 : 8) \
<< (TARGET_64BIT ? 1 : 0))
/* MEM representing address to save the TOC register */
@@ -1519,57 +1647,14 @@ typedef struct rs6000_stack {
/* 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.
-
- On the SPE, both FPs and vectors are returned in r3.
-
- On RS/6000 an integer value is in r3 and a floating-point value is in
- fp1, unless -msoft-float. */
-
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx_REG ((INTEGRAL_TYPE_P (VALTYPE) \
- && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
- || POINTER_TYPE_P (VALTYPE) \
- ? word_mode : TYPE_MODE (VALTYPE), \
- TREE_CODE (VALTYPE) == VECTOR_TYPE \
- && TARGET_ALTIVEC ? ALTIVEC_ARG_RETURN \
- : TREE_CODE (VALTYPE) == REAL_TYPE \
- && TARGET_SPE_ABI && !TARGET_FPRS \
- ? GP_ARG_RETURN \
- : TREE_CODE (VALTYPE) == REAL_TYPE \
- && TARGET_HARD_FLOAT && TARGET_FPRS \
- ? FP_ARG_RETURN : GP_ARG_RETURN)
+ otherwise, FUNC is 0. */
+
+#define FUNCTION_VALUE(VALTYPE, FUNC) rs6000_function_value ((VALTYPE), (FUNC))
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
-#define LIBCALL_VALUE(MODE) \
- gen_rtx_REG (MODE, ALTIVEC_VECTOR_MODE (MODE) ? ALTIVEC_ARG_RETURN \
- : GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && TARGET_HARD_FLOAT && TARGET_FPRS \
- ? FP_ARG_RETURN : GP_ARG_RETURN)
-
-/* The AIX ABI for the RS/6000 specifies that all structures are
- returned in memory. The Darwin ABI does the same. The SVR4 ABI
- specifies that structures <= 8 bytes are returned in r3/r4, but a
- draft put them in memory, and GCC used to implement the draft
- instead of the final standard. Therefore, TARGET_AIX_STRUCT_RET
- controls this instead of DEFAULT_ABI; V.4 targets needing backward
- compatibility can change DRAFT_V4_STRUCT_RET to override the
- default, and -m switches get the final word. See
- rs6000_override_options for more details.
-
- The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
- long double support is enabled. These values are returned in memory.
-
- int_size_in_bytes returns -1 for variable size objects, which go in
- memory always. The cast to unsigned makes -1 > 8. */
-
-#define RETURN_IN_MEMORY(TYPE) \
- ((AGGREGATE_TYPE_P (TYPE) \
- && (TARGET_AIX_STRUCT_RET \
- || (unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) > 8)) \
- || (DEFAULT_ABI == ABI_V4 && TYPE_MODE (TYPE) == TFmode))
+#define LIBCALL_VALUE(MODE) rs6000_libcall_value ((MODE))
/* DRAFT_V4_STRUCT_RET defaults off. */
#define DRAFT_V4_STRUCT_RET 0
@@ -1595,7 +1680,6 @@ typedef struct rs6000_stack {
#define FP_ARG_AIX_MAX_REG 45
#define FP_ARG_V4_MAX_REG 40
#define FP_ARG_MAX_REG ((DEFAULT_ABI == ABI_AIX \
- || DEFAULT_ABI == ABI_AIX_NODESC \
|| DEFAULT_ABI == ABI_DARWIN) \
? FP_ARG_AIX_MAX_REG : FP_ARG_V4_MAX_REG)
#define FP_ARG_NUM_REG (FP_ARG_MAX_REG - FP_ARG_MIN_REG + 1)
@@ -1625,7 +1709,7 @@ typedef struct rs6000_stack {
#define FUNCTION_VALUE_REGNO_P(N) \
((N) == GP_ARG_RETURN \
|| ((N) == FP_ARG_RETURN && TARGET_HARD_FLOAT) \
- || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC))
+ || ((N) == ALTIVEC_ARG_RETURN && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI))
/* 1 if N is a possible register number for function argument passing.
On RS/6000, these are r3-r10 and fp1-fp13.
@@ -1633,7 +1717,7 @@ typedef struct rs6000_stack {
#define FUNCTION_ARG_REGNO_P(N) \
((unsigned) (N) - GP_ARG_MIN_REG < GP_ARG_NUM_REG \
|| ((unsigned) (N) - ALTIVEC_ARG_MIN_REG < ALTIVEC_ARG_NUM_REG \
- && TARGET_ALTIVEC) \
+ && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI) \
|| ((unsigned) (N) - FP_ARG_MIN_REG < FP_ARG_NUM_REG \
&& TARGET_HARD_FLOAT))
@@ -1645,6 +1729,12 @@ typedef struct machine_function GTY(())
int sysv_varargs_p;
/* Flags if __builtin_return_address (n) with n >= 1 was used. */
int ra_needs_full_frame;
+ /* Some local-dynamic symbol. */
+ const char *some_ld_name;
+ /* Whether the instruction chain has been scanned already. */
+ int insn_chain_scanned_p;
+ /* Flags if __builtin_return_address (0) was used. */
+ int ra_need_lr;
} machine_function;
/* Define a data type for recording info about an argument list
@@ -1659,7 +1749,7 @@ typedef struct machine_function GTY(())
have prototype types for.
For ABI_V4, we treat these slightly differently -- `sysv_gregno' is
- the next availible GP register, `fregno' is the next available FP
+ the next available GP register, `fregno' is the next available FP
register, and `words' is the number of words used on the stack.
The varargs/stdarg support requires that this structure's size
@@ -1671,37 +1761,29 @@ typedef struct rs6000_args
int fregno; /* next available FP register */
int vregno; /* next available AltiVec register */
int nargs_prototype; /* # args left in the current prototype */
- int orig_nargs; /* Original value of nargs_prototype */
int prototype; /* Whether a prototype was defined */
+ int stdarg; /* Whether function is a stdarg function. */
int call_cookie; /* Do special things for this call */
int sysv_gregno; /* next available GP register */
} CUMULATIVE_ARGS;
-/* Define intermediate macro to compute the size (in registers) of an argument
- for the RS/6000. */
-
-#define RS6000_ARG_SIZE(MODE, TYPE) \
-((MODE) != BLKmode \
- ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD \
- : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
-
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
- init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE, FALSE)
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
+ init_cumulative_args (&CUM, FNTYPE, LIBNAME, FALSE, FALSE, N_NAMED_ARGS)
/* Similar, but when scanning the definition of a procedure. We always
set NARGS_PROTOTYPE large so we never return an EXPR_LIST. */
-#define INIT_CUMULATIVE_INCOMING_ARGS(CUM,FNTYPE,LIBNAME) \
- init_cumulative_args (&CUM, FNTYPE, LIBNAME, TRUE, FALSE)
+#define INIT_CUMULATIVE_INCOMING_ARGS(CUM, FNTYPE, LIBNAME) \
+ init_cumulative_args (&CUM, FNTYPE, LIBNAME, TRUE, FALSE, 1000)
/* Like INIT_CUMULATIVE_ARGS' but only used for outgoing libcalls. */
#define INIT_CUMULATIVE_LIBCALL_ARGS(CUM, MODE, LIBNAME) \
- init_cumulative_args (&CUM, NULL_TREE, LIBNAME, FALSE, TRUE)
+ init_cumulative_args (&CUM, NULL_TREE, LIBNAME, FALSE, TRUE, 0)
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
@@ -1710,18 +1792,6 @@ typedef struct rs6000_args
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
function_arg_advance (&CUM, MODE, TYPE, NAMED)
-/* Nonzero if we can use a floating-point register to pass this arg. */
-#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
- (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && (CUM).fregno <= FP_ARG_MAX_REG \
- && TARGET_HARD_FLOAT && TARGET_FPRS)
-
-/* Nonzero if we can use an AltiVec register to pass this arg. */
-#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE) \
- (ALTIVEC_VECTOR_MODE (MODE) \
- && (CUM).vregno <= ALTIVEC_ARG_MAX_REG \
- && TARGET_ALTIVEC_ABI)
-
/* Determine where to put an argument to a function.
Value is zero to push the argument on the stack,
or a hard register in which to store the argument.
@@ -1778,27 +1848,6 @@ typedef struct rs6000_args
#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
function_arg_boundary (MODE, TYPE)
-/* Perform any needed actions needed for a function that is receiving a
- variable number of arguments.
-
- CUM is as above.
-
- MODE and TYPE are the mode and type of the current parameter.
-
- PRETEND_SIZE is a variable that should be set to the amount of stack
- that must be pushed by the prolog to pretend that our caller pushed
- it.
-
- Normally, this macro will push all remaining incoming registers on the
- stack and set PRETEND_SIZE to the length of the registers pushed. */
-
-#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
- setup_incoming_varargs (&CUM, MODE, TYPE, &PRETEND_SIZE, NO_RTL)
-
-/* Define the `__builtin_va_list' type for the ABI. */
-#define BUILD_VA_LIST_TYPE(VALIST) \
- (VALIST) = rs6000_build_va_list ()
-
/* Implement `va_start' for varargs and stdarg. */
#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
rs6000_va_start (valist, nextarg)
@@ -1807,22 +1856,13 @@ typedef struct rs6000_args
#define EXPAND_BUILTIN_VA_ARG(valist, type) \
rs6000_va_arg (valist, type)
-/* For AIX, the rule is that structures are passed left-aligned in
- their stack slot. However, GCC does not presently do this:
- structures which are the same size as integer types are passed
- right-aligned, as if they were in fact integers. This only
- matters for structures of size 1 or 2, or 4 when TARGET_64BIT.
- ABI_V4 does not use std_expand_builtin_va_arg. */
-#define PAD_VARARGS_DOWN (TYPE_MODE (type) != BLKmode)
+#define PAD_VARARGS_DOWN \
+ (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
/* Define this macro to be a nonzero value if the location where a function
argument is passed depends on whether or not it is a named argument. */
#define STRICT_ARGUMENT_NAMING 1
-/* We do not allow indirect calls to be optimized into sibling calls, nor
- do we allow calls with vector parameters. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) function_ok_for_sibcall ((DECL))
-
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
@@ -1878,8 +1918,7 @@ typedef struct rs6000_args
abi's store the return address. */
#define RETURN_ADDRESS_OFFSET \
((DEFAULT_ABI == ABI_AIX \
- || DEFAULT_ABI == ABI_DARWIN \
- || DEFAULT_ABI == ABI_AIX_NODESC) ? (TARGET_32BIT ? 8 : 16) : \
+ || DEFAULT_ABI == ABI_DARWIN) ? (TARGET_32BIT ? 8 : 16) : \
(DEFAULT_ABI == ABI_V4) ? 4 : \
(internal_error ("RETURN_ADDRESS_OFFSET not supported"), 0))
@@ -1930,27 +1969,11 @@ typedef struct rs6000_args
/* Define the offset between two registers, one to be eliminated, and the other
its replacement, at the start of a routine. */
-#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-{ \
- rs6000_stack_t *info = rs6000_stack_info (); \
- \
- if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
- (OFFSET) = (info->push_p) ? 0 : - info->total_size; \
- else if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \
- (OFFSET) = info->total_size; \
- else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
- (OFFSET) = (info->push_p) ? info->total_size : 0; \
- else if ((FROM) == RS6000_PIC_OFFSET_TABLE_REGNUM) \
- (OFFSET) = 0; \
- else \
- abort (); \
-}
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ ((OFFSET) = rs6000_initial_elimination_offset(FROM, TO))
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT 0 */
-/* #define HAVE_POST_DECREMENT 0 */
-
#define HAVE_PRE_DECREMENT 1
#define HAVE_PRE_INCREMENT 1
@@ -1993,9 +2016,13 @@ typedef struct rs6000_args
acceptable. */
#define LEGITIMATE_CONSTANT_P(X) \
- (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode \
- || (TARGET_POWERPC64 && GET_MODE (X) == DImode) \
- || easy_fp_constant (X, GET_MODE (X)))
+ (((GET_CODE (X) != CONST_DOUBLE \
+ && GET_CODE (X) != CONST_VECTOR) \
+ || GET_MODE (X) == VOIDmode \
+ || (TARGET_POWERPC64 && GET_MODE (X) == DImode) \
+ || easy_fp_constant (X, GET_MODE (X)) \
+ || easy_vector_constant (X, GET_MODE (X))) \
+ && !rs6000_tls_referenced_p (X))
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
@@ -2042,7 +2069,7 @@ typedef struct rs6000_args
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 and DImode with an constant plus register,
+ auto-increment. For DFmode and DImode with a constant plus register,
we must ensure that both words are addressable or PowerPC64 with offset
word aligned.
@@ -2051,73 +2078,6 @@ typedef struct rs6000_args
adjacent memory cells are accessed by adding word-sized offsets
during assembly output. */
-#define CONSTANT_POOL_EXPR_P(X) (constant_pool_expr_p (X))
-
-#define TOC_RELATIVE_EXPR_P(X) (toc_relative_expr_p (X))
-
-/* SPE offset addressing is limited to 5-bits worth of double words. */
-#define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
-
-#define LEGITIMATE_CONSTANT_POOL_ADDRESS_P(X) \
- (TARGET_TOC \
- && GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == REG \
- && (TARGET_MINIMAL_TOC || REGNO (XEXP (X, 0)) == TOC_REGISTER) \
- && CONSTANT_POOL_EXPR_P (XEXP (X, 1)))
-
-#define LEGITIMATE_SMALL_DATA_P(MODE, X) \
- (DEFAULT_ABI == ABI_V4 \
- && !flag_pic && !TARGET_TOC \
- && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST) \
- && small_data_operand (X, MODE))
-
-#define LEGITIMATE_ADDRESS_INTEGER_P(X, OFFSET) \
- (GET_CODE (X) == CONST_INT \
- && (unsigned HOST_WIDE_INT) (INTVAL (X) + (OFFSET) + 0x8000) < 0x10000)
-
-#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X, STRICT) \
- (GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == REG \
- && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
- && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0) \
- && (! ALTIVEC_VECTOR_MODE (MODE) \
- || (GET_CODE (XEXP (X,1)) == CONST_INT && INTVAL (XEXP (X,1)) == 0)) \
- && (! SPE_VECTOR_MODE (MODE) \
- || (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && SPE_CONST_OFFSET_OK (INTVAL (XEXP (X, 1))))) \
- && (((MODE) != DFmode && (MODE) != DImode) \
- || (TARGET_32BIT \
- ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
- : ! (INTVAL (XEXP (X, 1)) & 3))) \
- && (((MODE) != TFmode && (MODE) != TImode) \
- || (TARGET_32BIT \
- ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \
- : (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \
- && ! (INTVAL (XEXP (X, 1)) & 3)))))
-
-#define LEGITIMATE_INDEXED_ADDRESS_P(X, STRICT) \
- (GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == REG \
- && GET_CODE (XEXP (X, 1)) == REG \
- && ((INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
- && INT_REG_OK_FOR_INDEX_P (XEXP (X, 1), (STRICT))) \
- || (INT_REG_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
- && INT_REG_OK_FOR_INDEX_P (XEXP (X, 0), (STRICT)))))
-
-#define LEGITIMATE_INDIRECT_ADDRESS_P(X, STRICT) \
- (GET_CODE (X) == REG && INT_REG_OK_FOR_BASE_P (X, (STRICT)))
-
-#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X, STRICT) \
- (TARGET_ELF \
- && ! flag_pic && ! TARGET_TOC \
- && GET_MODE_NUNITS (MODE) == 1 \
- && (GET_MODE_BITSIZE (MODE) <= 32 \
- || (TARGET_HARD_FLOAT && TARGET_FPRS && (MODE) == DFmode)) \
- && GET_CODE (X) == LO_SUM \
- && GET_CODE (XEXP (X, 0)) == REG \
- && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
- && CONSTANT_P (XEXP (X, 1)))
-
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ if (rs6000_legitimate_address (MODE, X, REG_OK_STRICT_FLAG)) \
goto ADDR; \
@@ -2172,27 +2132,13 @@ do { \
} while (0)
/* Go to LABEL if ADDR (a legitimate address expression)
- has an effect that depends on the machine mode it is used for.
-
- On the RS/6000 this is true if the address is valid with a zero offset
- but not with an offset of four (this means it cannot be used as an
- address for DImode or DFmode) or is a pre-increment or decrement. Since
- we know it is valid, we just check for an address that is not valid with
- an offset of four. */
+ has an effect that depends on the machine mode it is used for. */
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
-{ if (GET_CODE (ADDR) == PLUS \
- && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1), 0) \
- && ! LEGITIMATE_ADDRESS_INTEGER_P (XEXP (ADDR, 1), \
- (TARGET_32BIT ? 4 : 8))) \
+do { \
+ if (rs6000_mode_dependent_address (ADDR)) \
goto LABEL; \
- if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_INC) \
- goto LABEL; \
- if (TARGET_UPDATE && GET_CODE (ADDR) == PRE_DEC) \
- goto LABEL; \
- if (GET_CODE (ADDR) == LO_SUM) \
- goto LABEL; \
-}
+} while (0)
/* The register number of the register used to address a table of
static data addresses in memory. In some cases this register is
@@ -2239,14 +2185,6 @@ do { \
generating position independent code. */
/* #define LEGITIMATE_PIC_OPERAND_P (X) */
-
-/* In rare cases, correct code generation requires extra machine
- dependent processing between the second jump optimization pass and
- delayed branch scheduling. On those machines, define this macro
- as a C statement to act on the code starting at INSN. */
-
-/* #define MACHINE_DEPENDENT_REORG(INSN) */
-
/* Define this if some processing needs to be done immediately before
emitting code for an insn. */
@@ -2298,14 +2236,24 @@ do { \
is done just by pretending it is already truncated. */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
+/* The cntlzw and cntlzd instructions return 32 and 64 for input of zero. */
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
+ ((VALUE) = ((MODE) == SImode ? 32 : 64))
+
+/* The CTZ patterns return -1 for input of zero. */
+#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1)
+
/* Specify the machine mode that pointers have.
After generation of rtl, the compiler makes no further distinction
between pointers and any other objects of this machine mode. */
#define Pmode (TARGET_32BIT ? SImode : DImode)
+/* Supply definition of STACK_SIZE_MODE for allocate_dynamic_stack_space. */
+#define STACK_SIZE_MODE (TARGET_32BIT ? SImode : DImode)
+
/* Mode of a function address in a call instruction (for indexing purposes).
Doesn't matter on RS/6000. */
-#define FUNCTION_MODE (TARGET_32BIT ? SImode : DImode)
+#define FUNCTION_MODE SImode
/* Define this if addresses of constant functions
shouldn't be put through pseudo regs where they can be cse'd.
@@ -2321,155 +2269,6 @@ do { \
#define SHIFT_COUNT_TRUNCATED (TARGET_POWER ? 1 : 0)
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch.
-
- On the RS/6000, if it is valid in the insn, it is free. So this
- always returns 0. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- case CONST_DOUBLE: \
- case HIGH: \
- return 0;
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case PLUS: \
- return ((GET_CODE (XEXP (X, 1)) == CONST_INT \
- && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (X, 1)) \
- + 0x8000) >= 0x10000) \
- && ((INTVAL (XEXP (X, 1)) & 0xffff) != 0)) \
- ? COSTS_N_INSNS (2) \
- : COSTS_N_INSNS (1)); \
- case AND: \
- case IOR: \
- case XOR: \
- return ((GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (INTVAL (XEXP (X, 1)) & (~ (HOST_WIDE_INT) 0xffff)) != 0 \
- && ((INTVAL (XEXP (X, 1)) & 0xffff) != 0)) \
- ? COSTS_N_INSNS (2) \
- : COSTS_N_INSNS (1)); \
- case MULT: \
- if (optimize_size) \
- return COSTS_N_INSNS (2); \
- switch (rs6000_cpu) \
- { \
- case PROCESSOR_RIOS1: \
- case PROCESSOR_PPC405: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? COSTS_N_INSNS (5) \
- : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
- ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \
- case PROCESSOR_RS64A: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (20) : COSTS_N_INSNS (34) \
- : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
- ? COSTS_N_INSNS (8) : COSTS_N_INSNS (12)); \
- case PROCESSOR_RIOS2: \
- case PROCESSOR_MPCCORE: \
- case PROCESSOR_PPC604e: \
- return COSTS_N_INSNS (2); \
- case PROCESSOR_PPC601: \
- return COSTS_N_INSNS (5); \
- case PROCESSOR_PPC603: \
- case PROCESSOR_PPC7400: \
- case PROCESSOR_PPC750: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? COSTS_N_INSNS (5) \
- : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
- ? COSTS_N_INSNS (2) : COSTS_N_INSNS (3)); \
- case PROCESSOR_PPC7450: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? COSTS_N_INSNS (4) \
- : COSTS_N_INSNS (3)); \
- case PROCESSOR_PPC403: \
- case PROCESSOR_PPC604: \
- case PROCESSOR_PPC8540: \
- return COSTS_N_INSNS (4); \
- case PROCESSOR_PPC620: \
- case PROCESSOR_PPC630: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (5) : COSTS_N_INSNS (7) \
- : INTVAL (XEXP (X, 1)) >= -256 && INTVAL (XEXP (X, 1)) <= 255 \
- ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)); \
- case PROCESSOR_POWER4: \
- return (GET_CODE (XEXP (X, 1)) != CONST_INT \
- ? GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4) \
- : COSTS_N_INSNS (2)); \
- } \
- case DIV: \
- case MOD: \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT \
- && exact_log2 (INTVAL (XEXP (X, 1))) >= 0) \
- return COSTS_N_INSNS (2); \
- /* otherwise fall through to normal divide. */ \
- case UDIV: \
- case UMOD: \
- switch (rs6000_cpu) \
- { \
- case PROCESSOR_RIOS1: \
- return COSTS_N_INSNS (19); \
- case PROCESSOR_RIOS2: \
- return COSTS_N_INSNS (13); \
- case PROCESSOR_RS64A: \
- return (GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (65) \
- : COSTS_N_INSNS (67)); \
- case PROCESSOR_MPCCORE: \
- return COSTS_N_INSNS (6); \
- case PROCESSOR_PPC403: \
- return COSTS_N_INSNS (33); \
- case PROCESSOR_PPC405: \
- return COSTS_N_INSNS (35); \
- case PROCESSOR_PPC601: \
- return COSTS_N_INSNS (36); \
- case PROCESSOR_PPC603: \
- return COSTS_N_INSNS (37); \
- case PROCESSOR_PPC604: \
- case PROCESSOR_PPC604e: \
- return COSTS_N_INSNS (20); \
- case PROCESSOR_PPC620: \
- case PROCESSOR_PPC630: \
- case PROCESSOR_POWER4: \
- return (GET_MODE (XEXP (X, 1)) != DImode \
- ? COSTS_N_INSNS (21) \
- : COSTS_N_INSNS (37)); \
- case PROCESSOR_PPC750: \
- case PROCESSOR_PPC8540: \
- case PROCESSOR_PPC7400: \
- return COSTS_N_INSNS (19); \
- case PROCESSOR_PPC7450: \
- return COSTS_N_INSNS (23); \
- } \
- case FFS: \
- return COSTS_N_INSNS (4); \
- case MEM: \
- /* MEM should be slightly more expensive than (plus (reg) (const)) */ \
- return 5;
-
-/* Compute the cost of an address. This is meant to approximate the size
- and/or execution delay of an insn using that address. If the cost is
- approximated by the RTL complexity, including CONST_COSTS above, as
- is usually the case for CISC machines, this macro should not be defined.
- For aggressively RISCy machines, only one insn format is allowed, so
- this macro should be a constant. The value of this macro only matters
- for valid addresses.
-
- For the RS/6000, everything is cost 0. */
-
-#define ADDRESS_COST(RTX) 0
-
/* Adjust the length of an INSN. LENGTH is the currently-computed length and
should be adjusted to reflect any required changes. This macro is used when
there is some systematic length adjustment required that would be difficult
@@ -2490,9 +2289,16 @@ do { \
: (((OP) == EQ || (OP) == NE) && GET_RTX_CLASS (GET_CODE (X)) == '<' \
? CCEQmode : CCmode))
+/* Can the condition code MODE be safely reversed? This is safe in
+ all cases on this port, because at present it doesn't use the
+ trapping FP comparisons (fcmpo). */
+#define REVERSIBLE_CC_MODE(MODE) 1
+
+/* 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. Note that we can't use "rtx" here
- since it hasn't been defined! */
+ stored from the compare operation. */
extern GTY(()) rtx rs6000_compare_op0;
extern GTY(()) rtx rs6000_compare_op1;
@@ -2599,6 +2405,8 @@ extern int toc_initialized;
} \
while (0)
+#define TARGET_ASM_FILE_START rs6000_file_start
+
/* Output to assembler file text saying following lines
may contain character constants, extra white space, comments, etc. */
@@ -2736,31 +2544,6 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
&rs6000_reg_names[112][0], /* spefscr */ \
}
-/* print-rtl can't handle the above REGISTER_NAMES, so define the
- following for it. Switch to use the alternate names since
- they are more mnemonic. */
-
-#define DEBUG_REGISTER_NAMES \
-{ \
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", \
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", \
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
- "mq", "lr", "ctr", "ap", \
- "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
- "xer", \
- "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", \
- "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", \
- "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", \
- "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", \
- "vrsave", "vscr", \
- "spe_acc", "spefscr" \
-}
-
/* Table of additional register names to use in user input. */
#define ADDITIONAL_REGISTER_NAMES \
@@ -2820,14 +2603,6 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
if ((LOG) != 0) \
fprintf (FILE, "\t.align %d\n", (LOG))
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable named NAME.
- LABELNO is an integer which is different for each call. */
-
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
-
/* Pick up the return address upon entry to a procedure. Used for
dwarf2 unwind information. This also enables the table driven
mechanism. */
@@ -2848,7 +2623,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
/* Define which CODE values are valid. */
#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
- ((CODE) == '.')
+ ((CODE) == '.' || (CODE) == '&')
/* Print a memory address as an operand to reference that memory location. */
@@ -2880,11 +2655,15 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
{"got_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{"got_no_const_operand", {SYMBOL_REF, LABEL_REF}}, \
{"easy_fp_constant", {CONST_DOUBLE}}, \
+ {"easy_vector_constant", {CONST_VECTOR}}, \
+ {"easy_vector_constant_add_self", {CONST_VECTOR}}, \
{"zero_fp_constant", {CONST_DOUBLE}}, \
{"reg_or_mem_operand", {SUBREG, MEM, REG}}, \
{"lwa_operand", {SUBREG, MEM, REG}}, \
{"volatile_mem_operand", {MEM}}, \
{"offsettable_mem_operand", {MEM}}, \
+ {"invalid_gpr_mem", {MEM}}, \
+ {"base_reg_operand", {REG}}, \
{"mem_or_easy_const_operand", {SUBREG, MEM, CONST_DOUBLE}}, \
{"add_operand", {SUBREG, REG, CONST_INT}}, \
{"non_add_cint_operand", {CONST_INT}}, \
@@ -2900,6 +2679,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
{"count_register_operand", {REG}}, \
{"xer_operand", {REG}}, \
{"symbol_ref_operand", {SYMBOL_REF}}, \
+ {"rs6000_tls_symbol_ref", {SYMBOL_REF}}, \
{"call_operand", {SYMBOL_REF, REG}}, \
{"current_file_function_operand", {SYMBOL_REF}}, \
{"input_operand", {SUBREG, MEM, REG, CONST_INT, \
diff --git a/contrib/gcc/config/rs6000/rs6000.md b/contrib/gcc/config/rs6000/rs6000.md
index 4d5ef9db4caa..0fc4c045ea4f 100644
--- a/contrib/gcc/config/rs6000/rs6000.md
+++ b/contrib/gcc/config/rs6000/rs6000.md
@@ -1,45 +1,70 @@
;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
-;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;; 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+;; 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC 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.
+;; 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 2, or (at your
+;; option) any later version.
-;; GNU CC 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.
+;; 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 GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
-;; `unspec' values used in rs6000.md:
-;; Number Use
-;; 0 frsp for POWER machines
-;; 0/v blockage
-;; 5 used to tie the stack contents and the stack pointer
-;; 6 address of a word pointing to the TOC
-;; 7 address of the TOC (more-or-less)
-;; 8 movsi_got
-;; 9/v eh_reg_restore
-;; 10 fctiwz
-;; 15 load_macho_picbase
-;; 16 macho_correct_pic
-;; 19 movesi_from_cr
-;; 20 movesi_to_cr
+;;
+;; UNSPEC usage
+;;
+
+(define_constants
+ [(UNSPEC_FRSP 0) ; frsp for POWER machines
+ (UNSPEC_TIE 5) ; tie stack contents and stack pointer
+ (UNSPEC_TOCPTR 6) ; address of a word pointing to the TOC
+ (UNSPEC_TOC 7) ; address of the TOC (more-or-less)
+ (UNSPEC_MOVSI_GOT 8)
+ (UNSPEC_MV_CR_OV 9) ; move_from_CR_ov_bit
+ (UNSPEC_FCTIWZ 10)
+ (UNSPEC_LD_MPIC 15) ; load_macho_picbase
+ (UNSPEC_MPIC_CORRECT 16) ; macho_correct_pic
+ (UNSPEC_TLSGD 17)
+ (UNSPEC_TLSLD 18)
+ (UNSPEC_MOVESI_FROM_CR 19)
+ (UNSPEC_MOVESI_TO_CR 20)
+ (UNSPEC_TLSDTPREL 21)
+ (UNSPEC_TLSDTPRELHA 22)
+ (UNSPEC_TLSDTPRELLO 23)
+ (UNSPEC_TLSGOTDTPREL 24)
+ (UNSPEC_TLSTPREL 25)
+ (UNSPEC_TLSTPRELHA 26)
+ (UNSPEC_TLSTPRELLO 27)
+ (UNSPEC_TLSGOTTPREL 28)
+ (UNSPEC_TLSTLS 29)
+ (UNSPEC_FIX_TRUNC_TF 30) ; fadd, rounding towards zero
+ (UNSPEC_MV_CR_GT 31) ; move_from_CR_gt_bit
+ ])
+
+;;
+;; UNSPEC_VOLATILE usage
+;;
+
+(define_constants
+ [(UNSPECV_BLOCK 0)
+ (UNSPECV_EH_RR 9) ; eh_reg_restore
+ ])
;; Define an insn type attribute. This is used in function unit delay
;; computations.
-(define_attr "type" "integer,load,store,fpload,fpstore,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,branch,compare,cr_logical,delayed_compare,fpcompare,mtjmpr,fp,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,vecsimple,veccomplex,veccmp,vecperm,vecfloat,altivec"
+(define_attr "type" "integer,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv"
(const_string "integer"))
;; Length (in bytes).
@@ -58,800 +83,24 @@
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in rs6000.h.
-(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4"
+(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4,power5"
(const (symbol_ref "rs6000_cpu_attr")))
-; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
-; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
-
-; Load/Store Unit -- pure PowerPC only
-; (POWER and 601 use Integer Unit)
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "load")
- (eq_attr "cpu" "rs64a,mpccore,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "load,vecload")
- (eq_attr "cpu" "ppc7450"))
- 3 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "rs64a,mpccore,ppc603,ppc604,ppc604e,ppc620,ppc630"))
- 1 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "store,vecstore")
- (eq_attr "cpu" "ppc7450"))
- 3 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "fpstore")
- (eq_attr "cpu" "ppc7450"))
- 3 3)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "mpccore,ppc603,ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "ppc7450"))
- 4 1)
-
-(define_function_unit "lsu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "rs64a,ppc604,ppc604e,ppc620,ppc630"))
- 3 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "load")
- (eq_attr "cpu" "rios1,ppc403,ppc405,ppc601"))
- 2 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "rios1,ppc403,ppc405,ppc601"))
- 1 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpstore")
- (eq_attr "cpu" "rios1,ppc601"))
- 0 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "rios1"))
- 2 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "ppc601"))
- 3 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "load,fpload")
- (eq_attr "cpu" "rios2"))
- 2 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "rios2"))
- 1 1)
-
-; Integer Unit (RIOS1, PPC601, PPC603, RS64a)
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "rios1,rs64a,mpccore,ppc403,ppc405,ppc601,ppc603"))
- 1 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "mpccore,ppc403,ppc405,ppc601"))
- 1 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "ppc403"))
- 4 4)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc405"))
- 4 3)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul2,imul3")
- (eq_attr "cpu" "ppc405"))
- 3 2)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "rios1"))
- 5 5)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "rios1"))
- 4 4)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "rios1"))
- 3 3)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "ppc601,ppc603"))
- 5 5)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "rs64a"))
- 20 20)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "rs64a"))
- 12 12)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "rs64a"))
- 8 8)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "lmul")
- (eq_attr "cpu" "rs64a"))
- 34 34)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rios1"))
- 19 19)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rs64a"))
- 66 66)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "ldiv")
- (eq_attr "cpu" "rs64a"))
- 66 66)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc403"))
- 33 33)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc405"))
- 35 35)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc601"))
- 36 36)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc603"))
- 37 36)
-
-; RIOS2 has two integer units: a primary one which can perform all
-; operations and a secondary one which is fed in lock step with the first
-; and can perform "simple" integer operations.
-; To catch this we define a 'dummy' imuldiv-unit that is also needed
-; for the complex insns.
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "rios2"))
- 1 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "rios2"))
- 2 2)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rios2"))
- 13 13)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "rios2"))
- 2 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "rios2"))
- 13 13)
-
-; MPCCORE has separate IMUL/IDIV unit for multicycle instructions
-; Divide latency varies greatly from 2-11, use 6 as average
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "mpccore"))
- 2 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "mpccore"))
- 6 6)
-
-; PPC604{,e} has two units that perform integer operations
-; and one unit for divide/multiply operations (and move
-; from/to spr).
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
- 1 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "ppc604"))
- 4 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul,imul2,imul3")
- (eq_attr "cpu" "ppc604e"))
- 2 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc620,ppc630"))
- 5 3)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "ppc620,ppc630"))
- 4 3)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "ppc620,ppc630"))
- 3 3)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "lmul")
- (eq_attr "cpu" "ppc620,ppc630"))
- 7 5)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc604,ppc604e"))
- 20 19)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc620"))
- 37 36)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc630"))
- 21 20)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "ldiv")
- (eq_attr "cpu" "ppc620,ppc630"))
- 37 36)
-
-; PPC7450 has 3 integer units (for most integer insns) and one mul/div
-; unit, which also does CR-logical insns and move to/from SPR.
-; It also has 4 vector units, one for each type of vector instruction.
-; However, we can only dispatch 2 instructions per cycle.
-; We model this as saying that dispatching two of the same type of instruction
-; in a row incurs a single cycle delay.
-(define_function_unit "iu3" 3 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "ppc7450"))
- 1 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc7450"))
- 4 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul2,imul3")
- (eq_attr "cpu" "ppc7450"))
- 3 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc7450"))
- 23 23)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "ppc7450"))
- 1 1)
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecsimple")
- (eq_attr "cpu" "ppc7450"))
- 1 2 [(eq_attr "type" "vecsimple")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecsimple")
- (eq_attr "cpu" "ppc7450"))
- 1 1 [(eq_attr "type" "!vecsimple")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "veccomplex")
- (eq_attr "cpu" "ppc7450"))
- 4 2 [(eq_attr "type" "veccomplex")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "veccomplex")
- (eq_attr "cpu" "ppc7450"))
- 4 1 [(eq_attr "type" "!veccomplex")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "veccmp")
- (eq_attr "cpu" "ppc7450"))
- 2 2 [(eq_attr "type" "veccmp")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "veccmp")
- (eq_attr "cpu" "ppc7450"))
- 2 1 [(eq_attr "type" "!veccmp")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecfloat")
- (eq_attr "cpu" "ppc7450"))
- 4 2 [(eq_attr "type" "vecfloat")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecfloat")
- (eq_attr "cpu" "ppc7450"))
- 4 1 [(eq_attr "type" "!vecfloat")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecperm")
- (eq_attr "cpu" "ppc7450"))
- 2 2 [(eq_attr "type" "vecperm")])
-
-(define_function_unit "vec_alu2" 2 0
- (and (eq_attr "type" "vecperm")
- (eq_attr "cpu" "ppc7450"))
- 2 1 [(eq_attr "type" "!vecperm")])
-
-; PPC750 has two integer units: a primary one which can perform all
-; operations and a secondary one which is fed in lock step with the first
-; and can perform "simple" integer operations.
-; To catch this we define a 'dummy' imuldiv-unit that is also needed
-; for the complex insns.
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 1 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 4 4)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 3 2)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 19 19)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 4 4)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul2")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 3 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "imul3")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 2 1)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 19 19)
-
-; CR-logical operations are execute-serialized, that is they don't
-; start (and block the function unit) until all preceding operations
-; have finished. They don't block dispatch of other insns, though.
-; I've imitated this by giving them longer latency.
-(define_function_unit "sru" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "ppc603,ppc750,ppc7400"))
- 3 2)
-
-; compare is done on integer unit, but feeds insns which
-; execute on the branch unit.
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "compare")
- (eq_attr "cpu" "rios1"))
- 4 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "delayed_compare")
- (eq_attr "cpu" "rios1"))
- 5 1)
-
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "rs64a,mpccore,ppc403,ppc405,ppc601,ppc603"))
- 3 1)
-
-; some extra cycles added by TARGET_SCHED_ADJUST_COST between compare
-; and a following branch, to reduce mispredicts
-(define_function_unit "iu3" 3 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "ppc7450"))
- 1 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "rios2"))
- 3 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "compare,delayed_compare")
- (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400"))
- 1 1)
-
-; fp compare uses fp unit
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "rios1"))
- 9 1)
-
-; rios1 and rios2 have different fpcompare delays
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "rios2,ppc630"))
- 5 1)
-
-; on ppc601 and ppc603, fpcompare takes also 2 cycles from
-; the integer unit
-; here we do not define delays, just occupy the unit. The dependencies
-; will be assigned by the fpcompare definition in the fpu.
-(define_function_unit "iu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "ppc601,ppc603"))
- 0 2)
-
-; fp compare uses fp unit
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "rs64a,ppc601,ppc603,ppc604,ppc604e,ppc620"))
- 5 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "ppc750,ppc7400,ppc7450"))
- 3 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "mpccore"))
- 1 1)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "rios1,rios2,rs64a"))
- 5 1)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "mpccore,ppc403,ppc405,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630"))
- 4 1)
-
-(define_function_unit "sru" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "ppc750,ppc7400"))
- 2 2)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "ppc7450"))
- 2 2)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "rios1,rios2,ppc604"))
- 4 1)
-
-(define_function_unit "cru" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "ppc604e,ppc620,ppc630,rs64a"))
- 1 1)
-
-; all jumps/branches are executing on the bpu, in 1 cycle, for all machines.
-(define_function_unit "bpu" 1 0
- (eq_attr "type" "jmpreg")
- 1 1)
-
-(define_function_unit "bpu" 1 0
- (eq_attr "type" "branch")
- 1 1)
-
-; Floating Point Unit
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "rios1"))
- 2 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp")
- (eq_attr "cpu" "rs64a,mpccore"))
- 4 2)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp")
- (eq_attr "cpu" "ppc601"))
- 4 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp")
- (eq_attr "cpu" "ppc603,ppc604,ppc604e,ppc620,ppc750,ppc7400"))
- 3 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "ppc7450"))
- 5 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "rs64a"))
- 7 2)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "mpccore"))
- 5 5)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "ppc601"))
- 5 2)
-
-; is this true?
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "ppc603,ppc750"))
- 4 2)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dmul")
- (eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc7400"))
- 3 1)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv,ddiv")
- (eq_attr "cpu" "rios1"))
- 19 19)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "rs64a"))
- 31 31)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc601,ppc750,ppc7400"))
- 17 17)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc7450"))
- 21 21)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "mpccore"))
- 10 10)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc603,ppc604,ppc604e,ppc620"))
- 18 18)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "mpccore"))
- 17 17)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "rs64a,ppc601,ppc750,ppc604,ppc604e,ppc620,ppc7400"))
- 31 31)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "ppc7450"))
- 35 35)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "ppc603"))
- 33 33)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "ssqrt")
- (eq_attr "cpu" "ppc620"))
- 31 31)
-
-(define_function_unit "fpu" 1 0
- (and (eq_attr "type" "dsqrt")
- (eq_attr "cpu" "ppc620"))
- 31 31)
-
-; RIOS2 has two symmetric FPUs.
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "rios2"))
- 2 1)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "ppc630"))
- 3 1)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "sdiv,ddiv")
- (eq_attr "cpu" "rios2"))
- 17 17)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "sdiv")
- (eq_attr "cpu" "ppc630"))
- 17 17)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ddiv")
- (eq_attr "cpu" "ppc630"))
- 21 21)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ssqrt,dsqrt")
- (eq_attr "cpu" "rios2"))
- 26 26)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ssqrt")
- (eq_attr "cpu" "ppc630"))
- 18 18)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "dsqrt")
- (eq_attr "cpu" "ppc630"))
- 26 26)
-
-;; Power4
-(define_function_unit "lsu2" 2 0
- (and (eq_attr "type" "load")
- (eq_attr "cpu" "power4"))
- 3 1)
-
-(define_function_unit "lsu2" 2 0
- (and (eq_attr "type" "fpload")
- (eq_attr "cpu" "power4"))
- 5 1)
-
-(define_function_unit "lsu2" 2 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "power4"))
- 1 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "integer")
- (eq_attr "cpu" "power4"))
- 2 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "lmul")
- (eq_attr "cpu" "power4"))
- 7 6)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul")
- (eq_attr "cpu" "power4"))
- 5 4)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "imul2,imul3")
- (eq_attr "cpu" "power4"))
- 4 3)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "power4"))
- 36 35)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "ldiv")
- (eq_attr "cpu" "power4"))
- 68 67)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "idiv")
- (eq_attr "cpu" "power4"))
- 36 35)
-
-(define_function_unit "imuldiv" 1 0
- (and (eq_attr "type" "ldiv")
- (eq_attr "cpu" "power4"))
- 68 67)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "compare")
- (eq_attr "cpu" "power4"))
- 3 1)
-
-(define_function_unit "iu2" 2 0
- (and (eq_attr "type" "delayed_compare")
- (eq_attr "cpu" "power4"))
- 4 1)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "mtjmpr")
- (eq_attr "cpu" "power4"))
- 3 1)
-
-(define_function_unit "bpu" 1 0
- (and (eq_attr "type" "jmpreg,branch")
- (eq_attr "cpu" "power4"))
- 2 1)
-
-(define_function_unit "cru" 1 0
- (and (eq_attr "type" "cr_logical")
- (eq_attr "cpu" "power4"))
- 4 1)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fp,dmul")
- (eq_attr "cpu" "power4"))
- 6 1)
-
-; adjust_cost increases the cost of dependent branches,
-; so shave a few cycles off for fpcompare.
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "fpcompare")
- (eq_attr "cpu" "power4"))
- 5 1)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "sdiv,ddiv")
- (eq_attr "cpu" "power4"))
- 33 28)
-
-(define_function_unit "fpu2" 2 0
- (and (eq_attr "type" "ssqrt,dsqrt")
- (eq_attr "cpu" "power4"))
- 40 35)
+(automata_option "ndfa")
+
+(include "rios1.md")
+(include "rios2.md")
+(include "rs64.md")
+(include "mpc.md")
+(include "40x.md")
+(include "440.md")
+(include "603.md")
+(include "6xx.md")
+(include "7xx.md")
+(include "7450.md")
+(include "8540.md")
+(include "power4.md")
+(include "power5.md")
;; Start with fixed-point load and store insns. Here we put only the more
@@ -877,7 +126,7 @@
(compare:CC (zero_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rldicl. %2,%1,0,56
#"
@@ -903,7 +152,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rldicl. %0,%1,0,56
#"
@@ -935,7 +184,7 @@
(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
extsb. %2,%1
#"
@@ -961,7 +210,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(sign_extend:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
extsb. %0,%1
#"
@@ -1002,7 +251,7 @@
(compare:CC (zero_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rldicl. %2,%1,0,48
#"
@@ -1028,7 +277,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rldicl. %0,%1,0,48
#"
@@ -1062,14 +311,14 @@
"@
lha%U1%X1 %0,%1
extsh %0,%1"
- [(set_attr "type" "load,*")])
+ [(set_attr "type" "load_ext,*")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
extsh. %2,%1
#"
@@ -1095,7 +344,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(sign_extend:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
extsh. %0,%1
#"
@@ -1136,7 +385,7 @@
(compare:CC (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rldicl. %2,%1,0,32
#"
@@ -1162,7 +411,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rldicl. %0,%1,0,32
#"
@@ -1196,14 +445,14 @@
"@
lwa%U1%X1 %0,%1
extsw %0,%1"
- [(set_attr "type" "load,*")])
+ [(set_attr "type" "load_ext,*")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
extsw. %2,%1
#"
@@ -1229,7 +478,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(sign_extend:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
extsw. %0,%1
#"
@@ -1664,7 +913,7 @@
"@
lha%U1%X1 %0,%1
{exts|extsh} %0,%1"
- [(set_attr "type" "load,*")])
+ [(set_attr "type" "load_ext,*")])
(define_insn ""
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
@@ -1774,13 +1023,13 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I,r,I"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{cax.|add.} %3,%1,%2
{ai.|addic.} %3,%1,%2
#
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
@@ -1789,7 +1038,7 @@
(match_operand:SI 2 "reg_or_short_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(plus:SI (match_dup 1)
(match_dup 2)))
@@ -1806,13 +1055,13 @@
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(plus:SI (match_dup 1)
(match_dup 2)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{cax.|add.} %0,%1,%2
{ai.|addic.} %0,%1,%2
#
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
@@ -1822,7 +1071,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (match_dup 1)
(match_dup 2)))
@@ -1863,7 +1112,7 @@
(compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 2 "=r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
nor. %2,%1,%1
#"
@@ -1875,7 +1124,7 @@
(compare:CC (not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 2 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 2)
(not:SI (match_dup 1)))
(set (match_dup 0)
@@ -1889,7 +1138,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(not:SI (match_dup 1)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
nor. %0,%1,%1
#"
@@ -1902,7 +1151,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(not:SI (match_dup 1)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(not:SI (match_dup 1)))
(set (match_dup 2)
@@ -1945,11 +1194,11 @@
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
- "TARGET_POWERPC && ! TARGET_POWERPC64"
+ "TARGET_POWERPC && TARGET_32BIT"
"@
subf. %3,%2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -1958,7 +1207,7 @@
(match_operand:SI 2 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(minus:SI (match_dup 1)
(match_dup 2)))
@@ -1989,11 +1238,11 @@
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(minus:SI (match_dup 1)
(match_dup 2)))]
- "TARGET_POWERPC && ! TARGET_POWERPC64"
+ "TARGET_POWERPC && TARGET_32BIT"
"@
subf. %0,%2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2004,7 +1253,7 @@
(set (match_operand:SI 0 "gpc_reg_operand" "")
(minus:SI (match_dup 1)
(match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(minus:SI (match_dup 1)
(match_dup 2)))
@@ -2260,7 +1509,7 @@
(define_insn_and_split "abssi2_isel"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(abs:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
- (clobber (match_scratch:SI 2 "=b"))
+ (clobber (match_scratch:SI 2 "=&b"))
(clobber (match_scratch:CC 3 "=y"))]
"TARGET_ISEL"
"#"
@@ -2317,11 +1566,11 @@
(compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 2 "=r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
neg. %2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2329,7 +1578,7 @@
(compare:CC (neg:SI (match_operand:SI 1 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 2 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 2)
(neg:SI (match_dup 1)))
(set (match_dup 0)
@@ -2343,11 +1592,11 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(neg:SI (match_dup 1)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
neg. %0,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2356,7 +1605,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(neg:SI (match_dup 1)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(neg:SI (match_dup 1)))
(set (match_dup 2)
@@ -2364,13 +1613,44 @@
(const_int 0)))]
"")
-(define_insn "ffssi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
- (ffs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
+(define_insn "clzsi2"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (clz:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
""
- "neg %0,%1\;and %0,%0,%1\;{cntlz|cntlzw} %0,%0\;{sfi|subfic} %0,%0,32"
- [(set_attr "length" "16")])
+ "{cntlz|cntlzw} %0,%1")
+(define_expand "ctzsi2"
+ [(set (match_dup 2)
+ (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
+ (parallel [(set (match_dup 3) (and:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (scratch:CC))])
+ (set (match_dup 4) (clz:SI (match_dup 3)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (minus:SI (const_int 31) (match_dup 4)))]
+ ""
+ {
+ operands[2] = gen_reg_rtx (SImode);
+ operands[3] = gen_reg_rtx (SImode);
+ operands[4] = gen_reg_rtx (SImode);
+ })
+
+(define_expand "ffssi2"
+ [(set (match_dup 2)
+ (neg:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
+ (parallel [(set (match_dup 3) (and:SI (match_dup 1)
+ (match_dup 2)))
+ (clobber (scratch:CC))])
+ (set (match_dup 4) (clz:SI (match_dup 3)))
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (minus:SI (const_int 32) (match_dup 4)))]
+ ""
+ {
+ operands[2] = gen_reg_rtx (SImode);
+ operands[3] = gen_reg_rtx (SImode);
+ operands[4] = gen_reg_rtx (SImode);
+ })
+
(define_expand "mulsi3"
[(use (match_operand:SI 0 "gpc_reg_operand" ""))
(use (match_operand:SI 1 "gpc_reg_operand" ""))
@@ -2416,7 +1696,7 @@
(const_string "imul2")]
(const_string "imul")))])
-(define_insn ""
+(define_insn "*mulsi3_mq_internal1"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
@@ -2427,7 +1707,7 @@
"@
{muls.|mullw.} %3,%1,%2
#"
- [(set_attr "type" "delayed_compare")
+ [(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2446,7 +1726,7 @@
(const_int 0)))]
"")
-(define_insn ""
+(define_insn "*mulsi3_no_mq_internal1"
[(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
@@ -2456,7 +1736,7 @@
"@
{muls.|mullw.} %3,%1,%2
#"
- [(set_attr "type" "delayed_compare")
+ [(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2473,7 +1753,7 @@
(const_int 0)))]
"")
-(define_insn ""
+(define_insn "*mulsi3_mq_internal2"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
@@ -2485,7 +1765,7 @@
"@
{muls.|mullw.} %0,%1,%2
#"
- [(set_attr "type" "delayed_compare")
+ [(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2505,7 +1785,7 @@
(const_int 0)))]
"")
-(define_insn ""
+(define_insn "*mulsi3_no_mq_internal2"
[(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
@@ -2516,7 +1796,7 @@
"@
{muls.|mullw.} %0,%1,%2
#"
- [(set_attr "type" "delayed_compare")
+ [(set_attr "type" "imul_compare")
(set_attr "length" "4,8")])
(define_split
@@ -2542,7 +1822,7 @@
[(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
(div:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "gpc_reg_operand" "")))
- (set (match_operand:SI 3 "gpc_reg_operand" "")
+ (set (match_operand:SI 3 "register_operand" "")
(mod:SI (match_dup 1) (match_dup 2)))])]
"TARGET_POWER || (! TARGET_POWER && ! TARGET_POWERPC)"
"
@@ -2558,11 +1838,11 @@
}
}")
-(define_insn ""
+(define_insn "*divmodsi4_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "gpc_reg_operand" "r")))
- (set (match_operand:SI 3 "gpc_reg_operand" "=q")
+ (set (match_operand:SI 3 "register_operand" "=q")
(mod:SI (match_dup 1) (match_dup 2)))]
"TARGET_POWER"
"divs %0,%1,%2"
@@ -2948,7 +2228,7 @@
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r"))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
and. %3,%1,%2
{andil.|andi.} %3,%1,%b2
@@ -2968,7 +2248,7 @@
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r"))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
#
{andil.|andi.} %3,%1,%b2
@@ -3027,7 +2307,7 @@
(and:SI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
and. %0,%1,%2
{andil.|andi.} %0,%1,%b2
@@ -3049,7 +2329,7 @@
(and:SI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
#
{andil.|andi.} %0,%1,%b2
@@ -3239,7 +2519,7 @@
(match_operand:SI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
%q4. %3,%1,%2
#"
@@ -3253,7 +2533,7 @@
(match_operand:SI 2 "gpc_reg_operand" "")])
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0)
(compare:CC (match_dup 3)
@@ -3268,7 +2548,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
%q4. %0,%1,%2
#"
@@ -3283,14 +2563,14 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(match_dup 4))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 3)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
-;; Split an logical operation that we can't do in one insn into two insns,
+;; Split a logical operation that we can't do in one insn into two insns,
;; each of which does one 16-bit part. This is used by combine.
(define_split
@@ -3327,7 +2607,7 @@
(match_operand:SI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
%q4. %3,%2,%1
#"
@@ -3341,7 +2621,7 @@
(match_operand:SI 2 "gpc_reg_operand" "")])
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0)
(compare:CC (match_dup 3)
@@ -3356,7 +2636,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
%q4. %0,%2,%1
#"
@@ -3371,7 +2651,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(match_dup 4))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 3)
(compare:CC (match_dup 0)
@@ -3393,7 +2673,7 @@
(not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))])
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
%q4. %3,%1,%2
#"
@@ -3407,7 +2687,7 @@
(not:SI (match_operand:SI 2 "gpc_reg_operand" ""))])
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 0)
(compare:CC (match_dup 3)
@@ -3422,7 +2702,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
%q4. %0,%1,%2
#"
@@ -3437,7 +2717,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(match_dup 4))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0) (match_dup 4))
(set (match_dup 3)
(compare:CC (match_dup 0)
@@ -3674,7 +2954,8 @@
operands[4] = GEN_INT (32 - start - size);
operands[1] = GEN_INT (start + size - 1);
return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
-}")
+}"
+ [(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal1"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
@@ -3692,7 +2973,8 @@
operands[4] = GEN_INT (shift - start - size);
operands[1] = GEN_INT (start + size - 1);
return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
-}")
+}"
+ [(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal2"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
@@ -3710,7 +2992,8 @@
operands[4] = GEN_INT (32 - shift - start - size);
operands[1] = GEN_INT (start + size - 1);
return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
-}")
+}"
+ [(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal3"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
@@ -3728,7 +3011,8 @@
operands[4] = GEN_INT (32 - shift - start - size);
operands[1] = GEN_INT (start + size - 1);
return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
-}")
+}"
+ [(set_attr "type" "insert_word")])
(define_insn "*insvsi_internal4"
[(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
@@ -3749,7 +3033,8 @@
operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size);
operands[1] = GEN_INT (insert_start + insert_size - 1);
return \"{rlimi|rlwimi} %0,%3,%h5,%h2,%h1\";
-}")
+}"
+ [(set_attr "type" "insert_word")])
(define_insn "insvdi"
[(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
@@ -3941,7 +3226,7 @@
(match_operand:SI 3 "const_int_operand" "i"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"*
{
int start = INTVAL (operands[3]) & 63;
@@ -3963,7 +3248,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"*
{
int start = INTVAL (operands[3]) & 63;
@@ -4336,7 +3621,7 @@
(match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=r,r"))]
- "! TARGET_POWER && ! TARGET_POWERPC64"
+ "! TARGET_POWER && TARGET_32BIT"
"@
{sl|slw}%I2. %3,%1,%h2
#"
@@ -4349,7 +3634,7 @@
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed"
+ "! TARGET_POWER && TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(ashift:SI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
@@ -4398,7 +3683,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(ashift:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWER && ! TARGET_POWERPC64"
+ "! TARGET_POWER && TARGET_32BIT"
"@
{sl|slw}%I2. %0,%1,%h2
#"
@@ -4412,7 +3697,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(ashift:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed"
+ "! TARGET_POWER && TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(ashift:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -4569,7 +3854,7 @@
(match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=X,r,X,r"))]
- "! TARGET_POWER && ! TARGET_POWERPC64"
+ "! TARGET_POWER && TARGET_32BIT"
"@
mr. %1,%1
{sr|srw}%I2. %3,%1,%h2
@@ -4584,7 +3869,7 @@
(match_operand:SI 2 "reg_or_cint_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed"
+ "! TARGET_POWER && TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(lshiftrt:SI (match_dup 1) (match_dup 2)))
(set (match_dup 0)
@@ -4635,7 +3920,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(lshiftrt:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWER && ! TARGET_POWERPC64"
+ "! TARGET_POWER && TARGET_32BIT"
"@
mr. %0,%1
{sr|srw}%I2. %0,%1,%h2
@@ -4651,7 +3936,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(lshiftrt:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWER && ! TARGET_POWERPC64 && reload_completed"
+ "! TARGET_POWER && TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(lshiftrt:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -5109,7 +4394,7 @@
(define_insn "aux_truncdfsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
- (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] 0))]
+ (unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRSP))]
"! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
"frsp %0,%1"
[(set_attr "type" "fp")])
@@ -5678,9 +4963,9 @@
;; Conversions to and from floating-point.
-(define_expand "fixunssfsi2"
+(define_expand "fixuns_truncsfsi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
- (unsigned_fix:SI (fix:SF (match_operand:SF 1 "gpc_reg_operand" ""))))]
+ (unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
"TARGET_HARD_FLOAT && !TARGET_FPRS"
"")
@@ -5728,8 +5013,8 @@
(use (match_operand:SI 2 "gpc_reg_operand" "r"))
(use (match_operand:DF 3 "gpc_reg_operand" "f"))
(clobber (match_operand:DF 4 "memory_operand" "=o"))
- (clobber (match_operand:DF 5 "gpc_reg_operand" "=f"))
- (clobber (match_operand:SI 6 "gpc_reg_operand" "=r"))]
+ (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))
+ (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
"#"
[(set_attr "length" "24")])
@@ -5810,7 +5095,7 @@
(use (match_operand:SI 2 "gpc_reg_operand" "r"))
(use (match_operand:DF 3 "gpc_reg_operand" "f"))
(clobber (match_operand:DF 4 "memory_operand" "=o"))
- (clobber (match_operand:DF 5 "gpc_reg_operand" "=f"))]
+ (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
"#"
[(set_attr "length" "20")])
@@ -5895,13 +5180,14 @@
DONE;
}")
-; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] 10))
+; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
; rather than (set (subreg:SI (reg)) (fix:SI ...))
; because the first makes it clear that operand 0 is not live
; before the instruction.
(define_insn "fctiwz"
[(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
- (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))] 10))]
+ (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))]
+ UNSPEC_FCTIWZ))]
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
"{fcirz|fctiwz} %0,%1"
[(set_attr "type" "fp")])
@@ -5927,7 +5213,7 @@
(clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
"#"
- ""
+ "&& 1"
[(set (match_dup 3) (sign_extend:DI (match_dup 1)))
(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 2))
@@ -5942,7 +5228,7 @@
(clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
"#"
- ""
+ "&& 1"
[(set (match_dup 3) (zero_extend:DI (match_dup 1)))
(set (match_dup 2) (match_dup 3))
(set (match_dup 4) (match_dup 2))
@@ -5959,7 +5245,7 @@
(define_expand "floatdisf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "")
(float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
- "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_FPRS"
"
{
if (!flag_unsafe_math_optimizations)
@@ -5989,7 +5275,7 @@
"")
;; Twiddles bits to avoid double rounding.
-;; Bits that might be trucated when converting to DFmode are replaced
+;; Bits that might be truncated when converting to DFmode are replaced
;; by a bit that won't be lost at that stage, but is below the SFmode
;; rounding position.
(define_expand "floatdisf2_internal2"
@@ -6010,7 +5296,7 @@
(pc)))
(set (match_dup 0) (xor:DI (match_dup 0) (match_dup 2)))
(set (match_dup 0) (ior:DI (match_dup 0) (const_int 2048)))]
- "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_FPRS"
"
{
operands[2] = gen_reg_rtx (DImode);
@@ -6350,11 +5636,26 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "const_int_operand" "M,i")))]
- "TARGET_32BIT && !TARGET_POWER"
+ "TARGET_32BIT && !TARGET_POWERPC64 && !TARGET_POWER && WORDS_BIG_ENDIAN"
"@
{srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
{sri|srwi} %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;{srai|srawi} %0,%1,%h2"
[(set_attr "length" "8,12")])
+
+(define_insn "*ashrdisi3_noppc64"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
+ (const_int 32)) 4))]
+ "TARGET_32BIT && !TARGET_POWERPC64"
+ "*
+{
+ if (REGNO (operands[0]) == REGNO (operands[1]))
+ return \"\";
+ else
+ return \"mr %0,%1\";
+}"
+ [(set_attr "length" "4")])
+
;; PowerPC64 DImode operations.
@@ -6413,13 +5714,13 @@
(match_operand:DI 2 "reg_or_short_operand" "r,I,r,I"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
add. %3,%1,%2
addic. %3,%1,%2
#
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
@@ -6443,13 +5744,13 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(plus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
add. %0,%1,%2
addic. %0,%1,%2
#
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare,compare,compare,compare")
(set_attr "length" "4,4,8,8")])
(define_split
@@ -6509,7 +5810,7 @@
(compare:CC (not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
nor. %2,%1,%1
#"
@@ -6535,7 +5836,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(not:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
nor. %0,%1,%1
#"
@@ -6571,11 +5872,11 @@
(match_operand:DI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subf. %3,%2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -6599,11 +5900,11 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(minus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subf. %0,%2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -6677,11 +5978,11 @@
(compare:CC (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 2 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
neg. %2,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -6703,11 +6004,11 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(neg:DI (match_dup 1)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
neg. %0,%1
#"
- [(set_attr "type" "compare")
+ [(set_attr "type" "fast_compare")
(set_attr "length" "4,8")])
(define_split
@@ -6724,12 +6025,43 @@
(const_int 0)))]
"")
-(define_insn "ffsdi2"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
- (ffs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
+(define_insn "clzdi2"
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (clz:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
"TARGET_POWERPC64"
- "neg %0,%1\;and %0,%0,%1\;cntlzd %0,%0\;subfic %0,%0,64"
- [(set_attr "length" "16")])
+ "cntlzd %0,%1")
+
+(define_expand "ctzdi2"
+ [(set (match_dup 2)
+ (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
+ (parallel [(set (match_dup 3) (and:DI (match_dup 1)
+ (match_dup 2)))
+ (clobber (scratch:CC))])
+ (set (match_dup 4) (clz:DI (match_dup 3)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (minus:DI (const_int 63) (match_dup 4)))]
+ "TARGET_POWERPC64"
+ {
+ operands[2] = gen_reg_rtx (DImode);
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ })
+
+(define_expand "ffsdi2"
+ [(set (match_dup 2)
+ (neg:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
+ (parallel [(set (match_dup 3) (and:DI (match_dup 1)
+ (match_dup 2)))
+ (clobber (scratch:CC))])
+ (set (match_dup 4) (clz:DI (match_dup 3)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r")
+ (minus:DI (const_int 64) (match_dup 4)))]
+ "TARGET_POWERPC64"
+ {
+ operands[2] = gen_reg_rtx (DImode);
+ operands[3] = gen_reg_rtx (DImode);
+ operands[4] = gen_reg_rtx (DImode);
+ })
(define_insn "muldi3"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
@@ -6739,6 +6071,62 @@
"mulld %0,%1,%2"
[(set_attr "type" "lmul")])
+(define_insn "*muldi3_internal1"
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
+ (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
+ (match_operand:DI 2 "gpc_reg_operand" "r,r"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 3 "=r,r"))]
+ "TARGET_POWERPC64"
+ "@
+ mulld. %3,%1,%2
+ #"
+ [(set_attr "type" "lmul_compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
+ (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
+ (match_operand:DI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (clobber (match_scratch:DI 3 ""))]
+ "TARGET_POWERPC64 && reload_completed"
+ [(set (match_dup 3)
+ (mult:DI (match_dup 1) (match_dup 2)))
+ (set (match_dup 0)
+ (compare:CC (match_dup 3)
+ (const_int 0)))]
+ "")
+
+(define_insn "*muldi3_internal2"
+ [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
+ (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
+ (match_operand:DI 2 "gpc_reg_operand" "r,r"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
+ (mult:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_POWERPC64"
+ "@
+ mulld. %0,%1,%2
+ #"
+ [(set_attr "type" "lmul_compare")
+ (set_attr "length" "4,8")])
+
+(define_split
+ [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
+ (compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
+ (match_operand:DI 2 "gpc_reg_operand" ""))
+ (const_int 0)))
+ (set (match_operand:DI 0 "gpc_reg_operand" "")
+ (mult:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_POWERPC64 && reload_completed"
+ [(set (match_dup 0)
+ (mult:DI (match_dup 1) (match_dup 2)))
+ (set (match_dup 3)
+ (compare:CC (match_dup 0)
+ (const_int 0)))]
+ "")
+
(define_insn "smuldi3_highpart"
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(truncate:DI
@@ -6817,7 +6205,7 @@
(match_operand:DI 2 "exact_log2_cint_operand" "N,N"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
sradi %3,%1,%p2\;addze. %3,%3
#"
@@ -6845,7 +6233,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(div:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
sradi %0,%1,%p2\;addze. %0,%0
#"
@@ -6896,7 +6284,7 @@
(match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %3,%1,%H2,0
#"
@@ -6924,7 +6312,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(rotate:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %0,%1,%H2,0
#"
@@ -6962,7 +6350,7 @@
(match_operand:DI 3 "mask64_operand" "n,n"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2c%B3. %4,%1,%H2,%S3
#"
@@ -6996,7 +6384,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2c%B3. %0,%1,%H2,%S3
#"
@@ -7037,7 +6425,7 @@
(match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %3,%1,%H2,56
#"
@@ -7071,7 +6459,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %0,%1,%H2,56
#"
@@ -7112,7 +6500,7 @@
(match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %3,%1,%H2,48
#"
@@ -7146,7 +6534,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %0,%1,%H2,48
#"
@@ -7187,7 +6575,7 @@
(match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %3,%1,%H2,32
#"
@@ -7221,7 +6609,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
rld%I2cl. %0,%1,%H2,32
#"
@@ -7277,7 +6665,7 @@
(match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
sld%I2. %3,%1,%H2
#"
@@ -7305,7 +6693,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(ashift:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
sld%I2. %0,%1,%H2
#"
@@ -7343,7 +6731,7 @@
(match_operand:DI 3 "const_int_operand" "n,n"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r,r"))]
- "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
+ "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
"@
rldic. %4,%1,%H2,%W3
#"
@@ -7377,7 +6765,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
+ "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
"@
rldic. %0,%1,%H2,%W3
#"
@@ -7419,7 +6807,7 @@
(match_operand:DI 3 "mask64_operand" "n,n"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=r,r"))]
- "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
+ "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
"@
rldicr. %4,%1,%H2,%S3
#"
@@ -7453,7 +6841,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
+ "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
"@
rldicr. %0,%1,%H2,%S3
#"
@@ -7510,7 +6898,7 @@
(match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT "
"@
srd%I2. %3,%1,%H2
#"
@@ -7538,7 +6926,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(lshiftrt:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
srd%I2. %0,%1,%H2
#"
@@ -7564,7 +6952,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "reg_or_cint_operand" "")))]
- ""
+ "WORDS_BIG_ENDIAN"
"
{
if (TARGET_POWERPC64)
@@ -7574,7 +6962,8 @@
emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2]));
DONE;
}
- else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT)
+ else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT
+ && WORDS_BIG_ENDIAN)
{
emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2]));
DONE;
@@ -7596,7 +6985,7 @@
(match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
srad%I2. %3,%1,%H2
#"
@@ -7624,7 +7013,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
srad%I2. %0,%1,%H2
#"
@@ -7688,7 +7077,7 @@
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r,r,r"))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,x,x,X"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
and. %3,%1,%2
rldic%B2. %3,%1,0,%S2
@@ -7753,7 +7142,7 @@
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r")
(and:DI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,x,x,X"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
and. %0,%1,%2
rldic%B2. %0,%1,0,%S2
@@ -7898,7 +7287,7 @@
(match_operand:DI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
%q4. %3,%1,%2
#"
@@ -7927,7 +7316,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
%q4. %0,%1,%2
#"
@@ -7949,7 +7338,7 @@
(const_int 0)))]
"")
-;; Split an logical operation that we can't do in one insn into two insns,
+;; Split a logical operation that we can't do in one insn into two insns,
;; each of which does one 16-bit part. This is used by combine.
(define_split
@@ -7998,7 +7387,7 @@
(match_operand:DI 2 "gpc_reg_operand" "r,r")])
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
%q4. %3,%2,%1
#"
@@ -8027,7 +7416,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
%q4. %0,%2,%1
#"
@@ -8064,7 +7453,7 @@
(not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))])
(const_int 0)))
(clobber (match_scratch:DI 3 "=r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
%q4. %3,%1,%2
#"
@@ -8093,7 +7482,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(match_dup 4))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
%q4. %0,%1,%2
#"
@@ -8157,7 +7546,7 @@
(define_expand "movsi_got"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(unspec:SI [(match_operand:SI 1 "got_operand" "")
- (match_dup 2)] 8))]
+ (match_dup 2)] UNSPEC_MOVSI_GOT))]
"DEFAULT_ABI == ABI_V4 && flag_pic == 1"
"
{
@@ -8183,7 +7572,8 @@
(define_insn "*movsi_got_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
- (match_operand:SI 2 "gpc_reg_operand" "b")] 8))]
+ (match_operand:SI 2 "gpc_reg_operand" "b")]
+ UNSPEC_MOVSI_GOT))]
"DEFAULT_ABI == ABI_V4 && flag_pic == 1"
"{l|lwz} %0,%a1@got(%2)"
[(set_attr "type" "load")])
@@ -8193,12 +7583,14 @@
(define_split
[(set (match_operand:SI 0 "gpc_reg_operand" "")
(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
- (match_operand:SI 2 "memory_operand" "")] 8))]
+ (match_operand:SI 2 "memory_operand" "")]
+ UNSPEC_MOVSI_GOT))]
"DEFAULT_ABI == ABI_V4
&& flag_pic == 1
&& (reload_in_progress || reload_completed)"
[(set (match_dup 0) (match_dup 2))
- (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)] 8))]
+ (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
+ UNSPEC_MOVSI_GOT))]
"")
;; For SI, we special-case integers that can't be loaded in one insn. We
@@ -8246,12 +7638,23 @@
operands2[0] = operands[0];
operands2[1] = operands[1];
operands2[2] = operands[2];
- operands2[3] = gen_rtx_REG (SImode, RS6000_PIC_OFFSET_TABLE_REGNUM);
- output_asm_insn (\"{l|lwz} %0,lo16(%2)(%1)\", operands);
- /* We cannot rely on ha16(low half)==ha16(high half), alas,
- although in practice it almost always is. */
- output_asm_insn (\"{cau|addis} %L0,%3,ha16(%2+4)\", operands2);
- return (\"{l|lwz} %L0,lo16(%2+4)(%L0)\");
+ if (TARGET_POWERPC64 && TARGET_32BIT)
+ /* Note, old assemblers didn't support relocation here. */
+ return \"ld %0,lo16(%2)(%1)\";
+ else
+ {
+ operands2[3] = gen_rtx_REG (SImode, RS6000_PIC_OFFSET_TABLE_REGNUM);
+ output_asm_insn (\"{l|lwz} %0,lo16(%2)(%1)\", operands);
+#if TARGET_MACHO
+ if (MACHO_DYNAMIC_NO_PIC_P)
+ output_asm_insn (\"{liu|lis} %L0,ha16(%2+4)\", operands);
+ else
+ /* We cannot rely on ha16(low half)==ha16(high half), alas,
+ although in practice it almost always is. */
+ output_asm_insn (\"{cau|addis} %L0,%3,ha16(%2+4)\", operands2);
+#endif
+ return (\"{l|lwz} %L0,lo16(%2+4)(%L0)\");
+ }
}
default:
abort();
@@ -8310,7 +7713,7 @@
mt%0 %1
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,*,load,store,*,*,*,*,*,*,mtjmpr,*,*")
+ [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*")
(set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
;; Split a load of a large constant into the appropriate two-insn
@@ -8336,29 +7739,30 @@
}")
(define_insn "*movsi_internal2"
- [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
- (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r,r")
+ [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
+ (compare:CC (match_operand:SI 1 "gpc_reg_operand" "0,r,r")
(const_int 0)))
- (set (match_operand:SI 0 "gpc_reg_operand" "=r,r") (match_dup 1))]
- "! TARGET_POWERPC64"
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
+ "TARGET_32BIT"
"@
+ {cmpi|cmpwi} %2,%0,0
mr. %0,%1
#"
- [(set_attr "type" "compare")
- (set_attr "length" "4,8")])
-
+ [(set_attr "type" "cmp,compare,cmp")
+ (set_attr "length" "4,4,8")])
+
(define_split
[(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
(compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "") (match_dup 1))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0) (match_dup 1))
(set (match_dup 2)
(compare:CC (match_dup 0)
(const_int 0)))]
"")
-
+
(define_expand "movhi"
[(set (match_operand:HI 0 "general_operand" "")
(match_operand:HI 1 "any_operand" ""))]
@@ -8379,7 +7783,7 @@
mt%0 %1
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
+ [(set_attr "type" "*,load,store,*,mfjmpr,*,mtjmpr,*")])
(define_expand "movqi"
[(set (match_operand:QI 0 "general_operand" "")
@@ -8401,7 +7805,7 @@
mt%0 %1
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,load,store,*,*,*,mtjmpr,*")])
+ [(set_attr "type" "*,load,store,*,mfjmpr,*,mtjmpr,*")])
;; Here is how to move condition codes around. When we store CC data in
;; an integer register or memory, we store just the high-order 4 bits.
@@ -8413,23 +7817,41 @@
"")
(define_insn "*movcc_internal1"
- [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,y,r,r,r,cl,q,r,r,m")
- (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,r,r,h,m,r"))]
+ [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,r,r,r,r,q,cl,r,m")
+ (match_operand:CC 1 "nonimmediate_operand" "y,r,r,x,y,r,h,r,r,m,r"))]
"register_operand (operands[0], CCmode)
|| register_operand (operands[1], CCmode)"
"@
mcrf %0,%1
mtcrf 128,%1
{rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
- mfcr %0
- mfcr %0\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
+ mfcr %0%Q1
+ mfcr %0%Q1\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
mr %0,%1
+ mf%1 %0
mt%0 %1
mt%0 %1
- mf%1 %0
{l%U1%X1|lwz%U1%X1} %0,%1
{st%U0%U1|stw%U0%U1} %1,%0"
- [(set_attr "type" "cr_logical,cr_logical,cr_logical,cr_logical,cr_logical,*,*,mtjmpr,*,load,store")
+ [(set (attr "type")
+ (cond [(eq_attr "alternative" "0")
+ (const_string "cr_logical")
+ (eq_attr "alternative" "1,2")
+ (const_string "mtcr")
+ (eq_attr "alternative" "5,7")
+ (const_string "integer")
+ (eq_attr "alternative" "6")
+ (const_string "mfjmpr")
+ (eq_attr "alternative" "8")
+ (const_string "mtjmpr")
+ (eq_attr "alternative" "9")
+ (const_string "load")
+ (eq_attr "alternative" "10")
+ (const_string "store")
+ (ne (symbol_ref "TARGET_MFCRF") (const_int 0))
+ (const_string "mfcrf")
+ ]
+ (const_string "mfcr")))
(set_attr "length" "4,4,12,4,8,4,4,4,4,4,4")])
;; For floating-point, we normally deal with the floating-point registers
@@ -8490,8 +7912,8 @@
(set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")])
(define_insn "*movsf_softfloat"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r")
- (match_operand:SF 1 "input_operand" "r,r,r,h,m,r,I,L,R,G,Fn"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r,*h")
+ (match_operand:SF 1 "input_operand" "r,r,r,h,m,r,I,L,R,G,Fn,0"))]
"(gpc_reg_operand (operands[0], SFmode)
|| gpc_reg_operand (operands[1], SFmode))
&& (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
@@ -8506,9 +7928,10 @@
{liu|lis} %0,%v1
{cal|la} %0,%a1
#
- #"
- [(set_attr "type" "*,mtjmpr,*,*,load,store,*,*,*,*,*")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8")])
+ #
+ {cror 0,0,0|nop}"
+ [(set_attr "type" "*,mtjmpr,*,*,load,store,*,*,*,*,*,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8,4")])
(define_expand "movdf"
@@ -8581,7 +8004,9 @@
int endian = (WORDS_BIG_ENDIAN == 0);
long l[2];
REAL_VALUE_TYPE rv;
+#if HOST_BITS_PER_WIDE_INT >= 64
HOST_WIDE_INT val;
+#endif
REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
@@ -8738,16 +8163,19 @@
[(set_attr "type" "*,load,store,*,*,*")
(set_attr "length" "8,8,8,8,12,16")])
+; ld/std require word-aligned displacements -> 'Y' constraint.
+; List Y->r and r->Y before r->r for reload.
(define_insn "*movdf_hardfloat64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!cl,!r,!r,!r,!r")
- (match_operand:DF 1 "input_operand" "r,m,r,f,m,f,r,h,G,H,F"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,b,!r,f,f,m,!cl,!r,!r,!r,!r")
+ (match_operand:DF 1 "input_operand" "r,Y,m,r,f,m,f,r,h,G,H,F"))]
"TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
"@
- mr %0,%1
- ld%U1%X1 %0,%1
std%U0%X0 %1,%0
+ ld%U1%X1 %0,%1
+ #
+ mr %0,%1
fmr %0,%1
lfd%U1%X1 %0,%1
stfd%U0%X0 %1,%0
@@ -8756,180 +8184,148 @@
#
#
#"
- [(set_attr "type" "*,load,store,fp,fpload,fpstore,mtjmpr,*,*,*,*")
- (set_attr "length" "4,4,4,4,4,4,4,4,8,12,16")])
+ [(set_attr "type" "store,load,load,*,fp,fpload,fpstore,mtjmpr,*,*,*,*")
+ (set_attr "length" "4,4,8,4,4,4,4,4,4,8,12,16")])
+
+(define_split
+ [(set (match_operand:DF 0 "base_reg_operand" "")
+ (match_operand:DF 1 "invalid_gpr_mem" ""))]
+ "TARGET_POWERPC64 && no_new_pseudos"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0) (match_dup 4))]
+ "
+{
+ operands[2] = gen_rtx_REG (Pmode, REGNO (operands[0]));
+ operands[3] = XEXP (operands[1], 0);
+ operands[4] = replace_equiv_address (operands[1], operands[2]);
+}")
+
+(define_expand "reload_outdf"
+ [(parallel [(match_operand:DF 0 "invalid_gpr_mem" "")
+ (match_operand:DF 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "=&b")])]
+ "TARGET_POWERPC64"
+{
+ if (!TARGET_64BIT)
+ operands[2] = gen_rtx_REG (SImode, REGNO (operands[2]));
+ emit_move_insn (operands[2], XEXP (operands[0], 0));
+ operands[0] = replace_equiv_address (operands[0], operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+})
+
+(define_expand "reload_indf"
+ [(parallel [(match_operand:DF 0 "register_operand" "")
+ (match_operand:DF 1 "invalid_gpr_mem" "")
+ (match_operand:DI 2 "register_operand" "=&b")])]
+ "TARGET_POWERPC64"
+{
+ if (!TARGET_64BIT)
+ operands[2] = gen_rtx_REG (SImode, REGNO (operands[2]));
+ emit_move_insn (operands[2], XEXP (operands[1], 0));
+ operands[1] = replace_equiv_address (operands[1], operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+})
(define_insn "*movdf_softfloat64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r")
- (match_operand:DF 1 "input_operand" "r,r,h,m,r,G,H,F"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h")
+ (match_operand:DF 1 "input_operand" "Y,r,r,r,h,G,H,F,0"))]
"TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
&& (gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode))"
"@
+ ld%U1%X1 %0,%1
+ std%U0%X0 %1,%0
mr %0,%1
mt%0 %1
mf%1 %0
- ld%U1%X1 %0,%1
- std%U0%X0 %1,%0
#
#
- #"
- [(set_attr "type" "*,*,*,load,store,*,*,*")
- (set_attr "length" "4,4,4,4,4,8,12,16")])
+ #
+ nop"
+ [(set_attr "type" "load,store,*,*,*,*,*,*,*")
+ (set_attr "length" "4,4,4,4,4,8,12,16,4")])
(define_expand "movtf"
[(set (match_operand:TF 0 "general_operand" "")
(match_operand:TF 1 "any_operand" ""))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }")
-(define_insn "*movtf_internal"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,m,!r,!r,!r")
- (match_operand:TF 1 "input_operand" "f,m,f,G,H,F"))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128
+; It's important to list the o->f and f->o moves before f->f because
+; otherwise reload, given m->f, will try to pick f->f and reload it,
+; which doesn't make progress.
+(define_insn_and_split "*movtf_internal"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,rm,r")
+ (match_operand:TF 1 "input_operand" "f,o,f,r,mGHF"))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
&& (gpc_reg_operand (operands[0], TFmode)
|| gpc_reg_operand (operands[1], TFmode))"
- "*
-{
- switch (which_alternative)
- {
- default:
- abort ();
- 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[1]) + 1)
- return \"fmr %L0,%L1\;fmr %0,%1\";
- else
- return \"fmr %0,%1\;fmr %L0,%L1\";
- case 1:
- return \"lfd %0,%1\;lfd %L0,%Y1\";
- case 2:
- return \"stfd %1,%0\;stfd %L1,%Y0\";
- case 3:
- case 4:
- case 5:
- return \"#\";
- }
-}"
- [(set_attr "type" "fp,fpload,fpstore,*,*,*")
- (set_attr "length" "8,8,8,12,16,20")])
-
-(define_split
- [(set (match_operand:TF 0 "gpc_reg_operand" "")
- (match_operand:TF 1 "easy_fp_constant" ""))]
+ "#"
+ "&& reload_completed"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
+ [(set_attr "length" "8,8,8,20,20")])
+
+(define_expand "extenddftf2"
+ [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (float_extend:TF (match_operand:DF 1 "input_operand" "")))
+ (use (match_dup 2))])]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
- && TARGET_HARD_FLOAT && TARGET_FPRS && ! TARGET_POWERPC64
- && TARGET_LONG_DOUBLE_128 && reload_completed
- && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
- || (GET_CODE (operands[0]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[0])) == REG
- && REGNO (SUBREG_REG (operands[0])) <= 31))"
- [(set (match_dup 2) (match_dup 6))
- (set (match_dup 3) (match_dup 7))
- (set (match_dup 4) (match_dup 8))
- (set (match_dup 5) (match_dup 9))]
- "
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
{
- long l[4];
- REAL_VALUE_TYPE rv;
+ operands[2] = CONST0_RTX (DFmode);
+})
- REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
-
- operands[2] = operand_subword (operands[0], 0, 0, TFmode);
- operands[3] = operand_subword (operands[0], 1, 0, TFmode);
- operands[4] = operand_subword (operands[0], 2, 0, TFmode);
- operands[5] = operand_subword (operands[0], 3, 0, TFmode);
- operands[6] = gen_int_mode (l[0], SImode);
- operands[7] = gen_int_mode (l[1], SImode);
- operands[8] = gen_int_mode (l[2], SImode);
- operands[9] = gen_int_mode (l[3], SImode);
-}")
-
-(define_split
- [(set (match_operand:TF 0 "gpc_reg_operand" "")
- (match_operand:TF 1 "easy_fp_constant" ""))]
+(define_insn_and_split "*extenddftf2_internal"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,&f,r")
+ (float_extend:TF (match_operand:DF 1 "input_operand" "fr,mf,mf,rmGHF")))
+ (use (match_operand:DF 2 "input_operand" "rf,m,f,n"))]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
- && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64
- && TARGET_LONG_DOUBLE_128 && reload_completed
- && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
- || (GET_CODE (operands[0]) == SUBREG
- && GET_CODE (SUBREG_REG (operands[0])) == REG
- && REGNO (SUBREG_REG (operands[0])) <= 31))"
- [(set (match_dup 2) (match_dup 4))
- (set (match_dup 3) (match_dup 5))]
- "
-{
- long l[4];
- REAL_VALUE_TYPE rv;
- HOST_WIDE_INT val;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, l);
-
- operands[2] = gen_lowpart (DImode, operands[0]);
- operands[3] = gen_highpart (DImode, operands[0]);
-#if HOST_BITS_PER_WIDE_INT >= 64
- val = ((HOST_WIDE_INT)(unsigned long)l[0] << 32
- | ((HOST_WIDE_INT)(unsigned long)l[1]));
- operands[4] = gen_int_mode (val, DImode);
-
- val = ((HOST_WIDE_INT)(unsigned long)l[2] << 32
- | ((HOST_WIDE_INT)(unsigned long)l[3]));
- operands[5] = gen_int_mode (val, DImode);
-#else
- operands[4] = immed_double_const (l[1], l[0], DImode);
- operands[5] = immed_double_const (l[3], l[2], DImode);
-#endif
-}")
-
-(define_insn "extenddftf2"
- [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (float_extend:TF (match_operand:DF 1 "gpc_reg_operand" "f")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- "*
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "#"
+ "&& reload_completed"
+ [(pc)]
{
- if (REGNO (operands[0]) == REGNO (operands[1]))
- return \"fsub %L0,%L0,%L0\";
- else
- return \"fmr %0,%1\;fsub %L0,%L0,%L0\";
-}"
- [(set_attr "type" "fp")])
+ const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
+ const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
+ emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word),
+ operands[1]);
+ emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word),
+ operands[2]);
+ DONE;
+})
-(define_insn "extendsftf2"
- [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "f")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- "*
+(define_expand "extendsftf2"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
{
- if (REGNO (operands[0]) == REGNO (operands[1]))
- return \"fsub %L0,%L0,%L0\";
- else
- return \"fmr %0,%1\;fsub %L0,%L0,%L0\";
-}"
- [(set_attr "type" "fp")])
+ rtx tmp = gen_reg_rtx (DFmode);
+ emit_insn (gen_extendsfdf2 (tmp, operands[1]));
+ emit_insn (gen_extenddftf2 (operands[0], tmp));
+ DONE;
+})
(define_insn "trunctfdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"fadd %0,%1,%L1"
[(set_attr "type" "fp")
- (set_attr "length" "8")])
+ (set_attr "length" "4")])
(define_insn_and_split "trunctfsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
(float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f")))
(clobber (match_scratch:DF 2 "=f"))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT
- && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"#"
"&& reload_completed"
[(set (match_dup 2)
@@ -8938,67 +8334,80 @@
(float_truncate:SF (match_dup 2)))]
"")
-(define_insn_and_split "floatditf2"
+(define_expand "floatsitf2"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (float:TF (match_operand:DI 1 "gpc_reg_operand" "*f")))
- (clobber (match_scratch:DF 2 "=f"))]
- "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64
+ (float:TF (match_operand:SI 1 "gpc_reg_operand" "r")))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
- "#"
- "&& reload_completed"
- [(set (match_dup 2)
- (float:DF (match_dup 1)))
- (set (match_dup 0)
- (float_extend:TF (match_dup 2)))]
- "")
+{
+ rtx tmp = gen_reg_rtx (DFmode);
+ expand_float (tmp, operands[1], false);
+ emit_insn (gen_extenddftf2 (operands[0], tmp));
+ DONE;
+})
-(define_insn_and_split "floatsitf2"
- [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (float:TF (match_operand:SI 1 "gpc_reg_operand" "r")))
- (clobber (match_scratch:DF 2 "=f"))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- "#"
- "&& reload_completed"
- [(set (match_dup 2)
- (float:DF (match_dup 1)))
- (set (match_dup 0)
- (float_extend:TF (match_dup 2)))]
- "")
+; fadd, but rounding towards zero.
+; This is probably not the optimal code sequence.
+(define_insn "fix_trunc_helper"
+ [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
+ (unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")]
+ UNSPEC_FIX_TRUNC_TF))
+ (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS"
+ "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
+ [(set_attr "type" "fp")
+ (set_attr "length" "20")])
-(define_insn_and_split "fix_trunctfdi2"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
- (fix:DI (match_operand:TF 1 "gpc_reg_operand" "f")))
- (clobber (match_scratch:DF 2 "=f"))]
- "DEFAULT_ABI == ABI_AIX && TARGET_POWERPC64
+(define_expand "fix_trunctfsi2"
+ [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
+ (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (clobber (match_dup 4))
+ (clobber (match_dup 5))])]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && (TARGET_POWER2 || TARGET_POWERPC)
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
- "#"
- "&& reload_completed"
- [(set (match_dup 2)
- (float_truncate:DF (match_dup 1)))
- (set (match_dup 0)
- (fix:DI (match_dup 2)))]
- "")
+{
+ operands[2] = gen_reg_rtx (DFmode);
+ operands[3] = gen_reg_rtx (DFmode);
+ operands[4] = gen_reg_rtx (DImode);
+ operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
+})
-(define_insn_and_split "fix_trunctfsi2"
+(define_insn_and_split "*fix_trunctfsi2_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))
- (clobber (match_scratch:DF 2 "=f"))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
+ (clobber (match_operand:DF 2 "gpc_reg_operand" "=f"))
+ (clobber (match_operand:DF 3 "gpc_reg_operand" "=&f"))
+ (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))
+ (clobber (match_operand:DI 5 "memory_operand" "=o"))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"#"
"&& reload_completed"
- [(set (match_dup 2)
- (float_truncate:DF (match_dup 1)))
- (set (match_dup 0)
- (fix:SI (match_dup 2)))]
- "")
+ [(pc)]
+{
+ rtx lowword;
+ emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
+
+ if (GET_CODE (operands[5]) != MEM)
+ abort();
+ lowword = XEXP (operands[5], 0);
+ if (WORDS_BIG_ENDIAN)
+ lowword = plus_constant (lowword, 4);
+
+ emit_insn (gen_fctiwz (operands[4], operands[2]));
+ emit_move_insn (operands[5], operands[4]);
+ emit_move_insn (operands[0], gen_rtx_MEM (SImode, lowword));
+ DONE;
+})
(define_insn "negtf2"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
(neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"*
{
if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
@@ -9009,35 +8418,40 @@
[(set_attr "type" "fp")
(set_attr "length" "8")])
-(define_insn "abstf2"
+(define_expand "abstf2"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
(abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- "*
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "
{
- if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
- return \"fabs %L0,%L1\;fabs %0,%1\";
- else
- return \"fabs %0,%1\;fabs %L0,%L1\";
-}"
- [(set_attr "type" "fp")
- (set_attr "length" "8")])
+ rtx label = gen_label_rtx ();
+ emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
+ emit_label (label);
+ DONE;
+}")
-(define_insn ""
+(define_expand "abstf2_internal"
[(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (neg:TF (abs:TF (match_operand:TF 1 "gpc_reg_operand" "f"))))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- "*
+ (match_operand:TF 1 "gpc_reg_operand" "f"))
+ (set (match_dup 3) (match_dup 5))
+ (set (match_dup 5) (abs:DF (match_dup 5)))
+ (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
+ (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
+ (label_ref (match_operand 2 "" ""))
+ (pc)))
+ (set (match_dup 6) (neg:DF (match_dup 6)))]
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "
{
- if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
- return \"fnabs %L0,%L1\;fnabs %0,%1\";
- else
- return \"fnabs %0,%1\;fnabs %L0,%L1\";
-}"
- [(set_attr "type" "fp")
- (set_attr "length" "8")])
+ const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
+ const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
+ operands[3] = gen_reg_rtx (DFmode);
+ operands[4] = gen_reg_rtx (CCFPmode);
+ operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
+ operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
+}")
;; Next come the multi-word integer load and store and the load and store
;; multiple insns.
@@ -9060,25 +8474,9 @@
default:
abort ();
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[1]) + 1)
- return \"mr %L0,%L1\;mr %0,%1\";
- else
- return \"mr %0,%1\;mr %L0,%L1\";
case 1:
- /* If the low-address word is used in the address, we must load it
- last. Otherwise, load it first. Note that we cannot have
- auto-increment in that case since the address register is known to be
- dead. */
- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands[1], 0))
- return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
- else
- return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
case 2:
- return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
+ return \"#\";
case 3:
return \"fmr %0,%1\";
case 4:
@@ -9093,8 +8491,7 @@
return \"#\";
}
}"
- [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*")
- (set_attr "length" "8,8,8,4,4,4,8,12,8,12,16")])
+ [(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*")])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
@@ -9118,20 +8515,12 @@
}")
(define_split
- [(set (match_operand:DI 0 "gpc_reg_operand" "")
- (match_operand:DI 1 "const_double_operand" ""))]
- "HOST_BITS_PER_WIDE_INT == 32 && ! TARGET_POWERPC64 && reload_completed"
- [(set (match_dup 2) (match_dup 4))
- (set (match_dup 3) (match_dup 5))]
- "
-{
- operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
- DImode);
- operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
- DImode);
- operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
- operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
-}")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (match_operand:DI 1 "input_operand" ""))]
+ "reload_completed && !TARGET_POWERPC64
+ && gpr_or_gpr_p (operands[0], operands[1])"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
(define_split
[(set (match_operand:TI 0 "gpc_reg_operand" "")
@@ -9160,15 +8549,16 @@
}")
(define_insn "*movdi_internal64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,?f,f,m,r,*h,*h")
- (match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,b,r,r,r,r,r,??f,f,m,r,*h,*h")
+ (match_operand:DI 1 "input_operand" "r,Y,m,r,I,L,nF,R,f,m,f,*h,r,0"))]
"TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], DImode)
|| gpc_reg_operand (operands[1], DImode))"
"@
- mr %0,%1
- ld%U1%X1 %0,%1
std%U0%X0 %1,%0
+ ld%U1%X1 %0,%1
+ #
+ mr %0,%1
li %0,%1
lis %0,%v1
#
@@ -9179,8 +8569,51 @@
mf%1 %0
mt%0 %1
{cror 0,0,0|nop}"
- [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,*,mtjmpr,*")
- (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
+ [(set_attr "type" "store,load,load,*,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*")
+ (set_attr "length" "4,4,8,4,4,4,20,4,4,4,4,4,4,4")])
+
+(define_split
+ [(set (match_operand:DI 0 "base_reg_operand" "")
+ (match_operand:DI 1 "invalid_gpr_mem" ""))]
+ "TARGET_POWERPC64 && no_new_pseudos"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0) (match_dup 4))]
+ "
+{
+ operands[2] = operands[0];
+ if (!TARGET_64BIT)
+ operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));
+ operands[3] = XEXP (operands[1], 0);
+ operands[4] = replace_equiv_address (operands[1], operands[2]);
+}")
+
+(define_expand "reload_outdi"
+ [(parallel [(match_operand:DI 0 "invalid_gpr_mem" "")
+ (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "=&b")])]
+ "TARGET_POWERPC64"
+{
+ if (!TARGET_64BIT)
+ operands[2] = gen_rtx_REG (SImode, REGNO (operands[2]));
+ emit_move_insn (operands[2], XEXP (operands[0], 0));
+ operands[0] = replace_equiv_address (operands[0], operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+})
+
+(define_expand "reload_indi"
+ [(parallel [(match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "invalid_gpr_mem" "")
+ (match_operand:DI 2 "register_operand" "=&b")])]
+ "TARGET_POWERPC64"
+{
+ if (!TARGET_64BIT)
+ operands[2] = gen_rtx_REG (SImode, REGNO (operands[2]));
+ emit_move_insn (operands[2], XEXP (operands[1], 0));
+ operands[1] = replace_equiv_address (operands[1], operands[2]);
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+})
;; immediate value valid for a single instruction hiding in a const_double
(define_insn ""
@@ -9243,18 +8676,18 @@
FAIL;
}")
-;; Split a load of a large constant into the appropriate five-instruction
(define_insn "*movdi_internal2"
- [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
- (compare:CC (match_operand:DI 1 "gpc_reg_operand" "r,r")
+ [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
+ (compare:CC (match_operand:DI 1 "gpc_reg_operand" "0,r,r")
(const_int 0)))
- (set (match_operand:DI 0 "gpc_reg_operand" "=r,r") (match_dup 1))]
- "TARGET_POWERPC64"
+ (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
+ "TARGET_64BIT"
"@
+ cmpdi %2,%0,0
mr. %0,%1
#"
- [(set_attr "type" "compare")
- (set_attr "length" "4,8")])
+ [(set_attr "type" "cmp,compare,cmp")
+ (set_attr "length" "4,4,8")])
(define_split
[(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
@@ -9275,7 +8708,7 @@
[(parallel [(set (match_operand:TI 0 "general_operand" "")
(match_operand:TI 1 "general_operand" ""))
(clobber (scratch:SI))])]
- "TARGET_STRING || TARGET_POWERPC64"
+ ""
"{ rs6000_emit_move (operands[0], operands[1], TImode); DONE; }")
;; We say that MQ is clobbered in the last alternative because the first
@@ -9283,11 +8716,12 @@
;; while the 2nd alternative would not. We put memory cases first so they
;; are preferred. Otherwise, we'd try to reload the output instead of
;; giving the SCRATCH mq.
+
(define_insn "*movti_power"
[(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
(clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
- "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64
+ "TARGET_POWER && ! TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
"*
{
@@ -9297,50 +8731,28 @@
abort ();
case 0:
- return \"{stsi|stswi} %1,%P0,16\";
-
+ if (TARGET_STRING)
+ return \"{stsi|stswi} %1,%P0,16\";
case 1:
- return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
-
case 2:
- /* Normally copy registers with lowest numbered register copied first.
- But copy in the other order if the first register of the output
- is the second, third, or fourth register in the input. */
- if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
- && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
- return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
- else
- return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
+ return \"#\";
case 3:
/* If the address is not used in the output, we can use lsi. Otherwise,
fall through to generating four loads. */
- if (! reg_overlap_mentioned_p (operands[0], operands[1]))
+ if (TARGET_STRING
+ && ! reg_overlap_mentioned_p (operands[0], operands[1]))
return \"{lsi|lswi} %0,%P1,16\";
/* ... fall through ... */
case 4:
- /* If the address register is the same as the register for the lowest-
- addressed word, load it last. Similarly for the next two words.
- Otherwise load lowest address to highest. */
- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands[1], 0))
- return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
- else if (refers_to_regno_p (REGNO (operands[0]) + 1,
- REGNO (operands[0]) + 2, operands[1], 0))
- return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
- else if (refers_to_regno_p (REGNO (operands[0]) + 2,
- REGNO (operands[0]) + 3, operands[1], 0))
- return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
- else
- return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
+ return \"#\";
}
}"
- [(set_attr "type" "store,store,*,load,load")
- (set_attr "length" "4,16,16,4,16")])
+ [(set_attr "type" "store,store,*,load,load")])
(define_insn "*movti_string"
[(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))]
- "TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64
+ "! TARGET_POWER && ! TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
"*
{
@@ -9348,81 +8760,43 @@
{
default:
abort ();
-
case 0:
- return \"{stsi|stswi} %1,%P0,16\";
+ if (TARGET_STRING)
+ return \"{stsi|stswi} %1,%P0,16\";
case 1:
- return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
case 2:
- /* Normally copy registers with lowest numbered register copied first.
- But copy in the other order if the first register of the output
- is the second, third, or fourth register in the input. */
- if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
- && REGNO (operands[0]) <= REGNO (operands[1]) + 3)
- return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
- else
- return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
+ return \"#\";
case 3:
/* If the address is not used in the output, we can use lsi. Otherwise,
fall through to generating four loads. */
- if (! reg_overlap_mentioned_p (operands[0], operands[1]))
+ if (TARGET_STRING
+ && ! reg_overlap_mentioned_p (operands[0], operands[1]))
return \"{lsi|lswi} %0,%P1,16\";
/* ... fall through ... */
case 4:
- /* If the address register is the same as the register for the lowest-
- addressed word, load it last. Similarly for the next two words.
- Otherwise load lowest address to highest. */
- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands[1], 0))
- return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
- else if (refers_to_regno_p (REGNO (operands[0]) + 1,
- REGNO (operands[0]) + 2, operands[1], 0))
- return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
- else if (refers_to_regno_p (REGNO (operands[0]) + 2,
- REGNO (operands[0]) + 3, operands[1], 0))
- return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
- else
- return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
+ return \"#\";
}
}"
- [(set_attr "type" "store,store,*,load,load")
- (set_attr "length" "4,16,16,4,16")])
+ [(set_attr "type" "store,store,*,load,load")])
(define_insn "*movti_ppc64"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
- (match_operand:TI 1 "input_operand" "r,m,r"))]
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=r,m,r")
+ (match_operand:TI 1 "input_operand" "r,r,o"))]
"TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
|| gpc_reg_operand (operands[1], TImode))"
- "*
-{
- switch (which_alternative)
- {
- default:
- abort ();
- 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[1]) + 1)
- return \"mr %L0,%L1\;mr %0,%1\";
- else
- return \"mr %0,%1\;mr %L0,%L1\";
- case 1:
- /* If the low-address word is used in the address, we must load it
- last. Otherwise, load it first. Note that we cannot have
- auto-increment in that case since the address register is known to be
- dead. */
- if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands[1], 0))
- return \"ld %L0,%L1\;ld %0,%1\";
- else
- return \"ld%U1 %0,%1\;ld %L0,%L1\";
- case 2:
- return \"std%U0 %1,%0\;std %L1,%L0\";
- }
-}"
- [(set_attr "type" "*,load,store")
- (set_attr "length" "8,8,8")])
+ "@
+ #
+ #
+ #"
+ [(set_attr "type" "*,load,store")])
+
+(define_split
+ [(set (match_operand:TI 0 "nonimmediate_operand" "")
+ (match_operand:TI 1 "input_operand" ""))]
+ "reload_completed
+ && gpr_or_gpr_p (operands[0], operands[1])"
+ [(pc)]
+{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
(define_expand "load_multiple"
[(match_par_dup 3 [(set (match_operand:SI 0 "" "")
@@ -9627,15 +9001,113 @@
"{stsi|stswi} %2,%P1,%O0"
[(set_attr "type" "store")])
-(define_insn "*store_multiple_string"
+(define_insn "*stmsi8"
[(match_parallel 0 "store_multiple_operation"
- [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
- (match_operand:SI 2 "gpc_reg_operand" "r"))
- (clobber (match_scratch:SI 3 "X"))])]
- "TARGET_STRING && ! TARGET_POWER"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 7 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
+ (match_operand:SI 8 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
+ (match_operand:SI 9 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
+ (match_operand:SI 10 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 9"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
+
+(define_insn "*stmsi7"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 7 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
+ (match_operand:SI 8 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
+ (match_operand:SI 9 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 8"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
+
+(define_insn "*stmsi6"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 7 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
+ (match_operand:SI 8 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 7"
"{stsi|stswi} %2,%1,%O0"
[(set_attr "type" "store")])
+(define_insn "*stmsi5"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
+ (match_operand:SI 7 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 6"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
+
+(define_insn "*stmsi4"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
+ (match_operand:SI 6 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 5"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
+
+(define_insn "*stmsi3"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
+ (match_operand:SI 2 "gpc_reg_operand" "r"))
+ (clobber (match_scratch:SI 3 "X"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
+ (match_operand:SI 4 "gpc_reg_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
+ (match_operand:SI 5 "gpc_reg_operand" "r"))])]
+ "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 4"
+ "{stsi|stswi} %2,%1,%O0"
+ [(set_attr "type" "store")])
;; String/block move insn.
;; Argument 0 is the destination
@@ -10010,18 +9482,7 @@
"@
ldux %3,%0,%2
ldu %3,%2(%0)"
- [(set_attr "type" "load")])
-
-(define_insn "*movdi_update2"
- [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
- (sign_extend:DI
- (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
- (match_operand:DI 2 "gpc_reg_operand" "r")))))
- (set (match_operand:DI 0 "gpc_reg_operand" "=b")
- (plus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
- "lwaux %3,%0,%2"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "movdi_update"
[(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
@@ -10033,7 +9494,7 @@
"@
stdux %3,%0,%2
stdu %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
(define_insn "*movsi_update1"
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
@@ -10041,11 +9502,22 @@
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
(set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
(plus:SI (match_dup 1) (match_dup 2)))]
- ""
+ "TARGET_UPDATE"
"@
{lux|lwzux} %3,%0,%2
{lu|lwzu} %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
+
+(define_insn "*movsi_update2"
+ [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
+ (sign_extend:DI
+ (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
+ (match_operand:DI 2 "gpc_reg_operand" "r")))))
+ (set (match_operand:DI 0 "gpc_reg_operand" "=b")
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "TARGET_POWERPC64"
+ "lwaux %3,%0,%2"
+ [(set_attr "type" "load_ext_ux")])
(define_insn "movsi_update"
[(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -10057,9 +9529,9 @@
"@
{stux|stwux} %3,%0,%2
{stu|stwu} %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
-(define_insn "*movhi_update"
+(define_insn "*movhi_update1"
[(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))
@@ -10069,7 +9541,7 @@
"@
lhzux %3,%0,%2
lhzu %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movhi_update2"
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
@@ -10082,7 +9554,7 @@
"@
lhzux %3,%0,%2
lhzu %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movhi_update3"
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
@@ -10095,7 +9567,7 @@
"@
lhaux %3,%0,%2
lhau %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ext_ux,load_ext_u")])
(define_insn "*movhi_update4"
[(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -10107,7 +9579,7 @@
"@
sthux %3,%0,%2
sthu %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
(define_insn "*movqi_update1"
[(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
@@ -10119,7 +9591,7 @@
"@
lbzux %3,%0,%2
lbzu %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movqi_update2"
[(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
@@ -10132,7 +9604,7 @@
"@
lbzux %3,%0,%2
lbzu %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movqi_update3"
[(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -10144,7 +9616,7 @@
"@
stbux %3,%0,%2
stbu %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
(define_insn "*movsf_update1"
[(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
@@ -10156,7 +9628,7 @@
"@
lfsux %3,%0,%2
lfsu %3,%2(%0)"
- [(set_attr "type" "fpload")])
+ [(set_attr "type" "fpload_ux,fpload_u")])
(define_insn "*movsf_update2"
[(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -10168,7 +9640,7 @@
"@
stfsux %3,%0,%2
stfsu %3,%2(%0)"
- [(set_attr "type" "fpstore")])
+ [(set_attr "type" "fpstore_ux,fpstore_u")])
(define_insn "*movsf_update3"
[(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
@@ -10180,7 +9652,7 @@
"@
{lux|lwzux} %3,%0,%2
{lu|lwzu} %3,%2(%0)"
- [(set_attr "type" "load")])
+ [(set_attr "type" "load_ux,load_u")])
(define_insn "*movsf_update4"
[(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -10192,7 +9664,7 @@
"@
{stux|stwux} %3,%0,%2
{stu|stwu} %3,%2(%0)"
- [(set_attr "type" "store")])
+ [(set_attr "type" "store_ux,store_u")])
(define_insn "*movdf_update1"
[(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
@@ -10204,7 +9676,7 @@
"@
lfdux %3,%0,%2
lfdu %3,%2(%0)"
- [(set_attr "type" "fpload")])
+ [(set_attr "type" "fpload_ux,fpload_u")])
(define_insn "*movdf_update2"
[(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
@@ -10216,7 +9688,7 @@
"@
stfdux %3,%0,%2
stfdu %3,%2(%0)"
- [(set_attr "type" "fpstore")])
+ [(set_attr "type" "fpstore_ux,fpstore_u")])
;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
@@ -10244,6 +9716,186 @@
&& addrs_ok_for_quad_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
"stfq%U0%X0 %1,%0")
+;; TLS support.
+
+;; "b" output constraint here and on tls_ld to support tls linker optimization.
+(define_insn "tls_gd_32"
+ [(set (match_operand:SI 0 "register_operand" "=b")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGD))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addi %0,%1,%2@got@tlsgd")
+
+(define_insn "tls_gd_64"
+ [(set (match_operand:DI 0 "register_operand" "=b")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGD))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addi %0,%1,%2@got@tlsgd")
+
+(define_insn "tls_ld_32"
+ [(set (match_operand:SI 0 "register_operand" "=b")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")]
+ UNSPEC_TLSLD))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addi %0,%1,%&@got@tlsld")
+
+(define_insn "tls_ld_64"
+ [(set (match_operand:DI 0 "register_operand" "=b")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")]
+ UNSPEC_TLSLD))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addi %0,%1,%&@got@tlsld")
+
+(define_insn "tls_dtprel_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPREL))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addi %0,%1,%2@dtprel")
+
+(define_insn "tls_dtprel_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPREL))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addi %0,%1,%2@dtprel")
+
+(define_insn "tls_dtprel_ha_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPRELHA))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addis %0,%1,%2@dtprel@ha")
+
+(define_insn "tls_dtprel_ha_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPRELHA))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addis %0,%1,%2@dtprel@ha")
+
+(define_insn "tls_dtprel_lo_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPRELLO))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addi %0,%1,%2@dtprel@l")
+
+(define_insn "tls_dtprel_lo_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSDTPRELLO))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addi %0,%1,%2@dtprel@l")
+
+(define_insn "tls_got_dtprel_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGOTDTPREL))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "lwz %0,%2@got@dtprel(%1)")
+
+(define_insn "tls_got_dtprel_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGOTDTPREL))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "ld %0,%2@got@dtprel(%1)")
+
+(define_insn "tls_tprel_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPREL))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addi %0,%1,%2@tprel")
+
+(define_insn "tls_tprel_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPREL))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addi %0,%1,%2@tprel")
+
+(define_insn "tls_tprel_ha_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPRELHA))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addis %0,%1,%2@tprel@ha")
+
+(define_insn "tls_tprel_ha_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPRELHA))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addis %0,%1,%2@tprel@ha")
+
+(define_insn "tls_tprel_lo_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPRELLO))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "addi %0,%1,%2@tprel@l")
+
+(define_insn "tls_tprel_lo_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTPRELLO))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "addi %0,%1,%2@tprel@l")
+
+;; "b" output constraint here and on tls_tls input to support linker tls
+;; optimization. The linker may edit the instructions emitted by a
+;; tls_got_tprel/tls_tls pair to addis,addi.
+(define_insn "tls_got_tprel_32"
+ [(set (match_operand:SI 0 "register_operand" "=b")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGOTTPREL))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "lwz %0,%2@got@tprel(%1)")
+
+(define_insn "tls_got_tprel_64"
+ [(set (match_operand:DI 0 "register_operand" "=b")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSGOTTPREL))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "ld %0,%2@got@tprel(%1)")
+
+(define_insn "tls_tls_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "b")
+ (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTLS))]
+ "HAVE_AS_TLS && !TARGET_64BIT"
+ "add %0,%1,%2@tls")
+
+(define_insn "tls_tls_64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
+ UNSPEC_TLSTLS))]
+ "HAVE_AS_TLS && TARGET_64BIT"
+ "add %0,%1,%2@tls")
+
;; Next come insns related to the calling sequence.
;;
;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
@@ -10375,7 +10027,7 @@
(define_insn "load_toc_aix_si"
[(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(const_int 0)] 7))
+ (unspec:SI [(const_int 0)] UNSPEC_TOC))
(use (reg:SI 2))])]
"DEFAULT_ABI == ABI_AIX && TARGET_32BIT"
"*
@@ -10390,7 +10042,7 @@
(define_insn "load_toc_aix_di"
[(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
- (unspec:DI [(const_int 0)] 7))
+ (unspec:DI [(const_int 0)] UNSPEC_TOC))
(use (reg:DI 2))])]
"DEFAULT_ABI == ABI_AIX && TARGET_64BIT"
"*
@@ -10412,7 +10064,7 @@
(define_insn "load_toc_v4_pic_si"
[(set (match_operand:SI 0 "register_operand" "=l")
- (unspec:SI [(const_int 0)] 7))]
+ (unspec:SI [(const_int 0)] UNSPEC_TOC))]
"DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
"bl _GLOBAL_OFFSET_TABLE_@local-4"
[(set_attr "type" "branch")
@@ -10421,7 +10073,7 @@
(define_insn "load_toc_v4_PIC_1"
[(set (match_operand:SI 0 "register_operand" "=l")
(match_operand:SI 1 "immediate_operand" "s"))
- (unspec [(match_dup 1)] 7)]
+ (use (unspec [(match_dup 1)] UNSPEC_TOC))]
"TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
"bcl 20,31,%1\\n%1:"
[(set_attr "type" "branch")
@@ -10430,9 +10082,10 @@
(define_insn "load_toc_v4_PIC_1b"
[(set (match_operand:SI 0 "register_operand" "=l")
(match_operand:SI 1 "immediate_operand" "s"))
- (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")] 6)]
+ (use (unspec [(match_dup 1) (match_operand 2 "immediate_operand" "s")]
+ UNSPEC_TOCPTR))]
"TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
- "bcl 20,31,%1\\n\\t.long %2-%1+4\\n%1:"
+ "bcl 20,31,%1+4\\n%1:\\n\\t.long %2-%1"
[(set_attr "type" "branch")
(set_attr "length" "8")])
@@ -10447,7 +10100,8 @@
(define_insn "load_macho_picbase"
[(set (match_operand:SI 0 "register_operand" "=l")
- (unspec:SI [(match_operand:SI 1 "immediate_operand" "s")] 15))]
+ (unspec:SI [(match_operand:SI 1 "immediate_operand" "s")]
+ UNSPEC_LD_MPIC))]
"(DEFAULT_ABI == ABI_DARWIN) && flag_pic"
"bcl 20,31,%1\\n%1:"
[(set_attr "type" "branch")
@@ -10455,12 +10109,12 @@
(define_insn "macho_correct_pic"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (plus:SI (match_operand:SI 1 "gpc_reg_operand" "=r")
+ (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(unspec:SI [(match_operand:SI 2 "immediate_operand" "s")
(match_operand:SI 3 "immediate_operand" "s")]
- 16)))]
+ UNSPEC_MPIC_CORRECT)))]
"DEFAULT_ABI == ABI_DARWIN"
- "addis %0,%1,ha16(%2-%3)\n\taddi %1,%1,lo16(%2-%3)"
+ "addis %0,%1,ha16(%2-%3)\n\taddi %0,%0,lo16(%2-%3)"
[(set_attr "length" "8")])
;; If the TOC is shared over a translation unit, as happens with all
@@ -10478,15 +10132,15 @@
#if TARGET_MACHO
if (DEFAULT_ABI == ABI_DARWIN)
{
- char *picbase = machopic_function_base_name ();
- rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
+ const char *picbase = machopic_function_base_name ();
+ rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (picbase));
rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
rtx tmplabrtx;
char tmplab[20];
ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
CODE_LABEL_NUMBER (operands[0]));
- tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (tmplab, -1));
+ tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
emit_insn (gen_load_macho_picbase (picreg, tmplabrtx));
emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
@@ -10603,7 +10257,7 @@
"
{
#if TARGET_MACHO
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
operands[0] = machopic_indirect_call_target (operands[0]);
#endif
@@ -10613,13 +10267,13 @@
operands[0] = XEXP (operands[0], 0);
if (GET_CODE (operands[0]) != SYMBOL_REF
- || (INTVAL (operands[2]) & CALL_LONG) != 0)
+ || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[0]))
+ || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
{
if (INTVAL (operands[2]) & CALL_LONG)
operands[0] = rs6000_longcall_ref (operands[0]);
if (DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_AIX_NODESC
|| DEFAULT_ABI == ABI_DARWIN)
operands[0] = force_reg (Pmode, operands[0]);
@@ -10651,7 +10305,7 @@
"
{
#if TARGET_MACHO
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
operands[1] = machopic_indirect_call_target (operands[1]);
#endif
@@ -10661,15 +10315,15 @@
operands[1] = XEXP (operands[1], 0);
if (GET_CODE (operands[1]) != SYMBOL_REF
- || (INTVAL (operands[3]) & CALL_LONG) != 0)
+ || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[1]))
+ || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
{
if (INTVAL (operands[3]) & CALL_LONG)
operands[1] = rs6000_longcall_ref (operands[1]);
if (DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_AIX_NODESC
|| DEFAULT_ABI == ABI_DARWIN)
- operands[0] = force_reg (Pmode, operands[0]);
+ operands[1] = force_reg (Pmode, operands[1]);
else if (DEFAULT_ABI == ABI_AIX)
{
@@ -10898,8 +10552,7 @@
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
- "DEFAULT_ABI == ABI_AIX_NODESC
- || DEFAULT_ABI == ABI_V4
+ "DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_DARWIN"
{
if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
@@ -10918,10 +10571,9 @@
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
- "(DEFAULT_ABI == ABI_AIX_NODESC
- || DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_DARWIN)
- && (INTVAL (operands[2]) & CALL_LONG) == 0"
+ "(DEFAULT_ABI == ABI_DARWIN
+ || (DEFAULT_ABI == ABI_V4
+ && (INTVAL (operands[2]) & CALL_LONG) == 0))"
{
if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
output_asm_insn ("crxor 6,6,6", operands);
@@ -10929,7 +10581,11 @@
else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn ("creqv 6,6,6", operands);
+#if TARGET_MACHO
+ return output_call(insn, operands, 0, 2);
+#else
return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@plt" : "bl %z0";
+#endif
}
[(set_attr "type" "branch,branch")
(set_attr "length" "4,8")])
@@ -10940,8 +10596,7 @@
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
- "DEFAULT_ABI == ABI_AIX_NODESC
- || DEFAULT_ABI == ABI_V4
+ "DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_DARWIN"
{
if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
@@ -10961,10 +10616,9 @@
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
- "(DEFAULT_ABI == ABI_AIX_NODESC
- || DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_DARWIN)
- && (INTVAL (operands[3]) & CALL_LONG) == 0"
+ "(DEFAULT_ABI == ABI_DARWIN
+ || (DEFAULT_ABI == ABI_V4
+ && (INTVAL (operands[3]) & CALL_LONG) == 0))"
{
if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
output_asm_insn ("crxor 6,6,6", operands);
@@ -10972,7 +10626,11 @@
else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn ("creqv 6,6,6", operands);
+#if TARGET_MACHO
+ return output_call(insn, operands, 1, 3);
+#else
return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@plt" : "bl %z1";
+#endif
}
[(set_attr "type" "branch,branch")
(set_attr "length" "4,8")])
@@ -11010,13 +10668,13 @@
[(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))
- (use (scratch:SI))
+ (use (match_operand 3 "" ""))
(return)])]
""
"
{
#if TARGET_MACHO
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
operands[0] = machopic_indirect_call_target (operands[0]);
#endif
@@ -11024,6 +10682,7 @@
abort ();
operands[0] = XEXP (operands[0], 0);
+ operands[3] = gen_reg_rtx (SImode);
}")
@@ -11035,7 +10694,7 @@
[(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
- (use (match_scratch:SI 3 "=l,l"))
+ (use (match_operand:SI 3 "register_operand" "l,l"))
(return)]
"(INTVAL (operands[2]) & CALL_LONG) == 0"
"*
@@ -11055,7 +10714,7 @@
[(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
- (use (match_scratch:SI 3 "=l,l"))
+ (use (match_operand:SI 3 "register_operand" "l,l"))
(return)]
"TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
"*
@@ -11076,7 +10735,7 @@
(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
- (use (match_scratch:SI 4 "=l,l"))
+ (use (match_operand:SI 4 "register_operand" "l,l"))
(return)]
"(INTVAL (operands[3]) & CALL_LONG) == 0"
"*
@@ -11098,7 +10757,7 @@
(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
- (use (match_scratch:SI 4 "=l,l"))
+ (use (match_operand:SI 4 "register_operand" "l,l"))
(return)]
"TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
"*
@@ -11118,7 +10777,7 @@
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
(match_operand 1 "" "g"))
(use (match_operand:SI 2 "immediate_operand" "O"))
- (use (match_scratch:SI 3 "=l"))
+ (use (match_operand:SI 3 "register_operand" "l"))
(return)]
"TARGET_32BIT
&& DEFAULT_ABI == ABI_AIX
@@ -11131,7 +10790,7 @@
[(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
(match_operand 1 "" "g"))
(use (match_operand:SI 2 "immediate_operand" "O"))
- (use (match_scratch:SI 3 "=l"))
+ (use (match_operand:SI 3 "register_operand" "l"))
(return)]
"TARGET_64BIT
&& DEFAULT_ABI == ABI_AIX
@@ -11145,7 +10804,7 @@
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s"))
(match_operand 2 "" "g")))
(use (match_operand:SI 3 "immediate_operand" "O"))
- (use (match_scratch:SI 4 "=l"))
+ (use (match_operand:SI 4 "register_operand" "l"))
(return)]
"TARGET_32BIT
&& DEFAULT_ABI == ABI_AIX
@@ -11159,7 +10818,7 @@
(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))
(match_operand 2 "" "g")))
(use (match_operand:SI 3 "immediate_operand" "O"))
- (use (match_scratch:SI 4 "=l"))
+ (use (match_operand:SI 4 "register_operand" "l"))
(return)]
"TARGET_64BIT
&& DEFAULT_ABI == ABI_AIX
@@ -11172,11 +10831,10 @@
[(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s,s"))
(match_operand 1 "" ""))
(use (match_operand 2 "immediate_operand" "O,n"))
- (use (match_scratch:SI 3 "=l,l"))
+ (use (match_operand:SI 3 "register_operand" "l,l"))
(return)]
"(DEFAULT_ABI == ABI_DARWIN
- || DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_AIX_NODESC)
+ || DEFAULT_ABI == ABI_V4)
&& (INTVAL (operands[2]) & CALL_LONG) == 0"
"*
{
@@ -11196,13 +10854,13 @@
(call (mem:SI (match_operand 1 "address_operand" ""))
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))
- (use (scratch:SI))
+ (use (match_operand 4 "" ""))
(return)])]
""
"
{
#if TARGET_MACHO
- if (flag_pic)
+ if (MACHOPIC_INDIRECT)
operands[1] = machopic_indirect_call_target (operands[1]);
#endif
@@ -11210,6 +10868,7 @@
abort ();
operands[1] = XEXP (operands[1], 0);
+ operands[4] = gen_reg_rtx (SImode);
}")
@@ -11218,11 +10877,10 @@
(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s,s"))
(match_operand 2 "" "")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
- (use (match_scratch:SI 4 "=l,l"))
+ (use (match_operand:SI 4 "register_operand" "l,l"))
(return)]
"(DEFAULT_ABI == ABI_DARWIN
- || DEFAULT_ABI == ABI_V4
- || DEFAULT_ABI == ABI_AIX_NODESC)
+ || DEFAULT_ABI == ABI_V4)
&& (INTVAL (operands[3]) & CALL_LONG) == 0"
"*
{
@@ -11250,7 +10908,7 @@
;; all of memory. This blocks insns from being moved across this point.
(define_insn "blockage"
- [(unspec_volatile [(const_int 0)] 0)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
""
"")
@@ -11325,8 +10983,8 @@
(define_expand "cmptf"
[(set (cc0) (compare (match_operand:TF 0 "gpc_reg_operand" "")
(match_operand:TF 1 "gpc_reg_operand" "")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT
- && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
"
{
rs6000_compare_op0 = operands[0];
@@ -11447,8 +11105,8 @@
DONE;
}")
-;; A > 0 is best done using the portable sequence, so fail in that case.
-(define_expand "sgt"
+;; A >= 0 is best done the portable way for A an integer.
+(define_expand "sge"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
"
@@ -11457,26 +11115,26 @@
&& (! TARGET_POWER || rs6000_compare_op1 == const0_rtx))
FAIL;
- rs6000_emit_sCOND (GT, operands[0]);
+ rs6000_emit_sCOND (GE, operands[0]);
DONE;
}")
-;; A < 0 is best done in the portable way for A an integer.
-(define_expand "slt"
+;; 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
+ if (! rs6000_compare_fp_p
&& (! TARGET_POWER || rs6000_compare_op1 == const0_rtx))
FAIL;
- rs6000_emit_sCOND (LT, operands[0]);
+ rs6000_emit_sCOND (GT, operands[0]);
DONE;
}")
-;; A >= 0 is best done the portable way for A an integer.
-(define_expand "sge"
+;; A <= 0 is best done the portable way for A an integer.
+(define_expand "sle"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
"
@@ -11485,43 +11143,84 @@
&& (! TARGET_POWER || rs6000_compare_op1 == const0_rtx))
FAIL;
- rs6000_emit_sCOND (GE, operands[0]);
+ rs6000_emit_sCOND (LE, operands[0]);
DONE;
}")
-;; A <= 0 is best done the portable way for A an integer.
-(define_expand "sle"
+;; A < 0 is best done in the portable way for A an integer.
+(define_expand "slt"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
"
{
- if (! rs6000_compare_fp_p
+ if (! rs6000_compare_fp_p
&& (! TARGET_POWER || rs6000_compare_op1 == const0_rtx))
FAIL;
- rs6000_emit_sCOND (LE, operands[0]);
+ rs6000_emit_sCOND (LT, operands[0]);
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 "sgeu"
+(define_expand "sunordered"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
- "{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }")
+ "{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }")
-(define_expand "sleu"
+(define_expand "sordered"
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
""
- "{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }")
+ "{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }")
+
+(define_expand "suneq"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (UNEQ, operands[0]); DONE; }")
+
+(define_expand "sunge"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (UNGE, operands[0]); DONE; }")
+
+(define_expand "sungt"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (UNGT, operands[0]); DONE; }")
+
+(define_expand "sunle"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (UNLE, operands[0]); DONE; }")
+
+(define_expand "sunlt"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (UNLT, operands[0]); DONE; }")
+
+(define_expand "sltgt"
+ [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
+ ""
+ "{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }")
+
;; Here are the actual compare insns.
(define_insn "*cmpsi_internal1"
@@ -11530,7 +11229,7 @@
(match_operand:SI 2 "reg_or_short_operand" "rI")))]
""
"{cmp%I2|cmpw%I2} %0,%1,%2"
- [(set_attr "type" "compare")])
+ [(set_attr "type" "cmp")])
(define_insn "*cmpdi_internal1"
[(set (match_operand:CC 0 "cc_reg_operand" "=y")
@@ -11538,7 +11237,7 @@
(match_operand:DI 2 "reg_or_short_operand" "rI")))]
"TARGET_POWERPC64"
"cmpd%I2 %0,%1,%2"
- [(set_attr "type" "compare")])
+ [(set_attr "type" "cmp")])
;; If we are comparing a register for equality with a large constant,
;; we can do this with an XOR followed by a compare. But we need a scratch
@@ -11574,7 +11273,7 @@
(match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
""
"{cmpl%I2|cmplw%I2} %0,%1,%b2"
- [(set_attr "type" "compare")])
+ [(set_attr "type" "cmp")])
(define_insn "*cmpdi_internal2"
[(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
@@ -11582,7 +11281,7 @@
(match_operand:DI 2 "reg_or_u_short_operand" "rK")))]
""
"cmpld%I2 %0,%1,%b2"
- [(set_attr "type" "compare")])
+ [(set_attr "type" "cmp")])
;; The following two insns don't exist as single insns, but if we provide
;; them, we can swap an add and compare, which will enable us to overlap more
@@ -11650,9 +11349,9 @@
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
(match_operand:TF 2 "gpc_reg_operand" "f")))]
- "DEFAULT_ABI == ABI_AIX && TARGET_HARD_FLOAT && TARGET_FPRS
- && TARGET_LONG_DOUBLE_128"
- "fcmpu %0,%1,%2\;bne %0,$+4\;fcmpu %0,%L1,%L2"
+ "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
+ && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
+ "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
[(set_attr "type" "fpcompare")
(set_attr "length" "12")])
@@ -11669,17 +11368,31 @@
[(match_operand 2 "cc_reg_operand" "y")
(const_int 0)]))]
""
- "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
- [(set_attr "type" "cr_logical")
+ "mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%J1,1"
+ [(set (attr "type")
+ (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0))
+ (const_string "mfcrf")
+ ]
+ (const_string "mfcr")))
+ (set_attr "length" "12")])
+
+;; Same as above, but get the GT bit.
+(define_insn "move_from_CR_gt_bit"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
+ "TARGET_E500"
+ "mfcr %0\;{rlinm|rlwinm} %0,%0,%D1,1"
+ [(set_attr "type" "mfcr")
(set_attr "length" "12")])
;; Same as above, but get the OV/ORDERED bit.
(define_insn "move_from_CR_ov_bit"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] 724))]
+ (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_OV))]
"TARGET_ISEL"
- "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%t1,1"
- [(set_attr "length" "12")])
+ "mfcr %0\;{rlinm|rlwinm} %0,%0,%t1,1"
+ [(set_attr "type" "mfcr")
+ (set_attr "length" "12")])
(define_insn ""
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
@@ -11687,8 +11400,12 @@
[(match_operand 2 "cc_reg_operand" "y")
(const_int 0)]))]
"TARGET_POWERPC64"
- "%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
- [(set_attr "type" "cr_logical")
+ "mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%J1,1"
+ [(set (attr "type")
+ (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0))
+ (const_string "mfcrf")
+ ]
+ (const_string "mfcr")))
(set_attr "length" "12")])
(define_insn ""
@@ -11699,9 +11416,9 @@
(const_int 0)))
(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
- %D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1
+ mfcr %3%Q2\;{rlinm.|rlwinm.} %3,%3,%J1,1
#"
[(set_attr "type" "delayed_compare")
(set_attr "length" "12,16")])
@@ -11714,7 +11431,7 @@
(const_int 0)))
(set (match_operand:SI 3 "gpc_reg_operand" "")
(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(match_op_dup 1 [(match_dup 2) (const_int 0)]))
(set (match_dup 0)
@@ -11743,9 +11460,13 @@
operands[4] = GEN_INT (count);
operands[5] = GEN_INT (put_bit);
- return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
+ return \"mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
}"
- [(set_attr "type" "cr_logical")
+ [(set (attr "type")
+ (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0))
+ (const_string "mfcrf")
+ ]
+ (const_string "mfcr")))
(set_attr "length" "12")])
(define_insn ""
@@ -11778,7 +11499,7 @@
operands[5] = GEN_INT (count);
operands[6] = GEN_INT (put_bit);
- return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
+ return \"mfcr %4%Q2\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
}"
[(set_attr "type" "delayed_compare")
(set_attr "length" "12,16")])
@@ -11816,8 +11537,8 @@
[(match_operand 5 "cc_reg_operand" "y")
(const_int 0)]))]
"REGNO (operands[2]) != REGNO (operands[5])"
- "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
- [(set_attr "type" "cr_logical")
+ "mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
+ [(set_attr "type" "mfcr")
(set_attr "length" "20")])
(define_peephole
@@ -11830,8 +11551,8 @@
[(match_operand 5 "cc_reg_operand" "y")
(const_int 0)]))]
"TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
- "%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
- [(set_attr "type" "cr_logical")
+ "mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
+ [(set_attr "type" "mfcr")
(set_attr "length" "20")])
;; There are some scc insns that can be done directly, without a compare.
@@ -11853,7 +11574,7 @@
(eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I")))
(clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
{sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
@@ -11867,7 +11588,7 @@
(eq:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r")
(match_operand:DI 2 "reg_or_cint_operand" "r,O,K,J,I")))
(clobber (match_scratch:DI 3 "=r,&r,r,r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
xor %0,%1,%2\;subfic %3,%0,0\;adde %0,%3,%0
subfic %3,%1,0\;adde %0,%3,%1
@@ -11885,7 +11606,7 @@
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r")
(eq:SI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:SI 3 "=r,&r,r,r,r,r,&r,r,r,r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae.|adde.} %0,%3,%0
{sfi|subfic} %3,%1,0\;{ae.|adde.} %0,%3,%1
@@ -11909,7 +11630,7 @@
(set (match_operand:SI 0 "gpc_reg_operand" "")
(eq:SI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(parallel [(set (match_dup 0)
(eq:SI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])
@@ -11927,7 +11648,7 @@
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r")
(eq:DI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:DI 3 "=r,&r,r,r,r,r,&r,r,r,r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
xor %0,%1,%2\;subfic %3,%0,0\;adde. %0,%3,%0
subfic %3,%1,0\;adde. %0,%3,%1
@@ -11951,7 +11672,7 @@
(set (match_operand:DI 0 "gpc_reg_operand" "")
(eq:DI (match_dup 1) (match_dup 2)))
(clobber (match_scratch:DI 3 ""))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(parallel [(set (match_dup 0)
(eq:DI (match_dup 1) (match_dup 2)))
(clobber (match_dup 3))])
@@ -11980,7 +11701,7 @@
(plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I"))
(match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
xor %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze|addze} %0,%3
{sfi|subfic} %0,%1,0\;{aze|addze} %0,%3
@@ -11998,7 +11719,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
{sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
@@ -12022,7 +11743,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(plus:SI (eq:SI (match_dup 1)
(match_dup 2))
@@ -12042,7 +11763,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r")
(plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
xor %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze.|addze.} %0,%3
{sfi|subfic} %0,%1,0\;{aze.|addze.} %0,%3
@@ -12067,7 +11788,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
@@ -12079,7 +11800,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
(neg:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
(match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I"))))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
xor %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
{ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0
@@ -12095,7 +11816,7 @@
(lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
(const_int 31)))
(clobber (match_scratch:SI 2 "=&r"))]
- "! TARGET_POWER && ! TARGET_POWERPC64 && !TARGET_ISEL"
+ "! TARGET_POWER && TARGET_32BIT && !TARGET_ISEL"
"{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
[(set_attr "length" "8")])
@@ -12104,7 +11825,7 @@
(lshiftrt:DI (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
(const_int 63)))
(clobber (match_scratch:DI 2 "=&r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"addic %2,%1,-1\;subfe %0,%2,%1"
[(set_attr "length" "8")])
@@ -12116,7 +11837,7 @@
(const_int 31))
(match_operand:SI 2 "gpc_reg_operand" "r")))
(clobber (match_scratch:SI 3 "=&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
[(set_attr "length" "8")])
@@ -12127,7 +11848,7 @@
(const_int 63))
(match_operand:DI 2 "gpc_reg_operand" "r")))
(clobber (match_scratch:DI 3 "=&r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"addic %3,%1,-1\;addze %0,%2"
[(set_attr "length" "8")])
@@ -12141,7 +11862,7 @@
(const_int 0)))
(clobber (match_scratch:SI 3 "=&r,&r"))
(clobber (match_scratch:SI 4 "=X,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2
#"
@@ -12158,7 +11879,7 @@
(const_int 0)))
(clobber (match_scratch:SI 3 ""))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(parallel [(set (match_dup 3)
(plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1)))
(const_int 31))
@@ -12178,7 +11899,7 @@
(match_operand:DI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=&r,&r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addic %3,%1,-1\;addze. %3,%2
#"
@@ -12194,7 +11915,7 @@
(match_operand:DI 2 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 3)
(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1)))
(const_int 63))
@@ -12216,7 +11937,7 @@
(plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
(match_dup 2)))
(clobber (match_scratch:SI 3 "=&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2
#"
@@ -12235,7 +11956,7 @@
(plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
(match_dup 2)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(parallel [(set (match_dup 0)
(plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
(match_dup 2)))
@@ -12257,7 +11978,7 @@
(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
(match_dup 2)))
(clobber (match_scratch:DI 3 "=&r,&r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addic %3,%1,-1\;addze. %0,%2
#"
@@ -12276,7 +11997,7 @@
(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
(match_dup 2)))
(clobber (match_scratch:DI 3 ""))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(parallel [(set (match_dup 0)
(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
(match_dup 2)))
@@ -12427,7 +12148,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_short_operand" "rI")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
[(set_attr "length" "12")])
@@ -12435,7 +12156,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(leu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:DI 2 "reg_or_short_operand" "rI")))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"subf%I2c %0,%1,%2\;li %0,0\;adde %0,%0,%0"
[(set_attr "length" "12")])
@@ -12447,7 +12168,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(leu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0
#"
@@ -12462,7 +12183,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(leu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(leu:DI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -12478,7 +12199,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(leu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
#"
@@ -12493,7 +12214,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(leu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(leu:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -12502,26 +12223,11 @@
"")
(define_insn ""
- [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
- (compare:CC
- (leu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
- (match_operand:DI 2 "reg_or_short_operand" "rI,rI"))
- (const_int 0)))
- (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
- (leu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
- "@
- subf%I2c %0,%1,%2\;li %0,0\;adde. %0,%0,%0
- #"
- [(set_attr "type" "compare")
- (set_attr "length" "12,16")])
-
-(define_insn ""
[(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
(plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_short_operand" "rI"))
(match_operand:SI 3 "gpc_reg_operand" "r")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sf%I2|subf%I2c} %0,%1,%2\;{aze|addze} %0,%3"
[(set_attr "length" "8")])
@@ -12533,7 +12239,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3
#"
@@ -12548,7 +12254,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(plus:SI (leu:SI (match_dup 1) (match_dup 2))
(match_dup 3)))
@@ -12566,7 +12272,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
(plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf%I2|subf%I2c} %0,%1,%2\;{aze.|addze.} %0,%3
#"
@@ -12582,7 +12288,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
@@ -12594,7 +12300,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(neg:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_short_operand" "rI"))))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
[(set_attr "length" "12")])
@@ -12604,7 +12310,7 @@
(leu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_short_operand" "rI")))
(match_operand:SI 3 "gpc_reg_operand" "r")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0"
[(set_attr "length" "12")])
@@ -12617,7 +12323,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
#"
@@ -12633,7 +12339,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2)))
(match_dup 3)))
@@ -12652,7 +12358,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0
#"
@@ -12669,7 +12375,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2)))
(match_dup 3)))
@@ -12803,7 +12509,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg %0,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
@@ -12817,7 +12523,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(ltu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
@@ -12834,7 +12540,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(ltu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(ltu:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -12847,7 +12553,7 @@
(plus:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
(match_operand:SI 3 "reg_or_short_operand" "rI,rI")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3"
@@ -12861,7 +12567,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
{ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
@@ -12878,7 +12584,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(plus:SI (ltu:SI (match_dup 1) (match_dup 2))
(match_dup 3)))
@@ -12896,7 +12602,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
(plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;{sf.|subfc.} %0,%0,%3
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;{sf.|subfc.} %0,%0,%3
@@ -12914,7 +12620,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (ltu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
@@ -12926,7 +12632,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(neg:SI (ltu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
@@ -13061,7 +12767,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
{ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
@@ -13071,7 +12777,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(geu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:DI 2 "reg_or_neg_short_operand" "r,P")))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subfc %0,%2,%1\;li %0,0\;adde %0,%0,%0
addic %0,%1,%n2\;li %0,0\;adde %0,%0,%0"
@@ -13085,7 +12791,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
(geu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
{ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
@@ -13102,7 +12808,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(geu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(geu:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -13118,7 +12824,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
(geu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subfc %0,%2,%1\;li %0,0\;adde. %0,%0,%0
addic %0,%1,%n2\;li %0,0\;adde. %0,%0,%0
@@ -13135,7 +12841,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(geu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(geu:DI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -13148,7 +12854,7 @@
(plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_neg_short_operand" "r,P"))
(match_operand:SI 3 "gpc_reg_operand" "r,r")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{aze|addze} %0,%3
{ai|addic} %0,%1,%n2\;{aze|addze} %0,%3"
@@ -13162,7 +12868,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
{ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3
@@ -13179,7 +12885,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(plus:SI (geu:SI (match_dup 1) (match_dup 2))
(match_dup 3)))
@@ -13197,7 +12903,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
(plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{aze.|addze.} %0,%3
{ai|addic} %0,%1,%n2\;{aze.|addze.} %0,%3
@@ -13215,7 +12921,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
@@ -13227,7 +12933,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(neg:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_short_operand" "r,I"))))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
{sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0"
@@ -13239,7 +12945,7 @@
(geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_neg_short_operand" "r,P")))
(match_operand:SI 3 "gpc_reg_operand" "r,r")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0"
@@ -13254,7 +12960,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
{ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
@@ -13272,7 +12978,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2)))
(match_dup 3)))
@@ -13291,7 +12997,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0
{ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0
@@ -13310,7 +13016,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
(set (match_dup 4)
@@ -13322,7 +13028,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(const_int 0)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri|srwi} %0,%0,31"
[(set_attr "length" "12")])
@@ -13330,7 +13036,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(const_int 0)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"subfic %0,%1,0\;addme %0,%0\;srdi %0,%0,63"
[(set_attr "length" "12")])
@@ -13342,7 +13048,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(gt:SI (match_dup 1) (const_int 0)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{sri.|srwi.} %0,%0,31
#"
@@ -13357,7 +13063,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(gt:SI (match_dup 1) (const_int 0)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(gt:SI (match_dup 1) (const_int 0)))
(set (match_dup 2)
@@ -13373,7 +13079,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(gt:DI (match_dup 1) (const_int 0)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subfic %0,%1,0\;addme %0,%0\;srdi. %0,%0,63
#"
@@ -13388,7 +13094,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(gt:DI (match_dup 1) (const_int 0)))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(gt:DI (match_dup 1) (const_int 0)))
(set (match_dup 2)
@@ -13440,7 +13146,7 @@
(plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(const_int 0))
(match_operand:SI 2 "gpc_reg_operand" "r")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{a|addc} %0,%1,%1\;{sfe|subfe} %0,%1,%0\;{aze|addze} %0,%2"
[(set_attr "length" "12")])
@@ -13449,7 +13155,7 @@
(plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(const_int 0))
(match_operand:DI 2 "gpc_reg_operand" "r")))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"addc %0,%1,%1\;subfe %0,%1,%0\;addze %0,%2"
[(set_attr "length" "12")])
@@ -13461,7 +13167,7 @@
(match_operand:SI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:SI 3 "=&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2
#"
@@ -13476,7 +13182,7 @@
(match_operand:SI 2 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 3 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 3)
(plus:SI (gt:SI (match_dup 1) (const_int 0))
(match_dup 2)))
@@ -13493,7 +13199,7 @@
(match_operand:DI 2 "gpc_reg_operand" "r,r"))
(const_int 0)))
(clobber (match_scratch:DI 3 "=&r,&r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2
#"
@@ -13508,7 +13214,7 @@
(match_operand:DI 2 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 3 ""))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 3)
(plus:DI (gt:DI (match_dup 1) (const_int 0))
(match_dup 2)))
@@ -13526,7 +13232,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
(plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{a|addc} %0,%1,%1\;{sfe|subfe} %0,%1,%0\;{aze.|addze.} %0,%2
#"
@@ -13542,7 +13248,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
(set (match_dup 3)
@@ -13559,7 +13265,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
(plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addc %0,%1,%1\;subfe %0,%1,%0\;addze. %0,%2
#"
@@ -13575,7 +13281,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))
(set (match_dup 3)
@@ -13660,7 +13366,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(const_int 0))))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sfi|subfic} %0,%1,0\;{ame|addme} %0,%0\;{srai|srawi} %0,%0,31"
[(set_attr "length" "12")])
@@ -13668,7 +13374,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(neg:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(const_int 0))))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"subfic %0,%1,0\;addme %0,%0\;sradi %0,%0,63"
[(set_attr "length" "12")])
@@ -13684,7 +13390,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_short_operand" "rI")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg %0,%0"
[(set_attr "length" "12")])
@@ -13692,7 +13398,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:DI 2 "reg_or_short_operand" "rI")))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg %0,%0"
[(set_attr "length" "12")])
@@ -13704,7 +13410,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
(gtu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;neg. %0,%0
#"
@@ -13719,7 +13425,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(gtu:SI (match_dup 1) (match_dup 2)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(gtu:SI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -13735,7 +13441,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
(gtu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
subf%I2c %0,%1,%2\;subfe %0,%0,%0\;neg. %0,%0
#"
@@ -13750,7 +13456,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(gtu:DI (match_dup 1) (match_dup 2)))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(gtu:DI (match_dup 1) (match_dup 2)))
(set (match_dup 3)
@@ -13763,7 +13469,7 @@
(plus:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
(match_operand:SI 2 "reg_or_short_operand" "I,rI"))
(match_operand:SI 3 "reg_or_short_operand" "r,rI")))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{ai|addic} %0,%1,%k2\;{aze|addze} %0,%3
{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;{sf%I3|subf%I3c} %0,%0,%3"
@@ -13774,7 +13480,7 @@
(plus:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
(match_operand:DI 2 "reg_or_short_operand" "I,rI"))
(match_operand:DI 3 "reg_or_short_operand" "r,rI")))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addic %0,%1,%k2\;addze %0,%3
subf%I2c %0,%1,%2\;subfe %0,%0,%0\;subf%I3c %0,%0,%3"
@@ -13788,7 +13494,7 @@
(match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
(const_int 0)))
(clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{ai|addic} %4,%1,%k2\;{aze.|addze.} %4,%3
{sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;{sf.|subfc.} %4,%4,%3
@@ -13805,7 +13511,7 @@
(match_operand:SI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 4)
(plus:SI (gtu:SI (match_dup 1) (match_dup 2))
(match_dup 3)))
@@ -13822,7 +13528,7 @@
(match_operand:DI 3 "gpc_reg_operand" "r,r,r,r"))
(const_int 0)))
(clobber (match_scratch:DI 4 "=&r,&r,&r,&r"))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addic %4,%1,%k2\;addze. %4,%3
subf%I2c %4,%1,%2\;subfe %4,%4,%4\;subfc. %4,%4,%3
@@ -13839,7 +13545,7 @@
(match_operand:DI 3 "gpc_reg_operand" ""))
(const_int 0)))
(clobber (match_scratch:DI 4 ""))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 4)
(plus:DI (gtu:DI (match_dup 1) (match_dup 2))
(match_dup 3)))
@@ -13857,7 +13563,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
(plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"@
{ai|addic} %0,%1,%k2\;{aze.|addze.} %0,%3
{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;{sf.|subfc.} %0,%0,%3
@@ -13875,7 +13581,7 @@
(const_int 0)))
(set (match_operand:SI 0 "gpc_reg_operand" "")
(plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(set (match_dup 0)
(plus:SI (gtu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
@@ -13892,7 +13598,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
(plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"@
addic %0,%1,%k2\;addze. %0,%3
subf%I2c %0,%1,%2\;subfe %0,%0,%0\;subfc. %0,%0,%3
@@ -13910,7 +13616,7 @@
(const_int 0)))
(set (match_operand:DI 0 "gpc_reg_operand" "")
(plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(set (match_dup 0)
(plus:DI (gtu:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
(set (match_dup 4)
@@ -13922,7 +13628,7 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(neg:SI (gtu:SI (match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "reg_or_short_operand" "rI"))))]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
[(set_attr "length" "8")])
@@ -13930,7 +13636,7 @@
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(neg:DI (gtu:DI (match_operand:DI 1 "gpc_reg_operand" "r")
(match_operand:DI 2 "reg_or_short_operand" "rI"))))]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"subf%I2c %0,%1,%2\;subfe %0,%0,%0"
[(set_attr "length" "8")])
@@ -13942,7 +13648,7 @@
[(set (pc)
(if_then_else (match_operator 1 "branch_comparison_operator"
[(match_operand 2
- "cc_reg_operand" "x,?y")
+ "cc_reg_operand" "y")
(const_int 0)])
(label_ref (match_operand 0 "" ""))
(pc)))]
@@ -13957,7 +13663,7 @@
[(set (pc)
(if_then_else (match_operator 0 "branch_comparison_operator"
[(match_operand 1
- "cc_reg_operand" "x,?y")
+ "cc_reg_operand" "y")
(const_int 0)])
(return)
(pc)))]
@@ -13973,7 +13679,7 @@
[(set (pc)
(if_then_else (match_operator 1 "branch_comparison_operator"
[(match_operand 2
- "cc_reg_operand" "x,?y")
+ "cc_reg_operand" "y")
(const_int 0)])
(pc)
(label_ref (match_operand 0 "" ""))))]
@@ -13988,7 +13694,7 @@
[(set (pc)
(if_then_else (match_operator 0 "branch_comparison_operator"
[(match_operand 1
- "cc_reg_operand" "x,?y")
+ "cc_reg_operand" "y")
(const_int 0)])
(pc)
(return)))]
@@ -14007,56 +13713,57 @@
; (eq:SI (reg:CCFP 68) (const_int 0)))
; (const_int 1)))
; which are generated by the branch logic.
+; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
-(define_insn ""
- [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
+(define_insn "*cceq_ior_compare"
+ [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
(compare:CCEQ (match_operator:SI 1 "boolean_operator"
- [(match_operator:SI 2
+ [(match_operator:SI 2
"branch_positive_comparison_operator"
[(match_operand 3
- "cc_reg_operand" "y")
+ "cc_reg_operand" "y,y")
(const_int 0)])
- (match_operator:SI 4
+ (match_operator:SI 4
"branch_positive_comparison_operator"
[(match_operand 5
- "cc_reg_operand" "y")
+ "cc_reg_operand" "0,y")
(const_int 0)])])
(const_int 1)))]
""
"cr%q1 %E0,%j2,%j4"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "cr_logical,delayed_cr")])
; Why is the constant -1 here, but 1 in the previous pattern?
; Because ~1 has all but the low bit set.
(define_insn ""
- [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
+ [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
(compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
- [(not:SI (match_operator:SI 2
+ [(not:SI (match_operator:SI 2
"branch_positive_comparison_operator"
[(match_operand 3
- "cc_reg_operand" "y")
+ "cc_reg_operand" "y,y")
(const_int 0)]))
(match_operator:SI 4
"branch_positive_comparison_operator"
[(match_operand 5
- "cc_reg_operand" "y")
+ "cc_reg_operand" "0,y")
(const_int 0)])])
(const_int -1)))]
""
"cr%q1 %E0,%j2,%j4"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "cr_logical,delayed_cr")])
-(define_insn ""
- [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
+(define_insn "*cceq_rev_compare"
+ [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
(compare:CCEQ (match_operator:SI 1
"branch_positive_comparison_operator"
[(match_operand 2
- "cc_reg_operand" "y")
+ "cc_reg_operand" "0,y")
(const_int 0)])
(const_int 0)))]
- "!TARGET_SPE"
+ ""
"{crnor %E0,%j1,%j1|crnot %E0,%j1}"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "cr_logical,delayed_cr")])
;; If we are comparing the result of two comparisons, this can be done
;; using creqv or crxor.
@@ -14237,7 +13944,7 @@
/* Only use this on innermost loops. */
if (INTVAL (operands[3]) > 1)
FAIL;
- if (TARGET_POWERPC64)
+ if (TARGET_64BIT)
{
if (GET_MODE (operands[0]) != DImode)
FAIL;
@@ -14263,7 +13970,7 @@
(const_int -1)))
(clobber (match_scratch:CC 2 ""))
(clobber (match_scratch:SI 3 ""))])]
- "! TARGET_POWERPC64"
+ "TARGET_32BIT"
"")
(define_expand "ctrdi"
@@ -14277,7 +13984,7 @@
(const_int -1)))
(clobber (match_scratch:CC 2 ""))
(clobber (match_scratch:DI 3 ""))])]
- "TARGET_POWERPC64"
+ "TARGET_64BIT"
"")
;; We need to be able to do this for any operand, including MEM, or we
@@ -14288,16 +13995,16 @@
(define_insn "*ctrsi_internal1"
[(set (pc)
- (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(label_ref (match_operand 0 "" ""))
(pc)))
- (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
+ (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
(plus:SI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:SI 4 "=X,X,r"))]
- "! TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:SI 4 "=X,X,&r,r"))]
+ "TARGET_32BIT"
"*
{
if (which_alternative != 0)
@@ -14308,20 +14015,20 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrsi_internal2"
[(set (pc)
- (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ne (match_operand:SI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(pc)
(label_ref (match_operand 0 "" ""))))
- (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
+ (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
(plus:SI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:SI 4 "=X,X,r"))]
- "! TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:SI 4 "=X,X,&r,r"))]
+ "TARGET_32BIT"
"*
{
if (which_alternative != 0)
@@ -14332,20 +14039,20 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrdi_internal1"
[(set (pc)
- (if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(label_ref (match_operand 0 "" ""))
(pc)))
- (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
+ (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:DI 4 "=X,X,r"))]
- "TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:DI 4 "=X,X,&r,r"))]
+ "TARGET_64BIT"
"*
{
if (which_alternative != 0)
@@ -14356,20 +14063,20 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrdi_internal2"
[(set (pc)
- (if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ne (match_operand:DI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(pc)
(label_ref (match_operand 0 "" ""))))
- (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
+ (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:DI 4 "=X,X,r"))]
- "TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:DI 4 "=X,X,&r,r"))]
+ "TARGET_64BIT"
"*
{
if (which_alternative != 0)
@@ -14380,22 +14087,22 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
;; Similar, but we can use GE since we have a REG_NONNEG.
(define_insn "*ctrsi_internal3"
[(set (pc)
- (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r,*r")
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))
- (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
+ (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
(plus:SI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&X"))
- (clobber (match_scratch:SI 4 "=X,X,r"))]
- "! TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:SI 4 "=X,X,&r,r"))]
+ "TARGET_32BIT && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
if (which_alternative != 0)
@@ -14406,20 +14113,20 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrsi_internal4"
[(set (pc)
- (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ge (match_operand:SI 1 "register_operand" "c,*r,*r,*r")
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))
- (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
+ (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
(plus:SI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&X"))
- (clobber (match_scratch:SI 4 "=X,X,r"))]
- "! TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:SI 4 "=X,X,&r,r"))]
+ "TARGET_32BIT && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
if (which_alternative != 0)
@@ -14430,20 +14137,20 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrdi_internal3"
[(set (pc)
- (if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r,*r")
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))
- (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
+ (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:DI 4 "=X,X,r"))]
- "TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:DI 4 "=X,X,&r,r"))]
+ "TARGET_64BIT && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
if (which_alternative != 0)
@@ -14454,20 +14161,20 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrdi_internal4"
[(set (pc)
- (if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r")
+ (if_then_else (ge (match_operand:DI 1 "register_operand" "c,*r,*r,*r")
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))
- (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
+ (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:DI 4 "=X,X,r"))]
- "TARGET_POWERPC64 && find_reg_note (insn, REG_NONNEG, 0)"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:DI 4 "=X,X,&r,r"))]
+ "TARGET_64BIT && find_reg_note (insn, REG_NONNEG, 0)"
"*
{
if (which_alternative != 0)
@@ -14478,22 +14185,22 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
;; Similar but use EQ
(define_insn "*ctrsi_internal5"
[(set (pc)
- (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
+ (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(label_ref (match_operand 0 "" ""))
(pc)))
- (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
+ (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
(plus:SI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:SI 4 "=X,X,r"))]
- "! TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:SI 4 "=X,X,&r,r"))]
+ "TARGET_32BIT"
"*
{
if (which_alternative != 0)
@@ -14504,20 +14211,20 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrsi_internal6"
[(set (pc)
- (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r")
+ (if_then_else (eq (match_operand:SI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(pc)
(label_ref (match_operand 0 "" ""))))
- (set (match_operand:SI 2 "register_operand" "=1,*r,m*q*c*l")
+ (set (match_operand:SI 2 "register_operand" "=1,*r,m,*q*c*l")
(plus:SI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:SI 4 "=X,X,r"))]
- "! TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:SI 4 "=X,X,&r,r"))]
+ "TARGET_32BIT"
"*
{
if (which_alternative != 0)
@@ -14528,20 +14235,20 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrdi_internal5"
[(set (pc)
- (if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r")
+ (if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(label_ref (match_operand 0 "" ""))
(pc)))
- (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
+ (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:DI 4 "=X,X,r"))]
- "TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:DI 4 "=X,X,&r,r"))]
+ "TARGET_64BIT"
"*
{
if (which_alternative != 0)
@@ -14552,20 +14259,20 @@
return \"{bdn|bdnz} $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
(define_insn "*ctrdi_internal6"
[(set (pc)
- (if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r")
+ (if_then_else (eq (match_operand:DI 1 "register_operand" "c,*r,*r,*r")
(const_int 1))
(pc)
(label_ref (match_operand 0 "" ""))))
- (set (match_operand:DI 2 "register_operand" "=1,*r,m*c*l")
+ (set (match_operand:DI 2 "register_operand" "=1,*r,m,*c*l")
(plus:DI (match_dup 1)
(const_int -1)))
- (clobber (match_scratch:CC 3 "=X,&x,&x"))
- (clobber (match_scratch:DI 4 "=X,X,r"))]
- "TARGET_POWERPC64"
+ (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
+ (clobber (match_scratch:DI 4 "=X,X,&r,r"))]
+ "TARGET_64BIT"
"*
{
if (which_alternative != 0)
@@ -14576,7 +14283,7 @@
return \"bdz $+8\;b %l0\";
}"
[(set_attr "type" "branch")
- (set_attr "length" "*,12,16")])
+ (set_attr "length" "*,12,16,16")])
;; Now the splitters if we could not allocate the CTR register
@@ -14592,7 +14299,7 @@
(const_int -1)))
(clobber (match_scratch:CC 3 ""))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed"
+ "TARGET_32BIT && reload_completed"
[(parallel [(set (match_dup 3)
(compare:CC (plus:SI (match_dup 1)
(const_int -1))
@@ -14618,7 +14325,7 @@
(plus:SI (match_dup 1) (const_int -1)))
(clobber (match_scratch:CC 3 ""))
(clobber (match_scratch:SI 4 ""))]
- "! TARGET_POWERPC64 && reload_completed
+ "TARGET_32BIT && reload_completed
&& ! gpc_reg_operand (operands[0], SImode)"
[(parallel [(set (match_dup 3)
(compare:CC (plus:SI (match_dup 1)
@@ -14647,7 +14354,7 @@
(const_int -1)))
(clobber (match_scratch:CC 3 ""))
(clobber (match_scratch:DI 4 ""))]
- "TARGET_POWERPC64 && reload_completed"
+ "TARGET_64BIT && reload_completed"
[(parallel [(set (match_dup 3)
(compare:CC (plus:DI (match_dup 1)
(const_int -1))
@@ -14673,7 +14380,7 @@
(plus:DI (match_dup 1) (const_int -1)))
(clobber (match_scratch:CC 3 ""))
(clobber (match_scratch:DI 4 ""))]
- "TARGET_POWERPC64 && reload_completed
+ "TARGET_64BIT && reload_completed
&& ! gpc_reg_operand (operands[0], DImode)"
[(parallel [(set (match_dup 3)
(compare:CC (plus:DI (match_dup 1)
@@ -14690,7 +14397,6 @@
"
{ operands[7] = gen_rtx (GET_CODE (operands[2]), VOIDmode, operands[3],
const0_rtx); }")
-
(define_insn "trap"
[(trap_if (const_int 1) (const_int 0))]
@@ -14733,44 +14439,70 @@
DONE;
}")
+(define_insn "*movesi_from_cr_one"
+ [(match_parallel 0 "mfcr_operation"
+ [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
+ (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
+ (match_operand 3 "immediate_operand" "n")]
+ UNSPEC_MOVESI_FROM_CR))])]
+ "TARGET_MFCRF"
+ "*
+{
+ int mask = 0;
+ int i;
+ for (i = 0; i < XVECLEN (operands[0], 0); i++)
+ {
+ mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
+ operands[4] = GEN_INT (mask);
+ output_asm_insn (\"mfcr %1,%4\", operands);
+ }
+ return \"\";
+}"
+ [(set_attr "type" "mfcrf")])
+
(define_insn "movesi_from_cr"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71)
- (reg:CC 72) (reg:CC 73) (reg:CC 74) (reg:CC 75)] 19))]
+ (reg:CC 72) (reg:CC 73) (reg:CC 74) (reg:CC 75)]
+ UNSPEC_MOVESI_FROM_CR))]
""
"mfcr %0"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "mfcr")])
(define_insn "*stmw"
- [(match_parallel 0 "stmw_operation"
- [(set (match_operand:SI 1 "memory_operand" "=m")
- (match_operand:SI 2 "gpc_reg_operand" "r"))])]
- "TARGET_MULTIPLE"
- "{stm|stmw} %2,%1")
+ [(match_parallel 0 "stmw_operation"
+ [(set (match_operand:SI 1 "memory_operand" "=m")
+ (match_operand:SI 2 "gpc_reg_operand" "r"))])]
+ "TARGET_MULTIPLE"
+ "{stm|stmw} %2,%1")
(define_insn "*save_fpregs_si"
- [(match_parallel 0 "any_operand"
- [(clobber (match_operand:SI 1 "register_operand" "=l"))
- (use (match_operand:SI 2 "call_operand" "s"))
- (set (match_operand:DF 3 "memory_operand" "=m")
- (match_operand:DF 4 "gpc_reg_operand" "f"))])]
- "TARGET_32BIT"
- "bl %z2")
+ [(match_parallel 0 "any_operand"
+ [(clobber (match_operand:SI 1 "register_operand" "=l"))
+ (use (match_operand:SI 2 "call_operand" "s"))
+ (set (match_operand:DF 3 "memory_operand" "=m")
+ (match_operand:DF 4 "gpc_reg_operand" "f"))])]
+ "TARGET_32BIT"
+ "bl %z2"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")])
(define_insn "*save_fpregs_di"
- [(match_parallel 0 "any_operand"
- [(clobber (match_operand:DI 1 "register_operand" "=l"))
- (use (match_operand:DI 2 "call_operand" "s"))
- (set (match_operand:DF 3 "memory_operand" "=m")
- (match_operand:DF 4 "gpc_reg_operand" "f"))])]
- "TARGET_64BIT"
- "bl %z2")
+ [(match_parallel 0 "any_operand"
+ [(clobber (match_operand:DI 1 "register_operand" "=l"))
+ (use (match_operand:DI 2 "call_operand" "s"))
+ (set (match_operand:DF 3 "memory_operand" "=m")
+ (match_operand:DF 4 "gpc_reg_operand" "f"))])]
+ "TARGET_64BIT"
+ "bl %z2"
+ [(set_attr "type" "branch")
+ (set_attr "length" "4")])
; These are to explain that changes to the stack pointer should
; not be moved over stores to stack memory.
(define_insn "stack_tie"
[(set (match_operand:BLK 0 "memory_operand" "+m")
- (unspec:BLK [(match_dup 0)] 5))]
+ (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
""
""
[(set_attr "length" "0")])
@@ -14792,7 +14524,7 @@
(define_expand "movsi_to_cr_one"
[(set (match_operand:CC 0 "cc_reg_operand" "=y")
(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
- (match_dup 2)] 20))]
+ (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
""
"operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
@@ -14801,7 +14533,7 @@
[(set (match_operand:CC 1 "cc_reg_operand" "=y")
(unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
(match_operand 3 "immediate_operand" "n")]
- 20))])]
+ UNSPEC_MOVESI_TO_CR))])]
""
"*
{
@@ -14812,18 +14544,19 @@
operands[4] = GEN_INT (mask);
return \"mtcrf %4,%2\";
}"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "mtcr")])
-(define_insn ""
+(define_insn "*mtcrfsi"
[(set (match_operand:CC 0 "cc_reg_operand" "=y")
(unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
- (match_operand 2 "immediate_operand" "n")] 20))]
+ (match_operand 2 "immediate_operand" "n")]
+ UNSPEC_MOVESI_TO_CR))]
"GET_CODE (operands[0]) == REG
&& CR_REGNO_P (REGNO (operands[0]))
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
"mtcrf %R0,%1"
- [(set_attr "type" "cr_logical")])
+ [(set_attr "type" "mtcr")])
; The load-multiple instructions have similar properties.
; Note that "load_multiple" is a name known to the machine-independent
@@ -14879,9 +14612,6 @@
""
"
{
-#if TARGET_AIX
- rs6000_emit_eh_toc_restore (EH_RETURN_STACKADJ_RTX);
-#endif
if (TARGET_32BIT)
emit_insn (gen_eh_set_lr_si (operands[0]));
else
@@ -14891,48 +14621,27 @@
; We can't expand this before we know where the link register is stored.
(define_insn "eh_set_lr_si"
- [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] 9)
+ [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
+ UNSPECV_EH_RR)
(clobber (match_scratch:SI 1 "=&b"))]
"TARGET_32BIT"
"#")
(define_insn "eh_set_lr_di"
- [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 9)
+ [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")]
+ UNSPECV_EH_RR)
(clobber (match_scratch:DI 1 "=&b"))]
"TARGET_64BIT"
"#")
(define_split
- [(unspec_volatile [(match_operand 0 "register_operand" "")] 9)
+ [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
(clobber (match_scratch 1 ""))]
"reload_completed"
[(const_int 0)]
"
{
- rs6000_stack_t *info = rs6000_stack_info ();
-
- if (info->lr_save_p)
- {
- rtx frame_rtx = stack_pointer_rtx;
- int sp_offset = 0;
- rtx tmp;
-
- if (frame_pointer_needed
- || current_function_calls_alloca
- || info->total_size > 32767)
- {
- emit_move_insn (operands[1], gen_rtx_MEM (Pmode, frame_rtx));
- frame_rtx = operands[1];
- }
- else if (info->push_p)
- sp_offset = info->total_size;
-
- tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
- tmp = gen_rtx_MEM (Pmode, tmp);
- emit_move_insn (tmp, operands[0]);
- }
- else
- emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
+ rs6000_emit_eh_reg_restore (operands[0], operands[1]);
DONE;
}")
diff --git a/contrib/gcc/config/rs6000/rs64.md b/contrib/gcc/config/rs6000/rs64.md
new file mode 100644
index 000000000000..4d9987523f46
--- /dev/null
+++ b/contrib/gcc/config/rs6000/rs64.md
@@ -0,0 +1,128 @@
+;; Scheduling description for IBM RS64 processors.
+;; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
+
+(define_automaton "rs64,rs64fp")
+(define_cpu_unit "iu_rs64" "rs64")
+(define_cpu_unit "mciu_rs64" "rs64")
+(define_cpu_unit "fpu_rs64" "rs64fp")
+(define_cpu_unit "lsu_rs64,bpu_rs64" "rs64")
+
+;; RS64a 64-bit IU, LSU, FPU, BPU
+
+(define_insn_reservation "rs64a-load" 2
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-store" 1
+ (and (eq_attr "type" "store,store_ux,store_u,fpstore,fpstore_ux,fpstore_u")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-fpload" 3
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-integer" 1
+ (and (eq_attr "type" "integer,insert_word")
+ (eq_attr "cpu" "rs64a"))
+ "iu_rs64")
+
+(define_insn_reservation "rs64a-imul" 20
+ (and (eq_attr "type" "imul,imul_compare")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64*13")
+
+(define_insn_reservation "rs64a-imul2" 12
+ (and (eq_attr "type" "imul2")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64*5")
+
+(define_insn_reservation "rs64a-imul3" 8
+ (and (eq_attr "type" "imul3")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64*2")
+
+(define_insn_reservation "rs64a-lmul" 34
+ (and (eq_attr "type" "lmul,lmul_compare")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64*34")
+
+(define_insn_reservation "rs64a-idiv" 66
+ (and (eq_attr "type" "idiv")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64*66")
+
+(define_insn_reservation "rs64a-ldiv" 66
+ (and (eq_attr "type" "ldiv")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64*66")
+
+(define_insn_reservation "rs64a-compare" 3
+ (and (eq_attr "type" "cmp,fast_compare,compare,delayed_compare")
+ (eq_attr "cpu" "rs64a"))
+ "iu_rs64,nothing,bpu_rs64")
+
+(define_insn_reservation "rs64a-fpcompare" 5
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64,fpu_rs64,bpu_rs64")
+
+(define_insn_reservation "rs64a-fp" 4
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64,fpu_rs64")
+
+(define_insn_reservation "rs64a-sdiv" 31
+ (and (eq_attr "type" "sdiv,ddiv")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64,fpu_rs64*31")
+
+(define_insn_reservation "rs64a-sqrt" 49
+ (and (eq_attr "type" "ssqrt,dsqrt")
+ (eq_attr "cpu" "rs64a"))
+ "mciu_rs64,fpu_rs64*49")
+
+(define_insn_reservation "rs64a-mfcr" 2
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-mtcr" 3
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-mtjmpr" 3
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-mfjmpr" 2
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
+(define_insn_reservation "rs64a-jmpreg" 1
+ (and (eq_attr "type" "jmpreg,branch,cr_logical,delayed_cr")
+ (eq_attr "cpu" "rs64a"))
+ "bpu_rs64")
+
diff --git a/contrib/gcc/config/rs6000/rtems.h b/contrib/gcc/config/rs6000/rtems.h
index 7e7584604e9f..0245269203be 100644
--- a/contrib/gcc/config/rs6000/rtems.h
+++ b/contrib/gcc/config/rs6000/rtems.h
@@ -2,22 +2,22 @@
Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Joel Sherrill (joel@OARcorp.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Specify predefined symbols in preprocessor. */
@@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */
builtin_assert ("system=rtems"); \
builtin_assert ("cpu=powerpc"); \
builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
} \
while (0)
diff --git a/contrib/gcc/config/rs6000/sol-ci.asm b/contrib/gcc/config/rs6000/sol-ci.asm
index b1689605cc97..cc97b0ac6f52 100644
--- a/contrib/gcc/config/rs6000/sol-ci.asm
+++ b/contrib/gcc/config/rs6000/sol-ci.asm
@@ -39,6 +39,7 @@
.file "scrti.s"
.ident "GNU C scrti.s"
+#ifndef __powerpc64__
# Start of .text
.section ".text"
.globl _ex_text0
@@ -102,3 +103,4 @@ _fini: stwu %r1,-16(%r1)
.space 4
.weak environ
.set environ,_environ
+#endif
diff --git a/contrib/gcc/config/rs6000/sol-cn.asm b/contrib/gcc/config/rs6000/sol-cn.asm
index b1da7d7b6fb2..673540f7a1eb 100644
--- a/contrib/gcc/config/rs6000/sol-cn.asm
+++ b/contrib/gcc/config/rs6000/sol-cn.asm
@@ -39,6 +39,7 @@
.file "scrtn.s"
.ident "GNU C scrtn.s"
+#ifndef __powerpc64__
# Default versions of exception handling register/deregister
.weak _ex_register
.weak _ex_deregister
@@ -80,3 +81,4 @@ _ex_range1:
mtlr %r0
addi %r1,%r1,16
blr
+#endif
diff --git a/contrib/gcc/config/rs6000/spe.h b/contrib/gcc/config/rs6000/spe.h
index b15dac5a38b8..16765161fdea 100644
--- a/contrib/gcc/config/rs6000/spe.h
+++ b/contrib/gcc/config/rs6000/spe.h
@@ -2,22 +2,22 @@
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* As a special exception, if you include this header file into source
files compiled by GCC, this header file does not by itself cause
@@ -45,242 +45,239 @@ typedef unsigned __vector __ev64_u32__;
typedef long long __vector __ev64_s64__;
typedef unsigned long long __vector __ev64_u64__;
typedef float __vector __ev64_fs__;
-typedef int __vector __ev64_opaque__;
#define __v2si __ev64_opaque__
#define __v2sf __ev64_fs__
-#define __ev_addw(a,b) __builtin_spe_evaddw((__v2si) (a), (__v2si) (b))
-#define __ev_addiw(a,b) __builtin_spe_evaddiw ((__v2si) (a), (b))
-#define __ev_subfw(a,b) __builtin_spe_evsubfw ((__v2si) (a), (__v2si) (b))
-#define __ev_subw(a,b) __builtin_spe_evsubfw ((__v2si) (b), (__v2si) (a))
-/* ??? The spe_evsubifw pattern accepts operands reversed, so we need to also
- reverse them here between the intrinsic and the builtin function. */
-#define __ev_subifw(a,b) __builtin_spe_evsubifw ((__v2si) (b), (a))
-#define __ev_subiw(a,b) __builtin_spe_evsubifw ((__v2si) (a), (b))
-#define __ev_abs(a) __builtin_spe_evabs ((__v2si) (a))
-#define __ev_neg(a) __builtin_spe_evneg ((__v2si) (a))
-#define __ev_extsb(a) __builtin_spe_evextsb ((__v2si) (a))
-#define __ev_extsh(a) __builtin_spe_evextsh ((__v2si) (a))
-#define __ev_and(a,b) __builtin_spe_evand ((__v2si) (a), (__v2si) (b))
-#define __ev_or(a,b) __builtin_spe_evor ((__v2si) (a), (__v2si) (b))
-#define __ev_xor(a,b) __builtin_spe_evxor ((__v2si) (a), (__v2si) (b))
-#define __ev_nand(a,b) __builtin_spe_evnand ((__v2si) (a), (__v2si) (b))
-#define __ev_nor(a,b) __builtin_spe_evnor ((__v2si) (a), (__v2si) (b))
-#define __ev_eqv(a,b) __builtin_spe_eveqv ((__v2si) (a), (__v2si) (b))
-#define __ev_andc(a,b) __builtin_spe_evandc ((__v2si) (a), (__v2si) (b))
-#define __ev_orc(a,b) __builtin_spe_evorc ((__v2si) (a), (__v2si) (b))
-#define __ev_rlw(a,b) __builtin_spe_evrlw ((__v2si) (a), (__v2si) (b))
-#define __ev_rlwi(a,b) __builtin_spe_evrlwi ((__v2si) (a), (b))
-#define __ev_slw(a,b) __builtin_spe_evslw ((__v2si) (a), (__v2si) (b))
-#define __ev_slwi(a,b) __builtin_spe_evslwi ((__v2si) (a), (b))
-#define __ev_srws(a,b) __builtin_spe_evsrws ((__v2si) (a), (__v2si) (b))
-#define __ev_srwu(a,b) __builtin_spe_evsrwu ((__v2si) (a), (__v2si) (b))
-#define __ev_srwis(a,b) __builtin_spe_evsrwis ((__v2si) (a), (b))
-#define __ev_srwiu(a,b) __builtin_spe_evsrwiu ((__v2si) (a), (b))
-#define __ev_cntlzw(a) __builtin_spe_evcntlzw ((__v2si) (a))
-#define __ev_cntlsw(a) __builtin_spe_evcntlsw ((__v2si) (a))
-#define __ev_rndw(a) __builtin_spe_evrndw ((__v2si) (a))
-#define __ev_mergehi(a,b) __builtin_spe_evmergehi ((__v2si) (a), (__v2si) (b))
-#define __ev_mergelo(a,b) __builtin_spe_evmergelo ((__v2si) (a), (__v2si) (b))
-#define __ev_mergelohi(a,b) __builtin_spe_evmergelohi ((__v2si) (a), (__v2si) (b))
-#define __ev_mergehilo(a,b) __builtin_spe_evmergehilo ((__v2si) (a), (__v2si) (b))
-#define __ev_splati(a) __builtin_spe_evsplati ((a))
-#define __ev_splatfi(a) __builtin_spe_evsplatfi ((a))
-#define __ev_divws(a,b) __builtin_spe_evdivws ((__v2si) (a), (__v2si) (b))
-#define __ev_divwu(a,b) __builtin_spe_evdivwu ((__v2si) (a), (__v2si) (b))
-#define __ev_mra(a) __builtin_spe_evmra ((__v2si) (a))
+#define __ev_addw __builtin_spe_evaddw
+#define __ev_addiw __builtin_spe_evaddiw
+#define __ev_subfw(a,b) __builtin_spe_evsubfw ((b), (a))
+#define __ev_subw __builtin_spe_evsubfw
+#define __ev_subifw(a,b) __builtin_spe_evsubifw ((b), (a))
+#define __ev_subiw __builtin_spe_evsubifw
+#define __ev_abs __builtin_spe_evabs
+#define __ev_neg __builtin_spe_evneg
+#define __ev_extsb __builtin_spe_evextsb
+#define __ev_extsh __builtin_spe_evextsh
+#define __ev_and __builtin_spe_evand
+#define __ev_or __builtin_spe_evor
+#define __ev_xor __builtin_spe_evxor
+#define __ev_nand __builtin_spe_evnand
+#define __ev_nor __builtin_spe_evnor
+#define __ev_eqv __builtin_spe_eveqv
+#define __ev_andc __builtin_spe_evandc
+#define __ev_orc __builtin_spe_evorc
+#define __ev_rlw __builtin_spe_evrlw
+#define __ev_rlwi __builtin_spe_evrlwi
+#define __ev_slw __builtin_spe_evslw
+#define __ev_slwi __builtin_spe_evslwi
+#define __ev_srws __builtin_spe_evsrws
+#define __ev_srwu __builtin_spe_evsrwu
+#define __ev_srwis __builtin_spe_evsrwis
+#define __ev_srwiu __builtin_spe_evsrwiu
+#define __ev_cntlzw __builtin_spe_evcntlzw
+#define __ev_cntlsw __builtin_spe_evcntlsw
+#define __ev_rndw __builtin_spe_evrndw
+#define __ev_mergehi __builtin_spe_evmergehi
+#define __ev_mergelo __builtin_spe_evmergelo
+#define __ev_mergelohi __builtin_spe_evmergelohi
+#define __ev_mergehilo __builtin_spe_evmergehilo
+#define __ev_splati __builtin_spe_evsplati
+#define __ev_splatfi __builtin_spe_evsplatfi
+#define __ev_divws __builtin_spe_evdivws
+#define __ev_divwu __builtin_spe_evdivwu
+#define __ev_mra __builtin_spe_evmra
#define __brinc __builtin_spe_brinc
/* Loads. */
-#define __ev_lddx(a,b) __builtin_spe_evlddx ((void *)(a), (b))
-#define __ev_ldwx(a,b) __builtin_spe_evldwx ((void *)(a), (b))
-#define __ev_ldhx(a,b) __builtin_spe_evldhx ((void *)(a), (b))
-#define __ev_lwhex(a,b) __builtin_spe_evlwhex ((a), (b))
-#define __ev_lwhoux(a,b) __builtin_spe_evlwhoux ((a), (b))
-#define __ev_lwhosx(a,b) __builtin_spe_evlwhosx ((a), (b))
-#define __ev_lwwsplatx(a,b) __builtin_spe_evlwwsplatx ((a), (b))
-#define __ev_lwhsplatx(a,b) __builtin_spe_evlwhsplatx ((a), (b))
-#define __ev_lhhesplatx(a,b) __builtin_spe_evlhhesplatx ((a), (b))
-#define __ev_lhhousplatx(a,b) __builtin_spe_evlhhousplatx ((a), (b))
-#define __ev_lhhossplatx(a,b) __builtin_spe_evlhhossplatx ((a), (b))
-#define __ev_ldd(a,b) __builtin_spe_evldd ((void *)(a), (b))
-#define __ev_ldw(a,b) __builtin_spe_evldw ((void *)(a), (b))
-#define __ev_ldh(a,b) __builtin_spe_evldh ((void *)(a), (b))
-#define __ev_lwhe(a,b) __builtin_spe_evlwhe ((a), (b))
-#define __ev_lwhou(a,b) __builtin_spe_evlwhou ((a), (b))
-#define __ev_lwhos(a,b) __builtin_spe_evlwhos ((a), (b))
-#define __ev_lwwsplat(a,b) __builtin_spe_evlwwsplat ((a), (b))
-#define __ev_lwhsplat(a,b) __builtin_spe_evlwhsplat ((a), (b))
-#define __ev_lhhesplat(a,b) __builtin_spe_evlhhesplat ((a), (b))
-#define __ev_lhhousplat(a,b) __builtin_spe_evlhhousplat ((a), (b))
-#define __ev_lhhossplat(a,b) __builtin_spe_evlhhossplat ((a), (b))
+#define __ev_lddx __builtin_spe_evlddx
+#define __ev_ldwx __builtin_spe_evldwx
+#define __ev_ldhx __builtin_spe_evldhx
+#define __ev_lwhex __builtin_spe_evlwhex
+#define __ev_lwhoux __builtin_spe_evlwhoux
+#define __ev_lwhosx __builtin_spe_evlwhosx
+#define __ev_lwwsplatx __builtin_spe_evlwwsplatx
+#define __ev_lwhsplatx __builtin_spe_evlwhsplatx
+#define __ev_lhhesplatx __builtin_spe_evlhhesplatx
+#define __ev_lhhousplatx __builtin_spe_evlhhousplatx
+#define __ev_lhhossplatx __builtin_spe_evlhhossplatx
+#define __ev_ldd __builtin_spe_evldd
+#define __ev_ldw __builtin_spe_evldw
+#define __ev_ldh __builtin_spe_evldh
+#define __ev_lwhe __builtin_spe_evlwhe
+#define __ev_lwhou __builtin_spe_evlwhou
+#define __ev_lwhos __builtin_spe_evlwhos
+#define __ev_lwwsplat __builtin_spe_evlwwsplat
+#define __ev_lwhsplat __builtin_spe_evlwhsplat
+#define __ev_lhhesplat __builtin_spe_evlhhesplat
+#define __ev_lhhousplat __builtin_spe_evlhhousplat
+#define __ev_lhhossplat __builtin_spe_evlhhossplat
/* Stores. */
-#define __ev_stddx(a,b,c) __builtin_spe_evstddx ((__v2si)(a), (void *)(b), (c))
-#define __ev_stdwx(a,b,c) __builtin_spe_evstdwx ((__v2si)(a), (void *)(b), (c))
-#define __ev_stdhx(a,b,c) __builtin_spe_evstdhx ((__v2si)(a), (void *)(b), (c))
-#define __ev_stwwex(a,b,c) __builtin_spe_evstwwex ((__v2si)(a), (b), (c))
-#define __ev_stwwox(a,b,c) __builtin_spe_evstwwox ((__v2si)(a), (b), (c))
-#define __ev_stwhex(a,b,c) __builtin_spe_evstwhex ((__v2si)(a), (b), (c))
-#define __ev_stwhox(a,b,c) __builtin_spe_evstwhox ((__v2si)(a), (b), (c))
-#define __ev_stdd(a,b,c) __builtin_spe_evstdd ((__v2si)(a), (void *)(b), (c))
-#define __ev_stdw(a,b,c) __builtin_spe_evstdw ((__v2si)(a), (void *)(b), (c))
-#define __ev_stdh(a,b,c) __builtin_spe_evstdh ((__v2si)(a), (void *)(b), (c))
-#define __ev_stwwe(a,b,c) __builtin_spe_evstwwe ((__v2si)(a), (b), (c))
-#define __ev_stwwo(a,b,c) __builtin_spe_evstwwo ((__v2si)(a), (b), (c))
-#define __ev_stwhe(a,b,c) __builtin_spe_evstwhe ((__v2si)(a), (b), (c))
-#define __ev_stwho(a,b,c) __builtin_spe_evstwho ((__v2si)(a), (b), (c))
+#define __ev_stddx __builtin_spe_evstddx
+#define __ev_stdwx __builtin_spe_evstdwx
+#define __ev_stdhx __builtin_spe_evstdhx
+#define __ev_stwwex __builtin_spe_evstwwex
+#define __ev_stwwox __builtin_spe_evstwwox
+#define __ev_stwhex __builtin_spe_evstwhex
+#define __ev_stwhox __builtin_spe_evstwhox
+#define __ev_stdd __builtin_spe_evstdd
+#define __ev_stdw __builtin_spe_evstdw
+#define __ev_stdh __builtin_spe_evstdh
+#define __ev_stwwe __builtin_spe_evstwwe
+#define __ev_stwwo __builtin_spe_evstwwo
+#define __ev_stwhe __builtin_spe_evstwhe
+#define __ev_stwho __builtin_spe_evstwho
/* Fixed point complex. */
-#define __ev_mhossf(a, b) __builtin_spe_evmhossf ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmf(a, b) __builtin_spe_evmhosmf ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmi(a, b) __builtin_spe_evmhosmi ((__v2si) (a), (__v2si) (b))
-#define __ev_mhoumi(a, b) __builtin_spe_evmhoumi ((__v2si) (a), (__v2si) (b))
-#define __ev_mhessf(a, b) __builtin_spe_evmhessf ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmf(a, b) __builtin_spe_evmhesmf ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmi(a, b) __builtin_spe_evmhesmi ((__v2si) (a), (__v2si) (b))
-#define __ev_mheumi(a, b) __builtin_spe_evmheumi ((__v2si) (a), (__v2si) (b))
-#define __ev_mhossfa(a, b) __builtin_spe_evmhossfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmfa(a, b) __builtin_spe_evmhosmfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmia(a, b) __builtin_spe_evmhosmia ((__v2si) (a), (__v2si) (b))
-#define __ev_mhoumia(a, b) __builtin_spe_evmhoumia ((__v2si) (a), (__v2si) (b))
-#define __ev_mhessfa(a, b) __builtin_spe_evmhessfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmfa(a, b) __builtin_spe_evmhesmfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmia(a, b) __builtin_spe_evmhesmia ((__v2si) (a), (__v2si) (b))
-#define __ev_mheumia(a, b) __builtin_spe_evmheumia ((__v2si) (a), (__v2si) (b))
+#define __ev_mhossf __builtin_spe_evmhossf
+#define __ev_mhosmf __builtin_spe_evmhosmf
+#define __ev_mhosmi __builtin_spe_evmhosmi
+#define __ev_mhoumi __builtin_spe_evmhoumi
+#define __ev_mhessf __builtin_spe_evmhessf
+#define __ev_mhesmf __builtin_spe_evmhesmf
+#define __ev_mhesmi __builtin_spe_evmhesmi
+#define __ev_mheumi __builtin_spe_evmheumi
+#define __ev_mhossfa __builtin_spe_evmhossfa
+#define __ev_mhosmfa __builtin_spe_evmhosmfa
+#define __ev_mhosmia __builtin_spe_evmhosmia
+#define __ev_mhoumia __builtin_spe_evmhoumia
+#define __ev_mhessfa __builtin_spe_evmhessfa
+#define __ev_mhesmfa __builtin_spe_evmhesmfa
+#define __ev_mhesmia __builtin_spe_evmhesmia
+#define __ev_mheumia __builtin_spe_evmheumia
#define __ev_mhoumf __ev_mhoumi
#define __ev_mheumf __ev_mheumi
#define __ev_mhoumfa __ev_mhoumia
#define __ev_mheumfa __ev_mheumia
-#define __ev_mhossfaaw(a, b) __builtin_spe_evmhossfaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhossiaaw(a, b) __builtin_spe_evmhossiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmfaaw(a, b) __builtin_spe_evmhosmfaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmiaaw(a, b) __builtin_spe_evmhosmiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhousiaaw(a, b) __builtin_spe_evmhousiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhoumiaaw(a, b) __builtin_spe_evmhoumiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhessfaaw(a, b) __builtin_spe_evmhessfaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhessiaaw(a, b) __builtin_spe_evmhessiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmfaaw(a, b) __builtin_spe_evmhesmfaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmiaaw(a, b) __builtin_spe_evmhesmiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mheusiaaw(a, b) __builtin_spe_evmheusiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mheumiaaw(a, b) __builtin_spe_evmheumiaaw ((__v2si) (a), (__v2si) (b))
+#define __ev_mhossfaaw __builtin_spe_evmhossfaaw
+#define __ev_mhossiaaw __builtin_spe_evmhossiaaw
+#define __ev_mhosmfaaw __builtin_spe_evmhosmfaaw
+#define __ev_mhosmiaaw __builtin_spe_evmhosmiaaw
+#define __ev_mhousiaaw __builtin_spe_evmhousiaaw
+#define __ev_mhoumiaaw __builtin_spe_evmhoumiaaw
+#define __ev_mhessfaaw __builtin_spe_evmhessfaaw
+#define __ev_mhessiaaw __builtin_spe_evmhessiaaw
+#define __ev_mhesmfaaw __builtin_spe_evmhesmfaaw
+#define __ev_mhesmiaaw __builtin_spe_evmhesmiaaw
+#define __ev_mheusiaaw __builtin_spe_evmheusiaaw
+#define __ev_mheumiaaw __builtin_spe_evmheumiaaw
#define __ev_mhousfaaw __ev_mhousiaaw
#define __ev_mhoumfaaw __ev_mhoumiaaw
#define __ev_mheusfaaw __ev_mheusiaaw
#define __ev_mheumfaaw __ev_mheumiaaw
-#define __ev_mhossfanw(a, b) __builtin_spe_evmhossfanw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhossianw(a, b) __builtin_spe_evmhossianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmfanw(a, b) __builtin_spe_evmhosmfanw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhosmianw(a, b) __builtin_spe_evmhosmianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhousianw(a, b) __builtin_spe_evmhousianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhoumianw(a, b) __builtin_spe_evmhoumianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhessfanw(a, b) __builtin_spe_evmhessfanw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhessianw(a, b) __builtin_spe_evmhessianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmfanw(a, b) __builtin_spe_evmhesmfanw ((__v2si) (a), (__v2si) (b))
-#define __ev_mhesmianw(a, b) __builtin_spe_evmhesmianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mheusianw(a, b) __builtin_spe_evmheusianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mheumianw(a, b) __builtin_spe_evmheumianw ((__v2si) (a), (__v2si) (b))
+#define __ev_mhossfanw __builtin_spe_evmhossfanw
+#define __ev_mhossianw __builtin_spe_evmhossianw
+#define __ev_mhosmfanw __builtin_spe_evmhosmfanw
+#define __ev_mhosmianw __builtin_spe_evmhosmianw
+#define __ev_mhousianw __builtin_spe_evmhousianw
+#define __ev_mhoumianw __builtin_spe_evmhoumianw
+#define __ev_mhessfanw __builtin_spe_evmhessfanw
+#define __ev_mhessianw __builtin_spe_evmhessianw
+#define __ev_mhesmfanw __builtin_spe_evmhesmfanw
+#define __ev_mhesmianw __builtin_spe_evmhesmianw
+#define __ev_mheusianw __builtin_spe_evmheusianw
+#define __ev_mheumianw __builtin_spe_evmheumianw
#define __ev_mhousfanw __ev_mhousianw
#define __ev_mhoumfanw __ev_mhoumianw
#define __ev_mheusfanw __ev_mheusianw
#define __ev_mheumfanw __ev_mheumianw
-#define __ev_mhogsmfaa(a, b) __builtin_spe_evmhogsmfaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhogsmiaa(a, b) __builtin_spe_evmhogsmiaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhogumiaa(a, b) __builtin_spe_evmhogumiaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhegsmfaa(a, b) __builtin_spe_evmhegsmfaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhegsmiaa(a, b) __builtin_spe_evmhegsmiaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mhegumiaa(a, b) __builtin_spe_evmhegumiaa ((__v2si) (a), (__v2si) (b))
+#define __ev_mhogsmfaa __builtin_spe_evmhogsmfaa
+#define __ev_mhogsmiaa __builtin_spe_evmhogsmiaa
+#define __ev_mhogumiaa __builtin_spe_evmhogumiaa
+#define __ev_mhegsmfaa __builtin_spe_evmhegsmfaa
+#define __ev_mhegsmiaa __builtin_spe_evmhegsmiaa
+#define __ev_mhegumiaa __builtin_spe_evmhegumiaa
#define __ev_mhogumfaa __ev_mhogumiaa
#define __ev_mhegumfaa __ev_mhegumiaa
-#define __ev_mhogsmfan(a, b) __builtin_spe_evmhogsmfan ((__v2si) (a), (__v2si) (b))
-#define __ev_mhogsmian(a, b) __builtin_spe_evmhogsmian ((__v2si) (a), (__v2si) (b))
-#define __ev_mhogumian(a, b) __builtin_spe_evmhogumian ((__v2si) (a), (__v2si) (b))
-#define __ev_mhegsmfan(a, b) __builtin_spe_evmhegsmfan ((__v2si) (a), (__v2si) (b))
-#define __ev_mhegsmian(a, b) __builtin_spe_evmhegsmian ((__v2si) (a), (__v2si) (b))
-#define __ev_mhegumian(a, b) __builtin_spe_evmhegumian ((__v2si) (a), (__v2si) (b))
+#define __ev_mhogsmfan __builtin_spe_evmhogsmfan
+#define __ev_mhogsmian __builtin_spe_evmhogsmian
+#define __ev_mhogumian __builtin_spe_evmhogumian
+#define __ev_mhegsmfan __builtin_spe_evmhegsmfan
+#define __ev_mhegsmian __builtin_spe_evmhegsmian
+#define __ev_mhegumian __builtin_spe_evmhegumian
#define __ev_mhogumfan __ev_mhogumian
#define __ev_mhegumfan __ev_mhegumian
-#define __ev_mwhssf(a, b) __builtin_spe_evmwhssf ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmf(a, b) __builtin_spe_evmwhsmf ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmi(a, b) __builtin_spe_evmwhsmi ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhumi(a, b) __builtin_spe_evmwhumi ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhssfa(a, b) __builtin_spe_evmwhssfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmfa(a, b) __builtin_spe_evmwhsmfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmia(a, b) __builtin_spe_evmwhsmia ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhumia(a, b) __builtin_spe_evmwhumia ((__v2si) (a), (__v2si) (b))
+#define __ev_mwhssf __builtin_spe_evmwhssf
+#define __ev_mwhsmf __builtin_spe_evmwhsmf
+#define __ev_mwhsmi __builtin_spe_evmwhsmi
+#define __ev_mwhumi __builtin_spe_evmwhumi
+#define __ev_mwhssfa __builtin_spe_evmwhssfa
+#define __ev_mwhsmfa __builtin_spe_evmwhsmfa
+#define __ev_mwhsmia __builtin_spe_evmwhsmia
+#define __ev_mwhumia __builtin_spe_evmwhumia
#define __ev_mwhumf __ev_mwhumi
#define __ev_mwhumfa __ev_mwhumia
-#define __ev_mwlumi(a, b) __builtin_spe_evmwlumi ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlumia(a, b) __builtin_spe_evmwlumia ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlumiaaw(a, b) __builtin_spe_evmwlumiaaw ((__v2si) (a), (__v2si) (b))
-
-#define __ev_mwlssiaaw(a, b) __builtin_spe_evmwlssiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlsmiaaw(a, b) __builtin_spe_evmwlsmiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlusiaaw(a, b) __builtin_spe_evmwlusiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlusiaaw(a, b) __builtin_spe_evmwlusiaaw ((__v2si) (a), (__v2si) (b))
-
-#define __ev_mwlssianw(a, b) __builtin_spe_evmwlssianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlsmianw(a, b) __builtin_spe_evmwlsmianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlusianw(a, b) __builtin_spe_evmwlusianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwlumianw(a, b) __builtin_spe_evmwlumianw ((__v2si) (a), (__v2si) (b))
-
-#define __ev_mwssf(a, b) __builtin_spe_evmwssf ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmf(a, b) __builtin_spe_evmwsmf ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmi(a, b) __builtin_spe_evmwsmi ((__v2si) (a), (__v2si) (b))
-#define __ev_mwumi(a, b) __builtin_spe_evmwumi ((__v2si) (a), (__v2si) (b))
-#define __ev_mwssfa(a, b) __builtin_spe_evmwssfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmfa(a, b) __builtin_spe_evmwsmfa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmia(a, b) __builtin_spe_evmwsmia ((__v2si) (a), (__v2si) (b))
-#define __ev_mwumia(a, b) __builtin_spe_evmwumia ((__v2si) (a), (__v2si) (b))
+#define __ev_mwlumi __builtin_spe_evmwlumi
+#define __ev_mwlumia __builtin_spe_evmwlumia
+#define __ev_mwlumiaaw __builtin_spe_evmwlumiaaw
+
+#define __ev_mwlssiaaw __builtin_spe_evmwlssiaaw
+#define __ev_mwlsmiaaw __builtin_spe_evmwlsmiaaw
+#define __ev_mwlusiaaw __builtin_spe_evmwlusiaaw
+#define __ev_mwlusiaaw __builtin_spe_evmwlusiaaw
+
+#define __ev_mwlssianw __builtin_spe_evmwlssianw
+#define __ev_mwlsmianw __builtin_spe_evmwlsmianw
+#define __ev_mwlusianw __builtin_spe_evmwlusianw
+#define __ev_mwlumianw __builtin_spe_evmwlumianw
+
+#define __ev_mwssf __builtin_spe_evmwssf
+#define __ev_mwsmf __builtin_spe_evmwsmf
+#define __ev_mwsmi __builtin_spe_evmwsmi
+#define __ev_mwumi __builtin_spe_evmwumi
+#define __ev_mwssfa __builtin_spe_evmwssfa
+#define __ev_mwsmfa __builtin_spe_evmwsmfa
+#define __ev_mwsmia __builtin_spe_evmwsmia
+#define __ev_mwumia __builtin_spe_evmwumia
#define __ev_mwumf __ev_mwumi
#define __ev_mwumfa __ev_mwumia
-#define __ev_mwssfaa(a, b) __builtin_spe_evmwssfaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmfaa(a, b) __builtin_spe_evmwsmfaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmiaa(a, b) __builtin_spe_evmwsmiaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwumiaa(a, b) __builtin_spe_evmwumiaa ((__v2si) (a), (__v2si) (b))
+#define __ev_mwssfaa __builtin_spe_evmwssfaa
+#define __ev_mwsmfaa __builtin_spe_evmwsmfaa
+#define __ev_mwsmiaa __builtin_spe_evmwsmiaa
+#define __ev_mwumiaa __builtin_spe_evmwumiaa
#define __ev_mwumfaa __ev_mwumiaa
-#define __ev_mwssfan(a, b) __builtin_spe_evmwssfan ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmfan(a, b) __builtin_spe_evmwsmfan ((__v2si) (a), (__v2si) (b))
-#define __ev_mwsmian(a, b) __builtin_spe_evmwsmian ((__v2si) (a), (__v2si) (b))
-#define __ev_mwumian(a, b) __builtin_spe_evmwumian ((__v2si) (a), (__v2si) (b))
+#define __ev_mwssfan __builtin_spe_evmwssfan
+#define __ev_mwsmfan __builtin_spe_evmwsmfan
+#define __ev_mwsmian __builtin_spe_evmwsmian
+#define __ev_mwumian __builtin_spe_evmwumian
#define __ev_mwumfan __ev_mwumian
-#define __ev_addssiaaw(a) __builtin_spe_evaddssiaaw ((__v2si) (a))
-#define __ev_addsmiaaw(a) __builtin_spe_evaddsmiaaw ((__v2si) (a))
-#define __ev_addusiaaw(a) __builtin_spe_evaddusiaaw ((__v2si) (a))
-#define __ev_addumiaaw(a) __builtin_spe_evaddumiaaw ((__v2si) (a))
+#define __ev_addssiaaw __builtin_spe_evaddssiaaw
+#define __ev_addsmiaaw __builtin_spe_evaddsmiaaw
+#define __ev_addusiaaw __builtin_spe_evaddusiaaw
+#define __ev_addumiaaw __builtin_spe_evaddumiaaw
#define __ev_addusfaaw __ev_addusiaaw
#define __ev_addumfaaw __ev_addumiaaw
#define __ev_addsmfaaw __ev_addsmiaaw
#define __ev_addssfaaw __ev_addssiaaw
-#define __ev_subfssiaaw(a) __builtin_spe_evsubfssiaaw ((__v2si) (a))
-#define __ev_subfsmiaaw(a) __builtin_spe_evsubfsmiaaw ((__v2si) (a))
-#define __ev_subfusiaaw(a) __builtin_spe_evsubfusiaaw ((__v2si) (a))
-#define __ev_subfumiaaw(a) __builtin_spe_evsubfumiaaw ((__v2si) (a))
+#define __ev_subfssiaaw __builtin_spe_evsubfssiaaw
+#define __ev_subfsmiaaw __builtin_spe_evsubfsmiaaw
+#define __ev_subfusiaaw __builtin_spe_evsubfusiaaw
+#define __ev_subfumiaaw __builtin_spe_evsubfumiaaw
#define __ev_subfusfaaw __ev_subfusiaaw
#define __ev_subfumfaaw __ev_subfumiaaw
@@ -289,26 +286,23 @@ typedef int __vector __ev64_opaque__;
/* Floating Point SIMD Instructions */
-/* These all return V2SF, but we need to cast them to V2SI
- because the SPE expect all functions to be __ev64_opaque__. */
-
-#define __ev_fsabs(a) ((__v2si) __builtin_spe_evfsabs ((__v2sf) (a)))
-#define __ev_fsnabs(a) ((__v2si) __builtin_spe_evfsnabs ((__v2sf) (a)))
-#define __ev_fsneg(a) ((__v2si) __builtin_spe_evfsneg ((__v2sf) (a)))
-#define __ev_fsadd(a, b) ((__v2si) __builtin_spe_evfsadd ((__v2sf) (a), (__v2sf) (b)))
-#define __ev_fssub(a, b) ((__v2si) __builtin_spe_evfssub ((__v2sf) (a), (__v2sf) (b)))
-#define __ev_fsmul(a, b) ((__v2si) __builtin_spe_evfsmul ((__v2sf) (a), (__v2sf) b))
-#define __ev_fsdiv(a, b) ((__v2si) __builtin_spe_evfsdiv ((__v2sf) (a), (__v2sf) b))
-#define __ev_fscfui(a) ((__v2si) __builtin_spe_evfscfui ((__v2si) (a)))
-#define __ev_fscfsi(a) ((__v2si) __builtin_spe_evfscfsi ((__v2sf) (a)))
-#define __ev_fscfuf(a) ((__v2si) __builtin_spe_evfscfuf ((__v2sf) (a)))
-#define __ev_fscfsf(a) ((__v2si) __builtin_spe_evfscfsf ((__v2sf) (a)))
-#define __ev_fsctui(a) ((__v2si) __builtin_spe_evfsctui ((__v2sf) (a)))
-#define __ev_fsctsi(a) ((__v2si) __builtin_spe_evfsctsi ((__v2sf) (a)))
-#define __ev_fsctuf(a) ((__v2si) __builtin_spe_evfsctuf ((__v2sf) (a)))
-#define __ev_fsctsf(a) ((__v2si) __builtin_spe_evfsctsf ((__v2sf) (a)))
-#define __ev_fsctuiz(a) ((__v2si) __builtin_spe_evfsctuiz ((__v2sf) (a)))
-#define __ev_fsctsiz(a) ((__v2si) __builtin_spe_evfsctsiz ((__v2sf) (a)))
+#define __ev_fsabs __builtin_spe_evfsabs
+#define __ev_fsnabs __builtin_spe_evfsnabs
+#define __ev_fsneg __builtin_spe_evfsneg
+#define __ev_fsadd __builtin_spe_evfsadd
+#define __ev_fssub __builtin_spe_evfssub
+#define __ev_fsmul __builtin_spe_evfsmul
+#define __ev_fsdiv __builtin_spe_evfsdiv
+#define __ev_fscfui __builtin_spe_evfscfui
+#define __ev_fscfsi __builtin_spe_evfscfsi
+#define __ev_fscfuf __builtin_spe_evfscfuf
+#define __ev_fscfsf __builtin_spe_evfscfsf
+#define __ev_fsctui __builtin_spe_evfsctui
+#define __ev_fsctsi __builtin_spe_evfsctsi
+#define __ev_fsctuf __builtin_spe_evfsctuf
+#define __ev_fsctsf __builtin_spe_evfsctsf
+#define __ev_fsctuiz __builtin_spe_evfsctuiz
+#define __ev_fsctsiz __builtin_spe_evfsctsiz
/* NOT SUPPORTED IN FIRST e500, support via two instructions: */
@@ -319,26 +313,26 @@ typedef int __vector __ev64_opaque__;
#define __ev_mwhgumfaa __ev_mwhgumiaa
#define __ev_mwhgumfan __ev_mwhgumian
-#define __ev_mwhgssfaa(a, b) __internal_ev_mwhgssfaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgsmfaa(a, b) __internal_ev_mwhgsmfaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgsmiaa(a, b) __internal_ev_mwhgsmiaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgumiaa(a, b) __internal_ev_mwhgumiaa ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgssfan(a, b) __internal_ev_mwhgssfan ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgsmfan(a, b) __internal_ev_mwhgsmfan ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgsmian(a, b) __internal_ev_mwhgsmian ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhgumian(a, b) __internal_ev_mwhgumian ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhssiaaw(a, b) __internal_ev_mwhssiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhssfaaw(a, b) __internal_ev_mwhssfaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmfaaw(a, b) __internal_ev_mwhsmfaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmiaaw(a, b) __internal_ev_mwhsmiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhusiaaw(a, b) __internal_ev_mwhusiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhumiaaw(a, b) __internal_ev_mwhumiaaw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhssfanw(a, b) __internal_ev_mwhssfanw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhssianw(a, b) __internal_ev_mwhssianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmfanw(a, b) __internal_ev_mwhsmfanw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhsmianw(a, b) __internal_ev_mwhsmianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhusianw(a, b) __internal_ev_mwhusianw ((__v2si) (a), (__v2si) (b))
-#define __ev_mwhumianw(a, b) __internal_ev_mwhumianw ((__v2si) (a), (__v2si) (b))
+#define __ev_mwhgssfaa __internal_ev_mwhgssfaa
+#define __ev_mwhgsmfaa __internal_ev_mwhgsmfaa
+#define __ev_mwhgsmiaa __internal_ev_mwhgsmiaa
+#define __ev_mwhgumiaa __internal_ev_mwhgumiaa
+#define __ev_mwhgssfan __internal_ev_mwhgssfan
+#define __ev_mwhgsmfan __internal_ev_mwhgsmfan
+#define __ev_mwhgsmian __internal_ev_mwhgsmian
+#define __ev_mwhgumian __internal_ev_mwhgumian
+#define __ev_mwhssiaaw __internal_ev_mwhssiaaw
+#define __ev_mwhssfaaw __internal_ev_mwhssfaaw
+#define __ev_mwhsmfaaw __internal_ev_mwhsmfaaw
+#define __ev_mwhsmiaaw __internal_ev_mwhsmiaaw
+#define __ev_mwhusiaaw __internal_ev_mwhusiaaw
+#define __ev_mwhumiaaw __internal_ev_mwhumiaaw
+#define __ev_mwhssfanw __internal_ev_mwhssfanw
+#define __ev_mwhssianw __internal_ev_mwhssianw
+#define __ev_mwhsmfanw __internal_ev_mwhsmfanw
+#define __ev_mwhsmianw __internal_ev_mwhsmianw
+#define __ev_mwhusianw __internal_ev_mwhusianw
+#define __ev_mwhumianw __internal_ev_mwhumianw
static inline __ev64_opaque__
__internal_ev_mwhssfaaw (__ev64_opaque__ a, __ev64_opaque__ b)
@@ -665,31 +659,31 @@ __ev_convert_s64 (__ev64_opaque__ a)
/* __ev_get_* functions. */
-#define __ev_get_upper_u32(a) __ev_get_u32_internal ((__ev64_opaque__) (a), 0)
-#define __ev_get_lower_u32(a) __ev_get_u32_internal ((__ev64_opaque__) (a), 1)
-#define __ev_get_upper_s32(a) __ev_get_s32_internal ((__ev64_opaque__) (a), 0)
-#define __ev_get_lower_s32(a) __ev_get_s32_internal ((__ev64_opaque__) (a), 1)
-#define __ev_get_upper_fs(a) __ev_get_fs_internal ((__ev64_opaque__) (a), 0)
-#define __ev_get_lower_fs(a) __ev_get_fs_internal ((__ev64_opaque__) (a), 1)
-#define __ev_get_upper_ufix32_u32(a) __ev_get_upper_u32(a)
-#define __ev_get_lower_ufix32_u32(a) __ev_get_lower_u32(a)
-#define __ev_get_upper_sfix32_s32(a) __ev_get_upper_s32(a)
-#define __ev_get_lower_sfix32_s32(a) __ev_get_lower_s32(a)
-#define __ev_get_upper_sfix32_fs(a) __ev_get_sfix32_fs (a, 0)
-#define __ev_get_lower_sfix32_fs(a) __ev_get_sfix32_fs (a, 1)
-#define __ev_get_upper_ufix32_fs(a) __ev_get_ufix32_fs (a, 0)
-#define __ev_get_lower_ufix32_fs(a) __ev_get_ufix32_fs (a, 1)
-
-#define __ev_get_u32(a, b) __ev_get_u32_internal ((__ev64_opaque__) (a), b)
-#define __ev_get_s32(a, b) __ev_get_s32_internal ((__ev64_opaque__) (a), b)
-#define __ev_get_fs(a, b) __ev_get_fs_internal ((__ev64_opaque__) (a), b)
-#define __ev_get_u16(a, b) __ev_get_u16_internal ((__ev64_opaque__) (a), b)
-#define __ev_get_s16(a, b) __ev_get_s16_internal ((__ev64_opaque__) (a), b)
-
-#define __ev_get_ufix32_u32(a, b) __ev_get_u32 (a, b)
-#define __ev_get_sfix32_s32(a, b) __ev_get_s32 (a, b)
-#define __ev_get_ufix32_fs(a, b) __ev_get_ufix32_fs_internal ((__ev64_opaque__)(a), b)
-#define __ev_get_sfix32_fs(a, b) __ev_get_sfix32_fs_internal ((__ev64_opaque__)(a), b)
+#define __ev_get_upper_u32(a) __ev_get_u32_internal ((a), 0)
+#define __ev_get_lower_u32(a) __ev_get_u32_internal ((a), 1)
+#define __ev_get_upper_s32(a) __ev_get_s32_internal ((a), 0)
+#define __ev_get_lower_s32(a) __ev_get_s32_internal ((a), 1)
+#define __ev_get_upper_fs(a) __ev_get_fs_internal ((a), 0)
+#define __ev_get_lower_fs(a) __ev_get_fs_internal ((a), 1)
+#define __ev_get_upper_ufix32_u32 __ev_get_upper_u32
+#define __ev_get_lower_ufix32_u32 __ev_get_lower_u32
+#define __ev_get_upper_sfix32_s32 __ev_get_upper_s32
+#define __ev_get_lower_sfix32_s32 __ev_get_lower_s32
+#define __ev_get_upper_sfix32_fs(a) __ev_get_sfix32_fs ((a), 0)
+#define __ev_get_lower_sfix32_fs(a) __ev_get_sfix32_fs ((a), 1)
+#define __ev_get_upper_ufix32_fs(a) __ev_get_ufix32_fs ((a), 0)
+#define __ev_get_lower_ufix32_fs(a) __ev_get_ufix32_fs ((a), 1)
+
+#define __ev_get_u32 __ev_get_u32_internal
+#define __ev_get_s32 __ev_get_s32_internal
+#define __ev_get_fs __ev_get_fs_internal
+#define __ev_get_u16 __ev_get_u16_internal
+#define __ev_get_s16 __ev_get_s16_internal
+
+#define __ev_get_ufix32_u32 __ev_get_u32
+#define __ev_get_sfix32_s32 __ev_get_s32
+#define __ev_get_ufix32_fs __ev_get_ufix32_fs_internal
+#define __ev_get_sfix32_fs __ev_get_sfix32_fs_internal
static inline uint32_t
__ev_get_u32_internal (__ev64_opaque__ a, uint32_t pos)
@@ -776,17 +770,17 @@ __ev_get_s16_internal (__ev64_opaque__ a, uint32_t pos)
/* __ev_set_* functions. */
-#define __ev_set_u32(a, b, c) __ev_set_u32_internal ((__ev64_opaque__) a, b, c)
-#define __ev_set_s32(a, b, c) __ev_set_s32_internal ((__ev64_opaque__) a, b, c)
-#define __ev_set_fs(a, b, c) __ev_set_fs_internal ((__ev64_opaque__) a, b, c)
-#define __ev_set_u16(a, b, c) __ev_set_u16_internal ((__ev64_opaque__) a, b, c)
-#define __ev_set_s16(a, b, c) __ev_set_s16_internal ((__ev64_opaque__) a, b, c)
+#define __ev_set_u32 __ev_set_u32_internal
+#define __ev_set_s32 __ev_set_s32_internal
+#define __ev_set_fs __ev_set_fs_internal
+#define __ev_set_u16 __ev_set_u16_internal
+#define __ev_set_s16 __ev_set_s16_internal
#define __ev_set_ufix32_u32 __ev_set_u32
#define __ev_set_sfix32_s32 __ev_set_s32
-#define __ev_set_sfix32_fs(a, b, c) __ev_set_sfix32_fs_internal ((__ev64_opaque__) (a), b, c)
-#define __ev_set_ufix32_fs(a, b, c) __ev_set_ufix32_fs_internal ((__ev64_opaque__) (a), b, c)
+#define __ev_set_sfix32_fs __ev_set_sfix32_fs_internal
+#define __ev_set_ufix32_fs __ev_set_ufix32_fs_internal
#define __ev_set_upper_u32(a, b) __ev_set_u32 (a, b, 0)
#define __ev_set_lower_u32(a, b) __ev_set_u32 (a, b, 1)
@@ -803,7 +797,7 @@ __ev_get_s16_internal (__ev64_opaque__ a, uint32_t pos)
#define __ev_set_upper_ufix32_fs(a, b) __ev_set_ufix32_fs (a, b, 0)
#define __ev_set_lower_ufix32_fs(a, b) __ev_set_ufix32_fs (a, b, 1)
-#define __ev_set_acc_vec64(a) __builtin_spe_evmra ((__ev64_opaque__)(a))
+#define __ev_set_acc_vec64 __builtin_spe_evmra
static inline __ev64_opaque__
__ev_set_acc_u64 (uint64_t a)
@@ -932,72 +926,72 @@ __ev_set_s16_internal (__ev64_opaque__ a, int16_t b, uint32_t pos)
#define __pred_upper 2
#define __pred_lower 3
-#define __ev_any_gts(a, b) __builtin_spe_evcmpgts (__pred_any, (__v2si) (a), (__v2si) (b))
-#define __ev_all_gts(a, b) __builtin_spe_evcmpgts (__pred_all, (__v2si) (a), (__v2si) (b))
-#define __ev_upper_gts(a, b) __builtin_spe_evcmpgts (__pred_upper, (__v2si) (a), (__v2si) (b))
-#define __ev_lower_gts(a, b) __builtin_spe_evcmpgts (__pred_lower, (__v2si) (a), (__v2si) (b))
-#define __ev_select_gts(a, b, c, d) ((__v2si) __builtin_spe_evsel_gts ((__v2si) (a), (__v2si) (b), (__v2si) (c), (__v2si) (d)))
-
-#define __ev_any_gtu(a, b) __builtin_spe_evcmpgtu (__pred_any, (__v2si) (a), (__v2si) (b))
-#define __ev_all_gtu(a, b) __builtin_spe_evcmpgtu (__pred_all, (__v2si) (a), (__v2si) (b))
-#define __ev_upper_gtu(a, b) __builtin_spe_evcmpgtu (__pred_upper, (__v2si) (a), (__v2si) (b))
-#define __ev_lower_gtu(a, b) __builtin_spe_evcmpgtu (__pred_lower, (__v2si) (a), (__v2si) (b))
-#define __ev_select_gtu(a, b, c, d) ((__v2si) __builtin_spe_evsel_gtu ((__v2si) (a), (__v2si) (b), (__v2si) (c), (__v2si) (d)))
-
-#define __ev_any_lts(a, b) __builtin_spe_evcmplts (__pred_any, (__v2si) (a), (__v2si) (b))
-#define __ev_all_lts(a, b) __builtin_spe_evcmplts (__pred_all, (__v2si) (a), (__v2si) (b))
-#define __ev_upper_lts(a, b) __builtin_spe_evcmplts (__pred_upper, (__v2si) (a), (__v2si) (b))
-#define __ev_lower_lts(a, b) __builtin_spe_evcmplts (__pred_lower, (__v2si) (a), (__v2si) (b))
-#define __ev_select_lts(a, b, c, d) ((__v2si) __builtin_spe_evsel_lts ((__v2si) (a), (__v2si) (b), (__v2si) (c), (__v2si) (d)))
-
-#define __ev_any_ltu(a, b) __builtin_spe_evcmpltu (__pred_any, (__v2si) (a), (__v2si) (b))
-#define __ev_all_ltu(a, b) __builtin_spe_evcmpltu (__pred_all, (__v2si) (a), (__v2si) (b))
-#define __ev_upper_ltu(a, b) __builtin_spe_evcmpltu (__pred_upper, (__v2si) (a), (__v2si) (b))
-#define __ev_lower_ltu(a, b) __builtin_spe_evcmpltu (__pred_lower, (__v2si) (a), (__v2si) (b))
-#define __ev_select_ltu(a, b, c, d) ((__v2si) __builtin_spe_evsel_ltu ((__v2si) (a), (__v2si) (b), (__v2si) (c), (__v2si) (d)))
-#define __ev_any_eq(a, b) __builtin_spe_evcmpeq (__pred_any, (__v2si) (a), (__v2si) (b))
-#define __ev_all_eq(a, b) __builtin_spe_evcmpeq (__pred_all, (__v2si) (a), (__v2si) (b))
-#define __ev_upper_eq(a, b) __builtin_spe_evcmpeq (__pred_upper, (__v2si) (a), (__v2si) (b))
-#define __ev_lower_eq(a, b) __builtin_spe_evcmpeq (__pred_lower, (__v2si) (a), (__v2si) (b))
-#define __ev_select_eq(a, b, c, d) ((__v2si) __builtin_spe_evsel_eq ((__v2si) (a), (__v2si) (b), (__v2si) (c), (__v2si) (d)))
-
-#define __ev_any_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_any, (__v2sf) (a), (__v2sf) (b))
-#define __ev_all_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_all, (__v2sf) (a), (__v2sf) (b))
-#define __ev_upper_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_upper, (__v2sf) (a), (__v2sf) (b))
-#define __ev_lower_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_lower, (__v2sf) (a), (__v2sf) (b))
-#define __ev_select_fs_gt(a, b, c, d) ((__v2si) __builtin_spe_evsel_fsgt ((__v2sf) (a), (__v2sf) (b), (__v2sf) (c), (__v2sf) (d)))
-
-#define __ev_any_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_any, (__v2sf) (a), (__v2sf) (b))
-#define __ev_all_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_all, (__v2sf) (a), (__v2sf) (b))
-#define __ev_upper_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_upper, (__v2sf) (a), (__v2sf) (b))
-#define __ev_lower_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_lower, (__v2sf) (a), (__v2sf) (b))
-#define __ev_select_fs_lt(a, b, c, d) ((__v2si) __builtin_spe_evsel_fslt ((__v2sf) (a), (__v2sf) (b), (__v2sf) (c), (__v2sf) (d)))
-
-#define __ev_any_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_any, (__v2sf) (a), (__v2sf) (b))
-#define __ev_all_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_all, (__v2sf) (a), (__v2sf) (b))
-#define __ev_upper_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_upper, (__v2sf) (a), (__v2sf) (b))
-#define __ev_lower_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_lower, (__v2sf) (a), (__v2sf) (b))
-#define __ev_select_fs_eq(a, b, c, d) ((__v2si) __builtin_spe_evsel_fseq ((__v2sf) (a), (__v2sf) (b), (__v2sf) (c), (__v2sf) (d)))
-
-#define __ev_any_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_any, (__v2sf) (a), (__v2sf) (b))
-#define __ev_all_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_all, (__v2sf) (a), (__v2sf) (b))
-#define __ev_upper_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_upper, (__v2sf) (a), (__v2sf) (b))
-#define __ev_lower_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_lower, (__v2sf) (a), (__v2sf) (b))
-#define __ev_select_fs_tst_gt(a, b, c, d) ((__v2si) __builtin_spe_evsel_fststgt ((__v2sf) (a), (__v2sf) (b), (__v2sf) (c), (__v2sf) (d)))
-
-#define __ev_any_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_any, (__v2sf) (a), (__v2sf) (b))
-#define __ev_all_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_all, (__v2sf) (a), (__v2sf) (b))
-#define __ev_upper_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_upper, (__v2sf) (a), (__v2sf) (b))
-#define __ev_lower_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_lower, (__v2sf) (a), (__v2sf) (b))
-#define __ev_select_fs_tst_lt(a, b, c, d) ((__v2si) __builtin_spe_evsel_fststlt ((__v2sf) (a), (__v2sf) (b), (__v2sf) (c), (__v2sf) (d)))
-
-#define __ev_any_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_any, (__v2sf) (a), (__v2sf) (b))
-#define __ev_all_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_all, (__v2sf) (a), (__v2sf) (b))
-#define __ev_upper_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_upper, (__v2sf) (a), (__v2sf) (b))
-#define __ev_lower_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_lower, (__v2sf) (a), (__v2sf) (b))
-#define __ev_select_fs_tst_eq(a, b, c, d) ((__v2si) __builtin_spe_evsel_fststeq ((__v2sf) (a), (__v2sf) (b), (__v2sf) (c), (__v2sf) (d)))
-
-/* SPEFSCR accesor functions. */
+#define __ev_any_gts(a, b) __builtin_spe_evcmpgts (__pred_any, (a), (b))
+#define __ev_all_gts(a, b) __builtin_spe_evcmpgts (__pred_all, (a), (b))
+#define __ev_upper_gts(a, b) __builtin_spe_evcmpgts (__pred_upper, (a), (b))
+#define __ev_lower_gts(a, b) __builtin_spe_evcmpgts (__pred_lower, (a), (b))
+#define __ev_select_gts __builtin_spe_evsel_gts
+
+#define __ev_any_gtu(a, b) __builtin_spe_evcmpgtu (__pred_any, (a), (b))
+#define __ev_all_gtu(a, b) __builtin_spe_evcmpgtu (__pred_all, (a), (b))
+#define __ev_upper_gtu(a, b) __builtin_spe_evcmpgtu (__pred_upper, (a), (b))
+#define __ev_lower_gtu(a, b) __builtin_spe_evcmpgtu (__pred_lower, (a), (b))
+#define __ev_select_gtu __builtin_spe_evsel_gtu
+
+#define __ev_any_lts(a, b) __builtin_spe_evcmplts (__pred_any, (a), (b))
+#define __ev_all_lts(a, b) __builtin_spe_evcmplts (__pred_all, (a), (b))
+#define __ev_upper_lts(a, b) __builtin_spe_evcmplts (__pred_upper, (a), (b))
+#define __ev_lower_lts(a, b) __builtin_spe_evcmplts (__pred_lower, (a), (b))
+#define __ev_select_lts(a, b, c, d) ((__v2si) __builtin_spe_evsel_lts ((a), (b), (c), (d)))
+
+#define __ev_any_ltu(a, b) __builtin_spe_evcmpltu (__pred_any, (a), (b))
+#define __ev_all_ltu(a, b) __builtin_spe_evcmpltu (__pred_all, (a), (b))
+#define __ev_upper_ltu(a, b) __builtin_spe_evcmpltu (__pred_upper, (a), (b))
+#define __ev_lower_ltu(a, b) __builtin_spe_evcmpltu (__pred_lower, (a), (b))
+#define __ev_select_ltu __builtin_spe_evsel_ltu
+#define __ev_any_eq(a, b) __builtin_spe_evcmpeq (__pred_any, (a), (b))
+#define __ev_all_eq(a, b) __builtin_spe_evcmpeq (__pred_all, (a), (b))
+#define __ev_upper_eq(a, b) __builtin_spe_evcmpeq (__pred_upper, (a), (b))
+#define __ev_lower_eq(a, b) __builtin_spe_evcmpeq (__pred_lower, (a), (b))
+#define __ev_select_eq __builtin_spe_evsel_eq
+
+#define __ev_any_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_any, (a), (b))
+#define __ev_all_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_all, (a), (b))
+#define __ev_upper_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_upper, (a), (b))
+#define __ev_lower_fs_gt(a, b) __builtin_spe_evfscmpgt (__pred_lower, (a), (b))
+#define __ev_select_fs_gt __builtin_spe_evsel_fsgt
+
+#define __ev_any_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_any, (a), (b))
+#define __ev_all_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_all, (a), (b))
+#define __ev_upper_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_upper, (a), (b))
+#define __ev_lower_fs_lt(a, b) __builtin_spe_evfscmplt (__pred_lower, (a), (b))
+#define __ev_select_fs_lt __builtin_spe_evsel_fslt
+
+#define __ev_any_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_any, (a), (b))
+#define __ev_all_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_all, (a), (b))
+#define __ev_upper_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_upper, (a), (b))
+#define __ev_lower_fs_eq(a, b) __builtin_spe_evfscmpeq (__pred_lower, (a), (b))
+#define __ev_select_fs_eq __builtin_spe_evsel_fseq
+
+#define __ev_any_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_any, (a), (b))
+#define __ev_all_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_all, (a), (b))
+#define __ev_upper_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_upper, (a), (b))
+#define __ev_lower_fs_tst_gt(a, b) __builtin_spe_evfststgt (__pred_lower, (a), (b))
+#define __ev_select_fs_tst_gt __builtin_spe_evsel_fststgt
+
+#define __ev_any_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_any, (a), (b))
+#define __ev_all_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_all, (a), (b))
+#define __ev_upper_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_upper, (a), (b))
+#define __ev_lower_fs_tst_lt(a, b) __builtin_spe_evfststlt (__pred_lower, (a), (b))
+#define __ev_select_fs_tst_lt __builtin_spe_evsel_fststlt
+
+#define __ev_any_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_any, (a), (b))
+#define __ev_all_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_all, (a), (b))
+#define __ev_upper_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_upper, (a), (b))
+#define __ev_lower_fs_tst_eq(a, b) __builtin_spe_evfststeq (__pred_lower, (a), (b))
+#define __ev_select_fs_tst_eq __builtin_spe_evsel_fststeq
+
+/* SPEFSCR accessor functions. */
#define __SPEFSCR_SOVH 0x80000000
#define __SPEFSCR_OVH 0x40000000
@@ -1091,6 +1085,7 @@ __ev_set_spefscr_frmc (int rnd)
i = __builtin_spe_mfspefscr ();
i &= ~__SPEFSCR_FRMC;
i |= rnd;
+ __builtin_spe_mtspefscr (i);
}
#endif /* _SPE_H */
diff --git a/contrib/gcc/config/rs6000/spe.md b/contrib/gcc/config/rs6000/spe.md
index 3413858f333a..5eb6302f208a 100644
--- a/contrib/gcc/config/rs6000/spe.md
+++ b/contrib/gcc/config/rs6000/spe.md
@@ -1,23 +1,23 @@
;; e500 SPE description
-;; Copyright (C) 2002 Free Software Foundation, Inc.
+;; Copyright (C) 2002, 2003 Free Software Foundation, Inc.
;; Contributed by Aldy Hernandez (aldy@quesejoda.com)
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC 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.
+;; 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 2, or (at your
+;; option) any later version.
-;; GNU CC 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.
+;; 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 GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING. If not, write to the
+;; Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+;; MA 02111-1307, USA.
(define_constants
[(SPE_ACC_REGNO 111)
@@ -28,14 +28,21 @@
(neg:SF (match_operand:SF 1 "gpc_reg_operand" "r")))]
"TARGET_HARD_FLOAT && !TARGET_FPRS"
"efsneg %0,%1"
- [(set_attr "type" "fp")])
+ [(set_attr "type" "fpsimple")])
(define_insn "*abssf2_gpr"
[(set (match_operand:SF 0 "gpc_reg_operand" "=r")
(abs:SF (match_operand:SF 1 "gpc_reg_operand" "r")))]
"TARGET_HARD_FLOAT && !TARGET_FPRS"
"efsabs %0,%1"
- [(set_attr "type" "fp")])
+ [(set_attr "type" "fpsimple")])
+
+(define_insn "*nabssf2_gpr"
+ [(set (match_operand:SF 0 "gpc_reg_operand" "=r")
+ (neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "r"))))]
+ "TARGET_HARD_FLOAT && !TARGET_FPRS"
+ "efsnabs %0,%1"
+ [(set_attr "type" "fpsimple")])
(define_insn "*addsf3_gpr"
[(set (match_operand:SF 0 "gpc_reg_operand" "=r")
@@ -67,27 +74,20 @@
(match_operand:SF 2 "gpc_reg_operand" "r")))]
"TARGET_HARD_FLOAT && !TARGET_FPRS"
"efsdiv %0,%1,%2"
- [(set_attr "type" "fp")])
+ [(set_attr "type" "vecfdiv")])
-(define_insn "spe_efsctuiz"
+(define_insn "spe_fixuns_truncsfsi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unspec:SI [(match_operand:SF 1 "gpc_reg_operand" "r")] 700))]
+ (unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "r")))]
"TARGET_HARD_FLOAT && !TARGET_FPRS"
"efsctuiz %0,%1"
[(set_attr "type" "fp")])
-(define_insn "spe_fixunssfsi2"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
- (unsigned_fix:SI (fix:SF (match_operand:SF 1 "gpc_reg_operand" "r"))))]
- "TARGET_HARD_FLOAT && !TARGET_FPRS"
- "efsctui %0,%1"
- [(set_attr "type" "fp")])
-
(define_insn "spe_fix_truncsfsi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(fix:SI (match_operand:SF 1 "gpc_reg_operand" "r")))]
"TARGET_HARD_FLOAT && !TARGET_FPRS"
- "efsctsi %0,%1"
+ "efsctsiz %0,%1"
[(set_attr "type" "fp")])
(define_insn "spe_floatunssisf2"
@@ -283,12 +283,12 @@
(set_attr "length" "4")])
(define_insn "spe_evlhhesplat"
- [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
- (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
+ [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
+ (mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 509)]
- "TARGET_SPE"
- "evlhhesplat %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlhhesplat %0,%2*2(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -307,8 +307,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 511)]
- "TARGET_SPE"
- "evlhhossplat %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlhhossplat %0,%2*2(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -327,8 +327,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 513)]
- "TARGET_SPE"
- "evlhhousplat %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlhhousplat %0,%2*2(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -347,8 +347,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 515)]
- "TARGET_SPE"
- "evlwhsplat %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlwhsplat %0,%2*4(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -367,8 +367,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 517)]
- "TARGET_SPE"
- "evlwwsplat %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlwwsplat %0,%2*4(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -443,7 +443,7 @@
[(set_attr "type" "vecsimple")
(set_attr "length" "4")])
-(define_insn "spe_evneg"
+(define_insn "negv2si2"
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(neg:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")))]
"TARGET_SPE"
@@ -581,7 +581,9 @@
[(set_attr "type" "vecsimple")
(set_attr "length" "4")])
-(define_insn "spe_evxor"
+;; vector xors
+
+(define_insn "xorv2si3"
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(xor:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")))]
@@ -590,12 +592,32 @@
[(set_attr "type" "vecsimple")
(set_attr "length" "4")])
+(define_insn "xorv4hi3"
+ [(set (match_operand:V4HI 0 "gpc_reg_operand" "=r")
+ (xor:V4HI (match_operand:V4HI 1 "gpc_reg_operand" "r")
+ (match_operand:V4HI 2 "gpc_reg_operand" "r")))]
+ "TARGET_SPE"
+ "evxor %0,%1,%2"
+ [(set_attr "type" "vecsimple")
+ (set_attr "length" "4")])
+
+(define_insn "xorv1di3"
+ [(set (match_operand:V1DI 0 "gpc_reg_operand" "=r")
+ (xor:V1DI (match_operand:V1DI 1 "gpc_reg_operand" "r")
+ (match_operand:V1DI 2 "gpc_reg_operand" "r")))]
+ "TARGET_SPE"
+ "evxor %0,%1,%2"
+ [(set_attr "type" "vecsimple")
+ (set_attr "length" "4")])
+
+;; end of vector xors
+
(define_insn "spe_evfsabs"
[(set (match_operand:V2SF 0 "gpc_reg_operand" "=r")
(abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "r")))]
"TARGET_SPE"
"evfsabs %0,%1"
- [(set_attr "type" "vecfloat")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "4")])
(define_insn "spe_evfsadd"
@@ -617,8 +639,8 @@
(set_attr "length" "4")])
(define_insn "spe_evfscfsi"
- [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
- (fix:V2SI (match_operand:V2SF 1 "gpc_reg_operand" "r")))]
+ [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r")
+ (float:V2SF (match_operand:V2SI 1 "gpc_reg_operand" "r")))]
"TARGET_SPE"
"evfscfsi %0,%1"
[(set_attr "type" "vecfloat")
@@ -695,7 +717,7 @@
(clobber (reg:SI SPEFSCR_REGNO))]
"TARGET_SPE"
"evfsdiv %0,%1,%2"
- [(set_attr "type" "vecfloat")
+ [(set_attr "type" "vecfdiv")
(set_attr "length" "4")])
(define_insn "spe_evfsmul"
@@ -713,7 +735,7 @@
(unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "r")] 537))]
"TARGET_SPE"
"evfsnabs %0,%1"
- [(set_attr "type" "vecfloat")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "4")])
(define_insn "spe_evfsneg"
@@ -721,7 +743,7 @@
(neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "r")))]
"TARGET_SPE"
"evfsneg %0,%1"
- [(set_attr "type" "vecfloat")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "4")])
(define_insn "spe_evfssub"
@@ -736,7 +758,7 @@
;; SPE SIMD load instructions.
-;; Only the hardware engineer who designed the SPE inderstands the
+;; Only the hardware engineer who designed the SPE understands the
;; plethora of load and store instructions ;-). We have no way of
;; differentiating between them with RTL so use an unspec of const_int 0
;; to avoid identical RTL.
@@ -747,7 +769,7 @@
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 544)]
"TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
- "evldd %0,%1,%2"
+ "evldd %0,%2*8(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -767,7 +789,7 @@
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 546)]
"TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
- "evldh %0,%1,%2"
+ "evldh %0,%2*8(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -786,8 +808,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 548)]
- "TARGET_SPE"
- "evldw %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evldw %0,%2*8(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -806,8 +828,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 550)]
- "TARGET_SPE"
- "evlwhe %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlwhe %0,%2*4(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -826,8 +848,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 552)]
- "TARGET_SPE"
- "evlwhos %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlwhos %0,%2*4(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -846,8 +868,8 @@
(mem:V2SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
(match_operand:QI 2 "immediate_operand" "i"))))
(unspec [(const_int 0)] 554)]
- "TARGET_SPE"
- "evlwhou %0,%1,%2"
+ "TARGET_SPE && INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 31"
+ "evlwhou %0,%2*4(%1)"
[(set_attr "type" "vecload")
(set_attr "length" "4")])
@@ -867,7 +889,7 @@
(match_operand:SI 2 "gpc_reg_operand" "r")] 556))]
"TARGET_SPE"
"brinc %0,%1,%2"
- [(set_attr "type" "veccomplex")
+ [(set_attr "type" "brinc")
(set_attr "length" "4")])
(define_insn "spe_evmhegsmfaa"
@@ -875,7 +897,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 557))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhegsmfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -886,7 +908,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 558))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhegsmfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -897,7 +919,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 559))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhegsmiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -908,7 +930,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 560))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhegsmian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -919,7 +941,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 561))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhegumiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -930,7 +952,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 562))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhegumian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -941,7 +963,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 563))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhesmfaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -952,7 +974,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 564))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhesmfanw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -962,7 +984,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 565))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhesmfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -982,7 +1004,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 567))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhesmiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -993,7 +1015,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 568))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhesmianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1003,7 +1025,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 569))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhesmia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1024,7 +1046,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 571))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhessfaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1036,7 +1058,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 572))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhessfanw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1047,7 +1069,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 573))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhessfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1069,7 +1091,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 575))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhessiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1081,7 +1103,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 576))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhessianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1092,7 +1114,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 577))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmheumiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1103,7 +1125,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 578))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmheumianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1113,7 +1135,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 579))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmheumia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1134,7 +1156,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 581))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmheusiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1146,7 +1168,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 582))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmheusianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1157,7 +1179,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 583))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhogsmfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1168,7 +1190,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 584))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhogsmfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1179,7 +1201,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 585))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhogsmiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1190,7 +1212,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 586))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhogsmian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1201,7 +1223,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 587))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhogumiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1212,7 +1234,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 588))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhogumian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1223,7 +1245,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 589))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhosmfaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1234,7 +1256,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 590))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhosmfanw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1253,7 +1275,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 592))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhosmf %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1264,7 +1286,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 593))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhosmiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1275,7 +1297,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 594))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhosmianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1285,7 +1307,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 595))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhosmia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1306,7 +1328,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 597))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhossfaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1318,7 +1340,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 598))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhossfanw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1330,7 +1352,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 599))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhossfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1352,7 +1374,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 601))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhossiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1364,7 +1386,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 602))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhossianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1375,7 +1397,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 603))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhoumiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1386,7 +1408,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 604))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhoumianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1396,7 +1418,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 605))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhoumia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1417,7 +1439,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 607))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhousiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1429,7 +1451,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 608))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmhousianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1457,7 +1479,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 611))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhsmfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1476,7 +1498,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 613))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhsmia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1496,7 +1518,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 615))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhssfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1525,7 +1547,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 629))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhumia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1545,7 +1567,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 635))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlsmiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1556,7 +1578,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 636))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlsmianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1568,7 +1590,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 641))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlssiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1580,7 +1602,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 642))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlssianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1591,7 +1613,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 643))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlumiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1602,7 +1624,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 644))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlumianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1612,7 +1634,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 645))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlumia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1633,7 +1655,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 647))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlusiaaw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1645,7 +1667,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 648))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwlusianw %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1656,7 +1678,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 649))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwsmfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1667,7 +1689,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 650))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwsmfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1677,7 +1699,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 651))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwsmfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1697,7 +1719,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 653))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwsmiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1708,7 +1730,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 654))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwsmian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1718,7 +1740,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 655))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwsmia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1739,7 +1761,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 657))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwssfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1751,7 +1773,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 658))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwssfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1762,7 +1784,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 659))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwssfa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1783,7 +1805,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 661))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwumiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1794,7 +1816,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 662))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwumian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1804,7 +1826,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 663))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwumia %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -1825,7 +1847,7 @@
(match_operand:V2SI 2 "gpc_reg_operand" "r")))]
"TARGET_SPE"
"evaddw %0,%1,%2"
- [(set_attr "type" "veccomplex")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "4")])
(define_insn "spe_evaddusiaaw"
@@ -1833,7 +1855,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 673))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evaddusiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1843,7 +1865,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 674))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evaddumiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1854,7 +1876,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 675))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evaddssiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1864,7 +1886,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 676))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evaddsmiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1876,7 +1898,7 @@
(match_operand:QI 2 "immediate_operand" "i")] 677))]
"TARGET_SPE"
"evaddiw %0,%1,%2"
- [(set_attr "type" "veccomplex")
+ [(set_attr "type" "vecsimple")
(set_attr "length" "4")])
(define_insn "spe_evsubifw"
@@ -1893,7 +1915,7 @@
(minus:V2SI (match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")))]
"TARGET_SPE"
- "evsubfw %0,%1,%2"
+ "evsubfw %0,%2,%1"
[(set_attr "type" "veccomplex")
(set_attr "length" "4")])
@@ -1902,7 +1924,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 679))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evsubfusiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1912,7 +1934,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 680))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evsubfumiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1923,7 +1945,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 681))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evsubfssiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1933,7 +1955,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(reg:V2SI SPE_ACC_REGNO)] 682))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evsubfsmiaaw %0,%1"
[(set_attr "type" "veccomplex")
@@ -1956,7 +1978,7 @@
(clobber (reg:SI SPEFSCR_REGNO))]
"TARGET_SPE"
"evdivws %0,%1,%2"
- [(set_attr "type" "veccomplex")
+ [(set_attr "type" "vecdiv")
(set_attr "length" "4")])
(define_insn "spe_evdivwu"
@@ -1966,7 +1988,7 @@
(clobber (reg:SI SPEFSCR_REGNO))]
"TARGET_SPE"
"evdivwu %0,%1,%2"
- [(set_attr "type" "veccomplex")
+ [(set_attr "type" "vecdiv")
(set_attr "length" "4")])
(define_insn "spe_evsplatfi"
@@ -1990,8 +2012,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 686)]
- "TARGET_SPE"
- "evstdd %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstdd %2,%1*8(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2010,8 +2032,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 688)]
- "TARGET_SPE"
- "evstdh %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstdh %2,%1*8(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2030,8 +2052,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 690)]
- "TARGET_SPE"
- "evstdw %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstdw %2,%1*8(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2050,8 +2072,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 692)]
- "TARGET_SPE"
- "evstwhe %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstwhe %2,%1*4(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2070,8 +2092,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 694)]
- "TARGET_SPE"
- "evstwho %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstwho %2,%1*4(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2090,8 +2112,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 696)]
- "TARGET_SPE"
- "evstwwe %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstwwe %2,%1*4(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2110,8 +2132,8 @@
(match_operand:QI 1 "immediate_operand" "i")))
(match_operand:V2SI 2 "gpc_reg_operand" "r"))
(unspec [(const_int 0)] 698)]
- "TARGET_SPE"
- "evstwwo %2,%0,%1"
+ "TARGET_SPE && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 31"
+ "evstwwo %2,%1*4(%0)"
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
@@ -2125,36 +2147,6 @@
[(set_attr "type" "vecstore")
(set_attr "length" "4")])
-;; SPE vector clears
-
-(define_insn "*movv2si_const0"
- [(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
- (match_operand:V2SI 1 "zero_constant" ""))]
- "TARGET_SPE"
- "evxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
-(define_insn "*movv2sf_const0"
- [(set (match_operand:V2SF 0 "gpc_reg_operand" "=r")
- (match_operand:V2SF 1 "zero_constant" ""))]
- "TARGET_SPE"
- "evxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
-(define_insn "*movv4hi_const0"
- [(set (match_operand:V4HI 0 "gpc_reg_operand" "=r")
- (match_operand:V4HI 1 "zero_constant" ""))]
- "TARGET_SPE"
- "evxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
-(define_insn "*movv1di_const0"
- [(set (match_operand:V1DI 0 "gpc_reg_operand" "=r")
- (match_operand:V1DI 1 "zero_constant" ""))]
- "TARGET_SPE"
- "evxor %0,%0,%0"
- [(set_attr "type" "vecsimple")])
-
;; Vector move instructions.
(define_expand "movv2si"
@@ -2163,16 +2155,33 @@
"TARGET_SPE"
"{ rs6000_emit_move (operands[0], operands[1], V2SImode); DONE; }")
-
(define_insn "*movv2si_internal"
- [(set (match_operand:V2SI 0 "nonimmediate_operand" "=m,r,r")
- (match_operand:V2SI 1 "input_operand" "r,m,r"))]
- "TARGET_SPE"
- "@
- evstdd%X0 %1,%y0
- evldd%X1 %0,%y1
- evor %0,%1,%1"
- [(set_attr "type" "vecload")])
+ [(set (match_operand:V2SI 0 "nonimmediate_operand" "=m,r,r,r")
+ (match_operand:V2SI 1 "input_operand" "r,m,r,W"))]
+ "TARGET_SPE
+ && (gpc_reg_operand (operands[0], V2SImode)
+ || gpc_reg_operand (operands[1], V2SImode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: return \"evstdd%X0 %1,%y0\";
+ case 1: return \"evldd%X1 %0,%y1\";
+ case 2: return \"evor %0,%1,%1\";
+ case 3: return output_vec_const_move (operands);
+ default: abort ();
+ }
+}"
+ [(set_attr "type" "vecload,vecstore,*,*")
+ (set_attr "length" "*,*,*,12")])
+
+(define_split
+ [(set (match_operand:V2SI 0 "register_operand" "")
+ (match_operand:V2SI 1 "zero_constant" ""))]
+ "TARGET_SPE && reload_completed"
+ [(set (match_dup 0)
+ (xor:V2SI (match_dup 0) (match_dup 0)))]
+ "")
(define_expand "movv1di"
[(set (match_operand:V1DI 0 "nonimmediate_operand" "")
@@ -2181,14 +2190,18 @@
"{ rs6000_emit_move (operands[0], operands[1], V1DImode); DONE; }")
(define_insn "*movv1di_internal"
- [(set (match_operand:V1DI 0 "nonimmediate_operand" "=m,r,r")
- (match_operand:V1DI 1 "input_operand" "r,m,r"))]
- "TARGET_SPE"
+ [(set (match_operand:V1DI 0 "nonimmediate_operand" "=m,r,r,r")
+ (match_operand:V1DI 1 "input_operand" "r,m,r,W"))]
+ "TARGET_SPE
+ && (gpc_reg_operand (operands[0], V1DImode)
+ || gpc_reg_operand (operands[1], V1DImode))"
"@
evstdd%X0 %1,%y0
evldd%X1 %0,%y1
- evor %0,%1,%1"
- [(set_attr "type" "vecload")])
+ evor %0,%1,%1
+ evxor %0,%0,%0"
+ [(set_attr "type" "vecload,vecstore,*,*")
+ (set_attr "length" "*,*,*,*")])
(define_expand "movv4hi"
[(set (match_operand:V4HI 0 "nonimmediate_operand" "")
@@ -2199,7 +2212,9 @@
(define_insn "*movv4hi_internal"
[(set (match_operand:V4HI 0 "nonimmediate_operand" "=m,r,r")
(match_operand:V4HI 1 "input_operand" "r,m,r"))]
- "TARGET_SPE"
+ "TARGET_SPE
+ && (gpc_reg_operand (operands[0], V4HImode)
+ || gpc_reg_operand (operands[1], V4HImode))"
"@
evstdd%X0 %1,%y0
evldd%X1 %0,%y1
@@ -2213,21 +2228,27 @@
"{ rs6000_emit_move (operands[0], operands[1], V2SFmode); DONE; }")
(define_insn "*movv2sf_internal"
- [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,r,r")
- (match_operand:V2SF 1 "input_operand" "r,m,r"))]
- "TARGET_SPE"
+ [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,r,r,r")
+ (match_operand:V2SF 1 "input_operand" "r,m,r,W"))]
+ "TARGET_SPE
+ && (gpc_reg_operand (operands[0], V2SFmode)
+ || gpc_reg_operand (operands[1], V2SFmode))"
"@
evstdd%X0 %1,%y0
evldd%X1 %0,%y1
- evor %0,%1,%1"
- [(set_attr "type" "vecload")])
+ evor %0,%1,%1
+ evxor %0,%0,%0"
+ [(set_attr "type" "vecload,vecstore,*,*")
+ (set_attr "length" "*,*,*,*")])
+
+;; End of vector move instructions.
(define_insn "spe_evmwhssfaa"
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 702))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhssfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2238,7 +2259,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 703))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhssmaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2248,7 +2269,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 704))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhsmfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2258,7 +2279,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 705))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhsmiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2269,7 +2290,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 706))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhusiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2279,7 +2300,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 707))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhumiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2290,7 +2311,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 708))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhssfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2301,7 +2322,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 709))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhssian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2311,7 +2332,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 710))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhsmfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2321,7 +2342,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 711))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhsmian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2331,7 +2352,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 713))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhumian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2342,7 +2363,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 714))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgssfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2352,7 +2373,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 715))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgsmfaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2362,7 +2383,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 716))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgsmiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2372,7 +2393,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 717))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgumiaa %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2383,7 +2404,7 @@
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 718))
(clobber (reg:SI SPEFSCR_REGNO))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgssfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2393,7 +2414,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 719))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgsmfan %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2403,7 +2424,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 720))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgsmian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2413,7 +2434,7 @@
[(set (match_operand:V2SI 0 "gpc_reg_operand" "=r")
(unspec:V2SI [(match_operand:V2SI 1 "gpc_reg_operand" "r")
(match_operand:V2SI 2 "gpc_reg_operand" "r")] 721))
- (clobber (reg:V2SI SPE_ACC_REGNO))]
+ (set (reg:V2SI SPE_ACC_REGNO) (unspec:V2SI [(const_int 0)] 0))]
"TARGET_SPE"
"evmwhgumian %0,%1,%2"
[(set_attr "type" "veccomplex")
@@ -2434,55 +2455,80 @@
"mfspefscr %0"
[(set_attr "type" "vecsimple")])
+;; FP comparison stuff.
+
+;; Flip the GT bit.
+(define_insn "e500_flip_gt_bit"
+ [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
+ (unspec:CCFP
+ [(match_operand:CCFP 1 "cc_reg_operand" "y")] 999))]
+ "!TARGET_FPRS && TARGET_HARD_FLOAT"
+ "*
+{
+ return output_e500_flip_gt_bit (operands[0], operands[1]);
+}"
+ [(set_attr "type" "cr_logical")])
+
;; MPC8540 single-precision FP instructions on GPRs.
;; We have 2 variants for each. One for IEEE compliant math and one
;; for non IEEE compliant math.
(define_insn "cmpsfeq_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (eq:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1000))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
"efscmpeq %0,%1,%2"
- [(set_attr "type" "fpcompare")])
+ [(set_attr "type" "veccmp")])
(define_insn "tstsfeq_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (eq:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1001))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
"efststeq %0,%1,%2"
- [(set_attr "type" "fpcompare")])
+ [(set_attr "type" "veccmpsimple")])
(define_insn "cmpsfgt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (gt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1002))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
"efscmpgt %0,%1,%2"
- [(set_attr "type" "fpcompare")])
+ [(set_attr "type" "veccmp")])
(define_insn "tstsfgt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (gt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1003))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
"efststgt %0,%1,%2"
- [(set_attr "type" "fpcompare")])
+ [(set_attr "type" "veccmpsimple")])
(define_insn "cmpsflt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (lt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1004))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && !flag_unsafe_math_optimizations"
"efscmplt %0,%1,%2"
- [(set_attr "type" "fpcompare")])
+ [(set_attr "type" "veccmp")])
(define_insn "tstsflt_gpr"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (lt:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
- (match_operand:SF 2 "gpc_reg_operand" "r")))]
+ (unspec:CCFP
+ [(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "r")
+ (match_operand:SF 2 "gpc_reg_operand" "r"))]
+ 1005))]
"TARGET_HARD_FLOAT && !TARGET_FPRS && flag_unsafe_math_optimizations"
"efststlt %0,%1,%2"
- [(set_attr "type" "fpcompare")])
-
+ [(set_attr "type" "veccmpsimple")])
diff --git a/contrib/gcc/config/rs6000/sysv4.h b/contrib/gcc/config/rs6000/sysv4.h
index 26450e7ee273..ea149f01a323 100644
--- a/contrib/gcc/config/rs6000/sysv4.h
+++ b/contrib/gcc/config/rs6000/sysv4.h
@@ -1,25 +1,24 @@
/* Target definitions for GNU compiler for PowerPC running System V.4
- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+ 2004 Free Software Foundation, Inc.
Contributed by Cygnus Support.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
/* Header files should be C++ aware in general. */
#define NO_IMPLICIT_EXTERN_C
@@ -80,17 +79,15 @@ extern enum rs6000_sdata_type rs6000_sdata;
/* Strings provided by SUBTARGET_OPTIONS */
extern const char *rs6000_abi_name;
extern const char *rs6000_sdata_name;
+extern const char *rs6000_tls_size_string; /* For -mtls-size= */
/* Override rs6000.h definition. */
#undef SUBTARGET_OPTIONS
-#define SUBTARGET_OPTIONS \
- { "call-", &rs6000_abi_name, N_("Select ABI calling convention") }, \
- { "sdata=", &rs6000_sdata_name, N_("Select method for sdata handling") }
-
-/* Max # of bytes for variables to automatically be put into the .sdata
- or .sdata2 sections. */
-extern int g_switch_value; /* Value of the -G xx switch. */
-extern int g_switch_set; /* Whether -G xx was passed. */
+#define SUBTARGET_OPTIONS \
+ { "call-", &rs6000_abi_name, N_("Select ABI calling convention"), 0}, \
+ { "sdata=", &rs6000_sdata_name, N_("Select method for sdata handling"), 0}, \
+ { "tls-size=", &rs6000_tls_size_string, \
+ N_("Specify bit size of immediate TLS offsets"), 0 }
#define SDATA_DEFAULT_SIZE 8
@@ -150,9 +147,12 @@ extern int g_switch_set; /* Whether -G xx was passed. */
N_("Link with libmvme.a, libc.a and crt0.o") }, \
{ "emb", 0, \
N_("Set the PPC_EMB bit in the ELF flags header") }, \
- { "vxworks", 0, N_("no description yet") }, \
{ "windiss", 0, N_("Use the WindISS simulator") }, \
{ "shlib", 0, N_("no description yet") }, \
+ { "64", MASK_64BIT | MASK_POWERPC64 | MASK_POWERPC, \
+ N_("Generate 64-bit code") }, \
+ { "32", - (MASK_64BIT | MASK_POWERPC64), \
+ N_("Generate 32-bit code") }, \
EXTRA_SUBTARGET_SWITCHES \
{ "newlib", 0, N_("no description yet") },
@@ -173,6 +173,9 @@ do { \
if (!g_switch_set) \
g_switch_value = SDATA_DEFAULT_SIZE; \
\
+ if (rs6000_abi_name == NULL) \
+ rs6000_abi_name = RS6000_ABI_NAME; \
+ \
if (!strcmp (rs6000_abi_name, "sysv")) \
rs6000_current_abi = ABI_V4; \
else if (!strcmp (rs6000_abi_name, "sysv-noeabi")) \
@@ -186,11 +189,6 @@ do { \
rs6000_current_abi = ABI_V4; \
target_flags |= MASK_EABI; \
} \
- else if (!strcmp (rs6000_abi_name, "aix")) \
- { \
- rs6000_current_abi = ABI_AIX_NODESC; \
- target_flags |= MASK_EABI; \
- } \
else if (!strcmp (rs6000_abi_name, "aixdesc")) \
rs6000_current_abi = ABI_AIX; \
else if (!strcmp (rs6000_abi_name, "freebsd")) \
@@ -201,6 +199,8 @@ do { \
rs6000_current_abi = ABI_V4; \
else if (!strcmp (rs6000_abi_name, "netbsd")) \
rs6000_current_abi = ABI_V4; \
+ else if (!strcmp (rs6000_abi_name, "openbsd")) \
+ rs6000_current_abi = ABI_V4; \
else if (!strcmp (rs6000_abi_name, "i960-old")) \
{ \
rs6000_current_abi = ABI_V4; \
@@ -248,8 +248,9 @@ do { \
rs6000_sdata_name); \
} \
\
- else if (flag_pic && \
- (rs6000_sdata == SDATA_EABI || rs6000_sdata == SDATA_SYSV)) \
+ else if (flag_pic && DEFAULT_ABI != ABI_AIX \
+ && (rs6000_sdata == SDATA_EABI \
+ || rs6000_sdata == SDATA_SYSV)) \
{ \
rs6000_sdata = SDATA_DATA; \
error ("-f%s and -msdata=%s are incompatible", \
@@ -280,7 +281,7 @@ do { \
rs6000_abi_name); \
} \
\
- if (flag_pic > 1 && rs6000_current_abi == ABI_AIX) \
+ if (!TARGET_64BIT && flag_pic > 1 && rs6000_current_abi == ABI_AIX) \
{ \
flag_pic = 0; \
error ("-fPIC and -mcall-%s are incompatible", \
@@ -294,14 +295,21 @@ do { \
} \
\
/* Treat -fPIC the same as -mrelocatable. */ \
- if (flag_pic > 1) \
+ if (flag_pic > 1 && DEFAULT_ABI != ABI_AIX) \
target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC; \
\
else if (TARGET_RELOCATABLE) \
flag_pic = 2; \
- \
} while (0)
+#ifndef RS6000_BI_ARCH
+# define SUBSUBTARGET_OVERRIDE_OPTIONS \
+do { \
+ if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT) \
+ error ("-m%s not supported in this configuration", \
+ (target_flags & MASK_64BIT) ? "64" : "32"); \
+} while (0)
+#endif
/* Override rs6000.h definition. */
#undef TARGET_DEFAULT
@@ -377,12 +385,6 @@ do { \
#undef STRICT_ALIGNMENT
#define STRICT_ALIGNMENT (TARGET_STRICT_ALIGN)
-/* Alignment in bits of the stack boundary. Note, in order to allow building
- one set of libraries with -mno-eabi instead of eabi libraries and non-eabi
- versions, just use 64 as the stack boundary. */
-#undef STACK_BOUNDARY
-#define STACK_BOUNDARY (TARGET_ALTIVEC_ABI ? 128 : 64)
-
/* Define this macro if you wish to preserve a certain alignment for
the stack pointer, greater than what the hardware enforces. The
definition is a C expression for the desired alignment (measured
@@ -399,7 +401,8 @@ do { \
#define PREFERRED_STACK_BOUNDARY 128
/* Real stack boundary as mandated by the appropriate ABI. */
-#define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
+#define ABI_STACK_BOUNDARY \
+ ((TARGET_EABI && !TARGET_ALTIVEC && !TARGET_ALTIVEC_ABI) ? 64 : 128)
/* An expression for the alignment of a structure field FIELD if the
alignment computed in the usual way is COMPUTED. */
@@ -438,7 +441,8 @@ do { \
/* Put PC relative got entries in .got2. */
#define MINIMAL_TOC_SECTION_ASM_OP \
- ((TARGET_RELOCATABLE || flag_pic) ? "\t.section\t\".got2\",\"aw\"" : "\t.section\t\".got1\",\"aw\"")
+ (TARGET_RELOCATABLE || (flag_pic && DEFAULT_ABI != ABI_AIX) \
+ ? "\t.section\t\".got2\",\"aw\"" : "\t.section\t\".got1\",\"aw\"")
#define SDATA_SECTION_ASM_OP "\t.section\t\".sdata\",\"aw\""
#define SDATA2_SECTION_ASM_OP "\t.section\t\".sdata2\",\"a\""
@@ -461,7 +465,7 @@ do { \
#define TOC_SECTION_FUNCTION \
void \
-toc_section () \
+toc_section (void) \
{ \
if (in_section != in_toc) \
{ \
@@ -474,7 +478,7 @@ toc_section () \
{ \
toc_initialized = 1; \
fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP); \
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LCTOC", 0); \
+ (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0); \
fprintf (asm_out_file, "\t.tc "); \
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],"); \
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1"); \
@@ -502,15 +506,15 @@ toc_section () \
} \
} \
\
-extern int in_toc_section PARAMS ((void)); \
-int in_toc_section () \
+extern int in_toc_section (void); \
+int in_toc_section (void) \
{ \
return in_section == in_toc; \
}
#define SDATA_SECTION_FUNCTION \
void \
-sdata_section () \
+sdata_section (void) \
{ \
if (in_section != in_sdata) \
{ \
@@ -521,7 +525,7 @@ sdata_section () \
#define SDATA2_SECTION_FUNCTION \
void \
-sdata2_section () \
+sdata2_section (void) \
{ \
if (in_section != in_sdata2) \
{ \
@@ -532,7 +536,7 @@ sdata2_section () \
#define SBSS_SECTION_FUNCTION \
void \
-sbss_section () \
+sbss_section (void) \
{ \
if (in_section != in_sbss) \
{ \
@@ -543,7 +547,7 @@ sbss_section () \
#define INIT_SECTION_FUNCTION \
void \
-init_section () \
+init_section (void) \
{ \
if (in_section != in_init) \
{ \
@@ -554,7 +558,7 @@ init_section () \
#define FINI_SECTION_FUNCTION \
void \
-fini_section () \
+fini_section (void) \
{ \
if (in_section != in_fini) \
{ \
@@ -610,51 +614,7 @@ extern int rs6000_pic_labelno;
/* Override elfos.h definition. */
#undef ASM_DECLARE_FUNCTION_NAME
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
- do { \
- const char *const init_ptr = (TARGET_64BIT) ? ".quad" : ".long"; \
- \
- if (TARGET_RELOCATABLE \
- && (get_pool_size () != 0 || current_function_profile) \
- && uses_TOC()) \
- { \
- char buf[256]; \
- \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, "LCL", rs6000_pic_labelno); \
- \
- ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); \
- fprintf (FILE, "\t%s ", init_ptr); \
- assemble_name (FILE, buf); \
- putc ('-', FILE); \
- ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); \
- assemble_name (FILE, buf); \
- putc ('\n', FILE); \
- } \
- \
- ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
- ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
- \
- if (DEFAULT_ABI == ABI_AIX) \
- { \
- const char *desc_name, *orig_name; \
- \
- orig_name = (*targetm.strip_name_encoding) (NAME); \
- desc_name = orig_name; \
- while (*desc_name == '.') \
- desc_name++; \
- \
- if (TREE_PUBLIC (DECL)) \
- fprintf (FILE, "\t.globl %s\n", desc_name); \
- \
- fprintf (FILE, "%s\n", MINIMAL_TOC_SECTION_ASM_OP); \
- fprintf (FILE, "%s:\n", desc_name); \
- fprintf (FILE, "\t%s %s\n", init_ptr, orig_name); \
- fprintf (FILE, "\t%s _GLOBAL_OFFSET_TABLE_\n", init_ptr); \
- if (DEFAULT_ABI == ABI_AIX) \
- fprintf (FILE, "\t%s 0\n", init_ptr); \
- fprintf (FILE, "\t.previous\n"); \
- } \
- ASM_OUTPUT_LABEL (FILE, NAME); \
- } while (0)
+ rs6000_elf_declare_function_name ((FILE), (NAME), (DECL))
/* The USER_LABEL_PREFIX stuff is affected by the -fleading-underscore
flag. The LOCAL_LABEL_PREFIX variable is used by dbxelf.h. */
@@ -662,7 +622,7 @@ extern int rs6000_pic_labelno;
#define LOCAL_LABEL_PREFIX "."
#define USER_LABEL_PREFIX ""
-/* svr4.h overrides ASM_OUTPUT_INTERNAL_LABEL. */
+/* svr4.h overrides (*targetm.asm_out.internal_label). */
#define ASM_OUTPUT_INTERNAL_LABEL_PREFIX(FILE,PREFIX) \
asm_fprintf (FILE, "%L%s", PREFIX)
@@ -697,7 +657,8 @@ do { \
{ \
fprintf (FILE, "%s", LCOMM_ASM_OP); \
assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \
+ (SIZE), (ALIGN) / BITS_PER_UNIT); \
} \
ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
} while (0)
@@ -708,6 +669,20 @@ do { \
ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
} while (0)
+#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
+/* To support -falign-* switches we need to use .p2align so
+ that alignment directives in code sections will be padded
+ with no-op instructions, rather than zeroes. */
+#define ASM_OUTPUT_MAX_SKIP_ALIGN(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
+
/* This is how to output code to push a register on the stack.
It need not be very fast code.
@@ -747,16 +722,6 @@ do { \
|| (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'V' \
|| (CHAR) == 'B' || (CHAR) == 'b' || (CHAR) == 'G')
-/* Output .file. */
-/* Override elfos.h definition. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
-do { \
- output_file_directive ((FILE), main_input_filename); \
- rs6000_file_start (FILE, TARGET_CPU_DEFAULT); \
-} while (0)
-
-
extern int fixuplabelno;
/* Handle constructors specially for -mrelocatable. */
@@ -772,8 +737,21 @@ extern int fixuplabelno;
/* Historically we have also supported stabs debugging. */
#define DBX_DEBUGGING_INFO 1
+#define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
+
+/* Map register numbers held in the call frame info that gcc has
+ collected using DWARF_FRAME_REGNUM to those that should be output in
+ .debug_frame and .eh_frame. We continue to use gcc hard reg numbers
+ for .eh_frame, but use the numbers mandated by the various ABIs for
+ .debug_frame. rs6000_emit_prologue has translated any combination of
+ CR2, CR3, CR4 saves to a save of CR2. The actual code emitted saves
+ the whole of CR, so we map CR2_REGNO to the DWARF reg for CR. */
+#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) \
+ ((FOR_EH) ? (REGNO) \
+ : (REGNO) == CR2_REGNO ? 64 \
+ : DBX_REGISTER_NUMBER (REGNO))
+
#define TARGET_ENCODE_SECTION_INFO rs6000_elf_encode_section_info
-#define TARGET_STRIP_NAME_ENCODING rs6000_elf_strip_name_encoding
#define TARGET_IN_SMALL_DATA_P rs6000_elf_in_small_data_p
#define TARGET_SECTION_TYPE_FLAGS rs6000_elf_section_type_flags
@@ -782,25 +760,8 @@ extern int fixuplabelno;
#define RS6000_OUTPUT_BASENAME(FILE, NAME) \
assemble_name (FILE, NAME)
-/* This is how to output a reference to a user-level label named NAME.
- `assemble_name' uses this. */
-
-/* Override elfos.h definition. */
-#undef ASM_OUTPUT_LABELREF
-#define ASM_OUTPUT_LABELREF(FILE,NAME) \
-do { \
- const char *_name = NAME; \
- if (*_name == '@') \
- _name++; \
- \
- if (*_name == '*') \
- fprintf (FILE, "%s", _name + 1); \
- else \
- asm_fprintf (FILE, "%U%s", _name); \
-} while (0)
-
-/* But, to make this work, we have to output the stabs for the function
- name *first*... */
+/* We have to output the stabs for the function name *first*, before
+ outputting its label. */
#define DBX_FUNCTION_FIRST
@@ -810,6 +771,25 @@ do { \
#define TARGET_VERSION fprintf (stderr, " (PowerPC System V.4)");
#endif
+#define TARGET_OS_SYSV_CPP_BUILTINS() \
+ do \
+ { \
+ if (flag_pic == 1) \
+ { \
+ builtin_define ("__pic__=1"); \
+ builtin_define ("__PIC__=1"); \
+ } \
+ else if (flag_pic == 2) \
+ { \
+ builtin_define ("__pic__=2"); \
+ builtin_define ("__PIC__=2"); \
+ } \
+ if (target_flags_explicit \
+ & MASK_RELOCATABLE) \
+ builtin_define ("_RELOCATABLE"); \
+ } \
+ while (0)
+
#ifndef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
do \
@@ -821,6 +801,7 @@ do { \
builtin_assert ("system=svr4"); \
builtin_assert ("cpu=powerpc"); \
builtin_assert ("machine=powerpc"); \
+ TARGET_OS_SYSV_CPP_BUILTINS (); \
} \
while (0)
#endif
@@ -831,16 +812,17 @@ do { \
#define ASM_SPEC "%(asm_cpu) \
%{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \
%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
-%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} \
-%{memb} %{!memb: %{msdata: -memb} %{msdata=eabi: -memb}} \
-%{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian} \
-%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
- %{mcall-freebsd: -mbig} \
- %{mcall-i960-old: -mlittle} \
- %{mcall-linux: -mbig} \
- %{mcall-gnu: -mbig} \
- %{mcall-netbsd: -mbig} \
-}}}}"
+%{mrelocatable} %{mrelocatable-lib} %{fpic|fpie|fPIC|fPIE:-K PIC} \
+%{memb|msdata|msdata=eabi: -memb} \
+%{mlittle|mlittle-endian:-mlittle; \
+ mbig|mbig-endian :-mbig; \
+ mcall-aixdesc | \
+ mcall-freebsd | \
+ mcall-netbsd | \
+ mcall-openbsd | \
+ mcall-linux | \
+ mcall-gnu :-mbig; \
+ mcall-i960-old :-mlittle}"
#define CC1_ENDIAN_BIG_SPEC ""
@@ -855,19 +837,16 @@ do { \
/* Pass -G xxx to the compiler and set correct endian mode. */
#define CC1_SPEC "%{G*} \
-%{mlittle: %(cc1_endian_little)} %{!mlittle: %{mlittle-endian: %(cc1_endian_little)}} \
-%{mbig: %(cc1_endian_big)} %{!mbig: %{mbig-endian: %(cc1_endian_big)}} \
-%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: \
- %{mcall-aixdesc: -mbig %(cc1_endian_big) } \
- %{mcall-freebsd: -mbig %(cc1_endian_big) } \
- %{mcall-i960-old: -mlittle %(cc1_endian_little) } \
- %{mcall-linux: -mbig %(cc1_endian_big) } \
- %{mcall-gnu: -mbig %(cc1_endian_big) } \
- %{mcall-netbsd: -mbig %(cc1_endian_big) } \
- %{!mcall-aixdesc: %{!mcall-freebsd: %{!mcall-i960-old: %{!mcall-linux: %{!mcall-gnu: %{!mcall-netbsd: \
- %(cc1_endian_default) \
- }}}}}} \
-}}}} \
+%{mlittle|mlittle-endian: %(cc1_endian_little); \
+ mbig |mbig-endian : %(cc1_endian_big); \
+ mcall-aixdesc | \
+ mcall-freebsd | \
+ mcall-netbsd | \
+ mcall-openbsd | \
+ mcall-linux | \
+ mcall-gnu : -mbig %(cc1_endian_big); \
+ mcall-i960-old : -mlittle %(cc1_endian_little); \
+ : %(cc1_endian_default)} \
%{mno-sdata: -msdata=none } \
%{meabi: %{!mcall-*: -mcall-sysv }} \
%{!meabi: %{!mno-eabi: \
@@ -876,7 +855,8 @@ do { \
%{mcall-i960-old: -meabi } \
%{mcall-linux: -mno-eabi } \
%{mcall-gnu: -mno-eabi } \
- %{mcall-netbsd: -mno-eabi }}} \
+ %{mcall-netbsd: -mno-eabi } \
+ %{mcall-openbsd: -mno-eabi }}} \
%{msdata: -msdata=default} \
%{mno-sdata: -msdata=none} \
%{profile: -p}"
@@ -900,18 +880,17 @@ do { \
/* Default starting address if specified. */
#define LINK_START_SPEC "\
-%{mads: %(link_start_ads) } \
-%{myellowknife: %(link_start_yellowknife) } \
-%{mmvme: %(link_start_mvme) } \
-%{msim: %(link_start_sim) } \
-%{mwindiss: %(link_start_windiss) } \
-%{mcall-freebsd: %(link_start_freebsd) } \
-%{mcall-linux: %(link_start_linux) } \
-%{mcall-gnu: %(link_start_gnu) } \
-%{mcall-netbsd: %(link_start_netbsd) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mwindiss: \
- %{!mcall-linux: %{!mcall-gnu: %{!mcall-netbsd: \
- %{!mcall-freebsd: %(link_start_default) }}}}}}}}}"
+%{mads : %(link_start_ads) ; \
+ myellowknife : %(link_start_yellowknife) ; \
+ mmvme : %(link_start_mvme) ; \
+ msim : %(link_start_sim) ; \
+ mwindiss : %(link_start_windiss) ; \
+ mcall-freebsd: %(link_start_freebsd) ; \
+ mcall-linux : %(link_start_linux) ; \
+ mcall-gnu : %(link_start_gnu) ; \
+ mcall-netbsd : %(link_start_netbsd) ; \
+ mcall-openbsd: %(link_start_openbsd) ; \
+ : %(link_start_default) }"
#define LINK_START_DEFAULT_SPEC ""
@@ -959,97 +938,85 @@ do { \
/* Any specific OS flags. */
#define LINK_OS_SPEC "\
-%{mads: %(link_os_ads) } \
-%{myellowknife: %(link_os_yellowknife) } \
-%{mmvme: %(link_os_mvme) } \
-%{msim: %(link_os_sim) } \
-%{mwindiss: %(link_os_windiss) } \
-%{mcall-freebsd: %(link_os_freebsd) } \
-%{mcall-linux: %(link_os_linux) } \
-%{mcall-gnu: %(link_os_gnu) } \
-%{mcall-netbsd: %(link_os_netbsd) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mwindiss: \
- %{!mcall-freebsd: %{!mcall-linux: %{!mcall-gnu: \
- %{!mcall-netbsd: %(link_os_default) }}}}}}}}}"
+%{mads : %(link_os_ads) ; \
+ myellowknife : %(link_os_yellowknife) ; \
+ mmvme : %(link_os_mvme) ; \
+ msim : %(link_os_sim) ; \
+ mwindiss : %(link_os_windiss) ; \
+ mcall-freebsd: %(link_os_freebsd) ; \
+ mcall-linux : %(link_os_linux) ; \
+ mcall-gnu : %(link_os_gnu) ; \
+ mcall-netbsd : %(link_os_netbsd) ; \
+ mcall-openbsd: %(link_os_openbsd) ; \
+ : %(link_os_default) }"
#define LINK_OS_DEFAULT_SPEC ""
-#define CPP_SYSV_SPEC \
-"%{mrelocatable*: -D_RELOCATABLE} \
-%{fpic: -D__PIC__=1 -D__pic__=1} \
-%{!fpic: %{fPIC: -D__PIC__=2 -D__pic__=2}}"
-
/* Override rs6000.h definition. */
#undef CPP_SPEC
-#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_sysv) \
-%{mads: %(cpp_os_ads) } \
-%{myellowknife: %(cpp_os_yellowknife) } \
-%{mmvme: %(cpp_os_mvme) } \
-%{msim: %(cpp_os_sim) } \
-%{mwindiss: %(cpp_os_windiss) } \
-%{mcall-freebsd: %(cpp_os_freebsd) } \
-%{mcall-linux: %(cpp_os_linux) } \
-%{mcall-gnu: %(cpp_os_gnu) } \
-%{mcall-netbsd: %(cpp_os_netbsd) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mwindiss: \
- %{!mcall-freebsd: %{!mcall-linux: %{!mcall-gnu: \
- %{!mcall-netbsd: %(cpp_os_default) }}}}}}}}}"
+#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} \
+%{mads : %(cpp_os_ads) ; \
+ myellowknife : %(cpp_os_yellowknife) ; \
+ mmvme : %(cpp_os_mvme) ; \
+ msim : %(cpp_os_sim) ; \
+ mwindiss : %(cpp_os_windiss) ; \
+ mcall-freebsd: %(cpp_os_freebsd) ; \
+ mcall-linux : %(cpp_os_linux) ; \
+ mcall-gnu : %(cpp_os_gnu) ; \
+ mcall-netbsd : %(cpp_os_netbsd) ; \
+ mcall-openbsd: %(cpp_os_openbsd) ; \
+ : %(cpp_os_default) }"
#define CPP_OS_DEFAULT_SPEC ""
/* Override svr4.h definition. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "\
-%{mads: %(startfile_ads) } \
-%{myellowknife: %(startfile_yellowknife) } \
-%{mmvme: %(startfile_mvme) } \
-%{msim: %(startfile_sim) } \
-%{mwindiss: %(startfile_windiss) } \
-%{mcall-freebsd: %(startfile_freebsd) } \
-%{mcall-linux: %(startfile_linux) } \
-%{mcall-gnu: %(startfile_gnu) } \
-%{mcall-netbsd: %(startfile_netbsd) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mwindiss: \
- %{!mcall-freebsd: %{!mcall-linux: %{!mcall-gnu: \
- %{!mcall-netbsd: %(startfile_default) }}}}}}}}}"
+%{mads : %(startfile_ads) ; \
+ myellowknife : %(startfile_yellowknife) ; \
+ mmvme : %(startfile_mvme) ; \
+ msim : %(startfile_sim) ; \
+ mwindiss : %(startfile_windiss) ; \
+ mcall-freebsd: %(startfile_freebsd) ; \
+ mcall-linux : %(startfile_linux) ; \
+ mcall-gnu : %(startfile_gnu) ; \
+ mcall-netbsd : %(startfile_netbsd) ; \
+ mcall-openbsd: %(startfile_openbsd) ; \
+ : %(startfile_default) }"
#define STARTFILE_DEFAULT_SPEC ""
/* Override svr4.h definition. */
#undef LIB_SPEC
#define LIB_SPEC "\
-%{mads: %(lib_ads) } \
-%{myellowknife: %(lib_yellowknife) } \
-%{mmvme: %(lib_mvme) } \
-%{msim: %(lib_sim) } \
-%{mwindiss: %(lib_windiss) } \
-%{mcall-freebsd: %(lib_freebsd) } \
-%{mcall-linux: %(lib_linux) } \
-%{mcall-gnu: %(lib_gnu) } \
-%{mcall-netbsd: %(lib_netbsd) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mwindiss: \
- %{!mcall-freebsd: %{!mcall-linux: %{!mcall-gnu: \
- %{!mcall-netbsd: %(lib_default) }}}}}}}}}"
+%{mads : %(lib_ads) ; \
+ myellowknife : %(lib_yellowknife) ; \
+ mmvme : %(lib_mvme) ; \
+ msim : %(lib_sim) ; \
+ mwindiss : %(lib_windiss) ; \
+ mcall-freebsd: %(lib_freebsd) ; \
+ mcall-linux : %(lib_linux) ; \
+ mcall-gnu : %(lib_gnu) ; \
+ mcall-netbsd : %(lib_netbsd) ; \
+ mcall-openbsd: %(lib_openbsd) ; \
+ : %(lib_default) }"
#define LIB_DEFAULT_SPEC ""
/* Override svr4.h definition. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "\
-%{mads: crtsavres.o%s %(endfile_ads)} \
-%{myellowknife: crtsavres.o%s %(endfile_yellowknife)} \
-%{mmvme: crtsavres.o%s %(endfile_mvme)} \
-%{msim: crtsavres.o%s %(endfile_sim)} \
-%{mwindiss: %(endfile_windiss)} \
-%{mcall-freebsd: crtsavres.o%s %(endfile_freebsd) } \
-%{mcall-linux: crtsavres.o%s %(endfile_linux) } \
-%{mcall-gnu: crtsavres.o%s %(endfile_gnu) } \
-%{mcall-netbsd: crtsavres.o%s %(endfile_netbsd) } \
-%{mvxworks: crtsavres.o%s %(endfile_vxworks) } \
-%{!mads: %{!myellowknife: %{!mmvme: %{!msim: %{!mwindiss: \
- %{!mcall-freebsd: %{!mcall-linux: %{!mcall-gnu: \
- %{!mcall-netbsd: %{!mvxworks: %(crtsavres_default) \
- %(endfile_default) }}}}}}}}}}"
+%{mads : crtsavres.o%s %(endfile_ads) ; \
+ myellowknife : crtsavres.o%s %(endfile_yellowknife) ; \
+ mmvme : crtsavres.o%s %(endfile_mvme) ; \
+ msim : crtsavres.o%s %(endfile_sim) ; \
+ mwindiss : %(endfile_windiss) ; \
+ mcall-freebsd: crtsavres.o%s %(endfile_freebsd) ; \
+ mcall-linux : crtsavres.o%s %(endfile_linux) ; \
+ mcall-gnu : crtsavres.o%s %(endfile_gnu) ; \
+ mcall-netbsd : crtsavres.o%s %(endfile_netbsd) ; \
+ mcall-openbsd: crtsavres.o%s %(endfile_openbsd) ; \
+ : %(crtsavres_default) %(endfile_default) }"
#define CRTSAVRES_DEFAULT_SPEC "crtsavres.o%s"
@@ -1110,7 +1077,7 @@ do { \
/* FreeBSD support. */
#define CPP_OS_FREEBSD_SPEC "\
- -D__ELF__ -D__PPC__ -D__ppc__ -D__PowerPC__ -D__powerpc__ \
+ -D__PPC__ -D__ppc__ -D__PowerPC__ -D__powerpc__ \
-Acpu=powerpc -Amachine=powerpc"
#define STARTFILE_FREEBSD_SPEC FBSD_STARTFILE_SPEC
@@ -1120,38 +1087,32 @@ do { \
#define LINK_OS_FREEBSD_SPEC "\
%{p:%e`-p' not supported; use `-pg' and gprof(1)} \
- %{Wl,*:%*} \
- %{v:-V} \
- %{assert*} %{R*} %{rpath*} %{defsym*} \
- %{shared:-Bshareable %{h*} %{soname*}} \
- %{!shared: \
- %{!static: \
- %{rdynamic: -export-dynamic} \
- %{!dynamic-linker: -dynamic-linker /usr/libexec/ld-elf.so.1}} \
- %{static:-Bstatic}} \
- %{symbolic:-Bsymbolic}"
+ %{Wl,*:%*} \
+ %{v:-V} \
+ %{assert*} %{R*} %{rpath*} %{defsym*} \
+ %{shared:-Bshareable %{h*} %{soname*}} \
+ %{!shared: \
+ %{!static: \
+ %{rdynamic: -export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }} \
+ %{static:-Bstatic}} \
+ %{symbolic:-Bsymbolic}"
/* GNU/Linux support. */
-#ifdef USE_GNULIBC_1
-#define LIB_LINUX_SPEC "%{mnewlib: --start-group -llinux -lc --end-group } \
-%{!mnewlib: -lc }"
-#else
#define LIB_LINUX_SPEC "%{mnewlib: --start-group -llinux -lc --end-group } \
-%{!mnewlib: %{shared:-lc} %{!shared: %{pthread:-lpthread } \
-%{profile:-lc_p} %{!profile:-lc}}}"
-#endif
+%{!mnewlib: %{pthread:-lpthread} %{shared:-lc} \
+%{!shared: %{profile:-lc_p} %{!profile:-lc}}}"
-#ifdef USE_GNULIBC_1
+#ifdef HAVE_LD_PIE
#define STARTFILE_LINUX_SPEC "\
-%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \
-%{mnewlib: ecrti.o%s} %{!mnewlib: crti.o%s} \
-%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+%{!shared: %{pg|p:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
+%{mnewlib:ecrti.o%s;:crti.o%s} \
+%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#else
#define STARTFILE_LINUX_SPEC "\
-%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \
-%{mnewlib: ecrti.o%s} %{!mnewlib: crti.o%s} \
-%{static:crtbeginT.o%s} \
-%{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
+%{!shared: %{pg|p:gcrt1.o%s;:crt1.o%s}} \
+%{mnewlib:ecrti.o%s;:crti.o%s} \
+%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#endif
#define ENDFILE_LINUX_SPEC "%{!shared:crtend.o%s} %{shared:crtendS.o%s} \
@@ -1163,25 +1124,16 @@ do { \
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}"
-#if !defined(USE_GNULIBC_1) && defined(HAVE_LD_EH_FRAME_HDR)
+#if defined(HAVE_LD_EH_FRAME_HDR)
# define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
#endif
-#ifdef USE_GNULIBC_1
-#define CPP_OS_LINUX_SPEC "-D__unix__ -D__gnu_linux__ -D__linux__ \
-%{!undef: \
- %{!ansi: \
- %{!std=*:-Dunix -D__unix -Dlinux -D__linux} \
- %{std=gnu*:-Dunix -D__unix -Dlinux -D__linux}}} \
--Asystem=unix -Asystem=posix"
-#else
#define CPP_OS_LINUX_SPEC "-D__unix__ -D__gnu_linux__ -D__linux__ \
%{!undef: \
%{!ansi: \
%{!std=*:-Dunix -D__unix -Dlinux -D__linux} \
%{std=gnu*:-Dunix -D__unix -Dlinux -D__linux}}} \
--Asystem=unix -Asystem=posix %{pthread:-D_REENTRANT}"
-#endif
+-Asystem=linux -Asystem=unix -Asystem=posix %{pthread:-D_REENTRANT}"
/* GNU/Hurd support. */
#define LIB_GNU_SPEC "%{mnewlib: --start-group -lgnu -lc --end-group } \
@@ -1229,64 +1181,35 @@ ncrtn.o%s"
%{!dynamic-linker:-dynamic-linker /usr/libexec/ld.elf_so}}}"
#define CPP_OS_NETBSD_SPEC "\
--D__powerpc__ -D__NetBSD__ -D__ELF__ -D__KPRINTF_ATTRIBUTE__"
-
-/* RTEMS support. */
-
-#define CPP_OS_RTEMS_SPEC "\
-%{!mcpu*: %{!Dppc*: %{!Dmpc*: -Dmpc750} } }\
-%{mcpu=403: %{!Dppc*: %{!Dmpc*: -Dppc403} } } \
-%{mcpu=505: %{!Dppc*: %{!Dmpc*: -Dmpc505} } } \
-%{mcpu=601: %{!Dppc*: %{!Dmpc*: -Dppc601} } } \
-%{mcpu=602: %{!Dppc*: %{!Dmpc*: -Dppc602} } } \
-%{mcpu=603: %{!Dppc*: %{!Dmpc*: -Dppc603} } } \
-%{mcpu=603e: %{!Dppc*: %{!Dmpc*: -Dppc603e} } } \
-%{mcpu=604: %{!Dppc*: %{!Dmpc*: -Dmpc604} } } \
-%{mcpu=750: %{!Dppc*: %{!Dmpc*: -Dmpc750} } } \
-%{mcpu=821: %{!Dppc*: %{!Dmpc*: -Dmpc821} } } \
-%{mcpu=860: %{!Dppc*: %{!Dmpc*: -Dmpc860} } }"
-
-/* VxWorks support. */
-/* VxWorks does all the library stuff itself. */
-#define LIB_VXWORKS_SPEC ""
-
-/* VxWorks provides the functionality of crt0.o and friends itself. */
-
-#define STARTFILE_VXWORKS_SPEC ""
-
-#define ENDFILE_VXWORKS_SPEC ""
-
-/* Because it uses ld -r, vxworks has no start/end files, nor starting
- address. */
-
-#define LINK_START_VXWORKS_SPEC ""
-
-#define LINK_OS_VXWORKS_SPEC "-r"
-
-#define CPP_OS_VXWORKS_SPEC "\
--DCPU_FAMILY=PPC \
-%{!mcpu*: \
- %{mpowerpc*: -DCPU=PPC603} \
- %{!mno-powerpc: -DCPU=PPC603}} \
-%{mcpu=powerpc: -DCPU=PPC603} \
-%{mcpu=401: -DCPU=PPC403} \
-%{mcpu=403: -DCPU=PPC403} \
-%{mcpu=405: -DCPU=PPC405} \
-%{mcpu=601: -DCPU=PPC601} \
-%{mcpu=602: -DCPU=PPC603} \
-%{mcpu=603: -DCPU=PPC603} \
-%{mcpu=603e: -DCPU=PPC603} \
-%{mcpu=ec603e: -DCPU=PPC603} \
-%{mcpu=604: -DCPU=PPC604} \
-%{mcpu=604e: -DCPU=PPC604} \
-%{mcpu=620: -DCPU=PPC604} \
-%{mcpu=740: -DCPU=PPC603} \
-%{mcpu=7450: -DCPU=PPC603} \
-%{mcpu=750: -DCPU=PPC603} \
-%{mcpu=801: -DCPU=PPC603} \
-%{mcpu=821: -DCPU=PPC603} \
-%{mcpu=823: -DCPU=PPC603} \
-%{mcpu=860: -DCPU=PPC603}"
+-D__powerpc__ -D__NetBSD__ -D__KPRINTF_ATTRIBUTE__"
+
+/* OpenBSD support. */
+#ifndef LIB_OPENBSD_SPEC
+#define LIB_OPENBSD_SPEC "%{!shared:%{pthread:-lpthread%{p:_p}%{!p:%{pg:_p}}}} %{!shared:-lc%{p:_p}%{!p:%{pg:_p}}}"
+#endif
+
+#ifndef STARTFILE_OPENBSD_SPEC
+#define STARTFILE_OPENBSD_SPEC "\
+%{!shared: %{pg:gcrt0.o%s} %{!pg:%{p:gcrt0.o%s} %{!p:crt0.o%s}}} \
+%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+#endif
+
+#ifndef ENDFILE_OPENBSD_SPEC
+#define ENDFILE_OPENBSD_SPEC "\
+%{!shared:crtend.o%s} %{shared:crtendS.o%s}"
+#endif
+
+#ifndef LINK_START_OPENBSD_SPEC
+#define LINK_START_OPENBSD_SPEC "-Ttext 0x400074"
+#endif
+
+#ifndef LINK_OS_OPENBSD_SPEC
+#define LINK_OS_OPENBSD_SPEC ""
+#endif
+
+#ifndef CPP_OS_OPENBSD_SPEC
+#define CPP_OS_OPENBSD_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_POSIX_THREADS}"
+#endif
/* WindISS support. */
@@ -1311,7 +1234,6 @@ ncrtn.o%s"
/* Override rs6000.h definition. */
#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
- { "cpp_sysv", CPP_SYSV_SPEC }, \
{ "crtsavres_default", CRTSAVRES_DEFAULT_SPEC }, \
{ "lib_ads", LIB_ADS_SPEC }, \
{ "lib_yellowknife", LIB_YELLOWKNIFE_SPEC }, \
@@ -1321,7 +1243,7 @@ ncrtn.o%s"
{ "lib_gnu", LIB_GNU_SPEC }, \
{ "lib_linux", LIB_LINUX_SPEC }, \
{ "lib_netbsd", LIB_NETBSD_SPEC }, \
- { "lib_vxworks", LIB_VXWORKS_SPEC }, \
+ { "lib_openbsd", LIB_OPENBSD_SPEC }, \
{ "lib_windiss", LIB_WINDISS_SPEC }, \
{ "lib_default", LIB_DEFAULT_SPEC }, \
{ "startfile_ads", STARTFILE_ADS_SPEC }, \
@@ -1332,7 +1254,7 @@ ncrtn.o%s"
{ "startfile_gnu", STARTFILE_GNU_SPEC }, \
{ "startfile_linux", STARTFILE_LINUX_SPEC }, \
{ "startfile_netbsd", STARTFILE_NETBSD_SPEC }, \
- { "startfile_vxworks", STARTFILE_VXWORKS_SPEC }, \
+ { "startfile_openbsd", STARTFILE_OPENBSD_SPEC }, \
{ "startfile_windiss", STARTFILE_WINDISS_SPEC }, \
{ "startfile_default", STARTFILE_DEFAULT_SPEC }, \
{ "endfile_ads", ENDFILE_ADS_SPEC }, \
@@ -1343,7 +1265,7 @@ ncrtn.o%s"
{ "endfile_gnu", ENDFILE_GNU_SPEC }, \
{ "endfile_linux", ENDFILE_LINUX_SPEC }, \
{ "endfile_netbsd", ENDFILE_NETBSD_SPEC }, \
- { "endfile_vxworks", ENDFILE_VXWORKS_SPEC }, \
+ { "endfile_openbsd", ENDFILE_OPENBSD_SPEC }, \
{ "endfile_windiss", ENDFILE_WINDISS_SPEC }, \
{ "endfile_default", ENDFILE_DEFAULT_SPEC }, \
{ "link_path", LINK_PATH_SPEC }, \
@@ -1358,7 +1280,7 @@ ncrtn.o%s"
{ "link_start_gnu", LINK_START_GNU_SPEC }, \
{ "link_start_linux", LINK_START_LINUX_SPEC }, \
{ "link_start_netbsd", LINK_START_NETBSD_SPEC }, \
- { "link_start_vxworks", LINK_START_VXWORKS_SPEC }, \
+ { "link_start_openbsd", LINK_START_OPENBSD_SPEC }, \
{ "link_start_windiss", LINK_START_WINDISS_SPEC }, \
{ "link_start_default", LINK_START_DEFAULT_SPEC }, \
{ "link_os", LINK_OS_SPEC }, \
@@ -1370,7 +1292,7 @@ ncrtn.o%s"
{ "link_os_linux", LINK_OS_LINUX_SPEC }, \
{ "link_os_gnu", LINK_OS_GNU_SPEC }, \
{ "link_os_netbsd", LINK_OS_NETBSD_SPEC }, \
- { "link_os_vxworks", LINK_OS_VXWORKS_SPEC }, \
+ { "link_os_openbsd", LINK_OS_OPENBSD_SPEC }, \
{ "link_os_windiss", LINK_OS_WINDISS_SPEC }, \
{ "link_os_default", LINK_OS_DEFAULT_SPEC }, \
{ "cc1_endian_big", CC1_ENDIAN_BIG_SPEC }, \
@@ -1384,10 +1306,13 @@ ncrtn.o%s"
{ "cpp_os_gnu", CPP_OS_GNU_SPEC }, \
{ "cpp_os_linux", CPP_OS_LINUX_SPEC }, \
{ "cpp_os_netbsd", CPP_OS_NETBSD_SPEC }, \
- { "cpp_os_rtems", CPP_OS_RTEMS_SPEC }, \
- { "cpp_os_vxworks", CPP_OS_VXWORKS_SPEC }, \
+ { "cpp_os_openbsd", CPP_OS_OPENBSD_SPEC }, \
{ "cpp_os_windiss", CPP_OS_WINDISS_SPEC }, \
- { "cpp_os_default", CPP_OS_DEFAULT_SPEC },
+ { "cpp_os_default", CPP_OS_DEFAULT_SPEC }, \
+ { "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }, \
+ SUBSUBTARGET_EXTRA_SPECS
+
+#define SUBSUBTARGET_EXTRA_SPECS
/* Define this macro as a C expression for the initializer of an
array of string to tell the driver program which options are
@@ -1420,63 +1345,6 @@ ncrtn.o%s"
#define HANDLE_PRAGMA_PACK_PUSH_POP 1
-/* Define library calls for quad FP operations. These are all part of the
- PowerPC 32bit ABI. */
-#define ADDTF3_LIBCALL "_q_add"
-#define DIVTF3_LIBCALL "_q_div"
-#define EXTENDDFTF2_LIBCALL "_q_dtoq"
-#define EQTF2_LIBCALL "_q_feq"
-#define GETF2_LIBCALL "_q_fge"
-#define GTTF2_LIBCALL "_q_fgt"
-#define LETF2_LIBCALL "_q_fle"
-#define LTTF2_LIBCALL "_q_flt"
-#define NETF2_LIBCALL "_q_fne"
-#define FLOATSITF2_LIBCALL "_q_itoq"
-#define MULTF3_LIBCALL "_q_mul"
-#define NEGTF2_LIBCALL "_q_neg"
-#define TRUNCTFDF2_LIBCALL "_q_qtod"
-#define FIX_TRUNCTFSI2_LIBCALL "_q_qtoi"
-#define TRUNCTFSF2_LIBCALL "_q_qtos"
-#define FIXUNS_TRUNCTFSI2_LIBCALL "_q_qtou"
-#define SQRTTF_LIBCALL "_q_sqrt"
-#define EXTENDSFTF2_LIBCALL "_q_stoq"
-#define SUBTF3_LIBCALL "_q_sub"
-#define FLOATUNSSITF2_LIBCALL "_q_utoq"
-
-#define INIT_TARGET_OPTABS \
- do { \
- if (TARGET_HARD_FLOAT) \
- { \
- add_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (ADDTF3_LIBCALL); \
- sub_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (SUBTF3_LIBCALL); \
- neg_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (NEGTF2_LIBCALL); \
- smul_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (MULTF3_LIBCALL); \
- sdiv_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (DIVTF3_LIBCALL); \
- eqtf2_libfunc = init_one_libfunc (EQTF2_LIBCALL); \
- netf2_libfunc = init_one_libfunc (NETF2_LIBCALL); \
- gttf2_libfunc = init_one_libfunc (GTTF2_LIBCALL); \
- getf2_libfunc = init_one_libfunc (GETF2_LIBCALL); \
- lttf2_libfunc = init_one_libfunc (LTTF2_LIBCALL); \
- letf2_libfunc = init_one_libfunc (LETF2_LIBCALL); \
- trunctfsf2_libfunc = init_one_libfunc (TRUNCTFSF2_LIBCALL); \
- trunctfdf2_libfunc = init_one_libfunc (TRUNCTFDF2_LIBCALL); \
- extendsftf2_libfunc = init_one_libfunc (EXTENDSFTF2_LIBCALL); \
- extenddftf2_libfunc = init_one_libfunc (EXTENDDFTF2_LIBCALL); \
- floatsitf_libfunc = init_one_libfunc (FLOATSITF2_LIBCALL); \
- fixtfsi_libfunc = init_one_libfunc (FIX_TRUNCTFSI2_LIBCALL); \
- fixunstfsi_libfunc \
- = init_one_libfunc (FIXUNS_TRUNCTFSI2_LIBCALL); \
- if (TARGET_PPC_GPOPT || TARGET_POWER2) \
- sqrt_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (SQRTTF_LIBCALL); \
- } \
- } while (0)
-
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations. */
diff --git a/contrib/gcc/config/rs6000/sysv4le.h b/contrib/gcc/config/rs6000/sysv4le.h
index fda84775cc3b..38be8a6886fd 100644
--- a/contrib/gcc/config/rs6000/sysv4le.h
+++ b/contrib/gcc/config/rs6000/sysv4le.h
@@ -1,26 +1,26 @@
-/* Target definitions for GNU compiler for a little endian PowerPC
+/* Target definitions for GCC for a little endian PowerPC
running System V.4
- Copyright (C) 1995, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2000, 2003 Free Software Foundation, Inc.
Contributed by Cygnus Support.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef TARGET_DEFAULT
+#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_LITTLE_ENDIAN)
#undef CC1_ENDIAN_DEFAULT_SPEC
@@ -33,14 +33,5 @@ Boston, MA 02111-1307, USA. */
%{mcall-linux: --oformat elf32-powerpc} \
}}}}"
-/* Define this macro as a C expression for the initializer of an
- array of string to tell the driver program which options are
- defaults for this target and thus do not need to be handled
- specially when using `MULTILIB_OPTIONS'.
-
- Do not define this macro if `MULTILIB_OPTIONS' is not defined in
- the target makefile fragment or if none of the options listed in
- `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
-
#undef MULTILIB_DEFAULTS
#define MULTILIB_DEFAULTS { "mlittle", "mcall-sysv" }
diff --git a/contrib/gcc/config/rs6000/t-beos b/contrib/gcc/config/rs6000/t-beos
index 1d4fbf744753..badffefff429 100644
--- a/contrib/gcc/config/rs6000/t-beos
+++ b/contrib/gcc/config/rs6000/t-beos
@@ -1,23 +1,8 @@
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
- cat $(srcdir)/config/fp-bit.c > dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
-# Build the libraries for both hard and soft floating point
+# Build the libraries for both hard & soft floating point and ppc/common.
MULTILIB_OPTIONS = msoft-float mcpu=common
MULTILIB_DIRNAMES = soft-float common
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
-
# This is probably the correct define, to override the Makefile
# default, but using it causes more problems than it solves.
#
diff --git a/contrib/gcc/config/rs6000/t-darwin b/contrib/gcc/config/rs6000/t-darwin
index 7aca023302f9..185bb00eed2b 100644
--- a/contrib/gcc/config/rs6000/t-darwin
+++ b/contrib/gcc/config/rs6000/t-darwin
@@ -1,2 +1,7 @@
-# Library code must include trampoline support.
-LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-tramp.asm
+# Add trampoline and long double support to libgcc.
+LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/darwin-tramp.asm \
+ $(srcdir)/config/rs6000/darwin-ldouble.c
+
+# For libgcc, we always want 128-bit long double, since a libgcc built with
+# that will work without it.
+TARGET_LIBGCC2_CFLAGS = -mlong-double-128
diff --git a/contrib/gcc/config/rs6000/t-fprules b/contrib/gcc/config/rs6000/t-fprules
new file mode 100644
index 000000000000..4fb09a2789a4
--- /dev/null
+++ b/contrib/gcc/config/rs6000/t-fprules
@@ -0,0 +1,29 @@
+# We want fine grained libraries, so use the new code to build the
+# floating point emulation libraries.
+FPBIT = fp-bit.c
+DPBIT = dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+MULTILIB_MATCHES_FLOAT = msoft-float=mcpu?401 \
+ msoft-float=mcpu?403 \
+ msoft-float=mcpu?405 \
+ msoft-float=mcpu?ec603e \
+ msoft-float=mcpu?801 \
+ msoft-float=mcpu?821 \
+ msoft-float=mcpu?823 \
+ msoft-float=mcpu?860
+
+# Build the libraries for both hard and soft floating point by default
+
+MULTILIB_OPTIONS = msoft-float
+MULTILIB_DIRNAMES = soft-float
+MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT}
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
diff --git a/contrib/gcc/config/rs6000/t-linux64 b/contrib/gcc/config/rs6000/t-linux64
index af7b44bd70b7..77ba93e91525 100644
--- a/contrib/gcc/config/rs6000/t-linux64
+++ b/contrib/gcc/config/rs6000/t-linux64
@@ -1,19 +1,44 @@
-# Override t-linux. We don't want -fPIC.
-CRTSTUFF_T_CFLAGS_S =
-TARGET_LIBGCC2_CFLAGS =
-EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o \
- crtsavres.o
+#rs6000/t-linux64
-# These functions are needed for soft-float on powerpc64-linux.
-LIB2FUNCS_EXTRA = $(srcdir)/config/rs6000/ppc64-fp.c
+LIB2FUNCS_EXTRA = tramp.S $(srcdir)/config/rs6000/ppc64-fp.c \
+ $(srcdir)/config/rs6000/darwin-ldouble.c
-# ld provides these functions as needed.
-crtsavres.S:
- echo >crtsavres.S
+TARGET_LIBGCC2_CFLAGS = -mno-minimal-toc -fPIC -specs=bispecs
-$(T)crtsavres.o: crtsavres.S
- $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -c crtsavres.S -o $(T)crtsavres.o
+SHLIB_MAPFILES += $(srcdir)/config/rs6000/libgcc-ppc64.ver
-# Modify the shared lib version file
-SHLIB_MKMAP_OPTS = -v dotsyms=1
+MULTILIB_OPTIONS = m64/m32 msoft-float
+MULTILIB_DIRNAMES = 64 32 nof
+MULTILIB_EXTRA_OPTS = fPIC mstrict-align
+MULTILIB_EXCEPTIONS = m64/msoft-float
+MULTILIB_EXCLUSIONS = m64/!m32/msoft-float
+MULTILIB_OSDIRNAMES = ../lib64 ../lib nof
+MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT)
+
+# We want fine grained libraries, so use the new code to build the
+# floating point emulation libraries.
+# fp-bit is only to be used by 32-bit multilibs
+FPBIT = fp-bit32.c
+DPBIT = dp-bit32.c
+
+dp-bit32.c: $(srcdir)/config/fp-bit.c
+ ( echo '#ifndef __powerpc64__'; \
+ cat $(srcdir)/config/fp-bit.c; \
+ echo '#endif' ) > dp-bit32.c
+
+fp-bit32.c: $(srcdir)/config/fp-bit.c
+ ( echo '#ifndef __powerpc64__'; \
+ echo '#define FLOAT'; \
+ cat $(srcdir)/config/fp-bit.c; \
+ echo '#endif' ) > fp-bit32.c
+
+# Hack to use -mlong-double-128 just for compiling 64 bit libgcc
+mklibgcc: bispecs
+
+bispecs: specs
+ if [ x`$(GCC_FOR_TARGET) -print-multi-os-directory` = x../lib ]; then \
+ sed -e '/cc1_options/{ n; s/$$/ %{m64:-mlong-double-128}/; }' < specs > $@; \
+ else \
+ sed -e '/cc1_options/{ n; s/$$/ %{!m32:-mlong-double-128}/; }' < specs > $@; \
+ fi
diff --git a/contrib/gcc/config/rs6000/t-newas b/contrib/gcc/config/rs6000/t-newas
index b8e715a220a5..a26ce39402c8 100644
--- a/contrib/gcc/config/rs6000/t-newas
+++ b/contrib/gcc/config/rs6000/t-newas
@@ -1,15 +1,3 @@
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
- cat $(srcdir)/config/fp-bit.c > dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
# Build the libraries for both hard and soft floating point and all of the
# different processor models
@@ -19,7 +7,7 @@ MULTILIB_OPTIONS = msoft-float \
MULTILIB_DIRNAMES = soft-float \
common power powerpc
-MULTILIB_MATCHES = msoft-float=mcpu?403 \
+MULTILIB_MATCHES = $(MULTILIB_MATCHES_FLOAT) \
mcpu?power=mpower \
mcpu?power=mrios1 \
mcpu?power=mcpu?rios1 \
@@ -39,9 +27,6 @@ MULTILIB_MATCHES = msoft-float=mcpu?403 \
mcpu?powerpc=mpowerpc-gpopt \
mcpu?powerpc=mpowerpc-gfxopt
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
-
# Aix 3.2.x needs milli.exp for -mcpu=common
EXTRA_PARTS = milli.exp
milli.exp: $(srcdir)/config/rs6000/milli.exp
diff --git a/contrib/gcc/config/rs6000/t-ppccomm b/contrib/gcc/config/rs6000/t-ppccomm
index f4fcdce60a97..eaa3252a60b1 100644
--- a/contrib/gcc/config/rs6000/t-ppccomm
+++ b/contrib/gcc/config/rs6000/t-ppccomm
@@ -5,19 +5,6 @@ LIB2FUNCS_EXTRA = tramp.S
# This one can't end up in shared libgcc
LIB2FUNCS_STATIC_EXTRA = eabi.S
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
-
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
- cat $(srcdir)/config/fp-bit.c > dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
eabi.S: $(srcdir)/config/rs6000/eabi.asm
cat $(srcdir)/config/rs6000/eabi.asm > eabi.S
@@ -25,19 +12,9 @@ tramp.S: $(srcdir)/config/rs6000/tramp.asm
cat $(srcdir)/config/rs6000/tramp.asm > tramp.S
# Switch synonyms
-MULTILIB_MATCHES_FLOAT = msoft-float=mcpu?401 \
- msoft-float=mcpu?403 \
- msoft-float=mcpu?405 \
- msoft-float=mcpu?ec603e \
- msoft-float=mcpu?801 \
- msoft-float=mcpu?821 \
- msoft-float=mcpu?823 \
- msoft-float=mcpu?860
MULTILIB_MATCHES_ENDIAN = mlittle=mlittle-endian mbig=mbig-endian
MULTILIB_MATCHES_SYSV = mcall-sysv=mcall-sysv-eabi mcall-sysv=mcall-sysv-noeabi mcall-sysv=mcall-linux mcall-sysv=mcall-netbsd
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
EXTRA_MULTILIB_PARTS = crtbegin$(objext) crtend$(objext) \
crtbeginS$(objext) crtendS$(objext) crtbeginT$(objext) \
ecrti$(objext) ecrtn$(objext) \
diff --git a/contrib/gcc/config/rs6000/t-ppcgas b/contrib/gcc/config/rs6000/t-ppcgas
index 9b82b9f17961..120aef4467c1 100644
--- a/contrib/gcc/config/rs6000/t-ppcgas
+++ b/contrib/gcc/config/rs6000/t-ppcgas
@@ -2,18 +2,13 @@
MULTILIB_OPTIONS = msoft-float \
mlittle/mbig \
- mcall-sysv/mcall-aix \
fleading-underscore
MULTILIB_DIRNAMES = nof \
le be \
- cs ca \
und
MULTILIB_EXTRA_OPTS = mrelocatable-lib mno-eabi mstrict-align
-MULTILIB_EXCEPTIONS = *mcall-aix/*fleading-underscore* \
- *mlittle/*mcall-aix*
MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} \
- ${MULTILIB_MATCHES_ENDIAN} \
- ${MULTILIB_MATCHES_SYSV}
+ ${MULTILIB_MATCHES_ENDIAN}
diff --git a/contrib/gcc/config/rs6000/t-rs6000 b/contrib/gcc/config/rs6000/t-rs6000
index f50ef17027c7..caa07153ad3d 100644
--- a/contrib/gcc/config/rs6000/t-rs6000
+++ b/contrib/gcc/config/rs6000/t-rs6000
@@ -1,19 +1,20 @@
-# We want fine grained libraries, so use the new code to build the
-# floating point emulation libraries.
-FPBIT = fp-bit.c
-DPBIT = dp-bit.c
+# General rules that all rs6000/ targets must have.
-dp-bit.c: $(srcdir)/config/fp-bit.c
- cat $(srcdir)/config/fp-bit.c > dp-bit.c
+gt-rs6000.h: s-gtype ; @true
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+rs6000.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+ $(RTL_H) $(REGS_H) hard-reg-set.h \
+ real.h insn-config.h conditions.h insn-attr.h flags.h $(RECOG_H) \
+ $(OBSTACK_H) $(TREE_H) $(EXPR_H) $(OPTABS_H) except.h function.h \
+ output.h $(BASIC_BLOCK_H) $(INTEGRATE_H) toplev.h $(GGC_H) $(HASHTAB_H) \
+ $(TM_P_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h reload.h gt-rs6000.h \
+ cfglayout.h
-# Build the libraries for both hard and soft floating point
+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
-MULTILIB_OPTIONS = msoft-float
-MULTILIB_DIRNAMES = soft-float
-
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
+# The rs6000 backend doesn't cause warnings in these files.
+insn-conditions.o-warn =
diff --git a/contrib/gcc/config/rs6000/t-spe b/contrib/gcc/config/rs6000/t-spe
new file mode 100644
index 000000000000..bd0b79593186
--- /dev/null
+++ b/contrib/gcc/config/rs6000/t-spe
@@ -0,0 +1,68 @@
+# Multilibs for e500
+
+FPBIT = fp-bit.c
+DPBIT = dp-bit.c
+
+dp-bit.c: $(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
+
+fp-bit.c: $(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+# What we really want are these variants:
+# -mcpu=7400
+# -mcpu=7400 -maltivec -mabi=altivec
+# -mcpu=7400 -msoft-float
+# -msoft-float
+# -mspe=no -mabi=no-spe -misel=no
+# so we'll need to create exceptions later below.
+
+MULTILIB_OPTIONS = mcpu=7400 \
+ maltivec \
+ mabi=altivec \
+ msoft-float \
+ mspe=no \
+ mabi=no-spe \
+ misel=no \
+ mlittle
+
+MULTILIB_DIRNAMES = mpc7400 altivec abi-altivec \
+ nof no-spe no-abi-spe no-isel le
+
+MULTILIB_EXCEPTIONS = maltivec mabi=altivec mspe=no mabi=no-spe misel=no \
+ maltivec/mabi=altivec \
+ mcpu=7400/maltivec \
+ mcpu=7400/mabi=altivec \
+ *mcpu=7400/*mspe=no* \
+ *mcpu=7400/*mabi=no-spe* \
+ *mcpu=7400/*misel=no* \
+ *maltivec/*msoft-float* \
+ *maltivec/*mspe=no* \
+ *maltivec/*mabi=no-spe* \
+ *maltivec/*misel=no* \
+ *mabi=altivec/*msoft-float* \
+ *mabi=altivec/*mspe=no* \
+ *mabi=altivec/*mabi=no-spe* \
+ *mabi=altivec/*misel=no* \
+ *msoft-float/*mspe=no* \
+ *msoft-float/*mabi=no-spe* \
+ *msoft-float/*misel=no* \
+ mspe=no/mabi=no-spe \
+ mspe=no/misel=no \
+ mabi=no-spe/misel=no \
+ misel=no/mlittle \
+ mabi=no-spe/misel=no/mlittle \
+ mspe=no/mlittle \
+ mabi=spe/mlittle \
+ mcpu=7400/mabi=altivec/mlittle \
+ mcpu=7400/maltivec/mlittle \
+ mabi=no-spe/mlittle \
+ mspe=no/misel=no/mlittle \
+ mspe=no/mabi=no-spe/mlittle \
+ mabi=altivec/mlittle \
+ maltivec/mlittle \
+ maltivec/mabi=altivec/mlittle
diff --git a/contrib/gcc/config/rs6000/t-vxworks b/contrib/gcc/config/rs6000/t-vxworks
new file mode 100644
index 000000000000..e89e47b8d092
--- /dev/null
+++ b/contrib/gcc/config/rs6000/t-vxworks
@@ -0,0 +1,10 @@
+# Multilibs for VxWorks.
+
+MULTILIB_OPTIONS = t403/t405/t440/t603/t604/t860
+MULTILIB_DIRNAMES = PPC403gnu PPC405gnu PPC440gnu \
+ PPC603gnu PPC604gnu PPC860gnu
+
+MULTILIB_MATCHES = t604=
+
+# Put vxlib.c back in LIB2FUNCS_EXTRA (t-ppccomm clobbers it).
+LIB2FUNCS_EXTRA += $(srcdir)/config/vxlib.c
diff --git a/contrib/gcc/config/rs6000/tramp.asm b/contrib/gcc/config/rs6000/tramp.asm
index c2a38d10f5cf..284f93860742 100644
--- a/contrib/gcc/config/rs6000/tramp.asm
+++ b/contrib/gcc/config/rs6000/tramp.asm
@@ -39,6 +39,7 @@
.section ".text"
#include "ppc-asm.h"
+#ifndef __powerpc64__
.type trampoline_initial,@object
.align 2
trampoline_initial:
@@ -107,3 +108,4 @@ FUNC_START(__trampoline_setup)
bl JUMP_TARGET(abort)
FUNC_END(__trampoline_setup)
+#endif
diff --git a/contrib/gcc/config/rs6000/vxworks.h b/contrib/gcc/config/rs6000/vxworks.h
new file mode 100644
index 000000000000..e7a70922e7ac
--- /dev/null
+++ b/contrib/gcc/config/rs6000/vxworks.h
@@ -0,0 +1,82 @@
+/* Definitions of target machine for GNU compiler. Vxworks PowerPC version.
+ Copyright (C) 1996, 2000, 2002, 2003 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 2, 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
+
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__vxworks"); \
+ builtin_define ("__vxworks__"); \
+ } \
+ while (0)
+
+/* We have to kill off the entire specs set created by rs6000/sysv4.h
+ and substitute our own set. The top level vxworks.h has done some
+ of this for us. */
+
+#undef SUBTARGET_EXTRA_SPECS
+#undef CPP_SPEC
+#undef CC1_SPEC
+#undef ASM_SPEC
+
+#define SUBTARGET_EXTRA_SPECS /* none needed */
+
+#define CPP_SPEC \
+"-DCPU_FAMILY=PPC -D__ppc -D__EABI__ \
+ %{t403: -DCPU=PPC403 -D_SOFT_FLOAT ; \
+ t405: -DCPU=PPC405 -D_SOFT_FLOAT ; \
+ t440: -DCPU=PPC440 -D_SOFT_FLOAT ; \
+ t603: -DCPU=PPC603 ; \
+ t604: -DCPU=PPC604 ; \
+ t860: -DCPU=PPC860 -D_SOFT_FLOAT ; \
+ : -DCPU=PPC604} \
+ %{!msoft-float:-D__hardfp} \
+ %{fpic|fpie: -D__PIC__=1 -D__pic__=1 ; \
+ fPIC|fPIE: -D__PIC__=2 -D__pic__=2 } \
+ %(cpp_cpu)"
+
+#define CC1_SPEC \
+"%{t403: -mcpu=403 -mstrict-align ; \
+ t405: -mcpu=405 -mstrict-align ; \
+ t440: -mcpu=440 -mstrict-align ; \
+ t603: -mcpu=603 -mstrict-align ; \
+ t604: -mcpu=604 -mstrict-align ; \
+ t860: -mcpu=860 ; \
+ : -mcpu=604 -mstrict-align } \
+ %{G*} %{mno-sdata:-msdata=none} %{msdata:-msdata=default} \
+ %{mlittle|mlittle-endian:-mstrict-align} \
+ %{profile: -p} \
+ %{fvec:-maltivec} %{fvec-eabi:-maltivec -mabi=altivec}"
+
+#define ASM_SPEC "%(asm_cpu) \
+%{.s: %{mregnames} %{mno-regnames}} %{.S: %{mregnames} %{mno-regnames}} \
+%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
+%{mrelocatable} %{mrelocatable-lib} %{fpic:-K PIC} %{fPIC:-K PIC} -mbig"
+
+#undef MULTILIB_DEFAULTS
+#define MULTILIB_DEFAULTS { "t604" }
+
+/* We can't use .ctors/.dtors sections. */
+#undef TARGET_ASM_OUTPUT_CONSTRUCTOR
+#undef TARGET_ASM_OUTPUT_DESTRUCTOR
+
+/* Nor sdata. */
+#undef SDATA_DEFAULT_SIZE
+#define SDATA_DEFAULT_SIZE 0
diff --git a/contrib/gcc/config/rs6000/windiss.h b/contrib/gcc/config/rs6000/windiss.h
index 7aacb233c1d1..e66d128696dd 100644
--- a/contrib/gcc/config/rs6000/windiss.h
+++ b/contrib/gcc/config/rs6000/windiss.h
@@ -1,34 +1,34 @@
/* Support for GCC on PowerPC using WindISS simulator.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by CodeSourcery, LLC.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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.
+ 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
-#undef TARGET_VERSION
+#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC WindISS)");
-#undef LIB_DEFAULT_SPEC
+#undef LIB_DEFAULT_SPEC
#define LIB_DEFAULT_SPEC "%(lib_windiss)"
-#undef STARTFILE_DEFAULT_SPEC
+#undef STARTFILE_DEFAULT_SPEC
#define STARTFILE_DEFAULT_SPEC "%(startfile_windiss)"
-#undef ENDFILE_DEFAULT_SPEC
+#undef ENDFILE_DEFAULT_SPEC
#define ENDFILE_DEFAULT_SPEC "%(endfile_windiss)"
#undef LINK_START_DEFAULT_SPEC
@@ -37,11 +37,11 @@ Boston, MA 02111-1307, USA. */
#undef LINK_OS_DEFAULT_SPEC
#define LINK_OS_DEFAULT_SPEC "%(link_os_windiss)"
-#undef CRTSAVRES_DEFAULT_SPEC
+#undef CRTSAVRES_DEFAULT_SPEC
#define CRTSAVRES_DEFAULT_SPEC ""
-#undef WCHAR_TYPE
+#undef WCHAR_TYPE
#define WCHAR_TYPE "short unsigned int"
-#undef WCHAR_TYPE_SIZE
+#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 16
diff --git a/contrib/gcc/config/rs6000/x-darwin b/contrib/gcc/config/rs6000/x-darwin
new file mode 100644
index 000000000000..f7242a7ee5b3
--- /dev/null
+++ b/contrib/gcc/config/rs6000/x-darwin
@@ -0,0 +1,4 @@
+host-darwin.o : $(srcdir)/config/rs6000/host-darwin.c $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h hosthooks.h hosthooks-def.h toplev.h diagnostic.h
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/rs6000/host-darwin.c
diff --git a/contrib/gcc/config/rs6000/x-linux64 b/contrib/gcc/config/rs6000/x-linux64
new file mode 100644
index 000000000000..4371ca30431a
--- /dev/null
+++ b/contrib/gcc/config/rs6000/x-linux64
@@ -0,0 +1,2 @@
+# parts of gcc need more than a 64k TOC.
+X_CFLAGS = -mminimal-toc
diff --git a/contrib/gcc/config/rs6000/xcoff.h b/contrib/gcc/config/rs6000/xcoff.h
index 21d74a9e616d..d4e056b4b746 100644
--- a/contrib/gcc/config/rs6000/xcoff.h
+++ b/contrib/gcc/config/rs6000/xcoff.h
@@ -1,24 +1,23 @@
/* Definitions of target machine for GNU compiler,
for some generic XCOFF file format
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC 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.
+ 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 2, or (at your
+ option) any later version.
-GNU CC 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+ 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 COPYING. If not, write to the
+ Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA. */
#define TARGET_OBJECT_FORMAT OBJECT_XCOFF
@@ -70,9 +69,14 @@ Boston, MA 02111-1307, USA. */
BIGGEST_ALIGNMENT is 64, so align the sections that much. */
#define EXTRA_SECTION_FUNCTIONS \
- \
+ READ_ONLY_DATA_SECTION_FUNCTION \
+ PRIVATE_DATA_SECTION_FUNCTION \
+ READ_ONLY_PRIVATE_DATA_SECTION_FUNCTION \
+ TOC_SECTION_FUNCTION
+
+#define READ_ONLY_DATA_SECTION_FUNCTION \
void \
-read_only_data_section () \
+read_only_data_section (void) \
{ \
if (in_section != read_only_data) \
{ \
@@ -80,10 +84,11 @@ read_only_data_section () \
xcoff_read_only_section_name); \
in_section = read_only_data; \
} \
-} \
- \
+}
+
+#define PRIVATE_DATA_SECTION_FUNCTION \
void \
-private_data_section () \
+private_data_section (void) \
{ \
if (in_section != private_data) \
{ \
@@ -91,10 +96,11 @@ private_data_section () \
xcoff_private_data_section_name); \
in_section = private_data; \
} \
-} \
- \
+}
+
+#define READ_ONLY_PRIVATE_DATA_SECTION_FUNCTION \
void \
-read_only_private_data_section () \
+read_only_private_data_section (void) \
{ \
if (in_section != read_only_private_data) \
{ \
@@ -102,16 +108,18 @@ read_only_private_data_section () \
xcoff_private_data_section_name); \
in_section = read_only_private_data; \
} \
-} \
- \
+}
+
+#define TOC_SECTION_FUNCTION \
void \
-toc_section () \
+toc_section (void) \
{ \
if (TARGET_MINIMAL_TOC) \
{ \
- /* toc_section is always called at least once from ASM_FILE_START, \
- so this is guaranteed to always be defined once and only once \
- in each file. */ \
+ /* toc_section is always called at least once \
+ from rs6000_xcoff_file_start, so this is \
+ guaranteed to always be defined once and \
+ only once in each file. */ \
if (! toc_initialized) \
{ \
fputs ("\t.toc\nLCTOC..1:\n", asm_out_file); \
@@ -164,7 +172,6 @@ toc_section () \
#define TARGET_ASM_SELECT_SECTION rs6000_xcoff_select_section
#define TARGET_ASM_SELECT_RTX_SECTION rs6000_xcoff_select_rtx_section
#define TARGET_ASM_UNIQUE_SECTION rs6000_xcoff_unique_section
-#define TARGET_ENCODE_SECTION_INFO rs6000_xcoff_encode_section_info
#define TARGET_STRIP_NAME_ENCODING rs6000_xcoff_strip_name_encoding
#define TARGET_SECTION_TYPE_FLAGS rs6000_xcoff_section_type_flags
@@ -175,16 +182,9 @@ toc_section () \
#define RESTORE_FP_SUFFIX ""
/* Function name to call to do profiling. */
-#undef RS6000_MCOUNT
+#undef RS6000_MCOUNT
#define RS6000_MCOUNT ".__mcount"
-/* Function names to call to do floating point truncation. */
-
-#undef RS6000_ITRUNC
-#define RS6000_ITRUNC "__itrunc"
-#undef RS6000_UITRUNC
-#define RS6000_UITRUNC "__uitrunc"
-
/* This outputs NAME to FILE up to the first null or '['. */
#define RS6000_OUTPUT_BASENAME(FILE, NAME) \
@@ -202,53 +202,11 @@ toc_section () \
/* Globalizing directive for a label. */
#define GLOBAL_ASM_OP "\t.globl "
-/* Output at beginning of assembler file.
-
- Initialize the section names for the RS/6000 at this point.
-
- Specify filename, including full path, to assembler.
-
- We want to go into the TOC section so at least one .toc will be emitted.
- Also, in order to output proper .bs/.es pairs, we need at least one static
- [RW] section emitted.
-
- Finally, declare mcount when profiling to make the assembler happy. */
-
-#define ASM_FILE_START(FILE) \
-{ \
- rs6000_gen_section_name (&xcoff_bss_section_name, \
- main_input_filename, ".bss_"); \
- rs6000_gen_section_name (&xcoff_private_data_section_name, \
- main_input_filename, ".rw_"); \
- rs6000_gen_section_name (&xcoff_read_only_section_name, \
- main_input_filename, ".ro_"); \
- \
- fputs ("\t.file\t", FILE); \
- output_quoted_string (FILE, main_input_filename); \
- fputc ('\n', FILE); \
- if (TARGET_64BIT) \
- fputs ("\t.machine\t\"ppc64\"\n", FILE); \
- toc_section (); \
- if (write_symbols != NO_DEBUG) \
- private_data_section (); \
- text_section (); \
- if (profile_flag) \
- fprintf (FILE, "\t.extern %s\n", RS6000_MCOUNT); \
- rs6000_file_start (FILE, TARGET_CPU_DEFAULT); \
-}
-
-/* Output at end of assembler file.
-
- On the RS/6000, referencing data should automatically pull in text. */
-
-#define ASM_FILE_END(FILE) \
-{ \
- text_section (); \
- fputs ("_section_.text:\n", FILE); \
- data_section (); \
- fputs (TARGET_32BIT \
- ? "\t.long _section_.text\n" : "\t.llong _section_.text\n", FILE); \
-}
+#undef TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START rs6000_xcoff_file_start
+#define TARGET_ASM_FILE_END rs6000_xcoff_file_end
+#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE false
/* This macro produces the initial definition of a function name.
On the RS/6000, we need to place an extra '.' in the function name and
@@ -258,17 +216,11 @@ toc_section () \
`text_section' call previously done. We do have to go back to that
csect, however.
- We also record that the function exists in the current compilation
- unit, reachable by short branch, by setting SYMBOL_REF_FLAG.
-
The third and fourth parameters to the .function pseudo-op (16 and 044)
are placeholders which no longer have any use. */
#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
-{ rtx sym_ref = XEXP (DECL_RTL (DECL), 0); \
- if ((*targetm.binds_local_p) (DECL)) \
- SYMBOL_REF_FLAG (sym_ref) = 1; \
- if (TREE_PUBLIC (DECL)) \
+{ if (TREE_PUBLIC (DECL)) \
{ \
if (!RS6000_WEAK || !DECL_WEAK (decl)) \
{ \
@@ -296,11 +248,7 @@ toc_section () \
putc ('.', FILE); \
RS6000_OUTPUT_BASENAME (FILE, NAME); \
fputs (":\n", FILE); \
- if (write_symbols == XCOFF_DEBUG \
- /* When called before targetm.asm_out.output_mi_thunk, \
- we won't be emitting the rest of the debug info that \
- goes along with this, leading to assembler errors. */ \
- && !(current_function_is_thunk && !no_new_pseudos)) \
+ if (write_symbols != NO_DEBUG) \
xcoffout_declare_function (FILE, DECL, NAME); \
}
@@ -311,7 +259,7 @@ toc_section () \
/* This says how to output an external. */
-#undef ASM_OUTPUT_EXTERNAL
+#undef ASM_OUTPUT_EXTERNAL
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
{ rtx _symref = XEXP (DECL_RTL (DECL), 0); \
if ((TREE_CODE (DECL) == VAR_DECL \
@@ -325,12 +273,6 @@ toc_section () \
} \
}
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, "%s..%u:\n", (PREFIX), (unsigned) (NUM))
-
/* This is how to output an internal label prefix. rs6000.c uses this
when generating traceback tables. */
@@ -338,11 +280,11 @@ toc_section () \
fprintf (FILE, "%s..", PREFIX)
/* This is how to output a label for a jump table. Arguments are the same as
- for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
+ for (*targetm.asm_out.internal_label), except the insn for the jump table is
passed. */
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
-{ ASM_OUTPUT_ALIGN (FILE, 2); ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); }
+{ ASM_OUTPUT_ALIGN (FILE, 2); (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); }
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
@@ -362,7 +304,7 @@ toc_section () \
#define SKIP_ASM_OP "\t.space "
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "%s%u\n", SKIP_ASM_OP, (SIZE))
+ fprintf (FILE, "%s"HOST_WIDE_INT_PRINT_UNSIGNED"\n", SKIP_ASM_OP, (SIZE))
/* This says how to output an assembler line
to define a global common symbol. */
@@ -373,12 +315,12 @@ toc_section () \
do { fputs (COMMON_ASM_OP, (FILE)); \
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
if ((ALIGN) > 32) \
- fprintf ((FILE), ",%u,%u\n", (SIZE), \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", (SIZE), \
exact_log2 ((ALIGN) / BITS_PER_UNIT)); \
else if ((SIZE) > 4) \
- fprintf ((FILE), ",%u,3\n", (SIZE)); \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",3\n", (SIZE)); \
else \
- fprintf ((FILE), ",%u\n", (SIZE)); \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)); \
} while (0)
/* This says how to output an assembler line
@@ -392,7 +334,8 @@ toc_section () \
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
do { fputs (LOCAL_COMMON_ASM_OP, (FILE)); \
RS6000_OUTPUT_BASENAME ((FILE), (NAME)); \
- fprintf ((FILE), ",%u,%s\n", (TARGET_32BIT ? (SIZE) : (ROUNDED)), \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%s\n", \
+ (TARGET_32BIT ? (SIZE) : (ROUNDED)), \
xcoff_bss_section_name); \
} while (0)
diff --git a/contrib/gcc/config/rtems.h b/contrib/gcc/config/rtems.h
index a3f9ba301b4d..80636436124b 100644
--- a/contrib/gcc/config/rtems.h
+++ b/contrib/gcc/config/rtems.h
@@ -1,20 +1,20 @@
/* Configuration common to all targets running RTEMS.
- Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -35,3 +35,17 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC ""
+
+/*
+ * Some targets do not set up LIB_SPECS, override it, here.
+ */
+#define STD_LIB_SPEC \
+ "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{!qrtems: " STD_LIB_SPEC "} " \
+"%{!nostdlib: %{qrtems: --start-group \
+ %{!qrtems_debug: -lrtemsbsp -lrtemscpu} \
+ %{qrtems_debug: -lrtemsbsp_g -lrtemscpu_g} \
+ -lc -lgcc --end-group %{!qnolinkcmds: -T linkcmds%s}}}"
+
diff --git a/contrib/gcc/config/s390/2064.md b/contrib/gcc/config/s390/2064.md
new file mode 100644
index 000000000000..143cd1b9ca2a
--- /dev/null
+++ b/contrib/gcc/config/s390/2064.md
@@ -0,0 +1,131 @@
+;; Scheduling description for z900 (cpu 2064).
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
+;; Ulrich Weigand (uweigand@de.ibm.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 2, 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 COPYING. If not, write to the Free
+;; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
+
+;;
+;; References:
+;; 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
+;; |
+;; wr
+
+(define_automaton "z_ipu")
+(define_cpu_unit "z_e1" "z_ipu")
+(define_cpu_unit "z_wr" "z_ipu")
+
+
+(define_insn_reservation "z_la" 1
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "la"))
+ "z_e1,z_wr")
+
+(define_insn_reservation "z_larl" 1
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "larl"))
+ "z_e1,z_wr")
+
+(define_insn_reservation "z_load" 1
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "load"))
+ "z_e1,z_wr")
+
+(define_insn_reservation "z_store" 1
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "store"))
+ "z_e1,z_wr")
+
+(define_insn_reservation "z_call" 5
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "jsr"))
+ "z_e1*5,z_wr")
+
+(define_insn_reservation "z_o2" 2
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "o2"))
+ "z_e1*2,z_wr")
+
+(define_insn_reservation "z_o3" 3
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "type" "o3"))
+ "z_e1*3,z_wr")
+
+;
+; Insn still not mentioned are check for
+; the usage of the agen unit
+;
+
+(define_insn_reservation "z_int" 1
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "atype" "reg"))
+ "z_e1,z_wr")
+
+(define_insn_reservation "z_agen" 1
+ (and (eq_attr "cpu" "z900")
+ (eq_attr "atype" "agen"))
+ "z_e1,z_wr")
+
+
+;;
+;; 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"
+ "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.
+;;
+
+(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.
+;;
+
+(define_bypass 2 "z_larl,z_la"
+ "z_agen,z_la,z_call,z_load,z_store" "s390_agen_dep_p")
+
+
+
+
+
diff --git a/contrib/gcc/config/s390/2084.md b/contrib/gcc/config/s390/2084.md
new file mode 100644
index 000000000000..a74ffbfdd468
--- /dev/null
+++ b/contrib/gcc/config/s390/2084.md
@@ -0,0 +1,262 @@
+;; Scheduling description for z990 (cpu 2084).
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
+;; Ulrich Weigand (uweigand@de.ibm.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 2, 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 COPYING. If not, write to the Free
+;; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
+
+(define_automaton "x_ipu")
+
+(define_cpu_unit "x_e1_r,x_e1_s,x_e1_t" "x_ipu")
+(define_cpu_unit "x_wr_r,x_wr_s,x_wr_t,x_wr_fp" "x_ipu")
+(define_cpu_unit "x_s1,x_s2,x_s3,x_s4" "x_ipu")
+(define_cpu_unit "x_t1,x_t2,x_t3,x_t4" "x_ipu")
+(define_cpu_unit "x_f1,x_f2,x_f3,x_f4,x_f5,x_f6" "x_ipu")
+(define_cpu_unit "x_store_tok" "x_ipu")
+(define_cpu_unit "x_ms,x_mt" "x_ipu")
+
+(define_reservation "x-e1-st" "(x_e1_s | x_e1_t)")
+
+(define_reservation "x-e1-np" "(x_e1_r + x_e1_s + x_e1_t)")
+
+(absence_set "x_e1_r" "x_e1_s,x_e1_t")
+(absence_set "x_e1_s" "x_e1_t")
+
+;; Try to avoid int <-> fp transitions.
+
+(define_reservation "x-x" "x_s1|x_t1,x_s2|x_t2,x_s3|x_t3,x_s4|x_t4")
+(define_reservation "x-f" "x_f1,x_f2,x_f3,x_f4,x_f5,x_f6")
+(define_reservation "x-wr-st" "((x_wr_s | x_wr_t),x-x)")
+(define_reservation "x-wr-np" "((x_wr_r + x_wr_s + x_wr_t),x-x)")
+(define_reservation "x-wr-fp" "x_wr_fp,x-f")
+(define_reservation "x-mem" "x_ms|x_mt")
+
+(absence_set "x_wr_fp"
+ "x_s1,x_s2,x_s3,x_s4,x_t1,x_t2,x_t3,x_t4,x_wr_s,x_wr_t")
+
+(absence_set "x_e1_r,x_wr_r,x_wr_s,x_wr_t"
+ "x_f1,x_f2,x_f3,x_f4,x_f5,x_f6,x_wr_fp")
+
+;; Don't have any load type insn in same group as store
+
+(absence_set "x_ms,x_mt" "x_store_tok")
+
+
+;;
+;; Simple insns
+;;
+
+(define_insn_reservation "x_lr" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "lr"))
+ "x-e1-st,x-wr-st")
+
+(define_insn_reservation "x_la" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "la"))
+ "x-e1-st,x-wr-st")
+
+(define_insn_reservation "x_larl" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "larl"))
+ "x-e1-st,x-wr-st")
+
+(define_insn_reservation "x_load" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "load"))
+ "x-e1-st+x-mem,x-wr-st")
+
+(define_insn_reservation "x_store" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "store"))
+ "x-e1-st+x_store_tok,x-wr-st")
+
+(define_insn_reservation "x_branch" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "branch"))
+ "x_e1_r,x_wr_r")
+
+(define_insn_reservation "x_call" 5
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "jsr"))
+ "x-e1-np*5,x-wr-np")
+
+;;
+;; Multicycle insns
+;;
+
+(define_insn_reservation "x_ss" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "op_type" "SS"))
+ "x-e1-np,x-wr-np")
+
+(define_insn_reservation "x_stm" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "stm"))
+ "(x-e1-np+x_store_tok)*10,x-wr-np")
+
+(define_insn_reservation "x_lm" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "lm"))
+ "x-e1-np*10,x-wr-np")
+
+(define_insn_reservation "x_nn" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "op_type" "NN"))
+ "x-e1-np,x-wr-np")
+
+(define_insn_reservation "x_o2" 2
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "o2"))
+ "x-e1-np*2,x-wr-np")
+
+(define_insn_reservation "x_o3" 3
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "o3"))
+ "x-e1-np*3,x-wr-np")
+
+;;
+;; Floating point insns
+;;
+
+(define_insn_reservation "x_fsimpd" 6
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "fsimpd,fmuld"))
+ "x_e1_t,x-wr-fp")
+
+(define_insn_reservation "x_fsimps" 6
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "fsimps,fmuls"))
+ "x_e1_t,x-wr-fp")
+
+(define_insn_reservation "x_fdivd" 36
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "fdivd"))
+ "x_e1_t*30,x-wr-fp")
+
+(define_insn_reservation "x_fdivs" 36
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "fdivs"))
+ "x_e1_t*30,x-wr-fp")
+
+(define_insn_reservation "x_floadd" 6
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "floadd"))
+ "x_e1_t,x-wr-fp")
+
+(define_insn_reservation "x_floads" 6
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "floads"))
+ "x_e1_t,x-wr-fp")
+
+(define_insn_reservation "x_fstored" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "fstored"))
+ "x_e1_t,x-wr-fp")
+
+(define_insn_reservation "x_fstores" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "fstores"))
+ "x_e1_t,x-wr-fp")
+
+(define_insn_reservation "x_ftoi" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "ftoi"))
+ "x_e1_t*3,x-wr-fp")
+
+(define_insn_reservation "x_itof" 7
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "type" "itof"))
+ "x_e1_t*3,x-wr-fp")
+
+(define_bypass 1 "x_fsimpd" "x_fstored")
+
+(define_bypass 1 "x_fsimps" "x_fstores")
+
+(define_bypass 1 "x_floadd" "x_fsimpd,x_fstored,x_floadd")
+
+(define_bypass 1 "x_floads" "x_fsimps,x_fstores,x_floads")
+
+;;
+;; Insns still not mentioned are checked for
+;; the usage of the agen unit
+;;
+
+(define_insn_reservation "x_int" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "atype" "reg"))
+ "x-e1-st,x-wr-st")
+
+(define_insn_reservation "x_agen" 1
+ (and (eq_attr "cpu" "z990")
+ (eq_attr "atype" "agen"))
+ "x-e1-st+x-mem,x-wr-st")
+
+;;
+;; 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"
+ "x_agen,x_la,x_call,x_load,x_store,x_ss,x_stm,x_lm"
+ "s390_agen_dep_p")
+
+(define_bypass 9 "x_int,x_agen,x_lr"
+ "x_floadd, x_floads, x_fstored, x_fstores,\
+ x_fsimpd, x_fsimps, x_fdivd, x_fdivs"
+ "s390_agen_dep_p")
+;;
+;; A load type instruction uses a bypass to feed the result back
+;; to the address generation pipeline stage.
+;;
+
+(define_bypass 4 "x_load"
+ "x_agen,x_la,x_call,x_load,x_store,x_ss,x_stm,x_lm"
+ "s390_agen_dep_p")
+
+(define_bypass 5 "x_load"
+ "x_floadd, x_floads, x_fstored, x_fstores,\
+ x_fsimpd, x_fsimps, x_fdivd, x_fdivs"
+ "s390_agen_dep_p")
+
+;;
+;; 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"
+ "x_agen,x_la,x_call,x_load,x_store,x_ss,x_stm,x_lm"
+ "s390_agen_dep_p")
+
+(define_bypass 5 "x_larl, x_la"
+ "x_floadd, x_floads, x_fstored, x_fstores,\
+ x_fsimpd, x_fsimps, x_fdivd, x_fdivs"
+ "s390_agen_dep_p")
+
+;;
+;; Operand forwarding
+;;
+
+(define_bypass 0 "x_lr,x_la,x_load" "x_int,x_lr")
+
+
diff --git a/contrib/gcc/config/s390/fixdfdi.h b/contrib/gcc/config/s390/fixdfdi.h
index 1f82a9c7a2cd..a5b9212e7930 100644
--- a/contrib/gcc/config/s390/fixdfdi.h
+++ b/contrib/gcc/config/s390/fixdfdi.h
@@ -3,22 +3,22 @@
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC 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.
+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 2, or (at your option) any later
+version.
-GNU CC 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.
+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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#ifdef L_fixunsdfdi
#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
diff --git a/contrib/gcc/config/s390/linux.h b/contrib/gcc/config/s390/linux.h
index cbb771099dc3..9a6db9d76c1d 100644
--- a/contrib/gcc/config/s390/linux.h
+++ b/contrib/gcc/config/s390/linux.h
@@ -3,22 +3,22 @@
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC 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.
+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 2, or (at your option) any later
+version.
-GNU CC 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.
+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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#ifndef _LINUX_H
#define _LINUX_H
@@ -53,12 +53,7 @@ Boston, MA 02111-1307, USA. */
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- builtin_define_std ("linux"); \
- builtin_define_std ("unix"); \
- builtin_assert ("system=linux"); \
- builtin_assert ("system=unix"); \
- builtin_define ("__ELF__"); \
- builtin_define ("__gnu_linux__"); \
+ LINUX_TARGET_OS_CPP_BUILTINS(); \
if (flag_pic) \
{ \
builtin_define ("__PIC__"); \
@@ -70,13 +65,8 @@ Boston, MA 02111-1307, USA. */
/* Target specific assembler settings. */
-#ifdef DEFAULT_TARGET_64BIT
-#undef ASM_SPEC
-#define ASM_SPEC "%{m31:-m31 -Aesa}"
-#else
#undef ASM_SPEC
-#define ASM_SPEC "%{m64:-m64 -Aesame}"
-#endif
+#define ASM_SPEC "%{m31&m64}%{mesa&mzarch}%{march=*}"
/* Target specific linker settings. */
@@ -87,41 +77,20 @@ Boston, MA 02111-1307, USA. */
#define MULTILIB_DEFAULTS { "m31" }
#endif
-#define LINK_ARCH31_SPEC \
- "-m elf_s390 \
- %{shared:-shared} \
- %{!shared: \
- %{static:-static} \
- %{!static: \
- %{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /lib/ld.so.1}}}"
-
-#define LINK_ARCH64_SPEC \
- "-m elf64_s390 \
+#undef LINK_SPEC
+#define LINK_SPEC \
+ "%{m31:-m elf_s390}%{m64:-m elf64_s390} \
%{shared:-shared} \
%{!shared: \
%{static:-static} \
%{!static: \
%{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /lib/ld64.so.1}}}"
-
-#ifdef DEFAULT_TARGET_64BIT
-#undef LINK_SPEC
-#define LINK_SPEC "%{m31:%(link_arch31)} %{!m31:%(link_arch64)}"
-#else
-#undef LINK_SPEC
-#define LINK_SPEC "%{m64:%(link_arch64)} %{!m64:%(link_arch31)}"
-#endif
-
-
-/* This macro defines names of additional specifications to put in the specs
- that can be used in various specifications like CC1_SPEC. Its definition
- is an initializer with a subgrouping for each command option. */
+ %{!dynamic-linker: \
+ %{m31:-dynamic-linker /lib/ld.so.1} \
+ %{m64:-dynamic-linker /lib/ld64.so.1}}}}"
-#define EXTRA_SPECS \
- { "link_arch31", LINK_ARCH31_SPEC }, \
- { "link_arch64", LINK_ARCH64_SPEC }, \
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
diff --git a/contrib/gcc/config/s390/s390-modes.def b/contrib/gcc/config/s390/s390-modes.def
index 9f9d5265720e..08759558871a 100644
--- a/contrib/gcc/config/s390/s390-modes.def
+++ b/contrib/gcc/config/s390/s390-modes.def
@@ -1,38 +1,42 @@
/* Definitions of target machine for GNU compiler, for IBM S/390
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
-This file is part of GNU CC.
-GNU CC 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 file is part of GCC.
-GNU CC 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.
+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 2, 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* 256-bit integer mode is needed for STACK_SAVEAREA_MODE. */
+INT_MODE (OI, 32);
/* Add any extra modes needed to represent the condition code. */
-CC (CCZ)
-CC (CCA)
-CC (CCAP)
-CC (CCAN)
-CC (CCL)
-CC (CCL1)
-CC (CCL2)
-CC (CCU)
-CC (CCUR)
-CC (CCS)
-CC (CCSR)
-CC (CCT)
-CC (CCT1)
-CC (CCT2)
-CC (CCT3)
+CC_MODE (CCZ);
+CC_MODE (CCA);
+CC_MODE (CCAP);
+CC_MODE (CCAN);
+CC_MODE (CCL);
+CC_MODE (CCL1);
+CC_MODE (CCL2);
+CC_MODE (CCU);
+CC_MODE (CCUR);
+CC_MODE (CCS);
+CC_MODE (CCSR);
+CC_MODE (CCT);
+CC_MODE (CCT1);
+CC_MODE (CCT2);
+CC_MODE (CCT3);
diff --git a/contrib/gcc/config/s390/s390-protos.h b/contrib/gcc/config/s390/s390-protos.h
index 1f8b14456c94..90815a879384 100644
--- a/contrib/gcc/config/s390/s390-protos.h
+++ b/contrib/gcc/config/s390/s390-protos.h
@@ -1,96 +1,105 @@
/* Definitions of target machine for GNU compiler, for IBM S/390.
- Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC 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.
+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 2, or (at your option) any later
+version.
-GNU CC 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.
+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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
/* Declare functions in s390.c. */
-extern void optimization_options PARAMS ((int, int));
-extern void override_options PARAMS ((void));
-extern int s390_arg_frame_offset PARAMS ((void));
-extern void s390_emit_prologue PARAMS ((void));
-extern void s390_emit_epilogue PARAMS ((void));
-extern void s390_function_profiler PARAMS ((FILE *, int));
+extern void optimization_options (int, int);
+extern void override_options (void);
+extern HOST_WIDE_INT s390_arg_frame_offset (void);
+extern void s390_load_got (int);
+extern void s390_emit_prologue (void);
+extern void s390_emit_epilogue (void);
+extern void s390_function_profiler (FILE *, int);
#ifdef RTX_CODE
-extern int s390_address_cost PARAMS ((rtx));
-extern int q_constraint PARAMS ((rtx));
-extern int const0_operand PARAMS ((rtx, enum machine_mode));
-extern int consttable_operand PARAMS ((rtx, enum machine_mode));
-extern int larl_operand PARAMS ((rtx, enum machine_mode));
-extern int s_operand PARAMS ((rtx, enum machine_mode));
-extern int s_imm_operand PARAMS ((rtx, enum machine_mode));
-extern int bras_sym_operand PARAMS ((rtx, enum machine_mode));
-extern int load_multiple_operation PARAMS ((rtx, enum machine_mode));
-extern int store_multiple_operation PARAMS ((rtx, enum machine_mode));
-extern int s390_single_hi PARAMS ((rtx, enum machine_mode, int));
-extern int s390_extract_hi PARAMS ((rtx, enum machine_mode, int));
-extern int s390_single_qi PARAMS ((rtx, enum machine_mode, int));
-extern int s390_extract_qi PARAMS ((rtx, enum machine_mode, int));
-extern bool s390_split_ok_p PARAMS ((rtx, rtx, enum machine_mode, int));
-extern int tls_symbolic_operand PARAMS ((rtx));
+extern int s390_extra_constraint_str (rtx, int, const char *);
+extern int s390_const_ok_for_constraint_p (HOST_WIDE_INT, int, const char *);
+extern int const0_operand (rtx, enum machine_mode);
+extern int consttable_operand (rtx, enum machine_mode);
+extern int larl_operand (rtx, enum machine_mode);
+extern int s_operand (rtx, enum machine_mode);
+extern int s_imm_operand (rtx, enum machine_mode);
+extern int shift_count_operand (rtx, enum machine_mode);
+extern int bras_sym_operand (rtx, enum machine_mode);
+extern int load_multiple_operation (rtx, enum machine_mode);
+extern int store_multiple_operation (rtx, enum machine_mode);
+extern int s390_single_part (rtx, enum machine_mode, enum machine_mode, int);
+extern unsigned HOST_WIDE_INT s390_extract_part (rtx, enum machine_mode, int);
+extern bool s390_split_ok_p (rtx, rtx, enum machine_mode, int);
+extern int tls_symbolic_operand (rtx);
-extern int s390_match_ccmode PARAMS ((rtx, enum machine_mode));
-extern enum machine_mode s390_tm_ccmode PARAMS ((rtx, rtx, int));
-extern enum machine_mode s390_select_ccmode PARAMS ((enum rtx_code, rtx, rtx));
-extern int symbolic_reference_mentioned_p PARAMS ((rtx));
-extern int tls_symbolic_reference_mentioned_p PARAMS ((rtx));
-extern rtx s390_tls_get_offset PARAMS ((void));
-extern int legitimate_la_operand_p PARAMS ((rtx));
-extern int preferred_la_operand_p PARAMS ((rtx));
-extern int legitimate_pic_operand_p PARAMS ((rtx));
-extern int legitimate_constant_p PARAMS ((rtx));
-extern int legitimate_reload_constant_p PARAMS ((rtx));
-extern int legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
-extern rtx legitimize_pic_address PARAMS ((rtx, rtx));
-extern rtx legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
-extern enum reg_class s390_preferred_reload_class PARAMS ((rtx, enum reg_class));
-extern enum reg_class s390_secondary_input_reload_class PARAMS ((enum reg_class, enum machine_mode, rtx));
-extern enum reg_class s390_secondary_output_reload_class PARAMS ((enum reg_class, enum machine_mode, rtx));
-extern int s390_plus_operand PARAMS ((rtx, enum machine_mode));
-extern void s390_expand_plus_operand PARAMS ((rtx, rtx, rtx));
-extern void emit_symbolic_move PARAMS ((rtx *));
-extern void s390_load_address PARAMS ((rtx, rtx));
-extern void s390_expand_movstr PARAMS ((rtx, rtx, rtx));
-extern void s390_expand_clrstr PARAMS ((rtx, rtx));
-extern void s390_expand_cmpstr PARAMS ((rtx, rtx, rtx, rtx));
-extern rtx s390_return_addr_rtx PARAMS ((int, rtx));
+extern int s390_match_ccmode (rtx, enum machine_mode);
+extern enum machine_mode s390_tm_ccmode (rtx, rtx, int);
+extern enum machine_mode s390_select_ccmode (enum rtx_code, rtx, rtx);
+extern int s390_alc_comparison (rtx op, enum machine_mode mode);
+extern int s390_slb_comparison (rtx op, enum machine_mode mode);
+extern int symbolic_reference_mentioned_p (rtx);
+extern int tls_symbolic_reference_mentioned_p (rtx);
+extern rtx s390_tls_get_offset (void);
+extern int legitimate_la_operand_p (rtx);
+extern int preferred_la_operand_p (rtx);
+extern int legitimate_pic_operand_p (rtx);
+extern int legitimate_constant_p (rtx);
+extern int legitimate_reload_constant_p (rtx);
+extern int legitimate_address_p (enum machine_mode, rtx, int);
+extern rtx legitimize_pic_address (rtx, rtx);
+extern rtx legitimize_address (rtx, rtx, enum machine_mode);
+extern enum reg_class s390_preferred_reload_class (rtx, enum reg_class);
+extern enum reg_class s390_secondary_input_reload_class (enum reg_class,
+ enum machine_mode,
+ rtx);
+extern enum reg_class s390_secondary_output_reload_class (enum reg_class,
+ enum machine_mode,
+ rtx);
+extern int s390_plus_operand (rtx, enum machine_mode);
+extern void s390_expand_plus_operand (rtx, rtx, rtx);
+extern void emit_symbolic_move (rtx *);
+extern void s390_load_address (rtx, rtx);
+extern void s390_expand_movstr (rtx, rtx, rtx);
+extern void s390_expand_clrstr (rtx, rtx);
+extern void s390_expand_cmpmem (rtx, rtx, rtx, rtx);
+extern rtx s390_return_addr_rtx (int, rtx);
+
+extern void s390_output_symbolic_const (FILE *, rtx);
+extern void print_operand_address (FILE *, rtx);
+extern void print_operand (FILE *, rtx, int);
+extern void s390_output_constant_pool (rtx, rtx);
+extern void s390_output_pool_entry (FILE *, rtx, enum machine_mode,
+ unsigned int);
+extern void s390_trampoline_template (FILE *);
+extern void s390_initialize_trampoline (rtx, rtx, rtx);
+extern rtx s390_gen_rtx_const_DI (int, int);
+extern void s390_output_dwarf_dtprel (FILE*, int, rtx);
+extern int s390_agen_dep_p (rtx, rtx);
-extern void s390_output_symbolic_const PARAMS ((FILE *, rtx));
-extern void print_operand_address PARAMS ((FILE *, rtx));
-extern void print_operand PARAMS ((FILE *, rtx, int));
-extern void s390_output_constant_pool PARAMS ((rtx, rtx));
-extern void s390_trampoline_template PARAMS ((FILE *));
-extern void s390_initialize_trampoline PARAMS ((rtx, rtx, rtx));
-extern rtx s390_gen_rtx_const_DI PARAMS ((int, int));
-extern rtx s390_simplify_dwarf_addr PARAMS ((rtx));
-extern void s390_machine_dependent_reorg PARAMS ((rtx));
#endif /* RTX_CODE */
#ifdef TREE_CODE
-extern int s390_function_arg_pass_by_reference PARAMS ((enum machine_mode, tree));
-extern void s390_function_arg_advance PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
-extern tree s390_build_va_list PARAMS ((void));
+extern int s390_function_arg_pass_by_reference (enum machine_mode, tree);
+extern void s390_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
+ tree, int);
#ifdef RTX_CODE
-extern rtx s390_function_arg PARAMS ((CUMULATIVE_ARGS *, enum machine_mode, tree, int));
-extern void s390_va_start PARAMS ((tree, rtx));
-extern rtx s390_va_arg PARAMS ((tree, tree));
+extern rtx s390_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
+extern rtx s390_function_value (tree, enum machine_mode);
+extern void s390_va_start (tree, rtx);
+extern rtx s390_va_arg (tree, tree);
#endif /* RTX_CODE */
#endif /* TREE_CODE */
-
diff --git a/contrib/gcc/config/s390/s390.c b/contrib/gcc/config/s390/s390.c
index d6fda655a532..ced0bf9010a2 100644
--- a/contrib/gcc/config/s390/s390.c
+++ b/contrib/gcc/config/s390/s390.c
@@ -1,27 +1,30 @@
/* Subroutines used for code generation on IBM S/390 and zSeries
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC 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.
+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 2, or (at your option) any later
+version.
-GNU CC 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.
+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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
@@ -48,19 +51,34 @@ Boston, MA 02111-1307, USA. */
#include "langhooks.h"
#include "optabs.h"
-static bool s390_assemble_integer PARAMS ((rtx, unsigned int, int));
-static int s390_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static int s390_adjust_priority PARAMS ((rtx, int));
-static void s390_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
-static void s390_encode_section_info PARAMS ((tree, int));
-static const char *s390_strip_name_encoding PARAMS ((const char *));
-static bool s390_cannot_force_const_mem PARAMS ((rtx));
-static void s390_init_builtins PARAMS ((void));
-static rtx s390_expand_builtin PARAMS ((tree, rtx, rtx,
- enum machine_mode, int));
-static void s390_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
- HOST_WIDE_INT, tree));
+/* Machine-specific symbol_ref flags. */
+#define SYMBOL_FLAG_ALIGN1 (SYMBOL_FLAG_MACH_DEP << 0)
+
+
+static bool s390_assemble_integer (rtx, unsigned int, int);
+static void s390_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
+static void s390_encode_section_info (tree, rtx, int);
+static bool s390_cannot_force_const_mem (rtx);
+static rtx s390_delegitimize_address (rtx);
+static bool s390_return_in_memory (tree, tree);
+static void s390_init_builtins (void);
+static rtx s390_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+static void s390_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
+ HOST_WIDE_INT, tree);
+static enum attr_type s390_safe_attr_type (rtx);
+
+static int s390_adjust_cost (rtx, rtx, rtx, int);
+static int s390_adjust_priority (rtx, int);
+static int s390_issue_rate (void);
+static int s390_use_dfa_pipeline_interface (void);
+static int s390_first_cycle_multipass_dfa_lookahead (void);
+static int s390_sched_reorder2 (FILE *, int, rtx *, int *, int);
+static bool s390_rtx_costs (rtx, int, int, int *);
+static int s390_address_cost (rtx);
+static void s390_reorg (void);
+static bool s390_valid_pointer_mode (enum machine_mode);
+static tree s390_build_builtin_va_list (void);
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
@@ -78,16 +96,8 @@ static void s390_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
#undef TARGET_ASM_SELECT_RTX_SECTION
#define TARGET_ASM_SELECT_RTX_SECTION s390_select_rtx_section
-#undef TARGET_SCHED_ADJUST_COST
-#define TARGET_SCHED_ADJUST_COST s390_adjust_cost
-
-#undef TARGET_SCHED_ADJUST_PRIORITY
-#define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
-
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
-#undef TARGET_STRIP_NAME_ENCODING
-#define TARGET_STRIP_NAME_ENCODING s390_strip_name_encoding
#ifdef HAVE_AS_TLS
#undef TARGET_HAVE_TLS
@@ -96,6 +106,12 @@ static void s390_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
#undef TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM s390_cannot_force_const_mem
+#undef TARGET_DELEGITIMIZE_ADDRESS
+#define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
+
+#undef TARGET_RETURN_IN_MEMORY
+#define TARGET_RETURN_IN_MEMORY s390_return_in_memory
+
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS s390_init_builtins
#undef TARGET_EXPAND_BUILTIN
@@ -106,6 +122,33 @@ static void s390_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
+#undef TARGET_SCHED_ADJUST_COST
+#define TARGET_SCHED_ADJUST_COST s390_adjust_cost
+#undef TARGET_SCHED_ADJUST_PRIORITY
+#define TARGET_SCHED_ADJUST_PRIORITY s390_adjust_priority
+#undef TARGET_SCHED_ISSUE_RATE
+#define TARGET_SCHED_ISSUE_RATE s390_issue_rate
+#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
+#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE s390_use_dfa_pipeline_interface
+#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD s390_first_cycle_multipass_dfa_lookahead
+#undef TARGET_SCHED_REORDER2
+#define TARGET_SCHED_REORDER2 s390_sched_reorder2
+
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS s390_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST s390_address_cost
+
+#undef TARGET_MACHINE_DEPENDENT_REORG
+#define TARGET_MACHINE_DEPENDENT_REORG s390_reorg
+
+#undef TARGET_VALID_POINTER_MODE
+#define TARGET_VALID_POINTER_MODE s390_valid_pointer_mode
+
+#undef TARGET_BUILD_BUILTIN_VA_LIST
+#define TARGET_BUILD_BUILTIN_VA_LIST s390_build_builtin_va_list
+
struct gcc_target targetm = TARGET_INITIALIZER;
extern int reload_completed;
@@ -117,9 +160,6 @@ static int s390_sr_alias_set = 0;
emitted. */
rtx s390_compare_op0, s390_compare_op1;
-/* The encoding characters for the four TLS models present in ELF. */
-static char const tls_model_chars[] = " GLil";
-
/* Structure used to hold the components of a S/390 memory
address. A legitimate address on S/390 is of the general
form
@@ -137,16 +177,27 @@ struct s390_address
int pointer;
};
+/* Which cpu are we tuning for. */
+enum processor_type s390_tune;
+enum processor_flags s390_tune_flags;
+/* Which instruction set architecture to use. */
+enum processor_type s390_arch;
+enum processor_flags s390_arch_flags;
+
+/* Strings to hold which cpu and instruction set architecture to use. */
+const char *s390_tune_string; /* for -mtune=<xxx> */
+const char *s390_arch_string; /* for -march=<xxx> */
+
/* Define the structure for the machine field in struct function. */
struct machine_function GTY(())
{
- /* Label of start of initial literal pool. */
- rtx literal_pool_label;
-
/* Set, if some of the fprs 8-15 need to be saved (64 bit abi). */
int save_fprs_p;
+ /* Set if return address needs to be saved. */
+ bool save_return_addr_p;
+
/* Number of first and last gpr to be saved, restored. */
int first_save_gpr;
int first_restore_gpr;
@@ -159,43 +210,47 @@ struct machine_function GTY(())
const char *some_ld_name;
};
-static int s390_match_ccmode_set PARAMS ((rtx, enum machine_mode));
-static int s390_branch_condition_mask PARAMS ((rtx));
-static const char *s390_branch_condition_mnemonic PARAMS ((rtx, int));
-static int check_mode PARAMS ((rtx, enum machine_mode *));
-static int general_s_operand PARAMS ((rtx, enum machine_mode, int));
-static int s390_decompose_address PARAMS ((rtx, struct s390_address *));
-static rtx get_thread_pointer PARAMS ((void));
-static rtx legitimize_tls_address PARAMS ((rtx, rtx));
-static const char *get_some_local_dynamic_name PARAMS ((void));
-static int get_some_local_dynamic_name_1 PARAMS ((rtx *, void *));
-static int reg_used_in_mem_p PARAMS ((int, rtx));
-static int addr_generation_dependency_p PARAMS ((rtx, rtx));
-static int s390_split_branches PARAMS ((rtx, bool *));
-static void find_constant_pool_ref PARAMS ((rtx, rtx *));
-static void replace_constant_pool_ref PARAMS ((rtx *, rtx, rtx));
-static int find_base_register_in_addr PARAMS ((struct s390_address *));
-static bool find_base_register_ref PARAMS ((rtx));
-static void replace_base_register_ref PARAMS ((rtx *, rtx));
-static void s390_optimize_prolog PARAMS ((int));
-static bool s390_fixup_clobbered_return_reg PARAMS ((rtx));
-static int find_unused_clobbered_reg PARAMS ((void));
-static void s390_frame_info PARAMS ((void));
-static rtx save_fpr PARAMS ((rtx, int, int));
-static rtx restore_fpr PARAMS ((rtx, int, int));
-static rtx save_gprs PARAMS ((rtx, int, int, int));
-static rtx restore_gprs PARAMS ((rtx, int, int, int));
-static int s390_function_arg_size PARAMS ((enum machine_mode, tree));
-static struct machine_function * s390_init_machine_status PARAMS ((void));
-
+static int s390_match_ccmode_set (rtx, enum machine_mode);
+static int s390_branch_condition_mask (rtx);
+static const char *s390_branch_condition_mnemonic (rtx, int);
+static int check_mode (rtx, enum machine_mode *);
+static int general_s_operand (rtx, enum machine_mode, int);
+static int s390_short_displacement (rtx);
+static int s390_decompose_address (rtx, struct s390_address *);
+static rtx get_thread_pointer (void);
+static rtx legitimize_tls_address (rtx, rtx);
+static void print_shift_count_operand (FILE *, rtx);
+static const char *get_some_local_dynamic_name (void);
+static int get_some_local_dynamic_name_1 (rtx *, void *);
+static int reg_used_in_mem_p (int, rtx);
+static int addr_generation_dependency_p (rtx, rtx);
+static int s390_split_branches (void);
+static void find_constant_pool_ref (rtx, rtx *);
+static void replace_constant_pool_ref (rtx *, rtx, rtx);
+static rtx find_ltrel_base (rtx);
+static void replace_ltrel_base (rtx *, rtx);
+static void s390_optimize_prolog (bool);
+static int find_unused_clobbered_reg (void);
+static void s390_frame_info (void);
+static rtx save_fpr (rtx, int, int);
+static rtx restore_fpr (rtx, int, int);
+static rtx save_gprs (rtx, int, int, int);
+static rtx restore_gprs (rtx, int, int, int);
+static int s390_function_arg_size (enum machine_mode, tree);
+static bool s390_function_arg_float (enum machine_mode, tree);
+static struct machine_function * s390_init_machine_status (void);
+
+/* Check whether integer displacement is in range. */
+#define DISP_IN_RANGE(d) \
+ (TARGET_LONG_DISPLACEMENT? ((d) >= -524288 && (d) <= 524287) \
+ : ((d) >= 0 && (d) <= 4095))
+
/* Return true if SET either doesn't set the CC register, or else
- the source and destination have matching CC modes and that
+ the source and destination have matching CC modes and that
CC mode is at least as constrained as REQ_MODE. */
-
+
static int
-s390_match_ccmode_set (set, req_mode)
- rtx set;
- enum machine_mode req_mode;
+s390_match_ccmode_set (rtx set, enum machine_mode req_mode)
{
enum machine_mode set_mode;
@@ -233,23 +288,21 @@ s390_match_ccmode_set (set, req_mode)
if (req_mode != CCAmode)
return 0;
break;
-
+
default:
abort ();
}
-
+
return (GET_MODE (SET_SRC (set)) == set_mode);
}
-/* Return true if every SET in INSN that sets the CC register
- has source and destination with matching CC modes and that
- CC mode is at least as constrained as REQ_MODE.
+/* Return true if every SET in INSN that sets the CC register
+ has source and destination with matching CC modes and that
+ CC mode is at least as constrained as REQ_MODE.
If REQ_MODE is VOIDmode, always return false. */
-
+
int
-s390_match_ccmode (insn, req_mode)
- rtx insn;
- enum machine_mode req_mode;
+s390_match_ccmode (rtx insn, enum machine_mode req_mode)
{
int i;
@@ -272,18 +325,15 @@ s390_match_ccmode (insn, req_mode)
return 1;
}
-/* If a test-under-mask instruction can be used to implement
+/* If a test-under-mask instruction can be used to implement
(compare (and ... OP1) OP2), return the CC mode required
- to do that. Otherwise, return VOIDmode.
+ to do that. Otherwise, return VOIDmode.
MIXED is true if the instruction can distinguish between
CC1 and CC2 for mixed selected bits (TMxx), it is false
if the instruction cannot (TM). */
enum machine_mode
-s390_tm_ccmode (op1, op2, mixed)
- rtx op1;
- rtx op2;
- int mixed;
+s390_tm_ccmode (rtx op1, rtx op2, int mixed)
{
int bit0, bit1;
@@ -311,25 +361,23 @@ s390_tm_ccmode (op1, op2, mixed)
return VOIDmode;
}
-/* Given a comparison code OP (EQ, NE, etc.) and the operands
- OP0 and OP1 of a COMPARE, return the mode to be used for the
+/* Given a comparison code OP (EQ, NE, etc.) and the operands
+ OP0 and OP1 of a COMPARE, return the mode to be used for the
comparison. */
enum machine_mode
-s390_select_ccmode (code, op0, op1)
- enum rtx_code code;
- rtx op0;
- rtx op1;
+s390_select_ccmode (enum rtx_code code, rtx op0, rtx op1)
{
switch (code)
{
case EQ:
case NE:
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K'))
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
return CCAPmode;
- if (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
- || GET_CODE (op1) == NEG)
+ if ((GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
+ || GET_CODE (op1) == NEG)
+ && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
return CCLmode;
if (GET_CODE (op0) == AND)
@@ -345,11 +393,11 @@ s390_select_ccmode (code, op0, op1)
}
}
- if (register_operand (op0, HImode)
+ if (register_operand (op0, HImode)
&& GET_CODE (op1) == CONST_INT
&& (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
return CCT3mode;
- if (register_operand (op0, QImode)
+ if (register_operand (op0, QImode)
&& GET_CODE (op1) == CONST_INT
&& (INTVAL (op1) == -1 || INTVAL (op1) == 255))
return CCT3mode;
@@ -361,7 +409,7 @@ s390_select_ccmode (code, op0, op1)
case GE:
case GT:
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K'))
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (XEXP (op0, 1)), 'K', "K"))
{
if (INTVAL (XEXP((op0), 1)) < 0)
return CCANmode;
@@ -383,7 +431,8 @@ s390_select_ccmode (code, op0, op1)
case LTU:
case GEU:
- if (GET_CODE (op0) == PLUS)
+ if (GET_CODE (op0) == PLUS
+ && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
return CCL1mode;
if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
@@ -393,7 +442,8 @@ s390_select_ccmode (code, op0, op1)
case LEU:
case GTU:
- if (GET_CODE (op0) == MINUS)
+ if (GET_CODE (op0) == MINUS
+ && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT)
return CCL2mode;
if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
@@ -406,13 +456,96 @@ s390_select_ccmode (code, op0, op1)
}
}
-/* Return branch condition mask to implement a branch
+/* Return nonzero if OP is a valid comparison operator
+ for an ALC condition in mode MODE. */
+
+int
+s390_alc_comparison (rtx op, enum machine_mode mode)
+{
+ if (mode != VOIDmode && mode != GET_MODE (op))
+ return 0;
+
+ if (GET_RTX_CLASS (GET_CODE (op)) != '<')
+ return 0;
+
+ if (GET_CODE (XEXP (op, 0)) != REG
+ || REGNO (XEXP (op, 0)) != CC_REGNUM
+ || XEXP (op, 1) != const0_rtx)
+ return 0;
+
+ switch (GET_MODE (XEXP (op, 0)))
+ {
+ case CCL1mode:
+ return GET_CODE (op) == LTU;
+
+ case CCL2mode:
+ return GET_CODE (op) == LEU;
+
+ case CCUmode:
+ return GET_CODE (op) == GTU;
+
+ case CCURmode:
+ return GET_CODE (op) == LTU;
+
+ case CCSmode:
+ return GET_CODE (op) == UNGT;
+
+ case CCSRmode:
+ return GET_CODE (op) == UNLT;
+
+ default:
+ return 0;
+ }
+}
+
+/* Return nonzero if OP is a valid comparison operator
+ for an SLB condition in mode MODE. */
+
+int
+s390_slb_comparison (rtx op, enum machine_mode mode)
+{
+ if (mode != VOIDmode && mode != GET_MODE (op))
+ return 0;
+
+ if (GET_RTX_CLASS (GET_CODE (op)) != '<')
+ return 0;
+
+ if (GET_CODE (XEXP (op, 0)) != REG
+ || REGNO (XEXP (op, 0)) != CC_REGNUM
+ || XEXP (op, 1) != const0_rtx)
+ return 0;
+
+ switch (GET_MODE (XEXP (op, 0)))
+ {
+ case CCL1mode:
+ return GET_CODE (op) == GEU;
+
+ case CCL2mode:
+ return GET_CODE (op) == GTU;
+
+ case CCUmode:
+ return GET_CODE (op) == LEU;
+
+ case CCURmode:
+ return GET_CODE (op) == GEU;
+
+ case CCSmode:
+ return GET_CODE (op) == LE;
+
+ case CCSRmode:
+ return GET_CODE (op) == GE;
+
+ default:
+ return 0;
+ }
+}
+
+/* Return branch condition mask to implement a branch
specified by CODE. */
static int
-s390_branch_condition_mask (code)
- rtx code;
-{
+s390_branch_condition_mask (rtx code)
+{
const int CC0 = 1 << 3;
const int CC1 = 1 << 2;
const int CC2 = 1 << 1;
@@ -600,14 +733,12 @@ s390_branch_condition_mask (code)
}
}
-/* If INV is false, return assembler mnemonic string to implement
- a branch specified by CODE. If INV is true, return mnemonic
+/* If INV is false, return assembler mnemonic string to implement
+ a branch specified by CODE. If INV is true, return mnemonic
for the corresponding inverted branch. */
static const char *
-s390_branch_condition_mnemonic (code, inv)
- rtx code;
- int inv;
+s390_branch_condition_mnemonic (rtx code, int inv)
{
static const char *const mnemonic[16] =
{
@@ -628,228 +759,82 @@ s390_branch_condition_mnemonic (code, inv)
return mnemonic[mask];
}
-/* If OP is an integer constant of mode MODE with exactly one
- HImode subpart unequal to DEF, return the number of that
- subpart. As a special case, all HImode subparts of OP are
- equal to DEF, return zero. Otherwise, return -1. */
+/* Return the part of op which has a value different from def.
+ The size of the part is determined by mode.
+ Use this function only if you already know that op really
+ contains such a part. */
-int
-s390_single_hi (op, mode, def)
- rtx op;
- enum machine_mode mode;
- int def;
+unsigned HOST_WIDE_INT
+s390_extract_part (rtx op, enum machine_mode mode, int def)
{
- if (GET_CODE (op) == CONST_INT)
- {
- unsigned HOST_WIDE_INT value = 0;
- int n_parts = GET_MODE_SIZE (mode) / 2;
- int i, part = -1;
-
- for (i = 0; i < n_parts; i++)
- {
- if (i == 0)
- value = (unsigned HOST_WIDE_INT) INTVAL (op);
- else
- value >>= 16;
-
- if ((value & 0xffff) != (unsigned)(def & 0xffff))
- {
- if (part != -1)
- return -1;
- else
- part = i;
- }
- }
-
- return part == -1 ? 0 : (n_parts - 1 - part);
- }
-
- else if (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
- {
- unsigned HOST_WIDE_INT value = 0;
- int n_parts = GET_MODE_SIZE (mode) / 2;
- int i, part = -1;
-
- for (i = 0; i < n_parts; i++)
- {
- if (i == 0)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
- else if (i == HOST_BITS_PER_WIDE_INT / 16)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
- else
- value >>= 16;
-
- if ((value & 0xffff) != (unsigned)(def & 0xffff))
- {
- if (part != -1)
- return -1;
- else
- part = i;
- }
- }
-
- return part == -1 ? 0 : (n_parts - 1 - part);
- }
-
- return -1;
-}
-
-/* Extract the HImode part number PART from integer
- constant OP of mode MODE. */
-
-int
-s390_extract_hi (op, mode, part)
- rtx op;
- enum machine_mode mode;
- int part;
-{
- int n_parts = GET_MODE_SIZE (mode) / 2;
- if (part < 0 || part >= n_parts)
- abort();
- else
- part = n_parts - 1 - part;
-
- if (GET_CODE (op) == CONST_INT)
- {
- unsigned HOST_WIDE_INT value = (unsigned HOST_WIDE_INT) INTVAL (op);
- return ((value >> (16 * part)) & 0xffff);
- }
- else if (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
+ unsigned HOST_WIDE_INT value = 0;
+ int max_parts = HOST_BITS_PER_WIDE_INT / GET_MODE_BITSIZE (mode);
+ int part_bits = GET_MODE_BITSIZE (mode);
+ unsigned HOST_WIDE_INT part_mask = (1 << part_bits) - 1;
+ int i;
+
+ for (i = 0; i < max_parts; i++)
{
- unsigned HOST_WIDE_INT value;
- if (part < HOST_BITS_PER_WIDE_INT / 16)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
+ if (i == 0)
+ value = (unsigned HOST_WIDE_INT) INTVAL (op);
else
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
- part -= HOST_BITS_PER_WIDE_INT / 16;
-
- return ((value >> (16 * part)) & 0xffff);
+ value >>= part_bits;
+
+ if ((value & part_mask) != (def & part_mask))
+ return value & part_mask;
}
-
+
abort ();
}
/* If OP is an integer constant of mode MODE with exactly one
- QImode subpart unequal to DEF, return the number of that
- subpart. As a special case, all QImode subparts of OP are
- equal to DEF, return zero. Otherwise, return -1. */
+ part of mode PART_MODE unequal to DEF, return the number of that
+ part. Otherwise, return -1. */
int
-s390_single_qi (op, mode, def)
- rtx op;
- enum machine_mode mode;
- int def;
+s390_single_part (rtx op,
+ enum machine_mode mode,
+ enum machine_mode part_mode,
+ int def)
{
- if (GET_CODE (op) == CONST_INT)
- {
- unsigned HOST_WIDE_INT value = 0;
- int n_parts = GET_MODE_SIZE (mode);
- int i, part = -1;
-
- for (i = 0; i < n_parts; i++)
- {
- if (i == 0)
- value = (unsigned HOST_WIDE_INT) INTVAL (op);
- else
- value >>= 8;
-
- if ((value & 0xff) != (unsigned)(def & 0xff))
- {
- if (part != -1)
- return -1;
- else
- part = i;
- }
- }
-
- return part == -1 ? 0 : (n_parts - 1 - part);
- }
-
- else if (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
- {
- unsigned HOST_WIDE_INT value = 0;
- int n_parts = GET_MODE_SIZE (mode);
- int i, part = -1;
-
- for (i = 0; i < n_parts; i++)
- {
- if (i == 0)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
- else if (i == HOST_BITS_PER_WIDE_INT / 8)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op);
- else
- value >>= 8;
+ unsigned HOST_WIDE_INT value = 0;
+ int n_parts = GET_MODE_SIZE (mode) / GET_MODE_SIZE (part_mode);
+ unsigned HOST_WIDE_INT part_mask = (1 << GET_MODE_BITSIZE (part_mode)) - 1;
+ int i, part = -1;
- if ((value & 0xff) != (unsigned)(def & 0xff))
- {
- if (part != -1)
- return -1;
- else
- part = i;
- }
- }
-
- return part == -1 ? 0 : (n_parts - 1 - part);
- }
-
- return -1;
-}
-
-/* Extract the QImode part number PART from integer
- constant OP of mode MODE. */
-
-int
-s390_extract_qi (op, mode, part)
- rtx op;
- enum machine_mode mode;
- int part;
-{
- int n_parts = GET_MODE_SIZE (mode);
- if (part < 0 || part >= n_parts)
- abort();
- else
- part = n_parts - 1 - part;
-
- if (GET_CODE (op) == CONST_INT)
- {
- unsigned HOST_WIDE_INT value = (unsigned HOST_WIDE_INT) INTVAL (op);
- return ((value >> (8 * part)) & 0xff);
- }
- else if (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
+ if (GET_CODE (op) != CONST_INT)
+ return -1;
+
+ for (i = 0; i < n_parts; i++)
{
- unsigned HOST_WIDE_INT value;
- if (part < HOST_BITS_PER_WIDE_INT / 8)
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
+ if (i == 0)
+ value = (unsigned HOST_WIDE_INT) INTVAL (op);
else
- value = (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (op),
- part -= HOST_BITS_PER_WIDE_INT / 8;
-
- return ((value >> (8 * part)) & 0xff);
+ value >>= GET_MODE_BITSIZE (part_mode);
+
+ if ((value & part_mask) != (def & part_mask))
+ {
+ if (part != -1)
+ return -1;
+ else
+ part = i;
+ }
}
-
- abort ();
+ return part == -1 ? -1 : n_parts - 1 - part;
}
-/* Check whether we can (and want to) split a double-word
- move in mode MODE from SRC to DST into two single-word
+/* Check whether we can (and want to) split a double-word
+ move in mode MODE from SRC to DST into two single-word
moves, moving the subword FIRST_SUBWORD first. */
bool
-s390_split_ok_p (dst, src, mode, first_subword)
- rtx dst;
- rtx src;
- enum machine_mode mode;
- int first_subword;
+s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword)
{
/* Floating point registers cannot be split. */
if (FP_REG_P (src) || FP_REG_P (dst))
return false;
- /* We don't need to split if operands are directly accessable. */
+ /* We don't need to split if operands are directly accessible. */
if (s_operand (src, mode) || s_operand (dst, mode))
return false;
@@ -871,7 +856,7 @@ s390_split_ok_p (dst, src, mode, first_subword)
}
-/* Change optimizations to be performed, depending on the
+/* Change optimizations to be performed, depending on the
optimization level.
LEVEL is the optimization level specified; 2 if `-O2' is
@@ -880,9 +865,7 @@ s390_split_ok_p (dst, src, mode, first_subword)
SIZE is nonzero if `-Os' is specified and zero otherwise. */
void
-optimization_options (level, size)
- int level ATTRIBUTE_UNUSED;
- int size ATTRIBUTE_UNUSED;
+optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
{
/* ??? There are apparently still problems with -fcaller-saves. */
flag_caller_saves = 0;
@@ -893,13 +876,80 @@ optimization_options (level, size)
}
void
-override_options ()
+override_options (void)
{
+ int i;
+ static struct pta
+ {
+ const char *const name; /* processor name or nickname. */
+ const enum processor_type processor;
+ const enum processor_flags flags;
+ }
+ const processor_alias_table[] =
+ {
+ {"g5", PROCESSOR_9672_G5, PF_IEEE_FLOAT},
+ {"g6", PROCESSOR_9672_G6, PF_IEEE_FLOAT},
+ {"z900", PROCESSOR_2064_Z900, PF_IEEE_FLOAT | PF_ZARCH},
+ {"z990", PROCESSOR_2084_Z990, PF_IEEE_FLOAT | PF_ZARCH
+ | PF_LONG_DISPLACEMENT},
+ };
+
+ int const pta_size = ARRAY_SIZE (processor_alias_table);
+
/* Acquire a unique set number for our register saves and restores. */
s390_sr_alias_set = new_alias_set ();
/* Set up function hooks. */
init_machine_status = s390_init_machine_status;
+
+ /* Architecture mode defaults according to ABI. */
+ if (!(target_flags_explicit & MASK_ZARCH))
+ {
+ if (TARGET_64BIT)
+ target_flags |= MASK_ZARCH;
+ else
+ target_flags &= ~MASK_ZARCH;
+ }
+
+ /* Determine processor architectural level. */
+ if (!s390_arch_string)
+ s390_arch_string = TARGET_ZARCH? "z900" : "g5";
+
+ for (i = 0; i < pta_size; i++)
+ if (! strcmp (s390_arch_string, processor_alias_table[i].name))
+ {
+ s390_arch = processor_alias_table[i].processor;
+ s390_arch_flags = processor_alias_table[i].flags;
+ break;
+ }
+ if (i == pta_size)
+ error ("Unknown cpu used in -march=%s.", s390_arch_string);
+
+ /* Determine processor to tune for. */
+ if (!s390_tune_string)
+ {
+ s390_tune = s390_arch;
+ s390_tune_flags = s390_arch_flags;
+ s390_tune_string = s390_arch_string;
+ }
+ else
+ {
+ for (i = 0; i < pta_size; i++)
+ if (! strcmp (s390_tune_string, processor_alias_table[i].name))
+ {
+ s390_tune = processor_alias_table[i].processor;
+ s390_tune_flags = processor_alias_table[i].flags;
+ break;
+ }
+ if (i == pta_size)
+ error ("Unknown cpu used in -mtune=%s.", s390_tune_string);
+ }
+
+ /* Sanity checks. */
+ if (TARGET_ZARCH && !(s390_arch_flags & PF_ZARCH))
+ error ("z/Architecture mode not supported on %s.", s390_arch_string);
+ if (TARGET_64BIT && !TARGET_ZARCH)
+ error ("64-bit ABI not supported in ESA/390 mode.");
}
/* Map for smallest class containing reg regno. */
@@ -913,18 +963,26 @@ const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
- ADDR_REGS, NO_REGS, ADDR_REGS
+ ADDR_REGS, NO_REGS, ADDR_REGS
};
+/* Return attribute type of insn. */
+
+static enum attr_type
+s390_safe_attr_type (rtx insn)
+{
+ if (recog_memoized (insn) >= 0)
+ return get_attr_type (insn);
+ else
+ return TYPE_NONE;
+}
/* Return true if OP a (const_int 0) operand.
OP is the current operation.
MODE is the current operation mode. */
-
+
int
-const0_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+const0_operand (register rtx op, enum machine_mode mode)
{
return op == CONST0_RTX (mode);
}
@@ -934,20 +992,16 @@ const0_operand (op, mode)
MODE is the current operation mode. */
int
-consttable_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+consttable_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return CONSTANT_P (op);
}
/* Return true if the mode of operand OP matches MODE.
- If MODE is set to VOIDmode, set it to the mode of OP. */
+ If MODE is set to VOIDmode, set it to the mode of OP. */
static int
-check_mode (op, mode)
- register rtx op;
- enum machine_mode *mode;
+check_mode (register rtx op, enum machine_mode *mode)
{
if (*mode == VOIDmode)
*mode = GET_MODE (op);
@@ -964,9 +1018,7 @@ check_mode (op, mode)
MODE is the current operation mode. */
int
-larl_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+larl_operand (register rtx op, enum machine_mode mode)
{
if (! check_mode (op, &mode))
return 0;
@@ -974,44 +1026,45 @@ larl_operand (op, mode)
/* Allow labels and local symbols. */
if (GET_CODE (op) == LABEL_REF)
return 1;
- if (GET_CODE (op) == SYMBOL_REF
- && XSTR (op, 0)[0] != '@'
- && !tls_symbolic_operand (op)
- && (!flag_pic || SYMBOL_REF_FLAG (op)
- || CONSTANT_POOL_ADDRESS_P (op)))
- return 1;
+ if (GET_CODE (op) == SYMBOL_REF)
+ return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
+ && SYMBOL_REF_TLS_MODEL (op) == 0
+ && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
/* Everything else must have a CONST, so strip it. */
if (GET_CODE (op) != CONST)
return 0;
op = XEXP (op, 0);
- /* Allow adding *even* constants. */
+ /* Allow adding *even* in-range constants. */
if (GET_CODE (op) == PLUS)
{
if (GET_CODE (XEXP (op, 1)) != CONST_INT
|| (INTVAL (XEXP (op, 1)) & 1) != 0)
return 0;
+#if HOST_BITS_PER_WIDE_INT > 32
+ if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 32
+ || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 32))
+ return 0;
+#endif
op = XEXP (op, 0);
}
/* Labels and local symbols allowed here as well. */
if (GET_CODE (op) == LABEL_REF)
return 1;
- if (GET_CODE (op) == SYMBOL_REF
- && XSTR (op, 0)[0] != '@'
- && !tls_symbolic_operand (op)
- && (!flag_pic || SYMBOL_REF_FLAG (op)
- || CONSTANT_POOL_ADDRESS_P (op)))
- return 1;
+ if (GET_CODE (op) == SYMBOL_REF)
+ return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0
+ && SYMBOL_REF_TLS_MODEL (op) == 0
+ && (!flag_pic || SYMBOL_REF_LOCAL_P (op)));
/* Now we must have a @GOTENT offset or @PLT stub
or an @INDNTPOFF TLS offset. */
if (GET_CODE (op) == UNSPEC
- && XINT (op, 1) == 111)
+ && XINT (op, 1) == UNSPEC_GOTENT)
return 1;
if (GET_CODE (op) == UNSPEC
- && XINT (op, 1) == 113)
+ && XINT (op, 1) == UNSPEC_PLT)
return 1;
if (GET_CODE (op) == UNSPEC
&& XINT (op, 1) == UNSPEC_INDNTPOFF)
@@ -1027,10 +1080,8 @@ larl_operand (op, mode)
be accepted or not. */
static int
-general_s_operand (op, mode, allow_immediate)
- register rtx op;
- enum machine_mode mode;
- int allow_immediate;
+general_s_operand (register rtx op, enum machine_mode mode,
+ int allow_immediate)
{
struct s390_address addr;
@@ -1041,37 +1092,37 @@ general_s_operand (op, mode, allow_immediate)
/* Just like memory_operand, allow (subreg (mem ...))
after reload. */
- if (reload_completed
- && GET_CODE (op) == SUBREG
+ if (reload_completed
+ && GET_CODE (op) == SUBREG
&& GET_CODE (SUBREG_REG (op)) == MEM)
op = SUBREG_REG (op);
switch (GET_CODE (op))
{
- /* Constants that we are sure will be forced to the
- literal pool in reload are OK as s-operand. Note
- that we cannot call s390_preferred_reload_class here
- because it might not be known yet at this point
- whether the current function is a leaf or not. */
+ /* Constants are OK as s-operand if ALLOW_IMMEDIATE
+ is true and we are still before reload. */
case CONST_INT:
case CONST_DOUBLE:
if (!allow_immediate || reload_completed)
- break;
- if (!legitimate_reload_constant_p (op))
- return 1;
- if (!TARGET_64BIT)
- return 1;
- break;
+ return 0;
+ return 1;
/* Memory operands are OK unless they already use an
index register. */
case MEM:
if (GET_CODE (XEXP (op, 0)) == ADDRESSOF)
return 1;
- if (s390_decompose_address (XEXP (op, 0), &addr)
- && !addr.indx)
- return 1;
- break;
+ if (!s390_decompose_address (XEXP (op, 0), &addr))
+ return 0;
+ if (addr.indx)
+ return 0;
+ /* Do not allow literal pool references unless ALLOW_IMMEDIATE
+ is true. This prevents compares between two literal pool
+ entries from being accepted. */
+ if (!allow_immediate
+ && addr.base && REGNO (addr.base) == BASE_REGISTER)
+ return 0;
+ return 1;
default:
break;
@@ -1085,54 +1136,330 @@ general_s_operand (op, mode, allow_immediate)
MODE is the current operation mode. */
int
-s_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+s_operand (register rtx op, enum machine_mode mode)
{
return general_s_operand (op, mode, 0);
}
-/* Return true if OP is a valid S-type operand or an immediate
- operand that can be addressed as S-type operand by forcing
+/* Return true if OP is a valid S-type operand or an immediate
+ operand that can be addressed as S-type operand by forcing
it into the literal pool.
OP is the current operation.
MODE is the current operation mode. */
int
-s_imm_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+s_imm_operand (register rtx op, enum machine_mode mode)
{
return general_s_operand (op, mode, 1);
}
-/* Return true if OP is a valid operand for a 'Q' constraint.
- This differs from s_operand in that only memory operands
- without index register are accepted, nothing else. */
+/* Return true if OP a valid shift count operand.
+ OP is the current operation.
+ MODE is the current operation mode. */
int
-q_constraint (op)
- register rtx op;
+shift_count_operand (rtx op, enum machine_mode mode)
{
- struct s390_address addr;
+ HOST_WIDE_INT offset = 0;
- if (GET_CODE (op) != MEM)
+ if (! check_mode (op, &mode))
return 0;
- if (!s390_decompose_address (XEXP (op, 0), &addr))
+ /* We can have an integer constant, an address register,
+ or a sum of the two. Note that reload already checks
+ that any register present is an address register, so
+ we just check for any register here. */
+ if (GET_CODE (op) == CONST_INT)
+ {
+ offset = INTVAL (op);
+ op = NULL_RTX;
+ }
+ if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+ {
+ offset = INTVAL (XEXP (op, 1));
+ op = XEXP (op, 0);
+ }
+ while (op && GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+ if (op && GET_CODE (op) != REG)
return 0;
- if (addr.indx)
+ /* Unfortunately we have to reject constants that are invalid
+ for an address, or else reload will get confused. */
+ if (!DISP_IN_RANGE (offset))
return 0;
return 1;
}
-/* Return the cost of an address rtx ADDR. */
+/* Return true if DISP is a valid short displacement. */
+
+static int
+s390_short_displacement (rtx disp)
+{
+ /* No displacement is OK. */
+ if (!disp)
+ return 1;
+
+ /* Integer displacement in range. */
+ if (GET_CODE (disp) == CONST_INT)
+ return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
+
+ /* GOT offset is not OK, the GOT can be large. */
+ if (GET_CODE (disp) == CONST
+ && GET_CODE (XEXP (disp, 0)) == UNSPEC
+ && XINT (XEXP (disp, 0), 1) == UNSPEC_GOT)
+ return 0;
+
+ /* All other symbolic constants are literal pool references,
+ which are OK as the literal pool must be small. */
+ if (GET_CODE (disp) == CONST)
+ return 1;
+
+ return 0;
+}
+
+/* Return true if OP is a valid operand for a C constraint. */
int
-s390_address_cost (addr)
- rtx addr;
+s390_extra_constraint_str (rtx op, int c, const char * str)
+{
+ struct s390_address addr;
+
+ if (c != str[0])
+ abort ();
+
+ switch (c)
+ {
+ case 'Q':
+ if (GET_CODE (op) != MEM)
+ return 0;
+ if (!s390_decompose_address (XEXP (op, 0), &addr))
+ return 0;
+ if (addr.indx)
+ return 0;
+
+ if (TARGET_LONG_DISPLACEMENT)
+ {
+ if (!s390_short_displacement (addr.disp))
+ return 0;
+ }
+ break;
+
+ case 'R':
+ if (GET_CODE (op) != MEM)
+ return 0;
+
+ if (TARGET_LONG_DISPLACEMENT)
+ {
+ if (!s390_decompose_address (XEXP (op, 0), &addr))
+ return 0;
+ if (!s390_short_displacement (addr.disp))
+ return 0;
+ }
+ break;
+
+ case 'S':
+ if (!TARGET_LONG_DISPLACEMENT)
+ return 0;
+ if (GET_CODE (op) != MEM)
+ return 0;
+ if (!s390_decompose_address (XEXP (op, 0), &addr))
+ return 0;
+ if (addr.indx)
+ return 0;
+ if (s390_short_displacement (addr.disp))
+ return 0;
+ break;
+
+ case 'T':
+ if (!TARGET_LONG_DISPLACEMENT)
+ return 0;
+ if (GET_CODE (op) != MEM)
+ return 0;
+ /* Any invalid address here will be fixed up by reload,
+ so accept it for the most generic constraint. */
+ if (s390_decompose_address (XEXP (op, 0), &addr)
+ && s390_short_displacement (addr.disp))
+ return 0;
+ break;
+
+ case 'U':
+ if (TARGET_LONG_DISPLACEMENT)
+ {
+ if (!s390_decompose_address (op, &addr))
+ return 0;
+ if (!s390_short_displacement (addr.disp))
+ return 0;
+ }
+ break;
+
+ case 'W':
+ if (!TARGET_LONG_DISPLACEMENT)
+ return 0;
+ /* Any invalid address here will be fixed up by reload,
+ so accept it for the most generic constraint. */
+ if (s390_decompose_address (op, &addr)
+ && s390_short_displacement (addr.disp))
+ return 0;
+ break;
+
+ case 'Y':
+ return shift_count_operand (op, VOIDmode);
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Return true if VALUE matches the constraint STR. */
+
+int
+s390_const_ok_for_constraint_p (HOST_WIDE_INT value,
+ int c,
+ const char * str)
+{
+ enum machine_mode mode, part_mode;
+ int def;
+ unsigned char part;
+
+ if (c != str[0])
+ abort ();
+
+ switch (str[0])
+ {
+ case 'I':
+ return (unsigned int)value < 256;
+
+ case 'J':
+ return (unsigned int)value < 4096;
+
+ case 'K':
+ return value >= -32768 && value < 32768;
+
+ case 'L':
+ return (TARGET_LONG_DISPLACEMENT ?
+ (value >= -524288 && value <= 524287)
+ : (value >= 0 && value <= 4095));
+ case 'M':
+ return value == 2147483647;
+
+ case 'N':
+ part = str[1] - '0';
+
+ switch (str[2])
+ {
+ case 'H': part_mode = HImode; break;
+ case 'Q': part_mode = QImode; break;
+ default: return 0;
+ }
+
+ switch (str[3])
+ {
+ case 'H': mode = HImode; break;
+ case 'S': mode = SImode; break;
+ case 'D': mode = DImode; break;
+ default: return 0;
+ }
+
+ switch (str[4])
+ {
+ case '0': def = 0; break;
+ case 'F': def = -1; break;
+ default: return 0;
+ }
+
+ if (GET_MODE_SIZE (mode) <= GET_MODE_SIZE (part_mode))
+ return 0;
+
+ if (s390_single_part (GEN_INT (value), mode, part_mode, def) != part)
+ return 0;
+
+ break;
+
+ default:
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Compute a (partial) cost for rtx X. Return true if the complete
+ cost has been computed, and false if subexpressions should be
+ scanned. In either case, *TOTAL contains the cost result. */
+
+static bool
+s390_rtx_costs (rtx x, int code, int outer_code, int *total)
+{
+ switch (code)
+ {
+ case CONST:
+ if (GET_CODE (XEXP (x, 0)) == MINUS
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
+ *total = 1000;
+ else
+ *total = 0;
+ return true;
+
+ case CONST_INT:
+ /* Force_const_mem does not work out of reload, because the
+ saveable_obstack is set to reload_obstack, which does not
+ live long enough. Because of this we cannot use force_const_mem
+ in addsi3. This leads to problems with gen_add2_insn with a
+ constant greater than a short. Because of that we give an
+ addition of greater constants a cost of 3 (reload1.c 10096). */
+ /* ??? saveable_obstack no longer exists. */
+ if (outer_code == PLUS
+ && (INTVAL (x) > 32767 || INTVAL (x) < -32768))
+ *total = COSTS_N_INSNS (3);
+ else
+ *total = 0;
+ return true;
+
+ case LABEL_REF:
+ case SYMBOL_REF:
+ case CONST_DOUBLE:
+ *total = 0;
+ return true;
+
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ case PLUS:
+ case AND:
+ case IOR:
+ case XOR:
+ case MINUS:
+ case NEG:
+ case NOT:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
+ case MULT:
+ if (GET_MODE (XEXP (x, 0)) == DImode)
+ *total = COSTS_N_INSNS (40);
+ else
+ *total = COSTS_N_INSNS (7);
+ return true;
+
+ case DIV:
+ case UDIV:
+ case MOD:
+ case UMOD:
+ *total = COSTS_N_INSNS (33);
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+/* Return the cost of an address rtx ADDR. */
+
+static int
+s390_address_cost (rtx addr)
{
struct s390_address ad;
if (!s390_decompose_address (addr, &ad))
@@ -1146,9 +1473,7 @@ s390_address_cost (addr)
MODE is the current operation mode. */
int
-bras_sym_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+bras_sym_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
register enum rtx_code code = GET_CODE (op);
@@ -1159,7 +1484,7 @@ bras_sym_operand (op, mode)
/* Allow @PLT stubs. */
if (code == CONST
&& GET_CODE (XEXP (op, 0)) == UNSPEC
- && XINT (XEXP (op, 0), 1) == 113)
+ && XINT (XEXP (op, 0), 1) == UNSPEC_PLT)
return 1;
return 0;
}
@@ -1168,30 +1493,22 @@ bras_sym_operand (op, mode)
otherwise return 0. */
int
-tls_symbolic_operand (op)
- register rtx op;
+tls_symbolic_operand (register rtx op)
{
- const char *symbol_str;
-
if (GET_CODE (op) != SYMBOL_REF)
return 0;
- symbol_str = XSTR (op, 0);
-
- if (symbol_str[0] != '%')
- return 0;
- return strchr (tls_model_chars, symbol_str[1]) - tls_model_chars;
+ return SYMBOL_REF_TLS_MODEL (op);
}
/* Return true if OP is a load multiple operation. It is known to be a
- PARALLEL and the first section will be tested.
+ PARALLEL and the first section will be tested.
OP is the current operation.
MODE is the current operation mode. */
int
-load_multiple_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
+ enum machine_mode elt_mode;
int count = XVECLEN (op, 0);
unsigned int dest_regno;
rtx src_addr;
@@ -1207,13 +1524,14 @@ load_multiple_operation (op, mode)
dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
+ elt_mode = GET_MODE (SET_DEST (XVECEXP (op, 0, 0)));
/* Check, is base, or base + displacement. */
if (GET_CODE (src_addr) == REG)
off = 0;
else if (GET_CODE (src_addr) == PLUS
- && GET_CODE (XEXP (src_addr, 0)) == REG
+ && GET_CODE (XEXP (src_addr, 0)) == REG
&& GET_CODE (XEXP (src_addr, 1)) == CONST_INT)
{
off = INTVAL (XEXP (src_addr, 1));
@@ -1231,15 +1549,15 @@ load_multiple_operation (op, mode)
if (GET_CODE (elt) != SET
|| GET_CODE (SET_DEST (elt)) != REG
- || GET_MODE (SET_DEST (elt)) != Pmode
+ || GET_MODE (SET_DEST (elt)) != elt_mode
|| REGNO (SET_DEST (elt)) != dest_regno + i
|| GET_CODE (SET_SRC (elt)) != MEM
- || GET_MODE (SET_SRC (elt)) != Pmode
+ || GET_MODE (SET_SRC (elt)) != elt_mode
|| GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
|| ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
|| GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
|| INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1))
- != off + i * UNITS_PER_WORD)
+ != off + i * GET_MODE_SIZE (elt_mode))
return 0;
}
@@ -1247,15 +1565,14 @@ load_multiple_operation (op, mode)
}
/* Return true if OP is a store multiple operation. It is known to be a
- PARALLEL and the first section will be tested.
+ PARALLEL and the first section will be tested.
OP is the current operation.
MODE is the current operation mode. */
int
-store_multiple_operation (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
+ enum machine_mode elt_mode;
int count = XVECLEN (op, 0);
unsigned int src_regno;
rtx dest_addr;
@@ -1270,13 +1587,14 @@ store_multiple_operation (op, mode)
src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
+ elt_mode = GET_MODE (SET_SRC (XVECEXP (op, 0, 0)));
/* Check, is base, or base + displacement. */
if (GET_CODE (dest_addr) == REG)
off = 0;
else if (GET_CODE (dest_addr) == PLUS
- && GET_CODE (XEXP (dest_addr, 0)) == REG
+ && GET_CODE (XEXP (dest_addr, 0)) == REG
&& GET_CODE (XEXP (dest_addr, 1)) == CONST_INT)
{
off = INTVAL (XEXP (dest_addr, 1));
@@ -1294,15 +1612,15 @@ store_multiple_operation (op, mode)
if (GET_CODE (elt) != SET
|| GET_CODE (SET_SRC (elt)) != REG
- || GET_MODE (SET_SRC (elt)) != Pmode
+ || GET_MODE (SET_SRC (elt)) != elt_mode
|| REGNO (SET_SRC (elt)) != src_regno + i
|| GET_CODE (SET_DEST (elt)) != MEM
- || GET_MODE (SET_DEST (elt)) != Pmode
+ || GET_MODE (SET_DEST (elt)) != elt_mode
|| GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
|| ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
|| GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
|| INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1))
- != off + i * UNITS_PER_WORD)
+ != off + i * GET_MODE_SIZE (elt_mode))
return 0;
}
return 1;
@@ -1312,8 +1630,7 @@ store_multiple_operation (op, mode)
/* Return true if OP contains a symbol reference */
int
-symbolic_reference_mentioned_p (op)
- rtx op;
+symbolic_reference_mentioned_p (rtx op)
{
register const char *fmt;
register int i;
@@ -1343,8 +1660,7 @@ symbolic_reference_mentioned_p (op)
/* Return true if OP contains a reference to a thread-local symbol. */
int
-tls_symbolic_reference_mentioned_p (op)
- rtx op;
+tls_symbolic_reference_mentioned_p (rtx op)
{
register const char *fmt;
register int i;
@@ -1372,19 +1688,18 @@ tls_symbolic_reference_mentioned_p (op)
}
-/* Return true if OP is a legitimate general operand when
- generating PIC code. It is given that flag_pic is on
+/* Return true if OP is a legitimate general operand when
+ generating PIC code. It is given that flag_pic is on
and that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
int
-legitimate_pic_operand_p (op)
- register rtx op;
+legitimate_pic_operand_p (register rtx op)
{
/* Accept all non-symbolic constants. */
if (!SYMBOLIC_CONST (op))
return 1;
- /* Reject everything else; must be handled
+ /* Reject everything else; must be handled
via emit_symbolic_move. */
return 0;
}
@@ -1393,15 +1708,14 @@ legitimate_pic_operand_p (op)
It is given that OP satisfies CONSTANT_P or is a CONST_DOUBLE. */
int
-legitimate_constant_p (op)
- register rtx op;
+legitimate_constant_p (register rtx op)
{
/* Accept all non-symbolic constants. */
if (!SYMBOLIC_CONST (op))
return 1;
/* Accept immediate LARL operands. */
- if (TARGET_64BIT && larl_operand (op, VOIDmode))
+ if (TARGET_CPU_ZARCH && larl_operand (op, VOIDmode))
return 1;
/* Thread-local symbols are never legal constants. This is
@@ -1426,8 +1740,7 @@ legitimate_constant_p (op)
not constant (TLS) or not known at final link time (PIC). */
static bool
-s390_cannot_force_const_mem (x)
- rtx x;
+s390_cannot_force_const_mem (rtx x)
{
switch (GET_CODE (x))
{
@@ -1459,10 +1772,10 @@ s390_cannot_force_const_mem (x)
switch (XINT (x, 1))
{
/* Only lt-relative or GOT-relative UNSPECs are OK. */
- case 100:
- case 104:
- case 112:
- case 114:
+ case UNSPEC_LTREL_OFFSET:
+ case UNSPEC_GOT:
+ case UNSPEC_GOTOFF:
+ case UNSPEC_PLTOFF:
case UNSPEC_TLSGD:
case UNSPEC_TLSLDM:
case UNSPEC_NTPOFF:
@@ -1482,27 +1795,31 @@ s390_cannot_force_const_mem (x)
}
/* Returns true if the constant value OP is a legitimate general
- operand during and after reload. The difference to
+ operand during and after reload. The difference to
legitimate_constant_p is that this function will not accept
a constant that would need to be forced to the literal pool
before it can be used as operand. */
int
-legitimate_reload_constant_p (op)
- register rtx op;
+legitimate_reload_constant_p (register rtx op)
{
+ /* Accept la(y) operands. */
+ if (GET_CODE (op) == CONST_INT
+ && DISP_IN_RANGE (INTVAL (op)))
+ return 1;
+
/* Accept l(g)hi operands. */
if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), 'K'))
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'K', "K"))
return 1;
/* Accept lliXX operands. */
- if (TARGET_64BIT
- && s390_single_hi (op, DImode, 0) >= 0)
+ if (TARGET_ZARCH
+ && s390_single_part (op, DImode, HImode, 0) >= 0)
return 1;
/* Accept larl operands. */
- if (TARGET_64BIT
+ if (TARGET_CPU_ZARCH
&& larl_operand (op, VOIDmode))
return 1;
@@ -1514,9 +1831,7 @@ legitimate_reload_constant_p (op)
return the class of reg to actually use. */
enum reg_class
-s390_preferred_reload_class (op, class)
- rtx op;
- enum reg_class class;
+s390_preferred_reload_class (rtx op, enum reg_class class)
{
/* This can happen if a floating point constant is being
reloaded into an integer register. Leave well alone. */
@@ -1563,10 +1878,8 @@ s390_preferred_reload_class (op, class)
is not a legitimate operand of the LOAD ADDRESS instruction. */
enum reg_class
-s390_secondary_input_reload_class (class, mode, in)
- enum reg_class class ATTRIBUTE_UNUSED;
- enum machine_mode mode;
- rtx in;
+s390_secondary_input_reload_class (enum reg_class class ATTRIBUTE_UNUSED,
+ enum machine_mode mode, rtx in)
{
if (s390_plus_operand (in, mode))
return ADDR_REGS;
@@ -1577,14 +1890,12 @@ s390_secondary_input_reload_class (class, mode, in)
/* Return the register class of a scratch register needed to
store a register of class CLASS in MODE into OUT:
- We need a temporary when storing a double-word to a
+ We need a temporary when storing a double-word to a
non-offsettable memory address. */
enum reg_class
-s390_secondary_output_reload_class (class, mode, out)
- enum reg_class class;
- enum machine_mode mode;
- rtx out;
+s390_secondary_output_reload_class (enum reg_class class,
+ enum machine_mode mode, rtx out)
{
if ((TARGET_64BIT ? mode == TImode
: (mode == DImode || mode == DFmode))
@@ -1598,14 +1909,12 @@ s390_secondary_output_reload_class (class, mode, out)
}
/* Return true if OP is a PLUS that is not a legitimate
- operand for the LA instruction.
+ operand for the LA instruction.
OP is the current operation.
MODE is the current operation mode. */
int
-s390_plus_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+s390_plus_operand (register rtx op, enum machine_mode mode)
{
if (!check_mode (op, &mode) || mode != Pmode)
return FALSE;
@@ -1624,10 +1933,8 @@ s390_plus_operand (op, mode)
SCRATCH may be used as scratch register. */
void
-s390_expand_plus_operand (target, src, scratch)
- register rtx target;
- register rtx src;
- register rtx scratch;
+s390_expand_plus_operand (register rtx target, register rtx src,
+ register rtx scratch)
{
rtx sum1, sum2;
struct s390_address ad;
@@ -1693,14 +2000,14 @@ s390_expand_plus_operand (target, src, scratch)
canonical form so that they will be recognized. */
static int
-s390_decompose_address (addr, out)
- register rtx addr;
- struct s390_address *out;
+s390_decompose_address (register rtx addr, struct s390_address *out)
{
rtx base = NULL_RTX;
rtx indx = NULL_RTX;
rtx disp = NULL_RTX;
int pointer = FALSE;
+ int base_ptr = FALSE;
+ int indx_ptr = FALSE;
/* Decompose address into base + index + displacement. */
@@ -1746,35 +2053,18 @@ s390_decompose_address (addr, out)
disp = addr; /* displacement */
- /* Prefer to use pointer as base, not index. */
- if (base && indx)
- {
- int base_ptr = GET_CODE (base) == UNSPEC
- || (REG_P (base) && REG_POINTER (base));
- int indx_ptr = GET_CODE (indx) == UNSPEC
- || (REG_P (indx) && REG_POINTER (indx));
-
- if (!base_ptr && indx_ptr)
- {
- rtx tmp = base;
- base = indx;
- indx = tmp;
- }
- }
-
/* Validate base register. */
if (base)
{
if (GET_CODE (base) == UNSPEC)
{
- if (XVECLEN (base, 0) != 1 || XINT (base, 1) != 101)
- return FALSE;
- base = XVECEXP (base, 0, 0);
- pointer = TRUE;
+ if (XVECLEN (base, 0) != 1 || XINT (base, 1) != UNSPEC_LTREL_BASE)
+ return FALSE;
+ base = gen_rtx_REG (Pmode, BASE_REGISTER);
}
if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
- return FALSE;
+ return FALSE;
if (REGNO (base) == BASE_REGISTER
|| REGNO (base) == STACK_POINTER_REGNUM
@@ -1783,11 +2073,9 @@ s390_decompose_address (addr, out)
&& frame_pointer_needed
&& REGNO (base) == HARD_FRAME_POINTER_REGNUM)
|| REGNO (base) == ARG_POINTER_REGNUM
- || (REGNO (base) >= FIRST_VIRTUAL_REGISTER
- && REGNO (base) <= LAST_VIRTUAL_REGISTER)
|| (flag_pic
&& REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
- pointer = TRUE;
+ pointer = base_ptr = TRUE;
}
/* Validate index register. */
@@ -1795,14 +2083,13 @@ s390_decompose_address (addr, out)
{
if (GET_CODE (indx) == UNSPEC)
{
- if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != 101)
- return FALSE;
- indx = XVECEXP (indx, 0, 0);
- pointer = TRUE;
+ if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != UNSPEC_LTREL_BASE)
+ return FALSE;
+ indx = gen_rtx_REG (Pmode, BASE_REGISTER);
}
if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
- return FALSE;
+ return FALSE;
if (REGNO (indx) == BASE_REGISTER
|| REGNO (indx) == STACK_POINTER_REGNUM
@@ -1811,11 +2098,18 @@ s390_decompose_address (addr, out)
&& frame_pointer_needed
&& REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
|| REGNO (indx) == ARG_POINTER_REGNUM
- || (REGNO (indx) >= FIRST_VIRTUAL_REGISTER
- && REGNO (indx) <= LAST_VIRTUAL_REGISTER)
|| (flag_pic
&& REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
- pointer = TRUE;
+ pointer = indx_ptr = TRUE;
+ }
+
+ /* Prefer to use pointer as base, not index. */
+ if (base && indx && !base_ptr
+ && (indx_ptr || (!REG_POINTER (base) && REG_POINTER (indx))))
+ {
+ rtx tmp = base;
+ base = indx;
+ indx = tmp;
}
/* Validate displacement. */
@@ -1834,16 +2128,16 @@ s390_decompose_address (addr, out)
this is fixed up by reload in any case. */
if (base != arg_pointer_rtx && indx != arg_pointer_rtx)
{
- if (INTVAL (disp) < 0 || INTVAL (disp) >= 4096)
+ if (!DISP_IN_RANGE (INTVAL (disp)))
return FALSE;
}
}
- /* In the small-PIC case, the linker converts @GOT12
+ /* In the small-PIC case, the linker converts @GOT
and @GOTNTPOFF offsets to possible displacements. */
else if (GET_CODE (disp) == CONST
&& GET_CODE (XEXP (disp, 0)) == UNSPEC
- && (XINT (XEXP (disp, 0), 1) == 110
+ && (XINT (XEXP (disp, 0), 1) == UNSPEC_GOT
|| XINT (XEXP (disp, 0), 1) == UNSPEC_GOTNTPOFF))
{
if (flag_pic != 1)
@@ -1860,7 +2154,7 @@ s390_decompose_address (addr, out)
{
pointer = TRUE;
}
-
+
/* Likewise if a constant offset is present. */
else if (GET_CODE (disp) == CONST
&& GET_CODE (XEXP (disp, 0)) == PLUS
@@ -1872,7 +2166,7 @@ s390_decompose_address (addr, out)
pointer = TRUE;
}
- /* We can convert literal pool addresses to
+ /* We can convert literal pool addresses to
displacements by basing them off the base register. */
else
{
@@ -1899,7 +2193,7 @@ s390_decompose_address (addr, out)
if (offset && offset >= GET_MODE_SIZE (get_pool_mode (disp)))
return FALSE;
- /* Either base or index must be free to
+ /* Either base or index must be free to
hold the base register. */
if (base && indx)
return FALSE;
@@ -1910,7 +2204,8 @@ s390_decompose_address (addr, out)
else
base = gen_rtx_REG (Pmode, BASE_REGISTER);
- disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp), 100);
+ disp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, disp),
+ UNSPEC_LTREL_OFFSET);
disp = gen_rtx_CONST (Pmode, disp);
if (offset)
@@ -1922,7 +2217,7 @@ s390_decompose_address (addr, out)
if (!base && !indx)
pointer = TRUE;
-
+
if (out)
{
out->base = base;
@@ -1938,10 +2233,8 @@ s390_decompose_address (addr, out)
STRICT specifies whether strict register checking applies. */
int
-legitimate_address_p (mode, addr, strict)
- enum machine_mode mode ATTRIBUTE_UNUSED;
- register rtx addr;
- int strict;
+legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+ register rtx addr, int strict)
{
struct s390_address ad;
if (!s390_decompose_address (addr, &ad))
@@ -1970,8 +2263,7 @@ legitimate_address_p (mode, addr, strict)
address, as LA performs only a 31-bit addition. */
int
-legitimate_la_operand_p (op)
- register rtx op;
+legitimate_la_operand_p (register rtx op)
{
struct s390_address addr;
if (!s390_decompose_address (op, &addr))
@@ -1985,10 +2277,9 @@ legitimate_la_operand_p (op)
/* Return 1 if OP is a valid operand for the LA instruction,
and we prefer to use LA over addition to compute it. */
-
+
int
-preferred_la_operand_p (op)
- register rtx op;
+preferred_la_operand_p (register rtx op)
{
struct s390_address addr;
if (!s390_decompose_address (op, &addr))
@@ -2012,9 +2303,7 @@ preferred_la_operand_p (op)
where legitimate_la_operand_p (SRC) returns false. */
void
-s390_load_address (dst, src)
- rtx dst;
- rtx src;
+s390_load_address (rtx dst, rtx src)
{
if (TARGET_64BIT)
emit_move_insn (dst, src);
@@ -2033,7 +2322,7 @@ s390_load_address (dst, src)
2. Static data references, constant pool addresses, and code labels
compute the address as an offset from the GOT, whose base is in
- the PIC reg. Static data objects have SYMBOL_REF_FLAG set to
+ the PIC reg. Static data objects have SYMBOL_FLAG_LOCAL set to
differentiate them from global data objects. The returned
address is the PIC reg + an unspec constant.
@@ -2041,41 +2330,37 @@ s390_load_address (dst, src)
reg also appears in the address. */
rtx
-legitimize_pic_address (orig, reg)
- rtx orig;
- rtx reg;
+legitimize_pic_address (rtx orig, rtx reg)
{
rtx addr = orig;
rtx new = orig;
rtx base;
if (GET_CODE (addr) == LABEL_REF
- || (GET_CODE (addr) == SYMBOL_REF
- && (SYMBOL_REF_FLAG (addr)
- || CONSTANT_POOL_ADDRESS_P (addr))))
+ || (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (addr)))
{
/* This is a local symbol. */
- if (TARGET_64BIT && larl_operand (addr, VOIDmode))
+ if (TARGET_CPU_ZARCH && larl_operand (addr, VOIDmode))
{
- /* Access local symbols PC-relative via LARL.
- This is the same as in the non-PIC case, so it is
+ /* Access local symbols PC-relative via LARL.
+ This is the same as in the non-PIC case, so it is
handled automatically ... */
}
else
{
- /* Access local symbols relative to the literal pool. */
+ /* Access local symbols relative to the GOT. */
rtx temp = reg? reg : gen_reg_rtx (Pmode);
- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 100);
+ if (reload_in_progress || reload_completed)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+
+ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
addr = gen_rtx_CONST (Pmode, addr);
addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
- base = gen_rtx_REG (Pmode, BASE_REGISTER);
- base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
- new = gen_rtx_PLUS (Pmode, base, temp);
-
+ new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
if (reg != 0)
{
emit_move_insn (reg, new);
@@ -2091,12 +2376,12 @@ legitimize_pic_address (orig, reg)
if (flag_pic == 1)
{
/* Assume GOT offset < 4k. This is handled the same way
- in both 31- and 64-bit code (@GOT12). */
+ in both 31- and 64-bit code (@GOT). */
if (reload_in_progress || reload_completed)
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
- new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 110);
+ new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
new = gen_rtx_CONST (Pmode, new);
new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
new = gen_rtx_MEM (Pmode, new);
@@ -2104,14 +2389,14 @@ legitimize_pic_address (orig, reg)
emit_move_insn (reg, new);
new = reg;
}
- else if (TARGET_64BIT)
+ else if (TARGET_CPU_ZARCH)
{
/* If the GOT offset might be >= 4k, we determine the position
of the GOT entry via a PC-relative LARL (@GOTENT). */
rtx temp = gen_reg_rtx (Pmode);
- new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 111);
+ new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT);
new = gen_rtx_CONST (Pmode, new);
emit_move_insn (temp, new);
@@ -2122,7 +2407,7 @@ legitimize_pic_address (orig, reg)
}
else
{
- /* If the GOT offset might be >= 4k, we have to load it
+ /* If the GOT offset might be >= 4k, we have to load it
from the literal pool (@GOT). */
rtx temp = gen_reg_rtx (Pmode);
@@ -2130,7 +2415,7 @@ legitimize_pic_address (orig, reg)
if (reload_in_progress || reload_completed)
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 112);
+ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
addr = gen_rtx_CONST (Pmode, addr);
addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
@@ -2141,7 +2426,7 @@ legitimize_pic_address (orig, reg)
emit_move_insn (reg, new);
new = reg;
}
- }
+ }
else
{
if (GET_CODE (addr) == CONST)
@@ -2153,35 +2438,41 @@ legitimize_pic_address (orig, reg)
abort ();
switch (XINT (addr, 1))
{
- /* If someone moved an @GOT or lt-relative UNSPEC
+ /* If someone moved a GOT-relative UNSPEC
out of the literal pool, force them back in. */
- case 100:
- case 112:
- case 114:
+ case UNSPEC_GOTOFF:
+ case UNSPEC_PLTOFF:
new = force_const_mem (Pmode, orig);
break;
+ /* @GOT is OK as is if small. */
+ case UNSPEC_GOT:
+ if (flag_pic == 2)
+ new = force_const_mem (Pmode, orig);
+ break;
+
/* @GOTENT is OK as is. */
- case 111:
+ case UNSPEC_GOTENT:
break;
/* @PLT is OK as is on 64-bit, must be converted to
- lt-relative PLT on 31-bit. */
- case 113:
- if (!TARGET_64BIT)
+ GOT-relative @PLTOFF on 31-bit. */
+ case UNSPEC_PLT:
+ if (!TARGET_CPU_ZARCH)
{
rtx temp = reg? reg : gen_reg_rtx (Pmode);
+ if (reload_in_progress || reload_completed)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+
addr = XVECEXP (addr, 0, 0);
- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 114);
+ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
+ UNSPEC_PLTOFF);
addr = gen_rtx_CONST (Pmode, addr);
addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
- base = gen_rtx_REG (Pmode, BASE_REGISTER);
- base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
- new = gen_rtx_PLUS (Pmode, base, temp);
-
+ new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
if (reg != 0)
{
emit_move_insn (reg, new);
@@ -2201,23 +2492,21 @@ legitimize_pic_address (orig, reg)
if (GET_CODE (addr) == PLUS)
{
rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
- /* Check first to see if this is a constant offset
+ /* Check first to see if this is a constant offset
from a local symbol reference. */
if ((GET_CODE (op0) == LABEL_REF
- || (GET_CODE (op0) == SYMBOL_REF
- && (SYMBOL_REF_FLAG (op0)
- || CONSTANT_POOL_ADDRESS_P (op0))))
+ || (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
&& GET_CODE (op1) == CONST_INT)
{
- if (TARGET_64BIT && larl_operand (op0, VOIDmode))
+ if (TARGET_CPU_ZARCH && larl_operand (op0, VOIDmode))
{
if (INTVAL (op1) & 1)
{
- /* LARL can't handle odd offsets, so emit a
+ /* LARL can't handle odd offsets, so emit a
pair of LARL and LA. */
rtx temp = reg? reg : gen_reg_rtx (Pmode);
- if (INTVAL (op1) < 0 || INTVAL (op1) >= 4096)
+ if (!DISP_IN_RANGE (INTVAL (op1)))
{
int even = INTVAL (op1) - 1;
op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
@@ -2242,20 +2531,21 @@ legitimize_pic_address (orig, reg)
}
else
{
- /* Access local symbols relative to the literal pool. */
+ /* Access local symbols relative to the GOT. */
rtx temp = reg? reg : gen_reg_rtx (Pmode);
- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 100);
+ if (reload_in_progress || reload_completed)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+
+ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0),
+ UNSPEC_GOTOFF);
addr = gen_rtx_PLUS (Pmode, addr, op1);
addr = gen_rtx_CONST (Pmode, addr);
addr = force_const_mem (Pmode, addr);
- emit_move_insn (temp, addr);
-
- base = gen_rtx_REG (Pmode, BASE_REGISTER);
- base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
- new = gen_rtx_PLUS (Pmode, base, temp);
+ emit_move_insn (temp, addr);
+ new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
if (reg != 0)
{
emit_move_insn (reg, new);
@@ -2264,16 +2554,15 @@ legitimize_pic_address (orig, reg)
}
}
- /* Now, check whether it is an LT-relative symbol plus offset
+ /* Now, check whether it is a GOT relative symbol plus offset
that was pulled out of the literal pool. Force it back in. */
else if (GET_CODE (op0) == UNSPEC
- && GET_CODE (op1) == CONST_INT)
+ && GET_CODE (op1) == CONST_INT
+ && XINT (op0, 1) == UNSPEC_GOTOFF)
{
if (XVECLEN (op0, 0) != 1)
abort ();
- if (XINT (op0, 1) != 100)
- abort ();
new = force_const_mem (Pmode, orig);
}
@@ -2308,7 +2597,7 @@ legitimize_pic_address (orig, reg)
/* Load the thread pointer into a register. */
static rtx
-get_thread_pointer ()
+get_thread_pointer (void)
{
rtx tp;
@@ -2323,7 +2612,7 @@ get_thread_pointer ()
static GTY(()) rtx s390_tls_symbol;
rtx
-s390_tls_get_offset ()
+s390_tls_get_offset (void)
{
if (!s390_tls_symbol)
s390_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_offset");
@@ -2335,9 +2624,7 @@ s390_tls_get_offset ()
this (thread-local) address. REG may be used as temporary. */
static rtx
-legitimize_tls_address (addr, reg)
- rtx addr;
- rtx reg;
+legitimize_tls_address (rtx addr, rtx reg)
{
rtx new, tls_call, temp, base, r2, insn;
@@ -2417,7 +2704,7 @@ legitimize_tls_address (addr, reg)
temp = gen_reg_rtx (Pmode);
emit_move_insn (temp, new);
}
- else if (TARGET_64BIT)
+ else if (TARGET_CPU_ZARCH)
{
/* If the GOT offset might be >= 4k, we determine the position
of the GOT entry via a PC-relative LARL. */
@@ -2434,7 +2721,7 @@ legitimize_tls_address (addr, reg)
}
else if (flag_pic)
{
- /* If the GOT offset might be >= 4k, we have to load it
+ /* If the GOT offset might be >= 4k, we have to load it
from the literal pool. */
if (reload_in_progress || reload_completed)
@@ -2506,7 +2793,7 @@ legitimize_tls_address (addr, reg)
switch (XINT (XEXP (addr, 0), 1))
{
case UNSPEC_INDNTPOFF:
- if (TARGET_64BIT)
+ if (TARGET_CPU_ZARCH)
new = addr;
else
abort ();
@@ -2526,8 +2813,7 @@ legitimize_tls_address (addr, reg)
/* Emit insns to move operands[1] into operands[0]. */
void
-emit_symbolic_move (operands)
- rtx *operands;
+emit_symbolic_move (rtx *operands)
{
rtx temp = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
@@ -2551,10 +2837,8 @@ emit_symbolic_move (operands)
See comments by legitimize_pic_address for details. */
rtx
-legitimize_address (x, oldx, mode)
- register rtx x;
- register rtx oldx ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+legitimize_address (register rtx x, register rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
rtx constant_term = const0_rtx;
@@ -2568,8 +2852,8 @@ legitimize_address (x, oldx, mode)
else if (flag_pic)
{
if (SYMBOLIC_CONST (x)
- || (GET_CODE (x) == PLUS
- && (SYMBOLIC_CONST (XEXP (x, 0))
+ || (GET_CODE (x) == PLUS
+ && (SYMBOLIC_CONST (XEXP (x, 0))
|| SYMBOLIC_CONST (XEXP (x, 1)))))
x = legitimize_pic_address (x, 0);
@@ -2581,15 +2865,15 @@ legitimize_address (x, oldx, mode)
/* Optimize loading of large displacements by splitting them
into the multiple of 4K and the rest; this allows the
- former to be CSE'd if possible.
+ former to be CSE'd if possible.
Don't do this if the displacement is added to a register
pointing into the stack frame, as the offsets will
change later anyway. */
if (GET_CODE (constant_term) == CONST_INT
- && (INTVAL (constant_term) < 0
- || INTVAL (constant_term) >= 4096)
+ && !TARGET_LONG_DISPLACEMENT
+ && !DISP_IN_RANGE (INTVAL (constant_term))
&& !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
{
HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
@@ -2636,39 +2920,17 @@ legitimize_address (x, oldx, mode)
/* Emit code to move LEN bytes from DST to SRC. */
void
-s390_expand_movstr (dst, src, len)
- rtx dst;
- rtx src;
- rtx len;
+s390_expand_movstr (rtx dst, rtx src, rtx len)
{
- rtx (*gen_short) PARAMS ((rtx, rtx, rtx)) =
- TARGET_64BIT ? gen_movstr_short_64 : gen_movstr_short_31;
- rtx (*gen_long) PARAMS ((rtx, rtx, rtx, rtx)) =
- TARGET_64BIT ? gen_movstr_long_64 : gen_movstr_long_31;
-
-
if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
{
if (INTVAL (len) > 0)
- emit_insn ((*gen_short) (dst, src, GEN_INT (INTVAL (len) - 1)));
+ emit_insn (gen_movstr_short (dst, src, GEN_INT (INTVAL (len) - 1)));
}
else if (TARGET_MVCLE)
{
- enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
- enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
- rtx reg0 = gen_reg_rtx (double_mode);
- rtx reg1 = gen_reg_rtx (double_mode);
-
- emit_move_insn (gen_highpart (single_mode, reg0),
- force_operand (XEXP (dst, 0), NULL_RTX));
- emit_move_insn (gen_highpart (single_mode, reg1),
- force_operand (XEXP (src, 0), NULL_RTX));
-
- convert_move (gen_lowpart (single_mode, reg0), len, 1);
- convert_move (gen_lowpart (single_mode, reg1), len, 1);
-
- emit_insn ((*gen_long) (reg0, reg1, reg0, reg1));
+ emit_insn (gen_movstr_long (dst, src, convert_to_mode (Pmode, len, 1)));
}
else
@@ -2680,9 +2942,9 @@ s390_expand_movstr (dst, src, len)
mode = GET_MODE (len);
if (mode == VOIDmode)
- mode = word_mode;
+ mode = Pmode;
- type = (*lang_hooks.types.type_for_mode) (mode, 1);
+ type = lang_hooks.types.type_for_mode (mode, 1);
if (!type)
abort ();
@@ -2692,14 +2954,14 @@ s390_expand_movstr (dst, src, len)
blocks = gen_reg_rtx (mode);
convert_move (count, len, 1);
- emit_cmp_and_jump_insns (count, const0_rtx,
+ emit_cmp_and_jump_insns (count, const0_rtx,
EQ, NULL_RTX, mode, 1, end_label);
emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
emit_move_insn (src_addr, force_operand (XEXP (src, 0), NULL_RTX));
dst = change_address (dst, VOIDmode, dst_addr);
src = change_address (src, VOIDmode, src_addr);
-
+
temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
if (temp != count)
emit_move_insn (count, temp);
@@ -2713,19 +2975,20 @@ s390_expand_movstr (dst, src, len)
make_tree (type, blocks),
make_tree (type, const0_rtx)));
- emit_insn ((*gen_short) (dst, src, GEN_INT (255)));
- s390_load_address (dst_addr,
+ emit_insn (gen_movstr_short (dst, src, GEN_INT (255)));
+ s390_load_address (dst_addr,
gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
- s390_load_address (src_addr,
+ s390_load_address (src_addr,
gen_rtx_PLUS (Pmode, src_addr, GEN_INT (256)));
-
+
temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
if (temp != blocks)
emit_move_insn (blocks, temp);
expand_end_loop ();
- emit_insn ((*gen_short) (dst, src, convert_to_mode (word_mode, count, 1)));
+ emit_insn (gen_movstr_short (dst, src,
+ convert_to_mode (Pmode, count, 1)));
emit_label (end_label);
}
}
@@ -2733,37 +2996,17 @@ s390_expand_movstr (dst, src, len)
/* Emit code to clear LEN bytes at DST. */
void
-s390_expand_clrstr (dst, len)
- rtx dst;
- rtx len;
+s390_expand_clrstr (rtx dst, rtx len)
{
- rtx (*gen_short) PARAMS ((rtx, rtx)) =
- TARGET_64BIT ? gen_clrstr_short_64 : gen_clrstr_short_31;
- rtx (*gen_long) PARAMS ((rtx, rtx, rtx)) =
- TARGET_64BIT ? gen_clrstr_long_64 : gen_clrstr_long_31;
-
-
if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
{
if (INTVAL (len) > 0)
- emit_insn ((*gen_short) (dst, GEN_INT (INTVAL (len) - 1)));
+ emit_insn (gen_clrstr_short (dst, GEN_INT (INTVAL (len) - 1)));
}
else if (TARGET_MVCLE)
{
- enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
- enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
- rtx reg0 = gen_reg_rtx (double_mode);
- rtx reg1 = gen_reg_rtx (double_mode);
-
- emit_move_insn (gen_highpart (single_mode, reg0),
- force_operand (XEXP (dst, 0), NULL_RTX));
- convert_move (gen_lowpart (single_mode, reg0), len, 1);
-
- emit_move_insn (gen_highpart (single_mode, reg1), const0_rtx);
- emit_move_insn (gen_lowpart (single_mode, reg1), const0_rtx);
-
- emit_insn ((*gen_long) (reg0, reg1, reg0));
+ emit_insn (gen_clrstr_long (dst, convert_to_mode (Pmode, len, 1)));
}
else
@@ -2775,9 +3018,9 @@ s390_expand_clrstr (dst, len)
mode = GET_MODE (len);
if (mode == VOIDmode)
- mode = word_mode;
+ mode = Pmode;
- type = (*lang_hooks.types.type_for_mode) (mode, 1);
+ type = lang_hooks.types.type_for_mode (mode, 1);
if (!type)
abort ();
@@ -2787,12 +3030,12 @@ s390_expand_clrstr (dst, len)
blocks = gen_reg_rtx (mode);
convert_move (count, len, 1);
- emit_cmp_and_jump_insns (count, const0_rtx,
+ emit_cmp_and_jump_insns (count, const0_rtx,
EQ, NULL_RTX, mode, 1, end_label);
emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX));
dst = change_address (dst, VOIDmode, dst_addr);
-
+
temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
if (temp != count)
emit_move_insn (count, temp);
@@ -2806,17 +3049,17 @@ s390_expand_clrstr (dst, len)
make_tree (type, blocks),
make_tree (type, const0_rtx)));
- emit_insn ((*gen_short) (dst, GEN_INT (255)));
- s390_load_address (dst_addr,
+ emit_insn (gen_clrstr_short (dst, GEN_INT (255)));
+ s390_load_address (dst_addr,
gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
-
+
temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
if (temp != blocks)
emit_move_insn (blocks, temp);
expand_end_loop ();
- emit_insn ((*gen_short) (dst, convert_to_mode (word_mode, count, 1)));
+ emit_insn (gen_clrstr_short (dst, convert_to_mode (Pmode, count, 1)));
emit_label (end_label);
}
}
@@ -2825,17 +3068,9 @@ s390_expand_clrstr (dst, len)
and return the result in TARGET. */
void
-s390_expand_cmpstr (target, op0, op1, len)
- rtx target;
- rtx op0;
- rtx op1;
- rtx len;
-{
- rtx (*gen_short) PARAMS ((rtx, rtx, rtx)) =
- TARGET_64BIT ? gen_cmpstr_short_64 : gen_cmpstr_short_31;
- rtx (*gen_long) PARAMS ((rtx, rtx, rtx, rtx)) =
- TARGET_64BIT ? gen_cmpstr_long_64 : gen_cmpstr_long_31;
- rtx (*gen_result) PARAMS ((rtx)) =
+s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
+{
+ rtx (*gen_result) (rtx) =
GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si;
op0 = protect_from_queue (op0, 0);
@@ -2846,8 +3081,8 @@ s390_expand_cmpstr (target, op0, op1, len)
{
if (INTVAL (len) > 0)
{
- emit_insn ((*gen_short) (op0, op1, GEN_INT (INTVAL (len) - 1)));
- emit_insn ((*gen_result) (target));
+ emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
+ emit_insn (gen_result (target));
}
else
emit_move_insn (target, const0_rtx);
@@ -2855,21 +3090,8 @@ s390_expand_cmpstr (target, op0, op1, len)
else /* if (TARGET_MVCLE) */
{
- enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
- enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
- rtx reg0 = gen_reg_rtx (double_mode);
- rtx reg1 = gen_reg_rtx (double_mode);
-
- emit_move_insn (gen_highpart (single_mode, reg0),
- force_operand (XEXP (op0, 0), NULL_RTX));
- emit_move_insn (gen_highpart (single_mode, reg1),
- force_operand (XEXP (op1, 0), NULL_RTX));
-
- convert_move (gen_lowpart (single_mode, reg0), len, 1);
- convert_move (gen_lowpart (single_mode, reg1), len, 1);
-
- emit_insn ((*gen_long) (reg0, reg1, reg0, reg1));
- emit_insn ((*gen_result) (target));
+ emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
+ emit_insn (gen_result (target));
}
#if 0
@@ -2884,9 +3106,9 @@ s390_expand_cmpstr (target, op0, op1, len)
mode = GET_MODE (len);
if (mode == VOIDmode)
- mode = word_mode;
+ mode = Pmode;
- type = (*lang_hooks.types.type_for_mode) (mode, 1);
+ type = lang_hooks.types.type_for_mode (mode, 1);
if (!type)
abort ();
@@ -2896,14 +3118,14 @@ s390_expand_cmpstr (target, op0, op1, len)
blocks = gen_reg_rtx (mode);
convert_move (count, len, 1);
- emit_cmp_and_jump_insns (count, const0_rtx,
+ emit_cmp_and_jump_insns (count, const0_rtx,
EQ, NULL_RTX, mode, 1, end_label);
emit_move_insn (addr0, force_operand (XEXP (op0, 0), NULL_RTX));
emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
op0 = change_address (op0, VOIDmode, addr0);
op1 = change_address (op1, VOIDmode, addr1);
-
+
temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0);
if (temp != count)
emit_move_insn (count, temp);
@@ -2917,39 +3139,60 @@ s390_expand_cmpstr (target, op0, op1, len)
make_tree (type, blocks),
make_tree (type, const0_rtx)));
- emit_insn ((*gen_short) (op0, op1, GEN_INT (255)));
+ emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
- temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
+ temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
emit_jump_insn (temp);
- s390_load_address (addr0,
+ s390_load_address (addr0,
gen_rtx_PLUS (Pmode, addr0, GEN_INT (256)));
- s390_load_address (addr1,
+ s390_load_address (addr1,
gen_rtx_PLUS (Pmode, addr1, GEN_INT (256)));
-
+
temp = expand_binop (mode, add_optab, blocks, constm1_rtx, blocks, 1, 0);
if (temp != blocks)
emit_move_insn (blocks, temp);
expand_end_loop ();
- emit_insn ((*gen_short) (op0, op1, convert_to_mode (word_mode, count, 1)));
+ emit_insn (gen_cmpmem_short (op0, op1,
+ convert_to_mode (Pmode, count, 1)));
emit_label (end_label);
- emit_insn ((*gen_result) (target));
+ emit_insn (gen_result (target));
}
#endif
}
+/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
+ We need to emit DTP-relative relocations. */
+
+void
+s390_output_dwarf_dtprel (FILE *file, int size, rtx x)
+{
+ switch (size)
+ {
+ case 4:
+ fputs ("\t.long\t", file);
+ break;
+ case 8:
+ fputs ("\t.quad\t", file);
+ break;
+ default:
+ abort ();
+ }
+ output_addr_const (file, x);
+ fputs ("@DTPOFF", file);
+}
+
/* In the name of slightly smaller debug output, and to cater to
general assembler losage, recognize various UNSPEC sequences
and turn them back into a direct symbol reference. */
-rtx
-s390_simplify_dwarf_addr (orig_x)
- rtx orig_x;
+static rtx
+s390_delegitimize_address (rtx orig_x)
{
rtx x = orig_x, y;
@@ -2964,7 +3207,7 @@ s390_simplify_dwarf_addr (orig_x)
{
y = XEXP (XEXP (x, 1), 0);
if (GET_CODE (y) == UNSPEC
- && XINT (y, 1) == 110)
+ && XINT (y, 1) == UNSPEC_GOT)
return XVECEXP (y, 0, 0);
return orig_x;
}
@@ -2973,19 +3216,53 @@ s390_simplify_dwarf_addr (orig_x)
{
y = XEXP (x, 0);
if (GET_CODE (y) == UNSPEC
- && XINT (y, 1) == 111)
+ && XINT (y, 1) == UNSPEC_GOTENT)
return XVECEXP (y, 0, 0);
return orig_x;
}
- return orig_x;
+ return orig_x;
+}
+
+/* Output shift count operand OP to stdio stream FILE. */
+
+static void
+print_shift_count_operand (FILE *file, rtx op)
+{
+ HOST_WIDE_INT offset = 0;
+
+ /* We can have an integer constant, an address register,
+ or a sum of the two. */
+ if (GET_CODE (op) == CONST_INT)
+ {
+ offset = INTVAL (op);
+ op = NULL_RTX;
+ }
+ if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+ {
+ offset = INTVAL (XEXP (op, 1));
+ op = XEXP (op, 0);
+ }
+ while (op && GET_CODE (op) == SUBREG)
+ op = SUBREG_REG (op);
+
+ /* Sanity check. */
+ if (op && (GET_CODE (op) != REG
+ || REGNO (op) >= FIRST_PSEUDO_REGISTER
+ || REGNO_REG_CLASS (REGNO (op)) != ADDR_REGS))
+ abort ();
+
+ /* Shift counts are truncated to the low six bits anyway. */
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & 63);
+ if (op)
+ fprintf (file, "(%s)", reg_names[REGNO (op)]);
}
/* Locate some local-dynamic symbol still in use by this function
so that we can print its name in local-dynamic base patterns. */
static const char *
-get_some_local_dynamic_name ()
+get_some_local_dynamic_name (void)
{
rtx insn;
@@ -3001,9 +3278,7 @@ get_some_local_dynamic_name ()
}
static int
-get_some_local_dynamic_name_1 (px, data)
- rtx *px;
- void *data ATTRIBUTE_UNUSED;
+get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
{
rtx x = *px;
@@ -3023,13 +3298,11 @@ get_some_local_dynamic_name_1 (px, data)
return 0;
}
-/* Output symbolic constant X in assembler syntax to
+/* Output symbolic constant X in assembler syntax to
stdio stream FILE. */
void
-s390_output_symbolic_const (file, x)
- FILE *file;
- rtx x;
+s390_output_symbolic_const (FILE *file, rtx x)
{
switch (GET_CODE (x))
{
@@ -3063,37 +3336,25 @@ s390_output_symbolic_const (file, x)
output_operand_lossage ("invalid UNSPEC as operand (1)");
switch (XINT (x, 1))
{
- case 100:
- case 104:
- s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- fprintf (file, "-");
- s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
- break;
- case 105:
- s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
- fprintf (file, "-");
- s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- break;
- case 110:
- s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- fprintf (file, "@GOT12");
- break;
- case 111:
+ case UNSPEC_GOTENT:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@GOTENT");
break;
- case 112:
+ case UNSPEC_GOT:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@GOT");
break;
- case 113:
+ case UNSPEC_GOTOFF:
+ s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
+ fprintf (file, "@GOTOFF");
+ break;
+ case UNSPEC_PLT:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
fprintf (file, "@PLT");
break;
- case 114:
+ case UNSPEC_PLTOFF:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
- fprintf (file, "@PLT-");
- s390_output_symbolic_const (file, cfun->machine->literal_pool_label);
+ fprintf (file, "@PLTOFF");
break;
case UNSPEC_TLSGD:
s390_output_symbolic_const (file, XVECEXP (x, 0, 0));
@@ -3131,13 +3392,11 @@ s390_output_symbolic_const (file, x)
}
}
-/* Output address operand ADDR in assembler syntax to
+/* Output address operand ADDR in assembler syntax to
stdio stream FILE. */
void
-print_operand_address (file, addr)
- FILE *file;
- rtx addr;
+print_operand_address (FILE *file, rtx addr)
{
struct s390_address ad;
@@ -3145,7 +3404,7 @@ print_operand_address (file, addr)
|| (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
|| (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
output_operand_lossage ("Cannot decompose address.");
-
+
if (ad.disp)
s390_output_symbolic_const (file, ad.disp);
else
@@ -3158,8 +3417,8 @@ print_operand_address (file, addr)
fprintf (file, "(%s)", reg_names[REGNO (ad.base)]);
}
-/* Output operand X in assembler syntax to stdio stream FILE.
- CODE specified the format flag. The following format flags
+/* Output operand X in assembler syntax to stdio stream FILE.
+ CODE specified the format flag. The following format flags
are recognized:
'C': print opcode suffix for branch condition.
@@ -3169,16 +3428,16 @@ print_operand_address (file, addr)
'R': print only the base register of a memory reference.
'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.
'x': print integer X as if it's an unsigned word.
- 'h': print integer X as if it's a signed word. */
+ 'h': print integer X as if it's a signed word.
+ 'i': print the first nonzero HImode part of X.
+ 'j': print the first HImode part unequal to 0xffff of X. */
void
-print_operand (file, x, code)
- FILE *file;
- rtx x;
- int code;
+print_operand (FILE *file, rtx x, int code)
{
switch (code)
{
@@ -3261,6 +3520,10 @@ print_operand (file, x, code)
else
abort ();
break;
+
+ case 'Y':
+ print_shift_count_operand (file, x);
+ return;
}
switch (GET_CODE (x))
@@ -3287,6 +3550,12 @@ print_operand (file, x, code)
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff);
else if (code == 'h')
fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xffff) ^ 0x8000) - 0x8000);
+ else if (code == 'i')
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC,
+ s390_extract_part (x, HImode, 0));
+ else if (code == 'j')
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC,
+ s390_extract_part (x, HImode, -1));
else
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
break;
@@ -3315,44 +3584,35 @@ print_operand (file, x, code)
handle values smaller than INT_MIN when printed in decimal. */
static bool
-s390_assemble_integer (x, size, aligned_p)
- rtx x;
- unsigned int size;
- int aligned_p;
+s390_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
if (size == 8 && aligned_p
&& GET_CODE (x) == CONST_INT && INTVAL (x) < INT_MIN)
{
- fputs ("\t.quad\t", asm_out_file);
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
- putc ('\n', asm_out_file);
+ fprintf (asm_out_file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n",
+ INTVAL (x));
return true;
}
return default_assemble_integer (x, size, aligned_p);
}
-
-#define DEBUG_SCHED 0
-
-/* Returns true if register REGNO is used for forming
+/* Returns true if register REGNO is used for forming
a memory address in expression X. */
static int
-reg_used_in_mem_p (regno, x)
- int regno;
- rtx x;
+reg_used_in_mem_p (int regno, rtx x)
{
enum rtx_code code = GET_CODE (x);
int i, j;
const char *fmt;
-
+
if (code == MEM)
{
if (refers_to_regno_p (regno, regno+1,
XEXP (x, 0), 0))
return 1;
}
- else if (code == SET
+ else if (code == SET
&& GET_CODE (SET_DEST (x)) == PC)
{
if (refers_to_regno_p (regno, regno+1,
@@ -3366,7 +3626,7 @@ reg_used_in_mem_p (regno, x)
if (fmt[i] == 'e'
&& reg_used_in_mem_p (regno, XEXP (x, i)))
return 1;
-
+
else if (fmt[i] == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
if (reg_used_in_mem_p (regno, XVECEXP (x, i, j)))
@@ -3378,13 +3638,14 @@ reg_used_in_mem_p (regno, x)
/* Returns true if expression DEP_RTX sets an address register
used by instruction INSN to address memory. */
-static int
-addr_generation_dependency_p (dep_rtx, insn)
- rtx dep_rtx;
- rtx insn;
+static int
+addr_generation_dependency_p (rtx dep_rtx, rtx insn)
{
rtx target, pat;
+ if (GET_CODE (dep_rtx) == INSN)
+ dep_rtx = PATTERN (dep_rtx);
+
if (GET_CODE (dep_rtx) == SET)
{
target = SET_DEST (dep_rtx);
@@ -3397,7 +3658,7 @@ addr_generation_dependency_p (dep_rtx, insn)
{
int regno = REGNO (target);
- if (get_attr_type (insn) == TYPE_LA)
+ if (s390_safe_attr_type (insn) == TYPE_LA)
{
pat = PATTERN (insn);
if (GET_CODE (pat) == PARALLEL)
@@ -3411,31 +3672,48 @@ addr_generation_dependency_p (dep_rtx, insn)
else
abort();
}
- else if (get_attr_atype (insn) == ATYPE_MEM)
+ else if (get_attr_atype (insn) == ATYPE_AGEN)
return reg_used_in_mem_p (regno, PATTERN (insn));
}
}
return 0;
}
+/* Return 1, if dep_insn sets register used in insn in the agen unit. */
+
+int
+s390_agen_dep_p (rtx dep_insn, rtx insn)
+{
+ rtx dep_rtx = PATTERN (dep_insn);
+ int i;
+
+ if (GET_CODE (dep_rtx) == SET
+ && addr_generation_dependency_p (dep_rtx, insn))
+ return 1;
+ else if (GET_CODE (dep_rtx) == PARALLEL)
+ {
+ for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
+ {
+ if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
+ return 1;
+ }
+ }
+ return 0;
+}
/* Return the modified cost of the dependency of instruction INSN
- on instruction DEP_INSN through the link LINK. COST is the
+ on instruction DEP_INSN through the link LINK. COST is the
default cost of that dependency.
Data dependencies are all handled without delay. However, if a
- register is modified and subsequently used as base or index
+ register is modified and subsequently used as base or index
register of a memory reference, at least 4 cycles need to pass
- between setting and using the register to avoid pipeline stalls.
+ between setting and using the register to avoid pipeline stalls.
An exception is the LA instruction. An address generated by LA can
be used by introducing only a one cycle stall on the pipeline. */
static int
-s390_adjust_cost (insn, link, dep_insn, cost)
- rtx insn;
- rtx link;
- rtx dep_insn;
- int cost;
+s390_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
rtx dep_rtx;
int i;
@@ -3451,100 +3729,117 @@ s390_adjust_cost (insn, link, dep_insn, cost)
if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
return cost;
+ /* DFA based scheduling checks address dependency in md file. */
+ if (s390_use_dfa_pipeline_interface ())
+ {
+ /* Operand forward in case of lr, load and la. */
+ if (s390_tune == PROCESSOR_2084_Z990
+ && cost == 1
+ && (s390_safe_attr_type (dep_insn) == TYPE_LA
+ || s390_safe_attr_type (dep_insn) == TYPE_LR
+ || s390_safe_attr_type (dep_insn) == TYPE_LOAD))
+ return 0;
+ return cost;
+ }
+
dep_rtx = PATTERN (dep_insn);
- if (GET_CODE (dep_rtx) == SET)
- {
- if (addr_generation_dependency_p (dep_rtx, insn))
- {
- cost += (get_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
- if (DEBUG_SCHED)
- {
- fprintf (stderr, "\n\nAddress dependency detected: cost %d\n",
- cost);
- debug_rtx (dep_insn);
- debug_rtx (insn);
- }
- }
- }
+ if (GET_CODE (dep_rtx) == SET
+ && addr_generation_dependency_p (dep_rtx, insn))
+ cost += (s390_safe_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
else if (GET_CODE (dep_rtx) == PARALLEL)
{
for (i = 0; i < XVECLEN (dep_rtx, 0); i++)
{
- if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i),
- insn))
- {
- cost += (get_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
- if (DEBUG_SCHED)
- {
- fprintf (stderr, "\n\nAddress dependency detected: cost %d\n"
- ,cost);
- debug_rtx (dep_insn);
- debug_rtx (insn);
- }
- }
+ if (addr_generation_dependency_p (XVECEXP (dep_rtx, 0, i), insn))
+ cost += (s390_safe_attr_type (dep_insn) == TYPE_LA) ? 1 : 4;
}
}
return cost;
}
-
-
/* A C statement (sans semicolon) to update the integer scheduling priority
- INSN_PRIORITY (INSN). Reduce the priority to execute the INSN earlier,
- increase the priority to execute INSN later. Do not define this macro if
- you do not need to adjust the scheduling priorities of insns.
+ INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier,
+ reduce the priority to execute INSN later. Do not define this macro if
+ you do not need to adjust the scheduling priorities of insns.
- A LA instruction maybe scheduled later, since the pipeline bypasses the
- calculated value. */
+ A STD instruction should be scheduled earlier,
+ in order to use the bypass. */
static int
-s390_adjust_priority (insn, priority)
- rtx insn ATTRIBUTE_UNUSED;
- int priority;
+s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
{
if (! INSN_P (insn))
return priority;
- if (GET_CODE (PATTERN (insn)) == USE
- || GET_CODE (PATTERN (insn)) == CLOBBER)
+ if (s390_tune != PROCESSOR_2084_Z990)
return priority;
-
- switch (get_attr_type (insn))
+
+ switch (s390_safe_attr_type (insn))
{
- default:
- break;
-
- case TYPE_LA:
- if (priority >= 0 && priority < 0x01000000)
- priority <<= 3;
- break;
- case TYPE_LM:
- /* LM in epilogue should never be scheduled. This
- is due to literal access done in function body.
- The usage of register 13 is not mentioned explicitly,
- leading to scheduling 'LM' accross this instructions.
- */
- priority = 0x7fffffff;
- break;
+ case TYPE_FSTORED:
+ case TYPE_FSTORES:
+ priority = priority << 3;
+ break;
+ case TYPE_STORE:
+ priority = priority << 1;
+ break;
+ default:
+ break;
}
-
return priority;
}
+/* The number of instructions that can be issued per cycle. */
+
+static int
+s390_issue_rate (void)
+{
+ if (s390_tune == PROCESSOR_2084_Z990)
+ return 3;
+ return 1;
+}
+
+/* If the following function returns TRUE, we will use the the DFA
+ insn scheduler. */
+
+static int
+s390_use_dfa_pipeline_interface (void)
+{
+ if (s390_tune == PROCESSOR_2064_Z900
+ || s390_tune == PROCESSOR_2084_Z990)
+ return 1;
+
+ return 0;
+}
+
+static int
+s390_first_cycle_multipass_dfa_lookahead (void)
+{
+ return s390_use_dfa_pipeline_interface () ? 4 : 0;
+}
+
+/* Called after issuing each insn.
+ Triggers default sort algorithm to better slot instructions. */
+
+static int
+s390_sched_reorder2 (FILE *dump ATTRIBUTE_UNUSED,
+ int sched_verbose ATTRIBUTE_UNUSED,
+ rtx *ready ATTRIBUTE_UNUSED,
+ int *pn_ready ATTRIBUTE_UNUSED,
+ int clock_var ATTRIBUTE_UNUSED)
+{
+ return s390_issue_rate();
+}
-/* Split all branches that exceed the maximum distance.
- Returns true if this created a new literal pool entry.
- Code generated by this routine is allowed to use
- TEMP_REG as temporary scratch register. If this is
- done, TEMP_USED is set to true. */
+/* Split all branches that exceed the maximum distance.
+ Returns true if this created a new literal pool entry. */
-static int
-s390_split_branches (temp_reg, temp_used)
- rtx temp_reg;
- bool *temp_used;
+static int
+s390_split_branches (void)
{
+ rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
int new_literal = 0;
rtx insn, pat, tmp, target;
rtx *label;
@@ -3566,15 +3861,15 @@ s390_split_branches (temp_reg, temp_used)
if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
continue;
- if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
+ if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
{
label = &SET_SRC (pat);
- }
- else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
+ }
+ else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
{
- if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
+ if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
label = &XEXP (SET_SRC (pat), 1);
- else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
+ else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
label = &XEXP (SET_SRC (pat), 2);
else
continue;
@@ -3582,19 +3877,14 @@ s390_split_branches (temp_reg, temp_used)
else
continue;
- if (get_attr_length (insn) <= (TARGET_64BIT ? 6 : 4))
+ if (get_attr_length (insn) <= 4)
continue;
- *temp_used = 1;
-
- if (TARGET_64BIT)
- {
- tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, *label), insn);
- INSN_ADDRESSES_NEW (tmp, -1);
+ /* We are going to use the return register as scratch register,
+ make sure it will be saved/restored by the prologue/epilogue. */
+ cfun->machine->save_return_addr_p = 1;
- target = temp_reg;
- }
- else if (!flag_pic)
+ if (!flag_pic)
{
new_literal = 1;
tmp = force_const_mem (Pmode, *label);
@@ -3606,14 +3896,16 @@ s390_split_branches (temp_reg, temp_used)
else
{
new_literal = 1;
- tmp = gen_rtx_UNSPEC (SImode, gen_rtvec (1, *label), 104);
- tmp = gen_rtx_CONST (SImode, tmp);
- tmp = force_const_mem (SImode, tmp);
- tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
+ target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, *label),
+ UNSPEC_LTREL_OFFSET);
+ target = gen_rtx_CONST (Pmode, target);
+ target = force_const_mem (Pmode, target);
+ tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
INSN_ADDRESSES_NEW (tmp, -1);
- target = gen_rtx_REG (Pmode, BASE_REGISTER);
- target = gen_rtx_PLUS (Pmode, target, temp_reg);
+ target = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (target, 0)),
+ UNSPEC_LTREL_BASE);
+ target = gen_rtx_PLUS (Pmode, temp_reg, target);
}
if (!validate_change (insn, label, target, 0))
@@ -3624,22 +3916,29 @@ s390_split_branches (temp_reg, temp_used)
}
-/* Find a literal pool symbol referenced in RTX X, and store
- it at REF. Will abort if X contains references to more than
+/* Find a 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.
+ are allowed, however.
- The rtx pointed to by REF must be initialized to NULL_RTX
+ The rtx pointed to by REF must be initialized to NULL_RTX
by the caller before calling this routine. */
static void
-find_constant_pool_ref (x, ref)
- rtx x;
- rtx *ref;
+find_constant_pool_ref (rtx x, rtx *ref)
{
int i, j;
const char *fmt;
+ /* Ignore LTREL_BASE references. */
+ if (GET_CODE (x) == UNSPEC
+ && XINT (x, 1) == UNSPEC_LTREL_BASE)
+ return;
+ /* Likewise POOL_ENTRY insns. */
+ if (GET_CODE (x) == UNSPEC_VOLATILE
+ && XINT (x, 1) == UNSPECV_POOL_ENTRY)
+ return;
+
if (GET_CODE (x) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x))
{
@@ -3668,10 +3967,7 @@ find_constant_pool_ref (x, ref)
in X by the address ADDR. Fix up MEMs as required. */
static void
-replace_constant_pool_ref (x, ref, addr)
- rtx *x;
- rtx ref;
- rtx addr;
+replace_constant_pool_ref (rtx *x, rtx ref, rtx addr)
{
int i, j;
const char *fmt;
@@ -3738,135 +4034,55 @@ replace_constant_pool_ref (x, ref, addr)
}
}
-/* Check whether ADDR is an address that uses the base register,
- without actually constituting a literal pool access. (This happens
- in 31-bit PIC mode, where the base register is used as anchor for
- relative addressing of local symbols.)
-
- Returns 1 if the base register occupies the base slot,
- returns 2 if the base register occupies the index slot,
- returns 0 if the address is not of this form. */
-
-static int
-find_base_register_in_addr (addr)
- struct s390_address *addr;
-{
- /* If DISP is complex, we might have a literal pool reference. */
- if (addr->disp && GET_CODE (addr->disp) != CONST_INT)
- return 0;
-
- if (addr->base && REG_P (addr->base) && REGNO (addr->base) == BASE_REGISTER)
- return 1;
-
- if (addr->indx && REG_P (addr->indx) && REGNO (addr->indx) == BASE_REGISTER)
- return 2;
+/* Check whether X contains an UNSPEC_LTREL_BASE.
+ Return its constant pool symbol if found, NULL_RTX otherwise. */
- return 0;
-}
-
-/* Return true if X contains an address that uses the base register,
- without actually constituting a literal pool access. */
-
-static bool
-find_base_register_ref (x)
- rtx x;
+static rtx
+find_ltrel_base (rtx x)
{
- bool retv = FALSE;
- struct s390_address addr;
int i, j;
const char *fmt;
- /* Addresses can only occur inside a MEM ... */
- if (GET_CODE (x) == MEM)
- {
- if (s390_decompose_address (XEXP (x, 0), &addr)
- && find_base_register_in_addr (&addr))
- return TRUE;
- }
-
- /* ... or a load-address type pattern. */
- if (GET_CODE (x) == SET && GET_CODE (SET_DEST (x)) == REG)
- {
- if (s390_decompose_address (SET_SRC (x), &addr)
- && find_base_register_in_addr (&addr))
- return TRUE;
- }
+ if (GET_CODE (x) == UNSPEC
+ && XINT (x, 1) == UNSPEC_LTREL_BASE)
+ return XVECEXP (x, 0, 0);
fmt = GET_RTX_FORMAT (GET_CODE (x));
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
{
- retv |= find_base_register_ref (XEXP (x, i));
+ rtx fnd = find_ltrel_base (XEXP (x, i));
+ if (fnd)
+ return fnd;
}
else if (fmt[i] == 'E')
{
for (j = 0; j < XVECLEN (x, i); j++)
- retv |= find_base_register_ref (XVECEXP (x, i, j));
+ {
+ rtx fnd = find_ltrel_base (XVECEXP (x, i, j));
+ if (fnd)
+ return fnd;
+ }
}
}
- return retv;
+ return NULL_RTX;
}
-/* If X contains an address that uses the base register,
- without actually constituting a literal pool access,
- replace the base register with REPL in all such cases.
-
- Handles both MEMs and load address patterns. */
+/* Replace any occurrence of UNSPEC_LTREL_BASE in X with BASE. */
static void
-replace_base_register_ref (x, repl)
- rtx *x;
- rtx repl;
+replace_ltrel_base (rtx *x, rtx base)
{
- struct s390_address addr;
- rtx new_addr;
- int i, j, pos;
+ int i, j;
const char *fmt;
- /* Addresses can only occur inside a MEM ... */
- if (GET_CODE (*x) == MEM)
- {
- if (s390_decompose_address (XEXP (*x, 0), &addr)
- && (pos = find_base_register_in_addr (&addr)))
- {
- if (pos == 1)
- addr.base = repl;
- else
- addr.indx = repl;
-
- new_addr = addr.base;
- if (addr.indx)
- new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.indx);
- if (addr.disp)
- new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.disp);
-
- *x = replace_equiv_address (*x, new_addr);
- return;
- }
- }
-
- /* ... or a load-address type pattern. */
- if (GET_CODE (*x) == SET && GET_CODE (SET_DEST (*x)) == REG)
+ if (GET_CODE (*x) == UNSPEC
+ && XINT (*x, 1) == UNSPEC_LTREL_BASE)
{
- if (s390_decompose_address (SET_SRC (*x), &addr)
- && (pos = find_base_register_in_addr (&addr)))
- {
- if (pos == 1)
- addr.base = repl;
- else
- addr.indx = repl;
-
- new_addr = addr.base;
- if (addr.indx)
- new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.indx);
- if (addr.disp)
- new_addr = gen_rtx_PLUS (Pmode, new_addr, addr.disp);
-
- SET_SRC (*x) = new_addr;
- return;
- }
+ *x = base;
+ return;
}
fmt = GET_RTX_FORMAT (GET_CODE (*x));
@@ -3874,37 +4090,30 @@ replace_base_register_ref (x, repl)
{
if (fmt[i] == 'e')
{
- replace_base_register_ref (&XEXP (*x, i), repl);
+ replace_ltrel_base (&XEXP (*x, i), base);
}
else if (fmt[i] == 'E')
{
for (j = 0; j < XVECLEN (*x, i); j++)
- replace_base_register_ref (&XVECEXP (*x, i, j), repl);
+ replace_ltrel_base (&XVECEXP (*x, i, j), base);
}
}
}
-/* We keep a list of constants we which we have to add to internal
+/* We keep a list of constants which we have to add to internal
constant tables in the middle of large functions. */
-#define NR_C_MODES 6
-enum machine_mode constant_modes[NR_C_MODES] =
+#define NR_C_MODES 7
+enum machine_mode constant_modes[NR_C_MODES] =
{
+ TImode,
DFmode, DImode,
SFmode, SImode,
HImode,
QImode
};
-rtx (*gen_consttable[NR_C_MODES])(rtx) =
-{
- gen_consttable_df, gen_consttable_di,
- gen_consttable_sf, gen_consttable_si,
- gen_consttable_hi,
- gen_consttable_qi
-};
-
struct constant
{
struct constant *next;
@@ -3922,45 +4131,36 @@ struct constant_pool
struct constant *constants[NR_C_MODES];
rtx label;
int size;
- bool anchor;
};
-static struct constant_pool * s390_chunkify_start PARAMS ((rtx, bool *));
-static void s390_chunkify_finish PARAMS ((struct constant_pool *, rtx));
-static void s390_chunkify_cancel PARAMS ((struct constant_pool *));
+static struct constant_pool * s390_mainpool_start (void);
+static void s390_mainpool_finish (struct constant_pool *, rtx base_reg);
+static void s390_mainpool_cancel (struct constant_pool *);
+
+static struct constant_pool * s390_chunkify_start (rtx base_reg);
+static void s390_chunkify_finish (struct constant_pool *, rtx base_reg);
+static void s390_chunkify_cancel (struct constant_pool *);
-static struct constant_pool *s390_start_pool PARAMS ((struct constant_pool **, rtx));
-static void s390_end_pool PARAMS ((struct constant_pool *, rtx));
-static void s390_add_pool_insn PARAMS ((struct constant_pool *, rtx));
-static struct constant_pool *s390_find_pool PARAMS ((struct constant_pool *, rtx));
-static void s390_add_constant PARAMS ((struct constant_pool *, rtx, enum machine_mode));
-static rtx s390_find_constant PARAMS ((struct constant_pool *, rtx, enum machine_mode));
-static void s390_add_anchor PARAMS ((struct constant_pool *));
-static rtx s390_dump_pool PARAMS ((struct constant_pool *));
-static void s390_free_pool PARAMS ((struct constant_pool *));
+static struct constant_pool *s390_start_pool (struct constant_pool **, rtx);
+static void s390_end_pool (struct constant_pool *, rtx);
+static void s390_add_pool_insn (struct constant_pool *, rtx);
+static struct constant_pool *s390_find_pool (struct constant_pool *, rtx);
+static void s390_add_constant (struct constant_pool *, rtx, enum machine_mode);
+static rtx s390_find_constant (struct constant_pool *, rtx, enum machine_mode);
+static rtx s390_dump_pool (struct constant_pool *, bool);
+static struct constant_pool *s390_alloc_pool (void);
+static void s390_free_pool (struct constant_pool *);
/* Create new constant pool covering instructions starting at INSN
and chain it to the end of POOL_LIST. */
static struct constant_pool *
-s390_start_pool (pool_list, insn)
- struct constant_pool **pool_list;
- rtx insn;
+s390_start_pool (struct constant_pool **pool_list, rtx insn)
{
struct constant_pool *pool, **prev;
- int i;
- pool = (struct constant_pool *) xmalloc (sizeof *pool);
- pool->next = NULL;
- for (i = 0; i < NR_C_MODES; i++)
- pool->constants[i] = NULL;
-
- pool->label = gen_label_rtx ();
+ pool = s390_alloc_pool ();
pool->first_insn = insn;
- pool->pool_insn = NULL_RTX;
- pool->insns = BITMAP_XMALLOC ();
- pool->size = 0;
- pool->anchor = FALSE;
for (prev = pool_list; *prev; prev = &(*prev)->next)
;
@@ -3973,9 +4173,7 @@ s390_start_pool (pool_list, insn)
placeholder insn representing the pool. */
static void
-s390_end_pool (pool, insn)
- struct constant_pool *pool;
- rtx insn;
+s390_end_pool (struct constant_pool *pool, rtx insn)
{
rtx pool_size = GEN_INT (pool->size + 8 /* alignment slop */);
@@ -3989,9 +4187,7 @@ s390_end_pool (pool, insn)
/* Add INSN to the list of insns covered by POOL. */
static void
-s390_add_pool_insn (pool, insn)
- struct constant_pool *pool;
- rtx insn;
+s390_add_pool_insn (struct constant_pool *pool, rtx insn)
{
bitmap_set_bit (pool->insns, INSN_UID (insn));
}
@@ -3999,9 +4195,7 @@ s390_add_pool_insn (pool, insn)
/* Return pool out of POOL_LIST that covers INSN. */
static struct constant_pool *
-s390_find_pool (pool_list, insn)
- struct constant_pool *pool_list;
- rtx insn;
+s390_find_pool (struct constant_pool *pool_list, rtx insn)
{
struct constant_pool *pool;
@@ -4015,10 +4209,7 @@ s390_find_pool (pool_list, insn)
/* Add constant VAL of mode MODE to the constant pool POOL. */
static void
-s390_add_constant (pool, val, mode)
- struct constant_pool *pool;
- rtx val;
- enum machine_mode mode;
+s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
{
struct constant *c;
int i;
@@ -4047,77 +4238,55 @@ s390_add_constant (pool, val, mode)
/* Find constant VAL of mode MODE in the constant pool POOL.
Return an RTX describing the distance from the start of
the pool to the location of the new constant. */
-
+
static rtx
-s390_find_constant (pool, val, mode)
- struct constant_pool *pool;
- rtx val;
- enum machine_mode mode;
+s390_find_constant (struct constant_pool *pool, rtx val,
+ enum machine_mode mode)
{
struct constant *c;
rtx offset;
int i;
-
+
for (i = 0; i < NR_C_MODES; i++)
if (constant_modes[i] == mode)
break;
if (i == NR_C_MODES)
abort ();
-
+
for (c = pool->constants[i]; c != NULL; c = c->next)
if (rtx_equal_p (val, c->value))
break;
-
+
if (c == NULL)
abort ();
-
+
offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
gen_rtx_LABEL_REF (Pmode, pool->label));
offset = gen_rtx_CONST (Pmode, offset);
return offset;
}
-/* Set 'anchor' flag in POOL. */
-
-static void
-s390_add_anchor (pool)
- struct constant_pool *pool;
-{
- if (!pool->anchor)
- {
- pool->anchor = TRUE;
- pool->size += 4;
- }
-}
-
-/* Dump out the constants in POOL. */
+/* Dump out the constants in POOL. If REMOTE_LABEL is true,
+ do not emit the pool base label. */
static rtx
-s390_dump_pool (pool)
- struct constant_pool *pool;
+s390_dump_pool (struct constant_pool *pool, bool remote_label)
{
struct constant *c;
rtx insn;
int i;
- /* Pool start insn switches to proper section
+ /* Pool start insn switches to proper section
and guarantees necessary alignment. */
- if (TARGET_64BIT)
+ if (TARGET_CPU_ZARCH)
insn = emit_insn_after (gen_pool_start_64 (), pool->pool_insn);
else
insn = emit_insn_after (gen_pool_start_31 (), pool->pool_insn);
INSN_ADDRESSES_NEW (insn, -1);
- insn = emit_label_after (pool->label, insn);
- INSN_ADDRESSES_NEW (insn, -1);
-
- /* Emit anchor if we need one. */
- if (pool->anchor)
+ if (!remote_label)
{
- rtx anchor = gen_rtx_LABEL_REF (VOIDmode, pool->label);
- anchor = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, anchor), 105);
- anchor = gen_rtx_CONST (VOIDmode, anchor);
- insn = emit_insn_after (gen_consttable_si (anchor), insn);
+ insn = emit_label_after (pool->label, insn);
INSN_ADDRESSES_NEW (insn, -1);
}
@@ -4126,27 +4295,31 @@ s390_dump_pool (pool)
for (i = 0; i < NR_C_MODES; i++)
for (c = pool->constants[i]; c; c = c->next)
{
- /* Convert 104 unspecs to pool-relative references. */
+ /* Convert UNSPEC_LTREL_OFFSET unspecs to pool-relative references. */
rtx value = c->value;
if (GET_CODE (value) == CONST
&& GET_CODE (XEXP (value, 0)) == UNSPEC
- && XINT (XEXP (value, 0), 1) == 104
+ && XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
&& XVECLEN (XEXP (value, 0), 0) == 1)
{
value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
- gen_rtx_LABEL_REF (VOIDmode, pool->label));
+ gen_rtx_LABEL_REF (VOIDmode, pool->label));
value = gen_rtx_CONST (VOIDmode, value);
}
insn = emit_label_after (c->label, insn);
INSN_ADDRESSES_NEW (insn, -1);
- insn = emit_insn_after (gen_consttable[i] (value), insn);
+
+ value = gen_rtx_UNSPEC_VOLATILE (constant_modes[i],
+ gen_rtvec (1, value),
+ UNSPECV_POOL_ENTRY);
+ insn = emit_insn_after (value, insn);
INSN_ADDRESSES_NEW (insn, -1);
}
- /* Pool end insn switches back to previous section
+ /* Pool end insn switches back to previous section
and guarantees necessary alignment. */
- if (TARGET_64BIT)
+ if (TARGET_CPU_ZARCH)
insn = emit_insn_after (gen_pool_end_64 (), insn);
else
insn = emit_insn_after (gen_pool_end_31 (), insn);
@@ -4161,11 +4334,32 @@ s390_dump_pool (pool)
return insn;
}
+/* Allocate new constant_pool structure. */
+
+static struct constant_pool *
+s390_alloc_pool (void)
+{
+ struct constant_pool *pool;
+ int i;
+
+ pool = (struct constant_pool *) xmalloc (sizeof *pool);
+ pool->next = NULL;
+ for (i = 0; i < NR_C_MODES; i++)
+ pool->constants[i] = NULL;
+
+ pool->label = gen_label_rtx ();
+ pool->first_insn = NULL_RTX;
+ pool->pool_insn = NULL_RTX;
+ pool->insns = BITMAP_XMALLOC ();
+ pool->size = 0;
+
+ return pool;
+}
+
/* Free all memory used by POOL. */
static void
-s390_free_pool (pool)
- struct constant_pool *pool;
+s390_free_pool (struct constant_pool *pool)
{
int i;
@@ -4182,90 +4376,263 @@ s390_free_pool (pool)
BITMAP_XFREE (pool->insns);
free (pool);
-}
+}
+
+
+/* Collect main literal pool. Return NULL on overflow. */
+
+static struct constant_pool *
+s390_mainpool_start (void)
+{
+ struct constant_pool *pool;
+ rtx insn;
+
+ pool = s390_alloc_pool ();
+
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == INSN
+ && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE
+ && XINT (PATTERN (insn), 1) == UNSPECV_MAIN_POOL)
+ {
+ if (pool->pool_insn)
+ abort ();
+ pool->pool_insn = insn;
+ }
+
+ if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
+ {
+ rtx pool_ref = NULL_RTX;
+ find_constant_pool_ref (PATTERN (insn), &pool_ref);
+ if (pool_ref)
+ {
+ rtx constant = get_pool_constant (pool_ref);
+ enum machine_mode mode = get_pool_mode (pool_ref);
+ s390_add_constant (pool, constant, mode);
+ }
+ }
+ }
+
+ if (!pool->pool_insn)
+ abort ();
+
+ if (pool->size >= 4096)
+ {
+ /* We're going to chunkify the pool, so remove the main
+ pool placeholder insn. */
+ remove_insn (pool->pool_insn);
+
+ s390_free_pool (pool);
+ pool = NULL;
+ }
+
+ return pool;
+}
+
+/* POOL holds the main literal pool as collected by s390_mainpool_start.
+ Modify the current function to output the pool constants as well as
+ the pool register setup instruction. BASE_REG is the register to
+ be used as pool base register. */
+
+static void
+s390_mainpool_finish (struct constant_pool *pool, rtx base_reg)
+{
+ rtx insn;
+
+ /* If the pool is empty, we're done. */
+ if (pool->size == 0)
+ {
+ remove_insn (pool->pool_insn);
+ s390_free_pool (pool);
+ return;
+ }
+
+ /* We need correct insn addresses. */
+ shorten_branches (get_insns ());
+
+ /* On zSeries, we use a LARL to load the pool register. The pool is
+ located in the .rodata section, so we emit it after the function. */
+ if (TARGET_CPU_ZARCH)
+ {
+ insn = gen_main_base_64 (base_reg, pool->label);
+ insn = emit_insn_after (insn, pool->pool_insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+ remove_insn (pool->pool_insn);
+
+ insn = get_last_insn ();
+ pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
+ INSN_ADDRESSES_NEW (pool->pool_insn, -1);
+
+ s390_dump_pool (pool, 0);
+ }
+
+ /* On S/390, if the total size of the function's code plus literal pool
+ does not exceed 4096 bytes, we use BASR to set up a function base
+ pointer, and emit the literal pool at the end of the function. */
+ else if (INSN_ADDRESSES (INSN_UID (get_last_insn ()))
+ + pool->size + 8 /* alignment slop */ < 4096)
+ {
+ insn = gen_main_base_31_small (base_reg, pool->label);
+ insn = emit_insn_after (insn, pool->pool_insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+ remove_insn (pool->pool_insn);
+
+ insn = emit_label_after (pool->label, insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+
+ insn = get_last_insn ();
+ pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
+ INSN_ADDRESSES_NEW (pool->pool_insn, -1);
+
+ s390_dump_pool (pool, 1);
+ }
+
+ /* Otherwise, we emit an inline literal pool and use BASR to branch
+ over it, setting up the pool register at the same time. */
+ else
+ {
+ rtx pool_end = gen_label_rtx ();
+
+ insn = gen_main_base_31_large (base_reg, pool->label, pool_end);
+ insn = emit_insn_after (insn, pool->pool_insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+ remove_insn (pool->pool_insn);
+
+ insn = emit_label_after (pool->label, insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+
+ pool->pool_insn = emit_insn_after (gen_pool (const0_rtx), insn);
+ INSN_ADDRESSES_NEW (pool->pool_insn, -1);
+
+ insn = emit_label_after (pool_end, pool->pool_insn);
+ INSN_ADDRESSES_NEW (insn, -1);
+
+ s390_dump_pool (pool, 1);
+ }
+
+
+ /* Replace all literal pool references. */
+
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
+ replace_ltrel_base (&PATTERN (insn), base_reg);
+
+ if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
+ {
+ rtx addr, pool_ref = NULL_RTX;
+ find_constant_pool_ref (PATTERN (insn), &pool_ref);
+ if (pool_ref)
+ {
+ addr = s390_find_constant (pool, get_pool_constant (pool_ref),
+ get_pool_mode (pool_ref));
+ addr = gen_rtx_PLUS (Pmode, base_reg, addr);
+ replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
+ INSN_CODE (insn) = -1;
+ }
+ }
+ }
-/* Chunkify the literal pool if required.
+ /* Free the pool. */
+ s390_free_pool (pool);
+}
+
+/* POOL holds the main literal pool as collected by s390_mainpool_start.
+ We have decided we cannot use this pool, so revert all changes
+ to the current function that were done by s390_mainpool_start. */
+static void
+s390_mainpool_cancel (struct constant_pool *pool)
+{
+ /* We didn't actually change the instruction stream, so simply
+ free the pool memory. */
+ s390_free_pool (pool);
+}
- Code generated by this routine is allowed to use
- TEMP_REG as temporary scratch register. If this is
- done, TEMP_USED is set to true. */
+
+/* Chunkify the literal pool. BASE_REG is to be used as pool
+ register. */
#define S390_POOL_CHUNK_MIN 0xc00
#define S390_POOL_CHUNK_MAX 0xe00
-static struct constant_pool *
-s390_chunkify_start (temp_reg, temp_used)
- rtx temp_reg;
- bool *temp_used;
+static struct constant_pool *
+s390_chunkify_start (rtx base_reg)
{
- rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
-
struct constant_pool *curr_pool = NULL, *pool_list = NULL;
int extra_size = 0;
bitmap far_labels;
+ rtx pending_ltrel = NULL_RTX;
rtx insn;
- rtx (*gen_reload_base) PARAMS ((rtx, rtx)) =
- TARGET_64BIT? gen_reload_base_64 : gen_reload_base_31;
-
+ rtx (*gen_reload_base) (rtx, rtx) =
+ TARGET_CPU_ZARCH? gen_reload_base_64 : gen_reload_base_31;
- /* Do we need to chunkify the literal pool? */
-
- if (get_pool_size () < S390_POOL_CHUNK_MAX)
- return NULL;
/* We need correct insn addresses. */
shorten_branches (get_insns ());
- /* Scan all insns and move literals to pool chunks.
- Also, emit anchor reload insns before every insn that uses
- the literal pool base register as anchor pointer. */
+ /* Scan all insns and move literals to pool chunks. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
+ /* Check for pending LTREL_BASE. */
+ if (INSN_P (insn))
+ {
+ rtx ltrel_base = find_ltrel_base (PATTERN (insn));
+ if (ltrel_base)
+ {
+ if (ltrel_base == pending_ltrel)
+ pending_ltrel = NULL_RTX;
+ else
+ abort ();
+ }
+ }
+
if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
{
rtx pool_ref = NULL_RTX;
find_constant_pool_ref (PATTERN (insn), &pool_ref);
if (pool_ref)
{
+ rtx constant = get_pool_constant (pool_ref);
+ enum machine_mode mode = get_pool_mode (pool_ref);
+
if (!curr_pool)
curr_pool = s390_start_pool (&pool_list, insn);
- s390_add_constant (curr_pool, get_pool_constant (pool_ref),
- get_pool_mode (pool_ref));
+ s390_add_constant (curr_pool, constant, mode);
s390_add_pool_insn (curr_pool, insn);
- }
- else if (!TARGET_64BIT && flag_pic
- && find_base_register_ref (PATTERN (insn)))
- {
- rtx new = gen_reload_anchor (temp_reg, base_reg);
- new = emit_insn_before (new, insn);
- INSN_ADDRESSES_NEW (new, INSN_ADDRESSES (INSN_UID (insn)));
- extra_size += 8;
- *temp_used = 1;
-
- if (!curr_pool)
- curr_pool = s390_start_pool (&pool_list, new);
-
- s390_add_anchor (curr_pool);
- s390_add_pool_insn (curr_pool, insn);
+ /* Don't split the pool chunk between a LTREL_OFFSET load
+ and the corresponding LTREL_BASE. */
+ if (GET_CODE (constant) == CONST
+ && GET_CODE (XEXP (constant, 0)) == UNSPEC
+ && XINT (XEXP (constant, 0), 1) == UNSPEC_LTREL_OFFSET)
+ {
+ if (pending_ltrel)
+ abort ();
+ pending_ltrel = pool_ref;
+ }
}
}
if (GET_CODE (insn) == JUMP_INSN || GET_CODE (insn) == CODE_LABEL)
- if (curr_pool)
- s390_add_pool_insn (curr_pool, insn);
+ {
+ if (curr_pool)
+ s390_add_pool_insn (curr_pool, insn);
+ /* An LTREL_BASE must follow within the same basic block. */
+ if (pending_ltrel)
+ abort ();
+ }
- if (!curr_pool
+ if (!curr_pool
|| INSN_ADDRESSES_SIZE () <= (size_t) INSN_UID (insn)
|| INSN_ADDRESSES (INSN_UID (insn)) == -1)
continue;
- if (TARGET_64BIT)
+ if (TARGET_CPU_ZARCH)
{
if (curr_pool->size < S390_POOL_CHUNK_MAX)
continue;
@@ -4276,7 +4643,7 @@ s390_chunkify_start (temp_reg, temp_used)
else
{
int chunk_size = INSN_ADDRESSES (INSN_UID (insn))
- - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
+ - INSN_ADDRESSES (INSN_UID (curr_pool->first_insn))
+ extra_size;
/* We will later have to insert base register reload insns.
@@ -4310,13 +4677,12 @@ s390_chunkify_start (temp_reg, temp_used)
if (get_attr_length (insn) == 0)
continue;
- /* Don't separate insns created by s390_split_branches. */
- if (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) == SET
- && rtx_equal_p (SET_DEST (PATTERN (insn)), temp_reg))
+ /* Don't separate LTREL_BASE from the corresponding
+ LTREL_OFFSET load. */
+ if (pending_ltrel)
continue;
- label = gen_label_rtx ();
+ label = gen_label_rtx ();
jump = emit_jump_insn_after (gen_jump (label), insn);
barrier = emit_barrier_after (jump);
insn = emit_label_after (label, barrier);
@@ -4336,9 +4702,11 @@ s390_chunkify_start (temp_reg, temp_used)
if (curr_pool)
s390_end_pool (curr_pool, NULL_RTX);
+ if (pending_ltrel)
+ abort ();
- /* Find all labels that are branched into
+ /* Find all labels that are branched into
from an insn belonging to a different chunk. */
far_labels = BITMAP_XMALLOC ();
@@ -4352,11 +4720,11 @@ s390_chunkify_start (temp_reg, temp_used)
Don't do that, however, if it is the label before
a jump table. */
- if (GET_CODE (insn) == CODE_LABEL
+ if (GET_CODE (insn) == CODE_LABEL
&& (LABEL_PRESERVE_P (insn) || LABEL_NAME (insn)))
{
rtx vec_insn = next_real_insn (insn);
- rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
+ rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
PATTERN (vec_insn) : NULL_RTX;
if (!vec_pat
|| !(GET_CODE (vec_pat) == ADDR_VEC
@@ -4366,22 +4734,22 @@ s390_chunkify_start (temp_reg, temp_used)
/* If we have a direct jump (conditional or unconditional)
or a casesi jump, check all potential targets. */
- else if (GET_CODE (insn) == JUMP_INSN)
+ else if (GET_CODE (insn) == JUMP_INSN)
{
rtx pat = PATTERN (insn);
if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
pat = XVECEXP (pat, 0, 0);
- if (GET_CODE (pat) == SET)
+ if (GET_CODE (pat) == SET)
{
rtx label = JUMP_LABEL (insn);
if (label)
{
- if (s390_find_pool (pool_list, label)
+ if (s390_find_pool (pool_list, label)
!= s390_find_pool (pool_list, insn))
bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
}
- }
+ }
else if (GET_CODE (pat) == PARALLEL
&& XVECLEN (pat, 0) == 2
&& GET_CODE (XVECEXP (pat, 0, 0)) == SET
@@ -4391,7 +4759,7 @@ s390_chunkify_start (temp_reg, temp_used)
/* Find the jump table used by this casesi jump. */
rtx vec_label = XEXP (XEXP (XVECEXP (pat, 0, 1), 0), 0);
rtx vec_insn = next_real_insn (vec_label);
- rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
+ rtx vec_pat = vec_insn && GET_CODE (vec_insn) == JUMP_INSN ?
PATTERN (vec_insn) : NULL_RTX;
if (vec_pat
&& (GET_CODE (vec_pat) == ADDR_VEC
@@ -4403,7 +4771,7 @@ s390_chunkify_start (temp_reg, temp_used)
{
rtx label = XEXP (XVECEXP (vec_pat, diff_p, i), 0);
- if (s390_find_pool (pool_list, label)
+ if (s390_find_pool (pool_list, label)
!= s390_find_pool (pool_list, insn))
bitmap_set_bit (far_labels, CODE_LABEL_NUMBER (label));
}
@@ -4424,7 +4792,7 @@ s390_chunkify_start (temp_reg, temp_used)
/* Insert base register reload insns at every far label. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == CODE_LABEL
+ if (GET_CODE (insn) == CODE_LABEL
&& bitmap_bit_p (far_labels, CODE_LABEL_NUMBER (insn)))
{
struct constant_pool *pool = s390_find_pool (pool_list, insn);
@@ -4448,26 +4816,24 @@ s390_chunkify_start (temp_reg, temp_used)
}
/* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
- After we have decided to use this list, finish implementing
- all changes to the current function as required.
+ After we have decided to use this list, finish implementing
+ all changes to the current function as required. BASE_REG is
+ to be used as pool base register. */
- Code generated by this routine is allowed to use
- TEMP_REG as temporary scratch register. */
-
static void
-s390_chunkify_finish (pool_list, temp_reg)
- struct constant_pool *pool_list;
- rtx temp_reg;
+s390_chunkify_finish (struct constant_pool *pool_list, rtx base_reg)
{
- rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
struct constant_pool *curr_pool = NULL;
rtx insn;
-
-
+
+
/* Replace all literal pool references. */
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
+ if (INSN_P (insn))
+ replace_ltrel_base (&PATTERN (insn), base_reg);
+
curr_pool = s390_find_pool (pool_list, insn);
if (!curr_pool)
continue;
@@ -4484,20 +4850,14 @@ s390_chunkify_finish (pool_list, temp_reg)
replace_constant_pool_ref (&PATTERN (insn), pool_ref, addr);
INSN_CODE (insn) = -1;
}
-
- else if (!TARGET_64BIT && flag_pic
- && find_base_register_ref (PATTERN (insn)))
- {
- replace_base_register_ref (&PATTERN (insn), temp_reg);
- }
}
}
/* Dump out all literal pools. */
-
+
for (curr_pool = pool_list; curr_pool; curr_pool = curr_pool->next)
- s390_dump_pool (curr_pool);
-
+ s390_dump_pool (curr_pool, 0);
+
/* Free pool list. */
while (pool_list)
@@ -4511,10 +4871,9 @@ s390_chunkify_finish (pool_list, temp_reg)
/* POOL_LIST is a chunk list as prepared by s390_chunkify_start.
We have decided we cannot use this list, so revert all changes
to the current function that were done by s390_chunkify_start. */
-
+
static void
-s390_chunkify_cancel (pool_list)
- struct constant_pool *pool_list;
+s390_chunkify_cancel (struct constant_pool *pool_list)
{
struct constant_pool *curr_pool = NULL;
rtx insn;
@@ -4544,7 +4903,7 @@ s390_chunkify_cancel (pool_list)
remove_insn (curr_pool->pool_insn);
}
- /* Remove all base/anchor register reload insns. */
+ /* Remove all base register reload insns. */
for (insn = get_insns (); insn; )
{
@@ -4553,8 +4912,7 @@ s390_chunkify_cancel (pool_list)
if (GET_CODE (insn) == INSN
&& GET_CODE (PATTERN (insn)) == SET
&& GET_CODE (SET_SRC (PATTERN (insn))) == UNSPEC
- && (XINT (SET_SRC (PATTERN (insn)), 1) == 210
- || XINT (SET_SRC (PATTERN (insn)), 1) == 211))
+ && XINT (SET_SRC (PATTERN (insn)), 1) == UNSPEC_RELOAD_BASE)
remove_insn (insn);
insn = next_insn;
@@ -4571,98 +4929,80 @@ s390_chunkify_cancel (pool_list)
}
-/* Index of constant pool chunk that is currently being processed.
- Set to -1 before function output has started. */
-int s390_pool_count = -1;
-
-/* Number of elements of current constant pool. */
-int s390_nr_constants;
-
-/* Output main constant pool to stdio stream FILE. */
+/* Output to FILE the constant pool entry EXP in mode MODE
+ with alignment ALIGN. */
void
-s390_output_constant_pool (start_label, end_label)
- rtx start_label;
- rtx end_label;
+s390_output_pool_entry (FILE *file, rtx exp, enum machine_mode mode,
+ unsigned int align)
{
- if (TARGET_64BIT)
- {
- readonly_data_section ();
- ASM_OUTPUT_ALIGN (asm_out_file, 3);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
- CODE_LABEL_NUMBER (start_label));
- }
- else
- {
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
- CODE_LABEL_NUMBER (start_label));
- ASM_OUTPUT_ALIGN (asm_out_file, 2);
- }
+ REAL_VALUE_TYPE r;
- s390_pool_count = 0;
- output_constant_pool (current_function_name, current_function_decl);
- s390_pool_count = -1;
- if (TARGET_64BIT)
- function_section (current_function_decl);
- else
+ switch (GET_MODE_CLASS (mode))
{
- ASM_OUTPUT_ALIGN (asm_out_file, 1);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (end_label));
+ case MODE_FLOAT:
+ if (GET_CODE (exp) != CONST_DOUBLE)
+ abort ();
+
+ REAL_VALUE_FROM_CONST_DOUBLE (r, exp);
+ assemble_real (r, mode, align);
+ break;
+
+ case MODE_INT:
+ if (GET_CODE (exp) == CONST
+ || GET_CODE (exp) == SYMBOL_REF
+ || GET_CODE (exp) == LABEL_REF)
+ {
+ fputs (integer_asm_op (GET_MODE_SIZE (mode), TRUE), file);
+ s390_output_symbolic_const (file, exp);
+ fputc ('\n', file);
+ }
+ else
+ {
+ assemble_integer (exp, GET_MODE_SIZE (mode), align, 1);
+ }
+ break;
+
+ default:
+ abort ();
}
}
+
/* Rework the prolog/epilog to avoid saving/restoring
- registers unnecessarily. If TEMP_REGNO is nonnegative,
- it specifies the number of a caller-saved register used
- as temporary scratch register by code emitted during
- machine dependent reorg. */
+ registers unnecessarily. BASE_USED specifies whether
+ the literal pool base register needs to be saved. */
static void
-s390_optimize_prolog (temp_regno)
- int temp_regno;
+s390_optimize_prolog (bool base_used)
{
int save_first, save_last, restore_first, restore_last;
int i, j;
rtx insn, new_insn, next_insn;
/* Recompute regs_ever_live data for special registers. */
- regs_ever_live[BASE_REGISTER] = 0;
- regs_ever_live[RETURN_REGNUM] = 0;
+ regs_ever_live[BASE_REGISTER] = base_used;
+ regs_ever_live[RETURN_REGNUM] = cfun->machine->save_return_addr_p;
regs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
- /* If there is (possibly) any pool entry, we need to
- load the base register.
- ??? FIXME: this should be more precise. */
- if (get_pool_size ())
- regs_ever_live[BASE_REGISTER] = 1;
-
- /* In non-leaf functions, the prolog/epilog code relies
- on RETURN_REGNUM being saved in any case. */
- if (!current_function_is_leaf)
- regs_ever_live[RETURN_REGNUM] = 1;
-
- /* We need to save/restore the temporary register. */
- if (temp_regno >= 0)
- regs_ever_live[temp_regno] = 1;
-
/* Find first and last gpr to be saved. */
-
+
for (i = 6; i < 16; i++)
if (regs_ever_live[i])
if (!global_regs[i]
- || i == STACK_POINTER_REGNUM
+ || i == STACK_POINTER_REGNUM
|| i == RETURN_REGNUM
- || i == BASE_REGISTER
+ || i == BASE_REGISTER
|| (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
break;
for (j = 15; j > i; j--)
if (regs_ever_live[j])
if (!global_regs[j]
- || j == STACK_POINTER_REGNUM
+ || j == STACK_POINTER_REGNUM
|| j == RETURN_REGNUM
- || j == BASE_REGISTER
+ || j == BASE_REGISTER
|| (flag_pic && j == (int)PIC_OFFSET_TABLE_REGNUM))
break;
@@ -4691,7 +5031,7 @@ s390_optimize_prolog (temp_regno)
/* If all special registers are in fact used, there's nothing we
can do, so no point in walking the insn list. */
if (i <= BASE_REGISTER && j >= BASE_REGISTER
- && i <= RETURN_REGNUM && j >= RETURN_REGNUM)
+ && (TARGET_CPU_ZARCH || (i <= RETURN_REGNUM && j >= RETURN_REGNUM)))
return;
@@ -4706,10 +5046,9 @@ s390_optimize_prolog (temp_regno)
if (GET_CODE (insn) != INSN)
continue;
- if (GET_CODE (PATTERN (insn)) != PARALLEL)
- continue;
- if (store_multiple_operation (PATTERN (insn), VOIDmode))
+ if (GET_CODE (PATTERN (insn)) == PARALLEL
+ && store_multiple_operation (PATTERN (insn), VOIDmode))
{
set = XVECEXP (PATTERN (insn), 0, 0);
first = REGNO (SET_SRC (set));
@@ -4720,9 +5059,31 @@ s390_optimize_prolog (temp_regno)
if (GET_CODE (base) != REG || off < 0)
continue;
- if (first > BASE_REGISTER && first > RETURN_REGNUM)
+ if (first > BASE_REGISTER || last < BASE_REGISTER)
continue;
- if (last < BASE_REGISTER && last < RETURN_REGNUM)
+
+ if (save_first != -1)
+ {
+ new_insn = save_gprs (base, off, save_first, save_last);
+ new_insn = emit_insn_before (new_insn, insn);
+ INSN_ADDRESSES_NEW (new_insn, -1);
+ }
+
+ remove_insn (insn);
+ continue;
+ }
+
+ if (GET_CODE (PATTERN (insn)) == SET
+ && GET_CODE (SET_SRC (PATTERN (insn))) == REG
+ && REGNO (SET_SRC (PATTERN (insn))) == BASE_REGISTER
+ && GET_CODE (SET_DEST (PATTERN (insn))) == MEM)
+ {
+ set = PATTERN (insn);
+ offset = const0_rtx;
+ base = eliminate_constant_term (XEXP (SET_DEST (set), 0), &offset);
+ off = INTVAL (offset) - BASE_REGISTER * UNITS_PER_WORD;
+
+ if (GET_CODE (base) != REG || off < 0)
continue;
if (save_first != -1)
@@ -4733,9 +5094,11 @@ s390_optimize_prolog (temp_regno)
}
remove_insn (insn);
+ continue;
}
- if (load_multiple_operation (PATTERN (insn), VOIDmode))
+ if (GET_CODE (PATTERN (insn)) == PARALLEL
+ && load_multiple_operation (PATTERN (insn), VOIDmode))
{
set = XVECEXP (PATTERN (insn), 0, 0);
first = REGNO (SET_DEST (set));
@@ -4746,9 +5109,7 @@ s390_optimize_prolog (temp_regno)
if (GET_CODE (base) != REG || off < 0)
continue;
- if (first > BASE_REGISTER && first > RETURN_REGNUM)
- continue;
- if (last < BASE_REGISTER && last < RETURN_REGNUM)
+ if (first > BASE_REGISTER || last < BASE_REGISTER)
continue;
if (restore_first != -1)
@@ -4759,103 +5120,80 @@ s390_optimize_prolog (temp_regno)
}
remove_insn (insn);
+ continue;
}
- }
-}
-
-/* Check whether any insn in the function makes use of the original
- value of RETURN_REG (e.g. for __builtin_return_address).
- If so, insert an insn reloading that value.
-
- Return true if any such insn was found. */
-
-static bool
-s390_fixup_clobbered_return_reg (return_reg)
- rtx return_reg;
-{
- bool replacement_done = 0;
- rtx insn;
-
- /* If we never called __builtin_return_address, register 14
- might have been used as temp during the prolog; we do
- not want to touch those uses. */
- if (!has_hard_reg_initial_val (Pmode, REGNO (return_reg)))
- return false;
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- {
- rtx reg, off, new_insn;
+ if (GET_CODE (PATTERN (insn)) == SET
+ && GET_CODE (SET_DEST (PATTERN (insn))) == REG
+ && REGNO (SET_DEST (PATTERN (insn))) == BASE_REGISTER
+ && GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
+ {
+ set = PATTERN (insn);
+ offset = const0_rtx;
+ base = eliminate_constant_term (XEXP (SET_SRC (set), 0), &offset);
+ off = INTVAL (offset) - BASE_REGISTER * UNITS_PER_WORD;
- if (GET_CODE (insn) != INSN)
- continue;
- if (!reg_referenced_p (return_reg, PATTERN (insn)))
- continue;
- if (GET_CODE (PATTERN (insn)) == PARALLEL
- && store_multiple_operation (PATTERN (insn), VOIDmode))
- continue;
+ if (GET_CODE (base) != REG || off < 0)
+ continue;
- if (frame_pointer_needed)
- reg = hard_frame_pointer_rtx;
- else
- reg = stack_pointer_rtx;
+ if (restore_first != -1)
+ {
+ new_insn = restore_gprs (base, off, restore_first, restore_last);
+ new_insn = emit_insn_before (new_insn, insn);
+ INSN_ADDRESSES_NEW (new_insn, -1);
+ }
- off = GEN_INT (cfun->machine->frame_size + REGNO (return_reg) * UNITS_PER_WORD);
- if (INTVAL (off) >= 4096)
- {
- off = force_const_mem (Pmode, off);
- new_insn = gen_rtx_SET (Pmode, return_reg, off);
- new_insn = emit_insn_before (new_insn, insn);
- INSN_ADDRESSES_NEW (new_insn, -1);
- off = return_reg;
+ remove_insn (insn);
+ continue;
}
-
- new_insn = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, reg, off));
- new_insn = gen_rtx_SET (Pmode, return_reg, new_insn);
- new_insn = emit_insn_before (new_insn, insn);
- INSN_ADDRESSES_NEW (new_insn, -1);
-
- replacement_done = 1;
}
-
- return replacement_done;
}
/* Perform machine-dependent processing. */
-void
-s390_machine_dependent_reorg (first)
- rtx first ATTRIBUTE_UNUSED;
+static void
+s390_reorg (void)
{
- bool fixed_up_clobbered_return_reg = 0;
- rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
- bool temp_used = 0;
+ rtx base_reg = gen_rtx_REG (Pmode, BASE_REGISTER);
+ bool base_used = false;
+ bool pool_overflow = false;
/* Make sure all splits have been performed; splits after
machine_dependent_reorg might confuse insn length counts. */
split_all_insns_noflow ();
- /* There are two problematic situations we need to correct:
-
+ /* In small leaf functions, try to use an unused call-clobbered
+ register as base register to avoid save/restore overhead. */
+ if (current_function_is_leaf && !regs_ever_live[5])
+ base_reg = gen_rtx_REG (Pmode, 5);
+
+
+ /* Install the main literal pool and the associated base
+ register load insns.
+
+ In addition, there are two problematic situations we need
+ to correct:
+
- the literal pool might be > 4096 bytes in size, so that
some of its elements cannot be directly accessed
-
+
- a branch target might be > 64K away from the branch, so that
it is not possible to use a PC-relative instruction.
-
+
To fix those, we split the single literal pool into multiple
pool chunks, reloading the pool base register at various
points throughout the function to ensure it always points to
the pool chunk the following code expects, and / or replace
PC-relative branches by absolute branches.
-
+
However, the two problems are interdependent: splitting the
literal pool can move a branch further away from its target,
causing the 64K limit to overflow, and on the other hand,
replacing a PC-relative branch by an absolute branch means
we need to put the branch target address into the literal
pool, possibly causing it to overflow.
-
+
So, we loop trying to fix up both problems until we manage
to satisfy both conditions at the same time. Note that the
loop is guaranteed to terminate as every pass of the loop
@@ -4863,49 +5201,52 @@ s390_machine_dependent_reorg (first)
in the function. (This is not completely true as there
might be branch-over-pool insns introduced by chunkify_start.
Those never need to be split however.) */
-
+
for (;;)
{
- struct constant_pool *pool_list;
-
- /* Try to chunkify the literal pool. */
- pool_list = s390_chunkify_start (temp_reg, &temp_used);
+ struct constant_pool *pool = NULL;
+
+ /* Collect the literal pool. */
+ if (!pool_overflow)
+ {
+ pool = s390_mainpool_start ();
+ if (!pool)
+ pool_overflow = true;
+ }
+
+ /* If literal pool overflowed, start to chunkify it. */
+ if (pool_overflow)
+ pool = s390_chunkify_start (base_reg);
/* Split out-of-range branches. If this has created new
literal pool entries, cancel current chunk list and
- recompute it. */
- if (s390_split_branches (temp_reg, &temp_used))
+ recompute it. zSeries machines have large branch
+ instructions, so we never need to split a branch. */
+ if (!TARGET_CPU_ZARCH && s390_split_branches ())
{
- if (pool_list)
- s390_chunkify_cancel (pool_list);
-
+ if (pool_overflow)
+ s390_chunkify_cancel (pool);
+ else
+ s390_mainpool_cancel (pool);
+
continue;
}
- /* Check whether we have clobbered a use of the return
- register (e.g. for __builtin_return_address). If so,
- add insns reloading the register where necessary. */
- if (temp_used && !fixed_up_clobbered_return_reg
- && s390_fixup_clobbered_return_reg (temp_reg))
- {
- fixed_up_clobbered_return_reg = 1;
+ /* If we made it up to here, both conditions are satisfied.
+ Finish up literal pool related changes. */
+ if ((pool_overflow || pool->size > 0)
+ && REGNO (base_reg) == BASE_REGISTER)
+ base_used = true;
- /* The fixup insns might have caused a jump to overflow. */
- if (pool_list)
- s390_chunkify_cancel (pool_list);
+ if (pool_overflow)
+ s390_chunkify_finish (pool, base_reg);
+ else
+ s390_mainpool_finish (pool, base_reg);
- continue;
- }
-
- /* If we made it up to here, both conditions are satisfied.
- Finish up pool chunkification if required. */
- if (pool_list)
- s390_chunkify_finish (pool_list, temp_reg);
-
break;
}
-
- s390_optimize_prolog (temp_used? RETURN_REGNUM : -1);
+
+ s390_optimize_prolog (base_used);
}
@@ -4914,32 +5255,35 @@ s390_machine_dependent_reorg (first)
frame pointer of that frame. */
rtx
-s390_return_addr_rtx (count, frame)
- int count;
- rtx frame;
+s390_return_addr_rtx (int count, rtx frame)
{
rtx addr;
- /* For the current frame, we use the initial value of RETURN_REGNUM.
- This works both in leaf and non-leaf functions. */
+ /* Without backchain, we fail for all but the current frame. */
+
+ if (!TARGET_BACKCHAIN && count > 0)
+ return NULL_RTX;
+
+ /* For the current frame, we need to make sure the initial
+ value of RETURN_REGNUM is actually saved. */
if (count == 0)
- return get_hard_reg_initial_val (Pmode, RETURN_REGNUM);
+ cfun->machine->save_return_addr_p = true;
- /* For frames farther back, we read the stack slot where the
+ /* To retrieve the return address we read the stack slot where the
corresponding RETURN_REGNUM value was saved. */
addr = plus_constant (frame, RETURN_REGNUM * UNITS_PER_WORD);
addr = memory_address (Pmode, addr);
return gen_rtx_MEM (Pmode, addr);
-}
+}
/* Find first call clobbered register unsused in a function.
This could be used as base register in a leaf function
or for holding the return address before epilogue. */
static int
-find_unused_clobbered_reg ()
+find_unused_clobbered_reg (void)
{
int i;
for (i = 0; i < 6; i++)
@@ -4951,19 +5295,18 @@ find_unused_clobbered_reg ()
/* Fill FRAME with info about frame of current function. */
static void
-s390_frame_info ()
+s390_frame_info (void)
{
- char gprs_ever_live[16];
int i, j;
HOST_WIDE_INT fsize = get_frame_size ();
- if (fsize > 0x7fff0000)
+ if (!TARGET_64BIT && fsize > 0x7fff0000)
fatal_error ("Total size of local variables exceeds architecture limit.");
/* fprs 8 - 15 are caller saved for 64 Bit ABI. */
cfun->machine->save_fprs_p = 0;
if (TARGET_64BIT)
- for (i = 24; i < 32; i++)
+ for (i = 24; i < 32; i++)
if (regs_ever_live[i] && !global_regs[i])
{
cfun->machine->save_fprs_p = 1;
@@ -4973,38 +5316,49 @@ s390_frame_info ()
cfun->machine->frame_size = fsize + cfun->machine->save_fprs_p * 64;
/* Does function need to setup frame and save area. */
-
+
if (! current_function_is_leaf
|| cfun->machine->frame_size > 0
- || current_function_calls_alloca
+ || current_function_calls_alloca
|| current_function_stdarg)
cfun->machine->frame_size += STARTING_FRAME_OFFSET;
+ /* If we use the return register, we'll need to make sure
+ it is going to be saved/restored. */
+
+ if (!current_function_is_leaf
+ || regs_ever_live[RETURN_REGNUM])
+ cfun->machine->save_return_addr_p = 1;
+
/* Find first and last gpr to be saved. Note that at this point,
- we assume the return register and the base register always
- need to be saved. This is done because the usage of these
+ we assume the base register and -on S/390- the return register
+ always need to be saved. This is done because the usage of these
register might change even after the prolog was emitted.
If it turns out later that we really don't need them, the
prolog/epilog code is modified again. */
- for (i = 0; i < 16; i++)
- gprs_ever_live[i] = regs_ever_live[i] && !global_regs[i];
+ regs_ever_live[BASE_REGISTER] = 1;
+ if (!TARGET_CPU_ZARCH || cfun->machine->save_return_addr_p)
+ regs_ever_live[RETURN_REGNUM] = 1;
+ regs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
- if (flag_pic)
- gprs_ever_live[PIC_OFFSET_TABLE_REGNUM] =
- regs_ever_live[PIC_OFFSET_TABLE_REGNUM];
- gprs_ever_live[BASE_REGISTER] = 1;
- gprs_ever_live[RETURN_REGNUM] = 1;
- gprs_ever_live[STACK_POINTER_REGNUM] = cfun->machine->frame_size > 0;
-
for (i = 6; i < 16; i++)
- if (gprs_ever_live[i])
- break;
+ if (regs_ever_live[i])
+ if (!global_regs[i]
+ || i == STACK_POINTER_REGNUM
+ || i == RETURN_REGNUM
+ || i == BASE_REGISTER
+ || (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
+ break;
for (j = 15; j > i; j--)
- if (gprs_ever_live[j])
- break;
-
+ if (regs_ever_live[j])
+ if (!global_regs[j]
+ || j == STACK_POINTER_REGNUM
+ || j == RETURN_REGNUM
+ || j == BASE_REGISTER
+ || (flag_pic && j == (int)PIC_OFFSET_TABLE_REGNUM))
+ break;
/* Save / Restore from gpr i to j. */
cfun->machine->first_save_gpr = i;
@@ -5016,11 +5370,11 @@ s390_frame_info ()
cfun->machine->first_save_gpr = 2;
}
-/* Return offset between argument pointer and frame pointer
+/* Return offset between argument pointer and frame pointer
initially after prologue. */
-int
-s390_arg_frame_offset ()
+HOST_WIDE_INT
+s390_arg_frame_offset (void)
{
HOST_WIDE_INT fsize = get_frame_size ();
int save_fprs_p, i;
@@ -5028,7 +5382,7 @@ s390_arg_frame_offset ()
/* fprs 8 - 15 are caller saved for 64 Bit ABI. */
save_fprs_p = 0;
if (TARGET_64BIT)
- for (i = 24; i < 32; i++)
+ for (i = 24; i < 32; i++)
if (regs_ever_live[i] && !global_regs[i])
{
save_fprs_p = 1;
@@ -5038,23 +5392,20 @@ s390_arg_frame_offset ()
fsize = fsize + save_fprs_p * 64;
/* Does function need to setup frame and save area. */
-
+
if (! current_function_is_leaf
|| fsize > 0
- || current_function_calls_alloca
+ || current_function_calls_alloca
|| current_function_stdarg)
fsize += STARTING_FRAME_OFFSET;
return fsize + STACK_POINTER_OFFSET;
}
/* Emit insn to save fpr REGNUM at offset OFFSET relative
- to register BASE. Return generated insn. */
+ to register BASE. Return generated insn. */
static rtx
-save_fpr (base, offset, regnum)
- rtx base;
- int offset;
- int regnum;
+save_fpr (rtx base, int offset, int regnum)
{
rtx addr;
addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
@@ -5064,13 +5415,10 @@ save_fpr (base, offset, regnum)
}
/* Emit insn to restore fpr REGNUM from offset OFFSET relative
- to register BASE. Return generated insn. */
+ to register BASE. Return generated insn. */
static rtx
-restore_fpr (base, offset, regnum)
- rtx base;
- int offset;
- int regnum;
+restore_fpr (rtx base, int offset, int regnum)
{
rtx addr;
addr = gen_rtx_MEM (DFmode, plus_constant (base, offset));
@@ -5080,15 +5428,11 @@ restore_fpr (base, offset, regnum)
}
/* Generate insn to save registers FIRST to LAST into
- the register save area located at offset OFFSET
+ the register save area located at offset OFFSET
relative to register BASE. */
static rtx
-save_gprs (base, offset, first, last)
- rtx base;
- int offset;
- int first;
- int last;
+save_gprs (rtx base, int offset, int first, int last)
{
rtx addr, insn, note;
int i;
@@ -5119,7 +5463,7 @@ save_gprs (base, offset, first, last)
inside the store-multiple pattern.
However, we must not emit DWARF records for registers 2..5
- if they are stored for use by variable arguments ...
+ if they are stored for use by variable arguments ...
??? Unfortunately, it is not enough to simply not the the
FRAME_RELATED flags for those SETs, because the first SET
@@ -5140,13 +5484,13 @@ save_gprs (base, offset, first, last)
else if (last >= 6)
{
addr = plus_constant (base, offset + 6 * UNITS_PER_WORD);
- note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
+ note = gen_store_multiple (gen_rtx_MEM (Pmode, addr),
gen_rtx_REG (Pmode, 6),
GEN_INT (last - 6 + 1));
note = PATTERN (note);
REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
note, REG_NOTES (insn));
for (i = 0; i < XVECLEN (note, 0); i++)
@@ -5160,15 +5504,11 @@ save_gprs (base, offset, first, last)
}
/* Generate insn to restore registers FIRST to LAST from
- the register save area located at offset OFFSET
+ the register save area located at offset OFFSET
relative to register BASE. */
static rtx
-restore_gprs (base, offset, first, last)
- rtx base;
- int offset;
- int first;
- int last;
+restore_gprs (rtx base, int offset, int first, int last)
{
rtx addr, insn;
@@ -5193,82 +5533,98 @@ restore_gprs (base, offset, first, last)
return insn;
}
+/* Emit code to load the GOT register. If MAYBE_DEAD is true,
+ annotate generated insns with REG_MAYBE_DEAD notes. */
+
+static GTY(()) rtx got_symbol;
+void
+s390_load_got (int maybe_dead)
+{
+ if (!got_symbol)
+ {
+ got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+ SYMBOL_REF_FLAGS (got_symbol) = SYMBOL_FLAG_LOCAL;
+ }
+
+ if (TARGET_CPU_ZARCH)
+ {
+ rtx insn = emit_move_insn (pic_offset_table_rtx, got_symbol);
+ if (maybe_dead)
+ REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
+ REG_NOTES (insn));
+ }
+ else
+ {
+ rtx offset, insn;
+
+ offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol),
+ UNSPEC_LTREL_OFFSET);
+ offset = gen_rtx_CONST (Pmode, offset);
+ offset = force_const_mem (Pmode, offset);
+
+ insn = emit_move_insn (pic_offset_table_rtx, offset);
+ if (maybe_dead)
+ REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
+ REG_NOTES (insn));
+
+ offset = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (offset, 0)),
+ UNSPEC_LTREL_BASE);
+ offset = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, offset);
+
+ insn = emit_move_insn (pic_offset_table_rtx, offset);
+ if (maybe_dead)
+ REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
+ REG_NOTES (insn));
+ }
+}
+
/* Expand the prologue into a bunch of separate insns. */
void
-s390_emit_prologue ()
+s390_emit_prologue (void)
{
rtx insn, addr;
rtx temp_reg;
- rtx pool_start_label, pool_end_label;
int i;
/* Compute frame_info. */
s390_frame_info ();
- /* Choose best register to use for temp use within prologue. */
-
+ /* Choose best register to use for temp use within prologue.
+ See below for why TPF must use the register 1. */
+
if (!current_function_is_leaf
- && !has_hard_reg_initial_val (Pmode, RETURN_REGNUM)
- && get_pool_size () < S390_POOL_CHUNK_MAX / 2)
+ && !TARGET_TPF)
temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
else
temp_reg = gen_rtx_REG (Pmode, 1);
/* Save call saved gprs. */
- insn = save_gprs (stack_pointer_rtx, 0,
+ insn = save_gprs (stack_pointer_rtx, 0,
cfun->machine->first_save_gpr, cfun->machine->last_save_gpr);
emit_insn (insn);
- /* Dump constant pool and set constant pool register. */
+ /* Dummy insn to mark literal pool slot. */
+
+ emit_insn (gen_main_pool ());
- pool_start_label = gen_label_rtx();
- pool_end_label = gen_label_rtx();
- cfun->machine->literal_pool_label = pool_start_label;
-
- if (TARGET_64BIT)
- insn = emit_insn (gen_literal_pool_64 (gen_rtx_REG (Pmode, BASE_REGISTER),
- pool_start_label, pool_end_label));
- else
- insn = emit_insn (gen_literal_pool_31 (gen_rtx_REG (Pmode, BASE_REGISTER),
- pool_start_label, pool_end_label));
-
/* Save fprs for variable args. */
if (current_function_stdarg)
- {
- /* Save fpr 0 and 2. */
-
- save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 32, 16);
- save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 24, 17);
-
- if (TARGET_64BIT)
- {
- /* Save fpr 4 and 6. */
-
- save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 16, 18);
- save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 8, 19);
- }
- }
+ for (i = 16; i < (TARGET_64BIT ? 20 : 18); i++)
+ save_fpr (stack_pointer_rtx, 16*UNITS_PER_WORD + 8*(i-16), i);
/* Save fprs 4 and 6 if used (31 bit ABI). */
if (!TARGET_64BIT)
- {
- /* Save fpr 4 and 6. */
- if (regs_ever_live[18] && !global_regs[18])
- {
- insn = save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 16, 18);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
- if (regs_ever_live[19] && !global_regs[19])
+ for (i = 18; i < 20; i++)
+ if (regs_ever_live[i] && !global_regs[i])
{
- insn = save_fpr (stack_pointer_rtx, STACK_POINTER_OFFSET - 8, 19);
+ insn = save_fpr (stack_pointer_rtx, 16*UNITS_PER_WORD + 8*(i-16), i);
RTX_FRAME_RELATED_P (insn) = 1;
}
- }
/* Decrement stack pointer. */
@@ -5277,21 +5633,31 @@ s390_emit_prologue ()
rtx frame_off = GEN_INT (-cfun->machine->frame_size);
/* Save incoming stack pointer into temp reg. */
-
+
if (TARGET_BACKCHAIN || cfun->machine->save_fprs_p)
{
insn = emit_insn (gen_move_insn (temp_reg, stack_pointer_rtx));
}
-
- /* Substract frame size from stack pointer. */
- frame_off = GEN_INT (-cfun->machine->frame_size);
- if (!CONST_OK_FOR_LETTER_P (-cfun->machine->frame_size, 'K'))
- frame_off = force_const_mem (Pmode, frame_off);
+ /* Subtract frame size from stack pointer. */
+
+ if (DISP_IN_RANGE (INTVAL (frame_off)))
+ {
+ insn = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ frame_off));
+ insn = emit_insn (insn);
+ }
+ else
+ {
+ if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
+ frame_off = force_const_mem (Pmode, frame_off);
+
+ insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
+ }
- insn = emit_insn (gen_add2_insn (stack_pointer_rtx, frame_off));
RTX_FRAME_RELATED_P (insn) = 1;
- REG_NOTES (insn) =
+ REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
gen_rtx_SET (VOIDmode, stack_pointer_rtx,
gen_rtx_PLUS (Pmode, stack_pointer_rtx,
@@ -5299,7 +5665,7 @@ s390_emit_prologue ()
REG_NOTES (insn));
/* Set backchain. */
-
+
if (TARGET_BACKCHAIN)
{
addr = gen_rtx_MEM (Pmode, stack_pointer_rtx);
@@ -5319,7 +5685,7 @@ s390_emit_prologue ()
}
/* Save fprs 8 - 15 (64 bit ABI). */
-
+
if (cfun->machine->save_fprs_p)
{
insn = emit_insn (gen_add2_insn (temp_reg, GEN_INT(-64)));
@@ -5327,22 +5693,22 @@ s390_emit_prologue ()
for (i = 24; i < 32; i++)
if (regs_ever_live[i] && !global_regs[i])
{
- rtx addr = plus_constant (stack_pointer_rtx,
+ rtx addr = plus_constant (stack_pointer_rtx,
cfun->machine->frame_size - 64 + (i-24)*8);
insn = save_fpr (temp_reg, (i-24)*8, i);
RTX_FRAME_RELATED_P (insn) = 1;
- REG_NOTES (insn) =
+ REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
- gen_rtx_SET (VOIDmode,
+ gen_rtx_SET (VOIDmode,
gen_rtx_MEM (DFmode, addr),
gen_rtx_REG (DFmode, i)),
REG_NOTES (insn));
}
}
-
+
/* Set frame pointer, if needed. */
-
+
if (frame_pointer_needed)
{
insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
@@ -5350,54 +5716,70 @@ s390_emit_prologue ()
}
/* Set up got pointer, if needed. */
-
+
if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
+ s390_load_got(true);
+
+ if (TARGET_TPF)
{
- rtx got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
- SYMBOL_REF_FLAG (got_symbol) = 1;
+ /* Generate a BAS instruction to serve as a function
+ entry intercept to facilitate the use of tracing
+ algorithms located at the branch target.
- if (TARGET_64BIT)
- {
- insn = emit_insn (gen_movdi (pic_offset_table_rtx,
- got_symbol));
+ This must use register 1. */
+ rtx addr;
+ rtx unkn;
+ rtx link;
- /* It can happen that the GOT pointer isn't really needed ... */
- REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
- REG_NOTES (insn));
- }
- else
- {
- got_symbol = gen_rtx_UNSPEC (VOIDmode,
- gen_rtvec (1, got_symbol), 100);
- got_symbol = gen_rtx_CONST (VOIDmode, got_symbol);
- got_symbol = force_const_mem (Pmode, got_symbol);
- insn = emit_move_insn (pic_offset_table_rtx,
- got_symbol);
- REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
- REG_NOTES (insn));
-
- got_symbol = gen_rtx_REG (Pmode, BASE_REGISTER);
- got_symbol = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, got_symbol), 101);
- got_symbol = gen_rtx_PLUS (Pmode, got_symbol, pic_offset_table_rtx);
- insn = emit_move_insn (pic_offset_table_rtx, got_symbol);
- REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
- REG_NOTES (insn));
- }
- }
+ addr = GEN_INT (0xfe0);
+ unkn = CONST0_RTX (SImode);
+ link = gen_rtx_REG (Pmode, 1);
+
+ emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
+
+ /* Emit a blockage here so that all code
+ lies between the profiling mechanisms. */
+ emit_insn (gen_blockage ());
+ }
}
/* Expand the epilogue into a bunch of separate insns. */
void
-s390_emit_epilogue ()
+s390_emit_epilogue (void)
{
rtx frame_pointer, return_reg;
int area_bottom, area_top, offset = 0;
rtvec p;
+ int i;
+
+ if (TARGET_TPF)
+ {
+
+ /* Generate a BAS instruction to serve as a function
+ entry intercept to facilitate the use of tracing
+ algorithms located at the branch target.
+
+ This must use register 1. */
+
+ rtx addr;
+ rtx unkn;
+ rtx link;
+
+ addr = GEN_INT (0xfe6);
+ unkn = CONST0_RTX (SImode);
+ link = gen_rtx_REG (Pmode, 1);
+
+ /* Emit a blockage here so that all code
+ lies between the profiling mechanisms. */
+ emit_insn (gen_blockage ());
+
+ emit_call_insn (gen_call_exp (gen_rtx_MEM (QImode, addr), unkn, link));
+ }
/* 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;
/* Compute which parts of the save area we need to access. */
@@ -5425,31 +5807,25 @@ s390_emit_epilogue ()
}
else
{
- if (regs_ever_live[18] && !global_regs[18])
- {
- if (area_bottom > STACK_POINTER_OFFSET - 16)
- area_bottom = STACK_POINTER_OFFSET - 16;
- if (area_top < STACK_POINTER_OFFSET - 8)
- area_top = STACK_POINTER_OFFSET - 8;
- }
- if (regs_ever_live[19] && !global_regs[19])
- {
- if (area_bottom > STACK_POINTER_OFFSET - 8)
- area_bottom = STACK_POINTER_OFFSET - 8;
- if (area_top < STACK_POINTER_OFFSET)
- area_top = STACK_POINTER_OFFSET;
- }
+ for (i = 18; i < 20; i++)
+ if (regs_ever_live[i] && !global_regs[i])
+ {
+ if (area_bottom > 16*UNITS_PER_WORD + 8*(i-16))
+ area_bottom = 16*UNITS_PER_WORD + 8*(i-16);
+ if (area_top < 16*UNITS_PER_WORD + 8*(i-16) + 8)
+ area_top = 16*UNITS_PER_WORD + 8*(i-16) + 8;
+ }
}
- /* Check whether we can access the register save area.
+ /* Check whether we can access the register save area.
If not, increment the frame pointer as required. */
if (area_top <= area_bottom)
{
/* Nothing to restore. */
}
- else if (cfun->machine->frame_size + area_bottom >= 0
- && cfun->machine->frame_size + area_top <= 4096)
+ else if (DISP_IN_RANGE (cfun->machine->frame_size + area_bottom)
+ && DISP_IN_RANGE (cfun->machine->frame_size + area_top-1))
{
/* Area is in range. */
offset = cfun->machine->frame_size;
@@ -5458,38 +5834,45 @@ s390_emit_epilogue ()
{
rtx insn, frame_off;
- offset = area_bottom < 0 ? -area_bottom : 0;
+ offset = area_bottom < 0 ? -area_bottom : 0;
frame_off = GEN_INT (cfun->machine->frame_size - offset);
- if (!CONST_OK_FOR_LETTER_P (INTVAL (frame_off), 'K'))
- frame_off = force_const_mem (Pmode, frame_off);
+ if (DISP_IN_RANGE (INTVAL (frame_off)))
+ {
+ insn = gen_rtx_SET (VOIDmode, frame_pointer,
+ gen_rtx_PLUS (Pmode, frame_pointer, frame_off));
+ insn = emit_insn (insn);
+ }
+ else
+ {
+ if (!CONST_OK_FOR_CONSTRAINT_P (INTVAL (frame_off), 'K', "K"))
+ frame_off = force_const_mem (Pmode, frame_off);
- insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
+ insn = emit_insn (gen_add2_insn (frame_pointer, frame_off));
+ }
}
/* Restore call saved fprs. */
if (TARGET_64BIT)
{
- int i;
-
if (cfun->machine->save_fprs_p)
for (i = 24; i < 32; i++)
if (regs_ever_live[i] && !global_regs[i])
- restore_fpr (frame_pointer,
+ restore_fpr (frame_pointer,
offset - 64 + (i-24) * 8, i);
}
else
{
- if (regs_ever_live[18] && !global_regs[18])
- restore_fpr (frame_pointer, offset + STACK_POINTER_OFFSET - 16, 18);
- if (regs_ever_live[19] && !global_regs[19])
- restore_fpr (frame_pointer, offset + STACK_POINTER_OFFSET - 8, 19);
+ for (i = 18; i < 20; i++)
+ if (regs_ever_live[i] && !global_regs[i])
+ restore_fpr (frame_pointer,
+ offset + 16*UNITS_PER_WORD + 8*(i-16), i);
}
/* Return register. */
- return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
+ return_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
/* Restore call saved gprs. */
@@ -5498,43 +5881,45 @@ s390_emit_epilogue ()
rtx insn, addr;
int i;
- /* Check for global register and save them
+ /* Check for global register and save them
to stack location from where they get restored. */
- for (i = cfun->machine->first_restore_gpr;
+ for (i = cfun->machine->first_restore_gpr;
i <= cfun->machine->last_save_gpr;
i++)
{
- /* These registers are special and need to be
+ /* These registers are special and need to be
restored in any case. */
- if (i == STACK_POINTER_REGNUM
+ if (i == STACK_POINTER_REGNUM
|| i == RETURN_REGNUM
- || i == BASE_REGISTER
+ || i == BASE_REGISTER
|| (flag_pic && i == (int)PIC_OFFSET_TABLE_REGNUM))
continue;
if (global_regs[i])
{
- addr = plus_constant (frame_pointer,
+ addr = plus_constant (frame_pointer,
offset + i * UNITS_PER_WORD);
addr = gen_rtx_MEM (Pmode, addr);
set_mem_alias_set (addr, s390_sr_alias_set);
emit_move_insn (addr, gen_rtx_REG (Pmode, i));
- }
+ }
}
/* Fetch return address from stack before load multiple,
this will do good for scheduling. */
- if (!current_function_is_leaf)
+ if (cfun->machine->save_return_addr_p
+ || (cfun->machine->first_restore_gpr < BASE_REGISTER
+ && cfun->machine->last_save_gpr > RETURN_REGNUM))
{
int return_regnum = find_unused_clobbered_reg();
if (!return_regnum)
return_regnum = 4;
return_reg = gen_rtx_REG (Pmode, return_regnum);
-
- addr = plus_constant (frame_pointer,
- offset + RETURN_REGNUM * UNITS_PER_WORD);
+
+ addr = plus_constant (frame_pointer,
+ offset + RETURN_REGNUM * UNITS_PER_WORD);
addr = gen_rtx_MEM (Pmode, addr);
set_mem_alias_set (addr, s390_sr_alias_set);
emit_move_insn (return_reg, addr);
@@ -5544,10 +5929,10 @@ s390_emit_epilogue ()
explicit in insn RTX code, we have to add a barrier here
to prevent incorrect scheduling. */
- emit_insn (gen_blockage());
+ emit_insn (gen_blockage());
- insn = restore_gprs (frame_pointer, offset,
- cfun->machine->first_restore_gpr,
+ insn = restore_gprs (frame_pointer, offset,
+ cfun->machine->first_restore_gpr,
cfun->machine->last_save_gpr);
emit_insn (insn);
}
@@ -5555,21 +5940,19 @@ s390_emit_epilogue ()
/* Return to caller. */
p = rtvec_alloc (2);
-
+
RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode, return_reg);
emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
}
-/* Return the size in bytes of a function argument of
+/* Return the size in bytes of a function argument of
type TYPE and/or mode MODE. At least one of TYPE or
MODE must be specified. */
static int
-s390_function_arg_size (mode, type)
- enum machine_mode mode;
- tree type;
+s390_function_arg_size (enum machine_mode mode, tree type)
{
if (type)
return int_size_in_bytes (type);
@@ -5582,6 +5965,83 @@ s390_function_arg_size (mode, type)
abort ();
}
+/* Return true if a function argument of type TYPE and mode MODE
+ is to be passed in a floating-point register, if available. */
+
+static bool
+s390_function_arg_float (enum machine_mode mode, tree type)
+{
+ int size = s390_function_arg_size (mode, type);
+ if (size > 8)
+ return false;
+
+ /* Soft-float changes the ABI: no floating-point registers are used. */
+ if (TARGET_SOFT_FLOAT)
+ return false;
+
+ /* No type info available for some library calls ... */
+ if (!type)
+ return mode == SFmode || mode == DFmode;
+
+ /* The ABI says that record types with a single member are treated
+ just like that member would be. */
+ while (TREE_CODE (type) == RECORD_TYPE)
+ {
+ tree field, single = NULL_TREE;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ if (single == NULL_TREE)
+ single = TREE_TYPE (field);
+ else
+ return false;
+ }
+
+ if (single == NULL_TREE)
+ return false;
+ else
+ type = single;
+ }
+
+ return TREE_CODE (type) == REAL_TYPE;
+}
+
+/* Return true if a function argument of type TYPE and mode MODE
+ is to be passed in an integer register, or a pair of integer
+ registers, if available. */
+
+static bool
+s390_function_arg_integer (enum machine_mode mode, tree type)
+{
+ int size = s390_function_arg_size (mode, type);
+ if (size > 8)
+ return false;
+
+ /* No type info available for some library calls ... */
+ if (!type)
+ return GET_MODE_CLASS (mode) == MODE_INT
+ || (TARGET_SOFT_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT);
+
+ /* We accept small integral (and similar) types. */
+ if (INTEGRAL_TYPE_P (type)
+ || POINTER_TYPE_P (type)
+ || TREE_CODE (type) == OFFSET_TYPE
+ || (TARGET_SOFT_FLOAT && TREE_CODE (type) == REAL_TYPE))
+ return true;
+
+ /* We also accept structs of size 1, 2, 4, 8 that are not
+ passed in floating-point registers. */
+ if (AGGREGATE_TYPE_P (type)
+ && exact_log2 (size) >= 0
+ && !s390_function_arg_float (mode, type))
+ return true;
+
+ return false;
+}
+
/* Return 1 if a function argument of type TYPE and mode MODE
is to be passed by reference. The ABI specifies that only
structures of size 1, 2, 4, or 8 bytes are passed by value,
@@ -5589,23 +6049,23 @@ s390_function_arg_size (mode, type)
reference. */
int
-s390_function_arg_pass_by_reference (mode, type)
- enum machine_mode mode;
- tree type;
+s390_function_arg_pass_by_reference (enum machine_mode mode, tree type)
{
int size = s390_function_arg_size (mode, type);
+ if (size > 8)
+ return true;
if (type)
{
- if (AGGREGATE_TYPE_P (type) &&
- size != 1 && size != 2 && size != 4 && size != 8)
+ if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0)
return 1;
- if (TREE_CODE (type) == COMPLEX_TYPE)
+ if (TREE_CODE (type) == COMPLEX_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE)
return 1;
}
- return 0;
+ return 0;
}
/* Update the data in CUM to advance over an argument of mode MODE and
@@ -5615,25 +6075,24 @@ s390_function_arg_pass_by_reference (mode, type)
matching an ellipsis). */
void
-s390_function_arg_advance (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
+s390_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
+ tree type, int named ATTRIBUTE_UNUSED)
{
- if (! TARGET_SOFT_FLOAT && (mode == DFmode || mode == SFmode))
+ if (s390_function_arg_pass_by_reference (mode, type))
{
- cum->fprs++;
+ cum->gprs += 1;
}
- else if (s390_function_arg_pass_by_reference (mode, type))
+ else if (s390_function_arg_float (mode, type))
{
- cum->gprs += 1;
+ cum->fprs += 1;
}
- else
+ else if (s390_function_arg_integer (mode, type))
{
int size = s390_function_arg_size (mode, type);
cum->gprs += ((size + UNITS_PER_WORD-1) / UNITS_PER_WORD);
}
+ else
+ abort ();
}
/* Define where to put the arguments to a function.
@@ -5647,7 +6106,7 @@ s390_function_arg_advance (cum, mode, type, named)
CUM is a variable of type CUMULATIVE_ARGS which gives info about
the preceding args and about the function being called.
NAMED is nonzero if this argument is a named parameter
- (otherwise it is an extra parameter matching an ellipsis).
+ (otherwise it is an extra parameter matching an ellipsis).
On S/390, we use general purpose registers 2 through 6 to
pass integer, pointer, and certain structure arguments, and
@@ -5656,23 +6115,20 @@ s390_function_arg_advance (cum, mode, type, named)
are pushed to the stack. */
rtx
-s390_function_arg (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
+s390_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
+ int named ATTRIBUTE_UNUSED)
{
if (s390_function_arg_pass_by_reference (mode, type))
return 0;
- if (! TARGET_SOFT_FLOAT && (mode == DFmode || mode == SFmode))
+ if (s390_function_arg_float (mode, type))
{
if (cum->fprs + 1 > (TARGET_64BIT? 4 : 2))
return 0;
else
return gen_rtx (REG, mode, cum->fprs + 16);
}
- else
+ else if (s390_function_arg_integer (mode, type))
{
int size = s390_function_arg_size (mode, type);
int n_gprs = (size + UNITS_PER_WORD-1) / UNITS_PER_WORD;
@@ -5682,6 +6138,68 @@ s390_function_arg (cum, mode, type, named)
else
return gen_rtx (REG, mode, cum->gprs + 2);
}
+
+ /* After the real arguments, expand_call calls us once again
+ with a void_type_node type. Whatever we return here is
+ passed as operand 2 to the call expanders.
+
+ We don't need this feature ... */
+ else if (type == void_type_node)
+ return const0_rtx;
+
+ abort ();
+}
+
+/* Return true if return values of type TYPE should be returned
+ in a memory buffer whose address is passed by the caller as
+ hidden first argument. */
+
+static bool
+s390_return_in_memory (tree type, tree fundecl ATTRIBUTE_UNUSED)
+{
+ /* We accept small integral (and similar) types. */
+ if (INTEGRAL_TYPE_P (type)
+ || POINTER_TYPE_P (type)
+ || TREE_CODE (type) == OFFSET_TYPE
+ || TREE_CODE (type) == REAL_TYPE)
+ return int_size_in_bytes (type) > 8;
+
+ /* Aggregates and similar constructs are always returned
+ in memory. */
+ if (AGGREGATE_TYPE_P (type)
+ || TREE_CODE (type) == COMPLEX_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE)
+ return true;
+
+ /* ??? We get called on all sorts of random stuff from
+ aggregate_value_p. We can't abort, but it's not clear
+ what's safe to return. Pretend it's a struct I guess. */
+ return true;
+}
+
+/* Define where to return a (scalar) value of type TYPE.
+ If TYPE is null, define where to return a (scalar)
+ value of mode MODE from a libcall. */
+
+rtx
+s390_function_value (tree type, enum machine_mode mode)
+{
+ if (type)
+ {
+ int unsignedp = TREE_UNSIGNED (type);
+ mode = promote_mode (type, TYPE_MODE (type), &unsignedp, 1);
+ }
+
+ if (GET_MODE_CLASS (mode) != MODE_INT
+ && GET_MODE_CLASS (mode) != MODE_FLOAT)
+ abort ();
+ if (GET_MODE_SIZE (mode) > 8)
+ abort ();
+
+ if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ return gen_rtx_REG (mode, 16);
+ else
+ return gen_rtx_REG (mode, 2);
}
@@ -5695,31 +6213,30 @@ s390_function_arg (cum, mode, type, named)
long __fpr;
void *__overflow_arg_area;
void *__reg_save_area;
-
} va_list[1];
where __gpr and __fpr hold the number of general purpose
or floating point arguments used up to now, respectively,
- __overflow_arg_area points to the stack location of the
+ __overflow_arg_area points to the stack location of the
next argument passed on the stack, and __reg_save_area
always points to the start of the register area in the
call frame of the current function. The function prologue
saves all registers used for argument passing into this
area if the function uses variable arguments. */
-tree
-s390_build_va_list ()
+static tree
+s390_build_builtin_va_list (void)
{
tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
- record = (*lang_hooks.types.make_type) (RECORD_TYPE);
+ record = lang_hooks.types.make_type (RECORD_TYPE);
type_decl =
build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
- f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
+ f_gpr = build_decl (FIELD_DECL, get_identifier ("__gpr"),
long_integer_type_node);
- f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
+ f_fpr = build_decl (FIELD_DECL, get_identifier ("__fpr"),
long_integer_type_node);
f_ovf = build_decl (FIELD_DECL, get_identifier ("__overflow_arg_area"),
ptr_type_node);
@@ -5758,9 +6275,7 @@ s390_build_va_list ()
(relative to the virtual arg pointer). */
void
-s390_va_start (valist, nextarg)
- tree valist;
- rtx nextarg ATTRIBUTE_UNUSED;
+s390_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT n_gpr, n_fpr;
int off;
@@ -5815,15 +6330,15 @@ s390_va_start (valist, nextarg)
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
}
-/* Implement va_arg by updating the va_list structure
+/* Implement va_arg by updating the va_list structure
VALIST as required to retrieve an argument of type
- TYPE, and returning that argument.
-
+ TYPE, and returning that argument.
+
Generates code equivalent to:
-
+
if (integral value) {
if (size <= 4 && args.gpr < 5 ||
- size > 4 && args.gpr < 4 )
+ size > 4 && args.gpr < 4 )
ret = args.reg_save_area[args.gpr+8]
else
ret = *args.overflow_arg_area++;
@@ -5840,9 +6355,7 @@ s390_va_start (valist, nextarg)
} */
rtx
-s390_va_arg (valist, type)
- tree valist;
- tree type;
+s390_va_arg (tree valist, tree type)
{
tree f_gpr, f_fpr, f_ovf, f_sav;
tree gpr, fpr, ovf, sav, reg, t, u;
@@ -5879,7 +6392,7 @@ s390_va_arg (valist, type)
size = UNITS_PER_WORD;
max_reg = 4;
}
- else if (FLOAT_TYPE_P (type) && ! TARGET_SOFT_FLOAT)
+ else if (s390_function_arg_float (TYPE_MODE (type), type))
{
if (TARGET_DEBUG_ARG)
{
@@ -5909,13 +6422,9 @@ s390_va_arg (valist, type)
reg = gpr;
n_reg = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
sav_ofs = 2 * UNITS_PER_WORD;
- if (TARGET_64BIT)
- sav_ofs += TYPE_MODE (type) == SImode ? 4 :
- TYPE_MODE (type) == HImode ? 6 :
- TYPE_MODE (type) == QImode ? 7 : 0;
- else
- sav_ofs += TYPE_MODE (type) == HImode ? 2 :
- TYPE_MODE (type) == QImode ? 3 : 0;
+
+ if (size < UNITS_PER_WORD)
+ sav_ofs += UNITS_PER_WORD - size;
sav_scale = UNITS_PER_WORD;
if (n_reg > 1)
@@ -5982,10 +6491,10 @@ s390_va_arg (valist, type)
emit_label (lab_over);
- /* If less than max_regs a registers are retrieved out
+ /* If less than max_regs a registers are retrieved out
of register save area, increment. */
- u = build (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
+ u = build (PREINCREMENT_EXPR, TREE_TYPE (reg), reg,
build_int_2 (n_reg, 0));
TREE_SIDE_EFFECTS (u) = 1;
expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
@@ -6023,7 +6532,7 @@ static unsigned int const code_for_builtin_31[S390_BUILTIN_max] = {
};
static void
-s390_init_builtins ()
+s390_init_builtins (void)
{
tree ftype;
@@ -6045,16 +6554,13 @@ s390_init_builtins ()
IGNORE is nonzero if the value is to be ignored. */
static rtx
-s390_expand_builtin (exp, target, subtarget, mode, ignore)
- tree exp;
- rtx target;
- rtx subtarget ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- int ignore ATTRIBUTE_UNUSED;
+s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ int ignore ATTRIBUTE_UNUSED)
{
#define MAX_ARGS 2
- unsigned int const *code_for_builtin =
+ unsigned int const *code_for_builtin =
TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
@@ -6137,8 +6643,7 @@ s390_expand_builtin (exp, target, subtarget, mode, ignore)
gpr 0 is used to hold the static chain. */
void
-s390_trampoline_template (file)
- FILE *file;
+s390_trampoline_template (FILE *file)
{
if (TARGET_64BIT)
{
@@ -6165,18 +6670,15 @@ s390_trampoline_template (file)
CXT is an RTX for the static chain value for the function. */
void
-s390_initialize_trampoline (addr, fnaddr, cxt)
- rtx addr;
- rtx fnaddr;
- rtx cxt;
+s390_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
{
- emit_move_insn (gen_rtx
+ emit_move_insn (gen_rtx
(MEM, Pmode,
- memory_address (Pmode,
+ memory_address (Pmode,
plus_constant (addr, (TARGET_64BIT ? 20 : 12) ))), cxt);
emit_move_insn (gen_rtx
(MEM, Pmode,
- memory_address (Pmode,
+ memory_address (Pmode,
plus_constant (addr, (TARGET_64BIT ? 28 : 16) ))), fnaddr);
}
@@ -6184,16 +6686,14 @@ s390_initialize_trampoline (addr, fnaddr, cxt)
LOW and HIGH, independent of the host word size. */
rtx
-s390_gen_rtx_const_DI (high, low)
- int high;
- int low;
+s390_gen_rtx_const_DI (int high, int low)
{
#if HOST_BITS_PER_WIDE_INT >= 64
HOST_WIDE_INT val;
val = (HOST_WIDE_INT)high;
val <<= 32;
val |= (HOST_WIDE_INT)low;
-
+
return GEN_INT (val);
#else
#if HOST_BITS_PER_WIDE_INT >= 32
@@ -6202,15 +6702,13 @@ s390_gen_rtx_const_DI (high, low)
abort ();
#endif
#endif
-}
+}
/* Output assembler code to FILE to increment profiler label # LABELNO
for profiling a function entry. */
void
-s390_function_profiler (file, labelno)
- FILE *file;
- int labelno;
+s390_function_profiler (FILE *file, int labelno)
{
rtx op[7];
@@ -6225,12 +6723,12 @@ s390_function_profiler (file, labelno)
op[2] = gen_rtx_REG (Pmode, 1);
op[3] = gen_rtx_SYMBOL_REF (Pmode, label);
- SYMBOL_REF_FLAG (op[3]) = 1;
+ SYMBOL_REF_FLAGS (op[3]) = SYMBOL_FLAG_LOCAL;
op[4] = gen_rtx_SYMBOL_REF (Pmode, "_mcount");
if (flag_pic)
{
- op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), 113);
+ op[4] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[4]), UNSPEC_PLT);
op[4] = gen_rtx_CONST (Pmode, op[4]);
}
@@ -6249,7 +6747,7 @@ s390_function_profiler (file, labelno)
output_asm_insn ("bras\t%2,%l6", op);
output_asm_insn (".long\t%4", op);
output_asm_insn (".long\t%3", op);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[6]));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
output_asm_insn ("l\t%0,0(%2)", op);
output_asm_insn ("l\t%2,4(%2)", op);
output_asm_insn ("basr\t%0,%0", op);
@@ -6262,10 +6760,10 @@ s390_function_profiler (file, labelno)
output_asm_insn ("st\t%0,%1", op);
output_asm_insn ("bras\t%2,%l6", op);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[5]));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[5]));
output_asm_insn (".long\t%4-%l5", op);
output_asm_insn (".long\t%3-%l5", op);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[6]));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[6]));
output_asm_insn ("lr\t%0,%2", op);
output_asm_insn ("a\t%0,0(%2)", op);
output_asm_insn ("a\t%2,4(%2)", op);
@@ -6278,144 +6776,57 @@ s390_function_profiler (file, labelno)
constants go in the function section; in 64-bit mode in .rodata. */
static void
-s390_select_rtx_section (mode, x, align)
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx x ATTRIBUTE_UNUSED;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+s390_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx x ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
- if (TARGET_64BIT)
+ if (TARGET_CPU_ZARCH)
readonly_data_section ();
else
function_section (current_function_decl);
}
/* Encode symbol attributes (local vs. global, tls model) of a SYMBOL_REF
- into its name and SYMBOL_REF_FLAG. */
+ into its SYMBOL_REF_FLAGS. */
static void
-s390_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
+s390_encode_section_info (tree decl, rtx rtl, int first)
{
- bool local_p = (*targetm.binds_local_p) (decl);
- rtx rtl, symbol;
-
- rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
- if (GET_CODE (rtl) != MEM)
- return;
- symbol = XEXP (rtl, 0);
- if (GET_CODE (symbol) != SYMBOL_REF)
- return;
+ default_encode_section_info (decl, rtl, first);
- /* When using PIC, SYMBOL_REF_FLAG marks non-global symbols
- that can be accessed directly. */
- if (flag_pic)
- SYMBOL_REF_FLAG (symbol) = local_p;
-
- /* Encode thread-local data with %[GLil] for "global dynamic",
- "local dynamic", "initial exec" or "local exec" TLS models,
- respectively. */
-
- if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
- {
- const char *symbol_str = XSTR (symbol, 0);
- char *newstr;
- size_t len;
- enum tls_model kind = decl_tls_model (decl);
-
- if (!flag_pic)
- {
- /* We don't allow non-pic code for shared libraries,
- so don't generate GD/LD TLS models for non-pic code. */
- switch (kind)
- {
- case TLS_MODEL_GLOBAL_DYNAMIC:
- kind = TLS_MODEL_INITIAL_EXEC; break;
- case TLS_MODEL_LOCAL_DYNAMIC:
- kind = TLS_MODEL_LOCAL_EXEC; break;
- default:
- break;
- }
- }
-
- if (symbol_str[0] == '%')
- {
- if (symbol_str[1] == tls_model_chars[kind])
- return;
- symbol_str += 2;
- }
- len = strlen (symbol_str) + 1;
- newstr = alloca (len + 2);
-
- newstr[0] = '%';
- newstr[1] = tls_model_chars[kind];
- memcpy (newstr + 2, symbol_str, len);
-
- XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2 - 1);
- }
-
- /* If a variable has a forced alignment to < 2 bytes, mark it
- with '@' to prevent it from being used as LARL operand. */
-
- else if (TREE_CODE (decl) == VAR_DECL
- && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16
- && XSTR (symbol, 0)[0] != '@')
- {
- const char *symbol_str = XSTR (symbol, 0);
- size_t len = strlen (symbol_str) + 1;
- char *newstr = alloca (len + 1);
-
- newstr[0] = '@';
- memcpy (newstr + 1, symbol_str, len);
-
- XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 1 - 1);
- }
-}
-
-/* Undo the above when printing symbol names. */
-
-static const char *
-s390_strip_name_encoding (str)
- const char *str;
-{
- if (str[0] == '%')
- str += 2;
- if (str[0] == '@')
- str += 1;
- if (str[0] == '*')
- str += 1;
- return str;
+ /* If a variable has a forced alignment to < 2 bytes, mark it with
+ SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */
+ if (TREE_CODE (decl) == VAR_DECL
+ && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16)
+ SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1;
}
/* Output thunk to FILE that implements a C++ virtual function call (with
- multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
+ multiple inheritance) to FUNCTION. The thunk adjusts the this pointer
by DELTA, and unless VCALL_OFFSET is zero, applies an additional adjustment
stored at VCALL_OFFSET in the vtable whose address is located at offset 0
relative to the resulting this pointer. */
static void
-s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
- FILE *file;
- tree thunk ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset;
- tree function;
+s390_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
+ tree function)
{
rtx op[10];
int nonlocal = 0;
/* Operand 0 is the target function. */
op[0] = XEXP (DECL_RTL (function), 0);
- if (flag_pic && !SYMBOL_REF_FLAG (op[0]))
+ if (flag_pic && !SYMBOL_REF_LOCAL_P (op[0]))
{
nonlocal = 1;
op[0] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op[0]),
- TARGET_64BIT ? 113 : flag_pic == 2 ? 112 : 110);
+ TARGET_64BIT ? UNSPEC_PLT : UNSPEC_GOT);
op[0] = gen_rtx_CONST (Pmode, op[0]);
}
/* Operand 1 is the 'this' pointer. */
- if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
+ if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
op[1] = gen_rtx_REG (Pmode, 3);
else
op[1] = gen_rtx_REG (Pmode, 2);
@@ -6442,8 +6853,10 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
if (TARGET_64BIT)
{
/* Setup literal pool pointer if required. */
- if (!CONST_OK_FOR_LETTER_P (delta, 'K')
- || !CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
+ if ((!DISP_IN_RANGE (delta)
+ && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
+ || (!DISP_IN_RANGE (vcall_offset)
+ && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
{
op[5] = gen_label_rtx ();
output_asm_insn ("larl\t%4,%5", op);
@@ -6452,9 +6865,11 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
/* Add DELTA to this pointer. */
if (delta)
{
- if (CONST_OK_FOR_LETTER_P (delta, 'J'))
+ if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
output_asm_insn ("la\t%1,%2(%1)", op);
- else if (CONST_OK_FOR_LETTER_P (delta, 'K'))
+ else if (DISP_IN_RANGE (delta))
+ output_asm_insn ("lay\t%1,%2(%1)", op);
+ else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
output_asm_insn ("aghi\t%1,%2", op);
else
{
@@ -6466,12 +6881,12 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
/* Perform vcall adjustment. */
if (vcall_offset)
{
- if (CONST_OK_FOR_LETTER_P (vcall_offset, 'J'))
+ if (DISP_IN_RANGE (vcall_offset))
{
output_asm_insn ("lg\t%4,0(%1)", op);
output_asm_insn ("ag\t%1,%3(%4)", op);
}
- else if (CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
+ else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
{
output_asm_insn ("lghi\t%4,%3", op);
output_asm_insn ("ag\t%4,0(%1)", op);
@@ -6485,7 +6900,7 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
output_asm_insn ("ag\t%1,0(%4)", op);
}
}
-
+
/* Jump to target. */
output_asm_insn ("jg\t%0", op);
@@ -6493,16 +6908,19 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
if (op[5])
{
output_asm_insn (".align\t4", op);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[5]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[5]));
}
if (op[6])
{
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[6]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[6]));
output_asm_insn (".long\t%2", op);
}
if (op[7])
{
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[7]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[7]));
output_asm_insn (".long\t%3", op);
}
}
@@ -6510,20 +6928,25 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
{
/* Setup base pointer if required. */
if (!vcall_offset
- || !CONST_OK_FOR_LETTER_P (delta, 'K')
- || !CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
+ || (!DISP_IN_RANGE (delta)
+ && !CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
+ || (!DISP_IN_RANGE (delta)
+ && !CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K")))
{
op[5] = gen_label_rtx ();
output_asm_insn ("basr\t%4,0", op);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[5]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[5]));
}
/* Add DELTA to this pointer. */
if (delta)
{
- if (CONST_OK_FOR_LETTER_P (delta, 'J'))
+ if (CONST_OK_FOR_CONSTRAINT_P (delta, 'J', "J"))
output_asm_insn ("la\t%1,%2(%1)", op);
- else if (CONST_OK_FOR_LETTER_P (delta, 'K'))
+ else if (DISP_IN_RANGE (delta))
+ output_asm_insn ("lay\t%1,%2(%1)", op);
+ else if (CONST_OK_FOR_CONSTRAINT_P (delta, 'K', "K"))
output_asm_insn ("ahi\t%1,%2", op);
else
{
@@ -6535,12 +6958,17 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
/* Perform vcall adjustment. */
if (vcall_offset)
{
- if (CONST_OK_FOR_LETTER_P (vcall_offset, 'J'))
+ if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'J', "J"))
{
output_asm_insn ("lg\t%4,0(%1)", op);
output_asm_insn ("a\t%1,%3(%4)", op);
}
- else if (CONST_OK_FOR_LETTER_P (vcall_offset, 'K'))
+ else if (DISP_IN_RANGE (vcall_offset))
+ {
+ output_asm_insn ("lg\t%4,0(%1)", op);
+ output_asm_insn ("ay\t%1,%3(%4)", op);
+ }
+ else if (CONST_OK_FOR_CONSTRAINT_P (vcall_offset, 'K', "K"))
{
output_asm_insn ("lhi\t%4,%3", op);
output_asm_insn ("a\t%4,0(%1)", op);
@@ -6558,7 +6986,8 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
Re-setup the base pointer (with a different base). */
op[5] = gen_label_rtx ();
output_asm_insn ("basr\t%4,0", op);
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[5]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[5]));
}
/* Jump to target. */
@@ -6593,10 +7022,10 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
if (nonlocal)
{
op[0] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
- SYMBOL_REF_FLAG (op[0]) = 1;
+ SYMBOL_REF_FLAGS (op[0]) = SYMBOL_FLAG_LOCAL;
}
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[8]));
+ targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (op[8]));
if (!flag_pic)
output_asm_insn (".long\t%0", op);
else
@@ -6604,21 +7033,29 @@ s390_output_mi_thunk (file, thunk, delta, vcall_offset, function)
if (op[6])
{
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[6]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[6]));
output_asm_insn (".long\t%2", op);
}
if (op[7])
{
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (op[7]));
+ targetm.asm_out.internal_label (file, "L",
+ CODE_LABEL_NUMBER (op[7]));
output_asm_insn (".long\t%3", op);
}
}
}
+bool
+s390_valid_pointer_mode (enum machine_mode mode)
+{
+ return (mode == SImode || (TARGET_64BIT && mode == DImode));
+}
+
/* How to allocate a 'struct machine_function'. */
static struct machine_function *
-s390_init_machine_status ()
+s390_init_machine_status (void)
{
return ggc_alloc_cleared (sizeof (struct machine_function));
}
diff --git a/contrib/gcc/config/s390/s390.h b/contrib/gcc/config/s390/s390.h
index c3dad6829e07..d2416c8a0f85 100644
--- a/contrib/gcc/config/s390/s390.h
+++ b/contrib/gcc/config/s390/s390.h
@@ -1,23 +1,25 @@
/* Definitions of target machine for GNU compiler, for IBM S/390
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
-This file is part of GNU CC.
-GNU CC 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 file is part of GCC.
-GNU CC 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.
+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 2, 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#ifndef _S390_H
#define _S390_H
@@ -25,9 +27,49 @@ Boston, MA 02111-1307, USA. */
/* Override the __fixdfdi etc. routines when building libgcc2.
??? This should be done in a cleaner way ... */
#if defined (IN_LIBGCC2) && !defined (__s390x__)
-#include <s390/fixdfdi.h>
+#include <config/s390/fixdfdi.h>
#endif
+/* Which processor to generate code or schedule for. The cpu attribute
+ defines a list that mirrors this list, so changes to s390.md must be
+ made at the same time. */
+
+enum processor_type
+{
+ PROCESSOR_9672_G5,
+ PROCESSOR_9672_G6,
+ PROCESSOR_2064_Z900,
+ PROCESSOR_2084_Z990,
+ PROCESSOR_max
+};
+
+/* Optional architectural facilities supported by the processor. */
+
+enum processor_flags
+{
+ PF_IEEE_FLOAT = 1,
+ PF_ZARCH = 2,
+ PF_LONG_DISPLACEMENT = 4
+};
+
+extern enum processor_type s390_tune;
+extern enum processor_flags s390_tune_flags;
+extern const char *s390_tune_string;
+
+extern enum processor_type s390_arch;
+extern enum processor_flags s390_arch_flags;
+extern const char *s390_arch_string;
+
+#define TARGET_CPU_IEEE_FLOAT \
+ (s390_arch_flags & PF_IEEE_FLOAT)
+#define TARGET_CPU_ZARCH \
+ (s390_arch_flags & PF_ZARCH)
+#define TARGET_CPU_LONG_DISPLACEMENT \
+ (s390_arch_flags & PF_LONG_DISPLACEMENT)
+
+#define TARGET_LONG_DISPLACEMENT \
+ (TARGET_ZARCH && TARGET_CPU_LONG_DISPLACEMENT)
+
/* Run-time target specification. */
@@ -46,39 +88,85 @@ Boston, MA 02111-1307, USA. */
/* Optional target features. */
extern int target_flags;
-#define TARGET_HARD_FLOAT (target_flags & 1)
-#define TARGET_SOFT_FLOAT (!(target_flags & 1))
-#define TARGET_BACKCHAIN (target_flags & 2)
-#define TARGET_SMALL_EXEC (target_flags & 4)
-#define TARGET_DEBUG_ARG (target_flags & 8)
-#define TARGET_64BIT (target_flags & 16)
-#define TARGET_MVCLE (target_flags & 32)
+#define MASK_HARD_FLOAT 0x01
+#define MASK_BACKCHAIN 0x02
+#define MASK_SMALL_EXEC 0x04
+#define MASK_DEBUG_ARG 0x08
+#define MASK_64BIT 0x10
+#define MASK_ZARCH 0x20
+#define MASK_MVCLE 0x40
+#define MASK_TPF 0x80
+#define MASK_NO_FUSED_MADD 0x100
+
+#define TARGET_HARD_FLOAT (target_flags & MASK_HARD_FLOAT)
+#define TARGET_SOFT_FLOAT (!(target_flags & MASK_HARD_FLOAT))
+#define TARGET_BACKCHAIN (target_flags & MASK_BACKCHAIN)
+#define TARGET_SMALL_EXEC (target_flags & MASK_SMALL_EXEC)
+#define TARGET_DEBUG_ARG (target_flags & MASK_DEBUG_ARG)
+#define TARGET_64BIT (target_flags & MASK_64BIT)
+#define TARGET_ZARCH (target_flags & MASK_ZARCH)
+#define TARGET_MVCLE (target_flags & MASK_MVCLE)
+#define TARGET_TPF (target_flags & MASK_TPF)
+#define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD)
+#define TARGET_FUSED_MADD (! TARGET_NO_FUSED_MADD)
/* ??? Once this actually works, it could be made a runtime option. */
#define TARGET_IBM_FLOAT 0
#define TARGET_IEEE_FLOAT 1
#ifdef DEFAULT_TARGET_64BIT
-#define TARGET_DEFAULT 0x13
+#define TARGET_DEFAULT 0x31
#else
-#define TARGET_DEFAULT 0x3
+#define TARGET_DEFAULT 0x1
#endif
-#define TARGET_SWITCHES \
-{ { "hard-float", 1, N_("Use hardware fp")}, \
- { "soft-float", -1, N_("Don't use hardware fp")}, \
- { "backchain", 2, N_("Set backchain")}, \
- { "no-backchain", -2, N_("Don't set backchain (faster, but debug harder")}, \
- { "small-exec", 4, N_("Use bras for executable < 64k")}, \
- { "no-small-exec",-4, N_("Don't use bras")}, \
- { "debug", 8, N_("Additional debug prints")}, \
- { "no-debug", -8, N_("Don't print additional debug prints")}, \
- { "64", 16, N_("64 bit mode")}, \
- { "31", -16, N_("31 bit mode")}, \
- { "mvcle", 32, N_("mvcle use")}, \
- { "no-mvcle", -32, N_("mvc&ex")}, \
+#define TARGET_SWITCHES \
+{ { "hard-float", 1, N_("Use hardware fp")}, \
+ { "soft-float", -1, N_("Don't use hardware fp")}, \
+ { "backchain", 2, N_("Set backchain")}, \
+ { "no-backchain", -2, N_("Don't set backchain (faster, but debug harder")},\
+ { "small-exec", 4, N_("Use bras for executable < 64k")}, \
+ { "no-small-exec", -4, N_("Don't use bras")}, \
+ { "debug", 8, N_("Additional debug prints")}, \
+ { "no-debug", -8, N_("Don't print additional debug prints")}, \
+ { "64", 16, N_("64 bit ABI")}, \
+ { "31", -16, N_("31 bit ABI")}, \
+ { "zarch", 32, N_("z/Architecture")}, \
+ { "esa", -32, N_("ESA/390 architecture")}, \
+ { "mvcle", 64, N_("mvcle use")}, \
+ { "no-mvcle", -64, N_("mvc&ex")}, \
+ { "tpf", 128, N_("enable tpf OS code")}, \
+ { "no-tpf", -128, N_("disable tpf OS code")}, \
+ { "no-fused-madd", 256, N_("disable fused multiply/add instructions")},\
+ { "fused-madd", -256, N_("enable fused multiply/add instructions")}, \
{ "", TARGET_DEFAULT, 0 } }
+#define TARGET_OPTIONS \
+{ { "tune=", &s390_tune_string, \
+ N_("Schedule code for given CPU"), 0}, \
+ { "arch=", &s390_arch_string, \
+ N_("Generate code for given CPU"), 0}, \
+}
+
+/* Support for configure-time defaults. */
+#define OPTION_DEFAULT_SPECS \
+ { "mode", "%{!mesa:%{!mzarch:-m%(VALUE)}}" }, \
+ { "arch", "%{!march=*:-march=%(VALUE)}" }, \
+ { "tune", "%{!mtune=*:-mtune=%(VALUE)}" }
+
+/* Defaulting rules. */
+#ifdef DEFAULT_TARGET_64BIT
+#define DRIVER_SELF_SPECS \
+ "%{!m31:%{!m64:-m64}}", \
+ "%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}", \
+ "%{!march=*:%{mesa:-march=g5}%{mzarch:-march=z900}}"
+#else
+#define DRIVER_SELF_SPECS \
+ "%{!m31:%{!m64:-m31}}", \
+ "%{!mesa:%{!mzarch:%{m31:-mesa}%{m64:-mzarch}}}", \
+ "%{!march=*:%{mesa:-march=g5}%{mzarch:-march=z900}}"
+#endif
+
/* Target version string. Overridden by the OS header. */
#ifdef DEFAULT_TARGET_64BIT
#define TARGET_VERSION fprintf (stderr, " (zSeries)");
@@ -158,7 +246,7 @@ if (INTEGRAL_MODE_P (MODE) && \
NONLOCAL needs twice Pmode to maintain both backchain and SP. */
#define STACK_SAVEAREA_MODE(LEVEL) \
(LEVEL == SAVE_FUNCTION ? VOIDmode \
- : LEVEL == SAVE_NONLOCAL ? (TARGET_64BIT ? TImode : DImode) : Pmode)
+ : LEVEL == SAVE_NONLOCAL ? (TARGET_64BIT ? OImode : TImode) : Pmode)
/* Define target floating point format. */
#define TARGET_FLOAT_FORMAT \
@@ -186,7 +274,7 @@ if (INTEGRAL_MODE_P (MODE) && \
/* We have 16 general purpose registers (registers 0-15),
and 16 floating point registers (registers 16-31).
(On non-IEEE machines, we have only 4 fp registers.)
-
+
Amongst the general purpose registers, some are used
for specific purposes:
GPR 11: Hard frame pointer (if needed)
@@ -194,7 +282,7 @@ if (INTEGRAL_MODE_P (MODE) && \
GPR 13: Literal pool base register
GPR 14: Return address register
GPR 15: Stack pointer
-
+
Registers 32-34 are 'fake' hard registers that do not
correspond to actual hardware:
Reg 32: Argument pointer
@@ -226,7 +314,7 @@ if (INTEGRAL_MODE_P (MODE) && \
GPRs 6-15 are always call-saved.
GPR 12 is fixed if used as GOT pointer.
GPR 13 is always fixed (as literal pool pointer).
- GPR 14 is always fixed (as return address).
+ GPR 14 is always fixed on S/390 machines (as return address).
GPR 15 is always fixed (as stack pointer).
The 'fake' hard registers are call-clobbered and fixed.
@@ -277,6 +365,11 @@ do \
fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
} \
+ if (TARGET_CPU_ZARCH) \
+ { \
+ fixed_regs[RETURN_REGNUM] = 0; \
+ call_used_regs[RETURN_REGNUM] = 0; \
+ } \
if (TARGET_64BIT) \
{ \
for (i = 24; i < 32; i++) \
@@ -291,26 +384,26 @@ do \
/* Preferred register allocation order. */
#define REG_ALLOC_ORDER \
-{ 1, 2, 3, 4, 5, 0, 14, 13, 12, 11, 10, 9, 8, 7, 6, \
+{ 1, 2, 3, 4, 5, 0, 13, 12, 11, 10, 9, 8, 7, 6, 14, \
16, 17, 18, 19, 20, 21, 22, 23, \
24, 25, 26, 27, 28, 29, 30, 31, \
15, 32, 33, 34 }
/* Fitting values into registers. */
-
+
/* Integer modes <= word size fit into any GPR.
Integer modes > word size fit into successive GPRs, starting with
an even-numbered register.
SImode and DImode fit into FPRs as well.
-
+
Floating point modes <= word size fit into any FPR or GPR.
Floating point modes > word size (i.e. DFmode on 32-bit) fit
into any FPR, or an even-odd GPR pair.
-
+
Complex floating point modes fit either into two FPRs, or into
successive GPRs (again starting with an even number).
-
+
Condition code modes fit only into the CC register. */
#define HARD_REGNO_NREGS(REGNO, MODE) \
@@ -352,19 +445,19 @@ do \
? reg_classes_intersect_p (FP_REGS, CLASS) : 0)
/* Register classes. */
-
+
/* We use the following register classes:
GENERAL_REGS All general purpose registers
ADDR_REGS All general purpose registers except %r0
(These registers can be used in address generation)
FP_REGS All floating point registers
-
+
GENERAL_FP_REGS Union of GENERAL_REGS and FP_REGS
ADDR_FP_REGS Union of ADDR_REGS and FP_REGS
-
+
NO_REGS No registers
ALL_REGS All registers
-
+
Note that the 'fake' frame pointer and argument pointer registers
are included amongst the address registers here. The condition
code register is only included in ALL_REGS. */
@@ -444,23 +537,23 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
(C) == 'd' ? GENERAL_REGS : \
(C) == 'f' ? FP_REGS : NO_REGS)
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'I' ? (unsigned long) (VALUE) < 256 : \
- (C) == 'J' ? (unsigned long) (VALUE) < 4096 : \
- (C) == 'K' ? (VALUE) >= -32768 && (VALUE) < 32768 : \
- (C) == 'L' ? (unsigned long) (VALUE) < 65536 : 0)
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 1
+#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \
+ s390_const_ok_for_constraint_p ((VALUE), (C), (STR))
-#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'Q' ? q_constraint (OP) : \
- (C) == 'S' ? larl_operand (OP, GET_MODE (OP)) : 0)
+#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(VALUE, C, STR) 1
-#define EXTRA_MEMORY_CONSTRAINT(C) ((C) == 'Q')
+#define EXTRA_CONSTRAINT_STR(OP, C, STR) \
+ s390_extra_constraint_str ((OP), (C), (STR))
+#define EXTRA_MEMORY_CONSTRAINT(C, STR) \
+ ((C) == 'Q' || (C) == 'R' || (C) == 'S' || (C) == 'T')
+#define EXTRA_ADDRESS_CONSTRAINT(C, STR) \
+ ((C) == 'U' || (C) == 'W' || (C) == 'Y')
+#define CONSTRAINT_LEN(C, STR) \
+ ((C) == 'N' ? 5 : DEFAULT_CONSTRAINT_LEN ((C), (STR)))
/* Stack layout and calling conventions. */
-
+
/* Our stack grows from higher to lower addresses. However, local variables
are accessed by positive offsets, and function arguments are stored at
increasing addresses. */
@@ -490,7 +583,7 @@ extern int current_function_outgoing_args_size;
the argument area. */
#define FIRST_PARM_OFFSET(FNDECL) 0
-/* The return address of the current frame is retrieved
+/* The return address of the current frame is retrieved
from the initial value of register RETURN_REGNUM.
For frames farther back, we use the stack slot where
the corresponding RETURN_REGNUM register was saved. */
@@ -498,7 +591,7 @@ extern int current_function_outgoing_args_size;
#define DYNAMIC_CHAIN_ADDRESS(FRAME) \
((FRAME) != hard_frame_pointer_rtx ? (FRAME) : \
plus_constant (arg_pointer_rtx, -STACK_POINTER_OFFSET))
-
+
#define RETURN_ADDR_RTX(COUNT, FRAME) \
s390_return_addr_rtx ((COUNT), DYNAMIC_CHAIN_ADDRESS ((FRAME)))
@@ -507,7 +600,7 @@ extern int current_function_outgoing_args_size;
/* Exception handling. */
-
+
/* Describe calling conventions for DWARF-2 exception handling. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, RETURN_REGNUM)
#define INCOMING_FRAME_SP_OFFSET STACK_POINTER_OFFSET
@@ -517,7 +610,7 @@ extern int current_function_outgoing_args_size;
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 6 : INVALID_REGNUM)
#define EH_RETURN_HANDLER_RTX \
gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, \
- TARGET_64BIT? -48 : -40))
+ -STACK_POINTER_OFFSET + UNITS_PER_WORD*RETURN_REGNUM))
/* Select a format to encode pointers in exception handling data. */
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
@@ -533,8 +626,8 @@ extern int current_function_outgoing_args_size;
#define HARD_FRAME_POINTER_REGNUM 11
#define ARG_POINTER_REGNUM 32
-/* The static chain must be call-clobbered, but not used for
- function argument passing. As register 1 is clobbered by
+/* The static chain must be call-clobbered, but not used for
+ function argument passing. As register 1 is clobbered by
the trampoline code, we only have one option. */
#define STATIC_CHAIN_REGNUM 0
@@ -554,7 +647,7 @@ extern int current_function_outgoing_args_size;
{{ 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}}
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
#define CAN_ELIMINATE(FROM, TO) (1)
@@ -575,7 +668,7 @@ extern int current_function_outgoing_args_size;
/* Stack arguments. */
-
+
/* We need current_function_outgoing_args to be valid. */
#define ACCUMULATE_OUTGOING_ARGS 1
@@ -584,7 +677,7 @@ extern int current_function_outgoing_args_size;
/* Register arguments. */
-
+
typedef struct s390_arg_structure
{
int gprs; /* gpr so far */
@@ -592,7 +685,7 @@ typedef struct s390_arg_structure
}
CUMULATIVE_ARGS;
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, NN) \
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, NN, N_NAMED_ARGS) \
((CUM).gprs=0, (CUM).fprs=0)
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
@@ -613,41 +706,22 @@ CUMULATIVE_ARGS;
/* Scalar return values. */
-
-/* We return scalars in general purpose register 2 for integral values,
- and floating point register 0 for fp values. */
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx_REG ((INTEGRAL_TYPE_P (VALTYPE) \
- && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) \
- || POINTER_TYPE_P (VALTYPE) \
- ? word_mode : TYPE_MODE (VALTYPE), \
- TREE_CODE (VALTYPE) == REAL_TYPE && TARGET_HARD_FLOAT ? 16 : 2)
-
-/* Define how to find the value returned by a library function assuming
- the value has mode MODE. */
-#define RET_REG(MODE) ((GET_MODE_CLASS (MODE) == MODE_INT \
- || TARGET_SOFT_FLOAT ) ? 2 : 16)
-#define LIBCALL_VALUE(MODE) gen_rtx (REG, MODE, RET_REG (MODE))
-
-/* Only gpr 2 and fpr 0 are ever used as return registers. */
-#define FUNCTION_VALUE_REGNO_P(N) ((N) == 2 || (N) == 16)
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+ s390_function_value ((VALTYPE), VOIDmode)
-/* Aggregate return values. */
+#define LIBCALL_VALUE(MODE) \
+ s390_function_value (NULL, (MODE))
-/* The definition of this macro implies that there are cases where
- a scalar value cannot be returned in registers. */
-#define RETURN_IN_MEMORY(type) \
- (TYPE_MODE (type) == BLKmode || \
- GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_INT || \
- GET_MODE_CLASS (TYPE_MODE (type)) == MODE_COMPLEX_FLOAT)
+/* Only gpr 2 and fpr 0 are ever used as return registers. */
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == 2 || (N) == 16)
/* Structure value address is passed as invisible first argument (gpr 2). */
#define STRUCT_VALUE 0
/* Function entry and exit. */
-
+
/* When returning from a function, the stack pointer does not matter. */
#define EXIT_IGNORE_STACK 1
@@ -662,9 +736,6 @@ CUMULATIVE_ARGS;
/* Implementing the varargs macros. */
-#define BUILD_VA_LIST_TYPE(VALIST) \
- (VALIST) = s390_build_va_list ()
-
#define EXPAND_BUILTIN_VA_START(valist, nextarg) \
s390_va_start (valist, nextarg)
@@ -684,7 +755,7 @@ CUMULATIVE_ARGS;
/* Library calls. */
-
+
/* We should use memcpy, not bcopy. */
#define TARGET_MEM_FUNCTIONS
@@ -711,7 +782,7 @@ CUMULATIVE_ARGS;
#define REG_OK_FOR_INDEX_NONSTRICT_P(X) \
((GET_MODE (X) == Pmode) && \
((REGNO (X) >= FIRST_PSEUDO_REGISTER) \
- || REGNO_REG_CLASS (REGNO (X)) == ADDR_REGS))
+ || REGNO_REG_CLASS (REGNO (X)) == ADDR_REGS))
#define REG_OK_FOR_BASE_NONSTRICT_P(X) REG_OK_FOR_INDEX_NONSTRICT_P (X)
@@ -781,7 +852,7 @@ CUMULATIVE_ARGS;
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison. */
#define SELECT_CC_MODE(OP, X, Y) s390_select_ccmode ((OP), (X), (Y))
-
+
/* 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! */
@@ -790,77 +861,6 @@ extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
/* Relative costs of operations. */
-/* A part of a C `switch' statement that describes the relative costs
- of constant RTL expressions. It must contain `case' labels for
- expression codes `const_int', `const', `symbol_ref', `label_ref'
- and `const_double'. Each case must ultimately reach a `return'
- statement to return the relative cost of the use of that kind of
- constant value in an expression. The cost may depend on the
- precise value of the constant, which is available for examination
- in X, and the rtx code of the expression in which it is contained,
- found in OUTER_CODE.
-
- CODE is the expression code--redundant, since it can be obtained
- with `GET_CODE (X)'. */
-/* Force_const_mem does not work out of reload, because the saveable_obstack
- is set to reload_obstack, which does not live long enough.
- Because of this we cannot use force_const_mem in addsi3.
- This leads to problems with gen_add2_insn with a constant greater
- than a short. Because of that we give an addition of greater
- constants a cost of 3 (reload1.c 10096). */
-
-#define CONST_COSTS(RTX, CODE, OUTER_CODE) \
- case CONST: \
- if ((GET_CODE (XEXP (RTX, 0)) == MINUS) && \
- (GET_CODE (XEXP (XEXP (RTX, 0), 1)) != CONST_INT)) \
- return 1000; \
- case CONST_INT: \
- if ((OUTER_CODE == PLUS) && \
- ((INTVAL (RTX) > 32767) || \
- (INTVAL (RTX) < -32768))) \
- return COSTS_N_INSNS (3); \
- case LABEL_REF: \
- case SYMBOL_REF: \
- case CONST_DOUBLE: \
- return 0; \
-
-
-/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
- This can be used, for example, to indicate how costly a multiply
- instruction is. In writing this macro, you can use the construct
- `COSTS_N_INSNS (N)' to specify a cost equal to N fast
- instructions. OUTER_CODE is the code of the expression in which X
- is contained. */
-
-#define RTX_COSTS(X, CODE, OUTER_CODE) \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- case PLUS: \
- case AND: \
- case IOR: \
- case XOR: \
- case MINUS: \
- case NEG: \
- case NOT: \
- return COSTS_N_INSNS (1); \
- case MULT: \
- if (GET_MODE (XEXP (X, 0)) == DImode) \
- return COSTS_N_INSNS (40); \
- else \
- return COSTS_N_INSNS (7); \
- case DIV: \
- case UDIV: \
- case MOD: \
- case UMOD: \
- return COSTS_N_INSNS (33);
-
-
-/* An expression giving the cost of an addressing mode that contains
- ADDRESS. If not defined, the cost is computed from the ADDRESS
- expression and the `CONST_COSTS' values. */
-#define ADDRESS_COST(RTX) s390_address_cost ((RTX))
-
/* On s390, copy between fprs and gprs is expensive. */
#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
(( ( reg_classes_intersect_p ((CLASS1), GENERAL_REGS) \
@@ -925,7 +925,7 @@ extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
/* Position independent code. */
-extern int flag_pic;
+extern int flag_pic;
#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 12 : INVALID_REGNUM)
@@ -950,26 +950,11 @@ extern int flag_pic;
/* Advance the location counter by SIZE bytes. */
#define ASM_OUTPUT_SKIP(FILE, SIZE) \
- fprintf ((FILE), "\t.set\t.,.+%u\n", (SIZE))
-
-/* Output a reference to a user-level label named NAME. */
-#define ASM_OUTPUT_LABELREF(FILE, NAME) \
- asm_fprintf ((FILE), "%U%s", (*targetm.strip_name_encoding) (NAME))
-
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable named NAME.
- LABELNO is an integer which is different for each call. */
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
- ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+ fprintf ((FILE), "\t.set\t.,.+"HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
/* The LOCAL_LABEL_PREFIX variable is used by dbxelf.h. */
#define LOCAL_LABEL_PREFIX "."
-/* Either simplify a location expression, or return the original. */
-#define ASM_SIMPLIFY_DWARF_ADDR(X) \
- s390_simplify_dwarf_addr (X)
-
/* How to refer to registers in assembler output. This sequence is
indexed by compiler's hard-register-number (see above). */
#define REGISTER_NAMES \
@@ -980,6 +965,13 @@ extern int flag_pic;
"%ap", "%cc", "%fp" \
}
+/* Emit a dtp-relative reference to a TLS variable. */
+
+#ifdef HAVE_AS_TLS
+#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
+ s390_output_dwarf_dtprel (FILE, SIZE, X)
+#endif
+
/* Print operand X (an rtx) in assembler syntax to file FILE. */
#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
@@ -1008,71 +1000,13 @@ do { \
} while (0)
-/* Constant Pool for all symbols operands which are changed with
- force_const_mem during insn generation (expand_insn). */
-
-extern int s390_pool_count;
-extern int s390_nr_constants;
-
-#define ASM_OUTPUT_POOL_PROLOGUE(FILE, FUNNAME, fndecl, size) \
-{ \
- struct pool_constant *pool; \
- \
- if (s390_pool_count == -1) \
- { \
- s390_nr_constants = 0; \
- for (pool = first_pool; pool; pool = pool->next) \
- if (pool->mark) s390_nr_constants++; \
- return; \
- } \
-}
-
-#define ASM_OUTPUT_SPECIAL_POOL_ENTRY(FILE, EXP, MODE, ALIGN, LABELNO, WIN) \
-{ \
- fprintf (FILE, ".LC%d:\n", LABELNO); \
- \
- /* Output the value of the constant itself. */ \
- switch (GET_MODE_CLASS (MODE)) \
- { \
- case MODE_FLOAT: \
- if (GET_CODE (EXP) != CONST_DOUBLE) \
- abort (); \
- \
- REAL_VALUE_FROM_CONST_DOUBLE (r, EXP); \
- assemble_real (r, MODE, ALIGN); \
- break; \
- \
- case MODE_INT: \
- case MODE_PARTIAL_INT: \
- if (GET_CODE (EXP) == CONST \
- || GET_CODE (EXP) == SYMBOL_REF \
- || GET_CODE (EXP) == LABEL_REF) \
- { \
- fputs (integer_asm_op (UNITS_PER_WORD, TRUE), FILE); \
- s390_output_symbolic_const (FILE, EXP); \
- fputc ('\n', (FILE)); \
- } \
- else \
- { \
- assemble_integer (EXP, GET_MODE_SIZE (MODE), ALIGN, 1); \
- if (GET_MODE_SIZE (MODE) == 1) \
- ASM_OUTPUT_SKIP ((FILE), 1); \
- } \
- break; \
- \
- default: \
- abort (); \
- } \
- goto WIN; \
-}
-
-
/* Miscellaneous parameters. */
/* Define the codes that are matched by predicates in aux-output.c. */
#define PREDICATE_CODES \
{"s_operand", { SUBREG, MEM }}, \
{"s_imm_operand", { CONST_INT, CONST_DOUBLE, SUBREG, MEM }}, \
+ {"shift_count_operand", { REG, SUBREG, PLUS, CONST_INT }}, \
{"bras_sym_operand",{ SYMBOL_REF, CONST }}, \
{"larl_operand", { SYMBOL_REF, CONST, CONST_INT, CONST_DOUBLE }}, \
{"load_multiple_operation", {PARALLEL}}, \
@@ -1080,20 +1014,14 @@ extern int s390_nr_constants;
{"const0_operand", { CONST_INT, CONST_DOUBLE }}, \
{"consttable_operand", { SYMBOL_REF, LABEL_REF, CONST, \
CONST_INT, CONST_DOUBLE }}, \
- {"s390_plus_operand", { PLUS }},
+ {"s390_plus_operand", { PLUS }}, \
+ {"s390_alc_comparison", { LTU, GTU, LEU, GEU }}, \
+ {"s390_slb_comparison", { LTU, GTU, LEU, GEU }},
/* Specify the machine mode that this machine uses for the index in the
tablejump instruction. */
#define CASE_VECTOR_MODE (TARGET_64BIT ? DImode : SImode)
-/* Load from integral MODE < SI from memory into register makes sign_extend
- or zero_extend
- In our case sign_extension happens for Halfwords, other no extension. */
-#define LOAD_EXTEND_OP(MODE) \
-(TARGET_64BIT ? ((MODE) == QImode ? ZERO_EXTEND : \
- (MODE) == HImode ? SIGN_EXTEND : NIL) \
- : ((MODE) == HImode ? SIGN_EXTEND : NIL))
-
/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
is done just by pretending it is already truncated. */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
@@ -1103,6 +1031,9 @@ extern int s390_nr_constants;
between pointers and any other objects of this machine mode. */
#define Pmode ((enum machine_mode) (TARGET_64BIT ? DImode : SImode))
+/* This is -1 for "pointer mode" extend. See ptr_extend in s390.md. */
+#define POINTERS_EXTEND_UNSIGNED -1
+
/* A function address in a call instruction is a byte address (for
indexing purposes) so give the MEM rtx a byte's mode. */
#define FUNCTION_MODE QImode
@@ -1110,10 +1041,4 @@ extern int s390_nr_constants;
/* This macro definition sets up a default value for `main' to return. */
#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
-/* In rare cases, correct code generation requires extra machine dependent
- processing between the second jump optimization pass and delayed branch
- scheduling. On those machines, define this macro as a C statement to act on
- the code starting at INSN. */
-#define MACHINE_DEPENDENT_REORG(INSN) s390_machine_dependent_reorg (INSN)
-
-#endif
+#endif
diff --git a/contrib/gcc/config/s390/s390.md b/contrib/gcc/config/s390/s390.md
index 817851651f20..ebb8b5729929 100644
--- a/contrib/gcc/config/s390/s390.md
+++ b/contrib/gcc/config/s390/s390.md
@@ -1,23 +1,25 @@
;;- Machine description for GNU compiler -- S/390 / zSeries version.
-;; Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+;; Free Software Foundation, Inc.
;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
;; Ulrich Weigand (uweigand@de.ibm.com).
-;; This file is part of GNU CC.
-;; GNU CC 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 file is part of GCC.
-;; GNU CC 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.
+;; 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 2, 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 GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING. If not, write to the Free
+;; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
;;
;; Special constraints for s/390 machine description:
@@ -27,17 +29,42 @@
;; I -- An 8-bit constant (0..255).
;; J -- A 12-bit constant (0..4095).
;; K -- A 16-bit constant (-32768..32767).
-;; Q -- A memory reference without index-register.
-;; S -- Valid operand for the LARL instruction.
+;; L -- Value appropriate as displacement.
+;; (0..4095) for short displacement
+;; (-524288..524287) for long displacement
+;; M -- Constant integer with a value of 0x7fffffff.
+;; N -- Multiple letter constraint followed by 4 parameter letters.
+;; 0..9: number of the part counting from most to least significant
+;; H,Q: mode of the part
+;; D,S,H: mode of the containing operand
+;; 0,F: value of the other parts (F - all bits set)
+;;
+;; The constraint matches if the specified part of a constant
+;; has a value different from its other parts.
+;; Q -- Memory reference without index register and with short displacement.
+;; R -- Memory reference with index register and short displacement.
+;; S -- Memory reference without index register but with long displacement.
+;; T -- Memory reference with index register and long displacement.
+;; U -- Pointer with short displacement.
+;; W -- Pointer with long displacement.
+;; Y -- Shift count operand.
;;
;; Special formats used for outputting 390 instructions.
;;
-;; %b -- Print a constant byte integer. xy
-;; %h -- Print a signed 16-bit. wxyz
-;; %N -- Print next register (second word of a DImode reg) or next word.
-;; %M -- Print next register (second word of a TImode reg) or next word.
-;; %O -- Print the offset of a memory reference (PLUS (REG) (CONST_INT)).
-;; %R -- Print the register of a memory reference (PLUS (REG) (CONST_INT)).
+;; %C: print opcode suffix for branch condition.
+;; %D: print opcode suffix for inverse branch condition.
+;; %J: print tls_load/tls_gdcall/tls_ldcall suffix
+;; %O: print only the displacement of a memory reference.
+;; %R: print only the base register of a memory reference.
+;; %N: print the second word of a DImode operand.
+;; %M: print the second word of a TImode operand.
+
+;; %b: print integer X as if it's an unsigned byte.
+;; %x: print integer X as if it's an unsigned word.
+;; %h: print integer X as if it's a signed word.
+;; %i: print the first nonzero HImode part of X
+;; %j: print the first HImode part unequal to 0xffff of X
+
;;
;; We have a special constraint for pattern matching.
;;
@@ -49,7 +76,24 @@
;;
(define_constants
- [; TLS relocation specifiers
+ [; Miscellaneous
+ (UNSPEC_ROUND 1)
+ (UNSPEC_SETHIGH 10)
+
+ ; GOT/PLT and lt-relative accesses
+ (UNSPEC_LTREL_OFFSET 100)
+ (UNSPEC_LTREL_BASE 101)
+ (UNSPEC_GOTENT 110)
+ (UNSPEC_GOT 111)
+ (UNSPEC_GOTOFF 112)
+ (UNSPEC_PLT 113)
+ (UNSPEC_PLTOFF 114)
+
+ ; Literal pool
+ (UNSPEC_RELOAD_BASE 210)
+ (UNSPEC_MAIN_BASE 211)
+
+ ; TLS relocation specifiers
(UNSPEC_TLSGD 500)
(UNSPEC_TLSLDM 501)
(UNSPEC_NTPOFF 502)
@@ -61,6 +105,9 @@
(UNSPEC_TP 510)
(UNSPEC_TLSLDM_NTPOFF 511)
(UNSPEC_TLS_LOAD 512)
+
+ ; String Functions
+ (UNSPEC_SRST 600)
])
;;
@@ -68,25 +115,70 @@
;;
(define_constants
- [; TLS support
+ [; Blockage
+ (UNSPECV_BLOCKAGE 0)
+
+ ; Literal pool
+ (UNSPECV_POOL 200)
+ (UNSPECV_POOL_START 201)
+ (UNSPECV_POOL_END 202)
+ (UNSPECV_POOL_ENTRY 203)
+ (UNSPECV_MAIN_POOL 300)
+
+ ; TLS support
(UNSPECV_SET_TP 500)
])
+;; Processor type. This attribute must exactly match the processor_type
+;; enumeration in s390.h.
+
+(define_attr "cpu" "g5,g6,z900,z990"
+ (const (symbol_ref "s390_tune")))
+
;; Define an insn type attribute. This is used in function unit delay
;; computations.
-(define_attr "type" "none,integer,load,lr,la,lm,stm,cs,vs,store,imul,lmul,fmul,idiv,ldiv,fdiv,branch,jsr,other,o2,o3"
+(define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
+ cs,vs,store,imul,idiv,
+ branch,jsr,fsimpd,fsimps,
+ floadd,floads,fstored, fstores,
+ fmuld,fmuls,fdivd,fdivs,
+ ftoi,itof,fsqrtd,fsqrts,
+ other,o2,o3"
(const_string "integer"))
-;; Insn are devide in two classes:
-;; mem: Insn accessing memory
-;; reg: Insn operands all in registers
+;; Operand type. Used to default length attribute values
-(define_attr "atype" "reg,mem"
- (const_string "reg"))
+(define_attr "op_type"
+ "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY"
+ (const_string "RX"))
-;; Generic pipeline function unit.
+;; Insn are devide in two classes:
+;; agen: Insn using agen
+;; reg: Insn not using agen
+
+(define_attr "atype" "agen,reg"
+(cond [ (eq_attr "op_type" "E") (const_string "reg")
+ (eq_attr "op_type" "RR") (const_string "reg")
+ (eq_attr "op_type" "RX") (const_string "agen")
+ (eq_attr "op_type" "RI") (const_string "reg")
+ (eq_attr "op_type" "RRE") (const_string "reg")
+ (eq_attr "op_type" "RS") (const_string "agen")
+ (eq_attr "op_type" "RSI") (const_string "agen")
+ (eq_attr "op_type" "S") (const_string "agen")
+ (eq_attr "op_type" "SI") (const_string "agen")
+ (eq_attr "op_type" "SS") (const_string "agen")
+ (eq_attr "op_type" "SSE") (const_string "agen")
+ (eq_attr "op_type" "RXE") (const_string "agen")
+ (eq_attr "op_type" "RSE") (const_string "agen")
+ (eq_attr "op_type" "RIL") (const_string "agen")
+ (eq_attr "op_type" "RXY") (const_string "agen")
+ (eq_attr "op_type" "RSY") (const_string "agen")
+ (eq_attr "op_type" "SIY") (const_string "agen")]
+ (const_string "reg")))
+
+;; Generic pipeline function unit.
(define_function_unit "integer" 1 0
(eq_attr "type" "none") 0 0)
@@ -95,18 +187,42 @@
(eq_attr "type" "integer") 1 1)
(define_function_unit "integer" 1 0
+ (eq_attr "type" "fsimpd") 1 1)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fsimps") 1 1)
+
+(define_function_unit "integer" 1 0
(eq_attr "type" "load") 1 1)
(define_function_unit "integer" 1 0
+ (eq_attr "type" "floadd") 1 1)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "floads") 1 1)
+
+(define_function_unit "integer" 1 0
(eq_attr "type" "la") 1 1)
(define_function_unit "integer" 1 0
+ (eq_attr "type" "larl") 1 1)
+
+(define_function_unit "integer" 1 0
(eq_attr "type" "lr") 1 1)
(define_function_unit "integer" 1 0
+ (eq_attr "type" "branch") 1 1)
+
+(define_function_unit "integer" 1 0
(eq_attr "type" "store") 1 1)
(define_function_unit "integer" 1 0
+ (eq_attr "type" "fstored") 1 1)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fstores") 1 1)
+
+(define_function_unit "integer" 1 0
(eq_attr "type" "lm") 2 2)
(define_function_unit "integer" 1 0
@@ -125,13 +241,31 @@
(eq_attr "type" "imul") 7 7)
(define_function_unit "integer" 1 0
- (eq_attr "type" "fmul") 6 6)
+ (eq_attr "type" "fmuld") 6 6)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fmuls") 6 6)
(define_function_unit "integer" 1 0
(eq_attr "type" "idiv") 33 33)
(define_function_unit "integer" 1 0
- (eq_attr "type" "fdiv") 33 33)
+ (eq_attr "type" "fdivd") 33 33)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fdivs") 33 33)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fsqrtd") 30 30)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fsqrts") 30 30)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "ftoi") 2 2)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "itof") 2 2)
(define_function_unit "integer" 1 0
(eq_attr "type" "o2") 2 2)
@@ -142,11 +276,10 @@
(define_function_unit "integer" 1 0
(eq_attr "type" "other") 5 5)
-;; Operand type. Used to default length attribute values
+;; Pipeline description for z900
-(define_attr "op_type"
- "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE"
- (const_string "RX"))
+(include "2064.md")
+(include "2084.md")
;; Length in bytes.
@@ -158,14 +291,16 @@
(eq_attr "op_type" "RRE") (const_int 4)
(eq_attr "op_type" "RS") (const_int 4)
(eq_attr "op_type" "RSI") (const_int 4)
- (eq_attr "op_type" "RX") (const_int 4)
(eq_attr "op_type" "S") (const_int 4)
(eq_attr "op_type" "SI") (const_int 4)
(eq_attr "op_type" "SS") (const_int 6)
(eq_attr "op_type" "SSE") (const_int 6)
(eq_attr "op_type" "RXE") (const_int 6)
(eq_attr "op_type" "RSE") (const_int 6)
- (eq_attr "op_type" "RIL") (const_int 6)]
+ (eq_attr "op_type" "RIL") (const_int 6)
+ (eq_attr "op_type" "RXY") (const_int 6)
+ (eq_attr "op_type" "RSY") (const_int 6)
+ (eq_attr "op_type" "SIY") (const_int 6)]
(const_int 4)))
;; Define attributes for `asm' insns.
@@ -182,11 +317,11 @@
; CCU: Equal ULess UGreater -- (CL, CLR, CLI, CLM)
; CCS: Equal SLess SGreater -- (C, CR, CH, CHI, ICM)
; CCT: Zero Mixed Mixed Ones (TM, TMH, TML)
-
+
; CCZ -> CCL / CCZ1
; CCZ1 -> CCA/CCU/CCS/CCT
; CCS -> CCA
-
+
; String: CLC, CLCL, CLCLE, CLST, CUSE, MVCL, MVCLE, MVPG, MVST, SRST
; Clobber: CKSM, CFC, CS, CDS, CUUTF, CUTFU, PLO, SPM, STCK, STCKE, TS, TRT, TRE, UPT
@@ -200,48 +335,44 @@
(compare:CC (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "general_operand" "")))]
"TARGET_64BIT"
- "
{
s390_compare_op0 = operands[0];
s390_compare_op1 = operands[1];
DONE;
-}")
+})
(define_expand "cmpsi"
[(set (reg:CC 33)
(compare:CC (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "general_operand" "")))]
""
- "
{
s390_compare_op0 = operands[0];
s390_compare_op1 = operands[1];
DONE;
-}")
+})
(define_expand "cmpdf"
[(set (reg:CC 33)
(compare:CC (match_operand:DF 0 "register_operand" "")
(match_operand:DF 1 "general_operand" "")))]
"TARGET_HARD_FLOAT"
- "
{
s390_compare_op0 = operands[0];
s390_compare_op1 = operands[1];
DONE;
-}")
+})
(define_expand "cmpsf"
[(set (reg:CC 33)
(compare:CC (match_operand:SF 0 "register_operand" "")
(match_operand:SF 1 "general_operand" "")))]
"TARGET_HARD_FLOAT"
- "
{
s390_compare_op0 = operands[0];
s390_compare_op1 = operands[1];
DONE;
-}")
+})
; Test-under-Mask (zero_extract) instructions
@@ -253,11 +384,10 @@
(match_operand:DI 2 "const_int_operand" "n"))
(const_int 0)))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
- && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
+ && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
&& INTVAL (operands[1]) + INTVAL (operands[2]) <= 64
&& (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4
== INTVAL (operands[2]) >> 4"
- "*
{
int part = INTVAL (operands[2]) >> 4;
int block = (1 << INTVAL (operands[1])) - 1;
@@ -267,13 +397,13 @@
switch (part)
{
- case 0: return \"tmhh\\t%0,%x2\";
- case 1: return \"tmhl\\t%0,%x2\";
- case 2: return \"tmlh\\t%0,%x2\";
- case 3: return \"tmll\\t%0,%x2\";
+ case 0: return "tmhh\t%0,%x2";
+ case 1: return "tmhl\t%0,%x2";
+ case 2: return "tmlh\t%0,%x2";
+ case 3: return "tmll\t%0,%x2";
default: abort ();
}
-}"
+}
[(set_attr "op_type" "RI")])
(define_insn "*tmsi_ext"
@@ -283,11 +413,10 @@
(match_operand:SI 2 "const_int_operand" "n"))
(const_int 0)))]
"s390_match_ccmode(insn, CCTmode)
- && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
+ && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
&& INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
&& (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4
== INTVAL (operands[2]) >> 4"
- "*
{
int part = INTVAL (operands[2]) >> 4;
int block = (1 << INTVAL (operands[1])) - 1;
@@ -297,146 +426,140 @@
switch (part)
{
- case 0: return \"tmh\\t%0,%x2\";
- case 1: return \"tml\\t%0,%x2\";
+ case 0: return "tmh\t%0,%x2";
+ case 1: return "tml\t%0,%x2";
default: abort ();
}
-}"
+}
[(set_attr "op_type" "RI")])
-(define_insn "*tmqi_ext"
+(define_insn "*tmqisi_ext"
[(set (reg 33)
- (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q")
- (match_operand:SI 1 "const_int_operand" "n")
- (match_operand:SI 2 "const_int_operand" "n"))
+ (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,S")
+ (match_operand:SI 1 "const_int_operand" "n,n")
+ (match_operand:SI 2 "const_int_operand" "n,n"))
(const_int 0)))]
- "s390_match_ccmode(insn, CCTmode)
- && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
+ "!TARGET_64BIT && s390_match_ccmode(insn, CCTmode)
+ && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
&& INTVAL (operands[1]) + INTVAL (operands[2]) <= 8"
- "*
{
int block = (1 << INTVAL (operands[1])) - 1;
int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]);
operands[2] = GEN_INT (block << shift);
- return \"tm\\t%0,%b2\";
-}"
- [(set_attr "op_type" "SI")
- (set_attr "atype" "mem")])
+ return which_alternative == 0 ? "tm\t%0,%b2" : "tmy\t%0,%b2";
+}
+ [(set_attr "op_type" "SI,SIY")])
+
+(define_insn "*tmqidi_ext"
+ [(set (reg 33)
+ (compare (zero_extract:DI (match_operand:QI 0 "memory_operand" "Q,S")
+ (match_operand:SI 1 "const_int_operand" "n,n")
+ (match_operand:SI 2 "const_int_operand" "n,n"))
+ (const_int 0)))]
+ "TARGET_64BIT && s390_match_ccmode(insn, CCTmode)
+ && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
+ && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8"
+{
+ int block = (1 << INTVAL (operands[1])) - 1;
+ int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]);
+
+ operands[2] = GEN_INT (block << shift);
+ return which_alternative == 0 ? "tm\t%0,%b2" : "tmy\t%0,%b2";
+}
+ [(set_attr "op_type" "SI,SIY")])
+
; Test-under-Mask instructions
(define_insn "*tmdi_mem"
[(set (reg 33)
- (compare (and:DI (match_operand:DI 0 "memory_operand" "Q")
- (match_operand:DI 1 "immediate_operand" "n"))
- (match_operand:DI 2 "immediate_operand" "n")))]
- "TARGET_64BIT
- && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
- && s390_single_qi (operands[1], DImode, 0) >= 0"
- "*
+ (compare (and:DI (match_operand:DI 0 "memory_operand" "Q,S")
+ (match_operand:DI 1 "immediate_operand" "n,n"))
+ (match_operand:DI 2 "immediate_operand" "n,n")))]
+ "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
+ && s390_single_part (operands[1], DImode, QImode, 0) >= 0"
{
- int part = s390_single_qi (operands[1], DImode, 0);
- operands[1] = GEN_INT (s390_extract_qi (operands[1], DImode, part));
+ int part = s390_single_part (operands[1], DImode, QImode, 0);
+ operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0));
- operands[0] = gen_rtx_MEM (QImode,
+ operands[0] = gen_rtx_MEM (QImode,
plus_constant (XEXP (operands[0], 0), part));
- return \"tm\\t%0,%b1\";
-}"
- [(set_attr "op_type" "SI")
- (set_attr "atype" "mem")])
+ return which_alternative == 0 ? "tm\t%0,%b1" : "tmy\t%0,%b1";
+}
+ [(set_attr "op_type" "SI,SIY")])
(define_insn "*tmsi_mem"
[(set (reg 33)
- (compare (and:SI (match_operand:SI 0 "memory_operand" "Q")
- (match_operand:SI 1 "immediate_operand" "n"))
- (match_operand:SI 2 "immediate_operand" "n")))]
+ (compare (and:SI (match_operand:SI 0 "memory_operand" "Q,S")
+ (match_operand:SI 1 "immediate_operand" "n,n"))
+ (match_operand:SI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
- && s390_single_qi (operands[1], SImode, 0) >= 0"
- "*
+ && s390_single_part (operands[1], SImode, QImode, 0) >= 0"
{
- int part = s390_single_qi (operands[1], SImode, 0);
- operands[1] = GEN_INT (s390_extract_qi (operands[1], SImode, part));
+ int part = s390_single_part (operands[1], SImode, QImode, 0);
+ operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0));
- operands[0] = gen_rtx_MEM (QImode,
+ operands[0] = gen_rtx_MEM (QImode,
plus_constant (XEXP (operands[0], 0), part));
- return \"tm\\t%0,%b1\";
-}"
- [(set_attr "op_type" "SI")
- (set_attr "atype" "mem")])
+ return which_alternative == 0 ? "tm\t%0,%b1" : "tmy\t%0,%b1";
+}
+ [(set_attr "op_type" "SI")])
(define_insn "*tmhi_mem"
[(set (reg 33)
- (compare (and:SI (subreg:SI (match_operand:HI 0 "memory_operand" "Q") 0)
- (match_operand:SI 1 "immediate_operand" "n"))
- (match_operand:SI 2 "immediate_operand" "n")))]
+ (compare (and:SI (subreg:SI (match_operand:HI 0 "memory_operand" "Q,S") 0)
+ (match_operand:SI 1 "immediate_operand" "n,n"))
+ (match_operand:SI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
- && s390_single_qi (operands[1], HImode, 0) >= 0"
- "*
+ && s390_single_part (operands[1], HImode, QImode, 0) >= 0"
{
- int part = s390_single_qi (operands[1], HImode, 0);
- operands[1] = GEN_INT (s390_extract_qi (operands[1], HImode, part));
+ int part = s390_single_part (operands[1], HImode, QImode, 0);
+ operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0));
- operands[0] = gen_rtx_MEM (QImode,
+ operands[0] = gen_rtx_MEM (QImode,
plus_constant (XEXP (operands[0], 0), part));
- return \"tm\\t%0,%b1\";
-}"
- [(set_attr "op_type" "SI")
- (set_attr "atype" "mem")])
+ return which_alternative == 0 ? "tm\t%0,%b1" : "tmy\t%0,%b1";
+}
+ [(set_attr "op_type" "SI")])
(define_insn "*tmqi_mem"
[(set (reg 33)
- (compare (and:SI (subreg:SI (match_operand:QI 0 "memory_operand" "Q") 0)
- (match_operand:SI 1 "immediate_operand" "n"))
- (match_operand:SI 2 "immediate_operand" "n")))]
+ (compare (and:SI (subreg:SI (match_operand:QI 0 "memory_operand" "Q,S") 0)
+ (match_operand:SI 1 "immediate_operand" "n,n"))
+ (match_operand:SI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))"
- "tm\\t%0,%b1"
- [(set_attr "op_type" "SI")
- (set_attr "atype" "mem")])
+ "@
+ tm\t%0,%b1
+ tmy\t%0,%b1"
+ [(set_attr "op_type" "SI,SIY")])
(define_insn "*tmdi_reg"
[(set (reg 33)
- (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d")
- (match_operand:DI 1 "immediate_operand" "n"))
- (match_operand:DI 2 "immediate_operand" "n")))]
+ (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
+ (match_operand:DI 1 "immediate_operand"
+ "N0HD0,N1HD0,N2HD0,N3HD0"))
+ (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
"TARGET_64BIT
&& s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1))
- && s390_single_hi (operands[1], DImode, 0) >= 0"
- "*
-{
- int part = s390_single_hi (operands[1], DImode, 0);
- operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));
-
- switch (part)
- {
- case 0: return \"tmhh\\t%0,%x1\";
- case 1: return \"tmhl\\t%0,%x1\";
- case 2: return \"tmlh\\t%0,%x1\";
- case 3: return \"tmll\\t%0,%x1\";
- default: abort ();
- }
-}"
+ && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
+ "@
+ tmhh\t%0,%i1
+ tmhl\t%0,%i1
+ tmlh\t%0,%i1
+ tmll\t%0,%i1"
[(set_attr "op_type" "RI")])
(define_insn "*tmsi_reg"
[(set (reg 33)
- (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d")
- (match_operand:SI 1 "immediate_operand" "n"))
- (match_operand:SI 2 "immediate_operand" "n")))]
+ (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
+ (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
+ (match_operand:SI 2 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1))
- && s390_single_hi (operands[1], SImode, 0) >= 0"
- "*
-{
- int part = s390_single_hi (operands[1], SImode, 0);
- operands[1] = GEN_INT (s390_extract_hi (operands[1], SImode, part));
-
- switch (part)
- {
- case 0: return \"tmh\\t%0,%x1\";
- case 1: return \"tml\\t%0,%x1\";
- default: abort ();
- }
-}"
+ && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
+ "@
+ tmh\t%0,%i1
+ tml\t%0,%i1"
[(set_attr "op_type" "RI")])
(define_insn "*tmhi_full"
@@ -444,7 +567,7 @@
(compare (match_operand:HI 0 "register_operand" "d")
(match_operand:HI 1 "immediate_operand" "n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (GEN_INT (-1), operands[1], 1))"
- "tml\\t%0,65535"
+ "tml\t%0,65535"
[(set_attr "op_type" "RX")])
(define_insn "*tmqi_full"
@@ -452,7 +575,7 @@
(compare (match_operand:QI 0 "register_operand" "d")
(match_operand:QI 1 "immediate_operand" "n")))]
"s390_match_ccmode (insn, s390_tm_ccmode (GEN_INT (-1), operands[1], 1))"
- "tml\\t%0,255"
+ "tml\t%0,255"
[(set_attr "op_type" "RI")])
@@ -466,7 +589,7 @@
(set (match_operand:DI 2 "register_operand" "=d")
(sign_extend:DI (match_dup 0)))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
- "ltgfr\\t%2,%0"
+ "ltgfr\t%2,%0"
[(set_attr "op_type" "RRE")])
(define_insn "*tstdi"
@@ -476,7 +599,7 @@
(set (match_operand:DI 2 "register_operand" "=d")
(match_dup 0))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
- "ltgr\\t%2,%0"
+ "ltgr\t%2,%0"
[(set_attr "op_type" "RRE")])
(define_insn "*tstdi_cconly"
@@ -484,7 +607,7 @@
(compare (match_operand:DI 0 "register_operand" "d")
(match_operand:DI 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
- "ltgr\\t%0,%0"
+ "ltgr\t%0,%0"
[(set_attr "op_type" "RRE")])
(define_insn "*tstdi_cconly_31"
@@ -492,132 +615,138 @@
(compare (match_operand:DI 0 "register_operand" "d")
(match_operand:DI 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode) && !TARGET_64BIT"
- "srda\\t%0,0"
- [(set_attr "op_type" "RS")])
+ "srda\t%0,0"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
+
(define_insn "*tstsi"
[(set (reg 33)
- (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q")
+ (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
(match_operand:SI 1 "const0_operand" "")))
- (set (match_operand:SI 2 "register_operand" "=d,d")
+ (set (match_operand:SI 2 "register_operand" "=d,d,d")
(match_dup 0))]
"s390_match_ccmode(insn, CCSmode)"
"@
- ltr\\t%2,%0
- icm\\t%2,15,%0"
- [(set_attr "op_type" "RR,RS")
- (set_attr "atype" "reg,mem")])
+ ltr\t%2,%0
+ icm\t%2,15,%0
+ icmy\t%2,15,%0"
+ [(set_attr "op_type" "RR,RS,RSY")])
(define_insn "*tstsi_cconly"
[(set (reg 33)
- (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q")
+ (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
(match_operand:SI 1 "const0_operand" "")))
- (clobber (match_scratch:SI 2 "=X,d"))]
+ (clobber (match_scratch:SI 2 "=X,d,d"))]
"s390_match_ccmode(insn, CCSmode)"
"@
- ltr\\t%0,%0
- icm\\t%2,15,%0"
- [(set_attr "op_type" "RR,RS")
- (set_attr "atype" "reg,mem")])
+ ltr\t%0,%0
+ icm\t%2,15,%0
+ icmy\t%2,15,%0"
+ [(set_attr "op_type" "RR,RS,RSY")])
(define_insn "*tstsi_cconly2"
[(set (reg 33)
(compare (match_operand:SI 0 "register_operand" "d")
(match_operand:SI 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode)"
- "ltr\\t%0,%0"
+ "ltr\t%0,%0"
[(set_attr "op_type" "RR")])
(define_insn "*tsthiCCT"
[(set (reg 33)
- (compare (match_operand:HI 0 "nonimmediate_operand" "?Q,d")
+ (compare (match_operand:HI 0 "nonimmediate_operand" "?Q,?S,d")
(match_operand:HI 1 "const0_operand" "")))
- (set (match_operand:HI 2 "register_operand" "=d,0")
+ (set (match_operand:HI 2 "register_operand" "=d,d,0")
(match_dup 0))]
"s390_match_ccmode(insn, CCTmode)"
"@
- icm\\t%2,3,%0
- tml\\t%0,65535"
- [(set_attr "op_type" "RS,RI")
- (set_attr "atype" "mem,reg")])
+ icm\t%2,3,%0
+ icmy\t%2,3,%0
+ tml\t%0,65535"
+ [(set_attr "op_type" "RS,RSY,RI")])
(define_insn "*tsthiCCT_cconly"
[(set (reg 33)
- (compare (match_operand:HI 0 "nonimmediate_operand" "Q,d")
+ (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
(match_operand:HI 1 "const0_operand" "")))
- (clobber (match_scratch:HI 2 "=d,X"))]
+ (clobber (match_scratch:HI 2 "=d,d,X"))]
"s390_match_ccmode(insn, CCTmode)"
"@
- icm\\t%2,3,%0
- tml\\t%0,65535"
- [(set_attr "op_type" "RS,RI")
- (set_attr "atype" "mem,reg")])
+ icm\t%2,3,%0
+ icmy\t%2,3,%0
+ tml\t%0,65535"
+ [(set_attr "op_type" "RS,RSY,RI")])
(define_insn "*tsthi"
[(set (reg 33)
- (compare (match_operand:HI 0 "s_operand" "Q")
+ (compare (match_operand:HI 0 "s_operand" "Q,S")
(match_operand:HI 1 "const0_operand" "")))
- (set (match_operand:HI 2 "register_operand" "=d")
+ (set (match_operand:HI 2 "register_operand" "=d,d")
(match_dup 0))]
"s390_match_ccmode(insn, CCSmode)"
- "icm\\t%2,3,%0"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%2,3,%0
+ icmy\t%2,3,%0"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*tsthi_cconly"
[(set (reg 33)
- (compare (match_operand:HI 0 "s_operand" "Q")
+ (compare (match_operand:HI 0 "s_operand" "Q,S")
(match_operand:HI 1 "const0_operand" "")))
- (clobber (match_scratch:HI 2 "=d"))]
+ (clobber (match_scratch:HI 2 "=d,d"))]
"s390_match_ccmode(insn, CCSmode)"
- "icm\\t%2,3,%0"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%2,3,%0
+ icmy\t%2,3,%0"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*tstqiCCT"
[(set (reg 33)
- (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,d")
+ (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
(match_operand:QI 1 "const0_operand" "")))
- (set (match_operand:QI 2 "register_operand" "=d,0")
+ (set (match_operand:QI 2 "register_operand" "=d,d,0")
(match_dup 0))]
"s390_match_ccmode(insn, CCTmode)"
"@
- icm\\t%2,1,%0
- tml\\t%0,255"
- [(set_attr "op_type" "RS,RI")
- (set_attr "atype" "mem,reg")])
+ icm\t%2,1,%0
+ icmy\t%2,1,%0
+ tml\t%0,255"
+ [(set_attr "op_type" "RS,RSY,RI")])
(define_insn "*tstqiCCT_cconly"
[(set (reg 33)
- (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,d")
+ (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
(match_operand:QI 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCTmode)"
"@
- cli\\t%0,0
- tml\\t%0,255"
- [(set_attr "op_type" "SI,RI")
- (set_attr "atype" "mem,reg")])
+ cli\t%0,0
+ cliy\t%0,0
+ tml\t%0,255"
+ [(set_attr "op_type" "SI,SIY,RI")])
(define_insn "*tstqi"
[(set (reg 33)
- (compare (match_operand:QI 0 "s_operand" "Q")
+ (compare (match_operand:QI 0 "s_operand" "Q,S")
(match_operand:QI 1 "const0_operand" "")))
- (set (match_operand:QI 2 "register_operand" "=d")
+ (set (match_operand:QI 2 "register_operand" "=d,d")
(match_dup 0))]
"s390_match_ccmode(insn, CCSmode)"
- "icm\\t%2,1,%0"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%2,1,%0
+ icmy\t%2,1,%0"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*tstqi_cconly"
[(set (reg 33)
- (compare (match_operand:QI 0 "s_operand" "Q")
+ (compare (match_operand:QI 0 "s_operand" "Q,S")
(match_operand:QI 1 "const0_operand" "")))
- (clobber (match_scratch:QI 2 "=d"))]
+ (clobber (match_scratch:QI 2 "=d,d"))]
"s390_match_ccmode(insn, CCSmode)"
- "icm\\t%2,1,%0"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%2,1,%0
+ icmy\t%2,1,%0"
+ [(set_attr "op_type" "RS,RSY")])
; Compare (signed) instructions
@@ -628,10 +757,9 @@
(match_operand:DI 0 "register_operand" "d,d")))]
"s390_match_ccmode(insn, CCSRmode) && TARGET_64BIT"
"@
- cgfr\\t%0,%1
- cgf\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ cgfr\t%0,%1
+ cgf\t%0,%1"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*cmpdi_ccs"
[(set (reg 33)
@@ -639,33 +767,33 @@
(match_operand:DI 1 "general_operand" "d,K,m")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
"@
- cgr\\t%0,%1
- cghi\\t%0,%c1
- cg\\t%0,%1"
- [(set_attr "op_type" "RRE,RI,RXE")
- (set_attr "atype" "reg,reg,mem")])
-
+ cgr\t%0,%1
+ cghi\t%0,%c1
+ cg\t%0,%1"
+ [(set_attr "op_type" "RRE,RI,RXY")])
+
(define_insn "*cmpsi_ccs_sign"
[(set (reg 33)
- (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))
- (match_operand:SI 0 "register_operand" "d")))]
+ (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T"))
+ (match_operand:SI 0 "register_operand" "d,d")))]
"s390_match_ccmode(insn, CCSRmode)"
- "ch\\t%0,%1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
+ "@
+ ch\t%0,%1
+ chy\t%0,%1"
+ [(set_attr "op_type" "RX,RXY")])
(define_insn "*cmpsi_ccs"
[(set (reg 33)
- (compare (match_operand:SI 0 "register_operand" "d,d,d")
- (match_operand:SI 1 "general_operand" "d,K,m")))]
+ (compare (match_operand:SI 0 "register_operand" "d,d,d,d")
+ (match_operand:SI 1 "general_operand" "d,K,R,T")))]
"s390_match_ccmode(insn, CCSmode)"
"@
- cr\\t%0,%1
- chi\\t%0,%c1
- c\\t%0,%1"
- [(set_attr "op_type" "RR,RI,RX")
- (set_attr "atype" "reg,reg,mem")])
-
+ cr\t%0,%1
+ chi\t%0,%c1
+ c\t%0,%1
+ cy\t%0,%1"
+ [(set_attr "op_type" "RR,RI,RX,RXY")])
+
; Compare (unsigned) instructions
@@ -675,10 +803,9 @@
(match_operand:DI 0 "register_operand" "d,d")))]
"s390_match_ccmode(insn, CCURmode) && TARGET_64BIT"
"@
- clgfr\\t%0,%1
- clgf\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ clgfr\t%0,%1
+ clgf\t%0,%1"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*cmpdi_ccu"
[(set (reg 33)
@@ -686,84 +813,82 @@
(match_operand:DI 1 "general_operand" "d,m")))]
"s390_match_ccmode(insn, CCUmode) && TARGET_64BIT"
"@
- clgr\\t%0,%1
- clg\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ clgr\t%0,%1
+ clg\t%0,%1"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*cmpsi_ccu"
[(set (reg 33)
- (compare (match_operand:SI 0 "register_operand" "d,d")
- (match_operand:SI 1 "general_operand" "d,m")))]
+ (compare (match_operand:SI 0 "register_operand" "d,d,d")
+ (match_operand:SI 1 "general_operand" "d,R,T")))]
"s390_match_ccmode(insn, CCUmode)"
"@
- clr\\t%0,%1
- cl\\t%0,%1"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ clr\t%0,%1
+ cl\t%0,%1
+ cly\t%0,%1"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*cmphi_ccu"
[(set (reg 33)
- (compare (match_operand:HI 0 "register_operand" "d")
- (match_operand:HI 1 "s_imm_operand" "Q")))]
+ (compare (match_operand:HI 0 "register_operand" "d,d")
+ (match_operand:HI 1 "s_imm_operand" "Q,S")))]
"s390_match_ccmode(insn, CCUmode)"
- "clm\\t%0,3,%1"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ clm\t%0,3,%1
+ clmy\t%0,3,%1"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*cmpqi_ccu"
[(set (reg 33)
- (compare (match_operand:QI 0 "register_operand" "d")
- (match_operand:QI 1 "s_imm_operand" "Q")))]
+ (compare (match_operand:QI 0 "register_operand" "d,d")
+ (match_operand:QI 1 "s_imm_operand" "Q,S")))]
"s390_match_ccmode(insn, CCUmode)"
- "clm\\t%0,1,%1"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ clm\t%0,1,%1
+ clmy\t%0,1,%1"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*cli"
[(set (reg 33)
- (compare (match_operand:QI 0 "memory_operand" "Q")
- (match_operand:QI 1 "immediate_operand" "n")))]
+ (compare (match_operand:QI 0 "memory_operand" "Q,S")
+ (match_operand:QI 1 "immediate_operand" "n,n")))]
"s390_match_ccmode (insn, CCUmode)"
- "cli\\t%0,%b1"
- [(set_attr "op_type" "SI")
- (set_attr "atype" "mem")])
+ "@
+ cli\t%0,%b1
+ cliy\t%0,%b1"
+ [(set_attr "op_type" "SI,SIY")])
(define_insn "*cmpdi_ccu_mem"
[(set (reg 33)
(compare (match_operand:DI 0 "s_operand" "Q")
(match_operand:DI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
- "clc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "clc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*cmpsi_ccu_mem"
[(set (reg 33)
(compare (match_operand:SI 0 "s_operand" "Q")
(match_operand:SI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
- "clc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "clc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*cmphi_ccu_mem"
[(set (reg 33)
(compare (match_operand:HI 0 "s_operand" "Q")
(match_operand:HI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
- "clc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "clc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*cmpqi_ccu_mem"
[(set (reg 33)
(compare (match_operand:QI 0 "s_operand" "Q")
(match_operand:QI 1 "s_imm_operand" "Q")))]
"s390_match_ccmode(insn, CCUmode)"
- "clc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "clc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SS")])
; DF instructions
@@ -773,38 +898,40 @@
(compare (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "ltdbr\\t%0,%0"
- [(set_attr "op_type" "RRE")])
+ "ltdbr\t%0,%0"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimpd")])
(define_insn "*cmpdf_ccs_0_ibm"
[(set (reg 33)
(compare (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "ltdr\\t%0,%0"
- [(set_attr "op_type" "RR")])
+ "ltdr\t%0,%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "fsimpd")])
(define_insn "*cmpdf_ccs"
[(set (reg 33)
(compare (match_operand:DF 0 "register_operand" "f,f")
- (match_operand:DF 1 "general_operand" "f,m")))]
+ (match_operand:DF 1 "general_operand" "f,R")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- cdbr\\t%0,%1
- cdb\\t%0,%1"
+ cdbr\t%0,%1
+ cdb\t%0,%1"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimpd")])
(define_insn "*cmpdf_ccs_ibm"
[(set (reg 33)
(compare (match_operand:DF 0 "register_operand" "f,f")
- (match_operand:DF 1 "general_operand" "f,m")))]
+ (match_operand:DF 1 "general_operand" "f,R")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- cdr\\t%0,%1
- cd\\t%0,%1"
+ cdr\t%0,%1
+ cd\t%0,%1"
[(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimpd")])
; SF instructions
@@ -814,38 +941,40 @@
(compare (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "ltebr\\t%0,%0"
- [(set_attr "op_type" "RRE")])
+ "ltebr\t%0,%0"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimps")])
(define_insn "*cmpsf_ccs_0_ibm"
[(set (reg 33)
(compare (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "const0_operand" "")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "lter\\t%0,%0"
- [(set_attr "op_type" "RR")])
+ "lter\t%0,%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "fsimps")])
(define_insn "*cmpsf_ccs"
[(set (reg 33)
(compare (match_operand:SF 0 "register_operand" "f,f")
- (match_operand:SF 1 "general_operand" "f,m")))]
+ (match_operand:SF 1 "general_operand" "f,R")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- cebr\\t%0,%1
- ceb\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ cebr\t%0,%1
+ ceb\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimps")])
(define_insn "*cmpsf_ccs"
[(set (reg 33)
(compare (match_operand:SF 0 "register_operand" "f,f")
- (match_operand:SF 1 "general_operand" "f,m")))]
+ (match_operand:SF 1 "general_operand" "f,R")))]
"s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- cer\\t%0,%1
- ce\\t%0,%1"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ cer\t%0,%1
+ ce\t%0,%1"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "type" "fsimps")])
;;
@@ -857,17 +986,17 @@
;
(define_insn "movti"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=d,Q,d,o,Q")
- (match_operand:TI 1 "general_operand" "Q,d,dKm,d,Q"))]
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o,Q")
+ (match_operand:TI 1 "general_operand" "QS,d,dKm,d,Q"))]
"TARGET_64BIT"
"@
- lmg\\t%0,%N0,%1
- stmg\\t%1,%N1,%0
+ lmg\t%0,%N0,%1
+ stmg\t%1,%N1,%0
#
#
- mvc\\t%O0(16,%R0),%1"
- [(set_attr "op_type" "RSE,RSE,NN,NN,SS")
- (set_attr "atype" "mem")])
+ mvc\t%O0(16,%R0),%1"
+ [(set_attr "op_type" "RSY,RSY,NN,NN,SS")
+ (set_attr "type" "lm,stm,*,*,cs")])
(define_split
[(set (match_operand:TI 0 "nonimmediate_operand" "")
@@ -929,7 +1058,6 @@
[(set (match_operand:DI 0 "general_operand" "")
(match_operand:DI 1 "general_operand" ""))]
""
- "
{
/* Handle symbolic constants. */
if (TARGET_64BIT && SYMBOLIC_CONST (operands[1]))
@@ -938,85 +1066,64 @@
/* During and after reload, we need to force constants
to the literal pool ourselves, if necessary. */
if ((reload_in_progress || reload_completed)
- && CONSTANT_P (operands[1])
+ && CONSTANT_P (operands[1])
&& (!legitimate_reload_constant_p (operands[1])
|| FP_REG_P (operands[0])))
operands[1] = force_const_mem (DImode, operands[1]);
-}")
-
-(define_insn "*movdi_lhi"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (match_operand:DI 1 "immediate_operand" "K"))]
- "TARGET_64BIT
- && GET_CODE (operands[1]) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')
- && !FP_REG_P (operands[0])"
- "lghi\\t%0,%h1"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
-
-(define_insn "*movdi_lli"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (match_operand:DI 1 "immediate_operand" "n"))]
- "TARGET_64BIT && s390_single_hi (operands[1], DImode, 0) >= 0
- && !FP_REG_P (operands[0])"
- "*
-{
- int part = s390_single_hi (operands[1], DImode, 0);
- operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));
-
- switch (part)
- {
- case 0: return \"llihh\\t%0,%x1\";
- case 1: return \"llihl\\t%0,%x1\";
- case 2: return \"llilh\\t%0,%x1\";
- case 3: return \"llill\\t%0,%x1\";
- default: abort ();
- }
-}"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+})
(define_insn "*movdi_larl"
[(set (match_operand:DI 0 "register_operand" "=d")
(match_operand:DI 1 "larl_operand" "X"))]
"TARGET_64BIT
&& !FP_REG_P (operands[0])"
- "larl\\t%0,%1"
+ "larl\t%0,%1"
[(set_attr "op_type" "RIL")
- (set_attr "atype" "reg")
- (set_attr "type" "la")])
+ (set_attr "type" "larl")])
(define_insn "*movdi_64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m,?Q")
- (match_operand:DI 1 "general_operand" "d,m,d,*f,m,*f,?Q"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand"
+ "=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,?Q")
+ (match_operand:DI 1 "general_operand"
+ "K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,?Q"))]
"TARGET_64BIT"
"@
- lgr\\t%0,%1
- lg\\t%0,%1
- stg\\t%1,%0
- ldr\\t%0,%1
- ld\\t%0,%1
- std\\t%1,%0
- mvc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "RRE,RXE,RXE,RR,RX,RX,SS")
- (set_attr "atype" "reg,mem,mem,reg,mem,mem,mem")])
+ lghi\t%0,%h1
+ llihh\t%0,%i1
+ llihl\t%0,%i1
+ llilh\t%0,%i1
+ llill\t%0,%i1
+ lay\t%0,%a1
+ lgr\t%0,%1
+ lg\t%0,%1
+ stg\t%1,%0
+ ldr\t%0,%1
+ ld\t%0,%1
+ ldy\t%0,%1
+ std\t%1,%0
+ stdy\t%1,%0
+ mvc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY,RR,RX,RXY,RX,RXY,SS")
+ (set_attr "type" "*,*,*,*,*,la,lr,load,store,floadd,floadd,floadd,
+ fstored,fstored,cs")])
(define_insn "*movdi_31"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!m,Q")
- (match_operand:DI 1 "general_operand" "Q,d,dKm,d,*f,m,*f,Q"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!*f,!R,!T,Q")
+ (match_operand:DI 1 "general_operand" "Q,d,dKm,d,*f,R,T,*f,*f,Q"))]
"!TARGET_64BIT"
"@
- lm\\t%0,%N0,%1
- stm\\t%1,%N1,%0
+ lm\t%0,%N0,%1
+ stm\t%1,%N1,%0
#
#
- ldr\\t%0,%1
- ld\\t%0,%1
- std\\t%1,%0
- mvc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "RS,RS,NN,NN,RR,RX,RX,SS")
- (set_attr "atype" "mem,mem,*,*,reg,mem,mem,mem")])
+ ldr\t%0,%1
+ ld\t%0,%1
+ ldy\t%0,%1
+ std\t%1,%0
+ stdy\t%1,%0
+ mvc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RS,RS,NN,NN,RR,RX,RXY,RX,RXY,SS")
+ (set_attr "type" "lm,stm,*,*,floadd,floadd,floadd,fstored,fstored,cs")])
(define_split
[(set (match_operand:DI 0 "nonimmediate_operand" "")
@@ -1083,6 +1190,52 @@
[(set (match_dup 0) (match_dup 2))]
"operands[2] = get_pool_constant (operands[1]);")
+(define_insn "*la_64"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (match_operand:QI 1 "address_operand" "U,W"))]
+ "TARGET_64BIT"
+ "@
+ la\t%0,%a1
+ lay\t%0,%a1"
+ [(set_attr "op_type" "RX,RXY")
+ (set_attr "type" "la")])
+
+(define_peephole2
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:QI 1 "address_operand" ""))
+ (clobber (reg:CC 33))])]
+ "TARGET_64BIT
+ && strict_memory_address_p (VOIDmode, operands[1])
+ && preferred_la_operand_p (operands[1])"
+ [(set (match_dup 0) (match_dup 1))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "register_operand" ""))
+ (parallel
+ [(set (match_dup 0)
+ (plus:DI (match_dup 0)
+ (match_operand:DI 2 "nonmemory_operand" "")))
+ (clobber (reg:CC 33))])]
+ "TARGET_64BIT
+ && !reg_overlap_mentioned_p (operands[0], operands[2])
+ && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (DImode, operands[1], operands[2]))
+ && preferred_la_operand_p (gen_rtx_PLUS (DImode, operands[1], operands[2]))"
+ [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
+ "")
+
+(define_expand "reload_indi"
+ [(parallel [(match_operand:DI 0 "register_operand" "=a")
+ (match_operand:DI 1 "s390_plus_operand" "")
+ (match_operand:DI 2 "register_operand" "=&a")])]
+ "TARGET_64BIT"
+{
+ s390_expand_plus_operand (operands[0], operands[1], operands[2]);
+ DONE;
+})
+
;
; movsi instruction pattern(s).
;
@@ -1091,14 +1244,13 @@
[(set (match_operand:SI 0 "general_operand" "")
(match_operand:SI 1 "general_operand" ""))]
""
- "
{
/* Handle symbolic constants. */
if (!TARGET_64BIT && SYMBOLIC_CONST (operands[1]))
emit_symbolic_move (operands);
- /* expr.c tries to load an effective address using
- force_reg. This fails because we don't have a
+ /* expr.c tries to load an effective address using
+ force_reg. This fails because we don't have a
generic load_address pattern. Convert the move
to a proper arithmetic operation instead, unless
it is guaranteed to be OK. */
@@ -1113,54 +1265,61 @@
/* During and after reload, we need to force constants
to the literal pool ourselves, if necessary. */
if ((reload_in_progress || reload_completed)
- && CONSTANT_P (operands[1])
+ && CONSTANT_P (operands[1])
&& (!legitimate_reload_constant_p (operands[1])
|| FP_REG_P (operands[0])))
operands[1] = force_const_mem (SImode, operands[1]);
-}")
-
-(define_insn "*movsi_lhi"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:SI 1 "immediate_operand" "K"))]
- "GET_CODE (operands[1]) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')
- && !FP_REG_P (operands[0])"
- "lhi\\t%0,%h1"
- [(set_attr "op_type" "RI")])
+})
-(define_insn "*movsi_lli"
+(define_insn "*movsi_larl"
[(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:SI 1 "immediate_operand" "n"))]
- "TARGET_64BIT && s390_single_hi (operands[1], SImode, 0) >= 0
+ (match_operand:SI 1 "larl_operand" "X"))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH
&& !FP_REG_P (operands[0])"
- "*
-{
- int part = s390_single_hi (operands[1], SImode, 0);
- operands[1] = GEN_INT (s390_extract_hi (operands[1], SImode, part));
-
- switch (part)
- {
- case 0: return \"llilh\\t%0,%x1\";
- case 1: return \"llill\\t%0,%x1\";
- default: abort ();
- }
-}"
- [(set_attr "op_type" "RI")])
-
-(define_insn "*movsi"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m,?Q")
- (match_operand:SI 1 "general_operand" "d,m,d,*f,m,*f,?Q"))]
- ""
- "@
- lr\\t%0,%1
- l\\t%0,%1
- st\\t%1,%0
- ler\\t%0,%1
- le\\t%0,%1
- ste\\t%1,%0
- mvc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "RR,RX,RX,RR,RX,RX,SS")
- (set_attr "atype" "reg,mem,mem,reg,mem,mem,mem")])
+ "larl\t%0,%1"
+ [(set_attr "op_type" "RIL")
+ (set_attr "type" "larl")])
+
+(define_insn "*movsi_zarch"
+ [(set (match_operand:SI 0 "nonimmediate_operand"
+ "=d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,?Q")
+ (match_operand:SI 1 "general_operand"
+ "K,N0HS0,N1HS0,L,d,R,T,d,d,*f,R,T,*f,*f,?Q"))]
+ "TARGET_ZARCH"
+ "@
+ lhi\t%0,%h1
+ llilh\t%0,%i1
+ llill\t%0,%i1
+ lay\t%0,%a1
+ lr\t%0,%1
+ l\t%0,%1
+ ly\t%0,%1
+ st\t%1,%0
+ sty\t%1,%0
+ ler\t%0,%1
+ le\t%0,%1
+ ley\t%0,%1
+ ste\t%1,%0
+ stey\t%1,%0
+ mvc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RI,RI,RI,RXY,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
+ (set_attr "type" "*,*,*,la,lr,load,load,store,store,floads,floads,floads,fstores,fstores,cs")])
+
+(define_insn "*movsi_esa"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,?Q")
+ (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,?Q"))]
+ "!TARGET_ZARCH"
+ "@
+ lhi\t%0,%h1
+ lr\t%0,%1
+ l\t%0,%1
+ st\t%1,%0
+ ler\t%0,%1
+ le\t%0,%1
+ ste\t%1,%0
+ mvc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,SS")
+ (set_attr "type" "*,lr,load,store,floads,floads,fstores,cs")])
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
@@ -1173,22 +1332,125 @@
[(set (match_dup 0) (match_dup 2))]
"operands[2] = get_pool_constant (operands[1]);")
+(define_insn "*la_31"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (match_operand:QI 1 "address_operand" "U,W"))]
+ "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
+ "@
+ la\t%0,%a1
+ lay\t%0,%a1"
+ [(set_attr "op_type" "RX,RXY")
+ (set_attr "type" "la")])
+
+(define_peephole2
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:QI 1 "address_operand" ""))
+ (clobber (reg:CC 33))])]
+ "!TARGET_64BIT
+ && strict_memory_address_p (VOIDmode, operands[1])
+ && preferred_la_operand_p (operands[1])"
+ [(set (match_dup 0) (match_dup 1))]
+ "")
+
+(define_peephole2
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" ""))
+ (parallel
+ [(set (match_dup 0)
+ (plus:SI (match_dup 0)
+ (match_operand:SI 2 "nonmemory_operand" "")))
+ (clobber (reg:CC 33))])]
+ "!TARGET_64BIT
+ && !reg_overlap_mentioned_p (operands[0], operands[2])
+ && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (SImode, operands[1], operands[2]))
+ && preferred_la_operand_p (gen_rtx_PLUS (SImode, operands[1], operands[2]))"
+ [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
+ "")
+
+(define_insn "*la_31_and"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (and:SI (match_operand:QI 1 "address_operand" "U,W")
+ (const_int 2147483647)))]
+ "!TARGET_64BIT"
+ "@
+ la\t%0,%a1
+ lay\t%0,%a1"
+ [(set_attr "op_type" "RX,RXY")
+ (set_attr "type" "la")])
+
+(define_insn_and_split "*la_31_and_cc"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (and:SI (match_operand:QI 1 "address_operand" "p")
+ (const_int 2147483647)))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0)
+ (and:SI (match_dup 1) (const_int 2147483647)))]
+ ""
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "la")])
+
+(define_insn "force_la_31"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (match_operand:QI 1 "address_operand" "U,W"))
+ (use (const_int 0))]
+ "!TARGET_64BIT"
+ "@
+ la\t%0,%a1
+ lay\t%0,%a1"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "la")])
+
+(define_expand "reload_insi"
+ [(parallel [(match_operand:SI 0 "register_operand" "=a")
+ (match_operand:SI 1 "s390_plus_operand" "")
+ (match_operand:SI 2 "register_operand" "=&a")])]
+ "!TARGET_64BIT"
+{
+ s390_expand_plus_operand (operands[0], operands[1], operands[2]);
+ DONE;
+})
+
;
; movhi instruction pattern(s).
;
-(define_insn "movhi"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,?Q")
- (match_operand:HI 1 "general_operand" "d,n,m,d,?Q"))]
+(define_expand "movhi"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
+ (match_operand:HI 1 "general_operand" ""))]
+ ""
+{
+ /* Make it explicit that loading a register from memory
+ always sign-extends (at least) to SImode. */
+ if (optimize && !no_new_pseudos
+ && register_operand (operands[0], VOIDmode)
+ && GET_CODE (operands[1]) == MEM
+ && GET_CODE (XEXP (operands[1], 0)) != ADDRESSOF)
+ {
+ rtx tmp = gen_reg_rtx (SImode);
+ rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
+ emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
+ operands[1] = gen_lowpart (HImode, tmp);
+ }
+})
+
+(define_insn "*movhi"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,T,?Q")
+ (match_operand:HI 1 "general_operand" "d,n,R,T,d,d,?Q"))]
""
"@
- lr\\t%0,%1
- lhi\\t%0,%h1
- lh\\t%0,%1
- sth\\t%1,%0
- mvc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "RR,RI,RX,RX,SS")
- (set_attr "atype" "reg,reg,mem,mem,mem")])
+ lr\t%0,%1
+ lhi\t%0,%h1
+ lh\t%0,%1
+ lhy\t%0,%1
+ sth\t%1,%0
+ sthy\t%1,%0
+ mvc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SS")
+ (set_attr "type" "lr,*,*,*,store,store,cs")])
(define_peephole2
[(set (match_operand:HI 0 "register_operand" "")
@@ -1204,34 +1466,41 @@
; movqi instruction pattern(s).
;
-(define_insn "movqi_64"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q,?Q")
- (match_operand:QI 1 "general_operand" "d,n,m,d,n,?Q"))]
- "TARGET_64BIT"
- "@
- lr\\t%0,%1
- lhi\\t%0,%b1
- llgc\\t%0,%1
- stc\\t%1,%0
- mvi\\t%0,%b1
- mvc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "RR,RI,RXE,RX,SI,SS")
- (set_attr "atype" "reg,reg,mem,mem,mem,mem")])
-
+(define_expand "movqi"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
+ (match_operand:QI 1 "general_operand" ""))]
+ ""
+{
+ /* On z/Architecture, zero-extending from memory to register
+ is just as fast as a QImode load. */
+ if (TARGET_ZARCH && optimize && !no_new_pseudos
+ && register_operand (operands[0], VOIDmode)
+ && GET_CODE (operands[1]) == MEM
+ && GET_CODE (XEXP (operands[1], 0)) != ADDRESSOF)
+ {
+ rtx tmp = gen_reg_rtx (word_mode);
+ rtx ext = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
+ emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
+ operands[1] = gen_lowpart (QImode, tmp);
+ }
+})
-(define_insn "movqi"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q,?Q")
- (match_operand:QI 1 "general_operand" "d,n,m,d,n,?Q"))]
+(define_insn "*movqi"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q")
+ (match_operand:QI 1 "general_operand" "d,n,R,T,d,d,n,n,?Q"))]
""
"@
- lr\\t%0,%1
- lhi\\t%0,%b1
- ic\\t%0,%1
- stc\\t%1,%0
- mvi\\t%0,%b1
- mvc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "RR,RI,RX,RX,SI,SS")
- (set_attr "atype" "reg,reg,mem,mem,mem,mem")])
+ lr\t%0,%1
+ lhi\t%0,%b1
+ ic\t%0,%1
+ icy\t%0,%1
+ stc\t%1,%0
+ stcy\t%1,%0
+ mvi\t%0,%b1
+ mviy\t%0,%b1
+ mvc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS")
+ (set_attr "type" "lr,*,*,*,store,store,store,store,cs")])
(define_peephole2
[(set (match_operand:QI 0 "nonimmediate_operand" "")
@@ -1248,41 +1517,42 @@
;
(define_insn "*movstrictqi"
- [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
- (match_operand:QI 1 "memory_operand" "m"))]
+ [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
+ (match_operand:QI 1 "memory_operand" "R,T"))]
""
- "ic\\t%0,%1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
+ "@
+ ic\t%0,%1
+ icy\t%0,%1"
+ [(set_attr "op_type" "RX,RXY")])
;
; movstricthi instruction pattern(s).
;
(define_insn "*movstricthi"
- [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
- (match_operand:HI 1 "s_imm_operand" "Q"))
+ [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
+ (match_operand:HI 1 "s_imm_operand" "Q,S"))
(clobber (reg:CC 33))]
""
- "icm\\t%0,3,%1"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
-
+ "@
+ icm\t%0,3,%1
+ icmy\t%0,3,%1"
+ [(set_attr "op_type" "RS,RSY")])
;
; movstrictsi instruction pattern(s).
;
(define_insn "movstrictsi"
- [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d"))
- (match_operand:SI 1 "general_operand" "d,m"))]
+ [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d"))
+ (match_operand:SI 1 "general_operand" "d,R,T"))]
"TARGET_64BIT"
"@
- lr\\t%0,%1
- l\\t%0,%1"
- [(set_attr "op_type" "RR,RS")
- (set_attr "atype" "reg,mem")])
-
+ lr\t%0,%1
+ l\t%0,%1
+ ly\t%0,%1"
+ [(set_attr "op_type" "RR,RX,RXY")
+ (set_attr "type" "lr,load,load")])
;
; movdf instruction pattern(s).
@@ -1292,45 +1562,48 @@
[(set (match_operand:DF 0 "nonimmediate_operand" "")
(match_operand:DF 1 "general_operand" ""))]
""
- "
{
/* During and after reload, we need to force constants
to the literal pool ourselves, if necessary. */
if ((reload_in_progress || reload_completed)
&& CONSTANT_P (operands[1]))
operands[1] = force_const_mem (DFmode, operands[1]);
-}")
+})
(define_insn "*movdf_64"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,d,m,?Q")
- (match_operand:DF 1 "general_operand" "f,m,f,d,m,d,?Q"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,T,d,d,m,?Q")
+ (match_operand:DF 1 "general_operand" "f,R,T,f,f,d,m,d,?Q"))]
"TARGET_64BIT"
"@
- ldr\\t%0,%1
- ld\\t%0,%1
- std\\t%1,%0
- lgr\\t%0,%1
- lg\\t%0,%1
- stg\\t%1,%0
- mvc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "RR,RX,RX,RRE,RXE,RXE,SS")
- (set_attr "atype" "reg,mem,mem,reg,mem,mem,mem")])
+ ldr\t%0,%1
+ ld\t%0,%1
+ ldy\t%0,%1
+ std\t%1,%0
+ stdy\t%1,%0
+ lgr\t%0,%1
+ lg\t%0,%1
+ stg\t%1,%0
+ mvc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS")
+ (set_attr "type" "floadd,floadd,floadd,fstored,fstored,lr,load,store,cs")])
(define_insn "*movdf_31"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,Q,d,o,Q")
- (match_operand:DF 1 "general_operand" "f,m,f,Q,d,dKm,d,Q"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,T,d,Q,d,o,Q")
+ (match_operand:DF 1 "general_operand" "f,R,T,f,f,Q,d,dKm,d,Q"))]
"!TARGET_64BIT"
"@
- ldr\\t%0,%1
- ld\\t%0,%1
- std\\t%1,%0
- lm\\t%0,%N0,%1
- stm\\t%1,%N1,%0
+ ldr\t%0,%1
+ ld\t%0,%1
+ ldy\t%0,%1
+ std\t%1,%0
+ stdy\t%1,%0
+ lm\t%0,%N0,%1
+ stm\t%1,%N1,%0
#
#
- mvc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "RR,RX,RX,RS,RS,NN,NN,SS")
- (set_attr "atype" "reg,mem,mem,mem,mem,*,*,mem")])
+ mvc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RS,RS,NN,NN,SS")
+ (set_attr "type" "floadd,floadd,floadd,fstored,fstored,lm,stm,*,*,cs")])
(define_split
[(set (match_operand:DF 0 "nonimmediate_operand" "")
@@ -1393,41 +1666,47 @@
[(set (match_operand:SF 0 "nonimmediate_operand" "")
(match_operand:SF 1 "general_operand" ""))]
""
- "
{
/* During and after reload, we need to force constants
to the literal pool ourselves, if necessary. */
if ((reload_in_progress || reload_completed)
&& CONSTANT_P (operands[1]))
operands[1] = force_const_mem (SFmode, operands[1]);
-}")
+})
(define_insn "*movsf"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,d,d,m,?Q")
- (match_operand:SF 1 "general_operand" "f,m,f,d,m,d,?Q"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,R,T,d,d,d,R,T,?Q")
+ (match_operand:SF 1 "general_operand" "f,R,T,f,f,d,R,T,d,d,?Q"))]
""
"@
- ler\\t%0,%1
- le\\t%0,%1
- ste\\t%1,%0
- lr\\t%0,%1
- l\\t%0,%1
- st\\t%1,%0
- mvc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "RR,RX,RX,RR,RX,RX,SS")
- (set_attr "atype" "reg,mem,mem,reg,mem,mem,mem")])
+ ler\t%0,%1
+ le\t%0,%1
+ ley\t%0,%1
+ ste\t%1,%0
+ stey\t%1,%0
+ lr\t%0,%1
+ l\t%0,%1
+ ly\t%0,%1
+ st\t%1,%0
+ sty\t%1,%0
+ mvc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
+ (set_attr "type" "floads,floads,floads,fstores,fstores,lr,load,load,store,store,cs")])
;
; load_multiple pattern(s).
;
+; ??? Due to reload problems with replacing registers inside match_parallel
+; we currently support load_multiple/store_multiple only after reload.
+;
(define_expand "load_multiple"
[(match_par_dup 3 [(set (match_operand 0 "" "")
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))])]
- ""
- "
+ "reload_completed"
{
+ enum machine_mode mode;
int regno;
int count;
rtx from;
@@ -1445,6 +1724,9 @@
count = INTVAL (operands[2]);
regno = REGNO (operands[0]);
+ mode = GET_MODE (operands[0]);
+ if (mode != SImode && mode != word_mode)
+ FAIL;
operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
if (no_new_pseudos)
@@ -1475,61 +1757,48 @@
for (i = 0; i < count; i++)
XVECEXP (operands[3], 0, i)
- = gen_rtx_SET (VOIDmode, gen_rtx_REG (Pmode, regno + i),
- change_address (operands[1], Pmode,
- plus_constant (from,
- off + i * UNITS_PER_WORD)));
-}")
+ = gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, regno + i),
+ change_address (operands[1], mode,
+ plus_constant (from, off + i * GET_MODE_SIZE (mode))));
+})
(define_insn "*load_multiple_di"
[(match_parallel 0 "load_multiple_operation"
[(set (match_operand:DI 1 "register_operand" "=r")
- (match_operand:DI 2 "s_operand" "Q"))])]
- ""
- "*
+ (match_operand:DI 2 "s_operand" "QS"))])]
+ "reload_completed && word_mode == DImode"
{
int words = XVECLEN (operands[0], 0);
-
- if (XVECLEN (operands[0], 0) == 1)
- return \"lg\\t%1,0(%2)\";
-
operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
- return \"lmg\\t%1,%0,%2\";
-}"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")
+ return "lmg\t%1,%0,%2";
+}
+ [(set_attr "op_type" "RSY")
(set_attr "type" "lm")])
(define_insn "*load_multiple_si"
[(match_parallel 0 "load_multiple_operation"
- [(set (match_operand:SI 1 "register_operand" "=r")
- (match_operand:SI 2 "s_operand" "Q"))])]
- ""
- "*
+ [(set (match_operand:SI 1 "register_operand" "=r,r")
+ (match_operand:SI 2 "s_operand" "Q,S"))])]
+ "reload_completed"
{
int words = XVECLEN (operands[0], 0);
-
- if (XVECLEN (operands[0], 0) == 1)
- return \"l\\t%1,0(%2)\";
-
operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
- return \"lm\\t%1,%0,%2\";
-}"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")
+ return which_alternative == 0 ? "lm\t%1,%0,%2" : "lmy\t%1,%0,%2";
+}
+ [(set_attr "op_type" "RS,RSY")
(set_attr "type" "lm")])
;
-; store multiple pattern(s).
+; store multiple pattern(s).
;
(define_expand "store_multiple"
[(match_par_dup 3 [(set (match_operand 0 "" "")
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))])]
- ""
- "
+ "reload_completed"
{
+ enum machine_mode mode;
int regno;
int count;
rtx to;
@@ -1547,6 +1816,9 @@
count = INTVAL (operands[2]);
regno = REGNO (operands[1]);
+ mode = GET_MODE (operands[1]);
+ if (mode != SImode && mode != word_mode)
+ FAIL;
operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
@@ -1570,7 +1842,7 @@
if (to == frame_pointer_rtx || to == arg_pointer_rtx)
FAIL;
}
- else
+ else
{
to = force_reg (Pmode, XEXP (operands[0], 0));
off = 0;
@@ -1579,49 +1851,36 @@
for (i = 0; i < count; i++)
XVECEXP (operands[3], 0, i)
= gen_rtx_SET (VOIDmode,
- change_address (operands[0], Pmode,
- plus_constant (to,
- off + i * UNITS_PER_WORD)),
- gen_rtx_REG (Pmode, regno + i));
-}")
+ change_address (operands[0], mode,
+ plus_constant (to, off + i * GET_MODE_SIZE (mode))),
+ gen_rtx_REG (mode, regno + i));
+})
(define_insn "*store_multiple_di"
[(match_parallel 0 "store_multiple_operation"
- [(set (match_operand:DI 1 "s_operand" "=Q")
+ [(set (match_operand:DI 1 "s_operand" "=QS")
(match_operand:DI 2 "register_operand" "r"))])]
- ""
- "*
+ "reload_completed && word_mode == DImode"
{
int words = XVECLEN (operands[0], 0);
-
- if (XVECLEN (operands[0], 0) == 1)
- return \"stg\\t%1,0(%2)\";
-
operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
- return \"stmg\\t%2,%0,%1\";
-}"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")
+ return "stmg\t%2,%0,%1";
+}
+ [(set_attr "op_type" "RSY")
(set_attr "type" "stm")])
(define_insn "*store_multiple_si"
[(match_parallel 0 "store_multiple_operation"
- [(set (match_operand:SI 1 "s_operand" "=Q")
- (match_operand:SI 2 "register_operand" "r"))])]
- ""
- "*
+ [(set (match_operand:SI 1 "s_operand" "=Q,S")
+ (match_operand:SI 2 "register_operand" "r,r"))])]
+ "reload_completed"
{
int words = XVECLEN (operands[0], 0);
-
- if (XVECLEN (operands[0], 0) == 1)
- return \"st\\t%1,0(%2)\";
-
operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
- return \"stm\\t%2,%0,%1\";
-}"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")
+ return which_alternative == 0 ? "stm\t%2,%0,%1" : "stmy\t%2,%0,%1";
+}
+ [(set_attr "op_type" "RS,RSY")
(set_attr "type" "stm")])
;;
@@ -1629,6 +1888,82 @@
;;
;
+; strlenM instruction pattern(s).
+;
+
+(define_expand "strlendi"
+ [(set (reg:QI 0) (match_operand:QI 2 "immediate_operand" ""))
+ (parallel
+ [(set (match_dup 4)
+ (unspec:DI [(const_int 0)
+ (match_operand:BLK 1 "memory_operand" "")
+ (reg:QI 0)
+ (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
+ (clobber (scratch:DI))
+ (clobber (reg:CC 33))])
+ (parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (minus:DI (match_dup 4) (match_dup 5)))
+ (clobber (reg:CC 33))])]
+ "TARGET_64BIT"
+{
+ operands[4] = gen_reg_rtx (DImode);
+ operands[5] = gen_reg_rtx (DImode);
+ emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
+ operands[1] = replace_equiv_address (operands[1], operands[5]);
+})
+
+(define_insn "*strlendi"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (unspec:DI [(match_operand:DI 2 "general_operand" "0")
+ (mem:BLK (match_operand:DI 3 "register_operand" "1"))
+ (reg:QI 0)
+ (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
+ (clobber (match_scratch:DI 1 "=a"))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "srst\t%0,%1\;jo\t.-4"
+ [(set_attr "op_type" "NN")
+ (set_attr "type" "vs")
+ (set_attr "length" "8")])
+
+(define_expand "strlensi"
+ [(set (reg:QI 0) (match_operand:QI 2 "immediate_operand" ""))
+ (parallel
+ [(set (match_dup 4)
+ (unspec:SI [(const_int 0)
+ (match_operand:BLK 1 "memory_operand" "")
+ (reg:QI 0)
+ (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
+ (clobber (scratch:SI))
+ (clobber (reg:CC 33))])
+ (parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (minus:SI (match_dup 4) (match_dup 5)))
+ (clobber (reg:CC 33))])]
+ "!TARGET_64BIT"
+{
+ operands[4] = gen_reg_rtx (SImode);
+ operands[5] = gen_reg_rtx (SImode);
+ emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
+ operands[1] = replace_equiv_address (operands[1], operands[5]);
+})
+
+(define_insn "*strlensi"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (unspec:SI [(match_operand:SI 2 "general_operand" "0")
+ (mem:BLK (match_operand:SI 3 "register_operand" "1"))
+ (reg:QI 0)
+ (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
+ (clobber (match_scratch:SI 1 "=a"))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "srst\t%0,%1\;jo\t.-4"
+ [(set_attr "op_type" "NN")
+ (set_attr "type" "vs")
+ (set_attr "length" "8")])
+
+;
; movstrM instruction pattern(s).
;
@@ -1651,98 +1986,103 @@
; Move a block that is up to 256 bytes in length.
; The block length is taken as (operands[2] % 256) + 1.
-(define_insn "movstr_short_64"
- [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
- (match_operand:BLK 1 "memory_operand" "Q,Q"))
- (use (match_operand:DI 2 "nonmemory_operand" "n,a"))
- (clobber (match_scratch:DI 3 "=X,&a"))]
- "TARGET_64BIT"
- "*
-{
- switch (which_alternative)
- {
- case 0:
- return \"mvc\\t%O0(%b2+1,%R0),%1\";
-
- case 1:
- output_asm_insn (\"bras\\t%3,.+10\", operands);
- output_asm_insn (\"mvc\\t%O0(1,%R0),%1\", operands);
- return \"ex\\t%2,0(%3)\";
-
- default:
- abort ();
- }
-}"
- [(set_attr "op_type" "SS,NN")
- (set_attr "type" "cs,cs")
- (set_attr "atype" "mem,mem")
- (set_attr "length" "*,14")])
+(define_expand "movstr_short"
+ [(parallel
+ [(set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
+ (use (match_operand 2 "nonmemory_operand" ""))
+ (clobber (match_dup 3))])]
+ ""
+ "operands[3] = gen_rtx_SCRATCH (Pmode);")
-(define_insn "movstr_short_31"
+(define_insn "*movstr_short"
[(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
(match_operand:BLK 1 "memory_operand" "Q,Q"))
- (use (match_operand:SI 2 "nonmemory_operand" "n,a"))
- (clobber (match_scratch:SI 3 "=X,&a"))]
- "!TARGET_64BIT"
- "*
+ (use (match_operand 2 "nonmemory_operand" "n,a"))
+ (clobber (match_scratch 3 "=X,&a"))]
+ "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
+ && GET_MODE (operands[3]) == Pmode"
{
switch (which_alternative)
{
case 0:
- return \"mvc\\t%O0(%b2+1,%R0),%1\";
+ return "mvc\t%O0(%b2+1,%R0),%1";
case 1:
- output_asm_insn (\"bras\\t%3,.+10\", operands);
- output_asm_insn (\"mvc\\t%O0(1,%R0),%1\", operands);
- return \"ex\\t%2,0(%3)\";
+ output_asm_insn ("bras\t%3,.+10", operands);
+ output_asm_insn ("mvc\t%O0(1,%R0),%1", operands);
+ return "ex\t%2,0(%3)";
default:
abort ();
}
-}"
+}
[(set_attr "op_type" "SS,NN")
(set_attr "type" "cs,cs")
- (set_attr "atype" "mem,mem")
+ (set_attr "atype" "*,agen")
(set_attr "length" "*,14")])
; Move a block of arbitrary length.
-(define_insn "movstr_long_64"
- [(set (match_operand:TI 0 "register_operand" "=d")
- (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0")
- (lshiftrt:TI (match_dup 2) (const_int 64)))
- (const_int 64)))
- (set (match_operand:TI 1 "register_operand" "=d")
- (ashift:TI (plus:TI (match_operand:TI 3 "register_operand" "1")
- (lshiftrt:TI (match_dup 3) (const_int 64)))
- (const_int 64)))
- (set (mem:BLK (subreg:DI (match_dup 2) 0))
- (mem:BLK (subreg:DI (match_dup 3) 0)))
+(define_expand "movstr_long"
+ [(parallel
+ [(clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (set (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" ""))
+ (use (match_operand 2 "general_operand" ""))
+ (use (match_dup 3))
+ (clobber (reg:CC 33))])]
+ ""
+{
+ enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
+ rtx reg0 = gen_reg_rtx (dword_mode);
+ rtx reg1 = gen_reg_rtx (dword_mode);
+ rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
+ rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
+ rtx len0 = gen_lowpart (Pmode, reg0);
+ rtx len1 = gen_lowpart (Pmode, reg1);
+
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
+ emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
+ emit_move_insn (len0, operands[2]);
+
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
+ emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
+ emit_move_insn (len1, operands[2]);
+
+ operands[0] = replace_equiv_address_nv (operands[0], addr0);
+ operands[1] = replace_equiv_address_nv (operands[1], addr1);
+ operands[2] = reg0;
+ operands[3] = reg1;
+})
+
+(define_insn "*movstr_long_64"
+ [(clobber (match_operand:TI 0 "register_operand" "=d"))
+ (clobber (match_operand:TI 1 "register_operand" "=d"))
+ (set (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0))
+ (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0)))
+ (use (match_dup 2))
+ (use (match_dup 3))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "mvcle\\t%0,%1,0\;jo\\t.-4"
+ "mvcle\t%0,%1,0\;jo\t.-4"
[(set_attr "op_type" "NN")
(set_attr "type" "vs")
- (set_attr "atype" "mem")
(set_attr "length" "8")])
-(define_insn "movstr_long_31"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0")
- (lshiftrt:DI (match_dup 2) (const_int 32)))
- (const_int 32)))
- (set (match_operand:DI 1 "register_operand" "=d")
- (ashift:DI (plus:DI (match_operand:DI 3 "register_operand" "1")
- (lshiftrt:DI (match_dup 3) (const_int 32)))
- (const_int 32)))
- (set (mem:BLK (subreg:SI (match_dup 2) 0))
- (mem:BLK (subreg:SI (match_dup 3) 0)))
+(define_insn "*movstr_long_31"
+ [(clobber (match_operand:DI 0 "register_operand" "=d"))
+ (clobber (match_operand:DI 1 "register_operand" "=d"))
+ (set (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0))
+ (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0)))
+ (use (match_dup 2))
+ (use (match_dup 3))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
- "mvcle\\t%0,%1,0\;jo\\t.-4"
+ "mvcle\t%0,%1,0\;jo\t.-4"
[(set_attr "op_type" "NN")
(set_attr "type" "vs")
- (set_attr "atype" "mem")
(set_attr "length" "8")])
;
@@ -1766,184 +2106,202 @@
"s390_expand_clrstr (operands[0], operands[1]); DONE;")
; Clear a block that is up to 256 bytes in length.
-; The block length is taken as (operands[2] % 256) + 1.
+; The block length is taken as (operands[1] % 256) + 1.
-(define_insn "clrstr_short_64"
+(define_expand "clrstr_short"
+ [(parallel
+ [(set (match_operand:BLK 0 "memory_operand" "")
+ (const_int 0))
+ (use (match_operand 1 "nonmemory_operand" ""))
+ (clobber (match_dup 2))
+ (clobber (reg:CC 33))])]
+ ""
+ "operands[2] = gen_rtx_SCRATCH (Pmode);")
+
+(define_insn "*clrstr_short"
[(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
(const_int 0))
- (use (match_operand:DI 1 "nonmemory_operand" "n,a"))
- (clobber (match_scratch:DI 2 "=X,&a"))
+ (use (match_operand 1 "nonmemory_operand" "n,a"))
+ (clobber (match_scratch 2 "=X,&a"))
(clobber (reg:CC 33))]
- "TARGET_64BIT"
- "*
+ "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)
+ && GET_MODE (operands[2]) == Pmode"
{
switch (which_alternative)
{
case 0:
- return \"xc\\t%O0(%b1+1,%R0),%0\";
+ return "xc\t%O0(%b1+1,%R0),%0";
case 1:
- output_asm_insn (\"bras\\t%2,.+10\", operands);
- output_asm_insn (\"xc\\t%O0(1,%R0),%0\", operands);
- return \"ex\\t%1,0(%2)\";
+ output_asm_insn ("bras\t%2,.+10", operands);
+ output_asm_insn ("xc\t%O0(1,%R0),%0", operands);
+ return "ex\t%1,0(%2)";
default:
abort ();
}
-}"
+}
[(set_attr "op_type" "SS,NN")
(set_attr "type" "cs,cs")
- (set_attr "atype" "mem,mem")
+ (set_attr "atype" "*,agen")
(set_attr "length" "*,14")])
-(define_insn "clrstr_short_31"
- [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
- (const_int 0))
- (use (match_operand:SI 1 "nonmemory_operand" "n,a"))
- (clobber (match_scratch:SI 2 "=X,&a"))
- (clobber (reg:CC 33))]
- "!TARGET_64BIT"
- "*
+; Clear a block of arbitrary length.
+
+(define_expand "clrstr_long"
+ [(parallel
+ [(clobber (match_dup 1))
+ (set (match_operand:BLK 0 "memory_operand" "")
+ (const_int 0))
+ (use (match_operand 1 "general_operand" ""))
+ (use (match_dup 2))
+ (clobber (reg:CC 33))])]
+ ""
{
- switch (which_alternative)
- {
- case 0:
- return \"xc\\t%O0(%b1+1,%R0),%0\";
+ enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
+ rtx reg0 = gen_reg_rtx (dword_mode);
+ rtx reg1 = gen_reg_rtx (dword_mode);
+ rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
+ rtx len0 = gen_lowpart (Pmode, reg0);
- case 1:
- output_asm_insn (\"bras\\t%2,.+10\", operands);
- output_asm_insn (\"xc\\t%O0(1,%R0),%0\", operands);
- return \"ex\\t%1,0(%2)\";
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
+ emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
+ emit_move_insn (len0, operands[1]);
- default:
- abort ();
- }
-}"
- [(set_attr "op_type" "SS,NN")
- (set_attr "type" "cs,cs")
- (set_attr "atype" "mem,mem")
- (set_attr "length" "*,14")])
+ emit_move_insn (reg1, const0_rtx);
-; Clear a block of arbitrary length.
+ operands[0] = replace_equiv_address_nv (operands[0], addr0);
+ operands[1] = reg0;
+ operands[2] = reg1;
+})
-(define_insn "clrstr_long_64"
- [(set (match_operand:TI 0 "register_operand" "=d")
- (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0")
- (lshiftrt:TI (match_dup 2) (const_int 64)))
- (const_int 64)))
- (set (mem:BLK (subreg:DI (match_dup 2) 0))
+(define_insn "*clrstr_long_64"
+ [(clobber (match_operand:TI 0 "register_operand" "=d"))
+ (set (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0))
(const_int 0))
+ (use (match_dup 2))
(use (match_operand:TI 1 "register_operand" "d"))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "mvcle\\t%0,%1,0\;jo\\t.-4"
+ "mvcle\t%0,%1,0\;jo\t.-4"
[(set_attr "op_type" "NN")
- (set_attr "atype" "mem")
(set_attr "type" "vs")
(set_attr "length" "8")])
-(define_insn "clrstr_long_31"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0")
- (lshiftrt:DI (match_dup 2) (const_int 32)))
- (const_int 32)))
- (set (mem:BLK (subreg:SI (match_dup 2) 0))
+(define_insn "*clrstr_long_31"
+ [(clobber (match_operand:DI 0 "register_operand" "=d"))
+ (set (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0))
(const_int 0))
+ (use (match_dup 2))
(use (match_operand:DI 1 "register_operand" "d"))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
- "mvcle\\t%0,%1,0\;jo\\t.-4"
+ "mvcle\t%0,%1,0\;jo\t.-4"
[(set_attr "op_type" "NN")
- (set_attr "atype" "mem")
(set_attr "type" "vs")
(set_attr "length" "8")])
;
-; cmpstrM instruction pattern(s).
+; cmpmemM instruction pattern(s).
;
-(define_expand "cmpstrdi"
+(define_expand "cmpmemdi"
[(set (match_operand:DI 0 "register_operand" "")
(compare:DI (match_operand:BLK 1 "memory_operand" "")
(match_operand:BLK 2 "memory_operand" "") ) )
(use (match_operand:DI 3 "general_operand" ""))
(use (match_operand:DI 4 "" ""))]
"TARGET_64BIT"
- "s390_expand_cmpstr (operands[0], operands[1],
+ "s390_expand_cmpmem (operands[0], operands[1],
operands[2], operands[3]); DONE;")
-(define_expand "cmpstrsi"
+(define_expand "cmpmemsi"
[(set (match_operand:SI 0 "register_operand" "")
(compare:SI (match_operand:BLK 1 "memory_operand" "")
(match_operand:BLK 2 "memory_operand" "") ) )
(use (match_operand:SI 3 "general_operand" ""))
(use (match_operand:SI 4 "" ""))]
""
- "s390_expand_cmpstr (operands[0], operands[1],
+ "s390_expand_cmpmem (operands[0], operands[1],
operands[2], operands[3]); DONE;")
; Compare a block that is up to 256 bytes in length.
; The block length is taken as (operands[2] % 256) + 1.
-(define_insn "cmpstr_short_64"
- [(set (reg:CCS 33)
- (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q")
- (match_operand:BLK 1 "memory_operand" "Q,Q")))
- (use (match_operand:DI 2 "nonmemory_operand" "n,a"))
- (clobber (match_scratch:DI 3 "=X,&a"))]
- "TARGET_64BIT"
- "*
-{
- switch (which_alternative)
- {
- case 0:
- return \"clc\\t%O0(%b2+1,%R0),%1\";
-
- case 1:
- output_asm_insn (\"bras\\t%3,.+10\", operands);
- output_asm_insn (\"clc\\t%O0(1,%R0),%1\", operands);
- return \"ex\\t%2,0(%3)\";
-
- default:
- abort ();
- }
-}"
- [(set_attr "op_type" "SS,NN")
- (set_attr "type" "cs,cs")
- (set_attr "atype" "mem,mem")
- (set_attr "length" "*,14")])
+(define_expand "cmpmem_short"
+ [(parallel
+ [(set (reg:CCS 33)
+ (compare:CCS (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" "")))
+ (use (match_operand 2 "nonmemory_operand" ""))
+ (clobber (match_dup 3))])]
+ ""
+ "operands[3] = gen_rtx_SCRATCH (Pmode);")
-(define_insn "cmpstr_short_31"
+(define_insn "*cmpmem_short"
[(set (reg:CCS 33)
(compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q")
(match_operand:BLK 1 "memory_operand" "Q,Q")))
- (use (match_operand:SI 2 "nonmemory_operand" "n,a"))
- (clobber (match_scratch:SI 3 "=X,&a"))]
- "!TARGET_64BIT"
- "*
+ (use (match_operand 2 "nonmemory_operand" "n,a"))
+ (clobber (match_scratch 3 "=X,&a"))]
+ "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
+ && GET_MODE (operands[3]) == Pmode"
{
switch (which_alternative)
{
case 0:
- return \"clc\\t%O0(%b2+1,%R0),%1\";
+ return "clc\t%O0(%b2+1,%R0),%1";
case 1:
- output_asm_insn (\"bras\\t%3,.+10\", operands);
- output_asm_insn (\"clc\\t%O0(1,%R0),%1\", operands);
- return \"ex\\t%2,0(%3)\";
+ output_asm_insn ("bras\t%3,.+10", operands);
+ output_asm_insn ("clc\t%O0(1,%R0),%1", operands);
+ return "ex\t%2,0(%3)";
default:
abort ();
}
-}"
+}
[(set_attr "op_type" "SS,NN")
(set_attr "type" "cs,cs")
- (set_attr "atype" "mem,mem")
+ (set_attr "atype" "*,agen")
(set_attr "length" "*,14")])
; Compare a block of arbitrary length.
-(define_insn "cmpstr_long_64"
+(define_expand "cmpmem_long"
+ [(parallel
+ [(clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (set (reg:CCS 33)
+ (compare:CCS (match_operand:BLK 0 "memory_operand" "")
+ (match_operand:BLK 1 "memory_operand" "")))
+ (use (match_operand 2 "general_operand" ""))
+ (use (match_dup 3))])]
+ ""
+{
+ enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
+ rtx reg0 = gen_reg_rtx (dword_mode);
+ rtx reg1 = gen_reg_rtx (dword_mode);
+ rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
+ rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
+ rtx len0 = gen_lowpart (Pmode, reg0);
+ rtx len1 = gen_lowpart (Pmode, reg1);
+
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
+ emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
+ emit_move_insn (len0, operands[2]);
+
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
+ emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
+ emit_move_insn (len1, operands[2]);
+
+ operands[0] = replace_equiv_address_nv (operands[0], addr0);
+ operands[1] = replace_equiv_address_nv (operands[1], addr1);
+ operands[2] = reg0;
+ operands[3] = reg1;
+})
+
+(define_insn "*cmpmem_long_64"
[(clobber (match_operand:TI 0 "register_operand" "=d"))
(clobber (match_operand:TI 1 "register_operand" "=d"))
(set (reg:CCS 33)
@@ -1952,12 +2310,12 @@
(use (match_dup 2))
(use (match_dup 3))]
"TARGET_64BIT"
- "clcl\\t%0,%1"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "mem")
- (set_attr "type" "vs")])
+ "clcle\t%0,%1,0\;jo\t.-4"
+ [(set_attr "op_type" "NN")
+ (set_attr "type" "vs")
+ (set_attr "length" "8")])
-(define_insn "cmpstr_long_31"
+(define_insn "*cmpmem_long_31"
[(clobber (match_operand:DI 0 "register_operand" "=d"))
(clobber (match_operand:DI 1 "register_operand" "=d"))
(set (reg:CCS 33)
@@ -1966,10 +2324,10 @@
(use (match_dup 2))
(use (match_dup 3))]
"!TARGET_64BIT"
- "clcl\\t%0,%1"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "mem")
- (set_attr "type" "vs")])
+ "clcle\t%0,%1,0\;jo\t.-4"
+ [(set_attr "op_type" "NN")
+ (set_attr "type" "vs")
+ (set_attr "length" "8")])
; Convert condition code to integer in range (-1, 0, 1)
@@ -1977,34 +2335,30 @@
[(set (match_operand:SI 0 "register_operand" "=d")
(compare:SI (reg:CCS 33) (const_int 0)))]
""
- "*
{
- output_asm_insn (\"lhi\\t%0,1\", operands);
- output_asm_insn (\"jh\\t.+12\", operands);
- output_asm_insn (\"jl\\t.+6\", operands);
- output_asm_insn (\"sr\\t%0,%0\", operands);
- return \"lcr\\t%0,%0\";
-}"
+ output_asm_insn ("lhi\t%0,1", operands);
+ output_asm_insn ("jh\t.+12", operands);
+ output_asm_insn ("jl\t.+6", operands);
+ output_asm_insn ("sr\t%0,%0", operands);
+ return "lcr\t%0,%0";
+}
[(set_attr "op_type" "NN")
(set_attr "length" "16")
- (set_attr "atype" "reg")
(set_attr "type" "other")])
(define_insn "cmpint_di"
[(set (match_operand:DI 0 "register_operand" "=d")
(compare:DI (reg:CCS 33) (const_int 0)))]
"TARGET_64BIT"
- "*
{
- output_asm_insn (\"lghi\\t%0,1\", operands);
- output_asm_insn (\"jh\\t.+12\", operands);
- output_asm_insn (\"jl\\t.+6\", operands);
- output_asm_insn (\"sgr\\t%0,%0\", operands);
- return \"lcgr\\t%0,%0\";
-}"
+ output_asm_insn ("lghi\t%0,1", operands);
+ output_asm_insn ("jh\t.+16", operands);
+ output_asm_insn ("jl\t.+8", operands);
+ output_asm_insn ("sgr\t%0,%0", operands);
+ return "lcgr\t%0,%0";
+}
[(set_attr "op_type" "NN")
- (set_attr "length" "22")
- (set_attr "atype" "reg")
+ (set_attr "length" "20")
(set_attr "type" "other")])
@@ -2013,40 +2367,42 @@
;;
(define_insn "*sethighqisi"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (unspec:SI [(match_operand:QI 1 "s_operand" "Q")] 10))
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (unspec:SI [(match_operand:QI 1 "s_operand" "Q,S")] UNSPEC_SETHIGH))
(clobber (reg:CC 33))]
""
- "icm\\t%0,8,%1"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%0,8,%1
+ icmy\t%0,8,%1"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*sethighhisi"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (unspec:SI [(match_operand:HI 1 "s_operand" "Q")] 10))
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (unspec:SI [(match_operand:HI 1 "s_operand" "Q,S")] UNSPEC_SETHIGH))
(clobber (reg:CC 33))]
""
- "icm\\t%0,12,%1"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%0,12,%1
+ icmy\t%0,12,%1"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn "*sethighqidi_64"
[(set (match_operand:DI 0 "register_operand" "=d")
- (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
+ (unspec:DI [(match_operand:QI 1 "s_operand" "QS")] UNSPEC_SETHIGH))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "icmh\\t%0,8,%1"
- [(set_attr "op_type" "RSE")
- (set_attr "atype" "mem")])
+ "icmh\t%0,8,%1"
+ [(set_attr "op_type" "RSY")])
(define_insn "*sethighqidi_31"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (unspec:DI [(match_operand:QI 1 "s_operand" "Q,S")] UNSPEC_SETHIGH))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
- "icm\\t%0,8,%1"
- [(set_attr "op_type" "RS")
- (set_attr "atype" "mem")])
+ "@
+ icm\t%0,8,%1
+ icmy\t%0,8,%1"
+ [(set_attr "op_type" "RS,RSY")])
(define_insn_and_split "*extractqi"
[(set (match_operand:SI 0 "register_operand" "=d")
@@ -2059,15 +2415,14 @@
"#"
"&& reload_completed"
[(parallel
- [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
+ [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_SETHIGH))
(clobber (reg:CC 33))])
(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
- "
{
operands[2] = GEN_INT (32 - INTVAL (operands[2]));
operands[1] = change_address (operands[1], QImode, 0);
-}"
- [(set_attr "atype" "mem")])
+}
+ [(set_attr "atype" "agen")])
(define_insn_and_split "*extracthi"
[(set (match_operand:SI 0 "register_operand" "=d")
@@ -2080,15 +2435,14 @@
"#"
"&& reload_completed"
[(parallel
- [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
+ [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_SETHIGH))
(clobber (reg:CC 33))])
(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
- "
{
operands[2] = GEN_INT (32 - INTVAL (operands[2]));
operands[1] = change_address (operands[1], HImode, 0);
-}"
- [(set_attr "atype" "mem")])
+}
+ [(set_attr "atype" "agen")])
;
; extendsidi2 instruction pattern(s).
@@ -2116,10 +2470,9 @@
(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
"TARGET_64BIT"
"@
- lgfr\\t%0,%1
- lgf\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ lgfr\t%0,%1
+ lgf\t%0,%1"
+ [(set_attr "op_type" "RRE,RXY")])
;
; extendhidi2 instruction pattern(s).
@@ -2142,7 +2495,7 @@
{
operands[1] = gen_lowpart (DImode, operands[1]);
emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (48)));
- emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (48)));
+ emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (48)));
DONE;
}
}
@@ -2152,9 +2505,8 @@
[(set (match_operand:DI 0 "register_operand" "=d")
(sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
"TARGET_64BIT"
- "lgh\\t%0,%1"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "lgh\t%0,%1"
+ [(set_attr "op_type" "RXY")])
;
; extendqidi2 instruction pattern(s).
@@ -2177,18 +2529,28 @@
{
operands[1] = gen_lowpart (DImode, operands[1]);
emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (56)));
- emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (56)));
+ emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (56)));
DONE;
}
}
")
-(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:QI 1 "s_operand" "")))]
- "TARGET_64BIT && !reload_completed"
+(define_insn "*extendqidi2"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
+ "TARGET_64BIT && TARGET_LONG_DISPLACEMENT"
+ "lgb\t%0,%1"
+ [(set_attr "op_type" "RXY")])
+
+(define_insn_and_split "*extendqidi2_short_displ"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (sign_extend:DI (match_operand:QI 1 "s_operand" "Q")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && !TARGET_LONG_DISPLACEMENT"
+ "#"
+ "&& reload_completed"
[(parallel
- [(set (match_dup 0) (unspec:DI [(match_dup 1)] 10))
+ [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_SETHIGH))
(clobber (reg:CC 33))])
(parallel
[(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))
@@ -2207,18 +2569,19 @@
{
operands[1] = gen_lowpart (SImode, operands[1]);
emit_insn (gen_ashlsi3 (operands[0], operands[1], GEN_INT (16)));
- emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (16)));
+ emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (16)));
DONE;
}
")
(define_insn "*extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
""
- "lh\\t%0,%1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
+ "@
+ lh\t%0,%1
+ lhy\t%0,%1"
+ [(set_attr "op_type" "RX,RXY")])
;
; extendqisi2 instruction pattern(s).
@@ -2232,17 +2595,27 @@
{
operands[1] = gen_lowpart (SImode, operands[1]);
emit_insn (gen_ashlsi3 (operands[0], operands[1], GEN_INT (24)));
- emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (24)));
+ emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (24)));
DONE;
}
")
-(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (sign_extend:SI (match_operand:QI 1 "s_operand" "")))]
- "!reload_completed"
+(define_insn "*extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
+ "TARGET_LONG_DISPLACEMENT"
+ "lb\t%0,%1"
+ [(set_attr "op_type" "RXY")])
+
+(define_insn_and_split "*extendsiqi2_short_displ"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (sign_extend:SI (match_operand:QI 1 "s_operand" "Q")))
+ (clobber (reg:CC 33))]
+ "!TARGET_LONG_DISPLACEMENT"
+ "#"
+ "&& reload_completed"
[(parallel
- [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
+ [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_SETHIGH))
(clobber (reg:CC 33))])
(parallel
[(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))
@@ -2279,10 +2652,9 @@
(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
"TARGET_64BIT"
"@
- llgfr\\t%0,%1
- llgf\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ llgfr\t%0,%1
+ llgf\t%0,%1"
+ [(set_attr "op_type" "RRE,RXY")])
;
; zero_extendhidi2 instruction pattern(s).
@@ -2305,7 +2677,7 @@
{
operands[1] = gen_lowpart (DImode, operands[1]);
emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (48)));
- emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (48)));
+ emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (48)));
DONE;
}
}
@@ -2315,9 +2687,75 @@
[(set (match_operand:DI 0 "register_operand" "=d")
(zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
"TARGET_64BIT"
- "llgh\\t%0,%1"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "llgh\t%0,%1"
+ [(set_attr "op_type" "RXY")])
+
+;
+; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
+;
+
+(define_insn "*llgt_sisi"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,m")
+ (const_int 2147483647)))]
+ "TARGET_64BIT"
+ "@
+ llgtr\t%0,%1
+ llgt\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")])
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (const_int 2147483647)))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && reload_completed"
+ [(set (match_dup 0)
+ (and:SI (match_dup 1)
+ (const_int 2147483647)))]
+ "")
+
+(define_insn "*llgt_didi"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
+ (const_int 2147483647)))]
+ "TARGET_64BIT"
+ "@
+ llgtr\t%0,%1
+ llgt\t%0,%N1"
+ [(set_attr "op_type" "RRE,RXE")])
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
+ (const_int 2147483647)))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && reload_completed"
+ [(set (match_dup 0)
+ (and:DI (match_dup 1)
+ (const_int 2147483647)))]
+ "")
+
+(define_insn "*llgt_sidi"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
+ (const_int 2147483647)))]
+ "TARGET_64BIT"
+ "llgt\t%0,%1"
+ [(set_attr "op_type" "RXE")])
+
+(define_insn_and_split "*llgt_sidi_split"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
+ (const_int 2147483647)))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0)
+ (and:DI (subreg:DI (match_dup 1) 0)
+ (const_int 2147483647)))]
+ "")
;
; zero_extendqidi2 instruction pattern(s)
@@ -2340,7 +2778,7 @@
{
operands[1] = gen_lowpart (DImode, operands[1]);
emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (56)));
- emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (56)));
+ emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (56)));
DONE;
}
}
@@ -2350,9 +2788,8 @@
[(set (match_operand:DI 0 "register_operand" "=d")
(zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
"TARGET_64BIT"
- "llgc\\t%0,%1"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "llgc\t%0,%1"
+ [(set_attr "op_type" "RXY")])
;
; zero_extendhisi2 instruction pattern(s).
@@ -2374,13 +2811,12 @@
[(set (match_operand:SI 0 "register_operand" "=d")
(zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
"TARGET_64BIT"
- "llgh\\t%0,%1"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "llgh\t%0,%1"
+ [(set_attr "op_type" "RXY")])
(define_insn_and_split "*zero_extendhisi2_31"
[(set (match_operand:SI 0 "register_operand" "=&d")
- (zero_extend:SI (match_operand:HI 1 "memory_operand" "Q")))
+ (zero_extend:SI (match_operand:HI 1 "s_operand" "QS")))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
"#"
@@ -2390,8 +2826,8 @@
[(set (strict_low_part (match_dup 2)) (match_dup 1))
(clobber (reg:CC 33))])]
"operands[2] = gen_lowpart (HImode, operands[0]);"
- [(set_attr "atype" "mem")])
-
+ [(set_attr "atype" "agen")])
+
;
; zero_extendqisi2 instruction pattern(s).
;
@@ -2411,22 +2847,21 @@
(define_insn "*zero_extendqisi2_64"
[(set (match_operand:SI 0 "register_operand" "=d")
(zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
- "TARGET_64BIT"
- "llgc\\t%0,%1"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "TARGET_ZARCH"
+ "llgc\t%0,%1"
+ [(set_attr "op_type" "RXY")])
(define_insn_and_split "*zero_extendqisi2_31"
[(set (match_operand:SI 0 "register_operand" "=&d")
(zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
- "!TARGET_64BIT"
+ "!TARGET_ZARCH"
"#"
"&& reload_completed"
[(set (match_dup 0) (const_int 0))
(set (strict_low_part (match_dup 2)) (match_dup 1))]
"operands[2] = gen_lowpart (QImode, operands[0]);"
- [(set_attr "atype" "mem")])
-
+ [(set_attr "atype" "agen")])
+
;
; zero_extendqihi2 instruction pattern(s).
;
@@ -2434,7 +2869,7 @@
(define_expand "zero_extendqihi2"
[(set (match_operand:HI 0 "register_operand" "")
(zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
- "TARGET_64BIT"
+ "TARGET_ZARCH"
"
{
operands[1] = gen_lowpart (HImode, operands[1]);
@@ -2446,21 +2881,20 @@
(define_insn "*zero_extendqihi2_64"
[(set (match_operand:HI 0 "register_operand" "=d")
(zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
- "TARGET_64BIT"
- "llgc\\t%0,%1"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "TARGET_ZARCH"
+ "llgc\t%0,%1"
+ [(set_attr "op_type" "RXY")])
(define_insn_and_split "*zero_extendqihi2_31"
[(set (match_operand:HI 0 "register_operand" "=&d")
(zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
- "!TARGET_64BIT"
+ "!TARGET_ZARCH"
"#"
"&& reload_completed"
[(set (match_dup 0) (const_int 0))
(set (strict_low_part (match_dup 2)) (match_dup 1))]
"operands[2] = gen_lowpart (QImode, operands[0]);"
- [(set_attr "atype" "mem")])
+ [(set_attr "atype" "agen")])
;
@@ -2471,20 +2905,19 @@
[(set (match_operand:DI 0 "register_operand" "")
(unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "
{
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
rtx temp = gen_reg_rtx (DFmode);
operands[1] = force_reg (DFmode, operands[1]);
- emit_insn (gen_cmpdf (operands[1],
+ emit_insn (gen_cmpdf (operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"9223372036854775808.0\", DFmode), DFmode)));
+ REAL_VALUE_ATOF ("9223372036854775808.0", DFmode), DFmode)));
emit_jump_insn (gen_blt (label1));
emit_insn (gen_subdf3 (temp, operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"18446744073709551616.0\", DFmode), DFmode)));
+ REAL_VALUE_ATOF ("18446744073709551616.0", DFmode), DFmode)));
emit_insn (gen_fix_truncdfdi2_ieee (operands[0], temp, GEN_INT(7)));
emit_jump (label2);
@@ -2492,28 +2925,27 @@
emit_insn (gen_fix_truncdfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
emit_label (label2);
DONE;
-}")
+})
(define_expand "fix_truncdfdi2"
[(set (match_operand:DI 0 "register_operand" "")
(fix:DI (match_operand:DF 1 "nonimmediate_operand" "")))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "
{
operands[1] = force_reg (DFmode, operands[1]);
emit_insn (gen_fix_truncdfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
DONE;
-}")
+})
(define_insn "fix_truncdfdi2_ieee"
[(set (match_operand:DI 0 "register_operand" "=d")
(fix:DI (match_operand:DF 1 "register_operand" "f")))
- (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] 1)
+ (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
(clobber (reg:CC 33))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cgdbr\\t%0,%h2,%1"
+ "cgdbr\t%0,%h2,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other")])
+ (set_attr "type" "ftoi")])
;
; fixuns_truncdfsi2 and fix_truncdfsi2 instruction pattern(s).
@@ -2523,20 +2955,19 @@
[(set (match_operand:SI 0 "register_operand" "")
(unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "
{
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
rtx temp = gen_reg_rtx (DFmode);
operands[1] = force_reg (DFmode,operands[1]);
- emit_insn (gen_cmpdf (operands[1],
+ emit_insn (gen_cmpdf (operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"2147483648.0\", DFmode), DFmode)));
+ REAL_VALUE_ATOF ("2147483648.0", DFmode), DFmode)));
emit_jump_insn (gen_blt (label1));
emit_insn (gen_subdf3 (temp, operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"4294967296.0\", DFmode), DFmode)));
+ REAL_VALUE_ATOF ("4294967296.0", DFmode), DFmode)));
emit_insn (gen_fix_truncdfsi2_ieee (operands[0], temp, GEN_INT (7)));
emit_jump (label2);
@@ -2544,42 +2975,41 @@
emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
emit_label (label2);
DONE;
-}")
+})
(define_expand "fix_truncdfsi2"
[(set (match_operand:SI 0 "register_operand" "")
(fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))]
"TARGET_HARD_FLOAT"
- "
{
- if (TARGET_IBM_FLOAT)
+ if (TARGET_IBM_FLOAT)
{
/* This is the algorithm from POP chapter A.5.7.2. */
- rtx temp = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
+ rtx temp = assign_stack_local (BLKmode, 8, BITS_PER_WORD);
rtx two31r = s390_gen_rtx_const_DI (0x4f000000, 0x08000000);
rtx two32 = s390_gen_rtx_const_DI (0x4e000001, 0x00000000);
operands[1] = force_reg (DFmode, operands[1]);
- emit_insn (gen_fix_truncdfsi2_ibm (operands[0], operands[1],
+ emit_insn (gen_fix_truncdfsi2_ibm (operands[0], operands[1],
two31r, two32, temp));
- }
- else
+ }
+ else
{
operands[1] = force_reg (DFmode, operands[1]);
emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
}
DONE;
-}")
+})
(define_insn "fix_truncdfsi2_ieee"
[(set (match_operand:SI 0 "register_operand" "=d")
(fix:SI (match_operand:DF 1 "register_operand" "f")))
- (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] 1)
+ (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] UNSPEC_ROUND)
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cfdbr\\t%0,%h2,%1"
+ "cfdbr\t%0,%h2,%1"
[(set_attr "op_type" "RRE")
(set_attr "type" "other" )])
@@ -2591,16 +3021,16 @@
(use (match_operand:BLK 4 "memory_operand" "m"))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "*
{
- output_asm_insn (\"sd\\t%1,%2\", operands);
- output_asm_insn (\"aw\\t%1,%3\", operands);
- output_asm_insn (\"std\\t%1,%4\", operands);
- output_asm_insn (\"xi\\t%N4,128\", operands);
- return \"l\\t%0,%N4\";
-}"
+ output_asm_insn ("sd\t%1,%2", operands);
+ output_asm_insn ("aw\t%1,%3", operands);
+ output_asm_insn ("std\t%1,%4", operands);
+ output_asm_insn ("xi\t%N4,128", operands);
+ return "l\t%0,%N4";
+}
[(set_attr "op_type" "NN")
- (set_attr "type" "other")
+ (set_attr "type" "ftoi")
+ (set_attr "atype" "agen")
(set_attr "length" "20")])
;
@@ -2611,21 +3041,20 @@
[(set (match_operand:DI 0 "register_operand" "")
(unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "
{
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
rtx temp = gen_reg_rtx (SFmode);
operands[1] = force_reg (SFmode, operands[1]);
- emit_insn (gen_cmpsf (operands[1],
+ emit_insn (gen_cmpsf (operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"9223372036854775808.0\", SFmode), SFmode)));
+ REAL_VALUE_ATOF ("9223372036854775808.0", SFmode), SFmode)));
emit_jump_insn (gen_blt (label1));
emit_insn (gen_subsf3 (temp, operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"18446744073709551616.0\", SFmode), SFmode)));
+ REAL_VALUE_ATOF ("18446744073709551616.0", SFmode), SFmode)));
emit_insn (gen_fix_truncsfdi2_ieee (operands[0], temp, GEN_INT(7)));
emit_jump (label2);
@@ -2633,28 +3062,27 @@
emit_insn (gen_fix_truncsfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
emit_label (label2);
DONE;
-}")
+})
(define_expand "fix_truncsfdi2"
[(set (match_operand:DI 0 "register_operand" "")
(fix:DI (match_operand:SF 1 "nonimmediate_operand" "")))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "
{
operands[1] = force_reg (SFmode, operands[1]);
emit_insn (gen_fix_truncsfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
DONE;
-}")
+})
(define_insn "fix_truncsfdi2_ieee"
[(set (match_operand:DI 0 "register_operand" "=d")
(fix:DI (match_operand:SF 1 "register_operand" "f")))
- (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] 1)
+ (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
(clobber (reg:CC 33))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cgebr\\t%0,%h2,%1"
+ "cgebr\t%0,%h2,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other")])
+ (set_attr "type" "ftoi")])
;
; fixuns_truncsfsi2 and fix_truncsfsi2 instruction pattern(s).
@@ -2664,7 +3092,6 @@
[(set (match_operand:SI 0 "register_operand" "")
(unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "
{
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
@@ -2673,11 +3100,11 @@
operands[1] = force_reg (SFmode, operands[1]);
emit_insn (gen_cmpsf (operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"2147483648.0\", SFmode), SFmode)));
+ REAL_VALUE_ATOF ("2147483648.0", SFmode), SFmode)));
emit_jump_insn (gen_blt (label1));
emit_insn (gen_subsf3 (temp, operands[1],
CONST_DOUBLE_FROM_REAL_VALUE (
- REAL_VALUE_ATOF (\"4294967296.0\", SFmode), SFmode)));
+ REAL_VALUE_ATOF ("4294967296.0", SFmode), SFmode)));
emit_insn (gen_fix_truncsfsi2_ieee (operands[0], temp, GEN_INT (7)));
emit_jump (label2);
@@ -2685,13 +3112,12 @@
emit_insn (gen_fix_truncsfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
emit_label (label2);
DONE;
-}")
+})
(define_expand "fix_truncsfsi2"
[(set (match_operand:SI 0 "register_operand" "")
(fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))]
"TARGET_HARD_FLOAT"
- "
{
if (TARGET_IBM_FLOAT)
{
@@ -2707,17 +3133,17 @@
}
DONE;
-}")
+})
(define_insn "fix_truncsfsi2_ieee"
[(set (match_operand:SI 0 "register_operand" "=d")
(fix:SI (match_operand:SF 1 "register_operand" "f")))
- (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] 1)
+ (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] UNSPEC_ROUND)
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cfebr\\t%0,%h2,%1"
+ "cfebr\t%0,%h2,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other")])
+ (set_attr "type" "ftoi")])
;
; floatdidf2 instruction pattern(s).
@@ -2728,9 +3154,9 @@
(float:DF (match_operand:DI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cdgbr\\t%0,%1"
+ "cdgbr\t%0,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other" )])
+ (set_attr "type" "itof" )])
;
; floatdisf2 instruction pattern(s).
@@ -2741,9 +3167,9 @@
(float:SF (match_operand:DI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cegbr\\t%0,%1"
+ "cegbr\t%0,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other" )])
+ (set_attr "type" "itof" )])
;
; floatsidf2 instruction pattern(s).
@@ -2755,28 +3181,27 @@
(float:DF (match_operand:SI 1 "register_operand" "")))
(clobber (reg:CC 33))])]
"TARGET_HARD_FLOAT"
- "
{
- if (TARGET_IBM_FLOAT)
+ if (TARGET_IBM_FLOAT)
{
/* This is the algorithm from POP chapter A.5.7.1. */
- rtx temp = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
- rtx two31 = s390_gen_rtx_const_DI (0x4e000000, 0x80000000);
+ rtx temp = assign_stack_local (BLKmode, 8, BITS_PER_WORD);
+ rtx two31 = s390_gen_rtx_const_DI (0x4e000000, 0x80000000);
emit_insn (gen_floatsidf2_ibm (operands[0], operands[1], two31, temp));
DONE;
}
-}")
+})
(define_insn "floatsidf2_ieee"
[(set (match_operand:DF 0 "register_operand" "=f")
(float:DF (match_operand:SI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cdfbr\\t%0,%1"
+ "cdfbr\t%0,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other" )])
+ (set_attr "type" "itof" )])
(define_insn "floatsidf2_ibm"
[(set (match_operand:DF 0 "register_operand" "=f")
@@ -2785,16 +3210,16 @@
(use (match_operand:BLK 3 "memory_operand" "m"))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "*
{
- output_asm_insn (\"st\\t%1,%N3\", operands);
- output_asm_insn (\"xi\\t%N3,128\", operands);
- output_asm_insn (\"mvc\\t%O3(4,%R3),%2\", operands);
- output_asm_insn (\"ld\\t%0,%3\", operands);
- return \"sd\\t%0,%2\";
-}"
+ output_asm_insn ("st\t%1,%N3", operands);
+ output_asm_insn ("xi\t%N3,128", operands);
+ output_asm_insn ("mvc\t%O3(4,%R3),%2", operands);
+ output_asm_insn ("ld\t%0,%3", operands);
+ return "sd\t%0,%2";
+}
[(set_attr "op_type" "NN")
(set_attr "type" "other" )
+ (set_attr "atype" "agen")
(set_attr "length" "20")])
;
@@ -2807,7 +3232,6 @@
(float:SF (match_operand:SI 1 "register_operand" "")))
(clobber (reg:CC 33))])]
"TARGET_HARD_FLOAT"
- "
{
if (TARGET_IBM_FLOAT)
{
@@ -2817,16 +3241,16 @@
emit_insn (gen_truncdfsf2 (operands[0], temp));
DONE;
}
-}")
+})
(define_insn "floatsisf2_ieee"
[(set (match_operand:SF 0 "register_operand" "=f")
(float:SF (match_operand:SI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "cefbr\\t%0,%1"
+ "cefbr\t%0,%1"
[(set_attr "op_type" "RRE")
- (set_attr "type" "other" )])
+ (set_attr "type" "itof" )])
;
; truncdfsf2 instruction pattern(s).
@@ -2842,18 +3266,18 @@
[(set (match_operand:SF 0 "register_operand" "=f")
(float_truncate:SF (match_operand:DF 1 "general_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "ledbr\\t%0,%1"
+ "ledbr\t%0,%1"
[(set_attr "op_type" "RRE")])
(define_insn "truncdfsf2_ibm"
[(set (match_operand:SF 0 "register_operand" "=f,f")
- (float_truncate:SF (match_operand:DF 1 "general_operand" "f,m")))]
+ (float_truncate:SF (match_operand:DF 1 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- lrer\\t%0,%1
- le\\t%0,%1"
+ lrer\t%0,%1
+ le\t%0,%1"
[(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "floads,floads")])
;
; extendsfdf2 instruction pattern(s).
@@ -2863,41 +3287,42 @@
[(set (match_operand:DF 0 "register_operand" "")
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
"TARGET_HARD_FLOAT"
- "
{
if (TARGET_IBM_FLOAT)
{
emit_insn (gen_extendsfdf2_ibm (operands[0], operands[1]));
DONE;
}
-}")
+})
(define_insn "extendsfdf2_ieee"
[(set (match_operand:DF 0 "register_operand" "=f,f")
- (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m")))]
+ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- ldebr\\t%0,%1
- ldeb\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")])
+ ldebr\t%0,%1
+ ldeb\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "floads,floads")])
(define_insn "extendsfdf2_ibm"
[(set (match_operand:DF 0 "register_operand" "=f,f")
- (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m")))
+ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- sdr\\t%0,%0\;ler\\t%0,%1
- sdr\\t%0,%0\;le\\t%0,%1"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")
- (set_attr "type" "o2,o2")])
+ sdr\t%0,%0\;ler\t%0,%1
+ sdr\t%0,%0\;le\t%0,%1"
+ [(set_attr "op_type" "NN,NN")
+ (set_attr "atype" "reg,agen")
+ (set_attr "length" "4,6")
+ (set_attr "type" "o2,o2")])
;;
-;; ARITHMETRIC OPERATIONS
+;; ARITHMETIC OPERATIONS
;;
-; arithmetric operations set the ConditionCode,
+; arithmetic operations set the ConditionCode,
; because of unpredictable Bits in Register for Halfword and Byte
; the ConditionCode can be set wrong in operations for Halfword and Byte
@@ -2916,13 +3341,12 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- agfr\\t%0,%2
- agf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ agfr\t%0,%2
+ agf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_zero_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
(match_operand:DI 1 "register_operand" "0,0"))
(const_int 0)))
@@ -2930,23 +3354,21 @@
(plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
"s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- algfr\\t%0,%2
- algf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ algfr\t%0,%2
+ algf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_zero_cconly"
- [(set (reg 33)
+ [(set (reg 33)
(compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
(match_operand:DI 1 "register_operand" "0,0"))
(const_int 0)))
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- algfr\\t%0,%2
- algf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ algfr\t%0,%2
+ algf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_zero"
[(set (match_operand:DI 0 "register_operand" "=d,d")
@@ -2955,27 +3377,75 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- algfr\\t%0,%2
- algf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ algfr\t%0,%2
+ algf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_imm_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "0")
(match_operand:DI 2 "const_int_operand" "K"))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=d")
(plus:DI (match_dup 1) (match_dup 2)))]
- "TARGET_64BIT
- && s390_match_ccmode (insn, CCAmode)
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
- "aghi\\t%0,%h2"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+ "TARGET_64BIT
+ && s390_match_ccmode (insn, CCAmode)
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")"
+ "aghi\t%0,%h2"
+ [(set_attr "op_type" "RI")])
+
+(define_insn "*adddi3_carry1_cc"
+ [(set (reg 33)
+ (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_dup 1)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT"
+ "@
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*adddi3_carry1_cconly"
+ [(set (reg 33)
+ (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_dup 1)))
+ (clobber (match_scratch:DI 0 "=d,d"))]
+ "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT"
+ "@
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*adddi3_carry2_cc"
+ [(set (reg 33)
+ (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_dup 2)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT"
+ "@
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*adddi3_carry2_cconly"
+ [(set (reg 33)
+ (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_dup 2)))
+ (clobber (match_scratch:DI 0 "=d,d"))]
+ "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT"
+ "@
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
(match_operand:DI 2 "general_operand" "d,m"))
(const_int 0)))
@@ -2983,35 +3453,32 @@
(plus:DI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- algr\\t%0,%2
- alg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_cconly"
- [(set (reg 33)
+ [(set (reg 33)
(compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
(match_operand:DI 2 "general_operand" "d,m"))
(const_int 0)))
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- algr\\t%0,%2
- alg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_cconly2"
- [(set (reg 33)
+ [(set (reg 33)
(compare (match_operand:DI 1 "nonimmediate_operand" "%0,0")
(neg:SI (match_operand:DI 2 "general_operand" "d,m"))))
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode(insn, CCLmode) && TARGET_64BIT"
"@
- algr\\t%0,%2
- alg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ algr\t%0,%2
+ alg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*adddi3_64"
[(set (match_operand:DI 0 "register_operand" "=d,d,d")
@@ -3020,18 +3487,42 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- agr\\t%0,%2
- aghi\\t%0,%h2
- ag\\t%0,%2"
- [(set_attr "op_type" "RRE,RI,RXE")
- (set_attr "atype" "reg,reg,mem")])
+ agr\t%0,%2
+ aghi\t%0,%h2
+ ag\t%0,%2"
+ [(set_attr "op_type" "RRE,RI,RXY")])
+
+(define_insn_and_split "*adddi3_31z"
+ [(set (match_operand:DI 0 "register_operand" "=&d")
+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
+ (match_operand:DI 2 "general_operand" "do") ) )
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "#"
+ "&& reload_completed"
+ [(parallel
+ [(set (reg:CCL1 33)
+ (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
+ (match_dup 7)))
+ (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
+ (parallel
+ [(set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
+ (ltu:SI (reg:CCL1 33) (const_int 0))))
+ (clobber (reg:CC 33))])]
+ "operands[3] = operand_subword (operands[0], 0, 0, DImode);
+ operands[4] = operand_subword (operands[1], 0, 0, DImode);
+ operands[5] = operand_subword (operands[2], 0, 0, DImode);
+ operands[6] = operand_subword (operands[0], 1, 0, DImode);
+ operands[7] = operand_subword (operands[1], 1, 0, DImode);
+ operands[8] = operand_subword (operands[2], 1, 0, DImode);"
+ [(set_attr "op_type" "NN")])
(define_insn_and_split "*adddi3_31"
[(set (match_operand:DI 0 "register_operand" "=&d")
(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
(match_operand:DI 2 "general_operand" "do") ) )
(clobber (reg:CC 33))]
- "!TARGET_64BIT"
+ "!TARGET_CPU_ZARCH"
"#"
"&& reload_completed"
[(parallel
@@ -3068,277 +3559,138 @@
""
"")
-(define_insn "*la_64"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (match_operand:QI 1 "address_operand" "p"))]
- "TARGET_64BIT"
- "la\\t%0,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_peephole2
- [(parallel
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:QI 1 "address_operand" ""))
- (clobber (reg:CC 33))])]
- "TARGET_64BIT
- && strict_memory_address_p (VOIDmode, operands[1])
- && preferred_la_operand_p (operands[1])"
- [(set (match_dup 0) (match_dup 1))]
- "")
-
-(define_peephole2
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" ""))
- (parallel
- [(set (match_dup 0)
- (plus:DI (match_dup 0)
- (match_operand:DI 2 "nonmemory_operand" "")))
- (clobber (reg:CC 33))])]
- "TARGET_64BIT
- && !reg_overlap_mentioned_p (operands[0], operands[2])
- && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (DImode, operands[1], operands[2]))
- && preferred_la_operand_p (gen_rtx_PLUS (DImode, operands[1], operands[2]))"
- [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
- "")
-
-(define_expand "reload_indi"
- [(parallel [(match_operand:DI 0 "register_operand" "=a")
- (match_operand:DI 1 "s390_plus_operand" "")
- (match_operand:DI 2 "register_operand" "=&a")])]
- "TARGET_64BIT"
- "
-{
- s390_expand_plus_operand (operands[0], operands[1], operands[2]);
- DONE;
-}")
-
-
;
; addsi3 instruction pattern(s).
;
(define_insn "*addsi3_imm_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "0")
(match_operand:SI 2 "const_int_operand" "K"))
(const_int 0)))
(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode (insn, CCAmode)
- && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
- "ahi\\t%0,%h2"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")"
+ "ahi\t%0,%h2"
+ [(set_attr "op_type" "RI")])
(define_insn "*addsi3_carry1_cc"
- [(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(match_dup 1)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(plus:SI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode (insn, CCL1mode)"
+ "s390_match_ccmode (insn, CCL1mode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_carry1_cconly"
- [(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(match_dup 1)))
- (clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode (insn, CCL1mode)"
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode (insn, CCL1mode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_carry2_cc"
- [(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(match_dup 2)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(plus:SI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode (insn, CCL1mode)"
+ "s390_match_ccmode (insn, CCL1mode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_carry2_cconly"
- [(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(match_dup 2)))
- (clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode (insn, CCL1mode)"
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode (insn, CCL1mode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_cc"
- [(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(plus:SI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode (insn, CCLmode)"
+ "s390_match_ccmode (insn, CCLmode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_cconly"
- [(set (reg 33)
- (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode (insn, CCLmode)"
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode (insn, CCLmode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_cconly2"
- [(set (reg 33)
- (compare (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (neg:SI (match_operand:SI 2 "general_operand" "d,m"))))
- (clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode(insn, CCLmode)"
+ [(set (reg 33)
+ (compare (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (neg:SI (match_operand:SI 2 "general_operand" "d,R,T"))))
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode (insn, CCLmode)"
"@
- alr\\t%0,%2
- al\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ alr\t%0,%2
+ al\t%0,%2
+ aly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*addsi3_sign"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (plus:SI (match_operand:SI 1 "register_operand" "0")
- (sign_extend:SI (match_operand:HI 2 "memory_operand" "m"))))
- (clobber (reg:CC 33))]
- ""
- "ah\\t%0,%2"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
-
-(define_insn "*addsi3_sub"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (plus:SI (match_operand:SI 1 "register_operand" "0")
- (subreg:SI (match_operand:HI 2 "memory_operand" "m") 0)))
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (match_operand:SI 1 "register_operand" "0,0")
+ (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
(clobber (reg:CC 33))]
""
- "ah\\t%0,%2"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
+ "@
+ ah\t%0,%2
+ ahy\t%0,%2"
+ [(set_attr "op_type" "RX,RXY")])
(define_insn "addsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:SI 2 "general_operand" "d,K,m")))
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
+ (match_operand:SI 2 "general_operand" "d,K,R,T")))
(clobber (reg:CC 33))]
""
"@
- ar\\t%0,%2
- ahi\\t%0,%h2
- a\\t%0,%2"
- [(set_attr "op_type" "RR,RI,RX")
- (set_attr "atype" "reg,reg,mem")])
-
-(define_insn "*la_31"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:QI 1 "address_operand" "p"))]
- "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
- "la\\t%0,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_peephole2
- [(parallel
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:QI 1 "address_operand" ""))
- (clobber (reg:CC 33))])]
- "!TARGET_64BIT
- && strict_memory_address_p (VOIDmode, operands[1])
- && preferred_la_operand_p (operands[1])"
- [(set (match_dup 0) (match_dup 1))]
- "")
-
-(define_peephole2
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "register_operand" ""))
- (parallel
- [(set (match_dup 0)
- (plus:SI (match_dup 0)
- (match_operand:SI 2 "nonmemory_operand" "")))
- (clobber (reg:CC 33))])]
- "!TARGET_64BIT
- && !reg_overlap_mentioned_p (operands[0], operands[2])
- && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (SImode, operands[1], operands[2]))
- && preferred_la_operand_p (gen_rtx_PLUS (SImode, operands[1], operands[2]))"
- [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
- "")
-
-(define_insn "*la_31_and"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (and:SI (match_operand:QI 1 "address_operand" "p")
- (const_int 2147483647)))]
- "!TARGET_64BIT"
- "la\\t%0,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_insn_and_split "*la_31_and_cc"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (and:SI (match_operand:QI 1 "address_operand" "p")
- (const_int 2147483647)))
- (clobber (reg:CC 33))]
- "!TARGET_64BIT"
- "#"
- "&& reload_completed"
- [(set (match_dup 0)
- (and:SI (match_dup 1) (const_int 2147483647)))]
- ""
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_insn "force_la_31"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:QI 1 "address_operand" "p"))
- (use (const_int 0))]
- "!TARGET_64BIT"
- "la\\t%0,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")
- (set_attr "type" "la")])
-
-(define_expand "reload_insi"
- [(parallel [(match_operand:SI 0 "register_operand" "=a")
- (match_operand:SI 1 "s390_plus_operand" "")
- (match_operand:SI 2 "register_operand" "=&a")])]
- "!TARGET_64BIT"
- "
-{
- s390_expand_plus_operand (operands[0], operands[1], operands[2]);
- DONE;
-}")
-
+ ar\t%0,%2
+ ahi\t%0,%h2
+ a\t%0,%2
+ ay\t%0,%2"
+ [(set_attr "op_type" "RR,RI,RX,RXY")])
;
; adddf3 instruction pattern(s).
@@ -3348,7 +3700,7 @@
[(parallel
[(set (match_operand:DF 0 "register_operand" "=f,f")
(plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
+ (match_operand:DF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))])]
"TARGET_HARD_FLOAT"
"")
@@ -3356,26 +3708,53 @@
(define_insn "*adddf3"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
+ (match_operand:DF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- adbr\\t%0,%2
- adb\\t%0,%2"
+ adbr\t%0,%2
+ adb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimpd,fsimpd")])
+
+(define_insn "*adddf3_cc"
+ [(set (reg 33)
+ (compare (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DF 2 "general_operand" "f,R"))
+ (match_operand:DF 3 "const0_operand" "")))
+ (set (match_operand:DF 0 "register_operand" "=f,f")
+ (plus:DF (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ adbr\t%0,%2
+ adb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimpd,fsimpd")])
+
+(define_insn "*adddf3_cconly"
+ [(set (reg 33)
+ (compare (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DF 2 "general_operand" "f,R"))
+ (match_operand:DF 3 "const0_operand" "")))
+ (clobber (match_scratch:DF 0 "=f,f"))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ adbr\t%0,%2
+ adb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimpd,fsimpd")])
(define_insn "*adddf3_ibm"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
+ (match_operand:DF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- adr\\t%0,%2
- ad\\t%0,%2"
+ adr\t%0,%2
+ ad\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimpd,fsimpd")])
;
; addsf3 instruction pattern(s).
@@ -3385,7 +3764,7 @@
[(parallel
[(set (match_operand:SF 0 "register_operand" "=f,f")
(plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
+ (match_operand:SF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))])]
"TARGET_HARD_FLOAT"
"")
@@ -3393,26 +3772,53 @@
(define_insn "*addsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
+ (match_operand:SF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- aebr\\t%0,%2
- aeb\\t%0,%2"
+ aebr\t%0,%2
+ aeb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimps,fsimps")])
+
+(define_insn "*addsf3_cc"
+ [(set (reg 33)
+ (compare (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SF 2 "general_operand" "f,R"))
+ (match_operand:SF 3 "const0_operand" "")))
+ (set (match_operand:SF 0 "register_operand" "=f,f")
+ (plus:SF (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ aebr\t%0,%2
+ aeb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimps,fsimps")])
+
+(define_insn "*addsf3_cconly"
+ [(set (reg 33)
+ (compare (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SF 2 "general_operand" "f,R"))
+ (match_operand:SF 3 "const0_operand" "")))
+ (clobber (match_scratch:SF 0 "=f,f"))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ aebr\t%0,%2
+ aeb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimps,fsimps")])
(define_insn "*addsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
+ (match_operand:SF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- aer\\t%0,%2
- ae\\t%0,%2"
+ aer\t%0,%2
+ ae\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimps,fsimps")])
;;
@@ -3430,13 +3836,12 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- sgfr\\t%0,%2
- sgf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ sgfr\t%0,%2
+ sgf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_zero_cc"
- [(set (reg 33)
+ [(set (reg 33)
(compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
(zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))
(const_int 0)))
@@ -3444,23 +3849,21 @@
(minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
"s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- slgfr\\t%0,%2
- slgf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ slgfr\t%0,%2
+ slgf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_zero_cconly"
- [(set (reg 33)
+ [(set (reg 33)
(compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
(zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))
(const_int 0)))
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- slgfr\\t%0,%2
- slgf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ slgfr\t%0,%2
+ slgf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_zero"
[(set (match_operand:DI 0 "register_operand" "=d,d")
@@ -3469,10 +3872,34 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- slgfr\\t%0,%2
- slgf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ slgfr\t%0,%2
+ slgf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subdi3_borrow_cc"
+ [(set (reg 33)
+ (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_dup 1)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (minus:DI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCL2mode) && TARGET_64BIT"
+ "@
+ slgr\t%0,%2
+ slg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subdi3_borrow_cconly"
+ [(set (reg 33)
+ (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_dup 1)))
+ (clobber (match_scratch:DI 0 "=d,d"))]
+ "s390_match_ccmode (insn, CCL2mode) && TARGET_64BIT"
+ "@
+ slgr\t%0,%2
+ slg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_cc"
[(set (reg 33)
@@ -3481,12 +3908,11 @@
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=d,d")
(minus:DI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode (insn, CCLmode)"
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- slgr\\t%0,%2
- slg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ slgr\t%0,%2
+ slg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_cconly"
[(set (reg 33)
@@ -3494,12 +3920,11 @@
(match_operand:DI 2 "general_operand" "d,m"))
(const_int 0)))
(clobber (match_scratch:DI 0 "=d,d"))]
- "s390_match_ccmode (insn, CCLmode)"
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
"@
- slgr\\t%0,%2
- slg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ slgr\t%0,%2
+ slg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*subdi3_64"
[(set (match_operand:DI 0 "register_operand" "=d,d")
@@ -3508,17 +3933,41 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- sgr\\t%0,%2
- sg\\t%0,%2"
- [(set_attr "op_type" "RRE,RRE")
- (set_attr "atype" "reg,mem")])
+ sgr\t%0,%2
+ sg\t%0,%2"
+ [(set_attr "op_type" "RRE,RRE")])
+
+(define_insn_and_split "*subdi3_31z"
+ [(set (match_operand:DI 0 "register_operand" "=&d")
+ (minus:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:DI 2 "general_operand" "do") ) )
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "#"
+ "&& reload_completed"
+ [(parallel
+ [(set (reg:CCL2 33)
+ (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
+ (match_dup 7)))
+ (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
+ (parallel
+ [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
+ (gtu:SI (reg:CCL2 33) (const_int 0))))
+ (clobber (reg:CC 33))])]
+ "operands[3] = operand_subword (operands[0], 0, 0, DImode);
+ operands[4] = operand_subword (operands[1], 0, 0, DImode);
+ operands[5] = operand_subword (operands[2], 0, 0, DImode);
+ operands[6] = operand_subword (operands[0], 1, 0, DImode);
+ operands[7] = operand_subword (operands[1], 1, 0, DImode);
+ operands[8] = operand_subword (operands[2], 1, 0, DImode);"
+ [(set_attr "op_type" "NN")])
(define_insn_and_split "*subdi3_31"
[(set (match_operand:DI 0 "register_operand" "=&d")
(minus:DI (match_operand:DI 1 "register_operand" "0")
(match_operand:DI 2 "general_operand" "do") ) )
(clobber (reg:CC 33))]
- "!TARGET_64BIT"
+ "!TARGET_CPU_ZARCH"
"#"
"&& reload_completed"
[(parallel
@@ -3561,89 +4010,80 @@
(define_insn "*subsi3_borrow_cc"
[(set (reg 33)
- (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(match_dup 1)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(minus:SI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode(insn, CCL2mode)"
+ "s390_match_ccmode (insn, CCL2mode)"
"@
- slr\\t%0,%2
- sl\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ slr\t%0,%2
+ sl\t%0,%2
+ sly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*subsi3_borrow_cconly"
[(set (reg 33)
- (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(match_dup 1)))
- (clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode(insn, CCL2mode)"
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode (insn, CCL2mode)"
"@
- slr\\t%0,%2
- sl\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ slr\t%0,%2
+ sl\t%0,%2
+ sly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*subsi3_cc"
[(set (reg 33)
- (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(minus:SI (match_dup 1) (match_dup 2)))]
- "s390_match_ccmode(insn, CCLmode)"
+ "s390_match_ccmode (insn, CCLmode)"
"@
- slr\\t%0,%2
- sl\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ slr\t%0,%2
+ sl\t%0,%2
+ sly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*subsi3_cconly"
[(set (reg 33)
- (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
- "s390_match_ccmode(insn, CCLmode)"
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode (insn, CCLmode)"
"@
- slr\\t%0,%2
- sl\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ slr\t%0,%2
+ sl\t%0,%2
+ sly\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*subsi3_sign"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (minus:SI (match_operand:SI 1 "register_operand" "0")
- (sign_extend:SI (match_operand:HI 2 "memory_operand" "m"))))
- (clobber (reg:CC 33))]
- ""
- "sh\\t%0,%2"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
-
-(define_insn "*subsi3_sub"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (minus:SI (match_operand:SI 1 "register_operand" "0")
- (subreg:SI (match_operand:HI 2 "memory_operand" "m") 0)))
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (minus:SI (match_operand:SI 1 "register_operand" "0,0")
+ (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
(clobber (reg:CC 33))]
""
- "sh\\t%0,%2"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
+ "@
+ sh\t%0,%2
+ shy\t%0,%2"
+ [(set_attr "op_type" "RX,RXY")])
(define_insn "subsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (minus:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "general_operand" "d,m")))
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d")
+ (minus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T")))
(clobber (reg:CC 33))]
""
"@
- sr\\t%0,%2
- s\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ sr\t%0,%2
+ s\t%0,%2
+ sy\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
;
@@ -3654,7 +4094,7 @@
[(parallel
[(set (match_operand:DF 0 "register_operand" "=f,f")
(minus:DF (match_operand:DF 1 "register_operand" "0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
+ (match_operand:DF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))])]
"TARGET_HARD_FLOAT"
"")
@@ -3662,26 +4102,53 @@
(define_insn "*subdf3"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(minus:DF (match_operand:DF 1 "register_operand" "0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
+ (match_operand:DF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- sdbr\\t%0,%2
- sdb\\t%0,%2"
+ sdbr\t%0,%2
+ sdb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimpd,fsimpd")])
+
+(define_insn "*subdf3_cc"
+ [(set (reg 33)
+ (compare (minus:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")
+ (match_operand:DF 2 "general_operand" "f,R"))
+ (match_operand:DF 3 "const0_operand" "")))
+ (set (match_operand:DF 0 "register_operand" "=f,f")
+ (plus:DF (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ sdbr\t%0,%2
+ sdb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimpd,fsimpd")])
+
+(define_insn "*subdf3_cconly"
+ [(set (reg 33)
+ (compare (minus:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")
+ (match_operand:DF 2 "general_operand" "f,R"))
+ (match_operand:DF 3 "const0_operand" "")))
+ (clobber (match_scratch:DF 0 "=f,f"))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ sdbr\t%0,%2
+ sdb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimpd,fsimpd")])
(define_insn "*subdf3_ibm"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(minus:DF (match_operand:DF 1 "register_operand" "0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
+ (match_operand:DF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- sdr\\t%0,%2
- sd\\t%0,%2"
+ sdr\t%0,%2
+ sd\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimpd,fsimpd")])
;
; subsf3 instruction pattern(s).
@@ -3691,7 +4158,7 @@
[(parallel
[(set (match_operand:SF 0 "register_operand" "=f,f")
(minus:SF (match_operand:SF 1 "register_operand" "0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
+ (match_operand:SF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))])]
"TARGET_HARD_FLOAT"
"")
@@ -3699,26 +4166,174 @@
(define_insn "*subsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(minus:SF (match_operand:SF 1 "register_operand" "0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
+ (match_operand:SF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- sebr\\t%0,%2
- seb\\t%0,%2"
+ sebr\t%0,%2
+ seb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimps,fsimps")])
+
+(define_insn "*subsf3_cc"
+ [(set (reg 33)
+ (compare (minus:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")
+ (match_operand:SF 2 "general_operand" "f,R"))
+ (match_operand:SF 3 "const0_operand" "")))
+ (set (match_operand:SF 0 "register_operand" "=f,f")
+ (minus:SF (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ sebr\t%0,%2
+ seb\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fsimps,fsimps")])
+
+(define_insn "*subsf3_cconly"
+ [(set (reg 33)
+ (compare (minus:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")
+ (match_operand:SF 2 "general_operand" "f,R"))
+ (match_operand:SF 3 "const0_operand" "")))
+ (clobber (match_scratch:SF 0 "=f,f"))]
+ "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ sebr\t%0,%2
+ seb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimps,fsimps")])
(define_insn "*subsf3_ibm"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(minus:SF (match_operand:SF 1 "register_operand" "0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
+ (match_operand:SF 2 "general_operand" "f,R")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- ser\\t%0,%2
- se\\t%0,%2"
+ ser\t%0,%2
+ se\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fsimps,fsimps")])
+
+
+;;
+;;- Conditional add/subtract instructions.
+;;
+
+;
+; adddicc instruction pattern(s).
+;
+
+(define_insn "*adddi3_alc_cc"
+ [(set (reg 33)
+ (compare
+ (plus:DI (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_alc_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (plus:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+ "@
+ alcgr\\t%0,%2
+ alcg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*adddi3_alc"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_alc_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ alcgr\\t%0,%2
+ alcg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subdi3_slb_cc"
+ [(set (reg 33)
+ (compare
+ (minus:DI (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_slb_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (minus:DI (minus:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+ "@
+ slbgr\\t%0,%2
+ slbg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subdi3_slb"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (minus:DI (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_slb_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ slbgr\\t%0,%2
+ slbg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+;
+; addsicc instruction pattern(s).
+;
+
+(define_insn "*addsi3_alc_cc"
+ [(set (reg 33)
+ (compare
+ (plus:SI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_alc_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
+ "@
+ alcr\\t%0,%2
+ alc\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*addsi3_alc"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_alc_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_CPU_ZARCH"
+ "@
+ alcr\\t%0,%2
+ alc\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subsi3_slb_cc"
+ [(set (reg 33)
+ (compare
+ (minus:SI (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_slb_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d,d")
+ (minus:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
+ "@
+ slbr\\t%0,%2
+ slb\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subsi3_slb"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (minus:SI (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_slb_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_CPU_ZARCH"
+ "@
+ slbr\\t%0,%2
+ slb\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
;;
@@ -3735,160 +4350,196 @@
(match_operand:DI 1 "register_operand" "0,0")))]
"TARGET_64BIT"
"@
- msgfr\\t%0,%2
- msgf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")
+ msgfr\t%0,%2
+ msgf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
(set_attr "type" "imul")])
-
(define_insn "muldi3"
[(set (match_operand:DI 0 "register_operand" "=d,d,d")
(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
(match_operand:DI 2 "general_operand" "d,K,m")))]
"TARGET_64BIT"
"@
- msgr\\t%0,%2
- mghi\\t%0,%h2
- msg\\t%0,%2"
- [(set_attr "op_type" "RRE,RI,RXE")
- (set_attr "atype" "reg,reg,mem")
+ msgr\t%0,%2
+ mghi\t%0,%h2
+ msg\t%0,%2"
+ [(set_attr "op_type" "RRE,RI,RXY")
(set_attr "type" "imul")])
;
; mulsi3 instruction pattern(s).
;
+(define_insn "*mulsi3_sign"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R"))
+ (match_operand:SI 1 "register_operand" "0")))]
+ ""
+ "mh\t%0,%2"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "imul")])
+
(define_insn "mulsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:SI 2 "general_operand" "d,K,m")))]
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
+ (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
+ (match_operand:SI 2 "general_operand" "d,K,R,T")))]
""
"@
- msr\\t%0,%2
- mhi\\t%0,%h2
- ms\\t%0,%2"
- [(set_attr "op_type" "RRE,RI,RX")
- (set_attr "atype" "reg,reg,mem")
+ msr\t%0,%2
+ mhi\t%0,%h2
+ ms\t%0,%2
+ msy\t%0,%2"
+ [(set_attr "op_type" "RRE,RI,RX,RXY")
(set_attr "type" "imul")])
;
; mulsidi3 instruction pattern(s).
;
-(define_expand "mulsidi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ""))
- (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" ""))))]
+(define_insn "mulsidi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (mult:DI (sign_extend:DI
+ (match_operand:SI 1 "register_operand" "%0,0"))
+ (sign_extend:DI
+ (match_operand:SI 2 "nonimmediate_operand" "d,R"))))]
"!TARGET_64BIT"
- "
-{
- rtx insn;
+ "@
+ mr\t%0,%2
+ m\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "type" "imul")])
- emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
- insn = emit_insn (gen_mulsi_6432 (operands[0], operands[0], operands[2]));
+;
+; umulsidi3 instruction pattern(s).
+;
- REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_EQUAL,
- gen_rtx_MULT (DImode,
- gen_rtx_SIGN_EXTEND (DImode, operands[1]),
- gen_rtx_SIGN_EXTEND (DImode, operands[2])),
- REG_NOTES (insn));
- DONE;
-}")
-
-(define_insn "mulsi_6432"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (mult:DI (sign_extend:DI
- (truncate:SI (match_operand:DI 1 "register_operand" "0,0")))
- (sign_extend:DI
- (match_operand:SI 2 "nonimmediate_operand" "d,m"))))]
- "!TARGET_64BIT"
- "@
- mr\\t%0,%2
- m\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")
+(define_insn "umulsidi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (mult:DI (zero_extend:DI
+ (match_operand:SI 1 "register_operand" "%0,0"))
+ (zero_extend:DI
+ (match_operand:SI 2 "nonimmediate_operand" "d,m"))))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "@
+ mlr\t%0,%2
+ ml\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
(set_attr "type" "imul")])
-
+
;
; muldf3 instruction pattern(s).
;
(define_expand "muldf3"
- [(parallel
- [(set (match_operand:DF 0 "register_operand" "=f,f")
- (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))])]
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT"
"")
(define_insn "*muldf3"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:DF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- mdbr\\t%0,%2
- mdb\\t%0,%2"
+ mdbr\t%0,%2
+ mdb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "fmul")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fmuld")])
(define_insn "*muldf3_ibm"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:DF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- mdr\\t%0,%2
- md\\t%0,%2"
+ mdr\t%0,%2
+ md\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "type" "fmul")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fmuld")])
+
+(define_insn "*fmadddf"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "%f,f")
+ (match_operand:DF 2 "nonimmediate_operand" "f,R"))
+ (match_operand:DF 3 "register_operand" "0,0")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
+ "@
+ madbr\t%0,%1,%2
+ madb\t%0,%1,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fmuld")])
+
+(define_insn "*fmsubdf"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f,f")
+ (match_operand:DF 2 "nonimmediate_operand" "f,R"))
+ (match_operand:DF 3 "register_operand" "0,0")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
+ "@
+ msdbr\t%0,%1,%2
+ msdb\t%0,%1,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fmuld")])
;
; mulsf3 instruction pattern(s).
;
(define_expand "mulsf3"
- [(parallel
- [(set (match_operand:SF 0 "register_operand" "=f,f")
- (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))])]
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT"
"")
(define_insn "*mulsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:SF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- meebr\\t%0,%2
- meeb\\t%0,%2"
+ meebr\t%0,%2
+ meeb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "fmul")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fmuls")])
(define_insn "*mulsf3_ibm"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:SF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- mer\\t%0,%2
- me\\t%0,%2"
+ mer\t%0,%2
+ me\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "type" "fmul")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fmuls")])
+(define_insn "*fmaddsf"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f,f")
+ (match_operand:SF 2 "nonimmediate_operand" "f,R"))
+ (match_operand:SF 3 "register_operand" "0,0")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
+ "@
+ maebr\t%0,%1,%2
+ maeb\t%0,%1,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fmuls")])
+
+(define_insn "*fmsubsf"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f,f")
+ (match_operand:SF 2 "nonimmediate_operand" "f,R"))
+ (match_operand:SF 3 "register_operand" "0,0")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
+ "@
+ msebr\t%0,%1,%2
+ mseb\t%0,%1,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "fmuls")])
;;
;;- Divide and modulo instructions.
@@ -3900,31 +4551,20 @@
(define_expand "divmoddi4"
[(parallel [(set (match_operand:DI 0 "general_operand" "")
- (div:DI (match_operand:DI 1 "general_operand" "")
+ (div:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "general_operand" "")))
(set (match_operand:DI 3 "general_operand" "")
(mod:DI (match_dup 1) (match_dup 2)))])
(clobber (match_dup 4))]
"TARGET_64BIT"
- "
{
- rtx insn, div_equal, mod_equal, equal;
+ rtx insn, div_equal, mod_equal;
div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
- equal = gen_rtx_IOR (TImode,
- gen_rtx_ZERO_EXTEND (TImode, div_equal),
- gen_rtx_ASHIFT (TImode,
- gen_rtx_ZERO_EXTEND (TImode, mod_equal),
- GEN_INT (64)));
operands[4] = gen_reg_rtx(TImode);
- emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
- emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
- emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
- insn = emit_insn (gen_divmodtidi3 (operands[4], operands[4], operands[2]));
- REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
+ emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
REG_NOTES (insn) =
@@ -3935,45 +4575,43 @@
gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
DONE;
-}")
+})
(define_insn "divmodtidi3"
[(set (match_operand:TI 0 "register_operand" "=d,d")
(ior:TI
(zero_extend:TI
- (div:DI (truncate:DI (match_operand:TI 1 "register_operand" "0,0"))
+ (div:DI (match_operand:DI 1 "register_operand" "0,0")
(match_operand:DI 2 "general_operand" "d,m")))
(ashift:TI
(zero_extend:TI
- (mod:DI (truncate:DI (match_dup 1))
+ (mod:DI (match_dup 1)
(match_dup 2)))
(const_int 64))))]
"TARGET_64BIT"
"@
- dsgr\\t%0,%2
- dsg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "idiv")
- (set_attr "atype" "reg,mem")])
+ dsgr\t%0,%2
+ dsg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
+ (set_attr "type" "idiv")])
(define_insn "divmodtisi3"
[(set (match_operand:TI 0 "register_operand" "=d,d")
(ior:TI
(zero_extend:TI
- (div:DI (truncate:DI (match_operand:TI 1 "register_operand" "0,0"))
+ (div:DI (match_operand:DI 1 "register_operand" "0,0")
(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m"))))
(ashift:TI
(zero_extend:TI
- (mod:DI (truncate:DI (match_dup 1))
+ (mod:DI (match_dup 1)
(sign_extend:DI (match_dup 2))))
(const_int 64))))]
"TARGET_64BIT"
"@
- dsgfr\\t%0,%2
- dsgf\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "idiv")
- (set_attr "atype" "reg,mem")])
+ dsgfr\t%0,%2
+ dsgf\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
+ (set_attr "type" "idiv")])
;
; udivmoddi4 instruction pattern(s).
@@ -3987,7 +4625,6 @@
(umod:DI (match_dup 1) (match_dup 2)))])
(clobber (match_dup 4))]
"TARGET_64BIT"
- "
{
rtx insn, div_equal, mod_equal, equal;
@@ -4016,11 +4653,11 @@
gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
DONE;
-}")
+})
(define_insn "udivmodtidi3"
[(set (match_operand:TI 0 "register_operand" "=d,d")
- (ior:TI (zero_extend:TI
+ (ior:TI (zero_extend:TI
(truncate:DI
(udiv:TI (match_operand:TI 1 "register_operand" "0,0")
(zero_extend:TI
@@ -4032,11 +4669,10 @@
(const_int 64))))]
"TARGET_64BIT"
"@
- dlgr\\t%0,%2
- dlg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "idiv")
- (set_attr "atype" "reg,mem")])
+ dlgr\t%0,%2
+ dlg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
+ (set_attr "type" "idiv")])
;
; divmodsi4 instruction pattern(s).
@@ -4050,7 +4686,6 @@
(mod:SI (match_dup 1) (match_dup 2)))])
(clobber (match_dup 4))]
"!TARGET_64BIT"
- "
{
rtx insn, div_equal, mod_equal, equal;
@@ -4077,40 +4712,94 @@
gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
DONE;
-}")
+})
(define_insn "divmoddisi3"
[(set (match_operand:DI 0 "register_operand" "=d,d")
(ior:DI (zero_extend:DI
(truncate:SI
(div:DI (match_operand:DI 1 "register_operand" "0,0")
- (sign_extend:DI
- (match_operand:SI 2 "nonimmediate_operand" "d,m")))))
+ (sign_extend:DI
+ (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
(ashift:DI
(zero_extend:DI
(truncate:SI
- (mod:DI (match_dup 1) (sign_extend:SI (match_dup 2)))))
+ (mod:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))
(const_int 32))))]
"!TARGET_64BIT"
"@
- dr\\t%0,%2
- d\\t%0,%2"
+ dr\t%0,%2
+ d\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "type" "idiv")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "idiv")])
;
; udivsi3 and umodsi3 instruction pattern(s).
;
+(define_expand "udivmodsi4"
+ [(parallel [(set (match_operand:SI 0 "general_operand" "")
+ (udiv:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "nonimmediate_operand" "")))
+ (set (match_operand:SI 3 "general_operand" "")
+ (umod:SI (match_dup 1) (match_dup 2)))])
+ (clobber (match_dup 4))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+{
+ rtx insn, div_equal, mod_equal, equal;
+
+ div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
+ mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
+ equal = gen_rtx_IOR (DImode,
+ gen_rtx_ZERO_EXTEND (DImode, div_equal),
+ gen_rtx_ASHIFT (DImode,
+ gen_rtx_ZERO_EXTEND (DImode, mod_equal),
+ GEN_INT (32)));
+
+ operands[4] = gen_reg_rtx(DImode);
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
+ emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
+ emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
+ insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
+
+ DONE;
+})
+
+(define_insn "udivmoddisi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (ior:DI (zero_extend:DI
+ (truncate:SI
+ (udiv:DI (match_operand:DI 1 "register_operand" "0,0")
+ (zero_extend:DI
+ (match_operand:SI 2 "nonimmediate_operand" "d,m")))))
+ (ashift:DI
+ (zero_extend:DI
+ (truncate:SI
+ (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
+ (const_int 32))))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "@
+ dlr\t%0,%2
+ dl\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")
+ (set_attr "type" "idiv")])
(define_expand "udivsi3"
[(set (match_operand:SI 0 "register_operand" "=d")
(udiv:SI (match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")))
(clobber (match_dup 3))]
- "!TARGET_64BIT"
- "
+ "!TARGET_64BIT && !TARGET_CPU_ZARCH"
{
rtx insn, udiv_equal, umod_equal, equal;
@@ -4139,32 +4828,32 @@
}
else
{
- operands[2] = force_reg (SImode, operands[2]);
- operands[2] = make_safe_from (operands[2], operands[0]);
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
operands[2]));
REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
-
- insn = emit_move_insn (operands[0],
+
+ insn = emit_move_insn (operands[0],
gen_lowpart (SImode, operands[3]));
REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_EQUAL,
+ gen_rtx_EXPR_LIST (REG_EQUAL,
udiv_equal, REG_NOTES (insn));
}
}
else
- {
+ {
rtx label1 = gen_label_rtx ();
rtx label2 = gen_label_rtx ();
rtx label3 = gen_label_rtx ();
- operands[1] = force_reg (SImode, operands[1]);
- operands[1] = make_safe_from (operands[1], operands[0]);
- operands[2] = force_reg (SImode, operands[2]);
- operands[2] = make_safe_from (operands[2], operands[0]);
+ operands[1] = force_reg (SImode, operands[1]);
+ operands[1] = make_safe_from (operands[1], operands[0]);
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
emit_move_insn (operands[0], const0_rtx);
emit_insn (gen_cmpsi (operands[2], operands[1]));
@@ -4178,11 +4867,11 @@
operands[2]));
REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
-
- insn = emit_move_insn (operands[0],
+
+ insn = emit_move_insn (operands[0],
gen_lowpart (SImode, operands[3]));
REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_EQUAL,
+ gen_rtx_EXPR_LIST (REG_EQUAL,
udiv_equal, REG_NOTES (insn));
emit_jump (label3);
emit_label (label1);
@@ -4192,17 +4881,16 @@
emit_move_insn (operands[0], const1_rtx);
emit_label (label3);
}
- emit_move_insn (operands[0], operands[0]);
+ emit_move_insn (operands[0], operands[0]);
DONE;
-}")
+})
(define_expand "umodsi3"
[(set (match_operand:SI 0 "register_operand" "=d")
(umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
(match_operand:SI 2 "nonimmediate_operand" "")))
(clobber (match_dup 3))]
- "!TARGET_64BIT"
- "
+ "!TARGET_64BIT && !TARGET_CPU_ZARCH"
{
rtx insn, udiv_equal, umod_equal, equal;
@@ -4232,19 +4920,19 @@
}
else
{
- operands[2] = force_reg (SImode, operands[2]);
- operands[2] = make_safe_from (operands[2], operands[0]);
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
operands[2]));
REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
-
- insn = emit_move_insn (operands[0],
+
+ insn = emit_move_insn (operands[0],
gen_highpart (SImode, operands[3]));
REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_EQUAL,
+ gen_rtx_EXPR_LIST (REG_EQUAL,
umod_equal, REG_NOTES (insn));
}
}
@@ -4254,12 +4942,12 @@
rtx label2 = gen_label_rtx ();
rtx label3 = gen_label_rtx ();
- operands[1] = force_reg (SImode, operands[1]);
- operands[1] = make_safe_from (operands[1], operands[0]);
- operands[2] = force_reg (SImode, operands[2]);
- operands[2] = make_safe_from (operands[2], operands[0]);
+ operands[1] = force_reg (SImode, operands[1]);
+ operands[1] = make_safe_from (operands[1], operands[0]);
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
- emit_move_insn(operands[0], operands[1]);
+ 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], const1_rtx));
@@ -4271,11 +4959,11 @@
operands[2]));
REG_NOTES (insn) =
gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
-
- insn = emit_move_insn (operands[0],
+
+ insn = emit_move_insn (operands[0],
gen_highpart (SImode, operands[3]));
REG_NOTES (insn) =
- gen_rtx_EXPR_LIST (REG_EQUAL,
+ gen_rtx_EXPR_LIST (REG_EQUAL,
umod_equal, REG_NOTES (insn));
emit_jump (label3);
emit_label (label1);
@@ -4286,85 +4974,73 @@
emit_label (label3);
}
DONE;
-}")
+})
;
; divdf3 instruction pattern(s).
;
(define_expand "divdf3"
- [(parallel
- [(set (match_operand:DF 0 "register_operand" "=f,f")
- (div:DF (match_operand:DF 1 "register_operand" "0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))])]
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (div:DF (match_operand:DF 1 "register_operand" "0,0")
+ (match_operand:DF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT"
"")
(define_insn "*divdf3"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(div:DF (match_operand:DF 1 "register_operand" "0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:DF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- ddbr\\t%0,%2
- ddb\\t%0,%2"
+ ddbr\t%0,%2
+ ddb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "fdiv")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fdivd")])
(define_insn "*divdf3_ibm"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(div:DF (match_operand:DF 1 "register_operand" "0,0")
- (match_operand:DF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:DF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- ddr\\t%0,%2
- dd\\t%0,%2"
+ ddr\t%0,%2
+ dd\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "type" "fdiv")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fdivd")])
;
; divsf3 instruction pattern(s).
;
(define_expand "divsf3"
- [(parallel
- [(set (match_operand:SF 0 "register_operand" "=f,f")
- (div:SF (match_operand:SF 1 "register_operand" "0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))])]
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (div:SF (match_operand:SF 1 "register_operand" "0,0")
+ (match_operand:SF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT"
"")
(define_insn "*divsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(div:SF (match_operand:SF 1 "register_operand" "0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:SF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- debr\\t%0,%2
- deb\\t%0,%2"
+ debr\t%0,%2
+ deb\t%0,%2"
[(set_attr "op_type" "RRE,RXE")
- (set_attr "type" "fdiv")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fdivs")])
(define_insn "*divsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(div:SF (match_operand:SF 1 "register_operand" "0,0")
- (match_operand:SF 2 "general_operand" "f,m")))
- (clobber (reg:CC 33))]
+ (match_operand:SF 2 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
"@
- der\\t%0,%2
- de\\t%0,%2"
+ der\t%0,%2
+ de\t%0,%2"
[(set_attr "op_type" "RR,RX")
- (set_attr "type" "fdiv")
- (set_attr "atype" "reg,mem")])
+ (set_attr "type" "fdivs")])
;;
@@ -4384,10 +5060,9 @@
(and:DI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
"@
- ngr\\t%0,%2
- ng\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ ngr\t%0,%2
+ ng\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*anddi3_cconly"
[(set (reg 33)
@@ -4397,45 +5072,27 @@
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
"@
- ngr\\t%0,%2
- ng\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
-
-(define_insn "*anddi3_ni"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (and:DI (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:DI 2 "immediate_operand" "n")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT && s390_single_hi (operands[2], DImode, -1) >= 0"
- "*
-{
- int part = s390_single_hi (operands[2], DImode, -1);
- operands[2] = GEN_INT (s390_extract_hi (operands[2], DImode, part));
-
- switch (part)
- {
- case 0: return \"nihh\\t%0,%x2\";
- case 1: return \"nihl\\t%0,%x2\";
- case 2: return \"nilh\\t%0,%x2\";
- case 3: return \"nill\\t%0,%x2\";
- default: abort ();
- }
-}"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+ ngr\t%0,%2
+ ng\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "anddi3"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
- (match_operand:DI 2 "general_operand" "d,m")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT"
- "@
- ngr\\t%0,%2
- ng\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d,d,d,d")
+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o,0,0,0,0,0,0")
+ (match_operand:DI 2 "general_operand"
+ "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ #
+ #
+ nihh\t%0,%j2
+ nihl\t%0,%j2
+ nilh\t%0,%j2
+ nill\t%0,%j2
+ ngr\t%0,%2
+ ng\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY")])
(define_insn "*anddi3_ss"
[(set (match_operand:DI 0 "s_operand" "=Q")
@@ -4443,9 +5100,8 @@
(match_operand:DI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "nc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "nc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*anddi3_ss_inv"
[(set (match_operand:DI 0 "s_operand" "=Q")
@@ -4453,9 +5109,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "nc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "nc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; andsi3 instruction pattern(s).
@@ -4463,63 +5118,66 @@
(define_insn "*andsi3_cc"
[(set (reg 33)
- (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(and:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCTmode)"
"@
- nr\\t%0,%2
- n\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ nr\t%0,%2
+ n\t%0,%2
+ ny\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*andsi3_cconly"
[(set (reg 33)
- (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
"s390_match_ccmode(insn, CCTmode)"
"@
- nr\\t%0,%2
- n\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ nr\t%0,%2
+ n\t%0,%2
+ ny\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
-(define_insn "*andsi3_ni"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (and:SI (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:SI 2 "immediate_operand" "n")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT && s390_single_hi (operands[2], SImode, -1) >= 0"
- "*
-{
- int part = s390_single_hi (operands[2], SImode, -1);
- operands[2] = GEN_INT (s390_extract_hi (operands[2], SImode, part));
-
- switch (part)
- {
- case 0: return \"nilh\\t%0,%x2\";
- case 1: return \"nill\\t%0,%x2\";
- default: abort ();
- }
-}"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+(define_expand "andsi3"
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
-(define_insn "andsi3"
+(define_insn "*andsi3_zarch"
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d,d")
+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,o,0,0,0,0,0")
+ (match_operand:SI 2 "general_operand" "M,M,N0HSF,N1HSF,d,R,T")))
+ (clobber (reg:CC 33))]
+ "TARGET_ZARCH"
+ "@
+ #
+ #
+ nilh\t%0,%j2
+ nill\t%0,%j2
+ nr\t%0,%2
+ n\t%0,%2
+ ny\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE,RI,RI,RR,RX,RXY")])
+
+(define_insn "*andsi3_esa"
[(set (match_operand:SI 0 "register_operand" "=d,d")
(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m")))
+ (match_operand:SI 2 "general_operand" "d,R")))
(clobber (reg:CC 33))]
- ""
+ "!TARGET_ZARCH"
"@
- nr\\t%0,%2
- n\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ nr\t%0,%2
+ n\t%0,%2"
+ [(set_attr "op_type" "RR,RX")])
(define_insn "*andsi3_ss"
[(set (match_operand:SI 0 "s_operand" "=Q")
@@ -4527,9 +5185,8 @@
(match_operand:SI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "nc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "nc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*andsi3_ss_inv"
[(set (match_operand:SI 0 "s_operand" "=Q")
@@ -4537,9 +5194,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "nc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "nc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; andhi3 instruction pattern(s).
@@ -4550,12 +5206,11 @@
(and:HI (match_operand:HI 1 "register_operand" "%0,0")
(match_operand:HI 2 "nonmemory_operand" "d,n")))
(clobber (reg:CC 33))]
- "TARGET_64BIT"
+ "TARGET_ZARCH"
"@
- nr\\t%0,%2
- nill\\t%0,%x2"
- [(set_attr "op_type" "RR,RI")
- (set_attr "atype" "reg")])
+ nr\t%0,%2
+ nill\t%0,%x2"
+ [(set_attr "op_type" "RR,RI")])
(define_insn "andhi3"
[(set (match_operand:HI 0 "register_operand" "=d")
@@ -4563,9 +5218,8 @@
(match_operand:HI 2 "nonmemory_operand" "d")))
(clobber (reg:CC 33))]
""
- "nr\\t%0,%2"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "reg")])
+ "nr\t%0,%2"
+ [(set_attr "op_type" "RR")])
(define_insn "*andhi3_ss"
[(set (match_operand:HI 0 "s_operand" "=Q")
@@ -4573,9 +5227,8 @@
(match_operand:HI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "nc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "nc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*andhi3_ss_inv"
[(set (match_operand:HI 0 "s_operand" "=Q")
@@ -4583,9 +5236,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "nc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "nc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; andqi3 instruction pattern(s).
@@ -4596,12 +5248,11 @@
(and:QI (match_operand:QI 1 "register_operand" "%0,0")
(match_operand:QI 2 "nonmemory_operand" "d,n")))
(clobber (reg:CC 33))]
- "TARGET_64BIT"
+ "TARGET_ZARCH"
"@
- nr\\t%0,%2
- nill\\t%0,%b2"
- [(set_attr "op_type" "RR,RI")
- (set_attr "atype" "reg")])
+ nr\t%0,%2
+ nill\t%0,%b2"
+ [(set_attr "op_type" "RR,RI")])
(define_insn "andqi3"
[(set (match_operand:QI 0 "register_operand" "=d")
@@ -4609,33 +5260,32 @@
(match_operand:QI 2 "nonmemory_operand" "d")))
(clobber (reg:CC 33))]
""
- "nr\\t%0,%2"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "reg")])
+ "nr\t%0,%2"
+ [(set_attr "op_type" "RR")])
(define_insn "*andqi3_ss"
- [(set (match_operand:QI 0 "s_operand" "=Q,Q")
+ [(set (match_operand:QI 0 "s_operand" "=Q,S,Q")
(and:QI (match_dup 0)
- (match_operand:QI 1 "s_imm_operand" "n,Q")))
+ (match_operand:QI 1 "s_imm_operand" "n,n,Q")))
(clobber (reg:CC 33))]
""
"@
- ni\\t%0,%b1
- nc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SI,SS")
- (set_attr "atype" "mem")])
+ ni\t%0,%b1
+ niy\t%0,%b1
+ nc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SIY,SS")])
(define_insn "*andqi3_ss_inv"
- [(set (match_operand:QI 0 "s_operand" "=Q,Q")
- (and:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
+ [(set (match_operand:QI 0 "s_operand" "=Q,S,Q")
+ (and:QI (match_operand:QI 1 "s_imm_operand" "n,n,Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
"@
- ni\\t%0,%b1
- nc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SI,SS")
- (set_attr "atype" "mem")])
+ ni\t%0,%b1
+ niy\t%0,%b1
+ nc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SIY,SS")])
;;
@@ -4655,10 +5305,9 @@
(ior:DI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
"@
- ogr\\t%0,%2
- og\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ ogr\t%0,%2
+ og\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*iordi3_cconly"
[(set (reg 33)
@@ -4668,45 +5317,24 @@
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
"@
- ogr\\t%0,%2
- og\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
-
-(define_insn "*iordi3_oi"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (ior:DI (match_operand:DI 1 "nonimmediate_operand" "0")
- (match_operand:DI 2 "immediate_operand" "n")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT && s390_single_hi (operands[2], DImode, 0) >= 0"
- "*
-{
- int part = s390_single_hi (operands[2], DImode, 0);
- operands[2] = GEN_INT (s390_extract_hi (operands[2], DImode, part));
-
- switch (part)
- {
- case 0: return \"oihh\\t%0,%x2\";
- case 1: return \"oihl\\t%0,%x2\";
- case 2: return \"oilh\\t%0,%x2\";
- case 3: return \"oill\\t%0,%x2\";
- default: abort ();
- }
-}"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+ ogr\t%0,%2
+ og\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "iordi3"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
- (match_operand:DI 2 "general_operand" "d,m")))
+ [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d,d")
+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,0,0,0,0")
+ (match_operand:DI 2 "general_operand" "N0HD0,N1HD0,N2HD0,N3HD0,d,m")))
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- ogr\\t%0,%2
- og\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ oihh\t%0,%i2
+ oihl\t%0,%i2
+ oilh\t%0,%i2
+ oill\t%0,%i2
+ ogr\t%0,%2
+ og\t%0,%2"
+ [(set_attr "op_type" "RI,RI,RI,RI,RRE,RXY")])
(define_insn "*iordi3_ss"
[(set (match_operand:DI 0 "s_operand" "=Q")
@@ -4714,9 +5342,8 @@
(match_operand:DI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "oc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "oc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*iordi3_ss_inv"
[(set (match_operand:DI 0 "s_operand" "=Q")
@@ -4724,9 +5351,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "oc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "oc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; iorsi3 instruction pattern(s).
@@ -4734,63 +5360,64 @@
(define_insn "*iorsi3_cc"
[(set (reg 33)
- (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(ior:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCTmode)"
"@
- or\\t%0,%2
- o\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ or\t%0,%2
+ o\t%0,%2
+ oy\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*iorsi3_cconly"
[(set (reg 33)
- (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
"s390_match_ccmode(insn, CCTmode)"
"@
- or\\t%0,%2
- o\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ or\t%0,%2
+ o\t%0,%2
+ oy\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
-(define_insn "*iorsi3_oi"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0")
- (match_operand:SI 2 "immediate_operand" "n")))
- (clobber (reg:CC 33))]
- "TARGET_64BIT && s390_single_hi (operands[2], SImode, 0) >= 0"
- "*
-{
- int part = s390_single_hi (operands[2], SImode, 0);
- operands[2] = GEN_INT (s390_extract_hi (operands[2], SImode, part));
+(define_expand "iorsi3"
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
- switch (part)
- {
- case 0: return \"oilh\\t%0,%x2\";
- case 1: return \"oill\\t%0,%x2\";
- default: abort ();
- }
-}"
- [(set_attr "op_type" "RI")
- (set_attr "atype" "reg")])
+(define_insn "iorsi3_zarch"
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0,0,0")
+ (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,d,R,T")))
+ (clobber (reg:CC 33))]
+ "TARGET_ZARCH"
+ "@
+ oilh\t%0,%i2
+ oill\t%0,%i2
+ or\t%0,%2
+ o\t%0,%2
+ oy\t%0,%2"
+ [(set_attr "op_type" "RI,RI,RR,RX,RXY")])
-(define_insn "iorsi3"
+(define_insn "iorsi3_esa"
[(set (match_operand:SI 0 "register_operand" "=d,d")
- (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m")))
+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,R")))
(clobber (reg:CC 33))]
- ""
+ "!TARGET_ZARCH"
"@
- or\\t%0,%2
- o\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ or\t%0,%2
+ o\t%0,%2"
+ [(set_attr "op_type" "RR,RX")])
(define_insn "*iorsi3_ss"
[(set (match_operand:SI 0 "s_operand" "=Q")
@@ -4798,9 +5425,8 @@
(match_operand:SI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "oc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "oc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*iorsi3_ss_inv"
[(set (match_operand:SI 0 "s_operand" "=Q")
@@ -4808,9 +5434,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "oc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "oc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; iorhi3 instruction pattern(s).
@@ -4821,12 +5446,11 @@
(ior:HI (match_operand:HI 1 "register_operand" "%0,0")
(match_operand:HI 2 "nonmemory_operand" "d,n")))
(clobber (reg:CC 33))]
- "TARGET_64BIT"
+ "TARGET_ZARCH"
"@
- or\\t%0,%2
- oill\\t%0,%x2"
- [(set_attr "op_type" "RR,RI")
- (set_attr "atype" "reg")])
+ or\t%0,%2
+ oill\t%0,%x2"
+ [(set_attr "op_type" "RR,RI")])
(define_insn "iorhi3"
[(set (match_operand:HI 0 "register_operand" "=d")
@@ -4834,9 +5458,8 @@
(match_operand:HI 2 "nonmemory_operand" "d")))
(clobber (reg:CC 33))]
""
- "or\\t%0,%2"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "reg")])
+ "or\t%0,%2"
+ [(set_attr "op_type" "RR")])
(define_insn "*iorhi3_ss"
[(set (match_operand:HI 0 "s_operand" "=Q")
@@ -4844,9 +5467,8 @@
(match_operand:HI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "oc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "oc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*iorhi3_ss_inv"
[(set (match_operand:HI 0 "s_operand" "=Q")
@@ -4854,9 +5476,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "oc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "oc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; iorqi3 instruction pattern(s).
@@ -4867,12 +5488,11 @@
(ior:QI (match_operand:QI 1 "register_operand" "%0,0")
(match_operand:QI 2 "nonmemory_operand" "d,n")))
(clobber (reg:CC 33))]
- "TARGET_64BIT"
+ "TARGET_ZARCH"
"@
- or\\t%0,%2
- oill\\t%0,%b2"
- [(set_attr "op_type" "RR,RI")
- (set_attr "atype" "reg")])
+ or\t%0,%2
+ oill\t%0,%b2"
+ [(set_attr "op_type" "RR,RI")])
(define_insn "iorqi3"
[(set (match_operand:QI 0 "register_operand" "=d")
@@ -4880,33 +5500,32 @@
(match_operand:QI 2 "nonmemory_operand" "d")))
(clobber (reg:CC 33))]
""
- "or\\t%0,%2"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "reg")])
+ "or\t%0,%2"
+ [(set_attr "op_type" "RR")])
(define_insn "*iorqi3_ss"
- [(set (match_operand:QI 0 "s_operand" "=Q,Q")
+ [(set (match_operand:QI 0 "s_operand" "=Q,S,Q")
(ior:QI (match_dup 0)
- (match_operand:QI 1 "s_imm_operand" "n,Q")))
+ (match_operand:QI 1 "s_imm_operand" "n,n,Q")))
(clobber (reg:CC 33))]
""
"@
- oi\\t%0,%b1
- oc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SI,SS")
- (set_attr "atype" "reg,mem")])
+ oi\t%0,%b1
+ oiy\t%0,%b1
+ oc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SIY,SS")])
(define_insn "*iorqi3_ss_inv"
- [(set (match_operand:QI 0 "s_operand" "=Q,Q")
- (ior:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
+ [(set (match_operand:QI 0 "s_operand" "=Q,S,Q")
+ (ior:QI (match_operand:QI 1 "s_imm_operand" "n,n,Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
"@
- oi\\t%0,%b1
- oc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SI,SS")
- (set_attr "atype" "reg,mem")])
+ oi\t%0,%b1
+ oiy\t%0,%b1
+ oc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SIY,SS")])
;;
@@ -4926,10 +5545,9 @@
(xor:DI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
"@
- xgr\\t%0,%2
- xg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ xgr\t%0,%2
+ xg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*xordi3_cconly"
[(set (reg 33)
@@ -4939,10 +5557,9 @@
(clobber (match_scratch:DI 0 "=d,d"))]
"s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
"@
- xgr\\t%0,%2
- xr\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ xgr\t%0,%2
+ xr\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "xordi3"
[(set (match_operand:DI 0 "register_operand" "=d,d")
@@ -4951,10 +5568,9 @@
(clobber (reg:CC 33))]
"TARGET_64BIT"
"@
- xgr\\t%0,%2
- xg\\t%0,%2"
- [(set_attr "op_type" "RRE,RXE")
- (set_attr "atype" "reg,mem")])
+ xgr\t%0,%2
+ xg\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
(define_insn "*xordi3_ss"
[(set (match_operand:DI 0 "s_operand" "=Q")
@@ -4962,9 +5578,8 @@
(match_operand:DI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "xc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "xc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*xordi3_ss_inv"
[(set (match_operand:DI 0 "s_operand" "=Q")
@@ -4972,9 +5587,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "xc\\t%O0(8,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "xc\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; xorsi3 instruction pattern(s).
@@ -4982,42 +5596,42 @@
(define_insn "*xorsi3_cc"
[(set (reg 33)
- (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
(xor:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCTmode)"
"@
- xr\\t%0,%2
- x\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ xr\t%0,%2
+ x\t%0,%2
+ xy\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*xorsi3_cconly"
[(set (reg 33)
- (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m"))
+ (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
"s390_match_ccmode(insn, CCTmode)"
"@
- xr\\t%0,%2
- x\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ xr\t%0,%2
+ x\t%0,%2
+ xy\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "xorsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "d,m")))
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d")
+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,R,T")))
(clobber (reg:CC 33))]
""
"@
- xr\\t%0,%2
- x\\t%0,%2"
- [(set_attr "op_type" "RR,RX")
- (set_attr "atype" "reg,mem")])
+ xr\t%0,%2
+ x\t%0,%2
+ xy\t%0,%2"
+ [(set_attr "op_type" "RR,RX,RXY")])
(define_insn "*xorsi3_ss"
[(set (match_operand:SI 0 "s_operand" "=Q")
@@ -5025,9 +5639,8 @@
(match_operand:SI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "xc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "xc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*xorsi3_ss_inv"
[(set (match_operand:SI 0 "s_operand" "=Q")
@@ -5035,9 +5648,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "xc\\t%O0(4,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "xc\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; xorhi3 instruction pattern(s).
@@ -5049,9 +5661,8 @@
(match_operand:HI 2 "nonmemory_operand" "d")))
(clobber (reg:CC 33))]
""
- "xr\\t%0,%2"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "reg")])
+ "xr\t%0,%2"
+ [(set_attr "op_type" "RR")])
(define_insn "*xorhi3_ss"
[(set (match_operand:HI 0 "s_operand" "=Q")
@@ -5059,9 +5670,8 @@
(match_operand:HI 1 "s_imm_operand" "Q")))
(clobber (reg:CC 33))]
""
- "xc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "xc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
(define_insn "*xorhi3_ss_inv"
[(set (match_operand:HI 0 "s_operand" "=Q")
@@ -5069,9 +5679,8 @@
(match_dup 0)))
(clobber (reg:CC 33))]
""
- "xc\\t%O0(2,%R0),%1"
- [(set_attr "op_type" "SS")
- (set_attr "atype" "mem")])
+ "xc\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")])
;
; xorqi3 instruction pattern(s).
@@ -5083,33 +5692,32 @@
(match_operand:QI 2 "nonmemory_operand" "d")))
(clobber (reg:CC 33))]
""
- "xr\\t%0,%2"
- [(set_attr "op_type" "RR")
- (set_attr "atype" "reg")])
+ "xr\t%0,%2"
+ [(set_attr "op_type" "RR")])
(define_insn "*xorqi3_ss"
- [(set (match_operand:QI 0 "s_operand" "=Q,Q")
+ [(set (match_operand:QI 0 "s_operand" "=Q,S,Q")
(xor:QI (match_dup 0)
- (match_operand:QI 1 "s_imm_operand" "n,Q")))
+ (match_operand:QI 1 "s_imm_operand" "n,n,Q")))
(clobber (reg:CC 33))]
""
"@
- xi\\t%0,%b1
- xc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SI,SS")
- (set_attr "atype" "mem")])
+ xi\t%0,%b1
+ xiy\t%0,%b1
+ xc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SIY,SS")])
(define_insn "*xorqi3_ss_inv"
- [(set (match_operand:QI 0 "s_operand" "=Q,Q")
- (xor:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
+ [(set (match_operand:QI 0 "s_operand" "=Q,S,Q")
+ (xor:QI (match_operand:QI 1 "s_imm_operand" "n,n,Q")
(match_dup 0)))
(clobber (reg:CC 33))]
""
"@
- xi\\t%0,%b1
- xc\\t%O0(1,%R0),%1"
- [(set_attr "op_type" "SI,SS")
- (set_attr "atype" "mem")])
+ xi\t%0,%b1
+ xiy\t%0,%b1
+ xc\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SIY,SS")])
;;
@@ -5133,7 +5741,7 @@
(neg:DI (match_operand:DI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "lcgr\\t%0,%1"
+ "lcgr\t%0,%1"
[(set_attr "op_type" "RR")])
(define_insn "*negdi2_31"
@@ -5141,18 +5749,17 @@
(neg:DI (match_operand:DI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
- "*
{
rtx xop[1];
xop[0] = gen_label_rtx ();
- output_asm_insn (\"lcr\\t%0,%1\", operands);
- output_asm_insn (\"lcr\\t%N0,%N1\", operands);
- output_asm_insn (\"je\\t%l0\", xop);
- output_asm_insn (\"bctr\\t%0,0\", operands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ output_asm_insn ("lcr\t%0,%1", operands);
+ output_asm_insn ("lcr\t%N0,%N1", operands);
+ output_asm_insn ("je\t%l0", xop);
+ output_asm_insn ("bctr\t%0,0", operands);
+ targetm.asm_out.internal_label (asm_out_file, "L",
CODE_LABEL_NUMBER (xop[0]));
- return \"\";
-}"
+ return "";
+}
[(set_attr "op_type" "NN")
(set_attr "type" "other")
(set_attr "length" "10")])
@@ -5166,7 +5773,7 @@
(neg:SI (match_operand:SI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
""
- "lcr\\t%0,%1"
+ "lcr\t%0,%1"
[(set_attr "op_type" "RR")])
;
@@ -5186,16 +5793,18 @@
(neg:DF (match_operand:DF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "lcdbr\\t%0,%1"
- [(set_attr "op_type" "RRE")])
+ "lcdbr\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimpd")])
(define_insn "*negdf2_ibm"
[(set (match_operand:DF 0 "register_operand" "=f")
(neg:DF (match_operand:DF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "lcdr\\t%0,%1"
- [(set_attr "op_type" "RR")])
+ "lcdr\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "fsimpd")])
;
; negsf2 instruction pattern(s).
@@ -5214,16 +5823,18 @@
(neg:SF (match_operand:SF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "lcebr\\t%0,%1"
- [(set_attr "op_type" "RRE")])
+ "lcebr\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimps")])
(define_insn "*negsf2"
[(set (match_operand:SF 0 "register_operand" "=f")
(neg:SF (match_operand:SF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "lcer\\t%0,%1"
- [(set_attr "op_type" "RR")])
+ "lcer\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "fsimps")])
;;
@@ -5239,7 +5850,7 @@
(abs:DI (match_operand:DI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "lpgr\\t%0,%1"
+ "lpgr\t%0,%1"
[(set_attr "op_type" "RRE")])
;
@@ -5251,7 +5862,7 @@
(abs:SI (match_operand:SI 1 "register_operand" "d")))
(clobber (reg:CC 33))]
""
- "lpr\\t%0,%1"
+ "lpr\t%0,%1"
[(set_attr "op_type" "RR")])
;
@@ -5271,16 +5882,18 @@
(abs:DF (match_operand:DF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "lpdbr\\t%0,%1"
- [(set_attr "op_type" "RRE")])
+ "lpdbr\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimpd")])
(define_insn "*absdf2_ibm"
[(set (match_operand:DF 0 "register_operand" "=f")
(abs:DF (match_operand:DF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "lpdr\\t%0,%1"
- [(set_attr "op_type" "RR")])
+ "lpdr\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "fsimpd")])
;
; abssf2 instruction pattern(s).
@@ -5299,16 +5912,64 @@
(abs:SF (match_operand:SF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
- "lpebr\\t%0,%1"
- [(set_attr "op_type" "RRE")])
+ "lpebr\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimps")])
(define_insn "*abssf2_ibm"
[(set (match_operand:SF 0 "register_operand" "=f")
(abs:SF (match_operand:SF 1 "register_operand" "f")))
(clobber (reg:CC 33))]
"TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
- "lper\\t%0,%1"
- [(set_attr "op_type" "RR")])
+ "lper\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "fsimps")])
+
+;;
+;;- Negated absolute value instructions
+;;
+
+;
+; Integer
+;
+
+(define_insn "*negabssi2"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (neg:SI (abs:SI (match_operand:SI 1 "register_operand" "d"))))
+ (clobber (reg:CC 33))]
+ ""
+ "lnr\t%0,%1"
+ [(set_attr "op_type" "RR")])
+
+(define_insn "*negabsdi2"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (neg:DI (abs:DI (match_operand:DI 1 "register_operand" "d"))))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "lngr\t%0,%1"
+ [(set_attr "op_type" "RRE")])
+
+;
+; Floating point
+;
+
+(define_insn "*negabssf2"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "lnebr\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimps")])
+
+(define_insn "*negabsdf2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "lndbr\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "fsimpd")])
;;
;;- Square root instructions.
@@ -5320,12 +5981,12 @@
(define_insn "sqrtdf2"
[(set (match_operand:DF 0 "register_operand" "=f,f")
- (sqrt:DF (match_operand:DF 1 "general_operand" "f,m")))]
+ (sqrt:DF (match_operand:DF 1 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- sqdbr\\t%0,%1
- sqdb\\t%0,%1"
- [(set_attr "op_type" "RRE,RSE")])
+ sqdbr\t%0,%1
+ sqdb\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")])
;
; sqrtsf2 instruction pattern(s).
@@ -5333,12 +5994,12 @@
(define_insn "sqrtsf2"
[(set (match_operand:SF 0 "register_operand" "=f,f")
- (sqrt:SF (match_operand:SF 1 "general_operand" "f,m")))]
+ (sqrt:SF (match_operand:SF 1 "general_operand" "f,R")))]
"TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
"@
- sqebr\\t%0,%1
- sqeb\\t%0,%1"
- [(set_attr "op_type" "RRE,RSE")])
+ sqebr\t%0,%1
+ sqeb\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")])
;;
;;- One complement instructions.
@@ -5347,7 +6008,7 @@
;
; one_cmpldi2 instruction pattern(s).
;
-
+
(define_expand "one_cmpldi2"
[(parallel
[(set (match_operand:DI 0 "register_operand" "")
@@ -5356,11 +6017,11 @@
(clobber (reg:CC 33))])]
"TARGET_64BIT"
"")
-
+
;
; one_cmplsi2 instruction pattern(s).
;
-
+
(define_expand "one_cmplsi2"
[(parallel
[(set (match_operand:SI 0 "register_operand" "")
@@ -5369,11 +6030,11 @@
(clobber (reg:CC 33))])]
""
"")
-
+
;
; one_cmplhi2 instruction pattern(s).
;
-
+
(define_expand "one_cmplhi2"
[(parallel
[(set (match_operand:HI 0 "register_operand" "")
@@ -5382,11 +6043,11 @@
(clobber (reg:CC 33))])]
""
"")
-
+
;
; one_cmplqi2 instruction pattern(s).
;
-
+
(define_expand "one_cmplqi2"
[(parallel
[(set (match_operand:QI 0 "register_operand" "")
@@ -5406,28 +6067,26 @@
;
(define_insn "rotldi3"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (rotate:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (rotate:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"TARGET_64BIT"
- "@
- rllg\\t%0,%1,%c2
- rllg\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE")])
+ "rllg\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
;
; rotlsi3 instruction pattern(s).
;
(define_insn "rotlsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (rotate:SI (match_operand:SI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
- "TARGET_64BIT"
- "@
- rll\\t%0,%1,%c2
- rll\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE")])
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (rotate:SI (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
+ "TARGET_CPU_ZARCH"
+ "rll\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
;;
@@ -5441,29 +6100,27 @@
(define_expand "ashldi3"
[(set (match_operand:DI 0 "register_operand" "")
(ashift:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
+ (match_operand:SI 2 "shift_count_operand" "")))]
""
"")
(define_insn "*ashldi3_31"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ashift:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashift:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"!TARGET_64BIT"
- "@
- sldl\\t%0,%c2
- sldl\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "sldl\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
(define_insn "*ashldi3_64"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ashift:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashift:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"TARGET_64BIT"
- "@
- sllg\\t%0,%1,%2
- sllg\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE")])
+ "sllg\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
;
; ashrdi3 instruction pattern(s).
@@ -5473,96 +6130,90 @@
[(parallel
[(set (match_operand:DI 0 "register_operand" "")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))
+ (match_operand:SI 2 "shift_count_operand" "")))
(clobber (reg:CC 33))])]
""
"")
(define_insn "*ashrdi3_cc_31"
[(set (reg 33)
- (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=d,d")
+ (set (match_operand:DI 0 "register_operand" "=d")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
"!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
- "@
- srda\\t%0,%c2
- srda\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "srda\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
(define_insn "*ashrdi3_cconly_31"
[(set (reg 33)
- (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (clobber (match_scratch:DI 0 "=d,d"))]
+ (clobber (match_scratch:DI 0 "=d"))]
"!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
- "@
- srda\\t%0,%c2
- srda\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "srda\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
(define_insn "*ashrdi3_31"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))
(clobber (reg:CC 33))]
"!TARGET_64BIT"
- "@
- srda\\t%0,%c2
- srda\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "srda\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
(define_insn "*ashrdi3_cc_64"
[(set (reg 33)
- (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=d,d")
+ (set (match_operand:DI 0 "register_operand" "=d")
(ashiftrt:DI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
- "@
- srag\\t%0,%1,%c2
- srag\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE")])
+ "srag\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
(define_insn "*ashrdi3_cconly_64"
[(set (reg 33)
- (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (clobber (match_scratch:DI 0 "=d,d"))]
+ (clobber (match_scratch:DI 0 "=d"))]
"s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
- "@
- srag\\t%0,%1,%c2
- srag\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE")])
+ "srag\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
(define_insn "*ashrdi3_64"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "@
- srag\\t%0,%1,%c2
- srag\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE")])
+ "srag\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
+
;
; ashlsi3 instruction pattern(s).
;
(define_insn "ashlsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (ashift:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
""
- "@
- sll\\t%0,%c2
- sll\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "sll\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
;
; ashrsi3 instruction pattern(s).
@@ -5570,39 +6221,37 @@
(define_insn "*ashrsi3_cc"
[(set (reg 33)
- (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (set (match_operand:SI 0 "register_operand" "=d,d")
+ (set (match_operand:SI 0 "register_operand" "=d")
(ashiftrt:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode(insn, CCSmode)"
- "@
- sra\\t%0,%c2
- sra\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "sra\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
+
(define_insn "*ashrsi3_cconly"
[(set (reg 33)
- (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y"))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=d,d"))]
+ (clobber (match_scratch:SI 0 "=d"))]
"s390_match_ccmode(insn, CCSmode)"
- "@
- sra\\t%0,%c2
- sra\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "sra\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
(define_insn "ashrsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))
(clobber (reg:CC 33))]
""
- "@
- sra\\t%0,%c2
- sra\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "sra\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
;;
@@ -5616,43 +6265,40 @@
(define_expand "lshrdi3"
[(set (match_operand:DI 0 "register_operand" "")
(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:SI 2 "nonmemory_operand" "")))]
+ (match_operand:SI 2 "shift_count_operand" "")))]
""
"")
(define_insn "*lshrdi3_31"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"!TARGET_64BIT"
- "@
- srdl\\t%0,%c2
- srdl\\t%0,0(%2)"
- [(set_attr "op_type" "RS,RS")])
+ "srdl\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
(define_insn "*lshrdi3_64"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (lshiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
"TARGET_64BIT"
- "@
- srlg\\t%0,%1,%c2
- srlg\\t%0,%1,0(%2)"
- [(set_attr "op_type" "RSE,RSE")])
+ "srlg\t%0,%1,%Y2"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "reg")])
;
; lshrsi3 instruction pattern(s).
;
(define_insn "lshrsi3"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "shift_count_operand" "Y")))]
""
- "@
- srl\\t%0,%c2
- srl\\t%0,0(%2)"
- [(set_attr "op_type" "RS")])
+ "srl\t%0,%Y2"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "reg")])
;;
@@ -5666,7 +6312,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bne"
[(set (reg:CCZ 33) (compare:CCZ (match_dup 1) (match_dup 2)))
@@ -5675,7 +6321,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bgt"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5684,7 +6330,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bgtu"
[(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
@@ -5693,7 +6339,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "blt"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5702,7 +6348,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bltu"
[(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
@@ -5711,7 +6357,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bge"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5720,7 +6366,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bgeu"
[(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
@@ -5729,7 +6375,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "ble"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5738,7 +6384,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bleu"
[(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
@@ -5747,7 +6393,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bunordered"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5756,7 +6402,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bordered"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5765,7 +6411,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "buneq"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5774,7 +6420,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bungt"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5783,7 +6429,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bunlt"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5792,7 +6438,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bunge"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5801,7 +6447,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bunle"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5810,7 +6456,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
(define_expand "bltgt"
[(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
@@ -5819,7 +6465,7 @@
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+ "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;")
;;
@@ -5828,25 +6474,25 @@
(define_insn "cjump"
[(set (pc)
- (if_then_else
+ (if_then_else
(match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "*
{
if (get_attr_length (insn) == 4)
- return \"j%C1\\t%l0\";
- else if (TARGET_64BIT)
- return \"jg%C1\\t%l0\";
+ return "j%C1\t%l0";
+ else if (TARGET_CPU_ZARCH)
+ return "jg%C1\t%l0";
else
abort ();
-}"
+}
[(set_attr "op_type" "RI")
+ (set_attr "type" "branch")
(set (attr "length")
(cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
(const_int 4)
- (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+ (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
(const_int 6)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 6)] (const_int 8)))])
@@ -5855,20 +6501,20 @@
[(set (pc)
(if_then_else
(match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
- (match_operand 0 "address_operand" "p")
+ (match_operand 0 "address_operand" "U")
(pc)))]
""
- "*
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
- return \"b%C1r\\t%0\";
+ return "b%C1r\t%0";
else
- return \"b%C1\\t%a0\";
-}"
- [(set (attr "op_type")
+ return "b%C1\t%a0";
+}
+ [(set (attr "op_type")
(if_then_else (match_operand 0 "register_operand" "")
(const_string "RR") (const_string "RX")))
- (set_attr "atype" "mem")])
+ (set_attr "type" "branch")
+ (set_attr "atype" "agen")])
;;
@@ -5879,23 +6525,23 @@
[(set (pc)
(if_then_else
(match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
- (pc)
+ (pc)
(label_ref (match_operand 0 "" ""))))]
""
- "*
-{
+{
if (get_attr_length (insn) == 4)
- return \"j%D1\\t%l0\";
- else if (TARGET_64BIT)
- return \"jg%D1\\t%l0\";
+ return "j%D1\t%l0";
+ else if (TARGET_CPU_ZARCH)
+ return "jg%D1\t%l0";
else
abort ();
-}"
+}
[(set_attr "op_type" "RI")
+ (set_attr "type" "branch")
(set (attr "length")
(cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
(const_int 4)
- (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+ (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
(const_int 6)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 6)] (const_int 8)))])
@@ -5905,19 +6551,19 @@
(if_then_else
(match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
(pc)
- (match_operand 0 "address_operand" "p")))]
+ (match_operand 0 "address_operand" "U")))]
""
- "*
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
- return \"b%D1r\\t%0\";
+ return "b%D1r\t%0";
else
- return \"b%D1\\t%a0\";
-}"
- [(set (attr "op_type")
+ return "b%D1\t%a0";
+}
+ [(set (attr "op_type")
(if_then_else (match_operand 0 "register_operand" "")
(const_string "RR") (const_string "RX")))
- (set_attr "atype" "mem")])
+ (set_attr "type" "branch")
+ (set_attr "atype" "agen")])
;;
;;- Trap instructions.
@@ -5926,8 +6572,9 @@
(define_insn "trap"
[(trap_if (const_int 1) (const_int 0))]
""
- "j\\t.+2"
- [(set_attr "op_type" "RX")])
+ "j\t.+2"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "branch")])
(define_expand "conditional_trap"
[(set (match_dup 2) (match_dup 3))
@@ -5935,31 +6582,31 @@
[(match_dup 2) (const_int 0)])
(match_operand:SI 1 "general_operand" ""))]
""
- "
{
enum machine_mode ccmode;
- if (operands[1] != const0_rtx) FAIL;
+ if (operands[1] != const0_rtx) FAIL;
- ccmode = s390_select_ccmode (GET_CODE (operands[0]),
- s390_compare_op0, s390_compare_op1);
+ ccmode = s390_select_ccmode (GET_CODE (operands[0]),
+ s390_compare_op0, s390_compare_op1);
operands[2] = gen_rtx_REG (ccmode, 33);
operands[3] = gen_rtx_COMPARE (ccmode, s390_compare_op0, s390_compare_op1);
-}")
+})
(define_insn "*trap"
[(trap_if (match_operator 0 "comparison_operator" [(reg 33) (const_int 0)])
(const_int 0))]
""
- "j%C0\\t.+2";
- [(set_attr "op_type" "RX")])
+ "j%C0\t.+2";
+ [(set_attr "op_type" "RI")
+ (set_attr "type" "branch")])
;;
;;- Loop instructions.
;;
;; This is all complicated by the fact that since this is a jump insn
;; we must handle our own output reloads.
-
+
(define_expand "doloop_end"
[(use (match_operand 0 "" "")) ; loop pseudo
(use (match_operand 1 "" "")) ; iterations; zero if unknown
@@ -5967,7 +6614,6 @@
(use (match_operand 3 "" "")) ; loop level
(use (match_operand 4 "" ""))] ; label
""
- "
{
if (GET_MODE (operands[0]) == SImode)
emit_jump_insn (gen_doloop_si (operands[4], operands[0], operands[0]));
@@ -5977,7 +6623,7 @@
FAIL;
DONE;
-}")
+})
(define_insn "doloop_si"
[(set (pc)
@@ -5991,20 +6637,22 @@
(clobber (match_scratch:SI 3 "=X,&d"))
(clobber (reg:CC 33))]
""
- "*
{
if (which_alternative != 0)
- return \"#\";
+ return "#";
else if (get_attr_length (insn) == 4)
- return \"brct\\t%1,%l0\";
+ return "brct\t%1,%l0";
+ else if (TARGET_CPU_ZARCH)
+ return "ahi\t%1,-1\;jgne\t%l0";
else
abort ();
-}"
+}
[(set_attr "op_type" "RI")
+ (set_attr "type" "branch")
(set (attr "length")
(cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
(const_int 4)
- (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+ (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
(const_int 10)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 6)] (const_int 8)))])
@@ -6014,24 +6662,24 @@
(if_then_else
(ne (match_operand:SI 1 "register_operand" "d,d")
(const_int 1))
- (match_operand 0 "address_operand" "p,p")
+ (match_operand 0 "address_operand" "U,U")
(pc)))
(set (match_operand:SI 2 "register_operand" "=1,?*m*d")
(plus:SI (match_dup 1) (const_int -1)))
(clobber (match_scratch:SI 3 "=X,&d"))
(clobber (reg:CC 33))]
""
- "*
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
- return \"bctr\\t%1,%0\";
+ return "bctr\t%1,%0";
else
- return \"bct\\t%1,%a0\";
-}"
- [(set (attr "op_type")
+ return "bct\t%1,%a0";
+}
+ [(set (attr "op_type")
(if_then_else (match_operand 0 "register_operand" "")
(const_string "RR") (const_string "RX")))
- (set_attr "atype" "mem")])
+ (set_attr "type" "branch")
+ (set_attr "atype" "agen")])
(define_split
[(set (pc)
@@ -6069,43 +6717,19 @@
(clobber (match_scratch:DI 3 "=X,&d"))
(clobber (reg:CC 33))]
"TARGET_64BIT"
- "*
{
if (which_alternative != 0)
- return \"#\";
+ return "#";
else if (get_attr_length (insn) == 4)
- return \"brctg\\t%1,%l0\";
+ return "brctg\t%1,%l0";
else
- abort ();
-}"
+ return "aghi\t%1,-1\;jgne\t%l0";
+}
[(set_attr "op_type" "RI")
+ (set_attr "type" "branch")
(set (attr "length")
(if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
- (const_int 4) (const_int 12)))])
-
-(define_insn "*doloop_di_long"
- [(set (pc)
- (if_then_else
- (ne (match_operand:DI 1 "register_operand" "d,d")
- (const_int 1))
- (match_operand 0 "address_operand" "p,p")
- (pc)))
- (set (match_operand:DI 2 "register_operand" "=1,?*m*d")
- (plus:DI (match_dup 1) (const_int -1)))
- (clobber (match_scratch:DI 3 "=X,&d"))
- (clobber (reg:CC 33))]
- ""
- "*
-{
- if (get_attr_op_type (insn) == OP_TYPE_RRE)
- return \"bctgr\\t%1,%0\";
- else
- return \"bctg\\t%1,%a0\";
-}"
- [(set (attr "op_type")
- (if_then_else (match_operand 0 "register_operand" "")
- (const_string "RRE") (const_string "RXE")))
- (set_attr "atype" "mem")])
+ (const_int 4) (const_int 10)))])
(define_split
[(set (pc)
@@ -6142,20 +6766,20 @@
(define_insn "jump"
[(set (pc) (label_ref (match_operand 0 "" "")))]
""
- "*
{
if (get_attr_length (insn) == 4)
- return \"j\\t%l0\";
- else if (TARGET_64BIT)
- return \"jg\\t%l0\";
+ return "j\t%l0";
+ else if (TARGET_CPU_ZARCH)
+ return "jg\t%l0";
else
abort ();
-}"
+}
[(set_attr "op_type" "RI")
+ (set_attr "type" "branch")
(set (attr "length")
(cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
(const_int 4)
- (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+ (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
(const_int 6)
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 6)] (const_int 8)))])
@@ -6165,39 +6789,39 @@
;
(define_insn "indirect_jump"
- [(set (pc) (match_operand 0 "address_operand" "p"))]
+ [(set (pc) (match_operand 0 "address_operand" "U"))]
""
- "*
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
- return \"br\\t%0\";
+ return "br\t%0";
else
- return \"b\\t%a0\";
-}"
- [(set (attr "op_type")
+ return "b\t%a0";
+}
+ [(set (attr "op_type")
(if_then_else (match_operand 0 "register_operand" "")
(const_string "RR") (const_string "RX")))
- (set_attr "atype" "mem")])
+ (set_attr "type" "branch")
+ (set_attr "atype" "agen")])
;
; casesi instruction pattern(s).
;
(define_insn "casesi_jump"
- [(set (pc) (match_operand 0 "address_operand" "p"))
+ [(set (pc) (match_operand 0 "address_operand" "U"))
(use (label_ref (match_operand 1 "" "")))]
""
- "*
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
- return \"br\\t%0\";
+ return "br\t%0";
else
- return \"b\\t%a0\";
-}"
- [(set (attr "op_type")
+ return "b\t%a0";
+}
+ [(set (attr "op_type")
(if_then_else (match_operand 0 "register_operand" "")
(const_string "RR") (const_string "RX")))
- (set_attr "atype" "mem")])
+ (set_attr "type" "branch")
+ (set_attr "atype" "agen")])
(define_expand "casesi"
[(match_operand:SI 0 "general_operand" "")
@@ -6206,7 +6830,6 @@
(label_ref (match_operand 3 "" ""))
(label_ref (match_operand 4 "" ""))]
""
- "
{
rtx index = gen_reg_rtx (SImode);
rtx base = gen_reg_rtx (Pmode);
@@ -6237,7 +6860,7 @@
emit_jump_insn (gen_casesi_jump (target, operands[3]));
DONE;
-}")
+})
;;
@@ -6256,7 +6879,6 @@
(match_operand 1 "" "")
(match_operand 2 "" "")])]
""
- "
{
int i;
@@ -6275,13 +6897,13 @@
emit_insn (gen_blockage ());
DONE;
-}")
+})
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
;; all of memory. This blocks insns from being moved across this point.
(define_insn "blockage"
- [(unspec_volatile [(const_int 0)] 0)]
+ [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
""
""
[(set_attr "type" "none")
@@ -6298,9 +6920,8 @@
(match_operand 1 "" ""))
(use (match_operand 2 "" ""))]
""
- "
{
- int plt_call = 0;
+ bool plt_call = false;
rtx insn;
/* Direct function calls need special treatment. */
@@ -6310,22 +6931,22 @@
/* When calling a global routine in PIC mode, we must
replace the symbol itself with the PLT stub. */
- if (flag_pic && !SYMBOL_REF_FLAG (sym))
+ if (flag_pic && !SYMBOL_REF_LOCAL_P (sym))
{
- sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
+ sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
sym = gen_rtx_CONST (Pmode, sym);
-
- plt_call = 1;
+ plt_call = true;
}
- /* Unless we can use the bras(l) insn, force the
+ /* Unless we can use the bras(l) insn, force the
routine address into a register. */
- if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
- {
- rtx target = gen_reg_rtx (Pmode);
- emit_move_insn (target, sym);
- sym = target;
- }
+ if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
+ {
+ if (flag_pic)
+ sym = legitimize_pic_address (sym, 0);
+ else
+ sym = force_reg (Pmode, sym);
+ }
operands[0] = gen_rtx_MEM (QImode, sym);
}
@@ -6334,14 +6955,12 @@
insn = emit_call_insn (gen_call_exp (operands[0], operands[1],
gen_rtx_REG (Pmode, RETURN_REGNUM)));
- /* In 31-bit, we must load the GOT register even if the
- compiler doesn't know about it, because the PLT glue
- code uses it. In 64-bit, this is not necessary. */
- if (plt_call && !TARGET_64BIT)
+ /* 31-bit PLT stubs use the GOT register implicitly. */
+ if (!TARGET_64BIT && plt_call)
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
-
+
DONE;
-}")
+})
(define_expand "call_exp"
[(parallel [(call (match_operand 0 "" "")
@@ -6350,64 +6969,40 @@
""
"")
-(define_insn "brasl"
- [(call (mem:QI (match_operand:DI 0 "bras_sym_operand" "X"))
- (match_operand:SI 1 "const_int_operand" "n"))
- (clobber (match_operand:DI 2 "register_operand" "=r"))]
- "TARGET_64BIT"
- "brasl\\t%2,%0"
- [(set_attr "op_type" "RIL")
- (set_attr "type" "jsr")])
-
-(define_insn "bras"
- [(call (mem:QI (match_operand:SI 0 "bras_sym_operand" "X"))
- (match_operand:SI 1 "const_int_operand" "n"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))]
- "TARGET_SMALL_EXEC"
- "bras\\t%2,%0"
+(define_insn "*bras"
+ [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
+ (match_operand 1 "const_int_operand" "n"))
+ (clobber (match_operand 2 "register_operand" "=r"))]
+ "TARGET_SMALL_EXEC && GET_MODE (operands[2]) == Pmode"
+ "bras\t%2,%0"
[(set_attr "op_type" "RI")
(set_attr "type" "jsr")])
-(define_insn "basr_64"
- [(call (mem:QI (match_operand:DI 0 "register_operand" "a"))
- (match_operand:SI 1 "const_int_operand" "n"))
- (clobber (match_operand:DI 2 "register_operand" "=r"))]
- "TARGET_64BIT"
- "basr\\t%2,%0"
- [(set_attr "op_type" "RR")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "basr_31"
- [(call (mem:QI (match_operand:SI 0 "register_operand" "a"))
- (match_operand:SI 1 "const_int_operand" "n"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))]
- "!TARGET_64BIT"
- "basr\\t%2,%0"
- [(set_attr "op_type" "RR")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "bas_64"
- [(call (mem:QI (match_operand:QI 0 "address_operand" "p"))
- (match_operand:SI 1 "const_int_operand" "n"))
- (clobber (match_operand:DI 2 "register_operand" "=r"))]
- "TARGET_64BIT"
- "bas\\t%2,%a0"
- [(set_attr "op_type" "RX")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "bas_31"
- [(call (mem:QI (match_operand:QI 0 "address_operand" "p"))
- (match_operand:SI 1 "const_int_operand" "n"))
- (clobber (match_operand:SI 2 "register_operand" "=r"))]
- "!TARGET_64BIT"
- "bas\\t%2,%a0"
- [(set_attr "op_type" "RX")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
+(define_insn "*brasl"
+ [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
+ (match_operand 1 "const_int_operand" "n"))
+ (clobber (match_operand 2 "register_operand" "=r"))]
+ "TARGET_CPU_ZARCH && GET_MODE (operands[2]) == Pmode"
+ "brasl\t%2,%0"
+ [(set_attr "op_type" "RIL")
+ (set_attr "type" "jsr")])
+(define_insn "*basr"
+ [(call (mem:QI (match_operand 0 "address_operand" "U"))
+ (match_operand 1 "const_int_operand" "n"))
+ (clobber (match_operand 2 "register_operand" "=r"))]
+ "GET_MODE (operands[2]) == Pmode"
+{
+ if (get_attr_op_type (insn) == OP_TYPE_RR)
+ return "basr\t%2,%0";
+ else
+ return "bas\t%2,%a0";
+}
+ [(set (attr "op_type")
+ (if_then_else (match_operand 0 "register_operand" "")
+ (const_string "RR") (const_string "RX")))
+ (set_attr "type" "jsr")
+ (set_attr "atype" "agen")])
;
; call_value instruction pattern(s).
@@ -6419,9 +7014,8 @@
(match_operand 2 "" "")))
(use (match_operand 3 "" ""))]
""
- "
{
- int plt_call = 0;
+ bool plt_call = false;
rtx insn;
/* Direct function calls need special treatment. */
@@ -6431,21 +7025,21 @@
/* When calling a global routine in PIC mode, we must
replace the symbol itself with the PLT stub. */
- if (flag_pic && !SYMBOL_REF_FLAG (sym))
+ if (flag_pic && !SYMBOL_REF_LOCAL_P (sym))
{
- sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
+ sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
sym = gen_rtx_CONST (Pmode, sym);
-
- plt_call = 1;
+ plt_call = true;
}
- /* Unless we can use the bras(l) insn, force the
+ /* Unless we can use the bras(l) insn, force the
routine address into a register. */
- if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
+ if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
{
- rtx target = gen_reg_rtx (Pmode);
- emit_move_insn (target, sym);
- sym = target;
+ if (flag_pic)
+ sym = legitimize_pic_address (sym, 0);
+ else
+ sym = force_reg (Pmode, sym);
}
operands[1] = gen_rtx_MEM (QImode, sym);
@@ -6456,14 +7050,12 @@
gen_call_value_exp (operands[0], operands[1], operands[2],
gen_rtx_REG (Pmode, RETURN_REGNUM)));
- /* In 31-bit, we must load the GOT register even if the
- compiler doesn't know about it, because the PLT glue
- code uses it. In 64-bit, this is not necessary. */
- if (plt_call && !TARGET_64BIT)
+ /* 31-bit PLT stubs use the GOT register implicitly. */
+ if (!TARGET_64BIT && plt_call)
use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
-
+
DONE;
-}")
+})
(define_expand "call_value_exp"
[(parallel [(set (match_operand 0 "" "")
@@ -6473,68 +7065,43 @@
""
"")
-(define_insn "brasl_r"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:DI 1 "bras_sym_operand" "X"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:DI 3 "register_operand" "=r"))]
- "TARGET_64BIT"
- "brasl\\t%3,%1"
- [(set_attr "op_type" "RIL")
- (set_attr "type" "jsr")])
-
-(define_insn "bras_r"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:SI 1 "bras_sym_operand" "X"))
+(define_insn "*bras_r"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
(match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:SI 3 "register_operand" "=r"))]
- "TARGET_SMALL_EXEC"
- "bras\\t%3,%1"
+ (clobber (match_operand 3 "register_operand" "=r"))]
+ "TARGET_SMALL_EXEC && GET_MODE (operands[3]) == Pmode"
+ "bras\t%3,%1"
[(set_attr "op_type" "RI")
(set_attr "type" "jsr")])
-(define_insn "basr_r_64"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:DI 1 "register_operand" "a"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:DI 3 "register_operand" "=r"))]
- "TARGET_64BIT"
- "basr\\t%3,%1"
- [(set_attr "op_type" "RR")
+(define_insn "*brasl_r"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
+ (match_operand 2 "const_int_operand" "n")))
+ (clobber (match_operand 3 "register_operand" "=r"))]
+ "TARGET_CPU_ZARCH && GET_MODE (operands[3]) == Pmode"
+ "brasl\t%3,%1"
+ [(set_attr "op_type" "RIL")
(set_attr "type" "jsr")])
-(define_insn "basr_r_31"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:SI 1 "register_operand" "a"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:SI 3 "register_operand" "=r"))]
- "!TARGET_64BIT"
- "basr\\t%3,%1"
- [(set_attr "op_type" "RR")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "bas_r_64"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:DI 3 "register_operand" "=r"))]
- "TARGET_64BIT"
- "bas\\t%3,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "bas_r_31"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:SI 3 "register_operand" "=r"))]
- "!TARGET_64BIT"
- "bas\\t%3,%a1"
- [(set_attr "op_type" "RX")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
+(define_insn "*basr_r"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "address_operand" "U"))
+ (match_operand 2 "const_int_operand" "n")))
+ (clobber (match_operand 3 "register_operand" "=r"))]
+ "GET_MODE (operands[3]) == Pmode"
+{
+ if (get_attr_op_type (insn) == OP_TYPE_RR)
+ return "basr\t%3,%1";
+ else
+ return "bas\t%3,%a1";
+}
+ [(set (attr "op_type")
+ (if_then_else (match_operand 1 "register_operand" "")
+ (const_string "RR") (const_string "RX")))
+ (set_attr "type" "jsr")
+ (set_attr "atype" "agen")])
;;
;;- Thread-local storage support.
@@ -6545,10 +7112,10 @@
(unspec:DI [(const_int 0)] UNSPEC_TP))]
"TARGET_64BIT"
"@
- ear\\t%0,%%a0\;sllg\\t%0,%0,32\;ear\\t%0,%%a1
- stam\\t%%a0,%%a1,%0"
+ ear\t%0,%%a0\;sllg\t%0,%0,32\;ear\t%0,%%a1
+ stam\t%%a0,%%a1,%0"
[(set_attr "op_type" "NN,RS")
- (set_attr "atype" "reg,mem")
+ (set_attr "atype" "reg,*")
(set_attr "type" "o3,*")
(set_attr "length" "14,*")])
@@ -6557,20 +7124,19 @@
(unspec:SI [(const_int 0)] UNSPEC_TP))]
"!TARGET_64BIT"
"@
- ear\\t%0,%%a0
- stam\\t%%a0,%%a0,%0"
- [(set_attr "op_type" "RRE,RS")
- (set_attr "atype" "reg,mem")])
+ ear\t%0,%%a0
+ stam\t%%a0,%%a0,%0"
+ [(set_attr "op_type" "RRE,RS")])
(define_insn "set_tp_64"
[(unspec_volatile [(match_operand:DI 0 "general_operand" "??d,Q")] UNSPECV_SET_TP)
(clobber (match_scratch:SI 1 "=d,X"))]
"TARGET_64BIT"
"@
- sar\\t%%a1,%0\;srlg\\t%1,%0,32\;sar\\t%%a0,%1
- lam\\t%%a0,%%a1,%0"
+ sar\t%%a1,%0\;srlg\t%1,%0,32\;sar\t%%a0,%1
+ lam\t%%a0,%%a1,%0"
[(set_attr "op_type" "NN,RS")
- (set_attr "atype" "reg,mem")
+ (set_attr "atype" "reg,*")
(set_attr "type" "o3,*")
(set_attr "length" "14,*")])
@@ -6578,37 +7144,35 @@
[(unspec_volatile [(match_operand:SI 0 "general_operand" "d,Q")] UNSPECV_SET_TP)]
"!TARGET_64BIT"
"@
- sar\\t%%a0,%0
- lam\\t%%a0,%%a0,%0"
- [(set_attr "op_type" "RRE,RS")
- (set_attr "atype" "reg,mem")])
-
+ sar\t%%a0,%0
+ lam\t%%a0,%%a0,%0"
+ [(set_attr "op_type" "RRE,RS")])
+
(define_insn "*tls_load_64"
[(set (match_operand:DI 0 "register_operand" "=d")
(unspec:DI [(match_operand:DI 1 "memory_operand" "m")
(match_operand:DI 2 "" "")]
UNSPEC_TLS_LOAD))]
"TARGET_64BIT"
- "lg\\t%0,%1%J2"
- [(set_attr "op_type" "RXE")
- (set_attr "atype" "mem")])
+ "lg\t%0,%1%J2"
+ [(set_attr "op_type" "RXE")])
(define_insn "*tls_load_31"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
(match_operand:SI 2 "" "")]
UNSPEC_TLS_LOAD))]
"!TARGET_64BIT"
- "l\\t%0,%1%J2"
- [(set_attr "op_type" "RX")
- (set_attr "atype" "mem")])
+ "@
+ l\t%0,%1%J2
+ ly\t%0,%1%J2"
+ [(set_attr "op_type" "RX,RXY")])
(define_expand "call_value_tls"
[(set (match_operand 0 "" "")
(call (const_int 0) (const_int 0)))
(use (match_operand 1 "" ""))]
""
- "
{
rtx insn, sym;
@@ -6616,16 +7180,17 @@
abort ();
sym = s390_tls_get_offset ();
- sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
+ sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT);
sym = gen_rtx_CONST (Pmode, sym);
- /* Unless we can use the bras(l) insn, force the
+ /* Unless we can use the bras(l) insn, force the
routine address into a register. */
- if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
+ if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH)
{
- rtx target = gen_reg_rtx (Pmode);
- emit_move_insn (target, sym);
- sym = target;
+ if (flag_pic)
+ sym = legitimize_pic_address (sym, 0);
+ else
+ sym = force_reg (Pmode, sym);
}
sym = gen_rtx_MEM (QImode, sym);
@@ -6643,7 +7208,7 @@
CONST_OR_PURE_CALL_P (insn) = 1;
DONE;
-}")
+})
(define_expand "call_value_tls_exp"
[(parallel [(set (match_operand 0 "" "")
@@ -6654,74 +7219,46 @@
""
"")
-(define_insn "brasl_tls"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:DI 1 "bras_sym_operand" "X"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:DI 3 "register_operand" "=r"))
- (use (match_operand:DI 4 "" ""))]
- "TARGET_64BIT"
- "brasl\\t%3,%1%J4"
- [(set_attr "op_type" "RIL")
- (set_attr "type" "jsr")])
-
-(define_insn "bras_tls"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:SI 1 "bras_sym_operand" "X"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:SI 3 "register_operand" "=r"))
- (use (match_operand:SI 4 "" ""))]
- "TARGET_SMALL_EXEC"
- "bras\\t%3,%1%J4"
+(define_insn "*bras_tls"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
+ (match_operand 2 "const_int_operand" "n")))
+ (clobber (match_operand 3 "register_operand" "=r"))
+ (use (match_operand 4 "" ""))]
+ "TARGET_SMALL_EXEC && GET_MODE (operands[3]) == Pmode"
+ "bras\t%3,%1%J4"
[(set_attr "op_type" "RI")
(set_attr "type" "jsr")])
-(define_insn "basr_tls_64"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:DI 1 "register_operand" "a"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:DI 3 "register_operand" "=r"))
- (use (match_operand:DI 4 "" ""))]
- "TARGET_64BIT"
- "basr\\t%3,%1%J4"
- [(set_attr "op_type" "RR")
+(define_insn "*brasl_tls"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
+ (match_operand 2 "const_int_operand" "n")))
+ (clobber (match_operand 3 "register_operand" "=r"))
+ (use (match_operand 4 "" ""))]
+ "TARGET_CPU_ZARCH && GET_MODE (operands[3]) == Pmode"
+ "brasl\t%3,%1%J4"
+ [(set_attr "op_type" "RIL")
(set_attr "type" "jsr")])
-(define_insn "basr_tls_31"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:SI 1 "register_operand" "a"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:SI 3 "register_operand" "=r"))
- (use (match_operand:SI 4 "" ""))]
- "!TARGET_64BIT"
- "basr\\t%3,%1%J4"
- [(set_attr "op_type" "RR")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "bas_tls_64"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:DI 3 "register_operand" "=r"))
- (use (match_operand:DI 4 "" ""))]
- "TARGET_64BIT"
- "bas\\t%3,%a1%J4"
- [(set_attr "op_type" "RX")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-
-(define_insn "bas_tls_31"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
- (match_operand:SI 2 "const_int_operand" "n")))
- (clobber (match_operand:SI 3 "register_operand" "=r"))
- (use (match_operand:SI 4 "" ""))]
- "!TARGET_64BIT"
- "bas\\t%3,%a1%J4"
- [(set_attr "op_type" "RX")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
+(define_insn "*basr_tls"
+ [(set (match_operand 0 "" "")
+ (call (mem:QI (match_operand 1 "address_operand" "U"))
+ (match_operand 2 "const_int_operand" "n")))
+ (clobber (match_operand 3 "register_operand" "=r"))
+ (use (match_operand 4 "" ""))]
+ "GET_MODE (operands[3]) == Pmode"
+{
+ if (get_attr_op_type (insn) == OP_TYPE_RR)
+ return "basr\t%3,%1%J4";
+ else
+ return "bas\t%3,%a1%J4";
+}
+ [(set (attr "op_type")
+ (if_then_else (match_operand 1 "register_operand" "")
+ (const_string "RR") (const_string "RX")))
+ (set_attr "type" "jsr")
+ (set_attr "atype" "agen")])
;;
;;- Miscellaneous instructions.
@@ -6736,13 +7273,12 @@
(plus (reg 15) (match_operand 1 "general_operand" "")))
(set (match_operand 0 "general_operand" "")
(reg 15))]
- ""
- "
+ "TARGET_BACKCHAIN"
{
rtx stack = gen_rtx (REG, Pmode, STACK_POINTER_REGNUM);
rtx chain = gen_rtx (MEM, Pmode, stack);
rtx temp = gen_reg_rtx (Pmode);
-
+
emit_move_insn (temp, chain);
if (TARGET_64BIT)
@@ -6752,66 +7288,23 @@
emit_move_insn (chain, temp);
- emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
+ emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
DONE;
-}")
+})
;
-; setjmp/longjmp instruction pattern(s).
+; setjmp instruction pattern.
;
-(define_expand "builtin_setjmp_setup"
- [(unspec [(match_operand 0 "register_operand" "a")] 1)]
- ""
- "
-{
- rtx base = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4 * GET_MODE_SIZE (Pmode)));
- rtx basereg = gen_rtx_REG (Pmode, BASE_REGISTER);
-
- emit_move_insn (base, basereg);
- DONE;
-}")
-
(define_expand "builtin_setjmp_receiver"
- [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
+ [(match_operand 0 "" "")]
"flag_pic"
- "
-{
- rtx gotreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
- rtx got = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
- SYMBOL_REF_FLAG (got) = 1;
-
- emit_move_insn (gotreg, got);
- emit_insn (gen_rtx_USE (VOIDmode, gotreg));
- DONE;
-}")
-
-(define_expand "builtin_longjmp"
- [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
- ""
- "
{
- /* The elements of the buffer are, in order: */
- rtx fp = gen_rtx_MEM (Pmode, operands[0]);
- rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], GET_MODE_SIZE (Pmode)));
- rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2 * GET_MODE_SIZE (Pmode)));
- rtx base = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4 * GET_MODE_SIZE (Pmode)));
- rtx basereg = gen_rtx_REG (Pmode, BASE_REGISTER);
- rtx jmp = gen_rtx_REG (Pmode, 14);
-
- emit_move_insn (jmp, lab);
- emit_move_insn (basereg, base);
- emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
- emit_move_insn (hard_frame_pointer_rtx, fp);
-
- emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
- emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
- emit_insn (gen_rtx_USE (VOIDmode, basereg));
- emit_indirect_jump (jmp);
+ s390_load_got (false);
+ emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
DONE;
-}")
-
+})
;; These patterns say how to save and restore the stack pointer. We need not
;; save the stack pointer at function level since we are careful to
@@ -6840,49 +7333,57 @@
(set (match_dup 0) (match_operand 1 "register_operand" ""))
(set (match_dup 3) (match_dup 2))]
""
- "
{
operands[2] = gen_reg_rtx (Pmode);
operands[3] = gen_rtx_MEM (Pmode, operands[0]);
-}")
+})
(define_expand "save_stack_nonlocal"
[(match_operand 0 "memory_operand" "")
(match_operand 1 "register_operand" "")]
""
- "
{
rtx temp = gen_reg_rtx (Pmode);
- /* Copy the backchain to the first word, sp to the second. */
+ /* Copy the backchain to the first word, sp to the second and the literal pool
+ base to the third. */
+ emit_move_insn (operand_subword (operands[0], 2, 0,
+ TARGET_64BIT ? OImode : TImode),
+ gen_rtx_REG (Pmode, BASE_REGISTER));
emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
emit_move_insn (operand_subword (operands[0], 0, 0,
- TARGET_64BIT ? TImode : DImode),
+ TARGET_64BIT ? OImode : TImode),
temp);
emit_move_insn (operand_subword (operands[0], 1, 0,
- TARGET_64BIT ? TImode : DImode),
+ TARGET_64BIT ? OImode : TImode),
operands[1]);
DONE;
-}")
+})
(define_expand "restore_stack_nonlocal"
[(match_operand 0 "register_operand" "")
(match_operand 1 "memory_operand" "")]
""
- "
{
rtx temp = gen_reg_rtx (Pmode);
+ rtx base = gen_rtx_REG (Pmode, BASE_REGISTER);
- /* Restore the backchain from the first word, sp from the second. */
+ /* Restore the backchain from the first word, sp from the second and the
+ literal pool base from the third. */
emit_move_insn (temp,
operand_subword (operands[1], 0, 0,
- TARGET_64BIT ? TImode : DImode));
+ TARGET_64BIT ? OImode : TImode));
emit_move_insn (operands[0],
operand_subword (operands[1], 1, 0,
- TARGET_64BIT ? TImode : DImode));
+ TARGET_64BIT ? OImode : TImode));
emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp);
+ emit_move_insn (base,
+ operand_subword (operands[1], 2, 0,
+ TARGET_64BIT ? OImode : TImode));
+ emit_insn (gen_rtx_USE (VOIDmode, base));
+
DONE;
-}")
+})
;
@@ -6892,7 +7393,7 @@
(define_insn "nop"
[(const_int 0)]
""
- "lr\\t0,0"
+ "lr\t0,0"
[(set_attr "op_type" "RR")])
@@ -6900,143 +7401,97 @@
; Special literal pool access instruction pattern(s).
;
-(define_insn "consttable_qi"
- [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "X")] 200)]
- ""
- "*
-{
- assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
- return \"\";
-}"
- [(set_attr "op_type" "NN")
- (set_attr "length" "1")])
-
-(define_insn "consttable_hi"
- [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "X")] 201)]
- ""
- "*
-{
- assemble_integer (operands[0], 2, 2*BITS_PER_UNIT, 1);
- return \"\";
-}"
- [(set_attr "op_type" "NN")
- (set_attr "length" "2")])
-
-(define_insn "consttable_si"
- [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "X")] 202)]
+(define_insn "*pool_entry"
+ [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
+ UNSPECV_POOL_ENTRY)]
""
- "*
{
- if (!TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[0]))
- return \".long\\t%0\";
-
- assemble_integer (operands[0], 4, 4*BITS_PER_UNIT, 1);
- return \"\";
-}"
- [(set_attr "op_type" "NN")
- (set_attr "length" "4")])
-
-(define_insn "consttable_di"
- [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "X")] 203)]
- ""
- "*
-{
- assemble_integer (operands[0], 8, 8*BITS_PER_UNIT, 1);
- return \"\";
-}"
- [(set_attr "op_type" "NN")
- (set_attr "length" "8")])
-
-(define_insn "consttable_sf"
- [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "X")] 204)]
- ""
- "*
-{
- REAL_VALUE_TYPE r;
-
- if (GET_CODE (operands[0]) != CONST_DOUBLE)
- abort ();
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
- assemble_real (r, SFmode, 4*BITS_PER_UNIT);
- return \"\";
-}"
- [(set_attr "op_type" "NN")
- (set_attr "length" "4")])
-
-(define_insn "consttable_df"
- [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "X")] 205)]
- ""
- "*
-{
- REAL_VALUE_TYPE r;
-
- if (GET_CODE (operands[0]) != CONST_DOUBLE)
- abort ();
-
- REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
- assemble_real (r, DFmode, 8*BITS_PER_UNIT);
- return \"\";
-}"
- [(set_attr "op_type" "NN")
- (set_attr "length" "8")])
+ enum machine_mode mode = GET_MODE (PATTERN (insn));
+ unsigned int align = GET_MODE_BITSIZE (mode);
+ s390_output_pool_entry (asm_out_file, operands[0], mode, align);
+ return "";
+}
+ [(set_attr "op_type" "NN")
+ (set (attr "length")
+ (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
(define_insn "pool_start_31"
- [(unspec_volatile [(const_int 0)] 206)]
- "!TARGET_64BIT"
- ".align\\t4"
+ [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)]
+ "!TARGET_CPU_ZARCH"
+ ".align\t4"
[(set_attr "op_type" "NN")
(set_attr "length" "2")])
(define_insn "pool_end_31"
- [(unspec_volatile [(const_int 0)] 207)]
- "!TARGET_64BIT"
- ".align\\t2"
+ [(unspec_volatile [(const_int 0)] UNSPECV_POOL_END)]
+ "!TARGET_CPU_ZARCH"
+ ".align\t2"
[(set_attr "op_type" "NN")
(set_attr "length" "2")])
(define_insn "pool_start_64"
- [(unspec_volatile [(const_int 0)] 206)]
- "TARGET_64BIT"
- ".section\\t.rodata\;.align\\t8"
+ [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)]
+ "TARGET_CPU_ZARCH"
+ ".section\t.rodata\;.align\t8"
[(set_attr "op_type" "NN")
(set_attr "length" "0")])
(define_insn "pool_end_64"
- [(unspec_volatile [(const_int 0)] 207)]
- "TARGET_64BIT"
+ [(unspec_volatile [(const_int 0)] UNSPECV_POOL_END)]
+ "TARGET_CPU_ZARCH"
".previous"
[(set_attr "op_type" "NN")
(set_attr "length" "0")])
+(define_insn "main_base_31_small"
+ [(set (match_operand 0 "register_operand" "=a")
+ (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
+ "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
+ "basr\t%0,0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "la")])
+
+(define_insn "main_base_31_large"
+ [(set (match_operand 0 "register_operand" "=a")
+ (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
+ (set (pc) (label_ref (match_operand 2 "" "")))]
+ "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
+ "bras\t%0,%2"
+ [(set_attr "op_type" "RI")])
+
+(define_insn "main_base_64"
+ [(set (match_operand 0 "register_operand" "=a")
+ (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
+ "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
+ "larl\t%0,%1"
+ [(set_attr "op_type" "RIL")
+ (set_attr "type" "larl")])
+
+(define_insn "main_pool"
+ [(unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL)]
+ ""
+ "* abort ();"
+ [(set_attr "op_type" "NN")])
+
(define_insn "reload_base_31"
- [(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI [(label_ref (match_operand 1 "" ""))] 210))]
- "!TARGET_64BIT"
- "basr\\t%0,0\;la\\t%0,%1-.(%0)"
+ [(set (match_operand 0 "register_operand" "=a")
+ (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
+ "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
+ "basr\t%0,0\;la\t%0,%1-.(%0)"
[(set_attr "op_type" "NN")
(set_attr "type" "la")
(set_attr "length" "6")])
(define_insn "reload_base_64"
- [(set (match_operand:DI 0 "register_operand" "=a")
- (unspec:DI [(label_ref (match_operand 1 "" ""))] 210))]
- "TARGET_64BIT"
- "larl\\t%0,%1"
+ [(set (match_operand 0 "register_operand" "=a")
+ (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
+ "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
+ "larl\t%0,%1"
[(set_attr "op_type" "RIL")
- (set_attr "type" "la")])
-
-(define_insn "reload_anchor"
- [(set (match_operand:SI 0 "register_operand" "=a")
- (unspec:SI [(match_operand:SI 1 "register_operand" "a")] 211))]
- "!TARGET_64BIT"
- "l\\t%0,0(%1)\;la\\t%0,0(%0,%1)"
- [(set_attr "op_type" "NN")
- (set_attr "type" "la")
- (set_attr "length" "8")])
+ (set_attr "type" "larl")])
(define_insn "pool"
- [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] 220)]
+ [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
""
"* abort ();"
[(set_attr "op_type" "NN")
@@ -7050,78 +7505,33 @@
(define_expand "prologue"
[(use (const_int 0))]
""
- "
-{
- s390_emit_prologue ();
- DONE;
-}")
+ "s390_emit_prologue (); DONE;")
(define_expand "epilogue"
[(use (const_int 1))]
""
- "
-{
- s390_emit_epilogue ();
- DONE;
-}")
-
+ "s390_emit_epilogue (); DONE;")
-(define_insn "*return_si"
+(define_insn "*return"
[(return)
- (use (match_operand:SI 0 "register_operand" "a"))]
- "!TARGET_64BIT"
- "br\\t%0"
+ (use (match_operand 0 "register_operand" "a"))]
+ "GET_MODE (operands[0]) == Pmode"
+ "br\t%0"
[(set_attr "op_type" "RR")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
+ (set_attr "type" "jsr")
+ (set_attr "atype" "agen")])
-(define_insn "*return_di"
- [(return)
- (use (match_operand:DI 0 "register_operand" "a"))]
- "TARGET_64BIT"
- "br\\t%0"
- [(set_attr "op_type" "RR")
- (set_attr "type" "jsr")
- (set_attr "atype" "mem")])
-(define_insn "literal_pool_31"
- [(unspec_volatile [(const_int 0)] 300)
- (set (match_operand:SI 0 "register_operand" "=a")
- (label_ref (match_operand 1 "" "")))
- (use (label_ref (match_operand 2 "" "")))]
- ""
-{
- if (s390_nr_constants)
- {
- output_asm_insn ("bras\\t%0,%2", operands);
- s390_output_constant_pool (operands[1], operands[2]);
- }
- else if (flag_pic)
- {
- /* We need the anchor label in any case. */
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
- CODE_LABEL_NUMBER (operands[1]));
- }
-
- return "";
-}
- [(set_attr "op_type" "NN")
- (set_attr "type" "la")])
+;; Instruction definition to extend a 31-bit pointer into a 64-bit
+;; pointer. This is used for compatibility.
-(define_insn "literal_pool_64"
- [(unspec_volatile [(const_int 0)] 300)
- (set (match_operand:DI 0 "register_operand" "=a")
- (label_ref (match_operand 1 "" "")))
- (use (label_ref (match_operand 2 "" "")))]
- ""
+(define_expand "ptr_extend"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (match_operand:SI 1 "register_operand" "r"))]
+ "TARGET_64BIT"
{
- if (s390_nr_constants)
- {
- output_asm_insn ("larl\\t%0,%1", operands);
- s390_output_constant_pool (operands[1], operands[2]);
- }
-
- return "";
-}
- [(set_attr "op_type" "NN")
- (set_attr "type" "la")])
+ emit_insn (gen_anddi3 (operands[0],
+ gen_lowpart (DImode, operands[1]),
+ GEN_INT (0x7fffffff)));
+ DONE;
+})
diff --git a/contrib/gcc/config/s390/s390x.h b/contrib/gcc/config/s390/s390x.h
index c79acf5dc4fe..f9177c1c2669 100644
--- a/contrib/gcc/config/s390/s390x.h
+++ b/contrib/gcc/config/s390/s390x.h
@@ -2,22 +2,23 @@
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Hartmut Penner (hpenner@de.ibm.com) and
Ulrich Weigand (uweigand@de.ibm.com).
-This file is part of GNU CC.
-GNU CC 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 file is part of GCC.
-GNU CC 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.
+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 2, 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 GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
#ifndef _S390X_H
#define _S390X_H
diff --git a/contrib/gcc/config/s390/t-tpf b/contrib/gcc/config/s390/t-tpf
new file mode 100644
index 000000000000..c04d5622d6c9
--- /dev/null
+++ b/contrib/gcc/config/s390/t-tpf
@@ -0,0 +1,13 @@
+# Compile crtbeginS.o and crtendS.o with pic.
+CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) -fPIC
+# Compile libgcc2.a with pic.
+TARGET_LIBGCC2_CFLAGS = -fPIC
+
+# Override t-slibgcc-elf-ver to export some libgcc symbols with
+# the symbol versions that glibc used.
+SHLIB_MAPFILES += $(srcdir)/config/s390/libgcc-glibc.ver
+
+# Use unwind-dw2-fde-glibc
+LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
+ $(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c
+LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c gthr-gnat.c
diff --git a/contrib/gcc/config/s390/tpf.h b/contrib/gcc/config/s390/tpf.h
new file mode 100644
index 000000000000..ce984e64003a
--- /dev/null
+++ b/contrib/gcc/config/s390/tpf.h
@@ -0,0 +1,112 @@
+/* Definitions for target OS TPF for GNU compiler, for IBM S/390 hardware
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by P.J. Darcy (darcypj@us.ibm.com),
+ Hartmut Penner (hpenner@de.ibm.com), and
+ Ulrich Weigand (uweigand@de.ibm.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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef _TPF_H
+#define _TPF_H
+
+/* TPF wants the following macros defined/undefined as follows. */
+#undef ASM_APP_ON
+#define ASM_APP_ON "#APP\n"
+#undef ASM_APP_OFF
+#define ASM_APP_OFF "#NO_APP\n"
+#define NO_IMPLICIT_EXTERN_C
+#define TARGET_HAS_F_SETLKW
+#undef MD_EXEC_PREFIX
+#undef MD_STARTFILE_PREFIX
+
+#undef SIZE_TYPE
+#define SIZE_TYPE ("long unsigned int")
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE ("long int")
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "int"
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE 32
+
+
+/* Basic record keeping for the TPF OS name. */
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (TPF: zSeries)");
+
+/* TPF OS specific stack-pointer offset. */
+#undef STACK_POINTER_OFFSET
+#define STACK_POINTER_OFFSET 280
+
+/* When building for TPF, set a generic default target that is 64 bits. */
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT 0x33
+
+/* TPF OS specific compiler settings. */
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("tpf"); \
+ builtin_assert ("system=tpf"); \
+ builtin_define ("__ELF__"); \
+ if (flag_pic) \
+ { \
+ builtin_define ("__PIC__"); \
+ builtin_define ("__pic__"); \
+ } \
+ } \
+ while (0)
+
+
+/* Make TPF specific spec file settings here. */
+
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+ "%{!shared: \
+ %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
+ %{!p:%{profile:gcrt1.o%s} \
+ %{!profile:crt1.o%s}}}} \
+ crti.o%s %{static:crtbeginT.o%s} \
+ %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+ "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+
+/* The GNU C++ standard library requires that these macros be defined. */
+#undef CPLUSPLUS_CPP_SPEC
+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{pthread:-lpthread} -lc"
+
+#undef TARGET_C99_FUNCTIONS
+#define TARGET_C99_FUNCTIONS 1
+
+#undef LINK_SPEC
+#define LINK_SPEC \
+ "-m elf64_s390 \
+ %{shared:-shared} \
+ %{!shared: \
+ %{static:-static} \
+ %{!static: \
+ %{rdynamic:-export-dynamic} \
+ %{!dynamic-linker:-dynamic-linker /lib/ld64.so}}}"
+
+#endif /* ! _TPF_H */
+
diff --git a/contrib/gcc/config/sol2.h b/contrib/gcc/config/sol2.h
index c5980fbe1689..955cd0e7d1bf 100644
--- a/contrib/gcc/config/sol2.h
+++ b/contrib/gcc/config/sol2.h
@@ -1,21 +1,21 @@
/* Operating system specific defines to be used when targeting GCC for any
Solaris 2 system.
- Copyright 2002 Free Software Foundation, Inc.
+ Copyright 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -53,6 +53,7 @@ Boston, MA 02111-1307, USA. */
"
/* Names to predefine in the preprocessor for this target machine. */
+#define TARGET_SUB_OS_CPP_BUILTINS()
#define TARGET_OS_CPP_BUILTINS() \
do { \
builtin_define_std ("unix"); \
@@ -62,24 +63,28 @@ Boston, MA 02111-1307, USA. */
builtin_define ("__PRAGMA_REDEFINE_EXTNAME"); \
builtin_assert ("system=unix"); \
builtin_assert ("system=svr4"); \
- /* For C++ we need to add some additional macro \
+ /* For C++ we need to add some additional macro \
definitions required by the C++ standard \
library. */ \
- if (c_language == clk_cplusplus) \
+ if (c_dialect_cxx ()) \
{ \
builtin_define ("_XOPEN_SOURCE=500"); \
builtin_define ("_LARGEFILE_SOURCE=1"); \
builtin_define ("_LARGEFILE64_SOURCE=1"); \
builtin_define ("__EXTENSIONS__"); \
} \
+ TARGET_SUB_OS_CPP_BUILTINS(); \
} while (0)
+/* The system headers under Solaris 2 are C++-aware since 2.0. */
+#define NO_IMPLICIT_EXTERN_C
+
/* The sun bundled assembler doesn't accept -Yd, (and neither does gas).
It's safe to pass -s always, even if -g is not used. */
#undef ASM_SPEC
#define ASM_SPEC "\
%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s \
-%{fpic:-K PIC} %{fPIC:-K PIC} \
+%{fpic|fpie|fPIC|fPIE:-K PIC} \
%(asm_cpu) \
"
@@ -114,8 +119,8 @@ Boston, MA 02111-1307, USA. */
#undef STARTFILE_ARCH_SPEC
#define STARTFILE_ARCH_SPEC STARTFILE_ARCH32_SPEC
-#undef LINK_ARCH32_SPEC
-#define LINK_ARCH32_SPEC \
+#undef LINK_ARCH32_SPEC_BASE
+#define LINK_ARCH32_SPEC_BASE \
"%{G:-G} \
%{YP,*} \
%{R*} \
@@ -127,6 +132,9 @@ Boston, MA 02111-1307, USA. */
%{!YP,*:%{p|pg:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \
%{!p:%{!pg:-Y P,/usr/ccs/lib:/usr/lib}}}}"
+#undef LINK_ARCH32_SPEC
+#define LINK_ARCH32_SPEC LINK_ARCH32_SPEC_BASE
+
#undef LINK_ARCH_SPEC
#define LINK_ARCH_SPEC LINK_ARCH32_SPEC
@@ -155,24 +163,17 @@ Boston, MA 02111-1307, USA. */
/*
* Attempt to turn on access permissions for the stack.
*
- * This code must be defined when compiling gcc but not when compiling
- * libgcc2.a, unless we're generating code for 64-bit SPARC
- *
* _SC_STACK_PROT is only defined for post 2.6, but we want this code
* to run always. 2.6 can change the stack protection but has no way to
* query it.
*
*/
-/* This declares mprotect (used in TRANSFER_FROM_TRAMPOLINE) for
- libgcc2.c. */
-/* We don't want to include this because sys/mman.h is not present on
- some non-Solaris configurations that use sol2.h. */
-#if 0 /* def L_trampoline */
-#include <sys/mman.h>
-#endif
+/* sys/mman.h is not present on some non-Solaris configurations
+ that use sol2.h, so ENABLE_EXECUTE_STACK must use a magic
+ number instead of the appropriate PROT_* flags. */
-#define TRANSFER_FROM_TRAMPOLINE \
+#define ENABLE_EXECUTE_STACK \
\
/* #define STACK_PROT_RWX (PROT_READ | PROT_WRITE | PROT_EXEC) */ \
\
@@ -190,9 +191,9 @@ static void check_enabling(void) \
\
extern void __enable_execute_stack (void *); \
void \
-__enable_execute_stack (addr) \
- void *addr; \
+__enable_execute_stack (void *addr) \
{ \
+ extern int mprotect (void *, size_t, int); \
if (!need_enable_exec_stack) \
return; \
else { \
diff --git a/contrib/gcc/config/sparc/aout.h b/contrib/gcc/config/sparc/aout.h
index 7532281361d5..1031048df696 100644
--- a/contrib/gcc/config/sparc/aout.h
+++ b/contrib/gcc/config/sparc/aout.h
@@ -1,21 +1,21 @@
-/* Definitions of target machine for GNU compiler, for SPARC using a.out.
+/* Definitions of target machine for GCC, for SPARC using a.out.
Copyright (C) 1994, 1996, 2002 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -23,14 +23,6 @@ Boston, MA 02111-1307, USA. */
#define TARGET_VERSION fprintf (stderr, " (sparc)");
-/* Names to predefine in the preprocessor for this target machine.
- ??? It would be nice to not include any subtarget specific values here,
- however there's no way to portably provide subtarget values to
- CPP_PREFINES. Also, -D values in CPP_SUBTARGET_SPEC don't get turned into
- foo, __foo and __foo__. */
-
-#define CPP_PREDEFINES "-Dsparc -Acpu=sparc -Amachine=sparc"
-
/* These compiler options take an argument. We ignore -target for now. */
#define WORD_SWITCH_TAKES_ARG(STR) \
@@ -67,8 +59,6 @@ do { \
This is needed for SunOS 4.0, and should not hurt for 3.2
versions either. */
-#define ASM_OUTPUT_SOURCE_LINE(file, line) \
- { static int sym_lineno = 1; \
- fprintf (file, ".stabn 68,0,%d,LM%d\nLM%d:\n", \
- line, sym_lineno, sym_lineno); \
- sym_lineno += 1; }
+#define ASM_OUTPUT_SOURCE_LINE(file, line, counter) \
+ fprintf (file, ".stabn 68,0,%d,LM%d\nLM%d:\n", \
+ line, counter, counter)
diff --git a/contrib/gcc/config/sparc/biarch64.h b/contrib/gcc/config/sparc/biarch64.h
index f85111ab7eb2..b825f4f3e5b9 100644
--- a/contrib/gcc/config/sparc/biarch64.h
+++ b/contrib/gcc/config/sparc/biarch64.h
@@ -1,21 +1,21 @@
-/* Definitions of target machine for GNU compiler, for Sun SPARC.
+/* Definitions of target machine for GCC, for Sun SPARC.
Copyright (C) 2001 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org>.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/sparc/cypress.md b/contrib/gcc/config/sparc/cypress.md
index e9bff6d77a7d..c2345940fb7d 100644
--- a/contrib/gcc/config/sparc/cypress.md
+++ b/contrib/gcc/config/sparc/cypress.md
@@ -1,20 +1,20 @@
;; Scheduling description for SPARC Cypress.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/sparc/elf.h b/contrib/gcc/config/sparc/elf.h
index d2d3a0b74d36..5f01a34b5905 100644
--- a/contrib/gcc/config/sparc/elf.h
+++ b/contrib/gcc/config/sparc/elf.h
@@ -1,27 +1,24 @@
-/* Definitions of target machine for GNU compiler,
+/* Definitions of target machine for GCC,
for SPARC running in an embedded environment using the ELF file format.
Copyright (C) 1997 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc -D__elf__"
-
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s"
@@ -45,14 +42,9 @@ Boston, MA 02111-1307, USA. */
#undef STDC_0_IN_SYSTEM_HEADERS
/* We don't want to use the Solaris2 specific long long int conversion
- routines. */
-#undef INIT_SUBTARGET_OPTABS
-#define INIT_SUBTARGET_OPTABS
-
-/* ??? We haven't added Solaris2 equivalent 64 bit library routines to
- lb1sp*.asm, so we need to avoid using them. */
-#undef MULDI3_LIBCALL
-#undef DIVDI3_LIBCALL
-#undef UDIVDI3_LIBCALL
-#undef MODDI3_LIBCALL
-#undef UMODDI3_LIBCALL
+ routines or 64-bit integer multiply and divide routines. */
+#undef SUN_CONVERSION_LIBFUNCS
+#define SUN_CONVERSION_LIBFUNCS 0
+
+#undef SUN_INTEGER_MULTIPLY_64
+#define SUN_INTEGER_MULTIPLY_64 0
diff --git a/contrib/gcc/config/sparc/freebsd.h b/contrib/gcc/config/sparc/freebsd.h
index b2809ddb7cf5..c6f7398d9526 100644
--- a/contrib/gcc/config/sparc/freebsd.h
+++ b/contrib/gcc/config/sparc/freebsd.h
@@ -1,37 +1,38 @@
/* Definitions for Sun SPARC64 running FreeBSD using the ELF format
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
Contributed by David E. O'Brien <obrien@FreeBSD.org> and BSDi.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ { "fbsd_dynamic_linker", FBSD_DYNAMIC_LINKER }
+
/* FreeBSD needs the platform name (sparc64) defined.
Emacs needs to know if the arch is 64 or 32-bits. */
#undef CPP_CPU64_DEFAULT_SPEC
#define CPP_CPU64_DEFAULT_SPEC \
- "-D__sparc64__ -D__sparc_v9__ -D__sparcv9 -D__sparc__ -D__arch64__"
-
-/* Because we include sparc/sysv4.h. */
-#undef CPP_PREDEFINES
-/* Do not define it here, we now use TARGET_OS_CPP_BUILTINS. */
+ "-D__sparc64__ -D__sparc_v9__ -D__sparcv9 -D__arch64__"
#define LINK_SPEC "%(link_arch) \
%{!mno-relax:%{!r:-relax}} \
- %{p:%e`-p' not supported; use `-pg' and gprof(1)} \
+ %{p:%nconsider using `-pg' instead of `-p' with gprof(1)} \
%{Wl,*:%*} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
%{shared:-Bshareable %{h*} %{soname*}} \
@@ -39,7 +40,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \
+ %{!dynamic-linker:-dynamic-linker %(fbsd_dynamic_linker) }} \
%{static:-Bstatic}}"
@@ -99,7 +100,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#undef SPARC_DEFAULT_CMODEL
#define SPARC_DEFAULT_CMODEL CM_MEDLOW
-#define TRANSFER_FROM_TRAMPOLINE \
+#define ENABLE_EXECUTE_STACK \
static int need_enable_exec_stack; \
static void check_enabling(void) __attribute__ ((constructor)); \
static void check_enabling(void) \
@@ -131,14 +132,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define LOCAL_LABEL_PREFIX "."
/* XXX2 */
-/* This is how to output a definition of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".L%s%d:\n", PREFIX, NUM)
-
-/* XXX2 */
/* This is how to output a reference to an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
@@ -154,7 +147,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
- sprintf (LABEL, "*.L%s%d", PREFIX, NUM)
+ sprintf (LABEL, "*.L%s%lu", PREFIX, (unsigned long)(NUM))
/************************[ Debugger stuff ]*********************************/
diff --git a/contrib/gcc/config/sparc/gmon-sol2.c b/contrib/gcc/config/sparc/gmon-sol2.c
index c5776661eea2..9f9f019e38b3 100644
--- a/contrib/gcc/config/sparc/gmon-sol2.c
+++ b/contrib/gcc/config/sparc/gmon-sol2.c
@@ -32,8 +32,11 @@
* for Cygnus Support, July 1992.
*/
-#include "config.h"
-#include "system.h"
+#include "tconfig.h"
+#include "tsystem.h"
+#include <fcntl.h> /* for creat() */
+#include "coretypes.h"
+#include "tm.h"
#if 0
#include "sparc/gmon.h"
@@ -85,13 +88,11 @@ static int s_scale;
#define MSG "No space for profiling buffer(s)\n"
-static void moncontrol PARAMS ((int));
-extern void monstartup PARAMS ((char *, char *));
-extern void _mcleanup PARAMS ((void));
+static void moncontrol (int);
+extern void monstartup (char *, char *);
+extern void _mcleanup (void);
-void monstartup(lowpc, highpc)
- char *lowpc;
- char *highpc;
+void monstartup(char *lowpc, char *highpc)
{
int monsize;
char *buffer;
@@ -167,7 +168,7 @@ void monstartup(lowpc, highpc)
}
void
-_mcleanup()
+_mcleanup(void)
{
int fd;
int fromindex;
@@ -266,7 +267,8 @@ _mcleanup()
* -- [eichin:19920702.1107EST]
*/
-static void internal_mcount PARAMS ((char *, unsigned short *)) ATTRIBUTE_UNUSED;
+static void internal_mcount (char *, unsigned short *)
+ __attribute__ ((__unused__));
/* i7 == last ret, -> frompcindex */
/* o7 == current ret, -> selfpc */
@@ -275,9 +277,7 @@ asm(".global _mcount; _mcount: mov %i7,%o1; mov %o7,%o0;b,a internal_mcount");
/* This is for compatibility with old versions of gcc which used mcount. */
asm(".global mcount; mcount: mov %i7,%o1; mov %o7,%o0;b,a internal_mcount");
-static void internal_mcount(selfpc, frompcindex)
- register char *selfpc;
- register unsigned short *frompcindex;
+static void internal_mcount(char *selfpc, unsigned short *frompcindex)
{
register struct tostruct *top;
register struct tostruct *prevtop;
@@ -407,8 +407,7 @@ overflow:
* profiling is what mcount checks to see if
* all the data structures are ready.
*/
-static void moncontrol(mode)
- int mode;
+static void moncontrol(int mode)
{
if (mode) {
/* start */
diff --git a/contrib/gcc/config/sparc/hypersparc.md b/contrib/gcc/config/sparc/hypersparc.md
index d80e51e9848c..d617efd9fc81 100644
--- a/contrib/gcc/config/sparc/hypersparc.md
+++ b/contrib/gcc/config/sparc/hypersparc.md
@@ -1,20 +1,20 @@
;; Scheduling description for HyperSPARC.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/sparc/linux.h b/contrib/gcc/config/sparc/linux.h
index e4bd7bbe196c..7ddf2a35fdc7 100644
--- a/contrib/gcc/config/sparc/linux.h
+++ b/contrib/gcc/config/sparc/linux.h
@@ -1,37 +1,40 @@
/* Definitions for SPARC running Linux-based GNU systems with ELF.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Eddie C. Dost (ecd@skynet.be)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define LINUX_DEFAULT_ELF
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("unix"); \
+ builtin_define_std ("linux"); \
+ builtin_define ("__gnu_linux__"); \
+ builtin_assert ("system=linux"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=posix"); \
+ } \
+ while (0)
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
-/* GNU/Linux uses ctype from glibc.a. I am not sure how complete it is.
- For now, we play safe. It may change later. */
-
-#if 0
-#undef MULTIBYTE_CHARS
-#define MULTIBYTE_CHARS 1
-#endif
-
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
@@ -46,12 +49,14 @@ Boston, MA 02111-1307, USA. */
"%{!shared: \
%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
+#elif defined HAVE_LD_PIE
+#define STARTFILE_SPEC \
+ "%{!shared: %{pg|p:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#else
#define STARTFILE_SPEC \
- "%{!shared: \
- %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
- crti.o%s %{static:crtbeginT.o%s}\
- %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
+ "%{!shared: %{pg|p:gcrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
#endif
/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
@@ -63,7 +68,7 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
- %{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
+ %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
/* This is for -profile to use -lc_p instead of -lc. */
#undef CC1_SPEC
@@ -98,17 +103,14 @@ Boston, MA 02111-1307, USA. */
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__ELF__ -Dunix -D__sparc__ -D__gnu_linux__ -Dlinux -Asystem=unix -Asystem=posix"
-
#undef CPP_SUBTARGET_SPEC
#ifdef USE_GNULIBC_1
#define CPP_SUBTARGET_SPEC \
-"%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} \
+"%{fPIC|fPIE|fpic|fpie:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} \
%{mlong-double-128:-D__LONG_DOUBLE_128__}"
#else
#define CPP_SUBTARGET_SPEC \
-"%{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} \
+"%{fPIC|fPIE|fpic|fpie:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE} \
%{pthread:-D_REENTRANT} %{mlong-double-128:-D__LONG_DOUBLE_128__}"
#endif
@@ -152,15 +154,6 @@ Boston, MA 02111-1307, USA. */
#undef LINK_SPEC
#ifdef USE_GNULIBC_1
-#ifndef LINUX_DEFAULT_ELF
-#define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \
- %{!shared: \
- %{!ibcs: \
- %{!static: \
- %{rdynamic:-export-dynamic} \
- %{!dynamic-linker:-dynamic-linker /lib/elf/ld-linux.so.1} \
- %{!rpath:-rpath /lib/elf/}} %{static:-static}}}"
-#else
#define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \
%{!shared: \
%{!ibcs: \
@@ -168,7 +161,6 @@ Boston, MA 02111-1307, USA. */
%{rdynamic:-export-dynamic} \
%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.1}} \
%{static:-static}}}"
-#endif
#else
#define LINK_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \
%{!mno-relax:%{!r:-relax}} \
@@ -184,8 +176,8 @@ Boston, MA 02111-1307, USA. */
It's safe to pass -s always, even if -g is not used. */
#undef ASM_SPEC
#define ASM_SPEC \
- "%{V} %{v:%{!V:-V}} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s %{fpic:-K PIC} \
- %{fPIC:-K PIC} %(asm_cpu) %(asm_relax)"
+ "%{V} %{v:%{!V:-V}} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -s \
+ %{fpic|fPIC|fpie|fPIE:-K PIC} %(asm_cpu) %(asm_relax)"
/* Same as sparc.h */
#undef DBX_REGISTER_NUMBER
@@ -206,13 +198,6 @@ do { \
#undef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."
-/* This is how to output a definition of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".L%s%d:\n", PREFIX, NUM)
-
/* This is how to output a reference to an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
@@ -245,10 +230,20 @@ do { \
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
#endif
+#undef DITF_CONVERSION_LIBFUNCS
+#define DITF_CONVERSION_LIBFUNCS 1
+
#if !defined(USE_GNULIBC_1) && defined(HAVE_LD_EH_FRAME_HDR)
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
#endif
+#ifdef HAVE_AS_TLS
+#undef TARGET_SUN_TLS
+#undef TARGET_GNU_TLS
+#define TARGET_SUN_TLS 0
+#define TARGET_GNU_TLS 1
+#endif
+
/* Don't be different from other Linux platforms in this regard. */
#define HANDLE_PRAGMA_PACK_PUSH_POP
@@ -256,6 +251,14 @@ do { \
#undef CTORS_SECTION_ASM_OP
#undef DTORS_SECTION_ASM_OP
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
+
+/* Determine whether the the entire c99 runtime is present in the
+ runtime library. */
+#define TARGET_C99_FUNCTIONS 1
+
+#define TARGET_HAS_F_SETLKW
+
#undef LINK_GCC_C_SEQUENCE_SPEC
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
diff --git a/contrib/gcc/config/sparc/linux64.h b/contrib/gcc/config/sparc/linux64.h
index 27be1d13133f..bb1c591fc389 100644
--- a/contrib/gcc/config/sparc/linux64.h
+++ b/contrib/gcc/config/sparc/linux64.h
@@ -1,25 +1,37 @@
/* Definitions for 64-bit SPARC running Linux-based GNU systems with ELF.
- Copyright 1996, 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
+ Copyright 1996, 1997, 1998, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by David S. Miller (davem@caip.rutgers.edu)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#define LINUX_DEFAULT_ELF
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("unix"); \
+ builtin_define_std ("linux"); \
+ builtin_define ("_LONGLONG"); \
+ builtin_define ("__gnu_linux__"); \
+ builtin_assert ("system=linux"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=posix"); \
+ } \
+ while (0)
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
@@ -27,7 +39,9 @@ Boston, MA 02111-1307, USA. */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
-#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
+#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
/* A 64 bit v9 compiler with stack-bias,
in a Medium/Low code model environment. */
@@ -43,8 +57,7 @@ Boston, MA 02111-1307, USA. */
#ifdef SPARC_BI_ARCH
#undef CPP_ARCH32_SPEC
-#define CPP_ARCH32_SPEC "%{mlong-double-128:-D__LONG_DOUBLE_128__} \
--D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc"
+#define CPP_ARCH32_SPEC "%{mlong-double-128:-D__LONG_DOUBLE_128__}"
#endif
@@ -55,10 +68,15 @@ Boston, MA 02111-1307, USA. */
#undef STARTFILE_SPEC
+#ifdef HAVE_LD_PIE
#define STARTFILE_SPEC \
- "%{!shared:%{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}}\
- crti.o%s %{static:crtbeginT.o%s}\
- %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
+ "%{!shared:%{pg|p:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbeginS.o%s}"
+#else
+#define STARTFILE_SPEC \
+ "%{!shared:%{pg|p:gcrt1.o%s;:crt1.o%s}}\
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbeginS.o%s}"
+#endif
/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
the GNU/Linux magical crtend.o file (see crtstuff.c) which
@@ -69,7 +87,7 @@ Boston, MA 02111-1307, USA. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
- "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s\
+ "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s\
%{ffast-math|funsafe-math-optimizations:crtfastmath.o%s}"
/* The GNU C++ standard library requires that these macros be defined. */
@@ -111,13 +129,9 @@ Boston, MA 02111-1307, USA. */
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
#endif
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__ELF__ -Dunix -D_LONGLONG -D__sparc__ -D__gnu_linux__ -Dlinux -Asystem=unix -Asystem=posix"
-
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC "\
-%{fPIC:-D__PIC__ -D__pic__} \
-%{fpic:-D__PIC__ -D__pic__} \
+%{fPIC|fpic|fPIE|fpie:-D__PIC__ -D__pic__} \
%{posix:-D_POSIX_SOURCE} \
%{pthread:-D_REENTRANT} \
"
@@ -213,6 +227,27 @@ Boston, MA 02111-1307, USA. */
"
#endif
+/* Support for a compile-time default CPU, et cetera. The rules are:
+ --with-cpu is ignored if -mcpu is specified.
+ --with-tune is ignored if -mtune is specified.
+ --with-float is ignored if -mhard-float, -msoft-float, -mfpu, or -mno-fpu
+ are specified.
+ In the SPARC_BI_ARCH compiler we cannot pass %{!mcpu=*:-mcpu=%(VALUE)}
+ here, otherwise say -mcpu=v7 would be passed even when -m64.
+ CC1_SPEC above takes care of this instead. */
+#undef OPTION_DEFAULT_SPECS
+#if DEFAULT_ARCH32_P
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!m64:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:%{!fpu:%{!no-fpu:-m%(VALUE)-float}}}}" }
+#else
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!m32:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:%{!fpu:%{!no-fpu:-m%(VALUE)-float}}}}" }
+#endif
+
#if DEFAULT_ARCH32_P
#define MULTILIB_DEFAULTS { "m32" }
#else
@@ -246,7 +281,7 @@ Boston, MA 02111-1307, USA. */
%{T} \
%{Ym,*} \
%{Wa,*:%*} \
--s %{fpic:-K PIC} %{fPIC:-K PIC} \
+-s %{fpic|fPIC|fpie|fPIE:-K PIC} \
%{mlittle-endian:-EL} \
%(asm_cpu) %(asm_arch) %(asm_relax)"
@@ -254,10 +289,6 @@ Boston, MA 02111-1307, USA. */
#undef DBX_REGISTER_NUMBER
#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
-/* System V Release 4 uses DWARF debugging info. Buf DWARF1 doesn't do
- 64-bit anything, so we use DWARF2. */
-
-#undef DWARF_DEBUGGING_INFO
#define DWARF2_DEBUGGING_INFO 1
#define DBX_DEBUGGING_INFO 1
@@ -276,13 +307,6 @@ do { \
#undef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."
-/* This is how to output a definition of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".L%s%d:\n", PREFIX, NUM)
-
/* This is how to output a reference to an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
@@ -308,10 +332,20 @@ do { \
/* #define DWARF_OFFSET_SIZE PTR_SIZE */
+#undef DITF_CONVERSION_LIBFUNCS
+#define DITF_CONVERSION_LIBFUNCS 1
+
#if defined(HAVE_LD_EH_FRAME_HDR)
#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} "
#endif
+#ifdef HAVE_AS_TLS
+#undef TARGET_SUN_TLS
+#undef TARGET_GNU_TLS
+#define TARGET_SUN_TLS 0
+#define TARGET_GNU_TLS 1
+#endif
+
/* Don't be different from other Linux platforms in this regard. */
#define HANDLE_PRAGMA_PACK_PUSH_POP
@@ -319,6 +353,14 @@ do { \
#undef CTORS_SECTION_ASM_OP
#undef DTORS_SECTION_ASM_OP
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
+
+/* Determine whether the the entire c99 runtime is present in the
+ runtime library. */
+#define TARGET_C99_FUNCTIONS 1
+
+#define TARGET_HAS_F_SETLKW
+
#undef LINK_GCC_C_SEQUENCE_SPEC
#define LINK_GCC_C_SEQUENCE_SPEC \
"%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
diff --git a/contrib/gcc/config/sparc/lite.h b/contrib/gcc/config/sparc/lite.h
index 95da781812f9..cac67ec1d0b6 100644
--- a/contrib/gcc/config/sparc/lite.h
+++ b/contrib/gcc/config/sparc/lite.h
@@ -1,27 +1,24 @@
-/* Definitions of target machine for GNU compiler, for SPARClite w/o FPU.
+/* Definitions of target machine for GCC, for SPARClite w/o FPU.
Copyright (C) 1993, 1996 Free Software Foundation, Inc.
Contributed by Jim Wilson (wilson@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc -Dsparclite -Acpu=sparc -Amachine=sparc"
-
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (sparclite)");
@@ -30,6 +27,5 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT MASK_APP_REGS
-/* US Software GOFAST library support. */
-#undef INIT_SUBTARGET_OPTABS
-#define INIT_SUBTARGET_OPTABS INIT_GOFAST_OPTABS
+/* Enable US Software GOFAST library support. */
+#define US_SOFTWARE_GOFAST
diff --git a/contrib/gcc/config/sparc/litecoff.h b/contrib/gcc/config/sparc/litecoff.h
index 91808f5eda74..e31a0b40553a 100644
--- a/contrib/gcc/config/sparc/litecoff.h
+++ b/contrib/gcc/config/sparc/litecoff.h
@@ -1,28 +1,33 @@
-/* Definitions of target machine for GNU compiler, for SPARClite w/o FPU, COFF.
+/* Definitions of target machine for GCC, for SPARClite w/o FPU, COFF.
Copyright (C) 1994, 1996, 2000, 2002 Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define BSS_SECTION_ASM_OP "\t.section\t\".bss\""
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc -Dsparclite -Acpu=sparc -Amachine=sparc"
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("sparc"); \
+ builtin_define_std ("sparclite"); \
+ } \
+ while (0)
/* Default to stabs in COFF. */
diff --git a/contrib/gcc/config/sparc/liteelf.h b/contrib/gcc/config/sparc/liteelf.h
index 9b6cbaa93ffc..49a2089b211f 100644
--- a/contrib/gcc/config/sparc/liteelf.h
+++ b/contrib/gcc/config/sparc/liteelf.h
@@ -1,30 +1,34 @@
-/* Definitions of target machine for GNU compiler, for SPARClite w/o FPU.
+/* Definitions of target machine for GCC, for SPARClite w/o FPU, ELF.
Copyright (C) 1998, 1999 Free Software Foundation, Inc.
Contributed by Stan Cox (scox@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__sparc__ -D__sparclite__ -Acpu=sparc -Amachine=sparc"
+#undef TARGET_SUB_OS_CPP_BUILTINS
+#define TARGET_SUB_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__sparclite__"); \
+ } \
+ while (0)
/* Default to dwarf2 in ELF. */
-#define DWARF_DEBUGGING_INFO 1
#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
@@ -38,9 +42,8 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT MASK_APP_REGS
-/* US Software GOFAST library support. */
-#undef INIT_SUBTARGET_OPTABS
-#define INIT_SUBTARGET_OPTABS INIT_GOFAST_OPTABS
+/* Enable US Software GOFAST library support. */
+#define US_SOFTWARE_GOFAST
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crti.o%s crtbegin.o%s"
diff --git a/contrib/gcc/config/sparc/netbsd-elf.h b/contrib/gcc/config/sparc/netbsd-elf.h
index 10788f2ae3b0..bc92eb2a3379 100644
--- a/contrib/gcc/config/sparc/netbsd-elf.h
+++ b/contrib/gcc/config/sparc/netbsd-elf.h
@@ -1,22 +1,22 @@
-/* Definitions of target machine for GNU compiler, for ELF on NetBSD/sparc
+/* Definitions of target machine for GCC, for ELF on NetBSD/sparc
and NetBSD/sparc64.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Matthew Green (mrg@eterna.com.au).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -26,9 +26,9 @@ Boston, MA 02111-1307, USA. */
NETBSD_OS_CPP_BUILTINS_ELF(); \
if (TARGET_ARCH64) \
{ \
- NETBSD_OS_CPP_BUILTINS_LP64(); \
builtin_define ("__sparc64__"); \
builtin_define ("__sparc_v9__"); \
+ builtin_define ("__sparcv9"); \
} \
else \
builtin_define ("__sparc"); \
@@ -40,9 +40,6 @@ Boston, MA 02111-1307, USA. */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
-/* Make sure this is undefined. */
-#undef CPP_PREDEFINES
-
/* CPP defines used by all NetBSD targets. */
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC "%(netbsd_cpp_spec)"
@@ -69,13 +66,6 @@ Boston, MA 02111-1307, USA. */
#undef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."
-/* This is how to output a definition of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".L%s%d:\n", PREFIX, NUM)
-
/* This is how to output a reference to an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
@@ -96,31 +86,18 @@ Boston, MA 02111-1307, USA. */
#define USER_LABEL_PREFIX ""
#undef ASM_SPEC
-#define ASM_SPEC "%{fpic:-K PIC} %{fPIC:-K PIC} %{V} %{v:%{!V:-V}} \
+#define ASM_SPEC "%{fpic|fPIC|fpie|fPIE:-K PIC} %{V} %{v:%{!V:-V}} \
%{mlittle-endian:-EL} \
%(asm_cpu) %(asm_arch) %(asm_relax)"
#undef STDC_0_IN_SYSTEM_HEADERS
/* Attempt to enable execute permissions on the stack. */
-#define TRANSFER_FROM_TRAMPOLINE NETBSD_ENABLE_EXECUTE_STACK
+#define ENABLE_EXECUTE_STACK NETBSD_ENABLE_EXECUTE_STACK
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (%s)", TARGET_NAME);
-/*
- * Clean up afterwards generic SPARC ELF configuration.
- */
-
-/* FIXME: Aren't these supposed to be available for SPARC ELF? */
-#undef MULDI3_LIBCALL
-#undef DIVDI3_LIBCALL
-#undef UDIVDI3_LIBCALL
-#undef MODDI3_LIBCALL
-#undef UMODDI3_LIBCALL
-#undef INIT_SUBTARGET_OPTABS
-#define INIT_SUBTARGET_OPTABS
-
/* Below here exists the merged NetBSD/sparc & NetBSD/sparc64 compiler
description, allowing one to build 32 bit or 64 bit applications
on either. We define the sparc & sparc64 versions of things,
diff --git a/contrib/gcc/config/sparc/openbsd.h b/contrib/gcc/config/sparc/openbsd.h
index a4333df79ab5..e36f51eb602f 100644
--- a/contrib/gcc/config/sparc/openbsd.h
+++ b/contrib/gcc/config/sparc/openbsd.h
@@ -1,29 +1,33 @@
/* Configuration file for sparc OpenBSD target.
- Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Get generic OpenBSD definitions. */
-#define OBSD_OLD_GAS
-#include <openbsd.h>
-
-/* Run-time target specifications. */
-#define CPP_PREDEFINES "-D__unix__ -D__sparc__ -D__OpenBSD__ -Asystem=unix -Asystem=OpenBSD -Acpu=sparc -Amachine=sparc"
+/* Target OS builtins. */
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__unix__"); \
+ builtin_define ("__OpenBSD__"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=OpenBSD"); \
+ } \
+ while (0)
/* Layout of source language data types */
@@ -58,8 +62,7 @@ Boston, MA 02111-1307, USA. */
/* Assembler format: exception region output. */
/* All configurations that don't use elf must be explicit about not using
- dwarf unwind information. egcs doesn't try too hard to check internal
- configuration files... */
+ dwarf unwind information. */
#define DWARF2_UNWIND_INFO 0
#undef ASM_PREFERRED_EH_DATA_FORMAT
diff --git a/contrib/gcc/config/sparc/openbsd64.h b/contrib/gcc/config/sparc/openbsd64.h
index 4dfe3819c336..e13c8862554b 100644
--- a/contrib/gcc/config/sparc/openbsd64.h
+++ b/contrib/gcc/config/sparc/openbsd64.h
@@ -30,9 +30,20 @@ Boston, MA 02111-1307, USA. */
#undef SPARC_DEFAULT_CMODEL
#define SPARC_DEFAULT_CMODEL CM_MEDMID
-/* Run-time target specifications. */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__unix__ -D__sparc__ -D__sparc64__ -D__sparcv9__ -D__sparc_v9__ -D__arch64__ -D__ELF__ -D__OpenBSD__ -Asystem(unix) -Asystem(OpenBSD) -Acpu(sparc) -Amachine(sparc)"
+/* Target OS builtins. */
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__unix__"); \
+ builtin_define ("__OpenBSD__"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=OpenBSD"); \
+ builtin_define ("__sparc64__"); \
+ builtin_define ("__sparcv9__"); \
+ builtin_define ("__sparc_v9__"); \
+ builtin_define ("__arch64__"); \
+ } \
+ while (0)
#undef CPP_SUBTARGET_SPEC
#define CPP_SUBTARGET_SPEC ""
@@ -42,7 +53,7 @@ Boston, MA 02111-1307, USA. */
#undef ASM_SPEC
#define ASM_SPEC "\
-%{v:-V} -s %{fpic:-K PIC} %{fPIC:-K PIC} \
+%{v:-V} -s %{fpic|fPIC|fpie|fPIE:-K PIC} \
%{mlittle-endian:-EL} \
%(asm_cpu) %(asm_arch) \
"
diff --git a/contrib/gcc/config/sparc/pbd.h b/contrib/gcc/config/sparc/pbd.h
index e7c01c0b48ae..e9344a0d9c74 100644
--- a/contrib/gcc/config/sparc/pbd.h
+++ b/contrib/gcc/config/sparc/pbd.h
@@ -2,28 +2,32 @@
version (using GAS and COFF (encapsulated is unacceptable) )
Copyright (C) 1990, 1996, 2000 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-
-/* Names to predefine in the preprocessor for this target machine. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc -DUnicomPBD -Dunix -D__GCC_NEW_VARARGS__ -Asystem=unix -Acpu=sparc -Amachine=sparc"
+/* Target OS builtins. */
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("unix"); \
+ builtin_define_std ("UnicomPBD"); \
+ builtin_assert ("system=unix"); \
+ } \
+ while (0)
/* We want DBX format for use with gdb under COFF. */
@@ -116,18 +120,9 @@ Boston, MA 02111-1307, USA. */
This is suitable for output with `assemble_name'. */
#undef ASM_GENERATE_INTERNAL_LABEL
-
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
sprintf (LABEL, "*.%s%ld", PREFIX, (long)(NUM))
-
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
-
/* This is how to output an element of a case-vector that is relative. */
#undef ASM_OUTPUT_ADDR_DIFF_ELT
@@ -145,10 +140,8 @@ Boston, MA 02111-1307, USA. */
/* This is needed for SunOS 4.0, and should not hurt for 3.2
versions either. */
#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(file, line) \
- { static int sym_lineno = 1; \
- fprintf (file, ".stabn 68,0,%d,.LM%d\n.LM%d:\n", \
- line, sym_lineno, sym_lineno); \
- sym_lineno += 1; }
+#define ASM_OUTPUT_SOURCE_LINE(file, line, counter) \
+ fprintf (file, ".stabn 68,0,%d,.LM%d\n.LM%d:\n", \
+ line, counter, counter)
#define ASM_INT_OP "\t.long "
diff --git a/contrib/gcc/config/sparc/rtemself.h b/contrib/gcc/config/sparc/rtemself.h
index 4f2cc66bb6cc..ffb2a7233bd2 100644
--- a/contrib/gcc/config/sparc/rtemself.h
+++ b/contrib/gcc/config/sparc/rtemself.h
@@ -2,25 +2,30 @@
Copyright (C) 1996, 1997, 2000, 2002 Free Software Foundation, Inc.
Contributed by Joel Sherrill (joel@OARcorp.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Specify predefined symbols in preprocessor. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc -D__GCC_NEW_VARARGS__ -D__rtems__ \
- -D__USE_INIT_FINI__ -Asystem=rtems"
+/* Target OS builtins. */
+#define TARGET_SUB_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("sparc"); \
+ builtin_define ("__rtems__"); \
+ builtin_define ("__USE_INIT_FINI__"); \
+ builtin_assert ("system=rtems"); \
+ } \
+ while (0)
diff --git a/contrib/gcc/config/sparc/sol2-64.h b/contrib/gcc/config/sparc/sol2-64.h
index ccdc8f3f800c..d53747a6eb00 100644
--- a/contrib/gcc/config/sparc/sol2-64.h
+++ b/contrib/gcc/config/sparc/sol2-64.h
@@ -1,7 +1,16 @@
-/* Definitions of target machine for GNU compiler, for bi-arch SPARC
+/* Definitions of target machine for GCC, for bi-arch SPARC
running Solaris 2, defaulting to 64-bit code generation. */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT \
(MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ + \
MASK_STACK_BIAS + MASK_FPU + MASK_LONG_DOUBLE_128)
+
+/* Target OS builtins. */
+#undef TARGET_SUB_OS_CPP_BUILTINS
+#define TARGET_SUB_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("sparc"); \
+ } \
+ while (0)
diff --git a/contrib/gcc/config/sparc/sol2-bi.h b/contrib/gcc/config/sparc/sol2-bi.h
index 3f9416daaa09..80ec1daf05fd 100644
--- a/contrib/gcc/config/sparc/sol2-bi.h
+++ b/contrib/gcc/config/sparc/sol2-bi.h
@@ -1,4 +1,4 @@
-/* Definitions of target machine for GNU compiler, for bi-arch SPARC
+/* Definitions of target machine for GCC, for bi-arch SPARC
running Solaris 2 using the system assembler and linker. */
/* The default code model. */
@@ -18,6 +18,7 @@
#undef ASM_CPU32_DEFAULT_SPEC
#define ASM_CPU32_DEFAULT_SPEC "-xarch=v8plus"
#endif
+
#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc
#undef CPP_CPU64_DEFAULT_SPEC
#define CPP_CPU64_DEFAULT_SPEC ""
@@ -27,6 +28,15 @@
#define ASM_CPU64_DEFAULT_SPEC AS_SPARC64_FLAG "a"
#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
+#undef CPP_CPU64_DEFAULT_SPEC
+#define CPP_CPU64_DEFAULT_SPEC ""
+#undef ASM_CPU32_DEFAULT_SPEC
+#define ASM_CPU32_DEFAULT_SPEC "-xarch=v8plusb"
+#undef ASM_CPU64_DEFAULT_SPEC
+#define ASM_CPU64_DEFAULT_SPEC AS_SPARC64_FLAG "b"
+#endif
+
#if DEFAULT_ARCH32_P
#define DEF_ARCH32_SPEC(__str) "%{!m64:" __str "}"
#define DEF_ARCH64_SPEC(__str) "%{m64:" __str "}"
@@ -45,15 +55,16 @@
%{mcpu=sparclite|mcpu-f930|mcpu=f934:-D__sparclite__} \
%{mcpu=v8:" DEF_ARCH32_SPEC("-D__sparcv8") "} \
%{mcpu=supersparc:-D__supersparc__ " DEF_ARCH32_SPEC("-D__sparcv8") "} \
-%{mcpu=v9|mcpu=ultrasparc:" DEF_ARCH32_SPEC("-D__sparcv8") "} \
+%{mcpu=v9|mcpu=ultrasparc|mcpu=ultrasparc3:" DEF_ARCH32_SPEC("-D__sparcv8") "} \
%{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \
"
#undef ASM_CPU_SPEC
#define ASM_CPU_SPEC "\
-%{mcpu=ultrasparc:" DEF_ARCH32_SPEC("-xarch=v8plusa") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "a") "} \
%{mcpu=v9:" DEF_ARCH32_SPEC("-xarch=v8plus") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "} \
-%{!mcpu=ultrasparc:%{!mcpu=v9:%{mcpu*:" DEF_ARCH32_SPEC("-xarch=v8") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "}}} \
+%{mcpu=ultrasparc:" DEF_ARCH32_SPEC("-xarch=v8plusa") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "a") "} \
+%{mcpu=ultrasparc3:" DEF_ARCH32_SPEC("-xarch=v8plusb") DEF_ARCH64_SPEC(AS_SPARC64_FLAG "b") "} \
+%{!mcpu=ultrasparc3:%{!mcpu=ultrasparc:%{!mcpu=v9:%{mcpu*:" DEF_ARCH32_SPEC("-xarch=v8") DEF_ARCH64_SPEC(AS_SPARC64_FLAG) "}}}} \
%{!mcpu*:%(asm_cpu_default)} \
"
@@ -98,11 +109,9 @@
#define WINT_TYPE_SIZE 32
#undef CPP_ARCH32_SPEC
-#define CPP_ARCH32_SPEC "\
--D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc"
+#define CPP_ARCH32_SPEC ""
#undef CPP_ARCH64_SPEC
-#define CPP_ARCH64_SPEC "\
--D__arch64__ -Acpu=sparc64 -Amachine=sparcv9 -D__sparcv9"
+#define CPP_ARCH64_SPEC "-D__arch64__ -D__sparcv9"
#undef CPP_ARCH_SPEC
#define CPP_ARCH_SPEC "\
@@ -135,7 +144,7 @@
* This should be the same as in sol2.h, except with "/sparcv9"
* appended to the paths and /usr/ccs/lib is no longer necessary
*/
-#define LINK_ARCH64_SPEC \
+#define LINK_ARCH64_SPEC_BASE \
"%{mcmodel=medlow:-M /usr/lib/ld/sparcv9/map.below4G} \
%{G:-G} \
%{YP,*} \
@@ -143,17 +152,35 @@
%{compat-bsd: \
%{!YP,*:%{p|pg:-Y P,/usr/ucblib/sparcv9:/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \
%{!p:%{!pg:-Y P,/usr/ucblib/sparcv9:/usr/lib/sparcv9}}} \
- -R /usr/ucblib} \
+ -R /usr/ucblib/sparcv9} \
%{!compat-bsd: \
%{!YP,*:%{p|pg:-Y P,/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \
%{!p:%{!pg:-Y P,/usr/lib/sparcv9}}}}"
+#define LINK_ARCH64_SPEC LINK_ARCH64_SPEC_BASE
+
#undef LINK_ARCH_SPEC
+#if DISABLE_MULTILIB
+#if DEFAULT_ARCH32_P
#define LINK_ARCH_SPEC "\
%{m32:%(link_arch32)} \
+%{m64:%edoes not support multilib} \
+%{!m32:%{!m64:%(link_arch_default)}} \
+"
+#else
+#define LINK_ARCH_SPEC "\
+%{m32:%edoes not support multilib} \
%{m64:%(link_arch64)} \
%{!m32:%{!m64:%(link_arch_default)}} \
"
+#endif
+#else
+#define LINK_ARCH_SPEC "\
+%{m32:%(link_arch32)} \
+%{m64:%(link_arch64)} \
+%{!m32:%{!m64:%(link_arch_default)}} \
+"
+#endif
#define LINK_ARCH_DEFAULT_SPEC \
(DEFAULT_ARCH32_P ? LINK_ARCH32_SPEC : LINK_ARCH64_SPEC)
@@ -183,23 +210,36 @@
"
#endif
+/* Support for a compile-time default CPU, et cetera. The rules are:
+ --with-cpu is ignored if -mcpu is specified.
+ --with-tune is ignored if -mtune is specified.
+ --with-float is ignored if -mhard-float, -msoft-float, -mfpu, or -mno-fpu
+ are specified.
+ In the SPARC_BI_ARCH compiler we cannot pass %{!mcpu=*:-mcpu=%(VALUE)}
+ here, otherwise say -mcpu=v7 would be passed even when -m64.
+ CC1_SPEC above takes care of this instead. */
+#undef OPTION_DEFAULT_SPECS
+#if DEFAULT_ARCH32_P
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!m64:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:%{!fpu:%{!no-fpu:-m%(VALUE)-float}}}}" }
+#else
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!m32:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:%{!fpu:%{!no-fpu:-m%(VALUE)-float}}}}" }
+#endif
+
#if DEFAULT_ARCH32_P
#define MULTILIB_DEFAULTS { "m32" }
#else
#define MULTILIB_DEFAULTS { "m64" }
#endif
-/* We use stabs-in-elf in 32-bit mode, because that is what the native
- toolchain uses. But gdb can't handle truncated 32-bit stabs so we
- use dwarf2 in 64-bit mode. */
#undef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE (TARGET_ARCH32 ? DBX_DEBUG : DWARF2_DEBUG)
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
-/* We can't use the above definition for the purposes of specs. */
#if defined(HAVE_AS_GDWARF2_DEBUG_FLAG) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
-# if DEFAULT_ARCH32_P
-# define ASM_DEBUG_SPEC "%{gdwarf-2*:--gdwarf2}%{!gdwarf-2*:%{g*:--gstabs}}"
-# else
-# define ASM_DEBUG_SPEC "%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}"
-# endif
+# define ASM_DEBUG_SPEC "%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}"
#endif
diff --git a/contrib/gcc/config/sparc/sol2-gas-bi.h b/contrib/gcc/config/sparc/sol2-gas-bi.h
index 0b6cb618d36a..88b3954f8203 100644
--- a/contrib/gcc/config/sparc/sol2-gas-bi.h
+++ b/contrib/gcc/config/sparc/sol2-gas-bi.h
@@ -1,5 +1,5 @@
-/* Definitions of target machine for GNU compiler, for bi-arch SPARC
+/* Definitions of target machine for GCC, for bi-arch SPARC
running Solaris 2 using the GNU assembler. */
-#undef AS_SPARC64_FLAG
-#define AS_SPARC64_FLAG "-64 -Av9"
+#undef AS_SPARC64_FLAG
+#define AS_SPARC64_FLAG "-TSO -64 -Av9"
diff --git a/contrib/gcc/config/sparc/sol2-gld-bi.h b/contrib/gcc/config/sparc/sol2-gld-bi.h
index 81a1ff2395d1..aa9a40bdfcb7 100644
--- a/contrib/gcc/config/sparc/sol2-gld-bi.h
+++ b/contrib/gcc/config/sparc/sol2-gld-bi.h
@@ -1,9 +1,34 @@
-/* Definitions of target machine for GNU compiler, for bi-arch SPARC
+/* Definitions of target machine for GCC, for bi-arch SPARC
running Solaris 2 using the GNU linker. */
+#undef LINK_ARCH32_SPEC
+#define LINK_ARCH32_SPEC \
+ LINK_ARCH32_SPEC_BASE "%{!static: -rpath-link %R/usr/lib}"
+
+#undef LINK_ARCH64_SPEC
+#define LINK_ARCH64_SPEC \
+ LINK_ARCH64_SPEC_BASE "%{!static: -rpath-link %R/usr/lib/sparcv9}"
+
#undef LINK_ARCH_SPEC
+#if DISABLE_MULTILIB
+#if DEFAULT_ARCH32_P
#define LINK_ARCH_SPEC "\
%{m32:-m elf32_sparc %(link_arch32)} \
+%{m64:%edoes not support multilib} \
+%{!m32:%{!m64:%(link_arch_default)}} \
+"
+#else
+#define LINK_ARCH_SPEC "\
+%{m32:%edoes not support multilib} \
%{m64:-m elf64_sparc %(link_arch64)} \
%{!m32:%{!m64:%(link_arch_default)}} \
"
+#endif
+#else
+#define LINK_ARCH_SPEC "\
+%{m32:-m elf32_sparc %(link_arch32)} \
+%{m64:-m elf64_sparc %(link_arch64)} \
+%{!m32:%{!m64:%(link_arch_default)}} \
+"
+#endif
+
diff --git a/contrib/gcc/config/sparc/sol2-gld.h b/contrib/gcc/config/sparc/sol2-gld.h
index 76e034e46f1e..eb422cb8667b 100644
--- a/contrib/gcc/config/sparc/sol2-gld.h
+++ b/contrib/gcc/config/sparc/sol2-gld.h
@@ -1,6 +1,9 @@
-/* Definitions of target machine for GNU compiler, for SPARC running Solaris 2
+/* Definitions of target machine for GCC, for SPARC running Solaris 2
using the GNU linker. */
/* Undefine this so that attribute((init_priority)) works. */
#undef CTORS_SECTION_ASM_OP
#undef DTORS_SECTION_ASM_OP
+
+#undef SUPPORTS_INIT_PRIORITY
+#define SUPPORTS_INIT_PRIORITY 1
diff --git a/contrib/gcc/config/sparc/sol2.h b/contrib/gcc/config/sparc/sol2.h
index 3026e405f61c..cbf914e6b7aa 100644
--- a/contrib/gcc/config/sparc/sol2.h
+++ b/contrib/gcc/config/sparc/sol2.h
@@ -1,31 +1,28 @@
-/* Definitions of target machine for GNU compiler, for SPARC running Solaris 2
- Copyright 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+/* Definitions of target machine for GCC, for SPARC running Solaris 2
+ Copyright 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@netcom.com).
Additional changes by David V. Henkel-Wallace (gumby@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Supposedly the same as vanilla sparc svr4, except for the stuff below: */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc"
-
/* This is here rather than in sparc.h because it's not known what
other assemblers will accept. */
@@ -39,11 +36,16 @@ Boston, MA 02111-1307, USA. */
#define ASM_CPU_DEFAULT_SPEC "-xarch=v8plusa"
#endif
+#if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc3
+#undef ASM_CPU_DEFAULT_SPEC
+#define ASM_CPU_DEFAULT_SPEC "-xarch=v8plusb"
+#endif
+
#undef ASM_CPU_SPEC
#define ASM_CPU_SPEC "\
-%{mcpu=v8plus:-xarch=v8plus} \
%{mcpu=v9:-xarch=v8plus} \
%{mcpu=ultrasparc:-xarch=v8plusa} \
+%{mcpu=ultrasparc3:-xarch=v8plusb} \
%{!mcpu*:%(asm_cpu_default)} \
"
@@ -63,18 +65,11 @@ Boston, MA 02111-1307, USA. */
/* The Solaris 2 assembler uses .skip, not .zero, so put this back. */
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.skip %u\n", (SIZE))
+ fprintf (FILE, "\t.skip %u\n", (int)(SIZE))
#undef LOCAL_LABEL_PREFIX
#define LOCAL_LABEL_PREFIX "."
-/* This is how to output a definition of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".L%s%d:\n", PREFIX, NUM)
-
/* This is how to output a reference to an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
@@ -91,6 +86,33 @@ Boston, MA 02111-1307, USA. */
#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
sprintf ((LABEL), "*.L%s%ld", (PREFIX), (long)(NUM))
+/* The native TLS-enabled assembler requires the directive #tls_object
+ to be put on objects in TLS sections (as of v7.1). This is not
+ required by the GNU assembler but supported on SPARC. */
+#undef ASM_DECLARE_OBJECT_NAME
+#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
+ do \
+ { \
+ HOST_WIDE_INT size; \
+ \
+ if (DECL_THREAD_LOCAL (DECL)) \
+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "tls_object"); \
+ else \
+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \
+ \
+ size_directive_output = 0; \
+ if (!flag_inhibit_size_directive \
+ && (DECL) && DECL_SIZE (DECL)) \
+ { \
+ size_directive_output = 1; \
+ size = int_size_in_bytes (TREE_TYPE (DECL)); \
+ ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size); \
+ } \
+ \
+ ASM_OUTPUT_LABEL (FILE, NAME); \
+ } \
+ while (0)
+
#undef ENDFILE_SPEC
@@ -108,6 +130,10 @@ Boston, MA 02111-1307, USA. */
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
((flag_pic || GLOBAL) ? DW_EH_PE_aligned : DW_EH_PE_absptr)
#endif
+
+/* The Solaris linker doesn't understand constructor priorities. */
+#undef SUPPORTS_INIT_PRIORITY
+#define SUPPORTS_INIT_PRIORITY 0
/* ??? This does not work in SunOS 4.x, so it is not enabled in sparc.h.
Instead, it is enabled here, because it does work under Solaris. */
@@ -118,28 +144,20 @@ Boston, MA 02111-1307, USA. */
/* But indicate that it isn't supported by the hardware. */
#define WIDEST_HARDWARE_FP_SIZE 64
-#define MULDI3_LIBCALL "__mul64"
-#define DIVDI3_LIBCALL "__div64"
-#define UDIVDI3_LIBCALL "__udiv64"
-#define MODDI3_LIBCALL "__rem64"
-#define UMODDI3_LIBCALL "__urem64"
-
/* Solaris's _Qp_* library routine implementation clobbers the output
memory before the inputs are fully consumed. */
#undef TARGET_BUGGY_QP_LIB
#define TARGET_BUGGY_QP_LIB 1
-#undef INIT_SUBTARGET_OPTABS
-#define INIT_SUBTARGET_OPTABS \
- fixsfdi_libfunc \
- = init_one_libfunc (TARGET_ARCH64 ? "__ftol" : "__ftoll"); \
- fixunssfdi_libfunc \
- = init_one_libfunc (TARGET_ARCH64 ? "__ftoul" : "__ftoull"); \
- fixdfdi_libfunc \
- = init_one_libfunc (TARGET_ARCH64 ? "__dtol" : "__dtoll"); \
- fixunsdfdi_libfunc \
- = init_one_libfunc (TARGET_ARCH64 ? "__dtoul" : "__dtoull")
+#undef SUN_CONVERSION_LIBFUNCS
+#define SUN_CONVERSION_LIBFUNCS 1
+
+#undef DITF_CONVERSION_LIBFUNCS
+#define DITF_CONVERSION_LIBFUNCS 1
+
+#undef SUN_INTEGER_MULTIPLY_64
+#define SUN_INTEGER_MULTIPLY_64 1
/* Solaris allows 64 bit out and global registers in 32 bit mode.
sparc_override_options will disable V8+ if not generating V9 code. */
diff --git a/contrib/gcc/config/sparc/sol26-sld.h b/contrib/gcc/config/sparc/sol26-sld.h
index 74b54335011c..2e7fed9424c8 100644
--- a/contrib/gcc/config/sparc/sol26-sld.h
+++ b/contrib/gcc/config/sparc/sol26-sld.h
@@ -1,6 +1,5 @@
-/* Up through Solaris 2.6, the system linker does not work with DWARF
- or DWARF2, since it does not have working support for relocations
- to unaligned data. */
+/* Up through Solaris 2.6, the system linker does not work with DWARF2
+ since it does not have working support for relocations to unaligned
+ data. */
-#undef DWARF_DEBUGGING_INFO
#undef DWARF2_DEBUGGING_INFO
diff --git a/contrib/gcc/config/sparc/sp64-aout.h b/contrib/gcc/config/sparc/sp64-aout.h
index 1af9dea39a25..376cfa883e96 100644
--- a/contrib/gcc/config/sparc/sp64-aout.h
+++ b/contrib/gcc/config/sparc/sp64-aout.h
@@ -1,21 +1,21 @@
-/* Definitions of target machine for GNU compiler, for SPARC64, a.out.
+/* Definitions of target machine for GCC, for SPARC64, a.out.
Copyright (C) 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
Contributed by Doug Evans, dje@cygnus.com.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/sparc/sp64-elf.h b/contrib/gcc/config/sparc/sp64-elf.h
index 18187dc64fdf..650c3ff907be 100644
--- a/contrib/gcc/config/sparc/sp64-elf.h
+++ b/contrib/gcc/config/sparc/sp64-elf.h
@@ -1,22 +1,22 @@
-/* Definitions of target machine for GNU compiler, for SPARC64, ELF.
+/* Definitions of target machine for GCC, for SPARC64, ELF.
Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000
Free Software Foundation, Inc.
Contributed by Doug Evans, dje@cygnus.com.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -38,8 +38,14 @@ Boston, MA 02111-1307, USA. */
#undef SPARC_DEFAULT_CMODEL
#define SPARC_DEFAULT_CMODEL CM_EMBMEDANY
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dsparc -D__ELF__ -Acpu=sparc -Amachine=sparc"
+/* Target OS builtins for config/sol.h. */
+#undef TARGET_SUB_OS_CPP_BUILTINS
+#define TARGET_SUB_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("sparc"); \
+ } \
+ while (0)
/* __svr4__ is used by the C library (FIXME) */
#undef CPP_SUBTARGET_SPEC
@@ -50,7 +56,7 @@ Boston, MA 02111-1307, USA. */
#undef ASM_SPEC
#define ASM_SPEC "\
-%{v:-V} -s %{fpic:-K PIC} %{fPIC:-K PIC} \
+%{v:-V} -s %{fpic|fPIC|fpie|fPIE:-K PIC} \
%{mlittle-endian:-EL} \
%(asm_cpu) %(asm_arch) \
"
diff --git a/contrib/gcc/config/sparc/sp86x-elf.h b/contrib/gcc/config/sparc/sp86x-elf.h
index cb7e8c3f203e..593400d0dd2e 100644
--- a/contrib/gcc/config/sparc/sp86x-elf.h
+++ b/contrib/gcc/config/sparc/sp86x-elf.h
@@ -1,30 +1,34 @@
-/* Definitions of target machine for GNU compiler, for sparclite 86x w/o FPU.
+/* Definitions of target machine for GCC, for sparclite 86x w/o FPU.
Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
Contributed by Stan Cox (scox@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-D__sparc__ -D__sparclite86x__ -Acpu=sparc -Amachine=sparc"
+#undef TARGET_SUB_OS_CPP_BUILTINS
+#define TARGET_SUB_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("__sparclite86x__"); \
+ } \
+ while (0)
/* Default to dwarf2 in ELF. */
-#define DWARF_DEBUGGING_INFO 1
#define DWARF2_DEBUGGING_INFO 1
#undef PREFERRED_DEBUGGING_TYPE
@@ -41,9 +45,8 @@ Boston, MA 02111-1307, USA. */
#undef ASM_SPEC
#define ASM_SPEC "%{v:-V} %{mlittle-endian-data:--little-endian-data} %(asm_cpu)"
-/* US Software GOFAST library support. */
-#undef INIT_SUBTARGET_OPTABS
-#define INIT_SUBTARGET_OPTABS INIT_GOFAST_OPTABS
+/* Enable US Software GOFAST library support. */
+#define US_SOFTWARE_GOFAST
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crti.o%s crtbegin.o%s"
diff --git a/contrib/gcc/config/sparc/sparc-modes.def b/contrib/gcc/config/sparc/sparc-modes.def
index 3ebf9c8660dd..ea2a99d5ae13 100644
--- a/contrib/gcc/config/sparc/sparc-modes.def
+++ b/contrib/gcc/config/sparc/sparc-modes.def
@@ -1,26 +1,29 @@
-/* Definitions of target machine for GNU compiler, for Sun SPARC.
+/* Definitions of target machine for GCC, for Sun SPARC.
Copyright (C) 2002 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
at Cygnus Support.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* 128-bit floating point */
+FLOAT_MODE (TF, 16, ieee_quad_format);
+
/* Add any extra modes needed to represent the condition code.
On the SPARC, we have a "no-overflow" mode which is used when an add or
@@ -34,9 +37,8 @@ Boston, MA 02111-1307, USA. */
CCXmode and CCX_NOOVmode are only used by v9. */
-CC (CCX)
-CC (CC_NOOV)
-CC (CCX_NOOV)
-CC (CCFP)
-CC (CCFPE)
-
+CC_MODE (CCX);
+CC_MODE (CC_NOOV);
+CC_MODE (CCX_NOOV);
+CC_MODE (CCFP);
+CC_MODE (CCFPE);
diff --git a/contrib/gcc/config/sparc/sparc-protos.h b/contrib/gcc/config/sparc/sparc-protos.h
index 0aa6e58f7da9..3216f38698d5 100644
--- a/contrib/gcc/config/sparc/sparc-protos.h
+++ b/contrib/gcc/config/sparc/sparc-protos.h
@@ -1,23 +1,23 @@
-/* Prototypes of target machine for GNU compiler, for Sun SPARC.
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+/* Prototypes of target machine for SPARC.
+ Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
- 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
+ 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
at Cygnus Support.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -27,100 +27,101 @@ Boston, MA 02111-1307, USA. */
extern bool sparc_emitting_epilogue;
#ifdef TREE_CODE
-extern struct rtx_def *function_value PARAMS ((tree, enum machine_mode, int));
-extern void function_arg_advance PARAMS ((CUMULATIVE_ARGS *,
- enum machine_mode, tree, int));
-extern struct rtx_def *function_arg PARAMS ((const CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int, int));
-extern int function_arg_partial_nregs PARAMS ((const CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-extern int function_arg_pass_by_reference PARAMS ((const CUMULATIVE_ARGS *,
- enum machine_mode,
- tree, int));
-extern struct rtx_def *sparc_builtin_saveregs PARAMS ((void));
+extern struct rtx_def *function_value (tree, enum machine_mode, int);
+extern void function_arg_advance (CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern struct rtx_def *function_arg (const CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int, int);
+extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern int function_arg_pass_by_reference (const CUMULATIVE_ARGS *,
+ enum machine_mode, tree, int);
+extern struct rtx_def *sparc_builtin_saveregs (void);
#ifdef RTX_CODE
-extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx, int));
-extern void sparc_va_start PARAMS ((tree, rtx));
+extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
+extern void sparc_va_start (tree, rtx);
#endif
-extern struct rtx_def *sparc_va_arg PARAMS ((tree, tree));
-extern unsigned long sparc_type_code PARAMS ((tree));
+extern struct rtx_def *sparc_va_arg (tree, tree);
+extern unsigned long sparc_type_code (tree);
#ifdef ARGS_SIZE_RTX
/* expr.h defines ARGS_SIZE_RTX and `enum direction' */
-extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree));
+extern enum direction function_arg_padding (enum machine_mode, tree);
#endif /* ARGS_SIZE_RTX */
#endif /* TREE_CODE */
-extern void load_pic_register PARAMS ((void));
-extern void order_regs_for_local_alloc PARAMS ((void));
-extern int compute_frame_size PARAMS ((int, int));
-extern int check_pic PARAMS ((int));
-extern int short_branch PARAMS ((int, int));
-extern int sparc_flat_epilogue_delay_slots PARAMS ((void));
-extern unsigned long sparc_flat_compute_frame_size PARAMS ((int));
-extern void sparc_profile_hook PARAMS ((int));
-extern void sparc_override_options PARAMS ((void));
-extern int leaf_return_peephole_ok PARAMS ((void));
-extern void sparc_output_scratch_registers PARAMS ((FILE *));
-extern void sparc_flat_save_restore PARAMS ((FILE *, const char *,
- unsigned int, unsigned long,
- unsigned long, const char *,
- const char *, unsigned long));
+extern void load_pic_register (void);
+extern void order_regs_for_local_alloc (void);
+extern HOST_WIDE_INT compute_frame_size (HOST_WIDE_INT, int);
+extern int check_pic (int);
+extern int short_branch (int, int);
+extern int sparc_flat_epilogue_delay_slots (void);
+extern HOST_WIDE_INT sparc_flat_compute_frame_size (HOST_WIDE_INT);
+extern void sparc_profile_hook (int);
+extern void sparc_override_options (void);
+extern int leaf_return_peephole_ok (void);
+extern void sparc_output_scratch_registers (FILE *);
#ifdef RTX_CODE
-extern enum machine_mode select_cc_mode PARAMS ((enum rtx_code, rtx, rtx));
+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 PARAMS ((enum rtx_code code, rtx, rtx));
-extern void sparc_emit_float_lib_cmp PARAMS ((rtx, rtx, enum rtx_code));
-extern void sparc_emit_floatunsdi PARAMS ((rtx [2]));
-extern void emit_tfmode_binop PARAMS ((enum rtx_code, rtx *));
-extern void emit_tfmode_unop PARAMS ((enum rtx_code, rtx *));
-extern void emit_tfmode_cvt PARAMS ((enum rtx_code, rtx *));
+extern rtx gen_compare_reg (enum rtx_code code, rtx, rtx);
+extern void sparc_emit_float_lib_cmp (rtx, rtx, enum rtx_code);
+extern void sparc_emit_floatunsdi (rtx [2]);
+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 PARAMS ((enum rtx_code, rtx *));
-extern void sparc_initialize_trampoline PARAMS ((rtx, rtx, rtx));
-extern void sparc64_initialize_trampoline PARAMS ((rtx, rtx, rtx));
-extern rtx legitimize_pic_address PARAMS ((rtx, enum machine_mode, rtx));
-extern void sparc_defer_case_vector PARAMS ((rtx, rtx, int));
-extern void sparc_emit_set_const32 PARAMS ((rtx, rtx));
-extern void sparc_emit_set_const64 PARAMS ((rtx, rtx));
-extern void sparc_emit_set_symbolic_const64 PARAMS ((rtx, rtx, rtx));
-extern int sparc_splitdi_legitimate PARAMS ((rtx, rtx));
-extern int sparc_absnegfloat_split_legitimate PARAMS ((rtx, rtx));
-extern char *output_cbranch PARAMS ((rtx, rtx, int, int, int, int, rtx));
-extern const char *output_sibcall PARAMS ((rtx, rtx));
-extern char *output_v9branch PARAMS ((rtx, rtx, int, int, int, int, int,
- rtx));
-extern void emit_v9_brxx_insn PARAMS ((enum rtx_code, rtx, rtx));
-extern void print_operand PARAMS ((FILE *, rtx, int));
-extern int mems_ok_for_ldd_peep PARAMS ((rtx, rtx, rtx));
-extern int arith_double_4096_operand PARAMS ((rtx, enum machine_mode));
-extern int arith_4096_operand PARAMS ((rtx, enum machine_mode));
-extern int zero_operand PARAMS ((rtx, enum machine_mode));
-extern int fp_zero_operand PARAMS ((rtx, enum machine_mode));
-extern int reg_or_0_operand PARAMS ((rtx, enum machine_mode));
-extern int empty_delay_slot PARAMS ((rtx));
-extern int eligible_for_epilogue_delay PARAMS ((rtx, int));
-extern int eligible_for_sibcall_delay PARAMS ((rtx));
-extern int emit_move_sequence PARAMS ((rtx, enum machine_mode));
-extern int fp_sethi_p PARAMS ((rtx));
-extern int fp_mov_p PARAMS ((rtx));
-extern int fp_high_losum_p PARAMS ((rtx));
-extern int mem_min_alignment PARAMS ((rtx, int));
-extern int pic_address_needs_scratch PARAMS ((rtx));
-extern int reg_unused_after PARAMS ((rtx, rtx));
-extern int register_ok_for_ldd PARAMS ((rtx));
-extern int registers_ok_for_ldd_peep PARAMS ((rtx, rtx));
-extern int sparc_flat_eligible_for_epilogue_delay PARAMS ((rtx, int));
-extern int v9_regcmp_p PARAMS ((enum rtx_code));
-extern char *sparc_v8plus_shift PARAMS ((rtx *, rtx, const char *));
+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 rtx legitimize_address (rtx, rtx, enum machine_mode);
+extern void sparc_defer_case_vector (rtx, rtx, int);
+extern void sparc_emit_set_const32 (rtx, rtx);
+extern void sparc_emit_set_const64 (rtx, rtx);
+extern void sparc_emit_set_symbolic_const64 (rtx, rtx, rtx);
+extern int sparc_splitdi_legitimate (rtx, rtx);
+extern int sparc_absnegfloat_split_legitimate (rtx, rtx);
+extern const char *output_ubranch (rtx, int, rtx);
+extern char *output_cbranch (rtx, rtx, int, int, int, int, rtx);
+extern const char *output_sibcall (rtx, rtx);
+extern char *output_v9branch (rtx, rtx, int, int, int, int, int, rtx);
+extern void emit_v9_brxx_insn (enum rtx_code, rtx, 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);
+extern int arith_4096_operand (rtx, enum machine_mode);
+extern int zero_operand (rtx, enum machine_mode);
+extern int fp_zero_operand (rtx, enum machine_mode);
+extern int reg_or_0_operand (rtx, enum machine_mode);
+extern int tls_symbolic_operand (rtx);
+extern int empty_delay_slot (rtx);
+extern int eligible_for_epilogue_delay (rtx, int);
+extern int eligible_for_sibcall_delay (rtx);
+extern int tls_call_delay (rtx);
+extern int emit_move_sequence (rtx, enum machine_mode);
+extern int fp_sethi_p (rtx);
+extern int fp_mov_p (rtx);
+extern int fp_high_losum_p (rtx);
+extern int mem_min_alignment (rtx, int);
+extern int pic_address_needs_scratch (rtx);
+extern int reg_unused_after (rtx, rtx);
+extern int register_ok_for_ldd (rtx);
+extern int registers_ok_for_ldd_peep (rtx, rtx);
+extern int sparc_flat_eligible_for_epilogue_delay (rtx, int);
+extern int v9_regcmp_p (enum rtx_code);
+extern char *sparc_v8plus_shift (rtx *, rtx, const char *);
/* Function used for V8+ code generation. Returns 1 if the high
32 bits of REG are 0 before INSN. */
-extern int sparc_check_64 PARAMS ((rtx, rtx));
-extern rtx gen_df_reg PARAMS ((rtx, int));
-extern int sparc_extra_constraint_check PARAMS ((rtx, int, int));
-extern int sparc_rtx_costs PARAMS ((rtx, enum rtx_code, enum rtx_code));
+extern int sparc_check_64 (rtx, rtx);
+extern rtx gen_df_reg (rtx, int);
+extern int sparc_extra_constraint_check (rtx, int, int);
+extern void sparc_output_dwarf_dtprel (FILE*, int, rtx);
#endif /* RTX_CODE */
#endif /* __SPARC_PROTOS_H__ */
diff --git a/contrib/gcc/config/sparc/sparc.c b/contrib/gcc/config/sparc/sparc.c
index 79022b4b85dc..c95937067163 100644
--- a/contrib/gcc/config/sparc/sparc.c
+++ b/contrib/gcc/config/sparc/sparc.c
@@ -1,29 +1,31 @@
-/* Subroutines for insn-output.c for Sun SPARC.
+/* Subroutines for insn-output.c for SPARC.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
- 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
+ 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
at Cygnus Support.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "regs.h"
@@ -37,7 +39,6 @@ Boston, MA 02111-1307, USA. */
#include "function.h"
#include "expr.h"
#include "optabs.h"
-#include "libfuncs.h"
#include "recog.h"
#include "toplev.h"
#include "ggc.h"
@@ -45,6 +46,7 @@ Boston, MA 02111-1307, USA. */
#include "debug.h"
#include "target.h"
#include "target-def.h"
+#include "cfglayout.h"
/* 1 if the caller has placed an "unimp" insn immediately after the call.
This is used in v8 code when calling a function that returns a structure.
@@ -65,8 +67,8 @@ Boston, MA 02111-1307, USA. */
scheduling (to see what can go in a delay slot).
APPARENT_FSIZE is the size of the stack less the register save area and less
the outgoing argument area. It is used when saving call preserved regs. */
-static int apparent_fsize;
-static int actual_fsize;
+static HOST_WIDE_INT apparent_fsize;
+static HOST_WIDE_INT actual_fsize;
/* Number of live general or floating point registers needed to be
saved (as 4-byte quantities). */
@@ -117,67 +119,81 @@ char sparc_leaf_regs[] =
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1};
+struct machine_function GTY(())
+{
+ /* Some local-dynamic TLS symbol name. */
+ const char *some_ld_name;
+};
+
/* Name of where we pretend to think the frame pointer points.
Normally, this is "%fp", but if we are in a leaf procedure,
this is "%sp+something". We record "something" separately as it may be
too big for reg+constant addressing. */
static const char *frame_base_name;
-static int frame_base_offset;
-
-static void sparc_init_modes PARAMS ((void));
-static int save_regs PARAMS ((FILE *, int, int, const char *,
- int, int, int));
-static int restore_regs PARAMS ((FILE *, int, int, const char *, int, int));
-static void build_big_number PARAMS ((FILE *, int, const char *));
-static int function_arg_slotno PARAMS ((const CUMULATIVE_ARGS *,
- enum machine_mode, tree, int, int,
- int *, int *));
-
-static int supersparc_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static int hypersparc_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-
-static void sparc_output_addr_vec PARAMS ((rtx));
-static void sparc_output_addr_diff_vec PARAMS ((rtx));
-static void sparc_output_deferred_case_vectors PARAMS ((void));
-static int check_return_regs PARAMS ((rtx));
-static int epilogue_renumber PARAMS ((rtx *, int));
-static bool sparc_assemble_integer PARAMS ((rtx, unsigned int, int));
-static int set_extends PARAMS ((rtx));
-static void output_restore_regs PARAMS ((FILE *, int));
-static void sparc_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void sparc_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-static void sparc_flat_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
-static void sparc_flat_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
-static void sparc_nonflat_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT,
- int));
-static void sparc_nonflat_function_prologue PARAMS ((FILE *, HOST_WIDE_INT,
- int));
+static HOST_WIDE_INT frame_base_offset;
+
+static void sparc_init_modes (void);
+static int save_regs (FILE *, int, int, const char *, int, int, HOST_WIDE_INT);
+static int restore_regs (FILE *, int, int, const char *, int, int);
+static void build_big_number (FILE *, HOST_WIDE_INT, const char *);
+static void scan_record_type (tree, int *, int *, int *);
+static int function_arg_slotno (const CUMULATIVE_ARGS *, enum machine_mode,
+ tree, int, int, int *, int *);
+
+static int supersparc_adjust_cost (rtx, rtx, rtx, int);
+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 int check_return_regs (rtx);
+static int epilogue_renumber (rtx *, int);
+static bool sparc_assemble_integer (rtx, unsigned int, int);
+static int set_extends (rtx);
+static void output_restore_regs (FILE *, int);
+static void sparc_output_function_prologue (FILE *, HOST_WIDE_INT);
+static void sparc_output_function_epilogue (FILE *, HOST_WIDE_INT);
+static void sparc_flat_function_epilogue (FILE *, HOST_WIDE_INT);
+static void sparc_flat_function_prologue (FILE *, HOST_WIDE_INT);
+static void sparc_flat_save_restore (FILE *, const char *, int,
+ unsigned long, unsigned long,
+ const char *, const char *,
+ HOST_WIDE_INT);
+static void sparc_nonflat_function_epilogue (FILE *, HOST_WIDE_INT, int);
+static void sparc_nonflat_function_prologue (FILE *, HOST_WIDE_INT, int);
#ifdef OBJECT_FORMAT_ELF
-static void sparc_elf_asm_named_section PARAMS ((const char *, unsigned int));
+static void sparc_elf_asm_named_section (const char *, unsigned int);
#endif
-static void sparc_aout_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT))
+static void sparc_aout_select_section (tree, int, unsigned HOST_WIDE_INT)
ATTRIBUTE_UNUSED;
-static void sparc_aout_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT))
+static void sparc_aout_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT)
ATTRIBUTE_UNUSED;
-static int sparc_adjust_cost PARAMS ((rtx, rtx, rtx, int));
-static int sparc_issue_rate PARAMS ((void));
-static void sparc_sched_init PARAMS ((FILE *, int, int));
-static int sparc_use_dfa_pipeline_interface PARAMS ((void));
-static int sparc_use_sched_lookahead PARAMS ((void));
-
-static void emit_soft_tfmode_libcall PARAMS ((const char *, int, rtx *));
-static void emit_soft_tfmode_binop PARAMS ((enum rtx_code, rtx *));
-static void emit_soft_tfmode_unop PARAMS ((enum rtx_code, rtx *));
-static void emit_soft_tfmode_cvt PARAMS ((enum rtx_code, rtx *));
-static void emit_hard_tfmode_operation PARAMS ((enum rtx_code, rtx *));
-
-static void sparc_encode_section_info PARAMS ((tree, int));
-static void sparc_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
- HOST_WIDE_INT, tree));
+static int sparc_adjust_cost (rtx, rtx, rtx, int);
+static int sparc_issue_rate (void);
+static void sparc_sched_init (FILE *, int, int);
+static int sparc_use_dfa_pipeline_interface (void);
+static int sparc_use_sched_lookahead (void);
+
+static void emit_soft_tfmode_libcall (const char *, int, rtx *);
+static void emit_soft_tfmode_binop (enum rtx_code, rtx *);
+static void emit_soft_tfmode_unop (enum rtx_code, rtx *);
+static void emit_soft_tfmode_cvt (enum rtx_code, rtx *);
+static void emit_hard_tfmode_operation (enum rtx_code, rtx *);
+
+static bool sparc_function_ok_for_sibcall (tree, tree);
+static void sparc_init_libfuncs (void);
+static void sparc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
+ HOST_WIDE_INT, tree);
+static struct machine_function * sparc_init_machine_status (void);
+static bool sparc_cannot_force_const_mem (rtx);
+static rtx sparc_tls_get_addr (void);
+static rtx sparc_tls_got (void);
+static const char *get_some_local_dynamic_name (void);
+static int get_some_local_dynamic_name_1 (rtx *, void *);
+static bool sparc_rtx_costs (rtx, int, int, int *);
/* Option handling. */
@@ -238,21 +254,36 @@ enum processor_type sparc_cpu;
#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD sparc_use_sched_lookahead
-#undef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO sparc_encode_section_info
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL sparc_function_ok_for_sibcall
+
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS sparc_init_libfuncs
+
+#ifdef HAVE_AS_TLS
+#undef TARGET_HAVE_TLS
+#define TARGET_HAVE_TLS true
+#endif
+#undef TARGET_CANNOT_FORCE_CONST_MEM
+#define TARGET_CANNOT_FORCE_CONST_MEM sparc_cannot_force_const_mem
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK sparc_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#undef TARGET_RTX_COSTS
+#define TARGET_RTX_COSTS sparc_rtx_costs
+#undef TARGET_ADDRESS_COST
+#define TARGET_ADDRESS_COST hook_int_rtx_0
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Validate and override various options, and do some machine dependent
initialization. */
void
-sparc_override_options ()
+sparc_override_options (void)
{
static struct code_model {
const char *const name;
@@ -444,6 +475,9 @@ sparc_override_options ()
/* Do various machine dependent initializations. */
sparc_init_modes ();
+
+ /* Set up function hooks. */
+ init_machine_status = sparc_init_machine_status;
}
/* Miscellaneous utilities. */
@@ -452,8 +486,7 @@ sparc_override_options ()
or branch on register contents instructions. */
int
-v9_regcmp_p (code)
- enum rtx_code code;
+v9_regcmp_p (enum rtx_code code)
{
return (code == EQ || code == NE || code == GE || code == LT
|| code == LE || code == GT);
@@ -466,9 +499,7 @@ v9_regcmp_p (code)
or const0_rtx. */
int
-reg_or_0_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+reg_or_0_operand (rtx op, enum machine_mode mode)
{
if (register_operand (op, mode))
return 1;
@@ -486,9 +517,7 @@ reg_or_0_operand (op, mode)
/* Return nonzero only if OP is const1_rtx. */
int
-const1_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+const1_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return op == const1_rtx;
}
@@ -496,9 +525,7 @@ const1_operand (op, mode)
/* Nonzero if OP is a floating point value with value 0.0. */
int
-fp_zero_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fp_zero_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE_CLASS (GET_MODE (op)) != MODE_FLOAT)
return 0;
@@ -508,9 +535,7 @@ fp_zero_operand (op, mode)
/* Nonzero if OP is a register operand in floating point register. */
int
-fp_register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fp_register_operand (rtx op, enum machine_mode mode)
{
if (! register_operand (op, mode))
return 0;
@@ -524,8 +549,7 @@ fp_register_operand (op, mode)
sethi instruction. */
int
-fp_sethi_p (op)
- rtx op;
+fp_sethi_p (rtx op)
{
if (GET_CODE (op) == CONST_DOUBLE)
{
@@ -549,8 +573,7 @@ fp_sethi_p (op)
mov instruction. */
int
-fp_mov_p (op)
- rtx op;
+fp_mov_p (rtx op)
{
if (GET_CODE (op) == CONST_DOUBLE)
{
@@ -574,8 +597,7 @@ fp_mov_p (op)
instruction sequence. */
int
-fp_high_losum_p (op)
- rtx op;
+fp_high_losum_p (rtx op)
{
/* The constraints calling this should only be in
SFmode move insns, so any constant which cannot
@@ -601,9 +623,7 @@ fp_high_losum_p (op)
/* Nonzero if OP is an integer register. */
int
-intreg_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+intreg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (register_operand (op, SImode)
|| (TARGET_ARCH64 && register_operand (op, DImode)));
@@ -612,9 +632,7 @@ intreg_operand (op, mode)
/* Nonzero if OP is a floating point condition code register. */
int
-fcc_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fcc_reg_operand (rtx op, enum machine_mode mode)
{
/* This can happen when recog is called from combine. Op may be a MEM.
Fail instead of calling abort in this case. */
@@ -639,9 +657,7 @@ fcc_reg_operand (op, mode)
/* Nonzero if OP is a floating point condition code fcc0 register. */
int
-fcc0_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+fcc0_reg_operand (rtx op, enum machine_mode mode)
{
/* This can happen when recog is called from combine. Op may be a MEM.
Fail instead of calling abort in this case. */
@@ -660,9 +676,7 @@ fcc0_reg_operand (op, mode)
/* Nonzero if OP is an integer or floating point condition code register. */
int
-icc_or_fcc_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+icc_or_fcc_reg_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) == REG && REGNO (op) == SPARC_ICC_REG)
{
@@ -679,9 +693,7 @@ icc_or_fcc_reg_operand (op, mode)
/* Nonzero if OP can appear as the dest of a RESTORE insn. */
int
-restore_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+restore_operand (rtx op, enum machine_mode mode)
{
return (GET_CODE (op) == REG && GET_MODE (op) == mode
&& (REGNO (op) < 8 || (REGNO (op) >= 24 && REGNO (op) < 32)));
@@ -691,9 +703,7 @@ restore_operand (op, mode)
memory address. */
int
-call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+call_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != MEM)
abort ();
@@ -702,20 +712,51 @@ call_operand (op, mode)
}
int
-call_operand_address (op, mode)
- rtx op;
- enum machine_mode mode;
+call_operand_address (rtx op, enum machine_mode mode)
{
return (symbolic_operand (op, mode) || memory_address_p (Pmode, op));
}
+/* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
+ otherwise return 0. */
+
+int
+tls_symbolic_operand (rtx op)
+{
+ if (GET_CODE (op) != SYMBOL_REF)
+ return 0;
+ return SYMBOL_REF_TLS_MODEL (op);
+}
+
+int
+tgd_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return tls_symbolic_operand (op) == TLS_MODEL_GLOBAL_DYNAMIC;
+}
+
+int
+tld_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return tls_symbolic_operand (op) == TLS_MODEL_LOCAL_DYNAMIC;
+}
+
+int
+tie_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return tls_symbolic_operand (op) == TLS_MODEL_INITIAL_EXEC;
+}
+
+int
+tle_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return tls_symbolic_operand (op) == TLS_MODEL_LOCAL_EXEC;
+}
+
/* Returns 1 if OP is either a symbol reference or a sum of a symbol
reference and a constant. */
int
-symbolic_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+symbolic_operand (register rtx op, enum machine_mode mode)
{
enum machine_mode omode = GET_MODE (op);
@@ -725,12 +766,15 @@ symbolic_operand (op, mode)
switch (GET_CODE (op))
{
case SYMBOL_REF:
+ return !SYMBOL_REF_TLS_MODEL (op);
+
case LABEL_REF:
return 1;
case CONST:
op = XEXP (op, 0);
- return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ return (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+ && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0)))
|| GET_CODE (XEXP (op, 0)) == LABEL_REF)
&& GET_CODE (XEXP (op, 1)) == CONST_INT);
@@ -743,25 +787,22 @@ symbolic_operand (op, mode)
operand of mode MODE. */
int
-symbolic_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+symbolic_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == SUBREG)
op = SUBREG_REG (op);
if (GET_CODE (op) != MEM)
return 0;
op = XEXP (op, 0);
- return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
- || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
+ return ((GET_CODE (op) == SYMBOL_REF && !SYMBOL_REF_TLS_MODEL (op))
+ || GET_CODE (op) == CONST || GET_CODE (op) == HIGH
+ || GET_CODE (op) == LABEL_REF);
}
/* Return truth value of statement that OP is a LABEL_REF of mode MODE. */
int
-label_ref_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+label_ref_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != LABEL_REF)
return 0;
@@ -774,9 +815,7 @@ label_ref_operand (op, mode)
in either the medium/low or medium/anywhere code models of sparc64. */
int
-sp64_medium_pic_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+sp64_medium_pic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
/* Check for (const (minus (symbol_ref:GOT)
(const (minus (label) (pc))))). */
@@ -801,14 +840,12 @@ sp64_medium_pic_operand (op, mode)
are accessed with EMBMEDANY_BASE_REG. */
int
-data_segment_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+data_segment_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
case SYMBOL_REF :
- return ! SYMBOL_REF_FLAG (op);
+ return ! SYMBOL_REF_FUNCTION_P (op);
case PLUS :
/* Assume canonical format of symbol + constant.
Fall through. */
@@ -823,16 +860,14 @@ data_segment_operand (op, mode)
This is needed in the medium/anywhere code model on v9. */
int
-text_segment_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+text_segment_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
switch (GET_CODE (op))
{
case LABEL_REF :
return 1;
case SYMBOL_REF :
- return SYMBOL_REF_FLAG (op);
+ return SYMBOL_REF_FUNCTION_P (op);
case PLUS :
/* Assume canonical format of symbol + constant.
Fall through. */
@@ -847,9 +882,7 @@ text_segment_operand (op, mode)
not symbolic. */
int
-reg_or_nonsymb_mem_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
+reg_or_nonsymb_mem_operand (register rtx op, enum machine_mode mode)
{
if (register_operand (op, mode))
return 1;
@@ -861,9 +894,8 @@ reg_or_nonsymb_mem_operand (op, mode)
}
int
-splittable_symbolic_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+splittable_symbolic_memory_operand (rtx op,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != MEM)
return 0;
@@ -873,9 +905,8 @@ splittable_symbolic_memory_operand (op, mode)
}
int
-splittable_immediate_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+splittable_immediate_memory_operand (rtx op,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != MEM)
return 0;
@@ -887,9 +918,7 @@ splittable_immediate_memory_operand (op, mode)
/* Return truth value of whether OP is EQ or NE. */
int
-eq_or_neq (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+eq_or_neq (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
}
@@ -898,9 +927,7 @@ eq_or_neq (op, mode)
or LTU for non-floating-point. We handle those specially. */
int
-normal_comp_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+normal_comp_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
@@ -918,9 +945,7 @@ normal_comp_operator (op, mode)
MATCH_OPERATOR to recognize all the branch insns. */
int
-noov_compare_op (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+noov_compare_op (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
@@ -938,9 +963,7 @@ noov_compare_op (op, mode)
MATCH_OPERATOR to recognize all the branch insns. */
int
-noov_compare64_op (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+noov_compare64_op (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
@@ -960,9 +983,7 @@ noov_compare64_op (op, mode)
conditional move or branch on register contents instructions. */
int
-v9_regcmp_op (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+v9_regcmp_op (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (op);
@@ -975,9 +996,7 @@ v9_regcmp_op (op, mode)
/* Return 1 if this is a SIGN_EXTEND or ZERO_EXTEND operation. */
int
-extend_op (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+extend_op (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND;
}
@@ -987,9 +1006,7 @@ extend_op (op, mode)
because these require CC_NOOVmode, which we handle explicitly. */
int
-cc_arithop (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+cc_arithop (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) == AND
|| GET_CODE (op) == IOR
@@ -1003,9 +1020,7 @@ cc_arithop (op, mode)
complement its second operand and set the condition codes explicitly. */
int
-cc_arithopn (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+cc_arithopn (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
/* XOR is not here because combine canonicalizes (xor (not ...) ...)
and (xor ... (not ...)) to (not (xor ...)). */
@@ -1018,9 +1033,7 @@ cc_arithopn (op, mode)
most 3 address instructions. */
int
-arith_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith_operand (rtx op, enum machine_mode mode)
{
if (register_operand (op, mode))
return 1;
@@ -1032,9 +1045,7 @@ arith_operand (op, mode)
/* Return true if OP is a constant 4096 */
int
-arith_4096_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+arith_4096_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (GET_CODE (op) != CONST_INT)
return 0;
@@ -1045,9 +1056,7 @@ arith_4096_operand (op, mode)
/* Return true if OP is suitable as second operand for add/sub */
int
-arith_add_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith_add_operand (rtx op, enum machine_mode mode)
{
return arith_operand (op, mode) || arith_4096_operand (op, mode);
}
@@ -1056,9 +1065,7 @@ arith_add_operand (op, mode)
immediate field of OR and XOR instructions. Used for 64-bit
constant formation patterns. */
int
-const64_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+const64_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return ((GET_CODE (op) == CONST_INT
&& SPARC_SIMM13_P (INTVAL (op)))
@@ -1074,9 +1081,7 @@ const64_operand (op, mode)
/* The same, but only for sethi instructions. */
int
-const64_high_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+const64_high_operand (rtx op, enum machine_mode mode)
{
return ((GET_CODE (op) == CONST_INT
&& (INTVAL (op) & ~(HOST_WIDE_INT)0x3ff) != 0
@@ -1093,9 +1098,7 @@ const64_high_operand (op, mode)
the movcc instructions. */
int
-arith11_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith11_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT && SPARC_SIMM11_P (INTVAL (op))));
@@ -1106,9 +1109,7 @@ arith11_operand (op, mode)
the movrcc instructions. */
int
-arith10_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith10_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT && SPARC_SIMM10_P (INTVAL (op))));
@@ -1122,9 +1123,7 @@ arith10_operand (op, mode)
for most 3 address instructions. */
int
-arith_double_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith_double_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
|| (GET_CODE (op) == CONST_INT && SMALL_INT (op))
@@ -1144,9 +1143,7 @@ arith_double_operand (op, mode)
/* Return true if OP is a constant 4096 for DImode on ARCH64 */
int
-arith_double_4096_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+arith_double_4096_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (TARGET_ARCH64 &&
((GET_CODE (op) == CONST_INT && INTVAL (op) == 4096) ||
@@ -1158,9 +1155,7 @@ arith_double_4096_operand (op, mode)
/* Return true if OP is suitable as second operand for add/sub in DImode */
int
-arith_double_add_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith_double_add_operand (rtx op, enum machine_mode mode)
{
return arith_double_operand (op, mode) || arith_double_4096_operand (op, mode);
}
@@ -1171,9 +1166,7 @@ arith_double_add_operand (op, mode)
/* ??? Replace with arith11_operand? */
int
-arith11_double_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith11_double_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
|| (GET_CODE (op) == CONST_DOUBLE
@@ -1194,9 +1187,7 @@ arith11_double_operand (op, mode)
/* ??? Replace with arith10_operand? */
int
-arith10_double_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+arith10_double_operand (rtx op, enum machine_mode mode)
{
return (register_operand (op, mode)
|| (GET_CODE (op) == CONST_DOUBLE
@@ -1216,17 +1207,13 @@ arith10_double_operand (op, mode)
which have a 13 bit immediate field. */
int
-small_int (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT && SMALL_INT (op));
}
int
-small_int_or_double (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+small_int_or_double (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return ((GET_CODE (op) == CONST_INT && SMALL_INT (op))
|| (GET_CODE (op) == CONST_DOUBLE
@@ -1239,9 +1226,7 @@ small_int_or_double (op, mode)
interprets the extended result as an unsigned number. */
int
-uns_small_int (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+uns_small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
#if HOST_BITS_PER_WIDE_INT > 32
/* All allowed constants will fit a CONST_INT. */
@@ -1258,18 +1243,14 @@ uns_small_int (op, mode)
}
int
-uns_arith_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+uns_arith_operand (rtx op, enum machine_mode mode)
{
return register_operand (op, mode) || uns_small_int (op, mode);
}
/* Return truth value of statement that OP is a call-clobbered register. */
int
-clobbered_register (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+clobbered_register (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == REG && call_used_regs[REGNO (op)]);
}
@@ -1277,16 +1258,14 @@ clobbered_register (op, mode)
/* Return 1 if OP is a valid operand for the source of a move insn. */
int
-input_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+input_operand (rtx op, enum machine_mode mode)
{
/* If both modes are non-void they must be the same. */
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
return 0;
- /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
- if (GET_CODE (op) == CONST && GET_CODE (XEXP (op, 0)) == CONSTANT_P_RTX)
+ /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and result in 0/1. */
+ if (GET_CODE (op) == CONSTANT_P_RTX)
return 1;
/* Allow any one instruction integer constant, and all CONST_INT
@@ -1357,13 +1336,37 @@ input_operand (op, mode)
return 0;
}
+/* Return 1 if OP is valid for the lhs of a compare insn. */
+
+int
+compare_operand (rtx op, enum machine_mode mode)
+{
+ if (GET_CODE (op) == ZERO_EXTRACT)
+ return (register_operand (XEXP (op, 0), mode)
+ && small_int_or_double (XEXP (op, 1), mode)
+ && small_int_or_double (XEXP (op, 2), mode)
+ /* This matches cmp_zero_extract. */
+ && ((mode == SImode
+ && ((GET_CODE (XEXP (op, 2)) == CONST_INT
+ && INTVAL (XEXP (op, 2)) > 19)
+ || (GET_CODE (XEXP (op, 2)) == CONST_DOUBLE
+ && CONST_DOUBLE_LOW (XEXP (op, 2)) > 19)))
+ /* This matches cmp_zero_extract_sp64. */
+ || (mode == DImode
+ && TARGET_ARCH64
+ && ((GET_CODE (XEXP (op, 2)) == CONST_INT
+ && INTVAL (XEXP (op, 2)) > 51)
+ || (GET_CODE (XEXP (op, 2)) == CONST_DOUBLE
+ && CONST_DOUBLE_LOW (XEXP (op, 2)) > 51)))));
+ else
+ return register_operand (op, mode);
+}
+
/* We know it can't be done in one insn when we get here,
- the movsi expander guarentees this. */
+ the movsi expander guarantees this. */
void
-sparc_emit_set_const32 (op0, op1)
- rtx op0;
- rtx op1;
+sparc_emit_set_const32 (rtx op0, rtx op1)
{
enum machine_mode mode = GET_MODE (op0);
rtx temp;
@@ -1417,21 +1420,25 @@ sparc_emit_set_const32 (op0, op1)
}
-/* SPARC-v9 code-model support. */
+/* Load OP1, a symbolic 64-bit constant, into OP0, a DImode register.
+ If TEMP is non-zero, we are forbidden to use any other scratch
+ registers. Otherwise, we are allowed to generate them as needed.
+
+ Note that TEMP may have TImode if the code model is TARGET_CM_MEDANY
+ or TARGET_CM_EMBMEDANY (see the reload_indi and reload_outdi patterns). */
void
-sparc_emit_set_symbolic_const64 (op0, op1, temp1)
- rtx op0;
- rtx op1;
- rtx temp1;
+sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp)
{
- rtx ti_temp1 = 0;
+ rtx temp1, temp2, temp3, temp4, temp5;
+ rtx ti_temp = 0;
- if (temp1 && GET_MODE (temp1) == TImode)
+ if (temp && GET_MODE (temp) == TImode)
{
- ti_temp1 = temp1;
- temp1 = gen_rtx_REG (DImode, REGNO (temp1));
+ ti_temp = temp;
+ temp = gen_rtx_REG (DImode, REGNO (temp));
}
+ /* SPARC-V9 code-model support. */
switch (sparc_cmodel)
{
case CM_MEDLOW:
@@ -1443,8 +1450,13 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1)
The executable must be in the low 4TB of the virtual address
space.
- sethi %hi(symbol), %temp
- or %temp, %lo(symbol), %reg */
+ sethi %hi(symbol), %temp1
+ or %temp1, %lo(symbol), %reg */
+ if (temp)
+ temp1 = temp; /* op0 is allowed. */
+ else
+ temp1 = gen_reg_rtx (DImode);
+
emit_insn (gen_rtx_SET (VOIDmode, temp1, gen_rtx_HIGH (DImode, op1)));
emit_insn (gen_rtx_SET (VOIDmode, op0, gen_rtx_LO_SUM (DImode, temp1, op1)));
break;
@@ -1462,11 +1474,24 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1)
or %temp1, %m44(symbol), %temp2
sllx %temp2, 12, %temp3
or %temp3, %l44(symbol), %reg */
- emit_insn (gen_seth44 (op0, op1));
- emit_insn (gen_setm44 (op0, op0, op1));
- emit_insn (gen_rtx_SET (VOIDmode, temp1,
- gen_rtx_ASHIFT (DImode, op0, GEN_INT (12))));
- emit_insn (gen_setl44 (op0, temp1, op1));
+ if (temp)
+ {
+ temp1 = op0;
+ temp2 = op0;
+ temp3 = temp; /* op0 is allowed. */
+ }
+ else
+ {
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+ temp3 = gen_reg_rtx (DImode);
+ }
+
+ emit_insn (gen_seth44 (temp1, op1));
+ emit_insn (gen_setm44 (temp2, temp1, op1));
+ emit_insn (gen_rtx_SET (VOIDmode, temp3,
+ gen_rtx_ASHIFT (DImode, temp2, GEN_INT (12))));
+ emit_insn (gen_setl44 (op0, temp3, op1));
break;
case CM_MEDANY:
@@ -1481,29 +1506,44 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1)
sethi %hh(symbol), %temp1
sethi %lm(symbol), %temp2
or %temp1, %hm(symbol), %temp3
- or %temp2, %lo(symbol), %temp4
- sllx %temp3, 32, %temp5
- or %temp4, %temp5, %reg */
-
- /* It is possible that one of the registers we got for operands[2]
- might coincide with that of operands[0] (which is why we made
- it TImode). Pick the other one to use as our scratch. */
- if (rtx_equal_p (temp1, op0))
+ sllx %temp3, 32, %temp4
+ or %temp4, %temp2, %temp5
+ or %temp5, %lo(symbol), %reg */
+ if (temp)
{
- if (ti_temp1)
- temp1 = gen_rtx_REG (DImode, REGNO (temp1) + 1);
- else
- abort();
+ /* It is possible that one of the registers we got for operands[2]
+ might coincide with that of operands[0] (which is why we made
+ it TImode). Pick the other one to use as our scratch. */
+ if (rtx_equal_p (temp, op0))
+ {
+ if (ti_temp)
+ temp = gen_rtx_REG (DImode, REGNO (temp) + 1);
+ else
+ abort();
+ }
+ temp1 = op0;
+ temp2 = temp; /* op0 is _not_ allowed, see above. */
+ temp3 = op0;
+ temp4 = op0;
+ temp5 = op0;
+ }
+ else
+ {
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+ temp3 = gen_reg_rtx (DImode);
+ temp4 = gen_reg_rtx (DImode);
+ temp5 = gen_reg_rtx (DImode);
}
- emit_insn (gen_sethh (op0, op1));
- emit_insn (gen_setlm (temp1, op1));
- emit_insn (gen_sethm (op0, op0, op1));
- emit_insn (gen_rtx_SET (VOIDmode, op0,
- gen_rtx_ASHIFT (DImode, op0, GEN_INT (32))));
- emit_insn (gen_rtx_SET (VOIDmode, op0,
- gen_rtx_PLUS (DImode, op0, temp1)));
- emit_insn (gen_setlo (op0, op0, op1));
+ emit_insn (gen_sethh (temp1, op1));
+ emit_insn (gen_setlm (temp2, op1));
+ emit_insn (gen_sethm (temp3, temp1, op1));
+ emit_insn (gen_rtx_SET (VOIDmode, temp4,
+ gen_rtx_ASHIFT (DImode, temp3, GEN_INT (32))));
+ emit_insn (gen_rtx_SET (VOIDmode, temp5,
+ gen_rtx_PLUS (DImode, temp4, temp2)));
+ emit_insn (gen_setlo (op0, temp5, op1));
break;
case CM_EMBMEDANY:
@@ -1515,42 +1555,69 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1)
look different.
Data segment: sethi %hi(symbol), %temp1
- or %temp1, %lo(symbol), %temp2
- add %temp2, EMBMEDANY_BASE_REG, %reg
-
- Text segment: sethi %uhi(symbol), %temp1
- sethi %hi(symbol), %temp2
- or %temp1, %ulo(symbol), %temp3
- or %temp2, %lo(symbol), %temp4
- sllx %temp3, 32, %temp5
- or %temp4, %temp5, %reg */
+ add %temp1, EMBMEDANY_BASE_REG, %temp2
+ or %temp2, %lo(symbol), %reg */
if (data_segment_operand (op1, GET_MODE (op1)))
{
+ if (temp)
+ {
+ temp1 = temp; /* op0 is allowed. */
+ temp2 = op0;
+ }
+ else
+ {
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+ }
+
emit_insn (gen_embmedany_sethi (temp1, op1));
- emit_insn (gen_embmedany_brsum (op0, temp1));
- emit_insn (gen_embmedany_losum (op0, op0, op1));
+ emit_insn (gen_embmedany_brsum (temp2, temp1));
+ emit_insn (gen_embmedany_losum (op0, temp2, op1));
}
+
+ /* Text segment: sethi %uhi(symbol), %temp1
+ sethi %hi(symbol), %temp2
+ or %temp1, %ulo(symbol), %temp3
+ sllx %temp3, 32, %temp4
+ or %temp4, %temp2, %temp5
+ or %temp5, %lo(symbol), %reg */
else
{
- /* It is possible that one of the registers we got for operands[2]
- might coincide with that of operands[0] (which is why we made
- it TImode). Pick the other one to use as our scratch. */
- if (rtx_equal_p (temp1, op0))
+ if (temp)
{
- if (ti_temp1)
- temp1 = gen_rtx_REG (DImode, REGNO (temp1) + 1);
- else
- abort();
+ /* It is possible that one of the registers we got for operands[2]
+ might coincide with that of operands[0] (which is why we made
+ it TImode). Pick the other one to use as our scratch. */
+ if (rtx_equal_p (temp, op0))
+ {
+ if (ti_temp)
+ temp = gen_rtx_REG (DImode, REGNO (temp) + 1);
+ else
+ abort();
+ }
+ temp1 = op0;
+ temp2 = temp; /* op0 is _not_ allowed, see above. */
+ temp3 = op0;
+ temp4 = op0;
+ temp5 = op0;
+ }
+ else
+ {
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+ temp3 = gen_reg_rtx (DImode);
+ temp4 = gen_reg_rtx (DImode);
+ temp5 = gen_reg_rtx (DImode);
}
- emit_insn (gen_embmedany_textuhi (op0, op1));
- emit_insn (gen_embmedany_texthi (temp1, op1));
- emit_insn (gen_embmedany_textulo (op0, op0, op1));
- emit_insn (gen_rtx_SET (VOIDmode, op0,
- gen_rtx_ASHIFT (DImode, op0, GEN_INT (32))));
- emit_insn (gen_rtx_SET (VOIDmode, op0,
- gen_rtx_PLUS (DImode, op0, temp1)));
- emit_insn (gen_embmedany_textlo (op0, op0, op1));
+ emit_insn (gen_embmedany_textuhi (temp1, op1));
+ emit_insn (gen_embmedany_texthi (temp2, op1));
+ emit_insn (gen_embmedany_textulo (temp3, temp1, op1));
+ emit_insn (gen_rtx_SET (VOIDmode, temp4,
+ gen_rtx_ASHIFT (DImode, temp3, GEN_INT (32))));
+ emit_insn (gen_rtx_SET (VOIDmode, temp5,
+ gen_rtx_PLUS (DImode, temp4, temp2)));
+ emit_insn (gen_embmedany_textlo (op0, temp5, op1));
}
break;
@@ -1562,10 +1629,10 @@ sparc_emit_set_symbolic_const64 (op0, op1, temp1)
/* These avoid problems when cross compiling. If we do not
go through all this hair then the optimizer will see
invalid REG_EQUAL notes or in some cases none at all. */
-static void sparc_emit_set_safe_HIGH64 PARAMS ((rtx, HOST_WIDE_INT));
-static rtx gen_safe_SET64 PARAMS ((rtx, HOST_WIDE_INT));
-static rtx gen_safe_OR64 PARAMS ((rtx, HOST_WIDE_INT));
-static rtx gen_safe_XOR64 PARAMS ((rtx, HOST_WIDE_INT));
+static void sparc_emit_set_safe_HIGH64 (rtx, HOST_WIDE_INT);
+static rtx gen_safe_SET64 (rtx, HOST_WIDE_INT);
+static rtx gen_safe_OR64 (rtx, HOST_WIDE_INT);
+static rtx gen_safe_XOR64 (rtx, HOST_WIDE_INT);
#if HOST_BITS_PER_WIDE_INT == 64
#define GEN_HIGHINT64(__x) GEN_INT ((__x) & ~(HOST_WIDE_INT)0x3ff)
@@ -1584,33 +1651,25 @@ static rtx gen_safe_XOR64 PARAMS ((rtx, HOST_WIDE_INT));
during CSE. We mask out the non-HIGH bits, and matches
a plain movdi, to alleviate this problem. */
static void
-sparc_emit_set_safe_HIGH64 (dest, val)
- rtx dest;
- HOST_WIDE_INT val;
+sparc_emit_set_safe_HIGH64 (rtx dest, HOST_WIDE_INT val)
{
emit_insn (gen_rtx_SET (VOIDmode, dest, GEN_HIGHINT64 (val)));
}
static rtx
-gen_safe_SET64 (dest, val)
- rtx dest;
- HOST_WIDE_INT val;
+gen_safe_SET64 (rtx dest, HOST_WIDE_INT val)
{
return gen_rtx_SET (VOIDmode, dest, GEN_INT64 (val));
}
static rtx
-gen_safe_OR64 (src, val)
- rtx src;
- HOST_WIDE_INT val;
+gen_safe_OR64 (rtx src, HOST_WIDE_INT val)
{
return gen_rtx_IOR (DImode, src, GEN_INT64 (val));
}
static rtx
-gen_safe_XOR64 (src, val)
- rtx src;
- HOST_WIDE_INT val;
+gen_safe_XOR64 (rtx src, HOST_WIDE_INT val)
{
return gen_rtx_XOR (DImode, src, GEN_INT64 (val));
}
@@ -1623,15 +1682,12 @@ gen_safe_XOR64 (src, val)
Without doing this, the optimizer cannot see such
opportunities. */
-static void sparc_emit_set_const64_quick1
- PARAMS ((rtx, rtx, unsigned HOST_WIDE_INT, int));
+static void sparc_emit_set_const64_quick1 (rtx, rtx,
+ unsigned HOST_WIDE_INT, int);
static void
-sparc_emit_set_const64_quick1 (op0, temp, low_bits, is_neg)
- rtx op0;
- rtx temp;
- unsigned HOST_WIDE_INT low_bits;
- int is_neg;
+sparc_emit_set_const64_quick1 (rtx op0, rtx temp,
+ unsigned HOST_WIDE_INT low_bits, int is_neg)
{
unsigned HOST_WIDE_INT high_bits;
@@ -1666,17 +1722,14 @@ sparc_emit_set_const64_quick1 (op0, temp, low_bits, is_neg)
}
}
-static void sparc_emit_set_const64_quick2
- PARAMS ((rtx, rtx, unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, int));
+static void sparc_emit_set_const64_quick2 (rtx, rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, int);
static void
-sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_immediate, shift_count)
- rtx op0;
- rtx temp;
- unsigned HOST_WIDE_INT high_bits;
- unsigned HOST_WIDE_INT low_immediate;
- int shift_count;
+sparc_emit_set_const64_quick2 (rtx op0, rtx temp,
+ unsigned HOST_WIDE_INT high_bits,
+ unsigned HOST_WIDE_INT low_immediate,
+ int shift_count)
{
rtx temp2 = op0;
@@ -1707,17 +1760,15 @@ sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_immediate, shift_count)
gen_safe_OR64 (op0, low_immediate)));
}
-static void sparc_emit_set_const64_longway
- PARAMS ((rtx, rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT));
+static void sparc_emit_set_const64_longway (rtx, rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT);
/* Full 64-bit constant decomposition. Even though this is the
'worst' case, we still optimize a few things away. */
static void
-sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits)
- rtx op0;
- rtx temp;
- unsigned HOST_WIDE_INT high_bits;
- unsigned HOST_WIDE_INT low_bits;
+sparc_emit_set_const64_longway (rtx op0, rtx temp,
+ unsigned HOST_WIDE_INT high_bits,
+ unsigned HOST_WIDE_INT low_bits)
{
rtx sub_temp;
@@ -1815,15 +1866,14 @@ sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits)
}
/* Analyze a 64-bit constant for certain properties. */
-static void analyze_64bit_constant
- PARAMS ((unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT,
- int *, int *, int *));
+static void analyze_64bit_constant (unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT,
+ int *, int *, int *);
static void
-analyze_64bit_constant (high_bits, low_bits, hbsp, lbsp, abbasp)
- unsigned HOST_WIDE_INT high_bits, low_bits;
- int *hbsp, *lbsp, *abbasp;
+analyze_64bit_constant (unsigned HOST_WIDE_INT high_bits,
+ unsigned HOST_WIDE_INT low_bits,
+ int *hbsp, int *lbsp, int *abbasp)
{
int lowest_bit_set, highest_bit_set, all_bits_between_are_set;
int i;
@@ -1884,12 +1934,11 @@ analyze_64bit_constant (high_bits, low_bits, hbsp, lbsp, abbasp)
*abbasp = all_bits_between_are_set;
}
-static int const64_is_2insns
- PARAMS ((unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT));
+static int const64_is_2insns (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT);
static int
-const64_is_2insns (high_bits, low_bits)
- unsigned HOST_WIDE_INT high_bits, low_bits;
+const64_is_2insns (unsigned HOST_WIDE_INT high_bits,
+ unsigned HOST_WIDE_INT low_bits)
{
int highest_bit_set, lowest_bit_set, all_bits_between_are_set;
@@ -1912,14 +1961,14 @@ const64_is_2insns (high_bits, low_bits)
return 0;
}
-static unsigned HOST_WIDE_INT create_simple_focus_bits
- PARAMS ((unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
- int, int));
+static unsigned HOST_WIDE_INT create_simple_focus_bits (unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT,
+ int, int);
static unsigned HOST_WIDE_INT
-create_simple_focus_bits (high_bits, low_bits, lowest_bit_set, shift)
- unsigned HOST_WIDE_INT high_bits, low_bits;
- int lowest_bit_set, shift;
+create_simple_focus_bits (unsigned HOST_WIDE_INT high_bits,
+ unsigned HOST_WIDE_INT low_bits,
+ int lowest_bit_set, int shift)
{
HOST_WIDE_INT hi, lo;
@@ -1943,14 +1992,12 @@ create_simple_focus_bits (high_bits, low_bits, lowest_bit_set, shift)
insn sequence possible. Detection of all the 1-insn cases
has been done already. */
void
-sparc_emit_set_const64 (op0, op1)
- rtx op0;
- rtx op1;
+sparc_emit_set_const64 (rtx op0, rtx op1)
{
unsigned HOST_WIDE_INT high_bits, low_bits;
int lowest_bit_set, highest_bit_set;
int all_bits_between_are_set;
- rtx temp;
+ rtx temp = 0;
/* Sanity check that we know what we are working with. */
if (! TARGET_ARCH64)
@@ -1966,8 +2013,6 @@ sparc_emit_set_const64 (op0, op1)
if (reload_in_progress || reload_completed)
temp = op0;
- else
- temp = gen_reg_rtx (DImode);
if (GET_CODE (op1) != CONST_DOUBLE
&& GET_CODE (op1) != CONST_INT)
@@ -1976,6 +2021,9 @@ sparc_emit_set_const64 (op0, op1)
return;
}
+ if (! temp)
+ temp = gen_reg_rtx (DImode);
+
if (GET_CODE (op1) == CONST_DOUBLE)
{
#if HOST_BITS_PER_WIDE_INT == 64
@@ -2223,10 +2271,7 @@ sparc_emit_set_const64 (op0, op1)
processing is needed. */
enum machine_mode
-select_cc_mode (op, x, y)
- enum rtx_code op;
- rtx x;
- rtx y ATTRIBUTE_UNUSED;
+select_cc_mode (enum rtx_code op, rtx x, rtx y ATTRIBUTE_UNUSED)
{
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
{
@@ -2275,9 +2320,7 @@ select_cc_mode (op, x, y)
return the rtx for the cc reg in the proper mode. */
rtx
-gen_compare_reg (code, x, y)
- enum rtx_code code;
- rtx x, y;
+gen_compare_reg (enum rtx_code code, rtx x, rtx y)
{
enum machine_mode mode = SELECT_CC_MODE (code, x, y);
rtx cc_reg;
@@ -2358,9 +2401,7 @@ gen_compare_reg (code, x, y)
sparc_compare_op1. */
int
-gen_v9_scc (compare_code, operands)
- enum rtx_code compare_code;
- register rtx *operands;
+gen_v9_scc (enum rtx_code compare_code, register rtx *operands)
{
rtx temp, op0, op1;
@@ -2448,9 +2489,7 @@ gen_v9_scc (compare_code, operands)
This function exists to take advantage of the v9 brxx insns. */
void
-emit_v9_brxx_insn (code, op0, label)
- enum rtx_code code;
- rtx op0, label;
+emit_v9_brxx_insn (enum rtx_code code, rtx op0, rtx label)
{
emit_jump_insn (gen_rtx_SET (VOIDmode,
pc_rtx,
@@ -2466,9 +2505,7 @@ emit_v9_brxx_insn (code, op0, label)
low 64bit of the register and 0 otherwise.
*/
rtx
-gen_df_reg (reg, low)
- rtx reg;
- int low;
+gen_df_reg (rtx reg, int low)
{
int regno = REGNO (reg);
@@ -2482,10 +2519,7 @@ gen_df_reg (reg, low)
assumed that no more than 3 operands are required. */
static void
-emit_soft_tfmode_libcall (func_name, nargs, operands)
- const char *func_name;
- int nargs;
- rtx *operands;
+emit_soft_tfmode_libcall (const char *func_name, int nargs, rtx *operands)
{
rtx ret_slot = NULL, arg[3], func_sym;
int i;
@@ -2570,9 +2604,7 @@ emit_soft_tfmode_libcall (func_name, nargs, operands)
/* Expand soft-float TFmode calls to sparc abi routines. */
static void
-emit_soft_tfmode_binop (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_soft_tfmode_binop (enum rtx_code code, rtx *operands)
{
const char *func;
@@ -2598,9 +2630,7 @@ emit_soft_tfmode_binop (code, operands)
}
static void
-emit_soft_tfmode_unop (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_soft_tfmode_unop (enum rtx_code code, rtx *operands)
{
const char *func;
@@ -2617,9 +2647,7 @@ emit_soft_tfmode_unop (code, operands)
}
static void
-emit_soft_tfmode_cvt (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_soft_tfmode_cvt (enum rtx_code code, rtx *operands)
{
const char *func;
@@ -2720,9 +2748,7 @@ emit_soft_tfmode_cvt (code, operands)
registers. */
static void
-emit_hard_tfmode_operation (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_hard_tfmode_operation (enum rtx_code code, rtx *operands)
{
rtx op, dest;
@@ -2751,9 +2777,7 @@ emit_hard_tfmode_operation (code, operands)
}
void
-emit_tfmode_binop (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_tfmode_binop (enum rtx_code code, rtx *operands)
{
if (TARGET_HARD_QUAD)
emit_hard_tfmode_operation (code, operands);
@@ -2762,9 +2786,7 @@ emit_tfmode_binop (code, operands)
}
void
-emit_tfmode_unop (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_tfmode_unop (enum rtx_code code, rtx *operands)
{
if (TARGET_HARD_QUAD)
emit_hard_tfmode_operation (code, operands);
@@ -2773,9 +2795,7 @@ emit_tfmode_unop (code, operands)
}
void
-emit_tfmode_cvt (code, operands)
- enum rtx_code code;
- rtx *operands;
+emit_tfmode_cvt (enum rtx_code code, rtx *operands)
{
if (TARGET_HARD_QUAD)
emit_hard_tfmode_operation (code, operands);
@@ -2786,7 +2806,7 @@ emit_tfmode_cvt (code, operands)
/* Return nonzero if a return peephole merging return with
setting of output register is ok. */
int
-leaf_return_peephole_ok ()
+leaf_return_peephole_ok (void)
{
return (actual_fsize == 0);
}
@@ -2795,8 +2815,7 @@ leaf_return_peephole_ok ()
nop into its delay slot. */
int
-empty_delay_slot (insn)
- rtx insn;
+empty_delay_slot (rtx insn)
{
rtx seq;
@@ -2815,9 +2834,7 @@ empty_delay_slot (insn)
delay slot. SLOT is the slot we are trying to fill. */
int
-eligible_for_epilogue_delay (trial, slot)
- rtx trial;
- int slot;
+eligible_for_epilogue_delay (rtx trial, int slot)
{
rtx pat, src;
@@ -2939,12 +2956,37 @@ eligible_for_epilogue_delay (trial, slot)
return 0;
}
+/* Return nonzero if TRIAL can go into the call delay slot. */
+int
+tls_call_delay (rtx trial)
+{
+ rtx pat, unspec;
+
+ /* Binutils allows
+ call __tls_get_addr, %tgd_call (foo)
+ add %l7, %o0, %o0, %tgd_add (foo)
+ while Sun as/ld does not. */
+ if (TARGET_GNU_TLS || !TARGET_TLS)
+ return 1;
+
+ pat = PATTERN (trial);
+ if (GET_CODE (pat) != SET || GET_CODE (SET_DEST (pat)) != PLUS)
+ return 1;
+
+ unspec = XEXP (SET_DEST (pat), 1);
+ if (GET_CODE (unspec) != UNSPEC
+ || (XINT (unspec, 1) != UNSPEC_TLSGD
+ && XINT (unspec, 1) != UNSPEC_TLSLDM))
+ return 1;
+
+ return 0;
+}
+
/* Return nonzero if TRIAL can go into the sibling call
delay slot. */
int
-eligible_for_sibcall_delay (trial)
- rtx trial;
+eligible_for_sibcall_delay (rtx trial)
{
rtx pat, src;
@@ -3034,8 +3076,7 @@ eligible_for_sibcall_delay (trial)
}
static int
-check_return_regs (x)
- rtx x;
+check_return_regs (rtx x)
{
switch (GET_CODE (x))
{
@@ -3069,8 +3110,7 @@ check_return_regs (x)
}
int
-short_branch (uid1, uid2)
- int uid1, uid2;
+short_branch (int uid1, int uid2)
{
int delta = INSN_ADDRESSES (uid1) - INSN_ADDRESSES (uid2);
@@ -3085,9 +3125,7 @@ short_branch (uid1, uid2)
We assume REG is a reload reg, and therefore does
not live past labels or calls or jumps. */
int
-reg_unused_after (reg, insn)
- rtx reg;
- rtx insn;
+reg_unused_after (rtx reg, rtx insn)
{
enum rtx_code code, prev_code = UNKNOWN;
@@ -3116,18 +3154,56 @@ reg_unused_after (reg, insn)
return 1;
}
+/* Determine if it's legal to put X into the constant pool. This
+ is not possible if X contains the address of a symbol that is
+ not constant (TLS) or not known at final link time (PIC). */
+
+static bool
+sparc_cannot_force_const_mem (rtx x)
+{
+ switch (GET_CODE (x))
+ {
+ case CONST_INT:
+ case CONST_DOUBLE:
+ /* Accept all non-symbolic constants. */
+ return false;
+
+ case LABEL_REF:
+ /* Labels are OK iff we are non-PIC. */
+ return flag_pic != 0;
+
+ case SYMBOL_REF:
+ /* 'Naked' TLS symbol references are never OK,
+ non-TLS symbols are OK iff we are non-PIC. */
+ if (SYMBOL_REF_TLS_MODEL (x))
+ return true;
+ else
+ return flag_pic != 0;
+
+ case CONST:
+ return sparc_cannot_force_const_mem (XEXP (x, 0));
+ case PLUS:
+ case MINUS:
+ return sparc_cannot_force_const_mem (XEXP (x, 0))
+ || sparc_cannot_force_const_mem (XEXP (x, 1));
+ case UNSPEC:
+ return true;
+ default:
+ abort ();
+ }
+}
+
/* The table we use to reference PIC data. */
static GTY(()) rtx global_offset_table;
/* The function we use to get at it. */
static GTY(()) rtx get_pc_symbol;
-static char get_pc_symbol_name[256];
+static GTY(()) char get_pc_symbol_name[256];
/* Ensure that we are not using patterns that are not OK with PIC. */
int
-check_pic (i)
- int i;
+check_pic (int i)
{
switch (flag_pic)
{
@@ -3150,8 +3226,7 @@ check_pic (i)
reloaded while generating PIC code. */
int
-pic_address_needs_scratch (x)
- rtx x;
+pic_address_needs_scratch (rtx x)
{
/* An address which is a symbolic plus a non SMALL_INT needs a temp reg. */
if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS
@@ -3163,16 +3238,399 @@ pic_address_needs_scratch (x)
return 0;
}
+/* Determine if a given RTX is a valid constant. We already know this
+ satisfies CONSTANT_P. */
+
+bool
+legitimate_constant_p (rtx x)
+{
+ rtx inner;
+
+ switch (GET_CODE (x))
+ {
+ case SYMBOL_REF:
+ /* TLS symbols are not constant. */
+ if (SYMBOL_REF_TLS_MODEL (x))
+ return false;
+ break;
+
+ case CONST:
+ inner = XEXP (x, 0);
+
+ /* Offsets of TLS symbols are never valid.
+ Discourage CSE from creating them. */
+ if (GET_CODE (inner) == PLUS
+ && tls_symbolic_operand (XEXP (inner, 0)))
+ return false;
+ break;
+
+ case CONST_DOUBLE:
+ if (GET_MODE (x) == VOIDmode)
+ return true;
+
+ /* Floating point constants are generally not ok.
+ The only exception is 0.0 in VIS. */
+ if (TARGET_VIS
+ && (GET_MODE (x) == SFmode
+ || GET_MODE (x) == DFmode
+ || GET_MODE (x) == TFmode)
+ && fp_zero_operand (x, GET_MODE (x)))
+ return true;
+
+ return false;
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+/* Determine if a given RTX is a valid constant address. */
+
+bool
+constant_address_p (rtx x)
+{
+ switch (GET_CODE (x))
+ {
+ case LABEL_REF:
+ case CONST_INT:
+ case HIGH:
+ return true;
+
+ case CONST:
+ if (flag_pic && pic_address_needs_scratch (x))
+ return false;
+ return legitimate_constant_p (x);
+
+ case SYMBOL_REF:
+ return !flag_pic && legitimate_constant_p (x);
+
+ default:
+ return false;
+ }
+}
+
+/* Nonzero if the constant value X is a legitimate general operand
+ when generating PIC code. It is given that flag_pic is on and
+ that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
+
+bool
+legitimate_pic_operand_p (rtx x)
+{
+ if (pic_address_needs_scratch (x))
+ return false;
+ if (tls_symbolic_operand (x)
+ || (GET_CODE (x) == CONST
+ && GET_CODE (XEXP (x, 0)) == PLUS
+ && tls_symbolic_operand (XEXP (XEXP (x, 0), 0))))
+ return false;
+ return true;
+}
+
+/* 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)
+{
+ rtx rs1 = NULL, rs2 = NULL, imm1 = NULL, imm2;
+
+ if (REG_P (addr) || GET_CODE (addr) == SUBREG)
+ rs1 = addr;
+ else if (GET_CODE (addr) == PLUS)
+ {
+ rs1 = XEXP (addr, 0);
+ rs2 = XEXP (addr, 1);
+
+ /* Canonicalize. REG comes first, if there are no regs,
+ LO_SUM comes first. */
+ if (!REG_P (rs1)
+ && GET_CODE (rs1) != SUBREG
+ && (REG_P (rs2)
+ || GET_CODE (rs2) == SUBREG
+ || (GET_CODE (rs2) == LO_SUM && GET_CODE (rs1) != LO_SUM)))
+ {
+ rs1 = XEXP (addr, 1);
+ rs2 = XEXP (addr, 0);
+ }
+
+ if ((flag_pic == 1
+ && rs1 == pic_offset_table_rtx
+ && !REG_P (rs2)
+ && GET_CODE (rs2) != SUBREG
+ && GET_CODE (rs2) != LO_SUM
+ && GET_CODE (rs2) != MEM
+ && !tls_symbolic_operand (rs2)
+ && (! symbolic_operand (rs2, VOIDmode) || mode == Pmode)
+ && (GET_CODE (rs2) != CONST_INT || SMALL_INT (rs2)))
+ || ((REG_P (rs1)
+ || GET_CODE (rs1) == SUBREG)
+ && RTX_OK_FOR_OFFSET_P (rs2)))
+ {
+ imm1 = rs2;
+ rs2 = NULL;
+ }
+ else if ((REG_P (rs1) || GET_CODE (rs1) == SUBREG)
+ && (REG_P (rs2) || GET_CODE (rs2) == SUBREG))
+ {
+ /* We prohibit REG + REG for TFmode when there are no instructions
+ which accept REG+REG instructions. We do this because REG+REG
+ is not an offsetable address. If we get the situation in reload
+ where source and destination of a movtf pattern are both MEMs with
+ REG+REG address, then only one of them gets converted to an
+ offsetable address. */
+ if (mode == TFmode
+ && !(TARGET_FPU && TARGET_ARCH64 && TARGET_V9
+ && TARGET_HARD_QUAD))
+ return 0;
+
+ /* We prohibit REG + REG on ARCH32 if not optimizing for
+ DFmode/DImode because then mem_min_alignment is likely to be zero
+ after reload and the forced split would lack a matching splitter
+ pattern. */
+ if (TARGET_ARCH32 && !optimize
+ && (mode == DFmode || mode == DImode))
+ return 0;
+ }
+ else if (USE_AS_OFFSETABLE_LO10
+ && GET_CODE (rs1) == LO_SUM
+ && TARGET_ARCH64
+ && ! TARGET_CM_MEDMID
+ && RTX_OK_FOR_OLO10_P (rs2))
+ {
+ imm2 = rs2;
+ rs2 = NULL;
+ imm1 = XEXP (rs1, 1);
+ rs1 = XEXP (rs1, 0);
+ if (! CONSTANT_P (imm1) || tls_symbolic_operand (rs1))
+ return 0;
+ }
+ }
+ else if (GET_CODE (addr) == LO_SUM)
+ {
+ rs1 = XEXP (addr, 0);
+ imm1 = XEXP (addr, 1);
+
+ if (! CONSTANT_P (imm1) || tls_symbolic_operand (rs1))
+ return 0;
+
+ /* We can't allow TFmode, because an offset greater than or equal to the
+ alignment (8) may cause the LO_SUM to overflow if !v9. */
+ if (mode == TFmode && !TARGET_V9)
+ return 0;
+ }
+ else if (GET_CODE (addr) == CONST_INT && SMALL_INT (addr))
+ return 1;
+ else
+ return 0;
+
+ if (GET_CODE (rs1) == SUBREG)
+ rs1 = SUBREG_REG (rs1);
+ if (!REG_P (rs1))
+ return 0;
+
+ if (rs2)
+ {
+ if (GET_CODE (rs2) == SUBREG)
+ rs2 = SUBREG_REG (rs2);
+ if (!REG_P (rs2))
+ return 0;
+ }
+
+ if (strict)
+ {
+ if (!REGNO_OK_FOR_BASE_P (REGNO (rs1))
+ || (rs2 && !REGNO_OK_FOR_BASE_P (REGNO (rs2))))
+ return 0;
+ }
+ else
+ {
+ if ((REGNO (rs1) >= 32
+ && REGNO (rs1) != FRAME_POINTER_REGNUM
+ && REGNO (rs1) < FIRST_PSEUDO_REGISTER)
+ || (rs2
+ && (REGNO (rs2) >= 32
+ && REGNO (rs2) != FRAME_POINTER_REGNUM
+ && REGNO (rs2) < FIRST_PSEUDO_REGISTER)))
+ return 0;
+ }
+ return 1;
+}
+
+/* Construct the SYMBOL_REF for the tls_get_offset function. */
+
+static GTY(()) rtx sparc_tls_symbol;
+static rtx
+sparc_tls_get_addr (void)
+{
+ if (!sparc_tls_symbol)
+ sparc_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_addr");
+
+ return sparc_tls_symbol;
+}
+
+static rtx
+sparc_tls_got (void)
+{
+ rtx temp;
+ if (flag_pic)
+ {
+ current_function_uses_pic_offset_table = 1;
+ return pic_offset_table_rtx;
+ }
+
+ if (!global_offset_table)
+ global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+ temp = gen_reg_rtx (Pmode);
+ emit_move_insn (temp, global_offset_table);
+ return temp;
+}
+
+
+/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
+ this (thread-local) address. */
+
+rtx
+legitimize_tls_address (rtx addr)
+{
+ rtx temp1, temp2, temp3, ret, o0, got, insn;
+
+ if (no_new_pseudos)
+ abort ();
+
+ if (GET_CODE (addr) == SYMBOL_REF)
+ switch (SYMBOL_REF_TLS_MODEL (addr))
+ {
+ case TLS_MODEL_GLOBAL_DYNAMIC:
+ start_sequence ();
+ temp1 = gen_reg_rtx (SImode);
+ temp2 = gen_reg_rtx (SImode);
+ ret = gen_reg_rtx (Pmode);
+ o0 = gen_rtx_REG (Pmode, 8);
+ got = sparc_tls_got ();
+ emit_insn (gen_tgd_hi22 (temp1, addr));
+ emit_insn (gen_tgd_lo10 (temp2, temp1, addr));
+ if (TARGET_ARCH32)
+ {
+ emit_insn (gen_tgd_add32 (o0, got, temp2, addr));
+ insn = emit_call_insn (gen_tgd_call32 (o0, sparc_tls_get_addr (),
+ addr, const1_rtx));
+ }
+ else
+ {
+ emit_insn (gen_tgd_add64 (o0, got, temp2, addr));
+ insn = emit_call_insn (gen_tgd_call64 (o0, sparc_tls_get_addr (),
+ addr, const1_rtx));
+ }
+ CALL_INSN_FUNCTION_USAGE (insn)
+ = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, o0),
+ CALL_INSN_FUNCTION_USAGE (insn));
+ insn = get_insns ();
+ end_sequence ();
+ emit_libcall_block (insn, ret, o0, addr);
+ break;
+
+ case TLS_MODEL_LOCAL_DYNAMIC:
+ start_sequence ();
+ temp1 = gen_reg_rtx (SImode);
+ temp2 = gen_reg_rtx (SImode);
+ temp3 = gen_reg_rtx (Pmode);
+ ret = gen_reg_rtx (Pmode);
+ o0 = gen_rtx_REG (Pmode, 8);
+ got = sparc_tls_got ();
+ emit_insn (gen_tldm_hi22 (temp1));
+ emit_insn (gen_tldm_lo10 (temp2, temp1));
+ if (TARGET_ARCH32)
+ {
+ emit_insn (gen_tldm_add32 (o0, got, temp2));
+ insn = emit_call_insn (gen_tldm_call32 (o0, sparc_tls_get_addr (),
+ const1_rtx));
+ }
+ else
+ {
+ emit_insn (gen_tldm_add64 (o0, got, temp2));
+ insn = emit_call_insn (gen_tldm_call64 (o0, sparc_tls_get_addr (),
+ const1_rtx));
+ }
+ CALL_INSN_FUNCTION_USAGE (insn)
+ = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, o0),
+ CALL_INSN_FUNCTION_USAGE (insn));
+ insn = get_insns ();
+ end_sequence ();
+ emit_libcall_block (insn, temp3, o0,
+ gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_TLSLD_BASE));
+ temp1 = gen_reg_rtx (SImode);
+ temp2 = gen_reg_rtx (SImode);
+ emit_insn (gen_tldo_hix22 (temp1, addr));
+ emit_insn (gen_tldo_lox10 (temp2, temp1, addr));
+ if (TARGET_ARCH32)
+ emit_insn (gen_tldo_add32 (ret, temp3, temp2, addr));
+ else
+ emit_insn (gen_tldo_add64 (ret, temp3, temp2, addr));
+ break;
+
+ case TLS_MODEL_INITIAL_EXEC:
+ temp1 = gen_reg_rtx (SImode);
+ temp2 = gen_reg_rtx (SImode);
+ temp3 = gen_reg_rtx (Pmode);
+ got = sparc_tls_got ();
+ emit_insn (gen_tie_hi22 (temp1, addr));
+ emit_insn (gen_tie_lo10 (temp2, temp1, addr));
+ if (TARGET_ARCH32)
+ emit_insn (gen_tie_ld32 (temp3, got, temp2, addr));
+ else
+ emit_insn (gen_tie_ld64 (temp3, got, temp2, addr));
+ if (TARGET_SUN_TLS)
+ {
+ ret = gen_reg_rtx (Pmode);
+ if (TARGET_ARCH32)
+ emit_insn (gen_tie_add32 (ret, gen_rtx_REG (Pmode, 7),
+ temp3, addr));
+ else
+ emit_insn (gen_tie_add64 (ret, gen_rtx_REG (Pmode, 7),
+ temp3, addr));
+ }
+ else
+ ret = gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, 7), temp3);
+ break;
+
+ case TLS_MODEL_LOCAL_EXEC:
+ temp1 = gen_reg_rtx (Pmode);
+ temp2 = gen_reg_rtx (Pmode);
+ if (TARGET_ARCH32)
+ {
+ emit_insn (gen_tle_hix22_sp32 (temp1, addr));
+ emit_insn (gen_tle_lox10_sp32 (temp2, temp1, addr));
+ }
+ else
+ {
+ emit_insn (gen_tle_hix22_sp64 (temp1, addr));
+ emit_insn (gen_tle_lox10_sp64 (temp2, temp1, addr));
+ }
+ ret = gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, 7), temp2);
+ break;
+
+ default:
+ abort ();
+ }
+
+ else
+ abort (); /* for now ... */
+
+ return ret;
+}
+
+
/* Legitimize PIC addresses. If the address is already position-independent,
we return ORIG. Newly generated position-independent addresses go into a
reg. This is REG if nonzero, otherwise we allocate register(s) as
necessary. */
rtx
-legitimize_pic_address (orig, mode, reg)
- rtx orig;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx reg;
+legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx reg)
{
if (GET_CODE (orig) == SYMBOL_REF)
{
@@ -3272,10 +3730,56 @@ legitimize_pic_address (orig, mode, reg)
return orig;
}
+/* Try machine-dependent ways of modifying an illegitimate address X
+ to be legitimate. If we find one, return the new, valid address.
+
+ 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 is the mode of the operand pointed to by X. */
+
+rtx
+legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode)
+{
+ rtx orig_x = x;
+
+ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT)
+ x = gen_rtx_PLUS (Pmode, XEXP (x, 1),
+ force_operand (XEXP (x, 0), NULL_RTX));
+ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == MULT)
+ x = gen_rtx_PLUS (Pmode, XEXP (x, 0),
+ force_operand (XEXP (x, 1), NULL_RTX));
+ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS)
+ x = gen_rtx_PLUS (Pmode, force_operand (XEXP (x, 0), NULL_RTX),
+ XEXP (x, 1));
+ if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == PLUS)
+ 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))
+ return x;
+
+ if (tls_symbolic_operand (x))
+ x = legitimize_tls_address (x);
+ else if (flag_pic)
+ x = legitimize_pic_address (x, mode, 0);
+ else if (GET_CODE (x) == PLUS && CONSTANT_ADDRESS_P (XEXP (x, 1)))
+ x = gen_rtx_PLUS (Pmode, XEXP (x, 0),
+ copy_to_mode_reg (Pmode, XEXP (x, 1)));
+ else if (GET_CODE (x) == PLUS && CONSTANT_ADDRESS_P (XEXP (x, 0)))
+ x = gen_rtx_PLUS (Pmode, XEXP (x, 1),
+ copy_to_mode_reg (Pmode, XEXP (x, 0)));
+ else if (GET_CODE (x) == SYMBOL_REF
+ || GET_CODE (x) == CONST
+ || GET_CODE (x) == LABEL_REF)
+ x = copy_to_suggested_reg (x, NULL_RTX, Pmode);
+ return x;
+}
+
/* Emit special PIC prologues. */
void
-load_pic_register ()
+load_pic_register (void)
{
/* Labels to get the PC in the prologue of this function. */
int orig_flag_pic = flag_pic;
@@ -3294,7 +3798,7 @@ load_pic_register ()
align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
if (align > 0)
ASM_OUTPUT_ALIGN (asm_out_file, align);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LGETPC", 0);
+ (*targetm.asm_out.internal_label) (asm_out_file, "LGETPC", 0);
fputs ("\tretl\n\tadd\t%o7, %l7, %l7\n", asm_out_file);
}
@@ -3320,9 +3824,7 @@ load_pic_register ()
least a DESIRED byte boundary. */
int
-mem_min_alignment (mem, desired)
- rtx mem;
- int desired;
+mem_min_alignment (rtx mem, int desired)
{
rtx addr, base, offset;
@@ -3515,7 +4017,7 @@ int sparc_mode_class [NUM_MACHINE_MODES];
enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
static void
-sparc_init_modes ()
+sparc_init_modes (void)
{
int i;
@@ -3551,16 +4053,13 @@ sparc_init_modes ()
sparc_mode_class[i] = 0;
break;
case MODE_CC:
- default:
- /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
- we must explicitly check for them here. */
if (i == (int) CCFPmode || i == (int) CCFPEmode)
sparc_mode_class[i] = 1 << (int) CCFP_MODE;
- else if (i == (int) CCmode || i == (int) CC_NOOVmode
- || i == (int) CCXmode || i == (int) CCX_NOOVmode)
- sparc_mode_class[i] = 1 << (int) CC_MODE;
else
- sparc_mode_class[i] = 0;
+ sparc_mode_class[i] = 1 << (int) CC_MODE;
+ break;
+ default:
+ sparc_mode_class[i] = 0;
break;
}
}
@@ -3593,13 +4092,8 @@ sparc_init_modes ()
v9 int regs as it simplifies the code. */
static int
-save_regs (file, low, high, base, offset, n_regs, real_offset)
- FILE *file;
- int low, high;
- const char *base;
- int offset;
- int n_regs;
- int real_offset;
+save_regs (FILE *file, int low, int high, const char *base,
+ int offset, int n_regs, HOST_WIDE_INT real_offset)
{
int i;
@@ -3666,12 +4160,8 @@ save_regs (file, low, high, base, offset, n_regs, real_offset)
v9 int regs as it simplifies the code. */
static int
-restore_regs (file, low, high, base, offset, n_regs)
- FILE *file;
- int low, high;
- const char *base;
- int offset;
- int n_regs;
+restore_regs (FILE *file, int low, int high, const char *base,
+ int offset, int n_regs)
{
int i;
@@ -3710,10 +4200,8 @@ restore_regs (file, low, high, base, offset, n_regs)
/* Compute the frame size required by the function. This function is called
during the reload pass and also by output_function_prologue(). */
-int
-compute_frame_size (size, leaf_function)
- int size;
- int leaf_function;
+HOST_WIDE_INT
+compute_frame_size (HOST_WIDE_INT size, int leaf_function)
{
int n_regs = 0, i;
int outgoing_args_size = (current_function_outgoing_args_size
@@ -3767,41 +4255,102 @@ compute_frame_size (size, leaf_function)
return SPARC_STACK_ALIGN (actual_fsize);
}
-/* Build a (32 bit) big number in a register. */
-/* ??? We may be able to use the set macro here too. */
+/* Build big number NUM in register REG and output the result to FILE.
+ REG is guaranteed to be the only clobbered register. The function
+ will very likely emit several instructions, so it must not be called
+ from within a delay slot. */
static void
-build_big_number (file, num, reg)
- FILE *file;
- int num;
- const char *reg;
+build_big_number (FILE *file, HOST_WIDE_INT num, const char *reg)
{
- if (num >= 0 || ! TARGET_ARCH64)
+#if HOST_BITS_PER_WIDE_INT == 64
+ HOST_WIDE_INT high_bits = (num >> 32) & 0xffffffff;
+
+ if (high_bits == 0
+#else
+ if (num >= 0
+#endif
+ || ! TARGET_ARCH64)
{
- fprintf (file, "\tsethi\t%%hi(%d), %s\n", num, reg);
+ /* We don't use the 'set' macro because it appears to be broken
+ in the Solaris 7 assembler. */
+ fprintf (file, "\tsethi\t%%hi("HOST_WIDE_INT_PRINT_DEC"), %s\n",
+ num, reg);
if ((num & 0x3ff) != 0)
- fprintf (file, "\tor\t%s, %%lo(%d), %s\n", reg, num, reg);
+ fprintf (file, "\tor\t%s, %%lo("HOST_WIDE_INT_PRINT_DEC"), %s\n",
+ reg, num, reg);
}
+#if HOST_BITS_PER_WIDE_INT == 64
+ else if (high_bits == 0xffffffff) /* && TARGET_ARCH64 */
+#else
else /* num < 0 && TARGET_ARCH64 */
+#endif
{
/* Sethi does not sign extend, so we must use a little trickery
to use it for negative numbers. Invert the constant before
loading it in, then use xor immediate to invert the loaded bits
(along with the upper 32 bits) to the desired constant. This
works because the sethi and immediate fields overlap. */
- int asize = num;
- int inv = ~asize;
- int low = -0x400 + (asize & 0x3FF);
+ HOST_WIDE_INT inv = ~num;
+ HOST_WIDE_INT low = -0x400 + (num & 0x3ff);
- fprintf (file, "\tsethi\t%%hi(%d), %s\n\txor\t%s, %d, %s\n",
- inv, reg, reg, low, reg);
+ fprintf (file, "\tsethi\t%%hi("HOST_WIDE_INT_PRINT_DEC"), %s\n",
+ inv, reg);
+ fprintf (file, "\txor\t%s, "HOST_WIDE_INT_PRINT_DEC", %s\n",
+ reg, low, reg);
}
+#if HOST_BITS_PER_WIDE_INT == 64
+ else /* TARGET_ARCH64 */
+ {
+ /* We don't use the 'setx' macro because if requires a scratch register.
+ This is the translation of sparc_emit_set_const64_longway into asm.
+ Hopefully we will soon have prologue/epilogue emitted as RTL. */
+ HOST_WIDE_INT low1 = (num >> (32 - 12)) & 0xfff;
+ HOST_WIDE_INT low2 = (num >> (32 - 12 - 12)) & 0xfff;
+ HOST_WIDE_INT low3 = (num >> (32 - 12 - 12 - 8)) & 0x0ff;
+ int to_shift = 12;
+
+ /* We don't use the 'set' macro because it appears to be broken
+ in the Solaris 7 assembler. */
+ fprintf (file, "\tsethi\t%%hi("HOST_WIDE_INT_PRINT_DEC"), %s\n",
+ high_bits, reg);
+ if ((high_bits & 0x3ff) != 0)
+ fprintf (file, "\tor\t%s, %%lo("HOST_WIDE_INT_PRINT_DEC"), %s\n",
+ reg, high_bits, reg);
+
+ if (low1 != 0)
+ {
+ fprintf (file, "\tsllx\t%s, %d, %s\n", reg, to_shift, reg);
+ fprintf (file, "\tor\t%s, "HOST_WIDE_INT_PRINT_DEC", %s\n",
+ reg, low1, reg);
+ to_shift = 12;
+ }
+ else
+ {
+ to_shift += 12;
+ }
+ if (low2 != 0)
+ {
+ fprintf (file, "\tsllx\t%s, %d, %s\n", reg, to_shift, reg);
+ fprintf (file, "\tor\t%s, "HOST_WIDE_INT_PRINT_DEC", %s\n",
+ reg, low2, reg);
+ to_shift = 8;
+ }
+ else
+ {
+ to_shift += 8;
+ }
+ fprintf (file, "\tsllx\t%s, %d, %s\n", reg, to_shift, reg);
+ if (low3 != 0)
+ fprintf (file, "\tor\t%s, "HOST_WIDE_INT_PRINT_DEC", %s\n",
+ reg, low3, reg);
+ }
+#endif
}
/* Output any necessary .register pseudo-ops. */
void
-sparc_output_scratch_registers (file)
- FILE *file ATTRIBUTE_UNUSED;
+sparc_output_scratch_registers (FILE *file ATTRIBUTE_UNUSED)
{
#ifdef HAVE_AS_REGISTER_PSEUDO_OP
int i;
@@ -3841,9 +4390,7 @@ sparc_output_scratch_registers (file)
to do this is made in regclass.c. */
static void
-sparc_output_function_prologue (file, size)
- FILE *file;
- HOST_WIDE_INT size;
+sparc_output_function_prologue (FILE *file, HOST_WIDE_INT size)
{
if (TARGET_FLAT)
sparc_flat_function_prologue (file, size);
@@ -3855,10 +4402,8 @@ sparc_output_function_prologue (file, size)
/* Output code for the function prologue. */
static void
-sparc_nonflat_function_prologue (file, size, leaf_function)
- FILE *file;
- HOST_WIDE_INT size;
- int leaf_function;
+sparc_nonflat_function_prologue (FILE *file, HOST_WIDE_INT size,
+ int leaf_function)
{
sparc_output_scratch_registers (file);
@@ -3885,11 +4430,13 @@ sparc_nonflat_function_prologue (file, size, leaf_function)
else if (! leaf_function)
{
if (actual_fsize <= 4096)
- fprintf (file, "\tsave\t%%sp, -%d, %%sp\n", actual_fsize);
+ fprintf (file, "\tsave\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n",
+ actual_fsize);
else if (actual_fsize <= 8192)
{
fprintf (file, "\tsave\t%%sp, -4096, %%sp\n");
- fprintf (file, "\tadd\t%%sp, -%d, %%sp\n", actual_fsize - 4096);
+ fprintf (file, "\tadd\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n",
+ actual_fsize - 4096);
}
else
{
@@ -3900,11 +4447,13 @@ sparc_nonflat_function_prologue (file, size, leaf_function)
else /* leaf function */
{
if (actual_fsize <= 4096)
- fprintf (file, "\tadd\t%%sp, -%d, %%sp\n", actual_fsize);
+ fprintf (file, "\tadd\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n",
+ actual_fsize);
else if (actual_fsize <= 8192)
{
fprintf (file, "\tadd\t%%sp, -4096, %%sp\n");
- fprintf (file, "\tadd\t%%sp, -%d, %%sp\n", actual_fsize - 4096);
+ fprintf (file, "\tadd\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n",
+ actual_fsize - 4096);
}
else
{
@@ -3941,7 +4490,8 @@ sparc_nonflat_function_prologue (file, size, leaf_function)
/* Call saved registers are saved just above the outgoing argument area. */
if (num_gfregs)
{
- int offset, real_offset, n_regs;
+ HOST_WIDE_INT offset, real_offset;
+ int n_regs;
const char *base;
real_offset = -apparent_fsize;
@@ -3973,11 +4523,10 @@ sparc_nonflat_function_prologue (file, size, leaf_function)
/* Output code to restore any call saved registers. */
static void
-output_restore_regs (file, leaf_function)
- FILE *file;
- int leaf_function ATTRIBUTE_UNUSED;
+output_restore_regs (FILE *file, int leaf_function ATTRIBUTE_UNUSED)
{
- int offset, n_regs;
+ HOST_WIDE_INT offset;
+ int n_regs;
const char *base;
offset = -apparent_fsize + frame_base_offset;
@@ -4006,9 +4555,7 @@ output_restore_regs (file, leaf_function)
before returning. */
static void
-sparc_output_function_epilogue (file, size)
- FILE *file;
- HOST_WIDE_INT size;
+sparc_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
{
if (TARGET_FLAT)
sparc_flat_function_epilogue (file, size);
@@ -4020,10 +4567,9 @@ sparc_output_function_epilogue (file, size)
/* Output code for the function epilogue. */
static void
-sparc_nonflat_function_epilogue (file, size, leaf_function)
- FILE *file;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
- int leaf_function;
+sparc_nonflat_function_epilogue (FILE *file,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED,
+ int leaf_function)
{
const char *ret;
@@ -4088,7 +4634,7 @@ sparc_nonflat_function_epilogue (file, size, leaf_function)
? "\treturn\t%i7+12\n"
: "\treturn\t%i7+8\n", file);
final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
- file, 1, 0, 0);
+ file, 1, 0, 0, NULL);
}
else
{
@@ -4113,7 +4659,7 @@ sparc_nonflat_function_epilogue (file, size, leaf_function)
insn = emit_jump_insn (insn);
sparc_emitting_epilogue = true;
- final_scan_insn (insn, file, 1, 0, 1);
+ final_scan_insn (insn, file, 1, 0, 1, NULL);
sparc_emitting_epilogue = false;
}
}
@@ -4135,23 +4681,23 @@ sparc_nonflat_function_epilogue (file, size, leaf_function)
abort ();
fprintf (file, "\t%s\n", ret);
final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
- file, 1, 0, 1);
+ file, 1, 0, 1, NULL);
}
/* Output 'nop' instead of 'sub %sp,-0,%sp' when no frame, so as to
avoid generating confusing assembly language output. */
else if (actual_fsize == 0)
fprintf (file, "\t%s\n\tnop\n", ret);
else if (actual_fsize <= 4096)
- fprintf (file, "\t%s\n\tsub\t%%sp, -%d, %%sp\n", ret, actual_fsize);
+ fprintf (file, "\t%s\n\tsub\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n",
+ ret, actual_fsize);
else if (actual_fsize <= 8192)
- fprintf (file, "\tsub\t%%sp, -4096, %%sp\n\t%s\n\tsub\t%%sp, -%d, %%sp\n",
+ fprintf (file, "\tsub\t%%sp, -4096, %%sp\n\t%s\n\tsub\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n",
ret, actual_fsize - 4096);
- else if ((actual_fsize & 0x3ff) == 0)
- fprintf (file, "\tsethi\t%%hi(%d), %%g1\n\t%s\n\tadd\t%%sp, %%g1, %%sp\n",
- actual_fsize, ret);
- else
- fprintf (file, "\tsethi\t%%hi(%d), %%g1\n\tor\t%%g1, %%lo(%d), %%g1\n\t%s\n\tadd\t%%sp, %%g1, %%sp\n",
- actual_fsize, actual_fsize, ret);
+ else
+ {
+ build_big_number (file, actual_fsize, "%g1");
+ fprintf (file, "\t%s\n\tadd\t%%sp, %%g1, %%sp\n", ret);
+ }
output_vectors:
sparc_output_deferred_case_vectors ();
@@ -4160,8 +4706,7 @@ sparc_nonflat_function_epilogue (file, size, leaf_function)
/* Output a sibling call. */
const char *
-output_sibcall (insn, call_operand)
- rtx insn, call_operand;
+output_sibcall (rtx insn, rtx call_operand)
{
int leaf_regs = current_function_uses_only_leaf_regs;
rtx operands[3];
@@ -4179,7 +4724,7 @@ output_sibcall (insn, call_operand)
if (! delay)
abort ();
- final_scan_insn (delay, asm_out_file, 1, 0, 1);
+ final_scan_insn (delay, asm_out_file, 1, 0, 1, NULL);
PATTERN (delay) = gen_blockage ();
INSN_CODE (delay) = -1;
delay_slot = 0;
@@ -4200,7 +4745,7 @@ output_sibcall (insn, call_operand)
#else
int spare_slot = ((TARGET_ARCH32 || TARGET_CM_MEDLOW) && ! flag_pic);
#endif
- int size = 0;
+ HOST_WIDE_INT size = 0;
if ((actual_fsize || ! spare_slot) && delay_slot)
{
@@ -4209,7 +4754,7 @@ output_sibcall (insn, call_operand)
if (! delay)
abort ();
- final_scan_insn (delay, asm_out_file, 1, 0, 1);
+ final_scan_insn (delay, asm_out_file, 1, 0, 1, NULL);
PATTERN (delay) = gen_blockage ();
INSN_CODE (delay) = -1;
delay_slot = 0;
@@ -4223,15 +4768,9 @@ output_sibcall (insn, call_operand)
fputs ("\tsub\t%sp, -4096, %sp\n", asm_out_file);
size = actual_fsize - 4096;
}
- else if ((actual_fsize & 0x3ff) == 0)
- fprintf (asm_out_file,
- "\tsethi\t%%hi(%d), %%g1\n\tadd\t%%sp, %%g1, %%sp\n",
- actual_fsize);
else
{
- fprintf (asm_out_file,
- "\tsethi\t%%hi(%d), %%g1\n\tor\t%%g1, %%lo(%d), %%g1\n",
- actual_fsize, actual_fsize);
+ build_big_number (asm_out_file, actual_fsize, "%g1");
fputs ("\tadd\t%%sp, %%g1, %%sp\n", asm_out_file);
}
}
@@ -4240,14 +4779,14 @@ output_sibcall (insn, call_operand)
output_asm_insn ("sethi\t%%hi(%a0), %%g1", operands);
output_asm_insn ("jmpl\t%%g1 + %%lo(%a0), %%g0", operands);
if (size)
- fprintf (asm_out_file, "\t sub\t%%sp, -%d, %%sp\n", size);
+ fprintf (asm_out_file, "\t sub\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n", size);
else if (! delay_slot)
fputs ("\t nop\n", asm_out_file);
}
else
{
if (size)
- fprintf (asm_out_file, "\tsub\t%%sp, -%d, %%sp\n", size);
+ fprintf (asm_out_file, "\tsub\t%%sp, -"HOST_WIDE_INT_PRINT_DEC", %%sp\n", size);
/* Use or with rs2 %%g0 instead of mov, so that as/ld can optimize
it into branch if possible. */
output_asm_insn ("or\t%%o7, %%g0, %%g1", operands);
@@ -4363,19 +4902,48 @@ output_sibcall (insn, call_operand)
For a library call, FNTYPE is 0. */
void
-init_cumulative_args (cum, fntype, libname, indirect)
- CUMULATIVE_ARGS *cum;
- tree fntype;
- rtx libname ATTRIBUTE_UNUSED;
- int indirect ATTRIBUTE_UNUSED;
+init_cumulative_args (struct sparc_args *cum, tree fntype,
+ rtx libname ATTRIBUTE_UNUSED,
+ tree fndecl ATTRIBUTE_UNUSED)
{
cum->words = 0;
cum->prototype_p = fntype && TYPE_ARG_TYPES (fntype);
cum->libcall_p = fntype == 0;
}
+/* Scan the record type TYPE and return the following predicates:
+ - INTREGS_P: the record contains at least one field or sub-field
+ that is eligible for promotion in integer registers.
+ - FP_REGS_P: the record contains at least one field or sub-field
+ that is eligible for promotion in floating-point registers.
+ - PACKED_P: the record contains at least one field that is packed.
+
+ Sub-fields are not taken into account for the PACKED_P predicate. */
+
+static void
+scan_record_type (tree type, int *intregs_p, int *fpregs_p, int *packed_p)
+{
+ tree field;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) == FIELD_DECL)
+ {
+ if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
+ scan_record_type (TREE_TYPE (field), intregs_p, fpregs_p, 0);
+ else if (FLOAT_TYPE_P (TREE_TYPE (field)) && TARGET_FPU)
+ *fpregs_p = 1;
+ else
+ *intregs_p = 1;
+
+ if (packed_p && DECL_PACKED (field))
+ *packed_p = 1;
+ }
+ }
+}
+
/* Compute the slot number to pass an argument in.
- Returns the slot number or -1 if passing on the stack.
+ Return the slot number or -1 if passing on the stack.
CUM is a variable of type CUMULATIVE_ARGS which gives info about
the preceding args and about the function being called.
@@ -4390,14 +4958,9 @@ init_cumulative_args (cum, fntype, libname, indirect)
*PPADDING records the amount of padding needed in words. */
static int
-function_arg_slotno (cum, mode, type, named, incoming_p, pregno, ppadding)
- const CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
- int incoming_p;
- int *pregno;
- int *ppadding;
+function_arg_slotno (const struct sparc_args *cum, enum machine_mode mode,
+ tree type, int named, int incoming_p,
+ int *pregno, int *ppadding)
{
int regbase = (incoming_p
? SPARC_INCOMING_INT_ARG_FIRST
@@ -4421,19 +4984,27 @@ function_arg_slotno (cum, mode, type, named, incoming_p, pregno, ppadding)
See emit_call_1. */
return -1;
+ case TImode : case CTImode :
+ if (TARGET_ARCH64 && (slotno & 1) != 0)
+ slotno++, *ppadding = 1;
+ /* fallthrough */
+
case QImode : case CQImode :
case HImode : case CHImode :
case SImode : case CSImode :
case DImode : case CDImode :
- case TImode : case CTImode :
if (slotno >= SPARC_INT_ARG_MAX)
return -1;
regno = regbase + slotno;
break;
+ case TFmode : case TCmode :
+ if (TARGET_ARCH64 && (slotno & 1) != 0)
+ slotno++, *ppadding = 1;
+ /* fallthrough */
+
case SFmode : case SCmode :
case DFmode : case DCmode :
- case TFmode : case TCmode :
if (TARGET_ARCH32)
{
if (slotno >= SPARC_INT_ARG_MAX)
@@ -4442,9 +5013,6 @@ function_arg_slotno (cum, mode, type, named, incoming_p, pregno, ppadding)
}
else
{
- if ((mode == TFmode || mode == TCmode)
- && (slotno & 1) != 0)
- slotno++, *ppadding = 1;
if (TARGET_FPU && named)
{
if (slotno >= SPARC_FP_ARG_MAX)
@@ -4479,27 +5047,14 @@ function_arg_slotno (cum, mode, type, named, incoming_p, pregno, ppadding)
}
else
{
- tree field;
- int intregs_p = 0, fpregs_p = 0;
- /* The ABI obviously doesn't specify how packed
- structures are passed. These are defined to be passed
- in int regs if possible, otherwise memory. */
- int packed_p = 0;
+ int intregs_p = 0, fpregs_p = 0, packed_p = 0;
- /* First see what kinds of registers we need. */
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- {
- if (TREE_CODE (field) == FIELD_DECL)
- {
- if (TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
- && TARGET_FPU)
- fpregs_p = 1;
- else
- intregs_p = 1;
- if (DECL_PACKED (field))
- packed_p = 1;
- }
- }
+ /* First see what kinds of registers we would need. */
+ scan_record_type (type, &intregs_p, &fpregs_p, &packed_p);
+
+ /* The ABI obviously doesn't specify how packed structures
+ are passed. These are defined to be passed in int regs
+ if possible, otherwise memory. */
if (packed_p || !named)
fpregs_p = 0, intregs_p = 1;
@@ -4535,49 +5090,45 @@ struct function_arg_record_value_parms
int named; /* whether the argument is named. */
int regbase; /* regno of the base register. */
int stack; /* 1 if part of the argument is on the stack. */
- int intoffset; /* offset of the pending integer field. */
+ int intoffset; /* offset of the first pending integer field. */
unsigned int nregs; /* number of words passed in registers. */
};
static void function_arg_record_value_3
- PARAMS ((HOST_WIDE_INT, struct function_arg_record_value_parms *));
+ (HOST_WIDE_INT, struct function_arg_record_value_parms *);
static void function_arg_record_value_2
- PARAMS ((tree, HOST_WIDE_INT,
- struct function_arg_record_value_parms *));
+ (tree, HOST_WIDE_INT, struct function_arg_record_value_parms *, bool);
static void function_arg_record_value_1
- PARAMS ((tree, HOST_WIDE_INT,
- struct function_arg_record_value_parms *));
-static rtx function_arg_record_value
- PARAMS ((tree, enum machine_mode, int, int, int));
+ (tree, HOST_WIDE_INT, struct function_arg_record_value_parms *, bool);
+static rtx function_arg_record_value (tree, enum machine_mode, int, int, int);
+static rtx function_arg_union_value (int, enum machine_mode, int);
/* A subroutine of function_arg_record_value. Traverse the structure
- recusively and determine how many registers will be required. */
+ recursively and determine how many registers will be required. */
static void
-function_arg_record_value_1 (type, startbitpos, parms)
- tree type;
- HOST_WIDE_INT startbitpos;
- struct function_arg_record_value_parms *parms;
+function_arg_record_value_1 (tree type, HOST_WIDE_INT startbitpos,
+ struct function_arg_record_value_parms *parms,
+ bool packed_p)
{
tree field;
- /* The ABI obviously doesn't specify how packed structures are
- passed. These are defined to be passed in int regs if possible,
- otherwise memory. */
- int packed_p = 0;
-
/* We need to compute how many registers are needed so we can
allocate the PARALLEL but before we can do that we need to know
- whether there are any packed fields. If there are, int regs are
- used regardless of whether there are fp values present. */
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- {
- if (TREE_CODE (field) == FIELD_DECL && DECL_PACKED (field))
- {
- packed_p = 1;
- break;
- }
- }
+ whether there are any packed fields. The ABI obviously doesn't
+ specify how structures are passed in this case, so they are
+ defined to be passed in int regs if possible, otherwise memory,
+ regardless of whether there are fp values present. */
+
+ if (! packed_p)
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) == FIELD_DECL && DECL_PACKED (field))
+ {
+ packed_p = true;
+ break;
+ }
+ }
/* Compute how many registers we need. */
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
@@ -4593,21 +5144,24 @@ function_arg_record_value_1 (type, startbitpos, parms)
/* ??? FIXME: else assume zero offset. */
if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
- function_arg_record_value_1 (TREE_TYPE (field), bitpos, parms);
- else if ((TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
- || (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE
- && (TREE_CODE (TREE_TYPE (TREE_TYPE (field)))
- == REAL_TYPE)))
- && TARGET_FPU
- && ! packed_p
- && parms->named)
+ function_arg_record_value_1 (TREE_TYPE (field),
+ bitpos,
+ parms,
+ packed_p);
+ else if (FLOAT_TYPE_P (TREE_TYPE (field))
+ && TARGET_FPU
+ && parms->named
+ && ! packed_p)
{
if (parms->intoffset != -1)
{
+ unsigned int startbit, endbit;
int intslots, this_slotno;
- intslots = (bitpos - parms->intoffset + BITS_PER_WORD - 1)
- / BITS_PER_WORD;
+ startbit = parms->intoffset & -BITS_PER_WORD;
+ endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
+
+ intslots = (endbit - startbit) / BITS_PER_WORD;
this_slotno = parms->slotno + parms->intoffset
/ BITS_PER_WORD;
@@ -4641,9 +5195,8 @@ function_arg_record_value_1 (type, startbitpos, parms)
structure between parms->intoffset and bitpos to integer registers. */
static void
-function_arg_record_value_3 (bitpos, parms)
- HOST_WIDE_INT bitpos;
- struct function_arg_record_value_parms *parms;
+function_arg_record_value_3 (HOST_WIDE_INT bitpos,
+ struct function_arg_record_value_parms *parms)
{
enum machine_mode mode;
unsigned int regno;
@@ -4687,6 +5240,7 @@ function_arg_record_value_3 (bitpos, parms)
this_slotno += 1;
intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
+ mode = word_mode;
parms->nregs += 1;
intslots -= 1;
}
@@ -4699,22 +5253,21 @@ function_arg_record_value_3 (bitpos, parms)
to make that happen. */
static void
-function_arg_record_value_2 (type, startbitpos, parms)
- tree type;
- HOST_WIDE_INT startbitpos;
- struct function_arg_record_value_parms *parms;
+function_arg_record_value_2 (tree type, HOST_WIDE_INT startbitpos,
+ struct function_arg_record_value_parms *parms,
+ bool packed_p)
{
tree field;
- int packed_p = 0;
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- {
- if (TREE_CODE (field) == FIELD_DECL && DECL_PACKED (field))
- {
- packed_p = 1;
- break;
- }
- }
+ if (! packed_p)
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ if (TREE_CODE (field) == FIELD_DECL && DECL_PACKED (field))
+ {
+ packed_p = true;
+ break;
+ }
+ }
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{
@@ -4729,14 +5282,14 @@ function_arg_record_value_2 (type, startbitpos, parms)
/* ??? FIXME: else assume zero offset. */
if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
- function_arg_record_value_2 (TREE_TYPE (field), bitpos, parms);
- else if ((TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
- || (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE
- && (TREE_CODE (TREE_TYPE (TREE_TYPE (field)))
- == REAL_TYPE)))
- && TARGET_FPU
- && ! packed_p
- && parms->named)
+ function_arg_record_value_2 (TREE_TYPE (field),
+ bitpos,
+ parms,
+ packed_p);
+ else if (FLOAT_TYPE_P (TREE_TYPE (field))
+ && TARGET_FPU
+ && parms->named
+ && ! packed_p)
{
int this_slotno = parms->slotno + bitpos / BITS_PER_WORD;
int regno;
@@ -4794,10 +5347,8 @@ function_arg_record_value_2 (type, startbitpos, parms)
REGBASE is the regno of the base register for the parameter array. */
static rtx
-function_arg_record_value (type, mode, slotno, named, regbase)
- tree type;
- enum machine_mode mode;
- int slotno, named, regbase;
+function_arg_record_value (tree type, enum machine_mode mode,
+ int slotno, int named, int regbase)
{
HOST_WIDE_INT typesize = int_size_in_bytes (type);
struct function_arg_record_value_parms parms;
@@ -4812,8 +5363,9 @@ function_arg_record_value (type, mode, slotno, named, regbase)
/* Compute how many registers we need. */
parms.nregs = 0;
parms.intoffset = 0;
- function_arg_record_value_1 (type, 0, &parms);
+ function_arg_record_value_1 (type, 0, &parms, false);
+ /* Take into account pending integer fields. */
if (parms.intoffset != -1)
{
unsigned int startbit, endbit;
@@ -4874,7 +5426,7 @@ function_arg_record_value (type, mode, slotno, named, regbase)
/* Fill in the entries. */
parms.nregs = 0;
parms.intoffset = 0;
- function_arg_record_value_2 (type, 0, &parms);
+ function_arg_record_value_2 (type, 0, &parms, false);
function_arg_record_value_3 (typesize * BITS_PER_UNIT, &parms);
if (parms.nregs != nregs)
@@ -4883,6 +5435,33 @@ function_arg_record_value (type, mode, slotno, named, regbase)
return parms.ret;
}
+/* Used by function_arg and function_value to implement the conventions
+ of the 64-bit ABI for passing and returning unions.
+ Return an expression valid as a return value for the two macros
+ FUNCTION_ARG and FUNCTION_VALUE.
+
+ SIZE is the size in bytes of the union.
+ MODE is the argument's machine mode.
+ REGNO is the hard register the union will be passed in. */
+
+static rtx
+function_arg_union_value (int size, enum machine_mode mode, int regno)
+{
+ int nwords = ROUND_ADVANCE (size), i;
+ rtx regs;
+
+ /* Unions are passed left-justified. */
+ regs = gen_rtx_PARALLEL (mode, rtvec_alloc (nwords));
+
+ for (i = 0; i < nwords; i++)
+ XVECEXP (regs, 0, i)
+ = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (word_mode, regno + i),
+ GEN_INT (UNITS_PER_WORD * i));
+
+ return regs;
+}
+
/* Handle the FUNCTION_ARG macro.
Determine where to put an argument to a function.
Value is zero to push the argument on the stack,
@@ -4899,12 +5478,8 @@ function_arg_record_value (type, mode, slotno, named, regbase)
INCOMING_P is zero for FUNCTION_ARG, nonzero for FUNCTION_INCOMING_ARG. */
rtx
-function_arg (cum, mode, type, named, incoming_p)
- const CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
- int incoming_p;
+function_arg (const struct sparc_args *cum, enum machine_mode mode,
+ tree type, int named, int incoming_p)
{
int regbase = (incoming_p
? SPARC_INCOMING_INT_ARG_FIRST
@@ -4923,13 +5498,32 @@ function_arg (cum, mode, type, named, incoming_p)
reg = gen_rtx_REG (mode, regno);
return reg;
}
+
+ if (type && TREE_CODE (type) == RECORD_TYPE)
+ {
+ /* Structures up to 16 bytes in size are passed in arg slots on the
+ stack and are promoted to registers where possible. */
+ if (int_size_in_bytes (type) > 16)
+ abort (); /* shouldn't get here */
+
+ return function_arg_record_value (type, mode, slotno, named, regbase);
+ }
+ else if (type && TREE_CODE (type) == UNION_TYPE)
+ {
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+
+ if (size > 16)
+ abort (); /* shouldn't get here */
+
+ return function_arg_union_value (size, mode, regno);
+ }
/* v9 fp args in reg slots beyond the int reg slots get passed in regs
but also have the slot allocated for them.
If no prototype is in scope fp values in register slots get passed
in two places, either fp regs and int regs or fp regs and memory. */
- if ((GET_MODE_CLASS (mode) == MODE_FLOAT
- || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
+ else if ((GET_MODE_CLASS (mode) == MODE_FLOAT
+ || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
&& SPARC_FP_REG_P (regno))
{
reg = gen_rtx_REG (mode, regno);
@@ -4958,7 +5552,7 @@ function_arg (cum, mode, type, named, incoming_p)
This is due to locate_and_pad_parm being called in
expand_call whenever reg_parm_stack_space > 0, which
- while benefical to our example here, would seem to be
+ while beneficial to our example here, would seem to be
in error from what had been intended. Ho hum... -- r~ */
#endif
return reg;
@@ -4993,27 +5587,6 @@ function_arg (cum, mode, type, named, incoming_p)
}
}
}
- else if (type && TREE_CODE (type) == RECORD_TYPE)
- {
- /* Structures up to 16 bytes in size are passed in arg slots on the
- stack and are promoted to registers where possible. */
-
- if (int_size_in_bytes (type) > 16)
- abort (); /* shouldn't get here */
-
- return function_arg_record_value (type, mode, slotno, named, regbase);
- }
- else if (type && TREE_CODE (type) == UNION_TYPE)
- {
- enum machine_mode mode;
- int bytes = int_size_in_bytes (type);
-
- if (bytes > 16)
- abort ();
-
- mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 0);
- reg = gen_rtx_REG (mode, regno);
- }
else
{
/* Scalar or complex int. */
@@ -5035,11 +5608,8 @@ function_arg (cum, mode, type, named, incoming_p)
mode] will be split between that reg and memory. */
int
-function_arg_partial_nregs (cum, mode, type, named)
- const CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
+function_arg_partial_nregs (const struct sparc_args *cum,
+ enum machine_mode mode, tree type, int named)
{
int slotno, regno, padding;
@@ -5073,11 +5643,17 @@ function_arg_partial_nregs (cum, mode, type, named)
}
else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
|| (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
- && ! TARGET_FPU))
+ && ! (TARGET_FPU && named)))
{
+ /* The complex types are passed as packed types. */
+ if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
+ return 0;
+
if (GET_MODE_ALIGNMENT (mode) == 128)
{
slotno += slotno & 1;
+
+ /* ??? The mode needs 3 slots? */
if (slotno == SPARC_INT_ARG_MAX - 2)
return 1;
}
@@ -5106,21 +5682,21 @@ function_arg_partial_nregs (cum, mode, type, named)
For Pascal, also pass arrays by reference. */
int
-function_arg_pass_by_reference (cum, mode, type, named)
- const CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
- enum machine_mode mode;
- tree type;
- int named ATTRIBUTE_UNUSED;
+function_arg_pass_by_reference (const struct sparc_args *cum ATTRIBUTE_UNUSED,
+ enum machine_mode mode, tree type,
+ int named ATTRIBUTE_UNUSED)
{
if (TARGET_ARCH32)
{
return ((type && AGGREGATE_TYPE_P (type))
- || mode == TFmode || mode == TCmode);
+ || mode == SCmode
+ || GET_MODE_SIZE (mode) > 8);
}
else
{
return ((type && TREE_CODE (type) == ARRAY_TYPE)
- /* Consider complex values as aggregates, so care for TCmode. */
+ /* Consider complex values as aggregates, so care
+ for CTImode and TCmode. */
|| GET_MODE_SIZE (mode) > 16
|| (type
&& AGGREGATE_TYPE_P (type)
@@ -5134,11 +5710,8 @@ function_arg_pass_by_reference (cum, mode, type, named)
TYPE is null for libcalls where that information may not be available. */
void
-function_arg_advance (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
+function_arg_advance (struct sparc_args *cum, enum machine_mode mode,
+ tree type, int named)
{
int slotno, regno, padding;
@@ -5168,14 +5741,6 @@ function_arg_advance (cum, mode, type, named)
else /* passed by reference */
++cum->words;
}
- else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
- {
- cum->words += 2;
- }
- else if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
- {
- cum->words += GET_MODE_SIZE (mode) / UNITS_PER_WORD;
- }
else
{
cum->words += (mode != BLKmode
@@ -5190,21 +5755,13 @@ function_arg_advance (cum, mode, type, named)
argument slot. */
enum direction
-function_arg_padding (mode, type)
- enum machine_mode mode;
- tree type;
+function_arg_padding (enum machine_mode mode, tree type)
{
if (TARGET_ARCH64 && type != 0 && AGGREGATE_TYPE_P (type))
return upward;
- /* This is the default definition. */
- return (! BYTES_BIG_ENDIAN
- ? upward
- : ((mode == BLKmode
- ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
- : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
- ? downward : upward));
+ /* Fall back to the default. */
+ return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
}
/* Handle FUNCTION_VALUE, FUNCTION_OUTGOING_VALUE, and LIBCALL_VALUE macros.
@@ -5212,18 +5769,16 @@ function_arg_padding (mode, type)
except that up to 32-bytes may be returned in registers. */
rtx
-function_value (type, mode, incoming_p)
- tree type;
- enum machine_mode mode;
- int incoming_p;
+function_value (tree type, enum machine_mode mode, int incoming_p)
{
int regno;
- int regbase = (incoming_p
- ? SPARC_OUTGOING_INT_ARG_FIRST
- : SPARC_INCOMING_INT_ARG_FIRST);
if (TARGET_ARCH64 && type)
{
+ int regbase = (incoming_p
+ ? SPARC_OUTGOING_INT_ARG_FIRST
+ : SPARC_INCOMING_INT_ARG_FIRST);
+
if (TREE_CODE (type) == RECORD_TYPE)
{
/* Structures up to 32 bytes in size are passed in registers,
@@ -5234,6 +5789,15 @@ function_value (type, mode, incoming_p)
return function_arg_record_value (type, mode, 0, 1, regbase);
}
+ else if (TREE_CODE (type) == UNION_TYPE)
+ {
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+
+ if (size > 32)
+ abort (); /* shouldn't get here */
+
+ return function_arg_union_value (size, mode, regbase);
+ }
else if (AGGREGATE_TYPE_P (type))
{
/* All other aggregate types are passed in an integer register
@@ -5244,14 +5808,23 @@ function_value (type, mode, incoming_p)
abort ();
mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 0);
+
+ /* ??? We probably should have made the same ABI change in
+ 3.4.0 as the one we made for unions. The latter was
+ required by the SCD though, while the former is not
+ specified, so we favored compatibility and efficiency.
+
+ Now we're stuck for aggregates larger than 16 bytes,
+ because OImode vanished in the meantime. Let's not
+ try to be unduly clever, and simply follow the ABI
+ for unions in that case. */
+ if (mode == BLKmode)
+ return function_arg_union_value (bytes, mode, regbase);
}
+ else if (GET_MODE_CLASS (mode) == MODE_INT
+ && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
+ mode = word_mode;
}
-
- if (TARGET_ARCH64
- && GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_SIZE (mode) < UNITS_PER_WORD
- && type && ! AGGREGATE_TYPE_P (type))
- mode = DImode;
if (incoming_p)
regno = BASE_RETURN_VALUE_REG (mode);
@@ -5266,7 +5839,7 @@ function_value (type, mode, incoming_p)
the first unnamed parameter. */
rtx
-sparc_builtin_saveregs ()
+sparc_builtin_saveregs (void)
{
int first_reg = current_function_args_info.words;
rtx address;
@@ -5293,9 +5866,7 @@ sparc_builtin_saveregs ()
/* Implement `va_start' for varargs and stdarg. */
void
-sparc_va_start (valist, nextarg)
- tree valist;
- rtx nextarg;
+sparc_va_start (tree valist, rtx nextarg)
{
nextarg = expand_builtin_saveregs ();
std_expand_builtin_va_start (valist, nextarg);
@@ -5304,8 +5875,7 @@ sparc_va_start (valist, nextarg)
/* Implement `va_arg'. */
rtx
-sparc_va_arg (valist, type)
- tree valist, type;
+sparc_va_arg (tree valist, tree type)
{
HOST_WIDE_INT size, rsize, align;
tree addr, incr;
@@ -5322,16 +5892,19 @@ sparc_va_arg (valist, type)
if (TYPE_ALIGN (type) >= 2 * (unsigned) BITS_PER_WORD)
align = 2 * UNITS_PER_WORD;
- if (AGGREGATE_TYPE_P (type))
+ /* Consider complex values as aggregates, so care
+ for CTImode and TCmode. */
+ if ((unsigned HOST_WIDE_INT) size > 16)
{
- if ((unsigned HOST_WIDE_INT) size > 16)
- {
- indirect = 1;
- size = rsize = UNITS_PER_WORD;
- }
- /* SPARC v9 ABI states that structures up to 8 bytes in size are
- given one 8 byte slot. */
- else if (size == 0)
+ indirect = 1;
+ size = rsize = UNITS_PER_WORD;
+ align = 0;
+ }
+ else if (AGGREGATE_TYPE_P (type))
+ {
+ /* SPARC-V9 ABI states that structures up to 16 bytes in size
+ are given whole slots as needed. */
+ if (size == 0)
size = rsize = UNITS_PER_WORD;
else
size = rsize;
@@ -5340,8 +5913,8 @@ sparc_va_arg (valist, type)
else
{
if (AGGREGATE_TYPE_P (type)
- || TYPE_MODE (type) == TFmode
- || TYPE_MODE (type) == TCmode)
+ || TYPE_MODE (type) == SCmode
+ || GET_MODE_SIZE (TYPE_MODE (type)) > 8)
{
indirect = 1;
size = rsize = UNITS_PER_WORD;
@@ -5414,25 +5987,81 @@ sparc_va_arg (valist, type)
return addr_rtx;
}
+/* Return the string to output an unconditional branch to LABEL, which is
+ the operand number of the label.
+
+ DEST is the destination insn (i.e. the label), INSN is the source. */
+
+const char *
+output_ubranch (rtx dest, int label, rtx insn)
+{
+ static char string[64];
+ bool noop = false;
+ char *p;
+
+ /* TurboSPARC is reported to have problems with
+ with
+ foo: b,a foo
+ i.e. an empty loop with the annul bit set. The workaround is to use
+ foo: b foo; nop
+ instead. */
+
+ if (! TARGET_V9 && flag_delayed_branch
+ && (INSN_ADDRESSES (INSN_UID (dest))
+ == INSN_ADDRESSES (INSN_UID (insn))))
+ {
+ strcpy (string, "b\t");
+ noop = true;
+ }
+ else
+ {
+ bool v9_form = false;
+
+ if (TARGET_V9 && INSN_ADDRESSES_SET_P ())
+ {
+ int delta = (INSN_ADDRESSES (INSN_UID (dest))
+ - INSN_ADDRESSES (INSN_UID (insn)));
+ /* Leave some instructions for "slop". */
+ if (delta >= -260000 && delta < 260000)
+ v9_form = true;
+ }
+
+ if (v9_form)
+ strcpy (string, "ba%*,pt\t%%xcc, ");
+ else
+ strcpy (string, "b%*\t");
+ }
+
+ p = strchr (string, '\0');
+ *p++ = '%';
+ *p++ = 'l';
+ *p++ = '0' + label;
+ *p++ = '%';
+ if (noop)
+ *p++ = '#';
+ else
+ *p++ = '(';
+ *p = '\0';
+
+ return string;
+}
+
/* Return the string to output a conditional branch to LABEL, which is
the operand number of the label. OP is the conditional expression.
XEXP (OP, 0) is assumed to be a condition code register (integer or
floating point) and its mode specifies what kind of comparison we made.
+ DEST is the destination insn (i.e. the label), INSN is the source.
+
REVERSED is nonzero if we should reverse the sense of the comparison.
ANNUL is nonzero if we should generate an annulling branch.
- NOOP is nonzero if we have to follow this branch by a noop.
-
- INSN, if set, is the insn. */
+ NOOP is nonzero if we have to follow this branch by a noop. */
char *
-output_cbranch (op, dest, label, reversed, annul, noop, insn)
- rtx op, dest;
- int label;
- int reversed, annul, noop;
- rtx insn;
+output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
+ int noop, rtx insn)
{
static char string[50];
enum rtx_code code = GET_CODE (op);
@@ -5463,7 +6092,7 @@ output_cbranch (op, dest, label, reversed, annul, noop, insn)
nop
ba .LC29 */
- far = get_attr_length (insn) >= 3;
+ far = TARGET_V9 && (get_attr_length (insn) >= 3);
if (reversed ^ far)
{
/* Reversal of FP compares takes care -- an ordered compare
@@ -5593,9 +6222,7 @@ output_cbranch (op, dest, label, reversed, annul, noop, insn)
spaces -= 2;
}
- if (! TARGET_V9)
- labelno = "";
- else
+ if (TARGET_V9)
{
rtx note;
int v8 = 0;
@@ -5645,6 +6272,9 @@ output_cbranch (op, dest, label, reversed, annul, noop, insn)
spaces -= 3;
}
}
+ else
+ labelno = "";
+
if (spaces > 0)
*p++ = '\t';
else
@@ -5676,9 +6306,7 @@ output_cbranch (op, dest, label, reversed, annul, noop, insn)
values as arguments instead of the TFmode registers themselves,
that's why we cannot call emit_float_lib_cmp. */
void
-sparc_emit_float_lib_cmp (x, y, comparison)
- rtx x, y;
- enum rtx_code comparison;
+sparc_emit_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison)
{
const char *qpfunc;
rtx slot0, slot1, result, tem, tem2;
@@ -5815,8 +6443,7 @@ sparc_emit_float_lib_cmp (x, y, comparison)
optabs would emit if we didn't have TFmode patterns. */
void
-sparc_emit_floatunsdi (operands)
- rtx operands[2];
+sparc_emit_floatunsdi (rtx *operands)
{
rtx neglab, donelab, i0, i1, f0, in, out;
enum machine_mode mode;
@@ -5852,6 +6479,8 @@ sparc_emit_floatunsdi (operands)
operand number of the reg. OP is the conditional expression. The mode
of REG says what kind of comparison we made.
+ DEST is the destination insn (i.e. the label), INSN is the source.
+
REVERSED is nonzero if we should reverse the sense of the comparison.
ANNUL is nonzero if we should generate an annulling branch.
@@ -5859,11 +6488,8 @@ sparc_emit_floatunsdi (operands)
NOOP is nonzero if we have to follow this branch by a noop. */
char *
-output_v9branch (op, dest, reg, label, reversed, annul, noop, insn)
- rtx op, dest;
- int reg, label;
- int reversed, annul, noop;
- rtx insn;
+output_v9branch (rtx op, rtx dest, int reg, int label, int reversed,
+ int annul, int noop, rtx insn)
{
static char string[50];
enum rtx_code code = GET_CODE (op);
@@ -6003,9 +6629,7 @@ output_v9branch (op, dest, reg, label, reversed, annul, noop, insn)
*/
static int
-epilogue_renumber (where, test)
- register rtx *where;
- int test;
+epilogue_renumber (register rtx *where, int test)
{
register const char *fmt;
register int i;
@@ -6089,7 +6713,7 @@ static const int *const reg_alloc_orders[] = {
reg_nonleaf_alloc_order};
void
-order_regs_for_local_alloc ()
+order_regs_for_local_alloc (void)
{
static int last_order_nonleaf = 1;
@@ -6106,9 +6730,7 @@ order_regs_for_local_alloc ()
mem<-->reg splits to be run. */
int
-sparc_splitdi_legitimate (reg, mem)
- rtx reg;
- rtx mem;
+sparc_splitdi_legitimate (rtx reg, rtx mem)
{
/* Punt if we are here by mistake. */
if (! reload_completed)
@@ -6129,12 +6751,11 @@ sparc_splitdi_legitimate (reg, mem)
}
/* Return 1 if x and y are some kind of REG and they refer to
- different hard registers. This test is guarenteed to be
+ different hard registers. This test is guaranteed to be
run after reload. */
int
-sparc_absnegfloat_split_legitimate (x, y)
- rtx x, y;
+sparc_absnegfloat_split_legitimate (rtx x, rtx y)
{
if (GET_CODE (x) != REG)
return 0;
@@ -6151,8 +6772,7 @@ sparc_absnegfloat_split_legitimate (x, y)
Note reg1 and reg2 *must* be hard registers. */
int
-registers_ok_for_ldd_peep (reg1, reg2)
- rtx reg1, reg2;
+registers_ok_for_ldd_peep (rtx reg1, rtx reg2)
{
/* We might have been passed a SUBREG. */
if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
@@ -6200,12 +6820,11 @@ registers_ok_for_ldd_peep (reg1, reg2)
NULL_RTX. */
int
-mems_ok_for_ldd_peep (mem1, mem2, dependent_reg_rtx)
- rtx mem1, mem2, dependent_reg_rtx;
+mems_ok_for_ldd_peep (rtx mem1, rtx mem2, rtx dependent_reg_rtx)
{
rtx addr1, addr2;
unsigned int reg1;
- int offset1;
+ HOST_WIDE_INT offset1;
/* The mems cannot be volatile. */
if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
@@ -6275,8 +6894,7 @@ mems_ok_for_ldd_peep (mem1, mem2, dependent_reg_rtx)
ldd and std insns. */
int
-register_ok_for_ldd (reg)
- rtx reg;
+register_ok_for_ldd (rtx reg)
{
/* We might have been passed a SUBREG. */
if (GET_CODE (reg) != REG)
@@ -6293,10 +6911,7 @@ register_ok_for_ldd (reg)
For `%' followed by punctuation, CODE is the punctuation and X is null. */
void
-print_operand (file, x, code)
- FILE *file;
- rtx x;
- int code;
+print_operand (FILE *file, rtx x, int code)
{
switch (code)
{
@@ -6331,7 +6946,11 @@ print_operand (file, x, code)
/* Print out what we are using as the frame pointer. This might
be %fp, or might be %sp+offset. */
/* ??? What if offset is too big? Perhaps the caller knows it isn't? */
- fprintf (file, "%s+%d", frame_base_name, frame_base_offset);
+ fprintf (file, "%s+"HOST_WIDE_INT_PRINT_DEC, frame_base_name, frame_base_offset);
+ return;
+ case '&':
+ /* Print some local dynamic TLS name. */
+ assemble_name (file, get_some_local_dynamic_name ());
return;
case 'Y':
/* Adjust the operand to take into account a RESTORE operation. */
@@ -6581,10 +7200,7 @@ print_operand (file, x, code)
special handling for aligned DI-mode objects. */
static bool
-sparc_assemble_integer (x, size, aligned_p)
- rtx x;
- unsigned int size;
- int aligned_p;
+sparc_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
/* ??? We only output .xword's for symbols and only then in environments
where the assembler can handle them. */
@@ -6639,8 +7255,7 @@ sparc_assemble_integer (x, size, aligned_p)
#endif
unsigned long
-sparc_type_code (type)
- register tree type;
+sparc_type_code (register tree type)
{
register unsigned long qualifiers = 0;
register unsigned shift;
@@ -6764,10 +7379,9 @@ sparc_type_code (type)
Emit enough FLUSH insns to synchronize the data and instruction caches. */
void
-sparc_initialize_trampoline (tramp, fnaddr, cxt)
- rtx tramp, fnaddr, cxt;
+sparc_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt)
{
- /* SPARC 32 bit trampoline:
+ /* SPARC 32-bit trampoline:
sethi %hi(fn), %g1
sethi %hi(static), %g2
@@ -6777,10 +7391,6 @@ sparc_initialize_trampoline (tramp, fnaddr, cxt)
SETHI i,r = 00rr rrr1 00ii iiii iiii iiii iiii iiii
JMPL r+i,d = 10dd ddd1 1100 0rrr rr1i iiii iiii iiii
*/
-#ifdef TRANSFER_FROM_TRAMPOLINE
- emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
- LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
-#endif
emit_move_insn
(gen_rtx_MEM (SImode, plus_constant (tramp, 0)),
@@ -6819,22 +7429,25 @@ sparc_initialize_trampoline (tramp, fnaddr, cxt)
&& sparc_cpu != PROCESSOR_ULTRASPARC3)
emit_insn (gen_flush (validize_mem (gen_rtx_MEM (SImode,
plus_constant (tramp, 8)))));
+
+ /* Call __enable_execute_stack after writing onto the stack to make sure
+ the stack address is accessible. */
+#ifdef ENABLE_EXECUTE_STACK
+ emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
+ LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
+#endif
+
}
-/* The 64 bit version is simpler because it makes more sense to load the
+/* The 64-bit version is simpler because it makes more sense to load the
values as "immediate" data out of the trampoline. It's also easier since
we can read the PC without clobbering a register. */
void
-sparc64_initialize_trampoline (tramp, fnaddr, cxt)
- rtx tramp, fnaddr, cxt;
+sparc64_initialize_trampoline (rtx tramp, rtx fnaddr, rtx cxt)
{
-#ifdef TRANSFER_FROM_TRAMPOLINE
- emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
- LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
-#endif
+ /* SPARC 64-bit trampoline:
- /*
rd %pc, %g1
ldx [%g1+24], %g5
jmp %g5
@@ -6857,6 +7470,13 @@ sparc64_initialize_trampoline (tramp, fnaddr, cxt)
if (sparc_cpu != PROCESSOR_ULTRASPARC
&& sparc_cpu != PROCESSOR_ULTRASPARC3)
emit_insn (gen_flushdi (validize_mem (gen_rtx_MEM (DImode, plus_constant (tramp, 8)))));
+
+ /* Call __enable_execute_stack after writing onto the stack to make sure
+ the stack address is accessible. */
+#ifdef ENABLE_EXECUTE_STACK
+ emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"),
+ LCT_NORMAL, VOIDmode, 1, tramp, Pmode);
+#endif
}
/* Subroutines to support a flat (single) register window calling
@@ -6925,16 +7545,16 @@ sparc64_initialize_trampoline (tramp, fnaddr, cxt)
struct sparc_frame_info
{
- unsigned long total_size; /* # bytes that the entire frame takes up. */
- unsigned long var_size; /* # bytes that variables take up. */
- unsigned long args_size; /* # bytes that outgoing arguments take up. */
- unsigned long extra_size; /* # bytes of extra gunk. */
- unsigned int gp_reg_size; /* # bytes needed to store gp regs. */
- unsigned int fp_reg_size; /* # bytes needed to store fp regs. */
+ HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
+ HOST_WIDE_INT var_size; /* # bytes that variables take up. */
+ int args_size; /* # bytes that outgoing arguments take up. */
+ int extra_size; /* # bytes of extra gunk. */
+ int gp_reg_size; /* # bytes needed to store gp regs. */
+ int fp_reg_size; /* # bytes needed to store fp regs. */
unsigned long gmask; /* Mask of saved gp registers. */
unsigned long fmask; /* Mask of saved fp registers. */
- unsigned long reg_offset; /* Offset from new sp to store regs. */
- int initialized; /* Nonzero if frame size already calculated. */
+ int reg_offset; /* Offset from new sp to store regs. */
+ int initialized; /* Nonzero if frame size already calculated. */
};
/* Current frame information calculated by sparc_flat_compute_frame_size. */
@@ -6943,34 +7563,56 @@ struct sparc_frame_info current_frame_info;
/* Zero structure to initialize current_frame_info. */
struct sparc_frame_info zero_frame_info;
-/* Tell prologue and epilogue if register REGNO should be saved / restored. */
-
#define RETURN_ADDR_REGNUM 15
#define HARD_FRAME_POINTER_MASK (1 << (HARD_FRAME_POINTER_REGNUM))
#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
+
+/* Tell prologue and epilogue if register REGNO should be saved / restored. */
+
+static bool
+sparc_flat_must_save_register_p (int regno)
+{
+ /* General case: call-saved registers live at some point. */
+ if (!call_used_regs[regno] && regs_ever_live[regno])
+ return true;
+
+ /* Frame pointer register (%i7) if needed. */
+ if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
+ return true;
-#define MUST_SAVE_REGISTER(regno) \
- ((regs_ever_live[regno] && !call_used_regs[regno]) \
- || (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) \
- || (regno == RETURN_ADDR_REGNUM && regs_ever_live[RETURN_ADDR_REGNUM]))
+ /* PIC register (%l7) if needed. */
+ if (regno == (int) PIC_OFFSET_TABLE_REGNUM
+ && flag_pic && current_function_uses_pic_offset_table)
+ return true;
+ /* Return address register (%o7) if needed. */
+ if (regno == RETURN_ADDR_REGNUM
+ && (regs_ever_live[RETURN_ADDR_REGNUM]
+ /* When the PIC offset table is used, the PIC register
+ is set by using a bare call that clobbers %o7. */
+ || (flag_pic && current_function_uses_pic_offset_table)))
+ return true;
+
+ return false;
+}
+
/* Return the bytes needed to compute the frame pointer from the current
stack pointer. */
-unsigned long
-sparc_flat_compute_frame_size (size)
- int size; /* # of var. bytes allocated. */
+HOST_WIDE_INT
+sparc_flat_compute_frame_size (HOST_WIDE_INT size)
+ /* # of var. bytes allocated. */
{
int regno;
- unsigned long total_size; /* # bytes that the entire frame takes up. */
- unsigned long var_size; /* # bytes that variables take up. */
- unsigned long args_size; /* # bytes that outgoing arguments take up. */
- unsigned long extra_size; /* # extra bytes. */
- unsigned int gp_reg_size; /* # bytes needed to store gp regs. */
- unsigned int fp_reg_size; /* # bytes needed to store fp regs. */
+ HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */
+ HOST_WIDE_INT var_size; /* # bytes that variables take up. */
+ int args_size; /* # bytes that outgoing arguments take up. */
+ int extra_size; /* # extra bytes. */
+ int gp_reg_size; /* # bytes needed to store gp regs. */
+ int fp_reg_size; /* # bytes needed to store fp regs. */
unsigned long gmask; /* Mask of saved gp registers. */
unsigned long fmask; /* Mask of saved fp registers. */
- unsigned long reg_offset; /* Offset to register save area. */
+ int reg_offset; /* Offset to register save area. */
int need_aligned_p; /* 1 if need the save area 8 byte aligned. */
/* This is the size of the 16 word reg save area, 1 word struct addr
@@ -6995,11 +7637,11 @@ sparc_flat_compute_frame_size (size)
/* Calculate space needed for gp registers. */
for (regno = 1; regno <= 31; regno++)
{
- if (MUST_SAVE_REGISTER (regno))
+ if (sparc_flat_must_save_register_p (regno))
{
/* If we need to save two regs in a row, ensure there's room to bump
up the address to align it to a doubleword boundary. */
- if ((regno & 0x1) == 0 && MUST_SAVE_REGISTER (regno+1))
+ if ((regno & 0x1) == 0 && sparc_flat_must_save_register_p (regno+1))
{
if (gp_reg_size % 8 != 0)
gp_reg_size += 4;
@@ -7076,17 +7718,11 @@ sparc_flat_compute_frame_size (size)
WORD_OP is either "st" for save, "ld" for restore.
DOUBLEWORD_OP is either "std" for save, "ldd" for restore. */
-void
-sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op,
- doubleword_op, base_offset)
- FILE *file;
- const char *base_reg;
- unsigned int offset;
- unsigned long gmask;
- unsigned long fmask;
- const char *word_op;
- const char *doubleword_op;
- unsigned long base_offset;
+static void
+sparc_flat_save_restore (FILE *file, const char *base_reg, int offset,
+ unsigned long gmask, unsigned long fmask,
+ const char *word_op, const char *doubleword_op,
+ HOST_WIDE_INT base_offset)
{
int regno;
@@ -7181,9 +7817,7 @@ sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op,
/* Set up the stack and frame (if desired) for the function. */
static void
-sparc_flat_function_prologue (file, size)
- FILE *file;
- HOST_WIDE_INT size;
+sparc_flat_function_prologue (FILE *file, HOST_WIDE_INT size)
{
const char *sp_str = reg_names[STACK_POINTER_REGNUM];
unsigned long gmask = current_frame_info.gmask;
@@ -7192,7 +7826,8 @@ sparc_flat_function_prologue (file, size)
/* This is only for the human reader. */
fprintf (file, "\t%s#PROLOGUE# 0\n", ASM_COMMENT_START);
- fprintf (file, "\t%s# vars= %ld, regs= %d/%d, args= %d, extra= %ld\n",
+ fprintf (file, "\t%s# vars= "HOST_WIDE_INT_PRINT_DEC", "
+ "regs= %d/%d, args= %d, extra= %d\n",
ASM_COMMENT_START,
current_frame_info.var_size,
current_frame_info.gp_reg_size / 4,
@@ -7223,7 +7858,7 @@ sparc_flat_function_prologue (file, size)
after %i7 so gdb won't have to look too far to find it. */
if (size > 0)
{
- unsigned int reg_offset = current_frame_info.reg_offset;
+ int reg_offset = current_frame_info.reg_offset;
const char *const fp_str = reg_names[HARD_FRAME_POINTER_REGNUM];
static const char *const t1_str = "%g1";
@@ -7239,27 +7874,26 @@ sparc_flat_function_prologue (file, size)
the gdb folk first. */
/* Is the entire register save area offsettable from %sp? */
- if (reg_offset < 4096 - 64 * (unsigned) UNITS_PER_WORD)
+ if (reg_offset < 4096 - 64 * UNITS_PER_WORD)
{
if (size <= 4096)
{
- fprintf (file, "\tadd\t%s, %d, %s\n",
- sp_str, (int) -size, sp_str);
+ fprintf (file, "\tadd\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s\n",
+ sp_str, size, sp_str);
if (gmask & HARD_FRAME_POINTER_MASK)
{
fprintf (file, "\tst\t%s, [%s+%d]\n",
fp_str, sp_str, reg_offset);
- fprintf (file, "\tsub\t%s, %d, %s\t%s# set up frame pointer\n",
- sp_str, (int) -size, fp_str, ASM_COMMENT_START);
+ fprintf (file, "\tsub\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s"
+ "\t%s# set up frame pointer\n",
+ sp_str, size, fp_str, ASM_COMMENT_START);
reg_offset += 4;
}
}
else
{
- fprintf (file, "\tset\t");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, size);
- fprintf (file, ", %s\n\tsub\t%s, %s, %s\n",
- t1_str, sp_str, t1_str, sp_str);
+ build_big_number (file, size, t1_str);
+ fprintf (file, "\tsub\t%s, %s, %s\n", sp_str, t1_str, sp_str);
if (gmask & HARD_FRAME_POINTER_MASK)
{
fprintf (file, "\tst\t%s, [%s+%d]\n",
@@ -7297,34 +7931,40 @@ sparc_flat_function_prologue (file, size)
else
{
/* Subtract %sp in two steps, but make sure there is always a
- 64 byte register save area, and %sp is properly aligned. */
+ 64-byte register save area, and %sp is properly aligned. */
+
/* Amount to decrement %sp by, the first time. */
- unsigned HOST_WIDE_INT size1 = ((size - reg_offset + 64) + 15) & -16;
- /* Offset to register save area from %sp. */
- unsigned HOST_WIDE_INT offset = size1 - (size - reg_offset);
+ HOST_WIDE_INT size1 = ((size - reg_offset + 64) + 15) & -16;
+
+ /* Amount to decrement %sp by, the second time. */
+ HOST_WIDE_INT size2 = size - size1;
+
+ /* Offset to register save area from %sp after first decrement. */
+ int offset = (int)(size1 - (size - reg_offset));
if (size1 <= 4096)
{
- fprintf (file, "\tadd\t%s, %d, %s\n",
- sp_str, (int) -size1, sp_str);
+ fprintf (file, "\tadd\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s\n",
+ sp_str, size1, sp_str);
if (gmask & HARD_FRAME_POINTER_MASK)
{
- fprintf (file, "\tst\t%s, [%s+%d]\n\tsub\t%s, %d, %s\t%s# set up frame pointer\n",
- fp_str, sp_str, (int) offset, sp_str, (int) -size1,
+ fprintf (file, "\tst\t%s, [%s+%d]\n"
+ "\tsub\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s"
+ "\t%s# set up frame pointer\n",
+ fp_str, sp_str, offset, sp_str, size1,
fp_str, ASM_COMMENT_START);
offset += 4;
}
}
else
{
- fprintf (file, "\tset\t");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, size1);
- fprintf (file, ", %s\n\tsub\t%s, %s, %s\n",
- t1_str, sp_str, t1_str, sp_str);
+ build_big_number (file, size1, t1_str);
+ fprintf (file, "\tsub\t%s, %s, %s\n", sp_str, t1_str, sp_str);
if (gmask & HARD_FRAME_POINTER_MASK)
{
- fprintf (file, "\tst\t%s, [%s+%d]\n\tadd\t%s, %s, %s\t%s# set up frame pointer\n",
- fp_str, sp_str, (int) offset, sp_str, t1_str,
+ fprintf (file, "\tst\t%s, [%s+%d]\n"
+ "\tadd\t%s, %s, %s\t%s# set up frame pointer\n",
+ fp_str, sp_str, offset, sp_str, t1_str,
fp_str, ASM_COMMENT_START);
offset += 4;
}
@@ -7344,7 +7984,7 @@ sparc_flat_function_prologue (file, size)
if (gmask & RETURN_ADDR_MASK)
{
fprintf (file, "\tst\t%s, [%s+%d]\n",
- reg_names[RETURN_ADDR_REGNUM], sp_str, (int) offset);
+ reg_names[RETURN_ADDR_REGNUM], sp_str, offset);
if (dwarf2out_do_frame ())
/* offset - size1 == reg_offset - size
if reg_offset were updated above like offset. */
@@ -7355,10 +7995,14 @@ sparc_flat_function_prologue (file, size)
gmask & ~(HARD_FRAME_POINTER_MASK | RETURN_ADDR_MASK),
current_frame_info.fmask,
"st", "std", -size1);
- fprintf (file, "\tset\t");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, size - size1);
- fprintf (file, ", %s\n\tsub\t%s, %s, %s\n",
- t1_str, sp_str, t1_str, sp_str);
+ if (size2 <= 4096)
+ fprintf (file, "\tadd\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s\n",
+ sp_str, size2, sp_str);
+ else
+ {
+ build_big_number (file, size2, t1_str);
+ fprintf (file, "\tsub\t%s, %s, %s\n", sp_str, t1_str, sp_str);
+ }
if (dwarf2out_do_frame ())
if (! (gmask & HARD_FRAME_POINTER_MASK))
dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, size);
@@ -7372,9 +8016,7 @@ sparc_flat_function_prologue (file, size)
and regs. */
static void
-sparc_flat_function_epilogue (file, size)
- FILE *file;
- HOST_WIDE_INT size;
+sparc_flat_function_epilogue (FILE *file, HOST_WIDE_INT size)
{
rtx epilogue_delay = current_function_epilogue_delay_list;
int noepilogue = FALSE;
@@ -7406,8 +8048,8 @@ sparc_flat_function_epilogue (file, size)
if (!noepilogue)
{
- unsigned HOST_WIDE_INT reg_offset = current_frame_info.reg_offset;
- unsigned HOST_WIDE_INT size1;
+ int reg_offset = current_frame_info.reg_offset;
+ int reg_offset1;
const char *const sp_str = reg_names[STACK_POINTER_REGNUM];
const char *const fp_str = reg_names[HARD_FRAME_POINTER_REGNUM];
static const char *const t1_str = "%g1";
@@ -7416,41 +8058,43 @@ sparc_flat_function_epilogue (file, size)
slots for most of the loads, also see if we can fill the final
delay slot if not otherwise filled by the reload sequence. */
- if (size > 4095)
- {
- fprintf (file, "\tset\t");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, size);
- fprintf (file, ", %s\n", t1_str);
- }
+ if (size > 4096)
+ build_big_number (file, size, t1_str);
if (frame_pointer_needed)
{
- if (size > 4095)
+ if (size > 4096)
fprintf (file,"\tsub\t%s, %s, %s\t\t%s# sp not trusted here\n",
fp_str, t1_str, sp_str, ASM_COMMENT_START);
else
- fprintf (file,"\tsub\t%s, %d, %s\t\t%s# sp not trusted here\n",
- fp_str, (int) size, sp_str, ASM_COMMENT_START);
+ fprintf (file,"\tadd\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s"
+ "\t\t%s# sp not trusted here\n",
+ fp_str, size, sp_str, ASM_COMMENT_START);
}
/* Is the entire register save area offsettable from %sp? */
- if (reg_offset < 4096 - 64 * (unsigned) UNITS_PER_WORD)
+ if (reg_offset < 4096 - 64 * UNITS_PER_WORD)
{
- size1 = 0;
+ reg_offset1 = 0;
}
else
{
/* Restore %sp in two steps, but make sure there is always a
- 64 byte register save area, and %sp is properly aligned. */
+ 64-byte register save area, and %sp is properly aligned. */
+
/* Amount to increment %sp by, the first time. */
- size1 = ((reg_offset - 64 - 16) + 15) & -16;
+ reg_offset1 = ((reg_offset - 64 - 16) + 15) & -16;
+
/* Offset to register save area from %sp. */
- reg_offset = size1 - reg_offset;
+ reg_offset = reg_offset1 - reg_offset;
- fprintf (file, "\tset\t");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, size1);
- fprintf (file, ", %s\n\tadd\t%s, %s, %s\n",
- t1_str, sp_str, t1_str, sp_str);
+ if (reg_offset1 > 4096)
+ {
+ build_big_number (file, reg_offset1, t1_str);
+ fprintf (file, "\tadd\t%s, %s, %s\n", sp_str, t1_str, sp_str);
+ }
+ else
+ fprintf (file, "\tsub\t%s, -%d, %s\n", sp_str, reg_offset1, sp_str);
}
/* We must restore the frame pointer and return address reg first
@@ -7458,13 +8102,13 @@ sparc_flat_function_epilogue (file, size)
if (current_frame_info.gmask & HARD_FRAME_POINTER_MASK)
{
fprintf (file, "\tld\t[%s+%d], %s\n",
- sp_str, (int) reg_offset, fp_str);
+ sp_str, reg_offset, fp_str);
reg_offset += 4;
}
if (current_frame_info.gmask & RETURN_ADDR_MASK)
{
fprintf (file, "\tld\t[%s+%d], %s\n",
- sp_str, (int) reg_offset, reg_names[RETURN_ADDR_REGNUM]);
+ sp_str, reg_offset, reg_names[RETURN_ADDR_REGNUM]);
reg_offset += 4;
}
@@ -7476,15 +8120,11 @@ sparc_flat_function_epilogue (file, size)
/* If we had to increment %sp in two steps, record it so the second
restoration in the epilogue finishes up. */
- if (size1 > 0)
+ if (reg_offset1 > 0)
{
- size -= size1;
- if (size > 4095)
- {
- fprintf (file, "\tset\t");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, size);
- fprintf (file, ", %s\n", t1_str);
- }
+ size -= reg_offset1;
+ if (size > 4096)
+ build_big_number (file, size, t1_str);
}
if (current_function_returns_struct)
@@ -7501,14 +8141,15 @@ sparc_flat_function_epilogue (file, size)
{
if (size)
abort ();
- final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1);
+ final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1, NULL);
}
- else if (size > 4095)
+ else if (size > 4096)
fprintf (file, "\tadd\t%s, %s, %s\n", sp_str, t1_str, sp_str);
else if (size > 0)
- fprintf (file, "\tadd\t%s, %d, %s\n", sp_str, (int) size, sp_str);
+ fprintf (file, "\tsub\t%s, -"HOST_WIDE_INT_PRINT_DEC", %s\n",
+ sp_str, size, sp_str);
else
fprintf (file, "\tnop\n");
@@ -7526,7 +8167,7 @@ sparc_flat_function_epilogue (file, size)
or the only register saved is the return register. */
int
-sparc_flat_epilogue_delay_slots ()
+sparc_flat_epilogue_delay_slots (void)
{
if (!current_frame_info.initialized)
(void) sparc_flat_compute_frame_size (get_frame_size ());
@@ -7542,9 +8183,7 @@ sparc_flat_epilogue_delay_slots ()
pointer is OK. */
int
-sparc_flat_eligible_for_epilogue_delay (trial, slot)
- rtx trial;
- int slot ATTRIBUTE_UNUSED;
+sparc_flat_eligible_for_epilogue_delay (rtx trial, int slot ATTRIBUTE_UNUSED)
{
rtx pat = PATTERN (trial);
@@ -7562,11 +8201,7 @@ sparc_flat_eligible_for_epilogue_delay (trial, slot)
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
static int
-supersparc_adjust_cost (insn, link, dep_insn, cost)
- rtx insn;
- rtx link;
- rtx dep_insn;
- int cost;
+supersparc_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
enum attr_type insn_type;
@@ -7627,11 +8262,7 @@ supersparc_adjust_cost (insn, link, dep_insn, cost)
}
static int
-hypersparc_adjust_cost (insn, link, dep_insn, cost)
- rtx insn;
- rtx link;
- rtx dep_insn;
- int cost;
+hypersparc_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
{
enum attr_type insn_type, dep_type;
rtx pat = PATTERN(insn);
@@ -7708,11 +8339,7 @@ hypersparc_adjust_cost (insn, link, dep_insn, cost)
}
static int
-sparc_adjust_cost(insn, link, dep, cost)
- rtx insn;
- rtx link;
- rtx dep;
- int cost;
+sparc_adjust_cost(rtx insn, rtx link, rtx dep, int cost)
{
switch (sparc_cpu)
{
@@ -7730,15 +8357,14 @@ sparc_adjust_cost(insn, link, dep, cost)
}
static void
-sparc_sched_init (dump, sched_verbose, max_ready)
- FILE *dump ATTRIBUTE_UNUSED;
- int sched_verbose ATTRIBUTE_UNUSED;
- int max_ready ATTRIBUTE_UNUSED;
+sparc_sched_init (FILE *dump ATTRIBUTE_UNUSED,
+ int sched_verbose ATTRIBUTE_UNUSED,
+ int max_ready ATTRIBUTE_UNUSED)
{
}
static int
-sparc_use_dfa_pipeline_interface ()
+sparc_use_dfa_pipeline_interface (void)
{
if ((1 << sparc_cpu) &
((1 << PROCESSOR_ULTRASPARC) | (1 << PROCESSOR_CYPRESS) |
@@ -7750,7 +8376,7 @@ sparc_use_dfa_pipeline_interface ()
}
static int
-sparc_use_sched_lookahead ()
+sparc_use_sched_lookahead (void)
{
if (sparc_cpu == PROCESSOR_ULTRASPARC
|| sparc_cpu == PROCESSOR_ULTRASPARC3)
@@ -7763,7 +8389,7 @@ sparc_use_sched_lookahead ()
}
static int
-sparc_issue_rate ()
+sparc_issue_rate (void)
{
switch (sparc_cpu)
{
@@ -7784,8 +8410,7 @@ sparc_issue_rate ()
}
static int
-set_extends (insn)
- rtx insn;
+set_extends (rtx insn)
{
register rtx pat = PATTERN (insn);
@@ -7852,9 +8477,7 @@ static GTY(()) rtx sparc_addr_diff_list;
static GTY(()) rtx sparc_addr_list;
void
-sparc_defer_case_vector (lab, vec, diff)
- rtx lab, vec;
- int diff;
+sparc_defer_case_vector (rtx lab, rtx vec, int diff)
{
vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec);
if (diff)
@@ -7865,8 +8488,7 @@ sparc_defer_case_vector (lab, vec, diff)
}
static void
-sparc_output_addr_vec (vec)
- rtx vec;
+sparc_output_addr_vec (rtx vec)
{
rtx lab = XEXP (vec, 0), body = XEXP (vec, 1);
int idx, vlen = XVECLEN (body, 0);
@@ -7879,7 +8501,7 @@ sparc_output_addr_vec (vec)
ASM_OUTPUT_CASE_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (lab),
NEXT_INSN (lab));
#else
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
+ (*targetm.asm_out.internal_label) (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
#endif
for (idx = 0; idx < vlen; idx++)
@@ -7894,8 +8516,7 @@ sparc_output_addr_vec (vec)
}
static void
-sparc_output_addr_diff_vec (vec)
- rtx vec;
+sparc_output_addr_diff_vec (rtx vec)
{
rtx lab = XEXP (vec, 0), body = XEXP (vec, 1);
rtx base = XEXP (XEXP (body, 0), 0);
@@ -7909,7 +8530,7 @@ sparc_output_addr_diff_vec (vec)
ASM_OUTPUT_CASE_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (lab),
NEXT_INSN (lab));
#else
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
+ (*targetm.asm_out.internal_label) (asm_out_file, "L", CODE_LABEL_NUMBER (lab));
#endif
for (idx = 0; idx < vlen; idx++)
@@ -7927,7 +8548,7 @@ sparc_output_addr_diff_vec (vec)
}
static void
-sparc_output_deferred_case_vectors ()
+sparc_output_deferred_case_vectors (void)
{
rtx t;
int align;
@@ -7955,8 +8576,7 @@ sparc_output_deferred_case_vectors ()
unknown. Return 1 if the high bits are zero, -1 if the register is
sign extended. */
int
-sparc_check_64 (x, insn)
- rtx x, insn;
+sparc_check_64 (rtx x, rtx insn)
{
/* If a register is set only once it is safe to ignore insns this
code does not know how to handle. The loop will either recognize
@@ -8016,10 +8636,7 @@ sparc_check_64 (x, insn)
/* Returns assembly code to perform a DImode shift using
a 64-bit global or out register on SPARC-V8+. */
char *
-sparc_v8plus_shift (operands, insn, opcode)
- rtx *operands;
- rtx insn;
- const char *opcode;
+sparc_v8plus_shift (rtx *operands, rtx insn, const char *opcode)
{
static char asm_code[60];
@@ -8056,8 +8673,7 @@ sparc_v8plus_shift (operands, insn, opcode)
for profiling a function entry. */
void
-sparc_profile_hook (labelno)
- int labelno;
+sparc_profile_hook (int labelno)
{
char buf[32];
rtx lab, fun;
@@ -8071,9 +8687,7 @@ sparc_profile_hook (labelno)
#ifdef OBJECT_FORMAT_ELF
static void
-sparc_elf_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+sparc_elf_asm_named_section (const char *name, unsigned int flags)
{
if (flags & SECTION_MERGE)
{
@@ -8089,6 +8703,8 @@ sparc_elf_asm_named_section (name, flags)
fputs (",#alloc", asm_out_file);
if (flags & SECTION_WRITE)
fputs (",#write", asm_out_file);
+ if (flags & SECTION_TLS)
+ fputs (",#tls", asm_out_file);
if (flags & SECTION_CODE)
fputs (",#execinstr", asm_out_file);
@@ -8098,15 +8714,133 @@ sparc_elf_asm_named_section (name, flags)
}
#endif /* OBJECT_FORMAT_ELF */
+/* We do not allow sibling calls if -mflat, nor
+ we do not allow indirect calls to be optimized into sibling calls.
+
+ Also, on sparc 32-bit we cannot emit a sibling call when the
+ current function returns a structure. This is because the "unimp
+ after call" convention would cause the callee to return to the
+ wrong place. The generic code already disallows cases where the
+ function being called returns a structure.
+
+ It may seem strange how this last case could occur. Usually there
+ is code after the call which jumps to epilogue code which dumps the
+ return value into the struct return area. That ought to invalidate
+ the sibling call right? Well, in the c++ case we can end up passing
+ the pointer to the struct return area to a constructor (which returns
+ void) and then nothing else happens. Such a sibling call would look
+ valid without the added check here. */
+static bool
+sparc_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
+{
+ return (decl
+ && ! TARGET_FLAT
+ && (TARGET_ARCH64 || ! current_function_returns_struct));
+}
+
+/* libfunc renaming. */
+#include "config/gofast.h"
+
+static void
+sparc_init_libfuncs (void)
+{
+ if (TARGET_ARCH32)
+ {
+ /* Use the subroutines that Sun's library provides for integer
+ multiply and divide. The `*' prevents an underscore from
+ being prepended by the compiler. .umul is a little faster
+ than .mul. */
+ set_optab_libfunc (smul_optab, SImode, "*.umul");
+ set_optab_libfunc (sdiv_optab, SImode, "*.div");
+ set_optab_libfunc (udiv_optab, SImode, "*.udiv");
+ set_optab_libfunc (smod_optab, SImode, "*.rem");
+ set_optab_libfunc (umod_optab, SImode, "*.urem");
+
+ /* TFmode arithmetic. These names are part of the SPARC 32bit ABI. */
+ set_optab_libfunc (add_optab, TFmode, "_Q_add");
+ set_optab_libfunc (sub_optab, TFmode, "_Q_sub");
+ set_optab_libfunc (neg_optab, TFmode, "_Q_neg");
+ set_optab_libfunc (smul_optab, TFmode, "_Q_mul");
+ set_optab_libfunc (sdiv_optab, TFmode, "_Q_div");
+
+ /* We can define the TFmode sqrt optab only if TARGET_FPU. This
+ is because with soft-float, the SFmode and DFmode sqrt
+ instructions will be absent, and the compiler will notice and
+ try to use the TFmode sqrt instruction for calls to the
+ builtin function sqrt, but this fails. */
+ if (TARGET_FPU)
+ set_optab_libfunc (sqrt_optab, TFmode, "_Q_sqrt");
+
+ set_optab_libfunc (eq_optab, TFmode, "_Q_feq");
+ set_optab_libfunc (ne_optab, TFmode, "_Q_fne");
+ set_optab_libfunc (gt_optab, TFmode, "_Q_fgt");
+ set_optab_libfunc (ge_optab, TFmode, "_Q_fge");
+ set_optab_libfunc (lt_optab, TFmode, "_Q_flt");
+ set_optab_libfunc (le_optab, TFmode, "_Q_fle");
+
+ set_conv_libfunc (sext_optab, TFmode, SFmode, "_Q_stoq");
+ set_conv_libfunc (sext_optab, TFmode, DFmode, "_Q_dtoq");
+ set_conv_libfunc (trunc_optab, SFmode, TFmode, "_Q_qtos");
+ set_conv_libfunc (trunc_optab, DFmode, TFmode, "_Q_qtod");
+
+ set_conv_libfunc (sfix_optab, SImode, TFmode, "_Q_qtoi");
+ set_conv_libfunc (ufix_optab, SImode, TFmode, "_Q_qtou");
+ set_conv_libfunc (sfloat_optab, TFmode, SImode, "_Q_itoq");
+
+ if (DITF_CONVERSION_LIBFUNCS)
+ {
+ set_conv_libfunc (sfix_optab, DImode, TFmode, "_Q_qtoll");
+ set_conv_libfunc (ufix_optab, DImode, TFmode, "_Q_qtoull");
+ set_conv_libfunc (sfloat_optab, TFmode, DImode, "_Q_lltoq");
+ }
+
+ if (SUN_CONVERSION_LIBFUNCS)
+ {
+ set_conv_libfunc (sfix_optab, DImode, SFmode, "__ftoll");
+ set_conv_libfunc (ufix_optab, DImode, SFmode, "__ftoull");
+ set_conv_libfunc (sfix_optab, DImode, DFmode, "__dtoll");
+ set_conv_libfunc (ufix_optab, DImode, DFmode, "__dtoull");
+ }
+ }
+ if (TARGET_ARCH64)
+ {
+ /* In the SPARC 64bit ABI, SImode multiply and divide functions
+ do not exist in the library. Make sure the compiler does not
+ emit calls to them by accident. (It should always use the
+ hardware instructions.) */
+ set_optab_libfunc (smul_optab, SImode, 0);
+ set_optab_libfunc (sdiv_optab, SImode, 0);
+ set_optab_libfunc (udiv_optab, SImode, 0);
+ set_optab_libfunc (smod_optab, SImode, 0);
+ set_optab_libfunc (umod_optab, SImode, 0);
+
+ if (SUN_INTEGER_MULTIPLY_64)
+ {
+ set_optab_libfunc (smul_optab, DImode, "__mul64");
+ set_optab_libfunc (sdiv_optab, DImode, "__div64");
+ set_optab_libfunc (udiv_optab, DImode, "__udiv64");
+ set_optab_libfunc (smod_optab, DImode, "__rem64");
+ set_optab_libfunc (umod_optab, DImode, "__urem64");
+ }
+
+ if (SUN_CONVERSION_LIBFUNCS)
+ {
+ set_conv_libfunc (sfix_optab, DImode, SFmode, "__ftol");
+ set_conv_libfunc (ufix_optab, DImode, SFmode, "__ftoul");
+ set_conv_libfunc (sfix_optab, DImode, DFmode, "__dtol");
+ set_conv_libfunc (ufix_optab, DImode, DFmode, "__dtoul");
+ }
+ }
+
+ gofast_maybe_init_libfuncs ();
+}
+
/* ??? Similar to the standard section selection, but force reloc-y-ness
if SUNOS4_SHARED_LIBRARIES. Unclear why this helps (as opposed to
pretending PIC always on), but that's what the old code did. */
static void
-sparc_aout_select_section (t, reloc, align)
- tree t;
- int reloc;
- unsigned HOST_WIDE_INT align;
+sparc_aout_select_section (tree t, int reloc, unsigned HOST_WIDE_INT align)
{
default_select_section (t, reloc | SUNOS4_SHARED_LIBRARIES, align);
}
@@ -8115,10 +8849,8 @@ sparc_aout_select_section (t, reloc, align)
that offers. */
static void
-sparc_aout_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align;
+sparc_aout_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align)
{
if (align <= MAX_TEXT_ALIGN
&& ! (flag_pic && (symbolic_operand (x, mode)
@@ -8129,10 +8861,7 @@ sparc_aout_select_rtx_section (mode, x, align)
}
int
-sparc_extra_constraint_check (op, c, strict)
- rtx op;
- int c;
- int strict;
+sparc_extra_constraint_check (rtx op, int c, int strict)
{
int reload_ok_mem;
@@ -8194,10 +8923,8 @@ sparc_extra_constraint_check (op, c, strict)
??? scheduler description. Some day, teach genautomata to output
??? the latencies and then CSE will just use that. */
-int
-sparc_rtx_costs (x, code, outer_code)
- rtx x;
- enum rtx_code code, outer_code;
+static bool
+sparc_rtx_costs (rtx x, int code, int outer_code, int *total)
{
switch (code)
{
@@ -8211,50 +8938,61 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
case PROCESSOR_ULTRASPARC3:
- return COSTS_N_INSNS (4);
+ *total = COSTS_N_INSNS (4);
+ return true;
case PROCESSOR_SUPERSPARC:
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
+ return true;
case PROCESSOR_CYPRESS:
- return COSTS_N_INSNS (5);
+ *total = COSTS_N_INSNS (5);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
default:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
}
}
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
case SQRT:
switch (sparc_cpu)
{
case PROCESSOR_ULTRASPARC:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (13);
+ *total = COSTS_N_INSNS (13);
else
- return COSTS_N_INSNS (23);
+ *total = COSTS_N_INSNS (23);
+ return true;
case PROCESSOR_ULTRASPARC3:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (20);
+ *total = COSTS_N_INSNS (20);
else
- return COSTS_N_INSNS (29);
+ *total = COSTS_N_INSNS (29);
+ return true;
case PROCESSOR_SUPERSPARC:
- return COSTS_N_INSNS (12);
+ *total = COSTS_N_INSNS (12);
+ return true;
case PROCESSOR_CYPRESS:
- return COSTS_N_INSNS (63);
+ *total = COSTS_N_INSNS (63);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
- return COSTS_N_INSNS (17);
+ *total = COSTS_N_INSNS (17);
+ return true;
default:
- return COSTS_N_INSNS (30);
+ *total = COSTS_N_INSNS (30);
+ return true;
}
case COMPARE:
@@ -8264,18 +9002,22 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
case PROCESSOR_ULTRASPARC3:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
case PROCESSOR_SUPERSPARC:
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
+ return true;
case PROCESSOR_CYPRESS:
- return COSTS_N_INSNS (5);
+ *total = COSTS_N_INSNS (5);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
default:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
}
}
@@ -8283,7 +9025,8 @@ sparc_rtx_costs (x, code, outer_code)
??? all UltraSPARC processors because the result
??? can be bypassed to a branch in the same group. */
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
case MULT:
if (FLOAT_MODE_P (GET_MODE (x)))
@@ -8292,20 +9035,25 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
case PROCESSOR_ULTRASPARC3:
- return COSTS_N_INSNS (4);
+ *total = COSTS_N_INSNS (4);
+ return true;
case PROCESSOR_SUPERSPARC:
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
+ return true;
case PROCESSOR_CYPRESS:
- return COSTS_N_INSNS (7);
+ *total = COSTS_N_INSNS (7);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
default:
- return COSTS_N_INSNS (5);
+ *total = COSTS_N_INSNS (5);
+ return true;
}
}
@@ -8342,20 +9090,28 @@ sparc_rtx_costs (x, code, outer_code)
Since we do not play any such tricks currently the
safest thing to do is report the worst case latency. */
if (sparc_cpu == PROCESSOR_ULTRASPARC)
- return (GET_MODE (x) == DImode ?
- COSTS_N_INSNS (34) : COSTS_N_INSNS (19));
+ {
+ *total = (GET_MODE (x) == DImode
+ ? COSTS_N_INSNS (34) : COSTS_N_INSNS (19));
+ return true;
+ }
/* Multiply latency on Ultra-III, fortunately, is constant. */
if (sparc_cpu == PROCESSOR_ULTRASPARC3)
- return COSTS_N_INSNS (6);
+ {
+ *total = COSTS_N_INSNS (6);
+ return true;
+ }
if (sparc_cpu == PROCESSOR_HYPERSPARC
|| sparc_cpu == PROCESSOR_SPARCLITE86X)
- return COSTS_N_INSNS (17);
+ {
+ *total = COSTS_N_INSNS (17);
+ return true;
+ }
- return (TARGET_HARD_MUL
- ? COSTS_N_INSNS (5)
- : COSTS_N_INSNS (25));
+ *total = (TARGET_HARD_MUL ? COSTS_N_INSNS (5) : COSTS_N_INSNS (25));
+ return true;
case DIV:
case UDIV:
@@ -8367,57 +9123,67 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (13);
+ *total = COSTS_N_INSNS (13);
else
- return COSTS_N_INSNS (23);
+ *total = COSTS_N_INSNS (23);
+ return true;
case PROCESSOR_ULTRASPARC3:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (17);
+ *total = COSTS_N_INSNS (17);
else
- return COSTS_N_INSNS (20);
+ *total = COSTS_N_INSNS (20);
+ return true;
case PROCESSOR_SUPERSPARC:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (6);
+ *total = COSTS_N_INSNS (6);
else
- return COSTS_N_INSNS (9);
+ *total = COSTS_N_INSNS (9);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
if (GET_MODE (x) == SFmode)
- return COSTS_N_INSNS (8);
+ *total = COSTS_N_INSNS (8);
else
- return COSTS_N_INSNS (12);
+ *total = COSTS_N_INSNS (12);
+ return true;
default:
- return COSTS_N_INSNS (7);
+ *total = COSTS_N_INSNS (7);
+ return true;
}
}
if (sparc_cpu == PROCESSOR_ULTRASPARC)
- return (GET_MODE (x) == DImode ?
- COSTS_N_INSNS (68) : COSTS_N_INSNS (37));
- if (sparc_cpu == PROCESSOR_ULTRASPARC3)
- return (GET_MODE (x) == DImode ?
- COSTS_N_INSNS (71) : COSTS_N_INSNS (40));
- return COSTS_N_INSNS (25);
+ *total = (GET_MODE (x) == DImode
+ ? COSTS_N_INSNS (68) : COSTS_N_INSNS (37));
+ else if (sparc_cpu == PROCESSOR_ULTRASPARC3)
+ *total = (GET_MODE (x) == DImode
+ ? COSTS_N_INSNS (71) : COSTS_N_INSNS (40));
+ else
+ *total = COSTS_N_INSNS (25);
+ return true;
case IF_THEN_ELSE:
/* Conditional moves. */
switch (sparc_cpu)
{
case PROCESSOR_ULTRASPARC:
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
+ return true;
case PROCESSOR_ULTRASPARC3:
if (FLOAT_MODE_P (GET_MODE (x)))
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
else
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
+ return true;
default:
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
}
case MEM:
@@ -8428,9 +9194,10 @@ sparc_rtx_costs (x, code, outer_code)
{
case PROCESSOR_ULTRASPARC:
if (outer_code == ZERO_EXTEND)
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
else
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
+ return true;
case PROCESSOR_ULTRASPARC3:
if (outer_code == ZERO_EXTEND)
@@ -8438,112 +9205,110 @@ sparc_rtx_costs (x, code, outer_code)
if (GET_MODE (x) == QImode
|| GET_MODE (x) == HImode
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
else
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
}
else
{
/* This handles sign extension (3 cycles)
and everything else (2 cycles). */
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
}
+ return true;
case PROCESSOR_SUPERSPARC:
if (FLOAT_MODE_P (GET_MODE (x))
|| outer_code == ZERO_EXTEND
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (0);
+ *total = COSTS_N_INSNS (0);
else
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
case PROCESSOR_TSC701:
if (outer_code == ZERO_EXTEND
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
else
- return COSTS_N_INSNS (3);
+ *total = COSTS_N_INSNS (3);
+ return true;
case PROCESSOR_CYPRESS:
if (outer_code == ZERO_EXTEND
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
else
- return COSTS_N_INSNS (2);
+ *total = COSTS_N_INSNS (2);
+ return true;
case PROCESSOR_HYPERSPARC:
case PROCESSOR_SPARCLITE86X:
default:
if (outer_code == ZERO_EXTEND
|| outer_code == SIGN_EXTEND)
- return COSTS_N_INSNS (0);
+ *total = COSTS_N_INSNS (0);
else
- return COSTS_N_INSNS (1);
+ *total = COSTS_N_INSNS (1);
+ return true;
}
case CONST_INT:
if (INTVAL (x) < 0x1000 && INTVAL (x) >= -0x1000)
- return 0;
+ {
+ *total = 0;
+ return true;
+ }
+ /* FALLTHRU */
- /* fallthru */
case HIGH:
- return 2;
+ *total = 2;
+ return true;
case CONST:
case LABEL_REF:
case SYMBOL_REF:
- return 4;
+ *total = 4;
+ return true;
case CONST_DOUBLE:
- if (GET_MODE (x) == DImode)
- if ((XINT (x, 3) == 0
- && (unsigned) XINT (x, 2) < 0x1000)
- || (XINT (x, 3) == -1
- && XINT (x, 2) < 0
- && XINT (x, 2) >= -0x1000))
- return 0;
- return 8;
+ if (GET_MODE (x) == DImode
+ && ((XINT (x, 3) == 0
+ && (unsigned HOST_WIDE_INT) XINT (x, 2) < 0x1000)
+ || (XINT (x, 3) == -1
+ && XINT (x, 2) < 0
+ && XINT (x, 2) >= -0x1000)))
+ *total = 0;
+ else
+ *total = 8;
+ return true;
default:
- abort();
- };
-}
-
-/* If we are referencing a function make the SYMBOL_REF special. In
- the Embedded Medium/Anywhere code model, %g4 points to the data
- segment so we must not add it to function addresses. */
-
-static void
-sparc_encode_section_info (decl, first)
- tree decl;
- int first ATTRIBUTE_UNUSED;
-{
- if (TARGET_CM_EMBMEDANY && TREE_CODE (decl) == FUNCTION_DECL)
- SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
+ return false;
+ }
}
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
Used for C++ multiple inheritance. */
static void
-sparc_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
- FILE *file;
- tree thunk_fndecl ATTRIBUTE_UNUSED;
- HOST_WIDE_INT delta;
- HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
- tree function;
+sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
+ tree function)
{
rtx this, insn, funexp, delta_rtx, tmp;
reload_completed = 1;
+ epilogue_completed = 1;
no_new_pseudos = 1;
current_function_uses_only_leaf_regs = 1;
- emit_note (NULL, NOTE_INSN_PROLOGUE_END);
+ emit_note (NOTE_INSN_PROLOGUE_END);
/* Find the "this" pointer. Normally in %o0, but in ARCH64 if the function
returns a structure, the structure return pointer is there instead. */
- if (TARGET_ARCH64 && aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
+ if (TARGET_ARCH64 && aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
this = gen_rtx_REG (Pmode, SPARC_INCOMING_INT_ARG_FIRST + 1);
else
this = gen_rtx_REG (Pmode, SPARC_INCOMING_INT_ARG_FIRST);
@@ -8554,10 +9319,17 @@ sparc_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
if (!SPARC_SIMM13_P (delta))
{
rtx scratch = gen_rtx_REG (Pmode, 1);
- if (TARGET_ARCH64)
- sparc_emit_set_const64 (scratch, delta_rtx);
+
+ if (input_operand (delta_rtx, GET_MODE (scratch)))
+ emit_insn (gen_rtx_SET (VOIDmode, scratch, delta_rtx));
else
- sparc_emit_set_const32 (scratch, delta_rtx);
+ {
+ if (TARGET_ARCH64)
+ sparc_emit_set_const64 (scratch, delta_rtx);
+ else
+ sparc_emit_set_const32 (scratch, delta_rtx);
+ }
+
delta_rtx = scratch;
}
@@ -8581,13 +9353,79 @@ sparc_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
instruction scheduling worth while. Note that use_thunk calls
assemble_start_function and assemble_end_function. */
insn = get_insns ();
+ insn_locators_initialize ();
shorten_branches (insn);
final_start_function (insn, file, 1);
final (insn, file, 1, 0);
final_end_function ();
reload_completed = 0;
+ epilogue_completed = 0;
no_new_pseudos = 0;
}
+/* How to allocate a 'struct machine_function'. */
+
+static struct machine_function *
+sparc_init_machine_status (void)
+{
+ return ggc_alloc_cleared (sizeof (struct machine_function));
+}
+
+/* Locate some local-dynamic symbol still in use by this function
+ so that we can print its name in local-dynamic base patterns. */
+
+static const char *
+get_some_local_dynamic_name (void)
+{
+ rtx insn;
+
+ if (cfun->machine->some_ld_name)
+ return cfun->machine->some_ld_name;
+
+ for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
+ if (INSN_P (insn)
+ && for_each_rtx (&PATTERN (insn), get_some_local_dynamic_name_1, 0))
+ return cfun->machine->some_ld_name;
+
+ abort ();
+}
+
+static int
+get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
+{
+ rtx x = *px;
+
+ if (x
+ && GET_CODE (x) == SYMBOL_REF
+ && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
+ {
+ cfun->machine->some_ld_name = XSTR (x, 0);
+ return 1;
+ }
+
+ return 0;
+}
+
+/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
+ We need to emit DTP-relative relocations. */
+
+void
+sparc_output_dwarf_dtprel (FILE *file, int size, rtx x)
+{
+ switch (size)
+ {
+ case 4:
+ fputs ("\t.word\t%r_tls_dtpoff32(", file);
+ break;
+ case 8:
+ fputs ("\t.xword\t%r_tls_dtpoff64(", file);
+ break;
+ default:
+ abort ();
+ }
+ output_addr_const (file, x);
+ fputs (")", file);
+}
+
#include "gt-sparc.h"
diff --git a/contrib/gcc/config/sparc/sparc.h b/contrib/gcc/config/sparc/sparc.h
index 7c6a7fd1d72b..3202359755f9 100644
--- a/contrib/gcc/config/sparc/sparc.h
+++ b/contrib/gcc/config/sparc/sparc.h
@@ -1,30 +1,50 @@
/* Definitions of target machine for GNU compiler, for Sun SPARC.
Copyright (C) 1987, 1988, 1989, 1992, 1994, 1995, 1996, 1997, 1998, 1999
- 2000, 2001, 2002 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
- 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
+ 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
at Cygnus Support.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Note that some other tm.h files include this one and then override
whatever definitions are necessary. */
+/* Target CPU builtins. FIXME: Defining sparc is for the benefit of
+ Solaris only; otherwise just define __sparc__. Sadly the headers
+ are such a mess there is no Solaris-specific header. */
+#define TARGET_CPU_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("sparc"); \
+ if (TARGET_64BIT) \
+ { \
+ builtin_assert ("cpu=sparc64"); \
+ builtin_assert ("machine=sparc64"); \
+ } \
+ else \
+ { \
+ builtin_assert ("cpu=sparc"); \
+ builtin_assert ("machine=sparc"); \
+ } \
+ } \
+ while (0)
+
/* Specify this in a cover file to provide bi-architecture (32/64) support. */
/* #define SPARC_BI_ARCH */
@@ -49,35 +69,41 @@ Boston, MA 02111-1307, USA. */
#endif /* IN_LIBGCC2 */
#define TARGET_ARCH64 (! TARGET_ARCH32)
-/* Code model selection.
- -mcmodel is used to select the v9 code model.
- Different code models aren't supported for v7/8 code.
-
- TARGET_CM_32: 32 bit address space, top 32 bits = 0,
- pointers are 32 bits. Note that this isn't intended
- to imply a v7/8 abi.
-
- TARGET_CM_MEDLOW: 32 bit address space, top 32 bits = 0,
- avoid generating %uhi and %ulo terms,
- pointers are 64 bits.
-
- TARGET_CM_MEDMID: 64 bit address space.
- The executable must be in the low 16 TB of memory.
- This corresponds to the low 44 bits, and the %[hml]44
- relocs are used. The text segment has a maximum size
- of 31 bits.
-
- TARGET_CM_MEDANY: 64 bit address space.
- The text and data segments have a maximum size of 31
- bits and may be located anywhere. The maximum offset
- from any instruction to the label _GLOBAL_OFFSET_TABLE_
- is 31 bits.
-
- TARGET_CM_EMBMEDANY: 64 bit address space.
- The text and data segments have a maximum size of 31 bits
- and may be located anywhere. Register %g4 contains
- the start address of the data segment.
-*/
+/* Code model selection in 64-bit environment.
+
+ The machine mode used for addresses is 32-bit wide:
+
+ TARGET_CM_32: 32-bit address space.
+ It is the code model used when generating 32-bit code.
+
+ The machine mode used for addresses is 64-bit wide:
+
+ TARGET_CM_MEDLOW: 32-bit address space.
+ The executable must be in the low 32 bits of memory.
+ This avoids generating %uhi and %ulo terms. Programs
+ can be statically or dynamically linked.
+
+ TARGET_CM_MEDMID: 44-bit address space.
+ The executable must be in the low 44 bits of memory,
+ and the %[hml]44 terms are used. The text and data
+ segments have a maximum size of 2GB (31-bit span).
+ The maximum offset from any instruction to the label
+ _GLOBAL_OFFSET_TABLE_ is 2GB (31-bit span).
+
+ TARGET_CM_MEDANY: 64-bit address space.
+ The text and data segments have a maximum size of 2GB
+ (31-bit span) and may be located anywhere in memory.
+ The maximum offset from any instruction to the label
+ _GLOBAL_OFFSET_TABLE_ is 2GB (31-bit span).
+
+ TARGET_CM_EMBMEDANY: 64-bit address space.
+ The text and data segments have a maximum size of 2GB
+ (31-bit span) and may be located anywhere in memory.
+ The global register %g4 contains the start address of
+ the data segment. Programs are statically linked and
+ PIC is not supported.
+
+ Different code models are not supported in 32-bit environment. */
enum cmodel {
CM_32,
@@ -239,15 +265,8 @@ extern enum cmodel sparc_cmodel;
%{mcpu=ultrasparc3:-D__sparc_v9__} \
%{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \
"
-
-/* ??? The GCC_NEW_VARARGS macro is now obsolete, because gcc always uses
- the right varags.h file when bootstrapping. */
-/* ??? It's not clear what value we want to use for -Acpu/machine for
- sparc64 in 32 bit environments, so for now we only use `sparc64' in
- 64 bit environments. */
-
-#define CPP_ARCH32_SPEC "-D__GCC_NEW_VARARGS__ -Acpu=sparc -Amachine=sparc"
-#define CPP_ARCH64_SPEC "-D__arch64__ -Acpu=sparc64 -Amachine=sparc64"
+#define CPP_ARCH32_SPEC ""
+#define CPP_ARCH64_SPEC "-D__arch64__"
#define CPP_ARCH_DEFAULT_SPEC \
(DEFAULT_ARCH32_P ? CPP_ARCH32_SPEC : CPP_ARCH64_SPEC)
@@ -323,15 +342,17 @@ extern enum cmodel sparc_cmodel;
/* Special flags to the Sun-4 assembler when using pipe for input. */
#define ASM_SPEC "\
-%| %{R} %{!pg:%{!p:%{fpic:-k} %{fPIC:-k}}} %{keep-local-as-symbols:-L} \
+%{R} %{!pg:%{!p:%{fpic|fPIC|fpie|fPIE:-k}}} %{keep-local-as-symbols:-L} \
%(asm_cpu) %(asm_relax)"
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
+
/* This macro defines names of additional specifications to put in the specs
that can be used in various specifications like CC1_SPEC. Its definition
is an initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
- specification name, and a string constant that used by the GNU CC driver
+ specification name, and a string constant that used by the GCC driver
program.
Do not define this macro if it does not need to do anything. */
@@ -630,17 +651,27 @@ extern enum processor_type sparc_cpu;
#define TARGET_OPTIONS \
{ \
{ "cpu=", &sparc_select[1].string, \
- N_("Use features of and schedule code for given CPU") }, \
+ N_("Use features of and schedule code for given CPU"), 0}, \
{ "tune=", &sparc_select[2].string, \
- N_("Schedule code for given CPU") }, \
+ N_("Schedule code for given CPU"), 0}, \
{ "cmodel=", &sparc_cmodel_string, \
- N_("Use given SPARC code model") }, \
+ N_("Use given SPARC code model"), 0}, \
SUBTARGET_OPTIONS \
}
/* This is meant to be redefined in target specific files. */
#define SUBTARGET_OPTIONS
+/* Support for a compile-time default CPU, et cetera. The rules are:
+ --with-cpu is ignored if -mcpu is specified.
+ --with-tune is ignored if -mtune is specified.
+ --with-float is ignored if -mhard-float, -msoft-float, -mfpu, or -mno-fpu
+ are specified. */
+#define OPTION_DEFAULT_SPECS \
+ {"cpu", "%{!mcpu=*:-mcpu=%(VALUE)}" }, \
+ {"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
+ {"float", "%{!msoft-float:%{!mhard-float:%{!fpu:%{!no-fpu:-m%(VALUE)-float}}}}" }
+
/* sparc_select[0] is reserved for the default cpu. */
struct sparc_cpu_select
{
@@ -755,7 +786,13 @@ if (TARGET_ARCH64 \
#define PARM_BOUNDARY (TARGET_ARCH64 ? 64 : 32)
/* Boundary (in *bits*) on which stack pointer should be aligned. */
+/* FIXME, this is wrong when TARGET_ARCH64 and TARGET_STACK_BIAS, because
+ then sp+2047 is 128-bit aligned so sp is really only byte-aligned. */
#define STACK_BOUNDARY (TARGET_ARCH64 ? 128 : 64)
+/* Temporary hack until the FIXME above is fixed. This macro is used
+ only in pad_to_arg_alignment in function.c; see the comment there
+ for details about what it does. */
+#define SPARC_STACK_BOUNDARY_HACK (TARGET_ARCH64 && TARGET_STACK_BIAS)
/* ALIGN FRAMES on double word boundaries */
@@ -1018,7 +1055,7 @@ while (0)
: (GET_MODE_SIZE (MODE) + 3) / 4) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-/* Due to the ARCH64 descrepancy above we must override this next
+/* Due to the ARCH64 discrepancy above we must override this next
macro too. */
#define REGMODE_NATURAL_SIZE(MODE) \
((TARGET_ARCH64 && FLOAT_MODE_P (MODE)) ? 4 : UNITS_PER_WORD)
@@ -1126,8 +1163,7 @@ extern int sparc_mode_class[];
#define RETURN_IN_MEMORY(TYPE) \
(TARGET_ARCH32 \
? (TYPE_MODE (TYPE) == BLKmode \
- || TYPE_MODE (TYPE) == TFmode \
- || TYPE_MODE (TYPE) == TCmode) \
+ || TYPE_MODE (TYPE) == TFmode) \
: (TYPE_MODE (TYPE) == BLKmode \
&& (unsigned HOST_WIDE_INT) int_size_in_bytes (TYPE) > 32))
@@ -1233,6 +1269,20 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS,
{-1, -1, -1, 0x20}, /* GENERAL_OR_EXTRA_FP_REGS */ \
{-1, -1, -1, 0x3f}} /* ALL_REGS */
+/* Defines invalid mode changes. Borrowed from pa64-regs.h.
+
+ SImode loads to floating-point registers are not zero-extended.
+ The definition for LOAD_EXTEND_OP specifies that integer loads
+ narrower than BITS_PER_WORD will be zero-extended. As a result,
+ we inhibit changes from SImode unless they are to a mode that is
+ identical in size. */
+
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (TARGET_ARCH64 \
+ && (FROM) == SImode \
+ && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (CLASS, FP_REGS) : 0)
+
/* The same information, inverted:
Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
@@ -1253,7 +1303,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
We know in this case that we will not end up with a leaf function.
- The register allocater is given the global and out registers first
+ The register allocator is given the global and out registers first
because these registers are call clobbered and thus less useful to
global register allocation.
@@ -1626,13 +1676,13 @@ extern char leaf_reg_remap[];
#define BASE_RETURN_VALUE_REG(MODE) \
(TARGET_ARCH64 \
? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 : 8) \
- : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 : 8))
+ : (TARGET_FPU && FLOAT_MODE_P (MODE) && (MODE) != TFmode ? 32 : 8))
#define BASE_OUTGOING_VALUE_REG(MODE) \
(TARGET_ARCH64 \
? (TARGET_FPU && FLOAT_MODE_P (MODE) ? 32 \
: TARGET_FLAT ? 8 : 24) \
- : (((MODE) == SFmode || (MODE) == DFmode) && TARGET_FPU ? 32 \
+ : (TARGET_FPU && FLOAT_MODE_P (MODE) && (MODE) != TFmode ? 32\
: (TARGET_FLAT ? 8 : 24)))
#define BASE_PASSING_ARG_REG(MODE) \
@@ -1735,8 +1785,8 @@ struct sparc_args {
for a call to a function whose data type is FNTYPE.
For a library call, FNTYPE is 0. */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
-init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (INDIRECT));
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
+init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (FNDECL));
/* Update the data in CUM to advance over an argument
of mode MODE and data type TYPE.
@@ -1935,27 +1985,6 @@ do { \
#define STRICT_ARGUMENT_NAMING TARGET_V9
-/* We do not allow sibling calls if -mflat, nor
- we do not allow indirect calls to be optimized into sibling calls.
-
- Also, on sparc 32-bit we cannot emit a sibling call when the
- current function returns a structure. This is because the "unimp
- after call" convention would cause the callee to return to the
- wrong place. The generic code already disallows cases where the
- function being called returns a structure.
-
- It may seem strange how this last case could occur. Usually there
- is code after the call which jumps to epilogue code which dumps the
- return value into the struct return area. That ought to invalidate
- the sibling call right? Well, in the c++ case we can end up passing
- the pointer to the struct return area to a constructor (which returns
- void) and then nothing else happens. Such a sibling call would look
- valid without the added check here. */
-#define FUNCTION_OK_FOR_SIBCALL(DECL) \
- (DECL \
- && ! TARGET_FLAT \
- && (TARGET_ARCH64 || ! current_function_returns_struct))
-
/* Generate RTL to flush the register windows so as to make arbitrary frames
available. */
#define SETUP_FRAME_ADDRESSES() \
@@ -2050,12 +2079,6 @@ do { \
/* Addressing modes, and classification of registers for them. */
-/* #define HAVE_POST_INCREMENT 0 */
-/* #define HAVE_POST_DECREMENT 0 */
-
-/* #define HAVE_PRE_DECREMENT 0 */
-/* #define HAVE_PRE_INCREMENT 0 */
-
/* Macros to check register numbers against specific register classes. */
/* These assume that REGNO is a hard or pseudo reg number.
@@ -2101,27 +2124,18 @@ do { \
When PIC, we do not accept an address that would require a scratch reg
to load into a register. */
-#define CONSTANT_ADDRESS_P(X) \
- (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
- || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \
- || (GET_CODE (X) == CONST \
- && ! (flag_pic && pic_address_needs_scratch (X))))
+#define CONSTANT_ADDRESS_P(X) constant_address_p (X)
/* Define this, so that when PIC, reload won't try to reload invalid
addresses which require two reload registers. */
-#define LEGITIMATE_PIC_OPERAND_P(X) (! pic_address_needs_scratch (X))
+#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X)
/* Nonzero if the constant value X is a legitimate general operand.
Anything can be made to work except floating point constants.
If TARGET_VIS, 0.0 can be made to work as well. */
-#define LEGITIMATE_CONSTANT_P(X) \
- (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode || \
- (TARGET_VIS && \
- (GET_MODE (X) == SFmode || GET_MODE (X) == DFmode || \
- GET_MODE (X) == TFmode) && \
- fp_zero_operand (X, GET_MODE (X))))
+#define LEGITIMATE_CONSTANT_P(X) legitimate_constant_p (X)
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
@@ -2228,110 +2242,19 @@ 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 (RTX_OK_FOR_BASE_P (X)) \
+{ \
+ if (legitimate_address_p (MODE, X, 1)) \
goto ADDR; \
- else if (GET_CODE (X) == PLUS) \
- { \
- register rtx op0 = XEXP (X, 0); \
- register rtx op1 = XEXP (X, 1); \
- if (flag_pic && op0 == pic_offset_table_rtx) \
- { \
- if (RTX_OK_FOR_BASE_P (op1)) \
- goto ADDR; \
- else if (flag_pic == 1 \
- && GET_CODE (op1) != REG \
- && GET_CODE (op1) != LO_SUM \
- && GET_CODE (op1) != MEM \
- && (! SYMBOLIC_CONST (op1) \
- || MODE == Pmode) \
- && (GET_CODE (op1) != CONST_INT \
- || SMALL_INT (op1))) \
- goto ADDR; \
- } \
- else if (RTX_OK_FOR_BASE_P (op0)) \
- { \
- if ((RTX_OK_FOR_INDEX_P (op1) \
- /* We prohibit REG + REG for TFmode when \
- there are no instructions which accept \
- REG+REG instructions. We do this \
- because REG+REG is not an offsetable \
- address. If we get the situation \
- in reload where source and destination \
- of a movtf pattern are both MEMs with \
- REG+REG address, then only one of them \
- gets converted to an offsetable \
- address. */ \
- && (MODE != TFmode \
- || (TARGET_FPU && TARGET_ARCH64 \
- && TARGET_V9 \
- && TARGET_HARD_QUAD)) \
- /* We prohibit REG + REG on ARCH32 if \
- not optimizing for DFmode/DImode \
- because then mem_min_alignment is \
- likely to be zero after reload and the \
- forced split would lack a matching \
- splitter pattern. */ \
- && (TARGET_ARCH64 || optimize \
- || (MODE != DFmode \
- && MODE != DImode))) \
- || RTX_OK_FOR_OFFSET_P (op1)) \
- goto ADDR; \
- } \
- else if (RTX_OK_FOR_BASE_P (op1)) \
- { \
- if ((RTX_OK_FOR_INDEX_P (op0) \
- /* See the previous comment. */ \
- && (MODE != TFmode \
- || (TARGET_FPU && TARGET_ARCH64 \
- && TARGET_V9 \
- && TARGET_HARD_QUAD)) \
- && (TARGET_ARCH64 || optimize \
- || (MODE != DFmode \
- && MODE != DImode))) \
- || RTX_OK_FOR_OFFSET_P (op0)) \
- goto ADDR; \
- } \
- else if (USE_AS_OFFSETABLE_LO10 \
- && GET_CODE (op0) == LO_SUM \
- && TARGET_ARCH64 \
- && ! TARGET_CM_MEDMID \
- && RTX_OK_FOR_OLO10_P (op1)) \
- { \
- register rtx op00 = XEXP (op0, 0); \
- register rtx op01 = XEXP (op0, 1); \
- if (RTX_OK_FOR_BASE_P (op00) \
- && CONSTANT_P (op01)) \
- goto ADDR; \
- } \
- else if (USE_AS_OFFSETABLE_LO10 \
- && GET_CODE (op1) == LO_SUM \
- && TARGET_ARCH64 \
- && ! TARGET_CM_MEDMID \
- && RTX_OK_FOR_OLO10_P (op0)) \
- { \
- register rtx op10 = XEXP (op1, 0); \
- register rtx op11 = XEXP (op1, 1); \
- if (RTX_OK_FOR_BASE_P (op10) \
- && CONSTANT_P (op11)) \
- goto ADDR; \
- } \
- } \
- else if (GET_CODE (X) == LO_SUM) \
- { \
- register rtx op0 = XEXP (X, 0); \
- register rtx op1 = XEXP (X, 1); \
- if (RTX_OK_FOR_BASE_P (op0) \
- && CONSTANT_P (op1) \
- /* We can't allow TFmode, because an offset \
- greater than or equal to the alignment (8) \
- may cause the LO_SUM to overflow if !v9. */\
- && (MODE != TFmode || TARGET_V9)) \
- goto ADDR; \
- } \
- else if (GET_CODE (X) == CONST_INT && SMALL_INT (X)) \
+}
+#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.
@@ -2376,33 +2299,11 @@ do { \
/* On SPARC, change REG+N into REG+REG, and REG+(X*Y) into REG+REG. */
#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-{ rtx sparc_x = (X); \
- if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == MULT) \
- (X) = gen_rtx_PLUS (Pmode, XEXP (X, 1), \
- force_operand (XEXP (X, 0), NULL_RTX)); \
- if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == MULT) \
- (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \
- force_operand (XEXP (X, 1), NULL_RTX)); \
- if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == PLUS) \
- (X) = gen_rtx_PLUS (Pmode, force_operand (XEXP (X, 0), NULL_RTX),\
- XEXP (X, 1)); \
- if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == PLUS) \
- (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \
- force_operand (XEXP (X, 1), NULL_RTX)); \
- if (sparc_x != (X) && memory_address_p (MODE, X)) \
- goto WIN; \
- if (flag_pic) (X) = legitimize_pic_address (X, MODE, 0); \
- else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \
- (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0), \
- copy_to_mode_reg (Pmode, XEXP (X, 1))); \
- else if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 0))) \
- (X) = gen_rtx_PLUS (Pmode, XEXP (X, 1), \
- copy_to_mode_reg (Pmode, XEXP (X, 0))); \
- else if (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \
- || GET_CODE (X) == LABEL_REF) \
- (X) = copy_to_suggested_reg (X, NULL_RTX, Pmode); \
- if (memory_address_p (MODE, X)) \
- goto WIN; }
+{ \
+ (X) = legitimize_address (X, OLDX, MODE); \
+ if (memory_address_p (MODE, X)) \
+ goto WIN; \
+}
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
@@ -2491,11 +2392,6 @@ do { \
and maybe make use of that. */
#define SLOW_BYTE_ACCESS 1
-/* We assume that the store-condition-codes instructions store 0 for false
- and some other value for true. This is the value stored for true. */
-
-#define STORE_FLAG_VALUE 1
-
/* When a prototype says `char' or `short', really pass an `int'. */
#define PROMOTE_PROTOTYPES (TARGET_ARCH32)
@@ -2507,9 +2403,7 @@ do { \
is done just by pretending it is already truncated. */
#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-/* Specify the machine mode that pointers have.
- After generation of rtl, the compiler makes no further distinction
- between pointers and any other objects of this machine mode. */
+/* Specify the machine mode used for addresses. */
#define Pmode (TARGET_ARCH64 ? DImode : SImode)
/* Generate calls to memcpy, memcmp and memset. */
@@ -2540,100 +2434,20 @@ do { \
/* alloca should avoid clobbering the old register save area. */
#define SETJMP_VIA_SAVE_AREA
-/* Define subroutines to call to handle multiply and divide.
- Use the subroutines that Sun's library provides.
- The `*' prevents an underscore from being prepended by the compiler. */
-
-#define DIVSI3_LIBCALL "*.div"
-#define UDIVSI3_LIBCALL "*.udiv"
-#define MODSI3_LIBCALL "*.rem"
-#define UMODSI3_LIBCALL "*.urem"
-/* .umul is a little faster than .mul. */
-#define MULSI3_LIBCALL "*.umul"
-
-/* Define library calls for quad FP operations. These are all part of the
- SPARC 32bit ABI. */
-#define ADDTF3_LIBCALL "_Q_add"
-#define SUBTF3_LIBCALL "_Q_sub"
-#define NEGTF2_LIBCALL "_Q_neg"
-#define MULTF3_LIBCALL "_Q_mul"
-#define DIVTF3_LIBCALL "_Q_div"
-#define FLOATSITF2_LIBCALL "_Q_itoq"
-#define FIX_TRUNCTFSI2_LIBCALL "_Q_qtoi"
-#define FIXUNS_TRUNCTFSI2_LIBCALL "_Q_qtou"
-#define EXTENDSFTF2_LIBCALL "_Q_stoq"
-#define TRUNCTFSF2_LIBCALL "_Q_qtos"
-#define EXTENDDFTF2_LIBCALL "_Q_dtoq"
-#define TRUNCTFDF2_LIBCALL "_Q_qtod"
-#define EQTF2_LIBCALL "_Q_feq"
-#define NETF2_LIBCALL "_Q_fne"
-#define GTTF2_LIBCALL "_Q_fgt"
-#define GETF2_LIBCALL "_Q_fge"
-#define LTTF2_LIBCALL "_Q_flt"
-#define LETF2_LIBCALL "_Q_fle"
+/* The _Q_* comparison libcalls return booleans. */
+#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode)
/* Assume by default that the _Qp_* 64-bit libcalls are implemented such
that the inputs are fully consumed before the output memory is clobbered. */
#define TARGET_BUGGY_QP_LIB 0
-/* We can define the TFmode sqrt optab only if TARGET_FPU. This is because
- with soft-float, the SFmode and DFmode sqrt instructions will be absent,
- and the compiler will notice and try to use the TFmode sqrt instruction
- for calls to the builtin function sqrt, but this fails. */
-#define INIT_TARGET_OPTABS \
- do { \
- if (TARGET_ARCH32) \
- { \
- add_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (ADDTF3_LIBCALL); \
- sub_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (SUBTF3_LIBCALL); \
- neg_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (NEGTF2_LIBCALL); \
- smul_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (MULTF3_LIBCALL); \
- sdiv_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc (DIVTF3_LIBCALL); \
- eqtf2_libfunc = init_one_libfunc (EQTF2_LIBCALL); \
- netf2_libfunc = init_one_libfunc (NETF2_LIBCALL); \
- gttf2_libfunc = init_one_libfunc (GTTF2_LIBCALL); \
- getf2_libfunc = init_one_libfunc (GETF2_LIBCALL); \
- lttf2_libfunc = init_one_libfunc (LTTF2_LIBCALL); \
- letf2_libfunc = init_one_libfunc (LETF2_LIBCALL); \
- trunctfsf2_libfunc = init_one_libfunc (TRUNCTFSF2_LIBCALL); \
- trunctfdf2_libfunc = init_one_libfunc (TRUNCTFDF2_LIBCALL); \
- extendsftf2_libfunc = init_one_libfunc (EXTENDSFTF2_LIBCALL); \
- extenddftf2_libfunc = init_one_libfunc (EXTENDDFTF2_LIBCALL); \
- floatsitf_libfunc = init_one_libfunc (FLOATSITF2_LIBCALL); \
- fixtfsi_libfunc = init_one_libfunc (FIX_TRUNCTFSI2_LIBCALL); \
- fixunstfsi_libfunc \
- = init_one_libfunc (FIXUNS_TRUNCTFSI2_LIBCALL); \
- if (TARGET_FPU) \
- sqrt_optab->handlers[(int) TFmode].libfunc \
- = init_one_libfunc ("_Q_sqrt"); \
- } \
- if (TARGET_ARCH64) \
- { \
- /* In the SPARC 64bit ABI, these libfuncs do not exist in the \
- library. Make sure the compiler does not emit calls to them \
- by accident. */ \
- sdiv_optab->handlers[(int) SImode].libfunc = NULL; \
- udiv_optab->handlers[(int) SImode].libfunc = NULL; \
- smod_optab->handlers[(int) SImode].libfunc = NULL; \
- umod_optab->handlers[(int) SImode].libfunc = NULL; \
- smul_optab->handlers[(int) SImode].libfunc = NULL; \
- } \
- INIT_SUBTARGET_OPTABS; \
- } while (0)
-
-/* This is meant to be redefined in the host dependent files */
-#define INIT_SUBTARGET_OPTABS
+/* Assume by default that we do not have the Solaris-specific conversion
+ routines nor 64-bit integer multiply and divide routines. */
-/* Nonzero if a floating point comparison library call for
- mode MODE that will return a boolean value. Zero if one
- of the libgcc2 functions is used. */
-#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) ((MODE) == TFmode)
+#define SUN_CONVERSION_LIBFUNCS 0
+#define DITF_CONVERSION_LIBFUNCS 0
+#define SUN_INTEGER_MULTIPLY_64 0
/* Compute extra cost of moving data between one register class
and another. */
@@ -2662,29 +2476,6 @@ do { \
: (sparc_cpu == PROCESSOR_ULTRASPARC3 \
? 9 : 3))
-/* The cases that RTX_COSTS handles. */
-
-#define RTX_COSTS_CASES \
-case PLUS: case MINUS: case ABS: case NEG: \
-case FLOAT: case UNSIGNED_FLOAT: \
-case FIX: case UNSIGNED_FIX: \
-case FLOAT_EXTEND: case FLOAT_TRUNCATE: \
-case SQRT: \
-case COMPARE: case IF_THEN_ELSE: \
-case MEM: \
-case MULT: case DIV: case UDIV: case MOD: case UMOD: \
-case CONST_INT: case HIGH: case CONST: \
-case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE:
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- RTX_COSTS_CASES \
- return sparc_rtx_costs(X,CODE,OUTER_CODE);
-
-#define ADDRESS_COST(RTX) 1
-
#define PREFETCH_BLOCK \
((sparc_cpu == PROCESSOR_ULTRASPARC \
|| sparc_cpu == PROCESSOR_ULTRASPARC3) \
@@ -2698,10 +2489,6 @@ case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE:
/* Control the assembler format that we output. */
-/* Output at beginning of assembler file. */
-
-#define ASM_FILE_START(file)
-
/* A C string constant describing how to begin a comment in the target
assembler language. The compiler assumes that the comment will end at
the end of the line. */
@@ -2765,12 +2552,6 @@ case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE:
#define USER_LABEL_PREFIX "_"
-/* This is how to output a definition of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, "%s%d:\n", PREFIX, NUM)
-
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
PREFIX is the class of label and NUM is the number within the class.
@@ -2849,7 +2630,7 @@ do { \
fprintf (FILE, "\t.align %d,0x1000000\n", (1<<(LOG)))
#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.skip %u\n", (SIZE))
+ fprintf (FILE, "\t.skip "HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE))
/* This says how to output an assembler line
to define a global common symbol. */
@@ -2857,7 +2638,7 @@ do { \
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs ("\t.common ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u,\"bss\"\n", (SIZE)))
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",\"bss\"\n", (SIZE)))
/* This says how to output an assembler line to define a local common
symbol. */
@@ -2865,7 +2646,7 @@ do { \
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGNED) \
( fputs ("\t.reserve ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u,\"bss\",%u\n", \
+ fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",\"bss\",%u\n", \
(SIZE), ((ALIGNED) / BITS_PER_UNIT)))
/* A C statement (sans semicolon) to output to the stdio stream
@@ -2875,20 +2656,9 @@ do { \
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
do { \
- fputs (".globl ", (FILE)); \
- assemble_name ((FILE), (NAME)); \
- fputs ("\n", (FILE)); \
ASM_OUTPUT_ALIGNED_LOCAL (FILE, NAME, SIZE, ALIGN); \
} while (0)
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable named NAME.
- LABELNO is an integer which is different for each call. */
-
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
-
#define IDENT_ASM_OP "\t.ident\t"
/* Output #ident as a .ident. */
@@ -2896,8 +2666,16 @@ do { \
#define ASM_OUTPUT_IDENT(FILE, NAME) \
fprintf (FILE, "%s\"%s\"\n", IDENT_ASM_OP, NAME);
+/* Emit a dtp-relative reference to a TLS variable. */
+
+#ifdef HAVE_AS_TLS
+#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \
+ sparc_output_dwarf_dtprel (FILE, SIZE, X)
+#endif
+
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
- ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' || (CHAR) == '(' || (CHAR) == '_')
+ ((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^' \
+ || (CHAR) == '(' || (CHAR) == '_' || (CHAR) == '&')
/* Print operand X (an rtx) in assembler syntax to file FILE.
CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
@@ -2984,6 +2762,14 @@ do { \
} \
}
+#ifdef HAVE_AS_TLS
+#define TARGET_TLS 1
+#else
+#define TARGET_TLS 0
+#endif
+#define TARGET_SUN_TLS TARGET_TLS
+#define TARGET_GNU_TLS 0
+
/* Define the codes that are matched by predicates in sparc.c. */
#define PREDICATE_CODES \
@@ -3030,8 +2816,13 @@ do { \
{"uns_arith_operand", {SUBREG, REG, CONST_INT}}, \
{"clobbered_register", {REG}}, \
{"input_operand", {SUBREG, REG, CONST_INT, MEM, CONST}}, \
+{"compare_operand", {SUBREG, REG, ZERO_EXTRACT}}, \
{"const64_operand", {CONST_INT, CONST_DOUBLE}}, \
-{"const64_high_operand", {CONST_INT, CONST_DOUBLE}},
+{"const64_high_operand", {CONST_INT, CONST_DOUBLE}}, \
+{"tgd_symbolic_operand", {SYMBOL_REF}}, \
+{"tld_symbolic_operand", {SYMBOL_REF}}, \
+{"tie_symbolic_operand", {SYMBOL_REF}}, \
+{"tle_symbolic_operand", {SYMBOL_REF}},
/* The number of Pmode words for the setjmp buffer. */
#define JMP_BUF_SIZE 12
diff --git a/contrib/gcc/config/sparc/sparc.md b/contrib/gcc/config/sparc/sparc.md
index b53013ec397d..c7da780414d3 100644
--- a/contrib/gcc/config/sparc/sparc.md
+++ b/contrib/gcc/config/sparc/sparc.md
@@ -1,24 +1,24 @@
-;; Machine description for SPARC chip for GNU C compiler
+;; Machine description for SPARC chip for GCC
;; Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-;; 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+;; 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
;; Contributed by Michael Tiemann (tiemann@cygnus.com)
-;; 64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
+;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
;; at Cygnus Support.
-;; This file is part of GNU CC.
+;; This file is part of GCC.
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
@@ -38,6 +38,13 @@
(UNSPEC_EMB_TEXTHI 14)
(UNSPEC_EMB_TEXTULO 15)
(UNSPEC_EMB_SETHM 18)
+
+ (UNSPEC_TLSGD 30)
+ (UNSPEC_TLSLDM 31)
+ (UNSPEC_TLSLDO 32)
+ (UNSPEC_TLSIE 33)
+ (UNSPEC_TLSLE 34)
+ (UNSPEC_TLSLD_BASE 35)
])
(define_constants
@@ -99,6 +106,7 @@
fpcmp,
fpmul,fpdivs,fpdivd,
fpsqrts,fpsqrtd,
+ fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
cmove,
ialuX,
multi,flushw,iflush,trap"
@@ -120,6 +128,8 @@
(symbol_ref "TARGET_FLAT != 0"))
;; Length (in # of insns).
+;; Beware that setting a length greater or equal to 3 for conditional branches
+;; has a side-effect (see output_cbranch and output_v9branch).
(define_attr "length" ""
(cond [(eq_attr "type" "uncond_branch,call,sibcall")
(if_then_else (eq_attr "empty_delay_slot" "true")
@@ -199,6 +209,9 @@
;; Attributes for instruction and branch scheduling
+(define_attr "tls_call_delay" "false,true"
+ (symbol_ref "tls_call_delay (insn)"))
+
(define_attr "in_call_delay" "false,true"
(cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
(const_string "false")
@@ -206,7 +219,8 @@
(if_then_else (eq_attr "length" "1")
(const_string "true")
(const_string "false"))]
- (if_then_else (eq_attr "length" "1")
+ (if_then_else (and (eq_attr "length" "1")
+ (eq_attr "tls_call_delay" "true"))
(const_string "true")
(const_string "false"))))
@@ -290,10 +304,13 @@
(define_expand "cmpsi"
[(set (reg:CC 100)
- (compare:CC (match_operand:SI 0 "register_operand" "")
+ (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;
@@ -301,10 +318,13 @@
(define_expand "cmpdi"
[(set (reg:CCX 100)
- (compare:CCX (match_operand:DI 0 "register_operand" "")
+ (compare:CCX (match_operand:DI 0 "compare_operand" "")
(match_operand:DI 1 "arith_double_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;
@@ -1685,6 +1705,10 @@
}
}
+ /* Fixup TLS cases. */
+ if (tls_symbolic_operand (operands [1]))
+ operands[1] = legitimize_tls_address (operands[1]);
+
/* Fixup PIC cases. */
if (flag_pic)
{
@@ -1744,6 +1768,10 @@
}
}
+ /* Fixup TLS cases. */
+ if (tls_symbolic_operand (operands [1]))
+ operands[1] = legitimize_tls_address (operands[1]);
+
/* Fixup PIC cases. */
if (flag_pic)
{
@@ -1798,8 +1826,8 @@
;; We always work with constants here.
(define_insn "*movhi_lo_sum"
[(set (match_operand:HI 0 "register_operand" "=r")
- (ior:HI (match_operand:HI 1 "arith_operand" "%r")
- (match_operand:HI 2 "arith_operand" "I")))]
+ (ior:HI (match_operand:HI 1 "register_operand" "%r")
+ (match_operand:HI 2 "small_int" "I")))]
""
"or\t%1, %2, %0")
@@ -1826,6 +1854,10 @@
}
}
+ /* Fixup TLS cases. */
+ if (tls_symbolic_operand (operands [1]))
+ operands[1] = legitimize_tls_address (operands[1]);
+
/* Fixup PIC cases. */
if (flag_pic)
{
@@ -1897,7 +1929,7 @@
st\t%r1, %0
st\t%1, %0
fzeros\t%0"
- [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fpmove")])
+ [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
(define_insn "*movsi_lo_sum"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -2002,6 +2034,10 @@
}
}
+ /* Fixup TLS cases. */
+ if (tls_symbolic_operand (operands [1]))
+ operands[1] = legitimize_tls_address (operands[1]);
+
if (flag_pic)
{
if (CONSTANT_P (operands[1])
@@ -2165,7 +2201,7 @@
ldd\t%1, %0
std\t%1, %0
fzero\t%0"
- [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fpmove")
+ [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
(set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
(define_expand "movdi_pic_label_ref"
@@ -2613,7 +2649,7 @@
abort();
}
}
- [(set_attr "type" "fpmove,fpmove,*,*,*,*,load,fpload,fpstore,store")])
+ [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
;; Exactly the same as above, except that all `f' cases are deleted.
;; This is necessary to prevent reload from ever trying to use a `f' reg
@@ -2930,7 +2966,7 @@
#
#
#"
- [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
+ [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
(set_attr "length" "*,*,*,*,*,*,*,2,2,2")
(set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
@@ -2977,7 +3013,7 @@
ldx\t%1, %0
stx\t%r1, %0
#"
- [(set_attr "type" "fpmove,fpmove,load,store,*,load,store,*")
+ [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
(set_attr "length" "*,*,*,*,*,*,*,2")
(set_attr "fptype" "double,double,*,*,*,*,*,*")])
@@ -3205,7 +3241,7 @@
operands[1]));
}
- /* Handle MEM cases first, note that only v9 guarentees
+ /* Handle MEM cases first, note that only v9 guarantees
full 16-byte alignment for quads. */
if (GET_CODE (operands[0]) == MEM)
{
@@ -4949,7 +4985,7 @@
add\t%1, %2, %0
sub\t%1, -%2, %0
fpadd32s\t%1, %2, %0"
- [(set_attr "type" "*,*,fp")])
+ [(set_attr "type" "*,*,fga")])
(define_insn "*cmp_cc_plus"
[(set (reg:CC_NOOV 100)
@@ -5105,7 +5141,7 @@
sub\t%1, %2, %0
add\t%1, -%2, %0
fpsub32s\t%1, %2, %0"
- [(set_attr "type" "*,*,fp")])
+ [(set_attr "type" "*,*,fga")])
(define_insn "*cmp_minus_cc"
[(set (reg:CC_NOOV 100)
@@ -5829,7 +5865,7 @@
"@
#
fand\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -5841,7 +5877,7 @@
"@
and\t%1, %2, %0
fand\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "andsi3"
@@ -5852,7 +5888,7 @@
"@
and\t%1, %2, %0
fands\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
(define_split
[(set (match_operand:SI 0 "register_operand" "")
@@ -5924,7 +5960,7 @@
operands[6] = gen_lowpart (SImode, operands[0]);
operands[7] = gen_lowpart (SImode, operands[1]);
operands[8] = gen_lowpart (SImode, operands[2]);"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -5936,7 +5972,7 @@
"@
andn\t%2, %1, %0
fandnot1\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "*and_not_si"
@@ -5947,7 +5983,7 @@
"@
andn\t%2, %1, %0
fandnot1s\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
(define_expand "iordi3"
[(set (match_operand:DI 0 "register_operand" "")
@@ -5964,7 +6000,7 @@
"@
#
for\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -5976,7 +6012,7 @@
"@
or\t%1, %2, %0
for\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "iorsi3"
@@ -5987,7 +6023,7 @@
"@
or\t%1, %2, %0
fors\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
(define_split
[(set (match_operand:SI 0 "register_operand" "")
@@ -6025,7 +6061,7 @@
operands[6] = gen_lowpart (SImode, operands[0]);
operands[7] = gen_lowpart (SImode, operands[1]);
operands[8] = gen_lowpart (SImode, operands[2]);"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -6037,7 +6073,7 @@
"@
orn\t%2, %1, %0
fornot1\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "*or_not_si"
@@ -6048,7 +6084,7 @@
"@
orn\t%2, %1, %0
fornot1s\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
(define_expand "xordi3"
[(set (match_operand:DI 0 "register_operand" "")
@@ -6065,7 +6101,7 @@
"@
#
fxor\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -6077,7 +6113,7 @@
"@
xor\t%r1, %2, %0
fxor\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "*xordi3_sp64_dbl"
@@ -6096,7 +6132,7 @@
"@
xor\t%r1, %2, %0
fxors\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
(define_split
[(set (match_operand:SI 0 "register_operand" "")
@@ -6150,7 +6186,7 @@
operands[6] = gen_lowpart (SImode, operands[0]);
operands[7] = gen_lowpart (SImode, operands[1]);
operands[8] = gen_lowpart (SImode, operands[2]);"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -6162,7 +6198,7 @@
"@
xnor\t%r1, %2, %0
fxnor\t%1, %2, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "*xor_not_si"
@@ -6173,7 +6209,7 @@
"@
xnor\t%r1, %2, %0
fxnors\t%1, %2, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
;; These correspond to the above in the case where we also (or only)
;; want to set the condition code.
@@ -6436,7 +6472,7 @@
operands[3] = gen_highpart (SImode, operands[1]);
operands[4] = gen_lowpart (SImode, operands[0]);
operands[5] = gen_lowpart (SImode, operands[1]);"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "length" "2,*")
(set_attr "fptype" "double")])
@@ -6447,7 +6483,7 @@
"@
xnor\t%%g0, %1, %0
fnot1\t%1, %0"
- [(set_attr "type" "*,fp")
+ [(set_attr "type" "*,fga")
(set_attr "fptype" "double")])
(define_insn "one_cmplsi2"
@@ -6457,7 +6493,7 @@
"@
xnor\t%%g0, %1, %0
fnot1s\t%1, %0"
- [(set_attr "type" "*,fp")])
+ [(set_attr "type" "*,fga")])
(define_insn "*cmp_cc_not"
[(set (reg:CC 100)
@@ -7212,27 +7248,10 @@
[(set_attr "type" "shift")])
;; Unconditional and other jump instructions
-;; On the SPARC, by setting the annul bit on an unconditional branch, the
-;; following insn is never executed. This saves us a nop. Dbx does not
-;; handle such branches though, so we only use them when optimizing.
(define_insn "jump"
[(set (pc) (label_ref (match_operand 0 "" "")))]
""
-{
- /* TurboSPARC is reported to have problems with
- with
- foo: b,a foo
- i.e. an empty loop with the annul bit set. The workaround is to use
- foo: b foo; nop
- instead. */
-
- if (! TARGET_V9 && flag_delayed_branch
- && (INSN_ADDRESSES (INSN_UID (operands[0]))
- == INSN_ADDRESSES (INSN_UID (insn))))
- return "b\t%l0%#";
- else
- return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
-}
+ "* return output_ubranch (operands[0], 0, insn);"
[(set_attr "type" "uncond_branch")])
(define_expand "tablejump"
@@ -7658,7 +7677,7 @@
emit_insn (gen_rtx_USE (VOIDmode, valreg2));
/* Construct the return. */
- expand_null_return ();
+ expand_naked_return ();
DONE;
})
@@ -7796,7 +7815,7 @@
;; For __builtin_setjmp we need to flush register windows iff the function
;; calls alloca as well, because otherwise the register window might be
-;; saved after %sp adjustement and thus setjmp would crash
+;; saved after %sp adjustment and thus setjmp would crash
(define_expand "builtin_setjmp_setup"
[(match_operand 0 "register_operand" "r")]
""
@@ -8239,31 +8258,6 @@
[(set_attr "type" "multi")
(set_attr "length" "2")])
-;; Now peepholes to do a call followed by a jump.
-
-(define_peephole
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:SI 1 "call_operand_address" "ps"))
- (match_operand 2 "" "")))
- (clobber (reg:SI 15))])
- (set (pc) (label_ref (match_operand 3 "" "")))]
- "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
- && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
- && sparc_cpu != PROCESSOR_ULTRASPARC
- && sparc_cpu != PROCESSOR_ULTRASPARC3"
- "call\t%a1, %2\n\tadd\t%%o7, (%l3-.-4), %%o7")
-
-(define_peephole
- [(parallel [(call (mem:SI (match_operand:SI 0 "call_operand_address" "ps"))
- (match_operand 1 "" ""))
- (clobber (reg:SI 15))])
- (set (pc) (label_ref (match_operand 2 "" "")))]
- "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
- && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (ins1))
- && sparc_cpu != PROCESSOR_ULTRASPARC
- && sparc_cpu != PROCESSOR_ULTRASPARC3"
- "call\t%a0, %1\n\tadd\t%%o7, (%l2-.-4), %%o7")
-
;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
;; ??? operations. With DFA we might be able to model this, but it requires a lot of
@@ -8391,3 +8385,566 @@
"TARGET_V9"
"t%C0\t%%xcc, %1"
[(set_attr "type" "trap")])
+
+;; TLS support
+(define_insn "tgd_hi22"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
+ UNSPEC_TLSGD)))]
+ "TARGET_TLS"
+ "sethi\\t%%tgd_hi22(%a1), %0")
+
+(define_insn "tgd_lo10"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
+ UNSPEC_TLSGD)))]
+ "TARGET_TLS"
+ "add\\t%1, %%tgd_lo10(%a2), %0")
+
+(define_insn "tgd_add32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tgd_symbolic_operand" "")]
+ UNSPEC_TLSGD)))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "add\\t%1, %2, %0, %%tgd_add(%a3)")
+
+(define_insn "tgd_add64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tgd_symbolic_operand" "")]
+ UNSPEC_TLSGD)))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "add\\t%1, %2, %0, %%tgd_add(%a3)")
+
+(define_insn "tgd_call32"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
+ (match_operand 2 "tgd_symbolic_operand" "")]
+ UNSPEC_TLSGD))
+ (match_operand 3 "" "")))
+ (clobber (reg:SI 15))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "call\t%a1, %%tgd_call(%a2)%#"
+ [(set_attr "type" "call")])
+
+(define_insn "tgd_call64"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
+ (match_operand 2 "tgd_symbolic_operand" "")]
+ UNSPEC_TLSGD))
+ (match_operand 3 "" "")))
+ (clobber (reg:DI 15))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "call\t%a1, %%tgd_call(%a2)%#"
+ [(set_attr "type" "call")])
+
+(define_insn "tldm_hi22"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
+ "TARGET_TLS"
+ "sethi\\t%%tldm_hi22(%&), %0")
+
+(define_insn "tldm_lo10"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
+ "TARGET_TLS"
+ "add\\t%1, %%tldm_lo10(%&), %0")
+
+(define_insn "tldm_add32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
+ UNSPEC_TLSLDM)))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "add\\t%1, %2, %0, %%tldm_add(%&)")
+
+(define_insn "tldm_add64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
+ UNSPEC_TLSLDM)))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "add\\t%1, %2, %0, %%tldm_add(%&)")
+
+(define_insn "tldm_call32"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
+ UNSPEC_TLSLDM))
+ (match_operand 2 "" "")))
+ (clobber (reg:SI 15))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "call\t%a1, %%tldm_call(%&)%#"
+ [(set_attr "type" "call")])
+
+(define_insn "tldm_call64"
+ [(set (match_operand 0 "register_operand" "=r")
+ (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
+ UNSPEC_TLSLDM))
+ (match_operand 2 "" "")))
+ (clobber (reg:DI 15))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "call\t%a1, %%tldm_call(%&)%#"
+ [(set_attr "type" "call")])
+
+(define_insn "tldo_hix22"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)))]
+ "TARGET_TLS"
+ "sethi\\t%%tldo_hix22(%a1), %0")
+
+(define_insn "tldo_lox10"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)))]
+ "TARGET_TLS"
+ "xor\\t%1, %%tldo_lox10(%a2), %0")
+
+(define_insn "tldo_add32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "add\\t%1, %2, %0, %%tldo_add(%a3)")
+
+(define_insn "tldo_add64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "add\\t%1, %2, %0, %%tldo_add(%a3)")
+
+(define_insn "tie_hi22"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
+ UNSPEC_TLSIE)))]
+ "TARGET_TLS"
+ "sethi\\t%%tie_hi22(%a1), %0")
+
+(define_insn "tie_lo10"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
+ UNSPEC_TLSIE)))]
+ "TARGET_TLS"
+ "add\\t%1, %%tie_lo10(%a2), %0")
+
+(define_insn "tie_ld32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tie_symbolic_operand" "")]
+ UNSPEC_TLSIE))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
+ [(set_attr "type" "load")])
+
+(define_insn "tie_ld64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tie_symbolic_operand" "")]
+ UNSPEC_TLSIE))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
+ [(set_attr "type" "load")])
+
+(define_insn "tie_add32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (plus:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tie_symbolic_operand" "")]
+ UNSPEC_TLSIE)))]
+ "TARGET_SUN_TLS && TARGET_ARCH32"
+ "add\\t%1, %2, %0, %%tie_add(%a3)")
+
+(define_insn "tie_add64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (plus:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand:DI 2 "register_operand" "r")
+ (match_operand 3 "tie_symbolic_operand" "")]
+ UNSPEC_TLSIE)))]
+ "TARGET_SUN_TLS && TARGET_ARCH64"
+ "add\\t%1, %2, %0, %%tie_add(%a3)")
+
+(define_insn "tle_hix22_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
+ UNSPEC_TLSLE)))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "sethi\\t%%tle_hix22(%a1), %0")
+
+(define_insn "tle_lox10_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
+ UNSPEC_TLSLE)))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "xor\\t%1, %%tle_lox10(%a2), %0")
+
+(define_insn "tle_hix22_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
+ UNSPEC_TLSLE)))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "sethi\\t%%tle_hix22(%a1), %0")
+
+(define_insn "tle_lox10_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
+ (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
+ UNSPEC_TLSLE)))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "xor\\t%1, %%tle_lox10(%a2), %0")
+
+;; Now patterns combining tldo_add{32,64} with some integer loads or stores
+(define_insn "*tldo_ldub_sp32"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldub1_sp32"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldub2_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsb1_sp32"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsb2_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldub_sp64"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldub1_sp64"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldub2_sp64"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldub3_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsb1_sp64"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsb2_sp64"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsb3_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_lduh_sp32"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_lduh1_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsh1_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_lduh_sp64"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_lduh1_sp64"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_lduh2_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsh1_sp64"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldsh2_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_lduw_sp32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "ld\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")])
+
+(define_insn "*tldo_lduw_sp64"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")])
+
+(define_insn "*tldo_lduw1_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")])
+
+(define_insn "*tldo_ldsw1_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "sload")
+ (set_attr "us3load_type" "3cycle")])
+
+(define_insn "*tldo_ldx_sp64"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r"))))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
+ [(set_attr "type" "load")])
+
+(define_insn "*tldo_stb_sp32"
+ [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))
+ (match_operand:QI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "stb\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
+
+(define_insn "*tldo_stb_sp64"
+ [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))
+ (match_operand:QI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "stb\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
+
+(define_insn "*tldo_sth_sp32"
+ [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))
+ (match_operand:HI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "sth\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
+
+(define_insn "*tldo_sth_sp64"
+ [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))
+ (match_operand:HI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "sth\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
+
+(define_insn "*tldo_stw_sp32"
+ [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:SI 1 "register_operand" "r")))
+ (match_operand:SI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH32"
+ "st\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
+
+(define_insn "*tldo_stw_sp64"
+ [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))
+ (match_operand:SI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "stw\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
+
+(define_insn "*tldo_stx_sp64"
+ [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
+ (match_operand 3 "tld_symbolic_operand" "")]
+ UNSPEC_TLSLDO)
+ (match_operand:DI 1 "register_operand" "r")))
+ (match_operand:DI 0 "register_operand" "=r"))]
+ "TARGET_TLS && TARGET_ARCH64"
+ "stx\t%0, [%1 + %2], %%tldo_add(%3)"
+ [(set_attr "type" "store")])
diff --git a/contrib/gcc/config/sparc/sparclet.md b/contrib/gcc/config/sparc/sparclet.md
index 080090c3eadf..15020ba113e0 100644
--- a/contrib/gcc/config/sparc/sparclet.md
+++ b/contrib/gcc/config/sparc/sparclet.md
@@ -1,20 +1,20 @@
;; Scheduling description for SPARClet.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/sparc/supersparc.md b/contrib/gcc/config/sparc/supersparc.md
index ea328868e607..93e4cf779236 100644
--- a/contrib/gcc/config/sparc/supersparc.md
+++ b/contrib/gcc/config/sparc/supersparc.md
@@ -1,20 +1,20 @@
;; Scheduling description for SuperSPARC.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
diff --git a/contrib/gcc/config/sparc/sysv4-only.h b/contrib/gcc/config/sparc/sysv4-only.h
new file mode 100644
index 000000000000..da265a0c0df3
--- /dev/null
+++ b/contrib/gcc/config/sparc/sysv4-only.h
@@ -0,0 +1,35 @@
+/* Target macros for GCC for SPARC running System V.4
+ Copyright (C) 2003
+ 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Provide a set of pre-definitions and pre-assertions appropriate for
+ the SPARC running svr4. __svr4__ is our extension. */
+
+/* Target OS builtins. */ \
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define_std ("sparc"); \
+ builtin_define_std ("unix"); \
+ builtin_define ("__svr4__"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=svr4"); \
+ } \
+ while (0)
diff --git a/contrib/gcc/config/sparc/sysv4.h b/contrib/gcc/config/sparc/sysv4.h
index f304d6b5497b..776debc1a9ae 100644
--- a/contrib/gcc/config/sparc/sysv4.h
+++ b/contrib/gcc/config/sparc/sysv4.h
@@ -3,20 +3,20 @@
Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -48,13 +48,6 @@ Boston, MA 02111-1307, USA. */
#undef SKIP_ASM_OP
#undef SET_ASM_OP /* Has no equivalent. See ASM_OUTPUT_DEF below. */
-/* Provide a set of pre-definitions and pre-assertions appropriate for
- the SPARC running svr4. __svr4__ is our extension. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES \
-"-Dsparc -Dunix -D__svr4__ -Asystem=unix -Asystem=svr4"
-
/* The native assembler can't compute differences between symbols in different
sections when generating pic code, so we must put jump tables in the
text section. */
@@ -66,7 +59,7 @@ Boston, MA 02111-1307, USA. */
#undef ASM_SPEC
#define ASM_SPEC \
"%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} \
- %{fpic:-K PIC} %{fPIC:-K PIC} %(asm_cpu)"
+ %{fpic|fPIC|fpie|fPIE:-K PIC} %(asm_cpu)"
/* Define the names of various pseudo-op used by the SPARC/svr4 assembler.
Note that many of these are different from the typical pseudo-ops used
@@ -93,7 +86,7 @@ Boston, MA 02111-1307, USA. */
#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE) \
do { ASM_OUTPUT_ALIGN ((FILE), Pmode == SImode ? 2 : 3); \
- ASM_OUTPUT_INTERNAL_LABEL ((FILE), PREFIX, NUM); \
+ (*targetm.asm_out.internal_label) ((FILE), PREFIX, NUM); \
} while (0)
/* This is how to equate one symbol to another symbol. The syntax used is
@@ -161,11 +154,6 @@ do { ASM_OUTPUT_ALIGN ((FILE), Pmode == SImode ? 2 : 3); \
#undef TARGET_ASM_NAMED_SECTION
#define TARGET_ASM_NAMED_SECTION sparc_elf_asm_named_section
-/* A C statement (sans semicolon) to output to the stdio stream
- FILE the assembler definition of uninitialized global DECL named
- NAME whose size is SIZE bytes and alignment is ALIGN bytes.
- Try to use asm_output_aligned_bss to implement this macro. */
-
#undef ASM_OUTPUT_ALIGNED_BSS
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
diff --git a/contrib/gcc/config/sparc/t-sol2 b/contrib/gcc/config/sparc/t-sol2
index 4a5a13b8618e..f32765ff7f75 100644
--- a/contrib/gcc/config/sparc/t-sol2
+++ b/contrib/gcc/config/sparc/t-sol2
@@ -1,5 +1,6 @@
# gmon build rule:
-$(T)gmon.o: $(srcdir)/config/sparc/gmon-sol2.c $(GCC_PASSES) $(CONFIG_H) stmp-int-hdrs
+$(T)gmon.o: $(srcdir)/config/sparc/gmon-sol2.c $(GCC_PASSES) \
+ $(TCONFIG_H) tsystem.h coretypes.h $(TM_H) stmp-int-hdrs
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) \
-c $(srcdir)/config/sparc/gmon-sol2.c -o $(T)gmon.o
diff --git a/contrib/gcc/config/sparc/ultra1_2.md b/contrib/gcc/config/sparc/ultra1_2.md
index 2194be7ad786..e58c624abd23 100644
--- a/contrib/gcc/config/sparc/ultra1_2.md
+++ b/contrib/gcc/config/sparc/ultra1_2.md
@@ -1,20 +1,20 @@
;; Scheduling description for UltraSPARC-I/II.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
@@ -250,3 +250,53 @@
;; An integer branch may execute in the same cycle as the compare
;; creating the condition codes.
(define_bypass 0 "us1_simple_ieu1" "us1_branch")
+
+;; VIS scheduling
+(define_insn_reservation "us1_fga_single"
+ 2
+ (and (and
+ (eq_attr "cpu" "ultrasparc")
+ (eq_attr "type" "fga"))
+ (eq_attr "fptype" "single"))
+ "us1_fpa + us1_fp_single + us1_slotany, nothing")
+
+(define_bypass 1 "us1_fga_single" "us1_fga_single")
+
+(define_insn_reservation "us1_fga_double"
+ 2
+ (and (and
+ (eq_attr "cpu" "ultrasparc")
+ (eq_attr "type" "fga"))
+ (eq_attr "fptype" "double"))
+ "us1_fpa + us1_fp_double + us1_slotany, nothing")
+
+(define_bypass 1 "us1_fga_double" "us1_fga_double")
+
+(define_insn_reservation "us1_fgm_single"
+ 4
+ (and (and
+ (eq_attr "cpu" "ultrasparc")
+ (eq_attr "type" "fgm_pack,fgm_mul,fgm_cmp"))
+ (eq_attr "fptype" "single"))
+ "us1_fpm + us1_fp_single + us1_slotany, nothing*3")
+
+(define_bypass 3 "us1_fgm_single" "us1_fga_single")
+
+(define_insn_reservation "us1_fgm_double"
+ 4
+ (and (and
+ (eq_attr "cpu" "ultrasparc")
+ (eq_attr "type" "fgm_pack,fgm_mul,fgm_cmp"))
+ (eq_attr "fptype" "double"))
+ "us1_fpm + us1_fp_double + us1_slotany, nothing*3")
+
+(define_bypass 3 "us1_fgm_double" "us1_fga_double")
+
+(define_insn_reservation "us1_pdist"
+ 4
+ (and (eq_attr "cpu" "ultrasparc")
+ (eq_attr "type" "fgm_pdist"))
+ "us1_fpm + us1_fp_double + us1_slotany, nothing*3")
+
+(define_bypass 3 "us1_pdist" "us1_fga_double,us1_fga_single")
+(define_bypass 1 "us1_pdist" "us1_pdist")
diff --git a/contrib/gcc/config/sparc/ultra3.md b/contrib/gcc/config/sparc/ultra3.md
index cebc9f2aa80a..238beab29109 100644
--- a/contrib/gcc/config/sparc/ultra3.md
+++ b/contrib/gcc/config/sparc/ultra3.md
@@ -1,20 +1,20 @@
;; Scheduling description for UltraSPARC-III.
;; Copyright (C) 2002 Free Software Foundation, Inc.
;;
-;; This file is part of GNU CC.
+;; This file is part of GCC.
;;
-;; GNU CC is free software; you can redistribute it and/or modify
+;; 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 2, or (at your option)
;; any later version.
;;
-;; GNU CC is distributed in the hope that it will be useful,
+;; 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 GNU CC; see the file COPYING. If not, write to
+;; along with GCC; see the file COPYING. If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
@@ -167,3 +167,24 @@
;; If FMOVfcc is user of FPCMP, latency is only 1 cycle.
(define_bypass 1 "us3_fpcmp" "us3_fcmov")
+
+;; VIS scheduling
+(define_insn_reservation "us3_fga"
+ 3
+ (and (eq_attr "cpu" "ultrasparc3")
+ (eq_attr "type" "fga"))
+ "us3_fpa + us3_slotany, nothing*2")
+
+(define_insn_reservation "us3_fgm"
+ 4
+ (and (eq_attr "cpu" "ultrasparc3")
+ (eq_attr "type" "fgm_pack,fgm_mul,fgm_cmp"))
+ "us3_fpm + us3_slotany, nothing*3")
+
+(define_insn_reservation "us3_pdist"
+ 4
+ (and (eq_attr "cpu" "ultrasparc3")
+ (eq_attr "type" "fgm_pdist"))
+ "us3_fpm + us3_slotany, nothing*3")
+
+(define_bypass 1 "us3_pdist" "us3_pdist")
diff --git a/contrib/gcc/config/svr3.h b/contrib/gcc/config/svr3.h
index e559c5c59d39..21595eac2732 100644
--- a/contrib/gcc/config/svr3.h
+++ b/contrib/gcc/config/svr3.h
@@ -3,41 +3,22 @@
Copyright (C) 1991, 1996, 2000, 2002 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
-
- To use this file, make up a file with a name like:
-
- ?????svr3.h
-
- where ????? is replaced by the name of the basic hardware that you
- are targeting for. Then, in the file ?????svr3.h, put something
- like:
-
- #include "?????.h"
- #include "svr3.h"
-
- followed by any really system-specific defines (or overrides of
- defines) which you find that you need. For example, CPP_PREDEFINES
- is defined here with only the defined -Dunix and -DSVR3. You should
- probably override that in your target-specific ?????svr3.h file
- with a set of defines that includes these, but also contains an
- appropriate define for the type of hardware that you are targeting.
-*/
+Boston, MA 02111-1307, USA. */
/* Define a symbol indicating that we are using svr3.h. */
#define USING_SVR3_H
@@ -46,27 +27,10 @@ Boston, MA 02111-1307, USA.
environment and assembler syntax we are targeting for. */
#define SVR3_target
-/* Cpp, assembler, linker, library, and startfile spec's. */
-
-/* You should redefine CPP_PREDEFINES in any file which includes this one.
- The definition should be appropriate for the type of target system
- involved, and it should include any -A (assertion) options which are
- appropriate for the given target system. */
+/* Assembler, linker, library, and startfile spec's. */
-#undef CPP_PREDEFINES
-
-/* Output at beginning of assembler file. */
/* The .file command should always begin the output. */
-
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
- do { output_file_directive ((FILE), main_input_filename); \
- if (optimize) { ASM_FILE_START_1 (FILE); } \
- } while (0)
-
-/* By default, do nothing: a few machines support .optim, but not most. */
-#undef ASM_FILE_START_1
-#define ASM_FILE_START_1(FILE)
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
/* This says how to output an assembler line
to define a global common symbol. */
@@ -78,7 +42,7 @@ Boston, MA 02111-1307, USA.
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
( fputs (".comm ", (FILE)), \
assemble_name ((FILE), (NAME)), \
- fprintf ((FILE), ",%u\n", (SIZE)))
+ fprintf ((FILE), ",%lu\n", (unsigned long)(SIZE)))
/* This says how to output an assembler line
to define a local common symbol. */
@@ -93,26 +57,9 @@ Boston, MA 02111-1307, USA.
data_section (); \
ASM_OUTPUT_ALIGN ((FILE), align == -1 ? 2 : align); \
ASM_OUTPUT_LABEL ((FILE), (NAME)); \
- fprintf ((FILE), "\t.set .,.+%u\n", (ROUNDED)); \
+ fprintf ((FILE), "\t.set .,.+%u\n", (int)(ROUNDED)); \
} while (0)
-#if 0 /* For now, let's leave these machine-specific. */
-/* Use crt1.o as a startup file and crtn.o as a closing file. */
-
-#define STARTFILE_SPEC \
- "%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}"
-
-#ifdef CROSS_COMPILE
-#define LIB_SPEC "-lc crtn.o%s"
-#else
-#define LIB_SPEC "%{p:-L/usr/lib/libp}%{pg:-L/usr/lib/libp} -lc crtn.o%s"
-#endif
-
-/* Special flags for the linker. I don't know what they do. */
-
-#define LINK_SPEC "%{T*} %{z:-lm}"
-#endif
-
/* Output #ident as a .ident. */
#undef ASM_OUTPUT_IDENT
@@ -158,16 +105,6 @@ Boston, MA 02111-1307, USA.
#undef USER_LABEL_PREFIX
#define USER_LABEL_PREFIX "_"
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class.
-
- For most svr3 systems, the convention is that any symbol which begins
- with a period is not put into the linker symbol table by the assembler. */
-
-#undef ASM_OUTPUT_INTERNAL_LABEL
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- asm_fprintf (FILE, "%0L%s%d:\n", PREFIX, NUM)
-
/* This is how to store into the string LABEL
the symbol_ref name of an internal numbered label where
PREFIX is the class of label and NUM is the number within the class.
diff --git a/contrib/gcc/config/svr4.h b/contrib/gcc/config/svr4.h
index bc6a3b8ed5dc..ca65cd84aae7 100644
--- a/contrib/gcc/config/svr4.h
+++ b/contrib/gcc/config/svr4.h
@@ -4,20 +4,20 @@
2000, 2001 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
@@ -28,11 +28,7 @@ Boston, MA 02111-1307, USA.
where MACHINE is replaced by the name of the basic hardware that you
are targeting for. Then, in the file MACHINE/svr4.h, put any really
system-specific defines (or overrides of defines) which you find that
- you need. For example, CPP_PREDEFINES is defined here with only the
- defined -Dunix and -DSVR4. You should probably override that in your
- target-specific MACHINE/svr4.h file with a set of defines that
- includes these, but also contains an appropriate define for the type
- of hardware that you are targeting.
+ you need.
*/
/* Define a symbol indicating that we are using svr4.h. */
@@ -45,6 +41,7 @@ Boston, MA 02111-1307, USA.
-z* options (for the linker). Note however that there is no such
thing as a -T option for svr4. */
+#undef SWITCH_TAKES_ARG
#define SWITCH_TAKES_ARG(CHAR) \
(DEFAULT_SWITCH_TAKES_ARG (CHAR) \
|| (CHAR) == 'h' \
@@ -59,12 +56,6 @@ Boston, MA 02111-1307, USA.
&& strcmp (STR, "Tdata") && strcmp (STR, "Ttext") \
&& strcmp (STR, "Tbss"))
-/* You should redefine CPP_PREDEFINES in any file which includes this one.
- The definition should be appropriate for the type of target system
- involved, and it should include any -A (assertion) options which are
- appropriate for the given target system. */
-#undef CPP_PREDEFINES
-
/* Provide an ASM_SPEC appropriate for svr4. Here we try to support as
many of the specialized svr4 assembler options as seems reasonable,
given that there are certain options which we can't (or shouldn't)
@@ -79,22 +70,16 @@ Boston, MA 02111-1307, USA.
Note that gcc doesn't allow a space to follow -Y in a -Ym,* or -Yd,*
option.
+
+ The svr4 assembler wants '-' on the command line if it's expected to
+ read its stdin.
*/
#undef ASM_SPEC
#define ASM_SPEC \
"%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
-/* svr4 assemblers need the `-' (indicating input from stdin) to come after
- the -o option (and its argument) for some reason. If we try to put it
- before the -o option, the assembler will try to read the file named as
- the output file in the -o option as an input file (after it has already
- written some stuff to it) and the binary stuff contained therein will
- cause totally confuse the assembler, resulting in many spurious error
- messages. */
-
-#undef ASM_FINAL_SPEC
-#define ASM_FINAL_SPEC "%|"
+#define AS_NEEDS_DASH_FOR_PIPED_INPUT
/* Under svr4, the normal location of the `ld' and `as' programs is the
/usr/ccs/bin directory. */
@@ -218,8 +203,4 @@ Boston, MA 02111-1307, USA.
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE BITS_PER_WORD
-/* This causes trouble, because it requires the host machine
- to support ANSI C. */
-/* #define MULTIBYTE_CHARS */
-
#define TARGET_HAS_F_SETLKW
diff --git a/contrib/gcc/config/t-darwin b/contrib/gcc/config/t-darwin
index c823fa5d7a4e..a7076ab295dc 100644
--- a/contrib/gcc/config/t-darwin
+++ b/contrib/gcc/config/t-darwin
@@ -1,12 +1,12 @@
-darwin.o: $(srcdir)/config/darwin.c $(CONFIG_H) $(SYSTEM_H) $(RTL_BASE_H) \
- $(REGS_H) hard-reg-set.h insn-config.h conditions.h output.h \
- insn-attr.h flags.h $(TREE_H) $(EXPR_H) reload.h \
- function.h $(GGC_H) $(TM_P_H) gt-darwin.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+darwin.o: $(srcdir)/config/darwin.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(REAL_H) insn-config.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 $(TM_P_H) gt-darwin.h
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/darwin.c
-darwin-c.o: $(srcdir)/config/darwin-c.c $(CONFIG_H) $(SYSTEM_H) \
- $(TREE_H) $(C_TREE_H) c-pragma.h toplev.h cpplib.h $(TM_P_H)
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+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)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/darwin-c.c
gt-darwin.h : s-gtype ; @true
@@ -20,3 +20,5 @@ $(T)crt2$(objext): $(srcdir)/config/darwin-crt2.c $(GCC_PASSES) \
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-darwin.c \
$(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
+
+TARGET_LIBGCC2_CFLAGS = -fPIC
diff --git a/contrib/gcc/config/t-freebsd b/contrib/gcc/config/t-freebsd
index da9c6429acd0..211dbdf6b718 100644
--- a/contrib/gcc/config/t-freebsd
+++ b/contrib/gcc/config/t-freebsd
@@ -1,6 +1,3 @@
-# Don't run fixproto
-STMP_FIXPROTO =
-
# Compile crtbeginS.o and crtendS.o with pic.
CRTSTUFF_T_CFLAGS_S = -fPIC
diff --git a/contrib/gcc/config/t-gnu b/contrib/gcc/config/t-gnu
index 59481ee3635f..7be5d00a718b 100644
--- a/contrib/gcc/config/t-gnu
+++ b/contrib/gcc/config/t-gnu
@@ -1,2 +1,2 @@
# In GNU, "/usr" is a four-letter word.
-SYSTEM_HEADER_DIR = /include
+NATIVE_SYSTEM_HEADER_DIR = /include
diff --git a/contrib/gcc/config/t-kfreebsd-gnu b/contrib/gcc/config/t-kfreebsd-gnu
new file mode 100644
index 000000000000..a40dc7a568a2
--- /dev/null
+++ b/contrib/gcc/config/t-kfreebsd-gnu
@@ -0,0 +1,16 @@
+# glibc provides a limits.h, which must be combined with gcc's limits.h.
+LIMITS_H_TEST = true
+
+# Compile crtbeginS.o and crtendS.o with pic.
+CRTSTUFF_T_CFLAGS_S = -fPIC
+# Compile libgcc2.a with pic.
+TARGET_LIBGCC2_CFLAGS = -fPIC
+
+# Override t-slibgcc-elf-ver to export some libgcc symbols with
+# the symbol versions that glibc used.
+SHLIB_MAPFILES += $(srcdir)/config/libgcc-glibc.ver
+
+# Use unwind-dw2-fde-glibc
+LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
+ $(srcdir)/unwind-sjlj.c
+LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
diff --git a/contrib/gcc/config/t-libunwind b/contrib/gcc/config/t-libunwind
index be50bc481c5f..2204ae316d7a 100644
--- a/contrib/gcc/config/t-libunwind
+++ b/contrib/gcc/config/t-libunwind
@@ -1 +1,5 @@
-LIB2ADDEH = $(srcdir)/unwind-libunwind.c $(srcdir)/unwind-sjlj.c
+# Override the default value from t-slibgcc-elf-ver and mention -lunwind
+# so that the resulting libgcc_s.so has the necessary DT_NEEDED entry for
+# libunwind.
+SHLIB_LC = -lunwind -lc
+LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
diff --git a/contrib/gcc/config/t-linux b/contrib/gcc/config/t-linux
index 61bce29c245f..f25ab6430e98 100644
--- a/contrib/gcc/config/t-linux
+++ b/contrib/gcc/config/t-linux
@@ -1,6 +1,3 @@
-# Don't run fixproto
-STMP_FIXPROTO =
-
# Compile crtbeginS.o and crtendS.o with pic.
CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) -fPIC
# Compile libgcc2.a with pic.
@@ -12,5 +9,5 @@ SHLIB_MAPFILES += $(srcdir)/config/libgcc-glibc.ver
# Use unwind-dw2-fde-glibc
LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \
- $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c
-LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c
+ $(srcdir)/unwind-sjlj.c $(srcdir)/gthr-gnat.c $(srcdir)/unwind-c.c
+LIB2ADDEHDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c gthr-gnat.c
diff --git a/contrib/gcc/config/t-netbsd b/contrib/gcc/config/t-netbsd
index fa2a48863209..843e4100df76 100644
--- a/contrib/gcc/config/t-netbsd
+++ b/contrib/gcc/config/t-netbsd
@@ -1,5 +1,2 @@
-# Don't run fixproto
-STMP_FIXPROTO =
-
# Always build crtstuff with PIC.
CRTSTUFF_T_CFLAGS = -fPIC
diff --git a/contrib/gcc/config/t-openbsd b/contrib/gcc/config/t-openbsd
index 0578cbd62251..2289f154efc4 100644
--- a/contrib/gcc/config/t-openbsd
+++ b/contrib/gcc/config/t-openbsd
@@ -1,5 +1,2 @@
-# Don't run fixproto
-STMP_FIXPROTO =
-
# We don't need GCC's own include files.
USER_H =
diff --git a/contrib/gcc/config/t-rtems b/contrib/gcc/config/t-rtems
index c403ff85ddaf..dfbd3afe9eee 100644
--- a/contrib/gcc/config/t-rtems
+++ b/contrib/gcc/config/t-rtems
@@ -1,6 +1,3 @@
-# RTEMS uses newlib which does not require prototype fixing
-STMP_FIXPROTO =
-
# RTEMS always has limits.h.
LIMITS_H_TEST = true
diff --git a/contrib/gcc/config/t-slibgcc-darwin b/contrib/gcc/config/t-slibgcc-darwin
new file mode 100644
index 000000000000..f27fae4948c6
--- /dev/null
+++ b/contrib/gcc/config/t-slibgcc-darwin
@@ -0,0 +1,30 @@
+# Build a shared libgcc library with the darwin linker.
+SHLIB_MINOR = 1
+SHLIB_REVISION = 0
+SHLIB_VERSTRING = -compatibility_version $(SHLIB_MINOR) -current_version $(SHLIB_MINOR).$(SHLIB_REVISION)
+SHLIB_EXT = .dylib
+SHLIB_SOLINK = @shlib_base_name@.dylib
+SHLIB_SONAME = @shlib_so_name@.$(SHLIB_MINOR).$(SHLIB_REVISION).dylib
+SHLIB_NAME = @shlib_dir@@shlib_so_name@.$(SHLIB_MINOR).$(SHLIB_REVISION).dylib
+SHLIB_MAP = @shlib_map_file@
+SHLIB_OBJS = @shlib_objs@
+SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
+
+SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -dynamiclib -nodefaultlibs \
+ -Wl,-install_name,$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SONAME) \
+ -Wl,-flat_namespace -o $(SHLIB_NAME) \
+ $(SHLIB_VERSTRING) \
+ @multilib_flags@ $(SHLIB_OBJS) -lc && \
+ rm -f $(SHLIB_SOLINK) && \
+ $(LN_S) $(SHLIB_NAME) $(SHLIB_SOLINK)
+# $(slibdir) double quoted to protect it from expansion while building
+# libgcc.mk. We want this delayed until actual install time.
+SHLIB_INSTALL = \
+ $$(SHELL) $$(srcdir)/mkinstalldirs $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL); \
+ $(INSTALL_DATA) $(SHLIB_NAME) \
+ $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SONAME); \
+ rm -f $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK); \
+ $(LN_S) $(SHLIB_SONAME) \
+ $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK)
+SHLIB_MKMAP = $(srcdir)/mkmap-symver.awk
+SHLIB_MAPFILES = $(srcdir)/libgcc-darwin.ver
diff --git a/contrib/gcc/config/t-slibgcc-elf-ver b/contrib/gcc/config/t-slibgcc-elf-ver
index a176b10fa0ab..a4f8ef07c844 100644
--- a/contrib/gcc/config/t-slibgcc-elf-ver
+++ b/contrib/gcc/config/t-slibgcc-elf-ver
@@ -3,8 +3,9 @@
SHLIB_EXT = .so
SHLIB_SOLINK = @shlib_base_name@.so
-SHLIB_SONAME = @shlib_so_name@.so.1
-SHLIB_NAME = @shlib_dir@@shlib_so_name@.so.1
+SHLIB_SOVERSION = 1
+SHLIB_SONAME = @shlib_so_name@.so.$(SHLIB_SOVERSION)
+SHLIB_NAME = @shlib_dir@@shlib_so_name@.so.$(SHLIB_SOVERSION)
SHLIB_MAP = @shlib_map_file@
SHLIB_OBJS = @shlib_objs@
SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
diff --git a/contrib/gcc/config/t-vxworks b/contrib/gcc/config/t-vxworks
new file mode 100644
index 000000000000..ebf47e1bcceb
--- /dev/null
+++ b/contrib/gcc/config/t-vxworks
@@ -0,0 +1,22 @@
+# Since we have a functional assert.h, use it.
+INSTALL_ASSERT_H =
+
+# Build libgcc using the multilib mechanism
+
+LIBGCC = stmp-multilib
+INSTALL_LIBGCC = install-multilib
+
+# No special flags needed for libgcc.a
+TARGET_LIBGCC2_CFLAGS =
+
+# Don't build libgcc.a with debug info
+LIBGCC2_DEBUG_CFLAGS =
+
+# Extra libgcc2 module used by gthr-vxworks.h functions
+LIB2FUNCS_EXTRA = $(srcdir)/config/vxlib.c
+
+# This ensures that the correct target headers are used; some
+# VxWorks system headers have names that collide with GCC's
+# internal (host) headers, e.g. regs.h.
+# FIXME: May not be necessary anymore.
+LIBGCC2_INCLUDES="-I$(SYSTEM_HEADER_DIR)"
diff --git a/contrib/gcc/config/usegas.h b/contrib/gcc/config/usegas.h
index cf20c558e36d..54fa9bd62854 100644
--- a/contrib/gcc/config/usegas.h
+++ b/contrib/gcc/config/usegas.h
@@ -1,19 +1,19 @@
/* Copyright (C) 2001 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/config/vxlib.c b/contrib/gcc/config/vxlib.c
new file mode 100644
index 000000000000..20a257e02c44
--- /dev/null
+++ b/contrib/gcc/config/vxlib.c
@@ -0,0 +1,325 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ Contributed by Zack Weinberg <zack@codesourcery.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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Threads compatibility routines for libgcc2 for VxWorks.
+ These are out-of-line routines called from gthr-vxworks.h. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
+#include "tconfig.h"
+#include "tsystem.h"
+#include "gthr.h"
+
+#include <vxWorks.h>
+#include <vxLib.h>
+#include <taskLib.h>
+#include <taskHookLib.h>
+
+/* Init-once operation.
+
+ This would be a clone of the implementation from gthr-solaris.h,
+ except that we have a bootstrap problem - the whole point of this
+ exercise is to prevent double initialization, but if two threads
+ are racing with each other, once->mutex is liable to be initialized
+ by both. Then each thread will lock its own mutex, and proceed to
+ call the initialization routine.
+
+ So instead we use a bare atomic primitive (vxTas()) to handle
+ mutual exclusion. Threads losing the race then busy-wait, calling
+ taskDelay() to yield the processor, until the initialization is
+ completed. Inefficient, but reliable. */
+
+int
+__gthread_once (__gthread_once_t *guard, void (*func)(void))
+{
+ if (guard->done)
+ return 0;
+
+ while (!vxTas ((void *)&guard->busy))
+ taskDelay (1);
+
+ /* Only one thread at a time gets here. Check ->done again, then
+ go ahead and call func() if no one has done it yet. */
+ if (!guard->done)
+ {
+ func ();
+ guard->done = 1;
+ }
+
+ guard->busy = 0;
+ return 0;
+}
+
+/* Thread-specific data.
+
+ We reserve a field in the TCB to point to a dynamically allocated
+ array which is used to store TSD values. A TSD key is simply an
+ offset in this array. The exact location of the TCB field is not
+ known to this code nor to vxlib.c -- all access to it indirects
+ through the routines __gthread_get_tsd_data and
+ __gthread_set_tsd_data, which are provided by the VxWorks kernel.
+
+ There is also a global array which records which keys are valid and
+ which have destructors.
+
+ A task delete hook is installed to execute key destructors. The
+ routines __gthread_enter_tsd_dtor_context and
+ __gthread_leave_tsd_dtor_context, which are also provided by the
+ kernel, ensure that it is safe to call free() on memory allocated
+ by the task being deleted. (This is a no-op on VxWorks 5, but
+ a major undertaking on AE.)
+
+ Since this interface is used to allocate only a small number of
+ keys, the table size is small and static, which simplifies the
+ code quite a bit. Revisit this if and when it becomes necessary. */
+
+#define MAX_KEYS 4
+
+/* This is the structure pointed to by the pointer returned
+ by __gthread_get_tsd_data. */
+struct tsd_data
+{
+ void *values[MAX_KEYS];
+ unsigned int generation[MAX_KEYS];
+};
+
+
+/* kernel provided routines */
+extern void *__gthread_get_tsd_data (WIND_TCB *tcb);
+extern void __gthread_set_tsd_data (WIND_TCB *tcb, void *data);
+
+extern void __gthread_enter_tsd_dtor_context (WIND_TCB *tcb);
+extern void __gthread_leave_tsd_dtor_context (WIND_TCB *tcb);
+
+typedef void (*fet_callback_t) (WIND_TCB *, unsigned int);
+extern void __gthread_for_all_tasks (fet_callback_t fun, unsigned int number);
+
+/* This is a global structure which records all of the active keys.
+
+ A key is potentially valid (i.e. has been handed out by
+ __gthread_key_create) iff its generation count in this structure is
+ even. In that case, the matching entry in the dtors array is a
+ routine to be called when a thread terminates with a valid,
+ non-NULL specific value for that key.
+
+ A key is actually valid in a thread T iff the generation count
+ stored in this structure is equal to the generation count stored in
+ T's specific-value structure. */
+
+typedef void (*tsd_dtor) (void *);
+
+struct tsd_keys
+{
+ tsd_dtor dtor[MAX_KEYS];
+ unsigned int generation[MAX_KEYS];
+};
+
+#define KEY_VALID_P(key) !(tsd_keys.generation[key] & 1)
+
+/* Note: if MAX_KEYS is increased, this initializer must be updated
+ to match. All the generation counts begin at 1, which means no
+ key is valid. */
+static struct tsd_keys tsd_keys =
+{
+ { 0, 0, 0, 0 },
+ { 1, 1, 1, 1 }
+};
+
+/* This lock protects the tsd_keys structure. */
+static __gthread_mutex_t tsd_lock;
+
+static __gthread_once_t tsd_init_guard = __GTHREAD_ONCE_INIT;
+
+/* Internal routines. */
+
+/* The task TCB has just been deleted. Call the destructor
+ function for each TSD key that has both a destructor and
+ a non-NULL specific value in this thread.
+
+ This routine does not need to take tsd_lock; the generation
+ count protects us from calling a stale destructor. It does
+ need to read tsd_keys.dtor[key] atomically. */
+
+static void
+tsd_delete_hook (WIND_TCB *tcb)
+{
+ struct tsd_data *data = __gthread_get_tsd_data (tcb);
+ __gthread_key_t key;
+
+ if (data)
+ {
+ __gthread_enter_tsd_dtor_context (tcb);
+ for (key = 0; key < MAX_KEYS; key++)
+ {
+ if (data->generation[key] == tsd_keys.generation[key])
+ {
+ tsd_dtor dtor = tsd_keys.dtor[key];
+
+ if (dtor)
+ dtor (data->values[key]);
+ }
+ }
+ free (data);
+ __gthread_set_tsd_data (tcb, 0);
+ __gthread_leave_tsd_dtor_context (tcb);
+ }
+}
+
+/* Initialize global data used by the TSD system. */
+static void
+tsd_init (void)
+{
+ taskDeleteHookAdd ((FUNCPTR)tsd_delete_hook);
+ __GTHREAD_MUTEX_INIT_FUNCTION (&tsd_lock);
+}
+
+/* External interface */
+
+/* Store in KEYP a value which can be passed to __gthread_setspecific/
+ __gthread_getspecific to store and retrieve a value which is
+ specific to each calling thread. If DTOR is not NULL, it will be
+ called when a thread terminates with a non-NULL specific value for
+ this key, with the value as its sole argument. */
+
+int
+__gthread_key_create (__gthread_key_t *keyp, tsd_dtor dtor)
+{
+ __gthread_key_t key;
+
+ __gthread_once (&tsd_init_guard, tsd_init);
+
+ if (__gthread_mutex_lock (&tsd_lock) == ERROR)
+ return errno;
+
+ for (key = 0; key < MAX_KEYS; key++)
+ if (!KEY_VALID_P (key))
+ goto found_slot;
+
+ /* no room */
+ __gthread_mutex_unlock (&tsd_lock);
+ return EAGAIN;
+
+ found_slot:
+ tsd_keys.generation[key]++; /* making it even */
+ tsd_keys.dtor[key] = dtor;
+ *keyp = key;
+ __gthread_mutex_unlock (&tsd_lock);
+ return 0;
+}
+
+/* Invalidate KEY; it can no longer be used as an argument to
+ setspecific/getspecific. Note that this does NOT call destructor
+ functions for any live values for this key. */
+int
+__gthread_key_delete (__gthread_key_t key)
+{
+ if (key >= MAX_KEYS)
+ return EINVAL;
+
+ __gthread_once (&tsd_init_guard, tsd_init);
+
+ if (__gthread_mutex_lock (&tsd_lock) == ERROR)
+ return errno;
+
+ if (!KEY_VALID_P (key))
+ {
+ __gthread_mutex_unlock (&tsd_lock);
+ return EINVAL;
+ }
+
+ tsd_keys.generation[key]++; /* making it odd */
+ tsd_keys.dtor[key] = 0;
+
+ __gthread_mutex_unlock (&tsd_lock);
+ return 0;
+}
+
+/* Retrieve the thread-specific value for KEY. If it has never been
+ set in this thread, or KEY is invalid, returns NULL.
+
+ It does not matter if this function races with key_create or
+ key_delete; the worst that can happen is you get a value other than
+ the one that a serialized implementation would have provided. */
+
+void *
+__gthread_getspecific (__gthread_key_t key)
+{
+ struct tsd_data *data;
+
+ if (key >= MAX_KEYS)
+ return 0;
+
+ data = __gthread_get_tsd_data (taskTcb (taskIdSelf ()));
+
+ if (!data)
+ return 0;
+
+ if (data->generation[key] != tsd_keys.generation[key])
+ return 0;
+
+ return data->values[key];
+}
+
+/* Set the thread-specific value for KEY. If KEY is invalid, or
+ memory allocation fails, returns -1, otherwise 0.
+
+ The generation count protects this function against races with
+ key_create/key_delete; the worst thing that can happen is that a
+ value is successfully stored into a dead generation (and then
+ immediately becomes invalid). However, we do have to make sure
+ to read tsd_keys.generation[key] atomically. */
+
+int
+__gthread_setspecific (__gthread_key_t key, void *value)
+{
+ struct tsd_data *data;
+ WIND_TCB *tcb;
+ unsigned int generation;
+
+ if (key >= MAX_KEYS)
+ return EINVAL;
+
+ tcb = taskTcb (taskIdSelf ());
+ data = __gthread_get_tsd_data (tcb);
+ if (!data)
+ {
+ data = malloc (sizeof (struct tsd_data));
+ if (!data)
+ return ENOMEM;
+
+ memset (data, 0, sizeof (struct tsd_data));
+ __gthread_set_tsd_data (tcb, data);
+ }
+
+ generation = tsd_keys.generation[key];
+
+ if (generation & 1)
+ return EINVAL;
+
+ data->generation[key] = generation;
+ data->values[key] = value;
+
+ return 0;
+}
diff --git a/contrib/gcc/config/vxworks.h b/contrib/gcc/config/vxworks.h
new file mode 100644
index 000000000000..085eb8ce6484
--- /dev/null
+++ b/contrib/gcc/config/vxworks.h
@@ -0,0 +1,64 @@
+/* Common VxWorks target definitions for GCC.
+ Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Contributed by Wind River Systems.
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Specify what to link with. */
+/* VxWorks does all the library stuff itself. */
+#undef LIB_SPEC
+#define LIB_SPEC ""
+
+#undef LINK_SPEC
+#define LINK_SPEC "-r"
+
+/* VxWorks provides the functionality of crt0.o and friends itself. */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC ""
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC ""
+
+/* VxWorks cannot have dots in constructor labels, because it uses a
+ mutant variation of collect2 that generates C code instead of
+ assembly. Thus each constructor label must be a legitimate C
+ symbol. FIXME: Have VxWorks use real collect2 instead. */
+
+#undef NO_DOLLAR_IN_LABEL
+#define NO_DOT_IN_LABEL
+
+/* enable #pragma pack(n) */
+#define HANDLE_SYSV_PRAGMA
+
+/* No underscore is prepended to any C symbol name. */
+#undef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX ""
+
+/* VxWorks uses wchar_t == unsigned short (UCS2) on all architectures. */
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "short unsigned int"
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE 16
+
+/* Dwarf2 unwind info is not supported. */
+#define DWARF2_UNWIND_INFO 0
+/* Weak symbols and link-once sections are not enabled by default. */
+#define DEFAULT_USE_WEAK 0
+
+/* Only supported debug format is Dwarf2. */
+#undef DBX_DEBUGGING_INFO
diff --git a/contrib/gcc/config/windiss.h b/contrib/gcc/config/windiss.h
new file mode 100644
index 000000000000..7aef9b678813
--- /dev/null
+++ b/contrib/gcc/config/windiss.h
@@ -0,0 +1,38 @@
+/* Support for GCC using WindISS simulator.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by CodeSourcery, LLC.
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+/* windiss uses wchar_t == unsigned short (UCS2) on all architectures. */
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "short unsigned int"
+#undef WCHAR_TYPE_SIZE
+#define WCHAR_TYPE_SIZE 16
+
+/* windiss has wint_t == int */
+#undef WINT_TYPE
+#define WINT_TYPE "int"
+
+/* No profiling. */
+#undef FUNCTION_PROFILER
+#define FUNCTION_PROFILER(FILE, LABELNO) \
+{ \
+ sorry ("profiler support for WindISS"); \
+}
diff --git a/contrib/gcc/configure b/contrib/gcc/configure
index 74b8a4fa6083..e9d75d91d9a9 100755
--- a/contrib/gcc/configure
+++ b/contrib/gcc/configure
@@ -1,116 +1,324 @@
#! /bin/sh
-
# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.13
-# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+# Generated by GNU Autoconf 2.57.
#
+# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
+do
+ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+ { (exit 1); exit 1; }; }
+ fi
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
+ else
+ as_ln_s='ln -s'
+ fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
-# Defaults:
-ac_help=
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
ac_default_prefix=/usr/local
-# Any additions from configure.in:
-ac_help="$ac_help
- --with-gnu-ld arrange to work with GNU ld."
-ac_help="$ac_help
- --with-ld arrange to use the specified ld (full pathname)"
-ac_help="$ac_help
- --with-gnu-as arrange to work with GNU as"
-ac_help="$ac_help
- --with-as arrange to use the specified as (full pathname)"
-ac_help="$ac_help
- --with-stabs arrange to use stabs instead of host debug format"
-ac_help="$ac_help
- --with-elf arrange to use ELF instead of host debug format"
-ac_help="$ac_help
- --with-local-prefix=DIR specifies directory to put local include"
-ac_help="$ac_help
- --with-gxx-include-dir=DIR
- specifies directory to put g++ header files"
-ac_help="$ac_help
- --enable-multilib enable library support for multiple ABIs"
-ac_help="$ac_help
- --enable-checking[=LIST]
- enable expensive run-time checks. With LIST,
- enable only specific categories of checks.
- Categories are: misc,tree,rtl,rtlflag,gc,gcac;
- default is misc,tree,gc,rtlflag"
-ac_help="$ac_help
- --enable-coverage[=LEVEL]
- enable compiler\'s code coverage collection.
- Use to measure compiler performance and locate
- unused parts of the compiler. With LEVEL, specificy
- optimization. Values are opt, noopt,
- default is noopt"
-ac_help="$ac_help
- --with-cpp-install-dir=DIR
- install the user visible C preprocessor in DIR
- (relative to PREFIX) as well as PREFIX/bin"
-ac_help="$ac_help
- --enable-__cxa_atexit enable __cxa_atexit for C++"
-ac_help="$ac_help
- --enable-c-mbchar enable multibyte characters for C and C++"
-ac_help="$ac_help
- --enable-threads enable thread usage for target GCC
- --enable-threads=LIB use LIB thread package for target GCC"
-ac_help="$ac_help
- --enable-objc-gc enable the use of Boehm's garbage collector with
- the GNU Objective-C runtime"
-ac_help="$ac_help
- --with-dwarf2 force the default debug format to be DWARF 2"
-ac_help="$ac_help
- --disable-shared don't provide a shared libgcc"
-ac_help="$ac_help
- --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib"
-ac_help="$ac_help
- --enable-initfini-array use .init_array/.fini_array sections"
-ac_help="$ac_help
- --enable-sjlj-exceptions
- arrange to use setjmp/longjmp exception handling"
-ac_help="$ac_help
- --enable-libunwind-exceptions force use libunwind for exceptions"
-ac_help="$ac_help
- --enable-nls use Native Language Support (default)"
-ac_help="$ac_help
- --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib"
-ac_help="$ac_help
- --disable-nls do not use Native Language Support"
-ac_help="$ac_help
- --with-included-gettext use the GNU gettext library included here"
-ac_help="$ac_help
- --disable-win32-registry
- disable lookup of installation paths in the
- Registry on Windows hosts
- --enable-win32-registry enable registry lookup (default)
- --enable-win32-registry=KEY
- use KEY instead of GCC version as the last portion
- of the registry key"
-ac_help="$ac_help
- --with-gc={simple,page} choose the garbage collection mechanism to use
- with the compiler"
-ac_help="$ac_help
- --with-system-zlib use installed libz"
-ac_help="$ac_help
- --enable-maintainer-mode
- enable make rules and dependencies not useful
- (and sometimes confusing) to the casual installer"
-ac_help="$ac_help
- --enable-version-specific-runtime-libs
- specify that runtime libraries should be
- installed in a compiler-specific directory"
-ac_help="$ac_help
- --with-slibdir=DIR shared libraries in DIR [LIBDIR]"
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete. It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="tree.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+# include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# 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 build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os build_subdir host_subdir target_subdir GENINSRC CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT NO_MINUS_C_MINUS_O OUTPUT_OPTION CPP GNATBIND ac_ct_GNATBIND strict1_warn warn_cflags WERROR nocommon_flag EGREP valgrind_path valgrind_path_defines valgrind_command coverage_flags enable_multilib enable_shared TARGET_SYSTEM_ROOT TARGET_SYSTEM_ROOT_DEFINE CROSS_SYSTEM_HEADER_DIR onestep SET_MAKE AWK LN LN_S RANLIB ac_ct_RANLIB INSTALL INSTALL_PROGRAM INSTALL_DATA make_compare_target have_mktemp_command MAKEINFO BUILD_INFO GENERATED_MANPAGES FLEX BISON stage1_cflags COLLECT2_LIBS GNAT_LIBEXC LDEXP_LIB TARGET_GETGROUPS_T LIBICONV LIBICONV_DEP manext objext extra_modes_file FORBUILD PACKAGE VERSION USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS CROSS ALL SYSTEM_HEADER_DIR inhibit_libc BUILD_PREFIX BUILD_PREFIX_1 CC_FOR_BUILD BUILD_CFLAGS STMP_FIXINC STMP_FIXPROTO libgcc_visibility gthread_flags GGC zlibdir zlibinc MAINT gcc_tooldir dollar slibdir objdir subdirs srcdir all_boot_languages all_compilers all_gtfiles all_gtfiles_files_langs all_gtfiles_files_files all_lang_makefrags all_lang_makefiles all_languages all_stagestuff build_exeext build_install_headers_dir build_xm_file_list build_xm_include_list build_xm_defines check_languages cc_set_by_configure quoted_cc_set_by_configure cpp_install_dir xmake_file tmake_file extra_gcc_objs extra_headers_list extra_objs extra_parts extra_passes extra_programs float_h_file gcc_config_arguments gcc_gxx_include_dir libstdcxx_incdir gcc_version gcc_version_full gcc_version_trigger host_exeext host_xm_file_list host_xm_include_list host_xm_defines out_host_hook_obj install lang_opt_files lang_specs_files lang_tree_files local_prefix md_file objc_boehm_gc out_file out_object_file stage_prefix_set_by_configure quoted_stage_prefix_set_by_configure symbolic_link thread_file tm_file_list tm_include_list tm_defines tm_p_file_list tm_p_include_list xm_file_list xm_include_list xm_defines target_noncanonical c_target_objs cxx_target_objs target_cpu_default LIBOBJS LTLIBOBJS'
+ac_subst_files='language_hooks'
# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
# The variables have the same names as the options, with
# dashes changed to underlines.
-build=NONE
-cache_file=./config.cache
+cache_file=/dev/null
exec_prefix=NONE
-host=NONE
no_create=
-nonopt=NONE
no_recursion=
prefix=NONE
program_prefix=NONE
@@ -119,10 +327,15 @@ program_transform_name=s,x,x,
silent=
site=
srcdir=
-target=NONE
verbose=
x_includes=NONE
x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
@@ -136,17 +349,9 @@ oldincludedir='/usr/include'
infodir='${prefix}/info'
mandir='${prefix}/man'
-# Initialize some other variables.
-subdirs=
-MFLAGS= MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-# Maximum number of lines to put in a shell here document.
-ac_max_here_lines=12
-
ac_prev=
for ac_option
do
-
# If the previous option needs an argument, assign it.
if test -n "$ac_prev"; then
eval "$ac_prev=\$ac_option"
@@ -154,59 +359,59 @@ do
continue
fi
- case "$ac_option" in
- -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
- *) ac_optarg= ;;
- esac
+ ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
# Accept the important Cygnus configure options, so we can diagnose typos.
- case "$ac_option" in
+ case $ac_option in
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
-bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
- bindir="$ac_optarg" ;;
+ bindir=$ac_optarg ;;
-build | --build | --buil | --bui | --bu)
- ac_prev=build ;;
+ ac_prev=build_alias ;;
-build=* | --build=* | --buil=* | --bui=* | --bu=*)
- build="$ac_optarg" ;;
+ build_alias=$ac_optarg ;;
-cache-file | --cache-file | --cache-fil | --cache-fi \
| --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
ac_prev=cache_file ;;
-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
- cache_file="$ac_optarg" ;;
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
-datadir | --datadir | --datadi | --datad | --data | --dat | --da)
ac_prev=datadir ;;
-datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
| --da=*)
- datadir="$ac_optarg" ;;
+ datadir=$ac_optarg ;;
-disable-* | --disable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- eval "enable_${ac_feature}=no" ;;
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ eval "enable_$ac_feature=no" ;;
-enable-* | --enable-*)
- ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
- fi
- ac_feature=`echo $ac_feature| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
+ expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+ { (exit 1); exit 1; }; }
+ ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
*) ac_optarg=yes ;;
esac
- eval "enable_${ac_feature}='$ac_optarg'" ;;
+ eval "enable_$ac_feature='$ac_optarg'" ;;
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -215,95 +420,47 @@ do
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
| --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
| --exec=* | --exe=* | --ex=*)
- exec_prefix="$ac_optarg" ;;
+ exec_prefix=$ac_optarg ;;
-gas | --gas | --ga | --g)
# Obsolete; use --with-gas.
with_gas=yes ;;
- -help | --help | --hel | --he)
- # 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 << EOF
-Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
-Configuration:
- --cache-file=FILE cache test results in FILE
- --help print this message
- --no-create do not create output files
- --quiet, --silent do not print \`checking...' messages
- --version print the version of autoconf that created configure
-Directory and file names:
- --prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
- --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [same as prefix]
- --bindir=DIR user executables in DIR [EPREFIX/bin]
- --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
- --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data in DIR
- [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data in DIR
- [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
- --libdir=DIR object code libraries in DIR [EPREFIX/lib]
- --includedir=DIR C header files in DIR [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
- --infodir=DIR info documentation in DIR [PREFIX/info]
- --mandir=DIR man documentation in DIR [PREFIX/man]
- --srcdir=DIR find the sources in DIR [configure dir or ..]
- --program-prefix=PREFIX prepend PREFIX to installed program names
- --program-suffix=SUFFIX append SUFFIX to installed program names
- --program-transform-name=PROGRAM
- run sed PROGRAM on installed program names
-EOF
- cat << EOF
-Host type:
- --build=BUILD configure for building on BUILD [BUILD=HOST]
- --host=HOST configure for HOST [guessed]
- --target=TARGET configure for TARGET [TARGET=HOST]
-Features and packages:
- --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
- --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
- --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
- --x-includes=DIR X include files are in DIR
- --x-libraries=DIR X library files are in DIR
-EOF
- if test -n "$ac_help"; then
- echo "--enable and --with options recognized:$ac_help"
- fi
- exit 0 ;;
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
-host | --host | --hos | --ho)
- ac_prev=host ;;
+ ac_prev=host_alias ;;
-host=* | --host=* | --hos=* | --ho=*)
- host="$ac_optarg" ;;
+ host_alias=$ac_optarg ;;
-includedir | --includedir | --includedi | --included | --include \
| --includ | --inclu | --incl | --inc)
ac_prev=includedir ;;
-includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
| --includ=* | --inclu=* | --incl=* | --inc=*)
- includedir="$ac_optarg" ;;
+ includedir=$ac_optarg ;;
-infodir | --infodir | --infodi | --infod | --info | --inf)
ac_prev=infodir ;;
-infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
- infodir="$ac_optarg" ;;
+ infodir=$ac_optarg ;;
-libdir | --libdir | --libdi | --libd)
ac_prev=libdir ;;
-libdir=* | --libdir=* | --libdi=* | --libd=*)
- libdir="$ac_optarg" ;;
+ libdir=$ac_optarg ;;
-libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
| --libexe | --libex | --libe)
ac_prev=libexecdir ;;
-libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
| --libexe=* | --libex=* | --libe=*)
- libexecdir="$ac_optarg" ;;
+ libexecdir=$ac_optarg ;;
-localstatedir | --localstatedir | --localstatedi | --localstated \
| --localstate | --localstat | --localsta | --localst \
@@ -312,19 +469,19 @@ EOF
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
| --localstate=* | --localstat=* | --localsta=* | --localst=* \
| --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
- localstatedir="$ac_optarg" ;;
+ localstatedir=$ac_optarg ;;
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
ac_prev=mandir ;;
-mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
- mandir="$ac_optarg" ;;
+ mandir=$ac_optarg ;;
-nfp | --nfp | --nf)
# Obsolete; use --without-fp.
with_fp=no ;;
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c)
+ | --no-cr | --no-c | -n)
no_create=yes ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
@@ -338,26 +495,26 @@ EOF
-oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
| --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
| --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
- oldincludedir="$ac_optarg" ;;
+ oldincludedir=$ac_optarg ;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
- prefix="$ac_optarg" ;;
+ prefix=$ac_optarg ;;
-program-prefix | --program-prefix | --program-prefi | --program-pref \
| --program-pre | --program-pr | --program-p)
ac_prev=program_prefix ;;
-program-prefix=* | --program-prefix=* | --program-prefi=* \
| --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
- program_prefix="$ac_optarg" ;;
+ program_prefix=$ac_optarg ;;
-program-suffix | --program-suffix | --program-suffi | --program-suff \
| --program-suf | --program-su | --program-s)
ac_prev=program_suffix ;;
-program-suffix=* | --program-suffix=* | --program-suffi=* \
| --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
- program_suffix="$ac_optarg" ;;
+ program_suffix=$ac_optarg ;;
-program-transform-name | --program-transform-name \
| --program-transform-nam | --program-transform-na \
@@ -374,7 +531,7 @@ EOF
| --program-transfo=* | --program-transf=* \
| --program-trans=* | --program-tran=* \
| --progr-tra=* | --program-tr=* | --program-t=*)
- program_transform_name="$ac_optarg" ;;
+ program_transform_name=$ac_optarg ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
@@ -384,7 +541,7 @@ EOF
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
| --sbi=* | --sb=*)
- sbindir="$ac_optarg" ;;
+ sbindir=$ac_optarg ;;
-sharedstatedir | --sharedstatedir | --sharedstatedi \
| --sharedstated | --sharedstate | --sharedstat | --sharedsta \
@@ -395,58 +552,57 @@ EOF
| --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
| --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
| --sha=* | --sh=*)
- sharedstatedir="$ac_optarg" ;;
+ sharedstatedir=$ac_optarg ;;
-site | --site | --sit)
ac_prev=site ;;
-site=* | --site=* | --sit=*)
- site="$ac_optarg" ;;
+ site=$ac_optarg ;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
- srcdir="$ac_optarg" ;;
+ srcdir=$ac_optarg ;;
-sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
| --syscon | --sysco | --sysc | --sys | --sy)
ac_prev=sysconfdir ;;
-sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
| --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
- sysconfdir="$ac_optarg" ;;
+ sysconfdir=$ac_optarg ;;
-target | --target | --targe | --targ | --tar | --ta | --t)
- ac_prev=target ;;
+ ac_prev=target_alias ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
- target="$ac_optarg" ;;
+ target_alias=$ac_optarg ;;
-v | -verbose | --verbose | --verbos | --verbo | --verb)
verbose=yes ;;
- -version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.13"
- exit 0 ;;
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
-with-* | --with-*)
- ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
ac_package=`echo $ac_package| sed 's/-/_/g'`
- case "$ac_option" in
- *=*) ;;
+ case $ac_option in
+ *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
*) ac_optarg=yes ;;
esac
- eval "with_${ac_package}='$ac_optarg'" ;;
+ eval "with_$ac_package='$ac_optarg'" ;;
-without-* | --without-*)
- ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
- if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
- { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
- fi
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- eval "with_${ac_package}=no" ;;
+ expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid package name: $ac_package" >&2
+ { (exit 1); exit 1; }; }
+ ac_package=`echo $ac_package | sed 's/-/_/g'`
+ eval "with_$ac_package=no" ;;
--x)
# Obsolete; use --with-x.
@@ -457,99 +613,110 @@ EOF
ac_prev=x_includes ;;
-x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
| --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
- x_includes="$ac_optarg" ;;
+ x_includes=$ac_optarg ;;
-x-libraries | --x-libraries | --x-librarie | --x-librari \
| --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
ac_prev=x_libraries ;;
-x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
- x_libraries="$ac_optarg" ;;
+ x_libraries=$ac_optarg ;;
- -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+ { (exit 1); exit 1; }; }
;;
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+ { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+ { (exit 1); exit 1; }; }
+ ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+ eval "$ac_envvar='$ac_optarg'"
+ export $ac_envvar ;;
+
*)
- if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
- echo "configure: warning: $ac_option: invalid host type" 1>&2
- fi
- if test "x$nonopt" != xNONE; then
- { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
- fi
- nonopt="$ac_option"
+ # FIXME: should be removed in autoconf 3.0.
+ echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
;;
esac
done
if test -n "$ac_prev"; then
- { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
-fi
-
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
-# File descriptor usage:
-# 0 standard input
-# 1 file creation
-# 2 errors and warnings
-# 3 some systems may open it to /dev/tty
-# 4 used on the Kubota Titan
-# 6 checking for... messages and results
-# 5 compiler messages saved in config.log
-if test "$silent" = yes; then
- exec 6>/dev/null
-else
- exec 6>&1
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ { echo "$as_me: error: missing argument to $ac_option" >&2
+ { (exit 1); exit 1; }; }
fi
-exec 5>./config.log
-echo "\
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-" 1>&5
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
+ esac
+done
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Also quote any args containing shell metacharacters.
-ac_configure_args=
-for ac_arg
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+ localstatedir libdir includedir oldincludedir infodir mandir
do
- case "$ac_arg" in
- -no-create | --no-create | --no-creat | --no-crea | --no-cre \
- | --no-cr | --no-c) ;;
- -no-recursion | --no-recursion | --no-recursio | --no-recursi \
- | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
- ac_configure_args="$ac_configure_args '$ac_arg'" ;;
- *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ eval ac_val=$`echo $ac_var`
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) ;;
+ *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+ { (exit 1); exit 1; }; };;
esac
done
-# NLS nuisances.
-# Only set these to C if already set. These must not be set unconditionally
-# because not all systems understand e.g. LANG=C (notably SCO).
-# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
-# Non-C LC_CTYPE values break the ctype check.
-if test "${LANG+set}" = set; then LANG=C; export LANG; fi
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
-if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
-if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo > confdefs.h
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
-# A filename unique to this package, relative to the directory that
-# configure is in, which we can look for to find out if srcdir is correct.
-ac_unique_file=tree.c
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
ac_srcdir_defaulted=yes
# Try the directory containing this script, then its parent.
- ac_prog=$0
- ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
- test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
srcdir=$ac_confdir
if test ! -r $srcdir/$ac_unique_file; then
srcdir=..
@@ -559,13 +726,500 @@ else
fi
if test ! -r $srcdir/$ac_unique_file; then
if test "$ac_srcdir_defaulted" = yes; then
- { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+ { (exit 1); exit 1; }; }
else
- { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+ { (exit 1); exit 1; }; }
fi
fi
-srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+ { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+ { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+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 this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+ cat <<_ACEOF
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --infodir=DIR info documentation [PREFIX/info]
+ --mandir=DIR man documentation [PREFIX/man]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+ --target=TARGET configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-generated-files-in-srcdir
+ put copies of generated files in source dir
+ intended for creating source tarballs for users
+ without texinfo bison or flex.
+ --enable-werror enable -Werror in bootstrap stage2 and later
+ --enable-checking=LIST
+ enable expensive run-time checks. With LIST,
+ enable only specific categories of checks.
+ Categories are: misc,tree,rtl,rtlflag,gc,gcac,fold;
+ default is no checking
+ --enable-coverage=LEVEL
+ enable compiler\'s code coverage collection.
+ Use to measure compiler performance and locate
+ unused parts of the compiler. With LEVEL, specify
+ optimization. Values are opt, noopt,
+ default is noopt
+ --enable-gather-detailed-mem-stats enable detailed memory allocation stats gathering
+ --enable-multilib enable library support for multiple ABIs
+ --enable-__cxa_atexit enable __cxa_atexit for C++
+ --enable-threads enable thread usage for target GCC
+ --enable-threads=LIB use LIB thread package for target GCC
+ --enable-objc-gc enable the use of Boehm's garbage collector with
+ the GNU Objective-C runtime
+ --disable-shared don't provide a shared libgcc
+ --enable-intermodule build the compiler in one step
+ --enable-initfini-array use .init_array/.fini_array sections
+ --enable-sjlj-exceptions
+ arrange to use setjmp/longjmp exception handling
+ --enable-libunwind-exceptions force use libunwind for exceptions
+ --disable-win32-registry
+ disable lookup of installation paths in the
+ Registry on Windows hosts
+ --enable-win32-registry enable registry lookup (default)
+ --enable-win32-registry=KEY
+ use KEY instead of GCC version as the last portion
+ of the registry key
+ --enable-maintainer-mode
+ enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+ --enable-version-specific-runtime-libs
+ specify that runtime libraries should be
+ installed in a compiler-specific directory
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-local-prefix=DIR specifies directory to put local include
+ --with-gxx-include-dir=DIR
+ specifies directory to put g++ header files
+ --with-cpp-install-dir=DIR
+ install the user visible C preprocessor in DIR
+ (relative to PREFIX) as well as PREFIX/bin
+ --with-gnu-ld arrange to work with GNU ld.
+ --with-ld arrange to use the specified ld (full pathname)
+ --with-gnu-as arrange to work with GNU as
+ --with-as arrange to use the specified as (full pathname)
+ --with-stabs arrange to use stabs instead of host debug format
+ --with-dwarf2 force the default debug format to be DWARF 2
+ --with-sysroot=DIR Search for usr/lib, usr/include, et al, within DIR.
+ --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib
+ --with-gc={simple,page,zone} choose the garbage collection mechanism to use
+ with the compiler
+ --with-system-zlib use installed libz
+ --with-slibdir=DIR shared libraries in DIR LIBDIR
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
+ headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ ac_popdir=`pwd`
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d $ac_dir || continue
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+ cd $ac_dir
+ # Check for guested configure; otherwise get Cygnus style configure.
+ if test -f $ac_srcdir/configure.gnu; then
+ echo
+ $SHELL $ac_srcdir/configure.gnu --help=recursive
+ elif test -f $ac_srcdir/configure; then
+ echo
+ $SHELL $ac_srcdir/configure --help=recursive
+ elif test -f $ac_srcdir/configure.ac ||
+ test -f $ac_srcdir/configure.in; then
+ echo
+ $ac_configure --help
+ else
+ echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi
+ cd $ac_popdir
+ done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+ cat <<\_ACEOF
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit 0
+fi
+exec 5>config.log
+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 $as_me, which was
+generated by GNU Autoconf 2.57. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ echo "PATH: $as_dir"
+done
+
+} >&5
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 2)
+ ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+ # Get rid of the leading space.
+ ac_sep=" "
+ ;;
+ esac
+ done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+{
+ (set) 2>&1 |
+ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ sed -n \
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ ;;
+ *)
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+}
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=$`echo $ac_var`
+ echo "$ac_var='"'"'$ac_val'"'"'"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ sed "/^$/d" confdefs.h | sort
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ echo "$as_me: caught signal $ac_signal"
+ echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core core.* *.core &&
+ rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+ ' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
# Prefer explicitly selected file to automatically selected ones.
if test -z "$CONFIG_SITE"; then
if test "x$prefix" != xNONE; then
@@ -576,47 +1230,258 @@ if test -z "$CONFIG_SITE"; then
fi
for ac_site_file in $CONFIG_SITE; do
if test -r "$ac_site_file"; then
- echo "loading site script $ac_site_file"
+ { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
. "$ac_site_file"
fi
done
if test -r "$cache_file"; then
- echo "loading cache $cache_file"
- . $cache_file
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . $cache_file;;
+ *) . ./$cache_file;;
+ esac
+ fi
else
- echo "creating cache $cache_file"
- > $cache_file
+ { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+ eval ac_new_val="\$ac_env_${ac_var}_value"
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+echo "$as_me: former value: $ac_old_val" >&2;}
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+echo "$as_me: current value: $ac_new_val" >&2;}
+ ac_cache_corrupted=:
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+ ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+ { (exit 1); exit 1; }; }
fi
ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-ac_exeext=
-ac_objext=o
-if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
- # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
- if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
- ac_n= ac_c='
-' ac_t=' '
- else
- ac_n=-n ac_c= ac_t=
+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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_headers="$ac_config_headers auto-host.h:config.in"
+
+
+# Determine the host, build, and target systems
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f $ac_dir/shtool; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
fi
-else
- ac_n= ac_c='\c' ac_t=
+done
+if test -z "$ac_aux_dir"; then
+ { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+ { (exit 1); exit 1; }; }
fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+ { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+ { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+ ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+ { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+ { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+ ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6
+if test "${ac_cv_target+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_target_alias=$target_alias
+test "x$ac_cv_target_alias" = "x" &&
+ ac_cv_target_alias=$ac_cv_host_alias
+ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
+ { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
+ { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6
+target=$ac_cv_target
+target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+# Determine the noncanonical target name, for directory use.
+ case ${build_alias} in
+ "") build_noncanonical=${build} ;;
+ *) build_noncanonical=${build_alias} ;;
+esac
+
+ case ${host_alias} in
+ "") host_noncanonical=${build_noncanonical} ;;
+ *) host_noncanonical=${host_alias} ;;
+esac
+
+ case ${target_alias} in
+ "") target_noncanonical=${host_noncanonical} ;;
+ *) target_noncanonical=${target_alias} ;;
+esac
+
+
+# Determine the target- and build-specific subdirectories
+ # Prefix 'build-' so this never conflicts with target_subdir.
+build_subdir="build-${build_noncanonical}"
+# Not really a subdirectory, but here for completeness.
+host_subdir=.
+# No prefix.
+target_subdir=${target_noncanonical}
+
+
+# Set program_transform_name
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $. echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
-remove=rm
-hard_link=ln
-symbolic_link='ln -s'
-copy=cp
# Check for bogus environment variables.
# Test if LIBRARY_PATH contains the notation for the current directory
@@ -626,8 +1491,8 @@ copy=cp
# - one of the terminals (":" and ";") is the first or last sign
# - two terminals occur directly after each other
# - the path contains an element with a dot in it
-echo $ac_n "checking LIBRARY_PATH variable""... $ac_c" 1>&6
-echo "configure:631: checking LIBRARY_PATH variable" >&5
+echo "$as_me:$LINENO: checking LIBRARY_PATH variable" >&5
+echo $ECHO_N "checking LIBRARY_PATH variable... $ECHO_C" >&6
case ${LIBRARY_PATH} in
[:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
library_path_setting="contains current directory"
@@ -636,12 +1501,18 @@ case ${LIBRARY_PATH} in
library_path_setting="ok"
;;
esac
-echo "$ac_t""$library_path_setting" 1>&6
+echo "$as_me:$LINENO: result: $library_path_setting" >&5
+echo "${ECHO_T}$library_path_setting" >&6
if test "$library_path_setting" != "ok"; then
-{ echo "configure: error:
+{ { echo "$as_me:$LINENO: error:
+*** LIBRARY_PATH shouldn't contain the current directory when
+*** building gcc. Please change the environment variable
+*** and run configure again." >&5
+echo "$as_me: error:
*** LIBRARY_PATH shouldn't contain the current directory when
*** building gcc. Please change the environment variable
-*** and run configure again." 1>&2; exit 1; }
+*** and run configure again." >&2;}
+ { (exit 1); exit 1; }; }
fi
# Test if GCC_EXEC_PREFIX contains the notation for the current directory
@@ -651,8 +1522,8 @@ fi
# - one of the terminals (":" and ";") is the first or last sign
# - two terminals occur directly after each other
# - the path contains an element with a dot in it
-echo $ac_n "checking GCC_EXEC_PREFIX variable""... $ac_c" 1>&6
-echo "configure:656: checking GCC_EXEC_PREFIX variable" >&5
+echo "$as_me:$LINENO: checking GCC_EXEC_PREFIX variable" >&5
+echo $ECHO_N "checking GCC_EXEC_PREFIX variable... $ECHO_C" >&6
case ${GCC_EXEC_PREFIX} in
[:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
gcc_exec_prefix_setting="contains current directory"
@@ -661,476 +1532,860 @@ case ${GCC_EXEC_PREFIX} in
gcc_exec_prefix_setting="ok"
;;
esac
-echo "$ac_t""$gcc_exec_prefix_setting" 1>&6
+echo "$as_me:$LINENO: result: $gcc_exec_prefix_setting" >&5
+echo "${ECHO_T}$gcc_exec_prefix_setting" >&6
if test "$gcc_exec_prefix_setting" != "ok"; then
-{ echo "configure: error:
+{ { echo "$as_me:$LINENO: error:
*** GCC_EXEC_PREFIX shouldn't contain the current directory when
*** building gcc. Please change the environment variable
-*** and run configure again." 1>&2; exit 1; }
+*** and run configure again." >&5
+echo "$as_me: error:
+*** GCC_EXEC_PREFIX shouldn't contain the current directory when
+*** building gcc. Please change the environment variable
+*** and run configure again." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+# -----------
+# Directories
+# -----------
+
+# Specify the local prefix
+local_prefix=
+
+# Check whether --with-local-prefix or --without-local-prefix was given.
+if test "${with_local_prefix+set}" = set; then
+ withval="$with_local_prefix"
+ case "${withval}" in
+yes) { { echo "$as_me:$LINENO: error: bad value ${withval} given for local include directory prefix" >&5
+echo "$as_me: error: bad value ${withval} given for local include directory prefix" >&2;}
+ { (exit 1); exit 1; }; } ;;
+no) ;;
+*) local_prefix=$with_local_prefix ;;
+esac
+fi;
+
+# Default local prefix if it is empty
+if test x$local_prefix = x; then
+ local_prefix=/usr/local
+fi
+
+# Don't set gcc_gxx_include_dir to gxx_include_dir since that's only
+# passed in by the toplevel make and thus we'd get different behavior
+# depending on where we built the sources.
+gcc_gxx_include_dir=
+# Specify the g++ header file directory
+
+# Check whether --with-gxx-include-dir or --without-gxx-include-dir was given.
+if test "${with_gxx_include_dir+set}" = set; then
+ withval="$with_gxx_include_dir"
+ case "${withval}" in
+yes) { { echo "$as_me:$LINENO: error: bad value ${withval} given for g++ include directory" >&5
+echo "$as_me: error: bad value ${withval} given for g++ include directory" >&2;}
+ { (exit 1); exit 1; }; } ;;
+no) ;;
+*) gcc_gxx_include_dir=$with_gxx_include_dir ;;
+esac
+fi;
+
+if test x${gcc_gxx_include_dir} = x; then
+ if test x${enable_version_specific_runtime_libs} = xyes; then
+ gcc_gxx_include_dir='${libsubdir}/include/c++'
+ else
+ topsrcdir=${srcdir}/.. . ${srcdir}/../config.if
+ gcc_gxx_include_dir="\$(libsubdir)/\$(unlibsubdir)/..\`echo \$(exec_prefix) | sed -e 's|^\$(prefix)||' -e 's|/[^/]*|/..|g'\`/include/"${libstdcxx_incdir}
+ fi
+fi
+
+
+# Check whether --with-cpp_install_dir or --without-cpp_install_dir was given.
+if test "${with_cpp_install_dir+set}" = set; then
+ withval="$with_cpp_install_dir"
+ if test x$withval = xyes; then
+ { { echo "$as_me:$LINENO: error: option --with-cpp-install-dir requires an argument" >&5
+echo "$as_me: error: option --with-cpp-install-dir requires an argument" >&2;}
+ { (exit 1); exit 1; }; }
+elif test x$withval != xno; then
+ cpp_install_dir=$withval
+fi
+fi;
+
+# We would like to our source tree to be readonly. However when releases or
+# pre-releases are generated, the flex/bison generated files as well as the
+# various formats of manuals need to be included along with the rest of the
+# sources. Therefore we have --enable-generated-files-in-srcdir to do
+# just that.
+
+echo "$as_me:$LINENO: checking whether to place generated files in the source directory" >&5
+echo $ECHO_N "checking whether to place generated files in the source directory... $ECHO_C" >&6
+ # Check whether --enable-generated-files-in-srcdir or --disable-generated-files-in-srcdir was given.
+if test "${enable_generated_files_in_srcdir+set}" = set; then
+ enableval="$enable_generated_files_in_srcdir"
+ generated_files_in_srcdir=$enableval
+else
+ generated_files_in_srcdir=no
+fi;
+
+echo "$as_me:$LINENO: result: $generated_files_in_srcdir" >&5
+echo "${ECHO_T}$generated_files_in_srcdir" >&6
+
+if test "$generated_files_in_srcdir" = "yes"; then
+ GENINSRC=''
+else
+ GENINSRC='#'
fi
-# Check for additional parameters
+
+# -------------------
+# Find default linker
+# -------------------
# With GNU ld
+
# Check whether --with-gnu-ld or --without-gnu-ld was given.
if test "${with_gnu_ld+set}" = set; then
withval="$with_gnu_ld"
gnu_ld_flag="$with_gnu_ld"
else
gnu_ld_flag=no
-fi
-
+fi;
# With pre-defined ld
+
# Check whether --with-ld or --without-ld was given.
if test "${with_ld+set}" = set; then
withval="$with_ld"
DEFAULT_LINKER="$with_ld"
-fi
-
+fi;
if test x"${DEFAULT_LINKER+set}" = x"set"; then
if test ! -x "$DEFAULT_LINKER"; then
- echo "configure: warning: cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" 1>&2
+ { echo "$as_me:$LINENO: WARNING: cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" >&5
+echo "$as_me: WARNING: cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER" >&2;}
elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
gnu_ld_flag=yes
fi
- cat >> confdefs.h <<EOF
+
+cat >>confdefs.h <<_ACEOF
#define DEFAULT_LINKER "$DEFAULT_LINKER"
-EOF
+_ACEOF
+
+fi
+echo "$as_me:$LINENO: checking whether a default linker was specified" >&5
+echo $ECHO_N "checking whether a default linker was specified... $ECHO_C" >&6
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
+ if test x"$gnu_ld_flag" = x"no"; then
+ echo "$as_me:$LINENO: result: yes ($DEFAULT_LINKER)" >&5
+echo "${ECHO_T}yes ($DEFAULT_LINKER)" >&6
+ else
+ echo "$as_me:$LINENO: result: yes ($DEFAULT_LINKER - GNU ld)" >&5
+echo "${ECHO_T}yes ($DEFAULT_LINKER - GNU ld)" >&6
+ fi
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
+# ----------------------
+# Find default assembler
+# ----------------------
+
# With GNU as
+
# Check whether --with-gnu-as or --without-gnu-as was given.
if test "${with_gnu_as+set}" = set; then
withval="$with_gnu_as"
gas_flag="$with_gnu_as"
else
gas_flag=no
-fi
+fi;
# Check whether --with-as or --without-as was given.
if test "${with_as+set}" = set; then
withval="$with_as"
DEFAULT_ASSEMBLER="$with_as"
-fi
-
+fi;
if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
if test ! -x "$DEFAULT_ASSEMBLER"; then
- echo "configure: warning: cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER" 1>&2
+ { echo "$as_me:$LINENO: WARNING: cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER" >&5
+echo "$as_me: WARNING: cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER" >&2;}
elif $DEFAULT_ASSEMBLER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
gas_flag=yes
fi
- cat >> confdefs.h <<EOF
+
+cat >>confdefs.h <<_ACEOF
#define DEFAULT_ASSEMBLER "$DEFAULT_ASSEMBLER"
-EOF
+_ACEOF
fi
-# With stabs
-# Check whether --with-stabs or --without-stabs was given.
-if test "${with_stabs+set}" = set; then
- withval="$with_stabs"
- stabs="$with_stabs"
+echo "$as_me:$LINENO: checking whether a default assembler was specified" >&5
+echo $ECHO_N "checking whether a default assembler was specified... $ECHO_C" >&6
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
+ if test x"$gas_flag" = x"no"; then
+ echo "$as_me:$LINENO: result: yes ($DEFAULT_ASSEMBLER)" >&5
+echo "${ECHO_T}yes ($DEFAULT_ASSEMBLER)" >&6
+ else
+ echo "$as_me:$LINENO: result: yes ($DEFAULT_ASSEMBLER - GNU as)" >&5
+echo "${ECHO_T}yes ($DEFAULT_ASSEMBLER - GNU as)" >&6
+ fi
else
- stabs=no
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
+# ---------------
+# Find C compiler
+# ---------------
-# With ELF
-# Check whether --with-elf or --without-elf was given.
-if test "${with_elf+set}" = set; then
- withval="$with_elf"
- elf="$with_elf"
-else
- elf=no
-fi
+# If a non-executable a.out is present (e.g. created by GNU as above even if
+# invoked with -v only), the IRIX 6 native ld just overwrites the existing
+# file, even when creating an executable, so an execution test fails.
+# Remove possible default executable files to avoid this.
+#
+# FIXME: This really belongs into AC_PROG_CC and can be removed once
+# Autoconf includes it.
+rm -f a.out a.exe b.out
+# Find the native compiler
+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
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
-# Specify the local prefix
-local_prefix=
-# Check whether --with-local-prefix or --without-local-prefix was given.
-if test "${with_local_prefix+set}" = set; then
- withval="$with_local_prefix"
- case "${withval}" in
-yes) { echo "configure: error: bad value ${withval} given for local include directory prefix" 1>&2; exit 1; } ;;
-no) ;;
-*) local_prefix=$with_local_prefix ;;
-esac
fi
-
-
-# Default local prefix if it is empty
-if test x$local_prefix = x; then
- local_prefix=/usr/local
fi
-
-# Don't set gcc_gxx_include_dir to gxx_include_dir since that's only
-# passed in by the toplevel make and thus we'd get different behavior
-# depending on where we built the sources.
-gcc_gxx_include_dir=
-# Specify the g++ header file directory
-# Check whether --with-gxx-include-dir or --without-gxx-include-dir was given.
-if test "${with_gxx_include_dir+set}" = set; then
- withval="$with_gxx_include_dir"
- case "${withval}" in
-yes) { echo "configure: error: bad value ${withval} given for g++ include directory" 1>&2; exit 1; } ;;
-no) ;;
-*) gcc_gxx_include_dir=$with_gxx_include_dir ;;
-esac
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
-
-if test x${gcc_gxx_include_dir} = x; then
- if test x${enable_version_specific_runtime_libs} = xyes; then
- gcc_gxx_include_dir='${libsubdir}/include/c++'
- else
- topsrcdir=${srcdir}/.. . ${srcdir}/../config.if
- gcc_gxx_include_dir="\$(libsubdir)/\$(unlibsubdir)/..\`echo \$(exec_prefix) | sed -e 's|^\$(prefix)||' -e 's|/[^/]*|/..|g'\`/include/"${libstdcxx_incdir}
- fi
fi
-
-# Determine the host, build, and target systems
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
- if test -f $ac_dir/install-sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f $ac_dir/install.sh; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
fi
done
-if test -z "$ac_aux_dir"; then
- { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-
-# Do some error checking and defaulting for the host and target type.
-# The inputs are:
-# configure --host=HOST --target=TARGET --build=BUILD NONOPT
-#
-# The rules are:
-# 1. You are not allowed to specify --host, --target, and nonopt at the
-# same time.
-# 2. Host defaults to nonopt.
-# 3. If nonopt is not specified, then host defaults to the current host,
-# as determined by config.guess.
-# 4. Target and build default to nonopt.
-# 5. If nonopt is not specified, then target and build default to host.
-
-# The aliases save the names the user supplied, while $host etc.
-# will get canonicalized.
-case $host---$target---$nonopt in
-NONE---*---* | *---NONE---* | *---*---NONE) ;;
-*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
-esac
-
+done
-# Make sure we can run config.sub.
-if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
-else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi
-
-echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:843: checking host system type" >&5
-
-host_alias=$host
-case "$host_alias" in
-NONE)
- case $nonopt in
- NONE)
- if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
- else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
- fi ;;
- *) host_alias=$nonopt ;;
- esac ;;
-esac
-
-host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$host" 1>&6
-
-echo $ac_n "checking target system type""... $ac_c" 1>&6
-echo "configure:864: checking target system type" >&5
-
-target_alias=$target
-case "$target_alias" in
-NONE)
- case $nonopt in
- NONE) target_alias=$host_alias ;;
- *) target_alias=$nonopt ;;
- esac ;;
-esac
-
-target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
-target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$target" 1>&6
-
-echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:882: checking build system type" >&5
-
-build_alias=$build
-case "$build_alias" in
-NONE)
- case $nonopt in
- NONE) build_alias=$host_alias ;;
- *) build_alias=$nonopt ;;
- esac ;;
-esac
-
-build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
-build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-echo "$ac_t""$build" 1>&6
-
-test "$host_alias" != "$target_alias" &&
- test "$program_prefix$program_suffix$program_transform_name" = \
- NONENONEs,x,x, &&
- program_prefix=${target_alias}-
-
-
-# Set program_transform_name
-if test "$program_transform_name" = s,x,x,; then
- program_transform_name=
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
else
- # Double any \ or $. echo might interpret backslashes.
- cat <<\EOF_SED > conftestsed
-s,\\,\\\\,g; s,\$,$$,g
-EOF_SED
- program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
- rm -f conftestsed
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
-test "$program_prefix" != NONE &&
- program_transform_name="s,^,${program_prefix},; $program_transform_name"
-# Use a double $ so make ignores it.
-test "$program_suffix" != NONE &&
- program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
-
-# sed with no file args requires a program.
-test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
-# Find the native compiler
-# Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:930: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="gcc"
- break
- fi
- done
- IFS="$ac_save_ifs"
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
fi
fi
-CC="$ac_cv_prog_CC"
+CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ CC=$ac_ct_CC
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+fi
if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:960: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_prog_rejected=no
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
- ac_prog_rejected=yes
- continue
- fi
- ac_cv_prog_CC="cc"
- break
- fi
- done
- IFS="$ac_save_ifs"
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
if test $ac_prog_rejected = yes; then
# We found a bogon in the path, so make sure we never use it.
set dummy $ac_cv_prog_CC
shift
- if test $# -gt 0; then
+ if test $# != 0; then
# We chose a different compiler from the bogus one.
# However, it has the same basename, so the bogon will be chosen
# first if we set CC to just the basename; use the full file name.
shift
- set dummy "$ac_dir/$ac_word" "$@"
- shift
- ac_cv_prog_CC="$@"
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
fi
fi
fi
fi
-CC="$ac_cv_prog_CC"
+CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
- if test -z "$CC"; then
- case "`uname -s`" in
- *win32* | *WIN32*)
- # Extract the first word of "cl", so it can be a program name with args.
-set dummy cl; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1011: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_CC="cl"
- break
- fi
- done
- IFS="$ac_save_ifs"
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
fi
fi
-CC="$ac_cv_prog_CC"
+CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$ac_t""$CC" 1>&6
+ echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
else
- echo "$ac_t""no" 1>&6
-fi
- ;;
- esac
- fi
- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1043: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-cat > conftest.$ac_ext << EOF
+ test -n "$ac_ct_CC" && break
+done
-#line 1054 "configure"
-#include "confdefs.h"
+ CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+ "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+ (eval $ac_compiler --version </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+ (eval $ac_compiler -v </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+ (eval $ac_compiler -V </dev/null >&5) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
-main(){return(0);}
-EOF
-if { (eval echo configure:1059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- ac_cv_prog_cc_works=yes
- # If we can't run a trivial program, we are probably using a cross compiler.
- if (./conftest; exit) 2>/dev/null; then
- ac_cv_prog_cc_cross=no
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output" >&5
+echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+ (eval $ac_link_default) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # Find the output, starting from the most likely. This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+ ;;
+ conftest.$ac_ext )
+ # This is the source file.
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
+ * )
+ break;;
+ esac
+done
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+ { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { (eval 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
+ cross_compiling=no
else
- ac_cv_prog_cc_cross=yes
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
fi
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- ac_cv_prog_cc_works=no
fi
-rm -fr conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
-if test $ac_cv_prog_cc_works = no; then
- { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
-fi
-echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1085: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
-echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
-cross_compiling=$ac_cv_prog_cc_cross
-
-echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:1090: checking whether we are using GNU C" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.c <<EOF
-#ifdef __GNUC__
- yes;
-#endif
-EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1099: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
- ac_cv_prog_gcc=yes
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ export ac_cv_exeext
+ break;;
+ * ) break;;
+ esac
+done
else
- ac_cv_prog_gcc=no
-fi
-fi
-
-echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+ { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
-if test $ac_cv_prog_gcc = yes; then
- GCC=yes
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
else
- GCC=
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
fi
-ac_test_CFLAGS="${CFLAGS+set}"
-ac_save_CFLAGS="$CFLAGS"
-CFLAGS=
-echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:1118: checking whether ${CC-cc} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- echo 'void f(){}' > conftest.c
-if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ ac_compiler_gnu=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_prog_cc_g=yes
else
- ac_cv_prog_cc_g=no
-fi
-rm -f conftest*
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ac_cv_prog_cc_g=no
fi
-
-echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
if test "$ac_test_CFLAGS" = set; then
- CFLAGS="$ac_save_CFLAGS"
+ CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
CFLAGS="-g -O2"
@@ -1144,34 +2399,287 @@ else
CFLAGS=
fi
fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX 10.20 and later -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
-if test "x$CC" != xcc; then
- echo $ac_n "checking whether $CC and cc understand -c and -o together""... $ac_c" 1>&6
-echo "configure:1151: checking whether $CC and cc understand -c and -o together" >&5
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno)
+ echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+ *)
+ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+ CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C. Since we use `exit',
+# in C++ we need to declare it. In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+ choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ for ac_declaration in \
+ ''\
+ '#include <stdlib.h>' \
+ 'extern "C" void std::exit (int) throw (); using std::exit;' \
+ 'extern "C" void std::exit (int); using std::exit;' \
+ 'extern "C" void exit (int) throw ();' \
+ 'extern "C" void exit (int);' \
+ 'void exit (int);'
+do
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ break
else
- echo $ac_n "checking whether cc understands -c and -o together""... $ac_c" 1>&6
-echo "configure:1154: checking whether cc understands -c and -o together" >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+ echo '#ifdef __cplusplus' >>confdefs.h
+ echo $ac_declaration >>confdefs.h
+ echo '#endif' >>confdefs.h
fi
-set dummy $CC; ac_cc="`echo $2 |
- sed -e 's/[^a-zA-Z0-9_]/_/g' -e 's/^[0-9]/_/'`"
-if eval "test \"`echo '$''{'ac_cv_prog_cc_${ac_cc}_c_o'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+
else
- echo 'foo(){}' > conftest.c
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f 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
+
+if test "x$CC" != xcc; then
+ echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5
+echo $ECHO_N "checking whether $CC and cc understand -c and -o together... $ECHO_C" >&6
+else
+ echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5
+echo $ECHO_N "checking whether cc understands -c and -o together... $ECHO_C" >&6
+fi
+set dummy $CC; ac_cc=`echo $2 |
+ sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if eval "test \"\${ac_cv_prog_cc_${ac_cc}_c_o+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
# Make sure it works both with $CC and with simple cc.
# We do the test twice because some compilers refuse to overwrite an
# existing .o file with -o, though they will create one.
-ac_try='${CC-cc} -c conftest.c -o conftest.o 1>&5'
-if { (eval echo configure:1166: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
- test -f conftest.o && { (eval echo configure:1167: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+ac_try='$CC -c conftest.$ac_ext -o conftest.$ac_objext >&5'
+if { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ test -f 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
eval ac_cv_prog_cc_${ac_cc}_c_o=yes
if test "x$CC" != xcc; then
# Test first that cc exists at all.
- if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:1172: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
- ac_try='cc -c conftest.c -o conftest.o 1>&5'
- if { (eval echo configure:1174: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
- test -f conftest.o && { (eval echo configure:1175: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
+ if { ac_try='cc -c conftest.$ac_ext >&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
+ ac_try='cc -c conftest.$ac_ext -o conftest.$ac_objext >&5'
+ if { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ test -f 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
# cc works too.
:
@@ -1188,12 +2696,15 @@ rm -f conftest*
fi
if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = yes"; then
- echo "$ac_t""yes" 1>&6
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
else
- echo "$ac_t""no" 1>&6
- cat >> confdefs.h <<\EOF
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+cat >>confdefs.h <<\_ACEOF
#define NO_MINUS_C_MINUS_O 1
-EOF
+_ACEOF
fi
@@ -1206,730 +2717,1020 @@ fi
-# See if GNAT has been installed
-if test $host != $build; then
- ac_tool_prefix=${host_alias}-
-else
- ac_tool_prefix=
-fi
+# -------------------------
+# Check C compiler features
+# -------------------------
-# Extract the first word of "${ac_tool_prefix}gnatbind", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gnatbind; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1221: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_GNATBIND'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$GNATBIND"; then
- ac_cv_prog_GNATBIND="$GNATBIND" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_GNATBIND="${ac_tool_prefix}gnatbind"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-GNATBIND="$ac_cv_prog_GNATBIND"
-if test -n "$GNATBIND"; then
- echo "$ac_t""$GNATBIND" 1>&6
+echo "$as_me:$LINENO: checking whether ${CC-cc} accepts -Wno-long-long" >&5
+echo $ECHO_N "checking whether ${CC-cc} accepts -Wno-long-long... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_no_long_long+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- echo "$ac_t""no" 1>&6
-fi
-
+ save_CFLAGS="$CFLAGS"
+CFLAGS="-Wno-long-long"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
-if test -z "$ac_cv_prog_GNATBIND"; then
-if test -n "$ac_tool_prefix"; then
- # Extract the first word of "gnatbind", so it can be a program name with args.
-set dummy gnatbind; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1253: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_GNATBIND'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$GNATBIND"; then
- ac_cv_prog_GNATBIND="$GNATBIND" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_GNATBIND="gnatbind"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_GNATBIND" && ac_cv_prog_GNATBIND="no"
-fi
-fi
-GNATBIND="$ac_cv_prog_GNATBIND"
-if test -n "$GNATBIND"; then
- echo "$ac_t""$GNATBIND" 1>&6
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ ac_cv_prog_cc_no_long_long=yes
else
- echo "$ac_t""no" 1>&6
-fi
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-else
- GNATBIND="no"
+ac_cv_prog_cc_no_long_long=no
fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+CFLAGS="$save_CFLAGS"
fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_no_long_long" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_no_long_long" >&6
-echo $ac_n "checking for compiler driver that understands Ada""... $ac_c" 1>&6
-echo "configure:1286: checking for compiler driver that understands Ada" >&5
-if eval "test \"`echo '$''{'gcc_cv_prog_adac'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+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
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat >conftest.adb <<EOF
-procedure conftest is begin null; end conftest;
-EOF
-gcc_cv_prog_adac=no
-# Have to do ac_tool_prefix and user overrides by hand.
-for cand in ${ADAC+"$ADAC"} ${CC+"$CC"} \
- ${ac_tool_prefix}gcc gcc \
- ${ac_tool_prefix}cc cc \
- ${ac_tool_prefix}gnatgcc gnatgcc \
- ${ac_tool_prefix}gnatcc gnatcc \
- ${ac_tool_prefix}adagcc adagcc \
- ${ac_tool_prefix}adacc adacc ; do
- # There is a bug in all released versions of GCC which causes the
- # driver to exit successfully when the appropriate language module
- # has not been installed. This is fixed in 2.95.4, 3.0.2, and 3.1.
- # Therefore we must check for the error message as well as an
- # unsuccessful exit.
- errors=`($cand -c conftest.adb) 2>&1 || echo failure`
- if test x"$errors" = x; then
- gcc_cv_prog_adac=$cand
- break
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
fi
-done
-rm -f conftest.*
-fi
-
-echo "$ac_t""$gcc_cv_prog_adac" 1>&6
-ADAC=$gcc_cv_prog_adac
-
-
-if test x$GNATBIND != xno && test x$ADAC != xno; then
- have_gnat=yes
else
- have_gnat=no
+ ac_cpp_err=yes
fi
-
-
-echo $ac_n "checking whether ${CC-cc} accepts -Wno-long-long""... $ac_c" 1>&6
-echo "configure:1328: checking whether ${CC-cc} accepts -Wno-long-long" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_cc_no_long_long'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+if test -z "$ac_cpp_err"; then
+ :
else
- save_CFLAGS="$CFLAGS"
-CFLAGS="-Wno-long-long"
-cat > conftest.$ac_ext <<EOF
-#line 1335 "configure"
-#include "confdefs.h"
-
-int main() {
-
-; return 0; }
-EOF
-if { (eval echo configure:1342: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_prog_cc_no_long_long=yes
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_prog_cc_no_long_long=no
-fi
-rm -f conftest*
-CFLAGS="$save_CFLAGS"
+ ac_cpp_err=yes
fi
-
-echo "$ac_t""$ac_cv_prog_cc_no_long_long" 1>&6
-
-if test x$have_gnat != xno ; then
-echo $ac_n "checking whether ${ADAC} accepts -Wno-long-long""... $ac_c" 1>&6
-echo "configure:1359: checking whether ${ADAC} accepts -Wno-long-long" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_adac_no_long_long'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
else
- cat >conftest.adb <<EOF
-procedure conftest is begin null; end conftest;
-EOF
-if $ADAC -Wno-long-long -c conftest.adb 1>&5 2>&5 ; then
- ac_cv_prog_adac_no_long_long=yes
-else
- ac_cv_prog_adac_no_long_long=no
-fi
-rm -f conftest*
-fi
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-echo "$ac_t""$ac_cv_prog_adac_no_long_long" 1>&6
-else
- ac_cv_prog_adac_no_long_long=yes
+ # Passes both tests.
+ac_preproc_ok=:
+break
fi
+rm -f conftest.err conftest.$ac_ext
-strict1_warn=
-if test $ac_cv_prog_cc_no_long_long = yes && \
- test $ac_cv_prog_adac_no_long_long = yes ; then
- strict1_warn="-pedantic -Wno-long-long"
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
fi
+ done
+ ac_cv_prog_CPP=$CPP
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1387: checking how to run the C preprocessor" >&5
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
fi
-if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+ CPP=$ac_cv_prog_CPP
else
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and "${CC-cc}" will confuse make.
- CPP="${CC-cc} -E"
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
# On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp.
- cat > conftest.$ac_ext <<EOF
-#line 1402 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1408: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.$ac_ext <<EOF
-#line 1419 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1425: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
:
else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -nologo -E"
- cat > conftest.$ac_ext <<EOF
-#line 1436 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1442: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- :
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP=/lib/cpp
-fi
-rm -f conftest*
+ ac_cpp_err=yes
fi
-rm -f conftest*
-fi
-rm -f conftest*
- ac_cv_prog_CPP="$CPP"
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
fi
- CPP="$ac_cv_prog_CPP"
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
else
- ac_cv_prog_CPP="$CPP"
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
fi
-echo "$ac_t""$CPP" 1>&6
-echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:1467: checking for inline" >&5
-if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+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
+
+echo "$as_me:$LINENO: checking for inline" >&5
+echo $ECHO_N "checking for inline... $ECHO_C" >&6
+if test "${ac_cv_c_inline+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
- cat > conftest.$ac_ext <<EOF
-#line 1474 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
-int main() {
-} $ac_kw foo() {
-; return 0; }
-EOF
-if { (eval echo configure:1481: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_c_inline=$ac_kw; break
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
done
fi
-
-echo "$ac_t""$ac_cv_c_inline" 1>&6
-case "$ac_cv_c_inline" in
+echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
+echo "${ECHO_T}$ac_cv_c_inline" >&6
+case $ac_cv_c_inline in
inline | yes) ;;
- no) cat >> confdefs.h <<\EOF
-#define inline
-EOF
+ no)
+cat >>confdefs.h <<\_ACEOF
+#define inline
+_ACEOF
;;
- *) cat >> confdefs.h <<EOF
+ *) cat >>confdefs.h <<_ACEOF
#define inline $ac_cv_c_inline
-EOF
+_ACEOF
;;
esac
-echo $ac_n "checking for volatile""... $ac_c" 1>&6
-echo "configure:1507: checking for volatile" >&5
-if eval "test \"`echo '$''{'gcc_cv_c_volatile'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1512 "configure"
-#include "confdefs.h"
-
-int main() {
-volatile int foo;
-; return 0; }
-EOF
-if { (eval echo configure:1519: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- gcc_cv_c_volatile=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- gcc_cv_c_volatile=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$gcc_cv_c_volatile" 1>&6
-if test $gcc_cv_c_volatile = yes ; then
- cat >> confdefs.h <<\EOF
-#define HAVE_VOLATILE 1
-EOF
-
-fi
-
-
-echo $ac_n "checking for long double""... $ac_c" 1>&6
-echo "configure:1541: checking for long double" >&5
-if eval "test \"`echo '$''{'gcc_cv_c_long_double'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$GCC" = yes; then
- gcc_cv_c_long_double=yes
-else
-cat > conftest.$ac_ext <<EOF
-#line 1549 "configure"
-#include "confdefs.h"
-
-int main() {
-/* The Stardent Vistra knows sizeof(long double), but does not support it. */
-long double foo = 0.0;
-/* On Ultrix 4.3 cc, long double is 4 and double is 8. */
-switch (0) case 0: case (sizeof(long double) >= sizeof(double)):;
-; return 0; }
-EOF
-if { (eval echo configure:1559: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- gcc_cv_c_long_double=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- gcc_cv_c_long_double=no
-fi
-rm -f conftest*
-fi
-fi
-
-echo "$ac_t""$gcc_cv_c_long_double" 1>&6
-if test $gcc_cv_c_long_double = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_LONG_DOUBLE 1
-EOF
-
-fi
-echo $ac_n "checking for long long int""... $ac_c" 1>&6
-echo "configure:1581: checking for long long int" >&5
-if eval "test \"`echo '$''{'ac_cv_c_long_long'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking for long long int" >&5
+echo $ECHO_N "checking for long long int... $ECHO_C" >&6
+if test "${ac_cv_c_long_long+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftest.$ac_ext <<EOF
-#line 1586 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-int main() {
+int
+main ()
+{
long long int i;
-; return 0; }
-EOF
-if { (eval echo configure:1593: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_c_long_long=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_c_long_long=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_long_long=no
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-
-echo "$ac_t""$ac_cv_c_long_long" 1>&6
+echo "$as_me:$LINENO: result: $ac_cv_c_long_long" >&5
+echo "${ECHO_T}$ac_cv_c_long_long" >&6
if test $ac_cv_c_long_long = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_LONG_LONG 1
-EOF
+_ACEOF
fi
-echo $ac_n "checking for __int64""... $ac_c" 1>&6
-echo "configure:1613: checking for __int64" >&5
-if eval "test \"`echo '$''{'ac_cv_c___int64'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 1618 "configure"
-#include "confdefs.h"
-
-int main() {
+echo "$as_me:$LINENO: checking for __int64" >&5
+echo $ECHO_N "checking for __int64... $ECHO_C" >&6
+if test "${ac_cv_c___int64+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
__int64 i;
-; return 0; }
-EOF
-if { (eval echo configure:1625: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_c___int64=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_c___int64=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c___int64=no
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-
-echo "$ac_t""$ac_cv_c___int64" 1>&6
+echo "$as_me:$LINENO: result: $ac_cv_c___int64" >&5
+echo "${ECHO_T}$ac_cv_c___int64" >&6
if test $ac_cv_c___int64 = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE___INT64 1
-EOF
+_ACEOF
fi
-echo $ac_n "checking for built-in _Bool""... $ac_c" 1>&6
-echo "configure:1646: checking for built-in _Bool" >&5
-if eval "test \"`echo '$''{'gcc_cv_c__bool'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking for built-in _Bool" >&5
+echo $ECHO_N "checking for built-in _Bool... $ECHO_C" >&6
+if test "${gcc_cv_c__bool+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftest.$ac_ext <<EOF
-#line 1651 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-int main() {
+int
+main ()
+{
_Bool foo;
-; return 0; }
-EOF
-if { (eval echo configure:1658: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
gcc_cv_c__bool=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- gcc_cv_c__bool=no
-fi
-rm -f conftest*
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+gcc_cv_c__bool=no
fi
+rm -f conftest.$ac_objext conftest.$ac_ext
-echo "$ac_t""$gcc_cv_c__bool" 1>&6
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_c__bool" >&5
+echo "${ECHO_T}$gcc_cv_c__bool" >&6
if test $gcc_cv_c__bool = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE__BOOL 1
-EOF
+_ACEOF
fi
# sizeof(char) is 1 by definition.
-echo $ac_n "checking size of short""... $ac_c" 1>&6
-echo "configure:1682: checking size of short" >&5
-if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence.
- cat > conftest.$ac_ext <<EOF
-#line 1688 "configure"
+echo "$as_me:$LINENO: checking size of void *" >&5
+echo $ECHO_N "checking size of void *... $ECHO_C" >&6
+if test "${ac_cv_sizeof_void_p+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include "confdefs.h"
+#include <sys/types.h>
+
+
+int
+main ()
+{
+switch (0) case 0: case (sizeof (void *) == $ac_size):;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ ac_cv_sizeof_void_p=$ac_size
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ if test x$ac_cv_sizeof_void_p != x ; then break; fi
+done
+
+fi
+
+if test x$ac_cv_sizeof_void_p = x ; then
+ { { echo "$as_me:$LINENO: error: cannot determine a size for void *" >&5
+echo "$as_me: error: cannot determine a size for void *" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_void_p" >&5
+echo "${ECHO_T}$ac_cv_sizeof_void_p" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking size of short" >&5
+echo $ECHO_N "checking size of short... $ECHO_C" >&6
+if test "${ac_cv_sizeof_short+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include "confdefs.h"
#include <sys/types.h>
-int main() {
+int
+main ()
+{
switch (0) case 0: case (sizeof (short) == $ac_size):;
-; return 0; }
-EOF
-if { (eval echo configure:1698: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_sizeof_short=$ac_size
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
if test x$ac_cv_sizeof_short != x ; then break; fi
done
fi
if test x$ac_cv_sizeof_short = x ; then
- { echo "configure: error: cannot determine a size for short" 1>&2; exit 1; }
+ { { echo "$as_me:$LINENO: error: cannot determine a size for short" >&5
+echo "$as_me: error: cannot determine a size for short" >&2;}
+ { (exit 1); exit 1; }; }
fi
-echo "$ac_t""$ac_cv_sizeof_short" 1>&6
-cat >> confdefs.h <<EOF
-#define SIZEOF_SHORT $ac_cv_sizeof_short
-EOF
-
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_short" >&5
+echo "${ECHO_T}$ac_cv_sizeof_short" >&6
-echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:1721: checking size of int" >&5
-if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence.
- cat > conftest.$ac_ext <<EOF
-#line 1727 "configure"
-#include "confdefs.h"
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking size of int" >&5
+echo $ECHO_N "checking size of int... $ECHO_C" >&6
+if test "${ac_cv_sizeof_int+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include "confdefs.h"
#include <sys/types.h>
-int main() {
+int
+main ()
+{
switch (0) case 0: case (sizeof (int) == $ac_size):;
-; return 0; }
-EOF
-if { (eval echo configure:1737: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_sizeof_int=$ac_size
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
if test x$ac_cv_sizeof_int != x ; then break; fi
done
fi
if test x$ac_cv_sizeof_int = x ; then
- { echo "configure: error: cannot determine a size for int" 1>&2; exit 1; }
+ { { echo "$as_me:$LINENO: error: cannot determine a size for int" >&5
+echo "$as_me: error: cannot determine a size for int" >&2;}
+ { (exit 1); exit 1; }; }
fi
-echo "$ac_t""$ac_cv_sizeof_int" 1>&6
-cat >> confdefs.h <<EOF
-#define SIZEOF_INT $ac_cv_sizeof_int
-EOF
-
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_int" >&5
+echo "${ECHO_T}$ac_cv_sizeof_int" >&6
-echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:1760: checking size of long" >&5
-if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence.
- cat > conftest.$ac_ext <<EOF
-#line 1766 "configure"
-#include "confdefs.h"
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking size of long" >&5
+echo $ECHO_N "checking size of long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include "confdefs.h"
#include <sys/types.h>
-int main() {
+int
+main ()
+{
switch (0) case 0: case (sizeof (long) == $ac_size):;
-; return 0; }
-EOF
-if { (eval echo configure:1776: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_sizeof_long=$ac_size
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
if test x$ac_cv_sizeof_long != x ; then break; fi
done
fi
if test x$ac_cv_sizeof_long = x ; then
- { echo "configure: error: cannot determine a size for long" 1>&2; exit 1; }
+ { { echo "$as_me:$LINENO: error: cannot determine a size for long" >&5
+echo "$as_me: error: cannot determine a size for long" >&2;}
+ { (exit 1); exit 1; }; }
fi
-echo "$ac_t""$ac_cv_sizeof_long" 1>&6
-cat >> confdefs.h <<EOF
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long" >&6
+
+cat >>confdefs.h <<_ACEOF
#define SIZEOF_LONG $ac_cv_sizeof_long
-EOF
+_ACEOF
if test $ac_cv_c_long_long = yes; then
- echo $ac_n "checking size of long long""... $ac_c" 1>&6
-echo "configure:1800: checking size of long long" >&5
-if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence.
- cat > conftest.$ac_ext <<EOF
-#line 1806 "configure"
-#include "confdefs.h"
+ echo "$as_me:$LINENO: checking size of long long" >&5
+echo $ECHO_N "checking size of long long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long_long+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include "confdefs.h"
#include <sys/types.h>
-int main() {
+int
+main ()
+{
switch (0) case 0: case (sizeof (long long) == $ac_size):;
-; return 0; }
-EOF
-if { (eval echo configure:1816: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_sizeof_long_long=$ac_size
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
if test x$ac_cv_sizeof_long_long != x ; then break; fi
done
fi
if test x$ac_cv_sizeof_long_long = x ; then
- { echo "configure: error: cannot determine a size for long long" 1>&2; exit 1; }
+ { { echo "$as_me:$LINENO: error: cannot determine a size for long long" >&5
+echo "$as_me: error: cannot determine a size for long long" >&2;}
+ { (exit 1); exit 1; }; }
fi
-echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6
-cat >> confdefs.h <<EOF
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long_long" >&6
+
+cat >>confdefs.h <<_ACEOF
#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
-EOF
+_ACEOF
fi
if test $ac_cv_c___int64 = yes; then
- echo $ac_n "checking size of __int64""... $ac_c" 1>&6
-echo "configure:1841: checking size of __int64" >&5
-if eval "test \"`echo '$''{'ac_cv_sizeof___int64'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence.
- cat > conftest.$ac_ext <<EOF
-#line 1847 "configure"
-#include "confdefs.h"
+ echo "$as_me:$LINENO: checking size of __int64" >&5
+echo $ECHO_N "checking size of __int64... $ECHO_C" >&6
+if test "${ac_cv_sizeof___int64+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include "confdefs.h"
#include <sys/types.h>
-int main() {
+int
+main ()
+{
switch (0) case 0: case (sizeof (__int64) == $ac_size):;
-; return 0; }
-EOF
-if { (eval echo configure:1857: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_sizeof___int64=$ac_size
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
if test x$ac_cv_sizeof___int64 != x ; then break; fi
done
fi
if test x$ac_cv_sizeof___int64 = x ; then
- { echo "configure: error: cannot determine a size for __int64" 1>&2; exit 1; }
+ { { echo "$as_me:$LINENO: error: cannot determine a size for __int64" >&5
+echo "$as_me: error: cannot determine a size for __int64" >&2;}
+ { (exit 1); exit 1; }; }
fi
-echo "$ac_t""$ac_cv_sizeof___int64" 1>&6
-cat >> confdefs.h <<EOF
+echo "$as_me:$LINENO: result: $ac_cv_sizeof___int64" >&5
+echo "${ECHO_T}$ac_cv_sizeof___int64" >&6
+
+cat >>confdefs.h <<_ACEOF
#define SIZEOF___INT64 $ac_cv_sizeof___int64
-EOF
+_ACEOF
+
+
+fi
+
+# -----------------
+# Find Ada compiler
+# -----------------
+# See if GNAT has been installed
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gnatbind", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gnatbind; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_GNATBIND+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$GNATBIND"; then
+ ac_cv_prog_GNATBIND="$GNATBIND" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_GNATBIND="${ac_tool_prefix}gnatbind"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
fi
+fi
+GNATBIND=$ac_cv_prog_GNATBIND
+if test -n "$GNATBIND"; then
+ echo "$as_me:$LINENO: result: $GNATBIND" >&5
+echo "${ECHO_T}$GNATBIND" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
-echo $ac_n "checking execution character set""... $ac_c" 1>&6
-echo "configure:1882: checking execution character set" >&5
-if eval "test \"`echo '$''{'ac_cv_c_charset'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+fi
+if test -z "$ac_cv_prog_GNATBIND"; then
+ ac_ct_GNATBIND=$GNATBIND
+ # Extract the first word of "gnatbind", so it can be a program name with args.
+set dummy gnatbind; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_GNATBIND+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftest.$ac_ext <<EOF
-#line 1887 "configure"
-#include "confdefs.h"
-#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \
- && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21
-ASCII
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "ASCII" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_c_charset=ASCII
+ if test -n "$ac_ct_GNATBIND"; then
+ ac_cv_prog_ac_ct_GNATBIND="$ac_ct_GNATBIND" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_GNATBIND="gnatbind"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_GNATBIND" && ac_cv_prog_ac_ct_GNATBIND="no"
+fi
+fi
+ac_ct_GNATBIND=$ac_cv_prog_ac_ct_GNATBIND
+if test -n "$ac_ct_GNATBIND"; then
+ echo "$as_me:$LINENO: result: $ac_ct_GNATBIND" >&5
+echo "${ECHO_T}$ac_ct_GNATBIND" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
-rm -f conftest*
- if test x${ac_cv_c_charset+set} != xset; then
- cat > conftest.$ac_ext <<EOF
-#line 1903 "configure"
-#include "confdefs.h"
-#if '\n' == 0x15 && ' ' == 0x40 && '0' == 0xF0 \
- && 'A' == 0xC1 && 'a' == 0x81 && '!' == 0x5A
-EBCDIC
-#endif
+ GNATBIND=$ac_ct_GNATBIND
+else
+ GNATBIND="$ac_cv_prog_GNATBIND"
+fi
+
+echo "$as_me:$LINENO: checking whether compiler driver understands Ada" >&5
+echo $ECHO_N "checking whether compiler driver understands Ada... $ECHO_C" >&6
+if test "${gcc_cv_cc_supports_ada+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.adb <<EOF
+procedure conftest is begin null; end conftest;
EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "EBCDIC" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_c_charset=EBCDIC
+gcc_cv_cc_supports_ada=no
+# There is a bug in old released versions of GCC which causes the
+# driver to exit successfully when the appropriate language module
+# has not been installed. This is fixed in 2.95.4, 3.0.2, and 3.1.
+# Therefore we must check for the error message as well as an
+# unsuccessful exit.
+# Other compilers, like HP Tru64 UNIX cc, exit successfully when
+# given a .adb file, but produce no object file. So we must check
+# if an object file was really produced to guard against this.
+errors=`(${CC} -c conftest.adb) 2>&1 || echo failure`
+if test x"$errors" = x && test -f conftest.$ac_objext; then
+ gcc_cv_cc_supports_ada=yes
+ break
fi
-rm -f conftest*
+rm -f conftest.*
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_cc_supports_ada" >&5
+echo "${ECHO_T}$gcc_cv_cc_supports_ada" >&6
- fi
- if test x${ac_cv_c_charset+set} != xset; then
- ac_cv_c_charset=unknown
- fi
+if test x$GNATBIND != xno && test x$gcc_cv_cc_supports_ada != xno; then
+ have_gnat=yes
+else
+ have_gnat=no
fi
-echo "$ac_t""$ac_cv_c_charset" 1>&6
-if test $ac_cv_c_charset = unknown; then
- { echo "configure: error: *** Cannot determine host character set." 1>&2; exit 1; }
-elif test $ac_cv_c_charset = EBCDIC; then
- cat >> confdefs.h <<\EOF
-#define HOST_EBCDIC 1
-EOF
+# ---------------------
+# Warnings and checking
+# ---------------------
+
+strict1_warn=
+if test $ac_cv_prog_cc_no_long_long = yes ; then
+ strict1_warn="-pedantic -Wno-long-long"
fi
-# If the native compiler is GCC, we can enable warnings even in stage1.
+
+# If the native compiler is GCC, we can enable warnings even in stage1.
# That's useful for people building cross-compilers, or just running a
# quick `make'.
warn_cflags=
@@ -1938,17 +3739,20 @@ if test "x$GCC" = "xyes"; then
fi
-# Determine whether or not multilibs are enabled.
-# Check whether --enable-multilib or --disable-multilib was given.
-if test "${enable_multilib+set}" = set; then
- enableval="$enable_multilib"
- :
+# Enable -Werror in bootstrap stage2 and later.
+# Change the default to "no" on release branches.
+# Check whether --enable-werror or --disable-werror was given.
+if test "${enable_werror+set}" = set; then
+ enableval="$enable_werror"
+
else
- enable_multilib=yes
+ enable_werror=no
+fi;
+if test x$enable_werror = xyes ; then
+ WERROR=-Werror
fi
-
# Enable expensive internal checks
# Check whether --enable-checking or --disable-checking was given.
if test "${enable_checking+set}" = set; then
@@ -1959,6 +3763,7 @@ ac_rtl_checking=
ac_rtlflag_checking=
ac_gc_checking=
ac_gc_always_collect=
+ac_fold_checking=
case "${enableval}" in
yes) ac_checking=1 ; ac_tree_checking=1 ; ac_gc_checking=1 ;
ac_rtlflag_checking=1 ;;
@@ -1975,135 +3780,632 @@ no) ;;
rtl) ac_rtl_checking=1 ;;
gc) ac_gc_checking=1 ;;
gcac) ac_gc_always_collect=1 ;;
+ fold) ac_fold_checking=1 ;;
valgrind) ac_checking_valgrind=1 ;;
- *) { echo "configure: error: unknown check category $check" 1>&2; exit 1; } ;;
+ *) { { echo "$as_me:$LINENO: error: unknown check category $check" >&5
+echo "$as_me: error: unknown check category $check" >&2;}
+ { (exit 1); exit 1; }; } ;;
esac
done
;;
esac
-fi
-
+else
+ # By default, disable all checks for release versions of GCC.
+ac_checking=; ac_tree_checking=; ac_gc_checking=; ac_rtlflag_checking=;
+fi;
nocommon_flag=""
if test x$ac_checking != x ; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define ENABLE_CHECKING 1
-EOF
+_ACEOF
nocommon_flag=-fno-common
fi
if test x$ac_tree_checking != x ; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define ENABLE_TREE_CHECKING 1
-EOF
+_ACEOF
fi
if test x$ac_rtl_checking != x ; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define ENABLE_RTL_CHECKING 1
-EOF
+_ACEOF
fi
if test x$ac_rtlflag_checking != x ; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define ENABLE_RTL_FLAG_CHECKING 1
-EOF
+_ACEOF
fi
if test x$ac_gc_checking != x ; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define ENABLE_GC_CHECKING 1
-EOF
+_ACEOF
fi
if test x$ac_gc_always_collect != x ; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define ENABLE_GC_ALWAYS_COLLECT 1
-EOF
+_ACEOF
+
+fi
+if test x$ac_fold_checking != x ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ENABLE_FOLD_CHECKING 1
+_ACEOF
fi
valgrind_path_defines=
valgrind_command=
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./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
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+if test "${ac_cv_header_valgrind_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for valgrind.h" >&5
+echo $ECHO_N "checking for valgrind.h... $ECHO_C" >&6
+if test "${ac_cv_header_valgrind_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_valgrind_h" >&5
+echo "${ECHO_T}$ac_cv_header_valgrind_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking valgrind.h usability" >&5
+echo $ECHO_N "checking valgrind.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <valgrind.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking valgrind.h presence" >&5
+echo $ECHO_N "checking valgrind.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <valgrind.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+ yes:no )
+ { echo "$as_me:$LINENO: WARNING: valgrind.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: valgrind.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: valgrind.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: valgrind.h: proceeding with the preprocessor's result" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+ no:yes )
+ { echo "$as_me:$LINENO: WARNING: valgrind.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: valgrind.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: valgrind.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: valgrind.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: valgrind.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: valgrind.h: proceeding with the preprocessor's result" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for valgrind.h" >&5
+echo $ECHO_N "checking for valgrind.h... $ECHO_C" >&6
+if test "${ac_cv_header_valgrind_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_valgrind_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_valgrind_h" >&5
+echo "${ECHO_T}$ac_cv_header_valgrind_h" >&6
+
+fi
+if test $ac_cv_header_valgrind_h = yes; then
+ have_valgrind_h=yes
+else
+ have_valgrind_h=no
+fi
+
+
+
if test x$ac_checking_valgrind != x ; then
# It is certainly possible that there's valgrind but no valgrind.h.
# GCC relies on making annotations so we must have both.
- ac_safe=`echo "valgrind.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for valgrind.h""... $ac_c" 1>&6
-echo "configure:2034: checking for valgrind.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2039 "configure"
-#include "confdefs.h"
-#include <valgrind.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2044: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
+ echo "$as_me:$LINENO: checking for VALGRIND_DISCARD in <valgrind/memcheck.h>" >&5
+echo $ECHO_N "checking for VALGRIND_DISCARD in <valgrind/memcheck.h>... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <valgrind/memcheck.h>
+#ifndef VALGRIND_DISCARD
+#error VALGRIND_DISCARD not defined
+#endif
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ gcc_cv_header_valgrind_memcheck_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ gcc_cv_header_valgrind_memcheck_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
+ echo "$as_me:$LINENO: result: $gcc_cv_header_valgrind_memcheck_h" >&5
+echo "${ECHO_T}$gcc_cv_header_valgrind_memcheck_h" >&6
+ echo "$as_me:$LINENO: checking for VALGRIND_DISCARD in <memcheck.h>" >&5
+echo $ECHO_N "checking for VALGRIND_DISCARD in <memcheck.h>... $ECHO_C" >&6
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <memcheck.h>
+#ifndef VALGRIND_DISCARD
+#error VALGRIND_DISCARD not defined
+#endif
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
fi
-rm -f conftest*
+if test -z "$ac_cpp_err"; then
+ gcc_cv_header_memcheck_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ gcc_cv_header_memcheck_h=no
fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- have_valgrind_h=yes
+rm -f conftest.err conftest.$ac_ext
+ echo "$as_me:$LINENO: result: $gcc_cv_header_memcheck_h" >&5
+echo "${ECHO_T}$gcc_cv_header_memcheck_h" >&6
+
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ ac_executable_p="test -x"
else
- echo "$ac_t""no" 1>&6
-have_valgrind_h=no
+ ac_executable_p="test -f"
fi
+rm -f conf$$.file
- # Extract the first word of "valgrind", so it can be a program name with args.
+# Extract the first word of "valgrind", so it can be a program name with args.
set dummy valgrind; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2069: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_valgrind_path'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_valgrind_path+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
case "$valgrind_path" in
- /*)
- ac_cv_path_valgrind_path="$valgrind_path" # Let the user override the test with a path.
- ;;
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_valgrind_path="$valgrind_path" # Let the user override the test with a path.
+ ;;
*)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if $ac_dir/$ac_word --version | grep valgrind- >/dev/null 2>&1; then
- ac_cv_path_valgrind_path="$ac_dir/$ac_word"
- break
- fi
- fi
- done
- IFS="$ac_save_ifs"
- ;;
+ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$ac_save_IFS"
+ test -z "$ac_dir" && ac_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+ if $ac_dir/$ac_word --version | grep valgrind- >/dev/null 2>&1; then
+ ac_cv_path_valgrind_path="$ac_dir/$ac_word$ac_exec_ext"
+ break 2
+ fi
+ fi
+ done
+ done
+ IFS="$ac_save_IFS"
+ ;;
esac
fi
valgrind_path="$ac_cv_path_valgrind_path"
if test -n "$valgrind_path"; then
- echo "$ac_t""$valgrind_path" 1>&6
+ echo "$as_me:$LINENO: result: $valgrind_path" >&5
+echo "${ECHO_T}$valgrind_path" >&6
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
- if test "x$valgrind_path" = "x" || test $have_valgrind_h = no; then
- { echo "configure: error: *** Can't find both valgrind and valgrind.h" 1>&2; exit 1; }
+ if test "x$valgrind_path" = "x" \
+ || (test $have_valgrind_h = no \
+ && test $gcc_cv_header_memcheck_h = no \
+ && test $gcc_cv_header_valgrind_memcheck_h = no); then
+ { { echo "$as_me:$LINENO: error: *** Can't find both valgrind and valgrind/memcheck.h, memcheck.h or valgrind.h" >&5
+echo "$as_me: error: *** Can't find both valgrind and valgrind/memcheck.h, memcheck.h or valgrind.h" >&2;}
+ { (exit 1); exit 1; }; }
fi
valgrind_path_defines=-DVALGRIND_PATH='\"'$valgrind_path'\"'
valgrind_command="$valgrind_path -q"
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define ENABLE_VALGRIND_CHECKING 1
-EOF
+_ACEOF
+
+ if test $gcc_cv_header_valgrind_memcheck_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_VALGRIND_MEMCHECK_H 1
+_ACEOF
+
+ fi
+ if test $gcc_cv_header_memcheck_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MEMCHECK_H 1
+_ACEOF
+ fi
fi
@@ -2114,91 +4416,80 @@ if test "${enable_coverage+set}" = set; then
enableval="$enable_coverage"
case "${enableval}" in
yes|noopt)
- coverage_flags="-fprofile-arcs -ftest-coverage -O0"
+ coverage_flags="-fprofile-arcs -ftest-coverage -frandom-seed=\$@ -O0"
;;
opt)
- coverage_flags="-fprofile-arcs -ftest-coverage -O2"
+ coverage_flags="-fprofile-arcs -ftest-coverage -frandom-seed=\$@ -O2"
;;
*)
- { echo "configure: error: unknown coverage setting $enableval" 1>&2; exit 1; }
+ { { echo "$as_me:$LINENO: error: unknown coverage setting $enableval" >&5
+echo "$as_me: error: unknown coverage setting $enableval" >&2;}
+ { (exit 1); exit 1; }; }
;;
esac
else
coverage_flags=""
-fi
+fi;
+# Check whether --enable-gather-detailed-mem-stats or --disable-gather-detailed-mem-stats was given.
+if test "${enable_gather_detailed_mem_stats+set}" = set; then
+ enableval="$enable_gather_detailed_mem_stats"
+
+else
+ enable_gather_detailed_mem_stats=no
+fi;
+if test x$enable_gather_detailed_mem_stats = xyes ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define GATHER_STATISTICS 1
+_ACEOF
-# Check whether --with-cpp_install_dir or --without-cpp_install_dir was given.
-if test "${with_cpp_install_dir+set}" = set; then
- withval="$with_cpp_install_dir"
- if test x$withval = xyes; then
- { echo "configure: error: option --with-cpp-install-dir requires an argument" 1>&2; exit 1; }
-elif test x$withval != xno; then
- cpp_install_dir=$withval
-fi
fi
+# -------------------------------
+# Miscenalleous configure options
+# -------------------------------
+
+# With stabs
+
+# Check whether --with-stabs or --without-stabs was given.
+if test "${with_stabs+set}" = set; then
+ withval="$with_stabs"
+ stabs="$with_stabs"
+else
+ stabs=no
+fi;
+
+# Determine whether or not multilibs are enabled.
+# Check whether --enable-multilib or --disable-multilib was given.
+if test "${enable_multilib+set}" = set; then
+ enableval="$enable_multilib"
+
+else
+ enable_multilib=yes
+fi;
+
# Enable __cxa_atexit for C++.
# Check whether --enable-__cxa_atexit or --disable-__cxa_atexit was given.
if test "${enable___cxa_atexit+set}" = set; then
enableval="$enable___cxa_atexit"
- :
-fi
-
-if test x$enable___cxa_atexit = xyes; then
- cat >> confdefs.h <<\EOF
-#define DEFAULT_USE_CXA_ATEXIT 1
-EOF
-
-fi
-
-# Enable Multibyte Characters for C/C++
-# Check whether --enable-c-mbchar or --disable-c-mbchar was given.
-if test "${enable_c_mbchar+set}" = set; then
- enableval="$enable_c_mbchar"
- if test x$enable_c_mbchar != xno; then
- cat >> confdefs.h <<\EOF
-#define MULTIBYTE_CHARS 1
-EOF
-fi
-fi
+fi;
-
# Enable threads
# Pass with no value to take the default
# Pass with a value to specify a thread package
# Check whether --enable-threads or --disable-threads was given.
if test "${enable_threads+set}" = set; then
enableval="$enable_threads"
- :
+
else
enable_threads=''
-fi
-
-
+fi;
+# Save in case it gets overwritten in config.gcc
enable_threads_flag=$enable_threads
-# Check if a valid thread package
-case x${enable_threads_flag} in
- x | xno)
- # No threads
- target_thread_file='single'
- ;;
- xyes)
- # default
- target_thread_file=''
- ;;
- xdecosf1 | xirix | xmach | xos2 | xposix | xpthreads | xsingle | \
- xsolaris | xwin32 | xdce | xrtems| xvxworks | xaix)
- target_thread_file=$enable_threads_flag
- ;;
- *)
- echo "$enable_threads is an unknown thread package" 1>&2
- exit 1
- ;;
-esac
# Check whether --enable-objc-gc or --disable-objc-gc was given.
if test "${enable_objc_gc+set}" = set; then
@@ -2210,7 +4501,7 @@ else
fi
else
objc_boehm_gc=''
-fi
+fi;
# Check whether --with-dwarf2 or --without-dwarf2 was given.
@@ -2219,13 +4510,12 @@ if test "${with_dwarf2+set}" = set; then
dwarf2="$with_dwarf2"
else
dwarf2=no
-fi
-
+fi;
# Check whether --enable-shared or --disable-shared was given.
if test "${enable_shared+set}" = set; then
enableval="$enable_shared"
-
+
case $enable_shared in
yes | no) ;;
*)
@@ -2242,158 +4532,150 @@ if test "${enable_shared+set}" = set; then
else
enable_shared=yes
-fi
+fi;
-# Stage specific cflags for build.
-stage1_cflags=
-case $build in
-vax-*-*)
- if test x$GCC = xyes
- then
- stage1_cflags="-Wa,-J"
+# Check whether --with-sysroot or --without-sysroot was given.
+if test "${with_sysroot+set}" = set; then
+ withval="$with_sysroot"
+
+ case ${with_sysroot} in
+ yes) TARGET_SYSTEM_ROOT='${exec_prefix}/${target_noncanonical}/sys-root' ;;
+ *) TARGET_SYSTEM_ROOT=$with_sysroot ;;
+ esac
+
+ TARGET_SYSTEM_ROOT_DEFINE='-DTARGET_SYSTEM_ROOT=\"$(TARGET_SYSTEM_ROOT)\"'
+ CROSS_SYSTEM_HEADER_DIR='$(TARGET_SYSTEM_ROOT)$(NATIVE_SYSTEM_HEADER_DIR)'
+
+ if test "x$exec_prefix" = xNONE; then
+ if test "x$prefix" = xNONE; then
+ test_prefix=/usr/local
else
- stage1_cflags="-J"
+ test_prefix=$prefix
fi
- ;;
-powerpc-*-darwin*)
- # The spiffy cpp-precomp chokes on some legitimate constructs in GCC
- # sources; use -no-cpp-precomp to get to GNU cpp.
- # Apple's GCC has bugs in designated initializer handling, so disable
- # that too.
- stage1_cflags="-no-cpp-precomp -DHAVE_DESIGNATED_INITIALIZERS=0"
- ;;
+ else
+ test_prefix=$exec_prefix
+ fi
+ case ${TARGET_SYSTEM_ROOT} in
+ "${test_prefix}"|"${test_prefix}/"*|\
+ '${exec_prefix}'|'${exec_prefix}/'*)
+ t="$TARGET_SYSTEM_ROOT_DEFINE -DTARGET_SYSTEM_ROOT_RELOCATABLE"
+ TARGET_SYSTEM_ROOT_DEFINE="$t"
+ ;;
+ esac
+
+else
+
+ TARGET_SYSTEM_ROOT=
+ TARGET_SYSTEM_ROOT_DEFINE=
+ CROSS_SYSTEM_HEADER_DIR='$(gcc_tooldir)/sys-include'
+
+fi;
+
+
+
+
+# Build with intermodule optimisations
+# Check whether --enable-intermodule or --disable-intermodule was given.
+if test "${enable_intermodule+set}" = set; then
+ enableval="$enable_intermodule"
+ case ${enable_intermodule} in
+ yes) onestep="-onestep";;
+ *) onestep="";;
esac
+else
+ onestep=""
+fi;
-echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:2272: checking whether ${MAKE-make} sets \${MAKE}" >&5
-set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+# -------------------------
+# Checks for other programs
+# -------------------------
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftestmake <<\EOF
+ cat >conftest.make <<\_ACEOF
all:
- @echo 'ac_maketemp="${MAKE}"'
-EOF
+ @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
-eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
if test -n "$ac_maketemp"; then
eval ac_cv_prog_make_${ac_make}_set=yes
else
eval ac_cv_prog_make_${ac_make}_set=no
fi
-rm -f conftestmake
+rm -f conftest.make
fi
if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
- echo "$ac_t""yes" 1>&6
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
SET_MAKE=
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
SET_MAKE="MAKE=${MAKE-make}"
fi
-echo $ac_n "checking whether a default assembler was specified""... $ac_c" 1>&6
-echo "configure:2300: checking whether a default assembler was specified" >&5
-if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
- if test x"$gas_flag" = x"no"; then
- echo "$ac_t""yes ($DEFAULT_ASSEMBLER)" 1>&6
- else
- echo "$ac_t""yes ($DEFAULT_ASSEMBLER - GNU as)" 1>&6
- fi
-else
- echo "$ac_t""no" 1>&6
-fi
-
-echo $ac_n "checking whether a default linker was specified""... $ac_c" 1>&6
-echo "configure:2312: checking whether a default linker was specified" >&5
-if test x"${DEFAULT_LINKER+set}" = x"set"; then
- if test x"$gnu_ld_flag" = x"no"; then
- echo "$ac_t""yes ($DEFAULT_LINKER)" 1>&6
- else
- echo "$ac_t""yes ($DEFAULT_LINKER - GNU ld)" 1>&6
- fi
-else
- echo "$ac_t""no" 1>&6
-fi
-
-echo $ac_n "checking for GNU C library""... $ac_c" 1>&6
-echo "configure:2324: checking for GNU C library" >&5
-if eval "test \"`echo '$''{'gcc_cv_glibc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2329 "configure"
-#include "confdefs.h"
-#include <features.h>
-int main() {
-
-#if ! (defined __GLIBC__ || defined __GNU_LIBRARY__)
-#error Not a GNU C library system
-#endif
-; return 0; }
-EOF
-if { (eval echo configure:2339: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- gcc_cv_glibc=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- gcc_cv_glibc=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$gcc_cv_glibc" 1>&6
-if test $gcc_cv_glibc = yes; then
- cat >> confdefs.h <<\EOF
-#define _GNU_SOURCE 1
-EOF
-
-fi
-
# Find some useful tools
-for ac_prog in mawk gawk nawk awk
+for ac_prog in gawk mawk nawk awk
do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2365: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$AWK"; then
ac_cv_prog_AWK="$AWK" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_AWK="$ac_prog"
- break
- fi
- done
- IFS="$ac_save_ifs"
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_AWK="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
fi
fi
-AWK="$ac_cv_prog_AWK"
+AWK=$ac_cv_prog_AWK
if test -n "$AWK"; then
- echo "$ac_t""$AWK" 1>&6
+ echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
-test -n "$AWK" && break
+ test -n "$AWK" && break
done
-echo $ac_n "checking whether ln works""... $ac_c" 1>&6
-echo "configure:2395: checking whether ln works" >&5
-if eval "test \"`echo '$''{'gcc_cv_prog_LN'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+# We need awk to run opts.sh (to create options.c and options.h).
+# Bail out if it's missing.
+case ${AWK} in
+ "") { { echo "$as_me:$LINENO: error: can't build without awk, bailing out" >&5
+echo "$as_me: error: can't build without awk, bailing out" >&2;}
+ { (exit 1); exit 1; }; } ;;
+esac
+
+echo "$as_me:$LINENO: checking whether ln works" >&5
+echo $ECHO_N "checking whether ln works... $ECHO_C" >&6
+if test "${gcc_cv_prog_LN+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
rm -f conftestdata_t
echo >conftestdata_f
@@ -2413,19 +4695,22 @@ rm -f conftestdata_f conftestdata_t
fi
LN="$gcc_cv_prog_LN"
if test "$gcc_cv_prog_LN" = "ln"; then
- echo "$ac_t""yes" 1>&6
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
else
if test "$gcc_cv_prog_LN" = "ln -s"; then
- echo "$ac_t""no, using ln -s" 1>&6
+ echo "$as_me:$LINENO: result: no, using ln -s" >&5
+echo "${ECHO_T}no, using ln -s" >&6
else
- echo "$ac_t""no, and neither does ln -s, so using cp" 1>&6
+ echo "$as_me:$LINENO: result: no, and neither does ln -s, so using cp" >&5
+echo "${ECHO_T}no, and neither does ln -s, so using cp" >&6
fi
fi
-echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:2427: checking whether ln -s works" >&5
-if eval "test \"`echo '$''{'gcc_cv_prog_LN_S'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+if test "${gcc_cv_prog_LN_S+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
rm -f conftestdata_t
echo >conftestdata_f
@@ -2445,43 +4730,96 @@ rm -f conftestdata_f conftestdata_t
fi
LN_S="$gcc_cv_prog_LN_S"
if test "$gcc_cv_prog_LN_S" = "ln -s"; then
- echo "$ac_t""yes" 1>&6
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
else
if test "$gcc_cv_prog_LN_S" = "ln"; then
- echo "$ac_t""no, using ln" 1>&6
+ echo "$as_me:$LINENO: result: no, using ln" >&5
+echo "${ECHO_T}no, using ln" >&6
else
- echo "$ac_t""no, and neither does ln, so using cp" 1>&6
+ echo "$as_me:$LINENO: result: no, and neither does ln, so using cp" >&5
+echo "${ECHO_T}no, and neither does ln, so using cp" >&6
fi
fi
-# Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2461: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$RANLIB"; then
ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_RANLIB="ranlib"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
fi
fi
-RANLIB="$ac_cv_prog_RANLIB"
+RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
- echo "$ac_t""$RANLIB" 1>&6
+ echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
else
- echo "$ac_t""no" 1>&6
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ RANLIB=$ac_ct_RANLIB
+else
+ RANLIB="$ac_cv_prog_RANLIB"
fi
# Find a good install program. We prefer a C program (faster),
@@ -2494,11 +4832,11 @@ fi
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
-echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:2499: checking for a BSD compatible install" >&5
+echo "$as_me:$LINENO: checking for a BSD compatible install" >&5
+echo $ECHO_N "checking for a BSD compatible install... $ECHO_C" >&6
if test -z "$INSTALL"; then
-if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+if test "${ac_cv_path_install+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
for ac_dir in $PATH; do
@@ -2536,7 +4874,8 @@ fi
INSTALL="$ac_install_sh"
fi
fi
-echo "$ac_t""$INSTALL" 1>&6
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
@@ -2545,46 +4884,385 @@ test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2550: checking for ANSI C header files" >&5
-if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+# See if cmp has --ignore-initial.
+echo "$as_me:$LINENO: checking for cmp's capabilities" >&5
+echo $ECHO_N "checking for cmp's capabilities... $ECHO_C" >&6
+if test "${gcc_cv_prog_cmp_skip+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftest.$ac_ext <<EOF
-#line 2555 "configure"
-#include "confdefs.h"
+ echo abfoo >t1
+ echo cdfoo >t2
+ gcc_cv_prog_cmp_skip=slowcompare
+ if cmp --ignore-initial=2 t1 t2 > /dev/null 2>&1; then
+ if cmp --ignore-initial=1 t1 t2 > /dev/null 2>&1; then
+ :
+ else
+ gcc_cv_prog_cmp_skip=gnucompare
+ fi
+ fi
+ if test $gcc_cv_prog_cmp_skip = slowcompare ; then
+ if cmp t1 t2 2 2 > /dev/null 2>&1; then
+ if cmp t1 t2 1 1 > /dev/null 2>&1; then
+ :
+ else
+ gcc_cv_prog_cmp_skip=fastcompare
+ fi
+ fi
+ fi
+ rm t1 t2
+
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_prog_cmp_skip" >&5
+echo "${ECHO_T}$gcc_cv_prog_cmp_skip" >&6
+make_compare_target=$gcc_cv_prog_cmp_skip
+
+
+
+# See if we have the mktemp command.
+# Extract the first word of "mktemp", so it can be a program name with args.
+set dummy mktemp; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_have_mktemp_command+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$have_mktemp_command"; then
+ ac_cv_prog_have_mktemp_command="$have_mktemp_command" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_have_mktemp_command="yes"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_have_mktemp_command" && ac_cv_prog_have_mktemp_command="no"
+fi
+fi
+have_mktemp_command=$ac_cv_prog_have_mktemp_command
+if test -n "$have_mktemp_command"; then
+ echo "$as_me:$LINENO: result: $have_mktemp_command" >&5
+echo "${ECHO_T}$have_mktemp_command" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+# Do we have a single-tree copy of texinfo?
+if test -f $srcdir/../texinfo/Makefile.in; then
+ MAKEINFO='$(objdir)/../texinfo/makeinfo/makeinfo'
+ gcc_cv_prog_makeinfo_modern=yes
+ echo "$as_me:$LINENO: result: Using makeinfo from the unified source tree." >&5
+echo "${ECHO_T}Using makeinfo from the unified source tree." >&6
+else
+ # See if makeinfo has been installed and is modern enough
+ # that we can use it.
+ # Extract the first word of "makeinfo", so it can be a program name with args.
+set dummy makeinfo; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_MAKEINFO+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$MAKEINFO"; then
+ ac_cv_prog_MAKEINFO="$MAKEINFO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_MAKEINFO="makeinfo"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+MAKEINFO=$ac_cv_prog_MAKEINFO
+if test -n "$MAKEINFO"; then
+ echo "$as_me:$LINENO: result: $MAKEINFO" >&5
+echo "${ECHO_T}$MAKEINFO" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test -n "$MAKEINFO"; then
+ # Found it, now check the version.
+ echo "$as_me:$LINENO: checking for modern makeinfo" >&5
+echo $ECHO_N "checking for modern makeinfo... $ECHO_C" >&6
+if test "${gcc_cv_prog_makeinfo_modern+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_prog_version=`$MAKEINFO --version 2>&1 |
+ sed -n 's/^.*GNU texinfo.* \([0-9][0-9.]*\).*$/\1/p'`
+ echo "configure:5012: version of makeinfo is $ac_prog_version" >&5
+ case $ac_prog_version in
+ '') gcc_cv_prog_makeinfo_modern=no;;
+ 4.[2-9]*)
+ gcc_cv_prog_makeinfo_modern=yes;;
+ *) gcc_cv_prog_makeinfo_modern=no;;
+ esac
+
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_prog_makeinfo_modern" >&5
+echo "${ECHO_T}$gcc_cv_prog_makeinfo_modern" >&6
+else
+ gcc_cv_prog_makeinfo_modern=no
+fi
+
+fi
+
+if test $gcc_cv_prog_makeinfo_modern = no; then
+ { echo "$as_me:$LINENO: WARNING:
+*** Makeinfo is missing or too old.
+*** Info documentation will not be built." >&5
+echo "$as_me: WARNING:
+*** Makeinfo is missing or too old.
+*** Info documentation will not be built." >&2;}
+ BUILD_INFO=
+else
+ BUILD_INFO=info
+fi
+
+# Is pod2man recent enough to regenerate manpages?
+echo "$as_me:$LINENO: checking for recent Pod::Man" >&5
+echo $ECHO_N "checking for recent Pod::Man... $ECHO_C" >&6
+if (perl -e 'use 1.10 Pod::Man') >/dev/null 2>&1; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ GENERATED_MANPAGES=generated-manpages
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ GENERATED_MANPAGES=
+fi
+
+# How about lex?
+if test -f $srcdir/../flex/skel.c; then
+ FLEX='$(objdir)/../flex/flex'
+else
+ # Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_FLEX+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$FLEX"; then
+ ac_cv_prog_FLEX="$FLEX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_FLEX="flex"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_FLEX" && ac_cv_prog_FLEX="${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing flex"
+fi
+fi
+FLEX=$ac_cv_prog_FLEX
+if test -n "$FLEX"; then
+ echo "$as_me:$LINENO: result: $FLEX" >&5
+echo "${ECHO_T}$FLEX" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+
+# Bison?
+# The -L switch is so bison can find its skeleton file.
+if test -f $srcdir/../bison/bison.simple; then
+ BISON='$(objdir)/../bison/bison -L $(srcdir)/../bison/'
+else
+ # Extract the first word of "bison", so it can be a program name with args.
+set dummy bison; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_BISON+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$BISON"; then
+ ac_cv_prog_BISON="$BISON" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_BISON="bison"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+ test -z "$ac_cv_prog_BISON" && ac_cv_prog_BISON="${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing bison"
+fi
+fi
+BISON=$ac_cv_prog_BISON
+if test -n "$BISON"; then
+ echo "$as_me:$LINENO: result: $BISON" >&5
+echo "${ECHO_T}$BISON" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+
+# --------------------
+# Checks for C headers
+# --------------------
+
+echo "$as_me:$LINENO: checking for GNU C library" >&5
+echo $ECHO_N "checking for GNU C library... $ECHO_C" >&6
+if test "${gcc_cv_glibc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <features.h>
+int
+main ()
+{
+
+#if ! (defined __GLIBC__ || defined __GNU_LIBRARY__)
+#error Not a GNU C library system
+#endif
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ gcc_cv_glibc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gcc_cv_glibc=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+echo "$as_me:$LINENO: result: $gcc_cv_glibc" >&5
+echo "${ECHO_T}$gcc_cv_glibc" >&6
+if test $gcc_cv_glibc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define _GNU_SOURCE 1
+_ACEOF
+
+fi
+
+# Need to reject headers which give warnings, so that the -Werror bootstrap
+# works later. *sigh* This needs to come before all header checks.
+
+ac_c_preproc_warn_flag=yes
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2563: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_header_stdc=yes
else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_stdc=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 2580 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <string.h>
-EOF
+
+_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "memchr" >/dev/null 2>&1; then
+ $EGREP "memchr" >/dev/null 2>&1; then
:
else
- rm -rf conftest*
ac_cv_header_stdc=no
fi
rm -f conftest*
@@ -2593,16 +5271,20 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-cat > conftest.$ac_ext <<EOF
-#line 2598 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <stdlib.h>
-EOF
+
+_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "free" >/dev/null 2>&1; then
+ $EGREP "free" >/dev/null 2>&1; then
:
else
- rm -rf conftest*
ac_cv_header_stdc=no
fi
rm -f conftest*
@@ -2611,764 +5293,796 @@ fi
if test $ac_cv_header_stdc = yes; then
# /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-if test "$cross_compiling" = yes; then
+ if test "$cross_compiling" = yes; then
:
else
- cat > conftest.$ac_ext <<EOF
-#line 2619 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <ctype.h>
-#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int main () { int i; for (i = 0; i < 256; i++)
-if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
-exit (0); }
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
-EOF
-if { (eval echo configure:2630: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./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
:
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_header_stdc=no
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
fi
-rm -fr conftest*
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
-
fi
fi
-
-echo "$ac_t""$ac_cv_header_stdc" 1>&6
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
if test $ac_cv_header_stdc = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define STDC_HEADERS 1
-EOF
+_ACEOF
fi
-echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:2654: checking whether time.h and sys/time.h may both be included" >&5
-if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+if test "${ac_cv_header_time+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftest.$ac_ext <<EOF
-#line 2659 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
-int main() {
-struct tm *tp;
-; return 0; }
-EOF
-if { (eval echo configure:2668: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_header_time=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_time=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_time=no
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-
-echo "$ac_t""$ac_cv_header_time" 1>&6
+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6
if test $ac_cv_header_time = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define TIME_WITH_SYS_TIME 1
-EOF
+_ACEOF
fi
-echo $ac_n "checking for working stdbool.h""... $ac_c" 1>&6
-echo "configure:2689: checking for working stdbool.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_stdbool_h'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking for working stdbool.h" >&5
+echo $ECHO_N "checking for working stdbool.h... $ECHO_C" >&6
+if test "${ac_cv_header_stdbool_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftest.$ac_ext <<EOF
-#line 2694 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <stdbool.h>
-int main() {
+int
+main ()
+{
bool foo = false;
-; return 0; }
-EOF
-if { (eval echo configure:2701: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_header_stdbool_h=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_stdbool_h=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdbool_h=no
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-
-echo "$ac_t""$ac_cv_header_stdbool_h" 1>&6
+echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5
+echo "${ECHO_T}$ac_cv_header_stdbool_h" >&6
if test $ac_cv_header_stdbool_h = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_STDBOOL_H 1
-EOF
+_ACEOF
fi
-echo $ac_n "checking whether string.h and strings.h may both be included""... $ac_c" 1>&6
-echo "configure:2722: checking whether string.h and strings.h may both be included" >&5
-if eval "test \"`echo '$''{'gcc_cv_header_string'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking whether string.h and strings.h may both be included" >&5
+echo $ECHO_N "checking whether string.h and strings.h may both be included... $ECHO_C" >&6
+if test "${gcc_cv_header_string+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftest.$ac_ext <<EOF
-#line 2727 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <string.h>
#include <strings.h>
-int main() {
+int
+main ()
+{
-; return 0; }
-EOF
-if { (eval echo configure:2735: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
gcc_cv_header_string=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- gcc_cv_header_string=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gcc_cv_header_string=no
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-
-echo "$ac_t""$gcc_cv_header_string" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_header_string" >&5
+echo "${ECHO_T}$gcc_cv_header_string" >&6
if test $gcc_cv_header_string = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define STRING_WITH_STRINGS 1
-EOF
+_ACEOF
fi
-echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:2756: checking for sys/wait.h that is POSIX.1 compatible" >&5
-if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftest.$ac_ext <<EOF
-#line 2761 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <sys/types.h>
#include <sys/wait.h>
#ifndef WEXITSTATUS
-#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif
#ifndef WIFEXITED
-#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif
-int main() {
-int s;
-wait (&s);
-s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
-; return 0; }
-EOF
-if { (eval echo configure:2777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+
+int
+main ()
+{
+ int s;
+ wait (&s);
+ s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_header_sys_wait_h=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_sys_wait_h=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_sys_wait_h=no
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-
-echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
if test $ac_cv_header_sys_wait_h = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_SYS_WAIT_H 1
-EOF
+_ACEOF
fi
-for ac_hdr in limits.h stddef.h string.h strings.h stdlib.h time.h \
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_header in limits.h stddef.h string.h strings.h stdlib.h time.h \
fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
sys/resource.h sys/param.h sys/times.h sys/stat.h \
- direct.h malloc.h langinfo.h
+ direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h
do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2804: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2809 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2814: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
+if test -z "$ac_cpp_err"; then
+ eval "$as_ac_Header=yes"
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
fi
done
# Check for thread headers.
-ac_safe=`echo "thread.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for thread.h""... $ac_c" 1>&6
-echo "configure:2844: checking for thread.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2849 "configure"
-#include "confdefs.h"
+echo "$as_me:$LINENO: checking for thread.h" >&5
+echo $ECHO_N "checking for thread.h... $ECHO_C" >&6
+if test "${ac_cv_header_thread_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <thread.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2854: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
fi
-rm -f conftest*
+if test -z "$ac_cpp_err"; then
+ ac_cv_header_thread_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_thread_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
+echo "$as_me:$LINENO: result: $ac_cv_header_thread_h" >&5
+echo "${ECHO_T}$ac_cv_header_thread_h" >&6
+if test $ac_cv_header_thread_h = yes; then
have_thread_h=yes
else
- echo "$ac_t""no" 1>&6
-have_thread_h=
+ have_thread_h=
fi
-ac_safe=`echo "pthread.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for pthread.h""... $ac_c" 1>&6
-echo "configure:2878: checking for pthread.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking for pthread.h" >&5
+echo $ECHO_N "checking for pthread.h... $ECHO_C" >&6
+if test "${ac_cv_header_pthread_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftest.$ac_ext <<EOF
-#line 2883 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <pthread.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2888: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
fi
-rm -f conftest*
+if test -z "$ac_cpp_err"; then
+ ac_cv_header_pthread_h=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_header_pthread_h=no
+fi
+rm -f conftest.err conftest.$ac_ext
fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
+echo "$as_me:$LINENO: result: $ac_cv_header_pthread_h" >&5
+echo "${ECHO_T}$ac_cv_header_pthread_h" >&6
+if test $ac_cv_header_pthread_h = yes; then
have_pthread_h=yes
else
- echo "$ac_t""no" 1>&6
-have_pthread_h=
+ have_pthread_h=
fi
# These tests can't be done till we know if we have limits.h.
-echo $ac_n "checking for CHAR_BIT""... $ac_c" 1>&6
-echo "configure:2913: checking for CHAR_BIT" >&5
-if eval "test \"`echo '$''{'gcc_cv_decl_char_bit'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2918 "configure"
-#include "confdefs.h"
+echo "$as_me:$LINENO: checking for CHAR_BIT" >&5
+echo $ECHO_N "checking for CHAR_BIT... $ECHO_C" >&6
+if test "${gcc_cv_decl_char_bit+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef CHAR_BIT
found
#endif
-EOF
+_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "found" >/dev/null 2>&1; then
- rm -rf conftest*
+ $EGREP "found" >/dev/null 2>&1; then
gcc_cv_decl_char_bit=yes
else
- rm -rf conftest*
gcc_cv_decl_char_bit=no
fi
rm -f conftest*
fi
-
-echo "$ac_t""$gcc_cv_decl_char_bit" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_decl_char_bit" >&5
+echo "${ECHO_T}$gcc_cv_decl_char_bit" >&6
if test $gcc_cv_decl_char_bit = no; then
- echo $ac_n "checking number of bits in a byte""... $ac_c" 1>&6
-echo "configure:2943: checking number of bits in a byte" >&5
-if eval "test \"`echo '$''{'gcc_cv_c_nbby'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+ echo "$as_me:$LINENO: checking number of bits in a byte" >&5
+echo $ECHO_N "checking number of bits in a byte... $ECHO_C" >&6
+if test "${gcc_cv_c_nbby+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
i=8
gcc_cv_c_nbby=
while test $i -lt 65; do
- cat > conftest.$ac_ext <<EOF
-#line 2951 "configure"
-#include "confdefs.h"
-
-int main() {
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
switch(0) {
case (unsigned char)((unsigned long)1 << $i) == ((unsigned long)1 << $i):
case (unsigned char)((unsigned long)1<<($i-1)) == ((unsigned long)1<<($i-1)):
; }
-; return 0; }
-EOF
-if { (eval echo configure:2961: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
gcc_cv_c_nbby=$i; break
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
i=`expr $i + 1`
done
test -z "$gcc_cv_c_nbby" && gcc_cv_c_nbby=failed
fi
-
-echo "$ac_t""$gcc_cv_c_nbby" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_c_nbby" >&5
+echo "${ECHO_T}$gcc_cv_c_nbby" >&6
if test $gcc_cv_c_nbby = failed; then
- { echo "configure: error: cannot determine number of bits in a byte" 1>&2; exit 1; }
+ { { echo "$as_me:$LINENO: error: cannot determine number of bits in a byte" >&5
+echo "$as_me: error: cannot determine number of bits in a byte" >&2;}
+ { (exit 1); exit 1; }; }
else
- cat >> confdefs.h <<EOF
+
+cat >>confdefs.h <<_ACEOF
#define CHAR_BIT $gcc_cv_c_nbby
-EOF
+_ACEOF
fi
fi
-echo $ac_n "checking byte ordering""... $ac_c" 1>&6
-echo "configure:2986: checking byte ordering" >&5
-if eval "test \"`echo '$''{'ac_cv_c_compile_endian'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- ac_cv_c_compile_endian=unknown
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-cat > conftest.$ac_ext <<EOF
-#line 3000 "configure"
-#include "confdefs.h"
+ ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/param.h>
+int
+main ()
+{
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
#endif
-/* This structure must have no internal padding. */
- struct {
- char prefix[sizeof "\nendian:" - 1];
- short word;
- char postfix[2];
- } tester = {
- "\nendian:",
-#if SIZEOF_SHORT == 4
- ('A' << (CHAR_BIT * 3)) | ('B' << (CHAR_BIT * 2)) |
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <sys/param.h>
+int
+main ()
+{
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
#endif
- ('A' << CHAR_BIT) | 'B',
- 'X', '\n'
-};
-EOF
-if { (eval echo configure:3020: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- od -c conftest.o |
- sed 's/^[0-7]*[ ]*/ /
- s/\*/./g
- s/ \\n/*/g
- s/ [0-9][0-9][0-9]/./g
- s/ \\[^ ]/./g' |
- tr -d '
- ' | tr -s '*' '
-' | fold | sed '$a\
-' > conftest.dmp
- if grep 'endian:AB' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_compile_endian=big-endian
- elif grep 'endian:BA' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_compile_endian=little-endian
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ ac_cv_c_bigendian=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+ echo $ac_n "cross-compiling... " 2>&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./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_c_bigendian=no
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+if test $ac_cv_c_bigendian = unknown; then
+echo "$as_me:$LINENO: checking to probe for byte ordering" >&5
+echo $ECHO_N "checking to probe for byte ordering... $ECHO_C" >&6
+
+cat >conftest.c <<EOF
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii() { char* s = (char*) ascii_mm; s = (char*) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic() { char* s = (char*) ebcdic_mm; s = (char*) ebcdic_ii; }
+int main() { _ascii (); _ebcdic (); return 0; }
+EOF
+ if test -f conftest.c ; then
+ if ${CC-cc} ${CFLAGS} conftest.c -o conftest.o && test -f conftest.o ; then
+ if test `grep -l BIGenDianSyS conftest.o` ; then
+ echo $ac_n ' big endian probe OK, ' 1>&6
+ ac_cv_c_bigendian=yes
+ fi
+ if test `grep -l LiTTleEnDian conftest.o` ; then
+ echo $ac_n ' little endian probe OK, ' 1>&6
+ if test $ac_cv_c_bigendian = yes ; then
+ ac_cv_c_bigendian=unknown;
+ else
+ ac_cv_c_bigendian=no
+ fi
+ fi
+ echo $ac_n 'guessing bigendian ... ' >&6
+ fi
fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
fi
-rm -rf conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
+if test $ac_cv_c_bigendian = yes; then
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
-fi
-echo "$ac_t""$ac_cv_c_compile_endian" 1>&6
-if test $ac_cv_c_compile_endian = unknown; then
- { echo "configure: error: *** unable to determine endianness" 1>&2; exit 1; }
-elif test $ac_cv_c_compile_endian = big-endian; then
- cat >> confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
#define HOST_WORDS_BIG_ENDIAN 1
-EOF
-
-fi
+_ACEOF
-echo $ac_n "checking floating point format""... $ac_c" 1>&6
-echo "configure:3059: checking floating point format" >&5
-if eval "test \"`echo '$''{'ac_cv_c_float_format'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+ BYTEORDER=4321
else
-
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-cat > conftest.$ac_ext <<EOF
-#line 3072 "configure"
-#include "confdefs.h"
-/* This will not work unless sizeof(double) == 8. */
-extern char sizeof_double_must_be_8 [sizeof(double) == 8 ? 1 : -1];
-
-/* This structure must have no internal padding. */
-struct possibility {
- char prefix[8];
- double candidate;
- char postfix[8];
-};
-
-#define C(cand) { "\nformat:", cand, ":tamrof\n" }
-struct possibility table [] =
-{
- C( 3.25724264705901305206e+01), /* @@IEEEFP - IEEE 754 */
- C( 3.53802595280598432000e+18), /* D__float - VAX */
- C( 5.32201830133125317057e-19), /* D.PDP-10 - PDP-10 - the dot is 0x13a */
- C( 1.77977764695171661377e+10), /* IBMHEXFP - s/390 format, ascii */
- C(-5.22995989424860458374e+10) /* IBMHEXFP - s/390 format, EBCDIC */
-};
-EOF
-if { (eval echo configure:3094: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- od -c conftest.o |
- sed 's/^[0-7]*[ ]*/ /
- s/\*/./g
- s/ \\n/*/g
- s/ [0-9][0-9][0-9]/./g
- s/ \\[^ ]/./g' |
- tr -d '
- ' | tr -s '*' '
-' | fold | sed '$a\
-' > conftest.dmp
- if grep 'format:.@IEEEF.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='IEEE (big-endian)'
- elif grep 'format:.I@@PFE.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='IEEE (big-endian)'
- elif grep 'format:.FEEEI@.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='IEEE (little-endian)'
- elif grep 'format:.EFP@@I.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='IEEE (little-endian)'
- elif grep 'format:.__floa.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='VAX D-float'
- elif grep 'format:..PDP-1.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='PDP-10'
- elif grep 'format:.BMHEXF.:tamrof' conftest.dmp >/dev/null 2>&1; then
- ac_cv_c_float_format='IBM 370 hex'
- else
- { echo "configure: error: Unknown floating point format" 1>&2; exit 1; }
- fi
-else
- { echo "configure: error: compile failed" 1>&2; exit 1; }
-fi
-rm -rf conftest*
-ac_ext=c
-# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
-cross_compiling=$ac_cv_prog_cc_cross
-
-
-fi
-
-echo "$ac_t""$ac_cv_c_float_format" 1>&6
-# IEEE is the default format. If the float endianness isn't the same
-# as the integer endianness, we have to set FLOAT_WORDS_BIG_ENDIAN
-# (which is a tristate: yes, no, default). This is only an issue with
-# IEEE; the other formats are only supported by a few machines each,
-# all with the same endianness.
-format=
-fbigend=
-case $ac_cv_c_float_format in
- 'IEEE (big-endian)' )
- if test $ac_cv_c_compile_endian = little-endian; then
- fbigend=1
- fi
- ;;
- 'IEEE (little-endian)' )
- if test $ac_cv_c_compile_endian = big-endian; then
- fbigend=0
- fi
- ;;
- 'VAX D-float' )
- format=VAX_FLOAT_FORMAT
- ;;
- 'PDP-10' )
- format=PDP10_FLOAT_FORMAT
- ;;
- 'IBM 370 hex' )
- format=IBM_FLOAT_FORMAT
- ;;
-esac
-if test -n "$format"; then
- cat >> confdefs.h <<EOF
-#define HOST_FLOAT_FORMAT $format
-EOF
-
-fi
-if test -n "$fbigend"; then
- cat >> confdefs.h <<EOF
-#define HOST_FLOAT_WORDS_BIG_ENDIAN $fbigend
-EOF
-
-fi
-
-
-# See if we have the mktemp command.
-# Extract the first word of "mktemp", so it can be a program name with args.
-set dummy mktemp; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3183: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_have_mktemp_command'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$have_mktemp_command"; then
- ac_cv_prog_have_mktemp_command="$have_mktemp_command" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_have_mktemp_command="yes"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_have_mktemp_command" && ac_cv_prog_have_mktemp_command="no"
-fi
-fi
-have_mktemp_command="$ac_cv_prog_have_mktemp_command"
-if test -n "$have_mktemp_command"; then
- echo "$ac_t""$have_mktemp_command" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-# Do we have a single-tree copy of texinfo?
-if test -f $srcdir/../texinfo/Makefile.in; then
- MAKEINFO='$(objdir)/../texinfo/makeinfo/makeinfo'
- gcc_cv_prog_makeinfo_modern=yes
- echo "$ac_t""Using makeinfo from the unified source tree." 1>&6
-else
- # See if makeinfo has been installed and is modern enough
- # that we can use it.
- # Extract the first word of "makeinfo", so it can be a program name with args.
-set dummy makeinfo; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3222: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_MAKEINFO'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$MAKEINFO"; then
- ac_cv_prog_MAKEINFO="$MAKEINFO" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_MAKEINFO="makeinfo"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-MAKEINFO="$ac_cv_prog_MAKEINFO"
-if test -n "$MAKEINFO"; then
- echo "$ac_t""$MAKEINFO" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-if test -n "$MAKEINFO"; then
- # Found it, now check the version.
- echo $ac_n "checking for modern makeinfo""... $ac_c" 1>&6
-echo "configure:3251: checking for modern makeinfo" >&5
-if eval "test \"`echo '$''{'gcc_cv_prog_makeinfo_modern'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_prog_version=`$MAKEINFO --version 2>&1 |
- sed -n 's/^.*GNU texinfo.* \([0-9][0-9.]*\).*$/\1/p'`
- echo "configure:3257: version of makeinfo is $ac_prog_version" >&5
- case $ac_prog_version in
- '') gcc_cv_prog_makeinfo_modern=no;;
- 4.[2-9]*)
- gcc_cv_prog_makeinfo_modern=yes;;
- *) gcc_cv_prog_makeinfo_modern=no;;
- esac
-
+ BYTEORDER=1234
fi
-echo "$ac_t""$gcc_cv_prog_makeinfo_modern" 1>&6
-else
- gcc_cv_prog_makeinfo_modern=no
-fi
-
-fi
-
-if test $gcc_cv_prog_makeinfo_modern = no; then
- echo "configure: warning:
-*** Makeinfo is missing or too old.
-*** Info documentation will not be built." 1>&2
- BUILD_INFO=
-else
- BUILD_INFO=info
-fi
+cat >>confdefs.h <<_ACEOF
+#define BYTEORDER $BYTEORDER
+_ACEOF
-# Is pod2man recent enough to regenerate manpages?
-echo $ac_n "checking for recent Pod::Man""... $ac_c" 1>&6
-echo "configure:3285: checking for recent Pod::Man" >&5
-if (perl -e 'use 1.10 Pod::Man') >/dev/null 2>&1; then
- echo "$ac_t""yes" 1>&6
- GENERATED_MANPAGES=generated-manpages
-else
- echo "$ac_t""no" 1>&6
- GENERATED_MANPAGES=
+if test $ac_cv_c_bigendian = unknown; then
+ { { echo "$as_me:$LINENO: error: unknown endianess - sorry" >&5
+echo "$as_me: error: unknown endianess - sorry" >&2;}
+ { (exit please pre-set ac_cv_c_bigendian); exit please pre-set ac_cv_c_bigendian; }; }
fi
-# How about lex?
-if test -f $srcdir/../flex/skel.c; then
- FLEX='$(objdir)/../flex/flex'
-else
- # Extract the first word of "flex", so it can be a program name with args.
-set dummy flex; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3301: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_FLEX'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$FLEX"; then
- ac_cv_prog_FLEX="$FLEX" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_FLEX="flex"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_FLEX" && ac_cv_prog_FLEX="${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing flex"
-fi
-fi
-FLEX="$ac_cv_prog_FLEX"
-if test -n "$FLEX"; then
- echo "$ac_t""$FLEX" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-fi
+# --------
+# UNSORTED
+# --------
-# Bison?
-# The -L switch is so bison can find its skeleton file.
-if test -f $srcdir/../bison/bison.simple; then
- BISON='$(objdir)/../bison/bison -L $(srcdir)/../bison/'
-else
- # Extract the first word of "bison", so it can be a program name with args.
-set dummy bison; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3338: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_BISON'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$BISON"; then
- ac_cv_prog_BISON="$BISON" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_BISON="bison"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_prog_BISON" && ac_cv_prog_BISON="${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing bison"
-fi
-fi
-BISON="$ac_cv_prog_BISON"
-if test -n "$BISON"; then
- echo "$ac_t""$BISON" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
+# Stage specific cflags for build.
+stage1_cflags=
+case $build in
+vax-*-*)
+ if test x$GCC = xyes
+ then
+ stage1_cflags="-Wa,-J"
+ else
+ stage1_cflags="-J"
+ fi
+ ;;
+powerpc-*-darwin*)
+ # The spiffy cpp-precomp chokes on some legitimate constructs in GCC
+ # sources; use -no-cpp-precomp to get to GNU cpp.
+ # Apple's GCC has bugs in designated initializer handling, so disable
+ # that too.
+ stage1_cflags="-no-cpp-precomp -DHAVE_DESIGNATED_INITIALIZERS=0"
+ ;;
+esac
-fi
# These libraries may be used by collect2.
# We may need a special search path to get them linked.
-echo $ac_n "checking for collect2 libraries""... $ac_c" 1>&6
-echo "configure:3370: checking for collect2 libraries" >&5
-if eval "test \"`echo '$''{'gcc_cv_collect2_libs'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking for collect2 libraries" >&5
+echo $ECHO_N "checking for collect2 libraries... $ECHO_C" >&6
+if test "${gcc_cv_collect2_libs+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
save_LIBS="$LIBS"
for libs in '' -lld -lmld \
@@ -3376,32 +6090,54 @@ for libs in '' -lld -lmld \
'-L/usr/lib/cmplrs/cc3.11 -lmld'
do
LIBS="$libs"
- cat > conftest.$ac_ext <<EOF
-#line 3381 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* 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 ldopen();
-
-int main() {
-ldopen()
-; return 0; }
-EOF
-if { (eval echo configure:3392: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
+ builtin and then its argument prototype would still apply. */
+char ldopen ();
+int
+main ()
+{
+ldopen ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 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
gcc_cv_collect2_libs="$libs"; break
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
done
LIBS="$save_LIBS"
test -z "$gcc_cv_collect2_libs" && gcc_cv_collect2_libs='none required'
fi
-
-echo "$ac_t""$gcc_cv_collect2_libs" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_collect2_libs" >&5
+echo "${ECHO_T}$gcc_cv_collect2_libs" >&6
case $gcc_cv_collect2_libs in
"none required") ;;
*) COLLECT2_LIBS=$gcc_cv_collect2_libs ;;
@@ -3412,68 +6148,112 @@ esac
# -lexc. So test for it.
save_LIBS="$LIBS"
LIBS=
+echo "$as_me:$LINENO: checking for library containing exc_resume" >&5
+echo $ECHO_N "checking for library containing exc_resume... $ECHO_C" >&6
+if test "${ac_cv_search_exc_resume+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_exc_resume=no
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-echo $ac_n "checking for library containing exc_resume""... $ac_c" 1>&6
-echo "configure:3418: checking for library containing exc_resume" >&5
-if eval "test \"`echo '$''{'ac_cv_search_exc_resume'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_func_search_save_LIBS="$LIBS"
-ac_cv_search_exc_resume="no"
-cat > conftest.$ac_ext <<EOF
-#line 3425 "configure"
-#include "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 exc_resume();
-
-int main() {
-exc_resume()
-; return 0; }
-EOF
-if { (eval echo configure:3436: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
+ builtin and then its argument prototype would still apply. */
+char exc_resume ();
+int
+main ()
+{
+exc_resume ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 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_search_exc_resume="none required"
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
-test "$ac_cv_search_exc_resume" = "no" && for i in exc; do
-LIBS="-l$i $ac_func_search_save_LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 3447 "configure"
-#include "confdefs.h"
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_exc_resume" = no; then
+ for ac_lib in exc; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* 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 exc_resume();
-
-int main() {
-exc_resume()
-; return 0; }
-EOF
-if { (eval echo configure:3458: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- ac_cv_search_exc_resume="-l$i"
+ builtin and then its argument prototype would still apply. */
+char exc_resume ();
+int
+main ()
+{
+exc_resume ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 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_search_exc_resume="-l$ac_lib"
break
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
-done
-LIBS="$ac_func_search_save_LIBS"
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ done
fi
-
-echo "$ac_t""$ac_cv_search_exc_resume" 1>&6
-if test "$ac_cv_search_exc_resume" != "no"; then
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_exc_resume" >&5
+echo "${ECHO_T}$ac_cv_search_exc_resume" >&6
+if test "$ac_cv_search_exc_resume" != no; then
test "$ac_cv_search_exc_resume" = "none required" || LIBS="$ac_cv_search_exc_resume $LIBS"
-
-else :
-
+
fi
+
GNAT_LIBEXC="$LIBS"
LIBS="$save_LIBS"
@@ -3482,296 +6262,465 @@ LIBS="$save_LIBS"
# they're both in the same place. jcf-dump needs them.
save_LIBS="$LIBS"
LIBS=
+echo "$as_me:$LINENO: checking for library containing ldexp" >&5
+echo $ECHO_N "checking for library containing ldexp... $ECHO_C" >&6
+if test "${ac_cv_search_ldexp+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_ldexp=no
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-echo $ac_n "checking for library containing ldexp""... $ac_c" 1>&6
-echo "configure:3488: checking for library containing ldexp" >&5
-if eval "test \"`echo '$''{'ac_cv_search_ldexp'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_func_search_save_LIBS="$LIBS"
-ac_cv_search_ldexp="no"
-cat > conftest.$ac_ext <<EOF
-#line 3495 "configure"
-#include "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 ldexp();
-
-int main() {
-ldexp()
-; return 0; }
-EOF
-if { (eval echo configure:3506: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
+ builtin and then its argument prototype would still apply. */
+char ldexp ();
+int
+main ()
+{
+ldexp ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 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_search_ldexp="none required"
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
-test "$ac_cv_search_ldexp" = "no" && for i in m; do
-LIBS="-l$i $ac_func_search_save_LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 3517 "configure"
-#include "confdefs.h"
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_ldexp" = no; then
+ for ac_lib in m; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* 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 ldexp();
-
-int main() {
-ldexp()
-; return 0; }
-EOF
-if { (eval echo configure:3528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- ac_cv_search_ldexp="-l$i"
+ builtin and then its argument prototype would still apply. */
+char ldexp ();
+int
+main ()
+{
+ldexp ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 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_search_ldexp="-l$ac_lib"
break
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
-done
-LIBS="$ac_func_search_save_LIBS"
-fi
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-echo "$ac_t""$ac_cv_search_ldexp" 1>&6
-if test "$ac_cv_search_ldexp" != "no"; then
- test "$ac_cv_search_ldexp" = "none required" || LIBS="$ac_cv_search_ldexp $LIBS"
-
-else :
-
fi
-LDEXP_LIB="$LIBS"
-LIBS="$save_LIBS"
-
-
-# See if the stage1 system preprocessor understands the ANSI C
-# preprocessor stringification operator. (Used by symcat.h.)
-
-
-echo $ac_n "checking for preprocessor stringizing operator""... $ac_c" 1>&6
-echo "configure:3557: checking for preprocessor stringizing operator" >&5
-if eval "test \"`echo '$''{'ac_cv_c_stringize'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3562 "configure"
-#include "confdefs.h"
-
-#define x(y) #y
-
-char *s = x(teststring);
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "#teststring" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_c_stringize=no
-else
- rm -rf conftest*
- ac_cv_c_stringize=yes
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ done
fi
-rm -f conftest*
-
+LIBS=$ac_func_search_save_LIBS
fi
-
-if test "${ac_cv_c_stringize}" = yes
-then
- cat >> confdefs.h <<\EOF
-#define HAVE_STRINGIZE 1
-EOF
+echo "$as_me:$LINENO: result: $ac_cv_search_ldexp" >&5
+echo "${ECHO_T}$ac_cv_search_ldexp" >&6
+if test "$ac_cv_search_ldexp" != no; then
+ test "$ac_cv_search_ldexp" = "none required" || LIBS="$ac_cv_search_ldexp $LIBS"
fi
-echo "$ac_t""${ac_cv_c_stringize}" 1>&6
+
+LDEXP_LIB="$LIBS"
+LIBS="$save_LIBS"
# Use <inttypes.h> only if it exists,
# doesn't clash with <sys/types.h>, and declares intmax_t.
-echo $ac_n "checking for inttypes.h""... $ac_c" 1>&6
-echo "configure:3595: checking for inttypes.h" >&5
-if eval "test \"`echo '$''{'gcc_cv_header_inttypes_h'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3600 "configure"
-#include "confdefs.h"
+echo "$as_me:$LINENO: checking for inttypes.h" >&5
+echo $ECHO_N "checking for inttypes.h... $ECHO_C" >&6
+if test "${gcc_cv_header_inttypes_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <sys/types.h>
#include <inttypes.h>
-int main() {
+int
+main ()
+{
intmax_t i = -1;
-; return 0; }
-EOF
-if { (eval echo configure:3608: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
gcc_cv_header_inttypes_h=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- gcc_cv_header_inttypes_h=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gcc_cv_header_inttypes_h=no
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-echo "$ac_t""$gcc_cv_header_inttypes_h" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_header_inttypes_h" >&5
+echo "${ECHO_T}$gcc_cv_header_inttypes_h" >&6
if test $gcc_cv_header_inttypes_h = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_INTTYPES_H 1
-EOF
+_ACEOF
fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
for ac_func in times clock dup2 kill getrlimit setrlimit atoll atoq \
sysconf strsignal putc_unlocked fputc_unlocked fputs_unlocked \
- fwrite_unlocked fprintf_unlocked getrusage nl_langinfo lstat \
- scandir alphasort gettimeofday mmap
+ fwrite_unlocked fprintf_unlocked getrusage nl_langinfo \
+ scandir alphasort gettimeofday mbstowcs wcswidth mmap mincore \
+ setlocale
do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3635: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3640 "configure"
-#include "confdefs.h"
+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
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
+ 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
/* 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();
-
-int main() {
-
+ 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
-$ac_func();
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
#endif
-; return 0; }
-EOF
-if { (eval echo configure:3663: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
+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>&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.$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
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
fi
done
-echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
-echo "configure:3689: checking for ssize_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+if test x$ac_cv_func_mbstowcs = xyes; then
+ echo "$as_me:$LINENO: checking whether mbstowcs works" >&5
+echo $ECHO_N "checking whether mbstowcs works... $ECHO_C" >&6
+if test "${gcc_cv_func_mbstowcs_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftest.$ac_ext <<EOF
-#line 3694 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
+ if test "$cross_compiling" = yes; then
+ gcc_cv_func_mbstowcs_works=yes
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "(^|[^a-zA-Z_0-9])ssize_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
+int main()
+{
+ mbstowcs(0, "", 0);
+ return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./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
+ gcc_cv_func_mbstowcs_works=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+gcc_cv_func_mbstowcs_works=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_func_mbstowcs_works" >&5
+echo "${ECHO_T}$gcc_cv_func_mbstowcs_works" >&6
+ if test x$gcc_cv_func_mbstowcs_works = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_WORKING_MBSTOWCS 1
+_ACEOF
+
+ fi
+fi
+
+echo "$as_me:$LINENO: checking for ssize_t" >&5
+echo $ECHO_N "checking for ssize_t... $ECHO_C" >&6
+if test "${ac_cv_type_ssize_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((ssize_t *) 0)
+ return 0;
+if (sizeof (ssize_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_type_ssize_t=yes
else
- rm -rf conftest*
- ac_cv_type_ssize_t=no
-fi
-rm -f conftest*
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ac_cv_type_ssize_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-echo "$ac_t""$ac_cv_type_ssize_t" 1>&6
-if test $ac_cv_type_ssize_t = no; then
- cat >> confdefs.h <<\EOF
+echo "$as_me:$LINENO: result: $ac_cv_type_ssize_t" >&5
+echo "${ECHO_T}$ac_cv_type_ssize_t" >&6
+if test $ac_cv_type_ssize_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
#define ssize_t int
-EOF
+_ACEOF
fi
# Try to determine the array type of the second argument of getgroups
# for the target system (int or gid_t).
-echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:3725: checking for uid_t in sys/types.h" >&5
-if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3730 "configure"
-#include "confdefs.h"
+echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5
+echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6
+if test "${ac_cv_type_uid_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <sys/types.h>
-EOF
+
+_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "uid_t" >/dev/null 2>&1; then
- rm -rf conftest*
+ $EGREP "uid_t" >/dev/null 2>&1; then
ac_cv_type_uid_t=yes
else
- rm -rf conftest*
ac_cv_type_uid_t=no
fi
rm -f conftest*
fi
-
-echo "$ac_t""$ac_cv_type_uid_t" 1>&6
+echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5
+echo "${ECHO_T}$ac_cv_type_uid_t" >&6
if test $ac_cv_type_uid_t = no; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define uid_t int
-EOF
+_ACEOF
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define gid_t int
-EOF
+_ACEOF
fi
-echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6
-echo "configure:3759: checking type of array argument to getgroups" >&5
-if eval "test \"`echo '$''{'ac_cv_type_getgroups'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking type of array argument to getgroups" >&5
+echo $ECHO_N "checking type of array argument to getgroups... $ECHO_C" >&6
+if test "${ac_cv_type_getgroups+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test "$cross_compiling" = yes; then
ac_cv_type_getgroups=cross
else
- cat > conftest.$ac_ext <<EOF
-#line 3767 "configure"
-#include "confdefs.h"
-
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
/* Thanks to Mike Rendell for this test. */
#include <sys/types.h>
#define NGID 256
#undef MAX
#define MAX(x, y) ((x) > (y) ? (x) : (y))
-main()
+
+int
+main ()
{
gid_t gidset[NGID];
int i, n;
@@ -3786,43 +6735,56 @@ main()
happens when gid_t is short but getgroups modifies an array of ints. */
exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0);
}
-
-EOF
-if { (eval echo configure:3792: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
- ac_cv_type_getgroups=gid_t
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./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_type_getgroups=gid_t
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_type_getgroups=int
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_type_getgroups=int
fi
-rm -fr conftest*
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
-
if test $ac_cv_type_getgroups = cross; then
- cat > conftest.$ac_ext <<EOF
-#line 3806 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <unistd.h>
-EOF
+
+_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "getgroups.*int.*gid_t" >/dev/null 2>&1; then
- rm -rf conftest*
+ $EGREP "getgroups.*int.*gid_t" >/dev/null 2>&1; then
ac_cv_type_getgroups=gid_t
else
- rm -rf conftest*
ac_cv_type_getgroups=int
fi
rm -f conftest*
fi
fi
+echo "$as_me:$LINENO: result: $ac_cv_type_getgroups" >&5
+echo "${ECHO_T}$ac_cv_type_getgroups" >&6
-echo "$ac_t""$ac_cv_type_getgroups" 1>&6
-cat >> confdefs.h <<EOF
+cat >>confdefs.h <<_ACEOF
#define GETGROUPS_T $ac_cv_type_getgroups
-EOF
+_ACEOF
if test "${target}" = "${build}"; then
@@ -3842,17 +6804,21 @@ else
fi
-echo $ac_n "checking whether the printf functions support %p""... $ac_c" 1>&6
-echo "configure:3847: checking whether the printf functions support %p" >&5
-if eval "test \"`echo '$''{'gcc_cv_func_printf_ptr'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking whether the printf functions support %p" >&5
+echo $ECHO_N "checking whether the printf functions support %p... $ECHO_C" >&6
+if test "${gcc_cv_func_printf_ptr+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test "$cross_compiling" = yes; then
gcc_cv_func_printf_ptr=no
else
- cat > conftest.$ac_ext <<EOF
-#line 3855 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <stdio.h>
int main()
@@ -3863,27 +6829,38 @@ int main()
sscanf(buf, "%p", &q);
return (p != q);
}
-EOF
-if { (eval echo configure:3868: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./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
gcc_cv_func_printf_ptr=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- gcc_cv_func_printf_ptr=no
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+gcc_cv_func_printf_ptr=no
fi
-rm -fr conftest*
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
-
rm -f core core.* *.core
fi
-
-echo "$ac_t""$gcc_cv_func_printf_ptr" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_func_printf_ptr" >&5
+echo "${ECHO_T}$gcc_cv_func_printf_ptr" >&6
if test $gcc_cv_func_printf_ptr = yes ; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_PRINTF_PTR 1
-EOF
+_ACEOF
fi
@@ -3893,29 +6870,29 @@ if test $ac_cv_header_sys_mman_h != yes \
gcc_cv_func_mmap_dev_zero=no
gcc_cv_func_mmap_anon=no
else
- echo $ac_n "checking whether read-only mmap of a plain file works""... $ac_c" 1>&6
-echo "configure:3898: checking whether read-only mmap of a plain file works" >&5
-if eval "test \"`echo '$''{'gcc_cv_func_mmap_file'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+ echo "$as_me:$LINENO: checking whether read-only mmap of a plain file works" >&5
+echo $ECHO_N "checking whether read-only mmap of a plain file works... $ECHO_C" >&6
+if test "${gcc_cv_func_mmap_file+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- # Add a system to this blacklist if
+ # Add a system to this blacklist if
# mmap(0, stat_size, PROT_READ, MAP_PRIVATE, fd, 0) doesn't return a
# memory area containing the same data that you'd get if you applied
# read() to the same fd. The only system known to have a problem here
# is VMS, where text files have record structure.
case "$host_os" in
- vms*)
+ vms* | ultrix*)
gcc_cv_func_mmap_file=no ;;
*)
gcc_cv_func_mmap_file=yes;;
esac
fi
-
-echo "$ac_t""$gcc_cv_func_mmap_file" 1>&6
- echo $ac_n "checking whether mmap from /dev/zero works""... $ac_c" 1>&6
-echo "configure:3917: checking whether mmap from /dev/zero works" >&5
-if eval "test \"`echo '$''{'gcc_cv_func_mmap_dev_zero'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_func_mmap_file" >&5
+echo "${ECHO_T}$gcc_cv_func_mmap_file" >&6
+ echo "$as_me:$LINENO: checking whether mmap from /dev/zero works" >&5
+echo $ECHO_N "checking whether mmap from /dev/zero works... $ECHO_C" >&6
+if test "${gcc_cv_func_mmap_dev_zero+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
# Add a system to this blacklist if it has mmap() but /dev/zero
# does not exist, or if mmapping /dev/zero does not give anonymous
@@ -3934,18 +6911,22 @@ else
gcc_cv_func_mmap_dev_zero=yes;;
esac
fi
-
-echo "$ac_t""$gcc_cv_func_mmap_dev_zero" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_func_mmap_dev_zero" >&5
+echo "${ECHO_T}$gcc_cv_func_mmap_dev_zero" >&6
# Unlike /dev/zero, the MAP_ANON(YMOUS) defines can be probed for.
- echo $ac_n "checking for MAP_ANON(YMOUS)""... $ac_c" 1>&6
-echo "configure:3943: checking for MAP_ANON(YMOUS)" >&5
-if eval "test \"`echo '$''{'gcc_cv_decl_map_anon'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3948 "configure"
-#include "confdefs.h"
+ echo "$as_me:$LINENO: checking for MAP_ANON(YMOUS)" >&5
+echo $ECHO_N "checking for MAP_ANON(YMOUS)... $ECHO_C" >&6
+if test "${gcc_cv_decl_map_anon+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
@@ -3954,31 +6935,45 @@ else
#define MAP_ANONYMOUS MAP_ANON
#endif
-int main() {
+int
+main ()
+{
int n = MAP_ANONYMOUS;
-; return 0; }
-EOF
-if { (eval echo configure:3962: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
gcc_cv_decl_map_anon=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- gcc_cv_decl_map_anon=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gcc_cv_decl_map_anon=no
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-
-echo "$ac_t""$gcc_cv_decl_map_anon" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_decl_map_anon" >&5
+echo "${ECHO_T}$gcc_cv_decl_map_anon" >&6
if test $gcc_cv_decl_map_anon = no; then
gcc_cv_func_mmap_anon=no
else
- echo $ac_n "checking whether mmap with MAP_ANON(YMOUS) works""... $ac_c" 1>&6
-echo "configure:3980: checking whether mmap with MAP_ANON(YMOUS) works" >&5
-if eval "test \"`echo '$''{'gcc_cv_func_mmap_anon'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+ echo "$as_me:$LINENO: checking whether mmap with MAP_ANON(YMOUS) works" >&5
+echo $ECHO_N "checking whether mmap with MAP_ANON(YMOUS) works... $ECHO_C" >&6
+if test "${gcc_cv_func_mmap_anon+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
# Add a system to this blacklist if it has mmap() and MAP_ANON or
# MAP_ANONYMOUS, but using mmap(..., MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
@@ -3992,192 +6987,343 @@ else
gcc_cv_func_mmap_anon=yes;;
esac
fi
-
-echo "$ac_t""$gcc_cv_func_mmap_anon" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_func_mmap_anon" >&5
+echo "${ECHO_T}$gcc_cv_func_mmap_anon" >&6
fi
fi
if test $gcc_cv_func_mmap_file = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_MMAP_FILE 1
-EOF
+_ACEOF
fi
if test $gcc_cv_func_mmap_dev_zero = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_MMAP_DEV_ZERO 1
-EOF
+_ACEOF
fi
if test $gcc_cv_func_mmap_anon = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_MMAP_ANON 1
-EOF
+_ACEOF
fi
case "${host}" in
-*-*-uwin*)
- { echo "configure: error:
-*** UWIN may not be used as a host platform because
-*** linking with posix.dll is not allowed by the GNU GPL" 1>&2; exit 1; }
- ;;
*-*-*vms*)
- # Under VMS, vfork works very different than on Unix. The standard test
+ # Under VMS, vfork works very differently than on Unix. The standard test
# won't work, and it isn't easily adaptable. It makes more sense to
# just force it.
ac_cv_func_vfork_works=yes
;;
esac
-echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:4035: checking for pid_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 4040 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
+echo "$as_me:$LINENO: checking for pid_t" >&5
+echo $ECHO_N "checking for pid_t... $ECHO_C" >&6
+if test "${ac_cv_type_pid_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+if ((pid_t *) 0)
+ return 0;
+if (sizeof (pid_t))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_type_pid_t=yes
else
- rm -rf conftest*
- ac_cv_type_pid_t=no
-fi
-rm -f conftest*
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ac_cv_type_pid_t=no
fi
-echo "$ac_t""$ac_cv_type_pid_t" 1>&6
-if test $ac_cv_type_pid_t = no; then
- cat >> confdefs.h <<\EOF
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
+echo "${ECHO_T}$ac_cv_type_pid_t" >&6
+if test $ac_cv_type_pid_t = yes; then
+ :
+else
+
+cat >>confdefs.h <<_ACEOF
#define pid_t int
-EOF
+_ACEOF
fi
-ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
-echo "configure:4069: checking for vfork.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+
+
+for ac_header in unistd.h vfork.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
else
- cat > conftest.$ac_ext <<EOF
-#line 4074 "configure"
-#include "confdefs.h"
-#include <vfork.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4079: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
+ ac_cpp_err=yes
fi
-rm -f conftest*
+if test -z "$ac_cpp_err"; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ eval "$as_ac_Header=no"
fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define HAVE_VFORK_H 1
-EOF
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
-else
- echo "$ac_t""no" 1>&6
fi
+done
-echo $ac_n "checking for working vfork""... $ac_c" 1>&6
-echo "configure:4104: checking for working vfork" >&5
-if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- echo $ac_n "checking for vfork""... $ac_c" 1>&6
-echo "configure:4110: checking for vfork" >&5
-if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 4115 "configure"
-#include "confdefs.h"
+
+
+for ac_func in fork vfork
+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
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char vfork(); below. */
-#include <assert.h>
+ 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
/* 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 vfork();
-
-int main() {
-
+ 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_vfork) || defined (__stub___vfork)
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
-vfork();
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
#endif
-; return 0; }
-EOF
-if { (eval echo configure:4138: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_vfork=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_vfork=no"
-fi
-rm -f conftest*
+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>&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.$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
-if eval "test \"`echo '$ac_cv_func_'vfork`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- :
+if test "x$ac_cv_func_fork" = xyes; then
+ echo "$as_me:$LINENO: checking for working fork" >&5
+echo $ECHO_N "checking for working fork... $ECHO_C" >&6
+if test "${ac_cv_func_fork_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- echo "$ac_t""no" 1>&6
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_fork_works=cross
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* By Ruediger Kuhlmann. */
+ #include <sys/types.h>
+ #if HAVE_UNISTD_H
+ # include <unistd.h>
+ #endif
+ /* Some systems only have a dummy stub for fork() */
+ int main ()
+ {
+ if (fork() < 0)
+ exit (1);
+ exit (0);
+ }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./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_func_fork_works=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_func_fork_works=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5
+echo "${ECHO_T}$ac_cv_func_fork_works" >&6
+
+else
+ ac_cv_func_fork_works=$ac_cv_func_fork
+fi
+if test "x$ac_cv_func_fork_works" = xcross; then
+ case $host in
+ *-*-amigaos* | *-*-msdosdjgpp*)
+ # Override, as these systems have only a dummy fork() stub
+ ac_cv_func_fork_works=no
+ ;;
+ *)
+ ac_cv_func_fork_works=yes
+ ;;
+ esac
+ { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
+echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
fi
-
ac_cv_func_vfork_works=$ac_cv_func_vfork
+if test "x$ac_cv_func_vfork" = xyes; then
+ echo "$as_me:$LINENO: checking for working vfork" >&5
+echo $ECHO_N "checking for working vfork... $ECHO_C" >&6
+if test "${ac_cv_func_vfork_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftest.$ac_ext <<EOF
-#line 4160 "configure"
-#include "confdefs.h"
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_vfork_works=cross
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
/* Thanks to Paul Eggert for this test. */
#include <stdio.h>
+#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+#include <sys/wait.h>
+#if HAVE_UNISTD_H
+# include <unistd.h>
#endif
-#ifdef HAVE_VFORK_H
-#include <vfork.h>
+#if HAVE_VFORK_H
+# include <vfork.h>
#endif
/* On some sparc systems, changes by the child to local and incoming
- argument registers are propagated back to the parent.
- The compiler is told about this with #include <vfork.h>,
- but some compilers (e.g. gcc -O) don't grok <vfork.h>.
- Test for this by using a static variable whose address
- is put into a register that is clobbered by the vfork. */
-static
+ argument registers are propagated back to the parent. The compiler
+ is told about this with #include <vfork.h>, but some compilers
+ (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a
+ static variable whose address is put into a register that is
+ clobbered by the vfork. */
+static void
#ifdef __cplusplus
sparc_address_test (int arg)
-#else
+# else
sparc_address_test (arg) int arg;
#endif
{
@@ -4195,25 +7341,27 @@ sparc_address_test (arg) int arg;
}
}
}
-main() {
+
+int
+main ()
+{
pid_t parent = getpid ();
pid_t child;
- sparc_address_test ();
+ sparc_address_test (0);
child = vfork ();
if (child == 0) {
- /* Here is another test for sparc vfork register problems.
- This test uses lots of local variables, at least
- as many local variables as main has allocated so far
- including compiler temporaries. 4 locals are enough for
- gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe.
- A buggy compiler should reuse the register of parent
- for one of the local variables, since it will think that
- parent can't possibly be used any more in this routine.
- Assigning to the local variable will thus munge parent
- in the parent process. */
+ /* Here is another test for sparc vfork register problems. This
+ test uses lots of local variables, at least as many local
+ variables as main has allocated so far including compiler
+ temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris
+ 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should
+ reuse the register of parent for one of the local variables,
+ since it will think that parent can't possibly be used any more
+ in this routine. Assigning to the local variable will thus
+ munge parent in the parent process. */
pid_t
p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
@@ -4223,11 +7371,10 @@ main() {
|| p != p5 || p != p6 || p != p7)
_exit(1);
- /* On some systems (e.g. IRIX 3.3),
- vfork doesn't separate parent from child file descriptors.
- If the child closes a descriptor before it execs or exits,
- this munges the parent's descriptor as well.
- Test for this by closing stdout in the child. */
+ /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
+ from child file descriptors. If the child closes a descriptor
+ before it execs or exits, this munges the parent's descriptor
+ as well. Test for this by closing stdout in the child. */
_exit(close(fileno(stdout)) != 0);
} else {
int status;
@@ -4250,115 +7397,245 @@ main() {
);
}
}
-EOF
-if { (eval echo configure:4255: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./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_func_vfork_works=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_func_vfork_works=no
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_func_vfork_works=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
-rm -fr conftest*
fi
+echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5
+echo "${ECHO_T}$ac_cv_func_vfork_works" >&6
+fi;
+if test "x$ac_cv_func_fork_works" = xcross; then
+ ac_cv_func_vfork_works=ac_cv_func_vfork
+ { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
+echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
fi
-echo "$ac_t""$ac_cv_func_vfork_works" 1>&6
-if test $ac_cv_func_vfork_works = no; then
- cat >> confdefs.h <<\EOF
+if test "x$ac_cv_func_vfork_works" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_WORKING_VFORK 1
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
#define vfork fork
-EOF
+_ACEOF
fi
+if test "x$ac_cv_func_fork_works" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_WORKING_FORK 1
+_ACEOF
+
+fi
+
-
am_cv_lib_iconv_ldpath=
- # Check whether --with-libiconv-prefix or --without-libiconv-prefix was given.
+
+# Check whether --with-libiconv-prefix or --without-libiconv-prefix was given.
if test "${with_libiconv_prefix+set}" = set; then
withval="$with_libiconv_prefix"
-
+
for dir in `echo "$withval" | tr : ' '`; do
if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi
if test -d $dir/lib; then am_cv_lib_iconv_ldpath="-L$dir/lib"; fi
done
-
+
+fi;
+
+
+for ac_header in iconv.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 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); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
fi
+if test -z "$ac_cpp_err"; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
- echo $ac_n "checking for iconv""... $ac_c" 1>&6
-echo "configure:4294: checking for iconv" >&5
-if eval "test \"`echo '$''{'am_cv_func_iconv'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+
+ 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
- cat > conftest.$ac_ext <<EOF
-#line 4302 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* 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() {
+int
+main ()
+{
iconv_t cd = iconv_open("","");
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);
-; return 0; }
-EOF
-if { (eval echo configure:4312: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 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 "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
if test "$am_cv_func_iconv" != yes; then
am_save_LIBS="$LIBS"
LIBS="$LIBS $am_cv_libiconv_ldpath -liconv"
- cat > conftest.$ac_ext <<EOF
-#line 4324 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* 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() {
+int
+main ()
+{
iconv_t cd = iconv_open("","");
iconv(cd,NULL,NULL,NULL,NULL);
iconv_close(cd);
-; return 0; }
-EOF
-if { (eval echo configure:4334: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 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 "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS="$am_save_LIBS"
fi
-
-fi
-echo "$ac_t""$am_cv_func_iconv" 1>&6
+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 <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_ICONV 1
-EOF
+_ACEOF
- echo $ac_n "checking for iconv declaration""... $ac_c" 1>&6
-echo "configure:4355: checking for iconv declaration" >&5
- if eval "test \"`echo '$''{'am_cv_proto_iconv'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+ 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 <<EOF
-#line 4361 "configure"
-#include "confdefs.h"
+
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <stdlib.h>
#include <iconv.h>
@@ -4372,36 +7649,110 @@ size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, si
size_t iconv();
#endif
-int main() {
+int
+main ()
+{
-; return 0; }
-EOF
-if { (eval echo configure:4380: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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 "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- am_cv_proto_iconv_arg1="const"
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+am_cv_proto_iconv_arg1="const"
fi
-rm -f conftest*
+rm -f 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 "$ac_t""${ac_t:-
- }$am_cv_proto_iconv" 1>&6
- cat >> confdefs.h <<EOF
+ 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
-EOF
+_ACEOF
fi
LIBICONV=
if test "$am_cv_lib_iconv" = yes; then
LIBICONV="$am_cv_lib_iconv_ldpath -liconv"
fi
-
+
+
+# Until we have in-tree GNU iconv:
+LIBICONV_DEP=
+
+
+
+ echo "$as_me:$LINENO: checking for LC_MESSAGES" >&5
+echo $ECHO_N "checking for LC_MESSAGES... $ECHO_C" >&6
+if test "${am_cv_val_LC_MESSAGES+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <locale.h>
+int
+main ()
+{
+return LC_MESSAGES
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 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_val_LC_MESSAGES=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+am_cv_val_LC_MESSAGES=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $am_cv_val_LC_MESSAGES" >&5
+echo "${ECHO_T}$am_cv_val_LC_MESSAGES" >&6
+ if test $am_cv_val_LC_MESSAGES = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LC_MESSAGES 1
+_ACEOF
+
+ fi
# We will need to find libiberty.h and ansidecl.h
@@ -4409,142 +7760,192 @@ saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -I${srcdir} -I${srcdir}/../include"
for ac_func in getenv atol sbrk abort atof getcwd getwd \
strsignal putc_unlocked fputs_unlocked fwrite_unlocked \
- fprintf_unlocked strstr errno vasprintf \
+ fprintf_unlocked strstr errno snprintf vasprintf \
malloc realloc calloc free basename getopt clock
do
ac_tr_decl=HAVE_DECL_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-echo $ac_n "checking whether $ac_func is declared""... $ac_c" 1>&6
-echo "configure:4418: checking whether $ac_func is declared" >&5
-if eval "test \"`echo '$''{'gcc_cv_have_decl_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 4423 "configure"
-#include "confdefs.h"
+echo "$as_me:$LINENO: checking whether $ac_func is declared" >&5
+echo $ECHO_N "checking whether $ac_func is declared... $ECHO_C" >&6
+if eval "test \"\${gcc_cv_have_decl_$ac_func+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#undef $ac_tr_decl
#define $ac_tr_decl 1
-
+
#include "ansidecl.h"
#include "system.h"
-int main() {
+int
+main ()
+{
#ifndef $ac_func
char *(*pfn) = (char *(*)) $ac_func ;
#endif
-; return 0; }
-EOF
-if { (eval echo configure:4437: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
eval "gcc_cv_have_decl_$ac_func=yes"
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "gcc_cv_have_decl_$ac_func=no"
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "gcc_cv_have_decl_$ac_func=no"
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6 ; cat >> confdefs.h <<EOF
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6 ; cat >>confdefs.h <<_ACEOF
#define $ac_tr_decl 1
-EOF
-
+_ACEOF
+
else
- echo "$ac_t""no" 1>&6 ; cat >> confdefs.h <<EOF
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6 ; cat >>confdefs.h <<_ACEOF
#define $ac_tr_decl 0
-EOF
-
+_ACEOF
+
fi
done
if test x = y ; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_GETENV 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_ATOL 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_SBRK 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_ABORT 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_ATOF 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_GETCWD 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_GETWD 1
-EOF
+_ACEOF
\
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_STRSIGNAL 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_PUTC_UNLOCKED 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_FPUTS_UNLOCKED 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_FWRITE_UNLOCKED 1
-EOF
+_ACEOF
\
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_FPRINTF_UNLOCKED 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_STRSTR 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_ERRNO 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DECL_SNPRINTF 1
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_VASPRINTF 1
-EOF
+_ACEOF
\
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_MALLOC 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_REALLOC 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_CALLOC 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_FREE 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_BASENAME 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_GETOPT 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_CLOCK 1
-EOF
+_ACEOF
fi
for ac_func in getrlimit setrlimit getrusage
do
ac_tr_decl=HAVE_DECL_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-echo $ac_n "checking whether $ac_func is declared""... $ac_c" 1>&6
-echo "configure:4539: checking whether $ac_func is declared" >&5
-if eval "test \"`echo '$''{'gcc_cv_have_decl_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 4544 "configure"
-#include "confdefs.h"
+echo "$as_me:$LINENO: checking whether $ac_func is declared" >&5
+echo $ECHO_N "checking whether $ac_func is declared... $ECHO_C" >&6
+if eval "test \"\${gcc_cv_have_decl_$ac_func+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#undef $ac_tr_decl
#define $ac_tr_decl 1
-
+
#include "ansidecl.h"
#include "system.h"
#ifdef HAVE_SYS_RESOURCE_H
@@ -4552,53 +7953,76 @@ else
#endif
-int main() {
+int
+main ()
+{
#ifndef $ac_func
char *(*pfn) = (char *(*)) $ac_func ;
#endif
-; return 0; }
-EOF
-if { (eval echo configure:4562: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
eval "gcc_cv_have_decl_$ac_func=yes"
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "gcc_cv_have_decl_$ac_func=no"
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "gcc_cv_have_decl_$ac_func=no"
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6 ; cat >> confdefs.h <<EOF
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6 ; cat >>confdefs.h <<_ACEOF
#define $ac_tr_decl 1
-EOF
-
+_ACEOF
+
else
- echo "$ac_t""no" 1>&6 ; cat >> confdefs.h <<EOF
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6 ; cat >>confdefs.h <<_ACEOF
#define $ac_tr_decl 0
-EOF
-
+_ACEOF
+
fi
done
if test x = y ; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_GETRLIMIT 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_SETRLIMIT 1
-EOF
- cat >> confdefs.h <<\EOF
+_ACEOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_GETRUSAGE 1
-EOF
+_ACEOF
fi
-cat > conftest.$ac_ext <<EOF
-#line 4601 "configure"
-#include "confdefs.h"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include "ansidecl.h"
#include "system.h"
@@ -4606,37 +8030,137 @@ cat > conftest.$ac_ext <<EOF
#include <sys/resource.h>
#endif
-int main() {
+int
+main ()
+{
rlim_t l = 0;
-; return 0; }
-EOF
-if { (eval echo configure:4614: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
:
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- cat >> confdefs.h <<\EOF
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+cat >>confdefs.h <<\_ACEOF
#define rlim_t long
-EOF
+_ACEOF
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
-for ac_func in times
+for ac_func in ldgetname
do
ac_tr_decl=HAVE_DECL_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-echo $ac_n "checking whether $ac_func is declared""... $ac_c" 1>&6
-echo "configure:4631: checking whether $ac_func is declared" >&5
-if eval "test \"`echo '$''{'gcc_cv_have_decl_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+echo "$as_me:$LINENO: checking whether $ac_func is declared" >&5
+echo $ECHO_N "checking whether $ac_func is declared... $ECHO_C" >&6
+if eval "test \"\${gcc_cv_have_decl_$ac_func+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#undef $ac_tr_decl
+#define $ac_tr_decl 1
+
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_LDFCN_H
+#include <ldfcn.h>
+#endif
+
+
+int
+main ()
+{
+#ifndef $ac_func
+char *(*pfn) = (char *(*)) $ac_func ;
+#endif
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ eval "gcc_cv_have_decl_$ac_func=yes"
else
- cat > conftest.$ac_ext <<EOF
-#line 4636 "configure"
-#include "confdefs.h"
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "gcc_cv_have_decl_$ac_func=no"
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6 ; cat >>confdefs.h <<_ACEOF
+#define $ac_tr_decl 1
+_ACEOF
+
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6 ; cat >>confdefs.h <<_ACEOF
+#define $ac_tr_decl 0
+_ACEOF
+
+fi
+
+done
+if test x = y ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DECL_LDGETNAME 1
+_ACEOF
+fi
+
+
+for ac_func in times
+do
+ ac_tr_decl=HAVE_DECL_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+echo "$as_me:$LINENO: checking whether $ac_func is declared" >&5
+echo $ECHO_N "checking whether $ac_func is declared... $ECHO_C" >&6
+if eval "test \"\${gcc_cv_have_decl_$ac_func+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#undef $ac_tr_decl
#define $ac_tr_decl 1
-
+
#include "ansidecl.h"
#include "system.h"
#ifdef HAVE_SYS_TIMES_H
@@ -4644,54 +8168,75 @@ else
#endif
-int main() {
+int
+main ()
+{
#ifndef $ac_func
char *(*pfn) = (char *(*)) $ac_func ;
#endif
-; return 0; }
-EOF
-if { (eval echo configure:4654: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
eval "gcc_cv_have_decl_$ac_func=yes"
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "gcc_cv_have_decl_$ac_func=no"
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "gcc_cv_have_decl_$ac_func=no"
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
if eval "test \"`echo '$gcc_cv_have_decl_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6 ; cat >> confdefs.h <<EOF
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6 ; cat >>confdefs.h <<_ACEOF
#define $ac_tr_decl 1
-EOF
-
+_ACEOF
+
else
- echo "$ac_t""no" 1>&6 ; cat >> confdefs.h <<EOF
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6 ; cat >>confdefs.h <<_ACEOF
#define $ac_tr_decl 0
-EOF
-
+_ACEOF
+
fi
done
if test x = y ; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_DECL_TIMES 1
-EOF
+_ACEOF
fi
# More time-related stuff.
-echo $ac_n "checking for struct tms""... $ac_c" 1>&6
-echo "configure:4688: checking for struct tms" >&5
-if eval "test \"`echo '$''{'ac_cv_struct_tms'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
-cat > conftest.$ac_ext <<EOF
-#line 4694 "configure"
-#include "confdefs.h"
+echo "$as_me:$LINENO: checking for struct tms" >&5
+echo $ECHO_N "checking for struct tms... $ECHO_C" >&6
+if test "${ac_cv_struct_tms+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include "ansidecl.h"
#include "system.h"
@@ -4699,121 +8244,238 @@ cat > conftest.$ac_ext <<EOF
#include <sys/times.h>
#endif
-int main() {
+int
+main ()
+{
struct tms tms;
-; return 0; }
-EOF
-if { (eval echo configure:4707: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
ac_cv_struct_tms=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_struct_tms=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_struct_tms=no
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-
-echo "$ac_t""$ac_cv_struct_tms" 1>&6
+echo "$as_me:$LINENO: result: $ac_cv_struct_tms" >&5
+echo "${ECHO_T}$ac_cv_struct_tms" >&6
if test $ac_cv_struct_tms = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_STRUCT_TMS 1
-EOF
+_ACEOF
fi
# use gcc_cv_* here because this doesn't match the behavior of AC_CHECK_TYPE.
# revisit after autoconf 2.50.
-echo $ac_n "checking for clock_t""... $ac_c" 1>&6
-echo "configure:4730: checking for clock_t" >&5
-if eval "test \"`echo '$''{'gcc_cv_type_clock_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
-cat > conftest.$ac_ext <<EOF
-#line 4736 "configure"
-#include "confdefs.h"
+echo "$as_me:$LINENO: checking for clock_t" >&5
+echo $ECHO_N "checking for clock_t... $ECHO_C" >&6
+if test "${gcc_cv_type_clock_t+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include "ansidecl.h"
#include "system.h"
-int main() {
+int
+main ()
+{
clock_t x;
-; return 0; }
-EOF
-if { (eval echo configure:4746: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
gcc_cv_type_clock_t=yes
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- gcc_cv_type_clock_t=no
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gcc_cv_type_clock_t=no
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-
-echo "$ac_t""$gcc_cv_type_clock_t" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_type_clock_t" >&5
+echo "${ECHO_T}$gcc_cv_type_clock_t" >&6
if test $gcc_cv_type_clock_t = yes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_CLOCK_T 1
-EOF
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for uchar" >&5
+echo $ECHO_N "checking for uchar... $ECHO_C" >&6
+if test "${gcc_cv_type_uchar+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#include "ansidecl.h"
+#include "system.h"
+
+int
+main ()
+{
+if ((uchar *)0) return 0;
+ if (sizeof(uchar)) return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
+ ac_cv_type_uchar=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_uchar=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_type_uchar" >&5
+echo "${ECHO_T}$gcc_cv_type_uchar" >&6
+if test $ac_cv_type_uchar = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_UCHAR 1
+_ACEOF
fi
+# Restore CFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
+CFLAGS="$saved_CFLAGS"
+
# Check whether --enable-initfini-array or --disable-initfini-array was given.
if test "${enable_initfini_array+set}" = set; then
enableval="$enable_initfini_array"
- gcc_cv_initfinit_array=$enableval
+
+else
+
+echo "$as_me:$LINENO: checking for .preinit_array/.init_array/.fini_array support" >&5
+echo $ECHO_N "checking for .preinit_array/.init_array/.fini_array support... $ECHO_C" >&6
+if test "${gcc_cv_initfini_array+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- echo $ac_n "checking for .preinit_array/.init_array/.fini_array support""... $ac_c" 1>&6
-echo "configure:4772: checking for .preinit_array/.init_array/.fini_array support" >&5
-if eval "test \"`echo '$''{'gcc_cv_initfinit_array'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+ if test "$cross_compiling" = yes; then
+ gcc_cv_initfini_array=no
else
- cat > conftest.c <<EOF
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
static int x = -1;
int main (void) { return x; }
int foo (void) { x = 0; }
int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;
-EOF
- if { ac_try='${CC-cc} -o conftest conftest.c 1>&AS_MESSAGE_LOG_FD'; { (eval echo configure:4782: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }
- then
- if ./conftest; then
- gcc_cv_initfinit_array=yes
- else
- gcc_cv_initfinit_array=no
- fi
- else
- gcc_cv_initfinit_array=no
- fi
- rm -f conftest*
-fi
-
-echo "$ac_t""$gcc_cv_initfinit_array" 1>&6
-
- if test $gcc_cv_initfinit_array = yes; then
- cat >> confdefs.h <<\EOF
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./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
+ gcc_cv_initfini_array=yes
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+gcc_cv_initfini_array=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_initfini_array" >&5
+echo "${ECHO_T}$gcc_cv_initfini_array" >&6
+ enable_initfini_array=$gcc_cv_initfini_array
+
+fi;
+if test $enable_initfini_array = yes; then
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_INITFINI_ARRAY 1
-EOF
+_ACEOF
- fi
fi
-
-# Restore CFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
-CFLAGS="$saved_CFLAGS"
-
-# mkdir takes a single argument on some systems.
-echo $ac_n "checking if mkdir takes one argument""... $ac_c" 1>&6
-echo "configure:4811: checking if mkdir takes one argument" >&5
-if eval "test \"`echo '$''{'gcc_cv_mkdir_takes_one_arg'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+# mkdir takes a single argument on some systems.
+echo "$as_me:$LINENO: checking if mkdir takes one argument" >&5
+echo $ECHO_N "checking if mkdir takes one argument... $ECHO_C" >&6
+if test "${gcc_cv_mkdir_takes_one_arg+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat > conftest.$ac_ext <<EOF
-#line 4816 "configure"
-#include "confdefs.h"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
@@ -4825,27 +8487,42 @@ else
#ifdef HAVE_DIRECT_H
# include <direct.h>
#endif
-int main() {
+int
+main ()
+{
mkdir ("foo", 0);
-; return 0; }
-EOF
-if { (eval echo configure:4833: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 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
gcc_cv_mkdir_takes_one_arg=no
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- gcc_cv_mkdir_takes_one_arg=yes
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gcc_cv_mkdir_takes_one_arg=yes
fi
-rm -f conftest*
+rm -f conftest.$ac_objext conftest.$ac_ext
fi
-
-echo "$ac_t""$gcc_cv_mkdir_takes_one_arg" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_mkdir_takes_one_arg" >&5
+echo "${ECHO_T}$gcc_cv_mkdir_takes_one_arg" >&6
if test $gcc_cv_mkdir_takes_one_arg = yes ; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define MKDIR_TAKES_ONE_ARG 1
-EOF
+_ACEOF
fi
@@ -4861,50 +8538,71 @@ objext='.o'
if test "${enable_sjlj_exceptions+set}" = set; then
enableval="$enable_sjlj_exceptions"
sjlj=`if test $enableval = yes; then echo 1; else echo 0; fi`
-cat >> confdefs.h <<EOF
-#define CONFIG_SJLJ_EXCEPTIONS $sjlj
-EOF
-fi
+cat >>confdefs.h <<_ACEOF
+#define CONFIG_SJLJ_EXCEPTIONS $sjlj
+_ACEOF
+fi;
-echo $ac_n "checking for main in -lunwind""... $ac_c" 1>&6
-echo "configure:4873: checking for main in -lunwind" >&5
-ac_lib_var=`echo unwind'_'main | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+if test x$host = x$target; then
+ echo "$as_me:$LINENO: checking for main in -lunwind" >&5
+echo $ECHO_N "checking for main in -lunwind... $ECHO_C" >&6
+if test "${ac_cv_lib_unwind_main+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
else
- ac_save_LIBS="$LIBS"
+ ac_check_lib_save_LIBS=$LIBS
LIBS="-lunwind $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 4881 "configure"
-#include "confdefs.h"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
-int main() {
-main()
-; return 0; }
-EOF
-if { (eval echo configure:4888: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
+int
+main ()
+{
+main ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 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_unwind_main=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_unwind_main=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_unwind_main" >&5
+echo "${ECHO_T}$ac_cv_lib_unwind_main" >&6
+if test $ac_cv_lib_unwind_main = yes; then
use_libunwind_default=yes
else
- echo "$ac_t""no" 1>&6
-use_libunwind_default=no
+ use_libunwind_default=no
fi
+else
+ use_libunwind_default=no
+fi
# Use libunwind based exception handling.
# Check whether --enable-libunwind-exceptions or --disable-libunwind-exceptions was given.
if test "${enable_libunwind_exceptions+set}" = set; then
@@ -4912,35 +8610,32 @@ if test "${enable_libunwind_exceptions+set}" = set; then
use_libunwind_exceptions=$enableval
else
use_libunwind_exceptions=$use_libunwind_default
-fi
-
+fi;
if test x"$use_libunwind_exceptions" = xyes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define USE_LIBUNWIND_EXCEPTIONS 1
-EOF
+_ACEOF
fi
+# --------------------------------------------------------
+# Build, host, and target specific configuration fragments
+# --------------------------------------------------------
+
+# Collect build-machine-specific information.
+. ${srcdir}/config.build
+
+# Collect host-machine-specific information.
+. ${srcdir}/config.host
+
target_gtfiles=
-build_xm_file=
-build_xm_defines=
-build_install_headers_dir=install-headers-tar
-build_exeext=
-host_xm_file=
-host_xm_defines=
-host_xmake_file=
-host_truncate_target=
-host_exeext=
-
-# Decode the host machine, then the target machine.
-# For the host machine, we save the xm_file variable as host_xm_file;
-# then we decode the target machine and forget everything else
-# that came from the host machine.
-for machine in $build $host $target; do
- . ${srcdir}/config.gcc
-done
+
+# Collect target-machine-specific information.
+. ${srcdir}/config.gcc
extra_objs="${host_extra_objs} ${extra_objs}"
+extra_gcc_objs="${host_extra_gcc_objs} ${extra_gcc_objs}"
# Default the target-machine variables that were not explicitly set.
if test x"$tm_file" = x
@@ -4974,7 +8669,8 @@ bx=
for x in $build_xm_file; do
if test -f $srcdir/config/$x
then bx="$bx $x"
- else echo "configure: warning: $srcdir/config/$x does not exist." 1>&2
+ else { echo "$as_me:$LINENO: WARNING: $srcdir/config/$x does not exist." >&5
+echo "$as_me: WARNING: $srcdir/config/$x does not exist." >&2;}
fi
done
build_xm_file="$bx"
@@ -4983,7 +8679,8 @@ hx=
for x in $host_xm_file; do
if test -f $srcdir/config/$x
then hx="$hx $x"
- else echo "configure: warning: $srcdir/config/$x does not exist." 1>&2
+ else { echo "$as_me:$LINENO: WARNING: $srcdir/config/$x does not exist." >&5
+echo "$as_me: WARNING: $srcdir/config/$x does not exist." >&2;}
fi
done
host_xm_file="$hx"
@@ -4992,7 +8689,8 @@ tx=
for x in $xm_file; do
if test -f $srcdir/config/$x
then tx="$tx $x"
- else echo "configure: warning: $srcdir/config/$x does not exist." 1>&2
+ else { echo "$as_me:$LINENO: WARNING: $srcdir/config/$x does not exist." >&5
+echo "$as_me: WARNING: $srcdir/config/$x does not exist." >&2;}
fi
done
xm_file="$tx"
@@ -5010,6 +8708,14 @@ else
done
fi
+if test x$need_64bit_hwint = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define NEED_64BIT_HOST_WIDE_INT 1
+_ACEOF
+
+fi
+
count=a
for f in $host_xm_file; do
count=${count}x
@@ -5024,6 +8730,7 @@ else
echo " $srcdir/config/$f"
done
fi
+echo "Using ${out_host_hook_obj} for host machine hooks."
if test "$host_xm_file" != "$build_xm_file"; then
count=a
@@ -5042,32 +8749,133 @@ if test "$host_xm_file" != "$build_xm_file"; then
fi
fi
-if test x$thread_file = x; then
- if test x$target_thread_file != x; then
- thread_file=$target_thread_file
- else
- thread_file='single'
- fi
+# Check if a valid thread package
+case ${enable_threads_flag} in
+ "" | no)
+ # No threads
+ target_thread_file='single'
+ ;;
+ yes)
+ # default
+ target_thread_file='single'
+ ;;
+ aix | dce | gnat | irix | posix | rtems | \
+ single | solaris | vxworks | win32 )
+ target_thread_file=${enable_threads_flag}
+ ;;
+ *)
+ echo "${enable_threads_flag} is an unknown thread package" 1>&2
+ exit 1
+ ;;
+esac
+
+if test x${thread_file} = x; then
+ # No thread file set by target-specific clauses in config.gcc,
+ # so use file chosen by default logic above
+ thread_file=${target_thread_file}
+fi
+
+if test x$enable___cxa_atexit = xyes || \
+ test x$enable___cxa_atexit = x -a x$default_use_cxa_atexit = xyes; then
+ echo "$as_me:$LINENO: checking for __cxa_atexit" >&5
+echo $ECHO_N "checking for __cxa_atexit... $ECHO_C" >&6
+if test "${ac_cv_func___cxa_atexit+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char __cxa_atexit (); 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
+/* 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 __cxa_atexit ();
+/* 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___cxa_atexit) || defined (__stub_____cxa_atexit)
+choke me
+#else
+char (*f) () = __cxa_atexit;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != __cxa_atexit;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 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_func___cxa_atexit=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func___cxa_atexit=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func___cxa_atexit" >&5
+echo "${ECHO_T}$ac_cv_func___cxa_atexit" >&6
+if test $ac_cv_func___cxa_atexit = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define DEFAULT_USE_CXA_ATEXIT 1
+_ACEOF
+
+else
+ echo "__cxa_atexit can't be enabled on this target"
+fi
+
fi
# Look for a file containing extra machine modes.
if test -n "$extra_modes" && test -f $srcdir/config/$extra_modes; then
extra_modes_file='$(srcdir)'/config/${extra_modes}
-
- cat >> confdefs.h <<EOF
-#define EXTRA_MODES_FILE "$extra_modes"
-EOF
- cat >> confdefs.h <<\EOF
-#define EXTRA_CC_MODES 1
-EOF
+
+cat >>confdefs.h <<_ACEOF
+#define EXTRA_MODES_FILE "config/$extra_modes"
+_ACEOF
fi
# auto-host.h is the file containing items generated by autoconf and is
# the first file included by config.h.
-# If host=build, it is correct to have hconfig include auto-host.h
-# as well. If host!=build, we are in error and need to do more
+# If host=build, it is correct to have bconfig include auto-host.h
+# as well. If host!=build, we are in error and need to do more
# work to find out the build config parameters.
if test x$host = x$build
then
@@ -5077,7 +8885,7 @@ else
# We create a subdir, then run autoconf in the subdir.
# To prevent recursion we set host and build for the new
# invocation of configure to the build for this invocation
- # of configure.
+ # of configure.
tempdir=build.$$
rm -rf $tempdir
mkdir $tempdir
@@ -5098,19 +8906,21 @@ else
cd ..
rm -rf $tempdir
build_auto=auto-build.h
- FORBUILD=../$build_alias
+ FORBUILD=../${build_subdir}
fi
tm_file="${tm_file} defaults.h"
-host_xm_file="auto-host.h ansidecl.h ${host_xm_file} ${tm_file}"
-build_xm_file="${build_auto} ansidecl.h ${build_xm_file} ${tm_file}"
-xm_file="ansidecl.h ${xm_file} ${tm_file}"
+tm_p_file="${tm_p_file} tm-preds.h"
+host_xm_file="auto-host.h ansidecl.h ${host_xm_file}"
+build_xm_file="${build_auto} ansidecl.h ${build_xm_file}"
+# We don't want ansidecl.h in target files, write code there in ISO/GNU C.
+# put this back in temporarily.
+xm_file="ansidecl.h ${xm_file}"
-# Truncate the target if necessary
-if test x$host_truncate_target != x; then
- target=`echo $target | sed -e 's/\(..............\).*/\1/'`
-fi
+# --------
+# UNSORTED
+# --------
# Get the version trigger filename from the toplevel
if test "${with_gcc_version_trigger+set}" = set; then
@@ -5129,10 +8939,23 @@ if test -f configargs.h ; then
else
gcc_config_arguments="$TOPLEVEL_CONFIGURE_ARGUMENTS"
fi
+
+# Double all backslashes and backslash all quotes to turn
+# gcc_config_arguments into a C string.
+sed -e 's/\\/\\\\/g; s/"/\\"/g' <<EOF >conftest.out
+$gcc_config_arguments
+EOF
+gcc_config_arguments_str=`cat conftest.out`
+rm -f conftest.out
+
cat > configargs.h <<EOF
/* Generated automatically. */
-static const char configuration_arguments[] = "$gcc_config_arguments";
+static const char configuration_arguments[] = "$gcc_config_arguments_str";
static const char thread_model[] = "$thread_file";
+
+static const struct {
+ const char *name, *value;
+} configure_default_options[] = $configure_default_options;
EOF
# Internationalization
@@ -5141,1480 +8964,201 @@ VERSION="$gcc_version"
-# Enable NLS support by default
-# Check whether --enable-nls or --disable-nls was given.
-if test "${enable_nls+set}" = set; then
- enableval="$enable_nls"
- :
-else
- enable_nls=yes
+# If we haven't got the data from the intl directory,
+# assume NLS is disabled.
+USE_NLS=no
+LIBINTL=
+LIBINTL_DEP=
+INCINTL=
+XGETTEXT=
+GMSGFMT=
+POSUB=
+if test -f ../intl/config.intl; then
+ . ../intl/config.intl
fi
-
-
-# if cross compiling, disable NLS support.
-# It's not worth the trouble, at least for now.
-
-if test "${build}" != "${host}" && test "x$enable_nls" = "xyes"; then
- echo "configure: warning: Disabling NLS support for canadian cross compiler." 1>&2
- enable_nls=no
-fi
-
-
-
-echo $ac_n "checking for library containing strerror""... $ac_c" 1>&6
-echo "configure:5166: checking for library containing strerror" >&5
-if eval "test \"`echo '$''{'ac_cv_search_strerror'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_func_search_save_LIBS="$LIBS"
-ac_cv_search_strerror="no"
-cat > conftest.$ac_ext <<EOF
-#line 5173 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char strerror();
-
-int main() {
-strerror()
-; return 0; }
-EOF
-if { (eval echo configure:5184: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- ac_cv_search_strerror="none required"
+echo "$as_me:$LINENO: checking whether NLS is requested" >&5
+echo $ECHO_N "checking whether NLS is requested... $ECHO_C" >&6
+if test x"$USE_NLS" != xyes; then
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
-test "$ac_cv_search_strerror" = "no" && for i in cposix; do
-LIBS="-l$i $ac_func_search_save_LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 5195 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char strerror();
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
-int main() {
-strerror()
-; return 0; }
-EOF
-if { (eval echo configure:5206: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- ac_cv_search_strerror="-l$i"
-break
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
-done
-LIBS="$ac_func_search_save_LIBS"
-fi
-
-echo "$ac_t""$ac_cv_search_strerror" 1>&6
-if test "$ac_cv_search_strerror" != "no"; then
- test "$ac_cv_search_strerror" = "none required" || LIBS="$ac_cv_search_strerror $LIBS"
-
-else :
-
-fi
-
-
-echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:5229: checking for working const" >&5
-if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5234 "configure"
-#include "confdefs.h"
-
-int main() {
-
-/* Ultrix mips cc rejects this. */
-typedef int charset[2]; const charset x;
-/* SunOS 4.1.1 cc rejects this. */
-char const *const *ccp;
-char **p;
-/* NEC SVR4.0.2 mips cc rejects this. */
-struct point {int x, y;};
-static struct point const zero = {0,0};
-/* AIX XL C 1.02.0.0 rejects this.
- It does not let you subtract one const X* pointer from another in an arm
- of an if-expression whose if-part is not a constant expression */
-const char *g = "string";
-ccp = &g + (g ? g-g : 0);
-/* HPUX 7.0 cc rejects these. */
-++ccp;
-p = (char**) ccp;
-ccp = (char const *const *) p;
-{ /* SCO 3.2v4 cc rejects this. */
- char *t;
- char const *s = 0 ? (char *) 0 : (char const *) 0;
-
- *t++ = 0;
-}
-{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
- int x[] = {25, 17};
- const int *foo = &x[0];
- ++foo;
-}
-{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
- typedef const int *iptr;
- iptr p = 0;
- ++p;
-}
-{ /* AIX XL C 1.02.0.0 rejects this saying
- "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
- struct s { int j; const int *ap[3]; };
- struct s *b; b->j = 5;
-}
-{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
- const int foo = 10;
-}
-
-; return 0; }
-EOF
-if { (eval echo configure:5283: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_c_const=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_c_const=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_c_const" 1>&6
-if test $ac_cv_c_const = no; then
- cat >> confdefs.h <<\EOF
-#define const
-EOF
-
-fi
-
-echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:5304: checking for off_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5309 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_off_t=yes
-else
- rm -rf conftest*
- ac_cv_type_off_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_off_t" 1>&6
-if test $ac_cv_type_off_t = no; then
- cat >> confdefs.h <<\EOF
-#define off_t long
-EOF
-
-fi
-
-echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:5337: checking for size_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5342 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_size_t=yes
-else
- rm -rf conftest*
- ac_cv_type_size_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_size_t" 1>&6
-if test $ac_cv_type_size_t = no; then
- cat >> confdefs.h <<\EOF
-#define size_t unsigned
-EOF
-
-fi
-
-# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
-# for constant arguments. Useless!
-echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:5372: checking for working alloca.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5377 "configure"
-#include "confdefs.h"
-#include <alloca.h>
-int main() {
-char *p = alloca(2 * sizeof(int));
-; return 0; }
-EOF
-if { (eval echo configure:5384: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- ac_cv_header_alloca_h=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_alloca_h=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
-if test $ac_cv_header_alloca_h = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_ALLOCA_H 1
-EOF
-
-fi
-
-echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:5405: checking for alloca" >&5
-if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5410 "configure"
-#include "confdefs.h"
-
-#ifdef __GNUC__
-# define alloca __builtin_alloca
-#else
-# ifdef _MSC_VER
-# include <malloc.h>
-# define alloca _alloca
-# else
-# if HAVE_ALLOCA_H
-# include <alloca.h>
-# else
-# ifdef _AIX
- #pragma alloca
-# else
-# ifndef alloca /* predefined by HP cc +Olibcalls */
-char *alloca ();
-# endif
-# endif
-# endif
-# endif
-#endif
-
-int main() {
-char *p = (char *) alloca(1);
-; return 0; }
-EOF
-if { (eval echo configure:5438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- ac_cv_func_alloca_works=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_func_alloca_works=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
-if test $ac_cv_func_alloca_works = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_ALLOCA 1
-EOF
-
-fi
-
-if test $ac_cv_func_alloca_works = no; then
- # The SVR3 libPW and SVR4 libucb both contain incompatible functions
- # that cause trouble. Some versions do not even contain alloca or
- # contain a buggy version. If you still want to use their alloca,
- # use ar to extract alloca.o from them instead of compiling alloca.c.
- ALLOCA=alloca.${ac_objext}
- cat >> confdefs.h <<\EOF
-#define C_ALLOCA 1
-EOF
-
-
-echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:5470: checking whether alloca needs Cray hooks" >&5
-if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5475 "configure"
-#include "confdefs.h"
-#if defined(CRAY) && ! defined(CRAY2)
-webecray
-#else
-wenotbecray
-#endif
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "webecray" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_os_cray=yes
-else
- rm -rf conftest*
- ac_cv_os_cray=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$ac_cv_os_cray" 1>&6
-if test $ac_cv_os_cray = yes; then
-for ac_func in _getb67 GETB67 getb67; do
- echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5500: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5505 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* 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();
-
-int main() {
-
-/* 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
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:5528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<EOF
-#define CRAY_STACKSEG_END $ac_func
-EOF
-
- break
-else
- echo "$ac_t""no" 1>&6
-fi
-
-done
-fi
-
-echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:5555: checking stack direction for C alloca" >&5
-if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test "$cross_compiling" = yes; then
- ac_cv_c_stack_direction=0
-else
- cat > conftest.$ac_ext <<EOF
-#line 5563 "configure"
-#include "confdefs.h"
-find_stack_direction ()
-{
- static char *addr = 0;
- auto char dummy;
- if (addr == 0)
- {
- addr = &dummy;
- return find_stack_direction ();
- }
- else
- return (&dummy > addr) ? 1 : -1;
-}
-main ()
-{
- exit (find_stack_direction() < 0);
-}
-EOF
-if { (eval echo configure:5582: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
-then
- ac_cv_c_stack_direction=1
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- ac_cv_c_stack_direction=-1
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
-cat >> confdefs.h <<EOF
-#define STACK_DIRECTION $ac_cv_c_stack_direction
-EOF
-
-fi
-
-
- echo $ac_n "checking whether we are using the GNU C Library 2.1 or newer""... $ac_c" 1>&6
-echo "configure:5605: checking whether we are using the GNU C Library 2.1 or newer" >&5
-if eval "test \"`echo '$''{'ac_cv_gnu_library_2_1'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5610 "configure"
-#include "confdefs.h"
-
-#include <features.h>
-#ifdef __GNU_LIBRARY__
- #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)
- Lucky GNU user
- #endif
-#endif
-
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "Lucky GNU user" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_gnu_library_2_1=yes
-else
- rm -rf conftest*
- ac_cv_gnu_library_2_1=no
-fi
-rm -f conftest*
-
-
-
-fi
-
-echo "$ac_t""$ac_cv_gnu_library_2_1" 1>&6
-
- GLIBC21="$ac_cv_gnu_library_2_1"
-
-
-
- for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h stddef.h \
-stdlib.h string.h unistd.h sys/param.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:5646: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5651 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5656: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
- for ac_func in feof_unlocked fgets_unlocked getcwd getegid geteuid \
-getgid getuid mempcpy munmap putenv setenv setlocale stpcpy strchr strcasecmp \
-strdup strtoul tsearch __argz_count __argz_stringify __argz_next
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5687: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5692 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* 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();
-
-int main() {
-
-/* 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
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:5715: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-
-
- am_cv_lib_iconv_ldpath=
- # Check whether --with-libiconv-prefix or --without-libiconv-prefix was given.
-if test "${with_libiconv_prefix+set}" = set; then
- withval="$with_libiconv_prefix"
-
- for dir in `echo "$withval" | tr : ' '`; do
- if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi
- if test -d $dir/lib; then am_cv_lib_iconv_ldpath="-L$dir/lib"; fi
- done
-
-fi
-
-
- echo $ac_n "checking for iconv""... $ac_c" 1>&6
-echo "configure:5756: checking for iconv" >&5
-if eval "test \"`echo '$''{'am_cv_func_iconv'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- am_cv_func_iconv="no, consider installing GNU libiconv"
- am_cv_lib_iconv=no
- cat > conftest.$ac_ext <<EOF
-#line 5764 "configure"
-#include "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; }
-EOF
-if { (eval echo configure:5774: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- am_cv_func_iconv=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- if test "$am_cv_func_iconv" != yes; then
- am_save_LIBS="$LIBS"
- LIBS="$LIBS $am_cv_libiconv_ldpath -liconv"
- cat > conftest.$ac_ext <<EOF
-#line 5786 "configure"
-#include "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; }
-EOF
-if { (eval echo configure:5796: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- am_cv_lib_iconv=yes
- am_cv_func_iconv=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- LIBS="$am_save_LIBS"
- fi
-
-fi
-
-echo "$ac_t""$am_cv_func_iconv" 1>&6
- if test "$am_cv_func_iconv" = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_ICONV 1
-EOF
-
- echo $ac_n "checking for iconv declaration""... $ac_c" 1>&6
-echo "configure:5817: checking for iconv declaration" >&5
- if eval "test \"`echo '$''{'am_cv_proto_iconv'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- cat > conftest.$ac_ext <<EOF
-#line 5823 "configure"
-#include "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; }
-EOF
-if { (eval echo configure:5842: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- am_cv_proto_iconv_arg1=""
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- am_cv_proto_iconv_arg1="const"
-fi
-rm -f conftest*
- 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 "$ac_t""${ac_t:-
- }$am_cv_proto_iconv" 1>&6
- cat >> confdefs.h <<EOF
-#define ICONV_CONST $am_cv_proto_iconv_arg1
-EOF
-
- fi
- LIBICONV=
- if test "$am_cv_lib_iconv" = yes; then
- LIBICONV="$am_cv_lib_iconv_ldpath -liconv"
- fi
-
-
-
- echo $ac_n "checking for nl_langinfo and CODESET""... $ac_c" 1>&6
-echo "configure:5871: checking for nl_langinfo and CODESET" >&5
-if eval "test \"`echo '$''{'am_cv_langinfo_codeset'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5876 "configure"
-#include "confdefs.h"
-#include <langinfo.h>
-int main() {
-char* cs = nl_langinfo(CODESET);
-; return 0; }
-EOF
-if { (eval echo configure:5883: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- am_cv_langinfo_codeset=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- am_cv_langinfo_codeset=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$am_cv_langinfo_codeset" 1>&6
- if test $am_cv_langinfo_codeset = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_LANGINFO_CODESET 1
-EOF
-
- fi
-
- if test $ac_cv_header_locale_h = yes; then
- echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
-echo "configure:5906: checking for LC_MESSAGES" >&5
-if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5911 "configure"
-#include "confdefs.h"
-#include <locale.h>
-int main() {
-return LC_MESSAGES
-; return 0; }
-EOF
-if { (eval echo configure:5918: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- am_cv_val_LC_MESSAGES=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- am_cv_val_LC_MESSAGES=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6
- if test $am_cv_val_LC_MESSAGES = yes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_LC_MESSAGES 1
-EOF
-
- fi
- fi
- echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
-echo "configure:5939: checking whether NLS is requested" >&5
- # Check whether --enable-nls or --disable-nls was given.
-if test "${enable_nls+set}" = set; then
- enableval="$enable_nls"
- USE_NLS=$enableval
-else
- USE_NLS=yes
-fi
-
- echo "$ac_t""$USE_NLS" 1>&6
-
-
- BUILD_INCLUDED_LIBINTL=no
- USE_INCLUDED_LIBINTL=no
- INTLLIBS=
- INTLDEPS=
-
- if test "$USE_NLS" = "yes"; then
- cat >> confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
#define ENABLE_NLS 1
-EOF
-
- echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
-echo "configure:5962: checking whether included gettext is requested" >&5
- # Check whether --with-included-gettext or --without-included-gettext was given.
-if test "${with_included_gettext+set}" = set; then
- withval="$with_included_gettext"
- nls_cv_force_use_gnu_gettext=$withval
-else
- nls_cv_force_use_gnu_gettext=no
-fi
-
- echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
-
- nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
- if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
- CATOBJEXT=NONE
-
-
-
-
- ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
-echo "configure:5982: checking for libintl.h" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 5987 "configure"
-#include "confdefs.h"
-#include <libintl.h>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5992: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define HAVE_LIBINTL_H 1
-EOF
-
- echo $ac_n "checking for GNU gettext in libc""... $ac_c" 1>&6
-echo "configure:6013: checking for GNU gettext in libc" >&5
-if eval "test \"`echo '$''{'gt_cv_func_gnugettext1_libc'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 6018 "configure"
-#include "confdefs.h"
-#include <libintl.h>
-extern int _nl_msg_cat_cntr;
-int main() {
-bindtextdomain ("", "");
-return (int) gettext ("") + _nl_msg_cat_cntr
-; return 0; }
-EOF
-if { (eval echo configure:6027: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- gt_cv_func_gnugettext1_libc=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- gt_cv_func_gnugettext1_libc=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$gt_cv_func_gnugettext1_libc" 1>&6
-
- if test "$gt_cv_func_gnugettext1_libc" != "yes"; then
- echo $ac_n "checking for GNU gettext in libintl""... $ac_c" 1>&6
-echo "configure:6043: checking for GNU gettext in libintl" >&5
-if eval "test \"`echo '$''{'gt_cv_func_gnugettext1_libintl'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- gt_save_LIBS="$LIBS"
- LIBS="$LIBS -lintl $LIBICONV"
- cat > conftest.$ac_ext <<EOF
-#line 6050 "configure"
-#include "confdefs.h"
-#include <libintl.h>
-extern int _nl_msg_cat_cntr;
-int main() {
-bindtextdomain ("", "");
-return (int) gettext ("") + _nl_msg_cat_cntr
-; return 0; }
-EOF
-if { (eval echo configure:6059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- gt_cv_func_gnugettext1_libintl=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- gt_cv_func_gnugettext1_libintl=no
-fi
-rm -f conftest*
- LIBS="$gt_save_LIBS"
-fi
-
-echo "$ac_t""$gt_cv_func_gnugettext1_libintl" 1>&6
- fi
-
- if test "$gt_cv_func_gnugettext1_libc" = "yes" \
- || { test "$gt_cv_func_gnugettext1_libintl" = "yes" \
- && test "$PACKAGE" != gettext; }; then
- cat >> confdefs.h <<\EOF
-#define HAVE_GETTEXT 1
-EOF
-
-
- if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then
- INTLLIBS="-lintl $LIBICONV"
- fi
-
- gt_save_LIBS="$LIBS"
- LIBS="$LIBS $INTLLIBS"
- for ac_func in dcgettext
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6092: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 6097 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* 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();
-
-int main() {
-
-/* 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
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:6120: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
- LIBS="$gt_save_LIBS"
-
- # Extract the first word of "msgfmt", so it can be a program name with args.
-set dummy msgfmt; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6149: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- case "$MSGFMT" in
- /*)
- ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
- ;;
- *)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if $ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1; then
- ac_cv_path_MSGFMT="$ac_dir/$ac_word"
- break
- fi
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":"
- ;;
-esac
-fi
-MSGFMT="$ac_cv_path_MSGFMT"
-if test "$MSGFMT" != ":"; then
- echo "$ac_t""$MSGFMT" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
- # Extract the first word of "gmsgfmt", so it can be a program name with args.
-set dummy gmsgfmt; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6183: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- case "$GMSGFMT" in
- /*)
- ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
- ;;
- ?:/*)
- ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
- ;;
- *)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
- break
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
- ;;
-esac
-fi
-GMSGFMT="$ac_cv_path_GMSGFMT"
-if test -n "$GMSGFMT"; then
- echo "$ac_t""$GMSGFMT" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
- # Extract the first word of "xgettext", so it can be a program name with args.
-set dummy xgettext; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6220: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- case "$XGETTEXT" in
- /*)
- ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
- ;;
- *)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if $ac_dir/$ac_word --omit-header /dev/null >/dev/null 2>&1; then
- ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
- break
- fi
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
- ;;
-esac
-fi
-XGETTEXT="$ac_cv_path_XGETTEXT"
-if test "$XGETTEXT" != ":"; then
- echo "$ac_t""$XGETTEXT" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
- CATOBJEXT=.gmo
- fi
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
- if test "$CATOBJEXT" = "NONE"; then
- nls_cv_use_gnu_gettext=yes
- fi
- fi
-
- if test "$nls_cv_use_gnu_gettext" = "yes"; then
- INTLOBJS="\$(GETTOBJS)"
- # Extract the first word of "msgfmt", so it can be a program name with args.
-set dummy msgfmt; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6270: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- case "$MSGFMT" in
- /*)
- ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
- ;;
- *)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if $ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1; then
- ac_cv_path_MSGFMT="$ac_dir/$ac_word"
- break
- fi
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":"
- ;;
-esac
-fi
-MSGFMT="$ac_cv_path_MSGFMT"
-if test "$MSGFMT" != ":"; then
- echo "$ac_t""$MSGFMT" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
- # Extract the first word of "gmsgfmt", so it can be a program name with args.
-set dummy gmsgfmt; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6304: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- case "$GMSGFMT" in
- /*)
- ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
- ;;
- ?:/*)
- ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
- ;;
- *)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
- break
+_ACEOF
+
+
+ echo "$as_me:$LINENO: checking for catalogs to be installed" >&5
+echo $ECHO_N "checking for catalogs to be installed... $ECHO_C" >&6
+ # Look for .po and .gmo files in the source directory.
+ CATALOGS=
+ XLINGUAS=
+ for cat in $srcdir/po/*.gmo $srcdir/po/*.po; do
+ # If there aren't any .gmo files the shell will give us the
+ # literal string "../path/to/srcdir/po/*.gmo" which has to be
+ # weeded out.
+ case "$cat" in *\**)
+ continue;;
+ esac
+ # The quadruple backslash is collapsed to a double backslash
+ # by the backticks, then collapsed again by the double quotes,
+ # leaving us with one backslash in the sed expression (right
+ # before the dot that mustn't act as a wildcard).
+ cat=`echo $cat | sed -e "s!$srcdir/!!" -e "s!\\\\.po!.gmo!"`
+ lang=`echo $cat | sed -e 's!po/!!' -e "s!\\\\.gmo!!"`
+ # The user is allowed to set LINGUAS to a list of languages to
+ # install catalogs for. If it's empty that means "all of them."
+ if test "x$LINGUAS" = x; then
+ CATALOGS="$CATALOGS $cat"
+ XLINGUAS="$XLINGUAS $lang"
+ else
+ case "$LINGUAS" in *$lang*)
+ CATALOGS="$CATALOGS $cat"
+ XLINGUAS="$XLINGUAS $lang"
+ ;;
+ esac
fi
done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
- ;;
-esac
-fi
-GMSGFMT="$ac_cv_path_GMSGFMT"
-if test -n "$GMSGFMT"; then
- echo "$ac_t""$GMSGFMT" 1>&6
-else
- echo "$ac_t""no" 1>&6
+ LINGUAS="$XLINGUAS"
+ echo "$as_me:$LINENO: result: $LINGUAS" >&5
+echo "${ECHO_T}$LINGUAS" >&6
fi
- # Extract the first word of "xgettext", so it can be a program name with args.
-set dummy xgettext; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6340: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- case "$XGETTEXT" in
- /*)
- ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
- ;;
- *)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- if $ac_dir/$ac_word --omit-header /dev/null >/dev/null 2>&1; then
- ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
- break
- fi
- fi
- done
- IFS="$ac_save_ifs"
- test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
- ;;
+# If LIBINTL contains LIBICONV, then clear LIBICONV so we don't get
+# -liconv on the link line twice.
+case "$LIBINTL" in *$LIBICONV*)
+ LIBICONV= ;;
esac
-fi
-XGETTEXT="$ac_cv_path_XGETTEXT"
-if test "$XGETTEXT" != ":"; then
- echo "$ac_t""$XGETTEXT" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
- BUILD_INCLUDED_LIBINTL=yes
- USE_INCLUDED_LIBINTL=yes
- CATOBJEXT=.gmo
- INTLLIBS="\$(top_builddir)/intl/libintl.a $LIBICONV"
- INTLDEPS="\$(top_builddir)/intl/libintl.a"
- LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
- fi
-
- if test "$GMSGFMT" != ":"; then
- if $GMSGFMT --statistics /dev/null >/dev/null 2>&1; then
- : ;
- else
- echo "$ac_t""found msgfmt program is not GNU msgfmt; ignore it" 1>&6
- GMSGFMT=":"
- fi
- fi
-
- if test "$XGETTEXT" != ":"; then
- if $XGETTEXT --omit-header /dev/null >/dev/null 2>&1; then
- : ;
- else
- echo "$ac_t""found xgettext program is not GNU xgettext; ignore it" 1>&6
- XGETTEXT=":"
- fi
- fi
-
- POSUB=po
- fi
-
-
-
- if test "$PACKAGE" = gettext; then
- BUILD_INCLUDED_LIBINTL=yes
- fi
-
- for ac_prog in bison
-do
-# Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:6412: checking for $ac_word" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_INTLBISON'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- if test -n "$INTLBISON"; then
- ac_cv_prog_INTLBISON="$INTLBISON" # Let the user override the test.
-else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
- ac_dummy="$PATH"
- for ac_dir in $ac_dummy; do
- test -z "$ac_dir" && ac_dir=.
- if test -f $ac_dir/$ac_word; then
- ac_cv_prog_INTLBISON="$ac_prog"
- break
- fi
- done
- IFS="$ac_save_ifs"
-fi
-fi
-INTLBISON="$ac_cv_prog_INTLBISON"
-if test -n "$INTLBISON"; then
- echo "$ac_t""$INTLBISON" 1>&6
-else
- echo "$ac_t""no" 1>&6
-fi
-
-test -n "$INTLBISON" && break
-done
-
- if test -z "$INTLBISON"; then
- ac_verc_fail=yes
- else
- echo $ac_n "checking version of bison""... $ac_c" 1>&6
-echo "configure:6445: checking version of bison" >&5
- ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'`
- case $ac_prog_version in
- '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
- 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*)
- ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
- *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
- esac
- echo "$ac_t""$ac_prog_version" 1>&6
- fi
- if test $ac_verc_fail = yes; then
- INTLBISON=:
- fi
-
-
-
-
-
-
-
-
-
-
- if test $USE_INCLUDED_LIBINTL = yes; then
- cat >> confdefs.h <<\EOF
-#define USE_INCLUDED_LIBINTL 1
-EOF
-
- fi
-
- nls_cv_header_intl=
- nls_cv_header_libgt=
-
- DATADIRNAME=share
-
-
- INSTOBJEXT=.mo
-
-
- GENCAT=gencat
-
-
-
- if test "x$CATOBJEXT" != x; then
- echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
-echo "configure:6490: checking for catalogs to be installed" >&5
- # Look for .po and .gmo files in the source directory.
- CATALOGS=
- XLINGUAS=
- for cat in $srcdir/po/*$CATOBJEXT $srcdir/po/*.po; do
- # If there aren't any .gmo files the shell will give us the
- # literal string "../path/to/srcdir/po/*.gmo" which has to be
- # weeded out.
- case "$cat" in *\**)
- continue;;
- esac
- # The quadruple backslash is collapsed to a double backslash
- # by the backticks, then collapsed again by the double quotes,
- # leaving us with one backslash in the sed expression (right
- # before the dot that mustn't act as a wildcard). The dot to
- # be escaped in the second expression is hiding inside CATOBJEXT.
- cat=`echo $cat | sed -e "s!$srcdir/!!" -e "s!\\\\.po!$CATOBJEXT!"`
- lang=`echo $cat | sed -e 's!po/!!' -e "s!\\\\$CATOBJEXT!!"`
- # The user is allowed to set LINGUAS to a list of languages to
- # install catalogs for. If it's empty that means "all of them."
- if test "x$LINGUAS" = x; then
- CATALOGS="$CATALOGS $cat"
- XLINGUAS="$XLINGUAS $lang"
- else
- case "$LINGUAS" in *$lang*)
- CATALOGS="$CATALOGS $cat"
- XLINGUAS="$XLINGUAS $lang"
- ;;
- esac
- fi
- done
- LINGUAS="$XLINGUAS"
- echo "$ac_t""$LINGUAS" 1>&6
- fi
-
- MKINSTALLDIRS=
- if test -n "$ac_aux_dir"; then
- MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
- fi
- if test -z "$MKINSTALLDIRS"; then
- MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
- fi
-
-
- INTL_LIBTOOL_SUFFIX_PREFIX=
-
-
# Windows32 Registry support for specifying GCC installation paths.
# Check whether --enable-win32-registry or --disable-win32-registry was given.
if test "${enable_win32_registry+set}" = set; then
enableval="$enable_win32_registry"
- :
-fi
+fi;
case $host_os in
win32 | pe | cygwin* | mingw32* | uwin*)
-echo $ac_n "checking whether windows registry support is requested""... $ac_c" 1>&6
-echo "configure:6548: checking whether windows registry support is requested" >&5
+echo "$as_me:$LINENO: checking whether windows registry support is requested" >&5
+echo $ECHO_N "checking whether windows registry support is requested... $ECHO_C" >&6
if test "x$enable_win32_registry" != xno; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define ENABLE_WIN32_REGISTRY 1
-EOF
+_ACEOF
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ echo "$as_me:$LINENO: checking for library containing RegOpenKeyExA" >&5
+echo $ECHO_N "checking for library containing RegOpenKeyExA... $ECHO_C" >&6
+if test "${ac_cv_search_RegOpenKeyExA+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_RegOpenKeyExA=no
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
- echo "$ac_t""yes" 1>&6
-
-echo $ac_n "checking for library containing RegOpenKeyExA""... $ac_c" 1>&6
-echo "configure:6557: checking for library containing RegOpenKeyExA" >&5
-if eval "test \"`echo '$''{'ac_cv_search_RegOpenKeyExA'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_func_search_save_LIBS="$LIBS"
-ac_cv_search_RegOpenKeyExA="no"
-cat > conftest.$ac_ext <<EOF
-#line 6564 "configure"
-#include "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 RegOpenKeyExA();
-
-int main() {
-RegOpenKeyExA()
-; return 0; }
-EOF
-if { (eval echo configure:6575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
+ builtin and then its argument prototype would still apply. */
+char RegOpenKeyExA ();
+int
+main ()
+{
+RegOpenKeyExA ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 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_search_RegOpenKeyExA="none required"
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
-test "$ac_cv_search_RegOpenKeyExA" = "no" && for i in advapi32; do
-LIBS="-l$i $ac_func_search_save_LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 6586 "configure"
-#include "confdefs.h"
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_RegOpenKeyExA" = no; then
+ for ac_lib in advapi32; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* 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 RegOpenKeyExA();
-
-int main() {
-RegOpenKeyExA()
-; return 0; }
-EOF
-if { (eval echo configure:6597: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
- rm -rf conftest*
- ac_cv_search_RegOpenKeyExA="-l$i"
+ builtin and then its argument prototype would still apply. */
+char RegOpenKeyExA ();
+int
+main ()
+{
+RegOpenKeyExA ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 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_search_RegOpenKeyExA="-l$ac_lib"
break
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
fi
-rm -f conftest*
-done
-LIBS="$ac_func_search_save_LIBS"
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ done
fi
-
-echo "$ac_t""$ac_cv_search_RegOpenKeyExA" 1>&6
-if test "$ac_cv_search_RegOpenKeyExA" != "no"; then
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_RegOpenKeyExA" >&5
+echo "${ECHO_T}$ac_cv_search_RegOpenKeyExA" >&6
+if test "$ac_cv_search_RegOpenKeyExA" != no; then
test "$ac_cv_search_RegOpenKeyExA" = "none required" || LIBS="$ac_cv_search_RegOpenKeyExA $LIBS"
-
-else :
-
+
fi
+
else
- echo "$ac_t""no" 1>&6
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
fi
# Check if user specified a different registry key.
@@ -6634,13 +9178,15 @@ xno)
esac
if test "x$enable_win32_registry" != xno; then
- echo $ac_n "checking registry key on windows hosts""... $ac_c" 1>&6
-echo "configure:6639: checking registry key on windows hosts" >&5
- cat >> confdefs.h <<EOF
+ echo "$as_me:$LINENO: checking registry key on windows hosts" >&5
+echo $ECHO_N "checking registry key on windows hosts... $ECHO_C" >&6
+
+cat >>confdefs.h <<_ACEOF
#define WIN32_REGISTRY_KEY "$gcc_cv_win32_registry_key"
-EOF
+_ACEOF
- echo "$ac_t""$gcc_cv_win32_registry_key" 1>&6
+ echo "$as_me:$LINENO: result: $gcc_cv_win32_registry_key" >&5
+echo "${ECHO_T}$gcc_cv_win32_registry_key" >&6
fi
;;
esac
@@ -6652,30 +9198,27 @@ topdir=`${PWDCMD-pwd}`
cd $holddir
# Conditionalize the makefile for this host machine.
-# Make-host contains the concatenation of all host makefile fragments
-# [there can be more than one]. This file is built by configure.frag.
-host_overrides=Make-host
-dep_host_xmake_file=
-for f in .. ${host_xmake_file}
+xmake_file=
+for f in ${host_xmake_file}
do
if test -f ${srcdir}/config/$f
then
- dep_host_xmake_file="${dep_host_xmake_file} ${srcdir}/config/$f"
+ xmake_file="${xmake_file} \$(srcdir)/config/$f"
fi
done
# Conditionalize the makefile for this target machine.
-# Make-target contains the concatenation of all host makefile fragments
-# [there can be more than one]. This file is built by configure.frag.
-target_overrides=Make-target
-dep_tmake_file=
-for f in .. ${tmake_file}
+tmake_file_=
+for f in ${tmake_file}
do
if test -f ${srcdir}/config/$f
then
- dep_tmake_file="${dep_tmake_file} ${srcdir}/config/$f"
+ tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
fi
done
+tmake_file="${tmake_file_}"
+
+symbolic_link='ln -s'
# If the host doesn't support symlinks, modify CC in
# FLAGS_TO_PASS so CC="stage1/xgcc -Bstage1/" works.
@@ -6705,31 +9248,69 @@ rm -f symtest.tem
out_object_file=`basename $out_file .c`.o
tm_file_list=
+tm_include_list=
for f in $tm_file; do
case $f in
- ansidecl.h )
- tm_file_list="${tm_file_list} \$(srcdir)/../include/ansidecl.h" ;;
defaults.h )
- tm_file_list="${tm_file_list} \$(srcdir)/$f" ;;
- *) tm_file_list="${tm_file_list} \$(srcdir)/config/$f" ;;
+ tm_file_list="${tm_file_list} \$(srcdir)/$f"
+ tm_include_list="${tm_include_list} $f"
+ ;;
+ * )
+ tm_file_list="${tm_file_list} \$(srcdir)/config/$f"
+ tm_include_list="${tm_include_list} config/$f"
+ ;;
esac
done
tm_p_file_list=
+tm_p_include_list=
for f in $tm_p_file; do
- tm_p_file_list="${tm_p_file_list} \$(srcdir)/config/$f"
+ case $f in
+ tm-preds.h )
+ tm_p_file_list="${tm_p_file_list} $f"
+ tm_p_include_list="${tm_p_include_list} $f"
+ ;;
+ * )
+ tm_p_file_list="${tm_p_file_list} \$(srcdir)/config/$f"
+ tm_p_include_list="${tm_p_include_list} config/$f"
+ esac
+done
+
+xm_file_list=
+xm_include_list=
+for f in $xm_file; do
+ case $f in
+ ansidecl.h )
+ xm_file_list="${xm_file_list} \$(srcdir)/../include/$f"
+ xm_include_list="${xm_include_list} $f"
+ ;;
+ auto-host.h )
+ xm_file_list="${xm_file_list} $f"
+ xm_include_list="${xm_include_list} $f"
+ ;;
+ * )
+ xm_file_list="${xm_file_list} \$(srcdir)/config/$f"
+ xm_include_list="${xm_include_list} config/$f"
+ ;;
+ esac
done
host_xm_file_list=
+host_xm_include_list=
for f in $host_xm_file; do
case $f in
ansidecl.h )
- host_xm_file_list="${host_xm_file_list} \$(srcdir)/../include/ansidecl.h" ;;
+ host_xm_file_list="${host_xm_file_list} \$(srcdir)/../include/$f"
+ host_xm_include_list="${host_xm_include_list} $f"
+ ;;
auto-host.h )
- host_xm_file_list="${host_xm_file_list} $f" ;;
- defaults.h )
- host_xm_file_list="${host_xm_file_list} \$(srcdir)/$f" ;;
- *) host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f" ;;
+ host_xm_file_list="${host_xm_file_list} $f"
+ host_xm_include_list="${host_xm_include_list} $f"
+ ;;
+ * )
+ host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f"
+ host_xm_include_list="${host_xm_include_list} config/$f"
+ ;;
esac
done
@@ -6737,124 +9318,139 @@ build_xm_file_list=
for f in $build_xm_file; do
case $f in
ansidecl.h )
- build_xm_file_list="${build_xm_file_list} \$(srcdir)/../include/ansidecl.h" ;;
+ build_xm_file_list="${build_xm_file_list} \$(srcdir)/../include/$f"
+ build_xm_include_list="${build_xm_include_list} $f"
+ ;;
auto-build.h | auto-host.h )
- build_xm_file_list="${build_xm_file_list} $f" ;;
- defaults.h )
- host_xm_file_list="${host_xm_file_list} \$(srcdir)/$f" ;;
- *) build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f" ;;
+ build_xm_file_list="${build_xm_file_list} $f"
+ build_xm_include_list="${build_xm_include_list} $f"
+ ;;
+ * )
+ build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f"
+ build_xm_include_list="${build_xm_include_list} config/$f"
+ ;;
esac
done
# Define macro CROSS_COMPILE in compilation if this is a cross-compiler.
# Also use all.cross instead of all.internal and adjust SYSTEM_HEADER_DIR.
-CROSS=
-ALL=all.internal
-SYSTEM_HEADER_DIR='$(NATIVE_SYSTEM_HEADER_DIR)'
+CROSS=
+ALL=all.internal
+SYSTEM_HEADER_DIR='$(NATIVE_SYSTEM_HEADER_DIR)'
if test x$host != x$target
then
CROSS="-DCROSS_COMPILE"
ALL=all.cross
SYSTEM_HEADER_DIR='$(CROSS_SYSTEM_HEADER_DIR)'
case "$host","$target" in
+ # Darwin crosses can use the host system's libraries and headers,
+ # because of the fat library support. Of course, it must be the
+ # same version of Darwin on both sides. Allow the user to
+ # just say --target=foo-darwin without a version number to mean
+ # "the version on this system".
+ *-*-darwin*,*-*-darwin*)
+ hostos=`echo $host | sed 's/.*-darwin/darwin/'`
+ targetos=`echo $target | sed 's/.*-darwin/darwin/'`
+ if test $hostos = $targetos -o $targetos = darwin ; then
+ CROSS=
+ SYSTEM_HEADER_DIR='$(NATIVE_SYSTEM_HEADER_DIR)'
+ with_headers=yes
+ fi
+ ;;
+
i?86-*-*,x86_64-*-* \
| powerpc*-*-*,powerpc64*-*-*)
CROSS="$CROSS -DNATIVE_CROSS" ;;
esac
+elif test "x$TARGET_SYSTEM_ROOT" != x; then
+ # This is just $(TARGET_SYSTEM_ROOT)$(NATIVE_SYSTEM_HEADER_DIR)
+ SYSTEM_HEADER_DIR='$(CROSS_SYSTEM_HEADER_DIR)'
fi
# If this is a cross-compiler that does not
# have its own set of headers then define
# inhibit_libc
-# If this is using newlib, then define inhibit_libc in LIBGCC2_CFLAGS.
+# If this is using newlib, without having the headers available now,
+# then define inhibit_libc in LIBGCC2_CFLAGS.
# This prevents libgcc2 from containing any code which requires libc
# support.
inhibit_libc=
-if test x$host != x$target && test x$with_headers = x; then
+if { { test x$host != x$target && test "x$with_sysroot" = x ; } ||
+ test x$with_newlib = xyes ; } &&
+ { test "x$with_headers" = x || test "x$with_headers" = xno ; } ; then
inhibit_libc=-Dinhibit_libc
-else
- if test x$with_newlib = xyes; then
- inhibit_libc=-Dinhibit_libc
- fi
fi
# When building gcc with a cross-compiler, we need to adjust things so
# that the generator programs are still built with the native compiler.
# Also, we cannot run fixincludes or fix-header.
-# Note that the terminology here is wrong; it should be BUILD_* throughout.
-# FIXME.
# These are the normal (build=host) settings:
-BUILD_PREFIX=
-BUILD_PREFIX_1=ignore-
-HOST_CC='$(CC)'
-HOST_CFLAGS='$(ALL_CFLAGS)'
+BUILD_PREFIX=
+BUILD_PREFIX_1=ignore-
+CC_FOR_BUILD='$(CC)'
+BUILD_CFLAGS='$(ALL_CFLAGS)'
-STMP_FIXINC=stmp-fixinc
-STMP_FIXPROTO=stmp-fixproto
+STMP_FIXINC=stmp-fixinc
-# And these apply if build != host.
-if test x$build != x$host
+# Possibly disable fixproto, on a per-target basis.
+case ${use_fixproto} in
+ no)
+ STMP_FIXPROTO=
+ ;;
+ yes)
+ STMP_FIXPROTO=stmp-fixproto
+ ;;
+esac
+
+
+# And these apply if build != host, or we are generating coverage data
+if test x$build != x$host || test "x$coverage_flags" != x
then
BUILD_PREFIX=build-
BUILD_PREFIX_1=build-
- HOST_CC='$(CC_FOR_BUILD)'
- HOST_CFLAGS='$(INTERNAL_CFLAGS) $(T_CFLAGS) $(CFLAGS_FOR_BUILD) $(XCFLAGS)'
+ BUILD_CFLAGS='$(INTERNAL_CFLAGS) $(T_CFLAGS) $(CFLAGS_FOR_BUILD)'
- STMP_FIXINC=
- STMP_FIXPROTO=
+ if test "x$TARGET_SYSTEM_ROOT" = x; then
+ STMP_FIXINC=
+ STMP_FIXPROTO=
+ fi
fi
# Expand extra_headers to include complete path.
# This substitutes for lots of t-* files.
extra_headers_list=
-if test "x$extra_headers" = x
-then true
-else
- # Prepend ${srcdir}/config/${cpu_type}/ to every entry in extra_headers.
- for file in $extra_headers;
- do
- extra_headers_list="${extra_headers_list} \$(srcdir)/config/${cpu_type}/${file}"
- done
-fi
-
-if test x$use_collect2 = xno; then
- use_collect2=
-fi
+# Prepend $(srcdir)/config/${cpu_type}/ to every entry in extra_headers.
+for file in ${extra_headers} ; do
+ extra_headers_list="${extra_headers_list} \$(srcdir)/config/${cpu_type}/${file}"
+done
# Add a definition of USE_COLLECT2 if system wants one.
-if test x$use_collect2 != x
-then
- host_xm_defines="${host_xm_defines} USE_COLLECT2"
- xm_defines="${xm_defines} USE_COLLECT2"
-fi
-
-# If we have gas in the build tree, make a link to it.
-if test -f ../gas/Makefile; then
- rm -f as; $symbolic_link ../gas/as-new$host_exeext as$host_exeext 2>/dev/null
-fi
-
-# If we have nm and objdump in the build tree, make a link to them.
-if test -f ../binutils/Makefile; then
- rm -f nm; $symbolic_link ../binutils/nm-new$host_exeext nm$host_exeext 2>/dev/null
- rm -f objdump; $symbolic_link ../binutils/objdump$host_exeext objdump$host_exeext 2>/dev/null
-fi
-
-# If we have ld in the build tree, make a link to it.
-if test -f ../ld/Makefile; then
- rm -f collect-ld; $symbolic_link ../ld/ld-new$host_exeext collect-ld$host_exeext 2>/dev/null
-fi
+case $use_collect2 in
+ no) use_collect2= ;;
+ "") ;;
+ *)
+ host_xm_defines="${host_xm_defines} USE_COLLECT2"
+ xm_defines="${xm_defines} USE_COLLECT2"
+ ;;
+esac
-# Figure out what assembler we will be using.
-echo $ac_n "checking what assembler to use""... $ac_c" 1>&6
-echo "configure:6853: checking what assembler to use" >&5
+# Identify the assembler which will work hand-in-glove with the newly
+# built GCC, so that we can examine its features. This is the assembler
+# which will be driven by the driver program.
+#
+# If build != host, and we aren't building gas in-tree, we identify a
+# build->target assembler and hope that it will have the same features
+# as the host->target assembler we'll be using.
+echo "$as_me:$LINENO: checking what assembler to use" >&5
+echo $ECHO_N "checking what assembler to use... $ECHO_C" >&6
+in_tree_gas=no
gcc_cv_as=
gcc_cv_gas_major_version=
gcc_cv_gas_minor_version=
gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
-gcc_cv_as_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
if test -x "$DEFAULT_ASSEMBLER"; then
gcc_cv_as="$DEFAULT_ASSEMBLER"
elif test -x "$AS"; then
@@ -6862,18 +9458,39 @@ elif test -x "$AS"; then
elif test -x as$host_exeext; then
# Build using assembler in the current directory.
gcc_cv_as=./as$host_exeext
-elif test -f $gcc_cv_as_gas_srcdir/configure.in -a -f ../gas/Makefile; then
- # Single tree build which includes gas.
- for f in $gcc_cv_as_bfd_srcdir/configure $gcc_cv_as_gas_srcdir/configure $gcc_cv_as_gas_srcdir/configure.in $gcc_cv_as_gas_srcdir/Makefile.in
- do
- gcc_cv_gas_version=`grep '^VERSION=[0-9]*\.[0-9]*' $f`
- if test x$gcc_cv_gas_version != x; then
- break
- fi
- done
- gcc_cv_gas_major_version=`expr "$gcc_cv_gas_version" : "VERSION=\([0-9]*\)"`
- gcc_cv_gas_minor_version=`expr "$gcc_cv_gas_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
- gcc_cv_gas_patch_version=`expr "$gcc_cv_gas_version" : "VERSION=[0-9]*\.[0-9]*\.\([0-9]*\)"`
+elif test -f $gcc_cv_as_gas_srcdir/configure.in \
+ && test -f ../gas/Makefile; then
+ # Single tree build which includes gas.
+ in_tree_gas=yes
+ gcc_cv_as_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
+for f in $gcc_cv_as_bfd_srcdir/configure \
+ $gcc_cv_as_gas_srcdir/configure \
+ $gcc_cv_as_gas_srcdir/configure.in \
+ $gcc_cv_as_gas_srcdir/Makefile.in ; do
+ gcc_cv_gas_version=`grep '^VERSION=[0-9]*\.[0-9]*' $f`
+ if test x$gcc_cv_gas_version != x; then
+ break
+ fi
+done
+gcc_cv_gas_major_version=`expr "$gcc_cv_gas_version" : "VERSION=\([0-9]*\)"`
+gcc_cv_gas_minor_version=`expr "$gcc_cv_gas_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
+gcc_cv_gas_patch_version=`expr "$gcc_cv_gas_version" : "VERSION=[0-9]*\.[0-9]*\.\([0-9]*\)"`
+case $gcc_cv_gas_patch_version in
+ "") gcc_cv_gas_patch_version="0" ;;
+esac
+gcc_cv_gas_vers=`expr \( \( $gcc_cv_gas_major_version \* 1000 \) \
+ + $gcc_cv_gas_minor_version \) \* 1000 \
+ + $gcc_cv_gas_patch_version`
+
+ rm -f as$host_exeext
+ $symbolic_link ../gas/as-new$host_exeext as$host_exeext 2>/dev/null
+ in_tree_gas_is_elf=no
+ if grep 'obj_format = elf' ../gas/Makefile > /dev/null \
+ || (grep 'obj_format = multi' ../gas/Makefile \
+ && grep 'extra_objects =.* obj-elf' ../gas/Makefile) > /dev/null
+ then
+ in_tree_gas_is_elf=yes
+ fi
fi
if test "x$gcc_cv_as" = x; then
@@ -6907,12 +9524,12 @@ if test "x$gcc_cv_as" = x; then
gcc_cv_as=`echo as | sed ${program_transform_name}`$host_exeext
fi
- test_dirs="$test_prefix/lib/gcc-lib/$target_alias/$gcc_version \
- $test_prefix/lib/gcc-lib/$target_alias \
- /usr/lib/gcc/$target_alias/$gcc_version \
- /usr/lib/gcc/$target_alias \
- $test_prefix/$target_alias/bin/$target_alias/$gcc_version \
- $test_prefix/$target_alias/bin"
+ test_dirs="$test_prefix/libexec/gcc/$target_noncanonical/$gcc_version \
+ $test_prefix/libexec/gcc/$target_noncanonical \
+ /usr/lib/gcc/$target_noncanonical/$gcc_version \
+ /usr/lib/gcc/$target_noncanonical \
+ $test_prefix/$target_noncanonical/bin/$target_noncanonical/$gcc_version \
+ $test_prefix/$target_noncanonical/bin"
if test x$host = x$target; then
test_dirs="$test_dirs \
@@ -6935,15 +9552,27 @@ if test "x$gcc_cv_as" = x; then
fi
done
fi
-if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
- echo "$ac_t"""newly built gas"" 1>&6
-else
- echo "$ac_t""$gcc_cv_as" 1>&6
-fi
+case $in_tree_gas in
+ yes)
+ echo "$as_me:$LINENO: result: \"newly built gas\"" >&5
+echo "${ECHO_T}\"newly built gas\"" >&6
+ ;;
+ no)
+ echo "$as_me:$LINENO: result: $gcc_cv_as" >&5
+echo "${ECHO_T}$gcc_cv_as" >&6
+ ;;
+esac
-# Figure out what linker we will be using.
-echo $ac_n "checking what linker to use""... $ac_c" 1>&6
-echo "configure:6947: checking what linker to use" >&5
+# Identify the linker which will work hand-in-glove with the newly
+# built GCC, so that we can examine its features. This is the linker
+# which will be driven by the driver program.
+#
+# If build != host, and we aren't building gas in-tree, we identify a
+# build->target linker and hope that it will have the same features
+# as the host->target linker we'll be using.
+echo "$as_me:$LINENO: checking what linker to use" >&5
+echo $ECHO_N "checking what linker to use... $ECHO_C" >&6
+in_tree_ld=no
gcc_cv_ld=
gcc_cv_gld_major_version=
gcc_cv_gld_minor_version=
@@ -6953,11 +9582,18 @@ if test -x "$DEFAULT_LINKER"; then
gcc_cv_ld="$DEFAULT_LINKER"
elif test -x "$LD"; then
gcc_cv_ld="$LD"
-elif test -x ld$host_exeext; then
+elif test -x collect-ld$host_exeext; then
# Build using linker in the current directory.
- gcc_cv_ld=./ld$host_exeext
-elif test -f $gcc_cv_ld_gld_srcdir/configure.in -a -f ../ld/Makefile; then
+ gcc_cv_ld=./collect-ld$host_exeext
+elif test -f $gcc_cv_ld_gld_srcdir/configure.in \
+ && test -f ../ld/Makefile; then
# Single tree build which includes ld.
+ in_tree_ld=yes
+ in_tree_ld_is_elf=no
+ if (grep 'EMUL = .*elf' ../ld/Makefile \
+ || grep 'EMUL = .*linux' ../ld/Makefile) > /dev/null; then
+ in_tree_ld_is_elf=yes
+ fi
for f in $gcc_cv_ld_bfd_srcdir/configure $gcc_cv_ld_gld_srcdir/configure $gcc_cv_ld_gld_srcdir/configure.in $gcc_cv_ld_gld_srcdir/Makefile.in
do
gcc_cv_gld_version=`grep '^VERSION=[0-9]*\.[0-9]*' $f`
@@ -6967,6 +9603,9 @@ elif test -f $gcc_cv_ld_gld_srcdir/configure.in -a -f ../ld/Makefile; then
done
gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
+ rm -f collect-ld$host_exeext
+ $symbolic_link ../ld/ld-new$host_exeext collect-ld$host_exeext \
+ 2>/dev/null
fi
if test "x$gcc_cv_ld" = x; then
@@ -7000,12 +9639,12 @@ if test "x$gcc_cv_ld" = x; then
gcc_cv_ld=`echo ld | sed ${program_transform_name}`$host_exeext
fi
- test_dirs="$test_prefix/lib/gcc-lib/$target_alias/$gcc_version \
- $test_prefix/lib/gcc-lib/$target_alias \
- /usr/lib/gcc/$target_alias/$gcc_version \
- /usr/lib/gcc/$target_alias \
- $test_prefix/$target_alias/bin/$target_alias/$gcc_version \
- $test_prefix/$target_alias/bin"
+ test_dirs="$test_prefix/libexec/gcc/$target_noncanonical/$gcc_version \
+ $test_prefix/libexec/gcc/$target_noncanonical \
+ /usr/lib/gcc/$target_noncanonical/$gcc_version \
+ /usr/lib/gcc/$target_noncanonical \
+ $test_prefix/$target_noncanonical/bin/$target_noncanonical/$gcc_version \
+ $test_prefix/$target_noncanonical/bin"
if test x$host = x$target; then
test_dirs="$test_dirs \
@@ -7028,275 +9667,414 @@ if test "x$gcc_cv_ld" = x; then
fi
done
fi
-if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; then
- echo "$ac_t"""newly built ld"" 1>&6
-else
- echo "$ac_t""$gcc_cv_ld" 1>&6
-fi
+case $in_tree_ld in
+ yes)
+ echo "$as_me:$LINENO: result: \"newly built ld\"" >&5
+echo "${ECHO_T}\"newly built ld\"" >&6
+ ;;
+ no)
+ echo "$as_me:$LINENO: result: $gcc_cv_ld" >&5
+echo "${ECHO_T}$gcc_cv_ld" >&6
+ ;;
+esac
# Figure out what nm we will be using.
-echo $ac_n "checking what nm to use""... $ac_c" 1>&6
-echo "configure:7040: checking what nm to use" >&5
+gcc_cv_binutils_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/binutils
+echo "$as_me:$LINENO: checking what nm to use" >&5
+echo $ECHO_N "checking what nm to use... $ECHO_C" >&6
+in_tree_nm=no
if test -x nm$host_exeext; then
gcc_cv_nm=./nm$host_exeext
+elif test -f $gcc_cv_binutils_srcdir/configure.in \
+ && test -f ../binutils/Makefile; then
+ # Single tree build which includes binutils.
+ in_tree_nm=yes
+ gcc_cv_nm=./nm$host_exeext
+ rm -f nm$host_exeext
+ $symbolic_link ../binutils/nm-new$host_exeext nm$host_exeext 2>/dev/null
elif test "x$program_prefix" != xNONE; then
gcc_cv_nm=${program_prefix}nm$host_exeext
else
gcc_cv_nm=`echo nm | sed ${program_transform_name}`$host_exeext
fi
-echo "$ac_t""$gcc_cv_nm" 1>&6
+case $in_tree_nm in
+ yes) echo "$as_me:$LINENO: result: \"newly built nm\"" >&5
+echo "${ECHO_T}\"newly built nm\"" >&6 ;;
+ no) echo "$as_me:$LINENO: result: $gcc_cv_nm" >&5
+echo "${ECHO_T}$gcc_cv_nm" >&6 ;;
+esac
# Figure out what objdump we will be using.
-echo $ac_n "checking what objdump to use""... $ac_c" 1>&6
-echo "configure:7052: checking what objdump to use" >&5
+echo "$as_me:$LINENO: checking what objdump to use" >&5
+echo $ECHO_N "checking what objdump to use... $ECHO_C" >&6
+in_tree_objdump=no
if test -x objdump$host_exeext; then
gcc_cv_objdump=./objdump$host_exeext
+elif test -f $gcc_cv_binutils_srcdir/configure.in \
+ && test -f ../binutils/Makefile; then
+ # Single tree build which includes binutils.
+ in_tree_objdump=yes
+ gcc_cv_objdump=./objdump$host_exeext
+ rm -f objdump$host_exeext
+ $symbolic_link ../binutils/objdump$host_exeext \
+ objdump$host_exeext 2>/dev/null
elif test "x$program_prefix" != xNONE; then
gcc_cv_objdump=${program_prefix}objdump$host_exeext
else
- gcc_cv_objdump=`echo objdump | sed ${program_transform_name}`$host_exeext
+ gcc_cv_objdump=`echo objdump | \
+ sed ${program_transform_name}`$host_exeext
fi
-echo "$ac_t""$gcc_cv_objdump" 1>&6
+case $in_tree_objdump in
+ yes) echo "$as_me:$LINENO: result: \"newly built objdump\"" >&5
+echo "${ECHO_T}\"newly built objdump\"" >&6 ;;
+ no) echo "$as_me:$LINENO: result: $gcc_cv_objdump" >&5
+echo "${ECHO_T}$gcc_cv_objdump" >&6 ;;
+esac
# Figure out what assembler alignment features are present.
-echo $ac_n "checking assembler alignment features""... $ac_c" 1>&6
-echo "configure:7064: checking assembler alignment features" >&5
-gcc_cv_as_alignment_features=none
-if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
- # Gas version 2.6 and later support for .balign and .p2align.
- # bytes to skip when using .p2align.
- if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 6 -o "$gcc_cv_gas_major_version" -gt 2; then
- gcc_cv_as_alignment_features=".balign and .p2align"
- cat >> confdefs.h <<\EOF
+echo "$as_me:$LINENO: checking assembler for .balign and .p2align" >&5
+echo $ECHO_N "checking assembler for .balign and .p2align... $ECHO_C" >&6
+if test "${gcc_cv_as_balign_and_p2align+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_balign_and_p2align=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 6 \) \* 1000 + 0`
+ then gcc_cv_as_balign_and_p2align=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo '.balign 4
+.p2align 2' > 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_balign_and_p2align=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_balign_and_p2align" >&5
+echo "${ECHO_T}$gcc_cv_as_balign_and_p2align" >&6
+if test $gcc_cv_as_balign_and_p2align = yes; then
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_GAS_BALIGN_AND_P2ALIGN 1
-EOF
+_ACEOF
- fi
- # Gas version 2.8 and later support specifying the maximum
- # bytes to skip when using .p2align.
- if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 8 -o "$gcc_cv_gas_major_version" -gt 2; then
- gcc_cv_as_alignment_features=".p2align including maximum skip"
- cat >> confdefs.h <<\EOF
-#define HAVE_GAS_MAX_SKIP_P2ALIGN 1
-EOF
+fi
- fi
-elif test x$gcc_cv_as != x; then
- # Check if we have .balign and .p2align
- echo ".balign 4" > conftest.s
- echo ".p2align 2" >> conftest.s
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_alignment_features=".balign and .p2align"
- cat >> confdefs.h <<\EOF
-#define HAVE_GAS_BALIGN_AND_P2ALIGN 1
-EOF
+echo "$as_me:$LINENO: checking assembler for .p2align with maximum skip" >&5
+echo $ECHO_N "checking assembler for .p2align with maximum skip... $ECHO_C" >&6
+if test "${gcc_cv_as_max_skip_p2align+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_max_skip_p2align=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 8 \) \* 1000 + 0`
+ then gcc_cv_as_max_skip_p2align=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo '.p2align 4,,7' > 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_max_skip_p2align=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_max_skip_p2align" >&5
+echo "${ECHO_T}$gcc_cv_as_max_skip_p2align" >&6
+if test $gcc_cv_as_max_skip_p2align = yes; then
- fi
- rm -f conftest.s conftest.o
- # Check if specifying the maximum bytes to skip when
- # using .p2align is supported.
- echo ".p2align 4,,7" > conftest.s
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_alignment_features=".p2align including maximum skip"
- cat >> confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
#define HAVE_GAS_MAX_SKIP_P2ALIGN 1
-EOF
+_ACEOF
- fi
- rm -f conftest.s conftest.o
fi
-echo "$ac_t""$gcc_cv_as_alignment_features" 1>&6
-echo $ac_n "checking assembler subsection support""... $ac_c" 1>&6
-echo "configure:7112: checking assembler subsection support" >&5
-gcc_cv_as_subsections=no
-if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
- if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 9 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
- gcc_cv_as_subsections="working .subsection -1"
- fi
-elif test x$gcc_cv_as != x; then
- # Check if we have .subsection
- echo ".subsection 1" > conftest.s
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_subsections=".subsection"
- if test x$gcc_cv_nm != x; then
- cat > conftest.s <<EOF
-conftest_label1: .word 0
+echo "$as_me:$LINENO: checking assembler for working .subsection -1" >&5
+echo $ECHO_N "checking assembler for working .subsection -1... $ECHO_C" >&6
+if test "${gcc_cv_as_subsection_m1+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_subsection_m1=no
+ if test $in_tree_gas = yes; then
+ if test $in_tree_gas_is_elf = yes \
+ && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 9 \) \* 1000 + 0`
+ then gcc_cv_as_subsection_m1=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo 'conftest_label1: .word 0
.subsection -1
conftest_label2: .word 0
-.previous
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- $gcc_cv_nm conftest.o | grep conftest_label1 > conftest.nm1
- $gcc_cv_nm conftest.o | grep conftest_label2 | sed -e 's/label2/label1/' > conftest.nm2
- if cmp conftest.nm1 conftest.nm2 > /dev/null 2>&1; then
- :
- else
- gcc_cv_as_subsections="working .subsection -1"
- fi
- fi
- fi
- fi
- rm -f conftest.s conftest.o conftest.nm1 conftest.nm2
+.previous' > 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
+ if test x$gcc_cv_nm != x; then
+ $gcc_cv_nm conftest.o | grep conftest_label1 > conftest.nm1
+ $gcc_cv_nm conftest.o | grep conftest_label2 | sed -e 's/label2/label1/' > conftest.nm2
+ if cmp conftest.nm1 conftest.nm2 > /dev/null 2>&1
+ then :
+ else gcc_cv_as_subsection_m1=yes
+ fi
+ rm -f conftest.nm1 conftest.nm2
+ fi
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
fi
-if test x"$gcc_cv_as_subsections" = x"working .subsection -1"; then
- cat >> confdefs.h <<\EOF
+echo "$as_me:$LINENO: result: $gcc_cv_as_subsection_m1" >&5
+echo "${ECHO_T}$gcc_cv_as_subsection_m1" >&6
+if test $gcc_cv_as_subsection_m1 = yes; then
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_GAS_SUBSECTION_ORDERING 1
-EOF
+_ACEOF
fi
-echo "$ac_t""$gcc_cv_as_subsections" 1>&6
-echo $ac_n "checking assembler weak support""... $ac_c" 1>&6
-echo "configure:7152: checking assembler weak support" >&5
-gcc_cv_as_weak=no
-if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
- if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 2 -o "$gcc_cv_gas_major_version" -gt 2; then
- gcc_cv_as_weak="yes"
+echo "$as_me:$LINENO: checking assembler for .weak" >&5
+echo $ECHO_N "checking assembler for .weak... $ECHO_C" >&6
+if test "${gcc_cv_as_weak+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_weak=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 2 \) \* 1000 + 0`
+ then gcc_cv_as_weak=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo ' .weak foobar' > 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_weak=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
fi
-elif test x$gcc_cv_as != x; then
- # Check if we have .weak
- echo " .weak foobar" > conftest.s
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_weak="yes"
- fi
- rm -f conftest.s conftest.o conftest.nm1 conftest.nm2
fi
-if test x"$gcc_cv_as_weak" = xyes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_GAS_WEAK 1
-EOF
+echo "$as_me:$LINENO: result: $gcc_cv_as_weak" >&5
+echo "${ECHO_T}$gcc_cv_as_weak" >&6
+if test $gcc_cv_as_weak = yes; then
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GAS_WEAK 1
+_ACEOF
+
+fi
+
+# .hidden needs to be supported in both the assembler and the linker,
+# because GNU LD versions before 2.12.1 have buggy support for STV_HIDDEN.
+# This is irritatingly difficult to feature test for; we have to check the
+# date string after the version number. If we've got an in-tree
+# ld, we don't know its patchlevel version, so we set the baseline at 2.13
+# to be safe.
+# The gcc_GAS_CHECK_FEATURE call just sets a cache variable.
+echo "$as_me:$LINENO: checking assembler for .hidden" >&5
+echo $ECHO_N "checking assembler for .hidden... $ECHO_C" >&6
+if test "${gcc_cv_as_hidden+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_hidden=no
+ if test $in_tree_gas = yes; then
+ if test $in_tree_gas_is_elf = yes \
+ && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 13 \) \* 1000 + 0`
+ then gcc_cv_as_hidden=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo ' .hidden foobar
+foobar:' > 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_hidden=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
fi
-echo "$ac_t""$gcc_cv_as_weak" 1>&6
-
-echo $ac_n "checking assembler hidden support""... $ac_c" 1>&6
-echo "configure:7175: checking assembler hidden support" >&5
-gcc_cv_as_hidden=no
-if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
- if test "$gcc_cv_gas_major_version" -eq 2 \
- -a "$gcc_cv_gas_minor_version" -eq 12 \
- -a "$gcc_cv_gas_patch_version" -ge 1 \
- -o "$gcc_cv_gas_major_version" -eq 2 \
- -a "$gcc_cv_gas_minor_version" -gt 12 \
- -o "$gcc_cv_gas_major_version" -gt 2 \
- && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
- gcc_cv_as_hidden="yes"
+echo "$as_me:$LINENO: result: $gcc_cv_as_hidden" >&5
+echo "${ECHO_T}$gcc_cv_as_hidden" >&6
+
+
+echo "$as_me:$LINENO: checking linker for .hidden support" >&5
+echo $ECHO_N "checking linker for .hidden support... $ECHO_C" >&6
+if test "${gcc_cv_ld_hidden+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test $in_tree_ld = yes ; then
+ gcc_cv_ld_hidden=no
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 13 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_hidden=yes
fi
-elif test x$gcc_cv_as != x; then
- # Check if we have .hidden
- echo " .hidden foobar" > conftest.s
- echo "foobar:" >> conftest.s
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_hidden="yes"
- fi
- rm -f conftest.s conftest.o conftest.nm1 conftest.nm2
-
- # GNU LD versions before 2.12.1 have buggy support for STV_HIDDEN.
- # This is irritatingly difficult to feature test for. Look for
- # the date string after the version number.
- ld_ver=`$gcc_cv_ld --version 2>/dev/null | head -1`
- if echo "$ld_ver" | grep GNU > /dev/null; then
- ld_vers=`echo $ld_ver | sed -n 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\(\|\.[0-9][0-9]*\(\|\.[0-9][0-9]*\)\)\)\([ ].*\|\)$,\1,p'`
- ld_date=`echo $ld_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)[-]*\([01][0-9]\)[-]*\([0-3][0-9]\).*$,\1\2\3,p'`
- if test 0"$ld_date" -lt 20020404; then
- if test -n "$ld_date"; then
- # If there was date string, but was earlier than 2002-04-04, fail
- gcc_cv_as_hidden="no"
- elif test -z "$ld_vers"; then
- # If there was no date string nor ld version number, something is wrong
- gcc_cv_as_hidden="no"
- else
- ld_vers_major=`expr "$ld_vers" : '\([0-9]*\)'`
- ld_vers_minor=`expr "$ld_vers" : '[0-9]*\.\([0-9]*\)'`
- ld_vers_patch=`expr "$ld_vers" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
- test -z "$ld_vers_patch" && ld_vers_patch=0
- if test "$ld_vers_major" -lt 2; then
- gcc_cv_as_hidden="no"
- elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 12; then
- gcc_cv_as_hidden="no"
- elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -eq 12 \
- -a "$ld_vers_patch" -eq 0; then
- gcc_cv_as_hidden="no"
- fi
- fi
- fi
- else
- # non-GNU linkers don't seem to support .hidden yet
- gcc_cv_as_hidden=no
+else
+ gcc_cv_ld_hidden=yes
+ ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q`
+ if echo "$ld_ver" | grep GNU > /dev/null; then
+ ld_vers=`echo $ld_ver | sed -n \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\)$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\)[ ].*$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)[ ].*$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)[ ].*$,\1,p'`
+ ld_date=`echo $ld_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)[-]*\([01][0-9]\)[-]*\([0-3][0-9]\).*$,\1\2\3,p'`
+ if test 0"$ld_date" -lt 20020404; then
+ if test -n "$ld_date"; then
+ # If there was date string, but was earlier than 2002-04-04, fail
+ gcc_cv_ld_hidden=no
+ elif test -z "$ld_vers"; then
+ # If there was no date string nor ld version number, something is wrong
+ gcc_cv_ld_hidden=no
+ else
+ ld_vers_major=`expr "$ld_vers" : '\([0-9]*\)'`
+ ld_vers_minor=`expr "$ld_vers" : '[0-9]*\.\([0-9]*\)'`
+ ld_vers_patch=`expr "$ld_vers" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
+ test -z "$ld_vers_patch" && ld_vers_patch=0
+ if test "$ld_vers_major" -lt 2; then
+ gcc_cv_ld_hidden=no
+ elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 12; then
+ gcc_cv_ld_hidden="no"
+ elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -eq 12 -a "$ld_vers_patch" -eq 0; then
+ gcc_cv_ld_hidden=no
fi
+ fi
+ fi
+ else
+ case "${target}" in
+ hppa64*-*-hpux* | ia64*-*-hpux*)
+ gcc_cv_ld_hidden=yes
+ ;;
+ *)
+ gcc_cv_ld_hidden=no
+ ;;
+ esac
+ fi
fi
-if test x"$gcc_cv_as_hidden" = xyes; then
- cat >> confdefs.h <<\EOF
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_ld_hidden" >&5
+echo "${ECHO_T}$gcc_cv_ld_hidden" >&6
+libgcc_visibility=no
+
+if test $gcc_cv_as_hidden = yes && test $gcc_cv_ld_hidden = yes; then
+ libgcc_visibility=yes
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_GAS_HIDDEN 1
-EOF
+_ACEOF
fi
-echo "$ac_t""$gcc_cv_as_hidden" 1>&6
-libgcc_visibility=$gcc_cv_as_hidden
-
-echo $ac_n "checking assembler leb128 support""... $ac_c" 1>&6
-echo "configure:7241: checking assembler leb128 support" >&5
-gcc_cv_as_leb128=no
-if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
- if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 11 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
- gcc_cv_as_leb128="yes"
- fi
-elif test x$gcc_cv_as != x; then
- # Check if we have .[us]leb128, and support symbol arithmetic with it.
- cat > conftest.s <<EOF
- .data
+# Check if we have .[us]leb128, and support symbol arithmetic with it.
+echo "$as_me:$LINENO: checking assembler for .sleb128 and .uleb128" >&5
+echo $ECHO_N "checking assembler for .sleb128 and .uleb128... $ECHO_C" >&6
+if test "${gcc_cv_as_leb128+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_leb128=no
+ if test $in_tree_gas = yes; then
+ if test $in_tree_gas_is_elf = yes \
+ && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 11 \) \* 1000 + 0`
+ then gcc_cv_as_leb128=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo ' .data
.uleb128 L2 - L1
L1:
.uleb128 1280
.sleb128 -1010
-L2:
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_leb128="yes"
-
- # GAS versions before 2.11 do not support uleb128,
- # despite appearing to.
- # ??? There exists an elf-specific test that will crash
- # the assembler. Perhaps it's better to figure out whether
- # arbitrary sections are supported and try the test.
- as_ver=`$gcc_cv_as --version 2>/dev/null | head -1`
- if echo "$as_ver" | grep GNU > /dev/null; then
- as_ver=`echo $as_ver | sed -e 's/GNU assembler \([0-9.][0-9.]*\).*/\1/'`
- as_major=`echo $as_ver | sed 's/\..*//'`
- as_minor=`echo $as_ver | sed 's/[^.]*\.\([0-9]*\).*/\1/'`
- if test $as_major -eq 2 -a $as_minor -lt 11; then
- gcc_cv_as_leb128="no"
- fi
- fi
- fi
- rm -f conftest.s conftest.o conftest.nm1 conftest.nm2
+L2:' > 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
+ # GAS versions before 2.11 do not support uleb128,
+ # despite appearing to.
+ # ??? There exists an elf-specific test that will crash
+ # the assembler. Perhaps it's better to figure out whether
+ # arbitrary sections are supported and try the test.
+ as_ver=`$gcc_cv_as --version 2>/dev/null | sed 1q`
+ if echo "$as_ver" | grep GNU > /dev/null; then
+ as_ver=`echo $as_ver | sed -e 's/GNU assembler \([0-9.][0-9.]*\).*/\1/'`
+ as_major=`echo $as_ver | sed 's/\..*//'`
+ as_minor=`echo $as_ver | sed 's/[^.]*\.\([0-9]*\).*/\1/'`
+ if test $as_major -eq 2 && test $as_minor -lt 11
+ then :
+ else gcc_cv_as_leb128=yes
+ fi
+ fi
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
fi
-if test x"$gcc_cv_as_leb128" = xyes; then
- cat >> confdefs.h <<\EOF
+echo "$as_me:$LINENO: result: $gcc_cv_as_leb128" >&5
+echo "${ECHO_T}$gcc_cv_as_leb128" >&6
+if test $gcc_cv_as_leb128 = yes; then
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_AS_LEB128 1
-EOF
+_ACEOF
fi
-echo "$ac_t""$gcc_cv_as_leb128" 1>&6
-echo $ac_n "checking assembler eh_frame optimization""... $ac_c" 1>&6
-echo "configure:7286: checking assembler eh_frame optimization" >&5
-gcc_cv_as_eh_frame=no
-if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
- if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 12 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
- gcc_cv_as_eh_frame="yes"
- fi
-elif test x$gcc_cv_as != x; then
- # Check if this is GAS.
- as_ver=`$gcc_cv_as --version < /dev/null 2> /dev/null | head -1`
- rm -f a.out 2> /dev/null
- if echo "$as_ver" | grep GNU > /dev/null; then
- # Versions up to and including 2.11.0 may mis-optimize
- # .eh_frame data. Try something.
- cat > conftest.s <<EOF
- .text
+# GAS versions up to and including 2.11.0 may mis-optimize
+# .eh_frame data.
+echo "$as_me:$LINENO: checking assembler for eh_frame optimization" >&5
+echo $ECHO_N "checking assembler for eh_frame optimization... $ECHO_C" >&6
+if test "${gcc_cv_as_eh_frame+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_eh_frame=no
+ if test $in_tree_gas = yes; then
+ if test $in_tree_gas_is_elf = yes \
+ && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 12 \) \* 1000 + 0`
+ then gcc_cv_as_eh_frame=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo ' .text
.LFB1:
.4byte 0
.L1:
@@ -7327,70 +10105,105 @@ __FRAME_BEGIN__:
.4byte .LFE1-.LFB1
.byte 0x4
.4byte .L1-.LFB1
-.LEFDE1:
-EOF
- cat > conftest.lit <<EOF
+.LEFDE1:' > 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
+ cat > conftest.lit <<EOF
0000 10000000 00000000 017a0001 781a0004 .........z..x...
0010 01000000 12000000 18000000 00000000 ................
0020 08000000 04080000 0044 .........D
EOF
- cat > conftest.big <<EOF
+cat > conftest.big <<EOF
0000 00000010 00000000 017a0001 781a0004 .........z..x...
0010 00000001 00000012 00000018 00000000 ................
0020 00000008 04000000 0844 .........D
EOF
- # If the assembler didn't choke, and we can objdump,
- # and we got the correct data, then succeed.
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \
- && $gcc_cv_objdump -s -j .eh_frame conftest.o 2>/dev/null \
- | tail -3 > conftest.got \
- && { cmp conftest.lit conftest.got > /dev/null 2>&1 \
- || cmp conftest.big conftest.got > /dev/null 2>&1; }
- then
- gcc_cv_as_eh_frame="yes"
- else
- gcc_cv_as_eh_frame="bad"
- if $gcc_cv_as -o conftest.o --traditional-format /dev/null; then
- cat >> confdefs.h <<\EOF
+ # If the assembler didn't choke, and we can objdump,
+ # and we got the correct data, then succeed.
+ if test x$gcc_cv_objdump != x \
+ && $gcc_cv_objdump -s -j .eh_frame conftest.o 2>/dev/null \
+ | tail -3 > conftest.got \
+ && { cmp conftest.lit conftest.got > /dev/null 2>&1 \
+ || cmp conftest.big conftest.got > /dev/null 2>&1; }
+ then
+ gcc_cv_as_eh_frame=yes
+ elif { ac_try='$gcc_cv_as -o conftest.o --traditional-format /dev/null'
+ { (eval 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_eh_frame=buggy
+ else
+ # Uh oh, what do we do now?
+ gcc_cv_as_eh_frame=no
+ fi
+ 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_eh_frame" >&5
+echo "${ECHO_T}$gcc_cv_as_eh_frame" >&6
+
+
+if test $gcc_cv_as_eh_frame = buggy; then
+
+cat >>confdefs.h <<\_ACEOF
#define USE_AS_TRADITIONAL_FORMAT 1
-EOF
+_ACEOF
- fi
- fi
- fi
- rm -f conftest.*
fi
-echo "$ac_t""$gcc_cv_as_eh_frame" 1>&6
-echo $ac_n "checking assembler section merging support""... $ac_c" 1>&6
-echo "configure:7367: checking assembler section merging support" >&5
-gcc_cv_as_shf_merge=no
-if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
- if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 12 -o "$gcc_cv_gas_major_version" -gt 2 && grep 'obj_format = elf' ../gas/Makefile > /dev/null; then
- gcc_cv_as_shf_merge=yes
+echo "$as_me:$LINENO: checking assembler for section merging support" >&5
+echo $ECHO_N "checking assembler for section merging support... $ECHO_C" >&6
+if test "${gcc_cv_as_shf_merge+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_shf_merge=no
+ if test $in_tree_gas = yes; then
+ if test $in_tree_gas_is_elf = yes \
+ && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 12 \) \* 1000 + 0`
+ then gcc_cv_as_shf_merge=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo '.section .rodata.str, "aMS", @progbits, 1' > conftest.s
+ if { ac_try='$gcc_cv_as --fatal-warnings -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_shf_merge=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
fi
-elif test x$gcc_cv_as != x; then
- # Check if we support SHF_MERGE sections
- echo '.section .rodata.str, "aMS", @progbits, 1' > conftest.s
- if $gcc_cv_as --fatal-warnings -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_shf_merge=yes
- fi
- rm -f conftest.s conftest.o
fi
-if test x"$gcc_cv_as_shf_merge" = xyes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_GAS_SHF_MERGE 1
-EOF
+echo "$as_me:$LINENO: result: $gcc_cv_as_shf_merge" >&5
+echo "${ECHO_T}$gcc_cv_as_shf_merge" >&6
-fi
-echo "$ac_t""$gcc_cv_as_shf_merge" 1>&6
-echo $ac_n "checking assembler thread-local storage support""... $ac_c" 1>&6
-echo "configure:7390: checking assembler thread-local storage support" >&5
-gcc_cv_as_tls=no
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GAS_SHF_MERGE `if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi`
+_ACEOF
+
+
+# Thread-local storage - the check is heavily parametrized.
conftest_s=
tls_first_major=
tls_first_minor=
+tls_as_opt=
case "$target" in
alpha*-*-*)
conftest_s='
@@ -7413,6 +10226,7 @@ foo: .long 25
lda $4,foo($29) !tprel'
tls_first_major=2
tls_first_minor=13
+ tls_as_opt=--fatal-warnings
;;
i[34567]86-*-*)
conftest_s='
@@ -7432,6 +10246,7 @@ foo: .long 25
leal foo@NTPOFF(%ecx), %eax'
tls_first_major=2
tls_first_minor=14
+ tls_as_opt=--fatal-warnings
;;
x86_64-*-*)
conftest_s='
@@ -7446,6 +10261,7 @@ foo: .long 25
movq $foo@TPOFF, %rax'
tls_first_major=2
tls_first_minor=14
+ tls_as_opt=--fatal-warnings
;;
ia64-*-*)
conftest_s='
@@ -7463,6 +10279,67 @@ foo: data8 25
movl r24 = @tprel(foo#)'
tls_first_major=2
tls_first_minor=13
+ tls_as_opt=--fatal-warnings
+ ;;
+ powerpc-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+ .align 2
+ld0: .space 4
+ld1: .space 4
+x1: .space 4
+x2: .space 4
+x3: .space 4
+ .text
+ addi 3,31,ld0@got@tlsgd
+ bl __tls_get_addr
+ addi 3,31,x1@got@tlsld
+ bl __tls_get_addr
+ addi 9,3,x1@dtprel
+ addis 9,3,x2@dtprel@ha
+ addi 9,9,x2@dtprel@l
+ lwz 9,x3@got@tprel(31)
+ add 9,9,x@tls
+ addi 9,2,x1@tprel
+ addis 9,2,x2@tprel@ha
+ addi 9,9,x2@tprel@l'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-a32 --fatal-warnings"
+ ;;
+ powerpc64-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+ .align 3
+ld0: .space 8
+ld1: .space 8
+x1: .space 8
+x2: .space 8
+x3: .space 8
+ .text
+ addi 3,2,ld0@got@tlsgd
+ bl .__tls_get_addr
+ nop
+ addi 3,2,ld1@toc
+ bl .__tls_get_addr
+ nop
+ addi 3,2,x1@got@tlsld
+ bl .__tls_get_addr
+ nop
+ addi 9,3,x1@dtprel
+ bl .__tls_get_addr
+ nop
+ addis 9,3,x2@dtprel@ha
+ addi 9,9,x2@dtprel@l
+ bl .__tls_get_addr
+ nop
+ ld 9,x3@got@dtprel(2)
+ add 9,9,3
+ bl .__tls_get_addr
+ nop'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-a64 --fatal-warnings"
;;
s390-*-*)
conftest_s='
@@ -7481,6 +10358,7 @@ foo: .long 25
bas %r14,0(%r1,%r13):tls_ldcall:foo'
tls_first_major=2
tls_first_minor=14
+ tls_as_opt="-m31 --fatal-warnings"
;;
s390x-*-*)
conftest_s='
@@ -7498,54 +10376,143 @@ foo: .long 25
brasl %r14,__tls_get_offset@PLT:tls_ldcall:foo'
tls_first_major=2
tls_first_minor=14
+ tls_as_opt="-m64 -Aesame --fatal-warnings"
+ ;;
+ sh-*-* | sh[34]-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ .long foo@TLSGD
+ .long foo@TLSLDM
+ .long foo@DTPOFF
+ .long foo@GOTTPOFF
+ .long foo@TPOFF'
+ tls_first_major=2
+ tls_first_minor=13
+ tls_as_opt=--fatal-warnings
+ ;;
+ sparc*-*-*)
+ case "$target" in
+ sparc*-sun-solaris2.*)
+ on_solaris=yes
+ ;;
+ *)
+ on_solaris=no
+ ;;
+ esac
+ if test x$on_solaris = xyes && test x$gas_flag = xno; then
+ conftest_s='
+ .section ".tdata",#alloc,#write,#tls
+foo: .long 25
+ .text
+ sethi %tgd_hi22(foo), %o0
+ add %o0, %tgd_lo10(foo), %o1
+ add %l7, %o1, %o0, %tgd_add(foo)
+ call __tls_get_addr, %tgd_call(foo)
+ sethi %tldm_hi22(foo), %l1
+ add %l1, %tldm_lo10(foo), %l2
+ add %l7, %l2, %o0, %tldm_add(foo)
+ call __tls_get_addr, %tldm_call(foo)
+ sethi %tldo_hix22(foo), %l3
+ xor %l3, %tldo_lox10(foo), %l4
+ add %o0, %l4, %l5, %tldo_add(foo)
+ sethi %tie_hi22(foo), %o3
+ add %o3, %tie_lo10(foo), %o3
+ ld [%l7 + %o3], %o2, %tie_ld(foo)
+ add %g7, %o2, %o4, %tie_add(foo)
+ sethi %tle_hix22(foo), %l1
+ xor %l1, %tle_lox10(foo), %o5
+ ld [%g7 + %o5], %o1'
+ tls_first_major=0
+ tls_first_minor=0
+ else
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ sethi %tgd_hi22(foo), %o0
+ add %o0, %tgd_lo10(foo), %o1
+ add %l7, %o1, %o0, %tgd_add(foo)
+ call __tls_get_addr, %tgd_call(foo)
+ sethi %tldm_hi22(foo), %l1
+ add %l1, %tldm_lo10(foo), %l2
+ add %l7, %l2, %o0, %tldm_add(foo)
+ call __tls_get_addr, %tldm_call(foo)
+ sethi %tldo_hix22(foo), %l3
+ xor %l3, %tldo_lox10(foo), %l4
+ add %o0, %l4, %l5, %tldo_add(foo)
+ sethi %tie_hi22(foo), %o3
+ add %o3, %tie_lo10(foo), %o3
+ ld [%l7 + %o3], %o2, %tie_ld(foo)
+ add %g7, %o2, %o4, %tie_add(foo)
+ sethi %tle_hix22(foo), %l1
+ xor %l1, %tle_lox10(foo), %o5
+ ld [%g7 + %o5], %o1'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-32 --fatal-warnings"
+ fi
;;
esac
if test -z "$tls_first_major"; then
- :
-elif test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x
-then
- if test "$gcc_cv_gas_major_version" -eq "$tls_first_major" \
- -a "$gcc_cv_gas_minor_version" -ge "$tls_first_minor" \
- -o "$gcc_cv_gas_major_version" -gt "$tls_first_major"; then
- gcc_cv_as_tls=yes
- fi
-elif test x$gcc_cv_as != x; then
- echo "$conftest_s" > conftest.s
- if $gcc_cv_as --fatal-warnings -o conftest.o conftest.s > /dev/null 2>&1
- then
- gcc_cv_as_tls=yes
+ : # If we don't have a check, assume no support.
+else
+ echo "$as_me:$LINENO: checking assembler for thread-local storage support" >&5
+echo $ECHO_N "checking assembler for thread-local storage support... $ECHO_C" >&6
+if test "${gcc_cv_as_tls+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_tls=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( $tls_first_major \* 1000 \) + $tls_first_minor \) \* 1000 + 0`
+ then gcc_cv_as_tls=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo "$conftest_s" > conftest.s
+ if { ac_try='$gcc_cv_as $tls_as_opt -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_tls=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
fi
- rm -f conftest.s conftest.o
fi
-if test "$gcc_cv_as_tls" = yes; then
- cat >> confdefs.h <<\EOF
+echo "$as_me:$LINENO: result: $gcc_cv_as_tls" >&5
+echo "${ECHO_T}$gcc_cv_as_tls" >&6
+if test $gcc_cv_as_tls = yes; then
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_AS_TLS 1
-EOF
+_ACEOF
fi
-echo "$ac_t""$gcc_cv_as_tls" 1>&6
+fi
+
+# Target-specific assembler checks.
case "$target" in
# All TARGET_ABI_OSF targets.
alpha*-*-osf* | alpha*-*-linux* | alpha*-*-*bsd*)
- echo $ac_n "checking assembler supports explicit relocations""... $ac_c" 1>&6
-echo "configure:7533: checking assembler supports explicit relocations" >&5
-if eval "test \"`echo '$''{'gcc_cv_as_explicit_relocs'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- gcc_cv_as_explicit_relocs=unknown
- if test x$gcc_cv_gas_major_version != x \
- -a x$gcc_cv_gas_minor_version != x
- then
- if test "$gcc_cv_gas_major_version" -eq 2 \
- -a "$gcc_cv_gas_minor_version" -ge 12 \
- -o "$gcc_cv_gas_major_version" -gt 2; then
- gcc_cv_as_explicit_relocs=yes
- fi
- elif test x$gcc_cv_as != x; then
- cat > conftest.s << 'EOF'
- .set nomacro
+ echo "$as_me:$LINENO: checking assembler for explicit relocation support" >&5
+echo $ECHO_N "checking assembler for explicit relocation support... $ECHO_C" >&6
+if test "${gcc_cv_as_alpha_explicit_relocs+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_alpha_explicit_relocs=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 12 \) \* 1000 + 0`
+ then gcc_cv_as_alpha_explicit_relocs=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo ' .set nomacro
.text
extbl $3, $2, $3 !lituse_bytoff!1
ldq $2, a($29) !literal!1
@@ -7557,309 +10524,519 @@ else
lda $0, c($29) !gprel
ldah $1, d($29) !gprelhigh
lda $1, d($1) !gprellow
- lda $29, 0($29) !gpdisp!3
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_explicit_relocs=yes
- else
- gcc_cv_as_explicit_relocs=no
- fi
- rm -f conftest.s conftest.o
- fi
-
+ lda $29, 0($29) !gpdisp!3' > 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_alpha_explicit_relocs=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_alpha_explicit_relocs" >&5
+echo "${ECHO_T}$gcc_cv_as_alpha_explicit_relocs" >&6
+if test $gcc_cv_as_alpha_explicit_relocs = yes; then
-echo "$ac_t""$gcc_cv_as_explicit_relocs" 1>&6
- if test "x$gcc_cv_as_explicit_relocs" = xyes; then
- cat >> confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
#define HAVE_AS_EXPLICIT_RELOCS 1
-EOF
+_ACEOF
+
+fi
+ ;;
+ cris-*-*)
+ echo "$as_me:$LINENO: checking assembler for -no-mul-bug-abort option" >&5
+echo $ECHO_N "checking assembler for -no-mul-bug-abort option... $ECHO_C" >&6
+if test "${gcc_cv_as_cris_no_mul_bug+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_cris_no_mul_bug=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 15 \) \* 1000 + 91`
+ then gcc_cv_as_cris_no_mul_bug=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo '.text' > conftest.s
+ if { ac_try='$gcc_cv_as -no-mul-bug-abort -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_cris_no_mul_bug=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_cris_no_mul_bug" >&5
+echo "${ECHO_T}$gcc_cv_as_cris_no_mul_bug" >&6
+if test $gcc_cv_as_cris_no_mul_bug = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AS_NO_MUL_BUG_ABORT_OPTION 1
+_ACEOF
+
+fi
;;
+
sparc*-*-*)
- echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
-echo "configure:7583: checking assembler .register pseudo-op support" >&5
-if eval "test \"`echo '$''{'gcc_cv_as_register_pseudo_op'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- gcc_cv_as_register_pseudo_op=unknown
- if test x$gcc_cv_as != x; then
- # Check if we have .register
- echo ".register %g2, #scratch" > conftest.s
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_register_pseudo_op=yes
- else
- gcc_cv_as_register_pseudo_op=no
- fi
- rm -f conftest.s conftest.o
- fi
-
+ echo "$as_me:$LINENO: checking assembler for .register" >&5
+echo $ECHO_N "checking assembler for .register... $ECHO_C" >&6
+if test "${gcc_cv_as_sparc_register_op+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_sparc_register_op=no
+ if test x$gcc_cv_as != x; then
+ echo '.register %g2, #scratch' > 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_sparc_register_op=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_sparc_register_op" >&5
+echo "${ECHO_T}$gcc_cv_as_sparc_register_op" >&6
+if test $gcc_cv_as_sparc_register_op = yes; then
-echo "$ac_t""$gcc_cv_as_register_pseudo_op" 1>&6
- if test "x$gcc_cv_as_register_pseudo_op" = xyes; then
- cat >> confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
#define HAVE_AS_REGISTER_PSEUDO_OP 1
-EOF
+_ACEOF
- fi
+fi
- echo $ac_n "checking assembler supports -relax""... $ac_c" 1>&6
-echo "configure:7611: checking assembler supports -relax" >&5
-if eval "test \"`echo '$''{'gcc_cv_as_relax_opt'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- gcc_cv_as_relax_opt=unknown
- if test x$gcc_cv_as != x; then
- # Check if gas supports -relax
- echo ".text" > conftest.s
- if $gcc_cv_as -relax -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_relax_opt=yes
- else
- gcc_cv_as_relax_opt=no
- fi
- rm -f conftest.s conftest.o
- fi
-
+ echo "$as_me:$LINENO: checking assembler for -relax option" >&5
+echo $ECHO_N "checking assembler for -relax option... $ECHO_C" >&6
+if test "${gcc_cv_as_sparc_relax+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_sparc_relax=no
+ if test x$gcc_cv_as != x; then
+ echo '.text' > conftest.s
+ if { ac_try='$gcc_cv_as -relax -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_sparc_relax=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_sparc_relax" >&5
+echo "${ECHO_T}$gcc_cv_as_sparc_relax" >&6
+if test $gcc_cv_as_sparc_relax = yes; then
-echo "$ac_t""$gcc_cv_as_relax_opt" 1>&6
- if test "x$gcc_cv_as_relax_opt" = xyes; then
- cat >> confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
#define HAVE_AS_RELAX_OPTION 1
-EOF
-
- fi
+_ACEOF
- echo $ac_n "checking assembler and linker support unaligned pc related relocs""... $ac_c" 1>&6
-echo "configure:7639: checking assembler and linker support unaligned pc related relocs" >&5
-if eval "test \"`echo '$''{'gcc_cv_as_sparc_ua_pcrel'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- gcc_cv_as_sparc_ua_pcrel=unknown
- if test x$gcc_cv_as != x -a x$gcc_cv_ld != x; then
- gcc_cv_as_sparc_ua_pcrel=no
- echo ".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo)" > conftest.s
- if $gcc_cv_as -K PIC -o conftest.o conftest.s > /dev/null 2>&1 \
- && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
- gcc_cv_as_sparc_ua_pcrel=yes
- fi
- rm -f conftest.s conftest.o conftest
- fi
-
fi
-echo "$ac_t""$gcc_cv_as_sparc_ua_pcrel" 1>&6
- if test "x$gcc_cv_as_sparc_ua_pcrel" = xyes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_AS_SPARC_UA_PCREL 1
-EOF
-
+ echo "$as_me:$LINENO: checking assembler for unaligned pcrel relocs" >&5
+echo $ECHO_N "checking assembler for unaligned pcrel relocs... $ECHO_C" >&6
+if test "${gcc_cv_as_sparc_ua_pcrel+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_sparc_ua_pcrel=no
+ if test x$gcc_cv_as != x; then
+ echo '.text
+foo:
+ nop
+.data
+.align 4
+.byte 0
+.uaword %r_disp32(foo)' > conftest.s
+ if { ac_try='$gcc_cv_as -K PIC -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
+ if test x$gcc_cv_ld != x \
+ && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
+ gcc_cv_as_sparc_ua_pcrel=yes
+ fi
+ rm -f conftest
+ 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_sparc_ua_pcrel" >&5
+echo "${ECHO_T}$gcc_cv_as_sparc_ua_pcrel" >&6
+if test $gcc_cv_as_sparc_ua_pcrel = yes; then
- echo $ac_n "checking assembler and linker support unaligned pc related relocs against hidden symbols""... $ac_c" 1>&6
-echo "configure:7666: checking assembler and linker support unaligned pc related relocs against hidden symbols" >&5
-if eval "test \"`echo '$''{'gcc_cv_as_sparc_ua_pcrel_hidden'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- if test "x$gcc_cv_as_sparc_ua_pcrel" = xyes; then
- gcc_cv_as_sparc_ua_pcrel_hidden=unknown
- if test x$gcc_cv_objdump != x; then
- gcc_cv_as_sparc_ua_pcrel_hidden=no
- echo ".data; .align 4; .byte 0x31; .uaword %r_disp32(foo)" > conftest.s
- echo ".byte 0x32, 0x33, 0x34; .global foo; .hidden foo" >> conftest.s
- echo "foo: .skip 4" >> conftest.s
- if $gcc_cv_as -K PIC -o conftest.o conftest.s > /dev/null 2>&1 \
- && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1 \
- && $gcc_cv_objdump -s -j .data conftest 2> /dev/null \
- | grep ' 31000000 07323334' > /dev/null 2>&1; then
- if $gcc_cv_objdump -R conftest 2> /dev/null \
- | grep 'DISP32' > /dev/null 2>&1; then
- :
- else
- gcc_cv_as_sparc_ua_pcrel_hidden=yes
- fi
- fi
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AS_SPARC_UA_PCREL 1
+_ACEOF
+
+
+ echo "$as_me:$LINENO: checking assembler for unaligned pcrel relocs against hidden symbols" >&5
+echo $ECHO_N "checking assembler for unaligned pcrel relocs against hidden symbols... $ECHO_C" >&6
+if test "${gcc_cv_as_sparc_ua_pcrel_hidden+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_sparc_ua_pcrel_hidden=no
+ if test x$gcc_cv_as != x; then
+ echo '.data
+.align 4
+.byte 0x31
+.uaword %r_disp32(foo)
+.byte 0x32, 0x33, 0x34
+.global foo
+.hidden foo
+foo:
+.skip 4' > conftest.s
+ if { ac_try='$gcc_cv_as -K PIC -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
+ if test x$gcc_cv_ld != x && test x$gcc_cv_objdump != x \
+ && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1 \
+ && $gcc_cv_objdump -s -j .data conftest 2> /dev/null \
+ | grep ' 31000000 07323334' > /dev/null 2>&1; then
+ if $gcc_cv_objdump -R conftest 2> /dev/null \
+ | grep 'DISP32' > /dev/null 2>&1; then
+ :
+ else
+ gcc_cv_as_sparc_ua_pcrel_hidden=yes
fi
- rm -f conftest.s conftest.o conftest
- else
- gcc_cv_as_sparc_ua_pcrel_hidden="$gcc_cv_as_sparc_ua_pcrel"
- fi
-
+ fi
+ rm -f conftest
+ 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_sparc_ua_pcrel_hidden" >&5
+echo "${ECHO_T}$gcc_cv_as_sparc_ua_pcrel_hidden" >&6
+if test $gcc_cv_as_sparc_ua_pcrel_hidden = yes; then
-echo "$ac_t""$gcc_cv_as_sparc_ua_pcrel_hidden" 1>&6
- if test "x$gcc_cv_as_sparc_ua_pcrel_hidden" = xyes; then
- cat >> confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
#define HAVE_AS_SPARC_UA_PCREL_HIDDEN 1
-EOF
-
- fi
+_ACEOF
- echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6
-echo "configure:7706: checking for assembler offsetable %lo() support" >&5
-if eval "test \"`echo '$''{'gcc_cv_as_offsetable_lo10'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- gcc_cv_as_offsetable_lo10=unknown
- if test "x$gcc_cv_as" != x; then
- # Check if assembler has offsetable %lo()
- echo "or %g1, %lo(ab) + 12, %g1" > conftest.s
- echo "or %g1, %lo(ab + 12), %g1" > conftest1.s
- if $gcc_cv_as -xarch=v9 -o conftest.o conftest.s \
- > /dev/null 2>&1 &&
- $gcc_cv_as -xarch=v9 -o conftest1.o conftest1.s \
- > /dev/null 2>&1; then
- if cmp conftest.o conftest1.o > /dev/null 2>&1; then
- gcc_cv_as_offsetable_lo10=no
- else
- gcc_cv_as_offsetable_lo10=yes
- fi
- else
- gcc_cv_as_offsetable_lo10=no
- fi
- rm -f conftest.s conftest.o conftest1.s conftest1.o
- fi
-
fi
-echo "$ac_t""$gcc_cv_as_offsetable_lo10" 1>&6
- if test "x$gcc_cv_as_offsetable_lo10" = xyes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_AS_OFFSETABLE_LO10 1
-EOF
+fi # unaligned pcrel relocs
+ echo "$as_me:$LINENO: checking assembler for offsetable %lo()" >&5
+echo $ECHO_N "checking assembler for offsetable %lo()... $ECHO_C" >&6
+if test "${gcc_cv_as_sparc_offsetable_lo10+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_sparc_offsetable_lo10=no
+ if test x$gcc_cv_as != x; then
+ echo '.text
+ or %g1, %lo(ab) + 12, %g1
+ or %g1, %lo(ab + 12), %g1' > conftest.s
+ if { ac_try='$gcc_cv_as -xarch=v9 -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
+ if test x$gcc_cv_objdump != x \
+ && $gcc_cv_objdump -s -j .text conftest.o 2> /dev/null \
+ | grep ' 82106000 82106000' > /dev/null 2>&1; then
+ gcc_cv_as_offsetable_lo10=yes
+ fi
+ 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_sparc_offsetable_lo10" >&5
+echo "${ECHO_T}$gcc_cv_as_sparc_offsetable_lo10" >&6
+if test $gcc_cv_as_sparc_offsetable_lo10 = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AS_OFFSETABLE_LO10 1
+_ACEOF
+fi
;;
i[34567]86-*-* | x86_64-*-*)
- echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
-echo "configure:7745: checking assembler instructions" >&5
- gcc_cv_as_instructions=
- if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x; then
- if test "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 9 -o "$gcc_cv_gas_major_version" -gt 2; then
- gcc_cv_as_instructions="filds fists"
- fi
- elif test x$gcc_cv_as != x; then
- set "filds fists" "filds mem; fists mem"
- while test $# -gt 0
- do
- echo "$2" > conftest.s
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_instructions=${gcc_cv_as_instructions}$1" "
- fi
- shift 2
- done
- rm -f conftest.s conftest.o
+ echo "$as_me:$LINENO: checking assembler for filds and fists mnemonics" >&5
+echo $ECHO_N "checking assembler for filds and fists mnemonics... $ECHO_C" >&6
+if test "${gcc_cv_as_ix86_filds_fists+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_ix86_filds_fists=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 9 \) \* 1000 + 0`
+ then gcc_cv_as_ix86_filds_fists=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo 'filds mem; fists mem' > 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_ix86_filds_fists=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
fi
- if test x"$gcc_cv_as_instructions" != x; then
- cat >> confdefs.h <<EOF
-#define HAVE_GAS_`echo "$gcc_cv_as_instructions" | sed -e 's/ $//' | tr 'a-z ' 'A-Z_'` 1
-EOF
+ rm -f conftest.o conftest.s
+ fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_ix86_filds_fists" >&5
+echo "${ECHO_T}$gcc_cv_as_ix86_filds_fists" >&6
+if test $gcc_cv_as_ix86_filds_fists = yes; then
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GAS_FILDS_FISTS 1
+_ACEOF
+
+fi
+
+ echo "$as_me:$LINENO: checking assembler for cmov syntax" >&5
+echo $ECHO_N "checking assembler for cmov syntax... $ECHO_C" >&6
+if test "${gcc_cv_as_ix86_cmov_sun_syntax+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_ix86_cmov_sun_syntax=no
+ if test x$gcc_cv_as != x; then
+ echo 'cmovl.l %edx, %eax' > 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_ix86_cmov_sun_syntax=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
fi
- echo "$ac_t""$gcc_cv_as_instructions" 1>&6
-
- echo $ac_n "checking cmov syntax""... $ac_c" 1>&6
-echo "configure:7772: checking cmov syntax" >&5
- gcc_cv_as_ix86_cmov_sun_syntax=no
- if test x$gcc_cv_as != x; then
- echo 'cmovl.l %edx, %eax' > conftest.s
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_ix86_cmov_sun_syntax=yes
- fi
- rm -f conftest.s conftest.o
- fi
- if test "x$gcc_cv_as_ix86_cmov_sun_syntax" = xyes; then
- cat >> confdefs.h <<\EOF
+ rm -f conftest.o conftest.s
+ fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_ix86_cmov_sun_syntax" >&5
+echo "${ECHO_T}$gcc_cv_as_ix86_cmov_sun_syntax" >&6
+if test $gcc_cv_as_ix86_cmov_sun_syntax = yes; then
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_AS_IX86_CMOV_SUN_SYNTAX 1
-EOF
+_ACEOF
- fi
- echo "$ac_t""$gcc_cv_as_ix86_cmov_sun_syntax" 1>&6
+fi
- echo $ac_n "checking assembler GOTOFF in data directives""... $ac_c" 1>&6
-echo "configure:7790: checking assembler GOTOFF in data directives" >&5
- gcc_cv_as_gotoff_in_data=no
- if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x
- then
- if test "$gcc_cv_gas_major_version" -eq 2 \
- -a "$gcc_cv_gas_minor_version" -ge 11 \
- -o "$gcc_cv_gas_major_version" -gt 2; then
- gcc_cv_as_gotoff_in_data=yes
- fi
- elif test x$gcc_cv_as != x; then
- cat > conftest.s <<EOF
- .text
+ # This one is used unconditionally by i386.[ch]; it is to be defined
+ # to 1 if the feature is present, 0 otherwise.
+ echo "$as_me:$LINENO: checking assembler for GOTOFF in data" >&5
+echo $ECHO_N "checking assembler for GOTOFF in data... $ECHO_C" >&6
+if test "${gcc_cv_as_ix86_gotoff_in_data+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_ix86_gotoff_in_data=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 11 \) \* 1000 + 0`
+ then gcc_cv_as_ix86_gotoff_in_data=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo ' .text
.L0:
nop
.data
- .long .L0@GOTOFF
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_gotoff_in_data=yes
- fi
+ .long .L0@GOTOFF' > 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_ix86_gotoff_in_data=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
fi
- cat >> confdefs.h <<EOF
-#define HAVE_AS_GOTOFF_IN_DATA `if test $gcc_cv_as_gotoff_in_data = yes; then echo 1; else echo 0; fi`
-EOF
+ rm -f conftest.o conftest.s
+ fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_ix86_gotoff_in_data" >&5
+echo "${ECHO_T}$gcc_cv_as_ix86_gotoff_in_data" >&6
+
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_AS_GOTOFF_IN_DATA `if test $gcc_cv_as_ix86_gotoff_in_data = yes; then echo 1; else echo 0; fi`
+_ACEOF
- echo "$ac_t""$gcc_cv_as_gotoff_in_data" 1>&6
;;
ia64*-*-*)
- echo $ac_n "checking assembler supports ltoffx and ldxmov""... $ac_c" 1>&6
-echo "configure:7820: checking assembler supports ltoffx and ldxmov" >&5
-if eval "test \"`echo '$''{'gcc_cv_as_ltoffx_ldxmov_relocs'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- gcc_cv_as_ltoffx_ldxmov_relocs=unknown
- if test x$gcc_cv_gas_major_version != x \
- -a x$gcc_cv_gas_minor_version != x
- then
- if test "$gcc_cv_gas_major_version" -eq 2 \
- -a "$gcc_cv_gas_minor_version" -ge 14 \
- -o "$gcc_cv_gas_major_version" -gt 2; then
- gcc_cv_as_ltoffx_ldxmov_relocs=yes
- fi
- elif test x$gcc_cv_as != x; then
- cat > conftest.s << 'EOF'
- .text
+ echo "$as_me:$LINENO: checking assembler for ltoffx and ldxmov relocs" >&5
+echo $ECHO_N "checking assembler for ltoffx and ldxmov relocs... $ECHO_C" >&6
+if test "${gcc_cv_as_ia64_ltoffx_ldxmov_relocs+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_ia64_ltoffx_ldxmov_relocs=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 14 \) \* 1000 + 0`
+ then gcc_cv_as_ia64_ltoffx_ldxmov_relocs=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo ' .text
addl r15 = @ltoffx(x#), gp
;;
- ld8.mov r16 = [r15], x#
-EOF
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
- gcc_cv_as_ltoffx_ldxmov_relocs=yes
- else
- gcc_cv_as_ltoffx_ldxmov_relocs=no
- fi
- rm -f conftest.s conftest.o
- fi
-
+ ld8.mov r16 = [r15], x#' > 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_ia64_ltoffx_ldxmov_relocs=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_ia64_ltoffx_ldxmov_relocs" >&5
+echo "${ECHO_T}$gcc_cv_as_ia64_ltoffx_ldxmov_relocs" >&6
+if test $gcc_cv_as_ia64_ltoffx_ldxmov_relocs = yes; then
-echo "$ac_t""$gcc_cv_as_ltoffx_ldxmov_relocs" 1>&6
- if test "x$gcc_cv_as_ltoffx_ldxmov_relocs" = xyes; then
- cat >> confdefs.h <<\EOF
+cat >>confdefs.h <<\_ACEOF
#define HAVE_AS_LTOFFX_LDXMOV_RELOCS 1
-EOF
+_ACEOF
+
+fi
+
+ ;;
+
+ powerpc*-*-*)
+ case $target in
+ *-*-aix*) conftest_s=' .csect .text[PR]
+ mfcr 3,128';;
+ *-*-darwin*) conftest_s=' .text
+ mfcr r3,128';;
+ *) conftest_s=' .text
+ mfcr 3,128';;
+ esac
+
+ echo "$as_me:$LINENO: checking assembler for mfcr field support" >&5
+echo $ECHO_N "checking assembler for mfcr field support... $ECHO_C" >&6
+if test "${gcc_cv_as_powerpc_mfcrf+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_powerpc_mfcrf=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 14 \) \* 1000 + 0`
+ then gcc_cv_as_powerpc_mfcrf=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo "$conftest_s" > 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_powerpc_mfcrf=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_powerpc_mfcrf" >&5
+echo "${ECHO_T}$gcc_cv_as_powerpc_mfcrf" >&6
+if test $gcc_cv_as_powerpc_mfcrf = yes; then
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AS_MFCRF 1
+_ACEOF
+
+fi
+ ;;
+
+ mips*-*-*)
+ echo "$as_me:$LINENO: checking assembler for explicit relocation support" >&5
+echo $ECHO_N "checking assembler for explicit relocation support... $ECHO_C" >&6
+if test "${gcc_cv_as_mips_explicit_relocs+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_mips_explicit_relocs=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 14 \) \* 1000 + 0`
+ then gcc_cv_as_mips_explicit_relocs=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo ' lw $4,%gp_rel(foo)($4)' > 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_mips_explicit_relocs=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_mips_explicit_relocs" >&5
+echo "${ECHO_T}$gcc_cv_as_mips_explicit_relocs" >&6
+if test $gcc_cv_as_mips_explicit_relocs = yes; then
+ if test x$target_cpu_default = x
+ then target_cpu_default=MASK_EXPLICIT_RELOCS
+ else target_cpu_default="($target_cpu_default)|MASK_EXPLICIT_RELOCS"
+ fi
+fi
+
;;
esac
-
-echo $ac_n "checking assembler dwarf2 debug_line support""... $ac_c" 1>&6
-echo "configure:7862: checking assembler dwarf2 debug_line support" >&5
-gcc_cv_as_dwarf2_debug_line=no
# ??? Not all targets support dwarf2 debug_line, even within a version
# of gas. Moreover, we need to emit a valid instruction to trigger any
# info to the output file. So, as supported targets are added to gas 2.11,
@@ -7868,121 +11045,192 @@ gcc_cv_as_dwarf2_debug_line=no
# version to the per-target configury.
case "$target" in
i?86*-*-* | mips*-*-* | alpha*-*-* | powerpc*-*-* | sparc*-*-* | m68*-*-* \
- | x86_64*-*-* | hppa*-*-* | arm*-*-* | strongarm*-*-* | xscale*-*-*)
+ | x86_64*-*-* | hppa*-*-* | arm*-*-* | strongarm*-*-* | xscale*-*-* \
+ | xstormy16*-*-* | cris-*-* | xtensa-*-*)
insn="nop"
;;
- ia64*-*-*)
+ ia64*-*-* | s390*-*-*)
insn="nop 0"
;;
- esac
-if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x;
-then
- if test "$gcc_cv_gas_major_version" -eq 2 \
- -a "$gcc_cv_gas_minor_version" -ge 11 \
- -o "$gcc_cv_gas_major_version" -gt 2 \
- && grep 'obj_format = elf' ../gas/Makefile > /dev/null \
- && test x"$insn" != x ; then
- gcc_cv_as_dwarf2_debug_line="yes"
+ mmix-*-*)
+ insn="swym 0"
+ ;;
+esac
+if test x"$insn" != x; then
+ conftest_s="\
+ .file 1 \"conftest.s\"
+ .loc 1 3 0
+ $insn"
+ echo "$as_me:$LINENO: checking assembler for dwarf2 debug_line support" >&5
+echo $ECHO_N "checking assembler for dwarf2 debug_line support... $ECHO_C" >&6
+if test "${gcc_cv_as_dwarf2_debug_line+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_dwarf2_debug_line=no
+ if test $in_tree_gas = yes; then
+ if test $in_tree_gas_is_elf = yes \
+ && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 11 \) \* 1000 + 0`
+ then gcc_cv_as_dwarf2_debug_line=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo "$conftest_s" > 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
+ # ??? This fails with non-gnu grep. Maybe use objdump?
+ if grep debug_line conftest.o > /dev/null 2>&1; then
+ gcc_cv_as_dwarf2_debug_line=yes
+ fi
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
fi
-elif test x$gcc_cv_as != x -a x"$insn" != x ; then
- echo ' .file 1 "conftest.s"' > conftest.s
- echo ' .loc 1 3 0' >> conftest.s
- echo " $insn" >> conftest.s
- # ??? This fails with non-gnu grep.
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \
- && grep debug_line conftest.o > /dev/null 2>&1 ; then
- # The .debug_line file table must be in the exact order that
- # we specified the files, since these indices are also used
- # by DW_AT_decl_file. Approximate this test by testing if
- # the assembler bitches if the same index is assigned twice.
- echo ' .file 1 "foo.s"' > conftest.s
- echo ' .file 1 "bar.s"' >> conftest.s
- if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1
- then
- gcc_cv_as_dwarf2_debug_line="no"
- else
- gcc_cv_as_dwarf2_debug_line="yes"
- fi
- fi
- rm -f conftest.s conftest.o conftest.nm1 conftest.nm2
fi
-if test x"$gcc_cv_as_dwarf2_debug_line" = xyes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_AS_DWARF2_DEBUG_LINE 1
-EOF
-
+echo "$as_me:$LINENO: result: $gcc_cv_as_dwarf2_debug_line" >&5
+echo "${ECHO_T}$gcc_cv_as_dwarf2_debug_line" >&6
+
+
+# The .debug_line file table must be in the exact order that
+# we specified the files, since these indices are also used
+# by DW_AT_decl_file. Approximate this test by testing if
+# the assembler bitches if the same index is assigned twice.
+ echo "$as_me:$LINENO: checking assembler for buggy dwarf2 .file directive" >&5
+echo $ECHO_N "checking assembler for buggy dwarf2 .file directive... $ECHO_C" >&6
+if test "${gcc_cv_as_dwarf2_file_buggy+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_dwarf2_file_buggy=no
+ if test x$gcc_cv_as != x; then
+ echo ' .file 1 "foo.s"
+ .file 1 "bar.s"' > 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_dwarf2_file_buggy=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
fi
-echo "$ac_t""$gcc_cv_as_dwarf2_debug_line" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_as_dwarf2_file_buggy" >&5
+echo "${ECHO_T}$gcc_cv_as_dwarf2_file_buggy" >&6
-echo $ac_n "checking assembler --gdwarf2 support""... $ac_c" 1>&6
-echo "configure:7919: checking assembler --gdwarf2 support" >&5
-gcc_cv_as_gdwarf2_flag=no
-if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x;
-then
- if test "$gcc_cv_gas_major_version" -eq 2 \
- -a "$gcc_cv_gas_minor_version" -ge 11 \
- -o "$gcc_cv_gas_major_version" -gt 2 \
- && grep 'obj_format = elf' ../gas/Makefile > /dev/null \
- && test x"$insn" != x ; then
- gcc_cv_as_gdwarf2_flag="yes"
+
+ if test $gcc_cv_as_dwarf2_debug_line = yes \
+ && test $gcc_cv_as_dwarf2_file_buggy = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AS_DWARF2_DEBUG_LINE 1
+_ACEOF
+
+ fi
+
+ echo "$as_me:$LINENO: checking assembler for --gdwarf2 option" >&5
+echo $ECHO_N "checking assembler for --gdwarf2 option... $ECHO_C" >&6
+if test "${gcc_cv_as_gdwarf2_flag+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_gdwarf2_flag=no
+ if test $in_tree_gas = yes; then
+ if test $in_tree_gas_is_elf = yes \
+ && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 11 \) \* 1000 + 0`
+ then gcc_cv_as_gdwarf2_flag=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo "$insn" > conftest.s
+ if { ac_try='$gcc_cv_as --gdwarf2 -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_gdwarf2_flag=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
fi
-elif test x$gcc_cv_as != x -a x"$insn" != x ; then
- echo '' > conftest.s
- # ??? This fails with non-gnu grep.
- if $gcc_cv_as --gdwarf2 -o conftest.o conftest.s > /dev/null 2>&1
- then
- gcc_cv_as_gdwarf2_flag="yes"
- fi
- rm -f conftest.s conftest.o
fi
-if test x"$gcc_cv_as_gdwarf2_flag" = xyes; then
- cat >> confdefs.h <<\EOF
+echo "$as_me:$LINENO: result: $gcc_cv_as_gdwarf2_flag" >&5
+echo "${ECHO_T}$gcc_cv_as_gdwarf2_flag" >&6
+if test $gcc_cv_as_gdwarf2_flag = yes; then
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_AS_GDWARF2_DEBUG_FLAG 1
-EOF
+_ACEOF
fi
-echo "$ac_t""$gcc_cv_as_gdwarf2_flag" 1>&6
-echo $ac_n "checking assembler --gstabs support""... $ac_c" 1>&6
-echo "configure:7948: checking assembler --gstabs support" >&5
-gcc_cv_as_gstabs_flag=no
-if test x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x;
-then
- if test "$gcc_cv_gas_major_version" -eq 2 \
- -a "$gcc_cv_gas_minor_version" -ge 11 \
- -o "$gcc_cv_gas_major_version" -gt 2 \
- && grep 'obj_format = elf' ../gas/Makefile > /dev/null \
- && test x"$insn" != x ; then
- gcc_cv_as_gstabs_flag="yes"
+ echo "$as_me:$LINENO: checking assembler for --gstabs option" >&5
+echo $ECHO_N "checking assembler for --gstabs option... $ECHO_C" >&6
+if test "${gcc_cv_as_gstabs_flag+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_gstabs_flag=no
+ if test $in_tree_gas = yes; then
+ if test $in_tree_gas_is_elf = yes \
+ && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 11 \) \* 1000 + 0`
+ then gcc_cv_as_gstabs_flag=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo "$insn" > conftest.s
+ if { ac_try='$gcc_cv_as --gstabs -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
+ # The native Solaris 9/Intel assembler doesn't understand --gstabs
+ # and warns about it, but still exits successfully. So check for
+ # this.
+ if { ac_try='$gcc_cv_as --gstabs -o conftest.o conftest.s 2>&1 | grep -i warning > /dev/null'
+ { (eval 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 :
+ else gcc_cv_as_gstabs_flag=yes
+ fi
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
fi
-elif test x$gcc_cv_as != x -a x"$insn" != x ; then
- echo '' > conftest.s
- # ??? This fails with non-gnu grep.
- if $gcc_cv_as --gstabs -o conftest.o conftest.s > /dev/null 2>&1 ; then
- gcc_cv_as_gstabs_flag="yes"
- # The native Solaris 9/Intel assembler doesn't understand --gstabs
- # and warns about it, but still exits successfully. So check for
- # this.
- if $gcc_cv_as --gstabs -o conftest.o conftest.s 2>&1 | \
- grep -i warning > /dev/null ; then
- gcc_cv_as_gstabs_flag="no"
- fi
- fi
- rm -f conftest.s conftest.o
fi
-if test x"$gcc_cv_as_gstabs_flag" = xyes; then
- cat >> confdefs.h <<\EOF
+echo "$as_me:$LINENO: result: $gcc_cv_as_gstabs_flag" >&5
+echo "${ECHO_T}$gcc_cv_as_gstabs_flag" >&6
+if test $gcc_cv_as_gstabs_flag = yes; then
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_AS_GSTABS_DEBUG_FLAG 1
-EOF
+_ACEOF
fi
-echo "$ac_t""$gcc_cv_as_gstabs_flag" 1>&6
+fi
-echo $ac_n "checking linker read-only and read-write section mixing""... $ac_c" 1>&6
-echo "configure:7983: checking linker read-only and read-write section mixing" >&5
+echo "$as_me:$LINENO: checking linker read-only and read-write section mixing" >&5
+echo $ECHO_N "checking linker read-only and read-write section mixing... $ECHO_C" >&6
gcc_cv_ld_ro_rw_mix=unknown
-if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 10 -o "$gcc_cv_gld_major_version" -gt 2 && grep 'EMUL = elf' ../ld/Makefile > /dev/null; then
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 10 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
gcc_cv_ld_ro_rw_mix=read-write
fi
elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then
@@ -8009,18 +11257,21 @@ elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then
rm -f conftest.* conftest[123].*
fi
if test x$gcc_cv_ld_ro_rw_mix = xread-write; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_LD_RO_RW_SECTION_MIXING 1
-EOF
+_ACEOF
fi
-echo "$ac_t""$gcc_cv_ld_ro_rw_mix" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_ld_ro_rw_mix" >&5
+echo "${ECHO_T}$gcc_cv_ld_ro_rw_mix" >&6
-echo $ac_n "checking linker PT_GNU_EH_FRAME support""... $ac_c" 1>&6
-echo "configure:8021: checking linker PT_GNU_EH_FRAME support" >&5
+echo "$as_me:$LINENO: checking linker PT_GNU_EH_FRAME support" >&5
+echo $ECHO_N "checking linker PT_GNU_EH_FRAME support... $ECHO_C" >&6
gcc_cv_ld_eh_frame_hdr=no
-if test x$gcc_cv_gld_major_version != x -a x$gcc_cv_gld_minor_version != x; then
- if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 12 -o "$gcc_cv_gld_major_version" -gt 2 && grep 'EMUL = elf' ../ld/Makefile > /dev/null; then
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 12 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
gcc_cv_ld_eh_frame_hdr=yes
fi
elif test x$gcc_cv_ld != x; then
@@ -8030,50 +11281,78 @@ elif test x$gcc_cv_ld != x; then
fi
fi
if test x"$gcc_cv_ld_eh_frame_hdr" = xyes; then
- cat >> confdefs.h <<\EOF
+
+cat >>confdefs.h <<\_ACEOF
#define HAVE_LD_EH_FRAME_HDR 1
-EOF
+_ACEOF
fi
-echo "$ac_t""$gcc_cv_ld_eh_frame_hdr" 1>&6
+echo "$as_me:$LINENO: result: $gcc_cv_ld_eh_frame_hdr" >&5
+echo "${ECHO_T}$gcc_cv_ld_eh_frame_hdr" >&6
+
+echo "$as_me:$LINENO: checking linker position independent executable support" >&5
+echo $ECHO_N "checking linker position independent executable support... $ECHO_C" >&6
+gcc_cv_ld_pie=no
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 15 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_pie=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports -pie option
+ if $gcc_cv_ld --help 2>/dev/null | grep -- -pie > /dev/null; then
+ gcc_cv_ld_pie=yes
+ fi
+fi
+if test x"$gcc_cv_ld_pie" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LD_PIE 1
+_ACEOF
+
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_ld_pie" >&5
+echo "${ECHO_T}$gcc_cv_ld_pie" >&6
-# Miscellaneous target-specific checks.
case "$target" in
- mips*-*-*)
- echo $ac_n "checking whether libgloss uses STARTUP directives consistently""... $ac_c" 1>&6
-echo "configure:8045: checking whether libgloss uses STARTUP directives consistently" >&5
- gcc_cv_mips_libgloss_startup=no
- gcc_cv_libgloss_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/libgloss
- if test "x$exec_prefix" = xNONE; then
- if test "x$prefix" = xNONE; then
- test_prefix=/usr/local
- else
- test_prefix=$prefix
+ *-*-linux*)
+ echo "$as_me:$LINENO: checking linker --as-needed support" >&5
+echo $ECHO_N "checking linker --as-needed support... $ECHO_C" >&6
+if test "${gcc_cv_ld_as_needed+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_ld_as_needed=no
+ if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_as_needed=yes
fi
- else
- test_prefix=$exec_prefix
- fi
- for f in $gcc_cv_libgloss_srcdir/mips/idt.ld $test_prefix/$target_alias/lib/idt.ld
- do
- if grep '^STARTUP' $f > /dev/null 2>&1; then
- gcc_cv_mips_libgloss_startup=yes
- break
+ elif test x$gcc_cv_ld != x; then
+ # Check if linker supports --as-needed and --no-as-needed options
+ if $gcc_cv_ld --help 2>/dev/null | grep as-needed > /dev/null; then
+ gcc_cv_ld_as_needed=yes
fi
- done
- if test x"$gcc_cv_mips_libgloss_startup" = xyes; then
- cat >> confdefs.h <<\EOF
-#define HAVE_MIPS_LIBGLOSS_STARTUP_DIRECTIVES 1
-EOF
+ fi
+
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_ld_as_needed" >&5
+echo "${ECHO_T}$gcc_cv_ld_as_needed" >&6
+ if test x"$gcc_cv_ld_as_needed" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LD_AS_NEEDED 1
+_ACEOF
fi
- echo "$ac_t""$gcc_cv_mips_libgloss_startup" 1>&6
;;
esac
-if test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" ; then
- cat >> confdefs.h <<EOF
+if test x$with_sysroot = x && test x$host = x$target \
+ && test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" ; then
+
+cat >>confdefs.h <<_ACEOF
#define PREFIX_INCLUDE_DIR "$prefix/include"
-EOF
+_ACEOF
fi
@@ -8085,7 +11364,8 @@ fi
if test x"${enable_languages+set}" != xset; then
if test x"${LANGUAGES+set}" = xset; then
enable_languages="${LANGUAGES}"
- echo "configure: warning: setting LANGUAGES is deprecated, use --enable-languages instead" 1>&2
+ { echo "$as_me:$LINENO: WARNING: setting LANGUAGES is deprecated, use --enable-languages instead" >&5
+echo "$as_me: WARNING: setting LANGUAGES is deprecated, use --enable-languages instead" >&2;}
else
enable_languages=all
@@ -8094,7 +11374,9 @@ else
if test x"${enable_languages}" = x \
|| test x"${enable_languages}" = xyes;
then
- { echo "configure: error: --enable-languages needs at least one language argument" 1>&2; exit 1; }
+ { { echo "$as_me:$LINENO: error: --enable-languages needs at least one language argument" >&5
+echo "$as_me: error: --enable-languages needs at least one language argument" >&2;}
+ { (exit 1); exit 1; }; }
fi
fi
enable_languages=`echo "${enable_languages}" | sed -e 's/[ ,][ ,]*/,/g' -e 's/,$//'`
@@ -8102,11 +11384,9 @@ enable_languages=`echo "${enable_languages}" | sed -e 's/[ ,][ ,]*/,/g' -e 's/
# First scan to see if an enabled language requires some other language.
# We assume that a given config-lang.in will list all the language
# front ends it requires, even if some are required indirectly.
-for lang in ${srcdir}/*/config-lang.in ..
+for lang in ${srcdir}/*/config-lang.in
do
case $lang in
- ..)
- ;;
# The odd quoting in the next line works around
# an apparent bug in bash 1.12 on linux.
${srcdir}/[*]/config-lang.in)
@@ -8133,10 +11413,9 @@ done
expected_languages=`echo ,${enable_languages}, | sed -e 's:,: :g' -e 's: *: :g' -e 's: *: :g' -e 's:^ ::' -e 's: $::'`
found_languages=
subdirs=
-for lang in ${srcdir}/*/config-lang.in ..
+for lang in ${srcdir}/*/config-lang.in
do
case $lang in
- ..) ;;
# The odd quoting in the next line works around
# an apparent bug in bash 1.12 on linux.
${srcdir}/[*]/config-lang.in) ;;
@@ -8174,7 +11453,7 @@ done
missing_languages=
for expected_language in ${expected_languages} ..
-do
+do
if test "${expected_language}" != ..; then
missing_language="${expected_language}"
if test "${expected_language}" = "c" \
@@ -8182,7 +11461,7 @@ do
missing_language=
fi
for found_language in ${found_languages} ..
- do
+ do
if test "${found_language}" != ..; then
if test "${expected_language}" = "${found_language}"; then
missing_language=
@@ -8196,9 +11475,13 @@ do
done
if test "x$missing_languages" != x; then
- { echo "configure: error:
+ { { echo "$as_me:$LINENO: error:
The following requested languages were not found:${missing_languages}
-The following languages were available: c${found_languages}" 1>&2; exit 1; }
+The following languages were available: c${found_languages}" >&5
+echo "$as_me: error:
+The following requested languages were not found:${missing_languages}
+The following languages were available: c${found_languages}" >&2;}
+ { (exit 1); exit 1; }; }
fi
# Make gthr-default.h if we have a thread file.
@@ -8211,51 +11494,53 @@ fi
# Find out what GC implementation we want, or may, use.
+
# Check whether --with-gc or --without-gc was given.
if test "${with_gc+set}" = set; then
withval="$with_gc"
case "$withval" in
- simple | page)
+ simple | page | zone)
GGC=ggc-$withval
;;
*)
- { echo "configure: error: $withval is an invalid option to --with-gc" 1>&2; exit 1; }
+ { { echo "$as_me:$LINENO: error: $withval is an invalid option to --with-gc" >&5
+echo "$as_me: error: $withval is an invalid option to --with-gc" >&2;}
+ { (exit 1); exit 1; }; }
;;
esac
else
GGC=ggc-page
-fi
-
+fi;
echo "Using $GGC for garbage collection."
# Use the system's zlib library.
zlibdir=-L../zlib
zlibinc="-I\$(srcdir)/../zlib"
+
# Check whether --with-system-zlib or --without-system-zlib was given.
if test "${with_system_zlib+set}" = set; then
withval="$with_system_zlib"
zlibdir=
zlibinc=
-fi
-
+fi;
-echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:8249: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6
# Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
if test "${enable_maintainer_mode+set}" = set; then
enableval="$enable_maintainer_mode"
maintainer_mode=$enableval
else
maintainer_mode=no
-fi
-
+fi;
-echo "$ac_t""$maintainer_mode" 1>&6
+echo "$as_me:$LINENO: result: $maintainer_mode" >&5
+echo "${ECHO_T}$maintainer_mode" >&6
if test "$maintainer_mode" = "yes"; then
MAINT=''
@@ -8266,17 +11551,17 @@ fi
# Make empty files to contain the specs and options for each language.
# Then add #include lines to for a compiler that has specs and/or options.
+lang_opt_files=
lang_specs_files=
-lang_options_files=
lang_tree_files=
for subdir in . $subdirs
do
+ if test -f $srcdir/$subdir/lang.opt; then
+ lang_opt_files="$lang_opt_files $srcdir/$subdir/lang.opt"
+ fi
if test -f $srcdir/$subdir/lang-specs.h; then
lang_specs_files="$lang_specs_files $srcdir/$subdir/lang-specs.h"
fi
- if test -f $srcdir/$subdir/lang-options.h; then
- lang_options_files="$lang_options_files $srcdir/$subdir/lang-options.h"
- fi
if test -f $srcdir/$subdir/$subdir-tree.def; then
lang_tree_files="$lang_tree_files $srcdir/$subdir/$subdir-tree.def"
fi
@@ -8288,8 +11573,10 @@ all_languages=
all_boot_languages=
all_compilers=
all_stagestuff=
-all_outputs='Makefile intl/Makefile fixinc/Makefile gccbug mklibgcc mkheaders'
+all_outputs='Makefile fixinc/Makefile gccbug mklibgcc mkheaders'
# List of language makefile fragments.
+all_lang_makefrags=
+# List of language subdirectory makefiles. Deprecated.
all_lang_makefiles=
# Files for gengtype
all_gtfiles="$target_gtfiles"
@@ -8304,13 +11591,10 @@ all_gtfiles_files_files=
# The other mechanism is a set of hooks for each of the main targets
# like `clean', `install', etc.
-language_fragments="Make-lang"
language_hooks="Make-hooks"
-for s in .. $subdirs
+for s in $subdirs
do
- if test $s != ".."
- then
language=
boot_language=
compilers=
@@ -8323,9 +11607,9 @@ do
echo "${srcdir}/$s/config-lang.in doesn't set \$language." 1>&2
exit 1
fi
- all_lang_makefiles="$all_lang_makefiles ${srcdir}/$s/Make-lang.in"
+ all_lang_makefrags="$all_lang_makefrags \$(srcdir)/$s/Make-lang.in"
if test -f ${srcdir}/$s/Makefile.in
- then all_lang_makefiles="$all_lang_makefiles ${srcdir}/$s/Makefile.in"
+ then all_lang_makefiles="$s/Makefile"
fi
all_languages="$all_languages $language"
if test "x$boot_language" = xyes
@@ -8336,15 +11620,11 @@ do
all_stagestuff="$all_stagestuff $stagestuff"
all_outputs="$all_outputs $outputs"
all_gtfiles="$all_gtfiles $gtfiles"
- for f in .. $gtfiles
+ for f in $gtfiles
do
- if test $f != ".."
- then
all_gtfiles_files_langs="$all_gtfiles_files_langs ${s} "
all_gtfiles_files_files="$all_gtfiles_files_files ${f} "
- fi
done
- fi
done
# Pick up gtfiles for c
@@ -8352,43 +11632,34 @@ gtfiles=
s="c"
. ${srcdir}/c-config-lang.in
all_gtfiles="$all_gtfiles $gtfiles"
-for f in .. $gtfiles
+for f in $gtfiles
do
- if test $f != ".."
- then
all_gtfiles_files_langs="$all_gtfiles_files_langs ${s} "
all_gtfiles_files_files="$all_gtfiles_files_files ${f} "
- fi
done
check_languages=
-for language in .. $all_languages
+for language in $all_languages
do
- if test $language != ".."
- then
check_languages="$check_languages check-$language"
- fi
done
-# Since we can't use `::' targets, we link each language in
-# with a set of hooks, reached indirectly via lang.${target}.
+# We link each language in with a set of hooks, reached indirectly via
+# lang.${target}.
rm -f Make-hooks
touch Make-hooks
-target_list="all.build all.cross start.encap rest.encap \
- info dvi generated-manpages \
- install-normal install-common install-info install-man \
- uninstall \
- mostlyclean clean distclean extraclean maintainer-clean \
- stage1 stage2 stage3 stage4"
+target_list="all.build all.cross start.encap rest.encap tags \
+ install-normal install-common install-man \
+ uninstall info man srcextra srcman srcinfo \
+ mostlyclean clean distclean maintainer-clean \
+ stage1 stage2 stage3 stage4 stageprofile stagefeedback"
for t in $target_list
do
x=
- for lang in .. $all_languages
+ for lang in $all_languages
do
- if test $lang != ".."; then
x="$x $lang.$t"
- fi
done
echo "lang.$t: $x" >> Make-hooks
done
@@ -8409,18 +11680,6 @@ if test "x$subdirs" != x; then
fi
echo "source ${srcdir}/gdbinit.in" >> .gdbinit
-# Define variables host_canonical and build_canonical
-# because some Cygnus local changes in the Makefile depend on them.
-build_canonical=${build}
-host_canonical=${host}
-target_subdir=
-if test "${host}" != "${target}" ; then
- target_subdir=${target_alias}/
-fi
-
-
-
-
# If $(exec_prefix) exists and is not the same as $(prefix), then compute an
# absolute path for gcc_tooldir based on inserting the number of up-directory
# movements required to get from $(exec_prefix) to $(prefix) into the basic
@@ -8429,7 +11688,7 @@ fi
# make and thus we'd get different behavior depending on where we built the
# sources.
if test x$exec_prefix = xNONE -o x$exec_prefix = x$prefix; then
- gcc_tooldir='$(libsubdir)/$(unlibsubdir)/../$(target_alias)'
+ gcc_tooldir='$(libsubdir)/$(unlibsubdir)/../$(target_noncanonical)'
else
# An explanation of the sed strings:
# -e 's|^\$(prefix)||' matches and eliminates 'prefix' from 'exec_prefix'
@@ -8453,7 +11712,7 @@ else
# /foo /foo/bar/ugg ../../
#
dollar='$$'
- gcc_tooldir="\$(libsubdir)/\$(unlibsubdir)/\`echo \$(exec_prefix) | sed -e 's|^\$(prefix)||' -e 's|/\$(dollar)||' -e 's|^[^/]|/|' -e 's|/[^/]*|../|g'\`\$(target_alias)"
+ gcc_tooldir="\$(libsubdir)/\$(unlibsubdir)/\`echo \$(exec_prefix) | sed -e 's|^\$(prefix)||' -e 's|/\$(dollar)||' -e 's|^[^/]|/|' -e 's|/[^/]*|../|g'\`\$(target_noncanonical)"
fi
@@ -8463,8 +11722,8 @@ fi
# Check whether --enable-version-specific-runtime-libs or --disable-version-specific-runtime-libs was given.
if test "${enable_version_specific_runtime_libs+set}" = set; then
enableval="$enable_version_specific_runtime_libs"
- :
-fi
+
+fi;
# Check whether --with-slibdir or --without-slibdir was given.
@@ -8479,16 +11738,12 @@ elif test "$host" != "$target"; then
else
slibdir='$(libdir)'
fi
-fi
-
+fi;
objdir=`${PWDCMD-pwd}`
-# Process the language and host/target makefile fragments.
-${CONFIG_SHELL-/bin/sh} $srcdir/configure.frag $srcdir "$subdirs" "$dep_host_xmake_file" "$dep_tmake_file"
-
# Substitute configuration variables
@@ -8558,35 +11813,30 @@ ${CONFIG_SHELL-/bin/sh} $srcdir/configure.frag $srcdir "$subdirs" "$dep_host_xma
-# Echo that links are built
-if test x$host = x$target
-then
- str1="native "
+# If it doesn't already exist, create document directory
+echo "checking for the document directory." 1>&2
+if test -d doc ; then
+ true
else
- str1="cross-"
- str2=" from $host"
-fi
-
-if test x$host != x$build
-then
- str3=" on a $build system"
-fi
-
-if test "x$str2" != x || test "x$str3" != x
-then
- str4=
-fi
-
-echo "Links are now set up to build a ${str1}compiler for ${target}$str4" 1>&2
-
-if test "x$str2" != x || test "x$str3" != x
-then
- echo " ${str2}${str3}." 1>&2
+ mkdir doc
fi
-# Truncate the target if necessary
-if test x$host_truncate_target != x; then
- target=`echo $target | sed -e 's/\(..............\).*/\1/'`
+# Echo link setup.
+if test x${build} = x${host} ; then
+ if test x${host} = x${target} ; then
+ echo "Links are now set up to build a native compiler for ${target}." 1>&2
+ else
+ echo "Links are now set up to build a cross-compiler" 1>&2
+ echo " from ${host} to ${target}." 1>&2
+ fi
+else
+ if test x${host} = x${target} ; then
+ echo "Links are now set up to build (on ${build}) a native compiler" 1>&2
+ echo " for ${target}." 1>&2
+ else
+ echo "Links are now set up to build (on ${build}) a cross-compiler" 1>&2
+ echo " from ${host} to ${target}." 1>&2
+ fi
fi
# Configure the subdirectories
@@ -8594,551 +11844,1291 @@ fi
# Create the Makefile
# and configure language subdirectories
-trap '' 1 2 15
-cat > confcache <<\EOF
+ ac_config_files="$ac_config_files $all_outputs"
+
+
+ ac_config_commands="$ac_config_commands default"
+
+cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
-# scripts and configure runs. It is not useful on other systems.
-# If it contains results you don't want to keep, you may remove or edit it.
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
#
-# By default, configure uses ./config.cache as the cache file,
-# creating it if it does not exist already. You can give configure
-# the --cache-file=FILE option to use a different cache file; that is
-# what configure does when it calls configure scripts in
-# subdirectories, so they share the cache.
-# Giving --cache-file=/dev/null disables caching, for debugging configure.
-# config.status only pays attention to the cache file if you give it the
-# --recheck option to rerun configure.
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
#
-EOF
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
-(set) 2>&1 |
- case `(ac_space=' '; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote substitution
- # turns \\\\ into \\, and sed turns \\ into \).
- sed -n \
- -e "s/'/'\\\\''/g" \
- -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
- ;;
- *)
- # `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
- ;;
- esac >> confcache
-if cmp -s $cache_file confcache; then
- :
-else
+{
+ (set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n \
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ ;;
+ esac;
+} |
+ sed '
+ t clear
+ : clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
if test -w $cache_file; then
- echo "updating cache $cache_file"
- cat confcache > $cache_file
+ test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+ cat confcache >$cache_file
else
echo "not updating unwritable cache $cache_file"
fi
fi
rm -f confcache
-trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-
test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-# Any assignment to VPATH causes Sun make to only execute
-# the first set of double-colon rules, so remove it if not needed.
-# If there is a colon in the path, we need to keep it.
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[ ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[ ]*$//;
+}'
fi
-trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
-
DEFS=-DHAVE_CONFIG_H
-# Without the "./", some shells look in PATH for config.status.
-: ${CONFIG_STATUS=./config.status}
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_i=`echo "$ac_i" |
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ # 2. Add them.
+ ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+ ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
-echo creating $CONFIG_STATUS
-rm -f $CONFIG_STATUS
-cat > $CONFIG_STATUS <<EOF
-#! /bin/sh
-# Generated automatically by configure.
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
# Run this file to recreate the current configuration.
-# This directory was configured as follows,
-# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
-#
-# $0 $ac_configure_args
-#
# Compiler output produced by configure, useful for debugging
-# configure, is in ./config.log if it exists.
+# configure, is in config.log if it exists.
-ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
-for ac_option
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization. ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+ set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+ as_unset=unset
+else
+ as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+ LC_TELEPHONE LC_TIME
do
- case "\$ac_option" in
- -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
- exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
- -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.13"
- exit 0 ;;
- -help | --help | --hel | --he | --h)
- echo "\$ac_cs_usage"; exit 0 ;;
- *) echo "\$ac_cs_usage"; exit 1 ;;
- esac
+ if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ eval $as_var=C; export $as_var
+ else
+ $as_unset $as_var
+ fi
done
-ac_given_srcdir=$srcdir
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
-trap 'rm -fr `echo "$all_outputs auto-host.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
-EOF
-cat >> $CONFIG_STATUS <<EOF
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
-# Protect against being on the right side of a sed subst in config.status.
-sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
- s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
-$ac_vpsub
-$extrasub
-s%@SHELL@%$SHELL%g
-s%@CFLAGS@%$CFLAGS%g
-s%@CPPFLAGS@%$CPPFLAGS%g
-s%@CXXFLAGS@%$CXXFLAGS%g
-s%@FFLAGS@%$FFLAGS%g
-s%@DEFS@%$DEFS%g
-s%@LDFLAGS@%$LDFLAGS%g
-s%@LIBS@%$LIBS%g
-s%@exec_prefix@%$exec_prefix%g
-s%@prefix@%$prefix%g
-s%@program_transform_name@%$program_transform_name%g
-s%@bindir@%$bindir%g
-s%@sbindir@%$sbindir%g
-s%@libexecdir@%$libexecdir%g
-s%@datadir@%$datadir%g
-s%@sysconfdir@%$sysconfdir%g
-s%@sharedstatedir@%$sharedstatedir%g
-s%@localstatedir@%$localstatedir%g
-s%@libdir@%$libdir%g
-s%@includedir@%$includedir%g
-s%@oldincludedir@%$oldincludedir%g
-s%@infodir@%$infodir%g
-s%@mandir@%$mandir%g
-s%@host@%$host%g
-s%@host_alias@%$host_alias%g
-s%@host_cpu@%$host_cpu%g
-s%@host_vendor@%$host_vendor%g
-s%@host_os@%$host_os%g
-s%@target@%$target%g
-s%@target_alias@%$target_alias%g
-s%@target_cpu@%$target_cpu%g
-s%@target_vendor@%$target_vendor%g
-s%@target_os@%$target_os%g
-s%@build@%$build%g
-s%@build_alias@%$build_alias%g
-s%@build_cpu@%$build_cpu%g
-s%@build_vendor@%$build_vendor%g
-s%@build_os@%$build_os%g
-s%@CC@%$CC%g
-s%@NO_MINUS_C_MINUS_O@%$NO_MINUS_C_MINUS_O%g
-s%@OUTPUT_OPTION@%$OUTPUT_OPTION%g
-s%@GNATBIND@%$GNATBIND%g
-s%@ADAC@%$ADAC%g
-s%@strict1_warn@%$strict1_warn%g
-s%@CPP@%$CPP%g
-s%@warn_cflags@%$warn_cflags%g
-s%@enable_multilib@%$enable_multilib%g
-s%@nocommon_flag@%$nocommon_flag%g
-s%@valgrind_path@%$valgrind_path%g
-s%@valgrind_path_defines@%$valgrind_path_defines%g
-s%@valgrind_command@%$valgrind_command%g
-s%@coverage_flags@%$coverage_flags%g
-s%@enable_shared@%$enable_shared%g
-s%@stage1_cflags@%$stage1_cflags%g
-s%@SET_MAKE@%$SET_MAKE%g
-s%@AWK@%$AWK%g
-s%@LN@%$LN%g
-s%@LN_S@%$LN_S%g
-s%@RANLIB@%$RANLIB%g
-s%@INSTALL@%$INSTALL%g
-s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
-s%@INSTALL_DATA@%$INSTALL_DATA%g
-s%@have_mktemp_command@%$have_mktemp_command%g
-s%@MAKEINFO@%$MAKEINFO%g
-s%@BUILD_INFO@%$BUILD_INFO%g
-s%@GENERATED_MANPAGES@%$GENERATED_MANPAGES%g
-s%@FLEX@%$FLEX%g
-s%@BISON@%$BISON%g
-s%@COLLECT2_LIBS@%$COLLECT2_LIBS%g
-s%@GNAT_LIBEXC@%$GNAT_LIBEXC%g
-s%@LDEXP_LIB@%$LDEXP_LIB%g
-s%@TARGET_GETGROUPS_T@%$TARGET_GETGROUPS_T%g
-s%@LIBICONV@%$LIBICONV%g
-s%@gcc_cv_initfinit_array@%$gcc_cv_initfinit_array%g
-s%@manext@%$manext%g
-s%@objext@%$objext%g
-s%@extra_modes_file@%$extra_modes_file%g
-s%@FORBUILD@%$FORBUILD%g
-s%@PACKAGE@%$PACKAGE%g
-s%@VERSION@%$VERSION%g
-s%@ALLOCA@%$ALLOCA%g
-s%@GLIBC21@%$GLIBC21%g
-s%@USE_NLS@%$USE_NLS%g
-s%@MSGFMT@%$MSGFMT%g
-s%@GMSGFMT@%$GMSGFMT%g
-s%@XGETTEXT@%$XGETTEXT%g
-s%@INTLBISON@%$INTLBISON%g
-s%@BUILD_INCLUDED_LIBINTL@%$BUILD_INCLUDED_LIBINTL%g
-s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
-s%@CATALOGS@%$CATALOGS%g
-s%@CATOBJEXT@%$CATOBJEXT%g
-s%@INTLLIBS@%$INTLLIBS%g
-s%@INTLDEPS@%$INTLDEPS%g
-s%@INTLOBJS@%$INTLOBJS%g
-s%@POSUB@%$POSUB%g
-s%@DATADIRNAME@%$DATADIRNAME%g
-s%@INSTOBJEXT@%$INSTOBJEXT%g
-s%@GENCAT@%$GENCAT%g
-s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g
-s%@INTL_LIBTOOL_SUFFIX_PREFIX@%$INTL_LIBTOOL_SUFFIX_PREFIX%g
-s%@CROSS@%$CROSS%g
-s%@ALL@%$ALL%g
-s%@SYSTEM_HEADER_DIR@%$SYSTEM_HEADER_DIR%g
-s%@inhibit_libc@%$inhibit_libc%g
-s%@BUILD_PREFIX@%$BUILD_PREFIX%g
-s%@BUILD_PREFIX_1@%$BUILD_PREFIX_1%g
-s%@HOST_CC@%$HOST_CC%g
-s%@HOST_CFLAGS@%$HOST_CFLAGS%g
-s%@STMP_FIXINC@%$STMP_FIXINC%g
-s%@STMP_FIXPROTO@%$STMP_FIXPROTO%g
-s%@libgcc_visibility@%$libgcc_visibility%g
-s%@gthread_flags@%$gthread_flags%g
-s%@GGC@%$GGC%g
-s%@zlibdir@%$zlibdir%g
-s%@zlibinc@%$zlibinc%g
-s%@MAINT@%$MAINT%g
-s%@build_canonical@%$build_canonical%g
-s%@host_canonical@%$host_canonical%g
-s%@target_subdir@%$target_subdir%g
-s%@gcc_tooldir@%$gcc_tooldir%g
-s%@dollar@%$dollar%g
-s%@slibdir@%$slibdir%g
-s%@objdir@%$objdir%g
-s%@subdirs@%$subdirs%g
-s%@srcdir@%$srcdir%g
-s%@all_boot_languages@%$all_boot_languages%g
-s%@all_compilers@%$all_compilers%g
-s%@all_gtfiles@%$all_gtfiles%g
-s%@all_gtfiles_files_langs@%$all_gtfiles_files_langs%g
-s%@all_gtfiles_files_files@%$all_gtfiles_files_files%g
-s%@all_lang_makefiles@%$all_lang_makefiles%g
-s%@all_languages@%$all_languages%g
-s%@all_stagestuff@%$all_stagestuff%g
-s%@build_exeext@%$build_exeext%g
-s%@build_install_headers_dir@%$build_install_headers_dir%g
-s%@build_xm_file_list@%$build_xm_file_list%g
-s%@build_xm_file@%$build_xm_file%g
-s%@build_xm_defines@%$build_xm_defines%g
-s%@check_languages@%$check_languages%g
-s%@cc_set_by_configure@%$cc_set_by_configure%g
-s%@quoted_cc_set_by_configure@%$quoted_cc_set_by_configure%g
-s%@cpp_install_dir@%$cpp_install_dir%g
-s%@dep_host_xmake_file@%$dep_host_xmake_file%g
-s%@dep_tmake_file@%$dep_tmake_file%g
-s%@extra_headers_list@%$extra_headers_list%g
-s%@extra_objs@%$extra_objs%g
-s%@extra_parts@%$extra_parts%g
-s%@extra_passes@%$extra_passes%g
-s%@extra_programs@%$extra_programs%g
-s%@float_h_file@%$float_h_file%g
-s%@gcc_config_arguments@%$gcc_config_arguments%g
-s%@gcc_gxx_include_dir@%$gcc_gxx_include_dir%g
-s%@libstdcxx_incdir@%$libstdcxx_incdir%g
-s%@gcc_version@%$gcc_version%g
-s%@gcc_version_full@%$gcc_version_full%g
-s%@gcc_version_trigger@%$gcc_version_trigger%g
-s%@host_exeext@%$host_exeext%g
-s%@host_extra_gcc_objs@%$host_extra_gcc_objs%g
-s%@host_xm_file_list@%$host_xm_file_list%g
-s%@host_xm_file@%$host_xm_file%g
-s%@host_xm_defines@%$host_xm_defines%g
-s%@install@%$install%g
-s%@lang_options_files@%$lang_options_files%g
-s%@lang_specs_files@%$lang_specs_files%g
-s%@lang_tree_files@%$lang_tree_files%g
-s%@local_prefix@%$local_prefix%g
-s%@md_file@%$md_file%g
-s%@objc_boehm_gc@%$objc_boehm_gc%g
-s%@out_file@%$out_file%g
-s%@out_object_file@%$out_object_file%g
-s%@stage_prefix_set_by_configure@%$stage_prefix_set_by_configure%g
-s%@quoted_stage_prefix_set_by_configure@%$quoted_stage_prefix_set_by_configure%g
-s%@symbolic_link@%$symbolic_link%g
-s%@thread_file@%$thread_file%g
-s%@tm_file_list@%$tm_file_list%g
-s%@tm_file@%$tm_file%g
-s%@tm_defines@%$tm_defines%g
-s%@tm_p_file_list@%$tm_p_file_list%g
-s%@tm_p_file@%$tm_p_file%g
-s%@xm_file@%$xm_file%g
-s%@xm_defines@%$xm_defines%g
-s%@c_target_objs@%$c_target_objs%g
-s%@cxx_target_objs@%$cxx_target_objs%g
-s%@target_cpu_default@%$target_cpu_default%g
-/@target_overrides@/r $target_overrides
-s%@target_overrides@%%g
-/@host_overrides@/r $host_overrides
-s%@host_overrides@%%g
-/@language_fragments@/r $language_fragments
-s%@language_fragments@%%g
-/@language_hooks@/r $language_hooks
-s%@language_hooks@%%g
-CEOF
-EOF
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)$' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+ /^X\/\(\/\/\)$/{ s//\1/; q; }
+ /^X\/\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+
-cat >> $CONFIG_STATUS <<\EOF
-
-# Split the substitutions into bite-sized pieces for seds with
-# small command number limits, like on Digital OSF/1 and HP-UX.
-ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
-ac_file=1 # Number of current file.
-ac_beg=1 # First line for current file.
-ac_end=$ac_max_sed_cmds # Line after last line for current file.
-ac_more_lines=:
-ac_sed_cmds=""
-while $ac_more_lines; do
- if test $ac_beg -gt 1; then
- sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
else
- sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" || {
+ # Find who we are. Look in the path if we contain no path at all
+ # relative or not.
+ case $0 in
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+ ;;
+ esac
+ # We did not find ourselves, most probably we were run as `sh COMMAND'
+ # in which case we are not to be found in the path.
+ if test "x$as_myself" = x; then
+ as_myself=$0
+ fi
+ if test ! -f "$as_myself"; then
+ { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+ { (exit 1); exit 1; }; }
fi
- if test ! -s conftest.s$ac_file; then
- ac_more_lines=false
- rm -f conftest.s$ac_file
+ case $CONFIG_SHELL in
+ '')
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for as_base in sh bash ksh sh5; do
+ case $as_dir in
+ /*)
+ if ("$as_dir/$as_base" -c '
+ as_lineno_1=$LINENO
+ as_lineno_2=$LINENO
+ as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+ test "x$as_lineno_1" != "x$as_lineno_2" &&
+ test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
+ $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+ $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+ CONFIG_SHELL=$as_dir/$as_base
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+ fi;;
+ esac
+ done
+done
+;;
+ esac
+
+ # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+ # uniformly replaced by the line number. The first 'sed' inserts a
+ # line-number line before each line; the second 'sed' does the real
+ # work. The second script uses 'N' to pair each line-number line
+ # with the numbered line, and appends trailing '-' during
+ # substitution so that $LINENO is not a special case at line end.
+ # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+ # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
+ sed '=' <$as_myself |
+ sed '
+ N
+ s,$,-,
+ : loop
+ s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ t loop
+ s,-$,,
+ s,^['$as_cr_digits']*\n,,
+ ' >$as_me.lineno &&
+ chmod +x $as_me.lineno ||
+ { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+ { (exit 1); exit 1; }; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensible to this).
+ . ./$as_me.lineno
+ # Exit status is that of the last command.
+ exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T=' ' ;;
+ *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+ *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+ # We could just check for DJGPP; but this test a) works b) is more generic
+ # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+ if test -f conf$$.exe; then
+ # Don't use ln at all; we don't have any links
+ as_ln_s='cp -p'
else
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds="sed -f conftest.s$ac_file"
- else
- ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
- fi
- ac_file=`expr $ac_file + 1`
- ac_beg=$ac_end
- ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ as_ln_s='ln -s'
fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p=:
+else
+ as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling. Logging --version etc. is OK.
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.57. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+ echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+ echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+ echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+ echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.57,
+ with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value. By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "x$1" : 'x\([^=]*\)='`
+ ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ -*)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ *) # This is not an option, so the user has probably given explicit
+ # arguments.
+ ac_option=$1
+ ac_need_defaults=false;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --vers* | -V )
+ echo "$ac_cs_version"; exit 0 ;;
+ --he | --h)
+ # Conflict between --help and --header
+ { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; };;
+ --help | --hel | -h )
+ echo "$ac_cs_usage"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ ac_need_defaults=false;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+ { (exit 1); exit 1; }; } ;;
+
+ *) ac_config_targets="$ac_config_targets $1" ;;
+
+ esac
+ shift
done
-if test -z "$ac_sed_cmds"; then
- ac_sed_cmds=cat
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
fi
-EOF
-cat >> $CONFIG_STATUS <<EOF
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+ echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+ exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
-CONFIG_FILES=\${CONFIG_FILES-"$all_outputs"}
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+subdirs='$subdirs'
+symbolic_link='$symbolic_link'
+
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+ case "$ac_config_target" in
+ # Handling of arguments.
+ "$all_outputs" ) CONFIG_FILES="$CONFIG_FILES $all_outputs" ;;
+ "default" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
+ "auto-host.h" ) CONFIG_HEADERS="$CONFIG_HEADERS auto-host.h:config.in" ;;
+ *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+ { (exit 1); exit 1; }; };;
esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+ trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+ trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
- # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+# Create a (secure) tmp directory for tmp files.
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
- # A "../" for each directory in $ac_dir_suffix.
- ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
- else
- ac_dir_suffix= ac_dots=
+{
+ tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./confstat$$-$RANDOM
+ (umask 077 && mkdir $tmp)
+} ||
+{
+ echo "$me: cannot create a temporary directory in ." >&2
+ { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+ # Protect against being on the right side of a sed subst in config.status.
+ sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+ s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@target@,$target,;t t
+s,@target_cpu@,$target_cpu,;t t
+s,@target_vendor@,$target_vendor,;t t
+s,@target_os@,$target_os,;t t
+s,@build_subdir@,$build_subdir,;t t
+s,@host_subdir@,$host_subdir,;t t
+s,@target_subdir@,$target_subdir,;t t
+s,@GENINSRC@,$GENINSRC,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@NO_MINUS_C_MINUS_O@,$NO_MINUS_C_MINUS_O,;t t
+s,@OUTPUT_OPTION@,$OUTPUT_OPTION,;t t
+s,@CPP@,$CPP,;t t
+s,@GNATBIND@,$GNATBIND,;t t
+s,@ac_ct_GNATBIND@,$ac_ct_GNATBIND,;t t
+s,@strict1_warn@,$strict1_warn,;t t
+s,@warn_cflags@,$warn_cflags,;t t
+s,@WERROR@,$WERROR,;t t
+s,@nocommon_flag@,$nocommon_flag,;t t
+s,@EGREP@,$EGREP,;t t
+s,@valgrind_path@,$valgrind_path,;t t
+s,@valgrind_path_defines@,$valgrind_path_defines,;t t
+s,@valgrind_command@,$valgrind_command,;t t
+s,@coverage_flags@,$coverage_flags,;t t
+s,@enable_multilib@,$enable_multilib,;t t
+s,@enable_shared@,$enable_shared,;t t
+s,@TARGET_SYSTEM_ROOT@,$TARGET_SYSTEM_ROOT,;t t
+s,@TARGET_SYSTEM_ROOT_DEFINE@,$TARGET_SYSTEM_ROOT_DEFINE,;t t
+s,@CROSS_SYSTEM_HEADER_DIR@,$CROSS_SYSTEM_HEADER_DIR,;t t
+s,@onestep@,$onestep,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@AWK@,$AWK,;t t
+s,@LN@,$LN,;t t
+s,@LN_S@,$LN_S,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@INSTALL@,$INSTALL,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@make_compare_target@,$make_compare_target,;t t
+s,@have_mktemp_command@,$have_mktemp_command,;t t
+s,@MAKEINFO@,$MAKEINFO,;t t
+s,@BUILD_INFO@,$BUILD_INFO,;t t
+s,@GENERATED_MANPAGES@,$GENERATED_MANPAGES,;t t
+s,@FLEX@,$FLEX,;t t
+s,@BISON@,$BISON,;t t
+s,@stage1_cflags@,$stage1_cflags,;t t
+s,@COLLECT2_LIBS@,$COLLECT2_LIBS,;t t
+s,@GNAT_LIBEXC@,$GNAT_LIBEXC,;t t
+s,@LDEXP_LIB@,$LDEXP_LIB,;t t
+s,@TARGET_GETGROUPS_T@,$TARGET_GETGROUPS_T,;t t
+s,@LIBICONV@,$LIBICONV,;t t
+s,@LIBICONV_DEP@,$LIBICONV_DEP,;t t
+s,@manext@,$manext,;t t
+s,@objext@,$objext,;t t
+s,@extra_modes_file@,$extra_modes_file,;t t
+s,@FORBUILD@,$FORBUILD,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@USE_NLS@,$USE_NLS,;t t
+s,@LIBINTL@,$LIBINTL,;t t
+s,@LIBINTL_DEP@,$LIBINTL_DEP,;t t
+s,@INCINTL@,$INCINTL,;t t
+s,@XGETTEXT@,$XGETTEXT,;t t
+s,@GMSGFMT@,$GMSGFMT,;t t
+s,@POSUB@,$POSUB,;t t
+s,@CATALOGS@,$CATALOGS,;t t
+s,@CROSS@,$CROSS,;t t
+s,@ALL@,$ALL,;t t
+s,@SYSTEM_HEADER_DIR@,$SYSTEM_HEADER_DIR,;t t
+s,@inhibit_libc@,$inhibit_libc,;t t
+s,@BUILD_PREFIX@,$BUILD_PREFIX,;t t
+s,@BUILD_PREFIX_1@,$BUILD_PREFIX_1,;t t
+s,@CC_FOR_BUILD@,$CC_FOR_BUILD,;t t
+s,@BUILD_CFLAGS@,$BUILD_CFLAGS,;t t
+s,@STMP_FIXINC@,$STMP_FIXINC,;t t
+s,@STMP_FIXPROTO@,$STMP_FIXPROTO,;t t
+s,@libgcc_visibility@,$libgcc_visibility,;t t
+s,@gthread_flags@,$gthread_flags,;t t
+s,@GGC@,$GGC,;t t
+s,@zlibdir@,$zlibdir,;t t
+s,@zlibinc@,$zlibinc,;t t
+s,@MAINT@,$MAINT,;t t
+s,@gcc_tooldir@,$gcc_tooldir,;t t
+s,@dollar@,$dollar,;t t
+s,@slibdir@,$slibdir,;t t
+s,@objdir@,$objdir,;t t
+s,@subdirs@,$subdirs,;t t
+s,@srcdir@,$srcdir,;t t
+s,@all_boot_languages@,$all_boot_languages,;t t
+s,@all_compilers@,$all_compilers,;t t
+s,@all_gtfiles@,$all_gtfiles,;t t
+s,@all_gtfiles_files_langs@,$all_gtfiles_files_langs,;t t
+s,@all_gtfiles_files_files@,$all_gtfiles_files_files,;t t
+s,@all_lang_makefrags@,$all_lang_makefrags,;t t
+s,@all_lang_makefiles@,$all_lang_makefiles,;t t
+s,@all_languages@,$all_languages,;t t
+s,@all_stagestuff@,$all_stagestuff,;t t
+s,@build_exeext@,$build_exeext,;t t
+s,@build_install_headers_dir@,$build_install_headers_dir,;t t
+s,@build_xm_file_list@,$build_xm_file_list,;t t
+s,@build_xm_include_list@,$build_xm_include_list,;t t
+s,@build_xm_defines@,$build_xm_defines,;t t
+s,@check_languages@,$check_languages,;t t
+s,@cc_set_by_configure@,$cc_set_by_configure,;t t
+s,@quoted_cc_set_by_configure@,$quoted_cc_set_by_configure,;t t
+s,@cpp_install_dir@,$cpp_install_dir,;t t
+s,@xmake_file@,$xmake_file,;t t
+s,@tmake_file@,$tmake_file,;t t
+s,@extra_gcc_objs@,$extra_gcc_objs,;t t
+s,@extra_headers_list@,$extra_headers_list,;t t
+s,@extra_objs@,$extra_objs,;t t
+s,@extra_parts@,$extra_parts,;t t
+s,@extra_passes@,$extra_passes,;t t
+s,@extra_programs@,$extra_programs,;t t
+s,@float_h_file@,$float_h_file,;t t
+s,@gcc_config_arguments@,$gcc_config_arguments,;t t
+s,@gcc_gxx_include_dir@,$gcc_gxx_include_dir,;t t
+s,@libstdcxx_incdir@,$libstdcxx_incdir,;t t
+s,@gcc_version@,$gcc_version,;t t
+s,@gcc_version_full@,$gcc_version_full,;t t
+s,@gcc_version_trigger@,$gcc_version_trigger,;t t
+s,@host_exeext@,$host_exeext,;t t
+s,@host_xm_file_list@,$host_xm_file_list,;t t
+s,@host_xm_include_list@,$host_xm_include_list,;t t
+s,@host_xm_defines@,$host_xm_defines,;t t
+s,@out_host_hook_obj@,$out_host_hook_obj,;t t
+s,@install@,$install,;t t
+s,@lang_opt_files@,$lang_opt_files,;t t
+s,@lang_specs_files@,$lang_specs_files,;t t
+s,@lang_tree_files@,$lang_tree_files,;t t
+s,@local_prefix@,$local_prefix,;t t
+s,@md_file@,$md_file,;t t
+s,@objc_boehm_gc@,$objc_boehm_gc,;t t
+s,@out_file@,$out_file,;t t
+s,@out_object_file@,$out_object_file,;t t
+s,@stage_prefix_set_by_configure@,$stage_prefix_set_by_configure,;t t
+s,@quoted_stage_prefix_set_by_configure@,$quoted_stage_prefix_set_by_configure,;t t
+s,@symbolic_link@,$symbolic_link,;t t
+s,@thread_file@,$thread_file,;t t
+s,@tm_file_list@,$tm_file_list,;t t
+s,@tm_include_list@,$tm_include_list,;t t
+s,@tm_defines@,$tm_defines,;t t
+s,@tm_p_file_list@,$tm_p_file_list,;t t
+s,@tm_p_include_list@,$tm_p_include_list,;t t
+s,@xm_file_list@,$xm_file_list,;t t
+s,@xm_include_list@,$xm_include_list,;t t
+s,@xm_defines@,$xm_defines,;t t
+s,@target_noncanonical@,$target_noncanonical,;t t
+s,@c_target_objs@,$c_target_objs,;t t
+s,@cxx_target_objs@,$cxx_target_objs,;t t
+s,@target_cpu_default@,$target_cpu_default,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+/@language_hooks@/r $language_hooks
+s,@language_hooks@,,;t t
+CEOF
+
+_ACEOF
+
+ cat >>$CONFIG_STATUS <<\_ACEOF
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_lines=48
+ ac_sed_frag=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_lines # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=
+ while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ else
+ sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+ fi
+ if test ! -s $tmp/subs.frag; then
+ ac_more_lines=false
+ else
+ # The purpose of the label and of the branching condition is to
+ # speed up the sed processing (if there are no `@' at all, there
+ # is no need to browse any of the substitutions).
+ # These are the two extra sed commands mentioned above.
+ (echo ':t
+ /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ fi
+ ac_sed_frag=`expr $ac_sed_frag + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_lines`
+ fi
+ done
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
fi
+fi # test -n "$CONFIG_FILES"
- case "$ac_given_srcdir" in
- .) srcdir=.
- if test -z "$ac_dots"; then top_srcdir=.
- else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
- /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
- *) # Relative path.
- srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
- top_srcdir="$ac_dots$ac_given_srcdir" ;;
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
esac
+ # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
+ ac_builddir=.
- echo creating "$ac_file"
- rm -f "$ac_file"
- configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
- case "$ac_file" in
- *Makefile*) ac_comsub="1i\\
-# $configure_input" ;;
- *) ac_comsub= ;;
- esac
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ configure_input=
+ else
+ configure_input="$ac_file. "
+ fi
+ configure_input=$configure_input"Generated from `echo $ac_file_in |
+ sed 's,.*/,,'` by configure."
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo $f;;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo $f
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo $srcdir/$f
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+ sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+ rm -f $tmp/stdin
+ if test x"$ac_file" != x-; then
+ mv $tmp/out $ac_file
+ else
+ cat $tmp/out
+ rm -f $tmp/out
+ fi
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- sed -e "$ac_comsub
-s%@configure_input@%$configure_input%g
-s%@srcdir@%$srcdir%g
-s%@top_srcdir@%$top_srcdir%g
-" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
-fi; done
-rm -f conftest.s*
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
# NAME is the cpp macro being defined and VALUE is the value it is being given.
#
# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
-ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
-ac_dC='\3'
-ac_dD='%g'
-# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
-ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_uB='\([ ]\)%\1#\2define\3'
+ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='[ ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='$,\1#\2define\3'
ac_uC=' '
-ac_uD='\4%g'
-# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_eB='$%\1#\2define\3'
-ac_eC=' '
-ac_eD='%g'
-
-if test "${CONFIG_HEADERS+set}" != set; then
-EOF
-cat >> $CONFIG_STATUS <<EOF
- CONFIG_HEADERS="auto-host.h:config.in"
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-fi
-for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case "$ac_file" in
- *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
- ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- *) ac_file_in="${ac_file}.in" ;;
+ case $ac_file in
+ - | *:- | *:-:* ) # input from stdin
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ * ) ac_file_in=$ac_file.in ;;
esac
- echo creating $ac_file
-
- rm -f conftest.frag conftest.in conftest.out
- ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
- cat $ac_file_inputs > conftest.in
-
-EOF
-
-# Transform confdefs.h into a sed script conftest.vals that substitutes
-# the proper values into config.h.in to produce config.h. And first:
-# Protect against being on the right side of a sed subst in config.status.
-# Protect against being in an unquoted here document in config.status.
-rm -f conftest.vals
-cat > conftest.hdr <<\EOF
-s/[\\&%]/\\&/g
-s%[\\$`]%\\&%g
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
-s%ac_d%ac_u%gp
-s%ac_u%ac_e%gp
-EOF
-sed -n -f conftest.hdr confdefs.h > conftest.vals
-rm -f conftest.hdr
+ test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+ # First look for the input files in the build tree, otherwise in the
+ # src tree.
+ ac_file_inputs=`IFS=:
+ for f in $ac_file_in; do
+ case $f in
+ -) echo $tmp/stdin ;;
+ [\\/$]*)
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ echo $f;;
+ *) # Relative
+ if test -f "$f"; then
+ # Build tree
+ echo $f
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo $srcdir/$f
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+ { (exit 1); exit 1; }; }
+ fi;;
+ esac
+ done` || { (exit 1); exit 1; }
+ # Remove the trailing spaces.
+ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h. The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status. Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless. Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
# This sed command replaces #undef with comments. This is necessary, for
# example, in the case of _POSIX_SOURCE, which is predefined and required
# on some systems where configure will not decide to define it.
-cat >> conftest.vals <<\EOF
-s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
-EOF
-
-# Break up conftest.vals because some shells have a limit on
-# the size of here documents, and old seds have small limits too.
+cat >>conftest.undefs <<\_ACEOF
+s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo ' :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+ # Write a limited-size here document to $tmp/defines.sed.
+ echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#define' lines.
+ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+ echo 'CEOF
+ sed -f $tmp/defines.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+ rm -f conftest.defines
+ mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo ' fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
rm -f conftest.tail
-while :
+while grep . conftest.undefs >/dev/null
do
- ac_lines=`grep -c . conftest.vals`
- # grep -c gives empty output for an empty file on some AIX systems.
- if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
- # Write a limited-size here document to conftest.frag.
- echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
- sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ # Write a limited-size here document to $tmp/undefs.sed.
+ echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+ # Speed up: don't consider the non `#undef'
+ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
+ # Work around the forget-to-reset-the-flag bug.
+ echo 't clr' >>$CONFIG_STATUS
+ echo ': clr' >>$CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
echo 'CEOF
- sed -f conftest.frag conftest.in > conftest.out
- rm -f conftest.in
- mv conftest.out conftest.in
-' >> $CONFIG_STATUS
- sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
- rm -f conftest.vals
- mv conftest.tail conftest.vals
+ sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+ rm -f $tmp/in
+ mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+ rm -f conftest.undefs
+ mv conftest.tail conftest.undefs
done
-rm -f conftest.vals
-
-cat >> $CONFIG_STATUS <<\EOF
- rm -f conftest.frag conftest.h
- echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
- cat conftest.in >> conftest.h
- rm -f conftest.in
- if cmp -s $ac_file conftest.h 2>/dev/null; then
- echo "$ac_file is unchanged"
- rm -f conftest.h
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ if test x"$ac_file" = x-; then
+ echo "/* Generated by configure. */" >$tmp/config.h
else
- # Remove last slash and all that follows it. Not all systems have dirname.
- ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
- if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
- # The file is in a subdirectory.
- test ! -d "$ac_dir" && mkdir "$ac_dir"
- fi
- rm -f $ac_file
- mv conftest.h $ac_file
+ echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
fi
-fi; done
-
-EOF
-cat >> $CONFIG_STATUS <<EOF
-
-subdirs='$subdirs'
-symbolic_link='$symbolic_link'
+ cat $tmp/in >>$tmp/config.h
+ rm -f $tmp/in
+ if test x"$ac_file" != x-; then
+ if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+ { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
-EOF
-cat >> $CONFIG_STATUS <<\EOF
-for ac_file in $CONFIG_FILES; do
- # Support "outfile[:infile[:infile...]]"
- case "$ac_file" in
- *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- esac
- # PO directories have a Makefile.in generated from Makefile.in.in.
- case "$ac_file" in */Makefile.in)
- # Adjust a relative srcdir.
- ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
- ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
- ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
- # In autoconf-2.13 it is called $ac_given_srcdir.
- # In autoconf-2.50 it is called $srcdir.
- test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
- case "$ac_given_srcdir" in
- .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
- /*) top_srcdir="$ac_given_srcdir" ;;
- *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
- if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
- rm -f "$ac_dir/POTFILES"
- test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
- sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," -e "\$s/\(.*\) \\\\/\1/" < "$ac_given_srcdir/$ac_dir/POTFILES.in" > "$ac_dir/POTFILES"
- test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
- sed -e "/POTFILES =/r $ac_dir/POTFILES" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
- fi
- ;;
- esac
- done
+ rm -f $ac_file
+ mv $tmp/config.h $ac_file
+ fi
+ else
+ cat $tmp/config.h
+ rm -f $tmp/config.h
+ fi
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
-case x$CONFIG_HEADERS in
-xauto-host.h:config.in)
-echo > cstamp-h ;;
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+ ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+ ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_dest" : 'X\(//\)[^/]' \| \
+ X"$ac_dest" : 'X\(//\)$' \| \
+ X"$ac_dest" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ ac_builddir=.
+
+if test "$ac_dir" != .; then
+ ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+ ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+ .) # No --srcdir option. We are building in place.
+ ac_srcdir=.
+ if test -z "$ac_top_builddir"; then
+ ac_top_srcdir=.
+ else
+ ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+ fi ;;
+ [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir ;;
+ *) # Relative path.
+ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+ { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+ case $ac_dest in
+ default )
+case ${CONFIG_HEADERS} in
+ *auto-host.h:config.in*)
+ echo > cstamp-h ;;
esac
+# Make sure all the subdirs exist.
+for d in $subdirs
+do
+ test -d $d || mkdir $d
+done
# If the host supports symlinks, point stage[1234] at ../stage[1234] so
# bootstrapping and the installation procedure can still use
# CC="stage1/xgcc -Bstage1/". If the host doesn't support symlinks,
@@ -9146,28 +13136,48 @@ esac
# This is virtually a duplicate of what happens in configure.lang; we do
# an extra check to make sure this only happens if ln -s can be used.
if test "$symbolic_link" = "ln -s"; then
- for d in .. ${subdirs} fixinc ; do
- if test $d != ..; then
+ for d in ${subdirs} fixinc ; do
STARTDIR=`${PWDCMD-pwd}`
cd $d
- for t in stage1 stage2 stage3 stage4 include
+ for t in stage1 stage2 stage3 stage4 stageprofile stagefeedback include
do
rm -f $t
$symbolic_link ../$t $t 2>/dev/null
done
cd $STARTDIR
- fi
done
else true ; fi
-# Avoid having to add intl to our include paths.
-if test -f intl/libintl.h; then
- echo creating libintl.h
- echo '#include "intl/libintl.h"' >libintl.h
-fi
+ ;;
+ esac
+done
+_ACEOF
-exit 0
-EOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
chmod +x $CONFIG_STATUS
-rm -fr confdefs* $ac_clean_files
-test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || { (exit 1); exit 1; }
+fi
diff --git a/contrib/gcc/configure.ac b/contrib/gcc/configure.ac
new file mode 100644
index 000000000000..0aadf4ef3a8c
--- /dev/null
+++ b/contrib/gcc/configure.ac
@@ -0,0 +1,3169 @@
+# configure.ac for GCC
+# Process this file with autoconf to generate a configuration script.
+
+# Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+# 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 2, 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 COPYING. If not, write to the Free
+#Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+#02111-1307, USA.
+
+# --------------------------------
+# Initialization and sanity checks
+# --------------------------------
+
+AC_PREREQ(2.57)
+AC_INIT
+AC_CONFIG_SRCDIR(tree.c)
+AC_CONFIG_HEADER(auto-host.h:config.in)
+
+# Determine the host, build, and target systems
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
+# Determine the noncanonical target name, for directory use.
+_GCC_TOPLEV_NONCANONICAL_TARGET
+
+# Determine the target- and build-specific subdirectories
+GCC_TOPLEV_SUBDIRS
+
+# Set program_transform_name
+AC_ARG_PROGRAM
+
+# Check for bogus environment variables.
+# Test if LIBRARY_PATH contains the notation for the current directory
+# since this would lead to problems installing/building glibc.
+# LIBRARY_PATH contains the current directory if one of the following
+# is true:
+# - one of the terminals (":" and ";") is the first or last sign
+# - two terminals occur directly after each other
+# - the path contains an element with a dot in it
+AC_MSG_CHECKING(LIBRARY_PATH variable)
+changequote(,)dnl
+case ${LIBRARY_PATH} in
+ [:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
+ library_path_setting="contains current directory"
+ ;;
+ *)
+ library_path_setting="ok"
+ ;;
+esac
+changequote([,])dnl
+AC_MSG_RESULT($library_path_setting)
+if test "$library_path_setting" != "ok"; then
+AC_MSG_ERROR([
+*** LIBRARY_PATH shouldn't contain the current directory when
+*** building gcc. Please change the environment variable
+*** and run configure again.])
+fi
+
+# Test if GCC_EXEC_PREFIX contains the notation for the current directory
+# since this would lead to problems installing/building glibc.
+# GCC_EXEC_PREFIX contains the current directory if one of the following
+# is true:
+# - one of the terminals (":" and ";") is the first or last sign
+# - two terminals occur directly after each other
+# - the path contains an element with a dot in it
+AC_MSG_CHECKING(GCC_EXEC_PREFIX variable)
+changequote(,)dnl
+case ${GCC_EXEC_PREFIX} in
+ [:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* )
+ gcc_exec_prefix_setting="contains current directory"
+ ;;
+ *)
+ gcc_exec_prefix_setting="ok"
+ ;;
+esac
+changequote([,])dnl
+AC_MSG_RESULT($gcc_exec_prefix_setting)
+if test "$gcc_exec_prefix_setting" != "ok"; then
+AC_MSG_ERROR([
+*** GCC_EXEC_PREFIX shouldn't contain the current directory when
+*** building gcc. Please change the environment variable
+*** and run configure again.])
+fi
+
+# -----------
+# Directories
+# -----------
+
+# Specify the local prefix
+local_prefix=
+AC_ARG_WITH(local-prefix,
+[ --with-local-prefix=DIR specifies directory to put local include],
+[case "${withval}" in
+yes) AC_MSG_ERROR(bad value ${withval} given for local include directory prefix) ;;
+no) ;;
+*) local_prefix=$with_local_prefix ;;
+esac])
+
+# Default local prefix if it is empty
+if test x$local_prefix = x; then
+ local_prefix=/usr/local
+fi
+
+# Don't set gcc_gxx_include_dir to gxx_include_dir since that's only
+# passed in by the toplevel make and thus we'd get different behavior
+# depending on where we built the sources.
+gcc_gxx_include_dir=
+# Specify the g++ header file directory
+AC_ARG_WITH(gxx-include-dir,
+[ --with-gxx-include-dir=DIR
+ specifies directory to put g++ header files],
+[case "${withval}" in
+yes) AC_MSG_ERROR(bad value ${withval} given for g++ include directory) ;;
+no) ;;
+*) gcc_gxx_include_dir=$with_gxx_include_dir ;;
+esac])
+
+if test x${gcc_gxx_include_dir} = x; then
+ if test x${enable_version_specific_runtime_libs} = xyes; then
+ gcc_gxx_include_dir='${libsubdir}/include/c++'
+ else
+ topsrcdir=${srcdir}/.. . ${srcdir}/../config.if
+changequote(<<, >>)dnl
+ gcc_gxx_include_dir="\$(libsubdir)/\$(unlibsubdir)/..\`echo \$(exec_prefix) | sed -e 's|^\$(prefix)||' -e 's|/[^/]*|/..|g'\`/include/"${libstdcxx_incdir}
+changequote([, ])dnl
+ fi
+fi
+
+AC_ARG_WITH(cpp_install_dir,
+[ --with-cpp-install-dir=DIR
+ install the user visible C preprocessor in DIR
+ (relative to PREFIX) as well as PREFIX/bin],
+[if test x$withval = xyes; then
+ AC_MSG_ERROR([option --with-cpp-install-dir requires an argument])
+elif test x$withval != xno; then
+ cpp_install_dir=$withval
+fi])
+
+# We would like to our source tree to be readonly. However when releases or
+# pre-releases are generated, the flex/bison generated files as well as the
+# various formats of manuals need to be included along with the rest of the
+# sources. Therefore we have --enable-generated-files-in-srcdir to do
+# just that.
+
+AC_MSG_CHECKING([whether to place generated files in the source directory])
+ dnl generated-files-in-srcdir is disabled by default
+ AC_ARG_ENABLE(generated-files-in-srcdir,
+[ --enable-generated-files-in-srcdir
+ put copies of generated files in source dir
+ intended for creating source tarballs for users
+ without texinfo bison or flex.],
+ generated_files_in_srcdir=$enableval,
+ generated_files_in_srcdir=no)
+
+AC_MSG_RESULT($generated_files_in_srcdir)
+
+if test "$generated_files_in_srcdir" = "yes"; then
+ GENINSRC=''
+else
+ GENINSRC='#'
+fi
+AC_SUBST(GENINSRC)
+
+# -------------------
+# Find default linker
+# -------------------
+
+# With GNU ld
+AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld arrange to work with GNU ld.],
+gnu_ld_flag="$with_gnu_ld",
+gnu_ld_flag=no)
+
+# With pre-defined ld
+AC_ARG_WITH(ld,
+[ --with-ld arrange to use the specified ld (full pathname)],
+DEFAULT_LINKER="$with_ld")
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
+ if test ! -x "$DEFAULT_LINKER"; then
+ AC_MSG_WARN([cannot execute: $DEFAULT_LINKER: check --with-ld or env. var. DEFAULT_LINKER])
+ elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
+ gnu_ld_flag=yes
+ fi
+ AC_DEFINE_UNQUOTED(DEFAULT_LINKER,"$DEFAULT_LINKER",
+ [Define to enable the use of a default linker.])
+fi
+
+AC_MSG_CHECKING([whether a default linker was specified])
+if test x"${DEFAULT_LINKER+set}" = x"set"; then
+ if test x"$gnu_ld_flag" = x"no"; then
+ AC_MSG_RESULT([yes ($DEFAULT_LINKER)])
+ else
+ AC_MSG_RESULT([yes ($DEFAULT_LINKER - GNU ld)])
+ fi
+else
+ AC_MSG_RESULT(no)
+fi
+
+# ----------------------
+# Find default assembler
+# ----------------------
+
+# With GNU as
+AC_ARG_WITH(gnu-as,
+[ --with-gnu-as arrange to work with GNU as],
+gas_flag="$with_gnu_as",
+gas_flag=no)
+
+AC_ARG_WITH(as,
+[ --with-as arrange to use the specified as (full pathname)],
+DEFAULT_ASSEMBLER="$with_as")
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
+ if test ! -x "$DEFAULT_ASSEMBLER"; then
+ AC_MSG_WARN([cannot execute: $DEFAULT_ASSEMBLER: check --with-as or env. var. DEFAULT_ASSEMBLER])
+ elif $DEFAULT_ASSEMBLER -v < /dev/null 2>&1 | grep GNU > /dev/null; then
+ gas_flag=yes
+ fi
+ AC_DEFINE_UNQUOTED(DEFAULT_ASSEMBLER,"$DEFAULT_ASSEMBLER",
+ [Define to enable the use of a default assembler.])
+fi
+
+AC_MSG_CHECKING([whether a default assembler was specified])
+if test x"${DEFAULT_ASSEMBLER+set}" = x"set"; then
+ if test x"$gas_flag" = x"no"; then
+ AC_MSG_RESULT([yes ($DEFAULT_ASSEMBLER)])
+ else
+ AC_MSG_RESULT([yes ($DEFAULT_ASSEMBLER - GNU as)])
+ fi
+else
+ AC_MSG_RESULT(no)
+fi
+
+# ---------------
+# Find C compiler
+# ---------------
+
+# If a non-executable a.out is present (e.g. created by GNU as above even if
+# invoked with -v only), the IRIX 6 native ld just overwrites the existing
+# file, even when creating an executable, so an execution test fails.
+# Remove possible default executable files to avoid this.
+#
+# FIXME: This really belongs into AC_PROG_CC and can be removed once
+# Autoconf includes it.
+rm -f a.out a.exe b.out
+
+# Find the native compiler
+AC_PROG_CC
+AC_PROG_CC_C_O
+# autoconf is lame and doesn't give us any substitution variable for this.
+if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then
+ NO_MINUS_C_MINUS_O=yes
+else
+ OUTPUT_OPTION='-o $@'
+fi
+AC_SUBST(NO_MINUS_C_MINUS_O)
+AC_SUBST(OUTPUT_OPTION)
+
+# -------------------------
+# Check C compiler features
+# -------------------------
+
+AC_CACHE_CHECK(whether ${CC-cc} accepts -Wno-long-long,
+ac_cv_prog_cc_no_long_long,
+[save_CFLAGS="$CFLAGS"
+CFLAGS="-Wno-long-long"
+AC_TRY_COMPILE(,,ac_cv_prog_cc_no_long_long=yes,
+ ac_cv_prog_cc_no_long_long=no)
+CFLAGS="$save_CFLAGS"])
+
+AC_PROG_CPP
+AC_C_INLINE
+
+gcc_AC_C_LONG_LONG
+gcc_AC_C__BOOL
+
+# sizeof(char) is 1 by definition.
+AC_COMPILE_CHECK_SIZEOF(void *)
+AC_COMPILE_CHECK_SIZEOF(short)
+AC_COMPILE_CHECK_SIZEOF(int)
+AC_COMPILE_CHECK_SIZEOF(long)
+if test $ac_cv_c_long_long = yes; then
+ AC_COMPILE_CHECK_SIZEOF(long long)
+fi
+if test $ac_cv_c___int64 = yes; then
+ AC_COMPILE_CHECK_SIZEOF(__int64)
+fi
+
+# -----------------
+# Find Ada compiler
+# -----------------
+
+# See if GNAT has been installed
+gcc_AC_PROG_GNAT
+
+# ---------------------
+# Warnings and checking
+# ---------------------
+
+strict1_warn=
+if test $ac_cv_prog_cc_no_long_long = yes ; then
+ strict1_warn="-pedantic -Wno-long-long"
+fi
+AC_SUBST(strict1_warn)
+
+# If the native compiler is GCC, we can enable warnings even in stage1.
+# That's useful for people building cross-compilers, or just running a
+# quick `make'.
+warn_cflags=
+if test "x$GCC" = "xyes"; then
+ warn_cflags='$(GCC_WARN_CFLAGS)'
+fi
+AC_SUBST(warn_cflags)
+
+# Enable -Werror in bootstrap stage2 and later.
+# Change the default to "no" on release branches.
+AC_ARG_ENABLE(werror,
+[ --enable-werror enable -Werror in bootstrap stage2 and later], [],
+[enable_werror=no])
+if test x$enable_werror = xyes ; then
+ WERROR=-Werror
+fi
+AC_SUBST(WERROR)
+
+# Enable expensive internal checks
+AC_ARG_ENABLE(checking,
+[ --enable-checking[=LIST]
+ enable expensive run-time checks. With LIST,
+ enable only specific categories of checks.
+ Categories are: misc,tree,rtl,rtlflag,gc,gcac,fold;
+ default is no checking],
+[ac_checking=
+ac_tree_checking=
+ac_rtl_checking=
+ac_rtlflag_checking=
+ac_gc_checking=
+ac_gc_always_collect=
+ac_fold_checking=
+case "${enableval}" in
+yes) ac_checking=1 ; ac_tree_checking=1 ; ac_gc_checking=1 ;
+ ac_rtlflag_checking=1 ;;
+no) ;;
+*) IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="$IFS,"
+ set fnord $enableval; shift
+ IFS="$ac_save_IFS"
+ for check
+ do
+ case $check in
+ misc) ac_checking=1 ;;
+ tree) ac_tree_checking=1 ;;
+ rtlflag) ac_rtlflag_checking=1 ;;
+ rtl) ac_rtl_checking=1 ;;
+ gc) ac_gc_checking=1 ;;
+ gcac) ac_gc_always_collect=1 ;;
+ fold) ac_fold_checking=1 ;;
+ valgrind) ac_checking_valgrind=1 ;;
+ *) AC_MSG_ERROR(unknown check category $check) ;;
+ esac
+ done
+ ;;
+esac
+],
+# By default, disable all checks for release versions of GCC.
+[ac_checking=; ac_tree_checking=; ac_gc_checking=; ac_rtlflag_checking=;])
+nocommon_flag=""
+if test x$ac_checking != x ; then
+ AC_DEFINE(ENABLE_CHECKING, 1,
+[Define if you want more run-time sanity checks. This one gets a grab
+ bag of miscellaneous but relatively cheap checks.])
+ nocommon_flag=-fno-common
+fi
+AC_SUBST(nocommon_flag)
+if test x$ac_tree_checking != x ; then
+ AC_DEFINE(ENABLE_TREE_CHECKING, 1,
+[Define if you want all operations on trees (the basic data
+ structure of the front ends) to be checked for dynamic type safety
+ at runtime. This is moderately expensive.])
+fi
+if test x$ac_rtl_checking != x ; then
+ AC_DEFINE(ENABLE_RTL_CHECKING, 1,
+[Define if you want all operations on RTL (the basic data structure
+ of the optimizer and back end) to be checked for dynamic type safety
+ at runtime. This is quite expensive.])
+fi
+if test x$ac_rtlflag_checking != x ; then
+ AC_DEFINE(ENABLE_RTL_FLAG_CHECKING, 1,
+[Define if you want RTL flag accesses to be checked against the RTL
+ codes that are supported for each access macro. This is relatively
+ cheap.])
+fi
+if test x$ac_gc_checking != x ; then
+ AC_DEFINE(ENABLE_GC_CHECKING, 1,
+[Define if you want the garbage collector to do object poisoning and
+ other memory allocation checks. This is quite expensive.])
+fi
+if test x$ac_gc_always_collect != x ; then
+ AC_DEFINE(ENABLE_GC_ALWAYS_COLLECT, 1,
+[Define if you want the garbage collector to operate in maximally
+ paranoid mode, validating the entire heap and collecting garbage at
+ every opportunity. This is extremely expensive.])
+fi
+if test x$ac_fold_checking != x ; then
+ AC_DEFINE(ENABLE_FOLD_CHECKING, 1,
+[Define if you want fold checked that it never destructs its argument.
+ This is quite expensive.])
+fi
+valgrind_path_defines=
+valgrind_command=
+
+dnl # This check AC_REQUIREs various stuff, so it *must not* be inside
+dnl # an if statement. This was the source of very frustrating bugs
+dnl # in converting to autoconf 2.5x!
+AC_CHECK_HEADER(valgrind.h, have_valgrind_h=yes, have_valgrind_h=no)
+
+if test x$ac_checking_valgrind != x ; then
+ # It is certainly possible that there's valgrind but no valgrind.h.
+ # GCC relies on making annotations so we must have both.
+ AC_MSG_CHECKING(for VALGRIND_DISCARD in <valgrind/memcheck.h>)
+ AC_TRY_CPP(
+ [#include <valgrind/memcheck.h>
+#ifndef VALGRIND_DISCARD
+#error VALGRIND_DISCARD not defined
+#endif],
+ [gcc_cv_header_valgrind_memcheck_h=yes],
+ [gcc_cv_header_valgrind_memcheck_h=no])
+ AC_MSG_RESULT($gcc_cv_header_valgrind_memcheck_h)
+ AC_MSG_CHECKING(for VALGRIND_DISCARD in <memcheck.h>)
+ AC_TRY_CPP(
+ [#include <memcheck.h>
+#ifndef VALGRIND_DISCARD
+#error VALGRIND_DISCARD not defined
+#endif],
+ [gcc_cv_header_memcheck_h=yes],
+ gcc_cv_header_memcheck_h=no)
+ AC_MSG_RESULT($gcc_cv_header_memcheck_h)
+ AM_PATH_PROG_WITH_TEST(valgrind_path, valgrind,
+ [$ac_dir/$ac_word --version | grep valgrind- >/dev/null 2>&1])
+ if test "x$valgrind_path" = "x" \
+ || (test $have_valgrind_h = no \
+ && test $gcc_cv_header_memcheck_h = no \
+ && test $gcc_cv_header_valgrind_memcheck_h = no); then
+ AC_MSG_ERROR([*** Can't find both valgrind and valgrind/memcheck.h, memcheck.h or valgrind.h])
+ fi
+ valgrind_path_defines=-DVALGRIND_PATH='\"'$valgrind_path'\"'
+ valgrind_command="$valgrind_path -q"
+ AC_DEFINE(ENABLE_VALGRIND_CHECKING, 1,
+[Define if you want to run subprograms and generated programs
+ through valgrind (a memory checker). This is extremely expensive.])
+ if test $gcc_cv_header_valgrind_memcheck_h = yes; then
+ AC_DEFINE(HAVE_VALGRIND_MEMCHECK_H, 1,
+ [Define if valgrind's valgrind/memcheck.h header is installed.])
+ fi
+ if test $gcc_cv_header_memcheck_h = yes; then
+ AC_DEFINE(HAVE_MEMCHECK_H, 1,
+ [Define if valgrind's memcheck.h header is installed.])
+ fi
+fi
+AC_SUBST(valgrind_path_defines)
+AC_SUBST(valgrind_command)
+
+# Enable code coverage collection
+AC_ARG_ENABLE(coverage,
+[ --enable-coverage[=LEVEL]
+ enable compiler\'s code coverage collection.
+ Use to measure compiler performance and locate
+ unused parts of the compiler. With LEVEL, specify
+ optimization. Values are opt, noopt,
+ default is noopt],
+[case "${enableval}" in
+yes|noopt)
+ coverage_flags="-fprofile-arcs -ftest-coverage -frandom-seed=\$@ -O0"
+ ;;
+opt)
+ coverage_flags="-fprofile-arcs -ftest-coverage -frandom-seed=\$@ -O2"
+ ;;
+*)
+ AC_MSG_ERROR(unknown coverage setting $enableval)
+ ;;
+esac],
+[coverage_flags=""])
+AC_SUBST(coverage_flags)
+
+AC_ARG_ENABLE(gather-detailed-mem-stats,
+[ --enable-gather-detailed-mem-stats enable detailed memory allocation stats gathering], [],
+[enable_gather_detailed_mem_stats=no])
+if test x$enable_gather_detailed_mem_stats = xyes ; then
+ AC_DEFINE(GATHER_STATISTICS, 1,
+ [Define to enable detailed memory allocation stats gathering.])
+fi
+
+# -------------------------------
+# Miscenalleous configure options
+# -------------------------------
+
+# With stabs
+AC_ARG_WITH(stabs,
+[ --with-stabs arrange to use stabs instead of host debug format],
+stabs="$with_stabs",
+stabs=no)
+
+# Determine whether or not multilibs are enabled.
+AC_ARG_ENABLE(multilib,
+[ --enable-multilib enable library support for multiple ABIs],
+[], [enable_multilib=yes])
+AC_SUBST(enable_multilib)
+
+# Enable __cxa_atexit for C++.
+AC_ARG_ENABLE(__cxa_atexit,
+[ --enable-__cxa_atexit enable __cxa_atexit for C++],
+[], [])
+
+# Enable threads
+# Pass with no value to take the default
+# Pass with a value to specify a thread package
+AC_ARG_ENABLE(threads,
+[ --enable-threads enable thread usage for target GCC
+ --enable-threads=LIB use LIB thread package for target GCC],,
+enable_threads='')
+# Save in case it gets overwritten in config.gcc
+enable_threads_flag=$enable_threads
+
+AC_ARG_ENABLE(objc-gc,
+[ --enable-objc-gc enable the use of Boehm's garbage collector with
+ the GNU Objective-C runtime],
+if test x$enable_objc_gc = xno; then
+ objc_boehm_gc=''
+else
+ objc_boehm_gc=1
+fi,
+objc_boehm_gc='')
+
+AC_ARG_WITH(dwarf2,
+[ --with-dwarf2 force the default debug format to be DWARF 2],
+dwarf2="$with_dwarf2",
+dwarf2=no)
+
+AC_ARG_ENABLE(shared,
+[ --disable-shared don't provide a shared libgcc],
+[
+ case $enable_shared in
+ yes | no) ;;
+ *)
+ enable_shared=no
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "Xgcc" || test "X$pkg" = "Xlibgcc"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+ esac
+], [enable_shared=yes])
+AC_SUBST(enable_shared)
+
+AC_ARG_WITH(sysroot,
+[ --with-sysroot[=DIR] Search for usr/lib, usr/include, et al, within DIR.],
+[
+ case ${with_sysroot} in
+ yes) TARGET_SYSTEM_ROOT='${exec_prefix}/${target_noncanonical}/sys-root' ;;
+ *) TARGET_SYSTEM_ROOT=$with_sysroot ;;
+ esac
+
+ TARGET_SYSTEM_ROOT_DEFINE='-DTARGET_SYSTEM_ROOT=\"$(TARGET_SYSTEM_ROOT)\"'
+ CROSS_SYSTEM_HEADER_DIR='$(TARGET_SYSTEM_ROOT)$(NATIVE_SYSTEM_HEADER_DIR)'
+
+ if test "x$exec_prefix" = xNONE; then
+ if test "x$prefix" = xNONE; then
+ test_prefix=/usr/local
+ else
+ test_prefix=$prefix
+ fi
+ else
+ test_prefix=$exec_prefix
+ fi
+ case ${TARGET_SYSTEM_ROOT} in
+ "${test_prefix}"|"${test_prefix}/"*|\
+ '${exec_prefix}'|'${exec_prefix}/'*)
+ t="$TARGET_SYSTEM_ROOT_DEFINE -DTARGET_SYSTEM_ROOT_RELOCATABLE"
+ TARGET_SYSTEM_ROOT_DEFINE="$t"
+ ;;
+ esac
+], [
+ TARGET_SYSTEM_ROOT=
+ TARGET_SYSTEM_ROOT_DEFINE=
+ CROSS_SYSTEM_HEADER_DIR='$(gcc_tooldir)/sys-include'
+])
+AC_SUBST(TARGET_SYSTEM_ROOT)
+AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE)
+AC_SUBST(CROSS_SYSTEM_HEADER_DIR)
+
+# Build with intermodule optimisations
+AC_ARG_ENABLE(intermodule,
+[ --enable-intermodule build the compiler in one step],
+[case ${enable_intermodule} in
+ yes) onestep="-onestep";;
+ *) onestep="";;
+esac],
+[onestep=""])
+AC_SUBST(onestep)
+
+# -------------------------
+# Checks for other programs
+# -------------------------
+
+AC_PROG_MAKE_SET
+
+# Find some useful tools
+AC_PROG_AWK
+# We need awk to run opts.sh (to create options.c and options.h).
+# Bail out if it's missing.
+case ${AWK} in
+ "") AC_MSG_ERROR([can't build without awk, bailing out]) ;;
+esac
+
+gcc_AC_PROG_LN
+gcc_AC_PROG_LN_S
+AC_PROG_RANLIB
+gcc_AC_PROG_INSTALL
+
+# See if cmp has --ignore-initial.
+gcc_AC_PROG_CMP_IGNORE_INITIAL
+
+# See if we have the mktemp command.
+AC_CHECK_PROG(have_mktemp_command, mktemp, yes, no)
+
+# Do we have a single-tree copy of texinfo?
+if test -f $srcdir/../texinfo/Makefile.in; then
+ MAKEINFO='$(objdir)/../texinfo/makeinfo/makeinfo'
+ gcc_cv_prog_makeinfo_modern=yes
+ AC_MSG_RESULT([Using makeinfo from the unified source tree.])
+else
+ # See if makeinfo has been installed and is modern enough
+ # that we can use it.
+ gcc_AC_CHECK_PROG_VER(MAKEINFO, makeinfo, --version,
+ [GNU texinfo.* \([0-9][0-9.]*\)],
+ [4.[2-9]*])
+fi
+
+if test $gcc_cv_prog_makeinfo_modern = no; then
+ AC_MSG_WARN([
+*** Makeinfo is missing or too old.
+*** Info documentation will not be built.])
+ BUILD_INFO=
+else
+ BUILD_INFO=info AC_SUBST(BUILD_INFO)
+fi
+
+# Is pod2man recent enough to regenerate manpages?
+AC_MSG_CHECKING([for recent Pod::Man])
+if (perl -e 'use 1.10 Pod::Man') >/dev/null 2>&1; then
+ AC_MSG_RESULT(yes)
+ GENERATED_MANPAGES=generated-manpages AC_SUBST(GENERATED_MANPAGES)
+else
+ AC_MSG_RESULT(no)
+ GENERATED_MANPAGES=
+fi
+
+# How about lex?
+dnl Don't use AC_PROG_LEX; we insist on flex.
+dnl LEXLIB is not useful in gcc.
+if test -f $srcdir/../flex/skel.c; then
+ FLEX='$(objdir)/../flex/flex'
+else
+ AC_CHECK_PROG(FLEX, flex, flex, ${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing flex)
+fi
+
+# Bison?
+# The -L switch is so bison can find its skeleton file.
+if test -f $srcdir/../bison/bison.simple; then
+ BISON='$(objdir)/../bison/bison -L $(srcdir)/../bison/'
+else
+ AC_CHECK_PROG(BISON, bison, bison, ${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing bison)
+fi
+
+# --------------------
+# Checks for C headers
+# --------------------
+
+AC_MSG_CHECKING(for GNU C library)
+AC_CACHE_VAL(gcc_cv_glibc,
+[AC_TRY_COMPILE(
+ [#include <features.h>],[
+#if ! (defined __GLIBC__ || defined __GNU_LIBRARY__)
+#error Not a GNU C library system
+#endif],
+ [gcc_cv_glibc=yes],
+ gcc_cv_glibc=no)])
+AC_MSG_RESULT($gcc_cv_glibc)
+if test $gcc_cv_glibc = yes; then
+ AC_DEFINE(_GNU_SOURCE, 1, [Always define this when using the GNU C Library])
+fi
+
+# Need to reject headers which give warnings, so that the -Werror bootstrap
+# works later. *sigh* This needs to come before all header checks.
+AC_PROG_CPP_WERROR
+
+AC_HEADER_STDC
+AC_HEADER_TIME
+gcc_AC_HEADER_STDBOOL
+gcc_AC_HEADER_STRING
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h \
+ fcntl.h unistd.h sys/file.h sys/time.h sys/mman.h \
+ sys/resource.h sys/param.h sys/times.h sys/stat.h \
+ direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h)
+
+# Check for thread headers.
+AC_CHECK_HEADER(thread.h, [have_thread_h=yes], [have_thread_h=])
+AC_CHECK_HEADER(pthread.h, [have_pthread_h=yes], [have_pthread_h=])
+
+# These tests can't be done till we know if we have limits.h.
+gcc_AC_C_CHAR_BIT
+AC_C_BIGENDIAN_CROSS
+
+# --------
+# UNSORTED
+# --------
+
+# Stage specific cflags for build.
+stage1_cflags=
+case $build in
+vax-*-*)
+ if test x$GCC = xyes
+ then
+ stage1_cflags="-Wa,-J"
+ else
+ stage1_cflags="-J"
+ fi
+ ;;
+powerpc-*-darwin*)
+ # The spiffy cpp-precomp chokes on some legitimate constructs in GCC
+ # sources; use -no-cpp-precomp to get to GNU cpp.
+ # Apple's GCC has bugs in designated initializer handling, so disable
+ # that too.
+ stage1_cflags="-no-cpp-precomp -DHAVE_DESIGNATED_INITIALIZERS=0"
+ ;;
+esac
+AC_SUBST(stage1_cflags)
+
+# These libraries may be used by collect2.
+# We may need a special search path to get them linked.
+AC_CACHE_CHECK(for collect2 libraries, gcc_cv_collect2_libs,
+[save_LIBS="$LIBS"
+for libs in '' -lld -lmld \
+ '-L/usr/lib/cmplrs/cc2.11 -lmld' \
+ '-L/usr/lib/cmplrs/cc3.11 -lmld'
+do
+ LIBS="$libs"
+ AC_TRY_LINK_FUNC(ldopen,
+ [gcc_cv_collect2_libs="$libs"; break])
+done
+LIBS="$save_LIBS"
+test -z "$gcc_cv_collect2_libs" && gcc_cv_collect2_libs='none required'])
+case $gcc_cv_collect2_libs in
+ "none required") ;;
+ *) COLLECT2_LIBS=$gcc_cv_collect2_libs ;;
+esac
+AC_SUBST(COLLECT2_LIBS)
+
+# When building Ada code on Alpha, we need exc_resume which is usually in
+# -lexc. So test for it.
+save_LIBS="$LIBS"
+LIBS=
+AC_SEARCH_LIBS(exc_resume, exc)
+GNAT_LIBEXC="$LIBS"
+LIBS="$save_LIBS"
+AC_SUBST(GNAT_LIBEXC)
+
+# Some systems put ldexp and frexp in libm instead of libc; assume
+# they're both in the same place. jcf-dump needs them.
+save_LIBS="$LIBS"
+LIBS=
+AC_SEARCH_LIBS(ldexp, m)
+LDEXP_LIB="$LIBS"
+LIBS="$save_LIBS"
+AC_SUBST(LDEXP_LIB)
+
+# Use <inttypes.h> only if it exists,
+# doesn't clash with <sys/types.h>, and declares intmax_t.
+AC_MSG_CHECKING(for inttypes.h)
+AC_CACHE_VAL(gcc_cv_header_inttypes_h,
+[AC_TRY_COMPILE(
+ [#include <sys/types.h>
+#include <inttypes.h>],
+ [intmax_t i = -1;],
+ [gcc_cv_header_inttypes_h=yes],
+ gcc_cv_header_inttypes_h=no)])
+AC_MSG_RESULT($gcc_cv_header_inttypes_h)
+if test $gcc_cv_header_inttypes_h = yes; then
+ AC_DEFINE(HAVE_INTTYPES_H, 1,
+ [Define if you have a working <inttypes.h> header file.])
+fi
+
+dnl Disabled until we have a complete test for buggy enum bitfields.
+dnl gcc_AC_C_ENUM_BF_UNSIGNED
+
+AC_CHECK_FUNCS(times clock dup2 kill getrlimit setrlimit atoll atoq \
+ sysconf strsignal putc_unlocked fputc_unlocked fputs_unlocked \
+ fwrite_unlocked fprintf_unlocked getrusage nl_langinfo \
+ scandir alphasort gettimeofday mbstowcs wcswidth mmap mincore \
+ setlocale)
+
+if test x$ac_cv_func_mbstowcs = xyes; then
+ AC_CACHE_CHECK(whether mbstowcs works, gcc_cv_func_mbstowcs_works,
+[ AC_TRY_RUN([#include <stdlib.h>
+int main()
+{
+ mbstowcs(0, "", 0);
+ return 0;
+}],
+ gcc_cv_func_mbstowcs_works=yes,
+ gcc_cv_func_mbstowcs_works=no,
+ gcc_cv_func_mbstowcs_works=yes)])
+ if test x$gcc_cv_func_mbstowcs_works = xyes; then
+ AC_DEFINE(HAVE_WORKING_MBSTOWCS, 1,
+ [Define this macro if mbstowcs does not crash when its
+ first argument is NULL.])
+ fi
+fi
+
+AC_CHECK_TYPE(ssize_t, int)
+
+# Try to determine the array type of the second argument of getgroups
+# for the target system (int or gid_t).
+AC_TYPE_GETGROUPS
+if test "${target}" = "${build}"; then
+ TARGET_GETGROUPS_T=$ac_cv_type_getgroups
+else
+ case "${target}" in
+ # This condition may need some tweaking. It should include all
+ # targets where the array type of the second argument of getgroups
+ # is int and the type of gid_t is not equivalent to int.
+ *-*-sunos* | *-*-ultrix*)
+ TARGET_GETGROUPS_T=int
+ ;;
+ *)
+ TARGET_GETGROUPS_T=gid_t
+ ;;
+ esac
+fi
+AC_SUBST(TARGET_GETGROUPS_T)
+
+gcc_AC_FUNC_PRINTF_PTR
+gcc_AC_FUNC_MMAP_BLACKLIST
+
+case "${host}" in
+*-*-*vms*)
+ # Under VMS, vfork works very differently than on Unix. The standard test
+ # won't work, and it isn't easily adaptable. It makes more sense to
+ # just force it.
+ ac_cv_func_vfork_works=yes
+ ;;
+esac
+AC_FUNC_VFORK
+
+AM_ICONV
+# Until we have in-tree GNU iconv:
+LIBICONV_DEP=
+AC_SUBST(LIBICONV_DEP)
+
+AM_LC_MESSAGES
+
+# We will need to find libiberty.h and ansidecl.h
+saved_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -I${srcdir} -I${srcdir}/../include"
+gcc_AC_CHECK_DECLS(getenv atol sbrk abort atof getcwd getwd \
+ strsignal putc_unlocked fputs_unlocked fwrite_unlocked \
+ fprintf_unlocked strstr errno snprintf vasprintf \
+ malloc realloc calloc free basename getopt clock, , ,[
+#include "ansidecl.h"
+#include "system.h"])
+
+gcc_AC_CHECK_DECLS(getrlimit setrlimit getrusage, , ,[
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+])
+
+AC_TRY_COMPILE([
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+],[rlim_t l = 0;],,[AC_DEFINE([rlim_t],[long],
+[Define to \`long' if <sys/resource.h> doesn't define.])])
+
+gcc_AC_CHECK_DECLS(ldgetname, , ,[
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_LDFCN_H
+#include <ldfcn.h>
+#endif
+])
+
+gcc_AC_CHECK_DECLS(times, , ,[
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+])
+
+# More time-related stuff.
+AC_CACHE_CHECK(for struct tms, ac_cv_struct_tms, [
+AC_TRY_COMPILE([
+#include "ansidecl.h"
+#include "system.h"
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+], [struct tms tms;], ac_cv_struct_tms=yes, ac_cv_struct_tms=no)])
+if test $ac_cv_struct_tms = yes; then
+ AC_DEFINE(HAVE_STRUCT_TMS, 1,
+ [Define if <sys/times.h> defines struct tms.])
+fi
+
+# use gcc_cv_* here because this doesn't match the behavior of AC_CHECK_TYPE.
+# revisit after autoconf 2.50.
+AC_CACHE_CHECK(for clock_t, gcc_cv_type_clock_t, [
+AC_TRY_COMPILE([
+#include "ansidecl.h"
+#include "system.h"
+], [clock_t x;], gcc_cv_type_clock_t=yes, gcc_cv_type_clock_t=no)])
+if test $gcc_cv_type_clock_t = yes; then
+ AC_DEFINE(HAVE_CLOCK_T, 1,
+ [Define if <time.h> defines clock_t.])
+fi
+
+AC_CACHE_CHECK(for uchar, gcc_cv_type_uchar,
+[AC_TRY_COMPILE([
+#include "ansidecl.h"
+#include "system.h"
+],
+[if ((uchar *)0) return 0;
+ if (sizeof(uchar)) return 0;],
+ac_cv_type_uchar=yes, ac_cv_type_uchar=no)])
+if test $ac_cv_type_uchar = yes; then
+ AC_DEFINE(HAVE_UCHAR, 1,
+ [Define if <sys/types.h> defines \`uchar'.])
+fi
+
+# Restore CFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
+CFLAGS="$saved_CFLAGS"
+
+gcc_AC_INITFINI_ARRAY
+
+# mkdir takes a single argument on some systems.
+gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG
+
+# File extensions
+manext='.1'
+objext='.o'
+AC_SUBST(manext)
+AC_SUBST(objext)
+
+# With Setjmp/Longjmp based exception handling.
+AC_ARG_ENABLE(sjlj-exceptions,
+[ --enable-sjlj-exceptions
+ arrange to use setjmp/longjmp exception handling],
+[sjlj=`if test $enableval = yes; then echo 1; else echo 0; fi`
+AC_DEFINE_UNQUOTED(CONFIG_SJLJ_EXCEPTIONS, $sjlj,
+ [Define 0/1 to force the choice for exception handling model.])])
+
+if test x$host = x$target; then
+ AC_CHECK_LIB(unwind, main, use_libunwind_default=yes, use_libunwind_default=no)
+else
+ use_libunwind_default=no
+fi
+# Use libunwind based exception handling.
+AC_ARG_ENABLE(libunwind-exceptions,
+[ --enable-libunwind-exceptions force use libunwind for exceptions],
+use_libunwind_exceptions=$enableval,
+use_libunwind_exceptions=$use_libunwind_default)
+if test x"$use_libunwind_exceptions" = xyes; then
+ AC_DEFINE(USE_LIBUNWIND_EXCEPTIONS, 1,
+ [Define if gcc should use -lunwind.])
+fi
+
+# --------------------------------------------------------
+# Build, host, and target specific configuration fragments
+# --------------------------------------------------------
+
+# Collect build-machine-specific information.
+. ${srcdir}/config.build
+
+# Collect host-machine-specific information.
+. ${srcdir}/config.host
+
+target_gtfiles=
+
+# Collect target-machine-specific information.
+. ${srcdir}/config.gcc
+
+extra_objs="${host_extra_objs} ${extra_objs}"
+extra_gcc_objs="${host_extra_gcc_objs} ${extra_gcc_objs}"
+
+# Default the target-machine variables that were not explicitly set.
+if test x"$tm_file" = x
+then tm_file=$cpu_type/$cpu_type.h; fi
+
+if test x"$extra_headers" = x
+then extra_headers=; fi
+
+if test x$md_file = x
+then md_file=$cpu_type/$cpu_type.md; fi
+
+if test x$out_file = x
+then out_file=$cpu_type/$cpu_type.c; fi
+
+if test x"$tmake_file" = x
+then tmake_file=$cpu_type/t-$cpu_type
+fi
+
+if test x"$dwarf2" = xyes
+then tm_file="$tm_file tm-dwarf2.h"
+fi
+
+# Say what files are being used for the output code and MD file.
+echo "Using \`$srcdir/config/$out_file' for machine-specific logic."
+echo "Using \`$srcdir/config/$md_file' as machine description file."
+
+# If any of the xm_file variables contain nonexistent files, warn
+# about them and drop them.
+
+bx=
+for x in $build_xm_file; do
+ if test -f $srcdir/config/$x
+ then bx="$bx $x"
+ else AC_MSG_WARN($srcdir/config/$x does not exist.)
+ fi
+done
+build_xm_file="$bx"
+
+hx=
+for x in $host_xm_file; do
+ if test -f $srcdir/config/$x
+ then hx="$hx $x"
+ else AC_MSG_WARN($srcdir/config/$x does not exist.)
+ fi
+done
+host_xm_file="$hx"
+
+tx=
+for x in $xm_file; do
+ if test -f $srcdir/config/$x
+ then tx="$tx $x"
+ else AC_MSG_WARN($srcdir/config/$x does not exist.)
+ fi
+done
+xm_file="$tx"
+
+count=a
+for f in $tm_file; do
+ count=${count}x
+done
+if test $count = ax; then
+ echo "Using \`$srcdir/config/$tm_file' as target machine macro file."
+else
+ echo "Using the following target machine macro files:"
+ for f in $tm_file; do
+ echo " $srcdir/config/$f"
+ done
+fi
+
+if test x$need_64bit_hwint = xyes; then
+ AC_DEFINE(NEED_64BIT_HOST_WIDE_INT, 1,
+[Define to 1 if HOST_WIDE_INT must be 64 bits wide (see hwint.h).])
+fi
+
+count=a
+for f in $host_xm_file; do
+ count=${count}x
+done
+if test $count = a; then
+ :
+elif test $count = ax; then
+ echo "Using \`$srcdir/config/$host_xm_file' as host machine macro file."
+else
+ echo "Using the following host machine macro files:"
+ for f in $host_xm_file; do
+ echo " $srcdir/config/$f"
+ done
+fi
+echo "Using ${out_host_hook_obj} for host machine hooks."
+
+if test "$host_xm_file" != "$build_xm_file"; then
+ count=a
+ for f in $build_xm_file; do
+ count=${count}x
+ done
+ if test $count = a; then
+ :
+ elif test $count = ax; then
+ echo "Using \`$srcdir/config/$build_xm_file' as build machine macro file."
+ else
+ echo "Using the following build machine macro files:"
+ for f in $build_xm_file; do
+ echo " $srcdir/config/$f"
+ done
+ fi
+fi
+
+# Check if a valid thread package
+case ${enable_threads_flag} in
+ "" | no)
+ # No threads
+ target_thread_file='single'
+ ;;
+ yes)
+ # default
+ target_thread_file='single'
+ ;;
+ aix | dce | gnat | irix | posix | rtems | \
+ single | solaris | vxworks | win32 )
+ target_thread_file=${enable_threads_flag}
+ ;;
+ *)
+ echo "${enable_threads_flag} is an unknown thread package" 1>&2
+ exit 1
+ ;;
+esac
+
+if test x${thread_file} = x; then
+ # No thread file set by target-specific clauses in config.gcc,
+ # so use file chosen by default logic above
+ thread_file=${target_thread_file}
+fi
+
+if test x$enable___cxa_atexit = xyes || \
+ test x$enable___cxa_atexit = x -a x$default_use_cxa_atexit = xyes; then
+ AC_CHECK_FUNC(__cxa_atexit,
+ [AC_DEFINE(DEFAULT_USE_CXA_ATEXIT, 1,
+ [Define if you want to use __cxa_atexit, rather than atexit, to
+ register C++ destructors for local statics and global objects.
+ This is essential for fully standards-compliant handling of
+ destructors, but requires __cxa_atexit in libc.])],
+ echo "__cxa_atexit can't be enabled on this target")
+fi
+
+# Look for a file containing extra machine modes.
+if test -n "$extra_modes" && test -f $srcdir/config/$extra_modes; then
+ extra_modes_file='$(srcdir)'/config/${extra_modes}
+ AC_SUBST(extra_modes_file)
+ AC_DEFINE_UNQUOTED(EXTRA_MODES_FILE, "config/$extra_modes",
+ [Define to the name of a file containing a list of extra machine modes
+ for this architecture.])
+fi
+
+# auto-host.h is the file containing items generated by autoconf and is
+# the first file included by config.h.
+# If host=build, it is correct to have bconfig include auto-host.h
+# as well. If host!=build, we are in error and need to do more
+# work to find out the build config parameters.
+if test x$host = x$build
+then
+ build_auto=auto-host.h
+ FORBUILD=..
+else
+ # We create a subdir, then run autoconf in the subdir.
+ # To prevent recursion we set host and build for the new
+ # invocation of configure to the build for this invocation
+ # of configure.
+ tempdir=build.$$
+ rm -rf $tempdir
+ mkdir $tempdir
+ cd $tempdir
+ case ${srcdir} in
+ /* | [A-Za-z]:[\\/]* ) realsrcdir=${srcdir};;
+ *) realsrcdir=../${srcdir};;
+ esac
+ saved_CFLAGS="${CFLAGS}"
+ CC="${CC_FOR_BUILD}" CFLAGS="${CFLAGS_FOR_BUILD}" \
+ ${realsrcdir}/configure \
+ --target=$target_alias --host=$build_alias --build=$build_alias
+ CFLAGS="${saved_CFLAGS}"
+
+ # We just finished tests for the build machine, so rename
+ # the file auto-build.h in the gcc directory.
+ mv auto-host.h ../auto-build.h
+ cd ..
+ rm -rf $tempdir
+ build_auto=auto-build.h
+ FORBUILD=../${build_subdir}
+fi
+AC_SUBST(FORBUILD)
+
+tm_file="${tm_file} defaults.h"
+tm_p_file="${tm_p_file} tm-preds.h"
+host_xm_file="auto-host.h ansidecl.h ${host_xm_file}"
+build_xm_file="${build_auto} ansidecl.h ${build_xm_file}"
+# We don't want ansidecl.h in target files, write code there in ISO/GNU C.
+# put this back in temporarily.
+xm_file="ansidecl.h ${xm_file}"
+
+# --------
+# UNSORTED
+# --------
+
+# Get the version trigger filename from the toplevel
+if test "${with_gcc_version_trigger+set}" = set; then
+ gcc_version_trigger=$with_gcc_version_trigger
+else
+ gcc_version_trigger=${srcdir}/version.c
+fi
+changequote(,)dnl
+gcc_version_full=`grep version_string ${gcc_version_trigger} | sed -e 's/.*"\([^"]*\)".*/\1/'`
+gcc_version=`echo ${gcc_version_full} | sed -e 's/\([^ ]*\) .*/\1/'`
+
+# Compile in configure arguments.
+if test -f configargs.h ; then
+ # Being re-configured.
+ gcc_config_arguments=`grep configuration_arguments configargs.h | sed -e 's/.*"\([^"]*\)".*/\1/'`
+ gcc_config_arguments="$gcc_config_arguments : (reconfigured) $TOPLEVEL_CONFIGURE_ARGUMENTS"
+else
+ gcc_config_arguments="$TOPLEVEL_CONFIGURE_ARGUMENTS"
+fi
+
+# Double all backslashes and backslash all quotes to turn
+# gcc_config_arguments into a C string.
+sed -e 's/\\/\\\\/g; s/"/\\"/g' <<EOF >conftest.out
+$gcc_config_arguments
+EOF
+gcc_config_arguments_str=`cat conftest.out`
+rm -f conftest.out
+
+cat > configargs.h <<EOF
+/* Generated automatically. */
+static const char configuration_arguments[] = "$gcc_config_arguments_str";
+static const char thread_model[] = "$thread_file";
+
+static const struct {
+ const char *name, *value;
+} configure_default_options[] = $configure_default_options;
+EOF
+changequote([,])dnl
+
+# Internationalization
+PACKAGE=gcc
+VERSION="$gcc_version"
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+ZW_GNU_GETTEXT_SISTER_DIR
+
+# If LIBINTL contains LIBICONV, then clear LIBICONV so we don't get
+# -liconv on the link line twice.
+case "$LIBINTL" in *$LIBICONV*)
+ LIBICONV= ;;
+esac
+
+# Windows32 Registry support for specifying GCC installation paths.
+AC_ARG_ENABLE(win32-registry,
+[ --disable-win32-registry
+ disable lookup of installation paths in the
+ Registry on Windows hosts
+ --enable-win32-registry enable registry lookup (default)
+ --enable-win32-registry=KEY
+ use KEY instead of GCC version as the last portion
+ of the registry key],,)
+case $host_os in
+ win32 | pe | cygwin* | mingw32* | uwin*)
+AC_MSG_CHECKING(whether windows registry support is requested)
+if test "x$enable_win32_registry" != xno; then
+ AC_DEFINE(ENABLE_WIN32_REGISTRY, 1,
+[Define to 1 if installation paths should be looked up in Windows32
+ Registry. Ignored on non windows32 hosts.])
+ AC_MSG_RESULT(yes)
+ AC_SEARCH_LIBS(RegOpenKeyExA, advapi32)
+else
+ AC_MSG_RESULT(no)
+fi
+
+# Check if user specified a different registry key.
+case "x${enable_win32_registry}" in
+x | xyes)
+ # default.
+ gcc_cv_win32_registry_key="$VERSION"
+ ;;
+xno)
+ # no registry lookup.
+ gcc_cv_win32_registry_key=''
+ ;;
+*)
+ # user-specified key.
+ gcc_cv_win32_registry_key="$enable_win32_registry"
+ ;;
+esac
+
+if test "x$enable_win32_registry" != xno; then
+ AC_MSG_CHECKING(registry key on windows hosts)
+ AC_DEFINE_UNQUOTED(WIN32_REGISTRY_KEY, "$gcc_cv_win32_registry_key",
+ [Define to be the last portion of registry key on windows hosts.])
+ AC_MSG_RESULT($gcc_cv_win32_registry_key)
+fi
+;;
+esac
+
+# Get an absolute path to the GCC top-level source directory
+holddir=`${PWDCMD-pwd}`
+cd $srcdir
+topdir=`${PWDCMD-pwd}`
+cd $holddir
+
+# Conditionalize the makefile for this host machine.
+xmake_file=
+for f in ${host_xmake_file}
+do
+ if test -f ${srcdir}/config/$f
+ then
+ xmake_file="${xmake_file} \$(srcdir)/config/$f"
+ fi
+done
+
+# Conditionalize the makefile for this target machine.
+tmake_file_=
+for f in ${tmake_file}
+do
+ if test -f ${srcdir}/config/$f
+ then
+ tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
+ fi
+done
+tmake_file="${tmake_file_}"
+
+symbolic_link='ln -s'
+
+# If the host doesn't support symlinks, modify CC in
+# FLAGS_TO_PASS so CC="stage1/xgcc -Bstage1/" works.
+# Otherwise, we can use "CC=$(CC)".
+rm -f symtest.tem
+if $symbolic_link $srcdir/gcc.c symtest.tem 2>/dev/null
+then
+ cc_set_by_configure="\$(CC)"
+ quoted_cc_set_by_configure="\$(CC)"
+ stage_prefix_set_by_configure="\$(STAGE_PREFIX)"
+ quoted_stage_prefix_set_by_configure="\$(STAGE_PREFIX)"
+else
+ rm -f symtest.tem
+ if cp -p $srcdir/gcc.c symtest.tem 2>/dev/null
+ then
+ symbolic_link="cp -p"
+ else
+ symbolic_link="cp"
+ fi
+ cc_set_by_configure="\`case '\$(CC)' in stage*) echo '\$(CC)' | sed -e 's|stage|../stage|g';; *) echo '\$(CC)';; esac\`"
+ quoted_cc_set_by_configure="\\\`case '\\\$(CC)' in stage*) echo '\\\$(CC)' | sed -e 's|stage|../stage|g';; *) echo '\\\$(CC)';; esac\\\`"
+ stage_prefix_set_by_configure="\`case '\$(STAGE_PREFIX)' in stage*) echo '\$(STAGE_PREFIX)' | sed -e 's|stage|../stage|g';; *) echo '\$(STAGE_PREFIX)';; esac\`"
+ quoted_stage_prefix_set_by_configure="\\\`case '\\\$(STAGE_PREFIX)' in stage*) echo '\\\$(STAGE_PREFIX)' | sed -e 's|stage|../stage|g';; *) echo '\\\$(STAGE_PREFIX)';; esac\\\`"
+fi
+rm -f symtest.tem
+
+out_object_file=`basename $out_file .c`.o
+
+tm_file_list=
+tm_include_list=
+for f in $tm_file; do
+ case $f in
+ defaults.h )
+ tm_file_list="${tm_file_list} \$(srcdir)/$f"
+ tm_include_list="${tm_include_list} $f"
+ ;;
+ * )
+ tm_file_list="${tm_file_list} \$(srcdir)/config/$f"
+ tm_include_list="${tm_include_list} config/$f"
+ ;;
+ esac
+done
+
+tm_p_file_list=
+tm_p_include_list=
+for f in $tm_p_file; do
+ case $f in
+ tm-preds.h )
+ tm_p_file_list="${tm_p_file_list} $f"
+ tm_p_include_list="${tm_p_include_list} $f"
+ ;;
+ * )
+ tm_p_file_list="${tm_p_file_list} \$(srcdir)/config/$f"
+ tm_p_include_list="${tm_p_include_list} config/$f"
+ esac
+done
+
+xm_file_list=
+xm_include_list=
+for f in $xm_file; do
+ case $f in
+ ansidecl.h )
+ xm_file_list="${xm_file_list} \$(srcdir)/../include/$f"
+ xm_include_list="${xm_include_list} $f"
+ ;;
+ auto-host.h )
+ xm_file_list="${xm_file_list} $f"
+ xm_include_list="${xm_include_list} $f"
+ ;;
+ * )
+ xm_file_list="${xm_file_list} \$(srcdir)/config/$f"
+ xm_include_list="${xm_include_list} config/$f"
+ ;;
+ esac
+done
+
+host_xm_file_list=
+host_xm_include_list=
+for f in $host_xm_file; do
+ case $f in
+ ansidecl.h )
+ host_xm_file_list="${host_xm_file_list} \$(srcdir)/../include/$f"
+ host_xm_include_list="${host_xm_include_list} $f"
+ ;;
+ auto-host.h )
+ host_xm_file_list="${host_xm_file_list} $f"
+ host_xm_include_list="${host_xm_include_list} $f"
+ ;;
+ * )
+ host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f"
+ host_xm_include_list="${host_xm_include_list} config/$f"
+ ;;
+ esac
+done
+
+build_xm_file_list=
+for f in $build_xm_file; do
+ case $f in
+ ansidecl.h )
+ build_xm_file_list="${build_xm_file_list} \$(srcdir)/../include/$f"
+ build_xm_include_list="${build_xm_include_list} $f"
+ ;;
+ auto-build.h | auto-host.h )
+ build_xm_file_list="${build_xm_file_list} $f"
+ build_xm_include_list="${build_xm_include_list} $f"
+ ;;
+ * )
+ build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f"
+ build_xm_include_list="${build_xm_include_list} config/$f"
+ ;;
+ esac
+done
+
+# Define macro CROSS_COMPILE in compilation if this is a cross-compiler.
+# Also use all.cross instead of all.internal and adjust SYSTEM_HEADER_DIR.
+CROSS= AC_SUBST(CROSS)
+ALL=all.internal AC_SUBST(ALL)
+SYSTEM_HEADER_DIR='$(NATIVE_SYSTEM_HEADER_DIR)' AC_SUBST(SYSTEM_HEADER_DIR)
+if test x$host != x$target
+then
+ CROSS="-DCROSS_COMPILE"
+ ALL=all.cross
+ SYSTEM_HEADER_DIR='$(CROSS_SYSTEM_HEADER_DIR)'
+ case "$host","$target" in
+ # Darwin crosses can use the host system's libraries and headers,
+ # because of the fat library support. Of course, it must be the
+ # same version of Darwin on both sides. Allow the user to
+ # just say --target=foo-darwin without a version number to mean
+ # "the version on this system".
+ *-*-darwin*,*-*-darwin*)
+ hostos=`echo $host | sed 's/.*-darwin/darwin/'`
+ targetos=`echo $target | sed 's/.*-darwin/darwin/'`
+ if test $hostos = $targetos -o $targetos = darwin ; then
+ CROSS=
+ SYSTEM_HEADER_DIR='$(NATIVE_SYSTEM_HEADER_DIR)'
+ with_headers=yes
+ fi
+ ;;
+
+ i?86-*-*,x86_64-*-* \
+ | powerpc*-*-*,powerpc64*-*-*)
+ CROSS="$CROSS -DNATIVE_CROSS" ;;
+ esac
+elif test "x$TARGET_SYSTEM_ROOT" != x; then
+ # This is just $(TARGET_SYSTEM_ROOT)$(NATIVE_SYSTEM_HEADER_DIR)
+ SYSTEM_HEADER_DIR='$(CROSS_SYSTEM_HEADER_DIR)'
+fi
+
+# If this is a cross-compiler that does not
+# have its own set of headers then define
+# inhibit_libc
+
+# If this is using newlib, without having the headers available now,
+# then define inhibit_libc in LIBGCC2_CFLAGS.
+# This prevents libgcc2 from containing any code which requires libc
+# support.
+inhibit_libc=
+if { { test x$host != x$target && test "x$with_sysroot" = x ; } ||
+ test x$with_newlib = xyes ; } &&
+ { test "x$with_headers" = x || test "x$with_headers" = xno ; } ; then
+ inhibit_libc=-Dinhibit_libc
+fi
+AC_SUBST(inhibit_libc)
+
+# When building gcc with a cross-compiler, we need to adjust things so
+# that the generator programs are still built with the native compiler.
+# Also, we cannot run fixincludes or fix-header.
+
+# These are the normal (build=host) settings:
+BUILD_PREFIX= AC_SUBST(BUILD_PREFIX)
+BUILD_PREFIX_1=ignore- AC_SUBST(BUILD_PREFIX_1)
+CC_FOR_BUILD='$(CC)' AC_SUBST(CC_FOR_BUILD)
+BUILD_CFLAGS='$(ALL_CFLAGS)' AC_SUBST(BUILD_CFLAGS)
+
+STMP_FIXINC=stmp-fixinc AC_SUBST(STMP_FIXINC)
+
+# Possibly disable fixproto, on a per-target basis.
+case ${use_fixproto} in
+ no)
+ STMP_FIXPROTO=
+ ;;
+ yes)
+ STMP_FIXPROTO=stmp-fixproto
+ ;;
+esac
+AC_SUBST(STMP_FIXPROTO)
+
+# And these apply if build != host, or we are generating coverage data
+if test x$build != x$host || test "x$coverage_flags" != x
+then
+ BUILD_PREFIX=build-
+ BUILD_PREFIX_1=build-
+ BUILD_CFLAGS='$(INTERNAL_CFLAGS) $(T_CFLAGS) $(CFLAGS_FOR_BUILD)'
+
+ if test "x$TARGET_SYSTEM_ROOT" = x; then
+ STMP_FIXINC=
+ STMP_FIXPROTO=
+ fi
+fi
+
+# Expand extra_headers to include complete path.
+# This substitutes for lots of t-* files.
+extra_headers_list=
+# Prepend $(srcdir)/config/${cpu_type}/ to every entry in extra_headers.
+for file in ${extra_headers} ; do
+ extra_headers_list="${extra_headers_list} \$(srcdir)/config/${cpu_type}/${file}"
+done
+
+# Add a definition of USE_COLLECT2 if system wants one.
+case $use_collect2 in
+ no) use_collect2= ;;
+ "") ;;
+ *)
+ host_xm_defines="${host_xm_defines} USE_COLLECT2"
+ xm_defines="${xm_defines} USE_COLLECT2"
+ ;;
+esac
+
+# Identify the assembler which will work hand-in-glove with the newly
+# built GCC, so that we can examine its features. This is the assembler
+# which will be driven by the driver program.
+#
+# If build != host, and we aren't building gas in-tree, we identify a
+# build->target assembler and hope that it will have the same features
+# as the host->target assembler we'll be using.
+AC_MSG_CHECKING(what assembler to use)
+in_tree_gas=no
+gcc_cv_as=
+gcc_cv_gas_major_version=
+gcc_cv_gas_minor_version=
+gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
+if test -x "$DEFAULT_ASSEMBLER"; then
+ gcc_cv_as="$DEFAULT_ASSEMBLER"
+elif test -x "$AS"; then
+ gcc_cv_as="$AS"
+elif test -x as$host_exeext; then
+ # Build using assembler in the current directory.
+ gcc_cv_as=./as$host_exeext
+elif test -f $gcc_cv_as_gas_srcdir/configure.in \
+ && test -f ../gas/Makefile; then
+ # Single tree build which includes gas.
+ in_tree_gas=yes
+ _gcc_COMPUTE_GAS_VERSION
+ rm -f as$host_exeext
+ $symbolic_link ../gas/as-new$host_exeext as$host_exeext 2>/dev/null
+ in_tree_gas_is_elf=no
+ if grep 'obj_format = elf' ../gas/Makefile > /dev/null \
+ || (grep 'obj_format = multi' ../gas/Makefile \
+ && grep 'extra_objects =.* obj-elf' ../gas/Makefile) > /dev/null
+ then
+ in_tree_gas_is_elf=yes
+ fi
+fi
+
+if test "x$gcc_cv_as" = x; then
+ # Search the same directories that the installed compiler will
+ # search. Else we may find the wrong assembler and lose. If we
+ # do not find a suitable assembler binary, then try the user's
+ # path.
+ #
+ # Also note we have to check MD_EXEC_PREFIX before checking the
+ # user's path. Unfortunately, there is no good way to get at the
+ # value of MD_EXEC_PREFIX here. So we do a brute force search
+ # through all the known MD_EXEC_PREFIX values. Ugh. This needs
+ # to be fixed as part of the make/configure rewrite too.
+
+ if test "x$exec_prefix" = xNONE; then
+ if test "x$prefix" = xNONE; then
+ test_prefix=/usr/local
+ else
+ test_prefix=$prefix
+ fi
+ else
+ test_prefix=$exec_prefix
+ fi
+
+ # If the loop below does not find an assembler, then use whatever
+ # one we can find in the users's path.
+ # user's path.
+ if test "x$program_prefix" != xNONE; then
+ gcc_cv_as=${program_prefix}as$host_exeext
+ else
+ gcc_cv_as=`echo as | sed ${program_transform_name}`$host_exeext
+ fi
+
+ test_dirs="$test_prefix/libexec/gcc/$target_noncanonical/$gcc_version \
+ $test_prefix/libexec/gcc/$target_noncanonical \
+ /usr/lib/gcc/$target_noncanonical/$gcc_version \
+ /usr/lib/gcc/$target_noncanonical \
+ $test_prefix/$target_noncanonical/bin/$target_noncanonical/$gcc_version \
+ $test_prefix/$target_noncanonical/bin"
+
+ if test x$host = x$target; then
+ test_dirs="$test_dirs \
+ /usr/libexec \
+ /usr/ccs/gcc \
+ /usr/ccs/bin \
+ /udk/usr/ccs/bin \
+ /bsd43/usr/lib/cmplrs/cc \
+ /usr/cross64/usr/bin \
+ /usr/lib/cmplrs/cc \
+ /sysv/usr/lib/cmplrs/cc \
+ /svr4/usr/lib/cmplrs/cc \
+ /usr/bin"
+ fi
+
+ for dir in $test_dirs; do
+ if test -x $dir/as$host_exeext; then
+ gcc_cv_as=$dir/as$host_exeext
+ break;
+ fi
+ done
+fi
+case $in_tree_gas in
+ yes)
+ AC_MSG_RESULT("newly built gas")
+ ;;
+ no)
+ AC_MSG_RESULT($gcc_cv_as)
+ ;;
+esac
+
+# Identify the linker which will work hand-in-glove with the newly
+# built GCC, so that we can examine its features. This is the linker
+# which will be driven by the driver program.
+#
+# If build != host, and we aren't building gas in-tree, we identify a
+# build->target linker and hope that it will have the same features
+# as the host->target linker we'll be using.
+AC_MSG_CHECKING(what linker to use)
+in_tree_ld=no
+gcc_cv_ld=
+gcc_cv_gld_major_version=
+gcc_cv_gld_minor_version=
+gcc_cv_ld_gld_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/ld
+gcc_cv_ld_bfd_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/bfd
+if test -x "$DEFAULT_LINKER"; then
+ gcc_cv_ld="$DEFAULT_LINKER"
+elif test -x "$LD"; then
+ gcc_cv_ld="$LD"
+elif test -x collect-ld$host_exeext; then
+ # Build using linker in the current directory.
+ gcc_cv_ld=./collect-ld$host_exeext
+elif test -f $gcc_cv_ld_gld_srcdir/configure.in \
+ && test -f ../ld/Makefile; then
+ # Single tree build which includes ld.
+ in_tree_ld=yes
+ in_tree_ld_is_elf=no
+ if (grep 'EMUL = .*elf' ../ld/Makefile \
+ || grep 'EMUL = .*linux' ../ld/Makefile) > /dev/null; then
+ in_tree_ld_is_elf=yes
+ fi
+ for f in $gcc_cv_ld_bfd_srcdir/configure $gcc_cv_ld_gld_srcdir/configure $gcc_cv_ld_gld_srcdir/configure.in $gcc_cv_ld_gld_srcdir/Makefile.in
+ do
+changequote(,)dnl
+ gcc_cv_gld_version=`grep '^VERSION=[0-9]*\.[0-9]*' $f`
+changequote([,])dnl
+ if test x$gcc_cv_gld_version != x; then
+ break
+ fi
+ done
+changequote(,)dnl
+ gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
+ gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
+changequote([,])dnl
+ rm -f collect-ld$host_exeext
+ $symbolic_link ../ld/ld-new$host_exeext collect-ld$host_exeext \
+ 2>/dev/null
+fi
+
+if test "x$gcc_cv_ld" = x; then
+ # Search the same directories that the installed compiler will
+ # search. Else we may find the wrong linker and lose. If we
+ # do not find a suitable linker binary, then try the user's
+ # path.
+ #
+ # Also note we have to check MD_EXEC_PREFIX before checking the
+ # user's path. Unfortunately, there is no good way to get at the
+ # value of MD_EXEC_PREFIX here. So we do a brute force search
+ # through all the known MD_EXEC_PREFIX values. Ugh. This needs
+ # to be fixed as part of the make/configure rewrite too.
+
+ if test "x$exec_prefix" = xNONE; then
+ if test "x$prefix" = xNONE; then
+ test_prefix=/usr/local
+ else
+ test_prefix=$prefix
+ fi
+ else
+ test_prefix=$exec_prefix
+ fi
+
+ # If the loop below does not find an linker, then use whatever
+ # one we can find in the users's path.
+ # user's path.
+ if test "x$program_prefix" != xNONE; then
+ gcc_cv_ld=${program_prefix}ld$host_exeext
+ else
+ gcc_cv_ld=`echo ld | sed ${program_transform_name}`$host_exeext
+ fi
+
+ test_dirs="$test_prefix/libexec/gcc/$target_noncanonical/$gcc_version \
+ $test_prefix/libexec/gcc/$target_noncanonical \
+ /usr/lib/gcc/$target_noncanonical/$gcc_version \
+ /usr/lib/gcc/$target_noncanonical \
+ $test_prefix/$target_noncanonical/bin/$target_noncanonical/$gcc_version \
+ $test_prefix/$target_noncanonical/bin"
+
+ if test x$host = x$target; then
+ test_dirs="$test_dirs \
+ /usr/libexec \
+ /usr/ccs/gcc \
+ /usr/ccs/bin \
+ /udk/usr/ccs/bin \
+ /bsd43/usr/lib/cmplrs/cc \
+ /usr/cross64/usr/bin \
+ /usr/lib/cmplrs/cc \
+ /sysv/usr/lib/cmplrs/cc \
+ /svr4/usr/lib/cmplrs/cc \
+ /usr/bin"
+ fi
+
+ for dir in $test_dirs; do
+ if test -x $dir/ld$host_exeext; then
+ gcc_cv_ld=$dir/ld$host_exeext
+ break;
+ fi
+ done
+fi
+case $in_tree_ld in
+ yes)
+ AC_MSG_RESULT("newly built ld")
+ ;;
+ no)
+ AC_MSG_RESULT($gcc_cv_ld)
+ ;;
+esac
+
+# Figure out what nm we will be using.
+gcc_cv_binutils_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/binutils
+AC_MSG_CHECKING(what nm to use)
+in_tree_nm=no
+if test -x nm$host_exeext; then
+ gcc_cv_nm=./nm$host_exeext
+elif test -f $gcc_cv_binutils_srcdir/configure.in \
+ && test -f ../binutils/Makefile; then
+ # Single tree build which includes binutils.
+ in_tree_nm=yes
+ gcc_cv_nm=./nm$host_exeext
+ rm -f nm$host_exeext
+ $symbolic_link ../binutils/nm-new$host_exeext nm$host_exeext 2>/dev/null
+elif test "x$program_prefix" != xNONE; then
+ gcc_cv_nm=${program_prefix}nm$host_exeext
+else
+ gcc_cv_nm=`echo nm | sed ${program_transform_name}`$host_exeext
+fi
+case $in_tree_nm in
+ yes) AC_MSG_RESULT("newly built nm") ;;
+ no) AC_MSG_RESULT($gcc_cv_nm) ;;
+esac
+
+# Figure out what objdump we will be using.
+AC_MSG_CHECKING(what objdump to use)
+in_tree_objdump=no
+if test -x objdump$host_exeext; then
+ gcc_cv_objdump=./objdump$host_exeext
+elif test -f $gcc_cv_binutils_srcdir/configure.in \
+ && test -f ../binutils/Makefile; then
+ # Single tree build which includes binutils.
+ in_tree_objdump=yes
+ gcc_cv_objdump=./objdump$host_exeext
+ rm -f objdump$host_exeext
+ $symbolic_link ../binutils/objdump$host_exeext \
+ objdump$host_exeext 2>/dev/null
+elif test "x$program_prefix" != xNONE; then
+ gcc_cv_objdump=${program_prefix}objdump$host_exeext
+else
+ gcc_cv_objdump=`echo objdump | \
+ sed ${program_transform_name}`$host_exeext
+fi
+case $in_tree_objdump in
+ yes) AC_MSG_RESULT("newly built objdump") ;;
+ no) AC_MSG_RESULT($gcc_cv_objdump) ;;
+esac
+
+# Figure out what assembler alignment features are present.
+gcc_GAS_CHECK_FEATURE([.balign and .p2align], gcc_cv_as_balign_and_p2align,
+ [2,6,0],,
+[.balign 4
+.p2align 2],,
+[AC_DEFINE(HAVE_GAS_BALIGN_AND_P2ALIGN, 1,
+ [Define if your assembler supports .balign and .p2align.])])
+
+gcc_GAS_CHECK_FEATURE([.p2align with maximum skip], gcc_cv_as_max_skip_p2align,
+ [2,8,0],,
+ [.p2align 4,,7],,
+[AC_DEFINE(HAVE_GAS_MAX_SKIP_P2ALIGN, 1,
+ [Define if your assembler supports specifying the maximum number
+ of bytes to skip when using the GAS .p2align command.])])
+
+gcc_GAS_CHECK_FEATURE([working .subsection -1], gcc_cv_as_subsection_m1,
+ [elf,2,9,0],,
+ [conftest_label1: .word 0
+.subsection -1
+conftest_label2: .word 0
+.previous],
+ [if test x$gcc_cv_nm != x; then
+ $gcc_cv_nm conftest.o | grep conftest_label1 > conftest.nm1
+ $gcc_cv_nm conftest.o | grep conftest_label2 | sed -e 's/label2/label1/' > conftest.nm2
+ if cmp conftest.nm1 conftest.nm2 > /dev/null 2>&1
+ then :
+ else gcc_cv_as_subsection_m1=yes
+ fi
+ rm -f conftest.nm1 conftest.nm2
+ fi],
+ [AC_DEFINE(HAVE_GAS_SUBSECTION_ORDERING, 1,
+ [Define if your assembler supports .subsection and .subsection -1 starts
+ emitting at the beginning of your section.])])
+
+gcc_GAS_CHECK_FEATURE([.weak], gcc_cv_as_weak,
+ [2,2,0],,
+ [ .weak foobar],,
+[AC_DEFINE(HAVE_GAS_WEAK, 1, [Define if your assembler supports .weak.])])
+
+# .hidden needs to be supported in both the assembler and the linker,
+# because GNU LD versions before 2.12.1 have buggy support for STV_HIDDEN.
+# This is irritatingly difficult to feature test for; we have to check the
+# date string after the version number. If we've got an in-tree
+# ld, we don't know its patchlevel version, so we set the baseline at 2.13
+# to be safe.
+# The gcc_GAS_CHECK_FEATURE call just sets a cache variable.
+gcc_GAS_CHECK_FEATURE([.hidden], gcc_cv_as_hidden,
+ [elf,2,13,0],,
+[ .hidden foobar
+foobar:])
+
+AC_CACHE_CHECK(linker for .hidden support, gcc_cv_ld_hidden,
+[if test $in_tree_ld = yes ; then
+ gcc_cv_ld_hidden=no
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 13 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_hidden=yes
+ fi
+else
+ gcc_cv_ld_hidden=yes
+ ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q`
+ if echo "$ld_ver" | grep GNU > /dev/null; then
+changequote(,)dnl
+ ld_vers=`echo $ld_ver | sed -n \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\)$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\)[ ].*$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)[ ].*$,\1,p' \
+ -e 's,^.*[ ]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)[ ].*$,\1,p'`
+ ld_date=`echo $ld_ver | sed -n 's,^.*\([2-9][0-9][0-9][0-9]\)[-]*\([01][0-9]\)[-]*\([0-3][0-9]\).*$,\1\2\3,p'`
+ if test 0"$ld_date" -lt 20020404; then
+ if test -n "$ld_date"; then
+ # If there was date string, but was earlier than 2002-04-04, fail
+ gcc_cv_ld_hidden=no
+ elif test -z "$ld_vers"; then
+ # If there was no date string nor ld version number, something is wrong
+ gcc_cv_ld_hidden=no
+ else
+ ld_vers_major=`expr "$ld_vers" : '\([0-9]*\)'`
+ ld_vers_minor=`expr "$ld_vers" : '[0-9]*\.\([0-9]*\)'`
+ ld_vers_patch=`expr "$ld_vers" : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
+ test -z "$ld_vers_patch" && ld_vers_patch=0
+ if test "$ld_vers_major" -lt 2; then
+ gcc_cv_ld_hidden=no
+ elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 12; then
+ gcc_cv_ld_hidden="no"
+ elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -eq 12 -a "$ld_vers_patch" -eq 0; then
+ gcc_cv_ld_hidden=no
+ fi
+ fi
+changequote([,])dnl
+ fi
+ else
+ case "${target}" in
+ hppa64*-*-hpux* | ia64*-*-hpux*)
+ gcc_cv_ld_hidden=yes
+ ;;
+ *)
+ gcc_cv_ld_hidden=no
+ ;;
+ esac
+ fi
+fi])
+libgcc_visibility=no
+AC_SUBST(libgcc_visibility)
+if test $gcc_cv_as_hidden = yes && test $gcc_cv_ld_hidden = yes; then
+ libgcc_visibility=yes
+ AC_DEFINE(HAVE_GAS_HIDDEN, 1,
+ [Define if your assembler and linker support .hidden.])
+fi
+
+# Check if we have .[us]leb128, and support symbol arithmetic with it.
+gcc_GAS_CHECK_FEATURE([.sleb128 and .uleb128], gcc_cv_as_leb128,
+ [elf,2,11,0],,
+[ .data
+ .uleb128 L2 - L1
+L1:
+ .uleb128 1280
+ .sleb128 -1010
+L2:],
+ [# GAS versions before 2.11 do not support uleb128,
+ # despite appearing to.
+ # ??? There exists an elf-specific test that will crash
+ # the assembler. Perhaps it's better to figure out whether
+ # arbitrary sections are supported and try the test.
+ as_ver=`$gcc_cv_as --version 2>/dev/null | sed 1q`
+ if echo "$as_ver" | grep GNU > /dev/null; then
+changequote(,)dnl
+ as_ver=`echo $as_ver | sed -e 's/GNU assembler \([0-9.][0-9.]*\).*/\1/'`
+ as_major=`echo $as_ver | sed 's/\..*//'`
+ as_minor=`echo $as_ver | sed 's/[^.]*\.\([0-9]*\).*/\1/'`
+changequote([,])dnl
+ if test $as_major -eq 2 && test $as_minor -lt 11
+ then :
+ else gcc_cv_as_leb128=yes
+ fi
+ fi],
+ [AC_DEFINE(HAVE_AS_LEB128, 1,
+ [Define if your assembler supports .sleb128 and .uleb128.])])
+
+# GAS versions up to and including 2.11.0 may mis-optimize
+# .eh_frame data.
+gcc_GAS_CHECK_FEATURE(eh_frame optimization, gcc_cv_as_eh_frame,
+ [elf,2,12,0],,
+[ .text
+.LFB1:
+ .4byte 0
+.L1:
+ .4byte 0
+.LFE1:
+ .section .eh_frame,"aw",@progbits
+__FRAME_BEGIN__:
+ .4byte .LECIE1-.LSCIE1
+.LSCIE1:
+ .4byte 0x0
+ .byte 0x1
+ .ascii "z\0"
+ .byte 0x1
+ .byte 0x78
+ .byte 0x1a
+ .byte 0x0
+ .byte 0x4
+ .4byte 1
+ .p2align 1
+.LECIE1:
+.LSFDE1:
+ .4byte .LEFDE1-.LASFDE1
+.LASFDE1:
+ .4byte .LASFDE1-__FRAME_BEGIN__
+ .4byte .LFB1
+ .4byte .LFE1-.LFB1
+ .byte 0x4
+ .4byte .LFE1-.LFB1
+ .byte 0x4
+ .4byte .L1-.LFB1
+.LEFDE1:],
+[ dnl # For autoconf 2.5x, must protect trailing spaces with @&t@.
+cat > conftest.lit <<EOF
+ 0000 10000000 00000000 017a0001 781a0004 .........z..x...
+ 0010 01000000 12000000 18000000 00000000 ................
+ 0020 08000000 04080000 0044 .........D @&t@
+EOF
+cat > conftest.big <<EOF
+ 0000 00000010 00000000 017a0001 781a0004 .........z..x...
+ 0010 00000001 00000012 00000018 00000000 ................
+ 0020 00000008 04000000 0844 .........D @&t@
+EOF
+ # If the assembler didn't choke, and we can objdump,
+ # and we got the correct data, then succeed.
+ if test x$gcc_cv_objdump != x \
+ && $gcc_cv_objdump -s -j .eh_frame conftest.o 2>/dev/null \
+ | tail -3 > conftest.got \
+ && { cmp conftest.lit conftest.got > /dev/null 2>&1 \
+ || cmp conftest.big conftest.got > /dev/null 2>&1; }
+ then
+ gcc_cv_as_eh_frame=yes
+ elif AC_TRY_COMMAND($gcc_cv_as -o conftest.o --traditional-format /dev/null); then
+ gcc_cv_as_eh_frame=buggy
+ else
+ # Uh oh, what do we do now?
+ gcc_cv_as_eh_frame=no
+ fi])
+
+if test $gcc_cv_as_eh_frame = buggy; then
+ AC_DEFINE(USE_AS_TRADITIONAL_FORMAT, 1,
+ [Define if your assembler mis-optimizes .eh_frame data.])
+fi
+
+gcc_GAS_CHECK_FEATURE(section merging support, gcc_cv_as_shf_merge,
+ [elf,2,12,0], [--fatal-warnings],
+ [.section .rodata.str, "aMS", @progbits, 1])
+AC_DEFINE_UNQUOTED(HAVE_GAS_SHF_MERGE,
+ [`if test $gcc_cv_as_shf_merge = yes; then echo 1; else echo 0; fi`],
+[Define 0/1 if your assembler supports marking sections with SHF_MERGE flag.])
+
+# Thread-local storage - the check is heavily parametrized.
+conftest_s=
+tls_first_major=
+tls_first_minor=
+tls_as_opt=
+case "$target" in
+changequote(,)dnl
+ alpha*-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ ldq $27,__tls_get_addr($29) !literal!1
+ lda $16,foo($29) !tlsgd!1
+ jsr $26,($27),__tls_get_addr !lituse_tlsgd!1
+ ldq $27,__tls_get_addr($29) !literal!2
+ lda $16,foo($29) !tlsldm!2
+ jsr $26,($27),__tls_get_addr !lituse_tlsldm!2
+ ldq $1,foo($29) !gotdtprel
+ ldah $2,foo($29) !dtprelhi
+ lda $3,foo($2) !dtprello
+ lda $4,foo($29) !dtprel
+ ldq $1,foo($29) !gottprel
+ ldah $2,foo($29) !tprelhi
+ lda $3,foo($2) !tprello
+ lda $4,foo($29) !tprel'
+ tls_first_major=2
+ tls_first_minor=13
+ tls_as_opt=--fatal-warnings
+ ;;
+ i[34567]86-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ movl %gs:0, %eax
+ leal foo@TLSGD(,%ebx,1), %eax
+ leal foo@TLSLDM(%ebx), %eax
+ leal foo@DTPOFF(%eax), %edx
+ movl foo@GOTTPOFF(%ebx), %eax
+ subl foo@GOTTPOFF(%ebx), %eax
+ addl foo@GOTNTPOFF(%ebx), %eax
+ movl foo@INDNTPOFF, %eax
+ movl $foo@TPOFF, %eax
+ subl $foo@TPOFF, %eax
+ leal foo@NTPOFF(%ecx), %eax'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt=--fatal-warnings
+ ;;
+ x86_64-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ movq %fs:0, %rax
+ leaq foo@TLSGD(%rip), %rdi
+ leaq foo@TLSLD(%rip), %rdi
+ leaq foo@DTPOFF(%rax), %rdx
+ movq foo@GOTTPOFF(%rip), %rax
+ movq $foo@TPOFF, %rax'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt=--fatal-warnings
+ ;;
+ ia64-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: data8 25
+ .text
+ addl r16 = @ltoff(@dtpmod(foo#)), gp
+ addl r17 = @ltoff(@dtprel(foo#)), gp
+ addl r18 = @ltoff(@tprel(foo#)), gp
+ addl r19 = @dtprel(foo#), gp
+ adds r21 = @dtprel(foo#), r13
+ movl r23 = @dtprel(foo#)
+ addl r20 = @tprel(foo#), gp
+ adds r22 = @tprel(foo#), r13
+ movl r24 = @tprel(foo#)'
+ tls_first_major=2
+ tls_first_minor=13
+ tls_as_opt=--fatal-warnings
+ ;;
+ powerpc-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+ .align 2
+ld0: .space 4
+ld1: .space 4
+x1: .space 4
+x2: .space 4
+x3: .space 4
+ .text
+ addi 3,31,ld0@got@tlsgd
+ bl __tls_get_addr
+ addi 3,31,x1@got@tlsld
+ bl __tls_get_addr
+ addi 9,3,x1@dtprel
+ addis 9,3,x2@dtprel@ha
+ addi 9,9,x2@dtprel@l
+ lwz 9,x3@got@tprel(31)
+ add 9,9,x@tls
+ addi 9,2,x1@tprel
+ addis 9,2,x2@tprel@ha
+ addi 9,9,x2@tprel@l'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-a32 --fatal-warnings"
+ ;;
+ powerpc64-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+ .align 3
+ld0: .space 8
+ld1: .space 8
+x1: .space 8
+x2: .space 8
+x3: .space 8
+ .text
+ addi 3,2,ld0@got@tlsgd
+ bl .__tls_get_addr
+ nop
+ addi 3,2,ld1@toc
+ bl .__tls_get_addr
+ nop
+ addi 3,2,x1@got@tlsld
+ bl .__tls_get_addr
+ nop
+ addi 9,3,x1@dtprel
+ bl .__tls_get_addr
+ nop
+ addis 9,3,x2@dtprel@ha
+ addi 9,9,x2@dtprel@l
+ bl .__tls_get_addr
+ nop
+ ld 9,x3@got@dtprel(2)
+ add 9,9,3
+ bl .__tls_get_addr
+ nop'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-a64 --fatal-warnings"
+ ;;
+ s390-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ .long foo@TLSGD
+ .long foo@TLSLDM
+ .long foo@DTPOFF
+ .long foo@NTPOFF
+ .long foo@GOTNTPOFF
+ .long foo@INDNTPOFF
+ l %r1,foo@GOTNTPOFF(%r12)
+ l %r1,0(%r1):tls_load:foo
+ bas %r14,0(%r1,%r13):tls_gdcall:foo
+ bas %r14,0(%r1,%r13):tls_ldcall:foo'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-m31 --fatal-warnings"
+ ;;
+ s390x-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ .quad foo@TLSGD
+ .quad foo@TLSLDM
+ .quad foo@DTPOFF
+ .quad foo@NTPOFF
+ .quad foo@GOTNTPOFF
+ lg %r1,foo@GOTNTPOFF(%r12)
+ larl %r1,foo@INDNTPOFF
+ brasl %r14,__tls_get_offset@PLT:tls_gdcall:foo
+ brasl %r14,__tls_get_offset@PLT:tls_ldcall:foo'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-m64 -Aesame --fatal-warnings"
+ ;;
+ sh-*-* | sh[34]-*-*)
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ .long foo@TLSGD
+ .long foo@TLSLDM
+ .long foo@DTPOFF
+ .long foo@GOTTPOFF
+ .long foo@TPOFF'
+ tls_first_major=2
+ tls_first_minor=13
+ tls_as_opt=--fatal-warnings
+ ;;
+ sparc*-*-*)
+ case "$target" in
+ sparc*-sun-solaris2.*)
+ on_solaris=yes
+ ;;
+ *)
+ on_solaris=no
+ ;;
+ esac
+ if test x$on_solaris = xyes && test x$gas_flag = xno; then
+ conftest_s='
+ .section ".tdata",#alloc,#write,#tls
+foo: .long 25
+ .text
+ sethi %tgd_hi22(foo), %o0
+ add %o0, %tgd_lo10(foo), %o1
+ add %l7, %o1, %o0, %tgd_add(foo)
+ call __tls_get_addr, %tgd_call(foo)
+ sethi %tldm_hi22(foo), %l1
+ add %l1, %tldm_lo10(foo), %l2
+ add %l7, %l2, %o0, %tldm_add(foo)
+ call __tls_get_addr, %tldm_call(foo)
+ sethi %tldo_hix22(foo), %l3
+ xor %l3, %tldo_lox10(foo), %l4
+ add %o0, %l4, %l5, %tldo_add(foo)
+ sethi %tie_hi22(foo), %o3
+ add %o3, %tie_lo10(foo), %o3
+ ld [%l7 + %o3], %o2, %tie_ld(foo)
+ add %g7, %o2, %o4, %tie_add(foo)
+ sethi %tle_hix22(foo), %l1
+ xor %l1, %tle_lox10(foo), %o5
+ ld [%g7 + %o5], %o1'
+ tls_first_major=0
+ tls_first_minor=0
+ else
+ conftest_s='
+ .section ".tdata","awT",@progbits
+foo: .long 25
+ .text
+ sethi %tgd_hi22(foo), %o0
+ add %o0, %tgd_lo10(foo), %o1
+ add %l7, %o1, %o0, %tgd_add(foo)
+ call __tls_get_addr, %tgd_call(foo)
+ sethi %tldm_hi22(foo), %l1
+ add %l1, %tldm_lo10(foo), %l2
+ add %l7, %l2, %o0, %tldm_add(foo)
+ call __tls_get_addr, %tldm_call(foo)
+ sethi %tldo_hix22(foo), %l3
+ xor %l3, %tldo_lox10(foo), %l4
+ add %o0, %l4, %l5, %tldo_add(foo)
+ sethi %tie_hi22(foo), %o3
+ add %o3, %tie_lo10(foo), %o3
+ ld [%l7 + %o3], %o2, %tie_ld(foo)
+ add %g7, %o2, %o4, %tie_add(foo)
+ sethi %tle_hix22(foo), %l1
+ xor %l1, %tle_lox10(foo), %o5
+ ld [%g7 + %o5], %o1'
+ tls_first_major=2
+ tls_first_minor=14
+ tls_as_opt="-32 --fatal-warnings"
+ fi
+ ;;
+changequote([,])dnl
+esac
+if test -z "$tls_first_major"; then
+ : # If we don't have a check, assume no support.
+else
+ gcc_GAS_CHECK_FEATURE(thread-local storage support, gcc_cv_as_tls,
+ [$tls_first_major,$tls_first_minor,0], [$tls_as_opt], [$conftest_s],,
+ [AC_DEFINE(HAVE_AS_TLS, 1,
+ [Define if your assembler supports thread-local storage.])])
+fi
+
+# Target-specific assembler checks.
+
+case "$target" in
+ # All TARGET_ABI_OSF targets.
+ alpha*-*-osf* | alpha*-*-linux* | alpha*-*-*bsd*)
+ gcc_GAS_CHECK_FEATURE([explicit relocation support],
+ gcc_cv_as_alpha_explicit_relocs, [2,12,0],,
+[ .set nomacro
+ .text
+ extbl $3, $2, $3 !lituse_bytoff!1
+ ldq $2, a($29) !literal!1
+ ldq $4, b($29) !literal!2
+ ldq_u $3, 0($2) !lituse_base!1
+ ldq $27, f($29) !literal!5
+ jsr $26, ($27), f !lituse_jsr!5
+ ldah $29, 0($26) !gpdisp!3
+ lda $0, c($29) !gprel
+ ldah $1, d($29) !gprelhigh
+ lda $1, d($1) !gprellow
+ lda $29, 0($29) !gpdisp!3],,
+ [AC_DEFINE(HAVE_AS_EXPLICIT_RELOCS, 1,
+ [Define if your assembler supports explicit relocations.])])
+ ;;
+
+ cris-*-*)
+ gcc_GAS_CHECK_FEATURE([-no-mul-bug-abort option],
+ gcc_cv_as_cris_no_mul_bug,[2,15,91],
+ [-no-mul-bug-abort], [.text],,
+ [AC_DEFINE(HAVE_AS_NO_MUL_BUG_ABORT_OPTION, 1,
+ [Define if your assembler supports the -no-mul-bug-abort option.])])
+ ;;
+
+ sparc*-*-*)
+ gcc_GAS_CHECK_FEATURE([.register], gcc_cv_as_sparc_register_op,,,
+ [.register %g2, #scratch],,
+ [AC_DEFINE(HAVE_AS_REGISTER_PSEUDO_OP, 1,
+ [Define if your assembler supports .register.])])
+
+ gcc_GAS_CHECK_FEATURE([-relax option], gcc_cv_as_sparc_relax,,
+ [-relax], [.text],,
+ [AC_DEFINE(HAVE_AS_RELAX_OPTION, 1,
+ [Define if your assembler supports -relax option.])])
+
+ gcc_GAS_CHECK_FEATURE([unaligned pcrel relocs],
+ gcc_cv_as_sparc_ua_pcrel,,
+ [-K PIC],
+[.text
+foo:
+ nop
+.data
+.align 4
+.byte 0
+.uaword %r_disp32(foo)],
+ [if test x$gcc_cv_ld != x \
+ && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1; then
+ gcc_cv_as_sparc_ua_pcrel=yes
+ fi
+ rm -f conftest],
+ [AC_DEFINE(HAVE_AS_SPARC_UA_PCREL, 1,
+ [Define if your assembler and linker support unaligned PC relative relocs.])
+
+ gcc_GAS_CHECK_FEATURE([unaligned pcrel relocs against hidden symbols],
+ gcc_cv_as_sparc_ua_pcrel_hidden,,
+ [-K PIC],
+[.data
+.align 4
+.byte 0x31
+.uaword %r_disp32(foo)
+.byte 0x32, 0x33, 0x34
+.global foo
+.hidden foo
+foo:
+.skip 4],
+ [if test x$gcc_cv_ld != x && test x$gcc_cv_objdump != x \
+ && $gcc_cv_ld -o conftest conftest.o -G > /dev/null 2>&1 \
+ && $gcc_cv_objdump -s -j .data conftest 2> /dev/null \
+ | grep ' 31000000 07323334' > /dev/null 2>&1; then
+ if $gcc_cv_objdump -R conftest 2> /dev/null \
+ | grep 'DISP32' > /dev/null 2>&1; then
+ :
+ else
+ gcc_cv_as_sparc_ua_pcrel_hidden=yes
+ fi
+ fi
+ rm -f conftest],
+ [AC_DEFINE(HAVE_AS_SPARC_UA_PCREL_HIDDEN, 1,
+ [Define if your assembler and linker support unaligned PC relative relocs against hidden symbols.])])
+ ]) # unaligned pcrel relocs
+
+ gcc_GAS_CHECK_FEATURE([offsetable %lo()],
+ gcc_cv_as_sparc_offsetable_lo10,,
+ [-xarch=v9],
+[.text
+ or %g1, %lo(ab) + 12, %g1
+ or %g1, %lo(ab + 12), %g1],
+ [if test x$gcc_cv_objdump != x \
+ && $gcc_cv_objdump -s -j .text conftest.o 2> /dev/null \
+ | grep ' 82106000 82106000' > /dev/null 2>&1; then
+ gcc_cv_as_offsetable_lo10=yes
+ fi],
+ [AC_DEFINE(HAVE_AS_OFFSETABLE_LO10, 1,
+ [Define if your assembler supports offsetable %lo().])])
+ ;;
+
+changequote(,)dnl
+ i[34567]86-*-* | x86_64-*-*)
+changequote([,])dnl
+ gcc_GAS_CHECK_FEATURE([filds and fists mnemonics],
+ gcc_cv_as_ix86_filds_fists,
+ [2,9,0],, [filds mem; fists mem],,
+ [AC_DEFINE(HAVE_GAS_FILDS_FISTS, 1,
+ [Define if your assembler uses the new HImode fild and fist notation.])])
+
+ gcc_GAS_CHECK_FEATURE([cmov syntax],
+ gcc_cv_as_ix86_cmov_sun_syntax,,,
+ [cmovl.l %edx, %eax],,
+ [AC_DEFINE(HAVE_AS_IX86_CMOV_SUN_SYNTAX, 1,
+ [Define if your assembler supports the Sun syntax for cmov.])])
+
+ # This one is used unconditionally by i386.[ch]; it is to be defined
+ # to 1 if the feature is present, 0 otherwise.
+ gcc_GAS_CHECK_FEATURE([GOTOFF in data],
+ gcc_cv_as_ix86_gotoff_in_data, [2,11,0],,
+[ .text
+.L0:
+ nop
+ .data
+ .long .L0@GOTOFF])
+ AC_DEFINE_UNQUOTED(HAVE_AS_GOTOFF_IN_DATA,
+ [`if test $gcc_cv_as_ix86_gotoff_in_data = yes; then echo 1; else echo 0; fi`],
+ [Define true if the assembler supports '.long foo@GOTOFF'.])
+ ;;
+
+ ia64*-*-*)
+ gcc_GAS_CHECK_FEATURE([ltoffx and ldxmov relocs],
+ gcc_cv_as_ia64_ltoffx_ldxmov_relocs, [2,14,0],,
+[ .text
+ addl r15 = @ltoffx(x#), gp
+ ;;
+ ld8.mov r16 = [[r15]], x#],,
+ [AC_DEFINE(HAVE_AS_LTOFFX_LDXMOV_RELOCS, 1,
+ [Define if your assembler supports ltoffx and ldxmov relocations.])])
+
+ ;;
+
+ powerpc*-*-*)
+ case $target in
+ *-*-aix*) conftest_s=' .csect .text[[PR]]
+ mfcr 3,128';;
+ *-*-darwin*) conftest_s=' .text
+ mfcr r3,128';;
+ *) conftest_s=' .text
+ mfcr 3,128';;
+ esac
+
+ gcc_GAS_CHECK_FEATURE([mfcr field support],
+ gcc_cv_as_powerpc_mfcrf, [2,14,0],,
+ [$conftest_s],,
+ [AC_DEFINE(HAVE_AS_MFCRF, 1,
+ [Define if your assembler supports mfcr field.])])
+ ;;
+
+ mips*-*-*)
+ gcc_GAS_CHECK_FEATURE([explicit relocation support],
+ gcc_cv_as_mips_explicit_relocs, [2,14,0],,
+[ lw $4,%gp_rel(foo)($4)],,
+ [if test x$target_cpu_default = x
+ then target_cpu_default=MASK_EXPLICIT_RELOCS
+ else target_cpu_default="($target_cpu_default)|MASK_EXPLICIT_RELOCS"
+ fi])
+
+ ;;
+esac
+# ??? Not all targets support dwarf2 debug_line, even within a version
+# of gas. Moreover, we need to emit a valid instruction to trigger any
+# info to the output file. So, as supported targets are added to gas 2.11,
+# add some instruction here to (also) show we expect this might work.
+# ??? Once 2.11 is released, probably need to add first known working
+# version to the per-target configury.
+case "$target" in
+ i?86*-*-* | mips*-*-* | alpha*-*-* | powerpc*-*-* | sparc*-*-* | m68*-*-* \
+ | x86_64*-*-* | hppa*-*-* | arm*-*-* | strongarm*-*-* | xscale*-*-* \
+ | xstormy16*-*-* | cris-*-* | xtensa-*-*)
+ insn="nop"
+ ;;
+ ia64*-*-* | s390*-*-*)
+ insn="nop 0"
+ ;;
+ mmix-*-*)
+ insn="swym 0"
+ ;;
+esac
+if test x"$insn" != x; then
+ conftest_s="\
+ .file 1 \"conftest.s\"
+ .loc 1 3 0
+ $insn"
+ gcc_GAS_CHECK_FEATURE([dwarf2 debug_line support],
+ gcc_cv_as_dwarf2_debug_line,
+ [elf,2,11,0],, [$conftest_s],
+ [# ??? This fails with non-gnu grep. Maybe use objdump?
+ if grep debug_line conftest.o > /dev/null 2>&1; then
+ gcc_cv_as_dwarf2_debug_line=yes
+ fi])
+
+# The .debug_line file table must be in the exact order that
+# we specified the files, since these indices are also used
+# by DW_AT_decl_file. Approximate this test by testing if
+# the assembler bitches if the same index is assigned twice.
+ gcc_GAS_CHECK_FEATURE([buggy dwarf2 .file directive],
+ gcc_cv_as_dwarf2_file_buggy,,,
+[ .file 1 "foo.s"
+ .file 1 "bar.s"])
+
+ if test $gcc_cv_as_dwarf2_debug_line = yes \
+ && test $gcc_cv_as_dwarf2_file_buggy = no; then
+ AC_DEFINE(HAVE_AS_DWARF2_DEBUG_LINE, 1,
+ [Define if your assembler supports dwarf2 .file/.loc directives,
+ and preserves file table indices exactly as given.])
+ fi
+
+ gcc_GAS_CHECK_FEATURE([--gdwarf2 option],
+ gcc_cv_as_gdwarf2_flag,
+ [elf,2,11,0], [--gdwarf2], [$insn],,
+ [AC_DEFINE(HAVE_AS_GDWARF2_DEBUG_FLAG, 1,
+[Define if your assembler supports the --gdwarf2 option.])])
+
+ gcc_GAS_CHECK_FEATURE([--gstabs option],
+ gcc_cv_as_gstabs_flag,
+ [elf,2,11,0], [--gstabs], [$insn],
+ [# The native Solaris 9/Intel assembler doesn't understand --gstabs
+ # and warns about it, but still exits successfully. So check for
+ # this.
+ if AC_TRY_COMMAND([$gcc_cv_as --gstabs -o conftest.o conftest.s 2>&1 | grep -i warning > /dev/null])
+ then :
+ else gcc_cv_as_gstabs_flag=yes
+ fi],
+ [AC_DEFINE(HAVE_AS_GSTABS_DEBUG_FLAG, 1,
+[Define if your assembler supports the --gstabs option.])])
+fi
+
+AC_MSG_CHECKING(linker read-only and read-write section mixing)
+gcc_cv_ld_ro_rw_mix=unknown
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 10 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_ro_rw_mix=read-write
+ fi
+elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then
+ echo '.section myfoosect, "a"' > conftest1.s
+ echo '.section myfoosect, "aw"' > conftest2.s
+ echo '.byte 1' >> conftest2.s
+ echo '.section myfoosect, "a"' > conftest3.s
+ echo '.byte 0' >> conftest3.s
+ if $gcc_cv_as -o conftest1.o conftest1.s > /dev/null 2>&1 \
+ && $gcc_cv_as -o conftest2.o conftest2.s > /dev/null 2>&1 \
+ && $gcc_cv_as -o conftest3.o conftest3.s > /dev/null 2>&1 \
+ && $gcc_cv_ld -shared -o conftest1.so conftest1.o \
+ conftest2.o conftest3.o > /dev/null 2>&1; then
+ gcc_cv_ld_ro_rw_mix=`$gcc_cv_objdump -h conftest1.so \
+ | sed -e '/myfoosect/!d' -e N`
+ if echo "$gcc_cv_ld_ro_rw_mix" | grep CONTENTS > /dev/null; then
+ if echo "$gcc_cv_ld_ro_rw_mix" | grep READONLY > /dev/null; then
+ gcc_cv_ld_ro_rw_mix=read-only
+ else
+ gcc_cv_ld_ro_rw_mix=read-write
+ fi
+ fi
+ fi
+changequote(,)dnl
+ rm -f conftest.* conftest[123].*
+changequote([,])dnl
+fi
+if test x$gcc_cv_ld_ro_rw_mix = xread-write; then
+ AC_DEFINE(HAVE_LD_RO_RW_SECTION_MIXING, 1,
+ [Define if your linker links a mix of read-only
+ and read-write sections into a read-write section.])
+fi
+AC_MSG_RESULT($gcc_cv_ld_ro_rw_mix)
+
+AC_MSG_CHECKING(linker PT_GNU_EH_FRAME support)
+gcc_cv_ld_eh_frame_hdr=no
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 12 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_eh_frame_hdr=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports --eh-frame-hdr option
+ if $gcc_cv_ld --help 2>/dev/null | grep eh-frame-hdr > /dev/null; then
+ gcc_cv_ld_eh_frame_hdr=yes
+ fi
+fi
+if test x"$gcc_cv_ld_eh_frame_hdr" = xyes; then
+ AC_DEFINE(HAVE_LD_EH_FRAME_HDR, 1,
+[Define if your linker supports --eh-frame-hdr option.])
+fi
+AC_MSG_RESULT($gcc_cv_ld_eh_frame_hdr)
+
+AC_MSG_CHECKING(linker position independent executable support)
+gcc_cv_ld_pie=no
+if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 15 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_pie=yes
+ fi
+elif test x$gcc_cv_ld != x; then
+ # Check if linker supports -pie option
+ if $gcc_cv_ld --help 2>/dev/null | grep -- -pie > /dev/null; then
+ gcc_cv_ld_pie=yes
+ fi
+fi
+if test x"$gcc_cv_ld_pie" = xyes; then
+ AC_DEFINE(HAVE_LD_PIE, 1,
+[Define if your linker supports -pie option.])
+fi
+AC_MSG_RESULT($gcc_cv_ld_pie)
+
+case "$target" in
+ *-*-linux*)
+ AC_CACHE_CHECK(linker --as-needed support,
+ gcc_cv_ld_as_needed,
+ [gcc_cv_ld_as_needed=no
+ if test $in_tree_ld = yes ; then
+ if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 16 -o "$gcc_cv_gld_major_version" -gt 2 \
+ && test $in_tree_ld_is_elf = yes; then
+ gcc_cv_ld_as_needed=yes
+ fi
+ elif test x$gcc_cv_ld != x; then
+ # Check if linker supports --as-needed and --no-as-needed options
+ if $gcc_cv_ld --help 2>/dev/null | grep as-needed > /dev/null; then
+ gcc_cv_ld_as_needed=yes
+ fi
+ fi
+ ])
+ if test x"$gcc_cv_ld_as_needed" = xyes; then
+ AC_DEFINE(HAVE_LD_AS_NEEDED, 1,
+ [Define if your linker supports --as-needed and --no-as-needed options.])
+ fi
+ ;;
+esac
+
+if test x$with_sysroot = x && test x$host = x$target \
+ && test "$prefix" != "/usr" && test "x$prefix" != "x$local_prefix" ; then
+ AC_DEFINE_UNQUOTED(PREFIX_INCLUDE_DIR, "$prefix/include",
+[Define to PREFIX/include if cpp should also search that directory.])
+fi
+
+# Figure out what language subdirectories are present.
+# Look if the user specified --enable-languages="..."; if not, use
+# the environment variable $LANGUAGES if defined. $LANGUAGES might
+# go away some day.
+# NB: embedded tabs in this IF block -- do not untabify
+if test x"${enable_languages+set}" != xset; then
+ if test x"${LANGUAGES+set}" = xset; then
+ enable_languages="${LANGUAGES}"
+ AC_MSG_WARN([setting LANGUAGES is deprecated, use --enable-languages instead])
+
+ else
+ enable_languages=all
+ fi
+else
+ if test x"${enable_languages}" = x \
+ || test x"${enable_languages}" = xyes;
+ then
+ AC_MSG_ERROR([--enable-languages needs at least one language argument])
+ fi
+fi
+enable_languages=`echo "${enable_languages}" | sed -e 's/[[ ,]][[ ,]]*/,/g' -e 's/,$//'`
+
+# First scan to see if an enabled language requires some other language.
+# We assume that a given config-lang.in will list all the language
+# front ends it requires, even if some are required indirectly.
+for lang in ${srcdir}/*/config-lang.in
+do
+ case $lang in
+ # The odd quoting in the next line works around
+ # an apparent bug in bash 1.12 on linux.
+changequote(,)dnl
+ ${srcdir}/[*]/config-lang.in)
+ ;;
+ *)
+ lang_alias=`sed -n -e 's,^language=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^language=\([^ ]*\).*$,\1,p' $lang`
+ this_lang_requires=`sed -n -e 's,^lang_requires=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^lang_requires=\([^ ]*\).*$,\1,p' $lang`
+ for other in $this_lang_requires
+ do
+ case ,${enable_languages}, in
+ *,$other,*)
+ ;;
+ *,all,*)
+ ;;
+ *,$lang_alias,*)
+ enable_languages="$enable_languages,$other"
+ ;;
+ esac
+ done
+ ;;
+changequote([,])dnl
+ esac
+done
+
+expected_languages=`echo ,${enable_languages}, | sed -e 's:,: :g' -e 's: *: :g' -e 's: *: :g' -e 's:^ ::' -e 's: $::'`
+found_languages=
+subdirs=
+for lang in ${srcdir}/*/config-lang.in
+do
+ case $lang in
+ # The odd quoting in the next line works around
+ # an apparent bug in bash 1.12 on linux.
+changequote(,)dnl
+ ${srcdir}/[*]/config-lang.in) ;;
+ *)
+ lang_alias=`sed -n -e 's,^language=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^language=\([^ ]*\).*$,\1,p' $lang`
+ this_lang_libs=`sed -n -e 's,^target_libs=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^target_libs=\([^ ]*\).*$,\1,p' $lang`
+ build_by_default=`sed -n -e 's,^build_by_default=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^build_by_default=\([^ ]*\).*$,\1,p' $lang`
+ if test "x$lang_alias" = x
+ then
+ echo "$lang doesn't set \$language." 1>&2
+ exit 1
+ fi
+ case ${build_by_default},${enable_languages}, in
+ *,$lang_alias,*) add_this_lang=yes ;;
+ no,*) add_this_lang=no ;;
+ *,all,*) add_this_lang=yes ;;
+ *) add_this_lang=no ;;
+ esac
+ found_languages="${found_languages} ${lang_alias}"
+ if test x"${add_this_lang}" = xyes; then
+ case $lang in
+ ${srcdir}/ada/config-lang.in)
+ if test x$have_gnat = xyes ; then
+ subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`"
+ fi
+ ;;
+ *)
+ subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`"
+ ;;
+ esac
+ fi
+ ;;
+changequote([,])dnl
+ esac
+done
+
+missing_languages=
+for expected_language in ${expected_languages} ..
+do
+ if test "${expected_language}" != ..; then
+ missing_language="${expected_language}"
+ if test "${expected_language}" = "c" \
+ || test "${expected_language}" = "all"; then
+ missing_language=
+ fi
+ for found_language in ${found_languages} ..
+ do
+ if test "${found_language}" != ..; then
+ if test "${expected_language}" = "${found_language}"; then
+ missing_language=
+ fi
+ fi
+ done
+ if test "x${missing_language}" != x; then
+ missing_languages="${missing_languages} ${missing_language}"
+ fi
+ fi
+done
+
+if test "x$missing_languages" != x; then
+ AC_MSG_ERROR([
+The following requested languages were not found:${missing_languages}
+The following languages were available: c${found_languages}])
+fi
+
+# Make gthr-default.h if we have a thread file.
+gthread_flags=
+if test $thread_file != single; then
+ rm -f gthr-default.h
+ echo "#include \"gthr-${thread_file}.h\"" > gthr-default.h
+ gthread_flags=-DHAVE_GTHR_DEFAULT
+fi
+AC_SUBST(gthread_flags)
+
+# Find out what GC implementation we want, or may, use.
+AC_ARG_WITH(gc,
+[ --with-gc={simple,page,zone} choose the garbage collection mechanism to use
+ with the compiler],
+[case "$withval" in
+ simple | page | zone)
+ GGC=ggc-$withval
+ ;;
+ *)
+ AC_MSG_ERROR([$withval is an invalid option to --with-gc])
+ ;;
+esac],
+[GGC=ggc-page])
+AC_SUBST(GGC)
+echo "Using $GGC for garbage collection."
+
+# Use the system's zlib library.
+zlibdir=-L../zlib
+zlibinc="-I\$(srcdir)/../zlib"
+AC_ARG_WITH(system-zlib,
+[ --with-system-zlib use installed libz],
+zlibdir=
+zlibinc=
+)
+AC_SUBST(zlibdir)
+AC_SUBST(zlibinc)
+
+dnl Very limited version of automake's enable-maintainer-mode
+
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode
+ enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ maintainer_mode=$enableval,
+ maintainer_mode=no)
+
+AC_MSG_RESULT($maintainer_mode)
+
+if test "$maintainer_mode" = "yes"; then
+ MAINT=''
+else
+ MAINT='#'
+fi
+AC_SUBST(MAINT)dnl
+
+# Make empty files to contain the specs and options for each language.
+# Then add #include lines to for a compiler that has specs and/or options.
+
+lang_opt_files=
+lang_specs_files=
+lang_tree_files=
+for subdir in . $subdirs
+do
+ if test -f $srcdir/$subdir/lang.opt; then
+ lang_opt_files="$lang_opt_files $srcdir/$subdir/lang.opt"
+ fi
+ if test -f $srcdir/$subdir/lang-specs.h; then
+ lang_specs_files="$lang_specs_files $srcdir/$subdir/lang-specs.h"
+ fi
+ if test -f $srcdir/$subdir/$subdir-tree.def; then
+ lang_tree_files="$lang_tree_files $srcdir/$subdir/$subdir-tree.def"
+ fi
+done
+
+# These (without "all_") are set in each config-lang.in.
+# `language' must be a single word so is spelled singularly.
+all_languages=
+all_boot_languages=
+all_compilers=
+all_stagestuff=
+all_outputs='Makefile fixinc/Makefile gccbug mklibgcc mkheaders'
+# List of language makefile fragments.
+all_lang_makefrags=
+# List of language subdirectory makefiles. Deprecated.
+all_lang_makefiles=
+# Files for gengtype
+all_gtfiles="$target_gtfiles"
+# Files for gengtype with language
+all_gtfiles_files_langs=
+all_gtfiles_files_files=
+
+# Add the language fragments.
+# Languages are added via two mechanisms. Some information must be
+# recorded in makefile variables, these are defined in config-lang.in.
+# We accumulate them and plug them into the main Makefile.
+# The other mechanism is a set of hooks for each of the main targets
+# like `clean', `install', etc.
+
+language_hooks="Make-hooks"
+
+for s in $subdirs
+do
+ language=
+ boot_language=
+ compilers=
+ stagestuff=
+ outputs=
+ gtfiles=
+ . ${srcdir}/$s/config-lang.in
+ if test "x$language" = x
+ then
+ echo "${srcdir}/$s/config-lang.in doesn't set \$language." 1>&2
+ exit 1
+ fi
+ all_lang_makefrags="$all_lang_makefrags \$(srcdir)/$s/Make-lang.in"
+ if test -f ${srcdir}/$s/Makefile.in
+ then all_lang_makefiles="$s/Makefile"
+ fi
+ all_languages="$all_languages $language"
+ if test "x$boot_language" = xyes
+ then
+ all_boot_languages="$all_boot_languages $language"
+ fi
+ all_compilers="$all_compilers $compilers"
+ all_stagestuff="$all_stagestuff $stagestuff"
+ all_outputs="$all_outputs $outputs"
+ all_gtfiles="$all_gtfiles $gtfiles"
+ for f in $gtfiles
+ do
+ all_gtfiles_files_langs="$all_gtfiles_files_langs ${s} "
+ all_gtfiles_files_files="$all_gtfiles_files_files ${f} "
+ done
+done
+
+# Pick up gtfiles for c
+gtfiles=
+s="c"
+. ${srcdir}/c-config-lang.in
+all_gtfiles="$all_gtfiles $gtfiles"
+for f in $gtfiles
+do
+ all_gtfiles_files_langs="$all_gtfiles_files_langs ${s} "
+ all_gtfiles_files_files="$all_gtfiles_files_files ${f} "
+done
+
+check_languages=
+for language in $all_languages
+do
+ check_languages="$check_languages check-$language"
+done
+
+# We link each language in with a set of hooks, reached indirectly via
+# lang.${target}.
+
+rm -f Make-hooks
+touch Make-hooks
+target_list="all.build all.cross start.encap rest.encap tags \
+ install-normal install-common install-man \
+ uninstall info man srcextra srcman srcinfo \
+ mostlyclean clean distclean maintainer-clean \
+ stage1 stage2 stage3 stage4 stageprofile stagefeedback"
+for t in $target_list
+do
+ x=
+ for lang in $all_languages
+ do
+ x="$x $lang.$t"
+ done
+ echo "lang.$t: $x" >> Make-hooks
+done
+
+# Create .gdbinit.
+
+echo "dir ." > .gdbinit
+echo "dir ${srcdir}" >> .gdbinit
+if test x$gdb_needs_out_file_path = xyes
+then
+ echo "dir ${srcdir}/config/"`dirname ${out_file}` >> .gdbinit
+fi
+if test "x$subdirs" != x; then
+ for s in $subdirs
+ do
+ echo "dir ${srcdir}/$s" >> .gdbinit
+ done
+fi
+echo "source ${srcdir}/gdbinit.in" >> .gdbinit
+
+# If $(exec_prefix) exists and is not the same as $(prefix), then compute an
+# absolute path for gcc_tooldir based on inserting the number of up-directory
+# movements required to get from $(exec_prefix) to $(prefix) into the basic
+# $(libsubdir)/@(unlibsubdir) based path.
+# Don't set gcc_tooldir to tooldir since that's only passed in by the toplevel
+# make and thus we'd get different behavior depending on where we built the
+# sources.
+if test x$exec_prefix = xNONE -o x$exec_prefix = x$prefix; then
+ gcc_tooldir='$(libsubdir)/$(unlibsubdir)/../$(target_noncanonical)'
+else
+changequote(<<, >>)dnl
+# An explanation of the sed strings:
+# -e 's|^\$(prefix)||' matches and eliminates 'prefix' from 'exec_prefix'
+# -e 's|/$||' match a trailing forward slash and eliminates it
+# -e 's|^[^/]|/|' forces the string to start with a forward slash (*)
+# -e 's|/[^/]*|../|g' replaces each occurrence of /<directory> with ../
+#
+# (*) Note this pattern overwrites the first character of the string
+# with a forward slash if one is not already present. This is not a
+# problem because the exact names of the sub-directories concerned is
+# unimportant, just the number of them matters.
+#
+# The practical upshot of these patterns is like this:
+#
+# prefix exec_prefix result
+# ------ ----------- ------
+# /foo /foo/bar ../
+# /foo/ /foo/bar ../
+# /foo /foo/bar/ ../
+# /foo/ /foo/bar/ ../
+# /foo /foo/bar/ugg ../../
+#
+ dollar='$$'
+ gcc_tooldir="\$(libsubdir)/\$(unlibsubdir)/\`echo \$(exec_prefix) | sed -e 's|^\$(prefix)||' -e 's|/\$(dollar)||' -e 's|^[^/]|/|' -e 's|/[^/]*|../|g'\`\$(target_noncanonical)"
+changequote([, ])dnl
+fi
+AC_SUBST(gcc_tooldir)
+AC_SUBST(dollar)
+
+# Find a directory in which to install a shared libgcc.
+
+AC_ARG_ENABLE(version-specific-runtime-libs,
+[ --enable-version-specific-runtime-libs
+ specify that runtime libraries should be
+ installed in a compiler-specific directory])
+
+AC_ARG_WITH(slibdir,
+[ --with-slibdir=DIR shared libraries in DIR [LIBDIR]],
+slibdir="$with_slibdir",
+if test "${enable_version_specific_runtime_libs+set}" = set; then
+ slibdir='$(libsubdir)'
+elif test "$host" != "$target"; then
+ slibdir='$(build_tooldir)/lib'
+else
+ slibdir='$(libdir)'
+fi)
+AC_SUBST(slibdir)
+
+objdir=`${PWDCMD-pwd}`
+AC_SUBST(objdir)
+
+# Substitute configuration variables
+AC_SUBST(subdirs)
+AC_SUBST(srcdir)
+AC_SUBST(all_boot_languages)
+AC_SUBST(all_compilers)
+AC_SUBST(all_gtfiles)
+AC_SUBST(all_gtfiles_files_langs)
+AC_SUBST(all_gtfiles_files_files)
+AC_SUBST(all_lang_makefrags)
+AC_SUBST(all_lang_makefiles)
+AC_SUBST(all_languages)
+AC_SUBST(all_stagestuff)
+AC_SUBST(build_exeext)
+AC_SUBST(build_install_headers_dir)
+AC_SUBST(build_xm_file_list)
+AC_SUBST(build_xm_include_list)
+AC_SUBST(build_xm_defines)
+AC_SUBST(check_languages)
+AC_SUBST(cc_set_by_configure)
+AC_SUBST(quoted_cc_set_by_configure)
+AC_SUBST(cpp_install_dir)
+AC_SUBST(xmake_file)
+AC_SUBST(tmake_file)
+AC_SUBST(extra_gcc_objs)
+AC_SUBST(extra_headers_list)
+AC_SUBST(extra_objs)
+AC_SUBST(extra_parts)
+AC_SUBST(extra_passes)
+AC_SUBST(extra_programs)
+AC_SUBST(float_h_file)
+AC_SUBST(gcc_config_arguments)
+AC_SUBST(gcc_gxx_include_dir)
+AC_SUBST(libstdcxx_incdir)
+AC_SUBST(gcc_version)
+AC_SUBST(gcc_version_full)
+AC_SUBST(gcc_version_trigger)
+AC_SUBST(host_exeext)
+AC_SUBST(host_xm_file_list)
+AC_SUBST(host_xm_include_list)
+AC_SUBST(host_xm_defines)
+AC_SUBST(out_host_hook_obj)
+AC_SUBST(install)
+AC_SUBST(lang_opt_files)
+AC_SUBST(lang_specs_files)
+AC_SUBST(lang_tree_files)
+AC_SUBST(local_prefix)
+AC_SUBST(md_file)
+AC_SUBST(objc_boehm_gc)
+AC_SUBST(out_file)
+AC_SUBST(out_object_file)
+AC_SUBST(stage_prefix_set_by_configure)
+AC_SUBST(quoted_stage_prefix_set_by_configure)
+AC_SUBST(symbolic_link)
+AC_SUBST(thread_file)
+AC_SUBST(tm_file_list)
+AC_SUBST(tm_include_list)
+AC_SUBST(tm_defines)
+AC_SUBST(tm_p_file_list)
+AC_SUBST(tm_p_include_list)
+AC_SUBST(xm_file_list)
+AC_SUBST(xm_include_list)
+AC_SUBST(xm_defines)
+AC_SUBST(target_noncanonical)
+AC_SUBST(c_target_objs)
+AC_SUBST(cxx_target_objs)
+AC_SUBST(target_cpu_default)
+
+AC_SUBST_FILE(language_hooks)
+
+# If it doesn't already exist, create document directory
+echo "checking for the document directory." 1>&2
+if test -d doc ; then
+ true
+else
+ mkdir doc
+fi
+
+# Echo link setup.
+if test x${build} = x${host} ; then
+ if test x${host} = x${target} ; then
+ echo "Links are now set up to build a native compiler for ${target}." 1>&2
+ else
+ echo "Links are now set up to build a cross-compiler" 1>&2
+ echo " from ${host} to ${target}." 1>&2
+ fi
+else
+ if test x${host} = x${target} ; then
+ echo "Links are now set up to build (on ${build}) a native compiler" 1>&2
+ echo " for ${target}." 1>&2
+ else
+ echo "Links are now set up to build (on ${build}) a cross-compiler" 1>&2
+ echo " from ${host} to ${target}." 1>&2
+ fi
+fi
+
+# Configure the subdirectories
+# AC_CONFIG_SUBDIRS($subdirs)
+
+# Create the Makefile
+# and configure language subdirectories
+AC_CONFIG_FILES($all_outputs)
+
+AC_CONFIG_COMMANDS([default],
+[
+case ${CONFIG_HEADERS} in
+ *auto-host.h:config.in*)
+ echo > cstamp-h ;;
+esac
+# Make sure all the subdirs exist.
+for d in $subdirs
+do
+ test -d $d || mkdir $d
+done
+# If the host supports symlinks, point stage[1234] at ../stage[1234] so
+# bootstrapping and the installation procedure can still use
+# CC="stage1/xgcc -Bstage1/". If the host doesn't support symlinks,
+# FLAGS_TO_PASS has been modified to solve the problem there.
+# This is virtually a duplicate of what happens in configure.lang; we do
+# an extra check to make sure this only happens if ln -s can be used.
+if test "$symbolic_link" = "ln -s"; then
+ for d in ${subdirs} fixinc ; do
+ STARTDIR=`${PWDCMD-pwd}`
+ cd $d
+ for t in stage1 stage2 stage3 stage4 stageprofile stagefeedback include
+ do
+ rm -f $t
+ $symbolic_link ../$t $t 2>/dev/null
+ done
+ cd $STARTDIR
+ done
+else true ; fi
+],
+[subdirs='$subdirs'
+symbolic_link='$symbolic_link'
+])
+AC_OUTPUT
diff --git a/contrib/gcc/conflict.c b/contrib/gcc/conflict.c
index a6d755499bbc..a23bad35c193 100644
--- a/contrib/gcc/conflict.c
+++ b/contrib/gcc/conflict.c
@@ -1,5 +1,5 @@
/* Register conflict graph computation routines.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
Contributed by CodeSourcery, LLC
This file is part of GCC.
@@ -27,6 +27,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "obstack.h"
#include "hashtab.h"
#include "rtl.h"
@@ -112,17 +114,16 @@ struct conflict_graph_def
R1 and R2. R1 is assumed to be smaller or equal to R2. */
#define CONFLICT_HASH_FN(R1, R2) ((R2) * ((R2) - 1) / 2 + (R1))
-static hashval_t arc_hash PARAMS ((const void *));
-static int arc_eq PARAMS ((const void *, const void *));
-static int print_conflict PARAMS ((int, int, void *));
-static void mark_reg PARAMS ((rtx, rtx, void *));
+static hashval_t arc_hash (const void *);
+static int arc_eq (const void *, const void *);
+static int print_conflict (int, int, void *);
+static void mark_reg (rtx, rtx, void *);
/* Callback function to compute the hash value of an arc. Uses
current_graph to locate the graph to which the arc belongs. */
static hashval_t
-arc_hash (arcp)
- const void *arcp;
+arc_hash (const void *arcp)
{
const_conflict_graph_arc arc = (const_conflict_graph_arc) arcp;
@@ -133,9 +134,7 @@ arc_hash (arcp)
table. */
static int
-arc_eq (arcp1, arcp2)
- const void *arcp1;
- const void *arcp2;
+arc_eq (const void *arcp1, const void *arcp2)
{
const_conflict_graph_arc arc1 = (const_conflict_graph_arc) arcp1;
const_conflict_graph_arc arc2 = (const_conflict_graph_arc) arcp2;
@@ -147,11 +146,9 @@ arc_eq (arcp1, arcp2)
registers. */
conflict_graph
-conflict_graph_new (num_regs)
- int num_regs;
+conflict_graph_new (int num_regs)
{
- conflict_graph graph
- = (conflict_graph) xmalloc (sizeof (struct conflict_graph_def));
+ conflict_graph graph = xmalloc (sizeof (struct conflict_graph_def));
graph->num_regs = num_regs;
/* Set up the hash table. No delete action is specified; memory
@@ -163,18 +160,15 @@ conflict_graph_new (num_regs)
obstack_init (&graph->arc_obstack);
/* Create and zero the lookup table by register number. */
- graph->neighbor_heads
- = (conflict_graph_arc *) xmalloc (num_regs * sizeof (conflict_graph_arc));
+ graph->neighbor_heads = xcalloc (num_regs, sizeof (conflict_graph_arc));
- memset (graph->neighbor_heads, 0, num_regs * sizeof (conflict_graph_arc));
return graph;
}
/* Deletes a conflict graph. */
void
-conflict_graph_delete (graph)
- conflict_graph graph;
+conflict_graph_delete (conflict_graph graph)
{
obstack_free (&graph->arc_obstack, NULL);
htab_delete (graph->arc_hash_table);
@@ -187,10 +181,7 @@ conflict_graph_delete (graph)
in GRAPH, in which case it does nothing and returns zero. */
int
-conflict_graph_add (graph, reg1, reg2)
- conflict_graph graph;
- int reg1;
- int reg2;
+conflict_graph_add (conflict_graph graph, int reg1, int reg2)
{
int smaller = MIN (reg1, reg2);
int larger = MAX (reg1, reg2);
@@ -212,8 +203,7 @@ conflict_graph_add (graph, reg1, reg2)
/* Allocate an arc. */
arc
- = (conflict_graph_arc)
- obstack_alloc (&graph->arc_obstack,
+ = obstack_alloc (&graph->arc_obstack,
sizeof (struct conflict_graph_arc_def));
/* Record the reg numbers. */
@@ -236,10 +226,7 @@ conflict_graph_add (graph, reg1, reg2)
and REG2. */
int
-conflict_graph_conflict_p (graph, reg1, reg2)
- conflict_graph graph;
- int reg1;
- int reg2;
+conflict_graph_conflict_p (conflict_graph graph, int reg1, int reg2)
{
/* Build an arc to search for. */
struct conflict_graph_arc_def arc;
@@ -253,11 +240,8 @@ conflict_graph_conflict_p (graph, reg1, reg2)
passed back to ENUM_FN. */
void
-conflict_graph_enum (graph, reg, enum_fn, extra)
- conflict_graph graph;
- int reg;
- conflict_graph_enum_fn enum_fn;
- void *extra;
+conflict_graph_enum (conflict_graph graph, int reg,
+ conflict_graph_enum_fn enum_fn, void *extra)
{
conflict_graph_arc arc = graph->neighbor_heads[reg];
while (arc != NULL)
@@ -280,10 +264,7 @@ conflict_graph_enum (graph, reg, enum_fn, extra)
conflict to GRAPH between x and TARGET. */
void
-conflict_graph_merge_regs (graph, target, src)
- conflict_graph graph;
- int target;
- int src;
+conflict_graph_merge_regs (conflict_graph graph, int target, int src)
{
conflict_graph_arc arc = graph->neighbor_heads[src];
@@ -326,10 +307,7 @@ struct print_context
/* Callback function when enumerating conflicts during printing. */
static int
-print_conflict (reg1, reg2, contextp)
- int reg1;
- int reg2;
- void *contextp;
+print_conflict (int reg1, int reg2, void *contextp)
{
struct print_context *context = (struct print_context *) contextp;
int reg;
@@ -361,9 +339,7 @@ print_conflict (reg1, reg2, contextp)
/* Prints the conflicts in GRAPH to FP. */
void
-conflict_graph_print (graph, fp)
- conflict_graph graph;
- FILE *fp;
+conflict_graph_print (conflict_graph graph, FILE *fp)
{
int reg;
struct print_context context;
@@ -392,10 +368,7 @@ conflict_graph_print (graph, fp)
/* Callback function for note_stores. */
static void
-mark_reg (reg, setter, data)
- rtx reg;
- rtx setter ATTRIBUTE_UNUSED;
- void *data;
+mark_reg (rtx reg, rtx setter ATTRIBUTE_UNUSED, void *data)
{
regset set = (regset) data;
@@ -439,9 +412,7 @@ mark_reg (reg, setter, data)
canonical regs instead. */
conflict_graph
-conflict_graph_compute (regs, p)
- regset regs;
- partition p;
+conflict_graph_compute (regset regs, partition p)
{
conflict_graph graph = conflict_graph_new (max_reg_num ());
regset_head live_head;
@@ -464,9 +435,9 @@ conflict_graph_compute (regs, p)
AND_REG_SET (live, regs);
/* Walk the instruction stream backwards. */
- head = bb->head;
- insn = bb->end;
- for (insn = bb->end; insn != head; insn = PREV_INSN (insn))
+ head = BB_HEAD (bb);
+ insn = BB_END (bb);
+ for (insn = BB_END (bb); insn != head; insn = PREV_INSN (insn))
{
int born_reg;
int live_reg;
diff --git a/contrib/gcc/convert.c b/contrib/gcc/convert.c
index e440e35f5757..9096541fe2a1 100644
--- a/contrib/gcc/convert.c
+++ b/contrib/gcc/convert.c
@@ -1,6 +1,6 @@
-/* Utility routines for data type conversion for GNU C.
- Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1997,
- 1998 Free Software Foundation, Inc.
+/* Utility routines for data type conversion for GCC.
+ Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1997, 1998,
+ 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -25,20 +25,21 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "convert.h"
#include "toplev.h"
#include "langhooks.h"
-
+#include "real.h"
/* Convert EXPR to some pointer or reference type TYPE.
EXPR must be pointer, reference, integer, enumeral, or literal zero;
in other cases error is called. */
tree
-convert_to_pointer (type, expr)
- tree type, expr;
+convert_to_pointer (tree type, tree expr)
{
if (integer_zerop (expr))
{
@@ -71,15 +72,179 @@ convert_to_pointer (type, expr)
}
}
+/* Avoid any floating point extensions from EXP. */
+tree
+strip_float_extensions (tree exp)
+{
+ tree sub, expt, subt;
+
+ /* For floating point constant look up the narrowest type that can hold
+ it properly and handle it like (type)(narrowest_type)constant.
+ This way we can optimize for instance a=a*2.0 where "a" is float
+ but 2.0 is double constant. */
+ if (TREE_CODE (exp) == REAL_CST)
+ {
+ REAL_VALUE_TYPE orig;
+ tree type = NULL;
+
+ orig = TREE_REAL_CST (exp);
+ if (TYPE_PRECISION (TREE_TYPE (exp)) > TYPE_PRECISION (float_type_node)
+ && exact_real_truncate (TYPE_MODE (float_type_node), &orig))
+ type = float_type_node;
+ else if (TYPE_PRECISION (TREE_TYPE (exp))
+ > TYPE_PRECISION (double_type_node)
+ && exact_real_truncate (TYPE_MODE (double_type_node), &orig))
+ type = double_type_node;
+ if (type)
+ return build_real (type, real_value_truncate (TYPE_MODE (type), orig));
+ }
+
+ if (TREE_CODE (exp) != NOP_EXPR)
+ return exp;
+
+ sub = TREE_OPERAND (exp, 0);
+ subt = TREE_TYPE (sub);
+ expt = TREE_TYPE (exp);
+
+ if (!FLOAT_TYPE_P (subt))
+ return exp;
+
+ if (TYPE_PRECISION (subt) > TYPE_PRECISION (expt))
+ return exp;
+
+ return strip_float_extensions (sub);
+}
+
+
/* Convert EXPR to some floating-point type TYPE.
EXPR must be float, integer, or enumeral;
in other cases error is called. */
tree
-convert_to_real (type, expr)
- tree type, expr;
+convert_to_real (tree type, tree expr)
{
+ enum built_in_function fcode = builtin_mathfn_code (expr);
+ tree itype = TREE_TYPE (expr);
+
+ /* Disable until we figure out how to decide whether the functions are
+ present in runtime. */
+ /* Convert (float)sqrt((double)x) where x is float into sqrtf(x) */
+ if (optimize
+ && (fcode == BUILT_IN_SQRT
+ || fcode == BUILT_IN_SQRTL
+ || fcode == BUILT_IN_SIN
+ || fcode == BUILT_IN_SINL
+ || fcode == BUILT_IN_COS
+ || fcode == BUILT_IN_COSL
+ || fcode == BUILT_IN_EXP
+ || fcode == BUILT_IN_EXPL
+ || fcode == BUILT_IN_LOG
+ || fcode == BUILT_IN_LOGL)
+ && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
+ || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
+ {
+ tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr, 1)));
+ tree newtype = type;
+
+ /* We have (outertype)sqrt((innertype)x). Choose the wider mode from
+ the both as the safe type for operation. */
+ if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (type))
+ newtype = TREE_TYPE (arg0);
+
+ /* Be careful about integer to fp conversions.
+ These may overflow still. */
+ if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ && TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
+ && (TYPE_MODE (newtype) == TYPE_MODE (double_type_node)
+ || TYPE_MODE (newtype) == TYPE_MODE (float_type_node)))
+ {
+ tree arglist;
+ tree fn = mathfn_built_in (newtype, fcode);
+
+ if (fn)
+ {
+ arglist = build_tree_list (NULL_TREE, fold (convert_to_real (newtype, arg0)));
+ expr = build_function_call_expr (fn, arglist);
+ if (newtype == type)
+ return expr;
+ }
+ }
+ }
+ if (optimize
+ && (((fcode == BUILT_IN_FLOORL
+ || fcode == BUILT_IN_CEILL
+ || fcode == BUILT_IN_ROUND
+ || fcode == BUILT_IN_TRUNC
+ || fcode == BUILT_IN_NEARBYINT)
+ && (TYPE_MODE (type) == TYPE_MODE (double_type_node)
+ || TYPE_MODE (type) == TYPE_MODE (float_type_node)))
+ || ((fcode == BUILT_IN_FLOOR
+ || fcode == BUILT_IN_CEIL
+ || fcode == BUILT_IN_ROUND
+ || fcode == BUILT_IN_TRUNC
+ || fcode == BUILT_IN_NEARBYINT)
+ && (TYPE_MODE (type) == TYPE_MODE (float_type_node)))))
+ {
+ tree fn = mathfn_built_in (type, fcode);
+
+ if (fn)
+ {
+ tree arg0 = strip_float_extensions (TREE_VALUE (TREE_OPERAND (expr,
+ 1)));
+ tree arglist = build_tree_list (NULL_TREE,
+ fold (convert_to_real (type, arg0)));
+
+ return build_function_call_expr (fn, arglist);
+ }
+ }
+
+ /* Propagate the cast into the operation. */
+ if (itype != type && FLOAT_TYPE_P (type))
+ switch (TREE_CODE (expr))
+ {
+ /* Convert (float)-x into -(float)x. This is always safe. */
+ case ABS_EXPR:
+ case NEGATE_EXPR:
+ if (TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (expr)))
+ return build1 (TREE_CODE (expr), type,
+ fold (convert_to_real (type,
+ TREE_OPERAND (expr, 0))));
+ break;
+ /* Convert (outertype)((innertype0)a+(innertype1)b)
+ into ((newtype)a+(newtype)b) where newtype
+ is the widest mode from all of these. */
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case RDIV_EXPR:
+ {
+ tree arg0 = strip_float_extensions (TREE_OPERAND (expr, 0));
+ tree arg1 = strip_float_extensions (TREE_OPERAND (expr, 1));
+
+ if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ && FLOAT_TYPE_P (TREE_TYPE (arg1)))
+ {
+ tree newtype = type;
+ if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
+ newtype = TREE_TYPE (arg0);
+ if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
+ newtype = TREE_TYPE (arg1);
+ if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype))
+ {
+ expr = build (TREE_CODE (expr), newtype,
+ fold (convert_to_real (newtype, arg0)),
+ fold (convert_to_real (newtype, arg1)));
+ if (newtype == type)
+ return expr;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
switch (TREE_CODE (TREE_TYPE (expr)))
{
case REAL_TYPE:
@@ -117,8 +282,7 @@ convert_to_real (type, expr)
not in use in any existing structure. */
tree
-convert_to_integer (type, expr)
- tree type, expr;
+convert_to_integer (tree type, tree expr)
{
enum tree_code ex_form = TREE_CODE (expr);
tree intype = TREE_TYPE (expr);
@@ -156,6 +320,7 @@ convert_to_integer (type, expr)
if (TREE_CODE_CLASS (ex_form) == '<')
{
+ expr = copy_node (expr);
TREE_TYPE (expr) = type;
return expr;
}
@@ -164,6 +329,7 @@ convert_to_integer (type, expr)
|| ex_form == TRUTH_OR_EXPR || ex_form == TRUTH_ORIF_EXPR
|| ex_form == TRUTH_XOR_EXPR)
{
+ expr = copy_node (expr);
TREE_OPERAND (expr, 0) = convert (type, TREE_OPERAND (expr, 0));
TREE_OPERAND (expr, 1) = convert (type, TREE_OPERAND (expr, 1));
TREE_TYPE (expr) = type;
@@ -172,6 +338,7 @@ convert_to_integer (type, expr)
else if (ex_form == TRUTH_NOT_EXPR)
{
+ expr = copy_node (expr);
TREE_OPERAND (expr, 0) = convert (type, TREE_OPERAND (expr, 0));
TREE_TYPE (expr) = type;
return expr;
@@ -182,7 +349,27 @@ convert_to_integer (type, expr)
we are truncating EXPR. */
else if (outprec >= inprec)
- return build1 (NOP_EXPR, type, expr);
+ {
+ enum tree_code code;
+
+ /* If the precision of the EXPR's type is K bits and the
+ destination mode has more bits, and the sign is changing,
+ it is not safe to use a NOP_EXPR. For example, suppose
+ that EXPR's type is a 3-bit unsigned integer type, the
+ TYPE is a 3-bit signed integer type, and the machine mode
+ for the types is 8-bit QImode. In that case, the
+ conversion necessitates an explicit sign-extension. In
+ the signed-to-unsigned case the high-order bits have to
+ be cleared. */
+ if (TREE_UNSIGNED (type) != TREE_UNSIGNED (TREE_TYPE (expr))
+ && (TYPE_PRECISION (TREE_TYPE (expr))
+ != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)))))
+ code = CONVERT_EXPR;
+ else
+ code = NOP_EXPR;
+
+ return build1 (code, type, expr);
+ }
/* If TYPE is an enumeral type or a type with a precision less
than the number of bits in its mode, do the conversion to the
@@ -286,7 +473,6 @@ convert_to_integer (type, expr)
case BIT_AND_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
- case BIT_ANDTC_EXPR:
trunc1:
{
tree arg0 = get_unwidened (TREE_OPERAND (expr, 0), type);
@@ -315,7 +501,7 @@ convert_to_integer (type, expr)
/* Don't do unsigned arithmetic where signed was wanted,
or vice versa.
Exception: if both of the original operands were
- unsigned then we can safely do the work as unsigned.
+ unsigned then we can safely do the work as unsigned.
Exception: shift operations take their type solely
from the first argument.
Exception: the LSHIFT_EXPR case above requires that
@@ -390,7 +576,7 @@ convert_to_integer (type, expr)
/* It is sometimes worthwhile to push the narrowing down through
the conditional and never loses. */
return fold (build (COND_EXPR, type, TREE_OPERAND (expr, 0),
- convert (type, TREE_OPERAND (expr, 1)),
+ convert (type, TREE_OPERAND (expr, 1)),
convert (type, TREE_OPERAND (expr, 2))));
default:
@@ -425,11 +611,10 @@ convert_to_integer (type, expr)
/* Convert EXPR to the complex type TYPE in the usual ways. */
tree
-convert_to_complex (type, expr)
- tree type, expr;
+convert_to_complex (tree type, tree expr)
{
tree subtype = TREE_TYPE (type);
-
+
switch (TREE_CODE (TREE_TYPE (expr)))
{
case REAL_TYPE:
@@ -481,8 +666,7 @@ convert_to_complex (type, expr)
/* Convert EXPR to the vector type TYPE in the usual ways. */
tree
-convert_to_vector (type, expr)
- tree type, expr;
+convert_to_vector (tree type, tree expr)
{
switch (TREE_CODE (TREE_TYPE (expr)))
{
diff --git a/contrib/gcc/convert.h b/contrib/gcc/convert.h
index ddc3673824c8..fe3bcbb8441b 100644
--- a/contrib/gcc/convert.h
+++ b/contrib/gcc/convert.h
@@ -1,5 +1,5 @@
/* Definition of functions in convert.c.
- Copyright (C) 1993, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1993, 2000, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -18,8 +18,8 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-extern tree convert_to_integer PARAMS ((tree, tree));
-extern tree convert_to_pointer PARAMS ((tree, tree));
-extern tree convert_to_real PARAMS ((tree, tree));
-extern tree convert_to_complex PARAMS ((tree, tree));
-extern tree convert_to_vector PARAMS ((tree, tree));
+extern tree convert_to_integer (tree, tree);
+extern tree convert_to_pointer (tree, tree);
+extern tree convert_to_real (tree, tree);
+extern tree convert_to_complex (tree, tree);
+extern tree convert_to_vector (tree, tree);
diff --git a/contrib/gcc/coretypes.h b/contrib/gcc/coretypes.h
new file mode 100644
index 000000000000..e800d004252c
--- /dev/null
+++ b/contrib/gcc/coretypes.h
@@ -0,0 +1,65 @@
+/* GCC core type declarations.
+ Copyright (C) 2002 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Provide forward declarations of core types which are referred to by
+ most of the compiler. This allows header files to use these types
+ (e.g. in function prototypes) without concern for whether the full
+ definitions are visible. Some other declarations that need to be
+ universally visible are here, too.
+
+ In the context of tconfig.h, most of these have special definitions
+ which prevent them from being used except in further type
+ declarations. This is a kludge; the right thing is to avoid
+ including the "tm.h" header set in the context of tconfig.h, but
+ we're not there yet. */
+
+#ifndef GCC_CORETYPES_H
+#define GCC_CORETYPES_H
+
+#define GTY(x) /* nothing - marker for gengtype */
+
+#ifndef USED_FOR_TARGET
+
+struct rtx_def;
+typedef struct rtx_def *rtx;
+struct rtvec_def;
+typedef struct rtvec_def *rtvec;
+union tree_node;
+typedef union tree_node *tree;
+
+/* Provide forward struct declaration so that we don't have to include
+ all of cpplib.h whenever a random prototype includes a pointer.
+ Note that the cpp_reader typedef remains part of cpplib.h. */
+
+struct cpp_reader;
+
+#else
+
+struct _dont_use_rtx_here_;
+struct _dont_use_rtvec_here_;
+union _dont_use_tree_here_;
+#define rtx struct _dont_use_rtx_here_ *
+#define rtvec struct _dont_use_rtvec_here *
+#define tree union _dont_use_tree_here_ *
+
+#endif
+
+#endif /* coretypes.h */
+
diff --git a/contrib/gcc/coverage.c b/contrib/gcc/coverage.c
new file mode 100644
index 000000000000..395c1e4de55d
--- /dev/null
+++ b/contrib/gcc/coverage.c
@@ -0,0 +1,972 @@
+/* Read and write coverage files, and associated functionality.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
+ based on some ideas from Dain Samples of UC Berkeley.
+ Further mangling by Bob Manson, Cygnus Support.
+ Further mangled by Nathan Sidwell, CodeSourcery
+
+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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#define GCOV_LINKAGE
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "tree.h"
+#include "flags.h"
+#include "output.h"
+#include "regs.h"
+#include "expr.h"
+#include "function.h"
+#include "toplev.h"
+#include "ggc.h"
+#include "target.h"
+#include "coverage.h"
+#include "libfuncs.h"
+#include "langhooks.h"
+#include "hashtab.h"
+
+#include "gcov-io.c"
+
+struct function_list
+{
+ struct function_list *next; /* next function */
+ unsigned ident; /* function ident */
+ unsigned checksum; /* function checksum */
+ unsigned n_ctrs[GCOV_COUNTERS];/* number of counters. */
+};
+
+/* Counts information for a function. */
+typedef struct counts_entry
+{
+ /* We hash by */
+ unsigned ident;
+ unsigned ctr;
+
+ /* Store */
+ unsigned checksum;
+ gcov_type *counts;
+ struct gcov_ctr_summary summary;
+
+ /* Workspace */
+ struct counts_entry *chain;
+
+} counts_entry_t;
+
+static struct function_list *functions_head = 0;
+static struct function_list **functions_tail = &functions_head;
+static unsigned no_coverage = 0;
+
+/* Cumulative counter information for whole program. */
+static unsigned prg_ctr_mask; /* Mask of counter types generated. */
+static unsigned prg_n_ctrs[GCOV_COUNTERS]; /* Total counters allocated. */
+
+/* Counter information for current function. */
+static unsigned fn_ctr_mask; /* Mask of counters used. */
+static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated. */
+static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base. */
+
+/* Name of the output file for coverage output file. */
+static char *bbg_file_name;
+static unsigned bbg_file_opened;
+static int bbg_function_announced;
+
+/* Name of the count data file. */
+static char *da_file_name;
+
+/* Hash table of count data. */
+static htab_t counts_hash = NULL;
+
+/* The names of the counter tables. */
+static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
+
+/* The names of merge functions for counters. */
+static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
+static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
+
+/* Forward declarations. */
+static hashval_t htab_counts_entry_hash (const void *);
+static int htab_counts_entry_eq (const void *, const void *);
+static void htab_counts_entry_del (void *);
+static void read_counts_file (void);
+static unsigned compute_checksum (void);
+static unsigned coverage_checksum_string (unsigned, const char *);
+static tree build_fn_info_type (unsigned);
+static tree build_fn_info_value (const struct function_list *, tree);
+static tree build_ctr_info_type (void);
+static tree build_ctr_info_value (unsigned, tree);
+static tree build_gcov_info (void);
+static void create_coverage (void);
+
+
+static hashval_t
+htab_counts_entry_hash (const void *of)
+{
+ const counts_entry_t *entry = of;
+
+ return entry->ident * GCOV_COUNTERS + entry->ctr;
+}
+
+static int
+htab_counts_entry_eq (const void *of1, const void *of2)
+{
+ const counts_entry_t *entry1 = of1;
+ const counts_entry_t *entry2 = of2;
+
+ return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
+}
+
+static void
+htab_counts_entry_del (void *of)
+{
+ counts_entry_t *entry = of;
+
+ free (entry->counts);
+ free (entry);
+}
+
+/* Read in the counts file, if available. */
+
+static void
+read_counts_file (void)
+{
+ gcov_unsigned_t fn_ident = 0;
+ gcov_unsigned_t checksum = -1;
+ counts_entry_t *summaried = NULL;
+ unsigned seen_summary = 0;
+ gcov_unsigned_t tag;
+ int is_error = 0;
+
+ if (!gcov_open (da_file_name, 1))
+ return;
+
+ if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
+ {
+ warning ("`%s' is not a gcov data file", da_file_name);
+ gcov_close ();
+ return;
+ }
+ else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
+ {
+ char v[4], e[4];
+
+ GCOV_UNSIGNED2STRING (v, tag);
+ GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
+
+ warning ("`%s' is version `%.4s', expected version `%.4s'",
+ da_file_name, v, e);
+ gcov_close ();
+ return;
+ }
+
+ /* Read and discard the stamp. */
+ gcov_read_unsigned ();
+
+ counts_hash = htab_create (10,
+ htab_counts_entry_hash, htab_counts_entry_eq,
+ htab_counts_entry_del);
+ while ((tag = gcov_read_unsigned ()))
+ {
+ gcov_unsigned_t length;
+ gcov_position_t offset;
+
+ length = gcov_read_unsigned ();
+ offset = gcov_position ();
+ if (tag == GCOV_TAG_FUNCTION)
+ {
+ fn_ident = gcov_read_unsigned ();
+ checksum = gcov_read_unsigned ();
+ if (seen_summary)
+ {
+ /* We have already seen a summary, this means that this
+ new function begins a new set of program runs. We
+ must unlink the summaried chain. */
+ counts_entry_t *entry, *chain;
+
+ for (entry = summaried; entry; entry = chain)
+ {
+ chain = entry->chain;
+ entry->chain = NULL;
+ }
+ summaried = NULL;
+ seen_summary = 0;
+ }
+ }
+ else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
+ {
+ counts_entry_t *entry;
+ struct gcov_summary summary;
+
+ gcov_read_summary (&summary);
+ seen_summary = 1;
+ for (entry = summaried; entry; entry = entry->chain)
+ {
+ struct gcov_ctr_summary *csum = &summary.ctrs[entry->ctr];
+
+ entry->summary.runs += csum->runs;
+ entry->summary.sum_all += csum->sum_all;
+ if (entry->summary.run_max < csum->run_max)
+ entry->summary.run_max = csum->run_max;
+ entry->summary.sum_max += csum->sum_max;
+ }
+ }
+ else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
+ {
+ counts_entry_t **slot, *entry, elt;
+ unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
+ unsigned ix;
+
+ elt.ident = fn_ident;
+ elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
+
+ slot = (counts_entry_t **) htab_find_slot
+ (counts_hash, &elt, INSERT);
+ entry = *slot;
+ if (!entry)
+ {
+ *slot = entry = xcalloc (1, sizeof (counts_entry_t));
+ entry->ident = elt.ident;
+ entry->ctr = elt.ctr;
+ entry->checksum = checksum;
+ entry->summary.num = n_counts;
+ entry->counts = xcalloc (n_counts, sizeof (gcov_type));
+ }
+ else if (entry->checksum != checksum)
+ {
+ error ("coverage mismatch for function %u while reading execution counters.",
+ fn_ident);
+ error ("checksum is %x instead of %x", entry->checksum, checksum);
+ htab_delete (counts_hash);
+ break;
+ }
+ else if (entry->summary.num != n_counts)
+ {
+ error ("coverage mismatch for function %u while reading execution counters.",
+ fn_ident);
+ error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
+ htab_delete (counts_hash);
+ break;
+ }
+ else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
+ {
+ error ("cannot merge separate %s counters for function %u",
+ ctr_names[elt.ctr], fn_ident);
+ goto skip_merge;
+ }
+
+ if (elt.ctr < GCOV_COUNTERS_SUMMABLE
+ /* This should always be true for a just allocated entry,
+ and always false for an existing one. Check this way, in
+ case the gcov file is corrupt. */
+ && (!entry->chain || summaried != entry))
+ {
+ entry->chain = summaried;
+ summaried = entry;
+ }
+ for (ix = 0; ix != n_counts; ix++)
+ entry->counts[ix] += gcov_read_counter ();
+ skip_merge:;
+ }
+ gcov_sync (offset, length);
+ if ((is_error = gcov_is_error ()))
+ break;
+ }
+
+ if (!gcov_is_eof ())
+ {
+ error (is_error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
+ da_file_name);
+ htab_delete (counts_hash);
+ }
+
+ gcov_close ();
+}
+
+/* Returns the counters for a particular tag. */
+
+gcov_type *
+get_coverage_counts (unsigned counter, unsigned expected,
+ const struct gcov_ctr_summary **summary)
+{
+ counts_entry_t *entry, elt;
+ gcov_unsigned_t checksum = -1;
+
+ /* No hash table, no counts. */
+ if (!counts_hash)
+ {
+ static int warned = 0;
+
+ if (!warned++)
+ inform ("file %s not found, execution counts assumed to be zero",
+ da_file_name);
+ return NULL;
+ }
+
+ elt.ident = current_function_funcdef_no + 1;
+ elt.ctr = counter;
+ entry = htab_find (counts_hash, &elt);
+ if (!entry)
+ {
+ warning ("no coverage for function '%s' found.", IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (current_function_decl)));
+ return 0;
+ }
+
+ checksum = compute_checksum ();
+ if (entry->checksum != checksum)
+ {
+ error ("coverage mismatch for function '%s' while reading counter '%s'.",
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)),
+ ctr_names[counter]);
+ error ("checksum is %x instead of %x", entry->checksum, checksum);
+ return 0;
+ }
+ else if (entry->summary.num != expected)
+ {
+ error ("coverage mismatch for function '%s' while reading counter '%s'.",
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)),
+ ctr_names[counter]);
+ error ("number of counters is %d instead of %d", entry->summary.num, expected);
+ return 0;
+ }
+
+ if (summary)
+ *summary = &entry->summary;
+
+ return entry->counts;
+}
+
+/* Allocate NUM counters of type COUNTER. Returns nonzero if the
+ allocation succeeded. */
+
+int
+coverage_counter_alloc (unsigned counter, unsigned num)
+{
+ if (no_coverage)
+ return 0;
+
+ if (!num)
+ return 1;
+
+ if (!ctr_labels[counter])
+ {
+ /* Generate and save a copy of this so it can be shared. */
+ char buf[20];
+
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
+ ctr_labels[counter] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
+ SYMBOL_REF_FLAGS (ctr_labels[counter]) = SYMBOL_FLAG_LOCAL;
+ }
+ fn_b_ctrs[counter] = fn_n_ctrs[counter];
+ fn_n_ctrs[counter] += num;
+ fn_ctr_mask |= 1 << counter;
+ return 1;
+}
+
+/* Generate a MEM rtl to access COUNTER NO. */
+
+rtx
+coverage_counter_ref (unsigned counter, unsigned no)
+{
+ unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
+ enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
+ rtx ref;
+
+ if (no >= fn_n_ctrs[counter] - fn_b_ctrs[counter])
+ abort ();
+ no += prg_n_ctrs[counter] + fn_b_ctrs[counter];
+ ref = plus_constant (ctr_labels[counter], gcov_size / BITS_PER_UNIT * no);
+ ref = gen_rtx_MEM (mode, ref);
+ set_mem_alias_set (ref, new_alias_set ());
+ MEM_NOTRAP_P (ref) = 1;
+
+ return ref;
+}
+
+/* Generate a checksum for a string. CHKSUM is the current
+ checksum. */
+
+static unsigned
+coverage_checksum_string (unsigned chksum, const char *string)
+{
+ int i;
+ char *dup = NULL;
+
+ /* Look for everything that looks if it were produced by
+ get_file_function_name_long and zero out the second part
+ that may result from flag_random_seed. This is not critical
+ as the checksums are used only for sanity checking. */
+ for (i = 0; string[i]; i++)
+ {
+ if (!strncmp (string + i, "_GLOBAL__", 9))
+ for (i = i + 9; string[i]; i++)
+ if (string[i]=='_')
+ {
+ int y;
+ unsigned seed;
+
+ for (y = 1; y < 9; y++)
+ if (!(string[i + y] >= '0' && string[i + y] <= '9')
+ && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
+ break;
+ if (y != 9 || string[i + 9] != '_')
+ continue;
+ for (y = 10; y < 18; y++)
+ if (!(string[i + y] >= '0' && string[i + y] <= '9')
+ && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
+ break;
+ if (y != 18)
+ continue;
+ if (!sscanf (string + i + 10, "%X", &seed))
+ abort ();
+ if (seed != crc32_string (0, flag_random_seed))
+ continue;
+ string = dup = xstrdup (string);
+ for (y = 10; y < 18; y++)
+ dup[i + y] = '0';
+ break;
+ }
+ break;
+ }
+
+ chksum = crc32_string (chksum, string);
+ if (dup)
+ free (dup);
+
+ return chksum;
+}
+
+/* Compute checksum for the current function. We generate a CRC32. */
+
+static unsigned
+compute_checksum (void)
+{
+ unsigned chksum = DECL_SOURCE_LINE (current_function_decl);
+
+ chksum = coverage_checksum_string (chksum,
+ DECL_SOURCE_FILE (current_function_decl));
+ chksum = coverage_checksum_string
+ (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
+
+ return chksum;
+}
+
+/* Begin output to the graph file for the current function.
+ Opens the output file, if not already done. Writes the
+ function header, if not already done. Returns nonzero if data
+ should be output. */
+
+int
+coverage_begin_output (void)
+{
+ if (no_coverage)
+ return 0;
+
+ if (!bbg_function_announced)
+ {
+ const char *file = DECL_SOURCE_FILE (current_function_decl);
+ unsigned line = DECL_SOURCE_LINE (current_function_decl);
+ unsigned long offset;
+
+ if (!bbg_file_opened)
+ {
+ if (!gcov_open (bbg_file_name, -1))
+ error ("cannot open %s", bbg_file_name);
+ else
+ {
+ gcov_write_unsigned (GCOV_NOTE_MAGIC);
+ gcov_write_unsigned (GCOV_VERSION);
+ gcov_write_unsigned (local_tick);
+ }
+ bbg_file_opened = 1;
+ }
+
+ /* Announce function */
+ offset = gcov_write_tag (GCOV_TAG_FUNCTION);
+ gcov_write_unsigned (current_function_funcdef_no + 1);
+ gcov_write_unsigned (compute_checksum ());
+ gcov_write_string (IDENTIFIER_POINTER
+ (DECL_ASSEMBLER_NAME (current_function_decl)));
+ gcov_write_string (file);
+ gcov_write_unsigned (line);
+ gcov_write_length (offset);
+
+ bbg_function_announced = 1;
+ }
+ return !gcov_is_error ();
+}
+
+/* Finish coverage data for the current function. Verify no output
+ error has occurred. Save function coverage counts. */
+
+void
+coverage_end_function (void)
+{
+ unsigned i;
+
+ if (bbg_file_opened > 1 && gcov_is_error ())
+ {
+ warning ("error writing `%s'", bbg_file_name);
+ bbg_file_opened = -1;
+ }
+
+ if (fn_ctr_mask)
+ {
+ struct function_list *item;
+
+ item = xmalloc (sizeof (struct function_list));
+
+ *functions_tail = item;
+ functions_tail = &item->next;
+
+ item->next = 0;
+ item->ident = current_function_funcdef_no + 1;
+ item->checksum = compute_checksum ();
+ for (i = 0; i != GCOV_COUNTERS; i++)
+ {
+ item->n_ctrs[i] = fn_n_ctrs[i];
+ prg_n_ctrs[i] += fn_n_ctrs[i];
+ fn_n_ctrs[i] = fn_b_ctrs[i] = 0;
+ }
+ prg_ctr_mask |= fn_ctr_mask;
+ fn_ctr_mask = 0;
+ }
+ bbg_function_announced = 0;
+}
+
+/* Creates the gcov_fn_info RECORD_TYPE. */
+
+static tree
+build_fn_info_type (unsigned int counters)
+{
+ tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
+ tree field, fields;
+ tree array_type;
+
+ /* ident */
+ fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
+
+ /* checksum */
+ field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+
+ array_type = build_index_type (build_int_2 (counters - 1, 0));
+ array_type = build_array_type (unsigned_type_node, array_type);
+
+ /* counters */
+ field = build_decl (FIELD_DECL, NULL_TREE, array_type);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+
+ finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
+
+ return type;
+}
+
+/* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
+ the function being processed and TYPE is the gcov_fn_info
+ RECORD_TYPE. */
+
+static tree
+build_fn_info_value (const struct function_list *function, tree type)
+{
+ tree value = NULL_TREE;
+ tree fields = TYPE_FIELDS (type);
+ unsigned ix;
+ tree array_value = NULL_TREE;
+
+ /* ident */
+ value = tree_cons (fields,
+ convert (unsigned_intSI_type_node,
+ build_int_2 (function->ident, 0)),
+ value);
+ fields = TREE_CHAIN (fields);
+
+ /* checksum */
+ value = tree_cons (fields,
+ convert (unsigned_intSI_type_node,
+ build_int_2 (function->checksum, 0)),
+ value);
+ fields = TREE_CHAIN (fields);
+
+ /* counters */
+ for (ix = 0; ix != GCOV_COUNTERS; ix++)
+ if (prg_ctr_mask & (1 << ix))
+ {
+ tree counters = convert (unsigned_type_node,
+ build_int_2 (function->n_ctrs[ix], 0));
+
+ array_value = tree_cons (NULL_TREE, counters, array_value);
+ }
+
+ array_value = build_constructor (TREE_TYPE (fields), nreverse (array_value));
+ value = tree_cons (fields, array_value, value);
+
+ value = build_constructor (type, nreverse (value));
+
+ return value;
+}
+
+/* Creates the gcov_ctr_info RECORD_TYPE. */
+
+static tree
+build_ctr_info_type (void)
+{
+ tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
+ tree field, fields = NULL_TREE;
+ tree gcov_ptr_type = build_pointer_type (GCOV_TYPE_NODE);
+ tree gcov_merge_fn_type;
+
+ /* counters */
+ field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+
+ /* values */
+ field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+
+ /* merge */
+ gcov_merge_fn_type =
+ build_function_type_list (void_type_node,
+ gcov_ptr_type, unsigned_type_node,
+ NULL_TREE);
+ field = build_decl (FIELD_DECL, NULL_TREE,
+ build_pointer_type (gcov_merge_fn_type));
+ TREE_CHAIN (field) = fields;
+ fields = field;
+
+ finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
+
+ return type;
+}
+
+/* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
+ the counter being processed and TYPE is the gcov_ctr_info
+ RECORD_TYPE. */
+
+static tree
+build_ctr_info_value (unsigned int counter, tree type)
+{
+ tree value = NULL_TREE;
+ tree fields = TYPE_FIELDS (type);
+ tree fn;
+
+ /* counters */
+ value = tree_cons (fields,
+ convert (unsigned_intSI_type_node,
+ build_int_2 (prg_n_ctrs[counter], 0)),
+ value);
+ fields = TREE_CHAIN (fields);
+
+ if (prg_n_ctrs[counter])
+ {
+ tree array_type, array;
+
+ array_type = build_index_type (build_int_2 (prg_n_ctrs[counter] - 1, 0));
+ array_type = build_array_type (TREE_TYPE (TREE_TYPE (fields)),
+ array_type);
+
+ array = build_decl (VAR_DECL, NULL_TREE, array_type);
+ TREE_STATIC (array) = 1;
+ DECL_NAME (array) = get_identifier (XSTR (ctr_labels[counter], 0));
+ assemble_variable (array, 0, 0, 0);
+
+ value = tree_cons (fields,
+ build1 (ADDR_EXPR, TREE_TYPE (fields), array),
+ value);
+ }
+ else
+ value = tree_cons (fields, null_pointer_node, value);
+ fields = TREE_CHAIN (fields);
+
+ fn = build_decl (FUNCTION_DECL,
+ get_identifier (ctr_merge_functions[counter]),
+ TREE_TYPE (TREE_TYPE (fields)));
+ DECL_EXTERNAL (fn) = 1;
+ TREE_PUBLIC (fn) = 1;
+ DECL_ARTIFICIAL (fn) = 1;
+ TREE_NOTHROW (fn) = 1;
+ value = tree_cons (fields,
+ build1 (ADDR_EXPR, TREE_TYPE (fields), fn),
+ value);
+
+ value = build_constructor (type, nreverse (value));
+
+ return value;
+}
+
+/* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
+ CONSTRUCTOR. */
+
+static tree
+build_gcov_info (void)
+{
+ unsigned n_ctr_types, ix;
+ tree type, const_type;
+ tree fn_info_type, fn_info_value = NULL_TREE;
+ tree fn_info_ptr_type;
+ tree ctr_info_type, ctr_info_ary_type, ctr_info_value = NULL_TREE;
+ tree field, fields = NULL_TREE;
+ tree value = NULL_TREE;
+ tree filename_string;
+ char *filename;
+ int filename_len;
+ unsigned n_fns;
+ const struct function_list *fn;
+ tree string_type;
+
+ /* Count the number of active counters. */
+ for (n_ctr_types = 0, ix = 0; ix != GCOV_COUNTERS; ix++)
+ if (prg_ctr_mask & (1 << ix))
+ n_ctr_types++;
+
+ type = (*lang_hooks.types.make_type) (RECORD_TYPE);
+ const_type = build_qualified_type (type, TYPE_QUAL_CONST);
+
+ /* Version ident */
+ field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (field, convert (unsigned_intSI_type_node,
+ build_int_2 (GCOV_VERSION, 0)),
+ value);
+
+ /* next -- NULL */
+ field = build_decl (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, unsigned_intSI_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (field, convert (unsigned_intSI_type_node,
+ build_int_2 (local_tick, 0)),
+ value);
+
+ /* Filename */
+ string_type = build_pointer_type (build_qualified_type (char_type_node,
+ TYPE_QUAL_CONST));
+ field = build_decl (FIELD_DECL, NULL_TREE, string_type);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ filename = getpwd ();
+ filename = (filename && da_file_name[0] != '/'
+ ? concat (filename, "/", da_file_name, NULL)
+ : da_file_name);
+ filename_len = strlen (filename);
+ filename_string = build_string (filename_len + 1, filename);
+ if (filename != da_file_name)
+ free (filename);
+ TREE_TYPE (filename_string) =
+ build_array_type (char_type_node,
+ build_index_type (build_int_2 (filename_len, 0)));
+ value = tree_cons (field, build1 (ADDR_EXPR, string_type, filename_string),
+ value);
+
+ /* Build the fn_info type and initializer. */
+ fn_info_type = build_fn_info_type (n_ctr_types);
+ fn_info_ptr_type = build_pointer_type (build_qualified_type
+ (fn_info_type, TYPE_QUAL_CONST));
+ for (fn = functions_head, n_fns = 0; fn; fn = fn->next, n_fns++)
+ fn_info_value = tree_cons (NULL_TREE,
+ build_fn_info_value (fn, fn_info_type),
+ fn_info_value);
+ if (n_fns)
+ {
+ tree array_type;
+
+ array_type = build_index_type (build_int_2 (n_fns - 1, 0));
+ array_type = build_array_type (fn_info_type, array_type);
+
+ fn_info_value = build_constructor (array_type, nreverse (fn_info_value));
+ fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
+ }
+ else
+ fn_info_value = null_pointer_node;
+
+ /* number of functions */
+ field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (field,
+ convert (unsigned_type_node, build_int_2 (n_fns, 0)),
+ value);
+
+ /* fn_info table */
+ field = build_decl (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, unsigned_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (field,
+ convert (unsigned_type_node,
+ build_int_2 (prg_ctr_mask, 0)),
+ value);
+
+ /* counters */
+ ctr_info_type = build_ctr_info_type ();
+ ctr_info_ary_type = build_index_type (build_int_2 (n_ctr_types, 0));
+ ctr_info_ary_type = build_array_type (ctr_info_type, ctr_info_ary_type);
+ for (ix = 0; ix != GCOV_COUNTERS; ix++)
+ if (prg_ctr_mask & (1 << ix))
+ ctr_info_value = tree_cons (NULL_TREE,
+ build_ctr_info_value (ix, ctr_info_type),
+ ctr_info_value);
+ ctr_info_value = build_constructor (ctr_info_ary_type,
+ nreverse (ctr_info_value));
+
+ field = build_decl (FIELD_DECL, NULL_TREE, ctr_info_ary_type);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (field, ctr_info_value, value);
+
+ finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
+
+ value = build_constructor (type, nreverse (value));
+
+ return value;
+}
+
+/* Write out the structure which libgcov uses to locate all the
+ counters. The structures used here must match those defined in
+ gcov-io.h. Write out the constructor to call __gcov_init. */
+
+static void
+create_coverage (void)
+{
+ tree gcov_info, gcov_info_value;
+ char name[20];
+ char *ctor_name;
+ tree ctor;
+ rtx gcov_info_address;
+
+ no_coverage = 1; /* Disable any further coverage. */
+
+ if (!prg_ctr_mask)
+ return;
+
+ gcov_info_value = build_gcov_info ();
+
+ gcov_info = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (gcov_info_value));
+ DECL_INITIAL (gcov_info) = gcov_info_value;
+
+ TREE_STATIC (gcov_info) = 1;
+ ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
+ DECL_NAME (gcov_info) = get_identifier (name);
+
+ /* Build structure. */
+ assemble_variable (gcov_info, 0, 0, 0);
+
+ /* Build the constructor function to invoke __gcov_init. */
+ ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
+ "_GCOV", NULL);
+ ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
+ build_function_type (void_type_node, NULL_TREE));
+ free (ctor_name);
+ DECL_EXTERNAL (ctor) = 0;
+
+ /* It can be a static function as long as collect2 does not have
+ to scan the object file to find its ctor/dtor routine. */
+ TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
+ TREE_USED (ctor) = 1;
+ DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+ DECL_UNINLINABLE (ctor) = 1;
+
+ ctor = (*lang_hooks.decls.pushdecl) (ctor);
+ rest_of_decl_compilation (ctor, 0, 1, 0);
+ announce_function (ctor);
+ current_function_decl = ctor;
+ make_decl_rtl (ctor, NULL);
+ init_function_start (ctor);
+ expand_function_start (ctor, 0);
+ /* Actually generate the code to call __gcov_init. */
+ gcov_info_address = force_reg (Pmode, XEXP (DECL_RTL (gcov_info), 0));
+ emit_library_call (gcov_init_libfunc, LCT_NORMAL, VOIDmode, 1,
+ gcov_info_address, Pmode);
+
+ expand_function_end ();
+ /* Create a dummy BLOCK. */
+ DECL_INITIAL (ctor) = make_node (BLOCK);
+ TREE_USED (DECL_INITIAL (ctor)) = 1;
+
+ rest_of_compilation (ctor);
+
+ if (! quiet_flag)
+ fflush (asm_out_file);
+ current_function_decl = NULL_TREE;
+
+ if (targetm.have_ctors_dtors)
+ (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
+ DEFAULT_INIT_PRIORITY);
+}
+
+/* Perform file-level initialization. Read in data file, generate name
+ of graph file. */
+
+void
+coverage_init (const char *filename)
+{
+ int len = strlen (filename);
+
+ /* Name of da file. */
+ da_file_name = xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
+ strcpy (da_file_name, filename);
+ strcat (da_file_name, GCOV_DATA_SUFFIX);
+
+ /* Name of bbg file. */
+ bbg_file_name = xmalloc (len + strlen (GCOV_NOTE_SUFFIX) + 1);
+ strcpy (bbg_file_name, filename);
+ strcat (bbg_file_name, GCOV_NOTE_SUFFIX);
+
+ read_counts_file ();
+}
+
+/* Performs file-level cleanup. Close graph file, generate coverage
+ variables and constructor. */
+
+void
+coverage_finish (void)
+{
+ create_coverage ();
+ if (bbg_file_opened)
+ {
+ int error = gcov_close ();
+
+ if (error)
+ unlink (bbg_file_name);
+ if (!local_tick)
+ /* Only remove the da file, if we cannot stamp it. If we can
+ stamp it, libgcov will DTRT. */
+ unlink (da_file_name);
+ }
+}
+
+#include "gt-coverage.h"
diff --git a/contrib/gcc/coverage.h b/contrib/gcc/coverage.h
new file mode 100644
index 000000000000..9756bbaafa8f
--- /dev/null
+++ b/contrib/gcc/coverage.h
@@ -0,0 +1,48 @@
+/* coverage.h - Defines data exported from coverage.c
+ Copyright (C) 1998, 1999, 2000, 2001, 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef GCC_COVERAGE_H
+#define GCC_COVERAGE_H
+
+#include "gcov-io.h"
+
+extern void coverage_init (const char *);
+extern void coverage_finish (void);
+extern void coverage_read_counts_file (void);
+
+/* Complete the coverage information for the current function. Once
+ per function. */
+extern void coverage_end_function (void);
+
+/* Start outputting coverage information for the current
+ function. Repeatable per function. */
+extern int coverage_begin_output (void);
+
+/* Allocate some counters. Repeatable per function. */
+extern int coverage_counter_alloc (unsigned /*counter*/, unsigned/*num*/);
+/* Use a counter from the most recent allocation. */
+extern rtx coverage_counter_ref (unsigned /*counter*/, unsigned/*num*/);
+
+/* Get all the counters for the current function. */
+extern gcov_type *get_coverage_counts (unsigned /*counter*/,
+ unsigned /*expected*/,
+ const struct gcov_ctr_summary **);
+
+#endif
diff --git a/contrib/gcc/cp-demangle.c b/contrib/gcc/cp-demangle.c
index 5dcce5560ee1..fe4b36712d35 100644
--- a/contrib/gcc/cp-demangle.c
+++ b/contrib/gcc/cp-demangle.c
@@ -1,10 +1,10 @@
-/* Demangler for IA64 / g++ V3 ABI.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
- Written by Alex Samuel <samuel@codesourcery.com>.
+/* Demangler for g++ V3 ABI.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@wasabisystems.com>.
- This file is part of GNU CC.
+ This file is part of the libiberty library, which is part of GCC.
- This program is free software; you can redistribute it and/or modify
+ 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 2 of the License, or
(at your option) any later version.
@@ -28,3643 +28,4000 @@
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-/* This file implements demangling of C++ names mangled according to
- the IA64 / g++ V3 ABI. Use the cp_demangle function to
- demangle a mangled name, or compile with the preprocessor macro
- STANDALONE_DEMANGLER defined to create a demangling filter
- executable (functionally similar to c++filt, but includes this
- demangler only). */
+/* This code implements a demangler for the g++ V3 ABI. The ABI is
+ described on this web page:
+ http://www.codesourcery.com/cxx-abi/abi.html#mangling
+
+ This code was written while looking at the demangler written by
+ Alex Samuel <samuel@codesourcery.com>.
+
+ This code first pulls the mangled name apart into a list of
+ components, and then walks the list generating the demangled
+ name.
+
+ This file will normally define the following functions, q.v.:
+ char *cplus_demangle_v3(const char *mangled, int options)
+ char *java_demangle_v3(const char *mangled)
+ enum gnu_v3_ctor_kinds is_gnu_v3_mangled_ctor (const char *name)
+ enum gnu_v3_dtor_kinds is_gnu_v3_mangled_dtor (const char *name)
+
+ Also, the interface to the component list is public, and defined in
+ demangle.h. The interface consists of these types, which are
+ defined in demangle.h:
+ enum demangle_component_type
+ struct demangle_component
+ and these functions defined in this file:
+ cplus_demangle_fill_name
+ cplus_demangle_fill_extended_operator
+ cplus_demangle_fill_ctor
+ cplus_demangle_fill_dtor
+ cplus_demangle_print
+ and other functions defined in the file cp-demint.c.
+
+ This file also defines some other functions and variables which are
+ only to be used by the file cp-demint.c.
+
+ Preprocessor macros you can define while compiling this file:
+
+ IN_LIBGCC2
+ If defined, this file defines the following function, q.v.:
+ char *__cxa_demangle (const char *mangled, char *buf, size_t *len,
+ int *status)
+ instead of cplus_demangle_v3() and java_demangle_v3().
+
+ IN_GLIBCPP_V3
+ If defined, this file defines only __cxa_demangle(), and no other
+ publically visible functions or variables.
+
+ STANDALONE_DEMANGLER
+ If defined, this file defines a main() function which demangles
+ any arguments, or, if none, demangles stdin.
+
+ CP_DEMANGLE_DEBUG
+ If defined, turns on debugging mode, which prints information on
+ stdout about the mangled string. This is not generally useful.
+*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <sys/types.h>
+#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
-
-#include <stdio.h>
-
#ifdef HAVE_STRING_H
#include <string.h>
#endif
-#include <ctype.h>
-
#include "ansidecl.h"
#include "libiberty.h"
-#include "dyn-string.h"
#include "demangle.h"
+#include "cp-demangle.h"
-/* If CP_DEMANGLE_DEBUG is defined, a trace of the grammar evaluation,
- and other debugging output, will be generated. */
-#ifdef CP_DEMANGLE_DEBUG
-#define DEMANGLE_TRACE(PRODUCTION, DM) \
- fprintf (stderr, " -> %-24s at position %3d\n", \
- (PRODUCTION), current_position (DM));
-#else
-#define DEMANGLE_TRACE(PRODUCTION, DM)
-#endif
+/* If IN_GLIBCPP_V3 is defined, some functions are made static. We
+ also rename them via #define to avoid compiler errors when the
+ static definition conflicts with the extern declaration in a header
+ file. */
+#ifdef IN_GLIBCPP_V3
-/* Don't include <ctype.h>, to prevent additional unresolved symbols
- from being dragged into the C++ runtime library. */
-#define IS_DIGIT(CHAR) ((CHAR) >= '0' && (CHAR) <= '9')
-#define IS_ALPHA(CHAR) \
- (((CHAR) >= 'a' && (CHAR) <= 'z') \
- || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
+#define CP_STATIC_IF_GLIBCPP_V3 static
-/* The prefix prepended by GCC to an identifier represnting the
- anonymous namespace. */
-#define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
+#define cplus_demangle_fill_name d_fill_name
+static int
+d_fill_name PARAMS ((struct demangle_component *, const char *, int));
+
+#define cplus_demangle_fill_extended_operator d_fill_extended_operator
+static int
+d_fill_extended_operator PARAMS ((struct demangle_component *, int,
+ struct demangle_component *));
+
+#define cplus_demangle_fill_ctor d_fill_ctor
+static int
+d_fill_ctor PARAMS ((struct demangle_component *, enum gnu_v3_ctor_kinds,
+ struct demangle_component *));
-/* Character(s) to use for namespace separation in demangled output */
-#define NAMESPACE_SEPARATOR (dm->style == DMGL_JAVA ? "." : "::")
+#define cplus_demangle_fill_dtor d_fill_dtor
+static int
+d_fill_dtor PARAMS ((struct demangle_component *, enum gnu_v3_dtor_kinds,
+ struct demangle_component *));
-/* If flag_verbose is zero, some simplifications will be made to the
- output to make it easier to read and supress details that are
- generally not of interest to the average C++ programmer.
- Otherwise, the demangled representation will attempt to convey as
- much information as the mangled form. */
-static int flag_verbose;
+#define cplus_demangle_mangled_name d_mangled_name
+static struct demangle_component *
+d_mangled_name PARAMS ((struct d_info *, int));
-/* If flag_strict is non-zero, demangle strictly according to the
- specification -- don't demangle special g++ manglings. */
-static int flag_strict;
+#define cplus_demangle_type d_type
+static struct demangle_component *
+d_type PARAMS ((struct d_info *));
-/* String_list_t is an extended form of dyn_string_t which provides a
- link field and a caret position for additions to the string. A
- string_list_t may safely be cast to and used as a dyn_string_t. */
+#define cplus_demangle_print d_print
+static char *
+d_print PARAMS ((int, const struct demangle_component *, int, size_t *));
-struct string_list_def
-{
- /* The dyn_string; must be first. */
- struct dyn_string string;
+#define cplus_demangle_init_info d_init_info
+static void
+d_init_info PARAMS ((const char *, int, size_t, struct d_info *));
- /* The position at which additional text is added to this string
- (using the result_add* macros). This value is an offset from the
- end of the string, not the beginning (and should be
- non-positive). */
- int caret_position;
+#else /* ! defined(IN_GLIBCPP_V3) */
+#define CP_STATIC_IF_GLIBCPP_V3
+#endif /* ! defined(IN_GLIBCPP_V3) */
- /* The next string in the list. */
- struct string_list_def *next;
-};
+/* See if the compiler supports dynamic arrays. */
-typedef struct string_list_def *string_list_t;
+#ifdef __GNUC__
+#define CP_DYNAMIC_ARRAYS
+#else
+#ifdef __STDC__
+#ifdef __STDC_VERSION__
+#if __STDC_VERSION__ >= 199901L
+#define CP_DYNAMIC_ARRAYS
+#endif /* __STDC__VERSION >= 199901L */
+#endif /* defined (__STDC_VERSION__) */
+#endif /* defined (__STDC__) */
+#endif /* ! defined (__GNUC__) */
+
+/* We avoid pulling in the ctype tables, to prevent pulling in
+ additional unresolved symbols when this code is used in a library.
+ FIXME: Is this really a valid reason? This comes from the original
+ V3 demangler code.
+
+ As of this writing this file has the following undefined references
+ when compiled with -DIN_GLIBCPP_V3: malloc, realloc, free, memcpy,
+ strcpy, strcat, strlen. */
+
+#define IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
+#define IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z')
+#define IS_LOWER(c) ((c) >= 'a' && (c) <= 'z')
+
+/* The prefix prepended by GCC to an identifier represnting the
+ anonymous namespace. */
+#define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
+#define ANONYMOUS_NAMESPACE_PREFIX_LEN \
+ (sizeof (ANONYMOUS_NAMESPACE_PREFIX) - 1)
-/* Data structure representing a potential substitution. */
+/* Information we keep for the standard substitutions. */
-struct substitution_def
+struct d_standard_sub_info
{
- /* The demangled text of the substitution. */
- dyn_string_t text;
+ /* The code for this substitution. */
+ char code;
+ /* The simple string it expands to. */
+ const char *simple_expansion;
+ /* The length of the simple expansion. */
+ int simple_len;
+ /* The results of a full, verbose, expansion. This is used when
+ qualifying a constructor/destructor, or when in verbose mode. */
+ const char *full_expansion;
+ /* The length of the full expansion. */
+ int full_len;
+ /* What to set the last_name field of d_info to; NULL if we should
+ not set it. This is only relevant when qualifying a
+ constructor/destructor. */
+ const char *set_last_name;
+ /* The length of set_last_name. */
+ int set_last_name_len;
+};
+
+/* Accessors for subtrees of struct demangle_component. */
+
+#define d_left(dc) ((dc)->u.s_binary.left)
+#define d_right(dc) ((dc)->u.s_binary.right)
- /* Whether this substitution represents a template item. */
- int template_p : 1;
+/* A list of templates. This is used while printing. */
+
+struct d_print_template
+{
+ /* Next template on the list. */
+ struct d_print_template *next;
+ /* This template. */
+ const struct demangle_component *template;
};
-/* Data structure representing a template argument list. */
+/* A list of type modifiers. This is used while printing. */
-struct template_arg_list_def
+struct d_print_mod
{
- /* The next (lower) template argument list in the stack of currently
- active template arguments. */
- struct template_arg_list_def *next;
+ /* Next modifier on the list. These are in the reverse of the order
+ in which they appeared in the mangled string. */
+ struct d_print_mod *next;
+ /* The modifier. */
+ const struct demangle_component *mod;
+ /* Whether this modifier was printed. */
+ int printed;
+ /* The list of templates which applies to this modifier. */
+ struct d_print_template *templates;
+};
- /* The first element in the list of template arguments in
- left-to-right order. */
- string_list_t first_argument;
+/* We use this structure to hold information during printing. */
- /* The last element in the arguments lists. */
- string_list_t last_argument;
+struct d_print_info
+{
+ /* The options passed to the demangler. */
+ int options;
+ /* Buffer holding the result. */
+ char *buf;
+ /* Current length of data in buffer. */
+ size_t len;
+ /* Allocated size of buffer. */
+ size_t alc;
+ /* The current list of templates, if any. */
+ struct d_print_template *templates;
+ /* The current list of modifiers (e.g., pointer, reference, etc.),
+ if any. */
+ struct d_print_mod *modifiers;
+ /* Set to 1 if we had a memory allocation failure. */
+ int allocation_failure;
};
-typedef struct template_arg_list_def *template_arg_list_t;
+#define d_print_saw_error(dpi) ((dpi)->buf == NULL)
-/* Data structure to maintain the state of the current demangling. */
+#define d_append_char(dpi, c) \
+ do \
+ { \
+ if ((dpi)->buf != NULL && (dpi)->len < (dpi)->alc) \
+ (dpi)->buf[(dpi)->len++] = (c); \
+ else \
+ d_print_append_char ((dpi), (c)); \
+ } \
+ while (0)
-struct demangling_def
-{
- /* The full mangled name being mangled. */
- const char *name;
+#define d_append_buffer(dpi, s, l) \
+ do \
+ { \
+ if ((dpi)->buf != NULL && (dpi)->len + (l) <= (dpi)->alc) \
+ { \
+ memcpy ((dpi)->buf + (dpi)->len, (s), (l)); \
+ (dpi)->len += l; \
+ } \
+ else \
+ d_print_append_buffer ((dpi), (s), (l)); \
+ } \
+ while (0)
- /* Pointer into name at the current position. */
- const char *next;
+#define d_append_string_constant(dpi, s) \
+ d_append_buffer (dpi, (s), sizeof (s) - 1)
- /* Stack for strings containing demangled result generated so far.
- Text is emitted to the topmost (first) string. */
- string_list_t result;
+#define d_last_char(dpi) \
+ ((dpi)->buf == NULL || (dpi)->len == 0 ? '\0' : (dpi)->buf[(dpi)->len - 1])
- /* The number of presently available substitutions. */
- int num_substitutions;
+#ifdef CP_DEMANGLE_DEBUG
+static void
+d_dump PARAMS ((struct demangle_component *, int));
+#endif
- /* The allocated size of the substitutions array. */
- int substitutions_allocated;
+static struct demangle_component *
+d_make_empty PARAMS ((struct d_info *));
- /* An array of available substitutions. The number of elements in
- the array is given by num_substitions, and the allocated array
- size in substitutions_size.
+static struct demangle_component *
+d_make_comp PARAMS ((struct d_info *, enum demangle_component_type,
+ struct demangle_component *,
+ struct demangle_component *));
- The most recent substition is at the end, so
+static struct demangle_component *
+d_make_name PARAMS ((struct d_info *, const char *, int));
- - `S_' corresponds to substititutions[num_substitutions - 1]
- - `S0_' corresponds to substititutions[num_substitutions - 2]
+static struct demangle_component *
+d_make_builtin_type PARAMS ((struct d_info *,
+ const struct demangle_builtin_type_info *));
- etc. */
- struct substitution_def *substitutions;
+static struct demangle_component *
+d_make_operator PARAMS ((struct d_info *,
+ const struct demangle_operator_info *));
- /* The stack of template argument lists. */
- template_arg_list_t template_arg_lists;
+static struct demangle_component *
+d_make_extended_operator PARAMS ((struct d_info *, int,
+ struct demangle_component *));
- /* The most recently demangled source-name. */
- dyn_string_t last_source_name;
-
- /* Language style to use for demangled output. */
- int style;
+static struct demangle_component *
+d_make_ctor PARAMS ((struct d_info *, enum gnu_v3_ctor_kinds,
+ struct demangle_component *));
- /* Set to non-zero iff this name is a constructor. The actual value
- indicates what sort of constructor this is; see demangle.h. */
- enum gnu_v3_ctor_kinds is_constructor;
+static struct demangle_component *
+d_make_dtor PARAMS ((struct d_info *, enum gnu_v3_dtor_kinds,
+ struct demangle_component *));
- /* Set to non-zero iff this name is a destructor. The actual value
- indicates what sort of destructor this is; see demangle.h. */
- enum gnu_v3_dtor_kinds is_destructor;
+static struct demangle_component *
+d_make_template_param PARAMS ((struct d_info *, long));
-};
+static struct demangle_component *
+d_make_sub PARAMS ((struct d_info *, const char *, int));
-typedef struct demangling_def *demangling_t;
-
-/* This type is the standard return code from most functions. Values
- other than STATUS_OK contain descriptive messages. */
-typedef const char *status_t;
-
-/* Special values that can be used as a status_t. */
-#define STATUS_OK NULL
-#define STATUS_ERROR "Error."
-#define STATUS_UNIMPLEMENTED "Unimplemented."
-#define STATUS_INTERNAL_ERROR "Internal error."
-
-/* This status code indicates a failure in malloc or realloc. */
-static const char *const status_allocation_failed = "Allocation failed.";
-#define STATUS_ALLOCATION_FAILED status_allocation_failed
-
-/* Non-zero if STATUS indicates that no error has occurred. */
-#define STATUS_NO_ERROR(STATUS) ((STATUS) == STATUS_OK)
-
-/* Evaluate EXPR, which must produce a status_t. If the status code
- indicates an error, return from the current function with that
- status code. */
-#define RETURN_IF_ERROR(EXPR) \
- do \
- { \
- status_t s = EXPR; \
- if (!STATUS_NO_ERROR (s)) \
- return s; \
- } \
- while (0)
+static int
+has_return_type PARAMS ((struct demangle_component *));
-static status_t int_to_dyn_string
- PARAMS ((int, dyn_string_t));
-static string_list_t string_list_new
- PARAMS ((int));
-static void string_list_delete
- PARAMS ((string_list_t));
-static status_t result_add_separated_char
- PARAMS ((demangling_t, int));
-static status_t result_push
- PARAMS ((demangling_t));
-static string_list_t result_pop
- PARAMS ((demangling_t));
-static int substitution_start
- PARAMS ((demangling_t));
-static status_t substitution_add
- PARAMS ((demangling_t, int, int));
-static dyn_string_t substitution_get
- PARAMS ((demangling_t, int, int *));
-#ifdef CP_DEMANGLE_DEBUG
-static void substitutions_print
- PARAMS ((demangling_t, FILE *));
-#endif
-static template_arg_list_t template_arg_list_new
- PARAMS ((void));
-static void template_arg_list_delete
- PARAMS ((template_arg_list_t));
-static void template_arg_list_add_arg
- PARAMS ((template_arg_list_t, string_list_t));
-static string_list_t template_arg_list_get_arg
- PARAMS ((template_arg_list_t, int));
-static void push_template_arg_list
- PARAMS ((demangling_t, template_arg_list_t));
-static void pop_to_template_arg_list
- PARAMS ((demangling_t, template_arg_list_t));
-#ifdef CP_DEMANGLE_DEBUG
-static void template_arg_list_print
- PARAMS ((template_arg_list_t, FILE *));
-#endif
-static template_arg_list_t current_template_arg_list
- PARAMS ((demangling_t));
-static demangling_t demangling_new
- PARAMS ((const char *, int));
-static void demangling_delete
- PARAMS ((demangling_t));
-
-/* The last character of DS. Warning: DS is evaluated twice. */
-#define dyn_string_last_char(DS) \
- (dyn_string_buf (DS)[dyn_string_length (DS) - 1])
-
-/* Append a space character (` ') to DS if it does not already end
- with one. Evaluates to 1 on success, or 0 on allocation failure. */
-#define dyn_string_append_space(DS) \
- ((dyn_string_length (DS) > 0 \
- && dyn_string_last_char (DS) != ' ') \
- ? dyn_string_append_char ((DS), ' ') \
- : 1)
-
-/* Returns the index of the current position in the mangled name. */
-#define current_position(DM) ((DM)->next - (DM)->name)
-
-/* Returns the character at the current position of the mangled name. */
-#define peek_char(DM) (*((DM)->next))
-
-/* Returns the character one past the current position of the mangled
- name. */
-#define peek_char_next(DM) \
- (peek_char (DM) == '\0' ? '\0' : (*((DM)->next + 1)))
-
-/* Returns the character at the current position, and advances the
- current position to the next character. */
-#define next_char(DM) (*((DM)->next)++)
-
-/* Returns non-zero if the current position is the end of the mangled
- name, i.e. one past the last character. */
-#define end_of_name_p(DM) (peek_char (DM) == '\0')
-
-/* Advances the current position by one character. */
-#define advance_char(DM) (++(DM)->next)
-
-/* Returns the string containing the current demangled result. */
-#define result_string(DM) (&(DM)->result->string)
-
-/* Returns the position at which new text is inserted into the
- demangled result. */
-#define result_caret_pos(DM) \
- (result_length (DM) + \
- ((string_list_t) result_string (DM))->caret_position)
-
-/* Adds a dyn_string_t to the demangled result. */
-#define result_add_string(DM, STRING) \
- (dyn_string_insert (&(DM)->result->string, \
- result_caret_pos (DM), (STRING)) \
- ? STATUS_OK : STATUS_ALLOCATION_FAILED)
-
-/* Adds NUL-terminated string CSTR to the demangled result. */
-#define result_add(DM, CSTR) \
- (dyn_string_insert_cstr (&(DM)->result->string, \
- result_caret_pos (DM), (CSTR)) \
- ? STATUS_OK : STATUS_ALLOCATION_FAILED)
-
-/* Adds character CHAR to the demangled result. */
-#define result_add_char(DM, CHAR) \
- (dyn_string_insert_char (&(DM)->result->string, \
- result_caret_pos (DM), (CHAR)) \
- ? STATUS_OK : STATUS_ALLOCATION_FAILED)
-
-/* Inserts a dyn_string_t to the demangled result at position POS. */
-#define result_insert_string(DM, POS, STRING) \
- (dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \
- ? STATUS_OK : STATUS_ALLOCATION_FAILED)
-
-/* Inserts NUL-terminated string CSTR to the demangled result at
- position POS. */
-#define result_insert(DM, POS, CSTR) \
- (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \
- ? STATUS_OK : STATUS_ALLOCATION_FAILED)
-
-/* Inserts character CHAR to the demangled result at position POS. */
-#define result_insert_char(DM, POS, CHAR) \
- (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \
- ? STATUS_OK : STATUS_ALLOCATION_FAILED)
-
-/* The length of the current demangled result. */
-#define result_length(DM) \
- dyn_string_length (&(DM)->result->string)
-
-/* Appends a (less-than, greater-than) character to the result in DM
- to (open, close) a template argument or parameter list. Appends a
- space first if necessary to prevent spurious elision of angle
- brackets with the previous character. */
-#define result_open_template_list(DM) result_add_separated_char(DM, '<')
-#define result_close_template_list(DM) result_add_separated_char(DM, '>')
-
-/* Appends a base 10 representation of VALUE to DS. STATUS_OK on
- success. On failure, deletes DS and returns an error code. */
-
-static status_t
-int_to_dyn_string (value, ds)
- int value;
- dyn_string_t ds;
-{
- int i;
- int mask = 1;
+static int
+is_ctor_dtor_or_conversion PARAMS ((struct demangle_component *));
- /* Handle zero up front. */
- if (value == 0)
- {
- if (!dyn_string_append_char (ds, '0'))
- return STATUS_ALLOCATION_FAILED;
- return STATUS_OK;
- }
+static struct demangle_component *
+d_encoding PARAMS ((struct d_info *, int));
- /* For negative numbers, emit a minus sign. */
- if (value < 0)
- {
- if (!dyn_string_append_char (ds, '-'))
- return STATUS_ALLOCATION_FAILED;
- value = -value;
- }
-
- /* Find the power of 10 of the first digit. */
- i = value;
- while (i > 9)
- {
- mask *= 10;
- i /= 10;
- }
+static struct demangle_component *
+d_name PARAMS ((struct d_info *));
- /* Write the digits. */
- while (mask > 0)
- {
- int digit = value / mask;
+static struct demangle_component *
+d_nested_name PARAMS ((struct d_info *));
- if (!dyn_string_append_char (ds, '0' + digit))
- return STATUS_ALLOCATION_FAILED;
+static struct demangle_component *
+d_prefix PARAMS ((struct d_info *));
- value -= digit * mask;
- mask /= 10;
- }
+static struct demangle_component *
+d_unqualified_name PARAMS ((struct d_info *));
- return STATUS_OK;
-}
+static struct demangle_component *
+d_source_name PARAMS ((struct d_info *));
-/* Creates a new string list node. The contents of the string are
- empty, but the initial buffer allocation is LENGTH. The string
- list node should be deleted with string_list_delete. Returns NULL
- if allocation fails. */
+static long
+d_number PARAMS ((struct d_info *));
-static string_list_t
-string_list_new (length)
- int length;
-{
- string_list_t s = (string_list_t) malloc (sizeof (struct string_list_def));
- s->caret_position = 0;
- if (s == NULL)
- return NULL;
- if (!dyn_string_init ((dyn_string_t) s, length))
- return NULL;
- return s;
-}
+static struct demangle_component *
+d_identifier PARAMS ((struct d_info *, int));
-/* Deletes the entire string list starting at NODE. */
+static struct demangle_component *
+d_operator_name PARAMS ((struct d_info *));
-static void
-string_list_delete (node)
- string_list_t node;
-{
- while (node != NULL)
- {
- string_list_t next = node->next;
- dyn_string_delete ((dyn_string_t) node);
- node = next;
- }
-}
+static struct demangle_component *
+d_special_name PARAMS ((struct d_info *));
-/* Appends CHARACTER to the demangled result. If the current trailing
- character of the result is CHARACTER, a space is inserted first. */
+static int
+d_call_offset PARAMS ((struct d_info *, int));
-static status_t
-result_add_separated_char (dm, character)
- demangling_t dm;
- int character;
-{
- char *result = dyn_string_buf (result_string (dm));
- int caret_pos = result_caret_pos (dm);
+static struct demangle_component *
+d_ctor_dtor_name PARAMS ((struct d_info *));
- /* Add a space if the last character is already the character we
- want to add. */
- if (caret_pos > 0 && result[caret_pos - 1] == character)
- RETURN_IF_ERROR (result_add_char (dm, ' '));
- /* Add the character. */
- RETURN_IF_ERROR (result_add_char (dm, character));
+static struct demangle_component **
+d_cv_qualifiers PARAMS ((struct d_info *, struct demangle_component **, int));
- return STATUS_OK;
-}
+static struct demangle_component *
+d_function_type PARAMS ((struct d_info *));
-/* Allocates and pushes a new string onto the demangled results stack
- for DM. Subsequent demangling with DM will emit to the new string.
- Returns STATUS_OK on success, STATUS_ALLOCATION_FAILED on
- allocation failure. */
+static struct demangle_component *
+d_bare_function_type PARAMS ((struct d_info *, int));
-static status_t
-result_push (dm)
- demangling_t dm;
-{
- string_list_t new_string = string_list_new (0);
- if (new_string == NULL)
- /* Allocation failed. */
- return STATUS_ALLOCATION_FAILED;
-
- /* Link the new string to the front of the list of result strings. */
- new_string->next = (string_list_t) dm->result;
- dm->result = new_string;
- return STATUS_OK;
-}
+static struct demangle_component *
+d_class_enum_type PARAMS ((struct d_info *));
-/* Removes and returns the topmost element on the demangled results
- stack for DM. The caller assumes ownership for the returned
- string. */
+static struct demangle_component *
+d_array_type PARAMS ((struct d_info *));
-static string_list_t
-result_pop (dm)
- demangling_t dm;
-{
- string_list_t top = dm->result;
- dm->result = top->next;
- return top;
-}
+static struct demangle_component *
+d_pointer_to_member_type PARAMS ((struct d_info *));
-/* Returns the current value of the caret for the result string. The
- value is an offet from the end of the result string. */
+static struct demangle_component *
+d_template_param PARAMS ((struct d_info *));
-static int
-result_get_caret (dm)
- demangling_t dm;
-{
- return ((string_list_t) result_string (dm))->caret_position;
-}
+static struct demangle_component *
+d_template_args PARAMS ((struct d_info *));
-/* Sets the value of the caret for the result string, counted as an
- offet from the end of the result string. */
+static struct demangle_component *
+d_template_arg PARAMS ((struct d_info *));
-static void
-result_set_caret (dm, position)
- demangling_t dm;
- int position;
-{
- ((string_list_t) result_string (dm))->caret_position = position;
-}
+static struct demangle_component *
+d_expression PARAMS ((struct d_info *));
-/* Shifts the position of the next addition to the result by
- POSITION_OFFSET. A negative value shifts the caret to the left. */
+static struct demangle_component *
+d_expr_primary PARAMS ((struct d_info *));
-static void
-result_shift_caret (dm, position_offset)
- demangling_t dm;
- int position_offset;
-{
- ((string_list_t) result_string (dm))->caret_position += position_offset;
-}
+static struct demangle_component *
+d_local_name PARAMS ((struct d_info *));
-/* Returns non-zero if the character that comes right before the place
- where text will be added to the result is a space. In this case,
- the caller should supress adding another space. */
+static int
+d_discriminator PARAMS ((struct d_info *));
static int
-result_previous_char_is_space (dm)
- demangling_t dm;
-{
- char *result = dyn_string_buf (result_string (dm));
- int pos = result_caret_pos (dm);
- return pos > 0 && result[pos - 1] == ' ';
-}
+d_add_substitution PARAMS ((struct d_info *, struct demangle_component *));
-/* Returns the start position of a fragment of the demangled result
- that will be a substitution candidate. Should be called at the
- start of productions that can add substitutions. */
+static struct demangle_component *
+d_substitution PARAMS ((struct d_info *, int));
-static int
-substitution_start (dm)
- demangling_t dm;
-{
- return result_caret_pos (dm);
-}
+static void
+d_print_resize PARAMS ((struct d_print_info *, size_t));
-/* Adds the suffix of the current demangled result of DM starting at
- START_POSITION as a potential substitution. If TEMPLATE_P is
- non-zero, this potential substitution is a template-id. */
+static void
+d_print_append_char PARAMS ((struct d_print_info *, int));
-static status_t
-substitution_add (dm, start_position, template_p)
- demangling_t dm;
- int start_position;
- int template_p;
-{
- dyn_string_t result = result_string (dm);
- dyn_string_t substitution = dyn_string_new (0);
- int i;
+static void
+d_print_append_buffer PARAMS ((struct d_print_info *, const char *, size_t));
- if (substitution == NULL)
- return STATUS_ALLOCATION_FAILED;
+static void
+d_print_error PARAMS ((struct d_print_info *));
- /* Extract the substring of the current demangling result that
- represents the subsitution candidate. */
- if (!dyn_string_substring (substitution,
- result, start_position, result_caret_pos (dm)))
- {
- dyn_string_delete (substitution);
- return STATUS_ALLOCATION_FAILED;
- }
+static void
+d_print_comp PARAMS ((struct d_print_info *,
+ const struct demangle_component *));
- /* If there's no room for the new entry, grow the array. */
- if (dm->substitutions_allocated == dm->num_substitutions)
- {
- size_t new_array_size;
- if (dm->substitutions_allocated > 0)
- dm->substitutions_allocated *= 2;
- else
- dm->substitutions_allocated = 2;
- new_array_size =
- sizeof (struct substitution_def) * dm->substitutions_allocated;
-
- dm->substitutions = (struct substitution_def *)
- realloc (dm->substitutions, new_array_size);
- if (dm->substitutions == NULL)
- /* Realloc failed. */
- {
- dyn_string_delete (substitution);
- return STATUS_ALLOCATION_FAILED;
- }
- }
+static void
+d_print_java_identifier PARAMS ((struct d_print_info *, const char *, int));
- /* Add the substitution to the array. */
- i = dm->num_substitutions++;
- dm->substitutions[i].text = substitution;
- dm->substitutions[i].template_p = template_p;
+static void
+d_print_mod_list PARAMS ((struct d_print_info *, struct d_print_mod *, int));
-#ifdef CP_DEMANGLE_DEBUG
- substitutions_print (dm, stderr);
-#endif
+static void
+d_print_mod PARAMS ((struct d_print_info *,
+ const struct demangle_component *));
- return STATUS_OK;
-}
+static void
+d_print_function_type PARAMS ((struct d_print_info *,
+ const struct demangle_component *,
+ struct d_print_mod *));
-/* Returns the Nth-most-recent substitution. Sets *TEMPLATE_P to
- non-zero if the substitution is a template-id, zero otherwise.
- N is numbered from zero. DM retains ownership of the returned
- string. If N is negative, or equal to or greater than the current
- number of substitution candidates, returns NULL. */
-
-static dyn_string_t
-substitution_get (dm, n, template_p)
- demangling_t dm;
- int n;
- int *template_p;
-{
- struct substitution_def *sub;
+static void
+d_print_array_type PARAMS ((struct d_print_info *,
+ const struct demangle_component *,
+ struct d_print_mod *));
- /* Make sure N is in the valid range. */
- if (n < 0 || n >= dm->num_substitutions)
- return NULL;
+static void
+d_print_expr_op PARAMS ((struct d_print_info *,
+ const struct demangle_component *));
- sub = &(dm->substitutions[n]);
- *template_p = sub->template_p;
- return sub->text;
-}
+static void
+d_print_cast PARAMS ((struct d_print_info *,
+ const struct demangle_component *));
+
+static char *
+d_demangle PARAMS ((const char *, int, size_t *));
#ifdef CP_DEMANGLE_DEBUG
-/* Debugging routine to print the current substitutions to FP. */
static void
-substitutions_print (dm, fp)
- demangling_t dm;
- FILE *fp;
+d_dump (dc, indent)
+ struct demangle_component *dc;
+ int indent;
{
- int seq_id;
- int num = dm->num_substitutions;
+ int i;
- fprintf (fp, "SUBSTITUTIONS:\n");
- for (seq_id = -1; seq_id < num - 1; ++seq_id)
- {
- int template_p;
- dyn_string_t text = substitution_get (dm, seq_id + 1, &template_p);
+ if (dc == NULL)
+ return;
- if (seq_id == -1)
- fprintf (fp, " S_ ");
- else
- fprintf (fp, " S%d_", seq_id);
- fprintf (fp, " %c: %s\n", template_p ? '*' : ' ', dyn_string_buf (text));
+ for (i = 0; i < indent; ++i)
+ putchar (' ');
+
+ switch (dc->type)
+ {
+ case DEMANGLE_COMPONENT_NAME:
+ printf ("name '%.*s'\n", dc->u.s_name.len, dc->u.s_name.s);
+ return;
+ case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
+ printf ("template parameter %ld\n", dc->u.s_number.number);
+ return;
+ case DEMANGLE_COMPONENT_CTOR:
+ printf ("constructor %d\n", (int) dc->u.s_ctor.kind);
+ d_dump (dc->u.s_ctor.name, indent + 2);
+ return;
+ case DEMANGLE_COMPONENT_DTOR:
+ printf ("destructor %d\n", (int) dc->u.s_dtor.kind);
+ d_dump (dc->u.s_dtor.name, indent + 2);
+ return;
+ case DEMANGLE_COMPONENT_SUB_STD:
+ printf ("standard substitution %s\n", dc->u.s_string.string);
+ return;
+ case DEMANGLE_COMPONENT_BUILTIN_TYPE:
+ printf ("builtin type %s\n", dc->u.s_builtin.type->name);
+ return;
+ case DEMANGLE_COMPONENT_OPERATOR:
+ printf ("operator %s\n", dc->u.s_operator.op->name);
+ return;
+ case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
+ printf ("extended operator with %d args\n",
+ dc->u.s_extended_operator.args);
+ d_dump (dc->u.s_extended_operator.name, indent + 2);
+ return;
+
+ case DEMANGLE_COMPONENT_QUAL_NAME:
+ printf ("qualified name\n");
+ break;
+ case DEMANGLE_COMPONENT_LOCAL_NAME:
+ printf ("local name\n");
+ break;
+ case DEMANGLE_COMPONENT_TYPED_NAME:
+ printf ("typed name\n");
+ break;
+ case DEMANGLE_COMPONENT_TEMPLATE:
+ printf ("template\n");
+ break;
+ case DEMANGLE_COMPONENT_VTABLE:
+ printf ("vtable\n");
+ break;
+ case DEMANGLE_COMPONENT_VTT:
+ printf ("VTT\n");
+ break;
+ case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
+ printf ("construction vtable\n");
+ break;
+ case DEMANGLE_COMPONENT_TYPEINFO:
+ printf ("typeinfo\n");
+ break;
+ case DEMANGLE_COMPONENT_TYPEINFO_NAME:
+ printf ("typeinfo name\n");
+ break;
+ case DEMANGLE_COMPONENT_TYPEINFO_FN:
+ printf ("typeinfo function\n");
+ break;
+ case DEMANGLE_COMPONENT_THUNK:
+ printf ("thunk\n");
+ break;
+ case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
+ printf ("virtual thunk\n");
+ break;
+ case DEMANGLE_COMPONENT_COVARIANT_THUNK:
+ printf ("covariant thunk\n");
+ break;
+ case DEMANGLE_COMPONENT_JAVA_CLASS:
+ printf ("java class\n");
+ break;
+ case DEMANGLE_COMPONENT_GUARD:
+ printf ("guard\n");
+ break;
+ case DEMANGLE_COMPONENT_REFTEMP:
+ printf ("reference temporary\n");
+ break;
+ case DEMANGLE_COMPONENT_RESTRICT:
+ printf ("restrict\n");
+ break;
+ case DEMANGLE_COMPONENT_VOLATILE:
+ printf ("volatile\n");
+ break;
+ case DEMANGLE_COMPONENT_CONST:
+ printf ("const\n");
+ break;
+ case DEMANGLE_COMPONENT_RESTRICT_THIS:
+ printf ("restrict this\n");
+ break;
+ case DEMANGLE_COMPONENT_VOLATILE_THIS:
+ printf ("volatile this\n");
+ break;
+ case DEMANGLE_COMPONENT_CONST_THIS:
+ printf ("const this\n");
+ break;
+ case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
+ printf ("vendor type qualifier\n");
+ break;
+ case DEMANGLE_COMPONENT_POINTER:
+ printf ("pointer\n");
+ break;
+ case DEMANGLE_COMPONENT_REFERENCE:
+ printf ("reference\n");
+ break;
+ case DEMANGLE_COMPONENT_COMPLEX:
+ printf ("complex\n");
+ break;
+ case DEMANGLE_COMPONENT_IMAGINARY:
+ printf ("imaginary\n");
+ break;
+ case DEMANGLE_COMPONENT_VENDOR_TYPE:
+ printf ("vendor type\n");
+ break;
+ case DEMANGLE_COMPONENT_FUNCTION_TYPE:
+ printf ("function type\n");
+ break;
+ case DEMANGLE_COMPONENT_ARRAY_TYPE:
+ printf ("array type\n");
+ break;
+ case DEMANGLE_COMPONENT_PTRMEM_TYPE:
+ printf ("pointer to member type\n");
+ break;
+ case DEMANGLE_COMPONENT_ARGLIST:
+ printf ("argument list\n");
+ break;
+ case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
+ printf ("template argument list\n");
+ break;
+ case DEMANGLE_COMPONENT_CAST:
+ printf ("cast\n");
+ break;
+ case DEMANGLE_COMPONENT_UNARY:
+ printf ("unary operator\n");
+ break;
+ case DEMANGLE_COMPONENT_BINARY:
+ printf ("binary operator\n");
+ break;
+ case DEMANGLE_COMPONENT_BINARY_ARGS:
+ printf ("binary operator arguments\n");
+ break;
+ case DEMANGLE_COMPONENT_TRINARY:
+ printf ("trinary operator\n");
+ break;
+ case DEMANGLE_COMPONENT_TRINARY_ARG1:
+ printf ("trinary operator arguments 1\n");
+ break;
+ case DEMANGLE_COMPONENT_TRINARY_ARG2:
+ printf ("trinary operator arguments 1\n");
+ break;
+ case DEMANGLE_COMPONENT_LITERAL:
+ printf ("literal\n");
+ break;
+ case DEMANGLE_COMPONENT_LITERAL_NEG:
+ printf ("negative literal\n");
+ break;
}
+
+ d_dump (d_left (dc), indent + 2);
+ d_dump (d_right (dc), indent + 2);
}
#endif /* CP_DEMANGLE_DEBUG */
-/* Creates a new template argument list. Returns NULL if allocation
- fails. */
+/* Fill in a DEMANGLE_COMPONENT_NAME. */
-static template_arg_list_t
-template_arg_list_new ()
+CP_STATIC_IF_GLIBCPP_V3
+int
+cplus_demangle_fill_name (p, s, len)
+ struct demangle_component *p;
+ const char *s;
+ int len;
{
- template_arg_list_t new_list =
- (template_arg_list_t) malloc (sizeof (struct template_arg_list_def));
- if (new_list == NULL)
- return NULL;
- /* Initialize the new list to have no arguments. */
- new_list->first_argument = NULL;
- new_list->last_argument = NULL;
- /* Return the new list. */
- return new_list;
+ if (p == NULL || s == NULL || len == 0)
+ return 0;
+ p->type = DEMANGLE_COMPONENT_NAME;
+ p->u.s_name.s = s;
+ p->u.s_name.len = len;
+ return 1;
}
-/* Deletes a template argument list and the template arguments it
- contains. */
+/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR. */
-static void
-template_arg_list_delete (list)
- template_arg_list_t list;
+CP_STATIC_IF_GLIBCPP_V3
+int
+cplus_demangle_fill_extended_operator (p, args, name)
+ struct demangle_component *p;
+ int args;
+ struct demangle_component *name;
{
- /* If there are any arguments on LIST, delete them. */
- if (list->first_argument != NULL)
- string_list_delete (list->first_argument);
- /* Delete LIST. */
- free (list);
+ if (p == NULL || args < 0 || name == NULL)
+ return 0;
+ p->type = DEMANGLE_COMPONENT_EXTENDED_OPERATOR;
+ p->u.s_extended_operator.args = args;
+ p->u.s_extended_operator.name = name;
+ return 1;
}
-/* Adds ARG to the template argument list ARG_LIST. */
+/* Fill in a DEMANGLE_COMPONENT_CTOR. */
-static void
-template_arg_list_add_arg (arg_list, arg)
- template_arg_list_t arg_list;
- string_list_t arg;
+CP_STATIC_IF_GLIBCPP_V3
+int
+cplus_demangle_fill_ctor (p, kind, name)
+ struct demangle_component *p;
+ enum gnu_v3_ctor_kinds kind;
+ struct demangle_component *name;
{
- if (arg_list->first_argument == NULL)
- /* If there were no arguments before, ARG is the first one. */
- arg_list->first_argument = arg;
- else
- /* Make ARG the last argument on the list. */
- arg_list->last_argument->next = arg;
- /* Make ARG the last on the list. */
- arg_list->last_argument = arg;
- arg->next = NULL;
+ if (p == NULL
+ || name == NULL
+ || (kind < gnu_v3_complete_object_ctor
+ && kind > gnu_v3_complete_object_allocating_ctor))
+ return 0;
+ p->type = DEMANGLE_COMPONENT_CTOR;
+ p->u.s_ctor.kind = kind;
+ p->u.s_ctor.name = name;
+ return 1;
+}
+
+/* Fill in a DEMANGLE_COMPONENT_DTOR. */
+
+CP_STATIC_IF_GLIBCPP_V3
+int
+cplus_demangle_fill_dtor (p, kind, name)
+ struct demangle_component *p;
+ enum gnu_v3_dtor_kinds kind;
+ struct demangle_component *name;
+{
+ if (p == NULL
+ || name == NULL
+ || (kind < gnu_v3_deleting_dtor
+ && kind > gnu_v3_base_object_dtor))
+ return 0;
+ p->type = DEMANGLE_COMPONENT_DTOR;
+ p->u.s_dtor.kind = kind;
+ p->u.s_dtor.name = name;
+ return 1;
+}
+
+/* Add a new component. */
+
+static struct demangle_component *
+d_make_empty (di)
+ struct d_info *di;
+{
+ struct demangle_component *p;
+
+ if (di->next_comp >= di->num_comps)
+ return NULL;
+ p = &di->comps[di->next_comp];
+ ++di->next_comp;
+ return p;
}
-/* Returns the template arugment at position INDEX in template
- argument list ARG_LIST. */
+/* Add a new generic component. */
-static string_list_t
-template_arg_list_get_arg (arg_list, index)
- template_arg_list_t arg_list;
- int index;
+static struct demangle_component *
+d_make_comp (di, type, left, right)
+ struct d_info *di;
+ enum demangle_component_type type;
+ struct demangle_component *left;
+ struct demangle_component *right;
{
- string_list_t arg = arg_list->first_argument;
- /* Scan down the list of arguments to find the one at position
- INDEX. */
- while (index--)
+ struct demangle_component *p;
+
+ /* We check for errors here. A typical error would be a NULL return
+ from a subroutine. We catch those here, and return NULL
+ upward. */
+ switch (type)
{
- arg = arg->next;
- if (arg == NULL)
- /* Ran out of arguments before INDEX hit zero. That's an
- error. */
+ /* These types require two parameters. */
+ case DEMANGLE_COMPONENT_QUAL_NAME:
+ case DEMANGLE_COMPONENT_LOCAL_NAME:
+ case DEMANGLE_COMPONENT_TYPED_NAME:
+ case DEMANGLE_COMPONENT_TEMPLATE:
+ case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
+ case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
+ case DEMANGLE_COMPONENT_PTRMEM_TYPE:
+ case DEMANGLE_COMPONENT_UNARY:
+ case DEMANGLE_COMPONENT_BINARY:
+ case DEMANGLE_COMPONENT_BINARY_ARGS:
+ case DEMANGLE_COMPONENT_TRINARY:
+ case DEMANGLE_COMPONENT_TRINARY_ARG1:
+ case DEMANGLE_COMPONENT_TRINARY_ARG2:
+ case DEMANGLE_COMPONENT_LITERAL:
+ case DEMANGLE_COMPONENT_LITERAL_NEG:
+ if (left == NULL || right == NULL)
return NULL;
+ break;
+
+ /* These types only require one parameter. */
+ case DEMANGLE_COMPONENT_VTABLE:
+ case DEMANGLE_COMPONENT_VTT:
+ case DEMANGLE_COMPONENT_TYPEINFO:
+ case DEMANGLE_COMPONENT_TYPEINFO_NAME:
+ case DEMANGLE_COMPONENT_TYPEINFO_FN:
+ case DEMANGLE_COMPONENT_THUNK:
+ case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
+ case DEMANGLE_COMPONENT_COVARIANT_THUNK:
+ case DEMANGLE_COMPONENT_JAVA_CLASS:
+ case DEMANGLE_COMPONENT_GUARD:
+ case DEMANGLE_COMPONENT_REFTEMP:
+ case DEMANGLE_COMPONENT_POINTER:
+ case DEMANGLE_COMPONENT_REFERENCE:
+ case DEMANGLE_COMPONENT_COMPLEX:
+ case DEMANGLE_COMPONENT_IMAGINARY:
+ case DEMANGLE_COMPONENT_VENDOR_TYPE:
+ case DEMANGLE_COMPONENT_ARGLIST:
+ case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
+ case DEMANGLE_COMPONENT_CAST:
+ if (left == NULL)
+ return NULL;
+ break;
+
+ /* This needs a right parameter, but the left parameter can be
+ empty. */
+ case DEMANGLE_COMPONENT_ARRAY_TYPE:
+ if (right == NULL)
+ return NULL;
+ break;
+
+ /* These are allowed to have no parameters--in some cases they
+ will be filled in later. */
+ case DEMANGLE_COMPONENT_FUNCTION_TYPE:
+ case DEMANGLE_COMPONENT_RESTRICT:
+ case DEMANGLE_COMPONENT_VOLATILE:
+ case DEMANGLE_COMPONENT_CONST:
+ case DEMANGLE_COMPONENT_RESTRICT_THIS:
+ case DEMANGLE_COMPONENT_VOLATILE_THIS:
+ case DEMANGLE_COMPONENT_CONST_THIS:
+ break;
+
+ /* Other types should not be seen here. */
+ default:
+ return NULL;
+ }
+
+ p = d_make_empty (di);
+ if (p != NULL)
+ {
+ p->type = type;
+ p->u.s_binary.left = left;
+ p->u.s_binary.right = right;
}
- /* Return the argument at position INDEX. */
- return arg;
+ return p;
}
-/* Pushes ARG_LIST onto the top of the template argument list stack. */
+/* Add a new name component. */
-static void
-push_template_arg_list (dm, arg_list)
- demangling_t dm;
- template_arg_list_t arg_list;
+static struct demangle_component *
+d_make_name (di, s, len)
+ struct d_info *di;
+ const char *s;
+ int len;
{
- arg_list->next = dm->template_arg_lists;
- dm->template_arg_lists = arg_list;
-#ifdef CP_DEMANGLE_DEBUG
- fprintf (stderr, " ** pushing template arg list\n");
- template_arg_list_print (arg_list, stderr);
-#endif
+ struct demangle_component *p;
+
+ p = d_make_empty (di);
+ if (! cplus_demangle_fill_name (p, s, len))
+ return NULL;
+ return p;
}
-/* Pops and deletes elements on the template argument list stack until
- arg_list is the topmost element. If arg_list is NULL, all elements
- are popped and deleted. */
+/* Add a new builtin type component. */
-static void
-pop_to_template_arg_list (dm, arg_list)
- demangling_t dm;
- template_arg_list_t arg_list;
+static struct demangle_component *
+d_make_builtin_type (di, type)
+ struct d_info *di;
+ const struct demangle_builtin_type_info *type;
{
- while (dm->template_arg_lists != arg_list)
+ struct demangle_component *p;
+
+ if (type == NULL)
+ return NULL;
+ p = d_make_empty (di);
+ if (p != NULL)
{
- template_arg_list_t top = dm->template_arg_lists;
- /* Disconnect the topmost element from the list. */
- dm->template_arg_lists = top->next;
- /* Delete the popped element. */
- template_arg_list_delete (top);
-#ifdef CP_DEMANGLE_DEBUG
- fprintf (stderr, " ** removing template arg list\n");
-#endif
+ p->type = DEMANGLE_COMPONENT_BUILTIN_TYPE;
+ p->u.s_builtin.type = type;
}
+ return p;
}
-#ifdef CP_DEMANGLE_DEBUG
+/* Add a new operator component. */
-/* Prints the contents of ARG_LIST to FP. */
-
-static void
-template_arg_list_print (arg_list, fp)
- template_arg_list_t arg_list;
- FILE *fp;
+static struct demangle_component *
+d_make_operator (di, op)
+ struct d_info *di;
+ const struct demangle_operator_info *op;
{
- string_list_t arg;
- int index = -1;
+ struct demangle_component *p;
- fprintf (fp, "TEMPLATE ARGUMENT LIST:\n");
- for (arg = arg_list->first_argument; arg != NULL; arg = arg->next)
+ p = d_make_empty (di);
+ if (p != NULL)
{
- if (index == -1)
- fprintf (fp, " T_ : ");
- else
- fprintf (fp, " T%d_ : ", index);
- ++index;
- fprintf (fp, "%s\n", dyn_string_buf ((dyn_string_t) arg));
+ p->type = DEMANGLE_COMPONENT_OPERATOR;
+ p->u.s_operator.op = op;
}
+ return p;
}
-#endif /* CP_DEMANGLE_DEBUG */
-
-/* Returns the topmost element on the stack of template argument
- lists. If there is no list of template arguments, returns NULL. */
+/* Add a new extended operator component. */
-static template_arg_list_t
-current_template_arg_list (dm)
- demangling_t dm;
+static struct demangle_component *
+d_make_extended_operator (di, args, name)
+ struct d_info *di;
+ int args;
+ struct demangle_component *name;
{
- return dm->template_arg_lists;
+ struct demangle_component *p;
+
+ p = d_make_empty (di);
+ if (! cplus_demangle_fill_extended_operator (p, args, name))
+ return NULL;
+ return p;
}
-/* Allocates a demangling_t object for demangling mangled NAME. A new
- result must be pushed before the returned object can be used.
- Returns NULL if allocation fails. */
+/* Add a new constructor component. */
-static demangling_t
-demangling_new (name, style)
- const char *name;
- int style;
+static struct demangle_component *
+d_make_ctor (di, kind, name)
+ struct d_info *di;
+ enum gnu_v3_ctor_kinds kind;
+ struct demangle_component *name;
{
- demangling_t dm;
- dm = (demangling_t) malloc (sizeof (struct demangling_def));
- if (dm == NULL)
- return NULL;
+ struct demangle_component *p;
- dm->name = name;
- dm->next = name;
- dm->result = NULL;
- dm->num_substitutions = 0;
- dm->substitutions_allocated = 10;
- dm->template_arg_lists = NULL;
- dm->last_source_name = dyn_string_new (0);
- if (dm->last_source_name == NULL)
+ p = d_make_empty (di);
+ if (! cplus_demangle_fill_ctor (p, kind, name))
return NULL;
- dm->substitutions = (struct substitution_def *)
- malloc (dm->substitutions_allocated * sizeof (struct substitution_def));
- if (dm->substitutions == NULL)
- {
- dyn_string_delete (dm->last_source_name);
- return NULL;
- }
- dm->style = style;
- dm->is_constructor = (enum gnu_v3_ctor_kinds) 0;
- dm->is_destructor = (enum gnu_v3_dtor_kinds) 0;
+ return p;
+}
- return dm;
+/* Add a new destructor component. */
+
+static struct demangle_component *
+d_make_dtor (di, kind, name)
+ struct d_info *di;
+ enum gnu_v3_dtor_kinds kind;
+ struct demangle_component *name;
+{
+ struct demangle_component *p;
+
+ p = d_make_empty (di);
+ if (! cplus_demangle_fill_dtor (p, kind, name))
+ return NULL;
+ return p;
}
-/* Deallocates a demangling_t object and all memory associated with
- it. */
+/* Add a new template parameter. */
-static void
-demangling_delete (dm)
- demangling_t dm;
+static struct demangle_component *
+d_make_template_param (di, i)
+ struct d_info *di;
+ long i;
{
- int i;
- template_arg_list_t arg_list = dm->template_arg_lists;
+ struct demangle_component *p;
- /* Delete the stack of template argument lists. */
- while (arg_list != NULL)
+ p = d_make_empty (di);
+ if (p != NULL)
{
- template_arg_list_t next = arg_list->next;
- template_arg_list_delete (arg_list);
- arg_list = next;
+ p->type = DEMANGLE_COMPONENT_TEMPLATE_PARAM;
+ p->u.s_number.number = i;
}
- /* Delete the list of substitutions. */
- for (i = dm->num_substitutions; --i >= 0; )
- dyn_string_delete (dm->substitutions[i].text);
- free (dm->substitutions);
- /* Delete the demangled result. */
- string_list_delete (dm->result);
- /* Delete the stored identifier name. */
- dyn_string_delete (dm->last_source_name);
- /* Delete the context object itself. */
- free (dm);
+ return p;
}
-/* These functions demangle an alternative of the corresponding
- production in the mangling spec. The first argument of each is a
- demangling context structure for the current demangling
- operation. Most emit demangled text directly to the topmost result
- string on the result string stack in the demangling context
- structure. */
-
-static status_t demangle_char
- PARAMS ((demangling_t, int));
-static status_t demangle_mangled_name
- PARAMS ((demangling_t));
-static status_t demangle_encoding
- PARAMS ((demangling_t));
-static status_t demangle_name
- PARAMS ((demangling_t, int *));
-static status_t demangle_nested_name
- PARAMS ((demangling_t, int *));
-static status_t demangle_prefix
- PARAMS ((demangling_t, int *));
-static status_t demangle_unqualified_name
- PARAMS ((demangling_t, int *));
-static status_t demangle_source_name
- PARAMS ((demangling_t));
-static status_t demangle_number
- PARAMS ((demangling_t, int *, int, int));
-static status_t demangle_number_literally
- PARAMS ((demangling_t, dyn_string_t, int, int));
-static status_t demangle_identifier
- PARAMS ((demangling_t, int, dyn_string_t));
-static status_t demangle_operator_name
- PARAMS ((demangling_t, int, int *, int *));
-static status_t demangle_nv_offset
- PARAMS ((demangling_t));
-static status_t demangle_v_offset
- PARAMS ((demangling_t));
-static status_t demangle_call_offset
- PARAMS ((demangling_t));
-static status_t demangle_special_name
- PARAMS ((demangling_t));
-static status_t demangle_ctor_dtor_name
- PARAMS ((demangling_t));
-static status_t demangle_type_ptr
- PARAMS ((demangling_t, int *, int));
-static status_t demangle_type
- PARAMS ((demangling_t));
-static status_t demangle_CV_qualifiers
- PARAMS ((demangling_t, dyn_string_t));
-static status_t demangle_builtin_type
- PARAMS ((demangling_t));
-static status_t demangle_function_type
- PARAMS ((demangling_t, int *));
-static status_t demangle_bare_function_type
- PARAMS ((demangling_t, int *));
-static status_t demangle_class_enum_type
- PARAMS ((demangling_t, int *));
-static status_t demangle_array_type
- PARAMS ((demangling_t, int *));
-static status_t demangle_template_param
- PARAMS ((demangling_t));
-static status_t demangle_template_args
- PARAMS ((demangling_t));
-static status_t demangle_literal
- PARAMS ((demangling_t));
-static status_t demangle_template_arg
- PARAMS ((demangling_t));
-static status_t demangle_expression
- PARAMS ((demangling_t));
-static status_t demangle_scope_expression
- PARAMS ((demangling_t));
-static status_t demangle_expr_primary
- PARAMS ((demangling_t));
-static status_t demangle_substitution
- PARAMS ((demangling_t, int *));
-static status_t demangle_local_name
- PARAMS ((demangling_t));
-static status_t demangle_discriminator
- PARAMS ((demangling_t, int));
-static status_t cp_demangle
- PARAMS ((const char *, dyn_string_t, int));
-static status_t cp_demangle_type
- PARAMS ((const char*, dyn_string_t));
-
-/* When passed to demangle_bare_function_type, indicates that the
- function's return type is not encoded before its parameter types. */
-#define BFT_NO_RETURN_TYPE NULL
-
-/* Check that the next character is C. If so, consume it. If not,
- return an error. */
-
-static status_t
-demangle_char (dm, c)
- demangling_t dm;
- int c;
+/* Add a new standard substitution component. */
+
+static struct demangle_component *
+d_make_sub (di, name, len)
+ struct d_info *di;
+ const char *name;
+ int len;
{
- static char *error_message = NULL;
+ struct demangle_component *p;
- if (peek_char (dm) == c)
- {
- advance_char (dm);
- return STATUS_OK;
- }
- else
+ p = d_make_empty (di);
+ if (p != NULL)
{
- if (error_message == NULL)
- error_message = (char *) strdup ("Expected ?");
- error_message[9] = c;
- return error_message;
+ p->type = DEMANGLE_COMPONENT_SUB_STD;
+ p->u.s_string.string = name;
+ p->u.s_string.len = len;
}
+ return p;
}
-/* Demangles and emits a <mangled-name>.
+/* <mangled-name> ::= _Z <encoding>
- <mangled-name> ::= _Z <encoding> */
+ TOP_LEVEL is non-zero when called at the top level. */
-static status_t
-demangle_mangled_name (dm)
- demangling_t dm;
+CP_STATIC_IF_GLIBCPP_V3
+struct demangle_component *
+cplus_demangle_mangled_name (di, top_level)
+ struct d_info *di;
+ int top_level;
{
- DEMANGLE_TRACE ("mangled-name", dm);
- RETURN_IF_ERROR (demangle_char (dm, '_'));
- RETURN_IF_ERROR (demangle_char (dm, 'Z'));
- RETURN_IF_ERROR (demangle_encoding (dm));
- return STATUS_OK;
+ if (d_next_char (di) != '_')
+ return NULL;
+ if (d_next_char (di) != 'Z')
+ return NULL;
+ return d_encoding (di, top_level);
}
-/* Demangles and emits an <encoding>.
+/* Return whether a function should have a return type. The argument
+ is the function name, which may be qualified in various ways. The
+ rules are that template functions have return types with some
+ exceptions, function types which are not part of a function name
+ mangling have return types with some exceptions, and non-template
+ function names do not have return types. The exceptions are that
+ constructors, destructors, and conversion operators do not have
+ return types. */
+
+static int
+has_return_type (dc)
+ struct demangle_component *dc;
+{
+ if (dc == NULL)
+ return 0;
+ switch (dc->type)
+ {
+ default:
+ return 0;
+ case DEMANGLE_COMPONENT_TEMPLATE:
+ return ! is_ctor_dtor_or_conversion (d_left (dc));
+ case DEMANGLE_COMPONENT_RESTRICT_THIS:
+ case DEMANGLE_COMPONENT_VOLATILE_THIS:
+ case DEMANGLE_COMPONENT_CONST_THIS:
+ return has_return_type (d_left (dc));
+ }
+}
- <encoding> ::= <function name> <bare-function-type>
- ::= <data name>
- ::= <special-name> */
+/* Return whether a name is a constructor, a destructor, or a
+ conversion operator. */
-static status_t
-demangle_encoding (dm)
- demangling_t dm;
+static int
+is_ctor_dtor_or_conversion (dc)
+ struct demangle_component *dc;
{
- int encode_return_type;
- int start_position;
- template_arg_list_t old_arg_list = current_template_arg_list (dm);
- char peek = peek_char (dm);
+ if (dc == NULL)
+ return 0;
+ switch (dc->type)
+ {
+ default:
+ return 0;
+ case DEMANGLE_COMPONENT_QUAL_NAME:
+ case DEMANGLE_COMPONENT_LOCAL_NAME:
+ return is_ctor_dtor_or_conversion (d_right (dc));
+ case DEMANGLE_COMPONENT_CTOR:
+ case DEMANGLE_COMPONENT_DTOR:
+ case DEMANGLE_COMPONENT_CAST:
+ return 1;
+ }
+}
+
+/* <encoding> ::= <(function) name> <bare-function-type>
+ ::= <(data) name>
+ ::= <special-name>
- DEMANGLE_TRACE ("encoding", dm);
-
- /* Remember where the name starts. If it turns out to be a template
- function, we'll have to insert the return type here. */
- start_position = result_caret_pos (dm);
+ TOP_LEVEL is non-zero when called at the top level, in which case
+ if DMGL_PARAMS is not set we do not demangle the function
+ parameters. We only set this at the top level, because otherwise
+ we would not correctly demangle names in local scopes. */
+
+static struct demangle_component *
+d_encoding (di, top_level)
+ struct d_info *di;
+ int top_level;
+{
+ char peek = d_peek_char (di);
if (peek == 'G' || peek == 'T')
- RETURN_IF_ERROR (demangle_special_name (dm));
+ return d_special_name (di);
else
{
- /* Now demangle the name. */
- RETURN_IF_ERROR (demangle_name (dm, &encode_return_type));
+ struct demangle_component *dc;
- /* If there's anything left, the name was a function name, with
- maybe its return type, and its parameter types, following. */
- if (!end_of_name_p (dm)
- && peek_char (dm) != 'E')
+ dc = d_name (di);
+
+ if (dc != NULL && top_level && (di->options & DMGL_PARAMS) == 0)
{
- if (encode_return_type)
- /* Template functions have their return type encoded. The
- return type should be inserted at start_position. */
- RETURN_IF_ERROR
- (demangle_bare_function_type (dm, &start_position));
- else
- /* Non-template functions don't have their return type
- encoded. */
- RETURN_IF_ERROR
- (demangle_bare_function_type (dm, BFT_NO_RETURN_TYPE));
- }
- }
+ /* Strip off any initial CV-qualifiers, as they really apply
+ to the `this' parameter, and they were not output by the
+ v2 demangler without DMGL_PARAMS. */
+ while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
+ || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
+ || dc->type == DEMANGLE_COMPONENT_CONST_THIS)
+ dc = d_left (dc);
+
+ /* If the top level is a DEMANGLE_COMPONENT_LOCAL_NAME, then
+ there may be CV-qualifiers on its right argument which
+ really apply here; this happens when parsing a class
+ which is local to a function. */
+ if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME)
+ {
+ struct demangle_component *dcr;
+
+ dcr = d_right (dc);
+ while (dcr->type == DEMANGLE_COMPONENT_RESTRICT_THIS
+ || dcr->type == DEMANGLE_COMPONENT_VOLATILE_THIS
+ || dcr->type == DEMANGLE_COMPONENT_CONST_THIS)
+ dcr = d_left (dcr);
+ dc->u.s_binary.right = dcr;
+ }
- /* Pop off template argument lists that were built during the
- mangling of this name, to restore the old template context. */
- pop_to_template_arg_list (dm, old_arg_list);
+ return dc;
+ }
- return STATUS_OK;
+ peek = d_peek_char (di);
+ if (peek == '\0' || peek == 'E')
+ return dc;
+ return d_make_comp (di, DEMANGLE_COMPONENT_TYPED_NAME, dc,
+ d_bare_function_type (di, has_return_type (dc)));
+ }
}
-/* Demangles and emits a <name>.
+/* <name> ::= <nested-name>
+ ::= <unscoped-name>
+ ::= <unscoped-template-name> <template-args>
+ ::= <local-name>
- <name> ::= <unscoped-name>
- ::= <unscoped-template-name> <template-args>
- ::= <nested-name>
- ::= <local-name>
+ <unscoped-name> ::= <unqualified-name>
+ ::= St <unqualified-name>
- <unscoped-name> ::= <unqualified-name>
- ::= St <unqualified-name> # ::std::
-
- <unscoped-template-name>
- ::= <unscoped-name>
- ::= <substitution> */
+ <unscoped-template-name> ::= <unscoped-name>
+ ::= <substitution>
+*/
-static status_t
-demangle_name (dm, encode_return_type)
- demangling_t dm;
- int *encode_return_type;
+static struct demangle_component *
+d_name (di)
+ struct d_info *di;
{
- int start = substitution_start (dm);
- char peek = peek_char (dm);
- int is_std_substitution = 0;
-
- /* Generally, the return type is encoded if the function is a
- template-id, and suppressed otherwise. There are a few cases,
- though, in which the return type is not encoded even for a
- templated function. In these cases, this flag is set. */
- int suppress_return_type = 0;
-
- DEMANGLE_TRACE ("name", dm);
+ char peek = d_peek_char (di);
+ struct demangle_component *dc;
switch (peek)
{
case 'N':
- /* This is a <nested-name>. */
- RETURN_IF_ERROR (demangle_nested_name (dm, encode_return_type));
- break;
+ return d_nested_name (di);
case 'Z':
- RETURN_IF_ERROR (demangle_local_name (dm));
- *encode_return_type = 0;
- break;
+ return d_local_name (di);
case 'S':
- /* The `St' substitution allows a name nested in std:: to appear
- without being enclosed in a nested name. */
- if (peek_char_next (dm) == 't')
- {
- (void) next_char (dm);
- (void) next_char (dm);
- RETURN_IF_ERROR (result_add (dm, "std::"));
- RETURN_IF_ERROR
- (demangle_unqualified_name (dm, &suppress_return_type));
- is_std_substitution = 1;
- }
- else
- RETURN_IF_ERROR (demangle_substitution (dm, encode_return_type));
- /* Check if a template argument list immediately follows.
- If so, then we just demangled an <unqualified-template-name>. */
- if (peek_char (dm) == 'I')
- {
- /* A template name of the form std::<unqualified-name> is a
- substitution candidate. */
- if (is_std_substitution)
- RETURN_IF_ERROR (substitution_add (dm, start, 0));
- /* Demangle the <template-args> here. */
- RETURN_IF_ERROR (demangle_template_args (dm));
- *encode_return_type = !suppress_return_type;
- }
- else
- *encode_return_type = 0;
+ {
+ int subst;
- break;
+ if (d_peek_next_char (di) != 't')
+ {
+ dc = d_substitution (di, 0);
+ subst = 1;
+ }
+ else
+ {
+ d_advance (di, 2);
+ dc = d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME,
+ d_make_name (di, "std", 3),
+ d_unqualified_name (di));
+ di->expansion += 3;
+ subst = 0;
+ }
- default:
- /* This is an <unscoped-name> or <unscoped-template-name>. */
- RETURN_IF_ERROR (demangle_unqualified_name (dm, &suppress_return_type));
+ if (d_peek_char (di) != 'I')
+ {
+ /* The grammar does not permit this case to occur if we
+ called d_substitution() above (i.e., subst == 1). We
+ don't bother to check. */
+ }
+ else
+ {
+ /* This is <template-args>, which means that we just saw
+ <unscoped-template-name>, which is a substitution
+ candidate if we didn't just get it from a
+ substitution. */
+ if (! subst)
+ {
+ if (! d_add_substitution (di, dc))
+ return NULL;
+ }
+ dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc,
+ d_template_args (di));
+ }
- /* If the <unqualified-name> is followed by template args, this
- is an <unscoped-template-name>. */
- if (peek_char (dm) == 'I')
- {
- /* Add a substitution for the unqualified template name. */
- RETURN_IF_ERROR (substitution_add (dm, start, 0));
+ return dc;
+ }
- RETURN_IF_ERROR (demangle_template_args (dm));
- *encode_return_type = !suppress_return_type;
+ default:
+ dc = d_unqualified_name (di);
+ if (d_peek_char (di) == 'I')
+ {
+ /* This is <template-args>, which means that we just saw
+ <unscoped-template-name>, which is a substitution
+ candidate. */
+ if (! d_add_substitution (di, dc))
+ return NULL;
+ dc = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, dc,
+ d_template_args (di));
}
- else
- *encode_return_type = 0;
-
- break;
+ return dc;
}
-
- return STATUS_OK;
}
-/* Demangles and emits a <nested-name>.
-
- <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqulified-name> E */
+/* <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
+ ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
+*/
-static status_t
-demangle_nested_name (dm, encode_return_type)
- demangling_t dm;
- int *encode_return_type;
+static struct demangle_component *
+d_nested_name (di)
+ struct d_info *di;
{
- char peek;
+ struct demangle_component *ret;
+ struct demangle_component **pret;
- DEMANGLE_TRACE ("nested-name", dm);
+ if (d_next_char (di) != 'N')
+ return NULL;
- RETURN_IF_ERROR (demangle_char (dm, 'N'));
+ pret = d_cv_qualifiers (di, &ret, 1);
+ if (pret == NULL)
+ return NULL;
- peek = peek_char (dm);
- if (peek == 'r' || peek == 'V' || peek == 'K')
- {
- dyn_string_t cv_qualifiers;
- status_t status;
-
- /* Snarf up CV qualifiers. */
- cv_qualifiers = dyn_string_new (24);
- if (cv_qualifiers == NULL)
- return STATUS_ALLOCATION_FAILED;
- demangle_CV_qualifiers (dm, cv_qualifiers);
-
- /* Emit them, preceded by a space. */
- status = result_add_char (dm, ' ');
- if (STATUS_NO_ERROR (status))
- status = result_add_string (dm, cv_qualifiers);
- /* The CV qualifiers that occur in a <nested-name> will be
- qualifiers for member functions. These are placed at the end
- of the function. Therefore, shift the caret to the left by
- the length of the qualifiers, so other text is inserted
- before them and they stay at the end. */
- result_shift_caret (dm, -dyn_string_length (cv_qualifiers) - 1);
- /* Clean up. */
- dyn_string_delete (cv_qualifiers);
- RETURN_IF_ERROR (status);
- }
+ *pret = d_prefix (di);
+ if (*pret == NULL)
+ return NULL;
- RETURN_IF_ERROR (demangle_prefix (dm, encode_return_type));
- /* No need to demangle the final <unqualified-name>; demangle_prefix
- will handle it. */
- RETURN_IF_ERROR (demangle_char (dm, 'E'));
+ if (d_next_char (di) != 'E')
+ return NULL;
- return STATUS_OK;
+ return ret;
}
-/* Demangles and emits a <prefix>.
+/* <prefix> ::= <prefix> <unqualified-name>
+ ::= <template-prefix> <template-args>
+ ::= <template-param>
+ ::=
+ ::= <substitution>
- <prefix> ::= <prefix> <unqualified-name>
- ::= <template-prefix> <template-args>
- ::= # empty
- ::= <substitution>
-
- <template-prefix> ::= <prefix>
- ::= <substitution> */
+ <template-prefix> ::= <prefix> <(template) unqualified-name>
+ ::= <template-param>
+ ::= <substitution>
+*/
-static status_t
-demangle_prefix (dm, encode_return_type)
- demangling_t dm;
- int *encode_return_type;
+static struct demangle_component *
+d_prefix (di)
+ struct d_info *di;
{
- int start = substitution_start (dm);
- int nested = 0;
-
- /* ENCODE_RETURN_TYPE is updated as we decend the nesting chain.
- After <template-args>, it is set to non-zero; after everything
- else it is set to zero. */
-
- /* Generally, the return type is encoded if the function is a
- template-id, and suppressed otherwise. There are a few cases,
- though, in which the return type is not encoded even for a
- templated function. In these cases, this flag is set. */
- int suppress_return_type = 0;
-
- DEMANGLE_TRACE ("prefix", dm);
+ struct demangle_component *ret = NULL;
while (1)
{
char peek;
+ enum demangle_component_type comb_type;
+ struct demangle_component *dc;
- if (end_of_name_p (dm))
- return "Unexpected end of name in <compound-name>.";
-
- peek = peek_char (dm);
-
- /* We'll initialize suppress_return_type to false, and set it to true
- if we end up demangling a constructor name. However, make
- sure we're not actually about to demangle template arguments
- -- if so, this is the <template-args> following a
- <template-prefix>, so we'll want the previous flag value
- around. */
- if (peek != 'I')
- suppress_return_type = 0;
-
- if (IS_DIGIT ((unsigned char) peek)
- || (peek >= 'a' && peek <= 'z')
- || peek == 'C' || peek == 'D'
- || peek == 'S')
- {
- /* We have another level of scope qualification. */
- if (nested)
- RETURN_IF_ERROR (result_add (dm, NAMESPACE_SEPARATOR));
- else
- nested = 1;
+ peek = d_peek_char (di);
+ if (peek == '\0')
+ return NULL;
- if (peek == 'S')
- /* The substitution determines whether this is a
- template-id. */
- RETURN_IF_ERROR (demangle_substitution (dm, encode_return_type));
- else
- {
- /* It's just a name. */
- RETURN_IF_ERROR
- (demangle_unqualified_name (dm, &suppress_return_type));
- *encode_return_type = 0;
- }
- }
- else if (peek == 'Z')
- RETURN_IF_ERROR (demangle_local_name (dm));
+ /* The older code accepts a <local-name> here, but I don't see
+ that in the grammar. The older code does not accept a
+ <template-param> here. */
+
+ comb_type = DEMANGLE_COMPONENT_QUAL_NAME;
+ if (IS_DIGIT (peek)
+ || IS_LOWER (peek)
+ || peek == 'C'
+ || peek == 'D')
+ dc = d_unqualified_name (di);
+ else if (peek == 'S')
+ dc = d_substitution (di, 1);
else if (peek == 'I')
{
- RETURN_IF_ERROR (demangle_template_args (dm));
-
- /* Now we want to indicate to the caller that we've
- demangled template arguments, thus the prefix was a
- <template-prefix>. That's so that the caller knows to
- demangle the function's return type, if this turns out to
- be a function name. But, if it's a member template
- constructor or a templated conversion operator, report it
- as untemplated. Those never get encoded return types. */
- *encode_return_type = !suppress_return_type;
+ if (ret == NULL)
+ return NULL;
+ comb_type = DEMANGLE_COMPONENT_TEMPLATE;
+ dc = d_template_args (di);
}
+ else if (peek == 'T')
+ dc = d_template_param (di);
else if (peek == 'E')
- /* All done. */
- return STATUS_OK;
+ return ret;
else
- return "Unexpected character in <compound-name>.";
+ return NULL;
+
+ if (ret == NULL)
+ ret = dc;
+ else
+ ret = d_make_comp (di, comb_type, ret, dc);
- if (peek != 'S'
- && peek_char (dm) != 'E')
- /* Add a new substitution for the prefix thus far. */
- RETURN_IF_ERROR (substitution_add (dm, start, *encode_return_type));
+ if (peek != 'S' && d_peek_char (di) != 'E')
+ {
+ if (! d_add_substitution (di, ret))
+ return NULL;
+ }
}
}
-/* Demangles and emits an <unqualified-name>. If this
- <unqualified-name> is for a special function type that should never
- have its return type encoded (particularly, a constructor or
- conversion operator), *SUPPRESS_RETURN_TYPE is set to 1; otherwise,
- it is set to zero.
-
- <unqualified-name> ::= <operator-name>
- ::= <special-name>
- ::= <source-name> */
+/* <unqualified-name> ::= <operator-name>
+ ::= <ctor-dtor-name>
+ ::= <source-name>
+*/
-static status_t
-demangle_unqualified_name (dm, suppress_return_type)
- demangling_t dm;
- int *suppress_return_type;
+static struct demangle_component *
+d_unqualified_name (di)
+ struct d_info *di;
{
- char peek = peek_char (dm);
-
- DEMANGLE_TRACE ("unqualified-name", dm);
-
- /* By default, don't force suppression of the return type (though
- non-template functions still don't get a return type encoded). */
- *suppress_return_type = 0;
+ char peek;
- if (IS_DIGIT ((unsigned char) peek))
- RETURN_IF_ERROR (demangle_source_name (dm));
- else if (peek >= 'a' && peek <= 'z')
+ peek = d_peek_char (di);
+ if (IS_DIGIT (peek))
+ return d_source_name (di);
+ else if (IS_LOWER (peek))
{
- int num_args;
+ struct demangle_component *ret;
- /* Conversion operators never have a return type encoded. */
- if (peek == 'c' && peek_char_next (dm) == 'v')
- *suppress_return_type = 1;
-
- RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args, NULL));
+ ret = d_operator_name (di);
+ if (ret != NULL && ret->type == DEMANGLE_COMPONENT_OPERATOR)
+ di->expansion += sizeof "operator" + ret->u.s_operator.op->len - 2;
+ return ret;
}
else if (peek == 'C' || peek == 'D')
- {
- /* Constructors never have a return type encoded. */
- if (peek == 'C')
- *suppress_return_type = 1;
-
- RETURN_IF_ERROR (demangle_ctor_dtor_name (dm));
- }
+ return d_ctor_dtor_name (di);
else
- return "Unexpected character in <unqualified-name>.";
-
- return STATUS_OK;
+ return NULL;
}
-/* Demangles and emits <source-name>.
-
- <source-name> ::= <length number> <identifier> */
+/* <source-name> ::= <(positive length) number> <identifier> */
-static status_t
-demangle_source_name (dm)
- demangling_t dm;
+static struct demangle_component *
+d_source_name (di)
+ struct d_info *di;
{
- int length;
-
- DEMANGLE_TRACE ("source-name", dm);
-
- /* Decode the length of the identifier. */
- RETURN_IF_ERROR (demangle_number (dm, &length, 10, 0));
- if (length == 0)
- return "Zero length in <source-name>.";
-
- /* Now the identifier itself. It's placed into last_source_name,
- where it can be used to build a constructor or destructor name. */
- RETURN_IF_ERROR (demangle_identifier (dm, length,
- dm->last_source_name));
+ long len;
+ struct demangle_component *ret;
- /* Emit it. */
- RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
-
- return STATUS_OK;
+ len = d_number (di);
+ if (len <= 0)
+ return NULL;
+ ret = d_identifier (di, len);
+ di->last_name = ret;
+ return ret;
}
-/* Demangles a number, either a <number> or a <positive-number> at the
- current position, consuming all consecutive digit characters. Sets
- *VALUE to the resulting numberand returns STATUS_OK. The number is
- interpreted as BASE, which must be either 10 or 36. If IS_SIGNED
- is non-zero, negative numbers -- prefixed with `n' -- are accepted.
-
- <number> ::= [n] <positive-number>
+/* number ::= [n] <(non-negative decimal integer)> */
- <positive-number> ::= <decimal integer> */
-
-static status_t
-demangle_number (dm, value, base, is_signed)
- demangling_t dm;
- int *value;
- int base;
- int is_signed;
+static long
+d_number (di)
+ struct d_info *di;
{
- dyn_string_t number = dyn_string_new (10);
-
- DEMANGLE_TRACE ("number", dm);
-
- if (number == NULL)
- return STATUS_ALLOCATION_FAILED;
-
- demangle_number_literally (dm, number, base, is_signed);
- *value = strtol (dyn_string_buf (number), NULL, base);
- dyn_string_delete (number);
-
- return STATUS_OK;
-}
-
-/* Demangles a number at the current position. The digits (and minus
- sign, if present) that make up the number are appended to STR.
- Only base-BASE digits are accepted; BASE must be either 10 or 36.
- If IS_SIGNED, negative numbers -- prefixed with `n' -- are
- accepted. Does not consume a trailing underscore or other
- terminating character. */
-
-static status_t
-demangle_number_literally (dm, str, base, is_signed)
- demangling_t dm;
- dyn_string_t str;
- int base;
- int is_signed;
-{
- DEMANGLE_TRACE ("number*", dm);
-
- if (base != 10 && base != 36)
- return STATUS_INTERNAL_ERROR;
+ int negative;
+ char peek;
+ long ret;
- /* An `n' denotes a negative number. */
- if (is_signed && peek_char (dm) == 'n')
+ negative = 0;
+ peek = d_peek_char (di);
+ if (peek == 'n')
{
- /* Skip past the n. */
- advance_char (dm);
- /* The normal way to write a negative number is with a minus
- sign. */
- if (!dyn_string_append_char (str, '-'))
- return STATUS_ALLOCATION_FAILED;
+ negative = 1;
+ d_advance (di, 1);
+ peek = d_peek_char (di);
}
- /* Loop until we hit a non-digit. */
+ ret = 0;
while (1)
{
- char peek = peek_char (dm);
- if (IS_DIGIT ((unsigned char) peek)
- || (base == 36 && peek >= 'A' && peek <= 'Z'))
+ if (! IS_DIGIT (peek))
{
- /* Accumulate digits. */
- if (!dyn_string_append_char (str, next_char (dm)))
- return STATUS_ALLOCATION_FAILED;
+ if (negative)
+ ret = - ret;
+ return ret;
}
- else
- /* Not a digit? All done. */
- break;
+ ret = ret * 10 + peek - '0';
+ d_advance (di, 1);
+ peek = d_peek_char (di);
}
-
- return STATUS_OK;
}
-/* Demangles an identifier at the current position of LENGTH
- characters and places it in IDENTIFIER. */
+/* identifier ::= <(unqualified source code identifier)> */
-static status_t
-demangle_identifier (dm, length, identifier)
- demangling_t dm;
- int length;
- dyn_string_t identifier;
+static struct demangle_component *
+d_identifier (di, len)
+ struct d_info *di;
+ int len;
{
- DEMANGLE_TRACE ("identifier", dm);
-
- dyn_string_clear (identifier);
- if (!dyn_string_resize (identifier, length))
- return STATUS_ALLOCATION_FAILED;
+ const char *name;
- while (length-- > 0)
- {
- int ch;
- if (end_of_name_p (dm))
- return "Unexpected end of name in <identifier>.";
- ch = next_char (dm);
-
- /* Handle extended Unicode characters. We encode them as __U{hex}_,
- where {hex} omits leading 0's. For instance, '$' is encoded as
- "__U24_". */
- if (ch == '_'
- && peek_char (dm) == '_'
- && peek_char_next (dm) == 'U')
- {
- char buf[10];
- int pos = 0;
- advance_char (dm); advance_char (dm); length -= 2;
- while (length-- > 0)
- {
- ch = next_char (dm);
- if (!isxdigit (ch))
- break;
- buf[pos++] = ch;
- }
- if (ch != '_' || length < 0)
- return STATUS_ERROR;
- if (pos == 0)
- {
- /* __U_ just means __U. */
- if (!dyn_string_append_cstr (identifier, "__U"))
- return STATUS_ALLOCATION_FAILED;
- continue;
- }
- else
- {
- buf[pos] = '\0';
- ch = strtol (buf, 0, 16);
- }
- }
+ name = d_str (di);
- if (!dyn_string_append_char (identifier, ch))
- return STATUS_ALLOCATION_FAILED;
- }
+ if (di->send - name < len)
+ return NULL;
- /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.'
- followed by the source file name and some random characters.
- Unless we're in strict mode, decipher these names appropriately. */
- if (!flag_strict)
+ d_advance (di, len);
+
+ /* A Java mangled name may have a trailing '$' if it is a C++
+ keyword. This '$' is not included in the length count. We just
+ ignore the '$'. */
+ if ((di->options & DMGL_JAVA) != 0
+ && d_peek_char (di) == '$')
+ d_advance (di, 1);
+
+ /* Look for something which looks like a gcc encoding of an
+ anonymous namespace, and replace it with a more user friendly
+ name. */
+ if (len >= (int) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2
+ && memcmp (name, ANONYMOUS_NAMESPACE_PREFIX,
+ ANONYMOUS_NAMESPACE_PREFIX_LEN) == 0)
{
- char *name = dyn_string_buf (identifier);
- int prefix_length = strlen (ANONYMOUS_NAMESPACE_PREFIX);
-
- /* Compare the first, fixed part. */
- if (strncmp (name, ANONYMOUS_NAMESPACE_PREFIX, prefix_length) == 0)
- {
- name += prefix_length;
- /* The next character might be a period, an underscore, or
- dollar sign, depending on the target architecture's
- assembler's capabilities. After that comes an `N'. */
- if ((*name == '.' || *name == '_' || *name == '$')
- && *(name + 1) == 'N')
- /* This looks like the anonymous namespace identifier.
- Replace it with something comprehensible. */
- dyn_string_copy_cstr (identifier, "(anonymous namespace)");
+ const char *s;
+
+ s = name + ANONYMOUS_NAMESPACE_PREFIX_LEN;
+ if ((*s == '.' || *s == '_' || *s == '$')
+ && s[1] == 'N')
+ {
+ di->expansion -= len - sizeof "(anonymous namespace)";
+ return d_make_name (di, "(anonymous namespace)",
+ sizeof "(anonymous namespace)" - 1);
}
}
- return STATUS_OK;
+ return d_make_name (di, name, len);
}
-/* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero,
- the short form is emitted; otherwise the full source form
- (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of
- operands that the operator takes. If TYPE_ARG is non-NULL,
- *TYPE_ARG is set to 1 if the first argument is a type and 0
- otherwise.
-
- <operator-name>
- ::= nw # new
- ::= na # new[]
- ::= dl # delete
- ::= da # delete[]
- ::= ps # + (unary)
- ::= ng # - (unary)
- ::= ad # & (unary)
- ::= de # * (unary)
- ::= co # ~
- ::= pl # +
- ::= mi # -
- ::= ml # *
- ::= dv # /
- ::= rm # %
- ::= an # &
- ::= or # |
- ::= eo # ^
- ::= aS # =
- ::= pL # +=
- ::= mI # -=
- ::= mL # *=
- ::= dV # /=
- ::= rM # %=
- ::= aN # &=
- ::= oR # |=
- ::= eO # ^=
- ::= ls # <<
- ::= rs # >>
- ::= lS # <<=
- ::= rS # >>=
- ::= eq # ==
- ::= ne # !=
- ::= lt # <
- ::= gt # >
- ::= le # <=
- ::= ge # >=
- ::= nt # !
- ::= aa # &&
- ::= oo # ||
- ::= pp # ++
- ::= mm # --
- ::= cm # ,
- ::= pm # ->*
- ::= pt # ->
- ::= cl # ()
- ::= ix # []
- ::= qu # ?
- ::= st # sizeof (a type)
- ::= sz # sizeof (an expression)
- ::= cv <type> # cast
- ::= v [0-9] <source-name> # vendor extended operator */
-
-static status_t
-demangle_operator_name (dm, short_name, num_args, type_arg)
- demangling_t dm;
- int short_name;
- int *num_args;
- int *type_arg;
-{
- struct operator_code
- {
- /* The mangled code for this operator. */
- const char *const code;
- /* The source name of this operator. */
- const char *const name;
- /* The number of arguments this operator takes. */
- const int num_args;
- };
-
- static const struct operator_code operators[] =
- {
- { "aN", "&=" , 2 },
- { "aS", "=" , 2 },
- { "aa", "&&" , 2 },
- { "ad", "&" , 1 },
- { "an", "&" , 2 },
- { "cl", "()" , 0 },
- { "cm", "," , 2 },
- { "co", "~" , 1 },
- { "dV", "/=" , 2 },
- { "da", " delete[]", 1 },
- { "de", "*" , 1 },
- { "dl", " delete" , 1 },
- { "dv", "/" , 2 },
- { "eO", "^=" , 2 },
- { "eo", "^" , 2 },
- { "eq", "==" , 2 },
- { "ge", ">=" , 2 },
- { "gt", ">" , 2 },
- { "ix", "[]" , 2 },
- { "lS", "<<=" , 2 },
- { "le", "<=" , 2 },
- { "ls", "<<" , 2 },
- { "lt", "<" , 2 },
- { "mI", "-=" , 2 },
- { "mL", "*=" , 2 },
- { "mi", "-" , 2 },
- { "ml", "*" , 2 },
- { "mm", "--" , 1 },
- { "na", " new[]" , 1 },
- { "ne", "!=" , 2 },
- { "ng", "-" , 1 },
- { "nt", "!" , 1 },
- { "nw", " new" , 1 },
- { "oR", "|=" , 2 },
- { "oo", "||" , 2 },
- { "or", "|" , 2 },
- { "pL", "+=" , 2 },
- { "pl", "+" , 2 },
- { "pm", "->*" , 2 },
- { "pp", "++" , 1 },
- { "ps", "+" , 1 },
- { "pt", "->" , 2 },
- { "qu", "?" , 3 },
- { "rM", "%=" , 2 },
- { "rS", ">>=" , 2 },
- { "rm", "%" , 2 },
- { "rs", ">>" , 2 },
- { "sz", " sizeof" , 1 }
- };
-
- const int num_operators =
- sizeof (operators) / sizeof (struct operator_code);
-
- int c0 = next_char (dm);
- int c1 = next_char (dm);
- const struct operator_code* p1 = operators;
- const struct operator_code* p2 = operators + num_operators;
-
- DEMANGLE_TRACE ("operator-name", dm);
-
- /* Assume the first argument is not a type. */
- if (type_arg)
- *type_arg = 0;
-
- /* Is this a vendor-extended operator? */
- if (c0 == 'v' && IS_DIGIT (c1))
- {
- RETURN_IF_ERROR (result_add (dm, "operator "));
- RETURN_IF_ERROR (demangle_source_name (dm));
- *num_args = 0;
- return STATUS_OK;
- }
+/* operator_name ::= many different two character encodings.
+ ::= cv <type>
+ ::= v <digit> <source-name>
+*/
- /* Is this a conversion operator? */
- if (c0 == 'c' && c1 == 'v')
- {
- RETURN_IF_ERROR (result_add (dm, "operator "));
- /* Demangle the converted-to type. */
- RETURN_IF_ERROR (demangle_type (dm));
- *num_args = 0;
- return STATUS_OK;
- }
+#define NL(s) s, (sizeof s) - 1
- /* Is it the sizeof variant that takes a type? */
- if (c0 == 's' && c1 == 't')
- {
- RETURN_IF_ERROR (result_add (dm, " sizeof"));
- *num_args = 1;
- if (type_arg)
- *type_arg = 1;
- return STATUS_OK;
- }
+CP_STATIC_IF_GLIBCPP_V3
+const struct demangle_operator_info cplus_demangle_operators[] =
+{
+ { "aN", NL ("&="), 2 },
+ { "aS", NL ("="), 2 },
+ { "aa", NL ("&&"), 2 },
+ { "ad", NL ("&"), 1 },
+ { "an", NL ("&"), 2 },
+ { "cl", NL ("()"), 0 },
+ { "cm", NL (","), 2 },
+ { "co", NL ("~"), 1 },
+ { "dV", NL ("/="), 2 },
+ { "da", NL ("delete[]"), 1 },
+ { "de", NL ("*"), 1 },
+ { "dl", NL ("delete"), 1 },
+ { "dv", NL ("/"), 2 },
+ { "eO", NL ("^="), 2 },
+ { "eo", NL ("^"), 2 },
+ { "eq", NL ("=="), 2 },
+ { "ge", NL (">="), 2 },
+ { "gt", NL (">"), 2 },
+ { "ix", NL ("[]"), 2 },
+ { "lS", NL ("<<="), 2 },
+ { "le", NL ("<="), 2 },
+ { "ls", NL ("<<"), 2 },
+ { "lt", NL ("<"), 2 },
+ { "mI", NL ("-="), 2 },
+ { "mL", NL ("*="), 2 },
+ { "mi", NL ("-"), 2 },
+ { "ml", NL ("*"), 2 },
+ { "mm", NL ("--"), 1 },
+ { "na", NL ("new[]"), 1 },
+ { "ne", NL ("!="), 2 },
+ { "ng", NL ("-"), 1 },
+ { "nt", NL ("!"), 1 },
+ { "nw", NL ("new"), 1 },
+ { "oR", NL ("|="), 2 },
+ { "oo", NL ("||"), 2 },
+ { "or", NL ("|"), 2 },
+ { "pL", NL ("+="), 2 },
+ { "pl", NL ("+"), 2 },
+ { "pm", NL ("->*"), 2 },
+ { "pp", NL ("++"), 1 },
+ { "ps", NL ("+"), 1 },
+ { "pt", NL ("->"), 2 },
+ { "qu", NL ("?"), 3 },
+ { "rM", NL ("%="), 2 },
+ { "rS", NL (">>="), 2 },
+ { "rm", NL ("%"), 2 },
+ { "rs", NL (">>"), 2 },
+ { "st", NL ("sizeof "), 1 },
+ { "sz", NL ("sizeof "), 1 },
+ { NULL, NULL, 0, 0 }
+};
- /* Perform a binary search for the operator code. */
- while (1)
+static struct demangle_component *
+d_operator_name (di)
+ struct d_info *di;
+{
+ char c1;
+ char c2;
+
+ c1 = d_next_char (di);
+ c2 = d_next_char (di);
+ if (c1 == 'v' && IS_DIGIT (c2))
+ return d_make_extended_operator (di, c2 - '0', d_source_name (di));
+ else if (c1 == 'c' && c2 == 'v')
+ return d_make_comp (di, DEMANGLE_COMPONENT_CAST,
+ cplus_demangle_type (di), NULL);
+ else
{
- const struct operator_code* p = p1 + (p2 - p1) / 2;
- char match0 = p->code[0];
- char match1 = p->code[1];
-
- if (c0 == match0 && c1 == match1)
- /* Found it. */
+ /* LOW is the inclusive lower bound. */
+ int low = 0;
+ /* HIGH is the exclusive upper bound. We subtract one to ignore
+ the sentinel at the end of the array. */
+ int high = ((sizeof (cplus_demangle_operators)
+ / sizeof (cplus_demangle_operators[0]))
+ - 1);
+
+ while (1)
{
- if (!short_name)
- RETURN_IF_ERROR (result_add (dm, "operator"));
- RETURN_IF_ERROR (result_add (dm, p->name));
- *num_args = p->num_args;
+ int i;
+ const struct demangle_operator_info *p;
- return STATUS_OK;
- }
+ i = low + (high - low) / 2;
+ p = cplus_demangle_operators + i;
- if (p == p1)
- /* Couldn't find it. */
- return "Unknown code in <operator-name>.";
+ if (c1 == p->code[0] && c2 == p->code[1])
+ return d_make_operator (di, p);
- /* Try again. */
- if (c0 < match0 || (c0 == match0 && c1 < match1))
- p2 = p;
- else
- p1 = p;
+ if (c1 < p->code[0] || (c1 == p->code[0] && c2 < p->code[1]))
+ high = i;
+ else
+ low = i + 1;
+ if (low == high)
+ return NULL;
+ }
}
}
-/* Demangles and omits an <nv-offset>.
-
- <nv-offset> ::= <offset number> # non-virtual base override */
+/* <special-name> ::= TV <type>
+ ::= TT <type>
+ ::= TI <type>
+ ::= TS <type>
+ ::= GV <(object) name>
+ ::= T <call-offset> <(base) encoding>
+ ::= Tc <call-offset> <call-offset> <(base) encoding>
+ Also g++ extensions:
+ ::= TC <type> <(offset) number> _ <(base) type>
+ ::= TF <type>
+ ::= TJ <type>
+ ::= GR <name>
+*/
-static status_t
-demangle_nv_offset (dm)
- demangling_t dm;
+static struct demangle_component *
+d_special_name (di)
+ struct d_info *di;
{
- dyn_string_t number;
- status_t status = STATUS_OK;
-
- DEMANGLE_TRACE ("h-offset", dm);
+ char c;
- /* Demangle the offset. */
- number = dyn_string_new (4);
- if (number == NULL)
- return STATUS_ALLOCATION_FAILED;
- demangle_number_literally (dm, number, 10, 1);
-
- /* Don't display the offset unless in verbose mode. */
- if (flag_verbose)
+ di->expansion += 20;
+ c = d_next_char (di);
+ if (c == 'T')
{
- status = result_add (dm, " [nv:");
- if (STATUS_NO_ERROR (status))
- status = result_add_string (dm, number);
- if (STATUS_NO_ERROR (status))
- status = result_add_char (dm, ']');
- }
-
- /* Clean up. */
- dyn_string_delete (number);
- RETURN_IF_ERROR (status);
- return STATUS_OK;
-}
+ switch (d_next_char (di))
+ {
+ case 'V':
+ di->expansion -= 5;
+ return d_make_comp (di, DEMANGLE_COMPONENT_VTABLE,
+ cplus_demangle_type (di), NULL);
+ case 'T':
+ di->expansion -= 10;
+ return d_make_comp (di, DEMANGLE_COMPONENT_VTT,
+ cplus_demangle_type (di), NULL);
+ case 'I':
+ return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO,
+ cplus_demangle_type (di), NULL);
+ case 'S':
+ return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_NAME,
+ cplus_demangle_type (di), NULL);
-/* Demangles and emits a <v-offset>.
+ case 'h':
+ if (! d_call_offset (di, 'h'))
+ return NULL;
+ return d_make_comp (di, DEMANGLE_COMPONENT_THUNK,
+ d_encoding (di, 0), NULL);
- <v-offset> ::= <offset number> _ <virtual offset number>
- # virtual base override, with vcall offset */
+ case 'v':
+ if (! d_call_offset (di, 'v'))
+ return NULL;
+ return d_make_comp (di, DEMANGLE_COMPONENT_VIRTUAL_THUNK,
+ d_encoding (di, 0), NULL);
-static status_t
-demangle_v_offset (dm)
- demangling_t dm;
-{
- dyn_string_t number;
- status_t status = STATUS_OK;
+ case 'c':
+ if (! d_call_offset (di, '\0'))
+ return NULL;
+ if (! d_call_offset (di, '\0'))
+ return NULL;
+ return d_make_comp (di, DEMANGLE_COMPONENT_COVARIANT_THUNK,
+ d_encoding (di, 0), NULL);
- DEMANGLE_TRACE ("v-offset", dm);
+ case 'C':
+ {
+ struct demangle_component *derived_type;
+ long offset;
+ struct demangle_component *base_type;
+
+ derived_type = cplus_demangle_type (di);
+ offset = d_number (di);
+ if (offset < 0)
+ return NULL;
+ if (d_next_char (di) != '_')
+ return NULL;
+ base_type = cplus_demangle_type (di);
+ /* We don't display the offset. FIXME: We should display
+ it in verbose mode. */
+ di->expansion += 5;
+ return d_make_comp (di, DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE,
+ base_type, derived_type);
+ }
- /* Demangle the offset. */
- number = dyn_string_new (4);
- if (number == NULL)
- return STATUS_ALLOCATION_FAILED;
- demangle_number_literally (dm, number, 10, 1);
+ case 'F':
+ return d_make_comp (di, DEMANGLE_COMPONENT_TYPEINFO_FN,
+ cplus_demangle_type (di), NULL);
+ case 'J':
+ return d_make_comp (di, DEMANGLE_COMPONENT_JAVA_CLASS,
+ cplus_demangle_type (di), NULL);
- /* Don't display the offset unless in verbose mode. */
- if (flag_verbose)
- {
- status = result_add (dm, " [v:");
- if (STATUS_NO_ERROR (status))
- status = result_add_string (dm, number);
- if (STATUS_NO_ERROR (status))
- result_add_char (dm, ',');
+ default:
+ return NULL;
+ }
}
- dyn_string_delete (number);
- RETURN_IF_ERROR (status);
-
- /* Demangle the separator. */
- RETURN_IF_ERROR (demangle_char (dm, '_'));
+ else if (c == 'G')
+ {
+ switch (d_next_char (di))
+ {
+ case 'V':
+ return d_make_comp (di, DEMANGLE_COMPONENT_GUARD, d_name (di), NULL);
- /* Demangle the vcall offset. */
- number = dyn_string_new (4);
- if (number == NULL)
- return STATUS_ALLOCATION_FAILED;
- demangle_number_literally (dm, number, 10, 1);
+ case 'R':
+ return d_make_comp (di, DEMANGLE_COMPONENT_REFTEMP, d_name (di),
+ NULL);
- /* Don't display the vcall offset unless in verbose mode. */
- if (flag_verbose)
- {
- status = result_add_string (dm, number);
- if (STATUS_NO_ERROR (status))
- status = result_add_char (dm, ']');
+ default:
+ return NULL;
+ }
}
- dyn_string_delete (number);
- RETURN_IF_ERROR (status);
-
- return STATUS_OK;
+ else
+ return NULL;
}
-/* Demangles and emits a <call-offset>.
+/* <call-offset> ::= h <nv-offset> _
+ ::= v <v-offset> _
- <call-offset> ::= h <nv-offset> _
- ::= v <v-offset> _ */
+ <nv-offset> ::= <(offset) number>
-static status_t
-demangle_call_offset (dm)
- demangling_t dm;
-{
- DEMANGLE_TRACE ("call-offset", dm);
+ <v-offset> ::= <(offset) number> _ <(virtual offset) number>
- switch (peek_char (dm))
- {
- case 'h':
- advance_char (dm);
- /* Demangle the offset. */
- RETURN_IF_ERROR (demangle_nv_offset (dm));
- /* Demangle the separator. */
- RETURN_IF_ERROR (demangle_char (dm, '_'));
- break;
+ The C parameter, if not '\0', is a character we just read which is
+ the start of the <call-offset>.
- case 'v':
- advance_char (dm);
- /* Demangle the offset. */
- RETURN_IF_ERROR (demangle_v_offset (dm));
- /* Demangle the separator. */
- RETURN_IF_ERROR (demangle_char (dm, '_'));
- break;
+ We don't display the offset information anywhere. FIXME: We should
+ display it in verbose mode. */
- default:
- return "Unrecognized <call-offset>.";
- }
+static int
+d_call_offset (di, c)
+ struct d_info *di;
+ int c;
+{
+ long offset;
+ long virtual_offset;
- return STATUS_OK;
-}
+ if (c == '\0')
+ c = d_next_char (di);
-/* Demangles and emits a <special-name>.
+ if (c == 'h')
+ offset = d_number (di);
+ else if (c == 'v')
+ {
+ offset = d_number (di);
+ if (d_next_char (di) != '_')
+ return 0;
+ virtual_offset = d_number (di);
+ }
+ else
+ return 0;
- <special-name> ::= GV <object name> # Guard variable
- ::= TV <type> # virtual table
- ::= TT <type> # VTT
- ::= TI <type> # typeinfo structure
- ::= TS <type> # typeinfo name
+ if (d_next_char (di) != '_')
+ return 0;
- Other relevant productions include thunks:
+ return 1;
+}
- <special-name> ::= T <call-offset> <base encoding>
- # base is the nominal target function of thunk
+/* <ctor-dtor-name> ::= C1
+ ::= C2
+ ::= C3
+ ::= D0
+ ::= D1
+ ::= D2
+*/
- <special-name> ::= Tc <call-offset> <call-offset> <base encoding>
- # base is the nominal target function of thunk
- # first call-offset is 'this' adjustment
- # second call-offset is result adjustment
+static struct demangle_component *
+d_ctor_dtor_name (di)
+ struct d_info *di;
+{
+ if (di->last_name != NULL)
+ {
+ if (di->last_name->type == DEMANGLE_COMPONENT_NAME)
+ di->expansion += di->last_name->u.s_name.len;
+ else if (di->last_name->type == DEMANGLE_COMPONENT_SUB_STD)
+ di->expansion += di->last_name->u.s_string.len;
+ }
+ switch (d_next_char (di))
+ {
+ case 'C':
+ {
+ enum gnu_v3_ctor_kinds kind;
- where
+ switch (d_next_char (di))
+ {
+ case '1':
+ kind = gnu_v3_complete_object_ctor;
+ break;
+ case '2':
+ kind = gnu_v3_base_object_ctor;
+ break;
+ case '3':
+ kind = gnu_v3_complete_object_allocating_ctor;
+ break;
+ default:
+ return NULL;
+ }
+ return d_make_ctor (di, kind, di->last_name);
+ }
- <call-offset> ::= h <nv-offset> _
- ::= v <v-offset> _
+ case 'D':
+ {
+ enum gnu_v3_dtor_kinds kind;
- Also demangles the special g++ manglings,
+ switch (d_next_char (di))
+ {
+ case '0':
+ kind = gnu_v3_deleting_dtor;
+ break;
+ case '1':
+ kind = gnu_v3_complete_object_dtor;
+ break;
+ case '2':
+ kind = gnu_v3_base_object_dtor;
+ break;
+ default:
+ return NULL;
+ }
+ return d_make_dtor (di, kind, di->last_name);
+ }
+
+ default:
+ return NULL;
+ }
+}
- <special-name> ::= TC <type> <offset number> _ <base type>
- # construction vtable
- ::= TF <type> # typeinfo function (old ABI only)
- ::= TJ <type> # java Class structure */
+/* <type> ::= <builtin-type>
+ ::= <function-type>
+ ::= <class-enum-type>
+ ::= <array-type>
+ ::= <pointer-to-member-type>
+ ::= <template-param>
+ ::= <template-template-param> <template-args>
+ ::= <substitution>
+ ::= <CV-qualifiers> <type>
+ ::= P <type>
+ ::= R <type>
+ ::= C <type>
+ ::= G <type>
+ ::= U <source-name> <type>
+
+ <builtin-type> ::= various one letter codes
+ ::= u <source-name>
+*/
-static status_t
-demangle_special_name (dm)
- demangling_t dm;
+CP_STATIC_IF_GLIBCPP_V3
+const struct demangle_builtin_type_info
+cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT] =
{
- dyn_string_t number;
- int unused;
- char peek = peek_char (dm);
-
- DEMANGLE_TRACE ("special-name", dm);
+ /* a */ { NL ("signed char"), NL ("signed char"), D_PRINT_DEFAULT },
+ /* b */ { NL ("bool"), NL ("boolean"), D_PRINT_BOOL },
+ /* c */ { NL ("char"), NL ("byte"), D_PRINT_DEFAULT },
+ /* d */ { NL ("double"), NL ("double"), D_PRINT_FLOAT },
+ /* e */ { NL ("long double"), NL ("long double"), D_PRINT_FLOAT },
+ /* f */ { NL ("float"), NL ("float"), D_PRINT_FLOAT },
+ /* g */ { NL ("__float128"), NL ("__float128"), D_PRINT_FLOAT },
+ /* h */ { NL ("unsigned char"), NL ("unsigned char"), D_PRINT_DEFAULT },
+ /* i */ { NL ("int"), NL ("int"), D_PRINT_INT },
+ /* j */ { NL ("unsigned int"), NL ("unsigned"), D_PRINT_UNSIGNED },
+ /* k */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
+ /* l */ { NL ("long"), NL ("long"), D_PRINT_LONG },
+ /* m */ { NL ("unsigned long"), NL ("unsigned long"), D_PRINT_UNSIGNED_LONG },
+ /* n */ { NL ("__int128"), NL ("__int128"), D_PRINT_DEFAULT },
+ /* o */ { NL ("unsigned __int128"), NL ("unsigned __int128"),
+ D_PRINT_DEFAULT },
+ /* p */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
+ /* q */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
+ /* r */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
+ /* s */ { NL ("short"), NL ("short"), D_PRINT_DEFAULT },
+ /* t */ { NL ("unsigned short"), NL ("unsigned short"), D_PRINT_DEFAULT },
+ /* u */ { NULL, 0, NULL, 0, D_PRINT_DEFAULT },
+ /* v */ { NL ("void"), NL ("void"), D_PRINT_VOID },
+ /* w */ { NL ("wchar_t"), NL ("char"), D_PRINT_DEFAULT },
+ /* x */ { NL ("long long"), NL ("long"), D_PRINT_LONG_LONG },
+ /* y */ { NL ("unsigned long long"), NL ("unsigned long long"),
+ D_PRINT_UNSIGNED_LONG_LONG },
+ /* z */ { NL ("..."), NL ("..."), D_PRINT_DEFAULT },
+};
- if (peek == 'G')
+CP_STATIC_IF_GLIBCPP_V3
+struct demangle_component *
+cplus_demangle_type (di)
+ struct d_info *di;
+{
+ char peek;
+ struct demangle_component *ret;
+ int can_subst;
+
+ /* The ABI specifies that when CV-qualifiers are used, the base type
+ is substitutable, and the fully qualified type is substitutable,
+ but the base type with a strict subset of the CV-qualifiers is
+ not substitutable. The natural recursive implementation of the
+ CV-qualifiers would cause subsets to be substitutable, so instead
+ we pull them all off now.
+
+ FIXME: The ABI says that order-insensitive vendor qualifiers
+ should be handled in the same way, but we have no way to tell
+ which vendor qualifiers are order-insensitive and which are
+ order-sensitive. So we just assume that they are all
+ order-sensitive. g++ 3.4 supports only one vendor qualifier,
+ __vector, and it treats it as order-sensitive when mangling
+ names. */
+
+ peek = d_peek_char (di);
+ if (peek == 'r' || peek == 'V' || peek == 'K')
{
- /* Consume the G. */
- advance_char (dm);
- switch (peek_char (dm))
- {
- case 'V':
- /* A guard variable name. */
- advance_char (dm);
- RETURN_IF_ERROR (result_add (dm, "guard variable for "));
- RETURN_IF_ERROR (demangle_name (dm, &unused));
- break;
+ struct demangle_component **pret;
- case 'R':
- /* A reference temporary. */
- advance_char (dm);
- RETURN_IF_ERROR (result_add (dm, "reference temporary for "));
- RETURN_IF_ERROR (demangle_name (dm, &unused));
- break;
-
- default:
- return "Unrecognized <special-name>.";
- }
+ pret = d_cv_qualifiers (di, &ret, 0);
+ if (pret == NULL)
+ return NULL;
+ *pret = cplus_demangle_type (di);
+ if (! d_add_substitution (di, ret))
+ return NULL;
+ return ret;
}
- else if (peek == 'T')
+
+ can_subst = 1;
+
+ switch (peek)
{
- status_t status = STATUS_OK;
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
+ case 'h': case 'i': case 'j': case 'l': case 'm': case 'n':
+ case 'o': case 's': case 't':
+ case 'v': case 'w': case 'x': case 'y': case 'z':
+ ret = d_make_builtin_type (di,
+ &cplus_demangle_builtin_types[peek - 'a']);
+ di->expansion += ret->u.s_builtin.type->len;
+ can_subst = 0;
+ d_advance (di, 1);
+ break;
- /* Other C++ implementation miscellania. Consume the T. */
- advance_char (dm);
+ case 'u':
+ d_advance (di, 1);
+ ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE,
+ d_source_name (di), NULL);
+ break;
- switch (peek_char (dm))
- {
- case 'V':
- /* Virtual table. */
- advance_char (dm);
- RETURN_IF_ERROR (result_add (dm, "vtable for "));
- RETURN_IF_ERROR (demangle_type (dm));
- break;
+ case 'F':
+ ret = d_function_type (di);
+ break;
- case 'T':
- /* VTT structure. */
- advance_char (dm);
- RETURN_IF_ERROR (result_add (dm, "VTT for "));
- RETURN_IF_ERROR (demangle_type (dm));
- break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case 'N':
+ case 'Z':
+ ret = d_class_enum_type (di);
+ break;
- case 'I':
- /* Typeinfo structure. */
- advance_char (dm);
- RETURN_IF_ERROR (result_add (dm, "typeinfo for "));
- RETURN_IF_ERROR (demangle_type (dm));
- break;
+ case 'A':
+ ret = d_array_type (di);
+ break;
- case 'F':
- /* Typeinfo function. Used only in old ABI with new mangling. */
- advance_char (dm);
- RETURN_IF_ERROR (result_add (dm, "typeinfo fn for "));
- RETURN_IF_ERROR (demangle_type (dm));
- break;
+ case 'M':
+ ret = d_pointer_to_member_type (di);
+ break;
- case 'S':
- /* Character string containing type name, used in typeinfo. */
- advance_char (dm);
- RETURN_IF_ERROR (result_add (dm, "typeinfo name for "));
- RETURN_IF_ERROR (demangle_type (dm));
- break;
+ case 'T':
+ ret = d_template_param (di);
+ if (d_peek_char (di) == 'I')
+ {
+ /* This is <template-template-param> <template-args>. The
+ <template-template-param> part is a substitution
+ candidate. */
+ if (! d_add_substitution (di, ret))
+ return NULL;
+ ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
+ d_template_args (di));
+ }
+ break;
- case 'J':
- /* The java Class variable corresponding to a C++ class. */
- advance_char (dm);
- RETURN_IF_ERROR (result_add (dm, "java Class for "));
- RETURN_IF_ERROR (demangle_type (dm));
- break;
+ case 'S':
+ /* If this is a special substitution, then it is the start of
+ <class-enum-type>. */
+ {
+ char peek_next;
- case 'h':
- /* Non-virtual thunk. */
- advance_char (dm);
- RETURN_IF_ERROR (result_add (dm, "non-virtual thunk"));
- RETURN_IF_ERROR (demangle_nv_offset (dm));
- /* Demangle the separator. */
- RETURN_IF_ERROR (demangle_char (dm, '_'));
- /* Demangle and emit the target name and function type. */
- RETURN_IF_ERROR (result_add (dm, " to "));
- RETURN_IF_ERROR (demangle_encoding (dm));
- break;
+ peek_next = d_peek_next_char (di);
+ if (IS_DIGIT (peek_next)
+ || peek_next == '_'
+ || IS_UPPER (peek_next))
+ {
+ ret = d_substitution (di, 0);
+ /* The substituted name may have been a template name and
+ may be followed by tepmlate args. */
+ if (d_peek_char (di) == 'I')
+ ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
+ d_template_args (di));
+ else
+ can_subst = 0;
+ }
+ else
+ {
+ ret = d_class_enum_type (di);
+ /* If the substitution was a complete type, then it is not
+ a new substitution candidate. However, if the
+ substitution was followed by template arguments, then
+ the whole thing is a substitution candidate. */
+ if (ret != NULL && ret->type == DEMANGLE_COMPONENT_SUB_STD)
+ can_subst = 0;
+ }
+ }
+ break;
- case 'v':
- /* Virtual thunk. */
- advance_char (dm);
- RETURN_IF_ERROR (result_add (dm, "virtual thunk"));
- RETURN_IF_ERROR (demangle_v_offset (dm));
- /* Demangle the separator. */
- RETURN_IF_ERROR (demangle_char (dm, '_'));
- /* Demangle and emit the target function. */
- RETURN_IF_ERROR (result_add (dm, " to "));
- RETURN_IF_ERROR (demangle_encoding (dm));
- break;
+ case 'P':
+ d_advance (di, 1);
+ ret = d_make_comp (di, DEMANGLE_COMPONENT_POINTER,
+ cplus_demangle_type (di), NULL);
+ break;
- case 'c':
- /* Covariant return thunk. */
- advance_char (dm);
- RETURN_IF_ERROR (result_add (dm, "covariant return thunk"));
- RETURN_IF_ERROR (demangle_call_offset (dm));
- RETURN_IF_ERROR (demangle_call_offset (dm));
- /* Demangle and emit the target function. */
- RETURN_IF_ERROR (result_add (dm, " to "));
- RETURN_IF_ERROR (demangle_encoding (dm));
- break;
+ case 'R':
+ d_advance (di, 1);
+ ret = d_make_comp (di, DEMANGLE_COMPONENT_REFERENCE,
+ cplus_demangle_type (di), NULL);
+ break;
- case 'C':
- /* TC is a special g++ mangling for a construction vtable. */
- if (!flag_strict)
- {
- dyn_string_t derived_type;
+ case 'C':
+ d_advance (di, 1);
+ ret = d_make_comp (di, DEMANGLE_COMPONENT_COMPLEX,
+ cplus_demangle_type (di), NULL);
+ break;
- advance_char (dm);
- RETURN_IF_ERROR (result_add (dm, "construction vtable for "));
+ case 'G':
+ d_advance (di, 1);
+ ret = d_make_comp (di, DEMANGLE_COMPONENT_IMAGINARY,
+ cplus_demangle_type (di), NULL);
+ break;
- /* Demangle the derived type off to the side. */
- RETURN_IF_ERROR (result_push (dm));
- RETURN_IF_ERROR (demangle_type (dm));
- derived_type = (dyn_string_t) result_pop (dm);
+ case 'U':
+ d_advance (di, 1);
+ ret = d_source_name (di);
+ ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
+ cplus_demangle_type (di), ret);
+ break;
- /* Demangle the offset. */
- number = dyn_string_new (4);
- if (number == NULL)
- {
- dyn_string_delete (derived_type);
- return STATUS_ALLOCATION_FAILED;
- }
- demangle_number_literally (dm, number, 10, 1);
- /* Demangle the underscore separator. */
- status = demangle_char (dm, '_');
-
- /* Demangle the base type. */
- if (STATUS_NO_ERROR (status))
- status = demangle_type (dm);
-
- /* Emit the derived type. */
- if (STATUS_NO_ERROR (status))
- status = result_add (dm, "-in-");
- if (STATUS_NO_ERROR (status))
- status = result_add_string (dm, derived_type);
- dyn_string_delete (derived_type);
-
- /* Don't display the offset unless in verbose mode. */
- if (flag_verbose)
- {
- status = result_add_char (dm, ' ');
- if (STATUS_NO_ERROR (status))
- result_add_string (dm, number);
- }
- dyn_string_delete (number);
- RETURN_IF_ERROR (status);
- break;
- }
- /* If flag_strict, fall through. */
+ default:
+ return NULL;
+ }
- default:
- return "Unrecognized <special-name>.";
- }
+ if (can_subst)
+ {
+ if (! d_add_substitution (di, ret))
+ return NULL;
}
- else
- return STATUS_ERROR;
- return STATUS_OK;
+ return ret;
}
-/* Demangles and emits a <ctor-dtor-name>.
-
- <ctor-dtor-name>
- ::= C1 # complete object (in-charge) ctor
- ::= C2 # base object (not-in-charge) ctor
- ::= C3 # complete object (in-charge) allocating ctor
- ::= D0 # deleting (in-charge) dtor
- ::= D1 # complete object (in-charge) dtor
- ::= D2 # base object (not-in-charge) dtor */
-
-static status_t
-demangle_ctor_dtor_name (dm)
- demangling_t dm;
-{
- static const char *const ctor_flavors[] =
- {
- "in-charge",
- "not-in-charge",
- "allocating"
- };
- static const char *const dtor_flavors[] =
- {
- "in-charge deleting",
- "in-charge",
- "not-in-charge"
- };
+/* <CV-qualifiers> ::= [r] [V] [K] */
- int flavor;
- char peek = peek_char (dm);
+static struct demangle_component **
+d_cv_qualifiers (di, pret, member_fn)
+ struct d_info *di;
+ struct demangle_component **pret;
+ int member_fn;
+{
+ char peek;
- DEMANGLE_TRACE ("ctor-dtor-name", dm);
-
- if (peek == 'C')
+ peek = d_peek_char (di);
+ while (peek == 'r' || peek == 'V' || peek == 'K')
{
- /* A constructor name. Consume the C. */
- advance_char (dm);
- flavor = next_char (dm);
- if (flavor < '1' || flavor > '3')
- return "Unrecognized constructor.";
- RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
- switch (flavor)
+ enum demangle_component_type t;
+
+ d_advance (di, 1);
+ if (peek == 'r')
{
- case '1': dm->is_constructor = gnu_v3_complete_object_ctor;
- break;
- case '2': dm->is_constructor = gnu_v3_base_object_ctor;
- break;
- case '3': dm->is_constructor = gnu_v3_complete_object_allocating_ctor;
- break;
+ t = (member_fn
+ ? DEMANGLE_COMPONENT_RESTRICT_THIS
+ : DEMANGLE_COMPONENT_RESTRICT);
+ di->expansion += sizeof "restrict";
}
- /* Print the flavor of the constructor if in verbose mode. */
- if (flag_verbose)
+ else if (peek == 'V')
{
- RETURN_IF_ERROR (result_add (dm, "["));
- RETURN_IF_ERROR (result_add (dm, ctor_flavors[flavor - '1']));
- RETURN_IF_ERROR (result_add_char (dm, ']'));
+ t = (member_fn
+ ? DEMANGLE_COMPONENT_VOLATILE_THIS
+ : DEMANGLE_COMPONENT_VOLATILE);
+ di->expansion += sizeof "volatile";
}
- }
- else if (peek == 'D')
- {
- /* A destructor name. Consume the D. */
- advance_char (dm);
- flavor = next_char (dm);
- if (flavor < '0' || flavor > '2')
- return "Unrecognized destructor.";
- RETURN_IF_ERROR (result_add_char (dm, '~'));
- RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
- switch (flavor)
- {
- case '0': dm->is_destructor = gnu_v3_deleting_dtor;
- break;
- case '1': dm->is_destructor = gnu_v3_complete_object_dtor;
- break;
- case '2': dm->is_destructor = gnu_v3_base_object_dtor;
- break;
- }
- /* Print the flavor of the destructor if in verbose mode. */
- if (flag_verbose)
+ else
{
- RETURN_IF_ERROR (result_add (dm, " ["));
- RETURN_IF_ERROR (result_add (dm, dtor_flavors[flavor - '0']));
- RETURN_IF_ERROR (result_add_char (dm, ']'));
+ t = (member_fn
+ ? DEMANGLE_COMPONENT_CONST_THIS
+ : DEMANGLE_COMPONENT_CONST);
+ di->expansion += sizeof "const";
}
+
+ *pret = d_make_comp (di, t, NULL, NULL);
+ if (*pret == NULL)
+ return NULL;
+ pret = &d_left (*pret);
+
+ peek = d_peek_char (di);
}
- else
- return STATUS_ERROR;
- return STATUS_OK;
+ return pret;
}
-/* Handle pointer, reference, and pointer-to-member cases for
- demangle_type. All consecutive `P's, `R's, and 'M's are joined to
- build a pointer/reference type. We snarf all these, plus the
- following <type>, all at once since we need to know whether we have
- a pointer to data or pointer to function to construct the right
- output syntax. C++'s pointer syntax is hairy.
-
- This function adds substitution candidates for every nested
- pointer/reference type it processes, including the outermost, final
- type, assuming the substitution starts at SUBSTITUTION_START in the
- demangling result. For example, if this function demangles
- `PP3Foo', it will add a substitution for `Foo', `Foo*', and
- `Foo**', in that order.
-
- *INSERT_POS is a quantity used internally, when this function calls
- itself recursively, to figure out where to insert pointer
- punctuation on the way up. On entry to this function, INSERT_POS
- should point to a temporary value, but that value need not be
- initialized.
-
- <type> ::= P <type>
- ::= R <type>
- ::= <pointer-to-member-type>
-
- <pointer-to-member-type> ::= M </class/ type> </member/ type> */
-
-static status_t
-demangle_type_ptr (dm, insert_pos, substitution_start)
- demangling_t dm;
- int *insert_pos;
- int substitution_start;
-{
- status_t status;
- int is_substitution_candidate = 1;
+/* <function-type> ::= F [Y] <bare-function-type> E */
- DEMANGLE_TRACE ("type*", dm);
+static struct demangle_component *
+d_function_type (di)
+ struct d_info *di;
+{
+ struct demangle_component *ret;
- /* Scan forward, collecting pointers and references into symbols,
- until we hit something else. Then emit the type. */
- switch (peek_char (dm))
+ if (d_next_char (di) != 'F')
+ return NULL;
+ if (d_peek_char (di) == 'Y')
{
- case 'P':
- /* A pointer. Snarf the `P'. */
- advance_char (dm);
- /* Demangle the underlying type. */
- RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos,
- substitution_start));
- /* Insert an asterisk where we're told to; it doesn't
- necessarily go at the end. If we're doing Java style output,
- there is no pointer symbol. */
- if (dm->style != DMGL_JAVA)
- RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '*'));
- /* The next (outermost) pointer or reference character should go
- after this one. */
- ++(*insert_pos);
- break;
+ /* Function has C linkage. We don't print this information.
+ FIXME: We should print it in verbose mode. */
+ d_advance (di, 1);
+ }
+ ret = d_bare_function_type (di, 1);
+ if (d_next_char (di) != 'E')
+ return NULL;
+ return ret;
+}
- case 'R':
- /* A reference. Snarf the `R'. */
- advance_char (dm);
- /* Demangle the underlying type. */
- RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos,
- substitution_start));
- /* Insert an ampersand where we're told to; it doesn't
- necessarily go at the end. */
- RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '&'));
- /* The next (outermost) pointer or reference character should go
- after this one. */
- ++(*insert_pos);
- break;
+/* <bare-function-type> ::= <type>+ */
- case 'M':
+static struct demangle_component *
+d_bare_function_type (di, has_return_type)
+ struct d_info *di;
+ int has_return_type;
+{
+ struct demangle_component *return_type;
+ struct demangle_component *tl;
+ struct demangle_component **ptl;
+
+ return_type = NULL;
+ tl = NULL;
+ ptl = &tl;
+ while (1)
{
- /* A pointer-to-member. */
- dyn_string_t class_type;
-
- /* Eat the 'M'. */
- advance_char (dm);
-
- /* Capture the type of which this is a pointer-to-member. */
- RETURN_IF_ERROR (result_push (dm));
- RETURN_IF_ERROR (demangle_type (dm));
- class_type = (dyn_string_t) result_pop (dm);
-
- if (peek_char (dm) == 'F')
- /* A pointer-to-member function. We want output along the
- lines of `void (C::*) (int, int)'. Demangle the function
- type, which would in this case give `void () (int, int)'
- and set *insert_pos to the spot between the first
- parentheses. */
- status = demangle_type_ptr (dm, insert_pos, substitution_start);
- else if (peek_char (dm) == 'A')
- /* A pointer-to-member array variable. We want output that
- looks like `int (Klass::*) [10]'. Demangle the array type
- as `int () [10]', and set *insert_pos to the spot between
- the parentheses. */
- status = demangle_array_type (dm, insert_pos);
+ char peek;
+ struct demangle_component *type;
+
+ peek = d_peek_char (di);
+ if (peek == '\0' || peek == 'E')
+ break;
+ type = cplus_demangle_type (di);
+ if (type == NULL)
+ return NULL;
+ if (has_return_type)
+ {
+ return_type = type;
+ has_return_type = 0;
+ }
else
- {
- /* A pointer-to-member variable. Demangle the type of the
- pointed-to member. */
- status = demangle_type (dm);
- /* Make it pretty. */
- if (STATUS_NO_ERROR (status)
- && !result_previous_char_is_space (dm))
- status = result_add_char (dm, ' ');
- /* The pointer-to-member notation (e.g. `C::*') follows the
- member's type. */
- *insert_pos = result_caret_pos (dm);
+ {
+ *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL);
+ if (*ptl == NULL)
+ return NULL;
+ ptl = &d_right (*ptl);
}
+ }
- /* Build the pointer-to-member notation. */
- if (STATUS_NO_ERROR (status))
- status = result_insert (dm, *insert_pos, "::*");
- if (STATUS_NO_ERROR (status))
- status = result_insert_string (dm, *insert_pos, class_type);
- /* There may be additional levels of (pointer or reference)
- indirection in this type. If so, the `*' and `&' should be
- added after the pointer-to-member notation (e.g. `C::*&' for
- a reference to a pointer-to-member of class C). */
- *insert_pos += dyn_string_length (class_type) + 3;
-
- /* Clean up. */
- dyn_string_delete (class_type);
-
- RETURN_IF_ERROR (status);
+ /* There should be at least one parameter type besides the optional
+ return type. A function which takes no arguments will have a
+ single parameter type void. */
+ if (tl == NULL)
+ return NULL;
+
+ /* If we have a single parameter type void, omit it. */
+ if (d_right (tl) == NULL
+ && d_left (tl)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
+ && d_left (tl)->u.s_builtin.type->print == D_PRINT_VOID)
+ {
+ di->expansion -= d_left (tl)->u.s_builtin.type->len;
+ tl = NULL;
}
- break;
- case 'F':
- /* Ooh, tricky, a pointer-to-function. When we demangle the
- function type, the return type should go at the very
- beginning. */
- *insert_pos = result_caret_pos (dm);
- /* The parentheses indicate this is a function pointer or
- reference type. */
- RETURN_IF_ERROR (result_add (dm, "()"));
- /* Now demangle the function type. The return type will be
- inserted before the `()', and the argument list will go after
- it. */
- RETURN_IF_ERROR (demangle_function_type (dm, insert_pos));
- /* We should now have something along the lines of
- `void () (int, int)'. The pointer or reference characters
- have to inside the first set of parentheses. *insert_pos has
- already been updated to point past the end of the return
- type. Move it one character over so it points inside the
- `()'. */
- ++(*insert_pos);
- break;
+ return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE, return_type, tl);
+}
- case 'A':
- /* An array pointer or reference. demangle_array_type will figure
- out where the asterisks and ampersands go. */
- RETURN_IF_ERROR (demangle_array_type (dm, insert_pos));
- break;
+/* <class-enum-type> ::= <name> */
- default:
- /* No more pointer or reference tokens; this is therefore a
- pointer to data. Finish up by demangling the underlying
- type. */
- RETURN_IF_ERROR (demangle_type (dm));
- /* The pointer or reference characters follow the underlying
- type, as in `int*&'. */
- *insert_pos = result_caret_pos (dm);
- /* Because of the production <type> ::= <substitution>,
- demangle_type will already have added the underlying type as
- a substitution candidate. Don't do it again. */
- is_substitution_candidate = 0;
- break;
- }
-
- if (is_substitution_candidate)
- RETURN_IF_ERROR (substitution_add (dm, substitution_start, 0));
-
- return STATUS_OK;
+static struct demangle_component *
+d_class_enum_type (di)
+ struct d_info *di;
+{
+ return d_name (di);
}
-/* Demangles and emits a <type>.
-
- <type> ::= <builtin-type>
- ::= <function-type>
- ::= <class-enum-type>
- ::= <array-type>
- ::= <pointer-to-member-type>
- ::= <template-param>
- ::= <template-template-param> <template-args>
- ::= <CV-qualifiers> <type>
- ::= P <type> # pointer-to
- ::= R <type> # reference-to
- ::= C <type> # complex pair (C 2000)
- ::= G <type> # imaginary (C 2000)
- ::= U <source-name> <type> # vendor extended type qualifier
- ::= <substitution> */
-
-static status_t
-demangle_type (dm)
- demangling_t dm;
+/* <array-type> ::= A <(positive dimension) number> _ <(element) type>
+ ::= A [<(dimension) expression>] _ <(element) type>
+*/
+
+static struct demangle_component *
+d_array_type (di)
+ struct d_info *di;
{
- int start = substitution_start (dm);
- char peek = peek_char (dm);
- char peek_next;
- int encode_return_type = 0;
- template_arg_list_t old_arg_list = current_template_arg_list (dm);
- int insert_pos;
-
- /* A <type> can be a <substitution>; therefore, this <type> is a
- substitution candidate unless a special condition holds (see
- below). */
- int is_substitution_candidate = 1;
-
- DEMANGLE_TRACE ("type", dm);
-
- /* A <class-enum-type> can start with a digit (a <source-name>), an
- N (a <nested-name>), or a Z (a <local-name>). */
- if (IS_DIGIT ((unsigned char) peek) || peek == 'N' || peek == 'Z')
- RETURN_IF_ERROR (demangle_class_enum_type (dm, &encode_return_type));
- /* Lower-case letters begin <builtin-type>s, except for `r', which
- denotes restrict. */
- else if (peek >= 'a' && peek <= 'z' && peek != 'r')
+ char peek;
+ struct demangle_component *dim;
+
+ if (d_next_char (di) != 'A')
+ return NULL;
+
+ peek = d_peek_char (di);
+ if (peek == '_')
+ dim = NULL;
+ else if (IS_DIGIT (peek))
{
- RETURN_IF_ERROR (demangle_builtin_type (dm));
- /* Built-in types are not substitution candidates. */
- is_substitution_candidate = 0;
- }
- else
- switch (peek)
- {
- case 'r':
- case 'V':
- case 'K':
- /* CV-qualifiers (including restrict). We have to demangle
- them off to the side, since C++ syntax puts them in a funny
- place for qualified pointer and reference types. */
+ const char *s;
+
+ s = d_str (di);
+ do
{
- status_t status;
- dyn_string_t cv_qualifiers = dyn_string_new (24);
- int old_caret_position = result_get_caret (dm);
-
- if (cv_qualifiers == NULL)
- return STATUS_ALLOCATION_FAILED;
-
- /* Decode all adjacent CV qualifiers. */
- demangle_CV_qualifiers (dm, cv_qualifiers);
- /* Emit them, and shift the caret left so that the
- underlying type will be emitted before the qualifiers. */
- status = result_add_string (dm, cv_qualifiers);
- result_shift_caret (dm, -dyn_string_length (cv_qualifiers));
- /* Clean up. */
- dyn_string_delete (cv_qualifiers);
- RETURN_IF_ERROR (status);
- /* Also prepend a blank, if needed. */
- RETURN_IF_ERROR (result_add_char (dm, ' '));
- result_shift_caret (dm, -1);
-
- /* Demangle the underlying type. It will be emitted before
- the CV qualifiers, since we moved the caret. */
- RETURN_IF_ERROR (demangle_type (dm));
-
- /* Put the caret back where it was previously. */
- result_set_caret (dm, old_caret_position);
+ d_advance (di, 1);
+ peek = d_peek_char (di);
}
- break;
-
- case 'F':
- return "Non-pointer or -reference function type.";
+ while (IS_DIGIT (peek));
+ dim = d_make_name (di, s, d_str (di) - s);
+ if (dim == NULL)
+ return NULL;
+ }
+ else
+ {
+ dim = d_expression (di);
+ if (dim == NULL)
+ return NULL;
+ }
- case 'A':
- RETURN_IF_ERROR (demangle_array_type (dm, NULL));
- break;
+ if (d_next_char (di) != '_')
+ return NULL;
- case 'T':
- /* It's either a <template-param> or a
- <template-template-param>. In either case, demangle the
- `T' token first. */
- RETURN_IF_ERROR (demangle_template_param (dm));
+ return d_make_comp (di, DEMANGLE_COMPONENT_ARRAY_TYPE, dim,
+ cplus_demangle_type (di));
+}
- /* Check for a template argument list; if one is found, it's a
- <template-template-param> ::= <template-param>
- ::= <substitution> */
- if (peek_char (dm) == 'I')
- {
- /* Add a substitution candidate. The template parameter
- `T' token is a substitution candidate by itself,
- without the template argument list. */
- RETURN_IF_ERROR (substitution_add (dm, start, encode_return_type));
-
- /* Now demangle the template argument list. */
- RETURN_IF_ERROR (demangle_template_args (dm));
- /* The entire type, including the template template
- parameter and its argument list, will be added as a
- substitution candidate below. */
- }
+/* <pointer-to-member-type> ::= M <(class) type> <(member) type> */
- break;
+static struct demangle_component *
+d_pointer_to_member_type (di)
+ struct d_info *di;
+{
+ struct demangle_component *cl;
+ struct demangle_component *mem;
+ struct demangle_component **pmem;
- case 'S':
- /* First check if this is a special substitution. If it is,
- this is a <class-enum-type>. Special substitutions have a
- letter following the `S'; other substitutions have a digit
- or underscore. */
- peek_next = peek_char_next (dm);
- if (IS_DIGIT (peek_next) || peek_next == '_')
- {
- RETURN_IF_ERROR (demangle_substitution (dm, &encode_return_type));
-
- /* The substituted name may have been a template name.
- Check if template arguments follow, and if so, demangle
- them. */
- if (peek_char (dm) == 'I')
- RETURN_IF_ERROR (demangle_template_args (dm));
- else
- /* A substitution token is not itself a substitution
- candidate. (However, if the substituted template is
- instantiated, the resulting type is.) */
- is_substitution_candidate = 0;
- }
- else
- {
- /* Now some trickiness. We have a special substitution
- here. Often, the special substitution provides the
- name of a template that's subsequently instantiated,
- for instance `SaIcE' => std::allocator<char>. In these
- cases we need to add a substitution candidate for the
- entire <class-enum-type> and thus don't want to clear
- the is_substitution_candidate flag.
-
- However, it's possible that what we have here is a
- substitution token representing an entire type, such as
- `Ss' => std::string. In this case, we mustn't add a
- new substitution candidate for this substitution token.
- To detect this case, remember where the start of the
- substitution token is. */
- const char *next = dm->next;
- /* Now demangle the <class-enum-type>. */
- RETURN_IF_ERROR
- (demangle_class_enum_type (dm, &encode_return_type));
- /* If all that was just demangled is the two-character
- special substitution token, supress the addition of a
- new candidate for it. */
- if (dm->next == next + 2)
- is_substitution_candidate = 0;
- }
+ if (d_next_char (di) != 'M')
+ return NULL;
- break;
+ cl = cplus_demangle_type (di);
+
+ /* The ABI specifies that any type can be a substitution source, and
+ that M is followed by two types, and that when a CV-qualified
+ type is seen both the base type and the CV-qualified types are
+ substitution sources. The ABI also specifies that for a pointer
+ to a CV-qualified member function, the qualifiers are attached to
+ the second type. Given the grammar, a plain reading of the ABI
+ suggests that both the CV-qualified member function and the
+ non-qualified member function are substitution sources. However,
+ g++ does not work that way. g++ treats only the CV-qualified
+ member function as a substitution source. FIXME. So to work
+ with g++, we need to pull off the CV-qualifiers here, in order to
+ avoid calling add_substitution() in cplus_demangle_type(). */
+
+ pmem = d_cv_qualifiers (di, &mem, 1);
+ if (pmem == NULL)
+ return NULL;
+ *pmem = cplus_demangle_type (di);
- case 'P':
- case 'R':
- case 'M':
- RETURN_IF_ERROR (demangle_type_ptr (dm, &insert_pos, start));
- /* demangle_type_ptr adds all applicable substitution
- candidates. */
- is_substitution_candidate = 0;
- break;
+ return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem);
+}
- case 'C':
- /* A C99 complex type. */
- RETURN_IF_ERROR (result_add (dm, "complex "));
- advance_char (dm);
- RETURN_IF_ERROR (demangle_type (dm));
- break;
+/* <template-param> ::= T_
+ ::= T <(parameter-2 non-negative) number> _
+*/
- case 'G':
- /* A C99 imaginary type. */
- RETURN_IF_ERROR (result_add (dm, "imaginary "));
- advance_char (dm);
- RETURN_IF_ERROR (demangle_type (dm));
- break;
+static struct demangle_component *
+d_template_param (di)
+ struct d_info *di;
+{
+ long param;
- case 'U':
- /* Vendor-extended type qualifier. */
- advance_char (dm);
- RETURN_IF_ERROR (demangle_source_name (dm));
- RETURN_IF_ERROR (result_add_char (dm, ' '));
- RETURN_IF_ERROR (demangle_type (dm));
- break;
+ if (d_next_char (di) != 'T')
+ return NULL;
- default:
- return "Unexpected character in <type>.";
- }
+ if (d_peek_char (di) == '_')
+ param = 0;
+ else
+ {
+ param = d_number (di);
+ if (param < 0)
+ return NULL;
+ param += 1;
+ }
- if (is_substitution_candidate)
- /* Add a new substitution for the type. If this type was a
- <template-param>, pass its index since from the point of
- substitutions; a <template-param> token is a substitution
- candidate distinct from the type that is substituted for it. */
- RETURN_IF_ERROR (substitution_add (dm, start, encode_return_type));
+ if (d_next_char (di) != '_')
+ return NULL;
- /* Pop off template argument lists added during mangling of this
- type. */
- pop_to_template_arg_list (dm, old_arg_list);
+ ++di->did_subs;
- return STATUS_OK;
+ return d_make_template_param (di, param);
}
-/* C++ source names of builtin types, indexed by the mangled code
- letter's position in the alphabet ('a' -> 0, 'b' -> 1, etc). */
-static const char *const builtin_type_names[26] =
-{
- "signed char", /* a */
- "bool", /* b */
- "char", /* c */
- "double", /* d */
- "long double", /* e */
- "float", /* f */
- "__float128", /* g */
- "unsigned char", /* h */
- "int", /* i */
- "unsigned", /* j */
- NULL, /* k */
- "long", /* l */
- "unsigned long", /* m */
- "__int128", /* n */
- "unsigned __int128", /* o */
- NULL, /* p */
- NULL, /* q */
- NULL, /* r */
- "short", /* s */
- "unsigned short", /* t */
- NULL, /* u */
- "void", /* v */
- "wchar_t", /* w */
- "long long", /* x */
- "unsigned long long", /* y */
- "..." /* z */
-};
-
-/* Java source names of builtin types. Types that arn't valid in Java
- are also included here - we don't fail if someone attempts to demangle a
- C++ symbol in Java style. */
-static const char *const java_builtin_type_names[26] =
-{
- "signed char", /* a */
- "boolean", /* C++ "bool" */ /* b */
- "byte", /* C++ "char" */ /* c */
- "double", /* d */
- "long double", /* e */
- "float", /* f */
- "__float128", /* g */
- "unsigned char", /* h */
- "int", /* i */
- "unsigned", /* j */
- NULL, /* k */
- "long", /* l */
- "unsigned long", /* m */
- "__int128", /* n */
- "unsigned __int128", /* o */
- NULL, /* p */
- NULL, /* q */
- NULL, /* r */
- "short", /* s */
- "unsigned short", /* t */
- NULL, /* u */
- "void", /* v */
- "char", /* C++ "wchar_t" */ /* w */
- "long", /* C++ "long long" */ /* x */
- "unsigned long long", /* y */
- "..." /* z */
-};
+/* <template-args> ::= I <template-arg>+ E */
-/* Demangles and emits a <builtin-type>.
-
- <builtin-type> ::= v # void
- ::= w # wchar_t
- ::= b # bool
- ::= c # char
- ::= a # signed char
- ::= h # unsigned char
- ::= s # short
- ::= t # unsigned short
- ::= i # int
- ::= j # unsigned int
- ::= l # long
- ::= m # unsigned long
- ::= x # long long, __int64
- ::= y # unsigned long long, __int64
- ::= n # __int128
- ::= o # unsigned __int128
- ::= f # float
- ::= d # double
- ::= e # long double, __float80
- ::= g # __float128
- ::= z # ellipsis
- ::= u <source-name> # vendor extended type */
-
-static status_t
-demangle_builtin_type (dm)
- demangling_t dm;
+static struct demangle_component *
+d_template_args (di)
+ struct d_info *di;
{
+ struct demangle_component *hold_last_name;
+ struct demangle_component *al;
+ struct demangle_component **pal;
- char code = peek_char (dm);
+ /* Preserve the last name we saw--don't let the template arguments
+ clobber it, as that would give us the wrong name for a subsequent
+ constructor or destructor. */
+ hold_last_name = di->last_name;
- DEMANGLE_TRACE ("builtin-type", dm);
+ if (d_next_char (di) != 'I')
+ return NULL;
- if (code == 'u')
+ al = NULL;
+ pal = &al;
+ while (1)
{
- advance_char (dm);
- RETURN_IF_ERROR (demangle_source_name (dm));
- return STATUS_OK;
+ struct demangle_component *a;
+
+ a = d_template_arg (di);
+ if (a == NULL)
+ return NULL;
+
+ *pal = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE_ARGLIST, a, NULL);
+ if (*pal == NULL)
+ return NULL;
+ pal = &d_right (*pal);
+
+ if (d_peek_char (di) == 'E')
+ {
+ d_advance (di, 1);
+ break;
+ }
}
- else if (code >= 'a' && code <= 'z')
+
+ di->last_name = hold_last_name;
+
+ return al;
+}
+
+/* <template-arg> ::= <type>
+ ::= X <expression> E
+ ::= <expr-primary>
+*/
+
+static struct demangle_component *
+d_template_arg (di)
+ struct d_info *di;
+{
+ struct demangle_component *ret;
+
+ switch (d_peek_char (di))
{
- const char *type_name;
- /* Java uses different names for some built-in types. */
- if (dm->style == DMGL_JAVA)
- type_name = java_builtin_type_names[code - 'a'];
- else
- type_name = builtin_type_names[code - 'a'];
- if (type_name == NULL)
- return "Unrecognized <builtin-type> code.";
+ case 'X':
+ d_advance (di, 1);
+ ret = d_expression (di);
+ if (d_next_char (di) != 'E')
+ return NULL;
+ return ret;
- RETURN_IF_ERROR (result_add (dm, type_name));
- advance_char (dm);
- return STATUS_OK;
+ case 'L':
+ return d_expr_primary (di);
+
+ default:
+ return cplus_demangle_type (di);
}
- else
- return "Non-alphabetic <builtin-type> code.";
}
-/* Demangles all consecutive CV-qualifiers (const, volatile, and
- restrict) at the current position. The qualifiers are appended to
- QUALIFIERS. Returns STATUS_OK. */
+/* <expression> ::= <(unary) operator-name> <expression>
+ ::= <(binary) operator-name> <expression> <expression>
+ ::= <(trinary) operator-name> <expression> <expression> <expression>
+ ::= st <type>
+ ::= <template-param>
+ ::= sr <type> <unqualified-name>
+ ::= sr <type> <unqualified-name> <template-args>
+ ::= <expr-primary>
+*/
-static status_t
-demangle_CV_qualifiers (dm, qualifiers)
- demangling_t dm;
- dyn_string_t qualifiers;
+static struct demangle_component *
+d_expression (di)
+ struct d_info *di;
{
- DEMANGLE_TRACE ("CV-qualifiers", dm);
+ char peek;
- while (1)
+ peek = d_peek_char (di);
+ if (peek == 'L')
+ return d_expr_primary (di);
+ else if (peek == 'T')
+ return d_template_param (di);
+ else if (peek == 's' && d_peek_next_char (di) == 'r')
{
- switch (peek_char (dm))
+ struct demangle_component *type;
+ struct demangle_component *name;
+
+ d_advance (di, 2);
+ type = cplus_demangle_type (di);
+ name = d_unqualified_name (di);
+ if (d_peek_char (di) != 'I')
+ return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type, name);
+ else
+ return d_make_comp (di, DEMANGLE_COMPONENT_QUAL_NAME, type,
+ d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, name,
+ d_template_args (di)));
+ }
+ else
+ {
+ struct demangle_component *op;
+ int args;
+
+ op = d_operator_name (di);
+ if (op == NULL)
+ return NULL;
+
+ if (op->type == DEMANGLE_COMPONENT_OPERATOR)
+ di->expansion += op->u.s_operator.op->len - 2;
+
+ if (op->type == DEMANGLE_COMPONENT_OPERATOR
+ && strcmp (op->u.s_operator.op->code, "st") == 0)
+ return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
+ cplus_demangle_type (di));
+
+ switch (op->type)
{
- case 'r':
- if (!dyn_string_append_space (qualifiers))
- return STATUS_ALLOCATION_FAILED;
- if (!dyn_string_append_cstr (qualifiers, "restrict"))
- return STATUS_ALLOCATION_FAILED;
+ default:
+ return NULL;
+ case DEMANGLE_COMPONENT_OPERATOR:
+ args = op->u.s_operator.op->args;
break;
-
- case 'V':
- if (!dyn_string_append_space (qualifiers))
- return STATUS_ALLOCATION_FAILED;
- if (!dyn_string_append_cstr (qualifiers, "volatile"))
- return STATUS_ALLOCATION_FAILED;
+ case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
+ args = op->u.s_extended_operator.args;
break;
-
- case 'K':
- if (!dyn_string_append_space (qualifiers))
- return STATUS_ALLOCATION_FAILED;
- if (!dyn_string_append_cstr (qualifiers, "const"))
- return STATUS_ALLOCATION_FAILED;
+ case DEMANGLE_COMPONENT_CAST:
+ args = 1;
break;
+ }
+ switch (args)
+ {
+ case 1:
+ return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
+ d_expression (di));
+ case 2:
+ {
+ struct demangle_component *left;
+
+ left = d_expression (di);
+ return d_make_comp (di, DEMANGLE_COMPONENT_BINARY, op,
+ d_make_comp (di,
+ DEMANGLE_COMPONENT_BINARY_ARGS,
+ left,
+ d_expression (di)));
+ }
+ case 3:
+ {
+ struct demangle_component *first;
+ struct demangle_component *second;
+
+ first = d_expression (di);
+ second = d_expression (di);
+ return d_make_comp (di, DEMANGLE_COMPONENT_TRINARY, op,
+ d_make_comp (di,
+ DEMANGLE_COMPONENT_TRINARY_ARG1,
+ first,
+ d_make_comp (di,
+ DEMANGLE_COMPONENT_TRINARY_ARG2,
+ second,
+ d_expression (di))));
+ }
default:
- return STATUS_OK;
+ return NULL;
}
-
- advance_char (dm);
}
}
-/* Demangles and emits a <function-type>. *FUNCTION_NAME_POS is the
- position in the result string of the start of the function
- identifier, at which the function's return type will be inserted;
- *FUNCTION_NAME_POS is updated to position past the end of the
- function's return type.
+/* <expr-primary> ::= L <type> <(value) number> E
+ ::= L <type> <(value) float> E
+ ::= L <mangled-name> E
+*/
+
+static struct demangle_component *
+d_expr_primary (di)
+ struct d_info *di;
+{
+ struct demangle_component *ret;
- <function-type> ::= F [Y] <bare-function-type> E */
+ if (d_next_char (di) != 'L')
+ return NULL;
+ if (d_peek_char (di) == '_')
+ ret = cplus_demangle_mangled_name (di, 0);
+ else
+ {
+ struct demangle_component *type;
+ enum demangle_component_type t;
+ const char *s;
+
+ type = cplus_demangle_type (di);
+
+ /* If we have a type we know how to print, we aren't going to
+ print the type name itself. */
+ if (type->type == DEMANGLE_COMPONENT_BUILTIN_TYPE
+ && type->u.s_builtin.type->print != D_PRINT_DEFAULT)
+ di->expansion -= type->u.s_builtin.type->len;
+
+ /* Rather than try to interpret the literal value, we just
+ collect it as a string. Note that it's possible to have a
+ floating point literal here. The ABI specifies that the
+ format of such literals is machine independent. That's fine,
+ but what's not fine is that versions of g++ up to 3.2 with
+ -fabi-version=1 used upper case letters in the hex constant,
+ and dumped out gcc's internal representation. That makes it
+ hard to tell where the constant ends, and hard to dump the
+ constant in any readable form anyhow. We don't attempt to
+ handle these cases. */
+
+ t = DEMANGLE_COMPONENT_LITERAL;
+ if (d_peek_char (di) == 'n')
+ {
+ t = DEMANGLE_COMPONENT_LITERAL_NEG;
+ d_advance (di, 1);
+ }
+ s = d_str (di);
+ while (d_peek_char (di) != 'E')
+ d_advance (di, 1);
+ ret = d_make_comp (di, t, type, d_make_name (di, s, d_str (di) - s));
+ }
+ if (d_next_char (di) != 'E')
+ return NULL;
+ return ret;
+}
-static status_t
-demangle_function_type (dm, function_name_pos)
- demangling_t dm;
- int *function_name_pos;
+/* <local-name> ::= Z <(function) encoding> E <(entity) name> [<discriminator>]
+ ::= Z <(function) encoding> E s [<discriminator>]
+*/
+
+static struct demangle_component *
+d_local_name (di)
+ struct d_info *di;
{
- DEMANGLE_TRACE ("function-type", dm);
- RETURN_IF_ERROR (demangle_char (dm, 'F'));
- if (peek_char (dm) == 'Y')
+ struct demangle_component *function;
+
+ if (d_next_char (di) != 'Z')
+ return NULL;
+
+ function = d_encoding (di, 0);
+
+ if (d_next_char (di) != 'E')
+ return NULL;
+
+ if (d_peek_char (di) == 's')
{
- /* Indicate this function has C linkage if in verbose mode. */
- if (flag_verbose)
- RETURN_IF_ERROR (result_add (dm, " [extern \"C\"] "));
- advance_char (dm);
+ d_advance (di, 1);
+ if (! d_discriminator (di))
+ return NULL;
+ return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function,
+ d_make_name (di, "string literal",
+ sizeof "string literal" - 1));
}
- RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
- RETURN_IF_ERROR (demangle_char (dm, 'E'));
- return STATUS_OK;
+ else
+ {
+ struct demangle_component *name;
+
+ name = d_name (di);
+ if (! d_discriminator (di))
+ return NULL;
+ return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function, name);
+ }
+}
+
+/* <discriminator> ::= _ <(non-negative) number>
+
+ We demangle the discriminator, but we don't print it out. FIXME:
+ We should print it out in verbose mode. */
+
+static int
+d_discriminator (di)
+ struct d_info *di;
+{
+ long discrim;
+
+ if (d_peek_char (di) != '_')
+ return 1;
+ d_advance (di, 1);
+ discrim = d_number (di);
+ if (discrim < 0)
+ return 0;
+ return 1;
+}
+
+/* Add a new substitution. */
+
+static int
+d_add_substitution (di, dc)
+ struct d_info *di;
+ struct demangle_component *dc;
+{
+ if (dc == NULL)
+ return 0;
+ if (di->next_sub >= di->num_subs)
+ return 0;
+ di->subs[di->next_sub] = dc;
+ ++di->next_sub;
+ return 1;
}
-/* Demangles and emits a <bare-function-type>. RETURN_TYPE_POS is the
- position in the result string at which the function return type
- should be inserted. If RETURN_TYPE_POS is BFT_NO_RETURN_TYPE, the
- function's return type is assumed not to be encoded.
+/* <substitution> ::= S <seq-id> _
+ ::= S_
+ ::= St
+ ::= Sa
+ ::= Sb
+ ::= Ss
+ ::= Si
+ ::= So
+ ::= Sd
+
+ If PREFIX is non-zero, then this type is being used as a prefix in
+ a qualified name. In this case, for the standard substitutions, we
+ need to check whether we are being used as a prefix for a
+ constructor or destructor, and return a full template name.
+ Otherwise we will get something like std::iostream::~iostream()
+ which does not correspond particularly well to any function which
+ actually appears in the source.
+*/
- <bare-function-type> ::= <signature type>+ */
+static const struct d_standard_sub_info standard_subs[] =
+{
+ { 't', NL ("std"),
+ NL ("std"),
+ NULL, 0 },
+ { 'a', NL ("std::allocator"),
+ NL ("std::allocator"),
+ NL ("allocator") },
+ { 'b', NL ("std::basic_string"),
+ NL ("std::basic_string"),
+ NL ("basic_string") },
+ { 's', NL ("std::string"),
+ NL ("std::basic_string<char, std::char_traits<char>, std::allocator<char> >"),
+ NL ("basic_string") },
+ { 'i', NL ("std::istream"),
+ NL ("std::basic_istream<char, std::char_traits<char> >"),
+ NL ("basic_istream") },
+ { 'o', NL ("std::ostream"),
+ NL ("std::basic_ostream<char, std::char_traits<char> >"),
+ NL ("basic_ostream") },
+ { 'd', NL ("std::iostream"),
+ NL ("std::basic_iostream<char, std::char_traits<char> >"),
+ NL ("basic_iostream") }
+};
-static status_t
-demangle_bare_function_type (dm, return_type_pos)
- demangling_t dm;
- int *return_type_pos;
+static struct demangle_component *
+d_substitution (di, prefix)
+ struct d_info *di;
+ int prefix;
{
- /* Sequence is the index of the current function parameter, counting
- from zero. The value -1 denotes the return type. */
- int sequence =
- (return_type_pos == BFT_NO_RETURN_TYPE ? 0 : -1);
+ char c;
- DEMANGLE_TRACE ("bare-function-type", dm);
+ if (d_next_char (di) != 'S')
+ return NULL;
- RETURN_IF_ERROR (result_add_char (dm, '('));
- while (!end_of_name_p (dm) && peek_char (dm) != 'E')
+ c = d_next_char (di);
+ if (c == '_' || IS_DIGIT (c) || IS_UPPER (c))
{
- if (sequence == -1)
- /* We're decoding the function's return type. */
+ int id;
+
+ id = 0;
+ if (c != '_')
{
- dyn_string_t return_type;
- status_t status = STATUS_OK;
-
- /* Decode the return type off to the side. */
- RETURN_IF_ERROR (result_push (dm));
- RETURN_IF_ERROR (demangle_type (dm));
- return_type = (dyn_string_t) result_pop (dm);
-
- /* Add a space to the end of the type. Insert the return
- type where we've been asked to. */
- if (!dyn_string_append_space (return_type))
- status = STATUS_ALLOCATION_FAILED;
- if (STATUS_NO_ERROR (status))
+ do
{
- if (!dyn_string_insert (result_string (dm), *return_type_pos,
- return_type))
- status = STATUS_ALLOCATION_FAILED;
+ if (IS_DIGIT (c))
+ id = id * 36 + c - '0';
+ else if (IS_UPPER (c))
+ id = id * 36 + c - 'A' + 10;
else
- *return_type_pos += dyn_string_length (return_type);
+ return NULL;
+ c = d_next_char (di);
}
+ while (c != '_');
- dyn_string_delete (return_type);
- RETURN_IF_ERROR (status);
+ ++id;
}
- else
+
+ if (id >= di->next_sub)
+ return NULL;
+
+ ++di->did_subs;
+
+ return di->subs[id];
+ }
+ else
+ {
+ int verbose;
+ const struct d_standard_sub_info *p;
+ const struct d_standard_sub_info *pend;
+
+ verbose = (di->options & DMGL_VERBOSE) != 0;
+ if (! verbose && prefix)
{
- /* Skip `void' parameter types. One should only occur as
- the only type in a parameter list; in that case, we want
- to print `foo ()' instead of `foo (void)'. */
- if (peek_char (dm) == 'v')
- /* Consume the v. */
- advance_char (dm);
- else
+ char peek;
+
+ peek = d_peek_char (di);
+ if (peek == 'C' || peek == 'D')
+ verbose = 1;
+ }
+
+ pend = (&standard_subs[0]
+ + sizeof standard_subs / sizeof standard_subs[0]);
+ for (p = &standard_subs[0]; p < pend; ++p)
+ {
+ if (c == p->code)
{
- /* Separate parameter types by commas. */
- if (sequence > 0)
- RETURN_IF_ERROR (result_add (dm, ", "));
- /* Demangle the type. */
- RETURN_IF_ERROR (demangle_type (dm));
+ const char *s;
+ int len;
+
+ if (p->set_last_name != NULL)
+ di->last_name = d_make_sub (di, p->set_last_name,
+ p->set_last_name_len);
+ if (verbose)
+ {
+ s = p->full_expansion;
+ len = p->full_len;
+ }
+ else
+ {
+ s = p->simple_expansion;
+ len = p->simple_len;
+ }
+ di->expansion += len;
+ return d_make_sub (di, s, len);
}
}
- ++sequence;
+ return NULL;
}
- RETURN_IF_ERROR (result_add_char (dm, ')'));
+}
- /* We should have demangled at least one parameter type (which would
- be void, for a function that takes no parameters), plus the
- return type, if we were supposed to demangle that. */
- if (sequence == -1)
- return "Missing function return type.";
- else if (sequence == 0)
- return "Missing function parameter.";
+/* Resize the print buffer. */
- return STATUS_OK;
-}
+static void
+d_print_resize (dpi, add)
+ struct d_print_info *dpi;
+ size_t add;
+{
+ size_t need;
-/* Demangles and emits a <class-enum-type>. *ENCODE_RETURN_TYPE is set to
- non-zero if the type is a template-id, zero otherwise.
+ if (dpi->buf == NULL)
+ return;
+ need = dpi->len + add;
+ while (need > dpi->alc)
+ {
+ size_t newalc;
+ char *newbuf;
+
+ newalc = dpi->alc * 2;
+ newbuf = realloc (dpi->buf, newalc);
+ if (newbuf == NULL)
+ {
+ free (dpi->buf);
+ dpi->buf = NULL;
+ dpi->allocation_failure = 1;
+ return;
+ }
+ dpi->buf = newbuf;
+ dpi->alc = newalc;
+ }
+}
- <class-enum-type> ::= <name> */
+/* Append a character to the print buffer. */
-static status_t
-demangle_class_enum_type (dm, encode_return_type)
- demangling_t dm;
- int *encode_return_type;
+static void
+d_print_append_char (dpi, c)
+ struct d_print_info *dpi;
+ int c;
{
- DEMANGLE_TRACE ("class-enum-type", dm);
+ if (dpi->buf != NULL)
+ {
+ if (dpi->len >= dpi->alc)
+ {
+ d_print_resize (dpi, 1);
+ if (dpi->buf == NULL)
+ return;
+ }
- RETURN_IF_ERROR (demangle_name (dm, encode_return_type));
- return STATUS_OK;
+ dpi->buf[dpi->len] = c;
+ ++dpi->len;
+ }
}
-/* Demangles and emits an <array-type>.
+/* Append a buffer to the print buffer. */
- If PTR_INSERT_POS is not NULL, the array type is formatted as a
- pointer or reference to an array, except that asterisk and
- ampersand punctuation is omitted (since it's not know at this
- point). *PTR_INSERT_POS is set to the position in the demangled
- name at which this punctuation should be inserted. For example,
- `A10_i' is demangled to `int () [10]' and *PTR_INSERT_POS points
- between the parentheses.
+static void
+d_print_append_buffer (dpi, s, l)
+ struct d_print_info *dpi;
+ const char *s;
+ size_t l;
+{
+ if (dpi->buf != NULL)
+ {
+ if (dpi->len + l > dpi->alc)
+ {
+ d_print_resize (dpi, l);
+ if (dpi->buf == NULL)
+ return;
+ }
- If PTR_INSERT_POS is NULL, the array type is assumed not to be
- pointer- or reference-qualified. Then, for example, `A10_i' is
- demangled simply as `int[10]'.
+ memcpy (dpi->buf + dpi->len, s, l);
+ dpi->len += l;
+ }
+}
- <array-type> ::= A [<dimension number>] _ <element type>
- ::= A <dimension expression> _ <element type> */
+/* Indicate that an error occurred during printing. */
-static status_t
-demangle_array_type (dm, ptr_insert_pos)
- demangling_t dm;
- int *ptr_insert_pos;
+static void
+d_print_error (dpi)
+ struct d_print_info *dpi;
{
- status_t status = STATUS_OK;
- dyn_string_t array_size = NULL;
- char peek;
+ free (dpi->buf);
+ dpi->buf = NULL;
+}
+
+/* Turn components into a human readable string. OPTIONS is the
+ options bits passed to the demangler. DC is the tree to print.
+ ESTIMATE is a guess at the length of the result. This returns a
+ string allocated by malloc, or NULL on error. On success, this
+ sets *PALC to the size of the allocated buffer. On failure, this
+ sets *PALC to 0 for a bad parse, or to 1 for a memory allocation
+ failure. */
- DEMANGLE_TRACE ("array-type", dm);
+CP_STATIC_IF_GLIBCPP_V3
+char *
+cplus_demangle_print (options, dc, estimate, palc)
+ int options;
+ const struct demangle_component *dc;
+ int estimate;
+ size_t *palc;
+{
+ struct d_print_info dpi;
- RETURN_IF_ERROR (demangle_char (dm, 'A'));
+ dpi.options = options;
- /* Demangle the array size into array_size. */
- peek = peek_char (dm);
- if (peek == '_')
- /* Array bound is omitted. This is a C99-style VLA. */
- ;
- else if (IS_DIGIT (peek_char (dm)))
+ dpi.alc = estimate + 1;
+ dpi.buf = malloc (dpi.alc);
+ if (dpi.buf == NULL)
{
- /* It looks like a constant array bound. */
- array_size = dyn_string_new (10);
- if (array_size == NULL)
- return STATUS_ALLOCATION_FAILED;
- status = demangle_number_literally (dm, array_size, 10, 0);
+ *palc = 1;
+ return NULL;
}
+
+ dpi.len = 0;
+ dpi.templates = NULL;
+ dpi.modifiers = NULL;
+
+ dpi.allocation_failure = 0;
+
+ d_print_comp (&dpi, dc);
+
+ d_append_char (&dpi, '\0');
+
+ if (dpi.buf != NULL)
+ *palc = dpi.alc;
else
- {
- /* Anything is must be an expression for a nont-constant array
- bound. This happens if the array type occurs in a template
- and the array bound references a template parameter. */
- RETURN_IF_ERROR (result_push (dm));
- RETURN_IF_ERROR (demangle_expression (dm));
- array_size = (dyn_string_t) result_pop (dm);
- }
- /* array_size may have been allocated by now, so we can't use
- RETURN_IF_ERROR until it's been deallocated. */
+ *palc = dpi.allocation_failure;
- /* Demangle the base type of the array. */
- if (STATUS_NO_ERROR (status))
- status = demangle_char (dm, '_');
- if (STATUS_NO_ERROR (status))
- status = demangle_type (dm);
+ return dpi.buf;
+}
+
+/* Subroutine to handle components. */
- if (ptr_insert_pos != NULL)
+static void
+d_print_comp (dpi, dc)
+ struct d_print_info *dpi;
+ const struct demangle_component *dc;
+{
+ if (dc == NULL)
{
- /* This array is actually part of an pointer- or
- reference-to-array type. Format appropriately, except we
- don't know which and how much punctuation to use. */
- if (STATUS_NO_ERROR (status))
- status = result_add (dm, " () ");
- /* Let the caller know where to insert the punctuation. */
- *ptr_insert_pos = result_caret_pos (dm) - 2;
+ d_print_error (dpi);
+ return;
}
+ if (d_print_saw_error (dpi))
+ return;
- /* Emit the array dimension syntax. */
- if (STATUS_NO_ERROR (status))
- status = result_add_char (dm, '[');
- if (STATUS_NO_ERROR (status) && array_size != NULL)
- status = result_add_string (dm, array_size);
- if (STATUS_NO_ERROR (status))
- status = result_add_char (dm, ']');
- if (array_size != NULL)
- dyn_string_delete (array_size);
-
- RETURN_IF_ERROR (status);
-
- return STATUS_OK;
-}
+ switch (dc->type)
+ {
+ case DEMANGLE_COMPONENT_NAME:
+ if ((dpi->options & DMGL_JAVA) == 0)
+ d_append_buffer (dpi, dc->u.s_name.s, dc->u.s_name.len);
+ else
+ d_print_java_identifier (dpi, dc->u.s_name.s, dc->u.s_name.len);
+ return;
+
+ case DEMANGLE_COMPONENT_QUAL_NAME:
+ case DEMANGLE_COMPONENT_LOCAL_NAME:
+ d_print_comp (dpi, d_left (dc));
+ if ((dpi->options & DMGL_JAVA) == 0)
+ d_append_string_constant (dpi, "::");
+ else
+ d_append_char (dpi, '.');
+ d_print_comp (dpi, d_right (dc));
+ return;
-/* Demangles and emits a <template-param>.
+ case DEMANGLE_COMPONENT_TYPED_NAME:
+ {
+ struct d_print_mod *hold_modifiers;
+ struct demangle_component *typed_name;
+ struct d_print_mod adpm[4];
+ unsigned int i;
+ struct d_print_template dpt;
+
+ /* Pass the name down to the type so that it can be printed in
+ the right place for the type. We also have to pass down
+ any CV-qualifiers, which apply to the this parameter. */
+ hold_modifiers = dpi->modifiers;
+ i = 0;
+ typed_name = d_left (dc);
+ while (typed_name != NULL)
+ {
+ if (i >= sizeof adpm / sizeof adpm[0])
+ {
+ d_print_error (dpi);
+ return;
+ }
+
+ adpm[i].next = dpi->modifiers;
+ dpi->modifiers = &adpm[i];
+ adpm[i].mod = typed_name;
+ adpm[i].printed = 0;
+ adpm[i].templates = dpi->templates;
+ ++i;
+
+ if (typed_name->type != DEMANGLE_COMPONENT_RESTRICT_THIS
+ && typed_name->type != DEMANGLE_COMPONENT_VOLATILE_THIS
+ && typed_name->type != DEMANGLE_COMPONENT_CONST_THIS)
+ break;
- <template-param> ::= T_ # first template parameter
- ::= T <parameter-2 number> _ */
+ typed_name = d_left (typed_name);
+ }
-static status_t
-demangle_template_param (dm)
- demangling_t dm;
-{
- int parm_number;
- template_arg_list_t current_arg_list = current_template_arg_list (dm);
- string_list_t arg;
+ /* If typed_name is a template, then it applies to the
+ function type as well. */
+ if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE)
+ {
+ dpt.next = dpi->templates;
+ dpi->templates = &dpt;
+ dpt.template = typed_name;
+ }
- DEMANGLE_TRACE ("template-param", dm);
+ /* If typed_name is a DEMANGLE_COMPONENT_LOCAL_NAME, then
+ there may be CV-qualifiers on its right argument which
+ really apply here; this happens when parsing a class which
+ is local to a function. */
+ if (typed_name->type == DEMANGLE_COMPONENT_LOCAL_NAME)
+ {
+ struct demangle_component *local_name;
+
+ local_name = d_right (typed_name);
+ while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS
+ || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS
+ || local_name->type == DEMANGLE_COMPONENT_CONST_THIS)
+ {
+ if (i >= sizeof adpm / sizeof adpm[0])
+ {
+ d_print_error (dpi);
+ return;
+ }
+
+ adpm[i] = adpm[i - 1];
+ adpm[i].next = &adpm[i - 1];
+ dpi->modifiers = &adpm[i];
+
+ adpm[i - 1].mod = local_name;
+ adpm[i - 1].printed = 0;
+ adpm[i - 1].templates = dpi->templates;
+ ++i;
+
+ local_name = d_left (local_name);
+ }
+ }
- /* Make sure there is a template argmust list in which to look up
- this parameter reference. */
- if (current_arg_list == NULL)
- return "Template parameter outside of template.";
+ d_print_comp (dpi, d_right (dc));
- RETURN_IF_ERROR (demangle_char (dm, 'T'));
- if (peek_char (dm) == '_')
- parm_number = 0;
- else
- {
- RETURN_IF_ERROR (demangle_number (dm, &parm_number, 10, 0));
- ++parm_number;
- }
- RETURN_IF_ERROR (demangle_char (dm, '_'));
+ if (typed_name->type == DEMANGLE_COMPONENT_TEMPLATE)
+ dpi->templates = dpt.next;
- arg = template_arg_list_get_arg (current_arg_list, parm_number);
- if (arg == NULL)
- /* parm_number exceeded the number of arguments in the current
- template argument list. */
- return "Template parameter number out of bounds.";
- RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
+ /* If the modifiers didn't get printed by the type, print them
+ now. */
+ while (i > 0)
+ {
+ --i;
+ if (! adpm[i].printed)
+ {
+ d_append_char (dpi, ' ');
+ d_print_mod (dpi, adpm[i].mod);
+ }
+ }
- return STATUS_OK;
-}
+ dpi->modifiers = hold_modifiers;
-/* Demangles and emits a <template-args>.
+ return;
+ }
- <template-args> ::= I <template-arg>+ E */
+ case DEMANGLE_COMPONENT_TEMPLATE:
+ {
+ struct d_print_mod *hold_dpm;
-static status_t
-demangle_template_args (dm)
- demangling_t dm;
-{
- int first = 1;
- dyn_string_t old_last_source_name;
- template_arg_list_t arg_list = template_arg_list_new ();
+ /* Don't push modifiers into a template definition. Doing so
+ could give the wrong definition for a template argument.
+ Instead, treat the template essentially as a name. */
- if (arg_list == NULL)
- return STATUS_ALLOCATION_FAILED;
+ hold_dpm = dpi->modifiers;
+ dpi->modifiers = NULL;
- /* Preserve the most recently demangled source name. */
- old_last_source_name = dm->last_source_name;
- dm->last_source_name = dyn_string_new (0);
+ d_print_comp (dpi, d_left (dc));
+ if (d_last_char (dpi) == '<')
+ d_append_char (dpi, ' ');
+ d_append_char (dpi, '<');
+ d_print_comp (dpi, d_right (dc));
+ /* Avoid generating two consecutive '>' characters, to avoid
+ the C++ syntactic ambiguity. */
+ if (d_last_char (dpi) == '>')
+ d_append_char (dpi, ' ');
+ d_append_char (dpi, '>');
- DEMANGLE_TRACE ("template-args", dm);
+ dpi->modifiers = hold_dpm;
- if (dm->last_source_name == NULL)
- return STATUS_ALLOCATION_FAILED;
+ return;
+ }
- RETURN_IF_ERROR (demangle_char (dm, 'I'));
- RETURN_IF_ERROR (result_open_template_list (dm));
- do
- {
- string_list_t arg;
+ case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
+ {
+ long i;
+ struct demangle_component *a;
+ struct d_print_template *hold_dpt;
- if (first)
- first = 0;
+ if (dpi->templates == NULL)
+ {
+ d_print_error (dpi);
+ return;
+ }
+ i = dc->u.s_number.number;
+ for (a = d_right (dpi->templates->template);
+ a != NULL;
+ a = d_right (a))
+ {
+ if (a->type != DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
+ {
+ d_print_error (dpi);
+ return;
+ }
+ if (i <= 0)
+ break;
+ --i;
+ }
+ if (i != 0 || a == NULL)
+ {
+ d_print_error (dpi);
+ return;
+ }
+
+ /* While processing this parameter, we need to pop the list of
+ templates. This is because the template parameter may
+ itself be a reference to a parameter of an outer
+ template. */
+
+ hold_dpt = dpi->templates;
+ dpi->templates = hold_dpt->next;
+
+ d_print_comp (dpi, d_left (a));
+
+ dpi->templates = hold_dpt;
+
+ return;
+ }
+
+ case DEMANGLE_COMPONENT_CTOR:
+ d_print_comp (dpi, dc->u.s_ctor.name);
+ return;
+
+ case DEMANGLE_COMPONENT_DTOR:
+ d_append_char (dpi, '~');
+ d_print_comp (dpi, dc->u.s_dtor.name);
+ return;
+
+ case DEMANGLE_COMPONENT_VTABLE:
+ d_append_string_constant (dpi, "vtable for ");
+ d_print_comp (dpi, d_left (dc));
+ return;
+
+ case DEMANGLE_COMPONENT_VTT:
+ d_append_string_constant (dpi, "VTT for ");
+ d_print_comp (dpi, d_left (dc));
+ return;
+
+ case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
+ d_append_string_constant (dpi, "construction vtable for ");
+ d_print_comp (dpi, d_left (dc));
+ d_append_string_constant (dpi, "-in-");
+ d_print_comp (dpi, d_right (dc));
+ return;
+
+ case DEMANGLE_COMPONENT_TYPEINFO:
+ d_append_string_constant (dpi, "typeinfo for ");
+ d_print_comp (dpi, d_left (dc));
+ return;
+
+ case DEMANGLE_COMPONENT_TYPEINFO_NAME:
+ d_append_string_constant (dpi, "typeinfo name for ");
+ d_print_comp (dpi, d_left (dc));
+ return;
+
+ case DEMANGLE_COMPONENT_TYPEINFO_FN:
+ d_append_string_constant (dpi, "typeinfo fn for ");
+ d_print_comp (dpi, d_left (dc));
+ return;
+
+ case DEMANGLE_COMPONENT_THUNK:
+ d_append_string_constant (dpi, "non-virtual thunk to ");
+ d_print_comp (dpi, d_left (dc));
+ return;
+
+ case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
+ d_append_string_constant (dpi, "virtual thunk to ");
+ d_print_comp (dpi, d_left (dc));
+ return;
+
+ case DEMANGLE_COMPONENT_COVARIANT_THUNK:
+ d_append_string_constant (dpi, "covariant return thunk to ");
+ d_print_comp (dpi, d_left (dc));
+ return;
+
+ case DEMANGLE_COMPONENT_JAVA_CLASS:
+ d_append_string_constant (dpi, "java Class for ");
+ d_print_comp (dpi, d_left (dc));
+ return;
+
+ case DEMANGLE_COMPONENT_GUARD:
+ d_append_string_constant (dpi, "guard variable for ");
+ d_print_comp (dpi, d_left (dc));
+ return;
+
+ case DEMANGLE_COMPONENT_REFTEMP:
+ d_append_string_constant (dpi, "reference temporary for ");
+ d_print_comp (dpi, d_left (dc));
+ return;
+
+ case DEMANGLE_COMPONENT_SUB_STD:
+ d_append_buffer (dpi, dc->u.s_string.string, dc->u.s_string.len);
+ return;
+
+ case DEMANGLE_COMPONENT_RESTRICT:
+ case DEMANGLE_COMPONENT_VOLATILE:
+ case DEMANGLE_COMPONENT_CONST:
+ {
+ struct d_print_mod *pdpm;
+
+ /* When printing arrays, it's possible to have cases where the
+ same CV-qualifier gets pushed on the stack multiple times.
+ We only need to print it once. */
+
+ for (pdpm = dpi->modifiers; pdpm != NULL; pdpm = pdpm->next)
+ {
+ if (! pdpm->printed)
+ {
+ if (pdpm->mod->type != DEMANGLE_COMPONENT_RESTRICT
+ && pdpm->mod->type != DEMANGLE_COMPONENT_VOLATILE
+ && pdpm->mod->type != DEMANGLE_COMPONENT_CONST)
+ break;
+ if (pdpm->mod->type == dc->type)
+ {
+ d_print_comp (dpi, d_left (dc));
+ return;
+ }
+ }
+ }
+ }
+ /* Fall through. */
+ case DEMANGLE_COMPONENT_RESTRICT_THIS:
+ case DEMANGLE_COMPONENT_VOLATILE_THIS:
+ case DEMANGLE_COMPONENT_CONST_THIS:
+ case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
+ case DEMANGLE_COMPONENT_POINTER:
+ case DEMANGLE_COMPONENT_REFERENCE:
+ case DEMANGLE_COMPONENT_COMPLEX:
+ case DEMANGLE_COMPONENT_IMAGINARY:
+ {
+ /* We keep a list of modifiers on the stack. */
+ struct d_print_mod dpm;
+
+ dpm.next = dpi->modifiers;
+ dpi->modifiers = &dpm;
+ dpm.mod = dc;
+ dpm.printed = 0;
+ dpm.templates = dpi->templates;
+
+ d_print_comp (dpi, d_left (dc));
+
+ /* If the modifier didn't get printed by the type, print it
+ now. */
+ if (! dpm.printed)
+ d_print_mod (dpi, dc);
+
+ dpi->modifiers = dpm.next;
+
+ return;
+ }
+
+ case DEMANGLE_COMPONENT_BUILTIN_TYPE:
+ if ((dpi->options & DMGL_JAVA) == 0)
+ d_append_buffer (dpi, dc->u.s_builtin.type->name,
+ dc->u.s_builtin.type->len);
else
- RETURN_IF_ERROR (result_add (dm, ", "));
+ d_append_buffer (dpi, dc->u.s_builtin.type->java_name,
+ dc->u.s_builtin.type->java_len);
+ return;
- /* Capture the template arg. */
- RETURN_IF_ERROR (result_push (dm));
- RETURN_IF_ERROR (demangle_template_arg (dm));
- arg = result_pop (dm);
+ case DEMANGLE_COMPONENT_VENDOR_TYPE:
+ d_print_comp (dpi, d_left (dc));
+ return;
- /* Emit it in the demangled name. */
- RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
+ case DEMANGLE_COMPONENT_FUNCTION_TYPE:
+ {
+ if (d_left (dc) != NULL)
+ {
+ struct d_print_mod dpm;
- /* Save it for use in expanding <template-param>s. */
- template_arg_list_add_arg (arg_list, arg);
- }
- while (peek_char (dm) != 'E');
- /* Append the '>'. */
- RETURN_IF_ERROR (result_close_template_list (dm));
+ /* We must pass this type down as a modifier in order to
+ print it in the right location. */
- /* Consume the 'E'. */
- advance_char (dm);
+ dpm.next = dpi->modifiers;
+ dpi->modifiers = &dpm;
+ dpm.mod = dc;
+ dpm.printed = 0;
+ dpm.templates = dpi->templates;
- /* Restore the most recent demangled source name. */
- dyn_string_delete (dm->last_source_name);
- dm->last_source_name = old_last_source_name;
+ d_print_comp (dpi, d_left (dc));
- /* Push the list onto the top of the stack of template argument
- lists, so that arguments from it are used from now on when
- expanding <template-param>s. */
- push_template_arg_list (dm, arg_list);
+ dpi->modifiers = dpm.next;
- return STATUS_OK;
-}
+ if (dpm.printed)
+ return;
-/* This function, which does not correspond to a production in the
- mangling spec, handles the `literal' production for both
- <template-arg> and <expr-primary>. It does not expect or consume
- the initial `L' or final `E'. The demangling is given by:
+ d_append_char (dpi, ' ');
+ }
- <literal> ::= <type> </value/ number>
+ d_print_function_type (dpi, dc, dpi->modifiers);
- and the emitted output is `(type)number'. */
+ return;
+ }
-static status_t
-demangle_literal (dm)
- demangling_t dm;
-{
- char peek = peek_char (dm);
- dyn_string_t value_string;
- status_t status;
+ case DEMANGLE_COMPONENT_ARRAY_TYPE:
+ {
+ struct d_print_mod *hold_modifiers;
+ struct d_print_mod adpm[4];
+ unsigned int i;
+ struct d_print_mod *pdpm;
+
+ /* We must pass this type down as a modifier in order to print
+ multi-dimensional arrays correctly. If the array itself is
+ CV-qualified, we act as though the element type were
+ CV-qualified. We do this by copying the modifiers down
+ rather than fiddling pointers, so that we don't wind up
+ with a d_print_mod higher on the stack pointing into our
+ stack frame after we return. */
+
+ hold_modifiers = dpi->modifiers;
+
+ adpm[0].next = hold_modifiers;
+ dpi->modifiers = &adpm[0];
+ adpm[0].mod = dc;
+ adpm[0].printed = 0;
+ adpm[0].templates = dpi->templates;
+
+ i = 1;
+ pdpm = hold_modifiers;
+ while (pdpm != NULL
+ && (pdpm->mod->type == DEMANGLE_COMPONENT_RESTRICT
+ || pdpm->mod->type == DEMANGLE_COMPONENT_VOLATILE
+ || pdpm->mod->type == DEMANGLE_COMPONENT_CONST))
+ {
+ if (! pdpm->printed)
+ {
+ if (i >= sizeof adpm / sizeof adpm[0])
+ {
+ d_print_error (dpi);
+ return;
+ }
+
+ adpm[i] = *pdpm;
+ adpm[i].next = dpi->modifiers;
+ dpi->modifiers = &adpm[i];
+ pdpm->printed = 1;
+ ++i;
+ }
+
+ pdpm = pdpm->next;
+ }
- DEMANGLE_TRACE ("literal", dm);
+ d_print_comp (dpi, d_right (dc));
- if (!flag_verbose && peek >= 'a' && peek <= 'z')
- {
- /* If not in verbose mode and this is a builtin type, see if we
- can produce simpler numerical output. In particular, for
- integer types shorter than `long', just write the number
- without type information; for bools, write `true' or `false'.
- Other refinements could be made here too. */
-
- /* This constant string is used to map from <builtin-type> codes
- (26 letters of the alphabet) to codes that determine how the
- value will be displayed. The codes are:
- b: display as bool
- i: display as int
- l: display as long
- A space means the value will be represented using cast
- notation. */
- static const char *const code_map = "ibi iii ll ii i ";
-
- char code = code_map[peek - 'a'];
- /* FIXME: Implement demangling of floats and doubles. */
- if (code == 'u')
- return STATUS_UNIMPLEMENTED;
- if (code == 'b')
- {
- /* It's a boolean. */
- char value;
-
- /* Consume the b. */
- advance_char (dm);
- /* Look at the next character. It should be 0 or 1,
- corresponding to false or true, respectively. */
- value = peek_char (dm);
- if (value == '0')
- RETURN_IF_ERROR (result_add (dm, "false"));
- else if (value == '1')
- RETURN_IF_ERROR (result_add (dm, "true"));
- else
- return "Unrecognized bool constant.";
- /* Consume the 0 or 1. */
- advance_char (dm);
- return STATUS_OK;
- }
- else if (code == 'i' || code == 'l')
- {
- /* It's an integer or long. */
-
- /* Consume the type character. */
- advance_char (dm);
-
- /* Demangle the number and write it out. */
- value_string = dyn_string_new (0);
- status = demangle_number_literally (dm, value_string, 10, 1);
- if (STATUS_NO_ERROR (status))
- status = result_add_string (dm, value_string);
- /* For long integers, append an l. */
- if (code == 'l' && STATUS_NO_ERROR (status))
- status = result_add_char (dm, code);
- dyn_string_delete (value_string);
-
- RETURN_IF_ERROR (status);
- return STATUS_OK;
- }
- /* ...else code == ' ', so fall through to represent this
- literal's type explicitly using cast syntax. */
- }
+ dpi->modifiers = hold_modifiers;
- RETURN_IF_ERROR (result_add_char (dm, '('));
- RETURN_IF_ERROR (demangle_type (dm));
- RETURN_IF_ERROR (result_add_char (dm, ')'));
+ if (adpm[0].printed)
+ return;
- value_string = dyn_string_new (0);
- if (value_string == NULL)
- return STATUS_ALLOCATION_FAILED;
+ while (i > 1)
+ {
+ --i;
+ d_print_mod (dpi, adpm[i].mod);
+ }
- status = demangle_number_literally (dm, value_string, 10, 1);
- if (STATUS_NO_ERROR (status))
- status = result_add_string (dm, value_string);
- dyn_string_delete (value_string);
- RETURN_IF_ERROR (status);
+ d_print_array_type (dpi, dc, dpi->modifiers);
- return STATUS_OK;
-}
+ return;
+ }
-/* Demangles and emits a <template-arg>.
+ case DEMANGLE_COMPONENT_PTRMEM_TYPE:
+ {
+ struct d_print_mod dpm;
- <template-arg> ::= <type> # type
- ::= L <type> <value number> E # literal
- ::= LZ <encoding> E # external name
- ::= X <expression> E # expression */
+ dpm.next = dpi->modifiers;
+ dpi->modifiers = &dpm;
+ dpm.mod = dc;
+ dpm.printed = 0;
+ dpm.templates = dpi->templates;
-static status_t
-demangle_template_arg (dm)
- demangling_t dm;
-{
- DEMANGLE_TRACE ("template-arg", dm);
+ d_print_comp (dpi, d_right (dc));
- switch (peek_char (dm))
- {
- case 'L':
- advance_char (dm);
+ /* If the modifier didn't get printed by the type, print it
+ now. */
+ if (! dpm.printed)
+ {
+ d_append_char (dpi, ' ');
+ d_print_comp (dpi, d_left (dc));
+ d_append_string_constant (dpi, "::*");
+ }
+
+ dpi->modifiers = dpm.next;
- if (peek_char (dm) == 'Z')
+ return;
+ }
+
+ case DEMANGLE_COMPONENT_ARGLIST:
+ case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
+ d_print_comp (dpi, d_left (dc));
+ if (d_right (dc) != NULL)
{
- /* External name. */
- advance_char (dm);
- /* FIXME: Standard is contradictory here. */
- RETURN_IF_ERROR (demangle_encoding (dm));
+ d_append_string_constant (dpi, ", ");
+ d_print_comp (dpi, d_right (dc));
}
+ return;
+
+ case DEMANGLE_COMPONENT_OPERATOR:
+ {
+ char c;
+
+ d_append_string_constant (dpi, "operator");
+ c = dc->u.s_operator.op->name[0];
+ if (IS_LOWER (c))
+ d_append_char (dpi, ' ');
+ d_append_buffer (dpi, dc->u.s_operator.op->name,
+ dc->u.s_operator.op->len);
+ return;
+ }
+
+ case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
+ d_append_string_constant (dpi, "operator ");
+ d_print_comp (dpi, dc->u.s_extended_operator.name);
+ return;
+
+ case DEMANGLE_COMPONENT_CAST:
+ d_append_string_constant (dpi, "operator ");
+ d_print_cast (dpi, dc);
+ return;
+
+ case DEMANGLE_COMPONENT_UNARY:
+ if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST)
+ d_print_expr_op (dpi, d_left (dc));
else
- RETURN_IF_ERROR (demangle_literal (dm));
- RETURN_IF_ERROR (demangle_char (dm, 'E'));
- break;
+ {
+ d_append_char (dpi, '(');
+ d_print_cast (dpi, d_left (dc));
+ d_append_char (dpi, ')');
+ }
+ d_append_char (dpi, '(');
+ d_print_comp (dpi, d_right (dc));
+ d_append_char (dpi, ')');
+ return;
- case 'X':
- /* Expression. */
- advance_char (dm);
- RETURN_IF_ERROR (demangle_expression (dm));
- RETURN_IF_ERROR (demangle_char (dm, 'E'));
- break;
+ case DEMANGLE_COMPONENT_BINARY:
+ if (d_right (dc)->type != DEMANGLE_COMPONENT_BINARY_ARGS)
+ {
+ d_print_error (dpi);
+ return;
+ }
+
+ /* We wrap an expression which uses the greater-than operator in
+ an extra layer of parens so that it does not get confused
+ with the '>' which ends the template parameters. */
+ if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
+ && d_left (dc)->u.s_operator.op->len == 1
+ && d_left (dc)->u.s_operator.op->name[0] == '>')
+ d_append_char (dpi, '(');
+
+ d_append_char (dpi, '(');
+ d_print_comp (dpi, d_left (d_right (dc)));
+ d_append_string_constant (dpi, ") ");
+ d_print_expr_op (dpi, d_left (dc));
+ d_append_string_constant (dpi, " (");
+ d_print_comp (dpi, d_right (d_right (dc)));
+ d_append_char (dpi, ')');
+
+ if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
+ && d_left (dc)->u.s_operator.op->len == 1
+ && d_left (dc)->u.s_operator.op->name[0] == '>')
+ d_append_char (dpi, ')');
+
+ return;
+
+ case DEMANGLE_COMPONENT_BINARY_ARGS:
+ /* We should only see this as part of DEMANGLE_COMPONENT_BINARY. */
+ d_print_error (dpi);
+ return;
+
+ case DEMANGLE_COMPONENT_TRINARY:
+ if (d_right (dc)->type != DEMANGLE_COMPONENT_TRINARY_ARG1
+ || d_right (d_right (dc))->type != DEMANGLE_COMPONENT_TRINARY_ARG2)
+ {
+ d_print_error (dpi);
+ return;
+ }
+ d_append_char (dpi, '(');
+ d_print_comp (dpi, d_left (d_right (dc)));
+ d_append_string_constant (dpi, ") ");
+ d_print_expr_op (dpi, d_left (dc));
+ d_append_string_constant (dpi, " (");
+ d_print_comp (dpi, d_left (d_right (d_right (dc))));
+ d_append_string_constant (dpi, ") : (");
+ d_print_comp (dpi, d_right (d_right (d_right (dc))));
+ d_append_char (dpi, ')');
+ return;
+
+ case DEMANGLE_COMPONENT_TRINARY_ARG1:
+ case DEMANGLE_COMPONENT_TRINARY_ARG2:
+ /* We should only see these are part of DEMANGLE_COMPONENT_TRINARY. */
+ d_print_error (dpi);
+ return;
+
+ case DEMANGLE_COMPONENT_LITERAL:
+ case DEMANGLE_COMPONENT_LITERAL_NEG:
+ {
+ enum d_builtin_type_print tp;
+
+ /* For some builtin types, produce simpler output. */
+ tp = D_PRINT_DEFAULT;
+ if (d_left (dc)->type == DEMANGLE_COMPONENT_BUILTIN_TYPE)
+ {
+ tp = d_left (dc)->u.s_builtin.type->print;
+ switch (tp)
+ {
+ case D_PRINT_INT:
+ case D_PRINT_UNSIGNED:
+ case D_PRINT_LONG:
+ case D_PRINT_UNSIGNED_LONG:
+ case D_PRINT_LONG_LONG:
+ case D_PRINT_UNSIGNED_LONG_LONG:
+ if (d_right (dc)->type == DEMANGLE_COMPONENT_NAME)
+ {
+ if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG)
+ d_append_char (dpi, '-');
+ d_print_comp (dpi, d_right (dc));
+ switch (tp)
+ {
+ default:
+ break;
+ case D_PRINT_UNSIGNED:
+ d_append_char (dpi, 'u');
+ break;
+ case D_PRINT_LONG:
+ d_append_char (dpi, 'l');
+ break;
+ case D_PRINT_UNSIGNED_LONG:
+ d_append_string_constant (dpi, "ul");
+ break;
+ case D_PRINT_LONG_LONG:
+ d_append_string_constant (dpi, "ll");
+ break;
+ case D_PRINT_UNSIGNED_LONG_LONG:
+ d_append_string_constant (dpi, "ull");
+ break;
+ }
+ return;
+ }
+ break;
+
+ case D_PRINT_BOOL:
+ if (d_right (dc)->type == DEMANGLE_COMPONENT_NAME
+ && d_right (dc)->u.s_name.len == 1
+ && dc->type == DEMANGLE_COMPONENT_LITERAL)
+ {
+ switch (d_right (dc)->u.s_name.s[0])
+ {
+ case '0':
+ d_append_string_constant (dpi, "false");
+ return;
+ case '1':
+ d_append_string_constant (dpi, "true");
+ return;
+ default:
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ d_append_char (dpi, '(');
+ d_print_comp (dpi, d_left (dc));
+ d_append_char (dpi, ')');
+ if (dc->type == DEMANGLE_COMPONENT_LITERAL_NEG)
+ d_append_char (dpi, '-');
+ if (tp == D_PRINT_FLOAT)
+ d_append_char (dpi, '[');
+ d_print_comp (dpi, d_right (dc));
+ if (tp == D_PRINT_FLOAT)
+ d_append_char (dpi, ']');
+ }
+ return;
default:
- RETURN_IF_ERROR (demangle_type (dm));
- break;
+ d_print_error (dpi);
+ return;
}
-
- return STATUS_OK;
}
-/* Demangles and emits an <expression>.
+/* Print a Java dentifier. For Java we try to handle encoded extended
+ Unicode characters. The C++ ABI doesn't mention Unicode encoding,
+ so we don't it for C++. Characters are encoded as
+ __U<hex-char>+_. */
- <expression> ::= <unary operator-name> <expression>
- ::= <binary operator-name> <expression> <expression>
- ::= <expr-primary>
- ::= <scope-expression> */
-
-static status_t
-demangle_expression (dm)
- demangling_t dm;
+static void
+d_print_java_identifier (dpi, name, len)
+ struct d_print_info *dpi;
+ const char *name;
+ int len;
{
- char peek = peek_char (dm);
-
- DEMANGLE_TRACE ("expression", dm);
+ const char *p;
+ const char *end;
- if (peek == 'L' || peek == 'T')
- RETURN_IF_ERROR (demangle_expr_primary (dm));
- else if (peek == 's' && peek_char_next (dm) == 'r')
- RETURN_IF_ERROR (demangle_scope_expression (dm));
- else
- /* An operator expression. */
+ end = name + len;
+ for (p = name; p < end; ++p)
{
- int num_args;
- int type_arg;
- status_t status = STATUS_OK;
- dyn_string_t operator_name;
-
- /* We have an operator name. Since we want to output binary
- operations in infix notation, capture the operator name
- first. */
- RETURN_IF_ERROR (result_push (dm));
- RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args,
- &type_arg));
- operator_name = (dyn_string_t) result_pop (dm);
-
- /* If it's binary, do an operand first. */
- if (num_args > 1)
+ if (end - p > 3
+ && p[0] == '_'
+ && p[1] == '_'
+ && p[2] == 'U')
{
- status = result_add_char (dm, '(');
- if (STATUS_NO_ERROR (status))
- status = demangle_expression (dm);
- if (STATUS_NO_ERROR (status))
- status = result_add_char (dm, ')');
- }
+ unsigned long c;
+ const char *q;
- /* Emit the operator. */
- if (STATUS_NO_ERROR (status))
- status = result_add_string (dm, operator_name);
- dyn_string_delete (operator_name);
- RETURN_IF_ERROR (status);
-
- /* Emit its second (if binary) or only (if unary) operand. */
- RETURN_IF_ERROR (result_add_char (dm, '('));
- if (type_arg)
- RETURN_IF_ERROR (demangle_type (dm));
- else
- RETURN_IF_ERROR (demangle_expression (dm));
- RETURN_IF_ERROR (result_add_char (dm, ')'));
+ c = 0;
+ for (q = p + 3; q < end; ++q)
+ {
+ int dig;
+
+ if (IS_DIGIT (*q))
+ dig = *q - '0';
+ else if (*q >= 'A' && *q <= 'F')
+ dig = *q - 'A' + 10;
+ else if (*q >= 'a' && *q <= 'f')
+ dig = *q - 'a' + 10;
+ else
+ break;
- /* The ternary operator takes a third operand. */
- if (num_args == 3)
- {
- RETURN_IF_ERROR (result_add (dm, ":("));
- RETURN_IF_ERROR (demangle_expression (dm));
- RETURN_IF_ERROR (result_add_char (dm, ')'));
+ c = c * 16 + dig;
+ }
+ /* If the Unicode character is larger than 256, we don't try
+ to deal with it here. FIXME. */
+ if (q < end && *q == '_' && c < 256)
+ {
+ d_append_char (dpi, c);
+ p = q;
+ continue;
+ }
}
- }
- return STATUS_OK;
+ d_append_char (dpi, *p);
+ }
}
-/* Demangles and emits a <scope-expression>.
-
- <scope-expression> ::= sr <qualifying type> <source-name>
- ::= sr <qualifying type> <encoding> */
+/* Print a list of modifiers. SUFFIX is 1 if we are printing
+ qualifiers on this after printing a function. */
-static status_t
-demangle_scope_expression (dm)
- demangling_t dm;
+static void
+d_print_mod_list (dpi, mods, suffix)
+ struct d_print_info *dpi;
+ struct d_print_mod *mods;
+ int suffix;
{
- RETURN_IF_ERROR (demangle_char (dm, 's'));
- RETURN_IF_ERROR (demangle_char (dm, 'r'));
- RETURN_IF_ERROR (demangle_type (dm));
- RETURN_IF_ERROR (result_add (dm, "::"));
- RETURN_IF_ERROR (demangle_encoding (dm));
- return STATUS_OK;
-}
+ struct d_print_template *hold_dpt;
-/* Demangles and emits an <expr-primary>.
+ if (mods == NULL || d_print_saw_error (dpi))
+ return;
- <expr-primary> ::= <template-param>
- ::= L <type> <value number> E # literal
- ::= L <mangled-name> E # external name */
+ if (mods->printed
+ || (! suffix
+ && (mods->mod->type == DEMANGLE_COMPONENT_RESTRICT_THIS
+ || mods->mod->type == DEMANGLE_COMPONENT_VOLATILE_THIS
+ || mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS)))
+ {
+ d_print_mod_list (dpi, mods->next, suffix);
+ return;
+ }
-static status_t
-demangle_expr_primary (dm)
- demangling_t dm;
-{
- char peek = peek_char (dm);
+ mods->printed = 1;
- DEMANGLE_TRACE ("expr-primary", dm);
+ hold_dpt = dpi->templates;
+ dpi->templates = mods->templates;
- if (peek == 'T')
- RETURN_IF_ERROR (demangle_template_param (dm));
- else if (peek == 'L')
+ if (mods->mod->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
+ {
+ d_print_function_type (dpi, mods->mod, mods->next);
+ dpi->templates = hold_dpt;
+ return;
+ }
+ else if (mods->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE)
+ {
+ d_print_array_type (dpi, mods->mod, mods->next);
+ dpi->templates = hold_dpt;
+ return;
+ }
+ else if (mods->mod->type == DEMANGLE_COMPONENT_LOCAL_NAME)
{
- /* Consume the `L'. */
- advance_char (dm);
- peek = peek_char (dm);
+ struct d_print_mod *hold_modifiers;
+ struct demangle_component *dc;
+
+ /* When this is on the modifier stack, we have pulled any
+ qualifiers off the right argument already. Otherwise, we
+ print it as usual, but don't let the left argument see any
+ modifiers. */
+
+ hold_modifiers = dpi->modifiers;
+ dpi->modifiers = NULL;
+ d_print_comp (dpi, d_left (mods->mod));
+ dpi->modifiers = hold_modifiers;
- if (peek == '_')
- RETURN_IF_ERROR (demangle_mangled_name (dm));
+ if ((dpi->options & DMGL_JAVA) == 0)
+ d_append_string_constant (dpi, "::");
else
- RETURN_IF_ERROR (demangle_literal (dm));
+ d_append_char (dpi, '.');
+
+ dc = d_right (mods->mod);
+ while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
+ || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
+ || dc->type == DEMANGLE_COMPONENT_CONST_THIS)
+ dc = d_left (dc);
+
+ d_print_comp (dpi, dc);
- RETURN_IF_ERROR (demangle_char (dm, 'E'));
+ dpi->templates = hold_dpt;
+ return;
}
- else
- return STATUS_ERROR;
- return STATUS_OK;
+ d_print_mod (dpi, mods->mod);
+
+ dpi->templates = hold_dpt;
+
+ d_print_mod_list (dpi, mods->next, suffix);
}
-/* Demangles and emits a <substitution>. Sets *TEMPLATE_P to non-zero
- if the substitution is the name of a template, zero otherwise.
-
- <substitution> ::= S <seq-id> _
- ::= S_
-
- ::= St # ::std::
- ::= Sa # ::std::allocator
- ::= Sb # ::std::basic_string
- ::= Ss # ::std::basic_string<char,
- ::std::char_traits<char>,
- ::std::allocator<char> >
- ::= Si # ::std::basic_istream<char,
- std::char_traits<char> >
- ::= So # ::std::basic_ostream<char,
- std::char_traits<char> >
- ::= Sd # ::std::basic_iostream<char,
- std::char_traits<char> >
-*/
+/* Print a modifier. */
-static status_t
-demangle_substitution (dm, template_p)
- demangling_t dm;
- int *template_p;
+static void
+d_print_mod (dpi, mod)
+ struct d_print_info *dpi;
+ const struct demangle_component *mod;
{
- int seq_id;
- int peek;
- dyn_string_t text;
-
- DEMANGLE_TRACE ("substitution", dm);
+ switch (mod->type)
+ {
+ case DEMANGLE_COMPONENT_RESTRICT:
+ case DEMANGLE_COMPONENT_RESTRICT_THIS:
+ d_append_string_constant (dpi, " restrict");
+ return;
+ case DEMANGLE_COMPONENT_VOLATILE:
+ case DEMANGLE_COMPONENT_VOLATILE_THIS:
+ d_append_string_constant (dpi, " volatile");
+ return;
+ case DEMANGLE_COMPONENT_CONST:
+ case DEMANGLE_COMPONENT_CONST_THIS:
+ d_append_string_constant (dpi, " const");
+ return;
+ case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
+ d_append_char (dpi, ' ');
+ d_print_comp (dpi, d_right (mod));
+ return;
+ case DEMANGLE_COMPONENT_POINTER:
+ /* There is no pointer symbol in Java. */
+ if ((dpi->options & DMGL_JAVA) == 0)
+ d_append_char (dpi, '*');
+ return;
+ case DEMANGLE_COMPONENT_REFERENCE:
+ d_append_char (dpi, '&');
+ return;
+ case DEMANGLE_COMPONENT_COMPLEX:
+ d_append_string_constant (dpi, "complex ");
+ return;
+ case DEMANGLE_COMPONENT_IMAGINARY:
+ d_append_string_constant (dpi, "imaginary ");
+ return;
+ case DEMANGLE_COMPONENT_PTRMEM_TYPE:
+ if (d_last_char (dpi) != '(')
+ d_append_char (dpi, ' ');
+ d_print_comp (dpi, d_left (mod));
+ d_append_string_constant (dpi, "::*");
+ return;
+ case DEMANGLE_COMPONENT_TYPED_NAME:
+ d_print_comp (dpi, d_left (mod));
+ return;
+ default:
+ /* Otherwise, we have something that won't go back on the
+ modifier stack, so we can just print it. */
+ d_print_comp (dpi, mod);
+ return;
+ }
+}
- RETURN_IF_ERROR (demangle_char (dm, 'S'));
+/* Print a function type, except for the return type. */
- /* Scan the substitution sequence index. A missing number denotes
- the first index. */
- peek = peek_char (dm);
- if (peek == '_')
- seq_id = -1;
- /* If the following character is 0-9 or a capital letter, interpret
- the sequence up to the next underscore as a base-36 substitution
- index. */
- else if (IS_DIGIT ((unsigned char) peek)
- || (peek >= 'A' && peek <= 'Z'))
- RETURN_IF_ERROR (demangle_number (dm, &seq_id, 36, 0));
- else
+static void
+d_print_function_type (dpi, dc, mods)
+ struct d_print_info *dpi;
+ const struct demangle_component *dc;
+ struct d_print_mod *mods;
+{
+ int need_paren;
+ int saw_mod;
+ int need_space;
+ struct d_print_mod *p;
+ struct d_print_mod *hold_modifiers;
+
+ need_paren = 0;
+ saw_mod = 0;
+ need_space = 0;
+ for (p = mods; p != NULL; p = p->next)
{
- const char *new_last_source_name = NULL;
+ if (p->printed)
+ break;
- switch (peek)
+ saw_mod = 1;
+ switch (p->mod->type)
{
- case 't':
- RETURN_IF_ERROR (result_add (dm, "std"));
+ case DEMANGLE_COMPONENT_POINTER:
+ case DEMANGLE_COMPONENT_REFERENCE:
+ need_paren = 1;
break;
-
- case 'a':
- RETURN_IF_ERROR (result_add (dm, "std::allocator"));
- new_last_source_name = "allocator";
- *template_p = 1;
+ case DEMANGLE_COMPONENT_RESTRICT:
+ case DEMANGLE_COMPONENT_VOLATILE:
+ case DEMANGLE_COMPONENT_CONST:
+ case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
+ case DEMANGLE_COMPONENT_COMPLEX:
+ case DEMANGLE_COMPONENT_IMAGINARY:
+ case DEMANGLE_COMPONENT_PTRMEM_TYPE:
+ need_space = 1;
+ need_paren = 1;
break;
-
- case 'b':
- RETURN_IF_ERROR (result_add (dm, "std::basic_string"));
- new_last_source_name = "basic_string";
- *template_p = 1;
+ case DEMANGLE_COMPONENT_RESTRICT_THIS:
+ case DEMANGLE_COMPONENT_VOLATILE_THIS:
+ case DEMANGLE_COMPONENT_CONST_THIS:
break;
-
- case 's':
- if (!flag_verbose)
- {
- RETURN_IF_ERROR (result_add (dm, "std::string"));
- new_last_source_name = "string";
- }
- else
- {
- RETURN_IF_ERROR (result_add (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
- new_last_source_name = "basic_string";
- }
- *template_p = 0;
+ default:
break;
+ }
+ if (need_paren)
+ break;
+ }
- case 'i':
- if (!flag_verbose)
- {
- RETURN_IF_ERROR (result_add (dm, "std::istream"));
- new_last_source_name = "istream";
- }
- else
- {
- RETURN_IF_ERROR (result_add (dm, "std::basic_istream<char, std::char_traits<char> >"));
- new_last_source_name = "basic_istream";
- }
- *template_p = 0;
- break;
+ if (d_left (dc) != NULL && ! saw_mod)
+ need_paren = 1;
- case 'o':
- if (!flag_verbose)
- {
- RETURN_IF_ERROR (result_add (dm, "std::ostream"));
- new_last_source_name = "ostream";
- }
- else
- {
- RETURN_IF_ERROR (result_add (dm, "std::basic_ostream<char, std::char_traits<char> >"));
- new_last_source_name = "basic_ostream";
- }
- *template_p = 0;
- break;
+ if (need_paren)
+ {
+ if (! need_space)
+ {
+ if (d_last_char (dpi) != '('
+ && d_last_char (dpi) != '*')
+ need_space = 1;
+ }
+ if (need_space && d_last_char (dpi) != ' ')
+ d_append_char (dpi, ' ');
+ d_append_char (dpi, '(');
+ }
- case 'd':
- if (!flag_verbose)
- {
- RETURN_IF_ERROR (result_add (dm, "std::iostream"));
- new_last_source_name = "iostream";
- }
- else
- {
- RETURN_IF_ERROR (result_add (dm, "std::basic_iostream<char, std::char_traits<char> >"));
- new_last_source_name = "basic_iostream";
- }
- *template_p = 0;
- break;
+ hold_modifiers = dpi->modifiers;
+ dpi->modifiers = NULL;
- default:
- return "Unrecognized <substitution>.";
- }
-
- /* Consume the character we just processed. */
- advance_char (dm);
+ d_print_mod_list (dpi, mods, 0);
+
+ if (need_paren)
+ d_append_char (dpi, ')');
+
+ d_append_char (dpi, '(');
+
+ if (d_right (dc) != NULL)
+ d_print_comp (dpi, d_right (dc));
+
+ d_append_char (dpi, ')');
+
+ d_print_mod_list (dpi, mods, 1);
- if (new_last_source_name != NULL)
+ dpi->modifiers = hold_modifiers;
+}
+
+/* Print an array type, except for the element type. */
+
+static void
+d_print_array_type (dpi, dc, mods)
+ struct d_print_info *dpi;
+ const struct demangle_component *dc;
+ struct d_print_mod *mods;
+{
+ int need_space;
+
+ need_space = 1;
+ if (mods != NULL)
+ {
+ int need_paren;
+ struct d_print_mod *p;
+
+ need_paren = 0;
+ for (p = mods; p != NULL; p = p->next)
{
- if (!dyn_string_copy_cstr (dm->last_source_name,
- new_last_source_name))
- return STATUS_ALLOCATION_FAILED;
+ if (! p->printed)
+ {
+ if (p->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE)
+ {
+ need_space = 0;
+ break;
+ }
+ else
+ {
+ need_paren = 1;
+ need_space = 1;
+ break;
+ }
+ }
}
- return STATUS_OK;
+ if (need_paren)
+ d_append_string_constant (dpi, " (");
+
+ d_print_mod_list (dpi, mods, 0);
+
+ if (need_paren)
+ d_append_char (dpi, ')');
}
- /* Look up the substitution text. Since `S_' is the most recent
- substitution, `S0_' is the second-most-recent, etc., shift the
- numbering by one. */
- text = substitution_get (dm, seq_id + 1, template_p);
- if (text == NULL)
- return "Substitution number out of range.";
+ if (need_space)
+ d_append_char (dpi, ' ');
- /* Emit the substitution text. */
- RETURN_IF_ERROR (result_add_string (dm, text));
+ d_append_char (dpi, '[');
- RETURN_IF_ERROR (demangle_char (dm, '_'));
- return STATUS_OK;
-}
+ if (d_left (dc) != NULL)
+ d_print_comp (dpi, d_left (dc));
-/* Demangles and emits a <local-name>.
+ d_append_char (dpi, ']');
+}
- <local-name> := Z <function encoding> E <entity name> [<discriminator>]
- := Z <function encoding> E s [<discriminator>] */
+/* Print an operator in an expression. */
-static status_t
-demangle_local_name (dm)
- demangling_t dm;
+static void
+d_print_expr_op (dpi, dc)
+ struct d_print_info *dpi;
+ const struct demangle_component *dc;
{
- DEMANGLE_TRACE ("local-name", dm);
+ if (dc->type == DEMANGLE_COMPONENT_OPERATOR)
+ d_append_buffer (dpi, dc->u.s_operator.op->name,
+ dc->u.s_operator.op->len);
+ else
+ d_print_comp (dpi, dc);
+}
- RETURN_IF_ERROR (demangle_char (dm, 'Z'));
- RETURN_IF_ERROR (demangle_encoding (dm));
- RETURN_IF_ERROR (demangle_char (dm, 'E'));
- RETURN_IF_ERROR (result_add (dm, "::"));
+/* Print a cast. */
- if (peek_char (dm) == 's')
- {
- /* Local character string literal. */
- RETURN_IF_ERROR (result_add (dm, "string literal"));
- /* Consume the s. */
- advance_char (dm);
- RETURN_IF_ERROR (demangle_discriminator (dm, 0));
- }
+static void
+d_print_cast (dpi, dc)
+ struct d_print_info *dpi;
+ const struct demangle_component *dc;
+{
+ if (d_left (dc)->type != DEMANGLE_COMPONENT_TEMPLATE)
+ d_print_comp (dpi, d_left (dc));
else
{
- int unused;
- /* Local name for some other entity. Demangle its name. */
- RETURN_IF_ERROR (demangle_name (dm, &unused));
- RETURN_IF_ERROR (demangle_discriminator (dm, 1));
- }
-
- return STATUS_OK;
- }
-
- /* Optimonally demangles and emits a <discriminator>. If there is no
- <discriminator> at the current position in the mangled string, the
- descriminator is assumed to be zero. Emit the discriminator number
- in parentheses, unless SUPPRESS_FIRST is non-zero and the
- discriminator is zero.
-
- <discriminator> ::= _ <number> */
-
-static status_t
-demangle_discriminator (dm, suppress_first)
- demangling_t dm;
- int suppress_first;
-{
- /* Output for <discriminator>s to the demangled name is completely
- suppressed if not in verbose mode. */
+ struct d_print_mod *hold_dpm;
+ struct d_print_template dpt;
- if (peek_char (dm) == '_')
- {
- /* Consume the underscore. */
- advance_char (dm);
- if (flag_verbose)
- RETURN_IF_ERROR (result_add (dm, " [#"));
- /* Check if there's a number following the underscore. */
- if (IS_DIGIT ((unsigned char) peek_char (dm)))
- {
- int discriminator;
- /* Demangle the number. */
- RETURN_IF_ERROR (demangle_number (dm, &discriminator, 10, 0));
- if (flag_verbose)
- /* Write the discriminator. The mangled number is two
- less than the discriminator ordinal, counting from
- zero. */
- RETURN_IF_ERROR (int_to_dyn_string (discriminator + 1,
- (dyn_string_t) dm->result));
- }
- else
- return STATUS_ERROR;
- if (flag_verbose)
- RETURN_IF_ERROR (result_add_char (dm, ']'));
- }
- else if (!suppress_first)
- {
- if (flag_verbose)
- RETURN_IF_ERROR (result_add (dm, " [#0]"));
+ /* It appears that for a templated cast operator, we need to put
+ the template parameters in scope for the operator name, but
+ not for the parameters. The effect is that we need to handle
+ the template printing here. */
+
+ hold_dpm = dpi->modifiers;
+ dpi->modifiers = NULL;
+
+ dpt.next = dpi->templates;
+ dpi->templates = &dpt;
+ dpt.template = d_left (dc);
+
+ d_print_comp (dpi, d_left (d_left (dc)));
+
+ dpi->templates = dpt.next;
+
+ if (d_last_char (dpi) == '<')
+ d_append_char (dpi, ' ');
+ d_append_char (dpi, '<');
+ d_print_comp (dpi, d_right (d_left (dc)));
+ /* Avoid generating two consecutive '>' characters, to avoid
+ the C++ syntactic ambiguity. */
+ if (d_last_char (dpi) == '>')
+ d_append_char (dpi, ' ');
+ d_append_char (dpi, '>');
+
+ dpi->modifiers = hold_dpm;
}
+}
+
+/* Initialize the information structure we use to pass around
+ information. */
+
+CP_STATIC_IF_GLIBCPP_V3
+void
+cplus_demangle_init_info (mangled, options, len, di)
+ const char *mangled;
+ int options;
+ size_t len;
+ struct d_info *di;
+{
+ di->s = mangled;
+ di->send = mangled + len;
+ di->options = options;
- return STATUS_OK;
+ di->n = mangled;
+
+ /* We can not need more components than twice the number of chars in
+ the mangled string. Most components correspond directly to
+ chars, but the ARGLIST types are exceptions. */
+ di->num_comps = 2 * len;
+ di->next_comp = 0;
+
+ /* Similarly, we can not need more substitutions than there are
+ chars in the mangled string. */
+ di->num_subs = len;
+ di->next_sub = 0;
+ di->did_subs = 0;
+
+ di->last_name = NULL;
+
+ di->expansion = 0;
}
-/* Demangle NAME into RESULT, which must be an initialized
- dyn_string_t. On success, returns STATUS_OK. On failure, returns
- an error message, and the contents of RESULT are unchanged. */
+/* Entry point for the demangler. If MANGLED is a g++ v3 ABI mangled
+ name, return a buffer allocated with malloc holding the demangled
+ name. OPTIONS is the usual libiberty demangler options. On
+ success, this sets *PALC to the allocated size of the returned
+ buffer. On failure, this sets *PALC to 0 for a bad name, or 1 for
+ a memory allocation failure. On failure, this returns NULL. */
-static status_t
-cp_demangle (name, result, style)
- const char *name;
- dyn_string_t result;
- int style;
+static char *
+d_demangle (mangled, options, palc)
+ const char* mangled;
+ int options;
+ size_t *palc;
{
- status_t status;
- int length = strlen (name);
+ size_t len;
+ int type;
+ struct d_info di;
+ struct demangle_component *dc;
+ int estimate;
+ char *ret;
- if (length > 2 && name[0] == '_' && name[1] == 'Z')
- {
- demangling_t dm = demangling_new (name, style);
- if (dm == NULL)
- return STATUS_ALLOCATION_FAILED;
+ *palc = 0;
- status = result_push (dm);
- if (status != STATUS_OK)
- {
- demangling_delete (dm);
- return status;
- }
+ len = strlen (mangled);
- status = demangle_mangled_name (dm);
- if (STATUS_NO_ERROR (status))
+ if (mangled[0] == '_' && mangled[1] == 'Z')
+ type = 0;
+ else if (strncmp (mangled, "_GLOBAL_", 8) == 0
+ && (mangled[8] == '.' || mangled[8] == '_' || mangled[8] == '$')
+ && (mangled[9] == 'D' || mangled[9] == 'I')
+ && mangled[10] == '_')
+ {
+ char *r;
+
+ r = malloc (40 + len - 11);
+ if (r == NULL)
+ *palc = 1;
+ else
{
- dyn_string_t demangled = (dyn_string_t) result_pop (dm);
- if (!dyn_string_copy (result, demangled))
- return STATUS_ALLOCATION_FAILED;
- dyn_string_delete (demangled);
+ if (mangled[9] == 'I')
+ strcpy (r, "global constructors keyed to ");
+ else
+ strcpy (r, "global destructors keyed to ");
+ strcat (r, mangled + 11);
}
-
- demangling_delete (dm);
+ return r;
}
else
{
- /* It's evidently not a mangled C++ name. It could be the name
- of something with C linkage, though, so just copy NAME into
- RESULT. */
- if (!dyn_string_copy_cstr (result, name))
- return STATUS_ALLOCATION_FAILED;
- status = STATUS_OK;
+ if ((options & DMGL_TYPES) == 0)
+ return NULL;
+ type = 1;
}
- return status;
-}
+ cplus_demangle_init_info (mangled, options, len, &di);
-/* Demangle TYPE_NAME into RESULT, which must be an initialized
- dyn_string_t. On success, returns STATUS_OK. On failiure, returns
- an error message, and the contents of RESULT are unchanged. */
+ {
+#ifdef CP_DYNAMIC_ARRAYS
+ __extension__ struct demangle_component comps[di.num_comps];
+ __extension__ struct demangle_component *subs[di.num_subs];
-static status_t
-cp_demangle_type (type_name, result)
- const char* type_name;
- dyn_string_t result;
-{
- status_t status;
- demangling_t dm = demangling_new (type_name, DMGL_GNU_V3);
-
- if (dm == NULL)
- return STATUS_ALLOCATION_FAILED;
-
- /* Demangle the type name. The demangled name is stored in dm. */
- status = result_push (dm);
- if (status != STATUS_OK)
- {
- demangling_delete (dm);
- return status;
- }
+ di.comps = &comps[0];
+ di.subs = &subs[0];
+#else
+ di.comps = ((struct demangle_component *)
+ malloc (di.num_comps * sizeof (struct demangle_component)));
+ di.subs = ((struct demangle_component **)
+ malloc (di.num_subs * sizeof (struct demangle_component *)));
+ if (di.comps == NULL || di.subs == NULL)
+ {
+ if (di.comps != NULL)
+ free (di.comps);
+ if (di.subs != NULL)
+ free (di.subs);
+ *palc = 1;
+ return NULL;
+ }
+#endif
- status = demangle_type (dm);
+ if (! type)
+ dc = cplus_demangle_mangled_name (&di, 1);
+ else
+ dc = cplus_demangle_type (&di);
- if (STATUS_NO_ERROR (status))
- {
- /* The demangling succeeded. Pop the result out of dm and copy
- it into RESULT. */
- dyn_string_t demangled = (dyn_string_t) result_pop (dm);
- if (!dyn_string_copy (result, demangled))
- return STATUS_ALLOCATION_FAILED;
- dyn_string_delete (demangled);
- }
+ /* If DMGL_PARAMS is set, then if we didn't consume the entire
+ mangled string, then we didn't successfully demangle it. If
+ DMGL_PARAMS is not set, we didn't look at the trailing
+ parameters. */
+ if (((options & DMGL_PARAMS) != 0) && d_peek_char (&di) != '\0')
+ dc = NULL;
- /* Clean up. */
- demangling_delete (dm);
+#ifdef CP_DEMANGLE_DEBUG
+ if (dc == NULL)
+ printf ("failed demangling\n");
+ else
+ d_dump (dc, 0);
+#endif
+
+ /* We try to guess the length of the demangled string, to minimize
+ calls to realloc during demangling. */
+ estimate = len + di.expansion + 10 * di.did_subs;
+ estimate += estimate / 8;
- return status;
+ ret = NULL;
+ if (dc != NULL)
+ ret = cplus_demangle_print (options, dc, estimate, palc);
+
+#ifndef CP_DYNAMIC_ARRAYS
+ free (di.comps);
+ free (di.subs);
+#endif
+
+#ifdef CP_DEMANGLE_DEBUG
+ if (ret != NULL)
+ {
+ int rlen;
+
+ rlen = strlen (ret);
+ if (rlen > 2 * estimate)
+ printf ("*** Length %d much greater than estimate %d\n",
+ rlen, estimate);
+ else if (rlen > estimate)
+ printf ("*** Length %d greater than estimate %d\n",
+ rlen, estimate);
+ else if (rlen < estimate / 2)
+ printf ("*** Length %d much less than estimate %d\n",
+ rlen, estimate);
+ }
+#endif
+ }
+
+ return ret;
}
#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3)
+
extern char *__cxa_demangle PARAMS ((const char *, char *, size_t *, int *));
-/* ia64 ABI-mandated entry point in the C++ runtime library for performing
- demangling. MANGLED_NAME is a NUL-terminated character string
- containing the name to be demangled.
+/* ia64 ABI-mandated entry point in the C++ runtime library for
+ performing demangling. MANGLED_NAME is a NUL-terminated character
+ string containing the name to be demangled.
OUTPUT_BUFFER is a region of memory, allocated with malloc, of
*LENGTH bytes, into which the demangled name is stored. If
OUTPUT_BUFFER is not long enough, it is expanded using realloc.
OUTPUT_BUFFER may instead be NULL; in that case, the demangled name
- is placed in a region of memory allocated with malloc.
+ is placed in a region of memory allocated with malloc.
If LENGTH is non-NULL, the length of the buffer conaining the
- demangled name, is placed in *LENGTH.
+ demangled name, is placed in *LENGTH.
The return value is a pointer to the start of the NUL-terminated
demangled name, or NULL if the demangling fails. The caller is
- responsible for deallocating this memory using free.
+ responsible for deallocating this memory using free.
*STATUS is set to one of the following values:
0: The demangling operation succeeded.
- -1: A memory allocation failiure occurred.
+ -1: A memory allocation failure occurred.
-2: MANGLED_NAME is not a valid name under the C++ ABI mangling rules.
-3: One of the arguments is invalid.
- The demagling is performed using the C++ ABI mangling rules, with
+ The demangling is performed using the C++ ABI mangling rules, with
GNU extensions. */
char *
@@ -3674,137 +4031,92 @@ __cxa_demangle (mangled_name, output_buffer, length, status)
size_t *length;
int *status;
{
- struct dyn_string demangled_name;
- status_t result;
+ char *demangled;
+ size_t alc;
- if (status == NULL)
- return NULL;
+ if (mangled_name == NULL)
+ {
+ if (status != NULL)
+ *status = -3;
+ return NULL;
+ }
- if (mangled_name == NULL) {
- *status = -3;
- return NULL;
- }
+ if (output_buffer != NULL && length == NULL)
+ {
+ if (status != NULL)
+ *status = -3;
+ return NULL;
+ }
- /* Did the caller provide a buffer for the demangled name? */
- if (output_buffer == NULL) {
- /* No; dyn_string will malloc a buffer for us. */
- if (!dyn_string_init (&demangled_name, 0))
- {
- *status = -1;
- return NULL;
- }
- }
- else {
- /* Yes. Check that the length was provided. */
- if (length == NULL) {
- *status = -3;
+ /* The specification for __cxa_demangle() is that if the mangled
+ name could be either an extern "C" identifier, or an internal
+ built-in type name, then we resolve it as the identifier. All
+ internal built-in type names are a single lower case character.
+ Frankly, this simplistic disambiguation doesn't make sense to me,
+ but it is documented, so we implement it here. */
+ if (IS_LOWER (mangled_name[0])
+ && mangled_name[1] == '\0'
+ && cplus_demangle_builtin_types[mangled_name[0] - 'a'].name != NULL)
+ {
+ if (status != NULL)
+ *status = -2;
return NULL;
}
- /* Install the buffer into a dyn_string. */
- demangled_name.allocated = *length;
- demangled_name.length = 0;
- demangled_name.s = output_buffer;
- }
- if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
- /* MANGLED_NAME apprears to be a function or variable name.
- Demangle it accordingly. */
- result = cp_demangle (mangled_name, &demangled_name, 0);
- else
- /* Try to demangled MANGLED_NAME as the name of a type. */
- result = cp_demangle_type (mangled_name, &demangled_name);
+ demangled = d_demangle (mangled_name, DMGL_PARAMS | DMGL_TYPES, &alc);
- if (result == STATUS_OK)
- /* The demangling succeeded. */
+ if (demangled == NULL)
{
- /* If LENGTH isn't NULL, store the allocated buffer length
- there; the buffer may have been realloced by dyn_string
- functions. */
- if (length != NULL)
- *length = demangled_name.allocated;
- /* The operation was a success. */
- *status = 0;
- return dyn_string_buf (&demangled_name);
+ if (status != NULL)
+ {
+ if (alc == 1)
+ *status = -1;
+ else
+ *status = -2;
+ }
+ return NULL;
}
- else if (result == STATUS_ALLOCATION_FAILED)
- /* A call to malloc or realloc failed during the demangling
- operation. */
+
+ if (output_buffer == NULL)
{
- *status = -1;
- return NULL;
+ if (length != NULL)
+ *length = alc;
}
else
- /* The demangling failed for another reason, most probably because
- MANGLED_NAME isn't a valid mangled name. */
{
- /* If the buffer containing the demangled name wasn't provided
- by the caller, free it. */
- if (output_buffer == NULL)
- free (dyn_string_buf (&demangled_name));
- *status = -2;
- return NULL;
+ if (strlen (demangled) < *length)
+ {
+ strcpy (output_buffer, demangled);
+ free (demangled);
+ demangled = output_buffer;
+ }
+ else
+ {
+ free (output_buffer);
+ *length = alc;
+ }
}
+
+ if (status != NULL)
+ *status = 0;
+
+ return demangled;
}
#else /* ! (IN_LIBGCC2 || IN_GLIBCPP_V3) */
-/* Variant entry point for integration with the existing cplus-dem
- demangler. Attempts to demangle MANGLED. If the demangling
- succeeds, returns a buffer, allocated with malloc, containing the
- demangled name. The caller must deallocate the buffer using free.
- If the demangling failes, returns NULL. */
+/* Entry point for libiberty demangler. If MANGLED is a g++ v3 ABI
+ mangled name, return a buffer allocated with malloc holding the
+ demangled name. Otherwise, return NULL. */
char *
cplus_demangle_v3 (mangled, options)
const char* mangled;
int options;
{
- dyn_string_t demangled;
- status_t status;
- int type = !!(options & DMGL_TYPES);
-
- if (mangled[0] == '_' && mangled[1] == 'Z')
- /* It is not a type. */
- type = 0;
- else
- {
- /* It is a type. Stop if we don't want to demangle types. */
- if (!type)
- return NULL;
- }
-
- flag_verbose = !!(options & DMGL_VERBOSE);
-
- /* Create a dyn_string to hold the demangled name. */
- demangled = dyn_string_new (0);
- /* Attempt the demangling. */
- if (!type)
- /* Appears to be a function or variable name. */
- status = cp_demangle (mangled, demangled, 0);
- else
- /* Try to demangle it as the name of a type. */
- status = cp_demangle_type (mangled, demangled);
+ size_t alc;
- if (STATUS_NO_ERROR (status))
- /* Demangling succeeded. */
- {
- /* Grab the demangled result from the dyn_string. It was
- allocated with malloc, so we can return it directly. */
- char *return_value = dyn_string_release (demangled);
- /* Hand back the demangled name. */
- return return_value;
- }
- else if (status == STATUS_ALLOCATION_FAILED)
- {
- fprintf (stderr, "Memory allocation failed.\n");
- abort ();
- }
- else
- /* Demangling failed. */
- {
- dyn_string_delete (demangled);
- return NULL;
- }
+ return d_demangle (mangled, options, &alc);
}
/* Demangle a Java symbol. Java uses a subset of the V3 ABI C++ mangling
@@ -3818,195 +4130,179 @@ char *
java_demangle_v3 (mangled)
const char* mangled;
{
- dyn_string_t demangled;
- char *next;
- char *end;
- int len;
- status_t status;
- int nesting = 0;
- char *cplus_demangled;
- char *return_value;
-
- /* Create a dyn_string to hold the demangled name. */
- demangled = dyn_string_new (0);
-
- /* Attempt the demangling. */
- status = cp_demangle ((char *) mangled, demangled, DMGL_JAVA);
-
- if (STATUS_NO_ERROR (status))
- /* Demangling succeeded. */
- {
- /* Grab the demangled result from the dyn_string. */
- cplus_demangled = dyn_string_release (demangled);
- }
- else if (status == STATUS_ALLOCATION_FAILED)
- {
- fprintf (stderr, "Memory allocation failed.\n");
- abort ();
- }
- else
- /* Demangling failed. */
- {
- dyn_string_delete (demangled);
- return NULL;
- }
-
- len = strlen (cplus_demangled);
- next = cplus_demangled;
- end = next + len;
- demangled = NULL;
-
- /* Replace occurances of JArray<TYPE> with TYPE[]. */
- while (next < end)
+ size_t alc;
+ char *demangled;
+ int nesting;
+ char *from;
+ char *to;
+
+ demangled = d_demangle (mangled, DMGL_JAVA | DMGL_PARAMS, &alc);
+
+ if (demangled == NULL)
+ return NULL;
+
+ nesting = 0;
+ from = demangled;
+ to = from;
+ while (*from != '\0')
{
- char *open_str = strstr (next, "JArray<");
- char *close_str = NULL;
- if (nesting > 0)
- close_str = strchr (next, '>');
-
- if (open_str != NULL && (close_str == NULL || close_str > open_str))
- {
+ if (strncmp (from, "JArray<", 7) == 0)
+ {
+ from += 7;
++nesting;
-
- if (!demangled)
- demangled = dyn_string_new(len);
-
- /* Copy prepending symbols, if any. */
- if (open_str > next)
- {
- open_str[0] = 0;
- dyn_string_append_cstr (demangled, next);
- }
- next = open_str + 7;
}
- else if (close_str != NULL)
- {
+ else if (nesting > 0 && *from == '>')
+ {
+ while (to > demangled && to[-1] == ' ')
+ --to;
+ *to++ = '[';
+ *to++ = ']';
--nesting;
-
- /* Copy prepending type symbol, if any. Squash any spurious
- whitespace. */
- if (close_str > next && next[0] != ' ')
- {
- close_str[0] = 0;
- dyn_string_append_cstr (demangled, next);
- }
- dyn_string_append_cstr (demangled, "[]");
- next = close_str + 1;
+ ++from;
}
else
- {
- /* There are no more arrays. Copy the rest of the symbol, or
- simply return the original symbol if no changes were made. */
- if (next == cplus_demangled)
- return cplus_demangled;
-
- dyn_string_append_cstr (demangled, next);
- next = end;
- }
+ *to++ = *from++;
}
- free (cplus_demangled);
-
- if (demangled)
- return_value = dyn_string_release (demangled);
- else
- return_value = NULL;
+ *to = '\0';
- return return_value;
+ return demangled;
}
#endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */
-
#ifndef IN_GLIBCPP_V3
-/* Demangle NAME in the G++ V3 ABI demangling style, and return either
- zero, indicating that some error occurred, or a demangling_t
- holding the results. */
-static demangling_t
-demangle_v3_with_details (name)
- const char *name;
+
+/* Demangle a string in order to find out whether it is a constructor
+ or destructor. Return non-zero on success. Set *CTOR_KIND and
+ *DTOR_KIND appropriately. */
+
+static int
+is_ctor_or_dtor (mangled, ctor_kind, dtor_kind)
+ const char *mangled;
+ enum gnu_v3_ctor_kinds *ctor_kind;
+ enum gnu_v3_dtor_kinds *dtor_kind;
{
- demangling_t dm;
- status_t status;
+ struct d_info di;
+ struct demangle_component *dc;
+ int ret;
- if (strncmp (name, "_Z", 2))
- return 0;
+ *ctor_kind = (enum gnu_v3_ctor_kinds) 0;
+ *dtor_kind = (enum gnu_v3_dtor_kinds) 0;
- dm = demangling_new (name, DMGL_GNU_V3);
- if (dm == NULL)
- {
- fprintf (stderr, "Memory allocation failed.\n");
- abort ();
- }
+ cplus_demangle_init_info (mangled, DMGL_GNU_V3, strlen (mangled), &di);
- status = result_push (dm);
- if (! STATUS_NO_ERROR (status))
- {
- demangling_delete (dm);
- fprintf (stderr, "%s\n", status);
- abort ();
- }
+ {
+#ifdef CP_DYNAMIC_ARRAYS
+ __extension__ struct demangle_component comps[di.num_comps];
+ __extension__ struct demangle_component *subs[di.num_subs];
+
+ di.comps = &comps[0];
+ di.subs = &subs[0];
+#else
+ di.comps = ((struct demangle_component *)
+ malloc (di.num_comps * sizeof (struct demangle_component)));
+ di.subs = ((struct demangle_component **)
+ malloc (di.num_subs * sizeof (struct demangle_component *)));
+ if (di.comps == NULL || di.subs == NULL)
+ {
+ if (di.comps != NULL)
+ free (di.comps);
+ if (di.subs != NULL)
+ free (di.subs);
+ return 0;
+ }
+#endif
- status = demangle_mangled_name (dm);
- if (STATUS_NO_ERROR (status))
- return dm;
+ dc = cplus_demangle_mangled_name (&di, 1);
- demangling_delete (dm);
- return 0;
+ /* Note that because we did not pass DMGL_PARAMS, we don't expect
+ to demangle the entire string. */
+
+ ret = 0;
+ while (dc != NULL)
+ {
+ switch (dc->type)
+ {
+ default:
+ dc = NULL;
+ break;
+ case DEMANGLE_COMPONENT_TYPED_NAME:
+ case DEMANGLE_COMPONENT_TEMPLATE:
+ case DEMANGLE_COMPONENT_RESTRICT_THIS:
+ case DEMANGLE_COMPONENT_VOLATILE_THIS:
+ case DEMANGLE_COMPONENT_CONST_THIS:
+ dc = d_left (dc);
+ break;
+ case DEMANGLE_COMPONENT_QUAL_NAME:
+ case DEMANGLE_COMPONENT_LOCAL_NAME:
+ dc = d_right (dc);
+ break;
+ case DEMANGLE_COMPONENT_CTOR:
+ *ctor_kind = dc->u.s_ctor.kind;
+ ret = 1;
+ dc = NULL;
+ break;
+ case DEMANGLE_COMPONENT_DTOR:
+ *dtor_kind = dc->u.s_dtor.kind;
+ ret = 1;
+ dc = NULL;
+ break;
+ }
+ }
+
+#ifndef CP_DYNAMIC_ARRAYS
+ free (di.subs);
+ free (di.comps);
+#endif
+ }
+
+ return ret;
}
+/* Return whether NAME is the mangled form of a g++ V3 ABI constructor
+ name. A non-zero return indicates the type of constructor. */
-/* Return non-zero iff NAME is the mangled form of a constructor name
- in the G++ V3 ABI demangling style. Specifically, return:
- - '1' if NAME is a complete object constructor,
- - '2' if NAME is a base object constructor, or
- - '3' if NAME is a complete object allocating constructor. */
enum gnu_v3_ctor_kinds
is_gnu_v3_mangled_ctor (name)
const char *name;
{
- demangling_t dm = demangle_v3_with_details (name);
+ enum gnu_v3_ctor_kinds ctor_kind;
+ enum gnu_v3_dtor_kinds dtor_kind;
- if (dm)
- {
- enum gnu_v3_ctor_kinds result = dm->is_constructor;
- demangling_delete (dm);
- return result;
- }
- else
+ if (! is_ctor_or_dtor (name, &ctor_kind, &dtor_kind))
return (enum gnu_v3_ctor_kinds) 0;
+ return ctor_kind;
}
-/* Return non-zero iff NAME is the mangled form of a destructor name
- in the G++ V3 ABI demangling style. Specifically, return:
- - '0' if NAME is a deleting destructor,
- - '1' if NAME is a complete object destructor, or
- - '2' if NAME is a base object destructor. */
+/* Return whether NAME is the mangled form of a g++ V3 ABI destructor
+ name. A non-zero return indicates the type of destructor. */
+
enum gnu_v3_dtor_kinds
is_gnu_v3_mangled_dtor (name)
const char *name;
{
- demangling_t dm = demangle_v3_with_details (name);
+ enum gnu_v3_ctor_kinds ctor_kind;
+ enum gnu_v3_dtor_kinds dtor_kind;
- if (dm)
- {
- enum gnu_v3_dtor_kinds result = dm->is_destructor;
- demangling_delete (dm);
- return result;
- }
- else
+ if (! is_ctor_or_dtor (name, &ctor_kind, &dtor_kind))
return (enum gnu_v3_dtor_kinds) 0;
+ return dtor_kind;
}
-#endif /* IN_GLIBCPP_V3 */
+#endif /* IN_GLIBCPP_V3 */
#ifdef STANDALONE_DEMANGLER
#include "getopt.h"
+#include "dyn-string.h"
+
+static void print_usage PARAMS ((FILE* fp, int exit_value));
-static void print_usage
- PARAMS ((FILE* fp, int exit_value));
+#define IS_ALPHA(CHAR) \
+ (((CHAR) >= 'a' && (CHAR) <= 'z') \
+ || ((CHAR) >= 'A' && (CHAR) <= 'Z'))
/* Non-zero if CHAR is a character than can occur in a mangled name. */
#define is_mangled_char(CHAR) \
@@ -4026,7 +4322,7 @@ print_usage (fp, exit_value)
fprintf (fp, "Usage: %s [options] [names ...]\n", program_name);
fprintf (fp, "Options:\n");
fprintf (fp, " -h,--help Display this message.\n");
- fprintf (fp, " -s,--strict Demangle standard names only.\n");
+ fprintf (fp, " -p,--no-params Don't display function parameters\n");
fprintf (fp, " -v,--verbose Produce verbose demanglings.\n");
fprintf (fp, "If names are provided, they are demangled. Otherwise filters standard input.\n");
@@ -4036,10 +4332,10 @@ print_usage (fp, exit_value)
/* Option specification for getopt_long. */
static const struct option long_options[] =
{
- { "help", no_argument, NULL, 'h' },
- { "strict", no_argument, NULL, 's' },
- { "verbose", no_argument, NULL, 'v' },
- { NULL, no_argument, NULL, 0 },
+ { "help", no_argument, NULL, 'h' },
+ { "no-params", no_argument, NULL, 'p' },
+ { "verbose", no_argument, NULL, 'v' },
+ { NULL, no_argument, NULL, 0 },
};
/* Main entry for a demangling filter executable. It will demangle
@@ -4052,9 +4348,9 @@ main (argc, argv)
int argc;
char *argv[];
{
- status_t status;
int i;
int opt_char;
+ int options = DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES;
/* Use the program name of this program, as invoked. */
program_name = argv[0];
@@ -4062,7 +4358,7 @@ main (argc, argv)
/* Parse options. */
do
{
- opt_char = getopt_long (argc, argv, "hsv", long_options, NULL);
+ opt_char = getopt_long (argc, argv, "hpv", long_options, NULL);
switch (opt_char)
{
case '?': /* Unrecognized option. */
@@ -4073,12 +4369,12 @@ main (argc, argv)
print_usage (stdout, 0);
break;
- case 's':
- flag_strict = 1;
+ case 'p':
+ options &= ~ DMGL_PARAMS;
break;
case 'v':
- flag_verbose = 1;
+ options |= DMGL_VERBOSE;
break;
}
}
@@ -4088,41 +4384,12 @@ main (argc, argv)
/* No command line arguments were provided. Filter stdin. */
{
dyn_string_t mangled = dyn_string_new (3);
- dyn_string_t demangled = dyn_string_new (0);
- status_t status;
+ char *s;
/* Read all of input. */
while (!feof (stdin))
{
- char c = getchar ();
-
- /* The first character of a mangled name is an underscore. */
- if (feof (stdin))
- break;
- if (c != '_')
- {
- /* It's not a mangled name. Print the character and go
- on. */
- putchar (c);
- continue;
- }
- c = getchar ();
-
- /* The second character of a mangled name is a capital `Z'. */
- if (feof (stdin))
- break;
- if (c != 'Z')
- {
- /* It's not a mangled name. Print the previous
- underscore, the `Z', and go on. */
- putchar ('_');
- putchar (c);
- continue;
- }
-
- /* Start keeping track of the candidate mangled name. */
- dyn_string_append_char (mangled, '_');
- dyn_string_append_char (mangled, 'Z');
+ char c;
/* Pile characters into mangled until we hit one that can't
occur in a mangled name. */
@@ -4135,62 +4402,70 @@ main (argc, argv)
c = getchar ();
}
- /* Attempt to demangle the name. */
- status = cp_demangle (dyn_string_buf (mangled), demangled, 0);
-
- /* If the demangling succeeded, great! Print out the
- demangled version. */
- if (STATUS_NO_ERROR (status))
- fputs (dyn_string_buf (demangled), stdout);
- /* Abort on allocation failures. */
- else if (status == STATUS_ALLOCATION_FAILED)
+ if (dyn_string_length (mangled) > 0)
{
- fprintf (stderr, "Memory allocation failed.\n");
- abort ();
+#ifdef IN_GLIBCPP_V3
+ s = __cxa_demangle (dyn_string_buf (mangled), NULL, NULL, NULL);
+#else
+ s = cplus_demangle_v3 (dyn_string_buf (mangled), options);
+#endif
+
+ if (s != NULL)
+ {
+ fputs (s, stdout);
+ free (s);
+ }
+ else
+ {
+ /* It might not have been a mangled name. Print the
+ original text. */
+ fputs (dyn_string_buf (mangled), stdout);
+ }
+
+ dyn_string_clear (mangled);
}
- /* Otherwise, it might not have been a mangled name. Just
- print out the original text. */
- else
- fputs (dyn_string_buf (mangled), stdout);
/* If we haven't hit EOF yet, we've read one character that
can't occur in a mangled name, so print it out. */
if (!feof (stdin))
putchar (c);
-
- /* Clear the candidate mangled name, to start afresh next
- time we hit a `_Z'. */
- dyn_string_clear (mangled);
}
dyn_string_delete (mangled);
- dyn_string_delete (demangled);
}
else
/* Demangle command line arguments. */
{
- dyn_string_t result = dyn_string_new (0);
-
/* Loop over command line arguments. */
for (i = optind; i < argc; ++i)
{
+ char *s;
+#ifdef IN_GLIBCPP_V3
+ int status;
+#endif
+
/* Attempt to demangle. */
- status = cp_demangle (argv[i], result, 0);
+#ifdef IN_GLIBCPP_V3
+ s = __cxa_demangle (argv[i], NULL, NULL, &status);
+#else
+ s = cplus_demangle_v3 (argv[i], options);
+#endif
/* If it worked, print the demangled name. */
- if (STATUS_NO_ERROR (status))
- printf ("%s\n", dyn_string_buf (result));
- /* Abort on allocaiton failures. */
- else if (status == STATUS_ALLOCATION_FAILED)
+ if (s != NULL)
{
- fprintf (stderr, "Memory allocation failed.\n");
- abort ();
+ printf ("%s\n", s);
+ free (s);
+ }
+ else
+ {
+#ifdef IN_GLIBCPP_V3
+ fprintf (stderr, "Failed: %s (status %d)\n", argv[i], status);
+#else
+ fprintf (stderr, "Failed: %s\n", argv[i]);
+#endif
}
- /* If not, print the error message to stderr instead. */
- else
- fprintf (stderr, "%s\n", status);
}
- dyn_string_delete (result);
}
return 0;
diff --git a/contrib/gcc/cp-demangle.h b/contrib/gcc/cp-demangle.h
new file mode 100644
index 000000000000..eea086862d69
--- /dev/null
+++ b/contrib/gcc/cp-demangle.h
@@ -0,0 +1,149 @@
+/* Internal demangler interface for g++ V3 ABI.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@wasabisystems.com>.
+
+ This file is part of the libiberty library, which is part of GCC.
+
+ 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 2 of the License, or
+ (at your option) any later version.
+
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+ compiled version of this file into combinations with other programs,
+ and to distribute those combinations without any restriction coming
+ from the use of this file. (The General Public License restrictions
+ do apply in other respects; for example, they cover modification of
+ the file, and distribution when not linked into a combined
+ executable.)
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/* This file provides some definitions shared by cp-demangle.c and
+ cp-demint.c. It should not be included by any other files. */
+
+/* Information we keep for operators. */
+
+struct demangle_operator_info
+{
+ /* Mangled name. */
+ const char *code;
+ /* Real name. */
+ const char *name;
+ /* Length of real name. */
+ int len;
+ /* Number of arguments. */
+ int args;
+};
+
+/* How to print the value of a builtin type. */
+
+enum d_builtin_type_print
+{
+ /* Print as (type)val. */
+ D_PRINT_DEFAULT,
+ /* Print as integer. */
+ D_PRINT_INT,
+ /* Print as unsigned integer, with trailing "u". */
+ D_PRINT_UNSIGNED,
+ /* Print as long, with trailing "l". */
+ D_PRINT_LONG,
+ /* Print as unsigned long, with trailing "ul". */
+ D_PRINT_UNSIGNED_LONG,
+ /* Print as long long, with trailing "ll". */
+ D_PRINT_LONG_LONG,
+ /* Print as unsigned long long, with trailing "ull". */
+ D_PRINT_UNSIGNED_LONG_LONG,
+ /* Print as bool. */
+ D_PRINT_BOOL,
+ /* Print as float--put value in square brackets. */
+ D_PRINT_FLOAT,
+ /* Print in usual way, but here to detect void. */
+ D_PRINT_VOID
+};
+
+/* Information we keep for a builtin type. */
+
+struct demangle_builtin_type_info
+{
+ /* Type name. */
+ const char *name;
+ /* Length of type name. */
+ int len;
+ /* Type name when using Java. */
+ const char *java_name;
+ /* Length of java name. */
+ int java_len;
+ /* How to print a value of this type. */
+ enum d_builtin_type_print print;
+};
+
+/* The information structure we pass around. */
+
+struct d_info
+{
+ /* The string we are demangling. */
+ const char *s;
+ /* The end of the string we are demangling. */
+ const char *send;
+ /* The options passed to the demangler. */
+ int options;
+ /* The next character in the string to consider. */
+ const char *n;
+ /* The array of components. */
+ struct demangle_component *comps;
+ /* The index of the next available component. */
+ int next_comp;
+ /* The number of available component structures. */
+ int num_comps;
+ /* The array of substitutions. */
+ struct demangle_component **subs;
+ /* The index of the next substitution. */
+ int next_sub;
+ /* The number of available entries in the subs array. */
+ int num_subs;
+ /* The number of substitutions which we actually made from the subs
+ array, plus the number of template parameter references we
+ saw. */
+ int did_subs;
+ /* The last name we saw, for constructors and destructors. */
+ struct demangle_component *last_name;
+ /* A running total of the length of large expansions from the
+ mangled name to the demangled name, such as standard
+ substitutions and builtin types. */
+ int expansion;
+};
+
+#define d_peek_char(di) (*((di)->n))
+#define d_peek_next_char(di) ((di)->n[1])
+#define d_advance(di, i) ((di)->n += (i))
+#define d_next_char(di) (*((di)->n++))
+#define d_str(di) ((di)->n)
+
+/* Functions and arrays in cp-demangle.c which are referenced by
+ functions in cp-demint.c. */
+
+extern const struct demangle_operator_info cplus_demangle_operators[];
+
+#define D_BUILTIN_TYPE_COUNT (26)
+
+extern const struct demangle_builtin_type_info
+cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT];
+
+extern struct demangle_component *
+cplus_demangle_mangled_name PARAMS ((struct d_info *, int));
+
+extern struct demangle_component *
+cplus_demangle_type PARAMS ((struct d_info *));
+
+extern void
+cplus_demangle_init_info PARAMS ((const char *, int, size_t, struct d_info *));
diff --git a/contrib/gcc/cp-demint.c b/contrib/gcc/cp-demint.c
new file mode 100644
index 000000000000..533202dd1048
--- /dev/null
+++ b/contrib/gcc/cp-demint.c
@@ -0,0 +1,241 @@
+/* Demangler component interface functions.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Written by Ian Lance Taylor <ian@wasabisystems.com>.
+
+ This file is part of the libiberty library, which is part of GCC.
+
+ 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 2 of the License, or
+ (at your option) any later version.
+
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+ compiled version of this file into combinations with other programs,
+ and to distribute those combinations without any restriction coming
+ from the use of this file. (The General Public License restrictions
+ do apply in other respects; for example, they cover modification of
+ the file, and distribution when not linked into a combined
+ executable.)
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+/* This file implements a few interface functions which are provided
+ for use with struct demangle_component trees. These functions are
+ declared in demangle.h. These functions are closely tied to the
+ demangler code in cp-demangle.c, and other interface functions can
+ be found in that file. We put these functions in a separate file
+ because they are not needed by the demangler, and so we avoid
+ having them pulled in by programs which only need the
+ demangler. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include "ansidecl.h"
+#include "libiberty.h"
+#include "demangle.h"
+#include "cp-demangle.h"
+
+/* Fill in most component types. */
+
+int
+cplus_demangle_fill_component (p, type, left, right)
+ struct demangle_component *p;
+ enum demangle_component_type type;
+ struct demangle_component *left;
+ struct demangle_component *right;
+{
+ if (p == NULL)
+ return 0;
+ switch (type)
+ {
+ case DEMANGLE_COMPONENT_QUAL_NAME:
+ case DEMANGLE_COMPONENT_LOCAL_NAME:
+ case DEMANGLE_COMPONENT_TYPED_NAME:
+ case DEMANGLE_COMPONENT_TEMPLATE:
+ case DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE:
+ case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
+ case DEMANGLE_COMPONENT_FUNCTION_TYPE:
+ case DEMANGLE_COMPONENT_ARRAY_TYPE:
+ case DEMANGLE_COMPONENT_PTRMEM_TYPE:
+ case DEMANGLE_COMPONENT_ARGLIST:
+ case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
+ case DEMANGLE_COMPONENT_UNARY:
+ case DEMANGLE_COMPONENT_BINARY:
+ case DEMANGLE_COMPONENT_BINARY_ARGS:
+ case DEMANGLE_COMPONENT_TRINARY:
+ case DEMANGLE_COMPONENT_TRINARY_ARG1:
+ case DEMANGLE_COMPONENT_TRINARY_ARG2:
+ case DEMANGLE_COMPONENT_LITERAL:
+ case DEMANGLE_COMPONENT_LITERAL_NEG:
+ break;
+
+ /* These component types only have one subtree. */
+ case DEMANGLE_COMPONENT_VTABLE:
+ case DEMANGLE_COMPONENT_VTT:
+ case DEMANGLE_COMPONENT_TYPEINFO:
+ case DEMANGLE_COMPONENT_TYPEINFO_NAME:
+ case DEMANGLE_COMPONENT_TYPEINFO_FN:
+ case DEMANGLE_COMPONENT_THUNK:
+ case DEMANGLE_COMPONENT_VIRTUAL_THUNK:
+ case DEMANGLE_COMPONENT_COVARIANT_THUNK:
+ case DEMANGLE_COMPONENT_JAVA_CLASS:
+ case DEMANGLE_COMPONENT_GUARD:
+ case DEMANGLE_COMPONENT_REFTEMP:
+ case DEMANGLE_COMPONENT_RESTRICT:
+ case DEMANGLE_COMPONENT_VOLATILE:
+ case DEMANGLE_COMPONENT_CONST:
+ case DEMANGLE_COMPONENT_RESTRICT_THIS:
+ case DEMANGLE_COMPONENT_VOLATILE_THIS:
+ case DEMANGLE_COMPONENT_CONST_THIS:
+ case DEMANGLE_COMPONENT_POINTER:
+ case DEMANGLE_COMPONENT_REFERENCE:
+ case DEMANGLE_COMPONENT_COMPLEX:
+ case DEMANGLE_COMPONENT_IMAGINARY:
+ case DEMANGLE_COMPONENT_VENDOR_TYPE:
+ case DEMANGLE_COMPONENT_CAST:
+ if (right != NULL)
+ return 0;
+ break;
+
+ default:
+ /* Other types do not use subtrees. */
+ return 0;
+ }
+
+ p->type = type;
+ p->u.s_binary.left = left;
+ p->u.s_binary.right = right;
+
+ return 1;
+}
+
+/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE. */
+
+int
+cplus_demangle_fill_builtin_type (p, typename)
+ struct demangle_component *p;
+ const char *typename;
+{
+ int len;
+ unsigned int i;
+
+ if (p == NULL || typename == NULL)
+ return 0;
+ len = strlen (typename);
+ for (i = 0; i < D_BUILTIN_TYPE_COUNT; ++i)
+ {
+ if (len == cplus_demangle_builtin_types[i].len
+ && strcmp (typename, cplus_demangle_builtin_types[i].name) == 0)
+ {
+ p->type = DEMANGLE_COMPONENT_BUILTIN_TYPE;
+ p->u.s_builtin.type = &cplus_demangle_builtin_types[i];
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Fill in a DEMANGLE_COMPONENT_OPERATOR. */
+
+int
+cplus_demangle_fill_operator (p, opname, args)
+ struct demangle_component *p;
+ const char *opname;
+ int args;
+{
+ int len;
+ unsigned int i;
+
+ if (p == NULL || opname == NULL)
+ return 0;
+ len = strlen (opname);
+ for (i = 0; cplus_demangle_operators[i].name != NULL; ++i)
+ {
+ if (len == cplus_demangle_operators[i].len
+ && args == cplus_demangle_operators[i].args
+ && strcmp (opname, cplus_demangle_operators[i].name) == 0)
+ {
+ p->type = DEMANGLE_COMPONENT_OPERATOR;
+ p->u.s_operator.op = &cplus_demangle_operators[i];
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Translate a mangled name into components. */
+
+struct demangle_component *
+cplus_demangle_v3_components (mangled, options, mem)
+ const char *mangled;
+ int options;
+ void **mem;
+{
+ size_t len;
+ int type;
+ struct d_info di;
+ struct demangle_component *dc;
+
+ len = strlen (mangled);
+
+ if (mangled[0] == '_' && mangled[1] == 'Z')
+ type = 0;
+ else
+ {
+ if ((options & DMGL_TYPES) == 0)
+ return NULL;
+ type = 1;
+ }
+
+ cplus_demangle_init_info (mangled, options, len, &di);
+
+ di.comps = ((struct demangle_component *)
+ malloc (di.num_comps * sizeof (struct demangle_component)));
+ di.subs = ((struct demangle_component **)
+ malloc (di.num_subs * sizeof (struct demangle_component *)));
+ if (di.comps == NULL || di.subs == NULL)
+ {
+ if (di.comps != NULL)
+ free (di.comps);
+ if (di.subs != NULL)
+ free (di.subs);
+ return NULL;
+ }
+
+ if (! type)
+ dc = cplus_demangle_mangled_name (&di, 1);
+ else
+ dc = cplus_demangle_type (&di);
+
+ /* If DMGL_PARAMS is set, then if we didn't consume the entire
+ mangled string, then we didn't successfully demangle it. */
+ if ((options & DMGL_PARAMS) != 0 && d_peek_char (&di) != '\0')
+ dc = NULL;
+
+ free (di.subs);
+
+ if (dc != NULL)
+ *mem = di.comps;
+ else
+ free (di.comps);
+
+ return dc;
+}
diff --git a/contrib/gcc/cp/ChangeLog b/contrib/gcc/cp/ChangeLog
index e05c075b976b..7462819d7b90 100644
--- a/contrib/gcc/cp/ChangeLog
+++ b/contrib/gcc/cp/ChangeLog
@@ -1,16681 +1,1399 @@
-2003-10-23 Jason Merrill <jason@redhat.com>
+2004-07-21 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
- PR c++/12726
- * tree.c (build_target_expr_with_type): Don't call force_rvalue
- for CONSTRUCTORs.
+ PR c++/16175
+ * error.c (dump_type) <BOUND_TEMPLATE_TEMPLATE_PARM case>: Output
+ cv qualifier.
-2003-10-16 Release Manager
+2004-07-20 Mark Mitchell <mark@codesourcery.com>
- * GCC 3.3.2 Released.
-
-2003-10-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/12369
- * decl.c (grokdeclarator): Handle TEMPLATE_ID_EXPR if friend
- is a member of other class.
- * friend.c (do_friend): Don't build TEMPLATE_DECL if friend
- is a specialization of function template.
-
-2003-10-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/7939
- * typeck.c (comptypes): Don't ICE when its first argument is
- error_mark_node.
- (compparms): Reverse the arguments of same_type_p.
-
-2003-10-14 Jason Merrill <jason@redhat.com>
-
- PR c++/11878
- * tree.c (build_target_expr_with_type): Call force_rvalue for
- classes with non-trivial copy ctors.
-
- PR c++/11063
- * typeck.c (build_modify_expr): Call convert rather than abort.
-
-2003-10-06 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10147
- * call.c (initialize_reference): Tweak error message.
-
- PR c++/12337
- * init.c (build_new_1): Make sure that the expression returned is
- not an lvalue.
-
- PR c++/12344, c++/12236, c++/8656
- * decl.c (start_function): Do not ignore attributes embedded in a
- function declarator.
-
-2003-10-04 Roger Sayle <roger@eyesopen.com>
-
- PR c++/11409
- * class.c (resolve_address_of_overloaded_function): When building
- list of matching non-template function decls, ignore anticipated
- declarations of undeclared or shadowed GCC builtins.
-
-2003-10-02 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/12486
- * typeck.c (finish_class_member_access_expr): Issue diagnostic
- on erroneous use of qualified name.
-
-2003-07-09 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (break_out_calls): Remove declaration.
- * tree.c (break_out_calls): Remove.
- * typeck.c (build_modify_expr): Avoid invalid sharing of trees.
-
-2003-09-18 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (resolve_address_of_overloaded_function): Replace
- complain parameter with flags parameter.
- (instantiate_type): Adjust accordingly.
-
-2003-09-17 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/11991
- * typeck2.c (incomplete_type_diagnostic): Robustify.
-
- PR c++/12266
- * cp-tree.h (tsubst_flags_t): Add tf_conv.
- * class.c (standard_conversion): Pass tf_conv to
- instantiate_type.
- (resolve_address_of_overloaded_function): Do not call mark_used
- when just checking conversions.
-
-2003-09-14 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/3907
- * cp-tree.h (innermost_scope_is_class_p): New function.
- * class.c (maybe_note_name_used_in_class): Refine test for whether
- or not we are in a class scope.
- * decl.c (innermost_scope_is_class_p): Define.
-
-2003-09-14 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (layout_class_type): Make DECL_MODE match TYPE_MODE for
- an bit-field whose width exceeds that of its type.
-
-2003-09-09 Steven Bosscher <steven@gcc.gnu.org>
-
- PR c++/11595
- * decl.c (define_label): Remove unreachable timevar pop.
- Always return the decl, even if the definition is invalid.
-
-2003-09-08 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/11786
- * decl2.c (add_function): Do not complain about seeing the same
- non-function twice.
-
-2003-09-08 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/5296
- * pt.c (try_one_overload): Add addr_p parameter.
- (resolve_overloaded_unification): Pass it.
-
-2003-09-07 Jason Merrill <jason@redhat.com>
-
- PR c++/12181
- * typeck.c (build_modify_expr): Don't always stabilize the lhs and
- rhs. Do stabilize the lhs of a MODIFY_EXPR used on the lhs.
-
-2003-09-06 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/11867
- * call.c (standard_conversion): Improve comments.
- (perform_direct_initialization): Make sure we return an expression
- of the correct type.
- * typeck.c (build_static_cast): Check for ambiguity and
- accessibility when performing conversions.
-
-2003-09-05 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/12163
- * call.c (perform_direct_initialization): Correct logic for
- direct-initialization of a class type.
-
- PR c++/12146
- * pt.c (lookup_template_function): Robustify.
-
-2003-09-04 Mark Mitchell <mark@codesourcery.com>
-
- Revert this patch:
- * class.c (include_empty_classes): Correct logic for ABI version 1.
-
-2003-09-03 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/12053
- * class.c (include_empty_classes): Correct logic for ABI version 1.
-
-2003-09-01 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/12114
- * cp-tree.h (initialize_reference): Change prototype.
- * call.c (initialize_reference): Add cleanup parameter.
- * decl.c (grok_reference_init): Likewise.
- (check_initializer): Likewise.
- (cp_finish_decl): Insert a CLEANUP_STMT if necessary.
- (duplicate_decls): When replacing an anticipated builtin, do not
- honor TREE_NOTHROW.
- * typeck.c (convert_for_initialization): Correct call to
- initialize_reference.
-
-2003-08-29 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/11928
- * search.c (add_conversions): Avoid adding two conversion
- operators for the same type.
-
-2003-08-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * cp-tree.h (build_function_call_real): Remove unused parameter.
- * typeck.c (build_function_call_real): Likewise. Caller changed.
- * decl.c (binding_table_reverse_maybe_remap): Initialize variable.
-
-2003-08-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- PR c++/5293
- * call.c (initialize_reference): Improve diagnostic.
-
-2003-08-04 Release Manager
-
- * GCC 3.3.1 Released.
-
-2003-08-04 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/11713
- * search.c (setup_class_bindings): Handle conversion operators
- specially.
-
-2003-07-24 Alexandre Oliva <aoliva@redhat.com>
-
- PR c++/10796
- * decl.c (finish_enum): Make sure the underlying integer type has
- the same precision as some full integer type. Reverts part
- 2003-06-27's patch that didn't play any role in fixing the PR.
-
-2003-07-24 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (convert_to_base_statically): Declare.
- * call.c (build_special_member_call): Convert INSTANCE to the base
- type.
- * class.c (convert_to_base_statically): New method.
- * init.c (construct_virtual_base): Use it.
- * method.c (do_build_assign_ref): Fix typo in comment.
-
-2003-07-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/11513
- * cp-tree.h (PROCESSING_REAL_TEMPLATE_DECL_P): Use current_scope.
-
-2003-07-23 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/11645
- * cp-tree.h (accessible_base_p): Declare.
- * call.c (build_over_call): Use it.
- * search.c (accessible_base_p): New function, split out from ...
- (lookup_base): ... here.
-
-2003-07-23 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/11282
- * decl.c: (reshape_init): Always advance *INITP.
-
-2003-07-19 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/11546
- * pt.c (lookup_template_class): Treat TYPE_DECLs as TEMPLATE_DECLs
- where appropriate.
-
-2003-07-14 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/7053
- * pt.c (unregister_specialization): Rename to ...
- (reregister_specialization): ... this.
- (tsubst_friend_function): Use it.
- (regenerate_decl_from_template): Likewise.
-
-2003-07-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/11154
- * pt.c (more_specialized_class): Add full_args parameter.
- (most_specialized_class): Adjust calls to more_specialized_class.
- * cp-tree.h (more_specialized_class): Adjust declaration.
-
-2003-07-13 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/11503
- * cp-tree.h (DECL_SELF_REFERENCE_P): New macro.
- (SET_DECL_SELF_REFERENCE_P): Likewise.
- * class.c (build_self_reference): Use SET_DECL_SELF_REFERENCE_P.
- * pt.c (tsubst_decl): Copy it.
- * search.c (lookup_base): Use DECL_SELF_REFERENCE_P.
-
-2003-07-11 Danny Smith <dannysmith@users.sourceforge.net>
-
- Backport from mainline.
-
- 2003-05-21 Danny Smith <dannysmith@users.sourceforge.net>
-
- PR c++/9738
- * decl.c (duplicate_decls): Re-invoke make_decl_rtl
- if the old decl had instantiated DECL_RTL.
- (Based on Richard Henderson 2003-05-13 patch to c-decl.c).
-
-2003-07-11 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/8164
- * decl.c (duplicate_decls): Avoid mangling names unnecessarily.
-
-2003-07-10 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10558
- * parse.y (class_template_ok_as_expr): New variable.
- (template_arg_1): New non-terminal.
- (primary): Issue errors about uses of class templates as
- expressions.
-
-2003-07-09 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10032
- * decl.c (cxx_init_decl_processing): With -pedantic, pedwarns are
- still errors.
-
- PR c++/10527
- * error.c (decl_to_string): Do not print default argument
- expressions.
-
-2003-07-10 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/10849
- * decl2.c (handle_class_head_apparent_template): New function.
- * cp-tree.h (handle_class_head_apparent_template): Add declaration.
- * parse.y (class_head_defn): Use it.
- * search.c (type_access_control): Revert my 2003-05-25 change.
-
-2003-07-06 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/11236
- * cvt.c (convert_to_void): Treat an overloaded function like
- "((void) 0)" after issuing a diagnostic.
-
- PR c++/11345
- * search.c (lookup_base_r): Remove is_non_public and
- within_current_scope parameters. Remove other dead code.
- (lookup_base): Adjust call to lookup_base_r.
- (adjust_result_of_qualified_name_lookup): Improve comment.
- * semantics.c (finish_call_expr): Use maybe_dummy_object.
-
-2003-07-05 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/11431
- * typeck.c (build_static_cast): Check for reference conversions
- earlier.
-
-2003-07-01 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/6949
- * decl2.c (grokfield): Create TEMPLATE_DECLs for methods in local
- classes.
-
-2003-07-01 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (resolve_scoped_fn_name): Return error_mark_node for
- erroneous cases.
-
- PR c++/11137
- * decl2.c (generate_ctor_or_dtor_function): Tolerate a
- non-existant ssdf_decls array.
- (finish_file): Call generator_ctor_or_dtor_function when there are
- static constructors or destructors and no other static
- initializations.
-
- PR c++/11149
- * call.c (resolve_scoped_fn_name): Check that the qualifying scope
- is a class type.
-
-2003-07-01 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9559
- * decl2.c (grokfield): Do not build NOP_EXPRs around the
- error_mark_node.
-
-2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
-
- * mangle.c (write_expression): Exit gracefully when trying to
- mangle a CALL_EXPR.
-
-2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
-
- PR c++/11106
- * error.c (dump_decl): Call dump_decl to dump the DECL_NAME for a
- USING_DECL, instead of print_tree_identifier.
-
-2003-06-27 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10468
- * pt.c (tsubst): Handle qualified TYPEOF_TYPEs correctly.
-
- PR c++/10796
- * decl.c (finish_enum): Implement DR377.
-
- * decl.c (cp_finish_decl): Don't make variables with reference
- type readonly while they are being initialized.
-
-2003-06-26 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/11332
- * typeck.c (build_static_cast): Avoid returning expressions with
- reference type.
-
-2003-06-25 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10990
- * search.c (lookup_base_r): Rely on accessible_p, rather than
- trying to emulate that logic here.
-
- PR c++/10931
- * call.c (convert_like): Pass issue_conversion_warnings.
- (convert_like_with_context): Likewise.
- (convert_like_real): Add issue_conversion_warnings parameter.
- (perform_direct_initialization_if_possible): New function.
- * cp-tree.h (perform_direct_initialization_if_possible): Declare it.
- * typeck.c (check_for_casting_away_constness): New function.
- (build_static_cast): Rewrite.
+ (cp_parser_simple_type_specifier): Fix typo.
-2003-06-23 Mark Mitchell <mark@codesourcery.com>
+ PR c++/16637
+ * parser.c (cp_parser_simple_type_specifier): Do not record usage
+ of globally-qualified names.
- PR c++/5754
- * parse.y (structsp): Improve error handling of invalid nested
- template classes.
+2004-07-12 Andrew Pinski <apinski@apple.com>
-2003-06-23 Jakub Jelinek <jakub@redhat.com>
+ PR c++/16475
+ Revert:
+ 2004-07-07 H.J. Lu <hongjiu.lu@intel.com>
+ PR c++/16276
+ * rtti.c (emit_tinfo_decl): Turn off DECL_ONE_ONLY if typeinfo
+ is not public.
- * mangle.c: Include ggc.h, gt-cp-mangle.h.
- (mangle_conv_op_name_for_type): Use htab_create_ggc instead of
- htab_create.
- * config-lang.in (gtfiles): Add cp/mangle.c.
- * Make-lang.in (gt-cp-mangle.h): Depend on s-gtype.
- (cp/mangle.o): Depend on gt-cp-mangle.h.
-2003-06-23 Jakub Jelinek <jakub@redhat.com>
+2004-07-07 H.J. Lu <hongjiu.lu@intel.com>
- * mangle.c (hash_type): val is the TREE_LIST itself, not a pointer
- to it.
+ PR c++/16276
+ * rtti.c (emit_tinfo_decl): Turn off DECL_ONE_ONLY if typeinfo
+ is not public.
-2003-06-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+2004-07-01 Release Manager
- PR c++/10784
- * call.c (joust): Warn about choosing conversion sequence only if
- -Wconversion.
-
-2003-06-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+ * GCC 3.4.1 released.
- PR c++/10864
- * call.c (op_error): Tidy.
- * error.c (dump_expr): Properly format 'T()' when T is an
- aggregate type.
+2004-06-28 Nathan Sidwell <nathan@codesourcery.com>
-2003-06-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+ PR C++/16174
+ * call.c (build_temp): Declare.
+ (check_constructor_callable): New.
+ (reference_binding): Only set CHECK_COPY_CONSTRUCTOR if not for
+ CONSTRUCTOR_CALLABLE.
+ (convert_like_real, initialize_reference): Use
+ check_constructor_callable.
+ * cp-tree.h (LOOKUP_CONSTRUCTOR_CALLABLE): New.
+ (LOOKUP_*): Renumber.
- PR c++/10915
- * decl.c (grok_op_properties): Warn possible confusing conversion
- only if -Wconversion.
+2004-06-25 Jan Hubicka <jh@suse.cz>
-2003-06-20 Mark Mitchell <mark@codesourcery.com>
+ PR C++/14865
+ * decl2.c (maybe_emit_vtables): Always import_export_vtable for the
+ reachability analysis.
- PR c++/10845
- * pt.c (try_class_unification): Correct handling of member class
- templates.
+2004-06-22 Jan Hubicka <jh@suse.cz>
-2003-06-19 Mark Mitchell <mark@codesourcery.com>
+ PR C++/14950
+ * pt.c (instantiate_decl): Clean TI_PENDING_TEMPLATE_FLAG before
+ expanding the function.
- PR c++/10939
- * Make-lang.in (decl.o): Depend on input.h.
- * decl.c (input.h): Include it.
- (cp_finish_decl): Revert previous change:
- 2003-06-19 Mark Mitchell <mark@codesourcery.com>
- * decl.c (cp_finish_decl): Remove support for RESULT_DECLs.
- Don't check building_stmt_tree.
- * pt.c (tsubst_decl): Do not try to substitute into non-dependent
- functions.
+2004-06-21 Nathan Sidwell <nathan@codesourcery.com>
- PR c++/9649
- * cp-tree.h (pushdecl_class_level): Change prototype.
- (push_class_level_binding): Likewise.
- * decl.c (add_binding): Reject duplicate static data members.
- (pushdecl_class_level): Return a value indicating whether or not
- the binding was valid.
- (push_class_level_binding): Likewise.
- * semantics.c (finish_member_declaration): Don't keep invalid
- declarations.
-
-2003-06-19 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/11041
- * call.c (initialize_reference): Do not use cp_finish_decl to emit
- temporary variables.
- * cp-tree.h (static_aggregates): Declare.
- (pushdecl_top_level_and_finish): Likewise.
- * decl.c (pushdecl_top_level_1): New function.
- (pushdecl_top_level): Use it.
- (pushdecl_top_level_and_finish): New function.
- (initialize_local_var): Remove redundant code.
- (cp_finish_decl): Remove support for RESULT_DECLs. Don't check
- building_stmt_tree.
- * decl.h (static_aggregates): Remove.
- * decl2.c (get_guard): Use pushdecl_top_level_and_finish.
- * rtti.c (get_tinfo_decl): Use pushdecl_top_level_and_finish.
- (tinfo_base_init): Likewise.
-
-2003-06-19 Matt Austern <austern@apple.com>
-
- PR c++/11228
- * init.c (build_zero_init): Assert that number of array elements
- is an integer constant.
- (build_default_init) Don't use build_zero_init for arrays with
- variable number of elements.
+ PR c++/3518
+ * pt.c (check_cv_quals_for_unify): Ignore bogus CV quals at outer
+ level.
-2003-06-17 Mark Mitchell <mark@codesourcery.com>
-
- * mangle.c (mangle_conv_op_name_for_type): Correct sprintf format
- string again.
-
-2003-06-17 Mark Mitchell <mark@codesourcery.com>
-
- * mangle.c (mangle_conv_op_name_for_type): Correct sprintf format
- string.
-
-2003-06-17 Jason Merrill <jason@redhat.com>
-
- PR c++/10929
- * decl.c (grokfndecl): Don't mark a function inline for
- -finline-functions if it isn't defined.
-
-2003-06-17 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10712
- * class.c (handle_using_decl): Robustify.
-
- PR c++/11105
- * cp-tree.h (DECL_CONV_FN_TYPE): New method.
- * decl.c (lookup_name_real): Backport conversion operator code
- from mainline.
- * mangle.c (struct globals): Remove internal_mangling_p.
- (write_unqualified_name): Use DECL_CONV_FN_TYPE.
- (write_template_parm): Don't write out the level number.
- (conv_type_names): New variable.
- (hash_type): New function.
- (compare_type): Likewise.
- (mangle_conv_op_name_for_type): Don't try to mangle conversion
- operator names.
- * search.c (lookup_conversion_operator): New function.
- (lookup_fnfields_1): Use it.
-
-2003-06-12 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10635
- * typeck.c (build_c_cast): Check that the destination type is
- complete.
-
-2003-06-10 Jason Merrill <jason@redhat.com>
-
- PR c++/10968
- * pt.c (mark_decl_instantiated): Clear DECL_COMDAT.
-
-2003-06-09 Zack Weinberg <zack@codesourcery.com>
-
- PR 8861
- * mangle.c (write_real_cst): New function. Implement
- ABI-compliant mangling of floating-point literals when
- -fabi-version>=2; provide backward compatibility with 3.3 when
- -fabi-version=1 (with warning). Clarify commentary.
- (write_template_arg_literal): Use write_real_cst.
-
-2003-06-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/11039
- * decl2.c (handle_class_head): Remove implicitness in typename
- appeared as elaborated type specifier in declaration.
-
-2003-06-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/10940
- * pt.c (check_explicit_specialization): Check for 'static'
- earlier.
-
-2003-05-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/10956
- * pt.c (instantiate_decl): Don't use full template arguments if
- we are dealing with specializations.
-
-2003-05-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * decl.c (ENABLE_CHECKING_SCOPES): New macro.
- (binding_depth): Unconditionally define.
- (is_class_level): Likewise.
- (indent): Likewise. Take an indenting parameter.
- (push_binding_level): Remove conditional definittion.
- (pop_binding_level): Likewise.
- (suspend_binding_level): Likewise.
- (resume_binding_level): Likewise.
- (pushlevel): Likewise.
- (pushlevel_class): Likewise.
- (poplevel_class): Likewise.
- (pop_everything): Likewise.
-
-2003-05-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * decl.c (global_scope_p): New macro.
- (pop_binding_level): Use it.
- (suspend_binding_level): Likewise.
- (global_bindings_p): Likewise.
- (print_other_binding_stack): Likewise.
- (print_binding_stack): Likewise.
- (maybe_push_to_top_level): Likewise.
- (pushdecl_namespace_level): Likewise.
- (start_decl): Likewise.
- (cp_finish_decl): Likewise.
- (start_function): Likewise.
- (cxx_init_decl_processing): Don't refer to global_binding_level.
- (global_binding_level): Remove.
-
-2003-05-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/10849
- * search.c (type_access_control): Don't check access when
- processing_specialization.
-
-2003-05-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/10682
- * pt.c (instantiate_class_template): Use DECL_ARTIFICIAL to
- check for implicitly created typedef to an enum.
-
-2003-05-20 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * decl.c (free_binding_entry): Fix thinko.
-
-2003-05-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * cp-tree.h (struct binding_entry_s): New datatype.
- (binding_table): Declare.
- (binding_entry): Likewise.
- (bt_foreach_proc): Likewise.
- (binding_table_foreach): Likewise.
- (binding_table_find): Likewise.
- (cxx_remember_type_decls): Likewise.
- (CLASSTYPE_TAGS): Remove.
- (CLASSTYPE_NESTED_UDTS): New macro.
- (struct lang_type_class): Remove tags field. Add nested_types.
- * decl.c (ENTRY_INDEX): New macro.
- (free_binding_entry): New free list.
- (binding_entry_make): New function.
- (binding_entry_free): Likewise.
- (struct binding_table_s): New datatype.
- (SCOPE_DEFAULT_HT_SIZE): New macro.
- (CLASS_SCOPE_HT_SIZE): Likewise.
- (NAMESPACE_ORDINARY_HT_SIZE): Likewise.
- (NAMESPACE_STD_HT_SIZE): Likewise.
- (GLOBAL_SCOPE_HT_SIZE): Likewise.
- (binding_table_construct): New function.
- (binding_table_free): Likewise.
- (binding_table_new): Likewise.
- (binding_table_expand): Likewise.
- (binding_table_insert): Likewise.
- (binding_table_find): Likewise.
- (binding_table_find_anon_type): Likewise.
- (binding_table_reverse_maybe_remap): Likewise.
- (binding_table_remove_anonymous_types): Likewise.
- (binding_table_foreach): Likewise.
- (struct cp_binding_level): Remove tags field. Add type_decls.
- (pop_binding_level): Free binding_entries if possible.
- (kept_level_p): Tidy.
- (poplevel): Remove unused variable tags.
- (bt_print_entry): New function.
- (print_binding_level): Use it.
- (push_namespace): Construct binding table.
- (maybe_process_template_type_declaration): Tidy.
- (pushtag): Likewise.
- (clear_anon_tags): Likewise.
- (cxx_remember_type_decls): New function.
- (lookup_tag): Tidy.
- (lookup_tag_reverse): Likewise.
- (cxx_init_decl_processing): Construct binding_table for the global
- scope.
- (store_parm_decls): Remove pointless code.
- (gettags): Remove.
- (storetags): Likewise.
- * class.c (unreverse_member_declarations): Don't touch
- CLASSTYPE_TAGS.
- (pushclass): Remember CLASSTYPE_NESTED_UTDS.
- * pt.c (instantiate_class_template): Remove reference to
- CLASSTYPE_TAGS. Remeber CLASSTYPE_NESTED_UTDS.
- (bt_instantiate_type_proc): New function.
- (do_type_instantiation): Use it.
- * search.c (lookup_field_r): Use binding_table_find.
- * semantics.c (begin_class_definition): Remove reference to
- CLASSTYPE_TAGS. Nullify CLASSTYPE_NESTED_UTDS.
-
-2003-05-15 Jason Merrill <jason@redhat.com>
+ PR c++/14007
+ * pt.c (check_cv_quals_for_unify): Correct logic for disallowed
+ cv-qualifier unification.
+ * tree.c (cp_build_qualified_type_real): Renable DR295 logic.
- PR c++/5388
- * call.c (conditional_conversion): Don't consider implicit
- conversions if T2 is a base of T1.
- * cp-tree.h (DERIVED_FROM_P, UNIQUELY_DERIVED_FROM_P): Make boolean.
- (ACCESSIBLY_UNIQUELY_DERIVED_P, PUBLICLY_UNIQUELY_DERIVED_P): Likewise.
+2004-06-15 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- PR c++/10661
- * pt.c (instantiate_class_template): Also instantiate our
- enclosing class.
+ PR c++/15967
+ * search.c (build_new_1): Robustify.
-2003-05-13 Release Manager
+2004-06-14 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- * GCC 3.3 Released.
+ PR c++/15947
+ * parser.c (cp_parser_template_name): Ctors/dtors never need a
+ template keyword to disambiguate.
-2003-05-02 Richard Henderson <rth@redhat.com>
+2004-06-14 Mark Mitchell <mark@codesourcery.com>
- PR c++/10570
- * cfns.gperf: Comment out POSIX thread cancellation points,
- plus abort and raise.
- * cfns.h: Regenerate.
+ PR c++/15096
+ * decl.c (grokdeclarator): Ignore pointer-to-members when
+ computing template depth.
-2003-05-01 Mark Mitchell <mark@codesourcery.com>
+ PR c++/14930
+ * name-lookup.c (pushtag): Do not try to put class declarations in
+ explicit specialization scopes.
- * decl2.c (comdat_linkage): Don't externalize explicit
- instantiations.
+i2004-06-11 Mark Mitchell <mark@codesourcery.com>
-2003-04-29 Mark Mitchell <mark@codesourcery.com>
+ PR c++/15862
+ * name-lookup.c (unqualified_namespace_lookup): Do not ignore type
+ bindings for undeclared built-ins.
- PR c++/10551
- * pt.c (mark_decl_instantiated): Defer all explicit instantiations
- that have not yet been written out.
+2004-06-10 Jason Merrill <jason@redhat.com>
- PR c++/10549
- * class.c (layout_class_type): Mark overlong bitfields as having
- the maximum size permitted by their type, after layout.
+ PR c++/15875
+ Revert:
+ 2004-06-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ * init.c (build_offset_ref): Build SCOPE_REF with non-null
+ TREE_TYPE for non-dependent names.
+ * pt.c (type_dependent_expression_p): Handle SCOPE_REF with
+ unknown_type_node as its TREE_TYPE.
+ * cxx-pretty_print.c (pp_cxx_unqualified_id): Handle BASELINK.
+ * error.c (dump_decl) <SCOPE_REF case>: Use pp_expression.
+ (dump_expr) <SCOPE_REF case>: Likewise.
-2003-04-29 Mark Mitchell <mark@codesourcery.com>
+2004-06-10 Mark Mitchell <mark@codesourcery.com>
- PR c++/10527
- * error.c (dump_expr): Correctly handling of NEW_EXPR.4
+ PR c++/15227
+ * parser.c (cp_parser_direct_declarator): Robustify.
-2003-04-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ PR c++/15877
+ * pt.c (tsubst_copy): Use decl_constant_value on enumeration
+ constants in non-dependent contexts.
- * lang-options.h: Fix typo.
+ PR c++/14211
+ PR c++/15076
+ * typeck.c (build_static_cast): Wrap casts in NON_LVALUE_EXPR when
+ necessary.
-2003-04-29 Mark Mitchell <mark@codesourcery.com>
+2004-06-09 Mark Mitchell <mark@codesourcery.com>
- PR c++/10515
- * cp-tree.h (lookup_field_1): Declare it.
- * search.c (lookup_field_1): Make it public.
- * decl.c (reshape_init): Handle designated initializers.
+ Revert:
+ PR c++/15815
+ 2004-06-07 Mark Mitchell <mark@codesourcery.com>
+ * lex.c (handle_pragma_interface): Deprecate.
+ (handle_pragma_implementation): Likewise.
-2003-04-29 Mark Mitchell <mark@codesourcery.com>
+2004-06-07 Dan Kegel <dank@kegel.com>
- * decl.c (maybe_commonize_var): Further tweak support for systems
- without weak symbols.
+ PR c++/14808
+ * method.c (make_alias_for_thunk, use_thunk): Use TARGET_IS_PE_COFF
+ instead of __CYWGIN__ and __MINGW32__.
-2003-04-27 Mark Mitchell <mark@codesourcery.com>
+2004-06-07 Mark Mitchell <mark@codesourcery.com>
- * decl.c (maybe_commonize_var): Fix thinko in last patch.
+ PR c++/15815
+ * lex.c (handle_pragma_interface): Deprecate.
+ (handle_pragma_implementation): Likewise.
- PR c++/10506
- * method.c (use_thunk): Decrement immediate_size_expand.
-
- PR c++/10503
- * cp-tree.h (DECL_VAR_MARKED_P): New macro.
- (DECL_MAYBE_TEMPLATE): Remove.
- * class.c (fixed_type_or_null): Avoid infinite recursion.
-
-2003-04-27 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (maybe_commonize_var): Make the code match the comments.
- * pt.c (instantiate_decl): Move call to import_export_decl.
-
-2003-04-25 Mark Mitchell <mark@codesourcery.com>
-
- * decl2.c (finish_file): Don't call import_export_decl for
- functions that are not defined.
- (handle_class_head): Robustify.
- * pt.c (instantiate_decl): Do not call cp_finish_decl for
- variables that are not defined.
-
-2003-04-23 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10471
- * call.c (build_cxx_call): Robustify.
-
-2003-04-23 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10451
- * decl.c (grokdeclarator): Correct logic for "mutable" errors.
-
-2003-04-22 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10446
- * search.c (lookup_fnfields_1): Handle empty slots in the method
- vector.
-
-2003-04-22 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10428
- * decl.c (check_elaborated_type_specifier): New function, split
- out from ...
- (xref_tag): ... here. Use the new function in more places.
-
-2003-04-21 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (build_over_call): Use build_cxx_call.
- (build_cxx_call): New method, split out of build_over_call.
- * cp-tree.h (language_function): Add can_throw.
- (build_cxx_call): Declare it.
- * decl.c (finish_function): If a function does not contain any
- calls to functions that can throw an exception, indicate that
- fact.
- * decl2.c (mark_used): Do not defer the instantiation of
- functions, if the current function does not throw.
- * optimize.c (maybe_clone_body): Copy TREE_NOTHROW to the clones.
- * pt.c (instantiate_decl): Make sure import_export_decl is called
- before emitting things.
- * rtti.c (throw_bad_cast): Use build_cxx_call.
- (build_dynamic_cast_1): Likewise.
- * typeck.c (build_function_call): Likewise.
-
-2003-04-21 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/9881
- * typeck.c (build_unary_op): Fold all COMPONENT_REF addr
- expressions. Reverts my 2002-08-08 patch.
-
-2003-04-20 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/10405
- * search.c (lookup_field_1): Final scan goes backwards for
- types, forwards for non-types.
-
-2003-04-15 Jason Merrill <jason@redhat.com>
-
- * decl2.c (mark_used): Don't instantiate anything if
- skip_evaluation.
-
-2003-04-15 Mark Mitchell <mark@codesourcery.com>
-
- * init.c (build_new_1): Use nullexp instead of null_node to avoid
- unwanted macro expansion.
-
-2003-04-14 Ziemowit Laski <zlaski@apple.com>
-
- * tree.c (build_cplus_array_type_1): Do not call
- uses_template_parms() on a NULL index_type.
-
-2003-04-14 Andreas Schwab <schwab@suse.de>
-
- * init.c (build_new_1): Test use_cookie instead of cookie_size to
- avoid code-gen bug on ia64.
-
-2003-04-13 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10300
- * init.c (build_new_1): Correct logic for checking whether the
- return value from the allocation function was zero.
-
-2003-03-31 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/10278
- * spew.c (yyerror): Avoid crashing at all costs.
-
-2003-03-31 Jason Merrill <jason@redhat.com>
-
- PR java/10145
- * class.c (check_field_decl): Don't set DECL_ALIGN.
-
-2003-03-30 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/7647
- * search.c (lookup_field_1): Add want_type parameter.
- (lookup_field_r): Adjust call to lookup_field_1.
-
-2003-03-28 Jason Merrill <jason@redhat.com>
-
- PR c++/10245
- * cvt.c (force_rvalue): New fn.
- * call.c (build_conditional_expr): Use it.
- * cp-tree.h: Declare it.
-
-2003-03-28 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/10047
- * decl2.c (finish_file): Don't warn about explicitly instantiated
- inline decls.
-
-2003-03-27 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/10158
- * spew.c (snarf_method):Set DECL_INITIALIZED_IN_CLASS for
- members.
- * pt.c (instantiate_decl): Only reduce the template args for
- friends that are not defined in class.
-
-2003-03-24 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/9898, PR c++/383, DR 322
- * pt.c (maybe_adjust_types_for_deduction) [DEDUCE_CONV]: Look
- through reference types on both PARM and ARG.
-
- PR c++/10199
- * call.c (build_method_call): Deal with LOOKUP_EXPR.
- * semantics.c (finish_object_call_expr): Use build_method_call
- when in a template decl.
-
-2003-03-23 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/7086
- * semantics.c (genrtl_named_return_value): Adjust calls to
- put_var_into_stack.
- * typeck.c (cxx_mark_addressable): Likewise.
-
-2003-03-20 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/6412
- * cp/decl2.c (arg_assoc_class): Correct check for namespace-scope
- friends.
- * cp/pt.c (instantiate_class_template): Fix formatting.
-
-2003-03-19 Jason Merrill <jason@redhat.com>
-
- PR c++/8316, c++/9315, c++/10136
- * call.c (joust): Improve wording.
-
-2003-03-18 Roger Sayle <roger@eyesopen.com>
-
- PR c++/10031
- * decl.c (duplicate_decls): Use the new type when prototyping
- anticipated decls, even when the types match. This defines the
- exception list for the built-in function.
-
-2003-03-17 Jason Merrill <jason@redhat.com>
-
- PR c++/10091
- * typeck.c (build_class_member_access_expr): Compare
- TYPE_MAIN_VARIANTs.
-
- * decl.c (finish_function): Don't skip a block.
-
- PR c++/9993
- * decl.c (finish_function): Only allow the NRVO to use variables
- declared at function scope.
-
-2003-03-17 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/9629
- * cp-tree.h (struct language_function): Add in_base_initializer.
- (in_base_initializer): define it.
- (expand_member_init): Remove INIT param.
- * init.c (expand_member_init): Remove INIT param, return the member.
- (emit_mem_initializers): Set in_base_initializer.
- * class.c (build_base_path): Check in_base_initializer.
- * parse.y (begin_member_init): New reduction.
- (member_init): Use it.
- * pt.c (tsubst_initializer_list): Set in_base_initializer.
-
-2003-03-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/6440
- * pt.c (maybe_process_partial_specialization): Handle
- member class template when enclosing class template is
- explicit specialized.
- (most_general_template): Stop looking when DECL is already
- specialized.
-
-2003-03-13 Jason Merrill <jason@redhat.com>
-
- PR c++/9420
- * search.c (lookup_conversions): Call complete_type here.
- * call.c (implicit_conversion): Not here.
-
-2003-03-13 Jason Merrill <jason@redhat.com>
-
- PR c++/9336
- * decl2.c (lookup_arg_dependent): Handle error_mark_node.
-
-2003-03-13 Mark Mitchell <mark@codesourcery.com>
-
- * decl2.c (do_nonmember_using_decl): Correct handling of
- simultaneous type/non-type bindings.
-
-2003-03-13 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (initialize_reference): Remove bogus assertion.
- * decl.c (build_ptrmemfunc_type): Revert change of 2003-03-09.
-
-2003-03-12 Andrew Lewycky <andrew@mxc.ca>
-
- PR c++/7050
- * expr.c (cxx_expand_expr): Return const0_rtx for throw
- expressions.
-
-2003-03-11 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9474
- * decl2.c (do_nonmember_using_decl): Do not call duplicate decls
- to merge old and new declarations.
-
-2003-03-11 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9924
- * decl2.c (do_nonmember_using_decl): Ignore anticipated builtins.
-
-2003-03-11 Jason Merrill <jason@redhat.com>
-
- PR c++/9820
- * search.c (lookup_member): Fix handling of functions in a class
- being defined.
-
-2003-03-11 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/8700
- * call.c (print_z_candidates): Avoid printing duplicates.
-
-2003-03-11 Jason Merrill <jason@redhat.com>
-
- PR c++/8660
- * decl2.c (check_classfn): A member template only matches a
- member template.
-
-2003-03-10 Devang Patel <dpatel@apple.com>
-
- PR c++/9394
- * g++spec.c (lang_specific_driver): Use DEFAULT_WORD_SWITCH_TAKES_ARG.
-
-2003-03-10 Jason Merrill <jason@redhat.com>
-
- PR c++/9798
- * decl.c (push_using_directive): Push before recursing.
-
- PR c++/9868
- * call.c (resolve_scoped_fn_name): Handle the case of a function
- pointer member.
- * init.c (build_offset_ref): Handle getting a FIELD_DECL for NAME.
-
- * decl2.c (build_offset_ref_call_from_tree): Only mess with 'this'
- argument in the pointer-to-member case.
-
-2003-03-09 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9373
- * cp-lang.c (cxx_get_alias_set): Use alias set zero for
- pointers to member functions.
-
- PR c++/8534
- * decl.c (build_ptrmemfunc_type): Do not allow default arugments
- in pointer-to-member-function types.
-
-2003-03-09 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9912
- * cp-tree.h (is_ancestor): New function.
- * decl2.c (is_namespace_ancestor): Rename to ...
- (is_ancestor): ... this.
- (namespace_ancestor): Use it.
- (set_decl_namespace): Likewise.
- (handle_class_head): Check for invalid class definitions.
-
-2003-03-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- Compile-time improvement: 2/n.
- * cp-tree.h (struct cxx_binding): New datatype;
- (struct lang_identifier): Use it.
- (LOCAL_BINDING_P): Adjust definition.
- (INHERITED_VALUE_BINDING_P): Likewise.
- (BINDING_SCOPE): Likewise.
- (BINDING_HAS_LEVEL_P): Likewise.
- (BINDING_VALUE): Likewise.
- (BINDING_TYPE): Likewise.
- (IDENTIFIER_VALUE): Likewise.
- (struct tree_binding): Remove.
- (TS_CP_BINDING): Likewise.
- ((union lang_tree_node): Remove field "binding".
- (cxx_binding_clear): New macro.
- (binding_for_name): Adjust return type.
- (qualified_lookup_using_namespace): Adjust prototype.
- (lookup_using_namespace): Adjust prototype.
- (cxx_scope_find_binding_for_name): Declare.
- * cp-tree.def: Remove CPLUS_BINDING definition.
- * parse.y (parse_scoped_id): Don't type-abuse of 'id'. Allocate
- temporary cxx_binding on stack. Simplify.
- * decl.c (push_binding): Adjust local variable type.
- (add_binding): Likewise.
- (push_class_binding): Likewise.
- (pop_binding): Likewise.
- (poplevel): Likewise.
- (poplevel_class): Likewise.
- (free_bindings): Adjust type.
- (find_binding): Adjust return type, add a third parameter. Remove
- non-useful assertion now that we use static typing.
- (cxx_scope_find_binding_for_name): New function.
- (binding_for_name): Use it. Adjust local variable type. Simplify.
- (namespace_binding): Simplify.
- (set_namespace_binding): Likewise.
- (set_identifier_type_value_with_scope): Adjust local variable type.
- (lookup_tag): Don't type-abuse of local variable 'old'.
- (lookup_namespace_name): Likewise. Allocate binding on stack.
- (select_decl): Adjust prototype.
- (unqualified_namespace_lookup): Allocate binding on stack.
- Don't type-abuse of local variable 'val'.
- (lookup_name_real): Likewise.
- (maybe_inject_for_scope_var): Adjust local variable type.
- (cp_tree_node_structure): Remove CPLUS_BINDING case label.
- (namespace_binding): Adjust logic, simplify.
- (BINDING_LEVEL): Adjust definition.
- (push_class_level_binding): Adjust local variable type.
- (struct cxx_saved_binding): Adjust field 'binding' type.
- * decl2.c (ambiguous_decl): Adjust prototype.
- (lookup_using_namespace): Adjust local variable type.
- (qualified_lookup_using_namespace): Catch type error and correct
- ensueing logic error.
- (do_nonmember_using_decl): Adjust local variable type. Allocate
- temporary cxx_binding on stack.
- (do_toplevel_using_decl): Adjust local variable type.
- * ptree.c (cxx_print_cxx_binding): New function.
- (cxx_print_identifier): Use it.
- (cxx_print_xnode): Delete CPLUS_BINDING case label.
-
-2003-03-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/9970
- * decl.c (duplicate_decls): Only copy DECL_THUNKS for virtual
- functions.
-
-2003-03-07 Matt Austern <austern@apple.com>
-
- * cp-tree.h (struct lang_type_class): add field for key method
- (cp_global_trees): rename dynamic_classes to keyed_classes
- (key_method): add definition
- * class.c (finish_struct_1): compute class's key method, and add
- the class to keyed_classes list if there is no key method.
- * decl.c (finish_function): add class to keyed_classes list if we
- see a definition of the class's key method.
- * pt.c (instantiate_class_template): add template specialization
- of a dynamic class to keyed_classes list.
- * decl2.c (key_method): remove
- (finish_file): iterate only through keyed_classes list when
- deciding whether to emit vtables, remove class from its list after
- we do the emission.
-
-2003-03-08 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9809
- * call.c (add_function_candidate): Skip builtin fuctions that have
- not yet been declared.
-
-2003-03-07 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (reference_binding): Remove REF_IS_VAR parameter.
- (implicit_conversion): Adjust call to reference_binding.
- (make_temporary_var_for_ref_to_type): Add TYPE parameter.
- (initialize_reference): Adjust handling for references bound to
- rvalues.
- * cp-tree.h (make_temporary_var_for_ref_to_temp): Change
- prototype.
- (real_non_cast_lvalue_p): New method.
- * cvt.c (build_up_reference): Adjust use of
- make_temporary_var_for_ref_to_temp.
- * tree.c (real_non_cast_lvalue_p): New method.
-
-2003-03-06 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (merge_conversion_sequences): New function.
- (build_conv): Set ICS_USER_FLAG for USER_CONVs.
- (convert_class_to_reference): Correct handling of second
- standard conversion sequence in a user-defined conversion
- sequence.
- (build_user_type_conversion_1): Use merge_conversion_sequences.
- * cp-tree.def: Add comments for CONV nodes.
-
-2003-03-06 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9965
- * call.c (reference_binding): Add ref_is_var parameter.
- (implicit_conversion): Adjust call to reference_binding.
- (initialize_reference): Likewise.
-
- PR c++/9400
- * decl.c (pushdecl): Don't check for shadowing of DECL_ARTIFICIAL
- PARM_DECLs.
-
-2003-03-06 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9791
- * class.c (get_basefndecls): Use lookup_fnfields_1.
-
-2003-03-02 Matt Austern <austern@apple.com>
-
- * decl.c (cp_binding_level): Add static_decls varray member.
- (add_decl_to_level): Add static/inline namespace scope
- declarations to static_decls array.
- (wrapup_global_for_namespace): Pass static_decls only, instead of
- all decls, to wrapup_global_declarations/check_global_declarations.
- (push_namespace): Initialize static_decls for ordinary namespaces.
- (cxx_init_decl_processing): Initialize static_decls for global
- namespace.
-
-2003-03-05 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (end_of_class): Correct thinko.
-
-2003-03-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * cp-tree.h (cxx_saved_binding): Declare.
- (struct saved_scope): Adjust type of field 'old_binding'.
- * decl.c (cxx_saved_binding_make): New macro.
- (struct cxx_saved_binding): Define.
- (store_bindings): Adjust prototype. Use cxx_saved_binding to save
- C++ bindings.
- (maybe_push_to_top_level): Adjust local variable type.
- (pop_from_top_level): Likewise.
-
-2003-03-03 Jason Merrill <jason@redhat.com>
-
- * decl.c (finish_enum): Do set the type in a template. Simplify.
- * pt.c (tsubst_enum, tsubst_copy): Revert last patch.
-
-2003-03-03 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9878
- * call.c (convert_class_to_reference): Correct conversion
- sequences.
- (reference_binding): Add ref_bound_directly_to_rvalue_p parameter.
- (implicit_conversion): Adjust call to reference_binding.
- (add_candidate): Change type of candidates parameter.
- (add_function_candidate): Likewise.
- (add_conv_candidate): Likewise.
- (build_builtin_candidate): Likewise.
- (add_builtin_candidate): Likewise.
- (add_builtin_candidates): Likewise.
- (add_template_candidate_real): Likewise.
- (add_template_candidate): Likewise.
- (add_template_conv_candidate): Likewise.
- (build_user_type_conversion_1): Adjust accordingly.
- (build_object_call): Likewise.
- (build_conditional_expr): Likewise.
- (add_candidates): Likewise.
- (build_new_op): Likewise.
- (convert_like_real): Use USER_CONV_CAND. Use build_nop.
- (build_new_method_call): Adjust calls to add_function_candidate.
- (make_temporary_var_for_ref_to_temp): New function.
- (initialize_reference): Add decl parameter.
- * class.c (build_rtti_vtbl_entries): Use build_address and
- build_nop.
- * cp-tree.h (initialize_reference): Change prototype.
- (make_temporary_var_for_ref_to_temp): New function.
- (build_type_conversion): Change prototype.
- (build_address): New function.
- (build_nop): Likewise.
- * cvt.c (cp_convert_to_pointer): Adjust call to
- build_type_conversion. Avoid indicating redundant NOP_EXPRs.
- Use build_nop.
- (convert_to_pointer_force): Use build_nop.
- (build_up_reference): Use make_temporary_var_for_ref_to_temp.
- (convert_to_reference): Adjust call to build_type_conversion.
- (ocp_convert): Likewise.
- (build_type_conversion): Remove for_sure parameter.
- * decl.c (grok_reference_init): Use initialize_reference.
- * typeck.c (build_address): New function.
- (build_nop): Likewise.
- (build_unary_op): Use them.
- (build_ptrmemfunc): Tidy slightly.
- (convert_for_initialization): Adjust call to
- initialize_reference.
- * typeck2.c (store_init_value): Remove #if 0'd code.
-
-2003-03-02 Ashif Harji <asharji@uwaterloo.ca>
-
- * lang-specs.h (default_compilers): Add -no-integrated-cpp flag to
- invoke an external cpp during compilation.
-
-2003-02-28 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9892
- * pt.c (instantiate_decl): Clear DECL_RTL for a VAR_DECL when
- instantiating it.
-
-2003-02-28 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9879
- * cp-tree.h (build_zero_init): Add parameter.
- * decl.c (cp_finish_decl): Adjust call.
- * init.c (build_zero_init): Add nelts parameter. Adjust recursive
- calls.
- (build_default_init): Add nelts parameter. Adjust calls to
- build_zero_init.
- (build_new_1): Adjust call to build_default_init.
- * typeck2.c (process_init_constructor): Adjust call to build_zero_init.
-
-2003-02-27 Devang Patel <dpatel@apple.com>
-
- * decl.c (finish_enum): Merge two 'for' loops. Copy value node if required.
- Postpone enum setting for template decls.
- (build_enumerator): Delay copying value node until finish_enum (). Remove
- #if 0'ed code.
- * pt.c (tsubst_enum): Set TREE_TYPE and copy value node.
- (tsubst_copy): Add check for enum type.
-
-
-2003-02-25 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9829
- * decl.c (grokdeclarator): Handle SCOPE_REFs whose second argument
- is a NAMESPACE_DECL.
-
-2003-02-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
-
- * decl.c (add_binding): Time TV_NAME_LOOKUP.
- (push_class_binding): Likewise.
- (set_namespace_binding): Likewise.
-
-2003-02-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/9602
- * typeck2.c (abstract_virtuals_error): Don't check when we
- are processing a template.
-
-2003-02-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/7982
- * decl.c (warn_about_implicit_typename_lookup): Handle TYPEOF_TYPE.
-
-2003-02-21 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9749
- * decl.c (grokdeclarator): Do not allow parameters with variably
- modified types.
-
- PR c++/9727
- * decl2.c (push_scope): Don't pushclass for non-class types.
- (pop_scope): Don't popclass either.
-
- PR c++/8906
- * decl.c (lookup_name_real): Use IMPLICIT_TYPENAME_P.
- * decl2.c (handle_class_head): Check it.
-
- PR c++/8724
- * call.c (build_method_call): Make sure that the type destroyed in
- an explicit destructor call is complete.
-
-2003-02-20 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9729
- * mangle.c (mangle_conv_op_name_for_type): Issue an error message
- when the G++ 3.2 ABI prevents correct compilation.
-
-2003-02-18 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/9704
- * class.c (layout_class_type): In the 3.2 ABI, take into account
- trailing bit fields when computing CLASSTYPE_SIZE_UNIT.
-
-2003-02-18 Matt Austern <austern@apple.com>
-
- * cp/cp-lang.c: Change lang hooks so that final_write_globals does
- nothing for C++.
- * cp/decl.c (wrapup_globals_for_namespace): Remove special
- handling of global namespace.
+ PR c++/15766
+ * parser.c (cp_parser_iteration_statement): Fix typo in error
+ message.
-2003-02-18 Jason Merrill <jason@redhat.com>
+ PR c++/14777
+ * pt.c (tsubst_default_argument): Do not defer access checks
+ while substituting into the default argument.
- PR c++/9623
- * decl.c (reshape_init): Don't mess with initializer labels.
+ PR c++/15554
+ * pt.c (tsubst_copy): Do not try to substitute for an enumeration
+ constant in a non-dependent context.
+
+ PR c++/15057
+ * except.c (build_throw): Ensure that temp_expr has been
+ initialized.
-2003-02-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+2004-06-06 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- PR c++/9459
- * error.c (dump_type_prefix): Handle TYPEOF_TYPE.
- (dump_type_suffix): Likewise.
+ PR c++/15503
+ * parser.c (cp_parser_mem_initializer_id): Gracefully reject
+ 'typename', and accept 'template'.
-2003-02-17 Michael Elizabeth Chastain <mec@shout.net>
+2004-06-01 Jason Merrill <jason@redhat.com>
- PR debug/9717
- * class.c (build_base_field): Mark fields for base classes with
- DECL_IGNORED_P.
+ PR c++/15142
+ * call.c (call_builtin_trap): Remove type parm.
+ (convert_arg_to_ellipsis): Change a non-POD argument to integer type.
+ (build_x_va_arg): Dereference a null pointer for a non-POD argument.
-2003-02-13 Andrew Pinski <pinskia@physics.uc.edu>
+2004-06-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
- * decl.c: (define_label): Fix warning for return 0 instead of NULL.
+ PR c++/13092
+ * init.c (build_offset_ref): Build SCOPE_REF with non-null
+ TREE_TYPE for non-dependent names.
+ * pt.c (type_dependent_expression_p): Handle SCOPE_REF with
+ unknown_type_node as its TREE_TYPE.
+ * cxx-pretty_print.c (pp_cxx_unqualified_id): Handle BASELINK.
+ * error.c (dump_decl) <SCOPE_REF case>: Use pp_expression.
+ (dump_expr) <SCOPE_REF case>: Likewise.
-2003-02-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+2004-06-01 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- * Make-lang.in (cp/decl2.o): Add dependency on timevar.h
- * decl2.c: Include "timevar.h".
- (namespace_ancestor): Time name lookup.
- (add_using_namespace): Likewise.
- (lookup_using_namespace): Likewise.
- (qualified_lookup_using_namespace): Likewise.
- (decl_namespace): Likewise.
- (lookup_arg_dependent): Likewise.
- * lex.c (do_identifier): Likewise.
- (do_scoped_id): Likewise.
- * pt.c (lookup_template_class): Likewise.
+ PR c++/14932
+ * parser.c (cp_parser_postfix_expression): Allow subscript
+ operator in offsetof.
-2003-02-12 Gabriel Dos Reis <gdr@integrable-solutions.net>
+2004-05-31 Mark Mitchell <mark@codesourcery.com>
- * decl.c (define_label): Don't forget to pop TV_NAME_LOOKUP.
+ PR c++/15701
+ * friend.c (add_friend): Do not try to perform access checks for
+ functions from dependent classes.
-2003-02-11 Gabriel Dos Reis <gdr@integrable-solutions.net>
+ PR c++/15742
+ * call.c (build_over_call): Set
+ current_function_returns_abnormally even in template functions.
- * decl.c: Include "timevar.h".
- (poplevel): Time name lookup.
- (find_binding): Likewise.
- (push_namespace): Likewise.
- (pop_nested_namespace): Likewise.
- (store_bindings): Likewise.
- (maybe_push_to_top_level): Likewise.
- (pop_from_top_level): Likewise.
- (push_local_name): Likewise.
- (pushtag): Likewise.
- (pushdecl): Likewise.
- (pushdecl_with_scope): Likewise.
- (pushdecl_namespace_level): Likewise.
- (pushdecl_top_level): Likewise.
- (pushdecl_class_level): Likewise.
- (push_class_level_binding): Likewise.
- (push_using_decl): Likewise.
- (push_using_directive): Likewise.
- (push_overloaded_decl): Likewise.
- (lookup_label): Likewise.
- (define_label): Likewise.
- (lookup_tag): Likewise.
- (lookup_tag_reverse): Likewise.
- (lookup_namespace_name): Likewise.
- (select_decl): Likewise.
- (unqualified_namespace_lookup): Likewise.
- (lookup_name_real): Likewise.
- (lookup_name_current_level): Likewise.
- (lookup_type_current_level): Likewise.
- (maybe_inject_for_scope_var): Likewise.
- (xref_tag): Likewise.
+ PR c++/15696
+ * cp-tree.h (invalid_nonstatic_memfn_p): New function.
+ * cvt.c (convert_to_void): Use it.
+ * typeck.c (invalid_nonstatic_memfn_p): New function.
+ (decay_conversion): Use it.
- * Make-lang.in (cp/decl.o): Add dependency on timevar.h
-
-2003-02-03 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/7129
- * operators.def: Add <?= and >?=.
+ PR c++/15625
+ * pt.c (tsubst_decl): Set DECL_FRIEND_CONTEXT for instantiated
+ templates.
-2003-01-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ PR c++/15629
+ * name-lookup.c (arg_assoc_class): Do not find template
+ specializations.
- PR c++/8849
- * error.c (dump_expr): Handle BASELINK.
- * pt.c (resolve_overloaded_unification): Handle FUNCTION_DECL.
+ PR c++/15209
+ * tree.c (lvalue_p_1): Only consider the right-hand side of "."
+ expressions when determining whether or not an express is packed.
-2003-01-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+2004-05-28 Mark Mitchell <mark@codesourcery.com>
- PR c++/9453
- * friend.c (is_friend): Always accept when SUPPLICANT is still
- a TEMPLATE_DECL.
- * pt.c (push_access_scope_real): Call push_to_top_level for
- function in namespace scope.
- (push_access_scope): Remove ARGS argument, all caller adjusted.
- (pop_access_scope): Call pop_from_top_level for function in
- namespace scope.
- (regenerate_decl_from_template): Use push_access_scope_real.
+ PR c++/15083
+ * decl2.c (delete_sanity): Set TREE_SIDE_EFFECTS on a DELETE_EXPR,
+ even in a templat.e
+ * init.c (build_new): Likewise.
-2003-01-29 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/15640
+ * name-lookup.c (arg_assoc): Robustify.
- PR c++/9437
- * pt.c (unify): Don't unify '*T' with 'U C::*'.
+ PR c++/15471
+ * typeck.c (unary_complex_lvalue): Use context_for_name_lookup
+ when determining the scope to use for a pointer to member.
+ (lookup_anon_field): Give it external linkage.
+ * cp-tree.h (lookup_anon_field): Declare it.
+ * expr.c (cplus_expand_constant): Use it.
-2003-01-27 Jeffrey D. Oldham <oldham@codesourcery.com>
+ PR c++/14668
+ * parser.c (cp_parser_simple_type_specifier): Call
+ maybe_note_name_used_in_class.
- PR c++/47
- * cp-tree.h (lookup_nested_field): Add declaration.
- * decl.c (lookup_name_real): Call lookup_nested_field.
- * search.c (lookup_nested_field): Add function.
+2004-05-23 Mark Mitchell <mark@codesourcery.com>
-2003-01-26 Christian Cornelssen <ccorn@cs.tu-berlin.de>
+ PR c++/15044
+ * parser.c (cp_parser_class_head): Robustify.
- * Make-lang.in (c++.install-common, c++.install-man)
- (c++.uninstall): Prepend $(DESTDIR) to destination paths in
- all (un)installation commands.
- (c++.install-common): Rewrite $(LN) commands to support
- DESTDIR with "ln" as well as with "ln -s".
+ PR c++/15317
+ * parser.c (cp_parser_decl_specifier_seq): Correct error in
+ comment.
+ (cp_parser_constructor_declarator_p): Treat attributes
+ as decl-specifiers.
-2003-01-24 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+ PR c++/15329
+ * typeck.c (build_unary_op): Do not attempt to resolve casts to
+ base classes in templates.
- * decl2.c (check_classfn): Fix uninitialized warning.
+ PR c++/15165
+ * pt.c (instantiate_template): Robustify.
-2003-01-22 Mark Mitchell <mark@codesourcery.com>
+ PR c++/15025
+ * decl.c (xref_tag): Issue errors about redeclaring template
+ classes as non-template classes.
- PR c++/9328
- * error.c (dump_decl): For an OVERLOAD, just print the name of the
- function; it doesn't make sense to try to print its type.
- * semantics.c (finish_typeof): Issue errors about invalid uses.
+ PR c++/14821
+ * name-lookup.c (supplement_binding): Allow redefinitions of
+ namespace aliases.
-2003-01-22 Josef Zlomek <zlomekj@suse.cz>
+ PR c++/14883
+ * parser.c (cp_parser_template_argument): Robustify.
- PR/9386, PR/8801
- 2002-12-27 Mark Mitchell <mark@codesourcery.com>
- * typeck.c (build_class_member_access_expr): Fix anonymous union
- handling.
+2004-05-22 Mark Mitchell <mark@codesourcery.com>
-2003-01-17 Jason Merrill <jason@redhat.com>
+ PR c++/15285
+ PR c++/15299
+ * pt.c (build_non_dependent_expr): Expand the set of tree nodes
+ recognized as overloaded functions.
- PR c++/9167, c++/9358
- * decl.c (require_complete_types_for_parms): Also update DECL_ARG_TYPE.
+ PR c++/15507
+ * class.c (layout_nonempty_base_or_field): Do not try to avoid
+ layout conflicts for unions.
-2003-01-17 Jason Merrill <jason@redhat.com>
+ PR c++/15542
+ * typeck.c (build_x_unary_op): Instantiate template class
+ specializations before looking for "operator &".
- PR c++/9342
- * call.c (build_conditional_expr): Always do lvalue-rvalue
- conversion.
+ PR c++/15427
+ * typeck.c (complete_type): Layout non-dependent array types, even
+ in templates.
-2003-01-16 Jason Merrill <jason@redhat.com>
+ PR c++/15287
+ * typeck.c (build_unary_op): Do not optimize "&x[y]" when in a
+ template.
- PR c++/8564
- * init.c (build_vec_init): Re-add maxindex parm.
- (perform_member_init, build_aggr_init): Pass it.
- (build_new_1): Pass it. Use an incomplete array type for full_type.
- * typeck.c (build_modify_expr): Pass it.
- * cp-tree.h: Adjust.
+2004-04-23 Giovanni Bajo <giovannibajo@gcc.gnu.org>
-2003-01-13 Jason Merrill <jason@redhat.com>
+ PR c++/15064
+ * parser.c (cp_parser_postfix_expression): typeid operator cannot be
+ used in integral constant expressions.
- PR c++/8748
- * class.c (build_base_path): Take the address before calling save_expr.
+2004-04-18 Release Manager
- * call.c (build_user_type_conversion_1): Do set ICS_BAD_FLAG if
- all the ambiguous conversions are bad.
+ * GCC 3.4.0 released.
- * class.c (maybe_warn_about_overly_private_class): Don't stop
- searching when we find a nonprivate method.
+2004-04-08 Danny Smith <dannysmith@users.sourceforge.net>
-2003-01-09 Jakub Jelinek <jakub@redhat.com>
+ PR c++/14808
+ * method.c (make_alias_for_thunk): Just return function decl
+ for one_only functions if __CYGWIN__ or __MINGW32__
+ (use_thunk): Don't put function and thunk in same one_only
+ section if __CYGWIN__ or __MINGW32__.
- * decl.c (start_decl): Only check DECL_THREAD_LOCAL for VAR_DECLs.
+2004-04-08 Jakub Jelinek <jakub@redhat.com>
-2003-01-09 Jakub Jelinek <jakub@redhat.com>
+ * decl2.c (mark_used): Don't segfault if cfun != NULL but
+ current_function_decl == NULL.
- * decl.c (start_decl): Don't set DECL_COMMON for __thread variables.
+2004-04-01 Mark Mitchell <mark@codesourcery.com>
-2003-01-07 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ PR c++/14803
+ * typeck.c (get_delta_difference): Call fold before returning the
+ value.
- PR c++/9030
- * decl.c (make_typename_type): Check access only when tf_error.
- (make_unbound_class_template): Likewise.
- * pt.c (saved_access_scope): New variable.
- (push_access_scope_real): New function.
- (push_access_scope): Likewise.
- (pop_access_scope): Likewise.
- (tsubst_default_argument): Use them.
- (instantiate_template): Likewise.
- (regenerate_decl_from_template): Likewise.
- (instantiate_decl): Likewise.
- (get_mostly_instantiated_function_type): Likewise.
+2004-04-01 Richard Henderson <rth@redhat.com>
-2003-01-06 Mark Mitchell <mark@codesourcery.com>
+ PR c++/14804
+ * decl.c (cp_finish_decl): Preserve TREE_READONLY more often.
+ * typeck2.c (split_nonconstant_init): Clear TREE_READONLY.
- PR c++/9165
- * decl2.c (build_cleanup): Mark the object as used.
+2004-04-01 Mark Mitchell <mark@codesourcery.com>
-2003-01-03 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/14810
+ * name-lookup.c (maybe_push_cleanup_level): Robustify.
- PR c++/45, c++/3784
- * tree.c (cp_tree_equal, TEMPLATE_PARM_INDEX): The types must be
- the same too.
+2004-03-30 Mark Mitchell <mark@codesourcery.com>
-2002-12-30 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/14724
+ * decl.c (start_decl_1): Do not decide whether or not to create a
+ new cleanup level until after the type has been completed.
- PR c++/9054
- * class.c (layout_class_type): Set DECL_CONTEXT of type for base.
- * dump.c (cp_dump_tree, RECORD_TYPE): Deal with type for base types.
+ PR c++/14763
+ * pt.c (tsubst_default_argument): Clear current_function_decl.
-2002-12-26 Nathan Sidwell <nathan@codesourcery.com>
+2004-03-28 Jan Hubicka <jh@suse.cz>
- PR c++/4803
- * decl2.c (mark_used): Defer inline functions.
- (finish_file): Merge deferred_fns loops. Check all used
- inline functions have a definition.
- * method.c (make_thunk): Thunks are not inline.
+ PR C++/14639
+ * method.c (use_think): Do not mark thunk as referenced.
- PR c++/5116, c++/764
- * call.c (build_new_op): Make sure template class operands are
- instantiated.
+2004-03-21 Mark Mitchell <mark@codesourcery.com>
-2002-12-24 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/14616
+ * decl.c (cp_finish_decl): Compute the size of arrays declared in
+ templates, if their type is non-dependent.
- PR C++/7964
- * cp-tree.h (resolve_scoped_fn_name): Prototype.
- * call.c (resolve_scoped_fn_name): New function. Deal with
- more template expansion. Broken out of ...
- * parse.y (parse_finish_call_expr): ... here. Call it.
- * decl2.c (build_expr_from_tree, CALL_EXPR): Use
- resolve_scoped_fn_name and build_call_from_tree.
+2004-03-19 Mark Mitchell <mark@codesourcery.com>
- PR c++/9053
- * decl.c (duplicate_decls): Templates may be disambiguated by
- return type.
+ * call.c (build_op_delete_call): Do not forget the placement
+ arguments when iterating through mutiple delete operators.
- PR c++/8702
- * decl2.c (check_classfn): Use lookup_fnfield_1. List all
- conversion operators on failure.
+ * cp-tree.h (svaed_scope): Remove last_parms.
+ (NEW_DELETE_OPNAME_P): New macro.
+ (last_function_parms): Remove.
+ (do_friend): Adjust prototype.
+ * decl.c (grokparms): Return the PARM_DECLs directly, rather than
+ using last_function_parms.
+ (grokfndecl): Take the PARM_DECLs as an argument, rather than
+ using last_function_parms.
+ (grokdeclarator): Adjust accordingly. Do not form METHOD_TYPEs
+ for class-specific operator new and operator delete.
+ (grok_op_properties): Do not look for allocation functions with
+ METHOD_TYPEs.
+ (start_function): Use DECL_ARGUMENTS instead of
+ last_function_parms.
+ * decl.h (last_function_parms): Do not declare.
+ * decl2.c (grokclassfn): Do not use last_function_parms.
+ * friend.c (do_friend): Remove parmdecls parameter.
+ * name-lookup.c (push_to_top_level): Do not save last_function_parms.
+ (pop_from_top_level): Do not restore it.
+ * pt.c (check_explicit_specialization): Do not adjust
+ last_function_parms.
-2002-12-22 Nathan Sidwell <nathan@codesourcery.com>
+ * name-lookup.c (do_local_using_decl): Create a local binding for
+ types brought in via using declarations.
- PR c++/8572
- * cp-tree.h (grokoptypename): Add SCOPE parameter.
- * decl2.c (grokoptypename): Add SCOPE parameter. tsubst the type
- if in a template scope.
- * parse.y (unoperator): Return the scope.
- (operator_name): Adjust grokoptypename call.
+ * name-lookup.c (lookup_arg_dependent): Handle block-scope
+ function declarations correctly.
-2002-12-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ * semantics.c (finish_id_expression): Correct handling of
+ conversion operators to dependent types.
- * cp-tree.h (make_unbound_class_template): Use tsubst_flags_t.
- * decl.c (make_unbound_class_template): Adjust. Check for tf_error.
- * pt.c (tsubst) [OFFSET_TYPE]: Check for tf_error.
+ * typeck.c (lookup_destructor): Allow the use of destructors from
+ base classes.
+
+2004-03-19 Giovanni Bajo <giovannibajo@gcc.gnu.org>
-2002-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ PR c++/14545
+ * parser.c (cp_parser_functional_cast): A cast to anything
+ but integral or enumaration type is not an integral constant
+ expression.
+ * pt.c (value_dependent_expression_p): Handle cast expressions
+ without operands (such as "int()").
- PR c++/8099
- * friend.c (make_friend_class): Allow partial specialization
- when declaration is not a template friend.
+2004-03-18 Mark Mitchell <mark@codesourcery.com>
-2002-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ * semantics.c (finish_pseudo_destructor_expr): Allow differing
+ cv-qualification between the type named by the
+ pseudo-destructor-name and the object-type.
- PR c++/3663
- * pt.c (lookup_template_class): Copy TREE_PRIVATE and
- TREE_PROTECTED to created decl nodes.
+ * search.c (accessible_base_p): Handle non-proper bases.
-2002-12-18 Mark Mitchell <mark@codesourcery.com>
+ * name-lookup.c (do_nonmember_using_decl): If a using declaration
+ refers to a single overloaded function, set the type of the
+ function.
+ * tree.c (lvalue_type): Simplify.
+ * typeck.c (type_unknown_p): Do not assume all OVERLOADs have an
+ unknown type.
+ (build_unary_op): Handle OVERLOADs with known types.
+
+ * decl.c (duplicate_decls): Do not destroy DECL_ARGUMENTS for
+ function templates.
+
+ * parser.c (cp_parser_postfix_expression): Handle the use of
+ "typename" in non-dependent contexts. Convert appropriately when
+ when using a qualified name after "->" or ".".
+
+ * call.c (conditional_conversion): Honor the requirement that some
+ conversions refer to the original object.
+
+ * call.c (build_conditional_expr): Do not call force_rvalue for
+ operands of void_type when the conditional expression itself has
+ void type.
+ * name-lookup.c (pushdecl): Don't consider a declaration of a
+ function named "main" to be an overload of a type named "main".
+ * parser.c (cp_parser_template_name): Perform name lookup when the
+ template name is proceeded by "template" if the qualifying scope
+ is non-dependent.
+ * typeck.c (composite_pointer_type_r): Correctly handle
+ pointer-to-member types.
+ (build_const_cast): Likewise.
- * class.c (build_base_field): Do not set DECL_PACKED on the
- FIELD_DECL.
+2004-03-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14586
+ * cp-tree.h (build_new_op): Change prototype.
+ (build_x_binary_op): Likewise.
+ * call.c (build_new_op): Add overloaded_p parameter.
+ * decl2.c (grok_array_decl): Adjust call to build_new_op.
+ * parser.c (cp_parser_binary_expression): Note that uses of
+ overloaded operators prevents an expression from being considered
+ an integral constant.
+ * pt.c (tsubst_copy_and_build): Adjust calls to build_new_op and/or
+ build_x_binary_op.
+ * semantics.c (finish_call_expr): Likewise.
+ * typeck.c (rationalize_conditional_expr): Likewise.
+ (build_x_indirect_ref): Likewise.
+ (build_x_binary_op): Likewise.
+ (build_x_unary_op): Likewise.
+ (build_x_compound_expr): Likewise.
+ (build_modify_expr): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
-2002-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+2004-03-13 Mark Mitchell <mark@codesourcery.com>
- * parse.y (bad_parm): Add missing argument to error function call.
+ PR c++/14550
+ * parser.c (cp_parser_non_integral_constant_expression): Encode
+ more of the idiom that surrounded calls to this function within
+ the function itself
+ (cp_parser_primary_expression): Adjust accordingly.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_assignment_expression): Likewise.
+ (cp_parser_expression): Likewise.
+ (cp_parser_new_expression): Note that new-expressions are not
+ allowed in integral constant expressions.
+ (cp_parser_delete_expression): Likewise.
-2002-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+2004-03-11 Mark Mitchell <mark@codesourcery.com>
- PR c++/8442
- * decl2.c (handle_class_head): Verify if the looked up name is a
- type or template.
- * pt.c (convert_template_argument): Fix type or template template
- parameter decision logic.
+ PR c++/14476
+ * decl.c (xref_tag): Do not create dummy ENUMERAL_TYPEs.
-2002-12-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+2004-03-10 Mark Mitchell <mark@codesourcery.com>
- PR C++/8031
- * cvt.c (convert_to_pointer_force): Don't try comparing against
- erronous type.
+ PR c++/14510
+ * decl.c (xref_tag): Disregard non-type declarations when
+ looking up a tagged type.
-2002-12-13 Geoffrey Keating <geoffk@apple.com>
+2004-03-10 Jason Merrill <jason@redhat.com>
- * cp-tree.h: Have the multiple-include guards around
- the entire file.
+ PR c++/14452
+ * tree.c (stabilize_init): Return whether or not it worked.
+ * init.c (build_new_1): If not, use a sentry.
+ * cp-tree.h: Adjust prototype.
-2002-12-10 Mark Mitchell <mark@codesourcery.com>
+2004-03-09 Nathan Sidwell <nathan@garibaldi.home>
- PR c++/8372
- * pt.c (tsubst_copy): Handle destructor names more correctly.
+ PR c++/14397
+ * call.c (convert_like_real): Build a const qualified temporary,
+ when testing ctor access.
-2002-12-10 Matt Austern <austern@apple.com>
+2004-03-09 Mark Mitchell <mark@codesourcery.com>
- * cp-tree.h: get rid of needs_virtual_reinit bit.
+ * call.c (initialize_reference): Fix typo.
-2002-12-09 Mark Mitchell <mark@codesourcery.com>
+2004-03-09 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- * NEWS: Document removal of in-class initialization extension for
- static data members of non-arithmetic, non-enumeration type.
- * decl.c (check_static_variable_definition): Do not allow that
- extension.
- * decl2.c (grokfield): Do not call digest_init when processing
- templates.
+ PR c++/14409
+ * pt.c (determine_specialization): For member templates, match also
+ constness.
-2002-12-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+ PR c++/14448
+ * parser.c (cp_parser_initializer_clause): Fold initializer if it is
+ non-dependent.
+ * pt.c (tsubst_copy_and_build): Handle NOP_EXPRs.
- * error.c (dump_expr): Fix format specifier warning.
+2004-03-09 Mark Mitchell <mark@codesourcery.com>
-2002-12-04 Geoffrey Keating <geoffk@apple.com>
+ PR c++/14230
+ * call.c (initialize_reference): Handle initializers that are
+ class-member access expressions applies to rvalues.
- * class.c (finish_struct_1): Correct comment.
- * cp-tree.c (DECL_SORTED_FIELDS): Likewise.
+ PR c++/14432
+ * name-lookup.c (supplement_binding): Ignore functions that are
+ marked DECL_ANTICIPATED.
-2002-12-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+2004-03-08 Mark Mitchell <mark@codesourcery.com>
- PR C++/8799
- * error.c (dump_expr): Don't ever try to dump a non-existent
+ PR c++/14401
+ * class.c (check_field_decls): Complain about non-static data
+ members of reference type in unions. Propagate
+ CLASSTYPE_REF_FIELDS_NEED_INIT and
+ CLASSTYPE_READONLY_FIELDS_NEED_INIT from the types of non-static
+ data members.
+ * init.c (perform_member_init): Complain about mbmers with const
+ type that are not explicitly initialized.
+
+2004-03-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/13170
+ * decl.c (xref_tag): Remove attribute handling.
+ * cp-tree.h: Adjust prototype.
+ * decl.c, parser.c, rtti.c: Adjust callers.
+ * parser.c (cp_parser_class_head): Pass back attributes in the
+ class head.
+ (cp_parser_class_specifier): Adjust.
+
+2004-03-08 Matt Austern <austern@apple.com>
+
+ PR debug/14079
+ * name-lookup.c (add_decl_to_level): Add extern variables, as well
+ as static, to static_decls array.
+
+2004-03-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/13944
+ * except.c (do_free_exception): Remove #if 0 wrapper.
+ (build_throw): Use it if we elide a copy into the
+ exception object.
+
+ * tree.c (stabilize_call): Fix thinko.
+
+ * init.c (build_new_1): Preevaluate initializer. Simplify EH code.
+ (build_init): Call a constructor rather than call build_aggr_init
+ for classes.
+ * except.c (stabilize_throw_expr): Remove.
+ (build_throw): Use stabilize_init instead of stabilize_throw_expr.
+ * tree.c (stabilize_call, stabilize_init): New fns.
+ * call.c (build_over_call): A constructor no longer returns the
+ address of the object.
+
+2004-03-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14324
+ * lex.c (retrofit_lang_decl): Treat entities with no linkage as
+ having C++ linkage for name-mangling purposes.
+
+ PR c++/14260
+ * parser.c (cp_parser_direct_declarator): Recognize constructor
+ declarators that use a template-id to name the class being
+ constructed.
+
+ PR c++/14337
+ * pt.c (tsubst_qualified_id): Handle dependent qualifying scopes.
+ (tsubst_expr): Do not call tsubst_copy, even when
+ processing_template_decl.
+
+2004-03-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14369
+ * pt.c (build_non_dependent_expr): Do not create a
+ NON_DEPENDENT_EXPR for a THROW_EXPR.
+
+ PR c++/14360
+ * parser.c (cp_parser_postfix_expression): Do not perform Koenig
+ lookup if ordinary name-lookup finds a non-function.
+ * pt.c (tsubst_copy_and_build): Likewise.
+
+ PR c++/14361
+ * parser.c (cp_parser_late_parsing_default_args): Check that there
+ are no extra tokens after the end of the default-argument
expression.
-2002-12-03 Jason Merrill <jason@redhat.com>
-
- PR c++/8674
- * call.c (build_over_call): Check specifically for TARGET_EXPR
- when eliding.
-
- PR c++/8461, c++/8625
- * call.c (convert_for_arg_passing): Don't mess with error_mark_node.
- (cp_convert_parm_for_inlining): Remove.
- * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
- Remove.
- * cp-tree.h (ADDR_IS_INVISIREF): Remove.
- * except.c (stabilize_throw_expr): Remove ADDR_IS_INVISIREF code.
-
- * call.c (build_user_type_conversion_1): Don't set ICS_BAD_FLAG on
- an ambiguous conversion.
-
-2002-12-03 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/8688
- * decl.c (reshape_init): Handle erroneous initializers.
-
-2002-12-02 Mark Mitchell <mark@codesourcery.com>
+ PR c++/14359
+ Backport 2004-02-12 Mark Mitchell <mark@codesourcery.com>
+ * decl.c (redeclaration_error_message): Correct handling of
+ templates.
+ * pt.c (tsubst_friend_declaration): Adjust code to determine
+ whether or not a friend template is a definition.
+ (tsubst_decl): Clear DECL_INITIAL for new FUNCTION_DECLs.
- PR c++/8720
- * spew.c (remove_last_token): Make sure that last_chunk is set
- correctly.
+2004-03-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
- PR c++/8615
- * error.c (dump_expr): Handle character constants with
- TREE_OVERFLOW set.
+ PR c++/14369
+ * error.c (dump_expr): Handle THROW_EXPR.
-2002-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+2004-02-29 Mark Mitchell <mark@codesourcery.com>
- DR 180
- * decl.c (grokdeclarator): Require class-key for all friend class.
- Output the correct type and context in the error message.
+ PR c++/14138
+ * name-lookup.h (push_scope): Change prototype.
+ * name-lookup.c (push_scope): Do not reenter the current class
+ scope.
+ * decl.c (grokfndecl): Check return code from push_scope before
+ calling pop_scope.
+ * decl2.c (check_classfn): Likewise.
+ * parser.c (cp_parser_conversion_function_id): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_direct_declarator): Likewise.
+ (cp_parser_class_specifier): Likewise.
+ (cp_parser_class_head): Likewise.
+ (cp_parser_lookup_name): Likewise.
+ (cp_parser_constructor_declarator_p): Likewise.
+ * pt.c (instantiate_class_template): Likewise.
+ (resolve_typename_type): Likewise.
-2002-12-01 Mark Mitchell <mark@codesourcery.com>
+2004-02-27 Mark Mitchell <mark@codesourcery.com>
- PR c++/5919
- * pt.c (unify): Use variably_modified_type_p to test validity of
- template argument types.
+ PR debug/12103
+ * class.c (update_vtable_entry_for_fn): Do not go through
+ covariance machinery if the type returned by an overrider is the
+ same as the original.
- PR c++/8727
- * cp-tree.h (lang_type_class): Add typeinfo_var.
- (CLASSTYPE_TYPEINFO_VAR): New macro.
- * rtti.c (get_tinfo_decl): Use it.
+2004-02-27 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- PR c++/8663
- * init.c (expand_member_init): Always get the main variant of a
- base class.
+ PR c++/14284
+ * pt.c (dependent_type_p_r): A template template parameter is a
+ dependent type.
-2002-12-01 Mark Mitchell <mark@codesourcery.com>
+2004-02-26 Mark Mitchell <mark@codesourcery.com>
- PR c++/8332
- PR c++/8493
- * decl.c (cxx_init_decl_processing): Use size_type_node, not
- c_size_type_node.
- * decl2.c (coerce_new_type): Likewise.
- * except.c (do_allocate_exception): Likewise.
+ PR c++/14278
+ * parser.c (cp_parser_parameter_declaration_list): Commit
+ to fewer tentative parses.
-2002-11-30 Mark Mitchell <mark@codesourcery.com>
+2004-02-26 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- PR c++/8227
- * decl.c (layout_var_decl): Deal gracefully with erroneous types.
- (check_initializer): Validate the type of the initialized
- variable, even if the initializer is absent.
- * typeck.c (cp_type_quals): Deal gracefully with erroneous types.
+ PR c++/14246
+ * mangle.c (write_template_arg_literal): Don't rely on identity for
+ boolean constants.
- PR c++/8214
- * typeck.c (convert_for_assignment): Do not use
- decl_constant_value on the operand.
+2004-02-23 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- PR c++/8511
- * pt.c (instantiate_decl): Handle template friends defined outside
- of the class correctly.
+ PR c++/14250
+ * cvt.c (build_expr_type_conversion): Type must be complete before
+ looking up for conversions.
-2002-11-29 Joe Buck <jbuck@synopsys.com>
+2004-02-20 Mark Mitchell <mark@codesourcery.com>
- * parse.y (class_head_defn): Set CLASSTYPE_DECLARED_CLASS for
- anonymous structs.
+ PR c++/14199
+ * pt.c (tsubst_copy): Call mark_used for a PARM_DECL.
-2002-11-29 Mark Mitchell <mark@codesourcery.com>
+ PR c++/14173
+ * semantics.c (begin_class_definition): Set TYPE_PACKED correctly
+ for all type variants.
- * class.c (walk_subobject_offsets): Recur on binfos as well as on
- types.
- (layout_nonempty_base_or_field): Pass it a binfo when processing a
- base class.
- (layout_empty_base): Likewise.
- (build_base_field): Likewise.
+2004-02-19 Mark Mitchell <mark@codesourcery.com>
-2002-11-27 Mark Mitchell <mark@codesourcery.com>
+ PR c++/14186
+ * name-lookup.c (push_class_level_binding): Do not complain about
+ adding a binding for a member whose name is the same as the
+ enclosing class if the member is located in a base class of the
+ current class.
- * class.c (build_base_field): Make sure we get the canonical base
- when descending through primary bases.
+2004-02-19 Giovanni Bajo <giovannibajo@gcc.gnu.org>
-2002-11-26 Geoffrey Keating <geoffk@apple.com>
+ PR c++/14181
+ * parser.c (cp_parser_new_expression): Parse an ill-formed
+ direct-new-declarator after a parenthesized type-id to emit good
+ diagnostic.
- * decl.c (check_initializer): Don't error on initialisation of
- a scalar with a brace-enclosed expression.
+2004-02-17 Mark Mitchell <mark@codesourcery.com>
-2002-11-26 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/11326
+ * cp-tree.h (abi_version_at_least): Remove.
+ * mangle.c: Include flags.h.
- * cp-tree.h (DECL_LANG_FLAG_4): Document more uses.
- (template_parms_equal): Remove prototype.
- * typeck.c (buuld_indirect_ref): Reformat.
+2004-02-15 Mark Mitchell <mark@codesourcery.com>
-2002-11-25 Mark Mitchell <mark@codesourcery.com>
+ PR c++/13971
+ * call.c (build_conditional_expr): Handle conversions between
+ class types which result in differently cv-qualified type
+ variants.
- * tree.c (cp_build_qualified_type_real): Correct handling of
- array types.
- * class.c (walk_subobject_offsets): Fix thinko.
- (build_base_field): Record offsets of empty bases in primary
- virtual bases.
- (layout_class_type): Record offsets of empty bases in fields.
+ PR c++/14086
+ * class.c (delete_duplicate_fields_1): Remove.
+ (delete_duplicate_fields): Likewise.
+ (finish_struct_anon): Remove check for members with the same name
+ as their enclosing class.
+ (check_field_decls): Do not call duplicate_fields.
+ * decl.c (grokdeclarator): Remove check for static data members
+ with the same name as their enclosing class.
+ * name-lookup.c (push_class_level_binding): Check for members with
+ the same name as their enclosing class.
- * search.c (is_subobject_of_p_1): Fix thinko.
- (lookup_field_queue_p): Likewise.
+2004-02-15 Gabriel Dos Reis <gdr@integrable-solutions.net>
-2002-11-24 Mark Mitchell <mark@codesourcery.com>
+ PR c++/14085
+ * error.c (dump_decl): Handle TEMPLATE_TYPE_PARM.
- * class.c (layout_class_type): Reuse tail padding when laying out
- virtual bases.
+2004-02-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-2002-11-22 Mark Mitchell <mark@codesourcery.com>
+ PR c++/13635
+ * pt.c (push_template_decl_real): Make sure DECL_TI_ARGS of DECL
+ has full set of arguments.
- * rtti.c (qualifier_flags): Fix thinko.
+2004-02-13 Mark Mitchell <mark@codesourcery.com>
-2002-11-21 Glen Nakamura <glen@imodulo.com>
+ PR c++/14122
+ * cp-tree.h (delete_sanity): Change prototype.
+ * decl2.c (delete_sanity): Make doing_vec a bool, not an int.
+ Remove dead code. Adjust code to warn about deleting an array.
+ * typekc.c (decay_conversion): Use build_address and build_nop.
- PR c++/8342
- * typeck.c (get_member_function_from_ptrfunc): Make sure that a
- SAVE_EXPR for instance_ptr doesn't get evaluated first inside one
- of the branches of a COND_EXPR.
+ PR c++/14108
+ * search.c (accessible_p): Do not check access in thunks.
-2002-11-19 Mark Mitchell <mark@codesourcery.com>
+2004-02-13 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- * pt.c (for_each_template_parm): Free allocated memory.
- * search.c (is_subobject_of_p_1): New function.
- (is_subobject_of_p): Avoid walking virtual bases multiple times.
+ PR c++/13927
+ * error.c (dump_decl) <ALIAS_DECL>: Dump as simple declarations.
-2002-11-19 Jason Thorpe <thorpej@wasabisystems.com>
+2004-02-13 Mark Mitchell <mark@codesourcery.com>
- * g++spec.c (lang_specific_spec_functions): New.
+ PR c++/14083
+ * call.c (build_conditional_expr): Call force_rvalue on the
+ non-void operand in the case that one result is a throw-expression
+ and the other is not.
-2002-11-15 Kazu Hirata <kazu@cs.umass.edu>
+2004-02-13 Ian Lance Taylor <ian@wasabisystems.com>
- * ChangeLog: Follow spelling conventions.
- * class.c: Likewise.
- * decl2.c: Likewise.
+ PR c++/9851
+ * parser.c (cp_parser_pseudo_destructor_name): Check for errors on
+ the type name and look ahead for ::~, and bail out early with a
+ better error message if the parse is going to fail.
-2002-11-14 Zack Weinberg <zack@codesourcery.com>
+2004-02-10 Mark Mitchell <mark@codesourcery.com>
- * search.c (dfs_push_decls): Do not try to reorder elements
- 3..n of method_vec if method_vec has only two elements.
- Reverse order of two tests to avoid accessing unallocated
- memory.
+ * typeck.c (lookup_destructor): Fix typo in error message.
-2002-11-14 Mark Mitchell <mark@codesourcery.com>
+2004-02-07 Zack Weinberg <zack@codesourcery.com>
- * class.c (dfs_find_final_overrider): Adjust so that the most
- derived object is a binfo, rather than a class type.
- (find_final_overrider): Likewise.
- (add_vcall_offset_vtbl_entries_1): Simplify accordingly.
- (add_vcall_offset): Likewise.
+ Bug 13856
+ * optimize.c (maybe_clone_body): Don't update DECL_ESTIMATED_INSNS.
+ * decl.c (duplicate_decls, start_function): Likewise.
-2002-11-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+2004-02-07 Zack Weinberg <zack@codesourcery.com>
- PR c++/8389
- * pt.c (instantiate_template): Push class scope for member
- functions.
- (get_mostly_instantiated_function_type): Likewise. Don't call
- tsubst on context. Remove CONTEXTP and TPARMSP parameters.
- * cp-tree.h (get_mostly_instantiated_function_type): Adjust.
- * mangle.c (write_encoding, write_unqualified_name): Adjust.
-
-2002-11-07 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (add_vcall_offset_vtbl_entries_1): Correct ordering of
- vcall offfsets. Split out ...
- (add_vcall_offset): ... new function.
-
- PR c++/8338
- * pt.c (for_each_template_parm): Add htab parameter.
- (process_partial_specialization): Adjust call.
- (push_template_decl_real): Likewise.
- (pair_fn_data): Add visited.
- (for_each_template_parm_r): Avoid walking duplicates more than
- once.
- (uses_template_parms): Adjust call to for_each_template_parm.
-
-2002-11-07 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (add_implicitly_declared_members): Put implicitly
- declared functions at the end of TYPE_METHODs when -fabi-version
- is at least 2.
-
-2002-11-05 Geoffrey Keating <geoffk@apple.com>
-
- * decl2.c (finish_file): Correct spelling.
-
-2002-11-03 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (build_special_member_call): Do not try to lookup VTTs by
- name.
- * class.c (vtbl_init_data): Add generate_vcall_entries.
- (get_vtable_decl): Do not look up virtual tables by name.
- (copy_virtuals): Do not use BV_USE_VCALL_INDEX_P.
- (set_primary_base): Do not set CLASSTYPE_RTTI.
- (determine_primary_base): Likewise.
- (get_matching_virtual): Remove.
- (get_vcall_index): New function.
- (update_vtable_entry_for_fn): Do not try to use virtual thunks
- when they are not required. Assign vcall indices at this point.
- (finish_struct_1): Do not set CLASSTYPE_NEEDS_VIRTUAL_REINIT.
- Do update dynamic_classes.
- (build_vtt): Do not add VTTs to the symbol table.
- (build_ctor_vtbl_group): Likewise.
- (build_vtbl_initializer): Simplify handling of vcall indices.
- (build_vcall_offset_vtbl_entries): Pretend to build vcall offsets
- for the most derived class.
- (add_vcall_offset_vtbl_entries_1): But do not actually add them to
- the vtable.
- * cp-tree.h (dynamic_classes): New macro.
- (lang_type_class): Remove rtti. Add vtables. Add vcall_indices.
- (CLASSTYPE_RTTI): Remove.
- (CLASSTYPE_NEEDS_VIRTUAL_REINIT): Remove.
- (CLASSTYPE_VCALL_INDICES): New macro.
- (CLASSTYPE_VTABLES): Likewise.
- (BV_USE_VCALL_INDEX_P): Remove.
- (build_vtable_path): Remove.
- * decl2.c (finish_vtable_vardecl): Remove.
- (key_method): Remove #if 0'd code.
- (finish_vtable_vardecl): Rename to ...
- (maybe_emit_vtables): ... this.
- (finish_file): Use it.
- * search.c (look_for_overrides_here): Update comment.
-
-2002-11-01 Zack Weinberg <zack@codesourcery.com>
-
- PR c/7353 redux
- * decl2.c (grokfield): Reject TYPE_DECLs with initializers.
-
-2002-10-30 Jason Merrill <jason@redhat.com>
-
- PR c++/8186
- * cp-tree.h (ADDR_IS_INVISIREF): New macro.
- * call.c (convert_for_arg_passing): Set it.
- * except.c (stabilize_throw_expr): Recurse for such an arg.
-
-2002-10-31 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (lang_decl_flags): Remove init_priority.
- (lang_decl): Add delta.
- (GLOBAL_INIT_PRIORITY): Remove.
- (THUNK_DELTA): Revise definition.
- * decl2.c (start_objects): Don't set GLOBAL_INIT_PRIORITY.
- * dump.c (cp_dump_tree): Don't dump it.
-
-2002-10-30 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/8160
- * typeck2.c (process_init_constructor): Call complete_array_type.
-
- PR c++/8149
- * decl.c (make_typename_type): Issue errors about invalid results.
-
-2002-10-30 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- Core issue 287, PR c++/7639
- * cp-tree.h (lang_type_class): Add decl_list field.
- (CLASSTYPE_DECL_LIST): New macro.
- (maybe_add_class_template_decl_list): Add declaration.
- * class.c (duplicate_tag_error): Initialize CLASSTYPE_DECL_LIST.
- (unreverse_member_declarations): Reverse CLASSTYPE_DECL_LIST.
- (maybe_add_class_template_decl_list): New function.
- (add_implicitly_declared_members): Use it.
- * decl.c (maybe_process_template_type_declaration): Likewise.
- (pushtag): Likewise.
- * friend.c (add_friend): Likewise.
- (make_friend_class): Likewise.
- * semantics.c (finish_member_declaration): Likewise.
- (begin_class_definition): Initialize CLASSTYPE_DECL_LIST.
- * pt.c (instantiate_class_template): Use CLASSTYPE_DECL_LIST
- to process members and friends in the order of declaration.
-
-2002-10-29 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/8287
- * decl.c (finish_destructor_body): Create the label to jump to
- when returning from a destructor here.
- (finish_function_body): Rather than here.
-
-2002-10-25 Zack Weinberg <zack@codesourcery.com>
-
- PR c++/7266
- * decl.c (grokdeclarator): Check that TREE_OPERAND 0 of a
- SCOPE_REF is not null before dereferencing it.
-
-2002-10-25 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (build_over_call): Use DECL_CONTEXT, not
- DECL_VIRTUAL_CONTEXT.
- * class.c (modify_vtable_entry): Don't mess with
- DECL_VIRTUAL_CONTEXT.
- (set_vindex): Remove.
- (set_primary_base): Remove vfuns_p parameter.
- (determine_primary_base): Likewise.
- (modify_all_vtables): Likewise.
- (layout_class_type): Likewise. Adjust calls to other functions
- accordingly.
- (finish_struct_1): Adjust calls to modified functions. Set
- DECL_VINDEX here.
- * cp-tree.h (lang_type_class): Remove vsize.
- (CLASSTYPE_VSIZE): Remove.
- (lang_decl): Remove thunks.
- (DECL_THUNKS): Adjust.
- (DECL_VIRTUAL_CONTEXT): Remove.
- (duplicate_decls): Don't copy it.
- * pt.c (build_template_decl): Don't set it.
- (tsubst_decl): Likewise.
- * typeck.c (expand_ptrmemfunc_cst): Don't use it.
-
- * class.c (build_vtbl_initializer): Don't use build_vtable_entry.
- (build_vtable_entry): Remove.
- * cp-tree.h (BINFO_VIRTUALS): Expand documentation.
- (lang_decl): Add thunks.
- (DECL_THUNKS): New macro.
- * decl.c (duplicate_decls): Copy it.
- * method.c (make_thunk): Simplify, and add thunks to DECL_THUNKS.
- * semantics.c (emit_associated_thunks): Simplify.
-
-2002-10-24 David Edelsohn <edelsohn@gnu.org>
-
- PR c++/7228
- * cp-tree.h (CLASSTYPE_READONLY_FIELDS_NEED_INIT): Check that
- lang_type structure exists before accessing field.
- (SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT): New macro.
- (CLASSTYPE_REF_FIELDS_NEED_INIT): Similar.
- (SET_CLASSTYPE_REF_FIELDS_NEED_INIT): New macro.
- * class.c (check_field_decls): Use new macros.
- * typeck2.c (process_init_constructor): Remove redundant check for
- existence of lang_type structure.
-
-2002-10-24 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (end_of_base): New method.
- (end_of_class): Use it. Check indirect virtual bases.
-
- * class.c (check_field_decls): Fix typo.
-
-2002-10-23 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/8067
- * decl.c (maybe_inject_for_scope_var): Ignore __FUNCTION__ and
- related variables.
-
- PR c++/7679
- * spew.c (next_token): Do not return an endless stream of
- END_OF_SAVED_INPUT tokens.
- (snarf_method): Add three END_OF_SAVED_INPUT tokens to the end of
- the cached token stream.
- (snarf_defarg): Likewise.
-
-2002-10-23 Zack Weinberg <zack@codesourcery.com>
-
- * cp-lang.c (cp_var_mod_type_p): New: C++ hook for
- variably_modified_type_p.
- * cp-tree.h: Remove prototype of variably_modified_type_p.
- * tree.c (variably_modified_type_p): Remove; now implemented
- in language-independent code.
-
-2002-10-22 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/6579
- * spew.c (snarf_parenthesized_expression): New function.
- (snarf_block): Use it.
-
-2002-10-22 Richard Henderson <rth@redhat.com>
+ * name-lookup.c (pushdecl): Issue shadow warnings directly.
+ * parser.c (free_parser_stacks): Delete.
- * method.c (use_thunk): Always compute vcall_value; assert that
- it is not zero. Use can_output_mi_thunk; use output_mi_thunk
- for vcall thunks as well.
+2004-02-07 Kazu Hirata <kazu@cs.umass.edu>
-2002-10-21 Mark Mitchell <mark@codesourcery.com>
+ * rtti.c, tree.c: Update copyright.
- * class.c (empty_base_at_nonzero_offset_p): New function.
- (layout_nonempty_base_or_field): Do not check for conflicts when
- laying out a virtual base using the GCC 3.2 ABI.
- (build_base_field): Correct checking for presence of empty classes
- at nonzero offsets when clearing CLASSTYPE_NEARLY_EMPTY_P.
+2003-02-06 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- * class.c (include_empty_classes): Use normalize_rli.
- (layout_class_type): Likewise.
+ PR c++/14033
+ * decl.c (require_complete_types_for_parms): Do not insert
+ error_mark_node in the parameter list.
- * decl.c (reshape_init): Tweak handling of character arrays.
+2003-02-06 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- PR c++/8218
- * cp-tree.h (lang_type_class): Add contains_empty_class_p.
- (CLASSTYPE_CONTAINS_EMPTY_CLASS_P): New macro.
- * class.c (check_bases): Update CLASSTYPE_CONTAINS_EMPTY_CLASS_P.
- (check_field_decls): Likewise.
- (layout_class_type): Likewise.
- (finish_struct_1): Initialize it.
- (walk_subobject_offsets): Use it to prune searches.
+ PR c++/14028
+ * parser.c (cp_parser_enclosed_template_argument_list): Emit straight
+ error when terminator can not be found.
-2002-10-20 Mark Mitchell <mark@codesourcery.com>
+2004-02-05 Kelley Cook <kcook@gcc.gnu.org>
- * method.c (use_thunk): Compute the vcall index as a HOST_WIDE_INT.
- * optimize.c (optimize_function): Replace ASM_OUTPUT_MI_THUNK with
- TARGET_ASM_OUTPUT_MI_THUNK in comments.
+ Make-lang.in (po-generated): Delete.
-2002-10-18 Zack Weinberg <zack@codesourcery.com>
+2004-02-05 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
- * decl.c (start_decl): Point users of the old initialized-
- typedef extension at __typeof__.
+ PR middle-end/13750
+ Revert:
+ 2004-01-15 Geoffrey Keating <geoffk@apple.com>
+ PR pch/13361
+ * cp/lex.c (handle_pragma_interface): Duplicate string from tree.
+ (handle_pragma_implementation): Likewise.
-2002-10-18 Mark Mitchell <mark@codesourcery.com>
+2004-02-05 Mark Mitchell <mark@codesourcery.com>
- * Make-lang.in (method.o): Depend on TARGET_H.
- * method.c (target.h): Include it.
- (use_thunk): Use target hooks. Use vcall thunks, if available.
+ PR c++/13714
+ * typeck.c (lookup_destructor): Tweak error message.
-2002-10-18 Mark Mitchell <mark@codesourcery.com>
+2004-02-05 Paul Brook <paul@codesourcery.com>
- * class.c (base_derived_from): Make sure return value is a bool.
+ Backport from mainline.
-2002-10-18 Mark Mitchell <mark@codesourcery.com>
+ 2003-11-05 Mark Mitchell <mark@codesourcery.com>
- * class.c (find_final_overrider_data_s): Remove overriding_fn and
- overriding_base.
- (dfs_base_derived_from): New function.
- (base_derived_from): Likewise.
- (dfs_find_final_overrider): Use base_derived_from.
- (find_final_overrider): Adjust.
+ * decl.c (cxx_push_function_context): Do not set
+ current_function_is_thunk.
+ * method.c (use_thunk): Set CALL_FROM_THUNK on the call to the
+ actual function.
-2002-10-18 Jason Merrill <jason@redhat.com>
+2004-02-04 Mark Mitchell <mark@codesourcery.com>
- PR c++/8080
- * semantics.c (finish_for_cond, finish_while_cond): Don't mess
- with condition decls in a template.
+ PR c++/13932
+ * call.c (convert_like_real): Use "converting" rather than
+ "argument" as the descriptive keyword to
+ dubious_conversion_warnings.
+ * typeck.c (convert_for_assignment): Do not call
+ dubious_conversion_warnings.
-2002-10-17 Nathan Sidwell <nathan@codesourcery.com>
+2004-02-04 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- * class.c (add_method): Compare template parms too.
+ PR c++/13086
+ * init.c (build_delete): Emit a more informative error message in
+ case of an incomplete type, and on the correct source line.
-2002-10-17 Mark Mitchell <mark@codesourcery.com>
+2004-02-04 Mark Mitchell <mark@codesourcery.com>
- PR c++/7584
- * class.c (handle_using_decl): Allow the declaration used to be
- from an ambiguous base.
+ PR c++/9941
+ * rtti.c (tinfo_base_init): Use import_export_tinfo to decide the
+ linkage for the typeinfo name string.
- * pt.c (convert_template_argument): Revert this change:
- 2002-10-16 Mark Mitchell <mark@codesourcery.com>
- * pt.c (convert_template_argument): Do not fold non-type
- template rguments when inside a template.
+ PR c++/13969
+ * cp-tree.h (fold_non_dependent_expr): New function.
+ * parser.c (cp_parser_fold_non_dependent_expr): Remove.
+ (cp_parser_template_argument): Use fold_non_dependent_expr.
+ (cp_parser_direct_declarator): Likewise.
+ * pt.c (fold_non_dependent_expr): New function.
+ (convert_nontype_argument): Use it.
+ (tsubst_qualified_id): Simplify.
+ (tsubst_copy_and_build): Likewise.
- * init.c (expand_default_init): Handle brace-enclosed initializers
- correctly.
+2003-02-04 Giovanni Bajo <giovannibajo@gcc.gnu.org>
-2002-10-16 Mark Mitchell <mark@codesourcery.com>
+ PR c++/13997
+ * pt.c (more_specialized_class): Increase processing_template_decl
+ while partial ordering.
- * mangle.c (write_expression): Correct handling of enumeration
- constants.
- (write_template_arg): Likewise.
- * pt.c (convert_template_argument): Do not fold non-type template
- arguments when inside a template.
+2004-02-03 Mark Mitchell <mark@codesourcery.com>
- PR c++/7478
- * cvt.c (convert_to_reference): Allow references as the incoming
- type.
+ PR c++/13950
+ * parser.c (cp_parser_class_name): Robustify.
-2002-10-16 Mark Mitchell <mark@codesourcery.com>
+ PR c++/13970
+ * parser.c (cp_parser_cache_group): Do not consume the EOF token.
- PR c++/7524
- * method.c (do_build_assign_ref): Use cp_build_qualified_type, not
- build_qualified_type.
+2004-02-03 Mark Mitchell <mark@codesourcery.com>
-2002-10-15 Richard Henderson <rth@redhat.com>
+ PR c++/13925
+ * decl.c (start_function): Do not call pushdecl for any
+ instantiation or specialization of a primary template.
- * error.c (dump_expr): Use real_to_decimal directly, and with
- the new arguments.
+ PR c++/14002
+ * semantics.c (finish_id_expression): Do not return an
+ IDENTIFIER_NODE when lookup finds a PARM_DECL.
-2002-10-15 Mark Mitchell <mark@codesourcery.com>
+ PR c++/13978
+ * pt.c (build_non_dependent_expr): Do not build
+ NON_DEPENDENT_EXPRs for FUNCTION_DECLs or TEMPLATE_DECLs.
- * decl.c (reshape_init): Fix typo.
+ PR c++/13968
+ * semantics.c (finish_id_expression): Do not return an
+ IDENTIFIER_NODE when lookup finds a VAR_DECL.
- * cp-tree.h (operator_name_info_t): Add arity.
- * lex.c (init_operators): Initialize it.
- * mangle.c (write_conversion_operator_name): New function.
- (write_unqualified_name): Use it.
- (write_template_args): Accept template arguments as a TREE_LIST.
- (write_expression): Adjust handling of qualified names to match
- specification.
+ PR c++/13975
+ * parser.c (cp_parser_simple_declaration): When skipping to the
+ end of the statement swallow the terminating semicolon.
-2002-10-15 Jason Merrill <jason@redhat.com>
+2004-02-02 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- * call.c (call_builtin_trap): New fn.
- (convert_arg_to_ellipsis): Use it. Downgrade error to warning.
- (build_call): Don't set current_function_returns_abnormally outside
- a function.
+ DR206
+ PR c++/13813
+ * decl.c (grokdeclarator): Check immediatly type completeness for
+ non-dependent types.
-2002-10-14 Mark Mitchell <mark@codesourcery.com>
+2004-01-30 Mark Mitchell <mark@codesourcery.com>
- * class.c (check_field_decls): Remove empty_p parameter. Instead,
- clear CLASSTYPE_EMPTY_P.
- (build_base_field): Likewise.
- (build_base_fields): Likewise.
- (check_bases_and_members): Likewise.
- (create_vtbl_ptr): Likewise.
- (layout_class_type): Likewise. Ensure that empty classes have
- size zero when used as base classes in the 3.2 ABI.
- (finish_struct_1): Initialize CLASSTYPE_EMPTY_P and
- CLASSTYPE_NEARLY_EMPTY_P. Adjust calls to avoid passing empty_p
- parameter.
- (is_empty_class): Correct definition when using post-3.2 ABI.
- * cp-tree.h (lang_type_class): Add empty_p.
- (CLASSTYPE_EMPTY_P): New macro.
+ PR c++/13113
+ * init.c (build_offset_ref): Improve error recovery for invalid
+ uses of non-static member functions.
-2002-10-12 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/13854
+ * cp-tree.h (cp_build_type_attribute_variant): New function.
+ * class.c (build_clone): Use cp_build_type_attribute_variant.
+ * decl.c (duplicate_decls): Likewise.
+ * pt.c (copy_default_args_to_explicit_spec): Likewise.
+ (tsubst_function_type): Likewise.
+ * tree.c (build_exception_variant): Check attributes before
+ concluding that two types are the same.
+ (cp_build_type-attribute_variant): New method.
+ * typeck.c (merge_types): Use cp_build_type_attribute_variant.
- * init.c (build_delete): Do not apply save_expr for arrays.
- (build_vec_delete): Likewise.
+ PR c++/13907
+ * call.c (convert_class_to_reference): Keep better track of
+ pedantically invalid user-defined conversions.
-2002-10-14 Mark Mitchell <mark@codesourcery.com>
+2004-02-02 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- * decl.c (layout_var_decl): Call layout_decl even for variables
- whose type is an array with unspecified bounds.
+ PR c++/13957
+ * pt.c (tsubst_qualified_id): Improved error message when a type
+ is expected but not found.
- PR c++/7176
- * lex.c (do_identifier): Add another option for the parsing
- parameter.
- * parse.y (do_id): Use it.
+2004-01-30 Michael Matz <matz@suse.de>
-2002-10-11 Gabriel Dos Reis <gdr@integrable-solutions.net>
+ * parser.c (cp_parser_labeled_statement): Accept case ranges.
- PRs C++/6803, C++/7721 and C++/7803
- * decl.c (grokdeclarator): Gracefully handle template-name as
- decl-specifier.
+2004-01-28 Jan Hubicka <jh@suse.czi
-2002-10-11 Jason Molenda <jmolenda@apple.com>
+ * semantics.c (expand_body) Do emit_associated_thunks before
+ expansion.
- * init.c (build_field_list): Provide uses_unions_p with a default
- value.
+2004-01-30 Giovanni Bajo <giovannibajo@gcc.gnu.org>
-2002-10-11 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/5661
- * cp-tree.h (variably_modified_type_p): New function.
- (grokdeclarator) Tighten check for variably modified types as
- fields.
- * pt.c (convert_template_argument): Do not allow variably modified
- types as template arguments.
- * tree.c (variably_modified_type_p): New function.
-
- * NEWS: Document removal of "new X = ..." extension.
- * class.c (initialize_array): Set TREE_HAS_CONSTRUCTOR on
- brace-enclosed initializers.
- * cp-tree.h (CP_AGGREGATE_TYPE_P): New macro.
- (initialize_local_var): Remove declaration.
- (expand_static_init): Likewise.
- * decl.c (next_initializable_field): New function.
- (reshape_init): Likewise.
- (check_initializer): Use them. Build dynamic initializer for
- aggregates here too.
- (initialize_local_var): Simplify, and incorporate cleanup
- insertion code as well.
- (destroy_local_var): Remove.
- (cp_finish_decl): Tidy.
- (expand_static_init): Fold checks for whether or not a variable
- needs initialization into this function. Simplify.
- * decl2.c (do_static_initialization): Simplify.
- * init.c (build_init): Do not set TREE_SIDE_EFFECTS when it will
- be done for us automatically.
- (expand_default_init): Handle brace-enclosed initializers
- correctly.
- (expand_aggr_init_1): Remove RTL-generation code.
- (build_vec_init): Remove "new X = ..." support.
- * parse.y (new_initializer): Likewise.
- * rtti.c (get_pseudo_ti_init): Set TREE_HAS_CONSTRUCTOR on
- brace-enclosed initializer.
- (create_pseudo_type_info): Likewise.
- * typeck2.c (store_init_value): Don't try to handle digest_init
- being called more than once.
- (digest_init): Tidy handling of brace-enclosed initializers.
+ PR c++/13683
+ * call.c (convert_arg_to_ellipsis): Don't emit a warning if within
+ a sizeof expression.block
-2002-10-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+2004-01-29 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- * decl.c (typename_hash): Use htab_hash_pointer.
+ * parser.c (cp_parser_template_id): Parse tentatively `[:' after a
+ template name as it was `<::' (digraph typo).
+ (cp_parser_nth_token_starts_template_argument_list_p): New function.
+ (cp_parser_id_expression): Use it.
+ (cp_parser_nested_name_specifier_opt): Likewise.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_lexer_get_preprocessor_token): Use c_lex_with_flags.
-2002-10-10 Jim Wilson <wilson@redhat.com>
+2004-01-29 Mark Mitchell <mark@codesourcery.com>
- * decl.c (duplicate_decls): Don't call decl_attributes.
+ PR c++/13883
+ * mangle.c (write_encoding): Correct encoding of member template
+ constructors.
-2002-10-09 Zack Weinberg <zack@codesourcery.com>
+2004-01-28 Mark Mitchell <mark@codesourcery.com>
- PR c/7353
- * decl.c (start_decl): Unconditionally issue error for
- 'typedef foo = bar'.
- (cp_finish_decl): Remove special case for TYPE_DECL with initializer.
- (grokdeclarator): Remove redundant error for 'typedef foo = bar'.
+ PR c++/13791
+ * typeck.c (merge_types): Do not merge attributes into
+ TYPENAME_TYPEs.
-2002-10-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+2004-01-28 Mark Mitchell <mark@codesourcery.com>
- * decl2.c (prune_vtable_vardecl): Delete unused function.
+ PR c++/13736
+ * parser.c (cp_parser_direct_declarator): Do not prevent
+ backtracking inside a parenthesized declarator.
+ (cp_parser_parameter_declaration): Fix typo in comment.
-2002-10-03 Mark Mitchell <mark@codesourcery.com>
+2004-01-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
- PR c++/7754
- * decl2.c (finish_anon_union): Do not expand anonymous unions when
- procesing template functions.
- * pt.c (tsubst_decl, case VAR_DECL): Try to complete the variable
- type. Call layout_decl.
- (tsubst_expr, case DECL_STMT): Handle anonymous unions.
+ * cp-tree.h (language_function, lang_type_header): Use
+ BOOL_BITFIELD.
+ * name-lookup.h (cp_binding_level): Likewise.
-2002-10-07 Richard Henderson <rth@redhat.com>
+2004-01-26 Mark Mitchell <mark@codesourcery.com>
- * decl2.c, pt.c: Revert c++/7754 fix.
+ PR c++/13663
+ * semantics.c (finish_for_expr): Check for unresolved overloaded
+ functions.
-2002-10-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+2004-01-26 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_method): Just check processing_template_decl to
+ determine whether or not we are within a template.
+ * decl2.c (maybe_retrofit_in_chrg): Likewise.
+ * init.c (decl_constant_value): Check the type of the declaration,
+ not TREE_READONLY.
+ * name-lookup.c (maybe_push_to_top_level): Rename to ...
+ (push_to_top_level): ... this.
+ * name-lookup.h (maybe_push_to_top_level): Do not declare it.
+ * pt.c (push_template_decl_real): Reorder condition for speed.
+ (convert_template_argument): Use dependency-checking functions in
+ place of uses_template_parms.
+ (lookup_template_class): Avoid calling uses_template_parms more
+ than once.
+ (uses_template_parms): Reimplement, using dependency-checking
+ functions.
+ (instantiate_class_template): Use push_to_top_level, not
+ maybe_push_to_top_level.
+ (type_unification_real): Simplify.
+ (type_dependent_expression_p): Handle OFFSET_REFs and
+ TEMPLATE_DECLs.
+ (any_dependent_template_arguments_p): Handle multiple levels of
+ template argument.
+ * semantics.c (expand_or_defer_fn): Do not check
+ uses_template_parms for template instantiations.
+ * typeck.c (comptypes): Avoid calling cp_type_quals.
+
+2004-01-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13833
+ * call.c (build_over_call): Do not convert arguments when
+ processing a template.
+ * pt.c (build_non_dependent_expr): Do not build a
+ NON_DEPENDENT_EXPR for arithmetic constants.
- PR c++/7804
- * error.c (dump_expr) [REAL_CST]: Output in decimal format.
+2004-01-25 Giovanni Bajo <giovannibajo@gcc.gnu.org>
-2002-10-03 Mark Mitchell <mark@codesourcery.com>
+ PR c++/13810
+ * parser.c (cp_parser_type_parameter): When cp_parser_id_expression
+ returns a TYPE_DECL. no further lookup is required.
+ * semantics.c (check_template_template_default_arg): A TYPE_DECL
+ is invalid. Rework to give better diagnostics.
- PR c++/7931
- * pt.c (for_each_template_parm_r): Handle BASELINKs.
+2004-01-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
- PR c++/7754
- * decl2.c (finish_anon_union): Do not expand anonymous unions when
- procesing template functions.
- * pt.c (tsubst_decl, case VAR_DECL): Try to complete the variable
- type. Call layout_decl.
- (tsubst_expr, case DECL_STMT): Handle anonymous unions.
+ PR c++/13797
+ * pt.c (instantiate_class_template): Add an error_mark_node
+ check.
+ (tsubst_decl) <TEMPLATE_DECL case>: Likewise.
-2002-10-03 Mark Mitchell <mark@codesourcery.com>
+2004-01-24 Kazu Hirata <kazu@cs.umass.edu>
- PR c++/8006
- * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Handle instances of template
- template parameters.
- (globals): Add entity and need_abi_warning.
- (decl_is_template_id): Use TYPE_TEMPLATE_INFO, not
- CLASSTYPE_TEMPLATE_INFO.
- (is_std_substitution): Use CLASSTYPE_TI_TEMPLATE, not
- TYPE_TI_TEMPLATE.
- (write_prefix): Handle typename types correctly.
- (write_template_prefix): Handle template template parameters
- correctly.
- (start_mangling): Add entity parameter.
- (finish_mangling): Warn about names whose mangling will change.
- (mangle_decl_string): Adjust.
- (mangle_type_string): Likewise.
- (mangle_special_for_type): Likewise.
- (mangle_ctor_vtbl_for_type): Likewise.
- (mangle_thunk): Likewise.
- (mangle_guard_variable): Likewise.
- (mangle_ref_init_variable): Likewise.
-
-2002-10-02 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/7188.
- * cp-tree.def (CTOR_INITIALIZER): Use one slot, not two.
- * cp-tree.h (emit_base_init): Rename to ....
- (emit_mem_initializers): ... this.
- (expand_member_init): Change prototype.
- * init.c (perform_member_init): Compute explicit, rather than
- requiring it as a parameter.
- (sort_member_init): Rename to ...
- (sort_mem_initializers): ... this. Process bases and data members
- together.
- (sort_base_init): Remove.
- (emit_base_init): Rename to ...
- (emit_mem_initializers): ... this.
- (expand_aggr_vbase_init_1): Remove.
- (construct_virtual_bases): Rename to ...
- (construct_virtual_base): ... this.
- (expand_member_init): Rework handling of base initializers.
- * method.c (do_build_copy_constructor): Use
- finish_mem_initializers.
- * parse.y (member_init): Adjust calls to expand_member_init.
- * pt.c (tsubst_expr): Simplify CTOR_INITIALIZER case.
- (tsubst_initializer_list): Use expand_member_init.
- * semantics.c (finish_mem_intiailizers): Simplify.
-
-2002-10-02 Matt Austern <austern@apple.com>
- * decl.c (walk_vtables_r): Fixed typo that caused result to
- never get a nonzero value.
-
-2002-10-02 Roger Sayle <roger@eyesopen.com>
-
- PR optimization/6627
- * cp-tree.h (enum ptrmemfunc_vbit_where_t): Delete definition
- from here, and move it to tree.h.
- * decl.c (cxx_init_decl_processing): If storing the vbit
- in function pointers, ensure that force_align_functions_log
- is atleast one.
-
-2002-10-02 Matt Austern <austern@apple.com>
-
- * class.c (check_field_decls): Changed warning about const member
- variables so that it doesn't get issued for a class aggregate.
-
-2002-10-01 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (cp_finish_decl): Make sure array types are laid out,
- even if the array bounds are unknown.
-
-2002-10-01 Steve Ellcey <sje@cup.hp.com>
-
- * class.c (build_vtbl_initializer): Change build_c_cast
- to build1.
-
-2002-10-01 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (cp_finish_decl): Make sure array types are laid out,
- even if the array bounds are unknown.
-
- * decl.c (cp_finish_decl): Correct check for dynamic
- initialization of thread-local storage.
-
-2002-09-30 Nathan Sidwell <nathan@codesourcery.com>
-
- * tree.c (really_overloaded_fn): TEMPLATE_ID_EXPRs are also
- overloaded.
-
-2002-09-30 Steve Ellcey <sje@cup.hp.com>
-
- * class.c (build_vtbl_initializer): Add cast.
- (add_vcall_offset_vtbl_entries_1):
- Use TARGET_VTABLE_DATA_ENTRY_DISTANCE for offset.
-
-2002-09-30 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (walk_subobject_offsets): Correct the calculation of
- offsets for virtual bases. Correct the counting of array
- elements.
- (layout_nonempty_base_or_field): Simplify. Correct the
- calculation of offsets to be propagated through the binfo
- hierarchy.
- (build_base_field): Avoid creating a FIELD_DECL for empty bases.
- Add the FIELD_DECL to TYPE_FIELDS.
- (build_base_fields): Adjust accordingly.
- (layout_virtual_bases): Use build_base_field.
- (end_of_class): Return a tree, not an integer.
- (warn_about_ambiguous_direct_bases): Rename to ...
- (warn_about_ambiguous_bases): ... this.
- (include_empty_classes): New function.
- (layout_class_type): Create an alternative version of the type to
- be used when as a base class type. Do not call
- finish_record_layout until we are done laying out the class.
- * cp-tree.h (lang_type_class): Remove size, size_unit. Add
- as_base.
- (CLASSTYPE_SIZE): Reimplement.
- (CLASSTYPE_SIZE_UNIT): Likewise.
- (CLASSTYPE_ALIGN): Likweise.
- (CLASSTYPE_USER_ALIGN): Likewise.
- (CLASSTYPE_AS_BASE): New macro.
- (DECL_INITIALIZED_P): Likewise.
- (extract_init): Remove prototype.
- (build_forced_zero_init): Rename to ...
- (build_zero_init): ... this.
- (force_store_init_value): Remove.
- * decl.c (obscure_complex_init): Remove.
- (duplicate_decls): Copy DECL_INITIALIZED_P.
- (check_initializer): Do not leave junk in DECL_INITIAL.
- (cp_finish_decl): Handle zero-initialization of entities with
- static storage duration.
- * expr.c (extract_init): Remove.
- * init.c (build_forced_zero_init): Remove.
- (build_zero_init): New function.
- (build_default_init): Use it.
- (build_field_list): Skip FIELD_DECLs for base subobjects.
- (push_base_cleanups): Likewise.
- * method.c (do_build_assign_ref): Likewise.
- (synthesize_exception_spec): Likewise.
- * pt.c (tsubst_decl): Clear DECL_INITIALIZED_P.
- (regenerate_decl_from_template): To not set DECL_INITIAL for a
- static data member whose initialization took place in its class.
- (instantiate_decl): Do not pass an initializer to cp_finish_decl
- in that situation.
- * search.c (dfs_push_decls): Skip FIELD_DECLs for base subobjects.
- (dfs_unuse_fields): Likewise.
- * tree.c (pod_type_p): Handle error_mark_node.
- (zero_init_p): Likewise.
- * typeck.c (lookup_anon_field): Skip FIELD_DECLs for base
- subobjects.
- * typeck2.c (store_init_value): Remove #if 0'd code.
- (force_store_init_value): Remove.
- (process_init_constructor): Use build_zero_init.
-
-2002-09-29 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/7788
- * rtti.c (unemitted_tinfo_decl_p): Check it has a field.
-
-2002-09-29 Kazu Hirata <kazu@cs.umass.edu>
-
- * cp-tree.h: Fix comment typos.
- * decl.c: Likewise.
- * pt.c: Likewise.
-
-2002-09-25 Mark Mitchell <mark@codesourcery.com>
-
- * cp/class.c (contains_empty_class_p): New method.
- (walk_subobject_offsets): Correct computation of field offset.
- (layout_empty_base): Correct placement of emtpy base classes.
- (layout_class_type): Warn about ABI changes.
-
-2002-09-23 Mark Mitchell <mark@codesourcery.com>
-
- * cp/class.c (layout_virtual_bases): Do not round the size of the
- type to a multiple of the alignment before laying out virtual bases.
- (layout_class_type): Correct handling of bit-fields that are wider
- than their type inside unions. Round the size of the type to a
- even number of bytes when computing the size without virtual
- bases.
- * cp/cp-tree.h (abi_version_at_least): New macro.
-
-2002-09-21 Kazu Hirata <kazu@cs.umass.edu>
-
- * ChangeLog: Follow spelling conventions.
- * ChangeLog.2: Likewise.
- * call.c: Likewise.
+ * call.c: Update copyright.
* class.c: Likewise.
- * cp-tree.h: Likewise.
- * cvt.c: Likewise.
- * decl.c: Likewise.
* decl2.c: Likewise.
* except.c: Likewise.
- * friend.c: Likewise.
- * g++spec.c: Likewise.
- * init.c: Likewise.
- * lex.c: Likewise.
- * mangle.c: Likewise.
- * method.c: Likewise.
- * operators.def: Likewise.
- * optimize.c: Likewise.
- * pt.c: Likewise.
- * rtti.c: Likewise.
- * search.c: Likewise.
- * semantics.c: Likewise.
- * spew.c: Likewise.
- * tree.c: Likewise.
- * typeck.c: Likewise.
-
-2002-09-18 Devang Patel <dpatel@apple.com>
-
- * cp/cp-tree.h: New prototype for walk_vtabls().
- * cp/decl.c (walk_vtables_r): New function.
- (struct cp_binding_level): Add new members, namespaces,
- names_size and vtables.
- (add_decl_to_level): Add decl in namespaces or vtables
- chain, if conditions match.
- (walk_vtables): New function.
- (walk_namespaces_r): Travers separate namespace chain
- for namespace decls.
- (wrapup_globals_for_namespace): Use names_size instead
- of list_length().
- * cp/decl2.c (finish_file): Use walk_vtables() instead of
- walk_globals() to walk vtable decls.
-
-2002-09-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (grokdeclarator): Use assert, not internal_error. Don't
- ICE with invalid pointers & references.
-
-2002-09-17 Zack Weinberg <zack@codesourcery.com>
-
- * Make-lang.in: Remove all references to the demangler.
- * cxxfilt.c: Moved to binutils.
-
-2002-09-16 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/7718
- * pt.c (tsubst_decl): Remove assert.
-
- Remove DR 295 implementation.
- * pt.c (check_cv_quals_for_unify): Disable function & method cases.
- * tree.c (cp_build_qualified_type_real): Likewise. Don't warn
- about ignoring volatile qualifiers.
-
- * search.c (lookup_member): Correct documentation.
-
-2002-09-16 Geoffrey Keating <geoffk@apple.com>
-
- * cp-tree.h (union lang_tree_node): Add chain_next option.
-
-2002-09-16 Nathan Sidwell <nathan@codesourcery.com>
-
- * parse.y (parse_finish_call_expr): Check lookup_member result.
-
- PR c++/7015
- * semantic.c (finish_asm_stmt): Fix operand/output_operands
- thinko.
- * typeck.c (c_expand_asm_operands): Protect from error_mark_node.
-
-2002-09-15 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/7919
- * call.c (build_over_call): Convert this pointer for fns found by
- using decls.
-
-2002-09-15 Kazu Hirata <kazu@cs.umass.edu>
-
- * ChangeLog: Follow spelling conventions.
- * ChangeLog.1: Likewise.
-
-2002-09-14 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/7768
- * pt.c (build_template_decl): Copy DECL_DESTRUCTOR_P.
-
-2002-09-14 Kazu Hirata <kazu@cs.umass.edu>
-
- * error.c: Fix comment formatting.
- * except.c: Likewise.
* expr.c: Likewise.
- * friend.c: Likewise.
- * g++spec.c: Likewise.
* init.c: Likewise.
- * lex.c: Likewise.
* mangle.c: Likewise.
- * method.c: Likewise.
* optimize.c: Likewise.
- * pt.c: Likewise.
- * rtti.c: Likewise.
- * search.c: Likewise.
- * semantics.c: Likewise.
- * spew.c: Likewise.
- * tree.c: Likewise.
* typeck.c: Likewise.
* typeck2.c: Likewise.
-2002-09-13 Matt Austern <austern@apple.com>
-
- PR C++/7828
- * cp/cp-tree.h, cp/tree.c: New function non_cast_lvalue_p.
- * cp/call.c: Change call-by-const-reference mechanism to use
- non_cast_lvalue_p when deciding whether the create a temporary.
- We need a temporary when passing, e.g. (long) x by const ref.
-
-2002-09-13 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (unify, ARRAY_TYPE): Element type can be more qualified.
-
-2002-09-13 Kazu Hirata <kazu@cs.umass.edu>
-
- * decl.c: Fix comment formatting.
- * decl2.c: Likewise.
-
-2002-09-12 Kazu Hirata <kazu@cs.umass.edu>
+2004-01-23 Andrew Pinski <pinskia@physics.uc.edu>
- * call.c: Fix comment formatting.
- * class.c: Likewise.
- * cp-lang.c: Likewise.
- * cp-tree.h: Likewise.
- * cvt.c: Likewise.
-
-2002-09-11 Zack Weinberg <zack@codesourcery.com>
-
- * Make-lang.in: Build cp/cxxfilt.o from $(srcdir)/cp/cxxfilt.c,
- and c++filt from cxxfilt.o + version.o + $(LIBDEPS).
- * cxxfilt.c: New file: split from libiberty/cplus-dem.c, with
- minor adjustments (use version_string, eliminate yet another
- duplicate of xmalloc)
-
-2002-09-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+ PR c++/13701
+ * decl.c (finish_function): Move the call to
+ finish_fname_decls below the call to
+ finish_eh_spec_block.
- * cp-tree.h (require_complete_eh_spec_types): Add prototype.
+2004-01-21 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
-2002-09-05 Jason Merrill <jason@redhat.com>
+ * parser.c (cp_parser_class_specifier): Prevent garbage collection.
- * typeck2.c (add_exception_specifier): Only pedwarn for an
- incomplete type.
- (require_complete_eh_spec_types): New fn.
- (cxx_incomplete_type_diagnostic): Also support pedwarning.
- * typeck.c (complete_type_or_diagnostic): Likewise.
- * call.c (build_call): Call require_complete_eh_spec_types.
- * rtti.c (get_pseudo_ti_desc): Give an error rather than aborting
- on an incomplete type.
+2004-01-20 Kelley Cook <kcook@gcc.gnu.org>
-2002-09-04 Jakub Jelinek <jakub@redhat.com>
+ * Make-lang.in: Replace $(docdir) with doc.
+ (c++.info, c++.srcinfo): Dummy entry.
+ (c++.man, c++.srcman): New rules.
+ (c++.install-man): Revamp rule.
- * decl.c (start_cleanup_fn): Clear interface_only before
- start_function, restore it afterwards.
+2004-01-19 Kelley Cook <kcook@gcc.gnu.org>
-2002-08-31 Jason Merrill <jason@redhat.com>
+ * Make-lang.in (CXX_INSTALL_NAME, GXX_INSTALL_NAME,
+ CXX_TARGET_INSTALL_NAME, GXX_TARGET_INSTALL_NAME): Define via a
+ immediate $(shell) instead of deferred backquote.
- * cp-lang.c (cp_expr_size): Allow initialization from a
- CONSTRUCTOR.
+2004-01-19 Mark Mitchell <mark@codesourcery.com>
-2002-08-30 Richard Henderson <rth@redhat.com>
+ PR c++/13651
+ * parser.c (cp_parser_postfix_expression): When encountering
+ incomplete type on left-hand side of "->" or ".", treat the entire
+ expression as erroneous.
- PR opt/7515
- * tree.c: Include target.h.
- (cp_cannot_inline_tree_fn): Don't auto-inline functions that
- don't bind locally.
- * Makefile.in (tree.o): Update.
+2004-01-19 Mark Mitchell <mark@codesourcery.com>
-2002-08-27 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (layout_virtual_bases): Warn about bugs in G++ that
- result in incorrect object layouts.
- (layout_class_type): Likewise.
+ PR c++/13592
+ * call.c (build_field_call): Remove.
+ (n_build_method_call): Likewise.
+ (build_method_call): Likewise.
+ (build_new_method_call): Do not call build_field_call.
+ * class.c (n_build_method_call): Remove.
+ (print_class_statistics): Do not print it.
+ * cp-tree.h (build_method_call): Remove declaration.
+ (finish_object_call_expr): Likewise.
+ (build_new_1): Do not use build_method_call.
+ * parser.c (cp_parser_postfix_expression): Use finish_call_expr
+ when the function appearing on the right-hand-side of "." or "->"
+ is not actually a function.
+ * pt.c (tsubst_copy_and_build): Likewise.
+ * semantics.c (finish_object_call_expr): Remove.
-2002-08-24 Matt Austern <austern@apple.com>
+2004-01-18 Mark Mitchell <mark@codesourcery.com>
- * tree.c (lvalue_p_1): Add argument for whether casts of lvalues
- are allowable.
- (real_lvalue_p): Update caller.
- (lvalue_p): Ditto.
- (non_cast_lvalue_or_else): New.
- * tree.h: Declare it.
- * typeck.c (build_unary_op): Use non_cast_lvalue_or_else.
+ PR c++/13710
+ * pt.c (tsubst): Use finish_typeof.
-2002-08-22 Mark Mitchell <mark@codesourcery.com>
+2004-01-18 Jason Merrill <jason@redhat.com>
- * typeck.c (build_class_member_access_expr): Handle COMPOUND_EXPR
- and COND_EXPR specially; fix error message output.
+ PR c++/11725
+ * except.c (build_throw): In a template, set
+ current_function_returns_abnormally.
-2002-08-22 Jason Merrill <jason@redhat.com>
+2004-01-17 Fred Fish <fnf@intrinsity.com>
- * pt.c (tsubst_expr): RETURN_EXPR is now RETURN_STMT_EXPR.
- * semantics.c (nullify_returns_r): Likewise.
+ PR c++/11895
+ * decl.c (reshape_init): Handle VECTOR_TYPE like ARRAY_TYPE,
+ except don't call array_type_nelts() with a VECTOR_TYPE.
-2002-08-17 Gabriel Dos Reis <gdr@integrable-solutions.net>
+2004-01-16 Jan Hubicka <jh@suse.cz>
- Fix PR/7621
- * typeck.c (finish_class_member_access_expr): Diagnose cases where
- name lookup finds nothing.
+ * mangle.c (write_mangled_name): Remove inline modifier.
-2002-08-15 Jason Merrill <jason@redhat.com>
+2004-01-16 Mark Mitchell <mark@codesourcery.com>
- * semantics.c (finish_then_clause): Remove redundant assignment.
- (finish_if_stmt, begin_switch_stmt, finish_switch_stmt): Move the
- extra binding level outside the if/switch statement.
- (finish_while_cond, finish_for_cond): Rewrite complex condition
- into the loop body.
-
-2002-08-15 Alexandre Oliva <aoliva@redhat.com>
-
- * parse.y (sizeof, alignof, typeof): New non-terminals to
- increment skip_evaluation. Replace terminals with them and
- decrement skip_evaluation at the end of rules using them.
- * decl2.c (mark_used): Don't assemble_external if
- skipping evaluation.
-
-2002-08-15 Gabriel Dos Reis <gdr@nerim.net>
+ PR c++/13574
+ * decl.c (compute_array_index_type): Fix grammar in comment.
+ * init.c (build_zero_init): Handle zero-sized arrays correctly.
- Fix PR/7504
- * parse.y (parse_finish_call_expr): Handle incomplete
- type used to name a scope.
+ PR c++/13178
+ * call.c (name_as_c_string): Print conversion operator names
+ correctly.
-2002-08-15 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/13478
+ * call.c (initialize_reference): Pass -1 for inner parameter to
+ convert_like_real.
- PR c++/7598
- * typeck.c (build_unary_op): Fold offsetof idiom. Fixes
- regression caused by my 2002-08-08 patch.
+2004-01-15 Giovanni Bajo <giovannibajo@gcc.gnu.org>
-2002-08-13 Mark Mitchell <mark@codesourcery.com>
+ PR c++/13407
+ * parser.c (cp_parser_base_specifier): Check for an invalid
+ keyword `typename' and emit an user-friendly error message.
- * decl.c (pushdecl_class_level): Honor requests to bind names to
- OVERLOADs.
+2004-01-15 Geoffrey Keating <geoffk@apple.com>
-2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+ PR pch/13361
+ * cp/lex.c (handle_pragma_interface): Duplicate string from tree.
+ (handle_pragma_implementation): Likewise.
- * decl2.c (build_call_from_tree): Fix uninitialized variable.
- * parse.y (parse_finish_call_expr): Likewise.
- * repo.c (old_args, old_dir, old_main): Const-ify.
+2004-01-15 Giovanni Bajo <giovannibajo@gcc.gnu.org>
-2002-08-11 Gabriel Dos Reis <gdr@nerim.net>
-
- * decl.c (duplicate_decls): Replace DECL_SOURCE_FILE +
- DECL_SOURCE_LINE with DECL_SOURCE_LOCATION.
- * optimize.c (maybe_clone_body): Likewise.
- * pt.c (tsubst_enum): Likewise.
- (lookup_template_class): Likewise.
- * tree.c (cp_copy_res_decl_for_inlining): Likewise.
-
-2002-08-10 Neil Booth <neil@daikokuya.co.uk>
-
- * lang-specs.h: Remove -ansi.
-
-2002-08-10 Nathan Sidwell <nathan@codesourcery.com>
-
- * tree.c (maybe_dummy_object): Replace // with /* */
-
-2002-08-09 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (standard_conversion): Use build_ptrmem_type.
- * cp-tree.h (build_ptrmem_type): New function.
- (adjust_result_of_qualified_name_lookup): Likewise.
- * decl.c (grokvardecl): Do not look for OFFSET_TYPEs to indicate
- static data members.
- (build_ptrmem_type): New function.
- (grokdeclarator): Do not use build_offset_type when encountering a
- qualified name.
- * parse.y (parse_finish_call_expr): Use
- adjust_result_of_qualified_name_lookup.
- * search.c (adjust_result_of_qualified_name_lookup): New function.
- * typeck.c (qualify_type_recursive): Use TYPE_PTRMEM_* rather than
- accessing OFFSET_TYPEs directly.
-
-2002-08-08 Mike Stump <mrs@apple.com>
-
- * call.c (add_builtin_candidate): legal -> valid, illegal -> invalid.
- (type_decays_to): Likewise.
- * class.c (find_final_overrider): Likewise.
- (maybe_note_name_used_in_class): Likewise.
- * decl.c (current_tmpl_spec_kind): Likewise.
- (add_binding): Likewise.
- (push_class_binding): Likewise.
- (duplicate_decls): Likewise.
- (layout_var_decl): Likewise.
- (grokfndecl): Likewise.
- (grokdeclarator): Likewise.
- (check_default_argument): Likewise.
- * decl2.c (handle_class_head): Likewise.
- * error.c (dump_template_decl): Likewise.
- * init.c (build_offset_ref): Likewise.
- * pt.c (check_specialization_scope): Likewise.
- (determine_specialization): Likewise.
- (check_explicit_specialization): Likewise.
- (maybe_check_template_type): Likewise.
- (process_partial_specialization): Likewise.
- (check_default_tmpl_args): Likewise.
- (push_template_decl_real): Likewise.
- (convert_template_argument): Likewise.
- (try_class_unification): Likewise.
- (get_bindings_real): Likewise.
- (do_decl_instantiation): Likewise.
- * semantics.c (begin_function_definition): Likewise.
- (finish_member_declaration): Likewise.
- (check_multiple_declarators): Likewise.
- * typeck.c (comp_array_types): Likewise.
- (comptypes): Likewise.
- (expr_sizeof): Likewise.
- (build_binary_op): Likewise.
- (dubious_conversion_warnings): Likewise.
- (check_return_expr): Likewise.
-
-2002-08-08 Mark Mitchell <mark@codesourcery.com>
-
- * typeck.c (build_class_member_access_expr): Do not return
- error_mark_node when no error has occurred.
-
-2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck.c (build_component_addr): Remove.
- (build_unary_op): Just check it's not a bitfield, and then build
- an ADDR_EXPR.
-
-2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (convert_to_base): Correct check for error_mark_node.
- (create_vtable_ptr): Remove unused VFUNS_P parm.
-
-2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp/Make-lang.in (c++.mostlyclean): Remove coverage files.
-
-2002-08-07 Mark Mitchell <mark@codesourcery.com>
-
- Rework build_component_ref.
- * call.c (build_vfield_ref): Do not go through build_component_ref.
- (build_field_call): Use build_class_member_access_expr.
- (build_user_type_conversion_1): Use BASELINK_FUNCTIONS.
- (build_object_call): Likewise.
- * class.c (convert_to_base): New function.
- (type_requires_array_cookie): Use BASELINK_FUNCTIONS.
- (instantiate_type): Handle BASELINKs.
- * cp-tree.def (BASELINK): New tree code.
- * cp-tree.h (BASELINK_P): Reimplement.
- (SET_BASELINK_P): Remove.
- (BASELINK_BINFO): Reimplement.
- (BASELINK_FUNCTIONS): Likewise.
- (BASELINK_ACCESS_BINFO): Likewise.
- (BASELINK_OPTYPE): Likewise.
- (convert_to_base): New function.
- (name_p): Likewise.
- (build_object_ref): Remove.
- (build_component_ref_1): Likewise.
- (build_component_ref): Likewise.
- (build_x_component_ref): Likewise.
- (build_class_member_access_expr): New function.
- (finish_class_member_access_expr): Likewise.
- (build_ptrmemfunc_access_expr): Likewise.
- * decl.c (grokdeclarator): Handle BASELINKs.
- * decl2. (build_expr_from_tree): Handle COMPONENT_REFs by using
- finish_class_member_access_expr.
- (arg_assoc): Handle BASELINKs.
- (do_class_using_decl): Likewise.
- * error.c (dump_decl): Likewise.
- (dump_expr): Use build_ptrmemfunc_access_expr.
- * except.c (dtor_nothrow): Use CLASSTYPE_DESTRUCTORS to find
- destructors.
- (build_throw): Use BASELINK_FUNCTIONS.
- * init.c (perform_member_init): Use
- build_class_member_access_expr.
- (build_offset_ref): Handle BASELINKs. Use
- build_class_member_access_expr.
- * method.c (hack_identifier): Likewise.
- * parse.y (do_id): Use BASELINK, not TREE_LIST.
- (primary): Remove uses of build_object_ref.
- * pt.c (lookup_template_function): Handle BASELINKs.
- (resolve_overloaded_unification): Likewise.
- * search.c (build_baselink): Build a BASELINK, not a TREE_LIST.
- (lookup_field): Use BASELINK, not TREE_LIST.
- (lookup_fnfiels): Likewise.
- (setup_class_bindings): Likewise.
- * semantics.c (finish_object_call_expr): Do not use
- build_method_call when we already know what function is being
- called.
- * spew.c (identifier_type): Use BASELINK, not TREE_LIST.
- * tree.c (really_overloaded_fn): Use OVL_CHAIN for OVERLOADs, not
- TREE_CHAIN.
- (name_p): New function.
- * typeck.c (build_object_ref): Remove.
- (build_component_ref_1): Likewise.
- (build_x_component_ref): Likewise.
- (build_class_member_access_expr): New function.
+ PR c++/9259
+ * typeck.c (build_class_member_access_expr): Allow to access members
+ of the currently open class.
(finish_class_member_access_expr): Likewise.
- (build_ptrmemfunc_access_expr): Likewise.
- (get_member_function_from_ptrfunc): Use
- build_ptrmemfunc_access_expr.
- (build_binary_op): Likewise.
- (build_unary_op): Likewise.
- (build_ptrmemfunc): Likewise.
- (pfn_from_ptrmemfunc): Likewise.
- * typeck2.c (build_m_component_ref): Adjust comment.
-
-2002-08-07 Neil Booth <neil@daikokuya.co.uk>
-
- * Make-lang.in (CXX_C_OBJS): Update.
- * cp-lang.c (LANG_HOOKS_DECODE_OPTION): Use c_common_decode_option.
- * cp-tree.h (cxx_decode_option): Remove.
- * decl2.c (compare_options, lang_f_options, unsupported_options,
- cxx_decode_option): Remove.
-
-2002-08-06 Gabriel Dos Reis <gdr@nerim.net>
-
- * typeck.c (build_x_unary_op): Handle pointer-to-member.
-
-2002-08-05 Geoffrey Keating <geoffk@redhat.com>
-
- * class.c: Don't include obstack.h.
- (popclass):
- * decl2.c: Delete bogus comment.
- * error.c: Don't include obstack.h.
- * except.c: Likewise.
- (dump_type): Correct comment.
- * method.c: Don't include obstack.h.
- * tree.c: Likewise.
-
-2002-08-04 Gabriel Dos Reis <gdr@nerim.net>
-
- Fix PR/2213
- * cvt.c (cp_convert_to_pointer): Reject conversions from integral
- expressions to pointer-to-data-member of pointer-to-member-functions.
-
-2002-08-04 Geoffrey Keating <geoffk@redhat.com>
-
- * cvt.c (ocp_convert): Delete obsolete code.
- * parse.y (permanent_obstack): Delete declaration.
- * pt.c (permanent_obstack): Delete declaration.
- * repo.c (permanent_obstack): Delete declaration.
- (open_repo_file): Use xmalloc instead of permanent_obstack.
- (init_repo): Use xstrdup instead of permanent_obstack.
-
-2002-08-04 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (VF_DERIVED_VALUE): Remove.
- * class.c (finish_struct_1): Use VF_BINFO_VALUE not VF_DERIVED_VALUE.
-
-2002-08-03 Nathan Sidwell <nathan@codesourcery.com>
-
- PR 7470.
- C++ ABI change - vfunc ordering.
- * class.c (add_virtual_function): Remove.
- (dfs_modify_all_vtables): Take list of all declared
- virtuals. Assign all that are not in primary base.
- (check_for_override): Adjust comments.
- (create_vtable_ptr): Take single list of virtuals. Build chain
- of declared virtuals here.
- (layout_class_type): Take single list of virtuals. Adjust.
- (finish_struct_1): Keep virtuals on single list. Adjust.
-
-2002-08-02 Mark Mitchell <mark@codesourcery.com>
-
- * init.c (build_member_call): Use build_new_method_call, not
- build_method_call.
-
-2002-08-02 Krister Walfridsson <cato@df.lth.se>
-
- * Make-lang.in (spew.o, lex.o, pt.o): Add path to parse.h dependencies.
-
-2002-08-02 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (build_method_call): Issue a more helpful error message
- about ambiguous method names.
-
-2002-08-02 Nathan Sidwell <nathan@codesourcery.com>
-
- * tree.c (build_shared_int_cst): Make cache file scope, and
- GTY it.
-
-2002-08-02 Jason Merrill <jason@redhat.com>
-
- * cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define.
- (cp_expr_size): New fn.
- * call.c (build_over_call): Lose empty class hackery.
- (convert_arg_to_ellipsis): Promote non-POD warning to error.
- * typeck.c (build_modify_expr): Don't use save_expr on an lvalue.
-
- * semantics.c (expand_body): Do tree optimization in the function
- context, too.
-
-2002-08-01 Neil Booth <neil@daikokuya.co.uk>
-
- * cp-tree.h: Move all warning and flag declarations to c-common.h.
- * decl.c: Move all warning and flag variables to c-common.c.
- * decl2.c: Move all warning and flag variables to c-common.c.
- * lex.c (flag_digraphs): Remove.
- (warn_traditional): Now in c-common.c.
-
-2002-07-31 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (build_field_call): Do not look up the field by name.
- (build_method_call): Simplify.
- (struct z_candidate): Add access_path and conversion_path. Remove
- basetype_path.
- (convert_class_to_reference): Adjust use of
- add_function_candidate.
- (add_candidate): Add conversion_path argument.
- (add_function_candidate): Use it.
- (add_conv_dndidate): Likewise.
- (build_builtin_candidate): Likewise.
- (add_template_candidate_real): Add conversion_path argument.
- (add_template_conv_candidate): Likewise.
- (add_template_candidate): Likewise.
- (build_user_type_conversion_1): Use it.
- (build_new_function_call): Remove name lookup code. Adjust use of
- add_template_candidate and add_function_candidate.
- (build_new_op): Likewise.
- (convert_like_real): Use build_special_member_call.
- (build_over_call): Use cand->conversion_path.
- (build_special_member_call): New method.
- (build_new_method_call): Remove name lookup code.
- * cp-tree.def (OFFSET_REF): Update documentation.
- (TEMPLATE_ID_EXPR): Likewise.
- * cp-tree.h (BASELINK_ACCESS_BINFO): New macro.
- (BASELINK_OPTYPE): Likewise.
- (build_new_method_call): Adjust prototype.
- (build_special_member_call): New method.
- (build_baselink): New method.
- (build_offset_ref_call_from_tree): Likewise.
- (build_call_from_tree): Likewise.
- (finish_qualified_call_expr): Remove.
- (finish_call_expr): Adjust prototype.
- (build_x_function_call): Remove.
- * cvt.c (ocp_convert): Use build_special_member_call.
- * decl2.c (reparse_absdcl_as_expr): Use finish_call_expr.
- (build_expr_from_tree): Adjust handling for TEMPLATE_ID_EXPR and
- CALL_EXPR.
- (build_offset_ref_call_from_tree): New function.
- (build_call_from_tree): Likewise.
- * init.c (expand_cleanup): Use build_special_member_call.
- (expand_default_init): Likewise.
- (build_member_call): Use finish_call_expr.
- (build_new_1): Use build_special_member_call.
- (push_base_cleanups): Likewise.
- * method.c (do_build_assign_ref): Likewise.
- * parse.y (template_id): Do not pass a COMPONENT_REF to
- lookup_template_function.
- (primary): Use parse_finish_call_epxr, not finish_call_expr.
- (parse_finish_call_expr): New function.
- * pt.c (lookup_template_function): Add assertions.
- * search.c (lookup_base): Allow T to be a binfo.
- (build_baselink): New function.
- (lookup_member): Use it.
- * semantics.c (finish_call_expr): Do not do name lookup.
- (finish_object_call_expr): Remove #if 0'd code.
- (finish_qualified_call_expr): Remove.
- * typeck.c (build_x_function_call): Remove.
- (build_static_case): Use build_special_member_call.
- * typeck2.c (build_functional_cast): Likewise.
-
-2002-07-30 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
-
- * lang-specs.h: Remove __GXX_ABI_VERSION, moved to gcc.c.
-
-2002-07-30 Gabriel Dos Reis <gdr@nerim.net>
-
- * cp-tree.h (VF_DERIVED_VALUE): Restore from previous deletion.
-
-2002-07-30 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (CLASSTYPE_VFIELDS, VF_*, BV_*): Add more
- documentation.
-
-2002-07-29 Alan Modra <amodra@bigpond.net.au>
-
- * cp-tree.h: Comment typo fix.
-
-2002-07-29 Richard Earnshaw <rearnsha@arm.com>
-
- * spew.c (space_for_token): Allocate zeroed memory for a new token
- chunk.
-
-2002-07-27 Roger Sayle <roger@eyesopen.com>
-
- * decl.c (builtin_function_1): No need to explicitly mark
- BUILT_IN_RETURN and BUILT_IN_EH_RETURN as noreturn.
-
-2002-07-27 Roger Sayle <roger@eyesopen.com>
-
- * decl2.c (cxx_decode_option): Support -fno-builtin-foo.
-
-2002-07-26 Jason Merrill <jason@redhat.com>
-
- * call.c (build_over_call): Likewise.
- (cp_convert_parm_for_inlining): New fn.
- (convert_for_arg_passing): New fn.
- (convert_default_arg, build_over_call): Use it.
- (type_passed_as): New fn.
- * pt.c (tsubst_decl): Use it.
- * decl2.c (cp_build_parm_decl): New fn.
- (build_artificial_parm): Use it.
- (start_static_storage_duration_function): Likewise.
- * decl.c (start_cleanup_fn, grokdeclarater): Likewise.
- (grokparms): Don't mess with DECL_ARG_TYPE.
- * typeck.c (convert_arguments): Use convert_for_arg_passing.
- * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
- Define.
- * cp-tree.h: Declare new fns.
-
-2002-07-26 Neil Booth <neil@daikokuya.co.uk>
-
- * cp-tree.h (flag_operator_names): Remove.
- * decl2.c (flag_operator_names): Remove.
- (lang_f_options): Remove operator-names.
- * lex.c (D_OPNAME): Remove.
- (reswords): Remove operator names.
- (rid_to_yy): Remove operator names.
- (init_reswords): No need to handle D_OPNAME.
- * spew.c (read_process_identifier): There are no operator
- names.
-
-2002-07-26 Jason Merrill <jason@redhat.com>
-
- * dump.c (cp_dump_tree): Call c_dump_tree.
- * Make-lang.in (CXX_C_OBJS): Add c-dump.o.
-
-2002-07-25 Neil Booth <neil@daikokuya.co.uk>
-
- * error.c (print_whitespace): Remove.
- * g++spec.c (LIBUNWIND): Move.
- * mangle.c (mangled_position, write_signed_number): Remove.
-
-2002-07-25 Neil Booth <neil@daikokuya.co.uk>
-
- * decl2.c (cxx_decode_option): Similarly.
-
-2002-07-25 Gabriel Dos Reis <gdr@nerim.net>
-
- * cp-tree.h (cxx_sizeof_nowarn): Now a macro.
- (cxx_sizeof_or_alignof_type): Take a third argument.
- (cxx_sizeof): Adjust definition.
- (cxx_alignof): Likewise.
- * init.c (build_delete): Use cxx_sizeof_nowarn to reflect reality.
- * typeck.c (cxx_sizeof_or_alignof_type): Take a third argument for
- complaining.
- (c_sizeof_nowarn): Remove definition.
- (build_unary_op): Use cxx_sizeof_nowarn.
-
-2002-07-24 Geoffrey Keating <geoffk@redhat.com>
-
- * tree.c (cp_build_qualified_type_real): When copying
- pointer-to-method types, unshare the record that holds
- the cached pointer-to-member-function type.
-
-2002-07-23 Neil Booth <neil@daikokuya.co.uk>
-
- * cp-tree.h (FILE_FUNCTION_PREFIX_LEN): Remove.
-
-2002-07-23 Gabriel Dos Reis <gdr@nerim.net>
-
- Fix PR/7363:
- * typeck.c (cxx_sizeof_or_alignof_type): New function.
- (c_sizeof): Remove definition.
- (expr_sizeof): Use cxx_sizeof.
- * decl2.c (build_expr_from_tree): Use cxx_sizeof_or_alignof_type.
- * decl.c (finish_destructor_body): Use cxx_sizeof.
- * semantics.c (finish_alignof): Likewise.
- (finish_alignof): Use cxx_alignof.
- * cp-tree.h (cxx_sizeof, cxx_alignof): New macros.
- (cxx_sizeof_or_alignof_type): Declare.
- (my_friendly_assert): Move to ../c-common.h.
-
-2002-07-23 Neil Booth <neil@daikokuya.co.uk>
-
- * class.c, method.c, pt.c, search.c: Don't define obstack macros.
-
-2002-07-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/7347, c++/7348
- * cp-tree.h (tsubst_flags_t): Add tf_parsing.
- * decl.c (make_typename_type): Use it.
- (make_unbound_class_template): Likewise.
- (lookup_name_real): Don't call type_access_control if scope is
- template parameter dependent.
- * parse.y (template_arg): Call make_unbound_class_template with
- tf_parsing set.
- (nest_name_specifier): Call make_typename_type with tf_parsing set.
- (typename_sub0): Likewise.
- (typename_sub1): Likewise.
- (instantiate_decl): Push class scope.
- * pt.c (regenerate_decl_from_template): Call pushclass and popclass
- for both static variable and member function template.
- (instantiate_decl) Call pushclass and popclass when tsubst'ing type
- and arguments.
- * search.c (type_access_control): Do type access for TEMPLATE_DECL
- too.
-
-2002-07-20 Roger Sayle <roger@eyesopen.com>
-
- * decl2.c (cxx_decode_option): Simplify -fhandle-exceptions
- test by using positive_option. Make whitespace consistent.
-
-2002-07-20 Gabriel Dos Reis <gdr@nerim.net>
-
- * spew.c (struct unparsed_test): Replace 'filename' and 'lineno'
- members with 'locus'. Adjust use throughout.
- (struct feed): Likewise.
- (alloc_unparsed_test): Change prototype, take a 'const location_t *'.
- Adjust use.
- (snarf_defarg): Use error(), not error_with_file_and_line().
-
-2002-07-19 Chris Demetriou <cgd@broadcom.com>
-
- * lang-specs.h (@c++): Include "%2" (cc1plus_spec) wherever
- cpp_options is included.
-
-2002-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/2862, c++/2863
- * pt.c (determine_specialization): Compare the length of
- TYPE_ARG_TYPES. Tidy.
-
-2002-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/3797
- * decl.c (duplicate_decls): Don't propagate inlining parameters from
- olddecl to newdecl when newdecl is a specialization of the
- instantiation olddecl.
-
-2002-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/4802, c++/5387
- * decl.c (make_typename_type): Use enforce_access.
-
-2002-07-17 Scott Snyder <snyder@fnal.gov>
-
- PR c++/7320
- * rtti.c (get_tinfo_decl): Set DECL_COMDAT.
-
-2002-07-12 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (add_method): Correct handling of conversion operators.
-
-2002-07-11 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/7224
- * class.c (add_method): Simplify.
-
-2002-07-11 Jason Merrill <jason@redhat.com>
-
- PR c++/7279
- * tree.c (cp_copy_res_decl_for_inlining): Also copy
- TREE_ADDRESSABLE.
-
-2002-07-10 Graham Stott <graham.stott@btinternet.com>
-
- * pt.c (template_parm_this_level_p, push_template_decl_real):
- Pass depth as int pointer.
-
-2002-07-11 Tim Josling <tej@melbpc.org.au>
-
- Remove front end hard coding from gengtype.c.
-
- * config-lang.in (gtfiles): Add files needed for this front end.
-
-2002-07-10 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (unqualified_name_lookup_error): Declare it.
- (begin_function_definition): Adjust prototype.
- * lex.c (unqualified_name_lookup_error): New function, split out
- from ...
- (do_identifier): ... here.
- * parse.y (parse_begin_function_definition): New function.
- (fn.def1): Use it.
- * semantics.c (begin_function_definition): Accept decl-specifiers
- and attributes as separate parameters.
-
-2002-07-10 Jason Merrill <jason@redhat.com>
-
- PR c++/6255
- * decl.c (lookup_name_real): Build a new TYPENAME_TYPE rather than
- modifying the old one.
-
-2002-07-09 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (constructor_name_p): Declare it.
- (check_template_template_default_arg): Likewise.
- * class.c (handle_using_decl): Use constructor_name_p.
- * decl.c (grokdeclarator): Likewise.
- * decl2.c (constructor_name_p): Define it.
- * init.c (build_member_call): Use constructor_name_p.
- * parse.y (template_parm): Use check_template_template_default_arg.
- * pt.c (check_explicit_specialization): Use constructor_name_p.
- * semantics.c (check_template_template_default_arg): New function.
-
-2002-07-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (can_complete_type_without_circularity): Add static to
- function definition.
-
-2002-07-08 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (have_extern_spec): Declare it
- * decl.c (have_extern_spec): Define it.
- (start_decl): Eliminate use of used_extern_spec.
- (start_function): Likewise.
- * parse.y (have_extern_spec): Remove declaration.
- (used_extern_spec): Likewise.
- (frob_specs): Eliminate use of used_extern_spec.
- (.hush_warning): Likewise.
-
-2002-07-07 Mark Mitchell <mark@codesourcery.com>
-
- * Make-lang.in (cp/parse.o): Depend on decl.h.
- * cp-tree.h (do_decl_instantiation): Change prototype.
- * parse.y: Include decl.h.
- (parse_decl_instantiation): New function.
- (explicit_instantiation): Use it.
- * pt.c (do_decl_instantiation): Accept a DECL, not a DECLARATOR
- and DECLSPECS.
-
-2002-07-07 Roger Sayle <roger@eyesopen.com>
-
- * error.c (dump_function_name): Use DECL_TEMPLATE_RESULT for
- constructor and destructor tests when passed a TEMPLATE_DECL.
-
-2002-07-05 Jason Merrill <jason@redhat.com>
-
- * cvt.c (cp_convert_to_pointer): Call force_fit_type for null
- pointers.
-
- PR optimization/7145
- * tree.c (cp_copy_res_decl_for_inlining): Also copy DECL_INITIAL.
-
-2002-07-05 Nathan Sidwell <nathan@codesourcery.com>
-
- Repair damage on weak-impared targets caused by my previous patch.
- * cp-tree.h (import_export_tinfo): Add parameter.
- * decl2.c (import_export_tinfo): Add parameter, post adjust
- DECL_COMDAT.
- * rtti.c (emit_tinfo_decl): DECL_COMDAT is (nearly) always setup by
- import_export_tinfo.
-
-2002-07-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/6944
- * init.c (build_aggr_init): Remove qualifiers of init before calling
- build_vec_init.
- (build_vec_init): Flatten multi-dimensional array during cleanup.
- (build_vec_delete_1): Abort if the type of each element is array.
-
-2002-07-03 Graham Stott <graham.stott@btinternet.com>
-
- * pt.c (instantiate_class_template): Fix typo.
-
-2002-07-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * typeck2.c (cxx_incomplete_type_diagnostic): Fix typo caused
- by CVS conflict in my last patch.
-
-2002-07-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/6716
- * pt.c (can_complete_type_without_circularity): New function.
- (instantiate_class_template): Use it.
- * typeck2.c (cxx_incomplete_type_diagnostic): Improve error
- message due to incomplete fields.
-
-2002-07-01 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/7112
- * mangle.c (write_expression): Add mangling for sizeof when
- applied to a type.
- * operators.def: Remove stale comment.
-
-2002-06-30 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (CPTI_TINFO_DECL_TYPE): Replace with ...
- (CPTI_TYPE_INFO_PTR_TYPE): ... this.
- (tinfo_decl_type): Replace with ...
- (type_info_ptr_type): ... this.
- (import_export_tinfo): Declare.
- (tinfo_decl_p): Rename to ...
- (unemitted_tinfo_decl_p): ... this.
- * decl2.c (import_export_decl): Break out tinfo handling into ...
- (import_export_tinfo): ... here. New function.
- (finish_file): Adjust.
- * rtti.c (TINFO_REAL_NAME): New macro.
- (init_rtti_processing): Create the tinfo types.
- (get_tinfo_decl_dynamic): Use type_info_ptr_type, get_tinfo_ptr.
- (get_tinfo_decl): Adjust.
- (get_tinfo_ptr): New function.
- (get_type_id): Use it.
- (tinfo_base_init): Create vtable decl here, if it doesn't exist.
- (ptr_initializer): Use get_tinfo_ptr.
- (ptm_initializer): Likewise.
- (synthesize_tinfo_var): Break into ...
- (get_pseudo_ti_init): ... this. Just create the initializer.
- (get_pseudo_ti_desc): .. and this.
- (create_real_tinfo_var): Remove.
- (create_pseudo_type_info): Don't create the vtable decl here.
- (get_vmi_pseudo_type_info): Remove.
- (create_tinfo_types): Adjust.
- (tinfo_decl_p): Rename to ...
- (unemitted_tinfo_decl_p): ... here. Adjust.
- (emit_tinfo_decl): Adjust. Create the initializer.
-
-2002-06-27 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/6695
- * pt.c (tsubst_friend_class): Substitute into the context of the
- friend before using it.
-
-2002-06-26 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (xref_tag): Change prototype.
- (handle_class_head): Likewise.
- (build_x_component_ref): Likewise.
- * decl.c (cxx_init_decl_processing): Adjust call to xref_tag.
- (xref_tag): Take attributes as a separate parameter.
- (xref_tag_from_type): Adjust call to xref_tag.
- * decl2.c (build_expr_from_tree): Adjust call to
- build_x_component_ref.
- (handle_class_head): Take attributes as a separate parameter.
- * parse.y (parse_xref_tag): New function.
- (parse_handle_class_head): Likewise.
- (primary): Use parse_xref_tag.
- (class_head_decl): Use parse_handle_class_head.
- (class_head_defn): Likewise.
- * rtti.c (init_rtti_processing): Adjust call to xref_tag.
- (build_dynamic_cast_1): Likewise.
- (create_pseudo_type_info): Likewise.
- (emit_support_tinfos): Likewise.
- * typeck.c (build_object_ref): Adjust call to
- build_x_component_ref.
- (build_x_component_ref): Remove protect parameter.
-
-2002-06-25 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (build_op_delete_call): Use BASELINK_FUNCTIONS.
- * class.c (handle_using_decl): Likewise.
- (instantiate_type): Likewise.
- * cp-tree.h (BASELINK_FUNCTIONS): New macro.
- (xref_basetypes): Change prototype.
- (begin_mem_initializers): New function.
- (get_overloaded_fn): Likewise.
- * decl.c (xref_basetypes): Simplify.
- * error.c (dump_expr): Use BASELINK_FUNCTIONS.
- * init.c (build_offset_ref): Likewise.
- * parse.y (base_init): Use begin_mem_initializers().
- (structsp): Adjust call to xref_basetypes.
- * pt.c (determine_specialization): Use BASELINK_FUNCTIONS.
- (instantiate_class_template): Adjust call to xref_basetypes.
- * semantics.c (begin_mem_initializers): New function.
- * tree.c (is_overloaded_fn): Use BASELINK_FUNCTIONS.
- (really_overlaoded_fn): Likewise.
- (get_overloaded_fn): New function.'
- (get_first_fn): USe BASELINK_FUNCTIONS.
-
-2002-06-24 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (SCALAR_TYPE_P): New macro.
- (check_for_out_of_scope_variable): New function.
- (at_class_scope_p): Likewise.
- (finish_fname): Likewise.
- * class.c (finish_struct): Use at_function_scope_p.
- * decl.c (check_for_out_of_scope_variable): New function, split
- out from do_identifier.
- (finish_enum): Use at_function_scope_p.
- * lex.c (do_identifier): Use check_for_out_of_scope_variable.
- * parse.y (VAR_FUNC_NAME): Give it <ttype>. Use finish_fname.
- (primary): Use at_function_scope_p.
- * search.c (at_class_scope_p): New function.
- * semantics.c (finish_fname): Likewise.
- (check_multiple_declarators): Use at_function_scope_p.
-
-2002-06-23 Mark Mitchell <mark@codesourcery.com>
-
- * parse.y (parse_scoped_id): New function.
- (primary): Use it.
- * cp-tree.h (do_scoped_id): Adjust declaration.
- * lex.c (do_scoped_id): Remove call to yylex.
- * decl2.c (build_expr_from_tree): Adjust use of do_scoped_id.
- * typeck2.c (add_exception_specifier): Use tree_cons, rather than
- expanding it inline.
-
-2002-06-23 Matt Thomas <matt@3am-software.com>
-
- * decl.c (finish_function): Change "#ifdef VMS_TARGET" to
- "#if VMS_TARGET".
-
-2002-06-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * mangle.c (integer_type_codes): Const-ify.
-
-2002-06-20 Richard Henderson <rth@redhat.com>
-
- PR c++/6747
- * typeck.c (mark_addressable): Don't test TREE_ADDRESSABLE early.
- Call put_var_into_stack.
-
-2002-06-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * spew.c (remove_last_token): Use ARRAY_SIZE in lieu of explicit
- array size calculation.
-
-2002-06-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/6892
- * pt.c (tsubst_expr): Handle FILE_STMT.
-
-2002-06-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/6723
- * pt.c (lookup_template_class): Don't build complete argument of
- BOUND_TEMPLATE_TEMPLATE_PARM if appeared as a default template
- argument.
-
-2002-06-19 Akim Demaille <akim@epita.fr>
-
- * parse.y (TYPENAME): Rename as tTYPENAME to avoid the clash with
- decl.h's TYPENAME.
- * spew.c, lex.c: Adjust.
- * parse.y (explicit_instantiation): Add empty action to override
- the default $$ = $1 where it introduces a type clash.
-
-2002-06-14 Jason Merrill <jason@redhat.com>
-
- * semantics.c (begin_for_stmt): Push the 'for' scope before
- adding the FOR_STMT.
-
- C++ ABI changes.
- * class.c (build_base_field): Set DECL_PACKED.
- (layout_class_type): Don't use tail padding of PODs.
- * mangle.c (write_unqualified_name): Fix template conversion op
- mangling.
-
-2002-06-16 Richard Henderson <rth@redhat.com>
-
- PR opt/6793
- * tree.c (cp_cannot_inline_tree_fn): Don't short-circuit test
- after template instantiation.
-
-2002-06-16 Richard Henderson <rth@redhat.com>
-
- * cp-tree.h, decl2.c (flag_ms_extensions): Move to c-common.
-
-2002-06-15 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * cp-tree.h (compiler_error): Remove declaration.
- * lex.c (compiler_error): Remove definition.
-
-2002-06-14 Steve Ellcey <sje@cup.hp.com>
-
- * g++spec.c (LIBUNWIND): New.
- (lang_specific_driver): Add it if USE_UNWIND_EXCEPTIONS is set.
-
-2002-06-13 Jessica Han <jessica@cup.hp.com>
-
- * class.c (build_vtable): Use TARGET_VTABLE_ENTRY_ALIGN.
- (build_vtbl_initializer): Honor TARGET_VTABLE_DATA_ENTRY_DISTANCE.
- (build_vbase_offset_vtbl_entries): Likewise.
- * rtti.c (build_headof): Likewise.
- (get_tinfo_decl_dynamic): Likewise.
- (create_pseudo_type_info): Likewise.
-
-2002-06-12 Stan Shebs <shebs@apple.com>
-
- * mpw-config.in: Remove file, no longer used.
- * mpw-make.sed: Ditto.
-
-2002-06-07 Zack Weinberg <zack@codesourcery.com>
-
- * decl2.c: Update call to cpp_handle_option.
-
-2002-06-07 H.J. Lu (hjl@gnu.org)
-
- * decl2.c (flag_use_cxa_atexit): Set to DEFAULT_USE_CXA_ATEXIT.
-
-2002-06-06 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c (cp_error_at): Fix typo.
-
-2002-06-04 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c (cp_diagnostic_starter): Adjust call.
- (maybe_print_instantiation_context): Change prototype to take a
- 'diagnostic_info *'.
- (print_instantiation_full_context): Likewise.
- (print_instantiation_partial_context): Likewise.
- (cp_diagnostic_starter): Likewise.
- (cp_diagnostic_finalizer): Likewise.
- (cp_print_error_function): Likewise.
- (cp_printer): Take a secondary parameter as a 'text_info *'.
- Remove output_state savings. Adjust calls.
-
-2002-06-03 Geoffrey Keating <geoffk@redhat.com>
-
- * pt.c (inline_parm_levels): Mark for GC.
-
- * mangle.c (start_mangling): Allocate G.substitutions here...
- (init_mangle): ... rather than here.
- (finish_mangling): Clear the varray pointer when done with it.
- * spew.c (yylexstring): Don't use VARRAY_FREE.
- * search.c (bfs_walk): Don't use VARRAY_FREE.
- * decl2.c (pending_statics): Use gengtype to mark.
- (deferred_fns): Likewise.
- (ssdf_decls): Likewise.
- (init_decl2): Delete.
- * decl.c (pop_from_top_level): Don't use VARRAY_FREE.
- (cxx_init_decl_processing): Don't call init_decl2.
- (cxx_pop_function_context): Don't use VARRAY_FREE.
- * cp-tree.h (struct saved_scope): No need for special marking
- of varrays.
- (struct language_function): Likewise.
- (local_classes): Use gengtype to mark.
- (init_decl2): Delete prototype.
- * class.c (init_class_processing): Don't use
- ggc_add_tree_varray_root.
- (build_vtbl_initializer): Don't use VARRAY_FREE.
-
- * decl.c (typename_compare): Don't use same_type_p.
-
- * decl.c: Include hashtab.h instead of hash.h.
- (typename_hash): Update to use htab_h.
- (typename_compare): Likewise.
- (typename_htab): Use gengtype to mark.
- (build_typename_type): Update to use htab_h.
- * Make-lang.in (cp/decl.o): Use HASHTAB_H instead of hash.h.
-
- * Make-lang.in (gt-cp-tree.h): New rule.
- (cp/tree.o): Depend on gt-cp-tree.h.
- * config-lang.in (gtfiles): Add cp/tree.c.
- * tree.c: Include gt-cp-tree.h.
- (list_hash_table): Use gengtype to mark.
- (init_tree): Use gengtype to mark trees.
-
- * Make-lang.in (cp/decl.o): Add debug.h dependency.
- * call.c (struct z_candidate): Use gengtype.
- (USER_CONV_CAND): Use WRAPPER_ZC.
- (convert_class_to_reference): Use build_zc_wrapper.
- (build_type_conversion_1): Likewise.
- (build_over_call): Use WRAPPER_ZC.
- (add_warning): Use build_zc_wrapper.
- * cp-lang.c (LANG_HOOKS_MARK_TREE): Delete.
- * cp-tree.h (struct lang_identifier): Use gengtype.
- (struct template_parm_index_s): Likewise.
- (struct ptrmem_cst): Likewise.
- (struct tree_binding): Likewise.
- (struct tree_overload): Likewise.
- (struct tree_srcloc): Likewise.
- (struct tree_wrapper): Likewise. Also modify to have a pointer
- to struct z_candidate rather than void.
- (enum cp_tree_node_structure_enum): New.
- (union lang_tree_node): New.
- (cxx_mark_tree): Delete prototype.
- (cp_tree_node_structure): New prototype.
- (build_ptr_wrapper): Delete prototype.
- (build_int_wrapper): Delete prototype.
- (build_zc_wrapper): New prototype.
- * decl.c: Include debug.h
- (cxx_mark_tree): Delete.
- (cp_tree_node_structure): New.
- * tree.c (build_ptr_wrapper): Delete.
- (build_int_wrapper): Delete.
- (build_zc_wrapper): New.
-
- * cp-tree.h [! ENABLE_TREE_CHECKING] (LANG_TYPE_PTRMEM_CHECK):
- Correct typo. Patch from k_fukui@highway.ne.jp.
-
- * semantics.c (current_stmt_tree): Update for change to
- struct language_function.
- (finish_mem_initializers): Likewise.
- * decl.c (cxx_init_decl_processing): Don't set mark_lang_status.
- * cp-tree.h (struct language_function): Rename from
- cp_language_function. Change all uses.
- (cp_function_chain): Don't need to cast.
-
- * class.c (duplicate_tag_error): Reset discriminator.
- (check_bases_and_members): Update for data structure changes.
- * cp-tree.h (struct lang_id2): Use gengtype.
- (flagged_type_tree): Likewise.
- (SET_LANG_ID): Use GGC on struct lang_id2.
- (struct cp_language_function): Use gengtype. Remove field
- 'x_vcalls_possible_p'.
- (current_vcalls_possible_p): Delete.
- (struct lang_type_header): New.
- (struct lang_type_class): Rename from struct lang_type. Include
- struct lang_type_header.
- (struct lang_type_ptrmem): New.
- (struct lang_type): New.
- (LANG_TYPE_CLASS_CHECK): New. Use it in all the appropriate macros.
- (LANG_TYPE_PTRMEM_CHECK): New. Use it in all the appropriate macros.
- (TYPE_SET_PTRMEMFUNC_TYPE): Set discriminator, update for changes.
- (struct lang_decl_flags): Use gengtype. Add discriminators.
- (struct lang_decl): Use gengtype. Add and use discriminators.
- Update the macros that reference moved fields.
- (LANG_DECL_U2_CHECK): New function. Use it when appropriate.
- (SET_DECL_THUNK_P): Set discriminator too.
- (clear_inline_text_obstack): Delete prototype.
- (finish_inline_definitions): Delete prototype.
- (mark_pending_inlines): Delete prototype.
- (lang_check_failed): New prototype.
- * decl.c (struct named_label_use_list): Use gengtype.
- (struct named_label_list): Likewise.
- (mark_binding_level): Delete.
- (mark_named_label_lists): Delete.
- (push_local_name): Set discriminator on DECL_LANG_SPECIFIC.
- (cxx_init_decl_processing): Use generated marker routine.
- (begin_destructor_body): Delete dead set to
- current_vcalls_possible_p.
- (mark_lang_function): Delete.
- (mark_cp_function_context): Delete.
- (lang_mark_tree): Use generated marker routines.
- * decl2.c (start_objects): Set discriminator when setting
- GLOBAL_INIT_PRIORITY.
- * lex.c (retrofit_lang_decl): Set discriminators.
- (copy_lang_type): Update for changes to lang_type structure.
- (cp_make_lang_type): Set discriminator.
- * parse.y: Use gengtype on YYLVAL. Don't use dots in identifiers.
- * search.c: Include ggc.h.
- * semantics.c (anon_aggr_type_p): Use the macro, don't hand-code it.
- (finish_inline_definitions): Delete.
- * spew.c (struct token): Use gengtype.
- (struct token_chunk): New.
- (struct unparsed_text): Use gengtype. Store tokens in chunks.
- (struct feed): Use gengtype.
- (feed_obstack): Delete.
- (feed): Mark as GC root.
- (pending_inlines): Mark as GC root.
- (pending_inlines_tail): Likewise.
- (processing_these_inlines): Likewise.
- (token_obstack): Make static.
- (first_token): Likewise.
- (init_spew): Don't initialize deleted things; use gengtype for roots.
- (clear_inline_text_obstack): Delete.
- (feed_input): Use GC for struct feed. Update for changes to
- struct unparsed_text.
- (mark_pending_inlines): Delete.
- (next_token): Rename from add_token. Change all callers. Update
- for changes to struct unparsed_text.
- (space_for_token): New.
- (remove_last_token): New.
- (alloc_unparsed_text): New.
- (snarf_block): Take an unparsed_text. Update for changes to struct
- unparsed_text.
- (snarf_method): Update for changes to struct unparsed_text.
- (snarf_defarg): Update for changes to struct unparsed_text.
- * tree.c (lang_check_failed): New.
-
- * Make-lang.in (gt-cp-call.h gt-cp-decl2.h gt-cp-parse.h
- gt-cp-pt.h gt-cp-repo.h gt-cp-spew.h): New rules.
- (cp/spew.o): Add dependency on gt-<filename>.h.
- (cp/decl2.o): Add dependency on gt-<filename>.h.
- (cp/call.o): Add dependency on gt-<filename>.h.
- (cp/pt.o): Add dependency on gt-<filename>.h.
- (cp/repo.o): Add dependency on gt-<filename>.h.
- (cp/parse.o): Add dependency on gt-<filename>.h.
- * call.c: Use gengtype for roots.
- * config-lang.in (gtfiles): Add cp-tree.h decl.h lex.h call.c
- decl2.c parse.y pt.c repo.c spew.c.
- * cp-tree.h: Use gengtype for roots.
- (struct saved_scope): Use GGC, gengtype.
- (cp_parse_init): Delete prototype.
- (init_pt): Delete prototype.
- * decl.c: Use gengtype for roots.
- (mark_saved_scope): Delete.
- (cxx_init_decl_processing): Don't call deleted initilisation
- routines.
- (signed_size_zero_node): Delete, unused.
- * decl.h: Use gengtype for roots.
- * decl2.c: Use gengtype for roots.
- * lex.h: Use gengtype for roots.
- * parse.y: Use gengtype for roots.
- (cp_parse_init): Delete.
- * pt.c: Use gengtype for roots.
- (init_pt): Delete.
- * repo.c: Use gengtype for roots.
- * spew.c: Use gengtype for roots.
-
- * Make-lang.in: Allow for filename changes. Add gtype-cp.h.
- (cp/decl.o): Add dependency on gtype-cp.h.
- * decl.c: Remove use of add_deletable_root, use GTY marker instead.
- Include gtype-cp.h. Allow for filename changes.
-
- * Make-lang.in (cp/gt-decl.h): Generate using gengtype.
- (cp/decl.o): Add cp/gt-decl.h dependency.
- * config-lang.in (gtfiles): New.
- * tree.h: Rename struct binding_level to struct cp_binding_level.
- * decl.c: Rename struct binding_level to struct cp_binding_level.
- Include cp/gt-decl.h.
- (struct cp_binding_level): Use gengtype.
- (make_binding_level): Use GGC on struct cp_binding_level.
- (mark_binding_level): Use gt_ggc_m_cp_binding_level.
- (cxx_init_decl_processing): Mark free_binding_level as
- deletable.
-
- * decl.c (mark_cp_function_context): Update calling sequence.
-
- * decl.c (start_function): Don't free 'struct
- cp_language_function'.
- (pop_cp_function_context): Likewise.
- (save_function_data): Allocate it using GC.
- * semantics.c (genrtl_start_function): Don't free 'struct
- cp_language_function'.
-
-2002-05-31 Matthew Woodcraft <mattheww@chiark.greenend.org.uk>
-
- * lang-specs.h: Use cpp_debug_options.
-
-2002-05-28 Zack Weinberg <zack@codesourcery.com>
-
- * mangle.c, tree.c: Include real.h.
- * Make-lang.in: Update dependency lists.
-
-2002-05-25 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * lex.c: Don't include c-lex.h.
- * parse.y, spew.c: Don't include c-lex.h; include c-pragma.h.
-
-2002-05-23 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * spew.c (yyungetc, snarf_block): Remove indent_level handling.
-
-2002-05-22 Richard Henderson <rth@redhat.com>
-
- * decl.c (obscure_complex_init): Check for VAR_DECL
- before using DECL_THREAD_LOCAL.
-
-2002-05-22 Richard Henderson <rth@redhat.com>
-
- * decl.c (check_tag_decl): Handle RID_THREAD.
- (obscure_complex_init): Reject run-time init of tls.
- (grokvardecl, grokdeclarator): Handle RID_THREAD.
- * lex.c (reswords): Add __thread.
- (rid_to_yy): Map RID_THREAD to SCSPEC.
-
-2002-05-22 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_POST_OPTIONS): Use c_common_post_options.
- * cp-tree.h (cxx_post_options): Kill.
- * cp-lex.c (cxx_post_options): Kill.
-
-2002-05-21 Richard Henderson <rth@redhat.com>
-
- * lex.c (rid_to_yy): Add RID_THREAD.
-
-2002-05-21 Alexandre Oliva <aoliva@redhat.com>
-
- * init.c (build_vec_init): Test for trivial copy-assignment when
- copy-assigning arrays.
-
-2002-05-20 Andreas Jaeger <aj@suse.de>
-
- * init.c (build_default_init): Remove unused variable.
-
-2002-05-20 Alexandre Oliva <aoliva@redhat.com>
-
- * call.c (any_strictly_viable): New.
- (build_new_op): Use it for COMPOUND_EXPR and ADDR_EXPRs.
-
-2002-05-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * error.c (dump_type) [TYPEOF_TYPE]: Fix parenthesis printing.
-
-2002-05-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/186, DR 259
- * pt.c (do_decl_instantiation): Don't complain explicit
- instantiation after explicit specialization.
- (do_type_instantiation): Likewise.
-
-2002-05-19 Alexandre Oliva <aoliva@redhat.com>
-
- * cp-tree.h (complete_type_or_diagnostic): Changed prototype,
- renamed from...
- (complete_type_or_else): ... this. Redefined as macro.
- (cxx_incomplete_type_diagnostic): Declare.
- (cxx_incomplete_type_error): Define as macro.
- * init.c (build_delete): Warn about incomplete types other than
- void, and use the built-in operator delete for them.
- * typeck.c (complete_type_or_diagnostic): Renamed from
- complete_type_or_else. Added warn_only argument, passed to...
- * typeck2.c (cxx_incomplete_type_diagnostic): ... this. Print
- warnings or errors depending on new warn_only argument. Renamed
- from...
- (cxx_incomplete_type_error): ... this. New implementation in
- terms of cxx_incomplete_type_diagnostic.
-
-2002-05-18 Jason Merrill <jason@redhat.com>
-
- PR c++/6611
- * decl2.c (import_export_decl): If we clear
- DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set.
-
-2002-05-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- PR c++/6620
- * pt.c (verify_class_unification): Don't check if PARM is template
- parameter dependent. Simplify.
- (unify) [TEMPLATE_PARM_INDEX]: Handle when ARG is a template
- parameter dependent expression.
-
-2002-05-14 Jason Merrill <jason@redhat.com>
-
- * rtti.c (get_tinfo_decl): Don't call comdat_linkage.
- Do set DECL_COMDAT.
- (synthesize_tinfo_var): Take the public decl.
- (create_real_tinfo_var): Likewise. Check DECL_COMDAT.
- (emit_tinfo_decl): Adjust. Call import_export_decl.
- * decl2.c (import_export_decl): Simplify tinfo decl handling.
-
-2002-05-14 Alexandre Oliva <aoliva@redhat.com>
-
- * cp-tree.h (struct lang_type): Added non_zero_init.
- (CLASSTYPE_NON_ZERO_INIT_P): New macro.
- (zero_init_p, force_store_init_value, build_forced_zero_init): Declare.
- * class.c (check_field_decls): Test non_zero_init.
- * cvt.c (convert_to_pointer_force): Use cp_convert_to_pointer for
- zero-to-NULL conversions.
- * decl.c (obscure_complex_init): Don't reset DECL_INITIAL of a
- type that needs zero-initialization without zeros.
- (check_initializer_decl): Compute zero-initializer for types
- that require a non-trivial one.
- * init.c (build_forced_zero_init): New function.
- (build_default_init): Use it.
- * tree.c (zero_init_p): New function.
- * typeck2.c (force_store_init_value): New function.
- (process_init_constructor): Create non-trivial zero-initializers
- for array members and class fields.
-
-2002-05-14 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * lang-specs.h: Remove redundant -lang-c++.
-
-2002-05-13 Jason Merrill <jason@redhat.com>
-
- * class.c (build_vtbl_ref_1): Use fixed_type_or_null.
- (fixed_type_or_null): See through reference vars.
- (build_base_path): Vtable contents are constant.
- * typeck.c (get_member_function_from_ptrfunc): Likewise.
-
-2002-05-12 Jason Merrill <jason@redhat.com>
-
- * cp-lang.c (ok_to_generate_alias_set_for_type): Backend-created
- structs are safe.
-
-2002-05-09 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-tree.h (flag_ansi): Remove.
- * decl2.c (flag_ansi): Remove.
- (cxx_decode_option): Set flag_iso and flag_undef.
-
-2002-05-09 Jason Merrill <jason@redhat.com>
-
- * typeck.c (get_member_function_from_ptrfunc): Reorganize.
- Use subtraction rather than a bitmask to get the index.
- * cvt.c (cp_convert_to_pointer): Bail on an error_mark_node.
-
- * pt.c (tsubst_expr) [ASM_STMT]: Copy ASM_INPUT_P.
-
-2002-05-07 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * Make-lang.in (decl2.o): Update.
- * cp-tree.h (warn_multichar): Remove.
- * decl2.c: Include c-common.h.
- (warn_multichar): Remove.
-
-2002-05-03 Jason Merrill <jason@redhat.com>
-
- * tree.c (build_cplus_array_type): Only const and volatile get
- special handling.
-
- * decl.c (BOOL_TYPE_SIZE): Move default to defaults.h.
-
-2002-04-30 Mark Mitchell <mark@codesourcery.com>
-
- ABI change, returning simple classes from functions.
- * class.c (finish_struct_bits): Only mark TREE_ADDRESSABLE if
- TYPE_HAS_TRIVIAL_INIT_REF is false or
- TYPE_HAS_NONTRIVIAL_DESTRUCTOR is true.
-
-2002-04-30 Jason Merrill <jason@redhat.com>
-
- PR debug/6436
- * decl.c (grokdeclarator): Don't override TYPE_NAME of an
- anonymous class with a typedef if there are attributes.
-
-2002-04-29 Paul Eggert <eggert@twinsun.com>
-
- * parse.y (nomods_initdcl0): Replace $<ttype>3 with $<ttype>$.
-
-2002-04-29 Jakub Jelinek <jakub@redhat.com>
-
- PR c++/6477
- * decl.c (follow_tag_typedef): Check if TYPE_NAME (original) is
- non-NULL first.
-
-2002-04-29 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/6492
- * pt.c (tsubst_friend_class): If the friend has an explicit scope,
- enter that scope before name lookup.
-
- PR c++/6486
- * method.c (do_build_copy_constructor): Avoid building
- cv-qualified reference types.
-
-2002-04-29 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/5719
- * decl.c (grok_op_properties): Assignment ops don't have to return
- by value. operator% should.
-
-2002-04-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
-
- PR c/6343
- * decl.c (duplicate_decls): Call merge_weak.
-
-2002-04-26 Richard Henderson <rth@redhat.com>
-
- * parse.y (malloced_yyss, malloced_yyvs): New.
- (yyoverflow): Re-add. Set them.
- (free_parser_stacks): New.
-
-2002-04-26 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/6497
- * method.c (do_build_assign_ref): Pass a derivation to
- build_method_call when calling base class assignment operators.
-
-2002-04-26 Richard Henderson <rth@redhat.com>
-
- * parse.y (yyoverflow): Revert.
-
-2002-04-26 Richard Henderson <rth@redhat.com>
-
- PR c/3581
- * parse.y (string): Remove. Update all uses to use STRING
- instead, and not call combine_strings.
- * rtti.c (tinfo_name): Use fix_string_type.
- * semantics.c (finish_asm_stmt): Don't call combine_strings.
- * spew.c (yylexstring): New.
- (read_token): Use it.
-
-2002-04-25 Richard Henderson <rth@redhat.com>
-
- PR c/2161
- * parse.y (yyoverflow): New.
-
-2002-04-25 Jason Merrill <jason@redhat.com>
-
- PR c++/5607
- * search.c (check_final_overrider): No longer static.
- * class.c (update_vtable_entry_for_fn): Call it.
- * cp-tree.h: Adjust.
-
-2002-04-25 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_SET_YYDEBUG): Remove.
- * cp-tree.h (cxx_set_yydebug): Die.
- * lex.c (YYDEBUG): Get from c-lex.h.
- (cxx_set_yydebug): Remove.
- * parse.y: Include c-lex.h.
- (YYDEBUG): Get from c-lex.h.
-
-2002-04-24 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/6438.
- * cvt.c (convert_to_void): Don't unconditionally make COND_EXPRs
- void.
-
-2002-04-24 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE,
- LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE, LANG_HOOKS_ATTRIBUTE_TABLE):
- Redefine.
- * cp-tree.h (cp_attribute_table): Rename.
- * decl.c (lang_attribute_table): Remove declaration.
- (cxx_init_decl_processing): Don't set it.
- * tree.c (cp_attribute_table): Rename.
-
-2002-04-24 Jason Merrill <jason@redhat.com>
-
- PR c++/6331
- * method.c (do_build_copy_constructor): Use cp_build_qualified_type.
- * typeck.c (build_modify_expr): Allow arrays to differ in cv-quals.
- The pedwarn for array assignment is now unconditional.
- * tree.c (build_cplus_array_type_1): Still process simple array types
- normally in templates.
-
- PR c++/6395
- * decl.c (make_rtl_for_nonlocal_decl): Don't mess with #pragma i/i
- stuff for comdats.
-
-2002-04-23 Jakub Jelinek <jakub@redhat.com>
-
- * parse.y (check_class_key): Allow KEY to be union/enum/struct/class
- node with attributes.
-
-2002-2-23 David O'Brien <obrien@FreeBSD.org>
-
- * g++spec.c (MATH_LIBRARY_PROFILE, LIBSTDCXX_PROFILE): Add.
- Use MATH_LIBRARY_PROFILE and LIBSTDCXX_PROFILE if profile flag given.
-
-2002-04-23 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/6256:
- * pt.c (tsubst_friend_class): Handle templates with explicit
- nested names.
-
- PR c++/6331:
- * typeck.c (merge_types): Remember the cv-qualification of pointer
- types when merging them.
-
-2002-04-20 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_FUNCTION_INIT,
- LANG_HOOKS_FUNCTION_FREE, LANG_HOOKS_FUNCTION_MARK): Redefine.
- * cp-tree.h (cxx_push_function_context, cxx_pop_function_context,
- cxx_mark_function_context): New.
- * decl.c (push_cp_function_context, pop_cp_function_context,
- mark_cp_function_context): Rename for consistency.
- (cxx_init_decl_processing): Don't set old hooks.
-
-2002-04-19 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * call.c (convert_type_from_ellipsis): Rename, update.
- * cp-lang.c (LANG_HOOKS_TYPE_PROMOTES_TO): Redefine.
- * cp-tree.h (convert_type_from_ellipsis): Rename.
- * decl.c (cxx_init_decl_processing): Don't set hook.
-
-2002-04-18 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * call.c (build_new_method_call): Update.
- * cp-lang.c (LANG_HOOKS_INCOMPLETE_TYPE_ERROR): Redefine.
- * cp-tree.h (cxx_incomplete_type_error): New.
- * decl.c (grokdeclarator, grokparms): Update.
- * decl2.c (check_classfn): Update.
- * pt.c (tsubst): Update.
- * typeck.c (complete_type_or_else, expr_sizeof,
- decay_conversion): Update.
- * typeck2.c (incomplete_type_error): Rename.
- (add_exception_specifier): Update.
-
-2002-04-18 Jason Merrill <jason@redhat.com>
-
- PR c++/5658
- * search.c (setup_class_bindings): A class template qualifies as a
- type binding.
-
-2002-04-17 Jakub Jelinek <jakub@redhat.com>
-
- PR c++/6316
- * decl2.c (finish_file): Clear DECL_EXTERNAL in a separate loop
- before expanding.
-
-2002-04-16 Mark Mitchell <mark@codesourcery.com>
-
- * init.c (begin_init_stmts): Remove commented out code.
- (finish_init_stmts): Set STMT_EXPR_NO_SCOPE.
- * semantics.c (begin_gobal_stmt_expr): Adjust call to
- expand_start_stmt_expr.
-
-2002-04-15 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (register_dtor_fn): Pass the address of dso_handle, not
- dso_handle itself, to __cxa_atexit.
-
-2002-04-15 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
-
- * error.c (cxx_print_error_function): Adjust call to macros.
-
-2002-04-14 Jakub Jelinek <jakub@redhat.com>
-
- * class.c (layout_virtual_bases): Do all dsize computation on trees.
-
-2002-04-14 Jason Merrill <jason@redhat.com>
-
- * typeck.c (get_member_function_from_ptrfunc): Don't do
- gratuitious division and multiplication on
- ptrmemfunc_vbit_in_delta targets.
-
-2002-04-12 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/5373.
- * semantics.c (finish_expr_stmt): Remember the type of the
- expression before any conversions are performed.
-
-2002-04-12 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/5189.
- * call.c (add_template_candidate_real): Do not treat member
- templates as copy constructors.
-
-2002-04-12 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (duplicate_decls): Do not copy the RTL for a variable
- declaration if the old variable had an incomplete type and the new
- variable does not.
- (complete_vars): Do not call layout_decl for completed variables.
-
-2002-04-12 Richard Sandiford <rsandifo@redhat.com>
-
- * decl.c (duplicate_decls): Don't try to unify an implicit typedef
- with an explicit one.
- (follow_tag_typedef): New.
- (lookup_tag): Use it to extract the tag of an explicit typedef.
- (xref_tag): Likewise.
-
-2002-04-11 Andrew Haley <aph@redhat.com>
-
- * typeck.c (type_after_usual_arithmetic_conversions):
- If two types have the same variant, return immediately.
- When two floating-point operands are the same precision:
- convert to float if one of the operands is float;
- if neither operand is one of the standard types, return the type
- of the first operand.
-
-2002-04-10 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/5507
- * decl.c (make_typename_type): Remove implicit typenameness.
-
-2002-04-09 Jason Merrill <jason@redhat.com>
-
- PR optimization/6189
- * semantics.c (genrtl_start_function): Don't free
- DECL_SAVED_FUNCTION_DATA for inline functions.
-
- * init.c (build_member_call): For now, don't convert to
- intermediate base if it would cause an error.
-
-2002-04-08 Paolo Carlini <pcarlini@unitus.it>
-
- * parse.y (namespace_qualifier, maybe_identifier,
- begin_explicit_instantiation, end_explicit_instantiation,
- apparent_template_type, .finish_template_type,
- do_id, maybe_init, defarg_again, component_decl_1):
- Add ending ';', in accordance with POSIX.
-
-2002-04-06 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/5571
- * class.c (layout_class_type): Remember incomplete static
- variables.
- (finish_struct_1): Call complete_vars, not
- hack_incomplete_structures.
- * cp-tree.h (hack_incomplete_structures): Rename to ...
- (complete_vars): ... this.
- (struct saved_scope): Remove incomplete.
- (namespace_scope_incomplete): Remove.
- * decl.c (struct binding_level): Remove incomplete.
- (incomplete_vars): New variable.
- (mark_binding_level): Don't mark incomplete.
- (print_binding_level): Don't print it.
- (mark_saved_scope): Don't mark incomplete.
- (pushdecl): Use maybe_register_incopmlete_var.
- (cxx_init_decl_processing): Register incomplete_vars for GC.
- (start_decl_1): Clarify error message.
- (hack_incomplete_vars): Remove.
- (maybe_register_incomplete_var): New function.
- (complete_vars): Likewise.
-
-2002-04-06 Jason Merrill <jason@redhat.com>
-
- PR c++/4934
- * error.c (dump_expr) [CONVERT_EXPR]: Make sure TREE_TYPE (t) is
- set before checking it.
-
- PR c++/525
- * init.c (build_member_call): Use build_scoped_ref.
- (resolve_offset_ref): Likewise.
- * call.c (build_scoped_method_call): Likewise.
- * tree.c (maybe_dummy_object): Kludge around current_class_type being
- wrong.
- * typeck2.c (build_scoped_ref): Return the binfo via binfo_p parm.
- * cp-tree.h: Adjust.
-
- * init.c (push_base_cleanups): Just use build_scoped_method_call.
-
- PR c++/6179
- * method.c (implicitly_declare_fn): Pass unqualified type to
- synthesize_exception_spec.
-
-2002-04-04 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_TRUTHVALUE_CONVERSION): Redefine.
- * cvt.c: Update comment.
- * init.c (expand_cleanup_for_base): Update.
- * semantics.c (finish_parenthesized_expr): Update.
- * typeck.c (cp_truthvalue_conversion): Update.
-
-2002-04-04 Jason Merrill <jason@redhat.com>
-
- * semantics.c (finish_eh_cleanup): New fn.
- * cp-tree.h: Add prototype.
- * init.c (perform_member_init, expand_cleanup_for_base): Use
- finish_eh_cleanup.
- * cp-tree.def (SUBOBJECT, CTOR_STMT): Remove.
- * cp-tree.h: Remove references.
- * decl.c (begin_constructor_body, end_constructor_body): Likewise.
- * dump.c (cp_dump_tree): Likewise.
- * pt.c (tsubst_expr): Likewise.
- * semantics.c (genrtl_ctor_stmt, genrtl_subobject): Remove.
- (cp_expand_stmt): Remove handling of CTOR_STMT and SUBOBJECT.
- * tree.c (cp_statement_code_p): Likewise.
-
- * init.c (build_new_1): Set CLEANUP_EH_ONLY on deleting cleanup.
-
- PR c++/5636
- * semantics.c (nullify_returns_r): Just set CLEANUP_EH_ONLY on
- cleanup for nrv.
-
- PR c++/5104
- * typeck.c (comptypes) [FUNCTION_TYPE]: Don't compare exception
- specifiers.
- [METHOD_TYPE]: Use same code as FUNCTION_TYPE.
-
-2002-04-03 Richard Henderson <rth@redhat.com>
-
- * cp-lang.c (cxx_warn_unused_global_decl): New.
- (LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New.
-
-2002-04-03 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): Redefine.
- * tree.c (init_tree): Don't set hook.
-
-2002-04-03 Roger Sayle <roger@eyesopen.com>
-
- PR c++/5998:
- * decl.c (duplicate_decls): Don't mess with assembler names when
- redeclaring builtin functions as static.
-
-2002-04-01 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * call.c (build_addr_func): Update.
- * class.c (resolve_address_of_overloaded_function): Update.
- * cp-lang.c (LANG_HOOKS_MARK_ADDRESSABLE): Redefine.
- * cp-tree.h (cxx_mark_addressable): New.
- * decl.c (register_dtor_fn, cxx_maybe_build_cleanup): Update.
- * decl2.c (build_cleanup): Update.
- * except.c (build_throw): Update.
- * init.c (resolve_offset_ref): Update.
- * pt.c (convert_nontype_argument): Update.
- * semantics.c (finish_asm_stmt, simplify_affr_init_exprs_r): Update.
- * typeck.c (decay_conversion, build_array_ref, build_unary_op,
- unary_complex_lvalue): Update.
- (mark_addressable): Rename.
-
-2002-04-01 Roger Sayle <roger@eyesopen.com>
-
- PR c++/5998:
- * decl.c (duplicate_decls): Overwrite the RTL when (and only
- when) overwriting a built-in function. Don't use COPY_DECL_RTL,
- but follow the SET_DECL_RTL idiom used elsewhere in the function.
-
-2002-04-01 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_SIGNED_TYPE, LANG_HOOKS_UNSIGNED_TYPE,
- LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE): New.
- * decl.c (grokdeclarator): Update.
- * mangle.c (write_integer_cst): Update.
- * typeck.c (build_binary_op): Update.
-
-2002-03-31 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_UNSAFE_FOR_REEVAL): Redefine.
- * lex.c (cxx_init): Don't set hook.
-
-2002-03-31 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * Make-lang.in (error.o): Update.
- * cp-lang.c (LANG_HOOKS_PRINT_ERROR_FUNCTION): Redefine.
- * cp-tree.h (struct diagnostic_context): Predeclare.
- (cxx_print_error_function): New.
- * error.c: Include langhooks-def.h.
- (lang_print_error_function): Rename. Update.
- (init_error): Don't set hook.
-
-2002-03-29 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIZE):
- Redefine.
- * cvt.c (cp_convert_to_pointer, type_promotes_to): Use new hooks.
- * decl.c (finish_enum): Similarly.
- * error.c (dump_type): Similarly.
- * lex.c (cxx_init): Similarly.
- * mangle.c (write_builtin_type): Similarly.
- * typeck.c (comptypes): Similarly.
-
-2002-03-28 Roger Sayle <roger@eyesopen.com>
-
- PR c++/5998:
- * decl.c (cxx_init_decl_processing): Re-enable built-in functions
- in the g++ front-end.
- (duplicate_decl): Allow redefinition of anticipated built-ins.
- Fix inlining problem by over-writing the old DECL_RTL.
- (lookup_namespace_name): Fail to find an identifier in the
- specified namespace if its still anticipated.
- (builtin_function_1): New function split out from builtin_function
- to create a builtin in the current namespace with given context.
- (builtin_function): Call builtin_function_1 to define the
- appropriate builtins in both the std and global namespaces.
- (select_decl): Don't test for anticipated decls here.
- (unqualified_namespace_lookup): Instead ignore them whilst
- searching through scopes and namespaces.
- * decl2.c (do_nonmember_using_decl): If a using declaration
- specifies an anticipated built-in function, mark it as no longer
- anticipated in that scope.
- (ambiguous_decl): Avoid resolving to an anticipated decl.
- * lex.c (do_scoped_id): Fail to find an identifier in the global
- namespace if its still anticipated.
-
-2002-03-29 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_MAKE_TYPE): Redefine.
- * cp-tree.h (cp_make_lang_type): Rename.
- * lex.c (cp_make_lang_type): Rename.
- (make_aggr_type): Update.
- * tree.c (init_tree): Don't set make_lang_type_fn.
-
-2002-03-29 Jakub Jelinek <jakub@redhat.com>
-
- PR c++/6073
- * class.c (finish_struct_1): Update static field's DECL_MODE even
- if its type is a variant of t.
-
-2002-03-27 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Redefine.
- * cp-tree.h (cxx_insert_default_attributes): New.
- * decl.c (insert_default_attributes): Rename.
-
-2002-03-27 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/4884
- * call.c (build_op_delete_call): Allow for the fact the placement
- may be a COMPOUND_EXPR.
-
-2002-03-27 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_EXPAND_EXPR): Redefine.
- * cp-tree.h (init_cplus_expand): Remove.
- (cxx_expand_expr): New.
- * expr.c (cplus_expand_expr): Rename cxx_expand_expr,
- fix prototype.
- (init_cplus_expand): Remove.
- * lex.c (cxx_init): Don't call init_cplus_expand.
-
-2002-03-26 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/4884.
- * init.c (build_new_1): Allow for the fact the result of
- build_function_call may be a COMPOUND_EXPR.
-
-2002-03-26 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/5682
- * cp-tree.h (BINFO_PRIMARY_P): Explain meaning better.
- (dfs_skip_nonprimary_vbases_unmarkedp): Remove.
- (dfs_skip_nonprimary_vbases_markedp): Remove.
- * search.c (get_shared_vbase_if_not_primary): Remove.
- (dfs_skip_nonprimary_vbases_unmarkedp): Remove.
- (dfs_skip_nonprimary_vbases_markedp): Remove.
- (dfs_unmarked_real_bases_queue_p): Just get the canonical binfo.
- (dfs_marked_real_bases_queue_p): Likewise.
-
-2002-03-26 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_MARK_TREE): Redefine.
- * cp-tree.h (cxx_mark_tree): New.
- * decl.c (lang_mark_tree): Rename cxx_mark_tree.
-
-2002-03-25 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-tree.h (cxx_maybe_build_cleanup): New.
- * decl.c (destroy_local_var, hack_incomplete_structures): Update.
- (maybe_build_cleanup): Rename cxx_maybe_build_cleanup.
- * tree.c (build_target_expr): Update.
- * cp-lang.c (LANG_HOOKS_MAYBE_BUILD_CLEANUP): Redefine.
-
-2002-03-24 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * decl2.c (cxx_decode_option): Handle -E.
- * lang-specs.h (default_compilers): Preprocess with cc1plus.
- * lex.c (cxx_init): Exit quickly if c_common_init returns NULL.
-
-2002-03-23 Jakub Jelinek <jakub@redhat.com>
-
- PR c++/6037
- * decl.c (start_enum): Don't set TREE_ADDRESSABLE on TREE_LIST node.
-
-2002-03-23 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
-
- * error.c (dump_type): Be careful about implicit typenames.
-
-2002-03-21 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
-
- PR C++/3656
- * semantics.c (finish_base_specifier): Handle erronous base
- classes.
-
-2002-03-22 Zack Weinberg <zack@codesourcery.com>
-
- * error.c: Always use REAL_VALUE_TO_DECIMAL; don't test
- REAL_IS_NOT_DOUBLE.
-
-2002-03-22 Jeff Knaggs <jknaggs@redhat.com>
-
- * typeck.c (get_member_function_from_ptrfunc): Scale idx down to
- an index into the vtable_entry array regardless of
- TARGET_PTRMEMFUNC_VBIT_LOCATION.
-
-2002-03-21 Aldy Hernandez <aldyh@redhat.com>
-
- * tree.c (cp_cannot_inline_tree_fn): Same.
-
-2002-03-21 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-tree.h (pushdecl, pushlevel, poplevel, set_block,
- insert_block, getdecls, global_bindings_p): New.
-
-2002-03-20 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/4361
- * mangle.c (struct globals) Add internal_mangling_p member.
- (write_template_param): Do internal mangling, if needed.
- (mangle_conv_op_name_for_type): Request internal mangling.
-
-2002-03-20 Jason Merrill <jason@redhat.com>
-
- PR c++/2136
- * init.c (build_delete): Check access for a member op delete here.
- * decl2.c (delete_sanity): Not here.
-
-2002-03-19 Jason Merrill <jason@redhat.com>
-
- PR c++/5118
- * class.c (get_vfield_name): Use the constructor_name.
-
-2002-03-20 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_DECL_PRINTABLE_NAME): Redefine.
- * cp-tree.h (lang_printable_name): Rename.
- * error.c (lang_decl_name): Use new hook.
- * lex.c (cxx_init): Remove old hook.
- * pt.c (tsubst_decl): Use new hook.
- * tree.c (lang_printable_name): Rename.
-
-2002-03-18 Eric Botcazou <ebotcazou@multimania.com>
-
- PR c++/3882
- * pt.c (tsubst_decl): Move __PRETTY_FUNCTION__ handling...
- (tsubst_expr) [DECL_STMT]: ...here. And substitute the initializer
- only after recording the declaration.
-
-2002-03-18 Jason Merrill <jason@redhat.com>
-
- PR c++/2039
- * init.c (resolve_offset_ref): Hand off to build_component_ref.
-
- PR c++/4222, c++/5995
- * call.c (build_over_call): Fix empty class logic.
-
- PR c++/3870
- * cp-tree.h (struct saved_scope): Add last_parms field.
- * decl.c (maybe_push_to_top_level): Save last_function_parms.
- (pop_from_top_level): Restore it.
-
- PR c++/4377
- * mangle.c (write_expression): Strip NOP_EXPRs sooner. Also strip
- NON_LVALUE_EXPRs.
-
- PR c++/4003
- * pt.c (tsubst_friend_function): Use decl_namespace_context.
-
- PR c++/3948 -- C++ ABI change, followup to 2001-12-18 patch.
- * class.c (finish_struct_bits): Also set TREE_ADDRESSABLE for a
- type with a nontrivial destructor.
-
-2002-03-17 Jason Merrill <jason@redhat.com>
-
- PR c++/4460
- * class.c (build_base_path): Virtual base layout is fixed in
- in-charge [cd]tors.
-
-2002-03-17 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_PARSE_FILE): Redefine.
- * parse.y (yyparse): Remove macro.
-
-2002-03-17 Jason Merrill <jason@redhat.com>
-
- PR c++/5757
- * init.c (build_new_1): Pass the right pointer to op delete.
-
-2002-03-16 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/4361
- * cp-tree.h (CLASSTYPE_METHOD_VEC): Document where templated
- conversion operators go.
- (struct lang_decl_flags): Add template_conv_p and unused
- bitfields.
- (DECL_TEMPLATE_CONV_FN_P): New macro.
- * call.c (build_user_type_conversion_1): Don't check second type
- conversion of overload set first.
- * class.c (add_method): Make sure templated conversion operators
- all end up on slot 2.
- * lex.c (do_identifier): A conversion operator token might be
- satisfied by a templated conversion operator.
- * pt.c (check_explicit_specialization): Use
- CLASSTYPE_FIRST_CONVERSION_SLOT.
- (template_parm_this_level_p): New function.
- (push_template_decl_real): Determine DECL_TEMPLATE_CONV_FN_P.
- * search.c (lookup_fnfields_1): Template conversions will be on
- the first slot.
- * typeck.c (build_component_ref): Preserve the type of an
- conversion operator name on the overload type.
- (build_x_function_call): Retrieve the conversion operator name.
-
-2002-03-15 Richard Henderson <rth@redhat.com>
-
- * init.c (build_new_1): Use size_binop instead of cp_build_binary_op.
-
-2002-03-15 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (CLEANUP_DECL): Remove.
- (CLEANUP_EXPR): Likewise.
- * decl.c (destroy_local_var): Simplify.
- (maybe_build_cleanup): Tidy.
- * dump.c (cp_dump_tree): Remove handling of CLEANUP_STMT.
- * semantics.c (cp_expand_stmt): Likewise.
- * cp/tree.c (cp_statement_code_p): Likewise.
-
-2002-03-15 Jason Merrill <jason@redhat.com>
-
- PR c++/5857
- * decl.c (duplicate_decls): Use merge_types instead of common_type.
- * typeck.c (common_type): Just hand off to
- type_after_usual_arithmetic_conversions and
- composite_pointer_type.
- (merge_types): New fn.
- (commonparms): Use it instead of common_type.
- (type_after_usual_arithmetic_conversions): Also handle COMPLEX_TYPE.
- (composite_pointer_type): Also handle attributes.
- * cp-tree.h: Declare merge_types.
-
- * decl.c (make_rtl_for_nonlocal_decl): Also defer COMDAT
- variables.
- * decl2.c (maybe_make_one_only): Also mark the decl as needed.
-
-2002-03-14 Richard Henderson <rth@redhat.com>
-
- * decl.c: Include c-pragma.h.
- (start_decl, start_function): Invoke maybe_apply_pragma_weak.
- * Make-lang.in: Update dependencies.
-
-2002-03-14 Jakub Jelinek <jakub@redhat.com>
-
- PR c++/5908
- * call.c (build_over_call): Set TREE_NO_UNUSED_WARNING too.
- * cvt.c (convert_to_void): Preserve TREE_NO_UNUSED_WARNING.
-
-2002-03-12 Richard Sandiford <rsandifo@redhat.com>
-
- * mangle.c (write_builtin_type): Handle 128-bit integers even if
- they are not a standard integer type.
-
-2002-03-12 Richard Sandiford <rsandifo@redhat.com>
-
- * cp-tree.h (init_init_processing): Remove declaration.
- * init.c (BI_header_type, init_init_processing): Remove old ABI stuff.
- * decl.c (cxx_init_decl_processing): Don't call init_init_processing.
-
-2002-03-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * cp-lang.c (tree_code_type, tree_code_length, tree_code_name):
- Define.
- * decl.c (duplicate_decls): Use TREE_CODE_LENGTH, not
- tree_code_length.
- * lex.c (cplus_tree_code_type, cplus_tree_code_length,
- cplus_tree_code_name): Delete.
- (cxx_init): Don't call add_c_tree_codes, instead set
- lang_unsafe_for_reeval. Don't try to copy into the various
- tree_code arrays.
-
-2002-03-12 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/5659
- * decl.c (xref_tag): Don't set CLASSTYPE_DECLARED_CLASS here.
- * decl2.c (handle_class_head): Set CLASSTYPE_DECLARED_CLASS for
- definitions.
-
-2002-03-11 Nathan Sidwell <nathan@codesourcery.com>
-
- Revert 2001-03-26 Nathan Sidwell <nathan@codesourcery.com>,
- DR209 is now not a defect.
- * cp-tree.h (skip_type_access_control): Remove.
- * decl.c (grokdeclarator): Do type access control for friend
- declarations.
- * semantics.c (decl_type_access_control): Don't reset
- current_type_lookups.
- (save_type_access_control): Always save the lookups.
- (skip_type_access_control): Remove.
- (finish_class_definition): Don't change type_lookups.
-
-2002-03-11 Nathan Sidwell <nathan@codesourcery.com>
-
- Revert 2000-12-01 Nathan Sidwell <nathan@codesourcery.com>,
- It is incorrect.
- * typeck.c (build_static_cast): Compare non-qualified types
- with pointer to member conversions.
-
-2002-03-11 Dan Nicolaescu <dann@ics.uci.edu>
- Daniel Berlin <dan@dberlin.org>
-
- * cp-lang.c (ok_to_generate_alias_set_for_type): New function.
- (cxx_get_alias_set): Use it.
-
-2002-03-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * cp-tree.h (stabilize_expr): Prototype.
-
-2002-03-08 Craig Rodrigues <rodrigc@gcc.gnu.org>
-
- * cp-tree.h (CLEAR_BINFO_MARKED): Make both parts of
- conditional return void.
-
-2002-03-08 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_UNSAVE): Redefine.
- * cp-tree.h (cxx_unsave): New.
- * tree.c (cp_unsave): Rename cxx_unsave, update prototype.
- (init_tree): Update.
-
-2002-03-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * decl.c (cxx_init_decl_processing): Use ARRAY_SIZE in lieu of
- explicit sizeof/sizeof.
- * decl2.c (cxx_decode_option): Likewise.
- * lex.c (init_reswords, REDUCE_LENGTH, TOKEN_LENGTH): Likewise.
-
-2002-03-02 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/775
- * decl.c (lookup_tag): Only reject enum/class mismatch, not
- class/union mismatch.
- * parse.y (check_class_key): New function.
- (structsp): Call it.
-
-2002-03-01 Michael Matz <matz@suse.de>
-
- * typeck.c (cp_pointer_int_sum): Complete inner type which is
- used later by size_in_bytes().
-
-2002-03-01 Phil Edwards <pme@gcc.gnu.org>
-
- * cp-tree.h: Require __GNUC__ to be #defined.
- (build_init): Add missing prototype.
-
-2002-03-01 Jason Merrill <jason@redhat.com>
-
- * except.c: Don't include decl.h or obstack.h. Do include
- tree-inline.h.
- (build_throw): Destroy temporaries from the thrown
- expression before calling __cxa_throw. Construct a thrown
- temporary directly into the exception object.
- (stabilize_throw_expr): New function.
- (wrap_cleanups_r): New function.
- * tree.c (stabilize_expr): New function.
- * init.c (build_init): New function.
- * Make-lang.in (cp/except.o): Adjust .h deps.
-
-2002-02-28 Jason Merrill <jason@redhat.com>
-
- * search.c (lookup_base_r): Don't clear is_non_public just because
- we found a friendly scope.
-
- * decl.c (finish_function): Only warn about missing return
- statement with -Wreturn-type.
-
-2002-02-28 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * class.c (build_clone): Update.
- * cp-lang.c (LANG_HOOKS_DUP_LANG_SPECIFIC_DECL): Redefine.
- * cp-tree.h (cxx_dup_lang_specific_decl): New.
- * lex.c (copy_lang_decl): Rename cxx_dup_lang_specific_decl.
- (copy_decl): Update.
- * method.c (make_thunk): Update.
-
-2002-02-27 Zack Weinberg <zack@codesourcery.com>
-
- * decl2.c: Delete traditional-mode-related code copied from
- the C front end but not used, or used only to permit the
- compiler to link.
-
-2002-02-24 Craig Rodrigues <rodrigc@gcc.gnu.org>
-
- PR c++/4093
- * cp-tree.h (SET_BINFO_MARKED): Cast false part of condition
- to void.
-
-2002-02-22 Jakub Jelinek <jakub@redhat.com>
-
- PR other/5746
- * semantics.c (finish_switch_cond): Don't call get_unwidened
- if error_mark_node.
-
-2002-02-22 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/2645, DR 295
- * cp-tree.h (tsubst_flags_t): Add tf_ignore_bad_quals,
- tf_keep_type_decl.
- (make_typename_type): Use tsubst_flags_t.
- * decl.c (make_typename_type): Adjust. Return non-artificial
- TYPE_DECLs, if required.
- (grokdeclarator): Simplify CVR qualification handling. Allow bad
- qualifiers on typedef types.
- * decl2.c (handle_class_head): Adjust make_typename_type call.
- * parse.y (nested_name_specifier): Likewise.
- (typename_sub0): Likewise.
- (typename_sub1): Likewise.
- * pt.c (convert_template_argument): Adjust make_typename_type
- return value.
- (tsubst): Adjust cp_build_qualified_type_real calls.
- (check_cv_quals_for_unify): Cope with allowing bad qualifications
- on template type parms.
- (instantiate_decl): Recheck substitutions to give warnings on bad
- qualifications.
- * tree.c (cp_build_qualified_type_real): Use tf_allow_bad_quals.
-
-2002-02-21 Aldy Hernandez <aldyh@redhat.com>
-
- * cp/decl.c (duplicate_decls): Merge always_inline attribute.
-
- * cp/tree.c (cp_cannot_inline_tree_fn): Do not inline at -O0
- unless DECL_ALWAYS_INLINE.
-
-2002-02-20 Jakub Jelinek <jakub@redhat.com>
-
- * typeck.c (cp_pointer_int_sum): Renamed from
- pointer_int_sum, call pointer_int_sum.
-
-2002-02-20 Jakub Jelinek <jakub@redhat.com>
-
- * decl.c (duplicate_decls): Return 0 if issued error about
- redeclaration.
-
-2002-02-19 Jason Merrill <jason@redhat.com>
-
- ABI change: Mangle `void (A::*)() const' as
- M1AKFvvE, not MK1AFvvE.
- * mangle.c (write_function_type): Write cv-quals for member
- function type here.
- (write_pointer_to_member_type): Not here.
-
-2002-02-18 Jason Merrill <jason@redhat.com>
-
- * pt.c (do_type_instantiation): Don't pedwarn if in_system_header.
- (do_decl_instantiation): Likewise.
-
-2002-02-17 Craig Rodrigues <rodrigc@gcc.gnu.org>
-
- PR c++/5685
- * decl.c (duplicate_decls): Make warning unconditional
- if duplicate default argument declarations are present.
-
-2002-02-17 Jakub Jelinek <jakub@redhat.com>
-
- * typeck.c (build_binary_op) [BIT_XOR_EXPR]: Remove explicit
- shortening.
-
-2002-02-15 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (grokdeclarator): Set typedef_decl for all TYPE_DECLs,
- remove incorrect comment. Move #if 0'd code to common path. Use
- IMPLICIT_TYPENAME_P. Simplify & reformat ARRAY_TYPE duplication.
-
-2002-02-13 Jason Merrill <jason@redhat.com>
-
- * decl.c (builtin_function): Set TREE_THIS_VOLATILE on return fns.
- (finish_function): Don't warn if current_function_returns_null.
-
- * typeck2.c (digest_init): Do handle values of vector type.
-
- * typeck2.c (digest_init, process_init_constructor): Treat vectors
- like arrays.
-
-2002-02-11 Jason Merrill <jason@redhat.com>
-
- * parse.y (reserved_declspecs): Don't handle attributes.
- (reserved_typespecquals): Handle them here.
- * Make-lang.in (parse.c): Adjust expected conflicts.
-
-2002-02-08 Jakub Jelinek <jakub@redhat.com>
-
- * parse.y (primary, primary_no_id): Use compstmt_or_stmtexpr
- instead of compstmt.
- (compstmt_or_stmtexpr): Renamed from compstmt.
- (compstmt): In addition to compstmt_or_stmtexpr clear last_expr_type.
-
-2002-02-07 Nathan Sidwell <nathan@codesourcery.com>
-
- Rename instantiate_type_flags to tsubst_flags_t & expand use.
- * cp-tree.h (instantiate_type_flags): Rename to ...
- (tsubst_flags_t): ... here. Rename itf_complain to tf_error,
- add tf_warning flag.
- (instantiate_type): Adjust prototype.
- (tsubst, tsubst_expr, tsubst_copy, lookup_template_class,
- do_type_instantiation, cp_build_qualified_type_real): Likewise.
- cp_build_qualified_type: Adjust.
- * class.c (instantiate_type): Adjust parameter. Rename itf_* to
- tf_*.
- * call.c (standard_conversion): Rename itf_* to tf_*.
- (reference_binding): Likewise.
- (convert_like_real): Likewise.
- * cvt.c (cp_convert_to_pointer): Likewise.
- (convert_to_reference): Likewise.
- * decl.c (lookup_namespace_name): Use tf_* flags.
- (make_typename_type): Likewise.
- (grokdeclarator): Likewise.
- * pt.c (convert_nontype_argument): Adjust COMPLAIN usage.
- (coerce_template_template_parms, convert_template_argument,
- coerce_template_parms, maybe_get_template_decl_from_type_decl,
- lookup_template_class, tsubst_friend_function, tsubst_friend_class,
- instantiate_class_template, tsubst_template_arg_vector,
- tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument,
- tsubst_decl, tsubst_arg_types, tsubst_function_type,
- tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr,
- instantiate_template, fn_type_unification,
- resolve_overloaded_unification, verify_class_unification,
- unify, get_bindings_real, do_type_instantiation,
- regenerate_decl_from_template, instantiate_decl,
- tsubst_initializer_list, tsubst_enum,
- get_mostly_instantiated_function_type,
- invalid_nontype_parm_type_p): Likewise.
- * tree.c (cp_build_qualified_type_real): Likewise.
- * typeck.c (build_binary_op): Rename itf_* to tf_*.
- (build_ptrmemfunc): Likewise.
- (convert_for_assignment): Likewise.
-
-2002-02-07 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/109
- * decl.c (grokdeclarator): Allow friend declarations from
- dependent types.
- * decl2.c (handle_class_head): Don't push into template parm contexts.
- * pt.c (push_template_decl_real): Template parm contexts are never
- being defined.
-
-2002-02-05 Alexandre Oliva <aoliva@redhat.com>
-
- * class.c: Include target.h.
- (check_bitfield_decl): Disregard EMPTY_FIELD_BOUNDARY,
- BITFIELDS_NBYTES_LIMITED and PCC_BITFIELD_TYPE_MATTERS for MS
- bit-field layout.
- * Make-lang.in: Adjust deps.
-
-2002-02-05 Jason Merrill <jason@redhat.com>
-
- * error.c (dump_type): Be more helpful about VECTOR_TYPE.
-
-2002-02-04 Jakub Jelinek <jakub@redhat.com>
-
- * semantics.c (begin_switch_stmt): Clear SWITCH_TYPE.
- (finish_switch_cond): Set SWITCH_TYPE.
-
-2002-02-04 Richard Henderson <rth@redhat.com>
-
- * method.c (use_thunk): Always initialize the block tree. Reindent.
- * semantics.c (expand_body): Emit thunks after function, not before.
-
-2002-02-04 Jason Merrill <jason@redhat.com>
-
- * decl.c (start_function): Call cplus_decl_attributes immediately
- after grokdeclarator.
-
- * decl.c (start_function): Combine DECL_RESULT handling code.
-
-2002-02-03 Jason Merrill <jason@redhat.com>
-
- * xref.c: Remove.
- * Make-lang.in (CXX_OBJS): Remove cp/xref.o
- (cp/xref.o): Remove dependencies.
- * class.c (finish_struct_1, check_methods): Don't call xref fns.
- (finish_struct_1): Likewise.
- * friend.c (make_friend_class): Likewise.
- * lex.c (cxx_init, cxx_finish, extract_interface_info): Likewise.
- * spew.c (read_process_identifier): Likewise.
-
-2002-02-01 Jason Merrill <jason@redhat.com>
-
- PR c++/4872
- * decl.c (finish_function): Warn about a non-void function with
- no return statement and no abnormal exit.
- * cp-tree.h (struct cp_language_function): Add returns_abnormally.
- (current_function_returns_abnormally): New macro.
- * call.c (build_call): Set it.
-
- * typeck.c (build_component_ref): Always complain about offsetof
- constructs on non-PODs. Only make it an error for members of
- virtual bases.
-
- * error.c (dump_scope): Don't add TFF_DECL_SPECIFIERS.
- (dump_function_decl): Always dump parms.
-
- * decl2.c (finish_static_data_member_decl): Complain about a local
- class with a static data member.
-
- PR c++/4286
- * search.c (lookup_field_1): Don't xref a static data member
- just because we looked it up.
-
-2002-01-31 Jason Merrill <jason@redhat.com>
-
- * Make-lang.in (parse.c): Handle .output file.
-
- PR c++/3395
- * decl.c (xref_tag): Remember early attributes in TYPE_ATTRIBUTES,
- not TREE_TYPE.
- * semantics.c (finish_class_definition): Adjust.
-
- Allow attributes in parms and casts.
- * parse.y (named_parm): Don't strip attrs.
- (declmods): Remove 'attributes' production.
- (nonempty_cv_qualifiers): Accept attributes.
- (ATTRIBUTE): Give precedence.
- * decl.c (groktypename): Handle attributes.
- (grokparms): Likewise.
-
-2002-01-29 Jakub Jelinek <jakub@redhat.com>
-
- * decl2.c (cxx_decode_option): Pass 0 as last argument to
- cpp_handle_option.
- * lang-specs.h: Use cpp_unique_options instead of cpp_options
- when used together with cc1_options.
-
-2002-01-29 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/5132
- * typeck2.c (digest_init): Make sure non-array core type is
- instantiated.
- * decl2.c (reparse_absdcl_as_casts): Just store the type in the
- constructor, rather than build a new one.
- (build_expr_from_tree, CONSTRUCTOR case): Be careful with the
- PURPOSE of constructor elts.
-
-2002-01-23 Zack Weinberg <zack@codesourcery.com>
-
- * Make-lang.in (parse.c): Adjust expected number of
- shift-reduce conflicts.
- (decl.o): Depend on diagnostic.h.
- * decl.c: Include diagnostic.h.
- (grokdeclarator): Check for null pointer.
- (finish_function): Don't abort when
- current_binding_level->parm_flag != 1, if errors have
- occurred; throw away the statement tree and extra binding
- levels, and continue.
- * lex.c (note_list_got_semicolon): Check for null pointer.
- * method.c (hack_identifier): Just return error_mark_node if
- value is error_mark_node.
- * parse.y (primary: TYPEID(type_id)): No need to use
- TYPE_MAIN_VARIANT here.
- (handler_seq): Accept an empty list of catch clauses and
- generate a fake handler block to avoid later crashes.
- (ansi_raise_identifier): Accept the error token too.
- * semantics.c (begin_class_definition,
- finish_class_definition): Check for error_mark_node.
-
-2002-01-23 Zack Weinberg <zack@codesourcery.com>
-
- * typeck2.c (friendly_abort): Delete definition.
- * cp-tree.h (friendly_abort): Don't prototype.
- (my_friendly_assert): Use fancy_abort.
-
-2002-01-23 Craig Rodrigues <rodrigc@gcc.gnu.org>
-
- * cp-tree.h (my_friendly_abort): Remove.
-
-2002-01-23 Jakub Jelinek <jakub@redhat.com>
-
- * spew.c (pending_inlines, pending_inlines_tail,
- processing_these_inlines): Make static.
- (mark_pending_inlines): Remove static.
- (begin_parsing_inclass_inline): If in function, save pi
- for GC to cp_function_chain->unparsed_inlines instead.
- (process_next_inline): Likewise.
- * cp-tree.h (struct cp_language_function): Add unparsed_inlines.
- (mark_pending_inlines): Add prototype.
- * decl.c (spew_debug): Remove unused extern.
- (mark_lang_function): Call mark_pending_inlines.
-
-2002-01-23 Craig Rodrigues <rodrigc@gcc.gnu.org>
-
- * call.c, class.c, decl.c, decl2.c, error.c, expr.c, friend.c,
- init.c, lex.c, mangle.c, method.c, pt.c, repo.c, rtti.c, search.c,
- semantics.c, spew.c, tree.c, typeck.c, typeck2.c, xref.c:
- Change my_fancy_abort() to abort().
-
-2002-01-23 Jason Merrill <jason@redhat.com>
-
- PR c++/5453
- * class.c (fixed_type_or_null): Fix thinko.
-
- PR c++/3331
- * init.c (resolve_offset_ref): Use build_indirect_ref.
-
- * decl2.c (grokclassfn): Don't set DECL_REGISTER on 'this'.
-
-2002-01-22 Jason Merrill <jason@redhat.com>
-
- * parse.y (function_body): Suppress the block for the outermost
- curly braces.
- * decl.c (pushdecl): Don't try to skip it.
- (begin_function_body): Keep the block we create, not the next one.
- * init.c (emit_base_init): Don't mess with keep_next_level.
-
- * class.c (build_base_path): Tweak formatting.
-
-2002-01-19 Nathan Sidwell <nathan@codesourcery.com>
-
- Fix regression introduced with patch for c++/775
- * parse.y (class_head_defn): Check for template specializations
- with a different class-key.
-
-2002-01-17 Jason Merrill <jason@redhat.com>
-
- * decl.c (begin_constructor_body, begin_destructor_body): New fns.
- (begin_function_body): Call them and keep_next_level.
- * init.c (emit_base_init): Call keep_next_level.
- * semantics.c (setup_vtbl_ptr): Lose.
- * cp-tree.h (struct cp_language_function): Remove vtbls_set_up_p.
- (vtbls_set_up_p): Lose.
- * pt.c (tsubst_expr, CTOR_INITIALIZER): Call emit_base_init.
- * method.c (do_build_copy_constructor): Likewise.
- (synthesize_method): Call finish_mem_initializers.
- * parse.y (nodecls): Likewise.
-
- * error.c (dump_type_suffix): Print the exception specs before
- recursing.
- (dump_function_decl): Here, too.
-
- * cp-tree.h (TMPL_PARMS_DEPTH): Cast to signed HOST_WIDE_INT.
-
-2002-01-10 Ira Ruben <ira@apple.com>
-
- PR c++/907
- * decl.c (start_method): Handle attrlist.
-
-2002-01-10 Jakub Jelinek <jakub@redhat.com>
-
- * decl2.c (max_tinst_depth): Increase default limit to 500.
-
-2002-01-10 Graham Stott <grahams@redhat.com>
-
- * spew.c (YYCHAR): Uppercase macro parameter and add
- parenthesis.
- (YYCODE): Likewise.
- (NAME): Uppercase macro parameter.
-
-2002-01-09 Graham Stott <grahams@redhat.com>
-
- * decl.h (grokdeclarator): Wrap long line.
-
- * semantics.c (FINISH_COND): Uppercase macro paramaters and
- add parenthesis.
-
-2002-01-08 Graham Stott <grahams@redhat.com>
-
- * xref.c (FILE_NAME_ABSOLUTE_P): Add parenthesis.
- (PALLOC): Uppercase macro parameter and whitespace.
- (SALLOC): Uppercase macro parameter.
- (SFREE): Uppercase macros parameter, add parenthese and
- whitespace.
- (STREQL): Uppercase macro parameter and whitespace.
- (STRNEQ): Likewise.
- (STRLSS): Likewise.
- (STRLEQ): Likewise.
- (STRGTR): Likewise.
- (STRGEQ): Likewise.
-
- * call.c (convert_like): Add parenthesis and wrap.
- (convert_like_with_context): Likewise.
- (ICS_RANK): Whitespace.
- (NEED_TEMPORARY_P): Remove parenthesis.
-
- * class.c (VTT_TOP_LEVEL_P): Uppercase macro parameter and
- whitespace.
- (VTT_MARKED_BINFO_P): Likewise.
-
- * decl.c (BINDING_LEVEL): Add parenthesis.
- (DEF_OPERATOR): Likewise.
-
- * mangle.c (MANGLE_TRACE): Add parenthesis.
- (MANGLE_TRACE_TREE): Likewise.
- (write_signed_number): Likewise.
- (write_unsigned_number): Likewise.
-
- * pt.c (ccat): Uppercase macro parameter.
- (cat): Likewise
-
- * search.c (SET_BINFO_ACCESS): Add parenthesis.
-
-2002-01-07 Jason Merrill <jason@redhat.com>
-
- * decl2.c (coerce_new_type): Downgrade error for size_t mismatch
- to pedwarn.
-
- PR c++/3536
- * method.c (make_thunk): If !flag_weak, give the thunk the
- function's linkage.
- (use_thunk): Here, too.
-
-2002-01-07 Graham Stott <grahams@redhat.com>
-
- * error.c: Update copyright date.
- (print_scope_operator): Add parenthesis.
- (print_left_paren): Likewise.
- (print_right_paren): Likewise.
- (print_left_bracket): Likewise.
- (print_right_bracket): Likewise.
- (print_template_argument_list_start): Likewise.
- (print_template_argument_list_end): Likewise.
- (print_non_consecutive_character): Likewise.
- (print_tree_identifier): Likewise.
- (print_identifier): Likewise.
- (NEXT_CODE): Uppercase macro parameter.
- (ident_fndecl): Delete unused.
- (GLOBAL_THING): Likewise.
-
-2002-01-06 Graham Stott <grahams@redhat.com>
-
- * cp-tree.h (VAR_OR_FUNCTION_DECL_CHECK): Add parenthesis.
- (VAR_FUNCTION_OR_PARM_DECL_CHECK): Likewise.
- (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK) Likewise.
- (RECORD_OR_UNION_TYPE_CHECK): Likewise.
- (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): Likewise.
- (C_IS_RESERVED_WORD): Uppercase macro parameter.
- (C_RID_YYCODE) Likewise.
- (ptrmem_cst): Use rtx.
- (LOCAL_BINDING_P): Add whitespace.
- (INHERITED_VALUE_BINDING_P): Likewise.
- (BINDING_SCOPE): Wrap long line.
- (BINDING_HAS_LEVEL_P): Remove parenthesis.
- (BINDING_VALUE): Wrap long line.
- (BINDING_TYPE): Whitespace.
- (IDENTIFIER_GLOBAL_VALUE): Add parenthesis.
- (SET_IDENTIFIER_GLOBAL_VALUE): Likewise.
- (IDENTIFIER_NAMESPACE_VALUE): Likewise.
- (SET_IDENTIFIER_NAMESPACE_VALUE: Likewise.
- (same_type_p): Uppercase macro parameters.
- (same_type_ignoring_top_level_qualifiers_p): Likewise.
- (OVL_FUNCTION): Wrap long line.
- (OVL_CHAIN): Whitespace.
- (OVL_CURRENT): Add parenthesis and whitespace.
- (OVL_NEXT): Whitespace.
- (OVL_USED): Likewise.
- (IDENTIFIER_TYPE_VALUE): Likewise.
- (REAL_IDENTIFIER_TYPE_VALUE): Remove parenthesis.
- (SET_IDENTIFIER_TYPE_VALUE): Add parenthesis and whitespace.
- (LANG_ID_FIELD): Whitespace.
- (SET_LANG_ID(NODE,VALUE,NAME): Likewise.
- (IDENTIFIER_LABEL_VALUE): Whitespace and wrap.
- (SET_IDENTIFIER_LABEL_VALUE): Whitespace.
- (IDENTIFIER_IMPLICIT_DECL): Whitespace and wrap.
- (SET_IDENTIFIER_IMPLICIT_DECL); Whitespace.
- (IDENTIFIER_ERROR_LOCUS): Whitespace and wrap.
- (SET_IDENTIFIER_ERROR_LOCUS); Whitespace.
- (IDENTIFIER_VIRTUAL_P): Likewise.
- (IDENTIFIER_OPNAME_P): Likewise.
- (IDENTIFIER_TYPENAME_P): Remove parenthesis.
- (C_TYPE_FIELDS_READONLY): Uppercase macro parameters.
- (C_SET_EXP_ORIGINAL_CODE): Likewise.
- (TYPE_ASSEMBLER_NAME_STRING): Wrap long line.
- (TYPE_ASSEMBLER_NAME_LENGTH): Likewise.
- (IS_AGGR_TYPE): Uppercase macro parameter.
- (CLASS_TYPE_P): Likewise.
- (IS_AGGR_TYPE_CODE): Uppercase macro parameter and parenthesis.
- (IS_AGGR_TYPE_2): Whitespace.
- (TAGGED_TYPE_P): Uppercase macro parameter.
- (TYPE_BUILT_IN): Whitespace.
- (TYPE_FOR_JAVA): Likewise.
- (FUNCTION_ARG_CHAIN): Remove parenthesis.
- (FUNCTION_FIRST_USER_PARMTYPE): Add parenthesis.
- (FUNCTION_FIRST_USER_PARAM): Likewise.
- (PROMOTES_TO_AGGR_TYPE): Whitespace.
- (DERIVED_FROM_P): Add parenthesis and wrap.
- (UNIQUELY_DERIVED_FROM_P): Likewise.
- (ACCESSIBLY_UNIQUELY_DERIVED_P): Likewise.
- (PUBLICLY_UNIQUELY_DERIVED_P): Likewise.
- (CLASSTYPE_USE_TEMPLATE): Whitespace.
- (CLASSTYPE_INLINE_FRIENDS): Remove parenthesis.
- (TYPE_GETS_DELETE): Add parenthesis.
- (TYPE_HAS_CONVERSION): Add parenthesis and wrap.
- (TYPE_HAS_ASSIGN_REF): Likewise,
- (TYPE_HAS_CONST_ASSIGN_REF): Likewise.
- (TYPE_HAS_INIT_REF): Likewise.
- (TYPE_HAS_CONST_INIT_REF): Likewise.
- (TYPE_BEING_DEFINED): Likewise.
- (TYPE_LANG_SPECIFIC): Likewise.
- (CLASSTYPE_RTTI): Likewise.
- (TYPE_OVERLOADS_CALL_EXPR): Likewise.
- (TYPE_OVERLOADS_ARRAY_REF): Likewise.
- (TYPE_OVERLOADS_ARROW): Likewise.
- (TYPE_USES_MULTIPLE_INHERITANCE): Likewise.
- (TYPE_USES_VIRTUAL_BASECLASSES): Add parenthesis.
- (CLASSTYPE_METHOD_VEC): Likewise.
- (CLASSTYPE_MARKED_N): Likewise.
- (CLASSTYPE_MARKED): Likewise.
- (CLASSTYPE_MARKED2): Likewise.
- (CLASSTYPE_MARKED3): Likewise.
- (CLASSTYPE_MARKED4): Likewise.
- (CLASSTYPE_MARKED5): Likewise.
- (CLASSTYPE_MARKED6): Likewise.
- (SET_CLASSTYPE_MARKED): Whitespace.
- (CLEAR_CLASSTYPE_MARKED): Likewise.
- (SET_CLASSTYPE_MARKED2): Likewise.
- (CLEAR_CLASSTYPE_MARKED2): Likewise.
- (SET_CLASSTYPE_MARKED3): Likewise.
- (CLEAR_CLASSTYPE_MARKED3): Likewise.
- (SET_CLASSTYPE_MARKED4): Likewise.
- (CLEAR_CLASSTYPE_MARKED4): Likewise.
- (SET_CLASSTYPE_MARKED5): Likewise.
- (CLEAR_CLASSTYPE_MARKED5): Likewise.
- (SET_CLASSTYPE_MARKED6): Likewise.
- (CLEAR_CLASSTYPE_MARKED6): Likewise.
- (CLASSTYPE_TAGS): Likewise.
- (CLASSTYPE_VSIZE): Likewise.
- (CLASSTYPE_VBASECLASSES): Likewise.
- (CANONICAL_BINFO): Add parenthesis.
- (CLASSTYPE_SIZE(NODE): Likewise.
- (CLASSTYPE_SIZE_UNIT): Likewise.
- (CLASSTYPE_ALIGN(NODE): Likewise.
- (CLASSTYPE_USER_ALIGN): Likewise.
- (TYPE_JAVA_INTERFACE): Likewise.
- (CLASSTYPE_PURE_VIRTUALS): Likewise.
- (CLASSTYPE_NEEDS_VIRTUAL_REINIT): Whitespace and wrap.
- (TYPE_HAS_DEFAULT_CONSTRUCTOR): Likewise.
- (CLASSTYPE_HAS_MUTABLE): Likewise.
- (CLASSTYPE_FRIEND_CLASSES): Likewise. Likewise.
- (CLASSTYPE_DECLARED_CLASS): Whitespace and wrap.
- (CLASSTYPE_READONLY_FIELDS_NEED_INIT): Likewise.
- (CLASSTYPE_REF_FIELDS_NEED_INIT): Likewise.
- (CLASSTYPE_INTERFACE_ONLY): Likewise.
- (CLASSTYPE_INTERFACE_KNOWN): Likewise.
- (CLASSTYPE_INTERFACE_UNKNOWN): Likewise.
- (SET_CLASSTYPE_INTERFACE_UNKNOWN_X): Likewise.
- (SET_CLASSTYPE_INTERFACE_UNKNOWN): Likewise.
- (SET_CLASSTYPE_INTERFACE_KNOWN): Likewise.
- (CLASSTYPE_DEBUG_REQUESTED): Whitespace and wrap.
- (BINFO_UNSHARED_MARKED): Whitespace.
- (BINFO_MARKED): Whitespace and wrap.
- (SET_BINFO_MARKED): Likewise.
- (CLEAR_BINFO_MARKED): Likewise.
- (BINFO_VTABLE_PATH_MARKED): Likewise.
- (SET_BINFO_VTABLE_PATH_MARKED): Likewise.
- (CLEAR_BINFO_VTABLE_PATH_MARKED): Likewise.
- (BINFO_SUBVTT_INDEX): Remove parenthesis.
- (BINFO_VPTR_INDEX): Likewise.
- (BINFO_PRIMARY_BASE_OF): Likewise,
- (CLASSTYPE_VFIELDS): Whitespace.
- (VF_DERIVED_VALUE): Wrap long line.
- (NAMESPACE_LEVEL): Whitespace.
- (CAN_HAVE_FULL_LANG_DECL_P): Remove parenthesis.
- (DEFARG_POINTER): Whitespace.
- (DECL_NEEDED_P): Remove parenthesis.
- (DECL_LANGUAGE): Whitespace.
- (SET_DECL_LANGUAGE): Add parenthesis.
- (DECL_CONSTRUCTOR_P): Whitespace and wrap.
- (DECL_OVERLOADED_OPERATOR_P): Remove parenthesis.
- (DECL_IN_AGGR_P): Whitespace.
- (DECL_FRIEND_P): Likewise.
- (DECL_BEFRIENDING_CLASSES): Likewise.
- (DECL_STATIC_FUNCTION_P): Whitespace and wrap.
- (DECL_NONCONVERTING_P): Whitespace.
- (DECL_PURE_VIRTUAL_P): Likewise.
- (DECL_NEEDS_FINAL_OVERRIDER_P): Likewise.
- (DECL_PENDING_INLINE_INFO): Whitespace.
- (DECL_SORTED_FIELDS): Likewise.
- (DECL_DEFERRED_FN): Likewise.
- (DECL_TEMPLATE_INFO): Likewise.
- (CLASSTYPE_TEMPLATE_INFO): Whitespace and wrap.
- (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO); Likewise.
- (SET_TYPE_TEMPLATE_INFO): Add parenthesis.
- (TMPL_ARGS_LEVEL): Likewise.
- (SET_TMPL_ARGS_LEVEL): Likewise.
- (INNERMOST_TEMPLATE_PARMS): Whitespace.
- (C_TYPEDEF_EXPLICITLY_SIGNED): Uppercase macro parameter.
- (INTEGRAL_CODE_P(CODE): Add parenthesis.
- (CP_INTEGRAL_TYPE_P): Remove parenthesis.
- (TYPE_HAS_CONSTRUCTOR): Whitespace.
- (TREE_HAS_CONSTRUCTOR): Likewise.
- (TYPE_HAS_DESTRUCTOR): Likewise.
- (TYPE_HAS_REAL_ASSIGN_REF): Likewise.
- (TYPE_HAS_COMPLEX_ASSIGN_REF): Likewise.
- (TYPE_HAS_ABSTRACT_ASSIGN_REF): Likewise.
- (TYPE_HAS_COMPLEX_INIT_REF): Likewise.
- (TYPE_HAS_NONTRIVIAL_DESTRUCTOR): Likewise.
- (TYPE_PTRMEMFUNC_P): Likewise.
- (TYPE_PTRMEMFUNC_FLAG): Likewise.
- (TYPE_GET_PTRMEMFUNC_TYPE): Likewise.
- (TYPE_SET_PTRMEMFUNC_TYPE): Likewise.
- (TYPE_PTRMEM_CLASS_TYPE): Remove parenthesis.
- (TYPE_PTRMEM_POINTED_TO_TYPE): Likewise.
- (DECL_ACCESS): Whitespace.
- (DECL_GLOBAL_CTOR_P): Remove parenthesis.
- (DECL_GLOBAL_DTOR_P): Likewise.
- (GLOBAL_INIT_PRIORITY): Likewise.
- (DECL_TEMPLATE_PARMS): Likewise.
- (DECL_TEMPLATE_RESULT): Likewise.
- (DECL_TEMPLATE_INSTANTIATIONS): Likewise.
- (DECL_TEMPLATE_SPECIALIZATIONS): Likewise.
- (DECL_IMPLICIT_TYPEDEF_P): Remove parenthesis.
- (SET_DECL_IMPLICIT_TYPEDEF_P): Likewise.
- (PRIMARY_TEMPLATE_P): Add parenthesis.
- (DECL_USE_TEMPLATE): Whitespace.
- (CLASSTYPE_IMPLICIT_INSTANTIATION): Likewise.
- (SET_CLASSTYPE_IMPLICIT_INSTANTIATION): Likewise.
- (CLASSTYPE_EXPLICIT_INSTANTIATION): Likewise.
- (SET_CLASSTYPE_EXPLICIT_INSTANTIATION): Likewise.
- (CALL_DECLARATOR_PARMS): Remove parenthesis.
- (CALL_DECLARATOR_QUALS): Likewise.
- (CALL_DECLARATOR_EXCEPTION_SPEC): Likewise.
- (TEMP_NAME_P): Wrap.
- (VFIELD_NAME_P): Likewise.
- (B_SET): Uppercase macro parameters and add parenthesis.
- (B_CLR): Likewise.
- (B_TST): Likewise.
- (LOOKUP_NAMESPACES_ONLY): Uppercase macro parameters.
- (LOOKUP_TYPES_ONLY): Uppercase macro parameters.
- (LOOKUP_QUALIFIERS_ONLY): Uppercase macro parameters.
- (same_or_base_type_p): Likewise.
- (cp_deprecated): Likewise.
-
-2002-01-05 Richard Henderson <rth@redhat.com>
-
- * semantics.c (expand_body): Revert last change.
-
-2002-01-04 Jason Merrill <jason@redhat.com>
-
- PR c++/4122
- * class.c (update_vtable_entry_for_fn): Set delta to zero for a
- lost primary.
-
- * class.c (build_vtbl_initializer): Check for a lost primary
- before calculating the vtable entry to throw away.
-
-2002-01-02 Jason Merrill <jason@redhat.com>
-
- * semantics.c (expand_body): Call outlining_inline_function when
- emitting an inline function out of line.
-
-2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/5116, c++/764 reversion
- * call.c (build_new_op): Revert the instantiations. They are
- incorrect.
-
-2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/5089
- * decl2.c (reparse_absdcl_as_casts): Don't warn about casts to void.
-
-2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/3716
- * pt.c (tsubst_aggr_type): Move pmf handling into tsubst.
- (tsubst, case POINTER_TYPE): Handle pmfs here.
- (tsubst, case OFFSET_TYPE): Check it is not an offset to
- reference. If it is offset to FUNCTION_TYPE, create a METHOD_TYPE.
-
-2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/35
- * cp-tree.h (DECL_LANG_FLAG_0): Used for PARM_DECL too.
- (DECL_TEMPLATE_PARM_P): A PARM_DECL might be one too.
- * pt.c (process_template_parm): SET_DECL_TEMPLATE_PARM_P on the
- PARM_DECL.
- (tsubst_template_parms): Break up loop statements.
- (tsubst_decl, case PARM_DECL): Copy DECL_TEMPLATE_PARM_P. Template
- parm PARM_DECLs don't get promoted.
-
-2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/5123
- * typeck.c (build_component_ref): Cope with a TEMPLATE_ID_EXPR.
- (build_x_function_call): Cope with a COMPONENT_REF containing a
- TEMPLATE_ID_EXPR.
-
-2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/5213
- * pt.c (convert_template_argument): Be more careful determining
- when RECORD_TYPE templates are or are not templates.
-
-2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/775
- * cp-tree.h (handle_class_head): Adjust prototype.
- * decl2.c (handle_class_head): Add DEFN_P and NEW_TYPE_P
- parameters. Use for all class heads.
- * parse.y (named_class_head_sans_basetype, named_class_head,
- named_complex_class_head_sans_basetype,
- named_class_head_sans_basetype_defn,
- unnamed_class_head): Remove.
- (class_head, class_head_apparent_template): Recognize class heads
- (class_head_decl, class_head_defn): New reductions. Process class
- heads.
- (structsp): Adjust class definition and class declaration
- reductions.
- (maybe_base_class_list): Give diagnostic on empty list.
-
-2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/4379
- * typeck.c (build_x_unary_op): Don't destroy the OFFSET_REF on a
- single non-static member.
- (unary_complex_lvalue): If it cannot be a pointer to member, don't
- make it so. Check it is not pointer to reference.
-
-2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/5132
- * decl2.c (reparse_absdcl_as_casts): Don't digest_init if we
- are processing a template decl.
-
-2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/5116, c++/764
- * call.c (build_new_op): Make sure template class operands are
- instantiated. Simplify arglist construction.
-
-2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (build_user_type_conversion_1): Use my_friendly_assert
- rather than if ... abort.
- * cvt.c (convert_to_reference): Likewise.
- * semantics.c (setup_vtbl_ptr): Likewise.
- * pt.c (lookup_template_class): Comment typo.
-
-2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/5125
- * pt.c (push_template_decl_real): Make sure DECL has
- DECL_LANG_SPECIFIC.
-
-2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/335
- * init.c (resolve_offset_ref): Copy cv qualifiers of this pointer
- for non-reference fields.
- * typeck.c (require_complete_type): Use resolve_offset_ref).
-
-2001-12-26 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/196
- * parse.y (bad_parm): Better diagnostic when given a SCOPE_REF.
-
-2001-12-24 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/160
- * typeck.c (build_modify_expr): Remove old unreachable code & tidy
- up. Don't stabilize_references when initializing a reference.
-
-2001-12-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * decl2.c (lang_f_options): Const-ify.
-
-2001-12-20 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * config-lang.in (diff_excludes): Remove.
-
-2001-12-19 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/90
- * typeck.c (build_function_call_real): Use original function
- expression for errors.
-
-2001-12-18 Jason Merrill <jason@redhat.com>
-
- PR c++/3242
- * class.c (add_method): Do compare 'this' quals when trying to match a
- used function. Don't defer to another used function.
-
-2001-12-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (instantiate_clone): Remove, fold into ...
- (instantiate_template): ... here. Simplify by removing mutual
- recursion.
- * typeck2.c (build_m_component_ref): Don't cv qualify the function
- pointed to by a pointer to function.
- * class.c (delete_duplicate_fields_1): Typo.
-
-2001-12-18 Jason Merrill <jason@redhat.com>
-
- C++ ABI change: destroy value arguments in caller.
- * semantics.c (genrtl_start_function, genrtl_finish_function): Don't
- create an extra binding level for the parameters.
- * decl.c (store_parm_decls): Don't do parameter cleanups.
-
-2001-12-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (build_new_method_call): Use '%#V'.
- * error.c (cv_to_string): Use V parameter to determine padding.
-
-2001-12-18 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * call.c, decl2.c, init.c: Use "built-in" and "bit-field"
- spellings in messages.
-
-2001-12-17 Zack Weinberg <zack@codesourcery.com>
-
- * cp-tree.h: Delete #defines for cp_error, cp_warning,
- cp_pedwarn, and cp_compiler_error.
- * call.c, class.c, cp-tree.h, cvt.c, decl.c, decl2.c, error.c,
- except.c, friend.c, init.c, lex.c, method.c, parse.y, pt.c,
- rtti.c, search.c, semantics.c, spew.c, tree.c, typeck.c,
- typeck2.c: Change calls to the above macros to use their
- language-independent equivalents: error, warning, pedwarn, and
- internal_error respectively.
-
-2001-12-16 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * decl2.c (finish_file): Remove back_end_hook.
-
-2001-12-16 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * ChangeLog.1, ChangeLog.2, ChangeLog, NEWS, call.c, class.c,
- cp-tree.h, decl.c, decl2.c, except.c, operators.def, optimize.c,
- pt.c, rtti.c, semantics.c, typeck.c: Fix spelling errors.
-
-2001-12-15 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * lang-options.h: Use American spelling in messages.
-
-2001-12-13 Jason Merrill <jason@redhat.com>
-
- * Make-lang.in (parse.h): Separate rule, just depend on parse.c.
-
- Use cleanups to run base and member destructors.
- * init.c (push_base_cleanups): New function, split out from...
- (build_delete): ...here. Lose !TYPE_HAS_DESTRUCTOR code.
- * decl.c (finish_destructor_body): Move vbase destruction code to
- push_base_cleanups.
- (begin_function_body, finish_function_body): New fns.
- (finish_function): Move [cd]tor handling and call_poplevel to
- finish_function_body.
- (pushdecl): Skip the new level.
- * semantics.c (genrtl_try_block): Don't call end_protect_partials.
- (setup_vtbl_ptr): Call push_base_cleanups.
- * method.c (synthesize_method): Call {begin,end}_function_body.
- * pt.c (tsubst_expr): Handle COMPOUND_STMT_BODY_BLOCK.
- * cp-tree.h: Declare new fns.
- * parse.y (function_body, .begin_function_body): New nonterminals.
- (fndef, pending_inline, function_try_block): Use function_body.
- (ctor_initializer_opt, function_try_block): No longer has a value.
- (base_init): Remove .set_base_init token.
- (.set_base_init, compstmt_or_error): Remove.
- * Make-lang.in (parse.c): Expect two fewer s/r conflicts.
-
- * optimize.c (maybe_clone_body): Fix parameter updating.
-
-2001-12-12 Jason Merrill <jason@redhat.com>
-
- * decl.c (store_parm_decls): Remove parms_have_cleanups cruft.
- * semantics.c (genrtl_start_function): Don't pass
- parms_have_cleanups or push an extra binding level.
- (genrtl_finish_function): Lose cleanup_label cruft.
-
- * cp-tree.h (struct cp_language_function): Remove x_ctor_label.
- (ctor_label): Remove.
- * semantics.c (finish_return_stmt): Lose ctor_label support.
- * decl.c (finish_constructor_body, mark_lang_function): Likewise.
- * typeck.c (check_return_expr): Check DECL_DESTRUCTOR_P, not
- dtor_label.
-
- * call.c (build_new_method_call): Let resolves_to_fixed_type_p
- check for [cd]tors.
- * class.c (fixed_type_or_null, case INDIRECT_REF): Fix.
-
- * decl.c (finish_function): Check VMS_TARGET, not VMS.
-
- * decl.c (start_cleanup_fn): Remove redundant pushlevel.
- (end_cleanup_fn): And poplevel.
-
- * semantics.c (setup_vtbl_ptr): Always build a CTOR_INITIALIZER
- if we're in a template.
-
-2001-12-12 Jakub Jelinek <jakub@redhat.com>
-
- * cp-tree.h (DESTRUCTOR_DECL_PREFIX, DESTRUCTOR_NAME_P,
- ANON_PARMNAME_FORMAT, ANON_PARMNAME_P, DESTRUCTOR_NAME_FORMAT,
- THIS_NAME_P): Delete.
- * spew.c (read_process_identifier): Remove DESTRUCTOR_NAME_P,
- THIS_NAME_P and ANON_PARMNAME_P tests from warning about clash
- with internal naming scheme.
- * error.c (dump_decl): Remove DESTRUCTOR_NAME_P use.
-
-2001-12-12 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (grokdeclarator): Deprecated implicit typename use.
-
-2001-12-11 Nathan Sidwell <nathan@codesourcery.com>
-
- PR g++/51
- * parse.y (frob_specs): Indicate it is a language linkage which
- contained the extern.
- * decl.c (grokdeclarator): Allow extern language linkage with
- other specifiers.
-
-2001-12-10 Nathan Sidwell <nathan@codesourcery.com>
-
- PR g++/72
- * decl.c (add_binding): Don't reject duplicate typedefs involving
- template parameters.
-
-2001-12-10 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * parse.y, semantics.c: Similarly.
-
-2001-12-09 Nathan Sidwell <nathan@codesourcery.com>
-
- PR g++/87
- * cp-tree.h (DECL_COPY_CONSTRUCTOR_P): Use copy_fn_p.
- (copy_args_p): Rename to ...
- (copy_fn_p): ... here.
- (grok_special_member_properties): New function.
- (grok_op_properties): Lose VIRTUALP parameter.
- (copy_assignment_arg_p): Remove.
- * call.c (build_over_call): Use copy_fn_p.
- * decl.c (grokfndecl): Reformat. Adjust call to
- grok_op_properties.
- (copy_args_p): Rename to ...
- (copy_fn_p): ... here. Reject template functions. Check for pass
- by value.
- (grok_special_member_properties): Remember special functions.
- (grok_ctor_properties): Don't remember them here, just check.
- (grok_op_properties): Likewise.
- (start_method): Call grok_special_member_properties.
- * decl2.c (grokfield): Likewise.
- (copy_assignment_arg_p): Remove.
- (grok_function_init): Don't remember abstract assignment here.
- * pt.c (instantiate_class_template): Call
- grok_special_member_properties.
- (tsubst_decl): Adjust grok_op_properties call.
-
-2001-12-08 Aldy Hernandez <aldyh@redhat.com>
-
- * lex.c (rid_to_yy): Add RID_CHOOSE_EXPR and
- RID_TYPES_COMPATIBLE_P.
-
-2001-12-08 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * semantics.c (simplify_aggr_init_exprs_r): Add DIRECT_BIND flag in
- call to build_aggr_init.
- * cp-tree.h (DIRECT_BIND): Document new use of DIRECT_BIND.
-
-2001-12-08 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * parse.y: Replace uses of the string non-terminal with STRING.
- Don't perform string concatentaion here.
- (string): Remove non-terminal.
- * semantics.c (finish_asm_stmt): Don't concatenate strings here.
-
-2001-12-05 Jason Merrill <jason@redhat.com>
-
- * cp-lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING): Define.
- (LANG_HOOKS_TREE_INLINING_END_INLINING): Define.
- * tree.c (cp_start_inlining, cp_end_inlining): New fns.
- * pt.c (push_tinst_level): No longer static.
- * cp-tree.h: Declare them.
-
- * init.c (resolve_offset_ref): Don't check access for the base
- conversion to access a FIELD_DECL.
-
- * cp-tree.h (TYPE_REFFN_P): New macro.
- * decl.c (bad_specifiers): Check it, too.
-
- * rtti.c (create_pseudo_type_info): Set CLASSTYPE_INTERFACE_ONLY
- on the __*_type_info type if we haven't seen a definition.
-
-2001-12-05 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * decl.c: Include c-common.h.
- (shadow_warning): Move to c-common.c.
-
-Wed Dec 5 17:00:49 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * decl.c (duplicate_decls): Don't copy DECL_NO_CHECK_MEMORY_USAGE.
-
-2001-12-04 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (end_template_parm_list): Clear TREE_CHAIN of each parm.
-
-2001-12-04 Nathan Sidwell <nathan@codesourcery.com>
-
- PR g++/164
- * init.c (sort_base_init): Allow binfos to be directly specified.
- * method.c (do_build_copy_constructor): Explicitly convert to the
- base instance.
- (do_build_assign_ref): Likewise.
-
-2001-12-03 Hans-Peter Nilsson <hp@bitrange.com>
-
- * decl.c (xref_basetypes): Don't use C99 construct in tag_code
- declaration and initialization.
-
-2001-12-03 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * typeck2.c: Remove leading capital from diagnostic messages, as
- per GNU coding standards.
-
-2001-12-03 Mumit Khan <khan@nanotech.wisc.edu>
-
- PR c++/3394
- * decl.c (xref_basetypes): Handle attributes between
- 'class' and name.
-
-2001-12-03 Nathan Sidwell <nathan@codesourcery.com>
-
- PR g++/3381
- * parse.y (named_complex_class_head_sans_basetype): Add new
- reduction.
- * Make-lang.in (parse.c): Adjust expected conflict count.
-
-2001-12-03 Jason Merrill <jason@redhat.com>
-
- * class.c (finish_vtbls): Fill in BINFO_VPTR_FIELD in the
- immediate binfos for our virtual bases.
-
-2001-12-02 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * call.c (build_java_interface_fn_ref): Similarly.
- * except.c (is_admissible_throw_operand): Similarly.
- * init.c (build_java_class_ref): Similarly.
- * xref.c (open_xref_file): Similarly.
-
-2001-12-01 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * class.c (finish_struct): Remove trailing periods from messages.
- * decl.c (check_tag_decl): Similarly.
- * lex.c (cxx_set_yydebug): Similarly.
- * typeck2.c (friendly_abort): Similarly.
-
-2001-11-29 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/3048
- * cp-tree.h (ovl_member): Remove.
- * decl2.c (merge_functions): Handle extern "C" functions
- specially.
- * tree.c (ovl_member): Remove.
-
-2001-11-29 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/4842
- * class.c (get_basefndecls): Take an IDENTIFIER_NODE, not a
- FUNCTION_DECL, as input.
- (mark_overriders): Remove.
- (warn_hidden): Rework for the new ABI.
-
-2001-11-29 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/3471
- * call.c (convert_like_real): Do not build additional temporaries
- for rvalues of class type.
-
-2001-11-28 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (UNIQUELY_DERIVED_FROM_P): Use lookup base.
- (ACCESSIBLY_UNIQUELY_DERIVED_FROM_P): Likewise.
- (PUBLICLY_UNIQUELY_DERIVED_FROM_P: Likewise.
- (DERIVED_FROM_P): Likewise.
- (enum base_access): Renumber, add ba_quiet bit mask.
- (get_binfo): Remove.
- (get_base_distance): Remove.
- (binfo_value): Remove.
- (ACCESSIBLY_DERIVED_FROM_P): Remove.
- * call.c (standard_conversion): Use lookup_base.
- * class.c (strictly_overrides): Likewise.
- (layout_virtual_bases): Likewise.
- (warn_about_ambiguous_direct_bases): Likewise.
- (is_base_of_enclosing_class): Likewise.
- (add_vcall_offset_vtbl_entries_1): Likewise.
- * cvt.c (build_up_reference): Adjust comment.
- * init.c (build_member_call): Reformat.
- * search.c (get_binfo): Remove.
- (get_base_distance_recursive): Remove.
- (get_base_distance): Remove.
- (lookup_base_r): Tweak.
- (lookup_base): Add ba_quiet control. Complete the types here.
- (covariant_return_p): Use lookup_base.
- * tree.c (binfo_value): Remove.
- (maybe_dummy_object): Use lookup_base.
- * typeck.c (build_static_cast): Use lookup_base.
- (get_delta_difference): Likewise.
- * typeck2.c (binfo_or_else): Use lookup_base.
- (build_scoped_ref): Add back error_mark_check.
- (build_m_component_ref): Use lookup_base.
-
-2001-11-29 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * Make-lang.in (c++.generated-manpages): New dummy target.
-
-Tue Nov 27 09:03:47 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * Make-lang.in (cp-lang.o): Depends on c-common.h.
- * cp-lang.c (c-common.h): Include.
- (LANG_HOOKS_EXPAND_CONSTANT, LANG_HOOKS_SAFE_FROM_P): New hooks.
- * decl.c (cxx_init_decl_processing): Don't set lang_safe_from_p.
- * expr.c (init_cplus_expand): Don't set lang_expand_constant.
-
-2001-11-26 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * decl2.c (c_language): Move to c-common.c.
- * lex.c (cxx_post_options, cxx_init_options): Use c-common.c
- functions.
- (cxx_init): Update.
-
-2001-11-26 Jason Merrill <jason@redhat.com>
-
- * call.c (joust): Remove COND_EXPR hack.
-
-2001-11-25 Aldy Hernandez <aldyh@redhat.com>
-
- * search.c (lookup_base_r): Declare bk in variable declaration
- space.
-
-2001-11-25 Nathan Sidwell <nathan@codesourcery.com>
-
- PR g++/3145
- * class.c (build_vbase_pointer): Remove.
- (build_vbase_path): Remove.
- (build_base_path): New function.
- * cp-tree.h (base_access, base_kind): New enumerations.
- (build_base_path): Declare.
- (convert_pointer_to_real): Remove.
- (convert_pointer_to): Remove.
- (lookup_base): Declare.
- (convert_pointer_to_vbase): Remove.
- * call.c (build_scoped_method_call): Use lookup_base &
- build_base_path instead of convert_pointer_to_real,
- get_base_distance & get_binfo.
- (build_over_call): Likewise.
- * cvt.c (cp_convert_to_pointer): Likewise.
- (convert_to_pointer_force): Likewise.
- (build_up_reference): Likewise.
- (convert_pointer_to_real): Remove.
- (convert_pointer_to): Remove.
- * init.c (dfs_initialize_vtbl_ptrs): Use build_base_path
- instead of convert_pointer_to_vbase & build_vbase_path.
- (emit_base_init): Use build_base_path instead of
- convert_pointer_to_real.
- (expand_virtual_init): Lose unrequired conversions.
- (resolve_offset_ref): Use lookup_base and build_base_path
- instead of convert_pointer_to.
- * rtti.c (build_dynamic_cast_1): Use lookup_base &
- build_base_path instead of get_base_distance & build_vbase_path.
- * search.c (get_vbase_1): Remove.
- (get_vbase): Remove.
- (convert_pointer_to_vbase): Remove.
- (lookup_base_r): New function.
- (lookup_base): New function.
- * typeck.c (require_complete_type): Use lookup_base &
- build_base_path instead of convert_pointer_to.
- (build_component_ref): Likewise.
- (build_x_function_call): Likewise.
- (get_member_function_from_ptrfunc): Likewise.
- (build_component_addr): Likewise.
- * typeck2.c (build_scoped_ref): Likewise.
-
-2001-11-22 Bryce McKinlay <bryce@waitaki.otago.ac.nz>
-
- * cp-tree.h (CP_TYPE_QUALS): Removed.
- * decl.c (cxx_init_decl_processing): Don't set lang_dump_tree.
- * cp-lang.c: Set LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN and
- LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN.
- * dump.c (cp_dump_tree): Use void* dump_info argument to match
- lang-hooks prototype.
- * call.c, cp-tree.h, cvt.c, decl.c, init.c, mangle.c, method.c, pt.c,
- rtti.c, semantics.c, tree.c, typeck.c, typeck2.c: All references to
- CP_TYPE_QUALS changed to cp_type_quals.
- * Make-lang.in: References to c-dump.h changed to tree-dump.h.
- (CXX_C_OBJS): Remove c-dump.o.
-
-2001-11-21 Mark Mitchell <mark@codesourcery.com>
-
- PR c++/3637
- * pt.c (lookup_template_class): Ensure that all specializations
- are registered on the list corresponding to the most general
- template.
-
-2001-11-20 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (non_reference): Add documentation.
- (convert_class_to_reference): Do not strip reference types
- from conversion operators.
- (maybe_handle_ref_bind): Simplify.
- (compare_ics): Correct handling of references.
-
-2001-11-19 John Wilkinson <johnw@research.att.com>
-
- * dump.c (dump_op): New function.
- (cp_dump_tree): Dump CLASSTYPE_TEMPLATE_SPECIALIZATION. Use
- dump_op. Dump DECL_MUTABLE, access and staticness for VAR_DECLs.
- DECL_PURE_VIRTUAL_P, DECL_VIRTUAL_P,
-
-2001-11-19 Mark Mitchell <mark@codesourcery.com>
-
- PR4629
- * semantics.c (finish_sizeof): Make sure that expression created
- while processing a template do not have a type.
- (finish_alignof): Likewise.
- * typeck.c (c_sizeof): Likewise.
- (expr_sizeof): Likewise.
-
-2001-11-18 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * lex.c (cxx_finish): Call c_common_finish.
- (finish_parse): Remove.
-
-2001-11-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * decl.c (create_array_type_for_decl): Check if NAME is NULL_TREE
- when displaying error message about missing array bounds.
-
-2001-11-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * mangle.c (write_expression): Handle CAST_EXPR, STATIC_CAST_EXPR,
- CONST_CAST_EXPR.
- * operators.def: Add CAST_EXPR, STATIC_CAST_EXPR, CONST_CAST_EXPR.
-
-2001-11-16 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-tree.h (print_class_statistics): Restore.
-
-2001-11-15 Jason Merrill <jason@redhat.com>
-
- * method.c (use_thunk): Don't emit debugging information for thunks.
-
- * parse.y: Add ... IDENTIFIER SCOPE and ... PTYPENAME SCOPE expansions.
- * decl.c (make_typename_type): Handle getting a class template.
- * search.c (lookup_field_r): A class template is good enough for
- want_type.
-
- * call.c (convert_like_real): Only use cp_convert for the bad part.
- (standard_conversion): Also allow bad int->enum.
- * typeck.c (ptr_reasonably_similar): Also allow functions to
- interconvert. Pointers to same-size integers are reasonably
- similar.
-
- * cvt.c (convert_to_void): If we build a new COND_EXPR, always
- give it void type.
-
-2001-11-15 Nathan Sidwell <nathan@codesourcery.com>
-
- PR g++/3154
- * init.c (sort_base_init): Remove unreachable code.
- (expand_member_init): Adjust comment to reflect reality. Simplify
- and remove unreachable code.
-
-2001-11-15 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-tree.h (init_reswords, cxx_init_decl_processing): New.
- (cxx_init): Update prototype.
- * decl.c (init_decl_processing): Rename. Move null node init
- to its creation time.
- * lex.c (cxx_init_options): Update.
- (cxx_init): Combine with old init_parse; also call
- cxx_init_decl_processing.
-
-2001-11-14 Richard Sandiford <rsandifo@redhat.com>
-
- * decl.c (check_initializer): Try to complete the type of an
- array element before checking whether it's complete. Don't
- complain about arrays with complete element types but an
- unknown size.
- (cp_finish_decl): Build the hierarchical constructor before
- calling maybe_deduce_size_from_array_init.
-
-2001-11-14 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * Make-lang.in: Change all uses of $(manext) to $(man1ext).
-
-2001-11-13 Nathan Sidwell <nathan@codesourcery.com>
-
- PR g++/4206
- * parse.y (already_scoped_stmt): Remove.
- (simple_stmt, WHILE & FOR): Use implicitly_scoped_stmt.
-
-2001-11-12 H.J. Lu <hjl@gnu.org>
-
- * cvt.c (ocp_convert): Don't warn the address of a weak
- function is always `true'.
-
-2001-11-09 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_PRINT_DECL, LANG_HOOKS_PRINT_TYPE,
- LANG_HOOKS_PRINT_STATISTICS, LANG_HOOKS_PRINT_XNODE,
- LANG_HOOKS_PRINT_IDENTIFIER, LANG_HOOKS_SET_YYDEBUG): Override.
- * cp-tree.h (print_class_statistics): Remove.
- (cxx_print_statistics, cxx_print_xnode, cxx_print_decl, cxx_print_type,
- cxx_print_identifier, cxx_set_yydebug): New.
- * lex.c (set_yydebug): Rename c_set_yydebug.
- * ptree.c (print_lang_decl, print_lang_type, print_lang_identifier,
- lang_print_xnode): Rename.
- * tree.c (print_lang_statistics): Rename.
-
-2001-11-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * class.c (dump_array): Fix format specifier warning.
-
-2001-11-09 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-lang.c (LANG_HOOKS_NAME): Override.
- (struct lang_hooks): Constify.
- * lex.c (cxx_init_options): Update.
- (lang_identify): Remove.
- * parse.y (language_string): Remove.
-
-2001-11-08 Andreas Franck <afranck@gmx.de>
-
- * Make-lang.in (CXX_INSTALL_NAME, GXX_CROSS_NAME,
- DEMANGLER_CROSS_NAME): Handle program_transform_name the way
- suggested by autoconf.
- (GXX_TARGET_INSTALL_NAME, CXX_TARGET_INSTALL_NAME): Define.
- (c++.install-common): Use the transformed target alias names.
-
-2001-11-06 Neil Booth <neil@cat.daikokuya.demon.co.uk>
-
- * Make-lang.in: Update.
- * cp-lang.c: Include langhooks-def.h.
-
-2001-11-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (tsubst_copy): Call tsubst for TYPEOF_EXPR.
-
-2001-11-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * lex.c (copy_lang_type): Add static prototype.
-
-2001-11-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (unify): Handle SCOPE_REF.
-
-2001-11-01 Jakub Jelinek <jakub@redhat.com>
-
- * tree.c (cp_copy_res_decl_for_inlining): Adjust
- DECL_ABSTRACT_ORIGIN for the return variable.
-
-2001-10-31 Zack Weinberg <zack@codesourcery.com>
-
- * Make-lang.in: Replace $(INTL_TARGETS) with po-generated.
-
-2001-10-28 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * ChangeLog.1, ChangeLog.2, ChangeLog, class.c, decl2.c, search.c,
- semantics.c, spew.c: Fix spelling errors.
-
-2001-10-27 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * decl2.c (validate_nonmember_using_decl): Handle NAMESPACE_DECL.
-
-2001-10-25 Zack Weinberg <zack@codesourcery.com>
-
- * cp-lang.c: Redefine LANG_HOOKS_CLEAR_BINDING_STACK to
- pop_everything.
-
-Tue Oct 23 14:00:20 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * cp-lang.c (cxx_get_alias_set): New function.
- Point LANG_HOOKS_GET_ALIAS_SET to it.
-
-2001-10-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * cp-tree.def (UNBOUND_CLASS_TEMPLATE): New tree node.
- * cp-tree.h (make_unbound_class_template): Prototype new function.
- * decl.c (make_unbound_class_template): New function.
- * decl2.c (arg_assoc_template_arg): Handle UNBOUND_CLASS_TEMPLATE.
- * error.c (dump_type): Likewise.
- * mangle.c (write_type): Likewise.
- * parse.y (template_parm): Likewise.
- (template_argument): Use make_unbound_class_template.
- * pt.c (convert_template_argument): Handle UNBOUND_CLASS_TEMPLATE.
- (tsubst): Likewise.
- (tsubst_copy): Likewise.
- (unify): Likewise.
- * tree.c (walk_tree): Likewise.
- * typeck.c (comptypes): Likewise.
-
-2001-10-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * xref.c (GNU_xref_member): Use safe-ctype macros and/or fold
- extra calls into fewer ones.
-
-2001-10-18 Alexandre Oliva <aoliva@redhat.com>
-
- * decl.c (duplicate_decls): Propagate DECL_UNINLINABLE.
- Warn when merging inline with attribute noinline.
- (start_decl, start_function): Warn if inline and attribute
- noinline appear in the same declaration.
-
-2001-10-16 H.J. Lu <hjl@gnu.org>
-
- * cp-tree.h (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): Defined
- for tree checking disabled.
-
-2001-10-16 Hans-Peter Nilsson <hp@axis.com>
-
- * cp-tree.h (VFIELD_NAME_FORMAT) [NO_DOLLAR_IN_LABEL &&
- NO_DOT_IN_LABEL]: Adjust to match VFIELD_NAME.
-
-2001-10-15 Richard Sandiford <rsandifo@redhat.com>
-
- * pt.c (UNIFY_ALLOW_MAX_CORRECTION): Define.
- (unify): Only handle MINUS_EXPR specially if the above flag is set
- and the subtracted constant is 1. Clear the flag on recursive calls.
- Set it when unifying the maximum value in an INTEGER_TYPE's range.
-
-2001-10-15 Richard Sandiford <rsandifo@redhat.com>
-
- * decl.c (bad_specifiers): Don't allow exception specifications
- on any typedefs.
-
-2001-10-14 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp/lex.c (init_cp_pragma): Similarly.
-
-2001-10-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (lookup_template_class): Build complete template arguments
- for BOUND_TEMPLATE_TEMPLATE_PARM.
-
-2001-10-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * cp-tree.h (TYPE_BINFO): Update comment.
- (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): New macro.
- (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Use template_info.
- (TYPENAME_TYPE_FULLNAME): Use TYPE_FIELDS.
- (copy_type): Prototype new function.
- * lex.c (copy_lang_decl): Gather tree node statistics.
- (copy_lang_type): New function.
- (copy_type): Likewise.
- (cp_make_lang_type): Create lang_type for
- BOUND_TEMPLATE_TEMPLATE_PARM. Set TYPE_BINFO for TYPENAME_TYPE
- and BOUND_TEMPLATE_TEMPLATE_PARM.
- * pt.c (tsubst): Use copy_type instead of copy_node.
- * search.c (lookup_field_1): Ignore TYPENAME_TYPE.
-
-2001-10-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (determine_specialization): Ignore functions without
- DECL_TEMPLATE_INFO.
-
-2001-10-12 Nathan Sidwell <nathan@codesourcery.com>
-
- PR g++/4476
- * typeck2.c (abstract_virtuals_error): Ignore incomplete classes.
-
-2001-10-11 Jason Merrill <jason_merrill@redhat.com>
-
- * typeck2.c (store_init_value): Don't re-digest a bracketed
- initializer.
-
- * class.c (finish_struct_anon): Use TYPE_ANONYMOUS_P instead of
- ANON_AGGR_TYPE_P.
-
-2001-10-11 Richard Henderson <rth@redhat.com>
-
- * class.c (build_vtable_entry_ref): Create a VTABLE_REF instead
- of an asm statement.
- (build_vtbl_ref_1): Split out from build_vtbl_ref.
- (build_vfn_ref): Use it to handle vtable descriptors before
- calling build_vtable_entry_ref.
- * decl2.c (output_vtable_inherit): Use assemble_vtable_inherit.
-
-2001-10-10 Richard Henderson <rth@redhat.com>
-
- * parse.y (asm_operand): Allow named operands.
- * semantics.c (finish_asm_stmt): Tweek for changed location
- of the operand constrant.
-
-2001-10-09 Jason Merrill <jason_merrill@redhat.com>
-
- * call.c (standard_conversion): Add bad conversion between
- integers and pointers.
- (convert_like_real): Don't use convert_for_initialization for bad
- conversions; complain here and use cp_convert.
- (build_over_call): Don't handle bad conversions specially.
- (perform_implicit_conversion): Allow bad conversions.
- (can_convert_arg_bad): New fn.
- * cp-tree.h: Declare it.
- * typeck.c (convert_for_assignment): Use it.
- (ptr_reasonably_similar): Any target type is similar to void.
-
-2001-10-08 Alexandre Oliva <aoliva@redhat.com>
-
- * Make-lang.in (CXX_OBJS): Added cp-lang.o.
- (cp/cp-lang.o): New rule.
- * cp-tree.h: Declare hooks.
- * tree.c: Make hooks non-static.
- (init_tree): Don't initialize hooks here.
- * lex.c: Likewise. Move definition of lang_hooks to...
- * cp-lang.c: ... new file.
-
-2001-10-08 Richard Henderson <rth@redhat.com>
-
- * cp-tree.h (struct lang_decl_flags): Remove declared_inline.
- (DECL_DECLARED_INLINE_P): Use the bit in struct c_lang_decl.
-
-2001-10-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * class.c (build_vtable_entry_ref): Const-ify.
- * decl.c (predefined_identifier,
- initialize_predefined_identifiers): Likewise.
- * init.c (build_new_1): Likewise.
- * lex.c (cplus_tree_code_type, cplus_tree_code_length, resword):
- Likewise.
-
-2001-10-05 Alexandre Oliva <aoliva@redhat.com>
-
- * optimize.c (struct inline_data): Moved to ../tree-inline.c.
- (INSNS_PER_STMT): Likewise.
- (remap_decl, remap_block, copy_scopy_stmt, copy_body_r): Likewise.
- (copy_body, initialize_inlined_parameters): Likewise.
- (declare_return_variable, inlinable_function_p): Likewise.
- (expand_call_inline, expand_calls_inline): Likewise.
- (optimize_inline_calls, clone_body): Likewise.
- * tree.c (walk_tree): Moved to ../tree-inline.c.
- (walk_tree_without_duplicates): Likewise.
- (copy_tree_r, remap_save_expr): Likewise.
-
-2001-10-04 Alexandre Oliva <aoliva@redhat.com>
-
- * Make-lang.in (cp/decl.o, cp/tree.o): Depend on tree-inline.h.
- (cp/pt.o, cp/semantics.o, cp/optimize.o): Likewise.
- * cp-tree.h (lang_decl): Moved inlined_fns to tree_decl.
- (TREE_READONLY_DECL_P, DECL_INLINED_FNS): Moved to ../tree.h.
- (flag_inline_trees): Moved declaration to ../tree-inline.h.
- (walk_tree): Moved declaration to ../tree-inline.h.
- (walk_tree_without_duplicates, copy_tree_r): Likewise.
- (remap_save_expr): Likewise.
- * decl.c: Include tree-inline.h.
- (lang_mark_tree): Don't mark inlined_fns.
- * decl2.c (flag_inline_trees): Moved defn to ../tree-inline.c.
- * optimize.c: Include tree-inline.h.
- (optimize_inline_calls): Move declaration to ../tree.h, as
- non-static.
- (remap_decl): Use language-independent constructs and hooks.
- (remap_block, copy_body_r, declare_return_variable): Likewise.
- (inlinable_function_p): Likewise. Don't test for
- DECL_LANG_SPECIFIC before DECL_INLINED_FNS as inlined_fns is
- no longer language-specific.
- (optimize_inline_calls): Likewise. Make it non-static. Moved
- call of dump_function to...
- (optimize_function): Here...
- (clone_body): New function, extracted from...
- (maybe_clone_body): ... here. Build decl_map locally and pass
- it on to clone_body.
- * pt.c, semantics.c: Include tree-inline.h.
- * tree.c: Likewise.
- (cp_walk_subtrees): New language-specific hook for tree inlining.
- (cp_cannot_inline_tree_fn, cp_add_pending_fn_decls,
- cp_is_overload_p, cp_auto_var_in_fn_p,
- cp_copy_res_decl_for_inlining): Likewise.
- (walk_tree): Move language-specific constructs into...
- (cp_walk_subtrees): this new function.
- (copy_tree_r): Use language-independent constructs and hooks.
- (init_tree): Initialize tree inlining hooks.
- (remap_save_expr): Adjust prototype so that the declaration
- does not require the definition of splay_tree.
-
-2001-10-03 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * rtti.c (get_tinfo_decl): Call typeinfo_in_lib_p with the type used
- to build the declaration instead of the declaration itself.
-
-2001-10-02 Jason Merrill <jason_merrill@redhat.com>
-
- * decl2.c (cxx_decode_option): Add 'else'.
-
- * spew.c (end_input): No longer static.
- * cp-tree.h: Declare it.
- * parse.y (datadef): Add "error END_OF_SAVED_INPUT" expansion.
-
-2001-10-02 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * call.c (build_over_call), typeck.c (build_function_call_real):
- Pass type attributes to check_function_format rather than name or
- assembler name. Don't require there to be a name or assembler
- name to check formats.
-
-2001-10-02 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl.c (init_decl_processing): Don't call
- init_function_format_info. Initialize lang_attribute_table
- earlier.
- (builtin_function): Call decl_attributes.
- (insert_default_attributes): New.
-
-2001-10-01 Jason Merrill <jason_merrill@redhat.com>
-
- * decl.c (grokdeclarator): Copy array typedef handling from C
- frontend.
-
- * decl.c (grokdeclarator): Copy too-large array handling from C
- frontend.
-
-2001-09-29 Alexandre Oliva <aoliva@redhat.com>
-
- * config-lang.in (target_libs): Added target-gperf, so that we
- don't try to build it if C++ is disabled.
-
-2001-09-23 Zack Weinberg <zack@codesourcery.com>
-
- * Make-lang.in (CXX_OBJS): Take out cp/errfn.o.
- (cp/errfn.o): Delete rule.
- (cp/error.o): Depend on flags.h.
- * errfn.c: Delete file.
- * cp-tree.h: Declare warn_deprecated. Remove definitions of
- TFF_NAMESPACE_SCOPE, TFF_CLASS_SCOPE, TFF_CHASE_NAMESPACE_ALIAS,
- and TFF_TEMPLATE_DEFAULT_ARGUMENTS. #define cp_error, cp_warning,
- cp_pedwarn, and cp_compiler_error to error, warning, pedwarn, and
- internal_error respectively. Make cp_deprecated into a macro.
- Don't define cp_printer typedef or declare cp_printers.
- * error.c: Include flags.h.
- Delete: struct tree_formatting_info, print_function_argument_list,
- print_declaration, print_expression, print_function_declaration,
- print_function_parameter, print_type_id, print_cv_qualifier_seq,
- print_type_specifier_seq, print_simple_type_specifier,
- print_elaborated_type_specifier, print_rest_of_abstract_declarator,
- print_parameter_declaration_clause, print_exception_specification,
- print_nested_name_specifier, and definition of cp_printers.
- (locate_error): New function.
- (cp_error_at, cp_warning_at, cp_pedwarn_at): Moved here and
- rewritten in terms of locate_error and diagnostic.c.
- (cp_tree_printer): Rename cp_printer; wire up to *_to_string
- instead of deleted print_* routines. Handle %C, %L, %O, %Q also.
- (init_error): Adjust to match.
-
-Sat Sep 22 09:15:31 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * Make-lang.in (CXX_C_OBJS): Add attribs.o.
-
-2001-09-21 Richard Henderson <rth@redhat.com>
-
- * class.c (set_vindex): Mind TARGET_VTABLE_USES_DESCRIPTORS.
- (build_vtbl_initializer): Likewise.
- (build_vfn_ref): New.
- * cp-tree.h: Declare it.
- * call.c (build_over_call): Use it.
- * decl2.c (mark_vtable_entries): Mark FDESC_EXPR.
- * typeck.c (get_member_function_from_ptrfunc): Mind descriptors.
-
-Fri Sep 21 08:16:19 2001 J"orn Rennecke <amylaar@redhat.com>
-
- * decl.c (grokdeclarator): Use C syntax for attr_flags declaration.
-
-2001-09-21 Joseph S. Myers <jsm28@cam.ac.uk>
-
- Table-driven attributes.
- * decl.c: Rename DECL_MACHINE_ATTRIBUTES to DECL_ATTRIBUTES.
- * decl2.c (cplus_decl_attributes): Only take one attributes
- parameter.
- * cp-tree.c (cplus_decl_attributes): Update prototype.
- * class.c (finish_struct), decl.c (start_decl, start_function),
- decl2.c (grokfield), friend.c (do_friend), parse.y
- (parse_bitfield): Update calls to cplus_decl_attributes.
- * decl.c (grokdeclarator): Take a pointer to a single ordinary
- attribute list.
- * decl.h (grokdeclarator): Update prototype.
- * decl2.c (grokfield): Take a single ordinary attribute list.
- * friend.c (do_friend): Likewise.
- * decl.c (shadow_tag, groktypename, start_decl,
- start_handler_parms, grokdeclarator, grokparms, start_function,
- start_method), decl2.c (grokfield, grokbitfield, grokoptypename),
- parse.y (parse_field, parse_bitfield, component_decl_1), pt.c
- (process_template_parm, do_decl_instantiation): Pass single
- ordinary attribute lists around.
- * decl.c (grokdeclarator): Correct handling of nested attributes.
- Revert the patch
- 1998-10-18 Jason Merrill <jason@yorick.cygnus.com>
- * decl.c (grokdeclarator): Embedded attrs bind to the right,
- not the left.
- .
- * cp-tree.h (cp_valid_lang_attribute): Remove declaration
- (cp_attribute_table): Declare.
- * decl.c (valid_lang_attribute): Don't define.
- (lang_attribute_table): Define.
- (init_decl_processing): Initialize lang_attribute_table instead of
- valid_lang_attribute.
- * tree.c (cp_valid_lang_attribute): Remove.
- (handle_java_interface_attribute, handle_com_interface_attribute,
- handle_init_priority_attribute): New functions.
- (cp_attribute_table): New array.
- * decl2.c (import_export_class): Don't use
- targetm.valid_type_attribute.
-
-2001-09-15 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
-
- * Make-lang.in (cp/error.o): Depend on real.h
- * error.c: #include "real.h"
-
-2001-09-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * mangle.c (mangle_conv_op_name_for_type): Use concat in lieu of
- xmalloc/strcpy/strcat.
-
-2001-09-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * decl.c (warn_extern_redeclared_static, cp_make_fname_decl):
- Const-ification.
- * pt.c (tsubst_decl): Likewise.
-
-2001-09-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * decl2.c (lang_f_options): Const-ification.
- * lex.c (cplus_tree_code_name): Likewise.
- * spew.c (yyerror): Likewise.
-
-2001-09-06 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/3986
- * class.c (force_canonical_binfo_r): Check & move an indirect
- primary base first.
- (force_canonical_binfo): Check that it's not already
- canonical.
- (mark_primary_virtual_base): Remove BINFO parameter.
- (mark_primary_bases): Adjust, set BINFO_LOST_PRIMARY_P here.
-
-2001-09-06 Nathan Sidwell <nathan@codesourcery.com>
-
- Remove TYPE_NONCOPIED_PARTS.
- * cp-tree.h (CLASSTYPE_INLINE_FRIENDS): Map onto
- CLASSTYPE_PURE_VIRTUALS.
- (TYPE_RAISES_EXCEPTIONS): Map onto TYPE_BINFO.
- * class.c (duplicate_tag_error): Remove TYPE_NONCOPIED_PARTS.
- (layout_class_type): Don't call fixup_inline_methods here ...
- (finish_struct_1): ... call it here.
-
-2001-09-04 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (duplicate_decls): Remove code deadling with
- DECL_SAVED_INSNS.
- * decl2.c (finish_file): Likewise.
- * pt.c (instantiate_decl): Likewise.
- * semantics.c (expand_body): Don't defer local functions if
- they wouldn't be deferred for some other reason. Don't
- generate RTL for functions that will not be emitted.
- (genrtl_start_function): Remove code deadling with
- DECL_SAVED_INSNS.
- (genrtl_finish_function): Likewise.
-
-2001-09-04 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/4203
- * call.c (build_over_call): Do not optimize any empty base
- construction.
-
-2001-08-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * error.c (dump_template_decl): Output template parameters
- together with their specifiers.
- Output `class' prefix for template template parameter.
- (dump_decl): Fix formatting.
-
-2001-08-30 Kurt Garloff <garloff@suse.de>
-
- * optimize.c (inlinable_function_p): Allow only smaller single
- functions. Halve inline limit after reaching recursive limit.
-
-2001-08-30 Joern Rennecke <amylaar@redhat.com>
- Jason Merrill <jason_merrill@redhat.com>
-
- * class.c (build_vtable_entry_ref): Subtract in char*, not
- ptrdiff_t.
-
-2001-08-23 Jason Merrill <jason_merrill@redhat.com>
-
- * tree.c (cp_build_qualified_type_real): Use get_qualified_type.
- (build_cplus_array_type): Use cp_build_qualified_type, not
- TYPE_MAIN_VARIANT, to get an unqualified version.
-
- * decl2.c (grok_alignof): Lose.
- (build_expr_from_tree): Use expr_sizeof and c_alignof_expr.
- * typeck.c (c_alignof): Lose.
- * semantics.c (finish_sizeof, finish_alignof): New.
- * parse.y: Use them.
- * cp-tree.h: Declare them.
-
-2001-08-22 Jason Merrill <jason_merrill@redhat.com>
-
- * pt.c (tsubst_expr): Hand off to the TREE_CHAIN of a statement.
- Don't loop in COMPOUND_STMT, FOR_STMT or TRY_BLOCK.
- * tree.c (cp_statement_code_p): A TAG_DEFN is a statement.
-
-2001-08-19 Jakub Jelinek <jakub@redhat.com>
-
- * typeck2.c (add_exception_specifier): Only require complete type if
- not in processing template declaration.
-
-2001-08-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * decl.c: Cast argument to size_t, not HOST_WIDE_INT, in calls to
- GNU_xref_start_scope and GNU_xref_end_scope.
-
- * tree.c (TYPE_HASH): Moved to ../tree.h.
-
-2001-08-16 Mark Mitchell <mark@codesourcery.com>
-
- * cvt.c (convert_to_void): Preserve TREE_SIDE_EFFECTS
- on COMPOUND_EXPRs.
-
-2001-08-14 Richard Henderson <rth@redhat.com>
-
- * class.c, cp-tree.h (build_vfn_ref): Remove.
- * call.c, rtti.c: Replace all refernces with build_vtbl_ref.
-
-2001-08-13 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (build_over_call): Mark COMPOUND_EXPRs generated for
- empty class assignment as having side-effects to avoid
- spurious warnings.
-
-2001-08-13 Zack Weinberg <zackw@panix.com>
-
- * Make-lang.in (cp/except.o): Add libfuncs.h to dependencies.
- * except.c: Include libfuncs.h.
-
-2001-08-11 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
-
- * decl.c (grokdeclarator): Clarify diagnostic message.
-
-2001-08-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * decl2.c (do_nonmember_using_decl): Replace using directive
- with using declaration in the error message.
-
-2001-08-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (maybe_fold_nontype_arg): Use TREE_TYPE of ARG as the
- criterion to avoid rebuilding expression tree instead of
- processing_template_decl.
-
-2001-08-07 Jason Merrill <jason_merrill@redhat.com>
-
- Support named return value optimization for inlines, too.
- * decl.c (finish_function): Nullify returns here.
- * semantics.c (genrtl_start_function): Not here.
- (cp_expand_stmt): Don't mess with CLEANUP_STMTs.
- (nullify_returns_r): No longer static. Just clear RETURN_EXPR.
- Also nullify the CLEANUP_STMT for the nrv.
- * cp-tree.h: Declare it.
- * optimize.c (declare_return_variable): Replace the nrv with the
- return variable.
- * typeck.c (check_return_expr): Be more flexible on alignment check.
- Ignore cv-quals when checking for a matching type.
-
-2001-08-09 Richard Henderson <rth@redhat.com>
-
- * decl2.c (finish_objects): Use target hooks instead of
- assemble_constructor and assemble_destructor.
-
-2001-08-08 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * g++spec.c (lang_specific_driver): Quote argument after `-Xlinker'.
-
-2001-08-07 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/3820
- Stop using TYPE_NONCOPIED_PARTS.
- * call.c (build_over_call): Be careful when copy constructing
- or assigning to an empty class.
- * class.c (check_bases_and_members): It has a
- COMPLEX_ASSIGN_REF if it has a vptr.
- (layout_class_type): Don't add empty class padding to
- TYPE_NONCOPIED_PARTS.
- (finish_struct_1): Don't add the VFIELD either.
- * cp-tree.h (TYPE_HAS_TRIVIAL_INIT_REF): Mention _copy_
- initialization.
-
-2001-08-07 Jason Merrill <jason_merrill@redhat.com>
-
- * tree.c (walk_tree): Walk siblings even if !walk_subtrees.
-
-2001-08-06 Richard Henderson <rth@redhat.com>
-
- * decl2.c (finish_objects): Pass a symbol_ref and priority to
- assemble_{constructor,destructor}. Remove priority handling.
-
-2001-08-05 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
-
- Don't allow template-id in using-declaration.
- * decl2.c (validate_nonmember_using_decl): Handle template-ids.
- (do_class_using_decl): Likewise.
-
-2001-08-04 Neil Booth <neil@cat.daikokuya.demon.co.uk>
-
- * cp/spew.c (read_token): No need to pop buffers.
-
-2001-08-02 Stan Shebs <shebs@apple.com>
-
- * cp-tree.h (FNADDR_FROM_VTABLE_ENTRY): Remove, no longer used.
- (fnaddr_from_vtable_entry): Remove decl.
- * method.c (use_thunk): Update comment.
-
-2001-08-01 Andrew Cagney <ac131313@redhat.com>
-
- * repo.c (get_base_filename): Change return value to const char
- pointer.
-
-2001-08-02 Nathan Sidwell <nathan@codesourcery.com>
-
- Kill -fhonor-std.
- * NEWS: Document.
- * cp-tree.h (flag_honor_std): Remove.
- (CPTI_FAKE_STD): Remove.
- (std_node): Remove comment about it being NULL.
- (fake_std_node): Remove.
- * decl.c (in_fake_std): Remove.
- (walk_namespaces_r): Remove fake_std_node check.
- (push_namespace): Remove in_fake_std code.
- (pop_namespace): Likewise.
- (lookup_name_real): Remove fake_std_node check.
- (init_decl_processing): Always create std_node. Always add
- std:: things there.
- (builtin_function): Always put non '_' fns in std.
- * decl2.c (flag_honor_std): Remove.
- (lang_f_options): Remove honor-std.
- (unsupported_options): Add honor-std.
- (set_decl_namespace): Remove fake_std_node check.
- (validate_nonmember_using_decl): Likewise.
- (do_using_directive): Likewise.
- (handle_class_head): Likewise.
- * dump.c (cp_dump_tree): Likewise.
- * except.c (init_exception_processing): Adjust.
- * init.c (build_member_call): Remove fake_std_node check.
- (build_offset_ref): Likewise.
- * lang-options.h: Remove -fhonor-std, -fno-honor-std.
- * rtti.c (init_rtti_processing): Adjust.
-
-2001-07-31 Alexandre Petit-Bianco <apbianco@redhat.com>
-
- * tree.c (cp_tree_equal): WITH_CLEANUP_EXPR node to use its second
- operand while calling cp_tree_equal.
-
-2001-07-31 Nathan Sidwell <nathan@codesourcery.com>
-
- The 3.0 ABI no longer has vbase pointer fields.
- * cp-tree.h (VBASE_NAME, VBASE_NAME_FORMAT, VBASE_NAME_P,
- FORMAT_VBASE_NAME): Remove.
- * method.c (do_build_copy_constructor): Adjust.
- (do_build_assign_ref): Adjust.
- * search.c (lookup_field_r): Adjust.
- * typeck.c (build_component_ref): Adjust.
-
- The 3.0 ABI always has a vtable pointer at the start of every
- polymorphic class.
- * rtti.c (build_headof_sub): Remove.
- (build_headof): Adjust.
- (get_tinfo_decl_dynamic): No need to check flag_rtti
- here. Adjust.
- (create_real_tinfo_var): Explain why we need a hidden name.
-
-2001-07-31 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/3631
- * class.c (update_vtable_entry_for_fn): The fixed adjustment
- of a virtual thunk should be from declaring base.
-
-2001-07-31 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (dfs_ctor_vtable_bases_queue_p): Always walk into
- the shared virtual base, so preserving inheritance graph order.
-
-2001-07-30 Andreas Jaeger <aj@suse.de>
-
- * decl2.c: Remove unused var global_temp_name_counter.
-
-2001-07-28 Richard Henderson <rth@redhat.com>
-
- * method.c (pending_inlines): Remove.
-
-2001-07-27 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (mark_primary_virtual_base): Don't adjust base
- offsets here.
- (dfs_unshared_virtual_bases): Adjust them here.
- (mark_primary_bases): Explain why we adjust at the end.
-
-2001-07-27 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (finish_struct_1): When copying the primary base's
- VFIELD, make sure we find it is at offset zero.
-
-2001-07-26 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (tsubst_template_parms): Call maybe_fold_nontype_arg and
- tsubst_expr for default template arguments.
-
-2001-07-26 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/3621
- * spew.c (yylex): Only copy the token's lineno, if it is
- nonzero.
-
-2001-07-26 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/3624
- * call.c (resolve_args): Simplify, call
- convert_from_reference.
- (build_new_op): Resolve and convert from reference ARG1
- earlier. Adjust ARG2 & ARG3 resolve and conversion.
-
-2001-07-26 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (last_function_parm_tags): Remove.
- (current_function_parm_tags): Remove.
- (init_decl_processing): Adjust.
- (start_function): Adjust.
- (store_parm_decls): Adjust.
-
- PR c++/3152
- * decl.c (grokdeclarator): Detect when a function typedef is
- declaring a function, and create last_function_parms correctly.
-
-2001-07-25 Jason Merrill <jason_merrill@redhat.com>
-
- * call.c (joust): Only prefer a non-builtin candidate to a builtin
- one if they have the same signature.
-
- * cvt.c (build_up_reference): Take DECL parm. Check TREE_STATIC on
- it rather than toplevel_bindings_p. Give it a mangled name if static.
- (convert_to_reference): Adjust.
- * decl2.c (get_temp_name): Lose.
- * mangle.c (mangle_ref_init_variable): New fn.
- (mangle_guard_variable): Strip the ref-init header.
- * cp-tree.h: Adjust.
- * decl.c (cp_finish_decl): Add the DECL_STMT after processing the
- initializer.
- (grok_reference_init): Always use DECL_INITIAL.
-
-2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/3416
- * call.c (build_conditional_expr): Recheck args after
- conversions.
- * cp-tree.h (build_conditional_expr): Move to correct file.
- * typeck.c (decay_conversion): Diagnose any unknown types
- reaching here.
- (build_binary_op): Don't do initial decay or default
- conversions on overloaded functions.
- (build_static_cast): Don't do a decay conversion here.
-
-2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/3543
- * typeck.c (condition_conversion): Resolve an OFFSET_REF.
- * expr.c (cplus_expand_expr): An OFFSET_REF should never get here.
-
-2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (build_vtbl_or_vbase_field): Remove, move into ...
- (create_vtbl_ptr): ... here.
-
-2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (build_vbase_offset_vbtl_entries): Look for
- non-primary base of which we are a sub vtable.
-
-2001-07-24 Phil Edwards <pme@sources.redhat.com>
-
- * semantics.c (finish_this_expr): Remove unused code.
-
-2001-07-24 Nathan Sidwell <nathan@codesourcery.com>
-
- Simplify rtti, now we've only one ABI.
- * cp-tree.h (cp_tree_index): Remove CPTI_TINFO_DECL_ID,
- CPTI_TINFO_VAR_ID.
- (tinfo_decl_id, tinfo_var_id): Remove.
- (get_typeid_1): Remove.
- * rtti.c
- (init_rtti_processing): Remove tinfo_decl_id & tinfo_var_id.
- (typeid_ok_p): New function.
- (build_type_id): Call typeid_ok_p. Don't call tinfo_from_decl.
- (get_tinfo_decl): Remove old abi documentation.
- (tinfo_from_decl): Remove.
- (get_type_id): Call typeid_ok_p. Absorb get_typeid_1.
- (get_typeid_1): Remove.
- (get_base_offset): Remove.
- (synthesize_tinfo_var): Absorb get_base_offset.
- (create_real_tinfo_var): Don't use tinfo_decl_id.
-
-2001-07-23 Graham Stott <grahams@redhat.com>
-
- * cp/class.c (type_requires_array_cookie): Fix use of uninitialized
- variable has_two_argument_delete_p.
-
-2001-07-21 Nathan Sidwell <nathan@codesourcery.com>
-
- Remove flag_vtable_thunk. It is always on for the 3.0 ABI.
- * cp-tree.h (CPTI_DELTA2_IDENTIFIER): Remove.
- (CPTI_INDEX_IDENTIFIER): Remove.
- (CPT_PFN_OR_DELTA2_IDENTIFIER): Remove.
- (delta2_identifier): Remove.
- (index_identifier): Remove.
- (pfn_or_delta2_identifier): Remove.
- (flag_vtable_thunks): Remove.
- (VTABLE_DELTA2_NAME): Remove.
- (VTABLE_INDEX_NAME): Remove.
- (FNADDR_FROM_VTABLE_ENTRY): Adjust.
- (vfunc_ptr_type_node): Adjust.
- (VTABLE_NAME_PREFIX): Adjust.
- (build_vfn_ref): Lose first parameter.
- (fixup_all_virtual_upcast_offsets): Remove.
- * decl.c (initialize_predefined_identifiers): Remove
- delta2_identifier, index_identifier, pfn_or_delta2_identifier.
- (init_decl_processing): Remove no-vtable-thunk code.
- * decl2.c (flag_vtable_thunks): Remove.
- (mark_vtable_entries): Remove no-vtable-thunk code.
- * error.c (dump_decl): Remove no-vtable-thunk code.
- (dump_expr): Adjust ptr to member function code.
- * init.c (initialize_vtable_ptrs): Remove no-vtable-thunk
- code.
- * rtti.c (build_headof): Remove no-vtable-thunk code.
- (get_tinfo_decl_dynamic): Adjust build_vfn_ref call.
- * search.c (get_base_distance): Remove expand_upcast_fixups case.
- (virtual_context) Remove.
- (expand_upcast_fixups): Remove.
- (fixup_virtual_upcast_offsets): Remove.
- (fixup_all_virtual_upcast_offsets): Remove.
- * typeck.c (get_member_function_from_ptrfunc): Remove
- no-vtable-thunk code.
- * call.c (build_over_call): Adjust call to build_vfn_ref.
- * class.c (build_vfn_ref): Lose first parameter. Remove
- no-vtable-thunk code.
- (build_rtti_vtbl_entries): Remove no-vtable-thunk code.
- (build_vtable_entry): Remove no-vtable-thunk code.
-
-2001-07-20 Nathan Sidwell <nathan@codesourcery.com>
-
- Remove old-abi remnants. Remove comments about old abi
- behavior. Remove references to 'new-abi' in comments.
- * cp-tree.h: Adjust comments.
- (vbase_offsets_in_vtable_p): Delete.
- (vcall_offsets_in_vtable_p): Delete.
- (vptrs_present_everywhere_p): Delete.
- (all_overridden_vfuns_in_vtables_p): Delete.
- (merge_primary_and_secondary_vtables_p): Delete.
- (TYPE_CONTAINS_VPTR_P): Adjust.
- (VTT_NAME_PREFIX): Remove.
- (CTOR_VTBL_NAME_PREFIX): Remove.
- (init_vbase_pointers): Remove.
- * class.c: Adjust coments.
- (build_vbase_pointer_fields): Delete.
- (build_vbase_pointer): Remove old-abi code.
- (build_secondary_vtable): Likewise.
- (modify_all_vtables): Likewise.
- (create_vtable_ptr): Likewise.
- (layout_class_type): Likewise.
- (finish_struct_1): Likewise.
- (finish_vtbls): Likewise.
- (dfs_finish_vtbls): Delete.
- (build_vbase_offset_vtbl_entries): Remove old-abi code.
- * cvt.c: Adjust comments.
- * decl.c: Adjust comments.
- * decl2.c: Adjust comments.
- * init.c: Adjust comments.
- (construct_virtual_bases): Remove old-abi code.
- * lang-specs.h: Remove -fno-new-abi.
- * mangle.c: Adjust comments.
- * rtti.c: Adjust comments.
- (get_base_offset): Remove old-abi-code.
- * search.c: Adjust comments.
- (dfs_init_vbase_pointers): Remove.
- (dfs_vtable_path_unmark): Remove.
- (init_vbase_pointers): Remove.
- * semantics.c: Adjust comments.
- (emit_associated_thunks): Remove old-abi code.
- * typeck.c: Adjust comments.
-
-2001-07-20 Daniel Berlin <dan@cgsoftware.com>
-
- * Make-lang.in (cp/optimize.o): Depend on $(PARAMS_H), not
- params.h.
-
-2001-07-19 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (finish_struct_anon): Forbid nested classes.
-
-2001-07-19 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * decl2.c: Don't include dwarfout.h and dwarf2out.h.
- * optimize.c: Include debug.h.
- (maybe_clone_body): Use debug hook.
- * semantics.c: Include debug.h.
- (expand_body): Use debug hook.
-
-2001-07-19 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * spew.c (read_token, yyerror): Remove CPP_INT, CPP_FLOAT cases.
-
-2001-07-18 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (type_requires_array_cookie): New function.
- (check_methods): Don't try to figure out whether the type needs a
- cookie here.
- (check_bases_and_members): Set TYPE_VEC_NEW_USES_COOKIE here.
- * cp-tree.h (TYPE_VEC_DELETE_TAKES_SIZE): Remove.
- (TYPE_VEC_NEW_USES_COOKIE): Reimplement.
- * pt.c (instantiate_class_template): Don't set
- TYPE_VEC_DELETE_TAKES_SIZE.
- * NEWS: Document ABI changes from GCC 3.0.
-
-2001-07-18 Xavier Delacour <xavier@fmaudio.net>,
- Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
-
- * NEWS (Changes in GCC 3.0): Fix typo.
-
-2001-07-13 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl2.c (cplus_decl_attributes): Take a pointer to the node to
- which attributes are to be attached, and a flags argument. Update
- call to decl_attributes.
- (grokfield): Update call to decl_attributes.
- * class.c (finish_struct): Update call to cplus_decl_attributes.
- * cp-tree.h (cplus_decl_attributes): Update prototype.
- * decl.c (start_decl, grokdeclarator, start_function): Update
- calls to decl_attributes and cplus_decl_attributes.
- * friend.c (do_friend): Update call to cplus_decl_attributes.
- * parse.y (parse_bitfield): Update call to cplus_decl_attributes.
-
-2001-07-12 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (make_rtl_for_nonlocal_decl): Set DECL_C_HARD_REGISTER
- for `register' variables with an asm-specification.
-
-2001-07-11 Mark Mitchell <mark@codesourcery.com>
-
- * semantics.c (finish_asm_stmt): Mark the output operands
- to an asm addressable, if necessary.
-
-2001-07-11 Ben Elliston <bje@redhat.com>
-
- * Revert this change -- there is a subtle bug.
-
- PR c++/80
- * decl.c (finish_enum): New "attributes" argument; pass it to
- cplus_decl_attributes. Use a narrower type if the enum is packed.
- * cp-tree.h (finish_enum): Adjust prototype.
- * parse.y (enum_head): New non-terminal.
- (structsp): Use it. Enums now may be preceded or followed by
- optional attributes -- pass their chained tree to finish_enum().
- * pt.c (tsubst_enum): Pass NULL_TREE for the new argument.
-
-2001-07-10 Mark Mitchell <mark@codesourcery.com>
-
- * pt.c (tsubst_decl): Set DECL_CONTEXT for namespace-scope
- variables.
-
-2001-07-10 Jason Merrill <jason_merrill@redhat.com>
-
- * semantics.c (cp_expand_stmt): Fix for null
- current_function_return_value.
-
-2001-07-10 Jan van Male <jan.vanmale@fenk.wau.nl>
-
- * call.c (build_op_delete_call): Initialize fn.
- (convert_like_real): Delete conditional.
- (joust): Initialize *w and *l.
- * class.c: Add prototype for binfo_ctor_vtable.
- (get_primary_binfo): Initialize result.
- * init.c (build_java_class_ref): Initialize name.
-
-2001-07-09 Erik Rozendaal <dlr@acm.org>
-
- * typeck.c (unary_complex_lvalue): Do not duplicate the
- argument to modify, pre-, or post-increment when used as an
- lvalue and when the argument has side-effects.
-
-2001-07-08 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl.c (start_decl): Don't call SET_DEFAULT_DECL_ATTRIBUTES.
- (start_function): Don't call SET_DEFAULT_DECL_ATTRIBUTES. Call
- cplus_decl_attributes even if attrs is NULL.
- * friend.c (do_friend): Don't call SET_DEFAULT_DECL_ATTRIBUTES.
-
-2001-07-08 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl.c (grokdeclarator), decl2.c (cplus_decl_attributes): Update
- calls to decl_attributes.
-
-2001-07-06 Ira Ruben <ira@apple.com>
-
- * cp-tree.def (TEMPLATE_DECL): Update comment. DECL_RESULT should
- be DECL_TEMPLATE_RESULT.
-
-2001-07-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * cp-tree.h (copy_template_template_parm): Rename to ...
- (bind_template_template_parm): ... here.
- * tree.c (copy_template_template_parm): Rename to ...
- (bind_template_template_parm): ... here. Remove the case when
- NEWARGS is NULL_TREE.
- (copy_tree_r): Don't copy TEMPLATE_TEMPLATE_PARM and
- BOUND_TEMPLATE_TEMPLATE_PARM.
- * pt.c (lookup_template_class): Adjust.
-
-2001-07-05 Jason Merrill <jason_merrill@redhat.com>
-
- * cvt.c (convert_lvalue): New fn.
- * cp-tree.h: Declare it.
- * method.c (do_build_assign_ref): Use it.
- (do_build_copy_constructor): Convert parm to base types
- before calling base constructors.
-
- * typeck.c (check_return_expr): Check DECL_ALIGN instead of
- DECL_USER_ALIGN. Check flag_elide_constructors instead of
- optimize.
- * semantics.c (cp_expand_stmt): Don't destroy the named return value.
-
-2001-07-02 Nathan Sidwell <nathan@codesourcery.com>
-
- * optimize.c (optimize_inline_calls): New function, broken out
- of ...
- (optimize_function): ... here. Call it. Don't inline if it is
- a thunk.
- (dump_function): Print name of dump flag causing this dump.
- * semantics.c (expand_body): Move thunk inline check to
- optimize_function.
-
-2001-06-29 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * typeck.c (COMP_TYPE_ATTRIBUTES): Don't define.
- (comptypes): Use target.comp_type_attributes.
-
-2001-06-29 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (flag_dump_class_layout): Remove unneeded declaration.
-
-2001-06-28 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
-
- * error.c (lang_print_error_function): Add a `diagnostic_context *'
- parameter. Tweak.
-
-2001-06-27 Neil Booth <neil@cat.daikokuya.demon.co.uk>
-
- * decl2.c (import_export_class): Update.
-
-2001-06-26 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c (init_error): Adjust settings.
-
-2001-06-26 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c (init_error): Adjust settings.
-
-2001-06-19 Richard Sandiford <rsandifo@redhat.com>
-
- * except.c (initialize_handler_parm): Expect __cxa_begin_catch to
- return pointers to data members by reference rather than by value.
-
-2001-06-18 Jason Merrill <jason_merrill@redhat.com>
-
- Implement the Named Return Value optimization.
- * cp-tree.h (struct cp_language_function): Add x_return_value.
- (current_function_return_value): Now a macro.
- * decl.c: Don't define it.
- (define_label, finish_case_label): Don't clear it.
- (init_decl_processing): Don't register it with GC.
- * semantics.c (genrtl_finish_function): Don't check it for
- no_return_label. Copy the RTL from the return value to
- current_function_return_value and walk, calling...
- (nullify_returns_r): ...this new fn.
- * typeck.c (check_return_expr): Set current_function_return_value.
-
-2001-06-15 Jason Merrill <jason_merrill@redhat.com>
-
- * class.c (dfs_accumulate_vtbl_inits): Just point to the base we're
- sharing a ctor vtable with. Merge code for cases 1 and 2.
- (binfo_ctor_vtable): New fn.
- (build_vtt_inits, dfs_build_secondary_vptr_vtt_inits): Use it.
-
-2001-06-14 Jason Merrill <jason_merrill@redhat.com>
-
- * class.c (dfs_find_final_overrider): Fix logic.
-
- * class.c (update_vtable_entry_for_fn): Uncomment optimization to use
- virtual thunk instead of non-virtual.
- (get_matching_virtual): Uncomment.
-
- * pt.c (unify): Don't recurse between the POINTER_TYPE and the
- OFFSET_TYPE. If we're adding cv-quals, the extra ones would be on
- PARM, not ARG.
-
-2001-06-14 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (dfs_accumulate_vtbl_inits): For case 2 & 3, make sure
- we've not emerged from the hierarchy of RTTI_BINFO on reaching
- a non-virtual base.
-
-2001-06-13 Mark Mitchell <mark@codesourcery.com>
-
- * NEWS: Update release number.
-
-2001-06-12 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/3130, c++/3131, c++/3132
- * cp-tree.h (BINFO_UNSHARED_MARKED): New #define.
- * class.c (force_canonical_binfo_r): Move
- BINFO_UNSHARED_MARKED, BINFO_LOST_PRIMARY_P. Don't move
- virtual bases unless they're primary and what they're primary
- too has been moved.
- (dfs_unshared_virtual_bases): Use BINFO_UNSHARED_MARKED. Cope
- with morally virtual bases. Duplicate BINFO_LOST_PRIMARY_P and
- BINFO_PRIMARY_BASE_OF. Clear BINFO_VTABLE for all but the most
- derived binfo.
- (mark_primary_bases): Use BINFO_UNSHARED_MARKED.
- (layout_nonempty_base_or_field): Add most derived type
- parameter. Adjust.
- (layout_empty_base): Likewise.
- (build_base_field): Likewise.
- (build_base_fields): Likewise.
- (propagate_binfo_offsets): Add most derived type
- parameter. Skip non canonical virtual bases too.
- (dfs_set_offset_for_unshared_vbases): Don't skip primary
- bases. Do skip canonical bases.
- (layout_virtual_bases): Adjust.
- (layout_class_type): Adjust.
- (dfs_get_primary_binfo): Build list of virtual primary base
- candidates.
- (get_primary_binfo): Check that the shared virtual primary
- base candidate was found first.
- (accumulate_vtbl_inits): Don't do anything for non-vptr
- containing binfos. For case 1 primary virtual bases, keep
- checking that we've not emerged from the hierarchy of RTTI_BINFO.
-
-2001-06-12 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/3089
- * class.c (dfs_accumulate_vtbl_inits): Always walk down the
- hierarchy looking for primary bases for a ctor
- vtable. Recursively call oneself, if we meet our primary via
- this route and haven't met it yet via inheritance graph order.
-
-2001-06-11 Mark Mitchell <mark@codesourcery.com>
-
- * lang-options.h: Emit documentation for -fno-honor-std, not
- -fhonor-std.
-
-2001-06-10 Alexandre Oliva <aoliva@redhat.com>
-
- * typeck.c (get_member_function_from_ptrfunc) [vbit_in_delta]:
- Don't clobber delta.
- (expand_ptrmemfunc_cst) [ptrmemfunc_vbit_in_delta]: Adjust pfn.
-
-2001-06-10 Mark Mitchell <mark@codesourcery.com>
- Gabriel Dos Reis <gdr@codesourcery.com>
-
- * Make-lang.in (cp/call.o): Depend on diagnostic.h
- (cp/typeck.o): Depend on diagnostic.h
- (cp/typeck2.o): Depend on diagnostic.h
- (cp/repo.o): Depend on dignostic.h
- * typeck.c: #include diagnostic.h
- (convert_for_initialization): Remove extern declaration for
- warningcount and errorcount.
-
- * call.c: #include diagnostic.h
- (convert_like_real): Remove extern declaration for warnincount and
- errorcount.
-
- * repo.c: #include diagnostic.h
- * typeck2.c: #include diagnostic.h
-
-2001-06-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (duplicate_decls): Fix DECL_TEMPLATE_RESULT thinko
- in previous change.
-
-2001-06-08 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/2929
- * friend.c (do_friend): Use push_decl_namespace for classes at
- namespace scope.
-
-2001-06-08 Nathan Sidwell <nathan@codesourcery.com>
- Jason Merrill <jason_merrill@redhat.com>
-
- PR c++/3061
- * class.c (build_secondary_vtable): Use assert, rather than an error
- message.
- (dfs_fixup_binfo_vtbls): BINFO_VTABLE might be NULL.
- (dfs_accumulate_vtbl_inits): A lost primary virtual base may
- be between ORIG_BINFO and RTTI_BINFO, but neither of them.
- Don't set BINFO_VTABLE for a primary virtual base.
-
-2001-06-07 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (duplicate_decls): Update source position information
- when a template function is defined.
-
-2001-06-07 Phil Edwards <pme@sources.redhat.com>
-
- * lang-specs.h: Move -D_GNU_SOURCE to config/linux.h.
-
-2001-06-07 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/2914
- * decl.c (pushtag): Don't push into a complete type's scope.
-
-2001-06-06 Jason Merrill <jason_merrill@redhat.com>
-
- * cp-tree.h (THUNK_GENERATE_WITH_VTABLE_P): Lose.
- (struct lang_decl_flags): Lose generate_with_vtable_p.
- (BV_GENERATE_THUNK_WITH_VTABLE_P): Lose.
- * class.c (copy_virtuals): Adjust.
- * decl2.c (mark_vtable_entries): Adjust.
- * method.c (make_thunk, build_vtable_entry): Adjust.
- * class.c (update_vtable_entry_for_fn): Only look as far as the
- first defining class.
- (build_vtbl_initializer): Put nothing in the slot for a function only
- defined in a lost primary virtual base.
- (add_vcall_offset_vtbl_entries_1): Use the same code for
- the lost primary case and the normal case.
- (dfs_unshared_virtual_bases): Don't lose a non-virtual primary base.
- (get_vfield_offset, get_derived_offset): Lose.
- (dfs_find_final_overrider): Use look_for_overrides_here.
- (get_matching_virtual): New fn.
- * semantics.c (emit_associated_thunks): Check BV_USE_VCALL_INDEX_P,
- not BV_VCALL_INDEX.
- * search.c (look_for_overrides_here): Split out from...
- (look_for_overrides_r): Here.
-
- * class.c (find_final_overrider): Return error_mark_node on error.
-
- * decl2.c (key_method): #if 0 accidental change.
-2001-06-06 John David Anglin <dave@hiauly1.hia.nrc.ca>
+2004-01-15 Alexandre Oliva <aoliva@redhat.com>
- * call.c (convert_default_arg): Use INTEGRAL_TYPE_P.
- (build_over_call): Likewise.
- * decl.c (grokparms): Likewise.
- * pt.c (tsubst_decl): Likewise.
- * typeck.c (convert_arguments): Likewise.
-
-2001-06-05 Mark Mitchell <mark@codesourcery.com>
-
- * semantics.c (begin_class_definition): Robustify.
-
- * pt.c (instantiate_decl): Tell the repository code about the
- clones, not the cloned functions.
- * repo.c (repo_template_used): Explicitly instantiate the cloned
- function, not the clones.
-
-2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (build_user_type_conversion_1): Set ICS_USER_FLAG and
- ICS_BAD_FLAG on created conversion.
- (compare_ics): Break out rank.
-
-2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (xref_tag): Remove extraneous %s on dependent name
- lookup warning.
-
-2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (layout_vtable_decl): Fix off by one error on
- build_index_type.
- (build_vtt): Likewise.
- (build_ctor_vtbl_group): Likewise.
-
-2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (maybe_indent_hierarchy): New function.
- (dump_class_hierarchy_r): Add flags. Dump extra binfo
- information, if enabled. Use maybe_indent_hierarchy. Adjust
- output format.
- (dump_class_hierarchy): Adjust prototype. Adjust output format.
- (dump_array, dump_vtable, dump_vtt): New functions.
- (finish_struct_1): Adjust hierarchy dumping.
- (initialize_vtable): Call dump_vtable.
- (build_vtt): Call dump_vtt.
- (build_ctor_vtbl_group): Call dump_vtable.
- * decl2.c (flag_dump_class_layout): Remove.
- (cxx_decode_option): Remove dump translation unit
- and dump class hierarchy check. Call dump_switch_p.
- (finish_file): Adjust dumping.
- (dump.c): Only dump base classes if not TDF_SLIM.
- Only dump namespace members if not TDF_SLIM.
- * optimize.c (dump_function): New function.
- (optimize_function): Call dump_function.
- * semantics.c (expand_body): Use dump_enabled_p.
-
-2001-06-01 Nathan Sidwell <nathan@codesourcery.com>
-
- PR g++/2936
- Part missed from first commit
- * decl2.c (finish_anon_union): Copy context.
-
-2001-05-30 Nathan Sidwell <nathan@codesourcery.com>
-
- PR g++/2936
- * optimize.c (remap_decl): Remap anonymous aggregate members too.
-
-2001-05-26 Nathan Sidwell <nathan@codesourcery.com>
-
- PR g++/2823
- * semantics.c (expand_body): Don't optimize thunks.
-
-2001-05-25 Sam TH <sam@uchicago.edu>
-
- * cp-tree.h lex.h: Fix header include guards.
-
-2001-05-25 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (init_decl_processing): Tweak.
-
-2001-05-24 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (duplicate_decls): Tidy.
- (init_decl_processing): Always set flag_no_builtin.
-
-2001-05-24 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/2184
- * decl2.c (do_local_using_decl): Push the decls, even in a
- template.
-
-2001-05-22 Mark Mitchell <mark@codesourcery.com>
-
- * optimize.c (initialize_inlined_parameters): Don't set
- TREE_READONLY for a VAR_DECL taking the place of an inlined
- PARM_DECL.
-
-2001-05-22 Jason Merrill <jason_merrill@redhat.com>
-
- * class.c, cp-tree.h, rtti.c: Remove com_interface attribute support.
- * tree.c (cp_valid_lang_attribute): Warn about use of com_interface
- attribute.
-
-2001-05-22 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * parse.y: Refer to compound literals as such, not as
- constructor-expressions.
-
-2001-05-21 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (build_op_delete_call): Ignore exception-specifications
- when looking for matching delete operators.
- * init.c (build_new_1): Compute whether or not the allocation
- function used is a placement allocation function or not, and
- communicate this information to build_op_delete_call.
-
-2001-05-21 Jason Merrill <jason_merrill@redhat.com>
-
- * class.c (build_vtable_entry_ref): Lose vtbl parm. Fix for new abi.
- (build_vtbl_ref): Adjust.
- (dfs_accumulate_vtbl_inits): Set TREE_CONSTANT on the vtable address.
- * decl2.c (lang_f_options): Remove huge-objects, vtable-thunks.
- Re-add vtable-gc.
- (unsupported_options): Correspondingly.
-
- * decl2.c (maybe_make_one_only): Check flag_weak, not
- supports_one_only().
-
- * cp-tree.def (START_CATCH_STMT): Lose.
- * dump.c (cp_dump_tree): Don't dump it. Do dump HANDLER_PARMS.
- * tree.c (cp_statement_code_p): Don't case it.
- * semantics.c (cp_expand_stmt): Likewise.
- * cp-tree.h (START_CATCH_TYPE): Lose.
- (HANDLER_TYPE): New.
- * except.c (expand_start_catch_block): Don't start any blocks.
- Return the type.
- (expand_end_catch_block): Don't end any blocks.
- * parse.y (handler): Don't pass anything from finish_handler_parms
- to finish_handler.
+ PR c++/13659
+ * name-lookup.c (validate_nonmember_using_decl): Take scope and
+ name by value, instead of computing them.
+ (do_local_using_decl, do_toplevel_using_decl): Add scope and name
+ arguments. Pass them to validate_nonmember_using_decl.
+ * name-lookup.h (do_local_using_decl): Adjust.
+ (do_toplevel_using_decl): Likewise.
+ * parser.c (cp_parser_using_declaration): Likewise.
* pt.c (tsubst_expr): Likewise.
- * semantics.c (begin_handler): Call note_level_for_catch here.
- (finish_handler_parms): Don't return anything.
- (genrtl_catch_block, begin_catch_block): Lose.
- (genrtl_handler): Call expand_start_catch here.
-
-2001-05-18 Jason Merrill <jason_merrill@redhat.com>
-
- * class.c (build_vtable): Set DECL_ASSEMBLER_NAME for vtables here.
- (get_vtable_decl, build_vtt): Not here.
-
-2001-05-20 Nathan Sidwell <nathan@codesourcery.com>
-
- PR c++/2781
- * optimize.c (update_cloned_parm): Copy addressability and other
- flags.
-
-2001-05-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (determine_specialization): Ignore artificial functions.
-
-2001-05-20 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-tree.h (struct lang_identifier, C_RID_YYCODE): Update.
- (C_RID_CODE): Remove.
- * lex.c (cxx_init_options): Call set_identifier_size. Update.
- (init_parse): Don't do it here.
-
-2001-05-18 Diego Novillo <dnovillo@redhat.com>
-
- * decl2.c (finish_objects): Use the original SYMBOL_REF from the
- function declaration to avoid stripping the symbol's attributes.
-
-2001-05-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (pushdecl): Adjust error string.
- (xref_tag): Adjust friend class injection warning. Remove the
- inherited name from the class shadowed scope.
-
-2001-05-17 Mark Mitchell <mark@codesourcery.com>
-
- * except.c (cp_protect_cleanup_actions): New function.
- (init_exception_processing): Don't set protect_cleanup_actions
- here. Do set lang_protect_cleanup_actions.
-
-2001-05-16 Nathan Sidwell <nathan@codesourcery.com>
-
- * spew.c (read_token): Call yyerror on all unexpected tokens.
-
-2001-05-16 Nathan Sidwell <nathan@codesourcery.com>
-
- * init.c (member_init_ok_or_else): Take a tree rather than
- string for name.
- (expand_member_init): Adjust.
-
-2001-05-14 Nick Clifton <nickc@cambridge.redhat.com>
-
- * decl.c (duplicate_decls): Suppress warning about duplicate
- decls if the first decl is a friend.
-
-2001-05-12 Zack Weinberg <zackw@stanford.edu>
-
- * except.c (choose_personality_routine): Export. Add
- explanatory comment. Take an enum languages, not a boolean.
- (initialize_handler_parm): Adjust to match.
- * cp-tree.h: Prototype choose_personality_routine.
- * lex.c (handle_pragma_java_exceptions): New function.
- (init_cp_pragma): Register #pragma GCC java_exceptions.
-
-2001-05-12 Neil Booth <neil@cat.daikokuya.demon.co.uk>
-
- * method.c (build_mangled_C99_name): Remove unused prototype.
-
-2001-05-12 Alexandre Oliva <aoliva@redhat.com>
-
- * cp-tree.h (ptrmemfunc_vbit_where_t): Declare type.
- * typeck.c (get_member_function_from_ptrfunc,
- build_ptrmemfunc, expand_ptrmemfunc_cst): Take
- TARGET_PTRMEMFUNC_VBIT_LOCATION into account.
-
- Reverted Geoff Keating's 2001-05-03's patch.
-
-2001-05-11 Ira Ruben <ira@apple.com>
-
- * cp/cp-tree.h (C_EXP_ORIGINAL_CODE): Delete; declared in c-common.h.
-
-2001-05-11 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp-tree.h (finish_label_expr, lookup_label): Delete.
- * parse.y: Update for '&&'; don't issue warning here.
- * semantics.c (finish_label_expr): Delete.
-
-2001-05-07 Mark Mitchell <mark@codesourcery.com>
-
- * splay-tree.h (splay_tree_max): New function.
- (splay_tree_min): Likewise.
-
-2001-05-03 Geoffrey Keating <geoffk@redhat.com>
-
- * cp-tree.h (enum cp_tree_index): Add CPTI_PFN_VFLAG_IDENTIFIER.
- (pfn_vflag_identifier): Define.
- Update comment about layout of pointer functions.
- (build_ptrmemfunc1): Update prototype.
- (expand_ptrmemfunc_cst): Update prototype.
- * decl.c (initialize_predefined_identifiers): Initialize
- pfn_vflag_identifier.
- (build_ptrmemfunc_type): When FUNCTION_BOUNDARY < 16, add
- an extra field to the type.
- * expr.c (cplus_expand_constant): Pass 'flag' between
- expand_ptrmemfunc_cst and build_ptrmemfunc1.
- * typeck.c (get_member_function_from_ptrfunc): When
- FUNCTION_BOUNDARY < 16, look at additional field to determine
- if a pointer-to-member is a real pointer or a vtable offset.
- (build_ptrmemfunc1): Add new parameter to contain extra field.
- (build_ptrmemfunc): Pass the extra field around.
- (expand_ptrmemfunc_cst): Add new parameter to return extra field.
- (pfn_from_ptrmemfunc): Ignore the extra field.
-
-2001-05-03 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (flag_inline_trees): Update documentation.
- * decl.c (init_decl_processing): Adjust handling of
- flag_inline_functions and flag_inline_trees to support -O3.
- (grokfndecl): Set DECL_INLINE on all functions if that's what
- the user requested.
- (save_function_data): Clear DECL_INLINE in
- current_function_cannot_inline is non-NULL.
- * decl2.c (flag_inline_trees): Update documentation.
-
-2001-05-03 Nathan Sidwell <nathan@codesourcery.com>
-
- * dump.c (cp_dump_tree, USING_STMT case): New case.
- * tree.c (cp_statement_code_p): Add USING_STMT.
- * decl2.c (do_using_directive): Add the using directive statement.
-
- * tree.c (walk_tree): Reformat an if block.
-
-2001-05-02 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (compute_array_index_type): Don't try to do anything with
- the indices when processing a template.
-
-2001-05-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * call.c: NULL_PTR -> NULL.
- * class.c: Likewise.
- * cvt.c: Likewise.
- * decl.c: Likewise.
- * decl2.c: Likewise.
- * except.c: Likewise.
- * init.c: Likewise.
- * rtti.c: Likewise.
- * search.c: Likewise.
- * tree.c: Likewise.
- * typeck.c: Likewise.
- * typeck2.c: Likewise.
-
-2001-05-02 Mark Mitchell <mark@codesourcery.com>
-
- * decl2.c (do_using_directive): Revert previous patch.
-
-2001-05-01 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.def (USING_STMT): New statement node.
- * cp-tree.h (USING_STMT_NAMESPACE): New macro.
- * decl2.c (do_using_directive): Add USING_STMT to statement
- tree. Don't emit errors when processing template decl.
- * pt.c (tsubst_expr, USING_STMT case): New case.
- * semantics.c (cp_expand_stmt, USING_STMT case): New case.
-
-2001-05-01 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (build_new_op): Convert args from reference here.
- (build_conditional_expr): Don't convert here.
-
-2001-05-01 Nathan Sidwell <nathan@codesourcery.com>
-
- * spew.c (last_token_id): New static variable.
- (read_token): Set it here.
- (yyerror): Use it here.
-
-2001-04-30 Richard Henderson <rth@redhat.com>
-
- * cvt.c: Downcase C_PROMOTING_INTEGER_TYPE_P invocations.
- * decl.c: Likewise.
-
-2001-04-30 Mark Mitchell <mark@codesourcery.com>
-
- * gxxint.texi: Remove.
- * Make-lang.in: Remove all traces of gxxint.texi.
-
-Mon Apr 30 16:14:10 2001 Mark P Mitchell <mark@codesourcery.com>
-
- * decl2.c (start_static_initialization_or_destruction): Correct
- logic to handle the -fno-use-cxa-atexit case.
-
-2001-04-30 Mark Mitchell <mark@codesourcery.com>
-
- * optimize.c (update_cloned_parm): New function.
- (maybe_clone_body): Use it. Update the `this' parameter too.
-
-2001-04-29 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl2.c (unsupported_options): Add new-abi.
- * lang-options.h: Remove no longer supported options.
-
-2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
-
- * except.c (can_convert_eh): Don't check template parms,
- typename types etc.
-
-2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
-
- * optimize.c (maybe_clone_body): Copy parameter names and locations.
-
-2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (adjust_clone_args): Prototype new function.
- * class.c (adjust_clone_args): New function.
- * decl.c (start_function): Call it for in charge ctors.
-
-2001-04-26 Mark Mitchell <mark@codesourcery.com>
-
- * method.c (use_thunk): Make sure that thunks really are emitted
- when requested.
-
-2001-04-26 Nathan Sidwell <nathan@codesourcery.com>
-
- * mangle.c (write_chars): New macro.
- (hwint_to_ascii): New function
- (write_number): Use it.
- (write_integer_cst): Deal with really big numbers.
-
-2001-04-25 Mark Mitchell <mark@codesourcery.com>
-
- * optimize.c (maybe_clone_body): Copy TREE_PUBLIC before emitting
- the clone.
-
-2001-04-25 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (grokdeclarator): Set context of namespace scope
- TYPE_DECLS.
-
-2001-04-24 Zack Weinberg <zackw@stanford.edu>
-
- * cp/optimize.c: Include hashtab.h.
- (struct inline_data): Add tree_pruner.
- (expand_call_inline, expand_calls_inline): Use it when calling
- walk_tree.
- (optimize_function): Initialize and free tree_pruner.
-
-2001-04-24 Nathan Sidwell <nathan@codesourcery.com>
-
- Lazy __FUNCTION__ generation.
- * cp-tree.def (FUNCTION_NAME): Remove.
- * cp-tree.h (function_name_declared_p): Remove.
- (cp_fname_init): Prototype.
- * decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
- don't call declare_function_name. Call start_fname_decls.
- (cp_make_fname_decl): Adjust parameters. Generate the name. Don't
- clobber the line number.
- (cp_fname_init): New function.
- (start_function): Call start_fname_decls.
- (finish_function): Call finish_fname_decls.
- * lex.c (reswords): Add slots for __FUNCTION__ et al.
- (rid_to_yy): Add mappings for __FUNCTION__ et al.
- * optimize.c (maybe_clone_body): Remove function_name_declared_p.
- * parse.y (VAR_FUNC_NAME): New token.
- (primary): Add VAR_FUNC_NAME.
- * pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
- generation.
- (tsubst, FUNCTION_NAME case): Remove.
- (tsubst_copy, FUNCTION_NAME case): Remove.
- (tsubst_expr, DECL_STMT case): Be careful with a
- DECL_PRETTY_FUNCTION_P.
- (instantiate_decl): Remove function_name_declared_p.
- * semantics.c (begin_compound_statement): Don't call
- declare_function_name here.
- (setup_vtbl_ptr). Don't save & restore function_name_declared_p.
- (finish_translation_unit): Call finish_fname_decls.
- (expand_body): Remove function_name_declared_p.
- * typeck2.c (digest_init): Allow any ERROR_MARK.
-
-2001-04-24 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (tsubst_decl): Use VOID_TYPE_P.
- * semantics.c: Fix some typos.
-
-2001-04-23 Phil Edwards <pme@sources.redhat.com>
-
- * cp/decl2.c (flag_honor_std): Always initialize to 1.
-
-2001-04-22 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * xref.c (GNU_xref_file): Use concat in lieu of xmalloc/sprintf.
-
-2001-04-23 Jason Merrill <jason_merrill@redhat.com>
-
- * except.c (build_throw): Wrap the initialization of the exception
- object in a MUST_NOT_THROW_EXPR.
- (do_free_exception): #if 0.
-
-2001-04-20 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (finish_enum): Change prototype.
- * decl.c (finish_enum): Reorganize.
- * parse.y (structsp): Adjust calls to finish_enum.
-
-2001-04-20 Nathan Sidwell <nathan@codesourcery.com>
-
- * tree.c (cp_tree_equal): Adjust final switch formatting. Add
- 't' case.
-
-2001-04-20 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (dfs_unshared_virtual_bases): Add ATTRIBUTE_UNUSED.
- (layout_empty_base): Return at end flag.
- (build_base_field): Likewise.
- (build_base_fields): Likewise.
- (layout_virtual_bases): Don't add 1 to eoc value.
- (end_of_class): Use full size for empty bases.
- (layout_class_type): Clear CLASSNEARLY_EMPTY_P if we appended
- empty bases. Don't add 1 to eoc value. Only add trailing padding
- if we're an empty class with no empty bases.
- (dump_class_hierarchy): Dump size and alignment.
-
-2001-04-20 Jakub Jelinek <jakub@redhat.com>
-
- * call.c (maybe_handle_ref_bind): Copy ICS_USER_FLAG and
- ICS_BAD_FLAG.
-
-2001-04-20 Jakub Jelinek <jakub@redhat.com>
-
- * search.c (lookup_field_r): If looking for type and non-TYPE_DECL
- is found, look first if name does not match the structure name.
-
-2001-04-19 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (DECL_LANGUAGE): Don't assume DECL_LANG_SPECIFIC is
- set.
- (SET_DECL_LANGUAGE): New macro.
- * decl.c (duplicate_decls): Use SET_DECL_LANGUAGE.
- (pushdecl): Likewise.
- (build_library_fn_1): Likewise.
- (build_cp_library_fn): Likewise.
- (grokfndecl): Likewise.
- (grokvardecl): Mark `extern "C"' variables as having C linkage.
- * decl2.c (grokclassfn): Use SET_DECL_LANGUAGE.
- * lex.c (retrofit_lang_decl): Likewise.
- * mangle.c (mangle_decl_string): Don't mangle the names of
- variables declared with C language linkage.
- * semantics.c (finish_member_declaration): Use SET_DECL_LANGUAGE.
-
-2001-04-18 John David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * semantics.c (simplify_aggr_init_exprs_r): Don't restore
- flag_access_control from uninitialized storage.
-
-2001-04-15 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (TYPE_PTRMEM_CLASS_TYPE): Improve documentation.
- * mangle.c (write_pointer_to_member_type): Fix mangling of
- pointers to cv-qualified member function types.
-
- * init.c (build_delete): Create a SAVE_EXPR for the address if
- we're going to use it more than once.
-
-2001-04-13 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (DELTA2_FROM_PTRMEMFUNC): Remove.
- (expand_ptremfunc_cst): Change prototype.
- (delta2_from_ptrmemfunc): Remove.
- * expr.c (cplus_expand_constant): Adjust call to
- expand_ptrmemfunc_cst.
- * typeck.c (build_ptrmemfunc1): Simplify.
- (build_ptrmemfunc): Make sure that casting a PTRMEM_CST still
- results in a constant.
- (expand_ptrmemfunc_cst): Remove idx and delta2 parameters.
- (delta2_from_ptrmemfunc): Remove.
- (pfn_from_ptrmemfunc): Adjust call to expand_ptrmemfunc_cst.
-
-2001-04-12 Jason Merrill <jason_merrill@redhat.com>
-
- * cp-tree.h (decl_namespace_list): New macro.
- (struct saved_scope): Add decl_ns_list.
- * decl.c (mark_saved_scope): Mark it.
- * decl2.c: Lose static decl_namespace_list.
- (init_decl2): Don't save it.
-
-2001-04-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * cp-tree.h (warn_return_type, yylex): Delete redundant
- declarations.
-
- * decl.c (current_class_depth, global_namespace): Likewise.
-
- * decl2.c (current_class_depth, flag_gnu_xref): Likewise
-
- * repo.c (flag_use_repository): Likewise.
-
-2001-04-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * cp-tree.h (pedantic, convert, global_bindings_p, insert_block,
- set_block, pushdecl, getdecls, gettags, init_decl_processing,
- maybe_build_cleanup, copy_lang_decl, prep_stmt, lvalue_p,
- lvalue_or_else, print_lang_statistics, comp_target_types,
- unsigned_type, signed_type, signed_or_unsigned_type,
- build_function_call, mark_addressable, incomplete_type_error):
- Delete redundant declarations.
-
-2001-04-11 Jason Merrill <jason_merrill@redhat.com>
-
- * cp-tree.h (TYPE_LINKAGE_IDENTIFIER): New macro.
- (TYPE_ANONYMOUS_P): New macro.
- (TAGGED_TYPE_P): New macro.
- * decl.c (check_tag_decl): Use TYPE_ANONYMOUS_P.
- (grokfndecl, grokvardecl, grokdeclarator): Likewise.
- * tree.c (no_linkage_helper): Likewise.
- * semantics.c (begin_class_definition): Likewise.
- * pt.c (convert_template_argument): Likewise.
- * lex.c (check_for_missing_semicolon): Likewise.
-
-2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (dfs_unshared_virtual_bases): New function.
- (mark_primary_bases): Call it.
- (check_bases): Ignore virtual bases when determining
- nearly-emptiness.
-
-2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
-
- * method.c (make_thunk): Clear DECL_CLONED_FUNCTION.
-
-2001-04-11 Mark Mitchell <mark@codesourcery.com>
-
- * optimize.c (maybe_clone_body): Copy DECL_NUM_STMTS from the
- cloned function to the clone.
-
-2001-04-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * Make-lang.in (cp/semantics.o): Depend on $(EXPR_H).
-
- * semantics.c: Include expr.h.
-
-2001-04-11 Nathan Sidwell <nathan@codesourcery.com>
-
- * method.c (implicitly_declare_fn): Commonize code for copy ctor
- and assignment op. Set TREE_USED for parameter.
-
-2001-04-10 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (find_final_overrider_data): Add `candidates'.
- (dfs_find_final_overrider): Don't issue error messages
- prematurely.
- (find_final_overrider): Issue error messages here.
- (build_base_field): Don't warn about amgibuous direct bases here.
- (warn_about_ambiguous_direct_bases): New function.
- (layout_class_type): Use it.
-
-2001-04-10 Richard Henderson <rth@redhat.com>
-
- * typeck.c (build_array_ref): Push the array reference inside
- COMPOUND_EXPR and COND_EXPR.
-
-2001-04-05 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (DECL_THIS_INLINE): Rename to DECL_DECLARED_INLINE_P.
- * decl.c (duplicate_decls): Adjust accordingly.
- (maybe_commonize_var): Likewise.
- (grokfndecl): Likewise.
- (start_function): Likewise.
- (start_method): Likewise.
- * decl2.c (key_method): Likewise.
- (import_export_decl): Likewise.
- * method.c (implicitly_declare_fn): Likewise.
- * optimize.c (maybe_clone_body): Likewise.
-
-2001-04-05 Benjamin Kosnik <bkoz@redhat.com>
-
- * lang-specs.h: Add __DEPRECATED.
-
-Thu Apr 5 16:54:29 2001 J"orn Rennecke <amylaar@redhat.com>
-
- * search.c (get_dynamic_cast_base_type): When building a new
- constant, set its type to ssizetype.
-
-2001-04-04 Jakub Jelinek <jakub@redhat.com>
-
- * optimize.c (expand_call_inline): Only add newly inlined statements
- into inlined_stmts.
-
-2001-04-03 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (OPERATOR_ASSIGN_FORMAT): Remove.
- (OPERATOR_FORMAT): Likewise.
- (OPERATOR_TYPENAME_FORMAT): Likewise.
- * operators.def: Remove old name-mangling information.
- * decl.c (grok_op_properties): Adjust accordingly.
- * lex.c (init_operators): Likewise.
- * rtti.c (get_tinfo_decl): Issue error messages about types that
- have variable size.
-
-2001-04-03 Mark Mitchell <mark@codesourcery.com>
-
- * decl2.c (import_export_decl): Don't call import_export_class
- when processing an inline member function.
- * semantics.c (expand_body): Call import_export_decl before
- emitting inline functions.
-
-2001-03-28 Richard Henderson <rth@redhat.com>
-
- IA-64 ABI Exception Handling:
- * cp-tree.def (EH_SPEC_BLOCK): New.
- (MUST_NOT_THROW_EXPR): New.
- * cp-tree.h: Update changed function declarations.
- (CPTI_PUSH_EXCEPTION_IDENTIFIER): Remove.
- (CPTI_CALL_UNEXPECTED): New.
- (struct cp_language_function): Rename x_eh_spec_try_block
- to x_eh_spec_block.
- (EH_SPEC_STMTS, EH_SPEC_RAISES): New.
- * decl.c (current_binding_level): If no current function
- bindings, revert to scope_chain.
- (initialize_predefined_identifiers): Remove __cp_push_exception.
- (store_parm_decls): Use begin_eh_spec_block.
- (finish_function): Use finish_eh_spec_block.
- (mark_lang_function): Update for name changes.
- * decl2.c (finish_file): No mark_all_runtime_matches.
- * dump.c (cp_dump_tree): Handle new tree codes.
- * error.c (dump_expr) [BIND_EXPR]: Fix typo.
- * except.c (catch_language_init, catch_language): Remove.
- (init_exception_processing): Don't set language code.
- Initialize call_unexpected_node, protect_cleanup_actions,
- eh_personality_libfunc, lang_eh_runtime_type.
- (call_eh_info, push_eh_info, get_eh_info, get_eh_value): Remove.
- (get_eh_type, get_eh_caught, get_eh_handlers): Remove.
- (prepare_eh_type): Split out type canonicalizations ...
- (build_eh_type_type): ... from here.
- (build_eh_type_type_ref): Remove.
- (mark_all_runtime_matches): Remove.
- (build_exc_ptr): New.
- (do_begin_catch, do_end_catch): New.
- (do_pop_exception): Remove.
- (build_terminate_handler): Remove.
- (choose_personality_routine): Split out language choice from ...
- (initialize_handler_parm): ... here.
- Use MUST_NOT_THROW_EXPR.
- (expand_start_catch_block): Use do_begin_catch. Simplify Java
- exception object handling.
- (expand_start_eh_spec, expand_end_eh_spec): Remove.
- (expand_exception_blocks, alloc_eh_object): Remove.
- (begin_eh_spec_block, finish_eh_spec_block): New.
- (do_allocate_exception, do_free_exception): New.
- (expand_throw): Merge into ...
- (build_throw): ... here. Update for abi.
- * expr.c (cplus_expand_expr): No expand_internal_throw.
- Handle MUST_NOT_THROW_EXPR.
- * pt.c (tsubst_expr): Handle EH_SPEC_BLOCK.
- * semantics.c (*) Update for except.h name changes.
- (genrtl_try_block): No protect_with_terminate.
- (genrtl_eh_spec_block): New.
- (genrtl_handler): Don't emit the goto here.
- (cp_expand_stmt): Handle EH_SPEC_BLOCK.
- (genrtl_finish_function): Don't expand_exception_blocks.
- * tree.c (cp_statement_code_p): Handle EH_SPEC_BLOCK.
-
-2001-03-28 Richard Henderson <rth@redhat.com>
-
- * decl.c (struct named_label_list): Rename eh_region to
- in_try_scope, add in_catch_scope.
- (struct binding_level): Rename eh_region to is_try_scope,
- add is_catch_scope.
- (note_level_for_try): Rename from note_level_for_eh.
- (note_level_for_catch): New.
- (poplevel): Copy both is_try_scope and is_catch_scope to
- the named_label_list struct.
- (check_previous_goto_1): Don't check for catch block via
- DECL_ARTIFICIAL; use in_try_scope instead.
- (check_goto): Likewise.
- * cp-tree.h (note_level_for_try, note_level_for_catch): Declare.
- * except.c (expand_start_catch_block): Call note_level_for_catch.
- * semantics.c (begin_compound_stmt): Update for note_level_for_try.
-
-2001-03-27 Richard Henderson <rth@redhat.com>
-
- * except.c: Use USING_SJLJ_EXCEPTIONS instead of
- exceptions_via_longjmp.
-
-2001-03-27 Phil Edwards <pme@sources.redhat.com>
-
- * pt.c (check_default_tmpl_args): Make error messages clearer.
-
-2001-03-26 Phil Edwards <pme@sources.redhat.com>
-
- * error.c: Also undefine 'A' macro used for cp_printers definition.
-
-2001-03-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * Make-lang.in: Depend on $(SYSTEM_H), not system.h.
-
-2001-03-26 Mike Yang <yang@research.att.com>
- Mark Mitchell <mark@codesourcery.com>
-
- * dump.c (dump_access): New function.
- (cp_dump_tree): Use it. Dump basetype information for class
- types.
-
-2001-03-26 Mark Mitchell <mark@codesourcery.com>
-
- * Makefile.in (optimize.o): Depend on params.h.
- (duplicate_decls): Copy DECL_NUM_STMTS, not DECL_FRAME_SIZE.
- (init_decl_processing): Set flag_no_inline when doing
- inlining-on-trees.
- * optimize.c: Include params.h.
- (struct inline_data): Improve documentation of FNS. Add
- FIRST_INLINED_FN, INLINED_STMTS, and CLONING_P.
- (INSNS_PER_STMT): New macro.
- (remap_block): Use CLONING_P.
- (inlinable_function_p): Don't inline big functions.
- (expand_call_inline): Keep track of how much inlining we've done.
- (optimize_function): Set FIRST_INLINED_FN.
- (maybe_clone_body): Set CLONING_P.
- * semantics.c (simplify_aggr_init_exprs_r): Fix typing problems in
- tree nodes.
- (genrtl_finish_function): Clear DECL_DEFER_OUTPUT before calling
- rest_of_compilation. Clear DECL_RTL for local variables
- afterwards.
- (clear_decl_rtl): New function.
-
-2001-03-26 Nathan Sidwell <nathan@codesourcery.com>
-
- Implement DR 209
- * cp-tree.h (skip_type_access_control,
- reset_type_access_control): Prototype.
- * decl.c (grokdeclarator): Access of friends is not checked.
- * parse.y (component_decl_list): Reset type access control.
- * semantics.c (decl_type_access_control): Clear
- current_type_lookups.
- (save_type_access_control): Don't save if not deferring.
- (skip_type_access_control, reset_type_access_control): New
- functions.
- (begin_class_definition): Do type access control for basetypes.
- Start deferred access control.
- (finish_class_definition): Resume immediate access control if
- this is a local class.
-
-2001-03-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * class.c (add_method): Use memcpy/memmove, not bcopy.
-
- * decl.c (duplicate_decls): Likewise.
-
-2001-03-23 Jakub Jelinek <jakub@redhat.com>
-
- * mangle.c (write_discriminator): Use `_0' for discriminator 1,
- not `_'.
-
-2001-03-23 Jakub Jelinek <jakub@redhat.com>
-
- * decl.c (local_names): Define.
- (push_local_name): New.
- (grok_reference_init): Return init if initializing static reference
- variable with non-constant instead of emitting it.
- Move expand_static_init call to cp_finish_decl.
- (layout_var_decl): Call push_local_name.
- (maybe_commonize_var): Allow inlining functions even if they have
- static local variables, use comdat_linkage for them if flag_weak.
- (check_initializer): Call obscure_complex_init if
- grok_reference_init returned nonzero.
- (save_function_data): Clear x_local_names.
- (pop_cp_function_context): Free x_local_names.
- (mark_inlined_fns): Remove.
- (mark_lang_function): Mark x_local_names.
- (lang_mark_tree): Don't mark DECL_ACCESS for DECL_DISCRIMINATOR_P.
- Mark inlined_fns as tree, remove call to mark_inlined_fns.
- * class.c (alter_access): Ensure DECL_ACCESS is never set if
- DECL_DISCRIMINATOR_P.
- * cp-tree.h (cp_language_function): Add x_local_names.
- (lang_decl_flags): Add discriminator into u2.
- (lang_decl_inlined_fns): Remove.
- (lang_decl): inlined_fns is now a TREE_VEC.
- (DECL_DISCRIMINATOR_P, DECL_DISCRIMINATOR): Define.
- * optimize.c (inlinable_function_p): DECL_INLINED_FNS is now a
- TREE_VEC, not a custom structure.
- (optimize_function): Likewise.
- * mangle.c (discriminator_for_local_entity): Discriminate among
- VAR_DECL local entities.
- * search.c (dfs_access_in_type): If DECL_DISCRIMINATOR_P, DECL_ACCESS
- is not valid.
-
-2001-03-22 Bryce McKinlay <bryce@albatross.co.nz>
-
- Add support for Java interface method calls.
- * cp-tree.h (struct lang_type): Add java_interface flag.
- (TYPE_JAVA_INTERFACE): New macro.
- * tree.c (cp_valid_lang_attribute): Handle "java_interface" attribute
- by setting TYPE_JAVA_INTERFACE.
- * call.c (java_iface_lookup_fn): New static.
- (build_over_call): If calling a method declared in a
- TYPE_JAVA_INTERFACE, call build_java_interface_fn_ref to generate the
- expression which resolves the function address.
- (build_java_interface_fn_ref): New function.
-
-2001-03-22 Richard Henderson <rth@redhat.com>
-
- * Make-lang.in (cp/except.o): Don't depend on insn-flags.h.
- * except.c: Don't include it.
-
-2001-03-22 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
- based on an idea from Joe Buck <jbuck@synopsys.com>
-
- * parse.y (bad_decl, template_arg_list_ignore, arg_list_ignore):
- New nonterminals.
- (data_def, component_decl): Add reductions to bad_decl.
-
-2001-03-22 Jakub Jelinek <jakub@redhat.com>
-
- * method.c (do_build_assign_ref): Don't use build_modify_expr for
- anonymous aggregates, since they don't have assignment operator
- method.
- * decl.c (fixup_anonymous_aggr): Disallow ctors, dtors and copy
- assignment operators for anonymous structure fields.
-
-2001-03-21 Jason Merrill <jason@redhat.com>
-
- * pt.c (instantiate_decl): Abort if we see a member constant
- instantiation that doesn't already have its initializer.
- Downgrade explicit instantiation without definition to pedwarn.
-
- * cp-tree.h (DECL_TINFO_FN_P, SET_DECL_TINFO_FN_P): Remove.
- * class.c (build_vtable_entry): Don't check DECL_TINFO_FN_P.
- (import_export_decl): Check tinfo_decl_p, not DECL_TINFO_FN_P.
-
- * cp-tree.h (CLASSTYPE_VTABLE_NEEDS_WRITING): Remove.
- (pending_vtables): Remove.
- * decl2.c (pending_vtables): Remove.
- (import_export_vtable): Use CLASSTYPE_INTERFACE_ONLY, not
- CLASSTYPE_VTABLE_NEEDS_WRITING.
- (import_export_class): Likewise.
- (init_decl2): Don't mark pending_vtables.
- * lex.c (handle_pragma_vtable): Just sorry.
- * pt.c (instantiate_class_template): Don't mess with
- CLASSTYPE_VTABLE_NEEDS_WRITING.
- (mark_class_instantiated): Likewise.
- * ptree.c (print_lang_type): Don't print it.
- * semantics.c (begin_class_definition): Don't set it.
-
- * pt.c (template_tail): Replace with last_pending_template.
- (maybe_templates, maybe_template_tail): Remove.
- (add_pending_template): Adjust.
- (instantiate_pending_templates): Adjust.
-
- * cp-tree.h (struct saved_scope): Remove lang_stack field.
- (current_lang_stack): Remove.
- * decl.c (maybe_push_to_top_level): Don't initialize it.
- (duplicate_decls): Use current_lang_depth.
- (xref_basetypes): Likewise.
- * class.c (current_lang_depth): New fn.
- (push_lang_context): Use more varray functionality.
- (pop_lang_context): Likewise.
-
- * error.c (GLOBAL_THING): Always use '__'.
-
-2001-03-21 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (build_clone): Clear DECL_ASSEMBLER_NAME.
-
- * mangle.c (mangle_decl_string): Mangle the names of overloaded
- operators, even when they have `extern "C"' linkage.
-
-2001-03-19 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (get_vtable_decl): Use SET_DECL_ASSEMBLER_NAME,
- COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
- where it's not necessary.
- (add_method): Remove optimization involving comparison of
- DECL_ASSEMBLER_NAME.
- (build_vtbl_or_vbase_field): Use SET_DECL_ASSEMBLER_NAME,
- COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
- where it's not necessary.
- (check_methods): Likewise.
- (build_clone): Likewise.
- (built_vtt): Likewise.
- * cp-tree.h (DECL_NEEDED_P): Likewise.
- * decl.c (pushtag): Likewise.
- (duplicate_decls): Likewise.
- (pushdecl): Likewise.
- (builtin_function): Likewise.
- (build_library_fn_1): Set DECL_LANGUAGE for library functions.
- (build_cp_library_fn): Likewise.
- (maybe_commonize_var): Use SET_DECL_ASSEMBLER_NAME,
- COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
- where it's not necessary.
- (make_rtl_for_nonlocal_decl): Likewise.
- (cp_finish_decl): Likewise.
- (grokfndecl): Likewise.
- (grokvardecl): Likewise.
- (grokdeclarator): Likewise.
- (start_function): Likewise.
- (cp_missing_return_ok_p): Likewise.
- * decl2.c (grokclassfn): Likewise.
- (check_classfn): Likewise.
- (finish_static_data_member_decl): Likewise.
- (grokfield): Likewise.
- * error.c (GLOBAL_IORD_P): Remove.
- (dump_global_iord): Improve output.
- (dump_decl): Avoid using DECL_ASSEMBLER_NAME.
- * except.c (nothrow_libfn_p): Summarily reject any function not in
- namespace-scope.
- * init.c (build_java_class_ref): Don't explicitly set
- DECL_ASSEMBLER_NAME after calling mangle_decl.
- * mangle.c (mangle_decl_string): Handle extern "C" functions.
- (mangle_decl): Set the DECL_ASSEMBLER_NAME for the decl.
- * method.c (set_mangled_name_for_decl): Don't explicitly set
- DECL_ASSEMBLER_NAME after calling mangle_decl.
- (make_thunk): Explicitly set the DECL_ASSEMBLER_NAME and
- IDENTIFIER_GLOBAL_VALUE for the thunk.
- * pt.c (set_mangled_name_for_template_decl): Remove.
- (check_explicit_specialization): Don't use it.
- (looup_template_class): Don't set DECL_ASSEMBLER_NAME.
- (tsubst_friend_function): Likewise.
- (tsubst_decl): Likewise.
- (regenerate_decl_from_template): Use COPY_DECL_ASSEMBLER_NAME.
- * rtti.c (get_tinfo_decl): Use SET_DECL_ASSEMBLER_NAME,
- COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
- where it's not necessary.
- (tinfo_base_init): Likewise.
- (create_real_tinfo_var): Likewise.
- * search.c (looup_field_1): Likewise.
- * semantics.c (finish_named_return_value): Likewise.
- * tree.c (init_tree): Set lang_set_decl_assembler_name.
-
-2001-03-15 Gabriel Dos Reis <gdr@codesourcery.com>
-
- Correct semantics restrictions checking in throw-expression.
- * except.c (is_admissible_throw_operand): New function.
- (build_throw): Use it.
-
-2001-03-14 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (cp_make_fnname_decl): Set DECL_IGNORED_P on __FUNCTION__
- and its ilk.
-
-2001-03-14 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (build_clone): Use COPY_DECL_RTL, DECL_RTL_SET_P, etc.
- * cp-tree.h (DECL_IN_MEMORY_P): Likewise.
- * decl.c (duplicate_decls): Likewise.
- (builtin_function): Likewise.
- (build_library_fn): Likewise.
- (build_cp_library_fn): Likewise.
- (check_initializer): Likewise.
- (cp_finish_decl): Likewise.
- * decl2.c (grokfield): Likewise.
- (grok_function_init): Remove #if 0'd code.
- (finish_anon_union): Use COPY_DECL_RTL, DECL_RTL_SET_P, etc.
- * friend.c (do_friend): Likewise.
- * init.c (get_temp_regvar): Likewise.
- * method.c (make_thunk): Likewise.
- * pt.c (tsubst_friend_function): Likewise.
- (tsubst_decl): Likewise.
- (regenerate_decl_from_template): Likewise.
- * semantics.c (genrtl_named_return_value): Likewise.
- (expand_body): Likewise.
- (genrtl_finish_function): Likewise.
- * tree.c (cp_tree_equal): Likewise.
-
-2001-03-12 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (convert_like_real): Add extra semantics to INNER
- parameter. Don't convert to temporary if a user conversion
- gives us an lvalue that we're about to bind to a reference.
- Set INNER to indicate pending reference binding on recursive
- calls.
-
-2001-03-10 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp/lex.c: Delete duplicate pending_lang_change.
-
-2001-03-10 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp/lex.c (handle_pragma_interface, handle_pragma_implementation):
- Similarly.
- * cp/repo.c (get_base_filename, open_repo_file): Similarly.
- * cp/cp-tree.h: Remove file_name_nondirectory prototype.
-
-2001-03-09 Zack Weinberg <zackw@stanford.edu>
-
- * Make-lang.in: Add dependencies on $(TM_P_H) as appropriate.
-
-2001-03-08 Stan Shebs <shebs@apple.com>
-
- * cp-tree.h (set_identifier_local_value): Remove unused decl.
-
-2001-03-06 Zack Weinberg <zackw@stanford.edu>
-
- * spew.c: Remove references to CPP_OSTRING.
-
-2001-03-06 Andrew Haley <aph@redhat.com>
-
- * typeck.c (convert_arguments): Check that we have an fndecl.
-
-2001-03-05 Andrew Haley <aph@redhat.com>
-
- * typeck.c (convert_arguments): Don't do ellipsis conversion for
- __built_in_constant_p.
-
-2001-03-02 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck.c (build_static_cast): Allow enum to enum conversions
- as per DR 128.
-
-2001-03-02 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (check_field_decls): Pointers to member do not a
- non-pod struct make, as per DR 148.
-
-2001-03-02 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (joust): cp_pedwarn when using gnu extension concerning
- worst conversion sequences.
-
-2001-03-01 Zack Weinberg <zackw@stanford.edu>
-
- * decl.c: Replace all uses of 'boolean' with 'bool'.
-
-2001-03-01 Zack Weinberg <zackw@stanford.edu>
-
- * lang-specs.h: Add zero initializer for cpp_spec field to
- all array elements that need one. Don't put an #ifdef inside
- the initializer list; set a default for CPLUSPLUS_CPP_SPEC and
- use it.
-
-2001-03-01 Nathan Sidwell <nathan@codesourcery.com>
-
- Implement using decls inside template functions.
- * decl2.c (validate_nonmember_using_decl): Don't special case
- fake_std_node in the global namespace. Don't reject early when
- processing a template.
- (do_local_using_decl): Add to statement tree. Don't do further
- processing when building a template.
- * pt.c (tsubst_expr, DECL_STMT case): Deal with USING_DECLs.
-
-2001-03-01 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl2.c (do_nonmember_using_decl): Don't complain if we find
- same function. Do complain about ambiguating extern "C"
- declarations.
-
-2001-02-28 Nathan Sidwell <nathan@codesourcery.com>
-
- Remove floating point and complex type template constant parms.
- * pt.c (convert_nontype_argument): Remove REAL_TYPE and
- COMPLEX_TYPE extensions.
- (invalid_nontype_parm_type_p): Likewise.
-
-2001-02-27 Jeffrey Oldham <oldham@codesourcery.com>
-
- * except.c (call_eh_info): Revert "match_function"'s type.
-
-2001-02-27 Nathan Sidwell <nathan@codesourcery.com>
-
- Fix ctor vtable vcall offsets.
- * class.c (struct vtbl_init_data_s): Add rtti_binfo member.
- (build_rtt_vtbl_entries): Lose RTTI_BINFO parameter.
- (get_matching_base): Remove.
- (get_original_base): New function.
- (build_vtbl_initializer): Initialize vid.rtti_binfo.
- Use a virtual thunk for a ctor vtable with an index
- (add_vcall_offset_vtbl_entries_1): Check if binfo has lost a
- primary base within a constructor vtable. Only set
- BV_VCALL_INDEX when not a constructor vtable. Adjust vcall offset
- when primary base has been lost.
- * cp-tree.h (BINFO_VIRTUALS): Remove ambiguity from comment.
-
-2001-02-26 Jeffrey Oldham <oldham@codesourcery.com>
-
- * call.c (joust): Ensure more_specialized()'s argument length
- parameter has correct value for constructors.
-
-2001-02-26 Nathan Sidwell <nathan@codesourcery.com>
-
- * except.c (call_eh_info): Cleanup generation of cp_eh_info struct.
-
- * decl.c (mark_inlined_fns): Prototype.
-
-2001-02-22 Mark Mitchell <mark@codesourcery.com>
-
- * spew.c (yylex): Correct handling of friends.
-
-2001-02-22 Mark Mitchell <mark@codesourcery.com>
-
- * mangle.c (write_encoding): Pass write_function_type the
- FUNCTION_DECL for the function being encoded.
- (write_function_type): Pass it along to write_bare_function_type.
- (write_bare_function_type): Pass it along to write_method_parms.
- (write_method_parms): Don't mangle the compiler-generated
- parameters to a constructor or destructor.
-
-2001-02-22 Andreas Jaeger <aj@suse.de>
-
- * optimize.c: Include toplev.h for
- note_deferral_of_defined_inline_function prototype.
-
-2001-02-22 Jakub Jelinek <jakub@redhat.com>
-
- * cp-tree.h (struct lang_decl_inlined_fns): New.
- (struct lang_decls): Add inlined_fns.
- (DECL_INLINED_FNS): New macro.
- * optimize.c (struct inline_data): Add inlined_fns.
- (declare_return_variable): Use VARRAY_ACTIVE_SIZE macro.
- (inlinable_function_p): Likewise, fix typo in comment,
- function is not inlinable if it already inlined function currently
- being optimized.
- (expand_call_inline): Add fn to inlined_fns if necessary.
- (optimize_function): Initialize inlined_fns.
- Save inlined_fns into DECL_INLINED_FNS after expanding inlines.
- * decl.c (mark_inlined_fns): New function.
- (lang_mark_tree): Call it.
-
-2001-02-21 Jason Merrill <jason@redhat.com>
-
- * cp-tree.h (struct lang_decl_flags): Remove uninlinable flag.
- (DECL_UNINLINABLE): Move to middle-end.
-
- * class.c (clone_function_decl): Set DECL_ABSTRACT on original fn.
- * decl.c (duplicate_decls): Preserve DECL_ABSTRACT.
- * class.c (build_clone): Set DECL_ABSTRACT_ORIGIN for the clone.
- * optimize.c (maybe_clone_body): Set DECL_ABSTRACT_ORIGIN for the
- parms and outer BLOCK. note_deferral_of_defined_inline_function.
-
- * method.c (implicitly_declare_fn): Don't set DECL_ARTIFICIAL on
- second parm of op=.
-
-2001-02-19 Mark Mitchell <mark@codesourcery.com>
-
- * decl2.c (set_decl_namespace): Allow explicit instantiations in
- any namespace.
-
-2001-02-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * optimize.c (expand_call_inline): Don't walk subtrees of type
- nodes.
-
-2001-02-18 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (add_vcall_offset_vtbl_entries_1): Only add one entry
- for a destructor.
-
-2001-02-18 Jason Merrill <jason@redhat.com>
-
- Do put the VTT parameter in DECL_ARGUMENTS.
- * cp-tree.h (struct cp_language_function): Add x_vtt_parm.
- (current_vtt_parm): New macro.
- (struct lang_decl_flags): Add has_vtt_parm_p, remove vtt_parm.
- (DECL_HAS_VTT_PARM_P): New macro.
- (DECL_VTT_PARM): Remove.
- (FUNCTION_FIRST_USER_PARMTYPE, FUNCTION_FIRST_USER_PARM): New macros.
- * decl.c (duplicate_decls): Only copy the operator code if
- appropriate.
- (start_function): Set current_vtt_parm.
- (lang_mark_tree): Don't mark vtt_parm.
- * decl2.c (maybe_retrofit_in_chrg): Do add the VTT parm to
- DECL_ARGUMENTS. Set DECL_HAS_VTT_PARM_P.
- * class.c (build_clone): Maybe remove the VTT parm.
- * optimize.c (maybe_clone_body): Set up the VTT parm.
- * pt.c (copy_default_args_to_explicit_spec): Preserve the VTT parm.
- * call.c (build_over_call): Just allow the VTT arg.
- * method.c (make_thunk): Don't set DECL_VTT_PARM.
- (do_build_copy_constructor): Use FUNCTION_FIRST_USER_PARM.
- (synthesize_method): Use FUNCTION_FIRST_USER_PARMTYPE.
- * decl.c (grokdeclarator, copy_args_p, grok_ctor_properties): Likewise.
- * error.c (dump_function_decl): Likewise.
- * call.c (build_user_type_conversion_1, convert_like_real): Abort
- if we try to call a constructor with in-charge or VTT parms.
- * method.c (skip_artificial_parms_for): New fn.
- * call.c (add_function_candidate, build_over_call): Call it.
- * call.c (build_new_method_call): Use current_vtt_parm.
- * init.c (expand_virtual_init): Likewise.
- * class.c (same_signature_p): No longer static.
- * cp-tree.h: Declare it.
- * search.c (look_for_overrides_r): Use it.
-
-2001-02-17 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (new_abi_rtti_p): Remove.
- (name_mangling_version): Likewise.
- (flag_do_squangling): Likewise.
- * class.c (build_rtti_vtbl_entries): Remove old ABI support.
- * decl.c (grokfndecl): Likewise.
- * decl2.c (name_mangling_version): Remove.
- (flag_do_squangling): Likewise.
- (lang_f_options): Remove `squangle'.
- (unsupported_options): Add `squangle'.
- (cxx_decode_option): Issue a warning about uses of
- -fname-mangling-version.
- (finish_file): Remove old ABI support.
- * pt.c (check_explicit_specialization): Likewise.
- (tsubst_decl): Likewise.
- * rtti.c (init_rtti_processing): Likewise.
- (build_headof): Likewise.
- (get_tinfo_decl_dynamic): Likewise.
- (tinfo_from_decl): Likewise.
- (build_dynamic_cast_1): Likewise.
- (synthesize_tinfo_var): Likewise.
- * init.c (build_new): Allow enumeration types for the array-bounds
- in a direct-new-declarator.
-
- * semantics.c (finish_typeof): Resolve OFFSET_REFs.
-
- * pt.c (check_explicit_specialization): Copy TREE_PRIVATE and
- TREE_PROTECTED from the template being specialized.
-
-2001-02-17 Jason Merrill <jason@redhat.com>
-
- * decl2.c (build_artificial_parm): Set TREE_READONLY.
-
- * decl.c (bad_specifiers): Allow throw specs on things with
- pointer-to-function or -member-function type.
- * init.c (build_default_init): Don't use a CONSTRUCTOR to initialize
- a pmf.
-
-2001-02-17 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (check_dtor_name): Handle template names correctly.
-
-2001-02-16 Jason Merrill <jason@redhat.com>
-
- * cp-tree.h (DECL_USE_VTT_PARM): Remove.
- * decl2.c (maybe_retrofit_in_chrg): Don't create it.
- * optimize.c (maybe_clone_body): Don't substitute it.
- * call.c (build_new_method_call): Check in_chrg instead.
- * init.c (expand_virtual_init): Likewise.
-
-2001-02-16 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * decl.c (check_tag_decl): Make sure a typedef for an anonymous
- class-type introduces at least a type-name.
-
-2001-02-16 Jakub Jelinek <jakub@redhat.com>
-
- * call.c (convert_like_real): Create a temporary for non-lvalue.
-
-2001-02-16 Jeffrey Oldham <oldham@codesourcery.com>
-
- * cp-tree.h: Fix typos in comments.
-
-2001-02-16 Jason Merrill <jason@redhat.com>
-
- * optimize.c (remap_block): If we're compiling a clone, pass the
- new block to insert_block.
-
-2001-02-16 Mark Mitchell <mark@codesourcery.com>
-
- * semantics.c (finish_asm_stmt): Robustify.
-
-2001-02-15 Mark Mitchell <mark@codesourcery.com>
-
- * pt.c (push_template_decl_real): Don't remangle the name of a
- class template.
-
-2001-02-15 Jim Meyering <meyering@lucent.com>
-
- * Make-lang.in (c++.install-common): Depend on installdirs.
- (c++.install-info): Likewise.
- (c++.install-man): Likewise.
-
-2001-02-15 Mark Mitchell <mark@codesourcery.com>
-
- * typeck2.c (build_m_component_ref): Robustify.
-
-2001-02-15 Alexandre Oliva <aoliva@redhat.com>
-
- * friend.c (do_friend): Don't take the nested [template] class
- into account when deciding whether to warn about the friend
- function not referring to a template function.
-
-2001-02-14 Jakub Jelinek <jakub@redhat.com>
-
- * typeck.c (build_unary_op): Clarify error message.
-
-2001-02-08 Aldy Hernandez <aldyh@redhat.com>
-
- * parse.y (component_constructor_declarator): allow optional
- parentheses around constructor class name.
-
-2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (setup_vtbl_ptr): Move prototype to semantics.c
- section.
- * init.c (emit_base_init): Remove incorrect comment about
- virtual bases.
- * method.c (make_thunk): Fix comment alignment.
-
-2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
-
- Kill remnants of this is variable.
- * cp-tree.h (flag_this_is_variable): Remove.
- * decl2.c (flag_this_is_variable): Remove.
- * class.c (fixed_type_or_null): Add cdtor parm. Adjust.
- (build_vbase_path): The path is non-static, even in a cdtor.
- (resolves_to_fixed_type_p): Add additional return value.
- * search.c (init_vbase_pointers): Adjust.
- * tree.c (lvalue_p_1): Adjust.
- * typeck.c (mark_addressable): Adjust.
-
-2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (unify): Don't check cv quals of array types.
-
-2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
-
- * tree.c (cp_build_qualified_type_real): Use CP_TYPE_QUALS to
- check whether we already have the type.
-
-2001-02-13 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (CLASSTYPE_DESTRUCTORS): Fix typo in comment.
- * call.c (build_op_delete_call): Simplify to remove duplicate
- code.
- * class.c (clone_function_decl): Don't build the deleting variant
- of a non-virtual destructor.
- * decl.c (finish_destructor_body): Don't call delete if this is a
- non-virtual destructor.
- * init.c (build_delete): Explicitly call `operator delete' when
- deleting an object with a non-virtual destructor.
-
-2001-02-13 Jason Merrill <jason@redhat.com>
-
- * lang-specs.h: Add more __EXCEPTIONS.
-
-2001-02-12 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck2.c (process_init_constructor): Check
- TREE_HAS_CONSTRUCTOR before issuing missing init warning.
-
-2001-02-12 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (maybe_adjust_types_for_deduction, DEDUCE_ORDER case):
- Remove spurious information in comment. Allow further
- adjustments of REFERENCE_TYPE args.
-
-2001-02-12 Nathan Sidwell <nathan@codesourcery.com>
-
- * errfn.c (cp_deprecated): Tweak diagnostic text.
- * parse.y (new_initializer): Deprecate initializer lists
- extension.
-
-2001-02-12 Mark Mitchell <mark@codesourcery.com>
-
- Remove old ABI support.
-
-2001-02-11 Mark Mitchell <mark@codesourcery.com>
-
- * decl2.c (flag_vtable_thunks): Always set it to 1.
- (flag_new_abi): Likewise.
- * lang-specs.h: Remove conditional on ENABLE_NEW_GXX_ABI.
-
- * Makefile.in (g++spec.o): Fix typo.
-
-2001-02-09 Jason Merrill <jason@redhat.com>
-
- * lang-specs.h: Restore definition of __EXCEPTIONS.
-
-2001-02-08 Jason Merrill <jason@redhat.com>
-
- * search.c (shared_member_p): New function.
- (lookup_field_r): Use it.
- * cp-tree.h (SHARED_MEMBER_P): Remove.
-
- * method.c (process_overload_item): Handle template-dependent array
- bounds.
- * pt.c (type_unification_real): If we end up with undeduced nontype
- parms, try again.
-
- * decl.c (lookup_name_real): Tweak warning to refer to decls, not
- types.
-
- * typeck2.c (friendly_abort): Don't say anything if we have
- earlier errors or sorries.
-
- * decl.c (check_tag_decl): Notice attempts to redefine bool and
- wchar_t. Ignore if in_system_header.
-
- * decl.c (maybe_push_cleanup_level): New fn...
- (start_decl_1): ...split out from here.
- * cvt.c (build_up_reference): Use it.
- * cp-tree.h: Declare it.
-
-2001-02-07 Mark Mitchell <mark@codesourcery.com>
-
- * lang-specs.h: Use CPLUSPLUS_CPP_SPEC for the preprocessor
- spec.
-
-2001-02-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (lookup_template_class): Make sure it's a primary
- template or template_template_parm when called from the parser.
- (instantiate_template_class): Add assertion.
-
-2001-02-05 Alexandre Oliva <aoliva@redhat.com>
-
- * method.c (build_mangled_name) [old abi]: Protect flush_repeats()
- from error_mark_node.
-
-2001-02-05 Nathan Sidwell <nathan@codesourcery.com>
-
- Fix specification and implementation bugs in V3 ABI
- construction vtables.
- * cp-tree.h (flag_dump_class_layout): New flag.
- (BINFO_OVERRIDE_ALONG_VIRTUAL_PATH_P): Remove.
- (BINFO_LOST_PRIMARY_P): New flag.
- (SET_BINFO_NEW_VTABLE_MARKED): Adjust asserts.
- (BINFO_PRIMARY_MARKED_P): Rename to ...
- (BINFO_PRIMARY_P): ... here.
- (binfo_via_virtual): New prototype.
- * decl2.c (flag_dump_class_layout): New flag.
- (cxx_decode_option): Set it. Adjust -fdump-translation-unit to
- use `=' as a file name separator.
- * init.c (dfs_initialize_vtbl_ptrs): Walk into virtual primary
- bases.
- (build_vtbl_address): If this is a virtual primary base, then
- get the vtbl of what it is ultimately primary for.
- * search.c (dfs_skip_nonprimary_vbases_unmarkedp): Adjust
- for BINFO_PRIMARY_P.
- (dfs_skip_nonprimary_vbases_markedp): Likewise.
- (get_shared_vbase_if_not_primary): Likewise.
- (dfs_get_pure_virtuals): Likewise.
- (expand_upcast_fixups): Likewise.
- (fixup_virtual_upcast_offsets): Likewise.
- (dfs_find_vbase_instance): Likewise.
- (find_vbase_instance): Likewise.
- (binfo_from_vbase): Adjust comment to reflect reality.
- (binfo_via_virtual): New function.
- * class.c (VTT_TOP_LEVEL_P, VTT_MARKED_BINFO_P): New macros
- for binfo walking during VTT construction.
- (dfs_mark_primary_bases): Remove.
- (force_canonical_binfo_r): New function.
- (force_canonical_binfo): New function.
- (mark_primary_virtual_base): New function.
- (mark_primary_bases): Walk in inheritance graph order, use
- mark_primary_virtual_base.
- (determine_primary_base): Use some more intermediate variables.
- (dfs_find_final_overrider): Don't check for overriding along a
- virtual path.
- (dfs_modify_vtables): Walk into primary virtual bases too.
- (walk_subobject_offsets): Adjust for BINFO_PRIMARY_P.
- (build_base_fields): Likewise.
- (dfs_set_offset_for_unshared_vbases): Likewise.
- (layout_virtual_bases): Likewise.
- (end_of_class): Likewise.
- (finish_struct_1): Call dump_class_hierarchy, if requested.
- (dfs_get_primary_binfo): Use BINFO_TYPE for binfos.
- (dump_class_hierarchy_r): Add stream parameter. Emit more information.
- (dump_class_hierarchy): Add file parameter. Append to file, if
- required.
- (finish_vtbls): Adjust accumulate_vtbl_inits call.
- Use canonical base for virtual bases.
- (build_vtt): Add more comments. Adjust build_vtt_inits call.
- (build_vtt_inits): Remove VIRTUAL_VTTS_P parm.
- Only set BINFO_VPTR_INDEX on top level. Use VTT_TOP_LEVEL_P,
- VTT_MARKED_BINFO_P for binfo walking. Use canonical vbase for
- virtual VTTs.
- (dfs_build_secondary_vptr_vtt_inits): Extract VTT_TOP_LEVEL_P
- from DATA. We want virtual primary bases and all bases via virtual.
- Only set BINFO_VPTR_INDEX for top level. Look up from a primary
- virtual base when not a construction vtable.
- (dfs_ctor_vtable_bases_queue_p): New DFS predicate.
- (build_ctor_vtbl_group): Adjust accumulate_vtbl_inits call.
- Use canonical bases when processing virtual bases.
- (accumulate_vtbl_inits): We're interested in any base via a
- virtual path.
- (dfs_accumulate_vtbl_inits): If this is a primary virtual base
- within a construction vtable, determine what is being overridden.
- (build_vtbl_initializer): Add more comments
- (add_vcall_offset_vtbl_entries_1): Adjust comment.
- (build_rtti_vtbl_entries): Check if the base has lost its
- primary.
-
-2001-02-05 Mark Mitchell <mark@codesourcery.com>
-
- * Makefile.in (g++spec.o): Adjust use of DRIVER_DEFINES.
-
-Sun Feb 4 15:52:44 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * decl.c (pushdecl): Call abort instead of fatal.
- * except.c (decl_is_java_type): Call fatal_error instead of fatal.
- * init.c (build_new_1): Likewise.
- (build_java_class_ref): Call internal_error and fatal_error, not fatal.
- * decl.c (build_typename_type): hash_table_init now returns void.
- decl.c (init_decl_processing): Make an error non-fatal.
-
-2001-02-04 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (CLASSTYPE_INTERFACE_UNKNOWN): Fix formatting.
- Document.
- (CLASSTYPE_INTERFACE_KNOWN): Likewise.
- (SET_CLASSTYPE_INTERFACE_UNKNOWN_X): Likewise.
- (SET_CLASSTYPE_INTERFACE_UNKNOWN): Likewise.
- (SET_CLASSTYPE_INTERFACE_KNOWN): Likewise.
- * decl.c (maybe_commonize_var): Use the new name-mangling where
- appropriate.
- * decl2.c (comdat_linkage): Enhance comments. Make all
- compiler-generated things static, if COMDAT is not available.
- (get_tinfo_decl): Do not make typeinfo objects that belong in the
- library COMDAT.
- (tinfo_base_init): Use the correct mangled name for typeinfo
- strings, and push them into the global scope.
- (typeinfo_in_lib_p): New function.
- (synthesize_tinfo_var): Use it.
- (create_real_tinfo_var): Likewise.
-
-2001-02-03 Jakub Jelinek <jakub@redhat.com>
-
- * decl.c (push_class_binding): Use context_for_name_lookup instead
- of CP_DECL_CONTEXT.
- * search.c (context_for_name_lookup): Remove static. Check for NULL
- context in the loop.
- * cp-tree.h (context_for_name_lookup): Add prototype.
-
-2001-02-02 Jakub Jelinek <jakub@redhat.com>
-
- * cp-tree.h (build_expr_ptr_wrapper, can_free): Remove.
- * tree.c (build_expr_ptr_wrapper, can_free, permanent_obstack):
- Remove.
- * call.c (convert_class_to_reference, build_user_type_conversion_1,
- add_warning): Change build_expr_ptr_wrapper to build_ptr_wrapper.
-
-2001-02-02 Mark Mitchell <mark@codesourcery.com>
-
- * Make-lang.in (g++spec.o): Add DRIVER_DEFINES to the list
- of macros used when compiling g++spec.c.
- * g++spec.c (lang_specific_driver): Link with the shared
- libgcc by default.
-
-2001-01-29 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl2.c (build_expr_from_tree), lex.c (make_pointer_declarator,
- make_reference_declarator, make_call_declarator), method.c
- (implicitly_declare_fn), parse.y (namespace_using_decl,
- notype_unqualified_id, expr_or_declarator, new_type_id,
- after_type_declarator, direct_after_type_declarator,
- notype_declarator, complex_notype_declarator,
- complex_direct_notype_declarator, qualified_id,
- notype_qualified_id, overqualified_id, direct_new_declarator,
- absdcl, direct_abstract_declarator, conversion_declarator), pt.c
- (tsubst), semantics.c (begin_constructor_declarator): Use build_nt
- instead of build_parse_node.
-
-2001-01-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * cp-tree.h (cp_tree_index): Delete CPTI_MINUS_ONE.
- (minus_one_node): Moved to top level gcc directory. Renamed
- to integer_minus_one_node.
-
- * init.c (init_init_processing): Don't set minus_one_node.
- (build_vec_init): Use integer_minus_one_node.
-
- * rtti.c (get_tinfo_decl_dynamic): Likewise.
-
-2001-01-28 Jakub Jelinek <jakub@redhat.com>
-
- * optimize.c (copy_body_r): If MODIFY_EXPR has both arguments
- identical and they would be replaced with constant, remove
- MODIFY_EXPR from the tree.
-
-2001-01-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * Make-lang.in: Remove all dependencies on defaults.h.
- * call.c: Don't include defaults.h.
- * decl.c: Likewise.
- * decl2.c: Likewise.
- * except.c: Likewise.
- * pt.c: Likewise.
- * rtti.c: Likewise.
- * tree.c: Likewise.
- * typeck.c: Likewise.
-
-2001-01-25 Jakub Jelinek <jakub@redhat.com>
-
- * mangle.c (write_mangled_name, write_encoding): Mangle overloaded
- operators even in "C" linkage.
- * method.c (set_mangled_name_for_decl): Likewise.
- * decl.c (grokfndecl): Call set_mangled_name_for_decl even for
- overloaded operators in "C" linkage.
-
-2001-01-24 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (tsubst_decl): Remove IN_DECL parameter.
- (tsubst_arg_types): Check parameter is not void.
- (tsubst): Adjust tsubst_decl call.
-
-2001-01-24 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (add_builtin_candidate): Quote std properly, from
- previous change.
-
-2001-01-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (check_explicit_specialization): Clone constructors and
- destructors.
-
-2001-01-23 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (grokdeclarator): Don't presume DECL_LANG_SPECIFIC
- indicates anything special about template depth. Make sure we
- only count the user visible template classes.
-
-2001-01-23 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (build_conv): Typo in comment.
- (add_builtin_candidate): Add more explanation.
- Remove extra test for ENUMERAL_TYPE in {PRE,POST}INCREMENT_EXPR.
- Allow ENUMERAL_TYPEs for relops and eqops. Add both candidates
- when we have enumeral types.
- (add_builtin_candidates): Add more explanation. Add ENUMERAL_TYPE
- candidates for relops and eqops.
- (joust): Simplify control flow. Allow a non-template user
- function to hide a builtin.
-
-2001-01-22 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (unification_kind_t): Add DEDUCE_ORDER.
- (more_specialized): Add deduction parameter.
- * call.c (joust): Adjust more_specialized call.
- * pt.c (UNIFY_ALLOW_OUTER_MORE_CV_QUAL,
- UNIFY_ALLOW_OUTER_LESS_CV_QUAL): New unify flags.
- (get_bindings_order): Remove.
- (get_bindings_real): Add DEDUCE parameter.
- (maybe_adjust_types_for_deduction): Return extra unify flags. Do
- REFERENCE_TYPE jig for DEDUCE_ORDER.
- (type_unification_real): Deal with DEDUCE_ORDER. Use result of
- maybe_adjust_types_for_deduction.
- (more_specialized): Add DEDUCE parameter. Call get_bindings_real
- directly.
- (try_one_overload): Use result of maybe_adjust_types_for_deduction.
- (check_cv_quals_for_unify): Use new unify qualifier flags.
- (unify): Clear new unify qualifier flags.
- (get_bindings_real): Add DEDUCE parameter.
- (get_bindings): Adjust call to get_bindings_real.
- (get_bindings_overload): Likewise.
- (most_specialized_instantiation): Adjust call to
- more_specialized.
-
-2001-01-19 Jason Merrill <jason@redhat.com>
-
- * decl2.c (flag_vtable_thunks): Also depend on ENABLE_NEW_GXX_ABI.
-
- * decl.c (init_decl_processing): Just force -fvtable-thunks on if
- -fnew-abi.
-
-2001-01-19 Ute Pelkmann <scope.muc@t-online.de>
-
- * decl2.c (arg_assoc_class): Fix double iteration logic.
-
-2001-01-19 Jason Merrill <jason@redhat.com>
-
- * init.c (build_delete): Always call convert_force to strip cv-quals.
-
- * decl2.c (flag_new_abi): Depend on ENABLE_NEW_GXX_ABI.
- * lang-specs.h: Default ABI depends on ENABLE_NEW_GXX_ABI.
- * g++spec.c: Don't look at ENABLE_NEW_GXX_ABI.
-
-2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
-
- * search.c (get_vbase_1): Count only virtual bases.
-
-2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (duplicate_tag_error): Robustify flag clearing.
-
-2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (lookup_template_class): Add complain parm.
- * decl.c (lookup_namespace_name): Adjust call to
- lookup_template_class.
- (make_typename_type): Likewise.
- * semantics.c (finish_template_type): Likewise.
- * pt.c (lookup_template_class): Add complain parm. Adjust.
- (tsubst_aggr_type): Pass COMPLAIN down to lookup_template_class.
- (tsubst): Likewise.
-
-2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (copy_default_args_to_explicit_spec): Preserve
- object's CV quals. Reorganize.
-
-2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck.c (build_modify_expr): Say `initialization' for
- INIT_EXPRs.
- * init.c (build_default_init): Convert to enumeral type, if
- needed.
-
-2001-01-18 Jakub Jelinek <jakub@redhat.com>
-
- * parse.y (nomods_initdcl0): Properly set things up for
- initdcl0_innards.
-
-2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (UNIFY_ALLOW_OUTER_LEVEL): New unify flag.
- (type_unification_real): Set it.
- (unify): Use it.
-
-2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (finish_destructor_body): Convert to vbase pointer here.
-
-2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * semantics.c (begin_class_definition): Check we're not inside a
- template parm list.
-
-2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * tree.c (walk_tree, TREE_LIST): Don't walk the TREE_PURPOSE of
- BASELINK_P.
-
-2001-01-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * typeck.c (build_function_call_real): Call fold on the CALL_EXPR.
- * call.c (build_over_call): Add comment.
-
-2001-01-16 Daniel Berlin <dberlin@redhat.com>
-
- * cvt.c (ocp_convert): Handle vector type conversion
- * typeck2.c (digest_init): Handle vector type initializations
-
-2001-01-16 Phil Edwards <pme@sources.redhat.com>
-
- * g++spec.c: Don't add libraries needlessly if -fsyntax-only
- was given.
-
-2001-01-15 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (check_nontype_parm): Rename to ...
- (invalid_nontype_parm_type_p): ... here.
- (process_template_parm): Adjust.
- (convert_template_argument): Adjust.
-
-2001-01-15 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (check_nontype_parm): New function.
- (process_template_parm): Use it.
- (convert_template_argument): Use it.
- (convert_nontype_argument, RECORD_TYPE): Assert it's a ptr to
- member.
-
-2001-01-14 Jeffrey Oldham <oldham@codesourcery.com>
-
- * tree.c: Add defaults.h
- (cp_valid_lang_attribute): Incorporate SUPPORTS_INIT_PRIORITY.
- * Make-lang.in (cp/tree.o): Add defaults.h.
-
-2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * Make-lang.in (CXX_C_OBJS): Add c-format.o.
-
-2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * g++.1: Change to be ".so man1/gcc.1".
-
-2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * Make-lang.in (c++.info, c++.install-info): Build and install g++
- internals info.
- (c++.uninstall, c++.maintainer-clean): Remove g++ internals info.
- ($(srcdir)/cp/g++int.info): New target.
- * gxxint.texi: Add info directory entry. Use @@ in email address.
- * .cvsignore: Update.
-
-2001-01-12 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck.c (build_c_cast): Do template processing earlier.
- Always pedwarn on array casts.
-
-2001-01-12 Nathan Sidwell <nathan@codesourcery.com>
-
- * friend.c (make_friend_class): Make sure a templated class is
- actually a template.
-
-2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl2.c (get_guard): Set linkage from guarded decl.
-
-2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (convert_default_arg): Check for unprocessed
- DEFAULT_ARG.
- * cp-tree.h (replace_defarg): Move to spew.c.
- (maybe_snarf_defarg, add_defarg_fn, do_pending_defargs): Move to
- spew.c, which is where they really are.
- (done_pending_defargs): Declare.
- (unprocessed_defarg_fn): Declare.
- * decl.c (replace_defarg): Move to spew.c
- * parse.y (structsp): Call done_pending_defargs.
- * spew.c (defarg_fns): Rearrange list structure.
- (defarg_fnsdone): New static variable.
- (defarg_depfns): New static variable.
- (init_spew): Adjust.
- (add_defarg_fn): Store the type in TREE_TYPE.
- (do_pending_defargs): Detect and deal with ordering constraints
- and circularity.
- (done_pending_defargs): New function.
- (unprocessed_defarg_fn): New function.
- (replace_defarg): Moved from decl.c. Robustify. Don't save
- if circularity detected.
-
-2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (unify): Check array has a domain, before checking
- whether it is variable sized.
-
-2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (grokparms): Unobfuscate and get correct diagnostic for
- parameters with pointers to arrays of unknown bound.
-
-2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
-
- * parse.y (template_parm_header, template_spec_header): New
- reductions. Split out from ...
- (template_header): ... here. Use them.
- (template_template_parm): Use template_parm_header.
- * semantics.c (finish_template_template_parm): Add assert.
-
-2001-01-10 Mark Mitchell <mark@codesourcery.com>
-
- * mangle.c (write_builtin_type): Fix thinko.
-
- * pt.c (copy_default_args_to_explicit_spec_1): New function.
- (copy_default_args_to_explicit_spec): Likewise.
- (check_explicit_specialization): Use it.
-
- * class.c (finish_struct_1): Remove last argument in call to
- make_decl_rtl; use make_function_rtl instead of make_decl_rtl.
- * decl.c (builtin_function): Likewise.
- (build_cp_library_fn): Likewise.
- (check_initializer): Likewise.
- (make_rtl_for_nonlocal_decl): Likewise.
- (cp_finish_decl): Likewise.
- (start_function): Likewise.
- * decl2.c (finish_anon_union): Likewise.
- * friend.c (do_friend): Likewise.
- * init.c (build_java_class_ref): Likewise.
- * method.c (make_thunk): Likewise.
- * pt.c (tsubst_friend_function): Likewise.
- * semantics.c (expand_body): Likewise.
-
-2001-01-10 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (DECL_CLONED_FUNCTION_P): Avoid wild reads by not
- looking at DECL_CLONED_FUNCTION for non-functions.
-
-2001-01-10 Nathan Sidwell <nathan@codesourcery.com>
-
- * error.c (dump_template_parameter): Use parm to determine how
- to print default value.
-
-2001-01-10 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (duplicate_tag_error): Clear more flags.
-
-2001-01-10 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (build_new_method_call): Use binfo_for_vbase.
-
-2001-01-10 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * cp-tree.h (flag_cond_mismatch): Don't declare.
- * decl2.c (flag_cond_mismatch): Don't define.
- (lang_f_options): Remove cond-mismatch.
- (unsupported_options): Add cond-mismatch.
-
-2001-01-09 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (handle_using_decl): Reject using of constructor name
- of sourcing class. Allow injecting of a method with same name as
- nested class. Fixup error messages.
-
-2001-01-09 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl2.c (lang_decode_option): Handle -Wformat=2.
-
-2001-01-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (lang_decl_flags): Rename defined_in_class to
- initialized_in_class.
- (DECL_DEFINED_IN_CLASS_P): Rename to ...
- (DECL_INITIALIZED_IN_CLASS_P): ... here, to reflect true meaning.
- * decl.c (duplicate_decls): Preseve DECL_INITIALIZED_IN_CLASS_P.
- (cp_finish_decl): Adjust for DECL_INITIALIZED_IN_CLASS_P.
- * pt.c (check_default_tmpl_args): Adjust for
- DECL_INITIALIZED_IN_CLASS_P.
- (instantiate_class_template): Likewise.
- (instantiate_decl): Check DECL_INITIALIZED_IN_CLASS_P.
-
- * class.c (finish_struct): Constify saved_filename.
-
-2001-01-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (duplicate_tag_error): Adjust diagnostic.
- (finish_struct): Locally set location to start of struct.
- * decl.c (fixup_anonymous_aggr): Use cp_error_at.
-
-2001-01-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (struct binding_level): Adjust class_shadowed comments
- to reflect reality.
- (push_class_level_binding): Adjust comments to reflect reality.
- Set IDENTIFIER_CLASS_VALUE when replacing an existing binding.
- Don't set TREE_VALUE on the class_shadowed list.
-
-2001-01-07 Alexandre Petit-Bianco <apbianco@cygnus.com>
-
- * decl2.c (acceptable_java_type): Allow references too.
- * init.c (build_java_class_ref): When using the new ABI, search
- `class$' and have it mangled with `mangle_decl.'
- * mangle.c (write_java_integer_type_codes): New function.
- (write_builtin_type): Detect and mangle Java integer and real
- types.
-
-2001-01-07 Mark Mitchell <mark@codesourcery.com>
-
- * decl2.c (grokfield): Don't accept `asm' specifiers for
- non-static data members.
-
-2001-01-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * expr.c (cplus_expand_expr): Don't reset `target'.
-
-2001-01-07 Neil Booth <neil@daikokuya.demon.co.uk>
-
- * cp/decl2.c (cxx_post_options): Call cpp_post_options.
-
-2001-01-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * parse.y (template_datadef): Check for error_mark_node.
-
-2001-01-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.def (DEFAULT_ARG): Make `x' class.
-
-2001-01-04 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
- (record_builtin_type): Make non-static.
- (flag_short_double): Don't declare.
- (init_decl_processing): Remove the creation of many tree nodes now
- in c_common_nodes_and_builtins.
- (build_void_list_node): New function.
- * decl2.c (flag_short_double, flag_short_wchar): Don't define.
- * cp-tree.h (flag_short_wchar): Don't declare.
-
-2001-01-04 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (build_conv): Don't use build1 for USER_CONV.
- * pt.c (tsubst_copy): Or for PREINCREMENT_EXPR and similar nodes.
-
-2001-01-03 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * lex.c (lang_init): Call c_common_lang_init.
-
-2001-01-03 Nathan Sidwell <nathan@codesourcery.com>
-
- * search.c (lookup_fnfields_here): Remove.
- (look_for_overrides_r): Use lookup_fnfields_1.
- Ignore functions from using declarations.
-
-2001-01-03 Nathan Sidwell <nathan@codesourcery.com>
-
- Implement exceptions specifiers for implicit member functions.
- * cp-tree.h (merge_exceptions_specifiers): Declare new function.
- * method.c (synthesize_exception_spec): New function.
- (locate_dtor, locate_ctor, locate_copy): New functions.
- (implicitly_declare_fn): Generate the exception spec too.
- * search.c (check_final_overrider): Check artificial functions
- too.
- * typeck2.c (merge_exception_specifiers): New function.
-
-2001-01-03 Jason Merrill <jason@redhat.com>
-
- * init.c (build_default_init): New fn.
- (perform_member_init): Split out from here.
- (build_new_1): Use it. Simplify initialization logic.
- (build_vec_init): Take an array, rather than a pointer and maxindex.
- Speed up simple initializations. Don't clean up if we're assigning.
- * cp-tree.h: Adjust.
- * decl2.c (do_static_initialization): Remove TREE_VEC case.
- * parse.y (new_initializer): Return void_zero_node for ().
- * typeck.c (build_modify_expr): Handle getting a CONSTRUCTOR.
- * typeck2.c (digest_init): Only complain about user-written
- CONSTRUCTORs.
-
-2000-12-22 Mike Stump <mrs@wrs.com>
-
- * decl2.c: (max_tinst_depth): Increase to 50.
-
-2001-01-02 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (invalidate_class_lookup_cache): Zero the
- previous_class_values.
- * cp-tree.h (TMPL_PARMS_DEPTH): Use TREE_INT_CST_LOW, not
- TREE_INT_CST_HIGH.
- (CLASSTYPE_TEMPLATE_LEVEL): Likewise.
- * decl.c (free_bindings): New variable.
- (push_binding): Don't create a new binding if we have one on the
- free list.
- (pop_binding): Put old bindings on the free list.
- (init_decl_processing): Use size_int, not build_int_2.
- Register free_bindings as a GC root.
- (cp_make_fname_decl): Use size_int, not build_int_2.
- (push_inline_template_parms_recursive): Likewise.
- (end_template_parm_list): Likewise.
- (for_each_template_parm): Do not use walk_tree_without_duplicates.
- (tsubst_template_parms): Use size_int, not build_int_2.
- (tsubst): Likewise.
- * rtti.c (get_vmi_pseudo_type_info): Likewise.
-
-2001-01-02 Richard Henderson <rth@redhat.com>
-
- * parse.y (asm): Set ASM_INPUT_P.
-
-2001-01-02 Jason Merrill <jason@redhat.com>
-
- * tree.c (cp_valid_lang_attribute): Don't set CLASSTYPE_COM_INTERFACE
- for v3 ABI.
-
- * typeck.c (cp_truthvalue_conversion): New fn.
- * cvt.c (ocp_convert): Use it.
-
- * cp-tree.h: Lose c-common.c decls.
-
- * typeck.c (build_unary_op): Restore old &a.f diagnostic code.
- * cvt.c (convert_to_void): Use type_unknown_p.
-
- * typeck.c (strip_all_pointer_quals): Also strip quals from
- pointer-to-member types.
-
- * Make-lang.in (cp/TAGS): Use --no-globals. Ignore parse.c, and treat
- parse.y as C.
-
- * call.c (build_new_method_call): Do evaluate the object parameter
- when accessing a static member.
- * typeck.c (build_component_ref): Likewise.
-
-2001-01-02 Andreas Jaeger <aj@suse.de>
-
- * decl.c (cp_missing_noreturn_ok_p): New.
- (init_decl_processing): Set lang_missing_noreturn_ok_p.
-
-2000-12-29 Jakub Jelinek <jakub@redhat.com>
-
- * decl.c (init_decl_processing): Fix sign of wchar_type_node.
-
-2000-12-29 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (pushclass): Remove #if 0'd code.
- * cp-tree.h (overload_template_name): Remove.
- * decl.c (store_bindings): Simplify.
- (pop_from_top_level): Likewise.
- * pt.c (overload_template_name): Remove.
- (instantiate_decl): Don't call push_to_top_level if it's not
- needed.
-
-2000-12-28 Mark Mitchell <mark@codesourcery.com>
-
- * pt.c (register_local_specialization): Don't return a value.
- (lookup_template_class): Use move-to-front heuristic when looking
- up template instantiations.
- (instantiate_decl): Only push_to_top_level when we're actually
- going to instantiate the template.
-
-2000-12-29 Hans-Peter Nilsson <hp@bitrange.com>
-
- * search.c (binfo_for_vtable): Return least derived class, not
- most. Handle secondary vtables.
-
-2000-12-22 Jason Merrill <jason@redhat.com>
-
- * pt.c (more_specialized): Don't optimize len==0.
- (fn_type_unification): If we're adding the return type, increase len.
-
- * typeck.c (build_binary_op): Fix pmf comparison logic.
-
- * call.c (joust): Use DECL_NONSTATIC_MEMBER_FUNCTION_P, not
- DECL_STATIC_FUNCTION_P.
-
- * semantics.c (genrtl_finish_function): Don't try to jump to
- return_label unless it exists.
-
- In partial ordering for a call, ignore parms for which we don't have
- a real argument.
- * call.c (joust): Pass len to more_specialized.
- (add_template_candidate_real): Strip 'this', pass len.
- * pt.c (more_specialized): Pass len down. Lose explicit_args parm.
- (get_bindings_order): New fn. Pass len down.
- (get_bindings_real): Strip 'this', pass len.
- (fn_type_unification): Likewise.
- (type_unification_real): Succeed after checking 'len' args.
- (most_specialized_instantiation): Lose explicit_args parm.
- * class.c (resolve_address_of_overloaded_function): Strip 'this',
- pass len.
-
-2000-12-21 Jason Merrill <jason@redhat.com>
-
- * pt.c (tsubst_decl): A FUNCTION_DECL has DECL_RESULT, not
- DECL_TEMPLATE_RESULT.
-
- * search.c (lookup_field_r): Call lookup_fnfields_1, not
- lookup_fnfields_here.
-
- * parse.y (typename_sub2): Return the TYPE_DECL, not the type.
-
- * call.c (build_object_call): Also allow conversions that return
- reference to pointer to function.
- (add_conv_candidate): Handle totype being ref to ptr to fn.
- (build_field_call): Also allow members of type reference to function.
- Lose support for calling pointer to METHOD_TYPE fields.
-
- * error.c (dump_expr): Handle *_CAST_EXPR.
-
- * typeck2.c (build_scoped_ref): Always convert to the naming class.
-
- * tree.c (break_out_cleanups): Lose.
- * cp-tree.h: Remove prototype.
- * typeck.c (build_component_ref): Don't break_out_cleanups.
- (build_compound_expr): Likewise.
- * semantics.c (finish_expr_stmt): Likewise.
-
-2000-12-20 Richard Henderson <rth@redhat.com>
-
- * cp-tree.h: Update declarations.
- * decl.c (finish_case_label): Return the new stmt node.
- * semantics.c (finish_goto_stmt): Likewise.
- (finish_expr_stmt, finish_return_stmt): Likewise.
- (finish_break_stmt, finish_continue_stmt): Likewise.
- (finish_asm_stmt): Likewise.
- * parse.y (already_scoped_stmt): Set STMT_LINENO.
- (compstmt, implicitly_scoped_stmt, stmt): Likewise.
- (simple_if, simple_stmt): Return the new stmt node.
- (save_lineno): New.
-
-2000-12-18 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * cp-tree.h: Don't declare warn_long_long.
-
-2000-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * tree.c (no_linkage_helper): Use CLASS_TYPE_P instead of
- IS_AGGR_TYPE.
-
-2000-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (unify): Handle when both ARG and PARM are
- BOUND_TEMPLATE_TEMPLATE_PARM.
-
-2000-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (reduce_template_parm_level): Set DECL_ARTIFICIAL and
- DECL_TEMPLATE_PARM_P.
-
-2000-12-15 Jason Merrill <jason@redhat.com>
-
- * init.c (build_new_1): Reorganize. Now with 100% fewer SAVE_EXPRs!
-
- * init.c (build_new_1): Don't strip quals from type.
-
- * decl.c (pushdecl): Don't check for linkage on a non-decl.
-
- * call.c (build_op_delete_call): See through ARRAY_TYPEs.
-
- * call.c (build_new_function_call): Lose space before paren in
- error message.
- (build_new_method_call): Likewise.
-
- * typeck2.c (build_m_component_ref): Propagate quals from datum.
-
-2000-12-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (check_explicit_specialization): Propagate default
- function arguments to explicit specializations.
-
-2000-12-13 DJ Delorie <dj@redhat.com>
-
- * typeck.c (build_binary_op): Do signed/unsigned warnings for >?
- and <? operators.
-
-2000-12-08 Jason Merrill <jason@redhat.com>
-
- * error.c (dump_function_name): Don't let the user see __comp_ctor.
-
- Clean up copy-initialization in overloading code.
- * call.c (build_user_type_conversion_1): Die if we are asked to
- convert to the same or a base type.
- (implicit_conversion): Avoid doing so. Lose reference binding code.
- (convert_like_real): Treat BASE_CONV and RVALUE_CONV as implicit
- direct-initialization. Also do direct-init part of copy-init.
- (build_user_type_conversion): Don't provide context to convert_like.
- * cvt.c (ocp_convert): build_user_type_conversion will now provide
- the constructor call for copy-init.
-
- * pt.c (tsubst_decl): Call clone_function_decl here if this is an
- instantiation of a member template.
- (do_decl_instantiation): Not here.
-
-2000-12-07 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (check_field_decls): Don't special case anonymous
- fields in error messages.
- (note_name_declared_in_class): Use %D on diagnostic.
-
- * tree.c (pod_type_p): Use strip_array_types.
- (cp_valid_lang_attribute): Likewise.
- * typeck.c (cp_type_quals): Strip arrays separately, to avoid
- multiple evaluations.
- (cp_has_mutable_p): Use strip_array_types.
-
-2000-12-07 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (sufficient_parms_p): Declare new function.
- * call.c (sufficient_parms_p): New function, broken out of ...
- (add_function_candidate): ... here. Use it.
- (add_conv_candidate): Use it.
- * decl.c (grok_ctor_properties): Use it.
-
-2000-12-07 Jakub Jelinek <jakub@redhat.com>
-
- * optimize.c (copy_body_r): Set STMT_IS_FULL_EXPR_P on EXPR_STMT.
-
-2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl2.c (lang_decode_option): Handle -Wformat-security.
-
-2000-12-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * pt.c (verify_class_unification): New function.
- (get_class_bindings): Use it.
- (try_class_unification): Tidy.
- (unify): Handle when argument of a template-id is not
- template parameter dependent.
- (template_args_equal): Handle when TREE_CODE's do not match.
-
-2000-12-06 Alexandre Oliva <aoliva@redhat.com>
-
- * lang-specs.h (c++): When invoking the stand-alone preprocessor
- for -save-temps, pass all relevant -Defines to it, and then don't
- pass them to cc1plus.
-
-2000-12-05 Will Cohen <wcohen@redhat.com>
-
- * decl.c (finish_case_label): Cleared
- more_cleanups_ok in surrounding function scopes.
- (define_label): Likewise.
-
-2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (IDENTIFIER_VIRTUAL_P): Document.
- (get_matching_virtual): Remove.
- (look_for_overrides): Declare new function.
- * decl.c (grokfndecl): Don't set IDENTIFIER_VIRTUAL_P or
- DECL_VINDEX here.
- * class.c (check_for_override): Move base class iteration code
- to look_for_overrides.
- * search.c (next_baselink): Remove.
- (get_virtuals_named_this): Remove.
- (get_virtual_destructor): Remove.
- (tree_has_any_destructors_p): Remove.
- (struct gvnt_info): Remove.
- (check_final_overrider): Remove `virtual' from error messages.
- (get_matching_virtuals): Remove. Move functionality to ...
- (look_for_overrides): ... here, and ...
- (look_for_overrides_r): ... here. Set DECL_VIRTUAL_P, if found
- to be overriding.
-
-2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck.c (get_delta_difference): If via a virtual base,
- return zero.
- * cvt.c (cp_convert_to_pointer): If via a virtual base, do no
- adjustment.
-
-2000-12-04 Richard Henderson <rth@redhat.com>
-
- * error.c (dump_tree): Use output_add_string not OB_PUTS.
-
-2000-12-04 Jason Merrill <jason@redhat.com>
-
- * mangle.c (write_type): Mangle VECTOR_TYPE with "U8__vector".
- (write_builtin_type): Pass intSI_type_node and the like through
- type_for_mode.
- * method.c (process_overload_item): Mangle VECTOR_TYPEs with 'o'.
- Pass intSI_type_node and the like through type_for_mode.
- * decl2.c (arg_assoc_type): Handle VECTOR_TYPE like COMPLEX_TYPE.
- * pt.c (tsubst, unify): Likewise.
- * tree.c (walk_tree): Likewise.
- * error.c (dump_type): Likewise.
- (dump_type_prefix, dump_type_suffix): Don't bother with VECTOR_TYPE.
-
- * Make-lang.in: Tweak top comment for emacs.
- (cp/TAGS): Restore.
- * except.c (expand_throw): Use push_throw_library_fn for _Jv_Throw.
+2004-01-15 Alexandre Oliva <aoliva@redhat.com>
- * class.c (clone_function_decl): Robustify.
+ PR c++/13594
+ PR c++/13658
+ * name-lookup.c (qualified_lookup_using_namespace): Search
+ strongly-associated namespaces first, and only then try other
+ namespaces.
-2000-12-04 Michael Matz <matzmich@cs.tu-berlin.de>
+2004-01-15 Kelley Cook <kcook@gcc.gnu.org>
- * decl.c (store_bindings): Only search in the non modified
- old_bindings for duplicates.
+ * Make-lang.in (c++.srcextra): Dummy entry.
-2000-12-04 Nathan Sidwell <nathan@codesourcery.com>
+2004-01-15 Giovanni Bajo <giovannibajo@gcc.gnu.org>
- * error.c (dump_function_decl): Use DECL_VIRTUAL_P, not
- TYPE_POLYMORPHIC_P.
+ PR c++/8856
+ * parser.c (cp_parser_template_name): Don't try to parse a
+ conversion-function-id, as it cannot be a template-name.
+ (cp_parser_simple_type_specifier): Check for invalid template-ids
+ even after a built-in type.
- * typeck.c (build_static_cast): Remove unused variable.
+2004-01-14 Jan Hubicka <jh@suse.cz>
-2000-12-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ PR c++/12850
+ * pt.c (instantiate_decl): Do not increase function_depth.
- * pt.c: Fix typo in comment.
+2004-01-14 Danny Smith <dannysmith@users,sourceforge.net>
-2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
+ PR c++/9021
+ PR c++/11005
+ * parser.c (cp_parser_elaborated_type_specifier): Warn about
+ attributes and discard.
+ * decl.c (xref_tag): Don't overwite existing attributes with
+ NULL_TREE.
- * decl2.c (warn_format): Remove definition.
- (lang_decode_option): Handle -Wformat-nonliteral,
- -Wno-format-extra-args and -Wno-format-y2k. Use set_Wformat.
+2004-01-14 Giovanni Bajo <giovannibajo@gcc.gnu.org>
-2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
+ PR c++/12335
+ * parser.c (cp_parser_lookup_name): Return error_mark_node if there
+ is no destructor while looking up a BIT_NOT_EXPR.
- * decl.c (WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Don't define.
- (init_decl_processing): Don't create string_type_node,
- const_string_type_node, wint_type_node, intmax_type_node,
- uintmax_type_node, default_function_type, ptrdiff_type_node and
- unsigned_ptrdiff_type_node. Adjust position of call to
- c_common_nodes_and_builtins.
- (identifier_global_value): New function.
+2004-01-13 Ian Lance Taylor <ian@wasabisystems.com>
-2000-12-01 Nathan Sidwell <nathan@codesourcery.com>
+ * cxxfilt.c: Remove unused file.
- * call.c (standard_conversion): Reject pointer to member
- conversions from ambiguous, inaccessible or virtual bases.
- * typeck.c (build_static_cast): Don't check pointers to members
- specially.
+2004-01-14 Jan Hubicka <jh@suse.cz>
-2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
+ Partial fix to PR c++/12850
+ * decl2.c (mark_used): Do not proactively instantiate templates
+ when compiling in unit-at-a-time or not optimizing.
+ * optimize.c (maybe_clone_body): Do not increase function depth.
- * method.c (do_build_copy_constructor): Preserve cv
- qualifications when accessing source object members.
- (do_build_assign_ref): Likewise. Remove separate diagnostics for
- unnamed fields.
+2004-01-13 Giovanni Bajo <giovannibajo@gcc.gnu.org>
-2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/13474
+ * pt.c (tsubst) <INTEGER_TYPE>: Remove obsolete array index tweaking.
- * method.c (do_build_assign_ref): Construct appropriately
- CV-qualified base reference. Don't allow const casts in base
- conversion.
+2003-01-12 Steven Bosscher <stevenb@suse.de>
-2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/13558
+ * parser.c (cp_parser_member_declaration): Any non-type is also
+ not a class or a function.
- * call.c (build_over_call): Use VOID_TYPE_P. Don't die on
- incomplete return type.
+2004-01-12 Jason Merrill <jason@redhat.com>
-2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/12815
+ * class.c (build_base_path): Do not mark vtable references as
+ TREE_CONSTANT.
+ (build_vtbl_ref_1): Likewise.
- * parse.y (base_class.1): Produce a _TYPE not a _DECL.
- * semantics.c (finish_base_specifier): Accept a _TYPE not a
- _DECL.
+2004-01-12 Richard Henderson <rth@redhat.com>
-2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+ PR opt/10776
+ * typeck2.c (split_nonconstant_init_1, split_nonconstant_init): New.
+ (store_init_value): Use it.
+ * decl.c (check_initializer): Expect full initialization code
+ from store_init_value.
+ * init.c (expand_aggr_init_1): Likewise.
+ * decl2.c (maybe_emit_vtables): Abort if runtime init needed.
- * spew.c (yyerror): Cope if yylval.ttype is NULL.
+2004-01-12 Mark Mitchell <mark@codesourcery.com>
-2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+ * class.c (layout_class_type): For non-POD class types, also copy
+ the DECL_SIZE and DECL_MODE of fields to the base class type.
- * decl.c (grokdeclarator): Diagnose undefined template contexts.
+2004-01-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/13289
+ * pt.c (instantiate_decl): Set DECL_TEMPLATE_INSTANTIATED before
+ calling regenerate_decl_from_template.
- * decl.c (grokdeclarator): Do type access control on friend
- class.
+2004-01-12 Scott Brumbaugh <scottb.lists@verizon.net>
-2000-11-27 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/4100
+ * parser.c (cp_parser_decl_specifier_seq): Add check for a friend
+ decl-specifier occurring along with a class definition.
- * decl.c (grokfndecl): Undo COMPONENT_REF damage caused by
- bison parser ickiness.
- * pt.c (tsubst_friend_function): Enter namespace scope when
- tsubsting the function name.
- * cp-tree.h (DECL_TI_TEMPLATE): Update comment to reflect reality.
+2004-01-12 Ian Lance Taylor <ian@wasabisystems.com>
-2000-11-27 Nathan Sidwell <nathan@codesourcery.com>
+ * parser.c (cp_parser_decl_specifier_seq): Add parenthetical
+ clauses to comments describing declares_class_or_enum.
+ (cp_parser_type_specifier): Set *declares_class_or_enum to 0, not
+ false.
- * cp-tree.h (binfo_from_vbase): Return the virtual base's binfo.
- * cvt.c (cp_convert_to_pointer): Add force parameter.
- Allow conversions via virtual base if forced.
- (convert_to_pointer_force): Adjust call to cp_convert_to_pointer.
- (ocp_convert): Likewise.
- * search.c (binfo_from_vbase): Return the virtual base's binfo.
- * typeck.c (get_delta_difference): Adjust handling of virtual
- bases.
+2004-01-12 Jan Hubicka <jh@suse.cz>
-2000-11-26 Mark Mitchell <mark@codesourcery.com>
+ * pt.c (for_each_template_parm): Do not check for duplicates.
+ (for_each_template_parm): Use walk_tree duplicate checking code.
- * tree.c (struct list_hash): Remove.
- (list_hash_table): Make it be an htab.
- (struct list_proxy): New type.
- (list_hash_eq): New function.
- (list_hash_pieces): Renamed from ...
- (list_hash): ... this.
- (list_hash_lookup): Remove.
- (list_hash_add): Remove.
- (hash_tree_cons): Use the generic hashtable.
- (mark_list_hash): Remove.
- (init_tree): Create the hashtable.
+2004-01-11 Ian Lance Taylor <ian@wasabisystems.com>
-2000-11-25 Joseph S. Myers <jsm28@cam.ac.uk>
+ PR c++/3478
+ * parser.c (cp_parser_decl_specifier_seq): If the first decl_spec
+ is error_mark_node, don't add any more decl_specs.
+ (cp_parser_init_declarator): After committing to a declaration, if
+ the decl_specifiers start with error_mark_node, issue an error and
+ change the type to "int".
- * method.c (build_mangled_C9x_name): Rename to
- build_mangled_C99_name. Change C9X references in comments to
- refer to C99.
+2004-01-09 Nathanael Nerode <neroden@gcc.gnu.org>
-2000-11-24 Nathan Sidwell <nathan@codesourcery.com>
+ PR bootstrap/7817
+ * Make-lang.in: Copy gcc.1 to g++.1 rather than using .so.
- * parse.y (unary_expr): Move VA_ARG from here ...
- (primary): ... to here.
+2004-01-10 Giovanni Bajo <giovannibajo@gcc.gnu.org>
-2000-11-24 Nathan Sidwell <nathan@codesourcery.com>
+ DR 337
+ PR c++/9256
+ * pt.c (tsubst): Substitution must fail if we are attempting to
+ create an array with element type that is an abstract class type.
+ * decl.c (cp_finish_decl): Strip pointers and array types recursively
+ before calling abstract_virtuals_error.
- * semantics.c (finish_id_expr): If type is error_mark, return
- error_mark.
+2004-01-09 Alexandre Oliva <aoliva@redhat.com>
-2000-11-23 Nathan Sidwell <nathan@codesourcery.com>
+ * name-lookup.c (qualified_lookup_using_namespace): Consider
+ strong using directives even if we've already found a binding.
- * pt.c (lookup_template_class): Simplify loop exit constructs.
- Cope when there is no partial instantiation of a template
- template member.
+2004-01-09 Mark Mitchell <mark@codesourcery.com>
-Thu Nov 23 02:16:47 2000 J"orn Rennecke <amylaar@redhat.com>
+ * cp-tree.h (cxx_expand_expr): Change prototype.
+ * expr.c (cxx_expand_expr): Add alt_rtl parameter.
- * Make-lang.in (g++spec.o, cxxmain.o): Depend on $(CONFIG_H).
+2004-01-08 Giovanni Bajo <giovannibajo@gcc.gnu.org>
-2000-11-22 Mark Mitchell <mark@codesourcery.com>
+ PR c++/12573
+ * pt.c (value_dependent_expression_p): Handle COMPONENT_REFs by
+ looking into them recursively. They can be there because of the
+ new __offsetof__ extension.
- * mangle.c (mangle_conv_op_name_for_type): Don't use `__op'
- prefix.
+2004-01-07 Zack Weinberg <zack@codesourcery.com>
- * pt.c (do_decl_instantiate): Explicitly clone constructors and
- destructors that haven't already been cloned.
+ * parser.c (cp_parser_save_member_function_body): Mark the
+ definition static.
-2000-11-20 Richard Henderson <rth@redhat.com>
+2004-01-05 Mark Mitchell <mark@codesourcery.com>
- * parse.y (yyparse_1): Rename the parser entry point.
+ PR c++/13057
+ * class.c (build_clone): Copy type attributes from the original
+ function to the clone.
-2000-11-20 Alex Samuel <samuel@codesourcery.com>
+ PR c++/12815
+ * class.c (build_vtbl_ref_1): Do not unconditionally mark vtable
+ references as constant.
- * mangle.c (write_name): Use <unscoped-name> for names directly in
- function scope.
- (write_unscoped_name): Accept names directly in function scope.
+ PR c++/12132
+ * parser.c (cp_parser_explicit_instantiation): Improve error
+ recovery.
+ (cp_parser_require): Improve indication of the error location.
-2000-11-20 Nathan Sidwell <nathan@codesourcery.com>
+ PR c++/13451
+ * parser.c (cp_parser_class_head): Reorder logic to check for
+ invalid qualification.
- * lex.c (rid_to_yy, RID_EXPORT): Make unique keyword.
- * parse.y (extdef): Add EXPORT reduction.
- * spew.c (yylex): Don't skip export here.
+2004-01-04 Mark Mitchell <mark@codesourcery.com>
-2000-11-19 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (init_decl_processing): Correct name of pure virtual
- function under the new ABI.
- * rtti.c (throw_bad_cast): Likewise, for bad cast function.
- (throw_bad_typeid): Likewise for bad typeid function.
-
-2000-11-18 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (grokparms): Don't even function types of `void' type,
- either.
- * mangle.c (write_type): Don't crash when confronted with the
- error_mark_node.
-
- * decl.c (grokparms): Don't create parameters of `void' type.
-
-2000-11-17 Zack Weinberg <zack@wolery.stanford.edu>
-
- * lex.c (mark_impl_file_chain): Delete.
- (init_parse): Remove call to ggc_add_string_root. No need to
- ggc_strdup a string constant. Do not add impl_file_chain to GC
- roots.
- (handle_pragma_implementation): No need to ggc_strdup main_filename.
-
-2000-11-17 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (tsubst_expr, DECL_STMT): Instantiate decl's type.
-
-2000-11-17 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (PARMLIST_ELLIPSIS_P): New macro.
- * decl.c (grokdeclarator): Don't reject void parms here.
- (require_complete_types_for_parms): Simplify, use
- complete_type_or_else.
- (grokparms): Remove bitrot. Remove funcdef parm.
- Deal with ellipsis parm lists here.
- * semantics.c (finish_parmlist): Don't append void_list_node
- here. Set PARMLIST_ELLIPSIS_P.
-
-2000-11-17 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck2.c (incomplete_type_error): Reorganize to avoid
- excessive diagnostics.
-
-2000-11-16 Zack Weinberg <zack@wolery.stanford.edu>
-
- * lex.c (struct impl_files, internal_filename): Constify a char *.
-
-2000-11-16 Mark Mitchell <mark@codesourcery.com>
-
- * mangle.c (write_special_name_constructor): Don't generate
- assembler junk when confronted with an old-style constructor.
- (write_special_name_destructor): Likewise.
- (mangle_decl_string): Do it here instead.
-
-2000-11-16 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (op_error): Make error messages clearer.
-
-2000-11-15 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (wrapup_globals_for_namespace): Don't mark things
- TREE_ASM_WRITTEN when they're not.
-
-2000-11-15 Jason Merrill <jason@redhat.com>
-
- * typeck2.c (friendly_abort): Uncount the error before handing
- off to fancy_abort.
-
-2000-11-15 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck.c (lookup_anon_field): Cope with qv qualifiers.
-
-2000-11-14 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (build_vtbl_initializer): Fix typo in comment.
- * typeck.c (expr_sizeof): Don't crash on errors.
-
-2000-11-14 Jim Wilson <wilson@redhat.com>
-
- * lang-specs.h: Add %2 after %(cc1_options).
-
-2000-11-14 Richard Henderson <rth@redhat.com>
-
- * typeck.c (c_sizeof): Be strict about casting result value
- back to c_size_type_node.
- (expr_sizeof, c_sizeof_nowarn, c_alignof): Likewise.
-
-2000-11-13 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * typeck.c (build_unary_op): Use boolean_increment from
- c-common.c, moving the relevant code there.
-
-2000-11-11 Jason Merrill <jason@redhat.com>
-
- * typeck.c (mark_addressable): Don't call put_var_into_stack.
-
- * decl.c (maybe_commonize_var): Set DECL_UNINLINABLE for statics
- in inlines.
-
-2000-11-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * decl.c (grokdeclarator, save_function_data): Use memcpy, not bcopy.
- * lex.c (copy_lang_decl): Likewise.
-
-2000-11-09 Mark Mitchell <mark@codesourcery.com>
-
- * dump.c (cp_dump_tree): Don't dump function bodies here.
-
- * Make-lang.in (CXX_C_OBJS): Add c-dump.o.
- (dump.o): Update dependency list.
- * cp-tree.h (DECL_MAYBE_TEMPLATE): Remove.
- (flag_dump_translation_unit): Likewise.
- (CP_TYPE_QUALS): Adjust definition.
- (DECL_C_BIT_FIELD): Remove.
- (SET_DECL_C_BIT_FIELD): Likewise.
- (CLEAR_DECL_C_BIT_FIELD): Likewise.
- (add_maybe_template): Likewise.
- (strip_array_types): Likewise.
- (dump_node_to_file): Likewise.
- (cp_dump_tree): New function.
- * decl.c (init_decl_processing): Set lang_dump_tree.
- * decl2.c (flag_dump_translation_unit): Remove.
- * dump.c: Move most of it to ../c-dump.c.
- (cp_dump_tree): New function.
- * pt.c (add_maybe_template): Remove.
- * typeck.c (strip_array_types): Likewise.
-
-2000-11-07 Eric Christopher <echristo@redhat.com>
-
- * decl.c (init_decl_processing): Change definition of
- __wchar_t to wchar_t. Remove artificial declaration of
- wchar_t.
- * lex.c: Change instances of __wchar_t to wchar_t.
-
-2000-11-09 Nathan Sidwell <nathan@codesourcery.com>
-
- * lex.c (do_identifier): Don't lookup_name for operators.
- * parse.y (operator): Save looking_for_typename.
- (unoperator): Restore it.
- * spew.c (frob_opname): Use nth_token for lookahead.
-
-2000-11-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (grok_op_properties): Always use coerce_new_type and
- coerce_delete_type.
- * decl2.c (coerce_new_type): Use c_size_type_node. Preserve
- exception specification. Tidy up.
- (coerce_delete_type): Preserve exception specification. Tidy up.
-
-2000-11-07 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
- (push_binding_level), error.c (cp_tree_printer), pt.c
- (process_partial_specialization, tsubst_template_arg_vector),
- search.c (lookup_member): Use memset () instead of bzero ().
-
-2000-11-07 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (build_ptrmemfunc_type): Allow error_mark_node.
-
-2000-11-05 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * Make-lang.in (c++.distdir): Remove.
-
-2000-11-04 Mark Mitchell <mark@codesourcery.com>
-
- * decl2.c (do_nonmember_using_decl): Allow `extern "C"'
- declarations from different namespaces to be combined.
-
-2000-11-03 Zack Weinberg <zack@wolery.stanford.edu>
-
- * decl.c: Include tm_p.h.
-
-2000-11-03 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * tree.c (cp_tree_equal): Use memcmp () instead of bcmp ().
-
-2000-11-02 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * dump.c (dequeue_and_dump), lex.c (interface_strcmp), method.c
- (build_overload_value), repo.c (open_repo_file), xref.c
- (open_xref_file): Use strchr () and strrchr () instead of index ()
- and rindex ().
-
-2000-11-01 Bernd Schmidt <bernds@redhat.co.uk>
-
- * call.c (build_over_call): Call fold on the CALL_EXPR.
-
-2000-11-01 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c (dump_template_decl): Separate template hearders with
- space not comma.
-
-2000-10-31 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c: Move TFF_ macros into cp-tree.h. Throughout, replace
- TS_* flags with corresponding TFF_*. Adjust prototypes of
- functions (which used to take a tree_string_flags) to take an int.
-
- * cp-tree.h (enum tree_string_flags): Remove
- (TFF_PLAIN_IDENTIFIER, TFF_NAMESPACE_SCOPE, TFF_CLASS_SCOPE,
- TFF_CHASE_NAMESPACE_ALIAS, TFF_CHASE_TYPEDEF, TFF_DECL_SPECIFIERS,
- TFF_CLASS_KEY_OR_ENUM, TFF_RETURN_TYPE,
- TFF_FUNCTION_DEFAULT_ARGUMENTS, TFF_EXCEPTION_SPECIFICATION,
- TFF_TEMPLATE_HEADER, TFF_TEMPLATE_DEFAULT_ARGUMENTS,
- TFF_TEMPLATE_NAME, TFF_EXPR_IN_PARENS, TFF_SCOPE): New macros.
- (type_as_string, decl_as_string, expr_as_string,
- context_as_string): Adjust prototype.
-
- * class.c (dump_class_hierarchy_r): Use TFF_PLAIN_IDENTIFIER
- instead of TS_PLAIN.
-
- * pt.c (mangle_class_name_for_template): Use TFF_CHASE_TYPEDEF
- instead of TF_CHASE_TYPEDEFS. Use TFF_PLAIN_IDENTIFIER instead of
- plain `0'.
-
-2000-10-30 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (DECL_EXTERNAL_LINKAGE_P): New macro.
- (linkage_kind): New enumeration.
- (decl_linkage): New function.
- * decl2.c (comdat_linkage): Extend comment.
- * error.c (dump_function_decl): Print the arguments used to
- instantiate a template, even when not printing the type of the
- function.
- * pt.c (convert_nontype_argument): Use DECL_EXTERNAL_LINKAGE_P,
- not TREE_PUBLIC, to test for external linkage.
- * tree.c (decl_linkage): New function.
-
-2000-10-28 Mark Mitchell <mark@codesourcery.com>
-
- * pt.c (instantiate_decl): Always instantiate static data members
- initialized in-class.
-
-2000-10-27 Zack Weinberg <zack@wolery.stanford.edu>
-
- * Make-lang.in: Move all build rules here from Makefile.in,
- adapt to new context. Wrap all rules that change the current
- directory in parentheses. Expunge all references to $(P).
- When one command depends on another and they're run all at
- once, use && to separate them, not ;. Add OUTPUT_OPTION to
- all object-file generation rules. Delete obsolete variables.
-
- * Makefile.in: Delete.
- * config-lang.in: Delete outputs= line.
-
-2000-10-26 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c (dump_function_decl): Print no space between
- `ptr-operator' the `type-specifier' of the return type.
- (dump_type_prefix): Make sure we put space at the appropriate
- place.
-
-2000-10-23 Jason Merrill <jason@redhat.com>
-
- * call.c (equal_functions): Also call decls_match for extern "C" fns.
-
-2000-10-22 Jason Merrill <jason@redhat.com>
-
- * call.c (build_conditional_expr): Use ocp_convert to force
- rvalue conversion.
-
-2000-10-22 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (standard_conversion): Use RVALUE_CONVs for all
- expressions that satisfy lvalue_p, not just those that satisfy
- real_lvalue_p.
-
- * optimize.c (copy_body_r): Don't treat CALL_EXPRs specially.
-
- * typeck.c (c_sizeof): Return an expression of `size_t' type,
- not one with TYPE_IS_SIZETYPE set.
- (dubious_conversion_warnings): Remove special-case code.
-
-2000-10-21 Geoffrey Keating <geoffk@cygnus.com>
-
- * decl2.c (arg_assoc_type): Handle VECTOR_TYPE.
- * error.c (dump_type): Handle VECTOR_TYPE like POINTER_TYPE.
- (dump_type_prefix): Print vector-of-int as 'int vector'.
- (dump_type_suffix): Handle VECTOR_TYPE like POINTER_TYPE.
- * tree.c (walk_tree): Handle VECTOR_TYPE.
-
- * decl.c (init_decl_processing): Call MD_INIT_BUILTINS.
-
-2000-10-21 Jason Merrill <jason@redhat.com>
-
- * parse.y (operator): Set got_object from got_scope.
- Set looking_for_typename.
- * decl.c (lookup_name_real): Clear val after setting from_obj.
- Reorganize diagnostic.
-
-2000-10-20 Jason Merrill <jason@redhat.com>
-
- * tree.c (walk_tree): Don't walk into default args.
-
- * error.c (dump_expr): Use host_integerp.
-
-2000-10-20 David Edelsohn <edelsohn@gnu.org>
-
- * typeck2.c (abstract_virtuals_error): Use "because" instead of
- "since" in error message.
-
-Fri Oct 20 13:54:59 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * typeck.c (dubious_conversion_warning): Suppress if TYPE_IS_SIZETYPE.
-
-2000-10-20 Jeffrey Oldham <oldham@codesourcery.com>
-
- * decl.c (revert_static_member_fn): Fixed typo.
-
-2000-10-19 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (subobject_offset_fn): New type.
- (dfs_record_base_offsets): Remove.
- (record_base_offsets): Likewise.
- (dfs_search_base_offsets): Likewise.
- (record_subobject_offset): New function.
- (check_subobject_offset): Likewise.
- (walk_subobject_offsets): Likewise.
- (record_subobject_offsets): Likewise.
- (layout_conflict_p): Reimplement.
- (layout_nonempty_base_or_field): Correct handling of type
- conflicts during layout.
- (layout_empty_base): Likewise.
- (build_base_field): Adjust to handle new representation of empty
- base offset table.
- (build_base_fields): Likewise.
- (layout_virtual_bases): Likewise.
- (splay_tree_compare_integer_csts): New function.
- (layout_class_type): Use a splay_tree, rather than a varray, to
- represent the offsets of empty bases.
-
- * cp-tree.h (DECL_ANTICIPATED): Don't require a FUNCTION_DECL.
- * decl.c (select_decl): Don't return declarations that are
- DECL_ANTICIPATED.
-
-2000-10-18 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (cp_tree_index): Add CPTI_FAKE_STD.
- (fake_std_node): New macro.
- * decl.c (in_std): Rename to ...
- (in_fake_std): ... this.
- (flag_no_builtin): Remove.
- (flag_no_nonansi_builtin): Likewise.
- (walk_namespaces_r): Use fake_std_node.
- (push_namespace): Use std_identifier.
- (pop_namespace): Use in_fake_std.
- (lookup_name_real): Use fake_std_node.
- (init_decl_processing): When -fhonor-std, create the `std'
- namespace. Don't create a dummy fake_std_node in that case.
- Adjust call to c_common_nodes_and_builtins. Use std_identifier.
- (builtin_function): Put builtins whose names don't begin
- with `_' in the std namespace.
- * decl2.c (flag_no_builtin): Remove.
- (flag_no_nonansi_builtin): Likewise.
- (set_decl_namespace): Use fake_std_node.
- (validate_nonmember_using_decl): Likewise.
- (do_using_directive): Likewise.
- (handle_class_head): Likewise.
- * dump.c (dequeue_and_dump): Likewise.
- * except.c (init_exception_processing): Use std_identifier.
- * init.c (build_member_call): Use fake_std_node.
- * rtti.c (init_rtti_processing): Use std_identifier.
-
-2000-10-17 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (back_end_hook): Remove declaration.
- * decl2.c (back_end_hook): Remove definition.
-
- * dump.c (dequeue_and_dump): Dump TREE_USED.
-
-Tue Oct 17 20:19:06 2000 Brad Lucier <lucier@math.purdue.edu>
-
- * spew.c (snarf_defarg): Cast 2nd arg to obstack_blank to (int).
-
-2000-10-17 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl.c (WINT_TYPE): Define.
- (init_decl_processing): Create types unsigned_ptrdiff_type_node,
- c_size_type_node, signed_size_type_node and wint_type_node.
-
-2000-10-17 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl2.c (warn_missing_format_attribute): New variable.
- (lang_decode_option): Decode -Wmissing-format-attribute.
-
-2000-10-16 Mark Mitchell <mark@codesourcery.com>
-
- * typeck.c (qualify_type): Remove.
- (composite_pointer_type): Fix handling of conversions to `cv void*'.
-
-2000-10-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * Makefile.in (parse.c, parse.h): Fix think-o in last patch.
-
-2000-10-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * Makefile.in (parse.c, parse.h): Create atomically.
-
-2000-10-12 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (current_obstack): Remove.
- * decl.c (ggc_p): Remove.
- (start_decl): Don't use decl_tree_cons.
- (grokdeclarator): Don't use build_decl_list.
- (start_function): Don't use decl_tree_cons.
- (finish_function): Don't mess with obstacks.
- * decl2.c (grok_x_components): Don't use build_decl_list.
- * lex.c (make_call_declarator): Don't call decl_tree_cons.
- (implicitly_declare_fn): Don't call build_decl_list.
- * parse.y (frob_specs): Don't call build_decl_list or
- decl_tree_cons.
- (expr_or_declarator_intern): Don't call decl_tree_cons.
- (primary): Don't call build_decl_list.
- (fcast_or_absdcl): Likewise.
- (typed_declspecs): Don't call decl_tree_cons.
- (reserved_declspecs): Don't call build_decl_list.
- (declmods): Likewise.
- (reserved_typespecquals): Likewise.
- (aggr): Likewise.
- (new_type_id): Likewise.
- (cv_qualifiers): Likewise.
- (after_type_declarator_intern): Likewise.
- (notype_declarator_intern): Likewise.
- (absdcl_intern): Likewise.
- (named_parm): Likewise.
- * pt.c (most_specialized_class): Likewise.
- * repo.c (temporary_obstack): Make it a structure, not a pointer.
- (init_repo): Initialize it.
- * search.c (current_obstack): Remove.
- * typeck2.c (add_exception_specifier): Don't call build_decl_list.
-
-2000-10-09 Richard Henderson <rth@cygnus.com>
-
- * Make-lang.in (CXX_EXTRA_HEADERS): Remove.
- (c++ language support bits for libgcc): Remove.
- (c++.clean): Remove cplib2.txt cleanup.
- * config-lang.in (headers, lib2funcs): Remove.
-
- * exception.cc, new.cc, new1.cc, new2.cc: Remove files.
- * tinfo.cc, tinfo.h, tinfo2.cc, vec.cc: Remove files.
- * inc/cxxabi.h, inc/exception, inc/new: Remove files.
- * inc/new.h, inc/typeinfo: Remove files.
-
-2000-10-08 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl.c (INTMAX_TYPE, UINTMAX_TYPE): Define if not already
- defined.
- (init_decl_processing): Initialize intmax_type_node and
- uintmax_type_node.
-
-2000-10-06 Richard Henderson <rth@cygnus.com>
-
- * cp-tree.h (struct cp_language_function): Remove x_result_rtx.
- (original_result_rtx): Remove.
- * decl.c (save_function_data): Don't clear x_result_rtx.
- (mark_lang_function): Don't mark it either.
- * expr.c (fixup_result_decl): Remove.
- * semantics.c (genrtl_named_return_value): Frob the return decl
- before calling emit_local_var.
- (genrtl_finish_function): Don't call fixup_result_decl.
- Always emit the jump to return_label.
-
-2000-10-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (lookup_template_class): Set current access for enum.
- (tsubst_enum): Set file & line for enum decl.
-
- * spew.c (yylex): Remove unused variable.
-
-2000-10-05 Richard Henderson <rth@cygnus.com>
-
- * semantics.c (genrtl_finish_function): Don't init or check
- can_reach_end; remove noreturn and return value checks.
-
-2000-10-05 Tom Tromey <tromey@cygnus.com>
-
- * init.c (build_java_class_ref): Use `build_static_name' with a
- suffix, not a prefix, to build the class object's name.
-
-2000-10-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (access_kind): Fix comment typo.
- * decl2.c (grokfield): Fix diagnostic typo.
- * semantics.c (finish_template_type): Fix comment typo.
- (finish_qualified_object_call_expr): Likewise.
-
-2000-10-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (tsubst_expr, DECL_STMT case): Don't process if
- tsubsting fails.
-
-2000-10-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * spew.c (frob_id): New static function.
- (frob_opname): Use it.
- (yylex): Use it.
-
-2000-10-01 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (lang_mark_false_label_stack): Remove.
- * lex.c (cp_mang_lang_type): Use ggc_alloc_cleared.
-
-2000-09-30 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * gxxint.texi: Use @email for formatting email addresses.
-
-2000-09-29 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c: Remove direct obstack manipulation. Replace with
- output_buffer-based formatting. Adjust calls to removed macros.
- (obstack_chunk_alloc, obstack_chunk_free): Remove.
- (OB_INIT, OB_PUTC, OB_PUTC2, OB_PUTS, OB_PUTID, OB_PUTCP,
- OB_FINISH, OB_PUTI, OB_END_TEMPLATE): Likewise.
-
-2000-09-24 Mark Mitchell <mark@codesourcery.com>
-
- * ir.texi: Move to ../c-tree.texi.
-
-2000-09-20 Jason Merrill <jason@redhat.com>
-
- * decl2.c (get_guard): Check DECL_FUNCTION_SCOPE_P.
-
-2000-09-21 Andreas Jaeger <aj@suse.de>
-
- * errfn.c: Move declaration of cp_printer and cp_printers to ...
- * cp-tree.h: ... here.
-
- * error.c: Remove declaration of cp_printer.
-
-2000-09-20 Mark Mitchell <mark@codesourcery.com>
-
- * tree.c (mark_local_for_remap_r): Handle CASE_LABELs.
-
-2000-09-20 Hans-Peter Nilsson <hp@axis.com>
-
- * except.c: Delete #if 0:d EXCEPTION_SECTION_ASM_OP-default and
- users.
-
-2000-09-18 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (start_function): Robustify.
-
-2000-09-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * cp-tree.h (check_function_format): Accept a `status' parameter.
-
- * call.c, typeck.c: Updates calls to `check_function_format'.
-
-2000-09-17 Geoffrey Keating <geoffk@cygnus.com>
-
- * decl2.c (handle_class_head): Always push some scope even
- in the error case.
-
-2000-09-16 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (struct cp_language_function): Remove
- x_scope_stmt_stack and name_declared.
- (current_scope_stmt_stack): Remove.
- (function_name_declared_p): New macro.
- (struct lang_decl_flags): Use c_lang_decl as a base class.
- (context): Remove.
- (struct lang_decl): Replace saved_tree with context.
- (DECL_FRIEND_CONTEXT): Adjust accordingly.
- (SET_DECL_FRIEND_CONTEXT): Likewise.
- (DECL_VIRTUAL_CONTEXT): Likewise.
- (DECL_SAVED_TREE): Remove.
- (C_DECLARED_LABEL_FLAG): Likewise.
- (cplus_expand_expr_stmt): Don't declare.
- (add_decl_stmt): Likewise.
- (add_scope_stmt): Likewise.
- * decl.c (mark_stmt_tree): Remove.
- (case_compare): Likewise.
- (finish_case_label): Use c_add_case_label.
- (init_decl_processing): Set more language-specific hooks.
- (build_enumerator): Fix typo in comment.
- (cplus_expand_expr_stmt): Remove.
- (mark_lang_function): Use mark_c_language_function.
- (lang_mark_tree): Use c_mark_lang_decl.
- * decl2.c: Change order of inclusion.
- * except.c: Likewise.
- * expr.c (cplus_expand_expr): Remove handling of STMT_EXPR. Fall
- back on c_expand_expr.
- * friend.c: Include expr.h.
- * init.c: Change order of inclusion.
- * Makefile.in: Update dependencies.
- * lex.h (free_lang_decl_chain): Remove.
- * optimize.c (maybe_clone_body): Use function_name_declared_p.
- * pt.c (build_template_decl): Don't copy DECL_VIRTUAL_CONTEXT if
- it doesn't exist.
- (instantiate_decl): Use function_name_declared_p.
- * semantics.c (lang_expand_expr_stmt): Remove.
- (set_current_function_name_declared): Likewise.
- (current_function_name_declared): Likewise.
- (begin_compound_stmt): Use function_name_declared_p.
- (add_decl_stmt): Remove.
- (setup_vtbl_ptr): Use function_name_declared_p.
- (add_scope_stmt): Remove.
- (current_scope_stmt_stack): New function.
- (cp_expand_stmt): Don't handle SCOPE_STMTs.
- (expand_body): Use function_name_declared_p.
- * tree.c (cp_statement_code_p): Don't include SCOPE_STMT.
- * typeck.c: Change order of includes.
- (convert_sequence): Remove.
-
-2000-09-14 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * lex.c (reswords): Add _Complex.
-
-Thu Sep 14 12:10:45 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * Make-lang.in (cplib2.txt): Depend on cp/Makefile.
-
-2000-09-13 J. David Anglin <dave@hiauly1.hia.nrc.ca>
-
- * init.c (begin_init_stmts): Don't use // comments.
-
-2000-09-12 Jason Merrill <jason@redhat.com>
-
- * decl.c (maybe_deduce_size_from_array_init): Set do_default for
- all non-extern arrays.
-
- * decl.c (grokdeclarator): Complain about 'friend T' for implicit
- typenames, too. Downgrade complaint to pedwarn.
- (xref_tag): Warn about surprising behavior of 'friend struct T'.
- * decl2.c (handle_class_head): Generate a TYPENAME_TYPE for
- 'class This::Inherited'.
-
-2000-09-12 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (finish_case_label): Given the LABEL_DECL a
- DECL_CONTEXT.
-
-2000-09-12 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c (TFF_PLAIN_IDENTIFIER, TFF_NAMESPACE_SCOPE,
- TFF_CLASS_SCOPE, TFF_CHASE_NAMESPACE_ALIAS, TFF_CHASE_TYPDEF,
- TFF_DECL_SPECIFIERS, TFF_CLASS_KEY_OR_ENUM, TFF_RETURN_TYPE,
- TFF_FUNCTION_DEFAULT_ARGUMENTS, TFF_EXCEPTION_SPECIFICATION,
- TFF_TEMPLATE_HEADER, TFF_TEMPLATE_DEFAULT_ARGUMENTS, TFF_SCOPE):
- New macros.
- (sorry_for_unsupported_tree, print_scope_operator,
- print_left_paren, print_right_paren, print_left_bracket,
- print_right_bracket, print_whitespace): Likewise.
- (aggr_variety): Rename to class_key_or_enum.
- (print_type): Rename to print_type_id.
- (print_type_specifier_seq, print_simple_type_specifier,
- print_elaborated_type_specifier,
- print_rest_of_abstract_declarator,
- print_parameter_declaration_clause, print_exception_specification,
- print_nested_name_specifier, print_template_id,
- typedef_original_name, print_template_argument_list_start,
- print_template_argument_list_end): New functions.
-
-2000-09-11 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * ir.texi: Add more documentation.
-
-2000-09-11 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (struct saved_scope): Remove x_function_parms.
- (current_function_parms): Don't define.
- (struct cp_language_function): Remove parms_stored.
- (current_function_just_assigned_this): Don't define.
- (current_function_parms_stored): Likewise.
- (static_ctors): Declare.
- (static_dtors): Likewise.
- (SF_EXPAND): Don't define.
- (expand_start_early_try_stmts): Remove declaration.
- (store_parm_decls): Likewise.
- * decl.c (static_ctors): Don't declare.
- (static_dtors): Likewise.
- (struct binding_level): Remove this_block.
- (poplevel): Remove dead code.
- (set_block): Likewise.
- (mark_binding_level): Don't mark this_block.
- (mark_saved_scope): Don't mark x_function_parms.
- (init_decl_processing): Don't add current_function_parms as a GC
- root.
- (check_function_type): Change prototype.
- (start_function): Remove RTL-generation code.
- (expand_start_early_try_stmts): Remove.
- (store_parm_decls): Give it internal linkage. Remove
- RTL-generation code.
- (finish_function): Remove RTL-generation code.
- * decl2.c (static_ctors): Fix formatting.
- (static_dtors): Likewise.
- * method.c (use_thunk): Don't call store_parm_decls.
- (synthesize_method): Likewise.
- * optimize.c (maybe_clone_body): Likewise.
- * parse.y (fn.def2): Likewise.
- (.set_base_init): Likewise.
- (nodecls): Likewise.
- * pt.c (instantiate_decl): Likewise.
- * rtti.c (synthesize_tinfo_fn): Likewise.
- * semantics.c (genrtl_try_block): Simplify.
- (expand_body): Use genrtl_start_function and
- genrtl_finish_function.
- (genrtl_start_function): New function.
- (genrtl_finish_function): Likewise.
-
-2000-09-11 Nathan Sidwell <nathan@codesourcery.com>
-
- * error.c (cp_tree_printer, case 'P'): Append break.
-
-2000-09-11 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (frob_opname): Declare.
- * parse.y (saved_scopes): New static variable.
- (cp_parse_init): Adjust.
- (do_id): If lastiddecl is NULL, do do_identifier.
- (operator): Save scope information.
- (unoperator): New reduction. Restore scope information.
- (operator_name): Append unoperator. Call frob_opname.
- * spew.c (frob_opname): Define.
-
-2000-09-10 Zack Weinberg <zack@wolery.cumb.org>
-
- * decl.c, rtti.c: Include defaults.h if not already included.
- Don't define the *_TYPE_SIZE macros.
-
-2000-09-09 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (push_switch): Change prototype.
- (check_cp_case_value): Remove declaration.
- (decl_constant_value): Likewise.
- * decl.c (struct cp_switch): Add switch_stmt and cases.
- (case_compare): New function.
- (push_switch): Set switch_stmt. Initialize cases.
- (pop_switch): Clean up cases.
- (define_case_label): Rename to ...
- (finish_case_label): ... this. Do semantic analysis for case
- labels here.
- (start_function): Correct comment.
- * decl2.c (check_cp_case_value): Remove.
- * expr.c (do_case): Remove.
- * pt.c (tsubst_expr): Adjust call to finish_case_label.
- * semantics.c (genrtl_do_poplevel): Remove declaration.
- (RECHAIN_STMTS): Remove.
- (finish_break_stmt): Use build_break_stmt.
- (finish_continue_stmt): Use build_continue_stmt.
- (finish_switch_cond): Adjust condition here, rater than in
- c_expand_start_case.
- (finish_case_label): Remove.
- * typeck.c (c_expand_return): Remove.
- (c_expand_start_case): Likewise.
-
-2000-09-07 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * ir.texi: Document type nodes.
-
-2000-09-06 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (init_cp_semantics): Declare.
- (genrtl_try_block): Don't declare.
- (genrtl_handler): Likewise.
- (genrtl_catch_block): Likewise.
- (genrtl_ctor_stmt): Likewise.
- (genrtl_subobject): Likewise.
- (genrtl_do_poplevel): Likewise.
- (genrtl_named_return_value): Likewise.
- * lex.c (init_parse): Call init_cp_semantics.
- * semantics.c (genrtl_try_block): Give it internal linkage.
- (genrtl_handler): Likewise.
- (genrtl_catch_block): Likewise.
- (genrtl_ctor_stmt): Likewise.
- (genrtl_subobject): Likewise.
- (genrtl_do_poplevel): Likewise.
- (genrtl_named_return_value): Likewise.
- (lang_expand_stmt): Rename to ...
- (cp_expand_stmt): ... this. Only handle C++-specific nodes.
- (init_cp_semantics): Define.
-
- * decl.c (initialize_local_var): Remove RTL-generating code.
- * semantics.c (genrtl_try_block): Fix formatting.
-
- Move statement-tree facilities from C++ to C front-end.
- * cp-tree.h (cp_tree_index): Remove CPTI_VOID_ZERO.
- (void_zero_node): Remove.
- (stmt_tree): Likewise.
- (scope_chain): Adjust.
- (language_function): Rename to cp_language_function.
- (cp_function_chain): Adjust.
- (current_stmt_tree): Remove.
- (last_tree): Likewise.
- (last_expr_type): Likewise.
- (struct lang_decl): Adjust.
- (STMT_IS_FULL_EXPR_P): Remove.
- (add_tree): Remove.
- (begin_stmt_tree): Likewise.
- (finish_stmt_tree): Likewise.
- (walk_tree_fn): Likewise.
- (walk_stmt_tree): Likewise.
- * class.c (finish_struct): Replace use of add_tree with add_stmt.
- * decl.c (mark_stmt_tree): Adjust type.
- (init_decl_processing): Don't build void_zero_node.
- (initialize_local_var): Adjust usage of current_stmt_tree.
- (finish_enum): Use add_stmt, not add_tree.
- (save_function_data): Adjust use of language_function.
- (finish_constructor_body): Use add_stmt, not add_tree.
- (finish_destructor_body): Likewise.
- (push_cp_function_context): Adjust use of language_function.
- (pop_cp_function_context): Likewise.
- (mark_lang_function): Likewise.
- (mark_cp_function_context): Likewise.
- * init.c (build_aggr_init): Adjust use of current_stmt_tree.
- (build_vec_init): Likewise.
- * semantics.c (SET_LAST_STMT): Remove.
- (RECHAIN_STMTS): Don't use it.
- (stmts_are_full_exprs_p): Adjust use of current_stmt_tree.
- (current_stmt_tree): Define.
- (add_tree): Remove.
- (finish_goto_stmt): Use add_stmt, not add_tree.
- (finish_expr_stmt): Likewise.
- (begin_if_stmt): Likewise.
- (finish_then_clause): Likewise.
- (begin_while_stmt): Likewise.
- (begin_do_stmt): Likewise.
- (finish_return_stmt): Likewise.
- (begin_for_stmt): Likewise.
- (finish_break_stmt): Likewise.
- (finish_continue_stmt): Likewise.
- (begin_switch_stmt): Likewise.
- (finish_case_label): Likewise.
- (begin_try_block): Likewise.
- (begin_function_try_block): Likewise.
- (begin_handler): Likewise.
- (begin_catch_block): Likewise.
- (begin_compound_stmt): Likewise.
- (begin_asm_stmt): Likewise.
- (finish_asm_stmt): Likewise.
- (finish_label_stmt): Likewise.
- (add_decl_stmt): Likewise.
- (finish_subobject): Likewise.
- (finish_decl_cleanup): Likewise.
- (finish_named_return_value): Likewise.
- (setup_vtbl_ptr): Likewise.
- (add_scope_stmt): Likewise.
- (finish_stmt_expr): Likewise.
- (prune_unused_decls): Remove.
- (begin_stmt_tree): Likewise.
- (finish_stmt_tree): Likewise.
- (prep_stmt): Adjust use of current_stmt_tree.
- (lang_expand_stmt): Likewise.
- * tree.c (statement_code_p): Remove.
- (cp_statement_code_p): New function.
- (walk_stmt_tree): Remove.
- (init_tree): Set lang_statement_code_p.
-
-2000-09-06 Zack Weinberg <zack@wolery.cumb.org>
-
- Integrated preprocessor.
-
- * Make-lang.in, Makefile.in: Remove all references to input.c,
- gxx.gperf, and hash.h. Add ../c-lex.o to C_OBJS.
- * gxx.gperf, hash.h, input.c: Delete.
- * lang-specs.h: Pass -lang-c++ to cc1plus so cpplib is
- initialized properly.
-
- * class.c (fixup_pending_inline): Take a tree, not a
- struct pending_inline *. All callers changed.
- (init_class_processing): Set RID_PUBLIC, RID_PRIVATE,
- RID_PROTECTED entries in ridpointers[] array here.
- * decl.c (duplicate_decls): Do not refer to struct
- pending_inline.
- (record_builtin_type, init_decl_processing): Use RID_MAX not
- CP_RID_MAX.
- (grokdeclarator): Use C_IS_RESERVED_WORD.
- * decl2.c (lang_decode_option): Ignore -lang-c++ for sake of
- cpplib.
- (grok_x_components): Do not inspect pending_inlines chain.
-
- * cp-tree.h (struct lang_identifier): Add rid_code entry.
- (C_IS_RESERVED_WORD, C_RID_CODE, C_RID_YYCODE): New.
- (flag_no_gnu_keywords, flag_operator_names, rid_to_yy): Declare.
- (DEFARG_LENGTH, struct pending_inline, TIME_IDENTIFIER_TIME,
- TIME_IDENTIFIER_FILEINFO): Kill.
- Update prototypes.
- * lex.h: Expunge cp_rid. Rewrite RIDBIT macros to use just a
- single 32-bit word.
- * parse.y: Call do_pending_inlines unconditionally.
- reinit_parse_for_method is now snarf_method. fn.defpen is no
- longer necessary. Remove unnecessary <itype> annotation on
- SCOPE. Do not refer to end_of_file or struct pending_inline.
- * semantics.c (begin_inline_definitions): Call
- do_pending_inlines unconditionally.
-
- * lex.c: Remove all code now shared with C front end.
- Initialize cpplib properly if USE_CPPLIB. Put reserved words
- into the get_identifier table. Rewrite pragma handling to
- work with the registry. Move code to save tokens for later
- processing to spew.c.
-
- * spew.c: Rewrite everything in terms of token streams instead
- of text. Move routines here from lex.c / input.c as
- appropriate. GC-mark trees hanging off the pending inlines
- chain.
-
-2000-09-06 Mark Mitchell <mark@codesourcery.com>
-
- * NEWS: Mention that the named return value extension has been
- deprecated.
- * cp-tree.h (original_result_rtx): Define.
- (TREE_REFERENCE_EXPR): Remove.
- (DECL_VPARENT): Likewise.
- (pushdecl_nonclass_level): Likewise.
- (store_return_init): Likewise.
- (reinit_lang_specific): Likewise.
- (genrtl_named_return_value): Change prototype.
- * decl.c (original_result_rtx): Remove.
- (cp_finish_decl): Don't build DECL_STMTs for RESULT_DECLs.
- Do not generate RTL for local variables here.
- (store_return_init): Remove.
- * semantics.c (genrtl_named_return_value): Simplify. Fold in
- store_return_init.
- (finish_named_return_value): Adjust accordingly. Warn that this
- extension is deprecated.
- (lang_expand_stmt): Adjust call to genrtl_named_return_value.
-
-2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (type_unification_real): Replace switch with if.
- (unify): Tsubst non-type parms before comparing.
-
-2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * error.c (dump_typename): New function, broken out of ...
- (dump_type): ... here. Use it.
- * typeck.c (same_type_p): Use cp_tree_equal for TYPENAME_TYPE.
-
-2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * init.c (build_offset_ref): Deal with namespace scoped
- TEMPLATE_ID_EXPRs.
-
-2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (resolve_address_of_overloaded_function): Add
- explanation message.
- * decl.c (define_case_label): Reformat explanation.
- * decl2.c (finish_static_data_member_decl): Likewise.
- (grokfield): Likewise.
- * friend.c (do_friend): Likewise.
-
-2000-09-05 Zack Weinberg <zack@wolery.cumb.org>
-
- * tree.c (walk_tree): Expose tail recursion.
- (walk_stmt_tree): New function.
- * cp-tree.h: Prototype walk_stmt_tree.
- * semantics.c (prune_unused_decls): Operate on SCOPE_STMTs not
- the BLOCKs directly. If a BLOCK has no variables after
- pruning, discard it.
- (finish_stmt_tree): Use walk_stmt_tree. No need to save and
- restore the line number.
-
-2000-09-05 Mark Mitchell <mark@codesourcery.com>
-
- * Makefile.in (CXX_TREE_H): Add dependency on HTAB_H.
- (pt.o): Remove dependency on HTAB_H.
- * cp-tree.h: Include hashtab.h.
- (walk_tree): Change prototype.
- (walk_tree_without_duplicates): New function.
- * decl.c (check_default_argument): Use it.
- * optimize.c (remap_decl): Adjust calls to walk_tree.
- (copy_body): Likewise.
- (expand_calls_inline): Likewise.
- (calls_setjmp_p): Use walk_tree_without_duplicates.
- * pt.c: Don't include hashtab.h.
- (for_each_template_parm): Use walk_tree_without_duplicates.
- * semantics.c (finish-stmt_tree): Likewise.
- (expand_body): Likewise.
- * tree.c (walk_tree): Add additional parameter.
- (walk_tree_without_duplicates): New function.
- (count_trees): Use it.
- (verify_stmt_tree): Adjust call to walk_tree.
- (find_tree): Use walk_tree_without_duplicates.
- (no_linkage_check): Likewise.
- (break_out_target_exprs): Adjust call to walk_tree.
- (cp_unsave): Likewise.
-
-2000-09-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
-
- * cp-tree.def (BOUND_TEMPLATE_TEMPLATE_PARM): New tree code.
- (TEMPLATE_TEMPLATE_PARM): Adjust comment.
- * cp-tree.h (TYPE_BINFO): Adjust comment.
- (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise.
- (TEMPLATE_TYPE_PARM_INDEX): Likewise.
- (IS_AGGR_TYPE): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
- (TYPE_TEMPLATE_INFO): Likewise.
- (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): Likewise.
- * class.c (push_nested_class): Likewise.
- * decl.c (lookup_name_real): Likewise.
- (grokdeclarator): Likewise.
- (grok_op_properties): Likewise.
- (xref_tag): Likewise.
- (xref_basetypes): Likewise.
- * decl2.c (constructor_name_full): Likewise.
- (arg_assoc_template_arg): Add TEMPLATE_TEMPLATE_PARM case.
- (arg_assoc_type): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
- * error.c (dump_type): Split TEMPLATE_TEMPLATE_PARM case.
- (dump_type_prefix): Add BOUND_TEMPLATE_TEMPLATE_PARM.
- (dump_type_suffix): Likewise.
- * init.c (is_aggr_type): Use BOUND_TEMPLATE_TEMPLATE_PARM
- instead.
- (get_aggr_from_typedef): Likewise.
- * mangle.c (write_type): Split TEMPLATE_TEMPLATE_PARM case.
- (write_expression): Add BOUND_TEMPLATE_TEMPLATE_PARM.
- (write_template_parm): Likewise.
- (write_template_template_parm): Check tree code instead of
- using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
- * method.c (build_overload_nested_name): Add
- BOUND_TEMPLATE_TEMPLATE_PARM.
- (process_overload_item): Split TEMPLATE_TEMPLATE_PARM case.
- * parse.y (bad_parm): Add BOUND_TEMPLATE_TEMPLATE_PARM.
- * pt.c (convert_template_argument): Check tree code instead of
- using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
- (for_each_template_parm_r): Split TEMPLATE_TEMPLATE_PARM case.
- (for_each_template_parm): Adjust comment.
- (tsubst): Add BOUND_TEMPLATE_TEMPLATE_PARM. Reorganize.
- (tsubst_copy): Add BOUND_TEMPLATE_TEMPLATE_PARM.
- (unify): Add BOUND_TEMPLATE_TEMPLATE_PARM. Reorganize. Use
- template_args_equal to compare template template parameter cases.
- * ptree.c (print_lang_type): Add BOUND_TEMPLATE_TEMPLATE_PARM.
- * search.c (lookup_field_1): Use BOUND_TEMPLATE_TEMPLATE_PARM
- instead.
- * tree.c (copy_template_template_parm): Decide whether to create
- a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM node.
- (walk_tree): Add BOUND_TEMPLATE_TEMPLATE_PARM.
- (copy_tree_r): Likewise.
- * typeck.c (comptypes): Likewise. Check tree code instead of
- using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
-
-2000-09-04 Mark Elbrecht <snowball3@bigfoot.com>
-
- * decl.c (finish_function): Move the code for handling functions
- marked with the constructor and destructor attributes inside the
- expand_p block.
-
-2000-09-04 Nathan Sidwell <nathan@codesourcery.com>
-
- * init.c (resolve_offset_ref): Deal with TEMPLATE_ID_EXPR.
-
-2000-09-04 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (lookup_template_class): Remove abort.
- * tree.c (get_type_decl): Allow error_mark_node.
-
-2000-09-04 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl2.c (arg_assoc): Deal with COMPONENT_REFs inside
- TEMPLATE_ID_EXPRs.
-
-2000-09-03 Mark Mitchell <mark@codesourcery.com>
-
- * operators.def (ALIGNOF_EXPR, MAX_EXPR, MIN_EXPR): Change
- new ABI mangling.
-
-2000-09-01 Nathan Sidwell <nathan@codesourcery.com>
-
- * parse.y (named_class_head): Check for TYPENAME_TYPE. Simplify
- union tag mismatch error reporting.
-
-2000-09-01 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (build_scoped_method_call): Check it is not a namespace.
-
-2000-08-30 Jason Merrill <jason@redhat.com>
-
- * cp-tree.h (LOCAL_CLASS_P): Use decl_function_context.
-
- * tree.c (bot_manip): Check TREE_CONSTANT rather than
- !TREE_SIDE_EFFECTS. Call break_out_target_exprs and
- build_target_expr_with_type for the non-AGGR_INIT_EXPR case.
-
- * decl.c (start_function): Always call make_function_rtl.
-
-2000-08-29 Zack Weinberg <zack@wolery.cumb.org>
-
- * semantics.c (prune_unused_decls): New function.
- (finish_stmt_tree): Call it via walk_tree.
-
-2000-08-29 Zack Weinberg <zack@wolery.cumb.org>
-
- * class.c (build_secondary_vtable): Constify a char *.
- * decl.c (init_decl_processing): Initialize function_id_node,
- pretty_function_id_node, and func_id_node.
- * input.c (struct input_source): Constify 'str'.
- (feed_input): Constify first argument.
- * mangle.c (write_identifier): Constify argument.
- * pt.c (mangle_class_name_for_template): Constify argument.
-
-2000-08-29 Mark Mitchell <mark@codesourcery.com>
-
- * typeck.c (mark_addressable): Remove code that pokes around in
- RTL.
-
-2000-08-28 Jason Merrill <jason@redhat.com>
-
- * lex.c (file_name_nondirectory): Move to toplev.c.
-
- * cp-tree.h (LOCAL_CLASS_P): New macro.
- * class.c (finish_struct_1): Use it.
-
-2000-08-27 Alex Samuel <samuel@codesourcery.com>
-
- * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Remove unexplained voodoo.
- (write_encoding): Pass another argument to write_name.
- (write_name): Add ignore_local_scope parameter. Fix handling of
- local names.
- (write_nested_name): Use write_unqualified_name.
- (write_prefix): Likewise. Skip out on FUNCTION_DECLs.
- (write_template_prefix): Use write_unqualified_name.
- (write_component): Remove.
- (write_local_name): Add parameter. Use direct local entity to
- discriminator calculation.
- (write_class_enum_type): Pass another argument to write_name.
- (write_template_template_arg): Likewise.
- (make_guard_variable): Likewise.
-
-2000-08-27 Jason Merrill <jason@redhat.com>
-
- * decl.c (pushdecl): Matching decls for local externs are found in
- the current level. Propagate linkage information from previous
- declarations.
-
-2000-08-26 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * ir.texi (Expressions): Fix typo.
-
-2000-08-25 Greg McGary <greg@mcgary.org>
-
- * tree.c (init_tree): Use ARRAY_SIZE.
-
-2000-08-25 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c (cp_tree_printer): Rework.
-
-2000-08-25 Mark Mitchell <mark@codesourcery.com>
-
- * Make-lang.in (CXX_LIB2FUNCS): Remove cp-demangle.o and
- dyn-string.o.
- (CXX_LIB2SRCS): Remove cp-demangle.c and dyn-string.c.
- (cp-demangle.o): Remove target.
- (dyn-string.o): Likewise.
-
- * decl.c (grokfndecl): Require that `main' return an `int'.
- * mangle.c (write_encoding): Don't mangle return types for
- conversion functions.
-
-2000-08-25 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c (tree_formatting_info): New data type.
- (tree_being_formatted): New macro.
- (tree_formatting_flags): Likewise.
- (put_whitespace): Likewise.
- (print_tree_identifier): Likewise.
- (print_identifier): Likewise.
- (cp_tree_printer, print_function_argument_list, print_declaration,
- print_expression, print_function_declaration,
- print_function_parameter, print_type, print_cv_qualifier): New
- functions.
- (init_error): Initialize lang_printer.
-
-2000-08-24 Jason Merrill <jason@redhat.com>
-
- * typeck.c (build_ptrmemfunc): Just reinterpret if there's no
- adjustment necessary.
-
-2000-08-24 Greg McGary <greg@mcgary.org>
-
- * cp-tree.h (MAIN_NAME_P): Remove macro.
-
-2000-08-24 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c (print_instantiation_context): Don't forget to flush the
- buffer.
-
-2000-08-23 Jason Merrill <jason@redhat.com>
-
- * typeck.c (build_ptrmemfunc): Save the input pmf.
-
- * method.c (process_modifiers): Use same_type_p.
-
-2000-08-23 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (DECL_CLONED_FUNCTION_P): Check DECL_LANG_SPECIFIC.
- * mangle.c (write_function_type): Change prototype.
- (write_encoding): Don't mangle return types for
- constructors or destructors.
- (write_type): Adjust call to write_function_type.
- * pt.c (instantiate_template): Instantiate alternate entry points
- when instantiating the main function.
-
-2000-08-23 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * error.c (cp_print_error_function): Don't use embedded '\n' in
- output_printf.
-
-2000-08-23 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * decl.c (init_decl_processing): Remove bogus initialization.
- * error.c (lang_print_error_function): Restore here.
- (init_error): Initialize print_error_function.
-
-2000-08-22 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
-
- * decl2.c (arg_assoc): Revert my 2000-08-11 change.
-
-2000-08-22 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * Makefile.in (error.o): Depends on diagnostic.h
-
- * cp-tree.h (problematic_instantiation_changed,
- record_last_problematic_instantiation, current_instantiation,
- print_instantiation_context): Declare.
- (maybe_print_template_context): Remove.
-
- * decl.c (init_decl_processing): Set print_error_function to NULL.
- (lang_print_error_function): Remove, since we're using a new
- machinery.
-
- * error.c: #include diagnostic.h
- (function_category): New function.
- (cp_diagnostic_starter): Likewise.
- (cp_diagnostic_finalizer): Likewise.
- (cp_print_error_function): Likewise.
- (maybe_print_instantiation_context): Likewise.
- (print_instantiation_full_context): Likewise.
- (print_instantiation_partial_context): Likewise.
- (print_instantiation_context): Define.
- (init_error): Initialize diagnostic pager and finalizer.
-
- * pt.c (problematic_instantiation_changed): Define.
- (record_last_problematic_instantiation): Likewise.
- (current_instantiation): Likewise.
- (maybe_print_template_context): Remove.
- (print_template_context): Likewise.
- (current_tinst_level): Make static to reflect Brendan Kehoe's
- change of 1995-04-13.
- (push_tinst_level): Call print_instantiation_context.
-
-2000-08-21 Nix <nix@esperi.demon.co.uk>
-
- * lang-specs.h: Do not process -o or run the assembler if
- -fsyntax-only.
-
-2000-08-21 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl.c (flag_hosted, flag_noniso_default_format_attributes): New
- variables.
- * decl2.c (lang_decode_option): Disable gettext attributes for
- -ansi.
-
-2000-08-21 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * lex.c (lang_init_options): Default diagnostic message maximum
- length to 80, when line-wrapping.
-
-2000-08-20 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (build_vtbl_initializer): Clear the entire
- vtbl_init_data. Start keeping track of the functions for which we
- have created vcall offsets here.
- (dfs_build_vcall_offset_vtbl_entries): Remove.
- (build_vcall_offset_vtbl_entries): Reimplement.
- (add_vcall_offset_vtbl_entries_r): New function.
- (add_vcall_offset_vtbl_entries_1): Likewise. Tweak logic for
- computing when vcall offsets are necessary.
-
-2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (member_function_or_else): Use cp_error ... %T.
- (grokdeclarator): Likewise.
- (start_method): Likewise.
- * friend.c (make_friend_class): Use cp_pedwarn ... %T.
-
-2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl2.c (grokfield): Set CLASSTYPE_GOT_SEMICOLON on class
- TYPE_DECLs.
-
-2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (PTRMEM_OK_P): New macro.
- (itf_ptrmem_ok): New enumeration value.
- * class.c (resolve_address_of_overloaded_function): Add PTRMEM
- argument. Diagnose implicit pointer to member.
- (instantiate_type): Don't diagnose implicit pointer to member
- here. Pass itf_ptrmem_ok if ok. Adjust calls to
- resolve_address_of_overloaded_function.
- * init.c (build_offset_ref): Set PTRMEM_OK_P.
- (resolve_offset_ref): Don't diagnose implicit pointer to member here.
- * semantics.c (finish_parenthesized_expr): Clear OFFSET_REFs here.
- * typeck.c (build_x_unary_op): Calculate PTRMEM_OK_P.
- (build_unary_op): Deal with single non-static member in
- microsoft-land.
-
-2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl2.c (arg_assoc_type): Cope with TYPENAME_TYPE.
-
-2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (enum_name_string): Remove prototype.
- (report_case_error): Remove prototype.
- * cp/typeck2.c (enum_name_string): Remove.
- (report_case_error): Remove.
- * error.c (dump_expr): Deal with enum values directly.
- Correctly negate integer constant.
-
-2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
-
- * inc/cxxabi.h (__cxa_vec_new2, __cxa_vec_new3): Declare.
- (__cxa_vec_delete2, __cxa_vec_delete3): Declare.
- * vec.cc (__cxa_vec_new2, __cxa_vec_new3): Implement.
- (__cxa_vec_delete2, __cxa_vec_delete3): Implement.
- (__cxa_vec_new): Use __cxa_vec_new2.
- (__cxa_vec_delete): Use __cxa_vec_delete2.
-
-2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
-
- * vec.cc (__cxa_vec_new): Set "C" linkage.
- (__cxa_vec_ctor): Likewise.
- (__cxa_vec_cctor): Likewise.
- (__cxa_vec_dtor): Likewise.
- (__cxa_vec_delete): Likewise.
- * inc/cxxabi.h (__cxa_vec_new): Set "C" linkage.
- (__cxa_vec_ctor): Likewise.
- (__cxa_vec_cctor): Likewise.
- (__cxa_vec_dtor): Likewise.
- (__cxa_vec_delete): Likewise.
-
-2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (instantiate_type): Reinstate local variable
- deleted in previous change.
-
- * cvt.c (cp_convert_to_pointer): Pass itf_complain, not
- itf_no_attributes.
-
-2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (instantiate_type_flags): New enumeration.
- (instantiate_type): Change parameter.
- * class.c (instantiate_type): Adjust prototype. Adjust.
- * call.c (standard_conversion): Adjust instantiate_type call.
- (reference_binding): Likewise.
- (build_op_delete_call): Likewise.
- (convert_like_real): Likewise.
- * cvt.c (cp_convert_to_pointer): Likewise.
- (convert_to_reference): Likewise.
- * pt.c (convert_nontype_argument): Likewise.
- * typeck.c (build_binary_op): Likewise.
- (build_ptrmemfunc): Likewise.
- (convert_for_assignment): Likewise.
-
-2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (CPTR_AGGR_TAG): New global tree node.
- (current_aggr): Define.
- * decl.c (grokdeclarator): Make sure a friend class is an
- elaborated type specifier.
- * parse.y (current_aggr): Remove static definition.
- (cp_parse_init): Adjust.
- (structsp): Clear and restore current_aggr.
- (component_decl_list): Clear current_aggr.
-
- * error.c (dump_type, case TYPENAME_TYPE): Don't emit the
- aggregate tag on the typename's context.
-
- * pt.c (tsubst_friend_class): Return error_mark_node, if
- parms becomes NULL.
- (instantiate_class_template): Ignore error_mark_node friend types.
-
-2000-08-14 Nathan Sidwell <nathan@codesourcery.com>
-
- * cvt.c (warn_ref_binding): New static function, broken out of ...
- (convert_to_reference): ... here. Use it.
-
-2000-08-11 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
-
- * parse.y (template_arg): Add rule for template qualified with
- global scope.
-
-2000-08-11 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
-
- * decl2.c (add_function): Reorganize.
- (arg_assoc): Do not consider function template decls.
-
-2000-08-11 Jason Merrill <jason@redhat.com>
-
- * decl.c (lookup_name_real): Don't forget the TYPENAME_TYPE we're
- looking inside.
-
-2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (resolve_scope_to_name): Remove unused prototype.
- (lookup_nested_tag): Likewise.
-
- * decl2.c (grokfield): Fix comment to reflect many types of _DECLs
- can be produced.
-
-2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
-
- * parse.y (named_complex_class_head_sans_basetype): Remove
- always true if.
-
-2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl2.c (build_expr_from_tree, case METHOD_CALL_EXPR): Build
- explicit TEMPLATE_ID_EXPR args.
- (build_expr_from_tree, case CALL_EXPR): Likewise.
-
-2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (check_tag_decl): Diagnose typename's which don't
- declare anything.
-
-2000-08-10 Nathan Sidwell <nathan@codesourcery.com>
-
- * init.c (build_aggr_init): Reject bogus array initializers
- early.
-
-2000-08-09 Nathan Sidwell <nathan@codesourcery.com>
-
- * rtti.c (build_dynamic_cast_1): Set "C" linkage for new abi
- runtime.
- * cp/tinfo.cc (__dynamic_cast): Likewise.
- * cp/inc/cxxabi.h (__dynamic_cast): Likewise.
-
-2000-08-09 Nathan Sidwell <nathan@codesourcery.com>
-
- * cvt.c (convert_to_pointer_force): Fix error message when
- attempting to cast from ambiguous base.
-
-2000-08-08 Jason Merrill <jason@redhat.com>
-
- * pt.c (tsubst_aggr_type): Bail if creating the argvec fails.
- (tsubst_template_arg_vector): Likewise.
-
- * decl2.c (build_anon_union_vars): Choose the largest field; don't
- assume that one will be as large as the union.
-
-2000-08-07 Kazu Hirata <kazu@hxi.com>
-
- * cp-tree.h (CLASSTYPE_HAS_PRIMARY_BASE_P): Fix a comment typo.
- * decl.c (pop_labels): Likewise.
-
-2000-08-04 Jeffrey Oldham <oldham@codesourcery.com>
-
- * inc/cxxabi.h (__pbase_type_info): Changed member names to match
- specifications.
- (__pointer_to_member_type_info): Likewise.
- (__base_class_info): Likewise.
- (__class_type_info): Likewise.
- (__si_class_type_info): Likewise.
- (__vmi_class_type_info): Likewise.
- * tinfo.cc (__si_class_type_info::__do_find_public_src):
- Changed member names to match specifications.
- (__vmi_class_type_info::__do_find_public_src): Likewise.
- (__si_class_type_info::__do_dyncast): Likewise.
- (__vmi_class_type_info::__do_dyncast): Likewise.
- (__si_class_type_info::__do_upcast): Likewise.
- (__vmi_class_type_info::__do_upcast): Likewise.
- * tinfo2.cc (__pbase_type_info::__do_catch): Likewise.
- (__pbase_type_info::__pointer_catch): Likewise.
- (__pointer_type_info::__pointer_catch): Likewise.
- (__pointer_to_member_type_info::__pointer_catch): Likewise.
-
-2000-08-04 Zack Weinberg <zack@wolery.cumb.org>
-
- * Make-lang.in (cc1plus): Depend on $(BACKEND), not stamp-objlist.
- * Makefile.in: Add C_OBJS, BACKEND; delete OBJS, OBJDEPS.
- (cc1plus): Link with $(BACKEND) and $(C_OBJS).
-
-2000-08-04 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (add_method): Change prototype.
- * class.c (add_method): Remove FIELDS parameter. Add ERROR_P.
- Don't double the size of the method vector in the error case.
- (handle_using_decl): Adjust call to add_method.
- (add_implicitly_declared_members): Likewise.
- (clone_function_decl): Likewise.
- * decl2.c (check_classfn): Likewise.
- * semantics.c (finish_member_declaration): Likewise.
-
-2000-08-04 Joseph S. Myers <jsm28@cam.ac.uk>
-
- * decl.c (flag_isoc94): New variable.
-
-2000-08-02 Jason Merrill <jason@redhat.com>
-
- * pt.c (do_type_instantiation): Add complain parm; don't complain
- if called recursively.
- * cp-tree.h, parse.y: Adjust.
-
-2000-08-02 Zack Weinberg <zack@wolery.cumb.org>
-
- * decl2.c: Silently ignore -Wstrict-prototypes; warn about
- -Wno-strict-prototypes.
-
- * g++spec.c: Adjust type of second argument to
- lang_specific_driver, and update code as necessary.
-
- * cp-tree.h: Don't prototype min_precision here.
- (my_friendly_assert): Cast expression to void.
- * semantics.c (do_poplevel): Initialize scope_stmts.
-
-2000-08-02 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (DECL_NEEDED_P): Tweak.
-
-2000-07-28 Jason Merrill <jason@redhat.com>
-
- * lang-specs.h: Use %i in rule for .ii files.
-
-2000-07-31 Zack Weinberg <zack@wolery.cumb.org>
-
- * lang-specs.h: Rename cpp to cpp0 and/or tradcpp to tradcpp0.
-
-2000-07-30 Mark Mitchell <mark@codesourcery.com>
-
- Allow indirect primary bases.
- * cp-tree.h (struct lang_type): Remove vfield_parent. Add
- primary_base.
- (CLASSTYPE_VFIELD_PARENT): Remove.
- (CLASSTYPE_PRIMARY_BINFO): Reimplement.
- (BINFO_PRIMARY_BINFO): Remove.
- (CLASSTYPE_HAS_PRIMARY_BASE_P): Reimplement.
- (BINFO_VBASE_PRIMARY_P): Likewise.
- (BINFO_PRIMARY_BASE_OF): New macro.
- (BINFO_INDIRECT_PRIMARY_P): Likewise.
- (get_primary_binfo): New function.
- * decl.c (lang_mark_tree): Make lang_type::primary_base.
- * class.c (vcall_offset_data_s): Rename to ...
- (vtbl_init_data_s): ... this. Rename primary_p to primary_vtbl_p,
- and add ctor_vtbl_p.
- (get_derived_offset): Use get_primary_binfo.
- (dfs_mark_primary_bases): Adjust handling of virtual primary
- bases.
- (mark_primary_bases): Likewise.
- (set_primary_base): Take a binfo, not an integer, as a
- representation of the primary base.
- (indirect_primary_base_p): Remove.
- (determine_primary_base): Adjust for indirect primary bases.
- (dfs_find_final_overrider): Fix typo in coment.
- (update_vtable_entry_for_fn): Use get_primary_binfo.
- (layout_nonempty_base_or_field): Tweak.
- (build_base_fields): Adjust for new primary base semantics.
- (dfs_propagate_binfo_offsets): Remove.
- (propagate_binfo_offsets): Rewrite.
- (dfs_set_offset_for_shared_vbases): Remove.
- (layout_virtual_bases): Don't use it.
- (layout_class_type): Set CLASSTYPE_SIZE correctly under the new
- ABI.
- (finish_struct_1): Set CLASSTYPE_PRIMARY_BINFO, not
- CLASSTYPE_VFIELD_PARENT.
- (dfs_get_primary_binfo): New function.
- (get_primary_binfo): Likewise.
- (dump_class_hierarchy_r): Tweak printing of primary bases.
- (build_vtbl_initializer): Fix typo in comments. Use
- vtbl_init_data.
- (build_vcall_and_vbase_vtbl_entries): Likewise.
- (build_vbaes_offset_vtbl_entries): Likewise.
- (dfs_build_vcall_offset_vtbl_entries): Adjust setting of
- BV_VCALL_INDEX to handle indirect primary bases.
- (build_vcall_offset_vtbl_entries): Use vtbl_init_data.
- (build_rtti_vtbl_entries): Likewise.
- * search.c (get_shared_vbase_if_not_primary): Tweak.
- (find_vbase_instance): Likewise.
- (binfo_for_vtable): Simplify.
- * tree.c (unshare_base_binfos): Clear BINFO_PRIMARY_BASE_OF.
- (make_binfo): Make it have 11 entries.
-
-2000-07-30 Alex Samuel <samuel@codesourcery.com>
-
- * mangle.c (DECL_TEMPLATE_ID_P): Remove.
- (CLASSTYEP_TEMPLATE_ID_P): Check template info, and context when
- ascertaining primaryness.
- (G): Remove template_args.
- (decl_is_template_id): New function.
- (write_encoding): Use decl_is_template_id.
- (write_name): Likewise. Handle type_decls. Get main variant of
- type decls.
- (write_nested_name): Likewise.
- (write_prefix): Likewise.
- (write_template_prefix): Likewise.
- (write_special_name_constructor): Remove defunct production from
- comment.
- (write_bare_function_type): Remove comment about absent parameter.
- (write_template_template_arg): Add missing grammar production to
- comment.
-
-2000-07-27 Jason Merrill <jason@redhat.com>
-
- * decl.c (duplicate_decls): If common_type produces a non-typedef
- type for a typedef, just use the old type.
-
-2000-07-27 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (function_depth): Declare.
- (verify_stmt_tree): Likewise.
- (find_tree): Likewise.
- * decl.c (function_depth): Give it external linkage.
- * optimize.c (optimize_function): Increment and decrement it.
- * tree.c (verify_stmt_tree_r): New function.
- (verify_stmt_tree): Likewise.
- (find_tree_r): Likewise.
- (find_tree): Likewise.
-
-2000-07-27 Jason Merrill <jason@redhat.com>
-
- * pt.c (for_each_template_parm_r, case RECORD_TYPE): Use
- TYPE_PTRMEMFUNC_P.
- * cp-tree.h (TYPE_TEMPLATE_INFO): Check for TYPE_LANG_SPECIFIC.
-
-2000-07-26 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (start_cleanup_fn): Mark the function as `inline'.
- * decl2.c (get_guard): Call cp_finish_decl, not
- rest_of_decl_compilation, for local guards.
- * lex.c (do_identifier): Remove unused variable.
-
-Wed Jul 26 15:05:51 CEST 2000 Marc Espie <espie@cvs.openbsd.org>
-
- * parse.y: Add missing ';'.
-
-2000-07-26 Mark Mitchell <mark@codesourcery.com>
-
- * parse.y (empty_parms): Use `()', not `(...)', when in the scope
- of `extern "C++"'.
-
-2000-07-25 Nathan Sidwell <nathan@codesourcery.com>
-
- Kill strict_prototype. Backwards compatibility only for
- non NO_IMPLICIT_EXTERN_C systems.
- * cp-tree.h (flag_strict_prototype): Remove.
- (strict_prototype): Remove.
- (strict_prototypes_lang_c, strict_prototypes_lang_cplusplus): Remove.
- * decl.c (maybe_push_to_top_level): Adjust.
- (pop_from_top_level): Adjust.
- (decls_match): Only allow sloppy parm matching for ancient
- system headers.
- (init_decl_processing): Adjust.
- (grokdeclarator): Adjust.
- * decl2.c (flag_strict_prototype): Remove.
- (strict_prototype): Remove.
- (strict_prototypes_lang_c, strict_prototypes_lang_cplusplus): Remove.
- (lang_f_options): Remove "strict-prototype".
- (unsupported-options): Add "strict-prototype".
- * lex.c (do_identifier): Adjust.
- (do_scoped_id): Adjust.
- * parse.y (empty_parms): Adjust.
- * class.c (push_lang_context): Adjust.
- (pop_lang_context): Adjust.
- * typeck.c (comp_target_parms): Adjust.
-
-2000-07-25 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (poplevel): Deal with anonymous variables at for scope.
- (maybe_inject_for_scope_var): Likewise.
-
-2000-07-25 Zack Weinberg <zack@wolery.cumb.org>
-
- * decl.c: Remove all signal handling code, now done in toplev.c.
-
-2000-07-23 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (make_rtl_for_nonlocal_decl): Rework.
-
- * pt.c (lookup_template_class): Ensure that TYPE_CONTEXT is set
- correctly.
-
-2000-07-20 Zack Weinberg <zack@wolery.cumb.org>
-
- * cp-tree.h: Use __FUNCTION__ not __PRETTY_FUNCTION__.
- Define my_friendly_assert and my_friendly_abort as macros
- which may call friendly_abort. Prototype friendly abort, not
- my_friendly_abort or my_friendly_assert.
- * decl.c (signal_catch): Report the signal caught in the error
- message. Call fatal directly.
- * typeck2.c (ack, my_friendly_assert): Delete.
- (my_friendly_abort): Rename to friendly_abort. Expect file,
- line, and function parameters. Report the abort code, then
- call fancy_abort. Do not mask an abort if errors have
- already occurred.
-
-2000-07-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck.c (comp_target_parms): Remove obsolete parameter.
- (comp_target_types): Adjust.
-
-2000-07-17 Jason Merrill <jason@redhat.com>
-
- * typeck.c (mark_addressable): Never set TREE_USED.
- * call.c (build_call): Don't abort on calls to library functions
- that have been declared normally.
-
- * typeck.c (build_binary_op): Fix grammar in warning.
-
- * exception.cc (__eh_free): Fix prototype.
-
- * decl2.c (finish_decl_parsing): Handle TEMPLATE_ID_EXPR.
-
- * decl.c (pushdecl): Handle seeing an OVERLOAD in
- IDENTIFIER_NAMESPACE_VALUE.
-
-2000-07-16 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (THUNK_VCALL_OFFSET): Update documentation.
- * method.c (use_thunk): Correct handling of vcall offsets.
-
-2000-07-14 Zack Weinberg <zack@wolery.cumb.org>
-
- * .cvsignore: parse.h and parse.c have no cp- prefix.
-
-2000-07-13 Mark Mitchell <mark@codesourcery.com>
-
- * .cvsignore: New file.
-
-2000-07-13 Zack Weinberg <zack@wolery.cumb.org>
-
- * lang-specs.h: Use the new named specs. Remove unnecessary braces.
-
-2000-07-12 Mark Mitchell <mark@codesourcery.com>
-
- * Makefile.in ($(PARSE_H)): Depend directly on parse.y.
- * parse.c: Remove.
- * parse.h: Likewise.
-
-2000-07-11 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (layout_class_type): Add pointers to virtual bases after
- base classes under the old ABI.
-
-2000-07-10 Benjamin Chelf <chelf@codesourcery.com>
-
- * semantics.c (finish_for_stmt): Remove call to emit_line_note.
- (finish_continue_stmt): Likewise.
- (begin_for_stmt): Remove call to note_level_for_for.
- (finish_goto_stmt): Change call from build_min_nt
- to build_stmt.
- (finish_expr_stmt): Likewise.
- (begin_if_stmt): Likewise.
- (begin_while_stmt): Likewise.
- (finish_while_stmt): Likewise.
- (finish_return_stmt): Likewise.
- (begin_for_stmt): Likewise.
- (finish_for_stmt): Likewise.
- (finish_break_stmt): Likewise.
- (begin_switch_stmt): Likewise.
- (finish_case_label): Likewise.
- (genrtl_try_block): Likewise.
- (begin_try_block): Likewise.
- (begin_handler): Likewise.
- (begin_compound_stmt): Likewise.
- (finish_asm_stmt): Likewise.
- (finish_label_stmt): Likewise.
- (add_decl_stmt): Likewise.
- (finish_subobject): Likewise.
- (finish_decl_cleanup): Likewise.
- (finish_named_return_value): Likewise.
- (setup_vtbl_ptr): Likewise.
- (add_scope_stmt): Likewise.
- * decl.c (finish_constructor_body): Likewise.
- (finish_destructor_body): Likewise.
- * optimize.c (copy_body_r): Likewise.
- (initialize_inlined_parameters): Likewise.
- (declare_return_variable): Likewise.
- (expand_call_inline): Likewise.
-
-2000-07-10 Jakub Jelinek <jakub@redhat.com>
-
- * semantics.c (expand_body): Sync interface information
- at the end of function body expansion.
-
-2000-07-09 Jason Merrill <jason@redhat.com>
-
- * init.c (build_new_1): Bail early if the call to new fails.
-
- * decl.c (compute_array_index_type): Check specifically for
- an INTEGER_CST, not just TREE_CONSTANT.
-
- * decl.c (duplicate_decls): Don't call duplicate_decls on
- the DECL_TEMPLATE_RESULT.
- (decls_match): Return 0 if the DECL_TEMPLATE_RESULTs have different
- codes.
-
- * error.c (dump_template_bindings): Don't crash if we had an
- invalid argument list.
-
- * typeck.c (c_expand_start_case): Do narrowing here.
- * semantics.c (finish_switch_cond): Not here.
-
-2000-07-09 Hidvegi Zoli <hzoli@austin.ibm.com>
-
- * parse.y (asm_clobbers): Do string concatenation.
-
-2000-07-09 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (pushtag): Don't put local classes in template functions
- on the local_classes list.
-
-2000-07-04 Scott Snyder <snyder@fnal.gov>
-
- * decl2.c (get_guard): Add missing return for old ABI local
- variable case.
-
-2000-07-09 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (char_type_p): New function.
- * decl.c (init_decl_processing): Don't initialize
- signed_wchar_type_node or unsigned_wchar_type_node.
- (complete_array_type): Handle brace-enclosed string-constants.
- * rtti.c (emit_support_tinfos): Remove #if 0'd code.
- * tree.c (char_type_p): New function.
- * typeck2.c (digest_init): Use char_type_p.
-
-2000-07-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (tsubst): Don't layout type, if it's error_mark.
-
-2000-07-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (instantiate_pending_templates): Reset template level.
-
-2000-07-05 Jason Merrill <jason@redhat.com>
-
- * call.c (joust): Don't complain about `operator char *()' beating
- `operator const char *() const'.
-
-2000-07-04 scott snyder <snyder@fnal.gov>
- Jason Merrill <jason@redhat.com>
-
- * repo.c (repo_get_id): Handle the case where a class with virtual
- bases has a null TYPE_BINFO_VTABLE.
-
-2000-07-04 Kevin Buhr <buhr@stat.wisc.edu>
- Jason Merrill <jason@redhat.com>
-
- * parse.y (member_init): Just pass in the type.
- * init.c (expand_member_init): Handle getting a type.
-
-2000-07-04 Martin v. Löwis <loewis@informatik.hu-berlin.de>
- Jason Merrill <jason@redhat.com>
-
- * decl.c (finish_function): Warn if a function has no return
- statement.
- Suggested by Andrew Koenig.
- * typeck.c (check_return_expr): Do set current_function_returns_value
- if we got an error_mark_node.
-
-2000-07-03 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl2.c (push_decl_namespace): Push the original namespace.
-
-2000-07-03 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (instantiate_class_template): Set CLASSTYPE_VBASECLASSES.
- * semantics.c (begin_class_definition): Clear it.
-
-2000-07-02 Benjamin Chelf <chelf@codesourcery.com>
-
- * cp-tree.h (genrtl_goto_stmt): Remove declaration.
- (genrtl_expr_stmt): Likewise.
- (genrtl_decl_stmt): Likewise.
- (genrtl_if_stmt): Likewise.
- (genrtl_while_stmt): Likewise.
- (genrtl_do_stmt): Likewise.
- (genrtl_return_stmt): Likewise.
- (genrtl_for_stmt): Likewise.
- (genrtl_break_stmt): Likewise.
- (genrtl_continue_stmt): Likewise.
- (genrtl_scope_stmt): Likewise.
- (genrtl_switch_stmt): Likewise.
- (genrtl_case_label): Likewise.
- (genrtl_begin_compound_stmt): Likewise.
- (genrtl_finish_compound_stmt): Likewise.
- (genrtl_compound_stmt): Likewise.
- (genrtl_asm_stmt): Likewise.
-
- * init.c (begin_init_stmts): Remove call to
- genrtl_begin_compound_stmt.
- (finish_init_stmts): Remove call to genrtl_finish_compound_stmt.
-
- * semantics.c (lang_expand_stmt): Changed call to
- genrtl_compound_stmt to ignore return value.
-
-2000-07-02 Mark Mitchell <mark@codesourcery.com>
-
- * mangle.c (canonicalize_for_substitution): Return the canonical
- variant of a type.
-
- * decl.c (duplicate_decls): Preserve DECL_ORIGINAL_TYPE for a
- TYPE_DECL.
- * typeck.c (commonparms): Remove obstack manipulations.
-
-2000-07-01 Benjamin Chelf <chelf@codesourcery.com>
-
- * Make-lang.in (cc1plus$(exeext)): Added c-semantics.o.
-
- * Makefile.in (OBJS): Added ../c-semantics.o.
- (OBJDEPS): Likewise.
-
- * cp-tree.h (TREE_LANG_FLAG_?): Moved common documentation to
- ../c-common.h.
- (struct stmt_tree): Added comment.
- (current_function_name_declared): Removed.
- (stmts_are_full_exprs_p): Likewise.
- (genrtl_do_pushlevel): Likewise.
- (genrtl_clear_out_block): Likewise.
- (COMPOUND_STMT_NO_SCOPE): Moved to ../c-common.h.
- (DECL_ANON_UNION_ELEMS): Likewise.
- (emit_local_var): Likewise.
- (make_rtl_for_local_static): Likewise.
- (do_case): Likewise.
- (expand_stmt): Likewise.
- (genrtl_decl_cleanup): Likewise.
- (c_expand_asm_operands): Likewise.
- (c_expand_return): Likewise.
- (c_expand_start_case): Likewise.
-
- * decl.c (make_rtl_for_local_static): Moved to c-semantics.c.
- (emit_local_var): Likewise.
- (initialize_local_var): Change reference to
- stmts_are_full_exprs_p to call to stmts_are_full_exprs_p().
- Change reference to stmts_are_full_exprs_p to
- current_stmt_tree->stmts_are_full_exprs_p.
- (push_cp_function_context): Likewise.
-
- * expect.c (expand_throw): Change reference to
- stmts_are_full_exprs_p.
-
- * init.c (build_aggr_init): Change reference to
- stmts_are_full_exprs_p.
- (build_vec_init): Likewise.
-
- * optimize.c (maybe_clone_body): Change reference to
- current_function_name_declared to
- cp_function_chain->name_declared.
-
- * pt.c (instantiate_decl): Change reference to
- current_function_name_declared to
- cp_function_chain->name_declared.
-
- * semantics.c (expand_cond): Moved declaration to c-common.h.
- (genrtl_do_pushlevel): Moved to c-semantics.c.
- (genrtl_clear_out_block): Likewise.
- (genrtl_goto_stmt): Likewise.
- (genrtl_expr_stmt): Likewise.
- (genrtl_decl_stmt): Likewise.
- (gerntl_if_stmt): Likewise.
- (genrtl_while_stmt): Likewise.
- (genrtl_do_stmt): Likewise.
- (genrtl_return_stmt): Likewise.
- (genrtl_for_stmt): Likewise.
- (genrtl_break_stmt): Likewise.
- (genrtl_continue_stmt): Likewise.
- (genrtl_scope_stmt): Likewise.
- (genrtl_switch_stmt): Likewise.
- (genrtl_case_label): Likewise.
- (genrtl_begin_compound_stmt): Likewise.
- (genrtl_finish_compound_stmt): Likewise.
- (genrtl_compound_stmt): Likewise.
- (genrtl_asm_stmt): Likewise.
- (genrtl_decl_cleanup): Likewise.
- (expand_cond): Likewise.
- (expand_stmt): Renamed to ...
- (lang_expand_stmt): ... this.
- (lang_expand_expr_stmt): Initialize.
- (set_current_function_name_declared): Likewise.
- (stmts_are_full_exprs_p): Likewise.
- (current_function_name_declared): Likewise.
- (anon_aggr_type_p): Likewise.
- (do_poplevel): Change reference to
- stmts_are_full_exprs_p to call to stmts_are_full_exprs_p().
- Change reference to stmts_are_full_exprs_p to
- current_stmt_tree->stmts_are_full_exprs_p.
- (add_tree): Likewise.
- (finish_expr_stmt): Likewise.
- (prep_stmt): Likewise.
- (lang_expand_stmt): Likewise.
- (begin_compound_stmt): Change reference to
- current_function_name_declared to
- cp_function_chain->name_declared and call to
- current_function_name_declared().
- (setup_vtbl_ptr): Likewise.
- (genrtl_do_poplevel): Removed.
-
-2000-06-30 Jason Merrill <jason@redhat.com>
-
- * init.c (init_init_processing): Go back to aligning like
- double_type_node for old ABI.
- (get_cookie_size): Make cookie larger if we get a type that needs
- more alignment.
- (build_vec_delete): Call it.
-
- * typeck.c (qualify_type_recursive): New fn.
- (composite_pointer_type): Use it.
- (build_binary_op): Use composite_pointer_type.
-
-2000-06-24 Carlos O'Ryan <coryan@cs.wustl.edu>
- Jason Merrill <jason@redhat.com>
-
- * typeck.c (check_return_expr): Don't complain about returning
- NULL from operator new if -fcheck-new.
- * cp-tree.h: Declare flag_check_new here.
- * init.c: Not here.
-
-2000-06-28 Alex Samuel <samuel@codesourcery.com>
-
- * mangle.c (find_substitution): Use same_type_p.
- (write_encoding): Don't check for substitutions.
-
-2000-06-30 Nathan Sidwell <nathan@codesourcery.com>
-
- * parse.y (expr_no_comma_rangle): New non-terminal.
- (template_parm): Use it for default parameter case.
- (template_arg): Use it.
- (expr_no_commas): Remove commented out undefined extensions.
- * Makefile.in (CONFLICTS): Adjust to 33 s/r & 48 r/r.
- * parse.h, parse.c: Rebuilt.
-
-2000-06-30 Mark Mitchell <mark@codesourcery.com>
-
- * semantics.c (genrtl_asm_stmt): Don't decay input operands here.
- (finish_asm_stmt): Do it here, instead.
-
- * cp-tree.h (ridpointers): Don't declare.
- * decl.c (record_builtin_type): Use CP_RID_MAX instead of RID_MAX.
- (record_builtin_java_type): Likewise.
- (init_decl_processing): Likewise.
- * lex.c: Move inclusion of lex.h.
- (ridpointers): Don't define.
- (init_parse): Initialize ripdointers. Use CP_RID_MAX instead of
- RID_MAX.
- * lex.h (enum rid): Rename to ...
- (enum cp_rid): ... this.
- (ridpointers): Don't declare.
- * parse.y: Move inclusion of lex.h.
- * parse.c: Regenerated.
- * spew.c: Move inclusion of lex.h.
-
- * cp-tree.h (struct language_function): Remove temp_name_counter.
- (temp_name_counter): Remove.
- (get_temp_name): Change prototype.
- (get_guard): New function.
- (get_guard_cond): Likewise.
- (set_guard): Likewise.
- * cvt.c (build_up_reference): Adjust call to get_temp_name.
- * decl.c (expand_static_init): Use get_guard and friends to
- implement guard variables.
- * decl2.c (get_temp_name): Assume that the variables created are
- always static.
- (get_sentry): Rename to ...
- (get_guard): ... this. Implement new ABI guard variables.
- (get_guard_bits): New function.
- (get_guard_cond): Likewise.
- (set_guard): Likewise.
- (start_static_initialization_or_destruction): Use them.
- (do_static_initialization): Replace sentry with guard throughout.
- (do_static_destruction): Likewise.
- * init.c (create_temporary_var): Add comment.
-
-2000-06-28 Alex Samuel <samuel@codesourcery.com>
-
- * mangle.c (find_substitution): Use same_type_p.
- (write_encoding): Don't check for substitutions.
-
-2000-06-30 Nathan Sidwell <nathan@codesourcery.com>
-
- * parse.y (expr_no_comma_rangle): New non-terminal.
- (template_parm): Use it for default parameter case.
- (template_arg): Use it.
- (expr_no_commas): Remove commented out undefined extensions.
- * Makefile.in (CONFLICTS): Adjust to 33 s/r & 48 r/r.
- * parse.h, parse.c: Rebuilt.
-
-2000-06-29 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (flag_const_strings): Remove.
- (warn_parentheses): Likewise.
- (warn_format): Likewise.
- (common_type): Likewise.
- (default_conversion): Likewise.
- (build_binary_op): Likewise.
- (cp_build_binary_op): New macro.
- * call.c (build_new_op): Use cp_build_binary_op instead of
- build_binary_op.
- * class.c (build_vtable_entry_ref): Likewise.
- * decl.c (expand_static_init): Likewise.
- (compute_array_index_type): Likewise.
- (build_enumerator): Likewise.
- * decl2.c (delete_sanity): Likewise.
- (start_static_initialization_or_destruction): Likewise.
- * error.c (dump_type_suffix): Likewise.
- * init.c (resolve_offset_ref): Likewise.
- (build_new): Likewise.
- (build_new_1): Likewise.
- (build_vec_delete_1): Likewise.
- (build_vec_init): Likewise.
- (build_delete): Likewise.
- * rtti.c (synthesize_tinfo_fn): Likewise.
- (synthesize_tinfo_var): Likewise.
- * search.c (expand_upcast_fixups): Likewise.
- (fixup_all_virtual_upcast_offsets): Likewise.
- * typeck.c (build_array_ref): Likewise.
- (get_member_function_from_ptrfunc): Likewise.
- (build_binary_op): Add parameter.
- (pointer_int_sum): Use cp_build_binary_op.
- (pointer_diff): Likewise.
- (build_modify_expr): Likewise.
- (get_delta_difference): Likewise.
- (build_ptrmemfunc): Likewise.
-
-2000-06-29 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (SET_DECL_ARTIFICIAL): Remove.
- * decl.c (create_implicit_typedef): Adjust.
- * decl2.c (build_artificial_parm): Adjust.
- * method.c (implicitly_declare_fn): Adjust.
- * pt.c (push_inline_template_parms_recursive): Adjust.
- (process_template_parm): Adjust.
- (overloaded_template_name): Adjust.
- * semantics.c (finish_template_template_parm): Adjust.
-
-2000-06-28 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (CLEAR_BINFO_NEW_VTABLE_MARKED): Remove.
- * class.c (update_vtable_entry_for_fn): Correct logic for deciding
- where to emit thunks.
- (build_vtt): Adjust call to build_vtt_inits.
- (build_vtt_inits): Add parameter to indicate whether or not
- sub-VTTs for virtual bases should be included. Adjust handling of
- construction vtables.
- (get_matching_base): New function.
- (dfs_build_vtt_inits): Rename to ...
- (dfs_build_secondary_vptr_vtt_inits): Adjust handling of
- construction vtables.
- (dfs_fixup_binfo_vtbls): Likewise.
- (build_ctor_vtbl_groups): Build construction vtables for virtual
- bases, too.
- (accumulate_vtbl_inits): Tweak logic for deciding whether or not
- to build construction vtbls.
- (dfs_accumulate_vtbl_inits): Adjust handling of
- construction vtables.
-
- * pt.c (tsubst, case TEMPLATE_TEMPLATE_PARM): Handle cv-qualified
- types correctly.
-
-2000-06-27 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (grokfndecl): Set DECL_CONTEXT for static functions too.
-
-2000-06-26 Nathan Sidwell <nathan@codesourcery.com>
-
- * search.c (hides): Remove.
- (is_subobject_of_p): Add most_derived parameter. Use
- CANONICAL_BINFO.
- (lookup_field_queue_p): Adjust.
- (lookup_field_r): Adjust.
-
-2000-06-26 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl2.c (handle_class_head): Bash typedefs to the type's main
- decl.
-
-2000-06-25 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (genrtl_begin_stmt_expr): Rename to ...
- (begin_global_stmt_expr): ... this.
- (genrtl_finish_stmt_expr): Rename to ...
- (finish_global_stmt_expr): ... this.
- * init.c (begin_init_stmts): Adjust calls.
- (finish_init_stmts): Likewise.
- * semantics.c (genrtl_begin_stmt_expr): Rename to ...
- (begin_global_stmt_expr): ... this.
- (genrtl_finish_stmt_expr): Rename to ...
- (finish_global_stmt_expr): ... this.
-
-2000-06-25 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
-
- * search.c (lookup_member): Fix typo in comment.
-
-2000-06-24 Jason Merrill <jason@redhat.com>
-
- * decl.c (pushdecl): Don't set DECL_CONTEXT from current_namespace.
- (push_namespace): Set DECL_CONTEXT for a new NAMESPACE_DECL.
-
-2000-06-24 Martin v. Löwis <loewis@informatik.hu-berlin.de>
-
- * parse.y (complex_direct_notype_declarator): Support global_scope.
- * Makefile.in: Adjust conflict count.
-
-2000-06-23 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
-
- * parse.y (template_arg): Convert TEMPLATE_DECL
- that is a template template parameter to
- TEMPLATE_TEMPLATE_PARM here.
-
- * cp-tree.def (TEMPLATE_TEMPLATE_PARM): Adjust comment.
- * cp-tree.h (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): New macro.
- (copy_template_template_parm): Adjust prototype.
- * decl.c (grokdeclarator): Remove dead code.
- * pt.c (process_template_parm): Tidy.
- (lookup_template_class): Construct nodes in
- copy_template_template_parm.
- (tsubst): Pass TEMPLATE_DECL rather than IDENTIFIER_NODE to
- lookup_template_class. Use TYPE_TI_TEMPLATE.
- * tree.c (copy_template_template_parm): Add NEWARGS
- parameter.
- (mapcar): Adjust call to copy_template_template_parm.
- * typeck.c (comptypes): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL.
- * method.c (build_template_template_parm_names): Change error
- code to avoid compilation warning.
-
- * gxxint.texi: Document template template parameter
- name mangling.
-
-2000-06-21 Alex Samuel <samuel@codesourcery.com>
-
- * Make-lang.in (CXX_LIB2FUNCS): Add cp-demangle.o and dyn-string.o.
- (CXX_LIB2SRCS): Add cp-demangle.c and dyn-string.c.
- (cp-demangle.o): New rule.
- (dyn-string.o): Likewise.
- * inc/cxxabi.h (__cxa_demangle): New declaration.
-
-2000-06-22 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (BV_USE_VCALL_INDEX_P): New macro.
- (BV_GENERATE_THUNK_WITH_VTABLE_P): Likewise.
- (lang_decl_flags): Add generate_with_vtable_p. Make vcall_offset
- a tree, not an int.
- (THUNK_GENERATE_WITH_VTABLE_P): New macro.
- (make_thunk): Change prototype.
- (emit_thunk): Rename to use_thunk.
- (mangle_thunk): Change prototype.
- * class.c (get_derived_offset): Simplify.
- (copy_virtuals): Clear BV_USE_VCALL_INDEX_P and
- BV_GENERATE_THUNK_WITH_VTABLE_P.
- (build_primary_vtable): Simplify.
- (add_virtual_function): Use BV_FN, rather than TREE_VALUE.
- (dfs_find_base): Remove.
- (update_vtable_entry_for_fn): Correct bug in finding the base
- where a virtual function was first declared. Figure out whether
- or not to emit a vcall-thunk with the vtables in which it appears.
- Correct logic for deciding whether to use an ordinary thunk, or a
- vcall thunk.
- (finish_struct_1): Remove unnecssary code.
- (build_vtbl_initializer): Use ssize_int for the running counter of
- negative indices.
- (build_vtbl_initializer): Only use vcall thunks where necessary.
- Mark thunks as needing to be emitted with their vtables, or not.
- (build_vbase_offset_vtbl_entries): Adjust for use of ssize_int in
- indices. Use size_binop.
- (dfs_build_vcall_offset_vtbl_entries): Don't rely on
- BINFO_PRIMARY_MARKED_P here. Use BV_FN consistently. Use
- size_binop.
- (build_rtti_vtbl_entries): Adjust call to build_vtable_entry.
- (build_vtable_entry): Mark thunks as needing to be emitted with
- their vtables, or not.
- * decl.c (lang_mark_tree): Mark the vcall_offset in a thunk.
- * decl2.c (mark_vtable_entries): Use use_thunk instead of
- emit_thunk.
- * dump.c (dequeue_and_dump): Remove dead code. Dump new thunk
- information.
- * error.c (dump_expr): Use BV_FN.
- * mangle.c (mangle_thunk): Adjust now that vcall_offset is a tree,
- not an int.
- * method.c (make_thunk): Likewise.
- (emit_thunk): Rename to use_thunk. Allow callers to decide
- whether or not to actually emit the thunk. Adjust for changes in
- representation of vcall offsets.
- * search.c (dfs_get_pure_virtuals): Use BV_FN.
- * semantics.c (emit_associated_thunks): New function.
- (expand_body): Use it.
- * ir.texi: Adjust decriptions of thunks.
-
-2000-06-22 Jason Merrill <jason@redhat.com>
-
- * pt.c (tsubst_decl, case FUNCTION_DECL): Clear DECL_SAVED_TREE.
- (tsubst_friend_function): Copy it here.
-
- * decl.c (grok_op_properties): Fix typo.
-
- * decl2.c (delete_sanity): Clarify warning, avoid failure on
- deleting void*.
-
- * pt.c (check_explicit_specialization): Clarify error.
-
- * decl.c (pushdecl): Also pull out one of the FUNCTION_DECLs from
- an old OVERLOAD when we're declaring a non-function.
- (pushdecl, destroy_local_var): Check for error_mark_node.
- (warn_extern_redeclared_static): Also bail early if
- we're a CONST_DECL.
- (push_overloaded_decl): Ignore an old error_mark_node.
-
-2000-06-22 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (build_x_va_arg): Check if in a template decl.
- * pt.c (tsubst_copy, case VA_ARG_EXPR): Use build_x_va_arg.
-
-2000-06-20 Alexandre Petit-Bianco <apbianco@cygnus.com>
-
- * class.c (push_lang_context): TYPE_NAME gets you to the Java
- types DECLs.
- * decl.c (check_goto): Computed gotos assumed OK.
-
-2000-06-20 Jason Merrill <jason@redhat.com>
-
- * pt.c (tsubst_decl, case TYPE_DECL): Fix test for TYPE_DECLs
- for which we don't need to look for instantiations.
-
-2000-06-21 Nathan Sidwell <nathan@codesourcery.com>
-
- * parse.y (program): Always call finish_translation_unit.
- * parse.c, parse.h: Rebuilt.
-
-2000-06-20 Zack Weinberg <zack@wolery.cumb.org>
-
- * method.c: Don't include hard-reg-set.h.
-
-2000-06-20 Nathan Sidwell <nathan@codesourcery.com>
-
- * rtti.c (get_base_offset): Cope when vbase field is in a base.
-
-2000-06-20 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (build_conditional_expr): Use VOID_TYPE_P.
- * cvt.c (cp_convert_to_pointer): Likewise.
- (convert_to_void): Likewise.
- * error.c (dump_expr): Likewise.
- * except.c (complete_ptr_ref_or_void_ptr_p): Likewise.
- * init.c (build_delete): Likewise.
- * method.c (emit_thunk): Likewise.
- * optmize.c (declare_return_variable): Likewise.
- * rtti.c (get_tinfo_decl_dynamic): Likewise.
- (get_typeid): Likewise.
- (build_dynamic_cast_1): Likewise.
- * typeck.c (composite_pointer_type): Likewise.
- (common_type): Likewise.
- (build_indirect_ref): Likewise.
- (build_binary_op): Likewise.
- (build_x_compound_expr): Likewise.
- (check_return_expr): Likewise.
- * typeck2.c (add_exception_specifier): Likewise.
-
- * mangle.c (write_method_parms): Use direct comparison for end
- of parmlist.
-
-2000-06-19 Benjamin Chelf <chelf@codesourcery.com>
-
- * cp-tree.h (genrtl_try_block): Declare function.
- (genrtl_handler): Likewise.
- (genrtl_catch_block): Likewise.
- (genrtl_ctor_stmt): Likewise.
- (genrtl_subobject): Likewise.
- (genrtl_decl_cleanup): Likewise.
- (genrtl_do_poplevel): Likewise.
- (genrtl_do_pushlevel): Likewise.
- (genrtl_clear_out_block): Likewise.
- (genrtl_goto_stmt): Likewise.
- (genrtl_expr_stmt): Likewise.
- (genrtl_decl_stmt): Likewise.
- (genrtl_if_stmt): Likewise.
- (genrtl_while_stmt): Likewise.
- (genrtl_do_stmt): Likewise.
- (genrtl_return_stmt): Likewise.
- (genrtl_for_stmt): Likewise.
- (genrtl_break_stmt): Likewise.
- (genrtl_continue_stmt): Likewise.
- (genrtl_scope_stmt): Likewise.
- (genrtl_switch_stmt): Likewise.
- (genrtl_case_label): Likewise.
- (genrtl_begin_compound_stmt): Likewise.
- (genrtl_finish_compound_stmt): Likewise.
- (genrtl_compound_stmt): Likewise.
- (genrtl_asm_stmt): Likewise.
- (genrtl_named_return_value): Likewise.
- (genrtl_begin_stmt_expr): Likewise.
- (genrtl_finish_stmt_expr): Likewise.
- (finish_for_stmt): Removed first argument.
- (finish_switch_stmt): Likewise.
-
- * semantics.c (genrtl_try_block): Define function.
- (genrtl_handler): Likewise.
- (genrtl_catch_block): Likewise.
- (genrtl_ctor_stmt): Likewise.
- (genrtl_subobject): Likewise.
- (genrtl_decl_cleanup): Likewise.
- (genrtl_do_poplevel): Likewise.
- (genrtl_do_pushlevel): Likewise.
- (genrtl_clear_out_block): Likewise.
- (genrtl_goto_stmt): Likewise.
- (genrtl_expr_stmt): Likewise.
- (genrtl_decl_stmt): Likewise.
- (genrtl_if_stmt): Likewise.
- (genrtl_while_stmt): Likewise.
- (genrtl_do_stmt): Likewise.
- (genrtl_return_stmt): Likewise.
- (genrtl_for_stmt): Likewise.
- (genrtl_break_stmt): Likewise.
- (genrtl_continue_stmt): Likewise.
- (genrtl_scope_stmt): Likewise.
- (genrtl_switch_stmt): Likewise.
- (genrtl_case_label): Likewise.
- (genrtl_begin_compound_stmt): Likewise.
- (genrtl_finish_compound_stmt): Likewise.
- (genrtl_compound_stmt): Likewise.
- (genrtl_asm_stmt): Likewise.
- (genrtl_named_return_value): Likewise.
- (genrtl_begin_stmt_expr): Likewise.
- (genrtl_finish_stmt_expr): Likewise.
- (finish_for_stmt): Removed first argument and generate rtl
- specific code.
- (finish_switch_stmt): Likewise.
- (do_poplevel): Removed generate rtl specific code.
- (do_pushlevel): Likewise.
- (add_tree): Likewise.
- (finish_goto_stmt): Likewise.
- (finish_expr_stmt): Likewise.
- (begin_if_stmt): Likewise.
- (finish_if_stmt_cond): Likewise.
- (finish_then_clause): Likewise.
- (begin_else_clause): Likewise.
- (finish_else_clause): Likewise.
- (finish_if_stmt): Likewise.
- (clear_out_block): Likewise.
- (begin_while_stmt): Likewise.
- (finish_while_stmt_cond): Likewise.
- (finish_while_stmt): Likewise.
- (begin_do_stmt): Likewise.
- (finish_do_body): Likewise.
- (finish_do_stmt): Likewise.
- (finish_return_stmt): Likewise.
- (begin_for_stmt): Likewise.
- (finish_for_init_stmt): Likewise.
- (finish_for_cond): Likewise.
- (finish_for_expr): Likewise.
- (finish_break_stmt): Likewise.
- (finish_continue_stmt): Likewise.
- (begin_switch_stmt): Likewise.
- (finish_switch_cond): Likewise.
- (finish_case_label): Likewise.
- (begin_try_block): Likewise.
- (begin_function_try_block): Likewise.
- (finish_try_block): Likewise.
- (finish_cleanup_try_block): Likewise.
- (finish_cleanup): Likewise.
- (finish_function_try_block): Likewise.
- (finish_handler_sequence): Likewise.
- (finish_function_handler_sequence): Likewise.
- (begin_handler): Likewise.
- (finish_handler_parms): Likewise.
- (begin_catch_block): Likewise.
- (finish_handler): Likewise.
- (begin_compound_stmt): Likewise.
- (finish_compound_stmt): Likewise.
- (finish_asm_stmt): Likewise.
- (finish_label_stmt): Likewise.
- (finish_label_decl): Likewise.
- (finish_subobject): Likewise.
- (finish_decl_cleanup): Likewise.
- (finish_named_return_value): Likewise.
- (begin_stmt_expr): Likewise.
- (finish_stmt_expr): Likewise.
-
- * decl.c (initialize_local_var): Changed call to finish_expr_stmt
- to call genrtl_expr_stmt when appropriate.
-
- * init.c (begin_init_stmts): Changed calls to begin_stmt_expr and
- begin_compound_expr to call genrtl_begin_stmt_expr and
- genrtl_begin_compound_expr when appropriate.
- (finish_init_stmts): Changed calls to finish_compound_expr and
- finish_stmt_expr to call genrtl_finish_compound_expr and
- genrtl_finish_stmt_expr when appropriate.
- (expand_default_init): Changed call to finish_expr_stmt to call
- genrtl_expr_stmt when appropriate.
- (build_vec_init): Likewise.
-
- * parse.y (simple_stmt): Removed first argument from call to
- finish_for_stmt. Removed first argument from call to
- finish_switch_stmt.
-
- * parse.c: Regenerated.
-
- * pt.c (tsubst_expr): Removed first argument from call to
- finish_for_stmt. Removed first argument from call to
- finish_switch_stmt.
-
-2000-06-16 Benjamin Chelf <chelf@codesourcery.com>
-
- * cp-tree.h (enum cplus_tree_code): Changed __DUMMY to
- CP_DUMMY_TREE_CODE. Remove #include "c-common.def".
-
- * lex.c (cplus_tree_code_type[]): Removed #include "c-common.def".
- (cplus_tree_code_length[]): Likewise.
- (cplus_tree_code_name[]): Likewise.
- (init_parse): Added call to add_c_tree_codes. Changed
- LAST_AND_UNUSED_TREE_CODE to LAST_C_TREE_CODE.
-
-2000-06-16 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (finish_mem_initializers): Declare.
- (count_trees): Likewise.
- * parse.y (base_init): Use finish_mem_initializers.
- * semantics.c (finish_mem_initializers): New function.
-
- * tree.c (count_trees_r): Prototype. Use DATA parameter to store
- the number of trees.
- (n_trees): Remove.
- (count_trees): Don't use it.
-
-2000-06-15 Jason Merrill <jason@redhat.com>
-
- * tree.c (count_trees): New debugging function.
-
- * typeck.c (build_x_function_call): Use DECL_FUNCTION_TEMPLATE_P.
- * init.c (build_member_call): Pull out the name of a DECL.
-
- * Makefile.in (semantics.o, pt.o): Depend on TIMEVAR_H.
- * semantics.c (expand_body): Push to TV_INTEGRATION here.
- * optimize.c (optimize_function): Not here.
- * pt.c (instantiate_decl): Push to TV_PARSE.
-
-2000-06-15 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (struct language_function): Remove x_base_init_list
- and x_member_init_list.
- (current_base_init_list): Remove.
- (current_member_init_list): Likewise.
- (setup_vtbl_ptr): Change prototype.
- (emit_base_init): Likewise.
- (expand_member_init): Likewise.
- (reinit_parse_for_function): Remove.
- * decl.c (save_function_data): Don't clear x_base_init_list and
- x_member_init_list.
- (mark_language_function): Don't mark them.
- * init.c (perform_member_init): Tweak comment.
- (sort_member_init): Take the list of initializers as an argument.
- (sort_base_init): Likewise.
- (emit_base_init): Likewise.
- (expand_member_init): Return the initializer. Don't use global
- variables.
- * lex.c (reinit_parse_for_function): Remove.
- * method.c (build_template_parm_names): Correct substitution.
- (do_build_copy_constructor): Don't use current_member_init_list
- and current_base_init_list.
- (synthesize_method): Likewise.
- * parse.y (base_init): Split mem-initializers into
- base-initializers and field-initializers.
- (member_init_list): Build up the list here.
- (member_init): Return the initializer.
- (fn.depfn): Don't use reinit_parse_for_function.
- * parse.c: Regenerated.
- * pt.c (convert_nontype_argument): Don't make an ADDR_EXPR of the
- ERROR_MARK.
- (tsubst_expr): Don't use current_member_init_list
- and current_base_init_list.
- (tsubst_expr_values): Rename to ...
- (tsubst_initializer_list): ... this. Use convert_from_reference.
- * semantics.c (setup_vtbl_ptr): Don't use current_member_init_list
- and current_base_init_list.
- (begin_function_definition): Don't call reinit_parse_for_function.
-
- * dump.c (dequeue_and_dump): Use TREE_VEC_LENGTH with vectors.
-
- * error.c (dump_expr): Handle ADDR_EXPRs with REFERENCE_TYPE
- correctly.
-
- * cp-tree.h (DECL_PENDING_INLINE_P): Relax checking.
-
-2000-06-14 Benjamin Chelf <chelf@codesourcery.com>
-
- * cp-tree.h (IF_COND): Move to c-common.h.
- (THEN_CLAUSE): Likewise.
- (ELSE_CLAUSE): Likewise.
- (WHILE_COND): Likewise.
- (WHILE_BODY): Likewise.
- (DO_COND): Likewise.
- (DO_BODY): Likewise.
- (RETURN_EXPR): Likewise.
- (EXPR_STMT_EXPR): Likewise.
- (FOR_INIT_STMT): Likewise.
- (FOR_COND): Likewise.
- (FOR_EXPR): Likewise.
- (FOR_BODY): Likewise.
- (SWITCH_COND): Likewise.
- (SWITCH_BODY): Likewise.
- (CASE_LOW): Likewise.
- (CASE_HIGH): Likewise.
- (GOTO_DESTINATION): Likewise.
- (COMPOUND_BODY): Likewise.
- (ASM_CV_QUAL): Likewise.
- (ASM_STRING): Likewise.
- (ASM_OUTPUTS): Likewise.
- (ASM_INPUTS): Likewise.
- (ASM_CLOBBERS): Likewise.
- (DECL_STMT_DECL): Likewise.
- (STMT_EXPR_STMT): Likewise.
- (LABEL_STMT_LABEL): Likewise.
- (SCOPE_BEGIN_P): Likewise.
- (SCOPE_END_P): Likewise.
- (SCOPE_STMT_BLOCK): Likewise.
- (SCOPE_NULLIFIED_P): Likewise.
- (SCOPE_NO_CLEANUPS_P): Likewise.
- (SCOPE_PARTIAL_P): Likewise.
- (ASM_VOLATILE_P): Likewise.
- (STMT_LINENO): Likewise.
- (STMT_LINENO_FOR_FN_P): Likewise.
-
- * cp-tree.def: Removed SRCLOC, SIZEOF_EXPR, ARROW_EXPR,
- ALIGNOF_EXPR, EXPR_STMT, COMPOUND_STMT, DECL_STMT, IF_STMT,
- FOR_STMT, WHILE_STMT, DO_STMT, RETURN_STMT, BREAK_STMT,
- CONTINUE_STMT, SWITCH_STMT, GOTO_STMT, LABEL_STMT, ASM_STMT,
- SCOPE_STMT, CASE_LABEL, STMT_EXPR.
-
- * Makefile.in (CXX_TREE_H): Added $(srcdir)/../c-common.def.
-
- * Make-lang.in (CXX_SRCS): Added $(srcdir)/c-common.def.
- (cc1plus$(exeext)): Added $(srcdir)/c-common.def.
-
- * lex.c (cplus_tree_code_type[]): Added '#include "c-common.def"'.
- (cplus_tree_code_length[]): Added '#include "c-common.def"'.
- (cplus_tree_code_name[]): Added '#include "c-common.def"'.
-
-2000-06-14 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (BINFO_OVERRIDE_ALONG_VIRTUAL_PATH): New macro.
- * class.c (dfs_find_final_overrider): Set it appropriately.
- (dfs_built_vtt_inits): Check BINFO_OVERRIDE_ALONG_VIRTUAL_PATH to
- avoid unneeded secondary vptrs.
-
-2000-06-13 Jakub Jelinek <jakub@redhat.com>
-
- * class.c (build_secondary_vtable): Set DECL_USER_ALIGN.
- (check_bitfield_decl, check_field_decl): Likewise.
- (build_vtbl_or_vbase_field, build_base_field): Likewise.
- (layout_class_type): Set DECL_USER_ALIGN resp. CLASSTYPE_USER_ALIGN.
- * decl.c (record_unknown_type): Set TYPE_USER_ALIGN.
- (xfer_tag, finish_enum): Likewise.
- * decl2.c (finish_builtin_type): Likewise.
- * init.c (init_init_processing): Likewise.
- * pt.c (instantiate_class_template): Likewise.
- * rtti.c (get_tinfo_decl, synthesize_tinfo_fn): Set DECL_USER_ALIGN.
- * cp-tree.h (struct lang_type): Add user_align member.
- (CLASSTYPE_USER_ALIGN): Define.
-
-Tue Jun 13 15:48:03 2000 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
-
- * Make-lang.in (c++.install-common): Install g++-cross in
- $(gcc_tooldir)/bin as g++ and c++; g++ in $(bindir) as
- $(target_alias)-g++ and $(target_alias)-c++.
-
-2000-06-12 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (vcall_offset_data_s): Add last_init and fns.
- (overrides): Rename to same_signature_p.
- (dfs_find_final_overrider): Adjust accordingly.
- (mark_overriders): Likewise.
- (warn_hidden): Likewise.
- (build_vtbl_initializer): Reorganize machinery for building things
- at negative offsets.
- (build_vcall_and_vbase_vtbl_entries): Likewise.
- (build_vbase_offset_vtbl_entries): Likewise.
- (dfs_build_vcall_offset_vtbl_entries): Correct order of vcall
- offset entries. Do not create two entries for functions with the
- same signature.
- (build_vcall_offset_vtbl_entries): Initialize vod->fns.
- (build_rtti_vtbl_entries): Reorganize machinery for building things
- at negative offsets.
-
- * optimize.c (expand_call_inline): Don't recurse into the code
- used to initialize the parameters more than once.
-
-2000-06-11 Mark Mitchell <mark@codesourcery.com>
-
- * mangle.c (NESTED_TEMPLATE_MATCH): Fix typo in comment.
- (is_std_substitution): Don't check CLASSTYPE_USE_TEMPLATE here.
- (find_substitution): Only use the `Sa' substitution for
- std::allocator, not instantiations of it.
- (write_template_prefix): Move comment. Only use a TREE_LIST to
- represent substitutions for a member template.
- (write_array_type): Mangle array dimensions correctly.
- * optimize.c (maybe_clone_body): Copy more information from the
- cloned function.
- * pt.c (regenerate_decl_from_template): Preserve DECL_USE_TEMPLATE
- on the regenerated declaration.
-
-2000-06-11 Chip Salzenberg <chip@valinux.com>
- Mark Mitchell <mark@codesourcery.com>
-
- * class.c (build_vtable): Clarify comment.
- (build_ctor_vtbl_group): Pass the most derived type to
- build_vtable.
-
-2000-06-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * decl2.c (compare_options): Don't needlessly cast away const-ness.
-
-2000-06-10 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (add_binding): Handle duplicate declarations of external
- variables.
-
-2000-06-09 Chip Salzenberg <chip@valinux.com>
- Mark Mitchell <mark@codesourcery.com>
-
- * mangle.c (write_number): Take an unsigned HOST_WIDE_INT as an
- argument.
- (write_signed_number): New macro.
- (write_unsigned_number): Likewise.
- (write_source_name): Use them.
- (write_number): Handle signed and unsigned values.
- (write_integer_cst): Use tree_int_cst_sgn, and use
- write_unsigned_number or write_signed_number as appropriate.
- (write_discriminator): Use write_unsigned_number or
- write_signed_number as appropriate.
- (write_template_arg_literal): Likewise.
- (write_array_type): Use tree_low_cst.
- (write_template_parm): Use write_unsigned_number or
- write_signed_number as appropriate.
- (write_substitution): Adjust call to write_number.
- (write_type): Get the TYPE_MAIN_VARIANT before mangling it.
- (write_expression): Handle non-type template arguments of
- reference type correctly.
- (mangle_thunk): Use write_signed_number.
-
-2000-06-09 Chip Salzenberg <chip@valinux.com>
-
- * mangle.c (find_substition): Don't mangle objects with typename
- substitutions (e.g. "cin" as "Si").
-
-2000-06-09 Zack Weinberg <zack@wolery.cumb.org>
-
- * call.c (add_candidate): Use ggc_alloc_cleared.
- * decl.c (lookup_label): Likewise.
- * lex.c (retrofit_lang_decl): Likewise.
-
-2000-06-09 Jason Merrill <jason@casey.soma.redhat.com>
-
- * semantics.c (expand_body): Push to TV_EXPAND.
- * optimize.c (optimize_function): Push to TV_INTEGRATION.
- * decl.c (start_function): Always call announce_function.
-
- * tinfo2.cc: Just declare abort.
-
-2000-06-09 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * lex.c (DEF_OPERATOR): Say `operator@' -not- `operator @'
- whenever @ is a symbolic name.
-
-2000-06-08 Jakub Jelinek <jakub@redhat.com>
-
- * method.c (make_thunk): Clear DECL_VTT_PARM in thunk.
-
-2000-06-07 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (pushdecl): Look up functions by DECL_NAME, not
- DECL_ASSEMBLER_NAME.
-
-2000-06-06 Mark Mitchell <mark@codesourcery.com>
-
- * decl2.c (c_language): Define.
-
-2000-06-06 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * lex.c (lang_init_options): Tweak.
-
- * decl2.c: Remove #inclusion of diagnostic.h
- (lang_decode_option): Move diagnostic formatting options to
- toplevel.
-
- * lang-options.h: Remove documentation for diagnostic options.
-
- * Makefile.in (lex.o): Depends upon diagnostic.h
-
-2000-06-06 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (redeclaration_error_message): If two TEMPLATE_DECLs have
- the same DECL_RESULT, it's not a redefinition.
- * pt.c (tsubst_decl): Remove code to handle illegal
- specializations.
-
-2000-06-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * exception.cc: (__eh_alloc, __eh_free): Moved to libgcc2.c
-
-2000-06-05 Jason Merrill <jason@casey.soma.redhat.com>
-
- * search.c (maybe_suppress_debug_info): Don't check
- CLASSTYPE_INTERFACE_ONLY if CLASSTYPE_INTERFACE_KNOWN isn't set.
-
- * pt.c (mark_decl_instantiated): Do SET_DECL_EXPLICIT_INSTANTIATION
- here if extern_p.
-
- Remember instantiation context in deferred instantiations.
- * cp-tree.h (struct tinst_level): Remove.
- (TINST_DECL, TINST_LINE, TINST_FILE): New macros.
- * pt.c (current_tinst_level): Now a tree.
- (print_template_context, push_tinst_level, pop_tinst_level,
- tinst_for_decl): Adjust.
- (reopen_tinst_level): New fn.
- (init_pt): Register current_tinst_level as a root.
- (add_pending_template): Put current_tinst_level in TREE_PURPOSE
- of the pending templates list.
- (instantiate_pending_templates): Adjust. Call reopen_tinst_level.
- * lex.c (extract_interface_info): Adjust.
- * decl2.c (warn_if_unknown_interface): Adjust.
-
-2000-06-05 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (indirect_primary_base_p): New function.
- (determine_primary_base): Use it.
-
-2000-06-05 Nathan Sidwell <nathan@codesourcery.com>
-
- Update new-abi dynamic cast algorithm.
- * tinfo.cc (__class_type_info::__dyncast_result): Add
- whole_details. Adjust constructor.
- (__vmi_class_type_info::__do_dyncast): Adjust for vmi_flags.
- Avoid unnecessary searching.
- (__dynamic_cast): Adjust for __dyncast_result::whole_details.
-
-Mon Jun 5 06:48:55 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * decl.c (init_decl_processing): Don't call record_component_aliases.
- * tree.c (build_cplus_array_type_1): Likewise.
-
-2000-06-04 Mark Mitchell <mark@codesourcery.com>
-
- * ir.texi: Correct typo.
- * mangle.c (write_expression): Handle non-type template arguments
- with reference type.
- * method.c (build_overload_value): Likewise.
- * pt.c (convert_nontype_argument): Explicitly represent conversion
- to a reference with an ADDR_EXPR.
- (unify): Always unify arguments in left-to-right order.
-
-2000-06-03 Alex Samuel <samuel@codesourcery.com>
- Mark Mitchell <mark@codesourcery.com>
-
- * Make-lang.in (CXX_SRCS): Add mangle.c.
- * Makefile.in (CXX_OBJS): Add mangle.o.
- (mangle.o): New rule.
-
- * class.c (local_classes): New variable.
- * class.c (get_vtable_name): Use mangle_vtable_for_type for new ABI.
- (get_vtt_name): Use mangle_vtt_name for new ABI.
- (init_class_processing): Initialize local_classes.
- (build_ctor_vtbl_group): Use mangle_ctor_vtbl_for_type for new ABI.
- * cp-tree.h (cp_tree_index): Add CPTI_STD_IDENTIFIER.
- (std_identifier): New macro.
- (DECL_VOLATILE_MEMFUNC_P): New macro.
- (DECL_NAMESPACE_STD_P): Likewise.
- (local_classes): Declare.
- (get_mostly_instantiated_function_type): Declare.
- (init_mangle): Declare.
- (mangle_decl): Likewise.
- (mangle_type_string): Likewise.
- (mangle_type): Likewise.
- (mangle_typeinfo_for_type): Likewise.
- (mangle_typeinfo_string_for_type): Likewise.
- (mangle_vtbl_for_type): Likewise.
- (mangle_vtt_for_type): Likewise.
- (mangle_ctor_vtbl_for_type): Likewise.
- (mangle_thunk): Likewise.
- (mangle_conv_op_name_for_type): Likewise.
- (mangle_guard_variable): Likewise.
- * decl.c (pushtag): Keep track of local classes.
- (initialize_predefined_identifiers): Initialize std_identifier.
- (init_decl_processing): Use std_identifier.
- (start_decl): Don't treat instantiations as specializations.
- (grokdeclarator): Likewise.
- (grokvardecl): Call mangle_decl for new ABI. Only set mangled
- name for fully-instantiated templates.
- * decl2.c (grokclassfn): Use set_mangled_name_for_decl for
- destructors with the new ABI.
- (finish_static_data_member_decl): Use mangle_decl under the new ABI.
- (grokfield): Use mangle_type for new ABI.
- (grokoptypename): Use mangle_conv_op_for_type for new ABI.
- (get_sentry): Use mangle_guard_variable for new ABI.
- (start_static_initialization_or_destruction): Likewise.
- * expr.c (extract_aggr_init): Remove.
- (extract_scalar_init): Likewise.
- (extract_init): Remove #if 0'd code.
- * mangle.c: New function.
- * method.c (build_mangled_name): Assert not flag_new_abi.
- (build_static_name): Likewise.
- (build_decl_overload_real): Likewise.
- (build_typename_overload): Likewise.
- (build_overload_with_type): Likewise.
- (build_overload_name): Likewise.
- (get_ctor_vtbl_name): Likewise.
- (start_squangling): Likewise.
- (get_id_2): Likewise.
- (set_mangled_name_for_decl): Call mangle_decl for new ABI.
- (init_method): Call init_mangle for new ABI.
- (make_thunk): Call mangle_thunk for new ABI.
- * operators.def: Correct new ABI manglings for the `%' operator.
- Add `::' operator.
- * pt.c (build_template_decl): Copy DECL_OVERLOADED_OPERATOR_P and
- DECL_ASSIGNMENT_OPERATOR_P to the TEMPLATE_DECL.
- (lookup_template_class): Call mangle_decl for new ABI.
- (get_mostly_instantiated_function_type): New function.
- (set_mangled_name_for_template_decl): Use it.
- (tsubst_decl): Use set_mangled_name_for_decl for destructors with
- the new ABI. Use mangle_conv_op_name_for_type for instantiated
- conversion op names.
- * rtti.c (tinfo_name): Call mangle_type_string for new ABI.
- (get_tinfo_decl): Call mangle_typeinfo_for_type for new ABI.
- (tinfo_base_init): Likewise. Mangle typeinfo string name with
- mangle_typeinfo_string_for_type.
-
-2000-06-03 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (TMPL_ARGS_LEVEL): Clarify comment.
- (INNERMOST_TEMPLATE_ARGS): New macro.
- (innermost_args): Remove.
- (get_innermost_template_args): New function.
- * decl2.c (arg_assoc_class): Use INNERMOST_TEMPLATE_ARGS.
- * error.c (dump_function_decl): Be caution when using
- most_general_template.
- * method.c (build_template_parm_names): Use
- INNERMOST_TEMPLATE_ARGS.
- * pt.c (add_to_template_args): Tidy comment
- (get_innermost_template_args): New function.
- (check_explicit_specialization): Clear DECL_INITIAL for a new
- specialization.
- (process_partial_specialization): Use INNERMOST_TEMPLATE_ARGS.
- Tidy.
- (push_template_decl): Always register specializations of the most
- general template.
- (convert_template_argument): Use INNERMOST_TEMPLATE_ARGS.
- (coerce_template_parms): Likewise.
- (lookup_template_class): Likewise.
- (innermost_args): Remove.
- (tsubst_decl): Use INNERMOST_TEMPLATE_ARGS.
- (tsubst_decl): Handle tricky specializations. Use
- get_innermost_template_args.
- (instantiate_template): Simplify handling of partial
- instantiations.
- (get_class_bindings): Use INNERMOST_TEMPLATE_ARGS.
- (most_general_template): Reimplement, in a more straightforward
- manner.
- (regenerate_decl_from_template): Tweak formatting. Use
- TMPL_ARGS_DEPTH for clarity.
- (set_mangled_name_for_template_decl): Use INNERMOST_ARGS.
-
- * dump.c (dequeue_and_dump): Dump information about thunks.
-
-2000-06-01 Richard Henderson <rth@cygnus.com>
-
- * decl.c (init_decl_processing): Set lang_get_alias_set first thing.
-
-2000-06-01 Richard Henderson <rth@cygnus.com>
-
- * decl2.c (unsupported_options): Fix typo, make const.
- (lang_decode_option): Fix bsearch argument order.
-
-2000-06-01 Mark Mitchell <mark@codesourcery.com>
-
- * init.c (resolve_offset_ref): Remove check for TREE_ADDRESSABLE
- on FIELD_DECLs.
-
-Wed May 31 14:09:00 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * cp-tree.h (c_get_alias_set): Deleted.
- * Makefile.in (decl.o): Include ../expr.h.
- * decl.c (expr.h): Include.
- (init_decl_processing): Call record_component_aliases for arrays.
- (grokdeclarator): Likewise.
- Set TREE_ADDRESSABLE for fields that aren't bitfields.
- * tree.c (build_cplus_array_type_1): Call record_component_aliases.
-
-2000-05-31 Mark Mitchell <mark@codesourcery.com>
-
- Remove guiding declaration support.
- * cp/cp-tree.h (flag_dump_translation_unit): Make it const.
- (flag_guiding_decls): Remove.
- * call.c (build_user_type_conversion_1): Remove support for
- guiding decls.
- (build_new_function_call): Likewise.
- (build_new_op): Likewise.
- (build_new_method_call): Likewise.
- * decl.c (start_function): Likewise.
- * friend.c (is_friend): Likewise.
- (do_friend): Likewise.
- * decl2.c ((flag_dump_translation_unit): Make it const.
- (flag_guiding_decls): Remove.
- (unsupported_options): New variable
- (compare_options): New function.
- (lang_decode_option): Use them.
-
- * decl.c (build_cp_library_fn): Set DECL_CONTEXT.
-
- * method.c (mangle_expression): Adjust test for legal expression
- operators.
-
- * pt.c (instantiate_decl): Save and restore the local
- specializations list.
-
-2000-05-30 Jason Merrill <jason@decepticon.cygnus.com>
-
- * decl.c (grok_reference_init): Pass LOOKUP_ONLYCONVERTING.
-
-2000-05-30 Mark Mitchell <mark@codesourcery.com>
-
- * call.c (add_template_candidate_real): Handle member template
- constructors for classes with virtual bases.
- (build_user_type_conversion_1): Use in_charge_arg_for_name.
- (build_new_method_call): Use DECL_NONSTATIC_MEMBER_FUNCTION_P.
-
- * ir.texi: Update thunk documentation.
-
- * call.c (joust): Fix handling of overloaded builtin operators.
-
-2000-05-30 Zack Weinberg <zack@wolery.cumb.org>
-
- * cp-tree.h (DECL_ANTICIPATED): New macro.
- Document new use of DECL_LANG_FLAG_7.
- * decl.c (builtin_function): Set DECL_ANTICIPATED on builtins
- in the user namespace.
- * lex.c (do_identifier): If the identifier's declaration has
- DECL_ANTICIPATED on, it has not yet been declared. But do not
- replace it with an ordinary implicit declaration.
-
- * tinfo2.cc: Include stdlib.h.
-
-2000-05-29 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (CLASSTYPE_ALIGN_UNIT): New macro.
- * class.c (layout_empty_base): Use CLASSTYPE_ALIGN_UNIT, not
- CLASSTYPE_ALIGN.
-
-2000-05-28 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * decl2.c (lang_decode_option): Use skip_leading_substring instead
- of plain strncmp.
-
-2000-05-28 Alexandre Oliva <aoliva@cygnus.com>
-
- * operators.def (<?): Duplicated, should have been...
- (>?): this. Fixed.
-
-2000-05-27 Alex Samuel <samuel@codesourcery.com>
- Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (ansi_opname): Make it a macro.
- (ansi_assopname): Likewise.
- (struct lang_decl_flags): Add assignment_operator_p.
- (struct lang_decl): Add operator_code.
- (DECL_VTT_PARM): Adjust.
- (DECL_OVERLOADED_OPERATOR_P): Return the operator_code for an
- overloaded operator.
- (SET_OVERLOADED_OPERATOR_CODE): New macro.
- (DECL_ASSIGNMENT_OPERATOR_P): New macro.
- (DECL_ARRAY_DELETE_OPERATOR_P): Adjust.
- (opname_tab): Remove.
- (assignop_tab): Likewise.
- (operator_name_info_t): New type.
- (operator_name_info): New variable.
- (assignment_operator_name_info): Likewise.
- (build_cp_library_fn): Remove declaration.
- (push_cp_library_fn): Likewise.
- (operator_name_string): Likewise.
- (build_decl_overload): Likewise.
- * call.c (print_z_candidates): Simplify.
- (build_object_call): Adjust usage of ansi_opname. Use
- DECL_OVERLOADED_OPERATOR_P.
- (op_error): Adjust operator name lookup.
- (build_conditional_expr): Adjust usage of ansi_opname.
- (build_new_op): Likewise.
- (build_op_delete_call): Likewise.
- (build_over_call): Likewise.
- (joust): Use DECL_OVERLOADED_OPERATOR_P.
- * decl.c (duplicate_decls): Copy operator_code.
- (init_decl_processing): Adjust parameters to push_cp_library_fn.
- (builtin_function): Adjust parameters to build_library_fn_1.
- (build_library_fn_1): Accept an overloaded operator code.
- (build_library_fn): Pass ERROR_MARK.
- (build_cp_library_fn): Accept an overloaded operator code.
- (push_cp_library_fn): Likewise.
- (grokfndecl): Tweak.
- (grokdeclarator): Simplify code to compute names of overloaded
- operators. Adjust use of ansi_opname.
- (ambi_op_p): Work on tree_codes, not identifiers.
- (unary_op_p): Likewise.
- (grok_op_properties): Likewise.
- (start_function): Use DECL_OVERLOADED_OPERATOR_P.
- (lang_mark_tree): Don't try to mark the operator_code.
- * decl2.c (grok_function_init): Use DECL_OVERLOADED_OPERATOR_P.
- * error.c (dump_decl): Remove special handling for operator
- names.
- (dump_function_name): Likewise.
- (dump_expr): Adjust name lookup of operators.
- (op_to_string): Simplify.
- (assop_to_string): Likewise.
- * init.c (build_new_1): Adjust use of ansi_opname.
- * lex.c (opname_tab): Remove.
- (assignop_tab): Likewise.
- (ansi_opname): Likewise.
- (ansi_assopname): Likewise.
- (operator_name_string): Likewise.
- (reinit_lang_specific): Likewise.
- (operator_name_info): New variable.
- (assignment_operator_name_info): Likewise.
- (init_operators): New function.
- (init_parse): Use it.
- (do_identifier): Adjust use of ansi_opname.
- * method.c (mangle_expression): Don't use ansi_opname for
- mangling.
- (build_decl_overload_real): Use DECL_OVERLOADED_OPERATOR_P.
- (build_decl_overload): Remove.
- (build_typename_overload): Use OPERATOR_TYPENAME_FORMAT directly.
- (do_build_assign_ref): Adjust use of ansi_opname.
- (synthesize_method): Likewise.
- (implicitly_declare_fn): Likewise.
- * operators.def: New file.
- * parse.y (operator): Adjust use of ansi_opname.
- * pt.c (tsubst_decl): Use IDENTIFIER_OPNAME_P.
- (set_mangled_name_for_template_decl): Don't play games with
- current_namespace.
- (special_function_p): Adjust use of ansi_opname.
- * typeck.c (check_return_expr): Likewise.
- * Make-lang.in (cc1plus): Depend on operators.def.
- * Makefile.in (lex.o): Likewise.
- (decl.o): Likewise.
-
-2000-05-27 Zack Weinberg <zack@wolery.cumb.org>
-
- * Make-lang.in (cplib2.ready): Eradicate.
-
-Sat May 27 11:25:46 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * method.c (mangle_expression): Use TREE_CODE_LENGTH.
- * tree.c (break_out_calls, build_min_nt): Use TREE_CODE_LENGTH.
- (built_min, cp_tree_equal): Likewise.
-
-2000-05-26 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (layout_nonempty_base_or_field): Replace
- `record_layout_info' with `record_layout_info_s'.
-
-2000-05-26 Jason Merrill <jason@casey.soma.redhat.com>
-
- Fix goto checking.
- * cp-tree.h (struct language_function): x_named_labels is now
- a struct named_label_list*.
- * decl.c (struct named_label_use_list): Renamed from...
- (struct named_label_list): ...this. New struct.
- (push_binding_level): Don't set eh_region.
- (note_level_for_eh): New fn.
- (pop_label): Take label and old value directly.
- (pop_labels): Adjust for new named_labels format.
- (lookup_label): Likewise.
- (poplevel): Note characteristics of a binding level containing a
- named label. Mess with named label lists earlier.
- (mark_named_label_lists): New fn.
- (mark_lang_function): Call it.
- (use_label): New fn, split out from...
- (make_label_decl): ...here. Don't call it.
- (decl_jump_unsafe, check_previous_goto, check_previous_goto_1,
- check_previous_gotos): New fns, split out from...
- (define_label): ...here.
- (check_switch_goto): New fn.
- (define_case_label): Call it.
- (check_goto): New fn.
- * semantics.c (finish_goto_stmt): Call it and use_label.
- (begin_compound_stmt): If we're a try block, call note_level_for_eh.
- (expand_stmt): Never pass 1 as DONT_JUMP_IN to expand_end_bindings.
-
-2000-05-26 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (build_vtable_entry_ref): Correct usage of
- get_vtbl_decl_for_binfo.
-
- * decl2.c (grokclassfn): Set DECL_LANGUAGE here.
- * method.c (implicitly_declare_fn): Not here.
-
-2000-05-26 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (CPTI_PTMD_DESC_TYPE): Rename to ...
- (CPTI_PTMD_DESC_TYPE): ... here.
- (ptmd_desc_type_node): Rename to ...
- (ptm_desc_type_node): ... here.
- * decl.c: Likewise.
- * rtti.c (ptmd_initializer): Rename to ...
- (ptm_initializer): ... here.
- (sythesize_tinfo_var): Adjust. Deal with pointer to member
- function.
- (create_tinfo_types): Adjust.
-
-2000-05-25 Mark Mitchell <mark@codesourcery.com>
-
- Finish implementation of VTTs.
- * cp-tree.h (cp_tree_index): Add CPTI_VTT_PARM_TYPE and
- CPTI_VTT_PARM_IDENTIFIER.
- (vtt_parm_identifier): New macro.
- (vtt_parm_type): Likewise.
- (BINFO_SUBVTT_INDEX): Likewise.
- (BINFO_VPTR_INDEX): Likewise.
- (struct lang_decl): Add vtt_parm.
- (DECL_VTT_PARM): New macro.
- (DECL_USE_VTT_PARM): Likewise.
- (DECL_NEEDS_VTT_PARM_P): Likewise.
- (get_vtt_name): Declare.
- (build_artificial_parm): Likewise.
- (fixup_all_virtual_upcast_offsets): Likewise.
- (expand_indirect_vtbls_init): Remove.
- * call.c (build_new_method_call): Pass the vtt to subobject
- constructors and destructors.
- * class.c (get_vtt_name): Give it external linkage.
- (build_clone): Handle the magic VTT parameters for clones.
- (clone_function_decl): Fix typo in comment.
- (build_vtt): Keep track of the indices in the VTTs where various
- entities are stored.
- (build_vtt_inits): Likewise.
- (dfs_build_vtt_inits): Likewise.
- (build_ctor_vtbl_group): Tweak type of construction vtables.
- (dfs_accumulate_vtbl_inits): Build vtables for all bases, even
- primary bases, when building construction vtables.
- * decl.c (duplicate_decls): Handle DECL_VTT_PARM.
- (initialize_predefined_identifiers): Add vtt_parm_identifier.
- (init_decl_processing): Initialize vtt_parm_type.
- (grokfndecl): Use DECL_OVERLOADED_OPERATOR_P.
- (lang_mark_tree): Make vtt_parm.
- * decl2.c (build_artificial_parm): New function.
- (maybe_retrofit_in_chrg): Use it. Add VTT parameters.
- (grokclassfn): Use build_artificial_parm.
- * init.c (initialize_vtbl_ptrs): Call
- fixup_all_virtual_upcast_offsets directly.
- (perform_member_init): Use the complete subobject destructor for
- member cleanups.
- (build_vtbl_address): New function.
- (expand_virtual_init): Handle VTTs.
- * optimize (maybe_clone_body): Likewise.
- * search.c (fixup_all_virtual_upcast_offsets): Give it external
- linkage.
- (expand_indirect_vtbls_init): Remove.
- * semantics.c (setup_vtbl_ptr): Fix typos in comment.
- * tree.c (make_binfo): Make them bigger.
-
-2000-05-25 Nathan Sidwell <nathan@codesourcery.com>
-
- * inc/cxxabi.h (__pbase_type_info): Define, based on
- __pointer_type_info.
- (__pointer_type_info): Derive from __pbase_type_info. Adjust.
- (__pointer_to_member_type_info): Likewise.
- * tinfo2.cc (__pbase_type_info::~__pbase_type_info): Implement.
- (__pointer_to_member_type_info::__is_pointer_p): Remove.
- (__pointer_type_info::__do_catch): Rename to ...
- (__pbase_type_info::__do_catch): ... here. Adjust.
- (__pbase_type_info::__pointer_catch): Implement.
- (__pointer_type_info::__pointer_catch): Adjust.
- (__pointer_to_member_type_info::__pointer_catch): Adjust.
-
-2000-05-25 Nathan Sidwell <nathan@codesourcery.com>
-
- * tinfo.h (__user_type_info::contained_virtual_p): New
- predicate.
- * tinfo.cc (__user_type_info::do_upcast): Fix bug with diamond
- shaped hierarchy.
- (__vmi_class_type_info::__do_upcast): Fix bug with NULL pointer to
- diamond shaped hierarchy. Add early out for mixed diamond and
- duplicate shaped hierarchy.
-
-2000-05-24 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (build_delete): Change prototype.
- (build_vec_delete): Likewise.
- * call.c (build_scoped_method_call): Use special_function_kind
- values to indicate the kind of destruction to be done.
- (build_method_call): Likewise.
- * decl.c (finish_destructor_body): Likewise.
- (maybe_build_cleanup_1): Likewise. Rename to ...
- (maybe_build_cleanup): ... this.
- * decl2.c (delete_sanity): Use special_function_kind
- values to indicate the kind of destruction to be done.
- (build_cleanup): Likewise.
- * init.c (perform_member_init): Likewise.
- (build_vec_delete_1): Likewise.
- (build_dtor_call): Simplify.
- (build_delete): Use special_function_kind
- values to indicate the kind of destruction to be done.
- (build_vbase_delete): Likewise.
- (build_vec_delete): Likewise.
-
- * init.c (sort_member_init): Fix typo in error message generation
- code.
-
-Mon May 15 11:46:29 2000 Donald Lindsay <dlindsay@cygnus.com>
-
- * semantics.c (begin_class_definition): make the packed
- attribute be sensitive to the "-fpack-struct" command line flag
-
-2000-05-24 Nathan Sidwell <nathan@codesourcery.com>
-
- Update new-abi upcast algorithm.
- * inc/cxxabi.h (__class_type_info::__do_upcast): Change
- prototype and meaning of return value.
- (__si_class_type_info::__do_upcast): Likewise.
- (__vmi_class_type_info::__do_upcast): Likewise.
- * tinfo.cc (__class_type_info::__upcast_result): Replace
- whole2dst with part2dst. Adjust ctor.
- (__class_type_info::__do_upcast): Adjust call of worker function.
- (__class_type_info::__do_upcast): Adjust.
- (__si_class_type_info::__do_upcast): Adjust. Use parent's
- __do_upcast.
- (__vmi_class_type_info::__do_upcast): Likewise. Fix private
- virtual base in diamond hierarchy bug.
-
-2000-05-23 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (lang_decl_flags): Rename mutable_flag to uninlinable
- and bitfield to tinfo_fn_p.
- (DECL_TINFO_FN_P): Adjust.
- (SET_DECL_TINFO_FN_P): Likewise.
- (DECL_MUTABLE_P): Likewise.
- (DECL_C_BIT_FIELD): Likewise.
- (SET_DECL_C_BIT_FIELD): Likewise.
- (CLEAR_DECL_C_BIT_FIELD): Likewise.
- (DECL_UNINLINABLE): Likewise.
- * class.c (alter_access): Call retrofit_lang_decl if ncessary.
- (handle_using_decl): Remove assertion.
- (build_vtbl_or_vbase_field): Use build_decl, not build_lang_decl,
- to build FIELD_DECLs.
- (build_base_field): Likewise.
- (layout_class_type): Likewise.
- * decl.c (init_decl_processing): Likewise.
- (build_ptrmemfunc_type): Likewise.
- (grokdeclarator): Likewise.
- * decl2.c (grok_x_components): Likewise.
- * except.c (call_eh_info): Likewise.
- * init.c (init_init_processing): Likewise.
- * rtti.c (expand_class_desc): Likewise.
- (create_pseudo_type_info): Likewise.
- (get_vmi_pseudo_type_info): Likewise.
- (create_tinfo_types): Likewise.
- * ptree.c (print_lang_decl): Adjust.
- * typeck.c (build_component_ref): Don't check DECL_LANG_SPECIFIC
- before checking DECL_MUTABLE_P.
-
- * decl2.c (maybe_retrofit_in_chrg): Don't create in-charge
- parameters for template functions.
- * pt.c (tsubst_decl): Make sure we call maybe_retrofit_in_chrg for
- destructors as well as constructors.
-
-2000-05-22 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (build_ctor_vtbl_group): Set inits.
- * optimize.c (maybe_clone_body): Set DECL_INLINE and
- DECL_THIS_INLINE appropriately for clones.
-
- * cp-tree.h (IDENTIFIER_TYPENAME_P): Use a flag, not strncmp.
- (DECL_CONV_FN_P): Simplify.
- (DECL_OPERATOR): Remove.
- (language_to_string): Declare.
- * decl.c (duplicate_decls): Fix typo in comment.
- (grokdeclarator): Adjust use of IDENTIFIER_TYPENAME_P.
- (grok_op_properties): Use DECL_CONV_FN_P instead of
- IDENTIFIER_TYPENAME_P.
- * dump.c (dequeue_and_dump): Dump the language linkage of
- declarations.
- * error.c (language_to_string): Give it external linkage.
- * method.c (build_typename_overload): Set IDENTIFIER_TYPENAME_P.
- (implicitly_declare_fn): Set DECL_LANGUAGE.
- * pt.c (check_explicit_specialization): Use DECL_CONV_FN_P, not
- IDENTIFIER_TYPENAME_P.
- (tsubst_decl): Likewise.
- (tsubst_copy): Adjust use of IDENTIFIER_TYPENAME_P.
- * semantics.c (finish_member_declaration): Don't mark members of
- classes declared in an extern "C" region as extern "C".
-
-2000-05-22 Martin v. Löwis <loewis@informatik.hu-berlin.de>
-
- * decl2.c (qualified_lookup_using_namespace): Look through
- namespace aliases.
-
- * decl.c (push_using_decl): Return the old decl on namespace level.
-
-2000-05-21 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (SET_BINFO_NEW_VTABLE_MARKED): Add sanity checks.
- (VTT_NAME_PREFIX): New macro.
- (CTOR_VTBL_NAME_PREFIX): Likewise.
- (get_ctor_vtbl_name): New function.
- * class.c (get_vtable_name): Simplify.
- (get_vtt_name): New function.
- (get_vtable_decl): Don't set IDENTIFIER_GLOBAL_VALUE.
- (dfs_mark_primary_bases): Update the CLASSTYPE_VBASECLASSES list
- when a virtual base becomes primary.
- (finish_struct_1): Set CLASSTYPE_VFIELDS a little earlier. Build
- VTTs.
- (finish_vtbls): Adjust calls to accumulate_vtbl_inits to pass in
- additional parameters.
- (dfs_finish_vtbls): Don't clear BINFO_NEW_VTABLE_MARKED.
- (initialize_array): New function.
- (build_vtt): Likewise.
- (build_vtt_inits): Likewise.
- (dfs_build_vtt_inits): Likewise.
- (dfs_fixup_binfo_vtbls): Likewise.
- (build_ctor_vtbl_group): Likewise.
- (initialize_vtable): Use initialize_array.
- (accumulate_vtbl_inits): Reimplement to handle construction
- vtables.
- (dfs_accumulate_vtbl_inits): Likewise.
- (bulid_vtbl_initializer): Adjust parameter name.
- * method.c (build_typename_overload): Remove #if 0'd code.
- (get_ctor_vtbl_name): New function.
- * search.c (dfs_walk_real): Use BINFO_N_BASETYPES.
- (init_vbase_pointers): Don't mess with the TREE_CHAIN of a binfo.
-
- * cp-tree.h (struct lang_type): Remove search_slot.
- (CLASSTYPE_SEARCH_SLOT): Remove.
- (emit_base_init): Change prototype.
- (initialize_vtbl_ptrs): Likewise.
- (expand_indirect_vtbls_init): Likewise.
- (clear_search_slots): Remove.
- * decl.c (lang_mark_tree): Don't mark search_slot.
- * init.c (initialize_vtbl_ptrs): Simplify.
- (emit_base_init): Likewise.
- * search.c (struct vbase_info): Document decl_ptr.
- (convert_pointer_to_single_level): Remove.
- (dfs_find_vbases): Remove.
- (dfs_init_base_pointers): Simplify.
- (dfs_clear_vbase_slots): Remove.
- (dfs_vtable_path_unmark): New function.
- (init_vbase_pointers): Simplify.
- (expand_upcast_fixups): Don't rely on CLASSTYPE_SEARCH_SLOT.
- (expand_indirect_vtbls_init): Simplify. Don't call
- mark_all_temps_used.
- * semantics.c (setup_vtbl_ptr): Adjust calls to emit_base_init and
- initialize_vtbl_ptrs.
-
-2000-05-20 Zack Weinberg <zack@wolery.cumb.org>
-
- * except.c: Add static prototypes.
-
-2000-05-20 H.J. Lu <hjl@gnu.org>
-
- * Make-lang.in (cplib2.ready): Also depend on cc1plus$(exeext).
-
-2000-05-19 Mark Mitchell <mark@codesourcery.com>
-
- Don't create a separate copy of virtual bases for the
- CLASSTYPE_VBASECLASSES list.
- * cp-tree.h (CLASSTYPE_VBASECLASSES): Change documentation.
- (BINFO_FOR_VBASE): Remove.
- (CANONICAL_BINFO): Adjust.
- (binfo_for_vbase): New function.
- * class.c (build_vbase_pointer_fields): Use binfo_for_vbase
- instead of BINFO_FOR_VBASE.
- (build_vbase_pointer): Likewise.
- (build_secondary_vtable): Likewise.
- (dfs_mark_primary_bases): Likewise.
- (mark_primary_bases): Likewise.
- (layout_nonempty_base_or_field): Likewise.
- (dfs_set_offset_for_shared_vbases): Likewise.
- (dfs_set_offset_for_unshared_vbases): Likewise.
- (layout_virtual_bases): Likewise. Adjust for changes to the
- CLASSTYPE_VBASECLASSES list.
- (dump_class_hierarchy_r): Use binfo_for_vbase
- instead of BINFO_FOR_VBASE.
- (dump_class_hierarchy): Likewise.
- (finish_vtbls): Likewise.
- (build_vtbl_initializer): Adjust for changes to the
- CLASSTYPE_VBASECLASSES list.
- (build_vbase_offset_vtbl_entries): Use binfo_for_vbase.
- * decl.c (finish_destructor_body): Adjust for changes to the
- CLASSTYPE_VBASECLASSES list.
- * init.c (sort_base_init): Use binfo_for_vbase.
- (construct_virtual_bases): Adjust for changes to the
- CLASSTYPE_VBASECLASSES list.
- (expand_member_init): Use binfo_for_vbase.
- (build_vbase_delete): Adjust for changes to the
- CLASSTYPE_VBASECLASSES list.
- * method.c (do_build_copy_constructor): Likewise.
- * rtti.c (get_base_offset): Use binfo_for_vbase.
- (expand_class_desc): Remove #if 0'd code.
- * search.c (struct vbase_info): Remove vbase_types.
- (get_base_distance): Use binfo_for_vbase.
- (lookup_field_queue_p): Use CANONICAL_BINFO.
- (get_shared_vbase_if_not_primary): Use binfo_for_vbase.
- (get_pure_virtuals): Adjust for changes to the
- CLASSTYPE_VBASECLASSES list.
- (dfs_find_vbases): Use binfo_for_vbase.
- (dfs_init_vbase_pointers): Likewise.
- (init_vbase_pointers): Don't initialize vi.vbase_types.
- (virtual_context): Use binfo_for_vbase.
- (fixup_all_virtual_upcast_offsets): Adjust for changes to the
- CLASSTYPE_VBASECLASSES list.
- (expand_indirect_vtbls_init): Simplify.
- (dfs_get_vbase_types): Don't replicate virtual bases.
- (find_vbase_instance): Use binfo_for_vbase.
- (binfo_for_vbase): New function.
- * typeck.c (get_delta_difference): Use binfo_for_vbase.
-
-2000-05-17 Mark Mitchell <mark@codesourcery.com>
-
- * decl2.c (finish_anon_union): Generalize error messages to handle
- anonymous structures.
- * init.c (perform_member_init): Remove `name' parameter.
- (build_field_list): New function.
- (sort_member_init): Handle anonymous union initialization order
- correctly. Check for multiple initializations of the same union.
- (emit_base_init): Don't look up fields by name here.
- (expand_member_init): Record the result of name lookup for future
- reference.
- * typeck.c (build_component_ref): Fix formatting.
-
-Wed May 17 17:27:44 2000 Andrew Cagney <cagney@b1.cygnus.com>
-
- * decl.c (pop_label): Replace warn_unused with warn_unused_label.
- * typeck.c (build_x_compound_expr): Replace warn_unused with
- warn_unused_value.
-
- * decl2.c (lang_decode_option): Update -Wall unused flags by
- calling set_Wunused.
-
-2000-05-16 Mark Mitchell <mark@codesourcery.com>
-
- * cp-treeh (BINFO_NEW_VTABLE_MARKED): Update documentation.
- * init.c (dfs_vtable_path_unmark): Remove.
- * search.c (marked_new_vtable_p): Likewise.
- (unmarked_new_vtable_p): Likewise.
- (dfs_search_slot_nonempty_p): Likewise.
- (dfs_mark): Likewise.
- (dfs_vtable_path_unmark): Likewise.
- (dfs_find_vbases): Don't set BINFO_NEW_VTABLE_MARKED.
- (dfs_int_vbase_pointers): Don't clear BINFO_VTABLE_PATH_MARKED.
- (dfs_init_vbase_pointers): Remove special-case new ABI code.
- (dfs_clear_vbase_slots): Don't clear BINFO_NEW_VTABLE_MARKED.
- (init_vbase_pointers): Simplify.
- (expand_indirect_vtbls_init): Likewise.
-
- * class.c (copy_virtuals): New function.
- (build_primary_table): Use it.
- (build_secondary_vtable): Likewise.
- (modify_vtable_entry): Use NULL_TREE, not integer_zero_node, to
- indicate that no vcall offset is required.
- (add_virtual_function): Likewise.
- (modify_all_vtables): Likewise.
- (dfs_finish_vtbls): Adjust call to build_vtbl_initializer.
- (dfs_accumulate_vtbl_inits): Likewise.
- (build_vtbl_initializer): Make changes to handle construction
- vtables.
- (dfs_build_vcall_offset_vtbl_entries): Likewise.
- (build_rtti_vtbl_entries): Likewise.
- (build_vtable_entries): Handle a NULL vcall_index.
-
-2000-05-15 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * decl2.c (lang_decode_option): Fix thinko.
-
-2000-05-14 Jason Merrill <jason@casey.cygnus.com>
-
- * except.c (check_handlers): New fn.
- * cp-tree.h: Declare it.
- * semantics.c (finish_handler_sequence): Call it.
- (finish_function_handler_sequence): Likewise.
- (finish_handler_parms): Set TREE_TYPE on the handler.
- * cp-tree.h (PUBLICLY_UNIQUELY_DERIVED_P): New macro.
- * search.c (get_base_distance_recursive): If protect>1, ignore
- special access.
- (get_base_distance): Don't reduce watch_access.
-
-2000-05-13 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * lex.c: #include diagnostic.h.
- (lang_init_options): Set default prefixing rules.
-
- * lang-options.h: Add -fdiagnostics-show-location=.
-
- * decl2.c: #include diagnostic.h.
- (lang_decode_option): Handle -fdiagnostics-show-location=.
-
-2000-05-12 Nathan Sidwell <nathan@codesourcery.com>
-
- * tinfo.cc: Revert my 2000-05-08 and 2000-05-07 changes.
- * vec.cc: Revert my 2000-05-07 change.
-
-2000-05-11 Jason Merrill <jason@casey.cygnus.com>
-
- * class.c (check_field_decls): Complain about non-static data
- members with same name as class in class with constructor.
-
-2000-05-10 Jason Merrill <jason@casey.cygnus.com>
-
- * decl.c (grokdeclarator): Allow non-static data members with
- same name as class.
-
-2000-05-09 Zack Weinberg <zack@wolery.cumb.org>
-
- * cp-tree.h: Constify tree_srcloc.filename, tinst_level.file,
- and pending_inline.filename. Update prototypes.
- * decl.c (define_label): Constify filename parameter.
- * decl2.c (warn_if_unknown_interface): Constify local char *.
- * input.c Constify input_source.filename. Don't declare
- input_filename or lineno. Constify filename parameter to feed_input.
- * lex.c (init_parse): Constify parameter and return value.
- (cp_pragma_interface, cp_pragma_implementation): Constify
- filename argument.
- (reinit_parse_for_method, reinit_parse_for_block,
- reinit_parse_for_expr, feed_defarg, handle_cp_pragma):
- Constify local char *.
- * pt.c: Don't declare lineno or input_filename.
- (print_template_context, tsubst_friend_function, tsubst_decl,
- tsubst, instantiate_decl): Constify local char *.
- * semantics.c (expand_body): Constify local char *.
- * tree.c (build_srcloc): Constify filename parameter.
- * typeck.c (c_expand_asm_operands): Constify filename
+ PR c++/13157
+ * name-lookup.c (lookup_using_namespace): Remove spacesp
parameter.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_qualified_name): Adjust accordingly.
+ (lookup_name_real): Likewise.
+ (lookup_arg_dependent): Do not eliminate the namespace of the
+ functions found by unqualified name lookup unless that is the
+ current namespace.
-2000-05-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * tinfo.cc (__dynamic_cast): Use a reinterpret_cast. Fix
- offsetof expansion.
-
-2000-05-08 Branko Cibej <branko.cibej@hermes.si>
-
- * inc/cxxabi.h: Fix typos in comment.
- (__base_class_info::__offset): Use a static_cast.
-
-2000-05-07 Nathan Sidwell <nathan@codesourcery.com>
-
- * inc/cxxabi.h: Use __SIZE_TYPE_ and __PTRDIFF_TYPE__ in place
- of std::size_t and std::ptrdiff_t respectively.
- * tinfo.cc: Likewise.
- * vec.cc: Likewise.
-
-2000-05-06 Richard Henderson <rth@cygnus.com>
-
- * typeck.c (build_c_cast): Don't warn integer->pointer size
- mismatch for constants.
-
-2000-05-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * rtti.c (ptmd_initializer): Set non-public, if class is
- incomplete.
-
- * inc/cxxabi.h (__dynamic_cast): Explicitly say extern "C++".
- (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
- __cxa_vec_delete): Likewise.
- * tinfo.cc (__dynamic_cast): Likewise.
- * vec.cc (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
- __cxa_vec_delete): Likewise.
-
-2000-05-04 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (DELTA_FROM_VTABLE_ENTRY): Remove.
- (SET_FNADDR_FROM_VTABLE_ENTRY): Likewise.
- (lang_decl_flags): Add vcall_offset.
- (THUNK_VCALL_OFFSET): Use it.
- * decl.c (lang_mark_tree): Don't mark DECL_ACCESS for a thunk.
- * method.c (make_thunk): Create the lang_decl here, not in
- emit_thunk.
- (emit_thunk): Make generic thunks into ordinary functions once
- they have been fed to expand_body.
- * semantics.c (expand_body): Set current_function_is_thunk here.
-
-2000-05-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * class.c (update_vtable_entry_for_fn): Prototype.
-
- * pt.c (tsubst_decl): Initialize variables `argvec', `gen_tmpl'
- and `tmpl'.
-
- * search.c (dfs_build_inheritance_graph_order): Prototype.
-
-2000-05-04 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (special_function_kind): Add various kinds of
- destructors.
- (special_function_p): New function.
- * class.c (overrides): Don't let one kind of destructor override
- another.
- * decl2.c (mark_used): Use DECL_NON_THUNK_FUNCTION_P when deciding
- whether or not to instantiate a template.
- * tree.c (special_function_p): Define.
-
-2000-05-03 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.def (THUNK_DECL): Remove.
- * cp-tree.h (DECL_THUNK_P): New macro.
- (DECL_NON_THUNK_FUNCTION_P): Likewise.
- (DECL_EXTERN_C_FUNCTION_P): Likewise.
- (SET_DECL_THUNK_P): Likewise.
- (DELTA_FROM_VTABLE_ENTRY): Use DECL_THUNK_P.
- (FNADDR_FROM_VTABLE_ENTRY): Likewise.
- (DECL_MAIN_P): Use DECL_EXTERN_C_FUNCTION_P.
- * decl.c (decls_match): Use DECL_EXTERN_C_P.
- (duplicate_decls): Likewise.
- (pushdecl): Likewise. Adjust thunk handling.
- (grokfndecl): Use DECL_EXTERN_C_P.
- * decl2.c (mark_vtable_entries): Use DECL_THUNK_P.
- * dump.c (dequeue_and_dump): Remove THUNK_DECL handling.
- * except.c (nothrow_libfn_p): Use DECL_EXTERN_C_P.
- * expr.c (cplus_expand_expr): Remove THUNK_DECL handling.
- * method.c (make_thunk): Use SET_DECL_THUNK_P. Set
- DECL_NO_STATIC_CHAIN.
- (emit_thunk): Don't play games with TREE_CODE on thunks. Don't
- set DECL_DESTRUCTOR_P or DECL_CONSTRUCTOR_P on a thunk.
- * search.c (covariant_return_p): Remove THUNK_DECL handling.
- * ir.texi: Update.
-
-2000-05-01 Jason Merrill <jason@casey.cygnus.com>
-
- * tree.c (walk_tree): Set lineno.
-
-2000-05-01 Mark Mitchell <mark@codesourcery.com>
-
- * exception.cc: Update license notice.
- * new.cc: Likewise.
- * new1.cc: Likewise.
- * new2.cc: Likewise.
- * tinfo.cc: Likewise.
- * tinfo2.cc: Likewise.
- * vec.cc: Likewise.
- * inc/cxxabi.h: Likewise.
- * inc/exception: Likewise.
- * inc/new: Likewise.
- * inc/new.h: Likewise.
- * inc/typeinfo: Likewise.
-
-2000-05-01 Jason Merrill <jason@casey.cygnus.com>
-
- * tree.c (build_target_expr_with_type): If we already have a
- TARGET_EXPR, just return it.
-
- * optimize.c (initialize_inlined_parameters): Don't generate an
- EXPR_STMT if we can just use DECL_INITIAL.
- * decl.c (emit_local_var): Only make the initialization a
- full-expression if stmts_are_full_exprs_p.
-
-2000-05-01 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (same_type_ignoring_top_level_qualifiers_p): New
- macro.
- * call.c (standard_conversion): Use it.
- (direct_reference_binding): Likewise.
- (build_over_call): Likewise.
- (is_properly_derived_from): Likewise.
- (compare_ics): Likewise.
- * class.c (resolves_to_fixed_type_p): Likewise.
- * optimize.c (declare_return_variable): Likewise.
- * pt.c (is_specialization_of): Likewise.
- (unify): Likewise.
- * typeck.c (comp_target_parms): Likeiwse.
- (build_static_cast): Likewise.
- (build_reinterpret_cast): Likewise.
- (build_const_cast): Likewise.
- (comp_ptr_ttypes_real): Likewise.
- (comp_ptr_ttypes_const): Likewise.
- * typeck2.c (process_init_constructor): Likewise.
-
-2000-04-30 Scott Snyder <snyder@fnal.gov>
-
- * decl.c (finish_destructor_body): Use the base destructor when
- destroying virtual bases.
-
-2000-04-30 Mark Mitchell <mark@codesourcery.com>
-
- * expr.c (cplus_expand_expr): Preserve temporaries when expanding
- STMT_EXPRs.
- * optimize.c (struct inline_data): Add target_exprs field.
- (declare_return_variable): When a function returns an aggregate,
- use the variable declared in the TARGET_EXPR as the remapped
- DECL_RESULT.
- (expand_call_inline): Update the pending target_exprs stack.
- (optimize_function): Initialize the stack.
-
- * decl2.c (finish_file): Fix typo in comment.
-
- * method.c (emit_thunk): Don't try to return a `void' value.
-
- * optimize.c (initialize_inlined_parameters): If the parameter is
- addressable, we need to make a new VAR_DECL, even if the
- initializer is constant.
-
-2000-04-28 Cosmin Truta <cosmint@cs.ubbcluj.ro>
-
- * decl.c (grok_op_properties): Add an extra check of argtypes.
-
-2000-04-27 Mark Mitchell <mark@codesourcery.com>
-
- * optimize.c (copy_body_r): Use STRIP_TYPE_NOPS when copying
- variables.
- (initialize_inlined_parameters): Try to avoid creating new
- VAR_DECLs.
-
-2000-04-27 Alex Samuel <samuel@codesourcery.com>
-
- * lex.c (my_get_run_time): Remove.
- (init_filename_times): Use get_run_time instead of my_get_run_time.
- (check_newline): Likewise.
- (dump_time_statistics): Likewise.
- * decl2.c (finish_file): Push and pop timevar TV_VARCONST instead
- of computing elapsed time explicitly.
-
-2000-04-26 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (TREE_READONLY_DECL_P): Use DECL_P.
- * init.c (decl_constant_value): Check TREE_READONLY_DECL_P.
- * call.c (convert_like_real): Don't test TREE_READONLY_DECL_P
- before calling decl_constant_value.
- * class.c (check_bitfield_decl): Likewise.
- * cvt.c (ocp_convert): Likewise.
- (convert): Likewise.
- * decl.c (compute_array_index_type): Likewise.
- (build_enumerator): Likewise.
- * decl2.c (check_cp_case_value): Likewise.
- * pt.c (convert_nontype_argument): Likewise.
- (tsubst): Likewise.
- * typeck.c (decay_conversion): Likewise.
- (build_compound_expr): Likewise.
- (build_reinterpret_cast): Likewise.
- (build_c_cast): Likewise.
- (convert_for_assignment): Likewise.
-
-2000-04-26 Jason Merrill <jason@casey.cygnus.com>
-
- * decl.c (finish_function): Don't play games with DECL_INLINE.
-
-2000-04-25 Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
-
- * ir.texi: Correct typo.
-
-2000-04-25 Martin v. Löwis <loewis@informatik.hu-berlin.de>
-
- * decl.c (grokdeclarator): Reject VLAs as members.
-
-2000-04-24 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * call.c (standard_conversion): Accept conversion between
- COMPLEX_TYPEs.
-
- * cvt.c (ocp_convert): Handle conversion to COMPLEX_TYPE.
-
-2000-04-24 Zack Weinberg <zack@wolery.cumb.org>
-
- * decl2.c (finish_file): Remove double setup for accounting
- compile time.
-
-2000-04-24 Robert Lipe <robertlipe@usa.net>
-
- * cp-tree.h (lang_type): Member `language' now ENUM_BITFIELD.
-
-2000-04-23 Benjamin Kosnik <bkoz@cygnus.com>
-
- * new.cc (set_new_handler): Needs to be in std::.
-
-2000-04-23 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (lang_decl): Remove pretty_function_p.
- (DECL_PRETTY_FUNCTION_P): Use TREE_LANG_FLAG_0, not a bit in the
- language-specific node.
- * decl.c (cp_make_fname_decl): Use build_decl, not
- build_lang_decl, to build the variables.
- (grokvardecl): Don't call build_lang_decl for local variables in
- templates.
- (grokdeclarator): Don't call build_lang_decl for local type
- declarations in templates.
- * lex.c (retrofit_lang_decl): Use ggc_alloc_obj to allocated
- zero'd memory, rather than calling memset.
- * pt.c: Include hashtab.h.
- (local_specializations): New variable.
- (retrieve_local_specialization): Use it.
- (register_local_specialization): Likewise.
- (tsubst_decl): Don't assume local variables have
- DECL_LANG_SPECIFIC.
- (instantiate_decl): Set up local_specializations.
- * Makefile.in (HTAB_H): New variable.
-
-2000-04-23 Richard Henderson <rth@cygnus.com>
-
- * typeck.c (c_expand_asm_operands): Restore the original
- contents of the output list.
-
-2000-04-22 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * ir.texi: Document complex number representation.
-
-2000-04-20 Nathan Sidwell <nathan@codesourcery.com>
-
- * rtti.c (init_rtti_processing): Set tinfo_var_id in new-abi.
- (target_incomplete_p): New function.
- (tinfo_base_init): Create comdat NTBS name variable.
- (ptr_initializer): Add non_public parameter. Calculate it.
- (ptmd_initializer): Likewise.
- (synthesize_tinfo_var): Adjust. Emit incomplete class tinfo.
- (create_real_tinfo_var): Add non_public parameter. Use it.
- Push proxy into global namespace.
- * inc/cxxabi.h (__pointer_type_info::incomplete_class_mask):
- New enumeration.
- * inc/typeinfo (type_info::before, type_info::operator==):
- Compare __name addresses.
-
- * tinfo2.cc: Remove new-abi builtins comment.
-
-2000-04-20 Jason Merrill <jason@casey.cygnus.com>
-
- * typeck.c (build_x_function_call): Resolve an OFFSET_REF.
-
- * call.c (joust): Exit early if we get the same function, too.
-
- * decl2.c (key_method): Return NULL_TREE for template classes.
- (import_export_class): Don't need to check for template classes.
-
-2000-04-18 Zack Weinberg <zack@wolery.cumb.org>
-
- * lex.c: Remove references to cccp.c.
-
-2000-04-18 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (lang_decl_flags): Remove const_memfunc and
- volatile_memfunc. Add destructor_attr. Adjust dummy.
- (DECL_DESTRUCTOR_P): Use destructor_attr.
- (DECL_CONST_MEMFUNC_P): Reimplement.
- (DECL_VOLATILE_MEMFUNC_P): Remove.
- * class.c (finish_struct_methods): Use CLASSTYPE_DESTRUCTORS.
- (overrides): Use DECL_DESTRUCTOR_P.
- (check_for_override): Likewise.
- * decl.c (start_function): Likewise.
- * decl2.c (grokfclassfn): Likewise.
- (check_classfn): Likewise.
- (grok_function_init): Likewise.
-
-2000-04-17 Mark Mitchell <mark@codesourcery.com>
-
- * decl2.c (grokfield): Issue error on illegal data member
- declaration.
-
-Mon Apr 17 17:11:16 2000 Mark P Mitchell <mark@codesourcery.com>
-
- * method.c (make_thunk): Set DECL_CONTEXT for a THUNK_DECL.
-
-2000-04-16 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (build_vtable_entry): Don't build thunks for type-info
- functions.
-
-2000-04-16 Jason Merrill <jason@casey.cygnus.com>
-
- * decl.c (decls_match): Allow a redeclaration of a builtin to
- specify args while the builtin did not.
-
-2000-04-15 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.def (THUNK_DECL): Add to documentation.
- * cp-tree.h (flag_huge_objects): Declare.
- * class.c (modify_vtable_entry): Tidy.
- (update_vtable_entry_for_fn): Split out from dfs_modify_vtables.
- Calculate delta appropriately for the new ABI.
- (dfs_modify_vtables): Use it.
- (modify_all_vtables): Fix thinko in code to add overriding copies
- of functions to primary vtables.
- (build_clone): Fix typo in comment.
- (clone_function_decl): Correct order of destructors in vtable.
- (build_vbase_offset_vtbl_entries): Adjust comment.
- (dfs_vcall_offset_queue_p): Remove.
- (dfs_build_vcall_offset_vtbl_entries): Update BV_VCALL_INDEX.
- (build_vcall_offset_vtbl_entries): Juse use dfs_skip_vbases.
- (build_vtable_entry): Correct check for pure virtual functions.
- Don't declare flag_huge_objects.
- * decl.c (flag_huge_objects): Remove declaration.
- * method.c (make_thunk): Tweak mangling for vcall offset thunks.
- Use int_size_in_bytes.
- (emit_thunk): Handle vcall offset thunks.
-
-Sat Apr 15 16:00:01 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * decl2.c (parse_time, varconst_time): Delete declarations.
- (finish_file): Delete LINENO declaration.
- START_TIME and THIS_TIME now long.
-
-2000-04-13 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (build_base_field): Reformat comment.
-
- * inc/cxxabi.h (stddef.h): Comment inclusion.
- (__base_class_info::__offset): Comment shift.
-
-2000-04-12 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (IDENTIFIER_CTOR_OR_DTOR_P): New macro.
- (cp_tree_index): Add CPTI_PUSH_EXCEPTION_IDENTIFIER.
- (cp_push_exception_identifier): New macro.
- (DECL_COMPLETE_DESTRUCTOR_P): New macro.
- (DECL_BASE_DESTRUCTOR_P): Likewise.
- (DECL_DELETING_DESTRUCTOR_P): Likewise.
- (get_vtbl_decl_for_binfo): Fix formatting.
- (in_charge_arg_for_name): New macro.
- (maybe_build_cleanup_and_delete): Remove declaration.
- * call.c (build_field_call): Use IDENTIFIER_CTOR_OR_DTOR_P.
- (in_charge_arg_for_name): New function.
- (build_new_method_call): Use it. Handle cloned destructors.
- (build_clone): Don't make the base constructor virtual.
- Automatically defer generated functions.
- (clone_function_decl): Handle destructors, too.
- (clone_constructors_and_destructors): Likewise.
- (create_vtable_ptr): Don't create a vtable entry for a cloned
- function.
- * decl.c (predefined_identifier): Add ctor_or_dtor_p.
- (initialize_predefined_identifiers): Update appropriately.
- (finish_destructor_body): Simplify.
- (maybe_build_cleanup_and_delete): Remove.
- * except.c (expand_throw): Handle new-ABI destructors.
- * init.c (expand_cleanup_for_base): Use base_dtor_identifier.
- (build_dtor_call): New function.
- (build_delete): Use it. Simplify.
- * optimize.c (maybe_clone_body): Handle destructors.
- * search.c (lookup_field_queue_p): Use IDENTIFIER_CTOR_OR_DTOR_P.
-
- * exception.cc (cleanup_fn): New typedef.
- (CALL_CLEANUP): New macro.
- (cp_eh_info): Use them.
- (__cp_push_exception): Likewise.
- (__cp_pop_exception): Likewise.
-
-2000-04-11 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (cp_tree_index): Add CPTI_DTOR_IDENTIFIER.
- (complete_dtor_identifier): New macro.
- (CLASSTYPE_FIRST_CONVERSION): Remove.
- (CLASSTYPE_CONSTRUCTOR_SLOT): New macro.
- (CLASSTYPE_DESTRUCTOR_SLOT): Likewise.
- (CLASSTYPE_FIRST_CONVERSION_SLOT): Likewise.
- (CLASSTYPE_CONSTRUCTORS): Likewise.
- (CLASSTYPE_DESTRUCTORS): Likewise.
- (lang_decl): Add cloned_function.
- (DECL_COMPLETE_CONSTRUCTOR_P): New macro.
- (DECL_BASE_CONSTRUCTOR_P): Likewise.
- (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P): Likewise.
- (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P): Likewise.
- (DECL_CLONED_FUNCTION_P): Likewise.
- (DECL_CLONED_FUNCTION): Likewise.
- (clone_function_decl): Declare.
- (maybe_clone_body): Likewise.
- * call.c (build_user_type_conversion_1): Call complete object
- constructors in the new ABI.
- (build_new_method_call): Don't add in-charge parameters under the
- new ABI.
- * class.c (add_method): Use DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P,
- DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P, CLASSTYPE_CONSTRUCTOR_SLOT, and
- CLASSTYPE_DESTRUCTOR_SLOT.
- (build_clone): New function.
- (clone_function_decl): Likewise.
- (clone_constructors_and_destructors): Likewise.
- (check_bases_and_members): Use it.
- * decl.c (iniitialize_predefined_identifiers): Initialize
- complete_dtor_identifier.
- (finish_function): Don't add extra code to a clone.
- (lang_mark_tree): Mark cloned_function.
- * decl2.c (mark_used): Don't bother trying to instantiate things
- we synthesized.
- * dump.c (dequeue_and_dump): Don't dump CP_DECL_CONTEXT twice.
- * method.c (set_mangled_name_for_decl): Don't treat clones as
- constructors.
- (synthesize_method): Sythesize cloned functions, not the clones.
- * optimize.c (inline_data): Update comment on ret_label.
- (remap_block): Don't assume DECL_INITIAL exists.
- (copy_body_r): Allow ret_label to be NULL.
- (maybe_clone_body): Define.
- * pt.c (tsubst_decl): Handle clones.
- (instantiate_clone): New function.
- (instantiate_template): Use it.
- (set_mangled_name_for_template_decl): Don't treat clones as
- constructors.
- * search.c (lookup_fnfields_1): Use CLASSTYPE_CONSTRUCTOR_SLOT,
- CLASSTYPE_DESTRUCTOR_SLOT, and CLASSTYPE_FIRST_CONVERSION_SLOT.
- * semantics.c (expand_body): Clone function bodies as necessary.
-
- * optimize.c (remap_decl): Avoid sharing structure for arrays
- whose size is only known at run-time.
- * tree.c (copy_tree_r): Don't copy PARM_DECLs.
-
- * cp-tree.h (lang_decl_flags): Rename constructor_for_vbase_attr
- to has_in_charge_parm_p.
- (DECL_CONSTRUCTOR_FOR_VBASE_P): Rename to ...
- (DECL_HAS_IN_CHARGE_PARM_P): ... this.
- (DECL_COPY_CONSTRUCTOR_P): New macro.
- * call.c (add_function_candidate): Use DECL_HAS_IN_CHARGE_PARM_P.
- (build_user_type_conversion_1): Likewise.
- (convert_like_real): Likewise.
- (build_over_call): Likeiwse. Use DECL_COPY_CONSTRUCTOR_P.
- * decl.c (grokdeclarator): Use DECL_HAS_IN_CHARGE_PARM_P.
- (copy_args_p): Likewise.
- (grok_ctor_properties): Likewise.
- (start_function): Likewise.
- * decl2.c (maybe_retrofit_in_charge): Likewise. Set it.
- * error.c (dump_function_decl): Use DECL_HAS_IN_CHARGE_PARM_P.
- * init.c (emit_base_init): Use DECL_COPY_CONSTRUCTOR_P.
- * method.c (do_build_copy_constructor): Use
- DECL_HAS_IN_CHARGE_PARM_P.
- (synthesize_method): Likewise.
- * pt.c (instantiate_template): Remove goto.
- * tree.c (build_cplus_method_type): Remove mention of obstacks in
- comment.
-
- * cp-tre.h (finish_function): Change prototype.
- * decl.c (end_cleanup_fn): Adjust caller.
- (finish_function): Take only one parameter.
- * decl2.c (finish_objects): Adjust caller.
- (finish_static_storage_duration_function): Likewise.
- * method.c (emit_thunk): Likewise.
- * parse.y: Likewise.
- * parse.c: Regenerated.
- * pt.c (instantiate_decl): Likewise.
- * rtti.c (synthesize_tinfo_fn): Likewise.
- * semantics.c (expand_body): Likewise.
-
- * cp-tree.h (copy_decl): New function.
- * class.c (finish_struct_1): Use it.
- * lex.c (copy_decl): Define it.
- * pt.c (tsubst_decl): Likewise.
- * tree.c (copy_template_template_parm): Likewise.
-
- * cp-tree.h (lang_type): Remove has_nonpublic_ctor and
- has_nonpublic_assign_ref.
- (TYPE_HAS_NONPUBLIC_CTOR): Don't declare.
- (TYPE_HAS_NONPUBLIC_ASSIGN_REF): Likewise.
- * class.c (finish_struct_methods): Don't set
- TYPE_HAS_NONPUBLIC_CTOR or TYPE_HAS_NONPUBLIC_ASSIGN_REF.
- (interface_only): Don't declare.
- (interface_unknown): Likewise.
-
-2000-04-11 Martin v. Löwis <loewis@informatik.hu-berlin.de>
-
- * tree.h (HAVE_TEMPLATES): Remove definition.
- * lang-options.h (-fthis-is-variable): Remove documentation.
-
-2000-04-10 Jason Merrill <jason@casey.cygnus.com>
-
- * class.c (instantiate_type): Handle object-relative template-id.
-
- * semantics.c (finish_expr_stmt): Call convert_to_void here.
- * decl.c (cplus_expand_expr_stmt): Not here.
-
- * rtti.c (build_dynamic_cast_1): Call non_lvalue.
- Initialize exprtype earlier.
-
- * parse.y (fn.def1): Check for defining types in return types.
-
- * decl.c (check_tag_decl): Notice extra fundamental types.
- Diagnose empty decls in classes, too.
-
- * decl.c (grokdeclarator): Don't override an anonymous name if no
- declarator was given.
-
- * cvt.c (convert_to_void): Call resolve_offset_ref.
-
- * typeck.c (build_x_function_call): Abort if we get an OFFSET_REF.
-
- * decl2.c (decl_namespace): Handle getting a type.
-
- * typeck.c (build_c_cast): Re-enable warning for cast between
- pointer and integer of different size.
-
-2000-04-10 Nathan Sidwell <nathan@codesourcery.com>
-
- * inc/cxxabi.h (__pointer_type_info): Add restrict and
- incomplete flags.
- (__pointer_type_info::__pointer_catch): New virtual function.
- (__pointer_to_member_type_info): Derive from
- __pointer_type_info. Adjust.
- (__pointer_to_member_type_info::__do_catch): Remove.
- (__pointer_to_member_type_info::__is_pointer_p): Declare.
- (__pointer_to_member_type_info::__pointer_catch): Declare.
- * rtti.c (qualifier_flags): Add restrict flag.
- (ptmd_initializer): Reorder members.
- (create_tinfo_types): Expand comments. Reorder
- ptmd_desc_type_node members.
- * tinfo2.cc (__pointer_to_member_type_info::__is_pointer_p):
- Implement.
- (__pointer_type_info::__do_catch): Move specific code into
- __pointer_catch. Call it.
- (__pointer_type_info::__pointer_catch): Non-pointer-to-member
- specific catch checking. Fix void conversion check.
- (__pointer_to_member_type_info::__do_catch): Remove.
- (__pointer_to_member_type_info::__pointer_catch): Implement.
-
-2000-04-10 Martin v. Löwis <loewis@informatik.hu-berlin.de>
-
- * lex.c (init_parse): Remove traces of classof and headof.
- * decl2.c (flag_operator_names): Default to 1.
- (lang_decode_option): Do not set it for -ansi.
-
-2000-04-09 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (struct lang_decl): Remove main_decl_variant.
- (DECL_MAIN_VARIANT): Remove.
- * decl.c (duplicate_decls): Don't set it.
- (start_function): Likewise.
- (lang_mark_tree): Don't mark it.
- * decl2.c (defer_fn): Don't use it.
- * lex.c (retrofit_lang_decl): Don't set it.
- * pt.c (tsubst_decl): Likewise.
- * ptree.c (print_lang_decl): Don't print it.
- * typeck.c (mark_addressable): Don't use it.
-
-2000-04-09 Nathan Sidwell <nathan@codesourcery.com>
-
- * vec.cc: Include <new> and <exception>.
- (__cxa_vec_ctor): Use __cxa_vec_dtor for cleanup.
- (__cxa_vec_dtor): Catch dtor exceptions, and rethrow or
- terminate.
- (__cxa_vec_delete): Catch dtor exceptions.
-
-2000-04-09 Nathan Sidwell <nathan@codesourcery.com>
-
- Prepend __ to implementation defined names.
- * inc/typeinfo (type_info): Rename _name to __name.
- (type_info::type_info): Rename parameter.
- (type_info::operator==, type_info::operator!=,
- type_info::before): Likewise.
- (type_info::is_pointer_p, type_info::is_function_p,
- type_info::do_catch, type_info::do_upcast): Prepend __. Rename
- parameters.
- * inc/cxxabi.h
- (__fundamental_type_info::__fundamental_type_info) Rename parameters.
- (__pointer_type_info::__pointer_type_info): Likewise.
- (__pointer_type_info::is_pointer_p,
- __pointer_type_info::do_catch): Prepend __. Rename parameters.
- (__array_type_info::__array_type_info): Rename parameters.
- (__function_type_info::__function_type_info): Likewise.
- (__function_type_info::is_function_p): Prepend __.
- (__enum_type_info::__enum_type_info): Rename parameters.
- (__pointer_to_member_type_info::__pointer_to_member_type_info):
- Likewise.
- (__pointer_to_member_type_info::do_catch): Prepend __. Rename
- parameters.
- (__base_class_info::is_virtual_p, is_public_p, offset): Prepend __.
- (__class_type_info::__class_type_info): Rename parameters.
- (__class_type_info::sub_kind): Prepend __. Adjust member names.
- (__class_type_info::upcast_result,
- __class_type_info::dyncast_result): Prepend __. Move definition
- into tinfo.cc.
- (__class_type_info::do_upcast, __class_type_info::do_catch,
- __class_type_info::find_public_src,
- __class_type_info::do_dyncast,
- __class_type_info::do_find_public_src): Prepend __. Rename
- parameters.
- (__si_class_type_info::__si_class_type_info): Rename parameters.
- (__si_class_type_info::do_upcast, __si_class_type_info::do_dyncast,
- __si_class_type_info::do_find_public_src): Prepent __. Rename
- parameters.
- (__vmi_class_type_info::__vmi_class_type_info): Rename parameters.
- (__vmi_class_type_info::do_upcast, __vmi_class_type_info::do_dyncast,
- __vmi_class_type_info::do_find_public_src): Prepent __. Rename
- parameters.
- (__dynamic_cast): Rename parameters.
- * tinfo.cc (type_info::is_pointer_p, type_info::is_function_p,
- type_info::do_catch, type_info::do_upcast): Prepend __.
- (contained_p, public_p, virtual_p, contained_public_p,
- contained_nonpublic_p, contained_nonvirtual_p): Adjust.
- (__class_type_info::do_catch,
- __class_type_info::do_upcast): Prepend __. Adjust.
- (__class_type_info::__upcast_result,
- __class_type_info::__dyncast_result): Move from inc/cxxabi.h.
- Adjust.
- (__class_type_info::find_public_src): Prepend __. Adjust.
- (__class_type_info::do_find_public_src,
- __si_class_type_info::do_find_public_src,
- __vmi_class_type_info::do_find_public_src): Likewise.
- (__class_type_info::do_dyncast,
- __si_class_type_info::do_dyncast,
- __vmi_class_type_info::do_dyncast): Likewise.
- (__class_type_info::do_upcast,
- __si_class_type_info::do_upcast,
- __vmi_class_type_info::do_upcast): Likewise.
- (__dynamic_cast): Adjust.
- * tinfo2.cc (__pointer_type_info::is_pointer_p): Prepend __.
- (__function_type_info::is_function_p): Likewise.
- (__pointer_type_info::do_catch): Likewise. Adjust.
- (__pointer_to_member_type_info::do_catch): Likewise. Adjust.
- (__throw_type_match_rtti_2): Adjust.
- (__is_pointer): Adjust.
-
-2000-04-08 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (cp_tree_index): Add CPTI_COMPLETE_CTOR_IDENTIFIER.
- (complete_ctor_identifier): New macro.
- (special_function_kind): Add sfk_copy_constructor and
- sfk_assignment_operator.
- (LOOKUP_HAS_IN_CHARGE): Remove.
- (cons_up_default_function): Rename to ...
- (implicitly_declare_fn): ... this.
- * call.c (build_new_method_call): Add in-charge parameters for
- constructors here.
- * class.c (add_implicitly_declared_members): Change parameter name
- from cant_have_assignment to cant_have_const_assignment.
- Replace calls to cons_up_default_function to implicitly_declare_fn.
- * cvt.c (ocp_convert): Use complete_ctor_identifier.
- * decl.c (initialize_predefined_identifiers): Initialize it.
- (start_function): Use DECL_CONSTRUCTOR_FOR_VBASE_P instead of
- complex expression.
- * init.c (expand_default_init): Don't calculate the in-charge
- parameter here.
- (build_new_1): Likewise.
- * lex.c (cons_up_default_function): Move to method.c.
- * method.c (synthesize_method): Use DECL_DESTRUCTOR_P.
- (implicitly_declare_fn): New function.
- * typeck.c (build_static_cast): Use complete_ctor_identifier.
- (build_modify_expr): Likewise.
- * typeck2.c (build_functional_cast): Likewise.
-
- Under the new ABI, constructors don't return `this'.
- * cp-tree.h (warn_reorder): Declare.
- (special_function_kind): New enum.
- (global_base_init_list): Remove declaration.
- (emit_base_init): Don't return a value.
- (check_base_init): Don't declare.
- (is_aggr_typedef): Likewise.
- * decl.c (check_special_function_return_type): New function.
- (return_types): Remove.
- (grokdeclarator): Use check_special_function_return_type.
- (start_function): Don't initialize ctor_label under the new ABI.
- (finish_construtor_body): Don't create a corresponding LABEL_STMT.
- * init.c (begin_init_stmts): Move to top of file.
- (finish_init_stmts): Likewise.
- (warn_reorder): Don't declare.
- (emit_base_init): Don't create a STMT_EXPR here. Don't return a
- value.
- (check_base_init): Remove.
- (is_aggr_typedef): Likewise.
- (build_new_1): Don't use the return value of a constructor.
- * semantics.c (setup_vtbl_ptr): Don't use the return value
- of emit_base_init.
- * typeck.c (check_return_expr): Don't magically convert return
- statements into `return this' in constructors under the new ABI.
-
- * cp-tree.h (cp_tree_index): Add CPTI_BASE_CTOR_IDENTIFIER,
- CPTI_BASE_DTOR_IDENTIFIER, and CPTI_DELETING_DTOR_IDENTIFIER.
- (base_ctor_identifier): New macro.
- (base_dtor_identifier): Likewise.
- (deleting_dtor_identifier): Likewise.
- * decl.c: Don't include obstack.h.
- (obstack_chunk_alloc): Don't define.
- (obstack_chunk_free): Likewise.
- (struct predefined_identifier): New type.
- (initialize_predefined_identifiers): New function.
- (init_decl_processing): Use it.
- (debug_temp_inits): Remove.
- (start_method): Don't call preserve_data.
- (hack_incomplete_structures): Update comment.
- * init.c (init_init_processing): Don't initialize
- nelts_identifier.
- (build_offset_rf): Remove dead code.
- (build_delete): Use CLASSTYPE_N_BASECLASSES.
- * search.c (init_search_processing): Don't initialize
- vptr_identifier.
-
-2000-04-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * typeck.c (build_binary_op): Call `tree_expr_nonnegative_p' to elide
- some sign_compare warnings.
-
-2000-04-07 Nathan Sidwell <nathan@codesourcery.com>
-
- Rename abi::__vmi_class_type_info members.
- * inc/cxxabi.h (__vmi_class_type_info): Rename details, n_bases,
- base_list, detail_masks members to vmi_flags, vmi_base_count,
- vmi_bases and vmi_flags_masks respectively.
- (__vmi_class_type_info::vmi_flags_masks): Rename
- details_unknown_mask to flags_unknown_mask.
- * tinfo.cc (__class_type_info::do_upcast): Adjust.
- (__vmi_class_type_info::do_find_public_src): Adjust.
- (__vmi_class_type_info::do_dyncast): Adjust.
- (__vmi_class_type_info::do_upcast): Adjust.
-
-2000-04-07 Nathan Sidwell <nathan@codesourcery.com>
-
- * tinfo.cc (convert_to_base): New function.
- (get_vbase_offset): Remove. Move into convert_to_base.
- (__vmi_class_type_info::do_find_public_src): Adjust.
- (__vmi_class_type_info::do_dyncast): Adjust.
- (__vmi_class_type_info::do_upcast): Adjust.
-
-2000-04-06 Jason Merrill <jason@yorick.cygnus.com>
-
- * tinfo.cc (operator=): Use __builtin_strcmp.
- * tinfo2.cc (before): Likewise.
-
-2000-04-06 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (lang_decl_flags): Rename saved_inline to deferred.
- (DECL_SAVED_INLINE): Rename to ...
- (DECL_DEFERRED_FN): ... this.
- (in_function_p): Remove declaration.
- (mark_inline_for_output): Rename to ...
- (defer_fn): ... this.
- * decl.c (finish_function): Adjust call to mark_inline_for_output.
- (in_function_p): Remove definition.
- * decl2.c (saved_inlines): Rename to ...
- (deferred_fns): ... this.
- (saved_inlines_used): Rename to ...
- (deferred_fns_used): ... this.
- (mark_inline_for_output): Rename to ...
- (defer_fn): ... this.
- (finish_file): Adjust accordingly.
- (init_decl2): Likewise.
- * lex.c (cons_up_default_function): Likewise.
- * pt.c (mark_decl_instantiated): Likewise.
- (instantiate_decl): Don't set DECL_DEFER_OUTPUT under any
- circumstances.
- * rtti.c (get_tinfo_decl): Adjust call to mark_inline_for_output.
- * semantics.c (expand_body): Defer more functions.
-
-2000-04-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * vec.cc: New file.
- * Make-lang.in (CXX_LIB2FUNCS): Add it.
- (vec.o): Build it.
- * inc/cxxabi.h (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
- __cxa_vec_delete): Declare.
-
-2000-04-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * rtti.c (dfs_class_hint_mark): New static function.
- (dfs_class_hint_unmark): New static function.
- (class_hint_flags): Use them.
-
-2000-04-05 Benjamin Kosnik <bkoz@cygnus.com>
-
- * decl2.c: Make flag_honor_std dependent on ENABLE_STD_NAMESPACE.
-
-2000-04-05 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (instantiate_decl): Change prototype.
- * decl2.c (mark_used): Adjust call.
- * optimize.c (inlinable_function_p): Adjust handling of templates.
- * pt.c (do_decl_instantiation): Adjust call to instantiate_decl.
- (do_type_instantiation): Likewise.
- (instantiate_decl): Defer more templates.
- (instantiate_pending_templates): Adjust logic to handle inline
- friend functions.
-
- * Makefile.in (GGC_H): New variable. Use it throughout in place
- of ggc.h.
-
- * call.c: Don't include obstack.h. Include ggc.h.
- (obstack_chunk_alloc): Don't define.
- (obstack_chunk_free): Likewise.
- (add_candidate): Allocate the z_candidate with ggc_alloc_obj.
- * decl.c (push_switch): Use xmalloc to allocate the cp_switch.
- (pop_switch): Free it.
-
- * decl2.c (grokclassfn): Set TREE_READONLY for PARM_DECLs.
-
- * dump.c (dequeue_and_dump): Don't try to print the bit_position
- if we don't have a DECL_FIELD_OFFSET.
-
-Wed Apr 5 15:12:18 MET DST 2000 Jan Hubicka <jh@suse.cz>
-
- * optimize.c (calls_setjmp_r): Use setjmp_call_p instead of
- special_function_p.
-
-2000-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * cfns.gperf (hash, libc_name_p): Prototype.
-
- * rtti.c (build_dynamic_cast_1): Constification.
-
- * search.c (dfs_debug_unmarkedp, dfs_debug_mark): Unhide prototypes.
-
- * semantics.c (deferred_type_access_control): Prototype.
-
-2000-04-04 Mark Mitchell <mark@codesourcery.com>
-
- Correct many new ABI issues regarding vbase and vcall offset
- layout.
- * cp-tree.h (BINFO_VTABLE): Document.
- (struct lang_type): Tweak formatting.
- (BINFO_PRIMARY_BINFO): Add to documentation.
- (CLASSTYPE_VSIZE): Fix typo in comment.
- (CLASSTYPE_VBASECLASSES): Update documentation.
- (BINFO_VBASE_MARKED): Remove.
- (SET_BINFO_VBASE_MARKED): Likewise.
- (CLEAR_BINFO_VBASE_MARKED): Likewise.
- (BINFO_FIELDS_MARKED): Remove.
- (SET_BINFO_FIELDS_MARKED): Likewise.
- (CLEAR_BINFO_FIELDS_MARKED): Likewise.
- (enum access_kind): New enumeration.
- (num_extra_vtbl_entries): Remove declaration.
- (size_extra_vtbl_entries): Likewise.
- (get_vtbl_decl_for_binfo): New function.
- (dfs_vbase_unmark): Remove declaration.
- (mark_primary_bases): Likewise.
- * class.c (SAME_FN): Remove.
- (struct vcall_offset_data_s): Move definition.
- (build_vbase_pointer): Use `build', not `build_binary_op', to
- access the vbase pointer under the new ABI.
- (build_vtable_entry_ref): Use get_vtbl_decl_for_binfo.
- (build_primary_vtable): Likewise.
- (dfs_mark_primary_bases): Move here from search.c.
- (mark_primary_bases): Likewise.
- (determine_primary_bases): Under the new ABI, don't make a base
- class a primary base just because we don't yet have any virtual
- functions.
- (layout_vtable_decl): Use get_vtbl_decl_for_binfo.
- (num_vfun_entries): Remove.
- (dfs_count_virtuals): Likewise.
- (num_extra_vtbl_entries): Likewise.
- (size_extra_vtbl_entries): Likewise.
- (layout_virtual_bases): Iterate in inheritance graph order under
- the new ABI.
- (finish_struct_1): Use TYPE_VFIELD, not CLASSTYPE_VSIZE, to
- indicate that a vfield is present.
- (init_class_processing): Initialize access_public_node, etc., from
- ak_public, etc.
- (get_vtbl_decl_for_binfo): New function.
- (dump_class_hierarchy_r): Likewise.
- (dump_class_hierarchy): Use it.
- (finish_vtbls): Build the vtbls in inheritance graph order.
- (dfs_finish_vtbls): Adjust call to build_vtbl_initializer.
- (initialize_vtable): Use get_vtbl_decl_for_binfo.
- (accumulate_vtbl_inits): Add comments explaining why a pre-order
- walk is required.
- (dfs_accumulate_vtbl_inits): Set BINFO_VTABLE to the location
- where the vptr points, even for primary vtables.
- (build_vtbl_initializer): Adjust handling of vbase and vcall
- offsets.
- (build_vcall_and_vbase_vtable_entries): New function.
- (dfs_build_vbase_offset_vtbl_entries): Remove.
- (build_vbase_offset_vtbl_entries): Reimplement.
- (dfs_build_vcall_offset_vtbl_entries): Don't include virtuals that
- were already handled in a primary base class vtable.
- (build_vcall_offset_vtbl_entries): Adjust.
- (build_rtti_vtbl_entries): Adjust.
- * decl2.c (output_vtable_inherit): Use get_vtbl_decl_for_binfo.
- * init.c (expand_virtual_init): Simplify.
- * repo.c (repo_get_id): Use get_vtbl_decl_for_binfo.
- * rtti.c (create_pseudo_type_info): Adjust calculation of vptr.
- * search.c (BINFO_ACCESS): New macro.
- (SET_BINFO_ACCESS): Likewise.
- (dfs_access_in_type): Manipulate access_kinds, not access nodes.
- (access_in_type): Likewise.
- (dfs_accessible_p): Likewise.
- (protected_accessible_p): Likewise.
- (lookup_fnfields_1): Adjust documentation.
- (dfs_mark_primary_bases): Move to class.c
- (mark_primary_bases): Likewise.
- (dfs_vbase_unmark): Remove.
- (virtual_context): Use BINFO_FOR_VBASE.
- (dfs_get_vbase_types): Simplify.
- (dfs_build_inheritance_graph_order): New function.
- (get_vbase_types): Use it.
- * tree.c (debug_binfo): Use get_vtbl_decl_for_binfo.
-
- * tinfo.cc (get_vbase_offset): New function.
- (__vmi_class_type_info::do_find_public_src): Use it.
- (__vmi_class_type_info::do_dyncast): Likewise.
- (__vmi_class_type_info::do_upcast): Likewise.
-
-2000-04-03 Zack Weinberg <zack@wolery.cumb.org>
-
- * lang-specs.h: Pass -fno-show-column to the preprocessor.
-
-2000-03-30 Nathan Sidwell <nathan@codesourcery.com>
-
- * rtti.c (class_hint_flags): Rename flags.
- (class_initializer): Remove flags.
- (synthesize_tinfo_var): Combine offset and flags. Add flags
- for __vmi_class_type_info.
- (create_tinfo_types): Remove flags from __class_type_info and
- __si_class_type_info. Merge flags and offset from
- base_class_type_info.
- * inc/cxxabi.h (__base_class_info): Merge offset and vmi_flags.
- (__base_class_info::is_virtual_p): Adjust.
- (__base_class_info::is_public_p): Adjust.
- (__base_class_info::offset): New accessor.
- (__class_type_info::details): Remove member.
- (__class_type_info::__class_type_info): Lose details.
- (__class_type_info::detail_masks): Remove.
- (__si_class_type_info::__si_class_type_info): Lose details.
- (__vmi_class_type_info::details): New member.
- (__vmi_class_type_info::__vmi_class_type_info): Adjust.
- (__vmi_class_type_info::detail_masks): New member.
- * tinfo.cc (__class_type_info::do_upcast): Initialize result
- with unknown_details_mask.
- (__vmi_class_type_info::do_find_public_src): Adjust
- (__vmi_class_type_info::do_dyncast): Adjust.
- (__vmi_class_type_info::do_upcast): Set result details, if
- needed. Adjust.
- (__dynamic_cast): Temporarily #if out optimization.
-
-2000-03-29 Nathan Sidwell <nathan@codesourcery.com>
-
- * rtti.c (get_tinfo_decl): Mark used.
- (emit_tinfo_decl): Don't optimize polymorphic type_info. Only
- mark as dealt with, if we output it.
-
-2000-03-28 Mark Mitchell <mark@codesourcery.com>
-
- * class.c: Reorganize to put virtual function table initialization
- machinery at the end of the file.
-
-2000-03-28 Jason Merrill <jason@casey.cygnus.com>
-
- * class.c (finish_struct): Use bitsize_zero_node.
- * pt.c (instantiate_class_template): Likewise.
-
-2000-03-28 Mark Mitchell <mark@codesourcery.com>
-
- Put RTTI entries at negative offsets in new ABI.
- * class.c (dfs_build_vbase_offset_vtbl_entries): Put the first
- vbase offset at index -3, not -1.
- (build_vtabe_offset_vtbl_entries): Use unmarked_vtable_pathp, not
- dfs_vtable_path_unmarked_real_bases_queue_p to walk bases.
- (dfs_build_vcall_offset_vtbl_entries): Don't use skip_rtti_stuff.
- (build_rtti_vtbl_entries): New function.
- (set_rtti_entry): Remove.
- (build_primary_vtable): Don't use it.
- (build_secondary_vtable): Likewise.
- (start_vtable): Remove.
- (first_vfun_index): New function.
- (set_vindex): Likewise.
- (add_virtual_function): Don't call start_vtable. Do call
- set_vindex.
- (set_primary_base): Rename parameter.
- (determine_primary_base): Likewise.
- (num_vfun_entries): Don't use skip_rtti_stuff.
- (num_extra_vtbl_entries): Include RTTI information.
- (build_vtbl_initializer): Use build_rtti_vtbl_entries.
- (skip_rtti_stuff): Remove.
- (dfs_modify_vtables): Don't use it.
- (modify_all_vtables): Don't use start_vtable. Do use set_vindex.
- (layout_nonempty_base_or_field): Update size handling.
- (create_vtable_ptr): Tweak.
- (layout_class_type): Adjust parameter names.
- (finish_struct_1): Simplify.
- * cp-tree.h (CLASSTYPE_VSIZE): Tweak documentation.
- (skip_rtti_stuff): Remove.
- (first_vfun_index): New function.
- (dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
- (dfs_vtable_path_marked_real_bases_queue_p): Remove.
- (marked_vtable_pathp): Declare.
- (unmarked_vtable_pathp): Likewise.
- * error.c (dump_expr): Use first_vfun_index to calculate vtable
- offsets.
- * rtti.c (build_headof): Look for RTTI at negative offsets.
- (get_tinfo_decl_dynamic): Likewise.
- (tinfo_base_init): Don't take the address of the TINFO_VTABLE_DECL
- here.
- (create_pseudo_type_info): Do it here instead. Adjust so that
- vptr points at first virtual function.
- * search.c (marked_vtable_pathp): Make it global.
- (unmarked_vtable_pathp): Likewise.
- (dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
- (dfs_vtable_path_marked_real_bases_queue_p): Likewise.
- (dfs_get_pure_virtuals): Don't use skip_rtti_stuff.
- (get_pure_virtuals): Likewise.
- (expand_upcast_fixups): Likewise.
- * tree.c (debug_binfo): Likewise.
- * tinfo.cc (__dynamic_cast): Look for vtable_prefix at appropriate
- negative offset.
-
-Sun Mar 26 20:15:26 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * class.c (check_field_decl): Fix typo.
- (build_vtbl_or_vbase_field): Don't clear DECL_SAVED_INSNS.
- (check_methods): Likewise.
- (check_field_decls): Likewise.
- Use DECL_CONTEXT, not DECL_FIELD_CONTEXT.
- * cp-tree.h (DECL_SHADOWED_FOR_VAR, DECL_TEMPLATE_RESULT):
- Use DECL_RESULT_FLD, not DECL_RESULT.
- * decl.c (xref_tag): Use DECL_TEMPLATE_RESULT.
- * lex.c (identifier_type): Likewise.
- * pt.c (determine_specialization, lookup_template_class): Likewise.
- (tsubst_friend_function, tsubst_decl, instantiate_template): Likewise.
- (resolve_overloaded_unification, more_specialized): Likewise.
- * semantics.c (finish_member_declaration): Likewise.
- * typeck.c (build_x_function_call): Likewise.
-
-2000-03-26 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (layout_empty_base): Handle empty bases with non-byte
- alignment.
- (build_base_field): Likewise.
- (layout_virtual_bases): Likewise.
-
- * class.c (finish_struct_1): Fix typo in this change:
-
- Sat Mar 25 09:12:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
-2000-03-25 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (grokdeclarator): Count partial specializations when
- keeping track of how many template classes have been seen.
-
- * dump.c (dequeue_and_dump): Dump DECL_TEMPLATE_RESULT.
-
-Sat Mar 25 09:12:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * class.c (build_vbase_pointer_fields): layout_field now place_field.
- (get_vfield_offset): Use byte_position.
- (set_rtti_entry): Set OFFSET to ssizetype zero.
- (get_binfo_offset_as_int): Deleted.
- (dfs_record_base_offsets): Use tree_low_cst.
- (dfs_search_base_offsets): Likewise.
- (layout_nonempty_base_or_field): Reflect changes in RLI format
- and call byte_position.
- (layout_empty_base): Convert offset to ssizetype.
- (build_base_field): use rli_size_unit_so_far.
- (dfs_propagate_binfo_offsets): Do computation in proper type.
- (layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
- (layout_class_type): Reflect changes in RLI names and fields.
- (finish_struct_1): Set DECL_FIELD_OFFSET.
- * dump.c (dequeue_and_dump): Call bit_position.
- * expr.c (cplus_expand_constant): Use byte_position.
- * rtti.c (expand_class_desc): Use bitsize_one_node.
- * typeck.c (build_component_addr): Use byte_position and don't
- special case for zero offset.
-
-2000-03-24 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (vtype_decl_p): Use TYPE_POLYMORPHIC_P.
-
- * rtti.c (get_tinfo_decl): Set comdat linkage on new-abi
- tinfo object.
- (emit_tinfo_decl): Only emit polymorphic tinfo's when emitting
- vtable.
-
-2000-03-20 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
-
- * call.c (check_dtor_name, build_new_method_call): Use TYPE_P and
- DECL_P macros.
- * decl.c (push_class_binding, poplevel, pushtag, lookup_namespace_name,
- make_typename_type, check_initializer, cp_finish_decl,
- xref_tag): Likewise.
- * decl2.c (grokfield, build_expr_from_tree, build_expr_from_tree,
- decl_namespace, arg_assoc_template_arg, arg_assoc,
- validate_nonmember_using_decl, do_class_using_decl): Likewise.
- * error.c (dump_template_argument, dump_expr, cp_file_of, cp_line_of,
- args_to_string): Likewise.
- * friend.c (is_friend): Likewise.
- * lex.c (note_got_semicolon, note_list_got_semicolon,
- is_global): Likewise.
- * method.c (build_overload_nested_name, build_overload_value,
- build_qualified_name, build_qualified_name, hack_identifier): Likewise.
- * parse.y (typename_sub, typename_sub1): Likewise.
- * pt.c (push_inline_template_parms_recursive, check_template_shadow,
- process_partial_specialization, convert_template_argument,
- template_args_equal, add_pending_template, lookup_template_class,
- for_each_template_parm_r, maybe_fold_nontype_arg,
- tsubst, instantiate_template, type_unification_real, unify,
- instantiate_pending_templates, set_mangled_name_for_template_decl):
- Likewise.
- * repo.c (repo_get_id, repo_template_used): Likewise.
- * search.c (lookup_field_1): Likewise.
- * tree.c (walk_tree, get_type_decl, cp_tree_equal, member_p): Likewise.
- * xref.c (classname): Likewise.
-
-2000-03-22 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (BINFO_FOR_VBASE): Adjust documentation.
- (CANONICAL_BINFO): New macro.
- (BINFO_NEW_VTABLE_MARKED): Use it.
- (SET_BINFO_NEW_VTABLE_MARKED): Likewise.
- (CLEAR_BINFO_NEW_VTABLE_MARKED): Likewise.
- * class.c (dfs_build_vbase_offset_vtbl_entries): Use BINFO_TYPE,
- not TREE_TYPE.
- (build_primary_vtable): Adjust usage of BINFO_NEW_VTABLE_MARKED.
- (build_secondary_vtable): Likewise.
- (dfs_finish_vtbls): Likewise.
- (dfs_accumulate_vtbl_inits): Likewise.
- (accumulate_vtbl_inits): New function.
- (finish_vtbls): Make sure that virtual bases come after
- non-virtual bases in the vtable group.
- (record_base_offsets): Don't save and restore TREE_VIA_VIRTUAL.
- (finish_struct_1): Adjust usage of BINFO_NEW_VTABLE_MARKED.
- * search.c (struct vbase_info): Move definition.
- (marked_new_vtable_p): Adjust usage of BINFO_NEW_VTABLE_MARKED.
- (unmarked_new_vtable_p): Likewise.
- (dfs_mark_vtable_path): Remove.
- (dfs_mark_new_vtable): Remove.
- (dfs_unmark_new_vtable): Likewise.
- (dfs_clear_search_slot): Likewise.
- (dfs_find_vbases): Adjust usage of BINFO_NEW_VTABLE_MARKED.
- (dfs_clear_vbase_slots): Likewise.
- (init_vbase_pointers): LIkewise.
-
-2000-03-22 Jason Merrill <jason@casey.cygnus.com>
-
- * typeck.c (type_after_usual_arithmetic_conversions): Prefer a
- SIZETYPE to a non-SIZETYPE.
-
-2000-03-21 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (layout_virtual_bases): Adjust names in conditionally
- compiled code.
-
- * class.c (record_base_offsets): New function.
- (layout_conflict_p): Likewise.
- (layout_nonempty_base_or_field): Use it.
- (layout_empty_base): New function.
- (build_base_field): Use it.
- (build_base_fields): Update comment.
- (layout_virtual_bases): Fold in a little code form
- layout_basetypes. Use layout_empty_base.
- (layout_basetypes): Remove.
- (end_of_class): New function.
- (layout_class_type): Use it. Adjust.
-
- * cp-tree.h (CLASSTYPE_VBASECLASSES): Fix typo in comment.
- (fntype_p): Remove.
- * search.c (dfs_skip_nonprimary_vbases_unmarkedp): Fix typo in
- comment.
- (dfs_skip_nonprimary_vbases_markedp): Likewise.
- * typeck.c (fntype_p): Remove.
-
- * cp-tree.h (TI_SPEC_INFO): Remove.
- (CLASSTYPE_TI_SPEC_INFO): Likewise.
- * pt.c (process_partial_specialization): Likewise.
-
- * class.c (build_base_field): Fix thinko in computation of binfo
- offsets.
-
- * tree.c (mark_local_for_remap_p): Mark variables declared in
- TARGET_EXPRs as well.
-
-2000-03-21 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck.c (require_complete_type, complete_type,
- complete_type_or_else, c_sizeof, c_sizeof_nowarn,
- build_array_ref, convert_arguments, pointer_diff,
- build_x_unary_op, build_unary_op, build_c_cast,
- build_modify_expr): Use COMPLETE_TYPE_P etc.
- * call.c (is_complete, convert_like_real,
- build_new_method_call): Likewise.
- * class.c (build_vbase_pointer_fields, check_bases,
- build_base_field, finish_struct_1, pushclass): Likewise.
- * cvt.c (cp_convert_to_pointer, convert_to_void): Likewise.
- * decl.c (maybe_process_template_type_declaration, pushtag,
- pushdecl, redeclaration_error_message, start_decl, start_decl_1,
- layout_var_decl, check_initializer, cp_finish_decl,
- grokdeclarator, require_complete_types_for_parms,
- grok_op_properties, xref_tag, xref_basetypes,
- check_function_type): Likewise.
- * decl2.c (check_classfn, reparse_absdcl_as_casts): Likewise.
- * friend.c (do_friend): Likewise.
- * init.c (build_offset_ref): Likewise.
- * parse.y (structsp): Likewise.
- * pt.c (maybe_process_partial_specialization,
- tsubst_friend_function, instantiate_class_template, tsubst,
- do_type_instantiation, instantiate_pending_templates): Likewise.
- * repo.c (repo_get_id): Likewise.
- * rtti.c (build_typeid, get_typeid, build_dynamic_cast_1,
- synthesize_tinfo_var, emit_support_tinfos): Likewise.
- * search.c (lookup_fnfields_1, lookup_conversions): Likewise.
- * semantics.c (begin_class_definition): Likewise.
- * tree.c (build_cplus_method_type): Likewise.
- * typeck2.c (digest_init, build_functional_cast,
- add_exception_specifier): Likewise.
- * parse.h, parse.c: Regenerated.
-
-2000-03-21 Nathan Sidwell <nathan@codesourcery.com>
-
- * inc/cxxabi.h: New header file. Define new-abi entry points.
- (__pointer_type_info::target): Rename member to ...
- (__pointer_type_info::type): ... here.
- (__base_class_info::type): Rename member to ...
- (__base_class_info::base): ... here.
- * Make-lang.in (CXX_EXTRA_HEADERS): Add cxxabi.h
- * cp-tree.h (CPTI_ABI): New global tree enumeration.
- (abi_node): New global tree node.
- * decl.c (abi_node): Document.
- (init_decl_processing): Initialize abi_node.
- * rtti.c (build_dynamic_cast_1): Use abi_node for new-abi.
- (get_vmi_pseudo_type_info): Likewise.
- (create_tinfo_types): Likewise.
- (emit_support_tinfos): Likewise.
- * tinfo.h (cxxabi.h): Include for new-abi.
- Move rtti class definitions to new header file.
- * tinfo.cc (abi): Use the namespace.
- (std): Move new abi rtti classes from here ...
- (__cxxabiv1): ... to here.
- * tinfo2.cc (cxxabi.h): Include for new-abi.
- Move rtti class definitions to new header file.
- (std): Move new abi rtti classes from here ...
- (__cxxabiv1): ... to here.
- * inc/typeinfo (__class_type_info): Move into __cxxabiv1
- namespace.
-
-2000-03-20 Jed Wing <jedwin@zloty.ugcs.caltech.edu>
- Jason Merrill <jason@casey.cygnus.com>
-
- * method.c (build_overload_int): Use host_integerp.
-
-2000-03-20 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
-
- * init.c (build_offset_ref): Handle the case of a templated member
- function.
-
-2000-03-19 Martin v. Löwis <loewis@informatik.hu-berlin.de>
-
- * except.c (expand_exception_blocks): Clear catch_clauses_last.
-
-2000-03-18 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (CLEAR_DECL_C_BIT_FIELD): New macro.
- * class.c (check_bitfield_decl): Turn illegal bitfields into
- non-bitfields.
- (dfs_propagate_binfo_offsets): Adjust for new size_binop
- semantics.
- (dfs_offset_for_unshared_vbases): Likewise.
- * cvt.c (cp_convert_to_pointer): Convert NULL to a
- pointer-to-member correctly under the new ABI.
- * expr.c (cplus_expand_constant): Don't use cp_convert when
- turning an offset into a pointer-to-member.
- * init.c (resolve_offset_ref): Don't adjust pointers-to-members
- when dereferencing them under the new ABI.
- * typeck.c (get_member_function_from_ptrfunc): Tweak calculation
- of pointers-to-members under the new ABI.
-
- * class.c (check_bitfield_decl): Remove restriction on really long
- bitfields.
- (layout_class_type): Implement new ABI handling of bitfields
- longer than their types.
-
-2000-03-18 Martin v. Löwis <loewis@informatik.hu-berlin.de>
-
- * parse.y (extdefs): Call ggc_collect.
- * parse.c: Regenerated.
-
-2000-03-18 Nathan Sidwell <nathan@codesourcery.com>
-
- * class.c (build_base_field): Use TYPE_ALIGN to examine a type.
- (note_name_declared_in_class): Use OVL_CURRENT to get at a
- potential overload.
-
-Fri Mar 17 08:09:14 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * class.c (build_vbase_path): Use integer_zerop.
- (build_vtable_entry): Use tree_low_cst.
- (get_vfield_offset): Use bit_position.
- (dfs_modify_vtables): New variable vindex_val; `i' is HOST_WIDE_INT.
- Use tree_low_cst.
- (check_bitfield_decl): Set DECL_SIZE using convert.
- (build_base_field): Set DECL_SIZE and DECL_SIZE_UNIT using size_binop.
- (layout_virtual_bases): DSIZE is unsigned HOST_WIDE_INT.
- Use tree_low_cst.
- (finish_struct_1): Use bit_position.
- (dump_class_hierarchy): Use tree_low_cst.
- * cp-tree.h (min_precision): Add declaration.
- * decl.c (xref_tag, xref_basetypes): Use tree_low_cst.
- * error.c (dump_type_suffix): Use host_integerp and tree_low_cst.
- (dump_expr): Use integer_zerop, host_integerp, and tree_low_cst.
- * expr.c (cplus_expand_constant): Use bit_position.
- * init.c (build_vec_init): Use host_integerp and tree_low_cst.
- * rtti.c (get_base_offset): Use bit_position.
- * typeck.c (build_binary_op): Use integer_zerop, compare_tree_int,
- host_integerp, and tree_low_cst.
- (pointer_int_sum): Use integer_zerop.
- (build_component_addr): Use bit_position.
-
-2000-03-17 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck.c (require_complete_type): Don't assume size_zero_node.
- (complete_type_or_else): Likewise.
-
-2000-03-16 Steven Grady <grady@digitaldeck.com>
- Jason Merrill <jason@casey.cygnus.com>
-
- * rtti.c (build_dynamic_cast_1): Improve diagnostics.
-
-2000-03-16 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl2.c (grokfield): Bail out if type is error_mark_node.
-
-2000-03-15 Nathan Sidwell <nathan@codesourcery.com>
-
- * tinfo2.cc (__ptr_to_member_data): Rename to ...
- (__pointer_to_member_data): ... here. Adjust.
- * rtti.c (create_tinfo_types): Adjust.
-
-2000-03-15 Nathan Sidwell <nathan@codesourcery.com>
-
- * cp-tree.h (CPTI_REF_DESC_TYPE, ref_desc_type_node): Remove.
- * decl.c (ref_desc_type_node): Undocument.
- * rtti.c (ptr_ref_initializer): Rename to ...
- (ptr_initializer): ... here. Adjust comments.
- (ptmd_initializer): Fix comment thinko.
- (synthesize_tinfo_var): Remove REFERENCE_TYPE case.
- (create_tinfo_types): Remove ref_desc_type_node init.
- * tinfo2.cc (__reference_type_info): Remove.
-
-2000-03-15 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (cp_finish_decl): Remove obsolete comment.
-
- * typeck.c (build_ptrmemfunc1): Kill uninitialized warning.
-
-2000-03-14 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h: Tweak documentation.
- * class.c (build_vbase_pointer_fields): Layout the fields, too.
- (avoid_overlap): Remove.
- (get_binfo_offset_as_int): New function.
- (dfs_serach_base_offsets): Likewise.
- (layout_nonempty_base_or_field): Likewise.
- (build_base_field): Layout fields here. Avoid placing two objects
- of the same type at the same address, under the new ABI.
- (build_base_fields): Adjust accordingly.
- (create_vtable_ptr): Return the new field, but don't attach it to
- TYPE_FIELDS.
- (remove_base_field): Remove.
- (remove_base_fields): Remove.
- (layout_basetypes): Adjust accordingly.
- (layout_class_type): Call layout_field for each field, rather than
- just making a wholesale call to layout_type.
-
-2000-03-14 Jeff Sturm <jsturm@sigma6.com>
-
- * except.c (expand_throw): Fix typo in _Jv_Sjlj_Throw.
-
-2000-03-13 Jason Merrill <jason@casey.cygnus.com>
-
- * decl.c (grokfndecl): Set TREE_NOTHROW if TYPE_NOTHROW_P.
-
- * except.c (dtor_nothrow): New fn.
- (do_pop_exception): Use it. Take type parm.
- (push_eh_cleanup): Take type parm.
- (expand_start_catch_block): Pass it.
- (build_eh_type_type_ref): Accept null type.
-
-2000-03-12 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (revert_static_member_fn): Change prototype.
- * decl.c (grokfndecl): Adjust call to revert_static_member_fn.
- (grok_op_properties): Likewise.
- (start_function): Likewise.
- (revert_static_member_fn): Simplify.
- * pt.c (check_explicit_specialization): Adjust call to
- revert_static_member_fn.
-
-2000-03-11 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (scope_kind): New type.
- (tmpl_spec_kind): Likewise.
- (declare_pseudo_global_level): Remove.
- (pseudo_global_level_p): Rename to template_parm_scope_p.
- (pushlevel): Remove declaration.
- (begin_scope): New function.
- (finish_scope): Likewise.
- (current_tmpl_spec_kind): Likewise.
- * decl.c (struct binding_level): Shorten parm_flag to 2 bits.
- Shorten keep to 2 bits. Rename pseudo_global to template_parms_p.
- Add template_spec_p.
- (toplevel_bindings_p): Adjust.
- (declare_pseudo_global_level): Remove.
- (pseudo_global_level_p): Rename to template_parm_scope_p.
- (current_tmpl_spec_kind): New function.
- (begin_scope): Likewise.
- (finish_scope): Likewise.
- (maybe_push_to_top_level): Adjust.
- (maybe_process_template_type_declaration): Likewise.
- (pushtag): Likewise.
- (pushdecl_nonclass_level): Likewise.
- (lookup_tag): Likewise.
- (grokfndecl): Handle member template specializations. Share
- constructor and non-constructor code.
- * decl2.c (check_classfn): Handle member template specializations.
- * pt.c (begin_template_parm_list): Use begin_scope.
- (begin_specialization): Likewise.
- (end_specialization): Likewise.
- (check_explicit_specialization): Use current_tmpl_spec_kind.
- Handle member template specializations.
- (end_template_decl): Use finish_scope. Remove call to
- get_pending_sizes.
- (push_template_decl_real): Remove bogus error message.
- (tsubst_decl): Fix typo in code contained in comment.
- (instantiate_template): Handle member template specializations.
- (most_general_template): Likewise.
-
-2000-03-11 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * lex.c (whitespace_cr): Compress consecutive calls to warning().
- (do_identifier): Ditto for error().
-
- * pt.c (convert_nontype_argument): Ditto for cp_error().
- (convert_template_argument): Ditto for cp_pedwarn().
-
-2000-03-11 Jason Merrill <jason@casey.cygnus.com>
-
- * exception.cc (__check_null_eh_spec): New fn.
- * except.c (expand_end_eh_spec): Call it if the spec is throw().
-
-2000-03-10 Jason Merrill <jason@casey.cygnus.com>
-
- * decl.c (push_throw_library_fn): Take the FUNCTION_TYPE.
- * except.c (expand_end_eh_spec): Add the return type.
- * rtti.c (throw_bad_cast): Add the parmtypes.
- (throw_bad_typeid): Likewise.
-
- * semantics.c (expand_stmt): Only leave out rtl for unused
- artificials, and set DECL_IGNORED_P on them as well.
- * decl.c (wrapup_globals_for_namespace): Likewise.
-
-2000-03-09 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (maybe_commonize_var): Skip all artificial decls.
- * pt.c (tsubst_decl): Don't copy TREE_ASM_WRITTEN.
-
-2000-03-10 Jason Merrill <jason@casey.cygnus.com>
-
- * lang-options.h, decl2.c: Add -fno-enforce-eh-specs.
- * cp-tree.h: Declare flag_enforce_eh_specs.
- * decl.c (store_parm_decls, finish_function): Check it.
-
- C library functions don't throw.
- * Makefile.in (cfns.h): New target.
- (except.o): Depend on it.
- * Make-lang.in (cc1plus): Depend on cfns.gperf.
- * cfns.gperf: New file.
- * cfns.h: Generated.
- * except.c: Include it.
- (nothrow_libfn_p): New fn.
- * decl.c (grokfndecl): Use it.
- * cp-tree.h: Declare it.
-
- * decl.c (push_overloaded_decl_1, auto_function,
- define_function): Lose.
- (build_library_fn_1): New static fn.
- (builtin_function): Use it.
- (get_atexit_node): Use build_library_fn_ptr.
- (build_library_fn, build_cp_library_fn, build_library_fn_ptr,
- build_cp_library_fn_ptr, push_library_fn, push_cp_library_fn,
- push_void_library_fn, push_throw_library_fn): New fns.
- * cp-tree.h: Declare them.
- (cp_tree_index): Remove CPTI_BAD_CAST, CPTI_BAD_TYPEID.
- (throw_bad_cast_node, throw_bad_typeid_node): Lose.
- * except.c (init_exception_processing, call_eh_info, do_pop_exception,
- (expand_end_eh_spec, alloc_eh_object, expand_throw): Use above fns.
- * rtti.c (build_runtime_decl): Lose.
- (throw_bad_cast, throw_bad_typeid, get_tinfo_decl,
- build_dynamic_cast_1, expand_si_desc, expand_class_desc,
- expand_ptr_desc, expand_attr_desc, expand_generic_desc): Use above fns.
-
- * call.c (build_call): Remove result_type parm.
- Call mark_used on unused artificial fns.
- * init.c, method.c, typeck.c, except.c, rtti.c: Adjust.
-
-2000-03-09 Jason Merrill <jason@casey.cygnus.com>
-
- * call.c (build_call): Set TREE_NOTHROW on the CALL_EXPR as
- appropriate.
- * decl.c (define_function): Set TREE_NOTHROW on the FUNCTION_DECL.
- * except.c (call_eh_info, alloc_eh_object, expand_throw): Set
- TREE_NOTHROW or TREE_THIS_VOLATILE on the function as appropriate.
- * rtti.c (build_runtime_decl, get_tinfo_decl, build_dynamic_cast_1,
- expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc,
- expand_generic_desc): Likewise.
-
-2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * exception.cc (__cp_pop_exception): Cleanup the original object.
-
-2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (grok_op_properties): Merge conversion to void warning
- with other silly op warnings.
-
-2000-03-08 Jason Merrill <jason@casey.cygnus.com>
-
- * typeck2.c (process_init_constructor): Set TREE_PURPOSE of
- array CONSTRUCTOR elements. Don't use expr_tree_cons.
-
-2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (cp_make_fname_decl): New function.
- (wrapup_globals_for_namespace): Don't emit unused static vars.
- (init_decl_processing): Remove comment about use of
- array_domain_type. Set make_fname_decl.
- (cp_finish_decl): Remove __FUNCTION__ nadgering.
- * semantics.c (begin_compound_stmt): Remove
- current_function_name_declared flagging.
- (expand_stmt): Don't emit unused local statics.
- * typeck.c (decay_conversion): Don't treat __FUNCTION__ decls
- specially.
-
-2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck.c (convert_for_assignment): Don't look at array
- initializer.
- * call.c (convert_like_real): Likewise.
-
-2000-03-07 Jason Merrill <jason@casey.cygnus.com>
-
- Add initial support for '\uNNNN' specifier.
- * lex.c (read_ucs): New fn.
- (readescape, skip_white_space): Call it.
- (is_extended_char, is_extended_char_1): New fns.
- (utf8_extend_token): New fn, #if 0'd out.
- (real_yylex): Treat extended chars like letters.
-
- * search.c (note_debug_info_needed): Walk the bases even if we
- weren't deferring the type itself.
-
-2000-03-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * decl2.c (finish_objects): Constify a char*.
-
- * method.c (emit_thunk): Likewise.
-
-2000-03-06 Nathan Sidwell <nathan@codesourcery.com>
-
- * typeck.c (dubious_conversion_warnings): Look through
- REFERENCE_TYPE.
-
-Mon Mar 6 08:46:47 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * class.c (dfs_modify_vtables): I is now unsigned.
- (check_bitfield_decl): Use tree_int_cst_sgn and compare_tree_int.
- (build_base_field): Add casts of TREE_INT_CST_LOW to HOST_WIDE_INT.
- * error.c (dump_expr): Cast TREE_INT_CST_HIGH to unsigned.
- * init.c (build_vec_init): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
- * method.c (build_overload_int): Cast TREE_INT_CST_HIGH to unsigned.
- * typeck.c (build_binary_op, case TRUNC_DIV_EXPR):
- Call integer_all_onesp.
- * typeck2.c (process_init_constructor): Use compare_tree_int.
-
- * lang-specs.h (as): Don't call if -syntax-only.
-
-2000-03-06 Mark Mitchell <mark@codesourcery.com>
-
- * expr.c (cplus_expand_expr, case STMT_EXPR): Don't set
- RTL_EXPR_HAS_NO_SCOPE after all.
-
-2000-03-05 Mark Mitchell <mark@codesourcery.com>
-
- * expr.c (cplus_expand_expr, case STMT_EXPR): Use
- expand_start_stmt_expr and expand_end_stmt_expr directly. Set
- RTL_EXPR_HAS_NO_SCOPE.
-
- * pt.c (instantiate_decl): Clear TI_PENDING_TEMPLATE_FLAG a little
- later.
-
- * dump.c (dequeue_and_dump): Dump SCOPE_NO_CLEANUPS_P.
-
-2000-03-05 Nathan Sidwell <nathan@codesourcery.com>
-
- * call.c (convert_like): Macrofy.
- (convert_like_with_context): New macro.
- (convert_like_real): Renamed from convert_like. Add calling
- context parameters, for diagnostics. Add recursive flag. Call
- dubious_conversion_warnings for outer conversion.
- (build_user_type_conversion): Use convert_like_with_context.
- (build_over_call): Likewise. Don't warn about dubious
- conversions here. Adjust convert_default_arg calls.
- (convert_default_arg): Add context parameters for diagnostics.
- Pass through to convert_like_with_context.
- * cp-tree.h (convert_default_arg): Add context parameters.
- (dubious_conversion_warnings): Prototype new function.
- * typeck.c (convert_arguments): Adjust convert_default_arg call.
- (dubious_conversion_warnings): New function, broken
- out of convert_for_assignment.
- (convert_for_assignment): Adjust.
-
-2000-03-03 Jason Merrill <jason@casey.cygnus.com>
-
- * decl2.c (key_method): Break out from...
- (import_export_vtable, import_export_class): ...here.
-
- * decl.c (finish_function): Don't mess with flag_keep_inline_functions.
- * decl2.c (finish_vtable_vardecl): Don't check decl_function_context.
-
- * search.c (note_debug_info_needed, dfs_debug_mark,
- dfs_debug_unmarkedp): Uncomment. Adjust for new scheme.
- * decl2.c (finish_vtable_vardecl): Call note_debug_info_needed.
-
-2000-03-03 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (cp_finish_decl): Remove obsolete obstack comments, fix
- typos.
-
-2000-03-02 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (TYPE_NEEDS_DESTRUCTOR): Rename to ...
- (TYPE_HAS_NONTRIVIAL_DESTRUCTOR): ... this.
- (TYPE_HAS_TRIVIAL_DESTRUCTOR): New macro.
- (lang_type): Split gets_new into has_new and has_array_new.
- (TYPE_VEC_NEW_USES_COOKIE): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
- (TYPE_GETS_NEW): Split into ...
- (TYPE_HAS_NEW_OPERATOR): ... this, and ...
- (TYPE_HAS_ARRAY_NEW_OPERATOR): ... this.
- (DECL_ARRAY_DELETE_OPERATOR_P): New macro
- (build_op_new_call): Don't declare.
- (build_new_1): Likewise.
- * call.c (build_op_new_call): Remove.
- * class.c (check_bases): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR
- instead of TYPE_NEEDS_DESTRUCTOR.
- (finish_struct_bits): Likewise.
- (add_implicitly_declared_members): Likewise.
- (check_field_decl): Likewise.
- (check_methods): Set TYPE_VEC_DELETE_TAKES_SIZE here, and set it
- correctly under the new ABI.
- * decl.c (start_decl_1): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR
- instead of TYPE_NEEDS_DESTRUCTOR.
- (initialize_local_var): Likewise.
- (destroy_local_var): Likewise.
- (cp_finish_decl): Likewise.
- (register_dtor_fn): Likewise.
- (grok_op_properties): Set TYPE_HAS_NEW_OPERATOR and
- TYPE_HAS_ARRAY_NEW_OPERATOR, not TYPE_HAS_NEW. Don't set
- TYPE_VEC_DELETE_TAKES_SIZE here.
- (xref_basetypes): Set TYPE_HAS_NEW_OPERATOR and
- TYPE_HAS_ARRAY_NEW_OPERATOR, not TYPE_HAS_NEW.
- (store_parm_decls): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
- (finish_destructor_body): Likewise.
- (maybe_build_cleanup_1): Likewise.
- * decl2.c (do_static_destruction): Likewise.
- * init.c (build_new_1): Make it static.
- (perform_member_init): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
- (expand_cleanup_for_base): Likewise.
- (get_cookie_size): New function.
- (build_new_1): Handle array-new cookies correctly under the new
- ABI.
- (build_vec_delete_1): Likewise.
- (build_vec_init): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
- (build_delete): Likewise.
- (build_vec_delete): Handle array-new cookies correctly under the new
- ABI.
- * lex.c (do_identifier): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
- * pt.c (instantiate_class_template): Set TYPE_HAS_NEW_OPERATOR and
- TYPE_HAS_ARRAY_NEW_OPERATOR.
- * ptree.c (print_lang_type): Check them.
- * search.c (context_for_name_lookup): Fix typo in comment.
- (tree_has_any_destructor_p): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
- * tree.c (break_out_cleanups): Likewise.
- (build_cplus_array_test_1): Likewise.
- (cp_build_qualified_type_real): Likewise.
- * typeck.c (complete_type): Likewise.
-
- * g++spec.c (lang_specific_driver): Add -fnew-abi at the start of
- the command-line, not the end.
-
-2000-03-01 Jason Merrill <jason@casey.cygnus.com>
-
- * pt.c (instantiate_decl): Clear TI_PENDING_TEMPLATE_FLAG.
-
-2000-03-02 Tom Tromey <tromey@cygnus.com>
-
- * cp-tree.h (build_java_class_ref): Declare.
- * init.c (build_java_class_ref): No longer static.
- * except.c (expand_throw): Generate a Java-style `throw' if the
- thrown object is a "Java" object.
- (initialize_handler_parm): Generate a Java-style lookup of
- exception info if the caught object is a "Java" object.
- (catch_language, catch_language_init): New globals.
- (decl_is_java_type): New function.
- (expand_start_catch_block): Don't call push_eh_info() or
- push_eh_cleanup() when handling a Java-style "catch". Pass Java
- class reference to build_catch_block.
-
-Thu Mar 2 13:32:01 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * typeck.c (comptypes): Treat sizetype like its language equivalent.
-
-2000-03-01 Bernd Schmidt <bernds@cygnus.co.uk>
-
- * typeck.c (maybe_warn_about_returning_address_of_local): Reorganize
- to merge reference/pointer code and fix incorrect warnings.
-
-2000-02-29 Jason Merrill <jason@casey.cygnus.com>
-
- * search.c (protected_accessible_p): Use context_for_name_lookup.
-
- * init.c (construct_virtual_bases): Fix thinko.
- * typeck.c (expand_ptrmemfunc_cst): Fix thinko.
-
-2000-03-01 Martin von Loewis <loewis@informatik.hu-berlin.de>
-
- * decl.c (current_function_decl): Move to toplev.c.
-
-2000-02-29 Nathan Sidwell <nathan@codesourcery.com>
-
- * pt.c (fn_type_unification): Unify return type, whenever
- provided.
- (get_bindings_real): Only pass return type when necessary.
- Remove explicit return type check.
- * class.c (resolve_address_of_overloaded_function): Pass desired
- return type to fn_type_unification.
-
-Mon Feb 28 08:15:23 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * class.c (build_vtbl_or_vbase_field, check_methods): Don't clear
- DECL_FIELD_SIZE.
- (check_bitfield_decl, check_field_decls): Set DECL_SIZE, not
- DECL_FIELD_SIZE.
- * rtti.c (expand_class_desc): Likewise.
- * cp-tree.h (DECL_INIT_PRIORITY): Use underlying union name.
- (THUNK_VCALL_OFFSET): Likewise.
- (THUNK_DELTA): Reflect changes in ../tree.h.
-
-2000-02-28 Jason Merrill <jason@casey.cygnus.com>
-
- * search.c (protected_accessible_p): Also allow the access if
- the member is public in DERIVED. Lose TYPE parm.
- (friend_accessible_p): Lose TYPE parm.
- (accessible_p): Adjust.
-
-Sun Feb 27 16:40:33 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * class.c (dfs_build_vtable_offset_vtbl_entries): Don't use size_binop
- on things that are not sizes; ssize_binop deleted.
- Call size_diffop when appropriate.
- (dfs_build_vcall_offset_vtbl_entries): Likewise.
- (build_primary_vtable, build_secondary_vtable): Likewise.
- (dfs_set_offset_for_unshared_vbases, dfs_modify_vtables): Likewise.
- Variable I is HOST_WIDE_INT.
- (get_vfield_offset): Pass proper types to size_binop.
- (size_extra_vtbl_entries, layout_virtual_bases): Likewise.
- (finish_struct_1): Likewise.
- (skip_rtti_stuff): Arg N is now pointer to signed.
- (layout_class_type): Use size_zero_node.
- * cp-tree.h (skip_rtti_stuff): Arg N is pointer to signed.
- * cvt.c (cp_convert_to_pointer): Pass proper types to size_binop.
- * decl.c (complete_arry_type): Pass proper types to size_binop.
- (xref_basetypes): BINFO_OFFSET is sizetype.
- * error.c (dump_expr): Don't use size_binop non-sizes.
- * expr.c (cplus_expand_constant): Pass proper types to size_binop.
- * init.c (construct_virtual_bases): Fix type error.
- (build_vec_delete_1): Pass proper type to size_binop and don't
- fold result.
- * lex.c (cp_make_lang_type): BINFO_OFFSET is sizetype.
- * rtti.c (get_base_offset): Pass proper type to size_binop.
- * search.c (dfs_find_vbases): Fix type error.
- (expand_upcast_fixups): Arg to skip_rtti_stuff is pointer to signed.
- (dfs_get_vbase_types): BINFO_OFFSET is sizetype.
- * tree.c (debug_binfo): Variable N is signed.
- Use HOST_WIDE_INT_PRINT_DEC.
- * typeck.c (comptypes): sizetype is same as equivalent integer type.
- (c_sizeof, c_sizeof_nowarn, expr_sizeof): Use TYPE_SIZE_UNIT,
- size_one_node and size_zero_node.
- (c_alignof): Use size_one_node.
- (build_component_addr): Pass proper types to size_binop.
- (expand_ptrmemfunc_cst): Don't use size_binop on non-sizes.
-
-2000-02-26 Jason Merrill <jason@casey.cygnus.com>
-
- Implement class scope using-declarations for functions.
- * class.c (handle_using_decl): Call add_method for used functions.
- Use IDENTIFIER_CLASS_VALUE to check for conflicts.
- (add_method): Used functions are hidden by local functions.
- (check_bases_and_members): Handle using-decls before finalizing
- CLASSTYPE_METHOD_VEC.
- * call.c (add_function_candidate): Add ctype parm; if nonzero,
- override the type of 'this' accordingly.
- (add_template_candidate, add_template_candidate_real): Add ctype parm.
- (convert_class_to_reference, build_user_type_conversion_1,
- build_new_function_call, build_object_call, build_new_op,
- build_new_method_call): Pass ctype parm.
-
- * search.c (lookup_member): Put rval_binfo, not basetype_path, in
- the baselink.
- * call.c (convert_class_to_reference, build_user_type_conversion_1,
- build_new_function_call, build_object_call, build_new_op,
- build_new_method_call, build_op_delete_call): Don't get basetype_path
- from a baselink.
- * typeck.c (build_component_ref): Likewise.
- * init.c (build_offset_ref): Likewise.
- (resolve_offset_ref): Don't call enforce_access.
- Call build_scoped_ref.
- * typeck2.c (build_scoped_ref): Simplify. Do nothing if it
- would cause an error or if -pedantic.
- * class.c (alter_access): Lose binfo parm.
-
-2000-02-26 Mark Mitchell <mark@codesourcery.com>
-
- * semantics.c (simplify_aggr_init_exprs_p): Don't walk into
- types.
-
-2000-02-25 Alfred Minarik <a8601248@unet.univie.ac.at>
-
- * rtti.c (get_vmi_pseudo_type_info): Move __vmi_class_type_info
- pseudo_type_info creation into the std namespace
-
-2000-02-26 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (DECL_NEEDED_P): Tweak to correct usage before EOF.
- (import_export_class): Remove declaration.
- * decl2.c (import_export_class): Make it static.
- * dump.c (dequeue_and_dump): Handle PREDECREMENT_EXPR,
- PREINCREMENT_EXPR, POSTDECREMENT_EXPR, POSTINCREMENT_EXPR,
- EXPR_WITH_FILE_LOCATION.
- * lex.c (check_newline): Tweak filename/lineno setting.
- * semantics.c (begin_while_stmt): Fix typo in comment.
-
-Sat Feb 26 19:50:23 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * lang-options.h (-fmessage-length=): Add missing option.
-
- * Make-lang.in (CXX_SRCS): Add .h files and sort list.
-
-2000-02-26 Zack Weinberg <zack@wolery.cumb.org>
-
- * Make-lang.in: Delete refs to LIBGCC2_DEPS.
-
-Fri Feb 25 14:52:33 2000 Jim Wilson <wilson@cygnus.com>
-
- * optimize.c (expand_call_inline): Emit the return label before
- evaluating the return value.
-
-2000-02-24 Mark Mitchell <mark@codesourcery.com>
-
- * lex.c (check_newline): Use push_srcloc and pop_srcloc, rather
- than duplicating functionality here.
- * optimize.c: Include input.h.
- (expand_call_inline): Use push_srcloc and pop_srcloc.
- * parse.y (maybe_cv_qualifier): Remove calls to emit_line_note.
- * parse.c: Regenerated.
- * Makefile.in (lex.o): Depend on input.h.
- (optimize.o): Likewise.
-
-2000-02-24 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (grokdeclarator): Diagnose qualifiers on non-member
- function type, rather than ICE.
-
-2000-02-23 Jason Merrill <jason@casey.cygnus.com>
-
- * decl.c (grokdeclarator): Call decl_type_access_control.
- * parse.y (parse_end_decl): Don't call decl_type_access_control if
- decl is null.
-
-2000-02-23 Nathan Sidwell <nathan@codesourcery.com>
-
- * decl.c (decls_match): Remove obsolete static member nadgering.
-
-2000-02-21 Martin v. Löwis <loewis@informatik.hu-berlin.de>
-
- * decl.c (grokdeclarator): Change ANSI to ISO.
- * lex.c (consume_string, readescape, do_identifier): Likewise.
- (parse_float, real_yylex): Likewise.
- * parse.y (paren_expr_or_null, paren_cond_or_null): Likewise.
- (unary_expr, new_initializer, cast_expr, primary, primary_no_id,
- new_type_id, maybe_label_decls, simple_stmt,
- for.init.statement): Likewise.
- * pt.c (do_decl_instantiation, do_type_instantiation): Likewise.
- * semantics.c (finish_named_return_value): Likewise.
- * parse.c: Regenerate.
-
-2000-02-21 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (CPTI_VTABLE_INDEX_TYPE): New macro.
- (CPTI_CLASS_STAR_TYPE): Remove.
- (vtable_index_type): Likewise.
- (class_star_type_node): Remove.
- (TYPE_PTRMEMFUNC_FN_TYPE): Adjust for the new ABI.
- (build_binary_op_nodefault): Remove.
- * call.c (build_new_op): Use build_binary_op instead of
- build_binary_op_nodefault.
- * decl.c (init_decl_processing): Remove class_star_type_node
- initialization. Make delta_type_node ptrdiff_type_node under the
- new ABI. Initialize vtable_index_type.
- (build_ptrmemfunc_type): Build different structures for the new
- ABI.
- (build_enumerator): Use build_binary_op instead of
- build_binary_op_nodefault.
- * method.c (build_overload_value): Mangle pointers-to-members
- appropriately under the new ABI.
- * typeck.c (build_array_ref): Use build_binary_op instead of
- build_binary_op_nodefault.
- (get_member_function_from_ptrfunc): Adjust for the new ABI.
- (build_binary_op_nodefault): Rename to ...
- (build_binary_op): ... this. Remove old version. Adjust for
- pointer-to-member comparisons under the new ABI.
- (build_ptrmemfunc1): Remove dead code. Adjust for the new ABI.
- (build_ptrmemfunc): Adjust for the new ABI.
- (expand_ptrmemfunc_cst): Likewise.
- (delta2_from_ptrmemfunc): Assert that we're not using the new ABI.
- (pfn_from_ptrmemfunc): Adjust for the new ABI.
-
-2000-02-21 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * call.c (build_object_call): Compress consecutive calls to
- cp_error.
- (build_conditional_expr): Say 'ISO C++' not 'ANSI C++'.
- (build_op_delete_call): Adjust message formatting.
-
- * class.c (check_bases): Compress consecutive calls to
- cp_pedwarn.
- (finish_struct_anon): Say 'ISO C++'.
-
- * decl.c (start_decl): Same here.
- (grok_reference_init): Likewise.
- (grokfndecl): Correct message formatting.
- (grokfndecl): Improve diagnostic.
- (check_static_variable_definition): Likewise. Say 'ISO C++'
- (compute_array_index_type): Say 'ISO C++'
- (create_array_type_for_decl): Compress consecutive calls to
- cp_error.
- (grokdeclarator): Say 'ISO C++'
- (grok_op_properties): Likewise.
-
- * decl2.c (delete_sanity): Clairify diagnostic.
- (check_member_template): Same here.
- (grok_function_init): Use consistent terminology.
-
- * expr.c (do_case): Say 'ISO C++'
-
- * friend.c (do_friend): Compress consecutive calls to warning.
-
-2000-02-20 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (merge_primary_and_secondary_vtables_p): New macro.
- * class.c (build_secondary_vtable): Reorganize. Don't create a
- new vtable under the new ABI.
- (layout_vtable_decl): Don't add num_extra_vtbl_entries when
- computing the size.
- (build_vtbl_initializer): Don't return a CONSTRUCTOR; just return
- the initializing elements.
- (initialize_vtable): New function.
- (dfs_finish_vtbls): Use it.
- (dfs_accumulate_vtbl_inits): New function.
- (finish_vtbls): Merge primary and secondary vtables under the new
- ABI.
- (finish_struct_1): Remove redundant call to layout_vtable_decl.
- * init.c (expand_virtual_init): Deal with BINFO_VTABLEs that
- aren't VAR_DECLs.
-
- * class.c (build_vtable): New function, split out from ...
- (get_vtable_decl): ... here, and ...
- (build_secondary_vtable): ... here.
-
- * pt.c (tsubst_decl): Fix formatting.
-
-Sat Feb 19 18:43:13 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
-
- * class.c (build_primary_vtable, layout_vtable_decl): Likewise.
- (avoid_overlap, build_base_field): Likewise.
- (build_base_field, build_base_fields, is_empty_class):
- Test DECL_SIZE with integer_zero.
- (layout_class_type): Set CLASSTYPE_SIZE_UNIT.
- * cp-tree.h (struct lang_type): New field size_unit.
- (CLASSTYPE_SIZE_UNIT): New macro.
- * decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
- (cp_finish_decl): Delete -Wlarger-than processing.
- * optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
- * pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
- * tree.c (make_binfo): binfo vector is one entry longer.
- (walk_tree): Walk DECL_SIZE_UNIT.
-
-2000-02-19 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (dfs_build_vcall_offset_vtbl_entries): Fix typo in
- comment.
- (build_vtable_entry): Don't assume all vtable entries are
- functions.
- (build_vtbl_initializer): Adjust accordingly.
- (get_vtable_decl): Fix formatting.
-
-2000-02-18 Jason Merrill <jason@casey.cygnus.com>
-
- * semantics.c (deferred_type_access_control): Walk the entire
- type_lookups list.
- (save_type_access_control): Rename from
- initial_deferred_type_access_control. Just remember the value.
- (decl_type_access_control): New fn.
- (begin_function_definition): Use deferred_type_access_control, after
- we've started the function. Set type_lookups to error_mark_node.
- * parse.y (frob_specs, fn.def1): Adjust.
- (parse_decl0, parse_field, parse_field0, parse_bitfield): New fns.
- (parse_end_decl, parse_bitfield0, parse_method): New fns.
- (fn.def2, initdcl, initdcl0_innards, nomods_initdcl0): Use them.
- (after_type_component_declarator0): Likewise.
- (after_type_component_declarator): Likewise.
- (notype_component_declarator): Likewise.
- * cp-tree.h: Adjust.
-
- * decl.c (redeclaration_error_message): Allow redeclaration of
- namespace-scope decls.
-
-2000-02-18 Martin von Loewis <loewis@informatik.hu-berlin.de>
-
- * typeck2.c (my_friendly_abort): Use GCCBUGURL.
-
-2000-02-17 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (add_method): Don't set DECL_VIRTUAL_CONTEXT.
- * decl2.c (grokclassfn): Likewise.
-
- * ir.texi: Document DECL_TEMPLATE_INSTANTIATIONS.
-
- * decl2.c (lang_decode_option): Don't set default message length
- here.
- * lex.c (lang_init_options): Set it here.
-
-2000-02-16 Mark Mitchell <mark@codesourcery.com>
-
- Make DECL_CONTEXT mean the class in which a member function was
- declared, even for a virtual function.
- * cp-tree.h (DECL_CLASS_CONTEXT): Adjust.
- (DECL_FRIEND_CONTEXT): New macro.
- (DECL_REAL_CONTEXT): Remove.
- (SET_DECL_FRIEND_CONTEXT): Likewise.
- (DECL_VIRTUAL_CONTEXT): Adjust.
- (DECL_CLASS_SCOPE_P): Use TYPE_P.
- (add_friends): Remove.
- (hack_decl_function_context): Likewise.
- * call.c (build_new_function_call): Replace DECL_REAL_CONTEXT with
- CP_DECL_CONTEXT.
- (build_over_call): Fix indentation. Use DECL_CONTEXT
- instead of DECL_CLASS_CONTEXT.
- * class.c (dfs_build_vcall_offset_vtbl_entries): Likewise.
- (add_method): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
- (strictly_overrides): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
- (build_vtbl_or_vbase_field): Don't set DECL_CLASS_CONTEXT.
- (build_base_field): Likewise.
- (finish_struct_1): Likewise.
- (build_self_reference): Likewise.
- * decl.c (push_class_binding): Use CP_DECL_CONTEXT, not
- DECL_REAL_CONTEXT.
- (pushtag): Use decl_function_context, not
- hack_decl_function_context.
- (decls_match): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
- (duplicate_decls): Use DECL_VIRTUAL_CONTEXT.
- (pushdecl): Remove bogus code.
- (start_decl): Use DECL_CONTEXT rather than DECL_CLASS_CONTEXT.
- (cp_finish_decl): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
- (grokfndecl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
- Use decl_function_context, nothack_decl_function_context.
- (grokvardecl): Don't set DECL_CLASS_CONTEXT.
- (grokdeclarator): Likewise. Use decl_function_context, not
- hack_decl_function_context.
- (copy_args_p): Document. Don't use DECL_CLASS_CONTEXT.
- (start_function): Use DECL_FRIEND_CONTEXT, not
- DECL_CLASS_CONTEXT. Use decl_function_context, not
- hack_decl_function_context.
- (finish_function): Use decl_function_context, not
- hack_decl_function_context.
- (maybe_retrofit_in_chrg): Use DECL_CONTEXT, not
- DECL_CLASS_CONTEXT.
- (grokclassfn): Set DECL_VIRTUAL_CONTEXT, not DECL_CONTEXT.
- (finish_static_data_member_decl): Don't set DECL_CLASS_CONTEXT.
- (grokfield): Likewise.
- (finish_builtin_type): Likewise.
- (finish_vtable_vardec): Use decl_function_context, not
- hack_decl_function_context.
- (import_export_decl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
- (start_static_initialization_or_destruction): Likewise.
- (finish_static_initialization_or_destruction): Likewise.
- (mark_used): Adjust logic for deciding when to synthesize methods.
- * dump.c (dequeue_and_dump): Use CP_DECL_CONTEXT, not
- DECL_REAL_CONTEXT.
- * error.c (dump_function_decl): Use DECL_CONTEXT, not
- DECL_CLASS_CONTEXT.
- * friend.c (is_friend): Likewise.
- (add_friends): Remove.
- (do_friend): Use SET_DECL_FRIEND_CONTEXT.
- * lex.c (begin_definition_of_inclass_inline): Use
- decl_function_context, not hack_decl_function_context.
- (process_next_inline): Likewise.
- (do_identifier): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
- * method.c (set_mangled_name_for_decl): Use DECL_CONTEXT, not
- DECL_CLASSS_CONTEXT.
- (hack_identifier): Likewise.
- (synthesize_method): Use decl_function_context, not
- hack_decl_function_context.
- * pt.c (template_class_depth_real): Use CP_DECL_CONTEXT, not
- DECL_REAL_CONTEXT.
- (is_member_template): Use decl_function_context, not
- hack_decl_function_context. Use DECL_CONTEXT, not
- DECL_CLASS_CONTEXT.
- (build_template_decl): Set DECL_VIRTUAL_CONTEXT, not
- DECL_CLASS_CONTEXT.
- (check_default_tmpl_args): Use CP_DECL_CONTEXT, not
- DECL_REAL_CONTEXT.
- (push_template_decl_real): Likewise.
- (instantiate_class_template): Don't call add_friends.
- (tsubst_default_argument): Use DECL_CONTEXT, not
- DECL_REAL_CONTEXT.
- (tsubst_decl): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
- Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
- (set_meangled_name_for_template_decl): Use DECL_CONTEXT, not
- DECL_CLASS_CONTEXT.
- * repo.c (repo_inline_used): Likewise.
- * search.c (current_scope): Adjust for new _CONTEXT macros.
- (context_for_name_lookup): Use CP_DECL_CONTEXT, not
- DECL_REAL_CONTEXT.
- (friend_accessible_p): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
- (lookup_fnfields_here):Likewise.
- (check_final_overrider): Likewise.
- (init_vbase_pointers): Likewise.
- (virtual_context): Likewise.
- * semantics.c (finish_member_declaration): Just set DECL_CONTEXT.
- (expand_body): Use decl_function_context, not
- hack_decl_function_context.
- * tree.c (hack_decl_function_context): Remove.
- * typeck.c (build_x_function_call): Use DECL_CONTEXT, not
- DECL_CLASS_CONTEXT.
- * typeck2.c (error_not_base_type): Likewise.
-
-2000-02-15 Jason Merrill <jason@casey.cygnus.com>
-
- * decl.c (xref_tag): Don't SET_IDENTIFIER_NAMESPACE_VALUE.
-
-2000-02-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * Make-lang.in (g++spec.o): Depend on $(GCC_H), not gcc.h.
-
-2000-02-15 Jonathan Larmour <jlarmour@redhat.co.uk>
-
- * lang-specs.h: Add new __GNUC_PATCHLEVEL__ define to default spec.
-
-2000-01-16 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * decl2.c (lang_decode_option): Enable automatic line wrapping.
-
-2000-02-13 Jason Merrill <jason@casey.cygnus.com>
-
- * parse.y (frob_specs): Split out...
- (parse_decl): From here.
- (fn.def2): Call initial_deferred_type_access_control.
- (after_type_component_declarator0): Call frob_specs.
- (notype_component_declarator0): Likewise.
- * search.c (friend_accessible_p): Nested classes are friends of their
- enclosing classes.
-
-2000-02-10 Mark Mitchell <mark@codesourcery.com>
-
- * ir.texi (ADDR_EXPR): Document the fact that an ADDR_EXPR can be
- used to create an implicit temporary.
-
- * class.c (dfs_modify_vtables): Tweak calculation of functions to
- override.
-
-2000-02-08 Nathan Sidwell <nathan@acm.org>
-
- * typeck.c (strip_all_pointer_quals): Use TYPE_MAIN_VARIANT, to
- strip array element qualifiers too.
-
-2000-02-07 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (store_parm_decls): Don't build cleanups for parameters
- while processing_template_decl.
-
-2000-02-07 Jason Merrill <jason@casey.cygnus.com>
-
- * cp-tree.h (struct saved_scope): Add incomplete field.
- (namespace_scope_incomplete): New macro.
- * decl.c (pushdecl): Use it.
- (hack_incomplete_structures): Use it. See through artificial
- binding levels.
- (mark_saved_scope): Mark it.
-
- Implement access control for nested types.
- * search.c (type_access_control): New fn.
- (accessible_p): Now we do perform access control for types.
- * semantics.c (deferred_type_access_control): New fn.
- (initial_deferred_type_access_control): New fn.
- (begin_function_definition): Call it. Add lookups parm.
- * decl.c (struct binding_level): Add this_class field.
- (pushlevel_class): Set it.
- (mark_binding_level): Mark it.
- (lookup_name_real): Use it. Call type_access_control.
- (mark_saved_scope): Mark lookups field.
- * cp-tree.h (flagged_type_tree): Add lookups field.
- (struct saved_scope): Add lookups field.
- (type_lookups): New macro.
- * parse.y (declmods): Now <ftype>.
- (parse_decl): Add lookups parm. Call
- initial_deferred_type_access_control.
- (lang_extdef): Clear type_lookups.
- (typed_declspecs, declmods, typespec): Set lookups field.
- (initdcl): Call deferred_type_access_control.
- (fn.def1, fn.def2, typed_declspecs1, initdcl0_innards, nomods_initdcl0,
- component_decl_1, named_parm): Adjust.
- * friend.c (is_friend): Nested classes are friends of their
- enclosing classes.
-
- * class.c (currently_open_derived_class): New fn.
- * method.c (hack_identifier): Use it.
-
- * lex.c (do_identifier): Remove obsolete code.
-
- * parse.y (typed_typespecs): Propagate new_type_flag properly.
-
-2000-02-05 Zack Weinberg <zack@wolery.cumb.org>
-
- * tinfo.h: Remove apostrophes from C++ comment (xgettext
- thinks this file is plain C).
-
-2000-02-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * Makefile.in (call.o): Depend on $(EXPR_H).
-
- * call.c: Include "expr.h".
-
- * class.c (dump_class_hierarchy): Add prototype.
-
- * search.c (dfs_get_pure_virtuals): Likewise.
-
-2000-02-1 Ulrich Drepper <drepper@redhat.com>
-
- * parse.y (simple_stmt): Allow :: token in asm parameter list.
- * parse.c: Rebuilt.
-
-Mon Jan 31 15:35:29 2000 Jim Wilson <wilson@cygnus.com>
-
- * class.c (build_vtbl_or_vbase_field): New parameter fcontext.
- Store it in DECL_FCONTEXT.
- (build_vbase_pointer_fields, create_vtable_ptr): Fix callers.
-
-2000-01-31 Jason Merrill <jason@casey.cygnus.com>
-
- * tinfo.h (old abi): #include "tconfig.h".
- * tinfo.cc (convert_to_base): Move into old abi section.
-
-2000-01-31 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (BINFO_VIRTUALS): Tweak documentation.
- (CLASSTYPE_PRIMARY_BINFO): Use BINFO_PRIMARY_BINFO.
- (BINFO_PRIMARY_BINFO): New macro.
- (BF_DELTA): Rename to ...
- (BV_DELTA): ... this.
- (BF_VCALL_INDEX): Rename to ...
- (BV_VCALL_INDEX): ... this.
- (BF_FN): Rename to ...
- (BV_FN): ... this.
- * class.c (build_vbase_path): Adjust for changes to reverse_path.
- (set_rtti_entry): Rename BF_ macros to BV_ variants.
- (modify_vtable_entry): Simplify.
- (add_virtual_function): Rename BF_ macros to BV_ variants.
- (build_vtable_initializer): Likewise.
- (get_class_offset_1): Remove.
- (dfs_get_class_offset): Likewise.
- (get_class_offset): Likewise.
- (dfs_find_final_overrider): New function.
- (find_final_overrider): Likewise.
- (modify_one_vtable): Remove.
- (dfs_find_base): New function.
- (dfs_modify_vtables): Fold modify_one_vtable in here. Use
- find_final_overrider.
- (modify_all_vtables): Adjust. Set BV_VCALL_INDEX on new
- virtuals.
- (dfs_fixup_vtable_deltas): Remove.
- (override_one_vtable): Remove.
- (merge_overrides): Likewise.
- (layout_virtual_bases): Make sure BINFO_OFFSET is set right for
- unreal chilren of virtual bases.
- (finish_struct_1): Don't use merge_overrides. Don't use
- dfs_fixup_vtable_deltas.
- * tree.c (reverse_path): Return a TREE_LIST, not a chain of
- BINFOs.
-
-2000-01-31 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
- Jason Merrill <jason@yorick.cygnus.com>
-
- * tinfo.h: Rename USItype to myint32, depend on BITS_PER_UNIT.
-
-2000-01-31 Alfred Minarik <a8601248@unet.univie.ac.at>
-
- * exception.cc (__throw_bad_typeid): Add missing std::.
-
-2000-01-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * cp-tree.h (make_thunk): PROTO -> PARAMS.
-
-2000-01-31 Nathan Sidwell <sidwell@codesourcery.com>
-
- * cp-tree.h (new_abi_rtti_p): Use flag_new_abi.
-
- Runtime support for new-abi rtti.
- * inc/typeinfo (type_info::operator!=): Define in class.
- (type_info::before, type_info::name, type_info::operator==,
- type_info::operator!=): Define new ABI implementations.
- (type_info::is_pointer_p, type_info::is_function_p): Declare
- new virtual functions.
- (type_info::do_catch, type_info::do_upcast): Likewise.
-
- * tinfo.h (__base_class_info): Define new class.
- (__class_type_info): Likewise.
- (__si_class_type_info): Likewise.
- (__vmi_class_type_info): Likewise.
- (__dynamic_cast): Prototype.
-
- * tinfo.cc: Conditionalize old and new rtti mechanisms.
- (type_info::is_pointer_p): Define new function.
- (type_info::is_function_p): Likewise.
- (type_info::do_catch): Likewise.
- (type_info::do_upcast): Likewise.
- (vtable_prefix): New structure for vtable access.
- (adjust_pointer): Define new template function.
- (contained_p, public_p, virtual_p, contained_public_p,
- contained_nonpublic_p, contained_nonvirtual_p): Define new
- functions.
- (nonvirtual_base_type): New local variable.
- (__class_type_info::~__class_type_info): Define.
- (__si_class_type_info::~__si_class_type_info): Likewise.
- (__vmi_class_type_info::~__vmi_class_type_info): Likewise.
- (__class_type_info::do_catch): Define new function.
- (__class_type_info::do_upcast): Likewise.
- (__class_type_info::find_public_src): Likewise.
- (__class_type_info::do_find_public_src): Likewise.
- (__si_class_type_info::do_find_public_src): Likewise.
- (__vmi_class_type_info::do_find_public_src): Likewise.
- (__class_type_info::do_dyncast): Likewise.
- (__si_class_type_info::do_dyncast): Likewise.
- (__vmi_class_type_info::do_dyncast): Likewise.
- (__class_type_info::do_upcast): Likewise.
- (__si_class_type_info::do_upcast): Likewise.
- (__vmi_class_type_info::do_upcast): Likewise.
- (__dynamic_cast): Likewise.
-
- * tinfo2.cc (__fundamental_type_info): Define new class.
- (__pointer_type_info): Likewise.
- (__reference_type_info): Likewise.
- (__array_type_info): Likewise.
- (__function_type_info): Likewise.
- (__enum_type_info): Likewise.
- (__ptr_to_member_type_info): Likewise.
- (__fundamental_type_info::~__fundamental_type_info): Define.
- (__pointer_type_info::~__pointer_type_info): Likewise.
- (__reference_type_info::~__reference_type_info): Likewise.
- (__array_type_info::~__array_type_info): Likewise.
- (__function_type_info::~__function_type_info): Likewise.
- (__enum_type_info::~__enum_type_info): Likewise.
- (__ptr_to_member_type_info::~__ptr_to_member_type_info): Likewise.
- (__pointer_type_info::do_catch): Define new function.
- (__ptr_to_member_type_info::do_catch): Define new function.
-
- (__throw_type_match_rtti_2): Use new ABI interface, if enabled.
- (__is_pointer): Likewise.
-
- * exception.cc (__cplus_type_matcher): Deal with new-abi rtti.
-
-2000-01-30 Mark Mitchell <mark@codesourcery.com>
-
- * cp/class.c (build_vtable): Rename to build_primary_vtable.
- (prepare_fresh_vtable): Rename to build_secondary_vtable.
- (make_new_vtable): New function.
- (modify_vtable_entry): Handle generation of new vtables correctly.
- (modify_one_vtable): Remove unused parameter.
- (dfs_fixup_vtable_deltas): Likewise.
- (override_one_vtable): Use build_secondary_vtable.
- (finish_struct_1): Use build_primary_vtable and
- build_secondary_vtable.
-
-2000-01-28 Ulrich Drepper <drepper@redhat.com>
-
- * cp/decl.c: Adjust variable names, comments, help strings.
-
-2000-01-29 Nathan Sidwell <nathan@acm.org>
-
- * new2.cc (operator delete[]): Use operator delete, don't assume
- implementation.
-
-2000-01-29 Nathan Sidwell <sidwell@codesourcery.com>
-
- * class.c (build_vtbl_initializer): Add argument to
- build_vtable_entry call.
-
-2000-01-27 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.def (THUNK_DECL): Discuss vcall indices.
- * cp-tree.h (BINFO_VIRTUALS): Update documentation.
- (BF_DELTA): New macro.
- (BF_VCALL_INDEX): Likewise.
- (BF_FN): Likewise.
- (THUNK_VCALL_OFFSET): Likewise.
- (make_thunk): Change prototype.
- * class.c (build_vtable_entry): Integrate
- build_vtable_entry_for_fn. Handle vcall indices.
- (build_vtable_entry_for_fn): Remove.
- (set_rtti_entry): Handle vcall indices. Use BF_DELTA,
- BF_VCALL_INDEX, BF_FN.
- (modify_vtable_entry): Integrate common code from
- modify_one_vtable and dfs_fixup_vtable_deltas.
- (add_virtual_function): Set BF_VCALL_INDEX.
- (build_vtbl_initializer): Simplify. Use BF_DELTA, BF_VCALL_INDEX,
- and BF_FN.
- (modify_one_vtable): Simplify.
- (dfs_fixup_vtable_deltas): Likewise.
- (override_one_vtable): Use BF_DELTA, BF_VCALL_INDEX, BF_FN.
- * method.c (make_thunk): Handle vcall indices.
-
-2000-01-28 Nathan Sidwell <sidwell@codesourcery.com>
-
- Compiler side new abi rtti (not enabled).
- * cp-tree.h (new_abi_rtti_p): New macro.
- (emit_support_tinfos): Prototype new function.
- (tinfo_decl_p): Likewise.
- (emit_tinfo_decl): Likwise.
- * rtti.c (TINFO_PSEUDO_TYPE, TINFO_VTABLE_DECL): New accessor
- macros.
- (doing_runtime): New local static.
- (init_rtti_processing): Add new-abi initializer.
- (get_tinfo_decl): Add new-abi logic.
- (tinfo_from_decl): Likewise.
- (build_dynamic_cast_1): Likewise.
- (qualifier_flags): New static function.
- (tinfo_base_init): Likewise.
- (generic_initializer): Likewise.
- (ptr_ref_initializer): Likewise.
- (ptmd_initializer): Likewise.
- (class_hint_flags): Likewise.
- (class_initializer): Likewise.
- (synthesize_tinfo_var): Likewise.
- (create_real_tinfo_var): Likewise.
- (create_pseudo_type_info): Likewise.
- (get_vmi_pseudo_type_info): Likewise.
- (create_tinfo_types): Likewise.
- (emit_support_tinfos): New global function.
- (tinfo_decl_p): New global predicate.
- (emit_tinfo_decl): New global function.
- * class.c (set_rtti_entry): Generalize for old and new rtti.
- (build_vtbl_initializer): Likewise.
- * decl2.c (finish_file): Likewise.
-
-Thu Jan 27 20:53:36 2000 Jim Wilson <wilson@cygnus.com>
-
- * optimize.c (remap_decl): Add walk_tree calls for DECL_SIZE (t)
- and TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t))).
-
-Thu Jan 27 13:54:12 2000 Mike Stump <mrs@wrs.com>
-
- * decl.c (pushdecl): Fix up shadow warnings with respect to implicit
- for scopes.
-
-2000-01-26 Jason Merrill <jason@casey.cygnus.com>
-
- * pt.c (unify): Use fold, not maybe_fold_nontype_arg.
-
-Wed Jan 26 22:19:14 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
-
- * optimize.c (calls_setjmp_r): Supply new argument
- to special_function_p.
-
-2000-01-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * call.c: PROTO -> PARAMS.
- * class.c: Likewise.
- * cp-tree.h: Likewise.
- * cvt.c: Likewise.
- * decl.c: Likewise.
- * decl.h: Likewise.
- * decl2.c: Likewise.
- * dump.c: Likewise.
- * errfn.c: Likewise.
- * error.c: Likewise.
- * except.c: Likewise.
- * expr.c: Likewise.
- * init.c: Likewise.
- * input.c: Likewise.
- * lex.c: Likewise.
- * lex.h: Likewise.
- * method.c: Likewise.
- * optimize.c: Likewise.
- * parse.y: Likewise.
- * pt.c: Likewise.
- * repo.c: Likewise.
- * rtti.c: Likewise.
- * search.c: Likewise.
- * semantics.c: Likewise.
- * spew.c: Likewise.
- * tree.c: Likewise.
- * typeck.c: Likewise.
- * typeck2.c: Likewise.
- * xref.c: Likewise.
-
-2000-01-25 Richard Henderson <rth@cygnus.com>
-
- * typeck.c (build_binary_op_nodefault): Remove UNNE_EXPR.
-
-2000-01-25 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (vcall_offset_in_vtable_p): New macro.
- * class.c (build_vbase_offset_vtbl_entries): Fix typo in commment.
- (struct vcall_offset_data_s): New type.
- (dfs_vcall_offset_queue_p): New function.
- (dfs_build_vcall_offset_vtbl_entries): Likewise.
- (build_vcall_offset_vtbl_entries): Likewise.
- (layout_vtable_decl): Likewise.
- (num_vfun_entries): Likewise.
- (num_extra_vtbl_entries): Add the entries for vcall offsets.
- (build_vtbl_initializer): Likewise.
- (dfs_finish_vtabls): Use layout_vtable_decl.
- (modify_one_vtables): Always duplicate vtables under the new ABI.
- (finish_struct_1): Use layout_vtable_decl.
-
-2000-01-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+2004-01-04 Andrew Pinski <pinskia@physics.uc.edu>
- * decl.c (member_function_or_else): Change third arg from a format
- specifier to an `enum overload_flags'. Callers changed.
+ * semantics.c (push_deferring_access_checks): Fix format.
+ (resume_deferring_access_checks): Likewise.
+ (stop_deferring_access_checks): Likewise.
+ (pop_deferring_access_checks): Likewise.
+ (get_deferred_access_checks): Likewise.
+ (pop_to_parent_deferring_access_checks): Likewise.
+ (perform_deferred_access_checks): Likewise.
+ (perform_or_defer_access_check): Likewise.
-2000-01-25 Gabriel Dos Reis <gdr@codesourcery.com>
+2004-01-04 Richard Henderson <rth@redhat.com>
- * typeck.c (composite_pointer_type, c_sizeof, expr_sizeof,
- build_binary_op_nodefault, build_unary_op, build_reinterpret_cast,
- build_const_cast, get_delta_difference, check_return_expr): Avoid
- ANSI string concatenation usage.
+ * call.c (build_over_call): Don't create a save_expr of an
+ aggregate, but rather its address.
-2000-01-24 Mark Mitchell <mark@codesourcery.com>
+2004-01-04 Mark Mitchell <mark@codesourcery.com>
- * class.c (layout_class_type): Put the fields required to make a
- class non-empty at the end, not the beginning, of the TYPE_FIELDs
- list.
+ PR c++/13529
+ * parser.c (cp_parser_postfix_expression): Allow "." to appear in
+ an offsetof expression.
-2000-01-24 Jason Merrill <jason@casey.cygnus.com>
+ * parser.c (cp_parser_parameter_declaration): Fix comment.
- * pt.c (maybe_fold_nontype_arg): Do nothing if we're not in a
- template.
-
- * decl2.c (mark_used): Do instantiate inlines that have been
- explicitly instantiated.
-
-2000-01-24 Richard Henderson <rth@cygnus.com>
-
- * call.c (build_over_call): Use expand_tree_builtin.
- * typeck.c (build_function_call_real): Likewise.
- (build_binary_op_nodefault): Handle unordered compares.
-
-2000-01-24 Nathan Sidwell <sidwell@codesourcery.com>
-
- * cp-tree.h (CPTI_BAD_CAST, CPTI_BAD_TYPEID, CPTI_DCAST): New
- cp_tree_index values.
- (throw_bad_cast_node, throw_bad_typeid_node, dynamic_cast_node):
- New global node #defines for them.
- * rtti.c (call_void_fn): Replace with ...
- (build_runtime_decl): ... new static function.
- (throw_bad_cast): Use throw_bad_cast_node and build_runtime_decl.
- (throw_bad_typeid): Use throw_bad_typeid_node and build_runtime_decl.
- (build_dynamic_cast_1): Always produce correctly typed result.
- Explicitly produce type_info addresses. Use dynamic_cast_node.
- * exception.cc (__throw_bad_cast): Return `void *'.
- (__throw_bad_typeid): Return `const type_info &'.
-
-2000-01-24 Nathan Sidwell <sidwell@codesourcery.com>
-
- * cp-tree.h (get_vtable_decl): Prototype new function.
- * class.c (get_vtable_decl): New function. Broken out from ...
- (build_vtable): ... here. Use it.
- * decl2.c (finish_vtable_vardecl): Ignore dummy vtables created
- by get_vtable_decl.
-
-2000-01-24 Nathan Sidwell <sidwell@codesourcery.com>
-
- * cp-tree.h (CPTI_TP_DESC_TYPE, CPTI_ACCESS_MODE_TYPE,
- CPTI_USER_DESC_TYPE, CPTI_CLASS_DESC_TYPE, CPTI_ATTR_DESC_TYPE,
- CPTI_PTMF_DESC_TYPE): Remove cp_tree_index enumerations.
- (CPTI_TI_DESC_TYPE, CPTI_REF_DESC_TYPE, CPTI_ARY_DESC_TYPE,
- CPTI_ENUM_DESC_TYPE, CPTI_CLASS_DESC_TYPE, CPTI_SI_CLASS_DESC_TYPE,
- CPTI_VMI_CLASS_DESC_TYPE, CPTI_BASE_DESC_TYPE): New enumerations.
- (CPTI_TINFO_FN_ID, CPTI_TINFO_FN_TYPE): Rename to ...
- (CPTI_TINFO_DECL_ID, CPTI_TINFO_DECL_TYPE): ... here.
- (CPTI_TINFO_VAR_ID): New enumeration.
- (__tp_desc_type_node, __access_mode_type_node,
- __bltn_desc_type_node, __user_desc_type_node,
- __class_desc_type_node, __ptr_desc_type_node,
- __attr_desc_type_node, __func_desc_type_node,
- __ptmf_desc_type_node, __ptmd_desc_type_node): Remove #defines.
- (ti_desc_type_node, bltn_desc_type_node, ptr_desc_type_node,
- ref_desc_type_node, ary_desc_type_node, func_desc_type_node,
- enum_desc_type_node, class_desc_type_node,
- si_class_desc_type_node, vmi_class_desc_type_node,
- ptmd_desc_type_node, base_desc_type_node): New #defines.
- (tinfo_fn_id, tinfo_fn_type): Rename to ...
- (tinfo_decl_id, tinfo_decl_type): ... here. Adjust.
- (tinfo_var_id): New enumeration.
- (DECL_TINFO_FN_P): Augment comment.
- * decl.c (cp_global_trees): Adjust documentation.
- * rtti.c (init_rtti_processing): Adjust for tinfo_decl_id,
- tinfo_decl_type and tinfo_var_id.
- (get_tinfo_decl_dynamic): Adjust for tinfo_decl_type.
- (build_typeid): Remove unused variable.
- (get_tinfo_var): Use tinfo_var_id.
- (tinfo_name): New static function.
- (get_tinfo_decl): Adjust for tinfo_decl_id and tinfo_decl_type.
- (tinfo_from_decl): Likewise.
- (get_base_offset): New static function, broken out of
- expand_class_desc.
- (expand_si_desc): Use tinfo_name.
- (expand_class_desc): Likewise. Lose local static variable.
- Use base_desc_type_node. Use get_base_offset.
- (expand_ptr_desc): Use tinfo_name.
- (expand_attr_desc): Likewise.
- (expand_generic_desc): Likewise.
-
- * tinfo.cc (__GXX_ABI_VERSION): Test value and existence.
- * tinfo.h (__GXX_ABI_VERSION): Test value and existence.
-
-2000-01-23 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (__eprintf): Remove declaration.
- * tree.c (__eprintf): Remove definition.
-
-2000-01-23 Zack Weinberg <zack@rabi.columbia.edu>
- Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (CLASSTYPE_MARKED_N, SET_CLASSTYPE_MARKED_N,
- CLEAR_CLASSTYPE_MARKED_N): Avoid signed vs. unsigned warnings.
-
-2000-01-23 Brad Lucier <lucier@math.purdue.edu>
-
- * class.c (dump_class_hierarchy): Print HOST_WIDE_INT properly.
-
-2000-01-23 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (register_dtor_fn): New function.
- * decl.c (destroy_local_static): Rename to ...
- (register_dtor_fn): ... this. Give it external linkage.
- (expand_static_init): Use it.
- * decl2.c (do_static_initialization): Likewise, if using
- __cxa_atexit.
- (do_static_destruction): Check that __cxa_atexit is not in use.
- (finish_file): Don't call do_static_destruction if using
- __cxa_atexit.
-
- * typeck.c (convert_arguments): Restore two-message error
- reporting.
-
-2000-01-20 Nathan Sidwell <sidwell@codesourcery.com>
-
- Remap dynamic cast hint values to be consistent across ABIs.
- * search.c (dynamic_cast_base_recurse): Remap generated value.
- (get_dynamic_cast_base_type): Adjust documentation.
- * tinfo.h (__user_type_info::dyncast): Likewise.
- (__user_type_info::find_public_subobj): Remap BOFF meaning.
- * tinfo.cc (__si_type_info::do_dyncast): Remap BOFF meaning.
- (__class_type_info::do_dyncast): Likewise.
- (__class_type_info::do_find_public_subobj): Likewise.
- * tinfo2.cc (__dynamic_cast): Remap BOFF parameter.
-
-2000-01-19 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * typeck.c (build_unary_op): Use cp_pedwarn, not pedwarn.
-
- * typeck2.c (incomplete_type_error): Restore previous
- cp_error and cp_error_at call sequence.
-
-2000-01-20 Brad Lucier <lucier@math.purdue.edu>
-
- * class.c (dump_class_hierarchy): Make format agree with argument;
- cast pointer to unsigned long and print with %lx.
-
-2000-01-19 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * decl2.c (lang_decode_option): Set default line-wrap length to 72.
-
- * typeck.c (composite_pointer_type, common_type,
- comp_target_parms, c_sizeof, expr_sizeof, build_array_ref,
- build_function_call_real, convert_arguments,
- build_binary_op_nodefault, pointer_int_sum, pointer_diff,
- build_unary_op, mark_addressable, build_compound_expr,
- build_static_cast, build_reinterpret_cast, build_const_cast,
- build_c_cast, build_modify_expr, get_delta_difference,
- build_ptrmemfunc, check_return_expr): Replace 'ANSI C++' with
- 'ISO C++'. Fusion consecutive calls to diagnostic message routines
- into a single one.
- * typeck2.c (readonly_error, abstract_virtuals_error,
- process_init_constructor, check_for_new_type): Likewise.
-
-2000-01-19 Mark Mitchell <mark@codesourcery.com>
-
- * tree.c (bot_manip): Set DECL_CONTEXT for newly created
- VAR_DECLs.
-
-2000-01-18 Nathan Sidwell <sidwell@codesourcery.com>
-
- * cp-tree.h (get_tinfo_fn_dynamic): Remove prototype.
- (build_x_typeid): Likewise.
- (get_tinfo_fn): Likewise.
- (get_tinfo_fn_unused): Rename to ...
- (get_tinfo_decl): ... here.
- * rtti.c (build_headof): Replace logic error with assertion.
- (get_tinfo_fn_dynamic): Rename to ...
- (get_tinfo_decl_dynamic): ... here. Make static. Use
- complete_type_or_else.
- (build_x_typeid): Move into ...
- (build_typeid): ... here. Adjust call to
- get_tinfo_decl_dynamic. Use tinfo_from_decl. Simplify
- throw_bad_typeid expression.
- (get_tinfo_fn_unused): Rename to ...
- (get_tinfo_decl): ... here. Adjust comment.
- (get_tinfo_fn): Delete.
- (tinfo_from_decl): New static function.
- (get_typeid_1): Call get_tinfo_decl and tinfo_from_decl.
- (get_typeid): Use complete_type_or_else.
- (build_dynamic_cast_1): Adjust calls to
- get_tinfo_decl_dynamic. Simplify throw_bad_cast expression.
- * parse.y (primary): Adjust call to build_typeid.
- * except.c (build_eh_type_type_ref): Adjust call to
- get_tinfo_decl. Mark as used.
- * class.c (set_rtti_entry): Adjust call to get_tinfo_decl.
- * decl2.c (build_expr_from_tree): Adjust call to build_typeid.
- * parse.c: Regenerated.
-
-2000-01-17 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (fixed_type_or_null): Don't clear NONNULL. Document
- calling convention.
- (resolves_to_fixed_type_p): Document calling convention.
- * rtti.c (build_x_typeid): Initialize NONNULL.
-
- * cp-tree.h (build_shared_int_cst): New function.
- * call.c (build_over_call): Use DECL_VIRTUAL_CONTEXT, for clarity.
- * class.c (modify_vtable_entry): Likewise.
- (add_virtual_function): Split out code to generated shared
- INTEGER_CSTs to build_share_int_cst.
- (modify_all_vtables): Handle all the overridden functions here.
- Add overridden functions from non-primary virtual bases to the
- primary vtable.
- (finish_struct_1): Adjust call to modify_all_vtables. Add
- overridden functions from non-primary bases to the vtable.
- * tree.c (build_shared_int_cst): New function.
-
- * cp-tree.h (scratchalloc): Remove.
- (build_scratch_list): Likewise.
- * call.c (convert_class_to_reference): Replace build_scratch_list
- and build_expr_list with build_tree_list.
- (add_candidate): Replace scratchalloc with expralloc. Note memory
- leak.
- (build_user_type_conversion_1): Replace build_scratch_list
- and build_expr_list with build_tree_list.
- (build_new_op): Likewise.
- (build_op_delete_call): Likewise.
- (convert_like): Likewise.
- * cvt.c (ocp_convert): Likewise.
- * decl.c (start_decl): Likewise.
- (start_function): Likewise.
- (finish_destructor_body): Likewise.
- (maybe_build_cleanup_1): Likewise.
- * decl2.c (reparse_decl_as_expr): Likewise.
- * init.c (perform_member_init): Likewise.
- (expand_cleanup_for_base): Likewise.
- (build_builtin_delete_call): Likewise.
- (build_new_1): Likewise.
- (build_delete): Likewise.
- * method.c (do_build_assign_ref): Likewise.
- * parse.y (already_scoped_stmt): Likewise.
- (nontrivial_exprlist): Likewise.
- (net_initializer): Likewise.
- (initlist): Likewise.
- * parse.c: Regenerated.
- * rtti.c (build_x_typeid): Likewise.
- (build_dynamic_cast_1): Likewise.
- * typeck.c (build_x_compound_expr): Likewise.
- (build_static_cast): Likewise.
- (build_modify_expr): Likewise.
+ PR c++/12226
+ * call.c (CHECK_COPY_CONSTRUCTOR_P): New macro.
+ (reference_binding): Set it when appropriate.
+ (build_temp): New function, split out from ...
+ (convert_like_real): ... here. Honor CHECK_COPY_CONSTRUCTOR_P.
+ (initialize_reference): Likewise.
- * cp-tree.h (DECL_VINDEX): Add documentation.
- * class.c (build_vtable_entry): Likewise.
- (start_vtable): Add comment.
- (add_virtual_function): Replace pending_hard_virtuals with
- overridden_virtuals and pending_virtuals with new_virtuals.
- Replace redundant assignments with assertions.
- (check_for_override): Add comment.
- (check_bases_and_members): Replace pending_hard_virtuals with
- overridden_virtuals and pending_virtuals with new_virtuals.
- (create_vtbl_ptr): Likewise.
- (layout_class_type): Likewise.
- (finish_struct_1): Likewise. Add comments.
-
-2000-01-16 Mark Mitchell <mark@codesourcery.com>
-
- * class.c (finish_struct_1): Replace redundant code with
- assertions.
-
- * cp-tree.h (flag_new_abi): Move.
- (flag_use_cxa_atexit): Likewise.
- (flag_honor_std): Likewise.
- (flag_rtti): Likewise.
- (vbase_offsets_in_vtable_p): Define.
- (vptrs_present_everywhere_p): Likewise.
- (TYPE_CONTAINS_VPTR_P): Likewise.
- (dfs_walk_real): Declare.
- * class.c (build_vbase_pointer_fields): Check
- vbase_offsets_in_vtable_p.
- (dfs_build_vbase_offset_vtbl_entries): Record the vbase indices in
- BINFO_VPTR_FIELD.
- (build_vbase_offset_vtbl_entries): Simplify.
- (build_vbase_offset_vtbl_entries): Adjust.
- (build_vbase_pointer): Add ability to look up vbase offsets in
- vtable.
- (start_vtable): New function.
- (add_virtual_function): Use it.
- (determine_primary_base): Use TYPE_CONTAINS_VPTR_P.
- (num_extra_vtbl_entries): Use vbase_offsets_in_vtable_p.
- (build_vtbl_initializer): Take the type of the complete object as
- input. Use it to correctly calculate vbase offsets.
- (dfs_finish_vtbls): Pass the complete type to
- build_vtbl_initializer.
- (check_bases_and_members): Use TYPE_CONTAINS_VPTR_P.
- (create_vtable_ptr): Create a vtable even if there are no
- new virtual functions, under the new ABI.
- (finish_struct_1): Likewise.
- (get_vfield_name): Use TYPE_CONTAINS_VPTR_P.
- * decl.c (exapnd_static_init): Remove call to
- preserve_initializer.
- * decl2.c (mark_vtable_entries): Tweak to handle vbase offsets in
- vtables.
- * init.c (initialize_vtbl_ptrs): Initialize them in pre-order.
- (expand_virtual_init): Use vbase_offsets_in_vtable_p.
- (construct_virtual_bases): Don't initialize virtual base pointers
- under the new ABI.
- (build_aggr_init): Clean up comment.
- (expand_aggr_init_1): Likewise.
- * rtti.c (expand_class_desc): Store the virtual function table
- index where the vbase offset lives in the offset field.
- * search.c (dfs_walk_real): Make it global.
- (dfs_debug_mark): Use TYPE_CONTAINS_VPTR_P.
- * tree.c (make_binfo): Don't clear BINFO_VPTR_FIELD.
-
- * tinfo.h (USItype): Make it signed under the new ABI.
- * tinfo.cc (convert_to_base): New function. Encapsulate base
- conversion logic here.
- (__class_type_info::do_upcast): Use it.
- (__class_type_info::do_dyncast): Likewise.
- (__class_type_info::do_find_public_subobj): Likewise.
-
- * init.c (construct_virtual_bases): Don't look up the addresses of
- virtual bases at run-time.
-
- * class.c (build_vbase_pointer): Relocate.
- (build_vbase_pointer_fields): Likewise.
- (dfs_build_vbase_offset_vtbl_entries): Likewise.
- (build_vbase_offset_vtbl_entries): Likewise.
-
- * decl.c (init_decl_processing): Complain if -fnew-abi
- -fno-vtable-thunks is used.
-
- * decl2.c (lang_decode_option): Don't couple flag_honor_std to
- flag_new_abi.
-
-2000-01-15 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (num_extra_vtbl_entries): New function.
- (size_extra_vtbl_entries): Likewise.
- (dfs_vtable_path_unmark): Likewise.
- (dfs_vtable_path_unmarked_real_bases_queue_p): Likewise.
- (dfs_vtable_path_marked_real_bases_queue_p): Likewise.
- * class.c (num_extra_vtbl_entries): New function.
- (size_extra_vtbl_entries): Likewise.
- (dfs_build_vbase_offset_vtbl_entries): New function.
- (build_vbase_offset_vtbl_entries): Likewise.
- (build_vtbl_initializer): Use it.
- (finish_struct_1): Adjust vtable sizes (using
- num_extra_vtbl_entries).
- * expr.c (cplus_expand_expr): Assert that the DECL_RTL for a
- THUNK_DECL is non-NULL before expanding it.
- * init.c (expand_virtual_init): Adjust the vtable pointer by
- size_extra_vtbl_entries before storing it.
- * search.c (get_shared_vase_if_not_primary): Adjust prototype.
- Handle TREE_LIST parameters here, not in the dfs_* functions.
- (dfs_unmarked_real_bases_queue_p): Adjust.
- (dfs_marked_real_bases_queue_p): Likewise.
- (dfs_vtable_path_unmarked_real_bases_queue_p): New function.
- (dfs_vtable_path_marked_real_bases_queue_p): New function.
- (dfs_vtable_path_unmark): Likewise.
-
-2000-01-14 Mark Mitchell <mark@codesourcery.com>
-
- * optimize.c (copy_body_r): Clear the operand three of a
- TARGET_EXPR when copying it.
-
-2000-01-14 Martin v. Löwis <loewis@informatik.hu-berlin.de>
-
- * method.c (build_decl_overload_real): Check whether we are in ::
- before returning __builtin_new/delete.
-
-2000-01-13 Mark Mitchell <mark@codesourcery.com>
-
- * pt.c (tsubst_friend_function): Improve comment.
- (instantiate_decl): Avoid crashing when a "nested" function is
- instantiated from the top level.
-
- * dump.c (dqeueue_and_dump): Dump
- DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION.
-
-2000-01-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * call.c: If GATHER_STATISTICS, declare `n_build_method_call'.
-
-2000-01-13 Nathan Sidwell <sidwell@codesourcery.com>
-
- * g++spec.c (lang_specific_driver): Add -fnew-abi if
- ENABLE_NEW_GXX_ABI defined.
- * Make-lang.in (tinfo.o, tinfo2.o, exception.o, new.o,
- opnew.o, opnewnt.o, opvnew.o, opvnewnt.o, opdel.o, opdelnt.o,
- opvdel.o, opvdelnt.o): Use GXX_ABI_FLAG switch.
-
-2000-01-12 Mark Mitchell <mark@codesourcery.com>
-
- * decl.c (start_cleanup_fn): Call pushdecl.
-
- * call.c (convert_class_to_reference): Fix typos.
- (build_conditional_expr): Handle errors gracefully.
- * class.c (push_nested_class): Likewise.
- * cp-tree.h (VAR_FUNCTION_OR_PARM_DECL_CHECK): New macro.
- (DECL_THIS_EXTERN): Use it.
- (DECL_THIS_STATIC): Likewise.
- * cvt.c (convert_to_void): Handle errors gracefully.
- (build_expr_type_conversion): Likewise.
- * decl.c (maybe_push_decl): Likewise.
- (start_decl_1): Likewise.
- (require_complete_types_for_parms): Likewise.
- * parse.y (structsp): Likewise.
- (base_class): Likewise.
- * parse.c: Regenerated.
- * pt.c (finish_member_template_decl): Likewise.
- * typeck.c (decay_conversion): Likewise.
-
- * cp-tree.h (dfs_skip_vbases): New function.
- (find_vbase_instance): Likewise.
- * class.c (determine_primary_base): Allow a nearly empty base to
- serve as a primary base class under the new ABI.
- (get_class_offset_1): Rename to ...
- (dfs_get_class_offset): ... this. Simplify. Don't issue error
- messages here.
- (get_class_offset): Use it. Issue error messages here.
- (dfs_modify_vtables): Rely on dfs_unmarked_real_bases_queue_p to
- find the right copies of virtual bases.
- (fixup_vtable_deltas1): Rename to ...
- (dfs_fixup_vtable_deltas): ... this. Adjust to handle virtual
- bases as primary bases.
- (fixup_vtable_deltas): Remove.
- (override_one_vtable): Handle virtual bases as primary bases.
- (merge_overrides): Likewise.
- (finish_struct_1): Likewise.
- (dump_class_hierarchy): Dump primary-ness of bases as well.
- * search.c (mark_primary_bases): Use a pre-order traversal to
- handle primary virtual bases.
- (dfs_skip_vbases): New fiunction.
- (expand_upcast_fixups): Adjust to handle primary virtual bases.
- (fixup_virtual_upcast_offsets): Likewise.
- (fixup_all_virtual_upcast_offsets): Likewise.
- (dfs_find_vbase_instances): New function.
- (find_vbase_instance): Likewise.
-
-2000-01-11 Mumit Khan <khan@xraylith.wisc.edu>
-
- * lex.c (DIR_SEPARATOR): Delete macro.
-
-2000-01-12 Gabriel Dos Reis <gdr@codesourcery.com>
-
- * decl2.c (lang_decode_option): Handle automatic line wrapping
- option.
-
-2000-01-11 Mark Mitchell <mark@codesourcery.com>
-
- * friend.c (do_friend): Don't resolve scopes when processing
- template declarations, even if the qualifying scope doesn't
- involve template parameters.
-
-2000-01-10 Mark Mitchell <mitchell@dumbledore.codesourcery.com>
-
- * class.c (dfs_modify_vtables_queue_p): Remove.
- (modify_all_vtables): Use dfs_unmarked_real_bases_queue_p
- and dfs_marked_real_bases_queue_p instead of
- dfs_modify_vtables_queue_p.
-
- * class.c (build_vbase_path): Simplify.
- (dfs_propagate_binfo_offsets): New function.
- (propagate_binfo_offsets): Use it.
- (remove_base_field): Simplify.
- (dfs_set_offset_for_vbases): Remove.
- (dfs_set_offset_for_shared_vbases): New function.
- (dfs_set_offset_for_unshared_vbases): Likewise.
- (layout_virtual_bases): Use them.
- (layout_basetypes): Don't call propagate_binfo_offsets.
- * search.c (dfs_get_vbase_types): Clone completely fresh binfos
- for the vbases.
-
- * class.c (build_base_field): New function, split out from ...
- (build_base_fields): ... here. Use it. Allocate primary bases
- first, under the new ABI.
- (get_vtable_entry): Remove.
- (remove_base_field): New function, split out from ...
- (remove_base_fields): ... here. Adjust since primary bases come
- first under the new ABI.
-
- * cp-tree.h (expand_direct_vtbls_init): Remove declaration.
- (initialize_vtbl_ptrs): New function.
- (expand_indirect_vtbls_init): Change prototype.
- (convert_pointer_to_vbase): Declare.
- * init.c (expand_direct_vtbls_init): Remove.
- (dfs_initialize_vtbl_ptrs): New function.
- (initialize_vtbl_ptrs): Likewise.
- (emit_base_init): Use initialize_vtbl_ptrs.
- * search.c (convert_pointer_to_vbase): Make it global.
- (expand_indirect_vtbls_init): Remove vtable initialization code.
- * semantics.c (setup_vtbl_ptr): Use initialize_vtbl_ptrs.
-
- * class.c (dfs_finish_vtbls): New function.
- (finish_vtbls): Use it.
- (dump_class_hierarchy): New function.
-
- * cp-tree.h (BINFO_PRIMARY_MARKED_P): Change definition.
- (BINFO_VBASE_PRIMARY_P): New macro.
- (BINFO_VIRTUALS): Add to documentation.
- (SET_BINFO_PRIMARY_MARKED_P): Remove.
- (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
- (dfs_mark_primary_bases_queue_p): Likewise.
- (dfs_unmarked_real_bases_queue_p): New function.
- (dfs_marked_real_bases_queue_p): Likewise.
- * search.c (dfs_mark_primary_bases): Adjust.
- (mark_primary_bases): Likewise.
- (get_shared_vbase_if_not_primary): New function.
- (dfs_unmarked_real_bases_queue_p): Likewise.
- (dfs_marked_real_bases_queue_p): Likewise.
- (dfs_get_pure_virtuals): Simplify.
- (get_pure_virtuals): Likewise.
-
-2000-01-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * lex.c: Include tm_p.h.
-
-2000-01-07 Nathan Sidwell <sidwell@codesourcery.com>
-
- * lang-specs.h (__GXX_ABI_VERSION): New preprocessor macro.
-
-2000-01-06 Jason Merrill <jason@casey.cygnus.com>
-
- * decl2.c (comdat_linkage): Don't set DECL_DEFER_OUTPUT.
- * pt.c (instantiate_decl): Defer comdat templates that might not be
- needed.
-
- * cp-tree.h (DECL_NEEDED_P): Also true if !DECL_COMDAT.
- * decl2.c (finish_vtable_vardecl): Don't check !DECL_COMDAT.
- (finish_file): Likewise.
-
- * decl2.c (import_export_class): Undo 12/14 change.
-
- * error.c (dump_decl): operator new, not operatornew.
-
- * class.c (field_decl_cmp): A nontype is "greater" than a type.
- * search.c (lookup_field_1): Look for the last field with the
- desired name.
-
-2000-01-05 Nathan Sidwell <nathan@acm.org>
-
- * decl2.c (lookup_arg_dependent): Deal with FNS not being a
- FUNCTION_DECL.
-
-2000-01-05 Nathan Sidwell <nathan@acm.org>
-
- * typeck.c (build_static_cast): Don't strip target qualifiers
- when casting from a class.
-
-2000-01-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
-
- * class.c (warn_hidden): Initialize variable `fndecl'.
-
-2000-01-03 Ulrich Drepper <drepper@cygnus.com>
-
- * decl.c (flag_isoc9x): New variable to be able to use code in
- c-common.c. For now always zero.
-
-2000-01-03 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (CLASSTYPE_VBASECLASSES): Improve documentation.
- * class.c (layout_basetypes): Don't set BINFO_INHERITANCE_CHAIN
- or unshare_base_binfos for virtual bases here.
- * search.c (dfs_get_vbase_types): Do it here.
- (get_vbase_types): Adjust.
-
-2000-01-02 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (CLASSTYPE_VFIELDS): Move definition.
- (BINFO_PRIMARY_MARKED_P): Use flag 5.
- (SET_BINFO_PRIMARY_MARKED_P): Likewise.
- (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
- (unmark_primary_bases): Remove declaration.
- (unmarkedp): Declare.
- (dfs_vbase_unmark): Likewise.
- * class.c (determine_primary_base): Return immediately if there
- are no base classes. Call mark_primary_bases here.
- (modify_all_direct_vtables): Remove.
- (modify_all_indirect_vtables): Remove.
- (dfs_modify_vtables_queue_p): New function.
- (dfs_modify_vtables): New function.
- (modify_all_vtables): Use them.
- (build_base_fields): Build FIELD_DECLs for primary virtual base
- classes.
- (create_vtable_ptr): Don't call determine_primary_base here.
- (dfs_mark_primary_bases_and_set_vbase_offsets): Rename to ...
- (dfs_set_offset_for_vbases): ... this.
- (layout_virtual_bases): Use it.
- (layout_class_type): Call determine_primary_base here.
- * search.c (unmarkedp): Make it global.
- (shared_marked_p): Simplify.
- (shared_unmarked_p): Likewise.
- (dfs_primary_bases_queue_p): Remove.
- (dfs_unmark_primary_bases): Likewise.
- (unmark_primary_bases): Likewise.
- (mark_primary_bases): Simplify.
- (get_pure_virtuals): Don't call mark_primary_bases here.
- (dfs_vbase_unmark): New function.
- (get_vbase_types): Simplify.
-
- * class.c (struct base_info): Remove.
- (determine_primary_base): Take has_virtual_p rather than a
- base_info as input. Don't calculate max_has_virtual.
- (finish_struct_bits): Remove max_has_virtual argument.
- (create_vtable_ptr): Remove max_has_virtual_p argument.
- (layout_virtual_bases): Remove max argument.
- (layout_basetypes): Likewise.
- (layout_class_type): Remove max_has_virtual_p argument.
- (finish_struct_1): Remove max_has_virtual.
-
- * cp-tree.h (dfs_mark_primary_bases_queue_p): New function.
- (layout_basetypes): Remove.
- * class.c (propagate_binfo_offsets): Moved here from tree.c.
- Update to handle primary virtual bases.
- (remove_base_fields): New function, split out from
- layout_basetypes.
- (dfs_mark_primary_bases_and_set_vbase_offsets): New function.
- (layout_virtual_bases): New function, split out from
- layout_basetypes. Update to handle primary virtual bases.
- (layout_basetypes): Moved here from tree.c. Use
- remove_base_fields and layout_virtual_bases.
- * search.c (dfs_mark_primary_bases_queue_p): New function.
- (mark_primary_bases): Use it.
- * tree.c (CEIL): Remove.
- (propagate_binfo_offsets): Remove.
- (layout_basetypes): Remove.
-
-2000-01-01 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (CLASSTYPE_N_BASECLASSES): Use BINFO_N_BASETYPES.
- (BINFO_PRIMARY_MARKED_P): New macro.
- (SET_BINFO_PRIMARY_MARKED_P): Likewise.
- (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
- (mark_primary_bases): New function.
- (unmark_primary_bases): Likewise.
- * search.c (get_abstract_virtuals_1): Remove.
- (dfs_mark_primary_bases): New function.
- (mark_primary_bases): Likewise.
- (dfs_unmark_primary_bases): Likewise.
- (unmark_primary_bases): Likewise.
- (dfs_get_pure_virtuals): Likewise.
-
-2000-01-01 Mark Mitchell <mark@codesourcery.com>
-
- * cp-tree.h (skip_rtti_stuff): Adjust prototype.
- * class.c (skip_rtti_stuff): Reorganize parameters and return value.
- (modify_one_vtable): Adjust.
- (fixup_vtable_deltas1): Likewise.
- (override_one_vtable): Likewise.
- * search.c (get_abstract_virtuals_1): Likewise.
- (get_pure_virtuals): Likewise.
- (expand_upcast_fixups): Likewise.
- * tree.c (debug_binfo): Likewise.
-
- * class.c (build_vtable): Don't return a value. Don't rebuild
- vtables for bases that have already been handled.
- (prepare_fresh_vtable): Don't rebuild vtables for bases that have
- already been handled.
- (modify_one_vtable): Adjust accordingly.
- (fixup_vtable_deltas1): Likewise.
- (finish_struct_1): Likewise.
-
-2000-01-01 Martin v. Löwis <loewis@informatik.hu-berlin.de>
-
- * call.c (build_new_method_call): Also check destructors.
+ PR c++/13536
+ * parser.c (cp_parser): Add in_type_id_in_expr_p.
+ (cp_parser_new): Initialize it.
+ (cp_parser_postfix_expression): Set it.
+ (cp_parser_sizeof_operand): Likewise.
+ (cp_parser_parameteR_declaration): Do not commit early to tenative
+ parsers when in_type_id_in_expr_p is set.
+
+2004-01-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13094
+ * parser.c (cp_parser_template_argument): Don't call
+ make_unbound_class_template directly.
+ (cp_parser_lookup_name): Don't extract TEMPLATE_DECL from
+ UNBOUND_CLASS_TEMPLATE tree node.
+
+2004-01-02 Richard Sandiford <rsandifo@redhat.com>
+
+ PR target/12729
+ * method.c (use_thunk): Pass the CALL_EXPR through force_target_expr.
+
+2004-01-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13520
+ * cp-tree.h (DECL_UNBOUND_CLASS_TEMPLATE_P): New macro.
+ (DECL_FUNCTION_TEMPLATE_P): Use it.
+ (DECL_CLASS_TEMPLATE_P): Likewise.
+ * parser.c (cp_parser_lookup_name): Add is_template parameter.
+ (cp_parser_type_parameter): Adjust call to cp_parser_lookup_name.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_namespace_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_lookup_name_simple): Likewise.
+
+See ChangeLog.3 for earlier changes.
diff --git a/contrib/gcc/cp/ChangeLog.1 b/contrib/gcc/cp/ChangeLog.1
index 4b4afd315262..01ef399698c6 100644
--- a/contrib/gcc/cp/ChangeLog.1
+++ b/contrib/gcc/cp/ChangeLog.1
@@ -1386,7 +1386,7 @@ Wed May 10 00:55:59 1995 Jason Merrill <jason@phydeaux.cygnus.com>
Tue May 9 19:10:33 1995 Mike Stump <mrs@cygnus.com>
* decl2.c: Add flag_new_for_scope for new -ffor-scope flag.
- * parse.y (FOR): Conditionalize the pushing and poping of scope for
+ * parse.y (FOR): Conditionalize the pushing and popping of scope for
the for-init-statement upon the new flag_new_for_scope.
* parse.y (try_block): Simplify and use compstmt.
@@ -7211,7 +7211,7 @@ Thu Mar 31 19:50:35 1994 Jason Merrill <jason@deneb.cygnus.com>
Thu Mar 31 16:20:16 1994 Kung Hsu <kung@mexican.cygnus.com>
* decl2.c (grok_func_init): Do not abort as rtl for pur virtual
- fucntions. They can be defined somewhere else.
+ functions. They can be defined somewhere else.
Sat Jan 23 23:23:26 1994 Stephen R. van den Berg <berg@pool.informatik.rwth-aachen.de>
diff --git a/contrib/gcc/cp/ChangeLog.2 b/contrib/gcc/cp/ChangeLog.2
index 26dc387a37ea..c4d6880a00d9 100644
--- a/contrib/gcc/cp/ChangeLog.2
+++ b/contrib/gcc/cp/ChangeLog.2
@@ -13405,7 +13405,7 @@ Tue Jan 27 16:42:21 1998 Mark Mitchell <mmitchell@usa.net>
(classtype_mangled_name): Likewise.
(lookup_template_class): Likewise.
(tsubst): Likewise.
- (more_specialized): Take explict template arguments as a
+ (more_specialized): Take explicit template arguments as a
parameter.
(most_specialized): Likewise.
(get_bindings): Likewise. Check that return types match before
@@ -13627,7 +13627,7 @@ Mon Jan 19 22:40:03 1998 Mark Mitchell <mmitchell@usa.net>
(instantiate_template): Use retrieve_specialization.
(do_decl_instantiation): Likewise.
(instantiate_decl): Likewise.
- (type_unification): Improve handling of explict template
+ (type_unification): Improve handling of explicit template
arguments.
* tree.c (mapcar): Return error_mark_node, rather than aborting,
on VAR_DECLS, FUNCTION_DECLS, and CONST_DECLS.
@@ -20213,7 +20213,7 @@ Tue Jan 16 11:39:40 1996 Jason Merrill <jason@yorick.cygnus.com>
Tue Jan 16 11:09:42 1996 Mike Stump <mrs@cygnus.com>
- * decl.c (poplevel): When poping a level, don't give a warning for
+ * decl.c (poplevel): When popping a level, don't give a warning for
any subblocks that already exist.
Tue Jan 16 00:25:33 1996 Jason Merrill <jason@yorick.cygnus.com>
@@ -20673,3 +20673,5 @@ Wed Oct 11 16:30:34 1995 Brendan Kehoe <brendan@lisa.cygnus.com>
* parse.y (fn.def1): Call split_specs_attrs in
declmods notype_declarator case.
+
+See ChangeLog.1 for earlier changes.
diff --git a/contrib/gcc/cp/ChangeLog.3 b/contrib/gcc/cp/ChangeLog.3
new file mode 100644
index 000000000000..995175cf677d
--- /dev/null
+++ b/contrib/gcc/cp/ChangeLog.3
@@ -0,0 +1,22648 @@
+2003-12-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/13507
+ * decl.c (duplicate_decls): Use build_type_attribute_variant to
+ merge attributes.
+
+ PR c++/13494
+ * tree.c (build_cplus_array_type_1): Only build a minimal array
+ type for dependent types or domains.
+
+2003-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12774
+ * typeck.c (comp_array_types): Fold non-dependent domains for
+ ABI-1.
+
+2003-12-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13289
+ * semantics.c (finish_id_expression): Only check if the type of
+ a template argument is integral or enumeration when it is not
+ dependent.
+
+2003-12-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12403
+ * parser.c (cp_parser_template_declaration_after_export): Set up
+ template specialization scope in case of explicit specialization.
+
+2003-12-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13081
+ * decl.c (duplicate_decls): Preserve inline-ness when redeclaring
+ a function template.
+
+ PR c++/12613
+ * decl.c (reshape_init): Reject GNU colon-style designated
+ initializers in arrays.
+
+ PR c++/13009
+ * call.c (build_special_member_call): Do not assume that we have a
+ pointer to the complete object in an assignment operator.
+
+2003-12-28 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/13070
+ * decl.c (duplicate_decls): When setting the type of an anticipated
+ declaration, merge the existing type attributes.
+
+2003-12-25 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/13268, c++/13339
+ * class.c (add_method): Return early when method is error_mark_node.
+ * pt.c (tsubst_friend_function): Return early when new_friend is
+ error_mark_node.
+
+2003-12-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-lang.c (cp_expr_size): Return zero for empty classes.
+
+ * cp-tree.h (warn_if_uknown_interface): Remove unused function.
+ * decl2.c (warn_if_unknown_interface): Likewise.
+
+2003-12-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/13387
+ * cp-lang.c (cxx_get_alias_set): Correct logic for a base type.
+
+2003-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_function): Do not check
+ flag_alt_external_templates or flag_external_templates.
+ * decl2.c (warn_if_unknown_interface): Likewise.
+ * lex.c (extract_interface_info): Likewise.
+ * pt.c (lookup_template_class): Likewise.
+
+ PR c++/12862
+ * name-lookup.c (pushdecl): Look up all namespace-scope entities
+ in their corresponding namespace.
+
+ PR c++/12397
+ * typeck.c (finish_class_member_access_expr): Don't tree
+ IDENTIFIER_NODEs as non-dependent expressions.
+
+2003-12-22 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/5050
+ * tree.c (cp_start_inlining): Remove.
+ (cp_end_inlining): Remove.
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING): Do not define.
+ (LANG_HOOKS_TREE_INLINING_END_INLINING): Do not define.
+ * cp-tree.h (cp_start_inlining): Do not declare.
+ (cp_end_inlining): Do not declare.
+
+2003-12-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12479
+ * parser.c (cp_parser_declaration_seq_opt): Only issue "extra ;"
+ pedwarn when not in a system header.
+
+2003-12-21 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Remove CPTI_RECORD_TYPE,
+ CPTI_UNION_TYPE, CPTI_ENUM_TYPE.
+ (record_type_node): Remove.
+ (union_type_node): Likewise.
+ (enum_type_node): Likewise.
+ * decl.c: Remove mention of above tree nodes in comment.
+ * lex.c (cxx_init): Do not assign to record_type_node,
+ union_type_node, or enum_type_node. Simplify handling of
+ class_type_node.
+
+ PR c++/11554
+ * init.c (sort_mem_initializers): Add warning.
+
+2003-12-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment formatting.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * cxx-pretty-print.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * error.c: Likewise.
+ * except.c: Likewise.
+ * init.c: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * semantics.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2003-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cvt.c: Remove uses of "register" specifier in
+ declarations of arguments and local variables.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * expr.c: Likewise.
+ * friend.c: Likewise.
+ * lex.c: Likewise.
+ * name-lookup.c: Likewise.
+ * repo.c: Likewise.
+ * search.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2003-12-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12795
+ * name-lookup.c (pushdecl): Do not treated any functions as being
+ "nested" in C++.
+
+2003-12-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/13371
+ * typeck.c (build_modify_expr): Stabilize lhs if we're narrowing.
+ * cvt.c (convert_to_void): Don't warn about the RHS of a comma
+ being useless if TREE_NO_UNUSED_WARNING is set.
+
+2003-12-18 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h (struct lang_type_header): Remove __extension__.
+
+2003-12-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/12253
+ * init.c (build_vec_init): Initialization of an element from
+ an initializer list is also a full-expression.
+
+ * parser.c, pt.c, semantics.c: Rename constant_expression_p
+ to integral_constant_expression_p.
+
+2003-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13262
+ * pt.c (instantiate_decl): Wrap push_nested_class and
+ pop_nested_class around cp_finish_decl call for static member
+ variable.
+
+2003-12-18 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/9154
+ * parser.c (cp_parser_template_argument): A type-id followed by '>>'
+ is just an user typo, and should be accepted as last resort if any
+ other parsing fails.
+ (cp_parser_enclosed_template_argument_list): If the argument list is
+ parsed correctly, but the next token is '>>', emit a diagnostic.
+ (cp_parser_next_token_ends_template_argument): Accept '>>' as
+ delimiter of template argument, it will be later detected as a typo.
+
+2003-12-17 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in: Replace cp/g++.1 with $(docobjdir)/g++.1.
+
+2003-12-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10603
+ PR c++/12827
+ * parser.c (cp_parser_error): Help c_parse_error print good
+ messages if the next token is a keyword.
+ (cp_parser_parameter_declaration_list): When resynchronizing after
+ a bad parameter declaration, stop if a comma is found.
+ (cp_parser_parameter_declaration): Avoid backtracking.
+
+2003-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12696
+ * decl.c (reshape_init): Recover quickly from errors.
+
+2003-12-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9043
+ C++ ABI change: Mangling array indices in templates.
+ * decl.c (compute_array_index_type): Reorganize for earlier
+ template errors. Use value_dependent_expression_p for abi-2.
+ * mangle.c (write_array_type): Check broken mangling for
+ expression indices on abi-1
+
+2003-12-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12696
+ * decl.c (reshape_init): Recover quickly from errors.
+
+ PR c++/13275
+ * lex.c (reswords): Add "__offsetof" and "__offsetof__".
+ * parser.c (cp_parser): Add in_offsetof_p.
+ (cp_parser_new): Initialize it.
+ (cp_parser_primary_expression): Handle __offsetof__ (...).
+ (cp_parser_postfix_expression): Allow casts to pointer type and
+ uses of "->" in a constant expression if implementing offsetof.
+ (cp_parser_unary_expression): Allow the use of "&" in a constant
+ expression if implementing offsetof.
+
+2003-12-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/2294
+ * name-lookup.c (push_overloaded_decl): always construct an OVERLOAD
+ if the declaration comes from an using declaration.
+
+2003-12-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * semantics.c (finish_id_expression): Refactor the code to handle
+ template parameters, and emit a more informative error message
+ when they are used within an integral constant expression.
+
+2003-12-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/13387
+ * class.c (finish_struct_1): Compute mode and alias set for
+ CLASSTYPE_AS_BASE.
+ * call.c (build_over_call): Use CLASSTYPE_AS_BASE for trivial
+ assignment of a class, as necessary.
+ * cp-lang.c (cxx_get_alias_set): The alias set as a base is the
+ same as for the complete type.
+
+ PR c++/13242
+ C++ ABI change. Mangling template parameters of reference type
+ * mangle.c (write_template_args): Remove unreachable code.
+ (write_template_arg): Look through an argument of reference type.
+
+2003-12-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/2294
+ * name-lookup.c (push_overloaded_decl): always construct an OVERLOAD
+ if the declaration comes from an using declaration.
+
+2003-12-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10926
+ * decl2.c (grokfield): Robustify.
+
+ PR c++/11116
+ * parser.c (cp_parser_throw_expression): Determine whether or not
+ an assignment-expression is present by doing one-token lookahead.
+
+ PR c++/13269
+ * parser.c (cp_parser_function_definition_after_declarator): Stop
+ scanning tokens when reaching EOF.
+
+ PR c++/12989
+ * typeck.c (cxx_sizeof_or_alignof_expr): Robustify.
+
+ PR c++/13310
+ * pt.c (dependent_template_p): Handle OVERLOADs.
+
+2003-12-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13243
+ PR c++/12573
+ * parser.c (cp_parser_postfix_expression): Tighten handling of
+ integral constant expressions.
+ (cp_parser_unary_expression): Likewise.
+ * pt.c (value_dependent_expression_p): Remove handling for
+ COMPONENT_REFs.
+
+2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (add_method): Disallow destructor for java classes.
+ * decl.c (xref_basetypes): Check java class inheritance.
+ * decl2.c (check_java_method): Skip artificial params.
+
+ PR c++/13241
+ C++ ABI change. Mangling of symbols in expressions.
+ * mangle.c (write_mangled_name): Add top_level flag. Rework for
+ nested and unnested mangling. Deal with abi version 1 and version
+ 2 differences.
+ (write_expression): Adjust write_mangled_name call.
+ (mangle_decl_string): Use write_mangled_name for all non-type decls.
+
+2003-12-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10779
+ PR c++/12160
+ * parser.c (struct cp_parser): Add in_template_argument_list_p.
+ (cp_parser_error): Use c_parse_error.
+ (cp_parser_name_lookup_error): New function.
+ (cp_parser_new): Initialize it.
+ (cp_parser_declarator): Add parenthesized_p parameter.
+ (cp_parser_nested_name_specifier_opt): Use
+ cp_parser_name_lookup_error.
+ (cp_parser_parenthesized_expression_list): Improve comments.
+ (cp_parser_condition): Adjust call to cp_parser_declarator.
+ (cp_parser_template_parameter): Adjust call to
+ cp_parser_parameter_declaration.
+ (cp_parser_template_argument_list): Set
+ in_template_argument_list_p.
+ (cp_parser_explicit_instantiation): Adjust call to
+ cp_parser_declarator.
+ (cp_parser_simple_type_specifier): Remove unncessary code.
+ (cp_parser_using_declaration): Use cp_parser_name_lookup_error.
+ (cp_parser_init_declarator): Handle member function definitions.
+ (cp_parser_direct_declarator): Adjust call to
+ cp_parser_declarator.
+ (cp_parser_type_id): Adjust call to cp_parser_declarator.
+ (cp_parser_parameter_declaration_list): Avoid backtracking where
+ possible.
+ (cp_parser_parameter_declaration): Add parenthesized_p parameter.
+ (cp_parser_function_definition): Remove.
+ (cp_parser_member_declaration): Do not backtrack to look for
+ function definitions.
+ (cp_parser_exception_declaration): Adjust call to
+ cp_parser_declarator.
+ (cp_parser_single_declaration): Handle function definitions via
+ cp_parser_init_declarator.
+ (cp_parser_save_member_function_body): New function.
+
+2003-12-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13106
+ * decl.c (finish_function): Check if return type is dependent before
+ issuing no return statement warning.
+
+2003-12-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/13118
+ * cp-tree.h (lang_decl_u): Add thunk_alias member.
+ (THUNK_VIRTUAL_OFFSET): Must be a FUNCTION_DECL.
+ (THUNK_ALIAS_P): Remove.
+ (THUNK_ALIAS): Adjust.
+ * class.c (update_vtable_entry_for_fn): Get the vbase within the
+ overriding function's return type.
+ (dump_thunk): Adjust THUNK_ALIAS printing.
+ (build_vtbl_initializer): Adjust THUNK_ALIAS use.
+ * method.c (make_thunk): Revert 12881 test change. Clear
+ THUNK_ALIAS.
+ (finish_thunk): Adjust THUNK_ALIAS setting.
+ (use_thunk): Adjust THUNK_ALIAS use.
+ * semantics.c (emit_associated_thunks): Likewise.
+
+ PR c++/13114, c++/13115
+ * class.c (layout_empty_base): Propagate the move of an empty base
+ to offset zero.
+
+ PR c++/12881
+ * method.c (make_thunk): Deal with thunk aliases when searching
+ for a thunk. Robustify assertion.
+
+2003-12-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * mangle.c (conv_type_names): Holds IDENTIFIER_NODEs only.
+ (hash_type): Use TYPE_UID of the identifier's type.
+ (compare_type): Adjust.
+ (mangle_conv_op_name_for_type): Store identifier nodes only, use
+ TYPE_UID has hash value.
+
+2003-12-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_CONV_FN_P): Check that DECL_NAME is non-NULL.
+
+2003-12-08 Matt Austern <austern@apple.com>
+
+ PR c/13134
+ * decl.c (duplicate_decls): Copy visibility flag when appropriate.
+
+2003-12-09 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * init.c (build_new_1): Deal with an OVERLOAD set when
+ looking up for _Jv_AllocObject.
+ * except.c (build_throw): Likewise for _Jv_Throw.
+
+2003-12-08 Jason Merrill <jason@redhat.com>
+
+ PR c++/11971
+ * tree.c (build_local_temp): Split out from build_cplus_new.
+ (force_target_expr): New fn.
+ * call.c (call_builtin_trap): Call it. Take a type parm.
+ (convert_arg_to_ellipsis): Pass it.
+ (build_x_va_arg): Use call_builtin_trap.
+
+ PR c++/11929
+ * call.c (magic_varargs_p): New fn.
+ (build_over_call): Do no ellipsis conversions for arguments to
+ functions with magic varargs.
+
+ * name-lookup.c, init.c, except.c: Revert Giovanni's patch from
+ yesterday.
+
+ Give the anonymous namespace a null DECL_NAME.
+ * cp-tree.h: Don't declare anonymous_namespace_name.
+ * decl.c: Don't define it.
+ * dump.c (cp_dump_tree): Don't check for it.
+ * cxx-pretty-print.c (pp_cxx_original_namespace_definition): Likewise.
+ * error.c (dump_decl): Likewise.
+ * name-lookup.c: Define it here.
+ (push_namespace): Put it in DECL_ASSEMBLER_NAME instead.
+ * mangle.c (write_unqualified_name): Adjust.
+
+2003-12-07 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/2294
+ * name-lookup.c (push_overloaded_decl): Always construct an
+ OVERLOAD unless the declaration is a built-in.
+ (set_namespace_binding): While binding OVERLOADs with only one
+ declaration, we still need to call supplement_binding.
+ * init.c (build_new_1): Deal with an OVERLOAD set when
+ looking up for _Jv_AllocObject.
+ * except.c (build_throw): Likewise for _Jv_Throw.
+
+2003-12-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13323
+ * class.c (same_signature_p): Handle conversion operators
+ correctly.
+ (check_for_override): Likewise.
+
+2003-12-06 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in (GXX_CROSS_NAME, CXX_CROSS_NAME): Delete.
+ (c++.install_common, cp/g++.1, c++.install-man): Adjust for above.
+ (c++.uninstall): Likewise.
+
+2003-12-05 Danny Smith <dannysmith@gcc.gnu.org>
+ Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13305
+ * parser.c (cp_parser_elaborated_type_specifier): Accept
+ attributes.
+
+2003-12-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13314
+ * parser.c (cp_parser_class_specifier): Match push_scope/pop_scope
+ calls.
+ (cp_parser_class_head): Likewise.
+
+2003-12-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/13166
+ * parser.c (cp_parser_late_parsing_default_args): Make sure the
+ context is a class before calling push_nested_class and
+ pop_nested_class.
+
+2003-12-03 James E Wilson <wilson@specifixinc.com>
+
+ * g++spec.c (lang_specific_driver): Delete USE_LIBUNWIND_EXCEPTIONS
+ support.
+
+2003-12-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9127
+ * cp-tree.h (at_namespace_scope_p): New function.
+ * parser.c (cp_parser_class_head): Handle invalid explicit
+ specializations.
+ * search.c (at_namespace_scope_p): New function.
+
+ PR c++/13179
+ * semantics.c (finish_handler_parms): Do not call eh_type_info for
+ types used in templates.
+
+ PR c++/10771
+ * parser.c (cp_parser_check_for_invalid_template_id): New
+ function.
+ (cp_parser_simple_type_specifier): Use it.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_class_head): Likewise.
+
+2003-12-02 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/10126
+ * pt.c (convert_nontype_argument): Handle default conversions
+ while converting a pointer to member function.
+
+2003-12-02 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ PR c++/12573
+ * pt.c (value_dependent_expression_p): Handle COMPONENT_REFs by
+ looking into them recursively.
+
+2003-12-02 Richard Henderson <rth@redhat.com>
+
+ * name-lookup.h (struct cp_binding_level): Use ENUM_BITFIELD.
+ * parser.c (struct cp_token): Likewise.
+ (struct cp_parser_token_tree_map_node): Likewise.
+ * lex.c (struct resword): Move const after ENUM_BITFIELD.
+
+2003-11-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9849
+ * parser.c (cp_lexer_prev_token): New function.
+ (cp_parser_skip_to_closing_parenthesis): Add consume_paren
+ parameter.
+ (cp_parser_nested_name_specifier_opt): Add is_declaration
+ parameter.
+ (cp_parser_nested_name_specifier): Likewise.
+ (cp_parser_class_or_namespace_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_template_id): Likewise.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_id_expression): Adjust calls to
+ cp_parser_nested_name_specifier_op, cp_parser_template_id,
+ cp_parser_class_name.
+ (cp_parser_unqualified_id): Likewise.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_pseudo_destructor_name): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_mem_initializer_id): Likewise.
+ (cp_parser_simple_type_specifier): Likewise.
+ (cp_parser_type_name): Likewise.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_qualified_namespace_specifier): Likewise.
+ (cp_parser_using_declaration): Likewise.
+ (cp_parser_using_directive): Likewise.
+ (cp_parser_ptr_operator): Likewise.
+ (cp_parser_declarator_id): Likewise.
+ (cp_parser_class_head): Likewise.
+ (cp_parser_base_specifier): Likewise.
+ (cp_parser_constructor_declarator_p): Likewise.
+ (cp_parser_direct_declarator): Fix typo in comment.
+ (cp_parser_parenthesized_expression_list): Adjust call to
+ cp_parser_skip_to_closing_parenthesis.
+ (cp_parser_selection_statement): Likewise.
+
+2003-11-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12924
+ * typeck.c (finish_class_member_access_expr): Handle TEMPLATE_ID_EXPR
+ with OVERLOAD and DECL nodes as the first operand.
+
+2003-11-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (tsubst) <ARRAY_REF>: Remove erroneous argument to build_nt.
+
+2003-11-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/5369
+ * friend.c (is_friend): Handle member function of a class
+ template as template friend.
+ (do_friend): Likewise.
+ * decl2.c (check_classfn): Add template_header_p parameter.
+ * decl.c (start_decl): Adjust check_classfn call.
+ (grokfndecl): Likewise.
+ * pt.c (is_specialization_of_friend): New function.
+ (uses_template_parms_level): Likewise.
+ (push_template_decl_real): Use uses_template_parms_level.
+ (tsubst_friend_function): Adjust check_classfn call.
+ * cp-tree.h (check_classfn): Adjust declaration.
+ (uses_template_parms_level): Add declaration.
+ (is_specialization_of_friend): Likewise.
+
+2003-11-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12515
+ * pt.c (build_non_dependent_expr): Handle GNU extension to ?:
+ operator.
+
+2003-11-21 Jan Hubicka <jh@suse.cz>
+
+ * parser.c (cp_parser_postfix_expression): Initialize 's' to
+ NULL_TREE.
+
+2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Make-lang.in (c++.extraclean): Delete.
+
+2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Make-lang.in (check-g++, lang_checks): Add.
+
+2003-11-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12932
+ * class.c (currently_open_derived_class): Check if
+ current_class_type is NULL_TREE.
+ * semantics.c (finish_call_expr): Check if
+ currently_open_derived_class returns NULL_TREE.
+ * cp-tree.h (DERIVED_FROM_P): Add parenthesis around PARENT
+ parameter.
+
+2003-11-17 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Preevaluate placement args.
+ * call.c (build_op_delete_call): Don't expose placement args to
+ overload resolution.
+
+2003-11-16 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (c++.tags): Create TAGS.sub files in each directory
+ and TAGS files that include them for each front end.
+
+2003-11-15 Bernardo Innocenti <bernie@develer.com>
+
+ PR c++/2294
+ * name-lookup.c: Revert previous patch for PR c++/2294 to prevent
+ build failure on libjava.
+
+2003-11-14 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/2294
+ * name-lookup.c (push_overloaded_decl): Always construct an OVERLOAD
+ unless the declaration is a built-in.
+ (set_namespace_binding): While binding OVERLOADs with only one
+ declaration, we still need to call supplement_binding.
+
+2003-11-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12762
+ * parser.c (cp_parser_enclosed_template_argument_list): New
+ function.
+ (cp_parser_template_id): Use it.
+ (cp_parser_simple_type_specifier): Recognize invalid template
+ syntax.
+
+2003-11-14 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/2094
+ * pt.c (unify): Add support for PTRMEM_CST and
+ FIELD_DECL unification.
+
+2003-11-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * decl.c (grokfndecl): Change OK to type tree.
+
+2003-11-12 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (build_target_expr_with_type): Treate VA_ARG_EXPR like
+ CONSTRUCTOR.
+
+ * decl.c (cp_make_fname_decl): When creating a top-level
+ __FUNCTION__-like symbol, do register it with pushdecl.
+
+ * decl.c (finish_case_label): Do not check that we are within a
+ switch statement here.
+ * parser.c (struct cp_parser): Add in_iteration_statement_p and
+ in_switch_statement_p.
+ (cp_parser_new): Initialize them.
+ (cp_parser_labeled_statement): Check validity of case labels
+ here.
+ (cp_parser_selection_statement): Set in_switch_statement_p.
+ (cp_parser_iteration_statement): Set in_iteration_statement_p.
+ (cp_parser_jump_statement): Check validity of break/continue
+ statements here.
+
+ PR c++/12735
+ * cp-tree.h (duplicate_decls): Return a tree.
+ * decl.c (duplicate_decls): Clarify documentation. Return
+ error_mark_node to indicate a failed redeclaration.
+ * friend.c (do_friend): Handle that case.
+ * name-lookup.c (pushdecl): Likewise.
+
+2003-11-11 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_NAMESPACE_ASSOCIATIONS): New macro.
+ * name-lookup.c (parse_using_directive): New fn.
+ (is_associated_namespace): New fn.
+ (arg_assoc_namespace): Also check associated namespaces.
+ * name-lookup.h: Declare new fns.
+ * pt.c (maybe_process_partial_specialization): Allow
+ specialization in associated namespace.
+ * parser.c (cp_parser_using_directive): Accept attributes. Use
+ parse_using_directive.
+
+2003-11-10 Richard Henderson <rth@redhat.com>
+
+ * cvt.c (convert_to_void): Use void_zero_node after overload failure.
+
+2003-11-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/12832
+ * name-lookup.c (supplement_binding): Gracefully handle names
+ used at non-class scope prior declaration.
+
+2003-11-06 Matt Austern <austern@apple.com>
+
+ * decl.c (duplicate_decls): copy DECL_VISIBILITY field.
+ * method.c (use_thunk): give thunk same visibility as function.
+ * optimize.c (maybe_clone_body): copy DECL_VISIBILITY field.
+
+2003-11-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11616
+ * pt.c (instantiate_pending_templates): Save and restore
+ input_location.
+
+2003-11-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/2019
+ * friend.c (add_friend): Don't display previous declaration in
+ case of duplicate friend warning.
+
+2003-11-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9810
+ * call.c (build_over_call): Check access using primary template
+ if FN is a member function template.
+
+2003-11-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12796
+ * class.c (handle_using_decl): Set input_location before calling
+ error_not_base_type.
+
+2003-10-26 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10371
+ * semantics.c (finish_non_static_data_member): Handle when
+ both processing_template_decl and qualifying_scope are true.
+
+2003-10-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11076
+ * class.c (handle_using_decl): Swap arguments of error_not_base_type.
+ * parser.c (cp_parser_direct_declarator): Only resolve typename for
+ namespace scope declarations.
+
+2003-10-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12698, c++/12699, c++/12700, c++/12566
+ * cp-tree.h (THUNK_ALIAS_P, THUNK_ALIAS): New.
+ (debug_class, debug_thunks): New.
+ * class.c (dump_class_hierarchy_1): New break out from ...
+ (dump_class_hierarchy): ... here.
+ (dump_thunk, debug_thunks, debug_class): New.
+ (update_vtable_entry_for_fn): Add ssizetype casts. Correct
+ continued search for primary binfo via virtual.
+ (build_vtbl_initializer): Follow covariant thunk alias.
+ * method.c (make_thunk): Clear DECL_THUNKS of the thunk.
+ (finish_thunk): Look for an alias of the covariant thunk and point
+ to it.
+ (use_thunk): We should never use an alias.
+ * semantics.c (emit_associated_thunks): Do not emit aliases.
+
+ PR c++/12566
+ * cp-tree.h (cp_fname_init): Add TYPE pointer param.
+ * decl.c (cp_fname_init): Add TYPE pointer param. Set it. Don't
+ create an ad-hoc ERROR_MARK.
+ (cp_make_fname_decl): Adjust.
+ * pt.c (tsubst_expr): Adjust.
+
+2003-10-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/12726
+ * tree.c (build_target_expr_with_type): Don't call force_rvalue
+ for CONSTRUCTORs.
+
+2003-10-22 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment formatting.
+ * class.c: Likewise.
+ * cxx-pretty-print.c: Likewise.
+ * init.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2003-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11962
+ * typeck.c (build_x_conditional_expr): Handle missing middle
+ operands in templates.
+ * mangle.c (write_expression): Issue errors about attempts to
+ mangle a non-existant middle operator to the ?: operator.
+
+2003-10-21 Robert Bowdidge <bowdidge@apple.com>
+ * decl.c (cp_finish_decl): Remove clause intended for asm directives
+ in struct or class fields: this code is never executed.
+
+2003-10-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl.c (start_decl): Exit if push_template_decl returns
+ error_mark_node.
+
+2003-10-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Fix typos.
+ * call.c: Fix comment typos.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * cxx-pretty-print.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * init.c: Likewise.
+ * mangle.c: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2003-10-20 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (start_cleanup_fn): Set DECL_DECLARED_INLINE_P to deffer
+ the expansion.
+
+2003-10-20 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (c++.install-info): Remove.
+
+2003-10-20 Jason Merrill <jason@redhat.com>
+
+ * class.c (layout_class_type): Set DECL_ARTIFICIAL on padding
+ field.
+
+2003-10-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9781, c++/10583, c++/11862
+ * decl.c (cp_finish_decl): Exit immediately if decl is an
+ error_mark_node.
+ * pt.c (push_template_decl_real): Return error_mark_node for
+ invalid template declaration of variable.
+
+2003-10-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/12495
+ * pt.c (lookup_template_class): Handle when current_class_type
+ is a local class.
+
+2003-10-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/2513
+ * decl.c (make_typename_type): Use dependent_type_p.
+ (make_unbound_class_template): Likewise.
+ * pt.c (instantiate_class_template): Increment
+ processing_template_decl during substitution of template friend
+ function. Preincrement processing_template_decl rather than
+ postincrement.
+ (get_mostly_instantiated_function_type): Increment
+ processing_template_decl during partial substitution of function
+ type.
+
+2003-10-15 Jan Hubicka <jh@suse.cz>
+
+ PR c++/12574
+ * decl2.c (cxx_callgraph_analyze_expr): Deal with baselink.
+
+2003-10-14 Jason Merrill <jason@redhat.com>
+
+ PR c++/11878
+ * tree.c (build_target_expr_with_type): Call force_rvalue for
+ classes with non-trivial copy ctors.
+
+ PR c++/11063
+ * typeck.c (build_modify_expr): Call convert rather than abort.
+
+2003-10-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Breack out decl.c (3/n)
+ * name-lookup.c: Include flags.h
+ (lookup_name_current_level): Make static.
+ (add_decl_to_level): Likewise.
+ (push_local_binding): Likewise.
+ (push_overloaded_decl): Likewise.
+ (lookup_using_namespace): Likewise.
+ (qualified_lookup_using_namespace): Likewise.
+ (lookup_type_current_level): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (namespace_ancestor): Likewise.
+ (push_using_directive): Likewise.
+ * decl.c (pushdecl): Move to name-lookup.c.
+ (pushdecl_top_level_1): Likewise.
+ (pushdecl_top_level): Likewise.
+ (pushdecl_top_level_and_finish): Likewise.
+ (maybe_push_decl): Likewise.
+ (push_using_decl): Likewise.
+ (push_overloaded_decl): Likewise.
+ (make_anon_name): Likewise.
+ (anon_cnt): Likewise.
+ (clear_anon_tags): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (check_for_out_of_scope_variable): Likewise.
+ * Make-lang.in (cp/name-lookup.o): Depend on flags.h.
+ * decl.c (warn_extern_redeclared_static): Export.
+ * cp-tree.h (warn_extern_redeclared_static): Declare.
+
+2003-10-14 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Make-lang.in: Replace uses of $(target_alias) with
+ $(target_noncanonical).
+
+2003-10-13 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * ChangeLog: Add PR number to patch for PR c++/12370.
+
+2003-10-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.h (cxx_scope_find_binding_for_name): Don't export.
+ (binding_for_name): Likewise.
+ (cxx_binding_clear): Move to name-lookup.c.
+ * name-lookup.c (cxx_scope_find_binding_for_name): Now static.
+ (binding_for_name): Likewise.
+ * decl2.c (is_ancestor): Move to name-lookup.c
+ (namespace_ancestor): Likewise.
+ (add_using_namespace): Likewise.
+ (ambiguous_decl): Likewise.
+ (lookup_using_namespace): Likewise.
+ (qualified_lookup_using_namespace): Likewise.
+ (set_decl_namespace): Likewise.
+ (decl_namespace): Likewise.
+ (current_decl_namespace): Likewise.
+ (push_decl_namespace): Likewise.
+ (pop_decl_namespace): Likewise.
+ (push_scope): Likewise.
+ (pop_scope): Likewise.
+ (struct arg_lookup): Likewise.
+ (arg_assoc): Likewise.
+ (arg_assoc_args): Likewise.
+ (arg_assoc_type): Likewise.
+ (add_function): Likewise.
+ (arg_assoc_namespace): Likewise.
+ (arg_assoc_class): Likewise.
+ (arg_assoc_template_arg): Likewise.
+ (do_namespace_alias): Likewise.
+ (validate_nonmember_using_decl): Likewise.
+ (do_nonmember_using_decl): Likewise.
+ (do_toplevel_using_decl): Likewise.
+ (do_local_using_decl): Likewise.
+ (do_class_using_decl): Likewise.
+ (do_using_directive): Likewise.
+ (constructor_name_full): Likewise.
+ (constructor_name): Likewise.
+ (constructor_name_p): Likewise.
+
+2003-10-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Break out decl.c (2/n)
+ * name-lookup.c: Include diagnostic.h
+ (cxx_binding_free): Make static.
+ (cxx_binding_make): Likewise.
+ (binding_table_new): Likewise
+ (binding_table_free): Likewise.
+ (binding_table_insert): Likewise.
+ (binding_table_find_anon_type): Likewise.
+ (binding_table_reverse_maybe_remap): Likewise.
+ (supplement_binding): Likewise.
+ * name-lookup.h (global_scope_name): Declare extern.
+ (global_type_node): Likewise.
+ (cxx_binding_free): Don't export.
+ (cxx_binding_make): Likewise.
+ (binding_table_new): Likewise.
+ (binding_table_free): Likewise.
+ (binding_table_insert): Likewise.
+ (binding_table_find_anon_type): Likewise.
+ (binding_table_reverse_maybe_remap): Likewise.
+ * Make-lang.in (cp/name-lookup.o): Depend on $(DIAGNOSTIC_H)
+ * decl.c (lookup_namespace_name): Move to name-lookup.c
+ (select_decl): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_qualified_name): Likewise.
+ (lookup_name_real): Likewise.
+ (lookup_name_nonclass): Likewise.
+ (lookup_function_nonclass): Likewise.
+ (lookup_name): Likewise.
+ (lookup_name_current_level): Likewise.
+ (lookup_type_current_level): Likewise.
+ (lookup_flags): Likewise.
+ (qualify_lookup): Likewise.
+ (lookup_tag): Likewise.
+ (lookup_tag_reverse): Likewise.
+ (getdecls): Likewise.
+ (storedecls): Remove.
+ (cxx_remember_type_decls): Move to name-lookup.c.
+ (global_bindings_p): Likewise.
+ (innermost_nonclass_level): Likewise.
+ (toplevel_bindings_p): Likewise.
+ (namespace_bindings_p): Likewise.
+ (kept_level_p): Likewise.
+ (innermost_scope_kind): Likewise.
+ (template_parm_scope_p): Likewise.
+ (push_binding): Likewise.
+ (push_local_binding): Likewise.
+ (add_decl_to_level): Likewise. Make extern.
+ (push_class_binding): Move to name-lookup.c.
+ (resume_level): Likewise. Rename to resume_scope.
+ (begin_scope): Move to name-lookup.c.
+ (indent): Likewise.
+ (binding_depth): Likewise.
+ (is_class_level): Likewise.
+ (cxx_scope_descriptor): Likewise.
+ (cxx_scope_debug): Likewise.
+ (namespace_scope_ht_size): Likewise.
+ (leave_scope): Likewise.
+ (pushlevel_class): Likewise.
+ (poplevel_class): Likewise.
+ (clear_identifier_class_values): Likewise.
+ (pushdecl_with_scope): Likewise.
+ (pushdecl_namespace_level): Likewise.
+ (pushdecl_class_level): Likewise.
+ (push_class_level_binding): Likewise.
+ (push_using_directive): Likewise.
+ (identifier_global_value): Likewise.
+ (keep_next_level_flag): Likewise.
+ (keep_next_level): Likewise.
+ (free_binding_level): Likewise.
+ (set_class_shadows): Likewise.
+ (maybe_push_cleanup_level): Likewise.
+ (cp_namespace_decls): Likewise.
+ (bt_print_entry): Likewise.
+ (print_binding_level): Likewise.
+ (print_other_binding_stack): Likewise.
+ (print_binding_stack): Likewise.
+ (push_namespace): Likewise.
+ (pop_namespace): Likewise.
+ (push_nested_namespace): Likewise.
+ (pop_nested_namespace): Likewise.
+ (cxx_saved_binding_make): Likewise.
+ (struct cxx_saved_binding_make): Likewise.
+ (store_bindings): Likewise.
+ (maybe_push_to_top_level): Likewise.
+ (push_to_top_level): Likewise.
+ (pop_from_top_level): Likewise.
+ (identifier_type_value): Likewise.
+ (set_identifier_type_value): Likewise.
+ (set_identifier_type_value_with_scope): Likewise.
+ (pop_everything): Likewise.
+ (pushtag): Likewise.
+ (follow_tag_typedef): Likewise.
+ (maybe_process_template_type_declaration): Likewise.
+ (pop_binding): Likewise.
+ * cp-tree.h: Move corresponding declarations to name-lookup.h
+
+2003-10-12 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cvt.c (ocp_convert): Move warning to C common code.
+
+2003-10-09 Jason Merrill <jason@redhat.com>
+
+ PR c++/6392
+ * tree.c (build_cplus_array_type): Handle all quals the same.
+ (cp_build_qualified_type_real): Look through arrays first.
+
+ * tree.c (build_cplus_new): Use build_decl to create a VAR_DECL.
+ (build_target_expr_with_type): Likewise.
+
+ * pt.c (instantiate_class_template): Sanity check that our
+ enclosing class has been instantiated.
+
+2003-10-08 Giovanni Bajo <giovannibajo@libero.it>
+
+ * cp_tree.h: Added TFF_NO_FUNCTION_ARGUMENTS.
+ * error.c (dump_function_decl): Use it to skip the dump of the
+ arguments.
+ (dump_expr): When dumping a declaration found within an
+ expression, always set TFF_NO_FUNCTION_ARGUMENTS
+ in the flags.
+
+2003-10-08 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/11097
+ * pt.c (tsubst_decl): Substitute also the DECL_NAME node of
+ USING_DECL.
+
+2003-10-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10147
+ * call.c (initialize_reference): Tweak error message.
+ * cxx-pretty-print.h (cxx_pretty_printer_flags): Remove
+ pp_cxx_flag_qualified_id and pp_cxx_flag_global_scope.
+ * cxx-pretty-print.c (pp_cxx_id_expression): Always display
+ qualified entities using qualified names.
+
+ PR c++/12337
+ * init.c (build_new_1): Make sure that the expression returned is
+ not an lvalue.
+
+ PR c++/12344, c++/12236, c++/8656
+ * decl.c (start_function): Do not ignore attributes embedded in a
+ function declarator.
+
+2003-10-06 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (c++.info): Remove.
+ (c++.dvi): Remove.
+ (c++.generated-manpages): Replace with ...
+ (generated-manpages): ... this.
+
+2003-10-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (struct cp_binding_level): Move to name-lookup.h
+ (current_binding_level): Likewise.
+ (class_binding_level): Likewise.
+ * cp-tree.h (enum scope_kind): Likewise.
+
+2003-10-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.c (binding_entry_free): Nullify name and type
+ fields.
+
+2003-10-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12486
+ * typeck.c (finish_class_member_access_expr): Issue diagnostic
+ on erroneous use of qualified name.
+
+2003-09-30 Richard Henderson <rth@redhat.com>
+
+ PR c++/12370
+ * decl.c (duplicate_decls): Copy DECL_SAVED_INSNS too.
+
+2003-09-30 Kelley Cook <kelleycoook@wideopenwest.com>
+
+ * g++spec.c: Convert to ISO C90 prototypes.
+ * parser.c: Likewise.
+
+2003-09-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (pop_binding): Don't mess with nullifying binding->scope
+ here.
+ * name-lookup.c: Re-format.
+ (cxx_binding_free): Nullify binding->scope.
+
+2003-09-29 Jan Hubicka <jh@suse.cz>
+
+ PR C++/12047
+ * except.c (build_eh_type_type): Call mark_used on the type.
+
+2003-09-28 Richard Henderson <rth@redhat.com>
+
+ * typeck.c (c_expand_asm_operands): Take location_t, instead of
+ individual file and line.
+
+2003-09-28 Andreas Jaeger <aj@suse.de>
+
+ * decl.c (cxx_builtin_type_decls): Convert to ISO C90 function
+ definition.
+ * init.c (push_base_cleanups): Likewise.
+ * decl2.c (finish_file): Likewise.
+ * mangle.c (init_mangle): Likewise.
+ (dump_substitution_candidates): Likewise.
+ * search.c: Likewise.
+
+2003-09-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.h (get_global_value_if_present): New function.
+ (is_typename_at_global_scope): Likewise.
+ * except.c (do_begin_catch): Use get_global_value_if_present.
+ (do_end_catch): Likewise.
+ (do_allocate_exception): Likewise.
+ (do_free_exception): Likewise.
+ (build_throw): Likewise.
+ * parser.c (cp_parser_member_declaration): Likewise.
+ * rtti.c (throw_bad_cast): Likewise.
+ (throw_bad_typeid): Likewise.
+ * decl.c (check_tag_decl): Use is_typename_at_global_scope.
+ (grokdeclarator): Likewise.
+ * cp-tree.h (global_namespace): Move to name-lookup.h
+ * call.c (call_builtin_trap): Tidy.
+
+2003-09-27 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11415
+ * parser.c (cp_parser_nested_name_specifier_opt): Issue correct
+ error message when parser->scope is global_namespace.
+
+2003-09-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h, name-lookup.h, decl.c, decl2.c: Remove reference to
+ macros BINDING_SCOPE, BINDING_VALUE and BINDING_TYPE.
+
+2003-09-26 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (pop_binding_level, suspend_binding_level,
+ find_class_binding_level): Merge into leave_scope. Remove.
+ (leave_scope): New function.
+ (poplevel): Update.
+ (poplevel_class): Likewise.
+ (pop_namespace): Likewise.
+
+2003-09-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/5655
+ * parser.c (cp_parser_check_access_in_redeclaration): New function.
+ (cp_parser_member_declaration): Use it.
+ (cp_parser_template_declaration_after_export): Likewise.
+
+2003-09-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (scope_kind): Add new enumerator.
+ (keep_next_level): Change parameter type to bool.
+ (begin_scope): Change prototype.
+ (pushlevel): Remove declaration.
+ * decl.c (push_binding_level): Fold in begin_scope. Remove.
+ (struct cp_binding_level): Remove tag_tranparent field. Make keep
+ of bitsize one.
+ (keep_next_level_flag): Make a bool.
+ (cxx_scope_descriptor): Update scope names table
+ (make_cxx_scope): Fold in begin_scope. Remove..
+ (namespace_scope_ht_size): New function.
+ (begin_scope): Change prototype. Return a scope. Tidy.
+ (kept_level_p): Update.
+ (pushlevel): Remove.
+ (maybe_push_cleanup_level): Simplify.
+ (poplevel): Update for sk_cleanup and keep change.
+ (print_binding_level): Likewise.
+ (initial_push_namespace_scope): Fold in begin_scope. Remove.
+ (push_namespace): Update.
+ (pushtag): Likewise.
+ (lookup_tag): Likewise.
+ (lookup_name_current_level): Likewise.
+ (lookup_type_current_level): Likewise.
+ (cxx_init_decl_processing): Likewise.
+ (start_function): Likewise.
+ (begin_function_body): Likewise.
+ (start_method): Likewise.
+ * pt.c (push_inline_template_parms_recursive): Likewise.
+ (begin_template_parm_list): Likewise.
+ (begin_specialization): Likewise.
+ * semantics.c (do_pushlevel): Likewise.
+ (begin_compound_stmt): Likewise.
+ (begin_stmt_expr): Likewise.
+
+2003-09-21 Richard Henderson <rth@redhat.com>
+
+ * class.c, cp-tree.h, decl.c, decl2.c, error.c, init.c,
+ method.c, optimize.c, pt.c, semantics.c, tree.c: Revert.
+
+2003-09-21 Richard Henderson <rth@redhat.com>
+
+ * class.c, cp-tree.h, decl.c, decl2.c, error.c, init.c,
+ method.c, optimize.c, pt.c, semantics.c, tree.c: Update for
+ DECL_SOURCE_LOCATION rename and change to const.
+
+2003-09-20 Richard Henderson <rth@redhat.com>
+
+ * decl.c, decl2.c, pt.c: Use %J in diagnostics.
+
+2003-09-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/157
+ * parser.c (cp_parser_direct_declarator): Clear
+ parser->num_template_parameter_lists when parsing function
+ parameters.
+ (cp_parser_constructor_declarator_p): Likewise.
+
+2003-09-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/495
+ * pt.c (tsubst_friend_class): Only use innermost template
+ arguments for the injected friend class template.
+
+2003-09-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12332
+ * pt.c (instantiate_class_template): Increment
+ processing_template_decl around the tsubst of a template member
+ function.
+
+2003-09-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (cxx_scope_descriptor): Fix thinko.
+ (struct cp_binding_level): Adjust type of binding_depth field.
+
+2003-09-18 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c++/12320
+ * call.c (type_passed_as): Check for incomplete type.
+ (convert_for_arg_passing): Likewise.
+
+2003-09-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9848
+ * optimize.c (maybe_clone_body): Don't set MARK_USED on parameters
+ here.
+ * semantics.c (expand_body): Set it here on the remaining clones.
+
+2003-09-18 Roger Sayle <roger@eyesopen.com>
+
+ * lex.c (init_operators): Remove operator_name_info for FFS_EXPR.
+ * class.c (instantiate_type): Remove FFS_EXPR case.
+
+2003-09-18 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * ChangeLog: Fix recent commit.
+
+2003-09-18 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * ChangeLog: Add PR number to patch for PR c++/12316.
+
+2003-09-18 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_type): Simplify. Use pp_type_specifier_seq for
+ "C" types.
+ * cxx-pretty-print.c (pp_cxx_type_specifier_seq): Fix thinko.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (expand_body): Don't save/restore input_location.
+
+2003-09-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12266
+ * cp-tree.h (tsubst_flags_t): Add tf_conv.
+ * class.c (standard_conversion): Pass tf_conv to
+ instantiate_type.
+ (resolve_address_of_overloaded_function): Do not call mark_used
+ when just checking conversions.
+
+ PR debug/12066
+ * cp-lang.c (LANG_HOOKS_BUILTIN_TYPE_DECLS): Define.
+ * cp-tree.h (cxx_builtin_type_decls): Declare.
+ * decl.c (builtin_type_decls): New variables.
+ (cxx_builtin_type_decls): New function.
+ (record_builtin_type): Add to builtin_type_decls.
+
+2003-09-17 Richard Henderson <rth@redhat.com>
+
+ PR c++/12316
+ * semantics.c (expand_or_defer_fn): Inc/dec function_depth.
+
+2003-09-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/7939
+ * typeck.c (comptypes): Don't ICE when its first argument is
+ error_mark_node.
+ (compparms): Reverse the arguments of same_type_p.
+
+2003-09-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12184
+ * typeck.c (convert_arguments): Return error_mark_node for an
+ incomplete parameter. Make error message more informative.
+
+2003-09-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/3907
+ * class.c (maybe_note_name_used_in_class): Refine test for whether
+ or not we are in a class scope.
+
+ * cp-tree.h (language_function): Remove x_expanding_p.
+ (expanding_p): Remove.
+ (doing_semantic_analysis_p): Remove.
+ (scope_kind): Add sk_function_parms, sk_class,
+ sk_namespace.
+ (innermost_scope_kind): New method.
+ * call.c (cxx_type_promotes_to): Use type_decays_to.
+ * cp-lang.c (LANG_HOOKS_PUSHLEVEL): Redefine.
+ (LANG_HOOKS_POPLEVEL): Likewise.
+ * decl.c (cp_binding_level): Remove parm_flag, template_parms_p,
+ template_spec_p, namespace_p, is_for_scope, is_try_scope, and
+ is_catch_scope. Add kind and explicit_spec_p.
+ (cxx_scope_descriptor): Use a lookup table.
+ (find_class_binding_level): Use "kind" field in binding_level, not
+ the various flags.
+ (pop_binding_level): Likewise.
+ (innermost_nonclass_level): Likewise.
+ (toplevel_bindings_p): Likewise.
+ (namespace_bindings_p): Likewise.
+ (template_parm_scope_p): Likewise.
+ (innermost_scope_kind): New method.
+ (current_tmpl_spec_kind): Use "kind" field in binding_level, not
+ the various flags.
+ (pushlevel): Remove check for doing_semantic_analysis_p.
+ (begin_scope): Simplify.
+ (add_decl_to_level): Use "kind" field in binding_level, not
+ the various flags.
+ (push_local_binding): Likewise.
+ (pop_label): Remove check for doing_semantic_analysis_p.
+ (poplevel): Use "kind" field in binding_level, not
+ the various flags.
+ (set_block): Remove check for doing_semantic_analysis_p.
+ (pushlevel_class): Use "kind" field in binding_level, not
+ the various flags.
+ (poplevel_class): Likewise.
+ (initial_push_namespace_scope): Likewise.
+ (maybe_push_to_top_level): Likewise.
+ (set_identifier_type_value_with_scope): Likewise.
+ (pop_everything): Likewise.
+ (maybe_process_template_type_declaration): Likewise.
+ (pushtag): Likewise.
+ (pushdecl): Likewise.
+ (pushdecl_with_scope): Likewise.
+ (check_previous_goto_1): Likewise.
+ (define_label): Likewise.
+ (finish_case_label): Likewise.
+ (lookup_tag): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_name_real): Likewise.
+ (lookup_name_current_level): Likewise.
+ (lookup_type_current_level): Likewise.
+ (record_builtin_type): Likewise.
+ (cp_make_fname_decl): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (cp_finish_decl): Remove check for doing_semantic_analysis_p.
+ (start_function): Use begin_scope, not pushlevel.
+ (finish_function): Use "kind" field in binding_level, not
+ the various flags.
+ (start_method): Use begin_scope, not pushlevel.
+ (make_label_decl): Do not check expanding_p.
+ (save_function-data): Do not set expanding_p.
+ (cxx_push_function_context): Do not clear expanding_p.
+ * semantics.c (cxx_expand_function_start): Do not set expanding_p.
+
+2003-09-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Make DECL_MODE match TYPE_MODE for
+ an bit-field whose width exceeds that of its type.
+
+2003-09-14 Geoffrey Keating <geoffk@apple.com>
+
+ * rtti.c (get_tinfo_decl): Set TREE_PUBLIC for typeinfo decls.
+
+2003-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * parser.c: Likewise.
+
+2003-09-13 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (finish_file): Check cgraph_assemble_pending_functions
+ during relaxation loop.
+
+2003-09-11 David Edelsohn <edelsohn@gnu.org>
+
+ * decl2.c (var_finalized_p): Swap arms of conditional.
+
+2003-09-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11788
+ * typeck.c (build_address): If it is a function, mark it used.
+ (build_unary_op): Do not lose object's side-effects when taking
+ address of static member function.
+ * class.c (resolve_address_of_overloaded_function): Use
+ tsubst_flags_t parameter. Only expect overload sets. Adjust.
+ (instantiate_type): Adjust flags passing. Do not lose object's
+ side-effects when taking address of static member function.
+
+2003-09-11 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (expand_or_defer_fn): Update for new
+ cgraph_finalize_function argument.
+
+2003-09-10 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (cxx_callgraph_analyze_expr): Mark argument unused.
+
+2003-09-10 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (var_finalized_p): New.
+ (maybe_emit_vtables, write_out_vars, finish_file): Use it.
+
+2003-09-10 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (cxx_callgraph_analyze_expr): New, from corpse of
+ mark_member_pointers.
+ (lower_function): Remove.
+ * cp-tree.h: Update to match.
+ * cp-lang.c (LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR): New.
+ (LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION): Remove.
+
+2003-09-09 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (expand_or_defer_fn): Update call to
+ cgraph_finalize_function.
+
+ * semantics.c (expand_or_defer_fn): Use cgraph_finalize_function
+ always.
+
+ * decl2.c (finish_file): Avoid out-of-bounds array reference
+ during memmove.
+
+2003-09-09 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (mark_member_pointers): Rename from
+ mark_member_pointers_and_eh_handlers and don't check eh handlers.
+
+2003-09-09 Christian Ehrhardt <ehrhardt@mathematik.uni-ulm.de>
+
+ PR bootstrap/12168
+ * method.c (use_thunk): Clear DECL_RTL of copied nodes.
+
+2003-09-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-lang.c (LANG_HOOKS_REGISTER_BUILTIN_TYPE): Define to
+ c_register_builtin_type.
+
+ PR c++/11786
+ * decl2.c (add_function): Do not complain about seeing the same
+ non-function twice.
+ * semantics.c (perform_koenig_lookup): Improve documentation.
+
+ PR c++/5296
+ * pt.c (try_one_overload): Add addr_p parameter.
+ (resolve_overloaded_unification): Pass it.
+
+2003-09-08 Richard Henderson <rth@redhat.com>
+
+ * optimize.c (maybe_clone_body): Inc/dec function_depth.
+
+2003-09-08 Richard Henderson <rth@redhat.com>
+
+ * decl.c (finish_function): Clear current_function_decl.
+ * decl2.c (mark_used): Don't push/pop gc context.
+ * optimize.c (optimize_function): Likewise.
+ * tree.c (cp_cannot_inline_tree_fn): Likewise.
+ * pt.c (instantiate_decl): Inc/dec function_depth instead.
+ * semantics.c (expand_body): Update for tree_rest_of_compilation
+ nested argument.
+
+2003-09-07 Gabriel Dos Reis <gcc@integrable-solutions.net>
+
+ PR c++/11762
+ * error.c (dump_decl): Handle namespace-alias-definition.
+ * decl.c (warn_extern_redeclared_static): There is no point in
+ checking changes in storage class specifier for a namespace
+ declaration.
+ (duplicate_decls): Tidy diagnostic message.
+ * cxx-pretty-print.c (pp_cxx_left_brace): New macro.
+ (pp_cxx_right_brace): Likewise.
+ (pp_cxx_original_namespace_definition): New function.
+ (pp_cxx_namespace_alias_definition): Likewise.
+ (pp_cxx_declaration): Use them. Handle NAMESPACE_DECLs.
+
+2003-09-07 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (maybe_emit_vtables, write_out_vars, finish_file):
+ Avoid re-emitting variables in unit-at-a-time mode.
+
+2003-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11867
+ * call.c (standard_conversion): Improve comments.
+ (perform_direct_initialization): Make sure we return an expression
+ of the correct type.
+ * typeck.c (build_static_cast): Check for ambiguity and
+ accessibility when performing conversions.
+
+2003-09-06 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (add_binding): Remove declaration.
+ * name-lookup.h (supplement_binding): Declare.
+ * decl.c (add_binding): Move to name-lookup.c.
+ (push_local_binding): Adjust.
+ (push_class_binding): Likewise.
+ (set_identifier_type_value_with_scope): Likewise.
+ * name-lookup.c (supplement_binding): Rename from add_binding.
+ Return a bool. Improve documentation.
+ (set_namespace_binding): Adjust.
+ * Make-lang.in (cp/name-lookup.o): Depend on toplev.h
+
+2003-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11794
+ * class.c (pushclass): Push dependent using decls for nested
+ classes of templates too.
+
+2003-09-06 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/11409
+ * class.c (resolve_address_of_overloaded_function): When building
+ list of matching non-template function decls, ignore anticipated
+ declarations of undeclared or shadowed GCC builtins.
+
+2003-09-06 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR c++/11595
+ * decl.c (define_label): Remove unreachable timevar pop.
+ Always return the decl, even if the definition is invalid.
+
+2003-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/12167
+ * parser.c (cp_parser_late_parsing_default_args): Push & pop the
+ unparsed functions queue.
+
+2003-09-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12163
+ * call.c (perform_direct_initialization): Correct logic for
+ direct-initialization of a class type.
+
+ PR c++/12146
+ * pt.c (lookup_template_function): Robustify.
+
+2003-09-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11922
+ * pt.c (tsubst_qualified_id): Make sure we get a non-type.
+ (tsubst_expr, tsubst_copy_and_build): Pass false, not zero, as
+ is_type_p to lookup_qualified_name.
+
+ * semantics.c (finish_call_expr): Refactor some code.
+
+ PR c++/12037
+ * cp-tree.h (COMPOUND_EXPR_OVERLOADED): New.
+ (build_min_non_dep): Declare.
+ * tree.c (build_min): Propagate TREE_SIDE_EFFECTS.
+ (build_min_non_dep): New.
+ * cvt.c (convert_to_void): Don't explicitly copy
+ TREE_SIDE_EFFECTS, TREE_NO_UNUSED_WARNING.
+ * call.c (build_new_method_call): Use build_min_non_dep.
+ * decl2.c (grok_array_decl): Likewise.
+ (build_offset_ref_call_from_tree): Likewise.
+ * typeck.c (finish_class_member_access_expr,
+ build_x_indirect_ref, build_x_binary_op, build_x_unary_op,
+ build_x_conditional_expr, build_x_compound_expr): Likewise.
+ (build_static_cast, build_reinterpret_cast,
+ build_const_cast): Propagate TREE_SIDE_EFFECTS inside a template.
+ * typeck2.c (build_x_arrow): Use build_min_non_dep.
+ (build_functional_cast): Propagate TREE_SIDE_EFFECTS inside a
+ template.
+ * rtti.c (build_dynamic_cast_1): Set DECL_IS_PURE.
+ (build_dynamic_cast): Set TREE_SIDE_EFFECTS.
+ * pt.c (build_non_dependent_expr): Check COMPOUND_EXPR_OVERLOADED.
+
+2003-09-04 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (mark_member_pointers_and_eh_handlers): Update for
+ change in cgraph_mark_needed_node arguments.
+
+2003-09-02 Geoffrey Keating <geoffk@apple.com>
+
+ PR 12161
+ * decl2.c (mark_used): Use ggc_push_context/ggc_pop_context.
+ * tree.c (cp_cannot_inline_tree_fn): Likewise.
+
+2003-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (finish_sizeof, finish_alignof): Remove.
+ (expr_sizeof): Replace with ...
+ (cxx_sizeof_or_alignof_expr): ... here.
+ (cxx_sizeof_or_alignof_type): Make complain parameter a bool.
+ * parser.c (cp_parser_unary_expression): Commonize alignof and
+ sizeof handling.
+ * pt.c (tsubst_copy_and_build): Adjust alignof and sizeof
+ substitution.
+ * semantics.c (finish_sizeof, finish_alignof): Remove.
+ * typeck.c (cxx_sizeof_or_alignof_type): Complain parameter
+ becomes bool. Set TREE_READONLY.
+ (expr_sizeof): Replace with ...
+ (cxx_sizeof_or_alignof_expr): ... here. Clear TREE_SIDE_EFFECTS.
+
+2003-09-04 Mark Mitchell <mark@codesourcery.com>
+
+ Remove cast-as-lvalue extension.
+ * call.c (build_conditional_expr): Correct formatting.
+ (convert_like_real): Use lvalue_p, not non_cast_lvalue_p.
+ (initialize_real): Use real_lvalue_p, not real_non_cast_lvalue_p.
+ * cp-tree.h (non_cast_lvalue_p): Remove.
+ (real_non_cast_lvalue_p): Remove.
+ (non_cast_lvalue_or_else): Remove.
+ * tree.c (lvalue_p_1): Remove allow_cast_as_lvalue parameter.
+ (real_lvalue_p): Adjust call to lvalue_p_1.
+ (non_cast_lvalue_p): Remove.
+ (non_cast_lvalue_or_else): Remove.
+ (lvalue_p): Adjust call to lvalue_p_1.
+ (lvalue_or_else): Simplify.
+ * typeck.c (build_unary_op): Use lvalue_or_else, not
+ non_cast_lvalue_or_else.
+ (build_static_cast): Use real_lvalue_p, not real_non_cast_lvalue_p.
+
+2003-09-03 DJ Delorie <dj@redhat.com>
+
+ * decl.c (finish_function): Pass fndecl to aggregate_value_p.
+
+2003-09-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12053
+ * class.c (include_empty_classes): Correct logic for ABI version 1.
+
+2003-09-03 Richard Henderson <rth@redhat.com>
+
+ * optimize.c (optimize_function): Push/pop ggc context around
+ the call to optimize_inline_calls.
+
+2003-09-02 Scott Brumbaugh <scottb.lists@verizon.net>
+
+ PR c++/11553
+ * parser.c (cp_parser_decl_specifier_seq): Add check for a
+ duplicate friend decl-specifier.
+
+2003-09-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11847
+ * pt.c (convert_nontype_argument): Correct representation of
+ REFERENCE_TYPE expressions.
+
+ PR c++/11808
+ * cp-tree.h (KOENIG_LOOKUP_P): New macro.
+ (finish_call_expr): Change prototype.
+ * parser.c (cp_parser_postfix_expression): Adjust call to
+ finish_call_expr.
+ * pt.c (tsubst_copy_and_build): Use KOENIG_LOOKUP_P.
+ * semantics.c (finish_call_expr): Add koenig_p parameter.
+
+2003-09-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12114
+ * cp-tree.h (initialize_reference): Change prototype.
+ * call.c (initialize_reference): Add cleanup parameter.
+ * decl.c (grok_reference_init): Likewise.
+ (check_initializer): Likewise.
+ (cp_finish_decl): Insert a CLEANUP_STMT if necessary.
+ (duplicate_decls): When replacing an anticipated builtin, do not
+ honor TREE_NOTHROW.
+ * typeck.c (convert_for_initialization): Correct call to
+ initialize_reference.
+
+ PR c++/11972
+ * pt.c (dependent_type_p_r): Pass only the innermost template
+ arguments to any_dependent_template_arguments_p.
+
+2003-09-01 Josef Zlomek <zlomekj@suse.cz>
+
+ * error.c (dump_expr): Kill BIT_ANDTC_EXPR.
+ * lex.c (init_operators): Kill BIT_ANDTC_EXPR.
+ * pt.c (tsubst_copy): Kill BIT_ANDTC_EXPR.
+ * typeck.c (build_binary_op): Kill BIT_ANDTC_EXPR.
+ (tsubst_copy_and_build): Kill BIT_ANDTC_EXPR.
+
+2003-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/12093
+ * pt.c (build_non_dependent_expr): Do not build a
+ NON_DEPENDENT_EXPR for a STRING_CST.
+
+ PR c++/11928
+ * search.c (add_conversions): Avoid adding two conversion
+ operators for the same type.
+
+2003-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6196
+ * pt.c (tsubst_copy_and_build): Correct handling of
+ address-of-label extension.
+ * semantics.c (finish_goto_stmt): The address of a label must go
+ through the lvalue-to-rvalue conversion.
+
+2003-08-29 Richard Henderson <rth@redhat.com>
+ Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_RTL_EXPAND_START): New.
+ (LANG_HOOKS_RTL_EXPAND_STMT): New.
+ * cp-tree.h (cxx_expand_function_start): Declare.
+ * decl.c (start_function): Use allocate_struct_function.
+ Move stmts_are_full_exprs_p assertion from expand_body.
+ Do not free_after_parsing or free_after_compilation.
+ (cxx_push_function_context): Move code to set struct function
+ data from genrtl_start_function.
+ * optimize.c (optimize_function): Don't inc/dec function_depth.
+ * semantics.c (expand_body): Use tree_rest_of_compilation.
+ (cxx_expand_function_start): Rename from genrtl_start_function,
+ omit bits done by tree_rest_of_compilation.
+ (genrtl_finish_function): Remove.
+ (clear_decl_rtl): Move to ../tree-optimize.c.
+
+2003-08-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/11811
+ * cxx-pretty-print.c (pp_cxx_canonical_template_parameter): New
+ function.
+ * cxx-pretty-print.h: Declare.
+ * error.c (dump_template_parameter): Use it.
+ (dump_type): Likewise.
+
+2003-08-28 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (decl_constant_value): Deal with COND_EXPR specially.
+ * call.c (build_conditional_expr): Revert previous patch.
+
+ PR optimization/5079
+ * call.c (build_conditional_expr): Use decl_constant_value to
+ simplify the arguments.
+
+2003-08-26 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * parser.c (struct cp_token): Use enum bitfields.
+ (CP_TOKEN_BLOCK_NUM_TOKENS): Make sure cp_token_block fits in a
+ 512B allocation unit.
+ (cp_parser_token_tree_map_node): Use enum bitfields.
+
+2003-08-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11871
+ * decl.c (push_class_level_binding): Correct old_decl value from
+ my 2003-07-29 reorganization.
+
+ * call.c (build_call): Don't set TREE_SIDE_EFFECTS here.
+ (build_new_method_call): Add goto finish.
+ * semantics.c (simplify_aggr_init_exprs_r): Don't set
+ TREE_SIDE_EFFECTS on a call.
+
+2003-08-25 Richard Henderson <rth@redhat.com>
+
+ * cxx-pretty-print.c (pp_cxx_class_name): Remove unused function.
+
+2003-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (pp_cxx_flag_default_argument): New flag.
+ (cxx_pretty_printer): Adjust base type.
+ (pp_cxx_function_specifier): Declare.
+ * cxx-pretty-print.c (pp_cxx_whitespace): New macro.
+ (pp_cxx_left_paren): Likewise.
+ (pp_cxx_right_paren): Likewise.
+ (pp_cxx_dot): Likewise.
+ (pp_cxx_arrow): Likewise.
+ (pp_cxx_semicolon): Likewise.
+ (pp_cxx_identifier): Likewise.
+ (pp_cxx_cv_qualifier_seq): Likewise.
+ (pp_cxx_storage_class_specifier): Likewise.
+ (pp_cxx_expression_list): Likewise.
+ (pp_cxx_space_for_pointer_operator): Likewise.
+ (pp_cxx_init_declarator): Likewise.
+ (pp_cxx_call_argument_list): Likewise.
+ (pp_cxx_nonconsecutive_character): Tidy.
+ (pp_cxx_conversion_function_id): New function.
+ (pp_cxx_template_id): Likewise.
+ (pp_cxx_template_keyword_if_needed): Likewise.
+ (pp_cxx_nested_name_specifier): Likewise.
+ (pp_cxx_unqualified_id): Tidy
+ (pp_cxx_qualified_id): Handle more nodes.
+ (pp_cxx_primary_expression): Tidy.
+ (pp_cxx_postfix_expression): Likewise.
+ (pp_cxx_new_expression): Tidy.
+ (pp_cxx_delete_expression): Likewise.
+ (pp_cxx_cast_expression): New function.
+ (pp_cxx_pm_expression): Tidy.
+ (pp_cxx_conditional_expression): Likewise.
+ (pp_cxx_assignment_operator): New function.
+ (pp_cxx_assignment_expression): Tidy.
+ (pp_cxx_expression): New function.
+ (pp_cxx_function_specifier): Likewise.
+ (pp_cxx_decl_specifier_seq): Likewise.
+ (pp_cxx_simple_type_specifier): Tidy.
+ (pp_cxx_type_specifier_seq): Likewise.
+ (pp_cxx_ptr_operator): New function.
+ (pp_cxx_implicit_parameter_type): Likewise.
+ (pp_cxx_parameter_declaration): Tidy.
+ (pp_cxx_parameter_declaration_clause): New function.
+ (pp_cxx_exception_specification): Likewise.
+ (pp_cxx_direct_declarator): Tidy.
+ (pp_cxx_declarator): Likewise.
+ (pp_cxx_ctor_initializer): New function.
+ (pp_cxx_function_definition): Likewise.
+ (pp_cxx_abstract_declarator): Tidy.
+ (pp_cxx_direct_abstract_declarator): Likewise.
+ (pp_cxx_type_id): Likewise.
+ (pp_cxx_exception_declaration): New function.
+ (pp_cxx_statement): Likewise.
+ (pp_cxx_simple_declaration): Likewise.
+ (pp_cxx_template_parameter_list): Likewise.
+ (pp_cxx_template_parameter): Likewise.
+ (pp_cxx_template_declaration): Likewise.
+ (pp_cxx_explicit_specialization): Likewise.
+ (pp_cxx_explicit_instantiation): Likewise.
+ (pp_cxx_declaration): Tidy.
+ (pp_cxx_pretty_printer_init): Initialize more fields.
+
+2003-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8795
+ * cp-tree.h (build_cplus_method_type): Remove.
+ * call.c (standard_conversion): Use build_method_type_directly
+ instead of build_cplus_method_type.
+ * class.c (build_clone): Likewise.
+ (adjust_clone_args): Likewise.
+ * decl.c (build_ptrmem_type): Likewise.
+ (grokdeclarator): Likewise.
+ (check_function_type): Likewise.
+ * decl2.c (grok_method_quals): Likewise.
+ (maybe_retrofit_in_chrg): Likewise.
+ * pt.c (copy_default_args_to_explicit_spec): Likewise.
+ (tsubst_function_type): Likewise.
+ (tsubst): Likewise.
+ * tree.c (build_cplus_method_type): Remove.
+ * typeck.c (merge_types): Use build_method_type_directly.
+
+2003-08-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/3765
+ * search.c (dfs_access_in_type): Fix typo in comment.
+ (dfs_accessible_queue_p): Likewise.
+ (dfs_accessible_p): Only terminate when a friend is found.
+ (accessible_p): Return immediately if access_in_type allows
+ access.
+
+2003-08-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/641, c++/11876
+ * friend.c (add_friend): Add complain parameter.
+ (make_friend_class): Likewise.
+ (do_friend): Adjust add_friend call.
+ * decl.c (grokdeclarator): Adjust make_friend_class call.
+ * parser.c (cp_parser_member_declaration): Likewise.
+ (cp_parser_template_declaration_after_export): Likewise.
+ * pt.c (instantiate_class_template): Adjust make_friend_class
+ and add_friend call.
+ * cp-tree.h (make_friend_class): Adjust declaration.
+ (add_friend): Likewise.
+
+2003-08-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/11283
+ * call.c (build_conditional_expr): Ignore cv-qual differences for
+ non-class types.
+
+2003-08-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11551
+ * parser.c (cp_parser_id_expression): Add declarator_p parameter.
+ (cp_parser_primary_expression): Adjust call to
+ cp_parser_id_expression.
+ (cp_parser_unqualified_id): Complain about the use of
+ typedef-names in a destructor declarator.
+ (cp_parser_postfix_expression): Adjust call to
+ cp_parser_id_expression.
+ (cp_parser_type_parameter): Likewise.
+ (cp_parser_template_argument): Likewise.
+ (cp_parser_declarator_id): Likewise.
+
+ PR c++/11919
+ * call.c (standard_conversion): Use same_type_p, not pointer
+ equality, to compare types.
+
+ PR c++/10762
+ * parser.c (cp_parser_using_declaration): Check for invalid uses
+ of template-ids here...
+ * decl2.c (do_class_using_decl): ... rather than here.
+
+2003-08-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11834
+ * pt.c (more_specialized): Bump processing_template_decl.
+
+2003-08-21 Jason Merrill <jason@redhat.com>
+
+ PR c++/11614
+ * decl.c (grokdeclarator): Recognize a flexible array based on the
+ type, not the form of the declarator.
+
+2003-08-20 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (simplify_aggr_init_expr): Split out from
+ simplify_aggr_init_exprs_r. Convert slot address to match
+ the return type.
+ * cp-tree.h: Declare it.
+ * tree.c (cp_copy_res_decl_for_inlining): Don't clobber the
+ DECL_NAME of a user variable.
+
+2003-08-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11945
+ * pt.c (build_non_dependent_expr): Look inside COND_EXPR and
+ COMPOUND_EXPR.
+ * semantics.c (finish_expr_stmt): Always convert to void.
+ * typeck.c (build_x_compound_exp): Always convert to void.
+
+2003-08-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11684
+ * cp-tree.h (grok_op_properties): Change prototype.
+ * decl.c (grok_op_properties): Add complain parameter.
+ (grokfndecl): Pass it.
+ * pt.c (tsubst_decl): Adjust accordingly.
+
+ PR c++/10926
+ * decl.c (start_method): Return immediately if push_template_decl
+ does not like the declaration.
+ * pt.c (push_template_decl_real): Disallow member template
+ destructors.
+
+ PR c++/11036
+ * cp-tree.h (add_binding): Add prototype.
+ * class.c (add_method): Set TYPE_HAS_DESTRUCTOR if appropriate.
+ (maybe_warn_about_overly_private_class): Use
+ CLASSTYPE_DESTRUCTORS.
+ (pushclass): Adjust call to set_identifier_type_value.
+ * decl.c (add_binding): Give it external linkage.
+ (push_local_binding): Adjust call to add_binding.
+ (push_class_binding): Likewise.
+ (set_identifier_type_value_with_scope): Change prototype. Use
+ add_binding for global bindings.
+ (set_identifier_type_value): Adjust accordingly.
+ (pushtag): Likewise.
+ (pushdecl): Use set_identifier_type_value, not
+ set_identifier_type_value_with_scope.
+ (pushdecl_namespace_level): Adjust calls to
+ SET_IDENTIFIER_TYPE_VALUE to pass a DECL.
+ (pushdecl_class_level): Likewise.
+ (lookup_tag): Use select_decl.
+ (select_decl): Improve comment.
+ (record_builtin_type): Do not call pushdecl.
+ (cxx_init_decl_processing): Do not call xref_tag for bad_alloc.
+ (cp_finish_decl): Adjust call to set_identifier_type_value.
+ (check_elaborated_type_specifier): Improve checks for invalid uses
+ of typedefs.
+ (xref_tag): Adjust call to check_elaborated_type_specifier.
+ * decl2.c (grokclassfn): Do not set TYPE_HAS_DESTRUCTOR.
+ * name-lookup.c (set_namespace_binding): Use add_binding.
+ * parser.c (cp_parser_simple_type_specifier): Return a TYPE_DECL,
+ rather than an IDENTIFIER_NODE, to represent built-in types, if
+ requested by the caller.
+ (cp_parser_postfix_expression): Adjust call.
+ (cp_parser_type_specifier): Likewise.
+ (cp_parser_elaborated_type_specifier): Adjust call to
+ check_elaborated_type_specifier.
+ * typeck2.c (build_functional_cast): Do not perform name lookups.
+
+ PR c++/10717
+ * decl.c (expand_static_init): Remove unnecessary code.
+
+2003-08-19 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c++/10538, PR c/5582
+ * cp/cp-lang.c (LANG_HOOKS_DECL_UNINIT): Define.
+
+2003-08-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11174
+ * init.c (build_offset_ref): Perform access checking for
+ pointer to member correctly.
+
+2003-08-19 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-lang.c (LANG_HOOKS_INITIALIZE_DIAGNOSTICS): Fix spelling.
+
+2003-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11957
+ * cp-tree.h (finish_stmt_expr): Add bool parameter.
+ * init.c (finish_init_stmts): Pass true to finish_stmt_expr. Don't
+ adjust the stmt_expr here.
+ (build_vec_init): Use finish_stmt_expr_expr, convert result to
+ array type.
+ * parser.c (cp_parser_primar_expression): Adjust finish_stmt_expr
+ call.
+ * pt.c (tsubst_copy): Likewise.
+ * semantics.c (finish_stmt_expr): Add parameter.
+
+ * pt.c (instantiate_class_template): Push to class's scope before
+ tsubsting base.
+
+2003-08-17 Jan Hubicka <jh@suse.cz>
+
+ PR C++/11702
+ * semantics.c (finish_id_expression): Mark all functions as used.
+
+2003-08-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11512
+ * cvt.c (convert_to_void): Indicate which side of conditional has
+ no effects, and rhs of comma operator. Test for no sideeffect
+ expressions here and always build a convert expr.
+ * init.c (expand_default_init): Convert the init to void.
+ * typeck.c (build_x_compound_expr): Do not check for side effects
+ here.
+ (build_compound_expr): Do not convert lhs when building a
+ template.
+
+2003-08-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.def (NON_DEPENDENT_EXPR): Add operand.
+ * decl2.c (build_offset_ref_call_from_tree): Use
+ build_non_dependent_expr.
+ * error.c (dump_expr) <NON_DEPENDENT_EXPR case>: Dump the operand.
+ * pt.c (build_non_dependent_expr): Set operand.
+
+2003-08-14 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (mark_member_pointers): Rename to...
+ (mark_member_pointers_and_eh_tinfos): ... this one; deal with eh tinfos
+ (lower_function): Update call.
+ * except.c (eh_type_info): Break out from ...
+ (build_eh_type): ... here; tinfo is already used.
+ (finish_eh_spec_block): Mark tinfos as used.
+ * semantics.c (finish_handler_params): Mark tinfo as used.
+ * cp-tree.h (eh_type_info): Declare.
+
+2003-08-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (instantiate_class_template): Set location before
+ substuting bases.
+
+ * decl.c (make_typename_type): Use my_friendly_assert.
+ * pt.c (tsubst_aggr_type): Rearrange context substitution.
+
+2003-08-14 Jan Hubicka <jh@suse.cz>
+
+ * method.c (use_thunk): Expand body directly.
+
+2003-08-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11703
+ * call.c (type_passed_as): Use TYPE_SIZE, not TYPE_PRECISION to
+ determine whether or not to promote types.
+ (convert_for_arg_passing): Likewise.
+ * decl2.c (cp_build_parm_decl): Do not set DECL_ARG_TYPE in
+ templates.
+ * pt.c (tsubst_decl): Do not expect it to be set.
+
+ PR c++/9512
+ PR c++/10923
+ * cp-tree.h (check_elaborated_type_specifier): Declare.
+ (handle_class_head): Remove.
+ (note_got_semicolon): Likewise.
+ (note_list_got_semicolon): Likewise.
+ (finish_class_definition): Likewise.
+ * decl.c (check_elaborated_type_specifier): Make it public.
+ Robustify.
+ (handle_class_head): Remove.
+ * parser.c (cp_parser_elaborated_type_specifier): Use
+ check_elaborated_type_specifier.
+ (cp_parser_class_specifier): Do not call finish_class_definition.
+ (cp_parser_class_head): Or handle_class_head. Check for
+ over-qualified names.
+ * semantics.c (finish_class_definition): Remove.
+
+ * parser.c (cp_parser_check_for_definition_in_return_type): New
+ function.
+ (cp_parser_simple_declaration): Adjust call to
+ cp_parser_init_declarator.
+ (cp_parser_decl_specifier_seq): Change type of
+ declares_class_or_enum parameter.
+ (cp_parser_explicit_instantiation): Adjust accordingly.
+ (cp_parser_type_specifier): Change type of
+ declares_class_or_enum parameter.
+ (cp_parser_init_declarator): Add declares_class_or_enum
+ parameter.
+ (cp_parser_parameter_declaration): Adjust call to
+ cp_parser_decl_specifier_seq.
+ (cp_parser_function_definition): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_single_declaration): Likewise.
+
+ * cp-tree.h (lang_type_class): Remove has_call_overloaded,
+ has_array_ref_overloaded, has_arrow_overloaded, and got_semicolon.
+ (TYPE_OVERLOADS_CALL_EXPR): Remove.
+ (TYPE_OVERLOADS_ARRAY_REF): Likewise.
+ (TYPE_OVERLOADS_ARROW): Likewise.
+ (CLASSTYPE_GOT_SEMICOLON): Likewise.
+ * class.c (check_bases): Do not set them.
+ (finish_struct_1): Likewise.
+ * decl.c (cp_finish_decl): Do not set CLASSTYPE_GOT_SEMICOLON.
+ (build_ptrmemfunc_type): Likewise.
+ (grok_op_properties): Do not set TYPE_OVERLOADS_*.
+ (start_function): Do not check CLASSTYPE_GOT_SEMICOLON.
+ * decl2.c (grokfield): Do not set CLASSTYPE_GOT_SEMICOLON.
+ * lex.c (note_got_semicolon): Remove.
+ (note_list_got_semicolon): Likewise.
+ * parser.c (cp_parser_simple_declaration): Do not call
+ note_list_got_semicolon.
+ * pt.c (list_eq): Remove.
+ (lookup_template_class): Do not set CLASSTYPE_GOT_SEMICOLON.
+ (instantiate_class_template): Do not set TYPE_OVERLOADS*.
+ (instantiate_class_template): Do not set CLASSTYPE_GOT_SEMICOLON.
+ * ptree.c (cxx_print_type): Do not print them.
+ * semantics.c (finish_member_class_template): Do not call
+ note_list_got_semicolon.
+
+2003-08-11 Aldy Hernandez <aldyh@redhat.com>
+
+ * call.c (standard_conversion): Opaque pointers interconvert.
+
+ * testsuite/g++.dg/other/opaque-3.C: New.
+
+2003-08-11 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (merge_types): Handle cv-qualified pointer-to-member
+ types correctly.
+
+2003-08-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11789
+ * cp-tree.h (get_vbase): Remove.
+ (get_vbase_types): Remove.
+ * init.c (expand_member_init): Correct logic for looking up base
+ classes.
+
+2003-08-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_expr): Tidy.
+ * cxx-pretty-print.c (pp_cxx_nonconsecutive_character): New.
+ (pp_cxx_begin_template_argument_list): Likewise.
+ (pp_cxx_end_template_argument_list): Likewise.
+ (is_destructor_name): Likewise.
+ (pp_cxx_unqualified_id): Likewise.
+ (pp_cxx_qualified_id): Likewise.
+ (pp_cxx_id_expression): Likewise.
+ (pp_cxx_new_expression): Likewise.
+ (pp_cxx_delete_expression): Likewise.
+ (pp_cxx_pm_expression): Likewise.
+ (pp_cxx_type_specifier): Rework.
+ (pp_cxx_type_id): Likewise.
+ (pp_cxx_primary_expression): Likewise.
+ (pp_cxx_postfix_expression): Likewise.
+ (pp_cxx_unary_expression): Likewise.
+ (pp_cxx_multiplicative_expression): Likewise.
+ (pp_cxx_conditional_expression): Likewise.
+ (pp_cxx_assignment_expression): Likewise.
+ (pp_cxx_pretty_printer_init): Tidy.
+
+2003-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): non-NULL
+ NODE is always a TREE_VEC of nonzero size.
+ (NUM_TMPL_ARGS): NODE is always a TREE_VEC.
+ * decl2.c (arg_assoc): Template args will be a vec.
+ * error.c (dump_decl) <TEMPLATE_ID_EXPR case>: Call
+ dump_template_argument_list.
+ (dump_template_parms): Args will be a vec.
+ * parser.c (cp_parser_template_argument_list): Produce a
+ vector, not a list.
+ * pt.c (coerce_template_parms): Args are always vectors.
+ (mangle_class_name_for_template): Likewise.
+ (lookup_template_function): Likewise.
+ (lookup_template_class): Likewise.
+ (tsubst_template_args): Likewise.
+ (tsubst_baselink): Use tsubst_template_args.
+ (tsubst_qualified_id): Likewise.
+ (tsubst_copy) <TEMPLATE_ID_EXPR case>: Likewise.
+ (tsubst_copy_and_build) <TEMPLATE_ID_EXPR case>: Likewise.
+ (any_dependent_template_args_p): Args are always vectors.
+ * tree.c (cp_tree_equal): Add TEMPLATE_ID_EXPR case.
+
+ PR c++/11670
+ * call.c (convert_like_real): Add rvalue binding error message.
+ * error.c (dump_expr) <NOP_EXPR case>: Detect when the no expr is
+ really a cast.
+
+ PR c++/10530
+ * pt.c (dependent_type_p_r): A dependent template-id is a class
+ type with dependent template arguments, or a bound template
+ template parameter.
+ (type_dependent_expression_p): A template function decl cannot
+ have a dependent context.
+
+2003-08-07 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/5767
+ * parser.c (cp_parser_class_name): Return immediately when scope
+ is error_mark_node.
+
+2003-08-07 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp/Make-lang.in (cp/call.o): Add dependency for target.h.
+
+ * cp/call.c (standard_conversion): Support opaque types.
+ Include target.h.
+ (strip_top_quals): Use cp_build_qualified_type instead of
+ TYPE_MAIN_VARIANT.
+
+ * cp/typeck.c (convert_for_assignment): Support opaque types.
+
+ * testsuite/g++.dg/other/opaque-1.C: New.
+
+ * testsuite/g++.dg/other/opaque-2.C: New.
+
+2003-08-06 Aldy Hernandez <aldyh@redhat.com>
+
+ * decl.c (grokparms): Use cp_build_qualified_type instead
+ TYPE_MAIN_VARIANT.
+
+2003-08-05 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h: New file.
+ * cxx-pretty-print.c: Likewise.
+ * error.c (scratch_pretty_printer): Change type.
+ (init_error): Tidy.
+ (dump_aggr_type): Likewise.
+ (dump_global_iord): Likewise.
+ (dump_expr): Likewise.
+ (dump_char): Remove.
+ * cp-lang.c (LANG_HOOKS_INITIALIZE_DIAGNOSTITCS): Define.
+ (cxx_initialize_diagnostics): New function.
+ * Make-lang.in (CXX_OBJS): Add cp/cxx-pretty-print.o
+ (CXX_PRETTY_PRINT_H): New variable.
+ (cp/cxx-pretty-print.o): New rule.
+ (cp/cp-lang.o): Update dependence.
+ (cp/error.o): Likewise.
+
+2003-08-05 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cp-tree.h (struct lang_decl): Don't include c_lang_decl.
+ (DECL_DECLARED_INLINE_P): Remove.
+ * decl2.c (import_export_decl): Only look at DECL_DECLARED_INLINE_P
+ if decl is a FUNCTION_DECL. This never made sense, but now it is
+ required to avoid a tree check failure.
+ * decl.c (grokfndecl): Don't touch DID_INLINE_FUNC.
+ * optimize.c (maybe_clone_body): Likewise.
+
+2003-08-04 Roger Sayle <roger@eyesopen.com>
+
+ * decl.c (cxx_insert_default_attributes): Delete.
+ * cp-tree.h (cxx_insert_default_attributes): Don't prototype.
+ * cp-lang.c (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Don't define.
+
+2003-08-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11704
+ * pt.c (type_dependent_expression_p): Cope with COMPONENT_REF with
+ unknown type.
+
+ PR c++/11766
+ * typeck.c (comp_ptr_ttypes_real): Don't loop on pointers to
+ member functions.
+
+2003-08-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9447
+ * cp-tree.def (USING_DECL): Document its type.
+ * class.c (pushclass): If we're entering a template, push any
+ dependent using decls it has.
+ * decl2.c (do_class_using_decl): Refactor. Type is NULL iff it is
+ a dependent scope.
+ * pt.c (tsubst_decl) <USING_DECL case>: Set type.
+ (tsubst): Remove USING_DECL checks.
+ (type_dependent_expression_p): Remove USING_DECL case.
+ * semantics.c (finish_member_declaration): A USING_DECL's type
+ indicates whether it is dependent.
+
+2003-08-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (pushclass): Remove unneeded parameter.
+ * class.c (pushclass): Remove unneeded MODIFY parm. Adjust.
+ (push_nested_class): Adjust pushclass call.
+ * pt.c (instantiate_class_template): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+
+2003-08-01 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * typeck2.c (add_exception_specifier): Use 'bool' where appropriate.
+
+2003-08-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11697
+ * decl.c (decls_match): Don't ignore the types of template
+ classes.
+
+ PR c++/11744
+ * pt.c (tsubst_copy_and_build): Refine Koenig lookup logic.
+
+2003-08-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8442, c++/8806
+ * decl.c (qualify_lookup): Accept TEMPLATE_DECL if types are
+ preferred.
+ (check_elaborated_type_specifier): Add allow_template_p
+ parameter. Check tag mismatch and class template.
+ (xref_tag): Add template_header_p parameter. Add assertion
+ that name is an IDENTIFIER_NODE. Remove implicit typename
+ warning. Simplify lookup process if globalize is true.
+ (cxx_init_decl_processing): Adjust call to xref_tag.
+ (xref_tag_from_type): Likewise.
+ * decl2.c (handle_class_head): Likewise.
+ * parser.c (cp_parser_elaborated_type_specifier,
+ cp_parser_class_head): Likewise.
+ * rtti.c (init_rtti_processing, build_dynamic_cast1,
+ tinfo_base_init, emit_support_tinfos): Likewise.
+ * class.c (is_base_of_enclosing_class): Remove.
+ * pt.c (convert_template_argument): Don't accept RECORD_TYPE as
+ template template argument.
+ * cp-tree.h (xref_tag): Adjust declaration.
+ (is_base_of_enclosing_class): Remove.
+ * NEWS: Document template template argument change.
+
+2003-08-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parser.c (cp_parser_init_declarator,
+ cp_paser_member_declaration): Reformat.
+ * pt.c (lookup_template_class, type_unification_real, unify,
+ type_dependent_expression_p): Reformat.
+
+ PR c++/11295
+ * cp-tree.h (tubst_flags_t): Add tf_stmt_expr_cmpd,
+ tf_stmt_expr_body.
+ (finish_stmt_expr_expr): Declare.
+ * parser.c (cp_parser_primary_expression): Tell
+ cp_parser_compount_statement that it is a statement expression.
+ (cp_parser_statement, cp_parser_labeled_statement,
+ cp_parser_compound_statement, cp_parser_statement_seq_opt): Add
+ in_statement_expr_p parameter.
+ (cp_parser_expression_statement): Likewise. Call
+ finish_stmt_expr_expr for final expression of a statement
+ expression.
+ (cp_parser_for_init_statement,
+ cp_parser_implicitly_scoped_statement,
+ cp_parser_already_scoped_statement, cp_parser_function_definition,
+ cp_parser_try_block, cp_parser_handled): Adjust.
+ * pt.c (tsubst_copy) <STMT_EXPR case>: Pass tf_stmt_expr.
+ (tsubst_expr): Process tf_stmt_expr and tf_stmt_exprs flags.
+ (tsubst_expr) <EXPR_STMT case>: Check tf_stmt_exprs flag.
+ * semantics.c (finish_expr_stmt): Do not deal with statement
+ expressions.
+ (begin_stmt_expr): Clear last_expr_type.
+ (finish_stmt_expr_expr): New.
+ (finish_stmt_expr): Process the value expression.
+
+ * typeck.c (build_compound_expr): If RHS is a TARGET_EXPR, put the
+ compound expr inside the target's initializer.
+
+ PR c++/11525
+ * parser.c (cp_parser_primary_expression): Do not set
+ non-constant-p merely because it is a dependent scope.
+
+ PR c++/9447
+ * decl2.c (do_class_using_decl): Set type to NULL_TREE.
+ * semantics.c (finish_expr_stmt): Do not convert to void in a
+ template.
+
+2003-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (coerce_template_parms): Refactor.
+ (fn_type_unification): Increment processing_template_decl when
+ tsubsting an incomplete set of explicit args.
+
+ PR c++/11347
+ * pt.c (instantiate_class_template): Increment
+ processing_template_decl around the tsubst of a template member
+ class.
+ (tsubst_qualified_id): Assert we do not have a dependent scope.
+
+ * pt.c (coerce_template_template_parms, lookup_template_class,
+ can_complete_type_without_circularity, instantiate_class_template,
+ tsubst_decl, unify): Reformat.
+
+2003-07-31 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (maybe_make_one_only): Use mark_referenced.
+ * method.c (use_thunk): Likewsie.
+
+2003-07-30 Jan Hubicka <jh@suse.cz>
+
+ * class.c (build_vtable_entry_ref): Kill.
+ (build_vtbl_ref_1): Do not call build_vtable_entry_ref.
+ (build_vfn_ref): Do not call build_vtable_entry_ref.
+ * cp-lang.c (LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE): Kill.
+ * cp-tree.h (prepare_assemble_variable): Kill.
+ * cp-decl.c (prepare_assemble_variable): Kill.
+
+2003-07-29 Geoffrey Keating <geoffk@apple.com>
+
+ * parser.c (cp_lexer_new_main): Use c_common_no_more_pch instead
+ of setting valid_pch by hand.
+
+2003-07-29 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * decl.c (finish_enum): Initialize underlying_type.
+
+2003-07-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9447
+ * decl.c (add_binding): Add bval local variable.
+ (push_class_level_binding): Likewise. Allow a USING_DECL to be
+ pushed.
+ * decl2.c (do_class_using_decl): The type of a using decl is
+ unknown.
+ * parser.c (cp_parser_postfix_expression): Refactor unqualified-id
+ function call lookup code.
+ * pt.c (tsubst): A USING_DECL will have unknown type.
+ (tsubst_copy_and_build): Allow a using decl.
+ (type_dependent_expression_p): A USING_DECL will make it
+ dependent.
+ * semantics.c (finish_member_declaration): Push a dependent using
+ declaration.
+
+2003-07-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11530
+ * parser.c (cp_parser_postfix_expression): Do not call mark_used.
+ * semantics.c (finish_id_expression): Call mark_used for all
+ declarations.
+
+2003-07-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11667
+ * call.c (standard_conversion): Allow all integral->enumeral
+ conversions, after marking them as bad.
+ * decl.c (finish_enum): Make sure that all enumerators are
+ properly converted to the underlying type.
+ (build_enumerator): Set DECL_CONTEXT for namespace-scope
+ enumeration types.
+ * pt.c (tsubst_copy): Adjust handling of CONST_DECLs accordingly.
+ (tsubst_enum): Tidy.
+
+ * Make-lang.in (typeck.o): Depend on convert.h.
+ (class.o): Likewise.
+ (rtti.o): Likewise.
+ * call.c: Include convert.h.
+ (convert_arg_to_ellipsis): Use convert_to_real.
+ * class.c: Include convert.h.
+ (build_base_path): Use convert_to_integer.
+ * rtti.c: Include convert.h.
+ (build_headof): Use convert_to_integer.
+ * typeck.c: Include convert.h.
+ (decay_conversion): Use convert_to_integer.
+ (build_unary_op): Use build_nop.
+ (get_delta_difference): Use convert_to_integer.
+ (build_ptrmemfunc): Avoid unnecessary conversions.
+
+2003-07-28 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (mark_member_pointers): Verify that member pointer points to
+ the function.
+
+2003-07-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (begin_compound_stmt): No scope arg is a bool.
+ (finish_compound_stmt): Remove no scope arg.
+ * decl.c (register_dtor_fn): Adjust begin_compound_stmt and
+ end_compound_stmt calls.
+ (expand_static_init, begin_destructor_body, begin_function_body,
+ finish_function_body): Likewise.
+ * decl2.c (start_objects, finish_objects,
+ start_static_storage_duration_function,
+ finish_static_storage_duration_function): Likewise.
+ * init.c (begin_init_stmts, finish_init_stmts,
+ construct_virtual_base, build_vec_init): Likewise.
+ * method.c (do_build_assign_ref, synthesize_method): Likewise.
+ * parser.c (cp_parser_compound_statement,
+ cp_parser_implicitly_scoped_statement,
+ cp_parser_already_scoped_statement): Likewise.
+ * pt.c (tsubst_expr): Likewise.
+ * semantics.c (begin_compound_stmt): No scope arg is a bool.
+ (finish_compound_stmt): Remove no scope arg.
+
+ * error.c (dump_expr) <COMPOUND_EXPR case>: A compound expr is
+ always dyadic.
+
+2003-07-27 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (standard_conversion): Tweak handling of
+ pointer-to-member types.
+ * pt.c (tsubst): Correctly qualify pointers-to-data member types.
+ * typeck.c (comp_ptr_ttypes_real): Check qualifiers on
+ pointer-to-data member types.
+
+2003-07-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parser.c (cp_parser_type_parameter): Reformat.
+ (cp_parser_parameter_declaration): Deprecate default args where
+ not allowed.
+
+2003-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cfns.h: Rebuilt.
+
+ * cp-tree.h (begin_init_stmts, finish_init_stmts): Remove.
+ (begin_global_stmt_expr, finish_global_stmt_expr): Remove.
+ * init.c (begin_init_stmts): Make static. Return is_global
+ value. Always call begin_stmt_expr.
+ (finish_init_stmts): Make static. Add is_global parm. Always
+ building a stmt tree.
+ (build_aggr_init): Adjust begin_init_stmts, finish_init_stmts calls.
+ (build_vec_init): Likewise. Always building a stmt tree.
+ (expand_default_init): Always building a stmt tree.
+ (get_temp_regvar): Likewise.
+ * semantics.c (begin_global_stmt_expr,
+ finish_global_stmt_expr): Remove.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (build_compound_expr): Take LHS & RHS args.
+ (build_x_compound_expr_from_list): Declare.
+ * typeck.c (build_x_compound_expr_from_list): New.
+ (build_x_compound_expr): Adjust.
+ (build_compound_expr): Remove unreachable code. Take two
+ parameters, adjust.
+ * decl.c (grok_reference_init): Use
+ build_x_compound_expr_from_list.
+ (expand_static_init): Adjust build_compound_expr call.
+ (cxx_maybe_build_cleanup): Likewise.
+ * init.c (perform_member_init): Use
+ build_x_compound_expr_from_list.
+ (build_new_1): Likewise.
+ (build_vec_delete): Adjust build_compound_expr calls.
+ (build_vbase_delete): Likewise.
+ * typeck2.c (store_init_value): Use
+ build_x_compound_expr_from_list.
+ (build_functional_cast): Likewise.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (enum tsubst_flags_t): Add tf_user.
+ * decl.c (make_typename_type): Pass it.
+ * pt.c (lookup_template_class): Use it.
+ (resolve_typename_type): Pass it.
+ * semantics.c (finish_template_type): Pass it.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11617
+ * cp-tree.h (qualified_name_lookup_error): Declare.
+ * pt.c (tsubst_qualified_id): Use qualified_name_lookup_error for
+ errors.
+ (tsubst_expr) <DECL_STMT case>: Likewise.
+ (tsubst_copy_and_build) <COMPONENT_REF case>: Likewise.
+ * semantics.c (qualified_name_lookup_error): New, broken out of ...
+ (finish_id_expression): ... here. Use it.
+
+2003-07-25 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
+
+ * cfns.gperf: Add '%%' delimiter to placate gperf 3.0.
+
+2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11596
+ * pt.c (maybe_fold_nontype_arg, maybe_fold_nontype_args): Remove.
+ (tsubst_template_arg): New.
+ (tsubst_template_arg_vector): Rename to ...
+ (tsubst_template_args): ... this. Accept a TREE_LIST form. Use
+ tsubst_template_arg.
+ (coerce_template_parms): Use tsubst_template_arg for default
+ value.
+ (tsubst_template_parms): Likewise.
+ (tsubst_aggr_type): Adjust.
+ (tsubst_decl): Likewise.
+ (tsubst): Use tsubst_template_arg for a DOMAIN. Adjust.
+ (tsubst_copy) <TEMPLATE_ID_EXPR case>: Use tsubst_template_args.
+
+2003-07-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * Make-lang.in (cp/error.o): Depend on DIAGNOSTIC_H.
+ * error.c: Use the new pretty-printer framework.
+
+2003-07-24 Per Bothner <pbothner@apple.com>
+
+ * decl.c (pushdecl_class_level): Don't use push_srcloc/pop_srcloc
+ which causes errors messages to incorrectly mention included files.
+
+2003-07-24 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (convert_to_base_statically): Declare.
+ * call.c (build_special_member_call): Convert INSTANCE to the base
+ type.
+ * class.c (convert_to_base_statically): New method.
+ * init.c (construct_virtual_base): Use it.
+ * method.c (do_build_assign_ref): Fix typo in comment.
+
+2003-07-24 Jason Merrill <jason@redhat.com>
+
+ * decl.c: Just set truthvalue_* to boolean_*.
+
+2003-07-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (reshape_init): Remove unreachable code.
+
+2003-07-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11513
+ * cp-tree.h (PROCESSING_REAL_TEMPLATE_DECL_P): Use current_scope.
+
+2003-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11645
+ * cp-tree.h (accessible_base_p): Declare.
+ * call.c (build_over_call): Use it.
+ * search.c (accessible_base_p): New function, split out from ...
+ (lookup_base): ... here.
+
+ PR c++/11517
+ * call.c (build_conditional_expr): Use perform_implicit_conversion
+ and error_operand_p. Robustify.
+ * typeck.c (build_unary_op): Use perform_implicit_conversion.
+
+2003-07-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10953
+ * parser.c (cp_parser_nested_name_specifier): Reset scope on
+ failure.
+ (cp_parser_elaborated_type_specifier): Likewise.
+
+2003-07-22 Mark Mitchell <mark@codesourcery.com>
+
+ Eliminate use of POINTER_TYPE for pointers-to-members.
+ * call.c (standard_conversion): Rework pointer-to-member handling.
+ Add comments.
+ (add_builtin_candidate): Likewise.
+ (resolve_scoped_fn_name): Remove.
+ (build_conditional_expr): Rework pointer-to-member handling.
+ (compare_ics): Likewise.
+ * class.c (check_field_decls): Use TYPE_PTR_P.
+ * cp-lang.c (cp_var_mod_type_p): Rework pointer-to-member
+ handling.
+ * cp-tree.h (SCALAR_TYPE_P): Use TYPE_PTR_TO_MEMBER_P.
+ (TYPE_PTRMEM_P): Add comment.
+ (TYPE_PTR_P): Simplify.
+ (TYPE_PTROB_P): Correct definition.
+ (TYPE_PTR_TO_MEMBER_P): New macro.
+ (TYPE_PTRMEM_CLASS_TYPE): Adjust.
+ (TYPE_PTRMEM_POINTED_TO_TYPE): Likewise.
+ (resolved_scoped_fn_name): Remove declaration.
+ (build_offset_ref): Change prototype.
+ (resolve_offset_ref): Remove.
+ (comp_target_types): Remove.
+ * cvt.c (cp_convert_to_pointer): Rework pointer-to-member
+ handling.
+ (convert_to_reference): Use can_convert.
+ (ocp_convert): Improve error handling. Rework pointer-to-member
+ handling.
+ (perform_qualification_conversions): Rework pointer-to-member
+ handling.
+ * decl.c (build_ptrmem_type): Handle functions too.
+ (create_array_type_for_decl): Remove OFFSET_TYPE error message.
+ (grokdeclarator): Use OFFSET_TYPE for pointers to data members.
+ (grokparms): Remove OFFSET_TYPE error message.
+ * dump.c (cp_dump_tree): Rework pointer-to-member handling.
+ * error.c (dump_type_prefix): Likewise.
+ * expr.c (cplus_expand_constant): Use build_nop.
+ * init.c (build_offset_ref): Add address_p parameter. Fold in
+ necessary bits from resolve_offset_ref.
+ (resolve_offset_ref): Remove.
+ * parser.c (cp_parser_postfix_expression): Remove special case
+ code for OFFSET_TYPE.
+ * pt.c (convert_nontype_argument): Rework pointer-to-member
+ handling.
+ (convert_template_argument): Likewise.
+ (unify): Likewise.
+ (invalid_nontype_parm_type_p): Likewise.
+ (dependent_type_p_r): Likewise.
+ * rtti.c (get_tinfo_decl): Remove OFFSET_TYPE special case.
+ (target_incomplete_p_): Rework pointer-to-member
+ handling.
+ (get_pseudo_ti_init): Likewise.
+ (get_pseudo_ti_desc): Likewise.
+ * semantics.c (finish_qualified_id_expr): Adjust call to
+ build_offset_ref. Remove use of resolve_offset_ref.
+ * tree.c (pod_type_p): Use TYPE_PTR_TO_MEMBER_P.
+ * typeck.c (target_type): Use TYPE_PTRMEM_P.
+ (type_unknown_p): Remove obsolete code about the time before
+ non-dependent expressions were handled correctly.
+ (qualify_type_recursive): Remove.
+ (composite_pointer_type_r): New function.
+ (composite_pointer_type): Use it.
+ (merge_types): Remove dead comments.
+ (comp_cv_target_types): Remove.
+ (comp_target_types): Likewise.
+ (comp_target_parms): Likewise.
+ (cxx_sizeof_or_alignof_type): Remove OFFSET_TYPE error.
+ (build_indirect_ref): Use TYPE_PTR_TO_MEMBER_P.
+ (build_binary_op): Do not use of comp_target_types.
+ (pointer_diff): Remove OFFSET_TYPE case.
+ (build_unary_op): Adjust pointer-to-member handling.
+ (unary_complex_lvalue): Likewise.
+ (check_for_casting_away_constness): Add description parameter.
+ (build_static_cast): Pass it.
+ (build_reinterpret_cast): Use check_for_casting_away_constness.
+ (build_const_cast): Adjust pointer-to-member handling.
+ (build_c_cast): Likewise.
+ (convert_for_assignment): Remove OFFSET_TYPE error message.
+ (comp_ptr_ttypes_real): Adjust pointer-to-member handling.
+ (comp_ptr_ttypes_reinterpret): Remove.
+ (casts_away_constness_r): Adjust pointer-to-member handling.
+ (casts_away_constness): Liekwise.
+ (strip_all_pointer_quals): Remove.
+ * typeck2.c (digest_init): Adjust pointer-to-member handling.
+ (build_m_component_ref): Likewise.
+
+2003-07-22 Wolfgang Bangerth <bangerth@dealii.org>
+
+ * lex.c (unqualified_fn_lookup_error): Mention that the error
+ message needs to be kept in synch with the manual.
+
+2003-07-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11614
+ * decl.c (grokdeclarator): An array member is only a flexible
+ array member if the field itself is the array.
+
+2003-07-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10793
+ * decl.c (xref_basetypes): Handle error_mark_node.
+
+2003-07-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (enum cp_lvalue_kind): Add clk_packed.
+ * tree.c (lvalue_p_1): Set it.
+ * class.c (check_field): Don't allow non-packed non-POD fields to
+ be packed.
+ * call.c (reference_binding): Need a temporary for all bitfield
+ and packed fields.
+ (convert_like_real): Check it is ok to make a temporary here.
+
+2003-07-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (hack_identifier): Remove.
+ * method.c (hack_identifier): Remove.
+ * semantics.c (finish_id_expression): Expand hack_identifier
+ here. Simplify.
+
+2003-07-19 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c class.c decl.c decl2.c g++spec.c lex.c parser.c pt.c rtti.c
+ semantics.c typeck.c: Remove unnecessary casts.
+
+2003-07-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (hack_identifier): Remove.
+ * method.c (hack_identifier): Remove.
+ * semantics.c (finish_id_expression): Expand hack_identifier
+ here. Simplify.
+
+2003-07-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (finish_non_static_data_member): Add object param.
+ * method.c (hack_identifier): Adjust.
+ * pt.c (tsubst_copy_and_build) <COMPONENT_REF case>: Don't search
+ again for a FIELD_DECL.
+ * semantics.c (finish_non_static_data_member): Add object
+ parameter. Always save the DECL in the COMPONENT_REF.
+ * call.c (resolve_scoped_fn_name): Adjust.
+
+2003-07-17 Zack Weinberg <zack@codesourcery.com>
+
+ * pt.c (get_bindings): Make definition consistent with
+ forward declaration.
+
+2003-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/7809
+ * friend.c (add_friend): Check access for member functions
+ and templates.
+
+2003-07-17 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10668
+ * typeck.c (build_class_member_access_expr): Improve diagnostic.
+
+2003-07-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11547
+ * cp-tree.h (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P): New
+ macro.
+ (DECL_PRETTY_FUNCTION_P): Use VAR_DECL_CHECK.
+ * decl.c (duplicate_decls): Merge
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+ * parser.c (cp_parser_postfix_expression): Adjust call to
+ cp_parser_initializer_list and
+ cp_parser_parenthesized_expression_list.
+ (cp_parser_parenthesized_expression_list): Add non_constant_p.
+ (cp_parser_new_placement): Adjust call to
+ cp_parser_parenthesized_expression_list.
+ (cp_parser_direct_new_declarator): Likewise.
+ (cp_parser_conditional_expression): Remove.
+ (cp_parser_constant_expression): Parse an assignment-expression,
+ not a conditional-expression.
+ (cp_parser_simple_declaration): Resolve expression/declaration
+ ambiguity more quickly.
+ (cp_parser_mem_initializer): Adjust call to
+ cp_parser_parenthesized_expression_list.
+ (cp_parser_init_declarator): Keep track of whether or not the
+ initializer is a constant-expression.
+ (cp_parser_initializer): Add non_constant_p parameter.
+ (cp_parser_initializer_clause): Likewise.
+ (cp_parser_initializer_list): Likewise.
+ (cp_parser_attribute_list): Adjust call to
+ cp_parser_parenthesized_expression_list.
+ (cp_parser_functional_cast): Likewise.
+ * pt.c (tsubst_decl): Copy
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+ (tsubst_expr): Tweak use of DECL_PRETTY_FUNCTION_P.
+ * semantics.c (finish_id_expression): Use
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
+
+2003-07-16 Neil Booth <neil@daikokuya.co.uk>
+
+ * lang-options.h: Remove.
+
+2003-07-16 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR c/10962
+ * class.c (field_decl_cmp): Remove.
+ (resort_field_decl_cmp): Remove.
+ (resort_sorted_fields): Remove.
+ (add_fields_to_vec): Rename to ...
+ (add_fields_to_record_type): this.
+ (finish_struct_1): Change to be using
+ sorted_fields_type's fields.
+ * cp-tree.h (lang_decl): In lang_decl_u3
+ change sorted_fields to be a pointer to
+ sorted_fields_type.
+ (resort_sorted_fields): Remove prototype.
+ * search.c (lookup_field_1): Change to be using
+ sorted_fields_type's fields.
+
+2003-07-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/5421
+ * decl.c (grokdeclarator): Handle TEMPLATE_ID_EXPR if friend
+ is a member of other class.
+ * friend.c (do_friend): Don't build TEMPLATE_DECL if friend
+ is a specialization of function template.
+
+2003-07-16 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10903
+ * pt.c (convert_nontype_argument): Fix thinko in diagnostic.
+ Improve.
+
+2003-07-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (LOOKUP_EXPR): Remove.
+ * cp-tree.h (cp_id_kind): Add CP_ID_KIND_UNQUALIFIED_DEPENDENT.
+ (LOOKUP_EXPR_GLOBAL): Remove.
+ (get_bindings): Remove.
+ (is_aggr_type_2): Remove.
+ * call.c (resolved_scoped_fn_name): Remove support for
+ LOOKUP_EXPR.
+ * decl.c (grokfndecl): Likewise.
+ (grokdeclarator): Likewise.
+ * error.c (dump_decl): Likewise.
+ (dump_expr): Likewise.
+ * friend.c (do_friend): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * lex.c (unqualified_fn_lookup_error): Use pedwarn. Do not create
+ LOOKUP_EXPRs
+ * mangle.c (write_expression): Remove support for LOOKUP_EXPR.
+ * parser.c (cp_parser_postfix_expression): Modify Koenig lookup
+ test.
+ * pt.c (get_bindings): Give it internal linkage.
+ (check_explicit_specialization): Remove support for LOOKUP_EXPR.
+ (lookup_template_function): Likewise.
+ (for_each_tempalte_parm_r): Likewise.
+ (tsubst_decl): Likewise.
+ (tsubst_qualified_id): Handle template template parameters.
+ (tsubst_copy): Remove support for LOOKUP_EXPR.
+ (tsubst_copy_and_build): Likewise.
+ (most_general_template): Likewise.
+ (value_dependent_expression_p): Likewise.
+ (type_dependent_expression_p): Note that IDENTIFIER_NODEs are
+ always dependent.
+ * semantics.c (perform_koenig_lookup): Do not create
+ IDENTIFIER_NODEs.
+ (finish_fname): Likewise.
+ (finish_id_expression): Likewise.
+ * tree.c (is_aggr_type_2): Remove.
+
+2003-07-16 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/11531
+ * typeck.c (check_return_expr): Fix thinko in diagnostic.
+
+2003-07-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10108
+ * pt.c (tsubst_decl) <TEMPLATE_DECL>: Add a check for
+ error_mark_node.
+
+2003-07-14 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11509
+ * pt.c (dependent_scope_ref_p): New function.
+ (value_dependent_expression_p): Use it.
+ (type_dependent_expression_p): Likewise.
+
+ * pt.c (tsubst_friend_function): Use reregister_specialization.
+
+ PR c++/7019
+ * cp-tree.h (lookup_qualified_name): Adjust prototype.
+ * decl.c (lookup_qualified_name): Add complain parameter. Adjust
+ call to is_aggr_type.
+ * parser.c (cp_parser_lookup_name): Adjust call to
+ lookup_qualified_name.
+ * pt.c (tsubst_qualified_id): Likewise.
+ (tsubst_copy_and_build): Likewise.
+ * semantics.c (finish_qualified_id_expr): Deal with erroneous
+ expressions.
+
+2003-07-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/11510
+ * call.c (op_error): Properly format REALPART_EXPR and
+ IMAGPART_EXPR.
+ * error.c (dump_expr): Likewise.
+
+2003-07-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_expr): Handle EMPTY_CLASS_EXPR.
+
+2003-07-14 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/5293
+ * call.c (initialize_reference): Improve diagnostic.
+
+2003-07-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11154
+ * pt.c (more_specialized_class): Add full_args parameter.
+ (most_specialized_class): Adjust calls to more_specialized_class.
+ * cp-tree.h (more_specialized_class): Adjust declaration.
+
+2003-07-14 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * lex.c (enum tree_node_kind): Delete.
+
+2003-07-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11503
+ * cp-tree.h (DECL_SELF_REFERENCE_P): New macro.
+ (SET_DECL_SELF_REFERENCE_P): Likewise.
+ * class.c (build_self_reference): Use SET_DECL_SELF_REFERENCE_P.
+ * pt.c (tsubst_decl): Copy it.
+ * search.c (lookup_base): Use DECL_SELF_REFERENCE_P.
+
+ * pt.c (reregister_specialization): Fix thinko in previous change.
+
+ * cp-tree.h (cp_id_kind): New type.
+ (unqualified_name_lookup_error): Change prototype.
+ (unqualified_fn_lookup_error): New function.
+ (do_identifier): Remove.
+ (do_scoped_id): Likewise.
+ (tsubst_copy_and_build): Change prototype.
+ (reregister_specialization): New function.
+ (perform_koenig_lookup): Likewise.
+ (finish_id_expression): Likewise.
+ * call.c (build_method_call): Adjust call to
+ unqualified_name_lookup_error.
+ * decl.c (duplicate_decls): Use reregister_specialization.
+ * lex.c (is_global): Remove.
+ (unqualified_name_lookup_error): Return a value.
+ (do_identifier): Remove.
+ (do_scoped_id): Likewise.
+ (identifier_typedecl_value): Remove.
+ (unqualified_fn_lookup_error): New function.
+ * parser.c (cp_parser_id_kind): Remove.
+ (cp_parser_non_constant_id_expression): Remove.
+ (cp_parser_primary_expression): Use finish_id_expression.
+ (cp_parser_class_or_namespace_name): Use cp_id_kind, not
+ cp_parser_id_kind.
+ (cp_parser_postfix_expression): Use perform_koenig_lookup.
+ (cp_parser_template_argument): Use cp_id_kind.
+ (cp_parser_fold_non_dependent_expr): Adjust call to
+ tsubst_copy_and_build.
+ * pt.c (unregister_specialization): Rename to ...
+ (reregister_specialization): This.
+ (tsubst_friend_function): Use it.
+ (maybe_fold_nontype_arg): Adjust call to tsubst_copy_and_build.
+ (tsubst_qualified_id): Likewise.
+ (tsubst_expr): Likewise.
+ (tsubst_copy_and_build): Add function_p parameter. Use
+ finish_id_expression. Introduce RECUR macro.
+ (tsubst_non_call_postfix_expression): New function.
+ (regenerate_decl_from_template): Use reregister_specialization.
+ * semantics.c (perform_koenig_lookup): New function.
+ (finish_id_expression): Likewise.
+
+2003-07-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (push_access_scope_real): Remove.
+ (push_access_scope): Move code from push_access_scope_real.
+ (pop_access_scope): Don't check for TEMPLATE_DECL.
+ (instantiate_template): Defer access checking during template
+ substitution.
+ (regenerate_decl_from_template): Tidy.
+
+2003-07-11 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ PR c++/11437
+ * operators.def: Add definitions for __imag__, __real__.
+
+2003-07-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/11050
+ * parser.c (cp_parser_expression_list): Rename to ...
+ (cp_parser_parenthesized_expression_list): ... here. Add attribute
+ parameter, parse the surounding parentheses.
+ (cp_parser_skip_to_closing_parenthesis): Add recover and or_comma
+ parameters. Return int.
+ (cp_parser_skip_to_closing_parenthesis or comma): Remove.
+ (cp_parser_postfix_expression): Adjust function call parsing.
+ (cp_parser_new_placement): Adjust.
+ (cp_parser_new_initializer): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_selection_statement): Likewise.
+ (cp_parser_mem_initializer): Likewise.
+ (cp_parser_asm_definition): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_declarator): Make
+ cdtor_or_conv_p an int ptr.
+ (cp_parser_direct_declarator): Likewise. Check for a parameter
+ list on cdtors & conv functions.
+ (cp_parser_initializer): Adjust.
+ (cp_parser_member_declaration): Adjust.
+ (cp_parser_attribute_list): Move code into
+ cp_parser_parens_expression_list.
+ (cp_parser_functional_cast): Adjust.
+ * pt.c (type_dependent_expression_p): Erroneous expressions are
+ non-dependent.
+
+2003-07-11 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (cp_finish_decl): Handle 'used' attribute.
+
+ * cp-lang.c (c_reset_state): New dummy routine.
+ * cp-tree.h (finish_file): Move prototype to c-common.h.
+ * parser.c (c_parse_file): Rename from yyparse; don't call finish_file.
+
+2003-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8327
+ * pt.c (tsubst_qualified_id): Implement suggested resolution for
+ Core Issue 2.
+ (type_dependent_expression_p): Likewise.
+
+2003-07-10 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_binary_op): Do not warn about signed
+ vs. unsigned comparisons in the bodies of templates.
+
+ PR c++/9411
+ * parser.c (cp_parser_postfix_expression): Check dependency of
+ functions.
+
+2003-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10032
+ * decl.c (cxx_init_decl_processing): With -pedantic, pedwarns are
+ still errors.
+
+ PR c++/10527
+ * error.c (decl_to_string): Do not print default argument
+ expressions.
+
+ * cp-tree.h (break_out_calls): Remove declaration.
+ * tree.c (break_out_calls): Remove.
+ * typeck.c (build_modify_expr): Avoid invalid sharing of trees.
+
+2003-07-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++ 9483
+ * class.c (check_field_decls): Pass DECL_NAME to constructor_name_p.
+ * decl2.c (constructor_name_p): Avoid repeated constructor_name
+ calls.
+ * decl.c (grokdeclarator): Refactor ctor/dtor detection.
+
+2003-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_x_unary_op): Take note of the fact that
+ PREINCREMENT_EXPR and POSTINCREMENT_EXPR are binary operations on
+ trees.
+
+ * parser.c (cp_parser_primary_expression): Preserve the form of
+ qualified expressions in templates, even if they are not
+ dependent.
+ * pt.c (convert_nontype_argument): Handle non-dependent SCOPE_REFs.
+ (tsubst_qualified_id): Likewise.
+ * search.c (accessible_p): Treat everything in the body of a
+ template as accessible.
+
+2003-07-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (NON_DEPENDENT_EXPR): New node.
+ * cp-tree.h (build_call_from_tree): Remove.
+ (build_member_call): Likewise.
+ (dependent_template_arg_p): Remove.
+ (any_dependent_template_arguments_p): New function.
+ (dependent_template_id_p): Likewise.
+ (any_type_dependent_arguments_p): Likewise.
+ (build_non_dependent_expr): Likewise.
+ (build_non_dependent_args): Likewise.
+ (build_x_compound_expr): Adjust prototype.
+ * call.c (build_new_method_call): Handle non-dependent expressions
+ correctly.
+ * decl2.c (grok_array_decl): Likewise.
+ (build_offset_ref_call_from_tree): Likewise.
+ (build_call_from_tree): Remove.
+ * error.c (dump_decl): Handle NON_DEPENDENT_EXPR.
+ (dump_expr): Likewise.
+ * init.c (build_member_call): Remove.
+ * mangle.c (write_expression): Update handling for template-ids.
+ * parser.c (cp_parser_primary_expression): Use
+ any_dependent_template_arguments_p. Update constant-expression
+ handling.
+ (cp_parser_postfix_expression): Use
+ any_type_dependent_arguments_p. Simplify call processing.
+ (cp_parser_unary_expression): Simplify.
+ (cp_parser_expression): Adjust for changes to
+ build_x_compound_expr.
+ (cp_parser_template_argument): Implement standard-conforming
+ parsing of non-type template arguments.
+ (cp_parser_direct_declarator): Use
+ cp_parser_fold_non_dependent_expr.
+ (cp_parser_fold_non_dependent_expr): New function.
+ (cp_parser_next_token_ends_template_argument_p): Likewise.
+ * pt.c (convert_template_argument): Do not call
+ maybe_fold_nontype_arg.
+ (tsubst_baselink): Likewise.
+ (tsubst_copy_and_build): Share common code. Make sizeof/alignof
+ processing work correctly for non-dependent expressions. Adjust
+ handling of COMPOUND_EXPR. Simplify call processing.
+ (value_dependent_expression_p): Deal with functional casts and
+ sizeof/alignof correctly.
+ (type_dependent_expression_p): Handle overloaded functions.
+ (any_type_dependent_arguments_p): New function.
+ (any_dependent_template_arguments_p): Likewise.
+ (dependent_template_p): Treat SCOPE_REFs as dependent.
+ (dependent_template_id_p): Simplify.
+ (build_non_dependent_expr): New function.
+ (build_non_dependent_args): Likewise.
+ * semantics.c (finish_stmt_expr): Don't make dependent
+ statement-expresions have void type.
+ (finish_call_expr): Handle non-dependent expressions
+ correctly.
+ * tree.c (lvalue_p_1): Treat NON_DEPENDENT_EXPRs as lvalues.
+ * typeck.c (cxx_sizeof_or_alignof_type): Give the expression
+ type size_t, even in templates.
+ (expr_sizeof): Likewise.
+ (finish_class_member_access_expr): Handle non-dependent expressions
+ correctly.
+ (build_x_indirect_ref): Likewise.
+ (build_x_binary_op): Likewise.
+ (build_x_unary_op): Likewise.
+ (build_x_conditional_expr): Likewise.
+ (build_x_compound_expr): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+
+2003-07-09 Jan Hubicka <jh@suse.cz>
+
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS): New.
+ * decl.c (duplicate_decls): Use DECL_ESTIMATED_INSNS.
+ (start_function): Use DECL_ESTIMATED_INSNS.
+ * optimize.c (maybe_clone_body): Use DECL_ESTIMATED_INSNS.
+
+ * decl2.c (maybe_emit_vtables): Fix marking vtables as needed in
+ unit-at-a-time
+
+2003-07-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/11030
+ * pt.c (instantiate_class_template): Don't call xref_tag to
+ inject name when the friend class is a specialization.
+
+2003-07-07 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (build_scoped_method_call): Remove.
+ (lookup_qualified_name): Remove parameter.
+ (tsubst_copy_and_build): Declare.
+ (finish_qualified_object_call_expr): Remove.
+ (check_accessibility_of_qualified_id): New function.
+ (finish_qualified_id_expr): Likewise.
+ (non_reference): Likewise.
+ (build_expr_from-tree): Remove.
+ * call.c (non_reference): Remove.
+ (build_scoped_method_call): Likewise.
+ (build_method_call): Use error_operand_p. Assert that we are not
+ processing a template.
+ (standard_conversion): Use non_reference.
+ * class.c (build_vtbl_entry_ref): Likewise.
+ (build_vtbl_ref_1): Likewise.
+ * cvt.c (build_expr_type_conversion): Use non_reference.
+ * decl.c (lookup_qualified_name): Remove flags parameter.
+ (grok_op_properties): Use non_reference.
+ * decl2.c (grok_array_decl): Likewise.
+ (build_expr_from_tree): Remove.
+ (build_offset_ref_call_from_tree): Update comment.
+ * error.c (parm_to_string): Call reinit_global_formatting_buffer.
+ * except.c (prepare_eh_types): Use non_reference.
+ (can_convert_eh): Likewise.
+ * init.c (build_dtor_call): Avoid using build_method_call.
+ * mangle.c (write_template_param): Remove misleading comment.
+ * method.c (locate_copy): Use non_reference.
+ * parser.c (cp_parser_scope_through_which_access_occurs): Remove.
+ (cp_parser_primary_expression): Do not create SCOPE_REFs is
+ non-dependent contexts.
+ (cp_parser_postfix_expression): Use finish_qualified_id_expr.
+ (cp_parser_direct_declarator): Use tsubst_copy_and_build, not
+ build_expr_from_tree.
+ (cp_parser_lookup_name): Adjust call to lookup_qualified_name.
+ Use check_accessibility_of_qualified_id.
+ * pt.c (maybe_fold_nontype_arg): Use tsubst_copy_and_build, not
+ build_expr_from_tree.
+ (tsubst_baselink): New function.
+ (tsubst_qualified_id): Likewise.
+ (tsubst_copy): Use them. Remove support for METHOD_CALL_EXPR.
+ (tsubst_expr): Adjust call to lookup_qualified_name.
+ (tsubst_copy_and_build): Handle SCOPE_REFs specially. Adjust
+ handling of CALL_EXPRs.
+ (value_dependent_expression_p): Use INTEGRAL_OR_ENUMERATION_TYPE_P.
+ * rtti.c (get_tinfo_decl_dynamic): Use non_reference.
+ * search.c (check_final_overrider): Likewise.
+ * semantics.c (check_accessibility_of_qualified_id): New function.
+ (finish_qualified_object_call_expr): Remove.
+ * typeck.c (target_type): Use non_reference.
+ (cxx_sizeof_or_alignof_type): Likewise.
+ (dubious_conversion_warnings): Likewise.
+ (convert_for_initialization): Likewise.
+ (non_reference): New function.
+
+2003-07-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (print_binding_level, print_other_binding_stack,
+ print_binding_stack): Merge uses of HOST_PTR_PRINTF with adjacent
+ stdio calls.
+ * ptree.c (cxx_print_decl, cxx_print_binding): Likewise.
+
+2003-07-07 Andreas Jaeger <aj@suse.de>
+
+ * friend.c: Convert to ISO C90 prototypes.
+
+ * Make-lang.in ($(srcdir)/cp/cfns.h): Use ANSI-C as output
+ language.
+ * cfns.h: Regenerate.
+
+ * typeck.c: Convert remaining prototypes to ISO C90.
+ * search.c: Likewise.
+
+ * decl2.c (build_expr_from_tree): Convert prototype to ISO C90.
+ * semantics.c (expand_or_defer_fn): Likewise
+ * mangle.c (discriminator_for_string_literal): Likewise.
+ * g++spec.c (lang_specific_driver): Likewise.
+
+ * search.c (lookup_base_r): Remove unused variable.
+
+2003-07-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * semantics.c: (genrtl_try_block) Adjust emit_line_note
+ calls.
+
+2003-07-07 Andreas Jaeger <aj@suse.de>
+
+ * search.c (lookup_base_r): Remove unused variable.
+
+2003-07-06 Michael Chastain <mec@shout.net>
+
+ PR debug/10055
+ * lex.c (cxx_init): Call push_srcloc and pop_srcloc rather than
+ assigning to input_filename directly.
+
+2003-07-06 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment formatting.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * error.c: Likewise.
+ * method.c: Likewise.
+ * name-lookup.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * typeck.c: Likewise.
+
+2003-07-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11345
+ * search.c (lookup_base_r): Remove is_non_public and
+ within_current_scope parameters. Remove other dead code.
+ (lookup_base): Adjust call to lookup_base_r.
+ (adjust_result_of_qualified_name_lookup): Improve comment.
+ * semantics.c (finish_call_expr): Use maybe_dummy_object.
+
+2003-07-06 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_HANDLE_FILENAME,
+ LANG_HOOKS_MISSING_ARGUMENT): Override.
+
+2003-07-05 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11431
+ * typeck.c (build_static_cast): Check for reference conversions
+ earlier.
+
+2003-07-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (perform_integral_promotions): Declare.
+ * call.c (build_addr_func): Use decay_conversion.
+ (convert_arg_to_ellipsis): Likewise. Remove misleading comment.
+ (convert_for_arg_passing): Use perform_integral_promotions.
+ * cvt.c (build_expr_type_conversion): Use decay_conversion.
+ (type_promotes_to): Do not return a cv-qualified type.
+ * decl.c (grok_reference_init): Fix formatting.
+ (get_atexit_node): Use decay_conversion.
+ (build_enumerator): Use perform_integral_promotions.
+ * init.c (build_vec_init): Use decay_conversion.
+ * semantics.c (finish_expr_stmt): Likewise.
+ (finish_switch_cond): Use perform_integral_promotions.
+ * typeck.c (default_conversion): Likewise.
+ (perform_integral_promotions): New function.
+ (build_indirect_ref): Use decay_conversion.
+ (build_array_ref): Use perform_integral_promotions.
+ (convert_arguments): Use decay_conversion.
+ (build_unary_op): Use perform_integral_promotions.
+ (build_c_cast): Use decay_conversion.
+ (build_modify_expr): Likewise.
+ (convert_for_initialization): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+
+2003-07-04 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment typos.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * decl2.c: Likewise.
+ * decl.c: Likewise.
+ * init.c: Likewise.
+ * mangle.c: Likewise.
+ * parser.c: Likewise.
+ * pt.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2003-07-04 Zack Weinberg <zack@codesourcery.com>
+
+ * parser.c (cp_lexer_read_token): No need to handle string
+ constant concatenation.
+
+2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (GCC_DIAG_STYLE, ATTRIBUTE_GCC_CXXDIAG): Define.
+ (cp_error_at, cp_warning_at, cp_pedwarn_at): Mark with
+ ATTRIBUTE_GCC_CXXDIAG.
+
+2003-07-03 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_addr_func): Handle bound pointers-to-members.
+ (build_method_call): Do not call resolve_offset_ref.
+ (implicit_conversion): Likewise.
+ (resolve_scoped_fn_name): Use finish_non_static_data_member, not
+ resolve_offset_ref.
+ (resolve_args): Do not call resolve_offset_ref.
+ (build_conditional_expr): Likewise.
+ (build_new_method_call): Likewise.
+ * cp-tree.def (OFFSET_REF): Update documentation.
+ * cvt.c (cp_convert_to_pointer): Update handling of conversions from
+ pointers to members to pointers.
+ (ocp_convert): Do not call resolve_offset_ref.
+ (convert_to_void): Likewise.
+ (build_expr_type_conversion): Likewise.
+ * decl2.c (delete_sanity): Likewise.
+ * init.c (resolve_offset_ref): Simplify greatly.
+ (build_vec_delete): Do not call resolve_offset_ref.
+ * parser.c (cp_parser_postfix_expression): Call resolve_offset_ref
+ if appropriate.
+ (cp_parser_unary_expression): Use
+ cp_parser_simple_cast_expression.
+ (cp_parser_delete_expression): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_pm_expression): Use cp_parser_binary_op.
+ (cp_parser_simple_cast_expression): New function.
+ * rtti.c (build_dynamic_cast_1): Do not call resolve_offset_ref.
+ * semantics.c (finish_increment_expr): Likewise.
+ (finish_typeof): Likewise.
+ * tree.c (lvalue_p_1): Do not handle OFFSET_REF.
+ * typeck.c (require_complete_type): Do not handle OFFSET_REFs.
+ (decay_conversion): Do not call resolve_offset_ref.
+ (finish_class_member_access_expr): Likewise.
+ (convert_arguments): Likewise.
+ (build_x_binary_op): Handle DOTSTAR_EXPR.
+ (condition_conversion): Do not call resolve_offset_ref.
+ (unary_complex_lvalue): Likewise.
+ (build_static_cast): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+ (build_c_cast): Likewise.
+ (build_modify_expr): Likewise.
+ (convert_for_assignment): Likewise.
+ (convert_for_initialization): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+ (build_m_component_ref): Simplify.
+
+ * call.c (build_scoped_method_call): Use convert_to_void.
+ (build_method_call): Likewise.
+ * class.c (check_field_decls): Remove dead code.
+ * cvt.c (convert_from_reference): Remove OFFSET_TYPE handling.
+ * decl2.c (grok_array_decl): Remove dead code.
+ (arg_assoc_type): Avoid relying on POINTER_TYPE over OFFSET_TYPE
+ as pointer-to-member representation.
+ * init.c (build_offset_ref): Tidy.
+ (build_vec_delete_1): Use convert_to_void.
+ * mangle.c (write_type): Avoid relying on POINTER_TYPE over OFFSET_TYPE
+ as pointer-to-member representation.
+
+2003-07-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9162
+ * decl.c (grokdeclarator): Return friend decls, not
+ void_type_node.
+ * decl2.c (grokfield): Alter friend decl check.
+ * parser.c (struct cp_parser): Document default_arg chain on
+ unparsed_functions_queue.
+ (cp_parser_save_default_args): New.
+ (cp_parser_init_declarator, cp_parser_function_definition,
+ cp_parser_member_declaration): Call it.
+ (cp_parser_class_specifier): Remove unused variable. Alter
+ processing of unparsed_functions_queue.
+
+2003-07-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (add_method, check_field_decl): Fix format specifier.
+ * decl.c (duplicate_decls, pushdecl, check_goto,
+ fixup_anonymous_aggr, maybe_commonize_var, grokdeclarator,
+ start_enum): Likewise.
+ * decl2.c (ambiguous_decl): Likewise.
+ * pt.c (redeclare_class_template): Likewise.
+
+2003-07-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10219
+ * pt.c (type_unification_real): Don't unify exprs of error type.
+ * tree.c (error_type): Don't die on error_type.
+
+ PR c++/9779
+ * decl2.c (arg_assoc_class): Don't die on NULL type.
+ * typeck.c (type_unknown_p): Don't die on untyped expressions.
+
+2003-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6949
+ * decl2.c (grokfield): Create TEMPLATE_DECLs for methods in local
+ classes.
+
+2003-07-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c (locate_error): %P takes an `int', not a `tree'.
+
+2003-07-02 Jan Hubicka <jh@suse.cz>
+
+ * decl2.c (defer_fn): Set DECL_DEFER_OUTPUT.
+ (finish-file): Do not process function with DECL_DEFER_OUTPUT clear;
+ clear DECL_DEFER_OUTPUT once function is processed; avoid flags
+ massaging.
+
+ * cp-tree.h (DECL_NEEDED_P): Support unit-at-a-time
+ (expand_or_defer_fn): Declare.
+ (lower_function): Declare.
+ * decl.c (start_cleanup_fn): Use expand_or_defer_fn.
+ * decl2.c: Include cgraph.h and varpool.h
+ (maybe_emit_vtables): Make explicit instantations as needed.
+ (mark_member_pointers, lower_function): New functions.
+ (finish_file): Do unit-at-a-time.
+ * method.c (synthesize_method): Use expand_or_defer_fn.
+ * optimize.c (maybe_clone_body): Use expand_or_defer_fn.
+ * parser.c (cp_parser_function_definition_after_decl): Use
+ expand_or_defer_fn.
+ * pt.c (instantiate_decl): Likewise.
+ * semantics.c: Include cgraph.h
+ (expand_or_defer_fn): Break out from ...
+ (expand_body): ... here; deal with unit-at-a-time.
+ * cp-lang.c (LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION,
+ LANG_HOOKS_CALLGRAPH_LOWER_FUNCTION): Define.
+
+2003-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (resolve_scoped_fn_name): Return error_mark_node for
+ erroneous cases.
+
+2003-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11149
+ * call.c (resolve_scoped_fn_name): Check that the qualifying scope
+ is a class type.
+
+2003-07-01 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/8046
+ * error.c (dump_decl): Handle BIT_NOT_EXPR as
+ pseudo destructor calls.
+
+2003-07-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (define_label): Replace filename and lineno
+ arguments with a location_t.
+ * decl.c (pop_label): Adjust define_label call.
+ (define_label): Replace filename and lineno arguments with a
+ location_t.
+ * semantics.c (finish_label): Adjust define_label call.
+
+2003-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9559
+ * decl2.c (grokfield): Do not build NOP_EXPRs around the
+ error_mark_node.
+
+2003-06-30 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Update.
+ * cp-lang.c (c_language): Define.
+ (LANG_HOOKS_INIT_OPTIONS): Use common hook.
+ * cp-tree.h (cxx_init_options): Remove.
+ * lex.c: Don't include diagnostic.h.
+ (cxx_init_options): Remove.
+
+2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/4933
+ * error.c (dump_expr): Support correctly the COMPOUND_EXPR
+ tree generated within a template. Use dump_expr to dump an
+ expression sizeof.
+
+2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
+
+ * mangle.c (write_expression): Exit gracefully when trying to
+ mangle a CALL_EXPR.
+
+2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/10750
+ * parser.c (cp_parser_primary_expression): A VAR_DECL with a
+ (value- or type-) dependent expression as DECL_INITIAL is a
+ valid constant-expression (at parser time).
+
+2003-06-30 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/11106
+ * error.c (dump_decl): Call dump_decl to dump the DECL_NAME for a
+ USING_DECL, instead of print_tree_identifier.
+
+2003-06-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (language_to_string): Adjust declaration.
+ * dump.c (cp_dump_tree): Adjust usage.
+ * error.c (dump_char): Use output_formatted_scalar. Tidy.
+ (parm_to_string): Lose unused parameter. Tidy.
+ (expr_to_string): Likewise.
+ (code_to_string): Likewise.
+ (language_to_string): Likewise.
+ (op_to_string): Likewise.
+ (assop_to_string): Likewise.
+ (digit_buffer): Remove.
+ (dump_type): Format builtin vector type as __vector__.
+
+2003-06-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (print_integer): Remove.
+ (dump_type_suffix): Adjust.
+ (dump_expr): Likewise.
+
+2003-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (print_instantiation_partial_context): Take a
+ location_t.
+ (print_instantiation_full_context): Adjust.
+ (print_instantiation_context): Adjust.
+
+ * cp-tree.h (cp_line_of, cp_file_of): Remove.
+ * error.c (cp_line_of, cp_file_of): Merge into ...
+ (location_of): ... here. Make static, return a location_t.
+ (cp_error_at, cp_warning_at, cp_pedwarn_at): Adjust.
+
+2003-06-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10784
+ * call.c (joust): Move warn_conversion check outwards.
+
+2003-06-27 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (build_typename_type)
+ * mangle.c (write_template_template_arg)
+ * parser.c (cp_parser_scope_through_which_access_occurs)
+ * pt.c (push_access_scope_real, push_access_scope, pop_access_scope)
+ * repo.c (get_base_filename)
+ * semantics.c (maybe_convert_cond):
+ Mark the definition static, matching the forward declaration.
+
+2003-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10468
+ * pt.c (tsubst): Handle qualified TYPEOF_TYPEs correctly.
+
+2003-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10796
+ * decl.c (finish_enum): Implement DR377.
+
+ * decl.c (cp_finish_decl): Don't make variables with reference
+ type readonly while they are being initialized.
+
+2003-06-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11332
+ * typeck.c (build_static_cast): Avoid returning expressions with
+ reference type.
+
+2003-06-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_op_delete_call): Use strip_array_call. Correct
+ error message to say 'delete' or 'delete[]'.
+
+2003-06-26 Giovanni Bajo <giovannibajo@libero.it>
+
+ PR c++/8266
+ * pt.c (check_explicit_specialization): When looking up a
+ template function from an identifier outside class-scope, bind
+ it to CP_DECL_CONTEXT.
+
+2003-06-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10990
+ * search.c (lookup_base_r): Rely on accessible_p, rather than
+ trying to emulate that logic here.
+
+ PR c++/10931
+ * call.c (convert_like): Pass issue_conversion_warnings.
+ (convert_like_with_context): Likewise.
+ (convert_like_real): Add issue_conversion_warnings parameter.
+ (perform_direct_initialization_if_possible): New function.
+ * cp-tree.h (perform_direct_initialization_if_possible): Declare it.
+ * typeck.c (check_for_casting_away_constness): New function.
+ (build_static_cast): Rewrite.
+
+2003-06-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (enforce_access): Assert we get a binfo.
+ (build_op_delete_call): Pass a binfo to
+ perform_or_defer_access_check.
+ * class.c (alter_access): Likewise.
+ * decl.c (make_typename_type): Likewise.
+ (make_unbound_class_template): Likewise.
+ * lex.c (do_identifier): Likewise.
+ * method.c (hack_identifier): Likewise.
+ * parser.c (cp_parser_lookup_name): Likewise.
+ * search.c (lookup_member): Likewise. Move IDENTIFIER_CLASS_VALUE
+ test.
+ * semantics.c (finish_non_static_data_member): Likewise.
+ (perform_or_defer_access_check): Expect a binfo.
+ * typeck.c (comptypes): Expect types.
+
+ * mangle.c (find_substitution): Don't pass a non-type to same_type_p
+ * friend.c (make_friend_class): Likewise.
+ * pt.c (check_default_tmpl_args): Likewise.
+ (lookup_template_class): Likewise.
+
+2003-06-24 Jan Hubicka <jh@suse.cz>
+
+ * method.c (thunk_labelno): Move outside ifdef block to make garbage
+ collector happy.
+
+2003-06-24 Jan Hubicka <jh@suse.cz>
+
+ * class.c (build_vtable): Make vtables.
+ * cp-tree.h (DECL_VTABLE_OR_VTT_P): New macro.
+ * decl2.c (output_vtable_inherit): Rename to ...
+ (prepare_assemble_variable): ... this one; change interface.
+ (maybe_emit_vtables): Do not call output_vtable_inherit.
+ * cp-lang.c (LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE): Define.
+ * cp-tree.h (prepare_assemble_variable): New.
+
+2003-06-23 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * method.c: add prototype for make_alias_for_thunk.
+ (thunk_labelno, make_alias_for_thunk): only define
+ if ASM_OUTPUT_DEF is defined.
+
+2003-06-23 Jakub Jelinek <jakub@redhat.com>
+
+ * method.c (thunk_labelno): New variable.
+ (make_alias_for_thunk): New function.
+ (use_thunk): Use it if defined ASM_OUTPUT_DEF. Put the thunk
+ into the same section as the function it is calling.
+ Include gt-cp-method.h.
+ * Make-lang.in (gt-cp-method.h): Depend on s-gtype.
+ (cp/method.o): Depend on gt-cp-method.h.
+ * config-lang.in (gtfiles): Add $(srcdir)/cp/method.c.
+
+2003-06-23 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (register_dtor_fn): Mark cleanup as used.
+ * decl2.c (mark_vtable_entries): Skip nops.
+ * rtti.c (get_tinfo_ptr): Mark tinfo as used.
+ (build_dynamic_cast_1): Likewise.
+ (tinfo_base_init): Likewise.
+ (emit_tinfo_decl): Likewise.
+
+2003-06-23 Jakub Jelinek <jakub@redhat.com>
+
+ * mangle.c (hash_type): Val is the TREE_LIST itself, not a pointer
+ to it.
+
+2003-06-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10784
+ * call.c (joust): Warn about choosing conversion sequence only if
+ -Wconversion.
+
+2003-06-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10864
+ * call.c (op_error): Tidy.
+ * error.c (dump_expr): Properly format 'T()' when T is an
+ aggregate type.
+
+2003-06-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR c++/10915
+ * decl.c (grok_op_properties): Warn possible confusing conversion
+ only if -Wconversion.
+
+2003-06-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10749
+ * parser.c (cp_parser_class_head): See through dependent names
+ when parsing a class-head.
+
+ PR c++/10845
+ * pt.c (try_class_unification): Correct handling of member class
+ templates.
+
+2003-06-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * semantics.c (genrtl_finish_function): Adjust
+ expand_function_end call.
+
+2003-06-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10939
+ * pt.c (tsubst_decl): Do not try to substitute into non-dependent
+ functions.
+ (value_dependent_expression_p): Correct logic for FUNCTION_DECLs.
+
+ PR c++/9649
+ * cp-tree.h (pushdecl_class_level): Change prototype.
+ (push_class_level_binding): Likewise.
+ * decl.c (add_binding): Reject duplicate static data members.
+ (pushdecl_class_level): Return a value indicating whether or not
+ the binding was valid.
+ (push_class_level_binding): Likewise.
+ * semantics.c (finish_member_declaration): Don't keep invalid
+ declarations.
+
+ PR c++/11041
+ * call.c (initialize_reference): Do not use cp_finish_decl to emit
+ temporary variables.
+ * cp-tree.h (static_aggregates): Declare.
+ (pushdecl_top_level_and_finish): Likewise.
+ * decl.c (pushdecl_top_level_1): New function.
+ (pushdecl_top_level): Use it.
+ (pushdecl_top_level_and_finish): New function.
+ (initialize_local_var): Remove redundant code.
+ (cp_finish_decl): Remove support for RESULT_DECLs. Don't check
+ building_stmt_tree.
+ * decl.h (static_aggregates): Remove.
+ * decl2.c (get_guard): Use pushdecl_top_level_and_finish.
+ * rtti.c (get_tinfo_decl): Use pushdecl_top_level_and_finish.
+ (tinfo_base_init): Likewise.
+
+2003-06-19 Matt Austern <austern@apple.com>
+
+ PR c++/11228
+ * init.c (build_zero_init): Assert that number of array elements
+ is an integer constant.
+ (build_default_init) Don't use build_zero_init for arrays with
+ variable number of elements.
+
+2003-06-19 Andreas Jaeger <aj@suse.de>
+
+ * cp-tree.h: Remove duplicated declarations.
+
+2003-06-18 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * pt.c: Convert to ISO C.
+ * semantics.c: Convert to ISO C.
+
+2003-06-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (comp_except_specs, compparms, cp_has_mutable_p,
+ at_least_as_qualified_p, more_qualified_p): Return bool.
+ * typeck.c: ANSIFY function definitions.
+ (comp_array_types): Take redeclaration bool parameter.
+ (comptypes): Rearrange STRICT handling.
+ (at_least_as_qualified_p, more_qualified_p,
+ comp_cv_qualification): Cache cv quals.
+ (compparms): Rearrange loop.
+
+2003-06-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (COMPARE_RELAXED): Rename to ...
+ (COMPARE_DERIVED): ... here. Adjust comment.
+ (resolve_typename_type_in_current_instantiation): Remove.
+ (cp_tree_equal, comptypes): Return a bool.
+ * cvt.c (convert_to_reference): Adjust comptypes call.
+ * pt.c (template_args_equal, unify,): Adjust cp_tree_equal call.
+ (resolve_typename_type_in_current_instantiation): Remove.
+ * tree.c (cp_tree_equal): Return bool. Cope with TEMPLATE_DECLs and
+ IDENTIFIER_NODEs. Abort if undeciderable. Adjust recursive
+ calls. Refactor code.
+ * typeck.c (comp_array_types): Return bool. Lose callback.
+ parameter. Adjust cp_tree_equal calls.
+ (comptypes): Return bool. Adjust strict handling. Remove relaxed
+ enumeration and java type handling. Deal with typename types here.
+ Adjust recursive and cp_tree_equals calls. Adjust base and derived
+ checking.
+ (comp_target_types): Remove unreachable code. Adjust
+ same_or_base_type_p calls.
+ (ptr_reasonably_similar): Adjust base and derived check.
+
+ * typeck.c (maybe_warn_about_returning_address_of_local): Remove
+ unused calculation.
+ (check_return_expr): Adjust error messages.
+ * cp-tree.def (SCOPE_REF): Correct comment.
+
+2003-06-17 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (mangle_conv_op_name_for_type): Correct sprintf format
+ string again.
+
+2003-06-17 Robert Abeles <rabeles@archaelogic.com>
+
+ * optimize.c (dump_function): Form complete flag name by
+ prefixing 'fdump-' to string returned by dump_flag_name().
+
+2003-06-17 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (mangle_conv_op_name_for_type): Correct sprintf format
+ string.
+
+2003-06-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/10929
+ * decl.c (grokfndecl): Don't mark a function inline for
+ -finline-functions if it isn't defined.
+
+2003-06-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10712
+ * class.c (handle_using_decl): Robustify.
+
+ PR c++/11105
+ * cp-tree.h (DECL_CONV_FN_TYPE): New method.
+ * mangle.c (struct globals): Remove internal_mangling_p.
+ (write_unqualified_name): Use DECL_CONV_FN_TYPE.
+ (write_template_parm): Don't write out the level number.
+ (conv_type_names): New variable.
+ (hash_type): New function.
+ (compare_type): Likewise.
+ (mangle_conv_op_name_for_type): Don't try to mangle conversion
+ operator names.
+ * search.c (lookup_conversion_operator): New function.
+ (lookup_fnfields_1): Use it.
+
+2003-06-17 Andreas Jaeger <aj@suse.de>
+
+ * except.c: Remove duplicate declaration of push_eh_cleanup.
+
+ * call.c: Remove extra declaration of inhibit_warnings.
+
+2003-06-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ 2003-06-16 Jens-Michael Hoffmann <jensmh@gmx.de>
+ * mangle.c: Convert to ISO C.
+
+2003-06-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp/decl.c, cp/pt.c, cp/search.c, cp/tree.c: Don't use the PTR
+ macro.
+
+2003-06-16 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * tree.c: Convert to ISO C.
+
+2003-06-16 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h: Follow spelling conventions.
+ * mangle.c: Likewise.
+ * method.c: Likewise.
+ * parser.c: Likewise.
+
+2003-06-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (start_function): Adjust init_function_start call.
+ * method.c (use_thunk): Likewise.
+ * semantics.c (genrtl_start_function): Likewise.
+
+2003-06-14 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Remove c-options.o.
+
+2003-06-13 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * lex.c: Convert to ISO C.
+
+ 2003-05-19 Jens-Michael Hoffmann <jensmh@gmx.de>
+ * init.c: removes use of PARAMS macro. Use ISO style function
+ declarations. (Not copyright-significant change.)
+
+ * rtti.c: Remove PARAMS.
+
+ * typeck2.c: Convert to ISO C.
+
+2003-06-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10635
+ * typeck.c (build_c_cast): Check that the destination type is
+ complete.
+
+2003-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10432
+ * cp-tree.h (finish_declarator): Remove.
+ * decl.c (cp_finish_decl): Make sure to pop_nested_class even for
+ erroneous declarations.
+ * semantics.c (finish_declarator): Remove.
+
+2003-06-11 Roger Sayle <roger@eyesopen.com>
+
+ * decl2.c (generate_ctor_or_dtor_function): Avoid expanding a
+ global static constructor/destructor if it will be empty, i.e.
+ either doesn't call any ctors/dtors or only calls pure or const
+ ctors/dtors.
+
+2003-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (tm_p.h): Include it.
+ * Make-lang.in (cp/mangle.o): Depend on $(TM_P_H).
+
+ PR c++/11131
+ * tree.c (cp_cannot_inline_fn): Check for "inline" before
+ instantiation.
+
+2003-06-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/10968
+ * pt.c (mark_decl_instantiated): Clear DECL_COMDAT.
+
+2003-06-10 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * decl.c (start_cleanup_fn): Move static 'counter' out, mark with GTY.
+ (start_cleanup_cnt): New.
+
+2003-06-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/11131
+ * cp-tree.h (template_for_substitution): Declare.
+ * decl2.c (mark_used): Use it when figuring out whether or not a
+ function is inline.
+ * pt.c (template_for_substitution): Give it external linkage.
+ * tree.c (cp_cannot_inline_tree_fn): Instantiate as early as
+ possible.
+
+2003-06-09 Zack Weinberg <zack@codesourcery.com>
+
+ PR 8861
+ * mangle.c (write_real_cst): New function. Implement
+ ABI-compliant mangling of floating-point literals when
+ -fabi-version>=2; provide backward compatibility with 3.3 when
+ -fabi-version=1 (with warning). Clarify commentary.
+ (write_template_arg_literal): Use write_real_cst.
+
+2003-06-07 Andreas Jaeger <aj@suse.de>
+
+ * cp/decl.c (xref_tag): Remove undefined macro NONNESTED_CLASSES.
+
+2003-06-07 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_DECODE_OPTON): Drop.
+ (LANG_HOOKS_HANDLE_OPTION): Override.
+ * cp-tree.h (cxx_init_options): Update.
+ * lex.c (cxx_init_options): Update.
+
+2003-06-05 Jan Hubicka <jh@suse.cz>
+
+ * Make-lang.in: Add support for stageprofile and stagefeedback
+
+2003-06-04 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * decl.c (grokdeclarator): Error_mark_node in, error_mark_node out.
+
+2003-06-04 Andreas Jaeger <aj@suse.de>
+
+ * g++spec.c (lang_specific_driver): Remove ALT_LIBM usage.
+
+2003-06-03 Jason Merrill <jason@redhat.com>
+
+ * cp/cp-tree.h (CP_AGGREGATE_TYPE_P): Accept vectors.
+
+ * cp/decl.c (reshape_init): Handle vectors.
+
+ * testsuite/g++.dg/init/array10.C: New.
+
+2003-06-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10940
+ * pt.c (check_explicit_specialization): Check for 'static'
+ earlier.
+
+2003-05-31 Diego Novillo <dnovillo@redhat.com>
+
+ * class.c (dump_array): Call CONSTRUCTOR_ELTS to access
+ the operand of a CONSTRUCTOR node.
+
+2003-05-31 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (cp_binding_level::this_entity): Rename from this_class.
+ (cxx_scope_descriptor): New function.
+ (cxx_scope_debug): Likewise.
+ (push_binding_level): Use it.
+ (pop_binding_level): Likewise.
+ (suspend_binding_level): Likewise.
+ (resume_binding_level): Likewise.
+ (pushlevel_class): Adjust use of this_class.
+ (pushtag): Likewise.
+ (lookup_name_real): Likewise.
+ (global_scope_name): New variable.
+ (initialize_predefined_identifiers): Initialize it.
+ (push_namespace): Use it.
+ (make_cxx_scope): New function.
+ (pushlevel): Use it.
+ (pushlevel_class): Likewise.
+ (push_binding_level): Simplify. Loose the last two arguments.
+ (make_binding_level): Remove.
+ (initial_push__namespace_scope): New function.
+ (push_namespace): Use it. Simplify.
+ (cxx_init_decl_processing): Likewise.
+ (declare_namespace_level): Remove.
+
+2003-05-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10956
+ * pt.c (instantiate_decl): Don't use full template arguments if
+ we are dealing with specializations.
+
+2003-05-29 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (ENABLE_SCOPE_CHECKING): Rename from DEBUG_BINDING_LEVELS.
+ (binding_depth): Unconditionally define.
+ (is_class_level): Likewise.
+ (indent): Likewise. Take an indenting parameter.
+ (push_binding_level): Remove conditional definittion.
+ (pop_binding_level): Likewise.
+ (suspend_binding_level): Likewise.
+ (resume_binding_level): Likewise.
+ (pushlevel): Likewise.
+ (pushlevel_class): Likewise.
+ (poplevel_class): Likewise.
+ (pop_everything): Likewise.
+
+2003-05-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.h (global_scope_p): New macro.
+ * decl.c (pop_binding_level): Use it. Don't refer directly to
+ global_binding_level.
+ (suspend_binding_level): Likewise.
+ (global_bindings_p): Likewise.
+ (print_other_binding_stack): Likewise.
+ (print_binding_stack): Likewise.
+ (maybe_push_to_top_level): Likewise.
+ (pushdecl_namespace_level): Likewise.
+ (cxx_init_decl_processing): Likewise.
+ (start_decl): Likewise.
+ (cp_finish_decl): Likewise.
+ (start_function): Likewise.
+ (global_binding_level): Remove.
+
+2003-05-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * parser.c (cp_parser_explicit_instantiation): Restore old
+ access before template instantiation.
+
+2003-05-23 Geoffrey Keating <geoffk@apple.com>
+
+ * lang-specs.h: Use -o to specify preprocessor's output file.
+ Make -no-integrated-cpp work when building PCH files.
+
+2003-05-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10682
+ * pt.c (instantiate_class_template): Use DECL_ARTIFICIAL to
+ check for implicitly created typedef to an enum.
+
+2003-05-21 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_vec_delete): Copy the address into a temporary
+ variable before calling build_vec_delete_1.
+ * decl2.c (delete_sanity): Don't call stabilize_reference.
+
+2003-05-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (register_specialization): Update the decl's location,
+ if necessary.
+ (check_explicit_specialization): Likewise.
+
+2003-05-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c (dump_expr): Use HOST_WIDE_INT_PRINT_DOUBLE_HEX.
+
+2003-05-21 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR c++/9738
+ * decl.c (duplicate_decls): Re-invoke make_decl_rtl
+ if the old decl had instantiated DECL_RTL.
+ (Base on Richard Henderson 2003-05-13 patch to c-decl.c).
+
+2003-05-19 Matt Austern <austern@apple.com>
+
+ * lang-options.h: Document -Wno-invalid-offsetof
+ * typeck.c (build_class_member_access_expr): Don't complain about
+ (Foo *)p->x for non-POD Foo if warn_invalid_offset is zero.
+
+2003-05-18 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * name-lookup.c (free_binding_entry): fix where the GTY markers are.
+ (binding_entry_make): Make entry->chain NULL after getting an entry.
+ fix the spelling of chain in a comment.
+ (binding_table_free): speed up by having temporary variable.
+ (binding_table_new): set table->chain to be NULL after allocating
+ a table.
+ (cxx_binding_make): use gcc_alloc instead of ggc_alloc_cleared and set
+ binding->previous to NULL after getting an binding for speed.
+
+2003-05-18 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (struct lang_type_class): Replace data member tags
+ with hash-table nested_udts.
+ (CLASSTYPE_NESTED_UTDS): Rename from CLASSTYPE_TAGS.
+ * class.c (unreverse_member_declarations): Don't touch
+ CLASSTYPE_TAGS.
+ (pushclass): Use cxx_remember_type_decls.
+ * decl.c (struct cp_binding_level): Replace data member tags with
+ hash-table type_decls.
+ (pop_binding_level): Handle level->type_decls.
+ (kept_level_p): Adjust.
+ (poplevel): Remove unused local variable.
+ (bt_print_entry): New function.
+ (print_binding_level): Use it.
+ (push_namespace): Build current_binding_level->type_decls.
+ (maybe_process_template_type_declaration): Adjust.
+ (pushtag): Likewise.
+ (clear_anon_tags): Use binding_table_remove_anonymous_types.
+ (gettags): Remove.
+ (cxx_remember_type_decls): Rename from storetags. Adjust.
+ (lookup_tag): Use binding_table_find_anon_type. Tidy.
+ (lookup_tag_reverse): Use binding_table_reverse_maybe_remap.
+ (cxx_init_decl_processing): Build global_binding_level->type_decls.
+ (store_parm_decls): Remove pointless code.
+ * name-lookup.c (free_binding_entry): New variable.
+ (ENTRY_INDEX): New macro.
+ (struct binding_table_s): New datatype.
+ (binding_entry_make): New function.
+ (binding_entry_free): Likewise.
+ (binding_table_construct): Likewise.
+ (binding_table_free): Likewise.
+ (binding_table_new): Likewise.
+ (binding_table_expand): Likewise.
+ (binding_table_insert): Likewise.
+ (binding_table_find): Likewise.
+ (binding_table_find_anon_type): Likewise.
+ (binding_table_reverse_maybe_remap): Likewise.
+ (binding_table_remove_anonymous_types): Likewise.
+ (binding_table_foreach): Likewise.
+ * name-lookup.h (binding_table): New type.
+ (binding_entry): Likewise.
+ (bt_foreach_proc): Likewise.
+ (struct binding_entry_s): New datatype.
+ (SCOPE_DEFAULT_HT_SIZE): New macro.
+ (CLASS_SCOPE_HT_SIZE): Likewise.
+ (NAMESPACE_ORDINARY_HT_SIZE): Likewise.
+ (NAMESPACE_STD_HT_SIZE): Likewise.
+ (GLOBAL_SCOPE_HT_SIZE): Likewise.
+ (binding_table_new): Declare.
+ (binding_table_free): Likewise.
+ (binding_table_insert): Likewise.
+ (binding_table_find_anon_type): Likewise.
+ (binding_table_reverse_maybe_remap): Likewise.
+ (binding_table_remove_anonymous_types): Likewise.
+ (binding_table_foreach): Likewise.
+ (binding_table_find): Likewise.
+ (cxx_remember_type_decls): Likewise.
+ * pt.c (bt_instantiate_type_proc): New function.
+ (do_type_instantiation): Use it.
+ * search.c (lookup_field_r): Use binding_table_find.
+
+2003-05-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * semantics.c (perform_deferred_access_checks): Don't discard
+ checked access.
+
+2003-05-17 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c (cp_error_at, cp_warning_at, cp_pedwarn_at): Eliminate
+ libiberty VA_ macros, always use stdarg.
+ * rtti.c (create_pseudo_type_info): Likewise.
+ * tree.c (build_min_nt, build_min): Likewise.
+
+2003-05-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ptree.c (cxx_print_type, cxx_print_xnode): Use string
+ concatentation on HOST_WIDE_INT_PRINT_* format specifier to
+ collapse multiple function calls into one.
+ * tree.c (debug_binfo): Likewise.
+
+2003-05-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/5388
+ * call.c (conditional_conversion): Don't consider implicit
+ conversions if T2 is a base of T1.
+ * cp-tree.h (DERIVED_FROM_P, UNIQUELY_DERIVED_FROM_P): Make boolean.
+ (ACCESSIBLY_UNIQUELY_DERIVED_P, PUBLICLY_UNIQUELY_DERIVED_P): Likewise.
+
+ * parser.c (cp_parser_primary_expression): Convert a static data
+ member from reference.
+
+2003-05-15 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_op_delete_call): Avoid creating unnecessary types.
+ * class.c (instantiate_type): Remove tests for tf_no_attributes.
+ * cp-tree.h (tsubst_flags_t): Remove tf_no_attributes.
+ (COMPARE_NO_ATTRIBUTES): Remove.
+ * typeck.c (comptypes): Do not check COMPARE_NO_ATTRIBUTES.
+
+ PR c++/8385
+ * semantics.c (finish_typeof): Refine type-dependency check.
+
+2003-05-13 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_modify_expr): Don't always stabilize the lhs and
+ rhs. Do stabilize the lhs of a MODIFY_EXPR used on the lhs.
+
+2003-05-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * method.c (synthesize_method): Call push/pop_deferring_access_checks.
+
+2003-05-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10230, c++/10481
+ * semantics.c (finish_non_static_data_member): Handle when the
+ non-static member is not from a base of the current class type.
+
+2003-05-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10552
+ * pt.c (tsubst_copy): Handle TEMPLATE_DECL that is a member class
+ template and has dependent context.
+
+2003-05-10 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (instantiate_decl): Call push/pop_deferring_access_checks.
+
+2003-05-10 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9252
+ * cp-tree.h (saved_scope): Remove check_access field.
+ (tsubst_flags_t): Remove tf_parsing.
+ * decl.c (maybe_push_to_top_level): Don't initialize
+ scope_chain->check_access.
+ (make_typename_type, make_unbound_class_template): Don't use
+ tf_parsing.
+ (register_dtor_fn): Use push/pop_deferring_access_checks
+ instead of scope_chain->check_access.
+ * method.c (use_thunk): Likewise.
+ * parser.c (cp_parser_explicit_instantiation
+ (cp_parser_constructor_declarator_p): Don't call
+ push/pop_deferring_access_checks here.
+ (cp_parser_template_argument, cp_parser_class_name): Don't use
+ tf_parsing.
+ (yyparse): Check flag_access_control.
+ * pt.c (instantiate_class_template): Call
+ push/pop_deferring_access_checks.
+ * semantics.c (push_deferring_access_checks): Propagate
+ dk_no_check.
+ (perform_or_defer_access_check): Make sure basetype_path is
+ a type before comparison.
+ * call.c (build_op_delete_call, build_over_call): Use
+ perform_or_defer_access_check.
+ * class.c (alter_access): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * lex.c (do_identifier): Likewise.
+ * method.c (hack_identifier): Likewise.
+ * search.c (lookup_member): Likewise.
+ * semantics.c (finish_non_static_data_member): Likewise.
+ (simplify_aggr_init_exprs_r): Use push/pop_deferring_access_checks
+ instead of flag_access_control.
+
+2003-05-10 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9554
+ * parser.c (cp_parser_class_name): Remove check_access parameter.
+ All caller adjusted. Update declaration.
+ (cp_parser_lookup_name): Likewise.
+ * semantics.c (push_deferring_access_checks): Change parameter type
+ to enum deferring_kind. All caller adjusted.
+ (resume_deferring_access_checks): Adjust to use new enum.
+ (stop_deferring_access_checks): Likewise.
+ (perform_or_defer_access_check): Likewise.
+ * cp-tree.h (deferring_kind): New enum.
+ (deferred_access): Adjust field type.
+ (push_deferring_access_checks): Update declaration.
+
+2003-05-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10555, c++/10576
+ * pt.c (lookup_template_class): Handle class template with
+ multiple levels of parameters when one of the levels contain
+ errors.
+
+2003-05-08 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Don't reuse a TARGET_EXPR in an
+ expression. Undo some of the recent reorg.
+
+2003-05-07 Richard Henderson <rth@redhat.com>
+
+ PR c++/10570
+ * cfns.gperf: Comment out POSIX thread cancellation points,
+ plus abort and raise.
+ * cfns.h: Regenerate.
+
+2003-05-07 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_conditional_expr): Don't assume that the folded
+ expression has result_type.
+
+2003-05-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * typeck.c (build_unary_op): Deal with const qualifier in
+ invalid pointer-to-member earlier.
+
+2003-05-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/9537
+ * call.c (conditional_conversion): Build an RVALUE_CONV if
+ we're just changing the cv-quals.
+ (build_conditional_expr): Don't call convert to change
+ cv-quals.
+
+2003-05-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10496
+ * typeck.c (build_unary_op): Don't output const qualifier when
+ output invalid pointer-to-member diagnostics.
+
+2003-05-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl.c: Fix typos.
+
+2003-05-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/4494
+ * decl.c (start_function): Use same_type_p to check return type
+ of main.
+
+2003-05-03 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/10604
+ * cp/typeck.c (build_x_compound_expr): No need to check
+ extra_warnings as well as warn_unused_value.
+
+2003-05-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9364, c++/10553, c++/10586
+ * decl.c (make_typename_type): Don't crash on illegal code.
+
+2003-05-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (finish_struct): Use location_t and input_location
+ directly.
+ * decl.c (make_label_decl): Likewise.
+ (use_label): Likewise.
+ * decl2.c (warn_if_unknown_interface): Likewise.
+ (start_static_initialization_or_destruction): Likewise.
+ (generate_ctor_or_dtor_function): Likewise.
+ (finish_file): Likewise.
+ * error.c (print_instantiation_full_context): Likewise.
+ * init.c (create_temporary_var): Likewise.
+ * method.c (synthesize_method): Likewise.
+ * parser.c (cp_token): Likewise.
+ (cp_lexer_set_source_position_from_token): Likewise.
+ (cp_lexer_get_preprocessor_token): Likewise.
+ (cp_parser_statement): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+ (instantiate_class_template): Likewise.
+ (tsubst_decl): Likewise.
+ (tsubst): Likewise.
+ (instantiate_decl): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+ (expand_body): Likewise.
+
+2003-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (finish_struct): Rename lineno to input_line.
+ * decl.c (push_binding_level, pop_binding_level,
+ suspend_binding_level, resume_binding_level, make_label_decl,
+ use_label, start_function): Likewise.
+ * decl2.c (warn_if_unknown_interface,
+ start_static_initialization_or_destruction,
+ generate_ctor_or_dtor_function, finish_file): Likewise.
+ * error.c (cp_line_of, print_instantiation_full_context,
+ print_instantiation_context): Likewise.
+ * except.c (check_handlers_1, check_handlers): Likewise.
+ * init.c (create_temporary_var): Likewise.
+ * method.c (use_thunk, synthesize_method): Likewise.
+ * parser.c (cp_lexer_set_source_position_from_token,
+ cp_lexer_get_preprocessor_token): Likewise.
+ * pt.c (push_tinst_level, pop_tinst_level,
+ tsubst_friend_function, instantiate_class_template, tsubst_decl,
+ tsubst, tsubst_expr, instantiate_decl): Likewise.
+ * semantics.c (genrtl_try_block, finish_label_stmt,
+ begin_class_definition, expand_body,
+ genrtl_finish_function): Likewise.
+ * tree.c (build_min_nt, build_min): Likewise.
+
+2003-05-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (comdat_linkage): Don't externalize explicit
+ instantiations.
+
+2003-05-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10554
+ * decl2.c (do_class_using_decl): Check if operand 0 of SCOPE_REF
+ is not NULL.
+
+2003-05-01 Steven Bosscher <steven@gcc.gnu.org>
+
+ * cp-tree.h (struct lang_id2): Remove. Move fields from here...
+ (struct lang_identifier): ... to here.
+ (LANG_ID_FIELD): Remove.
+ (SET_LANG_ID): Remove.
+ (IDENTIFIER_LABEL_VALUE): Adjust for new lang_identifier.
+ (SET_IDENTIFIER_LABEL_VALUE): Likewise.
+ (IDENTIFIER_IMPLICIT_DECL): Likewise.
+ (SET_IDENTIFIERL_IMPLICIT_DECL): Likewise.
+ (IDENTIFIER_ERROR_LOCUS): Likewise.
+ (SET_IDENTIFIER_ERROR_LOCUS): Likewise.
+
+2003-05-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8772
+ * pt.c (convert_template_argument): Correct diagnostic.
+
+2003-04-30 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9432, c++/9528
+ * decl2.c (validate_nonmember_using_decl): Handle SCOPE_REF.
+
+2003-04-30 Garbiel Dos Reis <gcc@integrable-solutions.net>
+
+ * decl.c (check_previous_goto_1): Adjust prototype.
+ (check_previous_goto): Adjust use.
+ (check_switch_goto): Likewise.
+ (use_label): Adjust.
+ (check_previous_goto_1): Don't use pedwarn_with_file_and_line.
+ (struct named_label_use_list): Use location_t datatype.
+
+2003-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10551
+ * pt.c (mark_decl_instantiated): Defer all explicit instantiations
+ that have not yet been written out.
+
+2003-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10549
+ * class.c (layout_class_type): Mark overlong bitfields as having
+ the maximum size permitted by their type, after layout.
+
+ PR c++/10527
+ * error.c (dump_expr): Correctly handling of NEW_EXPR.4
+
+2003-04-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * call.c (build_operator_new_call): Fix typo.
+ * lang-options.h: Likewise.
+
+2003-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10515
+ * cp-tree.h (lookup_field_1): Declare it.
+ * search.c (lookup_field_1): Make it public.
+ * decl.c (reshape_init): Handle designated initializers.
+
+ * decl.c (maybe_commonize_var): Further tweak support for systems
+ without weak symbols.
+
+2003-04-27 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (maybe_commonize_var): Fix thinko in last patch.
+
+2003-04-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10506
+ * method.c (use_thunk): Decrement immediate_size_expand.
+
+ PR c++/10503
+ * cp-tree.h (DECL_VAR_MARKED_P): New macro.
+ (DECL_MAYBE_TEMPLATE): Remove.
+ * class.c (fixed_type_or_null): Avoid infinite recursion.
+
+ * decl.c (maybe_commonize_var): Make the code match the comments.
+ * pt.c (instantiate_decl): Move call to import_export_decl.
+
+2003-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (finish_file): Fix merge botch.
+
+2003-04-25 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (finish_file): Don't call import_export_decl for
+ functions that are not defined.
+ (handle_class_head): Robustify.
+ * pt.c (instantiate_decl): Do not call cp_finish_decl for
+ variables that are not defined.
+
+2003-04-24 Sylvain Pion <Sylvain.Pion@mpi-sb.mpg.de>
+
+ * call.c (print_z_candidates): Fix off by one error.
+
+2003-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10337
+ * call.c (joust): Don't warn about conversion ops that are exact
+ or cv-conversions. Rearrange to avoid multiple type comparisons.
+
+2003-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10471
+ * call.c (build_cxx_call): Robustify.
+
+2003-04-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (lex.o): Remove mbchar.h.
+ * lex.c (MULTIBYTE_CHARS): Lose.
+ * parser.c (cp_lexer_get_preprocessor_token): CPP_OTHER handled
+ in c-lex.c.
+
+2003-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9847
+ * cp-tree.h (duplicate_tag_error): Remove.
+ * class.c (duplicate_tag_error): Remove.
+ * semantics.c (begin_class_definition): Return immediately for a
+ duplicate class definition.
+
+ PR c++/10451
+ * decl.c (grokdeclarator): Correct logic for "mutable" errors.
+
+2003-04-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10446
+ * search.c (lookup_fnfields_1): Handle empty slots in the method
+ vector.
+
+ PR c++/10428
+ * decl.c (check_elaborated_type_specifier): New function, split
+ out from ...
+ (xref_tag): ... here. Use the new function in more places.
+
+ * rtti.c (throw_bad_typeid): Use build_cxx_call.
+
+2003-04-21 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_over_call): Use build_cxx_call.
+ (build_cxx_call): New method, split out of build_over_call.
+ * cp-tree.h (language_function): Add can_throw.
+ (build_cxx_call): Declare it.
+ * decl.c (finish_function): If a function does not contain any
+ calls to functions that can throw an exception, indicate that
+ fact.
+ * decl2.c (mark_used): Do not defer the instantiation of
+ functions, if the current function does not throw.
+ * optimize.c (maybe_clone_body): Copy TREE_NOTHROW to the clones.
+ * pt.c (instantiate_decl): Make sure import_export_decl is called
+ before emitting things.
+ * rtti.c (throw_bad_cast): Use build_cxx_call.
+ (build_dynamic_cast_1): Likewise.
+ * typeck.c (build_function_call): Likewise.
+
+2003-04-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9881
+ * typeck.c (build_unary_op): Fold all COMPONENT_REF addr
+ expressions. Reverts my 2002-08-08 patch.
+
+ * typeck.c (comp_ptr_ttypes_real): Swap final && operands for
+ cheaper early exit.
+
+2003-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp/decl2.c (start_static_storage_duration_function): Take count
+ arg, don't check if it wraps round.
+ (generate_ctor_or_dtor_function): Add locus arg, use it.
+ (generate_ctor_and_dtor_functions_for_priority): Data arg is a
+ locus.
+ (finish_file): Set line numbers to past EOF for synthesized
+ functions.
+
+2003-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10405
+ * search.c (lookup_field_1): Final scan goes backwards for
+ types, forwards for non-types.
+
+2003-04-17 Roger Sayle <roger@eyesopen.com>
+
+ PR c/10375
+ * decl.c (duplicate_decls): Preserve "const", "noreturn" and
+ "nothrow" function attributes.
+
+2003-04-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/10347
+ * pt.c (type_dependent_expression_p): Handle array new.
+
+2003-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10381
+ * parser.c (cp_parser_primary_expression): Reorganize logic for
+ dealing with name lookup failures.
+
+2003-04-15 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (mark_used): Don't instantiate anything if
+ skip_evaluation.
+
+2003-04-14 Ziemowit Laski <zlaski@apple.com>
+
+ * tree.c (build_cplus_array_type_1): Do not call
+ uses_template_parms() on a NULL index_type.
+
+2003-04-13 Roger Sayle <roger@eyesopen.com>
+
+ * decl.c (duplicate_decls): Preserve pure and malloc attributes.
+
+2003-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10300
+ * init.c (build_new_1): Reorganize.
+
+2003-04-12 Zack Weinberg <zack@codesourcery.com>
+
+ * class.c (initialize_array)
+ * decl.c (reshape_init)
+ * decl2.c (build_expr_from_tree)
+ * init.c (build_zero_init)
+ * pt.c (tsubst_copy, tsubst_copy_and_build)
+ * rtti.c (tinfo_base_init, generic_initializer, ptr_initializer)
+ (ptm_initializer, class_initializer, get_pseudo_ti_init)
+ * semantics.c (finish_compound_literal)
+ * typeck.c (build_ptrmemfunc1)
+ * typeck2.c (store_init_value, process_init_constructor)
+ (build_functional_cast): Use build_constructor.
+
+2003-04-12 Zack Weinberg <zack@codesourcery.com>
+
+ * call.c (print_z_candidates): Use gcc_gettext_width, not
+ strlen, to determine how much padding to use.
+
+2003-04-10 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c: Update all calls to shadow_warning.
+
+2003-04-10 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Correct handling for overlong
+ bit-fields whose width is the same as an integer type.
+
+2003-04-06 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-tree.def: Make fourth element for all 'c' and 'x' nodes zero.
+ * cp-lang.c (cp_tree_size): New function.
+ (LANG_HOOKS_TREE_SIZE): Override.
+
+ * cp-tree.h (SOURCE_LOCUS, SRCLOC_FILE, SRCLOC_LINE, struct
+ tree_srcloc, TS_CP_COMMON, TS_CP_SRCLOC): Kill.
+ (union lang_tree_node): Remove common and srcloc members.
+ (build_srcloc_here): Don't prototype.
+ * decl.c (cp_tree_node_structure): Kill SRCLOC case.
+ * pt.c (pending_templates): Correct comment.
+ * tree.c (build_srcloc, build_srcloc_here): Kill.
+
+2003-04-06 Zack Weinberg <zack@codesourcery.com>
+
+ * call.c: Include intl.h.
+ (print_z_candidate): Always use inform; get rid of errfn
+ argument. Reorganize so that all the strings get picked up
+ by xgettext. Note obligation of caller to pass first argument
+ through gettext.
+ (print_z_candidates): Update to match. Indent second and
+ successive candidates by strlen() of translated message.
+ (joust): Restructure ambiguous-conversion pedwarn so that
+ translators see a complete sentence. Update calls to
+ print_z_candidate.
+
+ * Make-lang.in (cp/call.o): Update dependencies.
+
+2003-04-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (set_current_binding_level): Delete, revert last change.
+ (current_binding_level): Modify to allow it as as lvalue.
+
+2003-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * name-lookup.c (find_binding): Pass appropriate pointer type to
+ POP_TIMEVAR_AND_RETURN.
+
+2003-04-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (cp-warn): Add $(STRICT_WARN).
+ * cp-tree.h: Don't insist on having GNUC.
+
+2003-04-03 Jason Merrill <jason@redhat.com>
+
+ * cvt.c (ocp_convert): Only abort if we try to convert an object
+ of TREE_ADDRESSABLE type.
+
+ * class.c (build_vtable): Set DECL_ALIGN here.
+ (get_vtable_decl): Not here.
+ (layout_vtable_decl): Or here.
+ (create_vtable_ptr): Or here.
+ (layout_class_type): Or here.
+ (check_bitfield_decl): Don't mess with field alignment.
+
+2003-04-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * operators.def (DEF_SIMPLE_OPERATOR, DEF_ASSN_OPERATOR,
+ DEF_ASSN_OPERATOR): Delete spurious semi-colon.
+ * rtti.c (dfs_class_hint_mark): Likewise.
+
+ * decl.c (push_local_name, push_class_level_binding,
+ maybe_inject_for_scope_var): Don't use POP_TIMEVAR_AND_RETURN in
+ functions returning void.
+ * decl2.c (add_using_namespace): Likewise.
+
+ * decl.c (print_binding_level, print_other_binding_stack,
+ print_binding_stack): Cast argument of %p specifier to void*.
+ * ptree.c (cxx_print_decl): Likewise.
+
+ * cp-tree.h (VAR_OR_FUNCTION_DECL_CHECK,
+ VAR_FUNCTION_OR_PARM_DECL_CHECK,
+ VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK, RECORD_OR_UNION_TYPE_CHECK,
+ BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK, LANG_TYPE_CLASS_CHECK,
+ LANG_TYPE_PTRMEM_CHECK, LANG_DECL_U2_CHECK): Add __extension__.
+
+ * decl.c (set_current_binding_level): New macro. Use throughout
+ when setting the current binding level.
+
+ * cp-tree.h (cp_lvalue_kind, base_access): Delete trailing comma
+ in enum.
+ * method.c (mangling_flags): Likewise.
+
+ * cp-tree.h (lang_type_header): Add __extension__ and use
+ CHAR_BITFIELD for members.
+
+2003-04-02 Geoffrey Keating <geoffk@apple.com>
+
+ PR other/9274
+ * mangle.c: Include gt-cp-mangle.h.
+ (subst_identifiers): Mark with GTY.
+ * config-lang.in (gtfiles): Add cp/mangle.c.
+ * Make-lang.in: (gt-cp-mangle.h): New rule.
+ (cp/mangle.o): Depends on gt-cp-mangle.h.
+
+2003-04-01 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * config-lang.in (gtfiles): Add \$(srcdir)/cp/name-lookup.c
+ after \$(srcdir)/cp/name-lookup.h.
+ * name-lookup.c: (cxx_binding_make): Use ggc_alloc_clearedinstead
+ of ggc_alloc. Include gt-cp-name-lookup.h at the end of the file.
+ * Make-lang.in: (gt-cp-name-lookup.h): Is generated by gengtype.
+ (cp/name-lookup.o): Depends on gt-cp-name-lookup.h.
+
+2003-03-31 Jason Merrill <jason@redhat.com>
+
+ PR java/10145
+ * class.c (check_field_decl): Don't set DECL_ALIGN.
+
+2003-03-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7647
+ * decl.c (grokdeclarator): Tidy, slightly.
+ * search.c (lookup_field_1): Add want_type parameter.
+ (lookup_field_r): Adjust call to lookup_field_1.
+
+2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * Make-lang.in (cp/name-lookup.o): Add more dependencies.
+
+2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (binding_for_name: Move to name-lookup.h Adjust
+ prototype.
+ (cxx_scope_find_binding_for_name): Likewise.
+ * decl.c (find_binding: Move to name-lookup.c.
+ (binding_for_name): Likewise.
+ (cxx_scope_find_binding_for_name): Likewise.
+ (BINDING_LEVEL): Remove.
+ (push_binding): Tidy.
+ (push_class_binding): Likewise.
+ (pop_binding): Likewise.
+ (poplevel): Likewise.
+ (poplevel_class): Likewise.
+ (set_identifier_type_value_with_scope): Likewise.
+ (push_overloaded_decl): Likewise.
+ (lookup_tag): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_name_current_level): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (namespace_binding): Move to name-lookup.c.
+ (set_namespace_binding): Likewise.
+ * decl2.c (lookup_using_namespace): Tidy.
+ (qualified_lookup_using_namespace): Likewise.
+ (do_toplevel_using_decl): Likewise.
+ * name-lookup.c: Include "timevar.h"
+ * name-lookup.h (cxx_scope): Declare.
+ (struct cxx_binding): Lose member "has_level". Adjust "scope"
+ member declaration.
+ (BINDING_SCOPE): Adjust definition.
+ (BINDING_HAS_LEVEL_P): Remove.
+
+2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * name-lookup.c: New file.
+ * name-lookup.h: Likewise..
+ * decl.c (push_binding): Adjust use cxx_binding_make.
+ (free_bindings): Move to name-lookup.c
+ (pop_binding): Use cxx_binding_free.
+ (binding_for_name): Tidy.
+ * cp-tree.h: Include "name-lookup.h"
+ (cxx_binding_make): Move to name-lookup.h
+ (cxx_binding_clear): Likewise.
+ (struct cxx_binding): Likewise.
+ (LOCAL_BINDING_P): Likewise.
+ (INHERITED_VALUE_BINDING_P): Likewise.
+ (BINDING_SCOPE): Likewise.
+ (BINDING_HAS_LEVEL_P): Likewise.
+ (BINDING_VALUE): Likewise.
+ (BINDING_TYPE): Likewise.
+ * config-lang.in (gtfiles): Add cp/name-lookup.h
+ * Make-lang.in (cp/name-lookup.o): New rule.
+ (CXX_OBJS): Add cp/name-lookup.o
+ (CXX_TREE_H): Add cp/name-lookup.h
+
+2003-03-28 Jason Merrill <jason@redhat.com>
+
+ PR c++/10245
+ * cvt.c (force_rvalue): New fn.
+ * call.c (build_conditional_expr): Use it.
+ * cp-tree.h: Declare it.
+
+2003-03-28 Mike Stump <mrs@apple.com>
+
+ * error.c (dump_expr): Add 0x to printed hex numbers to make
+ output match source code better.
+
+2003-03-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/10218
+ * decl.c (grokfndecl): Return NULL_TREE for bogus out-of-class
+ definitions.
+
+ * decl2.c (generate_ctor_or_dtor_function): Tolerate a
+ non-existant ssdf_decls array.
+ (finish_file): Call generator_ctor_or_dtor_function when there are
+ static constructors or destructors and no other static
+ initializations.
+
+2003-03-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10047
+ * decl2.c (finish_file): Don't warn about explicitly instantiated
+ inline decls.
+
+2003-03-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10224
+ * pt.c (lookup_template_class): Only check instantiated args if
+ they do not contain template parameters.
+
+2003-03-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10158
+ * parser.c (cp_parser_function_definition): Set
+ DECL_INITIALIZED_IN_CLASS for members.
+ * pt.c (instantiate_decl): Only reduce the template args for
+ friends that are not defined in class.
+
+2003-03-25 Jason Merrill <jason@redhat.com>
+
+ * call.c (print_z_candidate): Change name of first arg to msgid.
+ (joust): Add comment for translators.
+
+2003-03-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9898, PR c++/383, DR 322
+ * pt.c (maybe_adjust_types_for_deduction) <DEDUCE_CONV>: Look
+ through reference types on both PARM and ARG.
+
+2003-03-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10119
+ * error.c (dump_expr) <BASELINK>: Use dump_expr.
+ * pt.c (maybe_fold_nontype_args): New function.
+ (tsubst_copy) <SCOPE_REF>: Subst any template_id args.
+ <TEMPLATE_ID_EXPR>: Break out folding code, call it.
+ (tsubst_copy_and_build) <TEMPLATE_ID_EXPR>: Call
+ maybe_fold_nontype_args.
+
+2003-03-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/10026
+ * decl2.c (arg_assoc_type) <ERROR_MARK>: Don't die.
+
+2003-03-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7086
+ * typeck.c (cxx_mark_addressable): Adjust call to
+ gen_mem_addressof or put_var_into_stack.
+
+2003-03-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9978, c++/9708
+ * cp-tree.h (instantiate_template): Add tsubst_flags parameter.
+ * call.c (add_template_candidate_real): Adjust
+ instantiate_template call.
+ * class.c (resolve_address_of_overloaded_function): Likewise.
+ * decl.c (build_enumerator): Set TREE_CONSTANT.
+ * pt.c (check_instantiated_args): New.
+ (push_inline_template_parms_recursive): Set TREE_CONSTANT,
+ TREE_READONLY.
+ (build_template_parm_index): Copy TREE_CONSTANT, TREE_READONLY.
+ (reduce_template_parm_level): Likewise.
+ (process_template_parm): Likewise.
+ (check_explicit_specialization): Adjust instantiate_template call.
+ (convert_template_argument): Don't check non-type argument here.
+ (lookup_template_class): Check them here.
+ (tsubst_friend_function): Adjust instantiate_template call.
+ (instantiate_template): Add tsubst_flags parameter, use it. Check
+ instantiated args.
+
+2003-03-21 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c: Update calls to shadow_warning.
+
+2003-03-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9898
+ * error.c (dump_decl) [CONST_DECL]: Print '<enumerator>'.
+ (dump_expr) [CONSTRUCTOR]: Print default ctor as a function call.
+
+2003-03-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/decl2.c (arg_assoc_class): Correct check for namespace-scope
+ friends.
+ * cp/pt.c (instantiate_class_template): Fix formatting.
+
+2003-03-14 Matt Austern <austern@apple.com>
+
+ * cp-tree.h (unemitted_tinfo_decls): Declaration of a new varray.
+ (unemitted_tinfo_decl_p): Remove.
+ (emit_tinfo_decl): Change declaration to remove unused parameter.
+ * decl2.c (finish_file): Change tinfo emission to loop through
+ unemitted_tinfo_decls array instead of looping through all decls.
+ * rtti.c (unemitted_tinfo_decl_p): Declare as static, remove
+ unused second parameter.
+ (init_rtti_processing): initialize unemitted_tinfo_decls varray.
+ (get_tinfo_decls): push new tinfo decl on unemitted_tinfo_decls.
+ (emit_tinfo_decl): remove unused second parameter, add assertion
+ that decl hasn't already been emitted.
+
+2003-03-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * dump.c (cp_dump_tree), cp-tree.h (cp_dump_tree): Change return
+ type from 'int' to 'bool'. Replace 0 and 1 with true and false in
+ return statements.
+
+2003-03-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/8316, c++/9315, c++/10136
+ * call.c (print_z_candidate): Split out from...
+ (print_z_candidiates): ...here.
+ (joust): Use it.
+
+2003-03-17 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/10031
+ * decl.c (duplicate_decls): Use the new type when prototyping
+ anticipated decls, even when the types match. This defines the
+ exception list for the built-in function.
+
+2003-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/10091
+ * typeck.c (build_class_member_access_expr): Compare
+ TYPE_MAIN_VARIANTs.
+
+2003-03-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9639
+ * parser.c (cp_parser_declarator_id): Clear parser->scope.
+
+2003-03-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/9993
+ * decl.c (finish_function): Only allow the NRVO to use variables
+ declared at function scope.
+
+2003-03-17 Andreas Jaeger <aj@suse.de>
+
+ * Make-lang.in (cp/TAGS): Remove.
+
+2003-03-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9629
+ * cp-tree.h (struct language_function): Add in_base_initializer.
+ (in_base_initializer): define it.
+ (expand_member_init): Remove INIT param.
+ * init.c (expand_member_init): Remove INIT param, return the member.
+ (emit_mem_initializers): Set in_base_initializer.
+ * class.c (build_base_path): Check in_base_initializer.
+ * parser.c (cp_parser_mem_initializer): Set in_base_initializer.
+ * pt.c (tsubst_initializer_list): Likewise.
+
+2003-03-16 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (binding_for_name): Fix initialization thinko.
+
+2003-03-15 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Compile-time improvement: 2/n.
+ * cp-tree.h (struct cxx_binding): New datatype;
+ (struct lang_identifier): Use it.
+ (LOCAL_BINDING_P): Adjust definition.
+ (INHERITED_VALUE_BINDING_P): Likewise.
+ (BINDING_SCOPE): Likewise.
+ (BINDING_HAS_LEVEL_P): Likewise.
+ (BINDING_VALUE): Likewise.
+ (BINDING_TYPE): Likewise.
+ (IDENTIFIER_VALUE): Likewise.
+ (struct tree_binding): Remove.
+ (TS_CP_BINDING): Likewise.
+ ((union lang_tree_node): Remove field "binding".
+ (cxx_binding_clear): New macro.
+ (binding_for_name): Adjust return type.
+ (qualified_lookup_using_namespace): Adjust prototype.
+ (lookup_using_namespace): Adjust prototype.
+ (cxx_scope_find_binding_for_name): Declare.
+ * cp-tree.def: Remove CPLUS_BINDING definition.
+ * decl.c (push_binding): Adjust local variable type.
+ (add_binding): Likewise.
+ (push_class_binding): Likewise.
+ (pop_binding): Likewise.
+ (poplevel): Likewise.
+ (poplevel_class): Likewise.
+ (free_bindings): Adjust type.
+ (find_binding): Adjust return type, add a third parameter. Remove
+ non-useful assertion now that we use static typing.
+ (cxx_scope_find_binding_for_name): New function.
+ (binding_for_name): Use it. Adjust local variable type. Simplify.
+ (namespace_binding): Simplify.
+ (set_namespace_binding): Likewise.
+ (set_identifier_type_value_with_scope): Adjust local variable type.
+ (lookup_tag): Don't type-abuse of local variable 'old'.
+ (lookup_namespace_name): Likewise. Allocate binding on stack.
+ (select_decl): Adjust prototype.
+ (unqualified_namespace_lookup): Allocate binding on stack.
+ Don't type-abuse of local variable 'val'.
+ (lookup_name_real): Likewise.
+ (maybe_inject_for_scope_var): Adjust local variable type.
+ (cp_tree_node_structure): Remove CPLUS_BINDING case label.
+ (namespace_binding): Adjust logic, simplify.
+ (BINDING_LEVEL): Adjust definition.
+ (push_class_level_binding): Adjust local variable type.
+ (struct cxx_saved_binding): Adjust field 'binding' type.
+ * decl2.c (ambiguous_decl): Adjust prototype.
+ (lookup_using_namespace): Adjust local variable type.
+ (qualified_lookup_using_namespace): Catch type error and correct
+ ensueing logic error.
+ (do_nonmember_using_decl): Adjust local variable type. Allocate
+ temporary cxx_binding on stack.
+ (do_toplevel_using_decl): Adjust local variable type.
+ * ptree.c (cxx_print_cxx_binding): New function.
+ (cxx_print_identifier): Use it.
+ (cxx_print_xnode): Delete CPLUS_BINDING case label.
+
+2003-03-15 Roger Sayle <roger@eyesopen.com>
+
+ * tree.c (count_functions): Fix whitespace.
+
+2003-03-15 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Update.
+
+2003-03-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6440
+ * pt.c (maybe_process_partial_specialization): Handle
+ member class template when enclosing class template is
+ explicit specialized.
+ (most_general_template): Stop looking when DECL is already
+ specialized.
+
+2003-03-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/9420
+ * search.c (lookup_conversions): Call complete_type here.
+ * call.c (implicit_conversion): Not here.
+
+2003-03-13 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (do_nonmember_using_decl): Correct handling of
+ simultaneous type/non-type bindings.
+
+ * call.c (initialize_reference): Remove bogus assertion.
+ * decl.c (build_ptrmemfunc_type): Revert change of 2003-03-09.
+
+2003-03-12 Andrew Lewycky <andrew@mxc.ca>
+
+ PR c++/7050
+ * expr.c (cxx_expand_expr): Return const0_rtx for throw
+ expressions.
+
+2003-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9474
+ * decl2.c (do_nonmember_using_decl): Do not call duplicate decls
+ to merge old and new declarations.
+
+2003-03-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * g++.1: Remove.
+ * Make-lang.in (c++.generated-manpages): Build cp/g++.1.
+ (cp/g++.1): Build it from scratch in the build tree.
+ (c++.install-man): Depend on it. Install it from the build tree.
+ (c++.mostlyclean): Clean it.
+
+2003-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9474
+ * decl2.c (do_nonmember_using_decl): Do not call duplicate decls
+ to merge old and new declarations.
+
+ PR c++/9924
+ * decl2.c (do_nonmember_using_decl): Ignore anticipated builtins.
+
+2003-03-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/9820
+ * search.c (lookup_member): Fix handling of functions in a class
+ being defined.
+
+2003-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8700
+ * call.c (convert_class_to_reference): Adjust usage of
+ splice_viable.
+ (any_viable): Remove.
+ (splice_viable): Combine with any_viable.
+ (print_z_candidates): Avoid printing duplicates.
+ (build_user_type_conversion_1): Adjust usage of splice_viable.
+ (build_new_function_call): Likewise.
+ (build_operator_new_call): Likewise.
+ (build_object_call): Likewise.
+ (build_conditional_expr): Likewise.
+ (build_new_op): Likewise.
+ (build_new_method_call): Likewise.
+ (joust): Remove spurious comment.
+ * cp-tree.h (DECL_FRIENDLIST): Correct documentation.
+ * decl2.c (arg_assoc_class): Simplify.
+ * friend.c (add_friend): Likewise.
+
+2003-03-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/8660
+ * decl2.c (check_classfn): A member template only matches a
+ member template.
+
+2003-03-11 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (CXX_C_OBJS): Update.
+ * lang-specs.h: Don't define __GNUG__ here.
+
+2003-03-10 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (perform_overload_resolution): New function.
+ (build_new_function_call): Use it.
+ (build_operator_new_call): Likewise.
+ (add_candidates): Add explicit_targs and template_only parameters.
+ (build_new_op): Adjust accordingly.
+ * cp-tree.h (build_operator_new_call): New function.
+ (build_function_call_real): Remove.
+ (build_function_call_maybe): Likewise.
+ * init.c (build_new_1): Use build_operator_new_call.
+ * typeck.c (build_function_call_real): Rename to ...
+ (build_function_call): ... this.
+
+2003-03-10 Devang Patel <dpatel@apple.com>
+
+ PR c++/9394
+ * g++spec.c (lang_specific_driver): Use DEFAULT_WORD_SWTCH_TAKES_ARG.
+
+2003-03-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/9798
+ * decl.c (push_using_directive): Push before recursing.
+
+ PR c++/9868, c++/9524
+ * call.c (resolve_scoped_fn_name): Handle the case of a function
+ pointer member.
+
+ * decl2.c (build_offset_ref_call_from_tree): Only mess with 'this'
+ argument in the pointer-to-member case.
+
+2003-03-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9373
+ * cp-lang.c (cxx_get_alias_set): Use alias set zero for
+ pointers to member functions.
+
+ PR c++/8534
+ * decl.c (build_ptrmemfunc_type): Do not allow default arguments
+ in pointer-to-member-function types.
+
+2003-03-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * expr.c (cplus_expand_constant): Use C90 prototype style.
+ (cxx_expand_expr): Likewise.
+
+2003-03-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9970
+ * decl.c (duplicate_decls): Only copy DECL_THUNKS for virtual
+ functions.
+
+2003-03-08 Geoffrey Keating <geoffk@apple.com>
+
+ * lang-specs.h (c++-header): Change .pch to .gch.
+
+2003-03-08 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-tree.h (cxx_init): Update prototype.
+ * lex.c (cxx_init): Similarly.
+
+2003-03-08 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9823
+ * cp-tree.h (begin_mem_initializers): Remove.
+ * parser.c (cp_parser_mem_initializer_list): Inline it here.
+ Do not call finish_mem_initializers if not in a constructor.
+ (cp_parser_class_head): Fix typo in error message.
+ * semantics.c (begin_mem_initializers): Remove.
+ * testsuite/g++.dg/parser/constructor1.C: New test.
+
+ PR c++/9809
+ * call.c (add_function_candidate): Skip builtin fuctions that have
+ not yet been declared.
+
+ PR c++/9982
+ * init.c (build_new_1): Correct logic for determining whether or
+ not to use an array cookie.
+
+ PR c++/9524
+ * parser.c (cp_parser_postfix_expression): Call
+ finish_non_static_data_member, even when processing_template_decl.
+
+ PR c++/9912
+ * cp-tree.h (is_ancestor): New function.
+ (handle_class_head): Change prototype.
+ * decl2.c (is_namespace_ancestor): Rename to ...
+ (namespace_anecestor): ... this.
+ (set_decl_namespace): Adjust accordingly.
+ (handle_class_head): Remove unnecessary parameters.
+ * parser.c (cp_parser_class_head): Check that
+ nested-name-specifiers are used appropriately.
+
+2003-03-07 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (reference_binding): Remove REF_IS_VAR parameter.
+ (implicit_conversion): Adjust call to reference_binding.
+ (make_temporary_var_for_ref_to_type): Add TYPE parameter.
+ (initialize_reference): Adjust handling for references bound to
+ rvalues.
+ * cp-tree.h (make_temporary_var_for_ref_to_temp): Change
+ prototype.
+ (real_non_cast_lvalue_p): New method.
+ * cvt.c (build_up_reference): Adjust use of
+ make_temporary_var_for_ref_to_temp.
+ * tree.c (real_non_cast_lvalue_p): New method.
+
+2003-03-07 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * except.c (init_exception_processing): Use C90 prototype style.
+ (cp_protect_cleanup_actions): Likewise.
+ (prepare_eh_type): Likewise.
+ (build_eh_type_type): Likewise.
+ (build_exc_ptr): Likewise.
+ (do_begin_catch): Likewise.
+ (dtor_nothrow): Likewise.
+ (do_end_catch): Likewise.
+ (push_eh_cleanup): Likewise.
+ (decl_is_java_type): Likewise.
+ (choose_personality_routine): Likewise.
+ (initialize_handler_parm): Likewise.
+ (expand_start_catch_block): Likewise.
+ (expand_end_catch_block): Likewise.
+ (begin_eh_spec_block): Likewise.
+ (finish_eh_spec_block): Likewise.
+ (do_allocate_exception): Likewise.
+ (do_free_exception): Likewise.
+ (wrap_cleanups_r): Likewise.
+ (stabilize_throw_expr): Likewise.
+ (build_throw): Likewise.
+ (complete_ptr_ref_or_void_ptr_p): Likewise.
+ (is_admissible_throw_operand): Likewise.
+ (nothrow_libfn_p): Likewise.
+ (can_convert_eh): Likewise.
+ (check_handlers_1): Likewise.
+ (check_handlers): Likewise.
+
+2003-03-06 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (merge_conversion_sequences): New function.
+ (build_conv): Set ICS_USER_FLAG for USER_CONVs.
+ (convert_class_to_reference): Correct handling of second
+ standard conversion sequence in a user-defined conversion
+ sequence.
+ (build_user_type_conversion_1): Use merge_conversion_sequences.
+ * cp-tree.def: Add comments for CONV nodes.
+ * rtti.c (get_tinfo_decl): Use build_address/build_nop.
+
+2003-03-07 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (init_error): Use C90 prototype style.
+ (dump_scope): Likewise.
+ (dump_qualifiers): Likewise.
+ (dump_template_argument): Likewise.
+ (dump_template_argument_list): Likewise.
+ (dump_template_parameter): Likewise.
+ (dump_template_bindings): Likewise.
+ (dump_type): Likewise.
+ (dump_typename): Likewise.
+ (class_key_or_enum): Likewise.
+ (dump_aggr_type): Likewise.
+ (dump_type_prefix): Likewise.
+ (dump_type_suffix): Likewise.
+ (dump_global_iord): Likewise.
+ (dump_simple_decl): Likewise.
+ (dump_decl): Likewise.
+ (dump_template_decl): Likewise.
+ (dump_function_decl): Likewise.
+ (dump_parameters): Likewise.
+ (dump_exception_spec): Likewise.
+ (dump_function_name): Likewise.
+ (dump_template_parms): Likewise.
+ (dump_char): Likewise.
+ (dump_expr_list): Likewise.
+ (dump_expr): Likewise.
+ (dump_binary_op): Likewise.
+ (dump_unary_op): Likewise.
+ (type_as_string): Likewise.
+ (expr_as_string): Likewise.
+ (decl_as_string): Likewise.
+ (context_as_string): Likewise.
+ (lang_decl_name): Likewise.
+ (cp_file_of): Likewise.
+ (cp_line_of): Likewise.
+ (decl_to_string): Likewise.
+ (expr_to_string): Likewise.
+ (fndecl_to_string): Likewise.
+ (code_to_string): Likewise.
+ (language_to_string): Likewise.
+ (parm_to_string): Likewise.
+ (op_to_string): Likewise.
+ (type_to_string): Likewise.
+ (assop_to_string): Likewise.
+ (args_to_string): Likewise.
+ (cv_to_string): Likewise.
+ (cxx_print_error_function): Likewise.
+ (cp_diagnostic_starter): Likewise.
+ (cp_diagnostic_finalizer): Likewise.
+ (cp_print_error_function): Likewise.
+ (function_category): Likewise.
+ (print_instantiation_full_context): Likewise.
+ (print_instantiation_partial_context): Likewise.
+ (maybe_print_instantiation_context): Likewise.
+ (print_instantiation_context): Likewise.
+ (cp_printer): Likewise.
+ (print_integer): Likewise.
+ (print_non_consecutive_character): Likewise.
+ (locate_error): Likewise.
+
+2003-03-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9965
+ * call.c (reference_binding): Add ref_is_var parameter.
+ (implicit_conversion): Adjust call to reference_binding.
+ (initialize_reference): Likewise.
+
+ PR c++/9400
+ * decl.c (pushdecl): Don't check for shadowing of DECL_ARTIFICIAL
+ PARM_DECLs.
+
+ PR c++/9791
+ * class.c (get_basefndecls): Use lookup_fnfields_1.
+
+2003-03-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9188
+ * parser.c (cp_parser_type_parameter): Remove redundant `expect'
+ in error message.
+ (cp_parser_single_declaration): Likewise.
+
+2003-03-05 Jason Merrill <jason@redhat.com>
+
+ PR c++/9440
+ * call.c (build_conditional_expr): Use convert rather than an
+ explicit NOP_EXPR.
+
+2003-03-02 Matt Austern <austern@apple.com>
+
+ * decl.c (cp_binding_level): Add static_decls varray member.
+ (add_decl_to_level): Add static/inline namespace scope
+ declarations to static_decls array.
+ (wrapup_global_for_namespace): Pass static_decls only, instead of
+ all decls, to wrapup_global_declarations/check_global_declarations.
+ (push_namespace): Initialize static_decls for ordinary namespaces.
+ (cxx_init_decl_processing): Initialize static_decls for global
+ namespace.
+
+2003-03-05 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (end_of_class): Correct thinko.
+
+2003-03-04 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config-lang.in: Replace ${libstdcxx_version} by its value.
+
+2003-03-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (cxx_saved_binding): Declare.
+ (struct saved_scope): Adjust type of field 'old_binding'.
+ * decl.c (cxx_saved_binding_make): New macro.
+ (struct cxx_saved_binding): Define.
+ (store_bindings): Adjust prototype. Use cxx_saved_binding to save
+ C++ bindings.
+ (maybe_push_to_top_level): Adjust local variable type.
+ (pop_from_top_level): Likewise.
+
+2003-03-04 Tom Tromey <tromey@redhat.com>
+
+ * Make-lang.in (c++.tags): New target.
+
+2003-03-04 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Update.
+
+2003-03-03 Jason Merrill <jason@redhat.com>
+
+ * decl.c (finish_enum): Do set the type in a template. Simplify.
+ * pt.c (tsubst_enum, tsubst_copy): Revert last patch.
+
+2003-03-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9878
+ * call.c (convert_class_to_reference): Correct conversion
+ sequences.
+ (reference_binding): Add ref_bound_directly_to_rvalue_p parameter.
+ (implicit_conversion): Adjust call to reference_binding.
+ (add_candidate): Change type of candidates parameter.
+ (add_function_candidate): Likewise.
+ (add_conv_candidate): Likewise.
+ (build_builtin_candidate): Likewise.
+ (add_builtin_candidate): Likewise.
+ (add_builtin_candidates): Likewise.
+ (add_template_candidate_real): Likewise.
+ (add_template_candidate): Likewise.
+ (add_template_conv_candidate): Likewise.
+ (build_user_type_conversion_1): Adjust accordingly.
+ (build_object_call): Likewise.
+ (build_conditional_expr): Likewise.
+ (add_candidates): Likewise.
+ (build_new_op): Likewise.
+ (convert_like_real): Use USER_CONV_CAND. Use build_nop.
+ (build_new_method_call): Adjust calls to add_function_candidate.
+ (make_temporary_var_for_ref_to_temp): New function.
+ (initialize_reference): Add decl parameter.
+ * class.c (build_rtti_vtbl_entries): Use build_address and
+ build_nop.
+ * cp-tree.h (initialize_reference): Change prototype.
+ (make_temporary_var_for_ref_to_temp): New function.
+ (build_type_conversion): Change prototype.
+ (build_address): New function.
+ (build_nop): Likewise.
+ * cvt.c (cp_convert_to_pointer): Adjust call to
+ build_type_conversion. Avoid indicating redundant NOP_EXPRs.
+ Use build_nop.
+ (convert_to_pointer_force): Use build_nop.
+ (build_up_reference): Use make_temporary_var_for_ref_to_temp.
+ (convert_to_reference): Adjust call to build_type_conversion.
+ (ocp_convert): Likewise.
+ (build_type_conversion): Remove for_sure parameter.
+ * decl.c (grok_reference_init): Use initialize_reference.
+ * typeck.c (build_address): New function.
+ (build_nop): Likewise.
+ (build_unary_op): Use them.
+ (build_ptrmemfunc): Tidy slightly.
+ (convert_for_initialization): Adjust call to
+ initialize_reference.
+ * typeck2.c (store_init_value): Remove #if 0'd code.
+
+2003-03-03 Jason Merrill <jason@redhat.com>
+
+ * decl.c (start_function): Clear DECL_NUM_STMTS.
+
+ * class.c (get_vtable_decl): Use vtbl_type_node.
+ (build_primary_vtable): Check for it.
+
+2003-03-02 Aldy Hernandez <aldyh@redhat.com>
+
+ * decl.c (check_initializer): Check for vector_opaque_p.
+
+2003-03-02 Ashif Harji <asharji@uwaterloo.ca>
+
+ * lang-specs.h (default_compilers): Add -no-integrated-cpp flag to
+ invoke an external cpp during compilation.
+
+2003-03-01 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (duplicate_decls): Convert use of warning_with_decl() to
+ that of warning().
+ (start_decl): Likewise.
+ (start_function): Likewise.
+
+2003-03-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (CXX_C_OBJS): Update.
+
+2003-02-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9892
+ * pt.c (instantiate_decl): Clear DECL_RTL for a VAR_DECL when
+ instantiating it.
+
+2003-02-28 Aldy Hernandez <aldyh@redhat.com>
+
+ * parser.c (cp_parser_init_declarator): Revert opaque
+ vector_opaque_p change.
+ Do not include target.h.
+
+2003-02-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9879
+ * cp-tree.h (build_zero_init): Add parameter.
+ * decl.c (cp_finish_decl): Adjust call.
+ * init.c (build_zero_init): Add nelts parameter. Adjust recursive
+ calls.
+ (build_default_init): Add nelts parameter. Adjust calls to
+ build_zero_init.
+ (build_new_1): Adjust call to build_default_init.
+ * typeck2.c (process_init_constructor): Adjust call to build_zero_init.
+
+2003-02-26 Devang Patel <dpatel@apple.com>
+
+ * decl.c (finish_enum): Merge two 'for' loops. Copy value node if
+ required. Postpone enum setting for template decls.
+ (build_enumerator): Delay copying value node until finish_enum
+ (). Remove #if 0'ed code.
+ * pt.c (tsubst_enum): Set TREE_TYPE and copy value node.
+ (tsubst_copy): Add check for enum type.
+
+2003-02-25 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9683
+ * decl2.c (prune_vars_needing_no_initialization): Do not throw
+ away initializations for DECL_EXTERNAL VAR_DECLs.
+ (finish_file): Adjust accordingly.
+ * pt.c (instantiate_decl): Do not defer VAR_DECLs.
+
+2003-02-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c (add_binding): Time TV_NAME_LOOKUP.
+ (push_class_binding): Likewise.
+ (set_namespace_binding): Likewise.
+
+2003-02-24 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9836
+ * cp-tree.h (CLASSTYPE_PRIMARY_TEMPLATE): Do not skip from
+ specializations back to the main template.
+ * parser.c (cp_parser_diagnose_invalid_type_name):Adjust use.
+ * pt.c (resolve_typename_type): Likewise.
+
+2003-02-24 Jeffrey D. Oldham <oldham@codesourcery.com>
+
+ PR c++/9778
+ * pt.c (tsubst_copy_and_build): For a templated function inside a
+ scope, process template arguments.
+
+2003-02-24 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9602
+ * typeck2.c (abstract_virtuals_error): Don't check when
+ TYPE is still template parameter dependent.
+
+2003-02-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5333
+ * cp-tree.h (CLASSTYPE_PRIMARY_TEMPLATE): New macro.
+ * parser.c (cp_parser_diagnose_invalid_type_name): Use it.
+ * pt.c (instantiate_class_template): Don't try to instantiate
+ dependent types.
+ (resolve_typename_type): Use CLASSTYPE_PRIMARY_TEMPLATE.
+
+2003-02-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9749
+ * decl.c (grokdeclarator): Do not allow parameters with variably
+ modified types.
+
+2003-02-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (grow_bfs_bases): Remove. Fold into ...
+ (bfs_walk): ... here, fix fencepost error. Fix merge lossage
+ in previous patch.
+
+2003-02-20 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9729
+ * mangle.c (mangle_conv_op_name_for_type): Issue an error message
+ when the G++ 3.2 ABI prevents correct compilation.
+
+2003-02-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ Change base class access representation. Share virtual base
+ binfos.
+ * cp/call.c (build_special_member_call): Remove binfo_for_vbase
+ call.
+ * cp/class.c (build_base_path): Likewise.
+ (build_primary_vtable): Adjust BINFO_NEW_VTABLE_MARKED use.
+ (build_secondary_vtable): Remove FOR_TYPE arg. Adjust.
+ (make_new_vtable): Adjust.
+ (force_canonical_binfo_r): Delete.
+ (force_canonical_binfo): Delete.
+ (mark_primary_virtual_base): Delete.
+ (dfs_unshared_virtual_bases): Delete.
+ (mark_primary_bases): Adjust.
+ (maybe_warn_about_overly_private_class): Adjust.
+ (dfs_base_derived_from): Delete.
+ (base_derived_from): Follow the inheritance chain.
+ (struct find_final_overrider_data): Add vpath member.
+ (dfs_find_final_overrider): Adjust.
+ (dfs_find_final_overrider_q, dfs_find_final_overrider_post): New.
+ (find_final_overrider): Adjust.
+ (update_vtable_entry_for_fn): Adjust.
+ (modify_all_vtables): Adjust.
+ (walk_subobject_offsets): Adjust.
+ (layout_nonempty_base_or_field): Adjust.
+ (layout_empty_base): Remove last parameter. Adjust.
+ (build_base_field): Adjust.
+ (build_base_fields): Adjust.
+ (propagate_binfo_offsets): Remove last parameter. Adjust.
+ (dfs_set_offset_for_unshared_vbases): Delete.
+ (layout_virtual_bases): Adjust.
+ (finish_struct_1): Adjust.
+ (init_class_processing): Don't init access nodes.
+ (dfs_get_primary_binfo): Delete.
+ (get_primary_binfo): Adjust.
+ (dump_class_hierarchy_r): Remove most derived arg, add IGO
+ parameter. Adjust.
+ (dump_class_hierarchy): Adjust.
+ (finish_vtbls): Adjust.
+ (get_original_base): Delete.
+ (build_vtt_inits): Adjust.
+ (dfs_build_secondary_vptr_vtt_inits): Adjust.
+ (dfs_ctor_vtable_bases_queue_p): Adjust.
+ (build_ctor_vtbl_group): Adjust.
+ (dfs_accumulate_vtbl_inits): Adjust.
+ (build_vtbl_initializer): Adjust.
+ (build_vbase_offset_vtbl_entries): Adjust.
+ (add_vcall_offset_vtbl_entries_1): Adjust.
+ * cp/cp-tree.h (CPTI_ACCESS_*): Remove.
+ (access_*_node): Remove.
+ (CANONICAL_BINFO): Delete.
+ (BINFO_UNSHARED_MARKED): Remove.
+ (BINFO_MARKED): Set LANG_FLAG_0 directly.
+ (SET_BINFO_MARKED, CLEAR_BINFO_MARKED): Delete.
+ (BINFO_VTABLE_PATH_MARKED): Set LANG_FLAG_3 directly.
+ (SET_BINFO_VTABLE_PATH_MARKED, CLEAR_BINFO_VTABLE_PATH_MARKED):
+ Delete.
+ (BINFO_NEW_VTABLE_MARKED): Set LANG_FLAG_4 directly.
+ (SET_BINFO_NEW_VTABLE_MARKED): Adjust.
+ (SET_BINFO_PUSHDECLS_MARKED, CLEAR_BINFO_PUSHDECLS_MARKED):
+ Delete.
+ (BINFO_DEPENDENT_BASE_P): New.
+ (dfs_walk, dfs_walk_real): Queue function takes derived binfo and
+ index.
+ (markedp, unmarkedp): Adjust.
+ (dfs_unmarked_real_bases_queue_p, dfs_marked_real_bases_queue_p,
+ dfs_skip_vbases, marked_vtable_pathp, unmarked_vtable_pathp,
+ find_vbase_instance, binfo_for_vbase): Delete.
+ (copied_binfo, original_binfo): Declare.
+ (finish_base_specifier): Add virtual_p arg.
+ (unshare_base_binfos): Delete.
+ (copy_base_binfos): Declare.
+ (reverse_path): Delete.
+ * cp/decl.c (xref_basetypes): Access and virtuality passed
+ differently. Don't copy direct base binfos here. Call
+ copy_base_binfos.
+ * cp/init.c (dfs_initialize_vtbl_ptrs): Adjust.
+ (initialize_vtbl_ptrs): Adjust.
+ (expand_member_init): Adjust.
+ * cp/parser.c (cp_parser_base_specifier): Adjust.
+ * cp/pt.c (instantiate_class_template): Adjust.
+ (get_template_base_recursive): Adjust.
+ * cp/rtti.c (get_pseudo_ti_init): Adjust.
+ (get_pseudo_ti_desc): Adjust.
+ * cp/tree.c (unshare_base_binfos): Rename to ...
+ (copy_base_binfos): ... here, reimplement.
+ (make_binfo): Set BINFO_DEPENDENT_BASE_P.
+ (reverse_path): Remove.
+ * cp/typeck.c (get_delta_difference): Adjust error messages.
+ * cp/semantics.c (finish_base_specifier): Add virtual arg, adjust.
+ * cp/search.c (lookup_base_r): Adjust.
+ (dynamic_cast_base_recurse): Adjust.
+ (canonical_binfo): Remove.
+ (dfs_canonical_queue): Remove.
+ (dfs_assert_unmarked_p): Remove.
+ (assert_canonical_unmarked): Remove.
+ (shared_marked_p, shared_unmarked_p): Remove.
+ (BINFO_ACCESS, SET_BINFO_ACCESS): Use TREE_PUBLIC & TREE_PRIVATE.
+ (dfs_access_in_type): Adjust.
+ (access_in_type): Adjust.
+ (dfs_accessible_queue_p): Adjust.
+ (dfs_accessible_p): Adjust.
+ (is_subobject_of_p_1, is_subobject_of_p): Remove.
+ (struct lookup_field_info): Remove from_dep_base_p field.
+ (lookup_field_queue_p): Adjust, test BINFO_DEPENDENT_BASE_P.
+ (lookup_field_r): Remove dependent base code.
+ (lookup_member): Likewise.
+ (dfs_walk, dfs_walk_real): Add access arg to queue fn.
+ (dfs_unmarked_real_bases_queue_p): Remove.
+ (dfs_marked_real_bases_queue_p): Remove.
+ (dfs_skip_vbases): Remove.
+ (dfs_get_pure_virtuals): Adjust.
+ (markedp, unmarkedp): Adjust.
+ (marked_vtable_pathp, unmarked_vtable_pathp): Remove.
+ (marked_pushdecls_p, unmarked_pushdecls_p): Adjust.
+ (dfs_unmark): Adjust.
+ (dfs_get_vbase_types):Remove.
+ (dfs_build_inheritance_graph_order): Remove.
+ (get_vbase_types): Remove
+ (dfs_find_vbase_instance): Remove.
+ (find_vbase_instance): Remove.
+ (dfs_debug_unmarkedp): Adjust.
+ (dependent_base_p): Remove.
+ (dfs_push_type_decls): Adjust.
+ (dfs_push_decls): Adjust.
+ (dfs_no_overlap_yet): Adjust.
+ (copied_binfo): New function.
+ (original_binfo): New function.
+ (binfo_for_vbase): Remove.
+
+2003-02-18 Zack Weinberg <zack@codesourcery.com>
+
+ * cp/search.c (grow_bfs_bases): New subroutine of bfs_walk.
+ (bfs_walk): Rewritten using circular queue of BINFO_BASETYPES
+ vectors, for speed.
+
+2003-02-18 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9704
+ * class.c (layout_class_type): In the 3.2 ABI, take into account
+ trailing bit fields when computing CLASSTYPE_SIZE_UNIT.
+
+2003-02-18 Matt Austern <austern@apple.com>
+
+ * cp/cp-lang.c: Change lang hooks so that final_write_globals does
+ nothing for C++.
+ * cp/decl.c (wrapup_globals_for_namespace): Remove special
+ handling of global namespace.
+
+2003-02-18 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (rid_to_yy): Delete.
+ (C_RID_YYCODE): Delete.
+ (finish_file): Delete redundant declaration.
+
+2003-02-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/9623
+ * decl.c (reshape_init): Don't mess with initializer labels.
+
+ PR c++/9485
+ * parser.c (cp_parser_postfix_expression): Set idk properly for
+ object->scope::member.
+
+2003-02-18 Ben Elliston <bje@redhat.com>
+
+ PR other/7350
+ * decl.c (duplicate_decls): Fix typo in comment.
+
+2003-02-17 Michael Elizabeth Chastain <mec@shout.net>
+
+ PR debug/9717
+ * class.c (build_base_field): Mark fields for base classes with
+ DECL_IGNORED_P.
+
+2003-02-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9457
+ * pt.c (tsubst_copy_and_build) [CONSTRUCTOR]: Substitute
+ CONSTRUCTOR_ELTS only once.
+
+2003-02-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9459
+ * error.c (dump_type_prefix): Handle TYPEOF_TYPE.
+ (dump_type_suffix): Likewise.
+
+2003-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c: ANSIfy function declarations and definitions.
+ * cp-tree.h (lookup_field, lookup_member): Last parameter is a bool.
+ * call.c (build_method_call, resolve_scoped_fn_name,
+ build_java_interface_fn_ref): Adjust lookup_field, lookup_member
+ calls.
+ * class.c (handle_using_decl): Likewise.
+ * decl.c (make_typename_type, make_unmound_class_template,
+ start_decl, compute_array_index_type): Likewise.
+ * decl2.c (build_expr_from_tree, build_call_from_tree): Likewise.
+ * init.c (expand_member_init, build_member_call): Likewise.
+ * pt.c (tsubst_copy, tsubst_copy_and_build, do_decl_instantiation,
+ resolve_typename_type): Likewise.
+ * typeck.c (lookup_destructor, finish_class_member_access_exprm
+ build_prememfunc_access_expr): Likewise.
+
+2003-02-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl2.c: Include "timevar.h".
+ (namespace_ancestor): Time name lookup.
+ (add_using_namespace): Likewise.
+ (lookup_using_namespace): Likewise.
+ (qualified_lookup_using_namespace): Likewise.
+ (decl_namespace): Likewise.
+ (lookup_arg_dependent): Likewise.
+ * lex.c (do_identifier): Likewise.
+ (do_scoped_id): Likewise.
+ * pt.c (lookup_template_class): Likewise.
+
+2003-02-14 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * decl.c: (define_label): Fix warning for return 0 instead of NULL.
+
+2003-02-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * decl.c: Include "timevar.h".
+ (poplevel): Time name lookup.
+ (find_binding): Likewise.
+ (push_namespace): Likewise.
+ (pop_nested_namespace): Likewise.
+ (store_bindings): Likewise.
+ (maybe_push_to_top_level): Likewise.
+ (pop_from_top_level): Likewise.
+ (push_local_name): Likewise.
+ (pushtag): Likewise.
+ (pushdecl): Likewise.
+ (pushdecl_with_scope): Likewise.
+ (pushdecl_namespace_level): Likewise.
+ (pushdecl_top_level): Likewise.
+ (pushdecl_class_level): Likewise.
+ (push_class_level_binding): Likewise.
+ (push_using_decl): Likewise.
+ (push_using_directive): Likewise.
+ (push_overloaded_decl): Likewise.
+ (lookup_label): Likewise.
+ (define_label): Likewise.
+ (lookup_tag): Likewise.
+ (lookup_tag_reverse): Likewise.
+ (lookup_namespace_name): Likewise.
+ (select_decl): Likewise.
+ (unqualified_namespace_lookup): Likewise.
+ (lookup_name_real): Likewise.
+ (lookup_name_current_level): Likewise.
+ (lookup_type_current_level): Likewise.
+ (maybe_inject_for_scope_var): Likewise.
+ (xref_tag): Likewise.
+
+ * Make-lang.in (cp/decl.o): Add dependency on timevar.h
+
+2003-02-12 Phil Edwards <pme@gcc.gnu.org>
+
+ * decl.c (build_enumerator): Remove unneeded test.
+
+2003-02-09 Dan Nicolaescu <dann@ics.uci.edu>
+
+ * cp-tree.h (struct lang_type_header): Make all fields unsigned
+ char.
+
+2003-02-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7129
+ * call.c (z_candidate): Add args.
+ (convert_class_to_reference): Set it.
+ (implicit_conversion): Tidy.
+ (add_candidate): Add args parameter.
+ (add_function_candidate): Adjust call to add_candidate.
+ (add_conv_candidate): Likewise.
+ (build_builtin_candidate): Likewise.
+ (build_user_type_conversion_1): Eliminate wasteful tree_cons
+ usage.
+ (build_new_function_call): Likewise.
+ (build_object_call): Likewise.
+ (add_candidates): New function.
+ (build_new_op): Use it.
+ (covert_like_real): Adjust call to build_over_call.
+ (build_over_call): Remove args parameter.
+ * operators.def: Add <?= and >?=.
+
+2003-02-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * typeck.c (build_indirect_ref): Don't check flag_volatile.
+
+2003-01-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8849
+ * pt.c (resolve_overloaded_unification): Handle FUNCTION_DECL.
+
+2003-01-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX,
+ BINFO_PRIMARY_BASE_OF): Use BINFO_ELTS.
+ (BINFO_LANG_ELTS): New #define.
+ * tree.c (make_binfo): Use BINFO_LANG_ELTS.
+
+2003-01-30 Geoffrey Keating <geoffk@apple.com>
+
+ * cp/Make-lang.in: Remove -Wno-error from cp/decl.o.
+
+2003-01-30 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (check_field_decls): Only check C_TYPE_FIELDS_READONLY
+ for class types.
+ * cp-tree.h (C_TYPE_FIELDS_READONLY): Use a lang-specific bit
+ rather than TYPE_LANG_FLAG_0.
+ (TYPE_BUILT_IN): Remove.
+ (TYPE_DEPENDENT_P): New macro.
+ (TYPE_DEPENDENT_P_VALID): Likewise.
+ (lang_type_class): Add fields_readonly.
+ * decl.c (record_builtin_type): Don't set TYPE_BUILT_IN.
+ * pt.c (dependent_type_p_r): New function, split out from ...
+ (dependent_type_p): ... here. Memoize results.
+ * search.c (dependent_base_p): Use dependent_type_p, not
+ uses_template_parms.
+ * typeck.c (build_modify_expr): Only check C_TYPE_FIELDS_READONLY
+ for class types.
+
+2003-01-29 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_field_call): Use build_new_op, not build_opfncall.
+ (prep_operand): New function.
+ (build_new_op): Use it. Remove dead code.
+ * class.c (pushclass): Change "modify" parameter type from int to
+ bool.
+ (currently_open_class): Use same_type_p, not pointer equality.
+ (push_nested_class): Adjust calls to pushclass, remove modify
+ parameter.
+ * cp-tree.h (INTEGRAL_OR_ENUMERATION_TYPE_P): New macro.
+ (pushclass): Change prototype.
+ (push_nested_class): Likewise.
+ (grokoptypename): Remove.
+ (build_opfncall): Remove.
+ (value_dependent_expression_p): Declare.
+ (resolve_typename_type): Likewise.
+ (resolve_typename_type_in_current_instantiation): Likewise.
+ (enter_scope_of): Remove.
+ (tsubst): Remove.
+ (tsubst_expr): Likewise.
+ (tsubst_copy): Likewise.
+ (tsubst_copy_and_build): Likewise.
+ * decl.c (warn_about_implicit_typename_lookup): Remove.
+ (finish_case_label): Return error_mark_node for erroneous labels.
+ (start_decl): Adjust calls to push_nested_class.
+ (grokfndecl): Call push_scope/pop_scope around call to
+ duplicate_decls.
+ (grokdeclarator): Do not call tsubst.
+ (start_function): Adjust calls to push_nested_class.
+ * decl2.c (grok_array_decl): Use build_new_op, not build_opfncall.
+ (check_classfn): Use push_scope/pop_scope around type comparisions.
+ (grokoptypename): Remove.
+ (push_sscope): Adjust call to push_nested_class.
+ * error.c (dump_type): Show cv-qualification of typename types.
+ * init.c (build_member_call): Use build_new_op, not
+ build_opfncall.
+ * method.c (build_opfncall): Remove.
+ * parser.c (cp_parser): Add allow_non_constant_expression_p and
+ non_constant_expression_p.
+ (cp_parser_constant_expression): Adjust prototype.
+ (cp_parser_resolve_typename_type): Remove.
+ (cp_parser_non_constant_expression): New function.
+ (cp_parser_non_constant_id_expression): Likewise.
+ (cp_parser_new): Set allow_non_constant_expression_p and
+ non_constant_expression_p.
+ (cp_parser_primary_expression): Reject `this' and `va_arg' in
+ constant-expressions. Note that dependent names aren't really
+ constant.
+ (cp_parser_postfix_expression): Reject conversions to non-integral
+ types in constant-expressions. Neither are increments or
+ decrements.
+ (cp_parser_unary_expression): Reject increments and decrements in
+ constant-expressions.
+ (cp_parser_direct_new_declarator): Adjust call to
+ cp_parser_constant_expression.
+ (cp_parser_cast_expression): Reject conversions to non-integral
+ types in constant-expressions.
+ (cp_parser_assignment_expression): Rejects assignments in
+ constant-expressions.
+ (cp_parser_expression): Reject commas in constant-expressions.
+ (cp_parser_labeled_statement): Adjust call to
+ cp_parser_constant_expression.
+ (cp_parser_direct_declarator): Simplify array bounds, even in
+ templates, when they are non-dependent. Use
+ resolve_typename_type, not cp_parser_resolve_typename_type.
+ (cp_parser_class_head): Use resolve_typename_type, not
+ cp_parser_resolve_typename_type.
+ (cp_parser_member_declaration): Adjust call to
+ cp_parser_constant_expression.
+ (cp_parser_constant_initializer): Likewise.
+ (cp_parser_constructor_declarator): Use resolve_typename_type, not
+ cp_parser_resolve_typename_type.
+ (cp_parser_late_parsing_default_args): Adjust call to
+ push_nested_class.
+ * pt.c (tsubst): Give it internal linkage.
+ (tsubst_expr): Likewise.
+ (tsubst_copy): Likewise.
+ (tsubst_copy_and_build): Likewise.
+ (push_access_scope_real): Likewise.
+ (tsubst_friend_class): Likewise.
+ (instantiate_class_template): Adjust call to pushclass.
+ (value_dependent_expression_p): Give it external linkage.
+ Robustify.
+ (resolve_typename_type): New function.
+ * semantics.c (finish_call_expr): Use build_new_op, not
+ build_opfncall.
+ (begin_constructor_declarator): Remove.
+ (begin_class_definition): Adjust call to pushclass.
+ (enter_scope_of): Remove.
+ * typeck.c (comptypes): Resolve typename types as appropriate.
+ (build_x_indirect_ref): Use build_new_op, not build_opfncall.
+ (build_x_compound_expr): Likewise.
+ (build_modify_expr): Likewise.
+ (build_x_modify_expr): Likewise.
+ * typeck2.c (build_x_arrow): Likewise.
+
+2003-01-29 Fariborz Jahanian <fjahanian@apple.com>
+
+ * pt.c (last_pending_template) Declare GTY().
+
+2003-01-29 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8591
+ * parser.c (cp_parser_elaborated_type_specifier): Convert
+ TEMPLATE_DECL to TYPE_DECL only when processing template friends.
+ (cp_parser_maybe_treat_template_as_class): Remove redundant tests.
+
+2003-01-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9437
+ * pt.c (unify): Don't unify '*T' with 'U C::*'.
+
+ PR c++/3902
+ * parser.c (cp_parser_decl_specifier_seq): Cannot have constructor
+ inside a declarator.
+
+2003-01-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (update_vtable_entry_for_fn): Add index parameter.
+ Generate vcall thunk for covariant overriding from a virtual
+ primary base.
+ (dfs_modify_vtables): Adjust.
+
+2003-01-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9403
+ * parser.c (cp_parser_class_or_namespace_name): Reject duplicate
+ template keyword.
+ (cp_parser_base_specifier): Look for and consume a
+ TEMPLATE keyword. Replace switch with array index.
+
+ PR c++/795
+ * semantics.c (finish_non_static_data_member): Remember the
+ field's type even in a template.
+
+ PR c++/9415
+ * pt.c (tsubst_copy_and_build, CALL_EXPR): BASELINK exprs are
+ already scoped.
+
+ PR c++/8545
+ * parser.c (cp_parser_cast_expression): Be more tentative.
+
+2003-01-25 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.h (flagged_type_tree_s): Remove.
+ (check_for_new_type): Likewise.
+ * typeck2.c (check_for_new_type): Likewise.
+
+2003-01-23 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * dump.c: ANSIfy function declarations and definitions.
+
+ * cp-tree.h, decl.h: Get rid of PARAMS. Again.
+
+2003-01-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9354
+ * init.c (build_new): Set the type of the new-expression, even
+ when processing_templte_decl.
+
+ PR c++/9216
+ * parser.c (cp_parser_primary_expression): Improve error message
+ for templates used in an expression context.
+
+ PR c++/8696
+ * parser.c (cp_parser_decl_specifier_seq): Commit to tentative
+ parse when encountering "typedef".
+
+2003-01-22 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * class.c, parser.c: ANSIfy function definitions and declarations.
+
+2003-01-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9328
+ * error.c (dump_decl): For an OVERLOAD, just print the name of the
+ function; it doesn't make sense to try to print its type.
+ * semantics.c (finish_typeof): Issue errors about invalid uses.
+
+ PR c++/9298
+ * parser.c (cp_parser_consume_semicolon_at_end_of_statement): New
+ function.
+ (cp_parser_expression_statement): Use it.
+ (cp_parser_explicit_instantiation): Likewise.
+ * pt.c (do_decl_instantiation): Improve error handling logic.
+
+2003-01-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9384
+ * parser.c (cp_parser_using_declaration): Issue error messages
+ about name resolution failures here.
+
+ PR c++/9388
+ * class.c (currently_open_derived_class): Use dependent_type_p.
+ * cp-tree.h (dependent_type_p): New function.
+ (dependent_template_arg_p): Likewise.
+ (dependent_template_p): Likewise.
+ (type_dependent_expression_p): Likewise.
+ * parser.c (cp_parser_dependent_type_p): Remove.
+ (cp_parser_value_dependent_type_p): Likewise.
+ (cp_parser_type_dependent_expression_p): Likewise.
+ (cp_parser_dependent_template_arg_p): Likewise.
+ (cp_parser_dependent_template_id_p): Likewise.
+ (cp_parser_dependent_template_p): Likewise.
+ (cp_parser_diagnose_invalid_type_name): Replace
+ cp_parser_dependent_type_p with dependent_type_p, etc.
+ (cp_parser_primary_expresion): Likewise.
+ (cp_parser_nested_name_specifier_opt): Likewise.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_lookup_name): Likewise.
+ * pt.c (dependent_type_p): New function.
+ (value_dependent_expression_p): Likewise.
+ (type_dependent_expression_p): Likewise.
+ (dependent_template_arg_p): Likewise.
+ (dependent_template_id_p): Likewise.
+ (dependent_template_p): Likewise.
+
+ PR c++/9285
+ PR c++/9294
+ * parser.c (cp_parser_simple_declaration): Return quickly when
+ encountering errors.
+
+2003-01-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ Make-lang.in (cp/decl.o-warn): Add -Wno-error.
+
+2003-01-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/9167, c++/9358
+ * decl.c (require_complete_types_for_parms): Also update DECL_ARG_TYPE.
+
+2003-01-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/9342
+ * call.c (build_conditional_expr): Always do lvalue-rvalue
+ conversion.
+
+2003-01-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9294
+ * cp-tree.def (BASELINK): Make it class 'x', not class 'e'.
+ * cp-tree.h (BASELINK_BINFO): Adjust.
+ (BASELINK_FUNCTIONS): Likewise.
+ (BASELINK_ACCESS_BINFO): Likewise.
+ (tree_baselink): New structure.
+ (cp_tree_node_structure_enum): Add TS_CP_BASELINK.
+ (lang_tree_node): Add baselink.
+ * decl.c (cp_tree_node_structure): Add BASELINK case.
+ * search.c (build_baselink): Adjust.
+ * tree.c (cp_walk_subtrees): Add BASELINK case. Remove BASELINK_P
+ test from TREE_LIST case.
+
+ PR c++/9272
+ * parser.c (cp_parser_constructor_declarator_p): Do not assume
+ that a constructor cannot be declared outside of its own class.
+
+ * parser.c (cp_parser_resolve_typename_type): If the scope cannot
+ be resolved, neither can the qualified name.
+
+ * rtti.c (get_pseudo_ti_desc): Fix thinko.
+
+2003-01-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/8564
+ * init.c (build_vec_init): Re-add maxindex parm.
+ (perform_member_init, build_aggr_init): Pass it.
+ (build_new_1): Pass it. Use an incomplete array type for full_type.
+ * typeck.c (build_modify_expr): Pass it.
+ * cp-tree.h: Adjust.
+
+2003-01-16 Jeffrey D. Oldham <oldham@codesourcery.com>
+
+ * cp-tree.h (tsubst_copy_and_build): New declaration.
+ * pt.c (tsubst_copy): Remove 'build_expr_from_tree' from comment.
+ (tsubst_expr): Use 'tsubst_copy_and_build'. Update initial comment.
+ (tsubst_copy_and_build): New function.
+
+2003-01-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_type_class): Remove is_partial_instantiation.
+ (PARTIAL_INSTANTIATION_P): Remove.
+ (IMPLICIT_TYPENAME_P): Likewise.
+ (IMPLICIT_TYPENAME_TYPE_DECL_P): Likewise.
+ (build_typename_type): Remove declaration.
+ (parmlist_is_exprlist): Likewise.
+ * decl.c (build_typename_type): Make it static, remove third
+ parameter.
+ (push_class_binding): Don't do implicit typename stuff.
+ (make_typename_type): Likewise.
+ (lookup_name_real): Likewise.
+ (grokdeclarator): Don't try to convert declarations into
+ initializations. Don't do implicit typename stuff.
+ (parmlist_is_exprlist): Remove.
+ (xref_basetypes): Simplify.
+ * decl2.c (grokfield): Don't try to convert declarations into
+ initializations.
+ (build_anon_union_vars): Do this while processing templates, too.
+ (finish_anon_union): Likewise.
+ * error.c (dump_type): Remove implicit typename handling.
+ * parser.c (cp_parser_diagnose_invalid_type_name): New method.
+ (cp_parser_primary_expression): Correct handling of names not
+ found by unqualified name lookup in templates.
+ (cp_parser_nested_name_specifier_opt): Avoid checking dependency
+ of types when possible.
+ (cp_parser_simple_declaration): Complain intelligently about some
+ invalid declarations.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_constructor_declarator_p): Don't check when we're in a
+ function scope.
+ * pt.c (instantiate_class_template): Remove
+ PARTIAL_INSTANTIATION_P gunk.
+ * search.c (lookup_field_r): Don't build implicit typenames.
+ (marked_pushdecls_p): Don't enter dependent base types.
+ (unmarked_pushdecls_p): Likewise.
+ * semantics.c (begin_class_definition): Remove implicit typename
+ stuff.
+
+2003-01-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9212
+ * parser.c (cp_parser_direct_declarator): If accepting either
+ abstract or named, the name must be an unqualified-id.
+
+2003-01-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (layout_virtual_bases): Avoid signed/unsigned warning.
+
+2003-01-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (check_classfn): Fix uninitialized warning.
+ (build_anon_union_vars): Likewise.
+ * pt.c (tsubst_copy): Likewise.
+
+2003-01-14 Jeffrey D. Oldham <oldham@codesourcery.com>
+
+ Further conform g++'s __vmi_class_type_info to the C++ ABI
+ specification.
+ * rtti.c (dfs_class_hint_mark): Do not set hints not specified by
+ the specification.
+ (class_hint_flags): Likewise.
+
+2003-01-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * config-lang.in: Add semantics.c to gtfiles.
+ * cp-tree.h (flagged_type_tree_s): Remove lookups field.
+ (saved_scope): Likewise.
+ (type_lookups): Remove.
+ (deferred_access): New structure.
+ (type_access_control): Remove.
+ (save_type_access_control): Likewise.
+ (reset_type_access_control): Likewise.
+ (decl_type_access_control): Likewise.
+ (push_deferring_access_checks): Declare.
+ (resume_deferring_access_checks): Likewise.
+ (stop_deferring_access_checks): Likewise.
+ (pop_deferring_access_checks): Likewise.
+ (get_deferred_access_checks): Likewise.
+ (pop_to_parent_deferring_access_checks): Likewise.
+ (perform_deferred_access_checks): Likewise.
+ (perform_or_defer_access_check): Likewise.
+ * decl.c (make_typename_type): Use perform_or_defer_access_check.
+ (make_unbound_class_template): Likewise.
+ (grokdeclarator): Don't call decl_type_access_control.
+ * parser.c (cp_parser_context): Remove deferred_access_checks
+ and deferring_access_checks_p fields.
+ (cp_parser_context_new): Adjust.
+ (cp_parser): Remove access_checks_lists.
+ (cp_parser_defer_access_check): Remove.
+ (cp_parser_start_deferring_access_checks): Remove.
+ (cp_parser_stop_deferring_access_checks): Remove.
+ (cp_parser_perform_deferred_access_checks): Remove.
+ (cp_parser_nested_name_specifier_opt): Use new deferred access
+ functions.
+ (cp_parser_simple_declaration): Likewise.
+ (cp_parser_template_id): Likewise.
+ (cp_parser_function_definition): Likewise.
+ (cp_parser_class_specifier): Likewise.
+ (cp_parser_lookup_name): Likewise.
+ (cp_parser_single_declaration): Likewise.
+ (cp_parser_pre_parsed_nested_name_specifier): Likewise.
+ (cp_parser_parse_tentatively): Likewise.
+ (cp_parser_parse_definitely): Likewise.
+ (yyparse): Likewise.
+ (cp_parser_init_declarator): Remove access_checks parameter.
+ Use new deferred access functions.
+ (cp_parser_function_definition_from_specifiers_and_declarator):
+ Likewise.
+ (cp_parser_class_head): Remove deferring_access_checks_p and
+ saved_access_checks parameters. Use new deferred access functions.
+ (cp_parser_member_specification_opt): Don't call
+ reset_type_access_control.
+ * search.c (type_access_control): Remove.
+ * semantics.c: Include "gt-cp-semantics.h".
+ (deferred_type_access_control): Remove.
+ (deferred_access_stack): New variable.
+ (deferred_access_free_list): Likewise.
+ (push_deferring_access_checks): New function.
+ (resume_deferring_access_checks): Likewise.
+ (stop_deferring_access_checks): Likewise.
+ (pop_deferring_access_checks): Likewise.
+ (get_deferred_access_checks): Likewise.
+ (pop_to_parent_deferring_access_checks): Likewise.
+ (perform_deferred_access_checks): New function, adapted from
+ cp_parser_perform_deferred_access_checks.
+ (perform_or_defer_access_check): New function, adapted from
+ cp_parser_defer_access_check.
+ (current_type_lookups): Remove.
+ (deferred_type_access_control): Likewise.
+ (decl_type_access_control): Likewise.
+ (save_type_access_control): Likewise.
+ (reset_type_access_control): Likewise.
+ (begin_function_definition): Adjust.
+ (begin_class_definiton): Likewise.
+
+2003-01-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/8748
+ * class.c (build_base_path): Take the address before calling save_expr.
+
+ * call.c (build_user_type_conversion_1): Do set ICS_BAD_FLAG if
+ all the ambiguous conversions are bad.
+
+ * class.c (maybe_warn_about_overly_private_class): Don't stop
+ searching when we find a nonprivate method.
+
+ * typeck.c (build_class_member_access_expr): Use unary_complex_lvalue.
+
+2003-01-12 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (get_arglist_len_in_bytes): Remove.
+
+ PR c++/9264
+ * parser.c (cp_parser_elaborated_type_specifier): Handle erroneous
+ typeame types more robustly.
+
+2003-01-11 Phil Edwards <pme@gcc.gnu.org>
+
+ * parser.c: Fix comment typos.
+
+2003-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9099
+ * parser.c (cp_parser_scope_through_which_access_occurs): Handle
+ an object_type which is not a class type.
+
+2003-01-10 Geoffrey Keating <geoffk@apple.com>
+
+ * parser.c (cp_parser_late_parsing_for_member): Don't cast to void.
+ (cp_parser_late_parsing_default_args): Likewise.
+
+2003-01-10 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cfns.gperf: ANSIfy function declarations.
+ * cfns.h: Regenerate.
+ * cp-tree.h: ANSIfy function declarations.
+
+2003-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (reparse_absdcl_as_expr): Remove.
+ (reparse_absdcl_as_casts): Likewise.
+ (reparse_decl_as_expr): Likewise.
+ (finish_decl_parsing): Likewise.
+ * decl2.c (reparse_absdcl_as_expr): Remove.
+ (reparse_absdcl_as_casts): Likewise.
+ (repase_decl_as_expr): Likewise.
+ (finish_decl_parsing): Likewise.
+
+ PR c++/9128
+ PR c++/9153
+ PR c++/9171
+ * parser.c (cp_parser_pre_parsed_nested_name_specifier): New
+ function.
+ (cp_parser_nested_name_specifier_opt): Correct the
+ check_dependency_p false.
+ (cp_parser_postfix_expression): Fix formatting.
+ (cp_parser_decl_specifier_seq): Avoid looking for constructor
+ declarators when possible.
+ (cp_parser_template_id): Avoid performing name-lookup when
+ possible.
+ (cp_parser_class_head): Do not count specializations when counting
+ levels of templates.
+ (cp_parser_constructor_declarator_p): Return immediately if
+ there's no chance that the tokens form a constructor declarator.
+ * rtti.c (throw_bad_typeid): Add comment. Do not return an
+ expression with reference type.
+ (get_tinfo_decl_dynamic): Do not return an expression with
+ reference type.
+ (build_typeid): Add comment. Do not return an expression with
+ reference type.
+ * typeck.c (build_class_member_access_expr): Improve handling of
+ conditionals and comma-expressions as objects.
+
+2003-01-09 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cfns.gperf: ANSIfy function declarations.
+ * cfns.h: Regenerate.
+ * cp-tree.h: ANSIfy function declarations.
+ * parser.c: ANSIfy function declarations & definitions.
+
+ * decl.c (bad_specifiers): Fix parameter order error I introduced.
+
+2003-01-09 Geoffrey Keating <geoffk@apple.com>
+
+ Merge from pch-branch:
+
+ 2003-01-09 Geoffrey Keating <geoffk@apple.com>
+
+ Merge to tag pch-merge-20030102:
+
+ * semantics.c (finish_translation_unit): Don't call finish_file.
+ * parser.c: Don't include ggc.h.
+ (cp_lexer_new_main): Rename from cp_lexer_new, only create main lexer,
+ read first token here. Don't allow PCH files after the first
+ token is read.
+ (cp_lexer_new_from_tokens): Duplicate functionality from cp_lexer_new.
+ (cp_lexer_get_preprocessor_token): Allow LEXER to be NULL.
+ (cp_parser_new): Call cp_lexer_new_main before allocating GCed memory.
+ (cp_parser_late_parsing_for_member): Don't duplicate call to
+ cp_lexer_set_source_position_from_token.
+ (cp_parser_late_parsing_default_args): Likewise.
+ (yyparse): Call finish_file after clearing the_parser.
+
+ 2002-12-11 Geoffrey Keating <geoffk@apple.com>
+
+ * Make-lang.in: Remove $(GGC_H) from all dependencies.
+ (CXX_TREE_H): Add $(GGC_H).
+ * class.c: Don't include ggc.h.
+ (field_decl_cmp): Make parameters be 'const void *' to match qsort.
+ (method_name_cmp): Likewise.
+ (resort_data): New variable.
+ (resort_field_decl_cmp): New.
+ (resort_method_name_cmp): New.
+ (resort_sorted_fields): New.
+ (resort_type_method_vec): New.
+ (finish_struct_methods): Delete cast.
+ (finish_struct_1): Delete cast.
+ * cp-tree.h: Include ggc.h.
+ (struct lang_type_class): Add reorder attribute to field `methods'.
+ (union lang_decl_u3): Add reorder attribute to field `sorted_fields'.
+ (resort_sorted_fields): New prototype.
+ (resort_type_method_vec): New prototype.
+ * call.c: Don't include ggc.h.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * init.c: Likewise.
+ * lex.c: Likewise.
+ * method.c: Likewise.
+ * optimize.c: Likewise.
+ * parse.y: Likewise.
+ * pt.c: Likewise.
+ * repo.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * spew.c: Likewise.
+ * tree.c: Likewise.
+
+ * lang-specs.h: Remove comment.
+
+ 2002-12-03 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (struct operator_name_info_t): Mark for GTY machinery.
+ (operator_name_info): Mark to be saved for PCH, specify size.
+ (assignment_operator_name_info): Likewise.
+
+ 2002-11-19 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (anon_cnt): Mark to be saved for PCH.
+
+ 2002-10-25 Geoffrey Keating <geoffk@apple.com>
+
+ * lex.c (init_reswords): Delete now-untrue comment.
+ Allocate ridpointers using GGC.
+
+ 2002-10-04 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (union lang_decl_u2): Add tags to all fields.
+
+ * g++spec.c (lang_specific_driver): Don't include standard
+ libraries in `added'.
+
+ 2002-08-27 Geoffrey Keating <geoffk@redhat.com>
+
+ * decl2.c (finish_file): Call c_common_write_pch.
+ * Make-lang.in (CXX_C_OBJS): Add c-pch.o.
+
+ 2002-08-17 Geoffrey Keating <geoffk@redhat.com>
+
+ * g++spec.c (lang_specific_driver): Treat .h files as C++ header
+ files when using g++.
+ * lang-specs.h: Handle compiling C++ header files.
+
+2003-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (start_decl): Only check DECL_THREAD_LOCAL for VAR_DECLs.
+
+2003-01-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (push_access_scope_real): Call push_to_top_level for
+ function in namespace scope.
+ (pop_access_scope): Call pop_from_top_level for function in
+ namespace scope.
+
+2003-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (start_decl): Don't set DECL_COMMON for __thread variables.
+
+2003-01-09 Christian Cornelssen <ccorn@cs.tu-berlin.de>
+
+ * Make-lang.in (c++.install-common, c++.install-man,
+ c++.uninstall): Prepend $(DESTDIR) to destination paths in
+ all (un)installation commands.
+ (c++.install-common): Rewrite $(LN) commands to support
+ DESTDIR with "ln" as well as with "ln -s".
+
+2003-01-08 Jason Merrill <jason@redhat.com>
+
+ * parser.c (cp_parser_primary_expression): See through explicitly
+ scoped ALIAS_DECLs, too.
+
+2003-01-08 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * decl.c: Remove some #if 0 code.
+
+ * decl.c: ANSIfy function declarations.
+
+2003-01-07 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_asm_definition): Correct handling of omitted
+ operands.
+
+2003-01-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/9030
+ * decl.c (make_typename_type): Check access only when tf_error.
+ (make_unbound_class_template): Likewise.
+ * pt.c (saved_access_scope): New variable.
+ (push_access_scope_real): New function.
+ (push_access_scope): Likewise.
+ (pop_access_scope): Likewise.
+ (tsubst_default_argument): Use them.
+ (instantiate_template): Likewise.
+ (regenerate_decl_from_template): Likewise.
+ (instantiate_decl): Likewise.
+ (get_mostly_instantiated_function_type): Likewise.
+
+2003-01-07 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * tree.c: Delete bogus #if 0 code.
+
+2003-01-07 Andreas Schwab <schwab@suse.de>
+
+ * class.c (layout_class_type): Don't use
+ PCC_BITFIELD_TYPE_MATTERS if not defined.
+
+2003-01-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9165
+ * decl2.c (build_cleanup): Mark the object as used.
+
+ * pt.c (retrieve_local_specialization): Revert 2003-01-05 change.
+ (hash_local_specialization): New function.
+ (register_local_specialization): Revert 2003-01-05 change.
+ (instantiate_decl): Use hash_local_specialization when creating
+ the local_specializations table.
+
+ * decl2.c (mark_used): Do not synthesize thunks.
+
+ * class.c (layout_class_type): Correct handling of unnamed
+ bitfields wider than their types.
+
+ PR c++/9189
+ * parser.c (cp_parser): Remove default_arg_types. Update
+ documentation for unparsed_functions_queues.
+ (cp_parser_late_parsing_default_args): Take a FUNCTION_DECL as the
+ parameter.
+ (cp_parser_new): Don't set parser->default_arg_types.
+ (cp_parser_function_definition): Adjust usage of
+ unparsed_funtions_queues.
+ (cp_parser_class_specifier): Don't mess with
+ parser->default_arg_types. Handle default argument processing in
+ a separate phase from function body processing.
+ (cp_parser_template_declaration_after_export): Adjust usage of
+ unparsed_functions_queues.
+ (cp_parser_late_parsing_for_member): Do not handle default
+ arguments.
+
+2003-01-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/9109
+ * parser.c (cp_parser_declarator_kind): New enum.
+ (cp_parser_declarator): Adjust.
+ (cp_parser_direct_declarator): Adjust. Allow for either named or
+ abstract declarator. Prefer abstract, if possible. Allow
+ parenthesized function name.
+ (cp_parser_condition): Adjust cp_parser_declarator call.
+ (cp_parser_explicit_instantiation): Likewise.
+ (cp_parser_init_declarator): Likewise.
+ (cp_parser_type_id): Likewise.
+ (cp_parser_function_definition): Likewise.
+ (cp_parser_member_declaration): Likewise.
+ (cp_parser_parameter_declaration): Use cp_parser_declarator to do
+ the tentative parsing.
+ (cp_parser_exception_declaration): Likewise.
+
+2003-01-05 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_template_parameter): Adjust call to
+ cp_parser_parameter_declaration.
+ (cp_parser_parameter_declaration_list): Likewise.
+ (cp_parser_parameter_declaration): Replace
+ greater_than_is_operator_p with template_parm_p parameter. Do not
+ cache tokens for template default arguments.
+
+ * pt.c (retrieve_local_specialization): Use htab_find, not
+ htab_find_with_hash.
+ (register_local_specialization): Use htab_find_slot, not
+ htab_find_slot_with_hash.
+ (instantiate_decl): Pass a hash function to htab_create.
+
+2003-01-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * parser.c (cp_parser_binary_expression,
+ cp_parser_multiplicative_expression,
+ cp_parser_additive_expression, cp_parser_shift_expression,
+ cp_parser_relational_expression, cp_parser_equality_expression,
+ cp_parser_and_expression, cp_parser_exclusive_or_expression,
+ cp_parser_inclusive_or_expression,
+ cp_parser_logical_and_expression, cp_parser_logical_or_expression,
+ cp_parser_binary_expression): Const-ify.
+
+2003-01-04 Mark Mitchell <mark@codesourcery.com>
+
+ * method.c (use_thunk): Disable access control while building the
+ body of the thunk.
+
+2003-01-03 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * cvt.c, decl.c, decl2.c: This is the C++ front end, not the C
+ front end.
+
+2003-01-03 Matt Austern <austern@apple.com>
+
+ * cp-tree.h (struct lang_type_class): add field for key method
+ (cp_global_trees): rename dynamic_classes to keyed_classes
+ (key_method): add definition
+ * class.c (finish_struct_1): compute class's key method, and add
+ the class to keyed_classes list if there is no key method.
+ * decl.c (finish_function): add class to keyed_classes list if we
+ see a definition of the class's key method.
+ * pt.c (instantiate_class_template): add template specialization
+ of a dynamic class to keyed_classes list.
+ * decl2.c (key_method): remove
+ (finish_file): iterate only through keyed_classes list when
+ deciding whether to emit vtables, remove class from its list after
+ we do the emission.
+
+2003-01-02 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_conditional_expr): Stabilize lvalues properly.
+ * cvt.c (ocp_convert): Don't build NOP_EXPRs of class type.
+ * tree.c (lvalue_p_1): Don't allow sloppy NOP_EXPRs as lvalues.
+ Don't allow CALL_EXPR or VA_ARG_EXPR, either.
+
+ * call.c (convert_like_real): Call decl_constant_value for an
+ IDENTITY_CONV even if there are no more conversions.
+
+ * cvt.c (build_up_reference): Don't push unnamed temps.
+
+ * decl2.c (do_namespace_alias): Namespace aliases are DECL_EXTERNAL.
+
+ * dump.c (cp_dump_tree): Don't try to dump class-specific fields
+ for a backend struct.
+
+ * except.c (wrap_cleanups_r, build_throw): Make
+ MUST_NOT_THROW_EXPRs void.
+ * init.c (expand_default_init): Update to handle MUST_NOT_THROW_EXPR.
+
+ * init.c (build_vec_delete_1): Pre-evaluate the base address.
+
+ * init.c (get_temp_regvar): Simplify logic.
+
+ * tree.c (cp_copy_res_decl_for_inlining): Only do debug tweaks if
+ our replacement is a decl.
+
+ * decl.c (cp_make_fname_decl): Push the decls inside the
+ outermost scope.
+
+2003-01-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/45, c++/3784
+ * tree.c (cp_tree_equal, TEMPLATE_PARM_INDEX): The types must be
+ the same too.
+
+2003-01-03 Graham Stott <graham.stott@btinternet.com>
+
+ * parser.c (struct cp_parser): Add access_checks_lists field
+ (cp_parser_simple_declaration): Use.
+ (cp_parser_init_declarator): Likewise.
+
+2003-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_declaration): Accept the __extension__
+ keyword before the declaration.
+
+ PR c++/2843
+ * parser.c (cp_parser_parameter_declaration): Allow attributes to
+ appear after the declarator.
+
+ * call.c (build_new_method_call): Fix typo in message format
+ string.
+
+2003-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_lexer_next_token_is): Declare it inline.
+ (cp_lexer_set_source_position_from_token): Likewise.
+ (cp_lexer_debugging_p): Likewise.
+ (cp_parser_parsing_tentatively): Likewise.
+ (cp_parser_nested_name_specifier_opt): Reduce the number of calls
+ to the cp_lexer_peek_token.
+
+ * parser.c (cp_parser_sizeof_operand): Do not evaluate the
+ expression.
+
+2003-01-02 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * cp/except.c, cp/expr.c, cp/friend.c, cp/g++spec.c,
+ cp/lang-options.h, cp/lang-specs.h, cp/lex.h, cp/ptree.c,
+ cp/repo.c: Fix copyright years.
+
+2003-01-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * lex.c: Remove superfluous include of cpplib.h.
+ (CONSTRAINT): Define without conditions.
+ (init_cp_pragma): Use c_register_pragma.
+
+2002-12-31 Neil Booth <neil@daikokuya.co.uk>
+
+ * .cvsignore: Remove.
+
+2002-12-31 Steven Bosscher <s.bosscher@student.tudelft.nl>
+
+ * call.c, class.c, cp-lang.c, cp-tree.h, cvt.c, dump.c, error.c,
+ except.c, expr.c friend.c, g++spec.c, init.c, lang-options.h,
+ lang-specs.h, lex.c, mangle.c, method.c, optimize.c, parser.c,
+ pt.c, ptree.c, repo.c, rtti.c, search.c, semantics.c, tree.c,
+ typeck.c, typeck2.c: Replace "GNU CC" with "GCC" in the
+ copyright header.
+ * lex.h: parse.y is dead, so don't mention it. Also replace the
+ copyright header with the default GNU copyright header.
+
+2002-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (LOOKUP_TEMPLATES_EXPECTED): Remove.
+ (lookup_name_namespace_only): Likewise.
+ (begin_only_namespace_names): Likewise.
+ (end_only_namespace_names): Likewise.
+ * decl.c (only_namespace_names): Remove.
+ (qualify_lookup): Do not check LOOKUP_TEMPLATES_EXPECTED.
+ (lookup_name_real): Do not check only_namespace_names.
+ (lookup_name_namespace_only): Remove.
+ (begin_only_namespace_names): Likewise.
+ (end_only_namespace_names): Likewise.
+ * parser.c (cp_parser_nested_name_specifier_opt): Handle erroneous
+ nested-name-specifiers more gracefully.
+ (cp_parser_class_or_namespace_name): Avoid looking up namespace
+ names when they cannot possibly appear.
+ (cp_parser_template_name): Adjust call to cp_parser_lookup_name.
+ (cp_parser_elaborated_type_specifier): Likewise.
+ (cp_parser_namespace_name): Only look for namespace names.
+ (cp_parser_lookup_name): Add is_namespace parameter.
+ (cp_parser_lookup_name_simple): Adjust call to
+ cp_parser_lookup_name.
+
+ * parser.c (cp_parser_dependent_type_p): Fix thinko.
+
+2002-12-31 Neil Booth <neil@daikokuya.co.uk>
+
+ * .cvsignore: Update.
+
+2002-12-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (modify_vtable_entry): Remove unused variable.
+ (get_vcall_index): Always expect a non-thunk.
+ (update_vtable_entry_for_fn): Combine covariant adjustments, when
+ overriding a thunk. Pass get_vcall_index a non-thunk.
+
+ * decl2.c (finish_file): Mark undefined inlines as extern.
+
+2002-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (RETURN_INIT): Remove.
+ * cp-tree.h (DECL_IN_MEMORY_P): Remove.
+ (scope_kind): Add sk_block, sk_try, sk_catch, sk_for.
+ (note_level_for_for): Remove.
+ (note_level_for_try): Likewise.
+ (note_level_for_catch): Likewise.
+ (finish_named_return_value): Likewise.
+ (do_pushlevel): Change prototype.
+ (pending_lang_change): Remove.
+ * decl.c (begin_scope): Handle sk_block, sk_try, sk_catch,
+ sk_for.
+ (note_level_for_for): Remove.
+ (note_level_for_try): Likewise.
+ (note_level_for_catch): Likewise.
+ (maybe_inject_for_scope_var): Remove use of DECL_IN_MEMORY_P.
+ * parser.c (cp_parser_context_free_list): Make it "deletable".
+ (cp_parser_template_argument): Remove misleading comment.
+ * pt.c (tsubst_expr): Remove RETURN_INIT code.
+ * semantics.c (genrtl_named_return_value): Remove.
+ (do_pushlevel): Take a scope kind as an argument.
+ (begin_if_stmt): Adjust.
+ (begin_while_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (finish_for_init_stmt): Likewise.
+ (begin_switch_stmt): Likewise.
+ (begin_handler): Likewise.
+ (begin_compound_stmt): Likewise.
+ (finish_named_return_value): Remove.
+ (cp_expand_stmt): Remove RETURN_INIT case.
+ * tree.c (cp_statement_code_p): Remove RETURN_INIT case.
+
+2002-12-31 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9112
+ * parser.c (cp_parser_direct_declarator): Handle erroneous
+ parenthesized declarators correctly.
+
+2002-12-31 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (pending_lang_change): Declare.
+
+2002-12-30 Mark Mitchell <mark@codesourcery.com>
+
+ * parser.c (cp_parser_context_free_list): New variable.
+ (cp_parser_context_new): Use it.
+ (cp_parser_error): Check return code from
+ cp_parser_simulate_error.
+ (cp_parser_simulate_error): Return a value.
+ (cp_parser_id_expression): Optimize common case.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_class_specifier): Adjust call to
+ cp_parser_late_parsing_default_args.
+ (cp_parser_lookup_name): Optimize common case.
+ (cp_parser_late_parsing_for_member): Adjust call to
+ cp_parser_late_parsing_default_args.
+ (cp_parser_late_parsing_default_args): Add scope parameter.
+ (cp_parser_require): Avoid creating the error message unless it's
+ needed.
+ (cp_parser_parse_definitely): Place free'd contexts on the free
+ list.
+
+ * parser.c (cp_parser_declaration_seq_opt): Handle pending_lang_change.
+
+2002-12-30 David Edelsohn <edelsohn@gnu.org>
+
+ * parser.c (cp_parser_parameter_declaration_clause): Treat system
+ header as extern "C" if NO_IMPLICIT_EXTERN_C undefined.
+
+2002-12-30 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * config-lang.in, Make-lang.in, operators.def, cp-tree.def:
+ GCC, not GNU CC.
+
+2002-12-30 Mark Mitchell <mark@codesourcery.com>
+
+ * parse.y: Remove.
+ * spew.c: Likewise.
+ * Make-lang.in (gt-cp-spew.h): Remove.
+ * cp-tree.h (do_pending_lang_change): Remove.
+ (do_identifier): Change prototype.
+ (finish_id_expr): Remove.
+ * decl.c (lookup_name_real): Remove yylex variable.
+ * decl2.c (build_expr_from_tree): Adjust call to do_identifier.
+ * lex.c (init_cpp_parse): Remove.
+ (reduce_cmp): Likewise.
+ (token_cmp): Likewise.
+ (yychar): Likewise.
+ (lastiddecl): Likewise.
+ (token_count): Likewise.
+ (reduce_count): Likewise.
+ (yyhook): Likewise.
+ (print_parse_statistics): Likewise.
+ (do_pending_lang_change): Likewise.
+ (do_identifier): Remove parsing parameter.
+ * lex.h (lastiddecl): Remove.
+ (looking_for_typename): Remove.
+ (looking_for_template): Likewise.
+ (pending_lang_change): Likewise.
+ (yylex): Likewise.
+ * semantics.c (finish_id_expr): Remove.
+
+ * decl.c (grokdeclarator): Diagnost "extern thread" and "static
+ thread" correctly.
+
+2002-12-30 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * decl.c, decl2.c, decl.h: GCC, not GNU CC. This is the C++ front
+ end, not the C front end.
+
+2002-12-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (THUNK_TARGET): New macro.
+ (THUNK_VIRTUAL_OFFSET): For result thunks it is always a binfo.
+ (finish_thunk): Remove offset parms.
+ * class.c (find_final_overrider): Look through thunks.
+ (get_vcall_index): Use THUNK_TARGET.
+ (update_vtable_entry_for_fn): Look through thunks. Set covariant
+ fixed offset here. Adjust finish_thunk call.
+ (build_vtbl_initializer): Adjust finish_thunk calls.
+ * mangle.c (mangle_call_offset): Remove superfluous if.
+ (mangle_thunk): Adjust.
+ * method.c (make_thunk): Adjust.
+ (finish_thunk): Adjust.
+ (thunk_adjust): Remove assert.
+ (use_thunk): Use THUNK_TARGET
+ * dump1.c (cp_dump_tree): Adjust thunk dumping.
+
+ PR c++/9054
+ * class.c (layout_class_type): Set TYPE_CONTEXT of type for base.
+ * dump.c (cp_dump_tree, RECORD_TYPE): Deal with type for base types.
+
+2002-12-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove traditional C constructs 4/n.
+ * decl2.c (grok_method_quals, warn_if_unknown_interface,
+ grok_x_components, cp_build_parm_decl, build_artificial_parm,
+ maybe_retrofit_in_chrg, grokclassfn, grok_array_decl,
+ delete_sanity, check_member_template, check_java_method,
+ check_classfn, finish_static_data_member_decl, grokfield,
+ grokbitfield, grokoptypename, grok_function_init,
+ cplus_decl_attributes, constructor_name, defer_fn,
+ build_anon_union_vars, finish_anon_union, coerce_new_type,
+ coerce_delete_type, comdat_linkage, maybe_make_one_only,
+ key_method, import_export_vtable, import_export_class,
+ output_vtable_inherit, import_export_decl, import_export_tinfo,
+ build_cleanup, get_guard, get_guard_bits, get_guard_cond,
+ set_guard, start_objects, finish_objects,
+ start_static_storage_duration_function,
+ finish_static_storage_duration_function, get_priority_info,
+ start_static_initialization_or_destruction,
+ finish_static_initialization_or_destruction,
+ do_static_initialization, do_static_destruction,
+ prune_vars_needing_no_initialization, write_out_vars,
+ reparse_decl_as_expr, finish_decl_parsing, namespace_ancestor,
+ add_using_namespace, merge_functions, ambiguous_decl,
+ lookup_using_namespace, lookup_using_namespace,
+ qualified_lookup_using_namespace, set_decl_namespace,
+ decl_namespace, current_decl_namespace, push_decl_namespace,
+ pop_decl_namespace, push_scope, pop_scope, add_function,
+ arg_assoc_namespace, arg_assoc_template_arg, arg_assoc,
+ lookup_arg_dependent, do_namespace_alias,
+ validate_nonmember_using_decl, do_nonmember_using_decl,
+ do_toplevel_using_decl, do_local_using_decl,
+ do_class_using_decl, do_using_directive, check_default_args,
+ mark_used, handle_class_head): Use C90 prototypings. Use booleans.
+ * parser.c (cp_parser_class_head): Use booleanss.
+ * decl.c (walk_globals, walk_vtables): Likewise.
+ * cp-tree.h (walk_globals_pred, walk_globals_fn, walk_vtables,
+ walk_globals): Change return type from 'int' to 'bool'.
+ * rtti.c (init_rtti_processing, build_headof, throw_bad_cast
+ throw_bad_typeid, get_tinfo_decl_dynamic, typeid_ok_p,
+ build_typeid, tinfo_name, get_tinfo_decl, get_tinfo_ptr,
+ get_typeid, ifnonnull, build_dynamic_cast_1, build_dynamic_cast,
+ qualifier_flags, tinfo_base_init, generic_initializer,
+ ptr_initializer, dfs_class_hint_mark, ptm_initializer,
+ dfs_class_hint_unmark, class_hint_flags, class_initializer,
+ typeinfo_in_lib_p, get_pseudo_ti_init, create_pseudo_type_info,
+ get_pseudo_ti_desc, create_tinfo_types, emit_support_tinfos,
+ unemitted_tinfo_decl_p, emit_tinfo_decl): Likewise.
+ * repo.c (repo_compile_flags, repo_template_declared,
+ repo_template_defined, repo_class_defined, repo_get_id,
+ repo_template_used, repo_vtable_used, repo_inline_used,
+ repo_tinfo_used, repo_template_instantiated, extract_string,
+ open_repo_file, afgets, init_repo, reopen_repo_file_for_write,
+ finish_repo): Likewise.
+ * ptree.c (cxx_print_decl, cxx_print_type, cxx_print_identifier,
+ cxx_print_xnode): Likewise..
+ * cp-lang.c (ok_to_generate_alias_set_for_type, cxx_get_alias_set,
+ cxx_warn_unused_global_decl, cp_expr_size): Likewise.
+ * cxxfilt.c (demangle_it, print_demangler_list, usage,
+ standard_symbol_characters, hp_symbol_characters, main, fatal):
+ Likewise.
+ (strip_underscore): Change type from 'int' to 'bool'.
+ (main): Use boolean constants.
+
+2002-12-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove traditional C constructs 3/n.
+ * cvt.c (cp_convert_to_pointer, convert_to_pointer_force,
+ build_up_reference, warn_ref_binding, convert_to_reference,
+ convert_from_reference, convert_lvalue, cp_convert, ocp_convert,
+ convert_to_void, convert, convert_force, build_type_conversion,
+ build_expr_type_conversion, type_promotes_to,
+ perform_qualification_conversions): Use C90 prototyping style.
+ * decl2.c (grok_array_decl): Use boolean constant.
+ (delete_sanity): Likewise.
+ * typeck.c (build_unary_op): Likewise.
+ * semantics.c (finish_switch_cond): Likewise.
+ * parser.c (cp_parser_direct_new_declarator): Likewise.
+ * init.c (build_new): Likewise.
+
+2002-12-27 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (po-generated): Remove parse.c.
+ (CXX_OBJS): Remove parse.o and spew.o. Add parser.o.
+ ($(srcdir)/cp/parse.h): Remove target.
+ ($(srcdir)/cp/parse.c): Likewise.
+ (gt-cp-parse.h): Likewise.
+ (gt-cp-parser.h): New target.
+ (c++.distclean): Do not remove parse.output.
+ (c++.maintainer-clean): Do not remove parse.c or parse.h.
+ (cp/spew.o): Remove target.
+ (cp/lex.o): Adjust dependencies.
+ (cp/pt.o): Likewise.
+ (cp/parse.o): Likewise.
+ (cp/TAGS): Do not mention parse.c.
+ (cp/parser.o): New target.
+ * NEWS: Mention the new parser.
+ * call.c (build_scoped_method_call): Simplify.
+ (build_method_call): Likewise.
+ (build_new_function_call): Adjust calls to add_function_candidate
+ and add_template_candidate.
+ (build_new_op): Improve handling of erroroneous operands.
+ (convert_default_arg): Remove circular argument processing.
+ (name_as_c_string): New function.
+ (build_new_method_call): Use it.
+ (perform_implicit_conversion): Use error_operand_p.
+ * class.c (finish_struct_anon): Use constructor_name_p.
+ (check_field_decls): Likewise.
+ (pop_nested_class): Use OVL_NEXT, not OVL_CHAIN.
+ (resolve_address_of_overloaded_function): Likewise.
+ (instantiate_type): Tweak pointer-to-member handling.
+ (get_primary_binfo): Remove incorrect assertion.
+ * config-lang.in (gtfiles): Add parser.c, remove parse.c.
+ * cp-tree.h (DEFARG_TOKENS): New macro.
+ (default_arg): New structure.
+ (cp_tree_node_structure_enum): Add TS_CP_DEFAULT_ARG.
+ (lang_tree_node): Add default_arg.
+ (cp_tree_index): Add CPTI_TYPE_INFO_REF_TYPE.
+ (type_info_ref_type): New macro.
+ (saved_scope): Make processing_explicit_instantiation a boolean.
+ (check_access): New field.
+ (unparsed_text): Remove.
+ (language_function): Remove unparsed_inlines.
+ (error_operand_p): New macro.
+ (lang_decl): Adjust pending_inline_info.
+ (DEFARG_POINTER): Remove.
+ (tag_types): Add typenames.
+ (lookup_ualified_name): Declare.
+ (lookup_name_real): Likewise.
+ (shadow_tag): Adjust prototype.
+ (get_scope_of_declarator): Declare it.
+ (process_next_inline): Remove it.
+ (check_for_missing_semicolon): Likewise.
+ (maybe_get_template_decl_from_type_decl): Declare it.
+ (finish_label_stmt): Adjust prototype.
+ (finish_non_static_data_meber): Declare it.
+ (finish_pseudo_destructor_call_expr): Rename to ...
+ (finish_pseudo_destructor_expr): ... this.
+ (finish_compound_literal): Declare it.
+ (begin_inline_definitions): Remove it.
+ (init_spew): Remove.
+ (peekyylex): Likewise.
+ (arbitrate_lookup): Likewise.
+ (frob_opname): Likewise.
+ (maybe_snarf_defarg): Likewise.
+ (add_defarg_fn): Likewise.
+ (do_pending_defargs): Likewise.
+ (done_pending_defargs): Likewise.
+ (unprocessed_defarg_fn): Likewise.
+ (replace_defarg): Likewise.
+ (end_input): Likewise.
+ (get_overloaded_fn): Likewise.
+ * cvt.c (convert_to_reference): Improve error handling.
+ * decl.c (lookup_name_real): Do not declare it static.
+ (maybe_push_to_top_level): Set check_access.
+ (identifier_type_value): Adjust call to lookup_name_real.
+ (lookup_qualified_name): New method.
+ (lookup_name_real): Remove special-case parsing code.
+ (lookup_name-nonclass): Adjust call to lookup_name_real.
+ (lookup_name_namespace_only): Likewise.
+ (lookup_name): Likewise.
+ (check_tag_decl): Return the type declared.
+ (shadow_tag): Likewise.
+ (register_dtor_fn): Tweak check_access.
+ (grokfndecl): Use constructor_name_p.
+ (get_scope_of_declarator): New function.
+ (grokdeclarator): Obscure tweaks for slightly different declarator
+ representations.
+ (start_method): Return error_mark_node to indicate failure.
+ (cp_tree_node_structure_enum): Use TS_CP_DEFAULT_ARG for DEFAULT_ARGs.
+ * decl2.c (constructor_name_full): Simplify.
+ (constructor_name): Use it.
+ (build_expr_from_tree): Adjust for changes to do new parser.
+ (push_scope): Improve robustness.
+ (validate_nonmember_using_decl): Process declarations, not names.
+ (do_class_using_decl): Likewise.
+ (handle_class_head): Do not mess with CLASSTYPE_DECLARED_CLASS
+ here.
+ * error.c (dump_expr): Handle IDENTIFIER_NODEs and BASELINKs.
+ * expr.c (cxx_expand_expr): Handle BASELINKs.
+ * init.c (member_init_ok_or_else): Issue more errors.
+ (build_offset_ref): Tweak handling of FUNCTION_DECLs.
+ * lex.c: Do not include parse.h.
+ (yypring): Do not declare.
+ (yylval): Likewise.
+ (make_reference_declarator): Remove error-generating code.
+ (rid_to_yy): Remove.
+ (cxx_init): Do not call init_spew.
+ (yypring): Remove.
+ (check_for_missing_semicolon): Remove.
+ * lex.h (got_scope): Remove.
+ (got_object): Remove.
+ * method.c (hack_identifier): Use finish_non_static_data_member.
+ (implicitly_declare_fn): Adjust use of constructor_name.
+ * parser.c: New file.
+ * pt.c (parse.h): Do not include it.
+ (maybe_get_template_decl_from_template): Do not declare it.
+ (finish_member_template_decl): Tweak.
+ (begin_explicit_instantiation): Adjust for
+ processing_explicit_instantiation being boolean.
+ (end_explicit_instantiation): Likewise.
+ (maybe_process_partial_specialization): Tighten specialization
+ test.
+ (retrieve_local_specialization): Adjust ue of hash table.
+ (eq_local_specializations): New function.
+ (register_local_specialization): Likewise.
+ (push_template_decl_real): Remove unnecessary test.
+ (maybe_get_template_decl_from_type_decl): Don't make it static.
+ (for_each_template_parm_r): Handle TYPEOF_TYPE.
+ (tsubst_copy): Use retrieive_local_specialization to handle
+ PARM_DECL. Adjust handling of CONST_DECLs. Handle BASELINKs.
+ Handle COMPONENT_REFs with pseudo-destructor-expressions.
+ Simplify handling of CALL_EXPR and METHOD_CALL_EXPR.
+ (tsubst_expr): Pass decls, not names, to do_local_using_decl.
+ (unify): Tweak handling of CONST_DECLs.
+ (regenerate_decl_from_template): Use push_nested_class.
+ (template_for_substitution): New funciton.
+ (instantiate_decl): Use it. Register parameters as local
+ specializations.
+ * rtti.c (init_rtti_processing): Set type_info_ref_type.
+ (build_typeid): Use it.
+ (get_typeid): Likeise.
+ * search.c (accessible_p): Use check_access, not
+ flag_access_control.
+ (adjust_result_of_qualified_name_lookup): Pay attention to the
+ context_class.
+ * semantics.c (finish_asm_stmt): Adjust error handling.
+ (finish_label_stmt): Return the statement.
+ (finish_non_static_data_member): New function.
+ (finish_class_expr): Handle BASELINKs.
+ (finish_call_expr): Handle PSEUDO_DTOR_EXPR.
+ (finish_object_call_expr): Simplify handling during templates.
+ (finish_pseudo_destructor_call_expr): Rename to ...
+ (finish_pseudo_dtor_expr): ... this.
+ (finish_compound_literal): New function.
+ (begin_inline_definitions): Remove.
+ (finish_sizeof): Remove special template handling.
+ * spew.c: Do not include parse.h.
+ * tree.c (get_overloaded_fn): Remove.
+ * typeck.c (build_class_member_access_expr): Handle
+ PSEUDO_DTOR_EXPR. Adjust handling of static member functions.
+ (lookup_destructor): New function.
+ (finish_class_member_access_expr): Use it.
+ (convert_arguments): Simplify.
+ (build_unary_op): Handle BASELINKs.
+
+2002-12-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4803
+ * decl2.c (mark_used): Defer inline functions.
+ (finish_file): Merge deferred_fns loops. Check all used
+ inline functions have a definition.
+ * method.c (make_thunk): Thunks are not inline.
+
+ PR c++/5116, c++/764
+ * call.c (build_new_op): Make sure template class operands are
+ instantiated.
+
+2002-12-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR C++/7964
+ * cp-tree.h (resolve_scoped_fn_name): Prototype.
+ * call.c (resolve_scoped_fn_name): New function. Deal with
+ more template expansion. Broken out of ...
+ * parse.y (parse_finish_call_expr): ... here. Call it.
+ * decl2.c (build_expr_from_tree, CALL_EXPR): Use
+ resolve_scoped_fn_name and build_call_from_tree.
+
+ PR c++/9053
+ * decl.c (duplicate_decls): Templates may be disambiguated by
+ return type.
+
+ PR c++/8702
+ * decl2.c (check_classfn): Use lookup_fnfield_1. List all
+ conversion operators on failure.
+
+2002-12-23 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove traditional C constructs 2/n.
+ * call.c (tourney, build_field_call, equal_functions, joust,
+ compare_ics, build_over_call, build_java_interface_fn_ref,
+ convert_like_real, op_error, build_object_call, resolve_args,
+ build_vfield_ref, check_dtor_name, build_scoped_method_call,
+ build_addr_func, build_call, build_method_call, null_ptr_cst_p,
+ sufficient_parms_p, build_conv, non_reference, strip_top_quals,
+ standard_conversion, reference_related_p,
+ reference_compatible_p, convert_class_to_reference,
+ direct_reference_binding, reference_binding,
+ ,implicit_conversion, is_complete, promoted_arithmetic_type_p,
+ add_template_conv_candidate, any_viable, any_strictly_viable,
+ build_this, splice_viable, print_z_candidates,
+ build_user_type_conversion, build_new_function_call,
+ conditional_conversion, build_conditional_expr, build_new_op,
+ build_op_delete_call, enforce_access, call_builtin_trap,
+ convert_arg_to_ellipsis, build_x_va_arg, cxx_type_promotes_to,
+ convert_default_arg, type_passed_as, convert_for_arg_passing,
+ in_charge_arg_for_name, is_properly_derived_from,
+ maybe_handle_implicit_object, maybe_handle_ref_bind,
+ source_type, add_warning, can_convert, can_convert_arg,
+ perform_implicit_conversion, can_convert_arg_bad,
+ initialize_reference, add_conv_candidate,
+ add_template_candidate_real, add_template_candidate): Ansify.
+
+2002-12-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/8572
+ * cp-tree.h (grokoptypename): Add SCOPE parameter.
+ * decl2.c (grokoptypename): Add SCOPE parameter. tsubst the type
+ if in a template scope.
+ * parse.y (unoperator): Return the scope.
+ (operator_name): Adjust grokoptypename call.
+
+2002-12-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.h (make_unbound_class_template): Use tsubst_flags_t.
+ * decl.c (make_unbound_class_template): Adjust. Check for tf_error.
+ * pt.c (tsubst) [OFFSET_TYPE]: Check for tf_error.
+
+2002-12-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Fix a typo.
+ * class.c: Fix comment typos.
+ * cp-tree.h: Likewise.
+
+2002-12-18 Jason Merrill <jason@redhat.com>
+
+ Handle anonymous unions at the tree level.
+ C++ ABI change: Mangle anonymous unions using the name of their
+ first named field (by depth-first search). Should not cause
+ binary compatibility problems, though, as the compiler previously
+ didn't emit anything for affected unions.
+ * cp-tree.def (ALIAS_DECL): New tree code.
+ * decl2.c (build_anon_union_vars): Build ALIAS_DECLs. Return the
+ first field, not the largest.
+ (finish_anon_union): Don't mess with RTL. Do set DECL_ASSEMBLER_NAME,
+ push the decl, and write it out at namespace scope.
+ * decl.c (lookup_name_real): See through an ALIAS_DECL.
+ (pushdecl): Add namespace bindings for ALIAS_DECLs.
+ * rtti.c (unemitted_tinfo_decl_p): Don't try to look at the name
+ of a decl which doesn't have one.
+ * typeck.c (build_class_member_access_expr): Don't recurse if
+ we already have the type we want.
+
+2002-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8099
+ * friend.c (make_friend_class): Allow partial specialization
+ when declaration is not a template friend.
+
+2002-12-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/3663
+ * pt.c (lookup_template_class): Copy TREE_PRIVATE and
+ TREE_PROTECTED to created decl nodes.
+
+2002-12-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_base_field): Do not set DECL_PACKED on the
+ FIELD_DECL.
+
+2002-12-18 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cp-tree.h (struct tree_srcloc): Use location_t.
+ (SOURCE_LOCUS): New.
+ (SRCLOC_FILE, SRCLOC_LINE): Adjust.
+
+2002-12-17 Jason Merrill <jason@redhat.com>
+
+ * decl.c (finish_function): Also complain about no return in
+ templates.
+ * semantics.c (finish_return_stmt): Also call check_return_expr in
+ templates.
+ * typeck.c (check_return_expr): In a template, just remember that we
+ saw a return.
+
+2002-12-16 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Don't change the type
+ of the CALL_EXPR.
+
+ * semantics.c (do_pushlevel): Call pushlevel after adding the
+ SCOPE_STMT.
+ (do_poplevel): Call poplevel before adding the SCOPE_STMT.
+ * parse.y (function_body): Go back to using compstmt.
+ * decl.c (pushdecl): Skip another level to get to the parms level.
+
+ * call.c (build_new_method_call): Use is_dummy_object to determine
+ whether or not to evaluate the object parameter to a static member
+ function.
+
+2002-12-14 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Also prepend the
+ return slot for normal functions. Set CALL_EXPR_HAS_RETURN_SLOT_ADDR.
+ * tree.c (build_cplus_new): If the type isn't TREE_ADDRESSABLE,
+ don't bother with an AGGR_INIT_EXPR.
+ (cp_copy_res_decl_for_inlining): If the type isn't TREE_ADDRESSABLE,
+ just generate a new decl normally. Take return slot parm.
+ * cp-tree.h: Adjust prototype.
+
+2002-12-13 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR C++/8031
+ * cvt.c (convert_to_pointer_force): Don't try comparing against
+ erronous type.
+
+2002-12-13 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h: Have the multiple-include guards around
+ the entire file.
+
+2002-12-10 David Edelsohn <edelsohn@gnu.org>
+
+ * cp/spew.c (feed_input): Change limit to last_pos and pos to cur_pos
+ for SPEW_DEBUG.
+ (snarf_method): Same.
+ (snarf_defarg): Same.
+
+2002-12-10 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8372
+ * pt.c (tsubst_copy): Handle destructor names more correctly.
+
+2002-12-10 Matt Austern <austern@apple.com>
+
+ * cp-tree.h: get rid of needs_virtual_reinit bit.
+
+2002-12-09 Mark Mitchell <mark@codesourcery.com>
+
+ * NEWS: Document removal of in-class initialization extension for
+ static data members of non-arithmetic, non-enumeration type.
+ * decl.c (check_static_variable_definition): Do not allow that
+ extension.
+ * decl2.c (grokfield): Do not call digest_init when processing
+ templates.
+
+2002-12-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * error.c (dump_expr): Fix format specifier warning.
+
+2002-12-04 Geoffrey Keating <geoffk@apple.com>
+
+ * class.c (finish_struct_1): Correct comment.
+ * cp-tree.c (DECL_SORTED_FIELDS): Likewise.
+
+2002-12-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PR C++/8799
+ * error.c (dump_expr): Don't ever try to dump a non-existent
+ expression.
+
+2002-12-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ Implement covariant returns.
+ * cp-tree.h (IS_AGGR_TYPE_2): Remove.
+ (struct lang_decl_flags): Add this_thunk_p flag.
+ Rename vcall_offset to virtual_offset.
+ (struct lang_decl): Rename delta to fixed_offset.
+ (DECL_THIS_THUNK_P, DECL_RESULT_THUNK_P): New #defines.
+ (SET_DECL_THUNK_P): Add THIS_ADJUSTING arg.
+ (THUNK_DELTA, THUNK_VCALL_OFFSET): Rename to ...
+ (THUNK_FIXED_OFFSET, THUNK_VIRTUAL_OFFSET): ... here.
+ (make_thunk): Add this_adjusting arg.
+ (finish_thunk): Declare.
+ (mangle_thunk): Add this_adjusting arg.
+ * class.c (get_vcall_index): Use base function for lookup.
+ (update_vtable_entry_for_fn): Generate covariant thunk.
+ (finish_struct_1): Set DECL_VINDEX to NULL for thunks.
+ (build_vtbl_initializer): Use base function for lookup.
+ Finish covariant thunk here. Adjust thunk generation.
+ * dump.c (cp_dump_tree): Simplify DECL_GLOBAL_[CD]TOR_P handling.
+ Adjust thunk dumping.
+ * mangle.c (mangle_call_offset): New function.
+ (mangle_thunk): Adjust for covariant thunks.
+ * method.c (make_thunk): Adjust. Do not set name here.
+ (finish_thunk): New function. Set name here.
+ (use_thunk): Generate covariant thunks too.
+ (thunk_adjust): New function.
+ * search.c (covariant_return_p): Remove. Fold into ...
+ (check_final_overrider): ... here. Simplify.
+ * semantics.c (emit_associated_thunks): Walk covariant thunk lists.
+
+2002-12-03 Jason Merrill <jason@redhat.com>
+
+ PR c++/8674
+ * call.c (build_over_call): Check specifically for TARGET_EXPR
+ when eliding.
+
+ PR c++/8461, c++/8625
+ * call.c (convert_for_arg_passing): Don't mess with error_mark_node.
+ (cp_convert_parm_for_inlining): Remove.
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
+ Remove.
+ * cp-tree.h (ADDR_IS_INVISIREF): Remove.
+ * except.c (stabilize_throw_expr): Remove ADDR_IS_INVISIREF code.
+
+ * call.c (build_user_type_conversion_1): Don't set ICS_BAD_FLAG on
+ an ambiguous conversion.
+
+2002-12-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8688
+ * decl.c (reshape_init): Handle erroneous initializers.
+
+2002-12-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8720
+ * spew.c (remove_last_token): Make sure that last_chunk is set
+ correctly.
+
+ PR c++/8615
+ * error.c (dump_expr): Handle character constants with
+ TREE_OVERFLOW set.
+
+2002-12-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ DR 180
+ * decl.c (grokdeclarator): Require class-key for all friend class.
+ Output the correct type and context in the error message.
+
+2002-12-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5919
+ * pt.c (unify): Use variably_modified_type_p to test validity of
+ template argument types.
+
+ PR c++/8727
+ * cp-tree.h (lang_type_class): Add typeinfo_var.
+ (CLASSTYPE_TYPEINFO_VAR): New macro.
+ * rtti.c (get_tinfo_decl): Use it.
+
+ PR c++/8663
+ * init.c (expand_member_init): Always get the main variant of a
+ base class.
+
+2002-12-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8332
+ PR c++/8493
+ * decl.c (cxx_init_decl_processing): Use size_type_node, not
+ c_size_type_node.
+ * decl2.c (coerce_new_type): Likewise.
+ * except.c (do_allocate_exception): Likewise.
+
+2002-11-30 Zack Weinberg <zack@codesourcery.com>
+
+ * call.c, class.c, cp-lang.c, cvt.c, cxxfilt.c, decl.c, decl2.c,
+ dump.c, error.c, except.c, expr.c, friend.c, g++spec.c, init.c,
+ lex.c, mangle.c, method.c, optimize.c, parse.y, pt.c, ptree.c,
+ repo.c, rtti.c, search.c, semantics.c, spew.c, tree.c, typeck.c,
+ typeck2.c: Include coretypes.h and tm.h.
+ * Make-lang.in: Update dependencies.
+
+2002-11-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8227
+ * decl.c (layout_var_decl): Deal gracefully with erroneous types.
+ (check_initializer): Validate the type of the initialized
+ variable, even if the initializer is absent.
+ * typeck.c (cp_type_quals): Deal gracefully with erroneous types.
+
+ PR c++/8214
+ * typeck.c (convert_for_assignment): Do not use
+ decl_constant_value on the operand.
+
+ PR c++/8511
+ * pt.c (instantiate_decl): Handle template friends defined outside
+ of the class correctly.
+
+2002-11-29 Joe Buck <jbuck@synopsys.com>
+
+ * parse.y (class_head_defn): Set CLASSTYPE_DECLARED_CLASS for
+ anonymous structs.
+
+2002-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (walk_subobject_offsets): Recur on binfos as well as on
+ types.
+ (layout_nonempty_base_or_field): Pass it a binfo when processing a
+ base class.
+ (layout_empty_base): Likewise.
+ (build_base_field): Likewise.
+
+2002-11-27 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_base_field): Make sure we get the canonical base
+ when descending through primary bases.
+
+2002-11-26 Geoffrey Keating <geoffk@apple.com>
+
+ * decl.c (check_initializer): Don't error on initialisation of
+ a scalar with a brace-enclosed expression.
+
+2002-11-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (DECL_LANG_FLAG_4): Document more uses.
+ (template_parms_equal): Remove prototype.
+ * typeck.c (buuld_indirect_ref): Reformat.
+
+2002-11-25 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_vec_init): Use a FOR_STMT instead of an IF_STMT
+ and a DO_STMT.
+
+2002-11-25 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (cp_build_qualified_type_real): Correct handling of
+ array types.
+ * class.c (walk_subobject_offsets): Fix thinko.
+ (build_base_field): Record offsets of empty bases in primary
+ virtual bases.
+ (layout_class_type): Record offsets of empty bases in fields.
+
+ * search.c (is_subobject_of_p_1): Fix thinko.
+ (lookup_field_queue_p): Likewise.
+
+2002-11-24 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Reuse tail padding when laying out
+ virtual bases.
+
+2002-11-22 Mark Mitchell <mark@codesourcery.com>
+
+ * rtti.c (qualifier_flags): Fix thinko.
+
+2002-11-21 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Remove traditional C constructs 1/n.
+ * cp-tree.h (init_method, set_mangled_name_for_decl,
+ build_opfncall, hack_identifier, make_thunk, use_thunk,
+ synthesize_method, implicitly_declare_fn,
+ skip_artificial_parms_for, optimize_function, calls_setjmp_p,
+ maybe_clone_body): Remove use of PARAMS.
+
+ * method.c (do_build_assign_ref, do_build_copy_constructor,
+ synthesize_exception_spec, locate_dtor, locate_ctor, locate_copy):
+ Likewise.
+ (synthesize_method): Use 'bool' type and constants instead of
+ 'int'.
+ (locate_copy): Likewise.
+ (implicitly_declare_fn): Likewise.
+
+ * optimize.c (calls_setjmp_r, update_cloned_parm, dump_function):
+ Remove old-style declaration.
+ (maybe_clone_body): Use 'bool' type and constants.
+
+2002-11-21 Glen Nakamura <glen@imodulo.com>
+
+ PR c++/8342
+ * typeck.c (get_member_function_from_ptrfunc): Make sure that a
+ SAVE_EXPR for instance_ptr doesn't get evaluated first inside one
+ of the branches of a COND_EXPR.
+
+2002-11-19 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (for_each_template_parm): Free allocated memory.
+ * search.c (is_subobject_of_p_1): New function.
+ (is_subobject_of_p): Avoid walking virtual bases multiple times.
+
+2002-11-19 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * g++spec.c (lang_specific_spec_functions): New.
+
+2002-11-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * class.c: Likewise.
+ * decl2.c: Likewise.
+
+2002-11-14 Zack Weinberg <zack@codesourcery.com>
+
+ * search.c (dfs_push_decls): Do not try to reorder elements
+ 3..n of method_vec if method_vec has only two elements.
+ Reverse order of two tests to avoid accessing unallocated
+ memory.
+
+2002-11-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (dfs_find_final_overrider): Adjust so that the most
+ derived object is a binfo, rather than a class type.
+ (find_final_overrider): Likewise.
+ (add_vcall_offset_vtbl_entries_1): Simplify accordingly.
+ (add_vcall_offset): Likewise.
+
+2002-11-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/8389
+ * pt.c (instantiate_template): Push class scope for member
+ functions.
+ (get_mostly_instantiated_function_type): Likewise. Don't call
+ tsubst on context. Remove CONTEXTP and TPARMSP parameters.
+ * cp-tree.h (get_mostly_instantiated_function_type): Adjust.
+ * mangle.c (write_encoding, write_unqualified_name): Adjust.
+
+2002-11-07 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_vcall_offset_vtbl_entries_1): Correct ordering of
+ vcall offfsets. Split out ...
+ (add_vcall_offset): ... new function.
+
+ PR c++/8338
+ * pt.c (for_each_template_parm): Add htab parameter.
+ (process_partial_specialization): Adjust call.
+ (push_template_decl_real): Likewise.
+ (pair_fn_data): Add visited.
+ (for_each_template_parm_r): Avoid walking duplicates more than
+ once.
+ (uses_template_parms): Adjust call to for_each_template_parm.
+
+2002-11-07 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_implicitly_declared_members): Put implicitly
+ declared functions at the end of TYPE_METHODs when -fabi-version
+ is at least 2.
+
+2002-11-05 Geoffrey Keating <geoffk@apple.com>
+
+ * decl2.c (finish_file): Correct spelling.
+
+2002-11-03 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_special_member_call): Do not try to lookup VTTs by
+ name.
+ * class.c (vtbl_init_data): Add generate_vcall_entries.
+ (get_vtable_decl): Do not look up virtual tables by name.
+ (copy_virtuals): Do not use BV_USE_VCALL_INDEX_P.
+ (set_primary_base): Do not set CLASSTYPE_RTTI.
+ (determine_primary_base): Likewise.
+ (get_matching_virtual): Remove.
+ (get_vcall_index): New function.
+ (update_vtable_entry_for_fn): Do not try to use virtual thunks
+ when they are not required. Assign vcall indices at this point.
+ (finish_struct_1): Do not set CLASSTYPE_NEEDS_VIRTUAL_REINIT.
+ Do update dynamic_classes.
+ (build_vtt): Do not add VTTs to the symbol table.
+ (build_ctor_vtbl_group): Likewise.
+ (build_vtbl_initializer): Simplify handling of vcall indices.
+ (build_vcall_offset_vtbl_entries): Pretend to build vcall offsets
+ for the most derived class.
+ (add_vcall_offset_vtbl_entries_1): But do not actually add them to
+ the vtable.
+ * cp-tree.h (dynamic_classes): New macro.
+ (lang_type_class): Remove rtti. Add vtables. Add vcall_indices.
+ (CLASSTYPE_RTTI): Remove.
+ (CLASSTYPE_NEEDS_VIRTUAL_REINIT): Remove.
+ (CLASSTYPE_VCALL_INDICES): New macro.
+ (CLASSTYPE_VTABLES): Likewise.
+ (BV_USE_VCALL_INDEX_P): Remove.
+ (build_vtable_path): Remove.
+ * decl2.c (finish_vtable_vardecl): Remove.
+ (key_method): Remove #if 0'd code.
+ (finish_vtable_vardecl): Rename to ...
+ (maybe_emit_vtables): ... this.
+ (finish_file): Use it.
+ * search.c (look_for_overrides_here): Update comment.
+
+2002-11-01 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/7353 redux
+ * decl2.c (grokfield): Reject TYPE_DECLs with initializers.
+
+2002-10-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/8186
+ * cp-tree.h (ADDR_IS_INVISIREF): New macro.
+ * call.c (convert_for_arg_passing): Set it.
+ * except.c (stabilize_throw_expr): Recurse for such an arg.
+
+2002-10-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Remove init_priority.
+ (lang_decl): Add delta.
+ (GLOBAL_INIT_PRIORITY): Remove.
+ (THUNK_DELTA): Revise definition.
+ * decl2.c (start_objects): Don't set GLOBAL_INIT_PRIORITY.
+ * dump.c (cp_dump_tree): Don't dump it.
+
+2002-10-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8160
+ * typeck2.c (process_init_constructor): Call complete_array_type.
+
+ PR c++/8149
+ * decl.c (make_typename_type): Issue errors about invalid results.
+
+2002-10-30 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ Core issue 287, PR c++/7639
+ * cp-tree.h (lang_type_class): Add decl_list field.
+ (CLASSTYPE_DECL_LIST): New macro.
+ (maybe_add_class_template_decl_list): Add declaration.
+ * class.c (duplicate_tag_error): Initialize CLASSTYPE_DECL_LIST.
+ (unreverse_member_declarations): Reverse CLASSTYPE_DECL_LIST.
+ (maybe_add_class_template_decl_list): New function.
+ (add_implicitly_declared_members): Use it.
+ * decl.c (maybe_process_template_type_declaration): Likewise.
+ (pushtag): Likewise.
+ * friend.c (add_friend): Likewise.
+ (make_friend_class): Likewise.
+ * semantics.c (finish_member_declaration): Likewise.
+ (begin_class_definition): Initialize CLASSTYPE_DECL_LIST.
+ * pt.c (instantiate_class_template): Use CLASSTYPE_DECL_LIST
+ to process members and friends in the order of declaration.
+
+2002-10-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8287
+ * decl.c (finish_destructor_body): Create the label to jump to
+ when returning from a destructor here.
+ (finish_function_body): Rather than here.
+
+2002-10-25 Zack Weinberg <zack@codesourcery.com>
+
+ PR c++/7266
+ * decl.c (grokdeclarator): Check that TREE_OPERAND 0 of a
+ SCOPE_REF is not null before dereferencing it.
+
+2002-10-25 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_over_call): Use DECL_CONTEXT, not
+ DECL_VIRTUAL_CONTEXT.
+ * class.c (modify_vtable_entry): Don't mess with
+ DECL_VIRTUAL_CONTEXT.
+ (set_vindex): Remove.
+ (set_primary_base): Remove vfuns_p parameter.
+ (determine_primary_base): Likewise.
+ (modify_all_vtables): Likewise.
+ (layout_class_type): Likewise. Adjust calls to other functions
+ accordingly.
+ (finish_struct_1): Adjust calls to modified functions. Set
+ DECL_VINDEX here.
+ * cp-tree.h (lang_type_class): Remove vsize.
+ (CLASSTYPE_VSIZE): Remove.
+ (lang_decl): Remove thunks.
+ (DECL_THUNKS): Adjust.
+ (DECL_VIRTUAL_CONTEXT): Remove.
+ (duplicate_decls): Don't copy it.
+ * pt.c (build_template_decl): Don't set it.
+ (tsubst_decl): Likewise.
+ * typeck.c (expand_ptrmemfunc_cst): Don't use it.
+
+ * class.c (build_vtbl_initializer): Don't use build_vtable_entry.
+ (build_vtable_entry): Remove.
+ * cp-tree.h (BINFO_VIRTUALS): Expand documentation.
+ (lang_decl): Add thunks.
+ (DECL_THUNKS): New macro.
+ * decl.c (duplicate_decls): Copy it.
+ * method.c (make_thunk): Simplify, and add thunks to DECL_THUNKS.
+ * semantics.c (emit_associated_thunks): Simplify.
+
+2002-10-24 David Edelsohn <edelsohn@gnu.org>
+
+ PR c++/7228
+ * cp-tree.h (CLASSTYPE_READONLY_FIELDS_NEED_INIT): Check that
+ lang_type structure exists before accessing field.
+ (SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT): New macro.
+ (CLASSTYPE_REF_FIELDS_NEED_INIT): Similar.
+ (SET_CLASSTYPE_REF_FIELDS_NEED_INIT): New macro.
+ * class.c (check_field_decls): Use new macros.
+ * typeck2.c (process_init_constructor): Remove redundant check for
+ existence of lang_type structure.
+
+2002-10-24 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (end_of_base): New method.
+ (end_of_class): Use it. Check indirect virtual bases.
+
+ * class.c (check_field_decls): Fix typo.
+
+2002-10-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8067
+ * decl.c (maybe_inject_for_scope_var): Ignore __FUNCTION__ and
+ related variables.
+
+ PR c++/7679
+ * spew.c (next_token): Do not return an endless stream of
+ END_OF_SAVED_INPUT tokens.
+ (snarf_method): Add three END_OF_SAVED_INPUT tokens to the end of
+ the cached token stream.
+ (snarf_defarg): Likewise.
+
+2002-10-23 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-lang.c (cp_var_mod_type_p): New: C++ hook for
+ variably_modified_type_p.
+ * cp-tree.h: Remove prototype of variably_modified_type_p.
+ * tree.c (variably_modified_type_p): Remove; now implemented
+ in language-independent code.
+
+2002-10-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6579
+ * spew.c (snarf_parenthesized_expression): New function.
+ (snarf_block): Use it.
+
+2002-10-22 Richard Henderson <rth@redhat.com>
+
+ * method.c (use_thunk): Always compute vcall_value; assert that
+ it is not zero. Use can_output_mi_thunk; use output_mi_thunk
+ for vcall thunks as well.
+
+2002-10-21 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (empty_base_at_nonzero_offset_p): New function.
+ (layout_nonempty_base_or_field): Do not check for conflicts when
+ laying out a virtual base using the GCC 3.2 ABI.
+ (build_base_field): Correct checking for presence of empty classes
+ at nonzero offsets when clearing CLASSTYPE_NEARLY_EMPTY_P.
+
+ * class.c (include_empty_classes): Use normalize_rli.
+ (layout_class_type): Likewise.
+
+ * decl.c (reshape_init): Tweak handling of character arrays.
+
+ PR c++/8218
+ * cp-tree.h (lang_type_class): Add contains_empty_class_p.
+ (CLASSTYPE_CONTAINS_EMPTY_CLASS_P): New macro.
+ * class.c (check_bases): Update CLASSTYPE_CONTAINS_EMPTY_CLASS_P.
+ (check_field_decls): Likewise.
+ (layout_class_type): Likewise.
+ (finish_struct_1): Initialize it.
+ (walk_subobject_offsets): Use it to prune searches.
+
+2002-10-20 Mark Mitchell <mark@codesourcery.com>
+
+ * method.c (use_thunk): Compute the vcall index as a HOST_WIDE_INT.
+ * optimize.c (optimize_function): Replace ASM_OUTPUT_MI_THUNK with
+ TARGET_ASM_OUTPUT_MI_THUNK in comments.
+
+2002-10-18 Zack Weinberg <zack@codesourcery.com>
+
+ * decl.c (start_decl): Point users of the old initialized-
+ typedef extension at __typeof__.
+
+2002-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (method.o): Depend on TARGET_H.
+ * method.c (target.h): Include it.
+ (use_thunk): Use target hooks. Use vcall thunks, if available.
+
+2002-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (base_derived_from): Make sure return value is a bool.
+
+2002-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (find_final_overrider_data_s): Remove overriding_fn and
+ overriding_base.
+ (dfs_base_derived_from): New function.
+ (base_derived_from): Likewise.
+ (dfs_find_final_overrider): Use base_derived_from.
+ (find_final_overrider): Adjust.
+
+2002-10-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/8080
+ * semantics.c (finish_for_cond, finish_while_cond): Don't mess
+ with condition decls in a template.
+
+2002-10-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (add_method): Compare template parms too.
+
+2002-10-17 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7584
+ * class.c (handle_using_decl): Allow the declaration used to be
+ from an ambiguous base.
+
+ * pt.c (convert_template_argument): Revert this change:
+ 2002-10-16 Mark Mitchell <mark@codesourcery.com>
+ * pt.c (convert_template_argument): Do not fold non-type
+ template rguments when inside a template.
+
+ * init.c (expand_default_init): Handle brace-enclosed initializers
+ correctly.
+
+2002-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_expression): Correct handling of enumeration
+ constants.
+ (write_template_arg): Likewise.
+ * pt.c (convert_template_argument): Do not fold non-type template
+ arguments when inside a template.
+
+ PR c++/7478
+ * cvt.c (convert_to_reference): Allow references as the incoming
+ type.
+
+2002-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7524
+ * method.c (do_build_assign_ref): Use cp_build_qualified_type, not
+ build_qualified_type.
+
+2002-10-15 Richard Henderson <rth@redhat.com>
+
+ * error.c (dump_expr): Use real_to_decimal directly, and with
+ the new arguments.
+
+2002-10-15 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (reshape_init): Fix typo.
+
+ * cp-tree.h (operator_name_info_t): Add arity.
+ * lex.c (init_operators): Initialize it.
+ * mangle.c (write_conversion_operator_name): New function.
+ (write_unqualified_name): Use it.
+ (write_template_args): Accept template arguments as a TREE_LIST.
+ (write_expression): Adjust handling of qualified names to match
+ specification.
+
+2002-10-15 Jason Merrill <jason@redhat.com>
+
+ * call.c (call_builtin_trap): New fn.
+ (convert_arg_to_ellipsis): Use it. Downgrade error to warning.
+ (build_call): Don't set current_function_returns_abnormally outside
+ a function.
+
+2002-10-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (check_field_decls): Remove empty_p parameter. Instead,
+ clear CLASSTYPE_EMPTY_P.
+ (build_base_field): Likewise.
+ (build_base_fields): Likewise.
+ (check_bases_and_members): Likewise.
+ (create_vtbl_ptr): Likewise.
+ (layout_class_type): Likewise. Ensure that empty classes have
+ size zero when used as base classes in the 3.2 ABI.
+ (finish_struct_1): Initialize CLASSTYPE_EMPTY_P and
+ CLASSTYPE_NEARLY_EMPTY_P. Adjust calls to avoid passing empty_p
+ parameter.
+ (is_empty_class): Correct definition when using post-3.2 ABI.
+ * cp-tree.h (lang_type_class): Add empty_p.
+ (CLASSTYPE_EMPTY_P): New macro.
+
+2002-10-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (build_delete): Do not apply save_expr for arrays.
+ (build_vec_delete): Likewise.
+
+2002-10-14 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (layout_var_decl): Call layout_decl even for variables
+ whose type is an array with unspecified bounds.
+
+ PR c++/7176
+ * lex.c (do_identifier): Add another option for the parsing
+ parameter.
+ * parse.y (do_id): Use it.
+
+2002-10-11 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ PRs C++/6803, C++/7721 and C++/7803
+ * decl.c (grokdeclarator): Gracefully handle template-name as
+ decl-specifier.
+
+2002-10-11 Jason Molenda <jmolenda@apple.com>
+
+ * init.c (build_field_list): Provide uses_unions_p with a default
+ value.
+
+2002-10-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5661
+ * cp-tree.h (variably_modified_type_p): New function.
+ (grokdeclarator) Tighten check for variably modified types as
+ fields.
+ * pt.c (convert_template_argument): Do not allow variably modified
+ types as template arguments.
+ * tree.c (variably_modified_type_p): New function.
+
+ * NEWS: Document removal of "new X = ..." extension.
+ * class.c (initialize_array): Set TREE_HAS_CONSTRUCTOR on
+ brace-enclosed initializers.
+ * cp-tree.h (CP_AGGREGATE_TYPE_P): New macro.
+ (initialize_local_var): Remove declaration.
+ (expand_static_init): Likewise.
+ * decl.c (next_initializable_field): New function.
+ (reshape_init): Likewise.
+ (check_initializer): Use them. Build dynamic initializer for
+ aggregates here too.
+ (initialize_local_var): Simplify, and incorporate cleanup
+ insertion code as well.
+ (destroy_local_var): Remove.
+ (cp_finish_decl): Tidy.
+ (expand_static_init): Fold checks for whether or not a variable
+ needs initialization into this function. Simplify.
+ * decl2.c (do_static_initialization): Simplify.
+ * init.c (build_init): Do not set TREE_SIDE_EFFECTS when it will
+ be done for us automatically.
+ (expand_default_init): Handle brace-enclosed initializers
+ correctly.
+ (expand_aggr_init_1): Remove RTL-generation code.
+ (build_vec_init): Remove "new X = ..." support.
+ * parse.y (new_initializer): Likewise.
+ * rtti.c (get_pseudo_ti_init): Set TREE_HAS_CONSTRUCTOR on
+ brace-enclosed initializer.
+ (create_pseudo_type_info): Likewise.
+ * typeck2.c (store_init_value): Don't try to handle digest_init
+ being called more than once.
+ (digest_init): Tidy handling of brace-enclosed initializers.
+
+2002-10-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (typename_hash): Use htab_hash_pointer.
+
+2002-10-10 Jim Wilson <wilson@redhat.com>
+
+ * decl.c (duplicate_decls): Don't call decl_attributes.
+
+2002-10-09 Zack Weinberg <zack@codesourcery.com>
+
+ PR c/7353
+ * decl.c (start_decl): Unconditionally issue error for
+ 'typedef foo = bar'.
+ (cp_finish_decl): Remove special case for TYPE_DECL with initializer.
+ (grokdeclarator): Remove redundant error for 'typedef foo = bar'.
+
+2002-10-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (prune_vtable_vardecl): Delete unused function.
+
+2002-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7754
+ * decl2.c (finish_anon_union): Do not expand anonymous unions when
+ procesing template functions.
+ * pt.c (tsubst_decl, case VAR_DECL): Try to complete the variable
+ type. Call layout_decl.
+ (tsubst_expr, case DECL_STMT): Handle anonymous unions.
+
+2002-10-07 Richard Henderson <rth@redhat.com>
+
+ * decl2.c, pt.c: Revert c++/7754 fix.
+
+2002-10-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/7804
+ * error.c (dump_expr) [REAL_CST]: Output in decimal format.
+
+2002-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7931
+ * pt.c (for_each_template_parm_r): Handle BASELINKs.
+
+ PR c++/7754
+ * decl2.c (finish_anon_union): Do not expand anonymous unions when
+ procesing template functions.
+ * pt.c (tsubst_decl, case VAR_DECL): Try to complete the variable
+ type. Call layout_decl.
+ (tsubst_expr, case DECL_STMT): Handle anonymous unions.
+
+2002-10-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8006
+ * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Handle instances of template
+ template parameters.
+ (globals): Add entity and need_abi_warning.
+ (decl_is_template_id): Use TYPE_TEMPLATE_INFO, not
+ CLASSTYPE_TEMPLATE_INFO.
+ (is_std_substitution): Use CLASSTYPE_TI_TEMPLATE, not
+ TYPE_TI_TEMPLATE.
+ (write_prefix): Handle typename types correctly.
+ (write_template_prefix): Handle template template parameters
+ correctly.
+ (start_mangling): Add entity parameter.
+ (finish_mangling): Warn about names whose mangling will change.
+ (mangle_decl_string): Adjust.
+ (mangle_type_string): Likewise.
+ (mangle_special_for_type): Likewise.
+ (mangle_ctor_vtbl_for_type): Likewise.
+ (mangle_thunk): Likewise.
+ (mangle_guard_variable): Likewise.
+ (mangle_ref_init_variable): Likewise.
+
+2002-10-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7188.
+ * cp-tree.def (CTOR_INITIALIZER): Use one slot, not two.
+ * cp-tree.h (emit_base_init): Rename to ....
+ (emit_mem_initializers): ... this.
+ (expand_member_init): Change prototype.
+ * init.c (perform_member_init): Compute explicit, rather than
+ requiring it as a parameter.
+ (sort_member_init): Rename to ...
+ (sort_mem_initializers): ... this. Process bases and data members
+ together.
+ (sort_base_init): Remove.
+ (emit_base_init): Rename to ...
+ (emit_mem_initializers): ... this.
+ (expand_aggr_vbase_init_1): Remove.
+ (construct_virtual_bases): Rename to ...
+ (construct_virtual_base): ... this.
+ (expand_member_init): Rework handling of base initializers.
+ * method.c (do_build_copy_constructor): Use
+ finish_mem_initializers.
+ * parse.y (member_init): Adjust calls to expand_member_init.
+ * pt.c (tsubst_expr): Simplify CTOR_INITIALIZER case.
+ (tsubst_initializer_list): Use expand_member_init.
+ * semantics.c (finish_mem_intiailizers): Simplify.
+
+2002-10-02 Matt Austern <austern@apple.com>
+ * decl.c (walk_vtables_r): Fixed typo that caused result to
+ never get a nonzero value.
+
+2002-10-02 Roger Sayle <roger@eyesopen.com>
+
+ PR optimization/6627
+ * cp-tree.h (enum ptrmemfunc_vbit_where_t): Delete definition
+ from here, and move it to tree.h.
+ * decl.c (cxx_init_decl_processing): If storing the vbit
+ in function pointers, ensure that force_align_functions_log
+ is atleast one.
+
+2002-10-02 Matt Austern <austern@apple.com>
+
+ * class.c (check_field_decls): Changed warning about const member
+ variables so that it doesn't get issued for a class aggregate.
+
+2002-10-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Make sure array types are laid out,
+ even if the array bounds are unknown.
+
+2002-10-01 Steve Ellcey <sje@cup.hp.com>
+
+ * class.c (build_vtbl_initializer): Change build_c_cast
+ to build1.
+
+2002-10-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Make sure array types are laid out,
+ even if the array bounds are unknown.
+
+ * decl.c (cp_finish_decl): Correct check for dynamic
+ initialization of thread-local storage.
+
+2002-09-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (really_overloaded_fn): TEMPLATE_ID_EXPRs are also
+ overloaded.
+
+2002-09-30 Steve Ellcey <sje@cup.hp.com>
+
+ * class.c (build_vtbl_initializer): Add cast.
+ (add_vcall_offset_vtbl_entries_1):
+ Use TARGET_VTABLE_DATA_ENTRY_DISTANCE for offset.
+
+2002-09-30 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (walk_subobject_offsets): Correct the calculation of
+ offsets for virtual bases. Correct the counting of array
+ elements.
+ (layout_nonempty_base_or_field): Simplify. Correct the
+ calculation of offsets to be propagated through the binfo
+ hierarchy.
+ (build_base_field): Avoid creating a FIELD_DECL for empty bases.
+ Add the FIELD_DECL to TYPE_FIELDS.
+ (build_base_fields): Adjust accordingly.
+ (layout_virtual_bases): Use build_base_field.
+ (end_of_class): Return a tree, not an integer.
+ (warn_about_ambiguous_direct_bases): Rename to ...
+ (warn_about_ambiguous_bases): ... this.
+ (include_empty_classes): New function.
+ (layout_class_type): Create an alternative version of the type to
+ be used when as a base class type. Do not call
+ finish_record_layout until we are done laying out the class.
+ * cp-tree.h (lang_type_class): Remove size, size_unit. Add
+ as_base.
+ (CLASSTYPE_SIZE): Reimplement.
+ (CLASSTYPE_SIZE_UNIT): Likewise.
+ (CLASSTYPE_ALIGN): Likweise.
+ (CLASSTYPE_USER_ALIGN): Likewise.
+ (CLASSTYPE_AS_BASE): New macro.
+ (DECL_INITIALIZED_P): Likewise.
+ (extract_init): Remove prototype.
+ (build_forced_zero_init): Rename to ...
+ (build_zero_init): ... this.
+ (force_store_init_value): Remove.
+ * decl.c (obscure_complex_init): Remove.
+ (duplicate_decls): Copy DECL_INITIALIZED_P.
+ (check_initializer): Do not leave junk in DECL_INITIAL.
+ (cp_finish_decl): Handle zero-initialization of entities with
+ static storage duration.
+ * expr.c (extract_init): Remove.
+ * init.c (build_forced_zero_init): Remove.
+ (build_zero_init): New function.
+ (build_default_init): Use it.
+ (build_field_list): Skip FIELD_DECLs for base subobjects.
+ (push_base_cleanups): Likewise.
+ * method.c (do_build_assign_ref): Likewise.
+ (synthesize_exception_spec): Likewise.
+ * pt.c (tsubst_decl): Clear DECL_INITIALIZED_P.
+ (regenerate_decl_from_template): To not set DECL_INITIAL for a
+ static data member whose initialization took place in its class.
+ (instantiate_decl): Do not pass an initializer to cp_finish_decl
+ in that situation.
+ * search.c (dfs_push_decls): Skip FIELD_DECLs for base subobjects.
+ (dfs_unuse_fields): Likewise.
+ * tree.c (pod_type_p): Handle error_mark_node.
+ (zero_init_p): Likewise.
+ * typeck.c (lookup_anon_field): Skip FIELD_DECLs for base
+ subobjects.
+ * typeck2.c (store_init_value): Remove #if 0'd code.
+ (force_store_init_value): Remove.
+ (process_init_constructor): Use build_zero_init.
+
+2002-09-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7788
+ * rtti.c (unemitted_tinfo_decl_p): Check it has a field.
+
+2002-09-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cp-tree.h: Fix comment typos.
+ * decl.c: Likewise.
+ * pt.c: Likewise.
+
+2002-09-25 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/class.c (contains_empty_class_p): New method.
+ (walk_subobject_offsets): Correct computation of field offset.
+ (layout_empty_base): Correct placement of emtpy base classes.
+ (layout_class_type): Warn about ABI changes.
+
+2002-09-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/class.c (layout_virtual_bases): Do not round the size of the
+ type to a multiple of the alignment before laying out virtual bases.
+ (layout_class_type): Correct handling of bit-fields that are wider
+ than their type inside unions. Round the size of the type to a
+ even number of bytes when computing the size without virtual
+ bases.
+ * cp/cp-tree.h (abi_version_at_least): New macro.
+
+2002-09-21 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.2: Likewise.
+ * call.c: Likewise.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * except.c: Likewise.
+ * friend.c: Likewise.
+ * g++spec.c: Likewise.
+ * init.c: Likewise.
+ * lex.c: Likewise.
+ * mangle.c: Likewise.
+ * method.c: Likewise.
+ * operators.def: Likewise.
+ * optimize.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * spew.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2002-09-18 Devang Patel <dpatel@apple.com>
+
+ * cp/cp-tree.h: New prototype for walk_vtabls().
+ * cp/decl.c (walk_vtables_r): New function.
+ (struct cp_binding_level): Add new members, namespaces,
+ names_size and vtables.
+ (add_decl_to_level): Add decl in namespaces or vtables
+ chain, if conditions match.
+ (walk_vtables): New function.
+ (walk_namespaces_r): Travers separate namespace chain
+ for namespace decls.
+ (wrapup_globals_for_namespace): Use names_size instead
+ of list_length().
+ * cp/decl2.c (finish_file): Use walk_vtables() instead of
+ walk_globals() to walk vtable decls.
+
+2002-09-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Use assert, not internal_error. Don't
+ ICE with invalid pointers & references.
+
+2002-09-17 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in: Remove all references to the demangler.
+ * cxxfilt.c: Moved to binutils.
+
+2002-09-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7718
+ * pt.c (tsubst_decl): Remove assert.
+
+ Remove DR 295 implementation.
+ * pt.c (check_cv_quals_for_unify): Disable function & method cases.
+ * tree.c (cp_build_qualified_type_real): Likewise. Don't warn
+ about ignoring volatile qualifiers.
+
+ * search.c (lookup_member): Correct documentation.
+
+2002-09-16 Geoffrey Keating <geoffk@apple.com>
+
+ * cp-tree.h (union lang_tree_node): Add chain_next option.
+
+2002-09-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (parse_finish_call_expr): Check lookup_member result.
+
+ PR c++/7015
+ * semantic.c (finish_asm_stmt): Fix operand/output_operands
+ thinko.
+ * typeck.c (c_expand_asm_operands): Protect from error_mark_node.
+
+2002-09-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7919
+ * call.c (build_over_call): Convert this pointer for fns found by
+ using decls.
+
+2002-09-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.1: Likewise.
+
+2002-09-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7768
+ * pt.c (build_template_decl): Copy DECL_DESTRUCTOR_P.
+
+2002-09-14 Kazu Hirata <kazu@cs.umass.edu>
+
+ * error.c: Fix comment formatting.
+ * except.c: Likewise.
+ * expr.c: Likewise.
+ * friend.c: Likewise.
+ * g++spec.c: Likewise.
+ * init.c: Likewise.
+ * lex.c: Likewise.
+ * mangle.c: Likewise.
+ * method.c: Likewise.
+ * optimize.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * spew.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2002-09-13 Matt Austern <austern@apple.com>
+
+ PR C++/7828
+ * cp/cp-tree.h, cp/tree.c: New function non_cast_lvalue_p.
+ * cp/call.c: Change call-by-const-reference mechanism to use
+ non_cast_lvalue_p when deciding whether the create a temporary.
+ We need a temporary when passing, e.g. (long) x by const ref.
+
+2002-09-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (unify, ARRAY_TYPE): Element type can be more qualified.
+
+2002-09-13 Kazu Hirata <kazu@cs.umass.edu>
+
+ * decl.c: Fix comment formatting.
+ * decl2.c: Likewise.
+
+2002-09-12 Kazu Hirata <kazu@cs.umass.edu>
+
+ * call.c: Fix comment formatting.
+ * class.c: Likewise.
+ * cp-lang.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+
+2002-09-11 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in: Build cp/cxxfilt.o from $(srcdir)/cp/cxxfilt.c,
+ and c++filt from cxxfilt.o + version.o + $(LIBDEPS).
+ * cxxfilt.c: New file: split from libiberty/cplus-dem.c, with
+ minor adjustments (use version_string, eliminate yet another
+ duplicate of xmalloc)
+
+2002-09-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (require_complete_eh_spec_types): Add prototype.
+
+2002-09-05 Jason Merrill <jason@redhat.com>
+
+ * typeck2.c (add_exception_specifier): Only pedwarn for an
+ incomplete type.
+ (require_complete_eh_spec_types): New fn.
+ (cxx_incomplete_type_diagnostic): Also support pedwarning.
+ * typeck.c (complete_type_or_diagnostic): Likewise.
+ * call.c (build_call): Call require_complete_eh_spec_types.
+ * rtti.c (get_pseudo_ti_desc): Give an error rather than aborting
+ on an incomplete type.
+
+2002-09-04 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (start_cleanup_fn): Clear interface_only before
+ start_function, restore it afterwards.
+
+2002-09-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (finish_builtin_type): Remove.
+ * decl2.c (finish_builtin_type): Move to common code.
+ * decl.c (build_ptrmemfunc_type): Adjust.
+ * rtti.c (create_pseudo_type_info): Adjust.
+ (create_tinfo_types): Adjust.
+
+2002-08-31 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (cp_expr_size): Allow initialization from a
+ CONSTRUCTOR.
+
+2002-08-30 Richard Henderson <rth@redhat.com>
+
+ PR opt/7515
+ * tree.c: Include target.h.
+ (cp_cannot_inline_tree_fn): Don't auto-inline functions that
+ don't bind locally.
+ * Makefile.in (tree.o): Update.
+
+2002-08-27 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_virtual_bases): Warn about bugs in G++ that
+ result in incorrect object layouts.
+ (layout_class_type): Likewise.
+
+2002-08-24 Matt Austern <austern@apple.com>
+
+ * tree.c (lvalue_p_1): Add argument for whether casts of lvalues
+ are allowable.
+ (real_lvalue_p): Update caller.
+ (lvalue_p): Ditto.
+ (non_cast_lvalue_or_else): New.
+ * tree.h: Declare it.
+ * typeck.c (build_unary_op): Use non_cast_lvalue_or_else.
+
+2002-08-22 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_class_member_access_expr): Handle COMPOUND_EXPR
+ and COND_EXPR specially; fix error message output.
+
+2002-08-22 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_expr): RETURN_EXPR is now RETURN_STMT_EXPR.
+ * semantics.c (nullify_returns_r): Likewise.
+
+2002-08-17 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ Fix PR/7621
+ * typeck.c (finish_class_member_access_expr): Diagnose cases where
+ name lookup finds nothing.
+
+2002-08-15 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (finish_then_clause): Remove redundant assignment.
+ (finish_if_stmt, begin_switch_stmt, finish_switch_stmt): Move the
+ extra binding level outside the if/switch statement.
+ (finish_while_cond, finish_for_cond): Rewrite complex condition
+ into the loop body.
+
+2002-08-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * parse.y (sizeof, alignof, typeof): New non-terminals to
+ increment skip_evaluation. Replace terminals with them and
+ decrement skip_evaluation at the end of rules using them.
+ * decl2.c (mark_used): Don't assemble_external if
+ skipping evaluation.
+
+2002-08-15 Gabriel Dos Reis <gdr@nerim.net>
+
+ Fix PR/7504
+ * parse.y (parse_finish_call_expr): Handle incomplete
+ type used to name a scope.
+
+2002-08-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/7598
+ * typeck.c (build_unary_op): Fold offsetof idiom. Fixes
+ regression caused by my 2002-08-08 patch.
+
+2002-08-13 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (pushdecl_class_level): Honor requests to bind names to
+ OVERLOADs.
+
+2002-08-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (build_call_from_tree): Fix uninitialized variable.
+ * parse.y (parse_finish_call_expr): Likewise.
+ * repo.c (old_args, old_dir, old_main): Const-ify.
+
+2002-08-11 Gabriel Dos Reis <gdr@nerim.net>
+
+ * decl.c (duplicate_decls): Replace DECL_SOURCE_FILE
+ DECL_SOURCE_LINE with DECL_SOURCE_LOCATION.
+ * optimize.c (maybe_clone_body): Likewise.
+ * pt.c (tsubst_enum): Likewise.
+ (lookup_template_class): Likewise.
+ * tree.c (cp_copy_res_decl_for_inlining): Likewise.
+
+2002-08-10 Neil Booth <neil@daikokuya.co.uk>
+
+ * lang-specs.h: Remove -ansi.
+
+2002-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (maybe_dummy_object): Replace // with /* */
+
+2002-08-09 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (standard_conversion): Use build_ptrmem_type.
+ * cp-tree.h (build_ptrmem_type): New function.
+ (adjust_result_of_qualified_name_lookup): Likewise.
+ * decl.c (grokvardecl): Do not look for OFFSET_TYPEs to indicate
+ static data members.
+ (build_ptrmem_type): New function.
+ (grokdeclarator): Do not use build_offset_type when encountering a
+ qualified name.
+ * parse.y (parse_finish_call_expr): Use
+ adjust_result_of_qualified_name_lookup.
+ * search.c (adjust_result_of_qualified_name_lookup): New function.
+ * typeck.c (qualify_type_recursive): Use TYPE_PTRMEM_* rather than
+ accessing OFFSET_TYPEs directly.
+
+2002-08-08 Mike Stump <mrs@apple.com>
+
+ * call.c (add_builtin_candidate): legal -> valid, illegal -> invalid.
+ (type_decays_to): Likewise.
+ * class.c (find_final_overrider): Likewise.
+ (maybe_note_name_used_in_class): Likewise.
+ * decl.c (current_tmpl_spec_kind): Likewise.
+ (add_binding): Likewise.
+ (push_class_binding): Likewise.
+ (duplicate_decls): Likewise.
+ (layout_var_decl): Likewise.
+ (grokfndecl): Likewise.
+ (grokdeclarator): Likewise.
+ (check_default_argument): Likewise.
+ * decl2.c (handle_class_head): Likewise.
+ * error.c (dump_template_decl): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * pt.c (check_specialization_scope): Likewise.
+ (determine_specialization): Likewise.
+ (check_explicit_specialization): Likewise.
+ (maybe_check_template_type): Likewise.
+ (process_partial_specialization): Likewise.
+ (check_default_tmpl_args): Likewise.
+ (push_template_decl_real): Likewise.
+ (convert_template_argument): Likewise.
+ (try_class_unification): Likewise.
+ (get_bindings_real): Likewise.
+ (do_decl_instantiation): Likewise.
+ * semantics.c (begin_function_definition): Likewise.
+ (finish_member_declaration): Likewise.
+ (check_multiple_declarators): Likewise.
+ * typeck.c (comp_array_types): Likewise.
+ (comptypes): Likewise.
+ (expr_sizeof): Likewise.
+ (build_binary_op): Likewise.
+ (dubious_conversion_warnings): Likewise.
+ (check_return_expr): Likewise.
+
+2002-08-08 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (build_class_member_access_expr): Do not return
+ error_mark_node when no error has occurred.
+
+2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (build_component_addr): Remove.
+ (build_unary_op): Just check it's not a bitfield, and then build
+ an ADDR_EXPR.
+
+2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (convert_to_base): Correct check for error_mark_node.
+ (create_vtable_ptr): Remove unused VFUNS_P parm.
+
+2002-08-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp/Make-lang.in (c++.mostlyclean): Remove coverage files.
+
+2002-08-07 Mark Mitchell <mark@codesourcery.com>
+
+ Rework build_component_ref.
+ * call.c (build_vfield_ref): Do not go through build_component_ref.
+ (build_field_call): Use build_class_member_access_expr.
+ (build_user_type_conversion_1): Use BASELINK_FUNCTIONS.
+ (build_object_call): Likewise.
+ * class.c (convert_to_base): New function.
+ (type_requires_array_cookie): Use BASELINK_FUNCTIONS.
+ (instantiate_type): Handle BASELINKs.
+ * cp-tree.def (BASELINK): New tree code.
+ * cp-tree.h (BASELINK_P): Reimplement.
+ (SET_BASELINK_P): Remove.
+ (BASELINK_BINFO): Reimplement.
+ (BASELINK_FUNCTIONS): Likewise.
+ (BASELINK_ACCESS_BINFO): Likewise.
+ (BASELINK_OPTYPE): Likewise.
+ (convert_to_base): New function.
+ (name_p): Likewise.
+ (build_object_ref): Remove.
+ (build_component_ref_1): Likewise.
+ (build_component_ref): Likewise.
+ (build_x_component_ref): Likewise.
+ (build_class_member_access_expr): New function.
+ (finish_class_member_access_expr): Likewise.
+ (build_ptrmemfunc_access_expr): Likewise.
+ * decl.c (grokdeclarator): Handle BASELINKs.
+ * decl2. (build_expr_from_tree): Handle COMPONENT_REFs by using
+ finish_class_member_access_expr.
+ (arg_assoc): Handle BASELINKs.
+ (do_class_using_decl): Likewise.
+ * error.c (dump_decl): Likewise.
+ (dump_expr): Use build_ptrmemfunc_access_expr.
+ * except.c (dtor_nothrow): Use CLASSTYPE_DESTRUCTORS to find
+ destructors.
+ (build_throw): Use BASELINK_FUNCTIONS.
+ * init.c (perform_member_init): Use
+ build_class_member_access_expr.
+ (build_offset_ref): Handle BASELINKs. Use
+ build_class_member_access_expr.
+ * method.c (hack_identifier): Likewise.
+ * parse.y (do_id): Use BASELINK, not TREE_LIST.
+ (primary): Remove uses of build_object_ref.
+ * pt.c (lookup_template_function): Handle BASELINKs.
+ (resolve_overloaded_unification): Likewise.
+ * search.c (build_baselink): Build a BASELINK, not a TREE_LIST.
+ (lookup_field): Use BASELINK, not TREE_LIST.
+ (lookup_fnfiels): Likewise.
+ (setup_class_bindings): Likewise.
+ * semantics.c (finish_object_call_expr): Do not use
+ build_method_call when we already know what function is being
+ called.
+ * spew.c (identifier_type): Use BASELINK, not TREE_LIST.
+ * tree.c (really_overloaded_fn): Use OVL_CHAIN for OVERLOADs, not
+ TREE_CHAIN.
+ (name_p): New function.
+ * typeck.c (build_object_ref): Remove.
+ (build_component_ref_1): Likewise.
+ (build_x_component_ref): Likewise.
+ (build_class_member_access_expr): New function.
+ (finish_class_member_access_expr): Likewise.
+ (build_ptrmemfunc_access_expr): Likewise.
+ (get_member_function_from_ptrfunc): Use
+ build_ptrmemfunc_access_expr.
+ (build_binary_op): Likewise.
+ (build_unary_op): Likewise.
+ (build_ptrmemfunc): Likewise.
+ (pfn_from_ptrmemfunc): Likewise.
+ * typeck2.c (build_m_component_ref): Adjust comment.
+
+2002-08-07 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (CXX_C_OBJS): Update.
+ * cp-lang.c (LANG_HOOKS_DECODE_OPTION): Use c_common_decode_option.
+ * cp-tree.h (cxx_decode_option): Remove.
+ * decl2.c (compare_options, lang_f_options, unsupported_options,
+ cxx_decode_option): Remove.
+
+2002-08-06 Gabriel Dos Reis <gdr@nerim.net>
+
+ * typeck.c (build_x_unary_op): Handle pointer-to-member.
+
+2002-08-05 Geoffrey Keating <geoffk@redhat.com>
+
+ * class.c: Don't include obstack.h.
+ (popclass):
+ * decl2.c: Delete bogus comment.
+ * error.c: Don't include obstack.h.
+ * except.c: Likewise.
+ (dump_type): Correct comment.
+ * method.c: Don't include obstack.h.
+ * tree.c: Likewise.
+
+2002-08-04 Gabriel Dos Reis <gdr@nerim.net>
+
+ Fix PR/2213
+ * cvt.c (cp_convert_to_pointer): Reject conversions from integral
+ expressions to pointer-to-data-member of pointer-to-member-functions.
+
+2002-08-04 Geoffrey Keating <geoffk@redhat.com>
+
+ * cvt.c (ocp_convert): Delete obsolete code.
+ * parse.y (permanent_obstack): Delete declaration.
+ * pt.c (permanent_obstack): Delete declaration.
+ * repo.c (permanent_obstack): Delete declaration.
+ (open_repo_file): Use xmalloc instead of permanent_obstack.
+ (init_repo): Use xstrdup instead of permanent_obstack.
+
+2002-08-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (VF_DERIVED_VALUE): Remove.
+ * class.c (finish_struct_1): Use VF_BINFO_VALUE not VF_DERIVED_VALUE.
+
+2002-08-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR 7470.
+ C++ ABI change - vfunc ordering.
+ * class.c (add_virtual_function): Remove.
+ (dfs_modify_all_vtables): Take list of all declared
+ virtuals. Assign all that are not in primary base.
+ (check_for_override): Adjust comments.
+ (create_vtable_ptr): Take single list of virtuals. Build chain
+ of declared virtuals here.
+ (layout_class_type): Take single list of virtuals. Adjust.
+ (finish_struct_1): Keep virtuals on single list. Adjust.
+
+2002-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (build_member_call): Use build_new_method_call, not
+ build_method_call.
+
+2002-08-02 Krister Walfridsson <cato@df.lth.se>
+
+ * Make-lang.in (spew.o, lex.o, pt.o): Add path to parse.h dependencies.
+
+2002-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_method_call): Issue a more helpful error message
+ about ambiguous method names.
+
+2002-08-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (build_shared_int_cst): Make cache file scope, and
+ GTY it.
+
+2002-08-02 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_EXPR_SIZE): Define.
+ (cp_expr_size): New fn.
+ * call.c (build_over_call): Lose empty class hackery.
+ (convert_arg_to_ellipsis): Promote non-POD warning to error.
+ * typeck.c (build_modify_expr): Don't use save_expr on an lvalue.
+
+ * semantics.c (expand_body): Do tree optimization in the function
+ context, too.
+
+2002-08-01 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-tree.h: Move all warning and flag declarations to c-common.h.
+ * decl.c: Move all warning and flag variables to c-common.c.
+ * decl2.c: Move all warning and flag variables to c-common.c.
+ * lex.c (flag_digraphs): Remove.
+ (warn_traditional): Now in c-common.c.
+
+2002-07-31 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_field_call): Do not look up the field by name.
+ (build_method_call): Simplify.
+ (struct z_candidate): Add access_path and conversion_path. Remove
+ basetype_path.
+ (convert_class_to_reference): Adjust use of
+ add_function_candidate.
+ (add_candidate): Add conversion_path argument.
+ (add_function_candidate): Use it.
+ (add_conv_dndidate): Likewise.
+ (build_builtin_candidate): Likewise.
+ (add_template_candidate_real): Add conversion_path argument.
+ (add_template_conv_candidate): Likewise.
+ (add_template_candidate): Likewise.
+ (build_user_type_conversion_1): Use it.
+ (build_new_function_call): Remove name lookup code. Adjust use of
+ add_template_candidate and add_function_candidate.
+ (build_new_op): Likewise.
+ (convert_like_real): Use build_special_member_call.
+ (build_over_call): Use cand->conversion_path.
+ (build_special_member_call): New method.
+ (build_new_method_call): Remove name lookup code.
+ * cp-tree.def (OFFSET_REF): Update documentation.
+ (TEMPLATE_ID_EXPR): Likewise.
+ * cp-tree.h (BASELINK_ACCESS_BINFO): New macro.
+ (BASELINK_OPTYPE): Likewise.
+ (build_new_method_call): Adjust prototype.
+ (build_special_member_call): New method.
+ (build_baselink): New method.
+ (build_offset_ref_call_from_tree): Likewise.
+ (build_call_from_tree): Likewise.
+ (finish_qualified_call_expr): Remove.
+ (finish_call_expr): Adjust prototype.
+ (build_x_function_call): Remove.
+ * cvt.c (ocp_convert): Use build_special_member_call.
+ * decl2.c (reparse_absdcl_as_expr): Use finish_call_expr.
+ (build_expr_from_tree): Adjust handling for TEMPLATE_ID_EXPR and
+ CALL_EXPR.
+ (build_offset_ref_call_from_tree): New function.
+ (build_call_from_tree): Likewise.
+ * init.c (expand_cleanup): Use build_special_member_call.
+ (expand_default_init): Likewise.
+ (build_member_call): Use finish_call_expr.
+ (build_new_1): Use build_special_member_call.
+ (push_base_cleanups): Likewise.
+ * method.c (do_build_assign_ref): Likewise.
+ * parse.y (template_id): Do not pass a COMPONENT_REF to
+ lookup_template_function.
+ (primary): Use parse_finish_call_epxr, not finish_call_expr.
+ (parse_finish_call_expr): New function.
+ * pt.c (lookup_template_function): Add assertions.
+ * search.c (lookup_base): Allow T to be a binfo.
+ (build_baselink): New function.
+ (lookup_member): Use it.
+ * semantics.c (finish_call_expr): Do not do name lookup.
+ (finish_object_call_expr): Remove #if 0'd code.
+ (finish_qualified_call_expr): Remove.
+ * typeck.c (build_x_function_call): Remove.
+ (build_static_case): Use build_special_member_call.
+ * typeck2.c (build_functional_cast): Likewise.
+
+2002-07-30 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * lang-specs.h: Remove __GXX_ABI_VERSION, moved to gcc.c.
+
+2002-07-30 Gabriel Dos Reis <gdr@nerim.net>
+
+ * cp-tree.h (VF_DERIVED_VALUE): Restore from previous deletion.
+
+2002-07-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_VFIELDS, VF_*, BV_*): Add more
+ documentation.
+
+2002-07-29 Alan Modra <amodra@bigpond.net.au>
+
+ * cp-tree.h: Comment typo fix.
+
+2002-07-29 Richard Earnshaw <rearnsha@arm.com>
+
+ * spew.c (space_for_token): Allocate zeroed memory for a new token
+ chunk.
+
+2002-07-27 Roger Sayle <roger@eyesopen.com>
+
+ * decl.c (builtin_function_1): No need to explicitly mark
+ BUILT_IN_RETURN and BUILT_IN_EH_RETURN as noreturn.
+
+2002-07-27 Roger Sayle <roger@eyesopen.com>
+
+ * decl2.c (cxx_decode_option): Support -fno-builtin-foo.
+
+2002-07-26 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_over_call): Likewise.
+ (cp_convert_parm_for_inlining): New fn.
+ (convert_for_arg_passing): New fn.
+ (convert_default_arg, build_over_call): Use it.
+ (type_passed_as): New fn.
+ * pt.c (tsubst_decl): Use it.
+ * decl2.c (cp_build_parm_decl): New fn.
+ (build_artificial_parm): Use it.
+ (start_static_storage_duration_function): Likewise.
+ * decl.c (start_cleanup_fn, grokdeclarater): Likewise.
+ (grokparms): Don't mess with DECL_ARG_TYPE.
+ * typeck.c (convert_arguments): Use convert_for_arg_passing.
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING):
+ Define.
+ * cp-tree.h: Declare new fns.
+
+2002-07-26 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-tree.h (flag_operator_names): Remove.
+ * decl2.c (flag_operator_names): Remove.
+ (lang_f_options): Remove operator-names.
+ * lex.c (D_OPNAME): Remove.
+ (reswords): Remove operator names.
+ (rid_to_yy): Remove operator names.
+ (init_reswords): No need to handle D_OPNAME.
+ * spew.c (read_process_identifier): There are no operator
+ names.
+
+2002-07-26 Jason Merrill <jason@redhat.com>
+
+ * dump.c (cp_dump_tree): Call c_dump_tree.
+ * Make-lang.in (CXX_C_OBJS): Add c-dump.o.
+
+2002-07-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * error.c (print_whitespace): Remove.
+ * g++spec.c (LIBUNWIND): Move.
+ * mangle.c (mangled_position, write_signed_number): Remove.
+
+2002-07-25 Neil Booth <neil@daikokuya.co.uk>
+
+ * decl2.c (cxx_decode_option): Similarly.
+
+2002-07-25 Gabriel Dos Reis <gdr@nerim.net>
+
+ * cp-tree.h (cxx_sizeof_nowarn): Now a macro.
+ (cxx_sizeof_or_alignof_type): Take a third argument.
+ (cxx_sizeof): Adjust definition.
+ (cxx_alignof): Likewise.
+ * init.c (build_delete): Use cxx_sizeof_nowarn to reflect reality.
+ * typeck.c (cxx_sizeof_or_alignof_type): Take a third argument for
+ complaining.
+ (c_sizeof_nowarn): Remove definition.
+ (build_unary_op): Use cxx_sizeof_nowarn.
+
+2002-07-24 Geoffrey Keating <geoffk@redhat.com>
+
+ * tree.c (cp_build_qualified_type_real): When copying
+ pointer-to-method types, unshare the record that holds
+ the cached pointer-to-member-function type.
+
+2002-07-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * cp-tree.h (FILE_FUNCTION_PREFIX_LEN): Remove.
+
+2002-07-23 Gabriel Dos Reis <gdr@nerim.net>
+
+ Fix PR/7363:
+ * typeck.c (cxx_sizeof_or_alignof_type): New function.
+ (c_sizeof): Remove definition.
+ (expr_sizeof): Use cxx_sizeof.
+ * decl2.c (build_expr_from_tree): Use cxx_sizeof_or_alignof_type.
+ * decl.c (finish_destructor_body): Use cxx_sizeof.
+ * semantics.c (finish_alignof): Likewise.
+ (finish_alignof): Use cxx_alignof.
+ * cp-tree.h (cxx_sizeof, cxx_alignof): New macros.
+ (cxx_sizeof_or_alignof_type): Declare.
+ (my_friendly_assert): Move to ../c-common.h.
+
+2002-07-23 Neil Booth <neil@daikokuya.co.uk>
+
+ * class.c, method.c, pt.c, search.c: Don't define obstack macros.
+
+2002-07-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/7347, c++/7348
+ * cp-tree.h (tsubst_flags_t): Add tf_parsing.
+ * decl.c (make_typename_type): Use it.
+ (make_unbound_class_template): Likewise.
+ (lookup_name_real): Don't call type_access_control if scope is
+ template parameter dependent.
+ * parse.y (template_arg): Call make_unbound_class_template with
+ tf_parsing set.
+ (nest_name_specifier): Call make_typename_type with tf_parsing set.
+ (typename_sub0): Likewise.
+ (typename_sub1): Likewise.
+ (instantiate_decl): Push class scope.
+ * pt.c (regenerate_decl_from_template): Call pushclass and popclass
+ for both static variable and member function template.
+ (instantiate_decl) Call pushclass and popclass when tsubst'ing type
+ and arguments.
+ * search.c (type_access_control): Do type access for TEMPLATE_DECL
+ too.
+
+2002-07-20 Roger Sayle <roger@eyesopen.com>
+
+ * decl2.c (cxx_decode_option): Simplify -fhandle-exceptions
+ test by using positive_option. Make whitespace consistent.
+
+2002-07-20 Gabriel Dos Reis <gdr@nerim.net>
+
+ * spew.c (struct unparsed_test): Replace 'filename' and 'lineno'
+ members with 'locus'. Adjust use throughout.
+ (struct feed): Likewise.
+ (alloc_unparsed_test): Change prototype, take a 'const location_t *'.
+ Adjust use.
+ (snarf_defarg): Use error(), not error_with_file_and_line().
+
+2002-07-19 Chris Demetriou <cgd@broadcom.com>
+
+ * lang-specs.h (@c++): Include "%2" (cc1plus_spec) wherever
+ cpp_options is included.
+
+2002-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/2862, c++/2863
+ * pt.c (determine_specialization): Compare the length of
+ TYPE_ARG_TYPES. Tidy.
+
+2002-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/3797
+ * decl.c (duplicate_decls): Don't propagate inlining parameters from
+ olddecl to newdecl when newdecl is a specialization of the
+ instantiation olddecl.
+
+2002-07-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/4802, c++/5387
+ * decl.c (make_typename_type): Use enforce_access.
+
+2002-07-17 Scott Snyder <snyder@fnal.gov>
+
+ PR c++/7320
+ * rtti.c (get_tinfo_decl): Set DECL_COMDAT.
+
+2002-07-12 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_method): Correct handling of conversion operators.
+
+2002-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7224
+ * class.c (add_method): Simplify.
+
+2002-07-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/7279
+ * tree.c (cp_copy_res_decl_for_inlining): Also copy
+ TREE_ADDRESSABLE.
+
+2002-07-10 Graham Stott <graham.stott@btinternet.com>
+
+ * pt.c (template_parm_this_level_p, push_template_decl_real):
+ Pass depth as int pointer.
+
+2002-07-11 Tim Josling <tej@melbpc.org.au>
+
+ Remove front end hard coding from gengtype.c.
+
+ * config-lang.in (gtfiles): Add files needed for this front end.
+
+2002-07-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (unqualified_name_lookup_error): Declare it.
+ (begin_function_definition): Adjust prototype.
+ * lex.c (unqualified_name_lookup_error): New function, split out
+ from ...
+ (do_identifier): ... here.
+ * parse.y (parse_begin_function_definition): New function.
+ (fn.def1): Use it.
+ * semantics.c (begin_function_definition): Accept decl-specifiers
+ and attributes as separate parameters.
+
+2002-07-10 Jason Merrill <jason@redhat.com>
+
+ PR c++/6255
+ * decl.c (lookup_name_real): Build a new TYPENAME_TYPE rather than
+ modifying the old one.
+
+2002-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (constructor_name_p): Declare it.
+ (check_template_template_default_arg): Likewise.
+ * class.c (handle_using_decl): Use constructor_name_p.
+ * decl.c (grokdeclarator): Likewise.
+ * decl2.c (constructor_name_p): Define it.
+ * init.c (build_member_call): Use constructor_name_p.
+ * parse.y (template_parm): Use check_template_template_default_arg.
+ * pt.c (check_explicit_specialization): Use constructor_name_p.
+ * semantics.c (check_template_template_default_arg): New function.
+
+2002-07-08 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (can_complete_type_without_circularity): Add static to
+ function definition.
+
+2002-07-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (have_extern_spec): Declare it
+ * decl.c (have_extern_spec): Define it.
+ (start_decl): Eliminate use of used_extern_spec.
+ (start_function): Likewise.
+ * parse.y (have_extern_spec): Remove declaration.
+ (used_extern_spec): Likewise.
+ (frob_specs): Eliminate use of used_extern_spec.
+ (.hush_warning): Likewise.
+
+2002-07-07 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (cp/parse.o): Depend on decl.h.
+ * cp-tree.h (do_decl_instantiation): Change prototype.
+ * parse.y: Include decl.h.
+ (parse_decl_instantiation): New function.
+ (explicit_instantiation): Use it.
+ * pt.c (do_decl_instantiation): Accept a DECL, not a DECLARATOR
+ and DECLSPECS.
+
+2002-07-07 Roger Sayle <roger@eyesopen.com>
+
+ * error.c (dump_function_name): Use DECL_TEMPLATE_RESULT for
+ constructor and destructor tests when passed a TEMPLATE_DECL.
+
+2002-07-05 Jason Merrill <jason@redhat.com>
+
+ * cvt.c (cp_convert_to_pointer): Call force_fit_type for null
+ pointers.
+
+ PR optimization/7145
+ * tree.c (cp_copy_res_decl_for_inlining): Also copy DECL_INITIAL.
+
+2002-07-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ Repair damage on weak-impared targets caused by my previous patch.
+ * cp-tree.h (import_export_tinfo): Add parameter.
+ * decl2.c (import_export_tinfo): Add parameter, post adjust
+ DECL_COMDAT.
+ * rtti.c (emit_tinfo_decl): DECL_COMDAT is (nearly) always setup by
+ import_export_tinfo.
+
+2002-07-03 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6944
+ * init.c (build_aggr_init): Remove qualifiers of init before calling
+ build_vec_init.
+ (build_vec_init): Flatten multi-dimensional array during cleanup.
+ (build_vec_delete_1): Abort if the type of each element is array.
+
+2002-07-03 Graham Stott <graham.stott@btinternet.com>
+
+ * pt.c (instantiate_class_template): Fix typo.
+
+2002-07-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * typeck2.c (cxx_incomplete_type_diagnostic): Fix typo caused
+ by CVS conflict in my last patch.
+
+2002-07-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6716
+ * pt.c (can_complete_type_without_circularity): New function.
+ (instantiate_class_template): Use it.
+ * typeck2.c (cxx_incomplete_type_diagnostic): Improve error
+ message due to incomplete fields.
+
+2002-07-01 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/7112
+ * mangle.c (write_expression): Add mangling for sizeof when
+ applied to a type.
+ * operators.def: Remove stale comment.
+
+2002-06-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CPTI_TINFO_DECL_TYPE): Replace with ...
+ (CPTI_TYPE_INFO_PTR_TYPE): ... this.
+ (tinfo_decl_type): Replace with ...
+ (type_info_ptr_type): ... this.
+ (import_export_tinfo): Declare.
+ (tinfo_decl_p): Rename to ...
+ (unemitted_tinfo_decl_p): ... this.
+ * decl2.c (import_export_decl): Break out tinfo handling into ...
+ (import_export_tinfo): ... here. New function.
+ (finish_file): Adjust.
+ * rtti.c (TINFO_REAL_NAME): New macro.
+ (init_rtti_processing): Create the tinfo types.
+ (get_tinfo_decl_dynamic): Use type_info_ptr_type, get_tinfo_ptr.
+ (get_tinfo_decl): Adjust.
+ (get_tinfo_ptr): New function.
+ (get_type_id): Use it.
+ (tinfo_base_init): Create vtable decl here, if it doesn't exist.
+ (ptr_initializer): Use get_tinfo_ptr.
+ (ptm_initializer): Likewise.
+ (synthesize_tinfo_var): Break into ...
+ (get_pseudo_ti_init): ... this. Just create the initializer.
+ (get_pseudo_ti_desc): .. and this.
+ (create_real_tinfo_var): Remove.
+ (create_pseudo_type_info): Don't create the vtable decl here.
+ (get_vmi_pseudo_type_info): Remove.
+ (create_tinfo_types): Adjust.
+ (tinfo_decl_p): Rename to ...
+ (unemitted_tinfo_decl_p): ... here. Adjust.
+ (emit_tinfo_decl): Adjust. Create the initializer.
+
+2002-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6695
+ * pt.c (tsubst_friend_class): Substitute into the context of the
+ friend before using it.
+
+2002-06-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (xref_tag): Change prototype.
+ (handle_class_head): Likewise.
+ (build_x_component_ref): Likewise.
+ * decl.c (cxx_init_decl_processing): Adjust call to xref_tag.
+ (xref_tag): Take attributes as a separate parameter.
+ (xref_tag_from_type): Adjust call to xref_tag.
+ * decl2.c (build_expr_from_tree): Adjust call to
+ build_x_component_ref.
+ (handle_class_head): Take attributes as a separate parameter.
+ * parse.y (parse_xref_tag): New function.
+ (parse_handle_class_head): Likewise.
+ (primary): Use parse_xref_tag.
+ (class_head_decl): Use parse_handle_class_head.
+ (class_head_defn): Likewise.
+ * rtti.c (init_rtti_processing): Adjust call to xref_tag.
+ (build_dynamic_cast_1): Likewise.
+ (create_pseudo_type_info): Likewise.
+ (emit_support_tinfos): Likewise.
+ * typeck.c (build_object_ref): Adjust call to
+ build_x_component_ref.
+ (build_x_component_ref): Remove protect parameter.
+
+2002-06-25 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_op_delete_call): Use BASELINK_FUNCTIONS.
+ * class.c (handle_using_decl): Likewise.
+ (instantiate_type): Likewise.
+ * cp-tree.h (BASELINK_FUNCTIONS): New macro.
+ (xref_basetypes): Change prototype.
+ (begin_mem_initializers): New function.
+ (get_overloaded_fn): Likewise.
+ * decl.c (xref_basetypes): Simplify.
+ * error.c (dump_expr): Use BASELINK_FUNCTIONS.
+ * init.c (build_offset_ref): Likewise.
+ * parse.y (base_init): Use begin_mem_initializers().
+ (structsp): Adjust call to xref_basetypes.
+ * pt.c (determine_specialization): Use BASELINK_FUNCTIONS.
+ (instantiate_class_template): Adjust call to xref_basetypes.
+ * semantics.c (begin_mem_initializers): New function.
+ * tree.c (is_overloaded_fn): Use BASELINK_FUNCTIONS.
+ (really_overloaded_fn): Likewise.
+ (get_overloaded_fn): New function.'
+ (get_first_fn): USe BASELINK_FUNCTIONS.
+
+2002-06-24 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (SCALAR_TYPE_P): New macro.
+ (check_for_out_of_scope_variable): New function.
+ (at_class_scope_p): Likewise.
+ (finish_fname): Likewise.
+ * class.c (finish_struct): Use at_function_scope_p.
+ * decl.c (check_for_out_of_scope_variable): New function, split
+ out from do_identifier.
+ (finish_enum): Use at_function_scope_p.
+ * lex.c (do_identifier): Use check_for_out_of_scope_variable.
+ * parse.y (VAR_FUNC_NAME): Give it <ttype>. Use finish_fname.
+ (primary): Use at_function_scope_p.
+ * search.c (at_class_scope_p): New function.
+ * semantics.c (finish_fname): Likewise.
+ (check_multiple_declarators): Use at_function_scope_p.
+
+2002-06-23 Mark Mitchell <mark@codesourcery.com>
+
+ * parse.y (parse_scoped_id): New function.
+ (primary): Use it.
+ * cp-tree.h (do_scoped_id): Adjust declaration.
+ * lex.c (do_scoped_id): Remove call to yylex.
+ * decl2.c (build_expr_from_tree): Adjust use of do_scoped_id.
+ * typeck2.c (add_exception_specifier): Use tree_cons, rather than
+ expanding it inline.
+
+2002-06-23 Matt Thomas <matt@3am-software.com>
+
+ * decl.c (finish_function): Change "#ifdef VMS_TARGET" to
+ "#if VMS_TARGET".
+
+2002-06-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mangle.c (integer_type_codes): Const-ify.
+
+2002-06-20 Richard Henderson <rth@redhat.com>
+
+ PR c++/6747
+ * typeck.c (mark_addressable): Don't test TREE_ADDRESSABLE early.
+ Call put_var_into_stack.
+
+2002-06-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * spew.c (remove_last_token): Use ARRAY_SIZE in lieu of explicit
+ array size calculation.
+
+2002-06-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6892
+ * pt.c (tsubst_expr): Handle FILE_STMT.
+
+2002-06-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6723
+ * pt.c (lookup_template_class): Don't build complete argument of
+ BOUND_TEMPLATE_TEMPLATE_PARM if appeared as a default template
+ argument.
+
+2002-06-19 Akim Demaille <akim@epita.fr>
+
+ * parse.y (TYPENAME): Rename as tTYPENAME to avoid the clash with
+ decl.h's TYPENAME.
+ * spew.c, lex.c: Adjust.
+ * parse.y (explicit_instantiation): Add empty action to override
+ the default $$ = $1 where it introduces a type clash.
+
+2002-06-14 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (begin_for_stmt): Push the 'for' scope before
+ adding the FOR_STMT.
+
+ C++ ABI changes.
+ * class.c (build_base_field): Set DECL_PACKED.
+ (layout_class_type): Don't use tail padding of PODs.
+ * mangle.c (write_unqualified_name): Fix template conversion op
+ mangling.
+
+2002-06-16 Richard Henderson <rth@redhat.com>
+
+ PR opt/6793
+ * tree.c (cp_cannot_inline_tree_fn): Don't short-circuit test
+ after template instantiation.
+
+2002-06-16 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h, decl2.c (flag_ms_extensions): Move to c-common.
+
+2002-06-15 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * cp-tree.h (compiler_error): Remove declaration.
+ * lex.c (compiler_error): Remove definition.
+
+2002-06-14 Steve Ellcey <sje@cup.hp.com>
+
+ * g++spec.c (LIBUNWIND): New.
+ (lang_specific_driver): Add it if USE_UNWIND_EXCEPTIONS is set.
+
+2002-06-13 Jessica Han <jessica@cup.hp.com>
+
+ * class.c (build_vtable): Use TARGET_VTABLE_ENTRY_ALIGN.
+ (build_vtbl_initializer): Honor TARGET_VTABLE_DATA_ENTRY_DISTANCE.
+ (build_vbase_offset_vtbl_entries): Likewise.
+ * rtti.c (build_headof): Likewise.
+ (get_tinfo_decl_dynamic): Likewise.
+ (create_pseudo_type_info): Likewise.
+
+2002-06-12 Stan Shebs <shebs@apple.com>
+
+ * mpw-config.in: Remove file, no longer used.
+ * mpw-make.sed: Ditto.
+
+2002-06-07 Zack Weinberg <zack@codesourcery.com>
+
+ * decl2.c: Update call to cpp_handle_option.
+
+2002-06-07 H.J. Lu (hjl@gnu.org)
+
+ * decl2.c (flag_use_cxa_atexit): Set to DEFAULT_USE_CXA_ATEXIT.
+
+2002-06-06 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (cp_error_at): Fix typo.
+
+2002-06-04 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (cp_diagnostic_starter): Adjust call.
+ (maybe_print_instantiation_context): Change prototype to take a
+ 'diagnostic_info *'.
+ (print_instantiation_full_context): Likewise.
+ (print_instantiation_partial_context): Likewise.
+ (cp_diagnostic_starter): Likewise.
+ (cp_diagnostic_finalizer): Likewise.
+ (cp_print_error_function): Likewise.
+ (cp_printer): Take a secondary parameter as a 'text_info *'.
+ Remove output_state savings. Adjust calls.
+
+2002-06-03 Geoffrey Keating <geoffk@redhat.com>
+
+ * pt.c (inline_parm_levels): Mark for GC.
+
+ * mangle.c (start_mangling): Allocate G.substitutions here...
+ (init_mangle): ... rather than here.
+ (finish_mangling): Clear the varray pointer when done with it.
+ * spew.c (yylexstring): Don't use VARRAY_FREE.
+ * search.c (bfs_walk): Don't use VARRAY_FREE.
+ * decl2.c (pending_statics): Use gengtype to mark.
+ (deferred_fns): Likewise.
+ (ssdf_decls): Likewise.
+ (init_decl2): Delete.
+ * decl.c (pop_from_top_level): Don't use VARRAY_FREE.
+ (cxx_init_decl_processing): Don't call init_decl2.
+ (cxx_pop_function_context): Don't use VARRAY_FREE.
+ * cp-tree.h (struct saved_scope): No need for special marking
+ of varrays.
+ (struct language_function): Likewise.
+ (local_classes): Use gengtype to mark.
+ (init_decl2): Delete prototype.
+ * class.c (init_class_processing): Don't use
+ ggc_add_tree_varray_root.
+ (build_vtbl_initializer): Don't use VARRAY_FREE.
+
+ * decl.c (typename_compare): Don't use same_type_p.
+
+ * decl.c: Include hashtab.h instead of hash.h.
+ (typename_hash): Update to use htab_h.
+ (typename_compare): Likewise.
+ (typename_htab): Use gengtype to mark.
+ (build_typename_type): Update to use htab_h.
+ * Make-lang.in (cp/decl.o): Use HASHTAB_H instead of hash.h.
+
+ * Make-lang.in (gt-cp-tree.h): New rule.
+ (cp/tree.o): Depend on gt-cp-tree.h.
+ * config-lang.in (gtfiles): Add cp/tree.c.
+ * tree.c: Include gt-cp-tree.h.
+ (list_hash_table): Use gengtype to mark.
+ (init_tree): Use gengtype to mark trees.
+
+ * Make-lang.in (cp/decl.o): Add debug.h dependency.
+ * call.c (struct z_candidate): Use gengtype.
+ (USER_CONV_CAND): Use WRAPPER_ZC.
+ (convert_class_to_reference): Use build_zc_wrapper.
+ (build_type_conversion_1): Likewise.
+ (build_over_call): Use WRAPPER_ZC.
+ (add_warning): Use build_zc_wrapper.
+ * cp-lang.c (LANG_HOOKS_MARK_TREE): Delete.
+ * cp-tree.h (struct lang_identifier): Use gengtype.
+ (struct template_parm_index_s): Likewise.
+ (struct ptrmem_cst): Likewise.
+ (struct tree_binding): Likewise.
+ (struct tree_overload): Likewise.
+ (struct tree_srcloc): Likewise.
+ (struct tree_wrapper): Likewise. Also modify to have a pointer
+ to struct z_candidate rather than void.
+ (enum cp_tree_node_structure_enum): New.
+ (union lang_tree_node): New.
+ (cxx_mark_tree): Delete prototype.
+ (cp_tree_node_structure): New prototype.
+ (build_ptr_wrapper): Delete prototype.
+ (build_int_wrapper): Delete prototype.
+ (build_zc_wrapper): New prototype.
+ * decl.c: Include debug.h
+ (cxx_mark_tree): Delete.
+ (cp_tree_node_structure): New.
+ * tree.c (build_ptr_wrapper): Delete.
+ (build_int_wrapper): Delete.
+ (build_zc_wrapper): New.
+
+ * cp-tree.h [! ENABLE_TREE_CHECKING] (LANG_TYPE_PTRMEM_CHECK):
+ Correct typo. Patch from k_fukui@highway.ne.jp.
+
+ * semantics.c (current_stmt_tree): Update for change to
+ struct language_function.
+ (finish_mem_initializers): Likewise.
+ * decl.c (cxx_init_decl_processing): Don't set mark_lang_status.
+ * cp-tree.h (struct language_function): Rename from
+ cp_language_function. Change all uses.
+ (cp_function_chain): Don't need to cast.
+
+ * class.c (duplicate_tag_error): Reset discriminator.
+ (check_bases_and_members): Update for data structure changes.
+ * cp-tree.h (struct lang_id2): Use gengtype.
+ (flagged_type_tree): Likewise.
+ (SET_LANG_ID): Use GGC on struct lang_id2.
+ (struct cp_language_function): Use gengtype. Remove field
+ 'x_vcalls_possible_p'.
+ (current_vcalls_possible_p): Delete.
+ (struct lang_type_header): New.
+ (struct lang_type_class): Rename from struct lang_type. Include
+ struct lang_type_header.
+ (struct lang_type_ptrmem): New.
+ (struct lang_type): New.
+ (LANG_TYPE_CLASS_CHECK): New. Use it in all the appropriate macros.
+ (LANG_TYPE_PTRMEM_CHECK): New. Use it in all the appropriate macros.
+ (TYPE_SET_PTRMEMFUNC_TYPE): Set discriminator, update for changes.
+ (struct lang_decl_flags): Use gengtype. Add discriminators.
+ (struct lang_decl): Use gengtype. Add and use discriminators.
+ Update the macros that reference moved fields.
+ (LANG_DECL_U2_CHECK): New function. Use it when appropriate.
+ (SET_DECL_THUNK_P): Set discriminator too.
+ (clear_inline_text_obstack): Delete prototype.
+ (finish_inline_definitions): Delete prototype.
+ (mark_pending_inlines): Delete prototype.
+ (lang_check_failed): New prototype.
+ * decl.c (struct named_label_use_list): Use gengtype.
+ (struct named_label_list): Likewise.
+ (mark_binding_level): Delete.
+ (mark_named_label_lists): Delete.
+ (push_local_name): Set discriminator on DECL_LANG_SPECIFIC.
+ (cxx_init_decl_processing): Use generated marker routine.
+ (begin_destructor_body): Delete dead set to
+ current_vcalls_possible_p.
+ (mark_lang_function): Delete.
+ (mark_cp_function_context): Delete.
+ (lang_mark_tree): Use generated marker routines.
+ * decl2.c (start_objects): Set discriminator when setting
+ GLOBAL_INIT_PRIORITY.
+ * lex.c (retrofit_lang_decl): Set discriminators.
+ (copy_lang_type): Update for changes to lang_type structure.
+ (cp_make_lang_type): Set discriminator.
+ * parse.y: Use gengtype on YYLVAL. Don't use dots in identifiers.
+ * search.c: Include ggc.h.
+ * semantics.c (anon_aggr_type_p): Use the macro, don't hand-code it.
+ (finish_inline_definitions): Delete.
+ * spew.c (struct token): Use gengtype.
+ (struct token_chunk): New.
+ (struct unparsed_text): Use gengtype. Store tokens in chunks.
+ (struct feed): Use gengtype.
+ (feed_obstack): Delete.
+ (feed): Mark as GC root.
+ (pending_inlines): Mark as GC root.
+ (pending_inlines_tail): Likewise.
+ (processing_these_inlines): Likewise.
+ (token_obstack): Make static.
+ (first_token): Likewise.
+ (init_spew): Don't initialize deleted things; use gengtype for roots.
+ (clear_inline_text_obstack): Delete.
+ (feed_input): Use GC for struct feed. Update for changes to
+ struct unparsed_text.
+ (mark_pending_inlines): Delete.
+ (next_token): Rename from add_token. Change all callers. Update
+ for changes to struct unparsed_text.
+ (space_for_token): New.
+ (remove_last_token): New.
+ (alloc_unparsed_text): New.
+ (snarf_block): Take an unparsed_text. Update for changes to struct
+ unparsed_text.
+ (snarf_method): Update for changes to struct unparsed_text.
+ (snarf_defarg): Update for changes to struct unparsed_text.
+ * tree.c (lang_check_failed): New.
+
+ * Make-lang.in (gt-cp-call.h gt-cp-decl2.h gt-cp-parse.h
+ gt-cp-pt.h gt-cp-repo.h gt-cp-spew.h): New rules.
+ (cp/spew.o): Add dependency on gt-<filename>.h.
+ (cp/decl2.o): Add dependency on gt-<filename>.h.
+ (cp/call.o): Add dependency on gt-<filename>.h.
+ (cp/pt.o): Add dependency on gt-<filename>.h.
+ (cp/repo.o): Add dependency on gt-<filename>.h.
+ (cp/parse.o): Add dependency on gt-<filename>.h.
+ * call.c: Use gengtype for roots.
+ * config-lang.in (gtfiles): Add cp-tree.h decl.h lex.h call.c
+ decl2.c parse.y pt.c repo.c spew.c.
+ * cp-tree.h: Use gengtype for roots.
+ (struct saved_scope): Use GGC, gengtype.
+ (cp_parse_init): Delete prototype.
+ (init_pt): Delete prototype.
+ * decl.c: Use gengtype for roots.
+ (mark_saved_scope): Delete.
+ (cxx_init_decl_processing): Don't call deleted initilisation
+ routines.
+ (signed_size_zero_node): Delete, unused.
+ * decl.h: Use gengtype for roots.
+ * decl2.c: Use gengtype for roots.
+ * lex.h: Use gengtype for roots.
+ * parse.y: Use gengtype for roots.
+ (cp_parse_init): Delete.
+ * pt.c: Use gengtype for roots.
+ (init_pt): Delete.
+ * repo.c: Use gengtype for roots.
+ * spew.c: Use gengtype for roots.
+
+ * Make-lang.in: Allow for filename changes. Add gtype-cp.h.
+ (cp/decl.o): Add dependency on gtype-cp.h.
+ * decl.c: Remove use of add_deletable_root, use GTY marker instead.
+ Include gtype-cp.h. Allow for filename changes.
+
+ * Make-lang.in (cp/gt-decl.h): Generate using gengtype.
+ (cp/decl.o): Add cp/gt-decl.h dependency.
+ * config-lang.in (gtfiles): New.
+ * tree.h: Rename struct binding_level to struct cp_binding_level.
+ * decl.c: Rename struct binding_level to struct cp_binding_level.
+ Include cp/gt-decl.h.
+ (struct cp_binding_level): Use gengtype.
+ (make_binding_level): Use GGC on struct cp_binding_level.
+ (mark_binding_level): Use gt_ggc_m_cp_binding_level.
+ (cxx_init_decl_processing): Mark free_binding_level as
+ deletable.
+
+ * decl.c (mark_cp_function_context): Update calling sequence.
+
+ * decl.c (start_function): Don't free 'struct
+ cp_language_function'.
+ (pop_cp_function_context): Likewise.
+ (save_function_data): Allocate it using GC.
+ * semantics.c (genrtl_start_function): Don't free 'struct
+ cp_language_function'.
+
+2002-05-31 Matthew Woodcraft <mattheww@chiark.greenend.org.uk>
+
+ * lang-specs.h: Use cpp_debug_options.
+
+2002-05-28 Zack Weinberg <zack@codesourcery.com>
+
+ * mangle.c, tree.c: Include real.h.
+ * Make-lang.in: Update dependency lists.
+
+2002-05-25 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * lex.c: Don't include c-lex.h.
+ * parse.y, spew.c: Don't include c-lex.h; include c-pragma.h.
+
+2002-05-23 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * spew.c (yyungetc, snarf_block): Remove indent_level handling.
+
+2002-05-22 Richard Henderson <rth@redhat.com>
+
+ * decl.c (obscure_complex_init): Check for VAR_DECL
+ before using DECL_THREAD_LOCAL.
+
+2002-05-22 Richard Henderson <rth@redhat.com>
+
+ * decl.c (check_tag_decl): Handle RID_THREAD.
+ (obscure_complex_init): Reject run-time init of tls.
+ (grokvardecl, grokdeclarator): Handle RID_THREAD.
+ * lex.c (reswords): Add __thread.
+ (rid_to_yy): Map RID_THREAD to SCSPEC.
+
+2002-05-22 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_POST_OPTIONS): Use c_common_post_options.
+ * cp-tree.h (cxx_post_options): Kill.
+ * cp-lex.c (cxx_post_options): Kill.
+
+2002-05-21 Richard Henderson <rth@redhat.com>
+
+ * lex.c (rid_to_yy): Add RID_THREAD.
+
+2002-05-21 Alexandre Oliva <aoliva@redhat.com>
+
+ * init.c (build_vec_init): Test for trivial copy-assignment when
+ copy-assigning arrays.
+
+2002-05-20 Andreas Jaeger <aj@suse.de>
+
+ * init.c (build_default_init): Remove unused variable.
+
+2002-05-20 Alexandre Oliva <aoliva@redhat.com>
+
+ * call.c (any_strictly_viable): New.
+ (build_new_op): Use it for COMPOUND_EXPR and ADDR_EXPRs.
+
+2002-05-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * error.c (dump_type) [TYPEOF_TYPE]: Fix parenthesis printing.
+
+2002-05-19 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/186, DR 259
+ * pt.c (do_decl_instantiation): Don't complain explicit
+ instantiation after explicit specialization.
+ (do_type_instantiation): Likewise.
+
+2002-05-19 Alexandre Oliva <aoliva@redhat.com>
+
+ * cp-tree.h (complete_type_or_diagnostic): Changed prototype,
+ renamed from...
+ (complete_type_or_else): ... this. Redefined as macro.
+ (cxx_incomplete_type_diagnostic): Declare.
+ (cxx_incomplete_type_error): Define as macro.
+ * init.c (build_delete): Warn about incomplete types other than
+ void, and use the built-in operator delete for them.
+ * typeck.c (complete_type_or_diagnostic): Renamed from
+ complete_type_or_else. Added warn_only argument, passed to...
+ * typeck2.c (cxx_incomplete_type_diagnostic): ... this. Print
+ warnings or errors depending on new warn_only argument. Renamed
+ from...
+ (cxx_incomplete_type_error): ... this. New implementation in
+ terms of cxx_incomplete_type_diagnostic.
+
+2002-05-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/6611
+ * decl2.c (import_export_decl): If we clear
+ DECL_NOT_REALLY_EXTERN, make sure DECL_EXTERNAL is set.
+
+2002-05-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ PR c++/6620
+ * pt.c (verify_class_unification): Don't check if PARM is template
+ parameter dependent. Simplify.
+ (unify) [TEMPLATE_PARM_INDEX]: Handle when ARG is a template
+ parameter dependent expression.
+
+2002-05-14 Jason Merrill <jason@redhat.com>
+
+ * rtti.c (get_tinfo_decl): Don't call comdat_linkage.
+ Do set DECL_COMDAT.
+ (synthesize_tinfo_var): Take the public decl.
+ (create_real_tinfo_var): Likewise. Check DECL_COMDAT.
+ (emit_tinfo_decl): Adjust. Call import_export_decl.
+ * decl2.c (import_export_decl): Simplify tinfo decl handling.
+
+2002-05-14 Alexandre Oliva <aoliva@redhat.com>
+
+ * cp-tree.h (struct lang_type): Added non_zero_init.
+ (CLASSTYPE_NON_ZERO_INIT_P): New macro.
+ (zero_init_p, force_store_init_value, build_forced_zero_init): Declare.
+ * class.c (check_field_decls): Test non_zero_init.
+ * cvt.c (convert_to_pointer_force): Use cp_convert_to_pointer for
+ zero-to-NULL conversions.
+ * decl.c (obscure_complex_init): Don't reset DECL_INITIAL of a
+ type that needs zero-initialization without zeros.
+ (check_initializer_decl): Compute zero-initializer for types
+ that require a non-trivial one.
+ * init.c (build_forced_zero_init): New function.
+ (build_default_init): Use it.
+ * tree.c (zero_init_p): New function.
+ * typeck2.c (force_store_init_value): New function.
+ (process_init_constructor): Create non-trivial zero-initializers
+ for array members and class fields.
+
+2002-05-14 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * lang-specs.h: Remove redundant -lang-c++.
+
+2002-05-13 Jason Merrill <jason@redhat.com>
+
+ * class.c (build_vtbl_ref_1): Use fixed_type_or_null.
+ (fixed_type_or_null): See through reference vars.
+ (build_base_path): Vtable contents are constant.
+ * typeck.c (get_member_function_from_ptrfunc): Likewise.
+
+2002-05-12 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (ok_to_generate_alias_set_for_type): Backend-created
+ structs are safe.
+
+2002-05-09 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (flag_ansi): Remove.
+ * decl2.c (flag_ansi): Remove.
+ (cxx_decode_option): Set flag_iso and flag_undef.
+
+2002-05-09 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Reorganize.
+ Use subtraction rather than a bitmask to get the index.
+ * cvt.c (cp_convert_to_pointer): Bail on an error_mark_node.
+
+ * pt.c (tsubst_expr) [ASM_STMT]: Copy ASM_INPUT_P.
+
+2002-05-07 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * Make-lang.in (decl2.o): Update.
+ * cp-tree.h (warn_multichar): Remove.
+ * decl2.c: Include c-common.h.
+ (warn_multichar): Remove.
+
+2002-05-03 Jason Merrill <jason@redhat.com>
+
+ * tree.c (build_cplus_array_type): Only const and volatile get
+ special handling.
+
+ * decl.c (BOOL_TYPE_SIZE): Move default to defaults.h.
+
+2002-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ ABI change, returning simple classes from functions.
+ * class.c (finish_struct_bits): Only mark TREE_ADDRESSABLE if
+ TYPE_HAS_TRIVIAL_INIT_REF is false or
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR is true.
+
+2002-04-30 Jason Merrill <jason@redhat.com>
+
+ PR debug/6436
+ * decl.c (grokdeclarator): Don't override TYPE_NAME of an
+ anonymous class with a typedef if there are attributes.
+
+2002-04-29 Paul Eggert <eggert@twinsun.com>
+
+ * parse.y (nomods_initdcl0): Replace $<ttype>3 with $<ttype>$.
+
+2002-04-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/6477
+ * decl.c (follow_tag_typedef): Check if TYPE_NAME (original) is
+ non-NULL first.
+
+2002-04-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6492
+ * pt.c (tsubst_friend_class): If the friend has an explicit scope,
+ enter that scope before name lookup.
+
+ PR c++/6486
+ * method.c (do_build_copy_constructor): Avoid building
+ cv-qualified reference types.
+
+2002-04-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5719
+ * decl.c (grok_op_properties): Assignment ops don't have to return
+ by value. operator% should.
+
+2002-04-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ PR c/6343
+ * decl.c (duplicate_decls): Call merge_weak.
+
+2002-04-26 Richard Henderson <rth@redhat.com>
+
+ * parse.y (malloced_yyss, malloced_yyvs): New.
+ (yyoverflow): Re-add. Set them.
+ (free_parser_stacks): New.
+
+2002-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6497
+ * method.c (do_build_assign_ref): Pass a derivation to
+ build_method_call when calling base class assignment operators.
+
+2002-04-26 Richard Henderson <rth@redhat.com>
+
+ * parse.y (yyoverflow): Revert.
+
+2002-04-26 Richard Henderson <rth@redhat.com>
+
+ PR c/3581
+ * parse.y (string): Remove. Update all uses to use STRING
+ instead, and not call combine_strings.
+ * rtti.c (tinfo_name): Use fix_string_type.
+ * semantics.c (finish_asm_stmt): Don't call combine_strings.
+ * spew.c (yylexstring): New.
+ (read_token): Use it.
+
+2002-04-25 Richard Henderson <rth@redhat.com>
+
+ PR c/2161
+ * parse.y (yyoverflow): New.
+
+2002-04-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/5607
+ * search.c (check_final_overrider): No longer static.
+ * class.c (update_vtable_entry_for_fn): Call it.
+ * cp-tree.h: Adjust.
+
+2002-04-25 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_SET_YYDEBUG): Remove.
+ * cp-tree.h (cxx_set_yydebug): Die.
+ * lex.c (YYDEBUG): Get from c-lex.h.
+ (cxx_set_yydebug): Remove.
+ * parse.y: Include c-lex.h.
+ (YYDEBUG): Get from c-lex.h.
+
+2002-04-24 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6438.
+ * cvt.c (convert_to_void): Don't unconditionally make COND_EXPRs
+ void.
+
+2002-04-24 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_COMMON_ATTRIBUTE_TABLE,
+ LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE, LANG_HOOKS_ATTRIBUTE_TABLE):
+ Redefine.
+ * cp-tree.h (cp_attribute_table): Rename.
+ * decl.c (lang_attribute_table): Remove declaration.
+ (cxx_init_decl_processing): Don't set it.
+ * tree.c (cp_attribute_table): Rename.
+
+2002-04-24 Jason Merrill <jason@redhat.com>
+
+ PR c++/6331
+ * method.c (do_build_copy_constructor): Use cp_build_qualified_type.
+ * typeck.c (build_modify_expr): Allow arrays to differ in cv-quals.
+ The pedwarn for array assignment is now unconditional.
+ * tree.c (build_cplus_array_type_1): Still process simple array types
+ normally in templates.
+
+ PR c++/6395
+ * decl.c (make_rtl_for_nonlocal_decl): Don't mess with #pragma i/i
+ stuff for comdats.
+
+2002-04-23 Jakub Jelinek <jakub@redhat.com>
+
+ * parse.y (check_class_key): Allow KEY to be union/enum/struct/class
+ node with attributes.
+
+2002-2-23 David O'Brien <obrien@FreeBSD.org>
+
+ * g++spec.c (MATH_LIBRARY_PROFILE, LIBSTDCXX_PROFILE): Add.
+ Use MATH_LIBRARY_PROFILE and LIBSTDCXX_PROFILE if profile flag given.
+
+2002-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/6256:
+ * pt.c (tsubst_friend_class): Handle templates with explicit
+ nested names.
+
+ PR c++/6331:
+ * typeck.c (merge_types): Remember the cv-qualification of pointer
+ types when merging them.
+
+2002-04-20 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_FUNCTION_INIT,
+ LANG_HOOKS_FUNCTION_FREE, LANG_HOOKS_FUNCTION_MARK): Redefine.
+ * cp-tree.h (cxx_push_function_context, cxx_pop_function_context,
+ cxx_mark_function_context): New.
+ * decl.c (push_cp_function_context, pop_cp_function_context,
+ mark_cp_function_context): Rename for consistency.
+ (cxx_init_decl_processing): Don't set old hooks.
+
+2002-04-19 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * call.c (convert_type_from_ellipsis): Rename, update.
+ * cp-lang.c (LANG_HOOKS_TYPE_PROMOTES_TO): Redefine.
+ * cp-tree.h (convert_type_from_ellipsis): Rename.
+ * decl.c (cxx_init_decl_processing): Don't set hook.
+
+2002-04-18 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * call.c (build_new_method_call): Update.
+ * cp-lang.c (LANG_HOOKS_INCOMPLETE_TYPE_ERROR): Redefine.
+ * cp-tree.h (cxx_incomplete_type_error): New.
+ * decl.c (grokdeclarator, grokparms): Update.
+ * decl2.c (check_classfn): Update.
+ * pt.c (tsubst): Update.
+ * typeck.c (complete_type_or_else, expr_sizeof,
+ decay_conversion): Update.
+ * typeck2.c (incomplete_type_error): Rename.
+ (add_exception_specifier): Update.
+
+2002-04-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/5658
+ * search.c (setup_class_bindings): A class template qualifies as a
+ type binding.
+
+2002-04-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/6316
+ * decl2.c (finish_file): Clear DECL_EXTERNAL in a separate loop
+ before expanding.
+
+2002-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (begin_init_stmts): Remove commented out code.
+ (finish_init_stmts): Set STMT_EXPR_NO_SCOPE.
+ * semantics.c (begin_gobal_stmt_expr): Adjust call to
+ expand_start_stmt_expr.
+
+2002-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (register_dtor_fn): Pass the address of dso_handle, not
+ dso_handle itself, to __cxa_atexit.
+
+2002-04-15 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * error.c (cxx_print_error_function): Adjust call to macros.
+
+2002-04-14 Jakub Jelinek <jakub@redhat.com>
+
+ * class.c (layout_virtual_bases): Do all dsize computation on trees.
+
+2002-04-14 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Don't do
+ gratuitious division and multiplication on
+ ptrmemfunc_vbit_in_delta targets.
+
+2002-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5373.
+ * semantics.c (finish_expr_stmt): Remember the type of the
+ expression before any conversions are performed.
+
+2002-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5189.
+ * call.c (add_template_candidate_real): Do not treat member
+ templates as copy constructors.
+
+2002-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (duplicate_decls): Do not copy the RTL for a variable
+ declaration if the old variable had an incomplete type and the new
+ variable does not.
+ (complete_vars): Do not call layout_decl for completed variables.
+
+2002-04-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * decl.c (duplicate_decls): Don't try to unify an implicit typedef
+ with an explicit one.
+ (follow_tag_typedef): New.
+ (lookup_tag): Use it to extract the tag of an explicit typedef.
+ (xref_tag): Likewise.
+
+2002-04-11 Andrew Haley <aph@redhat.com>
+
+ * typeck.c (type_after_usual_arithmetic_conversions):
+ If two types have the same variant, return immediately.
+ When two floating-point operands are the same precision:
+ convert to float if one of the operands is float;
+ if neither operand is one of the standard types, return the type
+ of the first operand.
+
+2002-04-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5507
+ * decl.c (make_typename_type): Remove implicit typenameness.
+
+2002-04-09 Jason Merrill <jason@redhat.com>
+
+ PR optimization/6189
+ * semantics.c (genrtl_start_function): Don't free
+ DECL_SAVED_FUNCTION_DATA for inline functions.
+
+ * init.c (build_member_call): For now, don't convert to
+ intermediate base if it would cause an error.
+
+2002-04-08 Paolo Carlini <pcarlini@unitus.it>
+
+ * parse.y (namespace_qualifier, maybe_identifier,
+ begin_explicit_instantiation, end_explicit_instantiation,
+ apparent_template_type, .finish_template_type,
+ do_id, maybe_init, defarg_again, component_decl_1):
+ Add ending ';', in accordance with POSIX.
+
+2002-04-06 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/5571
+ * class.c (layout_class_type): Remember incomplete static
+ variables.
+ (finish_struct_1): Call complete_vars, not
+ hack_incomplete_structures.
+ * cp-tree.h (hack_incomplete_structures): Rename to ...
+ (complete_vars): ... this.
+ (struct saved_scope): Remove incomplete.
+ (namespace_scope_incomplete): Remove.
+ * decl.c (struct binding_level): Remove incomplete.
+ (incomplete_vars): New variable.
+ (mark_binding_level): Don't mark incomplete.
+ (print_binding_level): Don't print it.
+ (mark_saved_scope): Don't mark incomplete.
+ (pushdecl): Use maybe_register_incopmlete_var.
+ (cxx_init_decl_processing): Register incomplete_vars for GC.
+ (start_decl_1): Clarify error message.
+ (hack_incomplete_vars): Remove.
+ (maybe_register_incomplete_var): New function.
+ (complete_vars): Likewise.
+
+2002-04-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/4934
+ * error.c (dump_expr) [CONVERT_EXPR]: Make sure TREE_TYPE (t) is
+ set before checking it.
+
+ PR c++/525
+ * init.c (build_member_call): Use build_scoped_ref.
+ (resolve_offset_ref): Likewise.
+ * call.c (build_scoped_method_call): Likewise.
+ * tree.c (maybe_dummy_object): Kludge around current_class_type being
+ wrong.
+ * typeck2.c (build_scoped_ref): Return the binfo via binfo_p parm.
+ * cp-tree.h: Adjust.
+
+ * init.c (push_base_cleanups): Just use build_scoped_method_call.
+
+ PR c++/6179
+ * method.c (implicitly_declare_fn): Pass unqualified type to
+ synthesize_exception_spec.
+
+2002-04-04 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_TRUTHVALUE_CONVERSION): Redefine.
+ * cvt.c: Update comment.
+ * init.c (expand_cleanup_for_base): Update.
+ * semantics.c (finish_parenthesized_expr): Update.
+ * typeck.c (cp_truthvalue_conversion): Update.
+
+2002-04-04 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (finish_eh_cleanup): New fn.
+ * cp-tree.h: Add prototype.
+ * init.c (perform_member_init, expand_cleanup_for_base): Use
+ finish_eh_cleanup.
+ * cp-tree.def (SUBOBJECT, CTOR_STMT): Remove.
+ * cp-tree.h: Remove references.
+ * decl.c (begin_constructor_body, end_constructor_body): Likewise.
+ * dump.c (cp_dump_tree): Likewise.
+ * pt.c (tsubst_expr): Likewise.
+ * semantics.c (genrtl_ctor_stmt, genrtl_subobject): Remove.
+ (cp_expand_stmt): Remove handling of CTOR_STMT and SUBOBJECT.
+ * tree.c (cp_statement_code_p): Likewise.
+
+ * init.c (build_new_1): Set CLEANUP_EH_ONLY on deleting cleanup.
+
+ PR c++/5636
+ * semantics.c (nullify_returns_r): Just set CLEANUP_EH_ONLY on
+ cleanup for nrv.
+
+ PR c++/5104
+ * typeck.c (comptypes) [FUNCTION_TYPE]: Don't compare exception
+ specifiers.
+ [METHOD_TYPE]: Use same code as FUNCTION_TYPE.
+
+2002-04-03 Richard Henderson <rth@redhat.com>
+
+ * cp-lang.c (cxx_warn_unused_global_decl): New.
+ (LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL): New.
+
+2002-04-03 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): Redefine.
+ * tree.c (init_tree): Don't set hook.
+
+2002-04-03 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/5998:
+ * decl.c (duplicate_decls): Don't mess with assembler names when
+ redeclaring builtin functions as static.
+
+2002-04-01 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * call.c (build_addr_func): Update.
+ * class.c (resolve_address_of_overloaded_function): Update.
+ * cp-lang.c (LANG_HOOKS_MARK_ADDRESSABLE): Redefine.
+ * cp-tree.h (cxx_mark_addressable): New.
+ * decl.c (register_dtor_fn, cxx_maybe_build_cleanup): Update.
+ * decl2.c (build_cleanup): Update.
+ * except.c (build_throw): Update.
+ * init.c (resolve_offset_ref): Update.
+ * pt.c (convert_nontype_argument): Update.
+ * semantics.c (finish_asm_stmt, simplify_affr_init_exprs_r): Update.
+ * typeck.c (decay_conversion, build_array_ref, build_unary_op,
+ unary_complex_lvalue): Update.
+ (mark_addressable): Rename.
+
+2002-04-01 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/5998:
+ * decl.c (duplicate_decls): Overwrite the RTL when (and only
+ when) overwriting a built-in function. Don't use COPY_DECL_RTL,
+ but follow the SET_DECL_RTL idiom used elsewhere in the function.
+
+2002-04-01 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_SIGNED_TYPE, LANG_HOOKS_UNSIGNED_TYPE,
+ LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE): New.
+ * decl.c (grokdeclarator): Update.
+ * mangle.c (write_integer_cst): Update.
+ * typeck.c (build_binary_op): Update.
+
+2002-03-31 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_UNSAFE_FOR_REEVAL): Redefine.
+ * lex.c (cxx_init): Don't set hook.
+
+2002-03-31 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * Make-lang.in (error.o): Update.
+ * cp-lang.c (LANG_HOOKS_PRINT_ERROR_FUNCTION): Redefine.
+ * cp-tree.h (struct diagnostic_context): Predeclare.
+ (cxx_print_error_function): New.
+ * error.c: Include langhooks-def.h.
+ (lang_print_error_function): Rename. Update.
+ (init_error): Don't set hook.
+
+2002-03-29 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIZE):
+ Redefine.
+ * cvt.c (cp_convert_to_pointer, type_promotes_to): Use new hooks.
+ * decl.c (finish_enum): Similarly.
+ * error.c (dump_type): Similarly.
+ * lex.c (cxx_init): Similarly.
+ * mangle.c (write_builtin_type): Similarly.
+ * typeck.c (comptypes): Similarly.
+
+2002-03-28 Roger Sayle <roger@eyesopen.com>
+
+ PR c++/5998:
+ * decl.c (cxx_init_decl_processing): Re-enable built-in functions
+ in the g++ front-end.
+ (duplicate_decl): Allow redefinition of anticipated built-ins.
+ Fix inlining problem by over-writing the old DECL_RTL.
+ (lookup_namespace_name): Fail to find an identifier in the
+ specified namespace if its still anticipated.
+ (builtin_function_1): New function split out from builtin_function
+ to create a builtin in the current namespace with given context.
+ (builtin_function): Call builtin_function_1 to define the
+ appropriate builtins in both the std and global namespaces.
+ (select_decl): Don't test for anticipated decls here.
+ (unqualified_namespace_lookup): Instead ignore them whilst
+ searching through scopes and namespaces.
+ * decl2.c (do_nonmember_using_decl): If a using declaration
+ specifies an anticipated built-in function, mark it as no longer
+ anticipated in that scope.
+ (ambiguous_decl): Avoid resolving to an anticipated decl.
+ * lex.c (do_scoped_id): Fail to find an identifier in the global
+ namespace if its still anticipated.
+
+2002-03-29 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_MAKE_TYPE): Redefine.
+ * cp-tree.h (cp_make_lang_type): Rename.
+ * lex.c (cp_make_lang_type): Rename.
+ (make_aggr_type): Update.
+ * tree.c (init_tree): Don't set make_lang_type_fn.
+
+2002-03-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/6073
+ * class.c (finish_struct_1): Update static field's DECL_MODE even
+ if its type is a variant of t.
+
+2002-03-27 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES): Redefine.
+ * cp-tree.h (cxx_insert_default_attributes): New.
+ * decl.c (insert_default_attributes): Rename.
+
+2002-03-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/4884
+ * call.c (build_op_delete_call): Allow for the fact the placement
+ may be a COMPOUND_EXPR.
+
+2002-03-27 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_EXPAND_EXPR): Redefine.
+ * cp-tree.h (init_cplus_expand): Remove.
+ (cxx_expand_expr): New.
+ * expr.c (cplus_expand_expr): Rename cxx_expand_expr,
+ fix prototype.
+ (init_cplus_expand): Remove.
+ * lex.c (cxx_init): Don't call init_cplus_expand.
+
+2002-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/4884.
+ * init.c (build_new_1): Allow for the fact the result of
+ build_function_call may be a COMPOUND_EXPR.
+
+2002-03-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5682
+ * cp-tree.h (BINFO_PRIMARY_P): Explain meaning better.
+ (dfs_skip_nonprimary_vbases_unmarkedp): Remove.
+ (dfs_skip_nonprimary_vbases_markedp): Remove.
+ * search.c (get_shared_vbase_if_not_primary): Remove.
+ (dfs_skip_nonprimary_vbases_unmarkedp): Remove.
+ (dfs_skip_nonprimary_vbases_markedp): Remove.
+ (dfs_unmarked_real_bases_queue_p): Just get the canonical binfo.
+ (dfs_marked_real_bases_queue_p): Likewise.
+
+2002-03-26 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_MARK_TREE): Redefine.
+ * cp-tree.h (cxx_mark_tree): New.
+ * decl.c (lang_mark_tree): Rename cxx_mark_tree.
+
+2002-03-25 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (cxx_maybe_build_cleanup): New.
+ * decl.c (destroy_local_var, hack_incomplete_structures): Update.
+ (maybe_build_cleanup): Rename cxx_maybe_build_cleanup.
+ * tree.c (build_target_expr): Update.
+ * cp-lang.c (LANG_HOOKS_MAYBE_BUILD_CLEANUP): Redefine.
+
+2002-03-24 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c (cxx_decode_option): Handle -E.
+ * lang-specs.h (default_compilers): Preprocess with cc1plus.
+ * lex.c (cxx_init): Exit quickly if c_common_init returns NULL.
+
+2002-03-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/6037
+ * decl.c (start_enum): Don't set TREE_ADDRESSABLE on TREE_LIST node.
+
+2002-03-23 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * error.c (dump_type): Be careful about implicit typenames.
+
+2002-03-21 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ PR C++/3656
+ * semantics.c (finish_base_specifier): Handle erronous base
+ classes.
+
+2002-03-22 Zack Weinberg <zack@codesourcery.com>
+
+ * error.c: Always use REAL_VALUE_TO_DECIMAL; don't test
+ REAL_IS_NOT_DOUBLE.
+
+2002-03-22 Jeff Knaggs <jknaggs@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc): Scale idx down to
+ an index into the vtable_entry array regardless of
+ TARGET_PTRMEMFUNC_VBIT_LOCATION.
+
+2002-03-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree.c (cp_cannot_inline_tree_fn): Same.
+
+2002-03-21 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (pushdecl, pushlevel, poplevel, set_block,
+ insert_block, getdecls, global_bindings_p): New.
+
+2002-03-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4361
+ * mangle.c (struct globals) Add internal_mangling_p member.
+ (write_template_param): Do internal mangling, if needed.
+ (mangle_conv_op_name_for_type): Request internal mangling.
+
+2002-03-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/2136
+ * init.c (build_delete): Check access for a member op delete here.
+ * decl2.c (delete_sanity): Not here.
+
+2002-03-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/5118
+ * class.c (get_vfield_name): Use the constructor_name.
+
+2002-03-20 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_DECL_PRINTABLE_NAME): Redefine.
+ * cp-tree.h (lang_printable_name): Rename.
+ * error.c (lang_decl_name): Use new hook.
+ * lex.c (cxx_init): Remove old hook.
+ * pt.c (tsubst_decl): Use new hook.
+ * tree.c (lang_printable_name): Rename.
+
+2002-03-18 Eric Botcazou <ebotcazou@multimania.com>
+
+ PR c++/3882
+ * pt.c (tsubst_decl): Move __PRETTY_FUNCTION__ handling...
+ (tsubst_expr) [DECL_STMT]: ...here. And substitute the initializer
+ only after recording the declaration.
+
+2002-03-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/2039
+ * init.c (resolve_offset_ref): Hand off to build_component_ref.
+
+ PR c++/4222, c++/5995
+ * call.c (build_over_call): Fix empty class logic.
+
+ PR c++/3870
+ * cp-tree.h (struct saved_scope): Add last_parms field.
+ * decl.c (maybe_push_to_top_level): Save last_function_parms.
+ (pop_from_top_level): Restore it.
+
+ PR c++/4377
+ * mangle.c (write_expression): Strip NOP_EXPRs sooner. Also strip
+ NON_LVALUE_EXPRs.
+
+ PR c++/4003
+ * pt.c (tsubst_friend_function): Use decl_namespace_context.
+
+ PR c++/3948 -- C++ ABI change, followup to 2001-12-18 patch.
+ * class.c (finish_struct_bits): Also set TREE_ADDRESSABLE for a
+ type with a nontrivial destructor.
+
+2002-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/4460
+ * class.c (build_base_path): Virtual base layout is fixed in
+ in-charge [cd]tors.
+
+2002-03-17 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_PARSE_FILE): Redefine.
+ * parse.y (yyparse): Remove macro.
+
+2002-03-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/5757
+ * init.c (build_new_1): Pass the right pointer to op delete.
+
+2002-03-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4361
+ * cp-tree.h (CLASSTYPE_METHOD_VEC): Document where templated
+ conversion operators go.
+ (struct lang_decl_flags): Add template_conv_p and unused
+ bitfields.
+ (DECL_TEMPLATE_CONV_FN_P): New macro.
+ * call.c (build_user_type_conversion_1): Don't check second type
+ conversion of overload set first.
+ * class.c (add_method): Make sure templated conversion operators
+ all end up on slot 2.
+ * lex.c (do_identifier): A conversion operator token might be
+ satisfied by a templated conversion operator.
+ * pt.c (check_explicit_specialization): Use
+ CLASSTYPE_FIRST_CONVERSION_SLOT.
+ (template_parm_this_level_p): New function.
+ (push_template_decl_real): Determine DECL_TEMPLATE_CONV_FN_P.
+ * search.c (lookup_fnfields_1): Template conversions will be on
+ the first slot.
+ * typeck.c (build_component_ref): Preserve the type of an
+ conversion operator name on the overload type.
+ (build_x_function_call): Retrieve the conversion operator name.
+
+2002-03-15 Richard Henderson <rth@redhat.com>
+
+ * init.c (build_new_1): Use size_binop instead of cp_build_binary_op.
+
+2002-03-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLEANUP_DECL): Remove.
+ (CLEANUP_EXPR): Likewise.
+ * decl.c (destroy_local_var): Simplify.
+ (maybe_build_cleanup): Tidy.
+ * dump.c (cp_dump_tree): Remove handling of CLEANUP_STMT.
+ * semantics.c (cp_expand_stmt): Likewise.
+ * cp/tree.c (cp_statement_code_p): Likewise.
+
+2002-03-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/5857
+ * decl.c (duplicate_decls): Use merge_types instead of common_type.
+ * typeck.c (common_type): Just hand off to
+ type_after_usual_arithmetic_conversions and
+ composite_pointer_type.
+ (merge_types): New fn.
+ (commonparms): Use it instead of common_type.
+ (type_after_usual_arithmetic_conversions): Also handle COMPLEX_TYPE.
+ (composite_pointer_type): Also handle attributes.
+ * cp-tree.h: Declare merge_types.
+
+ * decl.c (make_rtl_for_nonlocal_decl): Also defer COMDAT
+ variables.
+ * decl2.c (maybe_make_one_only): Also mark the decl as needed.
+
+2002-03-14 Richard Henderson <rth@redhat.com>
+
+ * decl.c: Include c-pragma.h.
+ (start_decl, start_function): Invoke maybe_apply_pragma_weak.
+ * Make-lang.in: Update dependencies.
+
+2002-03-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/5908
+ * call.c (build_over_call): Set TREE_NO_UNUSED_WARNING too.
+ * cvt.c (convert_to_void): Preserve TREE_NO_UNUSED_WARNING.
+
+2002-03-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * mangle.c (write_builtin_type): Handle 128-bit integers even if
+ they are not a standard integer type.
+
+2002-03-12 Richard Sandiford <rsandifo@redhat.com>
+
+ * cp-tree.h (init_init_processing): Remove declaration.
+ * init.c (BI_header_type, init_init_processing): Remove old ABI stuff.
+ * decl.c (cxx_init_decl_processing): Don't call init_init_processing.
+
+2002-03-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-lang.c (tree_code_type, tree_code_length, tree_code_name):
+ Define.
+ * decl.c (duplicate_decls): Use TREE_CODE_LENGTH, not
+ tree_code_length.
+ * lex.c (cplus_tree_code_type, cplus_tree_code_length,
+ cplus_tree_code_name): Delete.
+ (cxx_init): Don't call add_c_tree_codes, instead set
+ lang_unsafe_for_reeval. Don't try to copy into the various
+ tree_code arrays.
+
+2002-03-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5659
+ * decl.c (xref_tag): Don't set CLASSTYPE_DECLARED_CLASS here.
+ * decl2.c (handle_class_head): Set CLASSTYPE_DECLARED_CLASS for
+ definitions.
+
+2002-03-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ Revert 2001-03-26 Nathan Sidwell <nathan@codesourcery.com>,
+ DR209 is now not a defect.
+ * cp-tree.h (skip_type_access_control): Remove.
+ * decl.c (grokdeclarator): Do type access control for friend
+ declarations.
+ * semantics.c (decl_type_access_control): Don't reset
+ current_type_lookups.
+ (save_type_access_control): Always save the lookups.
+ (skip_type_access_control): Remove.
+ (finish_class_definition): Don't change type_lookups.
+
+2002-03-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ Revert 2000-12-01 Nathan Sidwell <nathan@codesourcery.com>,
+ It is incorrect.
+ * typeck.c (build_static_cast): Compare non-qualified types
+ with pointer to member conversions.
+
+2002-03-11 Dan Nicolaescu <dann@ics.uci.edu>
+ Daniel Berlin <dan@dberlin.org>
+
+ * cp-lang.c (ok_to_generate_alias_set_for_type): New function.
+ (cxx_get_alias_set): Use it.
+
+2002-03-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (stabilize_expr): Prototype.
+
+2002-03-08 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ * cp-tree.h (CLEAR_BINFO_MARKED): Make both parts of
+ conditional return void.
+
+2002-03-08 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_UNSAVE): Redefine.
+ * cp-tree.h (cxx_unsave): New.
+ * tree.c (cp_unsave): Rename cxx_unsave, update prototype.
+ (init_tree): Update.
+
+2002-03-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (cxx_init_decl_processing): Use ARRAY_SIZE in lieu of
+ explicit sizeof/sizeof.
+ * decl2.c (cxx_decode_option): Likewise.
+ * lex.c (init_reswords, REDUCE_LENGTH, TOKEN_LENGTH): Likewise.
+
+2002-03-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/775
+ * decl.c (lookup_tag): Only reject enum/class mismatch, not
+ class/union mismatch.
+ * parse.y (check_class_key): New function.
+ (structsp): Call it.
+
+2002-03-01 Michael Matz <matz@suse.de>
+
+ * typeck.c (cp_pointer_int_sum): Complete inner type which is
+ used later by size_in_bytes().
+
+2002-03-01 Phil Edwards <pme@gcc.gnu.org>
+
+ * cp-tree.h: Require __GNUC__ to be #defined.
+ (build_init): Add missing prototype.
+
+2002-03-01 Jason Merrill <jason@redhat.com>
+
+ * except.c: Don't include decl.h or obstack.h. Do include
+ tree-inline.h.
+ (build_throw): Destroy temporaries from the thrown
+ expression before calling __cxa_throw. Construct a thrown
+ temporary directly into the exception object.
+ (stabilize_throw_expr): New function.
+ (wrap_cleanups_r): New function.
+ * tree.c (stabilize_expr): New function.
+ * init.c (build_init): New function.
+ * Make-lang.in (cp/except.o): Adjust .h deps.
+
+2002-02-28 Jason Merrill <jason@redhat.com>
+
+ * search.c (lookup_base_r): Don't clear is_non_public just because
+ we found a friendly scope.
+
+ * decl.c (finish_function): Only warn about missing return
+ statement with -Wreturn-type.
+
+2002-02-28 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * class.c (build_clone): Update.
+ * cp-lang.c (LANG_HOOKS_DUP_LANG_SPECIFIC_DECL): Redefine.
+ * cp-tree.h (cxx_dup_lang_specific_decl): New.
+ * lex.c (copy_lang_decl): Rename cxx_dup_lang_specific_decl.
+ (copy_decl): Update.
+ * method.c (make_thunk): Update.
+
+2002-02-27 Zack Weinberg <zack@codesourcery.com>
+
+ * decl2.c: Delete traditional-mode-related code copied from
+ the C front end but not used, or used only to permit the
+ compiler to link.
+
+2002-02-24 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ PR c++/4093
+ * cp-tree.h (SET_BINFO_MARKED): Cast false part of condition
+ to void.
+
+2002-02-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/5746
+ * semantics.c (finish_switch_cond): Don't call get_unwidened
+ if error_mark_node.
+
+2002-02-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2645, DR 295
+ * cp-tree.h (tsubst_flags_t): Add tf_ignore_bad_quals,
+ tf_keep_type_decl.
+ (make_typename_type): Use tsubst_flags_t.
+ * decl.c (make_typename_type): Adjust. Return non-artificial
+ TYPE_DECLs, if required.
+ (grokdeclarator): Simplify CVR qualification handling. Allow bad
+ qualifiers on typedef types.
+ * decl2.c (handle_class_head): Adjust make_typename_type call.
+ * parse.y (nested_name_specifier): Likewise.
+ (typename_sub0): Likewise.
+ (typename_sub1): Likewise.
+ * pt.c (convert_template_argument): Adjust make_typename_type
+ return value.
+ (tsubst): Adjust cp_build_qualified_type_real calls.
+ (check_cv_quals_for_unify): Cope with allowing bad qualifications
+ on template type parms.
+ (instantiate_decl): Recheck substitutions to give warnings on bad
+ qualifications.
+ * tree.c (cp_build_qualified_type_real): Use tf_allow_bad_quals.
+
+2002-02-21 Aldy Hernandez <aldyh@redhat.com>
+
+ * cp/decl.c (duplicate_decls): Merge always_inline attribute.
+
+ * cp/tree.c (cp_cannot_inline_tree_fn): Do not inline at -O0
+ unless DECL_ALWAYS_INLINE.
+
+2002-02-20 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck.c (cp_pointer_int_sum): Renamed from
+ pointer_int_sum, call pointer_int_sum.
+
+2002-02-20 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (duplicate_decls): Return 0 if issued error about
+ redeclaration.
+
+2002-02-19 Jason Merrill <jason@redhat.com>
+
+ ABI change: Mangle `void (A::*)() const' as
+ M1AKFvvE, not MK1AFvvE.
+ * mangle.c (write_function_type): Write cv-quals for member
+ function type here.
+ (write_pointer_to_member_type): Not here.
+
+2002-02-18 Jason Merrill <jason@redhat.com>
+
+ * pt.c (do_type_instantiation): Don't pedwarn if in_system_header.
+ (do_decl_instantiation): Likewise.
+
+2002-02-17 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ PR c++/5685
+ * decl.c (duplicate_decls): Make warning unconditional
+ if duplicate default argument declarations are present.
+
+2002-02-17 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck.c (build_binary_op) [BIT_XOR_EXPR]: Remove explicit
+ shortening.
+
+2002-02-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Set typedef_decl for all TYPE_DECLs,
+ remove incorrect comment. Move #if 0'd code to common path. Use
+ IMPLICIT_TYPENAME_P. Simplify & reformat ARRAY_TYPE duplication.
+
+2002-02-13 Jason Merrill <jason@redhat.com>
+
+ * decl.c (builtin_function): Set TREE_THIS_VOLATILE on return fns.
+ (finish_function): Don't warn if current_function_returns_null.
+
+ * typeck2.c (digest_init): Do handle values of vector type.
+
+ * typeck2.c (digest_init, process_init_constructor): Treat vectors
+ like arrays.
+
+2002-02-11 Jason Merrill <jason@redhat.com>
+
+ * parse.y (reserved_declspecs): Don't handle attributes.
+ (reserved_typespecquals): Handle them here.
+ * Make-lang.in (parse.c): Adjust expected conflicts.
+
+2002-02-08 Jakub Jelinek <jakub@redhat.com>
+
+ * parse.y (primary, primary_no_id): Use compstmt_or_stmtexpr
+ instead of compstmt.
+ (compstmt_or_stmtexpr): Renamed from compstmt.
+ (compstmt): In addition to compstmt_or_stmtexpr clear last_expr_type.
+
+2002-02-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ Rename instantiate_type_flags to tsubst_flags_t & expand use.
+ * cp-tree.h (instantiate_type_flags): Rename to ...
+ (tsubst_flags_t): ... here. Rename itf_complain to tf_error,
+ add tf_warning flag.
+ (instantiate_type): Adjust prototype.
+ (tsubst, tsubst_expr, tsubst_copy, lookup_template_class,
+ do_type_instantiation, cp_build_qualified_type_real): Likewise.
+ cp_build_qualified_type: Adjust.
+ * class.c (instantiate_type): Adjust parameter. Rename itf_* to
+ tf_*.
+ * call.c (standard_conversion): Rename itf_* to tf_*.
+ (reference_binding): Likewise.
+ (convert_like_real): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_reference): Likewise.
+ * decl.c (lookup_namespace_name): Use tf_* flags.
+ (make_typename_type): Likewise.
+ (grokdeclarator): Likewise.
+ * pt.c (convert_nontype_argument): Adjust COMPLAIN usage.
+ (coerce_template_template_parms, convert_template_argument,
+ coerce_template_parms, maybe_get_template_decl_from_type_decl,
+ lookup_template_class, tsubst_friend_function, tsubst_friend_class,
+ instantiate_class_template, tsubst_template_arg_vector,
+ tsubst_template_parms, tsubst_aggr_type, tsubst_default_argument,
+ tsubst_decl, tsubst_arg_types, tsubst_function_type,
+ tsubst_call_declarator_parms, tsubst, tsubst_copy, tsubst_expr,
+ instantiate_template, fn_type_unification,
+ resolve_overloaded_unification, verify_class_unification,
+ unify, get_bindings_real, do_type_instantiation,
+ regenerate_decl_from_template, instantiate_decl,
+ tsubst_initializer_list, tsubst_enum,
+ get_mostly_instantiated_function_type,
+ invalid_nontype_parm_type_p): Likewise.
+ * tree.c (cp_build_qualified_type_real): Likewise.
+ * typeck.c (build_binary_op): Rename itf_* to tf_*.
+ (build_ptrmemfunc): Likewise.
+ (convert_for_assignment): Likewise.
+
+2002-02-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/109
+ * decl.c (grokdeclarator): Allow friend declarations from
+ dependent types.
+ * decl2.c (handle_class_head): Don't push into template parm contexts.
+ * pt.c (push_template_decl_real): Template parm contexts are never
+ being defined.
+
+2002-02-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * class.c: Include target.h.
+ (check_bitfield_decl): Disregard EMPTY_FIELD_BOUNDARY,
+ BITFIELDS_NBYTES_LIMITED and PCC_BITFIELD_TYPE_MATTERS for MS
+ bit-field layout.
+ * Make-lang.in: Adjust deps.
+
+2002-02-05 Jason Merrill <jason@redhat.com>
+
+ * error.c (dump_type): Be more helpful about VECTOR_TYPE.
+
+2002-02-04 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (begin_switch_stmt): Clear SWITCH_TYPE.
+ (finish_switch_cond): Set SWITCH_TYPE.
+
+2002-02-04 Richard Henderson <rth@redhat.com>
+
+ * method.c (use_thunk): Always initialize the block tree. Reindent.
+ * semantics.c (expand_body): Emit thunks after function, not before.
+
+2002-02-04 Jason Merrill <jason@redhat.com>
+
+ * decl.c (start_function): Call cplus_decl_attributes immediately
+ after grokdeclarator.
+
+ * decl.c (start_function): Combine DECL_RESULT handling code.
+
+2002-02-03 Jason Merrill <jason@redhat.com>
+
+ * xref.c: Remove.
+ * Make-lang.in (CXX_OBJS): Remove cp/xref.o
+ (cp/xref.o): Remove dependencies.
+ * class.c (finish_struct_1, check_methods): Don't call xref fns.
+ (finish_struct_1): Likewise.
+ * friend.c (make_friend_class): Likewise.
+ * lex.c (cxx_init, cxx_finish, extract_interface_info): Likewise.
+ * spew.c (read_process_identifier): Likewise.
+
+2002-02-01 Jason Merrill <jason@redhat.com>
+
+ PR c++/4872
+ * decl.c (finish_function): Warn about a non-void function with
+ no return statement and no abnormal exit.
+ * cp-tree.h (struct cp_language_function): Add returns_abnormally.
+ (current_function_returns_abnormally): New macro.
+ * call.c (build_call): Set it.
+
+ * typeck.c (build_component_ref): Always complain about offsetof
+ constructs on non-PODs. Only make it an error for members of
+ virtual bases.
+
+ * error.c (dump_scope): Don't add TFF_DECL_SPECIFIERS.
+ (dump_function_decl): Always dump parms.
+
+ * decl2.c (finish_static_data_member_decl): Complain about a local
+ class with a static data member.
+
+ PR c++/4286
+ * search.c (lookup_field_1): Don't xref a static data member
+ just because we looked it up.
+
+2002-01-31 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (parse.c): Handle .output file.
+
+ PR c++/3395
+ * decl.c (xref_tag): Remember early attributes in TYPE_ATTRIBUTES,
+ not TREE_TYPE.
+ * semantics.c (finish_class_definition): Adjust.
+
+ Allow attributes in parms and casts.
+ * parse.y (named_parm): Don't strip attrs.
+ (declmods): Remove 'attributes' production.
+ (nonempty_cv_qualifiers): Accept attributes.
+ (ATTRIBUTE): Give precedence.
+ * decl.c (groktypename): Handle attributes.
+ (grokparms): Likewise.
+
+2002-01-29 Jakub Jelinek <jakub@redhat.com>
+
+ * decl2.c (cxx_decode_option): Pass 0 as last argument to
+ cpp_handle_option.
+ * lang-specs.h: Use cpp_unique_options instead of cpp_options
+ when used together with cc1_options.
+
+2002-01-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5132
+ * typeck2.c (digest_init): Make sure non-array core type is
+ instantiated.
+ * decl2.c (reparse_absdcl_as_casts): Just store the type in the
+ constructor, rather than build a new one.
+ (build_expr_from_tree, CONSTRUCTOR case): Be careful with the
+ PURPOSE of constructor elts.
+
+2002-01-23 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in (parse.c): Adjust expected number of
+ shift-reduce conflicts.
+ (decl.o): Depend on diagnostic.h.
+ * decl.c: Include diagnostic.h.
+ (grokdeclarator): Check for null pointer.
+ (finish_function): Don't abort when
+ current_binding_level->parm_flag != 1, if errors have
+ occurred; throw away the statement tree and extra binding
+ levels, and continue.
+ * lex.c (note_list_got_semicolon): Check for null pointer.
+ * method.c (hack_identifier): Just return error_mark_node if
+ value is error_mark_node.
+ * parse.y (primary: TYPEID(type_id)): No need to use
+ TYPE_MAIN_VARIANT here.
+ (handler_seq): Accept an empty list of catch clauses and
+ generate a fake handler block to avoid later crashes.
+ (ansi_raise_identifier): Accept the error token too.
+ * semantics.c (begin_class_definition,
+ finish_class_definition): Check for error_mark_node.
+
+2002-01-23 Zack Weinberg <zack@codesourcery.com>
+
+ * typeck2.c (friendly_abort): Delete definition.
+ * cp-tree.h (friendly_abort): Don't prototype.
+ (my_friendly_assert): Use fancy_abort.
+
+2002-01-23 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ * cp-tree.h (my_friendly_abort): Remove.
+
+2002-01-23 Jakub Jelinek <jakub@redhat.com>
+
+ * spew.c (pending_inlines, pending_inlines_tail,
+ processing_these_inlines): Make static.
+ (mark_pending_inlines): Remove static.
+ (begin_parsing_inclass_inline): If in function, save pi
+ for GC to cp_function_chain->unparsed_inlines instead.
+ (process_next_inline): Likewise.
+ * cp-tree.h (struct cp_language_function): Add unparsed_inlines.
+ (mark_pending_inlines): Add prototype.
+ * decl.c (spew_debug): Remove unused extern.
+ (mark_lang_function): Call mark_pending_inlines.
+
+2002-01-23 Craig Rodrigues <rodrigc@gcc.gnu.org>
+
+ * call.c, class.c, decl.c, decl2.c, error.c, expr.c, friend.c,
+ init.c, lex.c, mangle.c, method.c, pt.c, repo.c, rtti.c, search.c,
+ semantics.c, spew.c, tree.c, typeck.c, typeck2.c, xref.c:
+ Change my_fancy_abort() to abort().
+
+2002-01-23 Jason Merrill <jason@redhat.com>
+
+ PR c++/5453
+ * class.c (fixed_type_or_null): Fix thinko.
+
+ PR c++/3331
+ * init.c (resolve_offset_ref): Use build_indirect_ref.
+
+ * decl2.c (grokclassfn): Don't set DECL_REGISTER on 'this'.
+
+2002-01-22 Jason Merrill <jason@redhat.com>
+
+ * parse.y (function_body): Suppress the block for the outermost
+ curly braces.
+ * decl.c (pushdecl): Don't try to skip it.
+ (begin_function_body): Keep the block we create, not the next one.
+ * init.c (emit_base_init): Don't mess with keep_next_level.
+
+ * class.c (build_base_path): Tweak formatting.
+
+2002-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ Fix regression introduced with patch for c++/775
+ * parse.y (class_head_defn): Check for template specializations
+ with a different class-key.
+
+2002-01-17 Jason Merrill <jason@redhat.com>
+
+ * decl.c (begin_constructor_body, begin_destructor_body): New fns.
+ (begin_function_body): Call them and keep_next_level.
+ * init.c (emit_base_init): Call keep_next_level.
+ * semantics.c (setup_vtbl_ptr): Lose.
+ * cp-tree.h (struct cp_language_function): Remove vtbls_set_up_p.
+ (vtbls_set_up_p): Lose.
+ * pt.c (tsubst_expr, CTOR_INITIALIZER): Call emit_base_init.
+ * method.c (do_build_copy_constructor): Likewise.
+ (synthesize_method): Call finish_mem_initializers.
+ * parse.y (nodecls): Likewise.
+
+ * error.c (dump_type_suffix): Print the exception specs before
+ recursing.
+ (dump_function_decl): Here, too.
+
+ * cp-tree.h (TMPL_PARMS_DEPTH): Cast to signed HOST_WIDE_INT.
+
+2002-01-10 Ira Ruben <ira@apple.com>
+
+ PR c++/907
+ * decl.c (start_method): Handle attrlist.
+
+2002-01-10 Jakub Jelinek <jakub@redhat.com>
+
+ * decl2.c (max_tinst_depth): Increase default limit to 500.
+
+2002-01-10 Graham Stott <grahams@redhat.com>
+
+ * spew.c (YYCHAR): Uppercase macro parameter and add
+ parenthesis.
+ (YYCODE): Likewise.
+ (NAME): Uppercase macro parameter.
+
+2002-01-09 Graham Stott <grahams@redhat.com>
+
+ * decl.h (grokdeclarator): Wrap long line.
+
+ * semantics.c (FINISH_COND): Uppercase macro paramaters and
+ add parenthesis.
+
+2002-01-08 Graham Stott <grahams@redhat.com>
+
+ * xref.c (FILE_NAME_ABSOLUTE_P): Add parenthesis.
+ (PALLOC): Uppercase macro parameter and whitespace.
+ (SALLOC): Uppercase macro parameter.
+ (SFREE): Uppercase macros parameter, add parenthese and
+ whitespace.
+ (STREQL): Uppercase macro parameter and whitespace.
+ (STRNEQ): Likewise.
+ (STRLSS): Likewise.
+ (STRLEQ): Likewise.
+ (STRGTR): Likewise.
+ (STRGEQ): Likewise.
+
+ * call.c (convert_like): Add parenthesis and wrap.
+ (convert_like_with_context): Likewise.
+ (ICS_RANK): Whitespace.
+ (NEED_TEMPORARY_P): Remove parenthesis.
+
+ * class.c (VTT_TOP_LEVEL_P): Uppercase macro parameter and
+ whitespace.
+ (VTT_MARKED_BINFO_P): Likewise.
+
+ * decl.c (BINDING_LEVEL): Add parenthesis.
+ (DEF_OPERATOR): Likewise.
+
+ * mangle.c (MANGLE_TRACE): Add parenthesis.
+ (MANGLE_TRACE_TREE): Likewise.
+ (write_signed_number): Likewise.
+ (write_unsigned_number): Likewise.
+
+ * pt.c (ccat): Uppercase macro parameter.
+ (cat): Likewise
+
+ * search.c (SET_BINFO_ACCESS): Add parenthesis.
+
+2002-01-07 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (coerce_new_type): Downgrade error for size_t mismatch
+ to pedwarn.
+
+ PR c++/3536
+ * method.c (make_thunk): If !flag_weak, give the thunk the
+ function's linkage.
+ (use_thunk): Here, too.
+
+2002-01-07 Graham Stott <grahams@redhat.com>
+
+ * error.c: Update copyright date.
+ (print_scope_operator): Add parenthesis.
+ (print_left_paren): Likewise.
+ (print_right_paren): Likewise.
+ (print_left_bracket): Likewise.
+ (print_right_bracket): Likewise.
+ (print_template_argument_list_start): Likewise.
+ (print_template_argument_list_end): Likewise.
+ (print_non_consecutive_character): Likewise.
+ (print_tree_identifier): Likewise.
+ (print_identifier): Likewise.
+ (NEXT_CODE): Uppercase macro parameter.
+ (ident_fndecl): Delete unused.
+ (GLOBAL_THING): Likewise.
+
+2002-01-06 Graham Stott <grahams@redhat.com>
+
+ * cp-tree.h (VAR_OR_FUNCTION_DECL_CHECK): Add parenthesis.
+ (VAR_FUNCTION_OR_PARM_DECL_CHECK): Likewise.
+ (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK) Likewise.
+ (RECORD_OR_UNION_TYPE_CHECK): Likewise.
+ (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): Likewise.
+ (C_IS_RESERVED_WORD): Uppercase macro parameter.
+ (C_RID_YYCODE) Likewise.
+ (ptrmem_cst): Use rtx.
+ (LOCAL_BINDING_P): Add whitespace.
+ (INHERITED_VALUE_BINDING_P): Likewise.
+ (BINDING_SCOPE): Wrap long line.
+ (BINDING_HAS_LEVEL_P): Remove parenthesis.
+ (BINDING_VALUE): Wrap long line.
+ (BINDING_TYPE): Whitespace.
+ (IDENTIFIER_GLOBAL_VALUE): Add parenthesis.
+ (SET_IDENTIFIER_GLOBAL_VALUE): Likewise.
+ (IDENTIFIER_NAMESPACE_VALUE): Likewise.
+ (SET_IDENTIFIER_NAMESPACE_VALUE: Likewise.
+ (same_type_p): Uppercase macro parameters.
+ (same_type_ignoring_top_level_qualifiers_p): Likewise.
+ (OVL_FUNCTION): Wrap long line.
+ (OVL_CHAIN): Whitespace.
+ (OVL_CURRENT): Add parenthesis and whitespace.
+ (OVL_NEXT): Whitespace.
+ (OVL_USED): Likewise.
+ (IDENTIFIER_TYPE_VALUE): Likewise.
+ (REAL_IDENTIFIER_TYPE_VALUE): Remove parenthesis.
+ (SET_IDENTIFIER_TYPE_VALUE): Add parenthesis and whitespace.
+ (LANG_ID_FIELD): Whitespace.
+ (SET_LANG_ID(NODE,VALUE,NAME): Likewise.
+ (IDENTIFIER_LABEL_VALUE): Whitespace and wrap.
+ (SET_IDENTIFIER_LABEL_VALUE): Whitespace.
+ (IDENTIFIER_IMPLICIT_DECL): Whitespace and wrap.
+ (SET_IDENTIFIER_IMPLICIT_DECL); Whitespace.
+ (IDENTIFIER_ERROR_LOCUS): Whitespace and wrap.
+ (SET_IDENTIFIER_ERROR_LOCUS); Whitespace.
+ (IDENTIFIER_VIRTUAL_P): Likewise.
+ (IDENTIFIER_OPNAME_P): Likewise.
+ (IDENTIFIER_TYPENAME_P): Remove parenthesis.
+ (C_TYPE_FIELDS_READONLY): Uppercase macro parameters.
+ (C_SET_EXP_ORIGINAL_CODE): Likewise.
+ (TYPE_ASSEMBLER_NAME_STRING): Wrap long line.
+ (TYPE_ASSEMBLER_NAME_LENGTH): Likewise.
+ (IS_AGGR_TYPE): Uppercase macro parameter.
+ (CLASS_TYPE_P): Likewise.
+ (IS_AGGR_TYPE_CODE): Uppercase macro parameter and parenthesis.
+ (IS_AGGR_TYPE_2): Whitespace.
+ (TAGGED_TYPE_P): Uppercase macro parameter.
+ (TYPE_BUILT_IN): Whitespace.
+ (TYPE_FOR_JAVA): Likewise.
+ (FUNCTION_ARG_CHAIN): Remove parenthesis.
+ (FUNCTION_FIRST_USER_PARMTYPE): Add parenthesis.
+ (FUNCTION_FIRST_USER_PARAM): Likewise.
+ (PROMOTES_TO_AGGR_TYPE): Whitespace.
+ (DERIVED_FROM_P): Add parenthesis and wrap.
+ (UNIQUELY_DERIVED_FROM_P): Likewise.
+ (ACCESSIBLY_UNIQUELY_DERIVED_P): Likewise.
+ (PUBLICLY_UNIQUELY_DERIVED_P): Likewise.
+ (CLASSTYPE_USE_TEMPLATE): Whitespace.
+ (CLASSTYPE_INLINE_FRIENDS): Remove parenthesis.
+ (TYPE_GETS_DELETE): Add parenthesis.
+ (TYPE_HAS_CONVERSION): Add parenthesis and wrap.
+ (TYPE_HAS_ASSIGN_REF): Likewise,
+ (TYPE_HAS_CONST_ASSIGN_REF): Likewise.
+ (TYPE_HAS_INIT_REF): Likewise.
+ (TYPE_HAS_CONST_INIT_REF): Likewise.
+ (TYPE_BEING_DEFINED): Likewise.
+ (TYPE_LANG_SPECIFIC): Likewise.
+ (CLASSTYPE_RTTI): Likewise.
+ (TYPE_OVERLOADS_CALL_EXPR): Likewise.
+ (TYPE_OVERLOADS_ARRAY_REF): Likewise.
+ (TYPE_OVERLOADS_ARROW): Likewise.
+ (TYPE_USES_MULTIPLE_INHERITANCE): Likewise.
+ (TYPE_USES_VIRTUAL_BASECLASSES): Add parenthesis.
+ (CLASSTYPE_METHOD_VEC): Likewise.
+ (CLASSTYPE_MARKED_N): Likewise.
+ (CLASSTYPE_MARKED): Likewise.
+ (CLASSTYPE_MARKED2): Likewise.
+ (CLASSTYPE_MARKED3): Likewise.
+ (CLASSTYPE_MARKED4): Likewise.
+ (CLASSTYPE_MARKED5): Likewise.
+ (CLASSTYPE_MARKED6): Likewise.
+ (SET_CLASSTYPE_MARKED): Whitespace.
+ (CLEAR_CLASSTYPE_MARKED): Likewise.
+ (SET_CLASSTYPE_MARKED2): Likewise.
+ (CLEAR_CLASSTYPE_MARKED2): Likewise.
+ (SET_CLASSTYPE_MARKED3): Likewise.
+ (CLEAR_CLASSTYPE_MARKED3): Likewise.
+ (SET_CLASSTYPE_MARKED4): Likewise.
+ (CLEAR_CLASSTYPE_MARKED4): Likewise.
+ (SET_CLASSTYPE_MARKED5): Likewise.
+ (CLEAR_CLASSTYPE_MARKED5): Likewise.
+ (SET_CLASSTYPE_MARKED6): Likewise.
+ (CLEAR_CLASSTYPE_MARKED6): Likewise.
+ (CLASSTYPE_TAGS): Likewise.
+ (CLASSTYPE_VSIZE): Likewise.
+ (CLASSTYPE_VBASECLASSES): Likewise.
+ (CANONICAL_BINFO): Add parenthesis.
+ (CLASSTYPE_SIZE(NODE): Likewise.
+ (CLASSTYPE_SIZE_UNIT): Likewise.
+ (CLASSTYPE_ALIGN(NODE): Likewise.
+ (CLASSTYPE_USER_ALIGN): Likewise.
+ (TYPE_JAVA_INTERFACE): Likewise.
+ (CLASSTYPE_PURE_VIRTUALS): Likewise.
+ (CLASSTYPE_NEEDS_VIRTUAL_REINIT): Whitespace and wrap.
+ (TYPE_HAS_DEFAULT_CONSTRUCTOR): Likewise.
+ (CLASSTYPE_HAS_MUTABLE): Likewise.
+ (CLASSTYPE_FRIEND_CLASSES): Likewise. Likewise.
+ (CLASSTYPE_DECLARED_CLASS): Whitespace and wrap.
+ (CLASSTYPE_READONLY_FIELDS_NEED_INIT): Likewise.
+ (CLASSTYPE_REF_FIELDS_NEED_INIT): Likewise.
+ (CLASSTYPE_INTERFACE_ONLY): Likewise.
+ (CLASSTYPE_INTERFACE_KNOWN): Likewise.
+ (CLASSTYPE_INTERFACE_UNKNOWN): Likewise.
+ (SET_CLASSTYPE_INTERFACE_UNKNOWN_X): Likewise.
+ (SET_CLASSTYPE_INTERFACE_UNKNOWN): Likewise.
+ (SET_CLASSTYPE_INTERFACE_KNOWN): Likewise.
+ (CLASSTYPE_DEBUG_REQUESTED): Whitespace and wrap.
+ (BINFO_UNSHARED_MARKED): Whitespace.
+ (BINFO_MARKED): Whitespace and wrap.
+ (SET_BINFO_MARKED): Likewise.
+ (CLEAR_BINFO_MARKED): Likewise.
+ (BINFO_VTABLE_PATH_MARKED): Likewise.
+ (SET_BINFO_VTABLE_PATH_MARKED): Likewise.
+ (CLEAR_BINFO_VTABLE_PATH_MARKED): Likewise.
+ (BINFO_SUBVTT_INDEX): Remove parenthesis.
+ (BINFO_VPTR_INDEX): Likewise.
+ (BINFO_PRIMARY_BASE_OF): Likewise,
+ (CLASSTYPE_VFIELDS): Whitespace.
+ (VF_DERIVED_VALUE): Wrap long line.
+ (NAMESPACE_LEVEL): Whitespace.
+ (CAN_HAVE_FULL_LANG_DECL_P): Remove parenthesis.
+ (DEFARG_POINTER): Whitespace.
+ (DECL_NEEDED_P): Remove parenthesis.
+ (DECL_LANGUAGE): Whitespace.
+ (SET_DECL_LANGUAGE): Add parenthesis.
+ (DECL_CONSTRUCTOR_P): Whitespace and wrap.
+ (DECL_OVERLOADED_OPERATOR_P): Remove parenthesis.
+ (DECL_IN_AGGR_P): Whitespace.
+ (DECL_FRIEND_P): Likewise.
+ (DECL_BEFRIENDING_CLASSES): Likewise.
+ (DECL_STATIC_FUNCTION_P): Whitespace and wrap.
+ (DECL_NONCONVERTING_P): Whitespace.
+ (DECL_PURE_VIRTUAL_P): Likewise.
+ (DECL_NEEDS_FINAL_OVERRIDER_P): Likewise.
+ (DECL_PENDING_INLINE_INFO): Whitespace.
+ (DECL_SORTED_FIELDS): Likewise.
+ (DECL_DEFERRED_FN): Likewise.
+ (DECL_TEMPLATE_INFO): Likewise.
+ (CLASSTYPE_TEMPLATE_INFO): Whitespace and wrap.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO); Likewise.
+ (SET_TYPE_TEMPLATE_INFO): Add parenthesis.
+ (TMPL_ARGS_LEVEL): Likewise.
+ (SET_TMPL_ARGS_LEVEL): Likewise.
+ (INNERMOST_TEMPLATE_PARMS): Whitespace.
+ (C_TYPEDEF_EXPLICITLY_SIGNED): Uppercase macro parameter.
+ (INTEGRAL_CODE_P(CODE): Add parenthesis.
+ (CP_INTEGRAL_TYPE_P): Remove parenthesis.
+ (TYPE_HAS_CONSTRUCTOR): Whitespace.
+ (TREE_HAS_CONSTRUCTOR): Likewise.
+ (TYPE_HAS_DESTRUCTOR): Likewise.
+ (TYPE_HAS_REAL_ASSIGN_REF): Likewise.
+ (TYPE_HAS_COMPLEX_ASSIGN_REF): Likewise.
+ (TYPE_HAS_ABSTRACT_ASSIGN_REF): Likewise.
+ (TYPE_HAS_COMPLEX_INIT_REF): Likewise.
+ (TYPE_HAS_NONTRIVIAL_DESTRUCTOR): Likewise.
+ (TYPE_PTRMEMFUNC_P): Likewise.
+ (TYPE_PTRMEMFUNC_FLAG): Likewise.
+ (TYPE_GET_PTRMEMFUNC_TYPE): Likewise.
+ (TYPE_SET_PTRMEMFUNC_TYPE): Likewise.
+ (TYPE_PTRMEM_CLASS_TYPE): Remove parenthesis.
+ (TYPE_PTRMEM_POINTED_TO_TYPE): Likewise.
+ (DECL_ACCESS): Whitespace.
+ (DECL_GLOBAL_CTOR_P): Remove parenthesis.
+ (DECL_GLOBAL_DTOR_P): Likewise.
+ (GLOBAL_INIT_PRIORITY): Likewise.
+ (DECL_TEMPLATE_PARMS): Likewise.
+ (DECL_TEMPLATE_RESULT): Likewise.
+ (DECL_TEMPLATE_INSTANTIATIONS): Likewise.
+ (DECL_TEMPLATE_SPECIALIZATIONS): Likewise.
+ (DECL_IMPLICIT_TYPEDEF_P): Remove parenthesis.
+ (SET_DECL_IMPLICIT_TYPEDEF_P): Likewise.
+ (PRIMARY_TEMPLATE_P): Add parenthesis.
+ (DECL_USE_TEMPLATE): Whitespace.
+ (CLASSTYPE_IMPLICIT_INSTANTIATION): Likewise.
+ (SET_CLASSTYPE_IMPLICIT_INSTANTIATION): Likewise.
+ (CLASSTYPE_EXPLICIT_INSTANTIATION): Likewise.
+ (SET_CLASSTYPE_EXPLICIT_INSTANTIATION): Likewise.
+ (CALL_DECLARATOR_PARMS): Remove parenthesis.
+ (CALL_DECLARATOR_QUALS): Likewise.
+ (CALL_DECLARATOR_EXCEPTION_SPEC): Likewise.
+ (TEMP_NAME_P): Wrap.
+ (VFIELD_NAME_P): Likewise.
+ (B_SET): Uppercase macro parameters and add parenthesis.
+ (B_CLR): Likewise.
+ (B_TST): Likewise.
+ (LOOKUP_NAMESPACES_ONLY): Uppercase macro parameters.
+ (LOOKUP_TYPES_ONLY): Uppercase macro parameters.
+ (LOOKUP_QUALIFIERS_ONLY): Uppercase macro parameters.
+ (same_or_base_type_p): Likewise.
+ (cp_deprecated): Likewise.
+
+2002-01-05 Richard Henderson <rth@redhat.com>
+
+ * semantics.c (expand_body): Revert last change.
+
+2002-01-04 Jason Merrill <jason@redhat.com>
+
+ PR c++/4122
+ * class.c (update_vtable_entry_for_fn): Set delta to zero for a
+ lost primary.
+
+ * class.c (build_vtbl_initializer): Check for a lost primary
+ before calculating the vtable entry to throw away.
+
+2002-01-02 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (expand_body): Call outlining_inline_function when
+ emitting an inline function out of line.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5116, c++/764 reversion
+ * call.c (build_new_op): Revert the instantiations. They are
+ incorrect.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5089
+ * decl2.c (reparse_absdcl_as_casts): Don't warn about casts to void.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3716
+ * pt.c (tsubst_aggr_type): Move pmf handling into tsubst.
+ (tsubst, case POINTER_TYPE): Handle pmfs here.
+ (tsubst, case OFFSET_TYPE): Check it is not an offset to
+ reference. If it is offset to FUNCTION_TYPE, create a METHOD_TYPE.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/35
+ * cp-tree.h (DECL_LANG_FLAG_0): Used for PARM_DECL too.
+ (DECL_TEMPLATE_PARM_P): A PARM_DECL might be one too.
+ * pt.c (process_template_parm): SET_DECL_TEMPLATE_PARM_P on the
+ PARM_DECL.
+ (tsubst_template_parms): Break up loop statements.
+ (tsubst_decl, case PARM_DECL): Copy DECL_TEMPLATE_PARM_P. Template
+ parm PARM_DECLs don't get promoted.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5123
+ * typeck.c (build_component_ref): Cope with a TEMPLATE_ID_EXPR.
+ (build_x_function_call): Cope with a COMPONENT_REF containing a
+ TEMPLATE_ID_EXPR.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5213
+ * pt.c (convert_template_argument): Be more careful determining
+ when RECORD_TYPE templates are or are not templates.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/775
+ * cp-tree.h (handle_class_head): Adjust prototype.
+ * decl2.c (handle_class_head): Add DEFN_P and NEW_TYPE_P
+ parameters. Use for all class heads.
+ * parse.y (named_class_head_sans_basetype, named_class_head,
+ named_complex_class_head_sans_basetype,
+ named_class_head_sans_basetype_defn,
+ unnamed_class_head): Remove.
+ (class_head, class_head_apparent_template): Recognize class heads
+ (class_head_decl, class_head_defn): New reductions. Process class
+ heads.
+ (structsp): Adjust class definition and class declaration
+ reductions.
+ (maybe_base_class_list): Give diagnostic on empty list.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4379
+ * typeck.c (build_x_unary_op): Don't destroy the OFFSET_REF on a
+ single non-static member.
+ (unary_complex_lvalue): If it cannot be a pointer to member, don't
+ make it so. Check it is not pointer to reference.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5132
+ * decl2.c (reparse_absdcl_as_casts): Don't digest_init if we
+ are processing a template decl.
+
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5116, c++/764
+ * call.c (build_new_op): Make sure template class operands are
+ instantiated. Simplify arglist construction.
+
+2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_user_type_conversion_1): Use my_friendly_assert
+ rather than if ... abort.
+ * cvt.c (convert_to_reference): Likewise.
+ * semantics.c (setup_vtbl_ptr): Likewise.
+ * pt.c (lookup_template_class): Comment typo.
+
+2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5125
+ * pt.c (push_template_decl_real): Make sure DECL has
+ DECL_LANG_SPECIFIC.
+
+2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/335
+ * init.c (resolve_offset_ref): Copy cv qualifiers of this pointer
+ for non-reference fields.
+ * typeck.c (require_complete_type): Use resolve_offset_ref).
+
+2001-12-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/196
+ * parse.y (bad_parm): Better diagnostic when given a SCOPE_REF.
+
+2001-12-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/160
+ * typeck.c (build_modify_expr): Remove old unreachable code & tidy
+ up. Don't stabilize_references when initializing a reference.
+
+2001-12-23 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (lang_f_options): Const-ify.
+
+2001-12-20 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * config-lang.in (diff_excludes): Remove.
+
+2001-12-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/90
+ * typeck.c (build_function_call_real): Use original function
+ expression for errors.
+
+2001-12-18 Jason Merrill <jason@redhat.com>
+
+ PR c++/3242
+ * class.c (add_method): Do compare 'this' quals when trying to match a
+ used function. Don't defer to another used function.
+
+2001-12-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (instantiate_clone): Remove, fold into ...
+ (instantiate_template): ... here. Simplify by removing mutual
+ recursion.
+ * typeck2.c (build_m_component_ref): Don't cv qualify the function
+ pointed to by a pointer to function.
+ * class.c (delete_duplicate_fields_1): Typo.
+
+2001-12-18 Jason Merrill <jason@redhat.com>
+
+ C++ ABI change: destroy value arguments in caller.
+ * semantics.c (genrtl_start_function, genrtl_finish_function): Don't
+ create an extra binding level for the parameters.
+ * decl.c (store_parm_decls): Don't do parameter cleanups.
+
+2001-12-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_new_method_call): Use '%#V'.
+ * error.c (cv_to_string): Use V parameter to determine padding.
+
+2001-12-18 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * call.c, decl2.c, init.c: Use "built-in" and "bit-field"
+ spellings in messages.
+
+2001-12-17 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-tree.h: Delete #defines for cp_error, cp_warning,
+ cp_pedwarn, and cp_compiler_error.
+ * call.c, class.c, cp-tree.h, cvt.c, decl.c, decl2.c, error.c,
+ except.c, friend.c, init.c, lex.c, method.c, parse.y, pt.c,
+ rtti.c, search.c, semantics.c, spew.c, tree.c, typeck.c,
+ typeck2.c: Change calls to the above macros to use their
+ language-independent equivalents: error, warning, pedwarn, and
+ internal_error respectively.
+
+2001-12-16 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c (finish_file): Remove back_end_hook.
+
+2001-12-16 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * ChangeLog.1, ChangeLog.2, ChangeLog, NEWS, call.c, class.c,
+ cp-tree.h, decl.c, decl2.c, except.c, operators.def, optimize.c,
+ pt.c, rtti.c, semantics.c, typeck.c: Fix spelling errors.
+
+2001-12-15 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * lang-options.h: Use American spelling in messages.
+
+2001-12-13 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (parse.h): Separate rule, just depend on parse.c.
+
+ Use cleanups to run base and member destructors.
+ * init.c (push_base_cleanups): New function, split out from...
+ (build_delete): ...here. Lose !TYPE_HAS_DESTRUCTOR code.
+ * decl.c (finish_destructor_body): Move vbase destruction code to
+ push_base_cleanups.
+ (begin_function_body, finish_function_body): New fns.
+ (finish_function): Move [cd]tor handling and call_poplevel to
+ finish_function_body.
+ (pushdecl): Skip the new level.
+ * semantics.c (genrtl_try_block): Don't call end_protect_partials.
+ (setup_vtbl_ptr): Call push_base_cleanups.
+ * method.c (synthesize_method): Call {begin,end}_function_body.
+ * pt.c (tsubst_expr): Handle COMPOUND_STMT_BODY_BLOCK.
+ * cp-tree.h: Declare new fns.
+ * parse.y (function_body, .begin_function_body): New nonterminals.
+ (fndef, pending_inline, function_try_block): Use function_body.
+ (ctor_initializer_opt, function_try_block): No longer has a value.
+ (base_init): Remove .set_base_init token.
+ (.set_base_init, compstmt_or_error): Remove.
+ * Make-lang.in (parse.c): Expect two fewer s/r conflicts.
+
+ * optimize.c (maybe_clone_body): Fix parameter updating.
+
+2001-12-12 Jason Merrill <jason@redhat.com>
+
+ * decl.c (store_parm_decls): Remove parms_have_cleanups cruft.
+ * semantics.c (genrtl_start_function): Don't pass
+ parms_have_cleanups or push an extra binding level.
+ (genrtl_finish_function): Lose cleanup_label cruft.
+
+ * cp-tree.h (struct cp_language_function): Remove x_ctor_label.
+ (ctor_label): Remove.
+ * semantics.c (finish_return_stmt): Lose ctor_label support.
+ * decl.c (finish_constructor_body, mark_lang_function): Likewise.
+ * typeck.c (check_return_expr): Check DECL_DESTRUCTOR_P, not
+ dtor_label.
+
+ * call.c (build_new_method_call): Let resolves_to_fixed_type_p
+ check for [cd]tors.
+ * class.c (fixed_type_or_null, case INDIRECT_REF): Fix.
+
+ * decl.c (finish_function): Check VMS_TARGET, not VMS.
+
+ * decl.c (start_cleanup_fn): Remove redundant pushlevel.
+ (end_cleanup_fn): And poplevel.
+
+ * semantics.c (setup_vtbl_ptr): Always build a CTOR_INITIALIZER
+ if we're in a template.
+
+2001-12-12 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (DESTRUCTOR_DECL_PREFIX, DESTRUCTOR_NAME_P,
+ ANON_PARMNAME_FORMAT, ANON_PARMNAME_P, DESTRUCTOR_NAME_FORMAT,
+ THIS_NAME_P): Delete.
+ * spew.c (read_process_identifier): Remove DESTRUCTOR_NAME_P,
+ THIS_NAME_P and ANON_PARMNAME_P tests from warning about clash
+ with internal naming scheme.
+ * error.c (dump_decl): Remove DESTRUCTOR_NAME_P use.
+
+2001-12-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Deprecated implicit typename use.
+
+2001-12-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/51
+ * parse.y (frob_specs): Indicate it is a language linkage which
+ contained the extern.
+ * decl.c (grokdeclarator): Allow extern language linkage with
+ other specifiers.
+
+2001-12-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/72
+ * decl.c (add_binding): Don't reject duplicate typedefs involving
+ template parameters.
+
+2001-12-10 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * parse.y, semantics.c: Similarly.
+
+2001-12-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/87
+ * cp-tree.h (DECL_COPY_CONSTRUCTOR_P): Use copy_fn_p.
+ (copy_args_p): Rename to ...
+ (copy_fn_p): ... here.
+ (grok_special_member_properties): New function.
+ (grok_op_properties): Lose VIRTUALP parameter.
+ (copy_assignment_arg_p): Remove.
+ * call.c (build_over_call): Use copy_fn_p.
+ * decl.c (grokfndecl): Reformat. Adjust call to
+ grok_op_properties.
+ (copy_args_p): Rename to ...
+ (copy_fn_p): ... here. Reject template functions. Check for pass
+ by value.
+ (grok_special_member_properties): Remember special functions.
+ (grok_ctor_properties): Don't remember them here, just check.
+ (grok_op_properties): Likewise.
+ (start_method): Call grok_special_member_properties.
+ * decl2.c (grokfield): Likewise.
+ (copy_assignment_arg_p): Remove.
+ (grok_function_init): Don't remember abstract assignment here.
+ * pt.c (instantiate_class_template): Call
+ grok_special_member_properties.
+ (tsubst_decl): Adjust grok_op_properties call.
+
+2001-12-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * lex.c (rid_to_yy): Add RID_CHOOSE_EXPR and
+ RID_TYPES_COMPATIBLE_P.
+
+2001-12-08 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Add DIRECT_BIND flag in
+ call to build_aggr_init.
+ * cp-tree.h (DIRECT_BIND): Document new use of DIRECT_BIND.
+
+2001-12-08 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * parse.y: Replace uses of the string non-terminal with STRING.
+ Don't perform string concatentaion here.
+ (string): Remove non-terminal.
+ * semantics.c (finish_asm_stmt): Don't concatenate strings here.
+
+2001-12-05 Jason Merrill <jason@redhat.com>
+
+ * cp-lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING): Define.
+ (LANG_HOOKS_TREE_INLINING_END_INLINING): Define.
+ * tree.c (cp_start_inlining, cp_end_inlining): New fns.
+ * pt.c (push_tinst_level): No longer static.
+ * cp-tree.h: Declare them.
+
+ * init.c (resolve_offset_ref): Don't check access for the base
+ conversion to access a FIELD_DECL.
+
+ * cp-tree.h (TYPE_REFFN_P): New macro.
+ * decl.c (bad_specifiers): Check it, too.
+
+ * rtti.c (create_pseudo_type_info): Set CLASSTYPE_INTERFACE_ONLY
+ on the __*_type_info type if we haven't seen a definition.
+
+2001-12-05 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl.c: Include c-common.h.
+ (shadow_warning): Move to c-common.c.
+
+2001-12-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (duplicate_decls): Don't copy DECL_NO_CHECK_MEMORY_USAGE.
+
+2001-12-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (end_template_parm_list): Clear TREE_CHAIN of each parm.
+
+2001-12-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/164
+ * init.c (sort_base_init): Allow binfos to be directly specified.
+ * method.c (do_build_copy_constructor): Explicitly convert to the
+ base instance.
+ (do_build_assign_ref): Likewise.
+
+2001-12-03 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * decl.c (xref_basetypes): Don't use C99 construct in tag_code
+ declaration and initialization.
+
+2001-12-03 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * typeck2.c: Remove leading capital from diagnostic messages, as
+ per GNU coding standards.
+
+2001-12-03 Mumit Khan <khan@nanotech.wisc.edu>
+
+ PR c++/3394
+ * decl.c (xref_basetypes): Handle attributes between
+ 'class' and name.
+
+2001-12-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/3381
+ * parse.y (named_complex_class_head_sans_basetype): Add new
+ reduction.
+ * Make-lang.in (parse.c): Adjust expected conflict count.
+
+2001-12-03 Jason Merrill <jason@redhat.com>
+
+ * class.c (finish_vtbls): Fill in BINFO_VPTR_FIELD in the
+ immediate binfos for our virtual bases.
+
+2001-12-02 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * call.c (build_java_interface_fn_ref): Similarly.
+ * except.c (is_admissible_throw_operand): Similarly.
+ * init.c (build_java_class_ref): Similarly.
+ * xref.c (open_xref_file): Similarly.
+
+2001-12-01 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * class.c (finish_struct): Remove trailing periods from messages.
+ * decl.c (check_tag_decl): Similarly.
+ * lex.c (cxx_set_yydebug): Similarly.
+ * typeck2.c (friendly_abort): Similarly.
+
+2001-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/3048
+ * cp-tree.h (ovl_member): Remove.
+ * decl2.c (merge_functions): Handle extern "C" functions
+ specially.
+ * tree.c (ovl_member): Remove.
+
+2001-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/4842
+ * class.c (get_basefndecls): Take an IDENTIFIER_NODE, not a
+ FUNCTION_DECL, as input.
+ (mark_overriders): Remove.
+ (warn_hidden): Rework for the new ABI.
+
+2001-11-29 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/3471
+ * call.c (convert_like_real): Do not build additional temporaries
+ for rvalues of class type.
+
+2001-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (UNIQUELY_DERIVED_FROM_P): Use lookup base.
+ (ACCESSIBLY_UNIQUELY_DERIVED_FROM_P): Likewise.
+ (PUBLICLY_UNIQUELY_DERIVED_FROM_P: Likewise.
+ (DERIVED_FROM_P): Likewise.
+ (enum base_access): Renumber, add ba_quiet bit mask.
+ (get_binfo): Remove.
+ (get_base_distance): Remove.
+ (binfo_value): Remove.
+ (ACCESSIBLY_DERIVED_FROM_P): Remove.
+ * call.c (standard_conversion): Use lookup_base.
+ * class.c (strictly_overrides): Likewise.
+ (layout_virtual_bases): Likewise.
+ (warn_about_ambiguous_direct_bases): Likewise.
+ (is_base_of_enclosing_class): Likewise.
+ (add_vcall_offset_vtbl_entries_1): Likewise.
+ * cvt.c (build_up_reference): Adjust comment.
+ * init.c (build_member_call): Reformat.
+ * search.c (get_binfo): Remove.
+ (get_base_distance_recursive): Remove.
+ (get_base_distance): Remove.
+ (lookup_base_r): Tweak.
+ (lookup_base): Add ba_quiet control. Complete the types here.
+ (covariant_return_p): Use lookup_base.
+ * tree.c (binfo_value): Remove.
+ (maybe_dummy_object): Use lookup_base.
+ * typeck.c (build_static_cast): Use lookup_base.
+ (get_delta_difference): Likewise.
+ * typeck2.c (binfo_or_else): Use lookup_base.
+ (build_scoped_ref): Add back error_mark_check.
+ (build_m_component_ref): Use lookup_base.
+
+2001-11-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (c++.generated-manpages): New dummy target.
+
+2001-11-27 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (cp-lang.o): Depends on c-common.h.
+ * cp-lang.c (c-common.h): Include.
+ (LANG_HOOKS_EXPAND_CONSTANT, LANG_HOOKS_SAFE_FROM_P): New hooks.
+ * decl.c (cxx_init_decl_processing): Don't set lang_safe_from_p.
+ * expr.c (init_cplus_expand): Don't set lang_expand_constant.
+
+2001-11-26 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c (c_language): Move to c-common.c.
+ * lex.c (cxx_post_options, cxx_init_options): Use c-common.c
+ functions.
+ (cxx_init): Update.
+
+2001-11-26 Jason Merrill <jason@redhat.com>
+
+ * call.c (joust): Remove COND_EXPR hack.
+
+2001-11-25 Aldy Hernandez <aldyh@redhat.com>
+
+ * search.c (lookup_base_r): Declare bk in variable declaration
+ space.
+
+2001-11-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/3145
+ * class.c (build_vbase_pointer): Remove.
+ (build_vbase_path): Remove.
+ (build_base_path): New function.
+ * cp-tree.h (base_access, base_kind): New enumerations.
+ (build_base_path): Declare.
+ (convert_pointer_to_real): Remove.
+ (convert_pointer_to): Remove.
+ (lookup_base): Declare.
+ (convert_pointer_to_vbase): Remove.
+ * call.c (build_scoped_method_call): Use lookup_base &
+ build_base_path instead of convert_pointer_to_real,
+ get_base_distance & get_binfo.
+ (build_over_call): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_pointer_force): Likewise.
+ (build_up_reference): Likewise.
+ (convert_pointer_to_real): Remove.
+ (convert_pointer_to): Remove.
+ * init.c (dfs_initialize_vtbl_ptrs): Use build_base_path
+ instead of convert_pointer_to_vbase & build_vbase_path.
+ (emit_base_init): Use build_base_path instead of
+ convert_pointer_to_real.
+ (expand_virtual_init): Lose unrequired conversions.
+ (resolve_offset_ref): Use lookup_base and build_base_path
+ instead of convert_pointer_to.
+ * rtti.c (build_dynamic_cast_1): Use lookup_base &
+ build_base_path instead of get_base_distance & build_vbase_path.
+ * search.c (get_vbase_1): Remove.
+ (get_vbase): Remove.
+ (convert_pointer_to_vbase): Remove.
+ (lookup_base_r): New function.
+ (lookup_base): New function.
+ * typeck.c (require_complete_type): Use lookup_base &
+ build_base_path instead of convert_pointer_to.
+ (build_component_ref): Likewise.
+ (build_x_function_call): Likewise.
+ (get_member_function_from_ptrfunc): Likewise.
+ (build_component_addr): Likewise.
+ * typeck2.c (build_scoped_ref): Likewise.
+
+2001-11-22 Bryce McKinlay <bryce@waitaki.otago.ac.nz>
+
+ * cp-tree.h (CP_TYPE_QUALS): Removed.
+ * decl.c (cxx_init_decl_processing): Don't set lang_dump_tree.
+ * cp-lang.c: Set LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN and
+ LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN.
+ * dump.c (cp_dump_tree): Use void* dump_info argument to match
+ lang-hooks prototype.
+ * call.c, cp-tree.h, cvt.c, decl.c, init.c, mangle.c, method.c, pt.c,
+ rtti.c, semantics.c, tree.c, typeck.c, typeck2.c: All references to
+ CP_TYPE_QUALS changed to cp_type_quals.
+ * Make-lang.in: References to c-dump.h changed to tree-dump.h.
+ (CXX_C_OBJS): Remove c-dump.o.
+
+2001-11-21 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/3637
+ * pt.c (lookup_template_class): Ensure that all specializations
+ are registered on the list corresponding to the most general
+ template.
+
+2001-11-20 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (non_reference): Add documentation.
+ (convert_class_to_reference): Do not strip reference types
+ from conversion operators.
+ (maybe_handle_ref_bind): Simplify.
+ (compare_ics): Correct handling of references.
+
+2001-11-19 John Wilkinson <johnw@research.att.com>
+
+ * dump.c (dump_op): New function.
+ (cp_dump_tree): Dump CLASSTYPE_TEMPLATE_SPECIALIZATION. Use
+ dump_op. Dump DECL_MUTABLE, access and staticness for VAR_DECLs.
+ DECL_PURE_VIRTUAL_P, DECL_VIRTUAL_P,
+
+2001-11-19 Mark Mitchell <mark@codesourcery.com>
+
+ PR4629
+ * semantics.c (finish_sizeof): Make sure that expression created
+ while processing a template do not have a type.
+ (finish_alignof): Likewise.
+ * typeck.c (c_sizeof): Likewise.
+ (expr_sizeof): Likewise.
+
+2001-11-18 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * lex.c (cxx_finish): Call c_common_finish.
+ (finish_parse): Remove.
+
+2001-11-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl.c (create_array_type_for_decl): Check if NAME is NULL_TREE
+ when displaying error message about missing array bounds.
+
+2001-11-17 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * mangle.c (write_expression): Handle CAST_EXPR, STATIC_CAST_EXPR,
+ CONST_CAST_EXPR.
+ * operators.def: Add CAST_EXPR, STATIC_CAST_EXPR, CONST_CAST_EXPR.
+
+2001-11-16 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (print_class_statistics): Restore.
+
+2001-11-15 Jason Merrill <jason@redhat.com>
+
+ * method.c (use_thunk): Don't emit debugging information for thunks.
+
+ * parse.y: Add ... IDENTIFIER SCOPE and ... PTYPENAME SCOPE expansions.
+ * decl.c (make_typename_type): Handle getting a class template.
+ * search.c (lookup_field_r): A class template is good enough for
+ want_type.
+
+ * call.c (convert_like_real): Only use cp_convert for the bad part.
+ (standard_conversion): Also allow bad int->enum.
+ * typeck.c (ptr_reasonably_similar): Also allow functions to
+ interconvert. Pointers to same-size integers are reasonably
+ similar.
+
+ * cvt.c (convert_to_void): If we build a new COND_EXPR, always
+ give it void type.
+
+2001-11-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/3154
+ * init.c (sort_base_init): Remove unreachable code.
+ (expand_member_init): Adjust comment to reflect reality. Simplify
+ and remove unreachable code.
+
+2001-11-15 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (init_reswords, cxx_init_decl_processing): New.
+ (cxx_init): Update prototype.
+ * decl.c (init_decl_processing): Rename. Move null node init
+ to its creation time.
+ * lex.c (cxx_init_options): Update.
+ (cxx_init): Combine with old init_parse; also call
+ cxx_init_decl_processing.
+
+2001-11-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * decl.c (check_initializer): Try to complete the type of an
+ array element before checking whether it's complete. Don't
+ complain about arrays with complete element types but an
+ unknown size.
+ (cp_finish_decl): Build the hierarchical constructor before
+ calling maybe_deduce_size_from_array_init.
+
+2001-11-14 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in: Change all uses of $(manext) to $(man1ext).
+
+2001-11-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/4206
+ * parse.y (already_scoped_stmt): Remove.
+ (simple_stmt, WHILE & FOR): Use implicitly_scoped_stmt.
+
+2001-11-12 H.J. Lu <hjl@gnu.org>
+
+ * cvt.c (ocp_convert): Don't warn the address of a weak
+ function is always `true'.
+
+2001-11-09 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_PRINT_DECL, LANG_HOOKS_PRINT_TYPE,
+ LANG_HOOKS_PRINT_STATISTICS, LANG_HOOKS_PRINT_XNODE,
+ LANG_HOOKS_PRINT_IDENTIFIER, LANG_HOOKS_SET_YYDEBUG): Override.
+ * cp-tree.h (print_class_statistics): Remove.
+ (cxx_print_statistics, cxx_print_xnode, cxx_print_decl, cxx_print_type,
+ cxx_print_identifier, cxx_set_yydebug): New.
+ * lex.c (set_yydebug): Rename c_set_yydebug.
+ * ptree.c (print_lang_decl, print_lang_type, print_lang_identifier,
+ lang_print_xnode): Rename.
+ * tree.c (print_lang_statistics): Rename.
+
+2001-11-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (dump_array): Fix format specifier warning.
+
+2001-11-09 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-lang.c (LANG_HOOKS_NAME): Override.
+ (struct lang_hooks): Constify.
+ * lex.c (cxx_init_options): Update.
+ (lang_identify): Remove.
+ * parse.y (language_string): Remove.
+
+2001-11-08 Andreas Franck <afranck@gmx.de>
+
+ * Make-lang.in (CXX_INSTALL_NAME, GXX_CROSS_NAME,
+ DEMANGLER_CROSS_NAME): Handle program_transform_name the way
+ suggested by autoconf.
+ (GXX_TARGET_INSTALL_NAME, CXX_TARGET_INSTALL_NAME): Define.
+ (c++.install-common): Use the transformed target alias names.
+
+2001-11-06 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * Make-lang.in: Update.
+ * cp-lang.c: Include langhooks-def.h.
+
+2001-11-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (tsubst_copy): Call tsubst for TYPEOF_EXPR.
+
+2001-11-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lex.c (copy_lang_type): Add static prototype.
+
+2001-11-02 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (unify): Handle SCOPE_REF.
+
+2001-11-01 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.c (cp_copy_res_decl_for_inlining): Adjust
+ DECL_ABSTRACT_ORIGIN for the return variable.
+
+2001-10-31 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in: Replace $(INTL_TARGETS) with po-generated.
+
+2001-10-28 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * ChangeLog.1, ChangeLog.2, ChangeLog, class.c, decl2.c, search.c,
+ semantics.c, spew.c: Fix spelling errors.
+
+2001-10-27 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl2.c (validate_nonmember_using_decl): Handle NAMESPACE_DECL.
+
+2001-10-25 Zack Weinberg <zack@codesourcery.com>
+
+ * cp-lang.c: Redefine LANG_HOOKS_CLEAR_BINDING_STACK to
+ pop_everything.
+
+2001-10-23 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * cp-lang.c (cxx_get_alias_set): New function.
+ Point LANG_HOOKS_GET_ALIAS_SET to it.
+
+2001-10-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.def (UNBOUND_CLASS_TEMPLATE): New tree node.
+ * cp-tree.h (make_unbound_class_template): Prototype new function.
+ * decl.c (make_unbound_class_template): New function.
+ * decl2.c (arg_assoc_template_arg): Handle UNBOUND_CLASS_TEMPLATE.
+ * error.c (dump_type): Likewise.
+ * mangle.c (write_type): Likewise.
+ * parse.y (template_parm): Likewise.
+ (template_argument): Use make_unbound_class_template.
+ * pt.c (convert_template_argument): Handle UNBOUND_CLASS_TEMPLATE.
+ (tsubst): Likewise.
+ (tsubst_copy): Likewise.
+ (unify): Likewise.
+ * tree.c (walk_tree): Likewise.
+ * typeck.c (comptypes): Likewise.
+
+2001-10-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * xref.c (GNU_xref_member): Use safe-ctype macros and/or fold
+ extra calls into fewer ones.
+
+2001-10-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * decl.c (duplicate_decls): Propagate DECL_UNINLINABLE.
+ Warn when merging inline with attribute noinline.
+ (start_decl, start_function): Warn if inline and attribute
+ noinline appear in the same declaration.
+
+2001-10-16 H.J. Lu <hjl@gnu.org>
+
+ * cp-tree.h (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): Defined
+ for tree checking disabled.
+
+2001-10-16 Hans-Peter Nilsson <hp@axis.com>
+
+ * cp-tree.h (VFIELD_NAME_FORMAT) [NO_DOLLAR_IN_LABEL &&
+ NO_DOT_IN_LABEL]: Adjust to match VFIELD_NAME.
+
+2001-10-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * pt.c (UNIFY_ALLOW_MAX_CORRECTION): Define.
+ (unify): Only handle MINUS_EXPR specially if the above flag is set
+ and the subtracted constant is 1. Clear the flag on recursive calls.
+ Set it when unifying the maximum value in an INTEGER_TYPE's range.
+
+2001-10-15 Richard Sandiford <rsandifo@redhat.com>
+
+ * decl.c (bad_specifiers): Don't allow exception specifications
+ on any typedefs.
+
+2001-10-14 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp/lex.c (init_cp_pragma): Similarly.
+
+2001-10-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (lookup_template_class): Build complete template arguments
+ for BOUND_TEMPLATE_TEMPLATE_PARM.
+
+2001-10-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.h (TYPE_BINFO): Update comment.
+ (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK): New macro.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Use template_info.
+ (TYPENAME_TYPE_FULLNAME): Use TYPE_FIELDS.
+ (copy_type): Prototype new function.
+ * lex.c (copy_lang_decl): Gather tree node statistics.
+ (copy_lang_type): New function.
+ (copy_type): Likewise.
+ (cp_make_lang_type): Create lang_type for
+ BOUND_TEMPLATE_TEMPLATE_PARM. Set TYPE_BINFO for TYPENAME_TYPE
+ and BOUND_TEMPLATE_TEMPLATE_PARM.
+ * pt.c (tsubst): Use copy_type instead of copy_node.
+ * search.c (lookup_field_1): Ignore TYPENAME_TYPE.
+
+2001-10-12 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (determine_specialization): Ignore functions without
+ DECL_TEMPLATE_INFO.
+
+2001-10-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/4476
+ * typeck2.c (abstract_virtuals_error): Ignore incomplete classes.
+
+2001-10-11 Jason Merrill <jason_merrill@redhat.com>
+
+ * typeck2.c (store_init_value): Don't re-digest a bracketed
+ initializer.
+
+ * class.c (finish_struct_anon): Use TYPE_ANONYMOUS_P instead of
+ ANON_AGGR_TYPE_P.
+
+2001-10-11 Richard Henderson <rth@redhat.com>
+
+ * class.c (build_vtable_entry_ref): Create a VTABLE_REF instead
+ of an asm statement.
+ (build_vtbl_ref_1): Split out from build_vtbl_ref.
+ (build_vfn_ref): Use it to handle vtable descriptors before
+ calling build_vtable_entry_ref.
+ * decl2.c (output_vtable_inherit): Use assemble_vtable_inherit.
+
+2001-10-10 Richard Henderson <rth@redhat.com>
+
+ * parse.y (asm_operand): Allow named operands.
+ * semantics.c (finish_asm_stmt): Tweek for changed location
+ of the operand constraint.
+
+2001-10-09 Jason Merrill <jason_merrill@redhat.com>
+
+ * call.c (standard_conversion): Add bad conversion between
+ integers and pointers.
+ (convert_like_real): Don't use convert_for_initialization for bad
+ conversions; complain here and use cp_convert.
+ (build_over_call): Don't handle bad conversions specially.
+ (perform_implicit_conversion): Allow bad conversions.
+ (can_convert_arg_bad): New fn.
+ * cp-tree.h: Declare it.
+ * typeck.c (convert_for_assignment): Use it.
+ (ptr_reasonably_similar): Any target type is similar to void.
+
+2001-10-08 Alexandre Oliva <aoliva@redhat.com>
+
+ * Make-lang.in (CXX_OBJS): Added cp-lang.o.
+ (cp/cp-lang.o): New rule.
+ * cp-tree.h: Declare hooks.
+ * tree.c: Make hooks non-static.
+ (init_tree): Don't initialize hooks here.
+ * lex.c: Likewise. Move definition of lang_hooks to...
+ * cp-lang.c: ... new file.
+
+2001-10-08 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h (struct lang_decl_flags): Remove declared_inline.
+ (DECL_DECLARED_INLINE_P): Use the bit in struct c_lang_decl.
+
+2001-10-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (build_vtable_entry_ref): Const-ify.
+ * decl.c (predefined_identifier,
+ initialize_predefined_identifiers): Likewise.
+ * init.c (build_new_1): Likewise.
+ * lex.c (cplus_tree_code_type, cplus_tree_code_length, resword):
+ Likewise.
+
+2001-10-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * optimize.c (struct inline_data): Moved to ../tree-inline.c.
+ (INSNS_PER_STMT): Likewise.
+ (remap_decl, remap_block, copy_scopy_stmt, copy_body_r): Likewise.
+ (copy_body, initialize_inlined_parameters): Likewise.
+ (declare_return_variable, inlinable_function_p): Likewise.
+ (expand_call_inline, expand_calls_inline): Likewise.
+ (optimize_inline_calls, clone_body): Likewise.
+ * tree.c (walk_tree): Moved to ../tree-inline.c.
+ (walk_tree_without_duplicates): Likewise.
+ (copy_tree_r, remap_save_expr): Likewise.
+
+2001-10-04 Alexandre Oliva <aoliva@redhat.com>
+
+ * Make-lang.in (cp/decl.o, cp/tree.o): Depend on tree-inline.h.
+ (cp/pt.o, cp/semantics.o, cp/optimize.o): Likewise.
+ * cp-tree.h (lang_decl): Moved inlined_fns to tree_decl.
+ (TREE_READONLY_DECL_P, DECL_INLINED_FNS): Moved to ../tree.h.
+ (flag_inline_trees): Moved declaration to ../tree-inline.h.
+ (walk_tree): Moved declaration to ../tree-inline.h.
+ (walk_tree_without_duplicates, copy_tree_r): Likewise.
+ (remap_save_expr): Likewise.
+ * decl.c: Include tree-inline.h.
+ (lang_mark_tree): Don't mark inlined_fns.
+ * decl2.c (flag_inline_trees): Moved defn to ../tree-inline.c.
+ * optimize.c: Include tree-inline.h.
+ (optimize_inline_calls): Move declaration to ../tree.h, as
+ non-static.
+ (remap_decl): Use language-independent constructs and hooks.
+ (remap_block, copy_body_r, declare_return_variable): Likewise.
+ (inlinable_function_p): Likewise. Don't test for
+ DECL_LANG_SPECIFIC before DECL_INLINED_FNS as inlined_fns is
+ no longer language-specific.
+ (optimize_inline_calls): Likewise. Make it non-static. Moved
+ call of dump_function to...
+ (optimize_function): Here...
+ (clone_body): New function, extracted from...
+ (maybe_clone_body): ... here. Build decl_map locally and pass
+ it on to clone_body.
+ * pt.c, semantics.c: Include tree-inline.h.
+ * tree.c: Likewise.
+ (cp_walk_subtrees): New language-specific hook for tree inlining.
+ (cp_cannot_inline_tree_fn, cp_add_pending_fn_decls,
+ cp_is_overload_p, cp_auto_var_in_fn_p,
+ cp_copy_res_decl_for_inlining): Likewise.
+ (walk_tree): Move language-specific constructs into...
+ (cp_walk_subtrees): this new function.
+ (copy_tree_r): Use language-independent constructs and hooks.
+ (init_tree): Initialize tree inlining hooks.
+ (remap_save_expr): Adjust prototype so that the declaration
+ does not require the definition of splay_tree.
+
+2001-10-03 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * rtti.c (get_tinfo_decl): Call typeinfo_in_lib_p with the type used
+ to build the declaration instead of the declaration itself.
+
+2001-10-02 Jason Merrill <jason_merrill@redhat.com>
+
+ * decl2.c (cxx_decode_option): Add 'else'.
+
+ * spew.c (end_input): No longer static.
+ * cp-tree.h: Declare it.
+ * parse.y (datadef): Add "error END_OF_SAVED_INPUT" expansion.
+
+2001-10-02 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * call.c (build_over_call), typeck.c (build_function_call_real):
+ Pass type attributes to check_function_format rather than name or
+ assembler name. Don't require there to be a name or assembler
+ name to check formats.
+
+2001-10-02 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (init_decl_processing): Don't call
+ init_function_format_info. Initialize lang_attribute_table
+ earlier.
+ (builtin_function): Call decl_attributes.
+ (insert_default_attributes): New.
+
+2001-10-01 Jason Merrill <jason_merrill@redhat.com>
+
+ * decl.c (grokdeclarator): Copy array typedef handling from C
+ frontend.
+
+ * decl.c (grokdeclarator): Copy too-large array handling from C
+ frontend.
+
+2001-09-29 Alexandre Oliva <aoliva@redhat.com>
+
+ * config-lang.in (target_libs): Added target-gperf, so that we
+ don't try to build it if C++ is disabled.
+
+2001-09-23 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in (CXX_OBJS): Take out cp/errfn.o.
+ (cp/errfn.o): Delete rule.
+ (cp/error.o): Depend on flags.h.
+ * errfn.c: Delete file.
+ * cp-tree.h: Declare warn_deprecated. Remove definitions of
+ TFF_NAMESPACE_SCOPE, TFF_CLASS_SCOPE, TFF_CHASE_NAMESPACE_ALIAS,
+ and TFF_TEMPLATE_DEFAULT_ARGUMENTS. #define cp_error, cp_warning,
+ cp_pedwarn, and cp_compiler_error to error, warning, pedwarn, and
+ internal_error respectively. Make cp_deprecated into a macro.
+ Don't define cp_printer typedef or declare cp_printers.
+ * error.c: Include flags.h.
+ Delete: struct tree_formatting_info, print_function_argument_list,
+ print_declaration, print_expression, print_function_declaration,
+ print_function_parameter, print_type_id, print_cv_qualifier_seq,
+ print_type_specifier_seq, print_simple_type_specifier,
+ print_elaborated_type_specifier, print_rest_of_abstract_declarator,
+ print_parameter_declaration_clause, print_exception_specification,
+ print_nested_name_specifier, and definition of cp_printers.
+ (locate_error): New function.
+ (cp_error_at, cp_warning_at, cp_pedwarn_at): Moved here and
+ rewritten in terms of locate_error and diagnostic.c.
+ (cp_tree_printer): Rename cp_printer; wire up to *_to_string
+ instead of deleted print_* routines. Handle %C, %L, %O, %Q also.
+ (init_error): Adjust to match.
+
+2001-09-22 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (CXX_C_OBJS): Add attribs.o.
+
+2001-09-21 Richard Henderson <rth@redhat.com>
+
+ * class.c (set_vindex): Mind TARGET_VTABLE_USES_DESCRIPTORS.
+ (build_vtbl_initializer): Likewise.
+ (build_vfn_ref): New.
+ * cp-tree.h: Declare it.
+ * call.c (build_over_call): Use it.
+ * decl2.c (mark_vtable_entries): Mark FDESC_EXPR.
+ * typeck.c (get_member_function_from_ptrfunc): Mind descriptors.
+
+2001-09-21 J"orn Rennecke <amylaar@redhat.com>
+
+ * decl.c (grokdeclarator): Use C syntax for attr_flags declaration.
+
+2001-09-21 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ Table-driven attributes.
+ * decl.c: Rename DECL_MACHINE_ATTRIBUTES to DECL_ATTRIBUTES.
+ * decl2.c (cplus_decl_attributes): Only take one attributes
+ parameter.
+ * cp-tree.c (cplus_decl_attributes): Update prototype.
+ * class.c (finish_struct), decl.c (start_decl, start_function),
+ decl2.c (grokfield), friend.c (do_friend), parse.y
+ (parse_bitfield): Update calls to cplus_decl_attributes.
+ * decl.c (grokdeclarator): Take a pointer to a single ordinary
+ attribute list.
+ * decl.h (grokdeclarator): Update prototype.
+ * decl2.c (grokfield): Take a single ordinary attribute list.
+ * friend.c (do_friend): Likewise.
+ * decl.c (shadow_tag, groktypename, start_decl,
+ start_handler_parms, grokdeclarator, grokparms, start_function,
+ start_method), decl2.c (grokfield, grokbitfield, grokoptypename),
+ parse.y (parse_field, parse_bitfield, component_decl_1), pt.c
+ (process_template_parm, do_decl_instantiation): Pass single
+ ordinary attribute lists around.
+ * decl.c (grokdeclarator): Correct handling of nested attributes.
+ Revert the patch
+ 1998-10-18 Jason Merrill <jason@yorick.cygnus.com>
+ * decl.c (grokdeclarator): Embedded attrs bind to the right,
+ not the left.
+ .
+ * cp-tree.h (cp_valid_lang_attribute): Remove declaration
+ (cp_attribute_table): Declare.
+ * decl.c (valid_lang_attribute): Don't define.
+ (lang_attribute_table): Define.
+ (init_decl_processing): Initialize lang_attribute_table instead of
+ valid_lang_attribute.
+ * tree.c (cp_valid_lang_attribute): Remove.
+ (handle_java_interface_attribute, handle_com_interface_attribute,
+ handle_init_priority_attribute): New functions.
+ (cp_attribute_table): New array.
+ * decl2.c (import_export_class): Don't use
+ targetm.valid_type_attribute.
+
+2001-09-15 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * Make-lang.in (cp/error.o): Depend on real.h
+ * error.c: #include "real.h"
+
+2001-09-15 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * mangle.c (mangle_conv_op_name_for_type): Use concat in lieu of
+ xmalloc/strcpy/strcat.
+
+2001-09-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (warn_extern_redeclared_static, cp_make_fname_decl):
+ Const-ification.
+ * pt.c (tsubst_decl): Likewise.
+
+2001-09-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (lang_f_options): Const-ification.
+ * lex.c (cplus_tree_code_name): Likewise.
+ * spew.c (yyerror): Likewise.
+
+2001-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3986
+ * class.c (force_canonical_binfo_r): Check & move an indirect
+ primary base first.
+ (force_canonical_binfo): Check that it's not already
+ canonical.
+ (mark_primary_virtual_base): Remove BINFO parameter.
+ (mark_primary_bases): Adjust, set BINFO_LOST_PRIMARY_P here.
+
+2001-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove TYPE_NONCOPIED_PARTS.
+ * cp-tree.h (CLASSTYPE_INLINE_FRIENDS): Map onto
+ CLASSTYPE_PURE_VIRTUALS.
+ (TYPE_RAISES_EXCEPTIONS): Map onto TYPE_BINFO.
+ * class.c (duplicate_tag_error): Remove TYPE_NONCOPIED_PARTS.
+ (layout_class_type): Don't call fixup_inline_methods here ...
+ (finish_struct_1): ... call it here.
+
+2001-09-04 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (duplicate_decls): Remove code deadling with
+ DECL_SAVED_INSNS.
+ * decl2.c (finish_file): Likewise.
+ * pt.c (instantiate_decl): Likewise.
+ * semantics.c (expand_body): Don't defer local functions if
+ they wouldn't be deferred for some other reason. Don't
+ generate RTL for functions that will not be emitted.
+ (genrtl_start_function): Remove code deadling with
+ DECL_SAVED_INSNS.
+ (genrtl_finish_function): Likewise.
+
+2001-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/4203
+ * call.c (build_over_call): Do not optimize any empty base
+ construction.
+
+2001-08-31 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * error.c (dump_template_decl): Output template parameters
+ together with their specifiers.
+ Output `class' prefix for template template parameter.
+ (dump_decl): Fix formatting.
+
+2001-08-30 Kurt Garloff <garloff@suse.de>
+
+ * optimize.c (inlinable_function_p): Allow only smaller single
+ functions. Halve inline limit after reaching recursive limit.
+
+2001-08-30 Joern Rennecke <amylaar@redhat.com>
+ Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (build_vtable_entry_ref): Subtract in char*, not
+ ptrdiff_t.
+
+2001-08-23 Jason Merrill <jason_merrill@redhat.com>
+
+ * tree.c (cp_build_qualified_type_real): Use get_qualified_type.
+ (build_cplus_array_type): Use cp_build_qualified_type, not
+ TYPE_MAIN_VARIANT, to get an unqualified version.
+
+ * decl2.c (grok_alignof): Lose.
+ (build_expr_from_tree): Use expr_sizeof and c_alignof_expr.
+ * typeck.c (c_alignof): Lose.
+ * semantics.c (finish_sizeof, finish_alignof): New.
+ * parse.y: Use them.
+ * cp-tree.h: Declare them.
+
+2001-08-22 Jason Merrill <jason_merrill@redhat.com>
+
+ * pt.c (tsubst_expr): Hand off to the TREE_CHAIN of a statement.
+ Don't loop in COMPOUND_STMT, FOR_STMT or TRY_BLOCK.
+ * tree.c (cp_statement_code_p): A TAG_DEFN is a statement.
+
+2001-08-19 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck2.c (add_exception_specifier): Only require complete type if
+ not in processing template declaration.
+
+2001-08-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c: Cast argument to size_t, not HOST_WIDE_INT, in calls to
+ GNU_xref_start_scope and GNU_xref_end_scope.
+
+ * tree.c (TYPE_HASH): Moved to ../tree.h.
+
+2001-08-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cvt.c (convert_to_void): Preserve TREE_SIDE_EFFECTS
+ on COMPOUND_EXPRs.
+
+2001-08-14 Richard Henderson <rth@redhat.com>
+
+ * class.c, cp-tree.h (build_vfn_ref): Remove.
+ * call.c, rtti.c: Replace all refernces with build_vtbl_ref.
+
+2001-08-13 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_over_call): Mark COMPOUND_EXPRs generated for
+ empty class assignment as having side-effects to avoid
+ spurious warnings.
+
+2001-08-13 Zack Weinberg <zackw@panix.com>
+
+ * Make-lang.in (cp/except.o): Add libfuncs.h to dependencies.
+ * except.c: Include libfuncs.h.
+
+2001-08-11 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * decl.c (grokdeclarator): Clarify diagnostic message.
+
+2001-08-13 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * decl2.c (do_nonmember_using_decl): Replace using directive
+ with using declaration in the error message.
+
+2001-08-11 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (maybe_fold_nontype_arg): Use TREE_TYPE of ARG as the
+ criterion to avoid rebuilding expression tree instead of
+ processing_template_decl.
+
+2001-08-07 Jason Merrill <jason_merrill@redhat.com>
+
+ Support named return value optimization for inlines, too.
+ * decl.c (finish_function): Nullify returns here.
+ * semantics.c (genrtl_start_function): Not here.
+ (cp_expand_stmt): Don't mess with CLEANUP_STMTs.
+ (nullify_returns_r): No longer static. Just clear RETURN_EXPR.
+ Also nullify the CLEANUP_STMT for the nrv.
+ * cp-tree.h: Declare it.
+ * optimize.c (declare_return_variable): Replace the nrv with the
+ return variable.
+ * typeck.c (check_return_expr): Be more flexible on alignment check.
+ Ignore cv-quals when checking for a matching type.
+
+2001-08-09 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (finish_objects): Use target hooks instead of
+ assemble_constructor and assemble_destructor.
+
+2001-08-08 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * g++spec.c (lang_specific_driver): Quote argument after `-Xlinker'.
+
+2001-08-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3820
+ Stop using TYPE_NONCOPIED_PARTS.
+ * call.c (build_over_call): Be careful when copy constructing
+ or assigning to an empty class.
+ * class.c (check_bases_and_members): It has a
+ COMPLEX_ASSIGN_REF if it has a vptr.
+ (layout_class_type): Don't add empty class padding to
+ TYPE_NONCOPIED_PARTS.
+ (finish_struct_1): Don't add the VFIELD either.
+ * cp-tree.h (TYPE_HAS_TRIVIAL_INIT_REF): Mention _copy_
+ initialization.
+
+2001-08-07 Jason Merrill <jason_merrill@redhat.com>
+
+ * tree.c (walk_tree): Walk siblings even if !walk_subtrees.
+
+2001-08-06 Richard Henderson <rth@redhat.com>
+
+ * decl2.c (finish_objects): Pass a symbol_ref and priority to
+ assemble_{constructor,destructor}. Remove priority handling.
+
+2001-08-05 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ Don't allow template-id in using-declaration.
+ * decl2.c (validate_nonmember_using_decl): Handle template-ids.
+ (do_class_using_decl): Likewise.
+
+2001-08-04 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * cp/spew.c (read_token): No need to pop buffers.
+
+2001-08-02 Stan Shebs <shebs@apple.com>
+
+ * cp-tree.h (FNADDR_FROM_VTABLE_ENTRY): Remove, no longer used.
+ (fnaddr_from_vtable_entry): Remove decl.
+ * method.c (use_thunk): Update comment.
+
+2001-08-01 Andrew Cagney <ac131313@redhat.com>
+
+ * repo.c (get_base_filename): Change return value to const char
+ pointer.
+
+2001-08-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ Kill -fhonor-std.
+ * NEWS: Document.
+ * cp-tree.h (flag_honor_std): Remove.
+ (CPTI_FAKE_STD): Remove.
+ (std_node): Remove comment about it being NULL.
+ (fake_std_node): Remove.
+ * decl.c (in_fake_std): Remove.
+ (walk_namespaces_r): Remove fake_std_node check.
+ (push_namespace): Remove in_fake_std code.
+ (pop_namespace): Likewise.
+ (lookup_name_real): Remove fake_std_node check.
+ (init_decl_processing): Always create std_node. Always add
+ std:: things there.
+ (builtin_function): Always put non '_' fns in std.
+ * decl2.c (flag_honor_std): Remove.
+ (lang_f_options): Remove honor-std.
+ (unsupported_options): Add honor-std.
+ (set_decl_namespace): Remove fake_std_node check.
+ (validate_nonmember_using_decl): Likewise.
+ (do_using_directive): Likewise.
+ (handle_class_head): Likewise.
+ * dump.c (cp_dump_tree): Likewise.
+ * except.c (init_exception_processing): Adjust.
+ * init.c (build_member_call): Remove fake_std_node check.
+ (build_offset_ref): Likewise.
+ * lang-options.h: Remove -fhonor-std, -fno-honor-std.
+ * rtti.c (init_rtti_processing): Adjust.
+
+2001-07-31 Alexandre Petit-Bianco <apbianco@redhat.com>
+
+ * tree.c (cp_tree_equal): WITH_CLEANUP_EXPR node to use its second
+ operand while calling cp_tree_equal.
+
+2001-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ The 3.0 ABI no longer has vbase pointer fields.
+ * cp-tree.h (VBASE_NAME, VBASE_NAME_FORMAT, VBASE_NAME_P,
+ FORMAT_VBASE_NAME): Remove.
+ * method.c (do_build_copy_constructor): Adjust.
+ (do_build_assign_ref): Adjust.
+ * search.c (lookup_field_r): Adjust.
+ * typeck.c (build_component_ref): Adjust.
+
+ The 3.0 ABI always has a vtable pointer at the start of every
+ polymorphic class.
+ * rtti.c (build_headof_sub): Remove.
+ (build_headof): Adjust.
+ (get_tinfo_decl_dynamic): No need to check flag_rtti
+ here. Adjust.
+ (create_real_tinfo_var): Explain why we need a hidden name.
+
+2001-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3631
+ * class.c (update_vtable_entry_for_fn): The fixed adjustment
+ of a virtual thunk should be from declaring base.
+
+2001-07-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_ctor_vtable_bases_queue_p): Always walk into
+ the shared virtual base, so preserving inheritance graph order.
+
+2001-07-30 Andreas Jaeger <aj@suse.de>
+
+ * decl2.c: Remove unused var global_temp_name_counter.
+
+2001-07-28 Richard Henderson <rth@redhat.com>
+
+ * method.c (pending_inlines): Remove.
+
+2001-07-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (mark_primary_virtual_base): Don't adjust base
+ offsets here.
+ (dfs_unshared_virtual_bases): Adjust them here.
+ (mark_primary_bases): Explain why we adjust at the end.
+
+2001-07-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (finish_struct_1): When copying the primary base's
+ VFIELD, make sure we find it is at offset zero.
+
+2001-07-26 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (tsubst_template_parms): Call maybe_fold_nontype_arg and
+ tsubst_expr for default template arguments.
+
+2001-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3621
+ * spew.c (yylex): Only copy the token's lineno, if it is
+ nonzero.
+
+2001-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3624
+ * call.c (resolve_args): Simplify, call
+ convert_from_reference.
+ (build_new_op): Resolve and convert from reference ARG1
+ earlier. Adjust ARG2 & ARG3 resolve and conversion.
+
+2001-07-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (last_function_parm_tags): Remove.
+ (current_function_parm_tags): Remove.
+ (init_decl_processing): Adjust.
+ (start_function): Adjust.
+ (store_parm_decls): Adjust.
+
+ PR c++/3152
+ * decl.c (grokdeclarator): Detect when a function typedef is
+ declaring a function, and create last_function_parms correctly.
+
+2001-07-25 Jason Merrill <jason_merrill@redhat.com>
+
+ * call.c (joust): Only prefer a non-builtin candidate to a builtin
+ one if they have the same signature.
+
+ * cvt.c (build_up_reference): Take DECL parm. Check TREE_STATIC on
+ it rather than toplevel_bindings_p. Give it a mangled name if static.
+ (convert_to_reference): Adjust.
+ * decl2.c (get_temp_name): Lose.
+ * mangle.c (mangle_ref_init_variable): New fn.
+ (mangle_guard_variable): Strip the ref-init header.
+ * cp-tree.h: Adjust.
+ * decl.c (cp_finish_decl): Add the DECL_STMT after processing the
+ initializer.
+ (grok_reference_init): Always use DECL_INITIAL.
+
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3416
+ * call.c (build_conditional_expr): Recheck args after
+ conversions.
+ * cp-tree.h (build_conditional_expr): Move to correct file.
+ * typeck.c (decay_conversion): Diagnose any unknown types
+ reaching here.
+ (build_binary_op): Don't do initial decay or default
+ conversions on overloaded functions.
+ (build_static_cast): Don't do a decay conversion here.
+
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3543
+ * typeck.c (condition_conversion): Resolve an OFFSET_REF.
+ * expr.c (cplus_expand_expr): An OFFSET_REF should never get here.
+
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_vtbl_or_vbase_field): Remove, move into ...
+ (create_vtbl_ptr): ... here.
+
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_vbase_offset_vbtl_entries): Look for
+ non-primary base of which we are a sub vtable.
+
+2001-07-24 Phil Edwards <pme@sources.redhat.com>
+
+ * semantics.c (finish_this_expr): Remove unused code.
+
+2001-07-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ Simplify rtti, now we've only one ABI.
+ * cp-tree.h (cp_tree_index): Remove CPTI_TINFO_DECL_ID,
+ CPTI_TINFO_VAR_ID.
+ (tinfo_decl_id, tinfo_var_id): Remove.
+ (get_typeid_1): Remove.
+ * rtti.c
+ (init_rtti_processing): Remove tinfo_decl_id & tinfo_var_id.
+ (typeid_ok_p): New function.
+ (build_type_id): Call typeid_ok_p. Don't call tinfo_from_decl.
+ (get_tinfo_decl): Remove old abi documentation.
+ (tinfo_from_decl): Remove.
+ (get_type_id): Call typeid_ok_p. Absorb get_typeid_1.
+ (get_typeid_1): Remove.
+ (get_base_offset): Remove.
+ (synthesize_tinfo_var): Absorb get_base_offset.
+ (create_real_tinfo_var): Don't use tinfo_decl_id.
+
+2001-07-23 Graham Stott <grahams@redhat.com>
+
+ * cp/class.c (type_requires_array_cookie): Fix use of uninitialized
+ variable has_two_argument_delete_p.
+
+2001-07-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove flag_vtable_thunk. It is always on for the 3.0 ABI.
+ * cp-tree.h (CPTI_DELTA2_IDENTIFIER): Remove.
+ (CPTI_INDEX_IDENTIFIER): Remove.
+ (CPT_PFN_OR_DELTA2_IDENTIFIER): Remove.
+ (delta2_identifier): Remove.
+ (index_identifier): Remove.
+ (pfn_or_delta2_identifier): Remove.
+ (flag_vtable_thunks): Remove.
+ (VTABLE_DELTA2_NAME): Remove.
+ (VTABLE_INDEX_NAME): Remove.
+ (FNADDR_FROM_VTABLE_ENTRY): Adjust.
+ (vfunc_ptr_type_node): Adjust.
+ (VTABLE_NAME_PREFIX): Adjust.
+ (build_vfn_ref): Lose first parameter.
+ (fixup_all_virtual_upcast_offsets): Remove.
+ * decl.c (initialize_predefined_identifiers): Remove
+ delta2_identifier, index_identifier, pfn_or_delta2_identifier.
+ (init_decl_processing): Remove no-vtable-thunk code.
+ * decl2.c (flag_vtable_thunks): Remove.
+ (mark_vtable_entries): Remove no-vtable-thunk code.
+ * error.c (dump_decl): Remove no-vtable-thunk code.
+ (dump_expr): Adjust ptr to member function code.
+ * init.c (initialize_vtable_ptrs): Remove no-vtable-thunk
+ code.
+ * rtti.c (build_headof): Remove no-vtable-thunk code.
+ (get_tinfo_decl_dynamic): Adjust build_vfn_ref call.
+ * search.c (get_base_distance): Remove expand_upcast_fixups case.
+ (virtual_context) Remove.
+ (expand_upcast_fixups): Remove.
+ (fixup_virtual_upcast_offsets): Remove.
+ (fixup_all_virtual_upcast_offsets): Remove.
+ * typeck.c (get_member_function_from_ptrfunc): Remove
+ no-vtable-thunk code.
+ * call.c (build_over_call): Adjust call to build_vfn_ref.
+ * class.c (build_vfn_ref): Lose first parameter. Remove
+ no-vtable-thunk code.
+ (build_rtti_vtbl_entries): Remove no-vtable-thunk code.
+ (build_vtable_entry): Remove no-vtable-thunk code.
+
+2001-07-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove old-abi remnants. Remove comments about old abi
+ behavior. Remove references to 'new-abi' in comments.
+ * cp-tree.h: Adjust comments.
+ (vbase_offsets_in_vtable_p): Delete.
+ (vcall_offsets_in_vtable_p): Delete.
+ (vptrs_present_everywhere_p): Delete.
+ (all_overridden_vfuns_in_vtables_p): Delete.
+ (merge_primary_and_secondary_vtables_p): Delete.
+ (TYPE_CONTAINS_VPTR_P): Adjust.
+ (VTT_NAME_PREFIX): Remove.
+ (CTOR_VTBL_NAME_PREFIX): Remove.
+ (init_vbase_pointers): Remove.
+ * class.c: Adjust coments.
+ (build_vbase_pointer_fields): Delete.
+ (build_vbase_pointer): Remove old-abi code.
+ (build_secondary_vtable): Likewise.
+ (modify_all_vtables): Likewise.
+ (create_vtable_ptr): Likewise.
+ (layout_class_type): Likewise.
+ (finish_struct_1): Likewise.
+ (finish_vtbls): Likewise.
+ (dfs_finish_vtbls): Delete.
+ (build_vbase_offset_vtbl_entries): Remove old-abi code.
+ * cvt.c: Adjust comments.
+ * decl.c: Adjust comments.
+ * decl2.c: Adjust comments.
+ * init.c: Adjust comments.
+ (construct_virtual_bases): Remove old-abi code.
+ * lang-specs.h: Remove -fno-new-abi.
+ * mangle.c: Adjust comments.
+ * rtti.c: Adjust comments.
+ (get_base_offset): Remove old-abi-code.
+ * search.c: Adjust comments.
+ (dfs_init_vbase_pointers): Remove.
+ (dfs_vtable_path_unmark): Remove.
+ (init_vbase_pointers): Remove.
+ * semantics.c: Adjust comments.
+ (emit_associated_thunks): Remove old-abi code.
+ * typeck.c: Adjust comments.
+
+2001-07-20 Daniel Berlin <dan@cgsoftware.com>
+
+ * Make-lang.in (cp/optimize.o): Depend on $(PARAMS_H), not
+ params.h.
+
+2001-07-19 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (finish_struct_anon): Forbid nested classes.
+
+2001-07-19 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * decl2.c: Don't include dwarfout.h and dwarf2out.h.
+ * optimize.c: Include debug.h.
+ (maybe_clone_body): Use debug hook.
+ * semantics.c: Include debug.h.
+ (expand_body): Use debug hook.
+
+2001-07-19 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * spew.c (read_token, yyerror): Remove CPP_INT, CPP_FLOAT cases.
+
+2001-07-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (type_requires_array_cookie): New function.
+ (check_methods): Don't try to figure out whether the type needs a
+ cookie here.
+ (check_bases_and_members): Set TYPE_VEC_NEW_USES_COOKIE here.
+ * cp-tree.h (TYPE_VEC_DELETE_TAKES_SIZE): Remove.
+ (TYPE_VEC_NEW_USES_COOKIE): Reimplement.
+ * pt.c (instantiate_class_template): Don't set
+ TYPE_VEC_DELETE_TAKES_SIZE.
+ * NEWS: Document ABI changes from GCC 3.0.
+
+2001-07-18 Xavier Delacour <xavier@fmaudio.net>,
+ Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * NEWS (Changes in GCC 3.0): Fix typo.
+
+2001-07-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (cplus_decl_attributes): Take a pointer to the node to
+ which attributes are to be attached, and a flags argument. Update
+ call to decl_attributes.
+ (grokfield): Update call to decl_attributes.
+ * class.c (finish_struct): Update call to cplus_decl_attributes.
+ * cp-tree.h (cplus_decl_attributes): Update prototype.
+ * decl.c (start_decl, grokdeclarator, start_function): Update
+ calls to decl_attributes and cplus_decl_attributes.
+ * friend.c (do_friend): Update call to cplus_decl_attributes.
+ * parse.y (parse_bitfield): Update call to cplus_decl_attributes.
+
+2001-07-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (make_rtl_for_nonlocal_decl): Set DECL_C_HARD_REGISTER
+ for `register' variables with an asm-specification.
+
+2001-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (finish_asm_stmt): Mark the output operands
+ to an asm addressable, if necessary.
+
+2001-07-11 Ben Elliston <bje@redhat.com>
+
+ * Revert this change -- there is a subtle bug.
+
+ PR c++/80
+ * decl.c (finish_enum): New "attributes" argument; pass it to
+ cplus_decl_attributes. Use a narrower type if the enum is packed.
+ * cp-tree.h (finish_enum): Adjust prototype.
+ * parse.y (enum_head): New non-terminal.
+ (structsp): Use it. Enums now may be preceded or followed by
+ optional attributes -- pass their chained tree to finish_enum().
+ * pt.c (tsubst_enum): Pass NULL_TREE for the new argument.
+
+2001-07-10 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_decl): Set DECL_CONTEXT for namespace-scope
+ variables.
+
+2001-07-10 Jason Merrill <jason_merrill@redhat.com>
+
+ * semantics.c (cp_expand_stmt): Fix for null
+ current_function_return_value.
+
+2001-07-10 Jan van Male <jan.vanmale@fenk.wau.nl>
+
+ * call.c (build_op_delete_call): Initialize fn.
+ (convert_like_real): Delete conditional.
+ (joust): Initialize *w and *l.
+ * class.c: Add prototype for binfo_ctor_vtable.
+ (get_primary_binfo): Initialize result.
+ * init.c (build_java_class_ref): Initialize name.
+
+2001-07-09 Erik Rozendaal <dlr@acm.org>
+
+ * typeck.c (unary_complex_lvalue): Do not duplicate the
+ argument to modify, pre-, or post-increment when used as an
+ lvalue and when the argument has side-effects.
+
+2001-07-08 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (start_decl): Don't call SET_DEFAULT_DECL_ATTRIBUTES.
+ (start_function): Don't call SET_DEFAULT_DECL_ATTRIBUTES. Call
+ cplus_decl_attributes even if attrs is NULL.
+ * friend.c (do_friend): Don't call SET_DEFAULT_DECL_ATTRIBUTES.
+
+2001-07-08 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (grokdeclarator), decl2.c (cplus_decl_attributes): Update
+ calls to decl_attributes.
+
+2001-07-06 Ira Ruben <ira@apple.com>
+
+ * cp-tree.def (TEMPLATE_DECL): Update comment. DECL_RESULT should
+ be DECL_TEMPLATE_RESULT.
+
+2001-07-05 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.h (copy_template_template_parm): Rename to ...
+ (bind_template_template_parm): ... here.
+ * tree.c (copy_template_template_parm): Rename to ...
+ (bind_template_template_parm): ... here. Remove the case when
+ NEWARGS is NULL_TREE.
+ (copy_tree_r): Don't copy TEMPLATE_TEMPLATE_PARM and
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+ * pt.c (lookup_template_class): Adjust.
+
+2001-07-05 Jason Merrill <jason_merrill@redhat.com>
+
+ * cvt.c (convert_lvalue): New fn.
+ * cp-tree.h: Declare it.
+ * method.c (do_build_assign_ref): Use it.
+ (do_build_copy_constructor): Convert parm to base types
+ before calling base constructors.
+
+ * typeck.c (check_return_expr): Check DECL_ALIGN instead of
+ DECL_USER_ALIGN. Check flag_elide_constructors instead of
+ optimize.
+ * semantics.c (cp_expand_stmt): Don't destroy the named return value.
+
+2001-07-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * optimize.c (optimize_inline_calls): New function, broken out
+ of ...
+ (optimize_function): ... here. Call it. Don't inline if it is
+ a thunk.
+ (dump_function): Print name of dump flag causing this dump.
+ * semantics.c (expand_body): Move thunk inline check to
+ optimize_function.
+
+2001-06-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * typeck.c (COMP_TYPE_ATTRIBUTES): Don't define.
+ (comptypes): Use target.comp_type_attributes.
+
+2001-06-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (flag_dump_class_layout): Remove unneeded declaration.
+
+2001-06-28 Gabriel Dos Reis <gdr@merlin.codesourcery.com>
+
+ * error.c (lang_print_error_function): Add a `diagnostic_context *'
+ parameter. Tweak.
+
+2001-06-27 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * decl2.c (import_export_class): Update.
+
+2001-06-26 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (init_error): Adjust settings.
+
+2001-06-26 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (init_error): Adjust settings.
+
+2001-06-19 Richard Sandiford <rsandifo@redhat.com>
+
+ * except.c (initialize_handler_parm): Expect __cxa_begin_catch to
+ return pointers to data members by reference rather than by value.
+
+2001-06-18 Jason Merrill <jason_merrill@redhat.com>
+
+ Implement the Named Return Value optimization.
+ * cp-tree.h (struct cp_language_function): Add x_return_value.
+ (current_function_return_value): Now a macro.
+ * decl.c: Don't define it.
+ (define_label, finish_case_label): Don't clear it.
+ (init_decl_processing): Don't register it with GC.
+ * semantics.c (genrtl_finish_function): Don't check it for
+ no_return_label. Copy the RTL from the return value to
+ current_function_return_value and walk, calling...
+ (nullify_returns_r): ...this new fn.
+ * typeck.c (check_return_expr): Set current_function_return_value.
+
+2001-06-15 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (dfs_accumulate_vtbl_inits): Just point to the base we're
+ sharing a ctor vtable with. Merge code for cases 1 and 2.
+ (binfo_ctor_vtable): New fn.
+ (build_vtt_inits, dfs_build_secondary_vptr_vtt_inits): Use it.
+
+2001-06-14 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (dfs_find_final_overrider): Fix logic.
+
+ * class.c (update_vtable_entry_for_fn): Uncomment optimization to use
+ virtual thunk instead of non-virtual.
+ (get_matching_virtual): Uncomment.
+
+ * pt.c (unify): Don't recurse between the POINTER_TYPE and the
+ OFFSET_TYPE. If we're adding cv-quals, the extra ones would be on
+ PARM, not ARG.
+
+2001-06-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_accumulate_vtbl_inits): For case 2 & 3, make sure
+ we've not emerged from the hierarchy of RTTI_BINFO on reaching
+ a non-virtual base.
+
+2001-06-13 Mark Mitchell <mark@codesourcery.com>
+
+ * NEWS: Update release number.
+
+2001-06-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3130, c++/3131, c++/3132
+ * cp-tree.h (BINFO_UNSHARED_MARKED): New #define.
+ * class.c (force_canonical_binfo_r): Move
+ BINFO_UNSHARED_MARKED, BINFO_LOST_PRIMARY_P. Don't move
+ virtual bases unless they're primary and what they're primary
+ too has been moved.
+ (dfs_unshared_virtual_bases): Use BINFO_UNSHARED_MARKED. Cope
+ with morally virtual bases. Duplicate BINFO_LOST_PRIMARY_P and
+ BINFO_PRIMARY_BASE_OF. Clear BINFO_VTABLE for all but the most
+ derived binfo.
+ (mark_primary_bases): Use BINFO_UNSHARED_MARKED.
+ (layout_nonempty_base_or_field): Add most derived type
+ parameter. Adjust.
+ (layout_empty_base): Likewise.
+ (build_base_field): Likewise.
+ (build_base_fields): Likewise.
+ (propagate_binfo_offsets): Add most derived type
+ parameter. Skip non canonical virtual bases too.
+ (dfs_set_offset_for_unshared_vbases): Don't skip primary
+ bases. Do skip canonical bases.
+ (layout_virtual_bases): Adjust.
+ (layout_class_type): Adjust.
+ (dfs_get_primary_binfo): Build list of virtual primary base
+ candidates.
+ (get_primary_binfo): Check that the shared virtual primary
+ base candidate was found first.
+ (accumulate_vtbl_inits): Don't do anything for non-vptr
+ containing binfos. For case 1 primary virtual bases, keep
+ checking that we've not emerged from the hierarchy of RTTI_BINFO.
+
+2001-06-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3089
+ * class.c (dfs_accumulate_vtbl_inits): Always walk down the
+ hierarchy looking for primary bases for a ctor
+ vtable. Recursively call oneself, if we meet our primary via
+ this route and haven't met it yet via inheritance graph order.
+
+2001-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ * lang-options.h: Emit documentation for -fno-honor-std, not
+ -fhonor-std.
+
+2001-06-10 Alexandre Oliva <aoliva@redhat.com>
+
+ * typeck.c (get_member_function_from_ptrfunc) [vbit_in_delta]:
+ Don't clobber delta.
+ (expand_ptrmemfunc_cst) [ptrmemfunc_vbit_in_delta]: Adjust pfn.
+
+2001-06-10 Mark Mitchell <mark@codesourcery.com>
+ Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * Make-lang.in (cp/call.o): Depend on diagnostic.h
+ (cp/typeck.o): Depend on diagnostic.h
+ (cp/typeck2.o): Depend on diagnostic.h
+ (cp/repo.o): Depend on dignostic.h
+ * typeck.c: #include diagnostic.h
+ (convert_for_initialization): Remove extern declaration for
+ warningcount and errorcount.
+
+ * call.c: #include diagnostic.h
+ (convert_like_real): Remove extern declaration for warnincount and
+ errorcount.
+
+ * repo.c: #include diagnostic.h
+ * typeck2.c: #include diagnostic.h
+
+2001-06-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (duplicate_decls): Fix DECL_TEMPLATE_RESULT thinko
+ in previous change.
+
+2001-06-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2929
+ * friend.c (do_friend): Use push_decl_namespace for classes at
+ namespace scope.
+
+2001-06-08 Nathan Sidwell <nathan@codesourcery.com>
+ Jason Merrill <jason_merrill@redhat.com>
+
+ PR c++/3061
+ * class.c (build_secondary_vtable): Use assert, rather than an error
+ message.
+ (dfs_fixup_binfo_vtbls): BINFO_VTABLE might be NULL.
+ (dfs_accumulate_vtbl_inits): A lost primary virtual base may
+ be between ORIG_BINFO and RTTI_BINFO, but neither of them.
+ Don't set BINFO_VTABLE for a primary virtual base.
+
+2001-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (duplicate_decls): Update source position information
+ when a template function is defined.
+
+2001-06-07 Phil Edwards <pme@sources.redhat.com>
+
+ * lang-specs.h: Move -D_GNU_SOURCE to config/linux.h.
+
+2001-06-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2914
+ * decl.c (pushtag): Don't push into a complete type's scope.
+
+2001-06-06 Jason Merrill <jason_merrill@redhat.com>
+
+ * cp-tree.h (THUNK_GENERATE_WITH_VTABLE_P): Lose.
+ (struct lang_decl_flags): Lose generate_with_vtable_p.
+ (BV_GENERATE_THUNK_WITH_VTABLE_P): Lose.
+ * class.c (copy_virtuals): Adjust.
+ * decl2.c (mark_vtable_entries): Adjust.
+ * method.c (make_thunk, build_vtable_entry): Adjust.
+ * class.c (update_vtable_entry_for_fn): Only look as far as the
+ first defining class.
+ (build_vtbl_initializer): Put nothing in the slot for a function only
+ defined in a lost primary virtual base.
+ (add_vcall_offset_vtbl_entries_1): Use the same code for
+ the lost primary case and the normal case.
+ (dfs_unshared_virtual_bases): Don't lose a non-virtual primary base.
+ (get_vfield_offset, get_derived_offset): Lose.
+ (dfs_find_final_overrider): Use look_for_overrides_here.
+ (get_matching_virtual): New fn.
+ * semantics.c (emit_associated_thunks): Check BV_USE_VCALL_INDEX_P,
+ not BV_VCALL_INDEX.
+ * search.c (look_for_overrides_here): Split out from...
+ (look_for_overrides_r): Here.
+
+ * class.c (find_final_overrider): Return error_mark_node on error.
+
+ * decl2.c (key_method): #if 0 accidental change.
+
+2001-06-06 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * call.c (convert_default_arg): Use INTEGRAL_TYPE_P.
+ (build_over_call): Likewise.
+ * decl.c (grokparms): Likewise.
+ * pt.c (tsubst_decl): Likewise.
+ * typeck.c (convert_arguments): Likewise.
+
+2001-06-05 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (begin_class_definition): Robustify.
+
+ * pt.c (instantiate_decl): Tell the repository code about the
+ clones, not the cloned functions.
+ * repo.c (repo_template_used): Explicitly instantiate the cloned
+ function, not the clones.
+
+2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_user_type_conversion_1): Set ICS_USER_FLAG and
+ ICS_BAD_FLAG on created conversion.
+ (compare_ics): Break out rank.
+
+2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (xref_tag): Remove extraneous %s on dependent name
+ lookup warning.
+
+2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (layout_vtable_decl): Fix off by one error on
+ build_index_type.
+ (build_vtt): Likewise.
+ (build_ctor_vtbl_group): Likewise.
+
+2001-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (maybe_indent_hierarchy): New function.
+ (dump_class_hierarchy_r): Add flags. Dump extra binfo
+ information, if enabled. Use maybe_indent_hierarchy. Adjust
+ output format.
+ (dump_class_hierarchy): Adjust prototype. Adjust output format.
+ (dump_array, dump_vtable, dump_vtt): New functions.
+ (finish_struct_1): Adjust hierarchy dumping.
+ (initialize_vtable): Call dump_vtable.
+ (build_vtt): Call dump_vtt.
+ (build_ctor_vtbl_group): Call dump_vtable.
+ * decl2.c (flag_dump_class_layout): Remove.
+ (cxx_decode_option): Remove dump translation unit
+ and dump class hierarchy check. Call dump_switch_p.
+ (finish_file): Adjust dumping.
+ (dump.c): Only dump base classes if not TDF_SLIM.
+ Only dump namespace members if not TDF_SLIM.
+ * optimize.c (dump_function): New function.
+ (optimize_function): Call dump_function.
+ * semantics.c (expand_body): Use dump_enabled_p.
+
+2001-06-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/2936
+ Part missed from first commit
+ * decl2.c (finish_anon_union): Copy context.
+
+2001-05-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/2936
+ * optimize.c (remap_decl): Remap anonymous aggregate members too.
+
+2001-05-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR g++/2823
+ * semantics.c (expand_body): Don't optimize thunks.
+
+2001-05-25 Sam TH <sam@uchicago.edu>
+
+ * cp-tree.h lex.h: Fix header include guards.
+
+2001-05-25 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (init_decl_processing): Tweak.
+
+2001-05-24 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (duplicate_decls): Tidy.
+ (init_decl_processing): Always set flag_no_builtin.
+
+2001-05-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2184
+ * decl2.c (do_local_using_decl): Push the decls, even in a
+ template.
+
+2001-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (initialize_inlined_parameters): Don't set
+ TREE_READONLY for a VAR_DECL taking the place of an inlined
+ PARM_DECL.
+
+2001-05-22 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c, cp-tree.h, rtti.c: Remove com_interface attribute support.
+ * tree.c (cp_valid_lang_attribute): Warn about use of com_interface
+ attribute.
+
+2001-05-22 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * parse.y: Refer to compound literals as such, not as
+ constructor-expressions.
+
+2001-05-21 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_op_delete_call): Ignore exception-specifications
+ when looking for matching delete operators.
+ * init.c (build_new_1): Compute whether or not the allocation
+ function used is a placement allocation function or not, and
+ communicate this information to build_op_delete_call.
+
+2001-05-21 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (build_vtable_entry_ref): Lose vtbl parm. Fix for new abi.
+ (build_vtbl_ref): Adjust.
+ (dfs_accumulate_vtbl_inits): Set TREE_CONSTANT on the vtable address.
+ * decl2.c (lang_f_options): Remove huge-objects, vtable-thunks.
+ Re-add vtable-gc.
+ (unsupported_options): Correspondingly.
+
+ * decl2.c (maybe_make_one_only): Check flag_weak, not
+ supports_one_only().
+
+ * cp-tree.def (START_CATCH_STMT): Lose.
+ * dump.c (cp_dump_tree): Don't dump it. Do dump HANDLER_PARMS.
+ * tree.c (cp_statement_code_p): Don't case it.
+ * semantics.c (cp_expand_stmt): Likewise.
+ * cp-tree.h (START_CATCH_TYPE): Lose.
+ (HANDLER_TYPE): New.
+ * except.c (expand_start_catch_block): Don't start any blocks.
+ Return the type.
+ (expand_end_catch_block): Don't end any blocks.
+ * parse.y (handler): Don't pass anything from finish_handler_parms
+ to finish_handler.
+ * pt.c (tsubst_expr): Likewise.
+ * semantics.c (begin_handler): Call note_level_for_catch here.
+ (finish_handler_parms): Don't return anything.
+ (genrtl_catch_block, begin_catch_block): Lose.
+ (genrtl_handler): Call expand_start_catch here.
+
+2001-05-18 Jason Merrill <jason_merrill@redhat.com>
+
+ * class.c (build_vtable): Set DECL_ASSEMBLER_NAME for vtables here.
+ (get_vtable_decl, build_vtt): Not here.
+
+2001-05-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/2781
+ * optimize.c (update_cloned_parm): Copy addressability and other
+ flags.
+
+2001-05-20 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (determine_specialization): Ignore artificial functions.
+
+2001-05-20 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (struct lang_identifier, C_RID_YYCODE): Update.
+ (C_RID_CODE): Remove.
+ * lex.c (cxx_init_options): Call set_identifier_size. Update.
+ (init_parse): Don't do it here.
+
+2001-05-18 Diego Novillo <dnovillo@redhat.com>
+
+ * decl2.c (finish_objects): Use the original SYMBOL_REF from the
+ function declaration to avoid stripping the symbol's attributes.
+
+2001-05-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (pushdecl): Adjust error string.
+ (xref_tag): Adjust friend class injection warning. Remove the
+ inherited name from the class shadowed scope.
+
+2001-05-17 Mark Mitchell <mark@codesourcery.com>
+
+ * except.c (cp_protect_cleanup_actions): New function.
+ (init_exception_processing): Don't set protect_cleanup_actions
+ here. Do set lang_protect_cleanup_actions.
+
+2001-05-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * spew.c (read_token): Call yyerror on all unexpected tokens.
+
+2001-05-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (member_init_ok_or_else): Take a tree rather than
+ string for name.
+ (expand_member_init): Adjust.
+
+2001-05-14 Nick Clifton <nickc@cambridge.redhat.com>
+
+ * decl.c (duplicate_decls): Suppress warning about duplicate
+ decls if the first decl is a friend.
+
+2001-05-12 Zack Weinberg <zackw@stanford.edu>
+
+ * except.c (choose_personality_routine): Export. Add
+ explanatory comment. Take an enum languages, not a boolean.
+ (initialize_handler_parm): Adjust to match.
+ * cp-tree.h: Prototype choose_personality_routine.
+ * lex.c (handle_pragma_java_exceptions): New function.
+ (init_cp_pragma): Register #pragma GCC java_exceptions.
+
+2001-05-12 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * method.c (build_mangled_C99_name): Remove unused prototype.
+
+2001-05-12 Alexandre Oliva <aoliva@redhat.com>
+
+ * cp-tree.h (ptrmemfunc_vbit_where_t): Declare type.
+ * typeck.c (get_member_function_from_ptrfunc,
+ build_ptrmemfunc, expand_ptrmemfunc_cst): Take
+ TARGET_PTRMEMFUNC_VBIT_LOCATION into account.
+
+ Reverted Geoff Keating's 2001-05-03's patch.
+
+2001-05-11 Ira Ruben <ira@apple.com>
+
+ * cp/cp-tree.h (C_EXP_ORIGINAL_CODE): Delete; declared in c-common.h.
+
+2001-05-11 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (finish_label_expr, lookup_label): Delete.
+ * parse.y: Update for '&&'; don't issue warning here.
+ * semantics.c (finish_label_expr): Delete.
+
+2001-05-07 Mark Mitchell <mark@codesourcery.com>
+
+ * splay-tree.h (splay_tree_max): New function.
+ (splay_tree_min): Likewise.
+
+2001-05-03 Geoffrey Keating <geoffk@redhat.com>
+
+ * cp-tree.h (enum cp_tree_index): Add CPTI_PFN_VFLAG_IDENTIFIER.
+ (pfn_vflag_identifier): Define.
+ Update comment about layout of pointer functions.
+ (build_ptrmemfunc1): Update prototype.
+ (expand_ptrmemfunc_cst): Update prototype.
+ * decl.c (initialize_predefined_identifiers): Initialize
+ pfn_vflag_identifier.
+ (build_ptrmemfunc_type): When FUNCTION_BOUNDARY < 16, add
+ an extra field to the type.
+ * expr.c (cplus_expand_constant): Pass 'flag' between
+ expand_ptrmemfunc_cst and build_ptrmemfunc1.
+ * typeck.c (get_member_function_from_ptrfunc): When
+ FUNCTION_BOUNDARY < 16, look at additional field to determine
+ if a pointer-to-member is a real pointer or a vtable offset.
+ (build_ptrmemfunc1): Add new parameter to contain extra field.
+ (build_ptrmemfunc): Pass the extra field around.
+ (expand_ptrmemfunc_cst): Add new parameter to return extra field.
+ (pfn_from_ptrmemfunc): Ignore the extra field.
+
+2001-05-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (flag_inline_trees): Update documentation.
+ * decl.c (init_decl_processing): Adjust handling of
+ flag_inline_functions and flag_inline_trees to support -O3.
+ (grokfndecl): Set DECL_INLINE on all functions if that's what
+ the user requested.
+ (save_function_data): Clear DECL_INLINE in
+ current_function_cannot_inline is non-NULL.
+ * decl2.c (flag_inline_trees): Update documentation.
+
+2001-05-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * dump.c (cp_dump_tree, USING_STMT case): New case.
+ * tree.c (cp_statement_code_p): Add USING_STMT.
+ * decl2.c (do_using_directive): Add the using directive statement.
+
+ * tree.c (walk_tree): Reformat an if block.
+
+2001-05-02 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (compute_array_index_type): Don't try to do anything with
+ the indices when processing a template.
+
+2001-05-02 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c: NULL_PTR -> NULL.
+ * class.c: Likewise.
+ * cvt.c: Likewise.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * except.c: Likewise.
+ * init.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+
+2001-05-02 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (do_using_directive): Revert previous patch.
+
+2001-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.def (USING_STMT): New statement node.
+ * cp-tree.h (USING_STMT_NAMESPACE): New macro.
+ * decl2.c (do_using_directive): Add USING_STMT to statement
+ tree. Don't emit errors when processing template decl.
+ * pt.c (tsubst_expr, USING_STMT case): New case.
+ * semantics.c (cp_expand_stmt, USING_STMT case): New case.
+
+2001-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_new_op): Convert args from reference here.
+ (build_conditional_expr): Don't convert here.
+
+2001-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * spew.c (last_token_id): New static variable.
+ (read_token): Set it here.
+ (yyerror): Use it here.
+
+2001-04-30 Richard Henderson <rth@redhat.com>
+
+ * cvt.c: Downcase C_PROMOTING_INTEGER_TYPE_P invocations.
+ * decl.c: Likewise.
+
+2001-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ * gxxint.texi: Remove.
+ * Make-lang.in: Remove all traces of gxxint.texi.
+
+2001-04-30 Mark P Mitchell <mark@codesourcery.com>
+
+ * decl2.c (start_static_initialization_or_destruction): Correct
+ logic to handle the -fno-use-cxa-atexit case.
+
+2001-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (update_cloned_parm): New function.
+ (maybe_clone_body): Use it. Update the `this' parameter too.
+
+2001-04-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (unsupported_options): Add new-abi.
+ * lang-options.h: Remove no longer supported options.
+
+2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * except.c (can_convert_eh): Don't check template parms,
+ typename types etc.
+
+2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * optimize.c (maybe_clone_body): Copy parameter names and locations.
+
+2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (adjust_clone_args): Prototype new function.
+ * class.c (adjust_clone_args): New function.
+ * decl.c (start_function): Call it for in charge ctors.
+
+2001-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ * method.c (use_thunk): Make sure that thunks really are emitted
+ when requested.
+
+2001-04-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * mangle.c (write_chars): New macro.
+ (hwint_to_ascii): New function
+ (write_number): Use it.
+ (write_integer_cst): Deal with really big numbers.
+
+2001-04-25 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (maybe_clone_body): Copy TREE_PUBLIC before emitting
+ the clone.
+
+2001-04-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Set context of namespace scope
+ TYPE_DECLS.
+
+2001-04-24 Zack Weinberg <zackw@stanford.edu>
+
+ * cp/optimize.c: Include hashtab.h.
+ (struct inline_data): Add tree_pruner.
+ (expand_call_inline, expand_calls_inline): Use it when calling
+ walk_tree.
+ (optimize_function): Initialize and free tree_pruner.
+
+2001-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ Lazy __FUNCTION__ generation.
+ * cp-tree.def (FUNCTION_NAME): Remove.
+ * cp-tree.h (function_name_declared_p): Remove.
+ (cp_fname_init): Prototype.
+ * decl.c (init_decl_processing): Don't generate __FUNCTION__ et al ids,
+ don't call declare_function_name. Call start_fname_decls.
+ (cp_make_fname_decl): Adjust parameters. Generate the name. Don't
+ clobber the line number.
+ (cp_fname_init): New function.
+ (start_function): Call start_fname_decls.
+ (finish_function): Call finish_fname_decls.
+ * lex.c (reswords): Add slots for __FUNCTION__ et al.
+ (rid_to_yy): Add mappings for __FUNCTION__ et al.
+ * optimize.c (maybe_clone_body): Remove function_name_declared_p.
+ * parse.y (VAR_FUNC_NAME): New token.
+ (primary): Add VAR_FUNC_NAME.
+ * pt.c (tsubst_decl): Adjust a DECL_PRETTY_FUNCTION_P's
+ generation.
+ (tsubst, FUNCTION_NAME case): Remove.
+ (tsubst_copy, FUNCTION_NAME case): Remove.
+ (tsubst_expr, DECL_STMT case): Be careful with a
+ DECL_PRETTY_FUNCTION_P.
+ (instantiate_decl): Remove function_name_declared_p.
+ * semantics.c (begin_compound_statement): Don't call
+ declare_function_name here.
+ (setup_vtbl_ptr). Don't save & restore function_name_declared_p.
+ (finish_translation_unit): Call finish_fname_decls.
+ (expand_body): Remove function_name_declared_p.
+ * typeck2.c (digest_init): Allow any ERROR_MARK.
+
+2001-04-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst_decl): Use VOID_TYPE_P.
+ * semantics.c: Fix some typos.
+
+2001-04-23 Phil Edwards <pme@sources.redhat.com>
+
+ * cp/decl2.c (flag_honor_std): Always initialize to 1.
+
+2001-04-22 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * xref.c (GNU_xref_file): Use concat in lieu of xmalloc/sprintf.
+
+2001-04-23 Jason Merrill <jason_merrill@redhat.com>
+
+ * except.c (build_throw): Wrap the initialization of the exception
+ object in a MUST_NOT_THROW_EXPR.
+ (do_free_exception): #if 0.
+
+2001-04-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (finish_enum): Change prototype.
+ * decl.c (finish_enum): Reorganize.
+ * parse.y (structsp): Adjust calls to finish_enum.
+
+2001-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (cp_tree_equal): Adjust final switch formatting. Add
+ 't' case.
+
+2001-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_unshared_virtual_bases): Add ATTRIBUTE_UNUSED.
+ (layout_empty_base): Return at end flag.
+ (build_base_field): Likewise.
+ (build_base_fields): Likewise.
+ (layout_virtual_bases): Don't add 1 to eoc value.
+ (end_of_class): Use full size for empty bases.
+ (layout_class_type): Clear CLASSNEARLY_EMPTY_P if we appended
+ empty bases. Don't add 1 to eoc value. Only add trailing padding
+ if we're an empty class with no empty bases.
+ (dump_class_hierarchy): Dump size and alignment.
+
+2001-04-20 Jakub Jelinek <jakub@redhat.com>
+
+ * call.c (maybe_handle_ref_bind): Copy ICS_USER_FLAG and
+ ICS_BAD_FLAG.
+
+2001-04-20 Jakub Jelinek <jakub@redhat.com>
+
+ * search.c (lookup_field_r): If looking for type and non-TYPE_DECL
+ is found, look first if name does not match the structure name.
+
+2001-04-19 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_LANGUAGE): Don't assume DECL_LANG_SPECIFIC is
+ set.
+ (SET_DECL_LANGUAGE): New macro.
+ * decl.c (duplicate_decls): Use SET_DECL_LANGUAGE.
+ (pushdecl): Likewise.
+ (build_library_fn_1): Likewise.
+ (build_cp_library_fn): Likewise.
+ (grokfndecl): Likewise.
+ (grokvardecl): Mark `extern "C"' variables as having C linkage.
+ * decl2.c (grokclassfn): Use SET_DECL_LANGUAGE.
+ * lex.c (retrofit_lang_decl): Likewise.
+ * mangle.c (mangle_decl_string): Don't mangle the names of
+ variables declared with C language linkage.
+ * semantics.c (finish_member_declaration): Use SET_DECL_LANGUAGE.
+
+2001-04-18 John David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * semantics.c (simplify_aggr_init_exprs_r): Don't restore
+ flag_access_control from uninitialized storage.
+
+2001-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TYPE_PTRMEM_CLASS_TYPE): Improve documentation.
+ * mangle.c (write_pointer_to_member_type): Fix mangling of
+ pointers to cv-qualified member function types.
+
+ * init.c (build_delete): Create a SAVE_EXPR for the address if
+ we're going to use it more than once.
+
+2001-04-13 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DELTA2_FROM_PTRMEMFUNC): Remove.
+ (expand_ptremfunc_cst): Change prototype.
+ (delta2_from_ptrmemfunc): Remove.
+ * expr.c (cplus_expand_constant): Adjust call to
+ expand_ptrmemfunc_cst.
+ * typeck.c (build_ptrmemfunc1): Simplify.
+ (build_ptrmemfunc): Make sure that casting a PTRMEM_CST still
+ results in a constant.
+ (expand_ptrmemfunc_cst): Remove idx and delta2 parameters.
+ (delta2_from_ptrmemfunc): Remove.
+ (pfn_from_ptrmemfunc): Adjust call to expand_ptrmemfunc_cst.
+
+2001-04-12 Jason Merrill <jason_merrill@redhat.com>
+
+ * cp-tree.h (decl_namespace_list): New macro.
+ (struct saved_scope): Add decl_ns_list.
+ * decl.c (mark_saved_scope): Mark it.
+ * decl2.c: Lose static decl_namespace_list.
+ (init_decl2): Don't save it.
+
+2001-04-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (warn_return_type, yylex): Delete redundant
+ declarations.
+
+ * decl.c (current_class_depth, global_namespace): Likewise.
+
+ * decl2.c (current_class_depth, flag_gnu_xref): Likewise
+
+ * repo.c (flag_use_repository): Likewise.
+
+2001-04-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (pedantic, convert, global_bindings_p, insert_block,
+ set_block, pushdecl, getdecls, gettags, init_decl_processing,
+ maybe_build_cleanup, copy_lang_decl, prep_stmt, lvalue_p,
+ lvalue_or_else, print_lang_statistics, comp_target_types,
+ unsigned_type, signed_type, signed_or_unsigned_type,
+ build_function_call, mark_addressable, incomplete_type_error):
+ Delete redundant declarations.
+
+2001-04-11 Jason Merrill <jason_merrill@redhat.com>
+
+ * cp-tree.h (TYPE_LINKAGE_IDENTIFIER): New macro.
+ (TYPE_ANONYMOUS_P): New macro.
+ (TAGGED_TYPE_P): New macro.
+ * decl.c (check_tag_decl): Use TYPE_ANONYMOUS_P.
+ (grokfndecl, grokvardecl, grokdeclarator): Likewise.
+ * tree.c (no_linkage_helper): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+ * pt.c (convert_template_argument): Likewise.
+ * lex.c (check_for_missing_semicolon): Likewise.
+
+2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (dfs_unshared_virtual_bases): New function.
+ (mark_primary_bases): Call it.
+ (check_bases): Ignore virtual bases when determining
+ nearly-emptiness.
+
+2001-04-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (make_thunk): Clear DECL_CLONED_FUNCTION.
+
+2001-04-11 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (maybe_clone_body): Copy DECL_NUM_STMTS from the
+ cloned function to the clone.
+
+2001-04-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (cp/semantics.o): Depend on $(EXPR_H).
+
+ * semantics.c: Include expr.h.
+
+2001-04-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (implicitly_declare_fn): Commonize code for copy ctor
+ and assignment op. Set TREE_USED for parameter.
+
+2001-04-10 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (find_final_overrider_data): Add `candidates'.
+ (dfs_find_final_overrider): Don't issue error messages
+ prematurely.
+ (find_final_overrider): Issue error messages here.
+ (build_base_field): Don't warn about amgibuous direct bases here.
+ (warn_about_ambiguous_direct_bases): New function.
+ (layout_class_type): Use it.
+
+2001-04-10 Richard Henderson <rth@redhat.com>
+
+ * typeck.c (build_array_ref): Push the array reference inside
+ COMPOUND_EXPR and COND_EXPR.
+
+2001-04-05 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_THIS_INLINE): Rename to DECL_DECLARED_INLINE_P.
+ * decl.c (duplicate_decls): Adjust accordingly.
+ (maybe_commonize_var): Likewise.
+ (grokfndecl): Likewise.
+ (start_function): Likewise.
+ (start_method): Likewise.
+ * decl2.c (key_method): Likewise.
+ (import_export_decl): Likewise.
+ * method.c (implicitly_declare_fn): Likewise.
+ * optimize.c (maybe_clone_body): Likewise.
+
+2001-04-05 Benjamin Kosnik <bkoz@redhat.com>
+
+ * lang-specs.h: Add __DEPRECATED.
+
+2001-04-05 J"orn Rennecke <amylaar@redhat.com>
+
+ * search.c (get_dynamic_cast_base_type): When building a new
+ constant, set its type to ssizetype.
+
+2001-04-04 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (expand_call_inline): Only add newly inlined statements
+ into inlined_stmts.
+
+2001-04-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (OPERATOR_ASSIGN_FORMAT): Remove.
+ (OPERATOR_FORMAT): Likewise.
+ (OPERATOR_TYPENAME_FORMAT): Likewise.
+ * operators.def: Remove old name-mangling information.
+ * decl.c (grok_op_properties): Adjust accordingly.
+ * lex.c (init_operators): Likewise.
+ * rtti.c (get_tinfo_decl): Issue error messages about types that
+ have variable size.
+
+2001-04-03 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (import_export_decl): Don't call import_export_class
+ when processing an inline member function.
+ * semantics.c (expand_body): Call import_export_decl before
+ emitting inline functions.
+
+2001-03-28 Richard Henderson <rth@redhat.com>
+
+ IA-64 ABI Exception Handling:
+ * cp-tree.def (EH_SPEC_BLOCK): New.
+ (MUST_NOT_THROW_EXPR): New.
+ * cp-tree.h: Update changed function declarations.
+ (CPTI_PUSH_EXCEPTION_IDENTIFIER): Remove.
+ (CPTI_CALL_UNEXPECTED): New.
+ (struct cp_language_function): Rename x_eh_spec_try_block
+ to x_eh_spec_block.
+ (EH_SPEC_STMTS, EH_SPEC_RAISES): New.
+ * decl.c (current_binding_level): If no current function
+ bindings, revert to scope_chain.
+ (initialize_predefined_identifiers): Remove __cp_push_exception.
+ (store_parm_decls): Use begin_eh_spec_block.
+ (finish_function): Use finish_eh_spec_block.
+ (mark_lang_function): Update for name changes.
+ * decl2.c (finish_file): No mark_all_runtime_matches.
+ * dump.c (cp_dump_tree): Handle new tree codes.
+ * error.c (dump_expr) [BIND_EXPR]: Fix typo.
+ * except.c (catch_language_init, catch_language): Remove.
+ (init_exception_processing): Don't set language code.
+ Initialize call_unexpected_node, protect_cleanup_actions,
+ eh_personality_libfunc, lang_eh_runtime_type.
+ (call_eh_info, push_eh_info, get_eh_info, get_eh_value): Remove.
+ (get_eh_type, get_eh_caught, get_eh_handlers): Remove.
+ (prepare_eh_type): Split out type canonicalizations ...
+ (build_eh_type_type): ... from here.
+ (build_eh_type_type_ref): Remove.
+ (mark_all_runtime_matches): Remove.
+ (build_exc_ptr): New.
+ (do_begin_catch, do_end_catch): New.
+ (do_pop_exception): Remove.
+ (build_terminate_handler): Remove.
+ (choose_personality_routine): Split out language choice from ...
+ (initialize_handler_parm): ... here.
+ Use MUST_NOT_THROW_EXPR.
+ (expand_start_catch_block): Use do_begin_catch. Simplify Java
+ exception object handling.
+ (expand_start_eh_spec, expand_end_eh_spec): Remove.
+ (expand_exception_blocks, alloc_eh_object): Remove.
+ (begin_eh_spec_block, finish_eh_spec_block): New.
+ (do_allocate_exception, do_free_exception): New.
+ (expand_throw): Merge into ...
+ (build_throw): ... here. Update for abi.
+ * expr.c (cplus_expand_expr): No expand_internal_throw.
+ Handle MUST_NOT_THROW_EXPR.
+ * pt.c (tsubst_expr): Handle EH_SPEC_BLOCK.
+ * semantics.c (*) Update for except.h name changes.
+ (genrtl_try_block): No protect_with_terminate.
+ (genrtl_eh_spec_block): New.
+ (genrtl_handler): Don't emit the goto here.
+ (cp_expand_stmt): Handle EH_SPEC_BLOCK.
+ (genrtl_finish_function): Don't expand_exception_blocks.
+ * tree.c (cp_statement_code_p): Handle EH_SPEC_BLOCK.
+
+2001-03-28 Richard Henderson <rth@redhat.com>
+
+ * decl.c (struct named_label_list): Rename eh_region to
+ in_try_scope, add in_catch_scope.
+ (struct binding_level): Rename eh_region to is_try_scope,
+ add is_catch_scope.
+ (note_level_for_try): Rename from note_level_for_eh.
+ (note_level_for_catch): New.
+ (poplevel): Copy both is_try_scope and is_catch_scope to
+ the named_label_list struct.
+ (check_previous_goto_1): Don't check for catch block via
+ DECL_ARTIFICIAL; use in_try_scope instead.
+ (check_goto): Likewise.
+ * cp-tree.h (note_level_for_try, note_level_for_catch): Declare.
+ * except.c (expand_start_catch_block): Call note_level_for_catch.
+ * semantics.c (begin_compound_stmt): Update for note_level_for_try.
+
+2001-03-27 Richard Henderson <rth@redhat.com>
+
+ * except.c: Use USING_SJLJ_EXCEPTIONS instead of
+ exceptions_via_longjmp.
+
+2001-03-27 Phil Edwards <pme@sources.redhat.com>
+
+ * pt.c (check_default_tmpl_args): Make error messages clearer.
+
+2001-03-26 Phil Edwards <pme@sources.redhat.com>
+
+ * error.c: Also undefine 'A' macro used for cp_printers definition.
+
+2001-03-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in: Depend on $(SYSTEM_H), not system.h.
+
+2001-03-26 Mike Yang <yang@research.att.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (dump_access): New function.
+ (cp_dump_tree): Use it. Dump basetype information for class
+ types.
+
+2001-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (optimize.o): Depend on params.h.
+ (duplicate_decls): Copy DECL_NUM_STMTS, not DECL_FRAME_SIZE.
+ (init_decl_processing): Set flag_no_inline when doing
+ inlining-on-trees.
+ * optimize.c: Include params.h.
+ (struct inline_data): Improve documentation of FNS. Add
+ FIRST_INLINED_FN, INLINED_STMTS, and CLONING_P.
+ (INSNS_PER_STMT): New macro.
+ (remap_block): Use CLONING_P.
+ (inlinable_function_p): Don't inline big functions.
+ (expand_call_inline): Keep track of how much inlining we've done.
+ (optimize_function): Set FIRST_INLINED_FN.
+ (maybe_clone_body): Set CLONING_P.
+ * semantics.c (simplify_aggr_init_exprs_r): Fix typing problems in
+ tree nodes.
+ (genrtl_finish_function): Clear DECL_DEFER_OUTPUT before calling
+ rest_of_compilation. Clear DECL_RTL for local variables
+ afterwards.
+ (clear_decl_rtl): New function.
+
+2001-03-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ Implement DR 209
+ * cp-tree.h (skip_type_access_control,
+ reset_type_access_control): Prototype.
+ * decl.c (grokdeclarator): Access of friends is not checked.
+ * parse.y (component_decl_list): Reset type access control.
+ * semantics.c (decl_type_access_control): Clear
+ current_type_lookups.
+ (save_type_access_control): Don't save if not deferring.
+ (skip_type_access_control, reset_type_access_control): New
+ functions.
+ (begin_class_definition): Do type access control for basetypes.
+ Start deferred access control.
+ (finish_class_definition): Resume immediate access control if
+ this is a local class.
+
+2001-03-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (add_method): Use memcpy/memmove, not bcopy.
+
+ * decl.c (duplicate_decls): Likewise.
+
+2001-03-23 Jakub Jelinek <jakub@redhat.com>
+
+ * mangle.c (write_discriminator): Use `_0' for discriminator 1,
+ not `_'.
+
+2001-03-23 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (local_names): Define.
+ (push_local_name): New.
+ (grok_reference_init): Return init if initializing static reference
+ variable with non-constant instead of emitting it.
+ Move expand_static_init call to cp_finish_decl.
+ (layout_var_decl): Call push_local_name.
+ (maybe_commonize_var): Allow inlining functions even if they have
+ static local variables, use comdat_linkage for them if flag_weak.
+ (check_initializer): Call obscure_complex_init if
+ grok_reference_init returned nonzero.
+ (save_function_data): Clear x_local_names.
+ (pop_cp_function_context): Free x_local_names.
+ (mark_inlined_fns): Remove.
+ (mark_lang_function): Mark x_local_names.
+ (lang_mark_tree): Don't mark DECL_ACCESS for DECL_DISCRIMINATOR_P.
+ Mark inlined_fns as tree, remove call to mark_inlined_fns.
+ * class.c (alter_access): Ensure DECL_ACCESS is never set if
+ DECL_DISCRIMINATOR_P.
+ * cp-tree.h (cp_language_function): Add x_local_names.
+ (lang_decl_flags): Add discriminator into u2.
+ (lang_decl_inlined_fns): Remove.
+ (lang_decl): inlined_fns is now a TREE_VEC.
+ (DECL_DISCRIMINATOR_P, DECL_DISCRIMINATOR): Define.
+ * optimize.c (inlinable_function_p): DECL_INLINED_FNS is now a
+ TREE_VEC, not a custom structure.
+ (optimize_function): Likewise.
+ * mangle.c (discriminator_for_local_entity): Discriminate among
+ VAR_DECL local entities.
+ * search.c (dfs_access_in_type): If DECL_DISCRIMINATOR_P, DECL_ACCESS
+ is not valid.
+
+2001-03-22 Bryce McKinlay <bryce@albatross.co.nz>
+
+ Add support for Java interface method calls.
+ * cp-tree.h (struct lang_type): Add java_interface flag.
+ (TYPE_JAVA_INTERFACE): New macro.
+ * tree.c (cp_valid_lang_attribute): Handle "java_interface" attribute
+ by setting TYPE_JAVA_INTERFACE.
+ * call.c (java_iface_lookup_fn): New static.
+ (build_over_call): If calling a method declared in a
+ TYPE_JAVA_INTERFACE, call build_java_interface_fn_ref to generate the
+ expression which resolves the function address.
+ (build_java_interface_fn_ref): New function.
+
+2001-03-22 Richard Henderson <rth@redhat.com>
+
+ * Make-lang.in (cp/except.o): Don't depend on insn-flags.h.
+ * except.c: Don't include it.
+
+2001-03-22 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+ based on an idea from Joe Buck <jbuck@synopsys.com>
+
+ * parse.y (bad_decl, template_arg_list_ignore, arg_list_ignore):
+ New nonterminals.
+ (data_def, component_decl): Add reductions to bad_decl.
+
+2001-03-22 Jakub Jelinek <jakub@redhat.com>
+
+ * method.c (do_build_assign_ref): Don't use build_modify_expr for
+ anonymous aggregates, since they don't have assignment operator
+ method.
+ * decl.c (fixup_anonymous_aggr): Disallow ctors, dtors and copy
+ assignment operators for anonymous structure fields.
+
+2001-03-21 Jason Merrill <jason@redhat.com>
+
+ * pt.c (instantiate_decl): Abort if we see a member constant
+ instantiation that doesn't already have its initializer.
+ Downgrade explicit instantiation without definition to pedwarn.
+
+ * cp-tree.h (DECL_TINFO_FN_P, SET_DECL_TINFO_FN_P): Remove.
+ * class.c (build_vtable_entry): Don't check DECL_TINFO_FN_P.
+ (import_export_decl): Check tinfo_decl_p, not DECL_TINFO_FN_P.
+
+ * cp-tree.h (CLASSTYPE_VTABLE_NEEDS_WRITING): Remove.
+ (pending_vtables): Remove.
+ * decl2.c (pending_vtables): Remove.
+ (import_export_vtable): Use CLASSTYPE_INTERFACE_ONLY, not
+ CLASSTYPE_VTABLE_NEEDS_WRITING.
+ (import_export_class): Likewise.
+ (init_decl2): Don't mark pending_vtables.
+ * lex.c (handle_pragma_vtable): Just sorry.
+ * pt.c (instantiate_class_template): Don't mess with
+ CLASSTYPE_VTABLE_NEEDS_WRITING.
+ (mark_class_instantiated): Likewise.
+ * ptree.c (print_lang_type): Don't print it.
+ * semantics.c (begin_class_definition): Don't set it.
+
+ * pt.c (template_tail): Replace with last_pending_template.
+ (maybe_templates, maybe_template_tail): Remove.
+ (add_pending_template): Adjust.
+ (instantiate_pending_templates): Adjust.
+
+ * cp-tree.h (struct saved_scope): Remove lang_stack field.
+ (current_lang_stack): Remove.
+ * decl.c (maybe_push_to_top_level): Don't initialize it.
+ (duplicate_decls): Use current_lang_depth.
+ (xref_basetypes): Likewise.
+ * class.c (current_lang_depth): New fn.
+ (push_lang_context): Use more varray functionality.
+ (pop_lang_context): Likewise.
+
+ * error.c (GLOBAL_THING): Always use '__'.
+
+2001-03-21 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_clone): Clear DECL_ASSEMBLER_NAME.
+
+ * mangle.c (mangle_decl_string): Mangle the names of overloaded
+ operators, even when they have `extern "C"' linkage.
+
+2001-03-19 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (get_vtable_decl): Use SET_DECL_ASSEMBLER_NAME,
+ COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
+ where it's not necessary.
+ (add_method): Remove optimization involving comparison of
+ DECL_ASSEMBLER_NAME.
+ (build_vtbl_or_vbase_field): Use SET_DECL_ASSEMBLER_NAME,
+ COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
+ where it's not necessary.
+ (check_methods): Likewise.
+ (build_clone): Likewise.
+ (built_vtt): Likewise.
+ * cp-tree.h (DECL_NEEDED_P): Likewise.
+ * decl.c (pushtag): Likewise.
+ (duplicate_decls): Likewise.
+ (pushdecl): Likewise.
+ (builtin_function): Likewise.
+ (build_library_fn_1): Set DECL_LANGUAGE for library functions.
+ (build_cp_library_fn): Likewise.
+ (maybe_commonize_var): Use SET_DECL_ASSEMBLER_NAME,
+ COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
+ where it's not necessary.
+ (make_rtl_for_nonlocal_decl): Likewise.
+ (cp_finish_decl): Likewise.
+ (grokfndecl): Likewise.
+ (grokvardecl): Likewise.
+ (grokdeclarator): Likewise.
+ (start_function): Likewise.
+ (cp_missing_return_ok_p): Likewise.
+ * decl2.c (grokclassfn): Likewise.
+ (check_classfn): Likewise.
+ (finish_static_data_member_decl): Likewise.
+ (grokfield): Likewise.
+ * error.c (GLOBAL_IORD_P): Remove.
+ (dump_global_iord): Improve output.
+ (dump_decl): Avoid using DECL_ASSEMBLER_NAME.
+ * except.c (nothrow_libfn_p): Summarily reject any function not in
+ namespace-scope.
+ * init.c (build_java_class_ref): Don't explicitly set
+ DECL_ASSEMBLER_NAME after calling mangle_decl.
+ * mangle.c (mangle_decl_string): Handle extern "C" functions.
+ (mangle_decl): Set the DECL_ASSEMBLER_NAME for the decl.
+ * method.c (set_mangled_name_for_decl): Don't explicitly set
+ DECL_ASSEMBLER_NAME after calling mangle_decl.
+ (make_thunk): Explicitly set the DECL_ASSEMBLER_NAME and
+ IDENTIFIER_GLOBAL_VALUE for the thunk.
+ * pt.c (set_mangled_name_for_template_decl): Remove.
+ (check_explicit_specialization): Don't use it.
+ (looup_template_class): Don't set DECL_ASSEMBLER_NAME.
+ (tsubst_friend_function): Likewise.
+ (tsubst_decl): Likewise.
+ (regenerate_decl_from_template): Use COPY_DECL_ASSEMBLER_NAME.
+ * rtti.c (get_tinfo_decl): Use SET_DECL_ASSEMBLER_NAME,
+ COPY_DECL_ASSEMBLER_NAME, etc. Don't set DECL_ASSEMBLER_NAME
+ where it's not necessary.
+ (tinfo_base_init): Likewise.
+ (create_real_tinfo_var): Likewise.
+ * search.c (looup_field_1): Likewise.
+ * semantics.c (finish_named_return_value): Likewise.
+ * tree.c (init_tree): Set lang_set_decl_assembler_name.
+
+2001-03-15 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ Correct semantics restrictions checking in throw-expression.
+ * except.c (is_admissible_throw_operand): New function.
+ (build_throw): Use it.
+
+2001-03-14 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (cp_make_fnname_decl): Set DECL_IGNORED_P on __FUNCTION__
+ and its ilk.
+
+2001-03-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_clone): Use COPY_DECL_RTL, DECL_RTL_SET_P, etc.
+ * cp-tree.h (DECL_IN_MEMORY_P): Likewise.
+ * decl.c (duplicate_decls): Likewise.
+ (builtin_function): Likewise.
+ (build_library_fn): Likewise.
+ (build_cp_library_fn): Likewise.
+ (check_initializer): Likewise.
+ (cp_finish_decl): Likewise.
+ * decl2.c (grokfield): Likewise.
+ (grok_function_init): Remove #if 0'd code.
+ (finish_anon_union): Use COPY_DECL_RTL, DECL_RTL_SET_P, etc.
+ * friend.c (do_friend): Likewise.
+ * init.c (get_temp_regvar): Likewise.
+ * method.c (make_thunk): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+ (tsubst_decl): Likewise.
+ (regenerate_decl_from_template): Likewise.
+ * semantics.c (genrtl_named_return_value): Likewise.
+ (expand_body): Likewise.
+ (genrtl_finish_function): Likewise.
+ * tree.c (cp_tree_equal): Likewise.
+
+2001-03-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (convert_like_real): Add extra semantics to INNER
+ parameter. Don't convert to temporary if a user conversion
+ gives us an lvalue that we're about to bind to a reference.
+ Set INNER to indicate pending reference binding on recursive
+ calls.
+
+2001-03-10 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp/lex.c: Delete duplicate pending_lang_change.
+
+2001-03-10 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp/lex.c (handle_pragma_interface, handle_pragma_implementation):
+ Similarly.
+ * cp/repo.c (get_base_filename, open_repo_file): Similarly.
+ * cp/cp-tree.h: Remove file_name_nondirectory prototype.
+
+2001-03-09 Zack Weinberg <zackw@stanford.edu>
+
+ * Make-lang.in: Add dependencies on $(TM_P_H) as appropriate.
+
+2001-03-08 Stan Shebs <shebs@apple.com>
+
+ * cp-tree.h (set_identifier_local_value): Remove unused decl.
+
+2001-03-06 Zack Weinberg <zackw@stanford.edu>
+
+ * spew.c: Remove references to CPP_OSTRING.
+
+2001-03-06 Andrew Haley <aph@redhat.com>
+
+ * typeck.c (convert_arguments): Check that we have an fndecl.
+
+2001-03-05 Andrew Haley <aph@redhat.com>
+
+ * typeck.c (convert_arguments): Don't do ellipsis conversion for
+ __built_in_constant_p.
+
+2001-03-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (build_static_cast): Allow enum to enum conversions
+ as per DR 128.
+
+2001-03-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (check_field_decls): Pointers to member do not a
+ non-pod struct make, as per DR 148.
+
+2001-03-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (joust): cp_pedwarn when using gnu extension concerning
+ worst conversion sequences.
+
+2001-03-01 Zack Weinberg <zackw@stanford.edu>
+
+ * decl.c: Replace all uses of 'boolean' with 'bool'.
+
+2001-03-01 Zack Weinberg <zackw@stanford.edu>
+
+ * lang-specs.h: Add zero initializer for cpp_spec field to
+ all array elements that need one. Don't put an #ifdef inside
+ the initializer list; set a default for CPLUSPLUS_CPP_SPEC and
+ use it.
+
+2001-03-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ Implement using decls inside template functions.
+ * decl2.c (validate_nonmember_using_decl): Don't special case
+ fake_std_node in the global namespace. Don't reject early when
+ processing a template.
+ (do_local_using_decl): Add to statement tree. Don't do further
+ processing when building a template.
+ * pt.c (tsubst_expr, DECL_STMT case): Deal with USING_DECLs.
+
+2001-03-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (do_nonmember_using_decl): Don't complain if we find
+ same function. Do complain about ambiguating extern "C"
+ declarations.
+
+2001-02-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ Remove floating point and complex type template constant parms.
+ * pt.c (convert_nontype_argument): Remove REAL_TYPE and
+ COMPLEX_TYPE extensions.
+ (invalid_nontype_parm_type_p): Likewise.
+
+2001-02-27 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * except.c (call_eh_info): Revert "match_function"'s type.
+
+2001-02-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ Fix ctor vtable vcall offsets.
+ * class.c (struct vtbl_init_data_s): Add rtti_binfo member.
+ (build_rtt_vtbl_entries): Lose RTTI_BINFO parameter.
+ (get_matching_base): Remove.
+ (get_original_base): New function.
+ (build_vtbl_initializer): Initialize vid.rtti_binfo.
+ Use a virtual thunk for a ctor vtable with an index
+ (add_vcall_offset_vtbl_entries_1): Check if binfo has lost a
+ primary base within a constructor vtable. Only set
+ BV_VCALL_INDEX when not a constructor vtable. Adjust vcall offset
+ when primary base has been lost.
+ * cp-tree.h (BINFO_VIRTUALS): Remove ambiguity from comment.
+
+2001-02-26 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * call.c (joust): Ensure more_specialized()'s argument length
+ parameter has correct value for constructors.
+
+2001-02-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * except.c (call_eh_info): Cleanup generation of cp_eh_info struct.
+
+ * decl.c (mark_inlined_fns): Prototype.
+
+2001-02-22 Mark Mitchell <mark@codesourcery.com>
+
+ * spew.c (yylex): Correct handling of friends.
+
+2001-02-22 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_encoding): Pass write_function_type the
+ FUNCTION_DECL for the function being encoded.
+ (write_function_type): Pass it along to write_bare_function_type.
+ (write_bare_function_type): Pass it along to write_method_parms.
+ (write_method_parms): Don't mangle the compiler-generated
+ parameters to a constructor or destructor.
+
+2001-02-22 Andreas Jaeger <aj@suse.de>
+
+ * optimize.c: Include toplev.h for
+ note_deferral_of_defined_inline_function prototype.
+
+2001-02-22 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (struct lang_decl_inlined_fns): New.
+ (struct lang_decls): Add inlined_fns.
+ (DECL_INLINED_FNS): New macro.
+ * optimize.c (struct inline_data): Add inlined_fns.
+ (declare_return_variable): Use VARRAY_ACTIVE_SIZE macro.
+ (inlinable_function_p): Likewise, fix typo in comment,
+ function is not inlinable if it already inlined function currently
+ being optimized.
+ (expand_call_inline): Add fn to inlined_fns if necessary.
+ (optimize_function): Initialize inlined_fns.
+ Save inlined_fns into DECL_INLINED_FNS after expanding inlines.
+ * decl.c (mark_inlined_fns): New function.
+ (lang_mark_tree): Call it.
+
+2001-02-21 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (struct lang_decl_flags): Remove uninlinable flag.
+ (DECL_UNINLINABLE): Move to middle-end.
+
+ * class.c (clone_function_decl): Set DECL_ABSTRACT on original fn.
+ * decl.c (duplicate_decls): Preserve DECL_ABSTRACT.
+ * class.c (build_clone): Set DECL_ABSTRACT_ORIGIN for the clone.
+ * optimize.c (maybe_clone_body): Set DECL_ABSTRACT_ORIGIN for the
+ parms and outer BLOCK. note_deferral_of_defined_inline_function.
+
+ * method.c (implicitly_declare_fn): Don't set DECL_ARTIFICIAL on
+ second parm of op=.
+
+2001-02-19 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (set_decl_namespace): Allow explicit instantiations in
+ any namespace.
+
+2001-02-18 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * optimize.c (expand_call_inline): Don't walk subtrees of type
+ nodes.
+
+2001-02-18 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_vcall_offset_vtbl_entries_1): Only add one entry
+ for a destructor.
+
+2001-02-18 Jason Merrill <jason@redhat.com>
+
+ Do put the VTT parameter in DECL_ARGUMENTS.
+ * cp-tree.h (struct cp_language_function): Add x_vtt_parm.
+ (current_vtt_parm): New macro.
+ (struct lang_decl_flags): Add has_vtt_parm_p, remove vtt_parm.
+ (DECL_HAS_VTT_PARM_P): New macro.
+ (DECL_VTT_PARM): Remove.
+ (FUNCTION_FIRST_USER_PARMTYPE, FUNCTION_FIRST_USER_PARM): New macros.
+ * decl.c (duplicate_decls): Only copy the operator code if
+ appropriate.
+ (start_function): Set current_vtt_parm.
+ (lang_mark_tree): Don't mark vtt_parm.
+ * decl2.c (maybe_retrofit_in_chrg): Do add the VTT parm to
+ DECL_ARGUMENTS. Set DECL_HAS_VTT_PARM_P.
+ * class.c (build_clone): Maybe remove the VTT parm.
+ * optimize.c (maybe_clone_body): Set up the VTT parm.
+ * pt.c (copy_default_args_to_explicit_spec): Preserve the VTT parm.
+ * call.c (build_over_call): Just allow the VTT arg.
+ * method.c (make_thunk): Don't set DECL_VTT_PARM.
+ (do_build_copy_constructor): Use FUNCTION_FIRST_USER_PARM.
+ (synthesize_method): Use FUNCTION_FIRST_USER_PARMTYPE.
+ * decl.c (grokdeclarator, copy_args_p, grok_ctor_properties): Likewise.
+ * error.c (dump_function_decl): Likewise.
+ * call.c (build_user_type_conversion_1, convert_like_real): Abort
+ if we try to call a constructor with in-charge or VTT parms.
+ * method.c (skip_artificial_parms_for): New fn.
+ * call.c (add_function_candidate, build_over_call): Call it.
+ * call.c (build_new_method_call): Use current_vtt_parm.
+ * init.c (expand_virtual_init): Likewise.
+ * class.c (same_signature_p): No longer static.
+ * cp-tree.h: Declare it.
+ * search.c (look_for_overrides_r): Use it.
+
+2001-02-17 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (new_abi_rtti_p): Remove.
+ (name_mangling_version): Likewise.
+ (flag_do_squangling): Likewise.
+ * class.c (build_rtti_vtbl_entries): Remove old ABI support.
+ * decl.c (grokfndecl): Likewise.
+ * decl2.c (name_mangling_version): Remove.
+ (flag_do_squangling): Likewise.
+ (lang_f_options): Remove `squangle'.
+ (unsupported_options): Add `squangle'.
+ (cxx_decode_option): Issue a warning about uses of
+ -fname-mangling-version.
+ (finish_file): Remove old ABI support.
+ * pt.c (check_explicit_specialization): Likewise.
+ (tsubst_decl): Likewise.
+ * rtti.c (init_rtti_processing): Likewise.
+ (build_headof): Likewise.
+ (get_tinfo_decl_dynamic): Likewise.
+ (tinfo_from_decl): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ (synthesize_tinfo_var): Likewise.
+ * init.c (build_new): Allow enumeration types for the array-bounds
+ in a direct-new-declarator.
+
+ * semantics.c (finish_typeof): Resolve OFFSET_REFs.
+
+ * pt.c (check_explicit_specialization): Copy TREE_PRIVATE and
+ TREE_PROTECTED from the template being specialized.
+
+2001-02-17 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (build_artificial_parm): Set TREE_READONLY.
+
+ * decl.c (bad_specifiers): Allow throw specs on things with
+ pointer-to-function or -member-function type.
+ * init.c (build_default_init): Don't use a CONSTRUCTOR to initialize
+ a pmf.
+
+2001-02-17 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (check_dtor_name): Handle template names correctly.
+
+2001-02-16 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_USE_VTT_PARM): Remove.
+ * decl2.c (maybe_retrofit_in_chrg): Don't create it.
+ * optimize.c (maybe_clone_body): Don't substitute it.
+ * call.c (build_new_method_call): Check in_chrg instead.
+ * init.c (expand_virtual_init): Likewise.
+
+2001-02-16 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl.c (check_tag_decl): Make sure a typedef for an anonymous
+ class-type introduces at least a type-name.
+
+2001-02-16 Jakub Jelinek <jakub@redhat.com>
+
+ * call.c (convert_like_real): Create a temporary for non-lvalue.
+
+2001-02-16 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * cp-tree.h: Fix typos in comments.
+
+2001-02-16 Jason Merrill <jason@redhat.com>
+
+ * optimize.c (remap_block): If we're compiling a clone, pass the
+ new block to insert_block.
+
+2001-02-16 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (finish_asm_stmt): Robustify.
+
+2001-02-15 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (push_template_decl_real): Don't remangle the name of a
+ class template.
+
+2001-02-15 Jim Meyering <meyering@lucent.com>
+
+ * Make-lang.in (c++.install-common): Depend on installdirs.
+ (c++.install-info): Likewise.
+ (c++.install-man): Likewise.
+
+2001-02-15 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck2.c (build_m_component_ref): Robustify.
+
+2001-02-15 Alexandre Oliva <aoliva@redhat.com>
+
+ * friend.c (do_friend): Don't take the nested [template] class
+ into account when deciding whether to warn about the friend
+ function not referring to a template function.
+
+2001-02-14 Jakub Jelinek <jakub@redhat.com>
+
+ * typeck.c (build_unary_op): Clarify error message.
+
+2001-02-08 Aldy Hernandez <aldyh@redhat.com>
+
+ * parse.y (component_constructor_declarator): allow optional
+ parentheses around constructor class name.
+
+2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (setup_vtbl_ptr): Move prototype to semantics.c
+ section.
+ * init.c (emit_base_init): Remove incorrect comment about
+ virtual bases.
+ * method.c (make_thunk): Fix comment alignment.
+
+2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ Kill remnants of this is variable.
+ * cp-tree.h (flag_this_is_variable): Remove.
+ * decl2.c (flag_this_is_variable): Remove.
+ * class.c (fixed_type_or_null): Add cdtor parm. Adjust.
+ (build_vbase_path): The path is non-static, even in a cdtor.
+ (resolves_to_fixed_type_p): Add additional return value.
+ * search.c (init_vbase_pointers): Adjust.
+ * tree.c (lvalue_p_1): Adjust.
+ * typeck.c (mark_addressable): Adjust.
+
+2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (unify): Don't check cv quals of array types.
+
+2001-02-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (cp_build_qualified_type_real): Use CP_TYPE_QUALS to
+ check whether we already have the type.
+
+2001-02-13 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_DESTRUCTORS): Fix typo in comment.
+ * call.c (build_op_delete_call): Simplify to remove duplicate
+ code.
+ * class.c (clone_function_decl): Don't build the deleting variant
+ of a non-virtual destructor.
+ * decl.c (finish_destructor_body): Don't call delete if this is a
+ non-virtual destructor.
+ * init.c (build_delete): Explicitly call `operator delete' when
+ deleting an object with a non-virtual destructor.
+
+2001-02-13 Jason Merrill <jason@redhat.com>
+
+ * lang-specs.h: Add more __EXCEPTIONS.
+
+2001-02-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck2.c (process_init_constructor): Check
+ TREE_HAS_CONSTRUCTOR before issuing missing init warning.
+
+2001-02-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (maybe_adjust_types_for_deduction, DEDUCE_ORDER case):
+ Remove spurious information in comment. Allow further
+ adjustments of REFERENCE_TYPE args.
+
+2001-02-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * errfn.c (cp_deprecated): Tweak diagnostic text.
+ * parse.y (new_initializer): Deprecate initializer lists
+ extension.
+
+2001-02-12 Mark Mitchell <mark@codesourcery.com>
+
+ Remove old ABI support.
+
+2001-02-11 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (flag_vtable_thunks): Always set it to 1.
+ (flag_new_abi): Likewise.
+ * lang-specs.h: Remove conditional on ENABLE_NEW_GXX_ABI.
+
+ * Makefile.in (g++spec.o): Fix typo.
+
+2001-02-09 Jason Merrill <jason@redhat.com>
+
+ * lang-specs.h: Restore definition of __EXCEPTIONS.
+
+2001-02-08 Jason Merrill <jason@redhat.com>
+
+ * search.c (shared_member_p): New function.
+ (lookup_field_r): Use it.
+ * cp-tree.h (SHARED_MEMBER_P): Remove.
+
+ * method.c (process_overload_item): Handle template-dependent array
+ bounds.
+ * pt.c (type_unification_real): If we end up with undeduced nontype
+ parms, try again.
+
+ * decl.c (lookup_name_real): Tweak warning to refer to decls, not
+ types.
+
+ * typeck2.c (friendly_abort): Don't say anything if we have
+ earlier errors or sorries.
+
+ * decl.c (check_tag_decl): Notice attempts to redefine bool and
+ wchar_t. Ignore if in_system_header.
+
+ * decl.c (maybe_push_cleanup_level): New fn...
+ (start_decl_1): ...split out from here.
+ * cvt.c (build_up_reference): Use it.
+ * cp-tree.h: Declare it.
+
+2001-02-07 Mark Mitchell <mark@codesourcery.com>
+
+ * lang-specs.h: Use CPLUSPLUS_CPP_SPEC for the preprocessor
+ spec.
+
+2001-02-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (lookup_template_class): Make sure it's a primary
+ template or template_template_parm when called from the parser.
+ (instantiate_template_class): Add assertion.
+
+2001-02-05 Alexandre Oliva <aoliva@redhat.com>
+
+ * method.c (build_mangled_name) [old abi]: Protect flush_repeats()
+ from error_mark_node.
+
+2001-02-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ Fix specification and implementation bugs in V3 ABI
+ construction vtables.
+ * cp-tree.h (flag_dump_class_layout): New flag.
+ (BINFO_OVERRIDE_ALONG_VIRTUAL_PATH_P): Remove.
+ (BINFO_LOST_PRIMARY_P): New flag.
+ (SET_BINFO_NEW_VTABLE_MARKED): Adjust asserts.
+ (BINFO_PRIMARY_MARKED_P): Rename to ...
+ (BINFO_PRIMARY_P): ... here.
+ (binfo_via_virtual): New prototype.
+ * decl2.c (flag_dump_class_layout): New flag.
+ (cxx_decode_option): Set it. Adjust -fdump-translation-unit to
+ use `=' as a file name separator.
+ * init.c (dfs_initialize_vtbl_ptrs): Walk into virtual primary
+ bases.
+ (build_vtbl_address): If this is a virtual primary base, then
+ get the vtbl of what it is ultimately primary for.
+ * search.c (dfs_skip_nonprimary_vbases_unmarkedp): Adjust
+ for BINFO_PRIMARY_P.
+ (dfs_skip_nonprimary_vbases_markedp): Likewise.
+ (get_shared_vbase_if_not_primary): Likewise.
+ (dfs_get_pure_virtuals): Likewise.
+ (expand_upcast_fixups): Likewise.
+ (fixup_virtual_upcast_offsets): Likewise.
+ (dfs_find_vbase_instance): Likewise.
+ (find_vbase_instance): Likewise.
+ (binfo_from_vbase): Adjust comment to reflect reality.
+ (binfo_via_virtual): New function.
+ * class.c (VTT_TOP_LEVEL_P, VTT_MARKED_BINFO_P): New macros
+ for binfo walking during VTT construction.
+ (dfs_mark_primary_bases): Remove.
+ (force_canonical_binfo_r): New function.
+ (force_canonical_binfo): New function.
+ (mark_primary_virtual_base): New function.
+ (mark_primary_bases): Walk in inheritance graph order, use
+ mark_primary_virtual_base.
+ (determine_primary_base): Use some more intermediate variables.
+ (dfs_find_final_overrider): Don't check for overriding along a
+ virtual path.
+ (dfs_modify_vtables): Walk into primary virtual bases too.
+ (walk_subobject_offsets): Adjust for BINFO_PRIMARY_P.
+ (build_base_fields): Likewise.
+ (dfs_set_offset_for_unshared_vbases): Likewise.
+ (layout_virtual_bases): Likewise.
+ (end_of_class): Likewise.
+ (finish_struct_1): Call dump_class_hierarchy, if requested.
+ (dfs_get_primary_binfo): Use BINFO_TYPE for binfos.
+ (dump_class_hierarchy_r): Add stream parameter. Emit more information.
+ (dump_class_hierarchy): Add file parameter. Append to file, if
+ required.
+ (finish_vtbls): Adjust accumulate_vtbl_inits call.
+ Use canonical base for virtual bases.
+ (build_vtt): Add more comments. Adjust build_vtt_inits call.
+ (build_vtt_inits): Remove VIRTUAL_VTTS_P parm.
+ Only set BINFO_VPTR_INDEX on top level. Use VTT_TOP_LEVEL_P,
+ VTT_MARKED_BINFO_P for binfo walking. Use canonical vbase for
+ virtual VTTs.
+ (dfs_build_secondary_vptr_vtt_inits): Extract VTT_TOP_LEVEL_P
+ from DATA. We want virtual primary bases and all bases via virtual.
+ Only set BINFO_VPTR_INDEX for top level. Look up from a primary
+ virtual base when not a construction vtable.
+ (dfs_ctor_vtable_bases_queue_p): New DFS predicate.
+ (build_ctor_vtbl_group): Adjust accumulate_vtbl_inits call.
+ Use canonical bases when processing virtual bases.
+ (accumulate_vtbl_inits): We're interested in any base via a
+ virtual path.
+ (dfs_accumulate_vtbl_inits): If this is a primary virtual base
+ within a construction vtable, determine what is being overridden.
+ (build_vtbl_initializer): Add more comments
+ (add_vcall_offset_vtbl_entries_1): Adjust comment.
+ (build_rtti_vtbl_entries): Check if the base has lost its
+ primary.
+
+2001-02-05 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (g++spec.o): Adjust use of DRIVER_DEFINES.
+
+2001-02-04 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (pushdecl): Call abort instead of fatal.
+ * except.c (decl_is_java_type): Call fatal_error instead of fatal.
+ * init.c (build_new_1): Likewise.
+ (build_java_class_ref): Call internal_error and fatal_error, not fatal.
+ * decl.c (build_typename_type): hash_table_init now returns void.
+ decl.c (init_decl_processing): Make an error non-fatal.
+
+2001-02-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_INTERFACE_UNKNOWN): Fix formatting.
+ Document.
+ (CLASSTYPE_INTERFACE_KNOWN): Likewise.
+ (SET_CLASSTYPE_INTERFACE_UNKNOWN_X): Likewise.
+ (SET_CLASSTYPE_INTERFACE_UNKNOWN): Likewise.
+ (SET_CLASSTYPE_INTERFACE_KNOWN): Likewise.
+ * decl.c (maybe_commonize_var): Use the new name-mangling where
+ appropriate.
+ * decl2.c (comdat_linkage): Enhance comments. Make all
+ compiler-generated things static, if COMDAT is not available.
+ (get_tinfo_decl): Do not make typeinfo objects that belong in the
+ library COMDAT.
+ (tinfo_base_init): Use the correct mangled name for typeinfo
+ strings, and push them into the global scope.
+ (typeinfo_in_lib_p): New function.
+ (synthesize_tinfo_var): Use it.
+ (create_real_tinfo_var): Likewise.
+
+2001-02-03 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (push_class_binding): Use context_for_name_lookup instead
+ of CP_DECL_CONTEXT.
+ * search.c (context_for_name_lookup): Remove static. Check for NULL
+ context in the loop.
+ * cp-tree.h (context_for_name_lookup): Add prototype.
+
+2001-02-02 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (build_expr_ptr_wrapper, can_free): Remove.
+ * tree.c (build_expr_ptr_wrapper, can_free, permanent_obstack):
+ Remove.
+ * call.c (convert_class_to_reference, build_user_type_conversion_1,
+ add_warning): Change build_expr_ptr_wrapper to build_ptr_wrapper.
+
+2001-02-02 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (g++spec.o): Add DRIVER_DEFINES to the list
+ of macros used when compiling g++spec.c.
+ * g++spec.c (lang_specific_driver): Link with the shared
+ libgcc by default.
+
+2001-01-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (build_expr_from_tree), lex.c (make_pointer_declarator,
+ make_reference_declarator, make_call_declarator), method.c
+ (implicitly_declare_fn), parse.y (namespace_using_decl,
+ notype_unqualified_id, expr_or_declarator, new_type_id,
+ after_type_declarator, direct_after_type_declarator,
+ notype_declarator, complex_notype_declarator,
+ complex_direct_notype_declarator, qualified_id,
+ notype_qualified_id, overqualified_id, direct_new_declarator,
+ absdcl, direct_abstract_declarator, conversion_declarator), pt.c
+ (tsubst), semantics.c (begin_constructor_declarator): Use build_nt
+ instead of build_parse_node.
+
+2001-01-28 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (cp_tree_index): Delete CPTI_MINUS_ONE.
+ (minus_one_node): Moved to top level gcc directory. Renamed
+ to integer_minus_one_node.
+
+ * init.c (init_init_processing): Don't set minus_one_node.
+ (build_vec_init): Use integer_minus_one_node.
+
+ * rtti.c (get_tinfo_decl_dynamic): Likewise.
+
+2001-01-28 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (copy_body_r): If MODIFY_EXPR has both arguments
+ identical and they would be replaced with constant, remove
+ MODIFY_EXPR from the tree.
+
+2001-01-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in: Remove all dependencies on defaults.h.
+ * call.c: Don't include defaults.h.
+ * decl.c: Likewise.
+ * decl2.c: Likewise.
+ * except.c: Likewise.
+ * pt.c: Likewise.
+ * rtti.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+
+2001-01-25 Jakub Jelinek <jakub@redhat.com>
+
+ * mangle.c (write_mangled_name, write_encoding): Mangle overloaded
+ operators even in "C" linkage.
+ * method.c (set_mangled_name_for_decl): Likewise.
+ * decl.c (grokfndecl): Call set_mangled_name_for_decl even for
+ overloaded operators in "C" linkage.
+
+2001-01-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst_decl): Remove IN_DECL parameter.
+ (tsubst_arg_types): Check parameter is not void.
+ (tsubst): Adjust tsubst_decl call.
+
+2001-01-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (add_builtin_candidate): Quote std properly, from
+ previous change.
+
+2001-01-23 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (check_explicit_specialization): Clone constructors and
+ destructors.
+
+2001-01-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Don't presume DECL_LANG_SPECIFIC
+ indicates anything special about template depth. Make sure we
+ only count the user visible template classes.
+
+2001-01-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_conv): Typo in comment.
+ (add_builtin_candidate): Add more explanation.
+ Remove extra test for ENUMERAL_TYPE in {PRE,POST}INCREMENT_EXPR.
+ Allow ENUMERAL_TYPEs for relops and eqops. Add both candidates
+ when we have enumeral types.
+ (add_builtin_candidates): Add more explanation. Add ENUMERAL_TYPE
+ candidates for relops and eqops.
+ (joust): Simplify control flow. Allow a non-template user
+ function to hide a builtin.
+
+2001-01-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (unification_kind_t): Add DEDUCE_ORDER.
+ (more_specialized): Add deduction parameter.
+ * call.c (joust): Adjust more_specialized call.
+ * pt.c (UNIFY_ALLOW_OUTER_MORE_CV_QUAL,
+ UNIFY_ALLOW_OUTER_LESS_CV_QUAL): New unify flags.
+ (get_bindings_order): Remove.
+ (get_bindings_real): Add DEDUCE parameter.
+ (maybe_adjust_types_for_deduction): Return extra unify flags. Do
+ REFERENCE_TYPE jig for DEDUCE_ORDER.
+ (type_unification_real): Deal with DEDUCE_ORDER. Use result of
+ maybe_adjust_types_for_deduction.
+ (more_specialized): Add DEDUCE parameter. Call get_bindings_real
+ directly.
+ (try_one_overload): Use result of maybe_adjust_types_for_deduction.
+ (check_cv_quals_for_unify): Use new unify qualifier flags.
+ (unify): Clear new unify qualifier flags.
+ (get_bindings_real): Add DEDUCE parameter.
+ (get_bindings): Adjust call to get_bindings_real.
+ (get_bindings_overload): Likewise.
+ (most_specialized_instantiation): Adjust call to
+ more_specialized.
+
+2001-01-19 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (flag_vtable_thunks): Also depend on ENABLE_NEW_GXX_ABI.
+
+ * decl.c (init_decl_processing): Just force -fvtable-thunks on if
+ -fnew-abi.
+
+2001-01-19 Ute Pelkmann <scope.muc@t-online.de>
+
+ * decl2.c (arg_assoc_class): Fix double iteration logic.
+
+2001-01-19 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_delete): Always call convert_force to strip cv-quals.
+
+ * decl2.c (flag_new_abi): Depend on ENABLE_NEW_GXX_ABI.
+ * lang-specs.h: Default ABI depends on ENABLE_NEW_GXX_ABI.
+ * g++spec.c: Don't look at ENABLE_NEW_GXX_ABI.
+
+2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (get_vbase_1): Count only virtual bases.
+
+2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (duplicate_tag_error): Robustify flag clearing.
+
+2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (lookup_template_class): Add complain parm.
+ * decl.c (lookup_namespace_name): Adjust call to
+ lookup_template_class.
+ (make_typename_type): Likewise.
+ * semantics.c (finish_template_type): Likewise.
+ * pt.c (lookup_template_class): Add complain parm. Adjust.
+ (tsubst_aggr_type): Pass COMPLAIN down to lookup_template_class.
+ (tsubst): Likewise.
+
+2001-01-19 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (copy_default_args_to_explicit_spec): Preserve
+ object's CV quals. Reorganize.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (build_modify_expr): Say `initialization' for
+ INIT_EXPRs.
+ * init.c (build_default_init): Convert to enumeral type, if
+ needed.
+
+2001-01-18 Jakub Jelinek <jakub@redhat.com>
+
+ * parse.y (nomods_initdcl0): Properly set things up for
+ initdcl0_innards.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (UNIFY_ALLOW_OUTER_LEVEL): New unify flag.
+ (type_unification_real): Set it.
+ (unify): Use it.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (finish_destructor_body): Convert to vbase pointer here.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * semantics.c (begin_class_definition): Check we're not inside a
+ template parm list.
+
+2001-01-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tree.c (walk_tree, TREE_LIST): Don't walk the TREE_PURPOSE of
+ BASELINK_P.
+
+2001-01-16 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * typeck.c (build_function_call_real): Call fold on the CALL_EXPR.
+ * call.c (build_over_call): Add comment.
+
+2001-01-16 Daniel Berlin <dberlin@redhat.com>
+
+ * cvt.c (ocp_convert): Handle vector type conversion
+ * typeck2.c (digest_init): Handle vector type initializations
+
+2001-01-16 Phil Edwards <pme@sources.redhat.com>
+
+ * g++spec.c: Don't add libraries needlessly if -fsyntax-only
+ was given.
+
+2001-01-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (check_nontype_parm): Rename to ...
+ (invalid_nontype_parm_type_p): ... here.
+ (process_template_parm): Adjust.
+ (convert_template_argument): Adjust.
+
+2001-01-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (check_nontype_parm): New function.
+ (process_template_parm): Use it.
+ (convert_template_argument): Use it.
+ (convert_nontype_argument, RECORD_TYPE): Assert it's a ptr to
+ member.
+
+2001-01-14 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * tree.c: Add defaults.h
+ (cp_valid_lang_attribute): Incorporate SUPPORTS_INIT_PRIORITY.
+ * Make-lang.in (cp/tree.o): Add defaults.h.
+
+2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (CXX_C_OBJS): Add c-format.o.
+
+2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g++.1: Change to be ".so man1/gcc.1".
+
+2001-01-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (c++.info, c++.install-info): Build and install g++
+ internals info.
+ (c++.uninstall, c++.maintainer-clean): Remove g++ internals info.
+ ($(srcdir)/cp/g++int.info): New target.
+ * gxxint.texi: Add info directory entry. Use @@ in email address.
+ * .cvsignore: Update.
+
+2001-01-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (build_c_cast): Do template processing earlier.
+ Always pedwarn on array casts.
+
+2001-01-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * friend.c (make_friend_class): Make sure a templated class is
+ actually a template.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (get_guard): Set linkage from guarded decl.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (convert_default_arg): Check for unprocessed
+ DEFAULT_ARG.
+ * cp-tree.h (replace_defarg): Move to spew.c.
+ (maybe_snarf_defarg, add_defarg_fn, do_pending_defargs): Move to
+ spew.c, which is where they really are.
+ (done_pending_defargs): Declare.
+ (unprocessed_defarg_fn): Declare.
+ * decl.c (replace_defarg): Move to spew.c
+ * parse.y (structsp): Call done_pending_defargs.
+ * spew.c (defarg_fns): Rearrange list structure.
+ (defarg_fnsdone): New static variable.
+ (defarg_depfns): New static variable.
+ (init_spew): Adjust.
+ (add_defarg_fn): Store the type in TREE_TYPE.
+ (do_pending_defargs): Detect and deal with ordering constraints
+ and circularity.
+ (done_pending_defargs): New function.
+ (unprocessed_defarg_fn): New function.
+ (replace_defarg): Moved from decl.c. Robustify. Don't save
+ if circularity detected.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (unify): Check array has a domain, before checking
+ whether it is variable sized.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokparms): Unobfuscate and get correct diagnostic for
+ parameters with pointers to arrays of unknown bound.
+
+2001-01-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (template_parm_header, template_spec_header): New
+ reductions. Split out from ...
+ (template_header): ... here. Use them.
+ (template_template_parm): Use template_parm_header.
+ * semantics.c (finish_template_template_parm): Add assert.
+
+2001-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_builtin_type): Fix thinko.
+
+ * pt.c (copy_default_args_to_explicit_spec_1): New function.
+ (copy_default_args_to_explicit_spec): Likewise.
+ (check_explicit_specialization): Use it.
+
+ * class.c (finish_struct_1): Remove last argument in call to
+ make_decl_rtl; use make_function_rtl instead of make_decl_rtl.
+ * decl.c (builtin_function): Likewise.
+ (build_cp_library_fn): Likewise.
+ (check_initializer): Likewise.
+ (make_rtl_for_nonlocal_decl): Likewise.
+ (cp_finish_decl): Likewise.
+ (start_function): Likewise.
+ * decl2.c (finish_anon_union): Likewise.
+ * friend.c (do_friend): Likewise.
+ * init.c (build_java_class_ref): Likewise.
+ * method.c (make_thunk): Likewise.
+ * pt.c (tsubst_friend_function): Likewise.
+ * semantics.c (expand_body): Likewise.
+
+2001-01-10 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_CLONED_FUNCTION_P): Avoid wild reads by not
+ looking at DECL_CLONED_FUNCTION for non-functions.
+
+2001-01-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (dump_template_parameter): Use parm to determine how
+ to print default value.
+
+2001-01-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (duplicate_tag_error): Clear more flags.
+
+2001-01-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_new_method_call): Use binfo_for_vbase.
+
+2001-01-10 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * cp-tree.h (flag_cond_mismatch): Don't declare.
+ * decl2.c (flag_cond_mismatch): Don't define.
+ (lang_f_options): Remove cond-mismatch.
+ (unsupported_options): Add cond-mismatch.
+
+2001-01-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (handle_using_decl): Reject using of constructor name
+ of sourcing class. Allow injecting of a method with same name as
+ nested class. Fixup error messages.
+
+2001-01-09 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (lang_decode_option): Handle -Wformat=2.
+
+2001-01-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Rename defined_in_class to
+ initialized_in_class.
+ (DECL_DEFINED_IN_CLASS_P): Rename to ...
+ (DECL_INITIALIZED_IN_CLASS_P): ... here, to reflect true meaning.
+ * decl.c (duplicate_decls): Preseve DECL_INITIALIZED_IN_CLASS_P.
+ (cp_finish_decl): Adjust for DECL_INITIALIZED_IN_CLASS_P.
+ * pt.c (check_default_tmpl_args): Adjust for
+ DECL_INITIALIZED_IN_CLASS_P.
+ (instantiate_class_template): Likewise.
+ (instantiate_decl): Check DECL_INITIALIZED_IN_CLASS_P.
+
+ * class.c (finish_struct): Constify saved_filename.
+
+2001-01-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (duplicate_tag_error): Adjust diagnostic.
+ (finish_struct): Locally set location to start of struct.
+ * decl.c (fixup_anonymous_aggr): Use cp_error_at.
+
+2001-01-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (struct binding_level): Adjust class_shadowed comments
+ to reflect reality.
+ (push_class_level_binding): Adjust comments to reflect reality.
+ Set IDENTIFIER_CLASS_VALUE when replacing an existing binding.
+ Don't set TREE_VALUE on the class_shadowed list.
+
+2001-01-07 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * decl2.c (acceptable_java_type): Allow references too.
+ * init.c (build_java_class_ref): When using the new ABI, search
+ `class$' and have it mangled with `mangle_decl.'
+ * mangle.c (write_java_integer_type_codes): New function.
+ (write_builtin_type): Detect and mangle Java integer and real
+ types.
+
+2001-01-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (grokfield): Don't accept `asm' specifiers for
+ non-static data members.
+
+2001-01-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * expr.c (cplus_expand_expr): Don't reset `target'.
+
+2001-01-07 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp/decl2.c (cxx_post_options): Call cpp_post_options.
+
+2001-01-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (template_datadef): Check for error_mark_node.
+
+2001-01-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.def (DEFAULT_ARG): Make `x' class.
+
+2001-01-04 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE): Don't define.
+ (record_builtin_type): Make non-static.
+ (flag_short_double): Don't declare.
+ (init_decl_processing): Remove the creation of many tree nodes now
+ in c_common_nodes_and_builtins.
+ (build_void_list_node): New function.
+ * decl2.c (flag_short_double, flag_short_wchar): Don't define.
+ * cp-tree.h (flag_short_wchar): Don't declare.
+
+2001-01-04 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (build_conv): Don't use build1 for USER_CONV.
+ * pt.c (tsubst_copy): Or for PREINCREMENT_EXPR and similar nodes.
+
+2001-01-03 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * lex.c (lang_init): Call c_common_lang_init.
+
+2001-01-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (lookup_fnfields_here): Remove.
+ (look_for_overrides_r): Use lookup_fnfields_1.
+ Ignore functions from using declarations.
+
+2001-01-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ Implement exceptions specifiers for implicit member functions.
+ * cp-tree.h (merge_exceptions_specifiers): Declare new function.
+ * method.c (synthesize_exception_spec): New function.
+ (locate_dtor, locate_ctor, locate_copy): New functions.
+ (implicitly_declare_fn): Generate the exception spec too.
+ * search.c (check_final_overrider): Check artificial functions
+ too.
+ * typeck2.c (merge_exception_specifiers): New function.
+
+2001-01-03 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_default_init): New fn.
+ (perform_member_init): Split out from here.
+ (build_new_1): Use it. Simplify initialization logic.
+ (build_vec_init): Take an array, rather than a pointer and maxindex.
+ Speed up simple initializations. Don't clean up if we're assigning.
+ * cp-tree.h: Adjust.
+ * decl2.c (do_static_initialization): Remove TREE_VEC case.
+ * parse.y (new_initializer): Return void_zero_node for ().
+ * typeck.c (build_modify_expr): Handle getting a CONSTRUCTOR.
+ * typeck2.c (digest_init): Only complain about user-written
+ CONSTRUCTORs.
+
+2000-12-22 Mike Stump <mrs@wrs.com>
+
+ * decl2.c: (max_tinst_depth): Increase to 50.
+
+2001-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (invalidate_class_lookup_cache): Zero the
+ previous_class_values.
+ * cp-tree.h (TMPL_PARMS_DEPTH): Use TREE_INT_CST_LOW, not
+ TREE_INT_CST_HIGH.
+ (CLASSTYPE_TEMPLATE_LEVEL): Likewise.
+ * decl.c (free_bindings): New variable.
+ (push_binding): Don't create a new binding if we have one on the
+ free list.
+ (pop_binding): Put old bindings on the free list.
+ (init_decl_processing): Use size_int, not build_int_2.
+ Register free_bindings as a GC root.
+ (cp_make_fname_decl): Use size_int, not build_int_2.
+ (push_inline_template_parms_recursive): Likewise.
+ (end_template_parm_list): Likewise.
+ (for_each_template_parm): Do not use walk_tree_without_duplicates.
+ (tsubst_template_parms): Use size_int, not build_int_2.
+ (tsubst): Likewise.
+ * rtti.c (get_vmi_pseudo_type_info): Likewise.
+
+2001-01-02 Richard Henderson <rth@redhat.com>
+
+ * parse.y (asm): Set ASM_INPUT_P.
+
+2001-01-02 Jason Merrill <jason@redhat.com>
+
+ * tree.c (cp_valid_lang_attribute): Don't set CLASSTYPE_COM_INTERFACE
+ for v3 ABI.
+
+ * typeck.c (cp_truthvalue_conversion): New fn.
+ * cvt.c (ocp_convert): Use it.
+
+ * cp-tree.h: Lose c-common.c decls.
+
+ * typeck.c (build_unary_op): Restore old &a.f diagnostic code.
+ * cvt.c (convert_to_void): Use type_unknown_p.
+
+ * typeck.c (strip_all_pointer_quals): Also strip quals from
+ pointer-to-member types.
+
+ * Make-lang.in (cp/TAGS): Use --no-globals. Ignore parse.c, and treat
+ parse.y as C.
+
+ * call.c (build_new_method_call): Do evaluate the object parameter
+ when accessing a static member.
+ * typeck.c (build_component_ref): Likewise.
+
+2001-01-02 Andreas Jaeger <aj@suse.de>
+
+ * decl.c (cp_missing_noreturn_ok_p): New.
+ (init_decl_processing): Set lang_missing_noreturn_ok_p.
+
+2000-12-29 Jakub Jelinek <jakub@redhat.com>
+
+ * decl.c (init_decl_processing): Fix sign of wchar_type_node.
+
+2000-12-29 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (pushclass): Remove #if 0'd code.
+ * cp-tree.h (overload_template_name): Remove.
+ * decl.c (store_bindings): Simplify.
+ (pop_from_top_level): Likewise.
+ * pt.c (overload_template_name): Remove.
+ (instantiate_decl): Don't call push_to_top_level if it's not
+ needed.
+
+2000-12-28 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (register_local_specialization): Don't return a value.
+ (lookup_template_class): Use move-to-front heuristic when looking
+ up template instantiations.
+ (instantiate_decl): Only push_to_top_level when we're actually
+ going to instantiate the template.
+
+2000-12-29 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * search.c (binfo_for_vtable): Return least derived class, not
+ most. Handle secondary vtables.
+
+2000-12-22 Jason Merrill <jason@redhat.com>
+
+ * pt.c (more_specialized): Don't optimize len==0.
+ (fn_type_unification): If we're adding the return type, increase len.
+
+ * typeck.c (build_binary_op): Fix pmf comparison logic.
+
+ * call.c (joust): Use DECL_NONSTATIC_MEMBER_FUNCTION_P, not
+ DECL_STATIC_FUNCTION_P.
+
+ * semantics.c (genrtl_finish_function): Don't try to jump to
+ return_label unless it exists.
+
+ In partial ordering for a call, ignore parms for which we don't have
+ a real argument.
+ * call.c (joust): Pass len to more_specialized.
+ (add_template_candidate_real): Strip 'this', pass len.
+ * pt.c (more_specialized): Pass len down. Lose explicit_args parm.
+ (get_bindings_order): New fn. Pass len down.
+ (get_bindings_real): Strip 'this', pass len.
+ (fn_type_unification): Likewise.
+ (type_unification_real): Succeed after checking 'len' args.
+ (most_specialized_instantiation): Lose explicit_args parm.
+ * class.c (resolve_address_of_overloaded_function): Strip 'this',
+ pass len.
+
+2000-12-21 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_decl): A FUNCTION_DECL has DECL_RESULT, not
+ DECL_TEMPLATE_RESULT.
+
+ * search.c (lookup_field_r): Call lookup_fnfields_1, not
+ lookup_fnfields_here.
+
+ * parse.y (typename_sub2): Return the TYPE_DECL, not the type.
+
+ * call.c (build_object_call): Also allow conversions that return
+ reference to pointer to function.
+ (add_conv_candidate): Handle totype being ref to ptr to fn.
+ (build_field_call): Also allow members of type reference to function.
+ Lose support for calling pointer to METHOD_TYPE fields.
+
+ * error.c (dump_expr): Handle *_CAST_EXPR.
+
+ * typeck2.c (build_scoped_ref): Always convert to the naming class.
+
+ * tree.c (break_out_cleanups): Lose.
+ * cp-tree.h: Remove prototype.
+ * typeck.c (build_component_ref): Don't break_out_cleanups.
+ (build_compound_expr): Likewise.
+ * semantics.c (finish_expr_stmt): Likewise.
+
+2000-12-20 Richard Henderson <rth@redhat.com>
+
+ * cp-tree.h: Update declarations.
+ * decl.c (finish_case_label): Return the new stmt node.
+ * semantics.c (finish_goto_stmt): Likewise.
+ (finish_expr_stmt, finish_return_stmt): Likewise.
+ (finish_break_stmt, finish_continue_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ * parse.y (already_scoped_stmt): Set STMT_LINENO.
+ (compstmt, implicitly_scoped_stmt, stmt): Likewise.
+ (simple_if, simple_stmt): Return the new stmt node.
+ (save_lineno): New.
+
+2000-12-18 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * cp-tree.h: Don't declare warn_long_long.
+
+2000-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * tree.c (no_linkage_helper): Use CLASS_TYPE_P instead of
+ IS_AGGR_TYPE.
+
+2000-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (unify): Handle when both ARG and PARM are
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+
+2000-12-15 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (reduce_template_parm_level): Set DECL_ARTIFICIAL and
+ DECL_TEMPLATE_PARM_P.
+
+2000-12-15 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Reorganize. Now with 100% fewer SAVE_EXPRs!
+
+ * init.c (build_new_1): Don't strip quals from type.
+
+ * decl.c (pushdecl): Don't check for linkage on a non-decl.
+
+ * call.c (build_op_delete_call): See through ARRAY_TYPEs.
+
+ * call.c (build_new_function_call): Lose space before paren in
+ error message.
+ (build_new_method_call): Likewise.
+
+ * typeck2.c (build_m_component_ref): Propagate quals from datum.
+
+2000-12-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (check_explicit_specialization): Propagate default
+ function arguments to explicit specializations.
+
+2000-12-13 DJ Delorie <dj@redhat.com>
+
+ * typeck.c (build_binary_op): Do signed/unsigned warnings for >?
+ and <? operators.
+
+2000-12-08 Jason Merrill <jason@redhat.com>
+
+ * error.c (dump_function_name): Don't let the user see __comp_ctor.
+
+ Clean up copy-initialization in overloading code.
+ * call.c (build_user_type_conversion_1): Die if we are asked to
+ convert to the same or a base type.
+ (implicit_conversion): Avoid doing so. Lose reference binding code.
+ (convert_like_real): Treat BASE_CONV and RVALUE_CONV as implicit
+ direct-initialization. Also do direct-init part of copy-init.
+ (build_user_type_conversion): Don't provide context to convert_like.
+ * cvt.c (ocp_convert): build_user_type_conversion will now provide
+ the constructor call for copy-init.
+
+ * pt.c (tsubst_decl): Call clone_function_decl here if this is an
+ instantiation of a member template.
+ (do_decl_instantiation): Not here.
+
+2000-12-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (check_field_decls): Don't special case anonymous
+ fields in error messages.
+ (note_name_declared_in_class): Use %D on diagnostic.
+
+ * tree.c (pod_type_p): Use strip_array_types.
+ (cp_valid_lang_attribute): Likewise.
+ * typeck.c (cp_type_quals): Strip arrays separately, to avoid
+ multiple evaluations.
+ (cp_has_mutable_p): Use strip_array_types.
+
+2000-12-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (sufficient_parms_p): Declare new function.
+ * call.c (sufficient_parms_p): New function, broken out of ...
+ (add_function_candidate): ... here. Use it.
+ (add_conv_candidate): Use it.
+ * decl.c (grok_ctor_properties): Use it.
+
+2000-12-07 Jakub Jelinek <jakub@redhat.com>
+
+ * optimize.c (copy_body_r): Set STMT_IS_FULL_EXPR_P on EXPR_STMT.
+
+2000-12-07 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (lang_decode_option): Handle -Wformat-security.
+
+2000-12-06 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c (verify_class_unification): New function.
+ (get_class_bindings): Use it.
+ (try_class_unification): Tidy.
+ (unify): Handle when argument of a template-id is not
+ template parameter dependent.
+ (template_args_equal): Handle when TREE_CODE's do not match.
+
+2000-12-06 Alexandre Oliva <aoliva@redhat.com>
+
+ * lang-specs.h (c++): When invoking the stand-alone preprocessor
+ for -save-temps, pass all relevant -Defines to it, and then don't
+ pass them to cc1plus.
+
+2000-12-05 Will Cohen <wcohen@redhat.com>
+
+ * decl.c (finish_case_label): Cleared
+ more_cleanups_ok in surrounding function scopes.
+ (define_label): Likewise.
+
+2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (IDENTIFIER_VIRTUAL_P): Document.
+ (get_matching_virtual): Remove.
+ (look_for_overrides): Declare new function.
+ * decl.c (grokfndecl): Don't set IDENTIFIER_VIRTUAL_P or
+ DECL_VINDEX here.
+ * class.c (check_for_override): Move base class iteration code
+ to look_for_overrides.
+ * search.c (next_baselink): Remove.
+ (get_virtuals_named_this): Remove.
+ (get_virtual_destructor): Remove.
+ (tree_has_any_destructors_p): Remove.
+ (struct gvnt_info): Remove.
+ (check_final_overrider): Remove `virtual' from error messages.
+ (get_matching_virtuals): Remove. Move functionality to ...
+ (look_for_overrides): ... here, and ...
+ (look_for_overrides_r): ... here. Set DECL_VIRTUAL_P, if found
+ to be overriding.
+
+2000-12-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (get_delta_difference): If via a virtual base,
+ return zero.
+ * cvt.c (cp_convert_to_pointer): If via a virtual base, do no
+ adjustment.
+
+2000-12-04 Richard Henderson <rth@redhat.com>
+
+ * error.c (dump_tree): Use output_add_string not OB_PUTS.
+
+2000-12-04 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_type): Mangle VECTOR_TYPE with "U8__vector".
+ (write_builtin_type): Pass intSI_type_node and the like through
+ type_for_mode.
+ * method.c (process_overload_item): Mangle VECTOR_TYPEs with 'o'.
+ Pass intSI_type_node and the like through type_for_mode.
+ * decl2.c (arg_assoc_type): Handle VECTOR_TYPE like COMPLEX_TYPE.
+ * pt.c (tsubst, unify): Likewise.
+ * tree.c (walk_tree): Likewise.
+ * error.c (dump_type): Likewise.
+ (dump_type_prefix, dump_type_suffix): Don't bother with VECTOR_TYPE.
+
+ * Make-lang.in: Tweak top comment for emacs.
+ (cp/TAGS): Restore.
+
+ * except.c (expand_throw): Use push_throw_library_fn for _Jv_Throw.
+
+ * class.c (clone_function_decl): Robustify.
+
+2000-12-04 Michael Matz <matzmich@cs.tu-berlin.de>
+
+ * decl.c (store_bindings): Only search in the non modified
+ old_bindings for duplicates.
+
+2000-12-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (dump_function_decl): Use DECL_VIRTUAL_P, not
+ TYPE_POLYMORPHIC_P.
+
+ * typeck.c (build_static_cast): Remove unused variable.
+
+2000-12-01 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * pt.c: Fix typo in comment.
+
+2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (warn_format): Remove definition.
+ (lang_decode_option): Handle -Wformat-nonliteral,
+ -Wno-format-extra-args and -Wno-format-y2k. Use set_Wformat.
+
+2000-12-01 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (WINT_TYPE, INTMAX_TYPE, UINTMAX_TYPE): Don't define.
+ (init_decl_processing): Don't create string_type_node,
+ const_string_type_node, wint_type_node, intmax_type_node,
+ uintmax_type_node, default_function_type, ptrdiff_type_node and
+ unsigned_ptrdiff_type_node. Adjust position of call to
+ c_common_nodes_and_builtins.
+ (identifier_global_value): New function.
+
+2000-12-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (standard_conversion): Reject pointer to member
+ conversions from ambiguous, inaccessible or virtual bases.
+ * typeck.c (build_static_cast): Don't check pointers to members
+ specially.
+
+2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (do_build_copy_constructor): Preserve cv
+ qualifications when accessing source object members.
+ (do_build_assign_ref): Likewise. Remove separate diagnostics for
+ unnamed fields.
+
+2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (do_build_assign_ref): Construct appropriately
+ CV-qualified base reference. Don't allow const casts in base
+ conversion.
+
+2000-11-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_over_call): Use VOID_TYPE_P. Don't die on
+ incomplete return type.
+
+2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (base_class.1): Produce a _TYPE not a _DECL.
+ * semantics.c (finish_base_specifier): Accept a _TYPE not a
+ _DECL.
+
+2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * spew.c (yyerror): Cope if yylval.ttype is NULL.
+
+2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Diagnose undefined template contexts.
+
+2000-11-28 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Do type access control on friend
+ class.
+
+2000-11-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokfndecl): Undo COMPONENT_REF damage caused by
+ bison parser ickiness.
+ * pt.c (tsubst_friend_function): Enter namespace scope when
+ tsubsting the function name.
+ * cp-tree.h (DECL_TI_TEMPLATE): Update comment to reflect reality.
+
+2000-11-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (binfo_from_vbase): Return the virtual base's binfo.
+ * cvt.c (cp_convert_to_pointer): Add force parameter.
+ Allow conversions via virtual base if forced.
+ (convert_to_pointer_force): Adjust call to cp_convert_to_pointer.
+ (ocp_convert): Likewise.
+ * search.c (binfo_from_vbase): Return the virtual base's binfo.
+ * typeck.c (get_delta_difference): Adjust handling of virtual
+ bases.
+
+2000-11-26 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (struct list_hash): Remove.
+ (list_hash_table): Make it be an htab.
+ (struct list_proxy): New type.
+ (list_hash_eq): New function.
+ (list_hash_pieces): Renamed from ...
+ (list_hash): ... this.
+ (list_hash_lookup): Remove.
+ (list_hash_add): Remove.
+ (hash_tree_cons): Use the generic hashtable.
+ (mark_list_hash): Remove.
+ (init_tree): Create the hashtable.
+
+2000-11-25 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * method.c (build_mangled_C9x_name): Rename to
+ build_mangled_C99_name. Change C9X references in comments to
+ refer to C99.
+
+2000-11-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (unary_expr): Move VA_ARG from here ...
+ (primary): ... to here.
+
+2000-11-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * semantics.c (finish_id_expr): If type is error_mark, return
+ error_mark.
+
+2000-11-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (lookup_template_class): Simplify loop exit constructs.
+ Cope when there is no partial instantiation of a template
+ template member.
+
+2000-11-23 J"orn Rennecke <amylaar@redhat.com>
+
+ * Make-lang.in (g++spec.o, cxxmain.o): Depend on $(CONFIG_H).
+
+2000-11-22 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (mangle_conv_op_name_for_type): Don't use `__op'
+ prefix.
+
+ * pt.c (do_decl_instantiate): Explicitly clone constructors and
+ destructors that haven't already been cloned.
+
+2000-11-20 Richard Henderson <rth@redhat.com>
+
+ * parse.y (yyparse_1): Rename the parser entry point.
+
+2000-11-20 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (write_name): Use <unscoped-name> for names directly in
+ function scope.
+ (write_unscoped_name): Accept names directly in function scope.
+
+2000-11-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * lex.c (rid_to_yy, RID_EXPORT): Make unique keyword.
+ * parse.y (extdef): Add EXPORT reduction.
+ * spew.c (yylex): Don't skip export here.
+
+2000-11-19 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (init_decl_processing): Correct name of pure virtual
+ function under the new ABI.
+ * rtti.c (throw_bad_cast): Likewise, for bad cast function.
+ (throw_bad_typeid): Likewise for bad typeid function.
+
+2000-11-18 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokparms): Don't even function types of `void' type,
+ either.
+ * mangle.c (write_type): Don't crash when confronted with the
+ error_mark_node.
+
+ * decl.c (grokparms): Don't create parameters of `void' type.
+
+2000-11-17 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * lex.c (mark_impl_file_chain): Delete.
+ (init_parse): Remove call to ggc_add_string_root. No need to
+ ggc_strdup a string constant. Do not add impl_file_chain to GC
+ roots.
+ (handle_pragma_implementation): No need to ggc_strdup main_filename.
+
+2000-11-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst_expr, DECL_STMT): Instantiate decl's type.
+
+2000-11-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (PARMLIST_ELLIPSIS_P): New macro.
+ * decl.c (grokdeclarator): Don't reject void parms here.
+ (require_complete_types_for_parms): Simplify, use
+ complete_type_or_else.
+ (grokparms): Remove bitrot. Remove funcdef parm.
+ Deal with ellipsis parm lists here.
+ * semantics.c (finish_parmlist): Don't append void_list_node
+ here. Set PARMLIST_ELLIPSIS_P.
+
+2000-11-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck2.c (incomplete_type_error): Reorganize to avoid
+ excessive diagnostics.
+
+2000-11-16 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * lex.c (struct impl_files, internal_filename): Constify a char *.
+
+2000-11-16 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_special_name_constructor): Don't generate
+ assembler junk when confronted with an old-style constructor.
+ (write_special_name_destructor): Likewise.
+ (mangle_decl_string): Do it here instead.
+
+2000-11-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (op_error): Make error messages clearer.
+
+2000-11-15 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (wrapup_globals_for_namespace): Don't mark things
+ TREE_ASM_WRITTEN when they're not.
+
+2000-11-15 Jason Merrill <jason@redhat.com>
+
+ * typeck2.c (friendly_abort): Uncount the error before handing
+ off to fancy_abort.
+
+2000-11-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (lookup_anon_field): Cope with qv qualifiers.
+
+2000-11-14 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtbl_initializer): Fix typo in comment.
+ * typeck.c (expr_sizeof): Don't crash on errors.
+
+2000-11-14 Jim Wilson <wilson@redhat.com>
+
+ * lang-specs.h: Add %2 after %(cc1_options).
+
+2000-11-14 Richard Henderson <rth@redhat.com>
+
+ * typeck.c (c_sizeof): Be strict about casting result value
+ back to c_size_type_node.
+ (expr_sizeof, c_sizeof_nowarn, c_alignof): Likewise.
+
+2000-11-13 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * typeck.c (build_unary_op): Use boolean_increment from
+ c-common.c, moving the relevant code there.
+
+2000-11-11 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (mark_addressable): Don't call put_var_into_stack.
+
+ * decl.c (maybe_commonize_var): Set DECL_UNINLINABLE for statics
+ in inlines.
+
+2000-11-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (grokdeclarator, save_function_data): Use memcpy, not bcopy.
+ * lex.c (copy_lang_decl): Likewise.
+
+2000-11-09 Mark Mitchell <mark@codesourcery.com>
+
+ * dump.c (cp_dump_tree): Don't dump function bodies here.
+
+ * Make-lang.in (CXX_C_OBJS): Add c-dump.o.
+ (dump.o): Update dependency list.
+ * cp-tree.h (DECL_MAYBE_TEMPLATE): Remove.
+ (flag_dump_translation_unit): Likewise.
+ (CP_TYPE_QUALS): Adjust definition.
+ (DECL_C_BIT_FIELD): Remove.
+ (SET_DECL_C_BIT_FIELD): Likewise.
+ (CLEAR_DECL_C_BIT_FIELD): Likewise.
+ (add_maybe_template): Likewise.
+ (strip_array_types): Likewise.
+ (dump_node_to_file): Likewise.
+ (cp_dump_tree): New function.
+ * decl.c (init_decl_processing): Set lang_dump_tree.
+ * decl2.c (flag_dump_translation_unit): Remove.
+ * dump.c: Move most of it to ../c-dump.c.
+ (cp_dump_tree): New function.
+ * pt.c (add_maybe_template): Remove.
+ * typeck.c (strip_array_types): Likewise.
+
+2000-11-07 Eric Christopher <echristo@redhat.com>
+
+ * decl.c (init_decl_processing): Change definition of
+ __wchar_t to wchar_t. Remove artificial declaration of
+ wchar_t.
+ * lex.c: Change instances of __wchar_t to wchar_t.
+
+2000-11-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * lex.c (do_identifier): Don't lookup_name for operators.
+ * parse.y (operator): Save looking_for_typename.
+ (unoperator): Restore it.
+ * spew.c (frob_opname): Use nth_token for lookahead.
+
+2000-11-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grok_op_properties): Always use coerce_new_type and
+ coerce_delete_type.
+ * decl2.c (coerce_new_type): Use c_size_type_node. Preserve
+ exception specification. Tidy up.
+ (coerce_delete_type): Preserve exception specification. Tidy up.
+
+2000-11-07 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * class.c (duplicate_tag_error, build_vtbl_initializer), decl.c
+ (push_binding_level), error.c (cp_tree_printer), pt.c
+ (process_partial_specialization, tsubst_template_arg_vector),
+ search.c (lookup_member): Use memset () instead of bzero ().
+
+2000-11-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (build_ptrmemfunc_type): Allow error_mark_node.
+
+2000-11-05 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (c++.distdir): Remove.
+
+2000-11-04 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (do_nonmember_using_decl): Allow `extern "C"'
+ declarations from different namespaces to be combined.
+
+2000-11-03 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * decl.c: Include tm_p.h.
+
+2000-11-03 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * tree.c (cp_tree_equal): Use memcmp () instead of bcmp ().
+
+2000-11-02 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * dump.c (dequeue_and_dump), lex.c (interface_strcmp), method.c
+ (build_overload_value), repo.c (open_repo_file), xref.c
+ (open_xref_file): Use strchr () and strrchr () instead of index ()
+ and rindex ().
+
+2000-11-01 Bernd Schmidt <bernds@redhat.co.uk>
+
+ * call.c (build_over_call): Call fold on the CALL_EXPR.
+
+2000-11-01 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (dump_template_decl): Separate template hearders with
+ space not comma.
+
+2000-10-31 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c: Move TFF_ macros into cp-tree.h. Throughout, replace
+ TS_* flags with corresponding TFF_*. Adjust prototypes of
+ functions (which used to take a tree_string_flags) to take an int.
+
+ * cp-tree.h (enum tree_string_flags): Remove
+ (TFF_PLAIN_IDENTIFIER, TFF_NAMESPACE_SCOPE, TFF_CLASS_SCOPE,
+ TFF_CHASE_NAMESPACE_ALIAS, TFF_CHASE_TYPEDEF, TFF_DECL_SPECIFIERS,
+ TFF_CLASS_KEY_OR_ENUM, TFF_RETURN_TYPE,
+ TFF_FUNCTION_DEFAULT_ARGUMENTS, TFF_EXCEPTION_SPECIFICATION,
+ TFF_TEMPLATE_HEADER, TFF_TEMPLATE_DEFAULT_ARGUMENTS,
+ TFF_TEMPLATE_NAME, TFF_EXPR_IN_PARENS, TFF_SCOPE): New macros.
+ (type_as_string, decl_as_string, expr_as_string,
+ context_as_string): Adjust prototype.
+
+ * class.c (dump_class_hierarchy_r): Use TFF_PLAIN_IDENTIFIER
+ instead of TS_PLAIN.
+
+ * pt.c (mangle_class_name_for_template): Use TFF_CHASE_TYPEDEF
+ instead of TF_CHASE_TYPEDEFS. Use TFF_PLAIN_IDENTIFIER instead of
+ plain `0'.
+
+2000-10-30 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_EXTERNAL_LINKAGE_P): New macro.
+ (linkage_kind): New enumeration.
+ (decl_linkage): New function.
+ * decl2.c (comdat_linkage): Extend comment.
+ * error.c (dump_function_decl): Print the arguments used to
+ instantiate a template, even when not printing the type of the
+ function.
+ * pt.c (convert_nontype_argument): Use DECL_EXTERNAL_LINKAGE_P,
+ not TREE_PUBLIC, to test for external linkage.
+ * tree.c (decl_linkage): New function.
+
+2000-10-28 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (instantiate_decl): Always instantiate static data members
+ initialized in-class.
+
+2000-10-27 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * Make-lang.in: Move all build rules here from Makefile.in,
+ adapt to new context. Wrap all rules that change the current
+ directory in parentheses. Expunge all references to $(P).
+ When one command depends on another and they're run all at
+ once, use && to separate them, not ;. Add OUTPUT_OPTION to
+ all object-file generation rules. Delete obsolete variables.
+
+ * Makefile.in: Delete.
+ * config-lang.in: Delete outputs= line.
+
+2000-10-26 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (dump_function_decl): Print no space between
+ `ptr-operator' the `type-specifier' of the return type.
+ (dump_type_prefix): Make sure we put space at the appropriate
+ place.
+
+2000-10-23 Jason Merrill <jason@redhat.com>
+
+ * call.c (equal_functions): Also call decls_match for extern "C" fns.
+
+2000-10-22 Jason Merrill <jason@redhat.com>
+
+ * call.c (build_conditional_expr): Use ocp_convert to force
+ rvalue conversion.
+
+2000-10-22 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (standard_conversion): Use RVALUE_CONVs for all
+ expressions that satisfy lvalue_p, not just those that satisfy
+ real_lvalue_p.
+
+ * optimize.c (copy_body_r): Don't treat CALL_EXPRs specially.
+
+ * typeck.c (c_sizeof): Return an expression of `size_t' type,
+ not one with TYPE_IS_SIZETYPE set.
+ (dubious_conversion_warnings): Remove special-case code.
+
+2000-10-21 Geoffrey Keating <geoffk@cygnus.com>
+
+ * decl2.c (arg_assoc_type): Handle VECTOR_TYPE.
+ * error.c (dump_type): Handle VECTOR_TYPE like POINTER_TYPE.
+ (dump_type_prefix): Print vector-of-int as 'int vector'.
+ (dump_type_suffix): Handle VECTOR_TYPE like POINTER_TYPE.
+ * tree.c (walk_tree): Handle VECTOR_TYPE.
+
+ * decl.c (init_decl_processing): Call MD_INIT_BUILTINS.
+
+2000-10-21 Jason Merrill <jason@redhat.com>
+
+ * parse.y (operator): Set got_object from got_scope.
+ Set looking_for_typename.
+ * decl.c (lookup_name_real): Clear val after setting from_obj.
+ Reorganize diagnostic.
+
+2000-10-20 Jason Merrill <jason@redhat.com>
+
+ * tree.c (walk_tree): Don't walk into default args.
+
+ * error.c (dump_expr): Use host_integerp.
+
+2000-10-20 David Edelsohn <edelsohn@gnu.org>
+
+ * typeck2.c (abstract_virtuals_error): Use "because" instead of
+ "since" in error message.
+
+2000-10-20 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * typeck.c (dubious_conversion_warning): Suppress if TYPE_IS_SIZETYPE.
+
+2000-10-20 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * decl.c (revert_static_member_fn): Fixed typo.
+
+2000-10-19 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (subobject_offset_fn): New type.
+ (dfs_record_base_offsets): Remove.
+ (record_base_offsets): Likewise.
+ (dfs_search_base_offsets): Likewise.
+ (record_subobject_offset): New function.
+ (check_subobject_offset): Likewise.
+ (walk_subobject_offsets): Likewise.
+ (record_subobject_offsets): Likewise.
+ (layout_conflict_p): Reimplement.
+ (layout_nonempty_base_or_field): Correct handling of type
+ conflicts during layout.
+ (layout_empty_base): Likewise.
+ (build_base_field): Adjust to handle new representation of empty
+ base offset table.
+ (build_base_fields): Likewise.
+ (layout_virtual_bases): Likewise.
+ (splay_tree_compare_integer_csts): New function.
+ (layout_class_type): Use a splay_tree, rather than a varray, to
+ represent the offsets of empty bases.
+
+ * cp-tree.h (DECL_ANTICIPATED): Don't require a FUNCTION_DECL.
+ * decl.c (select_decl): Don't return declarations that are
+ DECL_ANTICIPATED.
+
+2000-10-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Add CPTI_FAKE_STD.
+ (fake_std_node): New macro.
+ * decl.c (in_std): Rename to ...
+ (in_fake_std): ... this.
+ (flag_no_builtin): Remove.
+ (flag_no_nonansi_builtin): Likewise.
+ (walk_namespaces_r): Use fake_std_node.
+ (push_namespace): Use std_identifier.
+ (pop_namespace): Use in_fake_std.
+ (lookup_name_real): Use fake_std_node.
+ (init_decl_processing): When -fhonor-std, create the `std'
+ namespace. Don't create a dummy fake_std_node in that case.
+ Adjust call to c_common_nodes_and_builtins. Use std_identifier.
+ (builtin_function): Put builtins whose names don't begin
+ with `_' in the std namespace.
+ * decl2.c (flag_no_builtin): Remove.
+ (flag_no_nonansi_builtin): Likewise.
+ (set_decl_namespace): Use fake_std_node.
+ (validate_nonmember_using_decl): Likewise.
+ (do_using_directive): Likewise.
+ (handle_class_head): Likewise.
+ * dump.c (dequeue_and_dump): Likewise.
+ * except.c (init_exception_processing): Use std_identifier.
+ * init.c (build_member_call): Use fake_std_node.
+ * rtti.c (init_rtti_processing): Use std_identifier.
+
+2000-10-17 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (back_end_hook): Remove declaration.
+ * decl2.c (back_end_hook): Remove definition.
+
+ * dump.c (dequeue_and_dump): Dump TREE_USED.
+
+2000-10-17 Brad Lucier <lucier@math.purdue.edu>
+
+ * spew.c (snarf_defarg): Cast 2nd arg to obstack_blank to (int).
+
+2000-10-17 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (WINT_TYPE): Define.
+ (init_decl_processing): Create types unsigned_ptrdiff_type_node,
+ c_size_type_node, signed_size_type_node and wint_type_node.
+
+2000-10-17 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl2.c (warn_missing_format_attribute): New variable.
+ (lang_decode_option): Decode -Wmissing-format-attribute.
+
+2000-10-16 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (qualify_type): Remove.
+ (composite_pointer_type): Fix handling of conversions to `cv void*'.
+
+2000-10-14 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (parse.c, parse.h): Fix think-o in last patch.
+
+2000-10-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (parse.c, parse.h): Create atomically.
+
+2000-10-12 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (current_obstack): Remove.
+ * decl.c (ggc_p): Remove.
+ (start_decl): Don't use decl_tree_cons.
+ (grokdeclarator): Don't use build_decl_list.
+ (start_function): Don't use decl_tree_cons.
+ (finish_function): Don't mess with obstacks.
+ * decl2.c (grok_x_components): Don't use build_decl_list.
+ * lex.c (make_call_declarator): Don't call decl_tree_cons.
+ (implicitly_declare_fn): Don't call build_decl_list.
+ * parse.y (frob_specs): Don't call build_decl_list or
+ decl_tree_cons.
+ (expr_or_declarator_intern): Don't call decl_tree_cons.
+ (primary): Don't call build_decl_list.
+ (fcast_or_absdcl): Likewise.
+ (typed_declspecs): Don't call decl_tree_cons.
+ (reserved_declspecs): Don't call build_decl_list.
+ (declmods): Likewise.
+ (reserved_typespecquals): Likewise.
+ (aggr): Likewise.
+ (new_type_id): Likewise.
+ (cv_qualifiers): Likewise.
+ (after_type_declarator_intern): Likewise.
+ (notype_declarator_intern): Likewise.
+ (absdcl_intern): Likewise.
+ (named_parm): Likewise.
+ * pt.c (most_specialized_class): Likewise.
+ * repo.c (temporary_obstack): Make it a structure, not a pointer.
+ (init_repo): Initialize it.
+ * search.c (current_obstack): Remove.
+ * typeck2.c (add_exception_specifier): Don't call build_decl_list.
+
+2000-10-09 Richard Henderson <rth@cygnus.com>
+
+ * Make-lang.in (CXX_EXTRA_HEADERS): Remove.
+ (c++ language support bits for libgcc): Remove.
+ (c++.clean): Remove cplib2.txt cleanup.
+ * config-lang.in (headers, lib2funcs): Remove.
+
+ * exception.cc, new.cc, new1.cc, new2.cc: Remove files.
+ * tinfo.cc, tinfo.h, tinfo2.cc, vec.cc: Remove files.
+ * inc/cxxabi.h, inc/exception, inc/new: Remove files.
+ * inc/new.h, inc/typeinfo: Remove files.
+
+2000-10-08 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (INTMAX_TYPE, UINTMAX_TYPE): Define if not already
+ defined.
+ (init_decl_processing): Initialize intmax_type_node and
+ uintmax_type_node.
+
+2000-10-06 Richard Henderson <rth@cygnus.com>
+
+ * cp-tree.h (struct cp_language_function): Remove x_result_rtx.
+ (original_result_rtx): Remove.
+ * decl.c (save_function_data): Don't clear x_result_rtx.
+ (mark_lang_function): Don't mark it either.
+ * expr.c (fixup_result_decl): Remove.
+ * semantics.c (genrtl_named_return_value): Frob the return decl
+ before calling emit_local_var.
+ (genrtl_finish_function): Don't call fixup_result_decl.
+ Always emit the jump to return_label.
+
+2000-10-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (lookup_template_class): Set current access for enum.
+ (tsubst_enum): Set file & line for enum decl.
+
+ * spew.c (yylex): Remove unused variable.
+
+2000-10-05 Richard Henderson <rth@cygnus.com>
+
+ * semantics.c (genrtl_finish_function): Don't init or check
+ can_reach_end; remove noreturn and return value checks.
+
+2000-10-05 Tom Tromey <tromey@cygnus.com>
+
+ * init.c (build_java_class_ref): Use `build_static_name' with a
+ suffix, not a prefix, to build the class object's name.
+
+2000-10-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (access_kind): Fix comment typo.
+ * decl2.c (grokfield): Fix diagnostic typo.
+ * semantics.c (finish_template_type): Fix comment typo.
+ (finish_qualified_object_call_expr): Likewise.
+
+2000-10-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst_expr, DECL_STMT case): Don't process if
+ tsubsting fails.
+
+2000-10-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * spew.c (frob_id): New static function.
+ (frob_opname): Use it.
+ (yylex): Use it.
+
+2000-10-01 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (lang_mark_false_label_stack): Remove.
+ * lex.c (cp_mang_lang_type): Use ggc_alloc_cleared.
+
+2000-09-30 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * gxxint.texi: Use @email for formatting email addresses.
+
+2000-09-29 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c: Remove direct obstack manipulation. Replace with
+ output_buffer-based formatting. Adjust calls to removed macros.
+ (obstack_chunk_alloc, obstack_chunk_free): Remove.
+ (OB_INIT, OB_PUTC, OB_PUTC2, OB_PUTS, OB_PUTID, OB_PUTCP,
+ OB_FINISH, OB_PUTI, OB_END_TEMPLATE): Likewise.
+
+2000-09-24 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi: Move to ../c-tree.texi.
+
+2000-09-20 Jason Merrill <jason@redhat.com>
+
+ * decl2.c (get_guard): Check DECL_FUNCTION_SCOPE_P.
+
+2000-09-21 Andreas Jaeger <aj@suse.de>
+
+ * errfn.c: Move declaration of cp_printer and cp_printers to ...
+ * cp-tree.h: ... here.
+
+ * error.c: Remove declaration of cp_printer.
+
+2000-09-20 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (mark_local_for_remap_r): Handle CASE_LABELs.
+
+2000-09-20 Hans-Peter Nilsson <hp@axis.com>
+
+ * except.c: Delete #if 0:d EXCEPTION_SECTION_ASM_OP-default and
+ users.
+
+2000-09-18 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_function): Robustify.
+
+2000-09-18 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (check_function_format): Accept a `status' parameter.
+
+ * call.c, typeck.c: Updates calls to `check_function_format'.
+
+2000-09-17 Geoffrey Keating <geoffk@cygnus.com>
+
+ * decl2.c (handle_class_head): Always push some scope even
+ in the error case.
+
+2000-09-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct cp_language_function): Remove
+ x_scope_stmt_stack and name_declared.
+ (current_scope_stmt_stack): Remove.
+ (function_name_declared_p): New macro.
+ (struct lang_decl_flags): Use c_lang_decl as a base class.
+ (context): Remove.
+ (struct lang_decl): Replace saved_tree with context.
+ (DECL_FRIEND_CONTEXT): Adjust accordingly.
+ (SET_DECL_FRIEND_CONTEXT): Likewise.
+ (DECL_VIRTUAL_CONTEXT): Likewise.
+ (DECL_SAVED_TREE): Remove.
+ (C_DECLARED_LABEL_FLAG): Likewise.
+ (cplus_expand_expr_stmt): Don't declare.
+ (add_decl_stmt): Likewise.
+ (add_scope_stmt): Likewise.
+ * decl.c (mark_stmt_tree): Remove.
+ (case_compare): Likewise.
+ (finish_case_label): Use c_add_case_label.
+ (init_decl_processing): Set more language-specific hooks.
+ (build_enumerator): Fix typo in comment.
+ (cplus_expand_expr_stmt): Remove.
+ (mark_lang_function): Use mark_c_language_function.
+ (lang_mark_tree): Use c_mark_lang_decl.
+ * decl2.c: Change order of inclusion.
+ * except.c: Likewise.
+ * expr.c (cplus_expand_expr): Remove handling of STMT_EXPR. Fall
+ back on c_expand_expr.
+ * friend.c: Include expr.h.
+ * init.c: Change order of inclusion.
+ * Makefile.in: Update dependencies.
+ * lex.h (free_lang_decl_chain): Remove.
+ * optimize.c (maybe_clone_body): Use function_name_declared_p.
+ * pt.c (build_template_decl): Don't copy DECL_VIRTUAL_CONTEXT if
+ it doesn't exist.
+ (instantiate_decl): Use function_name_declared_p.
+ * semantics.c (lang_expand_expr_stmt): Remove.
+ (set_current_function_name_declared): Likewise.
+ (current_function_name_declared): Likewise.
+ (begin_compound_stmt): Use function_name_declared_p.
+ (add_decl_stmt): Remove.
+ (setup_vtbl_ptr): Use function_name_declared_p.
+ (add_scope_stmt): Remove.
+ (current_scope_stmt_stack): New function.
+ (cp_expand_stmt): Don't handle SCOPE_STMTs.
+ (expand_body): Use function_name_declared_p.
+ * tree.c (cp_statement_code_p): Don't include SCOPE_STMT.
+ * typeck.c: Change order of includes.
+ (convert_sequence): Remove.
+
+2000-09-14 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * lex.c (reswords): Add _Complex.
+
+2000-09-14 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Make-lang.in (cplib2.txt): Depend on cp/Makefile.
+
+2000-09-13 J. David Anglin <dave@hiauly1.hia.nrc.ca>
+
+ * init.c (begin_init_stmts): Don't use // comments.
+
+2000-09-12 Jason Merrill <jason@redhat.com>
+
+ * decl.c (maybe_deduce_size_from_array_init): Set do_default for
+ all non-extern arrays.
+
+ * decl.c (grokdeclarator): Complain about 'friend T' for implicit
+ typenames, too. Downgrade complaint to pedwarn.
+ (xref_tag): Warn about surprising behavior of 'friend struct T'.
+ * decl2.c (handle_class_head): Generate a TYPENAME_TYPE for
+ 'class This::Inherited'.
+
+2000-09-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (finish_case_label): Given the LABEL_DECL a
+ DECL_CONTEXT.
+
+2000-09-12 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (TFF_PLAIN_IDENTIFIER, TFF_NAMESPACE_SCOPE,
+ TFF_CLASS_SCOPE, TFF_CHASE_NAMESPACE_ALIAS, TFF_CHASE_TYPDEF,
+ TFF_DECL_SPECIFIERS, TFF_CLASS_KEY_OR_ENUM, TFF_RETURN_TYPE,
+ TFF_FUNCTION_DEFAULT_ARGUMENTS, TFF_EXCEPTION_SPECIFICATION,
+ TFF_TEMPLATE_HEADER, TFF_TEMPLATE_DEFAULT_ARGUMENTS, TFF_SCOPE):
+ New macros.
+ (sorry_for_unsupported_tree, print_scope_operator,
+ print_left_paren, print_right_paren, print_left_bracket,
+ print_right_bracket, print_whitespace): Likewise.
+ (aggr_variety): Rename to class_key_or_enum.
+ (print_type): Rename to print_type_id.
+ (print_type_specifier_seq, print_simple_type_specifier,
+ print_elaborated_type_specifier,
+ print_rest_of_abstract_declarator,
+ print_parameter_declaration_clause, print_exception_specification,
+ print_nested_name_specifier, print_template_id,
+ typedef_original_name, print_template_argument_list_start,
+ print_template_argument_list_end): New functions.
+
+2000-09-11 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * ir.texi: Add more documentation.
+
+2000-09-11 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct saved_scope): Remove x_function_parms.
+ (current_function_parms): Don't define.
+ (struct cp_language_function): Remove parms_stored.
+ (current_function_just_assigned_this): Don't define.
+ (current_function_parms_stored): Likewise.
+ (static_ctors): Declare.
+ (static_dtors): Likewise.
+ (SF_EXPAND): Don't define.
+ (expand_start_early_try_stmts): Remove declaration.
+ (store_parm_decls): Likewise.
+ * decl.c (static_ctors): Don't declare.
+ (static_dtors): Likewise.
+ (struct binding_level): Remove this_block.
+ (poplevel): Remove dead code.
+ (set_block): Likewise.
+ (mark_binding_level): Don't mark this_block.
+ (mark_saved_scope): Don't mark x_function_parms.
+ (init_decl_processing): Don't add current_function_parms as a GC
+ root.
+ (check_function_type): Change prototype.
+ (start_function): Remove RTL-generation code.
+ (expand_start_early_try_stmts): Remove.
+ (store_parm_decls): Give it internal linkage. Remove
+ RTL-generation code.
+ (finish_function): Remove RTL-generation code.
+ * decl2.c (static_ctors): Fix formatting.
+ (static_dtors): Likewise.
+ * method.c (use_thunk): Don't call store_parm_decls.
+ (synthesize_method): Likewise.
+ * optimize.c (maybe_clone_body): Likewise.
+ * parse.y (fn.def2): Likewise.
+ (.set_base_init): Likewise.
+ (nodecls): Likewise.
+ * pt.c (instantiate_decl): Likewise.
+ * rtti.c (synthesize_tinfo_fn): Likewise.
+ * semantics.c (genrtl_try_block): Simplify.
+ (expand_body): Use genrtl_start_function and
+ genrtl_finish_function.
+ (genrtl_start_function): New function.
+ (genrtl_finish_function): Likewise.
+
+2000-09-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (cp_tree_printer, case 'P'): Append break.
+
+2000-09-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (frob_opname): Declare.
+ * parse.y (saved_scopes): New static variable.
+ (cp_parse_init): Adjust.
+ (do_id): If lastiddecl is NULL, do do_identifier.
+ (operator): Save scope information.
+ (unoperator): New reduction. Restore scope information.
+ (operator_name): Append unoperator. Call frob_opname.
+ * spew.c (frob_opname): Define.
+
+2000-09-10 Zack Weinberg <zack@wolery.cumb.org>
+
+ * decl.c, rtti.c: Include defaults.h if not already included.
+ Don't define the *_TYPE_SIZE macros.
+
+2000-09-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (push_switch): Change prototype.
+ (check_cp_case_value): Remove declaration.
+ (decl_constant_value): Likewise.
+ * decl.c (struct cp_switch): Add switch_stmt and cases.
+ (case_compare): New function.
+ (push_switch): Set switch_stmt. Initialize cases.
+ (pop_switch): Clean up cases.
+ (define_case_label): Rename to ...
+ (finish_case_label): ... this. Do semantic analysis for case
+ labels here.
+ (start_function): Correct comment.
+ * decl2.c (check_cp_case_value): Remove.
+ * expr.c (do_case): Remove.
+ * pt.c (tsubst_expr): Adjust call to finish_case_label.
+ * semantics.c (genrtl_do_poplevel): Remove declaration.
+ (RECHAIN_STMTS): Remove.
+ (finish_break_stmt): Use build_break_stmt.
+ (finish_continue_stmt): Use build_continue_stmt.
+ (finish_switch_cond): Adjust condition here, rater than in
+ c_expand_start_case.
+ (finish_case_label): Remove.
+ * typeck.c (c_expand_return): Remove.
+ (c_expand_start_case): Likewise.
+
+2000-09-07 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * ir.texi: Document type nodes.
+
+2000-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (init_cp_semantics): Declare.
+ (genrtl_try_block): Don't declare.
+ (genrtl_handler): Likewise.
+ (genrtl_catch_block): Likewise.
+ (genrtl_ctor_stmt): Likewise.
+ (genrtl_subobject): Likewise.
+ (genrtl_do_poplevel): Likewise.
+ (genrtl_named_return_value): Likewise.
+ * lex.c (init_parse): Call init_cp_semantics.
+ * semantics.c (genrtl_try_block): Give it internal linkage.
+ (genrtl_handler): Likewise.
+ (genrtl_catch_block): Likewise.
+ (genrtl_ctor_stmt): Likewise.
+ (genrtl_subobject): Likewise.
+ (genrtl_do_poplevel): Likewise.
+ (genrtl_named_return_value): Likewise.
+ (lang_expand_stmt): Rename to ...
+ (cp_expand_stmt): ... this. Only handle C++-specific nodes.
+ (init_cp_semantics): Define.
+
+ * decl.c (initialize_local_var): Remove RTL-generating code.
+ * semantics.c (genrtl_try_block): Fix formatting.
+
+ Move statement-tree facilities from C++ to C front-end.
+ * cp-tree.h (cp_tree_index): Remove CPTI_VOID_ZERO.
+ (void_zero_node): Remove.
+ (stmt_tree): Likewise.
+ (scope_chain): Adjust.
+ (language_function): Rename to cp_language_function.
+ (cp_function_chain): Adjust.
+ (current_stmt_tree): Remove.
+ (last_tree): Likewise.
+ (last_expr_type): Likewise.
+ (struct lang_decl): Adjust.
+ (STMT_IS_FULL_EXPR_P): Remove.
+ (add_tree): Remove.
+ (begin_stmt_tree): Likewise.
+ (finish_stmt_tree): Likewise.
+ (walk_tree_fn): Likewise.
+ (walk_stmt_tree): Likewise.
+ * class.c (finish_struct): Replace use of add_tree with add_stmt.
+ * decl.c (mark_stmt_tree): Adjust type.
+ (init_decl_processing): Don't build void_zero_node.
+ (initialize_local_var): Adjust usage of current_stmt_tree.
+ (finish_enum): Use add_stmt, not add_tree.
+ (save_function_data): Adjust use of language_function.
+ (finish_constructor_body): Use add_stmt, not add_tree.
+ (finish_destructor_body): Likewise.
+ (push_cp_function_context): Adjust use of language_function.
+ (pop_cp_function_context): Likewise.
+ (mark_lang_function): Likewise.
+ (mark_cp_function_context): Likewise.
+ * init.c (build_aggr_init): Adjust use of current_stmt_tree.
+ (build_vec_init): Likewise.
+ * semantics.c (SET_LAST_STMT): Remove.
+ (RECHAIN_STMTS): Don't use it.
+ (stmts_are_full_exprs_p): Adjust use of current_stmt_tree.
+ (current_stmt_tree): Define.
+ (add_tree): Remove.
+ (finish_goto_stmt): Use add_stmt, not add_tree.
+ (finish_expr_stmt): Likewise.
+ (begin_if_stmt): Likewise.
+ (finish_then_clause): Likewise.
+ (begin_while_stmt): Likewise.
+ (begin_do_stmt): Likewise.
+ (finish_return_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (finish_break_stmt): Likewise.
+ (finish_continue_stmt): Likewise.
+ (begin_switch_stmt): Likewise.
+ (finish_case_label): Likewise.
+ (begin_try_block): Likewise.
+ (begin_function_try_block): Likewise.
+ (begin_handler): Likewise.
+ (begin_catch_block): Likewise.
+ (begin_compound_stmt): Likewise.
+ (begin_asm_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ (finish_label_stmt): Likewise.
+ (add_decl_stmt): Likewise.
+ (finish_subobject): Likewise.
+ (finish_decl_cleanup): Likewise.
+ (finish_named_return_value): Likewise.
+ (setup_vtbl_ptr): Likewise.
+ (add_scope_stmt): Likewise.
+ (finish_stmt_expr): Likewise.
+ (prune_unused_decls): Remove.
+ (begin_stmt_tree): Likewise.
+ (finish_stmt_tree): Likewise.
+ (prep_stmt): Adjust use of current_stmt_tree.
+ (lang_expand_stmt): Likewise.
+ * tree.c (statement_code_p): Remove.
+ (cp_statement_code_p): New function.
+ (walk_stmt_tree): Remove.
+ (init_tree): Set lang_statement_code_p.
+
+2000-09-06 Zack Weinberg <zack@wolery.cumb.org>
+
+ Integrated preprocessor.
+
+ * Make-lang.in, Makefile.in: Remove all references to input.c,
+ gxx.gperf, and hash.h. Add ../c-lex.o to C_OBJS.
+ * gxx.gperf, hash.h, input.c: Delete.
+ * lang-specs.h: Pass -lang-c++ to cc1plus so cpplib is
+ initialized properly.
+
+ * class.c (fixup_pending_inline): Take a tree, not a
+ struct pending_inline *. All callers changed.
+ (init_class_processing): Set RID_PUBLIC, RID_PRIVATE,
+ RID_PROTECTED entries in ridpointers[] array here.
+ * decl.c (duplicate_decls): Do not refer to struct
+ pending_inline.
+ (record_builtin_type, init_decl_processing): Use RID_MAX not
+ CP_RID_MAX.
+ (grokdeclarator): Use C_IS_RESERVED_WORD.
+ * decl2.c (lang_decode_option): Ignore -lang-c++ for sake of
+ cpplib.
+ (grok_x_components): Do not inspect pending_inlines chain.
+
+ * cp-tree.h (struct lang_identifier): Add rid_code entry.
+ (C_IS_RESERVED_WORD, C_RID_CODE, C_RID_YYCODE): New.
+ (flag_no_gnu_keywords, flag_operator_names, rid_to_yy): Declare.
+ (DEFARG_LENGTH, struct pending_inline, TIME_IDENTIFIER_TIME,
+ TIME_IDENTIFIER_FILEINFO): Kill.
+ Update prototypes.
+ * lex.h: Expunge cp_rid. Rewrite RIDBIT macros to use just a
+ single 32-bit word.
+ * parse.y: Call do_pending_inlines unconditionally.
+ reinit_parse_for_method is now snarf_method. fn.defpen is no
+ longer necessary. Remove unnecessary <itype> annotation on
+ SCOPE. Do not refer to end_of_file or struct pending_inline.
+ * semantics.c (begin_inline_definitions): Call
+ do_pending_inlines unconditionally.
+
+ * lex.c: Remove all code now shared with C front end.
+ Initialize cpplib properly if USE_CPPLIB. Put reserved words
+ into the get_identifier table. Rewrite pragma handling to
+ work with the registry. Move code to save tokens for later
+ processing to spew.c.
+
+ * spew.c: Rewrite everything in terms of token streams instead
+ of text. Move routines here from lex.c / input.c as
+ appropriate. GC-mark trees hanging off the pending inlines
+ chain.
+
+2000-09-06 Mark Mitchell <mark@codesourcery.com>
+
+ * NEWS: Mention that the named return value extension has been
+ deprecated.
+ * cp-tree.h (original_result_rtx): Define.
+ (TREE_REFERENCE_EXPR): Remove.
+ (DECL_VPARENT): Likewise.
+ (pushdecl_nonclass_level): Likewise.
+ (store_return_init): Likewise.
+ (reinit_lang_specific): Likewise.
+ (genrtl_named_return_value): Change prototype.
+ * decl.c (original_result_rtx): Remove.
+ (cp_finish_decl): Don't build DECL_STMTs for RESULT_DECLs.
+ Do not generate RTL for local variables here.
+ (store_return_init): Remove.
+ * semantics.c (genrtl_named_return_value): Simplify. Fold in
+ store_return_init.
+ (finish_named_return_value): Adjust accordingly. Warn that this
+ extension is deprecated.
+ (lang_expand_stmt): Adjust call to genrtl_named_return_value.
+
+2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (type_unification_real): Replace switch with if.
+ (unify): Tsubst non-type parms before comparing.
+
+2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * error.c (dump_typename): New function, broken out of ...
+ (dump_type): ... here. Use it.
+ * typeck.c (same_type_p): Use cp_tree_equal for TYPENAME_TYPE.
+
+2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (build_offset_ref): Deal with namespace scoped
+ TEMPLATE_ID_EXPRs.
+
+2000-09-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (resolve_address_of_overloaded_function): Add
+ explanation message.
+ * decl.c (define_case_label): Reformat explanation.
+ * decl2.c (finish_static_data_member_decl): Likewise.
+ (grokfield): Likewise.
+ * friend.c (do_friend): Likewise.
+
+2000-09-05 Zack Weinberg <zack@wolery.cumb.org>
+
+ * tree.c (walk_tree): Expose tail recursion.
+ (walk_stmt_tree): New function.
+ * cp-tree.h: Prototype walk_stmt_tree.
+ * semantics.c (prune_unused_decls): Operate on SCOPE_STMTs not
+ the BLOCKs directly. If a BLOCK has no variables after
+ pruning, discard it.
+ (finish_stmt_tree): Use walk_stmt_tree. No need to save and
+ restore the line number.
+
+2000-09-05 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (CXX_TREE_H): Add dependency on HTAB_H.
+ (pt.o): Remove dependency on HTAB_H.
+ * cp-tree.h: Include hashtab.h.
+ (walk_tree): Change prototype.
+ (walk_tree_without_duplicates): New function.
+ * decl.c (check_default_argument): Use it.
+ * optimize.c (remap_decl): Adjust calls to walk_tree.
+ (copy_body): Likewise.
+ (expand_calls_inline): Likewise.
+ (calls_setjmp_p): Use walk_tree_without_duplicates.
+ * pt.c: Don't include hashtab.h.
+ (for_each_template_parm): Use walk_tree_without_duplicates.
+ * semantics.c (finish-stmt_tree): Likewise.
+ (expand_body): Likewise.
+ * tree.c (walk_tree): Add additional parameter.
+ (walk_tree_without_duplicates): New function.
+ (count_trees): Use it.
+ (verify_stmt_tree): Adjust call to walk_tree.
+ (find_tree): Use walk_tree_without_duplicates.
+ (no_linkage_check): Likewise.
+ (break_out_target_exprs): Adjust call to walk_tree.
+ (cp_unsave): Likewise.
+
+2000-09-04 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+
+ * cp-tree.def (BOUND_TEMPLATE_TEMPLATE_PARM): New tree code.
+ (TEMPLATE_TEMPLATE_PARM): Adjust comment.
+ * cp-tree.h (TYPE_BINFO): Adjust comment.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise.
+ (TEMPLATE_TYPE_PARM_INDEX): Likewise.
+ (IS_AGGR_TYPE): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
+ (TYPE_TEMPLATE_INFO): Likewise.
+ (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): Likewise.
+ * class.c (push_nested_class): Likewise.
+ * decl.c (lookup_name_real): Likewise.
+ (grokdeclarator): Likewise.
+ (grok_op_properties): Likewise.
+ (xref_tag): Likewise.
+ (xref_basetypes): Likewise.
+ * decl2.c (constructor_name_full): Likewise.
+ (arg_assoc_template_arg): Add TEMPLATE_TEMPLATE_PARM case.
+ (arg_assoc_type): Use BOUND_TEMPLATE_TEMPLATE_PARM instead.
+ * error.c (dump_type): Split TEMPLATE_TEMPLATE_PARM case.
+ (dump_type_prefix): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ (dump_type_suffix): Likewise.
+ * init.c (is_aggr_type): Use BOUND_TEMPLATE_TEMPLATE_PARM
+ instead.
+ (get_aggr_from_typedef): Likewise.
+ * mangle.c (write_type): Split TEMPLATE_TEMPLATE_PARM case.
+ (write_expression): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ (write_template_parm): Likewise.
+ (write_template_template_parm): Check tree code instead of
+ using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+ * method.c (build_overload_nested_name): Add
+ BOUND_TEMPLATE_TEMPLATE_PARM.
+ (process_overload_item): Split TEMPLATE_TEMPLATE_PARM case.
+ * parse.y (bad_parm): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ * pt.c (convert_template_argument): Check tree code instead of
+ using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+ (for_each_template_parm_r): Split TEMPLATE_TEMPLATE_PARM case.
+ (for_each_template_parm): Adjust comment.
+ (tsubst): Add BOUND_TEMPLATE_TEMPLATE_PARM. Reorganize.
+ (tsubst_copy): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ (unify): Add BOUND_TEMPLATE_TEMPLATE_PARM. Reorganize. Use
+ template_args_equal to compare template template parameter cases.
+ * ptree.c (print_lang_type): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ * search.c (lookup_field_1): Use BOUND_TEMPLATE_TEMPLATE_PARM
+ instead.
+ * tree.c (copy_template_template_parm): Decide whether to create
+ a TEMPLATE_TEMPLATE_PARM or BOUND_TEMPLATE_TEMPLATE_PARM node.
+ (walk_tree): Add BOUND_TEMPLATE_TEMPLATE_PARM.
+ (copy_tree_r): Likewise.
+ * typeck.c (comptypes): Likewise. Check tree code instead of
+ using TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO.
+
+2000-09-04 Mark Elbrecht <snowball3@bigfoot.com>
+
+ * decl.c (finish_function): Move the code for handling functions
+ marked with the constructor and destructor attributes inside the
+ expand_p block.
+
+2000-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (resolve_offset_ref): Deal with TEMPLATE_ID_EXPR.
+
+2000-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (lookup_template_class): Remove abort.
+ * tree.c (get_type_decl): Allow error_mark_node.
+
+2000-09-04 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (arg_assoc): Deal with COMPONENT_REFs inside
+ TEMPLATE_ID_EXPRs.
+
+2000-09-03 Mark Mitchell <mark@codesourcery.com>
+
+ * operators.def (ALIGNOF_EXPR, MAX_EXPR, MIN_EXPR): Change
+ new ABI mangling.
+
+2000-09-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (named_class_head): Check for TYPENAME_TYPE. Simplify
+ union tag mismatch error reporting.
+
+2000-09-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_scoped_method_call): Check it is not a namespace.
+
+2000-08-30 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (LOCAL_CLASS_P): Use decl_function_context.
+
+ * tree.c (bot_manip): Check TREE_CONSTANT rather than
+ !TREE_SIDE_EFFECTS. Call break_out_target_exprs and
+ build_target_expr_with_type for the non-AGGR_INIT_EXPR case.
+
+ * decl.c (start_function): Always call make_function_rtl.
+
+2000-08-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * semantics.c (prune_unused_decls): New function.
+ (finish_stmt_tree): Call it via walk_tree.
+
+2000-08-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * class.c (build_secondary_vtable): Constify a char *.
+ * decl.c (init_decl_processing): Initialize function_id_node,
+ pretty_function_id_node, and func_id_node.
+ * input.c (struct input_source): Constify 'str'.
+ (feed_input): Constify first argument.
+ * mangle.c (write_identifier): Constify argument.
+ * pt.c (mangle_class_name_for_template): Constify argument.
+
+2000-08-29 Mark Mitchell <mark@codesourcery.com>
+
+ * typeck.c (mark_addressable): Remove code that pokes around in
+ RTL.
+
+2000-08-28 Jason Merrill <jason@redhat.com>
+
+ * lex.c (file_name_nondirectory): Move to toplev.c.
+
+ * cp-tree.h (LOCAL_CLASS_P): New macro.
+ * class.c (finish_struct_1): Use it.
+
+2000-08-27 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (CLASSTYPE_TEMPLATE_ID_P): Remove unexplained voodoo.
+ (write_encoding): Pass another argument to write_name.
+ (write_name): Add ignore_local_scope parameter. Fix handling of
+ local names.
+ (write_nested_name): Use write_unqualified_name.
+ (write_prefix): Likewise. Skip out on FUNCTION_DECLs.
+ (write_template_prefix): Use write_unqualified_name.
+ (write_component): Remove.
+ (write_local_name): Add parameter. Use direct local entity to
+ discriminator calculation.
+ (write_class_enum_type): Pass another argument to write_name.
+ (write_template_template_arg): Likewise.
+ (make_guard_variable): Likewise.
+
+2000-08-27 Jason Merrill <jason@redhat.com>
+
+ * decl.c (pushdecl): Matching decls for local externs are found in
+ the current level. Propagate linkage information from previous
+ declarations.
+
+2000-08-26 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * ir.texi (Expressions): Fix typo.
+
+2000-08-25 Greg McGary <greg@mcgary.org>
+
+ * tree.c (init_tree): Use ARRAY_SIZE.
+
+2000-08-25 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (cp_tree_printer): Rework.
+
+2000-08-25 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (CXX_LIB2FUNCS): Remove cp-demangle.o and
+ dyn-string.o.
+ (CXX_LIB2SRCS): Remove cp-demangle.c and dyn-string.c.
+ (cp-demangle.o): Remove target.
+ (dyn-string.o): Likewise.
+
+ * decl.c (grokfndecl): Require that `main' return an `int'.
+ * mangle.c (write_encoding): Don't mangle return types for
+ conversion functions.
+
+2000-08-25 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (tree_formatting_info): New data type.
+ (tree_being_formatted): New macro.
+ (tree_formatting_flags): Likewise.
+ (put_whitespace): Likewise.
+ (print_tree_identifier): Likewise.
+ (print_identifier): Likewise.
+ (cp_tree_printer, print_function_argument_list, print_declaration,
+ print_expression, print_function_declaration,
+ print_function_parameter, print_type, print_cv_qualifier): New
+ functions.
+ (init_error): Initialize lang_printer.
+
+2000-08-24 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_ptrmemfunc): Just reinterpret if there's no
+ adjustment necessary.
+
+2000-08-24 Greg McGary <greg@mcgary.org>
+
+ * cp-tree.h (MAIN_NAME_P): Remove macro.
+
+2000-08-24 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (print_instantiation_context): Don't forget to flush the
+ buffer.
+
+2000-08-23 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (build_ptrmemfunc): Save the input pmf.
+
+ * method.c (process_modifiers): Use same_type_p.
+
+2000-08-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_CLONED_FUNCTION_P): Check DECL_LANG_SPECIFIC.
+ * mangle.c (write_function_type): Change prototype.
+ (write_encoding): Don't mangle return types for
+ constructors or destructors.
+ (write_type): Adjust call to write_function_type.
+ * pt.c (instantiate_template): Instantiate alternate entry points
+ when instantiating the main function.
+
+2000-08-23 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * error.c (cp_print_error_function): Don't use embedded '\n' in
+ output_printf.
+
+2000-08-23 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl.c (init_decl_processing): Remove bogus initialization.
+ * error.c (lang_print_error_function): Restore here.
+ (init_error): Initialize print_error_function.
+
+2000-08-22 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * decl2.c (arg_assoc): Revert my 2000-08-11 change.
+
+2000-08-22 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * Makefile.in (error.o): Depends on diagnostic.h
+
+ * cp-tree.h (problematic_instantiation_changed,
+ record_last_problematic_instantiation, current_instantiation,
+ print_instantiation_context): Declare.
+ (maybe_print_template_context): Remove.
+
+ * decl.c (init_decl_processing): Set print_error_function to NULL.
+ (lang_print_error_function): Remove, since we're using a new
+ machinery.
+
+ * error.c: #include diagnostic.h
+ (function_category): New function.
+ (cp_diagnostic_starter): Likewise.
+ (cp_diagnostic_finalizer): Likewise.
+ (cp_print_error_function): Likewise.
+ (maybe_print_instantiation_context): Likewise.
+ (print_instantiation_full_context): Likewise.
+ (print_instantiation_partial_context): Likewise.
+ (print_instantiation_context): Define.
+ (init_error): Initialize diagnostic pager and finalizer.
+
+ * pt.c (problematic_instantiation_changed): Define.
+ (record_last_problematic_instantiation): Likewise.
+ (current_instantiation): Likewise.
+ (maybe_print_template_context): Remove.
+ (print_template_context): Likewise.
+ (current_tinst_level): Make static to reflect Brendan Kehoe's
+ change of 1995-04-13.
+ (push_tinst_level): Call print_instantiation_context.
+
+2000-08-21 Nix <nix@esperi.demon.co.uk>
+
+ * lang-specs.h: Do not process -o or run the assembler if
+ -fsyntax-only.
+
+2000-08-21 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (flag_hosted, flag_noniso_default_format_attributes): New
+ variables.
+ * decl2.c (lang_decode_option): Disable gettext attributes for
+ -ansi.
+
+2000-08-21 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c (lang_init_options): Default diagnostic message maximum
+ length to 80, when line-wrapping.
+
+2000-08-20 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtbl_initializer): Clear the entire
+ vtbl_init_data. Start keeping track of the functions for which we
+ have created vcall offsets here.
+ (dfs_build_vcall_offset_vtbl_entries): Remove.
+ (build_vcall_offset_vtbl_entries): Reimplement.
+ (add_vcall_offset_vtbl_entries_r): New function.
+ (add_vcall_offset_vtbl_entries_1): Likewise. Tweak logic for
+ computing when vcall offsets are necessary.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (member_function_or_else): Use cp_error ... %T.
+ (grokdeclarator): Likewise.
+ (start_method): Likewise.
+ * friend.c (make_friend_class): Use cp_pedwarn ... %T.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (grokfield): Set CLASSTYPE_GOT_SEMICOLON on class
+ TYPE_DECLs.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (PTRMEM_OK_P): New macro.
+ (itf_ptrmem_ok): New enumeration value.
+ * class.c (resolve_address_of_overloaded_function): Add PTRMEM
+ argument. Diagnose implicit pointer to member.
+ (instantiate_type): Don't diagnose implicit pointer to member
+ here. Pass itf_ptrmem_ok if ok. Adjust calls to
+ resolve_address_of_overloaded_function.
+ * init.c (build_offset_ref): Set PTRMEM_OK_P.
+ (resolve_offset_ref): Don't diagnose implicit pointer to member here.
+ * semantics.c (finish_parenthesized_expr): Clear OFFSET_REFs here.
+ * typeck.c (build_x_unary_op): Calculate PTRMEM_OK_P.
+ (build_unary_op): Deal with single non-static member in
+ microsoft-land.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (arg_assoc_type): Cope with TYPENAME_TYPE.
+
+2000-08-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (enum_name_string): Remove prototype.
+ (report_case_error): Remove prototype.
+ * cp/typeck2.c (enum_name_string): Remove.
+ (report_case_error): Remove.
+ * error.c (dump_expr): Deal with enum values directly.
+ Correctly negate integer constant.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h (__cxa_vec_new2, __cxa_vec_new3): Declare.
+ (__cxa_vec_delete2, __cxa_vec_delete3): Declare.
+ * vec.cc (__cxa_vec_new2, __cxa_vec_new3): Implement.
+ (__cxa_vec_delete2, __cxa_vec_delete3): Implement.
+ (__cxa_vec_new): Use __cxa_vec_new2.
+ (__cxa_vec_delete): Use __cxa_vec_delete2.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.cc (__cxa_vec_new): Set "C" linkage.
+ (__cxa_vec_ctor): Likewise.
+ (__cxa_vec_cctor): Likewise.
+ (__cxa_vec_dtor): Likewise.
+ (__cxa_vec_delete): Likewise.
+ * inc/cxxabi.h (__cxa_vec_new): Set "C" linkage.
+ (__cxa_vec_ctor): Likewise.
+ (__cxa_vec_cctor): Likewise.
+ (__cxa_vec_dtor): Likewise.
+ (__cxa_vec_delete): Likewise.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (instantiate_type): Reinstate local variable
+ deleted in previous change.
+
+ * cvt.c (cp_convert_to_pointer): Pass itf_complain, not
+ itf_no_attributes.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (instantiate_type_flags): New enumeration.
+ (instantiate_type): Change parameter.
+ * class.c (instantiate_type): Adjust prototype. Adjust.
+ * call.c (standard_conversion): Adjust instantiate_type call.
+ (reference_binding): Likewise.
+ (build_op_delete_call): Likewise.
+ (convert_like_real): Likewise.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_reference): Likewise.
+ * pt.c (convert_nontype_argument): Likewise.
+ * typeck.c (build_binary_op): Likewise.
+ (build_ptrmemfunc): Likewise.
+ (convert_for_assignment): Likewise.
+
+2000-08-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CPTR_AGGR_TAG): New global tree node.
+ (current_aggr): Define.
+ * decl.c (grokdeclarator): Make sure a friend class is an
+ elaborated type specifier.
+ * parse.y (current_aggr): Remove static definition.
+ (cp_parse_init): Adjust.
+ (structsp): Clear and restore current_aggr.
+ (component_decl_list): Clear current_aggr.
+
+ * error.c (dump_type, case TYPENAME_TYPE): Don't emit the
+ aggregate tag on the typename's context.
+
+ * pt.c (tsubst_friend_class): Return error_mark_node, if
+ parms becomes NULL.
+ (instantiate_class_template): Ignore error_mark_node friend types.
+
+2000-08-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cvt.c (warn_ref_binding): New static function, broken out of ...
+ (convert_to_reference): ... here. Use it.
+
+2000-08-11 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu>
+
+ * parse.y (template_arg): Add rule for template qualified with
+ global scope.
+
+2000-08-11 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * decl2.c (add_function): Reorganize.
+ (arg_assoc): Do not consider function template decls.
+
+2000-08-11 Jason Merrill <jason@redhat.com>
+
+ * decl.c (lookup_name_real): Don't forget the TYPENAME_TYPE we're
+ looking inside.
+
+2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (resolve_scope_to_name): Remove unused prototype.
+ (lookup_nested_tag): Likewise.
+
+ * decl2.c (grokfield): Fix comment to reflect many types of _DECLs
+ can be produced.
+
+2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (named_complex_class_head_sans_basetype): Remove
+ always true if.
+
+2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (build_expr_from_tree, case METHOD_CALL_EXPR): Build
+ explicit TEMPLATE_ID_EXPR args.
+ (build_expr_from_tree, case CALL_EXPR): Likewise.
+
+2000-08-11 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (check_tag_decl): Diagnose typename's which don't
+ declare anything.
+
+2000-08-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * init.c (build_aggr_init): Reject bogus array initializers
+ early.
+
+2000-08-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (build_dynamic_cast_1): Set "C" linkage for new abi
+ runtime.
+ * cp/tinfo.cc (__dynamic_cast): Likewise.
+ * cp/inc/cxxabi.h (__dynamic_cast): Likewise.
+
+2000-08-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cvt.c (convert_to_pointer_force): Fix error message when
+ attempting to cast from ambiguous base.
+
+2000-08-08 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_aggr_type): Bail if creating the argvec fails.
+ (tsubst_template_arg_vector): Likewise.
+
+ * decl2.c (build_anon_union_vars): Choose the largest field; don't
+ assume that one will be as large as the union.
+
+2000-08-07 Kazu Hirata <kazu@hxi.com>
+
+ * cp-tree.h (CLASSTYPE_HAS_PRIMARY_BASE_P): Fix a comment typo.
+ * decl.c (pop_labels): Likewise.
+
+2000-08-04 Jeffrey Oldham <oldham@codesourcery.com>
+
+ * inc/cxxabi.h (__pbase_type_info): Changed member names to match
+ specifications.
+ (__pointer_to_member_type_info): Likewise.
+ (__base_class_info): Likewise.
+ (__class_type_info): Likewise.
+ (__si_class_type_info): Likewise.
+ (__vmi_class_type_info): Likewise.
+ * tinfo.cc (__si_class_type_info::__do_find_public_src):
+ Changed member names to match specifications.
+ (__vmi_class_type_info::__do_find_public_src): Likewise.
+ (__si_class_type_info::__do_dyncast): Likewise.
+ (__vmi_class_type_info::__do_dyncast): Likewise.
+ (__si_class_type_info::__do_upcast): Likewise.
+ (__vmi_class_type_info::__do_upcast): Likewise.
+ * tinfo2.cc (__pbase_type_info::__do_catch): Likewise.
+ (__pbase_type_info::__pointer_catch): Likewise.
+ (__pointer_type_info::__pointer_catch): Likewise.
+ (__pointer_to_member_type_info::__pointer_catch): Likewise.
+
+2000-08-04 Zack Weinberg <zack@wolery.cumb.org>
+
+ * Make-lang.in (cc1plus): Depend on $(BACKEND), not stamp-objlist.
+ * Makefile.in: Add C_OBJS, BACKEND; delete OBJS, OBJDEPS.
+ (cc1plus): Link with $(BACKEND) and $(C_OBJS).
+
+2000-08-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (add_method): Change prototype.
+ * class.c (add_method): Remove FIELDS parameter. Add ERROR_P.
+ Don't double the size of the method vector in the error case.
+ (handle_using_decl): Adjust call to add_method.
+ (add_implicitly_declared_members): Likewise.
+ (clone_function_decl): Likewise.
+ * decl2.c (check_classfn): Likewise.
+ * semantics.c (finish_member_declaration): Likewise.
+
+2000-08-04 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * decl.c (flag_isoc94): New variable.
+
+2000-08-02 Jason Merrill <jason@redhat.com>
+
+ * pt.c (do_type_instantiation): Add complain parm; don't complain
+ if called recursively.
+ * cp-tree.h, parse.y: Adjust.
+
+2000-08-02 Zack Weinberg <zack@wolery.cumb.org>
+
+ * decl2.c: Silently ignore -Wstrict-prototypes; warn about
+ -Wno-strict-prototypes.
+
+ * g++spec.c: Adjust type of second argument to
+ lang_specific_driver, and update code as necessary.
+
+ * cp-tree.h: Don't prototype min_precision here.
+ (my_friendly_assert): Cast expression to void.
+ * semantics.c (do_poplevel): Initialize scope_stmts.
+
+2000-08-02 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_NEEDED_P): Tweak.
+
+2000-07-28 Jason Merrill <jason@redhat.com>
+
+ * lang-specs.h: Use %i in rule for .ii files.
+
+2000-07-31 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Rename cpp to cpp0 and/or tradcpp to tradcpp0.
+
+2000-07-30 Mark Mitchell <mark@codesourcery.com>
+
+ Allow indirect primary bases.
+ * cp-tree.h (struct lang_type): Remove vfield_parent. Add
+ primary_base.
+ (CLASSTYPE_VFIELD_PARENT): Remove.
+ (CLASSTYPE_PRIMARY_BINFO): Reimplement.
+ (BINFO_PRIMARY_BINFO): Remove.
+ (CLASSTYPE_HAS_PRIMARY_BASE_P): Reimplement.
+ (BINFO_VBASE_PRIMARY_P): Likewise.
+ (BINFO_PRIMARY_BASE_OF): New macro.
+ (BINFO_INDIRECT_PRIMARY_P): Likewise.
+ (get_primary_binfo): New function.
+ * decl.c (lang_mark_tree): Make lang_type::primary_base.
+ * class.c (vcall_offset_data_s): Rename to ...
+ (vtbl_init_data_s): ... this. Rename primary_p to primary_vtbl_p,
+ and add ctor_vtbl_p.
+ (get_derived_offset): Use get_primary_binfo.
+ (dfs_mark_primary_bases): Adjust handling of virtual primary
+ bases.
+ (mark_primary_bases): Likewise.
+ (set_primary_base): Take a binfo, not an integer, as a
+ representation of the primary base.
+ (indirect_primary_base_p): Remove.
+ (determine_primary_base): Adjust for indirect primary bases.
+ (dfs_find_final_overrider): Fix typo in coment.
+ (update_vtable_entry_for_fn): Use get_primary_binfo.
+ (layout_nonempty_base_or_field): Tweak.
+ (build_base_fields): Adjust for new primary base semantics.
+ (dfs_propagate_binfo_offsets): Remove.
+ (propagate_binfo_offsets): Rewrite.
+ (dfs_set_offset_for_shared_vbases): Remove.
+ (layout_virtual_bases): Don't use it.
+ (layout_class_type): Set CLASSTYPE_SIZE correctly under the new
+ ABI.
+ (finish_struct_1): Set CLASSTYPE_PRIMARY_BINFO, not
+ CLASSTYPE_VFIELD_PARENT.
+ (dfs_get_primary_binfo): New function.
+ (get_primary_binfo): Likewise.
+ (dump_class_hierarchy_r): Tweak printing of primary bases.
+ (build_vtbl_initializer): Fix typo in comments. Use
+ vtbl_init_data.
+ (build_vcall_and_vbase_vtbl_entries): Likewise.
+ (build_vbaes_offset_vtbl_entries): Likewise.
+ (dfs_build_vcall_offset_vtbl_entries): Adjust setting of
+ BV_VCALL_INDEX to handle indirect primary bases.
+ (build_vcall_offset_vtbl_entries): Use vtbl_init_data.
+ (build_rtti_vtbl_entries): Likewise.
+ * search.c (get_shared_vbase_if_not_primary): Tweak.
+ (find_vbase_instance): Likewise.
+ (binfo_for_vtable): Simplify.
+ * tree.c (unshare_base_binfos): Clear BINFO_PRIMARY_BASE_OF.
+ (make_binfo): Make it have 11 entries.
+
+2000-07-30 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (DECL_TEMPLATE_ID_P): Remove.
+ (CLASSTYEP_TEMPLATE_ID_P): Check template info, and context when
+ ascertaining primaryness.
+ (G): Remove template_args.
+ (decl_is_template_id): New function.
+ (write_encoding): Use decl_is_template_id.
+ (write_name): Likewise. Handle type_decls. Get main variant of
+ type decls.
+ (write_nested_name): Likewise.
+ (write_prefix): Likewise.
+ (write_template_prefix): Likewise.
+ (write_special_name_constructor): Remove defunct production from
+ comment.
+ (write_bare_function_type): Remove comment about absent parameter.
+ (write_template_template_arg): Add missing grammar production to
+ comment.
+
+2000-07-27 Jason Merrill <jason@redhat.com>
+
+ * decl.c (duplicate_decls): If common_type produces a non-typedef
+ type for a typedef, just use the old type.
+
+2000-07-27 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (function_depth): Declare.
+ (verify_stmt_tree): Likewise.
+ (find_tree): Likewise.
+ * decl.c (function_depth): Give it external linkage.
+ * optimize.c (optimize_function): Increment and decrement it.
+ * tree.c (verify_stmt_tree_r): New function.
+ (verify_stmt_tree): Likewise.
+ (find_tree_r): Likewise.
+ (find_tree): Likewise.
+
+2000-07-27 Jason Merrill <jason@redhat.com>
+
+ * pt.c (for_each_template_parm_r, case RECORD_TYPE): Use
+ TYPE_PTRMEMFUNC_P.
+ * cp-tree.h (TYPE_TEMPLATE_INFO): Check for TYPE_LANG_SPECIFIC.
+
+2000-07-26 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_cleanup_fn): Mark the function as `inline'.
+ * decl2.c (get_guard): Call cp_finish_decl, not
+ rest_of_decl_compilation, for local guards.
+ * lex.c (do_identifier): Remove unused variable.
+
+2000-07-26 Marc Espie <espie@cvs.openbsd.org>
+
+ * parse.y: Add missing ';'.
+
+2000-07-26 Mark Mitchell <mark@codesourcery.com>
+
+ * parse.y (empty_parms): Use `()', not `(...)', when in the scope
+ of `extern "C++"'.
+
+2000-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ Kill strict_prototype. Backwards compatibility only for
+ non NO_IMPLICIT_EXTERN_C systems.
+ * cp-tree.h (flag_strict_prototype): Remove.
+ (strict_prototype): Remove.
+ (strict_prototypes_lang_c, strict_prototypes_lang_cplusplus): Remove.
+ * decl.c (maybe_push_to_top_level): Adjust.
+ (pop_from_top_level): Adjust.
+ (decls_match): Only allow sloppy parm matching for ancient
+ system headers.
+ (init_decl_processing): Adjust.
+ (grokdeclarator): Adjust.
+ * decl2.c (flag_strict_prototype): Remove.
+ (strict_prototype): Remove.
+ (strict_prototypes_lang_c, strict_prototypes_lang_cplusplus): Remove.
+ (lang_f_options): Remove "strict-prototype".
+ (unsupported-options): Add "strict-prototype".
+ * lex.c (do_identifier): Adjust.
+ (do_scoped_id): Adjust.
+ * parse.y (empty_parms): Adjust.
+ * class.c (push_lang_context): Adjust.
+ (pop_lang_context): Adjust.
+ * typeck.c (comp_target_parms): Adjust.
+
+2000-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (poplevel): Deal with anonymous variables at for scope.
+ (maybe_inject_for_scope_var): Likewise.
+
+2000-07-25 Zack Weinberg <zack@wolery.cumb.org>
+
+ * decl.c: Remove all signal handling code, now done in toplev.c.
+
+2000-07-23 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (make_rtl_for_nonlocal_decl): Rework.
+
+ * pt.c (lookup_template_class): Ensure that TYPE_CONTEXT is set
+ correctly.
+
+2000-07-20 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cp-tree.h: Use __FUNCTION__ not __PRETTY_FUNCTION__.
+ Define my_friendly_assert and my_friendly_abort as macros
+ which may call friendly_abort. Prototype friendly abort, not
+ my_friendly_abort or my_friendly_assert.
+ * decl.c (signal_catch): Report the signal caught in the error
+ message. Call fatal directly.
+ * typeck2.c (ack, my_friendly_assert): Delete.
+ (my_friendly_abort): Rename to friendly_abort. Expect file,
+ line, and function parameters. Report the abort code, then
+ call fancy_abort. Do not mask an abort if errors have
+ already occurred.
+
+2000-07-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (comp_target_parms): Remove obsolete parameter.
+ (comp_target_types): Adjust.
+
+2000-07-17 Jason Merrill <jason@redhat.com>
+
+ * typeck.c (mark_addressable): Never set TREE_USED.
+ * call.c (build_call): Don't abort on calls to library functions
+ that have been declared normally.
+
+ * typeck.c (build_binary_op): Fix grammar in warning.
+
+ * exception.cc (__eh_free): Fix prototype.
+
+ * decl2.c (finish_decl_parsing): Handle TEMPLATE_ID_EXPR.
+
+ * decl.c (pushdecl): Handle seeing an OVERLOAD in
+ IDENTIFIER_NAMESPACE_VALUE.
+
+2000-07-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (THUNK_VCALL_OFFSET): Update documentation.
+ * method.c (use_thunk): Correct handling of vcall offsets.
+
+2000-07-14 Zack Weinberg <zack@wolery.cumb.org>
+
+ * .cvsignore: parse.h and parse.c have no cp- prefix.
+
+2000-07-13 Mark Mitchell <mark@codesourcery.com>
+
+ * .cvsignore: New file.
+
+2000-07-13 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Use the new named specs. Remove unnecessary braces.
+
+2000-07-12 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in ($(PARSE_H)): Depend directly on parse.y.
+ * parse.c: Remove.
+ * parse.h: Likewise.
+
+2000-07-11 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Add pointers to virtual bases after
+ base classes under the old ABI.
+
+2000-07-10 Benjamin Chelf <chelf@codesourcery.com>
+
+ * semantics.c (finish_for_stmt): Remove call to emit_line_note.
+ (finish_continue_stmt): Likewise.
+ (begin_for_stmt): Remove call to note_level_for_for.
+ (finish_goto_stmt): Change call from build_min_nt
+ to build_stmt.
+ (finish_expr_stmt): Likewise.
+ (begin_if_stmt): Likewise.
+ (begin_while_stmt): Likewise.
+ (finish_while_stmt): Likewise.
+ (finish_return_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (finish_for_stmt): Likewise.
+ (finish_break_stmt): Likewise.
+ (begin_switch_stmt): Likewise.
+ (finish_case_label): Likewise.
+ (genrtl_try_block): Likewise.
+ (begin_try_block): Likewise.
+ (begin_handler): Likewise.
+ (begin_compound_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ (finish_label_stmt): Likewise.
+ (add_decl_stmt): Likewise.
+ (finish_subobject): Likewise.
+ (finish_decl_cleanup): Likewise.
+ (finish_named_return_value): Likewise.
+ (setup_vtbl_ptr): Likewise.
+ (add_scope_stmt): Likewise.
+ * decl.c (finish_constructor_body): Likewise.
+ (finish_destructor_body): Likewise.
+ * optimize.c (copy_body_r): Likewise.
+ (initialize_inlined_parameters): Likewise.
+ (declare_return_variable): Likewise.
+ (expand_call_inline): Likewise.
+
+2000-07-10 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (expand_body): Sync interface information
+ at the end of function body expansion.
+
+2000-07-09 Jason Merrill <jason@redhat.com>
+
+ * init.c (build_new_1): Bail early if the call to new fails.
+
+ * decl.c (compute_array_index_type): Check specifically for
+ an INTEGER_CST, not just TREE_CONSTANT.
+
+ * decl.c (duplicate_decls): Don't call duplicate_decls on
+ the DECL_TEMPLATE_RESULT.
+ (decls_match): Return 0 if the DECL_TEMPLATE_RESULTs have different
+ codes.
+
+ * error.c (dump_template_bindings): Don't crash if we had an
+ invalid argument list.
+
+ * typeck.c (c_expand_start_case): Do narrowing here.
+ * semantics.c (finish_switch_cond): Not here.
+
+2000-07-09 Hidvegi Zoli <hzoli@austin.ibm.com>
+
+ * parse.y (asm_clobbers): Do string concatenation.
+
+2000-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (pushtag): Don't put local classes in template functions
+ on the local_classes list.
+
+2000-07-04 Scott Snyder <snyder@fnal.gov>
+
+ * decl2.c (get_guard): Add missing return for old ABI local
+ variable case.
+
+2000-07-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (char_type_p): New function.
+ * decl.c (init_decl_processing): Don't initialize
+ signed_wchar_type_node or unsigned_wchar_type_node.
+ (complete_array_type): Handle brace-enclosed string-constants.
+ * rtti.c (emit_support_tinfos): Remove #if 0'd code.
+ * tree.c (char_type_p): New function.
+ * typeck2.c (digest_init): Use char_type_p.
+
+2000-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (tsubst): Don't layout type, if it's error_mark.
+
+2000-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (instantiate_pending_templates): Reset template level.
+
+2000-07-05 Jason Merrill <jason@redhat.com>
+
+ * call.c (joust): Don't complain about `operator char *()' beating
+ `operator const char *() const'.
+
+2000-07-04 scott snyder <snyder@fnal.gov>
+ Jason Merrill <jason@redhat.com>
+
+ * repo.c (repo_get_id): Handle the case where a class with virtual
+ bases has a null TYPE_BINFO_VTABLE.
+
+2000-07-04 Kevin Buhr <buhr@stat.wisc.edu>
+ Jason Merrill <jason@redhat.com>
+
+ * parse.y (member_init): Just pass in the type.
+ * init.c (expand_member_init): Handle getting a type.
+
+2000-07-04 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+ Jason Merrill <jason@redhat.com>
+
+ * decl.c (finish_function): Warn if a function has no return
+ statement.
+ Suggested by Andrew Koenig.
+ * typeck.c (check_return_expr): Do set current_function_returns_value
+ if we got an error_mark_node.
+
+2000-07-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (push_decl_namespace): Push the original namespace.
+
+2000-07-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (instantiate_class_template): Set CLASSTYPE_VBASECLASSES.
+ * semantics.c (begin_class_definition): Clear it.
+
+2000-07-02 Benjamin Chelf <chelf@codesourcery.com>
+
+ * cp-tree.h (genrtl_goto_stmt): Remove declaration.
+ (genrtl_expr_stmt): Likewise.
+ (genrtl_decl_stmt): Likewise.
+ (genrtl_if_stmt): Likewise.
+ (genrtl_while_stmt): Likewise.
+ (genrtl_do_stmt): Likewise.
+ (genrtl_return_stmt): Likewise.
+ (genrtl_for_stmt): Likewise.
+ (genrtl_break_stmt): Likewise.
+ (genrtl_continue_stmt): Likewise.
+ (genrtl_scope_stmt): Likewise.
+ (genrtl_switch_stmt): Likewise.
+ (genrtl_case_label): Likewise.
+ (genrtl_begin_compound_stmt): Likewise.
+ (genrtl_finish_compound_stmt): Likewise.
+ (genrtl_compound_stmt): Likewise.
+ (genrtl_asm_stmt): Likewise.
+
+ * init.c (begin_init_stmts): Remove call to
+ genrtl_begin_compound_stmt.
+ (finish_init_stmts): Remove call to genrtl_finish_compound_stmt.
+
+ * semantics.c (lang_expand_stmt): Changed call to
+ genrtl_compound_stmt to ignore return value.
+
+2000-07-02 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (canonicalize_for_substitution): Return the canonical
+ variant of a type.
+
+ * decl.c (duplicate_decls): Preserve DECL_ORIGINAL_TYPE for a
+ TYPE_DECL.
+ * typeck.c (commonparms): Remove obstack manipulations.
+
+2000-07-01 Benjamin Chelf <chelf@codesourcery.com>
+
+ * Make-lang.in (cc1plus$(exeext)): Added c-semantics.o.
+
+ * Makefile.in (OBJS): Added ../c-semantics.o.
+ (OBJDEPS): Likewise.
+
+ * cp-tree.h (TREE_LANG_FLAG_?): Moved common documentation to
+ ../c-common.h.
+ (struct stmt_tree): Added comment.
+ (current_function_name_declared): Removed.
+ (stmts_are_full_exprs_p): Likewise.
+ (genrtl_do_pushlevel): Likewise.
+ (genrtl_clear_out_block): Likewise.
+ (COMPOUND_STMT_NO_SCOPE): Moved to ../c-common.h.
+ (DECL_ANON_UNION_ELEMS): Likewise.
+ (emit_local_var): Likewise.
+ (make_rtl_for_local_static): Likewise.
+ (do_case): Likewise.
+ (expand_stmt): Likewise.
+ (genrtl_decl_cleanup): Likewise.
+ (c_expand_asm_operands): Likewise.
+ (c_expand_return): Likewise.
+ (c_expand_start_case): Likewise.
+
+ * decl.c (make_rtl_for_local_static): Moved to c-semantics.c.
+ (emit_local_var): Likewise.
+ (initialize_local_var): Change reference to
+ stmts_are_full_exprs_p to call to stmts_are_full_exprs_p().
+ Change reference to stmts_are_full_exprs_p to
+ current_stmt_tree->stmts_are_full_exprs_p.
+ (push_cp_function_context): Likewise.
+
+ * expect.c (expand_throw): Change reference to
+ stmts_are_full_exprs_p.
+
+ * init.c (build_aggr_init): Change reference to
+ stmts_are_full_exprs_p.
+ (build_vec_init): Likewise.
+
+ * optimize.c (maybe_clone_body): Change reference to
+ current_function_name_declared to
+ cp_function_chain->name_declared.
+
+ * pt.c (instantiate_decl): Change reference to
+ current_function_name_declared to
+ cp_function_chain->name_declared.
+
+ * semantics.c (expand_cond): Moved declaration to c-common.h.
+ (genrtl_do_pushlevel): Moved to c-semantics.c.
+ (genrtl_clear_out_block): Likewise.
+ (genrtl_goto_stmt): Likewise.
+ (genrtl_expr_stmt): Likewise.
+ (genrtl_decl_stmt): Likewise.
+ (gerntl_if_stmt): Likewise.
+ (genrtl_while_stmt): Likewise.
+ (genrtl_do_stmt): Likewise.
+ (genrtl_return_stmt): Likewise.
+ (genrtl_for_stmt): Likewise.
+ (genrtl_break_stmt): Likewise.
+ (genrtl_continue_stmt): Likewise.
+ (genrtl_scope_stmt): Likewise.
+ (genrtl_switch_stmt): Likewise.
+ (genrtl_case_label): Likewise.
+ (genrtl_begin_compound_stmt): Likewise.
+ (genrtl_finish_compound_stmt): Likewise.
+ (genrtl_compound_stmt): Likewise.
+ (genrtl_asm_stmt): Likewise.
+ (genrtl_decl_cleanup): Likewise.
+ (expand_cond): Likewise.
+ (expand_stmt): Renamed to ...
+ (lang_expand_stmt): ... this.
+ (lang_expand_expr_stmt): Initialize.
+ (set_current_function_name_declared): Likewise.
+ (stmts_are_full_exprs_p): Likewise.
+ (current_function_name_declared): Likewise.
+ (anon_aggr_type_p): Likewise.
+ (do_poplevel): Change reference to
+ stmts_are_full_exprs_p to call to stmts_are_full_exprs_p().
+ Change reference to stmts_are_full_exprs_p to
+ current_stmt_tree->stmts_are_full_exprs_p.
+ (add_tree): Likewise.
+ (finish_expr_stmt): Likewise.
+ (prep_stmt): Likewise.
+ (lang_expand_stmt): Likewise.
+ (begin_compound_stmt): Change reference to
+ current_function_name_declared to
+ cp_function_chain->name_declared and call to
+ current_function_name_declared().
+ (setup_vtbl_ptr): Likewise.
+ (genrtl_do_poplevel): Removed.
+
+2000-06-30 Jason Merrill <jason@redhat.com>
+
+ * init.c (init_init_processing): Go back to aligning like
+ double_type_node for old ABI.
+ (get_cookie_size): Make cookie larger if we get a type that needs
+ more alignment.
+ (build_vec_delete): Call it.
+
+ * typeck.c (qualify_type_recursive): New fn.
+ (composite_pointer_type): Use it.
+ (build_binary_op): Use composite_pointer_type.
+
+2000-06-24 Carlos O'Ryan <coryan@cs.wustl.edu>
+ Jason Merrill <jason@redhat.com>
+
+ * typeck.c (check_return_expr): Don't complain about returning
+ NULL from operator new if -fcheck-new.
+ * cp-tree.h: Declare flag_check_new here.
+ * init.c: Not here.
+
+2000-06-28 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (find_substitution): Use same_type_p.
+ (write_encoding): Don't check for substitutions.
+
+2000-06-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (expr_no_comma_rangle): New non-terminal.
+ (template_parm): Use it for default parameter case.
+ (template_arg): Use it.
+ (expr_no_commas): Remove commented out undefined extensions.
+ * Makefile.in (CONFLICTS): Adjust to 33 s/r & 48 r/r.
+ * parse.h, parse.c: Rebuilt.
+
+2000-06-30 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (genrtl_asm_stmt): Don't decay input operands here.
+ (finish_asm_stmt): Do it here, instead.
+
+ * cp-tree.h (ridpointers): Don't declare.
+ * decl.c (record_builtin_type): Use CP_RID_MAX instead of RID_MAX.
+ (record_builtin_java_type): Likewise.
+ (init_decl_processing): Likewise.
+ * lex.c: Move inclusion of lex.h.
+ (ridpointers): Don't define.
+ (init_parse): Initialize ripdointers. Use CP_RID_MAX instead of
+ RID_MAX.
+ * lex.h (enum rid): Rename to ...
+ (enum cp_rid): ... this.
+ (ridpointers): Don't declare.
+ * parse.y: Move inclusion of lex.h.
+ * parse.c: Regenerated.
+ * spew.c: Move inclusion of lex.h.
+
+ * cp-tree.h (struct language_function): Remove temp_name_counter.
+ (temp_name_counter): Remove.
+ (get_temp_name): Change prototype.
+ (get_guard): New function.
+ (get_guard_cond): Likewise.
+ (set_guard): Likewise.
+ * cvt.c (build_up_reference): Adjust call to get_temp_name.
+ * decl.c (expand_static_init): Use get_guard and friends to
+ implement guard variables.
+ * decl2.c (get_temp_name): Assume that the variables created are
+ always static.
+ (get_sentry): Rename to ...
+ (get_guard): ... this. Implement new ABI guard variables.
+ (get_guard_bits): New function.
+ (get_guard_cond): Likewise.
+ (set_guard): Likewise.
+ (start_static_initialization_or_destruction): Use them.
+ (do_static_initialization): Replace sentry with guard throughout.
+ (do_static_destruction): Likewise.
+ * init.c (create_temporary_var): Add comment.
+
+2000-06-28 Alex Samuel <samuel@codesourcery.com>
+
+ * mangle.c (find_substitution): Use same_type_p.
+ (write_encoding): Don't check for substitutions.
+
+2000-06-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (expr_no_comma_rangle): New non-terminal.
+ (template_parm): Use it for default parameter case.
+ (template_arg): Use it.
+ (expr_no_commas): Remove commented out undefined extensions.
+ * Makefile.in (CONFLICTS): Adjust to 33 s/r & 48 r/r.
+ * parse.h, parse.c: Rebuilt.
+
+2000-06-29 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (flag_const_strings): Remove.
+ (warn_parentheses): Likewise.
+ (warn_format): Likewise.
+ (common_type): Likewise.
+ (default_conversion): Likewise.
+ (build_binary_op): Likewise.
+ (cp_build_binary_op): New macro.
+ * call.c (build_new_op): Use cp_build_binary_op instead of
+ build_binary_op.
+ * class.c (build_vtable_entry_ref): Likewise.
+ * decl.c (expand_static_init): Likewise.
+ (compute_array_index_type): Likewise.
+ (build_enumerator): Likewise.
+ * decl2.c (delete_sanity): Likewise.
+ (start_static_initialization_or_destruction): Likewise.
+ * error.c (dump_type_suffix): Likewise.
+ * init.c (resolve_offset_ref): Likewise.
+ (build_new): Likewise.
+ (build_new_1): Likewise.
+ (build_vec_delete_1): Likewise.
+ (build_vec_init): Likewise.
+ (build_delete): Likewise.
+ * rtti.c (synthesize_tinfo_fn): Likewise.
+ (synthesize_tinfo_var): Likewise.
+ * search.c (expand_upcast_fixups): Likewise.
+ (fixup_all_virtual_upcast_offsets): Likewise.
+ * typeck.c (build_array_ref): Likewise.
+ (get_member_function_from_ptrfunc): Likewise.
+ (build_binary_op): Add parameter.
+ (pointer_int_sum): Use cp_build_binary_op.
+ (pointer_diff): Likewise.
+ (build_modify_expr): Likewise.
+ (get_delta_difference): Likewise.
+ (build_ptrmemfunc): Likewise.
+
+2000-06-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (SET_DECL_ARTIFICIAL): Remove.
+ * decl.c (create_implicit_typedef): Adjust.
+ * decl2.c (build_artificial_parm): Adjust.
+ * method.c (implicitly_declare_fn): Adjust.
+ * pt.c (push_inline_template_parms_recursive): Adjust.
+ (process_template_parm): Adjust.
+ (overloaded_template_name): Adjust.
+ * semantics.c (finish_template_template_parm): Adjust.
+
+2000-06-28 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLEAR_BINFO_NEW_VTABLE_MARKED): Remove.
+ * class.c (update_vtable_entry_for_fn): Correct logic for deciding
+ where to emit thunks.
+ (build_vtt): Adjust call to build_vtt_inits.
+ (build_vtt_inits): Add parameter to indicate whether or not
+ sub-VTTs for virtual bases should be included. Adjust handling of
+ construction vtables.
+ (get_matching_base): New function.
+ (dfs_build_vtt_inits): Rename to ...
+ (dfs_build_secondary_vptr_vtt_inits): Adjust handling of
+ construction vtables.
+ (dfs_fixup_binfo_vtbls): Likewise.
+ (build_ctor_vtbl_groups): Build construction vtables for virtual
+ bases, too.
+ (accumulate_vtbl_inits): Tweak logic for deciding whether or not
+ to build construction vtbls.
+ (dfs_accumulate_vtbl_inits): Adjust handling of
+ construction vtables.
+
+ * pt.c (tsubst, case TEMPLATE_TEMPLATE_PARM): Handle cv-qualified
+ types correctly.
+
+2000-06-27 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokfndecl): Set DECL_CONTEXT for static functions too.
+
+2000-06-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * search.c (hides): Remove.
+ (is_subobject_of_p): Add most_derived parameter. Use
+ CANONICAL_BINFO.
+ (lookup_field_queue_p): Adjust.
+ (lookup_field_r): Adjust.
+
+2000-06-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (handle_class_head): Bash typedefs to the type's main
+ decl.
+
+2000-06-25 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (genrtl_begin_stmt_expr): Rename to ...
+ (begin_global_stmt_expr): ... this.
+ (genrtl_finish_stmt_expr): Rename to ...
+ (finish_global_stmt_expr): ... this.
+ * init.c (begin_init_stmts): Adjust calls.
+ (finish_init_stmts): Likewise.
+ * semantics.c (genrtl_begin_stmt_expr): Rename to ...
+ (begin_global_stmt_expr): ... this.
+ (genrtl_finish_stmt_expr): Rename to ...
+ (finish_global_stmt_expr): ... this.
+
+2000-06-25 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * search.c (lookup_member): Fix typo in comment.
+
+2000-06-24 Jason Merrill <jason@redhat.com>
+
+ * decl.c (pushdecl): Don't set DECL_CONTEXT from current_namespace.
+ (push_namespace): Set DECL_CONTEXT for a new NAMESPACE_DECL.
+
+2000-06-24 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * parse.y (complex_direct_notype_declarator): Support global_scope.
+ * Makefile.in: Adjust conflict count.
+
+2000-06-23 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu>
+
+ * parse.y (template_arg): Convert TEMPLATE_DECL
+ that is a template template parameter to
+ TEMPLATE_TEMPLATE_PARM here.
+
+ * cp-tree.def (TEMPLATE_TEMPLATE_PARM): Adjust comment.
+ * cp-tree.h (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL): New macro.
+ (copy_template_template_parm): Adjust prototype.
+ * decl.c (grokdeclarator): Remove dead code.
+ * pt.c (process_template_parm): Tidy.
+ (lookup_template_class): Construct nodes in
+ copy_template_template_parm.
+ (tsubst): Pass TEMPLATE_DECL rather than IDENTIFIER_NODE to
+ lookup_template_class. Use TYPE_TI_TEMPLATE.
+ * tree.c (copy_template_template_parm): Add NEWARGS
+ parameter.
+ (mapcar): Adjust call to copy_template_template_parm.
+ * typeck.c (comptypes): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL.
+ * method.c (build_template_template_parm_names): Change error
+ code to avoid compilation warning.
+
+ * gxxint.texi: Document template template parameter
+ name mangling.
+
+2000-06-21 Alex Samuel <samuel@codesourcery.com>
+
+ * Make-lang.in (CXX_LIB2FUNCS): Add cp-demangle.o and dyn-string.o.
+ (CXX_LIB2SRCS): Add cp-demangle.c and dyn-string.c.
+ (cp-demangle.o): New rule.
+ (dyn-string.o): Likewise.
+ * inc/cxxabi.h (__cxa_demangle): New declaration.
+
+2000-06-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BV_USE_VCALL_INDEX_P): New macro.
+ (BV_GENERATE_THUNK_WITH_VTABLE_P): Likewise.
+ (lang_decl_flags): Add generate_with_vtable_p. Make vcall_offset
+ a tree, not an int.
+ (THUNK_GENERATE_WITH_VTABLE_P): New macro.
+ (make_thunk): Change prototype.
+ (emit_thunk): Rename to use_thunk.
+ (mangle_thunk): Change prototype.
+ * class.c (get_derived_offset): Simplify.
+ (copy_virtuals): Clear BV_USE_VCALL_INDEX_P and
+ BV_GENERATE_THUNK_WITH_VTABLE_P.
+ (build_primary_vtable): Simplify.
+ (add_virtual_function): Use BV_FN, rather than TREE_VALUE.
+ (dfs_find_base): Remove.
+ (update_vtable_entry_for_fn): Correct bug in finding the base
+ where a virtual function was first declared. Figure out whether
+ or not to emit a vcall-thunk with the vtables in which it appears.
+ Correct logic for deciding whether to use an ordinary thunk, or a
+ vcall thunk.
+ (finish_struct_1): Remove unnecssary code.
+ (build_vtbl_initializer): Use ssize_int for the running counter of
+ negative indices.
+ (build_vtbl_initializer): Only use vcall thunks where necessary.
+ Mark thunks as needing to be emitted with their vtables, or not.
+ (build_vbase_offset_vtbl_entries): Adjust for use of ssize_int in
+ indices. Use size_binop.
+ (dfs_build_vcall_offset_vtbl_entries): Don't rely on
+ BINFO_PRIMARY_MARKED_P here. Use BV_FN consistently. Use
+ size_binop.
+ (build_rtti_vtbl_entries): Adjust call to build_vtable_entry.
+ (build_vtable_entry): Mark thunks as needing to be emitted with
+ their vtables, or not.
+ * decl.c (lang_mark_tree): Mark the vcall_offset in a thunk.
+ * decl2.c (mark_vtable_entries): Use use_thunk instead of
+ emit_thunk.
+ * dump.c (dequeue_and_dump): Remove dead code. Dump new thunk
+ information.
+ * error.c (dump_expr): Use BV_FN.
+ * mangle.c (mangle_thunk): Adjust now that vcall_offset is a tree,
+ not an int.
+ * method.c (make_thunk): Likewise.
+ (emit_thunk): Rename to use_thunk. Allow callers to decide
+ whether or not to actually emit the thunk. Adjust for changes in
+ representation of vcall offsets.
+ * search.c (dfs_get_pure_virtuals): Use BV_FN.
+ * semantics.c (emit_associated_thunks): New function.
+ (expand_body): Use it.
+ * ir.texi: Adjust descriptions of thunks.
+
+2000-06-22 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_decl, case FUNCTION_DECL): Clear DECL_SAVED_TREE.
+ (tsubst_friend_function): Copy it here.
+
+ * decl.c (grok_op_properties): Fix typo.
+
+ * decl2.c (delete_sanity): Clarify warning, avoid failure on
+ deleting void*.
+
+ * pt.c (check_explicit_specialization): Clarify error.
+
+ * decl.c (pushdecl): Also pull out one of the FUNCTION_DECLs from
+ an old OVERLOAD when we're declaring a non-function.
+ (pushdecl, destroy_local_var): Check for error_mark_node.
+ (warn_extern_redeclared_static): Also bail early if
+ we're a CONST_DECL.
+ (push_overloaded_decl): Ignore an old error_mark_node.
+
+2000-06-22 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_x_va_arg): Check if in a template decl.
+ * pt.c (tsubst_copy, case VA_ARG_EXPR): Use build_x_va_arg.
+
+2000-06-20 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (push_lang_context): TYPE_NAME gets you to the Java
+ types DECLs.
+ * decl.c (check_goto): Computed gotos assumed OK.
+
+2000-06-20 Jason Merrill <jason@redhat.com>
+
+ * pt.c (tsubst_decl, case TYPE_DECL): Fix test for TYPE_DECLs
+ for which we don't need to look for instantiations.
+
+2000-06-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * parse.y (program): Always call finish_translation_unit.
+ * parse.c, parse.h: Rebuilt.
+
+2000-06-20 Zack Weinberg <zack@wolery.cumb.org>
+
+ * method.c: Don't include hard-reg-set.h.
+
+2000-06-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (get_base_offset): Cope when vbase field is in a base.
+
+2000-06-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (build_conditional_expr): Use VOID_TYPE_P.
+ * cvt.c (cp_convert_to_pointer): Likewise.
+ (convert_to_void): Likewise.
+ * error.c (dump_expr): Likewise.
+ * except.c (complete_ptr_ref_or_void_ptr_p): Likewise.
+ * init.c (build_delete): Likewise.
+ * method.c (emit_thunk): Likewise.
+ * optmize.c (declare_return_variable): Likewise.
+ * rtti.c (get_tinfo_decl_dynamic): Likewise.
+ (get_typeid): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ * typeck.c (composite_pointer_type): Likewise.
+ (common_type): Likewise.
+ (build_indirect_ref): Likewise.
+ (build_binary_op): Likewise.
+ (build_x_compound_expr): Likewise.
+ (check_return_expr): Likewise.
+ * typeck2.c (add_exception_specifier): Likewise.
+
+ * mangle.c (write_method_parms): Use direct comparison for end
+ of parmlist.
+
+2000-06-19 Benjamin Chelf <chelf@codesourcery.com>
+
+ * cp-tree.h (genrtl_try_block): Declare function.
+ (genrtl_handler): Likewise.
+ (genrtl_catch_block): Likewise.
+ (genrtl_ctor_stmt): Likewise.
+ (genrtl_subobject): Likewise.
+ (genrtl_decl_cleanup): Likewise.
+ (genrtl_do_poplevel): Likewise.
+ (genrtl_do_pushlevel): Likewise.
+ (genrtl_clear_out_block): Likewise.
+ (genrtl_goto_stmt): Likewise.
+ (genrtl_expr_stmt): Likewise.
+ (genrtl_decl_stmt): Likewise.
+ (genrtl_if_stmt): Likewise.
+ (genrtl_while_stmt): Likewise.
+ (genrtl_do_stmt): Likewise.
+ (genrtl_return_stmt): Likewise.
+ (genrtl_for_stmt): Likewise.
+ (genrtl_break_stmt): Likewise.
+ (genrtl_continue_stmt): Likewise.
+ (genrtl_scope_stmt): Likewise.
+ (genrtl_switch_stmt): Likewise.
+ (genrtl_case_label): Likewise.
+ (genrtl_begin_compound_stmt): Likewise.
+ (genrtl_finish_compound_stmt): Likewise.
+ (genrtl_compound_stmt): Likewise.
+ (genrtl_asm_stmt): Likewise.
+ (genrtl_named_return_value): Likewise.
+ (genrtl_begin_stmt_expr): Likewise.
+ (genrtl_finish_stmt_expr): Likewise.
+ (finish_for_stmt): Removed first argument.
+ (finish_switch_stmt): Likewise.
+
+ * semantics.c (genrtl_try_block): Define function.
+ (genrtl_handler): Likewise.
+ (genrtl_catch_block): Likewise.
+ (genrtl_ctor_stmt): Likewise.
+ (genrtl_subobject): Likewise.
+ (genrtl_decl_cleanup): Likewise.
+ (genrtl_do_poplevel): Likewise.
+ (genrtl_do_pushlevel): Likewise.
+ (genrtl_clear_out_block): Likewise.
+ (genrtl_goto_stmt): Likewise.
+ (genrtl_expr_stmt): Likewise.
+ (genrtl_decl_stmt): Likewise.
+ (genrtl_if_stmt): Likewise.
+ (genrtl_while_stmt): Likewise.
+ (genrtl_do_stmt): Likewise.
+ (genrtl_return_stmt): Likewise.
+ (genrtl_for_stmt): Likewise.
+ (genrtl_break_stmt): Likewise.
+ (genrtl_continue_stmt): Likewise.
+ (genrtl_scope_stmt): Likewise.
+ (genrtl_switch_stmt): Likewise.
+ (genrtl_case_label): Likewise.
+ (genrtl_begin_compound_stmt): Likewise.
+ (genrtl_finish_compound_stmt): Likewise.
+ (genrtl_compound_stmt): Likewise.
+ (genrtl_asm_stmt): Likewise.
+ (genrtl_named_return_value): Likewise.
+ (genrtl_begin_stmt_expr): Likewise.
+ (genrtl_finish_stmt_expr): Likewise.
+ (finish_for_stmt): Removed first argument and generate rtl
+ specific code.
+ (finish_switch_stmt): Likewise.
+ (do_poplevel): Removed generate rtl specific code.
+ (do_pushlevel): Likewise.
+ (add_tree): Likewise.
+ (finish_goto_stmt): Likewise.
+ (finish_expr_stmt): Likewise.
+ (begin_if_stmt): Likewise.
+ (finish_if_stmt_cond): Likewise.
+ (finish_then_clause): Likewise.
+ (begin_else_clause): Likewise.
+ (finish_else_clause): Likewise.
+ (finish_if_stmt): Likewise.
+ (clear_out_block): Likewise.
+ (begin_while_stmt): Likewise.
+ (finish_while_stmt_cond): Likewise.
+ (finish_while_stmt): Likewise.
+ (begin_do_stmt): Likewise.
+ (finish_do_body): Likewise.
+ (finish_do_stmt): Likewise.
+ (finish_return_stmt): Likewise.
+ (begin_for_stmt): Likewise.
+ (finish_for_init_stmt): Likewise.
+ (finish_for_cond): Likewise.
+ (finish_for_expr): Likewise.
+ (finish_break_stmt): Likewise.
+ (finish_continue_stmt): Likewise.
+ (begin_switch_stmt): Likewise.
+ (finish_switch_cond): Likewise.
+ (finish_case_label): Likewise.
+ (begin_try_block): Likewise.
+ (begin_function_try_block): Likewise.
+ (finish_try_block): Likewise.
+ (finish_cleanup_try_block): Likewise.
+ (finish_cleanup): Likewise.
+ (finish_function_try_block): Likewise.
+ (finish_handler_sequence): Likewise.
+ (finish_function_handler_sequence): Likewise.
+ (begin_handler): Likewise.
+ (finish_handler_parms): Likewise.
+ (begin_catch_block): Likewise.
+ (finish_handler): Likewise.
+ (begin_compound_stmt): Likewise.
+ (finish_compound_stmt): Likewise.
+ (finish_asm_stmt): Likewise.
+ (finish_label_stmt): Likewise.
+ (finish_label_decl): Likewise.
+ (finish_subobject): Likewise.
+ (finish_decl_cleanup): Likewise.
+ (finish_named_return_value): Likewise.
+ (begin_stmt_expr): Likewise.
+ (finish_stmt_expr): Likewise.
+
+ * decl.c (initialize_local_var): Changed call to finish_expr_stmt
+ to call genrtl_expr_stmt when appropriate.
+
+ * init.c (begin_init_stmts): Changed calls to begin_stmt_expr and
+ begin_compound_expr to call genrtl_begin_stmt_expr and
+ genrtl_begin_compound_expr when appropriate.
+ (finish_init_stmts): Changed calls to finish_compound_expr and
+ finish_stmt_expr to call genrtl_finish_compound_expr and
+ genrtl_finish_stmt_expr when appropriate.
+ (expand_default_init): Changed call to finish_expr_stmt to call
+ genrtl_expr_stmt when appropriate.
+ (build_vec_init): Likewise.
+
+ * parse.y (simple_stmt): Removed first argument from call to
+ finish_for_stmt. Removed first argument from call to
+ finish_switch_stmt.
+
+ * parse.c: Regenerated.
+
+ * pt.c (tsubst_expr): Removed first argument from call to
+ finish_for_stmt. Removed first argument from call to
+ finish_switch_stmt.
+
+2000-06-16 Benjamin Chelf <chelf@codesourcery.com>
+
+ * cp-tree.h (enum cplus_tree_code): Changed __DUMMY to
+ CP_DUMMY_TREE_CODE. Remove #include "c-common.def".
+
+ * lex.c (cplus_tree_code_type[]): Removed #include "c-common.def".
+ (cplus_tree_code_length[]): Likewise.
+ (cplus_tree_code_name[]): Likewise.
+ (init_parse): Added call to add_c_tree_codes. Changed
+ LAST_AND_UNUSED_TREE_CODE to LAST_C_TREE_CODE.
+
+2000-06-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (finish_mem_initializers): Declare.
+ (count_trees): Likewise.
+ * parse.y (base_init): Use finish_mem_initializers.
+ * semantics.c (finish_mem_initializers): New function.
+
+ * tree.c (count_trees_r): Prototype. Use DATA parameter to store
+ the number of trees.
+ (n_trees): Remove.
+ (count_trees): Don't use it.
+
+2000-06-15 Jason Merrill <jason@redhat.com>
+
+ * tree.c (count_trees): New debugging function.
+
+ * typeck.c (build_x_function_call): Use DECL_FUNCTION_TEMPLATE_P.
+ * init.c (build_member_call): Pull out the name of a DECL.
+
+ * Makefile.in (semantics.o, pt.o): Depend on TIMEVAR_H.
+ * semantics.c (expand_body): Push to TV_INTEGRATION here.
+ * optimize.c (optimize_function): Not here.
+ * pt.c (instantiate_decl): Push to TV_PARSE.
+
+2000-06-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct language_function): Remove x_base_init_list
+ and x_member_init_list.
+ (current_base_init_list): Remove.
+ (current_member_init_list): Likewise.
+ (setup_vtbl_ptr): Change prototype.
+ (emit_base_init): Likewise.
+ (expand_member_init): Likewise.
+ (reinit_parse_for_function): Remove.
+ * decl.c (save_function_data): Don't clear x_base_init_list and
+ x_member_init_list.
+ (mark_language_function): Don't mark them.
+ * init.c (perform_member_init): Tweak comment.
+ (sort_member_init): Take the list of initializers as an argument.
+ (sort_base_init): Likewise.
+ (emit_base_init): Likewise.
+ (expand_member_init): Return the initializer. Don't use global
+ variables.
+ * lex.c (reinit_parse_for_function): Remove.
+ * method.c (build_template_parm_names): Correct substitution.
+ (do_build_copy_constructor): Don't use current_member_init_list
+ and current_base_init_list.
+ (synthesize_method): Likewise.
+ * parse.y (base_init): Split mem-initializers into
+ base-initializers and field-initializers.
+ (member_init_list): Build up the list here.
+ (member_init): Return the initializer.
+ (fn.depfn): Don't use reinit_parse_for_function.
+ * parse.c: Regenerated.
+ * pt.c (convert_nontype_argument): Don't make an ADDR_EXPR of the
+ ERROR_MARK.
+ (tsubst_expr): Don't use current_member_init_list
+ and current_base_init_list.
+ (tsubst_expr_values): Rename to ...
+ (tsubst_initializer_list): ... this. Use convert_from_reference.
+ * semantics.c (setup_vtbl_ptr): Don't use current_member_init_list
+ and current_base_init_list.
+ (begin_function_definition): Don't call reinit_parse_for_function.
+
+ * dump.c (dequeue_and_dump): Use TREE_VEC_LENGTH with vectors.
+
+ * error.c (dump_expr): Handle ADDR_EXPRs with REFERENCE_TYPE
+ correctly.
+
+ * cp-tree.h (DECL_PENDING_INLINE_P): Relax checking.
+
+2000-06-14 Benjamin Chelf <chelf@codesourcery.com>
+
+ * cp-tree.h (IF_COND): Move to c-common.h.
+ (THEN_CLAUSE): Likewise.
+ (ELSE_CLAUSE): Likewise.
+ (WHILE_COND): Likewise.
+ (WHILE_BODY): Likewise.
+ (DO_COND): Likewise.
+ (DO_BODY): Likewise.
+ (RETURN_EXPR): Likewise.
+ (EXPR_STMT_EXPR): Likewise.
+ (FOR_INIT_STMT): Likewise.
+ (FOR_COND): Likewise.
+ (FOR_EXPR): Likewise.
+ (FOR_BODY): Likewise.
+ (SWITCH_COND): Likewise.
+ (SWITCH_BODY): Likewise.
+ (CASE_LOW): Likewise.
+ (CASE_HIGH): Likewise.
+ (GOTO_DESTINATION): Likewise.
+ (COMPOUND_BODY): Likewise.
+ (ASM_CV_QUAL): Likewise.
+ (ASM_STRING): Likewise.
+ (ASM_OUTPUTS): Likewise.
+ (ASM_INPUTS): Likewise.
+ (ASM_CLOBBERS): Likewise.
+ (DECL_STMT_DECL): Likewise.
+ (STMT_EXPR_STMT): Likewise.
+ (LABEL_STMT_LABEL): Likewise.
+ (SCOPE_BEGIN_P): Likewise.
+ (SCOPE_END_P): Likewise.
+ (SCOPE_STMT_BLOCK): Likewise.
+ (SCOPE_NULLIFIED_P): Likewise.
+ (SCOPE_NO_CLEANUPS_P): Likewise.
+ (SCOPE_PARTIAL_P): Likewise.
+ (ASM_VOLATILE_P): Likewise.
+ (STMT_LINENO): Likewise.
+ (STMT_LINENO_FOR_FN_P): Likewise.
+
+ * cp-tree.def: Removed SRCLOC, SIZEOF_EXPR, ARROW_EXPR,
+ ALIGNOF_EXPR, EXPR_STMT, COMPOUND_STMT, DECL_STMT, IF_STMT,
+ FOR_STMT, WHILE_STMT, DO_STMT, RETURN_STMT, BREAK_STMT,
+ CONTINUE_STMT, SWITCH_STMT, GOTO_STMT, LABEL_STMT, ASM_STMT,
+ SCOPE_STMT, CASE_LABEL, STMT_EXPR.
+
+ * Makefile.in (CXX_TREE_H): Added $(srcdir)/../c-common.def.
+
+ * Make-lang.in (CXX_SRCS): Added $(srcdir)/c-common.def.
+ (cc1plus$(exeext)): Added $(srcdir)/c-common.def.
+
+ * lex.c (cplus_tree_code_type[]): Added '#include "c-common.def"'.
+ (cplus_tree_code_length[]): Added '#include "c-common.def"'.
+ (cplus_tree_code_name[]): Added '#include "c-common.def"'.
+
+2000-06-14 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BINFO_OVERRIDE_ALONG_VIRTUAL_PATH): New macro.
+ * class.c (dfs_find_final_overrider): Set it appropriately.
+ (dfs_built_vtt_inits): Check BINFO_OVERRIDE_ALONG_VIRTUAL_PATH to
+ avoid unneeded secondary vptrs.
+
+2000-06-13 Jakub Jelinek <jakub@redhat.com>
+
+ * class.c (build_secondary_vtable): Set DECL_USER_ALIGN.
+ (check_bitfield_decl, check_field_decl): Likewise.
+ (build_vtbl_or_vbase_field, build_base_field): Likewise.
+ (layout_class_type): Set DECL_USER_ALIGN resp. CLASSTYPE_USER_ALIGN.
+ * decl.c (record_unknown_type): Set TYPE_USER_ALIGN.
+ (xfer_tag, finish_enum): Likewise.
+ * decl2.c (finish_builtin_type): Likewise.
+ * init.c (init_init_processing): Likewise.
+ * pt.c (instantiate_class_template): Likewise.
+ * rtti.c (get_tinfo_decl, synthesize_tinfo_fn): Set DECL_USER_ALIGN.
+ * cp-tree.h (struct lang_type): Add user_align member.
+ (CLASSTYPE_USER_ALIGN): Define.
+
+2000-06-13 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
+
+ * Make-lang.in (c++.install-common): Install g++-cross in
+ $(gcc_tooldir)/bin as g++ and c++; g++ in $(bindir) as
+ $(target_alias)-g++ and $(target_alias)-c++.
+
+2000-06-12 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (vcall_offset_data_s): Add last_init and fns.
+ (overrides): Rename to same_signature_p.
+ (dfs_find_final_overrider): Adjust accordingly.
+ (mark_overriders): Likewise.
+ (warn_hidden): Likewise.
+ (build_vtbl_initializer): Reorganize machinery for building things
+ at negative offsets.
+ (build_vcall_and_vbase_vtbl_entries): Likewise.
+ (build_vbase_offset_vtbl_entries): Likewise.
+ (dfs_build_vcall_offset_vtbl_entries): Correct order of vcall
+ offset entries. Do not create two entries for functions with the
+ same signature.
+ (build_vcall_offset_vtbl_entries): Initialize vod->fns.
+ (build_rtti_vtbl_entries): Reorganize machinery for building things
+ at negative offsets.
+
+ * optimize.c (expand_call_inline): Don't recurse into the code
+ used to initialize the parameters more than once.
+
+2000-06-11 Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (NESTED_TEMPLATE_MATCH): Fix typo in comment.
+ (is_std_substitution): Don't check CLASSTYPE_USE_TEMPLATE here.
+ (find_substitution): Only use the `Sa' substitution for
+ std::allocator, not instantiations of it.
+ (write_template_prefix): Move comment. Only use a TREE_LIST to
+ represent substitutions for a member template.
+ (write_array_type): Mangle array dimensions correctly.
+ * optimize.c (maybe_clone_body): Copy more information from the
+ cloned function.
+ * pt.c (regenerate_decl_from_template): Preserve DECL_USE_TEMPLATE
+ on the regenerated declaration.
+
+2000-06-11 Chip Salzenberg <chip@valinux.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtable): Clarify comment.
+ (build_ctor_vtbl_group): Pass the most derived type to
+ build_vtable.
+
+2000-06-11 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (compare_options): Don't needlessly cast away const-ness.
+
+2000-06-10 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (add_binding): Handle duplicate declarations of external
+ variables.
+
+2000-06-09 Chip Salzenberg <chip@valinux.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * mangle.c (write_number): Take an unsigned HOST_WIDE_INT as an
+ argument.
+ (write_signed_number): New macro.
+ (write_unsigned_number): Likewise.
+ (write_source_name): Use them.
+ (write_number): Handle signed and unsigned values.
+ (write_integer_cst): Use tree_int_cst_sgn, and use
+ write_unsigned_number or write_signed_number as appropriate.
+ (write_discriminator): Use write_unsigned_number or
+ write_signed_number as appropriate.
+ (write_template_arg_literal): Likewise.
+ (write_array_type): Use tree_low_cst.
+ (write_template_parm): Use write_unsigned_number or
+ write_signed_number as appropriate.
+ (write_substitution): Adjust call to write_number.
+ (write_type): Get the TYPE_MAIN_VARIANT before mangling it.
+ (write_expression): Handle non-type template arguments of
+ reference type correctly.
+ (mangle_thunk): Use write_signed_number.
+
+2000-06-09 Chip Salzenberg <chip@valinux.com>
+
+ * mangle.c (find_substition): Don't mangle objects with typename
+ substitutions (e.g. "cin" as "Si").
+
+2000-06-09 Zack Weinberg <zack@wolery.cumb.org>
+
+ * call.c (add_candidate): Use ggc_alloc_cleared.
+ * decl.c (lookup_label): Likewise.
+ * lex.c (retrofit_lang_decl): Likewise.
+
+2000-06-09 Jason Merrill <jason@casey.soma.redhat.com>
+
+ * semantics.c (expand_body): Push to TV_EXPAND.
+ * optimize.c (optimize_function): Push to TV_INTEGRATION.
+ * decl.c (start_function): Always call announce_function.
+
+ * tinfo2.cc: Just declare abort.
+
+2000-06-09 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c (DEF_OPERATOR): Say `operator@' -not- `operator @'
+ whenever @ is a symbolic name.
+
+2000-06-08 Jakub Jelinek <jakub@redhat.com>
+
+ * method.c (make_thunk): Clear DECL_VTT_PARM in thunk.
+
+2000-06-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (pushdecl): Look up functions by DECL_NAME, not
+ DECL_ASSEMBLER_NAME.
+
+2000-06-06 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (c_language): Define.
+
+2000-06-06 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c (lang_init_options): Tweak.
+
+ * decl2.c: Remove #inclusion of diagnostic.h
+ (lang_decode_option): Move diagnostic formatting options to
+ toplevel.
+
+ * lang-options.h: Remove documentation for diagnostic options.
+
+ * Makefile.in (lex.o): Depends upon diagnostic.h
+
+2000-06-06 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (redeclaration_error_message): If two TEMPLATE_DECLs have
+ the same DECL_RESULT, it's not a redefinition.
+ * pt.c (tsubst_decl): Remove code to handle illegal
+ specializations.
+
+2000-06-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * exception.cc: (__eh_alloc, __eh_free): Moved to libgcc2.c
+
+2000-06-05 Jason Merrill <jason@casey.soma.redhat.com>
+
+ * search.c (maybe_suppress_debug_info): Don't check
+ CLASSTYPE_INTERFACE_ONLY if CLASSTYPE_INTERFACE_KNOWN isn't set.
+
+ * pt.c (mark_decl_instantiated): Do SET_DECL_EXPLICIT_INSTANTIATION
+ here if extern_p.
+
+ Remember instantiation context in deferred instantiations.
+ * cp-tree.h (struct tinst_level): Remove.
+ (TINST_DECL, TINST_LINE, TINST_FILE): New macros.
+ * pt.c (current_tinst_level): Now a tree.
+ (print_template_context, push_tinst_level, pop_tinst_level,
+ tinst_for_decl): Adjust.
+ (reopen_tinst_level): New fn.
+ (init_pt): Register current_tinst_level as a root.
+ (add_pending_template): Put current_tinst_level in TREE_PURPOSE
+ of the pending templates list.
+ (instantiate_pending_templates): Adjust. Call reopen_tinst_level.
+ * lex.c (extract_interface_info): Adjust.
+ * decl2.c (warn_if_unknown_interface): Adjust.
+
+2000-06-05 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (indirect_primary_base_p): New function.
+ (determine_primary_base): Use it.
+
+2000-06-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ Update new-abi dynamic cast algorithm.
+ * tinfo.cc (__class_type_info::__dyncast_result): Add
+ whole_details. Adjust constructor.
+ (__vmi_class_type_info::__do_dyncast): Adjust for vmi_flags.
+ Avoid unnecessary searching.
+ (__dynamic_cast): Adjust for __dyncast_result::whole_details.
+
+2000-06-05 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (init_decl_processing): Don't call record_component_aliases.
+ * tree.c (build_cplus_array_type_1): Likewise.
+
+2000-06-04 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi: Correct typo.
+ * mangle.c (write_expression): Handle non-type template arguments
+ with reference type.
+ * method.c (build_overload_value): Likewise.
+ * pt.c (convert_nontype_argument): Explicitly represent conversion
+ to a reference with an ADDR_EXPR.
+ (unify): Always unify arguments in left-to-right order.
+
+2000-06-03 Alex Samuel <samuel@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (CXX_SRCS): Add mangle.c.
+ * Makefile.in (CXX_OBJS): Add mangle.o.
+ (mangle.o): New rule.
+
+ * class.c (local_classes): New variable.
+ * class.c (get_vtable_name): Use mangle_vtable_for_type for new ABI.
+ (get_vtt_name): Use mangle_vtt_name for new ABI.
+ (init_class_processing): Initialize local_classes.
+ (build_ctor_vtbl_group): Use mangle_ctor_vtbl_for_type for new ABI.
+ * cp-tree.h (cp_tree_index): Add CPTI_STD_IDENTIFIER.
+ (std_identifier): New macro.
+ (DECL_VOLATILE_MEMFUNC_P): New macro.
+ (DECL_NAMESPACE_STD_P): Likewise.
+ (local_classes): Declare.
+ (get_mostly_instantiated_function_type): Declare.
+ (init_mangle): Declare.
+ (mangle_decl): Likewise.
+ (mangle_type_string): Likewise.
+ (mangle_type): Likewise.
+ (mangle_typeinfo_for_type): Likewise.
+ (mangle_typeinfo_string_for_type): Likewise.
+ (mangle_vtbl_for_type): Likewise.
+ (mangle_vtt_for_type): Likewise.
+ (mangle_ctor_vtbl_for_type): Likewise.
+ (mangle_thunk): Likewise.
+ (mangle_conv_op_name_for_type): Likewise.
+ (mangle_guard_variable): Likewise.
+ * decl.c (pushtag): Keep track of local classes.
+ (initialize_predefined_identifiers): Initialize std_identifier.
+ (init_decl_processing): Use std_identifier.
+ (start_decl): Don't treat instantiations as specializations.
+ (grokdeclarator): Likewise.
+ (grokvardecl): Call mangle_decl for new ABI. Only set mangled
+ name for fully-instantiated templates.
+ * decl2.c (grokclassfn): Use set_mangled_name_for_decl for
+ destructors with the new ABI.
+ (finish_static_data_member_decl): Use mangle_decl under the new ABI.
+ (grokfield): Use mangle_type for new ABI.
+ (grokoptypename): Use mangle_conv_op_for_type for new ABI.
+ (get_sentry): Use mangle_guard_variable for new ABI.
+ (start_static_initialization_or_destruction): Likewise.
+ * expr.c (extract_aggr_init): Remove.
+ (extract_scalar_init): Likewise.
+ (extract_init): Remove #if 0'd code.
+ * mangle.c: New function.
+ * method.c (build_mangled_name): Assert not flag_new_abi.
+ (build_static_name): Likewise.
+ (build_decl_overload_real): Likewise.
+ (build_typename_overload): Likewise.
+ (build_overload_with_type): Likewise.
+ (build_overload_name): Likewise.
+ (get_ctor_vtbl_name): Likewise.
+ (start_squangling): Likewise.
+ (get_id_2): Likewise.
+ (set_mangled_name_for_decl): Call mangle_decl for new ABI.
+ (init_method): Call init_mangle for new ABI.
+ (make_thunk): Call mangle_thunk for new ABI.
+ * operators.def: Correct new ABI manglings for the `%' operator.
+ Add `::' operator.
+ * pt.c (build_template_decl): Copy DECL_OVERLOADED_OPERATOR_P and
+ DECL_ASSIGNMENT_OPERATOR_P to the TEMPLATE_DECL.
+ (lookup_template_class): Call mangle_decl for new ABI.
+ (get_mostly_instantiated_function_type): New function.
+ (set_mangled_name_for_template_decl): Use it.
+ (tsubst_decl): Use set_mangled_name_for_decl for destructors with
+ the new ABI. Use mangle_conv_op_name_for_type for instantiated
+ conversion op names.
+ * rtti.c (tinfo_name): Call mangle_type_string for new ABI.
+ (get_tinfo_decl): Call mangle_typeinfo_for_type for new ABI.
+ (tinfo_base_init): Likewise. Mangle typeinfo string name with
+ mangle_typeinfo_string_for_type.
+
+2000-06-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TMPL_ARGS_LEVEL): Clarify comment.
+ (INNERMOST_TEMPLATE_ARGS): New macro.
+ (innermost_args): Remove.
+ (get_innermost_template_args): New function.
+ * decl2.c (arg_assoc_class): Use INNERMOST_TEMPLATE_ARGS.
+ * error.c (dump_function_decl): Be caution when using
+ most_general_template.
+ * method.c (build_template_parm_names): Use
+ INNERMOST_TEMPLATE_ARGS.
+ * pt.c (add_to_template_args): Tidy comment
+ (get_innermost_template_args): New function.
+ (check_explicit_specialization): Clear DECL_INITIAL for a new
+ specialization.
+ (process_partial_specialization): Use INNERMOST_TEMPLATE_ARGS.
+ Tidy.
+ (push_template_decl): Always register specializations of the most
+ general template.
+ (convert_template_argument): Use INNERMOST_TEMPLATE_ARGS.
+ (coerce_template_parms): Likewise.
+ (lookup_template_class): Likewise.
+ (innermost_args): Remove.
+ (tsubst_decl): Use INNERMOST_TEMPLATE_ARGS.
+ (tsubst_decl): Handle tricky specializations. Use
+ get_innermost_template_args.
+ (instantiate_template): Simplify handling of partial
+ instantiations.
+ (get_class_bindings): Use INNERMOST_TEMPLATE_ARGS.
+ (most_general_template): Reimplement, in a more straightforward
+ manner.
+ (regenerate_decl_from_template): Tweak formatting. Use
+ TMPL_ARGS_DEPTH for clarity.
+ (set_mangled_name_for_template_decl): Use INNERMOST_ARGS.
+
+ * dump.c (dequeue_and_dump): Dump information about thunks.
+
+2000-06-01 Richard Henderson <rth@cygnus.com>
+
+ * decl.c (init_decl_processing): Set lang_get_alias_set first thing.
+
+2000-06-01 Richard Henderson <rth@cygnus.com>
+
+ * decl2.c (unsupported_options): Fix typo, make const.
+ (lang_decode_option): Fix bsearch argument order.
+
+2000-06-01 Mark Mitchell <mark@codesourcery.com>
+
+ * init.c (resolve_offset_ref): Remove check for TREE_ADDRESSABLE
+ on FIELD_DECLs.
+
+2000-05-31 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * cp-tree.h (c_get_alias_set): Deleted.
+ * Makefile.in (decl.o): Include ../expr.h.
+ * decl.c (expr.h): Include.
+ (init_decl_processing): Call record_component_aliases for arrays.
+ (grokdeclarator): Likewise.
+ Set TREE_ADDRESSABLE for fields that aren't bitfields.
+ * tree.c (build_cplus_array_type_1): Call record_component_aliases.
+
+2000-05-31 Mark Mitchell <mark@codesourcery.com>
+
+ Remove guiding declaration support.
+ * cp/cp-tree.h (flag_dump_translation_unit): Make it const.
+ (flag_guiding_decls): Remove.
+ * call.c (build_user_type_conversion_1): Remove support for
+ guiding decls.
+ (build_new_function_call): Likewise.
+ (build_new_op): Likewise.
+ (build_new_method_call): Likewise.
+ * decl.c (start_function): Likewise.
+ * friend.c (is_friend): Likewise.
+ (do_friend): Likewise.
+ * decl2.c ((flag_dump_translation_unit): Make it const.
+ (flag_guiding_decls): Remove.
+ (unsupported_options): New variable
+ (compare_options): New function.
+ (lang_decode_option): Use them.
+
+ * decl.c (build_cp_library_fn): Set DECL_CONTEXT.
+
+ * method.c (mangle_expression): Adjust test for legal expression
+ operators.
+
+ * pt.c (instantiate_decl): Save and restore the local
+ specializations list.
+
+2000-05-30 Jason Merrill <jason@decepticon.cygnus.com>
+
+ * decl.c (grok_reference_init): Pass LOOKUP_ONLYCONVERTING.
+
+2000-05-30 Mark Mitchell <mark@codesourcery.com>
+
+ * call.c (add_template_candidate_real): Handle member template
+ constructors for classes with virtual bases.
+ (build_user_type_conversion_1): Use in_charge_arg_for_name.
+ (build_new_method_call): Use DECL_NONSTATIC_MEMBER_FUNCTION_P.
+
+ * ir.texi: Update thunk documentation.
+
+ * call.c (joust): Fix handling of overloaded builtin operators.
+
+2000-05-30 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cp-tree.h (DECL_ANTICIPATED): New macro.
+ Document new use of DECL_LANG_FLAG_7.
+ * decl.c (builtin_function): Set DECL_ANTICIPATED on builtins
+ in the user namespace.
+ * lex.c (do_identifier): If the identifier's declaration has
+ DECL_ANTICIPATED on, it has not yet been declared. But do not
+ replace it with an ordinary implicit declaration.
+
+ * tinfo2.cc: Include stdlib.h.
+
+2000-05-29 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_ALIGN_UNIT): New macro.
+ * class.c (layout_empty_base): Use CLASSTYPE_ALIGN_UNIT, not
+ CLASSTYPE_ALIGN.
+
+2000-05-28 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Use skip_leading_substring instead
+ of plain strncmp.
+
+2000-05-28 Alexandre Oliva <aoliva@cygnus.com>
+
+ * operators.def (<?): Duplicated, should have been...
+ (>?): this. Fixed.
+
+2000-05-27 Alex Samuel <samuel@codesourcery.com>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (ansi_opname): Make it a macro.
+ (ansi_assopname): Likewise.
+ (struct lang_decl_flags): Add assignment_operator_p.
+ (struct lang_decl): Add operator_code.
+ (DECL_VTT_PARM): Adjust.
+ (DECL_OVERLOADED_OPERATOR_P): Return the operator_code for an
+ overloaded operator.
+ (SET_OVERLOADED_OPERATOR_CODE): New macro.
+ (DECL_ASSIGNMENT_OPERATOR_P): New macro.
+ (DECL_ARRAY_DELETE_OPERATOR_P): Adjust.
+ (opname_tab): Remove.
+ (assignop_tab): Likewise.
+ (operator_name_info_t): New type.
+ (operator_name_info): New variable.
+ (assignment_operator_name_info): Likewise.
+ (build_cp_library_fn): Remove declaration.
+ (push_cp_library_fn): Likewise.
+ (operator_name_string): Likewise.
+ (build_decl_overload): Likewise.
+ * call.c (print_z_candidates): Simplify.
+ (build_object_call): Adjust usage of ansi_opname. Use
+ DECL_OVERLOADED_OPERATOR_P.
+ (op_error): Adjust operator name lookup.
+ (build_conditional_expr): Adjust usage of ansi_opname.
+ (build_new_op): Likewise.
+ (build_op_delete_call): Likewise.
+ (build_over_call): Likewise.
+ (joust): Use DECL_OVERLOADED_OPERATOR_P.
+ * decl.c (duplicate_decls): Copy operator_code.
+ (init_decl_processing): Adjust parameters to push_cp_library_fn.
+ (builtin_function): Adjust parameters to build_library_fn_1.
+ (build_library_fn_1): Accept an overloaded operator code.
+ (build_library_fn): Pass ERROR_MARK.
+ (build_cp_library_fn): Accept an overloaded operator code.
+ (push_cp_library_fn): Likewise.
+ (grokfndecl): Tweak.
+ (grokdeclarator): Simplify code to compute names of overloaded
+ operators. Adjust use of ansi_opname.
+ (ambi_op_p): Work on tree_codes, not identifiers.
+ (unary_op_p): Likewise.
+ (grok_op_properties): Likewise.
+ (start_function): Use DECL_OVERLOADED_OPERATOR_P.
+ (lang_mark_tree): Don't try to mark the operator_code.
+ * decl2.c (grok_function_init): Use DECL_OVERLOADED_OPERATOR_P.
+ * error.c (dump_decl): Remove special handling for operator
+ names.
+ (dump_function_name): Likewise.
+ (dump_expr): Adjust name lookup of operators.
+ (op_to_string): Simplify.
+ (assop_to_string): Likewise.
+ * init.c (build_new_1): Adjust use of ansi_opname.
+ * lex.c (opname_tab): Remove.
+ (assignop_tab): Likewise.
+ (ansi_opname): Likewise.
+ (ansi_assopname): Likewise.
+ (operator_name_string): Likewise.
+ (reinit_lang_specific): Likewise.
+ (operator_name_info): New variable.
+ (assignment_operator_name_info): Likewise.
+ (init_operators): New function.
+ (init_parse): Use it.
+ (do_identifier): Adjust use of ansi_opname.
+ * method.c (mangle_expression): Don't use ansi_opname for
+ mangling.
+ (build_decl_overload_real): Use DECL_OVERLOADED_OPERATOR_P.
+ (build_decl_overload): Remove.
+ (build_typename_overload): Use OPERATOR_TYPENAME_FORMAT directly.
+ (do_build_assign_ref): Adjust use of ansi_opname.
+ (synthesize_method): Likewise.
+ (implicitly_declare_fn): Likewise.
+ * operators.def: New file.
+ * parse.y (operator): Adjust use of ansi_opname.
+ * pt.c (tsubst_decl): Use IDENTIFIER_OPNAME_P.
+ (set_mangled_name_for_template_decl): Don't play games with
+ current_namespace.
+ (special_function_p): Adjust use of ansi_opname.
+ * typeck.c (check_return_expr): Likewise.
+ * Make-lang.in (cc1plus): Depend on operators.def.
+ * Makefile.in (lex.o): Likewise.
+ (decl.o): Likewise.
+
+2000-05-27 Zack Weinberg <zack@wolery.cumb.org>
+
+ * Make-lang.in (cplib2.ready): Eradicate.
+
+2000-05-27 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * method.c (mangle_expression): Use TREE_CODE_LENGTH.
+ * tree.c (break_out_calls, build_min_nt): Use TREE_CODE_LENGTH.
+ (built_min, cp_tree_equal): Likewise.
+
+2000-05-26 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_nonempty_base_or_field): Replace
+ `record_layout_info' with `record_layout_info_s'.
+
+2000-05-26 Jason Merrill <jason@casey.soma.redhat.com>
+
+ Fix goto checking.
+ * cp-tree.h (struct language_function): x_named_labels is now
+ a struct named_label_list*.
+ * decl.c (struct named_label_use_list): Renamed from...
+ (struct named_label_list): ...this. New struct.
+ (push_binding_level): Don't set eh_region.
+ (note_level_for_eh): New fn.
+ (pop_label): Take label and old value directly.
+ (pop_labels): Adjust for new named_labels format.
+ (lookup_label): Likewise.
+ (poplevel): Note characteristics of a binding level containing a
+ named label. Mess with named label lists earlier.
+ (mark_named_label_lists): New fn.
+ (mark_lang_function): Call it.
+ (use_label): New fn, split out from...
+ (make_label_decl): ...here. Don't call it.
+ (decl_jump_unsafe, check_previous_goto, check_previous_goto_1,
+ check_previous_gotos): New fns, split out from...
+ (define_label): ...here.
+ (check_switch_goto): New fn.
+ (define_case_label): Call it.
+ (check_goto): New fn.
+ * semantics.c (finish_goto_stmt): Call it and use_label.
+ (begin_compound_stmt): If we're a try block, call note_level_for_eh.
+ (expand_stmt): Never pass 1 as DONT_JUMP_IN to expand_end_bindings.
+
+2000-05-26 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtable_entry_ref): Correct usage of
+ get_vtbl_decl_for_binfo.
+
+ * decl2.c (grokclassfn): Set DECL_LANGUAGE here.
+ * method.c (implicitly_declare_fn): Not here.
+
+2000-05-26 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CPTI_PTMD_DESC_TYPE): Rename to ...
+ (CPTI_PTMD_DESC_TYPE): ... here.
+ (ptmd_desc_type_node): Rename to ...
+ (ptm_desc_type_node): ... here.
+ * decl.c: Likewise.
+ * rtti.c (ptmd_initializer): Rename to ...
+ (ptm_initializer): ... here.
+ (sythesize_tinfo_var): Adjust. Deal with pointer to member
+ function.
+ (create_tinfo_types): Adjust.
+
+2000-05-25 Mark Mitchell <mark@codesourcery.com>
+
+ Finish implementation of VTTs.
+ * cp-tree.h (cp_tree_index): Add CPTI_VTT_PARM_TYPE and
+ CPTI_VTT_PARM_IDENTIFIER.
+ (vtt_parm_identifier): New macro.
+ (vtt_parm_type): Likewise.
+ (BINFO_SUBVTT_INDEX): Likewise.
+ (BINFO_VPTR_INDEX): Likewise.
+ (struct lang_decl): Add vtt_parm.
+ (DECL_VTT_PARM): New macro.
+ (DECL_USE_VTT_PARM): Likewise.
+ (DECL_NEEDS_VTT_PARM_P): Likewise.
+ (get_vtt_name): Declare.
+ (build_artificial_parm): Likewise.
+ (fixup_all_virtual_upcast_offsets): Likewise.
+ (expand_indirect_vtbls_init): Remove.
+ * call.c (build_new_method_call): Pass the vtt to subobject
+ constructors and destructors.
+ * class.c (get_vtt_name): Give it external linkage.
+ (build_clone): Handle the magic VTT parameters for clones.
+ (clone_function_decl): Fix typo in comment.
+ (build_vtt): Keep track of the indices in the VTTs where various
+ entities are stored.
+ (build_vtt_inits): Likewise.
+ (dfs_build_vtt_inits): Likewise.
+ (build_ctor_vtbl_group): Tweak type of construction vtables.
+ (dfs_accumulate_vtbl_inits): Build vtables for all bases, even
+ primary bases, when building construction vtables.
+ * decl.c (duplicate_decls): Handle DECL_VTT_PARM.
+ (initialize_predefined_identifiers): Add vtt_parm_identifier.
+ (init_decl_processing): Initialize vtt_parm_type.
+ (grokfndecl): Use DECL_OVERLOADED_OPERATOR_P.
+ (lang_mark_tree): Make vtt_parm.
+ * decl2.c (build_artificial_parm): New function.
+ (maybe_retrofit_in_chrg): Use it. Add VTT parameters.
+ (grokclassfn): Use build_artificial_parm.
+ * init.c (initialize_vtbl_ptrs): Call
+ fixup_all_virtual_upcast_offsets directly.
+ (perform_member_init): Use the complete subobject destructor for
+ member cleanups.
+ (build_vtbl_address): New function.
+ (expand_virtual_init): Handle VTTs.
+ * optimize (maybe_clone_body): Likewise.
+ * search.c (fixup_all_virtual_upcast_offsets): Give it external
+ linkage.
+ (expand_indirect_vtbls_init): Remove.
+ * semantics.c (setup_vtbl_ptr): Fix typos in comment.
+ * tree.c (make_binfo): Make them bigger.
+
+2000-05-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h (__pbase_type_info): Define, based on
+ __pointer_type_info.
+ (__pointer_type_info): Derive from __pbase_type_info. Adjust.
+ (__pointer_to_member_type_info): Likewise.
+ * tinfo2.cc (__pbase_type_info::~__pbase_type_info): Implement.
+ (__pointer_to_member_type_info::__is_pointer_p): Remove.
+ (__pointer_type_info::__do_catch): Rename to ...
+ (__pbase_type_info::__do_catch): ... here. Adjust.
+ (__pbase_type_info::__pointer_catch): Implement.
+ (__pointer_type_info::__pointer_catch): Adjust.
+ (__pointer_to_member_type_info::__pointer_catch): Adjust.
+
+2000-05-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.h (__user_type_info::contained_virtual_p): New
+ predicate.
+ * tinfo.cc (__user_type_info::do_upcast): Fix bug with diamond
+ shaped hierarchy.
+ (__vmi_class_type_info::__do_upcast): Fix bug with NULL pointer to
+ diamond shaped hierarchy. Add early out for mixed diamond and
+ duplicate shaped hierarchy.
+
+2000-05-24 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (build_delete): Change prototype.
+ (build_vec_delete): Likewise.
+ * call.c (build_scoped_method_call): Use special_function_kind
+ values to indicate the kind of destruction to be done.
+ (build_method_call): Likewise.
+ * decl.c (finish_destructor_body): Likewise.
+ (maybe_build_cleanup_1): Likewise. Rename to ...
+ (maybe_build_cleanup): ... this.
+ * decl2.c (delete_sanity): Use special_function_kind
+ values to indicate the kind of destruction to be done.
+ (build_cleanup): Likewise.
+ * init.c (perform_member_init): Likewise.
+ (build_vec_delete_1): Likewise.
+ (build_dtor_call): Simplify.
+ (build_delete): Use special_function_kind
+ values to indicate the kind of destruction to be done.
+ (build_vbase_delete): Likewise.
+ (build_vec_delete): Likewise.
+
+ * init.c (sort_member_init): Fix typo in error message generation
+ code.
+
+2000-05-15 Donald Lindsay <dlindsay@cygnus.com>
+
+ * semantics.c (begin_class_definition): make the packed
+ attribute be sensitive to the "-fpack-struct" command line flag
+
+2000-05-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ Update new-abi upcast algorithm.
+ * inc/cxxabi.h (__class_type_info::__do_upcast): Change
+ prototype and meaning of return value.
+ (__si_class_type_info::__do_upcast): Likewise.
+ (__vmi_class_type_info::__do_upcast): Likewise.
+ * tinfo.cc (__class_type_info::__upcast_result): Replace
+ whole2dst with part2dst. Adjust ctor.
+ (__class_type_info::__do_upcast): Adjust call of worker function.
+ (__class_type_info::__do_upcast): Adjust.
+ (__si_class_type_info::__do_upcast): Adjust. Use parent's
+ __do_upcast.
+ (__vmi_class_type_info::__do_upcast): Likewise. Fix private
+ virtual base in diamond hierarchy bug.
+
+2000-05-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Rename mutable_flag to uninlinable
+ and bitfield to tinfo_fn_p.
+ (DECL_TINFO_FN_P): Adjust.
+ (SET_DECL_TINFO_FN_P): Likewise.
+ (DECL_MUTABLE_P): Likewise.
+ (DECL_C_BIT_FIELD): Likewise.
+ (SET_DECL_C_BIT_FIELD): Likewise.
+ (CLEAR_DECL_C_BIT_FIELD): Likewise.
+ (DECL_UNINLINABLE): Likewise.
+ * class.c (alter_access): Call retrofit_lang_decl if ncessary.
+ (handle_using_decl): Remove assertion.
+ (build_vtbl_or_vbase_field): Use build_decl, not build_lang_decl,
+ to build FIELD_DECLs.
+ (build_base_field): Likewise.
+ (layout_class_type): Likewise.
+ * decl.c (init_decl_processing): Likewise.
+ (build_ptrmemfunc_type): Likewise.
+ (grokdeclarator): Likewise.
+ * decl2.c (grok_x_components): Likewise.
+ * except.c (call_eh_info): Likewise.
+ * init.c (init_init_processing): Likewise.
+ * rtti.c (expand_class_desc): Likewise.
+ (create_pseudo_type_info): Likewise.
+ (get_vmi_pseudo_type_info): Likewise.
+ (create_tinfo_types): Likewise.
+ * ptree.c (print_lang_decl): Adjust.
+ * typeck.c (build_component_ref): Don't check DECL_LANG_SPECIFIC
+ before checking DECL_MUTABLE_P.
+
+ * decl2.c (maybe_retrofit_in_chrg): Don't create in-charge
+ parameters for template functions.
+ * pt.c (tsubst_decl): Make sure we call maybe_retrofit_in_chrg for
+ destructors as well as constructors.
+
+2000-05-22 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_ctor_vtbl_group): Set inits.
+ * optimize.c (maybe_clone_body): Set DECL_INLINE and
+ DECL_THIS_INLINE appropriately for clones.
+
+ * cp-tree.h (IDENTIFIER_TYPENAME_P): Use a flag, not strncmp.
+ (DECL_CONV_FN_P): Simplify.
+ (DECL_OPERATOR): Remove.
+ (language_to_string): Declare.
+ * decl.c (duplicate_decls): Fix typo in comment.
+ (grokdeclarator): Adjust use of IDENTIFIER_TYPENAME_P.
+ (grok_op_properties): Use DECL_CONV_FN_P instead of
+ IDENTIFIER_TYPENAME_P.
+ * dump.c (dequeue_and_dump): Dump the language linkage of
+ declarations.
+ * error.c (language_to_string): Give it external linkage.
+ * method.c (build_typename_overload): Set IDENTIFIER_TYPENAME_P.
+ (implicitly_declare_fn): Set DECL_LANGUAGE.
+ * pt.c (check_explicit_specialization): Use DECL_CONV_FN_P, not
+ IDENTIFIER_TYPENAME_P.
+ (tsubst_decl): Likewise.
+ (tsubst_copy): Adjust use of IDENTIFIER_TYPENAME_P.
+ * semantics.c (finish_member_declaration): Don't mark members of
+ classes declared in an extern "C" region as extern "C".
+
+2000-05-22 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl2.c (qualified_lookup_using_namespace): Look through
+ namespace aliases.
+
+ * decl.c (push_using_decl): Return the old decl on namespace level.
+
+2000-05-21 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (SET_BINFO_NEW_VTABLE_MARKED): Add sanity checks.
+ (VTT_NAME_PREFIX): New macro.
+ (CTOR_VTBL_NAME_PREFIX): Likewise.
+ (get_ctor_vtbl_name): New function.
+ * class.c (get_vtable_name): Simplify.
+ (get_vtt_name): New function.
+ (get_vtable_decl): Don't set IDENTIFIER_GLOBAL_VALUE.
+ (dfs_mark_primary_bases): Update the CLASSTYPE_VBASECLASSES list
+ when a virtual base becomes primary.
+ (finish_struct_1): Set CLASSTYPE_VFIELDS a little earlier. Build
+ VTTs.
+ (finish_vtbls): Adjust calls to accumulate_vtbl_inits to pass in
+ additional parameters.
+ (dfs_finish_vtbls): Don't clear BINFO_NEW_VTABLE_MARKED.
+ (initialize_array): New function.
+ (build_vtt): Likewise.
+ (build_vtt_inits): Likewise.
+ (dfs_build_vtt_inits): Likewise.
+ (dfs_fixup_binfo_vtbls): Likewise.
+ (build_ctor_vtbl_group): Likewise.
+ (initialize_vtable): Use initialize_array.
+ (accumulate_vtbl_inits): Reimplement to handle construction
+ vtables.
+ (dfs_accumulate_vtbl_inits): Likewise.
+ (bulid_vtbl_initializer): Adjust parameter name.
+ * method.c (build_typename_overload): Remove #if 0'd code.
+ (get_ctor_vtbl_name): New function.
+ * search.c (dfs_walk_real): Use BINFO_N_BASETYPES.
+ (init_vbase_pointers): Don't mess with the TREE_CHAIN of a binfo.
+
+ * cp-tree.h (struct lang_type): Remove search_slot.
+ (CLASSTYPE_SEARCH_SLOT): Remove.
+ (emit_base_init): Change prototype.
+ (initialize_vtbl_ptrs): Likewise.
+ (expand_indirect_vtbls_init): Likewise.
+ (clear_search_slots): Remove.
+ * decl.c (lang_mark_tree): Don't mark search_slot.
+ * init.c (initialize_vtbl_ptrs): Simplify.
+ (emit_base_init): Likewise.
+ * search.c (struct vbase_info): Document decl_ptr.
+ (convert_pointer_to_single_level): Remove.
+ (dfs_find_vbases): Remove.
+ (dfs_init_base_pointers): Simplify.
+ (dfs_clear_vbase_slots): Remove.
+ (dfs_vtable_path_unmark): New function.
+ (init_vbase_pointers): Simplify.
+ (expand_upcast_fixups): Don't rely on CLASSTYPE_SEARCH_SLOT.
+ (expand_indirect_vtbls_init): Simplify. Don't call
+ mark_all_temps_used.
+ * semantics.c (setup_vtbl_ptr): Adjust calls to emit_base_init and
+ initialize_vtbl_ptrs.
+
+2000-05-20 Zack Weinberg <zack@wolery.cumb.org>
+
+ * except.c: Add static prototypes.
+
+2000-05-20 H.J. Lu <hjl@gnu.org>
+
+ * Make-lang.in (cplib2.ready): Also depend on cc1plus$(exeext).
+
+2000-05-19 Mark Mitchell <mark@codesourcery.com>
+
+ Don't create a separate copy of virtual bases for the
+ CLASSTYPE_VBASECLASSES list.
+ * cp-tree.h (CLASSTYPE_VBASECLASSES): Change documentation.
+ (BINFO_FOR_VBASE): Remove.
+ (CANONICAL_BINFO): Adjust.
+ (binfo_for_vbase): New function.
+ * class.c (build_vbase_pointer_fields): Use binfo_for_vbase
+ instead of BINFO_FOR_VBASE.
+ (build_vbase_pointer): Likewise.
+ (build_secondary_vtable): Likewise.
+ (dfs_mark_primary_bases): Likewise.
+ (mark_primary_bases): Likewise.
+ (layout_nonempty_base_or_field): Likewise.
+ (dfs_set_offset_for_shared_vbases): Likewise.
+ (dfs_set_offset_for_unshared_vbases): Likewise.
+ (layout_virtual_bases): Likewise. Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (dump_class_hierarchy_r): Use binfo_for_vbase
+ instead of BINFO_FOR_VBASE.
+ (dump_class_hierarchy): Likewise.
+ (finish_vtbls): Likewise.
+ (build_vtbl_initializer): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (build_vbase_offset_vtbl_entries): Use binfo_for_vbase.
+ * decl.c (finish_destructor_body): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ * init.c (sort_base_init): Use binfo_for_vbase.
+ (construct_virtual_bases): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (expand_member_init): Use binfo_for_vbase.
+ (build_vbase_delete): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ * method.c (do_build_copy_constructor): Likewise.
+ * rtti.c (get_base_offset): Use binfo_for_vbase.
+ (expand_class_desc): Remove #if 0'd code.
+ * search.c (struct vbase_info): Remove vbase_types.
+ (get_base_distance): Use binfo_for_vbase.
+ (lookup_field_queue_p): Use CANONICAL_BINFO.
+ (get_shared_vbase_if_not_primary): Use binfo_for_vbase.
+ (get_pure_virtuals): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (dfs_find_vbases): Use binfo_for_vbase.
+ (dfs_init_vbase_pointers): Likewise.
+ (init_vbase_pointers): Don't initialize vi.vbase_types.
+ (virtual_context): Use binfo_for_vbase.
+ (fixup_all_virtual_upcast_offsets): Adjust for changes to the
+ CLASSTYPE_VBASECLASSES list.
+ (expand_indirect_vtbls_init): Simplify.
+ (dfs_get_vbase_types): Don't replicate virtual bases.
+ (find_vbase_instance): Use binfo_for_vbase.
+ (binfo_for_vbase): New function.
+ * typeck.c (get_delta_difference): Use binfo_for_vbase.
+
+2000-05-17 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (finish_anon_union): Generalize error messages to handle
+ anonymous structures.
+ * init.c (perform_member_init): Remove `name' parameter.
+ (build_field_list): New function.
+ (sort_member_init): Handle anonymous union initialization order
+ correctly. Check for multiple initializations of the same union.
+ (emit_base_init): Don't look up fields by name here.
+ (expand_member_init): Record the result of name lookup for future
+ reference.
+ * typeck.c (build_component_ref): Fix formatting.
+
+2000-05-17 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * decl.c (pop_label): Replace warn_unused with warn_unused_label.
+ * typeck.c (build_x_compound_expr): Replace warn_unused with
+ warn_unused_value.
+
+ * decl2.c (lang_decode_option): Update -Wall unused flags by
+ calling set_Wunused.
+
+2000-05-16 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-treeh (BINFO_NEW_VTABLE_MARKED): Update documentation.
+ * init.c (dfs_vtable_path_unmark): Remove.
+ * search.c (marked_new_vtable_p): Likewise.
+ (unmarked_new_vtable_p): Likewise.
+ (dfs_search_slot_nonempty_p): Likewise.
+ (dfs_mark): Likewise.
+ (dfs_vtable_path_unmark): Likewise.
+ (dfs_find_vbases): Don't set BINFO_NEW_VTABLE_MARKED.
+ (dfs_int_vbase_pointers): Don't clear BINFO_VTABLE_PATH_MARKED.
+ (dfs_init_vbase_pointers): Remove special-case new ABI code.
+ (dfs_clear_vbase_slots): Don't clear BINFO_NEW_VTABLE_MARKED.
+ (init_vbase_pointers): Simplify.
+ (expand_indirect_vtbls_init): Likewise.
+
+ * class.c (copy_virtuals): New function.
+ (build_primary_table): Use it.
+ (build_secondary_vtable): Likewise.
+ (modify_vtable_entry): Use NULL_TREE, not integer_zero_node, to
+ indicate that no vcall offset is required.
+ (add_virtual_function): Likewise.
+ (modify_all_vtables): Likewise.
+ (dfs_finish_vtbls): Adjust call to build_vtbl_initializer.
+ (dfs_accumulate_vtbl_inits): Likewise.
+ (build_vtbl_initializer): Make changes to handle construction
+ vtables.
+ (dfs_build_vcall_offset_vtbl_entries): Likewise.
+ (build_rtti_vtbl_entries): Likewise.
+ (build_vtable_entries): Handle a NULL vcall_index.
+
+2000-05-15 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Fix thinko.
+
+2000-05-14 Jason Merrill <jason@casey.cygnus.com>
+
+ * except.c (check_handlers): New fn.
+ * cp-tree.h: Declare it.
+ * semantics.c (finish_handler_sequence): Call it.
+ (finish_function_handler_sequence): Likewise.
+ (finish_handler_parms): Set TREE_TYPE on the handler.
+ * cp-tree.h (PUBLICLY_UNIQUELY_DERIVED_P): New macro.
+ * search.c (get_base_distance_recursive): If protect>1, ignore
+ special access.
+ (get_base_distance): Don't reduce watch_access.
+
+2000-05-13 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c: #include diagnostic.h.
+ (lang_init_options): Set default prefixing rules.
+
+ * lang-options.h: Add -fdiagnostics-show-location=.
+
+ * decl2.c: #include diagnostic.h.
+ (lang_decode_option): Handle -fdiagnostics-show-location=.
+
+2000-05-12 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.cc: Revert my 2000-05-08 and 2000-05-07 changes.
+ * vec.cc: Revert my 2000-05-07 change.
+
+2000-05-11 Jason Merrill <jason@casey.cygnus.com>
+
+ * class.c (check_field_decls): Complain about non-static data
+ members with same name as class in class with constructor.
+
+2000-05-10 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (grokdeclarator): Allow non-static data members with
+ same name as class.
+
+2000-05-09 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cp-tree.h: Constify tree_srcloc.filename, tinst_level.file,
+ and pending_inline.filename. Update prototypes.
+ * decl.c (define_label): Constify filename parameter.
+ * decl2.c (warn_if_unknown_interface): Constify local char *.
+ * input.c Constify input_source.filename. Don't declare
+ input_filename or lineno. Constify filename parameter to feed_input.
+ * lex.c (init_parse): Constify parameter and return value.
+ (cp_pragma_interface, cp_pragma_implementation): Constify
+ filename argument.
+ (reinit_parse_for_method, reinit_parse_for_block,
+ reinit_parse_for_expr, feed_defarg, handle_cp_pragma):
+ Constify local char *.
+ * pt.c: Don't declare lineno or input_filename.
+ (print_template_context, tsubst_friend_function, tsubst_decl,
+ tsubst, instantiate_decl): Constify local char *.
+ * semantics.c (expand_body): Constify local char *.
+ * tree.c (build_srcloc): Constify filename parameter.
+ * typeck.c (c_expand_asm_operands): Constify filename
+ parameter.
+
+2000-05-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.cc (__dynamic_cast): Use a reinterpret_cast. Fix
+ offsetof expansion.
+
+2000-05-08 Branko Cibej <branko.cibej@hermes.si>
+
+ * inc/cxxabi.h: Fix typos in comment.
+ (__base_class_info::__offset): Use a static_cast.
+
+2000-05-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h: Use __SIZE_TYPE_ and __PTRDIFF_TYPE__ in place
+ of std::size_t and std::ptrdiff_t respectively.
+ * tinfo.cc: Likewise.
+ * vec.cc: Likewise.
+
+2000-05-06 Richard Henderson <rth@cygnus.com>
+
+ * typeck.c (build_c_cast): Don't warn integer->pointer size
+ mismatch for constants.
+
+2000-05-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (ptmd_initializer): Set non-public, if class is
+ incomplete.
+
+ * inc/cxxabi.h (__dynamic_cast): Explicitly say extern "C++".
+ (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
+ __cxa_vec_delete): Likewise.
+ * tinfo.cc (__dynamic_cast): Likewise.
+ * vec.cc (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
+ __cxa_vec_delete): Likewise.
+
+2000-05-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DELTA_FROM_VTABLE_ENTRY): Remove.
+ (SET_FNADDR_FROM_VTABLE_ENTRY): Likewise.
+ (lang_decl_flags): Add vcall_offset.
+ (THUNK_VCALL_OFFSET): Use it.
+ * decl.c (lang_mark_tree): Don't mark DECL_ACCESS for a thunk.
+ * method.c (make_thunk): Create the lang_decl here, not in
+ emit_thunk.
+ (emit_thunk): Make generic thunks into ordinary functions once
+ they have been fed to expand_body.
+ * semantics.c (expand_body): Set current_function_is_thunk here.
+
+2000-05-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (update_vtable_entry_for_fn): Prototype.
+
+ * pt.c (tsubst_decl): Initialize variables `argvec', `gen_tmpl'
+ and `tmpl'.
+
+ * search.c (dfs_build_inheritance_graph_order): Prototype.
+
+2000-05-04 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (special_function_kind): Add various kinds of
+ destructors.
+ (special_function_p): New function.
+ * class.c (overrides): Don't let one kind of destructor override
+ another.
+ * decl2.c (mark_used): Use DECL_NON_THUNK_FUNCTION_P when deciding
+ whether or not to instantiate a template.
+ * tree.c (special_function_p): Define.
+
+2000-05-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (THUNK_DECL): Remove.
+ * cp-tree.h (DECL_THUNK_P): New macro.
+ (DECL_NON_THUNK_FUNCTION_P): Likewise.
+ (DECL_EXTERN_C_FUNCTION_P): Likewise.
+ (SET_DECL_THUNK_P): Likewise.
+ (DELTA_FROM_VTABLE_ENTRY): Use DECL_THUNK_P.
+ (FNADDR_FROM_VTABLE_ENTRY): Likewise.
+ (DECL_MAIN_P): Use DECL_EXTERN_C_FUNCTION_P.
+ * decl.c (decls_match): Use DECL_EXTERN_C_P.
+ (duplicate_decls): Likewise.
+ (pushdecl): Likewise. Adjust thunk handling.
+ (grokfndecl): Use DECL_EXTERN_C_P.
+ * decl2.c (mark_vtable_entries): Use DECL_THUNK_P.
+ * dump.c (dequeue_and_dump): Remove THUNK_DECL handling.
+ * except.c (nothrow_libfn_p): Use DECL_EXTERN_C_P.
+ * expr.c (cplus_expand_expr): Remove THUNK_DECL handling.
+ * method.c (make_thunk): Use SET_DECL_THUNK_P. Set
+ DECL_NO_STATIC_CHAIN.
+ (emit_thunk): Don't play games with TREE_CODE on thunks. Don't
+ set DECL_DESTRUCTOR_P or DECL_CONSTRUCTOR_P on a thunk.
+ * search.c (covariant_return_p): Remove THUNK_DECL handling.
+ * ir.texi: Update.
+
+2000-05-01 Jason Merrill <jason@casey.cygnus.com>
+
+ * tree.c (walk_tree): Set lineno.
+
+2000-05-01 Mark Mitchell <mark@codesourcery.com>
+
+ * exception.cc: Update license notice.
+ * new.cc: Likewise.
+ * new1.cc: Likewise.
+ * new2.cc: Likewise.
+ * tinfo.cc: Likewise.
+ * tinfo2.cc: Likewise.
+ * vec.cc: Likewise.
+ * inc/cxxabi.h: Likewise.
+ * inc/exception: Likewise.
+ * inc/new: Likewise.
+ * inc/new.h: Likewise.
+ * inc/typeinfo: Likewise.
+
+2000-05-01 Jason Merrill <jason@casey.cygnus.com>
+
+ * tree.c (build_target_expr_with_type): If we already have a
+ TARGET_EXPR, just return it.
+
+ * optimize.c (initialize_inlined_parameters): Don't generate an
+ EXPR_STMT if we can just use DECL_INITIAL.
+ * decl.c (emit_local_var): Only make the initialization a
+ full-expression if stmts_are_full_exprs_p.
+
+2000-05-01 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (same_type_ignoring_top_level_qualifiers_p): New
+ macro.
+ * call.c (standard_conversion): Use it.
+ (direct_reference_binding): Likewise.
+ (build_over_call): Likewise.
+ (is_properly_derived_from): Likewise.
+ (compare_ics): Likewise.
+ * class.c (resolves_to_fixed_type_p): Likewise.
+ * optimize.c (declare_return_variable): Likewise.
+ * pt.c (is_specialization_of): Likewise.
+ (unify): Likewise.
+ * typeck.c (comp_target_parms): Likeiwse.
+ (build_static_cast): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_const_cast): Likewise.
+ (comp_ptr_ttypes_real): Likewise.
+ (comp_ptr_ttypes_const): Likewise.
+ * typeck2.c (process_init_constructor): Likewise.
+
+2000-04-30 Scott Snyder <snyder@fnal.gov>
+
+ * decl.c (finish_destructor_body): Use the base destructor when
+ destroying virtual bases.
+
+2000-04-30 Mark Mitchell <mark@codesourcery.com>
+
+ * expr.c (cplus_expand_expr): Preserve temporaries when expanding
+ STMT_EXPRs.
+ * optimize.c (struct inline_data): Add target_exprs field.
+ (declare_return_variable): When a function returns an aggregate,
+ use the variable declared in the TARGET_EXPR as the remapped
+ DECL_RESULT.
+ (expand_call_inline): Update the pending target_exprs stack.
+ (optimize_function): Initialize the stack.
+
+ * decl2.c (finish_file): Fix typo in comment.
+
+ * method.c (emit_thunk): Don't try to return a `void' value.
+
+ * optimize.c (initialize_inlined_parameters): If the parameter is
+ addressable, we need to make a new VAR_DECL, even if the
+ initializer is constant.
+
+2000-04-28 Cosmin Truta <cosmint@cs.ubbcluj.ro>
+
+ * decl.c (grok_op_properties): Add an extra check of argtypes.
+
+2000-04-27 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (copy_body_r): Use STRIP_TYPE_NOPS when copying
+ variables.
+ (initialize_inlined_parameters): Try to avoid creating new
+ VAR_DECLs.
+
+2000-04-27 Alex Samuel <samuel@codesourcery.com>
+
+ * lex.c (my_get_run_time): Remove.
+ (init_filename_times): Use get_run_time instead of my_get_run_time.
+ (check_newline): Likewise.
+ (dump_time_statistics): Likewise.
+ * decl2.c (finish_file): Push and pop timevar TV_VARCONST instead
+ of computing elapsed time explicitly.
+
+2000-04-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TREE_READONLY_DECL_P): Use DECL_P.
+ * init.c (decl_constant_value): Check TREE_READONLY_DECL_P.
+ * call.c (convert_like_real): Don't test TREE_READONLY_DECL_P
+ before calling decl_constant_value.
+ * class.c (check_bitfield_decl): Likewise.
+ * cvt.c (ocp_convert): Likewise.
+ (convert): Likewise.
+ * decl.c (compute_array_index_type): Likewise.
+ (build_enumerator): Likewise.
+ * decl2.c (check_cp_case_value): Likewise.
+ * pt.c (convert_nontype_argument): Likewise.
+ (tsubst): Likewise.
+ * typeck.c (decay_conversion): Likewise.
+ (build_compound_expr): Likewise.
+ (build_reinterpret_cast): Likewise.
+ (build_c_cast): Likewise.
+ (convert_for_assignment): Likewise.
+
+2000-04-26 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (finish_function): Don't play games with DECL_INLINE.
+
+2000-04-25 Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
+
+ * ir.texi: Correct typo.
+
+2000-04-25 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (grokdeclarator): Reject VLAs as members.
+
+2000-04-24 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * call.c (standard_conversion): Accept conversion between
+ COMPLEX_TYPEs.
+
+ * cvt.c (ocp_convert): Handle conversion to COMPLEX_TYPE.
+
+2000-04-24 Zack Weinberg <zack@wolery.cumb.org>
+
+ * decl2.c (finish_file): Remove double setup for accounting
+ compile time.
+
+2000-04-24 Robert Lipe <robertlipe@usa.net>
+
+ * cp-tree.h (lang_type): Member `language' now ENUM_BITFIELD.
+
+2000-04-23 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * new.cc (set_new_handler): Needs to be in std::.
+
+2000-04-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl): Remove pretty_function_p.
+ (DECL_PRETTY_FUNCTION_P): Use TREE_LANG_FLAG_0, not a bit in the
+ language-specific node.
+ * decl.c (cp_make_fname_decl): Use build_decl, not
+ build_lang_decl, to build the variables.
+ (grokvardecl): Don't call build_lang_decl for local variables in
+ templates.
+ (grokdeclarator): Don't call build_lang_decl for local type
+ declarations in templates.
+ * lex.c (retrofit_lang_decl): Use ggc_alloc_obj to allocated
+ zero'd memory, rather than calling memset.
+ * pt.c: Include hashtab.h.
+ (local_specializations): New variable.
+ (retrieve_local_specialization): Use it.
+ (register_local_specialization): Likewise.
+ (tsubst_decl): Don't assume local variables have
+ DECL_LANG_SPECIFIC.
+ (instantiate_decl): Set up local_specializations.
+ * Makefile.in (HTAB_H): New variable.
+
+2000-04-23 Richard Henderson <rth@cygnus.com>
+
+ * typeck.c (c_expand_asm_operands): Restore the original
+ contents of the output list.
+
+2000-04-22 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * ir.texi: Document complex number representation.
+
+2000-04-20 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (init_rtti_processing): Set tinfo_var_id in new-abi.
+ (target_incomplete_p): New function.
+ (tinfo_base_init): Create comdat NTBS name variable.
+ (ptr_initializer): Add non_public parameter. Calculate it.
+ (ptmd_initializer): Likewise.
+ (synthesize_tinfo_var): Adjust. Emit incomplete class tinfo.
+ (create_real_tinfo_var): Add non_public parameter. Use it.
+ Push proxy into global namespace.
+ * inc/cxxabi.h (__pointer_type_info::incomplete_class_mask):
+ New enumeration.
+ * inc/typeinfo (type_info::before, type_info::operator==):
+ Compare __name addresses.
+
+ * tinfo2.cc: Remove new-abi builtins comment.
+
+2000-04-20 Jason Merrill <jason@casey.cygnus.com>
+
+ * typeck.c (build_x_function_call): Resolve an OFFSET_REF.
+
+ * call.c (joust): Exit early if we get the same function, too.
+
+ * decl2.c (key_method): Return NULL_TREE for template classes.
+ (import_export_class): Don't need to check for template classes.
+
+2000-04-18 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lex.c: Remove references to cccp.c.
+
+2000-04-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Remove const_memfunc and
+ volatile_memfunc. Add destructor_attr. Adjust dummy.
+ (DECL_DESTRUCTOR_P): Use destructor_attr.
+ (DECL_CONST_MEMFUNC_P): Reimplement.
+ (DECL_VOLATILE_MEMFUNC_P): Remove.
+ * class.c (finish_struct_methods): Use CLASSTYPE_DESTRUCTORS.
+ (overrides): Use DECL_DESTRUCTOR_P.
+ (check_for_override): Likewise.
+ * decl.c (start_function): Likewise.
+ * decl2.c (grokfclassfn): Likewise.
+ (check_classfn): Likewise.
+ (grok_function_init): Likewise.
+
+2000-04-17 Mark Mitchell <mark@codesourcery.com>
+
+ * decl2.c (grokfield): Issue error on illegal data member
+ declaration.
+
+2000-04-17 Mark P Mitchell <mark@codesourcery.com>
+
+ * method.c (make_thunk): Set DECL_CONTEXT for a THUNK_DECL.
+
+2000-04-16 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (build_vtable_entry): Don't build thunks for type-info
+ functions.
+
+2000-04-16 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (decls_match): Allow a redeclaration of a builtin to
+ specify args while the builtin did not.
+
+2000-04-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (THUNK_DECL): Add to documentation.
+ * cp-tree.h (flag_huge_objects): Declare.
+ * class.c (modify_vtable_entry): Tidy.
+ (update_vtable_entry_for_fn): Split out from dfs_modify_vtables.
+ Calculate delta appropriately for the new ABI.
+ (dfs_modify_vtables): Use it.
+ (modify_all_vtables): Fix thinko in code to add overriding copies
+ of functions to primary vtables.
+ (build_clone): Fix typo in comment.
+ (clone_function_decl): Correct order of destructors in vtable.
+ (build_vbase_offset_vtbl_entries): Adjust comment.
+ (dfs_vcall_offset_queue_p): Remove.
+ (dfs_build_vcall_offset_vtbl_entries): Update BV_VCALL_INDEX.
+ (build_vcall_offset_vtbl_entries): Juse use dfs_skip_vbases.
+ (build_vtable_entry): Correct check for pure virtual functions.
+ Don't declare flag_huge_objects.
+ * decl.c (flag_huge_objects): Remove declaration.
+ * method.c (make_thunk): Tweak mangling for vcall offset thunks.
+ Use int_size_in_bytes.
+ (emit_thunk): Handle vcall offset thunks.
+
+2000-04-15 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl2.c (parse_time, varconst_time): Delete declarations.
+ (finish_file): Delete LINENO declaration.
+ START_TIME and THIS_TIME now long.
+
+2000-04-13 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_base_field): Reformat comment.
+
+ * inc/cxxabi.h (stddef.h): Comment inclusion.
+ (__base_class_info::__offset): Comment shift.
+
+2000-04-12 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (IDENTIFIER_CTOR_OR_DTOR_P): New macro.
+ (cp_tree_index): Add CPTI_PUSH_EXCEPTION_IDENTIFIER.
+ (cp_push_exception_identifier): New macro.
+ (DECL_COMPLETE_DESTRUCTOR_P): New macro.
+ (DECL_BASE_DESTRUCTOR_P): Likewise.
+ (DECL_DELETING_DESTRUCTOR_P): Likewise.
+ (get_vtbl_decl_for_binfo): Fix formatting.
+ (in_charge_arg_for_name): New macro.
+ (maybe_build_cleanup_and_delete): Remove declaration.
+ * call.c (build_field_call): Use IDENTIFIER_CTOR_OR_DTOR_P.
+ (in_charge_arg_for_name): New function.
+ (build_new_method_call): Use it. Handle cloned destructors.
+ (build_clone): Don't make the base constructor virtual.
+ Automatically defer generated functions.
+ (clone_function_decl): Handle destructors, too.
+ (clone_constructors_and_destructors): Likewise.
+ (create_vtable_ptr): Don't create a vtable entry for a cloned
+ function.
+ * decl.c (predefined_identifier): Add ctor_or_dtor_p.
+ (initialize_predefined_identifiers): Update appropriately.
+ (finish_destructor_body): Simplify.
+ (maybe_build_cleanup_and_delete): Remove.
+ * except.c (expand_throw): Handle new-ABI destructors.
+ * init.c (expand_cleanup_for_base): Use base_dtor_identifier.
+ (build_dtor_call): New function.
+ (build_delete): Use it. Simplify.
+ * optimize.c (maybe_clone_body): Handle destructors.
+ * search.c (lookup_field_queue_p): Use IDENTIFIER_CTOR_OR_DTOR_P.
+
+ * exception.cc (cleanup_fn): New typedef.
+ (CALL_CLEANUP): New macro.
+ (cp_eh_info): Use them.
+ (__cp_push_exception): Likewise.
+ (__cp_pop_exception): Likewise.
+
+2000-04-11 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Add CPTI_DTOR_IDENTIFIER.
+ (complete_dtor_identifier): New macro.
+ (CLASSTYPE_FIRST_CONVERSION): Remove.
+ (CLASSTYPE_CONSTRUCTOR_SLOT): New macro.
+ (CLASSTYPE_DESTRUCTOR_SLOT): Likewise.
+ (CLASSTYPE_FIRST_CONVERSION_SLOT): Likewise.
+ (CLASSTYPE_CONSTRUCTORS): Likewise.
+ (CLASSTYPE_DESTRUCTORS): Likewise.
+ (lang_decl): Add cloned_function.
+ (DECL_COMPLETE_CONSTRUCTOR_P): New macro.
+ (DECL_BASE_CONSTRUCTOR_P): Likewise.
+ (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P): Likewise.
+ (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P): Likewise.
+ (DECL_CLONED_FUNCTION_P): Likewise.
+ (DECL_CLONED_FUNCTION): Likewise.
+ (clone_function_decl): Declare.
+ (maybe_clone_body): Likewise.
+ * call.c (build_user_type_conversion_1): Call complete object
+ constructors in the new ABI.
+ (build_new_method_call): Don't add in-charge parameters under the
+ new ABI.
+ * class.c (add_method): Use DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P,
+ DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P, CLASSTYPE_CONSTRUCTOR_SLOT, and
+ CLASSTYPE_DESTRUCTOR_SLOT.
+ (build_clone): New function.
+ (clone_function_decl): Likewise.
+ (clone_constructors_and_destructors): Likewise.
+ (check_bases_and_members): Use it.
+ * decl.c (iniitialize_predefined_identifiers): Initialize
+ complete_dtor_identifier.
+ (finish_function): Don't add extra code to a clone.
+ (lang_mark_tree): Mark cloned_function.
+ * decl2.c (mark_used): Don't bother trying to instantiate things
+ we synthesized.
+ * dump.c (dequeue_and_dump): Don't dump CP_DECL_CONTEXT twice.
+ * method.c (set_mangled_name_for_decl): Don't treat clones as
+ constructors.
+ (synthesize_method): Sythesize cloned functions, not the clones.
+ * optimize.c (inline_data): Update comment on ret_label.
+ (remap_block): Don't assume DECL_INITIAL exists.
+ (copy_body_r): Allow ret_label to be NULL.
+ (maybe_clone_body): Define.
+ * pt.c (tsubst_decl): Handle clones.
+ (instantiate_clone): New function.
+ (instantiate_template): Use it.
+ (set_mangled_name_for_template_decl): Don't treat clones as
+ constructors.
+ * search.c (lookup_fnfields_1): Use CLASSTYPE_CONSTRUCTOR_SLOT,
+ CLASSTYPE_DESTRUCTOR_SLOT, and CLASSTYPE_FIRST_CONVERSION_SLOT.
+ * semantics.c (expand_body): Clone function bodies as necessary.
+
+ * optimize.c (remap_decl): Avoid sharing structure for arrays
+ whose size is only known at run-time.
+ * tree.c (copy_tree_r): Don't copy PARM_DECLs.
+
+ * cp-tree.h (lang_decl_flags): Rename constructor_for_vbase_attr
+ to has_in_charge_parm_p.
+ (DECL_CONSTRUCTOR_FOR_VBASE_P): Rename to ...
+ (DECL_HAS_IN_CHARGE_PARM_P): ... this.
+ (DECL_COPY_CONSTRUCTOR_P): New macro.
+ * call.c (add_function_candidate): Use DECL_HAS_IN_CHARGE_PARM_P.
+ (build_user_type_conversion_1): Likewise.
+ (convert_like_real): Likewise.
+ (build_over_call): Likeiwse. Use DECL_COPY_CONSTRUCTOR_P.
+ * decl.c (grokdeclarator): Use DECL_HAS_IN_CHARGE_PARM_P.
+ (copy_args_p): Likewise.
+ (grok_ctor_properties): Likewise.
+ (start_function): Likewise.
+ * decl2.c (maybe_retrofit_in_charge): Likewise. Set it.
+ * error.c (dump_function_decl): Use DECL_HAS_IN_CHARGE_PARM_P.
+ * init.c (emit_base_init): Use DECL_COPY_CONSTRUCTOR_P.
+ * method.c (do_build_copy_constructor): Use
+ DECL_HAS_IN_CHARGE_PARM_P.
+ (synthesize_method): Likewise.
+ * pt.c (instantiate_template): Remove goto.
+ * tree.c (build_cplus_method_type): Remove mention of obstacks in
+ comment.
+
+ * cp-tre.h (finish_function): Change prototype.
+ * decl.c (end_cleanup_fn): Adjust caller.
+ (finish_function): Take only one parameter.
+ * decl2.c (finish_objects): Adjust caller.
+ (finish_static_storage_duration_function): Likewise.
+ * method.c (emit_thunk): Likewise.
+ * parse.y: Likewise.
+ * parse.c: Regenerated.
+ * pt.c (instantiate_decl): Likewise.
+ * rtti.c (synthesize_tinfo_fn): Likewise.
+ * semantics.c (expand_body): Likewise.
+
+ * cp-tree.h (copy_decl): New function.
+ * class.c (finish_struct_1): Use it.
+ * lex.c (copy_decl): Define it.
+ * pt.c (tsubst_decl): Likewise.
+ * tree.c (copy_template_template_parm): Likewise.
+
+ * cp-tree.h (lang_type): Remove has_nonpublic_ctor and
+ has_nonpublic_assign_ref.
+ (TYPE_HAS_NONPUBLIC_CTOR): Don't declare.
+ (TYPE_HAS_NONPUBLIC_ASSIGN_REF): Likewise.
+ * class.c (finish_struct_methods): Don't set
+ TYPE_HAS_NONPUBLIC_CTOR or TYPE_HAS_NONPUBLIC_ASSIGN_REF.
+ (interface_only): Don't declare.
+ (interface_unknown): Likewise.
+
+2000-04-11 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * tree.h (HAVE_TEMPLATES): Remove definition.
+ * lang-options.h (-fthis-is-variable): Remove documentation.
+
+2000-04-10 Jason Merrill <jason@casey.cygnus.com>
+
+ * class.c (instantiate_type): Handle object-relative template-id.
+
+ * semantics.c (finish_expr_stmt): Call convert_to_void here.
+ * decl.c (cplus_expand_expr_stmt): Not here.
+
+ * rtti.c (build_dynamic_cast_1): Call non_lvalue.
+ Initialize exprtype earlier.
+
+ * parse.y (fn.def1): Check for defining types in return types.
+
+ * decl.c (check_tag_decl): Notice extra fundamental types.
+ Diagnose empty decls in classes, too.
+
+ * decl.c (grokdeclarator): Don't override an anonymous name if no
+ declarator was given.
+
+ * cvt.c (convert_to_void): Call resolve_offset_ref.
+
+ * typeck.c (build_x_function_call): Abort if we get an OFFSET_REF.
+
+ * decl2.c (decl_namespace): Handle getting a type.
+
+ * typeck.c (build_c_cast): Re-enable warning for cast between
+ pointer and integer of different size.
+
+2000-04-10 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h (__pointer_type_info): Add restrict and
+ incomplete flags.
+ (__pointer_type_info::__pointer_catch): New virtual function.
+ (__pointer_to_member_type_info): Derive from
+ __pointer_type_info. Adjust.
+ (__pointer_to_member_type_info::__do_catch): Remove.
+ (__pointer_to_member_type_info::__is_pointer_p): Declare.
+ (__pointer_to_member_type_info::__pointer_catch): Declare.
+ * rtti.c (qualifier_flags): Add restrict flag.
+ (ptmd_initializer): Reorder members.
+ (create_tinfo_types): Expand comments. Reorder
+ ptmd_desc_type_node members.
+ * tinfo2.cc (__pointer_to_member_type_info::__is_pointer_p):
+ Implement.
+ (__pointer_type_info::__do_catch): Move specific code into
+ __pointer_catch. Call it.
+ (__pointer_type_info::__pointer_catch): Non-pointer-to-member
+ specific catch checking. Fix void conversion check.
+ (__pointer_to_member_type_info::__do_catch): Remove.
+ (__pointer_to_member_type_info::__pointer_catch): Implement.
+
+2000-04-10 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * lex.c (init_parse): Remove traces of classof and headof.
+ * decl2.c (flag_operator_names): Default to 1.
+ (lang_decode_option): Do not set it for -ansi.
+
+2000-04-09 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (struct lang_decl): Remove main_decl_variant.
+ (DECL_MAIN_VARIANT): Remove.
+ * decl.c (duplicate_decls): Don't set it.
+ (start_function): Likewise.
+ (lang_mark_tree): Don't mark it.
+ * decl2.c (defer_fn): Don't use it.
+ * lex.c (retrofit_lang_decl): Don't set it.
+ * pt.c (tsubst_decl): Likewise.
+ * ptree.c (print_lang_decl): Don't print it.
+ * typeck.c (mark_addressable): Don't use it.
+
+2000-04-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.cc: Include <new> and <exception>.
+ (__cxa_vec_ctor): Use __cxa_vec_dtor for cleanup.
+ (__cxa_vec_dtor): Catch dtor exceptions, and rethrow or
+ terminate.
+ (__cxa_vec_delete): Catch dtor exceptions.
+
+2000-04-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ Prepend __ to implementation defined names.
+ * inc/typeinfo (type_info): Rename _name to __name.
+ (type_info::type_info): Rename parameter.
+ (type_info::operator==, type_info::operator!=,
+ type_info::before): Likewise.
+ (type_info::is_pointer_p, type_info::is_function_p,
+ type_info::do_catch, type_info::do_upcast): Prepend __. Rename
+ parameters.
+ * inc/cxxabi.h
+ (__fundamental_type_info::__fundamental_type_info) Rename parameters.
+ (__pointer_type_info::__pointer_type_info): Likewise.
+ (__pointer_type_info::is_pointer_p,
+ __pointer_type_info::do_catch): Prepend __. Rename parameters.
+ (__array_type_info::__array_type_info): Rename parameters.
+ (__function_type_info::__function_type_info): Likewise.
+ (__function_type_info::is_function_p): Prepend __.
+ (__enum_type_info::__enum_type_info): Rename parameters.
+ (__pointer_to_member_type_info::__pointer_to_member_type_info):
+ Likewise.
+ (__pointer_to_member_type_info::do_catch): Prepend __. Rename
+ parameters.
+ (__base_class_info::is_virtual_p, is_public_p, offset): Prepend __.
+ (__class_type_info::__class_type_info): Rename parameters.
+ (__class_type_info::sub_kind): Prepend __. Adjust member names.
+ (__class_type_info::upcast_result,
+ __class_type_info::dyncast_result): Prepend __. Move definition
+ into tinfo.cc.
+ (__class_type_info::do_upcast, __class_type_info::do_catch,
+ __class_type_info::find_public_src,
+ __class_type_info::do_dyncast,
+ __class_type_info::do_find_public_src): Prepend __. Rename
+ parameters.
+ (__si_class_type_info::__si_class_type_info): Rename parameters.
+ (__si_class_type_info::do_upcast, __si_class_type_info::do_dyncast,
+ __si_class_type_info::do_find_public_src): Prepent __. Rename
+ parameters.
+ (__vmi_class_type_info::__vmi_class_type_info): Rename parameters.
+ (__vmi_class_type_info::do_upcast, __vmi_class_type_info::do_dyncast,
+ __vmi_class_type_info::do_find_public_src): Prepent __. Rename
+ parameters.
+ (__dynamic_cast): Rename parameters.
+ * tinfo.cc (type_info::is_pointer_p, type_info::is_function_p,
+ type_info::do_catch, type_info::do_upcast): Prepend __.
+ (contained_p, public_p, virtual_p, contained_public_p,
+ contained_nonpublic_p, contained_nonvirtual_p): Adjust.
+ (__class_type_info::do_catch,
+ __class_type_info::do_upcast): Prepend __. Adjust.
+ (__class_type_info::__upcast_result,
+ __class_type_info::__dyncast_result): Move from inc/cxxabi.h.
+ Adjust.
+ (__class_type_info::find_public_src): Prepend __. Adjust.
+ (__class_type_info::do_find_public_src,
+ __si_class_type_info::do_find_public_src,
+ __vmi_class_type_info::do_find_public_src): Likewise.
+ (__class_type_info::do_dyncast,
+ __si_class_type_info::do_dyncast,
+ __vmi_class_type_info::do_dyncast): Likewise.
+ (__class_type_info::do_upcast,
+ __si_class_type_info::do_upcast,
+ __vmi_class_type_info::do_upcast): Likewise.
+ (__dynamic_cast): Adjust.
+ * tinfo2.cc (__pointer_type_info::is_pointer_p): Prepend __.
+ (__function_type_info::is_function_p): Likewise.
+ (__pointer_type_info::do_catch): Likewise. Adjust.
+ (__pointer_to_member_type_info::do_catch): Likewise. Adjust.
+ (__throw_type_match_rtti_2): Adjust.
+ (__is_pointer): Adjust.
+
+2000-04-08 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_tree_index): Add CPTI_COMPLETE_CTOR_IDENTIFIER.
+ (complete_ctor_identifier): New macro.
+ (special_function_kind): Add sfk_copy_constructor and
+ sfk_assignment_operator.
+ (LOOKUP_HAS_IN_CHARGE): Remove.
+ (cons_up_default_function): Rename to ...
+ (implicitly_declare_fn): ... this.
+ * call.c (build_new_method_call): Add in-charge parameters for
+ constructors here.
+ * class.c (add_implicitly_declared_members): Change parameter name
+ from cant_have_assignment to cant_have_const_assignment.
+ Replace calls to cons_up_default_function to implicitly_declare_fn.
+ * cvt.c (ocp_convert): Use complete_ctor_identifier.
+ * decl.c (initialize_predefined_identifiers): Initialize it.
+ (start_function): Use DECL_CONSTRUCTOR_FOR_VBASE_P instead of
+ complex expression.
+ * init.c (expand_default_init): Don't calculate the in-charge
+ parameter here.
+ (build_new_1): Likewise.
+ * lex.c (cons_up_default_function): Move to method.c.
+ * method.c (synthesize_method): Use DECL_DESTRUCTOR_P.
+ (implicitly_declare_fn): New function.
+ * typeck.c (build_static_cast): Use complete_ctor_identifier.
+ (build_modify_expr): Likewise.
+ * typeck2.c (build_functional_cast): Likewise.
+
+ Under the new ABI, constructors don't return `this'.
+ * cp-tree.h (warn_reorder): Declare.
+ (special_function_kind): New enum.
+ (global_base_init_list): Remove declaration.
+ (emit_base_init): Don't return a value.
+ (check_base_init): Don't declare.
+ (is_aggr_typedef): Likewise.
+ * decl.c (check_special_function_return_type): New function.
+ (return_types): Remove.
+ (grokdeclarator): Use check_special_function_return_type.
+ (start_function): Don't initialize ctor_label under the new ABI.
+ (finish_construtor_body): Don't create a corresponding LABEL_STMT.
+ * init.c (begin_init_stmts): Move to top of file.
+ (finish_init_stmts): Likewise.
+ (warn_reorder): Don't declare.
+ (emit_base_init): Don't create a STMT_EXPR here. Don't return a
+ value.
+ (check_base_init): Remove.
+ (is_aggr_typedef): Likewise.
+ (build_new_1): Don't use the return value of a constructor.
+ * semantics.c (setup_vtbl_ptr): Don't use the return value
+ of emit_base_init.
+ * typeck.c (check_return_expr): Don't magically convert return
+ statements into `return this' in constructors under the new ABI.
+
+ * cp-tree.h (cp_tree_index): Add CPTI_BASE_CTOR_IDENTIFIER,
+ CPTI_BASE_DTOR_IDENTIFIER, and CPTI_DELETING_DTOR_IDENTIFIER.
+ (base_ctor_identifier): New macro.
+ (base_dtor_identifier): Likewise.
+ (deleting_dtor_identifier): Likewise.
+ * decl.c: Don't include obstack.h.
+ (obstack_chunk_alloc): Don't define.
+ (obstack_chunk_free): Likewise.
+ (struct predefined_identifier): New type.
+ (initialize_predefined_identifiers): New function.
+ (init_decl_processing): Use it.
+ (debug_temp_inits): Remove.
+ (start_method): Don't call preserve_data.
+ (hack_incomplete_structures): Update comment.
+ * init.c (init_init_processing): Don't initialize
+ nelts_identifier.
+ (build_offset_rf): Remove dead code.
+ (build_delete): Use CLASSTYPE_N_BASECLASSES.
+ * search.c (init_search_processing): Don't initialize
+ vptr_identifier.
+
+2000-04-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * typeck.c (build_binary_op): Call `tree_expr_nonnegative_p' to elide
+ some sign_compare warnings.
+
+2000-04-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ Rename abi::__vmi_class_type_info members.
+ * inc/cxxabi.h (__vmi_class_type_info): Rename details, n_bases,
+ base_list, detail_masks members to vmi_flags, vmi_base_count,
+ vmi_bases and vmi_flags_masks respectively.
+ (__vmi_class_type_info::vmi_flags_masks): Rename
+ details_unknown_mask to flags_unknown_mask.
+ * tinfo.cc (__class_type_info::do_upcast): Adjust.
+ (__vmi_class_type_info::do_find_public_src): Adjust.
+ (__vmi_class_type_info::do_dyncast): Adjust.
+ (__vmi_class_type_info::do_upcast): Adjust.
+
+2000-04-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.cc (convert_to_base): New function.
+ (get_vbase_offset): Remove. Move into convert_to_base.
+ (__vmi_class_type_info::do_find_public_src): Adjust.
+ (__vmi_class_type_info::do_dyncast): Adjust.
+ (__vmi_class_type_info::do_upcast): Adjust.
+
+2000-04-06 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo.cc (operator=): Use __builtin_strcmp.
+ * tinfo2.cc (before): Likewise.
+
+2000-04-06 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Rename saved_inline to deferred.
+ (DECL_SAVED_INLINE): Rename to ...
+ (DECL_DEFERRED_FN): ... this.
+ (in_function_p): Remove declaration.
+ (mark_inline_for_output): Rename to ...
+ (defer_fn): ... this.
+ * decl.c (finish_function): Adjust call to mark_inline_for_output.
+ (in_function_p): Remove definition.
+ * decl2.c (saved_inlines): Rename to ...
+ (deferred_fns): ... this.
+ (saved_inlines_used): Rename to ...
+ (deferred_fns_used): ... this.
+ (mark_inline_for_output): Rename to ...
+ (defer_fn): ... this.
+ (finish_file): Adjust accordingly.
+ (init_decl2): Likewise.
+ * lex.c (cons_up_default_function): Likewise.
+ * pt.c (mark_decl_instantiated): Likewise.
+ (instantiate_decl): Don't set DECL_DEFER_OUTPUT under any
+ circumstances.
+ * rtti.c (get_tinfo_decl): Adjust call to mark_inline_for_output.
+ * semantics.c (expand_body): Defer more functions.
+
+2000-04-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.cc: New file.
+ * Make-lang.in (CXX_LIB2FUNCS): Add it.
+ (vec.o): Build it.
+ * inc/cxxabi.h (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
+ __cxa_vec_delete): Declare.
+
+2000-04-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (dfs_class_hint_mark): New static function.
+ (dfs_class_hint_unmark): New static function.
+ (class_hint_flags): Use them.
+
+2000-04-05 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * decl2.c: Make flag_honor_std dependent on ENABLE_STD_NAMESPACE.
+
+2000-04-05 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (instantiate_decl): Change prototype.
+ * decl2.c (mark_used): Adjust call.
+ * optimize.c (inlinable_function_p): Adjust handling of templates.
+ * pt.c (do_decl_instantiation): Adjust call to instantiate_decl.
+ (do_type_instantiation): Likewise.
+ (instantiate_decl): Defer more templates.
+ (instantiate_pending_templates): Adjust logic to handle inline
+ friend functions.
+
+ * Makefile.in (GGC_H): New variable. Use it throughout in place
+ of ggc.h.
+
+ * call.c: Don't include obstack.h. Include ggc.h.
+ (obstack_chunk_alloc): Don't define.
+ (obstack_chunk_free): Likewise.
+ (add_candidate): Allocate the z_candidate with ggc_alloc_obj.
+ * decl.c (push_switch): Use xmalloc to allocate the cp_switch.
+ (pop_switch): Free it.
+
+ * decl2.c (grokclassfn): Set TREE_READONLY for PARM_DECLs.
+
+ * dump.c (dequeue_and_dump): Don't try to print the bit_position
+ if we don't have a DECL_FIELD_OFFSET.
+
+Wed Apr 5 15:12:18 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * optimize.c (calls_setjmp_r): Use setjmp_call_p instead of
+ special_function_p.
+
+2000-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cfns.gperf (hash, libc_name_p): Prototype.
+
+ * rtti.c (build_dynamic_cast_1): Constification.
+
+ * search.c (dfs_debug_unmarkedp, dfs_debug_mark): Unhide prototypes.
+
+ * semantics.c (deferred_type_access_control): Prototype.
+
+2000-04-04 Mark Mitchell <mark@codesourcery.com>
+
+ Correct many new ABI issues regarding vbase and vcall offset
+ layout.
+ * cp-tree.h (BINFO_VTABLE): Document.
+ (struct lang_type): Tweak formatting.
+ (BINFO_PRIMARY_BINFO): Add to documentation.
+ (CLASSTYPE_VSIZE): Fix typo in comment.
+ (CLASSTYPE_VBASECLASSES): Update documentation.
+ (BINFO_VBASE_MARKED): Remove.
+ (SET_BINFO_VBASE_MARKED): Likewise.
+ (CLEAR_BINFO_VBASE_MARKED): Likewise.
+ (BINFO_FIELDS_MARKED): Remove.
+ (SET_BINFO_FIELDS_MARKED): Likewise.
+ (CLEAR_BINFO_FIELDS_MARKED): Likewise.
+ (enum access_kind): New enumeration.
+ (num_extra_vtbl_entries): Remove declaration.
+ (size_extra_vtbl_entries): Likewise.
+ (get_vtbl_decl_for_binfo): New function.
+ (dfs_vbase_unmark): Remove declaration.
+ (mark_primary_bases): Likewise.
+ * class.c (SAME_FN): Remove.
+ (struct vcall_offset_data_s): Move definition.
+ (build_vbase_pointer): Use `build', not `build_binary_op', to
+ access the vbase pointer under the new ABI.
+ (build_vtable_entry_ref): Use get_vtbl_decl_for_binfo.
+ (build_primary_vtable): Likewise.
+ (dfs_mark_primary_bases): Move here from search.c.
+ (mark_primary_bases): Likewise.
+ (determine_primary_bases): Under the new ABI, don't make a base
+ class a primary base just because we don't yet have any virtual
+ functions.
+ (layout_vtable_decl): Use get_vtbl_decl_for_binfo.
+ (num_vfun_entries): Remove.
+ (dfs_count_virtuals): Likewise.
+ (num_extra_vtbl_entries): Likewise.
+ (size_extra_vtbl_entries): Likewise.
+ (layout_virtual_bases): Iterate in inheritance graph order under
+ the new ABI.
+ (finish_struct_1): Use TYPE_VFIELD, not CLASSTYPE_VSIZE, to
+ indicate that a vfield is present.
+ (init_class_processing): Initialize access_public_node, etc., from
+ ak_public, etc.
+ (get_vtbl_decl_for_binfo): New function.
+ (dump_class_hierarchy_r): Likewise.
+ (dump_class_hierarchy): Use it.
+ (finish_vtbls): Build the vtbls in inheritance graph order.
+ (dfs_finish_vtbls): Adjust call to build_vtbl_initializer.
+ (initialize_vtable): Use get_vtbl_decl_for_binfo.
+ (accumulate_vtbl_inits): Add comments explaining why a pre-order
+ walk is required.
+ (dfs_accumulate_vtbl_inits): Set BINFO_VTABLE to the location
+ where the vptr points, even for primary vtables.
+ (build_vtbl_initializer): Adjust handling of vbase and vcall
+ offsets.
+ (build_vcall_and_vbase_vtable_entries): New function.
+ (dfs_build_vbase_offset_vtbl_entries): Remove.
+ (build_vbase_offset_vtbl_entries): Reimplement.
+ (dfs_build_vcall_offset_vtbl_entries): Don't include virtuals that
+ were already handled in a primary base class vtable.
+ (build_vcall_offset_vtbl_entries): Adjust.
+ (build_rtti_vtbl_entries): Adjust.
+ * decl2.c (output_vtable_inherit): Use get_vtbl_decl_for_binfo.
+ * init.c (expand_virtual_init): Simplify.
+ * repo.c (repo_get_id): Use get_vtbl_decl_for_binfo.
+ * rtti.c (create_pseudo_type_info): Adjust calculation of vptr.
+ * search.c (BINFO_ACCESS): New macro.
+ (SET_BINFO_ACCESS): Likewise.
+ (dfs_access_in_type): Manipulate access_kinds, not access nodes.
+ (access_in_type): Likewise.
+ (dfs_accessible_p): Likewise.
+ (protected_accessible_p): Likewise.
+ (lookup_fnfields_1): Adjust documentation.
+ (dfs_mark_primary_bases): Move to class.c
+ (mark_primary_bases): Likewise.
+ (dfs_vbase_unmark): Remove.
+ (virtual_context): Use BINFO_FOR_VBASE.
+ (dfs_get_vbase_types): Simplify.
+ (dfs_build_inheritance_graph_order): New function.
+ (get_vbase_types): Use it.
+ * tree.c (debug_binfo): Use get_vtbl_decl_for_binfo.
+
+ * tinfo.cc (get_vbase_offset): New function.
+ (__vmi_class_type_info::do_find_public_src): Use it.
+ (__vmi_class_type_info::do_dyncast): Likewise.
+ (__vmi_class_type_info::do_upcast): Likewise.
+
+2000-04-03 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Pass -fno-show-column to the preprocessor.
+
+2000-03-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (class_hint_flags): Rename flags.
+ (class_initializer): Remove flags.
+ (synthesize_tinfo_var): Combine offset and flags. Add flags
+ for __vmi_class_type_info.
+ (create_tinfo_types): Remove flags from __class_type_info and
+ __si_class_type_info. Merge flags and offset from
+ base_class_type_info.
+ * inc/cxxabi.h (__base_class_info): Merge offset and vmi_flags.
+ (__base_class_info::is_virtual_p): Adjust.
+ (__base_class_info::is_public_p): Adjust.
+ (__base_class_info::offset): New accessor.
+ (__class_type_info::details): Remove member.
+ (__class_type_info::__class_type_info): Lose details.
+ (__class_type_info::detail_masks): Remove.
+ (__si_class_type_info::__si_class_type_info): Lose details.
+ (__vmi_class_type_info::details): New member.
+ (__vmi_class_type_info::__vmi_class_type_info): Adjust.
+ (__vmi_class_type_info::detail_masks): New member.
+ * tinfo.cc (__class_type_info::do_upcast): Initialize result
+ with unknown_details_mask.
+ (__vmi_class_type_info::do_find_public_src): Adjust
+ (__vmi_class_type_info::do_dyncast): Adjust.
+ (__vmi_class_type_info::do_upcast): Set result details, if
+ needed. Adjust.
+ (__dynamic_cast): Temporarily #if out optimization.
+
+2000-03-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (get_tinfo_decl): Mark used.
+ (emit_tinfo_decl): Don't optimize polymorphic type_info. Only
+ mark as dealt with, if we output it.
+
+2000-03-28 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c: Reorganize to put virtual function table initialization
+ machinery at the end of the file.
+
+2000-03-28 Jason Merrill <jason@casey.cygnus.com>
+
+ * class.c (finish_struct): Use bitsize_zero_node.
+ * pt.c (instantiate_class_template): Likewise.
+
+2000-03-28 Mark Mitchell <mark@codesourcery.com>
+
+ Put RTTI entries at negative offsets in new ABI.
+ * class.c (dfs_build_vbase_offset_vtbl_entries): Put the first
+ vbase offset at index -3, not -1.
+ (build_vtabe_offset_vtbl_entries): Use unmarked_vtable_pathp, not
+ dfs_vtable_path_unmarked_real_bases_queue_p to walk bases.
+ (dfs_build_vcall_offset_vtbl_entries): Don't use skip_rtti_stuff.
+ (build_rtti_vtbl_entries): New function.
+ (set_rtti_entry): Remove.
+ (build_primary_vtable): Don't use it.
+ (build_secondary_vtable): Likewise.
+ (start_vtable): Remove.
+ (first_vfun_index): New function.
+ (set_vindex): Likewise.
+ (add_virtual_function): Don't call start_vtable. Do call
+ set_vindex.
+ (set_primary_base): Rename parameter.
+ (determine_primary_base): Likewise.
+ (num_vfun_entries): Don't use skip_rtti_stuff.
+ (num_extra_vtbl_entries): Include RTTI information.
+ (build_vtbl_initializer): Use build_rtti_vtbl_entries.
+ (skip_rtti_stuff): Remove.
+ (dfs_modify_vtables): Don't use it.
+ (modify_all_vtables): Don't use start_vtable. Do use set_vindex.
+ (layout_nonempty_base_or_field): Update size handling.
+ (create_vtable_ptr): Tweak.
+ (layout_class_type): Adjust parameter names.
+ (finish_struct_1): Simplify.
+ * cp-tree.h (CLASSTYPE_VSIZE): Tweak documentation.
+ (skip_rtti_stuff): Remove.
+ (first_vfun_index): New function.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
+ (dfs_vtable_path_marked_real_bases_queue_p): Remove.
+ (marked_vtable_pathp): Declare.
+ (unmarked_vtable_pathp): Likewise.
+ * error.c (dump_expr): Use first_vfun_index to calculate vtable
+ offsets.
+ * rtti.c (build_headof): Look for RTTI at negative offsets.
+ (get_tinfo_decl_dynamic): Likewise.
+ (tinfo_base_init): Don't take the address of the TINFO_VTABLE_DECL
+ here.
+ (create_pseudo_type_info): Do it here instead. Adjust so that
+ vptr points at first virtual function.
+ * search.c (marked_vtable_pathp): Make it global.
+ (unmarked_vtable_pathp): Likewise.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
+ (dfs_vtable_path_marked_real_bases_queue_p): Likewise.
+ (dfs_get_pure_virtuals): Don't use skip_rtti_stuff.
+ (get_pure_virtuals): Likewise.
+ (expand_upcast_fixups): Likewise.
+ * tree.c (debug_binfo): Likewise.
+ * tinfo.cc (__dynamic_cast): Look for vtable_prefix at appropriate
+ negative offset.
+
+2000-03-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (check_field_decl): Fix typo.
+ (build_vtbl_or_vbase_field): Don't clear DECL_SAVED_INSNS.
+ (check_methods): Likewise.
+ (check_field_decls): Likewise.
+ Use DECL_CONTEXT, not DECL_FIELD_CONTEXT.
+ * cp-tree.h (DECL_SHADOWED_FOR_VAR, DECL_TEMPLATE_RESULT):
+ Use DECL_RESULT_FLD, not DECL_RESULT.
+ * decl.c (xref_tag): Use DECL_TEMPLATE_RESULT.
+ * lex.c (identifier_type): Likewise.
+ * pt.c (determine_specialization, lookup_template_class): Likewise.
+ (tsubst_friend_function, tsubst_decl, instantiate_template): Likewise.
+ (resolve_overloaded_unification, more_specialized): Likewise.
+ * semantics.c (finish_member_declaration): Likewise.
+ * typeck.c (build_x_function_call): Likewise.
+
+2000-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_empty_base): Handle empty bases with non-byte
+ alignment.
+ (build_base_field): Likewise.
+ (layout_virtual_bases): Likewise.
+
+ * class.c (finish_struct_1): Fix typo in this change:
+
+ Sat Mar 25 09:12:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+2000-03-25 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokdeclarator): Count partial specializations when
+ keeping track of how many template classes have been seen.
+
+ * dump.c (dequeue_and_dump): Dump DECL_TEMPLATE_RESULT.
+
+2000-03-25 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_vbase_pointer_fields): layout_field now place_field.
+ (get_vfield_offset): Use byte_position.
+ (set_rtti_entry): Set OFFSET to ssizetype zero.
+ (get_binfo_offset_as_int): Deleted.
+ (dfs_record_base_offsets): Use tree_low_cst.
+ (dfs_search_base_offsets): Likewise.
+ (layout_nonempty_base_or_field): Reflect changes in RLI format
+ and call byte_position.
+ (layout_empty_base): Convert offset to ssizetype.
+ (build_base_field): use rli_size_unit_so_far.
+ (dfs_propagate_binfo_offsets): Do computation in proper type.
+ (layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
+ (layout_class_type): Reflect changes in RLI names and fields.
+ (finish_struct_1): Set DECL_FIELD_OFFSET.
+ * dump.c (dequeue_and_dump): Call bit_position.
+ * expr.c (cplus_expand_constant): Use byte_position.
+ * rtti.c (expand_class_desc): Use bitsize_one_node.
+ * typeck.c (build_component_addr): Use byte_position and don't
+ special case for zero offset.
+
+2000-03-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (vtype_decl_p): Use TYPE_POLYMORPHIC_P.
+
+ * rtti.c (get_tinfo_decl): Set comdat linkage on new-abi
+ tinfo object.
+ (emit_tinfo_decl): Only emit polymorphic tinfo's when emitting
+ vtable.
+
+2000-03-20 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * call.c (check_dtor_name, build_new_method_call): Use TYPE_P and
+ DECL_P macros.
+ * decl.c (push_class_binding, poplevel, pushtag, lookup_namespace_name,
+ make_typename_type, check_initializer, cp_finish_decl,
+ xref_tag): Likewise.
+ * decl2.c (grokfield, build_expr_from_tree, build_expr_from_tree,
+ decl_namespace, arg_assoc_template_arg, arg_assoc,
+ validate_nonmember_using_decl, do_class_using_decl): Likewise.
+ * error.c (dump_template_argument, dump_expr, cp_file_of, cp_line_of,
+ args_to_string): Likewise.
+ * friend.c (is_friend): Likewise.
+ * lex.c (note_got_semicolon, note_list_got_semicolon,
+ is_global): Likewise.
+ * method.c (build_overload_nested_name, build_overload_value,
+ build_qualified_name, build_qualified_name, hack_identifier): Likewise.
+ * parse.y (typename_sub, typename_sub1): Likewise.
+ * pt.c (push_inline_template_parms_recursive, check_template_shadow,
+ process_partial_specialization, convert_template_argument,
+ template_args_equal, add_pending_template, lookup_template_class,
+ for_each_template_parm_r, maybe_fold_nontype_arg,
+ tsubst, instantiate_template, type_unification_real, unify,
+ instantiate_pending_templates, set_mangled_name_for_template_decl):
+ Likewise.
+ * repo.c (repo_get_id, repo_template_used): Likewise.
+ * search.c (lookup_field_1): Likewise.
+ * tree.c (walk_tree, get_type_decl, cp_tree_equal, member_p): Likewise.
+ * xref.c (classname): Likewise.
+
+2000-03-22 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BINFO_FOR_VBASE): Adjust documentation.
+ (CANONICAL_BINFO): New macro.
+ (BINFO_NEW_VTABLE_MARKED): Use it.
+ (SET_BINFO_NEW_VTABLE_MARKED): Likewise.
+ (CLEAR_BINFO_NEW_VTABLE_MARKED): Likewise.
+ * class.c (dfs_build_vbase_offset_vtbl_entries): Use BINFO_TYPE,
+ not TREE_TYPE.
+ (build_primary_vtable): Adjust usage of BINFO_NEW_VTABLE_MARKED.
+ (build_secondary_vtable): Likewise.
+ (dfs_finish_vtbls): Likewise.
+ (dfs_accumulate_vtbl_inits): Likewise.
+ (accumulate_vtbl_inits): New function.
+ (finish_vtbls): Make sure that virtual bases come after
+ non-virtual bases in the vtable group.
+ (record_base_offsets): Don't save and restore TREE_VIA_VIRTUAL.
+ (finish_struct_1): Adjust usage of BINFO_NEW_VTABLE_MARKED.
+ * search.c (struct vbase_info): Move definition.
+ (marked_new_vtable_p): Adjust usage of BINFO_NEW_VTABLE_MARKED.
+ (unmarked_new_vtable_p): Likewise.
+ (dfs_mark_vtable_path): Remove.
+ (dfs_mark_new_vtable): Remove.
+ (dfs_unmark_new_vtable): Likewise.
+ (dfs_clear_search_slot): Likewise.
+ (dfs_find_vbases): Adjust usage of BINFO_NEW_VTABLE_MARKED.
+ (dfs_clear_vbase_slots): Likewise.
+ (init_vbase_pointers): LIkewise.
+
+2000-03-22 Jason Merrill <jason@casey.cygnus.com>
+
+ * typeck.c (type_after_usual_arithmetic_conversions): Prefer a
+ SIZETYPE to a non-SIZETYPE.
+
+2000-03-21 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_virtual_bases): Adjust names in conditionally
+ compiled code.
+
+ * class.c (record_base_offsets): New function.
+ (layout_conflict_p): Likewise.
+ (layout_nonempty_base_or_field): Use it.
+ (layout_empty_base): New function.
+ (build_base_field): Use it.
+ (build_base_fields): Update comment.
+ (layout_virtual_bases): Fold in a little code form
+ layout_basetypes. Use layout_empty_base.
+ (layout_basetypes): Remove.
+ (end_of_class): New function.
+ (layout_class_type): Use it. Adjust.
+
+ * cp-tree.h (CLASSTYPE_VBASECLASSES): Fix typo in comment.
+ (fntype_p): Remove.
+ * search.c (dfs_skip_nonprimary_vbases_unmarkedp): Fix typo in
+ comment.
+ (dfs_skip_nonprimary_vbases_markedp): Likewise.
+ * typeck.c (fntype_p): Remove.
+
+ * cp-tree.h (TI_SPEC_INFO): Remove.
+ (CLASSTYPE_TI_SPEC_INFO): Likewise.
+ * pt.c (process_partial_specialization): Likewise.
+
+ * class.c (build_base_field): Fix thinko in computation of binfo
+ offsets.
+
+ * tree.c (mark_local_for_remap_p): Mark variables declared in
+ TARGET_EXPRs as well.
+
+2000-03-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (require_complete_type, complete_type,
+ complete_type_or_else, c_sizeof, c_sizeof_nowarn,
+ build_array_ref, convert_arguments, pointer_diff,
+ build_x_unary_op, build_unary_op, build_c_cast,
+ build_modify_expr): Use COMPLETE_TYPE_P etc.
+ * call.c (is_complete, convert_like_real,
+ build_new_method_call): Likewise.
+ * class.c (build_vbase_pointer_fields, check_bases,
+ build_base_field, finish_struct_1, pushclass): Likewise.
+ * cvt.c (cp_convert_to_pointer, convert_to_void): Likewise.
+ * decl.c (maybe_process_template_type_declaration, pushtag,
+ pushdecl, redeclaration_error_message, start_decl, start_decl_1,
+ layout_var_decl, check_initializer, cp_finish_decl,
+ grokdeclarator, require_complete_types_for_parms,
+ grok_op_properties, xref_tag, xref_basetypes,
+ check_function_type): Likewise.
+ * decl2.c (check_classfn, reparse_absdcl_as_casts): Likewise.
+ * friend.c (do_friend): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ * parse.y (structsp): Likewise.
+ * pt.c (maybe_process_partial_specialization,
+ tsubst_friend_function, instantiate_class_template, tsubst,
+ do_type_instantiation, instantiate_pending_templates): Likewise.
+ * repo.c (repo_get_id): Likewise.
+ * rtti.c (build_typeid, get_typeid, build_dynamic_cast_1,
+ synthesize_tinfo_var, emit_support_tinfos): Likewise.
+ * search.c (lookup_fnfields_1, lookup_conversions): Likewise.
+ * semantics.c (begin_class_definition): Likewise.
+ * tree.c (build_cplus_method_type): Likewise.
+ * typeck2.c (digest_init, build_functional_cast,
+ add_exception_specifier): Likewise.
+ * parse.h, parse.c: Regenerated.
+
+2000-03-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ * inc/cxxabi.h: New header file. Define new-abi entry points.
+ (__pointer_type_info::target): Rename member to ...
+ (__pointer_type_info::type): ... here.
+ (__base_class_info::type): Rename member to ...
+ (__base_class_info::base): ... here.
+ * Make-lang.in (CXX_EXTRA_HEADERS): Add cxxabi.h
+ * cp-tree.h (CPTI_ABI): New global tree enumeration.
+ (abi_node): New global tree node.
+ * decl.c (abi_node): Document.
+ (init_decl_processing): Initialize abi_node.
+ * rtti.c (build_dynamic_cast_1): Use abi_node for new-abi.
+ (get_vmi_pseudo_type_info): Likewise.
+ (create_tinfo_types): Likewise.
+ (emit_support_tinfos): Likewise.
+ * tinfo.h (cxxabi.h): Include for new-abi.
+ Move rtti class definitions to new header file.
+ * tinfo.cc (abi): Use the namespace.
+ (std): Move new abi rtti classes from here ...
+ (__cxxabiv1): ... to here.
+ * tinfo2.cc (cxxabi.h): Include for new-abi.
+ Move rtti class definitions to new header file.
+ (std): Move new abi rtti classes from here ...
+ (__cxxabiv1): ... to here.
+ * inc/typeinfo (__class_type_info): Move into __cxxabiv1
+ namespace.
+
+2000-03-20 Jed Wing <jedwin@zloty.ugcs.caltech.edu>
+ Jason Merrill <jason@casey.cygnus.com>
+
+ * method.c (build_overload_int): Use host_integerp.
+
+2000-03-20 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * init.c (build_offset_ref): Handle the case of a templated member
+ function.
+
+2000-03-19 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * except.c (expand_exception_blocks): Clear catch_clauses_last.
+
+2000-03-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLEAR_DECL_C_BIT_FIELD): New macro.
+ * class.c (check_bitfield_decl): Turn illegal bitfields into
+ non-bitfields.
+ (dfs_propagate_binfo_offsets): Adjust for new size_binop
+ semantics.
+ (dfs_offset_for_unshared_vbases): Likewise.
+ * cvt.c (cp_convert_to_pointer): Convert NULL to a
+ pointer-to-member correctly under the new ABI.
+ * expr.c (cplus_expand_constant): Don't use cp_convert when
+ turning an offset into a pointer-to-member.
+ * init.c (resolve_offset_ref): Don't adjust pointers-to-members
+ when dereferencing them under the new ABI.
+ * typeck.c (get_member_function_from_ptrfunc): Tweak calculation
+ of pointers-to-members under the new ABI.
+
+ * class.c (check_bitfield_decl): Remove restriction on really long
+ bitfields.
+ (layout_class_type): Implement new ABI handling of bitfields
+ longer than their types.
+
+2000-03-18 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * parse.y (extdefs): Call ggc_collect.
+ * parse.c: Regenerated.
+
+2000-03-18 Nathan Sidwell <nathan@codesourcery.com>
+
+ * class.c (build_base_field): Use TYPE_ALIGN to examine a type.
+ (note_name_declared_in_class): Use OVL_CURRENT to get at a
+ potential overload.
+
+2000-03-17 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_vbase_path): Use integer_zerop.
+ (build_vtable_entry): Use tree_low_cst.
+ (get_vfield_offset): Use bit_position.
+ (dfs_modify_vtables): New variable vindex_val; `i' is HOST_WIDE_INT.
+ Use tree_low_cst.
+ (check_bitfield_decl): Set DECL_SIZE using convert.
+ (build_base_field): Set DECL_SIZE and DECL_SIZE_UNIT using size_binop.
+ (layout_virtual_bases): DSIZE is unsigned HOST_WIDE_INT.
+ Use tree_low_cst.
+ (finish_struct_1): Use bit_position.
+ (dump_class_hierarchy): Use tree_low_cst.
+ * cp-tree.h (min_precision): Add declaration.
+ * decl.c (xref_tag, xref_basetypes): Use tree_low_cst.
+ * error.c (dump_type_suffix): Use host_integerp and tree_low_cst.
+ (dump_expr): Use integer_zerop, host_integerp, and tree_low_cst.
+ * expr.c (cplus_expand_constant): Use bit_position.
+ * init.c (build_vec_init): Use host_integerp and tree_low_cst.
+ * rtti.c (get_base_offset): Use bit_position.
+ * typeck.c (build_binary_op): Use integer_zerop, compare_tree_int,
+ host_integerp, and tree_low_cst.
+ (pointer_int_sum): Use integer_zerop.
+ (build_component_addr): Use bit_position.
+
+2000-03-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (require_complete_type): Don't assume size_zero_node.
+ (complete_type_or_else): Likewise.
+
+2000-03-16 Steven Grady <grady@digitaldeck.com>
+ Jason Merrill <jason@casey.cygnus.com>
+
+ * rtti.c (build_dynamic_cast_1): Improve diagnostics.
+
+2000-03-16 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl2.c (grokfield): Bail out if type is error_mark_node.
+
+2000-03-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo2.cc (__ptr_to_member_data): Rename to ...
+ (__pointer_to_member_data): ... here. Adjust.
+ * rtti.c (create_tinfo_types): Adjust.
+
+2000-03-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * cp-tree.h (CPTI_REF_DESC_TYPE, ref_desc_type_node): Remove.
+ * decl.c (ref_desc_type_node): Undocument.
+ * rtti.c (ptr_ref_initializer): Rename to ...
+ (ptr_initializer): ... here. Adjust comments.
+ (ptmd_initializer): Fix comment thinko.
+ (synthesize_tinfo_var): Remove REFERENCE_TYPE case.
+ (create_tinfo_types): Remove ref_desc_type_node init.
+ * tinfo2.cc (__reference_type_info): Remove.
+
+2000-03-15 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Remove obsolete comment.
+
+ * typeck.c (build_ptrmemfunc1): Kill uninitialized warning.
+
+2000-03-14 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h: Tweak documentation.
+ * class.c (build_vbase_pointer_fields): Layout the fields, too.
+ (avoid_overlap): Remove.
+ (get_binfo_offset_as_int): New function.
+ (dfs_serach_base_offsets): Likewise.
+ (layout_nonempty_base_or_field): Likewise.
+ (build_base_field): Layout fields here. Avoid placing two objects
+ of the same type at the same address, under the new ABI.
+ (build_base_fields): Adjust accordingly.
+ (create_vtable_ptr): Return the new field, but don't attach it to
+ TYPE_FIELDS.
+ (remove_base_field): Remove.
+ (remove_base_fields): Remove.
+ (layout_basetypes): Adjust accordingly.
+ (layout_class_type): Call layout_field for each field, rather than
+ just making a wholesale call to layout_type.
+
+2000-03-14 Jeff Sturm <jsturm@sigma6.com>
+
+ * except.c (expand_throw): Fix typo in _Jv_Sjlj_Throw.
+
+2000-03-13 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (grokfndecl): Set TREE_NOTHROW if TYPE_NOTHROW_P.
+
+ * except.c (dtor_nothrow): New fn.
+ (do_pop_exception): Use it. Take type parm.
+ (push_eh_cleanup): Take type parm.
+ (expand_start_catch_block): Pass it.
+ (build_eh_type_type_ref): Accept null type.
+
+2000-03-12 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (revert_static_member_fn): Change prototype.
+ * decl.c (grokfndecl): Adjust call to revert_static_member_fn.
+ (grok_op_properties): Likewise.
+ (start_function): Likewise.
+ (revert_static_member_fn): Simplify.
+ * pt.c (check_explicit_specialization): Adjust call to
+ revert_static_member_fn.
+
+2000-03-11 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (scope_kind): New type.
+ (tmpl_spec_kind): Likewise.
+ (declare_pseudo_global_level): Remove.
+ (pseudo_global_level_p): Rename to template_parm_scope_p.
+ (pushlevel): Remove declaration.
+ (begin_scope): New function.
+ (finish_scope): Likewise.
+ (current_tmpl_spec_kind): Likewise.
+ * decl.c (struct binding_level): Shorten parm_flag to 2 bits.
+ Shorten keep to 2 bits. Rename pseudo_global to template_parms_p.
+ Add template_spec_p.
+ (toplevel_bindings_p): Adjust.
+ (declare_pseudo_global_level): Remove.
+ (pseudo_global_level_p): Rename to template_parm_scope_p.
+ (current_tmpl_spec_kind): New function.
+ (begin_scope): Likewise.
+ (finish_scope): Likewise.
+ (maybe_push_to_top_level): Adjust.
+ (maybe_process_template_type_declaration): Likewise.
+ (pushtag): Likewise.
+ (pushdecl_nonclass_level): Likewise.
+ (lookup_tag): Likewise.
+ (grokfndecl): Handle member template specializations. Share
+ constructor and non-constructor code.
+ * decl2.c (check_classfn): Handle member template specializations.
+ * pt.c (begin_template_parm_list): Use begin_scope.
+ (begin_specialization): Likewise.
+ (end_specialization): Likewise.
+ (check_explicit_specialization): Use current_tmpl_spec_kind.
+ Handle member template specializations.
+ (end_template_decl): Use finish_scope. Remove call to
+ get_pending_sizes.
+ (push_template_decl_real): Remove bogus error message.
+ (tsubst_decl): Fix typo in code contained in comment.
+ (instantiate_template): Handle member template specializations.
+ (most_general_template): Likewise.
+
+2000-03-11 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * lex.c (whitespace_cr): Compress consecutive calls to warning().
+ (do_identifier): Ditto for error().
+
+ * pt.c (convert_nontype_argument): Ditto for cp_error().
+ (convert_template_argument): Ditto for cp_pedwarn().
+
+2000-03-11 Jason Merrill <jason@casey.cygnus.com>
+
+ * exception.cc (__check_null_eh_spec): New fn.
+ * except.c (expand_end_eh_spec): Call it if the spec is throw().
+
+2000-03-10 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (push_throw_library_fn): Take the FUNCTION_TYPE.
+ * except.c (expand_end_eh_spec): Add the return type.
+ * rtti.c (throw_bad_cast): Add the parmtypes.
+ (throw_bad_typeid): Likewise.
+
+ * semantics.c (expand_stmt): Only leave out rtl for unused
+ artificials, and set DECL_IGNORED_P on them as well.
+ * decl.c (wrapup_globals_for_namespace): Likewise.
+
+2000-03-09 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (maybe_commonize_var): Skip all artificial decls.
+ * pt.c (tsubst_decl): Don't copy TREE_ASM_WRITTEN.
+
+2000-03-10 Jason Merrill <jason@casey.cygnus.com>
+
+ * lang-options.h, decl2.c: Add -fno-enforce-eh-specs.
+ * cp-tree.h: Declare flag_enforce_eh_specs.
+ * decl.c (store_parm_decls, finish_function): Check it.
+
+ C library functions don't throw.
+ * Makefile.in (cfns.h): New target.
+ (except.o): Depend on it.
+ * Make-lang.in (cc1plus): Depend on cfns.gperf.
+ * cfns.gperf: New file.
+ * cfns.h: Generated.
+ * except.c: Include it.
+ (nothrow_libfn_p): New fn.
+ * decl.c (grokfndecl): Use it.
+ * cp-tree.h: Declare it.
+
+ * decl.c (push_overloaded_decl_1, auto_function,
+ define_function): Lose.
+ (build_library_fn_1): New static fn.
+ (builtin_function): Use it.
+ (get_atexit_node): Use build_library_fn_ptr.
+ (build_library_fn, build_cp_library_fn, build_library_fn_ptr,
+ build_cp_library_fn_ptr, push_library_fn, push_cp_library_fn,
+ push_void_library_fn, push_throw_library_fn): New fns.
+ * cp-tree.h: Declare them.
+ (cp_tree_index): Remove CPTI_BAD_CAST, CPTI_BAD_TYPEID.
+ (throw_bad_cast_node, throw_bad_typeid_node): Lose.
+ * except.c (init_exception_processing, call_eh_info, do_pop_exception,
+ (expand_end_eh_spec, alloc_eh_object, expand_throw): Use above fns.
+ * rtti.c (build_runtime_decl): Lose.
+ (throw_bad_cast, throw_bad_typeid, get_tinfo_decl,
+ build_dynamic_cast_1, expand_si_desc, expand_class_desc,
+ expand_ptr_desc, expand_attr_desc, expand_generic_desc): Use above fns.
+
+ * call.c (build_call): Remove result_type parm.
+ Call mark_used on unused artificial fns.
+ * init.c, method.c, typeck.c, except.c, rtti.c: Adjust.
+
+2000-03-09 Jason Merrill <jason@casey.cygnus.com>
+
+ * call.c (build_call): Set TREE_NOTHROW on the CALL_EXPR as
+ appropriate.
+ * decl.c (define_function): Set TREE_NOTHROW on the FUNCTION_DECL.
+ * except.c (call_eh_info, alloc_eh_object, expand_throw): Set
+ TREE_NOTHROW or TREE_THIS_VOLATILE on the function as appropriate.
+ * rtti.c (build_runtime_decl, get_tinfo_decl, build_dynamic_cast_1,
+ expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc,
+ expand_generic_desc): Likewise.
+
+2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * exception.cc (__cp_pop_exception): Cleanup the original object.
+
+2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grok_op_properties): Merge conversion to void warning
+ with other silly op warnings.
+
+2000-03-08 Jason Merrill <jason@casey.cygnus.com>
+
+ * typeck2.c (process_init_constructor): Set TREE_PURPOSE of
+ array CONSTRUCTOR elements. Don't use expr_tree_cons.
+
+2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (cp_make_fname_decl): New function.
+ (wrapup_globals_for_namespace): Don't emit unused static vars.
+ (init_decl_processing): Remove comment about use of
+ array_domain_type. Set make_fname_decl.
+ (cp_finish_decl): Remove __FUNCTION__ nadgering.
+ * semantics.c (begin_compound_stmt): Remove
+ current_function_name_declared flagging.
+ (expand_stmt): Don't emit unused local statics.
+ * typeck.c (decay_conversion): Don't treat __FUNCTION__ decls
+ specially.
+
+2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (convert_for_assignment): Don't look at array
+ initializer.
+ * call.c (convert_like_real): Likewise.
+
+2000-03-07 Jason Merrill <jason@casey.cygnus.com>
+
+ Add initial support for '\uNNNN' specifier.
+ * lex.c (read_ucs): New fn.
+ (readescape, skip_white_space): Call it.
+ (is_extended_char, is_extended_char_1): New fns.
+ (utf8_extend_token): New fn, #if 0'd out.
+ (real_yylex): Treat extended chars like letters.
+
+ * search.c (note_debug_info_needed): Walk the bases even if we
+ weren't deferring the type itself.
+
+2000-03-07 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl2.c (finish_objects): Constify a char*.
+
+ * method.c (emit_thunk): Likewise.
+
+2000-03-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * typeck.c (dubious_conversion_warnings): Look through
+ REFERENCE_TYPE.
+
+2000-03-06 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (dfs_modify_vtables): I is now unsigned.
+ (check_bitfield_decl): Use tree_int_cst_sgn and compare_tree_int.
+ (build_base_field): Add casts of TREE_INT_CST_LOW to HOST_WIDE_INT.
+ * error.c (dump_expr): Cast TREE_INT_CST_HIGH to unsigned.
+ * init.c (build_vec_init): Cast TREE_INT_CST_LOW to HOST_WIDE_INT.
+ * method.c (build_overload_int): Cast TREE_INT_CST_HIGH to unsigned.
+ * typeck.c (build_binary_op, case TRUNC_DIV_EXPR):
+ Call integer_all_onesp.
+ * typeck2.c (process_init_constructor): Use compare_tree_int.
+
+ * lang-specs.h (as): Don't call if -syntax-only.
+
+2000-03-06 Mark Mitchell <mark@codesourcery.com>
+
+ * expr.c (cplus_expand_expr, case STMT_EXPR): Don't set
+ RTL_EXPR_HAS_NO_SCOPE after all.
+
+2000-03-05 Mark Mitchell <mark@codesourcery.com>
+
+ * expr.c (cplus_expand_expr, case STMT_EXPR): Use
+ expand_start_stmt_expr and expand_end_stmt_expr directly. Set
+ RTL_EXPR_HAS_NO_SCOPE.
+
+ * pt.c (instantiate_decl): Clear TI_PENDING_TEMPLATE_FLAG a little
+ later.
+
+ * dump.c (dequeue_and_dump): Dump SCOPE_NO_CLEANUPS_P.
+
+2000-03-05 Nathan Sidwell <nathan@codesourcery.com>
+
+ * call.c (convert_like): Macrofy.
+ (convert_like_with_context): New macro.
+ (convert_like_real): Renamed from convert_like. Add calling
+ context parameters, for diagnostics. Add recursive flag. Call
+ dubious_conversion_warnings for outer conversion.
+ (build_user_type_conversion): Use convert_like_with_context.
+ (build_over_call): Likewise. Don't warn about dubious
+ conversions here. Adjust convert_default_arg calls.
+ (convert_default_arg): Add context parameters for diagnostics.
+ Pass through to convert_like_with_context.
+ * cp-tree.h (convert_default_arg): Add context parameters.
+ (dubious_conversion_warnings): Prototype new function.
+ * typeck.c (convert_arguments): Adjust convert_default_arg call.
+ (dubious_conversion_warnings): New function, broken
+ out of convert_for_assignment.
+ (convert_for_assignment): Adjust.
+
+2000-03-03 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl2.c (key_method): Break out from...
+ (import_export_vtable, import_export_class): ...here.
+
+ * decl.c (finish_function): Don't mess with flag_keep_inline_functions.
+ * decl2.c (finish_vtable_vardecl): Don't check decl_function_context.
+
+ * search.c (note_debug_info_needed, dfs_debug_mark,
+ dfs_debug_unmarkedp): Uncomment. Adjust for new scheme.
+ * decl2.c (finish_vtable_vardecl): Call note_debug_info_needed.
+
+2000-03-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (cp_finish_decl): Remove obsolete obstack comments, fix
+ typos.
+
+2000-03-02 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (TYPE_NEEDS_DESTRUCTOR): Rename to ...
+ (TYPE_HAS_NONTRIVIAL_DESTRUCTOR): ... this.
+ (TYPE_HAS_TRIVIAL_DESTRUCTOR): New macro.
+ (lang_type): Split gets_new into has_new and has_array_new.
+ (TYPE_VEC_NEW_USES_COOKIE): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ (TYPE_GETS_NEW): Split into ...
+ (TYPE_HAS_NEW_OPERATOR): ... this, and ...
+ (TYPE_HAS_ARRAY_NEW_OPERATOR): ... this.
+ (DECL_ARRAY_DELETE_OPERATOR_P): New macro
+ (build_op_new_call): Don't declare.
+ (build_new_1): Likewise.
+ * call.c (build_op_new_call): Remove.
+ * class.c (check_bases): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR
+ instead of TYPE_NEEDS_DESTRUCTOR.
+ (finish_struct_bits): Likewise.
+ (add_implicitly_declared_members): Likewise.
+ (check_field_decl): Likewise.
+ (check_methods): Set TYPE_VEC_DELETE_TAKES_SIZE here, and set it
+ correctly under the new ABI.
+ * decl.c (start_decl_1): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR
+ instead of TYPE_NEEDS_DESTRUCTOR.
+ (initialize_local_var): Likewise.
+ (destroy_local_var): Likewise.
+ (cp_finish_decl): Likewise.
+ (register_dtor_fn): Likewise.
+ (grok_op_properties): Set TYPE_HAS_NEW_OPERATOR and
+ TYPE_HAS_ARRAY_NEW_OPERATOR, not TYPE_HAS_NEW. Don't set
+ TYPE_VEC_DELETE_TAKES_SIZE here.
+ (xref_basetypes): Set TYPE_HAS_NEW_OPERATOR and
+ TYPE_HAS_ARRAY_NEW_OPERATOR, not TYPE_HAS_NEW.
+ (store_parm_decls): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ (finish_destructor_body): Likewise.
+ (maybe_build_cleanup_1): Likewise.
+ * decl2.c (do_static_destruction): Likewise.
+ * init.c (build_new_1): Make it static.
+ (perform_member_init): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ (expand_cleanup_for_base): Likewise.
+ (get_cookie_size): New function.
+ (build_new_1): Handle array-new cookies correctly under the new
+ ABI.
+ (build_vec_delete_1): Likewise.
+ (build_vec_init): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ (build_delete): Likewise.
+ (build_vec_delete): Handle array-new cookies correctly under the new
+ ABI.
+ * lex.c (do_identifier): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ * pt.c (instantiate_class_template): Set TYPE_HAS_NEW_OPERATOR and
+ TYPE_HAS_ARRAY_NEW_OPERATOR.
+ * ptree.c (print_lang_type): Check them.
+ * search.c (context_for_name_lookup): Fix typo in comment.
+ (tree_has_any_destructor_p): Use TYPE_HAS_NONTRIVIAL_DESTRUCTOR.
+ * tree.c (break_out_cleanups): Likewise.
+ (build_cplus_array_test_1): Likewise.
+ (cp_build_qualified_type_real): Likewise.
+ * typeck.c (complete_type): Likewise.
+
+ * g++spec.c (lang_specific_driver): Add -fnew-abi at the start of
+ the command-line, not the end.
+
+2000-03-01 Jason Merrill <jason@casey.cygnus.com>
+
+ * pt.c (instantiate_decl): Clear TI_PENDING_TEMPLATE_FLAG.
+
+2000-03-02 Tom Tromey <tromey@cygnus.com>
+
+ * cp-tree.h (build_java_class_ref): Declare.
+ * init.c (build_java_class_ref): No longer static.
+ * except.c (expand_throw): Generate a Java-style `throw' if the
+ thrown object is a "Java" object.
+ (initialize_handler_parm): Generate a Java-style lookup of
+ exception info if the caught object is a "Java" object.
+ (catch_language, catch_language_init): New globals.
+ (decl_is_java_type): New function.
+ (expand_start_catch_block): Don't call push_eh_info() or
+ push_eh_cleanup() when handling a Java-style "catch". Pass Java
+ class reference to build_catch_block.
+
+2000-03-02 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * typeck.c (comptypes): Treat sizetype like its language equivalent.
+
+2000-03-01 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * typeck.c (maybe_warn_about_returning_address_of_local): Reorganize
+ to merge reference/pointer code and fix incorrect warnings.
+
+2000-02-29 Jason Merrill <jason@casey.cygnus.com>
+
+ * search.c (protected_accessible_p): Use context_for_name_lookup.
+
+ * init.c (construct_virtual_bases): Fix thinko.
+ * typeck.c (expand_ptrmemfunc_cst): Fix thinko.
+
+2000-03-01 Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (current_function_decl): Move to toplev.c.
+
+2000-02-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * pt.c (fn_type_unification): Unify return type, whenever
+ provided.
+ (get_bindings_real): Only pass return type when necessary.
+ Remove explicit return type check.
+ * class.c (resolve_address_of_overloaded_function): Pass desired
+ return type to fn_type_unification.
+
+2000-02-28 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_vtbl_or_vbase_field, check_methods): Don't clear
+ DECL_FIELD_SIZE.
+ (check_bitfield_decl, check_field_decls): Set DECL_SIZE, not
+ DECL_FIELD_SIZE.
+ * rtti.c (expand_class_desc): Likewise.
+ * cp-tree.h (DECL_INIT_PRIORITY): Use underlying union name.
+ (THUNK_VCALL_OFFSET): Likewise.
+ (THUNK_DELTA): Reflect changes in ../tree.h.
+
+2000-02-28 Jason Merrill <jason@casey.cygnus.com>
+
+ * search.c (protected_accessible_p): Also allow the access if
+ the member is public in DERIVED. Lose TYPE parm.
+ (friend_accessible_p): Lose TYPE parm.
+ (accessible_p): Adjust.
+
+2000-02-27 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (dfs_build_vtable_offset_vtbl_entries): Don't use size_binop
+ on things that are not sizes; ssize_binop deleted.
+ Call size_diffop when appropriate.
+ (dfs_build_vcall_offset_vtbl_entries): Likewise.
+ (build_primary_vtable, build_secondary_vtable): Likewise.
+ (dfs_set_offset_for_unshared_vbases, dfs_modify_vtables): Likewise.
+ Variable I is HOST_WIDE_INT.
+ (get_vfield_offset): Pass proper types to size_binop.
+ (size_extra_vtbl_entries, layout_virtual_bases): Likewise.
+ (finish_struct_1): Likewise.
+ (skip_rtti_stuff): Arg N is now pointer to signed.
+ (layout_class_type): Use size_zero_node.
+ * cp-tree.h (skip_rtti_stuff): Arg N is pointer to signed.
+ * cvt.c (cp_convert_to_pointer): Pass proper types to size_binop.
+ * decl.c (complete_arry_type): Pass proper types to size_binop.
+ (xref_basetypes): BINFO_OFFSET is sizetype.
+ * error.c (dump_expr): Don't use size_binop non-sizes.
+ * expr.c (cplus_expand_constant): Pass proper types to size_binop.
+ * init.c (construct_virtual_bases): Fix type error.
+ (build_vec_delete_1): Pass proper type to size_binop and don't
+ fold result.
+ * lex.c (cp_make_lang_type): BINFO_OFFSET is sizetype.
+ * rtti.c (get_base_offset): Pass proper type to size_binop.
+ * search.c (dfs_find_vbases): Fix type error.
+ (expand_upcast_fixups): Arg to skip_rtti_stuff is pointer to signed.
+ (dfs_get_vbase_types): BINFO_OFFSET is sizetype.
+ * tree.c (debug_binfo): Variable N is signed.
+ Use HOST_WIDE_INT_PRINT_DEC.
+ * typeck.c (comptypes): sizetype is same as equivalent integer type.
+ (c_sizeof, c_sizeof_nowarn, expr_sizeof): Use TYPE_SIZE_UNIT,
+ size_one_node and size_zero_node.
+ (c_alignof): Use size_one_node.
+ (build_component_addr): Pass proper types to size_binop.
+ (expand_ptrmemfunc_cst): Don't use size_binop on non-sizes.
+
+2000-02-26 Jason Merrill <jason@casey.cygnus.com>
+
+ Implement class scope using-declarations for functions.
+ * class.c (handle_using_decl): Call add_method for used functions.
+ Use IDENTIFIER_CLASS_VALUE to check for conflicts.
+ (add_method): Used functions are hidden by local functions.
+ (check_bases_and_members): Handle using-decls before finalizing
+ CLASSTYPE_METHOD_VEC.
+ * call.c (add_function_candidate): Add ctype parm; if nonzero,
+ override the type of 'this' accordingly.
+ (add_template_candidate, add_template_candidate_real): Add ctype parm.
+ (convert_class_to_reference, build_user_type_conversion_1,
+ build_new_function_call, build_object_call, build_new_op,
+ build_new_method_call): Pass ctype parm.
+
+ * search.c (lookup_member): Put rval_binfo, not basetype_path, in
+ the baselink.
+ * call.c (convert_class_to_reference, build_user_type_conversion_1,
+ build_new_function_call, build_object_call, build_new_op,
+ build_new_method_call, build_op_delete_call): Don't get basetype_path
+ from a baselink.
+ * typeck.c (build_component_ref): Likewise.
+ * init.c (build_offset_ref): Likewise.
+ (resolve_offset_ref): Don't call enforce_access.
+ Call build_scoped_ref.
+ * typeck2.c (build_scoped_ref): Simplify. Do nothing if it
+ would cause an error or if -pedantic.
+ * class.c (alter_access): Lose binfo parm.
+
+2000-02-26 Mark Mitchell <mark@codesourcery.com>
+
+ * semantics.c (simplify_aggr_init_exprs_p): Don't walk into
+ types.
+
+2000-02-25 Alfred Minarik <a8601248@unet.univie.ac.at>
+
+ * rtti.c (get_vmi_pseudo_type_info): Move __vmi_class_type_info
+ pseudo_type_info creation into the std namespace
+
+2000-02-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (DECL_NEEDED_P): Tweak to correct usage before EOF.
+ (import_export_class): Remove declaration.
+ * decl2.c (import_export_class): Make it static.
+ * dump.c (dequeue_and_dump): Handle PREDECREMENT_EXPR,
+ PREINCREMENT_EXPR, POSTDECREMENT_EXPR, POSTINCREMENT_EXPR,
+ EXPR_WITH_FILE_LOCATION.
+ * lex.c (check_newline): Tweak filename/lineno setting.
+ * semantics.c (begin_while_stmt): Fix typo in comment.
+
+2000-02-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * lang-options.h (-fmessage-length=): Add missing option.
+
+ * Make-lang.in (CXX_SRCS): Add .h files and sort list.
+
+2000-02-26 Zack Weinberg <zack@wolery.cumb.org>
+
+ * Make-lang.in: Delete refs to LIBGCC2_DEPS.
+
+2000-02-25 Jim Wilson <wilson@cygnus.com>
+
+ * optimize.c (expand_call_inline): Emit the return label before
+ evaluating the return value.
+
+2000-02-24 Mark Mitchell <mark@codesourcery.com>
+
+ * lex.c (check_newline): Use push_srcloc and pop_srcloc, rather
+ than duplicating functionality here.
+ * optimize.c: Include input.h.
+ (expand_call_inline): Use push_srcloc and pop_srcloc.
+ * parse.y (maybe_cv_qualifier): Remove calls to emit_line_note.
+ * parse.c: Regenerated.
+ * Makefile.in (lex.o): Depend on input.h.
+ (optimize.o): Likewise.
+
+2000-02-24 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (grokdeclarator): Diagnose qualifiers on non-member
+ function type, rather than ICE.
+
+2000-02-23 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (grokdeclarator): Call decl_type_access_control.
+ * parse.y (parse_end_decl): Don't call decl_type_access_control if
+ decl is null.
+
+2000-02-23 Nathan Sidwell <nathan@codesourcery.com>
+
+ * decl.c (decls_match): Remove obsolete static member nadgering.
+
+2000-02-21 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * decl.c (grokdeclarator): Change ANSI to ISO.
+ * lex.c (consume_string, readescape, do_identifier): Likewise.
+ (parse_float, real_yylex): Likewise.
+ * parse.y (paren_expr_or_null, paren_cond_or_null): Likewise.
+ (unary_expr, new_initializer, cast_expr, primary, primary_no_id,
+ new_type_id, maybe_label_decls, simple_stmt,
+ for.init.statement): Likewise.
+ * pt.c (do_decl_instantiation, do_type_instantiation): Likewise.
+ * semantics.c (finish_named_return_value): Likewise.
+ * parse.c: Regenerate.
+
+2000-02-21 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CPTI_VTABLE_INDEX_TYPE): New macro.
+ (CPTI_CLASS_STAR_TYPE): Remove.
+ (vtable_index_type): Likewise.
+ (class_star_type_node): Remove.
+ (TYPE_PTRMEMFUNC_FN_TYPE): Adjust for the new ABI.
+ (build_binary_op_nodefault): Remove.
+ * call.c (build_new_op): Use build_binary_op instead of
+ build_binary_op_nodefault.
+ * decl.c (init_decl_processing): Remove class_star_type_node
+ initialization. Make delta_type_node ptrdiff_type_node under the
+ new ABI. Initialize vtable_index_type.
+ (build_ptrmemfunc_type): Build different structures for the new
+ ABI.
+ (build_enumerator): Use build_binary_op instead of
+ build_binary_op_nodefault.
+ * method.c (build_overload_value): Mangle pointers-to-members
+ appropriately under the new ABI.
+ * typeck.c (build_array_ref): Use build_binary_op instead of
+ build_binary_op_nodefault.
+ (get_member_function_from_ptrfunc): Adjust for the new ABI.
+ (build_binary_op_nodefault): Rename to ...
+ (build_binary_op): ... this. Remove old version. Adjust for
+ pointer-to-member comparisons under the new ABI.
+ (build_ptrmemfunc1): Remove dead code. Adjust for the new ABI.
+ (build_ptrmemfunc): Adjust for the new ABI.
+ (expand_ptrmemfunc_cst): Likewise.
+ (delta2_from_ptrmemfunc): Assert that we're not using the new ABI.
+ (pfn_from_ptrmemfunc): Adjust for the new ABI.
+
+2000-02-21 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * call.c (build_object_call): Compress consecutive calls to
+ cp_error.
+ (build_conditional_expr): Say 'ISO C++' not 'ANSI C++'.
+ (build_op_delete_call): Adjust message formatting.
+
+ * class.c (check_bases): Compress consecutive calls to
+ cp_pedwarn.
+ (finish_struct_anon): Say 'ISO C++'.
+
+ * decl.c (start_decl): Same here.
+ (grok_reference_init): Likewise.
+ (grokfndecl): Correct message formatting.
+ (grokfndecl): Improve diagnostic.
+ (check_static_variable_definition): Likewise. Say 'ISO C++'
+ (compute_array_index_type): Say 'ISO C++'
+ (create_array_type_for_decl): Compress consecutive calls to
+ cp_error.
+ (grokdeclarator): Say 'ISO C++'
+ (grok_op_properties): Likewise.
+
+ * decl2.c (delete_sanity): Clairify diagnostic.
+ (check_member_template): Same here.
+ (grok_function_init): Use consistent terminology.
+
+ * expr.c (do_case): Say 'ISO C++'
+
+ * friend.c (do_friend): Compress consecutive calls to warning.
+
+2000-02-20 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (merge_primary_and_secondary_vtables_p): New macro.
+ * class.c (build_secondary_vtable): Reorganize. Don't create a
+ new vtable under the new ABI.
+ (layout_vtable_decl): Don't add num_extra_vtbl_entries when
+ computing the size.
+ (build_vtbl_initializer): Don't return a CONSTRUCTOR; just return
+ the initializing elements.
+ (initialize_vtable): New function.
+ (dfs_finish_vtbls): Use it.
+ (dfs_accumulate_vtbl_inits): New function.
+ (finish_vtbls): Merge primary and secondary vtables under the new
+ ABI.
+ (finish_struct_1): Remove redundant call to layout_vtable_decl.
+ * init.c (expand_virtual_init): Deal with BINFO_VTABLEs that
+ aren't VAR_DECLs.
+
+ * class.c (build_vtable): New function, split out from ...
+ (get_vtable_decl): ... here, and ...
+ (build_secondary_vtable): ... here.
+
+ * pt.c (tsubst_decl): Fix formatting.
+
+2000-02-19 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_primary_vtable, layout_vtable_decl): Likewise.
+ (avoid_overlap, build_base_field): Likewise.
+ (build_base_field, build_base_fields, is_empty_class):
+ Test DECL_SIZE with integer_zero.
+ (layout_class_type): Set CLASSTYPE_SIZE_UNIT.
+ * cp-tree.h (struct lang_type): New field size_unit.
+ (CLASSTYPE_SIZE_UNIT): New macro.
+ * decl.c (init_decl_processing): Set DECL_SIZE_UNIT.
+ (cp_finish_decl): Delete -Wlarger-than processing.
+ * optimize.c (remap_decl): Walk DECL_SIZE_UNIT.
+ * pt.c (tsubst_decl): Set DECL_SIZE_UNIT.
+ * tree.c (make_binfo): binfo vector is one entry longer.
+ (walk_tree): Walk DECL_SIZE_UNIT.
+
+2000-02-19 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (dfs_build_vcall_offset_vtbl_entries): Fix typo in
+ comment.
+ (build_vtable_entry): Don't assume all vtable entries are
+ functions.
+ (build_vtbl_initializer): Adjust accordingly.
+ (get_vtable_decl): Fix formatting.
+
+2000-02-18 Jason Merrill <jason@casey.cygnus.com>
+
+ * semantics.c (deferred_type_access_control): Walk the entire
+ type_lookups list.
+ (save_type_access_control): Rename from
+ initial_deferred_type_access_control. Just remember the value.
+ (decl_type_access_control): New fn.
+ (begin_function_definition): Use deferred_type_access_control, after
+ we've started the function. Set type_lookups to error_mark_node.
+ * parse.y (frob_specs, fn.def1): Adjust.
+ (parse_decl0, parse_field, parse_field0, parse_bitfield): New fns.
+ (parse_end_decl, parse_bitfield0, parse_method): New fns.
+ (fn.def2, initdcl, initdcl0_innards, nomods_initdcl0): Use them.
+ (after_type_component_declarator0): Likewise.
+ (after_type_component_declarator): Likewise.
+ (notype_component_declarator): Likewise.
+ * cp-tree.h: Adjust.
+
+ * decl.c (redeclaration_error_message): Allow redeclaration of
+ namespace-scope decls.
+
+2000-02-18 Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+ * typeck2.c (my_friendly_abort): Use GCCBUGURL.
+
+2000-02-17 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (add_method): Don't set DECL_VIRTUAL_CONTEXT.
+ * decl2.c (grokclassfn): Likewise.
+
+ * ir.texi: Document DECL_TEMPLATE_INSTANTIATIONS.
+
+ * decl2.c (lang_decode_option): Don't set default message length
+ here.
+ * lex.c (lang_init_options): Set it here.
+
+2000-02-16 Mark Mitchell <mark@codesourcery.com>
+
+ Make DECL_CONTEXT mean the class in which a member function was
+ declared, even for a virtual function.
+ * cp-tree.h (DECL_CLASS_CONTEXT): Adjust.
+ (DECL_FRIEND_CONTEXT): New macro.
+ (DECL_REAL_CONTEXT): Remove.
+ (SET_DECL_FRIEND_CONTEXT): Likewise.
+ (DECL_VIRTUAL_CONTEXT): Adjust.
+ (DECL_CLASS_SCOPE_P): Use TYPE_P.
+ (add_friends): Remove.
+ (hack_decl_function_context): Likewise.
+ * call.c (build_new_function_call): Replace DECL_REAL_CONTEXT with
+ CP_DECL_CONTEXT.
+ (build_over_call): Fix indentation. Use DECL_CONTEXT
+ instead of DECL_CLASS_CONTEXT.
+ * class.c (dfs_build_vcall_offset_vtbl_entries): Likewise.
+ (add_method): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (strictly_overrides): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (build_vtbl_or_vbase_field): Don't set DECL_CLASS_CONTEXT.
+ (build_base_field): Likewise.
+ (finish_struct_1): Likewise.
+ (build_self_reference): Likewise.
+ * decl.c (push_class_binding): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (pushtag): Use decl_function_context, not
+ hack_decl_function_context.
+ (decls_match): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
+ (duplicate_decls): Use DECL_VIRTUAL_CONTEXT.
+ (pushdecl): Remove bogus code.
+ (start_decl): Use DECL_CONTEXT rather than DECL_CLASS_CONTEXT.
+ (cp_finish_decl): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
+ (grokfndecl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ Use decl_function_context, nothack_decl_function_context.
+ (grokvardecl): Don't set DECL_CLASS_CONTEXT.
+ (grokdeclarator): Likewise. Use decl_function_context, not
+ hack_decl_function_context.
+ (copy_args_p): Document. Don't use DECL_CLASS_CONTEXT.
+ (start_function): Use DECL_FRIEND_CONTEXT, not
+ DECL_CLASS_CONTEXT. Use decl_function_context, not
+ hack_decl_function_context.
+ (finish_function): Use decl_function_context, not
+ hack_decl_function_context.
+ (maybe_retrofit_in_chrg): Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ (grokclassfn): Set DECL_VIRTUAL_CONTEXT, not DECL_CONTEXT.
+ (finish_static_data_member_decl): Don't set DECL_CLASS_CONTEXT.
+ (grokfield): Likewise.
+ (finish_builtin_type): Likewise.
+ (finish_vtable_vardec): Use decl_function_context, not
+ hack_decl_function_context.
+ (import_export_decl): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (start_static_initialization_or_destruction): Likewise.
+ (finish_static_initialization_or_destruction): Likewise.
+ (mark_used): Adjust logic for deciding when to synthesize methods.
+ * dump.c (dequeue_and_dump): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ * error.c (dump_function_decl): Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ * friend.c (is_friend): Likewise.
+ (add_friends): Remove.
+ (do_friend): Use SET_DECL_FRIEND_CONTEXT.
+ * lex.c (begin_definition_of_inclass_inline): Use
+ decl_function_context, not hack_decl_function_context.
+ (process_next_inline): Likewise.
+ (do_identifier): Use CP_DECL_CONTEXT, not DECL_REAL_CONTEXT.
+ * method.c (set_mangled_name_for_decl): Use DECL_CONTEXT, not
+ DECL_CLASSS_CONTEXT.
+ (hack_identifier): Likewise.
+ (synthesize_method): Use decl_function_context, not
+ hack_decl_function_context.
+ * pt.c (template_class_depth_real): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (is_member_template): Use decl_function_context, not
+ hack_decl_function_context. Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ (build_template_decl): Set DECL_VIRTUAL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ (check_default_tmpl_args): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (push_template_decl_real): Likewise.
+ (instantiate_class_template): Don't call add_friends.
+ (tsubst_default_argument): Use DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (tsubst_decl): Set DECL_VIRTUAL_CONTEXT, not DECL_CLASS_CONTEXT.
+ Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (set_meangled_name_for_template_decl): Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ * repo.c (repo_inline_used): Likewise.
+ * search.c (current_scope): Adjust for new _CONTEXT macros.
+ (context_for_name_lookup): Use CP_DECL_CONTEXT, not
+ DECL_REAL_CONTEXT.
+ (friend_accessible_p): Use DECL_CONTEXT, not DECL_CLASS_CONTEXT.
+ (lookup_fnfields_here):Likewise.
+ (check_final_overrider): Likewise.
+ (init_vbase_pointers): Likewise.
+ (virtual_context): Likewise.
+ * semantics.c (finish_member_declaration): Just set DECL_CONTEXT.
+ (expand_body): Use decl_function_context, not
+ hack_decl_function_context.
+ * tree.c (hack_decl_function_context): Remove.
+ * typeck.c (build_x_function_call): Use DECL_CONTEXT, not
+ DECL_CLASS_CONTEXT.
+ * typeck2.c (error_not_base_type): Likewise.
+
+2000-02-15 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl.c (xref_tag): Don't SET_IDENTIFIER_NAMESPACE_VALUE.
+
+2000-02-16 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (g++spec.o): Depend on $(GCC_H), not gcc.h.
+
+2000-02-15 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * lang-specs.h: Add new __GNUC_PATCHLEVEL__ define to default spec.
+
+2000-01-16 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Enable automatic line wrapping.
+
+2000-02-13 Jason Merrill <jason@casey.cygnus.com>
+
+ * parse.y (frob_specs): Split out...
+ (parse_decl): From here.
+ (fn.def2): Call initial_deferred_type_access_control.
+ (after_type_component_declarator0): Call frob_specs.
+ (notype_component_declarator0): Likewise.
+ * search.c (friend_accessible_p): Nested classes are friends of their
+ enclosing classes.
+
+2000-02-10 Mark Mitchell <mark@codesourcery.com>
+
+ * ir.texi (ADDR_EXPR): Document the fact that an ADDR_EXPR can be
+ used to create an implicit temporary.
+
+ * class.c (dfs_modify_vtables): Tweak calculation of functions to
+ override.
+
+2000-02-08 Nathan Sidwell <nathan@acm.org>
+
+ * typeck.c (strip_all_pointer_quals): Use TYPE_MAIN_VARIANT, to
+ strip array element qualifiers too.
+
+2000-02-07 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (store_parm_decls): Don't build cleanups for parameters
+ while processing_template_decl.
+
+2000-02-07 Jason Merrill <jason@casey.cygnus.com>
+
+ * cp-tree.h (struct saved_scope): Add incomplete field.
+ (namespace_scope_incomplete): New macro.
+ * decl.c (pushdecl): Use it.
+ (hack_incomplete_structures): Use it. See through artificial
+ binding levels.
+ (mark_saved_scope): Mark it.
+
+ Implement access control for nested types.
+ * search.c (type_access_control): New fn.
+ (accessible_p): Now we do perform access control for types.
+ * semantics.c (deferred_type_access_control): New fn.
+ (initial_deferred_type_access_control): New fn.
+ (begin_function_definition): Call it. Add lookups parm.
+ * decl.c (struct binding_level): Add this_class field.
+ (pushlevel_class): Set it.
+ (mark_binding_level): Mark it.
+ (lookup_name_real): Use it. Call type_access_control.
+ (mark_saved_scope): Mark lookups field.
+ * cp-tree.h (flagged_type_tree): Add lookups field.
+ (struct saved_scope): Add lookups field.
+ (type_lookups): New macro.
+ * parse.y (declmods): Now <ftype>.
+ (parse_decl): Add lookups parm. Call
+ initial_deferred_type_access_control.
+ (lang_extdef): Clear type_lookups.
+ (typed_declspecs, declmods, typespec): Set lookups field.
+ (initdcl): Call deferred_type_access_control.
+ (fn.def1, fn.def2, typed_declspecs1, initdcl0_innards, nomods_initdcl0,
+ component_decl_1, named_parm): Adjust.
+ * friend.c (is_friend): Nested classes are friends of their
+ enclosing classes.
+
+ * class.c (currently_open_derived_class): New fn.
+ * method.c (hack_identifier): Use it.
+
+ * lex.c (do_identifier): Remove obsolete code.
+
+ * parse.y (typed_typespecs): Propagate new_type_flag properly.
+
+2000-02-05 Zack Weinberg <zack@wolery.cumb.org>
+
+ * tinfo.h: Remove apostrophes from C++ comment (xgettext
+ thinks this file is plain C).
+
+2000-02-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (call.o): Depend on $(EXPR_H).
+
+ * call.c: Include "expr.h".
+
+ * class.c (dump_class_hierarchy): Add prototype.
+
+ * search.c (dfs_get_pure_virtuals): Likewise.
+
+2000-02-1 Ulrich Drepper <drepper@redhat.com>
+
+ * parse.y (simple_stmt): Allow :: token in asm parameter list.
+ * parse.c: Rebuilt.
+
+2000-01-31 Jim Wilson <wilson@cygnus.com>
+
+ * class.c (build_vtbl_or_vbase_field): New parameter fcontext.
+ Store it in DECL_FCONTEXT.
+ (build_vbase_pointer_fields, create_vtable_ptr): Fix callers.
+
+2000-01-31 Jason Merrill <jason@casey.cygnus.com>
+
+ * tinfo.h (old abi): #include "tconfig.h".
+ * tinfo.cc (convert_to_base): Move into old abi section.
+
+2000-01-31 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BINFO_VIRTUALS): Tweak documentation.
+ (CLASSTYPE_PRIMARY_BINFO): Use BINFO_PRIMARY_BINFO.
+ (BINFO_PRIMARY_BINFO): New macro.
+ (BF_DELTA): Rename to ...
+ (BV_DELTA): ... this.
+ (BF_VCALL_INDEX): Rename to ...
+ (BV_VCALL_INDEX): ... this.
+ (BF_FN): Rename to ...
+ (BV_FN): ... this.
+ * class.c (build_vbase_path): Adjust for changes to reverse_path.
+ (set_rtti_entry): Rename BF_ macros to BV_ variants.
+ (modify_vtable_entry): Simplify.
+ (add_virtual_function): Rename BF_ macros to BV_ variants.
+ (build_vtable_initializer): Likewise.
+ (get_class_offset_1): Remove.
+ (dfs_get_class_offset): Likewise.
+ (get_class_offset): Likewise.
+ (dfs_find_final_overrider): New function.
+ (find_final_overrider): Likewise.
+ (modify_one_vtable): Remove.
+ (dfs_find_base): New function.
+ (dfs_modify_vtables): Fold modify_one_vtable in here. Use
+ find_final_overrider.
+ (modify_all_vtables): Adjust. Set BV_VCALL_INDEX on new
+ virtuals.
+ (dfs_fixup_vtable_deltas): Remove.
+ (override_one_vtable): Remove.
+ (merge_overrides): Likewise.
+ (layout_virtual_bases): Make sure BINFO_OFFSET is set right for
+ unreal chilren of virtual bases.
+ (finish_struct_1): Don't use merge_overrides. Don't use
+ dfs_fixup_vtable_deltas.
+ * tree.c (reverse_path): Return a TREE_LIST, not a chain of
+ BINFOs.
+
+2000-01-31 Herman A.J. ten Brugge <Haj.Ten.Brugge@net.HCC.nl>
+ Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo.h: Rename USItype to myint32, depend on BITS_PER_UNIT.
+
+2000-01-31 Alfred Minarik <a8601248@unet.univie.ac.at>
+
+ * exception.cc (__throw_bad_typeid): Add missing std::.
+
+2000-01-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cp-tree.h (make_thunk): PROTO -> PARAMS.
+
+2000-01-31 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (new_abi_rtti_p): Use flag_new_abi.
+
+ Runtime support for new-abi rtti.
+ * inc/typeinfo (type_info::operator!=): Define in class.
+ (type_info::before, type_info::name, type_info::operator==,
+ type_info::operator!=): Define new ABI implementations.
+ (type_info::is_pointer_p, type_info::is_function_p): Declare
+ new virtual functions.
+ (type_info::do_catch, type_info::do_upcast): Likewise.
+
+ * tinfo.h (__base_class_info): Define new class.
+ (__class_type_info): Likewise.
+ (__si_class_type_info): Likewise.
+ (__vmi_class_type_info): Likewise.
+ (__dynamic_cast): Prototype.
+
+ * tinfo.cc: Conditionalize old and new rtti mechanisms.
+ (type_info::is_pointer_p): Define new function.
+ (type_info::is_function_p): Likewise.
+ (type_info::do_catch): Likewise.
+ (type_info::do_upcast): Likewise.
+ (vtable_prefix): New structure for vtable access.
+ (adjust_pointer): Define new template function.
+ (contained_p, public_p, virtual_p, contained_public_p,
+ contained_nonpublic_p, contained_nonvirtual_p): Define new
+ functions.
+ (nonvirtual_base_type): New local variable.
+ (__class_type_info::~__class_type_info): Define.
+ (__si_class_type_info::~__si_class_type_info): Likewise.
+ (__vmi_class_type_info::~__vmi_class_type_info): Likewise.
+ (__class_type_info::do_catch): Define new function.
+ (__class_type_info::do_upcast): Likewise.
+ (__class_type_info::find_public_src): Likewise.
+ (__class_type_info::do_find_public_src): Likewise.
+ (__si_class_type_info::do_find_public_src): Likewise.
+ (__vmi_class_type_info::do_find_public_src): Likewise.
+ (__class_type_info::do_dyncast): Likewise.
+ (__si_class_type_info::do_dyncast): Likewise.
+ (__vmi_class_type_info::do_dyncast): Likewise.
+ (__class_type_info::do_upcast): Likewise.
+ (__si_class_type_info::do_upcast): Likewise.
+ (__vmi_class_type_info::do_upcast): Likewise.
+ (__dynamic_cast): Likewise.
+
+ * tinfo2.cc (__fundamental_type_info): Define new class.
+ (__pointer_type_info): Likewise.
+ (__reference_type_info): Likewise.
+ (__array_type_info): Likewise.
+ (__function_type_info): Likewise.
+ (__enum_type_info): Likewise.
+ (__ptr_to_member_type_info): Likewise.
+ (__fundamental_type_info::~__fundamental_type_info): Define.
+ (__pointer_type_info::~__pointer_type_info): Likewise.
+ (__reference_type_info::~__reference_type_info): Likewise.
+ (__array_type_info::~__array_type_info): Likewise.
+ (__function_type_info::~__function_type_info): Likewise.
+ (__enum_type_info::~__enum_type_info): Likewise.
+ (__ptr_to_member_type_info::~__ptr_to_member_type_info): Likewise.
+ (__pointer_type_info::do_catch): Define new function.
+ (__ptr_to_member_type_info::do_catch): Define new function.
+
+ (__throw_type_match_rtti_2): Use new ABI interface, if enabled.
+ (__is_pointer): Likewise.
+
+ * exception.cc (__cplus_type_matcher): Deal with new-abi rtti.
+
+2000-01-30 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/class.c (build_vtable): Rename to build_primary_vtable.
+ (prepare_fresh_vtable): Rename to build_secondary_vtable.
+ (make_new_vtable): New function.
+ (modify_vtable_entry): Handle generation of new vtables correctly.
+ (modify_one_vtable): Remove unused parameter.
+ (dfs_fixup_vtable_deltas): Likewise.
+ (override_one_vtable): Use build_secondary_vtable.
+ (finish_struct_1): Use build_primary_vtable and
+ build_secondary_vtable.
+
+2000-01-28 Ulrich Drepper <drepper@redhat.com>
+
+ * cp/decl.c: Adjust variable names, comments, help strings.
+
+2000-01-29 Nathan Sidwell <nathan@acm.org>
+
+ * new2.cc (operator delete[]): Use operator delete, don't assume
+ implementation.
+
+2000-01-29 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * class.c (build_vtbl_initializer): Add argument to
+ build_vtable_entry call.
+
+2000-01-27 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.def (THUNK_DECL): Discuss vcall indices.
+ * cp-tree.h (BINFO_VIRTUALS): Update documentation.
+ (BF_DELTA): New macro.
+ (BF_VCALL_INDEX): Likewise.
+ (BF_FN): Likewise.
+ (THUNK_VCALL_OFFSET): Likewise.
+ (make_thunk): Change prototype.
+ * class.c (build_vtable_entry): Integrate
+ build_vtable_entry_for_fn. Handle vcall indices.
+ (build_vtable_entry_for_fn): Remove.
+ (set_rtti_entry): Handle vcall indices. Use BF_DELTA,
+ BF_VCALL_INDEX, BF_FN.
+ (modify_vtable_entry): Integrate common code from
+ modify_one_vtable and dfs_fixup_vtable_deltas.
+ (add_virtual_function): Set BF_VCALL_INDEX.
+ (build_vtbl_initializer): Simplify. Use BF_DELTA, BF_VCALL_INDEX,
+ and BF_FN.
+ (modify_one_vtable): Simplify.
+ (dfs_fixup_vtable_deltas): Likewise.
+ (override_one_vtable): Use BF_DELTA, BF_VCALL_INDEX, BF_FN.
+ * method.c (make_thunk): Handle vcall indices.
+
+2000-01-28 Nathan Sidwell <sidwell@codesourcery.com>
+
+ Compiler side new abi rtti (not enabled).
+ * cp-tree.h (new_abi_rtti_p): New macro.
+ (emit_support_tinfos): Prototype new function.
+ (tinfo_decl_p): Likewise.
+ (emit_tinfo_decl): Likwise.
+ * rtti.c (TINFO_PSEUDO_TYPE, TINFO_VTABLE_DECL): New accessor
+ macros.
+ (doing_runtime): New local static.
+ (init_rtti_processing): Add new-abi initializer.
+ (get_tinfo_decl): Add new-abi logic.
+ (tinfo_from_decl): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ (qualifier_flags): New static function.
+ (tinfo_base_init): Likewise.
+ (generic_initializer): Likewise.
+ (ptr_ref_initializer): Likewise.
+ (ptmd_initializer): Likewise.
+ (class_hint_flags): Likewise.
+ (class_initializer): Likewise.
+ (synthesize_tinfo_var): Likewise.
+ (create_real_tinfo_var): Likewise.
+ (create_pseudo_type_info): Likewise.
+ (get_vmi_pseudo_type_info): Likewise.
+ (create_tinfo_types): Likewise.
+ (emit_support_tinfos): New global function.
+ (tinfo_decl_p): New global predicate.
+ (emit_tinfo_decl): New global function.
+ * class.c (set_rtti_entry): Generalize for old and new rtti.
+ (build_vtbl_initializer): Likewise.
+ * decl2.c (finish_file): Likewise.
+
+2000-01-27 Jim Wilson <wilson@cygnus.com>
+
+ * optimize.c (remap_decl): Add walk_tree calls for DECL_SIZE (t)
+ and TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t))).
+
+2000-01-27 Mike Stump <mrs@wrs.com>
+
+ * decl.c (pushdecl): Fix up shadow warnings with respect to implicit
+ for scopes.
+
+2000-01-26 Jason Merrill <jason@casey.cygnus.com>
+
+ * pt.c (unify): Use fold, not maybe_fold_nontype_arg.
+
+2000-01-26 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * optimize.c (calls_setjmp_r): Supply new argument
+ to special_function_p.
+
+2000-01-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c: PROTO -> PARAMS.
+ * class.c: Likewise.
+ * cp-tree.h: Likewise.
+ * cvt.c: Likewise.
+ * decl.c: Likewise.
+ * decl.h: Likewise.
+ * decl2.c: Likewise.
+ * dump.c: Likewise.
+ * errfn.c: Likewise.
+ * error.c: Likewise.
+ * except.c: Likewise.
+ * expr.c: Likewise.
+ * init.c: Likewise.
+ * input.c: Likewise.
+ * lex.c: Likewise.
+ * lex.h: Likewise.
+ * method.c: Likewise.
+ * optimize.c: Likewise.
+ * parse.y: Likewise.
+ * pt.c: Likewise.
+ * repo.c: Likewise.
+ * rtti.c: Likewise.
+ * search.c: Likewise.
+ * semantics.c: Likewise.
+ * spew.c: Likewise.
+ * tree.c: Likewise.
+ * typeck.c: Likewise.
+ * typeck2.c: Likewise.
+ * xref.c: Likewise.
+
+2000-01-25 Richard Henderson <rth@cygnus.com>
+
+ * typeck.c (build_binary_op_nodefault): Remove UNNE_EXPR.
+
+2000-01-25 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (vcall_offset_in_vtable_p): New macro.
+ * class.c (build_vbase_offset_vtbl_entries): Fix typo in commment.
+ (struct vcall_offset_data_s): New type.
+ (dfs_vcall_offset_queue_p): New function.
+ (dfs_build_vcall_offset_vtbl_entries): Likewise.
+ (build_vcall_offset_vtbl_entries): Likewise.
+ (layout_vtable_decl): Likewise.
+ (num_vfun_entries): Likewise.
+ (num_extra_vtbl_entries): Add the entries for vcall offsets.
+ (build_vtbl_initializer): Likewise.
+ (dfs_finish_vtabls): Use layout_vtable_decl.
+ (modify_one_vtables): Always duplicate vtables under the new ABI.
+ (finish_struct_1): Use layout_vtable_decl.
+
+2000-01-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * decl.c (member_function_or_else): Change third arg from a format
+ specifier to an `enum overload_flags'. Callers changed.
+
+2000-01-25 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * typeck.c (composite_pointer_type, c_sizeof, expr_sizeof,
+ build_binary_op_nodefault, build_unary_op, build_reinterpret_cast,
+ build_const_cast, get_delta_difference, check_return_expr): Avoid
+ ANSI string concatenation usage.
+
+2000-01-24 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_class_type): Put the fields required to make a
+ class non-empty at the end, not the beginning, of the TYPE_FIELDs
+ list.
+
+2000-01-24 Jason Merrill <jason@casey.cygnus.com>
+
+ * pt.c (maybe_fold_nontype_arg): Do nothing if we're not in a
+ template.
+
+ * decl2.c (mark_used): Do instantiate inlines that have been
+ explicitly instantiated.
+
+2000-01-24 Richard Henderson <rth@cygnus.com>
+
+ * call.c (build_over_call): Use expand_tree_builtin.
+ * typeck.c (build_function_call_real): Likewise.
+ (build_binary_op_nodefault): Handle unordered compares.
+
+2000-01-24 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (CPTI_BAD_CAST, CPTI_BAD_TYPEID, CPTI_DCAST): New
+ cp_tree_index values.
+ (throw_bad_cast_node, throw_bad_typeid_node, dynamic_cast_node):
+ New global node #defines for them.
+ * rtti.c (call_void_fn): Replace with ...
+ (build_runtime_decl): ... new static function.
+ (throw_bad_cast): Use throw_bad_cast_node and build_runtime_decl.
+ (throw_bad_typeid): Use throw_bad_typeid_node and build_runtime_decl.
+ (build_dynamic_cast_1): Always produce correctly typed result.
+ Explicitly produce type_info addresses. Use dynamic_cast_node.
+ * exception.cc (__throw_bad_cast): Return `void *'.
+ (__throw_bad_typeid): Return `const type_info &'.
+
+2000-01-24 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (get_vtable_decl): Prototype new function.
+ * class.c (get_vtable_decl): New function. Broken out from ...
+ (build_vtable): ... here. Use it.
+ * decl2.c (finish_vtable_vardecl): Ignore dummy vtables created
+ by get_vtable_decl.
+
+2000-01-24 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (CPTI_TP_DESC_TYPE, CPTI_ACCESS_MODE_TYPE,
+ CPTI_USER_DESC_TYPE, CPTI_CLASS_DESC_TYPE, CPTI_ATTR_DESC_TYPE,
+ CPTI_PTMF_DESC_TYPE): Remove cp_tree_index enumerations.
+ (CPTI_TI_DESC_TYPE, CPTI_REF_DESC_TYPE, CPTI_ARY_DESC_TYPE,
+ CPTI_ENUM_DESC_TYPE, CPTI_CLASS_DESC_TYPE, CPTI_SI_CLASS_DESC_TYPE,
+ CPTI_VMI_CLASS_DESC_TYPE, CPTI_BASE_DESC_TYPE): New enumerations.
+ (CPTI_TINFO_FN_ID, CPTI_TINFO_FN_TYPE): Rename to ...
+ (CPTI_TINFO_DECL_ID, CPTI_TINFO_DECL_TYPE): ... here.
+ (CPTI_TINFO_VAR_ID): New enumeration.
+ (__tp_desc_type_node, __access_mode_type_node,
+ __bltn_desc_type_node, __user_desc_type_node,
+ __class_desc_type_node, __ptr_desc_type_node,
+ __attr_desc_type_node, __func_desc_type_node,
+ __ptmf_desc_type_node, __ptmd_desc_type_node): Remove #defines.
+ (ti_desc_type_node, bltn_desc_type_node, ptr_desc_type_node,
+ ref_desc_type_node, ary_desc_type_node, func_desc_type_node,
+ enum_desc_type_node, class_desc_type_node,
+ si_class_desc_type_node, vmi_class_desc_type_node,
+ ptmd_desc_type_node, base_desc_type_node): New #defines.
+ (tinfo_fn_id, tinfo_fn_type): Rename to ...
+ (tinfo_decl_id, tinfo_decl_type): ... here. Adjust.
+ (tinfo_var_id): New enumeration.
+ (DECL_TINFO_FN_P): Augment comment.
+ * decl.c (cp_global_trees): Adjust documentation.
+ * rtti.c (init_rtti_processing): Adjust for tinfo_decl_id,
+ tinfo_decl_type and tinfo_var_id.
+ (get_tinfo_decl_dynamic): Adjust for tinfo_decl_type.
+ (build_typeid): Remove unused variable.
+ (get_tinfo_var): Use tinfo_var_id.
+ (tinfo_name): New static function.
+ (get_tinfo_decl): Adjust for tinfo_decl_id and tinfo_decl_type.
+ (tinfo_from_decl): Likewise.
+ (get_base_offset): New static function, broken out of
+ expand_class_desc.
+ (expand_si_desc): Use tinfo_name.
+ (expand_class_desc): Likewise. Lose local static variable.
+ Use base_desc_type_node. Use get_base_offset.
+ (expand_ptr_desc): Use tinfo_name.
+ (expand_attr_desc): Likewise.
+ (expand_generic_desc): Likewise.
+
+ * tinfo.cc (__GXX_ABI_VERSION): Test value and existence.
+ * tinfo.h (__GXX_ABI_VERSION): Test value and existence.
+
+2000-01-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (__eprintf): Remove declaration.
+ * tree.c (__eprintf): Remove definition.
+
+2000-01-23 Zack Weinberg <zack@rabi.columbia.edu>
+ Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_MARKED_N, SET_CLASSTYPE_MARKED_N,
+ CLEAR_CLASSTYPE_MARKED_N): Avoid signed vs. unsigned warnings.
+
+2000-01-23 Brad Lucier <lucier@math.purdue.edu>
+
+ * class.c (dump_class_hierarchy): Print HOST_WIDE_INT properly.
+
+2000-01-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (register_dtor_fn): New function.
+ * decl.c (destroy_local_static): Rename to ...
+ (register_dtor_fn): ... this. Give it external linkage.
+ (expand_static_init): Use it.
+ * decl2.c (do_static_initialization): Likewise, if using
+ __cxa_atexit.
+ (do_static_destruction): Check that __cxa_atexit is not in use.
+ (finish_file): Don't call do_static_destruction if using
+ __cxa_atexit.
+
+ * typeck.c (convert_arguments): Restore two-message error
+ reporting.
+
+2000-01-20 Nathan Sidwell <sidwell@codesourcery.com>
+
+ Remap dynamic cast hint values to be consistent across ABIs.
+ * search.c (dynamic_cast_base_recurse): Remap generated value.
+ (get_dynamic_cast_base_type): Adjust documentation.
+ * tinfo.h (__user_type_info::dyncast): Likewise.
+ (__user_type_info::find_public_subobj): Remap BOFF meaning.
+ * tinfo.cc (__si_type_info::do_dyncast): Remap BOFF meaning.
+ (__class_type_info::do_dyncast): Likewise.
+ (__class_type_info::do_find_public_subobj): Likewise.
+ * tinfo2.cc (__dynamic_cast): Remap BOFF parameter.
+
+2000-01-19 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * typeck.c (build_unary_op): Use cp_pedwarn, not pedwarn.
+
+ * typeck2.c (incomplete_type_error): Restore previous
+ cp_error and cp_error_at call sequence.
+
+2000-01-20 Brad Lucier <lucier@math.purdue.edu>
+
+ * class.c (dump_class_hierarchy): Make format agree with argument;
+ cast pointer to unsigned long and print with %lx.
+
+2000-01-19 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Set default line-wrap length to 72.
+
+ * typeck.c (composite_pointer_type, common_type,
+ comp_target_parms, c_sizeof, expr_sizeof, build_array_ref,
+ build_function_call_real, convert_arguments,
+ build_binary_op_nodefault, pointer_int_sum, pointer_diff,
+ build_unary_op, mark_addressable, build_compound_expr,
+ build_static_cast, build_reinterpret_cast, build_const_cast,
+ build_c_cast, build_modify_expr, get_delta_difference,
+ build_ptrmemfunc, check_return_expr): Replace 'ANSI C++' with
+ 'ISO C++'. Fusion consecutive calls to diagnostic message routines
+ into a single one.
+ * typeck2.c (readonly_error, abstract_virtuals_error,
+ process_init_constructor, check_for_new_type): Likewise.
+
+2000-01-19 Mark Mitchell <mark@codesourcery.com>
+
+ * tree.c (bot_manip): Set DECL_CONTEXT for newly created
+ VAR_DECLs.
+
+2000-01-18 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * cp-tree.h (get_tinfo_fn_dynamic): Remove prototype.
+ (build_x_typeid): Likewise.
+ (get_tinfo_fn): Likewise.
+ (get_tinfo_fn_unused): Rename to ...
+ (get_tinfo_decl): ... here.
+ * rtti.c (build_headof): Replace logic error with assertion.
+ (get_tinfo_fn_dynamic): Rename to ...
+ (get_tinfo_decl_dynamic): ... here. Make static. Use
+ complete_type_or_else.
+ (build_x_typeid): Move into ...
+ (build_typeid): ... here. Adjust call to
+ get_tinfo_decl_dynamic. Use tinfo_from_decl. Simplify
+ throw_bad_typeid expression.
+ (get_tinfo_fn_unused): Rename to ...
+ (get_tinfo_decl): ... here. Adjust comment.
+ (get_tinfo_fn): Delete.
+ (tinfo_from_decl): New static function.
+ (get_typeid_1): Call get_tinfo_decl and tinfo_from_decl.
+ (get_typeid): Use complete_type_or_else.
+ (build_dynamic_cast_1): Adjust calls to
+ get_tinfo_decl_dynamic. Simplify throw_bad_cast expression.
+ * parse.y (primary): Adjust call to build_typeid.
+ * except.c (build_eh_type_type_ref): Adjust call to
+ get_tinfo_decl. Mark as used.
+ * class.c (set_rtti_entry): Adjust call to get_tinfo_decl.
+ * decl2.c (build_expr_from_tree): Adjust call to build_typeid.
+ * parse.c: Regenerated.
+
+2000-01-17 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (fixed_type_or_null): Don't clear NONNULL. Document
+ calling convention.
+ (resolves_to_fixed_type_p): Document calling convention.
+ * rtti.c (build_x_typeid): Initialize NONNULL.
+
+ * cp-tree.h (build_shared_int_cst): New function.
+ * call.c (build_over_call): Use DECL_VIRTUAL_CONTEXT, for clarity.
+ * class.c (modify_vtable_entry): Likewise.
+ (add_virtual_function): Split out code to generated shared
+ INTEGER_CSTs to build_share_int_cst.
+ (modify_all_vtables): Handle all the overridden functions here.
+ Add overridden functions from non-primary virtual bases to the
+ primary vtable.
+ (finish_struct_1): Adjust call to modify_all_vtables. Add
+ overridden functions from non-primary bases to the vtable.
+ * tree.c (build_shared_int_cst): New function.
+
+ * cp-tree.h (scratchalloc): Remove.
+ (build_scratch_list): Likewise.
+ * call.c (convert_class_to_reference): Replace build_scratch_list
+ and build_expr_list with build_tree_list.
+ (add_candidate): Replace scratchalloc with expralloc. Note memory
+ leak.
+ (build_user_type_conversion_1): Replace build_scratch_list
+ and build_expr_list with build_tree_list.
+ (build_new_op): Likewise.
+ (build_op_delete_call): Likewise.
+ (convert_like): Likewise.
+ * cvt.c (ocp_convert): Likewise.
+ * decl.c (start_decl): Likewise.
+ (start_function): Likewise.
+ (finish_destructor_body): Likewise.
+ (maybe_build_cleanup_1): Likewise.
+ * decl2.c (reparse_decl_as_expr): Likewise.
+ * init.c (perform_member_init): Likewise.
+ (expand_cleanup_for_base): Likewise.
+ (build_builtin_delete_call): Likewise.
+ (build_new_1): Likewise.
+ (build_delete): Likewise.
+ * method.c (do_build_assign_ref): Likewise.
+ * parse.y (already_scoped_stmt): Likewise.
+ (nontrivial_exprlist): Likewise.
+ (net_initializer): Likewise.
+ (initlist): Likewise.
+ * parse.c: Regenerated.
+ * rtti.c (build_x_typeid): Likewise.
+ (build_dynamic_cast_1): Likewise.
+ * typeck.c (build_x_compound_expr): Likewise.
+ (build_static_cast): Likewise.
+ (build_modify_expr): Likewise.
+
+ * cp-tree.h (DECL_VINDEX): Add documentation.
+ * class.c (build_vtable_entry): Likewise.
+ (start_vtable): Add comment.
+ (add_virtual_function): Replace pending_hard_virtuals with
+ overridden_virtuals and pending_virtuals with new_virtuals.
+ Replace redundant assignments with assertions.
+ (check_for_override): Add comment.
+ (check_bases_and_members): Replace pending_hard_virtuals with
+ overridden_virtuals and pending_virtuals with new_virtuals.
+ (create_vtbl_ptr): Likewise.
+ (layout_class_type): Likewise.
+ (finish_struct_1): Likewise. Add comments.
+
+2000-01-16 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (finish_struct_1): Replace redundant code with
+ assertions.
+
+ * cp-tree.h (flag_new_abi): Move.
+ (flag_use_cxa_atexit): Likewise.
+ (flag_honor_std): Likewise.
+ (flag_rtti): Likewise.
+ (vbase_offsets_in_vtable_p): Define.
+ (vptrs_present_everywhere_p): Likewise.
+ (TYPE_CONTAINS_VPTR_P): Likewise.
+ (dfs_walk_real): Declare.
+ * class.c (build_vbase_pointer_fields): Check
+ vbase_offsets_in_vtable_p.
+ (dfs_build_vbase_offset_vtbl_entries): Record the vbase indices in
+ BINFO_VPTR_FIELD.
+ (build_vbase_offset_vtbl_entries): Simplify.
+ (build_vbase_offset_vtbl_entries): Adjust.
+ (build_vbase_pointer): Add ability to look up vbase offsets in
+ vtable.
+ (start_vtable): New function.
+ (add_virtual_function): Use it.
+ (determine_primary_base): Use TYPE_CONTAINS_VPTR_P.
+ (num_extra_vtbl_entries): Use vbase_offsets_in_vtable_p.
+ (build_vtbl_initializer): Take the type of the complete object as
+ input. Use it to correctly calculate vbase offsets.
+ (dfs_finish_vtbls): Pass the complete type to
+ build_vtbl_initializer.
+ (check_bases_and_members): Use TYPE_CONTAINS_VPTR_P.
+ (create_vtable_ptr): Create a vtable even if there are no
+ new virtual functions, under the new ABI.
+ (finish_struct_1): Likewise.
+ (get_vfield_name): Use TYPE_CONTAINS_VPTR_P.
+ * decl.c (exapnd_static_init): Remove call to
+ preserve_initializer.
+ * decl2.c (mark_vtable_entries): Tweak to handle vbase offsets in
+ vtables.
+ * init.c (initialize_vtbl_ptrs): Initialize them in pre-order.
+ (expand_virtual_init): Use vbase_offsets_in_vtable_p.
+ (construct_virtual_bases): Don't initialize virtual base pointers
+ under the new ABI.
+ (build_aggr_init): Clean up comment.
+ (expand_aggr_init_1): Likewise.
+ * rtti.c (expand_class_desc): Store the virtual function table
+ index where the vbase offset lives in the offset field.
+ * search.c (dfs_walk_real): Make it global.
+ (dfs_debug_mark): Use TYPE_CONTAINS_VPTR_P.
+ * tree.c (make_binfo): Don't clear BINFO_VPTR_FIELD.
+
+ * tinfo.h (USItype): Make it signed under the new ABI.
+ * tinfo.cc (convert_to_base): New function. Encapsulate base
+ conversion logic here.
+ (__class_type_info::do_upcast): Use it.
+ (__class_type_info::do_dyncast): Likewise.
+ (__class_type_info::do_find_public_subobj): Likewise.
+
+ * init.c (construct_virtual_bases): Don't look up the addresses of
+ virtual bases at run-time.
+
+ * class.c (build_vbase_pointer): Relocate.
+ (build_vbase_pointer_fields): Likewise.
+ (dfs_build_vbase_offset_vtbl_entries): Likewise.
+ (build_vbase_offset_vtbl_entries): Likewise.
+
+ * decl.c (init_decl_processing): Complain if -fnew-abi
+ -fno-vtable-thunks is used.
+
+ * decl2.c (lang_decode_option): Don't couple flag_honor_std to
+ flag_new_abi.
+
+2000-01-15 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (num_extra_vtbl_entries): New function.
+ (size_extra_vtbl_entries): Likewise.
+ (dfs_vtable_path_unmark): Likewise.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): Likewise.
+ (dfs_vtable_path_marked_real_bases_queue_p): Likewise.
+ * class.c (num_extra_vtbl_entries): New function.
+ (size_extra_vtbl_entries): Likewise.
+ (dfs_build_vbase_offset_vtbl_entries): New function.
+ (build_vbase_offset_vtbl_entries): Likewise.
+ (build_vtbl_initializer): Use it.
+ (finish_struct_1): Adjust vtable sizes (using
+ num_extra_vtbl_entries).
+ * expr.c (cplus_expand_expr): Assert that the DECL_RTL for a
+ THUNK_DECL is non-NULL before expanding it.
+ * init.c (expand_virtual_init): Adjust the vtable pointer by
+ size_extra_vtbl_entries before storing it.
+ * search.c (get_shared_vase_if_not_primary): Adjust prototype.
+ Handle TREE_LIST parameters here, not in the dfs_* functions.
+ (dfs_unmarked_real_bases_queue_p): Adjust.
+ (dfs_marked_real_bases_queue_p): Likewise.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): New function.
+ (dfs_vtable_path_marked_real_bases_queue_p): New function.
+ (dfs_vtable_path_unmark): Likewise.
+
+2000-01-14 Mark Mitchell <mark@codesourcery.com>
+
+ * optimize.c (copy_body_r): Clear the operand three of a
+ TARGET_EXPR when copying it.
+
+2000-01-14 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * method.c (build_decl_overload_real): Check whether we are in ::
+ before returning __builtin_new/delete.
+
+2000-01-13 Mark Mitchell <mark@codesourcery.com>
+
+ * pt.c (tsubst_friend_function): Improve comment.
+ (instantiate_decl): Avoid crashing when a "nested" function is
+ instantiated from the top level.
+
+ * dump.c (dqeueue_and_dump): Dump
+ DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION.
+
+2000-01-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * call.c: If GATHER_STATISTICS, declare `n_build_method_call'.
+
+2000-01-13 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * g++spec.c (lang_specific_driver): Add -fnew-abi if
+ ENABLE_NEW_GXX_ABI defined.
+ * Make-lang.in (tinfo.o, tinfo2.o, exception.o, new.o,
+ opnew.o, opnewnt.o, opvnew.o, opvnewnt.o, opdel.o, opdelnt.o,
+ opvdel.o, opvdelnt.o): Use GXX_ABI_FLAG switch.
+
+2000-01-12 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (start_cleanup_fn): Call pushdecl.
+
+ * call.c (convert_class_to_reference): Fix typos.
+ (build_conditional_expr): Handle errors gracefully.
+ * class.c (push_nested_class): Likewise.
+ * cp-tree.h (VAR_FUNCTION_OR_PARM_DECL_CHECK): New macro.
+ (DECL_THIS_EXTERN): Use it.
+ (DECL_THIS_STATIC): Likewise.
+ * cvt.c (convert_to_void): Handle errors gracefully.
+ (build_expr_type_conversion): Likewise.
+ * decl.c (maybe_push_decl): Likewise.
+ (start_decl_1): Likewise.
+ (require_complete_types_for_parms): Likewise.
+ * parse.y (structsp): Likewise.
+ (base_class): Likewise.
+ * parse.c: Regenerated.
+ * pt.c (finish_member_template_decl): Likewise.
+ * typeck.c (decay_conversion): Likewise.
+
+ * cp-tree.h (dfs_skip_vbases): New function.
+ (find_vbase_instance): Likewise.
+ * class.c (determine_primary_base): Allow a nearly empty base to
+ serve as a primary base class under the new ABI.
+ (get_class_offset_1): Rename to ...
+ (dfs_get_class_offset): ... this. Simplify. Don't issue error
+ messages here.
+ (get_class_offset): Use it. Issue error messages here.
+ (dfs_modify_vtables): Rely on dfs_unmarked_real_bases_queue_p to
+ find the right copies of virtual bases.
+ (fixup_vtable_deltas1): Rename to ...
+ (dfs_fixup_vtable_deltas): ... this. Adjust to handle virtual
+ bases as primary bases.
+ (fixup_vtable_deltas): Remove.
+ (override_one_vtable): Handle virtual bases as primary bases.
+ (merge_overrides): Likewise.
+ (finish_struct_1): Likewise.
+ (dump_class_hierarchy): Dump primary-ness of bases as well.
+ * search.c (mark_primary_bases): Use a pre-order traversal to
+ handle primary virtual bases.
+ (dfs_skip_vbases): New fiunction.
+ (expand_upcast_fixups): Adjust to handle primary virtual bases.
+ (fixup_virtual_upcast_offsets): Likewise.
+ (fixup_all_virtual_upcast_offsets): Likewise.
+ (dfs_find_vbase_instances): New function.
+ (find_vbase_instance): Likewise.
+
+2000-01-11 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * lex.c (DIR_SEPARATOR): Delete macro.
+
+2000-01-12 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * decl2.c (lang_decode_option): Handle automatic line wrapping
+ option.
+
+2000-01-11 Mark Mitchell <mark@codesourcery.com>
+
+ * friend.c (do_friend): Don't resolve scopes when processing
+ template declarations, even if the qualifying scope doesn't
+ involve template parameters.
+
+2000-01-10 Mark Mitchell <mitchell@dumbledore.codesourcery.com>
+
+ * class.c (dfs_modify_vtables_queue_p): Remove.
+ (modify_all_vtables): Use dfs_unmarked_real_bases_queue_p
+ and dfs_marked_real_bases_queue_p instead of
+ dfs_modify_vtables_queue_p.
+
+ * class.c (build_vbase_path): Simplify.
+ (dfs_propagate_binfo_offsets): New function.
+ (propagate_binfo_offsets): Use it.
+ (remove_base_field): Simplify.
+ (dfs_set_offset_for_vbases): Remove.
+ (dfs_set_offset_for_shared_vbases): New function.
+ (dfs_set_offset_for_unshared_vbases): Likewise.
+ (layout_virtual_bases): Use them.
+ (layout_basetypes): Don't call propagate_binfo_offsets.
+ * search.c (dfs_get_vbase_types): Clone completely fresh binfos
+ for the vbases.
+
+ * class.c (build_base_field): New function, split out from ...
+ (build_base_fields): ... here. Use it. Allocate primary bases
+ first, under the new ABI.
+ (get_vtable_entry): Remove.
+ (remove_base_field): New function, split out from ...
+ (remove_base_fields): ... here. Adjust since primary bases come
+ first under the new ABI.
+
+ * cp-tree.h (expand_direct_vtbls_init): Remove declaration.
+ (initialize_vtbl_ptrs): New function.
+ (expand_indirect_vtbls_init): Change prototype.
+ (convert_pointer_to_vbase): Declare.
+ * init.c (expand_direct_vtbls_init): Remove.
+ (dfs_initialize_vtbl_ptrs): New function.
+ (initialize_vtbl_ptrs): Likewise.
+ (emit_base_init): Use initialize_vtbl_ptrs.
+ * search.c (convert_pointer_to_vbase): Make it global.
+ (expand_indirect_vtbls_init): Remove vtable initialization code.
+ * semantics.c (setup_vtbl_ptr): Use initialize_vtbl_ptrs.
+
+ * class.c (dfs_finish_vtbls): New function.
+ (finish_vtbls): Use it.
+ (dump_class_hierarchy): New function.
+
+ * cp-tree.h (BINFO_PRIMARY_MARKED_P): Change definition.
+ (BINFO_VBASE_PRIMARY_P): New macro.
+ (BINFO_VIRTUALS): Add to documentation.
+ (SET_BINFO_PRIMARY_MARKED_P): Remove.
+ (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
+ (dfs_mark_primary_bases_queue_p): Likewise.
+ (dfs_unmarked_real_bases_queue_p): New function.
+ (dfs_marked_real_bases_queue_p): Likewise.
+ * search.c (dfs_mark_primary_bases): Adjust.
+ (mark_primary_bases): Likewise.
+ (get_shared_vbase_if_not_primary): New function.
+ (dfs_unmarked_real_bases_queue_p): Likewise.
+ (dfs_marked_real_bases_queue_p): Likewise.
+ (dfs_get_pure_virtuals): Simplify.
+ (get_pure_virtuals): Likewise.
+
+2000-01-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lex.c: Include tm_p.h.
+
+2000-01-07 Nathan Sidwell <sidwell@codesourcery.com>
+
+ * lang-specs.h (__GXX_ABI_VERSION): New preprocessor macro.
+
+2000-01-06 Jason Merrill <jason@casey.cygnus.com>
+
+ * decl2.c (comdat_linkage): Don't set DECL_DEFER_OUTPUT.
+ * pt.c (instantiate_decl): Defer comdat templates that might not be
+ needed.
+
+ * cp-tree.h (DECL_NEEDED_P): Also true if !DECL_COMDAT.
+ * decl2.c (finish_vtable_vardecl): Don't check !DECL_COMDAT.
+ (finish_file): Likewise.
+
+ * decl2.c (import_export_class): Undo 12/14 change.
+
+ * error.c (dump_decl): operator new, not operatornew.
+
+ * class.c (field_decl_cmp): A nontype is "greater" than a type.
+ * search.c (lookup_field_1): Look for the last field with the
+ desired name.
+
+2000-01-05 Nathan Sidwell <nathan@acm.org>
+
+ * decl2.c (lookup_arg_dependent): Deal with FNS not being a
+ FUNCTION_DECL.
+
+2000-01-05 Nathan Sidwell <nathan@acm.org>
+
+ * typeck.c (build_static_cast): Don't strip target qualifiers
+ when casting from a class.
+
+2000-01-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * class.c (warn_hidden): Initialize variable `fndecl'.
+
+2000-01-03 Ulrich Drepper <drepper@cygnus.com>
+
+ * decl.c (flag_isoc9x): New variable to be able to use code in
+ c-common.c. For now always zero.
+
+2000-01-03 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_VBASECLASSES): Improve documentation.
+ * class.c (layout_basetypes): Don't set BINFO_INHERITANCE_CHAIN
+ or unshare_base_binfos for virtual bases here.
+ * search.c (dfs_get_vbase_types): Do it here.
+ (get_vbase_types): Adjust.
+
+2000-01-02 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_VFIELDS): Move definition.
+ (BINFO_PRIMARY_MARKED_P): Use flag 5.
+ (SET_BINFO_PRIMARY_MARKED_P): Likewise.
+ (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
+ (unmark_primary_bases): Remove declaration.
+ (unmarkedp): Declare.
+ (dfs_vbase_unmark): Likewise.
+ * class.c (determine_primary_base): Return immediately if there
+ are no base classes. Call mark_primary_bases here.
+ (modify_all_direct_vtables): Remove.
+ (modify_all_indirect_vtables): Remove.
+ (dfs_modify_vtables_queue_p): New function.
+ (dfs_modify_vtables): New function.
+ (modify_all_vtables): Use them.
+ (build_base_fields): Build FIELD_DECLs for primary virtual base
+ classes.
+ (create_vtable_ptr): Don't call determine_primary_base here.
+ (dfs_mark_primary_bases_and_set_vbase_offsets): Rename to ...
+ (dfs_set_offset_for_vbases): ... this.
+ (layout_virtual_bases): Use it.
+ (layout_class_type): Call determine_primary_base here.
+ * search.c (unmarkedp): Make it global.
+ (shared_marked_p): Simplify.
+ (shared_unmarked_p): Likewise.
+ (dfs_primary_bases_queue_p): Remove.
+ (dfs_unmark_primary_bases): Likewise.
+ (unmark_primary_bases): Likewise.
+ (mark_primary_bases): Simplify.
+ (get_pure_virtuals): Don't call mark_primary_bases here.
+ (dfs_vbase_unmark): New function.
+ (get_vbase_types): Simplify.
+
+ * class.c (struct base_info): Remove.
+ (determine_primary_base): Take has_virtual_p rather than a
+ base_info as input. Don't calculate max_has_virtual.
+ (finish_struct_bits): Remove max_has_virtual argument.
+ (create_vtable_ptr): Remove max_has_virtual_p argument.
+ (layout_virtual_bases): Remove max argument.
+ (layout_basetypes): Likewise.
+ (layout_class_type): Remove max_has_virtual_p argument.
+ (finish_struct_1): Remove max_has_virtual.
+
+ * cp-tree.h (dfs_mark_primary_bases_queue_p): New function.
+ (layout_basetypes): Remove.
+ * class.c (propagate_binfo_offsets): Moved here from tree.c.
+ Update to handle primary virtual bases.
+ (remove_base_fields): New function, split out from
+ layout_basetypes.
+ (dfs_mark_primary_bases_and_set_vbase_offsets): New function.
+ (layout_virtual_bases): New function, split out from
+ layout_basetypes. Update to handle primary virtual bases.
+ (layout_basetypes): Moved here from tree.c. Use
+ remove_base_fields and layout_virtual_bases.
+ * search.c (dfs_mark_primary_bases_queue_p): New function.
+ (mark_primary_bases): Use it.
+ * tree.c (CEIL): Remove.
+ (propagate_binfo_offsets): Remove.
+ (layout_basetypes): Remove.
+
+2000-01-01 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (CLASSTYPE_N_BASECLASSES): Use BINFO_N_BASETYPES.
+ (BINFO_PRIMARY_MARKED_P): New macro.
+ (SET_BINFO_PRIMARY_MARKED_P): Likewise.
+ (CLEAR_BINFO_PRIMARY_MARKED_P): Likewise.
+ (mark_primary_bases): New function.
+ (unmark_primary_bases): Likewise.
+ * search.c (get_abstract_virtuals_1): Remove.
+ (dfs_mark_primary_bases): New function.
+ (mark_primary_bases): Likewise.
+ (dfs_unmark_primary_bases): Likewise.
+ (unmark_primary_bases): Likewise.
+ (dfs_get_pure_virtuals): Likewise.
+
+2000-01-01 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (skip_rtti_stuff): Adjust prototype.
+ * class.c (skip_rtti_stuff): Reorganize parameters and return value.
+ (modify_one_vtable): Adjust.
+ (fixup_vtable_deltas1): Likewise.
+ (override_one_vtable): Likewise.
+ * search.c (get_abstract_virtuals_1): Likewise.
+ (get_pure_virtuals): Likewise.
+ (expand_upcast_fixups): Likewise.
+ * tree.c (debug_binfo): Likewise.
+
+ * class.c (build_vtable): Don't return a value. Don't rebuild
+ vtables for bases that have already been handled.
+ (prepare_fresh_vtable): Don't rebuild vtables for bases that have
+ already been handled.
+ (modify_one_vtable): Adjust accordingly.
+ (fixup_vtable_deltas1): Likewise.
+ (finish_struct_1): Likewise.
+
+2000-01-01 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * call.c (build_new_method_call): Also check destructors.
+
+See ChangeLog.2 for earlier changes.
diff --git a/contrib/gcc/cp/Make-lang.in b/contrib/gcc/cp/Make-lang.in
index afeb7aba4f80..9f7ebfb87cc2 100644
--- a/contrib/gcc/cp/Make-lang.in
+++ b/contrib/gcc/cp/Make-lang.in
@@ -1,21 +1,21 @@
# Top level -*- makefile -*- fragment for GNU C++.
-# Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001
+# Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
-#This file is part of GNU CC.
+#This file is part of GCC.
-#GNU CC is free software; you can redistribute it and/or modify
+#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 2, or (at your option)
#any later version.
-#GNU CC is distributed in the hope that it will be useful,
+#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 GNU CC; see the file COPYING. If not, write to
+#along with GCC; see the file COPYING. If not, write to
#the Free Software Foundation, 59 Temple Place - Suite 330,
#Boston, MA 02111-1307, USA.
@@ -23,10 +23,9 @@
# Each language makefile fragment must provide the following targets:
#
# foo.all.build, foo.all.cross, foo.start.encap, foo.rest.encap,
-# foo.info, foo.dvi,
-# foo.install-normal, foo.install-common, foo.install-info, foo.install-man,
+# foo.install-normal, foo.install-common, foo.install-man,
# foo.uninstall,
-# foo.mostlyclean, foo.clean, foo.distclean, foo.extraclean,
+# foo.mostlyclean, foo.clean, foo.distclean,
# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4
#
# where `foo' is the name of the language.
@@ -38,14 +37,10 @@
# - define the names for selecting the language in LANGUAGES.
# Actual names to use when installing a native compiler.
-CXX_INSTALL_NAME = `echo c++|sed '$(program_transform_name)'`
-GXX_INSTALL_NAME = `echo g++|sed '$(program_transform_name)'`
-CXX_TARGET_INSTALL_NAME = $(target_alias)-`echo c++|sed '$(program_transform_name)'`
-GXX_TARGET_INSTALL_NAME = $(target_alias)-`echo g++|sed '$(program_transform_name)'`
-
-# Actual names to use when installing a cross-compiler.
-CXX_CROSS_NAME = `echo c++|sed '$(program_transform_cross_name)'`
-GXX_CROSS_NAME = `echo g++|sed '$(program_transform_cross_name)'`
+CXX_INSTALL_NAME := $(shell echo c++|sed '$(program_transform_name)')
+GXX_INSTALL_NAME := $(shell echo g++|sed '$(program_transform_name)')
+CXX_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo c++|sed '$(program_transform_name)')
+GXX_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo g++|sed '$(program_transform_name)')
#
# Define the names for selecting c++ in LANGUAGES.
@@ -57,14 +52,12 @@ C++ c++: cc1plus$(exeext)
# Tell GNU make to ignore these if they exist.
.PHONY: C++ c++
-g++spec.o: $(srcdir)/cp/g++spec.c $(SYSTEM_H) $(GCC_H) $(CONFIG_H)
+g++spec.o: $(srcdir)/cp/g++spec.c $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) $(CONFIG_H)
(SHLIB_LINK='$(SHLIB_LINK)' \
SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \
$(INCLUDES) $(srcdir)/cp/g++spec.c)
-po-generated: $(srcdir)/cp/parse.c
-
# Create the compiler driver for g++.
GXX_OBJS = gcc.o g++spec.o intl.o prefix.o version.o
g++$(exeext): $(GXX_OBJS) $(EXTRA_GCC_OBJS) $(LIBDEPS)
@@ -79,17 +72,18 @@ g++-cross$(exeext): g++$(exeext)
# The compiler itself.
# Shared with C front end:
CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
- c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o
+ c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \
+ c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o
# Language-specific object files.
CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
- cp/class.o cp/decl2.o cp/error.o cp/lex.o cp/parse.o cp/ptree.o cp/rtti.o \
- cp/spew.o cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \
- cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o \
- cp/optimize.o cp/mangle.o cp/cp-lang.o
+ cp/class.o cp/decl2.o cp/error.o cp/lex.o cp/parser.o cp/ptree.o cp/rtti.o \
+ cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \
+ cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o cp/optimize.o \
+ cp/mangle.o cp/cp-lang.o cp/name-lookup.o cp/cxx-pretty-print.o
-# Use loose warnings for this front end.
-cp-warn =
+# Use strict warnings for this front end.
+cp-warn = $(STRICT_WARN) $(WERROR)
cc1plus$(exeext): $(CXX_OBJS) $(CXX_C_OBJS) $(BACKEND) \
libcpp.a $(LIBDEPS)
@@ -98,25 +92,12 @@ cc1plus$(exeext): $(CXX_OBJS) $(CXX_C_OBJS) $(BACKEND) \
# Special build rules.
$(srcdir)/cp/cfns.h: $(srcdir)/cp/cfns.gperf
- gperf -o -C -E -k '1-6,$$' -j1 -D -N 'libc_name_p' \
+ gperf -o -C -E -k '1-6,$$' -j1 -D -N 'libc_name_p' -L ANSI-C \
$(srcdir)/cp/cfns.gperf > $(srcdir)/cp/cfns.h
-$(srcdir)/cp/parse.h: $(srcdir)/cp/parse.c
-$(srcdir)/cp/parse.c: $(srcdir)/cp/parse.y
- @echo "Expect 33 shift/reduce conflicts and 58 reduce/reduce conflicts."
- cd $(srcdir)/cp && \
- if $(BISON) $(BISONFLAGS) -d -o p$$$$.c parse.y; then \
- grep '^#define[ ]*YYEMPTY' p$$$$.c >> p$$$$.h ; \
- test -f p$$$$.output && mv -f p$$$$.output parse.output ; \
- mv -f p$$$$.c parse.c ; mv -f p$$$$.h parse.h ; \
- else \
- rm -f p$$$$.* ; \
- false ; \
- fi
-
gtype-cp.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h : s-gtype; @true
-gt-cp-parse.h gt-cp-pt.h gt-cp-repo.h gt-cp-spew.h : s-gtype; @true
-gt-cp-tree.h gt-cp-mangle.h : s-gtype; @true
+gt-cp-pt.h gt-cp-repo.h gt-cp-parser.h gt-cp-method.h : s-gtype; @true
+gt-cp-tree.h gt-cp-mangle.h gt-cp-name-lookup.h: s-gtype; @true
#
# Build hooks:
@@ -125,10 +106,22 @@ c++.all.build: g++$(exeext)
c++.all.cross: g++-cross$(exeext)
c++.start.encap: g++$(exeext)
c++.rest.encap:
+c++.info:
+c++.srcinfo:
+c++.srcextra:
-c++.info:
-c++.dvi:
-c++.generated-manpages:
+c++.tags: force
+ cd $(srcdir)/cp; etags -o TAGS.sub *.c *.h --language=none \
+ --regex='/DEFTREECODE [(]\([A-Z_]+\)/\1/' cp-tree.def; \
+ etags --include TAGS.sub --include ../TAGS.sub
+
+c++.man: doc/g++.1
+
+c++.srcman: doc/g++.1
+ -cp -p $^ $(srcdir)/doc
+
+check-c++ : check-g++
+lang_checks += check-g++
#
# Install hooks:
@@ -140,14 +133,14 @@ c++.install-normal:
# Install the driver program as $(target)-g++
# and also as either g++ (if native) or $(tooldir)/bin/g++.
c++.install-common: installdirs
+ -rm -f $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext)
+ -$(INSTALL_PROGRAM) g++$(exeext) $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext)
+ -chmod a+x $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext)
+ -rm -f $(DESTDIR)$(bindir)/$(CXX_INSTALL_NAME)$(exeext)
+ -( cd $(DESTDIR)$(bindir) && \
+ $(LN) $(GXX_INSTALL_NAME)$(exeext) $(CXX_INSTALL_NAME)$(exeext) )
-if [ -f cc1plus$(exeext) ] ; then \
if [ -f g++-cross$(exeext) ] ; then \
- rm -f $(DESTDIR)$(bindir)/$(GXX_CROSS_NAME)$(exeext); \
- $(INSTALL_PROGRAM) g++-cross$(exeext) $(DESTDIR)$(bindir)/$(GXX_CROSS_NAME)$(exeext); \
- chmod a+x $(DESTDIR)$(bindir)/$(GXX_CROSS_NAME)$(exeext); \
- rm -f $(DESTDIR)$(bindir)/$(CXX_CROSS_NAME)$(exeext); \
- ( cd $(DESTDIR)$(bindir) && \
- $(LN) $(GXX_CROSS_NAME)$(exeext) $(CXX_CROSS_NAME)$(exeext) ); \
if [ -d $(DESTDIR)$(gcc_tooldir)/bin/. ] ; then \
rm -f $(DESTDIR)$(gcc_tooldir)/bin/g++$(exeext); \
$(INSTALL_PROGRAM) g++-cross$(exeext) $(DESTDIR)$(gcc_tooldir)/bin/g++$(exeext); \
@@ -156,12 +149,6 @@ c++.install-common: installdirs
$(LN) g++$(exeext) c++$(exeext) ); \
else true; fi; \
else \
- rm -f $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext); \
- $(INSTALL_PROGRAM) g++$(exeext) $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext); \
- chmod a+x $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext); \
- rm -f $(DESTDIR)$(bindir)/$(CXX_INSTALL_NAME)$(exeext); \
- ( cd $(DESTDIR)$(bindir) && \
- $(LN) $(GXX_INSTALL_NAME)$(exeext) $(CXX_INSTALL_NAME)$(exeext) ); \
rm -f $(DESTDIR)$(bindir)/$(GXX_TARGET_INSTALL_NAME)$(exeext); \
( cd $(DESTDIR)$(bindir) && \
$(LN) $(GXX_INSTALL_NAME)$(exeext) $(GXX_TARGET_INSTALL_NAME)$(exeext) ); \
@@ -171,43 +158,35 @@ c++.install-common: installdirs
fi ; \
fi
-c++.install-info:
+# We can't use links because not everyone supports them, and we can't use
+# .so because Irix 6.5 doesn't support them. So just copy the manpage.
+doc/g++.1: doc/gcc.1
+ cp doc/gcc.1 doc/g++.1
-c++.install-man: installdirs $(srcdir)/cp/g++.1
- -if [ -f cc1plus$(exeext) ] ; then \
- if [ -f g++-cross$(exeext) ] ; then \
- rm -f $(DESTDIR)$(man1dir)/$(GXX_CROSS_NAME)$(man1ext); \
- $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(DESTDIR)$(man1dir)/$(GXX_CROSS_NAME)$(man1ext); \
- chmod a-x $(DESTDIR)$(man1dir)/$(GXX_CROSS_NAME)$(man1ext); \
- else \
- rm -f $(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext); \
- $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext); \
- chmod a-x $(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext); \
- fi; \
- else true; fi
+c++.install-man: installdirs $(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext)
+
+$(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext): doc/g++.1
+ -rm -f $@
+ -$(INSTALL_DATA) $< $@
+ -chmod a-x $@
c++.uninstall:
-rm -rf $(DESTDIR)$(bindir)/$(CXX_INSTALL_NAME)$(exeext)
- -rm -rf $(DESTDIR)$(bindir)/$(CXX_CROSS_NAME)$(exeext)
-rm -rf $(DESTDIR)$(bindir)/$(GXX_INSTALL_NAME)$(exeext)
- -rm -rf $(DESTDIR)$(bindir)/$(GXX_CROSS_NAME)$(exeext)
-rm -rf $(DESTDIR)$(man1dir)/$(GXX_INSTALL_NAME)$(man1ext)
- -rm -rf $(DESTDIR)$(man1dir)/$(GXX_CROSS_NAME)$(man1ext)
#
# Clean hooks:
# A lot of the ancillary files are deleted by the main makefile.
# We just have to delete files specific to us.
c++.mostlyclean:
+ -rm -f doc/g++.1
-rm -f cp/*$(objext)
-rm -f cp/*$(coverageexts)
c++.clean:
c++.distclean:
-rm -f cp/config.status cp/Makefile
- -rm -f $(srcdir)/cp/parse.output
-c++.extraclean:
c++.maintainer-clean:
- -rm -f $(srcdir)/cp/parse.c $(srcdir)/cp/parse.h
#
# Stage hooks:
# The main makefile has already created stage?/cp.
@@ -220,74 +199,72 @@ c++.stage3: stage3-start
-mv cp/*$(objext) stage3/cp
c++.stage4: stage4-start
-mv cp/*$(objext) stage4/cp
+c++.stageprofile: stageprofile-start
+ -mv cp/*$(objext) stageprofile/cp
+c++.stagefeedback: stagefeedback-start
+ -mv cp/*$(objext) stagefeedback/cp
#
# .o: .h dependencies.
-CXX_TREE_H = $(TREE_H) cp/cp-tree.h c-common.h cp/cp-tree.def c-common.def \
- function.h varray.h $(SYSTEM_H) $(CONFIG_H) $(TARGET_H) \
+CXX_TREE_H = $(TREE_H) cp/name-lookup.h cp/cp-tree.h c-common.h \
+ cp/cp-tree.def c-common.def \
+ function.h varray.h $(SYSTEM_H) coretypes.h $(CONFIG_H) $(TARGET_H) \
+ $(GGC_H) \
$(srcdir)/../include/hashtab.h $(srcdir)/../include/splay-tree.h
-cp/spew.o: cp/spew.c $(CXX_TREE_H) $(srcdir)/cp/parse.h flags.h cp/lex.h \
- toplev.h gt-cp-spew.h
-cp/lex.o: cp/lex.c $(CXX_TREE_H) $(srcdir)/cp/parse.h flags.h cp/lex.h \
- c-pragma.h toplev.h output.h mbchar.h $(GGC_H) input.h diagnostic.h \
- cp/operators.def $(TM_P_H)
-cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) toplev.h langhooks.h $(LANGHOOKS_DEF_H) \
- c-common.h
-cp/decl.o: cp/decl.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h stack.h \
- output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(GGC_H) $(RTL_H) \
+CXX_PRETTY_PRINT_H = cp/cxx-pretty-print.h $(C_PRETTY_PRINT_H)
+
+cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h \
+ c-pragma.h toplev.h output.h input.h cp/operators.def $(TM_P_H)
+cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h langhooks.h \
+ $(LANGHOOKS_DEF_H) c-common.h $(CXX_PRETTY_PRINT_H) $(DIAGNOSTIC_H)
+cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h stack.h \
+ output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \
cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h \
- debug.h gt-cp-decl.h gtype-cp.h timevar.h input.h
-cp/decl2.o: cp/decl2.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \
- output.h except.h toplev.h $(GGC_H) $(RTL_H) c-common.h gt-cp-decl2.h \
- timevar.h
-cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) flags.h toplev.h output.h $(TM_P_H) \
+ debug.h gt-cp-decl.h gtype-cp.h timevar.h
+cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \
+ output.h except.h toplev.h $(RTL_H) c-common.h gt-cp-decl2.h cgraph.h
+cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h output.h $(TM_P_H) \
diagnostic.h
-cp/typeck.o: cp/typeck.c $(CXX_TREE_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
- diagnostic.h
-cp/class.o: cp/class.c $(CXX_TREE_H) flags.h toplev.h $(RTL_H) $(TARGET_H)
-cp/call.o: cp/call.c $(CXX_TREE_H) flags.h toplev.h $(RTL_H) $(EXPR_H) \
- $(GGC_H) diagnostic.h gt-cp-call.h
-cp/friend.o: cp/friend.c $(CXX_TREE_H) flags.h $(RTL_H) toplev.h $(EXPR_H)
-cp/init.o: cp/init.c $(CXX_TREE_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
- $(GGC_H) except.h
-cp/method.o: cp/method.c $(CXX_TREE_H) toplev.h $(GGC_H) $(RTL_H) $(EXPR_H) \
- $(TM_P_H) $(TARGET_H)
-cp/cvt.o: cp/cvt.c $(CXX_TREE_H) cp/decl.h flags.h toplev.h convert.h
-cp/search.o: cp/search.c $(CXX_TREE_H) stack.h flags.h toplev.h $(RTL_H)
-cp/tree.o: cp/tree.c $(CXX_TREE_H) flags.h toplev.h $(GGC_H) $(RTL_H) \
+cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
+ diagnostic.h convert.h
+cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) $(TARGET_H) convert.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
+cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) toplev.h $(EXPR_H)
+cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
+ except.h
+cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(RTL_H) $(EXPR_H) \
+ $(TM_P_H) $(TARGET_H) gt-cp-method.h
+cp/cvt.o: cp/cvt.c $(CXX_TREE_H) $(TM_H) cp/decl.h flags.h toplev.h convert.h
+cp/search.o: cp/search.c $(CXX_TREE_H) $(TM_H) stack.h flags.h toplev.h $(RTL_H)
+cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) \
insn-config.h integrate.h tree-inline.h real.h gt-cp-tree.h $(TARGET_H)
-cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(SYSTEM_H)
-cp/rtti.o: cp/rtti.c $(CXX_TREE_H) flags.h toplev.h
-cp/except.o: cp/except.c $(CXX_TREE_H) flags.h $(RTL_H) except.h toplev.h \
+cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(TM_H)
+cp/rtti.o: cp/rtti.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h convert.h
+cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) except.h toplev.h \
cp/cfns.h $(EXPR_H) libfuncs.h tree-inline.h
-cp/expr.o: cp/expr.c $(CXX_TREE_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \
+cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \
except.h $(TM_P_H)
-cp/pt.o: cp/pt.c $(CXX_TREE_H) cp/decl.h $(srcdir)/cp/parse.h cp/lex.h \
- toplev.h $(GGC_H) $(RTL_H) except.h tree-inline.h gt-cp-pt.h
-cp/error.o: cp/error.c $(CXX_TREE_H) toplev.h diagnostic.h flags.h real.h \
- $(LANGHOOKS_DEF_H)
-cp/repo.o: cp/repo.c $(CXX_TREE_H) toplev.h $(GGC_H) diagnostic.h \
+cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/lex.h \
+ toplev.h $(RTL_H) except.h tree-inline.h gt-cp-pt.h
+cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) toplev.h $(DIAGNOSTIC_H) \
+ flags.h real.h $(LANGHOOKS_DEF_H) $(CXX_PRETTY_PRINT_H)
+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) cp/lex.h except.h toplev.h \
- flags.h $(GGC_H) debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \
- tree-inline.h
-cp/dump.o: cp/dump.c $(CXX_TREE_H) tree-dump.h
-cp/optimize.o: cp/optimize.c $(CXX_TREE_H) rtl.h integrate.h insn-config.h \
+cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) cp/lex.h except.h toplev.h \
+ flags.h debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \
+ tree-inline.h cgraph.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
-cp/mangle.o: cp/mangle.c $(CXX_TREE_H) toplev.h real.h gt-cp-mangle.h $(TM_P_H)
+cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h $(TM_P_H)
-cp/parse.o: cp/parse.c $(CXX_TREE_H) flags.h cp/lex.h except.h output.h \
- cp/decl.h $(SYSTEM_H) toplev.h $(GGC_H) gt-cp-parse.h
- $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
- $(srcdir)/cp/parse.c $(OUTPUT_OPTION)
-#
-# These exist for maintenance purposes.
+cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) diagnostic.h gt-cp-parser.h output.h
-# Update the tags table.
-cp/TAGS: force
- cd $(srcdir)/cp ; \
- etags --no-globals -l c `echo *.c | sed 's/parse.c//'` \
- parse.y *.h ../*.c ../*.h;
+cp/name-lookup.o: cp/name-lookup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TM_H) $(CXX_TREE_H) timevar.h gt-cp-name-lookup.h toplev.h \
+ $(DIAGNOSTIC_H) flags.h
-.PHONY: cp/TAGS
+cp/cxx-pretty-print.o: cp/cxx-pretty-print.c $(CXX_PRETTY_PRINT_H) \
+ $(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h $(CXX_TREE_H)
diff --git a/contrib/gcc/cp/NEWS b/contrib/gcc/cp/NEWS
index 36720c60443a..75a5823fc96b 100644
--- a/contrib/gcc/cp/NEWS
+++ b/contrib/gcc/cp/NEWS
@@ -1,3 +1,7 @@
+*** Changes in GCC 3.4:
+
+* Changes in GCC 3.4 are described in 'gcc-3.4/changes.html'
+
*** Changes in GCC 3.3:
* The "new X = 3" extension has been removed; you must now use "new X(3)".
diff --git a/contrib/gcc/cp/call.c b/contrib/gcc/cp/call.c
index 1a1a493774b1..b1353f5a36a5 100644
--- a/contrib/gcc/cp/call.c
+++ b/contrib/gcc/cp/call.c
@@ -1,23 +1,23 @@
/* Functions related to invoking methods and overloaded functions.
- Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) and
modified by Brendan Kehoe (brendan@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -26,6 +26,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "output.h"
@@ -33,18 +35,17 @@ Boston, MA 02111-1307, USA. */
#include "rtl.h"
#include "toplev.h"
#include "expr.h"
-#include "ggc.h"
#include "diagnostic.h"
-
-extern int inhibit_warnings;
-
-static tree build_field_call PARAMS ((tree, tree, tree));
-static struct z_candidate * tourney PARAMS ((struct z_candidate *));
-static int equal_functions PARAMS ((tree, tree));
-static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int));
-static int compare_ics PARAMS ((tree, tree));
-static tree build_over_call PARAMS ((struct z_candidate *, tree, int));
-static tree build_java_interface_fn_ref PARAMS ((tree, tree));
+#include "intl.h"
+#include "target.h"
+#include "convert.h"
+
+static struct z_candidate * tourney (struct z_candidate *);
+static int equal_functions (tree, tree);
+static int joust (struct z_candidate *, struct z_candidate *, bool);
+static int compare_ics (tree, tree);
+static tree build_over_call (struct z_candidate *, int);
+static tree build_java_interface_fn_ref (tree, tree);
#define convert_like(CONV, EXPR) \
convert_like_real ((CONV), (EXPR), NULL_TREE, 0, 0, \
/*issue_conversion_warnings=*/true)
@@ -52,63 +53,67 @@ static tree build_java_interface_fn_ref PARAMS ((tree, tree));
convert_like_real ((CONV), (EXPR), (FN), (ARGNO), 0, \
/*issue_conversion_warnings=*/true)
static tree convert_like_real (tree, tree, tree, int, int, bool);
-static void op_error PARAMS ((enum tree_code, enum tree_code, tree, tree,
- tree, const char *));
-static tree build_object_call PARAMS ((tree, tree));
-static tree resolve_args PARAMS ((tree));
-static struct z_candidate * build_user_type_conversion_1
- PARAMS ((tree, tree, int));
-static void print_z_candidates PARAMS ((struct z_candidate *));
-static tree build_this PARAMS ((tree));
-static struct z_candidate * splice_viable PARAMS ((struct z_candidate *));
-static int any_viable PARAMS ((struct z_candidate *));
-static int any_strictly_viable PARAMS ((struct z_candidate *));
-static struct z_candidate * add_template_candidate
- PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree,
- tree, tree, int, unification_kind_t));
-static struct z_candidate * add_template_candidate_real
- PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree,
- tree, tree, int, tree, unification_kind_t));
-static struct z_candidate * add_template_conv_candidate
- PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree, tree));
+static void op_error (enum tree_code, enum tree_code, tree, tree,
+ tree, const char *);
+static tree build_object_call (tree, tree);
+static tree resolve_args (tree);
+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 *);
+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);
+static struct z_candidate *add_template_candidate_real
+ (struct z_candidate **, tree, tree, tree, tree, 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);
static void add_builtin_candidates
- PARAMS ((struct z_candidate **, enum tree_code, enum tree_code,
- tree, tree *, int));
+ (struct z_candidate **, enum tree_code, enum tree_code,
+ tree, tree *, int);
static void add_builtin_candidate
- PARAMS ((struct z_candidate **, enum tree_code, enum tree_code,
- tree, tree, tree, tree *, tree *, int));
-static int is_complete PARAMS ((tree));
+ (struct z_candidate **, enum tree_code, enum tree_code,
+ tree, tree, tree, tree *, tree *, int);
+static bool is_complete (tree);
static void build_builtin_candidate
- PARAMS ((struct z_candidate **, tree, tree, tree, tree *, tree *,
- int));
-static struct z_candidate * add_conv_candidate
- PARAMS ((struct z_candidate **, tree, tree, tree, tree, tree));
-static struct z_candidate * add_function_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);
+static struct z_candidate *add_function_candidate
(struct z_candidate **, tree, tree, tree, tree, tree, int);
-static tree implicit_conversion PARAMS ((tree, tree, tree, int));
-static tree standard_conversion PARAMS ((tree, tree, tree));
+static tree implicit_conversion (tree, tree, tree, int);
+static tree standard_conversion (tree, tree, tree);
static tree reference_binding (tree, tree, tree, int);
-static tree non_reference PARAMS ((tree));
-static tree build_conv PARAMS ((enum tree_code, tree, tree));
-static int is_subseq PARAMS ((tree, tree));
-static tree maybe_handle_ref_bind PARAMS ((tree*));
-static void maybe_handle_implicit_object PARAMS ((tree*));
+static tree build_conv (enum tree_code, tree, tree);
+static bool is_subseq (tree, tree);
+static tree maybe_handle_ref_bind (tree *);
+static void maybe_handle_implicit_object (tree *);
static struct z_candidate *add_candidate
- (struct z_candidate **, tree, tree, tree, tree, int);
-static tree source_type PARAMS ((tree));
-static void add_warning PARAMS ((struct z_candidate *, struct z_candidate *));
-static int reference_related_p PARAMS ((tree, tree));
-static int reference_compatible_p PARAMS ((tree, tree));
-static tree convert_class_to_reference PARAMS ((tree, tree, tree));
-static tree direct_reference_binding PARAMS ((tree, tree));
-static int promoted_arithmetic_type_p PARAMS ((tree));
-static tree conditional_conversion PARAMS ((tree, tree));
-static tree call_builtin_trap PARAMS ((void));
+ (struct z_candidate **, tree, tree, tree, tree, tree, int);
+static tree source_type (tree);
+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 tree convert_class_to_reference (tree, tree, tree);
+static tree direct_reference_binding (tree, tree);
+static bool promoted_arithmetic_type_p (tree);
+static tree 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,
+ int, struct z_candidate **);
static tree merge_conversion_sequences (tree, tree);
+static bool magic_varargs_p (tree);
+static tree build_temp (tree, tree, int, void (**)(const char *, ...));
+static void check_constructor_callable (tree, tree);
tree
-build_vfield_ref (datum, type)
- tree datum, type;
+build_vfield_ref (tree datum, tree type)
{
if (datum == error_mark_node)
return error_mark_node;
@@ -124,55 +129,18 @@ build_vfield_ref (datum, type)
datum, TYPE_VFIELD (type));
}
-/* Build a call to a member of an object. I.e., one that overloads
- operator ()(), or is a pointer-to-function or pointer-to-method. */
-
-static tree
-build_field_call (tree instance_ptr, tree decl, tree parms)
-{
- tree instance;
-
- if (decl == error_mark_node || decl == NULL_TREE)
- return decl;
-
- if (TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == VAR_DECL)
- {
- /* If it's a field, try overloading operator (),
- or calling if the field is a pointer-to-function. */
- instance = build_indirect_ref (instance_ptr, NULL);
- instance = build_class_member_access_expr (instance, decl,
- /*access_path=*/NULL_TREE,
- /*preserve_reference=*/false);
-
- if (instance == error_mark_node)
- return error_mark_node;
-
- if (IS_AGGR_TYPE (TREE_TYPE (instance)))
- return build_opfncall (CALL_EXPR, LOOKUP_NORMAL,
- instance, parms, NULL_TREE);
- else if (TREE_CODE (TREE_TYPE (instance)) == FUNCTION_TYPE
- || (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE
- && (TREE_CODE (TREE_TYPE (TREE_TYPE (instance)))
- == FUNCTION_TYPE)))
- return build_function_call (instance, parms);
- }
-
- return NULL_TREE;
-}
-
/* Returns nonzero iff the destructor name specified in NAME
(a BIT_NOT_EXPR) matches BASETYPE. The operand of NAME can take many
forms... */
-int
-check_dtor_name (basetype, name)
- tree basetype, name;
+bool
+check_dtor_name (tree basetype, tree name)
{
name = TREE_OPERAND (name, 0);
/* Just accept something we've already complained about. */
if (name == error_mark_node)
- return 1;
+ return true;
if (TREE_CODE (name) == TYPE_DECL)
name = TREE_TYPE (name);
@@ -195,129 +163,20 @@ check_dtor_name (basetype, name)
NAME will be a class template. */
else if (DECL_CLASS_TEMPLATE_P (name))
- return 0;
+ return false;
else
abort ();
if (name && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (name))
- return 1;
- return 0;
-}
-
-/* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'.
- This is how virtual function calls are avoided. */
-
-tree
-build_scoped_method_call (exp, basetype, name, parms)
- tree exp, basetype, name, parms;
-{
- /* Because this syntactic form does not allow
- a pointer to a base class to be `stolen',
- we need not protect the derived->base conversion
- that happens here.
-
- @@ But we do have to check access privileges later. */
- tree binfo, decl;
- tree type = TREE_TYPE (exp);
-
- if (type == error_mark_node
- || basetype == error_mark_node)
- return error_mark_node;
-
- if (processing_template_decl)
- {
- if (TREE_CODE (name) == BIT_NOT_EXPR
- && TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)
- {
- tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);
- if (type)
- name = build_min_nt (BIT_NOT_EXPR, type);
- }
- name = build_min_nt (SCOPE_REF, basetype, name);
- return build_min_nt (METHOD_CALL_EXPR, name, exp, parms, NULL_TREE);
- }
-
- if (TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
-
- if (TREE_CODE (basetype) == TREE_VEC)
- {
- binfo = basetype;
- basetype = BINFO_TYPE (binfo);
- }
- else
- binfo = NULL_TREE;
-
- /* Check the destructor call syntax. */
- if (TREE_CODE (name) == BIT_NOT_EXPR)
- {
- /* We can get here if someone writes their destructor call like
- `obj.NS::~T()'; this isn't really a scoped method call, so hand
- it off. */
- if (TREE_CODE (basetype) == NAMESPACE_DECL)
- return build_method_call (exp, name, parms, NULL_TREE, LOOKUP_NORMAL);
-
- if (! check_dtor_name (basetype, name))
- error ("qualified type `%T' does not match destructor name `~%T'",
- basetype, TREE_OPERAND (name, 0));
-
- /* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note
- that explicit ~int is caught in the parser; this deals with typedefs
- and template parms. */
- if (! IS_AGGR_TYPE (basetype))
- {
- if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (basetype))
- error ("type of `%E' does not match destructor type `%T' (type was `%T')",
- exp, basetype, type);
-
- return cp_convert (void_type_node, exp);
- }
- }
-
- if (TREE_CODE (basetype) == NAMESPACE_DECL)
- {
- error ("`%D' is a namespace", basetype);
- return error_mark_node;
- }
- if (! is_aggr_type (basetype, 1))
- return error_mark_node;
-
- if (! IS_AGGR_TYPE (type))
- {
- error ("base object `%E' of scoped method call is of non-aggregate type `%T'",
- exp, type);
- return error_mark_node;
- }
-
- decl = build_scoped_ref (exp, basetype, &binfo);
-
- if (binfo)
- {
- /* Call to a destructor. */
- if (TREE_CODE (name) == BIT_NOT_EXPR)
- {
- if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl)))
- return cp_convert (void_type_node, exp);
-
- return build_delete (TREE_TYPE (decl), decl,
- sfk_complete_destructor,
- LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR,
- 0);
- }
-
- /* Call to a method. */
- return build_method_call (decl, name, parms, binfo,
- LOOKUP_NORMAL|LOOKUP_NONVIRTUAL);
- }
- return error_mark_node;
+ return true;
+ return false;
}
/* We want the address of a function or method. We avoid creating a
pointer-to-member function. */
tree
-build_addr_func (function)
- tree function;
+build_addr_func (tree function)
{
tree type = TREE_TYPE (function);
@@ -325,24 +184,16 @@ build_addr_func (function)
functions. */
if (TREE_CODE (type) == METHOD_TYPE)
{
- tree addr;
-
- type = build_pointer_type (type);
-
- if (!cxx_mark_addressable (function))
- return error_mark_node;
-
- addr = build1 (ADDR_EXPR, type, function);
-
- /* Address of a static or external variable or function counts
- as a constant */
- if (staticp (function))
- TREE_CONSTANT (addr) = 1;
-
- function = addr;
+ if (TREE_CODE (function) == OFFSET_REF)
+ {
+ tree object = build_address (TREE_OPERAND (function, 0));
+ return get_member_function_from_ptrfunc (&object,
+ TREE_OPERAND (function, 1));
+ }
+ function = build_address (function);
}
else
- function = default_conversion (function);
+ function = decay_conversion (function);
return function;
}
@@ -352,8 +203,7 @@ build_addr_func (function)
(TYPE_PTRMEMFUNC_P) must be handled by our callers. */
tree
-build_call (function, parms)
- tree function, parms;
+build_call (tree function, tree parms)
{
int is_constructor = 0;
int nothrow;
@@ -419,10 +269,8 @@ build_call (function, parms)
TREE_VALUE (tmp), t);
}
- function = build_nt (CALL_EXPR, function, parms, NULL_TREE);
+ function = build (CALL_EXPR, result_type, function, parms);
TREE_HAS_CONSTRUCTOR (function) = is_constructor;
- TREE_TYPE (function) = result_type;
- TREE_SIDE_EFFECTS (function) = 1;
TREE_NOTHROW (function) = nothrow;
return function;
@@ -443,8 +291,7 @@ build_call (function, parms)
BASETYPE_PATH, if non-NULL, contains a chain from the type of INSTANCE
down to the real instance type to use for access checking. We need this
- information to get protected accesses correct. This parameter is used
- by build_member_call.
+ information to get protected accesses correct.
FLAGS is the logical disjunction of zero or more LOOKUP_
flags. See cp-tree.h for more info.
@@ -460,141 +307,20 @@ build_call (function, parms)
`operator()()' is defined for the type of that field, then we return
that result. */
-#ifdef GATHER_STATISTICS
-extern int n_build_method_call;
-#endif
-
-tree
-build_method_call (instance, name, parms, basetype_path, flags)
- tree instance, name, parms, basetype_path;
- int flags;
-{
- tree fn;
- tree object_type;
- tree template_args = NULL_TREE;
- bool has_template_args = false;
-
-#ifdef GATHER_STATISTICS
- n_build_method_call++;
-#endif
-
- if (instance == error_mark_node
- || name == error_mark_node
- || parms == error_mark_node
- || (instance && TREE_TYPE (instance) == error_mark_node))
- return error_mark_node;
-
- if (processing_template_decl)
- {
- /* We need to process template parm names here so that tsubst catches
- them properly. Other type names can wait. */
- if (TREE_CODE (name) == BIT_NOT_EXPR)
- {
- tree type = NULL_TREE;
-
- if (TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE)
- type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0);
- else if (TREE_CODE (TREE_OPERAND (name, 0)) == TYPE_DECL)
- type = TREE_TYPE (TREE_OPERAND (name, 0));
-
- if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM)
- name = build_min_nt (BIT_NOT_EXPR, type);
- }
-
- return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE);
- }
-
- if (TREE_CODE (instance) == OFFSET_REF)
- instance = resolve_offset_ref (instance);
- if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
- instance = convert_from_reference (instance);
- object_type = TREE_TYPE (instance);
-
- if (TREE_CODE (name) == BIT_NOT_EXPR)
- {
- tree instance_ptr;
-
- if (parms)
- error ("destructors take no parameters");
-
- if (! check_dtor_name (object_type, name))
- error
- ("destructor name `~%T' does not match type `%T' of expression",
- TREE_OPERAND (name, 0), object_type);
-
- /* The destructor type must be complete. */
- object_type = complete_type_or_else (object_type, NULL_TREE);
- if (!object_type || object_type == error_mark_node)
- return error_mark_node;
-
- if (! TYPE_HAS_DESTRUCTOR (object_type))
- return cp_convert (void_type_node, instance);
- instance = default_conversion (instance);
- instance_ptr = build_unary_op (ADDR_EXPR, instance, 0);
- return build_delete (build_pointer_type (object_type),
- instance_ptr, sfk_complete_destructor,
- LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
- }
-
- if (!CLASS_TYPE_P (object_type))
- {
- if ((flags & LOOKUP_COMPLAIN)
- && TREE_TYPE (instance) != error_mark_node)
- error ("request for member `%D' in `%E', which is of non-aggregate type `%T'",
- name, instance, object_type);
- return error_mark_node;
- }
-
- if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- {
- template_args = TREE_OPERAND (name, 1);
- has_template_args = true;
- name = TREE_OPERAND (name, 0);
- }
- if (TREE_CODE (name) == OVERLOAD)
- name = DECL_NAME (get_first_fn (name));
- else if (TREE_CODE (name) == LOOKUP_EXPR)
- name = TREE_OPERAND (name, 0);
- else if (DECL_P (name))
- name = DECL_NAME (name);
- if (has_template_args)
- fn = lookup_fnfields (object_type, name, /*protect=*/2);
- else
- fn = lookup_member (object_type, name, /*protect=*/2, /*want_type=*/0);
-
- if (fn && TREE_CODE (fn) == TREE_LIST && !BASELINK_P (fn))
- {
- error ("request for member `%D' is ambiguous", name);
- print_candidates (fn);
- return error_mark_node;
- }
-
- /* If the name could not be found, issue an error. */
- if (!fn)
- {
- unqualified_name_lookup_error (name);
- return error_mark_node;
- }
-
- if (BASELINK_P (fn) && has_template_args)
- BASELINK_FUNCTIONS (fn)
- = build_nt (TEMPLATE_ID_EXPR,
- BASELINK_FUNCTIONS (fn),
- template_args);
- if (BASELINK_P (fn) && basetype_path)
- BASELINK_ACCESS_BINFO (fn) = basetype_path;
-
- return build_new_method_call (instance, fn, parms,
- /*conversion_path=*/NULL_TREE, flags);
-}
-
/* New overloading code. */
struct z_candidate GTY(()) {
/* 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;
+ /* The implicit conversion sequences for each of the arguments to
+ FN. */
tree convs;
+ /* If FN is a user-defined conversion, the standard conversion
+ sequence from the type returned by FN to the desired destination
+ type. */
tree second_conv;
int viable;
/* If FN is a member function, the binfo indicating the path used to
@@ -640,12 +366,15 @@ struct z_candidate GTY(()) {
should be created to hold the result of the conversion. */
#define NEED_TEMPORARY_P(NODE) TREE_LANG_FLAG_4 (NODE)
+/* TRUE in an IDENTITY_CONV or BASE_CONV if the copy constructor must
+ be accessible, even though it is not being used. */
+#define CHECK_COPY_CONSTRUCTOR_P(NODE) TREE_LANG_FLAG_5 (NODE)
+
#define USER_CONV_CAND(NODE) WRAPPER_ZC (TREE_OPERAND (NODE, 1))
#define USER_CONV_FN(NODE) (USER_CONV_CAND (NODE)->fn)
-int
-null_ptr_cst_p (t)
- tree t;
+bool
+null_ptr_cst_p (tree t)
{
/* [conv.ptr]
@@ -653,29 +382,26 @@ null_ptr_cst_p (t)
(_expr.const_) rvalue of integer type that evaluates to zero. */
if (t == null_node
|| (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t)))
- return 1;
- return 0;
+ return true;
+ return false;
}
/* Returns nonzero if PARMLIST consists of only default parms and/or
ellipsis. */
-int
-sufficient_parms_p (parmlist)
- tree parmlist;
+bool
+sufficient_parms_p (tree parmlist)
{
for (; parmlist && parmlist != void_list_node;
parmlist = TREE_CHAIN (parmlist))
if (!TREE_PURPOSE (parmlist))
- return 0;
- return 1;
+ return false;
+ return true;
}
static tree
-build_conv (code, type, from)
- enum tree_code code;
- tree type, from;
+build_conv (enum tree_code code, tree type, tree from)
{
tree t;
int rank = ICS_STD_RANK (from);
@@ -710,25 +436,12 @@ build_conv (code, type, from)
return t;
}
-/* If T is a REFERENCE_TYPE return the type to which T refers.
- Otherwise, return T itself. */
-
-static tree
-non_reference (t)
- tree t;
-{
- if (TREE_CODE (t) == REFERENCE_TYPE)
- t = TREE_TYPE (t);
- return t;
-}
-
tree
-strip_top_quals (t)
- tree t;
+strip_top_quals (tree t)
{
if (TREE_CODE (t) == ARRAY_TYPE)
return t;
- return TYPE_MAIN_VARIANT (t);
+ return cp_build_qualified_type (t, 0);
}
/* Returns the standard conversion path (see [conv]) from type FROM to type
@@ -736,18 +449,16 @@ strip_top_quals (t)
also pass the expression EXPR to convert from. */
static tree
-standard_conversion (to, from, expr)
- tree to, from, expr;
+standard_conversion (tree to, tree from, tree expr)
{
enum tree_code fcode, tcode;
tree conv;
- int fromref = 0;
+ bool fromref = false;
- if (TREE_CODE (to) == REFERENCE_TYPE)
- to = TREE_TYPE (to);
+ to = non_reference (to);
if (TREE_CODE (from) == REFERENCE_TYPE)
{
- fromref = 1;
+ fromref = true;
from = TREE_TYPE (from);
}
to = strip_top_quals (to);
@@ -782,7 +493,7 @@ standard_conversion (to, from, expr)
else if (fromref || (expr && lvalue_p (expr)))
conv = build_conv (RVALUE_CONV, from, conv);
- /* Allow conversion between `__complex__' data types */
+ /* Allow conversion between `__complex__' data types. */
if (tcode == COMPLEX_TYPE && fcode == COMPLEX_TYPE)
{
/* The standard conversion sequence to convert FROM to TO is
@@ -805,11 +516,15 @@ standard_conversion (to, from, expr)
if (same_type_p (from, to))
return conv;
- if ((tcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (to))
+ if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to))
&& expr && null_ptr_cst_p (expr))
- {
- conv = build_conv (STD_CONV, to, conv);
- }
+ conv = build_conv (STD_CONV, to, conv);
+ else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE
+ && TREE_CODE (TREE_TYPE (to)) == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (from)) == VECTOR_TYPE
+ && ((*targetm.vector_opaque_p) (TREE_TYPE (to))
+ || (*targetm.vector_opaque_p) (TREE_TYPE (from))))
+ conv = build_conv (STD_CONV, to, conv);
else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
|| (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
{
@@ -818,41 +533,44 @@ standard_conversion (to, from, expr)
conv = build_conv (STD_CONV, to, conv);
ICS_BAD_FLAG (conv) = 1;
}
- else if (tcode == ENUMERAL_TYPE && fcode == INTEGER_TYPE
- && TYPE_PRECISION (to) == TYPE_PRECISION (from))
+ else if (tcode == ENUMERAL_TYPE && fcode == INTEGER_TYPE)
{
/* For backwards brain damage compatibility, allow interconversion of
enums and integers with a pedwarn. */
conv = build_conv (STD_CONV, to, conv);
ICS_BAD_FLAG (conv) = 1;
}
- else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE)
+ else if ((tcode == POINTER_TYPE && fcode == POINTER_TYPE)
+ || (TYPE_PTRMEM_P (to) && TYPE_PTRMEM_P (from)))
{
- enum tree_code ufcode = TREE_CODE (TREE_TYPE (from));
- enum tree_code utcode = TREE_CODE (TREE_TYPE (to));
+ tree to_pointee;
+ tree from_pointee;
- if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (from),
- TREE_TYPE (to)))
+ if (tcode == POINTER_TYPE
+ && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (from),
+ TREE_TYPE (to)))
;
- else if (utcode == VOID_TYPE && ufcode != OFFSET_TYPE
- && ufcode != FUNCTION_TYPE)
+ else if (VOID_TYPE_P (TREE_TYPE (to))
+ && !TYPE_PTRMEM_P (from)
+ && TREE_CODE (TREE_TYPE (from)) != FUNCTION_TYPE)
{
from = build_pointer_type
(cp_build_qualified_type (void_type_node,
cp_type_quals (TREE_TYPE (from))));
conv = build_conv (PTR_CONV, from, conv);
}
- else if (ufcode == OFFSET_TYPE && utcode == OFFSET_TYPE)
+ else if (TYPE_PTRMEM_P (from))
{
- tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from));
- tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to));
+ tree fbase = TYPE_PTRMEM_CLASS_TYPE (from);
+ tree tbase = TYPE_PTRMEM_CLASS_TYPE (to);
if (DERIVED_FROM_P (fbase, tbase)
&& (same_type_ignoring_top_level_qualifiers_p
- (TREE_TYPE (TREE_TYPE (from)),
- TREE_TYPE (TREE_TYPE (to)))))
+ (TYPE_PTRMEM_POINTED_TO_TYPE (from),
+ TYPE_PTRMEM_POINTED_TO_TYPE (to))))
{
- from = build_ptrmem_type (tbase, TREE_TYPE (TREE_TYPE (from)));
+ from = build_ptrmem_type (tbase,
+ TYPE_PTRMEM_POINTED_TO_TYPE (from));
conv = build_conv (PMEM_CONV, from, conv);
}
}
@@ -878,14 +596,25 @@ standard_conversion (to, from, expr)
conv = build_conv (PTR_CONV, from, conv);
}
+ if (tcode == POINTER_TYPE)
+ {
+ to_pointee = TREE_TYPE (to);
+ from_pointee = TREE_TYPE (from);
+ }
+ else
+ {
+ to_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (to);
+ from_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (from);
+ }
+
if (same_type_p (from, to))
/* OK */;
- else if (comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from)))
+ else if (comp_ptr_ttypes (to_pointee, from_pointee))
conv = build_conv (QUAL_CONV, to, conv);
else if (expr && string_conv_p (to, expr, 0))
/* converting from string constant to char *. */
conv = build_conv (QUAL_CONV, to, conv);
- else if (ptr_reasonably_similar (TREE_TYPE (to), TREE_TYPE (from)))
+ else if (ptr_reasonably_similar (to_pointee, from_pointee))
{
conv = build_conv (PTR_CONV, to, conv);
ICS_BAD_FLAG (conv) = 1;
@@ -910,21 +639,33 @@ standard_conversion (to, from, expr)
return 0;
from = cp_build_qualified_type (tbase, cp_type_quals (fbase));
- from = build_cplus_method_type (from, TREE_TYPE (fromfn),
- TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
+ from = build_method_type_directly (from,
+ TREE_TYPE (fromfn),
+ TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
from = build_ptrmemfunc_type (build_pointer_type (from));
conv = build_conv (PMEM_CONV, from, conv);
}
else if (tcode == BOOLEAN_TYPE)
{
- if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE
- || fcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (from)))
- return 0;
+ /* [conv.bool]
- conv = build_conv (STD_CONV, to, conv);
- if (fcode == POINTER_TYPE
- || (TYPE_PTRMEMFUNC_P (from) && ICS_STD_RANK (conv) < PBOOL_RANK))
- ICS_STD_RANK (conv) = PBOOL_RANK;
+ An rvalue of arithmetic, enumeration, pointer, or pointer to
+ member type can be converted to an rvalue of type bool. */
+ if (ARITHMETIC_TYPE_P (from)
+ || fcode == ENUMERAL_TYPE
+ || fcode == POINTER_TYPE
+ || TYPE_PTR_TO_MEMBER_P (from))
+ {
+ conv = build_conv (STD_CONV, to, conv);
+ if (fcode == POINTER_TYPE
+ || TYPE_PTRMEM_P (from)
+ || (TYPE_PTRMEMFUNC_P (from)
+ && ICS_STD_RANK (conv) < PBOOL_RANK))
+ ICS_STD_RANK (conv) = PBOOL_RANK;
+ return conv;
+ }
+
+ return NULL_TREE;
}
/* We don't check for ENUMERAL_TYPE here because there are no standard
conversions to enum type. */
@@ -936,10 +677,14 @@ standard_conversion (to, from, expr)
conv = build_conv (STD_CONV, to, conv);
/* Give this a better rank if it's a promotion. */
- if (to == type_promotes_to (from)
+ if (same_type_p (to, type_promotes_to (from))
&& ICS_STD_RANK (TREE_OPERAND (conv, 0)) <= PROMO_RANK)
ICS_STD_RANK (conv) = PROMO_RANK;
}
+ else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
+ && ((*targetm.vector_opaque_p) (from)
+ || (*targetm.vector_opaque_p) (to)))
+ return build_conv (STD_CONV, to, conv);
else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
&& is_properly_derived_from (from, to))
{
@@ -960,10 +705,8 @@ standard_conversion (to, from, expr)
/* Returns nonzero if T1 is reference-related to T2. */
-static int
-reference_related_p (t1, t2)
- tree t1;
- tree t2;
+static bool
+reference_related_p (tree t1, tree t2)
{
t1 = TYPE_MAIN_VARIANT (t1);
t2 = TYPE_MAIN_VARIANT (t2);
@@ -980,10 +723,8 @@ reference_related_p (t1, t2)
/* Returns nonzero if T1 is reference-compatible with T2. */
-static int
-reference_compatible_p (t1, t2)
- tree t1;
- tree t2;
+static bool
+reference_compatible_p (tree t1, tree t2)
{
/* [dcl.init.ref]
@@ -998,10 +739,7 @@ reference_compatible_p (t1, t2)
converted to T as in [over.match.ref]. */
static tree
-convert_class_to_reference (t, s, expr)
- tree t;
- tree s;
- tree expr;
+convert_class_to_reference (tree t, tree s, tree expr)
{
tree conversions;
tree arglist;
@@ -1009,6 +747,7 @@ convert_class_to_reference (t, s, expr)
tree reference_type;
struct z_candidate *candidates;
struct z_candidate *cand;
+ bool any_viable_p;
conversions = lookup_conversions (s);
if (!conversions)
@@ -1091,29 +830,39 @@ convert_class_to_reference (t, s, expr)
LOOKUP_NORMAL);
if (cand)
- /* Build a standard conversion sequence indicating the
- binding from the reference type returned by the
- function to the desired REFERENCE_TYPE. */
- cand->second_conv
- = (direct_reference_binding
- (reference_type,
- build1 (IDENTITY_CONV,
- TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),
- NULL_TREE)));
+ {
+ /* Build a standard conversion sequence indicating the
+ binding from the reference type returned by the
+ function to the desired REFERENCE_TYPE. */
+ cand->second_conv
+ = (direct_reference_binding
+ (reference_type,
+ build1 (IDENTITY_CONV,
+ TREE_TYPE (TREE_TYPE (TREE_TYPE (cand->fn))),
+ NULL_TREE)));
+ ICS_BAD_FLAG (cand->second_conv)
+ |= ICS_BAD_FLAG (TREE_VEC_ELT (cand->convs, 0));
+ }
}
conversions = TREE_CHAIN (conversions);
}
+ candidates = splice_viable (candidates, pedantic, &any_viable_p);
/* If none of the conversion functions worked out, let our caller
know. */
- if (!any_viable (candidates))
+ if (!any_viable_p)
return NULL_TREE;
-
- candidates = splice_viable (candidates);
+
cand = tourney (candidates);
if (!cand)
return NULL_TREE;
+ /* 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));
+
/* Build a user-defined conversion sequence representing the
conversion. */
conv = build_conv (USER_CONV,
@@ -1127,7 +876,7 @@ convert_class_to_reference (t, s, expr)
if (cand->viable == -1)
ICS_BAD_FLAG (conv) = 1;
-
+
return cand->second_conv;
}
@@ -1136,16 +885,14 @@ convert_class_to_reference (t, s, expr)
Return a conversion sequence for this binding. */
static tree
-direct_reference_binding (type, conv)
- tree type;
- tree conv;
+direct_reference_binding (tree type, tree conv)
{
tree t;
my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 20030306);
my_friendly_assert (TREE_CODE (TREE_TYPE (conv)) != REFERENCE_TYPE,
20030306);
-
+
t = TREE_TYPE (type);
/* [over.ics.rank]
@@ -1188,8 +935,8 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags)
tree conv = NULL_TREE;
tree to = TREE_TYPE (rto);
tree from = rfrom;
- int related_p;
- int compatible_p;
+ bool related_p;
+ bool compatible_p;
cp_lvalue_kind lvalue_p = clk_none;
if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
@@ -1224,14 +971,14 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags)
-- is an lvalue (but not an lvalue for a bit-field), and "cv1 T1"
is reference-compatible with "cv2 T2,"
- the reference is bound directly to the initializer exprssion
+ the reference is bound directly to the initializer expression
lvalue. */
conv = build1 (IDENTITY_CONV, from, expr);
conv = direct_reference_binding (rto, conv);
- if ((lvalue_p & clk_bitfield) != 0
- && CP_TYPE_CONST_NON_VOLATILE_P (to))
+ if ((lvalue_p & clk_bitfield) != 0
+ || ((lvalue_p & clk_packed) != 0 && !TYPE_PACKED (to)))
/* For the purposes of overload resolution, we ignore the fact
- this expression is a bitfield. (In particular,
+ this expression is a bitfield or packed field. (In particular,
[over.ics.ref] says specifically that a function with a
non-const reference parameter is viable even if the
argument is a bitfield.)
@@ -1242,13 +989,14 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags)
a temporary, so we just issue an error when the conversion
actually occurs. */
NEED_TEMPORARY_P (conv) = 1;
+
return conv;
}
else if (CLASS_TYPE_P (from) && !(flags & LOOKUP_NO_CONVERSION))
{
/* [dcl.init.ref]
- If the initializer exprsesion
+ If the initializer expression
-- has a class type (i.e., T2 is a class type) can be
implicitly converted to an lvalue of type "cv3 T3," where
@@ -1296,7 +1044,7 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags)
or to a sub-object within that object.
-- ...
-
+
We use the first alternative. The implicit conversion sequence
is supposed to be same as we would obtain by generating a
temporary. Fortunately, if the types are reference compatible,
@@ -1305,7 +1053,10 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags)
if (CLASS_TYPE_P (from) && compatible_p)
{
conv = build1 (IDENTITY_CONV, from, expr);
- return direct_reference_binding (rto, conv);
+ conv = direct_reference_binding (rto, conv);
+ if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE))
+ CHECK_COPY_CONSTRUCTOR_P (TREE_OPERAND (conv, 0)) = 1;
+ return conv;
}
/* [dcl.init.ref]
@@ -1336,20 +1087,10 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags)
significant. */
static tree
-implicit_conversion (to, from, expr, flags)
- tree to, from, expr;
- int flags;
+implicit_conversion (tree to, tree from, tree expr, int flags)
{
tree conv;
- /* Resolve expressions like `A::p' that we thought might become
- pointers-to-members. */
- if (expr && TREE_CODE (expr) == OFFSET_REF)
- {
- expr = resolve_offset_ref (expr);
- from = TREE_TYPE (expr);
- }
-
if (from == error_mark_node || to == error_mark_node
|| expr == error_mark_node)
return NULL_TREE;
@@ -1360,11 +1101,12 @@ implicit_conversion (to, from, expr, flags)
conv = standard_conversion (to, from, expr);
if (conv)
- ;
- else if (expr != NULL_TREE
- && (IS_AGGR_TYPE (from)
- || IS_AGGR_TYPE (to))
- && (flags & LOOKUP_NO_CONVERSION) == 0)
+ return conv;
+
+ if (expr != NULL_TREE
+ && (IS_AGGR_TYPE (from)
+ || IS_AGGR_TYPE (to))
+ && (flags & LOOKUP_NO_CONVERSION) == 0)
{
struct z_candidate *cand;
@@ -1376,9 +1118,10 @@ implicit_conversion (to, from, expr, flags)
/* We used to try to bind a reference to a temporary here, but that
is now handled by the recursive call to this function at the end
of reference_binding. */
+ return conv;
}
- return conv;
+ return NULL_TREE;
}
/* Add a new entry to the list of candidates. Used by the add_*_candidate
@@ -1386,13 +1129,13 @@ implicit_conversion (to, from, expr, flags)
static struct z_candidate *
add_candidate (struct z_candidate **candidates,
- tree fn, tree convs, tree access_path, tree
- conversion_path, int viable)
+ tree fn, tree args, tree convs, tree access_path,
+ tree conversion_path, int viable)
{
- struct z_candidate *cand
- = (struct z_candidate *) ggc_alloc_cleared (sizeof (struct z_candidate));
+ struct z_candidate *cand = ggc_alloc_cleared (sizeof (struct z_candidate));
cand->fn = fn;
+ cand->args = args;
cand->convs = convs;
cand->access_path = access_path;
cand->conversion_path = conversion_path;
@@ -1420,6 +1163,7 @@ add_function_candidate (struct z_candidate **candidates,
int i, len;
tree convs;
tree parmnode, argnode;
+ tree orig_arglist;
int viable = 1;
/* Built-in functions that haven't been declared don't really
@@ -1432,8 +1176,11 @@ 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);
}
+ else
+ orig_arglist = arglist;
len = list_length (arglist);
convs = make_tree_vec (len);
@@ -1531,7 +1278,7 @@ add_function_candidate (struct z_candidate **candidates,
}
out:
- return add_candidate (candidates, fn, convs, access_path,
+ return add_candidate (candidates, fn, orig_arglist, convs, access_path,
conversion_path, viable);
}
@@ -1547,12 +1294,8 @@ add_function_candidate (struct z_candidate **candidates,
instead of the function. */
static struct z_candidate *
-add_conv_candidate (candidates, fn, obj, arglist, access_path,
- conversion_path)
- struct z_candidate **candidates;
- tree fn, obj, arglist;
- tree access_path;
- tree conversion_path;
+add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
+ tree arglist, tree access_path, tree conversion_path)
{
tree totype = TREE_TYPE (TREE_TYPE (fn));
int i, len, viable, flags;
@@ -1612,17 +1355,14 @@ add_conv_candidate (candidates, fn, obj, arglist, access_path,
if (!sufficient_parms_p (parmnode))
viable = 0;
- return add_candidate (candidates, totype, convs, access_path,
+ return add_candidate (candidates, totype, arglist, convs, access_path,
conversion_path, viable);
}
static void
-build_builtin_candidate (candidates, fnname, type1, type2,
- args, argtypes, flags)
- struct z_candidate **candidates;
- tree fnname, type1, type2, *args, *argtypes;
- int flags;
-
+build_builtin_candidate (struct z_candidate **candidates, tree fnname,
+ tree type1, tree type2, tree *args, tree *argtypes,
+ int flags)
{
tree t, convs;
int viable = 1, i;
@@ -1662,24 +1402,22 @@ build_builtin_candidate (candidates, fnname, type1, type2,
viable = 0;
}
- add_candidate (candidates, fnname, convs,
+ add_candidate (candidates, fnname, /*args=*/NULL_TREE, convs,
/*access_path=*/NULL_TREE,
/*conversion_path=*/NULL_TREE,
viable);
}
-static int
-is_complete (t)
- tree t;
+static bool
+is_complete (tree t)
{
return COMPLETE_TYPE_P (complete_type (t));
}
/* Returns nonzero if TYPE is a promoted arithmetic type. */
-static int
-promoted_arithmetic_type_p (type)
- tree type;
+static bool
+promoted_arithmetic_type_p (tree type)
{
/* [over.built]
@@ -1704,12 +1442,9 @@ promoted_arithmetic_type_p (type)
CODE (TYPE1, TYPE1) and CODE (TYPE2, TYPE2). */
static void
-add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
- args, argtypes, flags)
- struct z_candidate **candidates;
- enum tree_code code, code2;
- tree fnname, type1, type2, *args, *argtypes;
- int flags;
+add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
+ enum tree_code code2, tree fnname, tree type1,
+ tree type2, tree *args, tree *argtypes, int flags)
{
switch (code)
{
@@ -1781,8 +1516,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
T operator-(T); */
case CONVERT_EXPR: /* unary + */
- if (TREE_CODE (type1) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (type1)) != OFFSET_TYPE)
+ if (TREE_CODE (type1) == POINTER_TYPE)
break;
case NEGATE_EXPR:
if (ARITHMETIC_TYPE_P (type1))
@@ -1807,12 +1541,10 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
case MEMBER_REF:
if (TREE_CODE (type1) == POINTER_TYPE
- && (TYPE_PTRMEMFUNC_P (type2) || TYPE_PTRMEM_P (type2)))
+ && TYPE_PTR_TO_MEMBER_P (type2))
{
tree c1 = TREE_TYPE (type1);
- tree c2 = (TYPE_PTRMEMFUNC_P (type2)
- ? TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type2)))
- : TYPE_OFFSET_BASETYPE (TREE_TYPE (type2)));
+ tree c2 = TYPE_PTRMEM_CLASS_TYPE (type2);
if (IS_AGGR_TYPE (c1) && DERIVED_FROM_P (c2, c1)
&& (TYPE_PTRMEMFUNC_P (type2)
@@ -1882,19 +1614,17 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2))
|| (TYPE_PTRMEM_P (type1) && TYPE_PTRMEM_P (type2)))
break;
- if ((TYPE_PTRMEMFUNC_P (type1) || TYPE_PTRMEM_P (type1))
- && null_ptr_cst_p (args[1]))
+ if (TYPE_PTR_TO_MEMBER_P (type1) && null_ptr_cst_p (args[1]))
{
type2 = type1;
break;
}
- if ((TYPE_PTRMEMFUNC_P (type2) || TYPE_PTRMEM_P (type2))
- && null_ptr_cst_p (args[0]))
+ if (TYPE_PTR_TO_MEMBER_P (type2) && null_ptr_cst_p (args[0]))
{
type1 = type2;
break;
}
- /* FALLTHROUGH */
+ /* Fall through. */
case LT_EXPR:
case GT_EXPR:
case LE_EXPR:
@@ -2060,12 +1790,8 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
break;
/* Otherwise, the types should be pointers. */
- if (!(TREE_CODE (type1) == POINTER_TYPE
- || TYPE_PTRMEM_P (type1)
- || TYPE_PTRMEMFUNC_P (type1))
- || !(TREE_CODE (type2) == POINTER_TYPE
- || TYPE_PTRMEM_P (type2)
- || TYPE_PTRMEMFUNC_P (type2)))
+ if (!(TYPE_PTR_P (type1) || TYPE_PTR_TO_MEMBER_P (type1))
+ || !(TYPE_PTR_P (type2) || TYPE_PTR_TO_MEMBER_P (type2)))
return;
/* We don't check that the two types are the same; the logic
@@ -2083,8 +1809,8 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
if (type2 && !same_type_p (type1, type2)
&& TREE_CODE (type1) == TREE_CODE (type2)
&& (TREE_CODE (type1) == REFERENCE_TYPE
- || (TREE_CODE (type1) == POINTER_TYPE
- && TYPE_PTRMEM_P (type1) == TYPE_PTRMEM_P (type2))
+ || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
+ || (TYPE_PTRMEM_P (type1) && TYPE_PTRMEM_P (type2))
|| TYPE_PTRMEMFUNC_P (type1)
|| IS_AGGR_TYPE (type1)
|| TREE_CODE (type1) == ENUMERAL_TYPE))
@@ -2101,8 +1827,7 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
}
tree
-type_decays_to (type)
- tree type;
+type_decays_to (tree type)
{
if (TREE_CODE (type) == ARRAY_TYPE)
return build_pointer_type (TREE_TYPE (type));
@@ -2125,11 +1850,9 @@ type_decays_to (type)
filter out the invalid set. */
static void
-add_builtin_candidates (candidates, code, code2, fnname, args, flags)
- struct z_candidate **candidates;
- enum tree_code code, code2;
- tree fnname, *args;
- int flags;
+add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
+ enum tree_code code2, tree fnname, tree *args,
+ int flags)
{
int ref1, i;
int enum_p = 0;
@@ -2194,7 +1917,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
case GT_EXPR:
case GE_EXPR:
enum_p = 1;
- /* FALLTHROUGH */
+ /* Fall through. */
default:
ref1 = 0;
@@ -2302,16 +2025,11 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
add_conv_candidate. */
static struct z_candidate*
-add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
- arglist, return_type, access_path,
- conversion_path, flags, obj, strict)
- struct z_candidate **candidates;
- tree tmpl, ctype, explicit_targs, arglist, return_type;
- tree access_path;
- tree conversion_path;
- int flags;
- tree obj;
- unification_kind_t strict;
+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)
{
int ntparms = DECL_NTPARMS (tmpl);
tree targs = make_tree_vec (ntparms);
@@ -2337,7 +2055,7 @@ add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
if (i != 0)
return NULL;
- fn = instantiate_template (tmpl, targs);
+ fn = instantiate_template (tmpl, targs, tf_none);
if (fn == error_mark_node)
return NULL;
@@ -2406,15 +2124,10 @@ add_template_candidate_real (candidates, tmpl, ctype, explicit_targs,
static struct z_candidate *
-add_template_candidate (candidates, tmpl, ctype, explicit_targs,
- arglist, return_type, access_path,
- conversion_path, flags, strict)
- struct z_candidate **candidates;
- tree tmpl, ctype, explicit_targs, arglist, return_type;
- tree access_path;
- tree conversion_path;
- int flags;
- unification_kind_t strict;
+add_template_candidate (struct z_candidate **candidates, tree tmpl, tree ctype,
+ tree explicit_targs, tree arglist, tree return_type,
+ tree access_path, tree conversion_path, int flags,
+ unification_kind_t strict)
{
return
add_template_candidate_real (candidates, tmpl, ctype,
@@ -2425,12 +2138,9 @@ add_template_candidate (candidates, tmpl, ctype, explicit_targs,
static struct z_candidate *
-add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type,
- access_path, conversion_path)
- struct z_candidate **candidates;
- tree tmpl, obj, arglist, return_type;
- tree access_path;
- tree conversion_path;
+add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
+ tree obj, tree arglist, tree return_type,
+ tree access_path, tree conversion_path)
{
return
add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
@@ -2438,47 +2148,55 @@ add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type,
conversion_path, 0, obj, DEDUCE_CONV);
}
+/* The CANDS are the set of candidates that were considered for
+ overload resolution. Return the set of viable candidates. If none
+ of the candidates were viable, set *ANY_VIABLE_P to true. STRICT_P
+ is true if a candidate should be considered viable only if it is
+ strictly viable. */
-static int
-any_viable (cands)
- struct z_candidate *cands;
-{
- for (; cands; cands = cands->next)
- if (pedantic ? cands->viable == 1 : cands->viable)
- return 1;
- return 0;
-}
-
-static int
-any_strictly_viable (cands)
- struct z_candidate *cands;
+static struct z_candidate*
+splice_viable (struct z_candidate *cands,
+ bool strict_p,
+ bool *any_viable_p)
{
- for (; cands; cands = cands->next)
- if (cands->viable == 1)
- return 1;
- return 0;
-}
+ struct z_candidate *viable;
+ struct z_candidate **last_viable;
+ struct z_candidate **cand;
-static struct z_candidate *
-splice_viable (cands)
- struct z_candidate *cands;
-{
- struct z_candidate **p = &cands;
+ viable = NULL;
+ last_viable = &viable;
+ *any_viable_p = false;
- for (; *p; )
+ cand = &cands;
+ while (*cand)
{
- if (pedantic ? (*p)->viable == 1 : (*p)->viable)
- p = &((*p)->next);
+ struct z_candidate *c = *cand;
+ if (strict_p ? c->viable == 1 : c->viable)
+ {
+ *last_viable = c;
+ *cand = c->next;
+ c->next = NULL;
+ last_viable = &c->next;
+ *any_viable_p = true;
+ }
else
- *p = (*p)->next;
+ cand = &c->next;
}
- return cands;
+ return viable ? viable : cands;
+}
+
+static bool
+any_strictly_viable (struct z_candidate *cands)
+{
+ for (; cands; cands = cands->next)
+ if (cands->viable == 1)
+ return true;
+ return false;
}
static tree
-build_this (obj)
- tree obj;
+build_this (tree obj)
{
/* Fix this to work on non-lvalues. */
return build_unary_op (ADDR_EXPR, obj, 0);
@@ -2489,9 +2207,7 @@ build_this (obj)
both are extern "C". */
static inline int
-equal_functions (fn1, fn2)
- tree fn1;
- tree fn2;
+equal_functions (tree fn1, tree fn2)
{
if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2)
|| DECL_EXTERN_C_FUNCTION_P (fn1))
@@ -2499,6 +2215,39 @@ equal_functions (fn1, fn2)
return fn1 == fn2;
}
+/* Print information about one overload candidate CANDIDATE. MSGSTR
+ is the text to print before the candidate itself.
+
+ NOTE: Unlike most diagnostic functions in GCC, MSGSTR is expected
+ to have been run through gettext by the caller. This wart makes
+ life simpler in print_z_candidates and for the translators. */
+
+static void
+print_z_candidate (const char *msgstr, struct z_candidate *candidate)
+{
+ if (TREE_CODE (candidate->fn) == IDENTIFIER_NODE)
+ {
+ if (TREE_VEC_LENGTH (candidate->convs) == 3)
+ inform ("%s %D(%T, %T, %T) <built-in>", msgstr, candidate->fn,
+ TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)),
+ TREE_TYPE (TREE_VEC_ELT (candidate->convs, 1)),
+ TREE_TYPE (TREE_VEC_ELT (candidate->convs, 2)));
+ else if (TREE_VEC_LENGTH (candidate->convs) == 2)
+ inform ("%s %D(%T, %T) <built-in>", msgstr, candidate->fn,
+ TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)),
+ TREE_TYPE (TREE_VEC_ELT (candidate->convs, 1)));
+ else
+ inform ("%s %D(%T) <built-in>", msgstr, candidate->fn,
+ TREE_TYPE (TREE_VEC_ELT (candidate->convs, 0)));
+ }
+ else if (TYPE_P (candidate->fn))
+ inform ("%s %T <conversion>", msgstr, candidate->fn);
+ else if (candidate->viable == -1)
+ inform ("%J%s %+#D <near match>", candidate->fn, msgstr, candidate->fn);
+ else
+ inform ("%J%s %+#D", candidate->fn, msgstr, candidate->fn);
+}
+
static void
print_z_candidates (struct z_candidate *candidates)
{
@@ -2528,30 +2277,27 @@ print_z_candidates (struct z_candidate *candidates)
}
}
- str = "candidates are:";
- for (; candidates; candidates = candidates->next)
+ if (!candidates)
+ return;
+
+ str = _("candidates are:");
+ print_z_candidate (str, candidates);
+ if (candidates->next)
{
- if (TREE_CODE (candidates->fn) == IDENTIFIER_NODE)
+ /* Indent successive candidates by the width of the translation
+ of the above string. */
+ size_t len = gcc_gettext_width (str) + 1;
+ char *spaces = alloca (len);
+ memset (spaces, ' ', len-1);
+ spaces[len - 1] = '\0';
+
+ candidates = candidates->next;
+ do
{
- if (TREE_VEC_LENGTH (candidates->convs) == 3)
- error ("%s %D(%T, %T, %T) <built-in>", str, candidates->fn,
- TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)),
- TREE_TYPE (TREE_VEC_ELT (candidates->convs, 1)),
- TREE_TYPE (TREE_VEC_ELT (candidates->convs, 2)));
- else if (TREE_VEC_LENGTH (candidates->convs) == 2)
- error ("%s %D(%T, %T) <built-in>", str, candidates->fn,
- TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)),
- TREE_TYPE (TREE_VEC_ELT (candidates->convs, 1)));
- else
- error ("%s %D(%T) <built-in>", str, candidates->fn,
- TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)));
+ print_z_candidate (spaces, candidates);
+ candidates = candidates->next;
}
- else if (TYPE_P (candidates->fn))
- error ("%s %T <conversion>", str, candidates->fn);
- else
- cp_error_at ("%s %+#D%s", str, candidates->fn,
- candidates->viable == -1 ? " <near match>" : "");
- str = " ";
+ while (candidates);
}
}
@@ -2591,14 +2337,13 @@ merge_conversion_sequences (tree user_seq, tree std_seq)
per [dcl.init.ref], so we ignore temporary bindings. */
static struct z_candidate *
-build_user_type_conversion_1 (totype, expr, flags)
- tree totype, expr;
- int flags;
+build_user_type_conversion_1 (tree totype, tree expr, int flags)
{
struct z_candidate *candidates, *cand;
tree fromtype = TREE_TYPE (expr);
tree ctors = NULL_TREE, convs = NULL_TREE;
tree args = NULL_TREE;
+ bool any_viable_p;
/* We represent conversion within a hierarchy using RVALUE_CONV and
BASE_CONV, as specified by [over.best.ics]; these become plain
@@ -2684,7 +2429,8 @@ build_user_type_conversion_1 (totype, expr, flags)
So we pass fromtype as CTYPE to add_*_candidate. */
if (TREE_CODE (fn) == TEMPLATE_DECL)
- cand = add_template_candidate (&candidates, fn, fromtype, NULL_TREE,
+ cand = add_template_candidate (&candidates, fn, fromtype,
+ NULL_TREE,
args, totype,
TYPE_BINFO (fromtype),
conversion_path,
@@ -2699,26 +2445,25 @@ build_user_type_conversion_1 (totype, expr, flags)
if (cand)
{
- tree ics = implicit_conversion
- (totype, TREE_TYPE (TREE_TYPE (cand->fn)),
- 0, convflags);
+ tree ics = implicit_conversion (totype,
+ TREE_TYPE (TREE_TYPE (cand->fn)),
+ 0, convflags);
cand->second_conv = ics;
if (ics == NULL_TREE)
cand->viable = 0;
- else if (cand->viable == 1 && ICS_BAD_FLAG (ics))
+ else if (candidates->viable == 1 && ICS_BAD_FLAG (ics))
cand->viable = -1;
}
}
}
- if (! any_viable (candidates))
+ candidates = splice_viable (candidates, pedantic, &any_viable_p);
+ if (!any_viable_p)
return 0;
- candidates = splice_viable (candidates);
cand = tourney (candidates);
-
if (cand == 0)
{
if (flags & LOOKUP_COMPLAIN)
@@ -2759,9 +2504,7 @@ build_user_type_conversion_1 (totype, expr, flags)
}
tree
-build_user_type_conversion (totype, expr, flags)
- tree totype, expr;
- int flags;
+build_user_type_conversion (tree totype, tree expr, int flags)
{
struct z_candidate *cand
= build_user_type_conversion_1 (totype, expr, flags);
@@ -2775,83 +2518,10 @@ build_user_type_conversion (totype, expr, flags)
return NULL_TREE;
}
-/* Find the possibly overloaded set of functions corresponding to a
- call of the form SCOPE::NAME (...). NAME might be a
- TEMPLATE_ID_EXPR, OVERLOAD, _DECL, IDENTIFIER_NODE or LOOKUP_EXPR. */
-
-tree
-resolve_scoped_fn_name (tree scope, tree name)
-{
- tree fn;
- tree template_args = NULL_TREE;
- bool is_template_id = TREE_CODE (name) == TEMPLATE_ID_EXPR;
-
- if (is_template_id)
- {
- template_args = TREE_OPERAND (name, 1);
- name = TREE_OPERAND (name, 0);
- }
- if (TREE_CODE (name) == OVERLOAD)
- name = DECL_NAME (get_first_fn (name));
- else if (TREE_CODE (name) == LOOKUP_EXPR)
- name = TREE_OPERAND (name, 0);
-
- if (TREE_CODE (scope) == NAMESPACE_DECL)
- fn = lookup_namespace_name (scope, name);
- else if (!CLASS_TYPE_P (scope))
- {
- error ("`%T' is not a class type", scope);
- return error_mark_node;
- }
- else
- {
- if (!TYPE_BEING_DEFINED (scope)
- && !COMPLETE_TYPE_P (complete_type (scope)))
- {
- error ("incomplete type '%T' cannot be used to name a scope",
- scope);
- return error_mark_node;
- }
-
- if (BASELINK_P (name))
- fn = name;
- else
- fn = lookup_member (scope, name, /*protect=*/1, /*prefer_type=*/0);
- if (fn && current_class_type)
- fn = (adjust_result_of_qualified_name_lookup
- (fn, scope, current_class_type));
-
- /* It might be the name of a function pointer member. */
- if (fn && TREE_CODE (fn) == FIELD_DECL)
- fn = resolve_offset_ref (build_offset_ref (scope, fn));
- }
-
- if (!fn)
- {
- error ("'%D' has no member named '%E'", scope, name);
- return error_mark_node;
- }
- if (is_template_id)
- {
- tree fns = fn;
-
- if (BASELINK_P (fn))
- fns = BASELINK_FUNCTIONS (fns);
- fns = build_nt (TEMPLATE_ID_EXPR, fns, template_args);
- if (BASELINK_P (fn))
- BASELINK_FUNCTIONS (fn) = fns;
- else
- fn = fns;
- }
-
- return fn;
-}
-
/* Do any initial processing on the arguments to a function call. */
static tree
-resolve_args (args)
- tree args;
+resolve_args (tree args)
{
tree t;
for (t = args; t; t = TREE_CHAIN (t))
@@ -2865,25 +2535,37 @@ resolve_args (args)
error ("invalid use of void expression");
return error_mark_node;
}
- else if (TREE_CODE (arg) == OFFSET_REF)
- arg = resolve_offset_ref (arg);
arg = convert_from_reference (arg);
TREE_VALUE (t) = arg;
}
return args;
}
-/* Return an expression for a call to FN (a namespace-scope function)
- with the ARGS. */
-
-tree
-build_new_function_call (fn, args)
- tree fn, args;
+/* Perform overload resolution on FN, which is called with the ARGS.
+
+ Return the candidate function selected by overload resolution, or
+ NULL if the event that overload resolution failed. In the case
+ that overload resolution fails, *CANDIDATES will be the set of
+ candidates considered, and ANY_VIABLE_P will be set to true or
+ false to indicate whether or not any of the candidates were
+ viable.
+
+ The ARGS should already have gone through RESOLVE_ARGS before this
+ function is called. */
+
+static struct z_candidate *
+perform_overload_resolution (tree fn,
+ tree args,
+ struct z_candidate **candidates,
+ bool *any_viable_p)
{
- struct z_candidate *candidates = 0, *cand;
+ struct z_candidate *cand;
tree explicit_targs = NULL_TREE;
int template_only = 0;
+ *candidates = NULL;
+ *any_viable_p = true;
+
/* Check FN and ARGS. */
my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL
|| TREE_CODE (fn) == TEMPLATE_DECL
@@ -2900,69 +2582,151 @@ build_new_function_call (fn, args)
template_only = 1;
}
- if (really_overloaded_fn (fn)
- || TREE_CODE (fn) == TEMPLATE_DECL)
- {
- tree t1;
+ /* Add the various candidate functions. */
+ add_candidates (fn, args, explicit_targs, template_only,
+ /*conversion_path=*/NULL_TREE,
+ /*access_path=*/NULL_TREE,
+ LOOKUP_NORMAL,
+ candidates);
- args = resolve_args (args);
+ *candidates = splice_viable (*candidates, pedantic, any_viable_p);
+ if (!*any_viable_p)
+ return NULL;
- if (args == error_mark_node)
- return error_mark_node;
+ cand = tourney (*candidates);
+ return cand;
+}
- for (t1 = fn; t1; t1 = OVL_NEXT (t1))
- {
- tree t = OVL_CURRENT (t1);
-
- if (TREE_CODE (t) == TEMPLATE_DECL)
- add_template_candidate
- (&candidates, t, NULL_TREE, explicit_targs, args,
- NULL_TREE,
- /*access_path=*/NULL_TREE, /*conversion_path=*/NULL_TREE,
- LOOKUP_NORMAL, DEDUCE_CALL);
- else if (! template_only)
- add_function_candidate
- (&candidates, t, NULL_TREE, args, /*access_path=*/NULL_TREE,
- /*conversion_path=*/NULL_TREE, LOOKUP_NORMAL);
- }
+/* Return an expression for a call to FN (a namespace-scope function,
+ or a static member function) with the ARGS. */
+
+tree
+build_new_function_call (tree fn, tree args)
+{
+ struct z_candidate *candidates, *cand;
+ bool any_viable_p;
- if (! any_viable (candidates))
- {
- if (candidates && ! candidates->next)
- return build_function_call (candidates->fn, args);
- error ("no matching function for call to `%D(%A)'",
- DECL_NAME (OVL_CURRENT (fn)), args);
- if (candidates)
- print_z_candidates (candidates);
- return error_mark_node;
- }
- candidates = splice_viable (candidates);
- cand = tourney (candidates);
+ args = resolve_args (args);
+ if (args == error_mark_node)
+ return error_mark_node;
- if (cand == 0)
- {
- error ("call of overloaded `%D(%A)' is ambiguous",
- DECL_NAME (OVL_FUNCTION (fn)), args);
- print_z_candidates (candidates);
- return error_mark_node;
- }
+ cand = perform_overload_resolution (fn, args, &candidates, &any_viable_p);
- return build_over_call (cand, args, LOOKUP_NORMAL);
+ if (!cand)
+ {
+ if (!any_viable_p && candidates && ! candidates->next)
+ return build_function_call (candidates->fn, args);
+ 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);
+ else
+ error ("call of overloaded `%D(%A)' is ambiguous",
+ DECL_NAME (OVL_CURRENT (fn)), args);
+ if (candidates)
+ print_z_candidates (candidates);
+ return error_mark_node;
}
- /* This is not really overloaded. */
- fn = OVL_CURRENT (fn);
+ return build_over_call (cand, LOOKUP_NORMAL);
+}
+
+/* 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. */
+
+tree
+build_operator_new_call (tree fnname, tree args, tree *size, tree *cookie_size)
+{
+ tree fns;
+ struct z_candidate *candidates;
+ struct z_candidate *cand;
+ bool any_viable_p;
+
+ args = tree_cons (NULL_TREE, *size, args);
+ args = resolve_args (args);
+ if (args == error_mark_node)
+ return args;
+
+ fns = lookup_function_nonclass (fnname, args);
+
+ /* Figure out what function is being called. */
+ cand = perform_overload_resolution (fns, args, &candidates, &any_viable_p);
+
+ /* If no suitable function could be found, issue an error message
+ and give up. */
+ if (!cand)
+ {
+ if (!any_viable_p)
+ error ("no matching function for call to `%D(%A)'",
+ DECL_NAME (OVL_CURRENT (fns)), args);
+ else
+ error ("call of overloaded `%D(%A)' is ambiguous",
+ DECL_NAME (OVL_CURRENT (fns)), args);
+ if (candidates)
+ print_z_candidates (candidates);
+ return error_mark_node;
+ }
- return build_function_call (fn, args);
+ /* If a cookie is required, add some extra space. Whether
+ or not a cookie is required cannot be determined until
+ after we know which function was called. */
+ if (*cookie_size)
+ {
+ 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)),
+ ptr_type_node))
+ use_cookie = false;
+ }
+ else
+ {
+ tree arg_types;
+
+ arg_types = TYPE_ARG_TYPES (TREE_TYPE (cand->fn));
+ /* Skip the size_t parameter. */
+ arg_types = TREE_CHAIN (arg_types);
+ /* Check the remaining parameters (if any). */
+ if (arg_types
+ && TREE_CHAIN (arg_types) == void_list_node
+ && same_type_p (TREE_VALUE (arg_types),
+ ptr_type_node))
+ use_cookie = false;
+ }
+ /* If we need a cookie, adjust the number of bytes allocated. */
+ if (use_cookie)
+ {
+ /* 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;
+ }
+ else
+ *cookie_size = NULL_TREE;
+ }
+
+ /* Build the CALL_EXPR. */
+ return build_over_call (cand, LOOKUP_NORMAL);
}
static tree
-build_object_call (obj, args)
- tree obj, args;
+build_object_call (tree obj, tree args)
{
struct z_candidate *candidates = 0, *cand;
tree fns, convs, mem_args = NULL_TREE;
tree type = TREE_TYPE (obj);
+ bool any_viable_p;
if (TYPE_PTRMEMFUNC_P (type))
{
@@ -3031,16 +2795,15 @@ build_object_call (obj, args)
}
}
- if (! any_viable (candidates))
+ candidates = splice_viable (candidates, pedantic, &any_viable_p);
+ if (!any_viable_p)
{
error ("no match for call to `(%T) (%A)'", TREE_TYPE (obj), args);
print_z_candidates (candidates);
return error_mark_node;
}
- candidates = splice_viable (candidates);
cand = tourney (candidates);
-
if (cand == 0)
{
error ("call of `(%T) (%A)' is ambiguous", TREE_TYPE (obj), args);
@@ -3053,7 +2816,7 @@ build_object_call (obj, args)
DECL_NAME here. */
if (TREE_CODE (cand->fn) == FUNCTION_DECL
&& DECL_OVERLOADED_OPERATOR_P (cand->fn) == CALL_EXPR)
- return build_over_call (cand, mem_args, LOOKUP_NORMAL);
+ return build_over_call (cand, LOOKUP_NORMAL);
obj = convert_like_with_context
(TREE_VEC_ELT (cand->convs, 0), obj, cand->fn, -1);
@@ -3063,10 +2826,8 @@ build_object_call (obj, args)
}
static void
-op_error (code, code2, arg1, arg2, arg3, problem)
- enum tree_code code, code2;
- tree arg1, arg2, arg3;
- const char *problem;
+op_error (enum tree_code code, enum tree_code code2,
+ tree arg1, tree arg2, tree arg3, const char *problem)
{
const char *opname;
@@ -3090,6 +2851,11 @@ op_error (code, code2, arg1, arg2, arg3, problem)
case ARRAY_REF:
error ("%s for 'operator[]' in '%E[%E]'", problem, arg1, arg2);
break;
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ error ("%s for '%s' in '%s %E'", problem, opname, opname, arg1);
+ break;
default:
if (arg2)
@@ -3106,9 +2872,7 @@ op_error (code, code2, arg1, arg2, arg3, problem)
convert E1 to E2 in [expr.cond]. */
static tree
-conditional_conversion (e1, e2)
- tree e1;
- tree e2;
+conditional_conversion (tree e1, tree e2)
{
tree t1 = non_reference (TREE_TYPE (e1));
tree t2 = non_reference (TREE_TYPE (e2));
@@ -3150,6 +2914,8 @@ conditional_conversion (e1, e2)
if (!same_type_p (TYPE_MAIN_VARIANT (t1),
TYPE_MAIN_VARIANT (t2)))
conv = build_conv (BASE_CONV, t2, conv);
+ else
+ conv = build_conv (RVALUE_CONV, t2, conv);
return conv;
}
else
@@ -3168,16 +2934,13 @@ conditional_conversion (e1, e2)
arguments to the conditional expression. */
tree
-build_conditional_expr (arg1, arg2, arg3)
- tree arg1;
- tree arg2;
- tree arg3;
+build_conditional_expr (tree arg1, tree arg2, tree arg3)
{
tree arg2_type;
tree arg3_type;
tree result;
tree result_type = NULL_TREE;
- int lvalue_p = 1;
+ bool lvalue_p = true;
struct z_candidate *candidates = 0;
struct z_candidate *cand;
@@ -3189,23 +2952,25 @@ build_conditional_expr (arg1, arg2, arg3)
{
if (pedantic)
pedwarn ("ISO C++ forbids omitting the middle term of a ?: expression");
- arg1 = arg2 = save_expr (arg1);
+
+ /* Make sure that lvalues remain lvalues. See g++.oliva/ext1.C. */
+ if (real_lvalue_p (arg1))
+ arg2 = arg1 = stabilize_reference (arg1);
+ else
+ arg2 = arg1 = save_expr (arg1);
}
/* [expr.cond]
The first expr ession is implicitly converted to bool (clause
_conv_). */
- arg1 = cp_convert (boolean_type_node, arg1);
+ arg1 = perform_implicit_conversion (boolean_type_node, arg1);
/* If something has already gone wrong, just pass that fact up the
tree. */
- if (arg1 == error_mark_node
- || arg2 == error_mark_node
- || arg3 == error_mark_node
- || TREE_TYPE (arg1) == error_mark_node
- || TREE_TYPE (arg2) == error_mark_node
- || TREE_TYPE (arg3) == error_mark_node)
+ if (error_operand_p (arg1)
+ || error_operand_p (arg2)
+ || error_operand_p (arg3))
return error_mark_node;
/* [expr.cond]
@@ -3238,11 +3003,27 @@ build_conditional_expr (arg1, arg2, arg3)
type of the other and is an rvalue.
--Both the second and the third operands have type void; the
- result is of type void and is an rvalue. */
- if ((TREE_CODE (arg2) == THROW_EXPR)
- ^ (TREE_CODE (arg3) == THROW_EXPR))
- result_type = ((TREE_CODE (arg2) == THROW_EXPR)
- ? arg3_type : arg2_type);
+ result is of type void and is an rvalue.
+
+ We must avoid calling force_rvalue for expressions of type
+ "void" because it will complain that their value is being
+ used. */
+ if (TREE_CODE (arg2) == THROW_EXPR
+ && TREE_CODE (arg3) != THROW_EXPR)
+ {
+ if (!VOID_TYPE_P (arg3_type))
+ arg3 = force_rvalue (arg3);
+ arg3_type = TREE_TYPE (arg3);
+ result_type = arg3_type;
+ }
+ else if (TREE_CODE (arg2) != THROW_EXPR
+ && TREE_CODE (arg3) == THROW_EXPR)
+ {
+ if (!VOID_TYPE_P (arg2_type))
+ arg2 = force_rvalue (arg2);
+ arg2_type = TREE_TYPE (arg2);
+ result_type = arg2_type;
+ }
else if (VOID_TYPE_P (arg2_type) && VOID_TYPE_P (arg3_type))
result_type = void_type_node;
else
@@ -3252,7 +3033,7 @@ build_conditional_expr (arg1, arg2, arg3)
return error_mark_node;
}
- lvalue_p = 0;
+ lvalue_p = false;
goto valid_operands;
}
/* [expr.cond]
@@ -3287,33 +3068,46 @@ build_conditional_expr (arg1, arg2, arg3)
{
arg2 = convert_like (conv2, arg2);
arg2 = convert_from_reference (arg2);
- /* That may not quite have done the trick. If the two types
- are cv-qualified variants of one another, we will have
- just used an IDENTITY_CONV. (There's no conversion from
- an lvalue of one class type to an lvalue of another type,
- even a cv-qualified variant, and we don't want to lose
- lvalue-ness here.) So, we manually add a NOP_EXPR here
- if necessary. */
- if (!same_type_p (TREE_TYPE (arg2), arg3_type))
- arg2 = build1 (NOP_EXPR, arg3_type, arg2);
arg2_type = TREE_TYPE (arg2);
}
else if (conv3 && !ICS_BAD_FLAG (conv3))
{
arg3 = convert_like (conv3, arg3);
arg3 = convert_from_reference (arg3);
- if (!same_type_p (TREE_TYPE (arg3), arg2_type))
- arg3 = build1 (NOP_EXPR, arg2_type, arg3);
arg3_type = TREE_TYPE (arg3);
}
+
+ /* If, after the conversion, both operands have class type,
+ treat the cv-qualification of both operands as if it were the
+ union of the cv-qualification of the operands.
+
+ The standard is not clear about what to do in this
+ circumstance. For example, if the first operand has type
+ "const X" and the second operand has a user-defined
+ conversion to "volatile X", what is the type of the second
+ operand after this step? Making it be "const X" (matching
+ the first operand) seems wrong, as that discards the
+ qualification without actuall performing a copy. Leaving it
+ as "volatile X" seems wrong as that will result in the
+ conditional expression failing altogether, even though,
+ according to this step, the one operand could be converted to
+ the type of the other. */
+ if ((conv2 || conv3)
+ && CLASS_TYPE_P (arg2_type)
+ && TYPE_QUALS (arg2_type) != TYPE_QUALS (arg3_type))
+ arg2_type = arg3_type =
+ cp_build_qualified_type (arg2_type,
+ TYPE_QUALS (arg2_type)
+ | TYPE_QUALS (arg3_type));
}
/* [expr.cond]
If the second and third operands are lvalues and have the same
type, the result is of that type and is an lvalue. */
- if (real_lvalue_p (arg2) && real_lvalue_p (arg3) &&
- same_type_p (arg2_type, arg3_type))
+ if (real_lvalue_p (arg2)
+ && real_lvalue_p (arg3)
+ && same_type_p (arg2_type, arg3_type))
{
result_type = arg2_type;
goto valid_operands;
@@ -3326,12 +3120,13 @@ build_conditional_expr (arg1, arg2, arg3)
cv-qualified) class type, overload resolution is used to
determine the conversions (if any) to be applied to the operands
(_over.match.oper_, _over.built_). */
- lvalue_p = 0;
+ lvalue_p = false;
if (!same_type_p (arg2_type, arg3_type)
&& (CLASS_TYPE_P (arg2_type) || CLASS_TYPE_P (arg3_type)))
{
tree args[3];
tree conv;
+ bool any_viable_p;
/* Rearrange the arguments so that add_builtin_candidate only has
to know about two args. In build_builtin_candidates, the
@@ -3350,13 +3145,13 @@ build_conditional_expr (arg1, arg2, arg3)
If the overload resolution fails, the program is
ill-formed. */
- if (!any_viable (candidates))
+ candidates = splice_viable (candidates, pedantic, &any_viable_p);
+ if (!any_viable_p)
{
op_error (COND_EXPR, NOP_EXPR, arg1, arg2, arg3, "no match");
print_z_candidates (candidates);
return error_mark_node;
}
- candidates = splice_viable (candidates);
cand = tourney (candidates);
if (!cand)
{
@@ -3387,16 +3182,15 @@ build_conditional_expr (arg1, arg2, arg3)
We need to force the lvalue-to-rvalue conversion here for class types,
so we get TARGET_EXPRs; trying to deal with a COND_EXPR of class rvalues
that isn't wrapped with a TARGET_EXPR plays havoc with exception
- regions.
-
- We use ocp_convert rather than build_user_type_conversion because the
- latter returns NULL_TREE on failure, while the former gives an error. */
+ regions. */
arg2 = force_rvalue (arg2);
- arg2_type = TREE_TYPE (arg2);
+ if (!CLASS_TYPE_P (arg2_type))
+ arg2_type = TREE_TYPE (arg2);
arg3 = force_rvalue (arg3);
- arg3_type = TREE_TYPE (arg3);
+ if (!CLASS_TYPE_P (arg2_type))
+ arg3_type = TREE_TYPE (arg3);
if (arg2 == error_mark_node || arg3 == error_mark_node)
return error_mark_node;
@@ -3454,18 +3248,17 @@ build_conditional_expr (arg1, arg2, arg3)
cv-qualification of either the second or the third operand.
The result is of the common type. */
else if ((null_ptr_cst_p (arg2)
- && (TYPE_PTR_P (arg3_type) || TYPE_PTRMEM_P (arg3_type)
- || TYPE_PTRMEMFUNC_P (arg3_type)))
+ && (TYPE_PTR_P (arg3_type) || TYPE_PTR_TO_MEMBER_P (arg3_type)))
|| (null_ptr_cst_p (arg3)
- && (TYPE_PTR_P (arg2_type) || TYPE_PTRMEM_P (arg2_type)
- || TYPE_PTRMEMFUNC_P (arg2_type)))
+ && (TYPE_PTR_P (arg2_type) || TYPE_PTR_TO_MEMBER_P (arg2_type)))
|| (TYPE_PTR_P (arg2_type) && TYPE_PTR_P (arg3_type))
|| (TYPE_PTRMEM_P (arg2_type) && TYPE_PTRMEM_P (arg3_type))
- || (TYPE_PTRMEMFUNC_P (arg2_type)
- && TYPE_PTRMEMFUNC_P (arg3_type)))
+ || (TYPE_PTRMEMFUNC_P (arg2_type) && TYPE_PTRMEMFUNC_P (arg3_type)))
{
result_type = composite_pointer_type (arg2_type, arg3_type, arg2,
arg3, "conditional expression");
+ if (result_type == error_mark_node)
+ return error_mark_node;
arg2 = perform_implicit_conversion (result_type, arg2);
arg3 = perform_implicit_conversion (result_type, arg3);
}
@@ -3478,45 +3271,125 @@ build_conditional_expr (arg1, arg2, arg3)
valid_operands:
result = fold (build (COND_EXPR, result_type, arg1, arg2, arg3));
+ /* We can't use result_type below, as fold might have returned a
+ throw_expr. */
+
/* Expand both sides into the same slot, hopefully the target of the
?: expression. We used to check for TARGET_EXPRs here, but now we
sometimes wrap them in NOP_EXPRs so the test would fail. */
- if (!lvalue_p && IS_AGGR_TYPE (result_type))
- result = build_target_expr_with_type (result, result_type);
+ if (!lvalue_p && CLASS_TYPE_P (TREE_TYPE (result)))
+ result = get_target_expr (result);
/* If this expression is an rvalue, but might be mistaken for an
lvalue, we must add a NON_LVALUE_EXPR. */
if (!lvalue_p && real_lvalue_p (result))
- result = build1 (NON_LVALUE_EXPR, result_type, result);
+ result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
return result;
}
+/* OPERAND is an operand to an expression. Perform necessary steps
+ required before using it. If OPERAND is NULL_TREE, NULL_TREE is
+ returned. */
+
+static tree
+prep_operand (tree operand)
+{
+ if (operand)
+ {
+ operand = convert_from_reference (operand);
+ if (CLASS_TYPE_P (TREE_TYPE (operand))
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (operand)))
+ /* Make sure the template type is instantiated now. */
+ instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (operand)));
+ }
+
+ return 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. */
+
+static void
+add_candidates (tree fns, tree 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;
+
+ ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
+ /* Delay creating the implicit this parameter until it is needed. */
+ non_static_args = NULL_TREE;
+
+ while (fns)
+ {
+ tree fn;
+ tree fn_args;
+
+ fn = OVL_CURRENT (fns);
+ /* Figure out which set of arguments to use. */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+ {
+ /* 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));
+ fn_args = non_static_args;
+ }
+ else
+ /* Otherwise, just use the list of arguments provided. */
+ fn_args = args;
+
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ add_template_candidate (candidates,
+ fn,
+ ctype,
+ explicit_targs,
+ fn_args,
+ NULL_TREE,
+ access_path,
+ conversion_path,
+ flags,
+ DEDUCE_CALL);
+ else if (!template_only)
+ add_function_candidate (candidates,
+ fn,
+ ctype,
+ fn_args,
+ access_path,
+ conversion_path,
+ flags);
+ fns = OVL_NEXT (fns);
+ }
+}
+
tree
-build_new_op (code, flags, arg1, arg2, arg3)
- enum tree_code code;
- int flags;
- tree arg1, arg2, arg3;
+build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
+ bool *overloaded_p)
{
struct z_candidate *candidates = 0, *cand;
- tree fns, mem_arglist = NULL_TREE, arglist, fnname;
+ tree arglist, fnname;
+ tree args[3];
enum tree_code code2 = NOP_EXPR;
tree conv;
- bool viable_candidates;
+ bool strict_p;
+ bool any_viable_p;
- if (arg1 == error_mark_node
- || arg2 == error_mark_node
- || arg3 == error_mark_node)
+ if (error_operand_p (arg1)
+ || error_operand_p (arg2)
+ || error_operand_p (arg3))
return error_mark_node;
- /* This can happen if a template takes all non-type parameters, e.g.
- undeclared_template<1, 5, 72>a; */
- if (code == LT_EXPR && TREE_CODE (arg1) == TEMPLATE_DECL)
- {
- error ("`%D' must be declared before use", arg1);
- return error_mark_node;
- }
-
if (code == MODIFY_EXPR)
{
code2 = TREE_CODE (arg3);
@@ -3526,13 +3399,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
else
fnname = ansi_opname (code);
- if (TREE_CODE (arg1) == OFFSET_REF)
- arg1 = resolve_offset_ref (arg1);
- arg1 = convert_from_reference (arg1);
- if (CLASS_TYPE_P (TREE_TYPE (arg1))
- && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg1)))
- /* Make sure the template type is instantiated now. */
- instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)));
+ arg1 = prep_operand (arg1);
switch (code)
{
@@ -3550,24 +3417,8 @@ build_new_op (code, flags, arg1, arg2, arg3)
break;
}
- if (arg2)
- {
- if (TREE_CODE (arg2) == OFFSET_REF)
- arg2 = resolve_offset_ref (arg2);
- arg2 = convert_from_reference (arg2);
- if (CLASS_TYPE_P (TREE_TYPE (arg2))
- && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg2)))
- instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg2)));
- }
- if (arg3)
- {
- if (TREE_CODE (arg3) == OFFSET_REF)
- arg3 = resolve_offset_ref (arg3);
- arg3 = convert_from_reference (arg3);
- if (CLASS_TYPE_P (TREE_TYPE (arg3))
- && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg3)))
- instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg3)));
- }
+ arg2 = prep_operand (arg2);
+ arg3 = prep_operand (arg3);
if (code == COND_EXPR)
{
@@ -3592,89 +3443,45 @@ build_new_op (code, flags, arg1, arg2, arg3)
arglist = tree_cons (NULL_TREE, arg2, arglist);
arglist = tree_cons (NULL_TREE, arg1, arglist);
- fns = lookup_function_nonclass (fnname, arglist);
-
- if (fns && TREE_CODE (fns) == TREE_LIST)
- fns = TREE_VALUE (fns);
- for (; fns; fns = OVL_NEXT (fns))
+ /* Add namespace-scope operators to the list of functions to
+ consider. */
+ add_candidates (lookup_function_nonclass (fnname, arglist),
+ arglist, NULL_TREE, false, NULL_TREE, NULL_TREE,
+ flags, &candidates);
+ /* Add class-member operators to the candidate set. */
+ if (CLASS_TYPE_P (TREE_TYPE (arg1)))
{
- tree fn = OVL_CURRENT (fns);
- if (TREE_CODE (fn) == TEMPLATE_DECL)
- add_template_candidate (&candidates, fn, NULL_TREE, NULL_TREE,
- arglist, TREE_TYPE (fnname),
- /*access_path=*/NULL_TREE,
- /*conversion_path=*/NULL_TREE,
- flags, DEDUCE_CALL);
- else
- add_function_candidate (&candidates, fn, NULL_TREE,
- arglist,
- /*access_path=*/NULL_TREE,
- /*conversion_path=*/NULL_TREE,
- flags);
- }
+ tree fns;
- if (IS_AGGR_TYPE (TREE_TYPE (arg1)))
- {
fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 1);
if (fns == error_mark_node)
return fns;
+ if (fns)
+ add_candidates (BASELINK_FUNCTIONS (fns), arglist,
+ NULL_TREE, false,
+ BASELINK_BINFO (fns),
+ TYPE_BINFO (TREE_TYPE (arg1)),
+ flags, &candidates);
+ }
+
+ /* Rearrange the arguments for ?: so that add_builtin_candidate only has
+ to know about two args; a builtin candidate will always have a first
+ parameter of type bool. We'll handle that in
+ build_builtin_candidate. */
+ if (code == COND_EXPR)
+ {
+ args[0] = arg2;
+ args[1] = arg3;
+ args[2] = arg1;
}
else
- fns = NULL_TREE;
-
- if (fns)
{
- tree conversion_path = BASELINK_BINFO (fns);
-
- mem_arglist = tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist));
- for (fns = BASELINK_FUNCTIONS (fns); fns; fns = OVL_NEXT (fns))
- {
- tree fn = OVL_CURRENT (fns);
- tree this_arglist;
- tree access_path = TYPE_BINFO (TREE_TYPE (arg1));
-
- if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
- this_arglist = mem_arglist;
- else
- this_arglist = arglist;
-
- if (TREE_CODE (fn) == TEMPLATE_DECL)
- /* A member template. */
- add_template_candidate (&candidates, fn,
- BINFO_TYPE (conversion_path),
- NULL_TREE,
- this_arglist, TREE_TYPE (fnname),
- access_path, conversion_path,
- flags, DEDUCE_CALL);
- else
- add_function_candidate
- (&candidates, fn, BINFO_TYPE (conversion_path), this_arglist,
- access_path, conversion_path, flags);
- }
+ args[0] = arg1;
+ args[1] = arg2;
+ args[2] = NULL_TREE;
}
- {
- tree args[3];
-
- /* Rearrange the arguments for ?: so that add_builtin_candidate only has
- to know about two args; a builtin candidate will always have a first
- parameter of type bool. We'll handle that in
- build_builtin_candidate. */
- if (code == COND_EXPR)
- {
- args[0] = arg2;
- args[1] = arg3;
- args[2] = arg1;
- }
- else
- {
- args[0] = arg1;
- args[1] = arg2;
- args[2] = NULL_TREE;
- }
-
- add_builtin_candidates (&candidates, code, code2, fnname, args, flags);
- }
+ add_builtin_candidates (&candidates, code, code2, fnname, args, flags);
switch (code)
{
@@ -3686,15 +3493,16 @@ build_new_op (code, flags, arg1, arg2, arg3)
operators. The built-in candidate set for COMPONENT_REF
would be empty too, but since there are no such built-in
operators, we accept non-strict matches for them. */
- viable_candidates = any_strictly_viable (candidates);
+ strict_p = true;
break;
default:
- viable_candidates = any_viable (candidates);
+ strict_p = pedantic;
break;
}
- if (! viable_candidates)
+ candidates = splice_viable (candidates, strict_p, &any_viable_p);
+ if (!any_viable_p)
{
switch (code)
{
@@ -3710,7 +3518,8 @@ build_new_op (code, flags, arg1, arg2, arg3)
code = PREINCREMENT_EXPR;
else
code = PREDECREMENT_EXPR;
- return build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE);
+ return build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE,
+ overloaded_p);
/* The caller will deal with these. */
case ADDR_EXPR:
@@ -3728,9 +3537,8 @@ build_new_op (code, flags, arg1, arg2, arg3)
}
return error_mark_node;
}
- candidates = splice_viable (candidates);
- cand = tourney (candidates);
+ cand = tourney (candidates);
if (cand == 0)
{
if (flags & LOOKUP_COMPLAIN)
@@ -3743,7 +3551,9 @@ build_new_op (code, flags, arg1, arg2, arg3)
if (TREE_CODE (cand->fn) == FUNCTION_DECL)
{
- extern int warn_synth;
+ if (overloaded_p)
+ *overloaded_p = true;
+
if (warn_synth
&& fnname == ansi_assopname (NOP_EXPR)
&& DECL_ARTIFICIAL (cand->fn)
@@ -3758,11 +3568,7 @@ build_new_op (code, flags, arg1, arg2, arg3)
: candidates->fn);
}
- return build_over_call
- (cand,
- TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE
- ? mem_arglist : arglist,
- LOOKUP_NORMAL);
+ return build_over_call (cand, LOOKUP_NORMAL);
}
/* Check for comparison of different enum types. */
@@ -3887,21 +3693,17 @@ builtin:
PLACEMENT is the corresponding placement new call, or NULL_TREE. */
tree
-build_op_delete_call (code, addr, size, flags, placement)
- enum tree_code code;
- tree addr, size, placement;
- int flags;
+build_op_delete_call (enum tree_code code, tree addr, tree size,
+ int flags, tree placement)
{
tree fn = NULL_TREE;
- tree fns, fnname, fntype, argtypes, args, type;
+ tree fns, fnname, argtypes, args, type;
int pass;
if (addr == error_mark_node)
return error_mark_node;
- type = TREE_TYPE (TREE_TYPE (addr));
- while (TREE_CODE (type) == ARRAY_TYPE)
- type = TREE_TYPE (type);
+ type = strip_array_types (TREE_TYPE (TREE_TYPE (addr)));
fnname = ansi_opname (code);
@@ -3912,7 +3714,7 @@ build_op_delete_call (code, addr, size, flags, placement)
the lookup selects a placement deallocation function, the
program is ill-formed.
- Therefore, we ask lookup_fnfields to complain ambout ambiguity. */
+ Therefore, we ask lookup_fnfields to complain about ambiguity. */
{
fns = lookup_fnfields (TYPE_BINFO (type), fnname, 1);
if (fns == error_mark_node)
@@ -3931,10 +3733,6 @@ build_op_delete_call (code, addr, size, flags, placement)
/* Find the allocation function that is being called. */
call_expr = placement;
- /* Sometimes we have a COMPOUND_EXPR, rather than a simple
- CALL_EXPR. */
- while (TREE_CODE (call_expr) == COMPOUND_EXPR)
- call_expr = TREE_OPERAND (call_expr, 1);
/* Extract the function. */
alloc_fn = get_callee_fndecl (call_expr);
my_friendly_assert (alloc_fn != NULL_TREE, 20020327);
@@ -3954,21 +3752,11 @@ build_op_delete_call (code, addr, size, flags, placement)
addr = cp_convert (ptr_type_node, addr);
/* We make two tries at finding a matching `operator delete'. On
- the first pass, we look for an one-operator (or placement)
+ the first pass, we look for a one-operator (or placement)
operator delete. If we're not doing placement delete, then on
the second pass we look for a two-argument delete. */
for (pass = 0; pass < (placement ? 1 : 2); ++pass)
{
- if (pass == 0)
- argtypes = tree_cons (NULL_TREE, ptr_type_node, argtypes);
- else
- /* Normal delete; now try to find a match including the size
- argument. */
- argtypes = tree_cons (NULL_TREE, ptr_type_node,
- tree_cons (NULL_TREE, sizetype,
- void_list_node));
- fntype = build_function_type (void_type_node, argtypes);
-
/* Go through the `operator delete' functions looking for one
with a matching type. */
for (fn = BASELINK_P (fns) ? BASELINK_FUNCTIONS (fns) : fns;
@@ -3977,13 +3765,30 @@ build_op_delete_call (code, addr, size, flags, placement)
{
tree t;
- /* Exception specifications on the `delete' operator do not
- matter. */
- t = build_exception_variant (TREE_TYPE (OVL_CURRENT (fn)),
- NULL_TREE);
- /* We also don't compare attributes. We're really just
- trying to check the types of the first two parameters. */
- if (comptypes (t, fntype, COMPARE_NO_ATTRIBUTES))
+ /* The first argument must be "void *". */
+ t = TYPE_ARG_TYPES (TREE_TYPE (OVL_CURRENT (fn)));
+ if (!same_type_p (TREE_VALUE (t), ptr_type_node))
+ continue;
+ t = TREE_CHAIN (t);
+ /* On the first pass, check the rest of the arguments. */
+ if (pass == 0)
+ {
+ tree a = argtypes;
+ while (a && t)
+ {
+ if (!same_type_p (TREE_VALUE (a), TREE_VALUE (t)))
+ break;
+ a = TREE_CHAIN (a);
+ t = TREE_CHAIN (t);
+ }
+ if (!a && !t)
+ break;
+ }
+ /* On the second pass, the second argument must be
+ "size_t". */
+ else if (pass == 1
+ && same_type_p (TREE_VALUE (t), sizetype)
+ && TREE_CHAIN (t) == void_list_node)
break;
}
@@ -4002,7 +3807,7 @@ build_op_delete_call (code, addr, size, flags, placement)
/* If the FN is a member function, make sure that it is
accessible. */
if (DECL_CLASS_SCOPE_P (fn))
- enforce_access (type, fn);
+ perform_or_defer_access_check (TYPE_BINFO (type), fn);
if (pass == 0)
args = tree_cons (NULL_TREE, addr, args);
@@ -4010,7 +3815,15 @@ build_op_delete_call (code, addr, size, flags, placement)
args = tree_cons (NULL_TREE, addr,
build_tree_list (NULL_TREE, size));
- return build_function_call (fn, args);
+ if (placement)
+ {
+ /* The placement args might not be suitable for overload
+ resolution at this point, so build the call directly. */
+ mark_used (fn);
+ return build_cxx_call (fn, args, args);
+ }
+ else
+ return build_function_call (fn, args);
}
/* If we are doing placement delete we do nothing if we don't find a
@@ -4018,7 +3831,8 @@ build_op_delete_call (code, addr, size, flags, placement)
if (placement)
return NULL_TREE;
- error ("no suitable `operator delete' for `%T'", type);
+ error ("no suitable `operator %s' for `%T'",
+ operator_name_info[(int)code].name, type);
return error_mark_node;
}
@@ -4026,15 +3840,12 @@ build_op_delete_call (code, addr, size, flags, placement)
BASETYPE_PATH, give an error. The most derived class in
BASETYPE_PATH is the one used to qualify DECL. */
-int
-enforce_access (basetype_path, decl)
- tree basetype_path;
- tree decl;
+bool
+enforce_access (tree basetype_path, tree decl)
{
- int accessible;
-
- accessible = accessible_p (basetype_path, decl);
- if (!accessible)
+ my_friendly_assert (TREE_CODE (basetype_path) == TREE_VEC, 20030624);
+
+ if (!accessible_p (basetype_path, decl))
{
if (TREE_PRIVATE (decl))
cp_error_at ("`%+#D' is private", decl);
@@ -4043,11 +3854,53 @@ enforce_access (basetype_path, decl)
else
cp_error_at ("`%+#D' is inaccessible", decl);
error ("within this context");
- return 0;
+ return false;
}
- return 1;
+ return true;
+}
+
+/* Check that a callable constructor to initialize a temporary of
+ TYPE from an EXPR exists. */
+
+static void
+check_constructor_callable (tree type, tree expr)
+{
+ build_special_member_call (NULL_TREE,
+ complete_ctor_identifier,
+ build_tree_list (NULL_TREE, expr),
+ TYPE_BINFO (type),
+ LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING
+ | LOOKUP_CONSTRUCTOR_CALLABLE);
+}
+
+/* Initialize a temporary of type TYPE with EXPR. The FLAGS are a
+ bitwise or of LOOKUP_* values. If any errors are warnings are
+ generated, set *DIAGNOSTIC_FN to "error" or "warning",
+ respectively. If no diagnostics are generated, set *DIAGNOSTIC_FN
+ to NULL. */
+
+static tree
+build_temp (tree expr, tree type, int flags,
+ void (**diagnostic_fn)(const char *, ...))
+{
+ int savew, savee;
+
+ savew = warningcount, savee = errorcount;
+ expr = build_special_member_call (NULL_TREE,
+ complete_ctor_identifier,
+ build_tree_list (NULL_TREE, expr),
+ TYPE_BINFO (type),
+ flags);
+ if (warningcount > savew)
+ *diagnostic_fn = warning;
+ else if (errorcount > savee)
+ *diagnostic_fn = error;
+ else
+ *diagnostic_fn = NULL;
+ return expr;
}
+
/* Perform the conversions in CONVS on the expression EXPR. FN and
ARGNUM are used for diagnostics. ARGNUM is zero based, -1
@@ -4061,9 +3914,8 @@ static tree
convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
bool issue_conversion_warnings)
{
- int savew, savee;
-
tree totype = TREE_TYPE (convs);
+ void (*diagnostic_fn)(const char *, ...);
if (ICS_BAD_FLAG (convs)
&& TREE_CODE (convs) != USER_CONV
@@ -4093,7 +3945,7 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
if (issue_conversion_warnings)
expr = dubious_conversion_warnings
- (totype, expr, "argument", fn, argnum);
+ (totype, expr, "converting", fn, argnum);
switch (TREE_CODE (convs))
{
case USER_CONV:
@@ -4117,7 +3969,7 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
}
else
args = build_this (expr);
- expr = build_over_call (cand, args, LOOKUP_NORMAL);
+ expr = build_over_call (cand, LOOKUP_NORMAL);
/* If this is a constructor or a function returning an aggr type,
we need to build up a TARGET_EXPR. */
@@ -4135,35 +3987,24 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
if (IS_AGGR_TYPE (totype)
&& (inner >= 0 || !lvalue_p (expr)))
{
- savew = warningcount, savee = errorcount;
- expr = build_special_member_call
- (NULL_TREE, complete_ctor_identifier,
- build_tree_list (NULL_TREE, expr), TYPE_BINFO (totype),
- /* Core issue 84, now a DR, says that we don't allow UDCs
- for these args (which deliberately breaks copy-init of an
- auto_ptr<Base> from an auto_ptr<Derived>). */
- LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION);
-
- /* Tell the user where this failing constructor call came from. */
- if (fn)
+ expr = (build_temp
+ (expr, totype,
+ /* Core issue 84, now a DR, says that we don't
+ allow UDCs for these args (which deliberately
+ breaks copy-init of an auto_ptr<Base> from an
+ auto_ptr<Derived>). */
+ LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION,
+ &diagnostic_fn));
+
+ if (diagnostic_fn)
{
- if (warningcount > savew)
- warning
+ if (fn)
+ diagnostic_fn
(" initializing argument %P of `%D' from result of `%D'",
argnum, fn, convfn);
- else if (errorcount > savee)
- error
- (" initializing argument %P of `%D' from result of `%D'",
- argnum, fn, convfn);
- }
- else
- {
- if (warningcount > savew)
- warning (" initializing temporary from result of `%D'",
- convfn);
- else if (errorcount > savee)
- error (" initializing temporary from result of `%D'",
- convfn);
+ else
+ diagnostic_fn
+ (" initializing temporary from result of `%D'", convfn);
}
expr = build_cplus_new (totype, expr);
}
@@ -4172,6 +4013,15 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
case IDENTITY_CONV:
if (type_unknown_p (expr))
expr = instantiate_type (totype, expr, tf_error | tf_warning);
+ /* Convert a non-array constant variable to its underlying
+ value, unless we are about to bind it to a reference, in
+ which case we need to leave it as an lvalue. */
+ if (inner >= 0
+ && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
+ expr = decl_constant_value (expr);
+ if (CHECK_COPY_CONSTRUCTOR_P (convs))
+ check_constructor_callable (totype, expr);
+
return expr;
case AMBIG_CONV:
/* Call build_user_type_conversion again for the error. */
@@ -4188,29 +4038,23 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
if (expr == error_mark_node)
return error_mark_node;
- /* Convert a non-array constant variable to its underlying value, unless we
- are about to bind it to a reference, in which case we need to
- leave it as an lvalue. */
- if (TREE_CODE (convs) != REF_BIND
- && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
- expr = decl_constant_value (expr);
-
switch (TREE_CODE (convs))
{
case RVALUE_CONV:
if (! IS_AGGR_TYPE (totype))
return expr;
- /* else fall through */
+ /* Else fall through. */
case BASE_CONV:
if (TREE_CODE (convs) == BASE_CONV && !NEED_TEMPORARY_P (convs))
{
/* We are going to bind a reference directly to a base-class
subobject of EXPR. */
- tree base_ptr = build_pointer_type (totype);
-
+ if (CHECK_COPY_CONSTRUCTOR_P (convs))
+ check_constructor_callable (TREE_TYPE (expr), expr);
/* Build an expression for `*((base*) &expr)'. */
expr = build_unary_op (ADDR_EXPR, expr, 0);
- expr = perform_implicit_conversion (base_ptr, expr);
+ expr = perform_implicit_conversion (build_pointer_type (totype),
+ expr);
expr = build_indirect_ref (expr, "implicit conversion");
return expr;
}
@@ -4218,18 +4062,10 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
/* Copy-initialization where the cv-unqualified version of the source
type is the same class as, or a derived class of, the class of the
destination [is treated as direct-initialization]. [dcl.init] */
- savew = warningcount, savee = errorcount;
- expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
- build_tree_list (NULL_TREE, expr),
- TYPE_BINFO (totype),
- LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING);
- if (fn)
- {
- if (warningcount > savew)
- warning (" initializing argument %P of `%D'", argnum, fn);
- else if (errorcount > savee)
- error (" initializing argument %P of `%D'", argnum, fn);
- }
+ expr = build_temp (expr, totype, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING,
+ &diagnostic_fn);
+ if (diagnostic_fn && fn)
+ diagnostic_fn (" initializing argument %P of `%D'", argnum, fn);
return build_cplus_new (totype, expr);
case REF_BIND:
@@ -4237,9 +4073,26 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
tree ref_type = totype;
/* If necessary, create a temporary. */
- if (NEED_TEMPORARY_P (convs) || !non_cast_lvalue_p (expr))
+ if (NEED_TEMPORARY_P (convs) || !lvalue_p (expr))
{
tree type = TREE_TYPE (TREE_OPERAND (convs, 0));
+
+ if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)))
+ {
+ /* If the reference is volatile or non-const, we
+ cannot create a temporary. */
+ cp_lvalue_kind lvalue = real_lvalue_p (expr);
+
+ if (lvalue & clk_bitfield)
+ error ("cannot bind bitfield `%E' to `%T'",
+ expr, ref_type);
+ else if (lvalue & clk_packed)
+ error ("cannot bind packed field `%E' to `%T'",
+ expr, ref_type);
+ else
+ error ("cannot bind rvalue `%E' to `%T'", expr, ref_type);
+ return error_mark_node;
+ }
expr = build_target_expr_with_type (expr, type);
}
@@ -4273,50 +4126,60 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner,
LOOKUP_NORMAL|LOOKUP_NO_CONVERSION);
}
-/* Build a call to __builtin_trap which can be used in an expression. */
+/* Build a call to __builtin_trap. */
static tree
-call_builtin_trap ()
+call_builtin_trap (void)
{
- tree fn = get_identifier ("__builtin_trap");
- if (IDENTIFIER_GLOBAL_VALUE (fn))
- fn = IDENTIFIER_GLOBAL_VALUE (fn);
- else
- abort ();
+ tree fn = IDENTIFIER_GLOBAL_VALUE (get_identifier ("__builtin_trap"));
+ my_friendly_assert (fn != NULL, 20030927);
fn = build_call (fn, NULL_TREE);
- fn = build (COMPOUND_EXPR, integer_type_node, fn, integer_zero_node);
return fn;
}
/* ARG is being passed to a varargs function. Perform any conversions
- required. Array/function to pointer decay must have already happened.
- Return the converted value. */
+ required. Return the converted value. */
tree
-convert_arg_to_ellipsis (arg)
- tree arg;
+convert_arg_to_ellipsis (tree arg)
{
+ /* [expr.call]
+
+ The lvalue-to-rvalue, array-to-pointer, and function-to-pointer
+ standard conversions are performed. */
+ arg = decay_conversion (arg);
+ /* [expr.call]
+
+ If the argument has integral or enumeration type that is subject
+ to the integral promotions (_conv.prom_), or a floating point
+ type that is subject to the floating point promotion
+ (_conv.fpprom_), the value of the argument is converted to the
+ promoted type before the call. */
if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE
&& (TYPE_PRECISION (TREE_TYPE (arg))
< TYPE_PRECISION (double_type_node)))
- /* Convert `float' to `double'. */
- arg = cp_convert (double_type_node, arg);
- else
- /* Convert `short' and `char' to full-size `int'. */
- arg = default_conversion (arg);
+ arg = convert_to_real (double_type_node, arg);
+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
+ arg = perform_integral_promotions (arg);
arg = require_complete_type (arg);
- if (arg != error_mark_node && ! pod_type_p (TREE_TYPE (arg)))
+ if (arg != error_mark_node
+ && !pod_type_p (TREE_TYPE (arg)))
{
/* Undefined behavior [expr.call] 5.2.2/7. We used to just warn
here and do a bitwise copy, but now cp_expr_size will abort if we
- try to do that. */
- warning ("cannot pass objects of non-POD type `%#T' through `...'; \
-call will abort at runtime",
- TREE_TYPE (arg));
+ try to do that.
+ 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)
+ warning ("cannot pass objects of non-POD type `%#T' through `...'; "
+ "call will abort at runtime", TREE_TYPE (arg));
arg = call_builtin_trap ();
+ arg = build (COMPOUND_EXPR, integer_type_node, arg,
+ integer_zero_node);
}
return arg;
@@ -4325,9 +4188,7 @@ call will abort at runtime",
/* va_arg (EXPR, TYPE) is a builtin. Make sure it is not abused. */
tree
-build_x_va_arg (expr, type)
- tree expr;
- tree type;
+build_x_va_arg (tree expr, tree type)
{
if (processing_template_decl)
return build_min (VA_ARG_EXPR, type, expr);
@@ -4340,8 +4201,14 @@ build_x_va_arg (expr, type)
if (! pod_type_p (type))
{
/* Undefined behavior [expr.call] 5.2.2/7. */
- warning ("cannot receive objects of non-POD type `%#T' through `...'",
- type);
+ warning ("cannot receive objects of non-POD type `%#T' through `...'; \
+call will abort at runtime",
+ type);
+ expr = convert (build_pointer_type (type), null_node);
+ expr = build (COMPOUND_EXPR, TREE_TYPE (expr),
+ call_builtin_trap (), expr);
+ expr = build_indirect_ref (expr, NULL);
+ return expr;
}
return build_va_arg (expr, type);
@@ -4352,16 +4219,13 @@ build_x_va_arg (expr, type)
type, or the passed type if there is no change. */
tree
-cxx_type_promotes_to (type)
- tree type;
+cxx_type_promotes_to (tree type)
{
tree promote;
- if (TREE_CODE (type) == ARRAY_TYPE)
- return build_pointer_type (TREE_TYPE (type));
-
- if (TREE_CODE (type) == FUNCTION_TYPE)
- return build_pointer_type (type);
+ /* Perform the array-to-pointer and function-to-pointer
+ conversions. */
+ type = type_decays_to (type);
promote = type_promotes_to (type);
if (same_type_p (type, promote))
@@ -4375,30 +4239,16 @@ cxx_type_promotes_to (type)
conversions. Return the converted value. */
tree
-convert_default_arg (type, arg, fn, parmnum)
- tree type;
- tree arg;
- tree fn;
- int parmnum;
+convert_default_arg (tree type, tree arg, tree fn, int parmnum)
{
+ /* If the ARG is an unparsed default argument expression, the
+ conversion cannot be performed. */
if (TREE_CODE (arg) == DEFAULT_ARG)
{
- /* When processing the default args for a class, we can find that
- there is an ordering constraint, and we call a function who's
- default args have not yet been converted. For instance,
- class A {
- A (int = 0);
- void Foo (A const & = A ());
- };
- We must process A::A before A::Foo's default arg can be converted.
- Remember the dependent function, so do_pending_defargs can retry,
- and check loops. */
- unprocessed_defarg_fn (fn);
-
- /* Don't return error_mark node, as we won't be able to distinguish
- genuine errors from this case, and that would lead to repeated
- diagnostics. Just make something of the right type. */
- return build1 (NOP_EXPR, type, integer_zero_node);
+ error ("the default argument for parameter %d of `%D' has "
+ "not yet been parsed",
+ parmnum, fn);
+ return error_mark_node;
}
if (fn && DECL_TEMPLATE_INFO (fn))
@@ -4430,15 +4280,16 @@ convert_default_arg (type, arg, fn, parmnum)
type TYPE. */
tree
-type_passed_as (type)
- tree type;
+type_passed_as (tree type)
{
/* Pass classes with copy ctors by invisible reference. */
if (TREE_ADDRESSABLE (type))
type = build_reference_type (type);
else if (PROMOTE_PROTOTYPES
&& INTEGRAL_TYPE_P (type)
- && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
+ && COMPLETE_TYPE_P (type)
+ && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
+ TYPE_SIZE (integer_type_node)))
type = integer_type_node;
return type;
@@ -4447,8 +4298,7 @@ type_passed_as (type)
/* Actually perform the appropriate conversion. */
tree
-convert_for_arg_passing (type, val)
- tree type, val;
+convert_for_arg_passing (tree type, tree val)
{
if (val == error_mark_node)
;
@@ -4457,23 +4307,46 @@ convert_for_arg_passing (type, val)
val = build1 (ADDR_EXPR, build_reference_type (type), val);
else if (PROMOTE_PROTOTYPES
&& INTEGRAL_TYPE_P (type)
- && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
- val = default_conversion (val);
+ && COMPLETE_TYPE_P (type)
+ && INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
+ TYPE_SIZE (integer_type_node)))
+ val = perform_integral_promotions (val);
return val;
}
+/* Returns true iff FN is a function with magic varargs, i.e. ones for
+ which no conversions at all should be done. This is true for some
+ builtins which don't act like normal functions. */
+
+static bool
+magic_varargs_p (tree fn)
+{
+ if (DECL_BUILT_IN (fn))
+ switch (DECL_FUNCTION_CODE (fn))
+ {
+ case BUILT_IN_CLASSIFY_TYPE:
+ case BUILT_IN_CONSTANT_P:
+ case BUILT_IN_NEXT_ARG:
+ case BUILT_IN_STDARG_START:
+ case BUILT_IN_VA_START:
+ return true;
+
+ default:;
+ }
+
+ return false;
+}
+
/* Subroutine of the various build_*_call functions. Overload resolution
has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a
bitmask of various LOOKUP_* flags which apply to the call itself. */
static tree
-build_over_call (cand, args, flags)
- struct z_candidate *cand;
- tree args;
- int flags;
+build_over_call (struct z_candidate *cand, int flags)
{
tree fn = cand->fn;
+ tree args = cand->args;
tree convs = cand->convs;
tree converted_args = NULL_TREE;
tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
@@ -4481,13 +4354,62 @@ build_over_call (cand, args, flags)
int i = 0;
int is_method = 0;
+ /* In a template, there is no need to perform all of the work that
+ is normally done. We are only interested in the type of the call
+ expression, i.e., the return type of the function. Any semantic
+ errors will be deferred until the template is instantiated. */
+ if (processing_template_decl)
+ {
+ tree expr;
+ tree return_type;
+ return_type = TREE_TYPE (TREE_TYPE (fn));
+ expr = build (CALL_EXPR, return_type, fn, args);
+ if (TREE_THIS_VOLATILE (fn) && cfun)
+ current_function_returns_abnormally = 1;
+ if (!VOID_TYPE_P (return_type))
+ require_complete_type (return_type);
+ return convert_from_reference (expr);
+ }
+
/* Give any warnings we noticed during overload resolution. */
if (cand->warnings)
for (val = cand->warnings; val; val = TREE_CHAIN (val))
joust (cand, WRAPPER_ZC (TREE_VALUE (val)), 1);
if (DECL_FUNCTION_MEMBER_P (fn))
- enforce_access (cand->access_path, fn);
+ {
+ /* If FN is a template function, two cases must be considered.
+ For example:
+
+ struct A {
+ protected:
+ template <class T> void f();
+ };
+ template <class T> struct B {
+ protected:
+ void g();
+ };
+ struct C : A, B<int> {
+ using A::f; // #1
+ using B<int>::g; // #2
+ };
+
+ In case #1 where `A::f' is a member template, DECL_ACCESS is
+ recorded in the primary template but not in its specialization.
+ We check access of FN using its primary template.
+
+ In case #2, where `B<int>::g' has a DECL_TEMPLATE_INFO simply
+ because it is a member of class template B, DECL_ACCESS is
+ recorded in the specialization `B<int>::g'. We cannot use its
+ primary template because `B<T>::g' and `B<int>::g' may have
+ different access. */
+ if (DECL_TEMPLATE_INFO (fn)
+ && is_member_template (DECL_TI_TEMPLATE (fn)))
+ perform_or_defer_access_check (cand->access_path,
+ DECL_TI_TEMPLATE (fn));
+ else
+ perform_or_defer_access_check (cand->access_path, fn);
+ }
if (args && TREE_CODE (args) != TREE_LIST)
args = build_tree_list (NULL_TREE, args);
@@ -4581,10 +4503,14 @@ build_over_call (cand, args, flags)
/* Ellipsis */
for (; arg; arg = TREE_CHAIN (arg))
- converted_args
- = tree_cons (NULL_TREE,
- convert_arg_to_ellipsis (TREE_VALUE (arg)),
- converted_args);
+ {
+ tree a = TREE_VALUE (arg);
+ if (magic_varargs_p (fn))
+ /* Do no conversions for magic varargs. */;
+ else
+ a = convert_arg_to_ellipsis (a);
+ converted_args = tree_cons (NULL_TREE, a, converted_args);
+ }
converted_args = nreverse (converted_args);
@@ -4645,16 +4571,11 @@ build_over_call (cand, args, flags)
else if (TREE_CODE (arg) == TARGET_EXPR
|| TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
{
- tree address;
tree to = stabilize_reference
(build_indirect_ref (TREE_VALUE (args), 0));
val = build (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
- address = build_unary_op (ADDR_EXPR, val, 0);
- /* Avoid a warning about this expression, if the address is
- never used. */
- TREE_USED (address) = 1;
- return address;
+ return val;
}
}
else if (DECL_OVERLOADED_OPERATOR_P (fn) == NOP_EXPR
@@ -4663,9 +4584,36 @@ build_over_call (cand, args, flags)
{
tree to = stabilize_reference
(build_indirect_ref (TREE_VALUE (converted_args), 0));
+ tree type = TREE_TYPE (to);
+ tree as_base = CLASSTYPE_AS_BASE (type);
arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0);
- val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
+ if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
+ val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg);
+ else
+ {
+ /* We must only copy the non-tail padding parts. Use
+ CLASSTYPE_AS_BASE for the bitwise copy. */
+ tree to_ptr, arg_ptr, to_as_base, arg_as_base, base_ptr_type;
+ tree save_to;
+
+ to_ptr = save_expr (build_unary_op (ADDR_EXPR, to, 0));
+ arg_ptr = build_unary_op (ADDR_EXPR, arg, 0);
+
+ base_ptr_type = build_pointer_type (as_base);
+ to_as_base = build_nop (base_ptr_type, to_ptr);
+ to_as_base = build_indirect_ref (to_as_base, 0);
+ arg_as_base = build_nop (base_ptr_type, arg_ptr);
+ arg_as_base = build_indirect_ref (arg_as_base, 0);
+
+ save_to = build_indirect_ref (to_ptr, 0);
+
+ val = build (MODIFY_EXPR, as_base, to_as_base, arg_as_base);
+ val = convert_to_void (val, NULL);
+ val = build (COMPOUND_EXPR, type, val, save_to);
+ TREE_NO_UNUSED_WARNING (val) = 1;
+ }
+
return val;
}
@@ -4752,8 +4700,7 @@ static GTY(()) tree java_iface_lookup_fn;
_Jv_LookupInterfaceMethodIdx(). */
static tree
-build_java_interface_fn_ref (fn, instance)
- tree fn, instance;
+build_java_interface_fn_ref (tree fn, tree instance)
{
tree lookup_args, lookup_fn, method, idx;
tree klass_ref, iface, iface_ref;
@@ -4779,7 +4726,7 @@ build_java_interface_fn_ref (fn, instance)
/* Get the java.lang.Class pointer for the interface being called. */
iface = DECL_CONTEXT (fn);
- iface_ref = lookup_field (iface, get_identifier ("class$"), 0, 0);
+ iface_ref = lookup_field (iface, get_identifier ("class$"), 0, false);
if (!iface_ref || TREE_CODE (iface_ref) != VAR_DECL
|| DECL_CONTEXT (iface_ref) != iface)
{
@@ -4814,8 +4761,7 @@ build_java_interface_fn_ref (fn, instance)
call to a function with the indicated NAME. */
tree
-in_charge_arg_for_name (name)
- tree name;
+in_charge_arg_for_name (tree name)
{
if (name == base_ctor_identifier
|| name == base_dtor_identifier)
@@ -4878,14 +4824,23 @@ build_special_member_call (tree instance, tree name, tree args,
|| name == deleting_dtor_identifier)
my_friendly_assert (args == NULL_TREE, 20020712);
- /* We must perform the conversion here so that we do not
- subsequently check to see whether BINFO is an accessible
- base. (It is OK for a constructor to call a constructor in
- an inaccessible base as long as the constructor being called
- is accessible.) */
+ /* Convert to the base class, if necessary. */
if (!same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (instance), BINFO_TYPE (binfo)))
- instance = convert_to_base_statically (instance, binfo);
+ {
+ if (name != ansi_assopname (NOP_EXPR))
+ /* For constructors and destructors, either the base is
+ non-virtual, or it is virtual but we are doing the
+ conversion from a constructor or destructor for the
+ complete object. In either case, we can convert
+ statically. */
+ instance = convert_to_base_statically (instance, binfo);
+ else
+ /* However, for assignment operators, we must convert
+ dynamically if the base is virtual. */
+ instance = build_base_path (PLUS_EXPR, instance,
+ binfo, /*nonnull=*/1);
+ }
}
my_friendly_assert (instance != NULL_TREE, 20020712);
@@ -4916,8 +4871,6 @@ build_special_member_call (tree instance, tree name, tree args,
current_in_charge_parm, integer_zero_node),
current_vtt_parm,
vtt);
- if (TREE_VIA_VIRTUAL (binfo))
- binfo = binfo_for_vbase (class_type, current_class_type);
my_friendly_assert (BINFO_SUBVTT_INDEX (binfo), 20010110);
sub_vtt = build (PLUS_EXPR, TREE_TYPE (vtt), vtt,
BINFO_SUBVTT_INDEX (binfo));
@@ -4930,6 +4883,51 @@ build_special_member_call (tree instance, tree name, tree args,
flags);
}
+/* Return the NAME, as a C string. The NAME indicates a function that
+ is a member of TYPE. *FREE_P is set to true if the caller must
+ free the memory returned.
+
+ Rather than go through all of this, we should simply set the names
+ of constructors and destructors appropriately, and dispense with
+ ctor_identifier, dtor_identifier, etc. */
+
+static char *
+name_as_c_string (tree name, tree type, bool *free_p)
+{
+ char *pretty_name;
+
+ /* Assume that we will not allocate memory. */
+ *free_p = false;
+ /* Constructors and destructors are special. */
+ if (IDENTIFIER_CTOR_OR_DTOR_P (name))
+ {
+ pretty_name
+ = (char *) IDENTIFIER_POINTER (constructor_name (type));
+ /* For a destructor, add the '~'. */
+ if (name == complete_dtor_identifier
+ || name == base_dtor_identifier
+ || name == deleting_dtor_identifier)
+ {
+ pretty_name = concat ("~", pretty_name, NULL);
+ /* Remember that we need to free the memory allocated. */
+ *free_p = true;
+ }
+ }
+ else if (IDENTIFIER_TYPENAME_P (name))
+ {
+ pretty_name = concat ("operator ",
+ type_as_string (TREE_TYPE (name),
+ TFF_PLAIN_IDENTIFIER),
+ NULL);
+ /* Remember that we need to free the memory allocated. */
+ *free_p = true;
+ }
+ else
+ pretty_name = (char *) IDENTIFIER_POINTER (name);
+
+ return pretty_name;
+}
+
/* Build a call to "INSTANCE.FN (ARGS)". */
tree
@@ -4942,25 +4940,44 @@ build_new_method_call (tree instance, tree fns, tree args,
tree access_binfo;
tree optype;
tree mem_args = NULL_TREE, instance_ptr;
- tree name, pretty_name;
+ tree name;
tree user_args;
tree call;
+ tree fn;
+ tree class_type;
int template_only = 0;
+ bool any_viable_p;
+ tree orig_instance;
+ tree orig_fns;
+ tree orig_args;
my_friendly_assert (instance != NULL_TREE, 20020729);
- if (instance == error_mark_node || fns == error_mark_node
+ if (error_operand_p (instance)
+ || error_operand_p (fns)
|| args == error_mark_node)
return error_mark_node;
+ orig_instance = instance;
+ orig_fns = fns;
+ orig_args = args;
+
+ if (processing_template_decl)
+ {
+ instance = build_non_dependent_expr (instance);
+ if (!BASELINK_P (fns)
+ && TREE_CODE (fns) != PSEUDO_DTOR_EXPR
+ && TREE_TYPE (fns) != unknown_type_node)
+ fns = build_non_dependent_expr (fns);
+ args = build_non_dependent_args (orig_args);
+ }
+
/* Process the argument list. */
user_args = args;
args = resolve_args (args);
if (args == error_mark_node)
return error_mark_node;
- if (TREE_CODE (instance) == OFFSET_REF)
- instance = resolve_offset_ref (instance);
if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE)
instance = convert_from_reference (instance);
basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance));
@@ -4968,9 +4985,6 @@ build_new_method_call (tree instance, tree fns, tree args,
if (!BASELINK_P (fns))
{
- call = build_field_call (instance_ptr, fns, args);
- if (call)
- return call;
error ("call to non-function `%D'", fns);
return error_mark_node;
}
@@ -5003,7 +5017,8 @@ build_new_method_call (tree instance, tree fns, tree args,
return error_mark_node;
}
- name = DECL_NAME (get_first_fn (fns));
+ fn = get_first_fn (fns);
+ name = DECL_NAME (fn);
if (IDENTIFIER_CTOR_OR_DTOR_P (name))
{
@@ -5012,60 +5027,56 @@ build_new_method_call (tree instance, tree fns, tree args,
my_friendly_assert (name != ctor_identifier, 20000408);
/* Similarly for destructors. */
my_friendly_assert (name != dtor_identifier, 20000408);
-
- if (name == complete_ctor_identifier
- || name == base_ctor_identifier)
- pretty_name = constructor_name (basetype);
- else
- pretty_name = dtor_identifier;
}
- else
- pretty_name = name;
- if (fns)
+ /* It's OK to call destructors on cv-qualified objects. Therefore,
+ convert the INSTANCE_PTR to the unqualified type, if necessary. */
+ if (DECL_DESTRUCTOR_P (fn))
{
- tree fn;
- tree class_type = (conversion_path
- ? BINFO_TYPE (conversion_path)
- : NULL_TREE);
+ tree type = build_pointer_type (basetype);
+ if (!same_type_p (type, TREE_TYPE (instance_ptr)))
+ instance_ptr = build_nop (type, instance_ptr);
+ }
- mem_args = tree_cons (NULL_TREE, instance_ptr, args);
- for (fn = fns; fn; fn = OVL_NEXT (fn))
- {
- tree t = OVL_CURRENT (fn);
- tree this_arglist;
+ class_type = (conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE);
+ mem_args = tree_cons (NULL_TREE, instance_ptr, args);
- /* We can end up here for copy-init of same or base class. */
- if ((flags & LOOKUP_ONLYCONVERTING)
- && DECL_NONCONVERTING_P (t))
- continue;
+ for (fn = fns; fn; fn = OVL_NEXT (fn))
+ {
+ tree t = OVL_CURRENT (fn);
+ tree this_arglist;
- if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
- this_arglist = mem_args;
- else
- this_arglist = args;
-
- if (TREE_CODE (t) == TEMPLATE_DECL)
- /* A member template. */
- add_template_candidate (&candidates, t,
- class_type,
- explicit_targs,
- this_arglist, optype,
- access_binfo,
- conversion_path,
- flags,
- DEDUCE_CALL);
- else if (! template_only)
- add_function_candidate (&candidates, t,
- class_type,
- this_arglist,
- access_binfo,
- conversion_path,
- flags);
- }
+ /* We can end up here for copy-init of same or base class. */
+ if ((flags & LOOKUP_ONLYCONVERTING)
+ && DECL_NONCONVERTING_P (t))
+ continue;
+
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
+ this_arglist = mem_args;
+ else
+ this_arglist = args;
+
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ /* A member template. */
+ add_template_candidate (&candidates, t,
+ class_type,
+ explicit_targs,
+ this_arglist, optype,
+ access_binfo,
+ conversion_path,
+ flags,
+ DEDUCE_CALL);
+ else if (! template_only)
+ add_function_candidate (&candidates, t,
+ class_type,
+ this_arglist,
+ access_binfo,
+ conversion_path,
+ flags);
}
- if (! any_viable (candidates))
+ candidates = splice_viable (candidates, pedantic, &any_viable_p);
+ if (!any_viable_p)
{
/* XXX will LOOKUP_SPECULATIVELY be needed when this is done? */
if (flags & LOOKUP_SPECULATIVELY)
@@ -5073,20 +5084,33 @@ build_new_method_call (tree instance, tree fns, tree args,
if (!COMPLETE_TYPE_P (basetype))
cxx_incomplete_type_error (instance_ptr, basetype);
else
- error ("no matching function for call to `%T::%D(%A)%#V'",
- basetype, pretty_name, user_args,
- TREE_TYPE (TREE_TYPE (instance_ptr)));
+ {
+ char *pretty_name;
+ bool free_p;
+
+ pretty_name = name_as_c_string (name, basetype, &free_p);
+ error ("no matching function for call to `%T::%s(%A)%#V'",
+ basetype, pretty_name, user_args,
+ TREE_TYPE (TREE_TYPE (instance_ptr)));
+ if (free_p)
+ free (pretty_name);
+ }
print_z_candidates (candidates);
return error_mark_node;
}
- candidates = splice_viable (candidates);
- cand = tourney (candidates);
+ cand = tourney (candidates);
if (cand == 0)
{
- error ("call of overloaded `%D(%A)' is ambiguous", pretty_name,
- user_args);
+ char *pretty_name;
+ bool free_p;
+
+ pretty_name = name_as_c_string (name, basetype, &free_p);
+ error ("call of overloaded `%s(%A)' is ambiguous", pretty_name,
+ user_args);
print_z_candidates (candidates);
+ if (free_p)
+ free (pretty_name);
return error_mark_node;
}
@@ -5112,25 +5136,29 @@ build_new_method_call (tree instance, tree fns, tree args,
flags |= LOOKUP_NONVIRTUAL;
if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE)
- call = build_over_call (cand, mem_args, flags);
+ call = build_over_call (cand, flags);
else
{
- call = build_over_call (cand, args, flags);
+ call = build_over_call (cand, flags);
/* In an expression of the form `a->f()' where `f' turns out to
be a static member function, `a' is none-the-less evaluated. */
- if (instance && TREE_SIDE_EFFECTS (instance))
+ if (!is_dummy_object (instance_ptr) && TREE_SIDE_EFFECTS (instance))
call = build (COMPOUND_EXPR, TREE_TYPE (call), instance, call);
}
-
+
+ if (processing_template_decl && call != error_mark_node)
+ return build_min_non_dep
+ (CALL_EXPR, call,
+ build_min_nt (COMPONENT_REF, orig_instance, orig_fns),
+ orig_args);
return call;
}
-/* Returns nonzero iff standard conversion sequence ICS1 is a proper
+/* Returns true iff standard conversion sequence ICS1 is a proper
subsequence of ICS2. */
-static int
-is_subseq (ics1, ics2)
- tree ics1, ics2;
+static bool
+is_subseq (tree ics1, tree ics2)
{
/* We can assume that a conversion of the same code
between the same types indicates a subsequence since we only get
@@ -5153,7 +5181,7 @@ is_subseq (ics1, ics2)
ICS2. We can get a USER_CONV when we are comparing the
second standard conversion sequence of two user conversion
sequences. */
- return 0;
+ return false;
ics2 = TREE_OPERAND (ics2, 0);
@@ -5161,21 +5189,19 @@ is_subseq (ics1, ics2)
&& same_type_p (TREE_TYPE (ics2), TREE_TYPE (ics1))
&& same_type_p (TREE_TYPE (TREE_OPERAND (ics2, 0)),
TREE_TYPE (TREE_OPERAND (ics1, 0))))
- return 1;
+ return true;
}
}
/* Returns nonzero iff DERIVED is derived from BASE. The inputs may
be any _TYPE nodes. */
-int
-is_properly_derived_from (derived, base)
- tree derived;
- tree base;
+bool
+is_properly_derived_from (tree derived, tree base)
{
if (!IS_AGGR_TYPE_CODE (TREE_CODE (derived))
|| !IS_AGGR_TYPE_CODE (TREE_CODE (base)))
- return 0;
+ return false;
/* We only allow proper derivation here. The DERIVED_FROM_P macro
considers every class derived from itself. */
@@ -5190,8 +5216,7 @@ is_properly_derived_from (derived, base)
modify it accordingly. */
static void
-maybe_handle_implicit_object (ics)
- tree* ics;
+maybe_handle_implicit_object (tree *ics)
{
if (ICS_THIS_FLAG (*ics))
{
@@ -5206,7 +5231,7 @@ maybe_handle_implicit_object (ics)
tree reference_type;
/* The `this' parameter is a pointer to a class type. Make the
- implict conversion talk about a reference to that same class
+ implicit conversion talk about a reference to that same class
type. */
reference_type = TREE_TYPE (TREE_TYPE (*ics));
reference_type = build_reference_type (reference_type);
@@ -5226,8 +5251,7 @@ maybe_handle_implicit_object (ics)
leave *ICS unchanged and return NULL_TREE. */
static tree
-maybe_handle_ref_bind (ics)
- tree* ics;
+maybe_handle_ref_bind (tree *ics)
{
if (TREE_CODE (*ics) == REF_BIND)
{
@@ -5250,8 +5274,7 @@ maybe_handle_ref_bind (ics)
0: ics1 and ics2 are indistinguishable */
static int
-compare_ics (ics1, ics2)
- tree ics1, ics2;
+compare_ics (tree ics1, tree ics2)
{
tree from_type1;
tree from_type2;
@@ -5301,7 +5324,7 @@ compare_ics (ics1, ics2)
{
/* XXX Isn't this an extension? */
/* Both ICS are bad. We try to make a decision based on what
- would have happenned if they'd been good. */
+ would have happened if they'd been good. */
if (ICS_USER_FLAG (ics1) > ICS_USER_FLAG (ics2)
|| ICS_STD_RANK (ics1) > ICS_STD_RANK (ics2))
return -1;
@@ -5421,25 +5444,17 @@ compare_ics (ics1, ics2)
for pointers A*, except opposite: if B is derived from A then
A::* converts to B::*, not vice versa. For that reason, we
switch the from_ and to_ variables here. */
- else if (TYPE_PTRMEM_P (from_type1)
- && TYPE_PTRMEM_P (from_type2)
- && TYPE_PTRMEM_P (to_type1)
- && TYPE_PTRMEM_P (to_type2))
+ else if ((TYPE_PTRMEM_P (from_type1) && TYPE_PTRMEM_P (from_type2)
+ && TYPE_PTRMEM_P (to_type1) && TYPE_PTRMEM_P (to_type2))
+ || (TYPE_PTRMEMFUNC_P (from_type1)
+ && TYPE_PTRMEMFUNC_P (from_type2)
+ && TYPE_PTRMEMFUNC_P (to_type1)
+ && TYPE_PTRMEMFUNC_P (to_type2)))
{
- deref_to_type1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (from_type1));
- deref_to_type2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (from_type2));
- deref_from_type1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (to_type1));
- deref_from_type2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (to_type2));
- }
- else if (TYPE_PTRMEMFUNC_P (from_type1)
- && TYPE_PTRMEMFUNC_P (from_type2)
- && TYPE_PTRMEMFUNC_P (to_type1)
- && TYPE_PTRMEMFUNC_P (to_type2))
- {
- deref_to_type1 = TYPE_PTRMEMFUNC_OBJECT_TYPE (from_type1);
- deref_to_type2 = TYPE_PTRMEMFUNC_OBJECT_TYPE (from_type2);
- deref_from_type1 = TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type1);
- deref_from_type2 = TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type2);
+ deref_to_type1 = TYPE_PTRMEM_CLASS_TYPE (from_type1);
+ deref_to_type2 = TYPE_PTRMEM_CLASS_TYPE (from_type2);
+ deref_from_type1 = TYPE_PTRMEM_CLASS_TYPE (to_type1);
+ deref_from_type2 = TYPE_PTRMEM_CLASS_TYPE (to_type2);
}
if (deref_from_type1 != NULL_TREE
@@ -5587,8 +5602,7 @@ compare_ics (ics1, ics2)
/* The source type for this standard conversion sequence. */
static tree
-source_type (t)
- tree t;
+source_type (tree t)
{
for (;; t = TREE_OPERAND (t, 0))
{
@@ -5605,8 +5619,7 @@ source_type (t)
is actually used. */
static void
-add_warning (winner, loser)
- struct z_candidate *winner, *loser;
+add_warning (struct z_candidate *winner, struct z_candidate *loser)
{
winner->warnings = tree_cons (NULL_TREE,
build_zc_wrapper (loser),
@@ -5621,9 +5634,7 @@ add_warning (winner, loser)
0: cand1 and cand2 are indistinguishable */
static int
-joust (cand1, cand2, warn)
- struct z_candidate *cand1, *cand2;
- int warn;
+joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn)
{
int winner = 0;
int i, off1 = 0, off2 = 0, len;
@@ -5721,45 +5732,52 @@ joust (cand1, cand2, warn)
/* warn about confusing overload resolution for user-defined conversions,
either between a constructor and a conversion op, or between two
conversion ops. */
- if (winner && cand1->second_conv
- && ((DECL_CONSTRUCTOR_P (cand1->fn)
- != DECL_CONSTRUCTOR_P (cand2->fn))
- /* Don't warn if the two conv ops convert to the same type... */
- || (! DECL_CONSTRUCTOR_P (cand1->fn)
- && ! same_type_p (TREE_TYPE (TREE_TYPE (cand1->fn)),
- TREE_TYPE (TREE_TYPE (cand2->fn))))))
- {
- int comp = compare_ics (cand1->second_conv, cand2->second_conv);
- if (comp != winner)
+ if (winner && warn_conversion && cand1->second_conv
+ && (!DECL_CONSTRUCTOR_P (cand1->fn) || !DECL_CONSTRUCTOR_P (cand2->fn))
+ && winner != compare_ics (cand1->second_conv, cand2->second_conv))
+ {
+ struct z_candidate *w, *l;
+ bool give_warning = false;
+
+ if (winner == 1)
+ w = cand1, l = cand2;
+ else
+ w = cand2, l = cand1;
+
+ /* We don't want to complain about `X::operator T1 ()'
+ beating `X::operator T2 () const', when T2 is a no less
+ cv-qualified version of T1. */
+ if (DECL_CONTEXT (w->fn) == DECL_CONTEXT (l->fn)
+ && !DECL_CONSTRUCTOR_P (w->fn) && !DECL_CONSTRUCTOR_P (l->fn))
{
- struct z_candidate *w, *l;
- tree convn;
- if (winner == 1)
- w = cand1, l = cand2;
- else
- w = cand2, l = cand1;
- if (DECL_CONTEXT (cand1->fn) == DECL_CONTEXT (cand2->fn)
- && ! DECL_CONSTRUCTOR_P (cand1->fn)
- && ! DECL_CONSTRUCTOR_P (cand2->fn)
- && (convn = standard_conversion
- (TREE_TYPE (TREE_TYPE (l->fn)),
- TREE_TYPE (TREE_TYPE (w->fn)), NULL_TREE))
- && TREE_CODE (convn) == QUAL_CONV)
- /* Don't complain about `operator char *()' beating
- `operator const char *() const'. */;
- else if (warn && warn_conversion)
+ tree t = TREE_TYPE (TREE_TYPE (l->fn));
+ tree f = TREE_TYPE (TREE_TYPE (w->fn));
+
+ if (TREE_CODE (t) == TREE_CODE (f) && POINTER_TYPE_P (t))
{
- tree source = source_type (TREE_VEC_ELT (w->convs, 0));
- if (! DECL_CONSTRUCTOR_P (w->fn))
- source = TREE_TYPE (source);
- warning ("choosing `%D' over `%D'", w->fn, l->fn);
- warning (" for conversion from `%T' to `%T'",
- source, TREE_TYPE (w->second_conv));
- warning (" because conversion sequence for the argument is better");
+ t = TREE_TYPE (t);
+ f = TREE_TYPE (f);
}
- else
- add_warning (w, l);
+ if (!comp_ptr_ttypes (t, f))
+ give_warning = true;
}
+ else
+ give_warning = true;
+
+ if (!give_warning)
+ /*NOP*/;
+ else if (warn)
+ {
+ tree source = source_type (TREE_VEC_ELT (w->convs, 0));
+ if (! DECL_CONSTRUCTOR_P (w->fn))
+ source = TREE_TYPE (source);
+ warning ("choosing `%D' over `%D'", w->fn, l->fn);
+ warning (" for conversion from `%T' to `%T'",
+ source, TREE_TYPE (w->second_conv));
+ warning (" because conversion sequence for the argument is better");
+ }
+ else
+ add_warning (w, l);
}
if (winner)
@@ -5795,7 +5813,6 @@ joust (cand1, cand2, warn)
TREE_VEC_LENGTH (cand1->convs)
- (DECL_NONSTATIC_MEMBER_FUNCTION_P (cand1->fn)
- DECL_CONSTRUCTOR_P (cand1->fn)));
- /* HERE */
if (winner)
return winner;
}
@@ -5852,7 +5869,7 @@ joust (cand1, cand2, warn)
if (DECL_P (cand1->fn) && DECL_P (cand2->fn)
&& equal_functions (cand1->fn, cand2->fn))
return 1;
-
+
tweak:
/* Extension: If the worst conversion for one candidate is worse than the
@@ -5876,9 +5893,14 @@ tweak:
if (winner)
{
if (warn)
- pedwarn ("ISO C++ says that `%D' and `%D' are ambiguous \
-even though the worst conversion for the former is better than the worst \
-conversion for the latter", w->fn, l->fn);
+ {
+ pedwarn ("\
+ISO C++ says that these are ambiguous, even \
+though the worst conversion for the first is better than \
+the worst conversion for the second:");
+ print_z_candidate (_("candidate 1:"), w);
+ print_z_candidate (_("candidate 2:"), l);
+ }
else
add_warning (w, l);
return winner;
@@ -5895,8 +5917,7 @@ conversion for the latter", w->fn, l->fn);
algorithm. */
static struct z_candidate *
-tourney (candidates)
- struct z_candidate *candidates;
+tourney (struct z_candidate *candidates)
{
struct z_candidate *champ = candidates, *challenger;
int fate;
@@ -5947,18 +5968,16 @@ tourney (candidates)
/* Returns nonzero if things of type FROM can be converted to TO. */
-int
-can_convert (to, from)
- tree to, from;
+bool
+can_convert (tree to, tree from)
{
return can_convert_arg (to, from, NULL_TREE);
}
/* Returns nonzero if ARG (of type FROM) can be converted to TO. */
-int
-can_convert_arg (to, from, arg)
- tree to, from, arg;
+bool
+can_convert_arg (tree to, tree from, tree arg)
{
tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL);
return (t && ! ICS_BAD_FLAG (t));
@@ -5966,12 +5985,10 @@ can_convert_arg (to, from, arg)
/* Like can_convert_arg, but allows dubious conversions as well. */
-int
-can_convert_arg_bad (to, from, arg)
- tree to, from, arg;
+bool
+can_convert_arg_bad (tree to, tree from, tree arg)
{
- tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL);
- return !!t;
+ return implicit_conversion (to, from, arg, LOOKUP_NORMAL) != 0;
}
/* Convert EXPR to TYPE. Return the converted expression.
@@ -5981,13 +5998,11 @@ can_convert_arg_bad (to, from, arg)
doing a bad conversion, convert_like will complain. */
tree
-perform_implicit_conversion (type, expr)
- tree type;
- tree expr;
+perform_implicit_conversion (tree type, tree expr)
{
tree conv;
- if (expr == error_mark_node)
+ if (error_operand_p (expr))
return error_mark_node;
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
LOOKUP_NORMAL);
@@ -6074,23 +6089,19 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type)
return var;
}
- /* Convert EXPR to the indicated reference TYPE, in a way suitable
- for initializing a variable of that TYPE. If DECL is non-NULL,
- it is the VAR_DECL being initialized with the EXPR. (In that
- case, the type of DECL will be TYPE.) If DECL is non-NULL, then
- CLEANUP must also be non-NULL, and with *CLEANUP initialized to
- NULL. Upon return, if *CLEANUP is no longer NULL, it will be a
- CLEANUP_STMT that should be inserted after the returned
- expression is used to initialize DECL.
+/* Convert EXPR to the indicated reference TYPE, in a way suitable for
+ initializing a variable of that TYPE. If DECL is non-NULL, it is
+ the VAR_DECL being initialized with the EXPR. (In that case, the
+ type of DECL will be TYPE.) If DECL is non-NULL, then CLEANUP must
+ also be non-NULL, and with *CLEANUP initialized to NULL. Upon
+ return, if *CLEANUP is no longer NULL, it will be a CLEANUP_STMT
+ that should be inserted after the returned expression is used to
+ initialize DECL.
- Return the converted expression. */
+ Return the converted expression. */
tree
-initialize_reference (type, expr, decl, cleanup)
- tree type;
- tree expr;
- tree decl;
- tree *cleanup;
+initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
{
tree conv;
@@ -6158,14 +6169,19 @@ initialize_reference (type, expr, decl, cleanup)
remember that the conversion was required. */
if (TREE_CODE (conv) == BASE_CONV && !NEED_TEMPORARY_P (conv))
{
+ if (CHECK_COPY_CONSTRUCTOR_P (conv))
+ check_constructor_callable (TREE_TYPE (expr), expr);
base_conv_type = TREE_TYPE (conv);
conv = TREE_OPERAND (conv, 0);
}
else
base_conv_type = NULL_TREE;
/* Perform the remainder of the conversion. */
- expr = convert_like (conv, expr);
- if (!real_non_cast_lvalue_p (expr))
+ expr = convert_like_real (conv, expr,
+ /*fn=*/NULL_TREE, /*argnum=*/0,
+ /*inner=*/-1,
+ /*issue_conversion_warnings=*/true);
+ if (!real_lvalue_p (expr))
{
tree init;
tree type;
@@ -6174,6 +6190,16 @@ initialize_reference (type, expr, decl, cleanup)
type = TREE_TYPE (expr);
var = make_temporary_var_for_ref_to_temp (decl, type);
layout_decl (var, 0);
+ /* If the rvalue is the result of a function call it will be
+ a TARGET_EXPR. If it is some other construct (such as a
+ member access expression where the underlying object is
+ itself the result of a function call), turn it into a
+ TARGET_EXPR here. It is important that EXPR be a
+ TARGET_EXPR below since otherwise the INIT_EXPR will
+ attempt to make a bitwise copy of EXPR to intialize
+ VAR. */
+ if (TREE_CODE (expr) != TARGET_EXPR)
+ expr = get_target_expr (expr);
/* Create the INIT_EXPR that will initialize the temporary
variable. */
init = build (INIT_EXPR, type, var, expr);
diff --git a/contrib/gcc/cp/cfns.gperf b/contrib/gcc/cp/cfns.gperf
index e0e9f235dd64..c713eb0c2bdd 100644
--- a/contrib/gcc/cp/cfns.gperf
+++ b/contrib/gcc/cp/cfns.gperf
@@ -2,12 +2,13 @@
#ifdef __GNUC__
__inline
#endif
-static unsigned int hash PARAMS ((const char *, unsigned int));
+static unsigned int hash (const char *, unsigned int);
#ifdef __GNUC__
__inline
#endif
-const char * libc_name_p PARAMS ((const char *, unsigned int));
+const char * libc_name_p (const char *, unsigned int);
%}
+%%
# The standard C library functions, for feeding to gperf; the result is used
# by nothrow_libfn_p.
#
diff --git a/contrib/gcc/cp/class.c b/contrib/gcc/cp/class.c
index f6e03963bedc..9fa7f2693699 100644
--- a/contrib/gcc/cp/class.c
+++ b/contrib/gcc/cp/class.c
@@ -1,22 +1,22 @@
/* Functions related to building classes and their related objects.
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,15 +25,17 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "flags.h"
#include "rtl.h"
#include "output.h"
#include "toplev.h"
-#include "ggc.h"
#include "lex.h"
#include "target.h"
+#include "convert.h"
/* The number of nested classes being processed. If we are not in the
scope of any class, this is zero. */
@@ -93,9 +95,9 @@ typedef struct vtbl_init_data_s
} vtbl_init_data;
/* The type of a function passed to walk_subobject_offsets. */
-typedef int (*subobject_offset_fn) PARAMS ((tree, tree, splay_tree));
+typedef int (*subobject_offset_fn) (tree, tree, splay_tree);
-/* The stack itself. This is an dynamically resized array. The
+/* The stack itself. This is a dynamically resized array. The
number of elements allocated is CURRENT_CLASS_STACK_SIZE. */
static int current_class_stack_size;
static class_stack_node_t current_class_stack;
@@ -104,113 +106,105 @@ static class_stack_node_t current_class_stack;
declaration order. */
varray_type local_classes;
-static tree get_vfield_name PARAMS ((tree));
-static void finish_struct_anon PARAMS ((tree));
-static tree get_vtable_name PARAMS ((tree));
-static tree get_basefndecls PARAMS ((tree, tree));
-static int build_primary_vtable PARAMS ((tree, tree));
-static int build_secondary_vtable PARAMS ((tree, tree));
-static void finish_vtbls PARAMS ((tree));
-static void modify_vtable_entry PARAMS ((tree, tree, tree, tree, tree *));
-static tree delete_duplicate_fields_1 PARAMS ((tree, tree));
-static void delete_duplicate_fields PARAMS ((tree));
-static void finish_struct_bits PARAMS ((tree));
-static int alter_access PARAMS ((tree, tree, tree));
-static void handle_using_decl PARAMS ((tree, tree));
-static void check_for_override PARAMS ((tree, tree));
-static tree dfs_modify_vtables PARAMS ((tree, void *));
-static tree modify_all_vtables PARAMS ((tree, tree));
-static void determine_primary_base PARAMS ((tree));
-static void finish_struct_methods PARAMS ((tree));
-static void maybe_warn_about_overly_private_class PARAMS ((tree));
-static int field_decl_cmp PARAMS ((const tree *, const tree *));
-static int method_name_cmp PARAMS ((const tree *, const tree *));
-static void add_implicitly_declared_members PARAMS ((tree, int, int, int));
-static tree fixed_type_or_null PARAMS ((tree, int *, int *));
-static tree resolve_address_of_overloaded_function PARAMS ((tree, tree,
- tsubst_flags_t,
- int, int, tree));
-static tree build_vtable_entry_ref PARAMS ((tree, tree, tree));
-static tree build_vtbl_ref_1 PARAMS ((tree, tree));
-static tree build_vtbl_initializer PARAMS ((tree, tree, tree, tree, int *));
-static int count_fields PARAMS ((tree));
-static int add_fields_to_vec PARAMS ((tree, tree, int));
-static void check_bitfield_decl PARAMS ((tree));
+static tree get_vfield_name (tree);
+static void finish_struct_anon (tree);
+static tree get_vtable_name (tree);
+static tree get_basefndecls (tree, tree);
+static int build_primary_vtable (tree, tree);
+static int build_secondary_vtable (tree);
+static void finish_vtbls (tree);
+static void modify_vtable_entry (tree, tree, tree, tree, tree *);
+static void finish_struct_bits (tree);
+static int alter_access (tree, tree, tree);
+static void handle_using_decl (tree, tree);
+static void check_for_override (tree, tree);
+static tree dfs_modify_vtables (tree, void *);
+static tree modify_all_vtables (tree, tree);
+static void determine_primary_base (tree);
+static void finish_struct_methods (tree);
+static void maybe_warn_about_overly_private_class (tree);
+static int method_name_cmp (const void *, const void *);
+static int resort_method_name_cmp (const void *, const void *);
+static void add_implicitly_declared_members (tree, int, int, int);
+static tree fixed_type_or_null (tree, int *, int *);
+static tree resolve_address_of_overloaded_function (tree, tree, tsubst_flags_t,
+ bool, tree);
+static tree build_vtbl_ref_1 (tree, tree);
+static tree build_vtbl_initializer (tree, tree, tree, tree, int *);
+static int count_fields (tree);
+static int add_fields_to_record_type (tree, struct sorted_fields_type*, int);
+static void check_bitfield_decl (tree);
static void check_field_decl (tree, tree, int *, int *, int *, int *);
static void check_field_decls (tree, tree *, int *, int *, int *);
static tree *build_base_field (record_layout_info, tree, splay_tree, tree *);
static void build_base_fields (record_layout_info, splay_tree, tree *);
-static void check_methods PARAMS ((tree));
-static void remove_zero_width_bit_fields PARAMS ((tree));
-static void check_bases PARAMS ((tree, int *, int *, int *));
+static void check_methods (tree);
+static void remove_zero_width_bit_fields (tree);
+static void check_bases (tree, int *, int *, int *);
static void check_bases_and_members (tree);
static tree create_vtable_ptr (tree, tree *);
static void include_empty_classes (record_layout_info);
static void layout_class_type (tree, tree *);
-static void fixup_pending_inline PARAMS ((tree));
-static void fixup_inline_methods PARAMS ((tree));
-static void set_primary_base PARAMS ((tree, tree));
-static void propagate_binfo_offsets PARAMS ((tree, tree, tree));
+static void fixup_pending_inline (tree);
+static void fixup_inline_methods (tree);
+static void set_primary_base (tree, tree);
+static void propagate_binfo_offsets (tree, tree);
static void layout_virtual_bases (record_layout_info, splay_tree);
-static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *));
-static void build_vbase_offset_vtbl_entries PARAMS ((tree, vtbl_init_data *));
-static void add_vcall_offset_vtbl_entries_r PARAMS ((tree, vtbl_init_data *));
-static void add_vcall_offset_vtbl_entries_1 PARAMS ((tree, vtbl_init_data *));
-static void build_vcall_offset_vtbl_entries PARAMS ((tree, vtbl_init_data *));
+static void build_vbase_offset_vtbl_entries (tree, vtbl_init_data *);
+static void add_vcall_offset_vtbl_entries_r (tree, vtbl_init_data *);
+static void add_vcall_offset_vtbl_entries_1 (tree, vtbl_init_data *);
+static void build_vcall_offset_vtbl_entries (tree, vtbl_init_data *);
static void add_vcall_offset (tree, tree, vtbl_init_data *);
-static void layout_vtable_decl PARAMS ((tree, int));
-static tree dfs_find_final_overrider PARAMS ((tree, void *));
-static tree find_final_overrider PARAMS ((tree, tree, tree));
-static int make_new_vtable PARAMS ((tree, tree));
-static int maybe_indent_hierarchy PARAMS ((FILE *, int, int));
-static void dump_class_hierarchy_r PARAMS ((FILE *, int, tree, tree, int));
-static void dump_class_hierarchy PARAMS ((tree));
-static void dump_array PARAMS ((FILE *, tree));
-static void dump_vtable PARAMS ((tree, tree, tree));
-static void dump_vtt PARAMS ((tree, tree));
-static tree build_vtable PARAMS ((tree, tree, tree));
-static void initialize_vtable PARAMS ((tree, tree));
-static void initialize_array PARAMS ((tree, tree));
-static void layout_nonempty_base_or_field PARAMS ((record_layout_info,
- tree, tree, splay_tree));
-static tree end_of_class PARAMS ((tree, int));
-static bool layout_empty_base PARAMS ((tree, tree, splay_tree, tree));
-static void accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree, tree));
-static tree dfs_accumulate_vtbl_inits PARAMS ((tree, tree, tree, tree,
- tree));
-static void build_rtti_vtbl_entries PARAMS ((tree, vtbl_init_data *));
-static void build_vcall_and_vbase_vtbl_entries PARAMS ((tree,
- vtbl_init_data *));
-static void force_canonical_binfo_r PARAMS ((tree, tree, tree, tree));
-static void force_canonical_binfo PARAMS ((tree, tree, tree, tree));
-static tree dfs_unshared_virtual_bases PARAMS ((tree, void *));
-static void mark_primary_bases PARAMS ((tree));
-static tree mark_primary_virtual_base PARAMS ((tree, tree));
-static void clone_constructors_and_destructors PARAMS ((tree));
-static tree build_clone PARAMS ((tree, tree));
-static void update_vtable_entry_for_fn PARAMS ((tree, tree, tree, tree *));
-static tree copy_virtuals PARAMS ((tree));
-static void build_ctor_vtbl_group PARAMS ((tree, tree));
-static void build_vtt PARAMS ((tree));
-static tree binfo_ctor_vtable PARAMS ((tree));
-static tree *build_vtt_inits PARAMS ((tree, tree, tree *, tree *));
-static tree dfs_build_secondary_vptr_vtt_inits PARAMS ((tree, void *));
-static tree dfs_ctor_vtable_bases_queue_p PARAMS ((tree, void *data));
-static tree dfs_fixup_binfo_vtbls PARAMS ((tree, void *));
-static tree get_original_base PARAMS ((tree, tree));
-static tree dfs_get_primary_binfo PARAMS ((tree, void*));
-static int record_subobject_offset PARAMS ((tree, tree, splay_tree));
-static int check_subobject_offset PARAMS ((tree, tree, splay_tree));
-static int walk_subobject_offsets PARAMS ((tree, subobject_offset_fn,
- tree, splay_tree, tree, int));
-static void record_subobject_offsets PARAMS ((tree, tree, splay_tree, int));
-static int layout_conflict_p PARAMS ((tree, tree, splay_tree, int));
-static int splay_tree_compare_integer_csts PARAMS ((splay_tree_key k1,
- splay_tree_key k2));
-static void warn_about_ambiguous_bases PARAMS ((tree));
-static bool type_requires_array_cookie PARAMS ((tree));
+static void layout_vtable_decl (tree, int);
+static tree dfs_find_final_overrider (tree, void *);
+static tree dfs_find_final_overrider_post (tree, void *);
+static tree dfs_find_final_overrider_q (tree, int, void *);
+static tree find_final_overrider (tree, tree, tree);
+static int make_new_vtable (tree, tree);
+static int maybe_indent_hierarchy (FILE *, int, int);
+static tree dump_class_hierarchy_r (FILE *, int, tree, tree, int);
+static void dump_class_hierarchy (tree);
+static void dump_class_hierarchy_1 (FILE *, int, tree);
+static void dump_array (FILE *, tree);
+static void dump_vtable (tree, tree, tree);
+static void dump_vtt (tree, tree);
+static void dump_thunk (FILE *, int, tree);
+static tree build_vtable (tree, tree, tree);
+static void initialize_vtable (tree, tree);
+static void initialize_array (tree, tree);
+static void layout_nonempty_base_or_field (record_layout_info,
+ tree, tree, splay_tree);
+static tree end_of_class (tree, int);
+static bool layout_empty_base (tree, tree, splay_tree);
+static void accumulate_vtbl_inits (tree, tree, tree, tree, tree);
+static tree dfs_accumulate_vtbl_inits (tree, tree, tree, tree,
+ tree);
+static void build_rtti_vtbl_entries (tree, vtbl_init_data *);
+static void build_vcall_and_vbase_vtbl_entries (tree,
+ vtbl_init_data *);
+static void mark_primary_bases (tree);
+static void clone_constructors_and_destructors (tree);
+static tree build_clone (tree, tree);
+static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned);
+static tree copy_virtuals (tree);
+static void build_ctor_vtbl_group (tree, tree);
+static void build_vtt (tree);
+static tree binfo_ctor_vtable (tree);
+static tree *build_vtt_inits (tree, tree, tree *, tree *);
+static tree dfs_build_secondary_vptr_vtt_inits (tree, void *);
+static tree dfs_ctor_vtable_bases_queue_p (tree, int, void *data);
+static tree dfs_fixup_binfo_vtbls (tree, void *);
+static int record_subobject_offset (tree, tree, splay_tree);
+static int check_subobject_offset (tree, tree, splay_tree);
+static int walk_subobject_offsets (tree, subobject_offset_fn,
+ tree, splay_tree, tree, int);
+static void record_subobject_offsets (tree, tree, splay_tree, int);
+static int layout_conflict_p (tree, tree, splay_tree, int);
+static int splay_tree_compare_integer_csts (splay_tree_key k1,
+ splay_tree_key k2);
+static void warn_about_ambiguous_bases (tree);
+static bool type_requires_array_cookie (tree);
static bool contains_empty_class_p (tree);
-static tree dfs_base_derived_from (tree, void *);
static bool base_derived_from (tree, tree);
static int empty_base_at_nonzero_offset_p (tree, tree, splay_tree);
static tree end_of_base (tree);
@@ -231,7 +225,6 @@ int n_vtable_searches = 0;
int n_vtable_elems = 0;
int n_convert_harshness = 0;
int n_compute_conversion_costs = 0;
-int n_build_method_call = 0;
int n_inner_fields_searched = 0;
#endif
@@ -246,11 +239,10 @@ int n_inner_fields_searched = 0;
from EXPR. */
tree
-build_base_path (code, expr, binfo, nonnull)
- enum tree_code code;
- tree expr;
- tree binfo;
- int nonnull;
+build_base_path (enum tree_code code,
+ tree expr,
+ tree binfo,
+ int nonnull)
{
tree v_binfo = NULL_TREE;
tree d_binfo = NULL_TREE;
@@ -313,10 +305,7 @@ build_base_path (code, expr, binfo, nonnull)
{
/* In a base member initializer, we cannot rely on
the vtable being set up. We have to use the vtt_parm. */
- tree derived = v_binfo;
-
- while (BINFO_INHERITANCE_CHAIN (derived))
- derived = BINFO_INHERITANCE_CHAIN (derived);
+ tree derived = BINFO_INHERITANCE_CHAIN (v_binfo);
v_offset = build (PLUS_EXPR, TREE_TYPE (current_vtt_parm),
current_vtt_parm, BINFO_VPTR_INDEX (derived));
@@ -324,23 +313,22 @@ build_base_path (code, expr, binfo, nonnull)
v_offset = build1 (INDIRECT_REF,
TREE_TYPE (TYPE_VFIELD (BINFO_TYPE (derived))),
v_offset);
+
}
else
v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
TREE_TYPE (TREE_TYPE (expr)));
- v_binfo = binfo_for_vbase (BINFO_TYPE (v_binfo), BINFO_TYPE (d_binfo));
-
v_offset = build (PLUS_EXPR, TREE_TYPE (v_offset),
v_offset, BINFO_VPTR_FIELD (v_binfo));
v_offset = build1 (NOP_EXPR,
build_pointer_type (ptrdiff_type_node),
v_offset);
v_offset = build_indirect_ref (v_offset, NULL);
- TREE_CONSTANT (v_offset) = 1;
- offset = cp_convert (ptrdiff_type_node,
- size_diffop (offset, BINFO_OFFSET (v_binfo)));
+ offset = convert_to_integer (ptrdiff_type_node,
+ size_diffop (offset,
+ BINFO_OFFSET (v_binfo)));
if (!integer_zerop (offset))
v_offset = build (code, ptrdiff_type_node, v_offset, offset);
@@ -430,43 +418,13 @@ convert_to_base_statically (tree expr, tree base)
}
-/* Virtual function things. */
-
-static tree
-build_vtable_entry_ref (array_ref, instance, idx)
- tree array_ref, instance, idx;
-{
- tree i, i2, vtable, first_fn, basetype;
-
- basetype = TREE_TYPE (instance);
- if (TREE_CODE (basetype) == REFERENCE_TYPE)
- basetype = TREE_TYPE (basetype);
-
- vtable = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
- first_fn = TYPE_BINFO_VTABLE (basetype);
-
- i = fold (build_array_ref (first_fn, idx));
- i = fold (build_c_cast (ptrdiff_type_node,
- build_unary_op (ADDR_EXPR, i, 0)));
- i2 = fold (build_array_ref (vtable, build_int_2 (0,0)));
- i2 = fold (build_c_cast (ptrdiff_type_node,
- build_unary_op (ADDR_EXPR, i2, 0)));
- i = fold (cp_build_binary_op (MINUS_EXPR, i, i2));
-
- if (TREE_CODE (i) != INTEGER_CST)
- abort ();
-
- return build (VTABLE_REF, TREE_TYPE (array_ref), array_ref, vtable, i);
-}
-
/* Given an object INSTANCE, return an expression which yields the
vtable element corresponding to INDEX. There are many special
cases for INSTANCE which we take care of here, mainly to avoid
creating extra tree nodes when we don't have to. */
static tree
-build_vtbl_ref_1 (instance, idx)
- tree instance, idx;
+build_vtbl_ref_1 (tree instance, tree idx)
{
tree aref;
tree vtbl = NULL_TREE;
@@ -477,9 +435,7 @@ build_vtbl_ref_1 (instance, idx)
int cdtorp = 0;
tree fixed_type = fixed_type_or_null (instance, NULL, &cdtorp);
- tree basetype = TREE_TYPE (instance);
- if (TREE_CODE (basetype) == REFERENCE_TYPE)
- basetype = TREE_TYPE (basetype);
+ tree basetype = non_reference (TREE_TYPE (instance));
if (fixed_type && !cdtorp)
{
@@ -490,27 +446,20 @@ build_vtbl_ref_1 (instance, idx)
}
if (!vtbl)
- {
- vtbl = build_vfield_ref (instance, basetype);
- }
-
+ vtbl = build_vfield_ref (instance, basetype);
+
assemble_external (vtbl);
aref = build_array_ref (vtbl, idx);
- TREE_CONSTANT (aref) = 1;
return aref;
}
tree
-build_vtbl_ref (instance, idx)
- tree instance, idx;
+build_vtbl_ref (tree instance, tree idx)
{
tree aref = build_vtbl_ref_1 (instance, idx);
- if (flag_vtable_gc)
- aref = build_vtable_entry_ref (aref, instance, idx);
-
return aref;
}
@@ -518,8 +467,7 @@ build_vtbl_ref (instance, idx)
function pointer corresponding to vtable element INDEX. */
tree
-build_vfn_ref (instance, idx)
- tree instance, idx;
+build_vfn_ref (tree instance, tree idx)
{
tree aref = build_vtbl_ref_1 (instance, idx);
@@ -529,9 +477,6 @@ build_vfn_ref (instance, idx)
aref = build1 (NOP_EXPR, TREE_TYPE (aref),
build_unary_op (ADDR_EXPR, aref, /*noconvert=*/1));
- if (flag_vtable_gc)
- aref = build_vtable_entry_ref (aref, instance, idx);
-
return aref;
}
@@ -539,8 +484,7 @@ build_vfn_ref (instance, idx)
for the given TYPE. */
static tree
-get_vtable_name (type)
- tree type;
+get_vtable_name (tree type)
{
return mangle_vtbl_for_type (type);
}
@@ -549,8 +493,7 @@ get_vtable_name (type)
for TYPE. */
tree
-get_vtt_name (type)
- tree type;
+get_vtt_name (tree type)
{
return mangle_vtt_for_type (type);
}
@@ -560,10 +503,7 @@ get_vtt_name (type)
Use NAME for the name of the vtable, and VTABLE_TYPE for its type. */
static tree
-build_vtable (class_type, name, vtable_type)
- tree class_type;
- tree name;
- tree vtable_type;
+build_vtable (tree class_type, tree name, tree vtable_type)
{
tree decl;
@@ -577,6 +517,12 @@ build_vtable (class_type, name, vtable_type)
TREE_READONLY (decl) = 1;
DECL_VIRTUAL_P (decl) = 1;
DECL_ALIGN (decl) = TARGET_VTABLE_ENTRY_ALIGN;
+ DECL_VTABLE_OR_VTT_P (decl) = 1;
+
+ /* At one time the vtable info was grabbed 2 words at a time. This
+ fails on sparc unless you have 8-byte alignment. (tiemann) */
+ DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
+ DECL_ALIGN (decl));
import_export_vtable (decl, class_type, 0);
@@ -590,23 +536,16 @@ build_vtable (class_type, name, vtable_type)
which are known to exist in the runtime. */
tree
-get_vtable_decl (type, complete)
- tree type;
- int complete;
+get_vtable_decl (tree type, int complete)
{
tree decl;
if (CLASSTYPE_VTABLES (type))
return CLASSTYPE_VTABLES (type);
- decl = build_vtable (type, get_vtable_name (type), void_type_node);
+ decl = build_vtable (type, get_vtable_name (type), vtbl_type_node);
CLASSTYPE_VTABLES (type) = decl;
- /* At one time the vtable info was grabbed 2 words at a time. This
- fails on sparc unless you have 8-byte alignment. (tiemann) */
- DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node),
- DECL_ALIGN (decl));
-
if (complete)
{
DECL_EXTERNAL (decl) = 1;
@@ -620,8 +559,7 @@ get_vtable_decl (type, complete)
BV_VCALL_INDEX for each entry is cleared. */
static tree
-copy_virtuals (binfo)
- tree binfo;
+copy_virtuals (tree binfo)
{
tree copies;
tree t;
@@ -640,8 +578,7 @@ copy_virtuals (binfo)
created. */
static int
-build_primary_vtable (binfo, type)
- tree binfo, type;
+build_primary_vtable (tree binfo, tree type)
{
tree decl;
tree virtuals;
@@ -650,7 +587,7 @@ build_primary_vtable (binfo, type)
if (binfo)
{
- if (BINFO_NEW_VTABLE_MARKED (binfo, type))
+ if (BINFO_NEW_VTABLE_MARKED (binfo))
/* We have already created a vtable for this base, so there's
no need to do it again. */
return 0;
@@ -662,8 +599,7 @@ build_primary_vtable (binfo, type)
}
else
{
- my_friendly_assert (TREE_CODE (TREE_TYPE (decl)) == VOID_TYPE,
- 20000118);
+ my_friendly_assert (TREE_TYPE (decl) == vtbl_type_node, 20000118);
virtuals = NULL_TREE;
}
@@ -676,7 +612,7 @@ build_primary_vtable (binfo, type)
on our first approximation. */
TYPE_BINFO_VTABLE (type) = decl;
TYPE_BINFO_VIRTUALS (type) = virtuals;
- SET_BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (type), type);
+ SET_BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (type));
return 1;
}
@@ -695,19 +631,16 @@ build_primary_vtable (binfo, type)
can result. */
static int
-build_secondary_vtable (binfo, for_type)
- tree binfo, for_type;
+build_secondary_vtable (tree binfo)
{
- my_friendly_assert (binfo == CANONICAL_BINFO (binfo, for_type), 20010605);
-
- if (BINFO_NEW_VTABLE_MARKED (binfo, for_type))
+ if (BINFO_NEW_VTABLE_MARKED (binfo))
/* We already created a vtable for this base. There's no need to
do it again. */
return 0;
/* Remember that we've created a vtable for this BINFO, so that we
don't try to do so again. */
- SET_BINFO_NEW_VTABLE_MARKED (binfo, for_type);
+ SET_BINFO_NEW_VTABLE_MARKED (binfo);
/* Make fresh virtual list, so we can smash it later. */
BINFO_VIRTUALS (binfo) = copy_virtuals (binfo);
@@ -722,9 +655,7 @@ build_secondary_vtable (binfo, for_type)
T. Return nonzero if we actually created a new vtable. */
static int
-make_new_vtable (t, binfo)
- tree t;
- tree binfo;
+make_new_vtable (tree t, tree binfo)
{
if (binfo == TYPE_BINFO (t))
/* In this case, it is *type*'s vtable we are modifying. We start
@@ -739,7 +670,7 @@ make_new_vtable (t, binfo)
we will fill in all the virtual functions that override the
virtual functions in these base classes which are not defined
by the current type. */
- return build_secondary_vtable (binfo, t);
+ return build_secondary_vtable (binfo);
}
/* Make *VIRTUALS, an entry on the BINFO_VIRTUALS list for BINFO
@@ -749,12 +680,11 @@ make_new_vtable (t, binfo)
the function is actually called. */
static void
-modify_vtable_entry (t, binfo, fndecl, delta, virtuals)
- tree t;
- tree binfo;
- tree fndecl;
- tree delta;
- tree *virtuals;
+modify_vtable_entry (tree t,
+ tree binfo,
+ tree fndecl,
+ tree delta,
+ tree *virtuals)
{
tree v;
@@ -763,8 +693,6 @@ modify_vtable_entry (t, binfo, fndecl, delta, virtuals)
if (fndecl != BV_FN (v)
|| !tree_int_cst_equal (delta, BV_DELTA (v)))
{
- tree base_fndecl;
-
/* We need a new vtable for BINFO. */
if (make_new_vtable (t, binfo))
{
@@ -777,7 +705,6 @@ modify_vtable_entry (t, binfo, fndecl, delta, virtuals)
v = *virtuals;
}
- base_fndecl = BV_FN (v);
BV_DELTA (v) = delta;
BV_VCALL_INDEX (v) = NULL_TREE;
BV_FN (v) = fndecl;
@@ -791,17 +718,20 @@ modify_vtable_entry (t, binfo, fndecl, delta, virtuals)
add the method for improved error recovery.) */
void
-add_method (type, method, error_p)
- tree type;
- tree method;
- int error_p;
+add_method (tree type, tree method, int error_p)
{
- int using = (DECL_CONTEXT (method) != type);
+ int using;
int len;
int slot;
tree method_vec;
- int template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL
- && DECL_TEMPLATE_CONV_FN_P (method));
+ int template_conv_p;
+
+ if (method == error_mark_node)
+ return;
+
+ using = (DECL_CONTEXT (method) != type);
+ template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL
+ && DECL_TEMPLATE_CONV_FN_P (method));
if (!CLASSTYPE_METHOD_VEC (type))
/* Make a new method vector. We start with 8 entries. We must
@@ -823,7 +753,16 @@ add_method (type, method, error_p)
if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (method))
slot = CLASSTYPE_CONSTRUCTOR_SLOT;
else if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (method))
- slot = CLASSTYPE_DESTRUCTOR_SLOT;
+ {
+ slot = CLASSTYPE_DESTRUCTOR_SLOT;
+ TYPE_HAS_DESTRUCTOR (type) = 1;
+
+ if (TYPE_FOR_JAVA (type))
+ error (DECL_ARTIFICIAL (method)
+ ? "Java class '%T' cannot have an implicit non-trivial destructor"
+ : "Java class '%T' cannot have a destructor",
+ DECL_CONTEXT (method));
+ }
else
{
int have_template_convs_p = 0;
@@ -925,7 +864,7 @@ add_method (type, method, error_p)
}
}
- if (template_class_depth (type))
+ if (processing_template_decl)
/* TYPE is a template class. Don't issue any errors now; wait
until instantiation time to complain. */
;
@@ -990,7 +929,7 @@ add_method (type, method, error_p)
else
{
cp_error_at ("`%#D' and `%#D' cannot be overloaded",
- method, fn, method);
+ method, fn);
/* We don't call duplicate_decls here to merge
the declarations because that will confuse
@@ -1016,124 +955,18 @@ add_method (type, method, error_p)
/* Subroutines of finish_struct. */
-/* Look through the list of fields for this struct, deleting
- duplicates as we go. This must be recursive to handle
- anonymous unions.
-
- FIELD is the field which may not appear anywhere in FIELDS.
- FIELD_PTR, if non-null, is the starting point at which
- chained deletions may take place.
- The value returned is the first acceptable entry found
- in FIELDS.
-
- Note that anonymous fields which are not of UNION_TYPE are
- not duplicates, they are just anonymous fields. This happens
- when we have unnamed bitfields, for example. */
-
-static tree
-delete_duplicate_fields_1 (field, fields)
- tree field, fields;
-{
- tree x;
- tree prev = 0;
- if (DECL_NAME (field) == 0)
- {
- if (! ANON_AGGR_TYPE_P (TREE_TYPE (field)))
- return fields;
-
- for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x))
- fields = delete_duplicate_fields_1 (x, fields);
- return fields;
- }
- else
- {
- for (x = fields; x; prev = x, x = TREE_CHAIN (x))
- {
- if (DECL_NAME (x) == 0)
- {
- if (! ANON_AGGR_TYPE_P (TREE_TYPE (x)))
- continue;
- TYPE_FIELDS (TREE_TYPE (x))
- = delete_duplicate_fields_1 (field, TYPE_FIELDS (TREE_TYPE (x)));
- if (TYPE_FIELDS (TREE_TYPE (x)) == 0)
- {
- if (prev == 0)
- fields = TREE_CHAIN (fields);
- else
- TREE_CHAIN (prev) = TREE_CHAIN (x);
- }
- }
- else if (TREE_CODE (field) == USING_DECL)
- /* A using declaration is allowed to appear more than
- once. We'll prune these from the field list later, and
- handle_using_decl will complain about invalid multiple
- uses. */
- ;
- else if (DECL_NAME (field) == DECL_NAME (x))
- {
- if (TREE_CODE (field) == CONST_DECL
- && TREE_CODE (x) == CONST_DECL)
- cp_error_at ("duplicate enum value `%D'", x);
- else if (TREE_CODE (field) == CONST_DECL
- || TREE_CODE (x) == CONST_DECL)
- cp_error_at ("duplicate field `%D' (as enum and non-enum)",
- x);
- else if (DECL_DECLARES_TYPE_P (field)
- && DECL_DECLARES_TYPE_P (x))
- {
- if (same_type_p (TREE_TYPE (field), TREE_TYPE (x)))
- continue;
- cp_error_at ("duplicate nested type `%D'", x);
- }
- else if (DECL_DECLARES_TYPE_P (field)
- || DECL_DECLARES_TYPE_P (x))
- {
- /* Hide tag decls. */
- if ((TREE_CODE (field) == TYPE_DECL
- && DECL_ARTIFICIAL (field))
- || (TREE_CODE (x) == TYPE_DECL
- && DECL_ARTIFICIAL (x)))
- continue;
- cp_error_at ("duplicate field `%D' (as type and non-type)",
- x);
- }
- else
- cp_error_at ("duplicate member `%D'", x);
- if (prev == 0)
- fields = TREE_CHAIN (fields);
- else
- TREE_CHAIN (prev) = TREE_CHAIN (x);
- }
- }
- }
- return fields;
-}
-
-static void
-delete_duplicate_fields (fields)
- tree fields;
-{
- tree x;
- for (x = fields; x && TREE_CHAIN (x); x = TREE_CHAIN (x))
- TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x));
-}
-
/* Change the access of FDECL to ACCESS in T. Return 1 if change was
legit, otherwise return 0. */
static int
-alter_access (t, fdecl, access)
- tree t;
- tree fdecl;
- tree access;
+alter_access (tree t, tree fdecl, tree access)
{
tree elem;
if (!DECL_LANG_SPECIFIC (fdecl))
retrofit_lang_decl (fdecl);
- if (DECL_DISCRIMINATOR_P (fdecl))
- abort ();
+ my_friendly_assert (!DECL_DISCRIMINATOR_P (fdecl), 20030624);
elem = purpose_member (t, DECL_ACCESS (fdecl));
if (elem)
@@ -1155,7 +988,7 @@ alter_access (t, fdecl, access)
}
else
{
- enforce_access (t, fdecl);
+ perform_or_defer_access_check (TYPE_BINFO (t), fdecl);
DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
return 1;
}
@@ -1165,9 +998,7 @@ alter_access (t, fdecl, access)
/* Process the USING_DECL, which is a member of T. */
static void
-handle_using_decl (using_decl, t)
- tree using_decl;
- tree t;
+handle_using_decl (tree using_decl, tree t)
{
tree ctype = DECL_INITIAL (using_decl);
tree name = DECL_NAME (using_decl);
@@ -1185,7 +1016,11 @@ handle_using_decl (using_decl, t)
binfo = lookup_base (t, ctype, ba_any, NULL);
if (! binfo)
{
- error_not_base_type (t, ctype);
+ location_t saved_loc = input_location;
+
+ input_location = DECL_SOURCE_LOCATION (using_decl);
+ error_not_base_type (ctype, t);
+ input_location = saved_loc;
return;
}
@@ -1200,7 +1035,7 @@ handle_using_decl (using_decl, t)
return;
}
- fdecl = lookup_member (binfo, name, 0, 0);
+ fdecl = lookup_member (binfo, name, 0, false);
if (!fdecl)
{
@@ -1249,7 +1084,7 @@ handle_using_decl (using_decl, t)
return;
}
- /* Make type T see field decl FDECL with access ACCESS.*/
+ /* Make type T see field decl FDECL with access ACCESS. */
if (flist)
for (; flist; flist = OVL_NEXT (flist))
{
@@ -1266,12 +1101,10 @@ handle_using_decl (using_decl, t)
the bases. */
static void
-check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
- no_const_asn_ref_p)
- tree t;
- int *cant_have_default_ctor_p;
- int *cant_have_const_ctor_p;
- int *no_const_asn_ref_p;
+check_bases (tree t,
+ int* cant_have_default_ctor_p,
+ int* cant_have_const_ctor_p,
+ int* no_const_asn_ref_p)
{
int n_baseclasses;
int i;
@@ -1367,237 +1200,52 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
TYPE_HAS_COMPLEX_ASSIGN_REF (t)
|= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype);
TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype);
- TYPE_OVERLOADS_CALL_EXPR (t) |= TYPE_OVERLOADS_CALL_EXPR (basetype);
- TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype);
- TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype);
TYPE_POLYMORPHIC_P (t) |= TYPE_POLYMORPHIC_P (basetype);
CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t)
|= CLASSTYPE_CONTAINS_EMPTY_CLASS_P (basetype);
}
}
-/* Binfo FROM is within a virtual hierarchy which is being reseated to
- TO. Move primary information from FROM to TO, and recursively traverse
- into FROM's bases. The hierarchy is dominated by TYPE. MAPPINGS is an
- assoc list of binfos that have already been reseated. */
-
-static void
-force_canonical_binfo_r (to, from, type, mappings)
- tree to;
- tree from;
- tree type;
- tree mappings;
-{
- int i, n_baseclasses = BINFO_N_BASETYPES (from);
-
- my_friendly_assert (to != from, 20010905);
- BINFO_INDIRECT_PRIMARY_P (to)
- = BINFO_INDIRECT_PRIMARY_P (from);
- BINFO_INDIRECT_PRIMARY_P (from) = 0;
- BINFO_UNSHARED_MARKED (to) = BINFO_UNSHARED_MARKED (from);
- BINFO_UNSHARED_MARKED (from) = 0;
- BINFO_LOST_PRIMARY_P (to) = BINFO_LOST_PRIMARY_P (from);
- BINFO_LOST_PRIMARY_P (from) = 0;
- if (BINFO_PRIMARY_P (from))
- {
- tree primary = BINFO_PRIMARY_BASE_OF (from);
- tree assoc;
-
- /* We might have just moved the primary base too, see if it's on our
- mappings. */
- assoc = purpose_member (primary, mappings);
- if (assoc)
- primary = TREE_VALUE (assoc);
- BINFO_PRIMARY_BASE_OF (to) = primary;
- BINFO_PRIMARY_BASE_OF (from) = NULL_TREE;
- }
- my_friendly_assert (same_type_p (BINFO_TYPE (to), BINFO_TYPE (from)),
- 20010104);
- mappings = tree_cons (from, to, mappings);
-
- if (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (from))
- && TREE_VIA_VIRTUAL (CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (from))))
- {
- tree from_primary = get_primary_binfo (from);
-
- if (BINFO_PRIMARY_BASE_OF (from_primary) == from)
- force_canonical_binfo (get_primary_binfo (to), from_primary,
- type, mappings);
- }
-
- for (i = 0; i != n_baseclasses; i++)
- {
- tree from_binfo = BINFO_BASETYPE (from, i);
- tree to_binfo = BINFO_BASETYPE (to, i);
-
- if (TREE_VIA_VIRTUAL (from_binfo))
- {
- if (BINFO_PRIMARY_P (from_binfo) &&
- purpose_member (BINFO_PRIMARY_BASE_OF (from_binfo), mappings))
- /* This base is a primary of some binfo we have already
- reseated. We must reseat this one too. */
- force_canonical_binfo (to_binfo, from_binfo, type, mappings);
- }
- else
- force_canonical_binfo_r (to_binfo, from_binfo, type, mappings);
- }
-}
-
-/* FROM is the canonical binfo for a virtual base. It is being reseated to
- make TO the canonical binfo, within the hierarchy dominated by TYPE.
- MAPPINGS is an assoc list of binfos that have already been reseated.
- Adjust any non-virtual bases within FROM, and also move any virtual bases
- which are canonical. This complication arises because selecting primary
- bases walks in inheritance graph order, but we don't share binfos for
- virtual bases, hence we can fill in the primaries for a virtual base,
- and then discover that a later base requires the virtual as its
- primary. */
-
-static void
-force_canonical_binfo (to, from, type, mappings)
- tree to;
- tree from;
- tree type;
- tree mappings;
-{
- tree assoc = purpose_member (BINFO_TYPE (to),
- CLASSTYPE_VBASECLASSES (type));
- if (TREE_VALUE (assoc) != to)
- {
- TREE_VALUE (assoc) = to;
- force_canonical_binfo_r (to, from, type, mappings);
- }
-}
-
-/* Make BASE_BINFO the a primary virtual base within the hierarchy
- dominated by TYPE. Returns BASE_BINFO, if it is not already one, NULL
- otherwise (because something else has already made it primary). */
-
-static tree
-mark_primary_virtual_base (base_binfo, type)
- tree base_binfo;
- tree type;
-{
- tree shared_binfo = binfo_for_vbase (BINFO_TYPE (base_binfo), type);
-
- if (BINFO_PRIMARY_P (shared_binfo))
- {
- /* It's already allocated in the hierarchy. BINFO won't have a
- primary base in this hierarchy, even though the complete object
- BINFO is for, would do. */
- return NULL_TREE;
- }
-
- /* We need to make sure that the assoc list
- CLASSTYPE_VBASECLASSES of TYPE, indicates this particular
- primary BINFO for the virtual base, as this is the one
- that'll really exist. */
- if (base_binfo != shared_binfo)
- force_canonical_binfo (base_binfo, shared_binfo, type, NULL);
-
- return base_binfo;
-}
-
-/* If BINFO is an unmarked virtual binfo for a class with a primary virtual
- base, then BINFO has no primary base in this graph. Called from
- mark_primary_bases. DATA is the most derived type. */
-
-static tree dfs_unshared_virtual_bases (binfo, data)
- tree binfo;
- void *data;
-{
- tree t = (tree) data;
-
- if (!BINFO_UNSHARED_MARKED (binfo)
- && CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
- {
- /* This morally virtual base has a primary base when it
- is a complete object. We need to locate the shared instance
- of this binfo in the type dominated by T. We duplicate the
- primary base information from there to here. */
- tree vbase;
- tree unshared_base;
-
- for (vbase = binfo; !TREE_VIA_VIRTUAL (vbase);
- vbase = BINFO_INHERITANCE_CHAIN (vbase))
- continue;
- unshared_base = get_original_base (binfo,
- binfo_for_vbase (BINFO_TYPE (vbase),
- t));
- my_friendly_assert (unshared_base != binfo, 20010612);
- BINFO_LOST_PRIMARY_P (binfo) = BINFO_LOST_PRIMARY_P (unshared_base);
- if (!BINFO_LOST_PRIMARY_P (binfo))
- BINFO_PRIMARY_BASE_OF (get_primary_binfo (binfo)) = binfo;
- }
-
- if (binfo != TYPE_BINFO (t))
- /* The vtable fields will have been copied when duplicating the
- base binfos. That information is bogus, make sure we don't try
- and use it. */
- BINFO_VTABLE (binfo) = NULL_TREE;
-
- /* If this is a virtual primary base, make sure its offset matches
- that which it is primary for. */
- if (BINFO_PRIMARY_P (binfo) && TREE_VIA_VIRTUAL (binfo) &&
- binfo_for_vbase (BINFO_TYPE (binfo), t) == binfo)
- {
- tree delta = size_diffop (BINFO_OFFSET (BINFO_PRIMARY_BASE_OF (binfo)),
- BINFO_OFFSET (binfo));
- if (!integer_zerop (delta))
- propagate_binfo_offsets (binfo, delta, t);
- }
-
- BINFO_UNSHARED_MARKED (binfo) = 0;
- return NULL;
-}
-
/* Set BINFO_PRIMARY_BASE_OF for all binfos in the hierarchy
dominated by TYPE that are primary bases. */
static void
-mark_primary_bases (type)
- tree type;
+mark_primary_bases (tree type)
{
tree binfo;
/* Walk the bases in inheritance graph order. */
for (binfo = TYPE_BINFO (type); binfo; binfo = TREE_CHAIN (binfo))
{
- tree base_binfo;
-
- if (!CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
- /* Not a dynamic base. */
- continue;
-
- base_binfo = get_primary_binfo (binfo);
+ tree base_binfo = get_primary_binfo (binfo);
- if (TREE_VIA_VIRTUAL (base_binfo))
- base_binfo = mark_primary_virtual_base (base_binfo, type);
-
- if (base_binfo)
- BINFO_PRIMARY_BASE_OF (base_binfo) = binfo;
- else
+ if (!base_binfo)
+ /* Not a dynamic base. */;
+ else if (BINFO_PRIMARY_P (base_binfo))
BINFO_LOST_PRIMARY_P (binfo) = 1;
-
- BINFO_UNSHARED_MARKED (binfo) = 1;
+ else
+ {
+ BINFO_PRIMARY_BASE_OF (base_binfo) = binfo;
+ /* A virtual binfo might have been copied from within
+ another hierarchy. As we're about to use it as a primary
+ base, make sure the offsets match. */
+ if (TREE_VIA_VIRTUAL (base_binfo))
+ {
+ tree delta = size_diffop (convert (ssizetype,
+ BINFO_OFFSET (binfo)),
+ convert (ssizetype,
+ BINFO_OFFSET (base_binfo)));
+
+ propagate_binfo_offsets (base_binfo, delta);
+ }
+ }
}
- /* There could remain unshared morally virtual bases which were not
- visited in the inheritance graph walk. These bases will have lost
- their virtual primary base (should they have one). We must now
- find them. Also we must fix up the BINFO_OFFSETs of primary
- virtual bases. We could not do that as we went along, as they
- were originally copied from the bases we inherited from by
- unshare_base_binfos. That may have decided differently about
- where a virtual primary base went. */
- dfs_walk (TYPE_BINFO (type), dfs_unshared_virtual_bases, NULL, type);
}
/* Make the BINFO the primary base of T. */
static void
-set_primary_base (t, binfo)
- tree t;
- tree binfo;
+set_primary_base (tree t, tree binfo)
{
tree basetype;
@@ -1611,8 +1259,7 @@ set_primary_base (t, binfo)
/* Determine the primary class for T. */
static void
-determine_primary_base (t)
- tree t;
+determine_primary_base (tree t)
{
int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
tree vbases;
@@ -1754,8 +1401,7 @@ determine_primary_base (t)
use. */
static void
-finish_struct_bits (t)
- tree t;
+finish_struct_bits (tree t)
{
int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
@@ -1834,8 +1480,7 @@ finish_struct_bits (t)
non-private static member functions. */
static void
-maybe_warn_about_overly_private_class (t)
- tree t;
+maybe_warn_about_overly_private_class (tree t)
{
int has_member_fn = 0;
int has_nonprivate_method = 0;
@@ -1899,10 +1544,10 @@ maybe_warn_about_overly_private_class (t)
issues error messages specifically referring to
constructors/destructors.) */
int i;
- tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
- for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++)
- if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i))
- || TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i)))
+ tree binfo = TYPE_BINFO (t);
+
+ for (i = 0; i < BINFO_N_BASETYPES (binfo); i++)
+ if (BINFO_BASEACCESS (binfo, i) != access_private_node)
{
has_nonprivate_method = 1;
break;
@@ -1917,16 +1562,12 @@ maybe_warn_about_overly_private_class (t)
/* Even if some of the member functions are non-private, the class
won't be useful for much if all the constructors or destructors
are private: such an object can never be created or destroyed. */
- if (TYPE_HAS_DESTRUCTOR (t))
+ if (TYPE_HAS_DESTRUCTOR (t)
+ && TREE_PRIVATE (CLASSTYPE_DESTRUCTORS (t)))
{
- tree dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1);
-
- if (TREE_PRIVATE (dtor))
- {
- warning ("`%#T' only defines a private destructor and has no friends",
- t);
- return;
- }
+ warning ("`%#T' only defines a private destructor and has no friends",
+ t);
+ return;
}
if (TYPE_HAS_CONSTRUCTOR (t))
@@ -1973,41 +1614,85 @@ maybe_warn_about_overly_private_class (t)
}
}
-/* Function to help qsort sort FIELD_DECLs by name order. */
+static struct {
+ gt_pointer_operator new_value;
+ void *cookie;
+} resort_data;
+
+/* Comparison function to compare two TYPE_METHOD_VEC entries by name. */
static int
-field_decl_cmp (x, y)
- const tree *x, *y;
+method_name_cmp (const void* m1_p, const void* m2_p)
{
- if (DECL_NAME (*x) == DECL_NAME (*y))
- /* A nontype is "greater" than a type. */
- return DECL_DECLARES_TYPE_P (*y) - DECL_DECLARES_TYPE_P (*x);
- if (DECL_NAME (*x) == NULL_TREE)
+ const tree *const m1 = m1_p;
+ const tree *const m2 = m2_p;
+
+ if (*m1 == NULL_TREE && *m2 == NULL_TREE)
+ return 0;
+ if (*m1 == NULL_TREE)
return -1;
- if (DECL_NAME (*y) == NULL_TREE)
+ if (*m2 == NULL_TREE)
return 1;
- if (DECL_NAME (*x) < DECL_NAME (*y))
+ if (DECL_NAME (OVL_CURRENT (*m1)) < DECL_NAME (OVL_CURRENT (*m2)))
return -1;
return 1;
}
-/* Comparison function to compare two TYPE_METHOD_VEC entries by name. */
+/* This routine compares two fields like method_name_cmp but using the
+ pointer operator in resort_field_decl_data. */
static int
-method_name_cmp (m1, m2)
- const tree *m1, *m2;
+resort_method_name_cmp (const void* m1_p, const void* m2_p)
{
+ const tree *const m1 = m1_p;
+ const tree *const m2 = m2_p;
if (*m1 == NULL_TREE && *m2 == NULL_TREE)
return 0;
if (*m1 == NULL_TREE)
return -1;
if (*m2 == NULL_TREE)
return 1;
- if (DECL_NAME (OVL_CURRENT (*m1)) < DECL_NAME (OVL_CURRENT (*m2)))
- return -1;
+ {
+ tree d1 = DECL_NAME (OVL_CURRENT (*m1));
+ tree d2 = DECL_NAME (OVL_CURRENT (*m2));
+ resort_data.new_value (&d1, resort_data.cookie);
+ resort_data.new_value (&d2, resort_data.cookie);
+ if (d1 < d2)
+ return -1;
+ }
return 1;
}
+/* Resort TYPE_METHOD_VEC because pointers have been reordered. */
+
+void
+resort_type_method_vec (void* obj,
+ void* orig_obj ATTRIBUTE_UNUSED ,
+ gt_pointer_operator new_value,
+ void* cookie)
+{
+ tree method_vec = obj;
+ int len = TREE_VEC_LENGTH (method_vec);
+ int slot;
+
+ /* The type conversion ops have to live at the front of the vec, so we
+ can't sort them. */
+ for (slot = 2; slot < len; ++slot)
+ {
+ tree fn = TREE_VEC_ELT (method_vec, slot);
+
+ if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
+ break;
+ }
+ if (len - slot > 1)
+ {
+ resort_data.new_value = new_value;
+ resort_data.cookie = cookie;
+ qsort (&TREE_VEC_ELT (method_vec, slot), len - slot, sizeof (tree),
+ resort_method_name_cmp);
+ }
+}
+
/* Warn about duplicate methods in fn_fields. Also compact method
lists so that lookup can be made faster.
@@ -2025,8 +1710,7 @@ method_name_cmp (m1, m2)
search. */
static void
-finish_struct_methods (t)
- tree t;
+finish_struct_methods (tree t)
{
tree fn_fields;
tree method_vec;
@@ -2078,80 +1762,7 @@ finish_struct_methods (t)
}
if (len - slot > 1)
qsort (&TREE_VEC_ELT (method_vec, slot), len-slot, sizeof (tree),
- (int (*)(const void *, const void *))method_name_cmp);
-}
-
-/* Emit error when a duplicate definition of a type is seen. Patch up. */
-
-void
-duplicate_tag_error (t)
- tree t;
-{
- error ("redefinition of `%#T'", t);
- cp_error_at ("previous definition of `%#T'", t);
-
- /* Pretend we haven't defined this type. */
-
- /* All of the component_decl's were TREE_CHAINed together in the parser.
- finish_struct_methods walks these chains and assembles all methods with
- the same base name into DECL_CHAINs. Now we don't need the parser chains
- anymore, so we unravel them. */
-
- /* This used to be in finish_struct, but it turns out that the
- TREE_CHAIN is used by dbxout_type_methods and perhaps some other
- things... */
- if (CLASSTYPE_METHOD_VEC (t))
- {
- tree method_vec = CLASSTYPE_METHOD_VEC (t);
- int i, len = TREE_VEC_LENGTH (method_vec);
- for (i = 0; i < len; i++)
- {
- tree unchain = TREE_VEC_ELT (method_vec, i);
- while (unchain != NULL_TREE)
- {
- TREE_CHAIN (OVL_CURRENT (unchain)) = NULL_TREE;
- unchain = OVL_NEXT (unchain);
- }
- }
- }
-
- if (TYPE_LANG_SPECIFIC (t))
- {
- tree binfo = TYPE_BINFO (t);
- int interface_only = CLASSTYPE_INTERFACE_ONLY (t);
- int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t);
- tree template_info = CLASSTYPE_TEMPLATE_INFO (t);
- int use_template = CLASSTYPE_USE_TEMPLATE (t);
-
- memset ((char *) TYPE_LANG_SPECIFIC (t), 0, sizeof (struct lang_type));
- BINFO_BASETYPES(binfo) = NULL_TREE;
-
- TYPE_LANG_SPECIFIC (t)->u.h.is_lang_type_class = 1;
- TYPE_BINFO (t) = binfo;
- CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
- SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
- TYPE_REDEFINED (t) = 1;
- CLASSTYPE_TEMPLATE_INFO (t) = template_info;
- CLASSTYPE_USE_TEMPLATE (t) = use_template;
- CLASSTYPE_DECL_LIST (t) = NULL_TREE;
- }
- TYPE_SIZE (t) = NULL_TREE;
- TYPE_MODE (t) = VOIDmode;
- TYPE_FIELDS (t) = NULL_TREE;
- TYPE_METHODS (t) = NULL_TREE;
- TYPE_VFIELD (t) = NULL_TREE;
- TYPE_CONTEXT (t) = NULL_TREE;
-
- /* Clear TYPE_LANG_FLAGS -- those in TYPE_LANG_SPECIFIC are cleared above. */
- TYPE_LANG_FLAG_0 (t) = 0;
- TYPE_LANG_FLAG_1 (t) = 0;
- TYPE_LANG_FLAG_2 (t) = 0;
- TYPE_LANG_FLAG_3 (t) = 0;
- TYPE_LANG_FLAG_4 (t) = 0;
- TYPE_LANG_FLAG_5 (t) = 0;
- TYPE_LANG_FLAG_6 (t) = 0;
- /* But not this one. */
- SET_IS_AGGR_TYPE (t, 1);
+ method_name_cmp);
}
/* Make BINFO's vtable have N entries, including RTTI entries,
@@ -2159,9 +1770,7 @@ duplicate_tag_error (t)
to lay it out. */
static void
-layout_vtable_decl (binfo, n)
- tree binfo;
- int n;
+layout_vtable_decl (tree binfo, int n)
{
tree atype;
tree vtable;
@@ -2177,11 +1786,6 @@ layout_vtable_decl (binfo, n)
TREE_TYPE (vtable) = atype;
DECL_SIZE (vtable) = DECL_SIZE_UNIT (vtable) = NULL_TREE;
layout_decl (vtable, 0);
-
- /* At one time the vtable info was grabbed 2 words at a time. This
- fails on SPARC unless you have 8-byte alignment. */
- DECL_ALIGN (vtable) = MAX (TYPE_ALIGN (double_type_node),
- DECL_ALIGN (vtable));
}
}
@@ -2189,8 +1793,7 @@ layout_vtable_decl (binfo, n)
have the same signature. */
int
-same_signature_p (fndecl, base_fndecl)
- tree fndecl, base_fndecl;
+same_signature_p (tree fndecl, tree base_fndecl)
{
/* One destructor overrides another if they are the same kind of
destructor. */
@@ -2204,7 +1807,11 @@ same_signature_p (fndecl, base_fndecl)
if (DECL_DESTRUCTOR_P (base_fndecl) || DECL_DESTRUCTOR_P (fndecl))
return 0;
- if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl))
+ if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl)
+ || (DECL_CONV_FN_P (fndecl)
+ && DECL_CONV_FN_P (base_fndecl)
+ && same_type_p (DECL_CONV_FN_TYPE (fndecl),
+ DECL_CONV_FN_TYPE (base_fndecl))))
{
tree types, base_types;
types = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
@@ -2217,27 +1824,27 @@ same_signature_p (fndecl, base_fndecl)
return 0;
}
-/* Called from base_derived_from via dfs_walk. */
-
-static tree
-dfs_base_derived_from (tree binfo, void *data)
-{
- tree base = (tree) data;
-
- if (same_type_p (TREE_TYPE (base), TREE_TYPE (binfo))
- && tree_int_cst_equal (BINFO_OFFSET (base), BINFO_OFFSET (binfo)))
- return error_mark_node;
-
- return NULL_TREE;
-}
-
/* Returns TRUE if DERIVED is a binfo containing the binfo BASE as a
subobject. */
static bool
base_derived_from (tree derived, tree base)
{
- return dfs_walk (derived, dfs_base_derived_from, NULL, base) != NULL_TREE;
+ tree probe;
+
+ for (probe = base; probe; probe = BINFO_INHERITANCE_CHAIN (probe))
+ {
+ if (probe == derived)
+ return true;
+ else if (TREE_VIA_VIRTUAL (probe))
+ /* If we meet a virtual base, we can't follow the inheritance
+ any more. See if the complete type of DERIVED contains
+ such a virtual base. */
+ return purpose_member (BINFO_TYPE (probe),
+ CLASSTYPE_VBASECLASSES (BINFO_TYPE (derived)))
+ != NULL_TREE;
+ }
+ return false;
}
typedef struct find_final_overrider_data_s {
@@ -2249,72 +1856,93 @@ typedef struct find_final_overrider_data_s {
tree most_derived_type;
/* The candidate overriders. */
tree candidates;
+ /* Binfos which inherited virtually on the current path. */
+ tree vpath;
} find_final_overrider_data;
/* Called from find_final_overrider via dfs_walk. */
static tree
-dfs_find_final_overrider (binfo, data)
- tree binfo;
- void *data;
+dfs_find_final_overrider (tree binfo, void* data)
{
find_final_overrider_data *ffod = (find_final_overrider_data *) data;
- if (same_type_p (BINFO_TYPE (binfo),
- BINFO_TYPE (ffod->declaring_base))
- && tree_int_cst_equal (BINFO_OFFSET (binfo),
- BINFO_OFFSET (ffod->declaring_base)))
- {
- tree path;
- tree method;
-
- /* We haven't found an overrider yet. */
- method = NULL_TREE;
- /* We've found a path to the declaring base. Walk down the path
- looking for an overrider for FN. */
- path = reverse_path (binfo);
- while (!same_type_p (BINFO_TYPE (TREE_VALUE (path)),
- ffod->most_derived_type))
- path = TREE_CHAIN (path);
- while (path)
+ if (binfo == ffod->declaring_base)
+ {
+ /* We've found a path to the declaring base. Walk the path from
+ derived to base, looking for an overrider for FN. */
+ tree path, probe, vpath;
+
+ /* Build the path, using the inheritance chain and record of
+ virtual inheritance. */
+ for (path = NULL_TREE, probe = binfo, vpath = ffod->vpath;;)
{
- method = look_for_overrides_here (BINFO_TYPE (TREE_VALUE (path)),
- ffod->fn);
+ path = tree_cons (NULL_TREE, probe, path);
+ if (same_type_p (BINFO_TYPE (probe), ffod->most_derived_type))
+ break;
+ if (TREE_VIA_VIRTUAL (probe))
+ {
+ probe = TREE_VALUE (vpath);
+ vpath = TREE_CHAIN (vpath);
+ }
+ else
+ probe = BINFO_INHERITANCE_CHAIN (probe);
+ }
+ /* Now walk path, looking for overrides. */
+ for (; path; path = TREE_CHAIN (path))
+ {
+ tree method = look_for_overrides_here
+ (BINFO_TYPE (TREE_VALUE (path)), ffod->fn);
+
if (method)
{
+ tree *candidate = &ffod->candidates;
path = TREE_VALUE (path);
+
+ /* Remove any candidates overridden by this new function. */
+ while (*candidate)
+ {
+ /* If *CANDIDATE overrides METHOD, then METHOD
+ cannot override anything else on the list. */
+ if (base_derived_from (TREE_VALUE (*candidate), path))
+ return NULL_TREE;
+ /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */
+ if (base_derived_from (path, TREE_VALUE (*candidate)))
+ *candidate = TREE_CHAIN (*candidate);
+ else
+ candidate = &TREE_CHAIN (*candidate);
+ }
+
+ /* Add the new function. */
+ ffod->candidates = tree_cons (method, path, ffod->candidates);
break;
}
-
- path = TREE_CHAIN (path);
}
+ }
- /* If we found an overrider, record the overriding function, and
- the base from which it came. */
- if (path)
- {
- tree *candidate;
+ return NULL_TREE;
+}
- /* Remove any candidates overridden by this new function. */
- candidate = &ffod->candidates;
- while (*candidate)
- {
- /* If *CANDIDATE overrides METHOD, then METHOD
- cannot override anything else on the list. */
- if (base_derived_from (TREE_VALUE (*candidate), path))
- return NULL_TREE;
- /* If METHOD overrides *CANDIDATE, remove *CANDIDATE. */
- if (base_derived_from (path, TREE_VALUE (*candidate)))
- *candidate = TREE_CHAIN (*candidate);
- else
- candidate = &TREE_CHAIN (*candidate);
- }
+static tree
+dfs_find_final_overrider_q (tree derived, int ix, void *data)
+{
+ tree binfo = BINFO_BASETYPE (derived, ix);
+ find_final_overrider_data *ffod = (find_final_overrider_data *) data;
- /* Add the new function. */
- ffod->candidates = tree_cons (method, path, ffod->candidates);
- }
- }
+ if (TREE_VIA_VIRTUAL (binfo))
+ ffod->vpath = tree_cons (NULL_TREE, derived, ffod->vpath);
+
+ return binfo;
+}
+static tree
+dfs_find_final_overrider_post (tree binfo, void *data)
+{
+ find_final_overrider_data *ffod = (find_final_overrider_data *) data;
+
+ if (TREE_VIA_VIRTUAL (binfo) && TREE_CHAIN (ffod->vpath))
+ ffod->vpath = TREE_CHAIN (ffod->vpath);
+
return NULL_TREE;
}
@@ -2324,10 +1952,7 @@ dfs_find_final_overrider (binfo, data)
DERIVED) is the base object in which FN is declared. */
static tree
-find_final_overrider (derived, binfo, fn)
- tree derived;
- tree binfo;
- tree fn;
+find_final_overrider (tree derived, tree binfo, tree fn)
{
find_final_overrider_data ffod;
@@ -2349,15 +1974,20 @@ find_final_overrider (derived, binfo, fn)
The solution is to look at all paths to BINFO. If we find
different overriders along any two, then there is a problem. */
+ if (DECL_THUNK_P (fn))
+ fn = THUNK_TARGET (fn);
+
ffod.fn = fn;
ffod.declaring_base = binfo;
ffod.most_derived_type = BINFO_TYPE (derived);
ffod.candidates = NULL_TREE;
+ ffod.vpath = NULL_TREE;
- dfs_walk (derived,
- dfs_find_final_overrider,
- NULL,
- &ffod);
+ dfs_walk_real (derived,
+ dfs_find_final_overrider,
+ dfs_find_final_overrider_post,
+ dfs_find_final_overrider_q,
+ &ffod);
/* If there was no winner, issue an error message. */
if (!ffod.candidates || TREE_CHAIN (ffod.candidates))
@@ -2390,21 +2020,21 @@ get_vcall_index (tree fn, tree type)
}
/* Update an entry in the vtable for BINFO, which is in the hierarchy
- dominated by T. FN has been overriden in BINFO; VIRTUALS points to the
+ dominated by T. FN has been overridden in BINFO; VIRTUALS points to the
corresponding position in the BINFO_VIRTUALS list. */
static void
-update_vtable_entry_for_fn (t, binfo, fn, virtuals)
- tree t;
- tree binfo;
- tree fn;
- tree *virtuals;
+update_vtable_entry_for_fn (tree t, tree binfo, tree fn, tree* virtuals,
+ unsigned ix)
{
tree b;
tree overrider;
tree delta;
tree virtual_base;
tree first_defn;
+ tree overrider_fn, overrider_target;
+ tree target_fn = DECL_THUNK_P (fn) ? THUNK_TARGET (fn) : fn;
+ tree over_return, base_return;
bool lost = false;
/* Find the nearest primary base (possibly binfo itself) which defines
@@ -2412,7 +2042,8 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
calling FN through BINFO. */
for (b = binfo; ; b = get_primary_binfo (b))
{
- if (look_for_overrides_here (BINFO_TYPE (b), fn))
+ my_friendly_assert (b, 20021227);
+ if (look_for_overrides_here (BINFO_TYPE (b), target_fn))
break;
/* The nearest definition is from a lost primary. */
@@ -2422,14 +2053,92 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
first_defn = b;
/* Find the final overrider. */
- overrider = find_final_overrider (TYPE_BINFO (t), b, fn);
+ overrider = find_final_overrider (TYPE_BINFO (t), b, target_fn);
if (overrider == error_mark_node)
return;
+ overrider_target = overrider_fn = TREE_PURPOSE (overrider);
+
+ /* Check for adjusting covariant return types. */
+ over_return = TREE_TYPE (TREE_TYPE (overrider_target));
+ base_return = TREE_TYPE (TREE_TYPE (target_fn));
+
+ if (POINTER_TYPE_P (over_return)
+ && TREE_CODE (over_return) == TREE_CODE (base_return)
+ && CLASS_TYPE_P (TREE_TYPE (over_return))
+ && CLASS_TYPE_P (TREE_TYPE (base_return)))
+ {
+ /* If FN is a covariant thunk, we must figure out the adjustment
+ to the final base FN was converting to. As OVERRIDER_TARGET might
+ also be converting to the return type of FN, we have to
+ combine the two conversions here. */
+ tree fixed_offset, virtual_offset;
+
+ if (DECL_THUNK_P (fn))
+ {
+ my_friendly_assert (DECL_RESULT_THUNK_P (fn), 20031211);
+ fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn));
+ virtual_offset = THUNK_VIRTUAL_OFFSET (fn);
+ }
+ else
+ fixed_offset = virtual_offset = NULL_TREE;
+
+ if (virtual_offset)
+ /* Find the equivalent binfo within the return type of the
+ overriding function. We will want the vbase offset from
+ there. */
+ virtual_offset =
+ TREE_VALUE (purpose_member
+ (BINFO_TYPE (virtual_offset),
+ CLASSTYPE_VBASECLASSES (TREE_TYPE (over_return))));
+ else if (!same_type_p (TREE_TYPE (over_return),
+ TREE_TYPE (base_return)))
+ {
+ /* There was no existing virtual thunk (which takes
+ precedence). */
+ tree thunk_binfo;
+ base_kind kind;
+
+ thunk_binfo = lookup_base (TREE_TYPE (over_return),
+ TREE_TYPE (base_return),
+ ba_check | ba_quiet, &kind);
- /* Check for unsupported covariant returns again now that we've
- calculated the base offsets. */
- check_final_overrider (TREE_PURPOSE (overrider), fn);
+ if (thunk_binfo && (kind == bk_via_virtual
+ || !BINFO_OFFSET_ZEROP (thunk_binfo)))
+ {
+ tree offset = convert (ssizetype, BINFO_OFFSET (thunk_binfo));
+ if (kind == bk_via_virtual)
+ {
+ /* We convert via virtual base. Find the virtual
+ base and adjust the fixed offset to be from there. */
+ while (!TREE_VIA_VIRTUAL (thunk_binfo))
+ thunk_binfo = BINFO_INHERITANCE_CHAIN (thunk_binfo);
+
+ virtual_offset = thunk_binfo;
+ offset = size_diffop
+ (offset, convert
+ (ssizetype, BINFO_OFFSET (virtual_offset)));
+ }
+ if (fixed_offset)
+ /* There was an existing fixed offset, this must be
+ from the base just converted to, and the base the
+ FN was thunking to. */
+ fixed_offset = size_binop (PLUS_EXPR, fixed_offset, offset);
+ else
+ fixed_offset = offset;
+ }
+ }
+
+ if (fixed_offset || virtual_offset)
+ /* Replace the overriding function with a covariant thunk. We
+ will emit the overriding function in its own slot as
+ well. */
+ overrider_fn = make_thunk (overrider_target, /*this_adjusting=*/0,
+ fixed_offset, virtual_offset);
+ }
+ else
+ my_friendly_assert (!DECL_THUNK_P (fn), 20021231);
+
/* Assume that we will produce a thunk that convert all the way to
the final overrider, and not to an intermediate virtual base. */
virtual_base = NULL_TREE;
@@ -2447,18 +2156,51 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
/* If we find a virtual base, and we haven't yet found the
overrider, then there is a virtual base between the
declaring base (first_defn) and the final overrider. */
- if (!virtual_base && TREE_VIA_VIRTUAL (b))
- virtual_base = b;
+ if (TREE_VIA_VIRTUAL (b))
+ {
+ virtual_base = b;
+ break;
+ }
}
+ if (overrider_fn != overrider_target && !virtual_base)
+ {
+ /* The ABI specifies that a covariant thunk includes a mangling
+ for a this pointer adjustment. This-adjusting thunks that
+ override a function from a virtual base have a vcall
+ adjustment. When the virtual base in question is a primary
+ virtual base, we know the adjustments are zero, (and in the
+ non-covariant case, we would not use the thunk).
+ Unfortunately we didn't notice this could happen, when
+ designing the ABI and so never mandated that such a covariant
+ thunk should be emitted. Because we must use the ABI mandated
+ name, we must continue searching from the binfo where we
+ found the most recent definition of the function, towards the
+ primary binfo which first introduced the function into the
+ vtable. If that enters a virtual base, we must use a vcall
+ this-adjusting thunk. Bleah! */
+ tree probe = first_defn;
+
+ while ((probe = get_primary_binfo (probe))
+ && (unsigned) list_length (BINFO_VIRTUALS (probe)) > ix)
+ if (TREE_VIA_VIRTUAL (probe))
+ virtual_base = probe;
+
+ if (virtual_base)
+ /* Even if we find a virtual base, the correct delta is
+ between the overrider and the binfo we're building a vtable
+ for. */
+ goto virtual_covariant;
+ }
+
/* Compute the constant adjustment to the `this' pointer. The
`this' pointer, when this function is called, will point at BINFO
(or one of its primary bases, which are at the same offset). */
if (virtual_base)
/* The `this' pointer needs to be adjusted from the declaration to
the nearest virtual base. */
- delta = size_diffop (BINFO_OFFSET (virtual_base),
- BINFO_OFFSET (first_defn));
+ delta = size_diffop (convert (ssizetype, BINFO_OFFSET (virtual_base)),
+ convert (ssizetype, BINFO_OFFSET (first_defn)));
else if (lost)
/* If the nearest definition is in a lost primary, we don't need an
entry in our vtable. Except possibly in a constructor vtable,
@@ -2469,27 +2211,22 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
/* The `this' pointer needs to be adjusted from pointing to
BINFO to pointing at the base where the final overrider
appears. */
- delta = size_diffop (BINFO_OFFSET (TREE_VALUE (overrider)),
- BINFO_OFFSET (binfo));
+ virtual_covariant:
+ delta = size_diffop (convert (ssizetype,
+ BINFO_OFFSET (TREE_VALUE (overrider))),
+ convert (ssizetype, BINFO_OFFSET (binfo)));
- modify_vtable_entry (t,
- binfo,
- TREE_PURPOSE (overrider),
- delta,
- virtuals);
+ modify_vtable_entry (t, binfo, overrider_fn, delta, virtuals);
if (virtual_base)
BV_VCALL_INDEX (*virtuals)
- = get_vcall_index (TREE_PURPOSE (overrider),
- BINFO_TYPE (virtual_base));
+ = get_vcall_index (overrider_target, BINFO_TYPE (virtual_base));
}
/* Called from modify_all_vtables via dfs_walk. */
static tree
-dfs_modify_vtables (binfo, data)
- tree binfo;
- void *data;
+dfs_modify_vtables (tree binfo, void* data)
{
if (/* There's no need to modify the vtable for a non-virtual
primary base; we're not going to use that vtable anyhow.
@@ -2499,29 +2236,28 @@ dfs_modify_vtables (binfo, data)
/* Similarly, a base without a vtable needs no modification. */
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
{
- tree t;
+ tree t = (tree) data;
tree virtuals;
tree old_virtuals;
-
- t = (tree) data;
-
+ unsigned ix;
+
make_new_vtable (t, binfo);
/* Now, go through each of the virtual functions in the virtual
function table for BINFO. Find the final overrider, and
update the BINFO_VIRTUALS list appropriately. */
- for (virtuals = BINFO_VIRTUALS (binfo),
+ for (ix = 0, virtuals = BINFO_VIRTUALS (binfo),
old_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
virtuals;
- virtuals = TREE_CHAIN (virtuals),
+ ix++, virtuals = TREE_CHAIN (virtuals),
old_virtuals = TREE_CHAIN (old_virtuals))
update_vtable_entry_for_fn (t,
binfo,
BV_FN (old_virtuals),
- &virtuals);
+ &virtuals, ix);
}
- SET_BINFO_MARKED (binfo);
+ BINFO_MARKED (binfo) = 1;
return NULL_TREE;
}
@@ -2536,19 +2272,14 @@ dfs_modify_vtables (binfo, data)
should therefore be appended to the end of the vtable for T. */
static tree
-modify_all_vtables (t, virtuals)
- tree t;
- tree virtuals;
+modify_all_vtables (tree t, tree virtuals)
{
tree binfo = TYPE_BINFO (t);
tree *fnsp;
/* Update all of the vtables. */
- dfs_walk (binfo,
- dfs_modify_vtables,
- dfs_unmarked_real_bases_queue_p,
- t);
- dfs_walk (binfo, dfs_unmark, dfs_marked_real_bases_queue_p, t);
+ dfs_walk (binfo, dfs_modify_vtables, unmarkedp, t);
+ dfs_walk (binfo, dfs_unmark, markedp, t);
/* Add virtual functions not already in our primary vtable. These
will be both those introduced by this class, and those overridden
@@ -2581,8 +2312,7 @@ modify_all_vtables (t, virtuals)
indicated NAME. */
static tree
-get_basefndecls (name, t)
- tree name, t;
+get_basefndecls (tree name, tree t)
{
tree methods;
tree base_fndecls = NULL_TREE;
@@ -2621,8 +2351,7 @@ get_basefndecls (name, t)
mark this field as being virtual as well. */
static void
-check_for_override (decl, ctype)
- tree decl, ctype;
+check_for_override (tree decl, tree ctype)
{
if (TREE_CODE (decl) == TEMPLATE_DECL)
/* In [temp.mem] we have:
@@ -2631,7 +2360,8 @@ check_for_override (decl, ctype)
override a virtual function from a base class. */
return;
if ((DECL_DESTRUCTOR_P (decl)
- || IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)))
+ || IDENTIFIER_VIRTUAL_P (DECL_NAME (decl))
+ || DECL_CONV_FN_P (decl))
&& look_for_overrides (ctype, decl)
&& !DECL_STATIC_FUNCTION_P (decl))
/* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor
@@ -2651,8 +2381,7 @@ check_for_override (decl, ctype)
We know that constructors and destructors don't apply. */
void
-warn_hidden (t)
- tree t;
+warn_hidden (tree t)
{
tree method_vec = CLASSTYPE_METHOD_VEC (t);
int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0;
@@ -2721,8 +2450,7 @@ warn_hidden (t)
things we should check for also. */
static void
-finish_struct_anon (t)
- tree t;
+finish_struct_anon (tree t)
{
tree field;
@@ -2751,10 +2479,6 @@ finish_struct_anon (t)
|| TYPE_ANONYMOUS_P (TREE_TYPE (elt))))
continue;
- if (DECL_NAME (elt) == constructor_name (t))
- cp_pedwarn_at ("ISO C++ forbids member `%D' with same name as enclosing class",
- elt);
-
if (TREE_CODE (elt) != FIELD_DECL)
{
cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members",
@@ -2787,10 +2511,7 @@ finish_struct_anon (t)
(FUNCTION_DECL, TEMPLATE_DECL). */
void
-maybe_add_class_template_decl_list (type, t, friend_p)
- tree type;
- tree t;
- int friend_p;
+maybe_add_class_template_decl_list (tree type, tree t, int friend_p)
{
/* Save some memory by not creating TREE_LIST if TYPE is not template. */
if (CLASSTYPE_TEMPLATE_INFO (type))
@@ -2809,13 +2530,10 @@ maybe_add_class_template_decl_list (type, t, friend_p)
DECL is returned; otherwise the return value is NULL_TREE. */
static void
-add_implicitly_declared_members (t, cant_have_default_ctor,
- cant_have_const_cctor,
- cant_have_const_assignment)
- tree t;
- int cant_have_default_ctor;
- int cant_have_const_cctor;
- int cant_have_const_assignment;
+add_implicitly_declared_members (tree t,
+ int cant_have_default_ctor,
+ int cant_have_const_cctor,
+ int cant_have_const_assignment)
{
tree default_fn;
tree implicit_fns = NULL_TREE;
@@ -2906,8 +2624,7 @@ add_implicitly_declared_members (t, cant_have_default_ctor,
in TYPE, including anonymous union members. */
static int
-count_fields (fields)
- tree fields;
+count_fields (tree fields)
{
tree x;
int n_fields = 0;
@@ -2922,20 +2639,18 @@ count_fields (fields)
}
/* Subroutine of finish_struct_1. Recursively add all the fields in the
- TREE_LIST FIELDS to the TREE_VEC FIELD_VEC, starting at offset IDX. */
+ TREE_LIST FIELDS to the SORTED_FIELDS_TYPE elts, starting at offset IDX. */
static int
-add_fields_to_vec (fields, field_vec, idx)
- tree fields, field_vec;
- int idx;
+add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, int idx)
{
tree x;
for (x = fields; x; x = TREE_CHAIN (x))
{
if (TREE_CODE (x) == FIELD_DECL && ANON_AGGR_TYPE_P (TREE_TYPE (x)))
- idx = add_fields_to_vec (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx);
+ idx = add_fields_to_record_type (TYPE_FIELDS (TREE_TYPE (x)), field_vec, idx);
else
- TREE_VEC_ELT (field_vec, idx++) = x;
+ field_vec->elts[idx++] = x;
}
return idx;
}
@@ -2945,8 +2660,7 @@ add_fields_to_vec (fields, field_vec, idx)
flags. */
static void
-check_bitfield_decl (field)
- tree field;
+check_bitfield_decl (tree field)
{
tree type = TREE_TYPE (field);
tree w = NULL_TREE;
@@ -3013,31 +2727,12 @@ check_bitfield_decl (field)
{
DECL_SIZE (field) = convert (bitsizetype, w);
DECL_BIT_FIELD (field) = 1;
-
- if (integer_zerop (w)
- && ! (* targetm.ms_bitfield_layout_p) (DECL_FIELD_CONTEXT (field)))
- {
-#ifdef EMPTY_FIELD_BOUNDARY
- DECL_ALIGN (field) = MAX (DECL_ALIGN (field),
- EMPTY_FIELD_BOUNDARY);
-#endif
-#ifdef PCC_BITFIELD_TYPE_MATTERS
- if (PCC_BITFIELD_TYPE_MATTERS)
- {
- DECL_ALIGN (field) = MAX (DECL_ALIGN (field),
- TYPE_ALIGN (type));
- DECL_USER_ALIGN (field) |= TYPE_USER_ALIGN (type);
- }
-#endif
- }
}
else
{
/* Non-bit-fields are aligned for their type. */
DECL_BIT_FIELD (field) = 0;
CLEAR_DECL_C_BIT_FIELD (field);
- DECL_ALIGN (field) = MAX (DECL_ALIGN (field), TYPE_ALIGN (type));
- DECL_USER_ALIGN (field) |= TYPE_USER_ALIGN (type);
}
}
@@ -3046,15 +2741,12 @@ check_bitfield_decl (field)
flags. */
static void
-check_field_decl (field, t, cant_have_const_ctor,
- cant_have_default_ctor, no_const_asn_ref,
- any_default_members)
- tree field;
- tree t;
- int *cant_have_const_ctor;
- int *cant_have_default_ctor;
- int *no_const_asn_ref;
- int *any_default_members;
+check_field_decl (tree field,
+ tree t,
+ int* cant_have_const_ctor,
+ int* cant_have_default_ctor,
+ int* no_const_asn_ref,
+ int* any_default_members)
{
tree type = strip_array_types (TREE_TYPE (field));
@@ -3118,7 +2810,7 @@ check_field_decl (field, t, cant_have_const_ctor,
/* `build_class_init_list' does not recognize
non-FIELD_DECLs. */
if (TREE_CODE (t) == UNION_TYPE && any_default_members != 0)
- cp_error_at ("multiple fields in union `%T' initialized");
+ error ("multiple fields in union `%T' initialized", t);
*any_default_members = 1;
}
}
@@ -3163,9 +2855,6 @@ check_field_decls (tree t, tree *access_decls,
int has_pointers;
int any_default_members;
- /* First, delete any duplicate fields. */
- delete_duplicate_fields (TYPE_FIELDS (t));
-
/* Assume there are no access declarations. */
*access_decls = NULL_TREE;
/* Assume this class has no pointer members. */
@@ -3183,7 +2872,15 @@ check_field_decls (tree t, tree *access_decls,
if (TREE_CODE (x) == FIELD_DECL)
{
- DECL_PACKED (x) |= TYPE_PACKED (t);
+ if (TYPE_PACKED (t))
+ {
+ if (!pod_type_p (TREE_TYPE (x)) && !TYPE_PACKED (TREE_TYPE (x)))
+ cp_warning_at
+ ("ignoring packed attribute on unpacked non-POD field `%#D'",
+ x);
+ else
+ DECL_PACKED (x) = 1;
+ }
if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
/* We don't treat zero-width bitfields as making a class
@@ -3226,9 +2923,30 @@ check_field_decls (tree t, tree *access_decls,
/* If we've gotten this far, it's a data member, possibly static,
or an enumerator. */
-
DECL_CONTEXT (x) = t;
+ /* When this goes into scope, it will be a non-local reference. */
+ DECL_NONLOCAL (x) = 1;
+
+ if (TREE_CODE (t) == UNION_TYPE)
+ {
+ /* [class.union]
+
+ If a union contains a static data member, or a member of
+ reference type, the program is ill-formed. */
+ if (TREE_CODE (x) == VAR_DECL)
+ {
+ cp_error_at ("`%D' may not be static because it is a member of a union", x);
+ continue;
+ }
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ cp_error_at ("`%D' may not have reference type `%T' because it is a member of a union",
+ x, type);
+ continue;
+ }
+ }
+
/* ``A local class cannot have static data members.'' ARM 9.4 */
if (current_function_decl && TREE_STATIC (x))
cp_error_at ("field `%D' in local class cannot be static", x);
@@ -3248,31 +2966,13 @@ check_field_decls (tree t, tree *access_decls,
type = build_pointer_type (type);
TREE_TYPE (x) = type;
}
- else if (TREE_CODE (type) == OFFSET_TYPE)
- {
- cp_error_at ("field `%D' invalidly declared offset type", x);
- type = build_pointer_type (type);
- TREE_TYPE (x) = type;
- }
if (type == error_mark_node)
continue;
- /* When this goes into scope, it will be a non-local reference. */
- DECL_NONLOCAL (x) = 1;
-
- if (TREE_CODE (x) == CONST_DECL)
+ if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL)
continue;
- if (TREE_CODE (x) == VAR_DECL)
- {
- if (TREE_CODE (t) == UNION_TYPE)
- /* Unions cannot have static members. */
- cp_error_at ("field `%D' declared static in union", x);
-
- continue;
- }
-
/* Now it can only be a FIELD_DECL. */
if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
@@ -3300,9 +3000,17 @@ check_field_decls (tree t, tree *access_decls,
type = strip_array_types (type);
- if (TREE_CODE (type) == POINTER_TYPE)
+ if (TYPE_PTR_P (type))
has_pointers = 1;
+ if (CLASS_TYPE_P (type))
+ {
+ if (CLASSTYPE_REF_FIELDS_NEED_INIT (type))
+ SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
+ if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))
+ SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
+ }
+
if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
CLASSTYPE_HAS_MUTABLE (t) = 1;
@@ -3333,7 +3041,7 @@ check_field_decls (tree t, tree *access_decls,
cp_warning_at ("non-static const member `%#D' in class without a constructor", x);
}
/* A field that is pseudo-const makes the structure likewise. */
- else if (IS_AGGR_TYPE (type))
+ else if (CLASS_TYPE_P (type))
{
C_TYPE_FIELDS_READONLY (t) |= C_TYPE_FIELDS_READONLY (type);
SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t,
@@ -3344,8 +3052,7 @@ check_field_decls (tree t, tree *access_decls,
/* Core issue 80: A nonstatic data member is required to have a
different name from the class iff the class has a
user-defined constructor. */
- if (DECL_NAME (x) == constructor_name (t)
- && TYPE_HAS_CONSTRUCTOR (t))
+ if (constructor_name_p (DECL_NAME (x), t) && TYPE_HAS_CONSTRUCTOR (t))
cp_pedwarn_at ("field `%#D' with same name as class", x);
/* We set DECL_C_BIT_FIELD in grokbitfield.
@@ -3389,10 +3096,7 @@ check_field_decls (tree t, tree *access_decls,
OFFSETS. */
static int
-record_subobject_offset (type, offset, offsets)
- tree type;
- tree offset;
- splay_tree offsets;
+record_subobject_offset (tree type, tree offset, splay_tree offsets)
{
splay_tree_node n;
@@ -3417,10 +3121,7 @@ record_subobject_offset (type, offset, offsets)
already an entry in OFFSETS for the same TYPE as the same OFFSET. */
static int
-check_subobject_offset (type, offset, offsets)
- tree type;
- tree offset;
- splay_tree offsets;
+check_subobject_offset (tree type, tree offset, splay_tree offsets)
{
splay_tree_node n;
tree t;
@@ -3452,13 +3153,12 @@ check_subobject_offset (type, offset, offsets)
is returned. Otherwise, returns zero. */
static int
-walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p)
- tree type;
- subobject_offset_fn f;
- tree offset;
- splay_tree offsets;
- tree max_offset;
- int vbases_p;
+walk_subobject_offsets (tree type,
+ subobject_offset_fn f,
+ tree offset,
+ splay_tree offsets,
+ tree max_offset,
+ int vbases_p)
{
int r = 0;
tree type_binfo = NULL_TREE;
@@ -3567,22 +3267,14 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p)
virtual. (If it is non-virtual, then it was walked
above.) */
vbase = get_primary_binfo (type_binfo);
- if (vbase && TREE_VIA_VIRTUAL (vbase))
+ if (vbase && TREE_VIA_VIRTUAL (vbase)
+ && BINFO_PRIMARY_BASE_OF (vbase) == type_binfo)
{
- tree derived = type_binfo;
- while (BINFO_INHERITANCE_CHAIN (derived))
- derived = BINFO_INHERITANCE_CHAIN (derived);
- derived = TREE_TYPE (derived);
- vbase = binfo_for_vbase (TREE_TYPE (vbase), derived);
-
- if (BINFO_PRIMARY_BASE_OF (vbase) == type_binfo)
- {
- r = (walk_subobject_offsets
- (vbase, f, offset,
- offsets, max_offset, /*vbases_p=*/0));
- if (r)
- return r;
- }
+ r = (walk_subobject_offsets
+ (vbase, f, offset,
+ offsets, max_offset, /*vbases_p=*/0));
+ if (r)
+ return r;
}
}
}
@@ -3656,11 +3348,10 @@ walk_subobject_offsets (type, f, offset, offsets, max_offset, vbases_p)
examined. */
static void
-record_subobject_offsets (type, offset, offsets, vbases_p)
- tree type;
- tree offset;
- splay_tree offsets;
- int vbases_p;
+record_subobject_offsets (tree type,
+ tree offset,
+ splay_tree offsets,
+ int vbases_p)
{
walk_subobject_offsets (type, record_subobject_offset, offset,
offsets, /*max_offset=*/NULL_TREE, vbases_p);
@@ -3671,11 +3362,10 @@ record_subobject_offsets (type, offset, offsets, vbases_p)
virtual bases of TYPE are examined. */
static int
-layout_conflict_p (type, offset, offsets, vbases_p)
- tree type;
- tree offset;
- splay_tree offsets;
- int vbases_p;
+layout_conflict_p (tree type,
+ tree offset,
+ splay_tree offsets,
+ int vbases_p)
{
splay_tree_node max_node;
@@ -3704,7 +3394,6 @@ layout_nonempty_base_or_field (record_layout_info rli,
tree binfo,
splay_tree offsets)
{
- tree t = rli->t;
tree offset = NULL_TREE;
bool field_p;
tree type;
@@ -3734,14 +3423,14 @@ layout_nonempty_base_or_field (record_layout_info rli,
/* Place this field. */
place_field (rli, decl);
offset = byte_position (decl);
-
+
/* We have to check to see whether or not there is already
something of the same type at the offset we're about to use.
- For example:
+ For example, consider:
- struct S {};
- struct T : public S { int i; };
- struct U : public S, public T {};
+ struct S {};
+ struct T : public S { int i; };
+ struct U : public S, public T {};
Here, we put S at offset zero in U. Then, we can't put T at
offset zero -- its S component would be at the same address
@@ -3750,6 +3439,10 @@ layout_nonempty_base_or_field (record_layout_info rli,
empty class, have nonzero size, any overlap can happen only
with a direct or indirect base-class -- it can't happen with
a data member. */
+ /* In a union, overlap is permitted; all members are placed at
+ offset zero. */
+ if (TREE_CODE (rli->t) == UNION_TYPE)
+ break;
/* G++ 3.2 did not check for overlaps when placing a non-empty
virtual base. */
if (!abi_version_at_least (2) && binfo && TREE_VIA_VIRTUAL (binfo))
@@ -3785,8 +3478,7 @@ layout_nonempty_base_or_field (record_layout_info rli,
propagate_binfo_offsets (binfo,
size_diffop (convert (ssizetype, offset),
convert (ssizetype,
- BINFO_OFFSET (binfo))),
- t);
+ BINFO_OFFSET (binfo))));
}
/* Returns true if TYPE is empty and OFFSET is nonzero. */
@@ -3806,11 +3498,7 @@ empty_base_at_nonzero_offset_p (tree type,
type. Return nonzero iff we added it at the end. */
static bool
-layout_empty_base (binfo, eoc, offsets, t)
- tree binfo;
- tree eoc;
- splay_tree offsets;
- tree t;
+layout_empty_base (tree binfo, tree eoc, splay_tree offsets)
{
tree alignment;
tree basetype = BINFO_TYPE (binfo);
@@ -3819,14 +3507,18 @@ layout_empty_base (binfo, eoc, offsets, t)
/* This routine should only be used for empty classes. */
my_friendly_assert (is_empty_class (basetype), 20000321);
alignment = ssize_int (CLASSTYPE_ALIGN_UNIT (basetype));
-
- if (abi_version_at_least (2))
- BINFO_OFFSET (binfo) = size_zero_node;
- if (warn_abi && !integer_zerop (BINFO_OFFSET (binfo)))
- warning ("offset of empty base `%T' may not be ABI-compliant and may"
- "change in a future version of GCC",
- BINFO_TYPE (binfo));
+ if (!integer_zerop (BINFO_OFFSET (binfo)))
+ {
+ if (abi_version_at_least (2))
+ propagate_binfo_offsets
+ (binfo, size_diffop (size_zero_node, BINFO_OFFSET (binfo)));
+ else if (warn_abi)
+ warning ("offset of empty base `%T' may not be ABI-compliant and may"
+ "change in a future version of GCC",
+ BINFO_TYPE (binfo));
+ }
+
/* This is an empty base class. We first try to put it at offset
zero. */
if (layout_conflict_p (binfo,
@@ -3837,7 +3529,7 @@ layout_empty_base (binfo, eoc, offsets, t)
/* That didn't work. Now, we move forward from the next
available spot in the class. */
atend = true;
- propagate_binfo_offsets (binfo, convert (ssizetype, eoc), t);
+ propagate_binfo_offsets (binfo, convert (ssizetype, eoc));
while (1)
{
if (!layout_conflict_p (binfo,
@@ -3848,7 +3540,7 @@ layout_empty_base (binfo, eoc, offsets, t)
break;
/* There's overlap here, too. Bump along to the next spot. */
- propagate_binfo_offsets (binfo, alignment, t);
+ propagate_binfo_offsets (binfo, alignment);
}
}
return atend;
@@ -3912,7 +3604,7 @@ build_base_field (record_layout_info rli, tree binfo,
byte-aligned. */
eoc = round_up (rli_size_unit_so_far (rli),
CLASSTYPE_ALIGN_UNIT (basetype));
- atend = layout_empty_base (binfo, eoc, offsets, t);
+ atend = layout_empty_base (binfo, eoc, offsets);
/* A nearly-empty class "has no proper base class that is empty,
not morally virtual, and at an offset other than zero." */
if (!TREE_VIA_VIRTUAL (binfo) && CLASSTYPE_NEARLY_EMPTY_P (t))
@@ -3991,11 +3683,9 @@ build_base_fields (record_layout_info rli,
if (base_binfo == CLASSTYPE_PRIMARY_BINFO (t))
continue;
- /* A primary virtual base class is allocated just like any other
- base class, but a non-primary virtual base is allocated
- later, in layout_virtual_bases. */
- if (TREE_VIA_VIRTUAL (base_binfo)
- && !BINFO_PRIMARY_P (base_binfo))
+ /* Virtual bases are added at the end (a primary virtual base
+ will have already been added). */
+ if (TREE_VIA_VIRTUAL (base_binfo))
continue;
next_field = build_base_field (rli, base_binfo,
@@ -4008,8 +3698,7 @@ build_base_fields (record_layout_info rli,
methods, and so forth. */
static void
-check_methods (t)
- tree t;
+check_methods (tree t)
{
tree x;
@@ -4041,9 +3730,7 @@ check_methods (t)
NAME. */
static tree
-build_clone (fn, name)
- tree fn;
- tree name;
+build_clone (tree fn, tree name)
{
tree parms;
tree clone;
@@ -4092,12 +3779,15 @@ build_clone (fn, name)
/* If this is subobject constructor or destructor, add the vtt
parameter. */
TREE_TYPE (clone)
- = build_cplus_method_type (basetype,
- TREE_TYPE (TREE_TYPE (clone)),
- parmtypes);
+ = build_method_type_directly (basetype,
+ TREE_TYPE (TREE_TYPE (clone)),
+ parmtypes);
if (exceptions)
TREE_TYPE (clone) = build_exception_variant (TREE_TYPE (clone),
exceptions);
+ TREE_TYPE (clone)
+ = cp_build_type_attribute_variant (TREE_TYPE (clone),
+ TYPE_ATTRIBUTES (TREE_TYPE (fn)));
}
/* Copy the function parameters. But, DECL_ARGUMENTS on a TEMPLATE_DECL
@@ -4162,9 +3852,7 @@ build_clone (fn, name)
CLASTYPE_METHOD_VEC as well. */
void
-clone_function_decl (fn, update_method_vec_p)
- tree fn;
- int update_method_vec_p;
+clone_function_decl (tree fn, int update_method_vec_p)
{
tree clone;
@@ -4223,8 +3911,7 @@ clone_function_decl (fn, update_method_vec_p)
clones. */
void
-adjust_clone_args (decl)
- tree decl;
+adjust_clone_args (tree decl)
{
tree clone;
@@ -4274,9 +3961,9 @@ adjust_clone_args (decl)
clone_parms);
TREE_TYPE (clone_parms) = TREE_TYPE (orig_clone_parms);
}
- type = build_cplus_method_type (basetype,
- TREE_TYPE (TREE_TYPE (clone)),
- clone_parms);
+ type = build_method_type_directly (basetype,
+ TREE_TYPE (TREE_TYPE (clone)),
+ clone_parms);
if (exceptions)
type = build_exception_variant (type, exceptions);
TREE_TYPE (clone) = type;
@@ -4293,8 +3980,7 @@ adjust_clone_args (decl)
in-charge and not-in-charge variant. */
static void
-clone_constructors_and_destructors (t)
- tree t;
+clone_constructors_and_destructors (tree t)
{
tree fns;
@@ -4312,8 +3998,7 @@ clone_constructors_and_destructors (t)
/* Remove all zero-width bit-fields from T. */
static void
-remove_zero_width_bit_fields (t)
- tree t;
+remove_zero_width_bit_fields (tree t)
{
tree *fieldsp;
@@ -4333,8 +4018,7 @@ remove_zero_width_bit_fields (t)
array whose elements have the indicated class TYPE. */
static bool
-type_requires_array_cookie (type)
- tree type;
+type_requires_array_cookie (tree type)
{
tree fns;
bool has_two_argument_delete_p = false;
@@ -4476,9 +4160,7 @@ check_bases_and_members (tree t)
on VIRTUALS_P. */
static tree
-create_vtable_ptr (t, virtuals_p)
- tree t;
- tree *virtuals_p;
+create_vtable_ptr (tree t, tree* virtuals_p)
{
tree fn;
@@ -4512,7 +4194,7 @@ create_vtable_ptr (t, virtuals_p)
type-based alias analysis code would decide that assignments
to the base class vtable pointer can't alias assignments to
the derived class vtable pointer, since they have different
- types. Thus, in an derived class destructor, where the base
+ types. Thus, in a derived class destructor, where the base
class constructor was inlined, we could generate bad code for
setting up the vtable pointer.
@@ -4529,8 +4211,6 @@ create_vtable_ptr (t, virtuals_p)
DECL_ARTIFICIAL (field) = 1;
DECL_FIELD_CONTEXT (field) = t;
DECL_FCONTEXT (field) = t;
- DECL_ALIGN (field) = TYPE_ALIGN (vtbl_ptr_type_node);
- DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (vtbl_ptr_type_node);
TYPE_VFIELD (t) = field;
@@ -4554,8 +4234,7 @@ create_vtable_ptr (t, virtuals_p)
complete. */
static void
-fixup_pending_inline (fn)
- tree fn;
+fixup_pending_inline (tree fn)
{
if (DECL_PENDING_INLINE_INFO (fn))
{
@@ -4572,8 +4251,7 @@ fixup_pending_inline (fn)
complete. */
static void
-fixup_inline_methods (type)
- tree type;
+fixup_inline_methods (tree type)
{
tree method = TYPE_METHODS (type);
@@ -4605,10 +4283,7 @@ fixup_inline_methods (type)
OFFSET, which is a type offset, is number of bytes. */
static void
-propagate_binfo_offsets (binfo, offset, t)
- tree binfo;
- tree offset;
- tree t;
+propagate_binfo_offsets (tree binfo, tree offset)
{
int i;
tree primary_binfo;
@@ -4649,39 +4324,11 @@ propagate_binfo_offsets (binfo, offset, t)
/* Skip virtual bases that aren't our canonical primary base. */
if (TREE_VIA_VIRTUAL (base_binfo)
- && (BINFO_PRIMARY_BASE_OF (base_binfo) != binfo
- || base_binfo != binfo_for_vbase (BINFO_TYPE (base_binfo), t)))
+ && BINFO_PRIMARY_BASE_OF (base_binfo) != binfo)
continue;
- propagate_binfo_offsets (base_binfo, offset, t);
- }
-}
-
-/* Called via dfs_walk from layout_virtual bases. */
-
-static tree
-dfs_set_offset_for_unshared_vbases (binfo, data)
- tree binfo;
- void *data;
-{
- /* If this is a virtual base, make sure it has the same offset as
- the shared copy. If it's a primary base, then we know it's
- correct. */
- if (TREE_VIA_VIRTUAL (binfo))
- {
- tree t = (tree) data;
- tree vbase;
- tree offset;
-
- vbase = binfo_for_vbase (BINFO_TYPE (binfo), t);
- if (vbase != binfo)
- {
- offset = size_diffop (BINFO_OFFSET (vbase), BINFO_OFFSET (binfo));
- propagate_binfo_offsets (binfo, offset, t);
- }
+ propagate_binfo_offsets (base_binfo, offset);
}
-
- return NULL_TREE;
}
/* Set BINFO_OFFSET for all of the virtual bases for RLI->T. Update
@@ -4691,7 +4338,7 @@ dfs_set_offset_for_unshared_vbases (binfo, data)
static void
layout_virtual_bases (record_layout_info rli, splay_tree offsets)
{
- tree vbases;
+ tree vbase;
tree t = rli->t;
bool first_vbase = true;
tree *next_field;
@@ -4707,7 +4354,7 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets)
#ifdef STRUCTURE_SIZE_BOUNDARY
/* Packed structures don't need to have minimum size. */
if (! TYPE_PACKED (t))
- TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), STRUCTURE_SIZE_BOUNDARY);
+ TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), (unsigned) STRUCTURE_SIZE_BOUNDARY);
#endif
rli->offset = TYPE_SIZE_UNIT (t);
rli->bitpos = bitsize_zero_node;
@@ -4723,17 +4370,11 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets)
/* Go through the virtual bases, allocating space for each virtual
base that is not already a primary base class. These are
allocated in inheritance graph order. */
- for (vbases = TYPE_BINFO (t);
- vbases;
- vbases = TREE_CHAIN (vbases))
+ for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
{
- tree vbase;
-
- if (!TREE_VIA_VIRTUAL (vbases))
+ if (!TREE_VIA_VIRTUAL (vbase))
continue;
- vbase = binfo_for_vbase (BINFO_TYPE (vbases), t);
-
if (!BINFO_PRIMARY_P (vbase))
{
tree basetype = TREE_TYPE (vbase);
@@ -4764,13 +4405,6 @@ layout_virtual_bases (record_layout_info rli, splay_tree offsets)
first_vbase = false;
}
}
-
- /* Now, go through the TYPE_BINFO hierarchy, setting the
- BINFO_OFFSETs correctly for all non-primary copies of the virtual
- bases and their direct and indirect bases. The ambiguity checks
- in lookup_base depend on the BINFO_OFFSETs being set
- correctly. */
- dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t);
}
/* Returns the offset of the byte just past the end of the base class
@@ -4797,9 +4431,7 @@ end_of_base (tree binfo)
only non-virtual bases are included. */
static tree
-end_of_class (t, include_virtuals_p)
- tree t;
- int include_virtuals_p;
+end_of_class (tree t, int include_virtuals_p)
{
tree result = size_zero_node;
tree binfo;
@@ -4845,8 +4477,7 @@ end_of_class (t, include_virtuals_p)
subobjects of U. */
static void
-warn_about_ambiguous_bases (t)
- tree t;
+warn_about_ambiguous_bases (tree t)
{
int i;
tree vbases;
@@ -4879,9 +4510,7 @@ warn_about_ambiguous_bases (t)
/* Compare two INTEGER_CSTs K1 and K2. */
static int
-splay_tree_compare_integer_csts (k1, k2)
- splay_tree_key k1;
- splay_tree_key k2;
+splay_tree_compare_integer_csts (splay_tree_key k1, splay_tree_key k2)
{
return tree_int_cst_compare ((tree) k1, (tree) k2);
}
@@ -4906,7 +4535,19 @@ include_empty_classes (record_layout_info rli)
if (TREE_CODE (rli_size) == INTEGER_CST
&& INT_CST_LT_UNSIGNED (rli_size, eoc))
{
- rli->bitpos = round_up (rli->bitpos, BITS_PER_UNIT);
+ if (!abi_version_at_least (2))
+ /* In version 1 of the ABI, the size of a class that ends with
+ a bitfield was not rounded up to a whole multiple of a
+ byte. Because rli_size_unit_so_far returns only the number
+ of fully allocated bytes, any extra bits were not included
+ in the size. */
+ rli->bitpos = round_down (rli->bitpos, BITS_PER_UNIT);
+ else
+ /* The size should have been rounded to a whole byte. */
+ my_friendly_assert (tree_int_cst_equal (rli->bitpos,
+ round_down (rli->bitpos,
+ BITS_PER_UNIT)),
+ 20030903);
rli->bitpos
= size_binop (PLUS_EXPR,
rli->bitpos,
@@ -4996,6 +4637,8 @@ layout_class_type (tree t, tree *virtuals_p)
}
type = TREE_TYPE (field);
+
+ padding = NULL_TREE;
/* If this field is a bit-field whose width is greater than its
type, then there are some special rules for allocating
@@ -5005,7 +4648,7 @@ layout_class_type (tree t, tree *virtuals_p)
{
integer_type_kind itk;
tree integer_type;
-
+ bool was_unnamed_p = false;
/* We must allocate the bits as if suitably aligned for the
longest integer type that fits in this many bits. type
of the field. Then, we are supposed to use the left over
@@ -5020,25 +4663,47 @@ layout_class_type (tree t, tree *virtuals_p)
type that fits. */
integer_type = integer_types[itk - 1];
- if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE)
- /* In a union, the padding field must have the full width
- of the bit-field; all fields start at offset zero. */
- padding = DECL_SIZE (field);
- else
+ /* Figure out how much additional padding is required. GCC
+ 3.2 always created a padding field, even if it had zero
+ width. */
+ if (!abi_version_at_least (2)
+ || INT_CST_LT (TYPE_SIZE (integer_type), DECL_SIZE (field)))
+ {
+ if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE)
+ /* In a union, the padding field must have the full width
+ of the bit-field; all fields start at offset zero. */
+ padding = DECL_SIZE (field);
+ else
+ {
+ if (warn_abi && TREE_CODE (t) == UNION_TYPE)
+ warning ("size assigned to `%T' may not be "
+ "ABI-compliant and may change in a future "
+ "version of GCC",
+ t);
+ padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
+ TYPE_SIZE (integer_type));
+ }
+ }
+#ifdef PCC_BITFIELD_TYPE_MATTERS
+ /* An unnamed bitfield does not normally affect the
+ alignment of the containing class on a target where
+ PCC_BITFIELD_TYPE_MATTERS. But, the C++ ABI does not
+ make any exceptions for unnamed bitfields when the
+ bitfields are longer than their types. Therefore, we
+ temporarily give the field a name. */
+ if (PCC_BITFIELD_TYPE_MATTERS && !DECL_NAME (field))
{
- if (warn_abi && TREE_CODE (t) == UNION_TYPE)
- warning ("size assigned to `%T' may not be "
- "ABI-compliant and may change in a future "
- "version of GCC",
- t);
- padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
- TYPE_SIZE (integer_type));
+ was_unnamed_p = true;
+ DECL_NAME (field) = make_anon_name ();
}
+#endif
DECL_SIZE (field) = TYPE_SIZE (integer_type);
DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
layout_nonempty_base_or_field (rli, field, NULL_TREE,
empty_base_offsets);
+ if (was_unnamed_p)
+ DECL_NAME (field) = NULL_TREE;
/* Now that layout has been performed, set the size of the
field to the size of its declared type; the rest of the
field is effectively invisible. */
@@ -5054,11 +4719,8 @@ layout_class_type (tree t, tree *virtuals_p)
"change in a future version of GCC", field);
}
else
- {
- padding = NULL_TREE;
- layout_nonempty_base_or_field (rli, field, NULL_TREE,
- empty_base_offsets);
- }
+ layout_nonempty_base_or_field (rli, field, NULL_TREE,
+ empty_base_offsets);
/* Remember the location of any empty classes in FIELD. */
if (abi_version_at_least (2))
@@ -5101,8 +4763,8 @@ layout_class_type (tree t, tree *virtuals_p)
char_type_node);
DECL_BIT_FIELD (padding_field) = 1;
DECL_SIZE (padding_field) = padding;
- DECL_ALIGN (padding_field) = 1;
- DECL_USER_ALIGN (padding_field) = 0;
+ DECL_CONTEXT (padding_field) = t;
+ DECL_ARTIFICIAL (padding_field) = 1;
layout_nonempty_base_or_field (rli, padding_field,
NULL_TREE,
empty_base_offsets);
@@ -5189,6 +4851,8 @@ layout_class_type (tree t, tree *virtuals_p)
DECL_FIELD_OFFSET (*next_field) = DECL_FIELD_OFFSET (field);
DECL_FIELD_BIT_OFFSET (*next_field)
= DECL_FIELD_BIT_OFFSET (field);
+ DECL_SIZE (*next_field) = DECL_SIZE (field);
+ DECL_MODE (*next_field) = DECL_MODE (field);
next_field = &TREE_CHAIN (*next_field);
}
@@ -5261,8 +4925,7 @@ key_method (tree type)
is complete. */
void
-finish_struct_1 (t)
- tree t;
+finish_struct_1 (tree t)
{
tree x;
/* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */
@@ -5283,7 +4946,6 @@ finish_struct_1 (t)
/* If this type was previously laid out as a forward reference,
make sure we lay it out again. */
TYPE_SIZE (t) = NULL_TREE;
- CLASSTYPE_GOT_SEMICOLON (t) = 0;
CLASSTYPE_PRIMARY_BINFO (t) = NULL_TREE;
fixup_inline_methods (t);
@@ -5298,19 +4960,23 @@ finish_struct_1 (t)
bases and members and add implicitly generated methods. */
check_bases_and_members (t);
- /* Find the key method */
- if (TYPE_CONTAINS_VPTR_P (t))
+ /* Find the key method. */
+ if (TYPE_CONTAINS_VPTR_P (t))
{
CLASSTYPE_KEY_METHOD (t) = key_method (t);
/* If a polymorphic class has no key method, we may emit the vtable
- in every translation unit where the class definition appears. */
+ in every translation unit where the class definition appears. */
if (CLASSTYPE_KEY_METHOD (t) == NULL_TREE)
keyed_classes = tree_cons (NULL_TREE, t, keyed_classes);
}
/* Layout the class itself. */
layout_class_type (t, &virtuals);
+ if (CLASSTYPE_AS_BASE (t) != t)
+ /* We use the base type for trivial assignments, and hence it
+ needs a mode. */
+ compute_record_mode (CLASSTYPE_AS_BASE (t));
/* Make sure that we get our own copy of the vfield FIELD_DECL. */
vfield = TYPE_VFIELD (t);
@@ -5348,7 +5014,7 @@ finish_struct_1 (t)
/* We must enter these virtuals into the table. */
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
build_primary_vtable (NULL_TREE, t);
- else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t), t))
+ else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t)))
/* Here we know enough to change the type of our virtual
function table, but we will wait until later this function. */
build_primary_vtable (CLASSTYPE_PRIMARY_BINFO (t), t);
@@ -5375,8 +5041,17 @@ finish_struct_1 (t)
fn = TREE_CHAIN (fn),
vindex += (TARGET_VTABLE_USES_DESCRIPTORS
? TARGET_VTABLE_USES_DESCRIPTORS : 1))
- if (TREE_CODE (DECL_VINDEX (BV_FN (fn))) != INTEGER_CST)
- DECL_VINDEX (BV_FN (fn)) = build_shared_int_cst (vindex);
+ {
+ tree fndecl = BV_FN (fn);
+
+ if (DECL_THUNK_P (fndecl))
+ /* A thunk. We should never be calling this entry directly
+ from this vtable -- we'd use the entry for the non
+ thunk base function. */
+ DECL_VINDEX (fndecl) = NULL_TREE;
+ else if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST)
+ DECL_VINDEX (fndecl) = build_shared_int_cst (vindex);
+ }
}
finish_struct_bits (t);
@@ -5398,10 +5073,12 @@ finish_struct_1 (t)
n_fields = count_fields (TYPE_FIELDS (t));
if (n_fields > 7)
{
- tree field_vec = make_tree_vec (n_fields);
- add_fields_to_vec (TYPE_FIELDS (t), field_vec, 0);
- qsort (&TREE_VEC_ELT (field_vec, 0), n_fields, sizeof (tree),
- (int (*)(const void *, const void *))field_decl_cmp);
+ struct sorted_fields_type *field_vec = ggc_alloc (sizeof (struct sorted_fields_type)
+ + n_fields * sizeof (tree));
+ field_vec->len = n_fields;
+ add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0);
+ qsort (field_vec->elts, n_fields, sizeof (tree),
+ field_decl_cmp);
if (! DECL_LANG_SPECIFIC (TYPE_MAIN_DECL (t)))
retrofit_lang_decl (TYPE_MAIN_DECL (t));
DECL_SORTED_FIELDS (TYPE_MAIN_DECL (t)) = field_vec;
@@ -5448,8 +5125,7 @@ finish_struct_1 (t)
order. Rearrange them to declaration order. */
void
-unreverse_member_declarations (t)
- tree t;
+unreverse_member_declarations (tree t)
{
tree next;
tree prev;
@@ -5480,11 +5156,9 @@ unreverse_member_declarations (t)
}
tree
-finish_struct (t, attributes)
- tree t, attributes;
+finish_struct (tree t, tree attributes)
{
- const char *saved_filename = input_filename;
- int saved_lineno = lineno;
+ location_t saved_loc = input_location;
/* Now that we've got all the field declarations, reverse everything
as necessary. */
@@ -5494,8 +5168,7 @@ finish_struct (t, attributes)
/* Nadger the current location so that diagnostics point to the start of
the struct, not the end. */
- input_filename = DECL_SOURCE_FILE (TYPE_NAME (t));
- lineno = DECL_SOURCE_LINE (TYPE_NAME (t));
+ input_location = DECL_SOURCE_LOCATION (TYPE_NAME (t));
if (processing_template_decl)
{
@@ -5505,8 +5178,7 @@ finish_struct (t, attributes)
else
finish_struct_1 (t);
- input_filename = saved_filename;
- lineno = saved_lineno;
+ input_location = saved_loc;
TYPE_BEING_DEFINED (t) = 0;
@@ -5530,10 +5202,7 @@ finish_struct (t, attributes)
before this function is called. */
static tree
-fixed_type_or_null (instance, nonnull, cdtorp)
- tree instance;
- int *nonnull;
- int *cdtorp;
+fixed_type_or_null (tree instance, int* nonnull, int* cdtorp)
{
switch (TREE_CODE (instance))
{
@@ -5665,9 +5334,7 @@ fixed_type_or_null (instance, nonnull, cdtorp)
before this function is called. */
int
-resolves_to_fixed_type_p (instance, nonnull)
- tree instance;
- int *nonnull;
+resolves_to_fixed_type_p (tree instance, int* nonnull)
{
tree t = TREE_TYPE (instance);
int cdtorp = 0;
@@ -5684,51 +5351,21 @@ resolves_to_fixed_type_p (instance, nonnull)
void
-init_class_processing ()
+init_class_processing (void)
{
current_class_depth = 0;
current_class_stack_size = 10;
current_class_stack
- = (class_stack_node_t) xmalloc (current_class_stack_size
- * sizeof (struct class_stack_node));
+ = xmalloc (current_class_stack_size * sizeof (struct class_stack_node));
VARRAY_TREE_INIT (local_classes, 8, "local_classes");
- access_default_node = build_int_2 (0, 0);
- access_public_node = build_int_2 (ak_public, 0);
- access_protected_node = build_int_2 (ak_protected, 0);
- access_private_node = build_int_2 (ak_private, 0);
- access_default_virtual_node = build_int_2 (4, 0);
- access_public_virtual_node = build_int_2 (4 | ak_public, 0);
- access_protected_virtual_node = build_int_2 (4 | ak_protected, 0);
- access_private_virtual_node = build_int_2 (4 | ak_private, 0);
-
ridpointers[(int) RID_PUBLIC] = access_public_node;
ridpointers[(int) RID_PRIVATE] = access_private_node;
ridpointers[(int) RID_PROTECTED] = access_protected_node;
}
-/* Set current scope to NAME. CODE tells us if this is a
- STRUCT, UNION, or ENUM environment.
-
- NAME may end up being NULL_TREE if this is an anonymous or
- late-bound struct (as in "struct { ... } foo;") */
-
-/* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE to
- appropriate values, found by looking up the type definition of
- NAME (as a CODE).
-
- If MODIFY is 1, we set IDENTIFIER_CLASS_VALUE's of names
- which can be seen locally to the class. They are shadowed by
- any subsequent local declaration (including parameter names).
-
- If MODIFY is 2, we set IDENTIFIER_CLASS_VALUE's of names
- which have static meaning (i.e., static members, static
- member functions, enum declarations, etc).
-
- If MODIFY is 3, we set IDENTIFIER_CLASS_VALUE of names
- which can be seen locally to the class (as in 1), but
- know that we are doing this for declaration purposes
- (i.e. friend foo::bar (int)).
+/* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE as
+ appropriate for TYPE.
So that we may avoid calls to lookup_name, we cache the _TYPE
nodes of local TYPE_DECLs in the TREE_TYPE field of the name.
@@ -5742,9 +5379,7 @@ init_class_processing ()
that name becomes `error_mark_node'. */
void
-pushclass (type, modify)
- tree type;
- int modify;
+pushclass (tree type)
{
type = TYPE_MAIN_VARIANT (type);
@@ -5753,9 +5388,9 @@ pushclass (type, modify)
{
current_class_stack_size *= 2;
current_class_stack
- = (class_stack_node_t) xrealloc (current_class_stack,
- current_class_stack_size
- * sizeof (struct class_stack_node));
+ = xrealloc (current_class_stack,
+ current_class_stack_size
+ * sizeof (struct class_stack_node));
}
/* Insert a new entry on the class stack. */
@@ -5788,39 +5423,50 @@ pushclass (type, modify)
/* If we're about to enter a nested class, clear
IDENTIFIER_CLASS_VALUE for the enclosing classes. */
- if (modify && current_class_depth > 1)
+ if (current_class_depth > 1)
clear_identifier_class_values ();
pushlevel_class ();
- if (modify)
+ if (type != previous_class_type || current_class_depth > 1)
{
- if (type != previous_class_type || current_class_depth > 1)
- push_class_decls (type);
- else
+ push_class_decls (type);
+ if (CLASSTYPE_TEMPLATE_INFO (type) && !CLASSTYPE_USE_TEMPLATE (type))
{
- tree item;
-
- /* We are re-entering the same class we just left, so we
- don't have to search the whole inheritance matrix to find
- all the decls to bind again. Instead, we install the
- cached class_shadowed list, and walk through it binding
- names and setting up IDENTIFIER_TYPE_VALUEs. */
- set_class_shadows (previous_class_values);
- for (item = previous_class_values; item; item = TREE_CHAIN (item))
- {
- tree id = TREE_PURPOSE (item);
- tree decl = TREE_TYPE (item);
-
- push_class_binding (id, decl);
- if (TREE_CODE (decl) == TYPE_DECL)
- set_identifier_type_value (id, TREE_TYPE (decl));
- }
- unuse_fields (type);
+ /* If we are entering the scope of a template declaration (not a
+ specialization), we need to push all the using decls with
+ dependent scope too. */
+ tree fields;
+
+ for (fields = TYPE_FIELDS (type);
+ fields; fields = TREE_CHAIN (fields))
+ if (TREE_CODE (fields) == USING_DECL && !TREE_TYPE (fields))
+ pushdecl_class_level (fields);
}
+ }
+ else
+ {
+ tree item;
- cxx_remember_type_decls (CLASSTYPE_NESTED_UDTS (type));
+ /* We are re-entering the same class we just left, so we don't
+ have to search the whole inheritance matrix to find all the
+ decls to bind again. Instead, we install the cached
+ class_shadowed list, and walk through it binding names and
+ setting up IDENTIFIER_TYPE_VALUEs. */
+ set_class_shadows (previous_class_values);
+ for (item = previous_class_values; item; item = TREE_CHAIN (item))
+ {
+ tree id = TREE_PURPOSE (item);
+ tree decl = TREE_TYPE (item);
+
+ push_class_binding (id, decl);
+ if (TREE_CODE (decl) == TYPE_DECL)
+ set_identifier_type_value (id, decl);
+ }
+ unuse_fields (type);
}
+
+ cxx_remember_type_decls (CLASSTYPE_NESTED_UTDS (type));
}
/* When we exit a toplevel class scope, we save the
@@ -5829,7 +5475,7 @@ pushclass (type, modify)
must invalidate our cache. */
void
-invalidate_class_lookup_cache ()
+invalidate_class_lookup_cache (void)
{
tree t;
@@ -5845,7 +5491,7 @@ invalidate_class_lookup_cache ()
previously, that is the one popped to. */
void
-popclass ()
+popclass (void)
{
poplevel_class ();
pop_class_decls ();
@@ -5863,14 +5509,14 @@ popclass ()
no type. */
int
-currently_open_class (t)
- tree t;
+currently_open_class (tree t)
{
int i;
- if (t == current_class_type)
+ if (current_class_type && same_type_p (t, current_class_type))
return 1;
for (i = 1; i < current_class_depth; ++i)
- if (current_class_stack [i].type == t)
+ if (current_class_stack[i].type
+ && same_type_p (current_class_stack [i].type, t))
return 1;
return 0;
}
@@ -5880,11 +5526,17 @@ currently_open_class (t)
something via unqualified lookup. */
tree
-currently_open_derived_class (t)
- tree t;
+currently_open_derived_class (tree t)
{
int i;
+ /* The bases of a dependent type are unknown. */
+ if (dependent_type_p (t))
+ return NULL_TREE;
+
+ if (!current_class_type)
+ return NULL_TREE;
+
if (DERIVED_FROM_P (t, current_class_type))
return current_class_type;
@@ -5896,16 +5548,13 @@ currently_open_derived_class (t)
}
/* When entering a class scope, all enclosing class scopes' names with
- static meaning (static variables, static functions, types and enumerators)
- have to be visible. This recursive function calls pushclass for all
- enclosing class contexts until global or a local scope is reached.
- TYPE is the enclosed class and MODIFY is equivalent with the pushclass
- formal of the same name. */
+ static meaning (static variables, static functions, types and
+ enumerators) have to be visible. This recursive function calls
+ pushclass for all enclosing class contexts until global or a local
+ scope is reached. TYPE is the enclosed class. */
void
-push_nested_class (type, modify)
- tree type;
- int modify;
+push_nested_class (tree type)
{
tree context;
@@ -5921,14 +5570,14 @@ push_nested_class (type, modify)
context = DECL_CONTEXT (TYPE_MAIN_DECL (type));
if (context && CLASS_TYPE_P (context))
- push_nested_class (context, 2);
- pushclass (type, modify);
+ push_nested_class (context);
+ pushclass (type);
}
-/* Undoes a push_nested_class call. MODIFY is passed on to popclass. */
+/* Undoes a push_nested_class call. */
void
-pop_nested_class ()
+pop_nested_class (void)
{
tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type));
@@ -5940,7 +5589,7 @@ pop_nested_class ()
/* Returns the number of extern "LANG" blocks we are nested within. */
int
-current_lang_depth ()
+current_lang_depth (void)
{
return VARRAY_ACTIVE_SIZE (current_lang_base);
}
@@ -5949,8 +5598,7 @@ current_lang_depth ()
so that behavior of name-mangling machinery is correct. */
void
-push_lang_context (name)
- tree name;
+push_lang_context (tree name)
{
VARRAY_PUSH_TREE (current_lang_base, current_lang_name);
@@ -5985,7 +5633,7 @@ push_lang_context (name)
/* Get out of the current language scope. */
void
-pop_lang_context ()
+pop_lang_context (void)
{
current_lang_name = VARRAY_TOP_TREE (current_lang_base);
VARRAY_POP (current_lang_base);
@@ -5995,25 +5643,18 @@ pop_lang_context ()
/* Given an OVERLOAD and a TARGET_TYPE, return the function that
matches the TARGET_TYPE. If there is no satisfactory match, return
- error_mark_node, and issue an error message if COMPLAIN is
- nonzero. Permit pointers to member function if PTRMEM is nonzero.
- If TEMPLATE_ONLY, the name of the overloaded function
- was a template-id, and EXPLICIT_TARGS are the explicitly provided
+ error_mark_node, and issue a error & warning messages under control
+ of FLAGS. Permit pointers to member function if FLAGS permits. If
+ TEMPLATE_ONLY, the name of the overloaded function was a
+ template-id, and EXPLICIT_TARGS are the explicitly provided
template arguments. */
static tree
-resolve_address_of_overloaded_function (target_type,
- overload,
- flags,
- ptrmem,
- template_only,
- explicit_targs)
- tree target_type;
- tree overload;
- tsubst_flags_t flags;
- int ptrmem;
- int template_only;
- tree explicit_targs;
+resolve_address_of_overloaded_function (tree target_type,
+ tree overload,
+ tsubst_flags_t flags,
+ bool template_only,
+ tree explicit_targs)
{
/* Here's what the standard says:
@@ -6056,9 +5697,8 @@ resolve_address_of_overloaded_function (target_type,
&& (TREE_CODE (TREE_TYPE (target_type))
== METHOD_TYPE)), 0);
- if (TREE_CODE (overload) == COMPONENT_REF)
- overload = TREE_OPERAND (overload, 1);
-
+ my_friendly_assert (is_overloaded_fn (overload), 20030910);
+
/* Check that the TARGET_TYPE is reasonable. */
if (TYPE_PTRFN_P (target_type))
/* This is OK. */;
@@ -6089,9 +5729,9 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'",
{
tree fns;
- for (fns = overload; fns; fns = OVL_CHAIN (fns))
+ for (fns = overload; fns; fns = OVL_NEXT (fns))
{
- tree fn = OVL_FUNCTION (fns);
+ tree fn = OVL_CURRENT (fns);
tree fntype;
if (TREE_CODE (fn) == TEMPLATE_DECL)
@@ -6142,9 +5782,9 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'",
if (TREE_CODE (target_fn_type) == METHOD_TYPE)
target_arg_types = TREE_CHAIN (target_arg_types);
- for (fns = overload; fns; fns = OVL_CHAIN (fns))
+ for (fns = overload; fns; fns = OVL_NEXT (fns))
{
- tree fn = OVL_FUNCTION (fns);
+ tree fn = OVL_CURRENT (fns);
tree instantiation;
tree instantiation_type;
tree targs;
@@ -6168,7 +5808,7 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'",
continue;
/* Instantiate the template. */
- instantiation = instantiate_template (fn, targs);
+ instantiation = instantiate_template (fn, targs, flags);
if (instantiation == error_mark_node)
/* Instantiation failed. */
continue;
@@ -6242,7 +5882,7 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'",
fn = TREE_PURPOSE (matches);
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
- && !ptrmem && !flag_ms_extensions)
+ && !(flags & tf_ptrmem_ok) && !flag_ms_extensions)
{
static int explained;
@@ -6279,7 +5919,7 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'",
/* This function will instantiate the type of the expression given in
RHS to match the type of LHSTYPE. If errors exist, then return
- error_mark_node. FLAGS is a bit mask. If ITF_COMPLAIN is set, then
+ error_mark_node. FLAGS is a bit mask. If TF_ERROR is set, then
we complain on errors. If we are not complaining, never modify rhs,
as overload resolution wants to try many possible instantiations, in
the hope that at least one will work.
@@ -6288,33 +5928,36 @@ cannot resolve overloaded function `%D' based on conversion to type `%T'",
function, or a pointer to member function. */
tree
-instantiate_type (lhstype, rhs, flags)
- tree lhstype, rhs;
- tsubst_flags_t flags;
+instantiate_type (tree lhstype, tree rhs, tsubst_flags_t flags)
{
tsubst_flags_t flags_in = flags;
- int complain = (flags & tf_error);
- int strict = (flags & tf_no_attributes)
- ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT;
- int allow_ptrmem = flags & tf_ptrmem_ok;
flags &= ~tf_ptrmem_ok;
if (TREE_CODE (lhstype) == UNKNOWN_TYPE)
{
- if (complain)
+ if (flags & tf_error)
error ("not enough type information");
return error_mark_node;
}
if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs)))
{
- if (comptypes (lhstype, TREE_TYPE (rhs), strict))
+ if (same_type_p (lhstype, TREE_TYPE (rhs)))
return rhs;
- if (complain)
- error ("argument of type `%T' does not match `%T'",
- TREE_TYPE (rhs), lhstype);
- return error_mark_node;
+ if (flag_ms_extensions
+ && TYPE_PTRMEMFUNC_P (lhstype)
+ && !TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs)))
+ /* Microsoft allows `A::f' to be resolved to a
+ pointer-to-member. */
+ ;
+ else
+ {
+ if (flags & tf_error)
+ error ("argument of type `%T' does not match `%T'",
+ TREE_TYPE (rhs), lhstype);
+ return error_mark_node;
+ }
}
if (TREE_CODE (rhs) == BASELINK)
@@ -6361,13 +6004,21 @@ instantiate_type (lhstype, rhs, flags)
return instantiate_type (lhstype, rhs, flags);
case COMPONENT_REF:
- return instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
+ {
+ tree addr = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags);
+
+ if (addr != error_mark_node
+ && TREE_SIDE_EFFECTS (TREE_OPERAND (rhs, 0)))
+ /* Do not lose object's side effects. */
+ addr = build (COMPOUND_EXPR, TREE_TYPE (addr),
+ TREE_OPERAND (rhs, 0), addr);
+ return addr;
+ }
case OFFSET_REF:
rhs = TREE_OPERAND (rhs, 1);
if (BASELINK_P (rhs))
- return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs),
- flags | allow_ptrmem);
+ return instantiate_type (lhstype, BASELINK_FUNCTIONS (rhs), flags_in);
/* This can happen if we are forming a pointer-to-member for a
member template. */
@@ -6381,21 +6032,16 @@ instantiate_type (lhstype, rhs, flags)
tree args = TREE_OPERAND (rhs, 1);
return
- resolve_address_of_overloaded_function (lhstype,
- fns,
- flags_in,
- allow_ptrmem,
- /*template_only=*/1,
+ resolve_address_of_overloaded_function (lhstype, fns, flags_in,
+ /*template_only=*/true,
args);
}
case OVERLOAD:
+ case FUNCTION_DECL:
return
- resolve_address_of_overloaded_function (lhstype,
- rhs,
- flags_in,
- allow_ptrmem,
- /*template_only=*/0,
+ resolve_address_of_overloaded_function (lhstype, rhs, flags_in,
+ /*template_only=*/false,
/*explicit_targs=*/NULL_TREE);
case TREE_LIST:
@@ -6443,7 +6089,6 @@ instantiate_type (lhstype, rhs, flags)
case ABS_EXPR:
case MAX_EXPR:
case MIN_EXPR:
- case FFS_EXPR:
case BIT_AND_EXPR:
case BIT_IOR_EXPR:
@@ -6457,7 +6102,7 @@ instantiate_type (lhstype, rhs, flags)
case PREDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
- if (complain)
+ if (flags & tf_error)
error ("invalid operation on uninstantiated type");
return error_mark_node;
@@ -6473,14 +6118,14 @@ instantiate_type (lhstype, rhs, flags)
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
case TRUTH_NOT_EXPR:
- if (complain)
+ if (flags & tf_error)
error ("not enough type information");
return error_mark_node;
case COND_EXPR:
if (type_unknown_p (TREE_OPERAND (rhs, 0)))
{
- if (complain)
+ if (flags & tf_error)
error ("not enough type information");
return error_mark_node;
}
@@ -6532,8 +6177,7 @@ instantiate_type (lhstype, rhs, flags)
all be the same name. Who knows for multiple inheritance). */
static tree
-get_vfield_name (type)
- tree type;
+get_vfield_name (tree type)
{
tree binfo = TYPE_BINFO (type);
char *buf;
@@ -6544,21 +6188,18 @@ get_vfield_name (type)
binfo = BINFO_BASETYPE (binfo, 0);
type = BINFO_TYPE (binfo);
- buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT)
- + TYPE_NAME_LENGTH (type) + 2);
+ buf = alloca (sizeof (VFIELD_NAME_FORMAT) + TYPE_NAME_LENGTH (type) + 2);
sprintf (buf, VFIELD_NAME_FORMAT,
IDENTIFIER_POINTER (constructor_name (type)));
return get_identifier (buf);
}
void
-print_class_statistics ()
+print_class_statistics (void)
{
#ifdef GATHER_STATISTICS
fprintf (stderr, "convert_harshness = %d\n", n_convert_harshness);
fprintf (stderr, "compute_conversion_costs = %d\n", n_compute_conversion_costs);
- fprintf (stderr, "build_method_call = %d (inner = %d)\n",
- n_build_method_call, n_inner_fields_searched);
if (n_vtables)
{
fprintf (stderr, "vtables = %d; vtable searches = %d\n",
@@ -6576,7 +6217,7 @@ print_class_statistics ()
the inserted class name is treated as if it were a public member name. */
void
-build_self_reference ()
+build_self_reference (void)
{
tree name = constructor_name (current_class_type);
tree value = build_lang_decl (TYPE_DECL, name, current_class_type);
@@ -6599,8 +6240,7 @@ build_self_reference ()
/* Returns 1 if TYPE contains only padding bytes. */
int
-is_empty_class (type)
- tree type;
+is_empty_class (tree type)
{
if (type == error_mark_node)
return 0;
@@ -6646,8 +6286,7 @@ contains_empty_class_p (tree type)
a *_TYPE node. NODE can also be a local class. */
tree
-get_enclosing_class (type)
- tree type;
+get_enclosing_class (tree type)
{
tree node = type;
@@ -6672,34 +6311,16 @@ get_enclosing_class (type)
return NULL_TREE;
}
-/* Return 1 if TYPE or one of its enclosing classes is derived from BASE. */
-
-int
-is_base_of_enclosing_class (base, type)
- tree base, type;
-{
- while (type)
- {
- if (lookup_base (type, base, ba_any, NULL))
- return 1;
-
- type = get_enclosing_class (type);
- }
- return 0;
-}
-
/* Note that NAME was looked up while the current class was being
defined and that the result of that lookup was DECL. */
void
-maybe_note_name_used_in_class (name, decl)
- tree name;
- tree decl;
+maybe_note_name_used_in_class (tree name, tree decl)
{
splay_tree names_used;
/* If we're not defining a class, there's nothing to do. */
- if (!innermost_scope_is_class_p ())
+ if (innermost_scope_kind() != sk_class)
return;
/* If there's already a binding for this NAME, then we don't have
@@ -6721,9 +6342,7 @@ maybe_note_name_used_in_class (name, decl)
to see that the declaration is valid. */
void
-note_name_declared_in_class (name, decl)
- tree name;
- tree decl;
+note_name_declared_in_class (tree name, tree decl)
{
splay_tree names_used;
splay_tree_node n;
@@ -6754,8 +6373,7 @@ note_name_declared_in_class (name, decl)
will return the VAR_DECL for the primary vtable. */
tree
-get_vtbl_decl_for_binfo (binfo)
- tree binfo;
+get_vtbl_decl_for_binfo (tree binfo)
{
tree decl;
@@ -6771,147 +6389,63 @@ get_vtbl_decl_for_binfo (binfo)
return decl;
}
-/* Called from get_primary_binfo via dfs_walk. DATA is a TREE_LIST
- who's TREE_PURPOSE is the TYPE of the required primary base and
- who's TREE_VALUE is a list of candidate binfos that we fill in. */
-static tree
-dfs_get_primary_binfo (binfo, data)
- tree binfo;
- void *data;
-{
- tree cons = (tree) data;
- tree primary_base = TREE_PURPOSE (cons);
-
- if (TREE_VIA_VIRTUAL (binfo)
- && same_type_p (BINFO_TYPE (binfo), primary_base))
- /* This is the right type of binfo, but it might be an unshared
- instance, and the shared instance is later in the dfs walk. We
- must keep looking. */
- TREE_VALUE (cons) = tree_cons (NULL, binfo, TREE_VALUE (cons));
-
- return NULL_TREE;
-}
-
-/* Returns the unshared binfo for the primary base of BINFO. Note
- that in a complex hierarchy the resulting BINFO may not actually
- *be* primary. In particular if the resulting BINFO is a virtual
- base, and it occurs elsewhere in the hierarchy, then this
- occurrence may not actually be a primary base in the complete
- object. Check BINFO_PRIMARY_P to be sure. */
+/* Returns the binfo for the primary base of BINFO. If the resulting
+ BINFO is a virtual base, and it is inherited elsewhere in the
+ hierarchy, then the returned binfo might not be the primary base of
+ BINFO in the complete object. Check BINFO_PRIMARY_P or
+ BINFO_LOST_PRIMARY_P to be sure. */
tree
-get_primary_binfo (binfo)
- tree binfo;
+get_primary_binfo (tree binfo)
{
tree primary_base;
- tree result = NULL_TREE;
- tree virtuals;
+ tree result;
primary_base = CLASSTYPE_PRIMARY_BINFO (BINFO_TYPE (binfo));
if (!primary_base)
return NULL_TREE;
- /* A non-virtual primary base is always a direct base, and easy to
- find. */
- if (!TREE_VIA_VIRTUAL (primary_base))
- {
- int i;
-
- /* Scan the direct basetypes until we find a base with the same
- type as the primary base. */
- for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i)
- {
- tree base_binfo = BINFO_BASETYPE (binfo, i);
-
- if (same_type_p (BINFO_TYPE (base_binfo),
- BINFO_TYPE (primary_base)))
- return base_binfo;
- }
-
- /* We should always find the primary base. */
- abort ();
- }
-
- /* For a primary virtual base, we have to scan the entire hierarchy
- rooted at BINFO; the virtual base could be an indirect virtual
- base. There could be more than one instance of the primary base
- in the hierarchy, and if one is the canonical binfo we want that
- one. If it exists, it should be the first one we find, but as a
- consistency check we find them all and make sure. */
- virtuals = build_tree_list (BINFO_TYPE (primary_base), NULL_TREE);
- dfs_walk (binfo, dfs_get_primary_binfo, NULL, virtuals);
- virtuals = TREE_VALUE (virtuals);
-
- /* We must have found at least one instance. */
- my_friendly_assert (virtuals, 20010612);
-
- if (TREE_CHAIN (virtuals))
- {
- /* We found more than one instance of the base. We must make
- sure that, if one is the canonical one, it is the first one
- we found. As the chain is in reverse dfs order, that means
- the last on the list. */
- tree complete_binfo;
- tree canonical;
-
- for (complete_binfo = binfo;
- BINFO_INHERITANCE_CHAIN (complete_binfo);
- complete_binfo = BINFO_INHERITANCE_CHAIN (complete_binfo))
- continue;
- canonical = binfo_for_vbase (BINFO_TYPE (primary_base),
- BINFO_TYPE (complete_binfo));
-
- for (; virtuals; virtuals = TREE_CHAIN (virtuals))
- {
- result = TREE_VALUE (virtuals);
-
- if (canonical == result)
- {
- /* This is the unshared instance. Make sure it was the
- first one found. */
- my_friendly_assert (!TREE_CHAIN (virtuals), 20010612);
- break;
- }
- }
- }
- else
- result = TREE_VALUE (virtuals);
+ result = copied_binfo (primary_base, binfo);
return result;
}
/* If INDENTED_P is zero, indent to INDENT. Return nonzero. */
static int
-maybe_indent_hierarchy (stream, indent, indented_p)
- FILE *stream;
- int indent;
- int indented_p;
+maybe_indent_hierarchy (FILE * stream, int indent, int indented_p)
{
if (!indented_p)
fprintf (stream, "%*s", indent, "");
return 1;
}
-/* Dump the offsets of all the bases rooted at BINFO (in the hierarchy
- dominated by T) to stderr. INDENT should be zero when called from
- the top level; it is incremented recursively. */
+/* Dump the offsets of all the bases rooted at BINFO to STREAM.
+ INDENT should be zero when called from the top level; it is
+ incremented recursively. IGO indicates the next expected BINFO in
+ inheritance graph ordering. */
-static void
-dump_class_hierarchy_r (stream, flags, t, binfo, indent)
- FILE *stream;
- int flags;
- tree t;
- tree binfo;
- int indent;
+static tree
+dump_class_hierarchy_r (FILE *stream,
+ int flags,
+ tree binfo,
+ tree igo,
+ int indent)
{
- int i;
int indented = 0;
+ tree base_binfos;
indented = maybe_indent_hierarchy (stream, indent, 0);
fprintf (stream, "%s (0x%lx) ",
type_as_string (binfo, TFF_PLAIN_IDENTIFIER),
(unsigned long) binfo);
+ if (binfo != igo)
+ {
+ fprintf (stream, "alternative-path\n");
+ return igo;
+ }
+ igo = TREE_CHAIN (binfo);
+
fprintf (stream, HOST_WIDE_INT_PRINT_DEC,
tree_low_cst (BINFO_OFFSET (binfo), 0));
if (is_empty_class (BINFO_TYPE (binfo)))
@@ -6919,15 +6453,7 @@ dump_class_hierarchy_r (stream, flags, t, binfo, indent)
else if (CLASSTYPE_NEARLY_EMPTY_P (BINFO_TYPE (binfo)))
fprintf (stream, " nearly-empty");
if (TREE_VIA_VIRTUAL (binfo))
- {
- tree canonical = binfo_for_vbase (BINFO_TYPE (binfo), t);
-
- fprintf (stream, " virtual");
- if (canonical == binfo)
- fprintf (stream, " canonical");
- else
- fprintf (stream, " non-canonical");
- }
+ fprintf (stream, " virtual");
fprintf (stream, "\n");
indented = 0;
@@ -6984,38 +6510,65 @@ dump_class_hierarchy_r (stream, flags, t, binfo, indent)
fprintf (stream, "\n");
}
+ base_binfos = BINFO_BASETYPES (binfo);
+ if (base_binfos)
+ {
+ int ix, n;
- for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i)
- dump_class_hierarchy_r (stream, flags,
- t, BINFO_BASETYPE (binfo, i),
- indent + 2);
+ n = TREE_VEC_LENGTH (base_binfos);
+ for (ix = 0; ix != n; ix++)
+ {
+ tree base_binfo = TREE_VEC_ELT (base_binfos, ix);
+
+ igo = dump_class_hierarchy_r (stream, flags, base_binfo,
+ igo, indent + 2);
+ }
+ }
+
+ return igo;
}
/* Dump the BINFO hierarchy for T. */
static void
-dump_class_hierarchy (t)
- tree t;
+dump_class_hierarchy_1 (FILE *stream, int flags, tree t)
{
- int flags;
- FILE *stream = dump_begin (TDI_class, &flags);
-
- if (!stream)
- return;
-
fprintf (stream, "Class %s\n", type_as_string (t, TFF_PLAIN_IDENTIFIER));
fprintf (stream, " size=%lu align=%lu\n",
(unsigned long)(tree_low_cst (TYPE_SIZE (t), 0) / BITS_PER_UNIT),
(unsigned long)(TYPE_ALIGN (t) / BITS_PER_UNIT));
- dump_class_hierarchy_r (stream, flags, t, TYPE_BINFO (t), 0);
+ fprintf (stream, " base size=%lu base align=%lu\n",
+ (unsigned long)(tree_low_cst (TYPE_SIZE (CLASSTYPE_AS_BASE (t)), 0)
+ / BITS_PER_UNIT),
+ (unsigned long)(TYPE_ALIGN (CLASSTYPE_AS_BASE (t))
+ / BITS_PER_UNIT));
+ dump_class_hierarchy_r (stream, flags, TYPE_BINFO (t), TYPE_BINFO (t), 0);
fprintf (stream, "\n");
- dump_end (TDI_class, stream);
+}
+
+/* Debug interface to hierarchy dumping. */
+
+extern void
+debug_class (tree t)
+{
+ dump_class_hierarchy_1 (stderr, TDF_SLIM, t);
+}
+
+static void
+dump_class_hierarchy (tree t)
+{
+ int flags;
+ FILE *stream = dump_begin (TDI_class, &flags);
+
+ if (stream)
+ {
+ dump_class_hierarchy_1 (stream, flags, t);
+ dump_end (TDI_class, stream);
+ }
}
static void
-dump_array (stream, decl)
- FILE *stream;
- tree decl;
+dump_array (FILE * stream, tree decl)
{
tree inits;
int ix;
@@ -7030,17 +6583,14 @@ dump_array (stream, decl)
TFF_PLAIN_IDENTIFIER));
fprintf (stream, "\n");
- for (ix = 0, inits = TREE_OPERAND (DECL_INITIAL (decl), 1);
+ for (ix = 0, inits = CONSTRUCTOR_ELTS (DECL_INITIAL (decl));
inits; ix++, inits = TREE_CHAIN (inits))
fprintf (stream, "%-4ld %s\n", (long)(ix * elt),
expr_as_string (TREE_VALUE (inits), TFF_PLAIN_IDENTIFIER));
}
static void
-dump_vtable (t, binfo, vtable)
- tree t;
- tree binfo;
- tree vtable;
+dump_vtable (tree t, tree binfo, tree vtable)
{
int flags;
FILE *stream = dump_begin (TDI_class, &flags);
@@ -7070,9 +6620,7 @@ dump_vtable (t, binfo, vtable)
}
static void
-dump_vtt (t, vtt)
- tree t;
- tree vtt;
+dump_vtt (tree t, tree vtt)
{
int flags;
FILE *stream = dump_begin (TDI_class, &flags);
@@ -7091,17 +6639,60 @@ dump_vtt (t, vtt)
dump_end (TDI_class, stream);
}
+/* Dump a function or thunk and its thunkees. */
+
+static void
+dump_thunk (FILE *stream, int indent, tree thunk)
+{
+ static const char spaces[] = " ";
+ tree name = DECL_NAME (thunk);
+ tree thunks;
+
+ fprintf (stream, "%.*s%p %s %s", indent, spaces,
+ (void *)thunk,
+ !DECL_THUNK_P (thunk) ? "function"
+ : DECL_THIS_THUNK_P (thunk) ? "this-thunk" : "covariant-thunk",
+ name ? IDENTIFIER_POINTER (name) : "<unset>");
+ if (DECL_THUNK_P (thunk))
+ {
+ HOST_WIDE_INT fixed_adjust = THUNK_FIXED_OFFSET (thunk);
+ tree virtual_adjust = THUNK_VIRTUAL_OFFSET (thunk);
+
+ fprintf (stream, " fixed=" HOST_WIDE_INT_PRINT_DEC, fixed_adjust);
+ if (!virtual_adjust)
+ /*NOP*/;
+ else if (DECL_THIS_THUNK_P (thunk))
+ fprintf (stream, " vcall=" HOST_WIDE_INT_PRINT_DEC,
+ tree_low_cst (virtual_adjust, 0));
+ else
+ fprintf (stream, " vbase=" HOST_WIDE_INT_PRINT_DEC "(%s)",
+ tree_low_cst (BINFO_VPTR_FIELD (virtual_adjust), 0),
+ type_as_string (BINFO_TYPE (virtual_adjust), TFF_SCOPE));
+ if (THUNK_ALIAS (thunk))
+ fprintf (stream, " alias to %p", (void *)THUNK_ALIAS (thunk));
+ }
+ fprintf (stream, "\n");
+ for (thunks = DECL_THUNKS (thunk); thunks; thunks = TREE_CHAIN (thunks))
+ dump_thunk (stream, indent + 2, thunks);
+}
+
+/* Dump the thunks for FN. */
+
+extern void
+debug_thunks (tree fn)
+{
+ dump_thunk (stderr, 0, fn);
+}
+
/* Virtual function table initialization. */
/* Create all the necessary vtables for T and its base classes. */
static void
-finish_vtbls (t)
- tree t;
+finish_vtbls (tree t)
{
tree list;
tree vbase;
- int i;
/* We lay out the primary and secondary vtables in one contiguous
vtable. The primary vtable is first, followed by the non-virtual
@@ -7113,29 +6704,9 @@ finish_vtbls (t)
/* Then come the virtual bases, also in inheritance graph order. */
for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
{
- tree real_base;
-
if (!TREE_VIA_VIRTUAL (vbase))
continue;
-
- /* Although we walk in inheritance order, that might not get the
- canonical base. */
- real_base = binfo_for_vbase (BINFO_TYPE (vbase), t);
-
- accumulate_vtbl_inits (real_base, real_base,
- TYPE_BINFO (t), t, list);
- }
-
- /* Fill in BINFO_VPTR_FIELD in the immediate binfos for our virtual
- base classes, for the benefit of the debugging backends. */
- for (i = 0; i < BINFO_N_BASETYPES (TYPE_BINFO (t)); ++i)
- {
- tree base = BINFO_BASETYPE (TYPE_BINFO (t), i);
- if (TREE_VIA_VIRTUAL (base))
- {
- vbase = binfo_for_vbase (BINFO_TYPE (base), t);
- BINFO_VPTR_FIELD (base) = BINFO_VPTR_FIELD (vbase);
- }
+ accumulate_vtbl_inits (vbase, vbase, TYPE_BINFO (t), t, list);
}
if (TYPE_BINFO_VTABLE (t))
@@ -7145,9 +6716,7 @@ finish_vtbls (t)
/* Initialize the vtable for BINFO with the INITS. */
static void
-initialize_vtable (binfo, inits)
- tree binfo;
- tree inits;
+initialize_vtable (tree binfo, tree inits)
{
tree decl;
@@ -7161,15 +6730,13 @@ initialize_vtable (binfo, inits)
the INITS. */
static void
-initialize_array (decl, inits)
- tree decl;
- tree inits;
+initialize_array (tree decl, tree inits)
{
tree context;
context = DECL_CONTEXT (decl);
DECL_CONTEXT (decl) = NULL_TREE;
- DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, inits);
+ DECL_INITIAL (decl) = build_constructor (NULL_TREE, inits);
TREE_HAS_CONSTRUCTOR (DECL_INITIAL (decl)) = 1;
cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
DECL_CONTEXT (decl) = context;
@@ -7189,8 +6756,7 @@ initialize_array (decl, inits)
Secondary VTTs look like complete object VTTs without part 4. */
static void
-build_vtt (t)
- tree t;
+build_vtt (tree t)
{
tree inits;
tree type;
@@ -7220,41 +6786,13 @@ build_vtt (t)
dump_vtt (t, vtt);
}
-/* The type corresponding to BASE_BINFO is a base of the type of BINFO, but
- from within some hierarchy which is inherited from the type of BINFO.
- Return BASE_BINFO's equivalent binfo from the hierarchy dominated by
- BINFO. */
-
-static tree
-get_original_base (base_binfo, binfo)
- tree base_binfo;
- tree binfo;
-{
- tree derived;
- int ix;
-
- if (same_type_p (BINFO_TYPE (base_binfo), BINFO_TYPE (binfo)))
- return binfo;
- if (TREE_VIA_VIRTUAL (base_binfo))
- return binfo_for_vbase (BINFO_TYPE (base_binfo), BINFO_TYPE (binfo));
- derived = get_original_base (BINFO_INHERITANCE_CHAIN (base_binfo), binfo);
-
- for (ix = 0; ix != BINFO_N_BASETYPES (derived); ix++)
- if (same_type_p (BINFO_TYPE (base_binfo),
- BINFO_TYPE (BINFO_BASETYPE (derived, ix))))
- return BINFO_BASETYPE (derived, ix);
- abort ();
- return NULL;
-}
-
/* When building a secondary VTT, BINFO_VTABLE is set to a TREE_LIST with
PURPOSE the RTTI_BINFO, VALUE the real vtable pointer for this binfo,
and CHAIN the vtable pointer for this binfo after construction is
complete. VALUE can also be another BINFO, in which case we recurse. */
static tree
-binfo_ctor_vtable (binfo)
- tree binfo;
+binfo_ctor_vtable (tree binfo)
{
tree vt;
@@ -7281,11 +6819,7 @@ binfo_ctor_vtable (binfo)
vtables for the BINFO-in-T variant. */
static tree *
-build_vtt_inits (binfo, t, inits, index)
- tree binfo;
- tree t;
- tree *inits;
- tree *index;
+build_vtt_inits (tree binfo, tree t, tree* inits, tree* index)
{
int i;
tree b;
@@ -7361,13 +6895,10 @@ build_vtt_inits (binfo, t, inits, index)
if (top_level_p)
for (b = TYPE_BINFO (BINFO_TYPE (binfo)); b; b = TREE_CHAIN (b))
{
- tree vbase;
-
if (!TREE_VIA_VIRTUAL (b))
continue;
- vbase = binfo_for_vbase (BINFO_TYPE (b), t);
- inits = build_vtt_inits (vbase, t, inits, index);
+ inits = build_vtt_inits (b, t, inits, index);
}
if (!top_level_p)
@@ -7392,9 +6923,7 @@ build_vtt_inits (binfo, t, inits, index)
TREE_TOP_LEVEL flag indicates that this is the primary VTT. */
static tree
-dfs_build_secondary_vptr_vtt_inits (binfo, data)
- tree binfo;
- void *data;
+dfs_build_secondary_vptr_vtt_inits (tree binfo, void* data)
{
tree l;
tree t;
@@ -7406,7 +6935,7 @@ dfs_build_secondary_vptr_vtt_inits (binfo, data)
t = TREE_CHAIN (l);
top_level_p = VTT_TOP_LEVEL_P (l);
- SET_BINFO_MARKED (binfo);
+ BINFO_MARKED (binfo) = 1;
/* We don't care about bases that don't have vtables. */
if (!TYPE_VFIELD (BINFO_TYPE (binfo)))
@@ -7457,14 +6986,11 @@ dfs_build_secondary_vptr_vtt_inits (binfo, data)
hierarchy. */
static tree
-dfs_ctor_vtable_bases_queue_p (binfo, data)
- tree binfo;
- void *data;
+dfs_ctor_vtable_bases_queue_p (tree derived, int ix,
+ void* data)
{
- if (TREE_VIA_VIRTUAL (binfo))
- /* Get the shared version. */
- binfo = binfo_for_vbase (BINFO_TYPE (binfo), TREE_PURPOSE ((tree) data));
-
+ tree binfo = BINFO_BASETYPE (derived, ix);
+
if (!BINFO_MARKED (binfo) == VTT_MARKED_BINFO_P ((tree) data))
return NULL_TREE;
return binfo;
@@ -7476,11 +7002,9 @@ dfs_ctor_vtable_bases_queue_p (binfo, data)
TREE_VALUE is the TREE_TYPE of the base whose sub vtt was generated. */
static tree
-dfs_fixup_binfo_vtbls (binfo, data)
- tree binfo;
- void *data;
+dfs_fixup_binfo_vtbls (tree binfo, void* data)
{
- CLEAR_BINFO_MARKED (binfo);
+ BINFO_MARKED (binfo) = 0;
/* We don't care about bases that don't have vtables. */
if (!TYPE_VFIELD (BINFO_TYPE (binfo)))
@@ -7501,9 +7025,7 @@ dfs_fixup_binfo_vtbls (binfo, data)
hierarchy dominated by T. */
static void
-build_ctor_vtbl_group (binfo, t)
- tree binfo;
- tree t;
+build_ctor_vtbl_group (tree binfo, tree t)
{
tree list;
tree type;
@@ -7533,14 +7055,12 @@ build_ctor_vtbl_group (binfo, t)
vbase = TREE_CHAIN (vbase))
{
tree b;
- tree orig_base;
if (!TREE_VIA_VIRTUAL (vbase))
continue;
- b = binfo_for_vbase (BINFO_TYPE (vbase), t);
- orig_base = binfo_for_vbase (BINFO_TYPE (vbase), BINFO_TYPE (binfo));
+ b = copied_binfo (vbase, binfo);
- accumulate_vtbl_inits (b, orig_base, binfo, t, list);
+ accumulate_vtbl_inits (b, vbase, binfo, t, list);
}
inits = TREE_VALUE (list);
@@ -7566,12 +7086,11 @@ build_ctor_vtbl_group (binfo, t)
but are not necessarily the same in terms of layout. */
static void
-accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, inits)
- tree binfo;
- tree orig_binfo;
- tree rtti_binfo;
- tree t;
- tree inits;
+accumulate_vtbl_inits (tree binfo,
+ tree orig_binfo,
+ tree rtti_binfo,
+ tree t,
+ tree inits)
{
int i;
int ctor_vtbl_p = !same_type_p (BINFO_TYPE (rtti_binfo), t);
@@ -7620,12 +7139,11 @@ accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, inits)
the BINFO vtable. */
static tree
-dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l)
- tree binfo;
- tree orig_binfo;
- tree rtti_binfo;
- tree t;
- tree l;
+dfs_accumulate_vtbl_inits (tree binfo,
+ tree orig_binfo,
+ tree rtti_binfo,
+ tree t,
+ tree l)
{
tree inits = NULL_TREE;
tree vtbl = NULL_TREE;
@@ -7672,8 +7190,8 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l)
either case, we share our vtable with LAST, i.e. the
derived-most base within B of which we are a primary. */
if (b == rtti_binfo
- || (b && binfo_for_vbase (BINFO_TYPE (b),
- BINFO_TYPE (rtti_binfo))))
+ || (b && purpose_member (BINFO_TYPE (b),
+ CLASSTYPE_VBASECLASSES (BINFO_TYPE (rtti_binfo)))))
/* Just set our BINFO_VTABLE to point to LAST, as we may not have
set LAST's BINFO_VTABLE yet. We'll extract the actual vptr in
binfo_ctor_vtable after everything's been set up. */
@@ -7681,7 +7199,7 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l)
/* Otherwise, this is case 3 and we get our own. */
}
- else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo, BINFO_TYPE (rtti_binfo)))
+ else if (!BINFO_NEW_VTABLE_MARKED (orig_binfo))
return inits;
if (!vtbl)
@@ -7747,12 +7265,11 @@ dfs_accumulate_vtbl_inits (binfo, orig_binfo, rtti_binfo, t, l)
constructed. */
static tree
-build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
- tree binfo;
- tree orig_binfo;
- tree t;
- tree rtti_binfo;
- int *non_fn_entries_p;
+build_vtbl_initializer (tree binfo,
+ tree orig_binfo,
+ tree t,
+ tree rtti_binfo,
+ int* non_fn_entries_p)
{
tree v, b;
tree vfun_inits;
@@ -7785,7 +7302,7 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
for (vbase = CLASSTYPE_VBASECLASSES (t);
vbase;
vbase = TREE_CHAIN (vbase))
- CLEAR_BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase));
+ BINFO_VTABLE_PATH_MARKED (TREE_VALUE (vbase)) = 0;
/* If the target requires padding between data entries, add that now. */
if (TARGET_VTABLE_DATA_ENTRY_DISTANCE > 1)
@@ -7816,11 +7333,23 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
{
tree delta;
tree vcall_index;
- tree fn;
+ tree fn, fn_original;
tree init = NULL_TREE;
fn = BV_FN (v);
-
+ fn_original = fn;
+ if (DECL_THUNK_P (fn))
+ {
+ if (!DECL_NAME (fn))
+ finish_thunk (fn);
+ if (THUNK_ALIAS (fn))
+ {
+ fn = THUNK_ALIAS (fn);
+ BV_FN (v) = fn;
+ }
+ fn_original = THUNK_TARGET (fn);
+ }
+
/* If the only definition of this function signature along our
primary base chain is from a lost primary, this vtable slot will
never be used, so just zero it out. This is important to avoid
@@ -7834,7 +7363,7 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
for (b = binfo; ; b = get_primary_binfo (b))
{
/* We found a defn before a lost primary; go ahead as normal. */
- if (look_for_overrides_here (BINFO_TYPE (b), fn))
+ if (look_for_overrides_here (BINFO_TYPE (b), fn_original))
break;
/* The nearest definition is from a lost primary; clear the
@@ -7858,10 +7387,14 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
/* You can't call an abstract virtual function; it's abstract.
So, we replace these functions with __pure_virtual. */
- if (DECL_PURE_VIRTUAL_P (fn))
+ if (DECL_PURE_VIRTUAL_P (fn_original))
fn = abort_fndecl;
else if (!integer_zerop (delta) || vcall_index)
- fn = make_thunk (fn, delta, vcall_index);
+ {
+ fn = make_thunk (fn, /*this_adjusting=*/1, delta, vcall_index);
+ if (!DECL_NAME (fn))
+ finish_thunk (fn);
+ }
/* Take the address of the function, considering it to be of an
appropriate generic type. */
init = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn);
@@ -7906,9 +7439,7 @@ build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo, non_fn_entries_p)
offsets in BINFO, which is in the hierarchy dominated by T. */
static void
-build_vcall_and_vbase_vtbl_entries (binfo, vid)
- tree binfo;
- vtbl_init_data *vid;
+build_vcall_and_vbase_vtbl_entries (tree binfo, vtbl_init_data* vid)
{
tree b;
@@ -7930,9 +7461,7 @@ build_vcall_and_vbase_vtbl_entries (binfo, vid)
where the next vbase offset will go. */
static void
-build_vbase_offset_vtbl_entries (binfo, vid)
- tree binfo;
- vtbl_init_data *vid;
+build_vbase_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
{
tree vbase;
tree t;
@@ -7982,13 +7511,13 @@ build_vbase_offset_vtbl_entries (binfo, vid)
/* Find the instance of this virtual base in the complete
object. */
- b = binfo_for_vbase (BINFO_TYPE (vbase), t);
+ b = copied_binfo (vbase, binfo);
/* If we've already got an offset for this virtual base, we
don't need another one. */
if (BINFO_VTABLE_PATH_MARKED (b))
continue;
- SET_BINFO_VTABLE_PATH_MARKED (b);
+ BINFO_VTABLE_PATH_MARKED (b) = 1;
/* Figure out where we can find this vbase offset. */
delta = size_binop (MULT_EXPR,
@@ -8000,16 +7529,10 @@ build_vbase_offset_vtbl_entries (binfo, vid)
if (binfo != TYPE_BINFO (t))
{
- tree orig_vbase;
-
- /* Find the instance of this virtual base in the type of BINFO. */
- orig_vbase = binfo_for_vbase (BINFO_TYPE (vbase),
- BINFO_TYPE (binfo));
-
/* The vbase offset had better be the same. */
- if (!tree_int_cst_equal (delta,
- BINFO_VPTR_FIELD (orig_vbase)))
- abort ();
+ my_friendly_assert (tree_int_cst_equal (delta,
+ BINFO_VPTR_FIELD (vbase)),
+ 20030202);
}
/* The next vbase will come at a more negative offset. */
@@ -8036,9 +7559,7 @@ build_vbase_offset_vtbl_entries (binfo, vid)
to VID->INITS. */
static void
-build_vcall_offset_vtbl_entries (binfo, vid)
- tree binfo;
- vtbl_init_data *vid;
+build_vcall_offset_vtbl_entries (tree binfo, vtbl_init_data* vid)
{
/* We only need these entries if this base is a virtual base. We
compute the indices -- but do not add to the vtable -- when
@@ -8076,9 +7597,7 @@ build_vcall_offset_vtbl_entries (binfo, vid)
/* Build vcall offsets, starting with those for BINFO. */
static void
-add_vcall_offset_vtbl_entries_r (binfo, vid)
- tree binfo;
- vtbl_init_data *vid;
+add_vcall_offset_vtbl_entries_r (tree binfo, vtbl_init_data* vid)
{
int i;
tree primary_binfo;
@@ -8112,9 +7631,7 @@ add_vcall_offset_vtbl_entries_r (binfo, vid)
/* Called from build_vcall_offset_vtbl_entries_r. */
static void
-add_vcall_offset_vtbl_entries_1 (binfo, vid)
- tree binfo;
- vtbl_init_data* vid;
+add_vcall_offset_vtbl_entries_1 (tree binfo, vtbl_init_data* vid)
{
/* Make entries for the rest of the virtuals. */
if (abi_version_at_least (2))
@@ -8169,8 +7686,8 @@ add_vcall_offset_vtbl_entries_1 (binfo, vid)
if (vid->ctor_vtbl_p)
/* For a ctor vtable we need the equivalent binfo within the hierarchy
where rtti_binfo is the most derived type. */
- non_primary_binfo = get_original_base
- (non_primary_binfo, TYPE_BINFO (BINFO_TYPE (vid->rtti_binfo)));
+ non_primary_binfo
+ = original_binfo (non_primary_binfo, vid->rtti_binfo);
for (base_virtuals = BINFO_VIRTUALS (binfo),
derived_virtuals = BINFO_VIRTUALS (non_primary_binfo),
@@ -8261,20 +7778,18 @@ add_vcall_offset (tree orig_fn, tree binfo, vtbl_init_data *vid)
vcall_offset = fold (build1 (NOP_EXPR, vtable_entry_type,
vcall_offset));
}
- /* Add the intiailizer to the vtable. */
+ /* Add the initializer to the vtable. */
*vid->last_init = build_tree_list (NULL_TREE, vcall_offset);
vid->last_init = &TREE_CHAIN (*vid->last_init);
}
}
-/* Return vtbl initializers for the RTTI entries coresponding to the
+/* Return vtbl initializers for the RTTI entries corresponding to the
BINFO's vtable. The RTTI entries should indicate the object given
by VID->rtti_binfo. */
static void
-build_rtti_vtbl_entries (binfo, vid)
- tree binfo;
- vtbl_init_data *vid;
+build_rtti_vtbl_entries (tree binfo, vtbl_init_data* vid)
{
tree b;
tree t;
diff --git a/contrib/gcc/cp/config-lang.in b/contrib/gcc/cp/config-lang.in
index b8feb03ec30b..8ba5506e8fb1 100644
--- a/contrib/gcc/cp/config-lang.in
+++ b/contrib/gcc/cp/config-lang.in
@@ -1,21 +1,21 @@
# Top level configure fragment for GNU C++.
-# Copyright (C) 1994, 1995, 1997, 1998, 2000, 2001
+# Copyright (C) 1994, 1995, 1997, 1998, 2000, 2001, 2002
# Free Software Foundation, Inc.
-#This file is part of GNU CC.
+#This file is part of GCC.
-#GNU CC is free software; you can redistribute it and/or modify
+#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 2, or (at your option)
#any later version.
-#GNU CC is distributed in the hope that it will be useful,
+#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 GNU CC; see the file COPYING. If not, write to
+#along with GCC; see the file COPYING. If not, write to
#the Free Software Foundation, 59 Temple Place - Suite 330,
#Boston, MA 02111-1307, USA.
@@ -32,6 +32,6 @@ compilers="cc1plus\$(exeext)"
stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)"
-target_libs="${libstdcxx_version} target-gperf"
+target_libs="target-libstdc++-v3 target-gperf"
-gtfiles="\$(srcdir)/cp/mangle.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/parse.y \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/spew.c \$(srcdir)/cp/tree.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c"
+gtfiles="\$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/lex.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c"
diff --git a/contrib/gcc/cp/cp-lang.c b/contrib/gcc/cp/cp-lang.c
index 0d8a4e355b5f..f1f5eedcc548 100644
--- a/contrib/gcc/cp/cp-lang.c
+++ b/contrib/gcc/cp/cp-lang.c
@@ -2,40 +2,50 @@
Copyright 2001, 2002 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <aoliva@redhat.com>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "c-common.h"
#include "toplev.h"
#include "langhooks.h"
#include "langhooks-def.h"
+#include "diagnostic.h"
+#include "cxx-pretty-print.h"
-static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
-static bool ok_to_generate_alias_set_for_type PARAMS ((tree));
-static bool cxx_warn_unused_global_decl PARAMS ((tree));
-static tree cp_expr_size PARAMS ((tree));
-static bool cp_var_mod_type_p PARAMS ((tree));
+enum c_language_kind c_language = clk_cxx;
+
+static HOST_WIDE_INT cxx_get_alias_set (tree);
+static bool ok_to_generate_alias_set_for_type (tree);
+static bool cxx_warn_unused_global_decl (tree);
+static tree cp_expr_size (tree);
+static size_t cp_tree_size (enum tree_code);
+static bool cp_var_mod_type_p (tree);
+static void cxx_initialize_diagnostics (diagnostic_context *);
#undef LANG_HOOKS_NAME
#define LANG_HOOKS_NAME "GNU C++"
+#undef LANG_HOOKS_TREE_SIZE
+#define LANG_HOOKS_TREE_SIZE cp_tree_size
#undef LANG_HOOKS_INIT
#define LANG_HOOKS_INIT cxx_init
#undef LANG_HOOKS_FINISH
@@ -43,9 +53,15 @@ static bool cp_var_mod_type_p PARAMS ((tree));
#undef LANG_HOOKS_CLEAR_BINDING_STACK
#define LANG_HOOKS_CLEAR_BINDING_STACK pop_everything
#undef LANG_HOOKS_INIT_OPTIONS
-#define LANG_HOOKS_INIT_OPTIONS cxx_init_options
-#undef LANG_HOOKS_DECODE_OPTION
-#define LANG_HOOKS_DECODE_OPTION c_common_decode_option
+#define LANG_HOOKS_INIT_OPTIONS c_common_init_options
+#undef LANG_HOOKS_INITIALIZE_DIAGNOSTICS
+#define LANG_HOOKS_INITIALIZE_DIAGNOSTICS cxx_initialize_diagnostics
+#undef LANG_HOOKS_HANDLE_OPTION
+#define LANG_HOOKS_HANDLE_OPTION c_common_handle_option
+#undef LANG_HOOKS_HANDLE_FILENAME
+#define LANG_HOOKS_HANDLE_FILENAME c_common_handle_filename
+#undef LANG_HOOKS_MISSING_ARGUMENT
+#define LANG_HOOKS_MISSING_ARGUMENT c_common_missing_argument
#undef LANG_HOOKS_POST_OPTIONS
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
#undef LANG_HOOKS_GET_ALIAS_SET
@@ -66,8 +82,6 @@ static bool cp_var_mod_type_p PARAMS ((tree));
#define LANG_HOOKS_MAYBE_BUILD_CLEANUP cxx_maybe_build_cleanup
#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion
-#undef LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES
-#define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES cxx_insert_default_attributes
#undef LANG_HOOKS_UNSAFE_FOR_REEVAL
#define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval
#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
@@ -88,10 +102,18 @@ static bool cp_var_mod_type_p PARAMS ((tree));
#define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name
#undef LANG_HOOKS_PRINT_ERROR_FUNCTION
#define LANG_HOOKS_PRINT_ERROR_FUNCTION cxx_print_error_function
+#undef LANG_HOOKS_BUILTIN_TYPE_DECLS
+#define LANG_HOOKS_BUILTIN_TYPE_DECLS cxx_builtin_type_decls
+#undef LANG_HOOKS_PUSHLEVEL
+#define LANG_HOOKS_PUSHLEVEL lhd_do_nothing_i
+#undef LANG_HOOKS_POPLEVEL
+#define LANG_HOOKS_POPLEVEL lhd_do_nothing_iii_return_null_tree
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl
#undef LANG_HOOKS_WRITE_GLOBALS
#define LANG_HOOKS_WRITE_GLOBALS lhd_do_nothing
+#undef LANG_HOOKS_DECL_UNINIT
+#define LANG_HOOKS_DECL_UNINIT c_decl_uninit
#undef LANG_HOOKS_FUNCTION_INIT
@@ -99,6 +121,11 @@ static bool cp_var_mod_type_p PARAMS ((tree));
#undef LANG_HOOKS_FUNCTION_FINAL
#define LANG_HOOKS_FUNCTION_FINAL cxx_pop_function_context
+#undef LANG_HOOKS_RTL_EXPAND_START
+#define LANG_HOOKS_RTL_EXPAND_START cxx_expand_function_start
+#undef LANG_HOOKS_RTL_EXPAND_STMT
+#define LANG_HOOKS_RTL_EXPAND_STMT expand_stmt
+
/* Attribute hooks. */
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE c_common_attribute_table
@@ -129,10 +156,8 @@ static bool cp_var_mod_type_p PARAMS ((tree));
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P anon_aggr_type_p
#undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P
#define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P cp_var_mod_type_p
-#undef LANG_HOOKS_TREE_INLINING_START_INLINING
-#define LANG_HOOKS_TREE_INLINING_START_INLINING cp_start_inlining
-#undef LANG_HOOKS_TREE_INLINING_END_INLINING
-#define LANG_HOOKS_TREE_INLINING_END_INLINING cp_end_inlining
+#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS
+#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS c_estimate_num_insns
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree
#undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN
@@ -140,6 +165,11 @@ static bool cp_var_mod_type_p PARAMS ((tree));
#undef LANG_HOOKS_EXPR_SIZE
#define LANG_HOOKS_EXPR_SIZE cp_expr_size
+#undef LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR
+#define LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR cxx_callgraph_analyze_expr
+#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
+#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION expand_body
+
#undef LANG_HOOKS_MAKE_TYPE
#define LANG_HOOKS_MAKE_TYPE cxx_make_type
#undef LANG_HOOKS_TYPE_FOR_MODE
@@ -156,6 +186,8 @@ static bool cp_var_mod_type_p PARAMS ((tree));
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR cxx_incomplete_type_error
#undef LANG_HOOKS_TYPE_PROMOTES_TO
#define LANG_HOOKS_TYPE_PROMOTES_TO cxx_type_promotes_to
+#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
+#define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
/* Each front end provides its own hooks, for toplev.c. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@@ -205,8 +237,7 @@ const char *const tree_code_name[] = {
Return TRUE if T safe for aliasing FALSE otherwise. */
static bool
-ok_to_generate_alias_set_for_type (t)
- tree t;
+ok_to_generate_alias_set_for_type (tree t)
{
if (TYPE_PTRMEMFUNC_P (t))
return true;
@@ -259,9 +290,15 @@ ok_to_generate_alias_set_for_type (t)
/* Special routine to get the alias set for C++. */
static HOST_WIDE_INT
-cxx_get_alias_set (t)
- tree t;
+cxx_get_alias_set (tree t)
{
+ if (TREE_CODE (t) == RECORD_TYPE
+ && TYPE_CONTEXT (t) && CLASS_TYPE_P (TYPE_CONTEXT (t))
+ && CLASSTYPE_AS_BASE (TYPE_CONTEXT (t)) == t)
+ /* The base variant of a type must be in the same alias set as the
+ complete type. */
+ return get_alias_set (TYPE_CONTEXT (t));
+
if (/* It's not yet safe to use alias sets for some classes in C++. */
!ok_to_generate_alias_set_for_type (t)
/* Nor is it safe to use alias sets for pointers-to-member
@@ -277,8 +314,7 @@ cxx_get_alias_set (t)
/* Called from check_global_declarations. */
static bool
-cxx_warn_unused_global_decl (decl)
- tree decl;
+cxx_warn_unused_global_decl (tree decl)
{
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
return false;
@@ -297,8 +333,7 @@ cxx_warn_unused_global_decl (decl)
might have allocated something there. */
static tree
-cp_expr_size (exp)
- tree exp;
+cp_expr_size (tree exp)
{
if (CLASS_TYPE_P (TREE_TYPE (exp)))
{
@@ -312,13 +347,33 @@ cp_expr_size (exp)
abort ();
/* This would be wrong for a type with virtual bases, but they are
caught by the abort above. */
- return CLASSTYPE_SIZE_UNIT (TREE_TYPE (exp));
+ return (is_empty_class (TREE_TYPE (exp))
+ ? size_zero_node
+ : CLASSTYPE_SIZE_UNIT (TREE_TYPE (exp)));
}
else
/* Use the default code. */
return lhd_expr_size (exp);
}
+/* Langhook for tree_size: determine size of our 'x' and 'c' nodes. */
+static size_t
+cp_tree_size (enum tree_code code)
+{
+ switch (code)
+ {
+ case PTRMEM_CST: return sizeof (struct ptrmem_cst);
+ case BASELINK: return sizeof (struct tree_baselink);
+ case TEMPLATE_PARM_INDEX: return sizeof (template_parm_index);
+ case DEFAULT_ARG: return sizeof (struct tree_default_arg);
+ case OVERLOAD: return sizeof (struct tree_overload);
+ case WRAPPER: return sizeof (struct tree_wrapper);
+ default:
+ abort ();
+ }
+ /* NOTREACHED */
+}
+
/* Returns true if T is a variably modified type, in the sense of C99.
This routine needs only check cases that cannot be handled by the
language-independent logic in tree-inline.c. */
@@ -328,7 +383,7 @@ cp_var_mod_type_p (tree type)
{
/* If TYPE is a pointer-to-member, it is variably modified if either
the class or the member are variably modified. */
- if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type))
+ if (TYPE_PTR_TO_MEMBER_P (type))
return (variably_modified_type_p (TYPE_PTRMEM_CLASS_TYPE (type))
|| variably_modified_type_p (TYPE_PTRMEM_POINTED_TO_TYPE (type)));
@@ -336,3 +391,24 @@ cp_var_mod_type_p (tree type)
return false;
}
+/* Stub routine to tell people that this doesn't work yet. */
+void
+c_reset_state (void)
+{
+ sorry ("inter-module optimisations not implemented yet");
+}
+
+/* Construct a C++-aware pretty-printer for CONTEXT. It is assumed
+ that CONTEXT->printer is an already constructed basic pretty_printer. */
+static void
+cxx_initialize_diagnostics (diagnostic_context *context)
+{
+ pretty_printer *base = context->printer;
+ cxx_pretty_printer *pp = xmalloc (sizeof (cxx_pretty_printer));
+ memcpy (pp_base (pp), base, sizeof (pretty_printer));
+ pp_cxx_pretty_printer_init (pp);
+ context->printer = (pretty_printer *) pp;
+
+ /* It is safe to free this object because it was previously malloc()'d. */
+ free (base);
+}
diff --git a/contrib/gcc/cp/cp-tree.def b/contrib/gcc/cp/cp-tree.def
index cee19abec99f..36b7aaa85e83 100644
--- a/contrib/gcc/cp/cp-tree.def
+++ b/contrib/gcc/cp/cp-tree.def
@@ -1,24 +1,24 @@
/* This file contains the definitions and documentation for the
additional tree codes used in the GNU C++ compiler (see tree.def
for the standard codes).
- Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998, 2003,
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -26,28 +26,28 @@ Boston, MA 02111-1307, USA. */
/* An OFFSET_REF is used in two situations:
1. An expression of the form `A::m' where `A' is a class and `m' is
- a non-static data member. In this case, operand 0 will be a
- TYPE (corresponding to `A') and operand 1 will be a FIELD_DECL
- (corresponding to `m'.
+ a non-static member. In this case, operand 0 will be a TYPE
+ (corresponding to `A') and operand 1 will be a FIELD_DECL,
+ BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m').
The expression is a pointer-to-member if its address is taken,
but simply denotes a member of the object if its address isnot
taken. In the latter case, resolve_offset_ref is used to
convert it to a representation of the member referred to by the
OFFSET_REF.
+
+ This form is only used during the parsing phase; once semantic
+ analysis has taken place they are eliminated.
2. An expression of the form `x.*p'. In this case, operand 0 will
be an expression corresponding to `x' and operand 1 will be an
- expression with pointer-to-member type.
-
- OFFSET_REFs are only used during the parsing phase; once semantic
- analysis has taken place they are eliminated. */
+ expression with pointer-to-member type. */
DEFTREECODE (OFFSET_REF, "offset_ref", 'r', 2)
/* A pointer-to-member constant. For a pointer-to-member constant
`X::Y' The PTRMEM_CST_CLASS is the RECORD_TYPE for `X' and the
PTRMEM_CST_MEMBER is the _DECL for `Y'. */
-DEFTREECODE (PTRMEM_CST, "ptrmem_cst", 'c', 2)
+DEFTREECODE (PTRMEM_CST, "ptrmem_cst", 'c', 0)
/* For NEW_EXPR, operand 0 is the placement list.
Operand 1 is the new-declarator.
@@ -62,8 +62,7 @@ DEFTREECODE (DELETE_EXPR, "dl_expr", 'e', 2)
DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", 'e', 2)
/* Value is reference to particular overloaded class method.
- Operand 0 is the class name (an IDENTIFIER_NODE);
- operand 1 is the field (also an IDENTIFIER_NODE).
+ Operand 0 is the class, operand 1 is the field
The COMPLEXITY field holds the class level (usually 0). */
DEFTREECODE (SCOPE_REF, "scope_ref", 'r', 2)
@@ -89,6 +88,10 @@ DEFTREECODE (THROW_EXPR, "throw_expr", 'e', 1)
these to avoid actually creating instances of the empty classes. */
DEFTREECODE (EMPTY_CLASS_EXPR, "empty_class_expr", 'e', 0)
+/* A DECL which is really just a placeholder for an expression. Used to
+ implement non-class scope anonymous unions. */
+DEFTREECODE (ALIAS_DECL, "alias_decl", 'd', 0)
+
/* A reference to a member function or member functions from a base
class. BASELINK_FUNCTIONS gives the FUNCTION_DECL,
TEMPLATE_DECL, OVERLOAD, or TEMPLATE_ID_EXPR corresponding to the
@@ -101,7 +104,7 @@ DEFTREECODE (EMPTY_CLASS_EXPR, "empty_class_expr", 'e', 0)
the type of the expression. This type is either a FUNCTION_TYPE,
METHOD_TYPE, or `unknown_type_node' indicating that the function is
overloaded. */
-DEFTREECODE (BASELINK, "baselink", 'e', 3)
+DEFTREECODE (BASELINK, "baselink", 'x', 0)
/* Template definition. The following fields have the specified uses,
although there are other macros in cp-tree.h that should be used for
@@ -153,16 +156,7 @@ DEFTREECODE (TEMPLATE_DECL, "template_decl", 'd', 0)
The LEVEL is the level of the parameter when we are worrying about
the types of things; the ORIG_LEVEL is the level when we are
worrying about instantiating things. */
-DEFTREECODE (TEMPLATE_PARM_INDEX, "template_parm_index", 'x',
- /* The addition of (sizeof(tree) - 1) in the next expression
- is to handle the case when padding pushes us past an even
- multiple of sizeof(tree). */
- /* We used to try to calculate this using
- 1+3*sizeof(HOST_WIDE_INT), but that fails if alignment
- makes it bigger. */
- ((sizeof (template_parm_index) - sizeof (struct tree_common))
- + sizeof (tree) - 1)
- / sizeof (tree))
+DEFTREECODE (TEMPLATE_PARM_INDEX, "template_parm_index", 'x', 0)
/* Index into a template parameter list. This parameter must be a type.
The TYPE_FIELDS value will be a TEMPLATE_PARM_INDEX. */
@@ -201,36 +195,31 @@ DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", 't', 0)
DEFTREECODE (TYPEOF_TYPE, "typeof_type", 't', 0)
/* A using declaration. DECL_INITIAL contains the specified scope.
- This is not an alias, but is later expanded into multiple aliases. */
+ This is not an alias, but is later expanded into multiple aliases.
+ The decl will have a NULL_TYPE iff the scope is a dependent scope,
+ otherwise it will have a void type. */
DEFTREECODE (USING_DECL, "using_decl", 'd', 0)
/* A using directive. The operand is USING_STMT_NAMESPACE. */
DEFTREECODE (USING_STMT, "using_directive", 'e', 1)
/* An un-parsed default argument. Looks like an IDENTIFIER_NODE. */
-DEFTREECODE (DEFAULT_ARG, "default_arg", 'x', 2)
+DEFTREECODE (DEFAULT_ARG, "default_arg", 'x', 0)
/* A template-id, like foo<int>. The first operand is the template.
- The second is the TREE_LIST or TREE_VEC of explicitly specified
- arguments. The template will be a FUNCTION_DECL, TEMPLATE_DECL, or
- an OVERLOAD. If the template-id refers to a member template, the
- template may be an IDENTIFIER_NODE. In an uninstantiated template,
- the template may be a LOOKUP_EXPR. */
+ The second is NULL if there are no explicit arguments, or a
+ TREE_VEC of arguments. The template will be a FUNCTION_DECL,
+ TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a
+ member template, the template may be an IDENTIFIER_NODE. */
DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2)
/* A list-like node for chaining overloading candidates. TREE_TYPE is
the original name, and the parameter is the FUNCTION_DECL. */
-DEFTREECODE (OVERLOAD, "overload", 'x', 1)
+DEFTREECODE (OVERLOAD, "overload", 'x', 0)
/* A generic wrapper for something not tree that we want to include in
tree structure. */
-DEFTREECODE (WRAPPER, "wrapper", 'x', 1)
-
-/* Used to represent deferred name lookup for dependent names while
- parsing a template declaration. The first argument is an
- IDENTIFIER_NODE for the name in question. The TREE_TYPE is
- unused. */
-DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 1)
+DEFTREECODE (WRAPPER, "wrapper", 'x', 0)
/* A whole bunch of tree codes for the initial, superficial parsing of
templates. */
@@ -244,10 +233,20 @@ DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", 'e', 2)
DEFTREECODE (TYPEID_EXPR, "typeid_expr", 'e', 1)
DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", 'e', 3)
+/* A placeholder for an expression that is not type-dependent, but
+ does occur in a template. When an expression that is not
+ type-dependent appears in a larger expression, we must compute the
+ type of that larger expression. That computation would normally
+ modify the original expression, which would change the mangling of
+ that expression if it appeared in a template argument list. In
+ that situation, we create a NON_DEPENDENT_EXPR to take the place of
+ the original expression. The expression is the only operand -- it
+ is only needed for diagnostics. */
+DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", 'e', 1)
+
/* CTOR_INITIALIZER is a placeholder in template code for a call to
setup_vtbl_pointer (and appears in all functions, not just ctors). */
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 1)
-DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2)
DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", 'e', 2)
/* A HANDLER wraps a catch handler for the HANDLER_TYPE. If this is
diff --git a/contrib/gcc/cp/cp-tree.h b/contrib/gcc/cp/cp-tree.h
index 493206d9ae43..b3ceab4945de 100644
--- a/contrib/gcc/cp/cp-tree.h
+++ b/contrib/gcc/cp/cp-tree.h
@@ -1,38 +1,36 @@
/* Definitions for C++ parsing and type checking.
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef GCC_CP_TREE_H
#define GCC_CP_TREE_H
+#include "ggc.h"
#include "function.h"
#include "hashtab.h"
#include "splay-tree.h"
#include "varray.h"
-#ifndef __GNUC__
-#error "You should be using 'make bootstrap' -- see installation instructions"
-#endif
-
#include "c-common.h"
+#include "name-lookup.h"
struct diagnostic_context;
@@ -41,13 +39,15 @@ struct diagnostic_context;
IDENTIFIER_MARKED (IDENTIFIER_NODEs)
NEW_EXPR_USE_GLOBAL (in NEW_EXPR).
DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR).
- LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR).
+ COMPOUND_EXPR_OVERLOADED (in COMPOUND_EXPR).
TREE_INDIRECT_USING (in NAMESPACE_DECL).
ICS_USER_FLAG (in _CONV)
CLEANUP_P (in TRY_BLOCK)
AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF)
PARMLIST_ELLIPSIS_P (in PARMLIST)
+ DECL_PRETTY_FUNCTION_P (in VAR_DECL)
+ KOENIG_LOOKUP_P (in CALL_EXPR)
1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@@ -55,13 +55,14 @@ struct diagnostic_context;
(TREE_CALLS_NEW) (in _EXPR or _REF) (commented-out).
TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (in _TYPE).
ICS_ELLIPSIS_FLAG (in _CONV)
- BINFO_ACCESS (in BINFO)
+ BINFO_DEPENDENT_BASE_P (in BINFO)
DECL_INITIALIZED_P (in VAR_DECL)
2: IDENTIFIER_OPNAME_P.
TYPE_POLYMORPHIC_P (in _TYPE)
ICS_THIS_FLAG (in _CONV)
BINFO_LOST_PRIMARY_P (in BINFO)
TREE_PARMLIST (in TREE_LIST)
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL)
3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE).
BINFO_VTABLE_PATH_MARKED.
BINFO_PUSHDECLS_MARKED.
@@ -75,16 +76,17 @@ struct diagnostic_context;
NEED_TEMPORARY_P (in REF_BIND, BASE_CONV)
IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE)
5: C_IS_RESERVED_WORD (in IDENTIFIER_NODE)
- 6: BINFO_ACCESS (in BINFO)
+ DECL_VTABLE_OR_VTT_P (in VAR_DECL)
+ 6: For future expansion
Usage of TYPE_LANG_FLAG_?:
- 0: C_TYPE_FIELDS_READONLY (in RECORD_TYPE or UNION_TYPE).
+ 0: TYPE_DEPENDENT_P
1: TYPE_HAS_CONSTRUCTOR.
2: TYPE_HAS_DESTRUCTOR.
3: TYPE_FOR_JAVA.
4: TYPE_HAS_NONTRIVIAL_DESTRUCTOR
5: IS_AGGR_TYPE.
- 6: TYPE_BUILT_IN.
+ 6: TYPE_DEPENDENT_P_VALID
Usage of DECL_LANG_FLAG_?:
0: DECL_ERROR_REPORTED (in VAR_DECL).
@@ -125,7 +127,7 @@ struct diagnostic_context;
The BV_DELTA of each node gives the amount by which to adjust the
`this' pointer when calling the function. If the method is an
- overriden version of a base class method, then it is assumed
+ overridden version of a base class method, then it is assumed
that, prior to adjustment, the this pointer points to an object
of the base class.
@@ -147,7 +149,7 @@ struct diagnostic_context;
function, it is eventually set to an INTEGER_CST indicating the
index in the vtable at which this function can be found. When
a virtual function is declared, but before it is known what
- function is overriden, this field is the error_mark_node.
+ function is overridden, this field is the error_mark_node.
Temporarily, it may be set to a TREE_LIST whose TREE_VALUE is
the virtual function this one overrides, and whose TREE_CHAIN is
@@ -157,7 +159,7 @@ struct diagnostic_context;
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
-#define VAR_OR_FUNCTION_DECL_CHECK(NODE) \
+#define VAR_OR_FUNCTION_DECL_CHECK(NODE) __extension__ \
({ const tree __t = (NODE); \
enum tree_code const __c = TREE_CODE(__t); \
if (__c != VAR_DECL && __c != FUNCTION_DECL) \
@@ -165,7 +167,7 @@ struct diagnostic_context;
__FUNCTION__); \
__t; })
-#define VAR_FUNCTION_OR_PARM_DECL_CHECK(NODE) \
+#define VAR_FUNCTION_OR_PARM_DECL_CHECK(NODE) __extension__ \
({ const tree __t = (NODE); \
enum tree_code const __c = TREE_CODE(__t); \
if (__c != VAR_DECL \
@@ -175,7 +177,7 @@ struct diagnostic_context;
__FUNCTION__); \
__t; })
-#define VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK(NODE) \
+#define VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK(NODE) __extension__ \
({ const tree __t = (NODE); \
enum tree_code const __c = TREE_CODE(__t); \
if (__c != VAR_DECL \
@@ -186,7 +188,7 @@ struct diagnostic_context;
__FUNCTION__); \
__t; })
-#define RECORD_OR_UNION_TYPE_CHECK(NODE) \
+#define RECORD_OR_UNION_TYPE_CHECK(NODE) __extension__ \
({ const tree __t = (NODE); \
enum tree_code const __c = TREE_CODE(__t); \
if (__c != RECORD_TYPE && __c != UNION_TYPE) \
@@ -194,7 +196,7 @@ struct diagnostic_context;
__FUNCTION__); \
__t; })
-#define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) \
+#define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) __extension__ \
({ const tree __t = (NODE); \
enum tree_code const __c = TREE_CODE(__t); \
if (__c != BOUND_TEMPLATE_TEMPLATE_PARM) \
@@ -212,62 +214,6 @@ struct diagnostic_context;
#endif
-/* Returns TRUE if generated code should match ABI version N or
- greater is in use. */
-
-#define abi_version_at_least(N) \
- (flag_abi_version == 0 || flag_abi_version >= (N))
-
-
-/* Datatype used to temporarily save C++ bindings (for implicit
- instantiations purposes and like). Implemented in decl.c. */
-typedef struct cxx_saved_binding cxx_saved_binding;
-
-/* Datatype that represents binding established by a declaration between
- a name and a C++ entity. */
-typedef struct cxx_binding cxx_binding;
-
-/* (GC-)allocate a cxx_binding object. */
-#define cxx_binding_make() (ggc_alloc (sizeof (cxx_binding)))
-
-/* Zero out a cxx_binding pointed to by B. */
-#define cxx_binding_clear(B) memset ((B), 0, sizeof (cxx_binding))
-
-struct cxx_binding GTY(())
-{
- /* Link to chain together various bindings for this name. */
- cxx_binding *previous;
- /* The non-type entity this name is bound to. */
- tree value;
- /* The type entity this name is bound to. */
- tree type;
- union tree_binding_u {
- tree GTY ((tag ("0"))) scope;
- struct cp_binding_level * GTY ((tag ("1"))) level;
- } GTY ((desc ("%0.has_level"))) scope;
- unsigned has_level : 1;
- unsigned value_is_inherited : 1;
- unsigned is_local : 1;
-};
-
-/* The type of dictionary used to map names to types declared at
- a given scope. */
-typedef struct binding_table_s *binding_table;
-typedef struct binding_entry_s *binding_entry;
-
-/* The type of a routine repeatedly called by binding_table_foreach. */
-typedef void (*bt_foreach_proc) (binding_entry, void *);
-
-struct binding_entry_s GTY(())
-{
- binding_entry chain;
- tree name;
- tree type;
-};
-
-extern void binding_table_foreach (binding_table, bt_foreach_proc, void *);
-extern binding_entry binding_table_find (binding_table, tree);
-extern void cxx_remember_type_decls (binding_table);
/* Language-dependent contents of an identifier. */
@@ -278,7 +224,9 @@ struct lang_identifier GTY(())
cxx_binding *bindings;
tree class_value;
tree class_template_info;
- struct lang_id2 *x;
+ tree label_value;
+ tree implicit_decl;
+ tree error_locus;
};
/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a
@@ -287,26 +235,9 @@ struct lang_identifier GTY(())
#define C_IS_RESERVED_WORD(ID) TREE_LANG_FLAG_5 (ID)
-extern const short rid_to_yy[RID_MAX];
-#define C_RID_YYCODE(ID) rid_to_yy[C_RID_CODE (ID)]
-
#define LANG_IDENTIFIER_CAST(NODE) \
((struct lang_identifier*)IDENTIFIER_NODE_CHECK (NODE))
-struct lang_id2 GTY(())
-{
- tree label_value;
- tree implicit_decl;
- tree error_locus;
-};
-
-typedef struct flagged_type_tree_s GTY(())
-{
- tree t;
- int new_type_flag;
- tree lookups;
-} flagged_type_tree;
-
typedef struct template_parm_index_s GTY(())
{
struct tree_common common;
@@ -326,31 +257,6 @@ struct ptrmem_cst GTY(())
};
typedef struct ptrmem_cst * ptrmem_cst_t;
-/* Nonzero if this binding is for a local scope, as opposed to a class
- or namespace scope. */
-#define LOCAL_BINDING_P(NODE) ((NODE)->is_local)
-
-/* Nonzero if BINDING_VALUE is from a base class of the class which is
- currently being defined. */
-#define INHERITED_VALUE_BINDING_P(NODE) ((NODE)->value_is_inherited)
-
-/* For a binding between a name and an entity at a non-local scope,
- defines the scope where the binding is declared. (Either a class
- _TYPE node, or a NAMESPACE_DECL.) This macro should be used only
- for namespace-level bindings; on the IDENTIFIER_BINDING list
- BINDING_LEVEL is used instead. */
-#define BINDING_SCOPE(NODE) ((NODE)->scope.scope)
-
-/* Nonzero if NODE has BINDING_LEVEL, rather than BINDING_SCOPE. */
-#define BINDING_HAS_LEVEL_P(NODE) ((NODE)->has_level)
-
-/* This is the declaration bound to the name. Possible values:
- variable, overloaded function, namespace, template, enumerator. */
-#define BINDING_VALUE(NODE) ((NODE)->value)
-
-/* If name is bound to a type, this is the type (struct, union, enum). */
-#define BINDING_TYPE(NODE) ((NODE)->type)
-
#define IDENTIFIER_GLOBAL_VALUE(NODE) \
namespace_binding ((NODE), global_namespace)
#define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \
@@ -408,16 +314,16 @@ struct tree_overload GTY(())
(TREE_CODE (NODE) == BASELINK)
/* The BINFO indicating the base from which the BASELINK_FUNCTIONS came. */
#define BASELINK_BINFO(NODE) \
- (TREE_OPERAND (BASELINK_CHECK (NODE), 0))
+ (((struct tree_baselink*) BASELINK_CHECK (NODE))->binfo)
/* The functions referred to by the BASELINK; either a FUNCTION_DECL,
a TEMPLATE_DECL, an OVERLOAD, or a TEMPLATE_ID_EXPR. */
#define BASELINK_FUNCTIONS(NODE) \
- (TREE_OPERAND (BASELINK_CHECK (NODE), 1))
+ (((struct tree_baselink*) BASELINK_CHECK (NODE))->functions)
/* The BINFO in which the search for the functions indicated by this baselink
began. This base is used to determine the accessibility of functions
selected by overload resolution. */
#define BASELINK_ACCESS_BINFO(NODE) \
- (TREE_OPERAND (BASELINK_CHECK (NODE), 2))
+ (((struct tree_baselink*) BASELINK_CHECK (NODE))->access_binfo)
/* For a type-conversion operator, the BASELINK_OPTYPE indicates the type
to which the conversion should occur. This value is important if
the BASELINK_FUNCTIONS include a template conversion operator --
@@ -426,6 +332,14 @@ struct tree_overload GTY(())
#define BASELINK_OPTYPE(NODE) \
(TREE_CHAIN (BASELINK_CHECK (NODE)))
+struct tree_baselink GTY(())
+{
+ struct tree_common common;
+ tree binfo;
+ tree functions;
+ tree access_binfo;
+};
+
#define WRAPPER_ZC(NODE) (((struct tree_wrapper*)WRAPPER_CHECK (NODE))->z_c)
struct tree_wrapper GTY(())
@@ -434,14 +348,21 @@ struct tree_wrapper GTY(())
struct z_candidate *z_c;
};
-#define SRCLOC_FILE(NODE) (((struct tree_srcloc*)SRCLOC_CHECK (NODE))->filename)
-#define SRCLOC_LINE(NODE) (((struct tree_srcloc*)SRCLOC_CHECK (NODE))->linenum)
-struct tree_srcloc GTY(())
+/* The different kinds of ids that we ecounter. */
+
+typedef enum cp_id_kind
{
- struct tree_common common;
- const char *filename;
- int linenum;
-};
+ /* Not an id at all. */
+ CP_ID_KIND_NONE,
+ /* An unqualified-id that is not a template-id. */
+ CP_ID_KIND_UNQUALIFIED,
+ /* An unqualified-id that is a dependent name. */
+ CP_ID_KIND_UNQUALIFIED_DEPENDENT,
+ /* An unqualified template-id. */
+ CP_ID_KIND_TEMPLATE_ID,
+ /* A qualified-id. */
+ CP_ID_KIND_QUALIFIED
+} cp_id_kind;
/* Macros for access to language-specific slots in an identifier. */
@@ -452,22 +373,22 @@ struct tree_srcloc GTY(())
/* The IDENTIFIER_BINDING is the innermost cxx_binding for the
identifier. It's PREVIOUS is the next outermost binding. Each
- BINDING_VALUE is a DECL for the associated declaration. Thus,
+ VALUE field is a DECL for the associated declaration. Thus,
name lookup consists simply of pulling off the node at the front
of the list (modulo oddities for looking up the names of types,
- and such.) You can use BINDING_SCOPE or BINDING_LEVEL to
- determine the scope that bound the name. */
+ and such.) You can use SCOPE field to determine the scope
+ that bound the name. */
#define IDENTIFIER_BINDING(NODE) \
(LANG_IDENTIFIER_CAST (NODE)->bindings)
/* The IDENTIFIER_VALUE is the value of the IDENTIFIER_BINDING, or
NULL_TREE if there is no binding. */
#define IDENTIFIER_VALUE(NODE) \
- (IDENTIFIER_BINDING (NODE) ? BINDING_VALUE (IDENTIFIER_BINDING (NODE)) : 0)
+ (IDENTIFIER_BINDING (NODE) ? IDENTIFIER_BINDING (NODE)->value : NULL)
/* If IDENTIFIER_CLASS_VALUE is set, then NODE is bound in the current
class, and IDENTIFIER_CLASS_VALUE is the value binding. This is
- just a pointer to the BINDING_VALUE of one of the bindings in the
+ just a pointer to the VALUE field of one of the bindings in the
IDENTIFIER_BINDINGs list, so any time that this is non-NULL so is
IDENTIFIER_BINDING. */
#define IDENTIFIER_CLASS_VALUE(NODE) \
@@ -482,30 +403,20 @@ struct tree_srcloc GTY(())
#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = (TYPE))
#define IDENTIFIER_HAS_TYPE_VALUE(NODE) (IDENTIFIER_TYPE_VALUE (NODE) ? 1 : 0)
-#define LANG_ID_FIELD(NAME, NODE) \
- (LANG_IDENTIFIER_CAST (NODE)->x \
- ? LANG_IDENTIFIER_CAST (NODE)->x->NAME : 0)
-
-#define SET_LANG_ID(NODE, VALUE, NAME) \
- (LANG_IDENTIFIER_CAST (NODE)->x == 0 \
- ? LANG_IDENTIFIER_CAST (NODE)->x \
- = (struct lang_id2 *)ggc_alloc_cleared (sizeof (struct lang_id2)) : 0, \
- LANG_IDENTIFIER_CAST (NODE)->x->NAME = (VALUE))
-
#define IDENTIFIER_LABEL_VALUE(NODE) \
- LANG_ID_FIELD (label_value, NODE)
+ (LANG_IDENTIFIER_CAST (NODE)->label_value)
#define SET_IDENTIFIER_LABEL_VALUE(NODE, VALUE) \
- SET_LANG_ID (NODE, VALUE, label_value)
+ IDENTIFIER_LABEL_VALUE (NODE) = (VALUE)
#define IDENTIFIER_IMPLICIT_DECL(NODE) \
- LANG_ID_FIELD (implicit_decl, NODE)
+ (LANG_IDENTIFIER_CAST (NODE)->implicit_decl)
#define SET_IDENTIFIER_IMPLICIT_DECL(NODE, VALUE) \
- SET_LANG_ID (NODE, VALUE, implicit_decl)
+ IDENTIFIER_IMPLICIT_DECL (NODE) = (VALUE)
#define IDENTIFIER_ERROR_LOCUS(NODE) \
- LANG_ID_FIELD (error_locus, NODE)
+ (LANG_IDENTIFIER_CAST (NODE)->error_locus)
#define SET_IDENTIFIER_ERROR_LOCUS(NODE, VALUE) \
- SET_LANG_ID (NODE, VALUE, error_locus)
+ IDENTIFIER_ERROR_LOCUS (NODE) = (VALUE)
/* Nonzero if this identifier is used as a virtual function name somewhere
(optimizes searches). */
@@ -526,21 +437,34 @@ struct tree_srcloc GTY(())
TREE_LANG_FLAG_3 (NODE)
/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */
-#define C_TYPE_FIELDS_READONLY(TYPE) TYPE_LANG_FLAG_0 (TYPE)
+#define C_TYPE_FIELDS_READONLY(TYPE) \
+ (LANG_TYPE_CLASS_CHECK (TYPE)->fields_readonly)
/* Store a value in that field. */
#define C_SET_EXP_ORIGINAL_CODE(EXP, CODE) \
(TREE_COMPLEXITY (EXP) = (int)(CODE))
+/* The tokens stored in the default argument. */
+
+#define DEFARG_TOKENS(NODE) \
+ (((struct tree_default_arg *)DEFAULT_ARG_CHECK (NODE))->tokens)
+
+struct tree_default_arg GTY (())
+{
+ struct tree_common common;
+ struct cp_token_cache *tokens;
+};
+
enum cp_tree_node_structure_enum {
- TS_CP_COMMON,
TS_CP_GENERIC,
TS_CP_IDENTIFIER,
TS_CP_TPI,
TS_CP_PTRMEM,
+ TS_CP_BINDING,
TS_CP_OVERLOAD,
+ TS_CP_BASELINK,
TS_CP_WRAPPER,
- TS_CP_SRCLOC,
+ TS_CP_DEFAULT_ARG,
LAST_TS_CP_ENUM
};
@@ -548,14 +472,14 @@ enum cp_tree_node_structure_enum {
union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"),
chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
{
- struct tree_common GTY ((tag ("TS_CP_COMMON"))) common;
union tree_node GTY ((tag ("TS_CP_GENERIC"),
desc ("tree_node_structure (&%h)"))) generic;
struct template_parm_index_s GTY ((tag ("TS_CP_TPI"))) tpi;
struct ptrmem_cst GTY ((tag ("TS_CP_PTRMEM"))) ptrmem;
struct tree_overload GTY ((tag ("TS_CP_OVERLOAD"))) overload;
+ struct tree_baselink GTY ((tag ("TS_CP_BASELINK"))) baselink;
struct tree_wrapper GTY ((tag ("TS_CP_WRAPPER"))) wrapper;
- struct tree_srcloc GTY ((tag ("TS_CP_SRCLOC"))) srcloc;
+ struct tree_default_arg GTY ((tag ("TS_CP_DEFAULT_ARG"))) default_arg;
struct lang_identifier GTY ((tag ("TS_CP_IDENTIFIER"))) identifier;
};
@@ -591,9 +515,6 @@ enum cp_tree_index
CPTI_BASE_DESC_TYPE,
CPTI_CLASS_TYPE,
- CPTI_RECORD_TYPE,
- CPTI_UNION_TYPE,
- CPTI_ENUM_TYPE,
CPTI_UNKNOWN_TYPE,
CPTI_VTBL_TYPE,
CPTI_VTBL_PTR_TYPE,
@@ -601,19 +522,11 @@ enum cp_tree_index
CPTI_ABI,
CPTI_TYPE_INFO_TYPE,
CPTI_TYPE_INFO_PTR_TYPE,
+ CPTI_TYPE_INFO_REF_TYPE,
CPTI_ABORT_FNDECL,
CPTI_GLOBAL_DELETE_FNDECL,
CPTI_AGGR_TAG,
- CPTI_ACCESS_DEFAULT,
- CPTI_ACCESS_PUBLIC,
- CPTI_ACCESS_PROTECTED,
- CPTI_ACCESS_PRIVATE,
- CPTI_ACCESS_DEFAULT_VIRTUAL,
- CPTI_ACCESS_PUBLIC_VIRTUAL,
- CPTI_ACCESS_PROTECTED_VIRTUAL,
- CPTI_ACCESS_PRIVATE_VIRTUAL,
-
CPTI_CTOR_IDENTIFIER,
CPTI_COMPLETE_CTOR_IDENTIFIER,
CPTI_BASE_CTOR_IDENTIFIER,
@@ -680,9 +593,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
#define base_desc_type_node cp_global_trees[CPTI_BASE_DESC_TYPE]
#define class_type_node cp_global_trees[CPTI_CLASS_TYPE]
-#define record_type_node cp_global_trees[CPTI_RECORD_TYPE]
-#define union_type_node cp_global_trees[CPTI_UNION_TYPE]
-#define enum_type_node cp_global_trees[CPTI_ENUM_TYPE]
#define unknown_type_node cp_global_trees[CPTI_UNKNOWN_TYPE]
#define vtbl_type_node cp_global_trees[CPTI_VTBL_TYPE]
#define vtbl_ptr_type_node cp_global_trees[CPTI_VTBL_PTR_TYPE]
@@ -690,23 +600,11 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
#define abi_node cp_global_trees[CPTI_ABI]
#define type_info_type_node cp_global_trees[CPTI_TYPE_INFO_TYPE]
#define type_info_ptr_type cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE]
+#define type_info_ref_type cp_global_trees[CPTI_TYPE_INFO_REF_TYPE]
#define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL]
#define global_delete_fndecl cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL]
#define current_aggr cp_global_trees[CPTI_AGGR_TAG]
-/* Define the sets of attributes that member functions and baseclasses
- can have. These are sensible combinations of {public,private,protected}
- cross {virtual,non-virtual}. */
-
-#define access_default_node cp_global_trees[CPTI_ACCESS_DEFAULT]
-#define access_public_node cp_global_trees[CPTI_ACCESS_PUBLIC]
-#define access_protected_node cp_global_trees[CPTI_ACCESS_PROTECTED]
-#define access_private_node cp_global_trees[CPTI_ACCESS_PRIVATE]
-#define access_default_virtual_node cp_global_trees[CPTI_ACCESS_DEFAULT_VIRTUAL]
-#define access_public_virtual_node cp_global_trees[CPTI_ACCESS_PUBLIC_VIRTUAL]
-#define access_protected_virtual_node cp_global_trees[CPTI_ACCESS_PROTECTED_VIRTUAL]
-#define access_private_virtual_node cp_global_trees[CPTI_ACCESS_PRIVATE_VIRTUAL]
-
/* We cache these tree nodes so as to call get_identifier less
frequently. */
@@ -780,6 +678,11 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
#define keyed_classes cp_global_trees[CPTI_KEYED_CLASSES]
+/* Node to indicate default access. This must be distinct from the
+ access nodes in tree.h. */
+
+#define access_default_node null_node
+
/* Global state. */
struct saved_scope GTY(())
@@ -797,12 +700,10 @@ struct saved_scope GTY(())
tree x_previous_class_type;
tree x_previous_class_values;
tree x_saved_tree;
- tree lookups;
- tree last_parms;
HOST_WIDE_INT x_processing_template_decl;
int x_processing_specialization;
- int x_processing_explicit_instantiation;
+ bool x_processing_explicit_instantiation;
int need_pop_function_context;
struct stmt_tree_s x_stmt_tree;
@@ -863,12 +764,8 @@ struct saved_scope GTY(())
/* A list of private types mentioned, for deferred access checking. */
-#define type_lookups scope_chain->lookups
-
extern GTY(()) struct saved_scope *scope_chain;
-struct unparsed_text;
-
/* Global state pertinent to the current function. */
struct language_function GTY(())
@@ -888,10 +785,9 @@ struct language_function GTY(())
int returns_abnormally;
int in_function_try_handler;
int in_base_initializer;
- int x_expanding_p;
/* True if this function can throw an exception. */
- bool can_throw : 1;
+ BOOL_BITFIELD can_throw : 1;
struct named_label_use_list *x_named_label_uses;
struct named_label_list *x_named_labels;
@@ -899,7 +795,6 @@ struct language_function GTY(())
varray_type x_local_names;
const char *cannot_inline;
- struct unparsed_text *unparsed_inlines;
};
/* The current C++-specific per-function global variables. */
@@ -951,18 +846,7 @@ struct language_function GTY(())
#define current_function_returns_abnormally \
cp_function_chain->returns_abnormally
-/* Nonzero if we should generate RTL for functions that we process.
- When this is zero, we just accumulate tree structure, without
- interacting with the back end. */
-
-#define expanding_p cp_function_chain->x_expanding_p
-
-/* Nonzero if we are in the semantic analysis phase for the current
- function. */
-
-#define doing_semantic_analysis_p() (!expanding_p)
-
-/* Non-zero if we are processing a base initializer. Zero elsewhere. */
+/* Nonzero if we are processing a base initializer. Zero elsewhere. */
#define in_base_initializer cp_function_chain->in_base_initializer
#define in_function_try_handler cp_function_chain->in_function_try_handler
@@ -973,7 +857,13 @@ struct language_function GTY(())
#define current_function_return_value \
(cp_function_chain->x_return_value)
-extern GTY(()) tree global_namespace;
+/* True if NAME is the IDENTIFIER_NODE for an overloaded "operator
+ new" or "operator delete". */
+#define NEW_DELETE_OPNAME_P(NAME) \
+ ((NAME) == ansi_opname (NEW_EXPR) \
+ || (NAME) == ansi_opname (VEC_NEW_EXPR) \
+ || (NAME) == ansi_opname (DELETE_EXPR) \
+ || (NAME) == ansi_opname (VEC_DELETE_EXPR))
#define ansi_opname(CODE) \
(operator_name_info[(int) (CODE)].identifier)
@@ -1002,6 +892,10 @@ enum cplus_tree_code {
};
#undef DEFTREECODE
+#define cp_stmt_codes \
+ CTOR_INITIALIZER, TRY_BLOCK, HANDLER, \
+ EH_SPEC_BLOCK, USING_STMT, TAG_DEFN
+
enum languages { lang_c, lang_cplusplus, lang_java };
/* Macros to make error reporting functions' lives easier. */
@@ -1046,19 +940,21 @@ enum languages { lang_c, lang_cplusplus, lang_java };
(IS_AGGR_TYPE_CODE (TREE_CODE (T)) && IS_AGGR_TYPE (T))
#define IS_AGGR_TYPE_CODE(T) ((T) == RECORD_TYPE || (T) == UNION_TYPE)
-#define IS_AGGR_TYPE_2(TYPE1, TYPE2) \
- (TREE_CODE (TYPE1) == TREE_CODE (TYPE2) \
- && IS_AGGR_TYPE (TYPE1) && IS_AGGR_TYPE (TYPE2))
#define TAGGED_TYPE_P(T) \
(CLASS_TYPE_P (T) || TREE_CODE (T) == ENUMERAL_TYPE)
#define IS_OVERLOAD_TYPE(T) TAGGED_TYPE_P (T)
-/* In a *_TYPE, nonzero means a built-in type. */
-#define TYPE_BUILT_IN(NODE) TYPE_LANG_FLAG_6 (NODE)
-
/* True if this a "Java" type, defined in 'extern "Java"'. */
#define TYPE_FOR_JAVA(NODE) TYPE_LANG_FLAG_3 (NODE)
+/* True if this type is dependent. This predicate is only valid if
+ TYPE_DEPENDENT_P_VALID is true. */
+#define TYPE_DEPENDENT_P(NODE) TYPE_LANG_FLAG_0 (NODE)
+
+/* True if dependent_type_p has been called for this type, with the
+ result that TYPE_DEPENDENT_P is valid. */
+#define TYPE_DEPENDENT_P_VALID(NODE) TYPE_LANG_FLAG_6(NODE)
+
/* Nonzero if this type is const-qualified. */
#define CP_TYPE_CONST_P(NODE) \
((cp_type_quals (NODE) & TYPE_QUAL_CONST) != 0)
@@ -1099,7 +995,7 @@ enum languages { lang_c, lang_cplusplus, lang_java };
/* Nonzero iff TYPE is derived from PARENT. Ignores accessibility and
ambiguity issues. */
#define DERIVED_FROM_P(PARENT, TYPE) \
- (lookup_base ((TYPE), PARENT, ba_any, NULL) != NULL_TREE)
+ (lookup_base ((TYPE), (PARENT), ba_any, NULL) != NULL_TREE)
/* Nonzero iff TYPE is uniquely derived from PARENT. Ignores
accessibility. */
#define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) \
@@ -1118,15 +1014,15 @@ enum languages { lang_c, lang_cplusplus, lang_java };
are put in this structure to save space. */
struct lang_type_header GTY(())
{
- unsigned is_lang_type_class : 1;
-
- unsigned has_type_conversion : 1;
- unsigned has_init_ref : 1;
- unsigned has_default_ctor : 1;
- unsigned uses_multiple_inheritance : 1;
- unsigned const_needs_init : 1;
- unsigned ref_needs_init : 1;
- unsigned has_const_assign_ref : 1;
+ BOOL_BITFIELD is_lang_type_class : 1;
+
+ BOOL_BITFIELD has_type_conversion : 1;
+ BOOL_BITFIELD has_init_ref : 1;
+ BOOL_BITFIELD has_default_ctor : 1;
+ BOOL_BITFIELD uses_multiple_inheritance : 1;
+ BOOL_BITFIELD const_needs_init : 1;
+ BOOL_BITFIELD ref_needs_init : 1;
+ BOOL_BITFIELD has_const_assign_ref : 1;
};
/* This structure provides additional information above and beyond
@@ -1158,11 +1054,12 @@ struct lang_type_class GTY(())
unsigned has_array_new : 1;
unsigned gets_delete : 2;
- unsigned has_call_overloaded : 1;
- unsigned has_array_ref_overloaded : 1;
- unsigned has_arrow_overloaded : 1;
unsigned interface_only : 1;
unsigned interface_unknown : 1;
+ unsigned contains_empty_class_p : 1;
+ unsigned anon_aggr : 1;
+ unsigned non_zero_init : 1;
+ unsigned empty_p : 1;
unsigned marks: 6;
unsigned vec_new_uses_cookie : 1;
@@ -1172,7 +1069,7 @@ struct lang_type_class GTY(())
unsigned redefined : 1;
unsigned debug_requested : 1;
unsigned use_template : 2;
- unsigned got_semicolon : 1;
+ unsigned fields_readonly : 1;
unsigned ptrmemfunc_flag : 1;
unsigned was_anonymous : 1;
@@ -1182,14 +1079,8 @@ struct lang_type_class GTY(())
unsigned has_complex_assign_ref : 1;
unsigned has_abstract_assign_ref : 1;
unsigned non_aggregate : 1;
- unsigned is_partial_instantiation : 1;
unsigned java_interface : 1;
- unsigned anon_aggr : 1;
- unsigned non_zero_init : 1;
- unsigned empty_p : 1;
- unsigned contains_empty_class_p : 1;
-
/* When adding a flag here, consider whether or not it ought to
apply to a template instance if it applies to the template. If
so, make sure to copy it in instantiate_class_template! */
@@ -1197,7 +1088,7 @@ struct lang_type_class GTY(())
/* There are some bits left to fill out a 32-bit word. Keep track
of this by updating the size of this bitfield whenever you add or
remove a flag. */
- unsigned dummy : 5;
+ unsigned dummy : 9;
tree primary_base;
tree vfields;
@@ -1209,7 +1100,7 @@ struct lang_type_class GTY(())
tree as_base;
tree pure_virtuals;
tree friend_classes;
- tree methods;
+ tree GTY ((reorder ("resort_type_method_vec"))) methods;
tree key_method;
tree decl_list;
tree template_info;
@@ -1234,13 +1125,13 @@ struct lang_type GTY(())
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
-#define LANG_TYPE_CLASS_CHECK(NODE) \
+#define LANG_TYPE_CLASS_CHECK(NODE) __extension__ \
({ struct lang_type *lt = TYPE_LANG_SPECIFIC (NODE); \
if (! lt->u.h.is_lang_type_class) \
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
&lt->u.c; })
-#define LANG_TYPE_PTRMEM_CHECK(NODE) \
+#define LANG_TYPE_PTRMEM_CHECK(NODE) __extension__ \
({ struct lang_type *lt = TYPE_LANG_SPECIFIC (NODE); \
if (lt->u.h.is_lang_type_class) \
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
@@ -1308,18 +1199,6 @@ struct lang_type GTY(())
convenient, don't reprocess any methods that appear in its redefinition. */
#define TYPE_REDEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->redefined)
-/* Nonzero means that this _CLASSTYPE node overloads operator(). */
-#define TYPE_OVERLOADS_CALL_EXPR(NODE) \
- (LANG_TYPE_CLASS_CHECK (NODE)->has_call_overloaded)
-
-/* Nonzero means that this _CLASSTYPE node overloads operator[]. */
-#define TYPE_OVERLOADS_ARRAY_REF(NODE) \
- (LANG_TYPE_CLASS_CHECK (NODE)->has_array_ref_overloaded)
-
-/* Nonzero means that this _CLASSTYPE node overloads operator->. */
-#define TYPE_OVERLOADS_ARROW(NODE) \
- (LANG_TYPE_CLASS_CHECK (NODE)->has_arrow_overloaded)
-
/* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses
multiple inheritance. If this is 0 for the root of a type
hierarchy, then we can use more efficient search techniques. */
@@ -1417,11 +1296,10 @@ struct lang_type GTY(())
#define SET_CLASSTYPE_MARKED6(NODE) SET_CLASSTYPE_MARKED_N (NODE, 5)
#define CLEAR_CLASSTYPE_MARKED6(NODE) CLEAR_CLASSTYPE_MARKED_N (NODE, 5)
-/* A binding_table of the nested tag-types (class, struct, union, or enum)
- found within this class. The ENTRY->name of each node is the name
- of the type; the ENTRY->type is the type itself. This table includes
- nested member class templates. */
-#define CLASSTYPE_NESTED_UDTS(NODE) \
+/* A dictionary of the nested user-defined-types (class-types, or enums)
+ found within this class. This table includes nested member class
+ templates. */
+#define CLASSTYPE_NESTED_UTDS(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->nested_udts)
/* Nonzero if NODE has a primary base class, i.e., a base class with
@@ -1438,21 +1316,9 @@ struct lang_type GTY(())
/* A chain of BINFOs for the direct and indirect virtual base classes
that this type uses in a post-order depth-first left-to-right
order. (In other words, these bases appear in the order that they
- should be initialized.) If a virtual base is primary, then the
- primary copy will appear on this list. Thus, the BINFOs on this
- list are all "real"; they are the same BINFOs that will be
- encountered when using dfs_unmarked_real_bases_queue_p and related
- functions. */
+ should be initialized.) */
#define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases)
-/* For a non-virtual BINFO, the BINFO itself; for a virtual BINFO, the
- binfo_for_vbase. C is the most derived class for the hierarchy
- containing BINFO. */
-#define CANONICAL_BINFO(BINFO, C) \
- (TREE_VIA_VIRTUAL (BINFO) \
- ? binfo_for_vbase (BINFO_TYPE (BINFO), C) \
- : (BINFO))
-
/* Number of direct baseclasses of NODE. */
#define CLASSTYPE_N_BASECLASSES(NODE) \
(BINFO_N_BASETYPES (TYPE_BINFO (NODE)))
@@ -1482,14 +1348,11 @@ struct lang_type GTY(())
class must provide its own definition for each of these functions. */
#define CLASSTYPE_PURE_VIRTUALS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->pure_virtuals)
-/* Nonzero means that this aggr type has been `closed' by a semicolon. */
-#define CLASSTYPE_GOT_SEMICOLON(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->got_semicolon)
-
/* Nonzero means that this type has an X() constructor. */
#define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->h.has_default_ctor)
-/* Nonzero means that this type contains a mutable member */
+/* Nonzero means that this type contains a mutable member. */
#define CLASSTYPE_HAS_MUTABLE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_mutable)
#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
@@ -1575,63 +1438,28 @@ struct lang_type GTY(())
/* Additional macros for inheritance information. */
/* The BINFO_INHERITANCE_CHAIN is used opposite to the description in
- gcc/tree.h. In particular if D is derived from B then the BINFO
- for B (in D) will have a BINFO_INHERITANCE_CHAIN pointing to
- D. In tree.h, this pointer is described as pointing in other
- direction. There is a different BINFO for each path to a virtual
- base; BINFOs for virtual bases are not shared.
-
- We use TREE_VIA_PROTECTED and TREE_VIA_PUBLIC, but private
- inheritance is indicated by the absence of the other two flags, not
- by TREE_VIA_PRIVATE, which is unused. */
-
-/* Mark the binfo, whether shared or not. Each instance of a virtual
- base can be separately marked. */
-#define BINFO_UNSHARED_MARKED(NODE) TREE_LANG_FLAG_0 (NODE)
+ gcc/tree.h. In particular if D is non-virtually derived from B
+ then the BINFO for B (in D) will have a BINFO_INHERITANCE_CHAIN
+ pointing to D. If D is virtually derived, its
+ BINFO_INHERITANCE_CHAIN will point to the most derived binfo. In
+ tree.h, this pointer is described as pointing in other
+ direction. The binfos of virtual bases are shared. */
/* Nonzero means marked by DFS or BFS search. */
-#define BINFO_MARKED(NODE) \
- (TREE_VIA_VIRTUAL (NODE) \
- ? CLASSTYPE_MARKED (BINFO_TYPE (NODE)) \
- : TREE_LANG_FLAG_0 (NODE))
-/* Macros needed because of C compilers that don't allow conditional
- expressions to be lvalues. Grr! */
-#define SET_BINFO_MARKED(NODE) \
- (TREE_VIA_VIRTUAL(NODE) \
- ? SET_CLASSTYPE_MARKED (BINFO_TYPE (NODE)) \
- : (void)(TREE_LANG_FLAG_0 (NODE) = 1))
-#define CLEAR_BINFO_MARKED(NODE) \
- (TREE_VIA_VIRTUAL (NODE) \
- ? CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (NODE)) \
- : (void)(TREE_LANG_FLAG_0 (NODE) = 0))
+#define BINFO_MARKED(NODE) TREE_LANG_FLAG_0 (NODE)
/* Nonzero means that this class is on a path leading to a new vtable. */
-#define BINFO_VTABLE_PATH_MARKED(NODE) \
- (TREE_VIA_VIRTUAL (NODE) \
- ? CLASSTYPE_MARKED3 (BINFO_TYPE (NODE)) \
- : TREE_LANG_FLAG_3 (NODE))
-#define SET_BINFO_VTABLE_PATH_MARKED(NODE) \
- (TREE_VIA_VIRTUAL(NODE) \
- ? SET_CLASSTYPE_MARKED3 (BINFO_TYPE (NODE)) \
- : (TREE_LANG_FLAG_3 (NODE) = 1))
-#define CLEAR_BINFO_VTABLE_PATH_MARKED(NODE) \
- (TREE_VIA_VIRTUAL (NODE) \
- ? CLEAR_CLASSTYPE_MARKED3 (BINFO_TYPE (NODE))\
- : (TREE_LANG_FLAG_3 (NODE) = 0))
-
-/* Nonzero means B (a BINFO) has its own vtable. Under the old ABI,
- secondary vtables are sometimes shared. Any copies will not have
- this flag set.
-
- B is part of the hierarchy dominated by C. */
-#define BINFO_NEW_VTABLE_MARKED(B, C) \
- (TREE_LANG_FLAG_4 (CANONICAL_BINFO (B, C)))
+#define BINFO_VTABLE_PATH_MARKED(NODE) TREE_LANG_FLAG_3 (NODE)
+
+/* Nonzero means B (a BINFO) has its own vtable. Any copies will not
+ have this flag set. */
+#define BINFO_NEW_VTABLE_MARKED(B) (TREE_LANG_FLAG_4 (B))
/* Any subobject that needs a new vtable must have a vptr and must not
be a non-virtual primary base (since it would then use the vtable from a
derived class and never become non-primary.) */
-#define SET_BINFO_NEW_VTABLE_MARKED(B, C) \
- (BINFO_NEW_VTABLE_MARKED (B, C) = 1, \
+#define SET_BINFO_NEW_VTABLE_MARKED(B) \
+ (BINFO_NEW_VTABLE_MARKED (B) = 1, \
my_friendly_assert (!BINFO_PRIMARY_P (B) \
|| TREE_VIA_VIRTUAL (B), 20000517), \
my_friendly_assert (CLASSTYPE_VFIELDS (BINFO_TYPE (B)) != NULL_TREE, \
@@ -1639,11 +1467,9 @@ struct lang_type GTY(())
/* Nonzero means this class has done dfs_pushdecls. */
#define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE)
-#define SET_BINFO_PUSHDECLS_MARKED(NODE) SET_BINFO_VTABLE_PATH_MARKED (NODE)
-#define CLEAR_BINFO_PUSHDECLS_MARKED(NODE) CLEAR_BINFO_VTABLE_PATH_MARKED (NODE)
/* Nonzero if this BINFO is a primary base class. Note, this can be
- set for non-canononical virtual bases. For a virtual primary base
+ set for non-canonical virtual bases. For a virtual primary base
you might also need to check whether it is canonical. */
#define BINFO_PRIMARY_P(NODE) \
@@ -1651,17 +1477,25 @@ struct lang_type GTY(())
/* The index in the VTT where this subobject's sub-VTT can be found.
NULL_TREE if there is no sub-VTT. */
-#define BINFO_SUBVTT_INDEX(NODE) TREE_VEC_ELT (NODE, 8)
+#define BINFO_SUBVTT_INDEX(NODE) TREE_VEC_ELT (NODE, BINFO_ELTS + 0)
/* The index in the VTT where the vptr for this subobject can be
found. NULL_TREE if there is no secondary vptr in the VTT. */
-#define BINFO_VPTR_INDEX(NODE) TREE_VEC_ELT (NODE, 9)
+#define BINFO_VPTR_INDEX(NODE) TREE_VEC_ELT (NODE, BINFO_ELTS + 1)
/* The binfo of which NODE is a primary base. (This is different from
BINFO_INHERITANCE_CHAIN for virtual base because a virtual base is
sometimes a primary base for a class for which it is not an
immediate base.) */
-#define BINFO_PRIMARY_BASE_OF(NODE) TREE_VEC_ELT (NODE, 10)
+#define BINFO_PRIMARY_BASE_OF(NODE) TREE_VEC_ELT (NODE, BINFO_ELTS + 2)
+
+/* C++ binfos have 3 additional entries. */
+
+#define BINFO_LANG_ELTS (BINFO_ELTS + 3)
+
+/* Nonzero if this binfo is for a dependent base - one that should not
+ be searched. */
+#define BINFO_DEPENDENT_BASE_P(NODE) TREE_LANG_FLAG_1(NODE)
/* Nonzero if this binfo has lost its primary base binfo (because that
is a nearly-empty virtual base that has been taken by some other
@@ -1766,8 +1600,6 @@ struct lang_type GTY(())
struct lang_decl_flags GTY(())
{
- struct c_lang_decl base;
-
ENUM_BITFIELD(languages) language : 8;
unsigned operator_attr : 1;
@@ -1794,15 +1626,20 @@ struct lang_decl_flags GTY(())
unsigned u1sel : 1;
unsigned u2sel : 1;
unsigned can_be_full : 1;
- unsigned unused : 1; /* One unused bit. */
+ unsigned this_thunk_p : 1;
union lang_decl_u {
- /* In a FUNCTION_DECL, VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this
- is DECL_TEMPLATE_INFO. */
+ /* In a FUNCTION_DECL for which DECL_THUNK_P does not hold,
+ VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this is
+ DECL_TEMPLATE_INFO. */
tree GTY ((tag ("0"))) template_info;
/* In a NAMESPACE_DECL, this is NAMESPACE_LEVEL. */
struct cp_binding_level * GTY ((tag ("1"))) level;
+
+ /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
+ THUNK_ALIAS. */
+ tree GTY ((tag ("2"))) thunk_alias;
} GTY ((desc ("%1.u1sel"))) u;
union lang_decl_u2 {
@@ -1810,14 +1647,17 @@ struct lang_decl_flags GTY(())
tree GTY ((tag ("0"))) access;
/* For VAR_DECL in function, this is DECL_DISCRIMINATOR. */
- int discriminator;
+ int GTY ((tag ("1"))) discriminator;
/* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
- THUNK_VCALL_OFFSET. */
- tree GTY((tag ("2"))) vcall_offset;
+ THUNK_VIRTUAL_OFFSET. */
+ tree GTY((tag ("2"))) virtual_offset;
} GTY ((desc ("%1.u2sel"))) u2;
};
+/* sorted_fields is sorted based on a pointer, so we need to be able
+ to resort it if pointers get rearranged. */
+
struct lang_decl GTY(())
{
struct lang_decl_flags decl_flags;
@@ -1826,19 +1666,25 @@ struct lang_decl GTY(())
{
struct full_lang_decl
{
+ /* For a non-thunk function decl, this is a tree list of
+ friendly classes. For a thunk function decl, it is the
+ thunked to function decl. */
tree befriending_classes;
/* For a non-virtual FUNCTION_DECL, this is
DECL_FRIEND_CONTEXT. For a virtual FUNCTION_DECL for which
- DECL_THUNK_P does not hold, this is DECL_THUNKS. */
+ DECL_THIS_THUNK_P does not hold, this is DECL_THUNKS. Both
+ this pointer and result pointer adjusting thunks are
+ chained here. This pointer thunks to return pointer thunks
+ will be chained on the return pointer thunk. */
tree context;
/* In a FUNCTION_DECL, this is DECL_CLONED_FUNCTION. */
tree cloned_function;
/* In a FUNCTION_DECL for which THUNK_P holds, this is
- THUNK_DELTA. */
- HOST_WIDE_INT delta;
+ THUNK_FIXED_OFFSET. */
+ HOST_WIDE_INT fixed_offset;
/* In an overloaded operator, this is the value of
DECL_OVERLOADED_OPERATOR_P. */
@@ -1849,8 +1695,9 @@ struct lang_decl GTY(())
union lang_decl_u3
{
- tree GTY ((tag ("0"))) sorted_fields;
- struct unparsed_text * GTY ((tag ("2"))) pending_inline_info;
+ struct sorted_fields_type * GTY ((tag ("0"), reorder ("resort_sorted_fields")))
+ sorted_fields;
+ struct cp_token_cache * GTY ((tag ("2"))) pending_inline_info;
struct language_function * GTY ((tag ("1")))
saved_language_function;
} GTY ((desc ("%1.u3sel + %1.pending_inline_p"))) u;
@@ -1860,7 +1707,7 @@ struct lang_decl GTY(())
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
-#define LANG_DECL_U2_CHECK(NODE, TF) \
+#define LANG_DECL_U2_CHECK(NODE, TF) __extension__ \
({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \
if (lt->decl_flags.u2sel != TF) \
lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \
@@ -1873,8 +1720,6 @@ struct lang_decl GTY(())
#endif /* ENABLE_TREE_CHECKING */
-#define DEFARG_POINTER(NODE) (DEFAULT_ARG_CHECK (NODE)->identifier.id.str)
-
/* DECL_NEEDED_P holds of a declaration when we need to emit its
definition. This is true when the back-end tells us that
the symbol has been referenced in the generated code. If, however,
@@ -1886,15 +1731,7 @@ struct lang_decl GTY(())
((at_eof && TREE_PUBLIC (DECL) && !DECL_COMDAT (DECL)) \
|| (DECL_ASSEMBLER_NAME_SET_P (DECL) \
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL))) \
- || (flag_syntax_only && TREE_USED (DECL)))
-
-/* Nonzero iff DECL is memory-based. The DECL_RTL of
- certain const variables might be a CONST_INT, or a REG
- in some cases. We cannot use `memory_operand' as a test
- here because on most RISC machines, a variable's address
- is not, by itself, a legitimate address. */
-#define DECL_IN_MEMORY_P(NODE) \
- (DECL_RTL_SET_P (NODE) && GET_CODE (DECL_RTL (NODE)) == MEM)
+ || (((flag_syntax_only || flag_unit_at_a_time) && TREE_USED (DECL))))
/* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the
declaration. Some entities (like a member function in a local
@@ -2003,7 +1840,7 @@ struct lang_decl GTY(())
/* Nonzero if NODE is a user-defined conversion operator. */
#define DECL_CONV_FN_P(NODE) \
- (IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)))
+ (DECL_NAME (NODE) && IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)))
/* If FN is a conversion operator, the type to which it converts.
Otherwise, NULL_TREE. */
@@ -2021,7 +1858,7 @@ struct lang_decl GTY(())
(DECL_LANG_SPECIFIC (NODE)->u.f.operator_code = (CODE))
/* If NODE is an overloaded operator, then this returns the TREE_CODE
- associcated with the overloaded operator.
+ associated with the overloaded operator.
DECL_ASSIGNMENT_OPERATOR_P must also be checked to determine
whether or not NODE is an assignment operator. If NODE is not an
overloaded operator, ERROR_MARK is returned. Since the numerical
@@ -2057,9 +1894,14 @@ struct lang_decl GTY(())
#define DECL_INITIALIZED_P(NODE) \
(TREE_LANG_FLAG_1 (VAR_DECL_CHECK (NODE)))
+/* Nonzero for a VAR_DECL that was initialized with a
+ constant-expression. */
+#define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \
+ (TREE_LANG_FLAG_2 (VAR_DECL_CHECK (NODE)))
+
/* Nonzero if the DECL was initialized in the class definition itself,
rather than outside the class. This is used for both static member
- VAR_DECLS, and FUNTION_DECLS that are defined in the class. */
+ VAR_DECLS, and FUNTION_DECLS that are defined in the class. */
#define DECL_INITIALIZED_IN_CLASS_P(DECL) \
(DECL_LANG_SPECIFIC (DECL)->decl_flags.initialized_in_class)
@@ -2126,8 +1968,7 @@ struct lang_decl GTY(())
#define DECL_NEEDS_FINAL_OVERRIDER_P(NODE) \
(DECL_LANG_SPECIFIC (NODE)->decl_flags.needs_final_overrider)
-/* The thunks associated with NODE, a FUNCTION_DECL that is not itself
- a thunk. */
+/* The thunks associated with NODE, a FUNCTION_DECL. */
#define DECL_THUNKS(NODE) \
(DECL_LANG_SPECIFIC (NODE)->u.f.context)
@@ -2136,6 +1977,14 @@ struct lang_decl GTY(())
(TREE_CODE (NODE) == FUNCTION_DECL \
&& DECL_LANG_FLAG_7 (NODE))
+/* Nonzero if NODE is a this pointer adjusting thunk. */
+#define DECL_THIS_THUNK_P(NODE) \
+ (DECL_THUNK_P (NODE) && DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p)
+
+/* Nonzero if NODE is a result pointer adjusting thunk. */
+#define DECL_RESULT_THUNK_P(NODE) \
+ (DECL_THUNK_P (NODE) && !DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p)
+
/* Nonzero if NODE is a FUNCTION_DECL, but not a thunk. */
#define DECL_NON_THUNK_FUNCTION_P(NODE) \
(TREE_CODE (NODE) == FUNCTION_DECL && !DECL_THUNK_P (NODE))
@@ -2149,14 +1998,15 @@ struct lang_decl GTY(())
(DECL_NON_THUNK_FUNCTION_P (NODE) && DECL_EXTERN_C_P (NODE))
/* Set DECL_THUNK_P for node. */
-#define SET_DECL_THUNK_P(NODE) \
+#define SET_DECL_THUNK_P(NODE, THIS_ADJUSTING) \
(DECL_LANG_FLAG_7 (NODE) = 1, \
- DECL_LANG_SPECIFIC (NODE)->u.f.u3sel = 1)
+ DECL_LANG_SPECIFIC (NODE)->u.f.u3sel = 1, \
+ DECL_LANG_SPECIFIC (NODE)->decl_flags.this_thunk_p = (THIS_ADJUSTING))
/* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
template function. */
#define DECL_PRETTY_FUNCTION_P(NODE) \
- (TREE_LANG_FLAG_0 (NODE))
+ (TREE_LANG_FLAG_0 (VAR_DECL_CHECK (NODE)))
/* The _TYPE context in which this _DECL appears. This field holds the
class where a virtual function instance is actually defined. */
@@ -2197,6 +2047,9 @@ struct lang_decl GTY(())
(DECL_CONTEXT (NODE) \
&& TREE_CODE (DECL_CONTEXT (NODE)) == FUNCTION_DECL)
+/* 1 iff VAR_DECL node NODE is virtual table or VTT. */
+#define DECL_VTABLE_OR_VTT_P(NODE) TREE_LANG_FLAG_5 (VAR_DECL_CHECK (NODE))
+
/* 1 iff NODE is function-local, but for types. */
#define LOCAL_CLASS_P(NODE) \
(decl_function_context (TYPE_MAIN_DECL (NODE)) != NULL_TREE)
@@ -2210,6 +2063,11 @@ struct lang_decl GTY(())
of a namespace, to record the transitive closure of using namespace. */
#define DECL_NAMESPACE_USERS(NODE) DECL_INITIAL (NAMESPACE_DECL_CHECK (NODE))
+/* In a NAMESPACE_DECL, the list of namespaces which have associated
+ themselves with this one. */
+#define DECL_NAMESPACE_ASSOCIATIONS(NODE) \
+ (NAMESPACE_DECL_CHECK (NODE)->decl.saved_tree)
+
/* In a NAMESPACE_DECL, points to the original namespace if this is
a namespace alias. */
#define DECL_NAMESPACE_ALIAS(NODE) \
@@ -2318,11 +2176,8 @@ struct lang_decl GTY(())
/* Nonzero if the template arguments is actually a vector of vectors,
rather than just a vector. */
-#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \
- ((NODE) != NULL_TREE \
- && TREE_CODE (NODE) == TREE_VEC \
- && TREE_VEC_LENGTH (NODE) > 0 \
- && TREE_VEC_ELT (NODE, 0) != NULL_TREE \
+#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \
+ (NODE && TREE_VEC_ELT (NODE, 0) \
&& TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC)
/* The depth of a template argument vector. When called directly by
@@ -2356,9 +2211,7 @@ struct lang_decl GTY(())
/* Given a single level of template arguments in NODE, return the
number of arguments. */
#define NUM_TMPL_ARGS(NODE) \
- ((NODE) == NULL_TREE ? 0 \
- : (TREE_CODE (NODE) == TREE_VEC \
- ? TREE_VEC_LENGTH (NODE) : list_length (NODE)))
+ (TREE_VEC_LENGTH (NODE))
/* Returns the innermost level of template arguments in ARGS. */
#define INNERMOST_TEMPLATE_ARGS(NODE) \
@@ -2378,14 +2231,13 @@ struct lang_decl GTY(())
DECL_TI_TEMPLATE, `template <class U> S<int>::f<U>'.
As a special case, for a member friend template of a template
- class, this value will not be a TEMPLATE_DECL, but rather a
- LOOKUP_EXPR, IDENTIFIER_NODE or OVERLOAD indicating the name of
- the template and any explicit template arguments provided. For
- example, in:
+ class, this value will not be a TEMPLATE_DECL, but rather an
+ IDENTIFIER_NODE or OVERLOAD indicating the name of the template and
+ any explicit template arguments provided. For example, in:
template <class T> struct S { friend void f<int>(int, double); }
- the DECL_TI_TEMPLATE will be a LOOKUP_EXPR for `f' and the
+ the DECL_TI_TEMPLATE will be an IDENTIFIER_NODE for `f' and the
DECL_TI_ARGS will be {int}. */
#define DECL_TI_TEMPLATE(NODE) TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE))
@@ -2402,6 +2254,14 @@ struct lang_decl GTY(())
#define ENUM_TI_ARGS(NODE) \
TI_ARGS (ENUM_TEMPLATE_INFO (NODE))
+/* For a template instantiation TYPE, returns the TYPE corresponding
+ to the primary template. Otherwise returns TYPE itself. */
+#define CLASSTYPE_PRIMARY_TEMPLATE_TYPE(TYPE) \
+ ((CLASSTYPE_USE_TEMPLATE ((TYPE)) && !CLASSTYPE_TEMPLATE_SPECIALIZATION ((TYPE))) \
+ ? TREE_TYPE (DECL_TEMPLATE_RESULT (DECL_PRIMARY_TEMPLATE \
+ (CLASSTYPE_TI_TEMPLATE ((TYPE))))) \
+ : (TYPE))
+
/* Like DECL_TI_TEMPLATE, but for an ENUMERAL_, RECORD_, or UNION_TYPE. */
#define TYPE_TI_TEMPLATE(NODE) \
(TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE)))
@@ -2425,7 +2285,14 @@ struct lang_decl GTY(())
#define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
#define DELETE_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
#define DELETE_EXPR_USE_VEC(NODE) TREE_LANG_FLAG_1 (NODE)
-#define LOOKUP_EXPR_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE)
+
+/* Indicates that this is a non-dependent COMPOUND_EXPR which will
+ resolve to a function call. */
+#define COMPOUND_EXPR_OVERLOADED(NODE) TREE_LANG_FLAG_0 (NODE)
+
+/* In a CALL_EXPR appearing in a template, true if Koenig lookup
+ should be performed at instantiation time. */
+#define KOENIG_LOOKUP_P(NODE) TREE_LANG_FLAG_0(NODE)
/* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
constructor call, rather than an ordinary function call. */
@@ -2447,17 +2314,6 @@ struct lang_decl GTY(())
TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'. */
#define TYPENAME_TYPE_FULLNAME(NODE) (TYPE_FIELDS (NODE))
-/* Nonzero if NODE is an implicit typename. */
-#define IMPLICIT_TYPENAME_P(NODE) \
- (TREE_CODE (NODE) == TYPENAME_TYPE && TREE_TYPE (NODE))
-
-/* Nonzero if NODE is a TYPE_DECL that should not be visible because
- it is from a dependent base class. */
-#define IMPLICIT_TYPENAME_TYPE_DECL_P(NODE) \
- (TREE_CODE (NODE) == TYPE_DECL \
- && DECL_ARTIFICIAL (NODE) \
- && IMPLICIT_TYPENAME_P (TREE_TYPE (NODE)))
-
/* Nonzero in INTEGER_CST means that this int is negative by dint of
using a twos-complement negated operand. */
#define TREE_NEGATED_INT(NODE) TREE_LANG_FLAG_0 (INTEGER_CST_CHECK (NODE))
@@ -2539,16 +2395,18 @@ struct lang_decl GTY(())
(ARITHMETIC_TYPE_P (TYPE) \
|| TREE_CODE (TYPE) == ENUMERAL_TYPE \
|| TYPE_PTR_P (TYPE) \
- || TYPE_PTRMEM_P (TYPE) \
- || TYPE_PTRMEMFUNC_P (TYPE))
+ || TYPE_PTR_TO_MEMBER_P (TYPE))
/* [dcl.init.aggr]
An aggregate is an array or a class with no user-declared
constructors, no private or protected non-static data members, no
- base classes, and no virtual functions. */
+ base classes, and no virtual functions.
+
+ As an extension, we also treat vectors as aggregates. */
#define CP_AGGREGATE_TYPE_P(TYPE) \
(TREE_CODE (TYPE) == ARRAY_TYPE \
+ || TREE_CODE (TYPE) == VECTOR_TYPE \
|| (CLASS_TYPE_P (TYPE) \
&& !CLASSTYPE_NON_AGGREGATE (TYPE)))
@@ -2623,14 +2481,15 @@ struct lang_decl GTY(())
#define TYPE_HAS_TRIVIAL_ASSIGN_REF(NODE) \
(TYPE_HAS_ASSIGN_REF (NODE) && ! TYPE_HAS_COMPLEX_ASSIGN_REF (NODE))
-#define TYPE_PTRMEM_P(NODE) \
- (TREE_CODE (NODE) == POINTER_TYPE \
- && TREE_CODE (TREE_TYPE (NODE)) == OFFSET_TYPE)
-#define TYPE_PTR_P(NODE) \
- (TREE_CODE (NODE) == POINTER_TYPE \
- && TREE_CODE (TREE_TYPE (NODE)) != OFFSET_TYPE)
-#define TYPE_PTROB_P(NODE) \
- (TYPE_PTR_P (NODE) && TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE \
+/* Returns true if NODE is a pointer-to-data-member. */
+#define TYPE_PTRMEM_P(NODE) \
+ (TREE_CODE (NODE) == OFFSET_TYPE)
+#define TYPE_PTR_P(NODE) \
+ (TREE_CODE (NODE) == POINTER_TYPE)
+#define TYPE_PTROB_P(NODE) \
+ (TYPE_PTR_P (NODE) \
+ && TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE \
+ && TREE_CODE (TREE_TYPE (NODE)) != METHOD_TYPE \
&& TREE_CODE (TREE_TYPE (NODE)) != VOID_TYPE)
#define TYPE_PTROBV_P(NODE) \
(TYPE_PTR_P (NODE) && TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE)
@@ -2651,6 +2510,10 @@ struct lang_decl GTY(())
#define TYPE_PTRMEMFUNC_FLAG(NODE) \
(LANG_TYPE_CLASS_CHECK (NODE)->ptrmemfunc_flag)
+/* Returns true if NODE is a pointer-to-member. */
+#define TYPE_PTR_TO_MEMBER_P(NODE) \
+ (TYPE_PTRMEM_P (NODE) || TYPE_PTRMEMFUNC_P (NODE))
+
/* Indicates when overload resolution may resolve to a pointer to
member function. [expr.unary.op]/3 */
#define PTRMEM_OK_P(NODE) TREE_LANG_FLAG_0 (NODE)
@@ -2689,13 +2552,13 @@ struct lang_decl GTY(())
type `const X*'. */
#define TYPE_PTRMEM_CLASS_TYPE(NODE) \
(TYPE_PTRMEM_P (NODE) \
- ? TYPE_OFFSET_BASETYPE (TREE_TYPE (NODE)) \
+ ? TYPE_OFFSET_BASETYPE (NODE) \
: TYPE_PTRMEMFUNC_OBJECT_TYPE (NODE))
/* For a pointer-to-member type of the form `T X::*', this is `T'. */
#define TYPE_PTRMEM_POINTED_TO_TYPE(NODE) \
(TYPE_PTRMEM_P (NODE) \
- ? TREE_TYPE (TREE_TYPE (NODE)) \
+ ? TREE_TYPE (NODE) \
: TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (NODE)))
/* For a pointer-to-member constant `X::Y' this is the RECORD_TYPE for
@@ -2742,14 +2605,8 @@ struct lang_decl GTY(())
/* The format of each node in the DECL_FRIENDLIST is as follows:
The TREE_PURPOSE will be the name of a function, i.e., an
- IDENTIFIER_NODE. The TREE_VALUE will be itself a TREE_LIST, the
- list of functions with that name which are friends. The
- TREE_PURPOSE of each node in this sublist will be error_mark_node,
- if the function was declared a friend individually, in which case
- the TREE_VALUE will be the function_decl. If, however, all
- functions with a given name in a class were declared to be friends,
- the TREE_PUROSE will be the class type, and the TREE_VALUE will be
- NULL_TREE. */
+ IDENTIFIER_NODE. The TREE_VALUE will be itself a TREE_LIST, whose
+ TREE_VALUEs are friends with the given name. */
#define DECL_FRIENDLIST(NODE) (DECL_INITIAL (NODE))
#define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST))
#define FRIEND_DECLS(LIST) (TREE_VALUE (LIST))
@@ -2780,7 +2637,7 @@ struct lang_decl GTY(())
TREE_LIST, whose TREE_VALUE is a PARM_DECL (if the parameter is a
non-type parameter), or a TYPE_DECL (if the parameter is a type
parameter). The TREE_PURPOSE is the default value, if any. The
- TEMPLATE_PARM_INDEX for the parameter is avilable as the
+ TEMPLATE_PARM_INDEX for the parameter is available as the
DECL_INITIAL (for a PARM_DECL) or as the TREE_TYPE (for a
TYPE_DECL). */
#define DECL_TEMPLATE_PARMS(NODE) DECL_ARGUMENTS (NODE)
@@ -2864,13 +2721,20 @@ struct lang_decl GTY(())
#define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE))
+/* Nonzero if NODE is a TEMPLATE_DECL representing an
+ UNBOUND_CLASS_TEMPLATE tree node. */
+#define DECL_UNBOUND_CLASS_TEMPLATE_P(NODE) \
+ (TREE_CODE (NODE) == TEMPLATE_DECL && !DECL_TEMPLATE_RESULT (NODE))
+
#define DECL_FUNCTION_TEMPLATE_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_DECL \
+ && !DECL_UNBOUND_CLASS_TEMPLATE_P (NODE) \
&& TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL)
/* Nonzero for a DECL that represents a template class. */
#define DECL_CLASS_TEMPLATE_P(NODE) \
(TREE_CODE (NODE) == TEMPLATE_DECL \
+ && !DECL_UNBOUND_CLASS_TEMPLATE_P (NODE) \
&& TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == TYPE_DECL \
&& !DECL_TEMPLATE_TEMPLATE_PARM_P (NODE))
@@ -2951,12 +2815,6 @@ struct lang_decl GTY(())
#define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \
(DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL))
-/* Nonzero if TYPE is a partial instantiation of a template class,
- i.e., an instantiation whose instantiation arguments involve
- template types. */
-#define PARTIAL_INSTANTIATION_P(TYPE) \
- (LANG_TYPE_CLASS_CHECK (TYPE)->is_partial_instantiation)
-
/* Nonzero iff we are currently processing a declaration for an
entity with its own template parameter list, and which is not a
full specialization. */
@@ -2972,12 +2830,6 @@ struct lang_decl GTY(())
/* We know what we're doing with this decl now. */
#define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE)
-/* This function was declared inline. This flag controls the linkage
- semantics of 'inline'; whether or not the function is inlined is
- controlled by DECL_INLINE. */
-#define DECL_DECLARED_INLINE_P(NODE) \
- (DECL_LANG_SPECIFIC (NODE)->decl_flags.base.declared_inline)
-
/* DECL_EXTERNAL must be set on a decl until the decl is actually emitted,
so that assemble_external will work properly. So we have this flag to
tell us whether the decl is really not external. */
@@ -2992,33 +2844,65 @@ struct lang_decl GTY(())
A thunk is an alternate entry point for an ordinary FUNCTION_DECL.
The address of the ordinary FUNCTION_DECL is given by the
DECL_INITIAL, which is always an ADDR_EXPR whose operand is a
- FUNCTION_DECL. The job of the thunk is to adjust the `this'
- pointer before transferring control to the FUNCTION_DECL.
-
+ FUNCTION_DECL. The job of the thunk is to either adjust the this
+ pointer before transferring control to the FUNCTION_DECL, or call
+ FUNCTION_DECL and then adjust the result value. Note, the result
+ pointer adjusting thunk must perform a call to the thunked
+ function, (or be implemented via passing some invisible parameter
+ to the thunked function, which is modified to perform the
+ adjustment just before returning).
+
A thunk may perform either, or both, of the following operations:
- o Adjust the `this' pointer by a constant offset.
- o Adjust the `this' pointer by looking up a vcall-offset
+ o Adjust the this or result pointer by a constant offset.
+ o Adjust the this or result pointer by looking up a vcall or vbase offset
in the vtable.
- If both operations are performed, then the constant adjument to
- `this' is performed first.
-
- The constant adjustment is given by THUNK_DELTA. If the
- vcall-offset is required, the index into the vtable is given by
- THUNK_VCALL_OFFSET. */
+ A this pointer adjusting thunk converts from a base to a derived
+ class, and hence adds the offsets. A result pointer adjusting thunk
+ converts from a derived class to a base, and hence subtracts the
+ offsets. If both operations are performed, then the constant
+ adjustment is performed first for this pointer adjustment and last
+ for the result pointer adjustment.
+
+ The constant adjustment is given by THUNK_FIXED_OFFSET. If the
+ vcall or vbase offset is required, THUNK_VIRTUAL_OFFSET is
+ used. For this pointer adjusting thunks, it is the vcall offset
+ into the vtable. For result pointer adjusting thunks it is the
+ binfo of the virtual base to convert to. Use that binfo's vbase
+ offset.
+
+ It is possible to have equivalent covariant thunks. These are
+ distinct virtual covariant thunks whose vbase offsets happen to
+ have the same value. THUNK_ALIAS is used to pick one as the
+ canonical thunk, which will get all the this pointer adjusting
+ thunks attached to it. */
/* An integer indicating how many bytes should be subtracted from the
- `this' pointer when this function is called. */
-#define THUNK_DELTA(DECL) \
- (DECL_LANG_SPECIFIC (DECL)->u.f.delta)
-
-/* A tree indicating how many bytes should be subtracted from the
- vtable for the `this' pointer to find the vcall offset. (The vptr
- is always located at offset zero from the f `this' pointer.) If
- NULL, then there is no vcall offset. */
-#define THUNK_VCALL_OFFSET(DECL) \
- (LANG_DECL_U2_CHECK (DECL, 0)->vcall_offset)
+ this or result pointer when this function is called. */
+#define THUNK_FIXED_OFFSET(DECL) \
+ (DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL))->u.f.fixed_offset)
+
+/* A tree indicating how to perform the virtual adjustment. For a this
+ adjusting thunk it is the number of bytes to be added to the vtable
+ to find the vcall offset. For a result adjusting thunk, it is the
+ binfo of the relevant virtual base. If NULL, then there is no
+ virtual adjust. (The vptr is always located at offset zero from
+ the this or result pointer.) (If the covariant type is within the
+ class hierarchy being laid out, the vbase index is not yet known
+ at the point we need to create the thunks, hence the need to use
+ binfos.) */
+
+#define THUNK_VIRTUAL_OFFSET(DECL) \
+ (LANG_DECL_U2_CHECK (FUNCTION_DECL_CHECK (DECL), 0)->virtual_offset)
+
+/* A thunk which is equivalent to another thunk. */
+#define THUNK_ALIAS(DECL) \
+ (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->decl_flags.u.thunk_alias)
+
+/* For thunk NODE, this is the FUNCTION_DECL thunked to. */
+#define THUNK_TARGET(NODE) \
+ (DECL_LANG_SPECIFIC (NODE)->u.f.befriending_classes)
/* These macros provide convenient access to the various _STMT nodes
created when parsing template declarations. */
@@ -3049,7 +2933,14 @@ struct lang_decl GTY(())
(TREE_TYPE (NODE))
/* An enumeration of the kind of tags that C++ accepts. */
-enum tag_types { record_type, class_type, union_type, enum_type };
+enum tag_types {
+ none_type = 0, /* Not a tag type. */
+ record_type, /* "struct" types. */
+ class_type, /* "class" types. */
+ union_type, /* "union" types. */
+ enum_type, /* "enum" types. */
+ typename_type /* "typename" types. */
+};
/* The various kinds of lvalues we distinguish. */
typedef enum cp_lvalue_kind {
@@ -3057,16 +2948,9 @@ typedef enum cp_lvalue_kind {
clk_ordinary = 1, /* An ordinary lvalue. */
clk_class = 2, /* An rvalue of class-type. */
clk_bitfield = 4, /* An lvalue for a bit-field. */
+ clk_packed = 8 /* An lvalue for a packed field. */
} cp_lvalue_kind;
-/* The kinds of scopes we recognize. */
-typedef enum scope_kind {
- sk_template_parms, /* A scope for template parameters. */
- sk_template_spec /* A scope corresponding to a template
- specialization. There is never anything in
- this scope. */
-} scope_kind;
-
/* Various kinds of template specialization, instantiation, etc. */
typedef enum tmpl_spec_kind {
tsk_none, /* Not a template at all. */
@@ -3142,19 +3026,22 @@ typedef enum tsubst_flags_t {
tf_none = 0, /* nothing special */
tf_error = 1 << 0, /* give error messages */
tf_warning = 1 << 1, /* give warnings too */
- tf_no_attributes = 1 << 2, /* ignore attributes on comparisons
- (instantiate_type use) */
- tf_ignore_bad_quals = 1 << 3, /* ignore bad cvr qualifiers */
- tf_keep_type_decl = 1 << 4, /* retain typedef type decls
+ tf_ignore_bad_quals = 1 << 2, /* ignore bad cvr qualifiers */
+ tf_keep_type_decl = 1 << 3, /* retain typedef type decls
(make_typename_type use) */
- tf_ptrmem_ok = 1 << 5, /* pointers to member ok (internal
- instantiate_type use) */
- tf_parsing = 1 << 6, /* called from parser
- (make_typename_type use) */
- tf_conv = 1 << 8, /* We are determining what kind of
- conversion might be permissible, not
- actually performing the
- conversion. */
+ tf_ptrmem_ok = 1 << 4, /* pointers to member ok (internal
+ instantiate_type use) */
+ tf_user = 1 << 5, /* found template must be a user template
+ (lookup_template_class use) */
+ tf_stmt_expr_cmpd = 1 << 6, /* tsubsting the compound statement of
+ a statement expr. */
+ tf_stmt_expr_body = 1 << 7, /* tsubsting the statements in the
+ body of the compound statement of a
+ statement expr. */
+ tf_conv = 1 << 8 /* We are determining what kind of
+ conversion might be permissible,
+ not actually performing the
+ conversion. */
} tsubst_flags_t;
/* The kind of checking we can do looking in a class hierarchy. */
@@ -3165,9 +3052,16 @@ typedef enum base_access {
ba_check = 2, /* Check access */
ba_not_special = 3, /* Do not consider special privilege
current_class_type might give. */
- ba_quiet = 4, /* Do not issue error messages (bit mask). */
+ ba_quiet = 4 /* Do not issue error messages (bit mask). */
} base_access;
+/* The various kinds of access check during parsing. */
+typedef enum deferring_kind {
+ dk_no_deferred = 0, /* Check access immediately */
+ dk_deferred = 1, /* Deferred check */
+ dk_no_check = 2 /* No access check */
+} deferring_kind;
+
/* The kind of base we can find, looking in a class hierarchy.
Values <0 indicate we failed. */
typedef enum base_kind {
@@ -3199,13 +3093,37 @@ extern GTY(()) tree error_mark_list;
extern GTY(()) tree integer_two_node;
extern GTY(()) tree integer_three_node;
-extern GTY(()) tree anonymous_namespace_name;
-
/* The number of function bodies which we are currently processing.
(Zero if we are at namespace scope, one inside the body of a
function, two inside the body of a function in a local class, etc.) */
extern int function_depth;
+typedef struct deferred_access GTY(())
+{
+ /* A TREE_LIST representing name-lookups for which we have deferred
+ checking access controls. We cannot check the accessibility of
+ names used in a decl-specifier-seq until we know what is being
+ declared because code like:
+
+ class A {
+ class B {};
+ B* f();
+ }
+
+ A::B* A::f() { return 0; }
+
+ is valid, even though `A::B' is not generally accessible.
+
+ The TREE_PURPOSE of each node is the scope used to qualify the
+ name being looked up; the TREE_VALUE is the DECL to which the
+ name was resolved. */
+ tree deferred_access_checks;
+ /* The current mode of access checks. */
+ enum deferring_kind deferring_access_checks_kind;
+ /* The next deferred access data in stack or linked-list. */
+ struct deferred_access *next;
+} deferred_access;
+
/* in pt.c */
/* These values are used for the `STRICT' parameter to type_unification and
@@ -3382,7 +3300,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
#define B_CLR(A,X) ((A)[(X)>>3] &= ~(1 << ((X)&7)))
#define B_TST(A,X) ((A)[(X)>>3] & (1 << ((X)&7)))
-/* These are uses as bits in flags passed to build_method_call
+/* These are uses as bits in flags passed to build_new_method_call
to control its error reporting behavior.
LOOKUP_PROTECT means flag access violations.
@@ -3412,25 +3330,23 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
LOOKUP_PREFER_TYPES means not to accept objects, and possibly namespaces.
LOOKUP_PREFER_NAMESPACES means not to accept objects, and possibly types.
- LOOKUP_PREFER_BOTH means class-or-namespace-name.
- LOOKUP_TEMPLATES_EXPECTED means that class templates also count
- as types. */
-
-#define LOOKUP_PROTECT (1)
-#define LOOKUP_COMPLAIN (2)
-#define LOOKUP_NORMAL (3)
-#define LOOKUP_NONVIRTUAL (8)
-#define LOOKUP_GLOBAL (16)
-#define LOOKUP_SPECULATIVELY (64)
-#define LOOKUP_ONLYCONVERTING (128)
-#define DIRECT_BIND (256)
-#define LOOKUP_NO_CONVERSION (512)
-#define LOOKUP_DESTRUCTOR (512)
-#define LOOKUP_NO_TEMP_BIND (1024)
-#define LOOKUP_PREFER_TYPES (2048)
-#define LOOKUP_PREFER_NAMESPACES (4096)
-#define LOOKUP_PREFER_BOTH (6144)
-#define LOOKUP_TEMPLATES_EXPECTED (8192)
+ LOOKUP_PREFER_BOTH means class-or-namespace-name. */
+
+#define LOOKUP_PROTECT (1 << 0)
+#define LOOKUP_COMPLAIN (1 << 1)
+#define LOOKUP_NORMAL (LOOKUP_PROTECT | LOOKUP_COMPLAIN)
+#define LOOKUP_NONVIRTUAL (1 << 2)
+#define LOOKUP_GLOBAL (1 << 3)
+#define LOOKUP_SPECULATIVELY (1 << 4)
+#define LOOKUP_ONLYCONVERTING (1 << 5)
+#define DIRECT_BIND (1 << 6)
+#define LOOKUP_NO_CONVERSION (1 << 7)
+#define LOOKUP_DESTRUCTOR (1 << 8)
+#define LOOKUP_NO_TEMP_BIND (1 << 9)
+#define LOOKUP_PREFER_TYPES (1 << 10)
+#define LOOKUP_PREFER_NAMESPACES (1 << 11)
+#define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES)
+#define LOOKUP_CONSTRUCTOR_CALLABLE (1 << 12)
#define LOOKUP_NAMESPACES_ONLY(F) \
(((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
@@ -3477,20 +3393,12 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
#define COMPARE_STRICT 0 /* Just check if the types are the
same. */
#define COMPARE_BASE 1 /* Check to see if the second type is
- derived from the first, or if both
- are pointers (or references) and
- the types pointed to by the second
- type is derived from the pointed to
- by the first. */
-#define COMPARE_RELAXED 2 /* Like COMPARE_DERIVED, but in
- reverse. Also treat enumeration
- types as the same as integer types
- of the same width. */
-#define COMPARE_REDECLARATION 4 /* The comparsion is being done when
+ derived from the first. */
+#define COMPARE_DERIVED 2 /* Like COMPARE_BASE, but in
+ reverse. */
+#define COMPARE_REDECLARATION 4 /* The comparison is being done when
another declaration of an existing
entity is seen. */
-#define COMPARE_NO_ATTRIBUTES 8 /* The comparison should ignore
- extra-linguistic type attributes. */
/* Used with push_overloaded_decl. */
#define PUSH_GLOBAL 0 /* Push the DECL into namespace scope,
@@ -3548,7 +3456,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
TFF_TEMPLATE_HEADER: show the template<...> header in a
template-declaration.
TFF_TEMPLATE_NAME: show only template-name.
- TFF_EXPR_IN_PARENS: Parenthesize expressions. */
+ TFF_EXPR_IN_PARENS: parenthesize expressions.
+ TFF_NO_FUNCTION_ARGUMENTS: don't show function arguments. */
#define TFF_PLAIN_IDENTIFIER (0)
#define TFF_SCOPE (1)
@@ -3561,6 +3470,7 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
#define TFF_TEMPLATE_HEADER (1 << 7)
#define TFF_TEMPLATE_NAME (1 << 8)
#define TFF_EXPR_IN_PARENS (1 << 9)
+#define TFF_NO_FUNCTION_ARGUMENTS (1 << 10)
/* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM
node. */
@@ -3571,14 +3481,14 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
/* in lex.c */
-extern void init_reswords PARAMS ((void));
+extern void init_reswords (void);
/* Indexed by TREE_CODE, these tables give C-looking names to
operators represented by TREE_CODES. For example,
opname_tab[(int) MINUS_EXPR] == "-". */
extern const char **opname_tab, **assignop_tab;
-typedef struct operator_name_info_t
+typedef struct operator_name_info_t GTY(())
{
/* The IDENTIFIER_NODE for the operator. */
tree identifier;
@@ -3591,856 +3501,745 @@ typedef struct operator_name_info_t
} operator_name_info_t;
/* A mapping from tree codes to operator name information. */
-extern operator_name_info_t operator_name_info[];
+extern GTY(()) operator_name_info_t operator_name_info
+ [(int) LAST_CPLUS_TREE_CODE];
/* Similar, but for assignment operators. */
-extern operator_name_info_t assignment_operator_name_info[];
+extern GTY(()) operator_name_info_t assignment_operator_name_info
+ [(int) LAST_CPLUS_TREE_CODE];
/* in call.c */
-extern int check_dtor_name PARAMS ((tree, tree));
-extern int get_arglist_len_in_bytes PARAMS ((tree));
-
-extern tree build_vfield_ref PARAMS ((tree, tree));
-extern tree build_scoped_method_call PARAMS ((tree, tree, tree, tree));
-extern tree build_conditional_expr PARAMS ((tree, tree, tree));
-extern tree build_addr_func PARAMS ((tree));
-extern tree build_call PARAMS ((tree, tree));
-extern tree build_method_call PARAMS ((tree, tree, tree, tree, int));
-extern int null_ptr_cst_p PARAMS ((tree));
-extern int sufficient_parms_p PARAMS ((tree));
-extern tree type_decays_to PARAMS ((tree));
-extern tree resolve_scoped_fn_name PARAMS ((tree, tree));
-extern tree build_user_type_conversion PARAMS ((tree, tree, int));
-extern tree build_new_function_call PARAMS ((tree, tree));
-extern tree build_new_method_call (tree, tree, tree, tree, int);
-extern tree build_special_member_call (tree, tree, tree, tree, int);
-extern tree build_new_op PARAMS ((enum tree_code, int, tree, tree, tree));
-extern tree build_op_delete_call PARAMS ((enum tree_code, tree, tree, int, tree));
-extern int can_convert PARAMS ((tree, tree));
-extern int can_convert_arg PARAMS ((tree, tree, tree));
-extern int can_convert_arg_bad PARAMS ((tree, tree, tree));
-extern int enforce_access PARAMS ((tree, tree));
-extern tree convert_default_arg PARAMS ((tree, tree, tree, int));
-extern tree convert_arg_to_ellipsis PARAMS ((tree));
-extern tree build_x_va_arg PARAMS ((tree, tree));
-extern tree cxx_type_promotes_to PARAMS ((tree));
-extern tree type_passed_as PARAMS ((tree));
-extern tree convert_for_arg_passing PARAMS ((tree, tree));
-extern tree cp_convert_parm_for_inlining PARAMS ((tree, tree, tree));
-extern int is_properly_derived_from PARAMS ((tree, tree));
-extern tree initialize_reference PARAMS ((tree, tree, tree, tree *));
-extern tree make_temporary_var_for_ref_to_temp (tree, tree);
-extern tree strip_top_quals PARAMS ((tree));
-extern tree perform_implicit_conversion PARAMS ((tree, tree));
+extern bool check_dtor_name (tree, tree);
+
+extern tree build_vfield_ref (tree, tree);
+extern tree build_conditional_expr (tree, tree, tree);
+extern tree build_addr_func (tree);
+extern tree build_call (tree, tree);
+extern bool null_ptr_cst_p (tree);
+extern bool sufficient_parms_p (tree);
+extern tree type_decays_to (tree);
+extern tree build_user_type_conversion (tree, tree, int);
+extern tree build_new_function_call (tree, tree);
+extern tree build_operator_new_call (tree, tree, tree *, tree *);
+extern tree build_new_method_call (tree, tree, tree, tree, int);
+extern tree build_special_member_call (tree, tree, tree, tree, int);
+extern tree build_new_op (enum tree_code, int, tree, tree, tree, bool *);
+extern tree build_op_delete_call (enum tree_code, tree, tree, int, tree);
+extern bool can_convert (tree, tree);
+extern bool can_convert_arg (tree, tree, tree);
+extern bool can_convert_arg_bad (tree, tree, tree);
+extern bool enforce_access (tree, tree);
+extern tree convert_default_arg (tree, tree, tree, int);
+extern tree convert_arg_to_ellipsis (tree);
+extern tree build_x_va_arg (tree, tree);
+extern tree cxx_type_promotes_to (tree);
+extern tree type_passed_as (tree);
+extern tree convert_for_arg_passing (tree, tree);
+extern tree cp_convert_parm_for_inlining (tree, tree, tree);
+extern bool is_properly_derived_from (tree, tree);
+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);
extern tree perform_direct_initialization_if_possible (tree, tree);
+extern tree in_charge_arg_for_name (tree);
+extern tree build_cxx_call (tree, tree, tree);
/* in class.c */
-extern tree build_base_path PARAMS ((enum tree_code, tree, tree, int));
+extern tree build_base_path (enum tree_code, tree, tree, int);
extern tree convert_to_base (tree, tree, bool);
-extern tree convert_to_base_statically (tree, tree);
-extern tree build_vtbl_ref PARAMS ((tree, tree));
-extern tree build_vfn_ref PARAMS ((tree, tree));
-extern tree get_vtable_decl PARAMS ((tree, int));
-extern void add_method PARAMS ((tree, tree, int));
-extern int currently_open_class PARAMS ((tree));
-extern tree currently_open_derived_class PARAMS ((tree));
-extern void duplicate_tag_error PARAMS ((tree));
-extern tree finish_struct PARAMS ((tree, tree));
-extern void finish_struct_1 PARAMS ((tree));
-extern int resolves_to_fixed_type_p PARAMS ((tree, int *));
-extern void init_class_processing PARAMS ((void));
-extern int is_empty_class PARAMS ((tree));
-extern void pushclass PARAMS ((tree, int));
-extern void popclass PARAMS ((void));
-extern void push_nested_class PARAMS ((tree, int));
-extern void pop_nested_class PARAMS ((void));
-extern int current_lang_depth PARAMS ((void));
-extern void push_lang_context PARAMS ((tree));
-extern void pop_lang_context PARAMS ((void));
-extern tree instantiate_type PARAMS ((tree, tree, tsubst_flags_t));
-extern void print_class_statistics PARAMS ((void));
-extern void cxx_print_statistics PARAMS ((void));
-extern void cxx_print_xnode PARAMS ((FILE *, tree, int));
-extern void cxx_print_decl PARAMS ((FILE *, tree, int));
-extern void cxx_print_type PARAMS ((FILE *, tree, int));
-extern void cxx_print_identifier PARAMS ((FILE *, tree, int));
-extern void cxx_print_error_function PARAMS ((struct diagnostic_context *,
- const char *));
-extern void build_self_reference PARAMS ((void));
-extern int same_signature_p PARAMS ((tree, tree));
-extern void warn_hidden PARAMS ((tree));
-extern void maybe_add_class_template_decl_list PARAMS ((tree, tree, int));
-extern tree get_enclosing_class PARAMS ((tree));
-int is_base_of_enclosing_class PARAMS ((tree, tree));
-extern void unreverse_member_declarations PARAMS ((tree));
-extern void invalidate_class_lookup_cache PARAMS ((void));
-extern void maybe_note_name_used_in_class PARAMS ((tree, tree));
-extern void note_name_declared_in_class PARAMS ((tree, tree));
-extern tree get_vtbl_decl_for_binfo PARAMS ((tree));
-extern tree in_charge_arg_for_name PARAMS ((tree));
-extern tree build_cxx_call PARAMS ((tree, tree, tree));
-extern tree get_vtt_name PARAMS ((tree));
-extern tree get_primary_binfo PARAMS ((tree));
+extern tree convert_to_base_statically (tree, tree);
+extern tree build_vtbl_ref (tree, tree);
+extern tree build_vfn_ref (tree, tree);
+extern tree get_vtable_decl (tree, int);
+extern void resort_type_method_vec
+ (void *, void *, gt_pointer_operator, void *);
+extern void add_method (tree, tree, int);
+extern int currently_open_class (tree);
+extern tree currently_open_derived_class (tree);
+extern tree finish_struct (tree, tree);
+extern void finish_struct_1 (tree);
+extern int resolves_to_fixed_type_p (tree, int *);
+extern void init_class_processing (void);
+extern int is_empty_class (tree);
+extern void pushclass (tree);
+extern void popclass (void);
+extern void push_nested_class (tree);
+extern void pop_nested_class (void);
+extern int current_lang_depth (void);
+extern void push_lang_context (tree);
+extern void pop_lang_context (void);
+extern tree instantiate_type (tree, tree, tsubst_flags_t);
+extern void print_class_statistics (void);
+extern void cxx_print_statistics (void);
+extern void cxx_print_xnode (FILE *, tree, int);
+extern void cxx_print_decl (FILE *, tree, int);
+extern void cxx_print_type (FILE *, tree, int);
+extern void cxx_print_identifier (FILE *, tree, int);
+extern void cxx_print_error_function (struct diagnostic_context *,
+ const char *);
+extern void build_self_reference (void);
+extern int same_signature_p (tree, tree);
+extern void warn_hidden (tree);
+extern void maybe_add_class_template_decl_list (tree, tree, int);
+extern tree get_enclosing_class (tree);
+extern void unreverse_member_declarations (tree);
+extern void invalidate_class_lookup_cache (void);
+extern void maybe_note_name_used_in_class (tree, tree);
+extern void note_name_declared_in_class (tree, tree);
+extern tree get_vtbl_decl_for_binfo (tree);
+extern tree get_vtt_name (tree);
+extern tree get_primary_binfo (tree);
+extern void debug_class (tree);
+extern void debug_thunks (tree);
/* in cvt.c */
-extern tree convert_to_reference PARAMS ((tree, tree, int, int, tree));
-extern tree convert_from_reference PARAMS ((tree));
-extern tree convert_lvalue PARAMS ((tree, tree));
-extern tree force_rvalue PARAMS ((tree));
-extern tree ocp_convert PARAMS ((tree, tree, int, int));
-extern tree cp_convert PARAMS ((tree, tree));
-extern tree convert_to_void PARAMS ((tree, const char */*implicit context*/));
-extern tree convert_force PARAMS ((tree, tree, int));
-extern tree build_type_conversion PARAMS ((tree, tree));
-extern tree build_expr_type_conversion PARAMS ((int, tree, int));
-extern tree type_promotes_to PARAMS ((tree));
-extern tree perform_qualification_conversions PARAMS ((tree, tree));
-extern void clone_function_decl PARAMS ((tree, int));
-extern void adjust_clone_args PARAMS ((tree));
+extern tree convert_to_reference (tree, tree, int, int, tree);
+extern tree convert_from_reference (tree);
+extern tree convert_lvalue (tree, tree);
+extern tree force_rvalue (tree);
+extern tree ocp_convert (tree, tree, int, int);
+extern tree cp_convert (tree, tree);
+extern tree convert_to_void (tree, const char */*implicit context*/);
+extern tree convert_force (tree, tree, int);
+extern tree build_type_conversion (tree, tree);
+extern tree build_expr_type_conversion (int, tree, bool);
+extern tree type_promotes_to (tree);
+extern tree perform_qualification_conversions (tree, tree);
+extern void clone_function_decl (tree, int);
+extern void adjust_clone_args (tree);
/* decl.c */
-extern int global_bindings_p PARAMS ((void));
-extern int kept_level_p PARAMS ((void));
-extern bool innermost_scope_is_class_p (void);
-extern tree getdecls PARAMS ((void));
-extern void pushlevel PARAMS ((int));
-extern tree poplevel PARAMS ((int,int, int));
-extern void insert_block PARAMS ((tree));
-extern void set_block PARAMS ((tree));
-extern tree pushdecl PARAMS ((tree));
-extern void cxx_init_decl_processing PARAMS ((void));
+extern void insert_block (tree);
+extern void set_block (tree);
+extern tree pushdecl (tree);
+extern void cxx_init_decl_processing (void);
enum cp_tree_node_structure_enum cp_tree_node_structure
- PARAMS ((union lang_tree_node *));
-extern void cxx_insert_default_attributes PARAMS ((tree));
-extern bool cxx_mark_addressable PARAMS ((tree));
-extern void cxx_push_function_context PARAMS ((struct function *));
-extern void cxx_pop_function_context PARAMS ((struct function *));
-extern void cxx_mark_function_context PARAMS ((struct function *));
-extern int toplevel_bindings_p PARAMS ((void));
-extern int namespace_bindings_p PARAMS ((void));
-extern void keep_next_level PARAMS ((int));
-extern int template_parm_scope_p PARAMS ((void));
-extern void set_class_shadows PARAMS ((tree));
-extern void maybe_push_cleanup_level PARAMS ((tree));
-extern void begin_scope PARAMS ((scope_kind));
-extern void finish_scope PARAMS ((void));
-extern void note_level_for_for PARAMS ((void));
-extern void note_level_for_try PARAMS ((void));
-extern void note_level_for_catch PARAMS ((void));
-extern void resume_level PARAMS ((struct cp_binding_level *));
-extern void delete_block PARAMS ((tree));
-extern void add_block_current_level PARAMS ((tree));
-extern void pushlevel_class PARAMS ((void));
-extern void poplevel_class PARAMS ((void));
-extern void print_binding_stack PARAMS ((void));
-extern void print_binding_level PARAMS ((struct cp_binding_level *));
-extern void push_namespace PARAMS ((tree));
-extern void pop_namespace PARAMS ((void));
-extern void push_nested_namespace PARAMS ((tree));
-extern void pop_nested_namespace PARAMS ((tree));
-extern void maybe_push_to_top_level PARAMS ((int));
-extern void push_to_top_level PARAMS ((void));
-extern void pop_from_top_level PARAMS ((void));
-extern void push_switch PARAMS ((tree));
-extern void pop_switch PARAMS ((void));
-extern tree identifier_type_value PARAMS ((tree));
-extern void set_identifier_type_value PARAMS ((tree, tree));
-extern void pop_everything PARAMS ((void));
-extern void pushtag PARAMS ((tree, tree, int));
-extern tree make_anon_name PARAMS ((void));
-extern void clear_anon_tags PARAMS ((void));
-extern int decls_match PARAMS ((tree, tree));
-extern int duplicate_decls PARAMS ((tree, tree));
-extern tree pushdecl_top_level PARAMS ((tree));
+ (union lang_tree_node *);
+extern bool cxx_mark_addressable (tree);
+extern void cxx_push_function_context (struct function *);
+extern void cxx_pop_function_context (struct function *);
+extern void cxx_mark_function_context (struct function *);
+extern void maybe_push_cleanup_level (tree);
+extern void finish_scope (void);
+extern void delete_block (tree);
+extern void add_block_current_level (tree);
+extern void push_switch (tree);
+extern void pop_switch (void);
+extern void pushtag (tree, tree, int);
+extern tree make_anon_name (void);
+extern void clear_anon_tags (void);
+extern int decls_match (tree, tree);
+extern tree duplicate_decls (tree, tree);
+extern tree pushdecl_top_level (tree);
extern tree pushdecl_top_level_and_finish (tree, tree);
-extern bool pushdecl_class_level (tree);
-extern tree pushdecl_namespace_level PARAMS ((tree));
-extern tree push_using_decl PARAMS ((tree, tree));
-extern tree push_using_directive PARAMS ((tree));
-extern bool push_class_level_binding (tree, tree);
-extern tree implicitly_declare PARAMS ((tree));
-extern tree declare_local_label PARAMS ((tree));
-extern tree define_label PARAMS ((const char *, int, tree));
-extern void check_goto PARAMS ((tree));
-extern void define_case_label PARAMS ((void));
-extern cxx_binding *binding_for_name (tree, tree);
-extern tree namespace_binding PARAMS ((tree, tree));
-extern void set_namespace_binding PARAMS ((tree, tree, tree));
-extern tree lookup_namespace_name PARAMS ((tree, tree));
-extern tree build_typename_type PARAMS ((tree, tree, tree, tree));
-extern tree make_typename_type PARAMS ((tree, tree, tsubst_flags_t));
-extern tree make_unbound_class_template PARAMS ((tree, tree, tsubst_flags_t));
-extern tree lookup_name_nonclass PARAMS ((tree));
-extern tree lookup_function_nonclass PARAMS ((tree, tree));
-extern tree lookup_name PARAMS ((tree, int));
-extern tree lookup_name_current_level PARAMS ((tree));
-extern tree lookup_type_current_level PARAMS ((tree));
-extern tree lookup_name_namespace_only PARAMS ((tree));
-extern void begin_only_namespace_names PARAMS ((void));
-extern void end_only_namespace_names PARAMS ((void));
-extern tree namespace_ancestor PARAMS ((tree, tree));
-extern bool is_ancestor (tree, tree);
-extern tree unqualified_namespace_lookup PARAMS ((tree, int, tree *));
+extern tree push_using_decl (tree, tree);
+extern tree implicitly_declare (tree);
+extern tree declare_local_label (tree);
+extern tree define_label (location_t, tree);
+extern void check_goto (tree);
+extern void define_case_label (void);
+extern tree make_typename_type (tree, tree, tsubst_flags_t);
+extern tree make_unbound_class_template (tree, tree, tsubst_flags_t);
extern tree check_for_out_of_scope_variable (tree);
-extern bool lookup_using_namespace (tree, cxx_binding *, tree, tree, int, tree *);
-extern bool qualified_lookup_using_namespace (tree, tree, cxx_binding *, int);
-extern tree build_library_fn PARAMS ((tree, tree));
-extern tree build_library_fn_ptr PARAMS ((const char *, tree));
-extern tree build_cp_library_fn_ptr PARAMS ((const char *, tree));
-extern tree push_library_fn PARAMS ((tree, tree));
-extern tree push_void_library_fn PARAMS ((tree, tree));
-extern tree push_throw_library_fn PARAMS ((tree, tree));
-extern int init_type_desc PARAMS ((void));
-extern tree check_tag_decl PARAMS ((tree));
-extern void shadow_tag PARAMS ((tree));
-extern tree groktypename PARAMS ((tree));
-extern tree start_decl PARAMS ((tree, tree, int, tree, tree));
-extern void start_decl_1 PARAMS ((tree));
-extern void cp_finish_decl PARAMS ((tree, tree, tree, int));
-extern void finish_decl PARAMS ((tree, tree, tree));
-extern void maybe_inject_for_scope_var PARAMS ((tree));
-extern tree start_handler_parms PARAMS ((tree, tree));
-extern int complete_array_type PARAMS ((tree, tree, int));
-extern tree build_ptrmemfunc_type PARAMS ((tree));
+extern tree build_library_fn (tree, tree);
+extern tree build_library_fn_ptr (const char *, tree);
+extern tree build_cp_library_fn_ptr (const char *, tree);
+extern tree push_library_fn (tree, tree);
+extern tree push_void_library_fn (tree, tree);
+extern tree push_throw_library_fn (tree, tree);
+extern int init_type_desc (void);
+extern tree check_tag_decl (tree);
+extern tree shadow_tag (tree);
+extern tree groktypename (tree);
+extern tree start_decl (tree, tree, int, tree, tree);
+extern void start_decl_1 (tree);
+extern void cp_finish_decl (tree, tree, tree, int);
+extern void finish_decl (tree, tree, tree);
+extern void maybe_inject_for_scope_var (tree);
+extern tree start_handler_parms (tree, tree);
+extern int complete_array_type (tree, tree, int);
+extern tree build_ptrmemfunc_type (tree);
extern tree build_ptrmem_type (tree, tree);
/* the grokdeclarator prototype is in decl.h */
-extern int parmlist_is_exprlist PARAMS ((tree));
-extern int copy_fn_p PARAMS ((tree));
-extern void grok_special_member_properties PARAMS ((tree));
-extern int grok_ctor_properties PARAMS ((tree, tree));
-extern void grok_op_properties PARAMS ((tree, int));
-extern tree xref_tag (enum tag_types, tree, tree, bool);
-extern tree xref_tag_from_type PARAMS ((tree, tree, int));
-extern void xref_basetypes PARAMS ((tree, tree));
-extern tree start_enum PARAMS ((tree));
-extern void finish_enum PARAMS ((tree));
-extern void build_enumerator PARAMS ((tree, tree, tree));
-extern int start_function PARAMS ((tree, tree, tree, int));
-extern tree begin_function_body PARAMS ((void));
-extern void finish_function_body PARAMS ((tree));
-extern tree finish_function PARAMS ((int));
-extern tree start_method PARAMS ((tree, tree, tree));
-extern tree finish_method PARAMS ((tree));
-extern void maybe_register_incomplete_var PARAMS ((tree));
-extern void complete_vars PARAMS ((tree));
-extern void finish_stmt PARAMS ((void));
-extern void print_other_binding_stack PARAMS ((struct cp_binding_level *));
-extern void revert_static_member_fn PARAMS ((tree));
-extern void fixup_anonymous_aggr PARAMS ((tree));
-extern int check_static_variable_definition PARAMS ((tree, tree));
-extern tree compute_array_index_type PARAMS ((tree, tree));
-extern void push_local_binding PARAMS ((tree, tree, int));
-extern int push_class_binding PARAMS ((tree, tree));
-extern tree check_default_argument PARAMS ((tree, tree));
-extern tree push_overloaded_decl PARAMS ((tree, int));
-extern void clear_identifier_class_values PARAMS ((void));
-extern void storetags PARAMS ((tree));
-extern int vtable_decl_p PARAMS ((tree, void *));
-extern int vtype_decl_p PARAMS ((tree, void *));
-extern int sigtable_decl_p PARAMS ((tree, void *));
-typedef int (*walk_globals_pred) PARAMS ((tree, void *));
-typedef int (*walk_globals_fn) PARAMS ((tree *, void *));
-extern int walk_globals PARAMS ((walk_globals_pred,
- walk_globals_fn,
- void *));
-extern int walk_vtables PARAMS ((walk_globals_pred,
- walk_globals_fn,
- void *));
-typedef int (*walk_namespaces_fn) PARAMS ((tree, void *));
-extern int walk_namespaces PARAMS ((walk_namespaces_fn,
- void *));
-extern int wrapup_globals_for_namespace PARAMS ((tree, void *));
-extern tree cp_namespace_decls PARAMS ((tree));
-extern tree create_implicit_typedef PARAMS ((tree, tree));
-extern tree maybe_push_decl PARAMS ((tree));
-extern tree build_target_expr_with_type PARAMS ((tree, tree));
-extern int local_variable_p PARAMS ((tree));
-extern int nonstatic_local_decl_p PARAMS ((tree));
-extern tree declare_global_var PARAMS ((tree, tree));
-extern void register_dtor_fn PARAMS ((tree));
-extern tmpl_spec_kind current_tmpl_spec_kind PARAMS ((int));
-extern cxx_binding *cxx_scope_find_binding_for_name (tree, tree);
-extern tree cp_fname_init PARAMS ((const char *));
+extern int copy_fn_p (tree);
+extern tree get_scope_of_declarator (tree);
+extern void grok_special_member_properties (tree);
+extern int grok_ctor_properties (tree, tree);
+extern bool grok_op_properties (tree, int, bool);
+extern tree xref_tag (enum tag_types, tree, bool, bool);
+extern tree xref_tag_from_type (tree, tree, int);
+extern void xref_basetypes (tree, tree);
+extern tree start_enum (tree);
+extern void finish_enum (tree);
+extern void build_enumerator (tree, tree, tree);
+extern int start_function (tree, tree, tree, int);
+extern tree begin_function_body (void);
+extern void finish_function_body (tree);
+extern tree finish_function (int);
+extern tree start_method (tree, tree, tree);
+extern tree finish_method (tree);
+extern void maybe_register_incomplete_var (tree);
+extern void complete_vars (tree);
+extern void finish_stmt (void);
+extern void print_other_binding_stack (struct cp_binding_level *);
+extern void revert_static_member_fn (tree);
+extern void fixup_anonymous_aggr (tree);
+extern int check_static_variable_definition (tree, tree);
+extern tree compute_array_index_type (tree, tree);
+extern tree check_default_argument (tree, tree);
+extern int vtable_decl_p (tree, void *);
+extern int vtype_decl_p (tree, void *);
+extern int sigtable_decl_p (tree, void *);
+typedef bool (*walk_globals_pred) (tree, void *);
+typedef bool (*walk_globals_fn) (tree *, void *);
+extern bool walk_globals (walk_globals_pred, walk_globals_fn, void *);
+extern bool walk_vtables (walk_globals_pred, walk_globals_fn, void *);
+typedef int (*walk_namespaces_fn) (tree, void *);
+extern int walk_namespaces (walk_namespaces_fn,
+ void *);
+extern int wrapup_globals_for_namespace (tree, void *);
+extern tree create_implicit_typedef (tree, tree);
+extern tree maybe_push_decl (tree);
+extern tree force_target_expr (tree, tree);
+extern tree build_target_expr_with_type (tree, tree);
+extern int local_variable_p (tree);
+extern int nonstatic_local_decl_p (tree);
+extern tree declare_global_var (tree, tree);
+extern void register_dtor_fn (tree);
+extern tmpl_spec_kind current_tmpl_spec_kind (int);
+extern tree cp_fname_init (const char *, tree *);
+extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
+extern tree cxx_builtin_type_decls (void);
+extern void warn_extern_redeclared_static (tree, tree);
+
extern bool have_extern_spec;
/* in decl2.c */
-extern int check_java_method PARAMS ((tree));
-extern int grok_method_quals PARAMS ((tree, tree, tree));
-extern void warn_if_unknown_interface PARAMS ((tree));
-extern void grok_x_components PARAMS ((tree));
-extern void maybe_retrofit_in_chrg PARAMS ((tree));
-extern void maybe_make_one_only PARAMS ((tree));
-extern void grokclassfn PARAMS ((tree, tree, enum overload_flags, tree));
-extern tree grok_array_decl PARAMS ((tree, tree));
-extern tree delete_sanity PARAMS ((tree, tree, int, int));
-extern tree check_classfn PARAMS ((tree, tree));
-extern void check_member_template PARAMS ((tree));
-extern tree grokfield PARAMS ((tree, tree, tree, tree, tree));
-extern tree grokbitfield PARAMS ((tree, tree, tree));
-extern tree groktypefield PARAMS ((tree, tree));
-extern tree grokoptypename PARAMS ((tree, tree, tree));
-extern void cplus_decl_attributes PARAMS ((tree *, tree, int));
-extern tree constructor_name_full PARAMS ((tree));
-extern tree constructor_name PARAMS ((tree));
-extern bool constructor_name_p (tree, tree);
-extern void defer_fn PARAMS ((tree));
-extern void finish_anon_union PARAMS ((tree));
-extern tree finish_table PARAMS ((tree, tree, tree, int));
-extern void finish_builtin_type PARAMS ((tree, const char *,
- tree *, int, tree));
-extern tree coerce_new_type PARAMS ((tree));
-extern tree coerce_delete_type PARAMS ((tree));
-extern void comdat_linkage PARAMS ((tree));
-extern void import_export_vtable PARAMS ((tree, tree, int));
-extern void import_export_decl PARAMS ((tree));
-extern void import_export_tinfo PARAMS ((tree, tree, int));
-extern tree build_cleanup PARAMS ((tree));
-extern void finish_file PARAMS ((void));
-extern tree reparse_absdcl_as_expr PARAMS ((tree, tree));
-extern tree reparse_absdcl_as_casts PARAMS ((tree, tree));
-extern tree build_expr_from_tree PARAMS ((tree));
+extern bool check_java_method (tree);
+extern int grok_method_quals (tree, tree, tree);
+extern void grok_x_components (tree);
+extern void maybe_retrofit_in_chrg (tree);
+extern void maybe_make_one_only (tree);
+extern void grokclassfn (tree, tree, enum overload_flags, tree);
+extern tree grok_array_decl (tree, tree);
+extern tree delete_sanity (tree, tree, bool, int);
+extern tree check_classfn (tree, tree, bool);
+extern void check_member_template (tree);
+extern tree grokfield (tree, tree, tree, tree, tree);
+extern tree grokbitfield (tree, tree, tree);
+extern tree groktypefield (tree, tree);
+extern void cplus_decl_attributes (tree *, tree, int);
+extern void defer_fn (tree);
+extern void finish_anon_union (tree);
+extern tree finish_table (tree, tree, tree, int);
+extern tree coerce_new_type (tree);
+extern tree coerce_delete_type (tree);
+extern void comdat_linkage (tree);
+extern void import_export_vtable (tree, tree, int);
+extern void import_export_decl (tree);
+extern void import_export_tinfo (tree, tree, bool);
+extern tree build_cleanup (tree);
extern tree build_offset_ref_call_from_tree (tree, tree);
-extern tree build_call_from_tree (tree, tree, bool);
-extern tree reparse_decl_as_expr PARAMS ((tree, tree));
-extern tree finish_decl_parsing PARAMS ((tree));
-extern void set_decl_namespace PARAMS ((tree, tree, int));
-extern tree current_decl_namespace PARAMS ((void));
-extern void push_decl_namespace PARAMS ((tree));
-extern void pop_decl_namespace PARAMS ((void));
-extern void push_scope PARAMS ((tree));
-extern void pop_scope PARAMS ((tree));
-extern void do_namespace_alias PARAMS ((tree, tree));
-extern void do_toplevel_using_decl PARAMS ((tree));
-extern void do_local_using_decl PARAMS ((tree));
-extern tree do_class_using_decl PARAMS ((tree));
-extern void do_using_directive PARAMS ((tree));
-extern void check_default_args PARAMS ((tree));
-extern void mark_used PARAMS ((tree));
-extern tree handle_class_head (enum tag_types, tree, tree, tree, int, int *);
-extern tree handle_class_head_apparent_template (tree, int *);
-extern tree lookup_arg_dependent PARAMS ((tree, tree, tree));
-extern void finish_static_data_member_decl PARAMS ((tree, tree, tree, int));
-extern tree cp_build_parm_decl PARAMS ((tree, tree));
-extern tree build_artificial_parm PARAMS ((tree, tree));
-extern tree get_guard PARAMS ((tree));
-extern tree get_guard_cond PARAMS ((tree));
-extern tree set_guard PARAMS ((tree));
-
-extern void cp_error_at PARAMS ((const char *msgid, ...));
-extern void cp_warning_at PARAMS ((const char *msgid, ...));
-extern void cp_pedwarn_at PARAMS ((const char *msgid, ...));
+extern void check_default_args (tree);
+extern void mark_used (tree);
+extern void finish_static_data_member_decl (tree, tree, tree, int);
+extern tree cp_build_parm_decl (tree, tree);
+extern tree build_artificial_parm (tree, tree);
+extern tree get_guard (tree);
+extern tree get_guard_cond (tree);
+extern tree set_guard (tree);
+extern tree cxx_callgraph_analyze_expr (tree *, int *, tree);
/* XXX Not i18n clean. */
-#define cp_deprecated(STR) \
- do { \
- if (warn_deprecated) \
- warning ("%s is deprecated, please see the documentation for details", \
- (STR)); \
+#define cp_deprecated(STR) \
+ do { \
+ if (warn_deprecated) \
+ warning ("%s is deprecated, please see the documentation for details", \
+ (STR)); \
} while (0)
/* in error.c */
-extern void init_error PARAMS ((void));
-extern const char *type_as_string PARAMS ((tree, int));
-extern const char *decl_as_string PARAMS ((tree, int));
-extern const char *expr_as_string PARAMS ((tree, int));
-extern const char *context_as_string PARAMS ((tree, int));
-extern const char *lang_decl_name PARAMS ((tree, int));
-extern const char *cp_file_of PARAMS ((tree));
-extern int cp_line_of PARAMS ((tree));
-extern const char *language_to_string PARAMS ((enum languages, int));
-extern void print_instantiation_context PARAMS ((void));
+extern void init_error (void);
+extern const char *type_as_string (tree, int);
+extern const char *decl_as_string (tree, int);
+extern const char *expr_as_string (tree, int);
+extern const char *context_as_string (tree, int);
+extern const char *lang_decl_name (tree, int);
+extern const char *language_to_string (enum languages);
+extern void print_instantiation_context (void);
/* in except.c */
-extern void init_exception_processing PARAMS ((void));
-extern tree expand_start_catch_block PARAMS ((tree));
-extern void expand_end_catch_block PARAMS ((void));
-extern void expand_builtin_throw PARAMS ((void));
-extern void expand_eh_spec_block PARAMS ((tree));
-extern void expand_exception_blocks PARAMS ((void));
-extern tree build_exc_ptr PARAMS ((void));
-extern tree build_throw PARAMS ((tree));
-extern void mark_all_runtime_matches PARAMS ((void));
-extern int nothrow_libfn_p PARAMS ((tree));
-extern void check_handlers PARAMS ((tree));
-extern void choose_personality_routine PARAMS ((enum languages));
+extern void init_exception_processing (void);
+extern tree expand_start_catch_block (tree);
+extern void expand_end_catch_block (void);
+extern void expand_builtin_throw (void);
+extern void expand_eh_spec_block (tree);
+extern void expand_exception_blocks (void);
+extern tree build_exc_ptr (void);
+extern tree build_throw (tree);
+extern void mark_all_runtime_matches (void);
+extern int nothrow_libfn_p (tree);
+extern void check_handlers (tree);
+extern void choose_personality_routine (enum languages);
+extern tree eh_type_info (tree);
/* in expr.c */
-extern rtx cxx_expand_expr PARAMS ((tree, rtx,
- enum machine_mode,
- int));
-extern tree cplus_expand_constant PARAMS ((tree));
+extern rtx cxx_expand_expr (tree, rtx,
+ enum machine_mode,
+ int, rtx *);
+extern tree cplus_expand_constant (tree);
/* friend.c */
-extern int is_friend PARAMS ((tree, tree));
-extern void make_friend_class PARAMS ((tree, tree));
-extern void add_friend PARAMS ((tree, tree));
-extern tree do_friend PARAMS ((tree, tree, tree, tree, tree, enum overload_flags, tree, int));
+extern int is_friend (tree, tree);
+extern void make_friend_class (tree, tree, bool);
+extern void add_friend (tree, tree, bool);
+extern tree do_friend (tree, tree, tree, tree, enum overload_flags, tree, int);
/* in init.c */
extern tree expand_member_init (tree);
extern void emit_mem_initializers (tree);
-extern tree build_aggr_init PARAMS ((tree, tree, int));
-extern tree build_init PARAMS ((tree, tree, int));
-extern int is_aggr_type PARAMS ((tree, int));
-extern tree get_aggr_from_typedef PARAMS ((tree, int));
-extern tree get_type_value PARAMS ((tree));
+extern tree build_aggr_init (tree, tree, int);
+extern tree build_init (tree, tree, int);
+extern int is_aggr_type (tree, int);
+extern tree get_aggr_from_typedef (tree, int);
+extern tree get_type_value (tree);
extern tree build_zero_init (tree, tree, bool);
-extern tree build_member_call PARAMS ((tree, tree, tree));
-extern tree build_offset_ref PARAMS ((tree, tree));
-extern tree resolve_offset_ref PARAMS ((tree));
-extern tree build_new PARAMS ((tree, tree, tree, int));
-extern tree build_vec_init PARAMS ((tree, tree, tree, int));
-extern tree build_x_delete PARAMS ((tree, int, tree));
-extern tree build_delete PARAMS ((tree, tree, special_function_kind, int, int));
-extern void push_base_cleanups PARAMS ((void));
-extern tree build_vbase_delete PARAMS ((tree, tree));
-extern tree build_vec_delete PARAMS ((tree, tree, special_function_kind, int));
-extern tree create_temporary_var PARAMS ((tree));
-extern void begin_init_stmts PARAMS ((tree *, tree *));
-extern tree finish_init_stmts PARAMS ((tree, tree));
-extern void initialize_vtbl_ptrs PARAMS ((tree));
-extern tree build_java_class_ref PARAMS ((tree));
+extern tree build_offset_ref (tree, tree, bool);
+extern tree build_new (tree, tree, tree, int);
+extern tree build_vec_init (tree, tree, tree, int);
+extern tree build_x_delete (tree, int, tree);
+extern tree build_delete (tree, tree, special_function_kind, int, int);
+extern void push_base_cleanups (void);
+extern tree build_vbase_delete (tree, tree);
+extern tree build_vec_delete (tree, tree, special_function_kind, int);
+extern tree create_temporary_var (tree);
+extern void initialize_vtbl_ptrs (tree);
+extern tree build_java_class_ref (tree);
/* in input.c */
/* in lex.c */
-extern void cxx_dup_lang_specific_decl PARAMS ((tree));
-extern tree make_pointer_declarator PARAMS ((tree, tree));
-extern tree make_reference_declarator PARAMS ((tree, tree));
-extern tree make_call_declarator PARAMS ((tree, tree, tree, tree));
-extern void set_quals_and_spec PARAMS ((tree, tree, tree));
-extern void print_parse_statistics PARAMS ((void));
-extern void do_pending_inlines PARAMS ((void));
-extern void process_next_inline PARAMS ((struct unparsed_text *));
-
-extern void yyungetc PARAMS ((int, int));
-extern void snarf_method PARAMS ((tree));
-
-extern void check_for_missing_semicolon PARAMS ((tree));
-extern void note_got_semicolon PARAMS ((tree));
-extern void note_list_got_semicolon PARAMS ((tree));
-extern void do_pending_lang_change PARAMS ((void));
-extern void see_typename PARAMS ((void));
-extern void unqualified_name_lookup_error PARAMS ((tree));
-extern tree do_identifier PARAMS ((tree, int, tree));
-extern tree do_scoped_id PARAMS ((tree, tree));
-extern tree identifier_typedecl_value PARAMS ((tree));
-extern tree build_lang_decl PARAMS ((enum tree_code, tree, tree));
-extern void retrofit_lang_decl PARAMS ((tree));
-extern tree copy_decl PARAMS ((tree));
-extern tree copy_type PARAMS ((tree));
-extern tree cxx_make_type PARAMS ((enum tree_code));
-extern tree make_aggr_type PARAMS ((enum tree_code));
-extern void yyerror PARAMS ((const char *));
-extern void yyhook PARAMS ((int));
-extern int cp_type_qual_from_rid PARAMS ((tree));
-extern const char *cxx_init PARAMS ((const char *));
-extern void cxx_finish PARAMS ((void));
-extern void cxx_init_options PARAMS ((void));
+extern void cxx_dup_lang_specific_decl (tree);
+extern tree make_pointer_declarator (tree, tree);
+extern tree make_reference_declarator (tree, tree);
+extern tree make_call_declarator (tree, tree, tree, tree);
+extern void set_quals_and_spec (tree, tree, tree);
+extern void print_parse_statistics (void);
+extern void do_pending_inlines (void);
+extern void yyungetc (int, int);
+extern void snarf_method (tree);
+
+extern void see_typename (void);
+extern tree unqualified_name_lookup_error (tree);
+extern tree unqualified_fn_lookup_error (tree);
+extern tree build_lang_decl (enum tree_code, tree, tree);
+extern void retrofit_lang_decl (tree);
+extern tree copy_decl (tree);
+extern tree copy_type (tree);
+extern tree cxx_make_type (enum tree_code);
+extern tree make_aggr_type (enum tree_code);
+extern void yyerror (const char *);
+extern void yyhook (int);
+extern int cp_type_qual_from_rid (tree);
+extern bool cxx_init (void);
+extern void cxx_finish (void);
/* in method.c */
-extern void init_method PARAMS ((void));
-extern void set_mangled_name_for_decl PARAMS ((tree));
-extern tree build_opfncall PARAMS ((enum tree_code, int, tree, tree, tree));
-extern tree hack_identifier PARAMS ((tree, tree));
-extern tree make_thunk PARAMS ((tree, tree, tree));
-extern void use_thunk PARAMS ((tree, int));
-extern void synthesize_method PARAMS ((tree));
-extern tree implicitly_declare_fn PARAMS ((special_function_kind, tree, int));
-extern tree skip_artificial_parms_for PARAMS ((tree, tree));
+extern void init_method (void);
+extern void set_mangled_name_for_decl (tree);
+extern tree make_thunk (tree, bool, tree, tree);
+extern void finish_thunk (tree);
+extern void use_thunk (tree, bool);
+extern void synthesize_method (tree);
+extern tree implicitly_declare_fn (special_function_kind, tree, bool);
+extern tree skip_artificial_parms_for (tree, tree);
/* In optimize.c */
-extern void optimize_function PARAMS ((tree));
-extern int calls_setjmp_p PARAMS ((tree));
-extern int maybe_clone_body PARAMS ((tree));
+extern void optimize_function (tree);
+extern bool calls_setjmp_p (tree);
+extern bool maybe_clone_body (tree);
/* in pt.c */
-extern void check_template_shadow PARAMS ((tree));
-extern tree get_innermost_template_args PARAMS ((tree, int));
-extern tree tsubst PARAMS ((tree, tree, tsubst_flags_t, tree));
-extern tree tsubst_expr PARAMS ((tree, tree, tsubst_flags_t, tree));
-extern tree tsubst_copy PARAMS ((tree, tree, tsubst_flags_t, tree));
-extern void maybe_begin_member_template_processing PARAMS ((tree));
-extern void maybe_end_member_template_processing PARAMS ((void));
-extern tree finish_member_template_decl PARAMS ((tree));
-extern void begin_template_parm_list PARAMS ((void));
-extern void begin_specialization PARAMS ((void));
-extern void reset_specialization PARAMS ((void));
-extern void end_specialization PARAMS ((void));
-extern void begin_explicit_instantiation PARAMS ((void));
-extern void end_explicit_instantiation PARAMS ((void));
-extern tree check_explicit_specialization PARAMS ((tree, tree, int, int));
-extern tree process_template_parm PARAMS ((tree, tree));
-extern tree end_template_parm_list PARAMS ((tree));
-extern void end_template_decl PARAMS ((void));
-extern tree current_template_args PARAMS ((void));
-extern tree push_template_decl PARAMS ((tree));
-extern tree push_template_decl_real PARAMS ((tree, int));
-extern void redeclare_class_template PARAMS ((tree, tree));
-extern tree lookup_template_class PARAMS ((tree, tree, tree, tree, int, tsubst_flags_t));
-extern tree lookup_template_function PARAMS ((tree, tree));
-extern int uses_template_parms PARAMS ((tree));
-extern tree instantiate_class_template PARAMS ((tree));
-extern tree instantiate_template PARAMS ((tree, tree));
-extern int fn_type_unification PARAMS ((tree, tree, tree, tree, tree, unification_kind_t, int));
-extern tree tinst_for_decl PARAMS ((void));
-extern void mark_decl_instantiated PARAMS ((tree, int));
-extern int more_specialized PARAMS ((tree, tree, int, int));
-extern void mark_class_instantiated PARAMS ((tree, int));
+extern void check_template_shadow (tree);
+extern tree get_innermost_template_args (tree, int);
+extern void maybe_begin_member_template_processing (tree);
+extern void maybe_end_member_template_processing (void);
+extern tree finish_member_template_decl (tree);
+extern void begin_template_parm_list (void);
+extern void begin_specialization (void);
+extern void reset_specialization (void);
+extern void end_specialization (void);
+extern void begin_explicit_instantiation (void);
+extern void end_explicit_instantiation (void);
+extern tree check_explicit_specialization (tree, tree, int, int);
+extern tree process_template_parm (tree, tree);
+extern tree end_template_parm_list (tree);
+extern void end_template_decl (void);
+extern tree current_template_args (void);
+extern tree push_template_decl (tree);
+extern tree push_template_decl_real (tree, int);
+extern void redeclare_class_template (tree, tree);
+extern tree lookup_template_class (tree, tree, tree, tree, int, tsubst_flags_t);
+extern tree lookup_template_function (tree, tree);
+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, tree, unification_kind_t, int);
+extern tree tinst_for_decl (void);
+extern void mark_decl_instantiated (tree, int);
+extern int more_specialized (tree, tree, int, int);
+extern void mark_class_instantiated (tree, int);
extern void do_decl_instantiation (tree, tree);
-extern void do_type_instantiation PARAMS ((tree, tree, tsubst_flags_t));
-extern tree instantiate_decl PARAMS ((tree, int));
-extern tree get_bindings PARAMS ((tree, tree, tree));
-extern int push_tinst_level PARAMS ((tree));
-extern void pop_tinst_level PARAMS ((void));
-extern int more_specialized_class PARAMS ((tree, tree, tree));
-extern int is_member_template PARAMS ((tree));
-extern int comp_template_parms PARAMS ((tree, tree));
-extern int template_class_depth PARAMS ((tree));
-extern int is_specialization_of PARAMS ((tree, tree));
-extern int comp_template_args PARAMS ((tree, tree));
-extern void maybe_process_partial_specialization PARAMS ((tree));
-extern void maybe_check_template_type PARAMS ((tree));
-extern tree most_specialized_instantiation PARAMS ((tree));
-extern void print_candidates PARAMS ((tree));
-extern int instantiate_pending_templates PARAMS ((void));
-extern tree tsubst_default_argument PARAMS ((tree, tree, tree));
-extern tree most_general_template PARAMS ((tree));
-extern tree get_mostly_instantiated_function_type PARAMS ((tree));
-extern int problematic_instantiation_changed PARAMS ((void));
-extern void record_last_problematic_instantiation PARAMS ((void));
-extern tree current_instantiation PARAMS ((void));
+extern void do_type_instantiation (tree, tree, tsubst_flags_t);
+extern tree instantiate_decl (tree, int);
+extern int push_tinst_level (tree);
+extern void pop_tinst_level (void);
+extern int more_specialized_class (tree, tree, tree);
+extern int is_member_template (tree);
+extern int comp_template_parms (tree, tree);
+extern int template_class_depth (tree);
+extern int is_specialization_of (tree, tree);
+extern bool is_specialization_of_friend (tree, tree);
+extern int comp_template_args (tree, tree);
+extern void maybe_process_partial_specialization (tree);
+extern void maybe_check_template_type (tree);
+extern tree most_specialized_instantiation (tree);
+extern void print_candidates (tree);
+extern int instantiate_pending_templates (void);
+extern tree tsubst_default_argument (tree, tree, tree);
+extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t, tree, bool);
+extern tree most_general_template (tree);
+extern tree get_mostly_instantiated_function_type (tree);
+extern int problematic_instantiation_changed (void);
+extern void record_last_problematic_instantiation (void);
+extern tree current_instantiation (void);
+extern tree maybe_get_template_decl_from_type_decl (tree);
extern int processing_template_parmlist;
+extern bool dependent_type_p (tree);
+extern bool any_dependent_template_arguments_p (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 (tree);
+extern bool value_dependent_expression_p (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 bool reregister_specialization (tree, tree, tree);
+extern tree fold_non_dependent_expr (tree);
/* in repo.c */
-extern void repo_template_used PARAMS ((tree));
-extern void repo_template_instantiated PARAMS ((tree, int));
-extern void init_repo PARAMS ((const char *));
-extern void finish_repo PARAMS ((void));
+extern void repo_template_used (tree);
+extern void repo_template_instantiated (tree, bool);
+extern void init_repo (const char *);
+extern void finish_repo (void);
/* in rtti.c */
-extern void init_rtti_processing PARAMS((void));
-extern tree build_typeid PARAMS((tree));
-extern tree get_tinfo_decl PARAMS((tree));
-extern tree get_typeid PARAMS((tree));
-extern tree build_dynamic_cast PARAMS((tree, tree));
-extern void emit_support_tinfos PARAMS((void));
-extern int unemitted_tinfo_decl_p PARAMS((tree, void *));
-extern int emit_tinfo_decl PARAMS((tree *, void *));
+/* A varray of all tinfo decls that haven't been emitted yet. */
+extern GTY(()) varray_type unemitted_tinfo_decls;
+
+extern void init_rtti_processing (void);
+extern tree build_typeid (tree);
+extern tree get_tinfo_decl (tree);
+extern tree get_typeid (tree);
+extern tree build_dynamic_cast (tree, tree);
+extern void emit_support_tinfos (void);
+extern bool emit_tinfo_decl (tree);
/* in search.c */
extern bool accessible_base_p (tree, tree);
-extern tree lookup_base PARAMS ((tree, tree, base_access, base_kind *));
-extern int types_overlap_p PARAMS ((tree, tree));
-extern tree get_vbase PARAMS ((tree, tree));
-extern tree get_dynamic_cast_base_type PARAMS ((tree, tree));
-extern void type_access_control PARAMS ((tree, tree));
-extern int accessible_p PARAMS ((tree, tree));
+extern tree lookup_base (tree, tree, base_access, base_kind *);
+extern int types_overlap_p (tree, tree);
+extern tree get_dynamic_cast_base_type (tree, tree);
+extern int accessible_p (tree, tree);
extern tree lookup_field_1 (tree, tree, bool);
-extern tree lookup_field PARAMS ((tree, tree, int, int));
-extern tree lookup_nested_field PARAMS ((tree, int));
-extern int lookup_fnfields_1 PARAMS ((tree, tree));
-extern tree lookup_fnfields PARAMS ((tree, tree, int));
-extern tree lookup_member PARAMS ((tree, tree, int, int));
-extern int look_for_overrides PARAMS ((tree, tree));
-extern void get_pure_virtuals PARAMS ((tree));
-extern void get_vbase_types PARAMS ((tree));
-extern void maybe_suppress_debug_info PARAMS ((tree));
-extern void note_debug_info_needed PARAMS ((tree));
-extern void push_class_decls PARAMS ((tree));
-extern void pop_class_decls PARAMS ((void));
-extern void unuse_fields PARAMS ((tree));
-extern void print_search_statistics PARAMS ((void));
-extern void init_search_processing PARAMS ((void));
-extern void reinit_search_statistics PARAMS ((void));
-extern tree current_scope PARAMS ((void));
-extern int at_function_scope_p PARAMS ((void));
+extern tree lookup_field (tree, tree, int, bool);
+extern int lookup_fnfields_1 (tree, tree);
+extern tree lookup_fnfields (tree, tree, int);
+extern tree lookup_member (tree, tree, int, bool);
+extern int look_for_overrides (tree, tree);
+extern void get_pure_virtuals (tree);
+extern void maybe_suppress_debug_info (tree);
+extern void note_debug_info_needed (tree);
+extern void push_class_decls (tree);
+extern void pop_class_decls (void);
+extern void unuse_fields (tree);
+extern void print_search_statistics (void);
+extern void init_search_processing (void);
+extern void reinit_search_statistics (void);
+extern tree current_scope (void);
+extern int at_function_scope_p (void);
extern bool at_class_scope_p (void);
-extern tree context_for_name_lookup PARAMS ((tree));
-extern tree lookup_conversions PARAMS ((tree));
-extern tree binfo_for_vtable PARAMS ((tree));
-extern tree binfo_from_vbase PARAMS ((tree));
-extern tree look_for_overrides_here PARAMS ((tree, tree));
-extern int check_final_overrider PARAMS ((tree, tree));
-extern tree dfs_walk PARAMS ((tree,
- tree (*) (tree, void *),
- tree (*) (tree, void *),
- void *));
-extern tree dfs_walk_real PARAMS ((tree,
- tree (*) (tree, void *),
- tree (*) (tree, void *),
- tree (*) (tree, void *),
- void *));
-extern tree dfs_unmark PARAMS ((tree, void *));
-extern tree markedp PARAMS ((tree, void *));
-extern tree unmarkedp PARAMS ((tree, void *));
-extern tree dfs_unmarked_real_bases_queue_p PARAMS ((tree, void *));
-extern tree dfs_marked_real_bases_queue_p PARAMS ((tree, void *));
-extern tree dfs_skip_vbases PARAMS ((tree, void *));
-extern tree marked_vtable_pathp PARAMS ((tree, void *));
-extern tree unmarked_vtable_pathp PARAMS ((tree, void *));
-extern tree find_vbase_instance PARAMS ((tree, tree));
-extern tree binfo_for_vbase PARAMS ((tree, tree));
-extern tree binfo_via_virtual PARAMS ((tree, tree));
+extern bool at_namespace_scope_p (void);
+extern tree context_for_name_lookup (tree);
+extern tree lookup_conversions (tree);
+extern tree binfo_for_vtable (tree);
+extern tree binfo_from_vbase (tree);
+extern tree look_for_overrides_here (tree, tree);
+extern int check_final_overrider (tree, tree);
+extern tree dfs_walk (tree,
+ tree (*) (tree, void *),
+ tree (*) (tree, int, void *),
+ void *);
+extern tree dfs_walk_real (tree,
+ tree (*) (tree, void *),
+ tree (*) (tree, void *),
+ tree (*) (tree, int, void *),
+ void *);
+extern tree dfs_unmark (tree, void *);
+extern tree markedp (tree, int, void *);
+extern tree unmarkedp (tree, int, void *);
+extern tree binfo_via_virtual (tree, tree);
extern tree build_baselink (tree, tree, tree, tree);
extern tree adjust_result_of_qualified_name_lookup
(tree, tree, tree);
+extern tree copied_binfo (tree, tree);
+extern tree original_binfo (tree, tree);
+
/* in semantics.c */
-extern void init_cp_semantics PARAMS ((void));
-extern tree finish_expr_stmt PARAMS ((tree));
-extern tree begin_if_stmt PARAMS ((void));
-extern void finish_if_stmt_cond PARAMS ((tree, tree));
-extern tree finish_then_clause PARAMS ((tree));
-extern void begin_else_clause PARAMS ((void));
-extern void finish_else_clause PARAMS ((tree));
-extern void finish_if_stmt PARAMS ((void));
-extern tree begin_while_stmt PARAMS ((void));
-extern void finish_while_stmt_cond PARAMS ((tree, tree));
-extern void finish_while_stmt PARAMS ((tree));
-extern tree begin_do_stmt PARAMS ((void));
-extern void finish_do_body PARAMS ((tree));
-extern void finish_do_stmt PARAMS ((tree, tree));
-extern tree finish_return_stmt PARAMS ((tree));
-extern tree begin_for_stmt PARAMS ((void));
-extern void finish_for_init_stmt PARAMS ((tree));
-extern void finish_for_cond PARAMS ((tree, tree));
-extern void finish_for_expr PARAMS ((tree, tree));
-extern void finish_for_stmt PARAMS ((tree));
-extern tree finish_break_stmt PARAMS ((void));
-extern tree finish_continue_stmt PARAMS ((void));
-extern tree begin_switch_stmt PARAMS ((void));
-extern void finish_switch_cond PARAMS ((tree, tree));
-extern void finish_switch_stmt PARAMS ((tree));
-extern tree finish_case_label PARAMS ((tree, tree));
-extern tree finish_goto_stmt PARAMS ((tree));
-extern tree begin_try_block PARAMS ((void));
-extern void finish_try_block PARAMS ((tree));
-extern tree begin_eh_spec_block PARAMS ((void));
-extern void finish_eh_spec_block PARAMS ((tree, tree));
-extern void finish_handler_sequence PARAMS ((tree));
-extern tree begin_function_try_block PARAMS ((void));
-extern void finish_function_try_block PARAMS ((tree));
-extern void finish_function_handler_sequence PARAMS ((tree));
-extern void finish_cleanup_try_block PARAMS ((tree));
-extern tree begin_handler PARAMS ((void));
-extern void finish_handler_parms PARAMS ((tree, tree));
-extern void begin_catch_block PARAMS ((tree));
-extern void finish_handler PARAMS ((tree));
-extern void finish_cleanup PARAMS ((tree, tree));
-extern tree begin_compound_stmt PARAMS ((int));
-extern tree finish_compound_stmt PARAMS ((int, tree));
-extern tree finish_asm_stmt PARAMS ((tree, tree, tree, tree, tree));
-extern void finish_label_stmt PARAMS ((tree));
-extern void finish_label_decl PARAMS ((tree));
-extern void finish_subobject PARAMS ((tree));
-extern tree finish_parenthesized_expr PARAMS ((tree));
-extern tree begin_stmt_expr PARAMS ((void));
-extern tree finish_stmt_expr PARAMS ((tree));
-extern tree finish_call_expr (tree, tree, bool);
-extern tree finish_increment_expr PARAMS ((tree, enum tree_code));
-extern tree finish_this_expr PARAMS ((void));
-extern tree finish_object_call_expr PARAMS ((tree, tree, tree));
-extern tree finish_qualified_object_call_expr PARAMS ((tree, tree, tree));
-extern tree finish_pseudo_destructor_call_expr PARAMS ((tree, tree, tree));
-extern tree finish_unary_op_expr PARAMS ((enum tree_code, tree));
-extern tree finish_id_expr PARAMS ((tree));
+extern void push_deferring_access_checks (deferring_kind);
+extern void resume_deferring_access_checks (void);
+extern void stop_deferring_access_checks (void);
+extern void pop_deferring_access_checks (void);
+extern tree get_deferred_access_checks (void);
+extern void pop_to_parent_deferring_access_checks (void);
+extern void perform_deferred_access_checks (void);
+extern void perform_or_defer_access_check (tree, tree);
+extern void init_cp_semantics (void);
+extern tree finish_expr_stmt (tree);
+extern tree begin_if_stmt (void);
+extern void finish_if_stmt_cond (tree, tree);
+extern tree finish_then_clause (tree);
+extern void begin_else_clause (void);
+extern void finish_else_clause (tree);
+extern void finish_if_stmt (void);
+extern tree begin_while_stmt (void);
+extern void finish_while_stmt_cond (tree, tree);
+extern void finish_while_stmt (tree);
+extern tree begin_do_stmt (void);
+extern void finish_do_body (tree);
+extern void finish_do_stmt (tree, tree);
+extern tree finish_return_stmt (tree);
+extern tree begin_for_stmt (void);
+extern void finish_for_init_stmt (tree);
+extern void finish_for_cond (tree, tree);
+extern void finish_for_expr (tree, tree);
+extern void finish_for_stmt (tree);
+extern tree finish_break_stmt (void);
+extern tree finish_continue_stmt (void);
+extern tree begin_switch_stmt (void);
+extern void finish_switch_cond (tree, tree);
+extern void finish_switch_stmt (tree);
+extern tree finish_case_label (tree, tree);
+extern tree finish_goto_stmt (tree);
+extern tree begin_try_block (void);
+extern void finish_try_block (tree);
+extern tree begin_eh_spec_block (void);
+extern void finish_eh_spec_block (tree, tree);
+extern void finish_handler_sequence (tree);
+extern tree begin_function_try_block (void);
+extern void finish_function_try_block (tree);
+extern void finish_function_handler_sequence (tree);
+extern void finish_cleanup_try_block (tree);
+extern tree begin_handler (void);
+extern void finish_handler_parms (tree, tree);
+extern void begin_catch_block (tree);
+extern void finish_handler (tree);
+extern void finish_cleanup (tree, tree);
+extern tree begin_compound_stmt (bool);
+extern tree finish_compound_stmt (tree);
+extern tree finish_asm_stmt (tree, tree, tree, tree, tree);
+extern tree finish_label_stmt (tree);
+extern void finish_label_decl (tree);
+extern void finish_subobject (tree);
+extern tree finish_parenthesized_expr (tree);
+extern tree finish_non_static_data_member (tree, tree, tree);
+extern tree begin_stmt_expr (void);
+extern tree finish_stmt_expr_expr (tree);
+extern tree finish_stmt_expr (tree, bool);
+extern tree perform_koenig_lookup (tree, tree);
+extern tree finish_call_expr (tree, tree, bool, bool);
+extern tree finish_increment_expr (tree, enum tree_code);
+extern tree finish_this_expr (void);
+extern tree finish_pseudo_destructor_expr (tree, tree, tree);
+extern tree finish_unary_op_expr (enum tree_code, tree);
+extern tree finish_compound_literal (tree, tree);
extern tree finish_fname (tree);
-extern void save_type_access_control PARAMS ((tree));
-extern void reset_type_access_control PARAMS ((void));
-extern void decl_type_access_control PARAMS ((tree));
extern int begin_function_definition (tree, tree, tree);
-extern tree begin_constructor_declarator PARAMS ((tree, tree));
-extern tree finish_declarator PARAMS ((tree, tree, tree, tree, int));
-extern void finish_translation_unit PARAMS ((void));
-extern tree finish_template_type_parm PARAMS ((tree, tree));
-extern tree finish_template_template_parm PARAMS ((tree, tree));
-extern tree finish_parmlist PARAMS ((tree, int));
-extern tree begin_class_definition PARAMS ((tree));
-extern tree finish_class_definition PARAMS ((tree, tree, int, int));
-extern void finish_default_args PARAMS ((void));
-extern void begin_inline_definitions PARAMS ((void));
-extern tree finish_member_class_template PARAMS ((tree));
-extern void finish_template_decl PARAMS ((tree));
-extern tree finish_template_type PARAMS ((tree, tree, int));
-extern void enter_scope_of PARAMS ((tree));
-extern tree finish_base_specifier PARAMS ((tree, tree));
-extern void finish_member_declaration PARAMS ((tree));
-extern void check_multiple_declarators PARAMS ((void));
-extern tree finish_typeof PARAMS ((tree));
-extern tree finish_sizeof PARAMS ((tree));
-extern tree finish_alignof PARAMS ((tree));
-extern void finish_decl_cleanup PARAMS ((tree, tree));
-extern void finish_eh_cleanup PARAMS ((tree));
-extern void finish_named_return_value PARAMS ((tree, tree));
-extern void expand_body PARAMS ((tree));
-extern tree nullify_returns_r PARAMS ((tree *, int *, void *));
-extern void do_pushlevel PARAMS ((void));
-extern tree do_poplevel PARAMS ((void));
-extern void begin_mem_initializers (void);
-extern void finish_mem_initializers PARAMS ((tree));
-extern void setup_vtbl_ptr PARAMS ((tree, tree));
-extern void clear_out_block PARAMS ((void));
-extern tree begin_global_stmt_expr PARAMS ((void));
-extern tree finish_global_stmt_expr PARAMS ((tree));
+extern void finish_translation_unit (void);
+extern tree finish_template_type_parm (tree, tree);
+extern tree finish_template_template_parm (tree, tree);
+extern tree finish_parmlist (tree, int);
+extern tree begin_class_definition (tree);
+extern void finish_default_args (void);
+extern tree finish_member_class_template (tree);
+extern void finish_template_decl (tree);
+extern tree finish_template_type (tree, tree, int);
+extern tree finish_base_specifier (tree, tree, bool);
+extern void finish_member_declaration (tree);
+extern void check_multiple_declarators (void);
+extern void qualified_name_lookup_error (tree, tree);
+extern tree finish_id_expression (tree, tree, tree,
+ cp_id_kind *, tree *,
+ bool, bool, bool *,
+ const char **);
+extern tree finish_typeof (tree);
+extern void finish_decl_cleanup (tree, tree);
+extern void finish_eh_cleanup (tree);
+extern void expand_body (tree);
+extern void cxx_expand_function_start (void);
+extern tree nullify_returns_r (tree *, int *, void *);
+extern void do_pushlevel (scope_kind);
+extern tree do_poplevel (void);
+extern void finish_mem_initializers (tree);
+extern void setup_vtbl_ptr (tree, tree);
+extern void clear_out_block (void);
extern tree check_template_template_default_arg (tree);
-
-/* in spew.c */
-extern void init_spew PARAMS ((void));
-extern int peekyylex PARAMS ((void));
-extern tree arbitrate_lookup PARAMS ((tree, tree, tree));
-extern tree frob_opname PARAMS ((tree));
-extern void maybe_snarf_defarg PARAMS ((void));
-extern void add_defarg_fn PARAMS ((tree));
-extern void do_pending_defargs PARAMS ((void));
-extern void done_pending_defargs PARAMS ((void));
-extern void unprocessed_defarg_fn PARAMS ((tree));
-extern void replace_defarg PARAMS ((tree, tree));
-extern void end_input PARAMS ((void));
+extern void expand_or_defer_fn (tree);
+extern void check_accessibility_of_qualified_id (tree, tree, tree);
+extern tree finish_qualified_id_expr (tree, tree, bool, bool);
+extern void simplify_aggr_init_expr (tree *);
/* in tree.c */
-extern void lang_check_failed PARAMS ((const char *, int,
- const char *));
-extern tree stabilize_expr PARAMS ((tree, tree *));
-extern tree cxx_unsave_expr_now PARAMS ((tree));
-extern tree cxx_maybe_build_cleanup PARAMS ((tree));
-extern void init_tree PARAMS ((void));
-extern int pod_type_p PARAMS ((tree));
-extern int zero_init_p PARAMS ((tree));
-extern tree canonical_type_variant PARAMS ((tree));
-extern void unshare_base_binfos PARAMS ((tree));
-extern int member_p PARAMS ((tree));
-extern cp_lvalue_kind real_lvalue_p PARAMS ((tree));
-extern cp_lvalue_kind real_non_cast_lvalue_p (tree);
-extern int non_cast_lvalue_p PARAMS ((tree));
-extern int non_cast_lvalue_or_else PARAMS ((tree, const char *));
-extern tree build_min PARAMS ((enum tree_code, tree,
- ...));
-extern tree build_min_nt PARAMS ((enum tree_code, ...));
-extern tree build_cplus_new PARAMS ((tree, tree));
-extern tree get_target_expr PARAMS ((tree));
-extern tree build_cplus_method_type PARAMS ((tree, tree, tree));
-extern tree build_cplus_staticfn_type PARAMS ((tree, tree, tree));
-extern tree build_cplus_array_type PARAMS ((tree, tree));
-extern tree hash_tree_cons PARAMS ((tree, tree, tree));
-extern tree hash_tree_chain PARAMS ((tree, tree));
-extern tree hash_chainon PARAMS ((tree, tree));
-extern tree make_binfo PARAMS ((tree, tree, tree, tree));
-extern tree reverse_path PARAMS ((tree));
-extern int count_functions PARAMS ((tree));
-extern int is_overloaded_fn PARAMS ((tree));
-extern tree get_overloaded_fn PARAMS ((tree));
-extern tree get_first_fn PARAMS ((tree));
-extern int bound_pmf_p PARAMS ((tree));
-extern tree ovl_cons PARAMS ((tree, tree));
-extern tree build_overload PARAMS ((tree, tree));
-extern tree function_arg_chain PARAMS ((tree));
-extern int promotes_to_aggr_type PARAMS ((tree, enum tree_code));
-extern int is_aggr_type_2 PARAMS ((tree, tree));
-extern const char *cxx_printable_name PARAMS ((tree, int));
-extern tree build_exception_variant PARAMS ((tree, tree));
-extern tree bind_template_template_parm PARAMS ((tree, tree));
-extern tree array_type_nelts_total PARAMS ((tree));
-extern tree array_type_nelts_top PARAMS ((tree));
-extern tree break_out_target_exprs PARAMS ((tree));
-extern tree get_type_decl PARAMS ((tree));
-extern tree vec_binfo_member PARAMS ((tree, tree));
-extern tree decl_namespace_context PARAMS ((tree));
-extern tree lvalue_type PARAMS ((tree));
-extern tree error_type PARAMS ((tree));
-extern tree build_zc_wrapper PARAMS ((struct z_candidate *));
-extern tree build_srcloc_here PARAMS ((void));
-extern int varargs_function_p PARAMS ((tree));
-extern int really_overloaded_fn PARAMS ((tree));
-extern int cp_tree_equal PARAMS ((tree, tree));
-extern tree no_linkage_check PARAMS ((tree));
-extern void debug_binfo PARAMS ((tree));
-extern tree build_dummy_object PARAMS ((tree));
-extern tree maybe_dummy_object PARAMS ((tree, tree *));
-extern int is_dummy_object PARAMS ((tree));
+extern void lang_check_failed (const char *, int,
+ const char *);
+extern tree stabilize_expr (tree, tree *);
+extern void stabilize_call (tree, tree *);
+extern bool stabilize_init (tree, tree *);
+extern tree cxx_unsave_expr_now (tree);
+extern tree cxx_maybe_build_cleanup (tree);
+extern void init_tree (void);
+extern int pod_type_p (tree);
+extern int zero_init_p (tree);
+extern tree canonical_type_variant (tree);
+extern tree copy_base_binfos (tree, tree, tree);
+extern int member_p (tree);
+extern cp_lvalue_kind real_lvalue_p (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_cplus_new (tree, tree);
+extern tree get_target_expr (tree);
+extern tree build_cplus_staticfn_type (tree, tree, tree);
+extern tree build_cplus_array_type (tree, tree);
+extern tree hash_tree_cons (tree, tree, tree);
+extern tree hash_tree_chain (tree, tree);
+extern tree hash_chainon (tree, tree);
+extern tree make_binfo (tree, tree, tree, tree);
+extern int count_functions (tree);
+extern int is_overloaded_fn (tree);
+extern tree get_first_fn (tree);
+extern int bound_pmf_p (tree);
+extern tree ovl_cons (tree, tree);
+extern tree build_overload (tree, tree);
+extern tree function_arg_chain (tree);
+extern int promotes_to_aggr_type (tree, enum tree_code);
+extern const char *cxx_printable_name (tree, int);
+extern tree build_exception_variant (tree, tree);
+extern tree bind_template_template_parm (tree, tree);
+extern tree array_type_nelts_total (tree);
+extern tree array_type_nelts_top (tree);
+extern tree break_out_target_exprs (tree);
+extern tree get_type_decl (tree);
+extern tree vec_binfo_member (tree, tree);
+extern tree decl_namespace_context (tree);
+extern tree lvalue_type (tree);
+extern tree error_type (tree);
+extern tree build_zc_wrapper (struct z_candidate *);
+extern int varargs_function_p (tree);
+extern int really_overloaded_fn (tree);
+extern bool cp_tree_equal (tree, tree);
+extern tree no_linkage_check (tree);
+extern void debug_binfo (tree);
+extern tree build_dummy_object (tree);
+extern tree maybe_dummy_object (tree, tree *);
+extern int is_dummy_object (tree);
extern const struct attribute_spec cxx_attribute_table[];
-extern tree make_ptrmem_cst PARAMS ((tree, tree));
-extern tree cp_build_qualified_type_real PARAMS ((tree, int, tsubst_flags_t));
+extern tree make_ptrmem_cst (tree, tree);
+extern tree cp_build_type_attribute_variant (tree, tree);
+extern tree cp_build_qualified_type_real (tree, int, tsubst_flags_t);
#define cp_build_qualified_type(TYPE, QUALS) \
cp_build_qualified_type_real ((TYPE), (QUALS), tf_error | tf_warning)
-extern tree build_shared_int_cst PARAMS ((int));
-extern special_function_kind special_function_p PARAMS ((tree));
+extern tree build_shared_int_cst (int);
+extern special_function_kind special_function_p (tree);
extern bool name_p (tree);
-extern int count_trees PARAMS ((tree));
-extern int char_type_p PARAMS ((tree));
-extern void verify_stmt_tree PARAMS ((tree));
-extern tree find_tree PARAMS ((tree, tree));
-extern linkage_kind decl_linkage PARAMS ((tree));
-extern tree cp_walk_subtrees PARAMS ((tree*, int*, walk_tree_fn,
- void*, void*));
-extern int cp_cannot_inline_tree_fn PARAMS ((tree*));
-extern tree cp_add_pending_fn_decls PARAMS ((void*,tree));
-extern int cp_is_overload_p PARAMS ((tree));
-extern int cp_auto_var_in_fn_p PARAMS ((tree,tree));
-extern tree cp_copy_res_decl_for_inlining PARAMS ((tree, tree, tree, void*,
- int*, void*));
-extern int cp_start_inlining PARAMS ((tree));
-extern void cp_end_inlining PARAMS ((tree));
+extern int count_trees (tree);
+extern int char_type_p (tree);
+extern void verify_stmt_tree (tree);
+extern tree find_tree (tree, tree);
+extern linkage_kind decl_linkage (tree);
+extern tree cp_walk_subtrees (tree*, int*, walk_tree_fn,
+ void*, void*);
+extern int cp_cannot_inline_tree_fn (tree*);
+extern tree cp_add_pending_fn_decls (void*,tree);
+extern int cp_is_overload_p (tree);
+extern int cp_auto_var_in_fn_p (tree,tree);
+extern tree cp_copy_res_decl_for_inlining (tree, tree, tree, void*,
+ int*, tree);
/* in typeck.c */
-extern int string_conv_p PARAMS ((tree, tree, int));
-extern tree cp_truthvalue_conversion PARAMS ((tree));
-extern tree condition_conversion PARAMS ((tree));
-extern tree target_type PARAMS ((tree));
-extern tree require_complete_type PARAMS ((tree));
-extern tree complete_type PARAMS ((tree));
-extern tree complete_type_or_diagnostic PARAMS ((tree, tree, int));
+extern int string_conv_p (tree, tree, int);
+extern tree cp_truthvalue_conversion (tree);
+extern tree condition_conversion (tree);
+extern tree target_type (tree);
+extern tree require_complete_type (tree);
+extern tree complete_type (tree);
+extern tree complete_type_or_diagnostic (tree, tree, int);
#define complete_type_or_else(T,V) (complete_type_or_diagnostic ((T), (V), 0))
-extern int type_unknown_p PARAMS ((tree));
-extern tree commonparms PARAMS ((tree, tree));
-extern tree original_type PARAMS ((tree));
-extern int comp_except_specs PARAMS ((tree, tree, int));
-extern int comptypes PARAMS ((tree, tree, int));
-extern int comp_target_types PARAMS ((tree, tree, int));
-extern int compparms PARAMS ((tree, tree));
-extern int comp_cv_qualification PARAMS ((tree, tree));
-extern int comp_cv_qual_signature PARAMS ((tree, tree));
-extern tree expr_sizeof PARAMS ((tree));
-extern tree cxx_sizeof_or_alignof_type PARAMS ((tree, enum tree_code, int));
+extern int type_unknown_p (tree);
+extern tree commonparms (tree, tree);
+extern tree original_type (tree);
+extern bool comp_except_specs (tree, tree, bool);
+extern bool comptypes (tree, tree, int);
+extern bool compparms (tree, tree);
+extern int comp_cv_qualification (tree, tree);
+extern int comp_cv_qual_signature (tree, tree);
+extern tree cxx_sizeof_or_alignof_expr (tree, enum tree_code);
+extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, bool);
#define cxx_sizeof_nowarn(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, false)
-extern tree inline_conversion PARAMS ((tree));
-extern tree decay_conversion PARAMS ((tree));
+extern tree inline_conversion (tree);
+extern tree decay_conversion (tree);
+extern tree perform_integral_promotions (tree);
extern tree build_class_member_access_expr (tree, tree, tree, bool);
extern tree finish_class_member_access_expr (tree, tree);
-extern tree build_x_indirect_ref PARAMS ((tree, const char *));
-extern tree build_indirect_ref PARAMS ((tree, const char *));
-extern tree build_array_ref PARAMS ((tree, tree));
-extern tree get_member_function_from_ptrfunc PARAMS ((tree *, tree));
-extern tree build_function_call_real PARAMS ((tree, tree, int));
-extern tree build_function_call_maybe PARAMS ((tree, tree));
-extern tree convert_arguments PARAMS ((tree, tree, tree, int));
-extern tree build_x_binary_op PARAMS ((enum tree_code, tree, tree));
-extern tree build_x_unary_op PARAMS ((enum tree_code, tree));
-extern tree unary_complex_lvalue PARAMS ((enum tree_code, tree));
-extern tree build_x_conditional_expr PARAMS ((tree, tree, tree));
-extern tree build_x_compound_expr PARAMS ((tree));
-extern tree build_compound_expr PARAMS ((tree));
-extern tree build_static_cast PARAMS ((tree, tree));
-extern tree build_reinterpret_cast PARAMS ((tree, tree));
-extern tree build_const_cast PARAMS ((tree, tree));
-extern tree build_c_cast PARAMS ((tree, tree));
-extern tree build_x_modify_expr PARAMS ((tree, enum tree_code, tree));
-extern tree build_modify_expr PARAMS ((tree, enum tree_code, tree));
-extern tree dubious_conversion_warnings PARAMS ((tree, tree, const char *, tree, int));
-extern tree convert_for_initialization PARAMS ((tree, tree, tree, int, const char *, tree, int));
-extern int comp_ptr_ttypes PARAMS ((tree, tree));
-extern int ptr_reasonably_similar PARAMS ((tree, tree));
-extern tree build_ptrmemfunc PARAMS ((tree, tree, int));
-extern int cp_type_quals PARAMS ((tree));
-extern int cp_has_mutable_p PARAMS ((tree));
-extern int at_least_as_qualified_p PARAMS ((tree, tree));
-extern int more_qualified_p PARAMS ((tree, tree));
-extern tree build_ptrmemfunc1 PARAMS ((tree, tree, tree));
-extern void expand_ptrmemfunc_cst PARAMS ((tree, tree *, tree *));
-extern tree pfn_from_ptrmemfunc PARAMS ((tree));
-extern tree type_after_usual_arithmetic_conversions PARAMS ((tree, tree));
-extern tree composite_pointer_type PARAMS ((tree, tree, tree, tree,
- const char*));
-extern tree merge_types PARAMS ((tree, tree));
-extern tree check_return_expr PARAMS ((tree));
+extern tree build_x_indirect_ref (tree, const char *);
+extern tree build_indirect_ref (tree, const char *);
+extern tree build_array_ref (tree, tree);
+extern tree get_member_function_from_ptrfunc (tree *, tree);
+extern tree convert_arguments (tree, tree, tree, int);
+extern tree build_x_binary_op (enum tree_code, tree, tree,
+ bool *);
+extern tree build_x_unary_op (enum tree_code, tree);
+extern tree unary_complex_lvalue (enum tree_code, tree);
+extern tree build_x_conditional_expr (tree, tree, tree);
+extern tree build_x_compound_expr_from_list (tree, const char *);
+extern tree build_x_compound_expr (tree, tree);
+extern tree build_compound_expr (tree, tree);
+extern tree build_static_cast (tree, tree);
+extern tree build_reinterpret_cast (tree, tree);
+extern tree build_const_cast (tree, tree);
+extern tree build_c_cast (tree, tree);
+extern tree build_x_modify_expr (tree, enum tree_code, tree);
+extern tree build_modify_expr (tree, enum tree_code, tree);
+extern tree dubious_conversion_warnings (tree, tree, const char *, tree, int);
+extern tree convert_for_initialization (tree, tree, tree, int, const char *, tree, int);
+extern int comp_ptr_ttypes (tree, tree);
+extern int ptr_reasonably_similar (tree, tree);
+extern tree build_ptrmemfunc (tree, tree, int);
+extern int cp_type_quals (tree);
+extern bool cp_has_mutable_p (tree);
+extern bool at_least_as_qualified_p (tree, tree);
+extern bool more_qualified_p (tree, tree);
+extern tree build_ptrmemfunc1 (tree, tree, tree);
+extern void expand_ptrmemfunc_cst (tree, tree *, tree *);
+extern tree pfn_from_ptrmemfunc (tree);
+extern tree type_after_usual_arithmetic_conversions (tree, tree);
+extern tree composite_pointer_type (tree, tree, tree, tree,
+ const char*);
+extern tree merge_types (tree, tree);
+extern tree check_return_expr (tree);
#define cp_build_binary_op(code, arg1, arg2) \
build_binary_op(code, arg1, arg2, 1)
#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true)
@@ -4448,47 +4247,63 @@ extern tree check_return_expr PARAMS ((tree));
extern tree build_ptrmemfunc_access_expr (tree, tree);
extern tree build_address (tree);
extern tree build_nop (tree, tree);
+extern tree non_reference (tree);
+extern tree lookup_anon_field (tree, tree);
+extern bool invalid_nonstatic_memfn_p (tree);
/* in typeck2.c */
-extern void require_complete_eh_spec_types PARAMS ((tree, tree));
-extern void cxx_incomplete_type_diagnostic PARAMS ((tree, tree, int));
+extern void require_complete_eh_spec_types (tree, tree);
+extern void cxx_incomplete_type_diagnostic (tree, tree, int);
#undef cxx_incomplete_type_error
-extern void cxx_incomplete_type_error PARAMS ((tree, tree));
+extern void cxx_incomplete_type_error (tree, tree);
#define cxx_incomplete_type_error(V,T) \
(cxx_incomplete_type_diagnostic ((V), (T), 0))
-extern tree error_not_base_type PARAMS ((tree, tree));
-extern tree binfo_or_else PARAMS ((tree, tree));
-extern void readonly_error PARAMS ((tree, const char *, int));
-extern int abstract_virtuals_error PARAMS ((tree, tree));
-
-extern tree store_init_value PARAMS ((tree, tree));
-extern tree digest_init PARAMS ((tree, tree, tree *));
-extern tree build_scoped_ref PARAMS ((tree, tree, tree *));
-extern tree build_x_arrow PARAMS ((tree));
-extern tree build_m_component_ref PARAMS ((tree, tree));
-extern tree build_functional_cast PARAMS ((tree, tree));
-extern void check_for_new_type PARAMS ((const char *, flagged_type_tree));
-extern tree add_exception_specifier PARAMS ((tree, tree, int));
-extern tree merge_exception_specifiers PARAMS ((tree, tree));
+extern tree error_not_base_type (tree, tree);
+extern tree binfo_or_else (tree, tree);
+extern void readonly_error (tree, const char *, int);
+extern int abstract_virtuals_error (tree, tree);
+
+extern tree store_init_value (tree, tree);
+extern tree digest_init (tree, tree, tree *);
+extern tree build_scoped_ref (tree, tree, tree *);
+extern tree build_x_arrow (tree);
+extern tree build_m_component_ref (tree, tree);
+extern tree build_functional_cast (tree, tree);
+extern tree add_exception_specifier (tree, tree, int);
+extern tree merge_exception_specifiers (tree, tree);
/* in mangle.c */
-extern void init_mangle PARAMS ((void));
-extern void mangle_decl PARAMS ((tree));
-extern const char *mangle_type_string PARAMS ((tree));
-extern tree mangle_type PARAMS ((tree));
-extern tree mangle_typeinfo_for_type PARAMS ((tree));
-extern tree mangle_typeinfo_string_for_type PARAMS ((tree));
-extern tree mangle_vtbl_for_type PARAMS ((tree));
-extern tree mangle_vtt_for_type PARAMS ((tree));
-extern tree mangle_ctor_vtbl_for_type PARAMS ((tree, tree));
-extern tree mangle_thunk PARAMS ((tree, tree, tree));
-extern tree mangle_conv_op_name_for_type PARAMS ((tree));
-extern tree mangle_guard_variable PARAMS ((tree));
-extern tree mangle_ref_init_variable PARAMS ((tree));
+extern void init_mangle (void);
+extern void mangle_decl (tree);
+extern const char *mangle_type_string (tree);
+extern tree mangle_type (tree);
+extern tree mangle_typeinfo_for_type (tree);
+extern tree mangle_typeinfo_string_for_type (tree);
+extern tree mangle_vtbl_for_type (tree);
+extern tree mangle_vtt_for_type (tree);
+extern tree mangle_ctor_vtbl_for_type (tree, tree);
+extern tree mangle_thunk (tree, int, tree, tree);
+extern tree mangle_conv_op_name_for_type (tree);
+extern tree mangle_guard_variable (tree);
+extern tree mangle_ref_init_variable (tree);
/* in dump.c */
-extern int cp_dump_tree PARAMS ((void *, tree));
+extern bool cp_dump_tree (void *, tree);
/* -- end of C++ */
+/* In order for the format checking to accept the C++ frontend
+ diagnostic framework extensions, you must include this file before
+ toplev.h, not after. */
+#define GCC_DIAG_STYLE __gcc_cxxdiag__
+#if GCC_VERSION >= 3004
+#define ATTRIBUTE_GCC_CXXDIAG(m, n) __attribute__ ((__format__ (GCC_DIAG_STYLE, m, n))) ATTRIBUTE_NONNULL(m)
+#else
+#define ATTRIBUTE_GCC_CXXDIAG(m, n) ATTRIBUTE_NONNULL(m)
+#endif
+
+extern void cp_error_at (const char *, ...) ATTRIBUTE_GCC_CXXDIAG(1, 2);
+extern void cp_warning_at (const char *, ...) ATTRIBUTE_GCC_CXXDIAG(1, 2);
+extern void cp_pedwarn_at (const char *, ...) ATTRIBUTE_GCC_CXXDIAG(1, 2);
+
#endif /* ! GCC_CP_TREE_H */
diff --git a/contrib/gcc/cp/cvt.c b/contrib/gcc/cp/cvt.c
index 75a6a3a689d2..48be5c519096 100644
--- a/contrib/gcc/cp/cvt.c
+++ b/contrib/gcc/cp/cvt.c
@@ -1,33 +1,35 @@
/* Language-level data type conversion for GNU C++.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* This file contains the functions for converting C expressions
+/* This file contains the functions for converting C++ expressions
to different data types. The only entry point is `convert'.
Every language front end must have a `convert' function
but what kind of conversions it does will depend on the language. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "cp-tree.h"
@@ -35,10 +37,10 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "decl.h"
-static tree cp_convert_to_pointer PARAMS ((tree, tree, int));
-static tree convert_to_pointer_force PARAMS ((tree, tree));
-static tree build_up_reference PARAMS ((tree, tree, int, tree));
-static void warn_ref_binding PARAMS ((tree, tree, tree));
+static tree cp_convert_to_pointer (tree, tree, bool);
+static tree convert_to_pointer_force (tree, tree);
+static tree build_up_reference (tree, tree, int, tree);
+static void warn_ref_binding (tree, tree, tree);
/* Change of width--truncation and extension of integers or reals--
is represented with NOP_EXPR. Proper functioning of many things
@@ -72,12 +74,10 @@ static void warn_ref_binding PARAMS ((tree, tree, tree));
but not static_cast). */
static tree
-cp_convert_to_pointer (type, expr, force)
- tree type, expr;
- int force;
+cp_convert_to_pointer (tree type, tree expr, bool force)
{
- register tree intype = TREE_TYPE (expr);
- register enum tree_code form;
+ tree intype = TREE_TYPE (expr);
+ enum tree_code form;
tree rval;
if (IS_AGGR_TYPE (intype))
@@ -109,24 +109,26 @@ cp_convert_to_pointer (type, expr, force)
functions. */
if (TYPE_PTRMEMFUNC_P (intype))
{
- tree fntype = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (intype));
- tree decl = maybe_dummy_object (TYPE_METHOD_BASETYPE (fntype), 0);
- expr = build (OFFSET_REF, fntype, decl, expr);
+ if (pedantic || warn_pmf2ptr)
+ pedwarn ("converting from `%T' to `%T'", intype, type);
+ if (TREE_CODE (expr) == PTRMEM_CST)
+ expr = build_address (PTRMEM_CST_MEMBER (expr));
+ else
+ {
+ tree decl = maybe_dummy_object (TYPE_PTRMEM_CLASS_TYPE (intype),
+ 0);
+ decl = build_address (decl);
+ expr = get_member_function_from_ptrfunc (&decl, expr);
+ }
}
-
- if (TREE_CODE (expr) == OFFSET_REF
- && TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
- expr = resolve_offset_ref (expr);
- if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
- expr = build_addr_func (expr);
- if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
+ else if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
{
- if (TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == METHOD_TYPE)
- if (pedantic || warn_pmf2ptr)
- pedwarn ("converting from `%T' to `%T'", TREE_TYPE (expr),
- type);
- return build1 (NOP_EXPR, type, expr);
+ if (pedantic || warn_pmf2ptr)
+ pedwarn ("converting from `%T' to `%T'", intype, type);
+ expr = build_addr_func (expr);
}
+ if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
+ return build_nop (type, expr);
intype = TREE_TYPE (expr);
}
@@ -178,68 +180,81 @@ cp_convert_to_pointer (type, expr, force)
}
}
- if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
+ if (TYPE_PTRMEMFUNC_P (type))
{
- tree b1;
- tree b2;
- tree binfo;
- enum tree_code code = PLUS_EXPR;
- base_kind bk;
+ error ("cannot convert `%E' from type `%T' to type `%T'",
+ expr, intype, type);
+ return error_mark_node;
+ }
- b1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (type));
- b2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (intype));
- binfo = lookup_base (b1, b2, ba_check, &bk);
- if (!binfo)
- {
- binfo = lookup_base (b2, b1, ba_check, &bk);
- code = MINUS_EXPR;
- }
- if (binfo == error_mark_node)
- return error_mark_node;
+ return build_nop (type, expr);
+ }
+ else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
+ {
+ tree b1;
+ tree b2;
+ tree binfo;
+ enum tree_code code = PLUS_EXPR;
+ base_kind bk;
+
+ b1 = TYPE_PTRMEM_CLASS_TYPE (type);
+ b2 = TYPE_PTRMEM_CLASS_TYPE (intype);
+ binfo = lookup_base (b1, b2, ba_check, &bk);
+ if (!binfo)
+ {
+ binfo = lookup_base (b2, b1, ba_check, &bk);
+ code = MINUS_EXPR;
+ }
+ if (binfo == error_mark_node)
+ return error_mark_node;
- if (bk == bk_via_virtual)
+ if (bk == bk_via_virtual)
+ {
+ if (force)
+ warning ("pointer to member cast from `%T' to `%T' is via virtual base",
+ intype, type);
+ else
{
- if (force)
- warning ("pointer to member cast from `%T' to `%T' is via virtual base",
- TREE_TYPE (intype), TREE_TYPE (type));
- else
- {
- error ("pointer to member cast from `%T' to `%T' is via virtual base",
- TREE_TYPE (intype), TREE_TYPE (type));
- return error_mark_node;
- }
- /* This is a reinterpret cast, whose result is unspecified.
- We choose to do nothing. */
- return build1 (NOP_EXPR, type, expr);
+ error ("pointer to member cast from `%T' to `%T' is via virtual base",
+ intype, type);
+ return error_mark_node;
}
-
- if (TREE_CODE (expr) == PTRMEM_CST)
- expr = cplus_expand_constant (expr);
-
- if (binfo)
- expr = size_binop (code, convert (sizetype, expr),
- BINFO_OFFSET (binfo));
- }
- else if (TYPE_PTRMEMFUNC_P (type))
- {
- error ("cannot convert `%E' from type `%T' to type `%T'",
- expr, intype, type);
- return error_mark_node;
+ /* This is a reinterpret cast, whose result is unspecified.
+ We choose to do nothing. */
+ return build1 (NOP_EXPR, type, expr);
}
+ if (TREE_CODE (expr) == PTRMEM_CST)
+ expr = cplus_expand_constant (expr);
+
+ if (binfo && !integer_zerop (BINFO_OFFSET (binfo)))
+ expr = size_binop (code,
+ build_nop (sizetype, expr),
+ BINFO_OFFSET (binfo));
return build_nop (type, expr);
}
else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))
return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0);
else if (TYPE_PTRMEMFUNC_P (intype))
{
+ if (!warn_pmf2ptr)
+ {
+ if (TREE_CODE (expr) == PTRMEM_CST)
+ return cp_convert_to_pointer (type,
+ PTRMEM_CST_MEMBER (expr),
+ force);
+ else if (TREE_CODE (expr) == OFFSET_REF)
+ {
+ tree object = TREE_OPERAND (expr, 0);
+ return get_member_function_from_ptrfunc (&object,
+ TREE_OPERAND (expr, 1));
+ }
+ }
error ("cannot convert `%E' from type `%T' to type `%T'",
expr, intype, type);
return error_mark_node;
}
- my_friendly_assert (form != OFFSET_TYPE, 186);
-
if (integer_zerop (expr))
{
if (TYPE_PTRMEMFUNC_P (type))
@@ -256,8 +271,7 @@ cp_convert_to_pointer (type, expr, force)
force_fit_type (expr, 0);
return expr;
}
- else if ((TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type))
- && INTEGRAL_CODE_P (form))
+ else if (TYPE_PTR_TO_MEMBER_P (type) && INTEGRAL_CODE_P (form))
{
error ("invalid conversion from '%T' to '%T'", intype, type);
return error_mark_node;
@@ -290,11 +304,10 @@ cp_convert_to_pointer (type, expr, force)
(such as conversion from sub-type to private super-type). */
static tree
-convert_to_pointer_force (type, expr)
- tree type, expr;
+convert_to_pointer_force (tree type, tree expr)
{
- register tree intype = TREE_TYPE (expr);
- register enum tree_code form = TREE_CODE (intype);
+ tree intype = TREE_TYPE (expr);
+ enum tree_code form = TREE_CODE (intype);
if (form == POINTER_TYPE)
{
@@ -333,7 +346,7 @@ convert_to_pointer_force (type, expr)
}
}
- return cp_convert_to_pointer (type, expr, 1);
+ return cp_convert_to_pointer (type, expr, true);
}
/* We are passing something to a function which requires a reference.
@@ -345,9 +358,7 @@ convert_to_pointer_force (type, expr)
If DIRECT_BIND is set, DECL is the reference we're binding to. */
static tree
-build_up_reference (type, arg, flags, decl)
- tree type, arg, decl;
- int flags;
+build_up_reference (tree type, tree arg, int flags, tree decl)
{
tree rval;
tree argtype = TREE_TYPE (arg);
@@ -406,8 +417,7 @@ build_up_reference (type, arg, flags, decl)
non-volatile const type. */
static void
-warn_ref_binding (reftype, intype, decl)
- tree reftype, intype, decl;
+warn_ref_binding (tree reftype, tree intype, tree decl)
{
tree ttl = TREE_TYPE (reftype);
@@ -436,41 +446,35 @@ warn_ref_binding (reftype, intype, decl)
we know it's an initialization. */
tree
-convert_to_reference (reftype, expr, convtype, flags, decl)
- tree reftype, expr;
- int convtype, flags;
- tree decl;
+convert_to_reference (tree reftype, tree expr, int convtype,
+ int flags, tree decl)
{
- register tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype));
- register tree intype;
+ tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype));
+ tree intype;
tree rval = NULL_TREE;
tree rval_as_conversion = NULL_TREE;
- int i;
+ bool can_convert_intype_to_type;
if (TREE_CODE (type) == FUNCTION_TYPE
&& TREE_TYPE (expr) == unknown_type_node)
- {
- expr = instantiate_type (type, expr,
- (flags & LOOKUP_COMPLAIN)
- ? tf_error | tf_warning : tf_none);
- if (expr == error_mark_node)
- return error_mark_node;
-
- intype = TREE_TYPE (expr);
- }
+ expr = instantiate_type (type, expr,
+ (flags & LOOKUP_COMPLAIN)
+ ? tf_error | tf_warning : tf_none);
else
- {
- expr = convert_from_reference (expr);
- intype = TREE_TYPE (expr);
- }
+ expr = convert_from_reference (expr);
+
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ intype = TREE_TYPE (expr);
my_friendly_assert (TREE_CODE (intype) != REFERENCE_TYPE, 364);
intype = TYPE_MAIN_VARIANT (intype);
- i = comp_target_types (type, intype, 0);
-
- if (i <= 0 && (convtype & CONV_IMPLICIT) && IS_AGGR_TYPE (intype)
+ can_convert_intype_to_type = can_convert (type, intype);
+ if (!can_convert_intype_to_type
+ && (convtype & CONV_IMPLICIT) && IS_AGGR_TYPE (intype)
&& ! (flags & LOOKUP_NO_CONVERSION))
{
/* Look for a user-defined conversion to lvalue that we can use. */
@@ -484,12 +488,12 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
expr = rval_as_conversion;
rval_as_conversion = NULL_TREE;
intype = type;
- i = 1;
+ can_convert_intype_to_type = 1;
}
}
- if (((convtype & CONV_STATIC) && i == -1)
- || ((convtype & CONV_IMPLICIT) && i == 1))
+ if (((convtype & CONV_STATIC) && can_convert (intype, type))
+ || ((convtype & CONV_IMPLICIT) && can_convert_intype_to_type))
{
if (flags & LOOKUP_COMPLAIN)
{
@@ -517,10 +521,10 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
/* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they
meant. */
if (TREE_CODE (intype) == POINTER_TYPE
- && (comptypes (TREE_TYPE (intype), type,
- COMPARE_BASE | COMPARE_RELAXED )))
+ && (comptypes (TREE_TYPE (intype), type,
+ COMPARE_BASE | COMPARE_DERIVED)))
warning ("casting `%T' to `%T' does not dereference pointer",
- intype, reftype);
+ intype, reftype);
rval = build_unary_op (ADDR_EXPR, expr, 0);
if (rval != error_mark_node)
@@ -545,8 +549,6 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
return rval;
}
- my_friendly_assert (TREE_CODE (intype) != OFFSET_TYPE, 189);
-
if (flags & LOOKUP_COMPLAIN)
error ("cannot convert type `%T' to type `%T'", intype, reftype);
@@ -560,14 +562,9 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
way down to its lowest form. */
tree
-convert_from_reference (val)
- tree val;
+convert_from_reference (tree val)
{
- tree type = TREE_TYPE (val);
-
- if (TREE_CODE (type) == OFFSET_TYPE)
- type = TREE_TYPE (type);
- if (TREE_CODE (type) == REFERENCE_TYPE)
+ if (TREE_CODE (TREE_TYPE (val)) == REFERENCE_TYPE)
return build_indirect_ref (val, NULL);
return val;
}
@@ -576,8 +573,7 @@ convert_from_reference (val)
preserving cv-qualification. */
tree
-convert_lvalue (totype, expr)
- tree totype, expr;
+convert_lvalue (tree totype, tree expr)
{
totype = cp_build_qualified_type (totype, TYPE_QUALS (TREE_TYPE (expr)));
totype = build_reference_type (totype);
@@ -604,8 +600,7 @@ force_rvalue (tree expr)
/* C++ conversions, preference to static cast conversions. */
tree
-cp_convert (type, expr)
- tree type, expr;
+cp_convert (tree type, tree expr)
{
return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL);
}
@@ -615,15 +610,12 @@ cp_convert (type, expr)
FLAGS indicates how we should behave. */
tree
-ocp_convert (type, expr, convtype, flags)
- tree type, expr;
- int convtype, flags;
+ocp_convert (tree type, tree expr, int convtype, int flags)
{
- register tree e = expr;
- register enum tree_code code = TREE_CODE (type);
+ tree e = expr;
+ enum tree_code code = TREE_CODE (type);
- if (e == error_mark_node
- || TREE_TYPE (e) == error_mark_node)
+ if (error_operand_p (e) || type == error_mark_node)
return error_mark_node;
complete_type (type);
@@ -642,7 +634,7 @@ ocp_convert (type, expr, convtype, flags)
if (same_type_p (type, TREE_TYPE (e)))
/* The call to fold will not always remove the NOP_EXPR as
might be expected, since if one of the types is a typedef;
- the comparsion in fold is just equality of pointers, not a
+ the comparison in fold is just equality of pointers, not a
call to comptypes. We don't call fold in this case because
that can result in infinite recursion; fold will call
convert, which will call ocp_convert, etc. */
@@ -651,6 +643,20 @@ ocp_convert (type, expr, convtype, flags)
conversion. */
else if (TREE_CODE (type) == COMPLEX_TYPE)
return fold (convert_to_complex (type, e));
+ else if (TREE_CODE (e) == TARGET_EXPR)
+ {
+ /* Don't build a NOP_EXPR of class type. Instead, change the
+ type of the temporary. Only allow this for cv-qual changes,
+ though. */
+ if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (e)),
+ TYPE_MAIN_VARIANT (type)))
+ abort ();
+ TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
+ return e;
+ }
+ else if (TREE_ADDRESSABLE (type))
+ /* We shouldn't be treating objects of ADDRESSABLE type as rvalues. */
+ abort ();
else
return fold (build1 (NOP_EXPR, type, e));
}
@@ -661,16 +667,6 @@ ocp_convert (type, expr, convtype, flags)
return e;
}
- /* Just convert to the type of the member. */
- if (code == OFFSET_TYPE)
- {
- type = TREE_TYPE (type);
- code = TREE_CODE (type);
- }
-
- if (TREE_CODE (e) == OFFSET_REF)
- e = resolve_offset_ref (e);
-
if (INTEGRAL_CODE_P (code))
{
tree intype = TREE_TYPE (e);
@@ -698,25 +694,12 @@ ocp_convert (type, expr, convtype, flags)
return error_mark_node;
}
if (code == BOOLEAN_TYPE)
- {
- tree fn = NULL_TREE;
-
- /* Common Ada/Pascal programmer's mistake. We always warn
- about this since it is so bad. */
- if (TREE_CODE (expr) == FUNCTION_DECL)
- fn = expr;
- else if (TREE_CODE (expr) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (expr, 0)) == FUNCTION_DECL)
- fn = TREE_OPERAND (expr, 0);
- if (fn && !DECL_WEAK (fn))
- warning ("the address of `%D', will always be `true'", fn);
- return cp_truthvalue_conversion (e);
- }
+ return cp_truthvalue_conversion (e);
+
return fold (convert_to_integer (type, e));
}
- if (code == POINTER_TYPE || code == REFERENCE_TYPE
- || TYPE_PTRMEMFUNC_P (type))
- return fold (cp_convert_to_pointer (type, e, 0));
+ if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type))
+ return fold (cp_convert_to_pointer (type, e, false));
if (code == VECTOR_TYPE)
return fold (convert_to_vector (type, e));
if (code == REAL_TYPE || code == COMPLEX_TYPE)
@@ -787,7 +770,7 @@ ocp_convert (type, expr, convtype, flags)
no lvalue-rvalue and similar conversions happen [expr.static.cast/4,
stmt.expr/1, expr.comma/1]. This permits dereferencing an incomplete type
in a void context. The C++ standard does not define what an `access' to an
- object is, but there is reason to beleive that it is the lvalue to rvalue
+ object is, but there is reason to believe that it is the lvalue to rvalue
conversion -- if it were not, `*&*p = 1' would violate [expr]/4 in that it
accesses `*p' not to calculate the value to be stored. But, dcl.type.cv/8
indicates that volatile semantics should be the same between C and C++
@@ -801,15 +784,15 @@ ocp_convert (type, expr, convtype, flags)
IMPLICIT is tells us the context of an implicit void conversion. */
tree
-convert_to_void (expr, implicit)
- tree expr;
- const char *implicit;
+convert_to_void (tree expr, const char *implicit)
{
if (expr == error_mark_node
|| TREE_TYPE (expr) == error_mark_node)
return error_mark_node;
if (!TREE_TYPE (expr))
return expr;
+ if (invalid_nonstatic_memfn_p (expr))
+ return error_mark_node;
if (VOID_TYPE_P (TREE_TYPE (expr)))
return expr;
switch (TREE_CODE (expr))
@@ -819,8 +802,12 @@ convert_to_void (expr, implicit)
/* The two parts of a cond expr might be separate lvalues. */
tree op1 = TREE_OPERAND (expr,1);
tree op2 = TREE_OPERAND (expr,2);
- tree new_op1 = convert_to_void (op1, implicit);
- tree new_op2 = convert_to_void (op2, implicit);
+ tree new_op1 = convert_to_void
+ (op1, (implicit && !TREE_SIDE_EFFECTS (op2)
+ ? "second operand of conditional" : NULL));
+ tree new_op2 = convert_to_void
+ (op2, (implicit && !TREE_SIDE_EFFECTS (op1)
+ ? "third operand of conditional" : NULL));
expr = build (COND_EXPR, TREE_TYPE (new_op1),
TREE_OPERAND (expr, 0), new_op1, new_op2);
@@ -831,14 +818,14 @@ convert_to_void (expr, implicit)
{
/* The second part of a compound expr contains the value. */
tree op1 = TREE_OPERAND (expr,1);
- tree new_op1 = convert_to_void (op1, implicit);
+ tree new_op1 = convert_to_void
+ (op1, (implicit && !TREE_NO_UNUSED_WARNING (expr)
+ ? "right-hand operand of comma" : NULL));
if (new_op1 != op1)
{
tree t = build (COMPOUND_EXPR, TREE_TYPE (new_op1),
TREE_OPERAND (expr, 0), new_op1);
- TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (expr);
- TREE_NO_UNUSED_WARNING (t) = TREE_NO_UNUSED_WARNING (expr);
expr = t;
}
@@ -850,7 +837,7 @@ convert_to_void (expr, implicit)
/* These have already decayed to rvalue. */
break;
- case CALL_EXPR: /* we have a special meaning for volatile void fn() */
+ case CALL_EXPR: /* We have a special meaning for volatile void fn(). */
break;
case INDIRECT_REF:
@@ -886,10 +873,6 @@ convert_to_void (expr, implicit)
break;
}
- case OFFSET_REF:
- expr = resolve_offset_ref (expr);
- break;
-
default:;
}
{
@@ -903,6 +886,7 @@ convert_to_void (expr, implicit)
of an overloaded function, and this is not one of them. */
pedwarn ("%s cannot resolve address of overloaded function",
implicit ? implicit : "void cast");
+ expr = void_zero_node;
}
else if (implicit && probe == expr && is_overloaded_fn (probe))
/* Only warn when there is no &. */
@@ -912,13 +896,9 @@ convert_to_void (expr, implicit)
if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
{
- /* FIXME: This is where we should check for expressions with no
- effects. At the moment we do that in both build_x_component_expr
- and expand_expr_stmt -- inconsistently too. For the moment
- leave implicit void conversions unadorned so that expand_expr_stmt
- has a chance of detecting some of the cases. */
- if (!implicit)
- expr = build1 (CONVERT_EXPR, void_type_node, expr);
+ if (implicit && !TREE_SIDE_EFFECTS (expr) && warn_unused_value)
+ warning ("%s has no effect", implicit);
+ expr = build1 (CONVERT_EXPR, void_type_node, expr);
}
return expr;
}
@@ -941,8 +921,7 @@ convert_to_void (expr, implicit)
do a little bit more work. */
tree
-convert (type, expr)
- tree type, expr;
+convert (tree type, tree expr)
{
tree intype;
@@ -966,13 +945,10 @@ convert (type, expr)
(such as conversion from sub-type to private super-type). */
tree
-convert_force (type, expr, convtype)
- tree type;
- tree expr;
- int convtype;
+convert_force (tree type, tree expr, int convtype)
{
- register tree e = expr;
- register enum tree_code code = TREE_CODE (type);
+ tree e = expr;
+ enum tree_code code = TREE_CODE (type);
if (code == REFERENCE_TYPE)
return fold (convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN,
@@ -1010,8 +986,7 @@ convert_force (type, expr, convtype)
(jason 8/9/95) */
tree
-build_type_conversion (xtype, expr)
- tree xtype, expr;
+build_type_conversion (tree xtype, tree expr)
{
/* C++: check to see if we can convert this aggregate type
into the required type. */
@@ -1020,14 +995,11 @@ build_type_conversion (xtype, expr)
/* Convert the given EXPR to one of a group of types suitable for use in an
expression. DESIRES is a combination of various WANT_* flags (q.v.)
- which indicates which types are suitable. If COMPLAIN is 1, complain
+ which indicates which types are suitable. If COMPLAIN is true, complain
about ambiguity; otherwise, the caller will deal with it. */
tree
-build_expr_type_conversion (desires, expr, complain)
- int desires;
- tree expr;
- int complain;
+build_expr_type_conversion (int desires, tree expr, bool complain)
{
tree basetype = TREE_TYPE (expr);
tree conv = NULL_TREE;
@@ -1038,8 +1010,6 @@ build_expr_type_conversion (desires, expr, complain)
&& !(desires & WANT_NULL))
warning ("converting NULL to non-pointer type");
- if (TREE_CODE (expr) == OFFSET_REF)
- expr = resolve_offset_ref (expr);
expr = convert_from_reference (expr);
basetype = TREE_TYPE (expr);
@@ -1065,7 +1035,7 @@ build_expr_type_conversion (desires, expr, complain)
case FUNCTION_TYPE:
case ARRAY_TYPE:
- return (desires & WANT_POINTER) ? default_conversion (expr)
+ return (desires & WANT_POINTER) ? decay_conversion (expr)
: NULL_TREE;
default:
return NULL_TREE;
@@ -1073,8 +1043,9 @@ build_expr_type_conversion (desires, expr, complain)
/* The code for conversions from class type is currently only used for
delete expressions. Other expressions are handled by build_new_op. */
-
- if (! TYPE_HAS_CONVERSION (basetype))
+ if (!complete_type_or_else (basetype, expr))
+ return error_mark_node;
+ if (!TYPE_HAS_CONVERSION (basetype))
return NULL_TREE;
for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv))
@@ -1086,9 +1057,7 @@ build_expr_type_conversion (desires, expr, complain)
if (winner && winner == cand)
continue;
- candidate = TREE_TYPE (TREE_TYPE (cand));
- if (TREE_CODE (candidate) == REFERENCE_TYPE)
- candidate = TREE_TYPE (candidate);
+ candidate = non_reference (TREE_TYPE (TREE_TYPE (cand)));
switch (TREE_CODE (candidate))
{
@@ -1126,9 +1095,7 @@ build_expr_type_conversion (desires, expr, complain)
if (winner)
{
- tree type = TREE_TYPE (TREE_TYPE (winner));
- if (TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
+ tree type = non_reference (TREE_TYPE (TREE_TYPE (winner)));
return build_user_type_conversion (type, expr, LOOKUP_NORMAL);
}
@@ -1138,15 +1105,11 @@ build_expr_type_conversion (desires, expr, complain)
/* Implements integral promotion (4.1) and float->double promotion. */
tree
-type_promotes_to (type)
- tree type;
+type_promotes_to (tree type)
{
- int type_quals;
-
if (type == error_mark_node)
return error_mark_node;
- type_quals = cp_type_quals (type);
type = TYPE_MAIN_VARIANT (type);
/* bool always promotes to int (not unsigned), even if it's the same
@@ -1179,8 +1142,8 @@ type_promotes_to (type)
}
else if (type == float_type_node)
type = double_type_node;
-
- return cp_build_qualified_type (type, type_quals);
+
+ return type;
}
/* The routines below this point are carefully written to conform to
@@ -1193,14 +1156,22 @@ type_promotes_to (type)
the conversion was impossible. */
tree
-perform_qualification_conversions (type, expr)
- tree type;
- tree expr;
+perform_qualification_conversions (tree type, tree expr)
{
- if (TREE_CODE (type) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE
- && comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (expr))))
- return build1 (NOP_EXPR, type, expr);
+ tree expr_type;
+
+ expr_type = TREE_TYPE (expr);
+
+ if (TYPE_PTR_P (type) && TYPE_PTR_P (expr_type)
+ && comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (expr_type)))
+ return build_nop (type, expr);
+ else if (TYPE_PTR_TO_MEMBER_P (type)
+ && TYPE_PTR_TO_MEMBER_P (expr_type)
+ && same_type_p (TYPE_PTRMEM_CLASS_TYPE (type),
+ TYPE_PTRMEM_CLASS_TYPE (expr_type))
+ && comp_ptr_ttypes (TYPE_PTRMEM_POINTED_TO_TYPE (type),
+ TYPE_PTRMEM_POINTED_TO_TYPE (expr_type)))
+ return build_nop (type, expr);
else
return error_mark_node;
}
diff --git a/contrib/gcc/cp/cxx-pretty-print.c b/contrib/gcc/cp/cxx-pretty-print.c
new file mode 100644
index 000000000000..53c677ab88ae
--- /dev/null
+++ b/contrib/gcc/cp/cxx-pretty-print.c
@@ -0,0 +1,1737 @@
+/* Implementation of subroutines for the GNU C++ pretty-printer.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "real.h"
+#include "cxx-pretty-print.h"
+#include "cp-tree.h"
+#include "toplev.h"
+
+static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
+static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
+static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
+static void pp_cxx_assignment_expression (cxx_pretty_printer *, tree);
+static void pp_cxx_expression (cxx_pretty_printer *, tree);
+static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
+static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
+static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
+static void pp_cxx_type_id (cxx_pretty_printer *, tree);
+static void pp_cxx_direct_abstract_declarator (cxx_pretty_printer *, tree);
+static void pp_cxx_declarator (cxx_pretty_printer *, tree);
+static void pp_cxx_abstract_declarator (cxx_pretty_printer *, tree);
+static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
+
+#define pp_cxx_whitespace(PP) pp_c_whitespace (pp_c_base (PP))
+#define pp_cxx_left_paren(PP) pp_c_left_paren (pp_c_base (PP))
+#define pp_cxx_right_paren(PP) pp_c_right_paren (pp_c_base (PP))
+#define pp_cxx_left_brace(PP) pp_c_left_brace (pp_c_base (PP))
+#define pp_cxx_right_brace(PP) pp_c_right_brace (pp_c_base (PP))
+#define pp_cxx_dot(PP) pp_c_dot (pp_c_base (PP))
+#define pp_cxx_arrow(PP) pp_c_arrow (pp_c_base (PP))
+#define pp_cxx_semicolon(PP) pp_c_semicolon (pp_c_base (PP))
+
+static inline void
+pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
+{
+ const char *p = pp_last_position_in_text (pp);
+
+ if (p != NULL && *p == c)
+ pp_cxx_whitespace (pp);
+ pp_character (pp, c);
+ pp_base (pp)->padding = pp_none;
+}
+
+#define pp_cxx_begin_template_argument_list(PP) \
+ pp_cxx_nonconsecutive_character (PP, '<')
+#define pp_cxx_end_template_argument_list(PP) \
+ pp_cxx_nonconsecutive_character (PP, '>')
+
+#define pp_cxx_identifier(PP, ID) pp_c_identifier (pp_c_base (PP), ID)
+#define pp_cxx_tree_identifier(PP, T) pp_c_tree_identifier (pp_c_base (PP), T)
+
+#define pp_cxx_cv_qualifier_seq(PP, T) \
+ pp_c_type_qualifier_list (pp_c_base (PP), T)
+#define pp_cxx_storage_class_specifier(PP, T) \
+ pp_c_storage_class_specifier (pp_c_base (PP), T)
+#define pp_cxx_expression_list(PP, T) \
+ pp_c_expression_list (pp_c_base (PP), T)
+#define pp_cxx_space_for_pointer_operator(PP, T) \
+ pp_c_space_for_pointer_operator (pp_c_base (PP), T)
+#define pp_cxx_init_declarator(PP, T) \
+ pp_c_init_declarator (pp_c_base (PP), T)
+#define pp_cxx_call_argument_list(PP, T) \
+ pp_c_call_argument_list (pp_c_base (PP), T)
+
+static void
+pp_cxx_colon_colon (cxx_pretty_printer *pp)
+{
+ pp_colon_colon (pp);
+ pp_base (pp)->padding = pp_none;
+}
+
+
+/* Expressions. */
+
+static inline bool
+is_destructor_name (tree name)
+{
+ return name == complete_dtor_identifier
+ || name == base_dtor_identifier
+ || name == deleting_dtor_identifier;
+}
+
+/* conversion-function-id:
+ operator conversion-type-id
+
+ conversion-type-id:
+ type-specifier-seq conversion-declarator(opt)
+
+ conversion-declarator:
+ ptr-operator conversion-declarator(opt) */
+static inline void
+pp_cxx_conversion_function_id (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_identifier (pp, "operator");
+ pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
+}
+
+static inline void
+pp_cxx_template_id (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 0));
+ pp_cxx_begin_template_argument_list (pp);
+ pp_cxx_template_argument_list (pp, TREE_OPERAND (t, 1));
+ pp_cxx_end_template_argument_list (pp);
+}
+
+/* unqualified-id:
+ identifier
+ operator-function-id
+ conversion-function-id
+ ~ class-name
+ template-id */
+static void
+pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+ switch (code)
+ {
+ case RESULT_DECL:
+ pp_cxx_identifier (pp, "<return-value>");
+ break;
+
+ case OVERLOAD:
+ t = OVL_CURRENT (t);
+ case VAR_DECL:
+ case PARM_DECL:
+ case CONST_DECL:
+ case TYPE_DECL:
+ case FUNCTION_DECL:
+ case NAMESPACE_DECL:
+ case FIELD_DECL:
+ case LABEL_DECL:
+ case USING_DECL:
+ case TEMPLATE_DECL:
+ t = DECL_NAME (t);
+
+ case IDENTIFIER_NODE:
+ if (t == NULL)
+ pp_cxx_identifier (pp, "<anonymous>");
+ else if (IDENTIFIER_TYPENAME_P (t))
+ pp_cxx_conversion_function_id (pp, t);
+ else
+ {
+ if (is_destructor_name (t))
+ {
+ pp_complement (pp);
+ /* FIXME: Why is this necessary? */
+ if (TREE_TYPE (t))
+ t = constructor_name (TREE_TYPE (t));
+ }
+ pp_cxx_tree_identifier (pp, t);
+ }
+ break;
+
+ case TEMPLATE_ID_EXPR:
+ pp_cxx_template_id (pp, t);
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ pp_cxx_unqualified_id (pp, TYPE_NAME (t));
+ break;
+
+ case TEMPLATE_TYPE_PARM:
+ t = TYPE_FIELDS (t);
+ case TEMPLATE_PARM_INDEX:
+ pp_cxx_unqualified_id (pp, TEMPLATE_PARM_DECL (t));
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ break;
+ }
+}
+
+static inline void
+pp_cxx_template_keyword_if_needed (cxx_pretty_printer *pp, tree scope, tree t)
+{
+ if (TREE_CODE (t) == TEMPLATE_ID_EXPR
+ && TYPE_P (scope) && dependent_type_p (scope))
+ pp_cxx_identifier (pp, "template");
+}
+
+/* nested-name-specifier:
+ class-or-namespace-name :: nested-name-specifier(opt)
+ class-or-namespace-name :: template nested-name-specifier */
+static void
+pp_cxx_nested_name_specifier (cxx_pretty_printer *pp, tree t)
+{
+ if (t != NULL && t != pp->enclosing_scope)
+ {
+ tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
+ pp_cxx_nested_name_specifier (pp, scope);
+ pp_cxx_template_keyword_if_needed (pp, scope, t);
+ pp_cxx_unqualified_id (pp, t);
+ pp_cxx_colon_colon (pp);
+ }
+}
+
+/* qualified-id:
+ nested-name-specifier template(opt) unqualified-id */
+static void
+pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case PTRMEM_CST:
+ pp_cxx_nested_name_specifier (pp, PTRMEM_CST_CLASS (t));
+ pp_cxx_unqualified_id (pp, PTRMEM_CST_MEMBER (t));
+ break;
+
+ case OVERLOAD:
+ t = OVL_CURRENT (t);
+ case FUNCTION_DECL:
+ if (DECL_FUNCTION_MEMBER_P (t))
+ pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
+ pp_cxx_unqualified_id
+ (pp, DECL_CONSTRUCTOR_P (t) ? DECL_CONTEXT (t) : t);
+ break;
+
+ case OFFSET_REF:
+ case SCOPE_REF:
+ pp_cxx_nested_name_specifier (pp, TREE_OPERAND (t, 0));
+ pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 1));
+ break;
+
+ default:
+ {
+ tree scope = TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t);
+ if (scope != pp->enclosing_scope)
+ {
+ pp_cxx_nested_name_specifier (pp, scope);
+ pp_cxx_template_keyword_if_needed (pp, scope, t);
+ }
+ pp_cxx_unqualified_id (pp, t);
+ }
+ break;
+ }
+}
+
+/* id-expression:
+ unqualified-id
+ qualified-id */
+static inline void
+pp_cxx_id_expression (cxx_pretty_printer *pp, tree t)
+{
+ if (TREE_CODE (t) == OVERLOAD)
+ t = OVL_CURRENT (t);
+ if (DECL_P (t) && DECL_CONTEXT (t))
+ pp_cxx_qualified_id (pp, t);
+ else
+ pp_cxx_unqualified_id (pp, t);
+}
+
+/* primary-expression:
+ literal
+ this
+ :: identifier
+ :: operator-function-id
+ :: qualifier-id
+ ( expression )
+ id-expression */
+static void
+pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case STRING_CST:
+ case INTEGER_CST:
+ case REAL_CST:
+ pp_c_constant (pp_c_base (pp), t);
+ break;
+
+ case BASELINK:
+ t = BASELINK_FUNCTIONS (t);
+ case VAR_DECL:
+ case PARM_DECL:
+ case FIELD_DECL:
+ case FUNCTION_DECL:
+ case OVERLOAD:
+ case CONST_DECL:
+ case TEMPLATE_DECL:
+ pp_cxx_id_expression (pp, t);
+ break;
+
+ case RESULT_DECL:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ pp_cxx_unqualified_id (pp, t);
+ break;
+
+ default:
+ pp_c_primary_expression (pp_c_base (pp), t);
+ break;
+ }
+}
+
+/* postfix-expression:
+ primary-expression
+ postfix-expression [ expression ]
+ postfix-expression ( expression-list(opt) )
+ simple-type-specifier ( expression-list(opt) )
+ typename ::(opt) nested-name-specifier identifier ( expression-list(opt) )
+ typename ::(opt) nested-name-specifier template(opt)
+ template-id ( expression-list(opt) )
+ postfix-expression . template(opt) ::(opt) id-expression
+ postfix-expression -> template(opt) ::(opt) id-expression
+ postfix-expression . pseudo-destructor-name
+ postfix-expression -> pseudo-destructor-name
+ postfix-expression ++
+ postfix-expression --
+ dynamic_cast < type-id > ( expression )
+ static_cast < type-id > ( expression )
+ reinterpret_cast < type-id > ( expression )
+ const_cast < type-id > ( expression )
+ typeid ( expression )
+ typeif ( type-id ) */
+
+static void
+pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+
+ switch (code)
+ {
+ case AGGR_INIT_EXPR:
+ case CALL_EXPR:
+ {
+ tree fun = TREE_OPERAND (t, 0);
+ tree args = TREE_OPERAND (t, 1);
+ tree saved_scope = pp->enclosing_scope;
+
+ if (TREE_CODE (fun) == ADDR_EXPR)
+ fun = TREE_OPERAND (fun, 0);
+
+ /* In templates, where there is no way to tell whether a given
+ call uses an actual member function. So the parser builds
+ FUN as a COMPONENT_REF or a plain IDENTIFIER_NODE until
+ instantiation time. */
+ if (TREE_CODE (fun) != FUNCTION_DECL)
+ ;
+ else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
+ {
+ tree object = code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t)
+ ? TREE_OPERAND (t, 2)
+ : TREE_VALUE (args);
+
+ while (TREE_CODE (object) == NOP_EXPR)
+ object = TREE_OPERAND (object, 0);
+
+ if (TREE_CODE (object) == ADDR_EXPR)
+ object = TREE_OPERAND (object, 0);
+
+ if (TREE_CODE (TREE_TYPE (object)) != POINTER_TYPE)
+ {
+ pp_cxx_postfix_expression (pp, object);
+ pp_cxx_dot (pp);
+ }
+ else
+ {
+ pp_cxx_postfix_expression (pp, object);
+ pp_cxx_arrow (pp);
+ }
+ args = TREE_CHAIN (args);
+ pp->enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
+ }
+
+ pp_cxx_postfix_expression (pp, fun);
+ pp->enclosing_scope = saved_scope;
+ pp_cxx_call_argument_list (pp, args);
+ }
+ if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
+ {
+ pp_separate_with (pp, ',');
+ pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 2));
+ }
+ break;
+
+ case BASELINK:
+ case VAR_DECL:
+ case PARM_DECL:
+ case FIELD_DECL:
+ case FUNCTION_DECL:
+ case OVERLOAD:
+ case CONST_DECL:
+ case TEMPLATE_DECL:
+ case RESULT_DECL:
+ pp_cxx_primary_expression (pp, t);
+ break;
+
+ case DYNAMIC_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ if (code == DYNAMIC_CAST_EXPR)
+ pp_identifier (pp, "dynamic_cast");
+ else if (code == STATIC_CAST_EXPR)
+ pp_identifier (pp, "static_cast");
+ else if (code == REINTERPRET_CAST_EXPR)
+ pp_identifier (pp, "reinterpret_cast");
+ else
+ pp_identifier (pp, "const_cast");
+ pp_cxx_begin_template_argument_list (pp);
+ pp_cxx_type_id (pp, TREE_TYPE (t));
+ pp_cxx_end_template_argument_list (pp);
+ pp_left_paren (pp);
+ pp_cxx_expression (pp, TREE_OPERAND (t, 0));
+ pp_right_paren (pp);
+ break;
+
+ case EMPTY_CLASS_EXPR:
+ pp_cxx_type_id (pp, TREE_TYPE (t));
+ pp_left_paren (pp);
+ pp_right_paren (pp);
+ break;
+
+ case TYPEID_EXPR:
+ t = TREE_OPERAND (t, 0);
+ pp_cxx_identifier (pp, "typeid");
+ pp_left_paren (pp);
+ if (TYPE_P (t))
+ pp_cxx_type_id (pp, t);
+ else
+ pp_cxx_expression (pp, t);
+ pp_right_paren (pp);
+ break;
+
+ case PSEUDO_DTOR_EXPR:
+ pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
+ pp_cxx_dot (pp);
+ pp_cxx_qualified_id (pp, TREE_OPERAND (t, 1));
+ pp_cxx_colon_colon (pp);
+ pp_complement (pp);
+ pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 2));
+ break;
+
+ default:
+ pp_c_postfix_expression (pp_c_base (pp), t);
+ break;
+ }
+}
+
+/* new-expression:
+ ::(opt) new new-placement(opt) new-type-id new-initializer(opt)
+ ::(opt) new new-placement(opt) ( type-id ) new-initializer(opt)
+
+ new-placement:
+ ( expression-list )
+
+ new-type-id:
+ type-specifier-seq new-declarator(opt)
+
+ new-declarator:
+ ptr-operator new-declarator(opt)
+ direct-new-declarator
+
+ direct-new-declarator
+ [ expression ]
+ direct-new-declarator [ constant-expression ]
+
+ new-initializer:
+ ( expression-list(opt) ) */
+static void
+pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+ switch (code)
+ {
+ case NEW_EXPR:
+ case VEC_NEW_EXPR:
+ if (NEW_EXPR_USE_GLOBAL (t))
+ pp_cxx_colon_colon (pp);
+ pp_cxx_identifier (pp, "new");
+ if (TREE_OPERAND (t, 0))
+ {
+ pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
+ pp_space (pp);
+ }
+ /* FIXME: array-types are built with one more element. */
+ pp_cxx_type_id (pp, TREE_OPERAND (t, 1));
+ if (TREE_OPERAND (t, 2))
+ {
+ pp_left_paren (pp);
+ t = TREE_OPERAND (t, 2);
+ if (TREE_CODE (t) == TREE_LIST)
+ pp_c_expression_list (pp_c_base (pp), t);
+ else if (t == void_zero_node)
+ ; /* OK, empty initializer list. */
+ else
+ pp_cxx_expression (pp, t);
+ pp_right_paren (pp);
+ }
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ }
+}
+
+/* delete-expression:
+ ::(opt) delete cast-expression
+ ::(opt) delete [ ] cast-expression */
+static void
+pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+ switch (code)
+ {
+ case DELETE_EXPR:
+ case VEC_DELETE_EXPR:
+ if (DELETE_EXPR_USE_GLOBAL (t))
+ pp_cxx_colon_colon (pp);
+ pp_cxx_identifier (pp, "delete");
+ if (code == VEC_DELETE_EXPR)
+ {
+ pp_left_bracket (pp);
+ pp_right_bracket (pp);
+ }
+ pp_c_cast_expression (pp_c_base (pp), TREE_OPERAND (t, 0));
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ }
+}
+
+/* unary-expression:
+ postfix-expression
+ ++ cast-expression
+ -- cast-expression
+ unary-operator cast-expression
+ sizeof unary-expression
+ sizeof ( type-id )
+ new-expression
+ delete-expression
+
+ unary-operator: one of
+ * & + - !
+
+ GNU extensions:
+ __alignof__ unary-expression
+ __alignof__ ( type-id ) */
+static void
+pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+ switch (code)
+ {
+ case NEW_EXPR:
+ case VEC_NEW_EXPR:
+ pp_cxx_new_expression (pp, t);
+ break;
+
+ case DELETE_EXPR:
+ case VEC_DELETE_EXPR:
+ pp_cxx_delete_expression (pp, t);
+ break;
+
+ default:
+ pp_c_unary_expression (pp_c_base (pp), t);
+ break;
+ }
+}
+
+/* cast-expression:
+ unary-expression
+ ( type-id ) cast-expression */
+static void
+pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case CAST_EXPR:
+ pp_cxx_type_id (pp, TREE_TYPE (t));
+ pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
+ break;
+
+ default:
+ pp_c_cast_expression (pp_c_base (pp), t);
+ break;
+ }
+}
+
+/* pm-expression:
+ cast-expression
+ pm-expression .* cast-expression
+ pm-expression ->* cast-expression */
+static void
+pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ /* Handle unfortunate OFFESET_REF overloading here. */
+ case OFFSET_REF:
+ if (TYPE_P (TREE_OPERAND (t, 0)))
+ {
+ pp_cxx_qualified_id (pp, t);
+ break;
+ }
+ /* Else fall through. */
+ case MEMBER_REF:
+ case DOTSTAR_EXPR:
+ pp_cxx_pm_expression (pp, TREE_OPERAND (t, 0));
+ pp_cxx_dot (pp);
+ pp_star(pp);
+ pp_cxx_cast_expression (pp, TREE_OPERAND (t, 1));
+ break;
+
+
+ default:
+ pp_cxx_cast_expression (pp, t);
+ break;
+ }
+}
+
+/* multiplicative-expression:
+ pm-expression
+ multiplicative-expression * pm-expression
+ multiplicative-expression / pm-expression
+ multiplicative-expression % pm-expression */
+static void
+pp_cxx_multiplicative_expression (cxx_pretty_printer *pp, tree e)
+{
+ enum tree_code code = TREE_CODE (e);
+ switch (code)
+ {
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ pp_cxx_multiplicative_expression (pp, TREE_OPERAND (e, 0));
+ pp_space (pp);
+ if (code == MULT_EXPR)
+ pp_star (pp);
+ else if (code == TRUNC_DIV_EXPR)
+ pp_slash (pp);
+ else
+ pp_modulo (pp);
+ pp_space (pp);
+ pp_cxx_pm_expression (pp, TREE_OPERAND (e, 1));
+ break;
+
+ default:
+ pp_cxx_pm_expression (pp, e);
+ break;
+ }
+}
+
+/* conditional-expression:
+ logical-or-expression
+ logical-or-expression ? expression : assignment-expression */
+static void
+pp_cxx_conditional_expression (cxx_pretty_printer *pp, tree e)
+{
+ if (TREE_CODE (e) == COND_EXPR)
+ {
+ pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
+ pp_space (pp);
+ pp_question (pp);
+ pp_space (pp);
+ pp_cxx_expression (pp, TREE_OPERAND (e, 1));
+ pp_space (pp);
+ pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
+ }
+ else
+ pp_c_logical_or_expression (pp_c_base (pp), e);
+}
+
+static void
+pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
+{
+ const char *op;
+
+ switch (TREE_CODE (t))
+ {
+ case NOP_EXPR:
+ op = "=";
+ break;
+
+ case PLUS_EXPR:
+ op = "+=";
+ break;
+
+ case MINUS_EXPR:
+ op = "-=";
+ break;
+
+ case TRUNC_DIV_EXPR:
+ op = "/=";
+ break;
+
+ case TRUNC_MOD_EXPR:
+ op = "%=";
+ break;
+
+ default:
+ op = tree_code_name[TREE_CODE (t)];
+ break;
+ }
+
+ pp_cxx_identifier (pp, op);
+}
+
+
+/* assignment-expression:
+ conditional-expression
+ logical-or-expression assignment-operator assignment-expression
+ throw-expression
+
+ throw-expression:
+ throw assignment-expression(opt)
+
+ assignment-operator: one of
+ = *= /= %= += -= >>= <<= &= ^= |= */
+static void
+pp_cxx_assignment_expression (cxx_pretty_printer *pp, tree e)
+{
+ switch (TREE_CODE (e))
+ {
+ case MODIFY_EXPR:
+ case INIT_EXPR:
+ pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
+ pp_space (pp);
+ pp_equal (pp);
+ pp_space (pp);
+ pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 1));
+ break;
+
+ case THROW_EXPR:
+ pp_cxx_identifier (pp, "throw");
+ if (TREE_OPERAND (e, 0))
+ pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0));
+ break;
+
+ case MODOP_EXPR:
+ pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
+ pp_cxx_assignment_operator (pp, TREE_OPERAND (e, 1));
+ pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
+ break;
+
+ default:
+ pp_cxx_conditional_expression (pp, e);
+ break;
+ }
+}
+
+static void
+pp_cxx_expression (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case STRING_CST:
+ case INTEGER_CST:
+ case REAL_CST:
+ pp_c_constant (pp_c_base (pp), t);
+ break;
+
+ case RESULT_DECL:
+ pp_cxx_unqualified_id (pp, t);
+ break;
+
+#if 0
+ case OFFSET_REF:
+#endif
+ case SCOPE_REF:
+ case PTRMEM_CST:
+ pp_cxx_qualified_id (pp, t);
+ break;
+
+ case OVERLOAD:
+ t = OVL_CURRENT (t);
+ case VAR_DECL:
+ case PARM_DECL:
+ case FIELD_DECL:
+ case CONST_DECL:
+ case FUNCTION_DECL:
+ case BASELINK:
+ case TEMPLATE_DECL:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ pp_cxx_primary_expression (pp, t);
+ break;
+
+ case CALL_EXPR:
+ case DYNAMIC_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case CONST_CAST_EXPR:
+#if 0
+ case MEMBER_REF:
+#endif
+ case EMPTY_CLASS_EXPR:
+ case TYPEID_EXPR:
+ case PSEUDO_DTOR_EXPR:
+ case AGGR_INIT_EXPR:
+ pp_cxx_postfix_expression (pp, t);
+ break;
+
+ case NEW_EXPR:
+ case VEC_NEW_EXPR:
+ pp_cxx_new_expression (pp, t);
+ break;
+
+ case DELETE_EXPR:
+ case VEC_DELETE_EXPR:
+ pp_cxx_delete_expression (pp, t);
+ break;
+
+ case CAST_EXPR:
+ pp_cxx_cast_expression (pp, t);
+ break;
+
+ case OFFSET_REF:
+ case MEMBER_REF:
+ case DOTSTAR_EXPR:
+ pp_cxx_pm_expression (pp, t);
+ break;
+
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case TRUNC_MOD_EXPR:
+ pp_cxx_multiplicative_expression (pp, t);
+ break;
+
+ case COND_EXPR:
+ pp_cxx_conditional_expression (pp, t);
+ break;
+
+ case MODIFY_EXPR:
+ case INIT_EXPR:
+ case THROW_EXPR:
+ case MODOP_EXPR:
+ pp_cxx_assignment_expression (pp, t);
+ break;
+
+ default:
+ pp_c_expression (pp_c_base (pp), t);
+ break;
+ }
+}
+
+
+/* Declarations. */
+
+/* function-specifier:
+ inline
+ virtual
+ explicit */
+static void
+pp_cxx_function_specifier (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case FUNCTION_DECL:
+ if (DECL_VIRTUAL_P (t))
+ pp_cxx_identifier (pp, "virtual");
+ else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
+ pp_cxx_identifier (pp, "explicit");
+ else
+ pp_c_function_specifier (pp_c_base (pp), t);
+
+ default:
+ break;
+ }
+}
+
+/* decl-specifier-seq:
+ decl-specifier-seq(opt) decl-specifier
+
+ decl-specifier:
+ storage-class-specifier
+ type-specifier
+ function-specifier
+ friend
+ typedef */
+static void
+pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case CONST_DECL:
+ case FIELD_DECL:
+ pp_cxx_storage_class_specifier (pp, t);
+ pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
+ break;
+
+ case TYPE_DECL:
+ pp_cxx_identifier (pp, "typedef");
+ pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
+ break;
+
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ {
+ tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
+ pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm)));
+ pp_cxx_whitespace (pp);
+ pp_cxx_ptr_operator (pp, t);
+ }
+ break;
+
+ case FUNCTION_DECL:
+ /* Constructors don't have return types. And conversion functions
+ do not have a type-specifier in their return types. */
+ if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
+ pp_cxx_function_specifier (pp, t);
+ else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
+ pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (t)));
+ else
+ default:
+ pp_c_declaration_specifiers (pp_c_base (pp), t);
+ break;
+ }
+}
+
+/* simple-type-specifier:
+ ::(opt) nested-name-specifier(opt) type-name
+ ::(opt) nested-name-specifier(opt) template(opt) template-id
+ char
+ wchar_t
+ bool
+ short
+ int
+ long
+ signed
+ unsigned
+ float
+ double
+ void */
+static void
+pp_cxx_simple_type_specifier (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ pp_cxx_qualified_id (pp, t);
+ break;
+
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ pp_cxx_unqualified_id (pp, t);
+ break;
+
+ case TYPENAME_TYPE:
+ pp_cxx_identifier (pp, "typename");
+ pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t));
+ pp_cxx_unqualified_id (pp, TYPE_NAME (t));
+ break;
+
+ default:
+ pp_c_type_specifier (pp_c_base (pp), t);
+ break;
+ }
+}
+
+/* type-specifier-seq:
+ type-specifier type-specifier-seq(opt)
+
+ type-specifier:
+ simple-type-specifier
+ class-specifier
+ enum-specifier
+ elaborated-type-specifier
+ cv-qualifier */
+
+static void
+pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case TEMPLATE_DECL:
+ case TEMPLATE_TYPE_PARM:
+ case TYPE_DECL:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ pp_c_type_qualifier_list (pp_c_base (pp), t);
+ pp_cxx_simple_type_specifier (pp, t);
+ break;
+
+ case METHOD_TYPE:
+ pp_cxx_type_specifier_seq (pp, TREE_TYPE (t));
+ pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
+ pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
+ break;
+
+ default:
+ if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
+ pp_c_specifier_qualifier_list (pp_c_base (pp), t);
+ }
+}
+
+/* ptr-operator:
+ * cv-qualifier-seq(opt)
+ &
+ ::(opt) nested-name-specifier * cv-qualifier-seq(opt) */
+
+static void
+pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
+{
+ if (!TYPE_P (t) && TREE_CODE (t) != TYPE_DECL)
+ t = TREE_TYPE (t);
+ switch (TREE_CODE (t))
+ {
+ case REFERENCE_TYPE:
+ case POINTER_TYPE:
+ if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
+ || TYPE_PTR_TO_MEMBER_P (TREE_TYPE (t)))
+ pp_cxx_ptr_operator (pp, TREE_TYPE (t));
+ if (TREE_CODE (t) == POINTER_TYPE)
+ {
+ pp_star (pp);
+ pp_cxx_cv_qualifier_seq (pp, t);
+ }
+ else
+ pp_ampersand (pp);
+ break;
+
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ {
+ pp_cxx_left_paren (pp);
+ pp_cxx_nested_name_specifier (pp, TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
+ pp_star (pp);
+ break;
+ }
+ case OFFSET_TYPE:
+ if (TYPE_PTR_TO_MEMBER_P (t))
+ {
+ pp_cxx_nested_name_specifier (pp, TYPE_PTRMEM_CLASS_TYPE (t));
+ pp_star (pp);
+ pp_cxx_cv_qualifier_seq (pp, t);
+ break;
+ }
+ /* else fall through. */
+
+ default:
+ pp_unsupported_tree (pp, t);
+ break;
+ }
+}
+
+static inline tree
+pp_cxx_implicit_parameter_type (tree mf)
+{
+ return TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (mf))));
+}
+
+/*
+ parameter-declaration:
+ decl-specifier-seq declarator
+ decl-specifier-seq declarator = assignment-expression
+ decl-specifier-seq abstract-declarator(opt)
+ decl-specifier-seq abstract-declarator(opt) assignment-expression */
+static inline void
+pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_decl_specifier_seq (pp, t);
+ if (TYPE_P (t))
+ pp_cxx_abstract_declarator (pp, t);
+ else
+ pp_cxx_declarator (pp, t);
+}
+
+/* parameter-declaration-clause:
+ parameter-declaration-list(opt) ...(opt)
+ parameter-declaration-list , ...
+
+ parameter-declaration-list:
+ parameter-declaration
+ parameter-declaration-list , parameter-declaration */
+static void
+pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
+{
+ tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
+ tree types = TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
+ const bool abstract = args == NULL
+ || pp_c_base (pp)->flags & pp_c_flag_abstract;
+ bool first = true;
+
+ /* Skip artificial parameter for nonstatic member functions. */
+ if (TREE_CODE (t) == METHOD_TYPE)
+ types = TREE_CHAIN (types);
+
+ pp_cxx_left_paren (pp);
+ for (; args; args = TREE_CHAIN (args), types = TREE_CHAIN (types))
+ {
+ if (!first)
+ pp_separate_with (pp, ',');
+ first = false;
+ pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
+ if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument)
+ {
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
+ pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
+ }
+ }
+ pp_cxx_right_paren (pp);
+}
+
+/* exception-specification:
+ throw ( type-id-list(opt) )
+
+ type-id-list
+ type-id
+ type-id-list , type-id */
+static void
+pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
+{
+ tree ex_spec = TYPE_RAISES_EXCEPTIONS (t);
+
+ if (!TYPE_NOTHROW_P (t) && ex_spec == NULL)
+ return;
+ pp_cxx_identifier (pp, "throw");
+ pp_cxx_left_paren (pp);
+ for (; ex_spec && TREE_VALUE (ex_spec); ex_spec = TREE_CHAIN (ex_spec))
+ {
+ pp_cxx_type_id (pp, TREE_VALUE (ex_spec));
+ if (TREE_CHAIN (ex_spec))
+ pp_separate_with (pp, ',');
+ }
+ pp_cxx_right_paren (pp);
+}
+
+/* direct-declarator:
+ declarator-id
+ direct-declarator ( parameter-declaration-clause ) cv-qualifier-seq(opt)
+ exception-specification(opt)
+ direct-declaration [ constant-expression(opt) ]
+ ( declarator ) */
+static void
+pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ case PARM_DECL:
+ case CONST_DECL:
+ case FIELD_DECL:
+ if (DECL_NAME (t))
+ {
+ pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
+ pp_cxx_id_expression (pp, DECL_NAME (t));
+ }
+ pp_cxx_abstract_declarator (pp, TREE_TYPE (t));
+ break;
+
+ case FUNCTION_DECL:
+ pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
+ pp_cxx_id_expression (pp, t);
+ pp_cxx_parameter_declaration_clause (pp, t);
+
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
+ {
+ pp_base (pp)->padding = pp_before;
+ pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
+ }
+
+ pp_cxx_exception_specification (pp, TREE_TYPE (t));
+ break;
+
+ case TYPENAME_TYPE:
+ case TEMPLATE_DECL:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ break;
+
+ default:
+ pp_c_direct_declarator (pp_c_base (pp), t);
+ break;
+ }
+}
+
+/* declarator:
+ direct-declarator
+ ptr-operator declarator */
+static void
+pp_cxx_declarator (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_direct_declarator (pp, t);
+}
+
+/* ctor-initializer:
+ : mem-initializer-list
+
+ mem-initializer-list:
+ mem-initializer
+ mem-initializer , mem-initializer-list
+
+ mem-initializer:
+ mem-initializer-id ( expression-list(opt) )
+
+ mem-initializer-id:
+ ::(opt) nested-name-specifier(opt) class-name
+ identifier */
+static void
+pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
+{
+ t = TREE_OPERAND (t, 0);
+ pp_cxx_whitespace (pp);
+ pp_colon (pp);
+ pp_cxx_whitespace (pp);
+ for (; t; t = TREE_CHAIN (t))
+ {
+ pp_cxx_primary_expression (pp, TREE_PURPOSE (t));
+ pp_cxx_call_argument_list (pp, TREE_VALUE (t));
+ if (TREE_CHAIN (t))
+ pp_separate_with (pp, ',');
+ }
+}
+
+/* function-definition:
+ decl-specifier-seq(opt) declarator ctor-initializer(opt) function-body
+ decl-specifier-seq(opt) declarator function-try-block */
+
+void
+pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
+{
+ tree saved_scope = pp->enclosing_scope;
+ pp_cxx_decl_specifier_seq (pp, t);
+ pp_cxx_declarator (pp, t);
+ pp_needs_newline (pp) = true;
+ pp->enclosing_scope = DECL_CONTEXT (t);
+ if (DECL_SAVED_TREE (t))
+ {
+ tree body = DECL_SAVED_TREE (t);
+ if (TREE_CODE (body) == COMPOUND_STMT
+ && TREE_CODE (COMPOUND_BODY (body)) == CTOR_INITIALIZER)
+ {
+ body = COMPOUND_BODY (body);
+ pp_cxx_ctor_initializer (pp, body);
+ body = TREE_CHAIN (body);
+ }
+ pp_cxx_statement (pp, body);
+ }
+ else
+ {
+ pp_cxx_semicolon (pp);
+ pp_needs_newline (pp) = true;
+ }
+ pp_flush (pp);
+ pp->enclosing_scope = saved_scope;
+}
+
+/* abstract-declarator:
+ ptr-operator abstract-declarator(opt)
+ direct-abstract-declarator */
+static void
+pp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t)
+{
+ if (TYPE_PTRMEM_P (t) || TYPE_PTRMEMFUNC_P (t))
+ pp_cxx_right_paren (pp);
+ else if (POINTER_TYPE_P (t))
+ {
+ if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
+ || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
+ pp_cxx_right_paren (pp);
+ t = TREE_TYPE (t);
+ }
+ pp_cxx_direct_abstract_declarator (pp, t);
+}
+
+/* direct-abstract-declarator:
+ direct-abstract-declarator(opt) ( parameter-declaration-clause )
+ cv-qualifier-seq(opt) exception-specification(opt)
+ direct-abstract-declarator(opt) [ constant-expression(opt) ]
+ ( abstract-declarator ) */
+static void
+pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case REFERENCE_TYPE:
+ pp_cxx_abstract_declarator (pp, t);
+ break;
+
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (t))
+ pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
+ break;
+
+ case METHOD_TYPE:
+ case FUNCTION_TYPE:
+ pp_cxx_parameter_declaration_clause (pp, t);
+ pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t));
+ if (TREE_CODE (t) == METHOD_TYPE)
+ {
+ pp_base (pp)->padding = pp_before;
+ pp_cxx_cv_qualifier_seq
+ (pp, TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))));
+ }
+ pp_cxx_exception_specification (pp, t);
+ break;
+
+ case TYPENAME_TYPE:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_TEMPLATE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ case UNBOUND_CLASS_TEMPLATE:
+ break;
+
+ default:
+ pp_c_direct_abstract_declarator (pp_c_base (pp), t);
+ break;
+ }
+}
+
+/* type-id:
+ type-specifier-seq abstract-declarator(opt) */
+static void
+pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
+{
+ pp_flags saved_flags = pp_c_base (pp)->flags;
+ pp_c_base (pp)->flags |= pp_c_flag_abstract;
+
+ switch (TREE_CODE (t))
+ {
+ case TYPE_DECL:
+ case UNION_TYPE:
+ case RECORD_TYPE:
+ case ENUMERAL_TYPE:
+ case TYPENAME_TYPE:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ case UNBOUND_CLASS_TEMPLATE:
+ case TEMPLATE_TEMPLATE_PARM:
+ case TEMPLATE_TYPE_PARM:
+ case TEMPLATE_PARM_INDEX:
+ case TEMPLATE_DECL:
+ case TYPEOF_TYPE:
+ case TEMPLATE_ID_EXPR:
+ /* FIXME: Should be pp_cxx_type_specifier_seq. */
+ pp_cxx_type_specifier_seq (pp, t);
+ pp_cxx_declarator (pp, t);
+ break;
+
+ default:
+ pp_c_type_id (pp_c_base (pp), t);
+ break;
+ }
+
+ pp_c_base (pp)->flags = saved_flags;
+}
+
+/* template-argument-list:
+ template-argument
+ template-argument-list, template-argument
+
+ template-argument:
+ assignment-expression
+ type-id
+ template-name */
+static void
+pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
+{
+ int i;
+ if (t == NULL)
+ return;
+ for (i = 0; i < TREE_VEC_LENGTH (t); ++i)
+ {
+ tree arg = TREE_VEC_ELT (t, i);
+ if (i != 0)
+ pp_separate_with (pp, ',');
+ if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
+ && TYPE_P (DECL_TEMPLATE_RESULT (arg))))
+ pp_cxx_type_id (pp, arg);
+ else
+ pp_cxx_expression (pp, arg);
+ }
+}
+
+
+static void
+pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
+{
+ t = DECL_STMT_DECL (t);
+ pp_cxx_type_specifier_seq (pp, t);
+ if (TYPE_P (t))
+ pp_cxx_abstract_declarator (pp, t);
+ else
+ pp_cxx_declarator (pp, t);
+}
+
+/* Statements. */
+
+void
+pp_cxx_statement (cxx_pretty_printer *pp, tree t)
+{
+ switch (TREE_CODE (t))
+ {
+ case USING_STMT:
+ pp_cxx_identifier (pp, "using");
+ pp_cxx_identifier (pp, "namespace");
+ pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t));
+ break;
+
+ case USING_DECL:
+ pp_cxx_identifier (pp, "using");
+ pp_cxx_nested_name_specifier (pp, DECL_INITIAL (t));
+ pp_cxx_unqualified_id (pp, DECL_NAME (t));
+ break;
+
+ case EH_SPEC_BLOCK:
+ break;
+
+ /* try-block:
+ try compound-statement handler-seq */
+ case TRY_BLOCK:
+ pp_maybe_newline_and_indent (pp, 0);
+ pp_cxx_identifier (pp, "try");
+ pp_newline_and_indent (pp, 3);
+ pp_cxx_statement (pp, TRY_STMTS (t));
+ pp_newline_and_indent (pp, -3);
+ if (CLEANUP_P (t))
+ ;
+ else
+ pp_cxx_statement (pp, TRY_HANDLERS (t));
+ break;
+
+ /*
+ handler-seq:
+ handler handler-seq(opt)
+
+ handler:
+ catch ( exception-declaration ) compound-statement
+
+ exception-declaration:
+ type-specifier-seq declarator
+ type-specifier-seq abstract-declarator
+ ... */
+ case HANDLER:
+ pp_cxx_identifier (pp, "catch");
+ pp_cxx_left_paren (pp);
+ pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
+ pp_cxx_right_paren (pp);
+ pp_indentation (pp) += 3;
+ pp_needs_newline (pp) = true;
+ pp_cxx_statement (pp, HANDLER_BODY (t));
+ pp_indentation (pp) -= 3;
+ pp_needs_newline (pp) = true;
+ break;
+
+ default:
+ pp_c_statement (pp_c_base (pp), t);
+ break;
+ }
+}
+
+/* original-namespace-definition:
+ namespace identifier { namespace-body }
+
+ As an edge case, we also handle unnamed namespace definition here. */
+
+static void
+pp_cxx_original_namespace_definition (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_identifier (pp, "namespace");
+ if (DECL_NAME (t))
+ pp_cxx_unqualified_id (pp, t);
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_brace (pp);
+ /* We do not print the namespace-body. */
+ pp_cxx_whitespace (pp);
+ pp_cxx_right_brace (pp);
+}
+
+/* namespace-alias:
+ identifier
+
+ namespace-alias-definition:
+ namespace identifier = qualified-namespace-specifier ;
+
+ qualified-namespace-specifier:
+ ::(opt) nested-name-specifier(opt) namespace-name */
+
+static void
+pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_identifier (pp, "namespace");
+ pp_cxx_unqualified_id (pp, t);
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
+ pp_cxx_qualified_id (pp, DECL_NAMESPACE_ALIAS (t));
+ pp_cxx_semicolon (pp);
+}
+
+/* simple-declaration:
+ decl-specifier-seq(opt) init-declarator-list(opt) */
+static void
+pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
+{
+ pp_cxx_decl_specifier_seq (pp, t);
+ pp_cxx_init_declarator (pp, t);
+ pp_cxx_semicolon (pp);
+ pp_needs_newline (pp) = true;
+}
+
+/*
+ template-parameter-list:
+ template-parameter
+ template-parameter-list , template-parameter */
+
+static inline void
+pp_cxx_template_parameter_list (cxx_pretty_printer *pp, tree t)
+{
+ const int n = TREE_VEC_LENGTH (t);
+ int i;
+ for (i = 0; i < n; ++i)
+ {
+ if (i)
+ pp_separate_with (pp, ',');
+ pp_cxx_template_parameter (pp, TREE_VEC_ELT (t, i));
+ }
+}
+
+/* template-parameter:
+ type-parameter
+ parameter-declaration
+
+ type-parameter:
+ class identifier(opt)
+ class identifier(op) = type-id
+ typename identifier(opt)
+ typename identifier(opt) = type-id
+ template < template-parameter-list > class identifier(opt)
+ template < template-parameter-list > class identifier(opt) = template-name
+*/
+static void
+pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t)
+{
+ tree parameter = TREE_VALUE (t);
+ switch (TREE_CODE (parameter))
+ {
+ case TYPE_DECL:
+ pp_cxx_identifier (pp, "class");
+ if (DECL_NAME (parameter))
+ pp_cxx_tree_identifier (pp, DECL_NAME (parameter));
+ /* FIXME: Chech if we should print also default argument. */
+ break;
+
+ case PARM_DECL:
+ pp_cxx_parameter_declaration (pp, parameter);
+ break;
+
+ case TEMPLATE_DECL:
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ break;
+ }
+}
+
+/* Pretty-print a template parameter in the canonical form
+ "template-parameter-<level>-<position in parameter list>". */
+
+void
+pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
+{
+ const enum tree_code code = TREE_CODE (parm);
+
+ /* Brings type template parameters to the canonical forms. */
+ if (code == TEMPLATE_TYPE_PARM || code == TEMPLATE_TEMPLATE_PARM
+ || code == BOUND_TEMPLATE_TEMPLATE_PARM)
+ parm = TEMPLATE_TYPE_PARM_INDEX (parm);
+
+ pp_cxx_begin_template_argument_list (pp);
+ pp_cxx_identifier (pp, "template-parameter-");
+ pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
+ pp_minus (pp);
+ pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
+ pp_cxx_end_template_argument_list (pp);
+}
+
+/*
+ template-declaration:
+ export(opt) template < template-parameter-list > declaration */
+static void
+pp_cxx_template_declaration (cxx_pretty_printer *pp, tree t)
+{
+ tree tmpl = most_general_template (t);
+ tree level;
+ int i = 0;
+
+ pp_maybe_newline_and_indent (pp, 0);
+ for (level = DECL_TEMPLATE_PARMS (tmpl); level; level = TREE_CHAIN (level))
+ {
+ pp_cxx_identifier (pp, "template");
+ pp_cxx_begin_template_argument_list (pp);
+ pp_cxx_template_parameter_list (pp, TREE_VALUE (level));
+ pp_cxx_end_template_argument_list (pp);
+ pp_newline_and_indent (pp, 3);
+ i += 3;
+ }
+ if (TREE_CODE (t) == FUNCTION_DECL && DECL_SAVED_TREE (t))
+ pp_cxx_function_definition (pp, t);
+ else
+ pp_cxx_simple_declaration (pp, t);
+}
+
+static void
+pp_cxx_explicit_specialization (cxx_pretty_printer *pp, tree t)
+{
+ pp_unsupported_tree (pp, t);
+}
+
+static void
+pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
+{
+ pp_unsupported_tree (pp, t);
+}
+
+/*
+ declaration:
+ block-declaration
+ function-definition
+ template-declaration
+ explicit-instantiation
+ explicit-specialization
+ linkage-specification
+ namespace-definition
+
+ block-declaration:
+ simple-declaration
+ asm-definition
+ namespace-alias-definition
+ using-declaration
+ using-directive */
+void
+pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
+{
+ if (!DECL_LANG_SPECIFIC (t))
+ pp_cxx_simple_declaration (pp, t);
+ else if (DECL_USE_TEMPLATE (t))
+ switch (DECL_USE_TEMPLATE (t))
+ {
+ case 1:
+ pp_cxx_template_declaration (pp, t);
+ break;
+
+ case 2:
+ pp_cxx_explicit_specialization (pp, t);
+ break;
+
+ case 3:
+ pp_cxx_explicit_instantiation (pp, t);
+ break;
+
+ default:
+ break;
+ }
+ else switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ case TYPE_DECL:
+ pp_cxx_simple_declaration (pp, t);
+ break;
+
+ case FUNCTION_DECL:
+ if (DECL_SAVED_TREE (t))
+ pp_cxx_function_definition (pp, t);
+ else
+ pp_cxx_simple_declaration (pp, t);
+ break;
+
+ case NAMESPACE_DECL:
+ if (DECL_NAMESPACE_ALIAS (t))
+ pp_cxx_namespace_alias_definition (pp, t);
+ else
+ pp_cxx_original_namespace_definition (pp, t);
+ break;
+
+ default:
+ pp_unsupported_tree (pp, t);
+ break;
+ }
+}
+
+
+typedef c_pretty_print_fn pp_fun;
+
+void
+pp_cxx_pretty_printer_init (cxx_pretty_printer *pp)
+{
+ pp_c_pretty_printer_init (pp_c_base (pp));
+ pp_set_line_maximum_length (pp, 0);
+
+ pp->c_base.declaration = (pp_fun) pp_cxx_declaration;
+ pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq;
+ pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier;
+ pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
+ pp->c_base.declarator = (pp_fun) pp_cxx_declarator;
+ pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator;
+ pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
+ pp->c_base.type_id = (pp_fun) pp_cxx_type_id;
+ pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator;
+ pp->c_base.direct_abstract_declarator =
+ (pp_fun) pp_cxx_direct_abstract_declarator;
+ pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier;
+
+ /* pp->c_base.statement = (pp_fun) pp_cxx_statement; */
+
+ pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression;
+ pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression;
+ pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression;
+ pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression;
+ pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression;
+ pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression;
+ pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression;
+ pp->c_base.expression = (pp_fun) pp_cxx_expression;
+ pp->enclosing_scope = global_namespace;
+}
diff --git a/contrib/gcc/cp/cxx-pretty-print.h b/contrib/gcc/cp/cxx-pretty-print.h
new file mode 100644
index 000000000000..b47eff0ef196
--- /dev/null
+++ b/contrib/gcc/cp/cxx-pretty-print.h
@@ -0,0 +1,52 @@
+/* Interface for the GNU C++ pretty-printer.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef GCC_CXX_PRETTY_PRINT_H
+#define GCC_CXX_PRETTY_PRINT_H
+
+#include "c-pretty-print.h"
+
+#undef pp_c_base
+#define pp_c_base(PP) (&(PP)->c_base)
+
+typedef enum
+{
+ /* Ask for an qualified-id. */
+ pp_cxx_flag_default_argument = 1 << pp_c_flag_last_bit
+
+} cxx_pretty_printer_flags;
+
+typedef struct
+{
+ c_pretty_printer c_base;
+ /* This is the enclosing scope of the entity being pretty-printed. */
+ tree enclosing_scope;
+} cxx_pretty_printer;
+
+void pp_cxx_pretty_printer_init (cxx_pretty_printer *);
+
+void pp_cxx_declaration (cxx_pretty_printer *, tree);
+void pp_cxx_function_definition (cxx_pretty_printer *, tree);
+void pp_cxx_canonical_template_parameter (cxx_pretty_printer *, tree);
+void pp_cxx_statement (cxx_pretty_printer *, tree);
+
+
+#endif /* GCC_CXX_PRETTY_PRINT_H */
diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c
index 03b90083696d..eb34d39ce8c0 100644
--- a/contrib/gcc/cp/decl.c
+++ b/contrib/gcc/cp/decl.c
@@ -1,27 +1,27 @@
-/* Process declarations and variables for C compiler.
+/* Process declarations and variables for C++ compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Process declarations and symbol lookup for C front end.
+/* Process declarations and symbol lookup for C++ front end.
Also constructs types; the standard scalar types at initialization,
and structure, union, array and enum types when they are declared. */
@@ -30,6 +30,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "expr.h"
@@ -42,7 +44,6 @@ Boston, MA 02111-1307, USA. */
#include "except.h"
#include "toplev.h"
#include "hashtab.h"
-#include "ggc.h"
#include "tm_p.h"
#include "target.h"
#include "c-common.h"
@@ -50,104 +51,75 @@ Boston, MA 02111-1307, USA. */
#include "diagnostic.h"
#include "debug.h"
#include "timevar.h"
-#include "input.h"
-
-static tree grokparms PARAMS ((tree));
-static const char *redeclaration_error_message PARAMS ((tree, tree));
-
-static void push_binding_level PARAMS ((struct cp_binding_level *, int,
- int));
-static void pop_binding_level PARAMS ((void));
-static void suspend_binding_level PARAMS ((void));
-static void resume_binding_level PARAMS ((struct cp_binding_level *));
-static struct cp_binding_level *make_binding_level PARAMS ((void));
-static void declare_namespace_level PARAMS ((void));
-static int decl_jump_unsafe PARAMS ((tree));
-static void storedecls PARAMS ((tree));
-static void require_complete_types_for_parms PARAMS ((tree));
-static int ambi_op_p PARAMS ((enum tree_code));
-static int unary_op_p PARAMS ((enum tree_code));
-static cxx_saved_binding *store_bindings (tree, cxx_saved_binding *);
-static tree lookup_tag_reverse PARAMS ((tree, tree));
-static tree lookup_name_real PARAMS ((tree, int, int, int));
-static void push_local_name PARAMS ((tree));
-static void warn_extern_redeclared_static PARAMS ((tree, tree));
-static tree grok_reference_init PARAMS ((tree, tree, tree, tree *));
-static tree grokfndecl PARAMS ((tree, tree, tree, tree, int,
- enum overload_flags, tree,
- tree, int, int, int, int, int, int, tree));
-static tree grokvardecl PARAMS ((tree, tree, RID_BIT_TYPE *, int, int, tree));
-static tree follow_tag_typedef PARAMS ((tree));
-static tree lookup_tag PARAMS ((enum tree_code, tree,
- struct cp_binding_level *, int));
-static void set_identifier_type_value_with_scope
- PARAMS ((tree, tree, struct cp_binding_level *));
-static void record_unknown_type PARAMS ((tree, const char *));
-static tree builtin_function_1 PARAMS ((const char *, tree, tree, int,
- enum built_in_class, const char *,
- tree));
-static tree build_library_fn_1 PARAMS ((tree, enum tree_code, tree));
-static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
-static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int,
- int));
-static tree maybe_process_template_type_declaration PARAMS ((tree, int, struct cp_binding_level*));
-static void check_for_uninitialized_const_var PARAMS ((tree));
-static hashval_t typename_hash PARAMS ((const void *));
-static int typename_compare PARAMS ((const void *, const void *));
-static void push_binding PARAMS ((tree, tree, struct cp_binding_level*));
-static int add_binding PARAMS ((tree, tree));
-static void pop_binding PARAMS ((tree, tree));
-static tree local_variable_p_walkfn PARAMS ((tree *, int *, void *));
-static cxx_binding *find_binding (tree, tree, cxx_binding *);
-static tree select_decl (cxx_binding *, int);
-static int lookup_flags PARAMS ((int, int));
-static tree qualify_lookup PARAMS ((tree, int));
-static tree record_builtin_java_type PARAMS ((const char *, int));
-static const char *tag_name PARAMS ((enum tag_types code));
-static void find_class_binding_level PARAMS ((void));
-static struct cp_binding_level *innermost_nonclass_level PARAMS ((void));
-static void warn_about_implicit_typename_lookup PARAMS ((tree, tree));
-static int walk_namespaces_r PARAMS ((tree, walk_namespaces_fn, void *));
-static int walk_globals_r PARAMS ((tree, void *));
-static int walk_vtables_r PARAMS ((tree, void*));
-static void add_decl_to_level PARAMS ((tree, struct cp_binding_level *));
-static tree make_label_decl PARAMS ((tree, int));
-static void use_label PARAMS ((tree));
-static void check_previous_goto_1 PARAMS ((tree, struct cp_binding_level *, tree,
- const char *, int));
-static void check_previous_goto PARAMS ((struct named_label_use_list *));
-static void check_switch_goto PARAMS ((struct cp_binding_level *));
-static void check_previous_gotos PARAMS ((tree));
-static void pop_label PARAMS ((tree, tree));
-static void pop_labels PARAMS ((tree));
-static void maybe_deduce_size_from_array_init PARAMS ((tree, tree));
-static void layout_var_decl PARAMS ((tree));
-static void maybe_commonize_var PARAMS ((tree));
+
+static tree grokparms (tree, tree *);
+static const char *redeclaration_error_message (tree, tree);
+
+static int decl_jump_unsafe (tree);
+static void require_complete_types_for_parms (tree);
+static int ambi_op_p (enum tree_code);
+static int unary_op_p (enum tree_code);
+static void push_local_name (tree);
+static tree grok_reference_init (tree, tree, tree, tree *);
+static tree grokfndecl (tree, tree, tree, tree, tree, int,
+ enum overload_flags, tree,
+ tree, int, int, int, int, int, int, tree);
+static tree grokvardecl (tree, tree, RID_BIT_TYPE *, int, int, tree);
+static void record_unknown_type (tree, const char *);
+static tree builtin_function_1 (const char *, tree, tree, int,
+ enum built_in_class, const char *,
+ tree);
+static tree build_library_fn_1 (tree, enum tree_code, tree);
+static int member_function_or_else (tree, tree, enum overload_flags);
+static void bad_specifiers (tree, const char *, int, int, int, int,
+ int);
+static void check_for_uninitialized_const_var (tree);
+static hashval_t typename_hash (const void *);
+static int typename_compare (const void *, const void *);
+static tree local_variable_p_walkfn (tree *, int *, void *);
+static tree record_builtin_java_type (const char *, int);
+static const char *tag_name (enum tag_types code);
+static int walk_namespaces_r (tree, walk_namespaces_fn, void *);
+static int walk_globals_r (tree, void*);
+static int walk_vtables_r (tree, void*);
+static tree make_label_decl (tree, int);
+static void use_label (tree);
+static void check_previous_goto_1 (tree, struct cp_binding_level *, tree,
+ const location_t *);
+static void check_previous_goto (struct named_label_use_list *);
+static void check_switch_goto (struct cp_binding_level *);
+static void check_previous_gotos (tree);
+static void pop_label (tree, tree);
+static void pop_labels (tree);
+static void maybe_deduce_size_from_array_init (tree, tree);
+static void layout_var_decl (tree);
+static void maybe_commonize_var (tree);
static tree check_initializer (tree, tree, int, tree *);
-static void make_rtl_for_nonlocal_decl PARAMS ((tree, tree, const char *));
-static void save_function_data PARAMS ((tree));
-static void check_function_type PARAMS ((tree, tree));
-static void begin_constructor_body PARAMS ((void));
-static void finish_constructor_body PARAMS ((void));
-static void begin_destructor_body PARAMS ((void));
-static void finish_destructor_body PARAMS ((void));
-static tree create_array_type_for_decl PARAMS ((tree, tree, tree));
-static tree get_atexit_node PARAMS ((void));
-static tree get_dso_handle_node PARAMS ((void));
-static tree start_cleanup_fn PARAMS ((void));
-static void end_cleanup_fn PARAMS ((void));
-static tree cp_make_fname_decl PARAMS ((tree, int));
-static void initialize_predefined_identifiers PARAMS ((void));
-static tree check_special_function_return_type
- PARAMS ((special_function_kind, tree, tree));
-static tree push_cp_library_fn PARAMS ((enum tree_code, tree));
-static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
-static void store_parm_decls PARAMS ((tree));
-static int cp_missing_noreturn_ok_p PARAMS ((tree));
+static void make_rtl_for_nonlocal_decl (tree, tree, const char *);
+static void save_function_data (tree);
+static void check_function_type (tree, tree);
+static void begin_constructor_body (void);
+static void finish_constructor_body (void);
+static void begin_destructor_body (void);
+static void finish_destructor_body (void);
+static tree create_array_type_for_decl (tree, tree, tree);
+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 void initialize_predefined_identifiers (void);
+static tree check_special_function_return_type
+ (special_function_kind, tree, tree);
+static tree push_cp_library_fn (enum tree_code, tree);
+static tree build_cp_library_fn (tree, enum tree_code, tree);
+static void store_parm_decls (tree);
+static int cp_missing_noreturn_ok_p (tree);
static void initialize_local_var (tree, tree);
static void expand_static_init (tree, tree);
static tree next_initializable_field (tree);
static tree reshape_init (tree, tree *);
+static tree build_typename_type (tree, tree, tree);
/* Erroneous argument lists can use this *IFF* they do not modify it. */
tree error_mark_list;
@@ -168,7 +140,7 @@ tree error_mark_list;
tree ptm_desc_type_node;
tree base_desc_type_node;
- tree class_type_node, record_type_node, union_type_node, enum_type_node;
+ tree class_type_node;
tree unknown_type_node;
Array type `vtable_entry_type[]'
@@ -202,10 +174,10 @@ tree cp_global_trees[CPTI_MAX];
/* Indicates that there is a type value in some namespace, although
that is not necessarily in scope at the moment. */
-static GTY(()) tree global_type_node;
+tree global_type_node;
-/* Expect only namespace names now. */
-static int only_namespace_names;
+/* The node that holds the "name" of the global scope. */
+tree global_scope_name;
/* Used only for jumps to as-yet undefined labels, since jumps to
defined labels can have their validity checked immediately. */
@@ -215,8 +187,7 @@ struct named_label_use_list GTY(())
struct cp_binding_level *binding_level;
tree names_in_scope;
tree label_decl;
- const char *filename_o_goto;
- int lineno_o_goto;
+ location_t o_goto_locus;
struct named_label_use_list *next;
};
@@ -236,9 +207,6 @@ tree static_aggregates;
tree integer_two_node, integer_three_node;
-/* Similar, for last_function_parm_tags. */
-tree last_function_parms;
-
/* A list of all LABEL_DECLs in the function that have names. Here so
we can clear out their names' definitions at the end of the
function, and so we can check the validity of jumps to these labels. */
@@ -257,10 +225,6 @@ struct named_label_list GTY(())
#define named_labels cp_function_chain->x_named_labels
-/* The name of the anonymous namespace, throughout this translation
- unit. */
-tree anonymous_namespace_name;
-
/* The number of function bodies which we are currently processing.
(Zero if we are at namespace scope, one inside the body of a
function, two inside the body of a function in a local class, etc.) */
@@ -288,670 +252,18 @@ int adding_implicit_members = 0;
bool have_extern_spec;
-/* Compute the chain index of a binding_entry given the HASH value of its
- name and the total COUNT of chains. COUNT is assumed to be a power
- of 2. */
-#define ENTRY_INDEX(HASH, COUNT) (((HASH) >> 3) & ((COUNT) - 1))
-
-/* A free list of "binding_entry"s awaiting for re-use. */
-static GTY((deletable(""))) binding_entry free_binding_entry;
-
-/* Create a binding_entry object for (NAME, TYPE). */
-static inline binding_entry
-binding_entry_make (tree name, tree type)
-{
- binding_entry entry;
-
- if (free_binding_entry)
- {
- entry = free_binding_entry;
- free_binding_entry = entry->chain;
- }
- else
- entry = ggc_alloc (sizeof (struct binding_entry_s));
-
- entry->name = name;
- entry->type = type;
-
- return entry;
-}
-
-/* Put ENTRY back on the free list. */
-static inline void
-binding_entry_free (binding_entry entry)
-{
- entry->chain = free_binding_entry;
- free_binding_entry = entry;
-}
-
-/* The datatype used to implement the mapping from names to types at
- a given scope. */
-struct binding_table_s GTY(())
-{
- /* Array of chains of "binding_entry"s */
- binding_entry * GTY((length ("%h.chain_count"))) chain;
-
- /* The number of chains in this table. This is the length of the
- the member "chaiin" considered as an array. */
- size_t chain_count;
-
- /* Number of "binding_entry"s in this table. */
- size_t entry_count;
-};
-
-/* These macros indicate the initial chains count for binding_table. */
-#define SCOPE_DEFAULT_HT_SIZE (1 << 3)
-#define CLASS_SCOPE_HT_SIZE (1 << 3)
-#define NAMESPACE_ORDINARY_HT_SIZE (1 << 5)
-#define NAMESPACE_STD_HT_SIZE (1 << 8)
-#define GLOBAL_SCOPE_HT_SIZE (1 << 8)
-
-/* Construct TABLE with an initial CHAIN_COUNT. */
-static inline void
-binding_table_construct (binding_table table, size_t chain_count)
-{
- table->chain_count = chain_count;
- table->entry_count = 0;
- table->chain = ggc_alloc_cleared
- (table->chain_count * sizeof (binding_entry));
-}
-
-/* Free TABLE by making its entries ready for reuse. */
-static inline void
-binding_table_free (binding_table table)
-{
- size_t i;
- if (table == NULL)
- return;
-
- for (i = 0; i < table->chain_count; ++i)
- {
- while (table->chain[i] != NULL)
- {
- binding_entry entry = table->chain[i];
- table->chain[i] = entry->chain;
- binding_entry_free (entry);
- }
- }
- table->entry_count = 0;
-}
-
-/* Allocate a table with CHAIN_COUNT, assumed to be a power of two. */
-static inline binding_table
-binding_table_new (size_t chain_count)
-{
- binding_table table = ggc_alloc (sizeof (struct binding_table_s));
- binding_table_construct (table, chain_count);
- return table;
-}
-
-/* Expand TABLE to twice its current chain_count. */
-static void
-binding_table_expand (binding_table table)
-{
- const size_t old_chain_count = table->chain_count;
- const size_t old_entry_count = table->entry_count;
- const size_t new_chain_count = 2 * old_chain_count;
- binding_entry *old_chains = table->chain;
- size_t i;
-
- binding_table_construct (table, new_chain_count);
- for (i = 0; i < old_chain_count; ++i)
- {
- binding_entry entry = old_chains[i];
- for (; entry != NULL; entry = old_chains[i])
- {
- const unsigned int hash = IDENTIFIER_HASH_VALUE (entry->name);
- const size_t j = ENTRY_INDEX (hash, new_chain_count);
-
- old_chains[i] = entry->chain;
- entry->chain = table->chain[j];
- table->chain[j] = entry;
- }
- }
- table->entry_count = old_entry_count;
-}
-
-/* Insert a binding for NAME to TYPe into TABLE. */
-static inline void
-binding_table_insert (binding_table table, tree name, tree type)
-{
- const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
- const size_t i = ENTRY_INDEX (hash, table->chain_count);
- binding_entry entry = binding_entry_make (name, type);
-
- entry->chain = table->chain[i];
- table->chain[i] = entry;
- ++table->entry_count;
-
- if (3 * table->chain_count < 5 * table->entry_count)
- binding_table_expand (table);
-}
-
-/* Return the binding_entry, if any, that maps NAME. */
-binding_entry
-binding_table_find (binding_table table, tree name)
-{
- const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
- binding_entry entry = table->chain[ENTRY_INDEX (hash, table->chain_count)];
-
- while (entry != NULL && entry->name != name)
- entry = entry->chain;
-
- return entry;
-}
-
-/* Return the binding_entry, if any, that maps name to an anonymous type. */
-static inline tree
-binding_table_find_anon_type (binding_table table, tree name)
-{
- const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
- binding_entry entry = table->chain[ENTRY_INDEX (hash, table->chain_count)];
-
- while (entry != NULL && TYPE_IDENTIFIER (entry->type) != name)
- entry = entry->chain;
-
- return entry ? entry->type : NULL;
-}
-
-/* Return the binding_entry, if any, that has TYPE as target. If NAME
- is non-null, then set the domain and rehash that entry. */
-static inline binding_entry
-binding_table_reverse_maybe_remap (binding_table table, tree type, tree name)
-{
- const size_t chain_count = table->chain_count;
- binding_entry entry = NULL;
- binding_entry *p = NULL;
- size_t i;
-
- for (i = 0; i < chain_count && entry == NULL; ++i)
- {
- p = &table->chain[i];
- while (*p != NULL && entry == NULL)
- if ((*p)->type == type)
- entry = *p;
- else
- p = &(*p)->chain;
- }
-
- if (entry != NULL && name != NULL && entry->name != name)
- {
- /* Remove the bucket from the previous chain. */
- *p = (*p)->chain;
-
- /* Remap the name type to type. */
- i = ENTRY_INDEX (IDENTIFIER_HASH_VALUE (name), chain_count);
- entry->chain = table->chain[i];
- entry->name = name;
- table->chain[i] = entry;
- }
-
- return entry;
-}
-
-/* Remove from TABLE all entries that map to anonymous enums or
- class-types. */
-static void
-binding_table_remove_anonymous_types (binding_table table)
-{
- const size_t chain_count = table->chain_count;
- size_t i;
-
- for (i = 0; i < chain_count; ++i)
- {
- binding_entry *p = &table->chain[i];
-
- while (*p != NULL)
- if (ANON_AGGRNAME_P ((*p)->name))
- {
- binding_entry e = *p;
- *p = (*p)->chain;
- --table->entry_count;
- binding_entry_free (e);
- }
- else
- p = &(*p)->chain;
- }
-}
-
-/* Apply PROC -- with DATA -- to all entries in TABLE. */
-void
-binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
-{
- const size_t chain_count = table->chain_count;
- size_t i;
-
- for (i = 0; i < chain_count; ++i)
- {
- binding_entry entry = table->chain[i];
- for (; entry != NULL; entry = entry->chain)
- proc (entry, data);
- }
-}
-
-
-/* For each binding contour we allocate a binding_level structure
- which records the names defined in that contour.
- Contours include:
- 0) the global one
- 1) one for each function definition,
- where internal declarations of the parameters appear.
- 2) one for each compound statement,
- to record its declarations.
-
- The current meaning of a name can be found by searching the levels
- from the current one out to the global one.
-
- Off to the side, may be the class_binding_level. This exists only
- to catch class-local declarations. It is otherwise nonexistent.
-
- Also there may be binding levels that catch cleanups that must be
- run when exceptions occur. Thus, to see whether a name is bound in
- the current scope, it is not enough to look in the
- CURRENT_BINDING_LEVEL. You should use lookup_name_current_level
- instead. */
-
-/* Note that the information in the `names' component of the global contour
- is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
-
-struct cp_binding_level GTY(())
- {
- /* A chain of _DECL nodes for all variables, constants, functions,
- and typedef types. These are in the reverse of the order
- supplied. There may be OVERLOADs on this list, too, but they
- are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */
- tree names;
-
- /* Count of elements in names chain. */
- size_t names_size;
-
- /* A chain of NAMESPACE_DECL nodes. */
- tree namespaces;
-
- /* An array of static functions and variables (for namespaces only) */
- varray_type static_decls;
-
- /* A chain of VTABLE_DECL nodes. */
- tree vtables;
-
- /* A dictionary for looking up enums or class-types names. */
- binding_table type_decls;
-
- /* A list of USING_DECL nodes. */
- tree usings;
-
- /* A list of used namespaces. PURPOSE is the namespace,
- VALUE the common ancestor with this binding_level's namespace. */
- tree using_directives;
-
- /* If this binding level is the binding level for a class, then
- class_shadowed is a TREE_LIST. The TREE_PURPOSE of each node
- is the name of an entity bound in the class. The TREE_TYPE is
- the DECL bound by this name in the class. */
- tree class_shadowed;
-
- /* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and
- is used for all binding levels. In addition the TREE_VALUE is the
- IDENTIFIER_TYPE_VALUE before we entered the class. */
- tree type_shadowed;
-
- /* A TREE_LIST. Each TREE_VALUE is the LABEL_DECL for a local
- label in this scope. The TREE_PURPOSE is the previous value of
- the IDENTIFIER_LABEL VALUE. */
- tree shadowed_labels;
-
- /* For each level (except not the global one),
- a chain of BLOCK nodes for all the levels
- that were entered and exited one level down. */
- tree blocks;
-
- /* The _TYPE node for this level, if parm_flag == 2. */
- tree this_class;
-
- /* The binding level which this one is contained in (inherits from). */
- struct cp_binding_level *level_chain;
-
- /* List of VAR_DECLS saved from a previous for statement.
- These would be dead in ISO-conforming code, but might
- be referenced in ARM-era code. These are stored in a
- TREE_LIST; the TREE_VALUE is the actual declaration. */
- tree dead_vars_from_for;
-
- /* 1 for the level that holds the parameters of a function.
- 2 for the level that holds a class declaration. */
- unsigned parm_flag : 2;
-
- /* 1 means make a BLOCK for this level regardless of all else.
- 2 for temporary binding contours created by the compiler. */
- unsigned keep : 2;
-
- /* Nonzero if this level "doesn't exist" for tags. */
- unsigned tag_transparent : 1;
-
- /* Nonzero if this level can safely have additional
- cleanup-needing variables added to it. */
- unsigned more_cleanups_ok : 1;
- unsigned have_cleanups : 1;
-
- /* Nonzero if this scope is for storing the decls for template
- parameters and generic decls; these decls will be discarded and
- replaced with a TEMPLATE_DECL. */
- unsigned template_parms_p : 1;
-
- /* Nonzero if this scope corresponds to the `<>' in a
- `template <>' clause. Whenever this flag is set,
- TEMPLATE_PARMS_P will be set as well. */
- unsigned template_spec_p : 1;
-
- /* This is set for a namespace binding level. */
- unsigned namespace_p : 1;
-
- /* True if this level is that of a for-statement where we need to
- worry about ambiguous (ARM or ISO) scope rules. */
- unsigned is_for_scope : 1;
-
- /* True if this level corresponds to a TRY block. Currently this
- information is only available while building the tree structure. */
- unsigned is_try_scope : 1;
-
- /* True if this level corresponds to a CATCH block. Currently this
- information is only available while building the tree structure. */
- unsigned is_catch_scope : 1;
-
- /* Three bits left for this word. */
-
- /* Binding depth at which this level began. */
- unsigned binding_depth;
- };
-
-#define NULL_BINDING_LEVEL ((struct cp_binding_level *) NULL)
-
-/* True if SCOPE designates the global scope binding contour. */
-#define global_scope_p(SCOPE) \
- ((SCOPE) == NAMESPACE_LEVEL (global_namespace))
-
-/* The binding level currently in effect. */
-
-#define current_binding_level \
- (cfun && cp_function_chain->bindings \
- ? cp_function_chain->bindings \
- : scope_chain->bindings)
-
-/* The binding level of the current class, if any. */
-
-#define class_binding_level scope_chain->class_bindings
-
-/* A chain of binding_level structures awaiting reuse. */
-
-static GTY((deletable (""))) struct cp_binding_level *free_binding_level;
-
-/* Nonzero means unconditionally make a BLOCK for the next level pushed. */
-
-static int keep_next_level_flag;
-
/* A TREE_LIST of VAR_DECLs. The TREE_PURPOSE is a RECORD_TYPE or
UNION_TYPE; the TREE_VALUE is a VAR_DECL with that type. At the
time the VAR_DECL was declared, the type was incomplete. */
static GTY(()) tree incomplete_vars;
-
-#ifndef ENABLE_SCOPE_CHECKING
-# define ENABLE_SCOPE_CHECKING 0
-#else
-# define ENABLE_SCOPE_CHECKING 1
-#endif
-
-static unsigned binding_depth = 0;
-static int is_class_level = 0;
-
-static void
-indent (unsigned depth)
-{
- unsigned i;
-
- for (i = 0; i < depth * 2; i++)
- putc (' ', stderr);
-}
-
-static tree pushdecl_with_scope PARAMS ((tree, struct cp_binding_level *));
-
-static void
-push_binding_level (newlevel, tag_transparent, keep)
- struct cp_binding_level *newlevel;
- int tag_transparent, keep;
-{
- /* Add this level to the front of the chain (stack) of levels that
- are active. */
- memset ((char*) newlevel, 0, sizeof (struct cp_binding_level));
- newlevel->level_chain = current_binding_level;
- current_binding_level = newlevel;
- newlevel->tag_transparent = tag_transparent;
- newlevel->more_cleanups_ok = 1;
-
- newlevel->keep = keep;
- if (ENABLE_SCOPE_CHECKING)
- {
- newlevel->binding_depth = binding_depth;
- indent (binding_depth);
- verbatim ("push %s level %p line %d\n",
- (is_class_level) ? "class" : "block",
- (void *) newlevel, lineno);
- is_class_level = 0;
- binding_depth++;
- }
-}
-
-/* Find the innermost enclosing class scope, and reset
- CLASS_BINDING_LEVEL appropriately. */
-
-static void
-find_class_binding_level ()
-{
- struct cp_binding_level *level = current_binding_level;
-
- while (level && level->parm_flag != 2)
- level = level->level_chain;
- if (level && level->parm_flag == 2)
- class_binding_level = level;
- else
- class_binding_level = 0;
-}
-
-static void
-pop_binding_level ()
-{
- if (NAMESPACE_LEVEL (global_namespace))
- /* Cannot pop a level, if there are none left to pop. */
- my_friendly_assert (!global_scope_p (current_binding_level), 20030527);
- /* Pop the current level, and free the structure for reuse. */
- if (ENABLE_SCOPE_CHECKING)
- {
- indent (--binding_depth);
- verbatim ("pop %s level %p line %d\n",
- (is_class_level) ? "class" : "block",
- (void *) current_binding_level, lineno);
- if (is_class_level != (current_binding_level == class_binding_level))
- {
- indent (binding_depth);
- verbatim ("XXX is_class_level != (current_binding_level "
- "== class_binding_level)\n");
- }
- is_class_level = 0;
- }
- {
- register struct cp_binding_level *level = current_binding_level;
- current_binding_level = current_binding_level->level_chain;
- level->level_chain = free_binding_level;
- if (level->parm_flag != 2)
- binding_table_free (level->type_decls);
- else
- level->type_decls = NULL;
- my_friendly_assert (!ENABLE_SCOPE_CHECKING
- || level->binding_depth == binding_depth, 20030529);
- free_binding_level = level;
- find_class_binding_level ();
- }
-}
-
-static void
-suspend_binding_level ()
-{
- if (class_binding_level)
- current_binding_level = class_binding_level;
-
- if (NAMESPACE_LEVEL (global_namespace))
- my_friendly_assert (!global_scope_p (current_binding_level), 20030527);
- /* Suspend the current level. */
- if (ENABLE_SCOPE_CHECKING)
- {
- indent (--binding_depth);
- verbatim("suspend %s level %p line %d\n",
- (is_class_level) ? "class" : "block",
- (void *) current_binding_level, lineno);
- if (is_class_level != (current_binding_level == class_binding_level))
- {
- indent (binding_depth);
- verbatim ("XXX is_class_level != (current_binding_level "
- "== class_binding_level)\n");
- }
- is_class_level = 0;
- }
- current_binding_level = current_binding_level->level_chain;
- find_class_binding_level ();
-}
-
-static void
-resume_binding_level (b)
- struct cp_binding_level *b;
-{
- /* Resuming binding levels is meant only for namespaces,
- and those cannot nest into classes. */
- my_friendly_assert(!class_binding_level, 386);
- /* Also, resuming a non-directly nested namespace is a no-no. */
- my_friendly_assert(b->level_chain == current_binding_level, 386);
- current_binding_level = b;
- if (ENABLE_SCOPE_CHECKING)
- {
- b->binding_depth = binding_depth;
- indent (binding_depth);
- verbatim ("resume %s level %p line %d\n",
- (is_class_level) ? "class" : "block", (void *) b, lineno);
- is_class_level = 0;
- binding_depth++;
- }
-}
-/* Create a new `struct cp_binding_level'. */
-
-static
-struct cp_binding_level *
-make_binding_level ()
-{
- /* NOSTRICT */
- return (struct cp_binding_level *) ggc_alloc (sizeof (struct cp_binding_level));
-}
-
-/* Nonzero if we are currently in the global binding level. */
-
-int
-global_bindings_p ()
-{
- return global_scope_p (current_binding_level);
-}
-
-/* Return the innermost binding level that is not for a class scope. */
-
-static struct cp_binding_level *
-innermost_nonclass_level ()
-{
- struct cp_binding_level *b;
-
- b = current_binding_level;
- while (b->parm_flag == 2)
- b = b->level_chain;
-
- return b;
-}
-
-/* Nonzero if we are currently in a toplevel binding level. This
- means either the global binding level or a namespace in a toplevel
- binding level. Since there are no non-toplevel namespace levels,
- this really means any namespace or template parameter level. We
- also include a class whose context is toplevel. */
-
-int
-toplevel_bindings_p ()
-{
- struct cp_binding_level *b = innermost_nonclass_level ();
-
- return b->namespace_p || b->template_parms_p;
-}
-
-/* Nonzero if this is a namespace scope, or if we are defining a class
- which is itself at namespace scope, or whose enclosing class is
- such a class, etc. */
-
-int
-namespace_bindings_p ()
-{
- struct cp_binding_level *b = innermost_nonclass_level ();
-
- return b->namespace_p;
-}
-
-/* If KEEP is nonzero, make a BLOCK node for the next binding level,
- unconditionally. Otherwise, use the normal logic to decide whether
- or not to create a BLOCK. */
-
-void
-keep_next_level (keep)
- int keep;
-{
- keep_next_level_flag = keep;
-}
-
-/* Nonzero if the current level needs to have a BLOCK made. */
-
-int
-kept_level_p ()
-{
- return (current_binding_level->blocks != NULL_TREE
- || current_binding_level->keep
- || current_binding_level->names != NULL_TREE
- || (current_binding_level->type_decls != NULL
- && !current_binding_level->tag_transparent));
-}
-
-/* Returns the kind of the innermost scope. */
-
-bool
-innermost_scope_is_class_p ()
-{
- return current_binding_level->parm_flag == 2;
-}
-
-static void
-declare_namespace_level ()
-{
- current_binding_level->namespace_p = 1;
-}
-
-/* Returns nonzero if this scope was created to store template
- parameters. */
-
-int
-template_parm_scope_p ()
-{
- return current_binding_level->template_parms_p;
-}
-
/* Returns the kind of template specialization we are currently
processing, given that it's declaration contained N_CLASS_SCOPES
explicit scope qualifications. */
tmpl_spec_kind
-current_tmpl_spec_kind (n_class_scopes)
- int n_class_scopes;
+current_tmpl_spec_kind (int n_class_scopes)
{
int n_template_parm_scopes = 0;
int seen_specialization_p = 0;
@@ -959,7 +271,9 @@ current_tmpl_spec_kind (n_class_scopes)
struct cp_binding_level *b;
/* Scan through the template parameter scopes. */
- for (b = current_binding_level; b->template_parms_p; b = b->level_chain)
+ for (b = current_binding_level;
+ b->kind == sk_template_parms;
+ b = b->level_chain)
{
/* If we see a specialization scope inside a parameter scope,
then something is wrong. That corresponds to a declaration
@@ -970,7 +284,7 @@ current_tmpl_spec_kind (n_class_scopes)
which is always invalid since [temp.expl.spec] forbids the
specialization of a class member template if the enclosing
class templates are not explicitly specialized as well. */
- if (b->template_spec_p)
+ if (b->explicit_spec_p)
{
if (n_template_parm_scopes == 0)
innermost_specialization_p = 1;
@@ -1034,439 +348,31 @@ current_tmpl_spec_kind (n_class_scopes)
return innermost_specialization_p ? tsk_expl_spec : tsk_template;
}
-void
-set_class_shadows (shadows)
- tree shadows;
-{
- class_binding_level->class_shadowed = shadows;
-}
-
-/* Enter a new binding level.
- If TAG_TRANSPARENT is nonzero, do so only for the name space of variables,
- not for that of tags. */
-
-void
-pushlevel (tag_transparent)
- int tag_transparent;
-{
- struct cp_binding_level *newlevel;
-
- if (cfun && !doing_semantic_analysis_p ())
- return;
-
- /* Reuse or create a struct for this binding level. */
- if (!ENABLE_SCOPE_CHECKING && free_binding_level)
- {
- newlevel = free_binding_level;
- free_binding_level = free_binding_level->level_chain;
- }
- else
- newlevel = make_binding_level ();
-
- push_binding_level (newlevel, tag_transparent, keep_next_level_flag);
- keep_next_level_flag = 0;
-}
-
-/* We're defining an object of type TYPE. If it needs a cleanup, but
- we're not allowed to add any more objects with cleanups to the current
- scope, create a new binding level. */
-
-void
-maybe_push_cleanup_level (type)
- tree type;
-{
- if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
- && current_binding_level->more_cleanups_ok == 0)
- {
- keep_next_level (2);
- pushlevel (1);
- clear_last_expr ();
- add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
- }
-}
-
-/* Enter a new scope. The KIND indicates what kind of scope is being
- created. */
-
-void
-begin_scope (sk)
- scope_kind sk;
-{
- pushlevel (0);
-
- switch (sk)
- {
- case sk_template_spec:
- current_binding_level->template_spec_p = 1;
- /* Fall through. */
-
- case sk_template_parms:
- current_binding_level->template_parms_p = 1;
- break;
-
- default:
- abort ();
- }
-}
-
/* Exit the current scope. */
void
-finish_scope ()
+finish_scope (void)
{
poplevel (0, 0, 0);
}
-void
-note_level_for_for ()
-{
- current_binding_level->is_for_scope = 1;
-}
-
-/* Record that the current binding level represents a try block. */
-
-void
-note_level_for_try ()
-{
- current_binding_level->is_try_scope = 1;
-}
-
-/* Record that the current binding level represents a catch block. */
-
-void
-note_level_for_catch ()
-{
- current_binding_level->is_catch_scope = 1;
-}
-
-/* For a binding between a name and an entity at a block scope,
- this is the `struct cp_binding_level' for the block. */
-#define BINDING_LEVEL(NODE) ((NODE)->scope.level)
-
-/* A free list of "cxx_binding"s, connected by their PREVIOUS. */
-
-static GTY((deletable (""))) cxx_binding *free_bindings;
-
-/* Make DECL the innermost binding for ID. The LEVEL is the binding
- level at which this declaration is being bound. */
-
-static void
-push_binding (id, decl, level)
- tree id;
- tree decl;
- struct cp_binding_level* level;
-{
- cxx_binding *binding;
-
- if (free_bindings)
- {
- binding = free_bindings;
- free_bindings = binding->previous;
- }
- else
- binding = cxx_binding_make ();
-
- /* Now, fill in the binding information. */
- BINDING_VALUE (binding) = decl;
- BINDING_TYPE (binding) = NULL_TREE;
- BINDING_LEVEL (binding) = level;
- INHERITED_VALUE_BINDING_P (binding) = 0;
- LOCAL_BINDING_P (binding) = (level != class_binding_level);
- BINDING_HAS_LEVEL_P (binding) = 1;
-
- /* And put it on the front of the list of bindings for ID. */
- binding->previous = IDENTIFIER_BINDING (id);
- IDENTIFIER_BINDING (id) = binding;
-}
-
-/* ID is already bound in the current scope. But, DECL is an
- additional binding for ID in the same scope. This is the `struct
- stat' hack whereby a non-typedef class-name or enum-name can be
- bound at the same level as some other kind of entity. It's the
- responsibility of the caller to check that inserting this name is
- valid here. Returns nonzero if the new binding was successful. */
-static int
-add_binding (id, decl)
- tree id;
- tree decl;
-{
- cxx_binding *binding = IDENTIFIER_BINDING (id);
- int ok = 1;
-
- timevar_push (TV_NAME_LOOKUP);
- if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
- /* The new name is the type name. */
- BINDING_TYPE (binding) = decl;
- else if (!BINDING_VALUE (binding))
- /* This situation arises when push_class_level_binding moves an
- inherited type-binding out of the way to make room for a new
- value binding. */
- BINDING_VALUE (binding) = decl;
- else if (TREE_CODE (BINDING_VALUE (binding)) == TYPE_DECL
- && DECL_ARTIFICIAL (BINDING_VALUE (binding)))
- {
- /* The old binding was a type name. It was placed in
- BINDING_VALUE because it was thought, at the point it was
- declared, to be the only entity with such a name. Move the
- type name into the type slot; it is now hidden by the new
- binding. */
- BINDING_TYPE (binding) = BINDING_VALUE (binding);
- BINDING_VALUE (binding) = decl;
- INHERITED_VALUE_BINDING_P (binding) = 0;
- }
- else if (TREE_CODE (BINDING_VALUE (binding)) == TYPE_DECL
- && TREE_CODE (decl) == TYPE_DECL
- && DECL_NAME (decl) == DECL_NAME (BINDING_VALUE (binding))
- && (same_type_p (TREE_TYPE (decl),
- TREE_TYPE (BINDING_VALUE (binding)))
- /* If either type involves template parameters, we must
- wait until instantiation. */
- || uses_template_parms (TREE_TYPE (decl))
- || uses_template_parms (TREE_TYPE (BINDING_VALUE (binding)))))
- /* We have two typedef-names, both naming the same type to have
- the same name. This is OK because of:
-
- [dcl.typedef]
-
- In a given scope, a typedef specifier can be used to redefine
- the name of any type declared in that scope to refer to the
- type to which it already refers. */
- ok = 0;
- /* There can be two block-scope declarations of the same variable,
- so long as they are `extern' declarations. However, there cannot
- be two declarations of the same static data member:
-
- [class.mem]
-
- A member shall not be declared twice in the
- member-specification. */
- else if (TREE_CODE (decl) == VAR_DECL
- && TREE_CODE (BINDING_VALUE (binding)) == VAR_DECL
- && DECL_EXTERNAL (decl)
- && DECL_EXTERNAL (BINDING_VALUE (binding))
- && !DECL_CLASS_SCOPE_P (decl))
- {
- duplicate_decls (decl, BINDING_VALUE (binding));
- ok = 0;
- }
- else
- {
- error ("declaration of `%#D'", decl);
- cp_error_at ("conflicts with previous declaration `%#D'",
- BINDING_VALUE (binding));
- ok = 0;
- }
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
-}
-
-/* Add DECL to the list of things declared in B. */
-
-static void
-add_decl_to_level (decl, b)
- tree decl;
- struct cp_binding_level *b;
-{
- if (TREE_CODE (decl) == NAMESPACE_DECL
- && !DECL_NAMESPACE_ALIAS (decl))
- {
- TREE_CHAIN (decl) = b->namespaces;
- b->namespaces = decl;
- }
- else if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
- {
- TREE_CHAIN (decl) = b->vtables;
- b->vtables = decl;
- }
- else
- {
- /* We build up the list in reverse order, and reverse it later if
- necessary. */
- TREE_CHAIN (decl) = b->names;
- b->names = decl;
- b->names_size++;
-
- /* If appropriate, add decl to separate list of statics */
- if (b->namespace_p)
- if ((TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
- || (TREE_CODE (decl) == FUNCTION_DECL
- && (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl))))
- VARRAY_PUSH_TREE (b->static_decls, decl);
- }
-}
-
-/* Bind DECL to ID in the current_binding_level, assumed to be a local
- binding level. If PUSH_USING is set in FLAGS, we know that DECL
- doesn't really belong to this binding level, that it got here
- through a using-declaration. */
-
-void
-push_local_binding (id, decl, flags)
- tree id;
- tree decl;
- int flags;
-{
- struct cp_binding_level *b;
-
- /* Skip over any local classes. This makes sense if we call
- push_local_binding with a friend decl of a local class. */
- b = current_binding_level;
- while (b->parm_flag == 2)
- b = b->level_chain;
-
- if (lookup_name_current_level (id))
- {
- /* Supplement the existing binding. */
- if (!add_binding (id, decl))
- /* It didn't work. Something else must be bound at this
- level. Do not add DECL to the list of things to pop
- later. */
- return;
- }
- else
- /* Create a new binding. */
- push_binding (id, decl, b);
-
- if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING))
- /* We must put the OVERLOAD into a TREE_LIST since the
- TREE_CHAIN of an OVERLOAD is already used. Similarly for
- decls that got here through a using-declaration. */
- decl = build_tree_list (NULL_TREE, decl);
-
- /* And put DECL on the list of things declared by the current
- binding level. */
- add_decl_to_level (decl, b);
-}
-
-/* Bind DECL to ID in the class_binding_level. Returns nonzero if the
- binding was successful. */
-
-int
-push_class_binding (id, decl)
- tree id;
- tree decl;
-{
- int result = 1;
- cxx_binding *binding = IDENTIFIER_BINDING (id);
- tree context;
-
- timevar_push (TV_NAME_LOOKUP);
- /* Note that we declared this value so that we can issue an error if
- this is an invalid redeclaration of a name already used for some
- other purpose. */
- note_name_declared_in_class (id, decl);
-
- if (binding && BINDING_LEVEL (binding) == class_binding_level)
- /* Supplement the existing binding. */
- result = add_binding (id, decl);
- else
- /* Create a new binding. */
- push_binding (id, decl, class_binding_level);
-
- /* Update the IDENTIFIER_CLASS_VALUE for this ID to be the
- class-level declaration. Note that we do not use DECL here
- because of the possibility of the `struct stat' hack; if DECL is
- a class-name or enum-name we might prefer a field-name, or some
- such. */
- IDENTIFIER_CLASS_VALUE (id) = BINDING_VALUE (IDENTIFIER_BINDING (id));
-
- /* If this is a binding from a base class, mark it as such. */
- binding = IDENTIFIER_BINDING (id);
- if (BINDING_VALUE (binding) == decl && TREE_CODE (decl) != TREE_LIST)
- {
- /* Any implicit typename must be from a base-class. The
- context for an implicit typename declaration is always
- the derived class in which the lookup was done, so the checks
- based on the context of DECL below will not trigger. */
- if (IMPLICIT_TYPENAME_TYPE_DECL_P (decl))
- INHERITED_VALUE_BINDING_P (binding) = 1;
- else
- {
- if (TREE_CODE (decl) == OVERLOAD)
- context = CP_DECL_CONTEXT (OVL_CURRENT (decl));
- else
- {
- my_friendly_assert (DECL_P (decl), 0);
- context = context_for_name_lookup (decl);
- }
-
- if (is_properly_derived_from (current_class_type, context))
- INHERITED_VALUE_BINDING_P (binding) = 1;
- else
- INHERITED_VALUE_BINDING_P (binding) = 0;
- }
- }
- else if (BINDING_VALUE (binding) == decl)
- /* We only encounter a TREE_LIST when push_class_decls detects an
- ambiguity. Such an ambiguity can be overridden by a definition
- in this class. */
- INHERITED_VALUE_BINDING_P (binding) = 1;
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result);
-}
-
-/* Remove the binding for DECL which should be the innermost binding
- for ID. */
-
-static void
-pop_binding (id, decl)
- tree id;
- tree decl;
-{
- cxx_binding *binding;
-
- if (id == NULL_TREE)
- /* It's easiest to write the loops that call this function without
- checking whether or not the entities involved have names. We
- get here for such an entity. */
- return;
-
- /* Get the innermost binding for ID. */
- binding = IDENTIFIER_BINDING (id);
-
- /* The name should be bound. */
- my_friendly_assert (binding != NULL, 0);
-
- /* The DECL will be either the ordinary binding or the type
- binding for this identifier. Remove that binding. */
- if (BINDING_VALUE (binding) == decl)
- BINDING_VALUE (binding) = NULL_TREE;
- else if (BINDING_TYPE (binding) == decl)
- BINDING_TYPE (binding) = NULL_TREE;
- else
- abort ();
-
- if (!BINDING_VALUE (binding) && !BINDING_TYPE (binding))
- {
- /* We're completely done with the innermost binding for this
- identifier. Unhook it from the list of bindings. */
- IDENTIFIER_BINDING (id) = binding->previous;
-
- /* Add it to the free list. */
- binding->previous = free_bindings;
- free_bindings = binding;
-
- /* Clear the BINDING_LEVEL so the garbage collector doesn't walk
- it. */
- BINDING_LEVEL (binding) = NULL;
- }
-}
-
/* When a label goes out of scope, check to see if that label was used
in a valid manner, and issue any appropriate warnings or errors. */
static void
-pop_label (label, old_value)
- tree label;
- tree old_value;
+pop_label (tree label, tree old_value)
{
- if (!processing_template_decl && doing_semantic_analysis_p ())
+ if (!processing_template_decl)
{
if (DECL_INITIAL (label) == NULL_TREE)
{
+ location_t location;
+
cp_error_at ("label `%D' used but not defined", label);
+ location.file = input_filename;
+ location.line = 0;
/* Avoid crashing later. */
- define_label (input_filename, 1, DECL_NAME (label));
+ define_label (location, DECL_NAME (label));
}
else if (warn_unused_label && !TREE_USED (label))
cp_warning_at ("label `%D' defined but not used", label);
@@ -1480,8 +386,7 @@ pop_label (label, old_value)
function. */
static void
-pop_labels (block)
- tree block;
+pop_labels (tree block)
{
struct named_label_list *link;
@@ -1515,12 +420,9 @@ pop_labels (block)
them into the BLOCK. */
tree
-poplevel (keep, reverse, functionbody)
- int keep;
- int reverse;
- int functionbody;
+poplevel (int keep, int reverse, int functionbody)
{
- register tree link;
+ tree link;
/* The chain of decls was accumulated in reverse order.
Put it into forward order, just for cleanliness. */
tree decls;
@@ -1530,16 +432,13 @@ poplevel (keep, reverse, functionbody)
tree block = NULL_TREE;
tree decl;
int leaving_for_scope;
+ scope_kind kind;
timevar_push (TV_NAME_LOOKUP);
- if (cfun && !doing_semantic_analysis_p ())
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ my_friendly_assert (current_binding_level->kind != sk_class, 19990916);
- my_friendly_assert (current_binding_level->parm_flag != 2,
- 19990916);
-
- real_functionbody = (current_binding_level->keep == 2
+ real_functionbody = (current_binding_level->kind == sk_cleanup
? ((functionbody = 0), tmp) : functionbody);
subblocks = functionbody >= 0 ? current_binding_level->blocks : 0;
@@ -1551,7 +450,7 @@ poplevel (keep, reverse, functionbody)
rather than the end. This hack is no longer used. */
my_friendly_assert (keep == 0 || keep == 1, 0);
- if (current_binding_level->keep == 1)
+ if (current_binding_level->keep)
keep = 1;
/* Any uses of undefined labels, and any defined labels, now operate
@@ -1568,9 +467,9 @@ poplevel (keep, reverse, functionbody)
if (labels->binding_level == current_binding_level)
{
tree decl;
- if (current_binding_level->is_try_scope)
+ if (current_binding_level->kind == sk_try)
labels->in_try_scope = 1;
- if (current_binding_level->is_catch_scope)
+ if (current_binding_level->kind == sk_catch)
labels->in_catch_scope = 1;
for (decl = labels->names_in_scope; decl;
decl = TREE_CHAIN (decl))
@@ -1649,10 +548,10 @@ poplevel (keep, reverse, functionbody)
/* We still support the old for-scope rules, whereby the variables
in a for-init statement were in scope after the for-statement
- ended. We only use the new rules in flag_new_for_scope is
+ ended. We only use the new rules if flag_new_for_scope is
nonzero. */
leaving_for_scope
- = current_binding_level->is_for_scope && flag_new_for_scope == 1;
+ = current_binding_level->kind == sk_for && flag_new_for_scope == 1;
/* Remove declarations for all the DECLs in this level. */
for (link = decls; link; link = TREE_CHAIN (link))
@@ -1670,8 +569,7 @@ poplevel (keep, reverse, functionbody)
ns_binding = NULL_TREE;
if (outer_binding
- && (BINDING_LEVEL (outer_binding)
- == current_binding_level->level_chain))
+ && outer_binding->scope == current_binding_level->level_chain)
/* We have something like:
int i;
@@ -1681,10 +579,8 @@ poplevel (keep, reverse, functionbody)
keep the binding of the inner `i' in this case. */
pop_binding (DECL_NAME (link), link);
else if ((outer_binding
- && (TREE_CODE (BINDING_VALUE (outer_binding))
- == TYPE_DECL))
- || (ns_binding
- && TREE_CODE (ns_binding) == TYPE_DECL))
+ && (TREE_CODE (outer_binding->value) == TYPE_DECL))
+ || (ns_binding && TREE_CODE (ns_binding) == TYPE_DECL))
/* Here, we have something like:
typedef int I;
@@ -1702,11 +598,10 @@ poplevel (keep, reverse, functionbody)
there only for backward compatibility. */
DECL_DEAD_FOR_LOCAL (link) = 1;
- /* Keep track of what should of have happenned when we
+ /* Keep track of what should have happened when we
popped the binding. */
- if (outer_binding && BINDING_VALUE (outer_binding))
- DECL_SHADOWED_FOR_VAR (link)
- = BINDING_VALUE (outer_binding);
+ if (outer_binding && outer_binding->value)
+ DECL_SHADOWED_FOR_VAR (link) = outer_binding->value;
/* Add it to the list of dead variables in the next
outermost binding to that we can remove these when we
@@ -1717,9 +612,8 @@ poplevel (keep, reverse, functionbody)
dead_vars_from_for);
/* Although we don't pop the cxx_binding, we do clear
- its BINDING_LEVEL since the level is going away now. */
- BINDING_LEVEL (IDENTIFIER_BINDING (DECL_NAME (link)))
- = 0;
+ its SCOPE since the scope is going away now. */
+ IDENTIFIER_BINDING (DECL_NAME (link))->scope = NULL;
}
}
else
@@ -1784,9 +678,9 @@ poplevel (keep, reverse, functionbody)
pop_labels (block);
}
- tmp = current_binding_level->keep;
+ kind = current_binding_level->kind;
- pop_binding_level ();
+ leave_scope ();
if (functionbody)
DECL_INITIAL (current_function_decl) = block;
else if (block)
@@ -1809,7 +703,7 @@ poplevel (keep, reverse, functionbody)
TREE_USED (block) = 1;
/* Take care of compiler's internal binding structures. */
- if (tmp == 2)
+ if (kind == sk_cleanup)
{
tree scope_stmts;
@@ -1832,8 +726,7 @@ poplevel (keep, reverse, functionbody)
so that the block can be reinserted where appropriate. */
void
-delete_block (block)
- tree block;
+delete_block (tree block)
{
tree t;
if (current_binding_level->blocks == block)
@@ -1856,8 +749,7 @@ delete_block (block)
to handle the BLOCK node inside the BIND_EXPR. */
void
-insert_block (block)
- tree block;
+insert_block (tree block)
{
TREE_USED (block) = 1;
current_binding_level->blocks
@@ -1868,140 +760,16 @@ insert_block (block)
(the one we are currently in). */
void
-set_block (block)
- tree block ATTRIBUTE_UNUSED;
+set_block (tree block ATTRIBUTE_UNUSED )
{
/* The RTL expansion machinery requires us to provide this callback,
but it is not applicable in function-at-a-time mode. */
- my_friendly_assert (cfun && !doing_semantic_analysis_p (), 20000911);
-}
-
-/* Do a pushlevel for class declarations. */
-
-void
-pushlevel_class ()
-{
- register struct cp_binding_level *newlevel;
-
- /* Reuse or create a struct for this binding level. */
- if (!ENABLE_SCOPE_CHECKING && free_binding_level)
- {
- newlevel = free_binding_level;
- free_binding_level = free_binding_level->level_chain;
- }
- else
- newlevel = make_binding_level ();
-
- if (ENABLE_SCOPE_CHECKING)
- is_class_level = 1;
-
- push_binding_level (newlevel, 0, 0);
-
- class_binding_level = current_binding_level;
- class_binding_level->parm_flag = 2;
- class_binding_level->this_class = current_class_type;
-}
-
-/* ...and a poplevel for class declarations. */
-
-void
-poplevel_class ()
-{
- register struct cp_binding_level *level = class_binding_level;
- tree shadowed;
-
- timevar_push (TV_NAME_LOOKUP);
-
- my_friendly_assert (level != 0, 354);
-
- /* If we're leaving a toplevel class, don't bother to do the setting
- of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot
- shouldn't even be used when current_class_type isn't set, and second,
- if we don't touch it here, we're able to use the cache effect if the
- next time we're entering a class scope, it is the same class. */
- if (current_class_depth != 1)
- {
- struct cp_binding_level* b;
-
- /* Clear out our IDENTIFIER_CLASS_VALUEs. */
- for (shadowed = level->class_shadowed;
- shadowed;
- shadowed = TREE_CHAIN (shadowed))
- IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = NULL_TREE;
-
- /* Find the next enclosing class, and recreate
- IDENTIFIER_CLASS_VALUEs appropriate for that class. */
- b = level->level_chain;
- while (b && b->parm_flag != 2)
- b = b->level_chain;
-
- if (b)
- for (shadowed = b->class_shadowed;
- shadowed;
- shadowed = TREE_CHAIN (shadowed))
- {
- cxx_binding *binding;
-
- binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
- while (binding && BINDING_LEVEL (binding) != b)
- binding = binding->previous;
-
- if (binding)
- IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed))
- = BINDING_VALUE (binding);
- }
- }
- else
- /* Remember to save what IDENTIFIER's were bound in this scope so we
- can recover from cache misses. */
- {
- previous_class_type = current_class_type;
- previous_class_values = class_binding_level->class_shadowed;
- }
- for (shadowed = level->type_shadowed;
- shadowed;
- shadowed = TREE_CHAIN (shadowed))
- SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
-
- /* Remove the bindings for all of the class-level declarations. */
- for (shadowed = level->class_shadowed;
- shadowed;
- shadowed = TREE_CHAIN (shadowed))
- pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed));
-
- /* Now, pop out of the binding level which we created up in the
- `pushlevel_class' routine. */
- if (ENABLE_SCOPE_CHECKING)
- is_class_level = 1;
-
- pop_binding_level ();
-
- timevar_pop (TV_NAME_LOOKUP);
-}
-
-/* We are entering the scope of a class. Clear IDENTIFIER_CLASS_VALUE
- for any names in enclosing classes. */
-
-void
-clear_identifier_class_values ()
-{
- tree t;
-
- if (!class_binding_level)
- return;
-
- for (t = class_binding_level->class_shadowed;
- t;
- t = TREE_CHAIN (t))
- IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
}
/* Returns nonzero if T is a virtual function table. */
int
-vtable_decl_p (t, data)
- tree t;
- void *data ATTRIBUTE_UNUSED;
+vtable_decl_p (tree t, void* data ATTRIBUTE_UNUSED )
{
return (TREE_CODE (t) == VAR_DECL && DECL_VIRTUAL_P (t));
}
@@ -2010,24 +778,13 @@ vtable_decl_p (t, data)
functions. */
int
-vtype_decl_p (t, data)
- tree t;
- void *data ATTRIBUTE_UNUSED;
+vtype_decl_p (tree t, void *data ATTRIBUTE_UNUSED )
{
return (TREE_CODE (t) == TYPE_DECL
&& TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE
&& TYPE_POLYMORPHIC_P (TREE_TYPE (t)));
}
-/* Return the declarations that are members of the namespace NS. */
-
-tree
-cp_namespace_decls (ns)
- tree ns;
-{
- return NAMESPACE_LEVEL (ns)->names;
-}
-
struct walk_globals_data {
walk_globals_pred p;
walk_globals_fn f;
@@ -2039,9 +796,7 @@ struct walk_globals_data {
to F returns a nonzero value, return a nonzero value. */
static int
-walk_vtables_r (namespace, data)
- tree namespace;
- void *data;
+walk_vtables_r (tree namespace, void* data)
{
struct walk_globals_data* wgd = (struct walk_globals_data *) data;
walk_globals_fn f = wgd->f;
@@ -2058,11 +813,8 @@ walk_vtables_r (namespace, data)
/* Walk the vtable declarations. Whenever one is found for which P
returns nonzero, call F with its address. If any call to F
returns a nonzero value, return a nonzero value. */
-int
-walk_vtables (p, f, data)
- walk_globals_pred p;
- walk_globals_fn f;
- void *data;
+bool
+walk_vtables (walk_globals_pred p, walk_globals_fn f, void *data)
{
struct walk_globals_data wgd;
wgd.p = p;
@@ -2076,10 +828,7 @@ walk_vtables (p, f, data)
itself, calling F for each. The DATA is passed to F as well. */
static int
-walk_namespaces_r (namespace, f, data)
- tree namespace;
- walk_namespaces_fn f;
- void *data;
+walk_namespaces_r (tree namespace, walk_namespaces_fn f, void* data)
{
int result = 0;
tree current = NAMESPACE_LEVEL (namespace)->namespaces;
@@ -2096,9 +845,7 @@ walk_namespaces_r (namespace, f, data)
F as well. */
int
-walk_namespaces (f, data)
- walk_namespaces_fn f;
- void *data;
+walk_namespaces (walk_namespaces_fn f, void* data)
{
return walk_namespaces_r (global_namespace, f, data);
}
@@ -2108,9 +855,7 @@ walk_namespaces (f, data)
to F returns a nonzero value, return a nonzero value. */
static int
-walk_globals_r (namespace, data)
- tree namespace;
- void *data;
+walk_globals_r (tree namespace, void* data)
{
struct walk_globals_data* wgd = (struct walk_globals_data *) data;
walk_globals_pred p = wgd->p;
@@ -2138,14 +883,11 @@ walk_globals_r (namespace, data)
}
/* Walk the global declarations. Whenever one is found for which P
- returns nonzero, call F with its address. If any call to F
- returns a nonzero value, return a nonzero value. */
+ returns true, call F with its address. If any call to F
+ returns true, return true. */
-int
-walk_globals (p, f, data)
- walk_globals_pred p;
- walk_globals_fn f;
- void *data;
+bool
+walk_globals (walk_globals_pred p, walk_globals_fn f, void *data)
{
struct walk_globals_data wgd;
wgd.p = p;
@@ -2160,9 +902,7 @@ walk_globals (p, f, data)
wrapup_global_declarations for this NAMESPACE. */
int
-wrapup_globals_for_namespace (namespace, data)
- tree namespace;
- void *data;
+wrapup_globals_for_namespace (tree namespace, void* data)
{
struct cp_binding_level *level = NAMESPACE_LEVEL (namespace);
varray_type statics = level->static_decls;
@@ -2181,741 +921,13 @@ wrapup_globals_for_namespace (namespace, data)
}
-/* For debugging. */
-static int no_print_functions = 0;
-static int no_print_builtins = 0;
-
-/* Called from print_binding_level through binding_table_foreach to
- print the content of binding ENTRY. DATA is a pointer to line offset
- marker. */
-static void
-bt_print_entry (binding_entry entry, void *data)
-{
- int *p = (int *) data;
- int len;
-
- if (entry->name == NULL)
- len = 3;
- else if (entry->name == TYPE_IDENTIFIER (entry->type))
- len = 2;
- else
- len = 4;
-
- *p += len;
-
- if (*p > 5)
- {
- fprintf (stderr, "\n\t");
- *p = len;
- }
- if (entry->name == NULL)
- {
- print_node_brief (stderr, "<unnamed-typedef", entry->type, 0);
- fprintf (stderr, ">");
- }
- else if (entry->name == TYPE_IDENTIFIER (entry->type))
- print_node_brief (stderr, "", entry->type, 0);
- else
- {
- print_node_brief (stderr, "<typedef", entry->name, 0);
- print_node_brief (stderr, "", entry->type, 0);
- fprintf (stderr, ">");
- }
-}
-
-void
-print_binding_level (lvl)
- struct cp_binding_level *lvl;
-{
- tree t;
- int i = 0, len;
- fprintf (stderr, " blocks=");
- fprintf (stderr, HOST_PTR_PRINTF, lvl->blocks);
- if (lvl->tag_transparent)
- fprintf (stderr, " tag-transparent");
- if (lvl->more_cleanups_ok)
- fprintf (stderr, " more-cleanups-ok");
- if (lvl->have_cleanups)
- fprintf (stderr, " have-cleanups");
- fprintf (stderr, "\n");
- if (lvl->names)
- {
- fprintf (stderr, " names:\t");
- /* We can probably fit 3 names to a line? */
- for (t = lvl->names; t; t = TREE_CHAIN (t))
- {
- if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL))
- continue;
- if (no_print_builtins
- && (TREE_CODE (t) == TYPE_DECL)
- && (!strcmp (DECL_SOURCE_FILE (t),"<built-in>")))
- continue;
-
- /* Function decls tend to have longer names. */
- if (TREE_CODE (t) == FUNCTION_DECL)
- len = 3;
- else
- len = 2;
- i += len;
- if (i > 6)
- {
- fprintf (stderr, "\n\t");
- i = len;
- }
- print_node_brief (stderr, "", t, 0);
- if (t == error_mark_node)
- break;
- }
- if (i)
- fprintf (stderr, "\n");
- }
- if (lvl->type_decls)
- {
- fprintf (stderr, " tags:\t");
- i = 0;
- binding_table_foreach (lvl->type_decls, bt_print_entry, &i);
- if (i)
- fprintf (stderr, "\n");
- }
- if (lvl->class_shadowed)
- {
- fprintf (stderr, " class-shadowed:");
- for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t))
- {
- fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
- }
- fprintf (stderr, "\n");
- }
- if (lvl->type_shadowed)
- {
- fprintf (stderr, " type-shadowed:");
- for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t))
- {
- fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
- }
- fprintf (stderr, "\n");
- }
-}
-
-void
-print_other_binding_stack (stack)
- struct cp_binding_level *stack;
-{
- struct cp_binding_level *level;
- for (level = stack; !global_scope_p (level); level = level->level_chain)
- {
- fprintf (stderr, "binding level ");
- fprintf (stderr, HOST_PTR_PRINTF, level);
- fprintf (stderr, "\n");
- print_binding_level (level);
- }
-}
-
-void
-print_binding_stack ()
-{
- struct cp_binding_level *b;
- fprintf (stderr, "current_binding_level=");
- fprintf (stderr, HOST_PTR_PRINTF, current_binding_level);
- fprintf (stderr, "\nclass_binding_level=");
- fprintf (stderr, HOST_PTR_PRINTF, class_binding_level);
- fprintf (stderr, "\nNAMESPACE_LEVEL (global_namespace)=");
- fprintf (stderr, HOST_PTR_PRINTF,
- (void *) NAMESPACE_LEVEL (global_namespace));
- fprintf (stderr, "\n");
- if (class_binding_level)
- {
- for (b = class_binding_level; b; b = b->level_chain)
- if (b == current_binding_level)
- break;
- if (b)
- b = class_binding_level;
- else
- b = current_binding_level;
- }
- else
- b = current_binding_level;
- print_other_binding_stack (b);
- fprintf (stderr, "global:\n");
- print_binding_level (NAMESPACE_LEVEL (global_namespace));
-}
-
-/* Namespace binding access routines. */
-
-/* Check whether the a binding for the name to scope is known.
- Returns the binding found, or NULL. */
-
-static inline cxx_binding *
-find_binding (tree name, tree scope, cxx_binding *front)
-{
- cxx_binding *iter;
- cxx_binding *prev = NULL;
-
- timevar_push (TV_NAME_LOOKUP);
-
- for (iter = front; iter; iter = iter->previous)
- {
- if (BINDING_SCOPE (iter) == scope)
- {
- /* Move binding found to the front of the list, so
- subsequent lookups will find it faster. */
- if (prev)
- {
- prev->previous = iter->previous;
- iter->previous = front;
- IDENTIFIER_NAMESPACE_BINDINGS (name) = iter;
- }
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, iter);
- }
- prev = iter;
- }
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL);
-}
-
-/* Return the binding for NAME in SCOPE, if any. Otherwise, return NULL. */
-cxx_binding *
-cxx_scope_find_binding_for_name (tree scope, tree name)
-{
- cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
- if (b)
- {
- scope = ORIGINAL_NAMESPACE (scope);
- /* Fold-in case where NAME is used only once. */
- if (scope == BINDING_SCOPE (b) && b->previous == NULL)
- return b;
- return find_binding (name, scope, b);
- }
- return b;
-}
-
-
-/* Always returns a binding for name in scope.
- If no binding is found, make a new one. */
-
-cxx_binding *
-binding_for_name (tree name, tree scope)
-{
- cxx_binding *result;
-
- scope = ORIGINAL_NAMESPACE (scope);
- result = cxx_scope_find_binding_for_name (scope, name);
- if (result)
- return result;
- /* Not found, make a new one. */
- result = cxx_binding_make ();
- result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
- BINDING_TYPE (result) = NULL_TREE;
- BINDING_VALUE (result) = NULL_TREE;
- BINDING_SCOPE (result) = scope;
- result->is_local = false;
- result->value_is_inherited = false;
- result->has_level = false;
- IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
- return result;
-}
-
-/* Return the binding value for name in scope. */
-
-tree
-namespace_binding (tree name, tree scope)
-{
- cxx_binding *b =
- cxx_scope_find_binding_for_name (scope ? scope : global_namespace, name);
-
- return b ? b->value : NULL_TREE;
-}
-
-/* Set the binding value for name in scope. */
-
-void
-set_namespace_binding (name, scope, val)
- tree name;
- tree scope;
- tree val;
-{
- cxx_binding *b;
-
- timevar_push (TV_NAME_LOOKUP);
- if (scope == NULL_TREE)
- scope = global_namespace;
-
- b = binding_for_name (name, scope);
- BINDING_VALUE (b) = val;
- timevar_pop (TV_NAME_LOOKUP);
-}
-
-/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we
- select a name that is unique to this compilation unit. */
-
-void
-push_namespace (name)
- tree name;
-{
- tree d = NULL_TREE;
- int need_new = 1;
- int implicit_use = 0;
- int global = 0;
-
- timevar_push (TV_NAME_LOOKUP);
-
- if (!global_namespace)
- {
- /* This must be ::. */
- my_friendly_assert (name == get_identifier ("::"), 377);
- global = 1;
- }
- else if (!name)
- {
- /* The name of anonymous namespace is unique for the translation
- unit. */
- if (!anonymous_namespace_name)
- anonymous_namespace_name = get_file_function_name ('N');
- name = anonymous_namespace_name;
- d = IDENTIFIER_NAMESPACE_VALUE (name);
- if (d)
- /* Reopening anonymous namespace. */
- need_new = 0;
- implicit_use = 1;
- }
- else
- {
- /* Check whether this is an extended namespace definition. */
- d = IDENTIFIER_NAMESPACE_VALUE (name);
- if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
- {
- need_new = 0;
- if (DECL_NAMESPACE_ALIAS (d))
- {
- error ("namespace alias `%D' not allowed here, assuming `%D'",
- d, DECL_NAMESPACE_ALIAS (d));
- d = DECL_NAMESPACE_ALIAS (d);
- }
- }
- }
-
- if (need_new)
- {
- /* Make a new namespace, binding the name to it. */
- d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
- /* The global namespace is not pushed, and the global binding
- level is set elsewhere. */
- if (!global)
- {
- DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
- d = pushdecl (d);
- pushlevel (0);
- declare_namespace_level ();
- NAMESPACE_LEVEL (d) = current_binding_level;
- current_binding_level->type_decls =
- binding_table_new (name == std_identifier
- ? NAMESPACE_STD_HT_SIZE
- : NAMESPACE_ORDINARY_HT_SIZE);
- VARRAY_TREE_INIT (current_binding_level->static_decls,
- name != std_identifier ? 10 : 200,
- "Static declarations");
- }
- }
- else
- resume_binding_level (NAMESPACE_LEVEL (d));
-
- if (implicit_use)
- do_using_directive (d);
- /* Enter the name space. */
- current_namespace = d;
-
- timevar_pop (TV_NAME_LOOKUP);
-}
-
-/* Pop from the scope of the current namespace. */
-
-void
-pop_namespace ()
-{
- my_friendly_assert (current_namespace != global_namespace, 20010801);
- current_namespace = CP_DECL_CONTEXT (current_namespace);
- /* The binding level is not popped, as it might be re-opened later. */
- suspend_binding_level ();
-}
-
-/* Push into the scope of the namespace NS, even if it is deeply
- nested within another namespace. */
-
-void
-push_nested_namespace (ns)
- tree ns;
-{
- if (ns == global_namespace)
- push_to_top_level ();
- else
- {
- push_nested_namespace (CP_DECL_CONTEXT (ns));
- push_namespace (DECL_NAME (ns));
- }
-}
-
-/* Pop back from the scope of the namespace NS, which was previously
- entered with push_nested_namespace. */
-
-void
-pop_nested_namespace (ns)
- tree ns;
-{
- timevar_push (TV_NAME_LOOKUP);
- while (ns != global_namespace)
- {
- pop_namespace ();
- ns = CP_DECL_CONTEXT (ns);
- }
-
- pop_from_top_level ();
- timevar_pop (TV_NAME_LOOKUP);
-}
-
-
-/* Allocate storage for saving a C++ binding. */
-#define cxx_saved_binding_make() \
- (ggc_alloc (sizeof (cxx_saved_binding)))
-
-struct cxx_saved_binding GTY(())
-{
- /* Link that chains saved C++ bindings for a given name into a stack. */
- cxx_saved_binding *previous;
- /* The name of the current binding. */
- tree identifier;
- /* The binding we're saving. */
- cxx_binding *binding;
- tree class_value;
- tree real_type_value;
-};
-
-/* Subroutines for reverting temporarily to top-level for instantiation
- of templates and such. We actually need to clear out the class- and
- local-value slots of all identifiers, so that only the global values
- are at all visible. Simply setting current_binding_level to the global
- scope isn't enough, because more binding levels may be pushed. */
-struct saved_scope *scope_chain;
-
-static cxx_saved_binding *
-store_bindings (tree names, cxx_saved_binding *old_bindings)
-{
- tree t;
- cxx_saved_binding *search_bindings = old_bindings;
-
- timevar_push (TV_NAME_LOOKUP);
- for (t = names; t; t = TREE_CHAIN (t))
- {
- tree id;
- cxx_saved_binding *saved;
- cxx_saved_binding *t1;
-
- if (TREE_CODE (t) == TREE_LIST)
- id = TREE_PURPOSE (t);
- else
- id = DECL_NAME (t);
-
- if (!id
- /* Note that we may have an IDENTIFIER_CLASS_VALUE even when
- we have no IDENTIFIER_BINDING if we have left the class
- scope, but cached the class-level declarations. */
- || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
- continue;
-
- for (t1 = search_bindings; t1; t1 = t1->previous)
- if (t1->identifier == id)
- goto skip_it;
-
- my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
- saved = cxx_saved_binding_make ();
- saved->previous = old_bindings;
- saved->identifier = id;
- saved->binding = IDENTIFIER_BINDING (id);
- saved->class_value = IDENTIFIER_CLASS_VALUE (id);;
- saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
- IDENTIFIER_BINDING (id) = NULL;
- IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
- old_bindings = saved;
- skip_it:
- ;
- }
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings);
-}
-
-void
-maybe_push_to_top_level (pseudo)
- int pseudo;
-{
- struct saved_scope *s;
- struct cp_binding_level *b;
- cxx_saved_binding *old_bindings;
- int need_pop;
-
- timevar_push (TV_NAME_LOOKUP);
-
- s = (struct saved_scope *) ggc_alloc_cleared (sizeof (struct saved_scope));
-
- b = scope_chain ? current_binding_level : 0;
-
- /* If we're in the middle of some function, save our state. */
- if (cfun)
- {
- need_pop = 1;
- push_function_context_to (NULL_TREE);
- }
- else
- need_pop = 0;
-
- old_bindings = NULL;
- if (scope_chain && previous_class_type)
- old_bindings = store_bindings (previous_class_values, old_bindings);
-
- /* Have to include the global scope, because class-scope decls
- aren't listed anywhere useful. */
- for (; b; b = b->level_chain)
- {
- tree t;
-
- /* Template IDs are inserted into the global level. If they were
- inserted into namespace level, finish_file wouldn't find them
- when doing pending instantiations. Therefore, don't stop at
- namespace level, but continue until :: . */
- if (global_scope_p (b) || (pseudo && b->template_parms_p))
- break;
-
- old_bindings = store_bindings (b->names, old_bindings);
- /* We also need to check class_shadowed to save class-level type
- bindings, since pushclass doesn't fill in b->names. */
- if (b->parm_flag == 2)
- old_bindings = store_bindings (b->class_shadowed, old_bindings);
-
- /* Unwind type-value slots back to top level. */
- for (t = b->type_shadowed; t; t = TREE_CHAIN (t))
- SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t));
- }
- s->prev = scope_chain;
- s->old_bindings = old_bindings;
- s->bindings = b;
- s->need_pop_function_context = need_pop;
- s->function_decl = current_function_decl;
- s->last_parms = last_function_parms;
-
- scope_chain = s;
- current_function_decl = NULL_TREE;
- VARRAY_TREE_INIT (current_lang_base, 10, "current_lang_base");
- current_lang_name = lang_name_cplusplus;
- current_namespace = global_namespace;
- timevar_pop (TV_NAME_LOOKUP);
-}
-
-void
-push_to_top_level ()
-{
- maybe_push_to_top_level (0);
-}
-
-void
-pop_from_top_level ()
-{
- struct saved_scope *s = scope_chain;
- cxx_saved_binding *saved;
-
- timevar_push (TV_NAME_LOOKUP);
-
- /* Clear out class-level bindings cache. */
- if (previous_class_type)
- invalidate_class_lookup_cache ();
-
- current_lang_base = 0;
-
- scope_chain = s->prev;
- for (saved = s->old_bindings; saved; saved = saved->previous)
- {
- tree id = saved->identifier;
-
- IDENTIFIER_BINDING (id) = saved->binding;
- IDENTIFIER_CLASS_VALUE (id) = saved->class_value;
- SET_IDENTIFIER_TYPE_VALUE (id, saved->real_type_value);
- }
-
- /* If we were in the middle of compiling a function, restore our
- state. */
- if (s->need_pop_function_context)
- pop_function_context_from (NULL_TREE);
- current_function_decl = s->function_decl;
- last_function_parms = s->last_parms;
-
- timevar_pop (TV_NAME_LOOKUP);
-}
-
-/* Push a definition of struct, union or enum tag "name".
- into binding_level "b". "type" should be the type node,
- We assume that the tag "name" is not already defined.
-
- Note that the definition may really be just a forward reference.
- In that case, the TYPE_SIZE will be a NULL_TREE.
-
- C++ gratuitously puts all these tags in the name space. */
-
-/* When setting the IDENTIFIER_TYPE_VALUE field of an identifier ID,
- record the shadowed value for this binding contour. TYPE is
- the type that ID maps to. */
-
-static void
-set_identifier_type_value_with_scope (id, type, b)
- tree id;
- tree type;
- struct cp_binding_level *b;
-{
- if (!b->namespace_p)
- {
- /* Shadow the marker, not the real thing, so that the marker
- gets restored later. */
- tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
- b->type_shadowed
- = tree_cons (id, old_type_value, b->type_shadowed);
- }
- else
- {
- cxx_binding *binding = binding_for_name (id, current_namespace);
- BINDING_TYPE (binding) = type;
- /* Store marker instead of real type. */
- type = global_type_node;
- }
- SET_IDENTIFIER_TYPE_VALUE (id, type);
-}
-
-/* As set_identifier_type_value_with_scope, but using current_binding_level. */
-
-void
-set_identifier_type_value (id, type)
- tree id;
- tree type;
-{
- set_identifier_type_value_with_scope (id, type, current_binding_level);
-}
-
-/* Return the type associated with id. */
-
-tree
-identifier_type_value (id)
- tree id;
-{
- timevar_push (TV_NAME_LOOKUP);
- /* There is no type with that name, anywhere. */
- if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
- /* This is not the type marker, but the real thing. */
- if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, REAL_IDENTIFIER_TYPE_VALUE (id));
- /* Have to search for it. It must be on the global level, now.
- Ask lookup_name not to return non-types. */
- id = lookup_name_real (id, 2, 1, 0);
- if (id)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_TYPE (id));
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-}
-
-/* Pop off extraneous binding levels left over due to syntax errors.
-
- We don't pop past namespaces, as they might be valid. */
-
-void
-pop_everything ()
-{
- if (ENABLE_SCOPE_CHECKING)
- verbatim ("XXX entering pop_everything ()\n");
- while (!toplevel_bindings_p ())
- {
- if (current_binding_level->parm_flag == 2)
- pop_nested_class ();
- else
- poplevel (0, 0, 0);
- }
- if (ENABLE_SCOPE_CHECKING)
- verbatim ("XXX leaving pop_everything ()\n");
-}
-
-/* The type TYPE is being declared. If it is a class template, or a
- specialization of a class template, do any processing required and
- perform error-checking. If IS_FRIEND is nonzero, this TYPE is
- being declared a friend. B is the binding level at which this TYPE
- should be bound.
-
- Returns the TYPE_DECL for TYPE, which may have been altered by this
- processing. */
-
-static tree
-maybe_process_template_type_declaration (type, globalize, b)
- tree type;
- int globalize;
- struct cp_binding_level* b;
-{
- tree decl = TYPE_NAME (type);
-
- if (processing_template_parmlist)
- /* You can't declare a new template type in a template parameter
- list. But, you can declare a non-template type:
-
- template <class A*> struct S;
-
- is a forward-declaration of `A'. */
- ;
- else
- {
- maybe_check_template_type (type);
-
- my_friendly_assert (IS_AGGR_TYPE (type)
- || TREE_CODE (type) == ENUMERAL_TYPE, 0);
-
-
- if (processing_template_decl)
- {
- /* This may change after the call to
- push_template_decl_real, but we want the original value. */
- tree name = DECL_NAME (decl);
-
- decl = push_template_decl_real (decl, globalize);
- /* If the current binding level is the binding level for the
- template parameters (see the comment in
- begin_template_parm_list) and the enclosing level is a class
- scope, and we're not looking at a friend, push the
- declaration of the member class into the class scope. In the
- friend case, push_template_decl will already have put the
- friend into global scope, if appropriate. */
- if (TREE_CODE (type) != ENUMERAL_TYPE
- && !globalize && b->template_parms_p
- && b->level_chain->parm_flag == 2)
- {
- finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
- /* Put this tag on the list of tags for the class, since
- that won't happen below because B is not the class
- binding level, but is instead the pseudo-global level. */
- if (b->level_chain->type_decls == NULL)
- b->level_chain->type_decls =
- binding_table_new (SCOPE_DEFAULT_HT_SIZE);
- binding_table_insert (b->level_chain->type_decls, name, type);
- if (!COMPLETE_TYPE_P (current_class_type))
- {
- maybe_add_class_template_decl_list (current_class_type,
- type, /*friend_p=*/0);
- CLASSTYPE_NESTED_UDTS (current_class_type) =
- b->level_chain->type_decls;
- }
- }
- }
- }
-
- return decl;
-}
-
/* In C++, you don't have to write `struct S' to refer to `S'; you
can just use `S'. We accomplish this by creating a TYPE_DECL as
if the user had written `typedef struct S S'. Create and return
the TYPE_DECL for TYPE. */
tree
-create_implicit_typedef (name, type)
- tree name;
- tree type;
+create_implicit_typedef (tree name, tree type)
{
tree decl;
@@ -2933,14 +945,12 @@ create_implicit_typedef (name, type)
/* Remember a local name for name-mangling purposes. */
static void
-push_local_name (decl)
- tree decl;
+push_local_name (tree decl)
{
size_t i, nelts;
tree t, name;
timevar_push (TV_NAME_LOOKUP);
-
if (!local_names)
VARRAY_TREE_INIT (local_names, 8, "local_names");
@@ -2961,179 +971,14 @@ push_local_name (decl)
DECL_DISCRIMINATOR (decl) = 1;
VARRAY_TREE (local_names, i) = decl;
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0);
+ timevar_pop (TV_NAME_LOOKUP);
+ return;
}
}
VARRAY_PUSH_TREE (local_names, decl);
timevar_pop (TV_NAME_LOOKUP);
}
-
-/* Push a tag name NAME for struct/class/union/enum type TYPE.
- Normally put it into the inner-most non-tag-transparent scope,
- but if GLOBALIZE is true, put it in the inner-most non-class scope.
- The latter is needed for implicit declarations. */
-
-void
-pushtag (name, type, globalize)
- tree name, type;
- int globalize;
-{
- register struct cp_binding_level *b;
-
- timevar_push (TV_NAME_LOOKUP);
-
- b = current_binding_level;
- while (b->tag_transparent
- || (b->parm_flag == 2
- && (globalize
- /* We may be defining a new type in the initializer
- of a static member variable. We allow this when
- not pedantic, and it is particularly useful for
- type punning via an anonymous union. */
- || COMPLETE_TYPE_P (b->this_class))))
- b = b->level_chain;
-
- if (b->type_decls == NULL)
- b->type_decls = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
- binding_table_insert (b->type_decls, name, type);
-
- if (name)
- {
- /* Do C++ gratuitous typedefing. */
- if (IDENTIFIER_TYPE_VALUE (name) != type)
- {
- register tree d = NULL_TREE;
- int in_class = 0;
- tree context = TYPE_CONTEXT (type);
-
- if (! context)
- {
- tree cs = current_scope ();
-
- if (! globalize)
- context = cs;
- else if (cs != NULL_TREE && TYPE_P (cs))
- /* When declaring a friend class of a local class, we want
- to inject the newly named class into the scope
- containing the local class, not the namespace scope. */
- context = decl_function_context (get_type_decl (cs));
- }
- if (!context)
- context = current_namespace;
-
- if ((b->template_parms_p && b->level_chain->parm_flag == 2)
- || b->parm_flag == 2)
- in_class = 1;
-
- if (current_lang_name == lang_name_java)
- TYPE_FOR_JAVA (type) = 1;
-
- d = create_implicit_typedef (name, type);
- DECL_CONTEXT (d) = FROB_CONTEXT (context);
- if (! in_class)
- set_identifier_type_value_with_scope (name, type, b);
-
- d = maybe_process_template_type_declaration (type,
- globalize, b);
-
- if (b->parm_flag == 2)
- {
- if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
- /* Put this TYPE_DECL on the TYPE_FIELDS list for the
- class. But if it's a member template class, we
- want the TEMPLATE_DECL, not the TYPE_DECL, so this
- is done later. */
- finish_member_declaration (d);
- else
- pushdecl_class_level (d);
- }
- else
- d = pushdecl_with_scope (d, b);
-
- /* FIXME what if it gets a name from typedef? */
- if (ANON_AGGRNAME_P (name))
- DECL_IGNORED_P (d) = 1;
-
- TYPE_CONTEXT (type) = DECL_CONTEXT (d);
-
- /* If this is a local class, keep track of it. We need this
- information for name-mangling, and so that it is possible to find
- all function definitions in a translation unit in a convenient
- way. (It's otherwise tricky to find a member function definition
- it's only pointed to from within a local class.) */
- if (TYPE_CONTEXT (type)
- && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL
- && !processing_template_decl)
- VARRAY_PUSH_TREE (local_classes, type);
- }
- if (b->parm_flag == 2)
- {
- if (!COMPLETE_TYPE_P (current_class_type))
- {
- maybe_add_class_template_decl_list (current_class_type,
- type, /*friend_p=*/0);
- CLASSTYPE_NESTED_UDTS (current_class_type) = b->type_decls;
- }
- }
- }
-
- if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
- /* Use the canonical TYPE_DECL for this node. */
- TYPE_STUB_DECL (type) = TYPE_NAME (type);
- else
- {
- /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE
- will be the tagged type we just added to the current
- binding level. This fake NULL-named TYPE_DECL node helps
- dwarfout.c to know when it needs to output a
- representation of a tagged type, and it also gives us a
- convenient place to record the "scope start" address for
- the tagged type. */
-
- tree d = build_decl (TYPE_DECL, NULL_TREE, type);
- TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b);
- }
-
- timevar_pop (TV_NAME_LOOKUP);
-}
-
-/* Counter used to create anonymous type names. */
-
-static int anon_cnt = 0;
-
-/* Return an IDENTIFIER which can be used as a name for
- anonymous structs and unions. */
-
-tree
-make_anon_name ()
-{
- char buf[32];
-
- sprintf (buf, ANON_AGGRNAME_FORMAT, anon_cnt++);
- return get_identifier (buf);
-}
-
-/* Clear the TREE_PURPOSE slot of tags which have anonymous typenames.
- This keeps dbxout from getting confused. */
-
-void
-clear_anon_tags ()
-{
- register struct cp_binding_level *b;
- static int last_cnt = 0;
-
- /* Fast out if no new anon names were declared. */
- if (last_cnt == anon_cnt)
- return;
-
- b = current_binding_level;
- while (b->tag_transparent)
- b = b->level_chain;
- if (b->type_decls != NULL)
- binding_table_remove_anonymous_types (b->type_decls);
- last_cnt = anon_cnt;
-}
/* Subroutine of duplicate_decls: return truthvalue of whether
or not types of these decls match.
@@ -3143,8 +988,7 @@ clear_anon_tags ()
`const int&'. */
int
-decls_match (newdecl, olddecl)
- tree newdecl, olddecl;
+decls_match (tree newdecl, tree olddecl)
{
int types_match;
@@ -3206,16 +1050,17 @@ decls_match (newdecl, olddecl)
}
else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
- if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
- DECL_TEMPLATE_PARMS (olddecl)))
- return 0;
-
if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl))
!= TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)))
return 0;
+ if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
+ DECL_TEMPLATE_PARMS (olddecl)))
+ return 0;
+
if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
- types_match = 1;
+ types_match = same_type_p (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl)),
+ TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl)));
else
types_match = decls_match (DECL_TEMPLATE_RESULT (olddecl),
DECL_TEMPLATE_RESULT (newdecl));
@@ -3246,9 +1091,8 @@ decls_match (newdecl, olddecl)
Don't complain about built-in functions, since they are beyond
the user's control. */
-static void
-warn_extern_redeclared_static (newdecl, olddecl)
- tree newdecl, olddecl;
+void
+warn_extern_redeclared_static (tree newdecl, tree olddecl)
{
static const char *const explicit_extern_static_warning
= "`%D' was declared `extern' and later `static'";
@@ -3259,7 +1103,8 @@ warn_extern_redeclared_static (newdecl, olddecl)
if (TREE_CODE (newdecl) == TYPE_DECL
|| TREE_CODE (newdecl) == TEMPLATE_DECL
- || TREE_CODE (newdecl) == CONST_DECL)
+ || TREE_CODE (newdecl) == CONST_DECL
+ || TREE_CODE (newdecl) == NAMESPACE_DECL)
return;
/* Don't get confused by static member functions; that's a different
@@ -3285,23 +1130,22 @@ warn_extern_redeclared_static (newdecl, olddecl)
cp_pedwarn_at ("previous declaration of `%D'", olddecl);
}
-/* Handle when a new declaration NEWDECL has the same name as an old
- one OLDDECL in the same binding contour. Prints an error message
- if appropriate.
+/* If NEWDECL is a redeclaration of OLDDECL, merge the declarations.
+ If the redeclaration is invalid, a diagnostic is issued, and the
+ error_mark_node is returned. Otherwise, OLDDECL is returned.
- If safely possible, alter OLDDECL to look like NEWDECL, and return 1.
- Otherwise, return 0. */
+ If NEWDECL is not a redeclaration of OLDDECL, NULL_TREE is
+ returned. */
-int
-duplicate_decls (newdecl, olddecl)
- tree newdecl, olddecl;
+tree
+duplicate_decls (tree newdecl, tree olddecl)
{
unsigned olddecl_uid = DECL_UID (olddecl);
int olddecl_friend = 0, types_match = 0;
int new_defines_function = 0;
if (newdecl == olddecl)
- return 1;
+ return olddecl;
types_match = decls_match (newdecl, olddecl);
@@ -3331,19 +1175,18 @@ duplicate_decls (newdecl, olddecl)
&& DECL_UNINLINABLE (olddecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
{
- warning_with_decl (newdecl,
- "function `%s' redeclared as inline");
- warning_with_decl (olddecl,
- "previous declaration of function `%s' with attribute noinline");
+ warning ("%Jfunction '%D' redeclared as inline", newdecl, newdecl);
+ warning ("%Jprevious declaration of '%D' with attribute noinline",
+ olddecl, olddecl);
}
else if (DECL_DECLARED_INLINE_P (olddecl)
&& DECL_UNINLINABLE (newdecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
{
- warning_with_decl (newdecl,
- "function `%s' redeclared with attribute noinline");
- warning_with_decl (olddecl,
- "previous declaration of function `%s' was inline");
+ warning ("%Jfunction '%D' redeclared with attribute noinline",
+ newdecl, newdecl);
+ warning ("%Jprevious declaration of '%D' was inline",
+ olddecl, olddecl);
}
}
@@ -3355,7 +1198,7 @@ duplicate_decls (newdecl, olddecl)
{
/* Avoid warnings redeclaring anticipated built-ins. */
if (DECL_ANTICIPATED (olddecl))
- return 0;
+ return NULL_TREE;
/* If you declare a built-in or predefined function name as static,
the old definition is overridden, but optionally warn this was a
@@ -3367,7 +1210,7 @@ duplicate_decls (newdecl, olddecl)
DECL_BUILT_IN (olddecl) ? "built-in" : "library",
olddecl);
/* Discard the old built-in function. */
- return 0;
+ return NULL_TREE;
}
/* If the built-in is not ansi, then programs can override
it even globally without an error. */
@@ -3380,7 +1223,7 @@ duplicate_decls (newdecl, olddecl)
error ("conflicts with built-in declaration `%#D'",
olddecl);
}
- return 0;
+ return NULL_TREE;
}
else if (!types_match)
{
@@ -3407,15 +1250,22 @@ duplicate_decls (newdecl, olddecl)
}
else
/* Discard the old built-in function. */
- return 0;
+ return NULL_TREE;
/* Replace the old RTL to avoid problems with inlining. */
SET_DECL_RTL (olddecl, DECL_RTL (newdecl));
}
/* Even if the types match, prefer the new declarations type
- for anitipated built-ins, for exception lists, etc... */
+ for anticipated built-ins, for exception lists, etc... */
else if (DECL_ANTICIPATED (olddecl))
- TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
+ {
+ tree type = TREE_TYPE (newdecl);
+ tree attribs = (*targetm.merge_type_attributes)
+ (TREE_TYPE (olddecl), type);
+
+ type = cp_build_type_attribute_variant (type, attribs);
+ TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = type;
+ }
/* Whether or not the builtin can throw exceptions has no
bearing on this declarator. */
@@ -3452,14 +1302,14 @@ duplicate_decls (newdecl, olddecl)
get shadowed, and know that if we need to find a TYPE_DECL
for a given name, we can look in the IDENTIFIER_TYPE_VALUE
slot of the identifier. */
- return 0;
+ return NULL_TREE;
}
if ((TREE_CODE (newdecl) == FUNCTION_DECL
&& DECL_FUNCTION_TEMPLATE_P (olddecl))
|| (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_FUNCTION_TEMPLATE_P (newdecl)))
- return 0;
+ return NULL_TREE;
error ("`%#D' redeclared as different kind of symbol", newdecl);
if (TREE_CODE (olddecl) == TREE_LIST)
@@ -3469,14 +1319,14 @@ duplicate_decls (newdecl, olddecl)
/* New decl is completely inconsistent with the old one =>
tell caller to replace the old one. */
- return 0;
+ return NULL_TREE;
}
else if (!types_match)
{
if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl))
/* These are certainly not duplicate declarations; they're
from different scopes. */
- return 0;
+ return NULL_TREE;
if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
@@ -3504,7 +1354,7 @@ duplicate_decls (newdecl, olddecl)
error ("new declaration `%#D'", newdecl);
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
}
- return 0;
+ return NULL_TREE;
}
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
@@ -3521,17 +1371,17 @@ duplicate_decls (newdecl, olddecl)
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
}
else
- return 0;
+ return NULL_TREE;
}
/* Already complained about this, so don't do so again. */
else if (current_class_type == NULL_TREE
- || !DECL_ASSEMBLER_NAME_SET_P (newdecl)
- || (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl))
- != current_class_type))
+ || IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type)
{
- error ("conflicting types for `%#D'", newdecl);
- cp_error_at ("previous declaration as `%#D'", olddecl);
+ error ("conflicting declaration '%#D'", newdecl);
+ cp_error_at ("'%D' has a previous declaration as `%#D'",
+ olddecl, olddecl);
+ return NULL_TREE;
}
}
else if (TREE_CODE (newdecl) == FUNCTION_DECL
@@ -3551,7 +1401,7 @@ duplicate_decls (newdecl, olddecl)
can occur if we instantiate a template class, and then
specialize one of its methods. This situation is valid, but
the declarations must be merged in the usual way. */
- return 0;
+ return NULL_TREE;
else if (TREE_CODE (newdecl) == FUNCTION_DECL
&& ((DECL_TEMPLATE_INSTANTIATION (olddecl)
&& !DECL_USE_TEMPLATE (newdecl))
@@ -3559,12 +1409,20 @@ duplicate_decls (newdecl, olddecl)
&& !DECL_USE_TEMPLATE (olddecl))))
/* One of the declarations is a template instantiation, and the
other is not a template at all. That's OK. */
- return 0;
+ return NULL_TREE;
else if (TREE_CODE (newdecl) == NAMESPACE_DECL
&& DECL_NAMESPACE_ALIAS (newdecl)
&& DECL_NAMESPACE_ALIAS (newdecl) == DECL_NAMESPACE_ALIAS (olddecl))
- /* Redeclaration of namespace alias, ignore it. */
- return 1;
+ /* In [namespace.alias] we have:
+
+ In a declarative region, a namespace-alias-definition can be
+ used to redefine a namespace-alias declared in that declarative
+ region to refer only to the namespace to which it already
+ refers.
+
+ Therefore, if we encounter a second alias directive for the same
+ alias, we can just ignore the second directive. */
+ return olddecl;
else
{
const char *errmsg = redeclaration_error_message (newdecl, olddecl);
@@ -3576,7 +1434,7 @@ duplicate_decls (newdecl, olddecl)
&& namespace_bindings_p ())
? "`%#D' previously defined here"
: "`%#D' previously declared here", olddecl);
- return 0;
+ return error_mark_node;
}
else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_INITIAL (olddecl) != NULL_TREE
@@ -3585,7 +1443,7 @@ duplicate_decls (newdecl, olddecl)
{
/* Prototype decl follows defn w/o prototype. */
cp_warning_at ("prototype for `%#D'", newdecl);
- cp_warning_at ("follows non-prototype definition here", olddecl);
+ warning ("%Jfollows non-prototype definition here", olddecl);
}
else if (TREE_CODE (olddecl) == FUNCTION_DECL
&& DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl))
@@ -3640,10 +1498,8 @@ duplicate_decls (newdecl, olddecl)
&& ! DECL_DECLARED_INLINE_P (olddecl)
&& TREE_ADDRESSABLE (olddecl) && warn_inline)
{
- warning ("`%#D' was used before it was declared inline",
- newdecl);
- cp_warning_at ("previous non-inline declaration here",
- olddecl);
+ warning ("`%#D' was used before it was declared inline", newdecl);
+ warning ("%Jprevious non-inline declaration here", olddecl);
}
}
}
@@ -3658,7 +1514,7 @@ duplicate_decls (newdecl, olddecl)
if (TREE_CODE (olddecl) == TYPE_DECL
&& (DECL_IMPLICIT_TYPEDEF_P (olddecl)
|| DECL_IMPLICIT_TYPEDEF_P (newdecl)))
- return 0;
+ return NULL_TREE;
/* If new decl is `static' and an `extern' was seen previously,
warn about it. */
@@ -3704,14 +1560,14 @@ duplicate_decls (newdecl, olddecl)
/* Deal with C++: must preserve virtual function table size. */
if (TREE_CODE (olddecl) == TYPE_DECL)
{
- register tree newtype = TREE_TYPE (newdecl);
- register tree oldtype = TREE_TYPE (olddecl);
+ tree newtype = TREE_TYPE (newdecl);
+ tree oldtype = TREE_TYPE (olddecl);
if (newtype != error_mark_node && oldtype != error_mark_node
&& TYPE_LANG_SPECIFIC (newtype) && TYPE_LANG_SPECIFIC (oldtype))
CLASSTYPE_FRIEND_CLASSES (newtype)
= CLASSTYPE_FRIEND_CLASSES (oldtype);
-\
+
DECL_ORIGINAL_TYPE (newdecl) = DECL_ORIGINAL_TYPE (olddecl);
}
@@ -3735,9 +1591,20 @@ duplicate_decls (newdecl, olddecl)
DECL_SOURCE_LOCATION (olddecl)
= DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (olddecl))
= DECL_SOURCE_LOCATION (newdecl);
+ if (DECL_FUNCTION_TEMPLATE_P (newdecl))
+ DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (olddecl))
+ = DECL_ARGUMENTS (DECL_TEMPLATE_RESULT (newdecl));
}
- return 1;
+ if (DECL_FUNCTION_TEMPLATE_P (newdecl))
+ {
+ DECL_INLINE (DECL_TEMPLATE_RESULT (olddecl))
+ |= DECL_INLINE (DECL_TEMPLATE_RESULT (newdecl));
+ DECL_DECLARED_INLINE_P (DECL_TEMPLATE_RESULT (olddecl))
+ |= DECL_DECLARED_INLINE_P (DECL_TEMPLATE_RESULT (newdecl));
+ }
+
+ return olddecl;
}
if (types_match)
@@ -3758,6 +1625,8 @@ duplicate_decls (newdecl, olddecl)
{
DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl);
DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl);
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (newdecl)
+ |= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (olddecl);
}
/* Do this after calling `merge_types' so that default
@@ -3813,7 +1682,10 @@ duplicate_decls (newdecl, olddecl)
if (CAN_HAVE_FULL_LANG_DECL_P (newdecl)
&& DECL_LANG_SPECIFIC (newdecl)
&& DECL_LANG_SPECIFIC (olddecl))
- DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
+ {
+ DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
+ DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl);
+ }
}
/* Merge the section attribute.
@@ -3827,8 +1699,12 @@ duplicate_decls (newdecl, olddecl)
{
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
|= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
- DECL_NO_LIMIT_STACK (newdecl)
- |= DECL_NO_LIMIT_STACK (olddecl);
+ DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
+ TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
+ TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
+ TREE_NOTHROW (newdecl) |= TREE_NOTHROW (olddecl);
+ DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
+ DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
/* Keep the old RTL. */
COPY_DECL_RTL (olddecl, newdecl);
}
@@ -3906,7 +1782,7 @@ duplicate_decls (newdecl, olddecl)
{
/* If newdecl is not a specialization, then it is not a
template-related function at all. And that means that we
- shoud have exited above, returning 0. */
+ should have exited above, returning 0. */
my_friendly_assert (DECL_TEMPLATE_SPECIALIZATION (newdecl),
0);
@@ -3977,8 +1853,6 @@ duplicate_decls (newdecl, olddecl)
regardless of declaration matches. */
SET_DECL_RTL (newdecl, DECL_RTL (olddecl));
}
- else
- DECL_NUM_STMTS (newdecl) = DECL_NUM_STMTS (olddecl);
DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
/* Don't clear out the arguments if we're redefining a function. */
@@ -3995,6 +1869,19 @@ duplicate_decls (newdecl, olddecl)
DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
+ /* If either declaration has a nondefault visibility, use it. */
+ if (DECL_VISIBILITY (olddecl) != VISIBILITY_DEFAULT)
+ {
+ if (DECL_VISIBILITY (newdecl) != VISIBILITY_DEFAULT
+ && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
+ {
+ warning ("%J'%D': visibility attribute ignored because it",
+ newdecl, newdecl);
+ warning ("%Jconflicts with previous declaration here", olddecl);
+ }
+ DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
+ }
+
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
int function_size;
@@ -4006,36 +1893,30 @@ duplicate_decls (newdecl, olddecl)
function_size - sizeof (struct tree_common));
if (DECL_TEMPLATE_INSTANTIATION (newdecl))
- {
- /* If newdecl is a template instantiation, it is possible that
- the following sequence of events has occurred:
-
- o A friend function was declared in a class template. The
- class template was instantiated.
-
- o The instantiation of the friend declaration was
- recorded on the instantiation list, and is newdecl.
+ /* If newdecl is a template instantiation, it is possible that
+ the following sequence of events has occurred:
- o Later, however, instantiate_class_template called pushdecl
- on the newdecl to perform name injection. But, pushdecl in
- turn called duplicate_decls when it discovered that another
- declaration of a global function with the same name already
- existed.
+ o A friend function was declared in a class template. The
+ class template was instantiated.
- o Here, in duplicate_decls, we decided to clobber newdecl.
+ o The instantiation of the friend declaration was
+ recorded on the instantiation list, and is newdecl.
- If we're going to do that, we'd better make sure that
- olddecl, and not newdecl, is on the list of
- instantiations so that if we try to do the instantiation
- again we won't get the clobbered declaration. */
+ o Later, however, instantiate_class_template called pushdecl
+ on the newdecl to perform name injection. But, pushdecl in
+ turn called duplicate_decls when it discovered that another
+ declaration of a global function with the same name already
+ existed.
- tree tmpl = DECL_TI_TEMPLATE (newdecl);
- tree decls = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
+ o Here, in duplicate_decls, we decided to clobber newdecl.
- for (; decls; decls = TREE_CHAIN (decls))
- if (TREE_VALUE (decls) == newdecl)
- TREE_VALUE (decls) = olddecl;
- }
+ If we're going to do that, we'd better make sure that
+ olddecl, and not newdecl, is on the list of
+ instantiations so that if we try to do the instantiation
+ again we won't get the clobbered declaration. */
+ reregister_specialization (newdecl,
+ DECL_TI_TEMPLATE (newdecl),
+ olddecl);
}
else
{
@@ -4054,938 +1935,24 @@ duplicate_decls (newdecl, olddecl)
DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);
/* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
- so that encode_section_info has a chance to look at the new decl
- flags and attributes. */
- if (DECL_RTL_SET_P (olddecl)
+ so that encode_section_info has a chance to look at the new decl
+ flags and attributes. */
+ if (DECL_RTL_SET_P (olddecl)
&& (TREE_CODE (olddecl) == FUNCTION_DECL
|| (TREE_CODE (olddecl) == VAR_DECL
&& TREE_STATIC (olddecl))))
make_decl_rtl (olddecl, NULL);
- return 1;
-}
-
-/* Record a decl-node X as belonging to the current lexical scope.
- Check for errors (such as an incompatible declaration for the same
- name already seen in the same scope).
-
- Returns either X or an old decl for the same name.
- If an old decl is returned, it may have been smashed
- to agree with what X says. */
-
-tree
-pushdecl (x)
- tree x;
-{
- register tree t;
- register tree name;
- int need_new_binding;
-
- timevar_push (TV_NAME_LOOKUP);
-
- /* We shouldn't be calling pushdecl when we're generating RTL for a
- function that we already did semantic analysis on previously. */
- my_friendly_assert (!cfun || doing_semantic_analysis_p (),
- 19990913);
-
- need_new_binding = 1;
-
- if (DECL_TEMPLATE_PARM_P (x))
- /* Template parameters have no context; they are not X::T even
- when declared within a class or namespace. */
- ;
- else
- {
- if (current_function_decl && x != current_function_decl
- /* A local declaration for a function doesn't constitute
- nesting. */
- && !(TREE_CODE (x) == FUNCTION_DECL && !DECL_INITIAL (x))
- /* A local declaration for an `extern' variable is in the
- scope of the current namespace, not the current
- function. */
- && !(TREE_CODE (x) == VAR_DECL && DECL_EXTERNAL (x))
- && !DECL_CONTEXT (x))
- DECL_CONTEXT (x) = current_function_decl;
-
- /* If this is the declaration for a namespace-scope function,
- but the declaration itself is in a local scope, mark the
- declaration. */
- if (TREE_CODE (x) == FUNCTION_DECL
- && DECL_NAMESPACE_SCOPE_P (x)
- && current_function_decl
- && x != current_function_decl)
- DECL_LOCAL_FUNCTION_P (x) = 1;
- }
-
- name = DECL_NAME (x);
- if (name)
- {
- int different_binding_level = 0;
-
- if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- name = TREE_OPERAND (name, 0);
-
- /* In case this decl was explicitly namespace-qualified, look it
- up in its namespace context. */
- if (TREE_CODE (x) == VAR_DECL && DECL_NAMESPACE_SCOPE_P (x)
- && namespace_bindings_p ())
- t = namespace_binding (name, DECL_CONTEXT (x));
- else
- t = lookup_name_current_level (name);
-
- /* [basic.link] If there is a visible declaration of an entity
- with linkage having the same name and type, ignoring entities
- declared outside the innermost enclosing namespace scope, the
- block scope declaration declares that same entity and
- receives the linkage of the previous declaration. */
- if (! t && current_function_decl && x != current_function_decl
- && (TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
- && DECL_EXTERNAL (x))
- {
- /* Look in block scope. */
- t = IDENTIFIER_VALUE (name);
- /* Or in the innermost namespace. */
- if (! t)
- t = namespace_binding (name, DECL_CONTEXT (x));
- /* Does it have linkage? Note that if this isn't a DECL, it's an
- OVERLOAD, which is OK. */
- if (t && DECL_P (t) && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
- t = NULL_TREE;
- if (t)
- different_binding_level = 1;
- }
-
- /* If we are declaring a function, and the result of name-lookup
- was an OVERLOAD, look for an overloaded instance that is
- actually the same as the function we are declaring. (If
- there is one, we have to merge our declaration with the
- previous declaration.) */
- if (t && TREE_CODE (t) == OVERLOAD)
- {
- tree match;
-
- if (TREE_CODE (x) == FUNCTION_DECL)
- for (match = t; match; match = OVL_NEXT (match))
- {
- if (decls_match (OVL_CURRENT (match), x))
- break;
- }
- else
- /* Just choose one. */
- match = t;
-
- if (match)
- t = OVL_CURRENT (match);
- else
- t = NULL_TREE;
- }
-
- if (t == error_mark_node)
- {
- /* error_mark_node is 0 for a while during initialization! */
- t = NULL_TREE;
- cp_error_at ("`%#D' used prior to declaration", x);
- }
- else if (t != NULL_TREE)
- {
- if (different_binding_level)
- {
- if (decls_match (x, t))
- /* The standard only says that the local extern
- inherits linkage from the previous decl; in
- particular, default args are not shared. It would
- be nice to propagate inlining info, though. FIXME. */
- TREE_PUBLIC (x) = TREE_PUBLIC (t);
- }
- else if (TREE_CODE (t) == PARM_DECL)
- {
- if (DECL_CONTEXT (t) == NULL_TREE)
- /* This is probaby caused by too many errors, but calling
- abort will say that if errors have occurred. */
- abort ();
-
- /* Check for duplicate params. */
- if (duplicate_decls (x, t))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
- }
- else if ((DECL_EXTERN_C_FUNCTION_P (x)
- || DECL_FUNCTION_TEMPLATE_P (x))
- && is_overloaded_fn (t))
- /* Don't do anything just yet. */;
- else if (t == wchar_decl_node)
- {
- if (pedantic && ! DECL_IN_SYSTEM_HEADER (x))
- pedwarn ("redeclaration of `wchar_t' as `%T'",
- TREE_TYPE (x));
-
- /* Throw away the redeclaration. */
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
- }
- else if (TREE_CODE (t) != TREE_CODE (x))
- {
- if (duplicate_decls (x, t))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
- }
- else if (duplicate_decls (x, t))
- {
- if (TREE_CODE (t) == TYPE_DECL)
- SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
- else if (TREE_CODE (t) == FUNCTION_DECL)
- check_default_args (t);
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
- }
- else if (DECL_MAIN_P (x))
- {
- /* A redeclaration of main, but not a duplicate of the
- previous one.
-
- [basic.start.main]
-
- This function shall not be overloaded. */
- cp_error_at ("invalid redeclaration of `%D'", t);
- error ("as `%D'", x);
- /* We don't try to push this declaration since that
- causes a crash. */
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
- }
- }
-
- check_template_shadow (x);
-
- /* If this is a function conjured up by the backend, massage it
- so it looks friendly. */
- if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_LANG_SPECIFIC (x))
- {
- retrofit_lang_decl (x);
- SET_DECL_LANGUAGE (x, lang_c);
- }
-
- if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_FUNCTION_MEMBER_P (x))
- {
- t = push_overloaded_decl (x, PUSH_LOCAL);
- if (t != x)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
- if (!namespace_bindings_p ())
- /* We do not need to create a binding for this name;
- push_overloaded_decl will have already done so if
- necessary. */
- need_new_binding = 0;
- }
- else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x))
- {
- t = push_overloaded_decl (x, PUSH_GLOBAL);
- if (t == x)
- add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t)));
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
- }
-
- /* If declaring a type as a typedef, copy the type (unless we're
- at line 0), and install this TYPE_DECL as the new type's typedef
- name. See the extensive comment in ../c-decl.c (pushdecl). */
- if (TREE_CODE (x) == TYPE_DECL)
- {
- tree type = TREE_TYPE (x);
- if (DECL_SOURCE_LINE (x) == 0)
- {
- if (TYPE_NAME (type) == 0)
- TYPE_NAME (type) = x;
- }
- else if (type != error_mark_node && TYPE_NAME (type) != x
- /* We don't want to copy the type when all we're
- doing is making a TYPE_DECL for the purposes of
- inlining. */
- && (!TYPE_NAME (type)
- || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x)))
- {
- DECL_ORIGINAL_TYPE (x) = type;
- type = build_type_copy (type);
- TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
- TYPE_NAME (type) = x;
- TREE_TYPE (x) = type;
- }
-
- if (type != error_mark_node
- && TYPE_NAME (type)
- && TYPE_IDENTIFIER (type))
- set_identifier_type_value_with_scope (DECL_NAME (x), type,
- current_binding_level);
-
- }
-
- /* Multiple external decls of the same identifier ought to match.
-
- We get warnings about inline functions where they are defined.
- We get warnings about other functions from push_overloaded_decl.
-
- Avoid duplicate warnings where they are used. */
- if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL)
- {
- tree decl;
-
- decl = IDENTIFIER_NAMESPACE_VALUE (name);
- if (decl && TREE_CODE (decl) == OVERLOAD)
- decl = OVL_FUNCTION (decl);
-
- if (decl && decl != error_mark_node
- && (DECL_EXTERNAL (decl) || TREE_PUBLIC (decl))
- /* If different sort of thing, we already gave an error. */
- && TREE_CODE (decl) == TREE_CODE (x)
- && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl)))
- {
- pedwarn ("type mismatch with previous external decl", x);
- cp_pedwarn_at ("previous external decl of `%#D'", decl);
- }
- }
-
- /* This name is new in its binding level.
- Install the new declaration and return it. */
- if (namespace_bindings_p ())
- {
- /* Install a global value. */
-
- /* If the first global decl has external linkage,
- warn if we later see static one. */
- if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
- TREE_PUBLIC (name) = 1;
-
- /* Bind the name for the entity. */
- if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
- && t != NULL_TREE)
- && (TREE_CODE (x) == TYPE_DECL
- || TREE_CODE (x) == VAR_DECL
- || TREE_CODE (x) == NAMESPACE_DECL
- || TREE_CODE (x) == CONST_DECL
- || TREE_CODE (x) == TEMPLATE_DECL))
- SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
-
- /* Don't forget if the function was used via an implicit decl. */
- if (IDENTIFIER_IMPLICIT_DECL (name)
- && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name)))
- TREE_USED (x) = 1;
-
- /* Don't forget if its address was taken in that way. */
- if (IDENTIFIER_IMPLICIT_DECL (name)
- && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name)))
- TREE_ADDRESSABLE (x) = 1;
-
- /* Warn about mismatches against previous implicit decl. */
- if (IDENTIFIER_IMPLICIT_DECL (name) != NULL_TREE
- /* If this real decl matches the implicit, don't complain. */
- && ! (TREE_CODE (x) == FUNCTION_DECL
- && TREE_TYPE (TREE_TYPE (x)) == integer_type_node))
- warning
- ("`%D' was previously implicitly declared to return `int'", x);
-
- /* If new decl is `static' and an `extern' was seen previously,
- warn about it. */
- if (x != NULL_TREE && t != NULL_TREE && decls_match (x, t))
- warn_extern_redeclared_static (x, t);
- }
- else
- {
- /* Here to install a non-global value. */
- tree oldlocal = IDENTIFIER_VALUE (name);
- tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);
-
- if (need_new_binding)
- {
- push_local_binding (name, x, 0);
- /* Because push_local_binding will hook X on to the
- current_binding_level's name list, we don't want to
- do that again below. */
- need_new_binding = 0;
- }
-
- /* If this is a TYPE_DECL, push it into the type value slot. */
- if (TREE_CODE (x) == TYPE_DECL)
- set_identifier_type_value_with_scope (name, TREE_TYPE (x),
- current_binding_level);
-
- /* Clear out any TYPE_DECL shadowed by a namespace so that
- we won't think this is a type. The C struct hack doesn't
- go through namespaces. */
- if (TREE_CODE (x) == NAMESPACE_DECL)
- set_identifier_type_value_with_scope (name, NULL_TREE,
- current_binding_level);
-
- if (oldlocal)
- {
- tree d = oldlocal;
-
- while (oldlocal
- && TREE_CODE (oldlocal) == VAR_DECL
- && DECL_DEAD_FOR_LOCAL (oldlocal))
- oldlocal = DECL_SHADOWED_FOR_VAR (oldlocal);
-
- if (oldlocal == NULL_TREE)
- oldlocal = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (d));
- }
-
- /* If this is an extern function declaration, see if we
- have a global definition or declaration for the function. */
- if (oldlocal == NULL_TREE
- && DECL_EXTERNAL (x)
- && oldglobal != NULL_TREE
- && TREE_CODE (x) == FUNCTION_DECL
- && TREE_CODE (oldglobal) == FUNCTION_DECL)
- {
- /* We have one. Their types must agree. */
- if (decls_match (x, oldglobal))
- /* OK */;
- else
- {
- warning ("extern declaration of `%#D' doesn't match", x);
- cp_warning_at ("global declaration `%#D'", oldglobal);
- }
- }
- /* If we have a local external declaration,
- and no file-scope declaration has yet been seen,
- then if we later have a file-scope decl it must not be static. */
- if (oldlocal == NULL_TREE
- && oldglobal == NULL_TREE
- && DECL_EXTERNAL (x)
- && TREE_PUBLIC (x))
- TREE_PUBLIC (name) = 1;
-
- /* Warn if shadowing an argument at the top level of the body. */
- if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
- /* Inline decls shadow nothing. */
- && !DECL_FROM_INLINE (x)
- && TREE_CODE (oldlocal) == PARM_DECL
- /* Don't check the `this' parameter. */
- && !DECL_ARTIFICIAL (oldlocal))
- {
- bool err = false;
-
- /* Don't complain if it's from an enclosing function. */
- if (DECL_CONTEXT (oldlocal) == current_function_decl
- && TREE_CODE (x) != PARM_DECL)
- {
- /* Go to where the parms should be and see if we find
- them there. */
- struct cp_binding_level *b = current_binding_level->level_chain;
-
- /* ARM $8.3 */
- if (b->parm_flag == 1)
- {
- error ("declaration of `%#D' shadows a parameter",
- name);
- err = true;
- }
- }
-
- if (warn_shadow && !err)
- shadow_warning ("a parameter", name, oldlocal);
- }
-
- /* Maybe warn if shadowing something else. */
- else if (warn_shadow && !DECL_EXTERNAL (x)
- /* No shadow warnings for internally generated vars. */
- && ! DECL_ARTIFICIAL (x)
- /* No shadow warnings for vars made for inlining. */
- && ! DECL_FROM_INLINE (x))
- {
- if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE
- && current_class_ptr
- && !TREE_STATIC (name))
- warning ("declaration of `%s' shadows a member of `this'",
- IDENTIFIER_POINTER (name));
- else if (oldlocal != NULL_TREE
- && TREE_CODE (oldlocal) == VAR_DECL)
- shadow_warning ("a previous local", name, oldlocal);
- else if (oldglobal != NULL_TREE
- && TREE_CODE (oldglobal) == VAR_DECL)
- /* XXX shadow warnings in outer-more namespaces */
- shadow_warning ("a global declaration", name, oldglobal);
- }
- }
-
- if (TREE_CODE (x) == FUNCTION_DECL)
- check_default_args (x);
-
- if (TREE_CODE (x) == VAR_DECL)
- maybe_register_incomplete_var (x);
- }
-
- if (need_new_binding)
- add_decl_to_level (x,
- DECL_NAMESPACE_SCOPE_P (x)
- ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
- : current_binding_level);
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
-}
-
-/* Same as pushdecl, but define X in binding-level LEVEL. We rely on the
- caller to set DECL_CONTEXT properly. */
-
-static tree
-pushdecl_with_scope (x, level)
- tree x;
- struct cp_binding_level *level;
-{
- register struct cp_binding_level *b;
- tree function_decl = current_function_decl;
-
- timevar_push (TV_NAME_LOOKUP);
-
- current_function_decl = NULL_TREE;
- if (level->parm_flag == 2)
- {
- b = class_binding_level;
- class_binding_level = level;
- pushdecl_class_level (x);
- class_binding_level = b;
- }
- else
- {
- b = current_binding_level;
- current_binding_level = level;
- x = pushdecl (x);
- current_binding_level = b;
- }
- current_function_decl = function_decl;
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
-}
-
-/* Like pushdecl, only it places X in the current namespace,
- if appropriate. */
-
-tree
-pushdecl_namespace_level (x)
- tree x;
-{
- register struct cp_binding_level *b = current_binding_level;
- register tree t;
-
- timevar_push (TV_NAME_LOOKUP);
- t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace));
-
- /* Now, the type_shadowed stack may screw us. Munge it so it does
- what we want. */
- if (TREE_CODE (x) == TYPE_DECL)
- {
- tree name = DECL_NAME (x);
- tree newval;
- tree *ptr = (tree *)0;
- for (; !global_scope_p (b); b = b->level_chain)
- {
- tree shadowed = b->type_shadowed;
- for (; shadowed; shadowed = TREE_CHAIN (shadowed))
- if (TREE_PURPOSE (shadowed) == name)
- {
- ptr = &TREE_VALUE (shadowed);
- /* Can't break out of the loop here because sometimes
- a binding level will have duplicate bindings for
- PT names. It's gross, but I haven't time to fix it. */
- }
- }
- newval = TREE_TYPE (x);
- if (ptr == (tree *)0)
- {
- /* @@ This shouldn't be needed. My test case "zstring.cc" trips
- up here if this is changed to an assertion. --KR */
- SET_IDENTIFIER_TYPE_VALUE (name, newval);
- }
- else
- {
- *ptr = newval;
- }
- }
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
-}
-
-/* Like pushdecl, only it places X in the global scope if appropriate.
- Calls cp_finish_decl to register the variable, initializing it with
- *INIT, if INIT is non-NULL. */
-
-static tree
-pushdecl_top_level_1 (tree x, tree *init)
-{
- timevar_push (TV_NAME_LOOKUP);
- push_to_top_level ();
- x = pushdecl_namespace_level (x);
- if (init)
- cp_finish_decl (x, *init, NULL_TREE, 0);
- pop_from_top_level ();
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
-}
-
-/* Like pushdecl, only it places X in the global scope if appropriate. */
-
-tree
-pushdecl_top_level (tree x)
-{
- return pushdecl_top_level_1 (x, NULL);
-}
-
-/* Like pushdecl, only it places X in the global scope if
- appropriate. Calls cp_finish_decl to register the variable,
- initializing it with INIT. */
-
-tree
-pushdecl_top_level_and_finish (tree x, tree init)
-{
- return pushdecl_top_level_1 (x, &init);
-}
-
-/* Make the declaration of X appear in CLASS scope. */
-
-bool
-pushdecl_class_level (x)
- tree x;
-{
- tree name;
- bool is_valid = true;
-
- timevar_push (TV_NAME_LOOKUP);
- /* Get the name of X. */
- if (TREE_CODE (x) == OVERLOAD)
- name = DECL_NAME (get_first_fn (x));
- else
- name = DECL_NAME (x);
-
- if (name)
- {
- is_valid = push_class_level_binding (name, x);
- if (TREE_CODE (x) == TYPE_DECL)
- set_identifier_type_value (name, TREE_TYPE (x));
- }
- else if (ANON_AGGR_TYPE_P (TREE_TYPE (x)))
- {
- /* If X is an anonymous aggregate, all of its members are
- treated as if they were members of the class containing the
- aggregate, for naming purposes. */
- tree f;
-
- for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f))
- {
- push_srcloc (DECL_SOURCE_FILE (f), DECL_SOURCE_LINE (f));
- if (!pushdecl_class_level (f))
- is_valid = false;
- pop_srcloc ();
- }
- }
- timevar_pop (TV_NAME_LOOKUP);
-
- return is_valid;
-}
-
-/* Enter DECL into the symbol table, if that's appropriate. Returns
- DECL, or a modified version thereof. */
-
-tree
-maybe_push_decl (decl)
- tree decl;
-{
- tree type = TREE_TYPE (decl);
-
- /* Add this decl to the current binding level, but not if it comes
- from another scope, e.g. a static member variable. TEM may equal
- DECL or it may be a previous decl of the same name. */
- if (decl == error_mark_node
- || (TREE_CODE (decl) != PARM_DECL
- && DECL_CONTEXT (decl) != NULL_TREE
- /* Definitions of namespace members outside their namespace are
- possible. */
- && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
- || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
- || TREE_CODE (type) == UNKNOWN_TYPE
- /* The declaration of a template specialization does not affect
- the functions available for overload resolution, so we do not
- call pushdecl. */
- || (TREE_CODE (decl) == FUNCTION_DECL
- && DECL_TEMPLATE_SPECIALIZATION (decl)))
- return decl;
- else
- return pushdecl (decl);
-}
-
-/* Make the declaration(s) of X appear in CLASS scope under the name
- NAME. Returns true if the binding is valid. */
-
-bool
-push_class_level_binding (tree name, tree x)
-{
- cxx_binding *binding;
-
- timevar_push (TV_NAME_LOOKUP);
- /* The class_binding_level will be NULL if x is a template
- parameter name in a member template. */
- if (!class_binding_level)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
-
- /* Make sure that this new member does not have the same name
- as a template parameter. */
- if (TYPE_BEING_DEFINED (current_class_type))
- check_template_shadow (x);
-
- /* If this declaration shadows a declaration from an enclosing
- class, then we will need to restore IDENTIFIER_CLASS_VALUE when
- we leave this class. Record the shadowed declaration here. */
- binding = IDENTIFIER_BINDING (name);
- if (binding
- && ((TREE_CODE (x) == OVERLOAD
- && BINDING_VALUE (binding)
- && is_overloaded_fn (BINDING_VALUE (binding)))
- || INHERITED_VALUE_BINDING_P (binding)))
- {
- tree shadow;
- tree old_decl;
-
- /* If the old binding was from a base class, and was for a tag
- name, slide it over to make room for the new binding. The
- old binding is still visible if explicitly qualified with a
- class-key. */
- if (INHERITED_VALUE_BINDING_P (binding)
- && BINDING_VALUE (binding)
- && TREE_CODE (BINDING_VALUE (binding)) == TYPE_DECL
- && DECL_ARTIFICIAL (BINDING_VALUE (binding))
- && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
- {
- old_decl = BINDING_TYPE (binding);
- BINDING_TYPE (binding) = BINDING_VALUE (binding);
- BINDING_VALUE (binding) = NULL_TREE;
- INHERITED_VALUE_BINDING_P (binding) = 0;
- }
- else
- old_decl = BINDING_VALUE (binding);
-
- /* Find the previous binding of name on the class-shadowed
- list, and update it. */
- for (shadow = class_binding_level->class_shadowed;
- shadow;
- shadow = TREE_CHAIN (shadow))
- if (TREE_PURPOSE (shadow) == name
- && TREE_TYPE (shadow) == old_decl)
- {
- BINDING_VALUE (binding) = x;
- INHERITED_VALUE_BINDING_P (binding) = 0;
- TREE_TYPE (shadow) = x;
- IDENTIFIER_CLASS_VALUE (name) = x;
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
- }
- }
-
- /* If we didn't replace an existing binding, put the binding on the
- stack of bindings for the identifier, and update the shadowed list. */
- if (push_class_binding (name, x))
- {
- class_binding_level->class_shadowed
- = tree_cons (name, NULL,
- class_binding_level->class_shadowed);
- /* Record the value we are binding NAME to so that we can know
- what to pop later. */
- TREE_TYPE (class_binding_level->class_shadowed) = x;
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
- }
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
-}
-
-/* Insert another USING_DECL into the current binding level, returning
- this declaration. If this is a redeclaration, do nothing, and
- return NULL_TREE if this not in namespace scope (in namespace
- scope, a using decl might extend any previous bindings). */
-
-tree
-push_using_decl (scope, name)
- tree scope;
- tree name;
-{
- tree decl;
-
- timevar_push (TV_NAME_LOOKUP);
-
- my_friendly_assert (TREE_CODE (scope) == NAMESPACE_DECL, 383);
- my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 384);
- for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
- if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name)
- break;
- if (decl)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
- namespace_bindings_p () ? decl : NULL_TREE);
- decl = build_lang_decl (USING_DECL, name, void_type_node);
- DECL_INITIAL (decl) = scope;
- TREE_CHAIN (decl) = current_binding_level->usings;
- current_binding_level->usings = decl;
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
-}
-
-/* Add namespace to using_directives. Return NULL_TREE if nothing was
- changed (i.e. there was already a directive), or the fresh
- TREE_LIST otherwise. */
-
-tree
-push_using_directive (used)
- tree used;
-{
- tree ud = current_binding_level->using_directives;
- tree iter, ancestor;
-
- timevar_push (TV_NAME_LOOKUP);
-
- /* Check if we already have this. */
- if (purpose_member (used, ud) != NULL_TREE)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-
- ancestor = namespace_ancestor (current_decl_namespace (), used);
- ud = current_binding_level->using_directives;
- ud = tree_cons (used, ancestor, ud);
- current_binding_level->using_directives = ud;
-
- /* Recursively add all namespaces used. */
- for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
- push_using_directive (TREE_PURPOSE (iter));
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ud);
-}
-
-/* DECL is a FUNCTION_DECL for a non-member function, which may have
- other definitions already in place. We get around this by making
- the value of the identifier point to a list of all the things that
- want to be referenced by that name. It is then up to the users of
- that name to decide what to do with that list.
-
- DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its
- DECL_TEMPLATE_RESULT. It is dealt with the same way.
-
- FLAGS is a bitwise-or of the following values:
- PUSH_LOCAL: Bind DECL in the current scope, rather than at
- namespace scope.
- PUSH_USING: DECL is being pushed as the result of a using
- declaration.
-
- The value returned may be a previous declaration if we guessed wrong
- about what language DECL should belong to (C or C++). Otherwise,
- it's always DECL (and never something that's not a _DECL). */
-
-tree
-push_overloaded_decl (decl, flags)
- tree decl;
- int flags;
-{
- tree name = DECL_NAME (decl);
- tree old;
- tree new_binding;
- int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL));
-
- timevar_push (TV_NAME_LOOKUP);
-
- if (doing_global)
- old = namespace_binding (name, DECL_CONTEXT (decl));
- else
- old = lookup_name_current_level (name);
-
- if (old)
- {
- if (TREE_CODE (old) == TYPE_DECL && DECL_ARTIFICIAL (old))
- {
- tree t = TREE_TYPE (old);
- if (IS_AGGR_TYPE (t) && warn_shadow
- && (! DECL_IN_SYSTEM_HEADER (decl)
- || ! DECL_IN_SYSTEM_HEADER (old)))
- warning ("`%#D' hides constructor for `%#T'", decl, t);
- old = NULL_TREE;
- }
- else if (is_overloaded_fn (old))
- {
- tree tmp;
-
- for (tmp = old; tmp; tmp = OVL_NEXT (tmp))
- {
- tree fn = OVL_CURRENT (tmp);
-
- if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
- && !(flags & PUSH_USING)
- && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
- TYPE_ARG_TYPES (TREE_TYPE (decl))))
- error ("`%#D' conflicts with previous using declaration `%#D'",
- decl, fn);
-
- if (duplicate_decls (decl, fn))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fn);
- }
- }
- else if (old == error_mark_node)
- /* Ignore the undefined symbol marker. */
- old = NULL_TREE;
- else
- {
- cp_error_at ("previous non-function declaration `%#D'", old);
- error ("conflicts with function declaration `%#D'", decl);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
- }
- }
-
- if (old || TREE_CODE (decl) == TEMPLATE_DECL)
- {
- if (old && TREE_CODE (old) != OVERLOAD)
- new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
- else
- new_binding = ovl_cons (decl, old);
- if (flags & PUSH_USING)
- OVL_USED (new_binding) = 1;
- }
- else
- /* NAME is not ambiguous. */
- new_binding = decl;
-
- if (doing_global)
- set_namespace_binding (name, current_namespace, new_binding);
- else
- {
- /* We only create an OVERLOAD if there was a previous binding at
- this level, or if decl is a template. In the former case, we
- need to remove the old binding and replace it with the new
- binding. We must also run through the NAMES on the binding
- level where the name was bound to update the chain. */
-
- if (TREE_CODE (new_binding) == OVERLOAD && old)
- {
- tree *d;
-
- for (d = &BINDING_LEVEL (IDENTIFIER_BINDING (name))->names;
- *d;
- d = &TREE_CHAIN (*d))
- if (*d == old
- || (TREE_CODE (*d) == TREE_LIST
- && TREE_VALUE (*d) == old))
- {
- if (TREE_CODE (*d) == TREE_LIST)
- /* Just replace the old binding with the new. */
- TREE_VALUE (*d) = new_binding;
- else
- /* Build a TREE_LIST to wrap the OVERLOAD. */
- *d = tree_cons (NULL_TREE, new_binding,
- TREE_CHAIN (*d));
-
- /* And update the cxx_binding node. */
- BINDING_VALUE (IDENTIFIER_BINDING (name))
- = new_binding;
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
- }
-
- /* We should always find a previous binding in this case. */
- abort ();
- }
-
- /* Install the new binding. */
- push_local_binding (name, new_binding, flags);
- }
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+ return olddecl;
}
/* Generate an implicit declaration for identifier FUNCTIONID
as a function of type int (). Print a warning if appropriate. */
tree
-implicitly_declare (functionid)
- tree functionid;
+implicitly_declare (tree functionid)
{
- register tree decl;
+ tree decl;
/* We used to reuse an old implicit decl here,
but this loses with inline functions because it can clobber
@@ -5019,8 +1986,7 @@ implicitly_declare (functionid)
where the identifier should go. */
static const char *
-redeclaration_error_message (newdecl, olddecl)
- tree newdecl, olddecl;
+redeclaration_error_message (tree newdecl, tree olddecl)
{
if (TREE_CODE (newdecl) == TYPE_DECL)
{
@@ -5062,16 +2028,31 @@ redeclaration_error_message (newdecl, olddecl)
}
else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{
- if ((TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
- && (DECL_TEMPLATE_RESULT (newdecl)
- != DECL_TEMPLATE_RESULT (olddecl))
- && DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl))
- && DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)))
- || (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL
- && COMPLETE_TYPE_P (TREE_TYPE (newdecl))
- && COMPLETE_TYPE_P (TREE_TYPE (olddecl))))
+ tree nt, ot;
+
+ if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
+ {
+ if (COMPLETE_TYPE_P (TREE_TYPE (newdecl))
+ && COMPLETE_TYPE_P (TREE_TYPE (olddecl)))
+ return "redefinition of `%#D'";
+ return NULL;
+ }
+
+ if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) != FUNCTION_DECL
+ || (DECL_TEMPLATE_RESULT (newdecl)
+ == DECL_TEMPLATE_RESULT (olddecl)))
+ return NULL;
+
+ nt = DECL_TEMPLATE_RESULT (newdecl);
+ if (DECL_TEMPLATE_INFO (nt))
+ nt = DECL_TEMPLATE_RESULT (template_for_substitution (nt));
+ ot = DECL_TEMPLATE_RESULT (olddecl);
+ if (DECL_TEMPLATE_INFO (ot))
+ ot = DECL_TEMPLATE_RESULT (template_for_substitution (ot));
+ if (DECL_INITIAL (nt) && DECL_INITIAL (ot))
return "redefinition of `%#D'";
- return 0;
+
+ return NULL;
}
else if (toplevel_bindings_p () || DECL_NAMESPACE_SCOPE_P (newdecl))
{
@@ -5096,16 +2077,11 @@ redeclaration_error_message (newdecl, olddecl)
/* Create a new label, named ID. */
static tree
-make_label_decl (id, local_p)
- tree id;
- int local_p;
+make_label_decl (tree id, int local_p)
{
tree decl;
decl = build_decl (LABEL_DECL, id, void_type_node);
- if (expanding_p)
- /* Make sure every label has an rtx. */
- label_rtx (decl);
DECL_CONTEXT (decl) = current_function_decl;
DECL_MODE (decl) = VOIDmode;
@@ -5113,8 +2089,7 @@ make_label_decl (id, local_p)
/* Say where one reference is to the label, for the sake of the
error if it is not defined. */
- DECL_SOURCE_LINE (decl) = lineno;
- DECL_SOURCE_FILE (decl) = input_filename;
+ DECL_SOURCE_LOCATION (decl) = input_location;
/* Record the fact that this identifier is bound to this label. */
SET_IDENTIFIER_LABEL_VALUE (id, decl);
@@ -5128,21 +2103,18 @@ make_label_decl (id, local_p)
this use is valid. */
static void
-use_label (decl)
- tree decl;
+use_label (tree decl)
{
if (named_label_uses == NULL
|| named_label_uses->names_in_scope != current_binding_level->names
|| named_label_uses->label_decl != decl)
{
struct named_label_use_list *new_ent;
- new_ent = ((struct named_label_use_list *)
- ggc_alloc (sizeof (struct named_label_use_list)));
+ new_ent = ggc_alloc (sizeof (struct named_label_use_list));
new_ent->label_decl = decl;
new_ent->names_in_scope = current_binding_level->names;
new_ent->binding_level = current_binding_level;
- new_ent->lineno_o_goto = lineno;
- new_ent->filename_o_goto = input_filename;
+ new_ent->o_goto_locus = input_location;
new_ent->next = named_label_uses;
named_label_uses = new_ent;
}
@@ -5153,14 +2125,12 @@ use_label (decl)
labels, and complain about them at the end of a function.) */
tree
-lookup_label (id)
- tree id;
+lookup_label (tree id)
{
tree decl;
struct named_label_list *ent;
timevar_push (TV_NAME_LOOKUP);
-
/* You can't use labels at global scope. */
if (current_function_decl == NULL_TREE)
{
@@ -5177,8 +2147,7 @@ lookup_label (id)
/* Record this label on the list of labels used in this function.
We do this before calling make_label_decl so that we get the
IDENTIFIER_LABEL_VALUE before the new label is declared. */
- ent = ((struct named_label_list *)
- ggc_alloc_cleared (sizeof (struct named_label_list)));
+ ent = ggc_alloc_cleared (sizeof (struct named_label_list));
ent->old_value = IDENTIFIER_LABEL_VALUE (id);
ent->next = named_labels;
named_labels = ent;
@@ -5195,8 +2164,7 @@ lookup_label (id)
/* Declare a local label named ID. */
tree
-declare_local_label (id)
- tree id;
+declare_local_label (tree id)
{
tree decl;
@@ -5218,8 +2186,7 @@ declare_local_label (id)
DECL. Returns 2 if it's also a real problem. */
static int
-decl_jump_unsafe (decl)
- tree decl;
+decl_jump_unsafe (tree decl)
{
if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl))
return 0;
@@ -5243,12 +2210,9 @@ decl_jump_unsafe (decl)
context; FILE and LINE are the source position of the jump or 0. */
static void
-check_previous_goto_1 (decl, level, names, file, line)
- tree decl;
- struct cp_binding_level *level;
- tree names;
- const char *file;
- int line;
+check_previous_goto_1 (tree decl,
+ struct cp_binding_level* level,
+ tree names, const location_t *locus)
{
int identified = 0;
int saw_eh = 0;
@@ -5271,8 +2235,8 @@ check_previous_goto_1 (decl, level, names, file, line)
else
pedwarn ("jump to case label");
- if (file)
- pedwarn_with_file_and_line (file, line, " from here");
+ if (locus)
+ pedwarn ("%H from here", locus);
identified = 1;
}
@@ -5286,7 +2250,7 @@ check_previous_goto_1 (decl, level, names, file, line)
if (b == level)
break;
- if ((b->is_try_scope || b->is_catch_scope) && ! saw_eh)
+ if ((b->kind == sk_try || b->kind == sk_catch) && ! saw_eh)
{
if (! identified)
{
@@ -5295,11 +2259,11 @@ check_previous_goto_1 (decl, level, names, file, line)
else
pedwarn ("jump to case label");
- if (file)
- pedwarn_with_file_and_line (file, line, " from here");
+ if (locus)
+ pedwarn ("%H from here", locus);
identified = 1;
}
- if (b->is_try_scope)
+ if (b->kind == sk_try)
error (" enters try block");
else
error (" enters catch block");
@@ -5309,27 +2273,23 @@ check_previous_goto_1 (decl, level, names, file, line)
}
static void
-check_previous_goto (use)
- struct named_label_use_list *use;
+check_previous_goto (struct named_label_use_list* use)
{
check_previous_goto_1 (use->label_decl, use->binding_level,
- use->names_in_scope, use->filename_o_goto,
- use->lineno_o_goto);
+ use->names_in_scope, &use->o_goto_locus);
}
static void
-check_switch_goto (level)
- struct cp_binding_level *level;
+check_switch_goto (struct cp_binding_level* level)
{
- check_previous_goto_1 (NULL_TREE, level, level->names, NULL, 0);
+ check_previous_goto_1 (NULL_TREE, level, level->names, NULL);
}
/* Check that any previously seen jumps to a newly defined label DECL
are OK. Called by define_label. */
static void
-check_previous_gotos (decl)
- tree decl;
+check_previous_gotos (tree decl)
{
struct named_label_use_list **usep;
@@ -5353,8 +2313,7 @@ check_previous_gotos (decl)
finish_goto_stmt. */
void
-check_goto (decl)
- tree decl;
+check_goto (tree decl)
{
int identified = 0;
tree bad;
@@ -5396,7 +2355,7 @@ check_goto (decl)
if (u > 1 && DECL_ARTIFICIAL (b))
/* Can't skip init of __exception_info. */
- cp_error_at (" enters catch block", b);
+ error ("%J enters catch block", b);
else if (u > 1)
cp_error_at (" skips initialization of `%#D'", b);
else
@@ -5413,24 +2372,22 @@ check_goto (decl)
Return the LABEL_DECL node for the label. */
tree
-define_label (filename, line, name)
- const char *filename;
- int line;
- tree name;
+define_label (location_t location, tree name)
{
tree decl = lookup_label (name);
struct named_label_list *ent;
- register struct cp_binding_level *p;
+ struct cp_binding_level *p;
timevar_push (TV_NAME_LOOKUP);
-
for (ent = named_labels; ent; ent = ent->next)
if (ent->label_decl == decl)
break;
/* After labels, make any new cleanups in the function go into their
own new (temporary) binding contour. */
- for (p = current_binding_level; !(p->parm_flag); p = p->level_chain)
+ for (p = current_binding_level;
+ p->kind != sk_function_parms;
+ p = p->level_chain)
p->more_cleanups_ok = 0;
if (name == get_identifier ("wchar_t"))
@@ -5443,8 +2400,7 @@ define_label (filename, line, name)
/* Mark label as having been defined. */
DECL_INITIAL (decl) = error_mark_node;
/* Say where in the source. */
- DECL_SOURCE_FILE (decl) = filename;
- DECL_SOURCE_LINE (decl) = line;
+ DECL_SOURCE_LOCATION (decl) = location;
if (ent)
{
ent->names_in_scope = current_binding_level->names;
@@ -5483,11 +2439,9 @@ static struct cp_switch *switch_stack;
SWITCH_STMT is the switch statement being parsed. */
void
-push_switch (switch_stmt)
- tree switch_stmt;
+push_switch (tree switch_stmt)
{
- struct cp_switch *p
- = (struct cp_switch *) xmalloc (sizeof (struct cp_switch));
+ struct cp_switch *p = xmalloc (sizeof (struct cp_switch));
p->level = current_binding_level;
p->next = switch_stack;
p->switch_stmt = switch_stmt;
@@ -5496,7 +2450,7 @@ push_switch (switch_stmt)
}
void
-pop_switch ()
+pop_switch (void)
{
struct cp_switch *cs;
@@ -5510,24 +2464,10 @@ pop_switch ()
is a bad place for one. */
tree
-finish_case_label (low_value, high_value)
- tree low_value;
- tree high_value;
+finish_case_label (tree low_value, tree high_value)
{
tree cond, r;
- register struct cp_binding_level *p;
-
- if (! switch_stack)
- {
- if (high_value)
- error ("case label not within a switch statement");
- else if (low_value)
- error ("case label `%E' not within a switch statement",
- low_value);
- else
- error ("`default' label not within a switch statement");
- return NULL_TREE;
- }
+ struct cp_binding_level *p;
if (processing_template_decl)
{
@@ -5545,336 +2485,23 @@ finish_case_label (low_value, high_value)
cond = TREE_VALUE (cond);
r = c_add_case_label (switch_stack->cases, cond, low_value, high_value);
- if (r == error_mark_node)
- r = NULL_TREE;
check_switch_goto (switch_stack->level);
/* After labels, make any new cleanups in the function go into their
own new (temporary) binding contour. */
- for (p = current_binding_level; !(p->parm_flag); p = p->level_chain)
+ for (p = current_binding_level;
+ p->kind != sk_function_parms;
+ p = p->level_chain)
p->more_cleanups_ok = 0;
return r;
}
-/* Return the list of declarations of the current level.
- Note that this list is in reverse order unless/until
- you nreverse it; and when you do nreverse it, you must
- store the result back using `storedecls' or you will lose. */
-
-tree
-getdecls ()
-{
- return current_binding_level->names;
-}
-
-/* Store the list of declarations of the current level.
- This is done for the parameter declarations of a function being defined,
- after they are modified in the light of any missing parameters. */
-
-static void
-storedecls (decls)
- tree decls;
-{
- current_binding_level->names = decls;
-}
-
-/* Set the current binding TABLE for type declarations.. This is a
- temporary workaround of the fact that the data structure classtypes
- does not currently carry its allocated cxx_scope structure. */
-void
-cxx_remember_type_decls (binding_table table)
-{
- current_binding_level->type_decls = table;
-}
-
-
-/* Return the type that should be used when TYPE's name is preceded
- by a tag such as 'struct' or 'union', or null if the name cannot
- be used in this way.
-
- For example, when processing the third line of:
-
- struct A;
- typedef struct A A;
- struct A;
-
- lookup of A will find the typedef. Given A's typedef, this function
- will return the type associated with "struct A". For the tag to be
- anything other than TYPE, TYPE must be a typedef whose original type
- has the same name and context as TYPE itself.
-
- It is not valid for a typedef of an anonymous type to be used with
- an explicit tag:
-
- typedef struct { ... } B;
- struct B;
-
- Return null for this case. */
-
-static tree
-follow_tag_typedef (type)
- tree type;
-{
- tree original;
-
- original = original_type (type);
- if (! TYPE_NAME (original))
- return NULL_TREE;
- if (TYPE_IDENTIFIER (original) == TYPE_IDENTIFIER (type)
- && (CP_DECL_CONTEXT (TYPE_NAME (original))
- == CP_DECL_CONTEXT (TYPE_NAME (type)))
- && !(CLASS_TYPE_P (original) && TYPE_WAS_ANONYMOUS (original)))
- return original;
- else
- return NULL_TREE;
-}
-
-/* Given NAME, an IDENTIFIER_NODE,
- return the structure (or union or enum) definition for that name.
- Searches binding levels from BINDING_LEVEL up to the global level.
- If THISLEVEL_ONLY is nonzero, searches only the specified context
- (but skips any tag-transparent contexts to find one that is
- meaningful for tags).
- FORM says which kind of type the caller wants;
- it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE.
- If the wrong kind of type is found, and it's not a template, an error is
- reported. */
-
-static tree
-lookup_tag (form, name, binding_level, thislevel_only)
- enum tree_code form;
- tree name;
- struct cp_binding_level *binding_level;
- int thislevel_only;
-{
- register struct cp_binding_level *level;
- /* Nonzero if, we should look past a template parameter level, even
- if THISLEVEL_ONLY. */
- int allow_template_parms_p = 1;
- bool type_is_anonymous = ANON_AGGRNAME_P (name);
-
- timevar_push (TV_NAME_LOOKUP);
-
- for (level = binding_level; level; level = level->level_chain)
- {
- register tree tail;
- if (type_is_anonymous && level->type_decls != NULL)
- {
- tree type = binding_table_find_anon_type (level->type_decls, name);
- /* There's no need for error checking here, because
- anon names are unique throughout the compilation. */
- if (type != NULL)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
- }
- else if (level->namespace_p)
- /* Do namespace lookup. */
- for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
- {
- cxx_binding *binding =
- cxx_scope_find_binding_for_name (tail, name);
- tree old;
-
- /* If we just skipped past a template parameter level,
- even though THISLEVEL_ONLY, and we find a template
- class declaration, then we use the _TYPE node for the
- template. See the example below. */
- if (thislevel_only && !allow_template_parms_p
- && binding && BINDING_VALUE (binding)
- && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (binding)))
- old = TREE_TYPE (BINDING_VALUE (binding));
- else if (binding)
- old = BINDING_TYPE (binding);
- else
- old = NULL;
-
- if (old)
- {
- /* We've found something at this binding level. If it is
- a typedef, extract the tag it refers to. Lookup fails
- if the typedef doesn't refer to a taggable type. */
- old = follow_tag_typedef (old);
- if (!old)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
- if (TREE_CODE (old) != form
- && (form == ENUMERAL_TYPE
- || TREE_CODE (old) == ENUMERAL_TYPE))
- {
- error ("`%#D' redeclared as %C", old, form);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
- }
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old);
- }
- if (thislevel_only || tail == global_namespace)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
- }
- else if (level->type_decls != NULL)
- {
- binding_entry entry = binding_table_find (level->type_decls, name);
- if (entry != NULL)
- {
- enum tree_code code = TREE_CODE (entry->type);
-
- if (code != form
- && (form == ENUMERAL_TYPE || code == ENUMERAL_TYPE))
- {
- /* Definition isn't the kind we were looking for. */
- error ("`%#D' redeclared as %C", entry->type, form);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
- }
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->type);
- }
- }
- if (thislevel_only && ! level->tag_transparent)
- {
- if (level->template_parms_p && allow_template_parms_p)
- {
- /* We must deal with cases like this:
-
- template <class T> struct S;
- template <class T> struct S {};
-
- When looking up `S', for the second declaration, we
- would like to find the first declaration. But, we
- are in the pseudo-global level created for the
- template parameters, rather than the (surrounding)
- namespace level. Thus, we keep going one more level,
- even though THISLEVEL_ONLY is nonzero. */
- allow_template_parms_p = 0;
- continue;
- }
- else
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
- }
- }
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-}
-
-#if 0
-void
-set_current_level_tags_transparency (tags_transparent)
- int tags_transparent;
-{
- current_binding_level->tag_transparent = tags_transparent;
-}
-#endif
-
-/* Given a type, find the tag that was defined for it and return the tag name.
- Otherwise return 0. However, the value can never be 0
- in the cases in which this is used.
-
- C++: If NAME is nonzero, this is the new name to install. This is
- done when replacing anonymous tags with real tag names. */
-
-static tree
-lookup_tag_reverse (type, name)
- tree type;
- tree name;
-{
- register struct cp_binding_level *level;
-
- timevar_push (TV_NAME_LOOKUP);
-
- for (level = current_binding_level; level; level = level->level_chain)
- {
- binding_entry entry = level->type_decls == NULL
- ? NULL
- : binding_table_reverse_maybe_remap (level->type_decls, type, name);
- if (entry)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->name);
- }
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
-}
-
-/* Look up NAME in the NAMESPACE. */
-
-tree
-lookup_namespace_name (namespace, name)
- tree namespace, name;
-{
- tree val;
- tree template_id = NULL_TREE;
- cxx_binding binding;
-
- timevar_push (TV_NAME_LOOKUP);
-
- my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370);
-
- if (TREE_CODE (name) == NAMESPACE_DECL)
- /* This happens for A::B<int> when B is a namespace. */
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, name);
- else if (TREE_CODE (name) == TEMPLATE_DECL)
- {
- /* This happens for A::B where B is a template, and there are no
- template arguments. */
- error ("invalid use of `%D'", name);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- }
-
- namespace = ORIGINAL_NAMESPACE (namespace);
-
- if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- {
- template_id = name;
- name = TREE_OPERAND (name, 0);
- if (TREE_CODE (name) == OVERLOAD)
- name = DECL_NAME (OVL_CURRENT (name));
- else if (DECL_P (name))
- name = DECL_NAME (name);
- }
-
- my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
-
- cxx_binding_clear (&binding);
- if (!qualified_lookup_using_namespace (name, namespace, &binding, 0))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-
- if (binding.value)
- {
- val = binding.value;
-
- if (template_id)
- {
- if (DECL_CLASS_TEMPLATE_P (val))
- val = lookup_template_class (val,
- TREE_OPERAND (template_id, 1),
- /*in_decl=*/NULL_TREE,
- /*context=*/NULL_TREE,
- /*entering_scope=*/0,
- tf_error | tf_warning);
- else if (DECL_FUNCTION_TEMPLATE_P (val)
- || TREE_CODE (val) == OVERLOAD)
- val = lookup_template_function (val,
- TREE_OPERAND (template_id, 1));
- else
- {
- error ("`%D::%D' is not a template",
- namespace, name);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- }
- }
-
- /* If we have a single function from a using decl, pull it out. */
- if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
- val = OVL_FUNCTION (val);
-
- /* Ignore built-in functions that haven't been prototyped yet. */
- if (!val || !DECL_P(val)
- || !DECL_LANG_SPECIFIC(val)
- || !DECL_ANTICIPATED (val))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
- }
-
- error ("`%D' undeclared in namespace `%D'", name, namespace);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-}
-
/* Hash a TYPENAME_TYPE. K is really of type `tree'. */
static hashval_t
-typename_hash (k)
- const void * k;
+typename_hash (const void* k)
{
hashval_t hash;
tree t = (tree) k;
@@ -5888,9 +2515,7 @@ typename_hash (k)
/* Compare two TYPENAME_TYPEs. K1 and K2 are really of type `tree'. */
static int
-typename_compare (k1, k2)
- const void * k1;
- const void * k2;
+typename_compare (const void * k1, const void * k2)
{
tree t1;
tree t2;
@@ -5920,16 +2545,12 @@ typename_compare (k1, k2)
static GTY ((param_is (union tree_node))) htab_t typename_htab;
-tree
-build_typename_type (context, name, fullname, base_type)
- tree context;
- tree name;
- tree fullname;
- tree base_type;
+static tree
+build_typename_type (tree context, tree name, tree fullname)
{
tree t;
tree d;
- PTR *e;
+ void **e;
if (typename_htab == NULL)
{
@@ -5941,7 +2562,6 @@ build_typename_type (context, name, fullname, base_type)
t = make_aggr_type (TYPENAME_TYPE);
TYPE_CONTEXT (t) = FROB_CONTEXT (context);
TYPENAME_TYPE_FULLNAME (t) = fullname;
- TREE_TYPE (t) = base_type;
/* Build the corresponding TYPE_DECL. */
d = build_decl (TYPE_DECL, name, t);
@@ -5968,12 +2588,15 @@ build_typename_type (context, name, fullname, base_type)
complain about errors, otherwise be quiet. */
tree
-make_typename_type (context, name, complain)
- tree context, name;
- tsubst_flags_t complain;
+make_typename_type (tree context, tree name, tsubst_flags_t complain)
{
tree fullname;
+ if (name == error_mark_node
+ || context == NULL_TREE
+ || context == error_mark_node)
+ return error_mark_node;
+
if (TYPE_P (name))
{
if (!(TYPE_LANG_SPECIFIC (name)
@@ -6002,9 +2625,8 @@ make_typename_type (context, name, complain)
error ("`%D' used without template parameters", name);
return error_mark_node;
}
- if (TREE_CODE (name) != IDENTIFIER_NODE)
- abort ();
-
+ my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 20030802);
+
if (TREE_CODE (context) == NAMESPACE_DECL)
{
/* We can get here from typename_sub0 in the explicit_template_type
@@ -6015,14 +2637,14 @@ make_typename_type (context, name, complain)
return error_mark_node;
}
- if (! uses_template_parms (context)
+ if (!dependent_type_p (context)
|| currently_open_class (context))
{
if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR)
{
tree tmpl = NULL_TREE;
if (IS_AGGR_TYPE (context))
- tmpl = lookup_field (context, name, 0, 0);
+ tmpl = lookup_field (context, name, 0, false);
if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
{
if (complain & tf_error)
@@ -6032,18 +2654,13 @@ make_typename_type (context, name, complain)
}
if (complain & tf_error)
- {
- if (complain & tf_parsing)
- type_access_control (context, tmpl);
- else
- enforce_access (context, tmpl);
- }
+ perform_or_defer_access_check (TYPE_BINFO (context), tmpl);
return lookup_template_class (tmpl,
TREE_OPERAND (fullname, 1),
NULL_TREE, context,
/*entering_scope=*/0,
- tf_error | tf_warning);
+ tf_error | tf_warning | tf_user);
}
else
{
@@ -6056,7 +2673,7 @@ make_typename_type (context, name, complain)
return error_mark_node;
}
- t = lookup_field (context, name, 0, 1);
+ t = lookup_field (context, name, 0, true);
if (t)
{
if (TREE_CODE (t) != TYPE_DECL)
@@ -6067,25 +2684,10 @@ make_typename_type (context, name, complain)
}
if (complain & tf_error)
- {
- if (complain & tf_parsing)
- type_access_control (context, t);
- else
- enforce_access (context, t);
- }
+ perform_or_defer_access_check (TYPE_BINFO (context), t);
if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
t = TREE_TYPE (t);
- if (IMPLICIT_TYPENAME_P (t))
- {
- /* Lookup found an implicit typename that we had
- injected into the current scope. Doing things
- properly would have located the exact same type,
- so there is no error here. We must remove the
- implicitness so that we do not warn about it. */
- t = copy_node (t);
- TREE_TYPE (t) = NULL_TREE;
- }
return t;
}
@@ -6094,14 +2696,14 @@ make_typename_type (context, name, complain)
/* If the CONTEXT is not a template type, then either the field is
there now or its never going to be. */
- if (!uses_template_parms (context))
+ if (!dependent_type_p (context))
{
if (complain & tf_error)
error ("no type named `%#T' in `%#T'", name, context);
return error_mark_node;
}
- return build_typename_type (context, name, fullname, NULL_TREE);
+ return build_typename_type (context, name, fullname);
}
/* Resolve `CONTEXT::template NAME'. Returns an appropriate type,
@@ -6111,9 +2713,7 @@ make_typename_type (context, name, complain)
that occur. */
tree
-make_unbound_class_template (context, name, complain)
- tree context, name;
- tsubst_flags_t complain;
+make_unbound_class_template (tree context, tree name, tsubst_flags_t complain)
{
tree t;
tree d;
@@ -6125,13 +2725,13 @@ make_unbound_class_template (context, name, complain)
if (TREE_CODE (name) != IDENTIFIER_NODE)
abort ();
- if (!uses_template_parms (context)
+ if (!dependent_type_p (context)
|| currently_open_class (context))
{
tree tmpl = NULL_TREE;
if (IS_AGGR_TYPE (context))
- tmpl = lookup_field (context, name, 0, 0);
+ tmpl = lookup_field (context, name, 0, false);
if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl))
{
@@ -6141,12 +2741,7 @@ make_unbound_class_template (context, name, complain)
}
if (complain & tf_error)
- {
- if (complain & tf_parsing)
- type_access_control (context, tmpl);
- else
- enforce_access (context, tmpl);
- }
+ perform_or_defer_access_check (TYPE_BINFO (context), tmpl);
return tmpl;
}
@@ -6166,594 +2761,29 @@ make_unbound_class_template (context, name, complain)
return t;
}
-/* Select the right _DECL from multiple choices. */
-
-static tree
-select_decl (cxx_binding *binding, int flags)
-{
- tree val;
-
- timevar_push (TV_NAME_LOOKUP);
-
- val = BINDING_VALUE (binding);
-
- if (LOOKUP_NAMESPACES_ONLY (flags))
- {
- /* We are not interested in types. */
- if (val && TREE_CODE (val) == NAMESPACE_DECL)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
- }
-
- /* If we could have a type and
- we have nothing or we need a type and have none. */
- if (BINDING_TYPE (binding)
- && (!val || ((flags & LOOKUP_PREFER_TYPES)
- && TREE_CODE (val) != TYPE_DECL)))
- val = TYPE_STUB_DECL (BINDING_TYPE (binding));
- /* Don't return non-types if we really prefer types. */
- else if (val && LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL
- && (TREE_CODE (val) != TEMPLATE_DECL
- || !DECL_CLASS_TEMPLATE_P (val)))
- val = NULL_TREE;
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-}
-
-/* Unscoped lookup of a global: iterate over current namespaces,
- considering using-directives. If SPACESP is non-NULL, store a list
- of the namespaces we've considered in it. */
-
-tree
-unqualified_namespace_lookup (name, flags, spacesp)
- tree name;
- int flags;
- tree *spacesp;
-{
- tree initial = current_decl_namespace ();
- tree scope = initial;
- tree siter;
- struct cp_binding_level *level;
- tree val = NULL_TREE;
- cxx_binding binding;
-
- timevar_push (TV_NAME_LOOKUP);
- cxx_binding_clear (&binding);
- if (spacesp)
- *spacesp = NULL_TREE;
-
- for (; !val; scope = CP_DECL_CONTEXT (scope))
- {
- cxx_binding *b;
- if (spacesp)
- *spacesp = tree_cons (scope, NULL_TREE, *spacesp);
- b = cxx_scope_find_binding_for_name (scope, name);
-
- /* Ignore anticipated built-in functions. */
- if (b && BINDING_VALUE (b) && DECL_P (BINDING_VALUE (b))
- && DECL_LANG_SPECIFIC (BINDING_VALUE (b))
- && DECL_ANTICIPATED (BINDING_VALUE (b)))
- /* Keep binding cleared. */;
- else if (b)
- {
- /* Initialize binding for this context. */
- binding.value = BINDING_VALUE (b);
- binding.type = BINDING_TYPE (b);
- }
-
- /* Add all _DECLs seen through local using-directives. */
- for (level = current_binding_level;
- !level->namespace_p;
- level = level->level_chain)
- if (!lookup_using_namespace (name, &binding, level->using_directives,
- scope, flags, spacesp))
- /* Give up because of error. */
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
-
- /* Add all _DECLs seen through global using-directives. */
- /* XXX local and global using lists should work equally. */
- siter = initial;
- while (1)
- {
- if (!lookup_using_namespace (name, &binding,
- DECL_NAMESPACE_USING (siter),
- scope, flags, spacesp))
- /* Give up because of error. */
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- if (siter == scope) break;
- siter = CP_DECL_CONTEXT (siter);
- }
-
- val = select_decl (&binding, flags);
- if (scope == global_namespace)
- break;
- }
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-}
-
-/* Combine prefer_type and namespaces_only into flags. */
-
-static int
-lookup_flags (prefer_type, namespaces_only)
- int prefer_type, namespaces_only;
-{
- if (namespaces_only)
- return LOOKUP_PREFER_NAMESPACES;
- if (prefer_type > 1)
- return LOOKUP_PREFER_TYPES;
- if (prefer_type > 0)
- return LOOKUP_PREFER_BOTH;
- return 0;
-}
-
-/* Given a lookup that returned VAL, use FLAGS to decide if we want to
- ignore it or not. Subroutine of lookup_name_real. */
-
-static tree
-qualify_lookup (val, flags)
- tree val;
- int flags;
-{
- if (val == NULL_TREE)
- return val;
- if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
- return val;
- if ((flags & LOOKUP_PREFER_TYPES)
- && (TREE_CODE (val) == TYPE_DECL
- || ((flags & LOOKUP_TEMPLATES_EXPECTED)
- && DECL_CLASS_TEMPLATE_P (val))))
- return val;
- if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
- return NULL_TREE;
- return val;
-}
-
-/* Any other BINDING overrides an implicit TYPENAME. Warn about
- that. */
-
-static void
-warn_about_implicit_typename_lookup (typename, binding)
- tree typename;
- tree binding;
-{
- tree subtype = TREE_TYPE (TREE_TYPE (typename));
- tree name = DECL_NAME (typename);
-
- if (! (TREE_CODE (binding) == TEMPLATE_DECL
- && CLASS_TYPE_P (subtype)
- && CLASSTYPE_TEMPLATE_INFO (subtype)
- && CLASSTYPE_TI_TEMPLATE (subtype) == binding)
- && ! (TREE_CODE (binding) == TYPE_DECL
- && same_type_p (TREE_TYPE (binding), subtype)))
- {
- warning ("lookup of `%D' finds `%#D'",
- name, binding);
- warning (" instead of `%D' from dependent base class",
- typename);
- warning (" (use `typename %T::%D' if that's what you meant)",
- constructor_name (current_class_type), name);
- }
-}
-
-/* Check to see whether or not DECL is a variable that would have been
- in scope under the ARM, but is not in scope under the ANSI/ISO
- standard. If so, issue an error message. If name lookup would
- work in both cases, but return a different result, this function
- returns the result of ANSI/ISO lookup. Otherwise, it returns
- DECL. */
-
-tree
-check_for_out_of_scope_variable (tree decl)
-{
- tree shadowed;
-
- /* We only care about out of scope variables. */
- if (!(TREE_CODE (decl) == VAR_DECL && DECL_DEAD_FOR_LOCAL (decl)))
- return decl;
-
- shadowed = DECL_SHADOWED_FOR_VAR (decl);
- while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
- && DECL_DEAD_FOR_LOCAL (shadowed))
- shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
- if (!shadowed)
- shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (decl));
- if (shadowed)
- {
- if (!DECL_ERROR_REPORTED (decl))
- {
- warning ("name lookup of `%D' changed",
- DECL_NAME (decl));
- cp_warning_at (" matches this `%D' under ISO standard rules",
- shadowed);
- cp_warning_at (" matches this `%D' under old rules", decl);
- DECL_ERROR_REPORTED (decl) = 1;
- }
- return shadowed;
- }
-
- /* If we have already complained about this declaration, there's no
- need to do it again. */
- if (DECL_ERROR_REPORTED (decl))
- return decl;
-
- DECL_ERROR_REPORTED (decl) = 1;
- if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
- {
- error ("name lookup of `%D' changed for new ISO `for' scoping",
- DECL_NAME (decl));
- cp_error_at (" cannot use obsolete binding at `%D' because it has a destructor", decl);
- return error_mark_node;
- }
- else
- {
- pedwarn ("name lookup of `%D' changed for new ISO `for' scoping",
- DECL_NAME (decl));
- cp_pedwarn_at (" using obsolete binding at `%D'", decl);
- }
-
- return decl;
-}
-
-/* Look up NAME in the current binding level and its superiors in the
- namespace of variables, functions and typedefs. Return a ..._DECL
- node of some kind representing its definition if there is only one
- such declaration, or return a TREE_LIST with all the overloaded
- definitions if there are many, or return 0 if it is undefined.
-
- If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
- If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
- If PREFER_TYPE is -2, we're being called from yylex(). (UGLY)
- Otherwise we prefer non-TYPE_DECLs.
-
- If NONCLASS is nonzero, we don't look for the NAME in class scope,
- using IDENTIFIER_CLASS_VALUE. */
-
-static tree
-lookup_name_real (name, prefer_type, nonclass, namespaces_only)
- tree name;
- int prefer_type, nonclass, namespaces_only;
-{
- tree t;
- tree val = NULL_TREE;
- int yylex = 0;
- tree from_obj = NULL_TREE;
- int flags;
- int val_is_implicit_typename = 0;
- cxx_binding *iter;
-
- timevar_push (TV_NAME_LOOKUP);
-
- /* Hack: copy flag set by parser, if set. */
- if (only_namespace_names)
- namespaces_only = 1;
-
- if (prefer_type == -2)
- {
- extern int looking_for_typename;
- tree type = NULL_TREE;
-
- yylex = 1;
- prefer_type = looking_for_typename;
-
- flags = lookup_flags (prefer_type, namespaces_only);
- /* If the next thing is '<', class templates are types. */
- if (looking_for_template)
- flags |= LOOKUP_TEMPLATES_EXPECTED;
-
- if (got_scope)
- type = got_scope;
- else if (got_object != error_mark_node)
- type = got_object;
-
- if (type)
- {
- if (type == error_mark_node)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- if (IMPLICIT_TYPENAME_P (type))
- type = TREE_TYPE (type);
-
- if (TYPE_P (type))
- type = complete_type (type);
-
- if (TREE_CODE (type) == VOID_TYPE)
- type = global_namespace;
- if (TREE_CODE (type) == NAMESPACE_DECL)
- {
- cxx_binding b;
- cxx_binding_clear (&b);
- flags |= LOOKUP_COMPLAIN;
- if (!qualified_lookup_using_namespace (name, type, &b, flags))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
- val = select_decl (&b, flags);
- }
- else if (! IS_AGGR_TYPE (type)
- || TREE_CODE (type) == TEMPLATE_TYPE_PARM
- || TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
- || TREE_CODE (type) == TYPENAME_TYPE)
- /* Someone else will give an error about this if needed. */
- val = NULL_TREE;
- else if (type == current_class_type)
- val = IDENTIFIER_CLASS_VALUE (name);
- else
- {
- val = lookup_member (type, name, 0, prefer_type);
- if (!uses_template_parms (type))
- type_access_control (type, val);
-
- /* Restore the containing TYPENAME_TYPE if we looked
- through it before. */
- if (got_scope && got_scope != type
- && val && TREE_CODE (val) == TYPE_DECL
- && TREE_CODE (TREE_TYPE (val)) == TYPENAME_TYPE)
- {
- val = TREE_TYPE (val);
- val = build_typename_type (got_scope, name,
- TYPENAME_TYPE_FULLNAME (val),
- TREE_TYPE (val));
- val = TYPE_STUB_DECL (val);
- }
- }
- }
- else
- val = NULL_TREE;
-
- if (got_scope)
- goto done;
- else if (got_object && val)
- {
- from_obj = val;
- val = NULL_TREE;
- }
- }
- else
- {
- flags = lookup_flags (prefer_type, namespaces_only);
- /* If we're not parsing, we need to complain. */
- flags |= LOOKUP_COMPLAIN;
- }
-
- /* Conversion operators are handled specially because ordinary
- unqualified name lookup will not find template conversion
- operators. */
- if (IDENTIFIER_TYPENAME_P (name))
- {
- struct cp_binding_level *level;
-
- for (level = current_binding_level;
- level && !level->namespace_p;
- level = level->level_chain)
- {
- tree class_type;
- tree operators;
-
- /* A conversion operator can only be declared in a class
- scope. */
- if (level->parm_flag != 2)
- continue;
-
- /* Lookup the conversion operator in the class. */
- class_type = level->this_class;
- operators = lookup_fnfields (class_type, name, /*protect=*/0);
- if (operators)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators);
- }
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
- }
-
- /* First, look in non-namespace scopes. */
-
- if (current_class_type == NULL_TREE)
- nonclass = 1;
-
- for (iter = IDENTIFIER_BINDING (name); iter; iter = iter->previous)
- {
- tree binding;
-
- if (!LOCAL_BINDING_P (iter) && nonclass)
- /* We're not looking for class-scoped bindings, so keep going. */
- continue;
-
- /* If this is the kind of thing we're looking for, we're done. */
- if (qualify_lookup (BINDING_VALUE (iter), flags))
- binding = BINDING_VALUE (iter);
- else if ((flags & LOOKUP_PREFER_TYPES)
- && qualify_lookup (BINDING_TYPE (iter), flags))
- binding = BINDING_TYPE (iter);
- else
- binding = NULL_TREE;
-
- /* Handle access control on types from enclosing or base classes. */
- if (binding && ! yylex
- && BINDING_LEVEL (iter) && BINDING_LEVEL (iter)->parm_flag == 2)
- type_access_control (BINDING_LEVEL (iter)->this_class, binding);
-
- if (binding
- && (!val || !IMPLICIT_TYPENAME_TYPE_DECL_P (binding)))
- {
- if (val_is_implicit_typename && !yylex)
- warn_about_implicit_typename_lookup (val, binding);
- val = binding;
- val_is_implicit_typename
- = IMPLICIT_TYPENAME_TYPE_DECL_P (val);
- if (!val_is_implicit_typename)
- break;
- }
- }
-
- /* The name might be from an enclosing class of the current scope. */
- if (!val && !nonclass && current_class_type)
- val = qualify_lookup (lookup_nested_field (name, !yylex), flags);
-
- /* Now lookup in namespace scopes. */
- if (!val || val_is_implicit_typename)
- {
- t = unqualified_namespace_lookup (name, flags, 0);
- if (t)
- {
- if (val_is_implicit_typename && !yylex)
- warn_about_implicit_typename_lookup (val, t);
- val = t;
- }
- }
-
- done:
- if (val)
- {
- /* This should only warn about types used in qualified-ids. */
- if (from_obj && from_obj != val)
- {
- if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL
- && TREE_CODE (val) == TYPE_DECL
- && ! same_type_p (TREE_TYPE (from_obj), TREE_TYPE (val)))
- pedwarn ("\
-lookup of `%D' in the scope of `%#T' (`%#D') \
-does not match lookup in the current scope (`%#D')",
- name, got_object, from_obj, val);
-
- /* We don't change val to from_obj if got_object depends on
- template parms because that breaks implicit typename for
- destructor calls. */
- if (! uses_template_parms (got_object))
- val = from_obj;
- }
-
- /* If we have a single function from a using decl, pull it out. */
- if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
- val = OVL_FUNCTION (val);
- }
- else if (from_obj)
- val = from_obj;
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
-}
-
-tree
-lookup_name_nonclass (name)
- tree name;
-{
- return lookup_name_real (name, 0, 1, 0);
-}
-
-tree
-lookup_function_nonclass (name, args)
- tree name;
- tree args;
-{
- return lookup_arg_dependent (name, lookup_name_nonclass (name), args);
-}
-
-tree
-lookup_name_namespace_only (name)
- tree name;
-{
- /* type-or-namespace, nonclass, namespace_only */
- return lookup_name_real (name, 1, 1, 1);
-}
-
-tree
-lookup_name (name, prefer_type)
- tree name;
- int prefer_type;
-{
- return lookup_name_real (name, prefer_type, 0, 0);
-}
-
-/* Similar to `lookup_name' but look only in the innermost non-class
- binding level. */
-
-tree
-lookup_name_current_level (name)
- tree name;
-{
- struct cp_binding_level *b;
- tree t = NULL_TREE;
-
- timevar_push (TV_NAME_LOOKUP);
-
- b = current_binding_level;
- while (b->parm_flag == 2)
- b = b->level_chain;
-
- if (b->namespace_p)
- {
- t = IDENTIFIER_NAMESPACE_VALUE (name);
-
- /* extern "C" function() */
- if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
- t = TREE_VALUE (t);
- }
- else if (IDENTIFIER_BINDING (name)
- && LOCAL_BINDING_P (IDENTIFIER_BINDING (name)))
- {
- while (1)
- {
- if (BINDING_LEVEL (IDENTIFIER_BINDING (name)) == b)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name));
+
- if (b->keep == 2)
- b = b->level_chain;
- else
- break;
- }
- }
+/* A chain of TYPE_DECLs for the builtin types. */
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
-}
+static GTY(()) tree builtin_type_decls;
-/* Like lookup_name_current_level, but for types. */
+/* Return a chain of TYPE_DECLs for the builtin types. */
tree
-lookup_type_current_level (name)
- tree name;
-{
- register tree t = NULL_TREE;
-
- timevar_push (TV_NAME_LOOKUP);
-
- my_friendly_assert (! current_binding_level->namespace_p, 980716);
-
- if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
- && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node)
- {
- struct cp_binding_level *b = current_binding_level;
- while (1)
- {
- if (purpose_member (name, b->type_shadowed))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
- REAL_IDENTIFIER_TYPE_VALUE (name));
- if (b->keep == 2)
- b = b->level_chain;
- else
- break;
- }
- }
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
-}
-
-void
-begin_only_namespace_names ()
+cxx_builtin_type_decls (void)
{
- only_namespace_names = 1;
+ return builtin_type_decls;
}
-void
-end_only_namespace_names ()
-{
- only_namespace_names = 0;
-}
-
/* Push the declarations of builtin types into the namespace.
- RID_INDEX is the index of the builtin type
- in the array RID_POINTERS. NAME is the name used when looking
- up the builtin type. TYPE is the _TYPE node for the builtin type. */
+ RID_INDEX is the index of the builtin type in the array
+ RID_POINTERS. NAME is the name used when looking up the builtin
+ type. TYPE is the _TYPE node for the builtin type. */
void
-record_builtin_type (rid_index, name, type)
- enum rid rid_index;
- const char *name;
- tree type;
+record_builtin_type (enum rid rid_index,
+ const char* name,
+ tree type)
{
tree rname = NULL_TREE, tname = NULL_TREE;
tree tdecl = NULL_TREE;
@@ -6763,28 +2793,34 @@ record_builtin_type (rid_index, name, type)
if (name)
tname = get_identifier (name);
- TYPE_BUILT_IN (type) = 1;
-
+ /* The calls to SET_IDENTIFIER_GLOBAL_VALUE below should be
+ eliminated. Built-in types should not be looked up name; their
+ names are keywords that the parser can recognize. However, there
+ is code in c-common.c that uses identifier_global_value to look
+ up built-in types by name. */
if (tname)
{
- tdecl = pushdecl (build_decl (TYPE_DECL, tname, type));
- set_identifier_type_value (tname, NULL_TREE);
- if ((int) rid_index < (int) RID_MAX)
- /* Built-in types live in the global namespace. */
- SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl);
+ tdecl = build_decl (TYPE_DECL, tname, type);
+ DECL_ARTIFICIAL (tdecl) = 1;
+ SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl);
}
- if (rname != NULL_TREE)
+ if (rname)
{
- if (tname != NULL_TREE)
- {
- set_identifier_type_value (rname, NULL_TREE);
- SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl);
- }
- else
+ if (!tdecl)
{
- tdecl = pushdecl (build_decl (TYPE_DECL, rname, type));
- set_identifier_type_value (rname, NULL_TREE);
+ tdecl = build_decl (TYPE_DECL, rname, type);
+ DECL_ARTIFICIAL (tdecl) = 1;
}
+ SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl);
+ }
+
+ if (!TYPE_NAME (type))
+ TYPE_NAME (type) = tdecl;
+
+ if (tdecl)
+ {
+ TREE_CHAIN (tdecl) = builtin_type_decls;
+ builtin_type_decls = tdecl;
}
}
@@ -6794,9 +2830,7 @@ record_builtin_type (rid_index, name, type)
* otherwise it is the negative of the size of one of the other types. */
static tree
-record_builtin_java_type (name, size)
- const char *name;
- int size;
+record_builtin_java_type (const char* name, int size)
{
tree type, decl;
if (size > 0)
@@ -6827,9 +2861,7 @@ record_builtin_java_type (name, size)
/* Push a type into the namespace so that the back-ends ignore it. */
static void
-record_unknown_type (type, name)
- tree type;
- const char *name;
+record_unknown_type (tree type, const char* name)
{
tree decl = pushdecl (build_decl (TYPE_DECL, get_identifier (name), type));
/* Make sure the "unknown type" typedecl gets ignored for debug info. */
@@ -6857,7 +2889,7 @@ typedef struct predefined_identifier
/* Create all the predefined identifiers. */
static void
-initialize_predefined_identifiers ()
+initialize_predefined_identifiers (void)
{
const predefined_identifier *pid;
@@ -6880,6 +2912,7 @@ initialize_predefined_identifiers ()
{ VTABLE_PFN_NAME, &pfn_identifier, 0 },
{ "_vptr", &vptr_identifier, 0 },
{ "__vtt_parm", &vtt_parm_identifier, 0 },
+ { "::", &global_scope_name, 0 },
{ "std", &std_identifier, 0 },
{ NULL, NULL, 0 }
};
@@ -6898,7 +2931,7 @@ initialize_predefined_identifiers ()
Make definitions for built-in primitive functions. */
void
-cxx_init_decl_processing ()
+cxx_init_decl_processing (void)
{
tree void_ftype;
tree void_ftype_ptr;
@@ -6912,10 +2945,14 @@ cxx_init_decl_processing ()
/* Create the global variables. */
push_to_top_level ();
+ current_function_decl = NULL_TREE;
+ current_binding_level = NULL;
/* Enter the global namespace. */
my_friendly_assert (global_namespace == NULL_TREE, 375);
- push_namespace (get_identifier ("::"));
- global_namespace = current_namespace;
+ global_namespace = build_lang_decl (NAMESPACE_DECL, global_scope_name,
+ void_type_node);
+ begin_scope (sk_namespace, global_namespace);
+
current_lang_name = NULL_TREE;
/* Adjust various flags based on command-line settings. */
@@ -6941,26 +2978,11 @@ cxx_init_decl_processing ()
/* Initially, C. */
current_lang_name = lang_name_c;
- current_function_decl = NULL_TREE;
- current_binding_level = NULL_BINDING_LEVEL;
- free_binding_level = NULL_BINDING_LEVEL;
-
build_common_tree_nodes (flag_signed_char);
error_mark_list = build_tree_list (error_mark_node, error_mark_node);
TREE_TYPE (error_mark_list) = error_mark_node;
- /* Make the binding_level structure for global names. */
- pushlevel (0);
- current_binding_level->type_decls = binding_table_new (GLOBAL_SCOPE_HT_SIZE);
- /* The global level is the namespace level of ::. */
- NAMESPACE_LEVEL (global_namespace) = current_binding_level;
- declare_namespace_level ();
-
- VARRAY_TREE_INIT (current_binding_level->static_decls,
- 200,
- "Static declarations");
-
/* Create the `std' namespace. */
push_namespace (std_identifier);
std_node = current_namespace;
@@ -6982,16 +3004,10 @@ cxx_init_decl_processing ()
integer_three_node = build_int_2 (3, 0);
TREE_TYPE (integer_three_node) = integer_type_node;
- boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
- TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
- TYPE_MAX_VALUE (boolean_type_node) = build_int_2 (1, 0);
- TREE_TYPE (TYPE_MAX_VALUE (boolean_type_node)) = boolean_type_node;
- TYPE_PRECISION (boolean_type_node) = 1;
record_builtin_type (RID_BOOL, "bool", boolean_type_node);
- boolean_false_node = build_int_2 (0, 0);
- TREE_TYPE (boolean_false_node) = boolean_type_node;
- boolean_true_node = build_int_2 (1, 0);
- TREE_TYPE (boolean_true_node) = boolean_type_node;
+ truthvalue_type_node = boolean_type_node;
+ truthvalue_false_node = boolean_false_node;
+ truthvalue_true_node = boolean_true_node;
empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE);
@@ -7056,14 +3072,22 @@ cxx_init_decl_processing ()
current_lang_name = lang_name_cplusplus;
{
- tree bad_alloc_type_node, newtype, deltype;
+ tree bad_alloc_id;
+ tree bad_alloc_type_node;
+ tree bad_alloc_decl;
+ tree newtype, deltype;
tree ptr_ftype_sizetype;
push_namespace (std_identifier);
- bad_alloc_type_node
- = xref_tag (class_type, get_identifier ("bad_alloc"),
- /*attributes=*/NULL_TREE, 1);
+ bad_alloc_id = get_identifier ("bad_alloc");
+ bad_alloc_type_node = make_aggr_type (RECORD_TYPE);
+ TYPE_CONTEXT (bad_alloc_type_node) = current_namespace;
+ bad_alloc_decl
+ = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node);
+ DECL_CONTEXT (bad_alloc_decl) = current_namespace;
+ TYPE_STUB_DECL (bad_alloc_type_node) = bad_alloc_decl;
pop_namespace ();
+
ptr_ftype_sizetype
= build_function_type (ptr_type_node,
tree_cons (NULL_TREE,
@@ -7106,12 +3130,11 @@ cxx_init_decl_processing ()
}
/* Generate an initializer for a function naming variable from
- NAME. NAME may be NULL, in which case we generate a special
- ERROR_MARK node which should be replaced later. */
+ NAME. NAME may be NULL, to indicate a dependent name. TYPE_P is
+ filled in with the type of the init. */
tree
-cp_fname_init (name)
- const char *name;
+cp_fname_init (const char* name, tree *type_p)
{
tree domain = NULL_TREE;
tree type;
@@ -7128,12 +3151,12 @@ cp_fname_init (name)
type = build_qualified_type (char_type_node, TYPE_QUAL_CONST);
type = build_cplus_array_type (type, domain);
+ *type_p = type;
+
if (init)
TREE_TYPE (init) = type;
else
- /* We don't know the value until instantiation time. Make
- something which will be digested now, but replaced later. */
- init = build (ERROR_MARK, type);
+ init = error_mark_node;
return init;
}
@@ -7145,16 +3168,15 @@ cp_fname_init (name)
lazily at the point of first use, so we musn't push the decl now. */
static tree
-cp_make_fname_decl (id, type_dep)
- tree id;
- int type_dep;
+cp_make_fname_decl (tree id, int type_dep)
{
const char *const name = (type_dep && processing_template_decl
- ? NULL : fname_as_string (type_dep));
- tree init = cp_fname_init (name);
- tree decl = build_decl (VAR_DECL, id, TREE_TYPE (init));
+ ? NULL : fname_as_string (type_dep));
+ tree type;
+ tree init = cp_fname_init (name, &type);
+ tree decl = build_decl (VAR_DECL, id, type);
- /* As we don't push the decl here, we must set the context. */
+ /* As we're using pushdecl_with_scope, we must set the context. */
DECL_CONTEXT (decl) = current_function_decl;
DECL_PRETTY_FUNCTION_P (decl) = type_dep;
@@ -7165,7 +3187,16 @@ cp_make_fname_decl (id, type_dep)
TREE_USED (decl) = 1;
- cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
+ if (current_function_decl)
+ {
+ struct cp_binding_level *b = current_binding_level;
+ while (b->level_chain->kind != sk_function_parms)
+ b = b->level_chain;
+ pushdecl_with_scope (decl, b);
+ cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
+ }
+ else
+ pushdecl_top_level_and_finish (decl, init);
return decl;
}
@@ -7183,14 +3214,13 @@ cp_make_fname_decl (id, type_dep)
list. */
static tree
-builtin_function_1 (name, type, context, code, class, libname, attrs)
- const char *name;
- tree type;
- tree context;
- int code;
- enum built_in_class class;
- const char *libname;
- tree attrs;
+builtin_function_1 (const char* name,
+ tree type,
+ tree context,
+ int code,
+ enum built_in_class class,
+ const char* libname,
+ tree attrs)
{
tree decl = build_library_fn_1 (get_identifier (name), ERROR_MARK, type);
DECL_BUILT_IN_CLASS (decl) = class;
@@ -7222,7 +3252,7 @@ builtin_function_1 (name, type, context, code, class, libname, attrs)
/* Entry point for the benefit of c_common_nodes_and_builtins.
- Make a defintion for a builtin function named NAME and whose data type
+ Make a definition for a builtin function named NAME and whose data type
is TYPE. TYPE should be a function type with argument types. This
function places the anticipated declaration in the global namespace
and additionally in the std namespace if appropriate.
@@ -7237,13 +3267,12 @@ builtin_function_1 (name, type, context, code, class, libname, attrs)
list. */
tree
-builtin_function (name, type, code, class, libname, attrs)
- const char *name;
- tree type;
- int code;
- enum built_in_class class;
- const char *libname;
- tree attrs;
+builtin_function (const char* name,
+ tree type,
+ int code,
+ enum built_in_class class,
+ const char* libname,
+ tree attrs)
{
/* All builtins that don't begin with an '_' should additionally
go in the 'std' namespace. */
@@ -7262,10 +3291,7 @@ builtin_function (name, type, code, class, libname, attrs)
function. Not called directly. */
static tree
-build_library_fn_1 (name, operator_code, type)
- tree name;
- enum tree_code operator_code;
- tree type;
+build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
{
tree fn = build_lang_decl (FUNCTION_DECL, name, type);
DECL_EXTERNAL (fn) = 1;
@@ -7282,9 +3308,7 @@ build_library_fn_1 (name, operator_code, type)
callers should unset TREE_NOTHROW. */
tree
-build_library_fn (name, type)
- tree name;
- tree type;
+build_library_fn (tree name, tree type)
{
return build_library_fn_1 (name, ERROR_MARK, type);
}
@@ -7292,10 +3316,7 @@ build_library_fn (name, type)
/* Returns the _DECL for a library function with C++ linkage. */
static tree
-build_cp_library_fn (name, operator_code, type)
- tree name;
- enum tree_code operator_code;
- tree type;
+build_cp_library_fn (tree name, enum tree_code operator_code, tree type)
{
tree fn = build_library_fn_1 (name, operator_code, type);
TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
@@ -7309,9 +3330,7 @@ build_cp_library_fn (name, operator_code, type)
IDENTIFIER_NODE. */
tree
-build_library_fn_ptr (name, type)
- const char *name;
- tree type;
+build_library_fn_ptr (const char* name, tree type)
{
return build_library_fn (get_identifier (name), type);
}
@@ -7320,9 +3339,7 @@ build_library_fn_ptr (name, type)
IDENTIFIER_NODE. */
tree
-build_cp_library_fn_ptr (name, type)
- const char *name;
- tree type;
+build_cp_library_fn_ptr (const char* name, tree type)
{
return build_cp_library_fn (get_identifier (name), ERROR_MARK, type);
}
@@ -7331,8 +3348,7 @@ build_cp_library_fn_ptr (name, type)
be able to find it via IDENTIFIER_GLOBAL_VALUE. */
tree
-push_library_fn (name, type)
- tree name, type;
+push_library_fn (tree name, tree type)
{
tree fn = build_library_fn (name, type);
pushdecl_top_level (fn);
@@ -7343,9 +3359,7 @@ push_library_fn (name, type)
will be found by normal lookup. */
static tree
-push_cp_library_fn (operator_code, type)
- enum tree_code operator_code;
- tree type;
+push_cp_library_fn (enum tree_code operator_code, tree type)
{
tree fn = build_cp_library_fn (ansi_opname (operator_code),
operator_code,
@@ -7358,8 +3372,7 @@ push_cp_library_fn (operator_code, type)
a FUNCTION_TYPE. */
tree
-push_void_library_fn (name, parmtypes)
- tree name, parmtypes;
+push_void_library_fn (tree name, tree parmtypes)
{
tree type = build_function_type (void_type_node, parmtypes);
return push_library_fn (name, type);
@@ -7369,28 +3382,13 @@ push_void_library_fn (name, parmtypes)
and does not return. Used for __throw_foo and the like. */
tree
-push_throw_library_fn (name, type)
- tree name, type;
+push_throw_library_fn (tree name, tree type)
{
tree fn = push_library_fn (name, type);
TREE_THIS_VOLATILE (fn) = 1;
TREE_NOTHROW (fn) = 0;
return fn;
}
-
-/* Apply default attributes to a function, if a system function with default
- attributes. */
-
-void
-cxx_insert_default_attributes (decl)
- tree decl;
-{
- if (!DECL_EXTERN_C_FUNCTION_P (decl))
- return;
- if (!TREE_PUBLIC (decl))
- return;
- c_common_insert_default_attributes (decl);
-}
/* When we call finish_struct for an anonymous union, we create
default copy constructors and such. But, an anonymous union
@@ -7403,12 +3401,11 @@ cxx_insert_default_attributes (decl)
union type.) */
void
-fixup_anonymous_aggr (t)
- tree t;
+fixup_anonymous_aggr (tree t)
{
tree *q;
- /* Wipe out memory of synthesized methods */
+ /* Wipe out memory of synthesized methods. */
TYPE_HAS_CONSTRUCTOR (t) = 0;
TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0;
TYPE_HAS_INIT_REF (t) = 0;
@@ -7429,7 +3426,8 @@ fixup_anonymous_aggr (t)
/* ISO C++ 9.5.3. Anonymous unions may not have function members. */
if (TYPE_METHODS (t))
- cp_error_at ("an anonymous union cannot have function members", t);
+ error ("%Jan anonymous union cannot have function members",
+ TYPE_MAIN_DECL (t));
/* Anonymous aggregates cannot have fields with ctors, dtors or complex
assignment operators (because they cannot have these methods themselves).
@@ -7460,30 +3458,32 @@ fixup_anonymous_aggr (t)
}
/* Make sure that a declaration with no declarator is well-formed, i.e.
- just defines a tagged type or anonymous union.
+ just declares a tagged type or anonymous union.
- Returns the type defined, if any. */
+ Returns the type declared; or NULL_TREE if none. */
tree
-check_tag_decl (declspecs)
- tree declspecs;
+check_tag_decl (tree declspecs)
{
int found_type = 0;
int saw_friend = 0;
int saw_typedef = 0;
tree ob_modifier = NULL_TREE;
- register tree link;
- register tree t = NULL_TREE;
+ tree link;
+ /* If a class, struct, or enum type is declared by the DECLSPECS
+ (i.e, if a class-specifier, enum-specifier, or non-typename
+ elaborated-type-specifier appears in the DECLSPECS),
+ DECLARED_TYPE is set to the corresponding type. */
+ tree declared_type = NULL_TREE;
+ bool error_p = false;
for (link = declspecs; link; link = TREE_CHAIN (link))
{
- register tree value = TREE_VALUE (link);
+ tree value = TREE_VALUE (link);
- if (TYPE_P (value)
- || TREE_CODE (value) == TYPE_DECL
+ if (TYPE_P (value) || TREE_CODE (value) == TYPE_DECL
|| (TREE_CODE (value) == IDENTIFIER_NODE
- && IDENTIFIER_GLOBAL_VALUE (value)
- && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (value)) == TYPE_DECL))
+ && is_typename_at_global_scope (value)))
{
++found_type;
@@ -7499,7 +3499,7 @@ check_tag_decl (declspecs)
|| TREE_CODE (value) == ENUMERAL_TYPE))
{
my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261);
- t = value;
+ declared_type = value;
}
}
else if (value == ridpointers[(int) RID_TYPEDEF])
@@ -7523,17 +3523,18 @@ check_tag_decl (declspecs)
|| value == ridpointers[(int) RID_EXPLICIT]
|| value == ridpointers[(int) RID_THREAD])
ob_modifier = value;
+ else if (value == error_mark_node)
+ error_p = true;
}
if (found_type > 1)
error ("multiple types in one declaration");
- if (t == NULL_TREE && ! saw_friend)
+ if (declared_type == NULL_TREE && ! saw_friend && !error_p)
pedwarn ("declaration does not declare anything");
-
/* Check for an anonymous union. */
- else if (t && IS_AGGR_TYPE_CODE (TREE_CODE (t))
- && TYPE_ANONYMOUS_P (t))
+ else if (declared_type && IS_AGGR_TYPE_CODE (TREE_CODE (declared_type))
+ && TYPE_ANONYMOUS_P (declared_type))
{
/* 7/3 In a simple-declaration, the optional init-declarator-list
can be omitted only when declaring a class (clause 9) or
@@ -7557,9 +3558,10 @@ check_tag_decl (declspecs)
return NULL_TREE;
}
/* Anonymous unions are objects, so they can have specifiers. */;
- SET_ANON_AGGR_TYPE_P (t);
+ SET_ANON_AGGR_TYPE_P (declared_type);
- if (TREE_CODE (t) != UNION_TYPE && pedantic && ! in_system_header)
+ if (TREE_CODE (declared_type) != UNION_TYPE && pedantic
+ && !in_system_header)
pedwarn ("ISO C++ prohibits anonymous structs");
}
@@ -7578,7 +3580,7 @@ check_tag_decl (declspecs)
ob_modifier);
}
- return t;
+ return declared_type;
}
/* Called when a declaration is seen that contains no names to declare.
@@ -7590,23 +3592,26 @@ check_tag_decl (declspecs)
Otherwise, it is an error.
C++: may have to grok the declspecs to learn about static,
- complain for anonymous unions. */
+ complain for anonymous unions.
-void
-shadow_tag (declspecs)
- tree declspecs;
+ Returns the TYPE declared -- or NULL_TREE if none. */
+
+tree
+shadow_tag (tree declspecs)
{
tree t = check_tag_decl (declspecs);
- if (t)
- maybe_process_partial_specialization (t);
+ if (!t)
+ return NULL_TREE;
+
+ maybe_process_partial_specialization (t);
/* This is where the variables in an anonymous union are
declared. An anonymous union declaration looks like:
union { ... } ;
because there is no declarator after the union, the parser
sends that declaration here. */
- if (t && ANON_AGGR_TYPE_P (t))
+ if (ANON_AGGR_TYPE_P (t))
{
fixup_anonymous_aggr (t);
@@ -7617,13 +3622,14 @@ shadow_tag (declspecs)
finish_anon_union (decl);
}
}
+
+ return t;
}
/* Decode a "typename", such as "int **", returning a ..._TYPE node. */
tree
-groktypename (typename)
- tree typename;
+groktypename (tree typename)
{
tree specs, attrs;
tree type;
@@ -7653,20 +3659,16 @@ groktypename (typename)
grokfield and not through here. */
tree
-start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
- tree declarator, declspecs;
- int initialized;
- tree attributes, prefix_attributes;
+start_decl (tree declarator,
+ tree declspecs,
+ int initialized,
+ tree attributes,
+ tree prefix_attributes)
{
tree decl;
- register tree type, tem;
+ tree type, tem;
tree context;
-#if 0
- /* See code below that used this. */
- int init_written = initialized;
-#endif
-
/* This should only be done once on the top most decl. */
if (have_extern_spec)
{
@@ -7756,25 +3758,25 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
&& DECL_DECLARED_INLINE_P (decl)
&& DECL_UNINLINABLE (decl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
- warning_with_decl (decl,
- "inline function `%s' given attribute noinline");
+ warning ("%Jinline function '%D' given attribute noinline", decl, decl);
if (context && COMPLETE_TYPE_P (complete_type (context)))
{
- push_nested_class (context, 2);
+ push_nested_class (context);
if (TREE_CODE (decl) == VAR_DECL)
{
- tree field = lookup_field (context, DECL_NAME (decl), 0, 0);
+ tree field = lookup_field (context, DECL_NAME (decl), 0, false);
if (field == NULL_TREE || TREE_CODE (field) != VAR_DECL)
error ("`%#D' is not a static member of `%#T'", decl, context);
else
{
if (DECL_CONTEXT (field) != context)
{
- pedwarn ("ISO C++ does not permit `%T::%D' to be defined as `%T::%D'",
- DECL_CONTEXT (field), DECL_NAME (decl),
- context, DECL_NAME (decl));
+ if (!same_type_p (DECL_CONTEXT (field), context))
+ pedwarn ("ISO C++ does not permit `%T::%D' to be defined as `%T::%D'",
+ DECL_CONTEXT (field), DECL_NAME (decl),
+ context, DECL_NAME (decl));
DECL_CONTEXT (decl) = DECL_CONTEXT (field);
}
/* Static data member are tricky; an in-class initialization
@@ -7790,7 +3792,9 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
}
else
{
- tree field = check_classfn (context, decl);
+ tree field = check_classfn (context, decl,
+ processing_template_decl
+ > template_class_depth (context));
if (field && duplicate_decls (decl, field))
decl = field;
}
@@ -7821,6 +3825,8 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
if (processing_template_decl)
tem = push_template_decl (tem);
+ if (tem == error_mark_node)
+ return error_mark_node;
#if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS)
/* Tell the back-end to use or not use .common as appropriate. If we say
@@ -7840,8 +3846,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes)
}
void
-start_decl_1 (decl)
- tree decl;
+start_decl_1 (tree decl)
{
tree type = TREE_TYPE (decl);
int initialized = (DECL_INITIAL (decl) != NULL_TREE);
@@ -7849,8 +3854,6 @@ start_decl_1 (decl)
if (type == error_mark_node)
return;
- maybe_push_cleanup_level (type);
-
if (initialized)
/* Is it valid for this decl to have an initializer at all?
If not, set INITIALIZED to zero, which will indirectly
@@ -7906,18 +3909,26 @@ start_decl_1 (decl)
if (! initialized)
DECL_INITIAL (decl) = NULL_TREE;
+
+ /* Create a new scope to hold this declaration if necessary.
+ Whether or not a new scope is necessary cannot be determined
+ until after the type has been completed; if the type is a
+ specialization of a class template it is not until after
+ instantiation has occurred that TYPE_HAS_NONTRIVIAL_DESTRUCTOR
+ will be set correctly. */
+ maybe_push_cleanup_level (type);
}
/* Handle initialization of references. DECL, TYPE, and INIT have the
same meaning as in cp_finish_decl. *CLEANUP must be NULL on entry,
but will be set to a new CLEANUP_STMT if a temporary is created
- that must be destroeyd subsequently.
+ that must be destroyed subsequently.
Returns an initializer expression to use to initialize DECL, or
NULL if the initialization can be performed statically.
Quotes on semantics can be found in ARM 8.4.3. */
-
+
static tree
grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
{
@@ -7932,9 +3943,6 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
return NULL_TREE;
}
- if (init == error_mark_node)
- return NULL_TREE;
-
if (TREE_CODE (init) == CONSTRUCTOR)
{
error ("ISO C++ forbids use of initializer list to initialize reference `%D'", decl);
@@ -7942,17 +3950,15 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
}
if (TREE_CODE (init) == TREE_LIST)
- init = build_compound_expr (init);
+ init = build_x_compound_expr_from_list (init, "initializer");
if (TREE_CODE (TREE_TYPE (init)) == REFERENCE_TYPE)
init = convert_from_reference (init);
if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE)
- {
- /* Note: default conversion is only called in very special cases. */
- init = default_conversion (init);
- }
+ /* Note: default conversion is only called in very special cases. */
+ init = decay_conversion (init);
/* Convert INIT to the reference type TYPE. This may involve the
creation of a temporary, whose lifetime must be the same as that
@@ -7984,9 +3990,7 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
situation we're in, update DECL accordingly. */
static void
-maybe_deduce_size_from_array_init (decl, init)
- tree decl;
- tree init;
+maybe_deduce_size_from_array_init (tree decl, tree init)
{
tree type = TREE_TYPE (decl);
@@ -8028,8 +4032,7 @@ maybe_deduce_size_from_array_init (decl, init)
any appropriate error messages regarding the layout. */
static void
-layout_var_decl (decl)
- tree decl;
+layout_var_decl (tree decl)
{
tree type = TREE_TYPE (decl);
#if 0
@@ -8039,7 +4042,7 @@ layout_var_decl (decl)
/* If we haven't already layed out this declaration, do so now.
Note that we must not call complete type for an external object
because it's type might involve templates that we are not
- supposed to isntantiate yet. (And it's perfectly valid to say
+ supposed to instantiate yet. (And it's perfectly valid to say
`extern X x' for some incomplete type `X'.) */
if (!DECL_EXTERNAL (decl))
complete_type (type);
@@ -8093,8 +4096,7 @@ layout_var_decl (decl)
instance of the variable at link-time. */
static void
-maybe_commonize_var (decl)
- tree decl;
+maybe_commonize_var (tree decl)
{
/* Static data in a function with comdat linkage also has comdat
linkage. */
@@ -8135,7 +4137,8 @@ maybe_commonize_var (decl)
TREE_PUBLIC (decl) = 0;
DECL_COMMON (decl) = 0;
cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl);
- cp_warning_at (" you can work around this by removing the initializer", decl);
+ warning ("%J you can work around this by removing the initializer",
+ decl);
}
}
}
@@ -8148,8 +4151,7 @@ maybe_commonize_var (decl)
/* Issue an error message if DECL is an uninitialized const variable. */
static void
-check_for_uninitialized_const_var (decl)
- tree decl;
+check_for_uninitialized_const_var (tree decl)
{
tree type = TREE_TYPE (decl);
@@ -8209,19 +4211,13 @@ reshape_init (tree type, tree *initp)
old_init_value = (TREE_CODE (*initp) == TREE_LIST
? TREE_VALUE (*initp) : old_init);
- /* For some parse errors, OLD_INIT_VALUE may be NULL. */
- if (!old_init_value)
- {
- my_friendly_assert (TREE_CODE (old_init) == TREE_LIST, 20021202);
- TREE_VALUE (old_init) = error_mark_node;
- *initp = TREE_CHAIN (old_init);
- return old_init;
- }
+ my_friendly_assert (old_init_value, 20030723);
/* If the initializer is brace-enclosed, pull initializers from the
enclosed elements. Advance past the brace-enclosed initializer
now. */
- if (TREE_CODE (old_init_value) == CONSTRUCTOR
+ if (TREE_CODE (old_init_value) == CONSTRUCTOR
+ && TREE_TYPE (old_init_value) == NULL_TREE
&& TREE_HAS_CONSTRUCTOR (old_init_value))
{
*initp = TREE_CHAIN (old_init);
@@ -8266,8 +4262,7 @@ reshape_init (tree type, tree *initp)
non-empty subaggregate, brace elision is assumed and the
initializer is considered for the initialization of the first
member of the subaggregate. */
- if (CLASS_TYPE_P (type)
- && !brace_enclosed_p
+ if (!brace_enclosed_p
&& can_convert_arg (type, TREE_TYPE (old_init_value), old_init_value))
{
*initp = TREE_CHAIN (old_init);
@@ -8293,7 +4288,7 @@ reshape_init (tree type, tree *initp)
else
{
/* Build a CONSTRUCTOR to hold the contents of the aggregate. */
- new_init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
+ new_init = build_constructor (type, NULL_TREE);
TREE_HAS_CONSTRUCTOR (new_init) = 1;
if (CLASS_TYPE_P (type))
@@ -8310,8 +4305,11 @@ reshape_init (tree type, tree *initp)
empty class shall have the form of an empty
initializer-list {}. */
if (!brace_enclosed_p)
- error ("initializer for `%T' must be brace-enclosed",
- type);
+ {
+ error ("initializer for `%T' must be brace-enclosed",
+ type);
+ return error_mark_node;
+ }
}
else
{
@@ -8336,6 +4334,8 @@ reshape_init (tree type, tree *initp)
break;
field_init = reshape_init (TREE_TYPE (field), initp);
+ if (field_init == error_mark_node)
+ return error_mark_node;
TREE_CHAIN (field_init) = CONSTRUCTOR_ELTS (new_init);
CONSTRUCTOR_ELTS (new_init) = field_init;
/* [dcl.init.aggr]
@@ -8349,14 +4349,14 @@ reshape_init (tree type, tree *initp)
}
}
}
- else if (TREE_CODE (type) == ARRAY_TYPE)
+ else if ((TREE_CODE (type) == ARRAY_TYPE)|| (TREE_CODE (type) == VECTOR_TYPE))
{
tree index;
tree max_index;
/* If the bound of the array is known, take no more initializers
than are allowed. */
- max_index = (TYPE_DOMAIN (type)
+ max_index = ((TYPE_DOMAIN (type) && (TREE_CODE (type) == ARRAY_TYPE))
? array_type_nelts (type) : NULL_TREE);
/* Loop through the array elements, gathering initializers. */
for (index = size_zero_node;
@@ -8366,10 +4366,22 @@ reshape_init (tree type, tree *initp)
tree element_init;
element_init = reshape_init (TREE_TYPE (type), initp);
+ if (element_init == error_mark_node)
+ return error_mark_node;
TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init);
CONSTRUCTOR_ELTS (new_init) = element_init;
if (TREE_PURPOSE (element_init))
- index = TREE_PURPOSE (element_init);
+ {
+ tree next_index = TREE_PURPOSE (element_init);
+ if (TREE_CODE (next_index) == IDENTIFIER_NODE)
+ {
+ error ("name `%D' used in a GNU-style designated "
+ "initializer for an array", next_index);
+ TREE_PURPOSE (element_init) = NULL_TREE;
+ }
+ else
+ index = next_index;
+ }
}
}
else
@@ -8402,6 +4414,7 @@ static tree
check_initializer (tree decl, tree init, int flags, tree *cleanup)
{
tree type = TREE_TYPE (decl);
+ tree init_code = NULL;
/* If `start_decl' didn't like having an initialization, ignore it now. */
if (init != NULL_TREE && DECL_INITIAL (decl) == NULL_TREE)
@@ -8465,6 +4478,12 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
scalar, so just don't call it. */
if (CP_AGGREGATE_TYPE_P (type))
init = reshape_init (type, &init);
+
+ if ((*targetm.vector_opaque_p) (type))
+ {
+ error ("opaque vector types cannot be initialized");
+ init = error_mark_node;
+ }
}
/* If DECL has an array type without a specific bound, deduce the
@@ -8512,7 +4531,10 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
{
dont_use_constructor:
if (TREE_CODE (init) != TREE_VEC)
- init = store_init_value (decl, init);
+ {
+ init_code = store_init_value (decl, init);
+ init = NULL;
+ }
}
}
else if (DECL_EXTERNAL (decl))
@@ -8535,18 +4557,15 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
check_for_uninitialized_const_var (decl);
if (init && init != error_mark_node)
- init = build (INIT_EXPR, type, decl, init);
+ init_code = build (INIT_EXPR, type, decl, init);
- return init;
+ return init_code;
}
/* If DECL is not a local variable, give it RTL. */
static void
-make_rtl_for_nonlocal_decl (decl, init, asmspec)
- tree decl;
- tree init;
- const char *asmspec;
+make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
{
int toplev = toplevel_bindings_p ();
int defer_p;
@@ -8572,7 +4591,7 @@ make_rtl_for_nonlocal_decl (decl, init, asmspec)
/* Set the DECL_ASSEMBLER_NAME for the variable. */
if (asmspec)
{
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
+ change_decl_assembler_name (decl, get_identifier (asmspec));
/* The `register' keyword, when used together with an
asm-specification, indicates that the variable should be
placed in a particular register. */
@@ -8624,66 +4643,10 @@ make_rtl_for_nonlocal_decl (decl, init, asmspec)
rest_of_decl_compilation (decl, asmspec, toplev, at_eof);
}
-/* The old ARM scoping rules injected variables declared in the
- initialization statement of a for-statement into the surrounding
- scope. We support this usage, in order to be backward-compatible.
- DECL is a just-declared VAR_DECL; if necessary inject its
- declaration into the surrounding scope. */
-
-void
-maybe_inject_for_scope_var (decl)
- tree decl;
-{
- timevar_push (TV_NAME_LOOKUP);
-
- if (!DECL_NAME (decl))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0);
-
- /* Declarations of __FUNCTION__ and its ilk appear magically when
- the variable is first used. If that happens to be inside a
- for-loop, we don't want to do anything special. */
- if (DECL_PRETTY_FUNCTION_P (decl))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0);
-
- if (current_binding_level->is_for_scope)
- {
- struct cp_binding_level *outer
- = current_binding_level->level_chain;
-
- /* Check to see if the same name is already bound at the outer
- level, either because it was directly declared, or because a
- dead for-decl got preserved. In either case, the code would
- not have been valid under the ARM scope rules, so clear
- is_for_scope for the current_binding_level.
-
- Otherwise, we need to preserve the temp slot for decl to last
- into the outer binding level. */
-
- cxx_binding *outer_binding
- = IDENTIFIER_BINDING (DECL_NAME (decl))->previous;
-
- if (outer_binding && BINDING_LEVEL (outer_binding) == outer
- && (TREE_CODE (BINDING_VALUE (outer_binding))
- == VAR_DECL)
- && DECL_DEAD_FOR_LOCAL (BINDING_VALUE (outer_binding)))
- {
- BINDING_VALUE (outer_binding)
- = DECL_SHADOWED_FOR_VAR (BINDING_VALUE (outer_binding));
- current_binding_level->is_for_scope = 0;
- }
- else if (DECL_IN_MEMORY_P (decl))
- preserve_temp_slots (DECL_RTL (decl));
- }
-
- timevar_pop (TV_NAME_LOOKUP);
-}
-
/* Generate code to initialize DECL (a local variable). */
static void
-initialize_local_var (decl, init)
- tree decl;
- tree init;
+initialize_local_var (tree decl, tree init)
{
tree type = TREE_TYPE (decl);
tree cleanup;
@@ -8753,10 +4716,7 @@ initialize_local_var (decl, init)
if the (init) syntax was used. */
void
-cp_finish_decl (decl, init, asmspec_tree, flags)
- tree decl, init;
- tree asmspec_tree;
- int flags;
+cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
{
tree type;
tree ttype = NULL_TREE;
@@ -8764,20 +4724,24 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
const char *asmspec = NULL;
int was_readonly = 0;
- if (! decl)
+ if (decl == error_mark_node)
+ return;
+ else if (! decl)
{
if (init)
error ("assignment (not initialization) in declaration");
return;
}
+ my_friendly_assert (TREE_CODE (decl) != RESULT_DECL, 20030619);
+
/* Assume no cleanup is required. */
cleanup = NULL_TREE;
/* If a name was specified, get the string. */
if (global_scope_p (current_binding_level))
asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
- if (asmspec_tree)
+ if (asmspec_tree)
asmspec = TREE_STRING_POINTER (asmspec_tree);
if (init && TREE_CODE (init) == NAMESPACE_DECL)
@@ -8806,7 +4770,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
type = TREE_TYPE (decl);
if (type == error_mark_node)
- return;
+ goto finish_end0;
if (TYPE_HAS_MUTABLE_P (type))
TREE_READONLY (decl) = 0;
@@ -8814,12 +4778,15 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
if (processing_template_decl)
{
/* Add this declaration to the statement-tree. */
- if (at_function_scope_p ()
- && TREE_CODE (decl) != RESULT_DECL)
+ if (at_function_scope_p ())
add_decl_stmt (decl);
if (init && DECL_INITIAL (decl))
DECL_INITIAL (decl) = init;
+ if (TREE_CODE (decl) == VAR_DECL
+ && !DECL_PRETTY_FUNCTION_P (decl)
+ && !dependent_type_p (TREE_TYPE (decl)))
+ maybe_deduce_size_from_array_init (decl, init);
goto finish_end0;
}
@@ -8834,8 +4801,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
{
if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type)
warning ("shadowing previous type declaration of `%#D'", decl);
- set_identifier_type_value (DECL_NAME (decl), type);
- CLASSTYPE_GOT_SEMICOLON (type) = 1;
+ set_identifier_type_value (DECL_NAME (decl), decl);
}
/* If we have installed this as the canonical typedef for this
@@ -8853,29 +4819,20 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
if (TREE_CODE (decl) != FUNCTION_DECL)
ttype = target_type (type);
- if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl)
- && (TYPE_NEEDS_CONSTRUCTING (type)
- || TREE_CODE (type) == REFERENCE_TYPE))
+
+ /* Currently, GNU C++ puts constants in text space, making them
+ impossible to initialize. In the future, one would hope for
+ an operating system which understood the difference between
+ initialization and the running of a program. */
+ if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl))
{
- /* Currently, GNU C++ puts constants in text space, making them
- impossible to initialize. In the future, one would hope for
- an operating system which understood the difference between
- initialization and the running of a program. */
was_readonly = 1;
- TREE_READONLY (decl) = 0;
+ if (TYPE_NEEDS_CONSTRUCTING (type)
+ || TREE_CODE (type) == REFERENCE_TYPE)
+ TREE_READONLY (decl) = 0;
}
- if (TREE_CODE (decl) == FIELD_DECL && asmspec)
- {
- /* This must override the asm specifier which was placed by
- grokclassfn. Lay this out fresh. */
- SET_DECL_RTL (TREE_TYPE (decl), NULL_RTX);
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
- make_decl_rtl (decl, asmspec);
- }
- else if (TREE_CODE (decl) == RESULT_DECL)
- init = check_initializer (decl, init, flags, &cleanup);
- else if (TREE_CODE (decl) == VAR_DECL)
+ if (TREE_CODE (decl) == VAR_DECL)
{
/* Only PODs can have thread-local storage. Other types may require
various kinds of non-trivial initialization. */
@@ -8930,9 +4887,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
/* Add this declaration to the statement-tree. This needs to happen
after the call to check_initializer so that the DECL_STMT for a
reference temp is added before the DECL_STMT for the reference itself. */
- if (building_stmt_tree ()
- && at_function_scope_p ()
- && TREE_CODE (decl) != RESULT_DECL)
+ if (at_function_scope_p ())
add_decl_stmt (decl);
if (TREE_CODE (decl) == VAR_DECL)
@@ -8941,8 +4896,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
/* Output the assembler code and/or RTL code for variables and functions,
unless the type is an undefined structure or union.
If not, it will get done when the type is completed. */
- if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL
- || TREE_CODE (decl) == RESULT_DECL)
+ if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
{
if (TREE_CODE (decl) == VAR_DECL)
maybe_commonize_var (decl);
@@ -8953,8 +4907,19 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
|| TREE_CODE (type) == METHOD_TYPE)
abstract_virtuals_error (decl,
strip_array_types (TREE_TYPE (type)));
+ else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
+ {
+ /* If it's either a pointer or an array type, strip through all
+ of them but the last one. If the last is an array type, issue
+ an error if the element type is abstract. */
+ while (POINTER_TYPE_P (TREE_TYPE (type))
+ || TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ abstract_virtuals_error (decl, TREE_TYPE (type));
+ }
else
- abstract_virtuals_error (decl, strip_array_types (type));
+ abstract_virtuals_error (decl, type);
if (TREE_CODE (decl) == FUNCTION_DECL
|| TREE_TYPE (decl) == error_mark_node)
@@ -8973,8 +4938,7 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
if (DECL_FUNCTION_SCOPE_P (decl))
{
/* This is a local declaration. */
- if (doing_semantic_analysis_p ())
- maybe_inject_for_scope_var (decl);
+ maybe_inject_for_scope_var (decl);
/* Initialize the local variable. */
if (processing_template_decl)
{
@@ -9019,14 +4983,16 @@ cp_finish_decl (decl, init, asmspec_tree, flags)
if (was_readonly)
TREE_READONLY (decl) = 1;
+
+ /* If this was marked 'used', be sure it will be output. */
+ if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
+ mark_referenced (DECL_ASSEMBLER_NAME (decl));
}
-/* This is here for a midend callback from c-common.c */
+/* This is here for a midend callback from c-common.c. */
void
-finish_decl (decl, init, asmspec_tree)
- tree decl, init;
- tree asmspec_tree;
+finish_decl (tree decl, tree init, tree asmspec_tree)
{
cp_finish_decl (decl, init, asmspec_tree, 0);
}
@@ -9039,9 +5005,7 @@ finish_decl (decl, init, asmspec_tree)
variables. */
tree
-declare_global_var (name, type)
- tree name;
- tree type;
+declare_global_var (tree name, tree type)
{
tree decl;
@@ -9062,7 +5026,7 @@ declare_global_var (name, type)
`__cxa_atexit' function specified in the IA64 C++ ABI. */
static tree
-get_atexit_node ()
+get_atexit_node (void)
{
tree atexit_fndecl;
tree arg_types;
@@ -9117,7 +5081,7 @@ get_atexit_node ()
atexit_fndecl = build_library_fn_ptr (name, fn_type);
mark_used (atexit_fndecl);
pop_lang_context ();
- atexit_node = default_conversion (atexit_fndecl);
+ atexit_node = decay_conversion (atexit_fndecl);
return atexit_node;
}
@@ -9125,7 +5089,7 @@ get_atexit_node ()
/* Returns the __dso_handle VAR_DECL. */
static tree
-get_dso_handle_node ()
+get_dso_handle_node (void)
{
if (dso_handle_node)
return dso_handle_node;
@@ -9140,10 +5104,11 @@ get_dso_handle_node ()
/* Begin a new function with internal linkage whose job will be simply
to destroy some particular variable. */
+static GTY(()) int start_cleanup_cnt;
+
static tree
-start_cleanup_fn ()
+start_cleanup_fn (void)
{
- static int counter = 0;
int old_interface_only = interface_only;
int old_interface_unknown = interface_unknown;
char name[32];
@@ -9170,7 +5135,7 @@ start_cleanup_fn ()
/* Build the function type itself. */
fntype = build_function_type (void_type_node, parmtypes);
/* Build the name of the function. */
- sprintf (name, "__tcf_%d", counter++);
+ sprintf (name, "__tcf_%d", start_cleanup_cnt++);
/* Build the function declaration. */
fndecl = build_lang_decl (FUNCTION_DECL, get_identifier (name), fntype);
/* It's a function with internal linkage, generated by the
@@ -9182,6 +5147,8 @@ start_cleanup_fn ()
it is only called via a function pointer, but we avoid unnecessary
emissions this way. */
DECL_INLINE (fndecl) = 1;
+ DECL_DECLARED_INLINE_P (fndecl) = 1;
+ DECL_INTERFACE_KNOWN (fndecl) = 1;
/* Build the parameter. */
if (flag_use_cxa_atexit)
{
@@ -9207,9 +5174,9 @@ start_cleanup_fn ()
/* Finish the cleanup function begun by start_cleanup_fn. */
static void
-end_cleanup_fn ()
+end_cleanup_fn (void)
{
- expand_body (finish_function (0));
+ expand_or_defer_fn (finish_function (0));
pop_from_top_level ();
}
@@ -9218,16 +5185,13 @@ end_cleanup_fn ()
static storage duration. */
void
-register_dtor_fn (decl)
- tree decl;
+register_dtor_fn (tree decl)
{
tree cleanup;
tree compound_stmt;
tree args;
tree fcall;
- int saved_flag_access_control;
-
if (TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
return;
@@ -9243,19 +5207,20 @@ register_dtor_fn (decl)
to the original function, rather than the anonymous one. That
will make the back-end think that nested functions are in use,
which causes confusion. */
- saved_flag_access_control = flag_access_control;
- flag_access_control = 0;
+
+ push_deferring_access_checks (dk_no_check);
fcall = build_cleanup (decl);
- flag_access_control = saved_flag_access_control;
+ pop_deferring_access_checks ();
/* Create the body of the anonymous function. */
- compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
+ compound_stmt = begin_compound_stmt (/*has_no_scope=*/false);
finish_expr_stmt (fcall);
- finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
+ finish_compound_stmt (compound_stmt);
end_cleanup_fn ();
/* Call atexit with the cleanup function. */
cxx_mark_addressable (cleanup);
+ mark_used (cleanup);
cleanup = build_unary_op (ADDR_EXPR, cleanup, 0);
if (flag_use_cxa_atexit)
{
@@ -9275,12 +5240,8 @@ register_dtor_fn (decl)
and destruction of DECL. */
static void
-expand_static_init (decl, init)
- tree decl;
- tree init;
+expand_static_init (tree decl, tree init)
{
- tree oldstatic;
-
my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 20021010);
my_friendly_assert (TREE_STATIC (decl), 20021010);
@@ -9290,14 +5251,7 @@ expand_static_init (decl, init)
&& TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
return;
- oldstatic = value_member (decl, static_aggregates);
-
- if (oldstatic)
- {
- if (TREE_PURPOSE (oldstatic) && init != NULL_TREE)
- error ("multiple initializations given for `%D'", decl);
- }
- else if (! toplevel_bindings_p ())
+ if (! toplevel_bindings_p ())
{
/* Emit code to perform this initialization but once. */
tree if_stmt;
@@ -9337,7 +5291,7 @@ expand_static_init (decl, init)
/* Begin the conditional initialization. */
if_stmt = begin_if_stmt ();
finish_if_stmt_cond (get_guard_cond (guard), if_stmt);
- then_clause = begin_compound_stmt (/*has_no_scope=*/0);
+ then_clause = begin_compound_stmt (/*has_no_scope=*/false);
/* Do the initialization itself. */
assignment = init ? init : NULL_TREE;
@@ -9352,12 +5306,7 @@ expand_static_init (decl, init)
run until after TEMP is set to 1. */
guard_init = set_guard (guard);
if (assignment)
- {
- assignment = tree_cons (NULL_TREE, assignment,
- build_tree_list (NULL_TREE,
- guard_init));
- assignment = build_compound_expr (assignment);
- }
+ assignment = build_compound_expr (assignment, guard_init);
else
assignment = guard_init;
finish_expr_stmt (assignment);
@@ -9366,7 +5315,7 @@ expand_static_init (decl, init)
variable. */
register_dtor_fn (decl);
- finish_compound_stmt (/*has_no_scope=*/0, then_clause);
+ finish_compound_stmt (then_clause);
finish_then_clause (if_stmt);
finish_if_stmt ();
}
@@ -9377,9 +5326,7 @@ expand_static_init (decl, init)
/* Finish the declaration of a catch-parameter. */
tree
-start_handler_parms (declspecs, declarator)
- tree declspecs;
- tree declarator;
+start_handler_parms (tree declspecs, tree declarator)
{
tree decl;
if (declspecs)
@@ -9401,11 +5348,9 @@ start_handler_parms (declspecs, declarator)
2 if there was no information (in which case assume 0 if DO_DEFAULT). */
int
-complete_array_type (type, initial_value, do_default)
- tree type, initial_value;
- int do_default;
+complete_array_type (tree type, tree initial_value, int do_default)
{
- register tree maxindex = NULL_TREE;
+ tree maxindex = NULL_TREE;
int value = 0;
if (initial_value)
@@ -9498,9 +5443,7 @@ complete_array_type (type, initial_value, do_default)
message to print in that case. Otherwise, quietly return 1. */
static int
-member_function_or_else (ctype, cur_type, flags)
- tree ctype, cur_type;
- enum overload_flags flags;
+member_function_or_else (tree ctype, tree cur_type, enum overload_flags flags)
{
if (ctype && ctype != cur_type)
{
@@ -9521,10 +5464,13 @@ member_function_or_else (ctype, cur_type, flags)
This is for ARM $7.1.2. */
static void
-bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
- tree object;
- const char *type;
- int virtualp, quals, friendp, raises, inlinep;
+bad_specifiers (tree object,
+ const char* type,
+ int virtualp,
+ int quals,
+ int inlinep,
+ int friendp,
+ int raises)
{
if (virtualp)
error ("`%D' declared as a `virtual' %s", object, type);
@@ -9547,6 +5493,7 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
or METHOD_TYPE.
DECLARATOR is the function's name.
+ PARMS is a chain of PARM_DECLs for the function.
VIRTUALP is truthvalue of whether the function is virtual or not.
FLAGS are to be passed through to `grokclassfn'.
QUALS are qualifiers indicating whether the function is `const'
@@ -9559,17 +5506,22 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
applicable error messages. */
static tree
-grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
- raises, check, friendp, publicp, inlinep, funcdef_flag,
- template_count, in_namespace)
- tree ctype, type;
- tree declarator;
- tree orig_declarator;
- int virtualp;
- enum overload_flags flags;
- tree quals, raises;
- int check, friendp, publicp, inlinep, funcdef_flag, template_count;
- tree in_namespace;
+grokfndecl (tree ctype,
+ tree type,
+ tree declarator,
+ tree parms,
+ tree orig_declarator,
+ int virtualp,
+ enum overload_flags flags,
+ tree quals,
+ tree raises,
+ int check,
+ int friendp,
+ int publicp,
+ int inlinep,
+ int funcdef_flag,
+ int template_count,
+ tree in_namespace)
{
tree decl;
int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
@@ -9580,6 +5532,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
type = build_exception_variant (type, raises);
decl = build_lang_decl (FUNCTION_DECL, declarator, type);
+ DECL_ARGUMENTS (decl) = parms;
/* Propagate volatile out from type to decl. */
if (TYPE_VOLATILE (type))
TREE_THIS_VOLATILE (decl) = 1;
@@ -9640,7 +5593,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
or enumeration declared in a local scope) shall not be used to
declare an entity with linkage.
- Only check this for public decls for now. */
+ Only check this for public decls for now. See core 319, 389. */
t = no_linkage_check (TREE_TYPE (decl));
if (t)
{
@@ -9671,19 +5624,14 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
DECL_NOT_REALLY_EXTERN (decl) = 1;
}
- DID_INLINE_FUNC (decl) = 0;
/* If the declaration was declared inline, mark it as such. */
if (inlinep)
DECL_DECLARED_INLINE_P (decl) = 1;
/* We inline functions that are explicitly declared inline, or, when
the user explicitly asks us to, all functions. */
- if (DECL_DECLARED_INLINE_P (decl))
+ if (DECL_DECLARED_INLINE_P (decl)
+ || (flag_inline_trees == 2 && !DECL_INLINE (decl) && funcdef_flag))
DECL_INLINE (decl) = 1;
- if (flag_inline_trees == 2 && !DECL_INLINE (decl) && funcdef_flag)
- {
- DID_INLINE_FUNC (decl) = 1;
- DECL_INLINE (decl) = 1;
- }
DECL_EXTERNAL (decl) = 1;
if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE)
@@ -9694,7 +5642,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
}
if (IDENTIFIER_OPNAME_P (DECL_NAME (decl)))
- grok_op_properties (decl, friendp);
+ grok_op_properties (decl, friendp, /*complain=*/true);
if (ctype && decl_function_context (decl))
DECL_NO_STATIC_CHAIN (decl) = 1;
@@ -9744,7 +5692,6 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
fns = TREE_OPERAND (fns, 1);
}
my_friendly_assert (TREE_CODE (fns) == IDENTIFIER_NODE
- || TREE_CODE (fns) == LOOKUP_EXPR
|| TREE_CODE (fns) == OVERLOAD, 20001120);
DECL_TEMPLATE_INFO (decl) = tree_cons (fns, args, NULL_TREE);
@@ -9764,9 +5711,6 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
}
}
- if (has_default_arg)
- add_defarg_fn (decl);
-
if (funcdef_flag)
/* Make the init_value nonzero so pushdecl knows this is not
tentative. error_mark_node is replaced later with the BLOCK. */
@@ -9779,7 +5723,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
if (check < 0)
return decl;
- if (flags == NO_SPECIAL && ctype && constructor_name (ctype) == declarator)
+ if (flags == NO_SPECIAL && ctype && constructor_name_p (declarator, ctype))
DECL_CONSTRUCTOR_P (decl) = 1;
/* Function gets the ugly name, field gets the nice one. This call
@@ -9801,7 +5745,9 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
{
tree old_decl;
- old_decl = check_classfn (ctype, decl);
+ old_decl = check_classfn (ctype, decl,
+ processing_template_decl
+ > template_class_depth (ctype));
if (old_decl && TREE_CODE (old_decl) == TEMPLATE_DECL)
/* Because grokfndecl is always supposed to return a
@@ -9812,17 +5758,17 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
if (old_decl && DECL_STATIC_FUNCTION_P (old_decl)
&& TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
- {
- /* Remove the `this' parm added by grokclassfn.
- XXX Isn't this done in start_function, too? */
- revert_static_member_fn (decl);
- last_function_parms = TREE_CHAIN (last_function_parms);
- }
+ /* Remove the `this' parm added by grokclassfn.
+ XXX Isn't this done in start_function, too? */
+ revert_static_member_fn (decl);
if (old_decl && DECL_ARTIFICIAL (old_decl))
error ("definition of implicitly-declared `%D'", old_decl);
if (old_decl)
{
+ tree ok;
+ bool pop_p;
+
/* Since we've smashed OLD_DECL to its
DECL_TEMPLATE_RESULT, we must do the same to DECL. */
if (TREE_CODE (decl) == TEMPLATE_DECL)
@@ -9830,9 +5776,16 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
/* Attempt to merge the declarations. This can fail, in
the case of some invalid specialization declarations. */
- if (!duplicate_decls (decl, old_decl))
- error ("no `%#D' member function declared in class `%T'",
- decl, ctype);
+ pop_p = push_scope (ctype);
+ ok = duplicate_decls (decl, old_decl);
+ if (pop_p)
+ pop_scope (ctype);
+ if (!ok)
+ {
+ error ("no `%#D' member function declared in class `%T'",
+ decl, ctype);
+ return NULL_TREE;
+ }
return old_decl;
}
}
@@ -9856,13 +5809,12 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals,
the innermost enclosings scope. */
static tree
-grokvardecl (type, name, specbits_in, initialized, constp, scope)
- tree type;
- tree name;
- RID_BIT_TYPE *specbits_in;
- int initialized;
- int constp;
- tree scope;
+grokvardecl (tree type,
+ tree name,
+ RID_BIT_TYPE * specbits_in,
+ int initialized,
+ int constp,
+ tree scope)
{
tree decl;
RID_BIT_TYPE specbits;
@@ -9978,7 +5930,7 @@ grokvardecl (type, name, specbits_in, initialized, constp, scope)
tree
build_ptrmemfunc_type (tree type)
{
- tree fields[4];
+ tree field, fields;
tree t;
tree unqualified_variant = NULL_TREE;
@@ -10004,10 +5956,14 @@ build_ptrmemfunc_type (tree type)
/* ... and not really an aggregate. */
SET_IS_AGGR_TYPE (t, 0);
- fields[0] = build_decl (FIELD_DECL, pfn_identifier, type);
- fields[1] = build_decl (FIELD_DECL, delta_identifier,
- delta_type_node);
- finish_builtin_type (t, "__ptrmemfunc_type", fields, 1, ptr_type_node);
+ field = build_decl (FIELD_DECL, pfn_identifier, type);
+ fields = field;
+
+ field = build_decl (FIELD_DECL, delta_identifier, delta_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+
+ finish_builtin_struct (t, "__ptrmemfunc_type", fields, ptr_type_node);
/* Zap out the name so that the back-end will give us the debugging
information for this anonymous RECORD_TYPE. */
@@ -10029,9 +5985,6 @@ build_ptrmemfunc_type (tree type)
later. */
TYPE_SET_PTRMEMFUNC_TYPE (type, t);
- /* Seems to be wanted. */
- CLASSTYPE_GOT_SEMICOLON (t) = 1;
-
return t;
}
@@ -10040,7 +5993,26 @@ build_ptrmemfunc_type (tree type)
tree
build_ptrmem_type (tree class_type, tree member_type)
{
- return build_pointer_type (build_offset_type (class_type, member_type));
+ if (TREE_CODE (member_type) == METHOD_TYPE)
+ {
+ tree arg_types;
+
+ arg_types = TYPE_ARG_TYPES (member_type);
+ class_type = (cp_build_qualified_type
+ (class_type,
+ cp_type_quals (TREE_TYPE (TREE_VALUE (arg_types)))));
+ member_type
+ = build_method_type_directly (class_type,
+ TREE_TYPE (member_type),
+ TREE_CHAIN (arg_types));
+ return build_ptrmemfunc_type (build_pointer_type (member_type));
+ }
+ else
+ {
+ my_friendly_assert (TREE_CODE (member_type) != FUNCTION_TYPE,
+ 20030716);
+ return build_offset_type (class_type, member_type);
+ }
}
/* DECL is a VAR_DECL defined in-class, whose TYPE is also given.
@@ -10049,9 +6021,7 @@ build_ptrmem_type (tree class_type, tree member_type)
otherwise. */
int
-check_static_variable_definition (decl, type)
- tree decl;
- tree type;
+check_static_variable_definition (tree decl, tree type)
{
/* Motion 10 at San Diego: If a static const integral data member is
initialized with an integral constant expression, the initializer
@@ -10083,52 +6053,37 @@ check_static_variable_definition (decl, type)
name of the thing being declared. */
tree
-compute_array_index_type (name, size)
- tree name;
- tree size;
+compute_array_index_type (tree name, tree size)
{
+ tree type = TREE_TYPE (size);
tree itype;
- /* If this involves a template parameter, it will be a constant at
- instantiation time, but we don't know what the value is yet.
- Even if no template parameters are involved, we may an expression
- that is not a constant; we don't even simplify `1 + 2' when
- processing a template. */
- if (processing_template_decl)
+ /* The array bound must be an integer type. */
+ if (!dependent_type_p (type) && !INTEGRAL_TYPE_P (type))
{
- /* Resolve a qualified reference to an enumerator or static
- const data member of ours. */
- if (TREE_CODE (size) == SCOPE_REF
- && TREE_OPERAND (size, 0) == current_class_type)
- {
- tree t = lookup_field (current_class_type,
- TREE_OPERAND (size, 1), 0, 0);
- if (t)
- size = t;
- }
-
- return build_index_type (build_min (MINUS_EXPR, sizetype,
- size, integer_one_node));
+ if (name)
+ error ("size of array `%D' has non-integral type `%T'", name, type);
+ else
+ error ("size of array has non-integral type `%T'", type);
+ size = integer_one_node;
+ type = TREE_TYPE (size);
}
+ if (abi_version_at_least (2)
+ /* We should only handle value dependent expressions specially. */
+ ? value_dependent_expression_p (size)
+ /* But for abi-1, we handled all instances in templates. This
+ effects the manglings produced. */
+ : processing_template_decl)
+ return build_index_type (build_min (MINUS_EXPR, sizetype,
+ size, integer_one_node));
+
/* The size might be the result of a cast. */
STRIP_TYPE_NOPS (size);
/* It might be a const variable or enumeration constant. */
size = decl_constant_value (size);
- /* The array bound must be an integer type. */
- if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE
- && TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE
- && TREE_CODE (TREE_TYPE (size)) != BOOLEAN_TYPE)
- {
- if (name)
- error ("size of array `%D' has non-integer type", name);
- else
- error ("size of array has non-integer type");
- size = integer_one_node;
- }
-
/* Normally, the array-bound will be a constant. */
if (TREE_CODE (size) == INTEGER_CST)
{
@@ -10150,9 +6105,8 @@ compute_array_index_type (name, size)
error ("size of array is negative");
size = integer_one_node;
}
- /* Except that an extension we allow zero-sized arrays. We
- always allow them in system headers because glibc uses
- them. */
+ /* As an extension we allow zero-sized arrays. We always allow
+ them in system headers because glibc uses them. */
else if (integer_zerop (size) && pedantic && !in_system_header)
{
if (name)
@@ -10170,53 +6124,89 @@ compute_array_index_type (name, size)
else
error ("size of array is not an integral constant-expression");
}
+ else if (pedantic)
+ {
+ if (name)
+ pedwarn ("ISO C++ forbids variable-size array `%D'", name);
+ else
+ pedwarn ("ISO C++ forbids variable-size array");
+ }
- /* Compute the index of the largest element in the array. It is
- one less than the number of elements in the array. */
- itype
- = fold (cp_build_binary_op (MINUS_EXPR,
- cp_convert (ssizetype, size),
- cp_convert (ssizetype,
- integer_one_node)));
-
- /* Check for variable-sized arrays. We allow such things as an
- extension, even though they are not allowed in ANSI/ISO C++. */
- if (!TREE_CONSTANT (itype))
+ if (processing_template_decl && !TREE_CONSTANT (size))
+ /* A variable sized array. */
+ itype = build_min (MINUS_EXPR, sizetype, size, integer_one_node);
+ else
{
- if (pedantic)
+ /* Compute the index of the largest element in the array. It is
+ one less than the number of elements in the array. */
+ itype
+ = fold (cp_build_binary_op (MINUS_EXPR,
+ cp_convert (ssizetype, size),
+ cp_convert (ssizetype, integer_one_node)));
+ if (!TREE_CONSTANT (itype))
+ /* A variable sized array. */
+ itype = variable_size (itype);
+ /* Make sure that there was no overflow when creating to a signed
+ index type. (For example, on a 32-bit machine, an array with
+ size 2^32 - 1 is too big.) */
+ else if (TREE_OVERFLOW (itype))
{
- if (name)
- pedwarn ("ISO C++ forbids variable-size array `%D'",
- name);
- else
- pedwarn ("ISO C++ forbids variable-size array");
+ error ("overflow in array dimension");
+ TREE_OVERFLOW (itype) = 0;
}
-
- /* Create a variable-sized array index type. */
- itype = variable_size (itype);
- }
- /* Make sure that there was no overflow when creating to a signed
- index type. (For example, on a 32-bit machine, an array with
- size 2^32 - 1 is too big.) */
- else if (TREE_OVERFLOW (itype))
- {
- error ("overflow in array dimension");
- TREE_OVERFLOW (itype) = 0;
}
/* Create and return the appropriate index type. */
return build_index_type (itype);
}
+/* Returns the scope (if any) in which the entity declared by
+ DECLARATOR will be located. If the entity was declared with an
+ unqualified name, NULL_TREE is returned. */
+
+tree
+get_scope_of_declarator (tree declarator)
+{
+ if (!declarator)
+ return NULL_TREE;
+
+ switch (TREE_CODE (declarator))
+ {
+ case CALL_EXPR:
+ case ARRAY_REF:
+ case INDIRECT_REF:
+ case ADDR_EXPR:
+ /* For any of these, the main declarator is the first operand. */
+ return get_scope_of_declarator (TREE_OPERAND
+ (declarator, 0));
+
+ case SCOPE_REF:
+ /* For a pointer-to-member, continue descending. */
+ if (TREE_CODE (TREE_OPERAND (declarator, 1))
+ == INDIRECT_REF)
+ return get_scope_of_declarator (TREE_OPERAND
+ (declarator, 1));
+ /* Otherwise, if the declarator-id is a SCOPE_REF, the scope in
+ which the declaration occurs is the first operand. */
+ return TREE_OPERAND (declarator, 0);
+
+ case TREE_LIST:
+ /* Attributes to be applied. The declarator is TREE_VALUE. */
+ return get_scope_of_declarator (TREE_VALUE (declarator));
+
+ default:
+ /* Otherwise, we have a declarator-id which is not a qualified
+ name; the entity will be declared in the current scope. */
+ return NULL_TREE;
+ }
+}
+
/* Returns an ARRAY_TYPE for an array with SIZE elements of the
indicated TYPE. If non-NULL, NAME is the NAME of the declaration
with this type. */
static tree
-create_array_type_for_decl (name, type, size)
- tree name;
- tree type;
- tree size;
+create_array_type_for_decl (tree name, tree type, tree size)
{
tree itype = NULL_TREE;
const char* error_msg;
@@ -10243,10 +6233,6 @@ create_array_type_for_decl (name, type, size)
error_msg = "array of references";
break;
- case OFFSET_TYPE:
- error_msg = "array of data members";
- break;
-
case METHOD_TYPE:
error_msg = "array of function members";
break;
@@ -10296,10 +6282,9 @@ create_array_type_for_decl (name, type, size)
special functions. */
static tree
-check_special_function_return_type (sfk, type, optype)
- special_function_kind sfk;
- tree type;
- tree optype;
+check_special_function_return_type (special_function_kind sfk,
+ tree type,
+ tree optype)
{
switch (sfk)
{
@@ -10332,11 +6317,9 @@ check_special_function_return_type (sfk, type, optype)
return type;
}
-/* Given declspecs and a declarator,
- determine the name and type of the object declared
- and construct a ..._DECL node for it.
- (In one case we can return a ..._TYPE node instead.
- For invalid input we sometimes return 0.)
+/* Given declspecs and a declarator (abstract or otherwise), determine
+ the name and type of the object declared and construct a DECL node
+ for it.
DECLSPECS is a chain of tree_list nodes whose value fields
are the storage classes and type specifiers.
@@ -10363,43 +6346,22 @@ check_special_function_return_type (sfk, type, optype)
if there are none; *ATTRLIST may be modified if attributes from inside
the declarator should be applied to the declaration.
- In the TYPENAME case, DECLARATOR is really an abstract declarator.
- It may also be so in the PARM case, for a prototype where the
- argument type is specified but not the name.
-
- This function is where the complicated C meanings of `static'
- and `extern' are interpreted.
-
- For C++, if there is any monkey business to do, the function which
- calls this one must do it, i.e., prepending instance variables,
- renaming overloaded function names, etc.
-
- Note that for this C++, it is an error to define a method within a class
- which does not belong to that class.
-
- Except in the case where SCOPE_REFs are implicitly known (such as
- methods within a class being redundantly qualified),
- declarations which involve SCOPE_REFs are returned as SCOPE_REFs
- (class_name::decl_name). The caller must also deal with this.
+ When this function is called, scoping variables (such as
+ CURRENT_CLASS_TYPE) should reflect the scope in which the
+ declaration occurs, not the scope in which the new declaration will
+ be placed. For example, on:
- If a constructor or destructor is seen, and the context is FIELD,
- then the type gains the attribute TREE_HAS_x. If such a declaration
- is erroneous, NULL_TREE is returned.
+ void S::f() { ... }
- QUALS is used only for FUNCDEF and MEMFUNCDEF cases. For a member
- function, these are the qualifiers to give to the `this' pointer. We
- apply TYPE_QUAL_RESTRICT to the this ptr, not the object.
-
- May return void_type_node if the declarator turned out to be a friend.
- See grokfield for details. */
+ when grokdeclarator is called for `S::f', the CURRENT_CLASS_TYPE
+ should not be `S'. */
tree
-grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
- tree declspecs;
- tree declarator;
- enum decl_context decl_context;
- int initialized;
- tree *attrlist;
+grokdeclarator (tree declarator,
+ tree declspecs,
+ enum decl_context decl_context,
+ int initialized,
+ tree* attrlist)
{
RID_BIT_TYPE specbits;
int nclasses = 0;
@@ -10424,9 +6386,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
/* See the code below that used this. */
tree decl_attr = NULL_TREE;
#endif
- /* Set this to error_mark_node for FIELD_DECLs we could not handle properly.
- All FIELD_DECLs we build here have `init' put into their DECL_INITIAL. */
- tree init = NULL_TREE;
/* Keep track of what sort of function is being processed
so that we can warn about default return values, or explicit
@@ -10442,6 +6401,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
int template_count = 0;
tree in_namespace = NULL_TREE;
tree returned_attrs = NULL_TREE;
+ tree scope = NULL_TREE;
+ tree parms = NULL_TREE;
RIDBIT_RESET_ALL (specbits);
if (decl_context == FUNCDEF)
@@ -10455,7 +6416,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
and get it as a string, for an error message. */
{
tree *next = &declarator;
- register tree decl;
+ tree decl;
name = NULL;
while (next && *next)
@@ -10481,7 +6442,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
my_friendly_assert (flags == NO_SPECIAL, 152);
flags = DTOR_FLAG;
sfk = sfk_destructor;
- if (TREE_CODE (name) == TYPE_DECL)
+ if (TYPE_P (name))
TREE_OPERAND (decl, 0) = name = constructor_name (name);
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153);
if (ctype == NULL_TREE)
@@ -10493,7 +6454,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
else
{
- tree t = constructor_name (current_class_name);
+ tree t = constructor_name (current_class_type);
if (t != name)
rename = t;
}
@@ -10525,47 +6486,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
break;
case CALL_EXPR:
- if (parmlist_is_exprlist (CALL_DECLARATOR_PARMS (decl)))
- {
- /* This is actually a variable declaration using
- constructor syntax. We need to call start_decl and
- cp_finish_decl so we can get the variable
- initialized... */
-
- tree attributes;
-
- if (decl_context != NORMAL)
- {
- error ("variable declaration is not allowed here");
- return error_mark_node;
- }
-
- *next = TREE_OPERAND (decl, 0);
- init = CALL_DECLARATOR_PARMS (decl);
-
- if (attrlist)
- {
- attributes = *attrlist;
- }
- else
- {
- attributes = NULL_TREE;
- }
-
- decl = start_decl (declarator, declspecs, 1,
- attributes, NULL_TREE);
- decl_type_access_control (decl);
- if (decl)
- {
- /* Look for __unused__ attribute */
- if (TREE_USED (TREE_TYPE (decl)))
- TREE_USED (decl) = 1;
- finish_decl (decl, init, NULL_TREE);
- }
- else
- error ("invalid declarator");
- return NULL_TREE;
- }
innermost_code = TREE_CODE (decl);
if (decl_context == FIELD && ctype == NULL_TREE)
ctype = current_class_type;
@@ -10579,7 +6499,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
decl = *next;
if (ctype != NULL_TREE
&& decl != NULL_TREE && flags != DTOR_FLAG
- && decl == constructor_name (ctype))
+ && constructor_name_p (decl, ctype))
{
sfk = sfk_constructor;
ctor_return_type = ctype;
@@ -10591,9 +6511,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
{
tree fns = TREE_OPERAND (decl, 0);
- if (TREE_CODE (fns) == LOOKUP_EXPR)
- fns = TREE_OPERAND (fns, 0);
-
dname = fns;
if (TREE_CODE (dname) == COMPONENT_REF)
dname = TREE_OPERAND (dname, 1);
@@ -10626,9 +6543,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
flags = TYPENAME_FLAG;
ctor_return_type = TREE_TYPE (dname);
sfk = sfk_conversion;
- if (IDENTIFIER_GLOBAL_VALUE (dname)
- && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (dname))
- == TYPE_DECL))
+ if (is_typename_at_global_scope (dname))
name = IDENTIFIER_POINTER (dname);
else
name = "<invalid operator>";
@@ -10646,10 +6561,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
{
ctype = NULL_TREE;
in_namespace = TREE_OPERAND (decl, 0);
- TREE_OPERAND (decl, 0) = NULL_TREE;
}
else if (! is_aggr_type (cname, 1))
- TREE_OPERAND (decl, 0) = NULL_TREE;
+ ctype = NULL_TREE;
/* Must test TREE_OPERAND (decl, 1), in case user gives
us `typedef (class::memfunc)(int); memfunc *memfuncptr;' */
else if (TREE_OPERAND (decl, 1)
@@ -10666,26 +6580,34 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
else if (ctype == NULL_TREE)
ctype = cname;
else if (TREE_COMPLEXITY (decl) == current_class_depth)
- TREE_OPERAND (decl, 0) = ctype;
+ ;
else
{
if (! UNIQUELY_DERIVED_FROM_P (cname, ctype))
{
error ("type `%T' is not derived from type `%T'",
cname, ctype);
- TREE_OPERAND (decl, 0) = NULL_TREE;
+ ctype = NULL_TREE;
}
else
ctype = cname;
}
- /* If the parser sees something like "void a::b" where
- "a::b" is a namespace, it will build a SCOPE_REF with
- a NAMESPACE_DECL, rather than an IDENTIFIER_NODE, as
- the second operand. Since the SCOPE_REF is being
- used as a declarator, we recover from that here. */
- if (TREE_CODE (TREE_OPERAND (decl, 1)) == NAMESPACE_DECL)
- TREE_OPERAND (decl, 1) = DECL_NAME (TREE_OPERAND (decl, 1));
+ /* It is valid to write:
+
+ class C { void f(); };
+ typedef C D;
+ void D::f();
+
+ The standard is not clear about whether `typedef const C D' is
+ legal; as of 2002-09-15 the committee is considering
+ that question. EDG 3.0 allows that syntax.
+ Therefore, we do as well. */
+ if (ctype)
+ ctype = TYPE_MAIN_VARIANT (ctype);
+ /* Update the declarator so that when we process it
+ again the correct type is present. */
+ TREE_OPERAND (decl, 0) = ctype;
if (ctype && TREE_CODE (TREE_OPERAND (decl, 1)) == TYPE_DECL
&& constructor_name_p (DECL_NAME (TREE_OPERAND (decl, 1)),
@@ -10695,16 +6617,19 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
decl = *next;
if (ctype)
{
- if (TREE_CODE (decl) == IDENTIFIER_NODE
- && constructor_name (ctype) == decl)
+ tree name = decl;
+
+ if (TREE_CODE (name) == BIT_NOT_EXPR)
+ name = TREE_OPERAND (name, 0);
+
+ if (!constructor_name_p (decl, ctype))
+ ;
+ else if (decl == name)
{
sfk = sfk_constructor;
ctor_return_type = ctype;
}
- else if (TREE_CODE (decl) == BIT_NOT_EXPR
- && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE
- && constructor_name_p (TREE_OPERAND (decl, 0),
- ctype))
+ else
{
sfk = sfk_destructor;
ctor_return_type = ctype;
@@ -10815,8 +6740,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
{
- register int i;
- register tree id;
+ int i;
+ tree id;
/* Certain parse errors slip through. For example,
`int class;' is not caught by the parser. Try
@@ -10884,13 +6809,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
else if (RIDBIT_SETP (i, specbits))
pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id));
- /* Diagnose "__thread extern". Recall that this list
- is in the reverse order seen in the text. */
- if (i == (int)RID_THREAD)
+ /* Diagnose "__thread extern" or "__thread static". */
+ if (RIDBIT_SETP (RID_THREAD, specbits))
{
- if (RIDBIT_SETP (RID_EXTERN, specbits))
+ if (i == (int)RID_EXTERN)
error ("`__thread' before `extern'");
- if (RIDBIT_SETP (RID_STATIC, specbits))
+ else if (i == (int)RID_STATIC)
error ("`__thread' before `static'");
}
@@ -10921,7 +6845,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
error ("two or more data types in declaration of `%s'", name);
else if (TREE_CODE (id) == IDENTIFIER_NODE)
{
- register tree t = lookup_name (id, 1);
+ tree t = lookup_name (id, 1);
if (!t || TREE_CODE (t) != TYPE_DECL)
error ("`%s' fails to be a typedef or built in type",
IDENTIFIER_POINTER (id));
@@ -10989,21 +6913,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
type = integer_type_node;
}
- if (type && IMPLICIT_TYPENAME_P (type))
- {
- /* The implicit typename extension is deprecated and will be
- removed. Warn about its use now. */
- warning ("`%T' is implicitly a typename", type);
- cp_deprecated ("implicit typename");
-
- /* Now remove its implicitness, so that we don't warn again.
- For instance this might be a typedef, and we do not want to
- warn on uses of the typedef itself. Simply clearing the
- TREE_TYPE is insufficient. */
- type = copy_node (type);
- TREE_TYPE (type) = NULL_TREE;
- }
-
ctype = NULL_TREE;
/* Now process the modifiers that were specified
@@ -11245,7 +7154,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
else if (RIDBIT_SETP (RID_TYPEDEF, specbits))
;
else if (decl_context == FIELD
- /* C++ allows static class elements */
+ /* C++ allows static class elements. */
&& RIDBIT_SETP (RID_STATIC, specbits))
/* C++ also allows inlines and signed and unsigned elements,
but in those cases we don't come in here. */
@@ -11255,7 +7164,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (decl_context == FIELD)
{
tree tmp = NULL_TREE;
- register int op = 0;
+ int op = 0;
if (declarator)
{
@@ -11267,9 +7176,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
op = IDENTIFIER_OPNAME_P (tmp);
if (IDENTIFIER_TYPENAME_P (tmp))
{
- if (IDENTIFIER_GLOBAL_VALUE (tmp)
- && (TREE_CODE (IDENTIFIER_GLOBAL_VALUE (tmp))
- == TYPE_DECL))
+ if (is_typename_at_global_scope (tmp))
name = IDENTIFIER_POINTER (tmp);
else
name = "<invalid operator>";
@@ -11324,6 +7231,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (nclasses > 0 && friendp)
error ("storage class specifiers invalid in friend function declarations");
+ scope = get_scope_of_declarator (declarator);
+
/* Now figure out the structure of the declarator proper.
Descend through it, creating more complex types, until we reach
the declared identifier (or NULL_TREE, in an abstract declarator). */
@@ -11354,7 +7263,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (type == error_mark_node)
{
- if (TREE_CODE (declarator) == SCOPE_REF)
+ if (declarator == error_mark_node)
+ return error_mark_node;
+ else if (TREE_CODE (declarator) == SCOPE_REF)
declarator = TREE_OPERAND (declarator, 1);
else
declarator = TREE_OPERAND (declarator, 0);
@@ -11371,7 +7282,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
tree dummy = build_decl (TYPE_DECL, NULL_TREE, type);
grok_method_quals (ctype, dummy, quals);
type = TREE_TYPE (dummy);
- ctype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type)));
quals = NULL_TREE;
}
}
@@ -11407,15 +7317,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
case ARRAY_REF:
{
- register tree size;
-
- size = TREE_OPERAND (declarator, 1);
-
- /* VC++ spells a zero-sized array with []. */
- if (size == NULL_TREE && decl_context == FIELD && ! staticp
- && ! RIDBIT_SETP (RID_TYPEDEF, specbits))
- size = integer_zero_node;
-
+ tree size = TREE_OPERAND (declarator, 1);
declarator = TREE_OPERAND (declarator, 0);
type = create_array_type_for_decl (dname, type, size);
@@ -11479,7 +7381,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (ctype && sfk == sfk_conversion)
TYPE_HAS_CONVERSION (ctype) = 1;
- if (ctype && constructor_name (ctype) == dname)
+ if (ctype && constructor_name_p (dname, ctype))
{
/* We are within a class's scope. If our declarator name
is the same as the class name, and we are defining
@@ -11573,10 +7475,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
declarator = TREE_OPERAND (declarator, 0);
- /* FIXME: This is where default args should be fully
- processed. */
-
- arg_types = grokparms (inner_parms);
+ arg_types = grokparms (inner_parms, &parms);
if (declarator && flags == DTOR_FLAG)
{
@@ -11590,24 +7489,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
{
error ("destructors may not have parameters");
arg_types = void_list_node;
- last_function_parms = NULL_TREE;
+ parms = NULL_TREE;
}
}
/* ANSI says that `const int foo ();'
does not make the function foo const. */
type = build_function_type (type, arg_types);
-
- {
- tree t;
- for (t = arg_types; t; t = TREE_CHAIN (t))
- if (TREE_PURPOSE (t)
- && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
- {
- add_defarg_fn (type);
- break;
- }
- }
}
break;
@@ -11652,7 +7540,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (TREE_TYPE (declarator))
{
- register tree typemodlist;
+ tree typemodlist;
int erred = 0;
int constp = 0;
int volatilep = 0;
@@ -11712,44 +7600,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (TREE_CODE (sname) == BIT_NOT_EXPR)
sname = TREE_OPERAND (sname, 0);
- if (TREE_COMPLEXITY (declarator) == 0)
- /* This needs to be here, in case we are called
- multiple times. */ ;
- else if (TREE_COMPLEXITY (declarator) == -1)
- /* Namespace member. */
- pop_decl_namespace ();
- else if (friendp && (TREE_COMPLEXITY (declarator) < 2))
- /* Don't fall out into global scope. Hides real bug? --eichin */ ;
- else if (!TREE_OPERAND (declarator, 0)
- || !IS_AGGR_TYPE_CODE
- (TREE_CODE (TREE_OPERAND (declarator, 0))))
- ;
- else if (TREE_COMPLEXITY (declarator) == current_class_depth)
- {
- /* Resolve any TYPENAME_TYPEs from the decl-specifier-seq
- that refer to ctype. They couldn't be resolved earlier
- because we hadn't pushed into the class yet.
- Example: resolve 'B<T>::type' in
- 'B<typename B<T>::type> B<T>::f () { }'. */
- if (current_template_parms
- && uses_template_parms (type)
- && uses_template_parms (current_class_type))
- {
- tree args = current_template_args ();
- type = tsubst (type, args, tf_error | tf_warning,
- NULL_TREE);
- }
-
- /* This pop_nested_class corresponds to the
- push_nested_class used to push into class scope for
- parsing the argument list of a function decl, in
- qualified_id. */
- pop_nested_class ();
- TREE_COMPLEXITY (declarator) = current_class_depth;
- }
- else
- abort ();
-
if (TREE_OPERAND (declarator, 0) == NULL_TREE)
{
/* We had a reference to a global decl, or
@@ -11762,27 +7612,28 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
ctype = TREE_OPERAND (declarator, 0);
t = ctype;
- while (t != NULL_TREE && CLASS_TYPE_P (t))
- {
- /* You're supposed to have one `template <...>'
- for every template class, but you don't need one
- for a full specialization. For example:
-
+ if (TREE_CODE (TREE_OPERAND (declarator, 1)) != INDIRECT_REF)
+ while (t != NULL_TREE && CLASS_TYPE_P (t))
+ {
+ /* You're supposed to have one `template <...>'
+ for every template class, but you don't need one
+ for a full specialization. For example:
+
template <class T> struct S{};
template <> struct S<int> { void f(); };
void S<int>::f () {}
-
- is correct; there shouldn't be a `template <>' for
- the definition of `S<int>::f'. */
- if (CLASSTYPE_TEMPLATE_INFO (t)
- && (CLASSTYPE_TEMPLATE_INSTANTIATION (t)
- || uses_template_parms (CLASSTYPE_TI_ARGS (t)))
- && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
- template_count += 1;
-
- t = TYPE_MAIN_DECL (t);
- t = DECL_CONTEXT (t);
- }
+
+ is correct; there shouldn't be a `template <>' for
+ the definition of `S<int>::f'. */
+ if (CLASSTYPE_TEMPLATE_INFO (t)
+ && (CLASSTYPE_TEMPLATE_INSTANTIATION (t)
+ || uses_template_parms (CLASSTYPE_TI_ARGS (t)))
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))
+ template_count += 1;
+
+ t = TYPE_MAIN_DECL (t);
+ t = DECL_CONTEXT (t);
+ }
if (sname == NULL_TREE)
goto done_scoping;
@@ -11806,14 +7657,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
- if (current_class_type == NULL_TREE || friendp)
- type = build_cplus_method_type (ctype, TREE_TYPE (type),
+ if (NEW_DELETE_OPNAME_P (sname))
+ /* Overloaded operator new and operator delete
+ are always static functions. */
+ ;
+ else if (current_class_type == NULL_TREE || friendp)
+ type
+ = build_method_type_directly (ctype,
+ TREE_TYPE (type),
TYPE_ARG_TYPES (type));
else
{
error ("cannot declare member function `%T::%s' within `%T'",
ctype, name, current_class_type);
- return void_type_node;
+ return error_mark_node;
}
}
else if (RIDBIT_SETP (RID_TYPEDEF, specbits)
@@ -11849,8 +7706,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
/* In this case, we will deal with it later. */
;
else if (TREE_CODE (type) == FUNCTION_TYPE)
- type = build_cplus_method_type (ctype, TREE_TYPE (type),
- TYPE_ARG_TYPES (type));
+ type = build_method_type_directly (ctype,
+ TREE_TYPE (type),
+ TYPE_ARG_TYPES (type));
}
}
break;
@@ -11977,7 +7835,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (decl_context == FIELD)
{
- if (declarator == constructor_name (current_class_type))
+ if (constructor_name_p (declarator, current_class_type))
pedwarn ("ISO C++ forbids nested type `%D' with same name as enclosing class",
declarator);
decl = build_lang_decl (TYPE_DECL, declarator, type);
@@ -11985,6 +7843,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
else
{
decl = build_decl (TYPE_DECL, declarator, type);
+ if (in_namespace || ctype)
+ error ("%Jtypedef name may not be a nested-name-specifier", decl);
if (!current_function_decl)
DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
}
@@ -12025,17 +7885,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
type with external linkage have external linkage. */
}
- if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE)
- {
- cp_error_at ("typedef name may not be class-qualified", decl);
- return NULL_TREE;
- }
- else if (quals)
+ if (quals)
{
if (ctype == NULL_TREE)
{
if (TREE_CODE (type) != METHOD_TYPE)
- cp_error_at ("invalid type qualifier for non-member function type", decl);
+ error ("%Jinvalid type qualifier for non-member function type",
+ decl);
else
ctype = TYPE_METHOD_BASETYPE (type);
}
@@ -12064,8 +7920,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
/* Detect where we're using a typedef of function type to declare a
- function. last_function_parms will not be set, so we must create
- it now. */
+ function. PARMS will not be set, so we must create it now. */
if (type == typedef_type && TREE_CODE (type) == FUNCTION_TYPE)
{
@@ -12080,7 +7935,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
decls = decl;
}
- last_function_parms = nreverse (decls);
+ parms = nreverse (decls);
}
/* If this is a type name (such as, in a cast or sizeof),
@@ -12125,11 +7980,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
/* Only try to do this stuff if we didn't already give up. */
if (type != integer_type_node)
{
- decl_type_access_control (TYPE_NAME (type));
-
/* A friendly class? */
if (current_class_type)
- make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type));
+ make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type),
+ /*complain=*/true);
else
error ("trying to make class `%T' a friend of global scope",
type);
@@ -12206,12 +8060,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
type = build_pointer_type (type);
- else if (TREE_CODE (type) == OFFSET_TYPE)
- type = build_pointer_type (type);
}
{
- register tree decl;
+ tree decl;
if (decl_context == PARM)
{
@@ -12222,6 +8074,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
else if (decl_context == FIELD)
{
+ /* The C99 flexible array extension. */
+ if (!staticp && TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_DOMAIN (type) == NULL_TREE)
+ {
+ tree itype = compute_array_index_type (dname, integer_zero_node);
+ type = build_cplus_array_type (TREE_TYPE (type), itype);
+ }
+
if (type == error_mark_node)
{
/* Happens when declaring arrays of sizes which
@@ -12269,10 +8129,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
return void_type_node;
}
- if (declarator == ansi_opname (NEW_EXPR)
- || declarator == ansi_opname (VEC_NEW_EXPR)
- || declarator == ansi_opname (DELETE_EXPR)
- || declarator == ansi_opname (VEC_DELETE_EXPR))
+ if (NEW_DELETE_OPNAME_P (declarator))
{
if (virtualp)
{
@@ -12282,8 +8139,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
}
else if (staticp < 2)
- type = build_cplus_method_type (ctype, TREE_TYPE (type),
- TYPE_ARG_TYPES (type));
+ type = build_method_type_directly (ctype,
+ TREE_TYPE (type),
+ TYPE_ARG_TYPES (type));
}
/* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */
@@ -12294,6 +8152,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
decl = grokfndecl (ctype, type,
TREE_CODE (declarator) != TEMPLATE_ID_EXPR
? declarator : dname,
+ parms,
declarator,
virtualp, flags, quals, raises,
friendp ? -1 : 0, friendp, publicp, inlinep,
@@ -12340,6 +8199,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
decl = grokfndecl (ctype, type,
TREE_CODE (declarator) != TEMPLATE_ID_EXPR
? declarator : dname,
+ parms,
declarator,
virtualp, flags, quals, raises,
friendp ? -1 : 0, friendp, 1, 0, funcdef_flag,
@@ -12347,7 +8207,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (decl == NULL_TREE)
return NULL_TREE;
}
- else if (!staticp && ! processing_template_decl
+ else if (!staticp && !dependent_type_p (type)
&& !COMPLETE_TYPE_P (complete_type (type))
&& (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))
{
@@ -12385,33 +8245,26 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
/* Friends are treated specially. */
if (ctype == current_class_type)
warning ("member functions are implicitly friends of their class");
- else
- {
- tree t = NULL_TREE;
- if (decl && DECL_NAME (decl))
- {
- if (template_class_depth (current_class_type) == 0)
- {
- decl
- = check_explicit_specialization
- (declarator, decl,
- template_count, 2 * (funcdef_flag != 0) + 4);
- if (decl == error_mark_node)
- return error_mark_node;
- }
-
- t = do_friend (ctype, declarator, decl,
- last_function_parms, *attrlist,
- flags, quals, funcdef_flag);
- }
- if (t && funcdef_flag)
- return t;
-
- return void_type_node;
- }
+ else if (decl && DECL_NAME (decl))
+ {
+ if (template_class_depth (current_class_type) == 0)
+ {
+ decl = check_explicit_specialization
+ (declarator, decl, template_count,
+ 2 * (funcdef_flag != 0) + 4);
+ if (decl == error_mark_node)
+ return error_mark_node;
+ }
+
+ decl = do_friend (ctype, declarator, decl,
+ *attrlist, flags, quals, funcdef_flag);
+ return decl;
+ }
+ else
+ return void_type_node;
}
- /* Structure field. It may not be a function, except for C++ */
+ /* Structure field. It may not be a function, except for C++. */
if (decl == NULL_TREE)
{
@@ -12450,16 +8303,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
return void_type_node;
}
- /* 9.2p13 [class.mem] */
- if (declarator == constructor_name (current_class_type)
- /* The standard does not allow non-static data members
- here either, but we agreed at the 10/99 meeting
- to change that in TC 1 so that they are allowed in
- classes with no user-defined constructors. */
- && staticp)
- pedwarn ("ISO C++ forbids static data member `%D' with same name as enclosing class",
- declarator);
-
if (staticp)
{
/* C++ allows static class members. All other work
@@ -12484,7 +8327,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
inlinep, friendp, raises != NULL_TREE);
}
}
- else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
+ else if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)
{
tree original_name;
int publicp = 0;
@@ -12526,16 +8370,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
virtualp = 0;
}
}
- else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2)
- type = build_cplus_method_type (ctype, TREE_TYPE (type),
- TYPE_ARG_TYPES (type));
+ else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
+ && !NEW_DELETE_OPNAME_P (original_name))
+ type = build_method_type_directly (ctype,
+ TREE_TYPE (type),
+ TYPE_ARG_TYPES (type));
/* Record presence of `static'. */
publicp = (ctype != NULL_TREE
|| RIDBIT_SETP (RID_EXTERN, specbits)
|| !RIDBIT_SETP (RID_STATIC, specbits));
- decl = grokfndecl (ctype, type, original_name, declarator,
+ decl = grokfndecl (ctype, type, original_name, parms, declarator,
virtualp, flags, quals, raises,
1, friendp,
publicp, inlinep, funcdef_flag,
@@ -12627,61 +8473,30 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
}
}
-/* Tell if a parmlist/exprlist looks like an exprlist or a parmlist.
- An empty exprlist is a parmlist. An exprlist which
- contains only identifiers at the global level
- is a parmlist. Otherwise, it is an exprlist. */
-
-int
-parmlist_is_exprlist (exprs)
- tree exprs;
-{
- if (exprs == NULL_TREE || TREE_PARMLIST (exprs))
- return 0;
-
- if (toplevel_bindings_p ())
- {
- /* At the global level, if these are all identifiers,
- then it is a parmlist. */
- while (exprs)
- {
- if (TREE_CODE (TREE_VALUE (exprs)) != IDENTIFIER_NODE)
- return 1;
- exprs = TREE_CHAIN (exprs);
- }
- return 0;
- }
- return 1;
-}
-
/* Subroutine of start_function. Ensure that each of the parameter
types (as listed in PARMS) is complete, as is required for a
function definition. */
static void
-require_complete_types_for_parms (parms)
- tree parms;
+require_complete_types_for_parms (tree parms)
{
for (; parms; parms = TREE_CHAIN (parms))
{
if (VOID_TYPE_P (TREE_TYPE (parms)))
- /* grokparms will have already issued an error */
+ /* grokparms will have already issued an error. */
TREE_TYPE (parms) = error_mark_node;
else if (complete_type_or_else (TREE_TYPE (parms), parms))
{
layout_decl (parms, 0);
DECL_ARG_TYPE (parms) = type_passed_as (TREE_TYPE (parms));
}
- else
- TREE_TYPE (parms) = error_mark_node;
}
}
/* Returns nonzero if T is a local variable. */
int
-local_variable_p (t)
- tree t;
+local_variable_p (tree t)
{
if ((TREE_CODE (t) == VAR_DECL
/* A VAR_DECL with a context that is a _TYPE is a static data
@@ -12700,8 +8515,7 @@ local_variable_p (t)
containing them is duplicated.) */
int
-nonstatic_local_decl_p (t)
- tree t;
+nonstatic_local_decl_p (tree t)
{
return ((local_variable_p (t) && !TREE_STATIC (t))
|| TREE_CODE (t) == LABEL_DECL
@@ -12712,10 +8526,9 @@ nonstatic_local_decl_p (t)
function. */
static tree
-local_variable_p_walkfn (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+local_variable_p_walkfn (tree* tp,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data ATTRIBUTE_UNUSED )
{
return ((local_variable_p (*tp) && !DECL_ARTIFICIAL (*tp))
? *tp : NULL_TREE);
@@ -12727,9 +8540,7 @@ local_variable_p_walkfn (tp, walk_subtrees, data)
DECL, if there is no DECL available. */
tree
-check_default_argument (decl, arg)
- tree decl;
- tree arg;
+check_default_argument (tree decl, tree arg)
{
tree var;
tree decl_type;
@@ -12808,11 +8619,10 @@ check_default_argument (decl, arg)
flag. If unset, we append void_list_node. A parmlist declared
as `(void)' is accepted as the empty parmlist.
- Also set last_function_parms to the chain of PARM_DECLs. */
+ *PARMS is set to the chain of PARM_DECLs created. */
static tree
-grokparms (first_parm)
- tree first_parm;
+grokparms (tree first_parm, tree *parms)
{
tree result = NULL_TREE;
tree decls = NULL_TREE;
@@ -12873,19 +8683,13 @@ grokparms (first_parm)
{
/* Top-level qualifiers on the parameters are
ignored for function types. */
- type = TYPE_MAIN_VARIANT (type);
+ type = cp_build_qualified_type (type, 0);
if (TREE_CODE (type) == METHOD_TYPE)
{
error ("parameter `%D' invalidly declared method type", decl);
type = build_pointer_type (type);
TREE_TYPE (decl) = type;
}
- else if (TREE_CODE (type) == OFFSET_TYPE)
- {
- error ("parameter `%D' invalidly declared offset type", decl);
- type = build_pointer_type (type);
- TREE_TYPE (decl) = type;
- }
else if (abstract_virtuals_error (decl, type))
any_error = 1; /* Seems like a good idea. */
else if (POINTER_TYPE_P (type))
@@ -12924,7 +8728,7 @@ grokparms (first_parm)
result = nreverse (result);
if (!ellipsis)
result = chainon (result, void_list_node);
- last_function_parms = decls;
+ *parms = decls;
return result;
}
@@ -12949,8 +8753,7 @@ grokparms (first_parm)
operator. */
int
-copy_fn_p (d)
- tree d;
+copy_fn_p (tree d)
{
tree args;
tree arg_type;
@@ -12996,8 +8799,7 @@ copy_fn_p (d)
/* Remember any special properties of member function DECL. */
-void grok_special_member_properties (decl)
- tree decl;
+void grok_special_member_properties (tree decl)
{
if (!DECL_NONSTATIC_MEMBER_FUNCTION_P(decl))
; /* Not special. */
@@ -13046,8 +8848,7 @@ void grok_special_member_properties (decl)
if the class has a constructor of the form X(X). */
int
-grok_ctor_properties (ctype, decl)
- tree ctype, decl;
+grok_ctor_properties (tree ctype, tree decl)
{
int ctor_parm = copy_fn_p (decl);
@@ -13080,8 +8881,7 @@ grok_ctor_properties (ctype, decl)
/* An operator with this code is unary, but can also be binary. */
static int
-ambi_op_p (code)
- enum tree_code code;
+ambi_op_p (enum tree_code code)
{
return (code == INDIRECT_REF
|| code == ADDR_EXPR
@@ -13094,8 +8894,7 @@ ambi_op_p (code)
/* An operator with this name can only be unary. */
static int
-unary_op_p (code)
- enum tree_code code;
+unary_op_p (enum tree_code code)
{
return (code == TRUTH_NOT_EXPR
|| code == BIT_NOT_EXPR
@@ -13103,12 +8902,12 @@ unary_op_p (code)
|| code == TYPE_EXPR);
}
-/* Do a little sanity-checking on how they declared their operator. */
+/* DECL is a declaration for an overloaded operator. Returns true if
+ the declaration is valid; false otherwise. If COMPLAIN is true,
+ errors are issued for invalid declarations. */
-void
-grok_op_properties (decl, friendp)
- tree decl;
- int friendp;
+bool
+grok_op_properties (tree decl, int friendp, bool complain)
{
tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
tree argtype;
@@ -13116,6 +8915,10 @@ grok_op_properties (decl, friendp)
tree name = DECL_NAME (decl);
enum tree_code operator_code;
int arity;
+ bool ok;
+
+ /* Assume that the declaration is valid. */
+ ok = true;
/* Count the number of arguments. */
for (argtype = argtypes, arity = 0;
@@ -13157,19 +8960,6 @@ grok_op_properties (decl, friendp)
{
switch (operator_code)
{
- case CALL_EXPR:
- TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1;
- break;
-
- case ARRAY_REF:
- TYPE_OVERLOADS_ARRAY_REF (current_class_type) = 1;
- break;
-
- case COMPONENT_REF:
- case MEMBER_REF:
- TYPE_OVERLOADS_ARROW (current_class_type) = 1;
- break;
-
case NEW_EXPR:
TYPE_HAS_NEW_OPERATOR (current_class_type) = 1;
break;
@@ -13192,21 +8982,9 @@ grok_op_properties (decl, friendp)
}
if (operator_code == NEW_EXPR || operator_code == VEC_NEW_EXPR)
- {
- /* When the compiler encounters the definition of A::operator new, it
- doesn't look at the class declaration to find out if it's static. */
- if (methodp)
- revert_static_member_fn (decl);
-
- TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
- }
+ TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl));
else if (operator_code == DELETE_EXPR || operator_code == VEC_DELETE_EXPR)
- {
- if (methodp)
- revert_static_member_fn (decl);
-
- TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
- }
+ TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl));
else
{
/* An operator function must either be a non-static member function
@@ -13222,35 +9000,38 @@ grok_op_properties (decl, friendp)
error ("`%D' must be a nonstatic member function", decl);
else
{
- tree p = argtypes;
+ tree p;
if (DECL_STATIC_FUNCTION_P (decl))
error ("`%D' must be either a non-static member function or a non-member function", decl);
- if (p)
- for (; TREE_CODE (TREE_VALUE (p)) != VOID_TYPE ; p = TREE_CHAIN (p))
- {
- tree arg = TREE_VALUE (p);
- if (TREE_CODE (arg) == REFERENCE_TYPE)
- arg = TREE_TYPE (arg);
-
- /* This lets bad template code slip through. */
- if (IS_AGGR_TYPE (arg)
- || TREE_CODE (arg) == ENUMERAL_TYPE
- || TREE_CODE (arg) == TEMPLATE_TYPE_PARM
- || TREE_CODE (arg) == BOUND_TEMPLATE_TEMPLATE_PARM)
- goto foundaggr;
- }
- error
- ("`%D' must have an argument of class or enumerated type",
- decl);
- foundaggr:
- ;
+ for (p = argtypes; p && p != void_list_node; p = TREE_CHAIN (p))
+ {
+ tree arg = non_reference (TREE_VALUE (p));
+ /* IS_AGGR_TYPE, rather than CLASS_TYPE_P, is used
+ because these checks are performed even on
+ template functions. */
+ if (IS_AGGR_TYPE (arg) || TREE_CODE (arg) == ENUMERAL_TYPE)
+ break;
+ }
+
+ if (!p || p == void_list_node)
+ {
+ if (!complain)
+ return false;
+
+ error ("`%D' must have an argument of class or "
+ "enumerated type",
+ decl);
+ ok = false;
+ }
}
}
+ /* There are no restrictions on the arguments to an overloaded
+ "operator ()". */
if (operator_code == CALL_EXPR)
- return; /* No restrictions on args. */
+ return ok;
if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl))
{
@@ -13433,11 +9214,12 @@ grok_op_properties (decl, friendp)
}
}
+
+ return ok;
}
static const char *
-tag_name (code)
- enum tag_types code;
+tag_name (enum tag_types code)
{
switch (code)
{
@@ -13455,58 +9237,109 @@ tag_name (code)
}
/* Name lookup in an elaborated-type-specifier (after the keyword
- indicated by TAG_CODE) has found TYPE. If the
+ indicated by TAG_CODE) has found the TYPE_DECL DECL. If the
elaborated-type-specifier is invalid, issue a diagnostic and return
- error_mark_node; otherwise, return TYPE itself. */
+ error_mark_node; otherwise, return the *_TYPE to which it referred.
+ If ALLOW_TEMPLATE_P is true, TYPE may be a class template. */
-static tree
+tree
check_elaborated_type_specifier (enum tag_types tag_code,
- tree type)
+ tree decl,
+ bool allow_template_p)
{
- tree t;
+ tree type;
- t = follow_tag_typedef (type);
+ /* In the case of:
- /* [dcl.type.elab] If the identifier resolves to a typedef-name or a
- template type-parameter, the elaborated-type-specifier is
- ill-formed. */
- if (!t)
+ struct S { struct S *p; };
+
+ name lookup will find the TYPE_DECL for the implicit "S::S"
+ typedef. Adjust for that here. */
+ if (DECL_SELF_REFERENCE_P (decl))
+ decl = TYPE_NAME (TREE_TYPE (decl));
+
+ type = TREE_TYPE (decl);
+
+ /* [dcl.type.elab]
+
+ If the identifier resolves to a typedef-name or a template
+ type-parameter, the elaborated-type-specifier is ill-formed.
+
+ In other words, the only legitimate declaration to use in the
+ elaborated type specifier is the implicit typedef created when
+ the type is declared. */
+ if (!DECL_IMPLICIT_TYPEDEF_P (decl))
{
- error ("using typedef-name `%D' after `%s'",
- TYPE_NAME (type), tag_name (tag_code));
- t = error_mark_node;
+ error ("using typedef-name `%D' after `%s'", decl, tag_name (tag_code));
+ return IS_AGGR_TYPE (type) ? type : error_mark_node;
}
- else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+
+ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
{
error ("using template type parameter `%T' after `%s'",
type, tag_name (tag_code));
- t = error_mark_node;
+ return error_mark_node;
+ }
+ else if (TREE_CODE (type) != RECORD_TYPE
+ && TREE_CODE (type) != UNION_TYPE
+ && tag_code != enum_type)
+ {
+ error ("`%T' referred to as `%s'", type, tag_name (tag_code));
+ return error_mark_node;
+ }
+ else if (TREE_CODE (type) != ENUMERAL_TYPE
+ && tag_code == enum_type)
+ {
+ error ("`%T' referred to as enum", type);
+ return error_mark_node;
}
+ else if (!allow_template_p
+ && TREE_CODE (type) == RECORD_TYPE
+ && CLASSTYPE_IS_TEMPLATE (type))
+ {
+ /* If a class template appears as elaborated type specifier
+ without a template header such as:
- return t;
+ template <class T> class C {};
+ void f(class C); // No template header here
+
+ then the required template argument is missing. */
+
+ error ("template argument required for `%s %T'",
+ tag_name (tag_code),
+ DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)));
+ return error_mark_node;
+ }
+
+ return type;
}
-/* Get the struct, enum or union (CODE says which) with tag NAME.
+/* Get the struct, enum or union (TAG_CODE says which) with tag NAME.
Define the tag as a forward-reference if it is not defined.
- C++: If a class derivation is given, process it here, and report
- an error if multiple derivation declarations are not identical.
+ If a declaration is given, process it here, and report an error if
+ multiple declarations are not identical.
- If this is a definition, come in through xref_tag and only look in
+ GLOBALIZE is false when this is also a definition. Only look in
the current frame for the name (since C++ allows new names in any
- scope.) */
+ scope.)
+
+ TEMPLATE_HEADER_P is true when this declaration is preceded by
+ a set of template parameters. */
tree
-xref_tag (enum tag_types tag_code, tree name, tree attributes,
- bool globalize)
+xref_tag (enum tag_types tag_code, tree name,
+ bool globalize, bool template_header_p)
{
enum tree_code code;
- register tree ref, t;
+ tree t;
struct cp_binding_level *b = current_binding_level;
tree context = NULL_TREE;
timevar_push (TV_NAME_LOOKUP);
+ my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0);
+
switch (tag_code)
{
case record_type:
@@ -13523,93 +9356,50 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
abort ();
}
- /* If a cross reference is requested, look up the type
- already defined for this tag and return it. */
- if (TYPE_P (name))
- {
- t = name;
- name = TYPE_IDENTIFIER (t);
- }
- else
- t = IDENTIFIER_TYPE_VALUE (name);
-
- /* Warn about 'friend struct Inherited;' doing the wrong thing. */
- if (t && globalize && TREE_CODE (t) == TYPENAME_TYPE)
- {
- static int explained;
- tree shadowed;
-
- warning ("`%s %T' declares a new type at namespace scope",
- tag_name (tag_code), name);
- if (!explained++)
- warning (" names from dependent base classes are not visible to unqualified name lookup - to refer to the inherited type, say `%s %T::%T'",
- tag_name (tag_code),
- constructor_name (current_class_type),
- TYPE_IDENTIFIER (t));
-
- /* We need to remove the class scope binding for the
- TYPENAME_TYPE as otherwise poplevel_class gets confused. */
- for (shadowed = b->class_shadowed;
- shadowed;
- shadowed = TREE_CHAIN (shadowed))
- if (TREE_TYPE (shadowed) == TYPE_NAME (t))
- {
- TREE_PURPOSE (shadowed) = NULL_TREE;
- break;
- }
- }
-
- if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM
- && TREE_CODE (t) != BOUND_TEMPLATE_TEMPLATE_PARM)
- t = NULL_TREE;
-
if (! globalize)
{
/* If we know we are defining this tag, only look it up in
this scope and don't try to find it as a type. */
- ref = lookup_tag (code, name, b, 1);
+ t = lookup_tag (code, name, b, 1);
}
else
{
- if (t)
- {
- ref = check_elaborated_type_specifier (tag_code, t);
- if (ref == error_mark_node)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- }
- else
- ref = lookup_tag (code, name, b, 0);
+ tree decl = lookup_name (name, 2);
- if (! ref)
+ if (decl && DECL_CLASS_TEMPLATE_P (decl))
+ decl = DECL_TEMPLATE_RESULT (decl);
+
+ if (decl && TREE_CODE (decl) == TYPE_DECL)
{
- /* Try finding it as a type declaration. If that wins,
- use it. */
- ref = lookup_name (name, 1);
+ /* Two cases we need to consider when deciding if a class
+ template is allowed as an elaborated type specifier:
+ 1. It is a self reference to its own class.
+ 2. It comes with a template header.
- if (ref != NULL_TREE
- && processing_template_decl
- && DECL_CLASS_TEMPLATE_P (ref)
- && template_class_depth (current_class_type) == 0)
- /* Since GLOBALIZE is true, we're declaring a global
- template, so we want this type. */
- ref = DECL_TEMPLATE_RESULT (ref);
+ For example:
- if (ref && TREE_CODE (ref) == TYPE_DECL)
- {
- ref = check_elaborated_type_specifier (tag_code,
- TREE_TYPE (ref));
- if (ref == error_mark_node)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- if (ref && TREE_CODE (ref) != code)
- ref = NULL_TREE;
- }
- else
- ref = NULL_TREE;
+ template <class T> class C {
+ class C *c1; // DECL_SELF_REFERENCE_P is true
+ class D;
+ };
+ template <class U> class C; // template_header_p is true
+ template <class T> class C<T>::D {
+ class C *c2; // DECL_SELF_REFERENCE_P is true
+ }; */
+
+ t = check_elaborated_type_specifier (tag_code,
+ decl,
+ template_header_p
+ | DECL_SELF_REFERENCE_P (decl));
+ if (t == error_mark_node)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
+ else
+ t = NULL_TREE;
- if (ref && current_class_type
+ if (t && current_class_type
&& template_class_depth (current_class_type)
- && PROCESSING_REAL_TEMPLATE_DECL_P ())
+ && template_header_p)
{
/* Since GLOBALIZE is nonzero, we are not looking at a
definition of this tag. Since, in addition, we are currently
@@ -13647,12 +9437,12 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
accomplish this by making sure that the new type we
create to represent this declaration has the right
TYPE_CONTEXT. */
- context = TYPE_CONTEXT (ref);
- ref = NULL_TREE;
+ context = TYPE_CONTEXT (t);
+ t = NULL_TREE;
}
}
- if (! ref)
+ if (! t)
{
/* If no such tag is yet defined, create a forward-reference node
and record it as the "definition".
@@ -13661,56 +9451,33 @@ xref_tag (enum tag_types tag_code, tree name, tree attributes,
if (code == ENUMERAL_TYPE)
{
error ("use of enum `%#D' without previous declaration", name);
-
- ref = make_node (ENUMERAL_TYPE);
-
- /* Give the type a default layout like unsigned int
- to avoid crashing if it does not get defined. */
- TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
- TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node);
- TYPE_USER_ALIGN (ref) = 0;
- TREE_UNSIGNED (ref) = 1;
- TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node);
- TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node);
- TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node);
-
- /* Enable us to recognize when a type is created in class context.
- To do nested classes correctly, this should probably be cleared
- out when we leave this classes scope. Currently this in only
- done in `start_enum'. */
-
- pushtag (name, ref, globalize);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
else
{
- struct cp_binding_level *old_b = class_binding_level;
-
- ref = make_aggr_type (code);
- TYPE_CONTEXT (ref) = context;
-
-#ifdef NONNESTED_CLASSES
- /* Class types don't nest the way enums do. */
- class_binding_level = (struct cp_binding_level *)0;
-#endif
- pushtag (name, ref, globalize);
- class_binding_level = old_b;
+ t = make_aggr_type (code);
+ TYPE_CONTEXT (t) = context;
+ pushtag (name, t, globalize);
}
}
else
{
- if (!globalize && processing_template_decl && IS_AGGR_TYPE (ref))
- redeclare_class_template (ref, current_template_parms);
+ if (!globalize && processing_template_decl && IS_AGGR_TYPE (t))
+ redeclare_class_template (t, current_template_parms);
+ else if (!processing_template_decl
+ && CLASS_TYPE_P (t)
+ && CLASSTYPE_IS_TEMPLATE (t))
+ {
+ error ("redeclaration of `%T' as a non-template", t);
+ t = error_mark_node;
+ }
}
- TYPE_ATTRIBUTES (ref) = attributes;
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ref);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
}
tree
-xref_tag_from_type (old, id, globalize)
- tree old, id;
- int globalize;
+xref_tag_from_type (tree old, tree id, int globalize)
{
enum tag_types tag_kind;
@@ -13722,28 +9489,29 @@ xref_tag_from_type (old, id, globalize)
if (id == NULL_TREE)
id = TYPE_IDENTIFIER (old);
- return xref_tag (tag_kind, id, /*attributes=*/NULL_TREE, globalize);
+ return xref_tag (tag_kind, id, globalize, false);
}
/* REF is a type (named NAME), for which we have just seen some
- baseclasses. BINFO is a list of those baseclasses; the
+ baseclasses. BASE_LIST is a list of those baseclasses; the
TREE_PURPOSE is an access_* node, and the TREE_VALUE is the type of
- the base-class. CODE_TYPE_NODE indicates whether REF is a class,
+ the base-class. TREE_VIA_VIRTUAL indicates virtual
+ inheritance. CODE_TYPE_NODE indicates whether REF is a class,
struct, or union. */
void
-xref_basetypes (ref, binfo)
- tree ref;
- tree binfo;
+xref_basetypes (tree ref, tree base_list)
{
/* In the declaration `A : X, Y, ... Z' we mark all the types
(A, X, Y, ..., Z) so we can check for duplicates. */
- tree binfos;
- tree base;
+ tree *basep;
- int i, len;
+ int i;
enum tag_types tag_code;
+ if (ref == error_mark_node)
+ return;
+
if (TREE_CODE (ref) == UNION_TYPE)
{
error ("derived union `%T' invalid", ref);
@@ -13752,61 +9520,58 @@ xref_basetypes (ref, binfo)
tag_code = (CLASSTYPE_DECLARED_CLASS (ref) ? class_type : record_type);
- len = list_length (binfo);
-
/* First, make sure that any templates in base-classes are
instantiated. This ensures that if we call ourselves recursively
we do not get confused about which classes are marked and which
are not. */
- for (base = binfo; base; base = TREE_CHAIN (base))
- complete_type (TREE_VALUE (base));
+ basep = &base_list;
+ while (*basep)
+ {
+ tree basetype = TREE_VALUE (*basep);
+ if (!(processing_template_decl && uses_template_parms (basetype))
+ && !complete_type_or_else (basetype, NULL))
+ /* An incomplete type. Remove it from the list. */
+ *basep = TREE_CHAIN (*basep);
+ else
+ basep = &TREE_CHAIN (*basep);
+ }
SET_CLASSTYPE_MARKED (ref);
- BINFO_BASETYPES (TYPE_BINFO (ref)) = binfos = make_tree_vec (len);
-
- for (i = 0; binfo; binfo = TREE_CHAIN (binfo))
- {
- /* The base of a derived struct is public by default. */
- int via_public
- = (TREE_PURPOSE (binfo) == access_public_node
- || TREE_PURPOSE (binfo) == access_public_virtual_node
- || (tag_code != class_type
- && (TREE_PURPOSE (binfo) == access_default_node
- || TREE_PURPOSE (binfo) == access_default_virtual_node)));
- int via_protected
- = (TREE_PURPOSE (binfo) == access_protected_node
- || TREE_PURPOSE (binfo) == access_protected_virtual_node);
- int via_virtual
- = (TREE_PURPOSE (binfo) == access_private_virtual_node
- || TREE_PURPOSE (binfo) == access_protected_virtual_node
- || TREE_PURPOSE (binfo) == access_public_virtual_node
- || TREE_PURPOSE (binfo) == access_default_virtual_node);
- tree basetype = TREE_VALUE (binfo);
- tree base_binfo;
-
- if (basetype && TREE_CODE (basetype) == TYPE_DECL)
- basetype = TREE_TYPE (basetype);
- if (!basetype
- || (TREE_CODE (basetype) != RECORD_TYPE
- && TREE_CODE (basetype) != TYPENAME_TYPE
- && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM
- && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM))
- {
- error ("base type `%T' fails to be a struct or class type",
- TREE_VALUE (binfo));
- continue;
- }
-
- /* This code replaces similar code in layout_basetypes.
- We put the complete_type first for implicit `typename'. */
- if (!COMPLETE_TYPE_P (basetype)
- && ! (current_template_parms && uses_template_parms (basetype)))
- {
- error ("base class `%T' has incomplete type", basetype);
- continue;
- }
- else
+ i = list_length (base_list);
+ if (i)
+ {
+ tree binfo = TYPE_BINFO (ref);
+ tree binfos = make_tree_vec (i);
+ tree accesses = make_tree_vec (i);
+
+ BINFO_BASETYPES (binfo) = binfos;
+ BINFO_BASEACCESSES (binfo) = accesses;
+
+ for (i = 0; base_list; base_list = TREE_CHAIN (base_list))
{
+ tree access = TREE_PURPOSE (base_list);
+ int via_virtual = TREE_VIA_VIRTUAL (base_list);
+ tree basetype = TREE_VALUE (base_list);
+ tree base_binfo;
+
+ if (access == access_default_node)
+ /* The base of a derived struct is public by default. */
+ access = (tag_code == class_type
+ ? access_private_node : access_public_node);
+
+ if (basetype && TREE_CODE (basetype) == TYPE_DECL)
+ basetype = TREE_TYPE (basetype);
+ if (!basetype
+ || (TREE_CODE (basetype) != RECORD_TYPE
+ && TREE_CODE (basetype) != TYPENAME_TYPE
+ && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM
+ && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM))
+ {
+ error ("base type `%T' fails to be a struct or class type",
+ basetype);
+ continue;
+ }
+
if (CLASSTYPE_MARKED (basetype))
{
if (basetype == ref)
@@ -13815,48 +9580,41 @@ xref_basetypes (ref, binfo)
error ("duplicate base type `%T' invalid", basetype);
continue;
}
-
+
if (TYPE_FOR_JAVA (basetype)
&& (current_lang_depth () == 0))
TYPE_FOR_JAVA (ref) = 1;
-
- /* Note that the BINFO records which describe individual
- inheritances are *not* shared in the lattice! They
- cannot be shared because a given baseclass may be
- inherited with different `accessibility' by different
- derived classes. (Each BINFO record describing an
- individual inheritance contains flags which say what
- the `accessibility' of that particular inheritance is.) */
-
- base_binfo
- = make_binfo (size_zero_node, basetype,
- CLASS_TYPE_P (basetype)
- ? TYPE_BINFO_VTABLE (basetype) : NULL_TREE,
- CLASS_TYPE_P (basetype)
- ? TYPE_BINFO_VIRTUALS (basetype) : NULL_TREE);
-
+
+ if (CLASS_TYPE_P (basetype))
+ {
+ base_binfo = TYPE_BINFO (basetype);
+ /* This flag will be in the binfo of the base type, we must
+ clear it after copying the base binfos. */
+ BINFO_DEPENDENT_BASE_P (base_binfo)
+ = dependent_type_p (basetype);
+ }
+ else
+ base_binfo = make_binfo (size_zero_node, basetype,
+ NULL_TREE, NULL_TREE);
+
TREE_VEC_ELT (binfos, i) = base_binfo;
- TREE_VIA_PUBLIC (base_binfo) = via_public;
- TREE_VIA_PROTECTED (base_binfo) = via_protected;
+ TREE_VEC_ELT (accesses, i) = access;
+ /* This flag will be in the binfo of the base type, we must
+ clear it after copying the base binfos. */
TREE_VIA_VIRTUAL (base_binfo) = via_virtual;
- BINFO_INHERITANCE_CHAIN (base_binfo) = TYPE_BINFO (ref);
-
- /* We need to unshare the binfos now so that lookups during class
- definition work. */
- unshare_base_binfos (base_binfo);
-
+
SET_CLASSTYPE_MARKED (basetype);
-
+
/* We are free to modify these bits because they are meaningless
at top level, and BASETYPE is a top-level type. */
if (via_virtual || TYPE_USES_VIRTUAL_BASECLASSES (basetype))
{
TYPE_USES_VIRTUAL_BASECLASSES (ref) = 1;
/* Converting to a virtual base class requires looking
- up the offset of the virtual base. */
+ up the offset of the virtual base. */
TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1;
}
-
+
if (CLASS_TYPE_P (basetype))
{
TYPE_HAS_NEW_OPERATOR (ref)
@@ -13868,36 +9626,53 @@ xref_basetypes (ref, binfo)
TYPE_USES_MULTIPLE_INHERITANCE (ref)
|= TYPE_USES_MULTIPLE_INHERITANCE (basetype);
/* Likewise, if converting to a base of the base may require
- code, then we may need to generate code to convert to a
- base as well. */
+ code, then we may need to generate code to convert to a
+ base as well. */
TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref)
|= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (basetype);
}
-
- i += 1;
+ i++;
+ }
+ if (i)
+ TREE_VEC_LENGTH (accesses) = TREE_VEC_LENGTH (binfos) = i;
+ else
+ BINFO_BASEACCESSES (binfo) = BINFO_BASETYPES (binfo) = NULL_TREE;
+
+ if (i > 1)
+ {
+ TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1;
+ /* If there is more than one non-empty they cannot be at the same
+ address. */
+ TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1;
}
}
- if (i)
- TREE_VEC_LENGTH (binfos) = i;
- else
- BINFO_BASETYPES (TYPE_BINFO (ref)) = NULL_TREE;
+
+ /* Copy the base binfos, collect the virtual bases and set the
+ inheritance order chain. */
+ copy_base_binfos (TYPE_BINFO (ref), ref, NULL_TREE);
+ CLASSTYPE_VBASECLASSES (ref) = nreverse (CLASSTYPE_VBASECLASSES (ref));
- if (i > 1)
+ if (TYPE_FOR_JAVA (ref))
{
- TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1;
- /* If there is more than one non-empty they cannot be at the same
- address. */
- TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1;
+ if (TYPE_USES_MULTIPLE_INHERITANCE (ref))
+ error ("Java class '%T' cannot have multiple bases", ref);
+ if (CLASSTYPE_VBASECLASSES (ref))
+ error ("Java class '%T' cannot have virtual bases", ref);
}
/* Unmark all the types. */
- while (--i >= 0)
- CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (TREE_VEC_ELT (binfos, i)));
+ while (i--)
+ {
+ tree basetype = BINFO_TYPE (BINFO_BASETYPE (TYPE_BINFO (ref), i));
+
+ CLEAR_CLASSTYPE_MARKED (basetype);
+ if (CLASS_TYPE_P (basetype))
+ {
+ TREE_VIA_VIRTUAL (TYPE_BINFO (basetype)) = 0;
+ BINFO_DEPENDENT_BASE_P (TYPE_BINFO (basetype)) = 0;
+ }
+ }
CLEAR_CLASSTYPE_MARKED (ref);
-
- /* Now that we know all the base-classes, set up the list of virtual
- bases. */
- get_vbase_types (ref);
}
@@ -13908,10 +9683,9 @@ xref_basetypes (ref, binfo)
may be used to declare the individual values as they are read. */
tree
-start_enum (name)
- tree name;
+start_enum (tree name)
{
- register tree enumtype = NULL_TREE;
+ tree enumtype = NULL_TREE;
struct cp_binding_level *b = current_binding_level;
/* If this is the real definition for a previous forward reference,
@@ -13924,7 +9698,7 @@ start_enum (name)
if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE)
{
error ("multiple definition of `%#T'", enumtype);
- cp_error_at ("previous definition here", enumtype);
+ error ("%Jprevious definition here", TYPE_MAIN_DECL (enumtype));
/* Clear out TYPE_VALUES, and start again. */
TYPE_VALUES (enumtype) = NULL_TREE;
}
@@ -13942,10 +9716,11 @@ start_enum (name)
ENUMTYPE is the type object and VALUES a list of name-value pairs. */
void
-finish_enum (enumtype)
- tree enumtype;
+finish_enum (tree enumtype)
{
- tree pair;
+ tree values;
+ tree decl;
+ tree value;
tree minnode;
tree maxnode;
tree t;
@@ -13953,6 +9728,8 @@ finish_enum (enumtype)
int lowprec;
int highprec;
int precision;
+ integer_type_kind itk;
+ tree underlying_type = NULL_TREE;
/* We built up the VALUES in reverse order. */
TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));
@@ -13963,21 +9740,25 @@ finish_enum (enumtype)
works. */
if (processing_template_decl)
{
- for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
- TREE_TYPE (TREE_VALUE (pair)) = enumtype;
+ for (values = TYPE_VALUES (enumtype);
+ values;
+ values = TREE_CHAIN (values))
+ TREE_TYPE (TREE_VALUE (values)) = enumtype;
if (at_function_scope_p ())
add_stmt (build_min (TAG_DEFN, enumtype));
return;
}
+ /* Determine the minimum and maximum values of the enumerators. */
if (TYPE_VALUES (enumtype))
{
minnode = maxnode = NULL_TREE;
- for (pair = TYPE_VALUES (enumtype); pair; pair = TREE_CHAIN (pair))
+ for (values = TYPE_VALUES (enumtype);
+ values;
+ values = TREE_CHAIN (values))
{
- tree decl = TREE_VALUE (pair);
- tree value = DECL_INITIAL (decl);
+ decl = TREE_VALUE (values);
/* [dcl.enum]: Following the closing brace of an enum-specifier,
each enumerator has the type of its enumeration. Prior to the
@@ -13985,6 +9766,8 @@ finish_enum (enumtype)
initializing value. */
TREE_TYPE (decl) = enumtype;
+ /* Update the minimum and maximum values, if appropriate. */
+ value = DECL_INITIAL (decl);
/* Figure out what the minimum and maximum values of the
enumerators are. */
if (!minnode)
@@ -14003,13 +9786,13 @@ finish_enum (enumtype)
value = DECL_INITIAL (decl) = copy_node (value);
TREE_TYPE (value) = enumtype;
}
-
- /* In addition, transform the TYPE_VALUES list to contain the
- values, rather than the CONST_DECLs for them. */
- TREE_VALUE (pair) = value;
}
}
else
+ /* [dcl.enum]
+
+ If the enumerator-list is empty, the underlying type is as if
+ the enumeration had a single enumerator with value 0. */
minnode = maxnode = integer_zero_node;
/* Compute the number of bits require to represent all values of the
@@ -14021,36 +9804,76 @@ finish_enum (enumtype)
highprec = min_precision (maxnode, unsignedp);
precision = MAX (lowprec, highprec);
- /* DR 377
-
- IF no integral type can represent all the enumerator values, the
- enumeration is ill-formed. */
- if (precision > TYPE_PRECISION (long_long_integer_type_node))
+ /* Determine the underlying type of the enumeration.
+
+ [dcl.enum]
+
+ The underlying type of an enumeration is an integral type that
+ can represent all the enumerator values defined in the
+ enumeration. It is implementation-defined which integral type is
+ used as the underlying type for an enumeration except that the
+ underlying type shall not be larger than int unless the value of
+ an enumerator cannot fit in an int or unsigned int.
+
+ We use "int" or an "unsigned int" as the underlying type, even if
+ a smaller integral type would work, unless the user has
+ explicitly requested that we use the smallest possible type. */
+ for (itk = (flag_short_enums ? itk_char : itk_int);
+ itk != itk_none;
+ itk++)
{
+ underlying_type = integer_types[itk];
+ if (TYPE_PRECISION (underlying_type) >= precision
+ && TREE_UNSIGNED (underlying_type) == unsignedp)
+ break;
+ }
+ if (itk == itk_none)
+ {
+ /* DR 377
+
+ IF no integral type can represent all the enumerator values, the
+ enumeration is ill-formed. */
error ("no integral type can represent all of the enumerator values "
"for `%T'", enumtype);
precision = TYPE_PRECISION (long_long_integer_type_node);
+ underlying_type = integer_types[itk_unsigned_long_long];
}
- /* Compute the minium and maximum values for the type, the size of
- the type, and so forth. */
- TYPE_PRECISION (enumtype) = precision;
- TYPE_SIZE (enumtype) = NULL_TREE;
- if (unsignedp)
- fixup_unsigned_type (enumtype);
- else
- fixup_signed_type (enumtype);
+ /* Compute the minium and maximum values for the type.
- if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node)))
- /* Use the width of the narrowest normal C type which is wide
- enough. */
- TYPE_PRECISION (enumtype) = TYPE_PRECISION (c_common_type_for_size
- (precision, 1));
- else
- TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node);
+ [dcl.enum]
- TYPE_SIZE (enumtype) = NULL_TREE;
- layout_type (enumtype);
+ For an enumeration where emin is the smallest enumerator and emax
+ is the largest, the values of the enumeration are the values of the
+ underlying type in the range bmin to bmax, where bmin and bmax are,
+ respectively, the smallest and largest values of the smallest bit-
+ field that can store emin and emax. */
+ TYPE_PRECISION (enumtype) = precision;
+ set_min_and_max_values_for_integral_type (enumtype, precision, unsignedp);
+
+ /* [dcl.enum]
+
+ The value of sizeof() applied to an enumeration type, an object
+ of an enumeration type, or an enumerator, is the value of sizeof()
+ applied to the underlying type. */
+ TYPE_SIZE (enumtype) = TYPE_SIZE (underlying_type);
+ TYPE_SIZE_UNIT (enumtype) = TYPE_SIZE_UNIT (underlying_type);
+ TYPE_MODE (enumtype) = TYPE_MODE (underlying_type);
+ TYPE_ALIGN (enumtype) = TYPE_ALIGN (underlying_type);
+ TYPE_USER_ALIGN (enumtype) = TYPE_USER_ALIGN (underlying_type);
+ TREE_UNSIGNED (enumtype) = TREE_UNSIGNED (underlying_type);
+
+ /* Convert each of the enumerators to the type of the underlying
+ type of the enumeration. */
+ for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
+ {
+ decl = TREE_VALUE (values);
+ value = perform_implicit_conversion (underlying_type,
+ DECL_INITIAL (decl));
+ TREE_TYPE (value) = enumtype;
+ DECL_INITIAL (decl) = value;
+ TREE_VALUE (values) = value;
+ }
/* Fix up all variant types of this enum type. */
for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t))
@@ -14076,10 +9899,7 @@ finish_enum (enumtype)
Assignment of sequential values by default is handled here. */
void
-build_enumerator (name, value, enumtype)
- tree name;
- tree value;
- tree enumtype;
+build_enumerator (tree name, tree value, tree enumtype)
{
tree decl;
tree context;
@@ -14098,7 +9918,7 @@ build_enumerator (name, value, enumtype)
if (TREE_CODE (value) == INTEGER_CST)
{
- value = default_conversion (value);
+ value = perform_integral_promotions (value);
constant_expression_warning (value);
}
else
@@ -14109,7 +9929,7 @@ build_enumerator (name, value, enumtype)
}
/* Default based on previous value. */
- if (value == NULL_TREE && ! processing_template_decl)
+ if (value == NULL_TREE)
{
tree prev_value;
@@ -14135,6 +9955,8 @@ build_enumerator (name, value, enumtype)
/* C++ associates enums with global, function, or class declarations. */
context = current_scope ();
+ if (!context)
+ context = current_namespace;
/* Build the actual enumeration constant. Note that the enumeration
constants have the type of their initializers until the
@@ -14161,13 +9983,13 @@ build_enumerator (name, value, enumtype)
decl = build_decl (CONST_DECL, name, type);
DECL_CONTEXT (decl) = FROB_CONTEXT (context);
+ TREE_CONSTANT (decl) = TREE_READONLY (decl) = 1;
DECL_INITIAL (decl) = value;
- TREE_READONLY (decl) = 1;
if (context && context == current_class_type)
/* In something like `struct S { enum E { i = 7 }; };' we put `i'
- on the TYPE_FIELDS list for `S'. (That's so that you can say
- things like `S::i' later.) */
+ on the TYPE_FIELDS list for `S'. (That's so that you can say
+ things like `S::i' later.) */
finish_member_declaration (decl);
else
pushdecl (decl);
@@ -14180,9 +10002,7 @@ build_enumerator (name, value, enumtype)
/* We're defining DECL. Make sure that it's type is OK. */
static void
-check_function_type (decl, current_function_parms)
- tree decl;
- tree current_function_parms;
+check_function_type (tree decl, tree current_function_parms)
{
tree fntype = TREE_TYPE (decl);
tree return_type = complete_type (TREE_TYPE (fntype));
@@ -14200,9 +10020,9 @@ check_function_type (decl, current_function_parms)
{
tree ctype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype)));
TREE_TYPE (decl)
- = build_cplus_method_type (ctype,
- void_type_node,
- FUNCTION_ARG_CHAIN (decl));
+ = build_method_type_directly (ctype,
+ void_type_node,
+ FUNCTION_ARG_CHAIN (decl));
}
else
TREE_TYPE (decl)
@@ -14239,9 +10059,7 @@ check_function_type (decl, current_function_parms)
applied to it with the argument list [1, 2]. */
int
-start_function (declspecs, declarator, attrs, flags)
- tree declspecs, declarator, attrs;
- int flags;
+start_function (tree declspecs, tree declarator, tree attrs, int flags)
{
tree decl1;
tree ctype = NULL_TREE;
@@ -14284,8 +10102,6 @@ start_function (declspecs, declarator, attrs, flags)
else
doing_friend = 1;
}
-
- last_function_parms = DECL_ARGUMENTS (decl1);
}
else
{
@@ -14304,27 +10120,14 @@ start_function (declspecs, declarator, attrs, flags)
fntype = TREE_TYPE (decl1);
restype = TREE_TYPE (fntype);
- if (CLASS_TYPE_P (restype) && !CLASSTYPE_GOT_SEMICOLON (restype))
- {
- error ("semicolon missing after declaration of `%#T'", restype);
- shadow_tag (build_tree_list (NULL_TREE, restype));
- CLASSTYPE_GOT_SEMICOLON (restype) = 1;
- if (TREE_CODE (fntype) == FUNCTION_TYPE)
- fntype = build_function_type (integer_type_node,
- TYPE_ARG_TYPES (fntype));
- else
- fntype = build_cplus_method_type (build_type_variant (TYPE_METHOD_BASETYPE (fntype), TREE_READONLY (decl1), TREE_SIDE_EFFECTS (decl1)),
- integer_type_node,
- TYPE_ARG_TYPES (fntype));
- TREE_TYPE (decl1) = fntype;
- }
if (TREE_CODE (fntype) == METHOD_TYPE)
ctype = TYPE_METHOD_BASETYPE (fntype);
else if (DECL_MAIN_P (decl1))
{
- /* If this doesn't return integer_type, complain. */
- if (TREE_TYPE (TREE_TYPE (decl1)) != integer_type_node)
+ /* If this doesn't return integer_type, or a typedef to
+ integer_type, complain. */
+ if (!same_type_p (TREE_TYPE (TREE_TYPE (decl1)), integer_type_node))
{
if (pedantic || warn_return_type)
pedwarn ("return type for `main' changed to `int'");
@@ -14335,8 +10138,7 @@ start_function (declspecs, declarator, attrs, flags)
if (DECL_DECLARED_INLINE_P (decl1)
&& lookup_attribute ("noinline", attrs))
- warning_with_decl (decl1,
- "inline function `%s' given attribute noinline");
+ warning ("%Jinline function '%D' given attribute noinline", decl1, decl1);
if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1))
/* This is a constructor, we must ensure that any default args
@@ -14350,7 +10152,6 @@ start_function (declspecs, declarator, attrs, flags)
&& TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE)
{
revert_static_member_fn (decl1);
- last_function_parms = TREE_CHAIN (last_function_parms);
ctype = NULL_TREE;
}
@@ -14363,9 +10164,9 @@ start_function (declspecs, declarator, attrs, flags)
/* Set up current_class_type, and enter the scope of the class, if
appropriate. */
if (ctype)
- push_nested_class (ctype, 1);
+ push_nested_class (ctype);
else if (DECL_STATIC_FUNCTION_P (decl1))
- push_nested_class (DECL_CONTEXT (decl1), 2);
+ push_nested_class (DECL_CONTEXT (decl1));
/* Now that we have entered the scope of the class, we must restore
the bindings for any template parameters surrounding DECL1, if it
@@ -14403,7 +10204,7 @@ start_function (declspecs, declarator, attrs, flags)
/* Save the parm names or decls from this function's declarator
where store_parm_decls will find them. */
- current_function_parms = last_function_parms;
+ current_function_parms = DECL_ARGUMENTS (decl1);
/* Make sure the parameter and return types are reasonable. When
you declare a function, these types can be incomplete, but they
@@ -14430,7 +10231,7 @@ start_function (declspecs, declarator, attrs, flags)
CFUN set up, and our per-function variables initialized.
FIXME factor out the non-RTL stuff. */
bl = current_binding_level;
- init_function_start (decl1, input_filename, lineno);
+ allocate_struct_function (decl1);
current_binding_level = bl;
/* Even though we're inside a function body, we still don't want to
@@ -14452,9 +10253,22 @@ start_function (declspecs, declarator, attrs, flags)
if (!processing_template_decl && !(flags & SF_PRE_PARSED))
{
/* A specialization is not used to guide overload resolution. */
- if (!DECL_TEMPLATE_SPECIALIZATION (decl1)
- && ! DECL_FUNCTION_MEMBER_P (decl1))
- decl1 = pushdecl (decl1);
+ if (!DECL_FUNCTION_MEMBER_P (decl1)
+ && !(DECL_USE_TEMPLATE (decl1) &&
+ PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl1))))
+ {
+ tree olddecl = pushdecl (decl1);
+
+ if (olddecl == error_mark_node)
+ /* If something went wrong when registering the declaration,
+ use DECL1; we have to have a FUNCTION_DECL to use when
+ parsing the body of the function. */
+ ;
+ else
+ /* Otherwise, OLDDECL is either a previous declaration of
+ the same function or DECL1 itself. */
+ decl1 = olddecl;
+ }
else
{
/* We need to set the DECL_CONTEXT. */
@@ -14525,8 +10339,7 @@ start_function (declspecs, declarator, attrs, flags)
If it belongs to someone else's interface, it is also external.
This only affects inlines and template instantiations. */
else if (interface_unknown == 0
- && (! DECL_TEMPLATE_INSTANTIATION (decl1)
- || flag_alt_external_templates))
+ && ! DECL_TEMPLATE_INSTANTIATION (decl1))
{
if (DECL_DECLARED_INLINE_P (decl1)
|| DECL_TEMPLATE_INSTANTIATION (decl1)
@@ -14547,8 +10360,7 @@ start_function (declspecs, declarator, attrs, flags)
DECL_INTERFACE_KNOWN (decl1) = 1;
}
else if (interface_unknown && interface_only
- && (! DECL_TEMPLATE_INSTANTIATION (decl1)
- || flag_alt_external_templates))
+ && ! DECL_TEMPLATE_INSTANTIATION (decl1))
{
/* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma
interface, we will have interface_only set but not
@@ -14576,8 +10388,7 @@ start_function (declspecs, declarator, attrs, flags)
DECL_INTERFACE_KNOWN (decl1) = 1;
}
- pushlevel (0);
- current_binding_level->parm_flag = 1;
+ begin_scope (sk_function_parms, decl1);
++function_depth;
@@ -14601,11 +10412,10 @@ start_function (declspecs, declarator, attrs, flags)
Also install to binding contour return value identifier, if any. */
static void
-store_parm_decls (current_function_parms)
- tree current_function_parms;
+store_parm_decls (tree current_function_parms)
{
- register tree fndecl = current_function_decl;
- register tree parm;
+ tree fndecl = current_function_decl;
+ tree parm;
/* This is a chain of any other decls that came in among the parm
declarations. If a parm is declared with enum {foo, bar} x;
@@ -14624,7 +10434,7 @@ store_parm_decls (current_function_parms)
/* Must clear this because it might contain TYPE_DECLs declared
at class level. */
- storedecls (NULL_TREE);
+ current_binding_level->names = NULL;
/* If we're doing semantic analysis, then we'll call pushdecl
for each of these. We must do them in reverse order so that
@@ -14663,7 +10473,7 @@ store_parm_decls (current_function_parms)
as the decl-chain of the current lexical scope.
Put the enumerators in as well, at the front so that
DECL_ARGUMENTS is not modified. */
- storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl)));
+ current_binding_level->names = chainon (nonparms, DECL_ARGUMENTS (fndecl));
/* Do the starting of the exception specifications, if we have any. */
if (flag_exceptions && !processing_template_decl
@@ -14678,8 +10488,7 @@ store_parm_decls (current_function_parms)
when we want to generate RTL later we know what to do. */
static void
-save_function_data (decl)
- tree decl;
+save_function_data (tree decl)
{
struct language_function *f;
@@ -14689,8 +10498,7 @@ save_function_data (decl)
19990908);
/* Make a copy. */
- f = ((struct language_function *)
- ggc_alloc (sizeof (struct language_function)));
+ f = ggc_alloc (sizeof (struct language_function));
memcpy (f, cp_function_chain, sizeof (struct language_function));
DECL_SAVED_FUNCTION_DATA (decl) = f;
@@ -14701,9 +10509,6 @@ save_function_data (decl)
f->bindings = NULL;
f->x_local_names = NULL;
- /* When we get back here again, we will be expanding. */
- f->x_expanding_p = 1;
-
/* If we've already decided that we cannot inline this function, we
must remember that fact when we actually go to expand the
function. */
@@ -14719,7 +10524,7 @@ save_function_data (decl)
fully-constructed bases and members. */
static void
-begin_constructor_body ()
+begin_constructor_body (void)
{
}
@@ -14728,7 +10533,7 @@ begin_constructor_body ()
members. */
static void
-finish_constructor_body ()
+finish_constructor_body (void)
{
}
@@ -14736,7 +10541,7 @@ finish_constructor_body ()
vtable pointers and cleanups for bases and members. */
static void
-begin_destructor_body ()
+begin_destructor_body (void)
{
tree if_stmt;
tree compound_stmt;
@@ -14763,14 +10568,14 @@ begin_destructor_body ()
initialize the vtables.) */
finish_if_stmt_cond (boolean_true_node, if_stmt);
- compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
+ compound_stmt = begin_compound_stmt (/*has_no_scope=*/false);
/* Make all virtual function table pointers in non-virtual base
classes point to CURRENT_CLASS_TYPE's virtual function
tables. */
initialize_vtbl_ptrs (current_class_ptr);
- finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
+ finish_compound_stmt (compound_stmt);
finish_then_clause (if_stmt);
finish_if_stmt ();
@@ -14783,7 +10588,7 @@ begin_destructor_body ()
necessary. Do that now. */
static void
-finish_destructor_body ()
+finish_destructor_body (void)
{
tree exprstmt;
@@ -14825,7 +10630,7 @@ finish_destructor_body ()
In other functions, this isn't necessary, but it doesn't hurt. */
tree
-begin_function_body ()
+begin_function_body (void)
{
tree stmt;
@@ -14835,9 +10640,9 @@ begin_function_body ()
/* Always keep the BLOCK node associated with the outermost pair of
curly braces of a function. These are needed for correct
operation of dwarfout.c. */
- keep_next_level (1);
+ keep_next_level (true);
- stmt = begin_compound_stmt (0);
+ stmt = begin_compound_stmt (/*has_no_scope=*/false);
COMPOUND_STMT_BODY_BLOCK (stmt) = 1;
if (processing_template_decl)
@@ -14860,11 +10665,10 @@ begin_function_body ()
main() would also need to return 0. */
void
-finish_function_body (compstmt)
- tree compstmt;
+finish_function_body (tree compstmt)
{
/* Close the block. */
- finish_compound_stmt (0, compstmt);
+ finish_compound_stmt (compstmt);
if (processing_template_decl)
/* Do nothing now. */;
@@ -14885,10 +10689,9 @@ finish_function_body (compstmt)
after the class definition is complete.) */
tree
-finish_function (flags)
- int flags;
+finish_function (int flags)
{
- register tree fndecl = current_function_decl;
+ tree fndecl = current_function_decl;
tree fntype, ctype = NULL_TREE;
int inclass_inline = (flags & 2) != 0;
int nested;
@@ -14915,8 +10718,6 @@ finish_function (flags)
which then got a warning when stored in a ptr-to-function variable. */
my_friendly_assert (building_stmt_tree (), 20000911);
-
- finish_fname_decls ();
/* For a cloned function, we've already got all the code we need;
there's no need to add any extra bits. */
@@ -14941,6 +10742,8 @@ finish_function (flags)
current_eh_spec_block);
}
+ finish_fname_decls ();
+
/* If we're saving up tree structure, tie off the function now. */
finish_stmt_tree (&DECL_SAVED_TREE (fndecl));
@@ -14957,7 +10760,7 @@ finish_function (flags)
/* If the current binding level isn't the outermost binding level
for this function, either there is a bug, or we have experienced
syntax errors and the statement tree is malformed. */
- if (current_binding_level->parm_flag != 1)
+ if (current_binding_level->kind != sk_function_parms)
{
/* Make sure we have already experienced errors. */
if (errorcount == 0)
@@ -14967,9 +10770,9 @@ finish_function (flags)
levels. */
DECL_SAVED_TREE (fndecl) = build_stmt (COMPOUND_STMT, NULL_TREE);
- while (current_binding_level->parm_flag != 1)
+ while (current_binding_level->kind != sk_function_parms)
{
- if (current_binding_level->parm_flag == 2)
+ if (current_binding_level->kind == sk_class)
pop_nested_class ();
else
poplevel (0, 0, 0);
@@ -14977,6 +10780,10 @@ finish_function (flags)
}
poplevel (1, 0, 1);
+ /* Statements should always be full-expressions at the outermost set
+ of curly braces for a function. */
+ my_friendly_assert (stmts_are_full_exprs_p (), 19990831);
+
/* Set up the named return value optimization, if we can. Here, we
eliminate the copy from the nrv into the RESULT_DECL and any cleanup
for the nrv. genrtl_start_function and declare_return_variable
@@ -14989,12 +10796,13 @@ finish_function (flags)
if (r != error_mark_node
/* This is only worth doing for fns that return in memory--and
simpler, since we don't have to worry about promoted modes. */
- && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)))
+ && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)), fndecl)
/* Only allow this for variables declared in the outer scope of
the function so we know that their lifetime always ends with a
return; see g++.dg/opt/nrv6.C. We could be more flexible if
we were to do this optimization in tree-ssa. */
- && (outer = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl)),
+ /* Skip the artificial function body block. */
+ && (outer = BLOCK_SUBBLOCKS (BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl))),
chain_member (r, BLOCK_VARS (outer))))
{
@@ -15037,23 +10845,21 @@ finish_function (flags)
/* Complain if there's just no return statement. */
if (warn_return_type
- && !processing_template_decl
&& TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE
+ && !dependent_type_p (TREE_TYPE (fntype))
&& !current_function_returns_value && !current_function_returns_null
/* Don't complain if we abort or throw. */
&& !current_function_returns_abnormally
&& !DECL_NAME (DECL_RESULT (fndecl))
/* Normally, with -Wreturn-type, flow will complain. Unless we're an
inline function, as we might never be compiled separately. */
- && DECL_INLINE (fndecl))
+ && (DECL_INLINE (fndecl) || processing_template_decl))
warning ("no return statement in function returning non-void");
-
- /* Clear out memory we no longer need. */
- free_after_parsing (cfun);
- /* Since we never call rest_of_compilation, we never clear
- CFUN. Do so explicitly. */
- free_after_compilation (cfun);
+
+ /* We're leaving the context of this function, so zap cfun. It's still in
+ DECL_SAVED_INSNS, and we'll restore it in tree_rest_of_compilation. */
cfun = NULL;
+ current_function_decl = NULL;
/* If this is an in-class inline definition, we may have to pop the
bindings for the template parameters that we added in
@@ -15100,15 +10906,19 @@ finish_function (flags)
CHANGES TO CODE IN `grokfield'. */
tree
-start_method (declspecs, declarator, attrlist)
- tree declarator, declspecs, attrlist;
+start_method (tree declspecs, tree declarator, tree attrlist)
{
tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
&attrlist);
- /* Something too ugly to handle. */
- if (fndecl == NULL_TREE)
- return NULL_TREE;
+ if (fndecl == error_mark_node)
+ return error_mark_node;
+
+ if (fndecl == NULL || TREE_CODE (fndecl) != FUNCTION_DECL)
+ {
+ error ("invalid member function declaration");
+ return error_mark_node;
+ }
if (attrlist)
cplus_decl_attributes (&fndecl, attrlist, 0);
@@ -15117,10 +10927,6 @@ start_method (declspecs, declarator, attrlist)
if (fndecl == void_type_node)
return fndecl;
- if (TREE_CODE (fndecl) != FUNCTION_DECL)
- /* Not a function, tell parser to report parse error. */
- return NULL_TREE;
-
if (DECL_IN_AGGR_P (fndecl))
{
if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (fndecl)) != current_class_type)
@@ -15136,14 +10942,16 @@ start_method (declspecs, declarator, attrlist)
check_template_shadow (fndecl);
DECL_DECLARED_INLINE_P (fndecl) = 1;
-
- DID_INLINE_FUNC (fndecl) = 0;
if (flag_default_inline)
DECL_INLINE (fndecl) = 1;
/* We process method specializations in finish_struct_1. */
if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl))
- fndecl = push_template_decl (fndecl);
+ {
+ fndecl = push_template_decl (fndecl);
+ if (fndecl == error_mark_node)
+ return fndecl;
+ }
if (! DECL_FRIEND_P (fndecl))
{
@@ -15157,9 +10965,8 @@ start_method (declspecs, declarator, attrlist)
cp_finish_decl (fndecl, NULL_TREE, NULL_TREE, 0);
- /* Make a place for the parms */
- pushlevel (0);
- current_binding_level->parm_flag = 1;
+ /* Make a place for the parms. */
+ begin_scope (sk_function_parms, fndecl);
DECL_IN_AGGR_P (fndecl) = 1;
return fndecl;
@@ -15178,13 +10985,12 @@ start_method (declspecs, declarator, attrlist)
DECL is the ..._DECL that `start_method' provided. */
tree
-finish_method (decl)
- tree decl;
+finish_method (tree decl)
{
- register tree fndecl = decl;
+ tree fndecl = decl;
tree old_initial;
- register tree link;
+ tree link;
if (decl == void_type_node)
return decl;
@@ -15231,8 +11037,7 @@ finish_method (decl)
we can lay it out later, when and if its type becomes complete. */
void
-maybe_register_incomplete_var (var)
- tree var;
+maybe_register_incomplete_var (tree var)
{
my_friendly_assert (TREE_CODE (var) == VAR_DECL, 20020406);
@@ -15259,8 +11064,7 @@ maybe_register_incomplete_var (var)
declaration, update them now. */
void
-complete_vars (type)
- tree type;
+complete_vars (tree type)
{
tree *list = &incomplete_vars;
@@ -15285,8 +11089,7 @@ complete_vars (type)
here. */
tree
-cxx_maybe_build_cleanup (decl)
- tree decl;
+cxx_maybe_build_cleanup (tree decl)
{
tree type = TREE_TYPE (decl);
@@ -15313,8 +11116,7 @@ cxx_maybe_build_cleanup (decl)
if (TYPE_USES_VIRTUAL_BASECLASSES (type)
&& ! TYPE_HAS_DESTRUCTOR (type))
- rval = build_compound_expr (tree_cons (NULL_TREE, rval,
- build_tree_list (NULL_TREE, build_vbase_delete (type, decl))));
+ rval = build_compound_expr (rval, build_vbase_delete (type, decl));
return rval;
}
@@ -15324,7 +11126,7 @@ cxx_maybe_build_cleanup (decl)
/* When a stmt has been parsed, this function is called. */
void
-finish_stmt ()
+finish_stmt (void)
{
/* Always assume this statement was not an expression statement. If
it actually was an expression statement, its our callers
@@ -15336,8 +11138,7 @@ finish_stmt ()
but turned out to be static. Update it accordingly. */
void
-revert_static_member_fn (decl)
- tree decl;
+revert_static_member_fn (tree decl)
{
tree tmp;
tree function = TREE_TYPE (decl);
@@ -15363,29 +11164,45 @@ revert_static_member_fn (decl)
function. */
void
-cxx_push_function_context (f)
- struct function *f;
+cxx_push_function_context (struct function * f)
{
struct language_function *p
- = ((struct language_function *)
- ggc_alloc_cleared (sizeof (struct language_function)));
+ = ggc_alloc_cleared (sizeof (struct language_function));
f->language = p;
- /* It takes an explicit call to expand_body to generate RTL for a
- function. */
- expanding_p = 0;
-
/* Whenever we start a new function, we destroy temporaries in the
usual way. */
current_stmt_tree ()->stmts_are_full_exprs_p = 1;
+
+ if (f->decl)
+ {
+ tree fn = f->decl;
+
+ if (DECL_SAVED_FUNCTION_DATA (fn))
+ {
+ /* If we already parsed this function, and we're just expanding it
+ now, restore saved state. */
+ *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (fn);
+
+ /* If we decided that we didn't want to inline this function,
+ make sure the back-end knows that. */
+ if (!current_function_cannot_inline)
+ current_function_cannot_inline = cp_function_chain->cannot_inline;
+
+ /* We don't need the saved data anymore. Unless this is an inline
+ function; we need the named return value info for
+ cp_copy_res_decl_for_inlining. */
+ if (! DECL_INLINE (fn))
+ DECL_SAVED_FUNCTION_DATA (fn) = NULL;
+ }
+ }
}
/* Free the language-specific parts of F, now that we've finished
compiling the function. */
void
-cxx_pop_function_context (f)
- struct function *f;
+cxx_pop_function_context (struct function * f)
{
f->language = 0;
}
@@ -15394,35 +11211,24 @@ cxx_pop_function_context (f)
one of the language-independent trees. */
enum cp_tree_node_structure_enum
-cp_tree_node_structure (t)
- union lang_tree_node *t;
+cp_tree_node_structure (union lang_tree_node * t)
{
switch (TREE_CODE (&t->generic))
{
- case DEFAULT_ARG: return TS_CP_IDENTIFIER;
+ case DEFAULT_ARG: return TS_CP_DEFAULT_ARG;
case IDENTIFIER_NODE: return TS_CP_IDENTIFIER;
case OVERLOAD: return TS_CP_OVERLOAD;
case TEMPLATE_PARM_INDEX: return TS_CP_TPI;
case PTRMEM_CST: return TS_CP_PTRMEM;
+ case BASELINK: return TS_CP_BASELINK;
case WRAPPER: return TS_CP_WRAPPER;
- case SRCLOC: return TS_CP_SRCLOC;
default: return TS_CP_GENERIC;
}
}
-/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
- the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++. */
-
-tree
-identifier_global_value (t)
- tree t;
-{
- return IDENTIFIER_GLOBAL_VALUE (t);
-}
-
/* Build the void_list_node (void_type_node having been created). */
tree
-build_void_list_node ()
+build_void_list_node (void)
{
tree t = build_tree_list (NULL_TREE, void_type_node);
TREE_PARMLIST (t) = 1;
@@ -15430,8 +11236,7 @@ build_void_list_node ()
}
static int
-cp_missing_noreturn_ok_p (decl)
- tree decl;
+cp_missing_noreturn_ok_p (tree decl)
{
/* A missing noreturn is ok for the `main' function. */
return DECL_MAIN_P (decl);
diff --git a/contrib/gcc/cp/decl.h b/contrib/gcc/cp/decl.h
index 2b917a4d5e23..46a1ec806886 100644
--- a/contrib/gcc/cp/decl.h
+++ b/contrib/gcc/cp/decl.h
@@ -1,20 +1,20 @@
/* Variables and structures for declaration processing.
Copyright (C) 1993, 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -31,12 +31,7 @@ enum decl_context
};
/* We need this in here to get the decl_context definition. */
-extern tree grokdeclarator PARAMS ((tree, tree, enum decl_context, int,
- tree *));
-
-/* Parsing a function declarator leaves a list of parameter names
- or a chain or parameter decls here. */
-extern GTY(()) tree last_function_parms;
+extern tree grokdeclarator (tree, tree, enum decl_context, int, tree*);
#ifdef DEBUG_CP_BINDING_LEVELS
/* Purely for debugging purposes. */
diff --git a/contrib/gcc/cp/decl2.c b/contrib/gcc/cp/decl2.c
index 55613700d3bc..4e8c2f82b215 100644
--- a/contrib/gcc/cp/decl2.c
+++ b/contrib/gcc/cp/decl2.c
@@ -1,27 +1,27 @@
-/* Process declarations and variables for C compiler.
+/* Process declarations and variables for C++ compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Process declarations and symbol lookup for C front end.
+/* Process declarations and symbol lookup for C++ front end.
Also constructs types; the standard scalar types at initialization,
and structure, union, array and enum types when they are declared. */
@@ -30,6 +30,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "expr.h"
@@ -40,12 +42,12 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "except.h"
#include "toplev.h"
-#include "ggc.h"
#include "timevar.h"
#include "cpplib.h"
#include "target.h"
#include "c-common.h"
-#include "timevar.h"
+#include "cgraph.h"
+#include "tree-inline.h"
extern cpp_reader *parse_in;
/* This structure contains information about the initializations
@@ -59,35 +61,27 @@ typedef struct priority_info_s {
int destructions_p;
} *priority_info;
-static void mark_vtable_entries PARAMS ((tree));
-static void grok_function_init PARAMS ((tree, tree));
-static int maybe_emit_vtables (tree);
-static void add_using_namespace PARAMS ((tree, tree, int));
-static cxx_binding *ambiguous_decl (tree, cxx_binding *, cxx_binding *,int);
-static tree build_anon_union_vars PARAMS ((tree, tree*, int, int));
-static int acceptable_java_type PARAMS ((tree));
-static void output_vtable_inherit PARAMS ((tree));
-static tree start_objects PARAMS ((int, int));
-static void finish_objects PARAMS ((int, int, tree));
-static tree merge_functions PARAMS ((tree, tree));
-static tree decl_namespace PARAMS ((tree));
-static tree validate_nonmember_using_decl PARAMS ((tree, tree *, tree *));
-static void do_nonmember_using_decl PARAMS ((tree, tree, tree, tree,
- tree *, tree *));
-static tree start_static_storage_duration_function PARAMS ((void));
-static void finish_static_storage_duration_function PARAMS ((tree));
-static priority_info get_priority_info PARAMS ((int));
-static void do_static_initialization PARAMS ((tree, tree));
-static void do_static_destruction PARAMS ((tree));
-static tree start_static_initialization_or_destruction PARAMS ((tree, int));
-static void finish_static_initialization_or_destruction PARAMS ((tree));
-static void generate_ctor_or_dtor_function PARAMS ((int, int));
-static int generate_ctor_and_dtor_functions_for_priority
- PARAMS ((splay_tree_node, void *));
-static tree prune_vars_needing_no_initialization PARAMS ((tree *));
-static void write_out_vars PARAMS ((tree));
-static void import_export_class PARAMS ((tree));
-static tree get_guard_bits PARAMS ((tree));
+static void mark_vtable_entries (tree);
+static void grok_function_init (tree, tree);
+static bool maybe_emit_vtables (tree);
+static tree build_anon_union_vars (tree);
+static bool acceptable_java_type (tree);
+static tree start_objects (int, int);
+static void finish_objects (int, int, tree);
+static tree start_static_storage_duration_function (unsigned);
+static void finish_static_storage_duration_function (tree);
+static priority_info get_priority_info (int);
+static void do_static_initialization (tree, tree);
+static void do_static_destruction (tree);
+static tree start_static_initialization_or_destruction (tree, int);
+static void finish_static_initialization_or_destruction (tree);
+static void generate_ctor_or_dtor_function (bool, int, location_t *);
+static int generate_ctor_and_dtor_functions_for_priority (splay_tree_node,
+ void *);
+static tree prune_vars_needing_no_initialization (tree *);
+static void write_out_vars (tree);
+static void import_export_class (tree);
+static tree get_guard_bits (tree);
/* A list of static class variables. This is needed, because a
static class variable can be declared inside the class without
@@ -115,9 +109,6 @@ int at_eof;
tree static_ctors;
tree static_dtors;
-/* The :: namespace. */
-
-tree global_namespace;
/* Incorporate `const' and `volatile' qualifiers for member functions.
FUNCTION is a TYPE_DECL or a FUNCTION_DECL.
@@ -126,8 +117,7 @@ tree global_namespace;
TYPE_UNQUALIFIED will be an extension. */
int
-grok_method_quals (ctype, function, quals)
- tree ctype, function, quals;
+grok_method_quals (tree ctype, tree function, tree quals)
{
tree fntype = TREE_TYPE (function);
tree raises = TYPE_RAISES_EXCEPTIONS (fntype);
@@ -155,10 +145,10 @@ grok_method_quals (ctype, function, quals)
? "member function" : "type");
ctype = cp_build_qualified_type (ctype, type_quals);
- fntype = build_cplus_method_type (ctype, TREE_TYPE (fntype),
- (TREE_CODE (fntype) == METHOD_TYPE
- ? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
- : TYPE_ARG_TYPES (fntype)));
+ fntype = build_method_type_directly (ctype, TREE_TYPE (fntype),
+ (TREE_CODE (fntype) == METHOD_TYPE
+ ? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
+ : TYPE_ARG_TYPES (fntype)));
if (raises)
fntype = build_exception_variant (fntype, raises);
@@ -166,44 +156,10 @@ grok_method_quals (ctype, function, quals)
return this_quals;
}
-/* Warn when -fexternal-templates is used and #pragma
- interface/implementation is not used all the times it should be,
- inform the user. */
-
-void
-warn_if_unknown_interface (decl)
- tree decl;
-{
- static int already_warned = 0;
- if (already_warned++)
- return;
-
- if (flag_alt_external_templates)
- {
- tree til = tinst_for_decl ();
- int sl = lineno;
- const char *sf = input_filename;
-
- if (til)
- {
- lineno = TINST_LINE (til);
- input_filename = TINST_FILE (til);
- }
- warning ("template `%#D' instantiated in file without #pragma interface",
- decl);
- lineno = sl;
- input_filename = sf;
- }
- else
- cp_warning_at ("template `%#D' defined in file without #pragma interface",
- decl);
-}
-
/* A subroutine of the parser, to handle a component list. */
void
-grok_x_components (specs)
- tree specs;
+grok_x_components (tree specs)
{
tree t;
@@ -225,12 +181,13 @@ grok_x_components (specs)
appropriately. */
tree
-cp_build_parm_decl (name, type)
- tree name;
- tree type;
+cp_build_parm_decl (tree name, tree type)
{
tree parm = build_decl (PARM_DECL, name, type);
- DECL_ARG_TYPE (parm) = type_passed_as (type);
+ /* DECL_ARG_TYPE is only used by the back end and the back end never
+ sees templates. */
+ if (!processing_template_decl)
+ DECL_ARG_TYPE (parm) = type_passed_as (type);
return parm;
}
@@ -238,9 +195,7 @@ cp_build_parm_decl (name, type)
indicated NAME. */
tree
-build_artificial_parm (name, type)
- tree name;
- tree type;
+build_artificial_parm (tree name, tree type)
{
tree parm = cp_build_parm_decl (name, type);
DECL_ARTIFICIAL (parm) = 1;
@@ -264,8 +219,7 @@ build_artificial_parm (name, type)
VTT parm (if any), then the user-written parms. */
void
-maybe_retrofit_in_chrg (fn)
- tree fn;
+maybe_retrofit_in_chrg (tree fn)
{
tree basetype, arg_types, parms, parm, fntype;
@@ -275,7 +229,7 @@ maybe_retrofit_in_chrg (fn)
/* When processing templates we can't know, in general, whether or
not we're going to have virtual baseclasses. */
- if (uses_template_parms (fn))
+ if (processing_template_decl)
return;
/* We don't need an in-charge parameter for constructors that don't
@@ -316,8 +270,8 @@ maybe_retrofit_in_chrg (fn)
TREE_CHAIN (DECL_ARGUMENTS (fn)) = parms;
/* And rebuild the function type. */
- fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)),
- arg_types);
+ fntype = build_method_type_directly (basetype, TREE_TYPE (TREE_TYPE (fn)),
+ arg_types);
if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)))
fntype = build_exception_variant (fntype,
TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)));
@@ -348,10 +302,7 @@ maybe_retrofit_in_chrg (fn)
QUALS are the qualifiers for the this pointer. */
void
-grokclassfn (ctype, function, flags, quals)
- tree ctype, function;
- enum overload_flags flags;
- tree quals;
+grokclassfn (tree ctype, tree function, enum overload_flags flags, tree quals)
{
tree fn_name = DECL_NAME (function);
int this_quals = TYPE_UNQUALIFIED;
@@ -385,11 +336,10 @@ grokclassfn (ctype, function, flags, quals)
qual_type = cp_build_qualified_type (type, this_quals);
parm = build_artificial_parm (this_identifier, qual_type);
c_apply_type_quals_to_decl (this_quals, parm);
- TREE_CHAIN (parm) = last_function_parms;
- last_function_parms = parm;
+ TREE_CHAIN (parm) = DECL_ARGUMENTS (function);
+ DECL_ARGUMENTS (function) = parm;
}
- DECL_ARGUMENTS (function) = last_function_parms;
DECL_CONTEXT (function) = ctype;
if (flags == DTOR_FLAG)
@@ -397,101 +347,99 @@ grokclassfn (ctype, function, flags, quals)
if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function))
maybe_retrofit_in_chrg (function);
-
- if (flags == DTOR_FLAG)
- {
- DECL_DESTRUCTOR_P (function) = 1;
- TYPE_HAS_DESTRUCTOR (ctype) = 1;
- }
}
/* Create an ARRAY_REF, checking for the user doing things backwards
along the way. */
tree
-grok_array_decl (array_expr, index_exp)
- tree array_expr, index_exp;
+grok_array_decl (tree array_expr, tree index_exp)
{
- tree type = TREE_TYPE (array_expr);
- tree p1, p2, i1, i2;
+ tree type;
+ tree expr;
+ tree orig_array_expr = array_expr;
+ tree orig_index_exp = index_exp;
- if (type == error_mark_node || index_exp == error_mark_node)
+ if (error_operand_p (array_expr) || error_operand_p (index_exp))
return error_mark_node;
- if (processing_template_decl)
- return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE,
- array_expr, index_exp);
- if (type == NULL_TREE)
+ if (processing_template_decl)
{
- /* Something has gone very wrong. Assume we are mistakenly reducing
- an expression instead of a declaration. */
- error ("parser may be lost: is there a '{' missing somewhere?");
- return NULL_TREE;
+ if (type_dependent_expression_p (array_expr)
+ || type_dependent_expression_p (index_exp))
+ return build_min_nt (ARRAY_REF, array_expr, index_exp);
+ array_expr = build_non_dependent_expr (array_expr);
+ index_exp = build_non_dependent_expr (index_exp);
}
- if (TREE_CODE (type) == OFFSET_TYPE
- || TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
+ type = TREE_TYPE (array_expr);
+ my_friendly_assert (type, 20030626);
+ type = non_reference (type);
/* If they have an `operator[]', use that. */
if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp)))
- return build_opfncall (ARRAY_REF, LOOKUP_NORMAL,
- array_expr, index_exp, NULL_TREE);
-
- /* Otherwise, create an ARRAY_REF for a pointer or array type. It
- is a little-known fact that, if `a' is an array and `i' is an
- int, you can write `i[a]', which means the same thing as `a[i]'. */
-
- if (TREE_CODE (type) == ARRAY_TYPE)
- p1 = array_expr;
+ expr = build_new_op (ARRAY_REF, LOOKUP_NORMAL,
+ array_expr, index_exp, NULL_TREE,
+ /*overloaded_p=*/NULL);
else
- p1 = build_expr_type_conversion (WANT_POINTER, array_expr, 0);
+ {
+ tree p1, p2, i1, i2;
- if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE)
- p2 = index_exp;
- else
- p2 = build_expr_type_conversion (WANT_POINTER, index_exp, 0);
+ /* Otherwise, create an ARRAY_REF for a pointer or array type.
+ It is a little-known fact that, if `a' is an array and `i' is
+ an int, you can write `i[a]', which means the same thing as
+ `a[i]'. */
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ p1 = array_expr;
+ else
+ p1 = build_expr_type_conversion (WANT_POINTER, array_expr, false);
- i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr, 0);
- i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp, 0);
+ if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE)
+ p2 = index_exp;
+ else
+ p2 = build_expr_type_conversion (WANT_POINTER, index_exp, false);
- if ((p1 && i2) && (i1 && p2))
- error ("ambiguous conversion for array subscript");
+ i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr,
+ false);
+ i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp,
+ false);
- if (p1 && i2)
- array_expr = p1, index_exp = i2;
- else if (i1 && p2)
- array_expr = p2, index_exp = i1;
- else
- {
- error ("invalid types `%T[%T]' for array subscript",
- type, TREE_TYPE (index_exp));
- return error_mark_node;
- }
+ if ((p1 && i2) && (i1 && p2))
+ error ("ambiguous conversion for array subscript");
+
+ if (p1 && i2)
+ array_expr = p1, index_exp = i2;
+ else if (i1 && p2)
+ array_expr = p2, index_exp = i1;
+ else
+ {
+ error ("invalid types `%T[%T]' for array subscript",
+ type, TREE_TYPE (index_exp));
+ return error_mark_node;
+ }
- if (array_expr == error_mark_node || index_exp == error_mark_node)
- error ("ambiguous conversion for array subscript");
+ if (array_expr == error_mark_node || index_exp == error_mark_node)
+ error ("ambiguous conversion for array subscript");
- return build_array_ref (array_expr, index_exp);
+ expr = build_array_ref (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);
+ return expr;
}
/* Given the cast expression EXP, checking out its validity. Either return
an error_mark_node if there was an unavoidable error, return a cast to
void for trying to delete a pointer w/ the value 0, or return the
- call to delete. If DOING_VEC is 1, we handle things differently
- for doing an array delete. If DOING_VEC is 2, they gave us the
- array size as an argument to delete.
+ call to delete. If DOING_VEC is true, we handle things differently
+ for doing an array delete.
Implements ARM $5.3.4. This is called from the parser. */
tree
-delete_sanity (exp, size, doing_vec, use_global_delete)
- tree exp, size;
- int doing_vec, use_global_delete;
+delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete)
{
tree t, type;
- /* For a regular vector delete (aka, no size argument) we will pass
- this down as a NULL_TREE into build_vec_delete. */
- tree maxindex = NULL_TREE;
if (exp == error_mark_node)
return exp;
@@ -501,14 +449,18 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
t = build_min (DELETE_EXPR, void_type_node, exp, size);
DELETE_EXPR_USE_GLOBAL (t) = use_global_delete;
DELETE_EXPR_USE_VEC (t) = doing_vec;
+ TREE_SIDE_EFFECTS (t) = 1;
return t;
}
- if (TREE_CODE (exp) == OFFSET_REF)
- exp = resolve_offset_ref (exp);
exp = convert_from_reference (exp);
- t = stabilize_reference (exp);
- t = build_expr_type_conversion (WANT_POINTER, t, 1);
+
+ /* An array can't have been allocated by new, so complain. */
+ if (TREE_CODE (exp) == VAR_DECL
+ && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+ warning ("deleting array `%#D'", exp);
+
+ t = build_expr_type_conversion (WANT_POINTER, exp, true);
if (t == NULL_TREE || t == error_mark_node)
{
@@ -517,12 +469,6 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
return error_mark_node;
}
- if (doing_vec == 2)
- {
- maxindex = cp_build_binary_op (MINUS_EXPR, size, integer_one_node);
- pedwarn ("anachronistic use of array size in vector delete");
- }
-
type = TREE_TYPE (t);
/* As of Valley Forge, you can delete a pointer to const. */
@@ -541,18 +487,13 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
doing_vec = 0;
}
- /* An array can't have been allocated by new, so complain. */
- if (TREE_CODE (t) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == ARRAY_TYPE)
- warning ("deleting array `%#D'", TREE_OPERAND (t, 0));
-
/* Deleting a pointer with the value zero is valid and has no effect. */
if (integer_zerop (t))
return build1 (NOP_EXPR, void_type_node, t);
if (doing_vec)
- return build_vec_delete (t, maxindex, sfk_deleting_destructor,
+ return build_vec_delete (t, /*maxindex=*/NULL_TREE,
+ sfk_deleting_destructor,
use_global_delete);
else
return build_delete (type, t, sfk_deleting_destructor,
@@ -563,8 +504,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
sort of thing that should be a member template. */
void
-check_member_template (tmpl)
- tree tmpl;
+check_member_template (tree tmpl)
{
tree decl;
@@ -603,9 +543,8 @@ check_member_template (tmpl)
/* Return true iff TYPE is a valid Java parameter or return type. */
-static int
-acceptable_java_type (type)
- tree type;
+static bool
+acceptable_java_type (tree type)
{
if (TREE_CODE (type) == VOID_TYPE || TYPE_FOR_JAVA (type))
return 1;
@@ -616,9 +555,9 @@ acceptable_java_type (type)
{
tree args; int i;
if (! TYPE_FOR_JAVA (type))
- return 0;
+ return false;
if (! CLASSTYPE_TEMPLATE_INFO (type))
- return 1;
+ return true;
args = CLASSTYPE_TI_ARGS (type);
i = TREE_VEC_LENGTH (args);
while (--i >= 0)
@@ -627,51 +566,59 @@ acceptable_java_type (type)
if (TREE_CODE (type) == POINTER_TYPE)
type = TREE_TYPE (type);
if (! TYPE_FOR_JAVA (type))
- return 0;
+ return false;
}
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-/* For a METHOD in a Java class CTYPE, return 1 if
+/* For a METHOD in a Java class CTYPE, return true if
the parameter and return types are valid Java types.
- Otherwise, print appropriate error messages, and return 0. */
+ Otherwise, print appropriate error messages, and return false. */
-int
-check_java_method (method)
- tree method;
+bool
+check_java_method (tree method)
{
- int jerr = 0;
+ bool jerr = false;
tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));
tree ret_type = TREE_TYPE (TREE_TYPE (method));
- if (! acceptable_java_type (ret_type))
+
+ if (!acceptable_java_type (ret_type))
{
error ("Java method '%D' has non-Java return type `%T'",
method, ret_type);
- jerr++;
+ jerr = true;
}
+
+ arg_types = TREE_CHAIN (arg_types);
+ if (DECL_HAS_IN_CHARGE_PARM_P (method))
+ arg_types = TREE_CHAIN (arg_types);
+ if (DECL_HAS_VTT_PARM_P (method))
+ arg_types = TREE_CHAIN (arg_types);
+
for (; arg_types != NULL_TREE; arg_types = TREE_CHAIN (arg_types))
{
tree type = TREE_VALUE (arg_types);
- if (! acceptable_java_type (type))
+ if (!acceptable_java_type (type))
{
error ("Java method '%D' has non-Java parameter type `%T'",
method, type);
- jerr++;
+ jerr = true;
}
}
- return jerr ? 0 : 1;
+ return !jerr;
}
/* Sanity check: report error if this function FUNCTION is not
really a member of the class (CTYPE) it is supposed to belong to.
- CNAME is the same here as it is for grokclassfn above. */
+ CNAME is the same here as it is for grokclassfn above.
+ TEMPLATE_HEADER_P is true when this declaration comes with a
+ template header. */
tree
-check_classfn (ctype, function)
- tree ctype, function;
+check_classfn (tree ctype, tree function, bool template_header_p)
{
int ix;
int is_template;
@@ -694,7 +641,7 @@ check_classfn (ctype, function)
/* OK, is this a definition of a member template? */
is_template = (TREE_CODE (function) == TEMPLATE_DECL
- || (processing_template_decl - template_class_depth (ctype)));
+ || template_header_p);
ix = lookup_fnfields_1 (complete_type (ctype),
DECL_CONSTRUCTOR_P (function) ? ctor_identifier :
@@ -706,8 +653,10 @@ check_classfn (ctype, function)
tree methods = CLASSTYPE_METHOD_VEC (ctype);
tree fndecls, fndecl = 0;
bool is_conv_op;
+ bool pop_p;
const char *format = NULL;
+ pop_p = push_scope (ctype);
for (fndecls = TREE_VEC_ELT (methods, ix);
fndecls; fndecls = OVL_NEXT (fndecls))
{
@@ -741,8 +690,12 @@ check_classfn (ctype, function)
&& (!DECL_TEMPLATE_SPECIALIZATION (function)
|| (DECL_TI_TEMPLATE (function)
== DECL_TI_TEMPLATE (fndecl))))
- return fndecl;
+ break;
}
+ if (pop_p)
+ pop_scope (ctype);
+ if (fndecls)
+ return OVL_CURRENT (fndecls);
error ("prototype for `%#D' does not match any in class `%T'",
function, ctype);
is_conv_op = DECL_CONV_FN_P (fndecl);
@@ -800,11 +753,8 @@ check_classfn (ctype, function)
FLAGS is as for cp_finish_decl. */
void
-finish_static_data_member_decl (decl, init, asmspec_tree, flags)
- tree decl;
- tree init;
- tree asmspec_tree;
- int flags;
+finish_static_data_member_decl (tree decl, tree init, tree asmspec_tree,
+ int flags)
{
my_friendly_assert (TREE_PUBLIC (decl), 0);
@@ -870,42 +820,13 @@ finish_static_data_member_decl (decl, init, asmspec_tree, flags)
CHANGES TO CODE IN `start_method'. */
tree
-grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
- tree declarator, declspecs, init, asmspec_tree, attrlist;
+grokfield (tree declarator, tree declspecs, tree init, tree asmspec_tree,
+ tree attrlist)
{
tree value;
const char *asmspec = 0;
int flags = LOOKUP_ONLYCONVERTING;
- /* Convert () initializers to = initializers. */
- if (init == NULL_TREE && declarator != NULL_TREE
- && TREE_CODE (declarator) == CALL_EXPR
- && TREE_OPERAND (declarator, 0)
- && (TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE
- || TREE_CODE (TREE_OPERAND (declarator, 0)) == SCOPE_REF)
- && parmlist_is_exprlist (CALL_DECLARATOR_PARMS (declarator)))
- {
- /* It's invalid to try to initialize a data member using a
- functional notation, e.g.:
-
- struct S {
- static int i (3);
- };
-
- Explain that to the user. */
- static int explained;
-
- error ("invalid data member initialization");
- if (!explained)
- {
- error ("(use `=' to initialize static data members)");
- explained = 1;
- }
-
- declarator = TREE_OPERAND (declarator, 0);
- flags = 0;
- }
-
if (declspecs == NULL_TREE
&& TREE_CODE (declarator) == SCOPE_REF
&& TREE_CODE (TREE_OPERAND (declarator, 1)) == IDENTIFIER_NODE)
@@ -925,10 +846,8 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
init = NULL_TREE;
value = grokdeclarator (declarator, declspecs, FIELD, init != 0, &attrlist);
- if (! value || value == error_mark_node)
+ if (! value || error_operand_p (value))
/* friend or constructor went bad. */
- return value;
- if (TREE_TYPE (value) == error_mark_node)
return error_mark_node;
if (TREE_CODE (value) == TYPE_DECL && init)
@@ -938,8 +857,14 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
}
/* Pass friendly classes back. */
- if (TREE_CODE (value) == VOID_TYPE)
- return void_type_node;
+ if (value == void_type_node)
+ return value;
+
+ /* Pass friend decls back. */
+ if ((TREE_CODE (value) == FUNCTION_DECL
+ || TREE_CODE (value) == TEMPLATE_DECL)
+ && DECL_CONTEXT (value) != current_class_type)
+ return value;
if (DECL_NAME (value) != NULL_TREE
&& IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_'
@@ -953,9 +878,6 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
DECL_NONLOCAL (value) = 1;
DECL_CONTEXT (value) = current_class_type;
- if (CLASS_TYPE_P (TREE_TYPE (value)))
- CLASSTYPE_GOT_SEMICOLON (TREE_TYPE (value)) = 1;
-
if (processing_template_decl)
value = push_template_decl (value);
@@ -1021,7 +943,11 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
if (processing_template_decl
&& (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL))
- value = push_template_decl (value);
+ {
+ value = push_template_decl (value);
+ if (error_operand_p (value))
+ return error_mark_node;
+ }
if (attrlist)
cplus_decl_attributes (&value, attrlist, 0);
@@ -1050,7 +976,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
/* This must override the asm specifier which was placed
by grokclassfn. Lay this out fresh. */
SET_DECL_RTL (value, NULL_RTX);
- SET_DECL_ASSEMBLER_NAME (value, get_identifier (asmspec));
+ change_decl_assembler_name (value, get_identifier (asmspec));
}
if (!DECL_FRIEND_P (value))
grok_special_member_properties (value);
@@ -1073,11 +999,9 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node. */
tree
-grokbitfield (declarator, declspecs, width)
- tree declarator, declspecs, width;
+grokbitfield (tree declarator, tree declspecs, tree width)
{
- register tree value = grokdeclarator (declarator, declspecs, BITFIELD,
- 0, NULL);
+ tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, NULL);
if (! value) return NULL_TREE; /* friends went bad. */
@@ -1127,32 +1051,6 @@ grokbitfield (declarator, declspecs, width)
return value;
}
-/* Convert a conversion operator name to an identifier. SCOPE is the
- scope of the conversion operator, if explicit. */
-
-tree
-grokoptypename (declspecs, declarator, scope)
- tree declspecs, declarator;
- tree scope;
-{
- tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL);
-
- /* Resolve any TYPENAME_TYPEs that refer to SCOPE, before mangling
- the name, so that we mangle the right thing. */
- if (scope && current_template_parms
- && uses_template_parms (t)
- && uses_template_parms (scope))
- {
- tree args = current_template_args ();
-
- push_scope (scope);
- t = tsubst (t, args, tf_error | tf_warning, NULL_TREE);
- pop_scope (scope);
- }
-
- return mangle_conv_op_name_for_type (t);
-}
-
/* When a function is declared with an initializer,
do the right thing. Currently, there are two possibilities:
@@ -1189,9 +1087,7 @@ grokoptypename (declspecs, declarator, scope)
*/
static void
-grok_function_init (decl, init)
- tree decl;
- tree init;
+grok_function_init (tree decl, tree init)
{
/* An initializer for a function tells how this function should
be inherited. */
@@ -1206,9 +1102,7 @@ grok_function_init (decl, init)
}
void
-cplus_decl_attributes (decl, attributes, flags)
- tree *decl, attributes;
- int flags;
+cplus_decl_attributes (tree *decl, tree attributes, int flags)
{
if (*decl == NULL_TREE || *decl == void_type_node)
return;
@@ -1222,94 +1116,29 @@ cplus_decl_attributes (decl, attributes, flags)
SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (*decl), TREE_TYPE (*decl));
}
-/* CONSTRUCTOR_NAME:
- Return the name for the constructor (or destructor) for the
- specified class. Argument can be RECORD_TYPE, TYPE_DECL, or
- IDENTIFIER_NODE. When given a template, this routine doesn't
- lose the specialization. */
-
-tree
-constructor_name_full (thing)
- tree thing;
-{
- if (TREE_CODE (thing) == TEMPLATE_TYPE_PARM
- || TREE_CODE (thing) == BOUND_TEMPLATE_TEMPLATE_PARM
- || TREE_CODE (thing) == TYPENAME_TYPE)
- thing = TYPE_NAME (thing);
- else if (IS_AGGR_TYPE_CODE (TREE_CODE (thing)))
- {
- if (TYPE_WAS_ANONYMOUS (thing) && TYPE_HAS_CONSTRUCTOR (thing))
- thing = DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (thing), 0)));
- else
- thing = TYPE_NAME (thing);
- }
- if (TREE_CODE (thing) == TYPE_DECL
- || (TREE_CODE (thing) == TEMPLATE_DECL
- && TREE_CODE (DECL_TEMPLATE_RESULT (thing)) == TYPE_DECL))
- thing = DECL_NAME (thing);
- my_friendly_assert (TREE_CODE (thing) == IDENTIFIER_NODE, 197);
- return thing;
-}
-
-/* CONSTRUCTOR_NAME:
- Return the name for the constructor (or destructor) for the
- specified class. Argument can be RECORD_TYPE, TYPE_DECL, or
- IDENTIFIER_NODE. When given a template, return the plain
- unspecialized name. */
-
-tree
-constructor_name (thing)
- tree thing;
-{
- tree t;
- thing = constructor_name_full (thing);
- t = IDENTIFIER_TEMPLATE (thing);
- if (!t)
- return thing;
- return t;
-}
-
-/* Returns TRUE if NAME is the name for the constructor for TYPE. */
-
-bool
-constructor_name_p (tree name, tree type)
-{
- return (name == constructor_name (type)
- || name == constructor_name_full (type));
-}
-
-
/* Defer the compilation of the FN until the end of compilation. */
void
-defer_fn (fn)
- tree fn;
+defer_fn (tree fn)
{
if (DECL_DEFERRED_FN (fn))
return;
DECL_DEFERRED_FN (fn) = 1;
+ DECL_DEFER_OUTPUT (fn) = 1;
if (!deferred_fns)
VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
VARRAY_PUSH_TREE (deferred_fns, fn);
}
-/* Hunts through the global anonymous union ANON_DECL, building
- appropriate VAR_DECLs. Stores cleanups on the list of ELEMS, and
- returns a VAR_DECL whose size is the same as the size of the
- ANON_DECL, if one is available.
-
- FIXME: we should really handle anonymous unions by binding the names
- of the members to COMPONENT_REFs rather than this kludge. */
+/* Walks through the namespace- or function-scope anonymous union OBJECT,
+ building appropriate ALIAS_DECLs. Returns one of the fields for use in
+ the mangled name. */
-static tree
-build_anon_union_vars (anon_decl, elems, static_p, external_p)
- tree anon_decl;
- tree* elems;
- int static_p;
- int external_p;
+static tree
+build_anon_union_vars (tree object)
{
- tree type = TREE_TYPE (anon_decl);
+ tree type = TREE_TYPE (object);
tree main_decl = NULL_TREE;
tree field;
@@ -1323,12 +1152,14 @@ build_anon_union_vars (anon_decl, elems, static_p, external_p)
field = TREE_CHAIN (field))
{
tree decl;
+ tree ref;
if (DECL_ARTIFICIAL (field))
continue;
if (TREE_CODE (field) != FIELD_DECL)
{
- cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members",
+ cp_pedwarn_at ("\
+`%#D' invalid; an anonymous union can only have non-static data members",
field);
continue;
}
@@ -1338,55 +1169,30 @@ build_anon_union_vars (anon_decl, elems, static_p, external_p)
else if (TREE_PROTECTED (field))
cp_pedwarn_at ("protected member `%#D' in anonymous union", field);
- if (DECL_NAME (field) == NULL_TREE
- && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
- {
- decl = build_anon_union_vars (field, elems, static_p, external_p);
- if (!decl)
- continue;
- }
- else if (DECL_NAME (field) == NULL_TREE)
- continue;
+ if (processing_template_decl)
+ ref = build_min_nt (COMPONENT_REF, object, DECL_NAME (field));
else
+ ref = build_class_member_access_expr (object, field, NULL_TREE,
+ false);
+
+ if (DECL_NAME (field))
{
- decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field));
- /* tell `pushdecl' that this is not tentative. */
- DECL_INITIAL (decl) = error_mark_node;
+ decl = build_decl (ALIAS_DECL, DECL_NAME (field), TREE_TYPE (field));
+ DECL_INITIAL (decl) = ref;
TREE_PUBLIC (decl) = 0;
- TREE_STATIC (decl) = static_p;
- DECL_EXTERNAL (decl) = external_p;
+ TREE_STATIC (decl) = 0;
+ DECL_EXTERNAL (decl) = 1;
decl = pushdecl (decl);
- DECL_INITIAL (decl) = NULL_TREE;
- }
-
- /* Only write out one anon union element--choose the largest
- one. We used to try to find one the same size as the union,
- but that fails if the ABI forces us to align the union more
- strictly. */
- if (main_decl == NULL_TREE
- || tree_int_cst_lt (DECL_SIZE (main_decl), DECL_SIZE (decl)))
- {
- if (main_decl)
- TREE_ASM_WRITTEN (main_decl) = 1;
- main_decl = decl;
}
- else
- /* ??? This causes there to be no debug info written out
- about this decl. */
- TREE_ASM_WRITTEN (decl) = 1;
-
- if (DECL_NAME (field) == NULL_TREE
- && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
- /* The remainder of the processing was already done in the
- recursive call. */
- continue;
+ else if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
+ decl = build_anon_union_vars (ref);
+ else
+ decl = 0;
- /* If there's a cleanup to do, it belongs in the
- TREE_PURPOSE of the following TREE_LIST. */
- *elems = tree_cons (NULL_TREE, decl, *elems);
- TREE_TYPE (*elems) = type;
+ if (main_decl == NULL_TREE)
+ main_decl = decl;
}
-
+
return main_decl;
}
@@ -1395,14 +1201,11 @@ build_anon_union_vars (anon_decl, elems, static_p, external_p)
is nonzero if this union is not declared static. */
void
-finish_anon_union (anon_union_decl)
- tree anon_union_decl;
+finish_anon_union (tree anon_union_decl)
{
tree type = TREE_TYPE (anon_union_decl);
tree main_decl;
- int public_p = TREE_PUBLIC (anon_union_decl);
- int static_p = TREE_STATIC (anon_union_decl);
- int external_p = DECL_EXTERNAL (anon_union_decl);
+ bool public_p = TREE_PUBLIC (anon_union_decl);
/* The VAR_DECL's context is the same as the TYPE's context. */
DECL_CONTEXT (anon_union_decl) = DECL_CONTEXT (TYPE_NAME (type));
@@ -1416,68 +1219,28 @@ finish_anon_union (anon_union_decl)
return;
}
- if (!processing_template_decl)
+ main_decl = build_anon_union_vars (anon_union_decl);
+ if (main_decl == NULL_TREE)
{
- main_decl
- = build_anon_union_vars (anon_union_decl,
- &DECL_ANON_UNION_ELEMS (anon_union_decl),
- static_p, external_p);
-
- if (main_decl == NULL_TREE)
- {
- warning ("anonymous aggregate with no members");
- return;
- }
-
- if (static_p)
- {
- make_decl_rtl (main_decl, 0);
- COPY_DECL_RTL (main_decl, anon_union_decl);
- expand_anon_union_decl (anon_union_decl,
- NULL_TREE,
- DECL_ANON_UNION_ELEMS (anon_union_decl));
- return;
- }
+ warning ("anonymous union with no members");
+ return;
}
- add_decl_stmt (anon_union_decl);
-}
-
-/* Finish processing a builtin type TYPE. It's name is NAME,
- its fields are in the array FIELDS. LEN is the number of elements
- in FIELDS minus one, or put another way, it is the maximum subscript
- used in FIELDS.
-
- It is given the same alignment as ALIGN_TYPE. */
-
-void
-finish_builtin_type (type, name, fields, len, align_type)
- tree type;
- const char *name;
- tree fields[];
- int len;
- tree align_type;
-{
- register int i;
-
- TYPE_FIELDS (type) = fields[0];
- for (i = 0; i < len; i++)
+ if (!processing_template_decl)
{
- layout_type (TREE_TYPE (fields[i]));
- DECL_FIELD_CONTEXT (fields[i]) = type;
- TREE_CHAIN (fields[i]) = fields[i+1];
+ /* Use main_decl to set the mangled name. */
+ DECL_NAME (anon_union_decl) = DECL_NAME (main_decl);
+ mangle_decl (anon_union_decl);
+ DECL_NAME (anon_union_decl) = NULL_TREE;
}
- DECL_FIELD_CONTEXT (fields[i]) = type;
- TYPE_ALIGN (type) = TYPE_ALIGN (align_type);
- TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (align_type);
- layout_type (type);
-#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);
-#endif
- TYPE_STUB_DECL (type) = TYPE_NAME (type);
- layout_decl (TYPE_NAME (type), 0);
+
+ pushdecl (anon_union_decl);
+ if (building_stmt_tree ()
+ && at_function_scope_p ())
+ add_decl_stmt (anon_union_decl);
+ else if (!processing_template_decl)
+ rest_of_decl_compilation (anon_union_decl, NULL,
+ toplevel_bindings_p (), at_eof);
}
/* Auxiliary functions to make type signatures for
@@ -1485,8 +1248,7 @@ finish_builtin_type (type, name, fields, len, align_type)
what compiler will be expecting. */
tree
-coerce_new_type (type)
- tree type;
+coerce_new_type (tree type)
{
int e = 0;
tree args = TYPE_ARG_TYPES (type);
@@ -1508,20 +1270,19 @@ coerce_new_type (type)
{
case 2:
args = tree_cons (NULL_TREE, size_type_node, args);
- /* FALLTHROUGH */
+ /* Fall through. */
case 1:
type = build_exception_variant
(build_function_type (ptr_type_node, args),
TYPE_RAISES_EXCEPTIONS (type));
- /* FALLTHROUGH */
+ /* Fall through. */
default:;
}
return type;
}
tree
-coerce_delete_type (type)
- tree type;
+coerce_delete_type (tree type)
{
int e = 0;
tree args = TYPE_ARG_TYPES (type);
@@ -1543,12 +1304,12 @@ coerce_delete_type (type)
{
case 2:
args = tree_cons (NULL_TREE, ptr_type_node, args);
- /* FALLTHROUGH */
+ /* Fall through. */
case 1:
type = build_exception_variant
(build_function_type (void_type_node, args),
TYPE_RAISES_EXCEPTIONS (type));
- /* FALLTHROUGH */
+ /* Fall through. */
default:;
}
@@ -1556,8 +1317,7 @@ coerce_delete_type (type)
}
static void
-mark_vtable_entries (decl)
- tree decl;
+mark_vtable_entries (tree decl)
{
tree entries = CONSTRUCTOR_ELTS (DECL_INITIAL (decl));
@@ -1565,7 +1325,9 @@ mark_vtable_entries (decl)
{
tree fnaddr = TREE_VALUE (entries);
tree fn;
-
+
+ STRIP_NOPS (fnaddr);
+
if (TREE_CODE (fnaddr) != ADDR_EXPR
&& TREE_CODE (fnaddr) != FDESC_EXPR)
/* This entry is an offset: a virtual base class offset, a
@@ -1588,8 +1350,7 @@ mark_vtable_entries (decl)
linkage available. */
void
-comdat_linkage (decl)
- tree decl;
+comdat_linkage (tree decl)
{
if (flag_weak)
make_decl_one_only (decl);
@@ -1642,8 +1403,7 @@ comdat_linkage (decl)
instantiations; otherwise we get duplicate symbol errors. */
void
-maybe_make_one_only (decl)
- tree decl;
+maybe_make_one_only (tree decl)
{
/* We used to say that this was not necessary on targets that support weak
symbols, because the implicit instantiations will defer to the explicit
@@ -1665,11 +1425,10 @@ maybe_make_one_only (decl)
{
DECL_COMDAT (decl) = 1;
/* Mark it needed so we don't forget to emit it. */
- TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) = 1;
+ mark_referenced (DECL_ASSEMBLER_NAME (decl));
}
}
-
/* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL,
based on TYPE and other static flags.
@@ -1677,9 +1436,7 @@ maybe_make_one_only (decl)
it's public in this file or in another one. */
void
-import_export_vtable (decl, type, final)
- tree decl, type;
- int final;
+import_export_vtable (tree decl, tree type, int final)
{
if (DECL_INTERFACE_KNOWN (decl))
return;
@@ -1721,8 +1478,7 @@ import_export_vtable (decl, type, final)
using various heuristics. */
static void
-import_export_class (ctype)
- tree ctype;
+import_export_class (tree ctype)
{
/* -1 for imported, 1 for exported. */
int import_export = 0;
@@ -1778,60 +1534,46 @@ import_export_class (ctype)
CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0);
}
}
-
-/* We need to describe to the assembler the relationship between
- a vtable and the vtable of the parent class. */
-static void
-output_vtable_inherit (vars)
- tree vars;
+/* Return true if VAR has already been provided to the back end; in that
+ case VAR should not be modified further by the front end. */
+static bool
+var_finalized_p (tree var)
{
- tree parent;
- rtx child_rtx, parent_rtx;
-
- child_rtx = XEXP (DECL_RTL (vars), 0); /* strip the mem ref */
-
- parent = binfo_for_vtable (vars);
-
- if (parent == TYPE_BINFO (DECL_CONTEXT (vars)))
- parent_rtx = const0_rtx;
- else if (parent)
- {
- parent = get_vtbl_decl_for_binfo (TYPE_BINFO (BINFO_TYPE (parent)));
- parent_rtx = XEXP (DECL_RTL (parent), 0); /* strip the mem ref */
- }
+ if (flag_unit_at_a_time)
+ return cgraph_varpool_node (var)->finalized;
else
- abort ();
-
- assemble_vtable_inherit (child_rtx, parent_rtx);
+ return TREE_ASM_WRITTEN (var);
}
/* If necessary, write out the vtables for the dynamic class CTYPE.
- Returns nonzero if any vtables were emitted. */
+ Returns true if any vtables were emitted. */
-static int
+static bool
maybe_emit_vtables (tree ctype)
{
tree vtbl;
tree primary_vtbl;
+ bool needed = false;
/* If the vtables for this class have already been emitted there is
nothing more to do. */
primary_vtbl = CLASSTYPE_VTABLES (ctype);
- if (TREE_ASM_WRITTEN (primary_vtbl))
- return 0;
+ if (var_finalized_p (primary_vtbl))
+ return false;
/* Ignore dummy vtables made by get_vtable_decl. */
if (TREE_TYPE (primary_vtbl) == void_type_node)
- return 0;
+ return false;
import_export_class (ctype);
- import_export_vtable (primary_vtbl, ctype, 1);
/* See if any of the vtables are needed. */
for (vtbl = CLASSTYPE_VTABLES (ctype); vtbl; vtbl = TREE_CHAIN (vtbl))
- if (!DECL_EXTERNAL (vtbl) && DECL_NEEDED_P (vtbl))
- break;
-
+ {
+ import_export_vtable (vtbl, ctype, 1);
+ if (!DECL_EXTERNAL (vtbl) && DECL_NEEDED_P (vtbl))
+ break;
+ }
if (!vtbl)
{
/* If the references to this class' vtables are optimized away,
@@ -1840,8 +1582,11 @@ maybe_emit_vtables (tree ctype)
if (DECL_COMDAT (primary_vtbl)
&& CLASSTYPE_DEBUG_REQUESTED (ctype))
note_debug_info_needed (ctype);
- return 0;
+ return false;
}
+ else if (TREE_PUBLIC (vtbl) && !DECL_COMDAT (vtbl))
+ needed = true;
+
/* The ABI requires that we emit all of the vtables if we emit any
of them. */
@@ -1850,8 +1595,17 @@ maybe_emit_vtables (tree ctype)
/* Write it out. */
import_export_vtable (vtbl, ctype, 1);
mark_vtable_entries (vtbl);
+
+ /* If we know that DECL is needed, mark it as such for the varpool. */
+ if (needed)
+ cgraph_varpool_mark_needed_node (cgraph_varpool_node (vtbl));
+
if (TREE_TYPE (DECL_INITIAL (vtbl)) == 0)
- store_init_value (vtbl, DECL_INITIAL (vtbl));
+ {
+ /* It had better be all done at compile-time. */
+ if (store_init_value (vtbl, DECL_INITIAL (vtbl)))
+ abort ();
+ }
if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG)
{
@@ -1885,9 +1639,6 @@ maybe_emit_vtables (tree ctype)
rest_of_decl_compilation (vtbl, NULL, 1, 1);
- if (flag_vtable_gc)
- output_vtable_inherit (vtbl);
-
/* Because we're only doing syntax-checking, we'll never end up
actually marking the variable as written. */
if (flag_syntax_only)
@@ -1898,15 +1649,14 @@ maybe_emit_vtables (tree ctype)
info. */
note_debug_info_needed (ctype);
- return 1;
+ return true;
}
/* Determines the proper settings of TREE_PUBLIC and DECL_EXTERNAL for an
inline function or template instantiation at end-of-file. */
void
-import_export_decl (decl)
- tree decl;
+import_export_decl (tree decl)
{
if (DECL_INTERFACE_KNOWN (decl))
return;
@@ -1918,7 +1668,8 @@ import_export_decl (decl)
if ((DECL_IMPLICIT_INSTANTIATION (decl)
|| DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl))
&& (flag_implicit_templates
- || (flag_implicit_inline_templates
+ || (flag_implicit_inline_templates
+ && TREE_CODE (decl) == FUNCTION_DECL
&& DECL_DECLARED_INLINE_P (decl))))
{
if (!TREE_PUBLIC (decl))
@@ -1972,10 +1723,7 @@ import_export_decl (decl)
typeinfo for TYPE should be in the runtime library. */
void
-import_export_tinfo (decl, type, is_in_library)
- tree decl;
- tree type;
- int is_in_library;
+import_export_tinfo (tree decl, tree type, bool is_in_library)
{
if (DECL_INTERFACE_KNOWN (decl))
return;
@@ -2013,8 +1761,7 @@ import_export_tinfo (decl, type, is_in_library)
an array whose (innermost) elements have a non-trivial destructor. */
tree
-build_cleanup (decl)
- tree decl;
+build_cleanup (tree decl)
{
tree temp;
tree type = TREE_TYPE (decl);
@@ -2044,8 +1791,7 @@ build_cleanup (decl)
which has static storage duration. */
tree
-get_guard (decl)
- tree decl;
+get_guard (tree decl)
{
tree sname;
tree guard;
@@ -2080,8 +1826,7 @@ get_guard (decl)
guarded entity is actually initialized. */
static tree
-get_guard_bits (guard)
- tree guard;
+get_guard_bits (tree guard)
{
/* We only set the first byte of the guard, in order to leave room
for a mutex in the high-order bits. */
@@ -2100,8 +1845,7 @@ get_guard_bits (guard)
variable has already been initialized. */
tree
-get_guard_cond (guard)
- tree guard;
+get_guard_cond (tree guard)
{
tree guard_value;
@@ -2117,8 +1861,7 @@ get_guard_cond (guard)
the variable being guarded has been initialized. */
tree
-set_guard (guard)
- tree guard;
+set_guard (tree guard)
{
tree guard_init;
@@ -2134,8 +1877,7 @@ set_guard (guard)
or destructors. Subroutine of do_[cd]tors. */
static tree
-start_objects (method_type, initp)
- int method_type, initp;
+start_objects (int method_type, int initp)
{
tree fnname;
tree body;
@@ -2179,11 +1921,11 @@ start_objects (method_type, initp)
DECL_GLOBAL_DTOR_P (current_function_decl) = 1;
DECL_LANG_SPECIFIC (current_function_decl)->decl_flags.u2sel = 1;
- body = begin_compound_stmt (/*has_no_scope=*/0);
+ body = begin_compound_stmt (/*has_no_scope=*/false);
/* We cannot allow these functions to be elided, even if they do not
have external linkage. And, there's no point in deferring
- copmilation of thes functions; they're all going to have to be
+ compilation of thes functions; they're all going to have to be
out anyhow. */
current_function_cannot_inline
= "static constructors and destructors cannot be inlined";
@@ -2195,16 +1937,14 @@ start_objects (method_type, initp)
or destructors. Subroutine of do_[cd]tors. */
static void
-finish_objects (method_type, initp, body)
- int method_type, initp;
- tree body;
+finish_objects (int method_type, int initp, tree body)
{
tree fn;
/* Finish up. */
- finish_compound_stmt (/*has_no_scope=*/0, body);
+ finish_compound_stmt (body);
fn = finish_function (0);
- expand_body (fn);
+ expand_or_defer_fn (fn);
/* When only doing semantic analysis, and no RTL generation, we
can't call functions that directly emit assembly code; there is
@@ -2263,10 +2003,8 @@ static splay_tree priority_info_map;
translation unit. */
static tree
-start_static_storage_duration_function ()
+start_static_storage_duration_function (unsigned count)
{
- static unsigned ssdf_number;
-
tree parm_types;
tree type;
tree body;
@@ -2274,14 +2012,7 @@ start_static_storage_duration_function ()
/* Create the identifier for this function. It will be of the form
SSDF_IDENTIFIER_<number>. */
- sprintf (id, "%s_%u", SSDF_IDENTIFIER, ssdf_number++);
- if (ssdf_number == 0)
- {
- /* Overflow occurred. That means there are at least 4 billion
- initialization functions. */
- sorry ("too many initialization functions required");
- abort ();
- }
+ sprintf (id, "%s_%u", SSDF_IDENTIFIER, count);
/* Create the parameters. */
parm_types = void_list_node;
@@ -2334,7 +2065,7 @@ start_static_storage_duration_function ()
/* Put the function in the global scope. */
pushdecl (ssdf_decl);
- /* Start the function itself. This is equivalent to declarating the
+ /* Start the function itself. This is equivalent to declaring the
function as:
static void __ssdf (int __initialize_p, init __priority_p);
@@ -2347,7 +2078,7 @@ start_static_storage_duration_function ()
SF_PRE_PARSED);
/* Set up the scope of the outermost block in the function. */
- body = begin_compound_stmt (/*has_no_scope=*/0);
+ body = begin_compound_stmt (/*has_no_scope=*/false);
/* This function must not be deferred because we are depending on
its compilation to tell us what is TREE_SYMBOL_REFERENCED. */
@@ -2362,12 +2093,11 @@ start_static_storage_duration_function ()
this point, no more such objects can be created. */
static void
-finish_static_storage_duration_function (body)
- tree body;
+finish_static_storage_duration_function (tree body)
{
/* Close out the function. */
- finish_compound_stmt (/*has_no_scope=*/0, body);
- expand_body (finish_function (0));
+ finish_compound_stmt (body);
+ expand_or_defer_fn (finish_function (0));
}
/* Return the information about the indicated PRIORITY level. If no
@@ -2375,8 +2105,7 @@ finish_static_storage_duration_function (body)
appropriate prologue. */
static priority_info
-get_priority_info (priority)
- int priority;
+get_priority_info (int priority)
{
priority_info pi;
splay_tree_node n;
@@ -2387,7 +2116,7 @@ get_priority_info (priority)
{
/* Create a new priority information structure, and insert it
into the map. */
- pi = (priority_info) xmalloc (sizeof (struct priority_info_s));
+ pi = xmalloc (sizeof (struct priority_info_s));
pi->initializations_p = 0;
pi->destructions_p = 0;
splay_tree_insert (priority_info_map,
@@ -2405,9 +2134,7 @@ get_priority_info (priority)
are destroying it. */
static tree
-start_static_initialization_or_destruction (decl, initp)
- tree decl;
- int initp;
+start_static_initialization_or_destruction (tree decl, int initp)
{
tree guard_if_stmt = NULL_TREE;
int priority;
@@ -2433,8 +2160,7 @@ start_static_initialization_or_destruction (decl, initp)
where DECL was declared so that error-messages make sense, and so
that the debugger will show somewhat sensible file and line
information. */
- input_filename = DECL_SOURCE_FILE (decl);
- lineno = DECL_SOURCE_LINE (decl);
+ input_location = DECL_SOURCE_LOCATION (decl);
/* Because of:
@@ -2529,8 +2255,7 @@ start_static_initialization_or_destruction (decl, initp)
the initialization. */
static void
-finish_static_initialization_or_destruction (guard_if_stmt)
- tree guard_if_stmt;
+finish_static_initialization_or_destruction (tree guard_if_stmt)
{
finish_then_clause (guard_if_stmt);
finish_if_stmt ();
@@ -2545,9 +2270,7 @@ finish_static_initialization_or_destruction (guard_if_stmt)
static storage duration. The initialization is INIT. */
static void
-do_static_initialization (decl, init)
- tree decl;
- tree init;
+do_static_initialization (tree decl, tree init)
{
tree guard_if_stmt;
@@ -2575,8 +2298,7 @@ do_static_initialization (decl, init)
destruction. */
static void
-do_static_destruction (decl)
- tree decl;
+do_static_destruction (tree decl)
{
tree guard_if_stmt;
@@ -2604,8 +2326,7 @@ do_static_destruction (decl)
i.e., the first variable should be initialized first. */
static tree
-prune_vars_needing_no_initialization (vars)
- tree *vars;
+prune_vars_needing_no_initialization (tree *vars)
{
tree *var = vars;
tree result = NULL_TREE;
@@ -2657,13 +2378,12 @@ prune_vars_needing_no_initialization (vars)
VARS. */
static void
-write_out_vars (vars)
- tree vars;
+write_out_vars (tree vars)
{
tree v;
for (v = vars; v; v = TREE_CHAIN (v))
- if (! TREE_ASM_WRITTEN (TREE_VALUE (v)))
+ if (!var_finalized_p (TREE_VALUE (v)))
rest_of_decl_compilation (TREE_VALUE (v), 0, 1, 1);
}
@@ -2672,36 +2392,45 @@ write_out_vars (vars)
storage duration having the indicated PRIORITY. */
static void
-generate_ctor_or_dtor_function (constructor_p, priority)
- int constructor_p;
- int priority;
+generate_ctor_or_dtor_function (bool constructor_p, int priority,
+ location_t *locus)
{
char function_key;
tree arguments;
+ tree fndecl;
tree body;
size_t i;
+ input_location = *locus;
+ locus->line++;
+
/* We use `I' to indicate initialization and `D' to indicate
destruction. */
- if (constructor_p)
- function_key = 'I';
- else
- function_key = 'D';
+ function_key = constructor_p ? 'I' : 'D';
- /* Begin the function. */
- body = start_objects (function_key, priority);
+ /* We emit the function lazily, to avoid generating empty
+ global constructors and destructors. */
+ body = NULL_TREE;
/* Call the static storage duration function with appropriate
arguments. */
if (ssdf_decls)
for (i = 0; i < ssdf_decls->elements_used; ++i)
{
- arguments = tree_cons (NULL_TREE, build_int_2 (priority, 0),
- NULL_TREE);
- arguments = tree_cons (NULL_TREE, build_int_2 (constructor_p, 0),
- arguments);
- finish_expr_stmt (build_function_call (VARRAY_TREE (ssdf_decls, i),
- arguments));
+ fndecl = VARRAY_TREE (ssdf_decls, i);
+
+ /* Calls to pure or const functions will expand to nothing. */
+ if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE)))
+ {
+ if (! body)
+ body = start_objects (function_key, priority);
+
+ arguments = tree_cons (NULL_TREE, build_int_2 (priority, 0),
+ NULL_TREE);
+ arguments = tree_cons (NULL_TREE, build_int_2 (constructor_p, 0),
+ arguments);
+ finish_expr_stmt (build_function_call (fndecl, arguments));
+ }
}
/* If we're generating code for the DEFAULT_INIT_PRIORITY, throw in
@@ -2714,21 +2443,31 @@ generate_ctor_or_dtor_function (constructor_p, priority)
for (fns = constructor_p ? static_ctors : static_dtors;
fns;
fns = TREE_CHAIN (fns))
- finish_expr_stmt (build_function_call (TREE_VALUE (fns), NULL_TREE));
+ {
+ fndecl = TREE_VALUE (fns);
+
+ /* Calls to pure/const functions will expand to nothing. */
+ if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE)))
+ {
+ if (! body)
+ body = start_objects (function_key, priority);
+ finish_expr_stmt (build_function_call (fndecl, NULL_TREE));
+ }
+ }
}
/* Close out the function. */
- finish_objects (function_key, priority, body);
+ if (body)
+ finish_objects (function_key, priority, body);
}
/* Generate constructor and destructor functions for the priority
indicated by N. */
static int
-generate_ctor_and_dtor_functions_for_priority (n, data)
- splay_tree_node n;
- void *data ATTRIBUTE_UNUSED;
+generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
{
+ location_t *locus = data;
int priority = (int) n->key;
priority_info pi = (priority_info) n->value;
@@ -2736,38 +2475,73 @@ generate_ctor_and_dtor_functions_for_priority (n, data)
needed. */
if (pi->initializations_p
|| (priority == DEFAULT_INIT_PRIORITY && static_ctors))
- generate_ctor_or_dtor_function (/*constructor_p=*/1,
- priority);
+ generate_ctor_or_dtor_function (/*constructor_p=*/true, priority, locus);
if (pi->destructions_p
|| (priority == DEFAULT_INIT_PRIORITY && static_dtors))
- generate_ctor_or_dtor_function (/*constructor_p=*/0,
- priority);
+ generate_ctor_or_dtor_function (/*constructor_p=*/false, priority, locus);
/* Keep iterating. */
return 0;
}
+/* Called via LANGHOOK_CALLGRAPH_ANALYZE_EXPR. It is supposed to mark
+ decls referenced from frontend specific constructs; it will be called
+ only for language-specific tree nodes.
+
+ Here we must deal with member pointers. */
+
+tree
+cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ tree from ATTRIBUTE_UNUSED)
+{
+ tree t = *tp;
+
+ if (flag_unit_at_a_time)
+ switch (TREE_CODE (t))
+ {
+ case PTRMEM_CST:
+ if (TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))
+ cgraph_mark_needed_node (cgraph_node (PTRMEM_CST_MEMBER (t)));
+ break;
+ case BASELINK:
+ if (TREE_CODE (BASELINK_FUNCTIONS (t)) == FUNCTION_DECL)
+ cgraph_mark_needed_node (cgraph_node (BASELINK_FUNCTIONS (t)));
+ break;
+
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
/* This routine is called from the last rule in yyparse ().
Its job is to create all the code needed to initialize and
destroy the global aggregates. We do the destruction
first, since that way we only need to reverse the decls once. */
void
-finish_file ()
+finish_file (void)
{
tree vars;
- int reconsider;
+ bool reconsider;
size_t i;
+ location_t locus;
+ unsigned ssdf_count = 0;
+ locus = input_location;
at_eof = 1;
/* Bad parse errors. Just forget about it. */
if (! global_bindings_p () || current_class_type || decl_namespace_list)
return;
+ if (pch_file)
+ c_common_write_pch ();
+
/* Otherwise, GDB can get confused, because in only knows
about source for LINENO-1 lines. */
- lineno -= 1;
+ input_line -= 1;
interface_unknown = 1;
interface_only = 0;
@@ -2795,49 +2569,75 @@ finish_file ()
do
{
tree t;
+ size_t n_old, n_new;
- reconsider = 0;
+ reconsider = false;
/* If there are templates that we've put off instantiating, do
them now. */
instantiate_pending_templates ();
+ ggc_collect ();
/* Write out virtual tables as required. Note that writing out
- the virtual table for a template class may cause the
- instantiation of members of that class. If we write out
- vtables then we remove the class from our list so we don't
- have to look at it again. */
-
+ the virtual table for a template class may cause the
+ instantiation of members of that class. If we write out
+ vtables then we remove the class from our list so we don't
+ have to look at it again. */
+
while (keyed_classes != NULL_TREE
- && maybe_emit_vtables (TREE_VALUE (keyed_classes)))
- {
- reconsider = 1;
- keyed_classes = TREE_CHAIN (keyed_classes);
- }
-
+ && maybe_emit_vtables (TREE_VALUE (keyed_classes)))
+ {
+ reconsider = true;
+ keyed_classes = TREE_CHAIN (keyed_classes);
+ }
+
t = keyed_classes;
if (t != NULL_TREE)
- {
- tree next = TREE_CHAIN (t);
-
- while (next)
- {
- if (maybe_emit_vtables (TREE_VALUE (next)))
- {
- reconsider = 1;
- TREE_CHAIN (t) = TREE_CHAIN (next);
- }
- else
- t = next;
-
- next = TREE_CHAIN (t);
- }
- }
-
- /* Write out needed type info variables. Writing out one variable
- might cause others to be needed. */
- if (walk_globals (unemitted_tinfo_decl_p, emit_tinfo_decl, /*data=*/0))
- reconsider = 1;
+ {
+ tree next = TREE_CHAIN (t);
+
+ while (next)
+ {
+ if (maybe_emit_vtables (TREE_VALUE (next)))
+ {
+ reconsider = true;
+ TREE_CHAIN (t) = TREE_CHAIN (next);
+ }
+ else
+ t = next;
+
+ next = TREE_CHAIN (t);
+ }
+ }
+
+ /* Write out needed type info variables. We have to be careful
+ looping through unemitted decls, because emit_tinfo_decl may
+ cause other variables to be needed. We stick new elements
+ (and old elements that we may need to reconsider) at the end
+ of the array, then shift them back to the beginning once we're
+ done. */
+
+ n_old = VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls);
+ for (i = 0; i < n_old; ++i)
+ {
+ tree tinfo_decl = VARRAY_TREE (unemitted_tinfo_decls, i);
+ if (emit_tinfo_decl (tinfo_decl))
+ reconsider = true;
+ else
+ VARRAY_PUSH_TREE (unemitted_tinfo_decls, tinfo_decl);
+ }
+
+ /* The only elements we want to keep are the new ones. Copy
+ them to the beginning of the array, then get rid of the
+ leftovers. */
+ n_new = VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls) - n_old;
+ if (n_new)
+ memmove (&VARRAY_TREE (unemitted_tinfo_decls, 0),
+ &VARRAY_TREE (unemitted_tinfo_decls, n_old),
+ n_new * sizeof (tree));
+ memset (&VARRAY_TREE (unemitted_tinfo_decls, n_new),
+ 0, n_old * sizeof (tree));
+ VARRAY_ACTIVE_SIZE (unemitted_tinfo_decls) = n_new;
/* The list of objects with static storage duration is built up
in reverse order. We clear STATIC_AGGREGATES so that any new
@@ -2857,7 +2657,12 @@ finish_file ()
out. That's a deficiency in the back-end. When this is
fixed, these initialization functions could all become
inline, with resulting performance improvements. */
- tree ssdf_body = start_static_storage_duration_function ();
+ tree ssdf_body;
+
+ /* Set the line and file, so that it is obviously not from
+ the source file. */
+ input_location = locus;
+ ssdf_body = start_static_storage_duration_function (ssdf_count);
/* Make sure the back end knows about all the variables. */
write_out_vars (vars);
@@ -2884,12 +2689,15 @@ finish_file ()
/* Finish up the static storage duration function for this
round. */
+ input_location = locus;
finish_static_storage_duration_function (ssdf_body);
/* All those initializations and finalizations might cause
us to need more inline functions, more template
instantiations, etc. */
- reconsider = 1;
+ reconsider = true;
+ ssdf_count++;
+ locus.line++;
}
for (i = 0; i < deferred_fns_used; ++i)
@@ -2909,7 +2717,7 @@ finish_file ()
push_to_top_level ();
synthesize_method (decl);
pop_from_top_level ();
- reconsider = 1;
+ reconsider = true;
}
/* If the function has no body, avoid calling
@@ -2922,7 +2730,7 @@ finish_file ()
continue;
import_export_decl (decl);
-
+
/* We lie to the back-end, pretending that some functions
are not defined when they really are. This keeps these
functions from being put out unnecessarily. But, we must
@@ -2945,41 +2753,33 @@ finish_file ()
if (!DECL_EXTERNAL (decl)
&& DECL_NEEDED_P (decl)
&& DECL_SAVED_TREE (decl)
- && !TREE_ASM_WRITTEN (decl))
+ && !TREE_ASM_WRITTEN (decl)
+ && (!flag_unit_at_a_time
+ || !cgraph_node (decl)->local.finalized))
{
- int saved_not_really_extern;
-
- /* When we call finish_function in expand_body, it will
- try to reset DECL_NOT_REALLY_EXTERN so we save and
- restore it here. */
- saved_not_really_extern = DECL_NOT_REALLY_EXTERN (decl);
+ /* We will output the function; no longer consider it in this
+ loop. */
+ DECL_DEFER_OUTPUT (decl) = 0;
/* Generate RTL for this function now that we know we
need it. */
- expand_body (decl);
- /* Undo the damage done by finish_function. */
- DECL_EXTERNAL (decl) = 0;
- DECL_NOT_REALLY_EXTERN (decl) = saved_not_really_extern;
+ expand_or_defer_fn (decl);
/* If we're compiling -fsyntax-only pretend that this
function has been written out so that we don't try to
expand it again. */
if (flag_syntax_only)
TREE_ASM_WRITTEN (decl) = 1;
- reconsider = 1;
+ reconsider = true;
}
}
- if (deferred_fns_used
- && wrapup_global_declarations (&VARRAY_TREE (deferred_fns, 0),
- deferred_fns_used))
- reconsider = 1;
if (walk_namespaces (wrapup_globals_for_namespace, /*data=*/0))
- reconsider = 1;
+ reconsider = true;
/* Static data members are just like namespace-scope globals. */
for (i = 0; i < pending_statics_used; ++i)
{
tree decl = VARRAY_TREE (pending_statics, i);
- if (TREE_ASM_WRITTEN (decl))
+ if (var_finalized_p (decl))
continue;
import_export_decl (decl);
if (DECL_NOT_REALLY_EXTERN (decl) && ! DECL_IN_AGGR_P (decl))
@@ -2988,11 +2788,14 @@ finish_file ()
if (pending_statics
&& wrapup_global_declarations (&VARRAY_TREE (pending_statics, 0),
pending_statics_used))
- reconsider = 1;
+ reconsider = true;
+
+ if (cgraph_assemble_pending_functions ())
+ reconsider = true;
}
while (reconsider);
- /* All used inline functions must have a definition at this point. */
+ /* All used inline functions must have a definition at this point. */
for (i = 0; i < deferred_fns_used; ++i)
{
tree decl = VARRAY_TREE (deferred_fns, i);
@@ -3000,10 +2803,17 @@ finish_file ()
if (TREE_USED (decl) && DECL_DECLARED_INLINE_P (decl)
&& !(TREE_ASM_WRITTEN (decl) || DECL_SAVED_TREE (decl)
/* An explicit instantiation can be used to specify
- that the body is in another unit. It will have
- already verified there was a definition. */
+ that the body is in another unit. It will have
+ already verified there was a definition. */
|| DECL_EXPLICIT_INSTANTIATION (decl)))
- cp_warning_at ("inline function `%D' used but never defined", decl);
+ {
+ cp_warning_at ("inline function `%D' used but never defined", decl);
+ /* This symbol is effectively an "extern" declaration now.
+ This is not strictly necessary, but removes a duplicate
+ warning. */
+ TREE_PUBLIC (decl) = 1;
+ }
+
}
/* We give C linkage to static constructors and destructors. */
@@ -3014,15 +2824,16 @@ finish_file ()
if (priority_info_map)
splay_tree_foreach (priority_info_map,
generate_ctor_and_dtor_functions_for_priority,
- /*data=*/0);
+ /*data=*/&locus);
else
{
+
if (static_ctors)
generate_ctor_or_dtor_function (/*constructor_p=*/true,
- DEFAULT_INIT_PRIORITY);
+ DEFAULT_INIT_PRIORITY, &locus);
if (static_dtors)
generate_ctor_or_dtor_function (/*constructor_p=*/false,
- DEFAULT_INIT_PRIORITY);
+ DEFAULT_INIT_PRIORITY, &locus);
}
/* We're done with the splay-tree now. */
@@ -3033,6 +2844,12 @@ finish_file ()
linkage now. */
pop_lang_context ();
+ if (flag_unit_at_a_time)
+ {
+ cgraph_finalize_compilation_unit ();
+ cgraph_optimize ();
+ }
+
/* Now, issue warnings about static, but not defined, functions,
etc., and emit debugging information. */
walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider);
@@ -3062,1756 +2879,78 @@ finish_file ()
dump_tree_statistics ();
dump_time_statistics ();
}
+ input_location = locus;
}
-/* This is something of the form 'A()()()()()+1' that has turned out to be an
- expr. Since it was parsed like a type, we need to wade through and fix
- that. Unfortunately, since operator() is left-associative, we can't use
- tail recursion. In the above example, TYPE is `A', and DECL is
- `()()()()()'.
-
- Maybe this shouldn't be recursive, but how often will it actually be
- used? (jason) */
+/* 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. */
tree
-reparse_absdcl_as_expr (type, decl)
- tree type, decl;
-{
- /* do build_functional_cast (type, NULL_TREE) at bottom */
- if (TREE_OPERAND (decl, 0) == NULL_TREE)
- return build_functional_cast (type, NULL_TREE);
-
- /* recurse */
- decl = reparse_absdcl_as_expr (type, TREE_OPERAND (decl, 0));
-
- return finish_call_expr (decl, NULL_TREE, /*disallow_virtual=*/false);
-}
-
-/* This is something of the form `int ((int)(int)(int)1)' that has turned
- out to be an expr. Since it was parsed like a type, we need to wade
- through and fix that. Since casts are right-associative, we are
- reversing the order, so we don't have to recurse.
-
- In the above example, DECL is the `(int)(int)(int)', and EXPR is the
- `1'. */
-
-tree
-reparse_absdcl_as_casts (decl, expr)
- tree decl, expr;
+build_offset_ref_call_from_tree (tree fn, tree args)
{
- tree type;
- int non_void_p = 0;
-
- if (TREE_CODE (expr) == CONSTRUCTOR
- && TREE_TYPE (expr) == 0)
- {
- type = groktypename (TREE_VALUE (CALL_DECLARATOR_PARMS (decl)));
- decl = TREE_OPERAND (decl, 0);
-
- if (processing_template_decl)
- TREE_TYPE (expr) = type;
- else
- {
- expr = digest_init (type, expr, (tree *) 0);
- if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
- {
- int failure = complete_array_type (type, expr, 1);
- my_friendly_assert (!failure, 78);
- }
- }
- }
-
- while (decl)
- {
- type = groktypename (TREE_VALUE (CALL_DECLARATOR_PARMS (decl)));
- decl = TREE_OPERAND (decl, 0);
- if (!VOID_TYPE_P (type))
- non_void_p = 1;
- expr = build_c_cast (type, expr);
- }
+ tree orig_fn;
+ tree orig_args;
+ tree expr;
+ tree object;
- if (warn_old_style_cast && ! in_system_header
- && non_void_p && current_lang_name != lang_name_c)
- warning ("use of old-style cast");
+ orig_fn = fn;
+ orig_args = args;
+ object = TREE_OPERAND (fn, 0);
- return expr;
-}
-
-/* T is the parse tree for an expression. Return the expression after
- performing semantic analysis. */
-
-tree
-build_expr_from_tree (t)
- tree t;
-{
- if (t == NULL_TREE || t == error_mark_node)
- return t;
-
- switch (TREE_CODE (t))
+ if (processing_template_decl)
{
- case IDENTIFIER_NODE:
- return do_identifier (t, 0, NULL_TREE);
-
- case LOOKUP_EXPR:
- if (LOOKUP_EXPR_GLOBAL (t))
- {
- tree token = TREE_OPERAND (t, 0);
- return do_scoped_id (token, IDENTIFIER_GLOBAL_VALUE (token));
- }
- else
- return do_identifier (TREE_OPERAND (t, 0), 0, NULL_TREE);
-
- case TEMPLATE_ID_EXPR:
- {
- tree template;
- tree args;
- tree object;
-
- template = build_expr_from_tree (TREE_OPERAND (t, 0));
- args = build_expr_from_tree (TREE_OPERAND (t, 1));
-
- if (TREE_CODE (template) == COMPONENT_REF)
- {
- object = TREE_OPERAND (template, 0);
- template = TREE_OPERAND (template, 1);
- }
- else
- object = NULL_TREE;
-
- template = lookup_template_function (template, args);
- if (object)
- return build (COMPONENT_REF, TREE_TYPE (template),
- object, template);
- else
- return template;
- }
-
- case INDIRECT_REF:
- return build_x_indirect_ref
- (build_expr_from_tree (TREE_OPERAND (t, 0)), "unary *");
-
- case CAST_EXPR:
- return build_functional_cast
- (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
-
- case REINTERPRET_CAST_EXPR:
- return build_reinterpret_cast
- (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
-
- case CONST_CAST_EXPR:
- return build_const_cast
- (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
-
- case DYNAMIC_CAST_EXPR:
- return build_dynamic_cast
- (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
-
- case STATIC_CAST_EXPR:
- return build_static_cast
- (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0)));
-
- case PREDECREMENT_EXPR:
- case PREINCREMENT_EXPR:
- case POSTDECREMENT_EXPR:
- case POSTINCREMENT_EXPR:
- case NEGATE_EXPR:
- case BIT_NOT_EXPR:
- case ABS_EXPR:
- case TRUTH_NOT_EXPR:
- case ADDR_EXPR:
- case CONVERT_EXPR: /* Unary + */
- case REALPART_EXPR:
- case IMAGPART_EXPR:
- if (TREE_TYPE (t))
- return t;
- return build_x_unary_op (TREE_CODE (t),
- build_expr_from_tree (TREE_OPERAND (t, 0)));
-
- case PLUS_EXPR:
- case MINUS_EXPR:
- case MULT_EXPR:
- case TRUNC_DIV_EXPR:
- case CEIL_DIV_EXPR:
- case FLOOR_DIV_EXPR:
- case ROUND_DIV_EXPR:
- case EXACT_DIV_EXPR:
- case BIT_AND_EXPR:
- case BIT_ANDTC_EXPR:
- case BIT_IOR_EXPR:
- case BIT_XOR_EXPR:
- case TRUNC_MOD_EXPR:
- case FLOOR_MOD_EXPR:
- case TRUTH_ANDIF_EXPR:
- case TRUTH_ORIF_EXPR:
- case TRUTH_AND_EXPR:
- case TRUTH_OR_EXPR:
- case RSHIFT_EXPR:
- case LSHIFT_EXPR:
- case RROTATE_EXPR:
- case LROTATE_EXPR:
- case EQ_EXPR:
- case NE_EXPR:
- case MAX_EXPR:
- case MIN_EXPR:
- case LE_EXPR:
- case GE_EXPR:
- case LT_EXPR:
- case GT_EXPR:
- case MEMBER_REF:
- return build_x_binary_op
- (TREE_CODE (t),
- build_expr_from_tree (TREE_OPERAND (t, 0)),
- build_expr_from_tree (TREE_OPERAND (t, 1)));
-
- case DOTSTAR_EXPR:
- return build_m_component_ref
- (build_expr_from_tree (TREE_OPERAND (t, 0)),
- build_expr_from_tree (TREE_OPERAND (t, 1)));
-
- case SCOPE_REF:
- return build_offset_ref (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1));
-
- case ARRAY_REF:
- if (TREE_OPERAND (t, 0) == NULL_TREE)
- /* new-type-id */
- return build_nt (ARRAY_REF, NULL_TREE,
- build_expr_from_tree (TREE_OPERAND (t, 1)));
- return grok_array_decl (build_expr_from_tree (TREE_OPERAND (t, 0)),
- build_expr_from_tree (TREE_OPERAND (t, 1)));
-
- case SIZEOF_EXPR:
- case ALIGNOF_EXPR:
- {
- tree r = build_expr_from_tree (TREE_OPERAND (t, 0));
- if (!TYPE_P (r))
- return TREE_CODE (t) == SIZEOF_EXPR ? expr_sizeof (r) : c_alignof_expr (r);
- else
- return cxx_sizeof_or_alignof_type (r, TREE_CODE (t), true);
- }
-
- case MODOP_EXPR:
- return build_x_modify_expr
- (build_expr_from_tree (TREE_OPERAND (t, 0)),
- TREE_CODE (TREE_OPERAND (t, 1)),
- build_expr_from_tree (TREE_OPERAND (t, 2)));
-
- case ARROW_EXPR:
- return build_x_arrow
- (build_expr_from_tree (TREE_OPERAND (t, 0)));
-
- case NEW_EXPR:
- return build_new
- (build_expr_from_tree (TREE_OPERAND (t, 0)),
- build_expr_from_tree (TREE_OPERAND (t, 1)),
- build_expr_from_tree (TREE_OPERAND (t, 2)),
- NEW_EXPR_USE_GLOBAL (t));
-
- case DELETE_EXPR:
- return delete_sanity
- (build_expr_from_tree (TREE_OPERAND (t, 0)),
- build_expr_from_tree (TREE_OPERAND (t, 1)),
- DELETE_EXPR_USE_VEC (t), DELETE_EXPR_USE_GLOBAL (t));
-
- case COMPOUND_EXPR:
- if (TREE_OPERAND (t, 1) == NULL_TREE)
- return build_x_compound_expr
- (build_expr_from_tree (TREE_OPERAND (t, 0)));
- else
- abort ();
-
- case METHOD_CALL_EXPR:
- if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF)
- {
- tree ref = TREE_OPERAND (t, 0);
- tree name = TREE_OPERAND (ref, 1);
-
- if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- name = build_nt (TEMPLATE_ID_EXPR,
- TREE_OPERAND (name, 0),
- build_expr_from_tree (TREE_OPERAND (name, 1)));
-
- return build_scoped_method_call
- (build_expr_from_tree (TREE_OPERAND (t, 1)),
- build_expr_from_tree (TREE_OPERAND (ref, 0)),
- name,
- build_expr_from_tree (TREE_OPERAND (t, 2)));
- }
- else
- {
- tree fn = TREE_OPERAND (t, 0);
-
- /* We can get a TEMPLATE_ID_EXPR here on code like:
-
- x->f<2>();
-
- so we must resolve that. However, we can also get things
- like a BIT_NOT_EXPR here, when referring to a destructor,
- and things like that are not correctly resolved by
- build_expr_from_tree. So, just use build_expr_from_tree
- when we really need it. */
- if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
- fn = lookup_template_function
- (TREE_OPERAND (fn, 0),
- build_expr_from_tree (TREE_OPERAND (fn, 1)));
-
- return build_method_call
- (build_expr_from_tree (TREE_OPERAND (t, 1)),
- fn,
- build_expr_from_tree (TREE_OPERAND (t, 2)),
- NULL_TREE, LOOKUP_NORMAL);
- }
-
- case CALL_EXPR:
- if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF)
- {
- tree ref = TREE_OPERAND (t, 0);
- tree name = TREE_OPERAND (ref, 1);
- tree fn, scope, args;
-
- if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- name = build_nt (TEMPLATE_ID_EXPR,
- TREE_OPERAND (name, 0),
- build_expr_from_tree (TREE_OPERAND (name, 1)));
-
- scope = build_expr_from_tree (TREE_OPERAND (ref, 0));
- args = build_expr_from_tree (TREE_OPERAND (t, 1));
- fn = resolve_scoped_fn_name (scope, name);
-
- return build_call_from_tree (fn, args, 1);
- }
- else
- {
- tree name = TREE_OPERAND (t, 0);
- tree id;
- tree args = build_expr_from_tree (TREE_OPERAND (t, 1));
- if (args != NULL_TREE && TREE_CODE (name) == LOOKUP_EXPR
- && !LOOKUP_EXPR_GLOBAL (name)
- && TREE_CODE ((id = TREE_OPERAND (name, 0))) == IDENTIFIER_NODE
- && (!current_class_type
- || !lookup_member (current_class_type, id, 0, 0)))
- {
- /* Do Koenig lookup if there are no class members. */
- name = do_identifier (id, 0, args);
- }
- else if (TREE_CODE (name) == TEMPLATE_ID_EXPR
- || ! really_overloaded_fn (name))
- name = build_expr_from_tree (name);
-
- if (TREE_CODE (name) == OFFSET_REF)
- return build_offset_ref_call_from_tree (name, args);
- if (TREE_CODE (name) == COMPONENT_REF)
- return finish_object_call_expr (TREE_OPERAND (name, 1),
- TREE_OPERAND (name, 0),
- args);
- name = convert_from_reference (name);
- return build_call_from_tree (name, args,
- /*disallow_virtual=*/false);
- }
-
- case COND_EXPR:
- return build_x_conditional_expr
- (build_expr_from_tree (TREE_OPERAND (t, 0)),
- build_expr_from_tree (TREE_OPERAND (t, 1)),
- build_expr_from_tree (TREE_OPERAND (t, 2)));
-
- case PSEUDO_DTOR_EXPR:
- return (finish_pseudo_destructor_call_expr
- (build_expr_from_tree (TREE_OPERAND (t, 0)),
- build_expr_from_tree (TREE_OPERAND (t, 1)),
- build_expr_from_tree (TREE_OPERAND (t, 2))));
-
- case TREE_LIST:
- {
- tree purpose, value, chain;
-
- if (t == void_list_node)
- return t;
-
- purpose = TREE_PURPOSE (t);
- if (purpose)
- purpose = build_expr_from_tree (purpose);
- value = TREE_VALUE (t);
- if (value)
- value = build_expr_from_tree (value);
- chain = TREE_CHAIN (t);
- if (chain && chain != void_type_node)
- chain = build_expr_from_tree (chain);
- return tree_cons (purpose, value, chain);
- }
-
- case COMPONENT_REF:
- {
- tree object = build_expr_from_tree (TREE_OPERAND (t, 0));
- return finish_class_member_access_expr (object,
- TREE_OPERAND (t, 1));
- }
-
- case THROW_EXPR:
- return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0)));
-
- case CONSTRUCTOR:
- {
- tree r;
- tree elts;
- tree type = TREE_TYPE (t);
- bool purpose_p;
-
- /* digest_init will do the wrong thing if we let it. */
- if (type && TYPE_PTRMEMFUNC_P (type))
- return t;
-
- r = NULL_TREE;
- /* We do not want to process the purpose of aggregate
- initializers as they are identifier nodes which will be
- looked up by digest_init. */
- purpose_p = !(type && IS_AGGR_TYPE (type));
- for (elts = CONSTRUCTOR_ELTS (t); elts; elts = TREE_CHAIN (elts))
- {
- tree purpose = TREE_PURPOSE (elts);
- tree value = TREE_VALUE (elts);
-
- if (purpose && purpose_p)
- purpose = build_expr_from_tree (purpose);
- value = build_expr_from_tree (value);
- r = tree_cons (purpose, value, r);
- }
-
- r = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (r));
- TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
-
- if (type)
- return digest_init (type, r, 0);
- return r;
- }
-
- case TYPEID_EXPR:
- if (TYPE_P (TREE_OPERAND (t, 0)))
- return get_typeid (TREE_OPERAND (t, 0));
- return build_typeid (build_expr_from_tree (TREE_OPERAND (t, 0)));
-
- case VAR_DECL:
- return convert_from_reference (t);
+ my_friendly_assert (TREE_CODE (fn) == DOTSTAR_EXPR
+ || TREE_CODE (fn) == MEMBER_REF,
+ 20030708);
+ if (type_dependent_expression_p (fn)
+ || any_type_dependent_arguments_p (args))
+ return build_min_nt (CALL_EXPR, fn, args);
- case VA_ARG_EXPR:
- return build_va_arg (build_expr_from_tree (TREE_OPERAND (t, 0)),
- TREE_TYPE (t));
-
- default:
- return t;
+ /* 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);
+ if (TREE_CODE (fn) == DOTSTAR_EXPR)
+ object = build_unary_op (ADDR_EXPR, object, 0);
+ object = build_non_dependent_expr (object);
+ args = tree_cons (NULL_TREE, object, args);
+ /* Now that the arguments are done, transform FN. */
+ fn = build_non_dependent_expr (fn);
}
-}
-
-/* FN is an OFFSET_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
- analzyed. */
-
-tree
-build_offset_ref_call_from_tree (tree fn, tree args)
-{
- tree object_addr;
-
- my_friendly_assert (TREE_CODE (fn) == OFFSET_REF, 20020725);
- /* A qualified name corresponding to a non-static member
- function or a pointer-to-member is represented as an
- OFFSET_REF.
-
- For both of these function calls, FN will be an OFFSET_REF.
-
- struct A { void f(); };
- void A::f() { (A::f) (); }
+ /* A qualified name corresponding to a bound pointer-to-member is
+ represented as an OFFSET_REF:
struct B { void g(); };
void (B::*p)();
void B::g() { (this->*p)(); } */
-
- /* This code is not really correct (for example, it does not
- handle the case that `A::f' is overloaded), but it is
- historically how we have handled this situation. */
- if (TREE_CODE (TREE_OPERAND (fn, 1)) == FIELD_DECL)
- fn = resolve_offset_ref (fn);
- else
+ if (TREE_CODE (fn) == OFFSET_REF)
{
- object_addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (fn, 0), 0);
+ tree object_addr = build_unary_op (ADDR_EXPR, object, 0);
fn = TREE_OPERAND (fn, 1);
fn = get_member_function_from_ptrfunc (&object_addr, fn);
args = tree_cons (NULL_TREE, object_addr, args);
}
- return build_function_call (fn, args);
-}
-
-/* FN indicates the function to call. Name resolution has been
- performed on FN. ARGS are the arguments to the function. They
- have already been semantically analyzed. DISALLOW_VIRTUAL is true
- if the function call should be determined at compile time, even if
- FN is virtual. */
-
-tree
-build_call_from_tree (tree fn, tree args, bool disallow_virtual)
-{
- tree template_args;
- tree template_id;
- tree f;
-
- /* Check to see that name lookup has already been performed. */
- my_friendly_assert (TREE_CODE (fn) != OFFSET_REF, 20020725);
- my_friendly_assert (TREE_CODE (fn) != SCOPE_REF, 20020725);
-
- /* In the future all of this should be eliminated. Instead,
- name-lookup for a member function should simply return a
- baselink, instead of a FUNCTION_DECL, TEMPLATE_DECL, or
- TEMPLATE_ID_EXPR. */
-
- if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
- {
- template_id = fn;
- template_args = TREE_OPERAND (fn, 1);
- fn = TREE_OPERAND (fn, 0);
- }
- else
- {
- template_id = NULL_TREE;
- template_args = NULL_TREE;
- }
-
- f = (TREE_CODE (fn) == OVERLOAD) ? get_first_fn (fn) : fn;
- /* Make sure we have a baselink (rather than simply a
- FUNCTION_DECL) for a member function. */
- if (current_class_type
- && ((TREE_CODE (f) == FUNCTION_DECL
- && DECL_FUNCTION_MEMBER_P (f))
- || (DECL_FUNCTION_TEMPLATE_P (f)
- && DECL_FUNCTION_MEMBER_P (f))))
- {
- f = lookup_member (current_class_type, DECL_NAME (f),
- /*protect=*/1, /*want_type=*/0);
- if (f)
- fn = f;
- }
-
- if (template_id)
- {
- if (BASELINK_P (fn))
- BASELINK_FUNCTIONS (fn) = build_nt (TEMPLATE_ID_EXPR,
- BASELINK_FUNCTIONS (fn),
- template_args);
- else
- fn = template_id;
- }
-
- return finish_call_expr (fn, args, disallow_virtual);
-}
-
-/* This is something of the form `int (*a)++' that has turned out to be an
- expr. It was only converted into parse nodes, so we need to go through
- and build up the semantics. Most of the work is done by
- build_expr_from_tree, above.
-
- In the above example, TYPE is `int' and DECL is `*a'. */
-
-tree
-reparse_decl_as_expr (type, decl)
- tree type, decl;
-{
- decl = build_expr_from_tree (decl);
- if (type)
- return build_functional_cast (type, build_tree_list (NULL_TREE, decl));
- else
- return decl;
-}
-
-/* This is something of the form `int (*a)' that has turned out to be a
- decl. It was only converted into parse nodes, so we need to do the
- checking that make_{pointer,reference}_declarator do. */
-
-tree
-finish_decl_parsing (decl)
- tree decl;
-{
- switch (TREE_CODE (decl))
- {
- case IDENTIFIER_NODE:
- return decl;
- case INDIRECT_REF:
- return make_pointer_declarator
- (NULL_TREE, finish_decl_parsing (TREE_OPERAND (decl, 0)));
- case ADDR_EXPR:
- return make_reference_declarator
- (NULL_TREE, finish_decl_parsing (TREE_OPERAND (decl, 0)));
- case BIT_NOT_EXPR:
- TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0));
- return decl;
- case SCOPE_REF:
- push_nested_class (TREE_TYPE (TREE_OPERAND (decl, 0)), 3);
- TREE_COMPLEXITY (decl) = current_class_depth;
- return decl;
- case ARRAY_REF:
- TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0));
- return decl;
- case TREE_LIST:
- /* For attribute handling. */
- TREE_VALUE (decl) = finish_decl_parsing (TREE_VALUE (decl));
- return decl;
- case TEMPLATE_ID_EXPR:
- return decl;
- default:
- abort ();
- return NULL_TREE;
- }
-}
-
-/* Returns true if ROOT (a namespace, class, or function) encloses
- CHILD. CHILD may be either a class type or a namespace. */
-
-bool
-is_ancestor (tree root, tree child)
-{
- my_friendly_assert ((TREE_CODE (root) == NAMESPACE_DECL
- || TREE_CODE (root) == FUNCTION_DECL
- || CLASS_TYPE_P (root)), 20030307);
- my_friendly_assert ((TREE_CODE (child) == NAMESPACE_DECL
- || TREE_CODE (root) == FUNCTION_DECL
- || CLASS_TYPE_P (child)),
- 20030307);
-
- /* The global namespace encloses everything. */
- if (root == global_namespace)
- return true;
-
- while (true)
- {
- /* If we've run out of scopes, stop. */
- if (!child)
- return false;
- /* If we've reached the ROOT, it encloses CHILD. */
- if (root == child)
- return true;
- /* Go out one level. */
- if (TYPE_P (child))
- child = TYPE_NAME (child);
- child = DECL_CONTEXT (child);
- }
-}
-
-/* Return the namespace that is the common ancestor
- of two given namespaces. */
-
-tree
-namespace_ancestor (ns1, ns2)
- tree ns1, ns2;
-{
- timevar_push (TV_NAME_LOOKUP);
- if (is_ancestor (ns1, ns2))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ns1);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
- namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2));
-}
-
-/* Insert used into the using list of user. Set indirect_flag if this
- directive is not directly from the source. Also find the common
- ancestor and let our users know about the new namespace */
-static void
-add_using_namespace (user, used, indirect)
- tree user;
- tree used;
- int indirect;
-{
- tree t;
- timevar_push (TV_NAME_LOOKUP);
- /* Using oneself is a no-op. */
- if (user == used)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0);
- my_friendly_assert (TREE_CODE (user) == NAMESPACE_DECL, 380);
- my_friendly_assert (TREE_CODE (used) == NAMESPACE_DECL, 380);
- /* Check if we already have this. */
- t = purpose_member (used, DECL_NAMESPACE_USING (user));
- if (t != NULL_TREE)
- {
- if (!indirect)
- /* Promote to direct usage. */
- TREE_INDIRECT_USING (t) = 0;
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (void)0);
- }
- /* Add used to the user's using list. */
- DECL_NAMESPACE_USING (user)
- = tree_cons (used, namespace_ancestor (user, used),
- DECL_NAMESPACE_USING (user));
-
- TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
-
- /* Add user to the used's users list. */
- DECL_NAMESPACE_USERS (used)
- = tree_cons (user, 0, DECL_NAMESPACE_USERS (used));
-
- /* Recursively add all namespaces used. */
- for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t))
- /* indirect usage */
- add_using_namespace (user, TREE_PURPOSE (t), 1);
-
- /* Tell everyone using us about the new used namespaces. */
- for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t))
- add_using_namespace (TREE_PURPOSE (t), used, 1);
- timevar_pop (TV_NAME_LOOKUP);
-}
-
-/* Combines two sets of overloaded functions into an OVERLOAD chain, removing
- duplicates. The first list becomes the tail of the result.
-
- The algorithm is O(n^2). We could get this down to O(n log n) by
- doing a sort on the addresses of the functions, if that becomes
- necessary. */
-
-static tree
-merge_functions (s1, s2)
- tree s1;
- tree s2;
-{
- for (; s2; s2 = OVL_NEXT (s2))
- {
- tree fn2 = OVL_CURRENT (s2);
- tree fns1;
-
- for (fns1 = s1; fns1; fns1 = OVL_NEXT (fns1))
- {
- tree fn1 = OVL_CURRENT (fns1);
-
- /* If the function from S2 is already in S1, there is no
- need to add it again. For `extern "C"' functions, we
- might have two FUNCTION_DECLs for the same function, in
- different namespaces; again, we only need one of them. */
- if (fn1 == fn2
- || (DECL_EXTERN_C_P (fn1) && DECL_EXTERN_C_P (fn2)
- && DECL_NAME (fn1) == DECL_NAME (fn2)))
- break;
- }
-
- /* If we exhausted all of the functions in S1, FN2 is new. */
- if (!fns1)
- s1 = build_overload (fn2, s1);
- }
- return s1;
-}
-
-/* This should return an error not all definitions define functions.
- It is not an error if we find two functions with exactly the
- same signature, only if these are selected in overload resolution.
- old is the current set of bindings, new the freshly-found binding.
- XXX Do we want to give *all* candidates in case of ambiguity?
- XXX In what way should I treat extern declarations?
- XXX I don't want to repeat the entire duplicate_decls here */
-
-static cxx_binding *
-ambiguous_decl (tree name, cxx_binding *old, cxx_binding *new, int flags)
-{
- tree val, type;
- my_friendly_assert (old != NULL, 393);
- /* Copy the value. */
- val = BINDING_VALUE (new);
- if (val)
- switch (TREE_CODE (val))
- {
- case TEMPLATE_DECL:
- /* If we expect types or namespaces, and not templates,
- or this is not a template class. */
- if (LOOKUP_QUALIFIERS_ONLY (flags)
- && !DECL_CLASS_TEMPLATE_P (val))
- val = NULL_TREE;
- break;
- case TYPE_DECL:
- if (LOOKUP_NAMESPACES_ONLY (flags))
- val = NULL_TREE;
- break;
- case NAMESPACE_DECL:
- if (LOOKUP_TYPES_ONLY (flags))
- val = NULL_TREE;
- break;
- case FUNCTION_DECL:
- /* Ignore built-in functions that are still anticipated. */
- if (LOOKUP_QUALIFIERS_ONLY (flags) || DECL_ANTICIPATED (val))
- val = NULL_TREE;
- break;
- default:
- if (LOOKUP_QUALIFIERS_ONLY (flags))
- val = NULL_TREE;
- }
-
- if (!BINDING_VALUE (old))
- BINDING_VALUE (old) = val;
- else if (val && val != BINDING_VALUE (old))
- {
- if (is_overloaded_fn (BINDING_VALUE (old))
- && is_overloaded_fn (val))
- {
- BINDING_VALUE (old) = merge_functions (BINDING_VALUE (old),
- val);
- }
- else
- {
- /* Some declarations are functions, some are not. */
- if (flags & LOOKUP_COMPLAIN)
- {
- /* If we've already given this error for this lookup,
- BINDING_VALUE (old) is error_mark_node, so let's not
- repeat ourselves. */
- if (BINDING_VALUE (old) != error_mark_node)
- {
- error ("use of `%D' is ambiguous", name);
- cp_error_at (" first declared as `%#D' here",
- BINDING_VALUE (old));
- }
- cp_error_at (" also declared as `%#D' here", val);
- }
- BINDING_VALUE (old) = error_mark_node;
- }
- }
- /* ... and copy the type. */
- type = BINDING_TYPE (new);
- if (LOOKUP_NAMESPACES_ONLY (flags))
- type = NULL_TREE;
- if (!BINDING_TYPE (old))
- BINDING_TYPE (old) = type;
- else if (type && BINDING_TYPE (old) != type)
- {
- if (flags & LOOKUP_COMPLAIN)
- {
- error ("`%D' denotes an ambiguous type",name);
- cp_error_at (" first type here", BINDING_TYPE (old));
- cp_error_at (" other type here", type);
- }
- }
- return old;
-}
-
-/* Subroutine of unualified_namespace_lookup:
- Add the bindings of NAME in used namespaces to VAL.
- We are currently looking for names in namespace SCOPE, so we
- look through USINGS for using-directives of namespaces
- which have SCOPE as a common ancestor with the current scope.
- Returns zero on errors. */
-
-bool
-lookup_using_namespace (tree name, cxx_binding *val, tree usings,
- tree scope, int flags, tree *spacesp)
-{
- tree iter;
- cxx_binding *val1;
- timevar_push (TV_NAME_LOOKUP);
- /* Iterate over all used namespaces in current, searching for using
- directives of scope. */
- for (iter = usings; iter; iter = TREE_CHAIN (iter))
- if (TREE_VALUE (iter) == scope)
- {
- if (spacesp)
- *spacesp = tree_cons (TREE_PURPOSE (iter), NULL_TREE,
- *spacesp);
- val1 = cxx_scope_find_binding_for_name (TREE_PURPOSE (iter), name);
- /* Resolve possible ambiguities. */
- if (val1)
- val = ambiguous_decl (name, val, val1, flags);
- }
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
- BINDING_VALUE (val) != error_mark_node);
-}
-
-/* [namespace.qual]
- Accepts the NAME to lookup and its qualifying SCOPE.
- Returns the name/type pair found into the cxx_binding *RESULT,
- or 0 on error. */
-
-bool
-qualified_lookup_using_namespace (tree name, tree scope, cxx_binding *result,
- int flags)
-{
- /* Maintain a list of namespaces visited... */
- tree seen = NULL_TREE;
- /* ... and a list of namespace yet to see. */
- tree todo = NULL_TREE;
- tree usings;
- timevar_push (TV_NAME_LOOKUP);
- /* Look through namespace aliases. */
- scope = ORIGINAL_NAMESPACE (scope);
- while (scope && result->value != error_mark_node)
- {
- cxx_binding *b = cxx_scope_find_binding_for_name (scope, name);
- /* Record SCOPE and resolve declaration ambiguities if NAME was
- bound in SCOPE. */
- if (b)
- {
- seen = tree_cons (scope, NULL_TREE, seen);
- result = ambiguous_decl (name, result, b, flags);
- }
- if (!BINDING_VALUE (result) && !BINDING_TYPE (result))
- /* Consider using directives. */
- for (usings = DECL_NAMESPACE_USING (scope); usings;
- usings = TREE_CHAIN (usings))
- /* If this was a real directive, and we have not seen it. */
- if (!TREE_INDIRECT_USING (usings)
- && !purpose_member (TREE_PURPOSE (usings), seen))
- todo = tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo);
- if (todo)
- {
- scope = TREE_PURPOSE (todo);
- todo = TREE_CHAIN (todo);
- }
- else
- scope = NULL_TREE; /* If there never was a todo list. */
- }
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
-}
-
-/* [namespace.memdef]/2 */
-
-/* Set the context of a declaration to scope. Complain if we are not
- outside scope. */
-
-void
-set_decl_namespace (decl, scope, friendp)
- tree decl;
- tree scope;
- int friendp;
-{
- tree old;
-
- /* Get rid of namespace aliases. */
- scope = ORIGINAL_NAMESPACE (scope);
-
- /* It is ok for friends to be qualified in parallel space. */
- if (!friendp && !is_ancestor (current_namespace, scope))
- error ("declaration of `%D' not in a namespace surrounding `%D'",
- decl, scope);
- DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
- if (scope != current_namespace)
- {
- /* See whether this has been declared in the namespace. */
- old = namespace_binding (DECL_NAME (decl), scope);
- if (!old)
- /* No old declaration at all. */
- goto complain;
- /* A template can be explicitly specialized in any namespace. */
- if (processing_explicit_instantiation)
- return;
- if (!is_overloaded_fn (decl))
- /* Don't compare non-function decls with decls_match here,
- since it can't check for the correct constness at this
- point. pushdecl will find those errors later. */
- return;
- /* Since decl is a function, old should contain a function decl. */
- if (!is_overloaded_fn (old))
- goto complain;
- if (processing_template_decl || processing_specialization)
- /* We have not yet called push_template_decl to turn the
- FUNCTION_DECL into a TEMPLATE_DECL, so the declarations
- won't match. But, we'll check later, when we construct the
- template. */
- return;
- for (; old; old = OVL_NEXT (old))
- if (decls_match (decl, OVL_CURRENT (old)))
- return;
- }
- else
- return;
- complain:
- error ("`%D' should have been declared inside `%D'",
- decl, scope);
-}
-
-/* Compute the namespace where a declaration is defined. */
-
-static tree
-decl_namespace (decl)
- tree decl;
-{
- timevar_push (TV_NAME_LOOKUP);
- if (TYPE_P (decl))
- decl = TYPE_STUB_DECL (decl);
- while (DECL_CONTEXT (decl))
- {
- decl = DECL_CONTEXT (decl);
- if (TREE_CODE (decl) == NAMESPACE_DECL)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
- if (TYPE_P (decl))
- decl = TYPE_STUB_DECL (decl);
- my_friendly_assert (DECL_P (decl), 390);
- }
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, global_namespace);
-}
-
-/* Return the namespace where the current declaration is declared. */
-
-tree
-current_decl_namespace ()
-{
- tree result;
- /* If we have been pushed into a different namespace, use it. */
- if (decl_namespace_list)
- return TREE_PURPOSE (decl_namespace_list);
-
- if (current_class_type)
- result = decl_namespace (TYPE_STUB_DECL (current_class_type));
- else if (current_function_decl)
- result = decl_namespace (current_function_decl);
- else
- result = current_namespace;
- return result;
-}
-
-/* Temporarily set the namespace for the current declaration. */
-
-void
-push_decl_namespace (decl)
- tree decl;
-{
- if (TREE_CODE (decl) != NAMESPACE_DECL)
- decl = decl_namespace (decl);
- decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl),
- NULL_TREE, decl_namespace_list);
-}
-
-void
-pop_decl_namespace ()
-{
- decl_namespace_list = TREE_CHAIN (decl_namespace_list);
-}
-
-/* Enter a class or namespace scope. */
-
-void
-push_scope (t)
- tree t;
-{
- if (TREE_CODE (t) == NAMESPACE_DECL)
- push_decl_namespace (t);
- else if (CLASS_TYPE_P (t))
- pushclass (t, 2);
-}
-
-/* Leave scope pushed by push_scope. */
-
-void
-pop_scope (t)
- tree t;
-{
- if (TREE_CODE (t) == NAMESPACE_DECL)
- pop_decl_namespace ();
- else if (CLASS_TYPE_P (t))
- popclass ();
-}
-
-/* [basic.lookup.koenig] */
-/* A nonzero return value in the functions below indicates an error. */
-
-struct arg_lookup
-{
- tree name;
- tree namespaces;
- tree classes;
- tree functions;
-};
-
-static int arg_assoc PARAMS ((struct arg_lookup*, tree));
-static int arg_assoc_args PARAMS ((struct arg_lookup*, tree));
-static int arg_assoc_type PARAMS ((struct arg_lookup*, tree));
-static int add_function PARAMS ((struct arg_lookup *, tree));
-static int arg_assoc_namespace PARAMS ((struct arg_lookup *, tree));
-static int arg_assoc_class PARAMS ((struct arg_lookup *, tree));
-static int arg_assoc_template_arg PARAMS ((struct arg_lookup*, tree));
-
-/* Add a function to the lookup structure.
- Returns 1 on error. */
-
-static int
-add_function (k, fn)
- struct arg_lookup *k;
- tree fn;
-{
- /* We used to check here to see if the function was already in the list,
- but that's O(n^2), which is just too expensive for function lookup.
- Now we deal with the occasional duplicate in joust. In doing this, we
- assume that the number of duplicates will be small compared to the
- total number of functions being compared, which should usually be the
- case. */
-
- /* We must find only functions, or exactly one non-function. */
- if (!k->functions)
- k->functions = fn;
- else if (fn == k->functions)
- ;
- else if (is_overloaded_fn (k->functions) && is_overloaded_fn (fn))
- k->functions = build_overload (fn, k->functions);
- else
- {
- tree f1 = OVL_CURRENT (k->functions);
- tree f2 = fn;
- if (is_overloaded_fn (f1))
- {
- fn = f1; f1 = f2; f2 = fn;
- }
- cp_error_at ("`%D' is not a function,", f1);
- cp_error_at (" conflict with `%D'", f2);
- error (" in call to `%D'", k->name);
- return 1;
- }
-
- return 0;
-}
-
-/* Add functions of a namespace to the lookup structure.
- Returns 1 on error. */
-
-static int
-arg_assoc_namespace (k, scope)
- struct arg_lookup *k;
- tree scope;
-{
- tree value;
-
- if (purpose_member (scope, k->namespaces))
- return 0;
- k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces);
-
- value = namespace_binding (k->name, scope);
- if (!value)
- return 0;
-
- for (; value; value = OVL_NEXT (value))
- if (add_function (k, OVL_CURRENT (value)))
- return 1;
-
- return 0;
-}
-
-/* Adds everything associated with a template argument to the lookup
- structure. Returns 1 on error. */
-
-static int
-arg_assoc_template_arg (k, arg)
- struct arg_lookup* k;
- tree arg;
-{
- /* [basic.lookup.koenig]
-
- If T is a template-id, its associated namespaces and classes are
- ... the namespaces and classes associated with the types of the
- template arguments provided for template type parameters
- (excluding template template parameters); the namespaces in which
- any template template arguments are defined; and the classes in
- which any member templates used as template template arguments
- are defined. [Note: non-type template arguments do not
- contribute to the set of associated namespaces. ] */
-
- /* Consider first template template arguments. */
- if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
- || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)
- return 0;
- else if (TREE_CODE (arg) == TEMPLATE_DECL)
- {
- tree ctx = CP_DECL_CONTEXT (arg);
-
- /* It's not a member template. */
- if (TREE_CODE (ctx) == NAMESPACE_DECL)
- return arg_assoc_namespace (k, ctx);
- /* Otherwise, it must be member template. */
- else
- return arg_assoc_class (k, ctx);
- }
- /* It's not a template template argument, but it is a type template
- argument. */
- else if (TYPE_P (arg))
- return arg_assoc_type (k, arg);
- /* It's a non-type template argument. */
- else
- return 0;
-}
-
-/* Adds everything associated with class to the lookup structure.
- Returns 1 on error. */
-
-static int
-arg_assoc_class (k, type)
- struct arg_lookup* k;
- tree type;
-{
- tree list, friends, context;
- int i;
-
- /* Backend build structures, such as __builtin_va_list, aren't
- affected by all this. */
- if (!CLASS_TYPE_P (type))
- return 0;
-
- if (purpose_member (type, k->classes))
- return 0;
- k->classes = tree_cons (type, NULL_TREE, k->classes);
-
- context = decl_namespace (TYPE_MAIN_DECL (type));
- if (arg_assoc_namespace (k, context))
- return 1;
-
- /* Process baseclasses. */
- for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); i++)
- if (arg_assoc_class (k, TYPE_BINFO_BASETYPE (type, i)))
- return 1;
-
- /* Process friends. */
- for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
- list = TREE_CHAIN (list))
- if (k->name == TREE_PURPOSE (list))
- for (friends = TREE_VALUE (list); friends;
- friends = TREE_CHAIN (friends))
- /* Only interested in global functions with potentially hidden
- (i.e. unqualified) declarations. */
- if (TREE_PURPOSE (friends) == error_mark_node && TREE_VALUE (friends)
- && CP_DECL_CONTEXT (TREE_VALUE (friends)) == context)
- if (add_function (k, TREE_VALUE (friends)))
- return 1;
-
- /* Process template arguments. */
- if (CLASSTYPE_TEMPLATE_INFO (type))
- {
- list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
- for (i = 0; i < TREE_VEC_LENGTH (list); ++i)
- arg_assoc_template_arg (k, TREE_VEC_ELT (list, i));
- }
-
- return 0;
-}
-
-/* Adds everything associated with a given type.
- Returns 1 on error. */
-
-static int
-arg_assoc_type (k, type)
- struct arg_lookup *k;
- tree type;
-{
- switch (TREE_CODE (type))
- {
- case VOID_TYPE:
- case INTEGER_TYPE:
- case REAL_TYPE:
- case COMPLEX_TYPE:
- case VECTOR_TYPE:
- case CHAR_TYPE:
- case BOOLEAN_TYPE:
- return 0;
- case RECORD_TYPE:
- if (TYPE_PTRMEMFUNC_P (type))
- return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type));
- return arg_assoc_class (k, type);
- case POINTER_TYPE:
- case REFERENCE_TYPE:
- case ARRAY_TYPE:
- return arg_assoc_type (k, TREE_TYPE (type));
- case UNION_TYPE:
- case ENUMERAL_TYPE:
- return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type)));
- case OFFSET_TYPE:
- /* Pointer to member: associate class type and value type. */
- if (arg_assoc_type (k, TYPE_OFFSET_BASETYPE (type)))
- return 1;
- return arg_assoc_type (k, TREE_TYPE (type));
- case METHOD_TYPE:
- /* The basetype is referenced in the first arg type, so just
- fall through. */
- case FUNCTION_TYPE:
- /* Associate the parameter types. */
- if (arg_assoc_args (k, TYPE_ARG_TYPES (type)))
- return 1;
- /* Associate the return type. */
- return arg_assoc_type (k, TREE_TYPE (type));
- case TEMPLATE_TYPE_PARM:
- case BOUND_TEMPLATE_TEMPLATE_PARM:
- return 0;
- case TYPENAME_TYPE:
- return 0;
- case LANG_TYPE:
- if (type == unknown_type_node)
- return 0;
- /* else fall through */
- default:
- abort ();
- }
- return 0;
-}
-
-/* Adds everything associated with arguments. Returns 1 on error. */
-
-static int
-arg_assoc_args (k, args)
- struct arg_lookup* k;
- tree args;
-{
- for (; args; args = TREE_CHAIN (args))
- if (arg_assoc (k, TREE_VALUE (args)))
- return 1;
- return 0;
-}
-
-/* Adds everything associated with a given tree_node. Returns 1 on error. */
-
-static int
-arg_assoc (k, n)
- struct arg_lookup* k;
- tree n;
-{
- if (n == error_mark_node)
- return 0;
-
- if (TYPE_P (n))
- return arg_assoc_type (k, n);
-
- if (! type_unknown_p (n))
- return arg_assoc_type (k, TREE_TYPE (n));
-
- if (TREE_CODE (n) == ADDR_EXPR)
- n = TREE_OPERAND (n, 0);
- if (TREE_CODE (n) == COMPONENT_REF)
- n = TREE_OPERAND (n, 1);
- if (TREE_CODE (n) == OFFSET_REF)
- n = TREE_OPERAND (n, 1);
- while (TREE_CODE (n) == TREE_LIST)
- n = TREE_VALUE (n);
- if (TREE_CODE (n) == BASELINK)
- n = BASELINK_FUNCTIONS (n);
-
- if (TREE_CODE (n) == FUNCTION_DECL)
- return arg_assoc_type (k, TREE_TYPE (n));
- if (TREE_CODE (n) == TEMPLATE_ID_EXPR)
- {
- /* [basic.lookup.koenig]
-
- If T is a template-id, its associated namespaces and classes
- are the namespace in which the template is defined; for
- member templates, the member template's class... */
- tree template = TREE_OPERAND (n, 0);
- tree args = TREE_OPERAND (n, 1);
- tree ctx;
- tree arg;
-
- if (TREE_CODE (template) == COMPONENT_REF)
- template = TREE_OPERAND (template, 1);
-
- /* First, the template. There may actually be more than one if
- this is an overloaded function template. But, in that case,
- we only need the first; all the functions will be in the same
- namespace. */
- template = OVL_CURRENT (template);
-
- ctx = CP_DECL_CONTEXT (template);
-
- if (TREE_CODE (ctx) == NAMESPACE_DECL)
- {
- if (arg_assoc_namespace (k, ctx) == 1)
- return 1;
- }
- /* It must be a member template. */
- else if (arg_assoc_class (k, ctx) == 1)
- return 1;
-
- /* Now the arguments. */
- for (arg = args; arg != NULL_TREE; arg = TREE_CHAIN (arg))
- if (arg_assoc_template_arg (k, TREE_VALUE (arg)) == 1)
- return 1;
- }
- else
- {
- my_friendly_assert (TREE_CODE (n) == OVERLOAD, 980715);
-
- for (; n; n = OVL_CHAIN (n))
- if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n))))
- return 1;
- }
-
- return 0;
-}
-
-/* Performs Koenig lookup depending on arguments, where fns
- are the functions found in normal lookup. */
-
-tree
-lookup_arg_dependent (name, fns, args)
- tree name;
- tree fns;
- tree args;
-{
- struct arg_lookup k;
- tree fn = NULL_TREE;
-
- if (fns == error_mark_node)
- fns = NULL_TREE;
-
- timevar_push (TV_NAME_LOOKUP);
- k.name = name;
- k.functions = fns;
- k.classes = NULL_TREE;
-
- /* Note that we've already looked at some namespaces during normal
- unqualified lookup, unless we found a decl in function scope. */
- if (fns)
- fn = OVL_CURRENT (fns);
- if (fn && TREE_CODE (fn) == FUNCTION_DECL && DECL_LOCAL_FUNCTION_P (fn))
- k.namespaces = NULL_TREE;
- else
- unqualified_namespace_lookup (name, 0, &k.namespaces);
-
- arg_assoc_args (&k, args);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, k.functions);
-}
-
-/* Process a namespace-alias declaration. */
-
-void
-do_namespace_alias (alias, namespace)
- tree alias, namespace;
-{
- if (TREE_CODE (namespace) != NAMESPACE_DECL)
- {
- /* The parser did not find it, so it's not there. */
- error ("unknown namespace `%D'", namespace);
- return;
- }
-
- namespace = ORIGINAL_NAMESPACE (namespace);
-
- /* Build the alias. */
- alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
- DECL_NAMESPACE_ALIAS (alias) = namespace;
- pushdecl (alias);
-}
-
-/* Check a non-member using-declaration. Return the name and scope
- being used, and the USING_DECL, or NULL_TREE on failure. */
-
-static tree
-validate_nonmember_using_decl (decl, scope, name)
- tree decl;
- tree *scope;
- tree *name;
-{
- if (TREE_CODE (decl) == SCOPE_REF)
- {
- *scope = TREE_OPERAND (decl, 0);
- *name = TREE_OPERAND (decl, 1);
-
- if (!processing_template_decl)
- {
- /* [namespace.udecl]
- A using-declaration for a class member shall be a
- member-declaration. */
- if(TREE_CODE (*scope) != NAMESPACE_DECL)
- {
- if (TYPE_P (*scope))
- error ("`%T' is not a namespace", *scope);
- else
- error ("`%D' is not a namespace", *scope);
- return NULL_TREE;
- }
-
- /* 7.3.3/5
- A using-declaration shall not name a template-id. */
- if (TREE_CODE (*name) == TEMPLATE_ID_EXPR)
- {
- *name = TREE_OPERAND (*name, 0);
- error ("a using-declaration cannot specify a template-id. Try `using %D'", *name);
- return NULL_TREE;
- }
- }
- }
- else if (TREE_CODE (decl) == IDENTIFIER_NODE
- || TREE_CODE (decl) == TYPE_DECL
- || TREE_CODE (decl) == TEMPLATE_DECL)
- {
- *scope = global_namespace;
- *name = decl;
- }
- else if (TREE_CODE (decl) == NAMESPACE_DECL)
- {
- error ("namespace `%D' not allowed in using-declaration", decl);
- return NULL_TREE;
- }
- else
- abort ();
- if (DECL_P (*name))
- *name = DECL_NAME (*name);
- /* Make a USING_DECL. */
- return push_using_decl (*scope, *name);
-}
-
-/* Process local and global using-declarations. */
-
-static void
-do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
- tree scope, name;
- tree oldval, oldtype;
- tree *newval, *newtype;
-{
- cxx_binding decls;
-
- *newval = *newtype = NULL_TREE;
- cxx_binding_clear (&decls);
- if (!qualified_lookup_using_namespace (name, scope, &decls, 0))
- /* Lookup error */
- return;
-
- if (!decls.value && !decls.type)
- {
- error ("`%D' not declared", name);
- return;
- }
-
- /* Check for using functions. */
- if (decls.value && is_overloaded_fn (decls.value))
- {
- tree tmp, tmp1;
-
- if (oldval && !is_overloaded_fn (oldval))
- {
- if (!DECL_IMPLICIT_TYPEDEF_P (oldval))
- error ("`%D' is already declared in this scope", name);
- oldval = NULL_TREE;
- }
-
- *newval = oldval;
- for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
- {
- tree new_fn = OVL_CURRENT (tmp);
-
- /* [namespace.udecl]
-
- If a function declaration in namespace scope or block
- scope has the same name and the same parameter types as a
- function introduced by a using declaration the program is
- ill-formed. */
- for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
- {
- tree old_fn = OVL_CURRENT (tmp1);
-
- if (new_fn == old_fn)
- /* The function already exists in the current namespace. */
- break;
- else if (OVL_USED (tmp1))
- continue; /* this is a using decl */
- else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
- TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
- {
- /* There was already a non-using declaration in
- this scope with the same parameter types. If both
- are the same extern "C" functions, that's ok. */
- if (decls_match (new_fn, old_fn))
- {
- /* If the OLD_FN was a builtin, there is now a
- real declaration. */
- if (DECL_ANTICIPATED (old_fn))
- DECL_ANTICIPATED (old_fn) = 0;
- break;
- }
- else if (!DECL_ANTICIPATED (old_fn))
- {
- /* If the OLD_FN was really declared, the
- declarations don't match. */
- error ("`%D' is already declared in this scope", name);
- break;
- }
-
- /* If the OLD_FN was not really there, just ignore
- it and keep going. */
- }
- }
-
- /* If we broke out of the loop, there's no reason to add
- this function to the using declarations for this
- scope. */
- if (tmp1)
- continue;
-
- *newval = build_overload (OVL_CURRENT (tmp), *newval);
- if (TREE_CODE (*newval) != OVERLOAD)
- *newval = ovl_cons (*newval, NULL_TREE);
- OVL_USED (*newval) = 1;
- }
- }
- else
- {
- *newval = decls.value;
- if (oldval && !decls_match (*newval, oldval))
- error ("`%D' is already declared in this scope", name);
- }
-
- *newtype = decls.type;
- if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
- {
- error ("using declaration `%D' introduced ambiguous type `%T'",
- name, oldtype);
- return;
- }
-}
-
-/* Process a using-declaration not appearing in class or local scope. */
-
-void
-do_toplevel_using_decl (decl)
- tree decl;
-{
- tree scope, name;
- tree oldval, oldtype, newval, newtype;
- cxx_binding *binding;
-
- decl = validate_nonmember_using_decl (decl, &scope, &name);
- if (decl == NULL_TREE)
- return;
-
- /* A multiple using-declaration is valid, so we call binding_for_name,
- not just cxx_binding_make. */
- binding = binding_for_name (name, current_namespace);
-
- oldval = BINDING_VALUE (binding);
- oldtype = BINDING_TYPE (binding);
-
- do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
-
- /* Copy declarations found. */
- if (newval)
- BINDING_VALUE (binding) = newval;
- if (newtype)
- BINDING_TYPE (binding) = newtype;
- return;
-}
-
-/* Process a using-declaration at function scope. */
-
-void
-do_local_using_decl (decl)
- tree decl;
-{
- tree scope, name;
- tree oldval, oldtype, newval, newtype;
-
- decl = validate_nonmember_using_decl (decl, &scope, &name);
- if (decl == NULL_TREE)
- return;
-
- if (building_stmt_tree ()
- && at_function_scope_p ())
- add_decl_stmt (decl);
-
- oldval = lookup_name_current_level (name);
- oldtype = lookup_type_current_level (name);
-
- do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
-
- if (newval)
- {
- if (is_overloaded_fn (newval))
- {
- tree fn, term;
-
- /* We only need to push declarations for those functions
- that were not already bound in the current level.
- The old value might be NULL_TREE, it might be a single
- function, or an OVERLOAD. */
- if (oldval && TREE_CODE (oldval) == OVERLOAD)
- term = OVL_FUNCTION (oldval);
- else
- term = oldval;
- for (fn = newval; fn && OVL_CURRENT (fn) != term;
- fn = OVL_NEXT (fn))
- push_overloaded_decl (OVL_CURRENT (fn),
- PUSH_LOCAL | PUSH_USING);
- }
- else
- push_local_binding (name, newval, PUSH_USING);
- }
- if (newtype)
- set_identifier_type_value (name, newtype);
-}
-
-tree
-do_class_using_decl (decl)
- tree decl;
-{
- tree name, value;
-
- if (TREE_CODE (decl) != SCOPE_REF
- || !TYPE_P (TREE_OPERAND (decl, 0)))
- {
- error ("using-declaration for non-member at class scope");
- return NULL_TREE;
- }
- name = TREE_OPERAND (decl, 1);
- if (TREE_CODE (name) == BIT_NOT_EXPR)
- {
- error ("using-declaration for destructor");
- return NULL_TREE;
- }
- else if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- {
- name = TREE_OPERAND (name, 0);
- error ("a using-declaration cannot specify a template-id. Try `using %T::%D'", TREE_OPERAND (decl, 0), name);
- return NULL_TREE;
- }
- if (TREE_CODE (name) == TYPE_DECL || TREE_CODE (name) == TEMPLATE_DECL)
- name = DECL_NAME (name);
- else if (BASELINK_P (name))
- {
- name = BASELINK_FUNCTIONS (name);
- if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- name = TREE_OPERAND (name, 0);
- name = DECL_NAME (get_first_fn (name));
- }
-
- my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716);
-
- value = build_lang_decl (USING_DECL, name, void_type_node);
- DECL_INITIAL (value) = TREE_OPERAND (decl, 0);
- return value;
+ expr = build_function_call (fn, args);
+ if (processing_template_decl && expr != error_mark_node)
+ return build_min_non_dep (CALL_EXPR, expr, orig_fn, orig_args);
+ return expr;
}
-
-/* Process a using-directive. */
-
-void
-do_using_directive (namespace)
- tree namespace;
-{
- if (building_stmt_tree ())
- add_stmt (build_stmt (USING_STMT, namespace));
- /* using namespace A::B::C; */
- if (TREE_CODE (namespace) == SCOPE_REF)
- namespace = TREE_OPERAND (namespace, 1);
- if (TREE_CODE (namespace) == IDENTIFIER_NODE)
- {
- /* Lookup in lexer did not find a namespace. */
- if (!processing_template_decl)
- error ("namespace `%T' undeclared", namespace);
- return;
- }
- if (TREE_CODE (namespace) != NAMESPACE_DECL)
- {
- if (!processing_template_decl)
- error ("`%T' is not a namespace", namespace);
- return;
- }
- namespace = ORIGINAL_NAMESPACE (namespace);
- if (!toplevel_bindings_p ())
- push_using_directive (namespace);
- else
- /* direct usage */
- add_using_namespace (current_namespace, namespace, 0);
-}
void
-check_default_args (x)
- tree x;
+check_default_args (tree x)
{
tree arg = TYPE_ARG_TYPES (TREE_TYPE (x));
- int saw_def = 0, i = 0 - (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE);
+ bool saw_def = false;
+ int i = 0 - (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE);
for (; arg && arg != void_list_node; arg = TREE_CHAIN (arg), ++i)
{
if (TREE_PURPOSE (arg))
- saw_def = 1;
+ saw_def = true;
else if (saw_def)
{
cp_error_at ("default argument missing for parameter %P of `%+#D'",
@@ -4822,8 +2961,7 @@ check_default_args (x)
}
void
-mark_used (decl)
- tree decl;
+mark_used (tree decl)
{
TREE_USED (decl) = 1;
if (processing_template_decl || skip_evaluation)
@@ -4840,6 +2978,7 @@ mark_used (decl)
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
&& DECL_ARTIFICIAL (decl)
+ && !DECL_THUNK_P (decl)
&& ! DECL_INITIAL (decl)
/* Kludge: don't synthesize for default args. */
&& current_function_decl)
@@ -4857,7 +2996,9 @@ mark_used (decl)
if ((DECL_NON_THUNK_FUNCTION_P (decl) || TREE_CODE (decl) == VAR_DECL)
&& DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
&& (!DECL_EXPLICIT_INSTANTIATION (decl)
- || (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))))
+ || (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_INLINE (DECL_TEMPLATE_RESULT
+ (template_for_substitution (decl))))))
{
bool defer;
@@ -4868,13 +3009,20 @@ mark_used (decl)
However, if instantiating this function might help us mark
the current function TREE_NOTHROW, we go ahead and
- instantiate it now. */
+ instantiate it now.
+
+ This is not needed for unit-at-a-time since we reorder the functions
+ in topological order anyway.
+ */
defer = (!flag_exceptions
+ || flag_unit_at_a_time
+ || !optimize
|| TREE_CODE (decl) != FUNCTION_DECL
/* If the called function can't throw, we don't need to
generate its body to find that out. */
|| TREE_NOTHROW (decl)
|| !cfun
+ || !current_function_decl
/* If we already know the current function can't throw,
then we don't need to work hard to prove it. */
|| TREE_NOTHROW (current_function_decl)
@@ -4887,196 +3035,4 @@ mark_used (decl)
}
}
-/* Helper function for class_head_decl and class_head_defn
- nonterminals. AGGR is the class, union or struct tag. SCOPE is the
- explicit scope used (NULL for no scope resolution). ID is the
- name. DEFN_P is true, if this is a definition of the class and
- NEW_TYPE_P is set to nonzero, if we push into the scope containing
- the to be defined aggregate.
-
- Return a TYPE_DECL for the type declared by ID in SCOPE. */
-
-tree
-handle_class_head (tag_kind, scope, id, attributes, defn_p, new_type_p)
- enum tag_types tag_kind;
- tree scope, id, attributes;
- int defn_p;
- int *new_type_p;
-{
- tree decl = NULL_TREE;
- tree type;
- tree current = current_scope ();
- bool xrefd_p = false;
-
- if (current == NULL_TREE)
- current = current_namespace;
-
- *new_type_p = 0;
-
- if (scope)
- {
- if (TREE_CODE (id) == TYPE_DECL)
- /* We must bash typedefs back to the main decl of the
- type. Otherwise we become confused about scopes. */
- decl = TYPE_MAIN_DECL (TREE_TYPE (id));
- else if (DECL_CLASS_TEMPLATE_P (id))
- decl = DECL_TEMPLATE_RESULT (id);
- else
- {
- if (TYPE_P (scope))
- {
- /* According to the suggested resolution of core issue
- 180, 'typename' is assumed after a class-key. */
- decl = make_typename_type (scope, id, tf_error);
- if (decl != error_mark_node)
- decl = TYPE_MAIN_DECL (decl);
- else
- decl = NULL_TREE;
- }
- else if (scope == current)
- {
- /* We've been given AGGR SCOPE::ID, when we're already
- inside SCOPE. Be nice about it. */
- if (pedantic)
- pedwarn ("extra qualification `%T::' on member `%D' ignored",
- scope, id);
- }
- else
- error ("`%T' does not have a class or union named `%D'",
- scope, id);
- }
- }
-
- if (!decl)
- {
- decl = xref_tag (tag_kind, id, attributes, !defn_p);
- if (decl == error_mark_node)
- return error_mark_node;
- decl = TYPE_MAIN_DECL (decl);
- xrefd_p = true;
- }
-
- type = TREE_TYPE (decl);
-
- if (!TYPE_BINFO (type))
- {
- error ("`%T' is not a class or union type", decl);
- return error_mark_node;
- }
-
- /* When `A' is a template class, using `class A' without template
- argument is invalid unless
- - we are inside the scope of the template class `A' or one of its
- specialization.
- - we are declaring the template class `A' itself. */
- if (TREE_CODE (type) == RECORD_TYPE
- && CLASSTYPE_IS_TEMPLATE (type)
- && processing_template_decl <= template_class_depth (current)
- && ! is_base_of_enclosing_class (type, current_class_type))
- {
- error ("template argument is required for `%T'", type);
- return error_mark_node;
- }
-
- if (defn_p)
- {
- /* For a definition, we want to enter the containing scope
- before looking up any base classes etc. Only do so, if this
- is different to the current scope. */
- tree context = CP_DECL_CONTEXT (decl);
-
- if (IMPLICIT_TYPENAME_P (context))
- context = TREE_TYPE (context);
-
- /* If that scope does not contain the scope in which the
- class was originally declared, the program is invalid. */
- if (current && !is_ancestor (current, context))
- {
- error ("declaration of `%D' in `%D' which does not "
- "enclose `%D'", decl, current, CP_DECL_CONTEXT (decl));
- return NULL_TREE;
- }
-
- *new_type_p = (current != context
- && TREE_CODE (context) != TEMPLATE_TYPE_PARM
- && TREE_CODE (context) != BOUND_TEMPLATE_TEMPLATE_PARM);
- if (*new_type_p)
- push_scope (context);
-
- if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE)
- /* It is valid to define a class with a different class key,
- and this changes the default member access. */
- CLASSTYPE_DECLARED_CLASS (TREE_TYPE (decl))
- = (tag_kind == class_type);
-
- if (!xrefd_p && PROCESSING_REAL_TEMPLATE_DECL_P ())
- decl = push_template_decl (decl);
- }
- else
- {
- /* For elaborated type specifier in declaration like
-
- class A::B *a;
-
- we get an implicit typename here. Let's remove its
- implicitness so that we don't issue any implicit
- typename warning later. Note that when defn_p is true,
- implicitness is still required by begin_class_definition. */
- if (IMPLICIT_TYPENAME_P (type))
- decl = TYPE_STUB_DECL (build_typename_type (TYPE_CONTEXT (type),
- TYPE_IDENTIFIER (type),
- TYPENAME_TYPE_FULLNAME (type),
- NULL_TREE));
- }
-
- return decl;
-}
-
-/* Like handle_class_head but for a definition of a class specialization.
- DECL is a TYPE_DECL node representing the class. NEW_TYPE_P is set to
- nonzero, if we push into the scope containing the to be defined
- aggregate.
-
- Return a TYPE_DECL for the type declared by ID in SCOPE. */
-
-tree
-handle_class_head_apparent_template (decl, new_type_p)
- tree decl;
- int *new_type_p;
-{
- tree context;
- tree current;
-
- if (decl == error_mark_node)
- return decl;
-
- current = current_scope ();
- if (current == NULL_TREE)
- current = current_namespace;
-
- *new_type_p = 0;
-
- /* For a definition, we want to enter the containing scope
- before looking up any base classes etc. Only do so, if this
- is different to the current scope. */
- context = CP_DECL_CONTEXT (decl);
-
- if (IMPLICIT_TYPENAME_P (context))
- context = TREE_TYPE (context);
-
- *new_type_p = (current != context
- && TREE_CODE (context) != TEMPLATE_TYPE_PARM
- && TREE_CODE (context) != BOUND_TEMPLATE_TEMPLATE_PARM);
- if (*new_type_p)
- push_scope (context);
-
- if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE)
- /* We might be specializing a template with a different
- class-key. */
- CLASSTYPE_DECLARED_CLASS (TREE_TYPE (decl))
- = (current_aggr == class_type_node);
-
- return decl;
-}
-
#include "gt-cp-decl2.h"
diff --git a/contrib/gcc/cp/dump.c b/contrib/gcc/cp/dump.c
index 39e72dcd9832..17b30c94367b 100644
--- a/contrib/gcc/cp/dump.c
+++ b/contrib/gcc/cp/dump.c
@@ -2,42 +2,40 @@
Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Written by Mark Mitchell <mark@codesourcery.com>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "tree-dump.h"
-static void dump_access
- PARAMS ((dump_info_p, tree));
+static void dump_access (dump_info_p, tree);
-static void dump_op
- PARAMS ((dump_info_p, tree));
+static void dump_op (dump_info_p, tree);
/* Dump a representation of the accessibility information associated
with T. */
static void
-dump_access (di, t)
- dump_info_p di;
- tree t;
+dump_access (dump_info_p di, tree t)
{
if (TREE_PROTECTED(t))
dump_string (di, "protected");
@@ -51,9 +49,7 @@ dump_access (di, t)
operator associated with node t. */
static void
-dump_op (di, t)
- dump_info_p di;
- tree t;
+dump_op (dump_info_p di, tree t)
{
switch (DECL_OVERLOADED_OPERATOR_P (t)) {
case NEW_EXPR:
@@ -206,10 +202,8 @@ dump_op (di, t)
}
}
-int
-cp_dump_tree (dump_info, t)
- void *dump_info;
- tree t;
+bool
+cp_dump_tree (void* dump_info, tree t)
{
enum tree_code code;
dump_info_p di = (dump_info_p) dump_info;
@@ -220,7 +214,7 @@ cp_dump_tree (dump_info, t)
if (DECL_P (t))
{
if (DECL_LANG_SPECIFIC (t) && DECL_LANGUAGE (t) != lang_cplusplus)
- dump_string (di, language_to_string (DECL_LANGUAGE (t), 0));
+ dump_string (di, language_to_string (DECL_LANGUAGE (t)));
}
switch (code)
@@ -229,48 +223,43 @@ cp_dump_tree (dump_info, t)
if (IDENTIFIER_OPNAME_P (t))
{
dump_string (di, "operator");
- return 1;
+ return true;
}
else if (IDENTIFIER_TYPENAME_P (t))
{
dump_child ("tynm", TREE_TYPE (t));
- return 1;
- }
- else if (t == anonymous_namespace_name)
- {
- dump_string (di, "unnamed");
- return 1;
+ return true;
}
break;
- case POINTER_TYPE:
- if (TYPE_PTRMEM_P (t))
- {
- dump_string (di, "ptrmem");
- dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
- dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
- return 1;
- }
- break;
+ case OFFSET_TYPE:
+ dump_string (di, "ptrmem");
+ dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
+ dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
+ return true;
case RECORD_TYPE:
- case UNION_TYPE:
if (TYPE_PTRMEMFUNC_P (t))
{
dump_string (di, "ptrmem");
dump_child ("ptd", TYPE_PTRMEM_POINTED_TO_TYPE (t));
dump_child ("cls", TYPE_PTRMEM_CLASS_TYPE (t));
- return 1;
+ return true;
}
+ /* Fall through. */
+ case UNION_TYPE:
/* Is it a type used as a base? */
if (TYPE_CONTEXT (t) && TREE_CODE (TYPE_CONTEXT (t)) == TREE_CODE (t)
&& CLASSTYPE_AS_BASE (TYPE_CONTEXT (t)) == t)
{
dump_child ("bfld", TYPE_CONTEXT (t));
- return 1;
+ return true;
}
+ if (! IS_AGGR_TYPE (t))
+ break;
+
dump_child ("vfld", TYPE_VFIELD (t));
if (CLASSTYPE_TEMPLATE_SPECIALIZATION(t))
dump_string(di, "spec");
@@ -325,21 +314,29 @@ cp_dump_tree (dump_info, t)
dump_string (di, "destructor");
if (DECL_CONV_FN_P (t))
dump_string (di, "conversion");
- if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
- {
- if (DECL_GLOBAL_CTOR_P (t))
- dump_string (di, "global init");
- if (DECL_GLOBAL_DTOR_P (t))
- dump_string (di, "global fini");
- }
+ if (DECL_GLOBAL_CTOR_P (t))
+ dump_string (di, "global init");
+ if (DECL_GLOBAL_DTOR_P (t))
+ dump_string (di, "global fini");
if (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t))
dump_string (di, "pseudo tmpl");
}
else
{
+ tree virt = THUNK_VIRTUAL_OFFSET (t);
+
dump_string (di, "thunk");
- dump_int (di, "dlta", THUNK_DELTA (t));
- dump_child ("vcll", THUNK_VCALL_OFFSET (t));
+ if (DECL_THIS_THUNK_P (t))
+ dump_string (di, "this adjusting");
+ else
+ {
+ dump_string (di, "result adjusting");
+ if (virt)
+ virt = BINFO_VPTR_FIELD (virt);
+ }
+ dump_int (di, "fixd", THUNK_FIXED_OFFSET (t));
+ if (virt)
+ dump_int (di, "virt", tree_low_cst (virt, 0));
dump_child ("fn", DECL_INITIAL (t));
}
break;
diff --git a/contrib/gcc/cp/error.c b/contrib/gcc/cp/error.c
index 804c9182b59c..9c9561ffff56 100644
--- a/contrib/gcc/cp/error.c
+++ b/contrib/gcc/cp/error.c
@@ -1,26 +1,28 @@
/* Call-backs for C++ error reporting.
This code is non-reentrant.
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002
- Free Software Foundation, Inc.
- This file is part of GNU CC.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+ 2003 Free Software Foundation, Inc.
+ This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "real.h"
@@ -28,110 +30,93 @@ Boston, MA 02111-1307, USA. */
#include "flags.h"
#include "diagnostic.h"
#include "langhooks-def.h"
+#include "cxx-pretty-print.h"
enum pad { none, before, after };
-#define sorry_for_unsupported_tree(T) \
- sorry ("`%s' not supported by %s", tree_code_name[(int) TREE_CODE (T)], \
- __FUNCTION__)
-
-#define print_scope_operator(BUFFER) output_add_string ((BUFFER), "::")
-#define print_left_paren(BUFFER) output_add_character ((BUFFER), '(')
-#define print_right_paren(BUFFER) output_add_character ((BUFFER), ')')
-#define print_left_bracket(BUFFER) output_add_character ((BUFFER), '[')
-#define print_right_bracket(BUFFER) output_add_character ((BUFFER), ']')
-#define print_template_argument_list_start(BUFFER) \
- print_non_consecutive_character ((BUFFER), '<')
-#define print_template_argument_list_end(BUFFER) \
- print_non_consecutive_character ((BUFFER), '>')
-#define print_tree_identifier(BUFFER, TID) \
- output_add_string ((BUFFER), IDENTIFIER_POINTER (TID))
-#define print_identifier(BUFFER, ID) output_add_string ((BUFFER), (ID))
-#define separate_with_comma(BUFFER) output_add_string ((BUFFER), ", ")
+#define pp_template_argument_list_start(PP) \
+ pp_non_consecutive_character (PP, '<')
+#define pp_template_argument_list_end(PP) \
+ pp_non_consecutive_character (PP, '>')
+#define pp_separate_with_comma(PP) pp_string (PP, ", ")
/* The global buffer where we dump everything. It is there only for
transitional purpose. It is expected, in the near future, to be
completely removed. */
-static output_buffer scratch_buffer_rec;
-static output_buffer *scratch_buffer = &scratch_buffer_rec;
+static cxx_pretty_printer scratch_pretty_printer;
+#define cxx_pp (&scratch_pretty_printer)
# define NEXT_CODE(T) (TREE_CODE (TREE_TYPE (T)))
#define reinit_global_formatting_buffer() \
output_clear_message_text (scratch_buffer)
-static const char *args_to_string PARAMS ((tree, int));
-static const char *assop_to_string PARAMS ((enum tree_code, int));
-static const char *code_to_string PARAMS ((enum tree_code, int));
-static const char *cv_to_string PARAMS ((tree, int));
-static const char *decl_to_string PARAMS ((tree, int));
-static const char *expr_to_string PARAMS ((tree, int));
-static const char *fndecl_to_string PARAMS ((tree, int));
-static const char *op_to_string PARAMS ((enum tree_code, int));
-static const char *parm_to_string PARAMS ((int, int));
-static const char *type_to_string PARAMS ((tree, int));
-
-static void dump_type PARAMS ((tree, int));
-static void dump_typename PARAMS ((tree, int));
-static void dump_simple_decl PARAMS ((tree, tree, int));
-static void dump_decl PARAMS ((tree, int));
-static void dump_template_decl PARAMS ((tree, int));
-static void dump_function_decl PARAMS ((tree, int));
-static void dump_expr PARAMS ((tree, int));
-static void dump_unary_op PARAMS ((const char *, tree, int));
-static void dump_binary_op PARAMS ((const char *, tree, int));
-static void dump_aggr_type PARAMS ((tree, int));
-static enum pad dump_type_prefix PARAMS ((tree, int));
-static void dump_type_suffix PARAMS ((tree, int));
-static void dump_function_name PARAMS ((tree, int));
-static void dump_expr_list PARAMS ((tree, int));
-static void dump_global_iord PARAMS ((tree));
-static enum pad dump_qualifiers PARAMS ((tree, enum pad));
-static void dump_char PARAMS ((int));
-static void dump_parameters PARAMS ((tree, int));
-static void dump_exception_spec PARAMS ((tree, int));
-static const char *class_key_or_enum PARAMS ((tree));
-static void dump_template_argument PARAMS ((tree, int));
-static void dump_template_argument_list PARAMS ((tree, int));
-static void dump_template_parameter PARAMS ((tree, int));
-static void dump_template_bindings PARAMS ((tree, tree));
-static void dump_scope PARAMS ((tree, int));
-static void dump_template_parms PARAMS ((tree, int, int));
-
-static const char *function_category PARAMS ((tree));
-static void maybe_print_instantiation_context PARAMS ((diagnostic_context *));
-static void print_instantiation_full_context PARAMS ((diagnostic_context *));
-static void print_instantiation_partial_context PARAMS ((diagnostic_context *,
- tree,
- const char *, int));
-static void cp_diagnostic_starter PARAMS ((diagnostic_context *,
- diagnostic_info *));
-static void cp_diagnostic_finalizer PARAMS ((diagnostic_context *,
- diagnostic_info *));
-static void cp_print_error_function PARAMS ((diagnostic_context *,
- diagnostic_info *));
-
-static bool cp_printer PARAMS ((output_buffer *, text_info *));
-static void print_non_consecutive_character PARAMS ((output_buffer *, int));
-static void print_integer PARAMS ((output_buffer *, HOST_WIDE_INT));
-static tree locate_error PARAMS ((const char *, va_list));
+static const char *args_to_string (tree, int);
+static const char *assop_to_string (enum tree_code);
+static const char *code_to_string (enum tree_code);
+static const char *cv_to_string (tree, int);
+static const char *decl_to_string (tree, int);
+static const char *expr_to_string (tree);
+static const char *fndecl_to_string (tree, int);
+static const char *op_to_string (enum tree_code);
+static const char *parm_to_string (int);
+static const char *type_to_string (tree, int);
+
+static void dump_type (tree, int);
+static void dump_typename (tree, int);
+static void dump_simple_decl (tree, tree, int);
+static void dump_decl (tree, int);
+static void dump_template_decl (tree, int);
+static void dump_function_decl (tree, int);
+static void dump_expr (tree, int);
+static void dump_unary_op (const char *, tree, int);
+static void dump_binary_op (const char *, tree, int);
+static void dump_aggr_type (tree, int);
+static enum pad dump_type_prefix (tree, int);
+static void dump_type_suffix (tree, int);
+static void dump_function_name (tree, int);
+static void dump_expr_list (tree, int);
+static void dump_global_iord (tree);
+static enum pad dump_qualifiers (tree, enum pad);
+static void dump_parameters (tree, int);
+static void dump_exception_spec (tree, int);
+static const char *class_key_or_enum (tree);
+static void dump_template_argument (tree, int);
+static void dump_template_argument_list (tree, int);
+static void dump_template_parameter (tree, int);
+static void dump_template_bindings (tree, tree);
+static void dump_scope (tree, int);
+static void dump_template_parms (tree, int, int);
+
+static const char *function_category (tree);
+static void maybe_print_instantiation_context (diagnostic_context *);
+static void print_instantiation_full_context (diagnostic_context *);
+static void print_instantiation_partial_context (diagnostic_context *,
+ tree, location_t);
+static void cp_diagnostic_starter (diagnostic_context *, diagnostic_info *);
+static void cp_diagnostic_finalizer (diagnostic_context *, diagnostic_info *);
+static void cp_print_error_function (diagnostic_context *, diagnostic_info *);
+
+static bool cp_printer (pretty_printer *, text_info *);
+static void pp_non_consecutive_character (cxx_pretty_printer *, int);
+static tree locate_error (const char *, va_list);
+static location_t location_of (tree);
void
-init_error ()
+init_error (void)
{
diagnostic_starter (global_dc) = cp_diagnostic_starter;
diagnostic_finalizer (global_dc) = cp_diagnostic_finalizer;
diagnostic_format_decoder (global_dc) = cp_printer;
- init_output_buffer (scratch_buffer, /* prefix */NULL, /* line-width */0);
+ pp_construct (pp_base (cxx_pp), NULL, 0);
+ pp_cxx_pretty_printer_init (cxx_pp);
}
/* Dump a scope, if deemed necessary. */
static void
-dump_scope (scope, flags)
- tree scope;
- int flags;
+dump_scope (tree scope, int flags)
{
int f = ~TFF_RETURN_TYPE & (flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF));
@@ -143,18 +128,18 @@ dump_scope (scope, flags)
if (scope != global_namespace)
{
dump_decl (scope, f);
- print_scope_operator (scratch_buffer);
+ pp_colon_colon (cxx_pp);
}
}
else if (AGGREGATE_TYPE_P (scope))
{
dump_type (scope, f);
- print_scope_operator (scratch_buffer);
+ pp_colon_colon (cxx_pp);
}
else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL)
{
dump_function_decl (scope, f);
- print_scope_operator (scratch_buffer);
+ pp_colon_colon (cxx_pp);
}
}
@@ -162,9 +147,7 @@ dump_scope (scope, flags)
indication of whether we dumped something. */
static enum pad
-dump_qualifiers (t, p)
- tree t;
- enum pad p;
+dump_qualifiers (tree t, enum pad p)
{
static const int masks[] =
{TYPE_QUAL_CONST, TYPE_QUAL_VOLATILE, TYPE_QUAL_RESTRICT};
@@ -180,28 +163,22 @@ dump_qualifiers (t, p)
if (masks[ix] & quals)
{
if (p == before)
- output_add_space (scratch_buffer);
+ pp_space (cxx_pp);
p = before;
- print_identifier (scratch_buffer, names[ix]);
+ pp_identifier (cxx_pp, names[ix]);
}
if (do_after)
- output_add_space (scratch_buffer);
+ pp_space (cxx_pp);
}
else
p = none;
return p;
}
-/* This must be large enough to hold any printed integer or floating-point
- value. */
-static char digit_buffer[128];
-
/* Dump the template ARGument under control of FLAGS. */
static void
-dump_template_argument (arg, flags)
- tree arg;
- int flags;
+dump_template_argument (tree arg, int flags)
{
if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
@@ -213,9 +190,7 @@ dump_template_argument (arg, flags)
of FLAGS. */
static void
-dump_template_argument_list (args, flags)
- tree args;
- int flags;
+dump_template_argument_list (tree args, int flags)
{
int n = TREE_VEC_LENGTH (args);
int need_comma = 0;
@@ -224,7 +199,7 @@ dump_template_argument_list (args, flags)
for (i = 0; i< n; ++i)
{
if (need_comma)
- separate_with_comma (scratch_buffer);
+ pp_separate_with_comma (cxx_pp);
dump_template_argument (TREE_VEC_ELT (args, i), flags);
need_comma = 1;
}
@@ -233,9 +208,7 @@ dump_template_argument_list (args, flags)
/* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS. */
static void
-dump_template_parameter (parm, flags)
- tree parm;
- int flags;
+dump_template_parameter (tree parm, int flags)
{
tree p = TREE_VALUE (parm);
tree a = TREE_PURPOSE (parm);
@@ -244,24 +217,24 @@ dump_template_parameter (parm, flags)
{
if (flags & TFF_DECL_SPECIFIERS)
{
- print_identifier (scratch_buffer, "class");
+ pp_identifier (cxx_pp, "class");
if (DECL_NAME (p))
{
- output_add_space (scratch_buffer);
- print_tree_identifier (scratch_buffer, DECL_NAME (p));
+ pp_space (cxx_pp);
+ pp_tree_identifier (cxx_pp, DECL_NAME (p));
}
}
else if (DECL_NAME (p))
- print_tree_identifier (scratch_buffer, DECL_NAME (p));
+ pp_tree_identifier (cxx_pp, DECL_NAME (p));
else
- print_identifier (scratch_buffer, "{template default argument error}");
+ pp_cxx_canonical_template_parameter (cxx_pp, TREE_TYPE (p));
}
else
dump_decl (p, flags | TFF_DECL_SPECIFIERS);
if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE)
{
- output_add_string (scratch_buffer, " = ");
+ pp_string (cxx_pp, " = ");
if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
dump_type (a, flags & ~TFF_CHASE_TYPEDEF);
else
@@ -274,8 +247,7 @@ dump_template_parameter (parm, flags)
TREE_VEC. */
static void
-dump_template_bindings (parms, args)
- tree parms, args;
+dump_template_bindings (tree parms, tree args)
{
int need_comma = 0;
@@ -299,13 +271,13 @@ dump_template_bindings (parms, args)
}
if (need_comma)
- separate_with_comma (scratch_buffer);
+ pp_separate_with_comma (cxx_pp);
dump_template_parameter (TREE_VEC_ELT (p, i), TFF_PLAIN_IDENTIFIER);
- output_add_string (scratch_buffer, " = ");
+ pp_string (cxx_pp, " = ");
if (arg)
dump_template_argument (arg, TFF_PLAIN_IDENTIFIER);
else
- print_identifier (scratch_buffer, "<missing>");
+ pp_identifier (cxx_pp, "<missing>");
++arg_idx;
need_comma = 1;
@@ -319,9 +291,7 @@ dump_template_bindings (parms, args)
format. */
static void
-dump_type (t, flags)
- tree t;
- int flags;
+dump_type (tree t, int flags)
{
if (t == NULL_TREE)
return;
@@ -332,7 +302,7 @@ dump_type (t, flags)
switch (TREE_CODE (t))
{
case UNKNOWN_TYPE:
- print_identifier (scratch_buffer, "<unknown type>");
+ pp_identifier (cxx_pp, "<unknown type>");
break;
case TREE_LIST:
@@ -341,7 +311,7 @@ dump_type (t, flags)
break;
case IDENTIFIER_NODE:
- print_tree_identifier (scratch_buffer, t);
+ pp_tree_identifier (cxx_pp, t);
break;
case TREE_VEC:
@@ -361,80 +331,49 @@ dump_type (t, flags)
? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags);
break;
}
- /* else fallthrough */
+ /* Else fall through. */
case TEMPLATE_DECL:
case NAMESPACE_DECL:
dump_decl (t, flags & ~TFF_DECL_SPECIFIERS);
break;
- case COMPLEX_TYPE:
- output_add_string (scratch_buffer, "__complex__ ");
- dump_type (TREE_TYPE (t), flags);
- break;
-
- case VECTOR_TYPE:
- output_add_string (scratch_buffer, "vector ");
- {
- /* The subtype of a VECTOR_TYPE is something like intQI_type_node,
- which has no name and is not very useful for diagnostics. So
- look up the equivalent C type and print its name. */
- tree elt = TREE_TYPE (t);
- elt = c_common_type_for_mode (TYPE_MODE (elt), TREE_UNSIGNED (elt));
- dump_type (elt, flags);
- }
- break;
-
case INTEGER_TYPE:
- if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t))
- output_add_string (scratch_buffer, "unsigned ");
- else if (TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && !TREE_UNSIGNED (t))
- output_add_string (scratch_buffer, "signed ");
-
- /* fall through. */
case REAL_TYPE:
case VOID_TYPE:
case BOOLEAN_TYPE:
- {
- tree type;
- dump_qualifiers (t, after);
- type = flags & TFF_CHASE_TYPEDEF ? TYPE_MAIN_VARIANT (t) : t;
- if (TYPE_NAME (type) && TYPE_IDENTIFIER (type))
- print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (type));
- else
- /* Types like intQI_type_node and friends have no names.
- These don't come up in user error messages, but it's nice
- to be able to print them from the debugger. */
- print_identifier (scratch_buffer, "<anonymous>");
- }
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ pp_base (cxx_pp)->padding = pp_none;
+ pp_type_specifier_seq (cxx_pp, t);
break;
case TEMPLATE_TEMPLATE_PARM:
/* For parameters inside template signature. */
if (TYPE_IDENTIFIER (t))
- print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
+ pp_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
else
- print_identifier
- (scratch_buffer, "<anonymous template template parameter>");
+ pp_cxx_canonical_template_parameter (cxx_pp, t);
break;
case BOUND_TEMPLATE_TEMPLATE_PARM:
{
tree args = TYPE_TI_ARGS (t);
- print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
- print_template_argument_list_start (scratch_buffer);
+ dump_qualifiers (t, after);
+ pp_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
+ pp_template_argument_list_start (cxx_pp);
dump_template_argument_list (args, flags);
- print_template_argument_list_end (scratch_buffer);
+ pp_template_argument_list_end (cxx_pp);
}
break;
case TEMPLATE_TYPE_PARM:
dump_qualifiers (t, after);
if (TYPE_IDENTIFIER (t))
- print_tree_identifier (scratch_buffer, TYPE_IDENTIFIER (t));
+ pp_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
else
- print_identifier
- (scratch_buffer, "<anonymous template type parameter>");
+ pp_cxx_canonical_template_parameter
+ (cxx_pp, TEMPLATE_TYPE_PARM_INDEX (t));
break;
/* This is not always necessary for pointers and such, but doing this
@@ -452,30 +391,30 @@ dump_type (t, flags)
break;
}
case TYPENAME_TYPE:
- if (!IMPLICIT_TYPENAME_P (t))
- output_add_string (scratch_buffer, "typename ");
+ dump_qualifiers (t, after);
+ pp_string (cxx_pp, "typename ");
dump_typename (t, flags);
break;
case UNBOUND_CLASS_TEMPLATE:
dump_type (TYPE_CONTEXT (t), flags);
- print_scope_operator (scratch_buffer);
- print_identifier (scratch_buffer, "template ");
+ pp_colon_colon (cxx_pp);
+ pp_identifier (cxx_pp, "template ");
dump_type (DECL_NAME (TYPE_NAME (t)), flags);
break;
case TYPEOF_TYPE:
- output_add_string (scratch_buffer, "__typeof (");
+ pp_string (cxx_pp, "__typeof (");
dump_expr (TYPE_FIELDS (t), flags & ~TFF_EXPR_IN_PARENS);
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
break;
default:
- sorry_for_unsupported_tree (t);
+ pp_unsupported_tree (cxx_pp, t);
/* Fall through to error. */
case ERROR_MARK:
- print_identifier (scratch_buffer, "<type error>");
+ pp_identifier (cxx_pp, "<type error>");
break;
}
}
@@ -484,9 +423,7 @@ dump_type (t, flags)
a TYPENAME_TYPE. */
static void
-dump_typename (t, flags)
- tree t;
- int flags;
+dump_typename (tree t, int flags)
{
tree ctx = TYPE_CONTEXT (t);
@@ -494,15 +431,14 @@ dump_typename (t, flags)
dump_typename (ctx, flags);
else
dump_type (ctx, flags & ~TFF_CLASS_KEY_OR_ENUM);
- print_scope_operator (scratch_buffer);
+ pp_colon_colon (cxx_pp);
dump_decl (TYPENAME_TYPE_FULLNAME (t), flags);
}
/* Return the name of the supplied aggregate, or enumeral type. */
static const char *
-class_key_or_enum (t)
- tree t;
+class_key_or_enum (tree t)
{
if (TREE_CODE (t) == ENUMERAL_TYPE)
return "enum";
@@ -518,9 +454,7 @@ class_key_or_enum (t)
in the form `class foo'. */
static void
-dump_aggr_type (t, flags)
- tree t;
- int flags;
+dump_aggr_type (tree t, int flags)
{
tree name;
const char *variety = class_key_or_enum (t);
@@ -531,8 +465,8 @@ dump_aggr_type (t, flags)
if (flags & TFF_CLASS_KEY_OR_ENUM)
{
- print_identifier (scratch_buffer, variety);
- output_add_space (scratch_buffer);
+ pp_identifier (cxx_pp, variety);
+ pp_space (cxx_pp);
}
if (flags & TFF_CHASE_TYPEDEF)
@@ -566,12 +500,12 @@ dump_aggr_type (t, flags)
if (name == 0 || ANON_AGGRNAME_P (name))
{
if (flags & TFF_CLASS_KEY_OR_ENUM)
- print_identifier (scratch_buffer, "<anonymous>");
+ pp_identifier (cxx_pp, "<anonymous>");
else
- output_printf (scratch_buffer, "<anonymous %s>", variety);
+ pp_printf (pp_base (cxx_pp), "<anonymous %s>", variety);
}
else
- print_tree_identifier (scratch_buffer, name);
+ pp_tree_identifier (cxx_pp, name);
if (tmplate)
dump_template_parms (TYPE_TEMPLATE_INFO (t),
!CLASSTYPE_USE_TEMPLATE (t),
@@ -593,9 +527,7 @@ dump_aggr_type (t, flags)
want to pad non-*, non-& cores, but not pad * or & types. */
static enum pad
-dump_type_prefix (t, flags)
- tree t;
- int flags;
+dump_type_prefix (tree t, int flags)
{
enum pad padding = before;
@@ -613,19 +545,13 @@ dump_type_prefix (t, flags)
tree sub = TREE_TYPE (t);
padding = dump_type_prefix (sub, flags);
- /* A tree for a member pointer looks like pointer to offset,
- so let the OFFSET_TYPE case handle it. */
- if (!TYPE_PTRMEM_P (t))
+ if (TREE_CODE (sub) == ARRAY_TYPE)
{
- if (TREE_CODE (sub) == ARRAY_TYPE)
- {
- output_add_space (scratch_buffer);
- print_left_paren (scratch_buffer);
- }
- output_add_character
- (scratch_buffer, "&*"[TREE_CODE (t) == POINTER_TYPE]);
- padding = dump_qualifiers (t, before);
+ pp_space (cxx_pp);
+ pp_left_paren (cxx_pp);
}
+ pp_character (cxx_pp, "&*"[TREE_CODE (t) == POINTER_TYPE]);
+ padding = dump_qualifiers (t, before);
}
break;
@@ -635,11 +561,11 @@ dump_type_prefix (t, flags)
if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */
{
if (padding != none)
- output_add_space (scratch_buffer);
+ pp_space (cxx_pp);
dump_type (TYPE_OFFSET_BASETYPE (t), flags);
- print_scope_operator (scratch_buffer);
+ pp_colon_colon (cxx_pp);
}
- output_add_character (scratch_buffer, '*');
+ pp_star (cxx_pp);
padding = dump_qualifiers (t, none);
break;
@@ -648,19 +574,19 @@ dump_type_prefix (t, flags)
case FUNCTION_TYPE:
padding = dump_type_prefix (TREE_TYPE (t), flags);
if (padding != none)
- output_add_space (scratch_buffer);
- print_left_paren (scratch_buffer);
+ pp_space (cxx_pp);
+ pp_left_paren (cxx_pp);
padding = none;
break;
case METHOD_TYPE:
padding = dump_type_prefix (TREE_TYPE (t), flags);
if (padding != none)
- output_add_space (scratch_buffer);
- print_left_paren (scratch_buffer);
+ pp_space (cxx_pp);
+ pp_left_paren (cxx_pp);
padding = none;
dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags);
- print_scope_operator (scratch_buffer);
+ pp_colon_colon (cxx_pp);
break;
case ARRAY_TYPE:
@@ -691,10 +617,10 @@ dump_type_prefix (t, flags)
break;
default:
- sorry_for_unsupported_tree (t);
+ pp_unsupported_tree (cxx_pp, t);
/* fall through. */
case ERROR_MARK:
- print_identifier (scratch_buffer, "<typeprefixerror>");
+ pp_identifier (cxx_pp, "<typeprefixerror>");
break;
}
return padding;
@@ -704,9 +630,7 @@ dump_type_prefix (t, flags)
which appears after the identifier (or function parms). */
static void
-dump_type_suffix (t, flags)
- tree t;
- int flags;
+dump_type_suffix (tree t, int flags)
{
if (TYPE_PTRMEMFUNC_P (t))
t = TYPE_PTRMEMFUNC_FN_TYPE (t);
@@ -717,16 +641,16 @@ dump_type_suffix (t, flags)
case REFERENCE_TYPE:
case OFFSET_TYPE:
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
dump_type_suffix (TREE_TYPE (t), flags);
break;
- /* Can only be reached through function pointer */
+ /* Can only be reached through function pointer. */
case FUNCTION_TYPE:
case METHOD_TYPE:
{
tree arg;
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
arg = TYPE_ARG_TYPES (t);
if (TREE_CODE (t) == METHOD_TYPE)
arg = TREE_CHAIN (arg);
@@ -744,13 +668,12 @@ dump_type_suffix (t, flags)
}
case ARRAY_TYPE:
- print_left_bracket (scratch_buffer);
+ pp_left_bracket (cxx_pp);
if (TYPE_DOMAIN (t))
{
if (host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0))
- print_integer
- (scratch_buffer,
- tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0) + 1);
+ pp_wide_integer
+ (cxx_pp, tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0) + 1);
else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR)
dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0),
flags & ~TFF_EXPR_IN_PARENS);
@@ -760,7 +683,7 @@ dump_type_suffix (t, flags)
integer_one_node)),
flags & ~TFF_EXPR_IN_PARENS);
}
- print_right_bracket (scratch_buffer);
+ pp_right_bracket (cxx_pp);
dump_type_suffix (TREE_TYPE (t), flags);
break;
@@ -786,7 +709,7 @@ dump_type_suffix (t, flags)
break;
default:
- sorry_for_unsupported_tree (t);
+ pp_unsupported_tree (cxx_pp, t);
case ERROR_MARK:
/* Don't mark it here, we should have already done in
dump_type_prefix. */
@@ -795,8 +718,7 @@ dump_type_suffix (t, flags)
}
static void
-dump_global_iord (t)
- tree t;
+dump_global_iord (tree t)
{
const char *p = NULL;
@@ -807,26 +729,23 @@ dump_global_iord (t)
else
abort ();
- output_printf (scratch_buffer, "(static %s for %s)", p, input_filename);
+ pp_printf (pp_base (cxx_pp), "(static %s for %s)", p, input_filename);
}
static void
-dump_simple_decl (t, type, flags)
- tree t;
- tree type;
- int flags;
+dump_simple_decl (tree t, tree type, int flags)
{
if (flags & TFF_DECL_SPECIFIERS)
{
if (dump_type_prefix (type, flags) != none)
- output_add_space (scratch_buffer);
+ pp_space (cxx_pp);
}
if (!DECL_INITIAL (t) || TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX)
dump_scope (CP_DECL_CONTEXT (t), flags);
if (DECL_NAME (t))
dump_decl (DECL_NAME (t), flags);
else
- print_identifier (scratch_buffer, "<anonymous>");
+ pp_identifier (cxx_pp, "<anonymous>");
if (flags & TFF_DECL_SPECIFIERS)
dump_type_suffix (type, flags);
}
@@ -834,9 +753,7 @@ dump_simple_decl (t, type, flags)
/* Dump a human readable string for the decl T under control of FLAGS. */
static void
-dump_decl (t, flags)
- tree t;
- int flags;
+dump_decl (tree t, int flags)
{
if (t == NULL_TREE)
return;
@@ -851,14 +768,14 @@ dump_decl (t, flags)
if ((flags & TFF_DECL_SPECIFIERS)
&& TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
/* Say `class T' not just `T'. */
- output_add_string (scratch_buffer, "class ");
+ pp_string (cxx_pp, "class ");
dump_type (TREE_TYPE (t), flags);
break;
}
}
if (flags & TFF_DECL_SPECIFIERS)
- output_add_string (scratch_buffer, "typedef ");
+ pp_string (cxx_pp, "typedef ");
dump_simple_decl (t, DECL_ORIGINAL_TYPE (t)
? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
flags);
@@ -867,41 +784,47 @@ dump_decl (t, flags)
case VAR_DECL:
if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
{
- output_add_string (scratch_buffer, "vtable for ");
+ pp_string (cxx_pp, "vtable for ");
my_friendly_assert (TYPE_P (DECL_CONTEXT (t)), 20010720);
dump_type (DECL_CONTEXT (t), flags);
break;
}
- /* else fall through */
+ /* Else fall through. */
case FIELD_DECL:
case PARM_DECL:
+ case ALIAS_DECL:
dump_simple_decl (t, TREE_TYPE (t), flags);
break;
case RESULT_DECL:
- output_add_string (scratch_buffer, "<return value> ");
+ pp_string (cxx_pp, "<return value> ");
dump_simple_decl (t, TREE_TYPE (t), flags);
break;
case NAMESPACE_DECL:
- dump_scope (CP_DECL_CONTEXT (t), flags);
- if (DECL_NAME (t) == anonymous_namespace_name)
- print_identifier (scratch_buffer, "<unnamed>");
+ if (flags & TFF_DECL_SPECIFIERS)
+ pp_cxx_declaration (cxx_pp, t);
else
- print_tree_identifier (scratch_buffer, DECL_NAME (t));
+ {
+ dump_scope (CP_DECL_CONTEXT (t), flags);
+ if (DECL_NAME (t) == NULL_TREE)
+ pp_identifier (cxx_pp, "<unnamed>");
+ else
+ pp_tree_identifier (cxx_pp, DECL_NAME (t));
+ }
break;
case SCOPE_REF:
dump_decl (TREE_OPERAND (t, 0), flags & ~TFF_DECL_SPECIFIERS);
- print_scope_operator (scratch_buffer);
+ pp_colon_colon (cxx_pp);
dump_decl (TREE_OPERAND (t, 1), flags);
break;
case ARRAY_REF:
dump_decl (TREE_OPERAND (t, 0), flags);
- print_left_bracket (scratch_buffer);
+ pp_left_bracket (cxx_pp);
dump_decl (TREE_OPERAND (t, 1), flags);
- print_right_bracket (scratch_buffer);
+ pp_right_bracket (cxx_pp);
break;
/* So that we can do dump_decl on an aggr type. */
@@ -911,6 +834,13 @@ dump_decl (t, flags)
dump_type (t, flags);
break;
+ case BIT_NOT_EXPR:
+ /* This is a pseudo destructor call which has not been folded into
+ a PSEUDO_DTOR_EXPR yet. */
+ pp_complement (cxx_pp);
+ dump_type (TREE_OPERAND (t, 0), flags);
+ break;
+
case TYPE_EXPR:
abort ();
break;
@@ -920,13 +850,13 @@ dump_decl (t, flags)
case IDENTIFIER_NODE:
if (IDENTIFIER_TYPENAME_P (t))
{
- output_add_string (scratch_buffer, "operator ");
+ pp_string (cxx_pp, "operator ");
/* Not exactly IDENTIFIER_TYPE_VALUE. */
dump_type (TREE_TYPE (t), flags);
break;
}
else
- print_tree_identifier (scratch_buffer, t);
+ pp_tree_identifier (cxx_pp, t);
break;
case OVERLOAD:
@@ -936,12 +866,12 @@ dump_decl (t, flags)
if (DECL_CLASS_SCOPE_P (t))
{
dump_type (DECL_CONTEXT (t), flags);
- output_add_string (scratch_buffer, "::");
+ pp_colon_colon (cxx_pp);
}
else if (DECL_CONTEXT (t))
{
dump_decl (DECL_CONTEXT (t), flags);
- output_add_string (scratch_buffer, "::");
+ pp_colon_colon (cxx_pp);
}
dump_decl (DECL_NAME (t), flags);
break;
@@ -956,7 +886,7 @@ dump_decl (t, flags)
if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
dump_global_iord (t);
else if (! DECL_LANG_SPECIFIC (t))
- print_identifier (scratch_buffer, "<internal>");
+ pp_identifier (cxx_pp, "<internal>");
else
dump_function_decl (t, flags);
break;
@@ -967,28 +897,20 @@ dump_decl (t, flags)
case TEMPLATE_ID_EXPR:
{
- tree args;
tree name = TREE_OPERAND (t, 0);
+
if (is_overloaded_fn (name))
name = DECL_NAME (get_first_fn (name));
dump_decl (name, flags);
- print_template_argument_list_start (scratch_buffer);
- for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args))
- {
- dump_template_argument (TREE_VALUE (args), flags);
- if (TREE_CHAIN (args))
- separate_with_comma (scratch_buffer);
- }
- print_template_argument_list_end (scratch_buffer);
+ pp_template_argument_list_start (cxx_pp);
+ if (TREE_OPERAND (t, 1))
+ dump_template_argument_list (TREE_OPERAND (t, 1), flags);
+ pp_template_argument_list_end (cxx_pp);
}
break;
- case LOOKUP_EXPR:
- dump_decl (TREE_OPERAND (t, 0), flags);
- break;
-
case LABEL_DECL:
- print_tree_identifier (scratch_buffer, DECL_NAME (t));
+ pp_tree_identifier (cxx_pp, DECL_NAME (t));
break;
case CONST_DECL:
@@ -1001,13 +923,13 @@ dump_decl (t, flags)
else if (DECL_INITIAL (t))
dump_expr (DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS);
else
- print_identifier (scratch_buffer, "enumerator");
+ pp_identifier (cxx_pp, "<enumerator>");
break;
case USING_DECL:
- output_add_string (scratch_buffer, "using ");
+ pp_string (cxx_pp, "using ");
dump_type (DECL_INITIAL (t), flags);
- print_scope_operator (scratch_buffer);
+ pp_colon_colon (cxx_pp);
dump_decl (DECL_NAME (t), flags);
break;
@@ -1015,12 +937,23 @@ dump_decl (t, flags)
dump_decl (BASELINK_FUNCTIONS (t), flags);
break;
+ case NON_DEPENDENT_EXPR:
+ dump_expr (t, flags);
+ break;
+
+ case TEMPLATE_TYPE_PARM:
+ if (flags & TFF_DECL_SPECIFIERS)
+ pp_cxx_declaration (cxx_pp, t);
+ else
+ pp_type_id (cxx_pp, t);
+ break;
+
default:
- sorry_for_unsupported_tree (t);
+ pp_unsupported_tree (cxx_pp, t);
/* Fallthrough to error. */
case ERROR_MARK:
- print_identifier (scratch_buffer, "<declaration error>");
+ pp_identifier (cxx_pp, "<declaration error>");
break;
}
}
@@ -1029,9 +962,7 @@ dump_decl (t, flags)
'template <...> leaders plus the 'class X' or 'void fn(...)' part. */
static void
-dump_template_decl (t, flags)
- tree t;
- int flags;
+dump_template_decl (tree t, int flags)
{
tree orig_parms = DECL_TEMPLATE_PARMS (t);
tree parms;
@@ -1046,7 +977,7 @@ dump_template_decl (t, flags)
tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
int len = TREE_VEC_LENGTH (inner_parms);
- output_add_string (scratch_buffer, "template<");
+ pp_string (cxx_pp, "template<");
/* If we've shown the template prefix, we'd better show the
parameters' and decl's type too. */
@@ -1055,17 +986,17 @@ dump_template_decl (t, flags)
for (i = 0; i < len; i++)
{
if (i)
- separate_with_comma (scratch_buffer);
+ pp_separate_with_comma (cxx_pp);
dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags);
}
- print_template_argument_list_end (scratch_buffer);
- output_add_space (scratch_buffer);
+ pp_template_argument_list_end (cxx_pp);
+ pp_space (cxx_pp);
}
nreverse(orig_parms);
if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
/* Say `template<arg> class TT' not just `template<arg> TT'. */
- output_add_string (scratch_buffer, "class ");
+ pp_string (cxx_pp, "class ");
}
if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL)
@@ -1097,9 +1028,7 @@ dump_template_decl (t, flags)
is %D which doesn't print the throw specs, and %F which does. */
static void
-dump_function_decl (t, flags)
- tree t;
- int flags;
+dump_function_decl (tree t, int flags)
{
tree fntype;
tree parmtypes;
@@ -1130,16 +1059,16 @@ dump_function_decl (t, flags)
if (DECL_CLASS_SCOPE_P (t))
cname = DECL_CONTEXT (t);
- /* this is for partially instantiated template methods */
+ /* This is for partially instantiated template methods. */
else if (TREE_CODE (fntype) == METHOD_TYPE)
cname = TREE_TYPE (TREE_VALUE (parmtypes));
if (!(flags & TFF_DECL_SPECIFIERS))
/* OK */;
else if (DECL_STATIC_FUNCTION_P (t))
- print_identifier (scratch_buffer, "static ");
+ pp_identifier (cxx_pp, "static ");
else if (DECL_VIRTUAL_P (t))
- print_identifier (scratch_buffer, "virtual ");
+ pp_identifier (cxx_pp, "virtual ");
/* Print the return type? */
if (show_return)
@@ -1148,21 +1077,21 @@ dump_function_decl (t, flags)
if (show_return)
{
dump_type_prefix (TREE_TYPE (fntype), flags);
- output_add_space (scratch_buffer);
+ pp_space (cxx_pp);
}
/* Print the function name. */
if (cname)
{
dump_type (cname, flags);
- print_scope_operator (scratch_buffer);
+ pp_colon_colon (cxx_pp);
}
else
dump_scope (CP_DECL_CONTEXT (t), flags);
dump_function_name (t, flags);
- if (1)
+ if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
{
dump_parameters (parmtypes, flags);
@@ -1180,9 +1109,9 @@ dump_function_decl (t, flags)
/* If T is a template instantiation, dump the parameter binding. */
if (template_parms != NULL_TREE && template_args != NULL_TREE)
{
- output_add_string (scratch_buffer, " [with ");
+ pp_string (cxx_pp, " [with ");
dump_template_bindings (template_parms, template_args);
- print_right_bracket (scratch_buffer);
+ pp_right_bracket (cxx_pp);
}
}
@@ -1191,47 +1120,43 @@ dump_function_decl (t, flags)
already been removed. */
static void
-dump_parameters (parmtypes, flags)
- tree parmtypes;
- int flags;
+dump_parameters (tree parmtypes, int flags)
{
int first;
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
for (first = 1; parmtypes != void_list_node;
parmtypes = TREE_CHAIN (parmtypes))
{
if (!first)
- separate_with_comma (scratch_buffer);
+ pp_separate_with_comma (cxx_pp);
first = 0;
if (!parmtypes)
{
- print_identifier (scratch_buffer, "...");
+ pp_identifier (cxx_pp, "...");
break;
}
dump_type (TREE_VALUE (parmtypes), flags);
if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes))
{
- output_add_string (scratch_buffer, " = ");
+ pp_string (cxx_pp, " = ");
dump_expr (TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS);
}
}
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
}
/* Print an exception specification. T is the exception specification. */
static void
-dump_exception_spec (t, flags)
- tree t;
- int flags;
+dump_exception_spec (tree t, int flags)
{
if (t)
{
- output_add_string (scratch_buffer, " throw (");
+ pp_string (cxx_pp, " throw (");
if (TREE_VALUE (t) != NULL_TREE)
while (1)
{
@@ -1239,9 +1164,9 @@ dump_exception_spec (t, flags)
t = TREE_CHAIN (t);
if (!t)
break;
- separate_with_comma (scratch_buffer);
+ pp_separate_with_comma (cxx_pp);
}
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
}
}
@@ -1249,9 +1174,7 @@ dump_exception_spec (t, flags)
and destructors properly. */
static void
-dump_function_name (t, flags)
- tree t;
- int flags;
+dump_function_name (tree t, int flags)
{
tree name = DECL_NAME (t);
@@ -1265,7 +1188,7 @@ dump_function_name (t, flags)
if (DECL_DESTRUCTOR_P (t))
{
- output_add_character (scratch_buffer, '~');
+ pp_complement (cxx_pp);
dump_decl (name, TFF_PLAIN_IDENTIFIER);
}
else if (DECL_CONV_FN_P (t))
@@ -1276,11 +1199,11 @@ dump_function_name (t, flags)
declarations, both will have the same name, yet
the types will be different, hence the TREE_TYPE field
of the first name will be clobbered by the second. */
- output_add_string (scratch_buffer, "operator ");
+ pp_string (cxx_pp, "operator ");
dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
}
else if (IDENTIFIER_OPNAME_P (name))
- print_tree_identifier (scratch_buffer, name);
+ pp_tree_identifier (cxx_pp, name);
else
dump_decl (name, flags);
@@ -1300,57 +1223,37 @@ dump_function_name (t, flags)
decoration. */
static void
-dump_template_parms (info, primary, flags)
- tree info;
- int primary;
- int flags;
+dump_template_parms (tree info, int primary, int flags)
{
tree args = info ? TI_ARGS (info) : NULL_TREE;
if (primary && flags & TFF_TEMPLATE_NAME)
return;
flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME);
- print_template_argument_list_start (scratch_buffer);
+ pp_template_argument_list_start (cxx_pp);
/* Be careful only to print things when we have them, so as not
to crash producing error messages. */
if (args && !primary)
{
- int len = 0;
- int ix = 0;
- int need_comma = 0;
+ int len, ix;
- if (TREE_CODE (args) == TREE_VEC)
- {
- if (TREE_VEC_LENGTH (args) > 0
- && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
- args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
+ if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
+ args = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
+
+ len = TREE_VEC_LENGTH (args);
- len = TREE_VEC_LENGTH (args);
- }
- else if (TREE_CODE (args) == TREE_LIST)
- len = -1;
- while (ix != len && args)
+ for (ix = 0; ix != len; ix++)
{
- tree arg;
- if (len >= 0)
- {
- arg = TREE_VEC_ELT (args, ix);
- ix++;
- }
- else
- {
- arg = TREE_VALUE (args);
- args = TREE_CHAIN (args);
- }
- if (need_comma)
- separate_with_comma (scratch_buffer);
+ tree arg = TREE_VEC_ELT (args, ix);
+
+ if (ix)
+ pp_separate_with_comma (cxx_pp);
if (!arg)
- print_identifier (scratch_buffer, "<template parameter error>");
+ pp_identifier (cxx_pp, "<template parameter error>");
else
dump_template_argument (arg, flags);
- need_comma = 1;
}
}
else if (primary)
@@ -1367,83 +1270,32 @@ dump_template_parms (info, primary, flags)
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
if (ix)
- separate_with_comma (scratch_buffer);
+ pp_separate_with_comma (cxx_pp);
dump_decl (parm, flags & ~TFF_DECL_SPECIFIERS);
}
}
- print_template_argument_list_end (scratch_buffer);
+ pp_template_argument_list_end (cxx_pp);
}
-static void
-dump_char (c)
- int c;
-{
- switch (c)
- {
- case TARGET_NEWLINE:
- output_add_string (scratch_buffer, "\\n");
- break;
- case TARGET_TAB:
- output_add_string (scratch_buffer, "\\t");
- break;
- case TARGET_VT:
- output_add_string (scratch_buffer, "\\v");
- break;
- case TARGET_BS:
- output_add_string (scratch_buffer, "\\b");
- break;
- case TARGET_CR:
- output_add_string (scratch_buffer, "\\r");
- break;
- case TARGET_FF:
- output_add_string (scratch_buffer, "\\f");
- break;
- case TARGET_BELL:
- output_add_string (scratch_buffer, "\\a");
- break;
- case '\\':
- output_add_string (scratch_buffer, "\\\\");
- break;
- case '\'':
- output_add_string (scratch_buffer, "\\'");
- break;
- case '\"':
- output_add_string (scratch_buffer, "\\\"");
- break;
- default:
- if (ISPRINT (c))
- output_add_character (scratch_buffer, c);
- else
- {
- sprintf (digit_buffer, "\\%03o", (int) c);
- output_add_string (scratch_buffer, digit_buffer);
- }
- }
-}
-
-/* Print out a list of initializers (subr of dump_expr) */
+/* Print out a list of initializers (subr of dump_expr). */
static void
-dump_expr_list (l, flags)
- tree l;
- int flags;
+dump_expr_list (tree l, int flags)
{
while (l)
{
dump_expr (TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS);
l = TREE_CHAIN (l);
if (l)
- separate_with_comma (scratch_buffer);
+ pp_separate_with_comma (cxx_pp);
}
}
/* Print out an expression E under control of FLAGS. */
static void
-dump_expr (t, flags)
- tree t;
- int flags;
+dump_expr (tree t, int flags)
{
if (t == 0)
return;
@@ -1458,138 +1310,54 @@ dump_expr (t, flags)
case TEMPLATE_DECL:
case NAMESPACE_DECL:
case OVERLOAD:
- dump_decl (t, flags & ~TFF_DECL_SPECIFIERS);
+ case IDENTIFIER_NODE:
+ dump_decl (t, (flags & ~TFF_DECL_SPECIFIERS) | TFF_NO_FUNCTION_ARGUMENTS);
break;
case INTEGER_CST:
- {
- tree type = TREE_TYPE (t);
- my_friendly_assert (type != 0, 81);
-
- /* If it's an enum, output its tag, rather than its value. */
- if (TREE_CODE (type) == ENUMERAL_TYPE)
- {
- tree values = TYPE_VALUES (type);
-
- for (; values;
- values = TREE_CHAIN (values))
- if (tree_int_cst_equal (TREE_VALUE (values), t))
- break;
-
- if (values)
- print_tree_identifier (scratch_buffer, TREE_PURPOSE (values));
- else
- {
- /* Value must have been cast. */
- print_left_paren (scratch_buffer);
- dump_type (type, flags);
- print_right_paren (scratch_buffer);
- goto do_int;
- }
- }
- else if (type == boolean_type_node)
- {
- if (t == boolean_false_node || integer_zerop (t))
- print_identifier (scratch_buffer, "false");
- else if (t == boolean_true_node)
- print_identifier (scratch_buffer, "true");
- }
- else if (type == char_type_node)
- {
- output_add_character (scratch_buffer, '\'');
- if (host_integerp (t, TREE_UNSIGNED (type)))
- dump_char (tree_low_cst (t, TREE_UNSIGNED (type)));
- else
- output_printf (scratch_buffer, "\\x%x",
- (unsigned int) TREE_INT_CST_LOW (t));
- output_add_character (scratch_buffer, '\'');
- }
- else
- {
- do_int:
- if (! host_integerp (t, 0))
- {
- tree val = t;
-
- if (tree_int_cst_sgn (val) < 0)
- {
- output_add_character (scratch_buffer, '-');
- val = build_int_2 (-TREE_INT_CST_LOW (val),
- ~TREE_INT_CST_HIGH (val)
- + !TREE_INT_CST_LOW (val));
- }
- /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
- systems? */
- {
- static char format[10]; /* "%x%09999x\0" */
- if (!format[0])
- sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4);
- sprintf (digit_buffer, format, TREE_INT_CST_HIGH (val),
- TREE_INT_CST_LOW (val));
- output_add_string (scratch_buffer, digit_buffer);
- }
- }
- else
- print_integer (scratch_buffer, TREE_INT_CST_LOW (t));
- }
- }
+ case STRING_CST:
+ case REAL_CST:
+ pp_c_constant (pp_c_base (cxx_pp), t);
break;
- case REAL_CST:
- real_to_decimal (digit_buffer, &TREE_REAL_CST (t),
- sizeof (digit_buffer), 0, 1);
- output_add_string (scratch_buffer, digit_buffer);
+ case THROW_EXPR:
+ pp_identifier (cxx_pp, "throw");
+ dump_expr (TREE_OPERAND (t, 0), flags);
break;
case PTRMEM_CST:
- output_add_character (scratch_buffer, '&');
+ pp_ampersand (cxx_pp);
dump_type (PTRMEM_CST_CLASS (t), flags);
- print_scope_operator (scratch_buffer);
- print_tree_identifier
- (scratch_buffer, DECL_NAME (PTRMEM_CST_MEMBER (t)));
- break;
-
- case STRING_CST:
- {
- const char *p = TREE_STRING_POINTER (t);
- int len = TREE_STRING_LENGTH (t) - 1;
- int i;
-
- output_add_character (scratch_buffer, '\"');
- for (i = 0; i < len; i++)
- dump_char (p[i]);
- output_add_character (scratch_buffer, '\"');
- }
+ pp_colon_colon (cxx_pp);
+ pp_tree_identifier (cxx_pp, DECL_NAME (PTRMEM_CST_MEMBER (t)));
break;
case COMPOUND_EXPR:
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- separate_with_comma (scratch_buffer);
+ pp_separate_with_comma (cxx_pp);
dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
break;
case COND_EXPR:
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- output_add_string (scratch_buffer, " ? ");
+ pp_string (cxx_pp, " ? ");
dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
- output_add_string (scratch_buffer, " : ");
+ pp_string (cxx_pp, " : ");
dump_expr (TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS);
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
break;
case SAVE_EXPR:
if (TREE_HAS_CONSTRUCTOR (t))
{
- output_add_string (scratch_buffer, "new ");
+ pp_string (cxx_pp, "new ");
dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
}
else
- {
- dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- }
+ dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
break;
case AGGR_INIT_EXPR:
@@ -1602,18 +1370,17 @@ dump_expr (t, flags)
if (fn && TREE_CODE (fn) == FUNCTION_DECL)
{
if (DECL_CONSTRUCTOR_P (fn))
- print_tree_identifier
- (scratch_buffer, TYPE_IDENTIFIER (TREE_TYPE (t)));
+ pp_tree_identifier (cxx_pp, TYPE_IDENTIFIER (TREE_TYPE (t)));
else
dump_decl (fn, 0);
}
else
dump_expr (TREE_OPERAND (t, 0), 0);
}
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
if (TREE_OPERAND (t, 1))
dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
break;
case CALL_EXPR:
@@ -1630,20 +1397,20 @@ dump_expr (t, flags)
if (TREE_CODE (ob) == ADDR_EXPR)
{
dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
- output_add_character (scratch_buffer, '.');
+ pp_dot (cxx_pp);
}
else if (TREE_CODE (ob) != PARM_DECL
|| strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
{
dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
- output_add_string (scratch_buffer, "->");
+ pp_arrow (cxx_pp);
}
args = TREE_CHAIN (args);
}
dump_expr (fn, flags | TFF_EXPR_IN_PARENS);
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
dump_expr_list (args, flags);
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
}
break;
@@ -1652,13 +1419,13 @@ dump_expr (t, flags)
tree type = TREE_OPERAND (t, 1);
tree init = TREE_OPERAND (t, 2);
if (NEW_EXPR_USE_GLOBAL (t))
- print_scope_operator (scratch_buffer);
- output_add_string (scratch_buffer, "new ");
+ pp_colon_colon (cxx_pp);
+ pp_string (cxx_pp, "new ");
if (TREE_OPERAND (t, 0))
{
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
dump_expr_list (TREE_OPERAND (t, 0), flags);
- output_add_string (scratch_buffer, ") ");
+ pp_string (cxx_pp, ") ");
}
if (TREE_CODE (type) == ARRAY_REF)
type = build_cplus_array_type
@@ -1669,7 +1436,7 @@ dump_expr (t, flags)
dump_type (type, flags);
if (init)
{
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
if (TREE_CODE (init) == TREE_LIST)
dump_expr_list (init, flags);
else if (init == void_zero_node)
@@ -1678,7 +1445,7 @@ dump_expr (t, flags)
;
else
dump_expr (init, flags);
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
}
}
break;
@@ -1707,7 +1474,6 @@ dump_expr (t, flags)
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
case BIT_AND_EXPR:
- case BIT_ANDTC_EXPR:
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
case LT_EXPR:
@@ -1742,13 +1508,13 @@ dump_expr (t, flags)
|| strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
{
dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
- output_add_string (scratch_buffer, "->");
+ pp_arrow (cxx_pp);
}
}
else
{
dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
- output_add_character (scratch_buffer, '.');
+ pp_dot (cxx_pp);
}
dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
}
@@ -1756,17 +1522,17 @@ dump_expr (t, flags)
case ARRAY_REF:
dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- print_left_bracket (scratch_buffer);
+ pp_left_bracket (cxx_pp);
dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
- print_right_bracket (scratch_buffer);
+ pp_right_bracket (cxx_pp);
break;
case CONVERT_EXPR:
if (TREE_TYPE (t) && VOID_TYPE_P (TREE_TYPE (t)))
{
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
dump_type (TREE_TYPE (t), flags);
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
dump_expr (TREE_OPERAND (t, 0), flags);
}
else
@@ -1792,9 +1558,9 @@ dump_expr (t, flags)
t = TREE_OPERAND (t, 0);
my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237);
dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1)), flags);
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
}
else
{
@@ -1817,11 +1583,10 @@ dump_expr (t, flags)
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- print_identifier
- (scratch_buffer, operator_name_info[(int)TREE_CODE (t)].name);
- print_right_paren (scratch_buffer);
+ pp_identifier (cxx_pp, operator_name_info[(int)TREE_CODE (t)].name);
+ pp_right_paren (cxx_pp);
break;
case NON_LVALUE_EXPR:
@@ -1838,22 +1603,40 @@ dump_expr (t, flags)
if (TREE_CODE (next) == FUNCTION_TYPE)
{
if (flags & TFF_EXPR_IN_PARENS)
- print_left_paren (scratch_buffer);
- output_add_character (scratch_buffer, '*');
+ pp_left_paren (cxx_pp);
+ pp_star (cxx_pp);
dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
if (flags & TFF_EXPR_IN_PARENS)
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
break;
}
- /* else FALLTHRU */
+ /* Else fall through. */
}
dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
break;
case NOP_EXPR:
- dump_expr (TREE_OPERAND (t, 0), flags);
- break;
-
+ {
+ tree op = TREE_OPERAND (t, 0);
+
+ if (!same_type_p (TREE_TYPE (op), TREE_TYPE (t)))
+ {
+ /* It is a cast, but we cannot tell whether it is a
+ reinterpret or static cast. Use the C style notation. */
+ if (flags & TFF_EXPR_IN_PARENS)
+ pp_left_paren (cxx_pp);
+ pp_left_paren (cxx_pp);
+ dump_type (TREE_TYPE (t), flags);
+ pp_right_paren (cxx_pp);
+ dump_expr (op, flags | TFF_EXPR_IN_PARENS);
+ if (flags & TFF_EXPR_IN_PARENS)
+ pp_right_paren (cxx_pp);
+ }
+ else
+ dump_expr (op, flags);
+ break;
+ }
+
case EXPR_WITH_FILE_LOCATION:
dump_expr (EXPR_WFL_NODE (t), flags);
break;
@@ -1866,9 +1649,11 @@ dump_expr (t, flags)
if (integer_zerop (idx))
{
/* A NULL pointer-to-member constant. */
- output_add_string (scratch_buffer, "((");
+ pp_left_paren (cxx_pp);
+ pp_left_paren (cxx_pp);
dump_type (TREE_TYPE (t), flags);
- output_add_string (scratch_buffer, ") 0)");
+ pp_right_paren (cxx_pp);
+ pp_string (cxx_pp, ")0)");
break;
}
else if (host_integerp (idx, 0))
@@ -1899,19 +1684,19 @@ dump_expr (t, flags)
}
}
}
- /* We've gotten an rvalue of the form 'T()'. */
- else if (TREE_TYPE (t))
- {
- dump_type (TREE_TYPE (t), flags);
- print_left_paren (scratch_buffer);
- print_right_paren (scratch_buffer);
- }
+ if (TREE_TYPE (t) && !CONSTRUCTOR_ELTS (t))
+ {
+ dump_type (TREE_TYPE (t), 0);
+ pp_left_paren (cxx_pp);
+ pp_right_paren (cxx_pp);
+ }
else
- {
- output_add_character (scratch_buffer, '{');
- dump_expr_list (CONSTRUCTOR_ELTS (t), flags);
- output_add_character (scratch_buffer, '}');
- }
+ {
+ pp_left_brace (cxx_pp);
+ dump_expr_list (CONSTRUCTOR_ELTS (t), flags);
+ pp_right_brace (cxx_pp);
+ }
+
break;
case OFFSET_REF:
@@ -1934,12 +1719,12 @@ dump_expr (t, flags)
if (TREE_CODE (ob) == INDIRECT_REF)
{
dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
- output_add_string (scratch_buffer, "->*");
+ pp_string (cxx_pp, "->*");
}
else
{
dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
- output_add_string (scratch_buffer, ".*");
+ pp_string (cxx_pp, ".*");
}
dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
}
@@ -1950,13 +1735,9 @@ dump_expr (t, flags)
dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
break;
- case IDENTIFIER_NODE:
- print_tree_identifier (scratch_buffer, t);
- break;
-
case SCOPE_REF:
dump_type (TREE_OPERAND (t, 0), flags);
- print_scope_operator (scratch_buffer);
+ pp_colon_colon (cxx_pp);
dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
break;
@@ -1965,65 +1746,68 @@ dump_expr (t, flags)
|| TREE_CHAIN (TREE_OPERAND (t, 0)))
{
dump_type (TREE_TYPE (t), flags);
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
dump_expr_list (TREE_OPERAND (t, 0), flags);
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
}
else
{
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
dump_type (TREE_TYPE (t), flags);
- output_add_string (scratch_buffer, ")(");
+ pp_string (cxx_pp, ")(");
dump_expr_list (TREE_OPERAND (t, 0), flags);
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
}
break;
case STATIC_CAST_EXPR:
- output_add_string (scratch_buffer, "static_cast<");
+ pp_string (cxx_pp, "static_cast<");
goto cast;
case REINTERPRET_CAST_EXPR:
- output_add_string (scratch_buffer, "reinterpret_cast<");
+ pp_string (cxx_pp, "reinterpret_cast<");
goto cast;
case CONST_CAST_EXPR:
- output_add_string (scratch_buffer, "const_cast<");
+ pp_string (cxx_pp, "const_cast<");
goto cast;
case DYNAMIC_CAST_EXPR:
- output_add_string (scratch_buffer, "dynamic_cast<");
+ pp_string (cxx_pp, "dynamic_cast<");
cast:
dump_type (TREE_TYPE (t), flags);
- output_add_string (scratch_buffer, ">(");
+ pp_string (cxx_pp, ">(");
dump_expr (TREE_OPERAND (t, 0), flags);
- print_right_paren (scratch_buffer);
- break;
-
- case LOOKUP_EXPR:
- print_tree_identifier (scratch_buffer, TREE_OPERAND (t, 0));
+ pp_right_paren (cxx_pp);
break;
case ARROW_EXPR:
dump_expr (TREE_OPERAND (t, 0), flags);
- output_add_string (scratch_buffer, "->");
+ pp_arrow (cxx_pp);
break;
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
if (TREE_CODE (t) == SIZEOF_EXPR)
- output_add_string (scratch_buffer, "sizeof (");
+ pp_string (cxx_pp, "sizeof (");
else
{
my_friendly_assert (TREE_CODE (t) == ALIGNOF_EXPR, 0);
- output_add_string (scratch_buffer, "__alignof__ (");
+ pp_string (cxx_pp, "__alignof__ (");
}
if (TYPE_P (TREE_OPERAND (t, 0)))
dump_type (TREE_OPERAND (t, 0), flags);
else
- dump_unary_op ("*", t, flags | TFF_EXPR_IN_PARENS);
- print_right_paren (scratch_buffer);
+ dump_expr (TREE_OPERAND (t, 0), flags);
+ pp_right_paren (cxx_pp);
+ break;
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ pp_identifier (cxx_pp, operator_name_info[TREE_CODE (t)].name);
+ pp_space (cxx_pp);
+ dump_expr (TREE_OPERAND (t, 0), flags);
break;
case DEFAULT_ARG:
- print_identifier (scratch_buffer, "<unparsed>");
+ pp_identifier (cxx_pp, "<unparsed>");
break;
case TRY_CATCH_EXPR:
@@ -2034,9 +1818,10 @@ dump_expr (t, flags)
case PSEUDO_DTOR_EXPR:
dump_expr (TREE_OPERAND (t, 2), flags);
- output_add_character (scratch_buffer, '.');
+ pp_dot (cxx_pp);
dump_type (TREE_OPERAND (t, 0), flags);
- output_add_string (scratch_buffer, "::~");
+ pp_colon_colon (cxx_pp);
+ pp_complement (cxx_pp);
dump_type (TREE_OPERAND (t, 1), flags);
break;
@@ -2047,150 +1832,127 @@ dump_expr (t, flags)
case STMT_EXPR:
/* We don't yet have a way of dumping statements in a
human-readable format. */
- output_add_string (scratch_buffer, "({...})");
+ pp_string (cxx_pp, "({...})");
break;
case BIND_EXPR:
- output_add_character (scratch_buffer, '{');
+ pp_left_brace (cxx_pp);
dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
- output_add_character (scratch_buffer, '}');
+ pp_right_brace (cxx_pp);
break;
case LOOP_EXPR:
- output_add_string (scratch_buffer, "while (1) { ");
+ pp_string (cxx_pp, "while (1) { ");
dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
- output_add_character (scratch_buffer, '}');
+ pp_right_brace (cxx_pp);
break;
case EXIT_EXPR:
- output_add_string (scratch_buffer, "if (");
+ pp_string (cxx_pp, "if (");
dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
- output_add_string (scratch_buffer, ") break; ");
+ pp_string (cxx_pp, ") break; ");
break;
case BASELINK:
- print_tree_identifier (scratch_buffer, DECL_NAME (get_first_fn (t)));
+ dump_expr (get_first_fn (t), flags & ~TFF_EXPR_IN_PARENS);
break;
- case TREE_LIST:
- if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL)
- {
- print_tree_identifier (scratch_buffer, DECL_NAME (TREE_VALUE (t)));
- break;
- }
- /* else fall through */
+ case EMPTY_CLASS_EXPR:
+ dump_type (TREE_TYPE (t), flags);
+ pp_left_paren (cxx_pp);
+ pp_right_paren (cxx_pp);
+ break;
+
+ case NON_DEPENDENT_EXPR:
+ dump_expr (TREE_OPERAND (t, 0), flags);
+ break;
/* This list is incomplete, but should suffice for now.
It is very important that `sorry' does not call
`report_error_function'. That could cause an infinite loop. */
default:
- sorry_for_unsupported_tree (t);
+ pp_unsupported_tree (cxx_pp, t);
/* fall through to ERROR_MARK... */
case ERROR_MARK:
- print_identifier (scratch_buffer, "<expression error>");
+ pp_identifier (cxx_pp, "<expression error>");
break;
}
}
static void
-dump_binary_op (opstring, t, flags)
- const char *opstring;
- tree t;
- int flags;
+dump_binary_op (const char *opstring, tree t, int flags)
{
- print_left_paren (scratch_buffer);
+ pp_left_paren (cxx_pp);
dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- output_add_space (scratch_buffer);
+ pp_space (cxx_pp);
if (opstring)
- print_identifier (scratch_buffer, opstring);
+ pp_identifier (cxx_pp, opstring);
else
- print_identifier (scratch_buffer, "<unknown operator>");
- output_add_space (scratch_buffer);
+ pp_identifier (cxx_pp, "<unknown operator>");
+ pp_space (cxx_pp);
dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
}
static void
-dump_unary_op (opstring, t, flags)
- const char *opstring;
- tree t;
- int flags;
+dump_unary_op (const char *opstring, tree t, int flags)
{
if (flags & TFF_EXPR_IN_PARENS)
- print_left_paren (scratch_buffer);
- print_identifier (scratch_buffer, opstring);
+ pp_left_paren (cxx_pp);
+ pp_identifier (cxx_pp, opstring);
dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
if (flags & TFF_EXPR_IN_PARENS)
- print_right_paren (scratch_buffer);
+ pp_right_paren (cxx_pp);
}
/* Exported interface to stringifying types, exprs and decls under TFF_*
control. */
const char *
-type_as_string (typ, flags)
- tree typ;
- int flags;
+type_as_string (tree typ, int flags)
{
- reinit_global_formatting_buffer ();
-
+ pp_clear_output_area (cxx_pp);
dump_type (typ, flags);
-
- return output_finalize_message (scratch_buffer);
+ return pp_formatted_text (cxx_pp);
}
const char *
-expr_as_string (decl, flags)
- tree decl;
- int flags;
+expr_as_string (tree decl, int flags)
{
- reinit_global_formatting_buffer ();
-
+ pp_clear_output_area (cxx_pp);
dump_expr (decl, flags);
-
- return output_finalize_message (scratch_buffer);
+ return pp_formatted_text (cxx_pp);
}
const char *
-decl_as_string (decl, flags)
- tree decl;
- int flags;
+decl_as_string (tree decl, int flags)
{
- reinit_global_formatting_buffer ();
-
+ pp_clear_output_area (cxx_pp);
dump_decl (decl, flags);
-
- return output_finalize_message (scratch_buffer);
+ return pp_formatted_text (cxx_pp);
}
const char *
-context_as_string (context, flags)
- tree context;
- int flags;
+context_as_string (tree context, int flags)
{
- reinit_global_formatting_buffer ();
-
+ pp_clear_output_area (cxx_pp);
dump_scope (context, flags);
-
- return output_finalize_message (scratch_buffer);
+ return pp_formatted_text (cxx_pp);
}
/* Generate the three forms of printable names for cxx_printable_name. */
const char *
-lang_decl_name (decl, v)
- tree decl;
- int v;
+lang_decl_name (tree decl, int v)
{
if (v >= 2)
return decl_as_string (decl, TFF_DECL_SPECIFIERS);
- reinit_global_formatting_buffer ();
-
+ pp_clear_output_area (cxx_pp);
if (v == 1 && DECL_CLASS_SCOPE_P (decl))
{
dump_type (CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER);
- print_scope_operator (scratch_buffer);
+ pp_colon_colon (cxx_pp);
}
if (TREE_CODE (decl) == FUNCTION_DECL)
@@ -2198,45 +1960,20 @@ lang_decl_name (decl, v)
else
dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
- return output_finalize_message (scratch_buffer);
+ return pp_formatted_text (cxx_pp);
}
-const char *
-cp_file_of (t)
- tree t;
+static location_t
+location_of (tree t)
{
if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
- return DECL_SOURCE_FILE (DECL_CONTEXT (t));
+ t = DECL_CONTEXT (t);
else if (TYPE_P (t))
- return DECL_SOURCE_FILE (TYPE_MAIN_DECL (t));
- else if (TREE_CODE (t) == OVERLOAD)
- return DECL_SOURCE_FILE (OVL_FUNCTION (t));
- else
- return DECL_SOURCE_FILE (t);
-}
-
-int
-cp_line_of (t)
- tree t;
-{
- int line = 0;
- if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t))
- line = DECL_SOURCE_LINE (DECL_CONTEXT (t));
- if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t)
- && TYPE_MAIN_DECL (TREE_TYPE (t)))
- t = TREE_TYPE (t);
-
- if (TYPE_P (t))
- line = DECL_SOURCE_LINE (TYPE_MAIN_DECL (t));
+ t = TYPE_MAIN_DECL (t);
else if (TREE_CODE (t) == OVERLOAD)
- line = DECL_SOURCE_LINE (OVL_FUNCTION (t));
- else
- line = DECL_SOURCE_LINE (t);
-
- if (line == 0)
- return lineno;
-
- return line;
+ t = OVL_FUNCTION (t);
+
+ return DECL_SOURCE_LOCATION (t);
}
/* Now the interfaces from error et al to dump_type et al. Each takes an
@@ -2244,9 +1981,7 @@ cp_line_of (t)
function. */
static const char *
-decl_to_string (decl, verbose)
- tree decl;
- int verbose;
+decl_to_string (tree decl, int verbose)
{
int flags = 0;
@@ -2259,55 +1994,41 @@ decl_to_string (decl, verbose)
flags |= TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE;
flags |= TFF_TEMPLATE_HEADER;
- reinit_global_formatting_buffer ();
-
+ pp_clear_output_area (cxx_pp);
dump_decl (decl, flags);
-
- return output_finalize_message (scratch_buffer);
+ return pp_formatted_text (cxx_pp);
}
static const char *
-expr_to_string (decl, verbose)
- tree decl;
- int verbose ATTRIBUTE_UNUSED;
+expr_to_string (tree decl)
{
- reinit_global_formatting_buffer ();
-
+ pp_clear_output_area (cxx_pp);
dump_expr (decl, 0);
-
- return output_finalize_message (scratch_buffer);
+ return pp_formatted_text (cxx_pp);
}
static const char *
-fndecl_to_string (fndecl, verbose)
- tree fndecl;
- int verbose;
+fndecl_to_string (tree fndecl, int verbose)
{
int flags;
flags = TFF_EXCEPTION_SPECIFICATION | TFF_DECL_SPECIFIERS;
if (verbose)
flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS;
- reinit_global_formatting_buffer ();
-
+ pp_clear_output_area (cxx_pp);
dump_decl (fndecl, flags);
-
- return output_finalize_message (scratch_buffer);
+ return pp_formatted_text (cxx_pp);
}
static const char *
-code_to_string (c, v)
- enum tree_code c;
- int v ATTRIBUTE_UNUSED;
+code_to_string (enum tree_code c)
{
return tree_code_name [c];
}
const char *
-language_to_string (c, v)
- enum languages c;
- int v ATTRIBUTE_UNUSED;
+language_to_string (enum languages c)
{
switch (c)
{
@@ -2329,62 +2050,45 @@ language_to_string (c, v)
/* Return the proper printed version of a parameter to a C++ function. */
static const char *
-parm_to_string (p, v)
- int p;
- int v ATTRIBUTE_UNUSED;
+parm_to_string (int p)
{
+ pp_clear_output_area (cxx_pp);
if (p < 0)
- return "`this'";
-
- sprintf (digit_buffer, "%d", p+1);
- return digit_buffer;
+ pp_string (cxx_pp, "'this'");
+ else
+ pp_decimal_int (cxx_pp, p + 1);
+ return pp_formatted_text (cxx_pp);
}
static const char *
-op_to_string (p, v)
- enum tree_code p;
- int v ATTRIBUTE_UNUSED;
+op_to_string (enum tree_code p)
{
- tree id;
-
- id = operator_name_info[(int) p].identifier;
- return id ? IDENTIFIER_POINTER (id) : "{unknown}";
+ tree id = operator_name_info[(int) p].identifier;
+ return id ? IDENTIFIER_POINTER (id) : "<unknown>";
}
static const char *
-type_to_string (typ, verbose)
- tree typ;
- int verbose;
+type_to_string (tree typ, int verbose)
{
- int flags;
-
- flags = 0;
+ int flags = 0;
if (verbose)
flags |= TFF_CLASS_KEY_OR_ENUM;
flags |= TFF_TEMPLATE_HEADER;
- reinit_global_formatting_buffer ();
-
+ pp_clear_output_area (cxx_pp);
dump_type (typ, flags);
-
- return output_finalize_message (scratch_buffer);
+ return pp_formatted_text (cxx_pp);
}
static const char *
-assop_to_string (p, v)
- enum tree_code p;
- int v ATTRIBUTE_UNUSED;
+assop_to_string (enum tree_code p)
{
- tree id;
-
- id = assignment_operator_name_info[(int) p].identifier;
+ tree id = assignment_operator_name_info[(int) p].identifier;
return id ? IDENTIFIER_POINTER (id) : "{unknown}";
}
static const char *
-args_to_string (p, verbose)
- tree p;
- int verbose;
+args_to_string (tree p, int verbose)
{
int flags = 0;
if (verbose)
@@ -2396,95 +2100,85 @@ args_to_string (p, verbose)
if (TYPE_P (TREE_VALUE (p)))
return type_as_string (p, flags);
- reinit_global_formatting_buffer ();
+ pp_clear_output_area (cxx_pp);
for (; p; p = TREE_CHAIN (p))
{
if (TREE_VALUE (p) == null_node)
- print_identifier (scratch_buffer, "NULL");
+ pp_identifier (cxx_pp, "NULL");
else
dump_type (error_type (TREE_VALUE (p)), flags);
if (TREE_CHAIN (p))
- separate_with_comma (scratch_buffer);
+ pp_separate_with_comma (cxx_pp);
}
- return output_finalize_message (scratch_buffer);
+ return pp_formatted_text (cxx_pp);
}
static const char *
-cv_to_string (p, v)
- tree p;
- int v;
+cv_to_string (tree p, int v)
{
- reinit_global_formatting_buffer ();
-
+ pp_clear_output_area (cxx_pp);
dump_qualifiers (p, v ? before : none);
-
- return output_finalize_message (scratch_buffer);
+ return pp_formatted_text (cxx_pp);
}
/* Langhook for print_error_function. */
void
-cxx_print_error_function (context, file)
- diagnostic_context *context;
- const char *file;
+cxx_print_error_function (diagnostic_context *context, const char *file)
{
lhd_print_error_function (context, file);
- output_set_prefix (&context->buffer, file);
+ pp_base_set_prefix (context->printer, file);
maybe_print_instantiation_context (context);
}
static void
-cp_diagnostic_starter (context, diagnostic)
- diagnostic_context *context;
- diagnostic_info *diagnostic;
+cp_diagnostic_starter (diagnostic_context *context,
+ diagnostic_info *diagnostic)
{
diagnostic_report_current_module (context);
cp_print_error_function (context, diagnostic);
maybe_print_instantiation_context (context);
- output_set_prefix (&context->buffer, diagnostic_build_prefix (diagnostic));
+ pp_base_set_prefix (context->printer, diagnostic_build_prefix (diagnostic));
}
static void
-cp_diagnostic_finalizer (context, diagnostic)
- diagnostic_context *context;
- diagnostic_info *diagnostic __attribute__((unused));
+cp_diagnostic_finalizer (diagnostic_context *context,
+ diagnostic_info *diagnostic ATTRIBUTE_UNUSED)
{
- output_destroy_prefix (&context->buffer);
+ pp_base_destroy_prefix (context->printer);
}
/* Print current function onto BUFFER, in the process of reporting
a diagnostic message. Called from cp_diagnostic_starter. */
static void
-cp_print_error_function (context, diagnostic)
- diagnostic_context *context;
- diagnostic_info *diagnostic;
+cp_print_error_function (diagnostic_context *context,
+ diagnostic_info *diagnostic)
{
if (diagnostic_last_function_changed (context))
{
- const char *old_prefix = output_prefix (&context->buffer);
+ const char *old_prefix = context->printer->prefix;
char *new_prefix = diagnostic->location.file
? file_name_as_prefix (diagnostic->location.file)
: NULL;
- output_set_prefix (&context->buffer, new_prefix);
+ pp_base_set_prefix (context->printer, new_prefix);
if (current_function_decl == NULL)
- output_add_string (&context->buffer, "At global scope:");
+ pp_base_string (context->printer, "At global scope:");
else
- output_printf (&context->buffer, "In %s `%s':",
- function_category (current_function_decl),
- cxx_printable_name (current_function_decl, 2));
- output_add_newline (&context->buffer);
+ pp_printf (context->printer, "In %s `%s':",
+ function_category (current_function_decl),
+ cxx_printable_name (current_function_decl, 2));
+ pp_base_newline (context->printer);
diagnostic_set_last_function (context);
- output_destroy_prefix (&context->buffer);
- context->buffer.state.prefix = old_prefix;
+ pp_base_destroy_prefix (context->printer);
+ context->printer->prefix = old_prefix;
}
}
/* Returns a description of FUNCTION using standard terminology. */
static const char *
-function_category (fn)
- tree fn;
+function_category (tree fn)
{
if (DECL_FUNCTION_MEMBER_P (fn))
{
@@ -2506,13 +2200,11 @@ function_category (fn)
/* Report the full context of a current template instantiation,
onto BUFFER. */
static void
-print_instantiation_full_context (context)
- diagnostic_context *context;
+print_instantiation_full_context (diagnostic_context *context)
{
tree p = current_instantiation ();
- int line = lineno;
- const char *file = input_filename;
-
+ location_t location = input_location;
+
if (p)
{
if (current_function_decl != TINST_DECL (p)
@@ -2526,43 +2218,41 @@ print_instantiation_full_context (context)
if (current_function_decl == TINST_DECL (p))
/* Avoid redundancy with the the "In function" line. */;
else
- output_verbatim (&context->buffer,
- "%s: In instantiation of `%s':\n", file,
- decl_as_string (TINST_DECL (p),
- TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
+ pp_verbatim (context->printer,
+ "%s: In instantiation of `%s':\n", location.file,
+ decl_as_string (TINST_DECL (p),
+ TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
- line = TINST_LINE (p);
- file = TINST_FILE (p);
+ location.line = TINST_LINE (p);
+ location.file = TINST_FILE (p);
p = TREE_CHAIN (p);
}
}
- print_instantiation_partial_context (context, p, file, line);
+ print_instantiation_partial_context (context, p, location);
}
/* Same as above but less verbose. */
static void
-print_instantiation_partial_context (context, t, file, line)
- diagnostic_context *context;
- tree t;
- const char *file;
- int line;
+print_instantiation_partial_context (diagnostic_context *context,
+ tree t, location_t loc)
{
for (; t; t = TREE_CHAIN (t))
{
- output_verbatim
- (&context->buffer, "%s:%d: instantiated from `%s'\n", file, line,
- decl_as_string (TINST_DECL (t), TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
- line = TINST_LINE (t);
- file = TINST_FILE (t);
+ pp_verbatim (context->printer, "%s:%d: instantiated from `%s'\n",
+ loc.file, loc.line,
+ decl_as_string (TINST_DECL (t),
+ TFF_DECL_SPECIFIERS | TFF_RETURN_TYPE));
+ loc.line = TINST_LINE (t);
+ loc.file = TINST_FILE (t);
}
- output_verbatim (&context->buffer, "%s:%d: instantiated from here\n", file, line);
+ pp_verbatim (context->printer, "%s:%d: instantiated from here\n",
+ loc.file, loc.line);
}
/* Called from cp_thing to print the template context for an error. */
static void
-maybe_print_instantiation_context (context)
- diagnostic_context *context;
+maybe_print_instantiation_context (diagnostic_context *context)
{
if (!problematic_instantiation_changed () || current_instantiation () == 0)
return;
@@ -2573,10 +2263,10 @@ maybe_print_instantiation_context (context)
/* Report the bare minimum context of a template instantiation. */
void
-print_instantiation_context ()
+print_instantiation_context (void)
{
print_instantiation_partial_context
- (global_dc, current_instantiation (), input_filename, lineno);
+ (global_dc, current_instantiation (), input_location);
diagnostic_flush_buffer (global_dc);
}
@@ -2594,9 +2284,7 @@ print_instantiation_context ()
%T type.
%V cv-qualifier. */
static bool
-cp_printer (buffer, text)
- output_buffer *buffer;
- text_info *text;
+cp_printer (pretty_printer *pp, text_info *text)
{
int verbose = 0;
const char *result;
@@ -2616,14 +2304,14 @@ cp_printer (buffer, text)
switch (*text->format_spec)
{
case 'A': result = args_to_string (next_tree, verbose); break;
- case 'C': result = code_to_string (next_tcode, verbose); break;
+ case 'C': result = code_to_string (next_tcode); break;
case 'D': result = decl_to_string (next_tree, verbose); break;
- case 'E': result = expr_to_string (next_tree, verbose); break;
+ case 'E': result = expr_to_string (next_tree); break;
case 'F': result = fndecl_to_string (next_tree, verbose); break;
- case 'L': result = language_to_string (next_lang, verbose); break;
- case 'O': result = op_to_string (next_tcode, verbose); break;
- case 'P': result = parm_to_string (next_int, verbose); break;
- case 'Q': result = assop_to_string (next_tcode, verbose); break;
+ case 'L': result = language_to_string (next_lang); break;
+ case 'O': result = op_to_string (next_tcode); break;
+ case 'P': result = parm_to_string (next_int); break;
+ case 'Q': result = assop_to_string (next_tcode); break;
case 'T': result = type_to_string (next_tree, verbose); break;
case 'V': result = cv_to_string (next_tree, verbose); break;
@@ -2631,7 +2319,7 @@ cp_printer (buffer, text)
return false;
}
- output_add_string (buffer, result);
+ pp_base_string (pp, result);
return true;
#undef next_tree
#undef next_tcode
@@ -2640,33 +2328,20 @@ cp_printer (buffer, text)
}
static void
-print_integer (buffer, i)
- output_buffer *buffer;
- HOST_WIDE_INT i;
-{
- sprintf (digit_buffer, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) i);
- output_add_string (buffer, digit_buffer);
-}
-
-static void
-print_non_consecutive_character (buffer, c)
- output_buffer *buffer;
- int c;
+pp_non_consecutive_character (cxx_pretty_printer *pp, int c)
{
- const char *p = output_last_position (buffer);
+ const char *p = pp_last_position_in_text (pp);
if (p != NULL && *p == c)
- output_add_space (buffer);
- output_add_character (buffer, c);
+ pp_space (pp);
+ pp_character (pp, c);
}
/* These are temporary wrapper functions which handle the historic
behavior of cp_*_at. */
static tree
-locate_error (msgid, ap)
- const char *msgid;
- va_list ap;
+locate_error (const char *msgid, va_list ap)
{
tree here = 0, t;
int plus = 0;
@@ -2687,6 +2362,7 @@ locate_error (msgid, ap)
{
/* Just ignore these possibilities. */
case '%': break;
+ case 'P':
case 'd': (void) va_arg (ap, int); break;
case 's': (void) va_arg (ap, char *); break;
case 'L': (void) va_arg (ap, enum languages); break;
@@ -2700,7 +2376,6 @@ locate_error (msgid, ap)
case 'D':
case 'E':
case 'F':
- case 'P':
case 'T':
case 'V':
t = va_arg (ap, tree);
@@ -2723,62 +2398,55 @@ locate_error (msgid, ap)
void
-cp_error_at VPARAMS ((const char *msgid, ...))
+cp_error_at (const char *msgid, ...)
{
tree here;
diagnostic_info diagnostic;
+ va_list ap;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_start (ap, msgid);
here = locate_error (msgid, ap);
- VA_CLOSE (ap);
-
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_end (ap);
+ va_start (ap, msgid);
diagnostic_set_info (&diagnostic, msgid, &ap,
- cp_file_of (here), cp_line_of (here), DK_ERROR);
+ location_of (here), DK_ERROR);
report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
+ va_end (ap);
}
void
-cp_warning_at VPARAMS ((const char *msgid, ...))
+cp_warning_at (const char *msgid, ...)
{
tree here;
diagnostic_info diagnostic;
+ va_list ap;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_start (ap, msgid);
here = locate_error (msgid, ap);
- VA_CLOSE (ap);
-
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_end (ap);
+ va_start (ap, msgid);
diagnostic_set_info (&diagnostic, msgid, &ap,
- cp_file_of (here), cp_line_of (here), DK_WARNING);
+ location_of (here), DK_WARNING);
report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
+ va_end (ap);
}
void
-cp_pedwarn_at VPARAMS ((const char *msgid, ...))
+cp_pedwarn_at (const char *msgid, ...)
{
tree here;
diagnostic_info diagnostic;
+ va_list ap;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_start (ap, msgid);
here = locate_error (msgid, ap);
- VA_CLOSE (ap);
-
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_end (ap);
+ va_start (ap, msgid);
diagnostic_set_info (&diagnostic, msgid, &ap,
- cp_file_of (here), cp_line_of (here),
- pedantic_error_kind());
+ location_of (here), pedantic_error_kind());
report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
+ va_end (ap);
}
diff --git a/contrib/gcc/cp/except.c b/contrib/gcc/cp/except.c
index 747cc1aaef69..c8112d1db130 100644
--- a/contrib/gcc/cp/except.c
+++ b/contrib/gcc/cp/except.c
@@ -1,30 +1,32 @@
/* Handle exceptional things in C++.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann <tiemann@cygnus.com>
Rewritten by Mike Stump <mrs@cygnus.com>, based upon an
initial re-implementation courtesy Tad Hunt.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "expr.h"
@@ -36,29 +38,27 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "tree-inline.h"
-static void push_eh_cleanup PARAMS ((tree));
-static tree prepare_eh_type PARAMS ((tree));
-static tree build_eh_type_type PARAMS ((tree));
-static tree do_begin_catch PARAMS ((void));
-static int dtor_nothrow PARAMS ((tree));
-static tree do_end_catch PARAMS ((tree));
-static void push_eh_cleanup PARAMS ((tree));
-static bool decl_is_java_type PARAMS ((tree decl, int err));
-static void initialize_handler_parm PARAMS ((tree, tree));
-static tree do_allocate_exception PARAMS ((tree));
-static tree stabilize_throw_expr PARAMS ((tree, tree *));
-static tree wrap_cleanups_r PARAMS ((tree *, int *, void *));
-static int complete_ptr_ref_or_void_ptr_p PARAMS ((tree, tree));
-static bool is_admissible_throw_operand PARAMS ((tree));
-static int can_convert_eh PARAMS ((tree, tree));
-static void check_handlers_1 PARAMS ((tree, tree));
-static tree cp_protect_cleanup_actions PARAMS ((void));
+static void push_eh_cleanup (tree);
+static tree prepare_eh_type (tree);
+static tree build_eh_type_type (tree);
+static tree do_begin_catch (void);
+static int dtor_nothrow (tree);
+static tree do_end_catch (tree);
+static bool decl_is_java_type (tree decl, int err);
+static void initialize_handler_parm (tree, tree);
+static tree do_allocate_exception (tree);
+static tree wrap_cleanups_r (tree *, int *, void *);
+static int complete_ptr_ref_or_void_ptr_p (tree, tree);
+static bool is_admissible_throw_operand (tree);
+static int can_convert_eh (tree, tree);
+static void check_handlers_1 (tree, tree);
+static tree cp_protect_cleanup_actions (void);
/* Sets up all the global eh stuff that needs to be initialized at the
start of compilation. */
void
-init_exception_processing ()
+init_exception_processing (void)
{
tree tmp;
@@ -88,7 +88,7 @@ init_exception_processing ()
propagated out of a cleanup region. */
static tree
-cp_protect_cleanup_actions ()
+cp_protect_cleanup_actions (void)
{
/* [except.terminate]
@@ -98,8 +98,7 @@ cp_protect_cleanup_actions ()
}
static tree
-prepare_eh_type (type)
- tree type;
+prepare_eh_type (tree type)
{
if (type == NULL_TREE)
return type;
@@ -107,8 +106,7 @@ prepare_eh_type (type)
return error_mark_node;
/* peel back references, so they match. */
- if (TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
+ type = non_reference (type);
/* Peel off cv qualifiers. */
type = TYPE_MAIN_VARIANT (type);
@@ -116,12 +114,9 @@ prepare_eh_type (type)
return type;
}
-/* Build the address of a typeinfo decl for use in the runtime
- matching field of the exception model. */
-
-static tree
-build_eh_type_type (type)
- tree type;
+/* Return the type info for TYPE as used by EH machinery. */
+tree
+eh_type_info (tree type)
{
tree exp;
@@ -133,14 +128,27 @@ build_eh_type_type (type)
else
exp = get_tinfo_decl (type);
+ return exp;
+}
+
+/* Build the address of a typeinfo decl for use in the runtime
+ matching field of the exception model. */
+
+static tree
+build_eh_type_type (tree type)
+{
+ tree exp = eh_type_info (type);
+
+ if (!exp)
+ return NULL;
+
mark_used (exp);
- exp = build1 (ADDR_EXPR, ptr_type_node, exp);
- return exp;
+ return build1 (ADDR_EXPR, ptr_type_node, exp);
}
tree
-build_exc_ptr ()
+build_exc_ptr (void)
{
return build (EXC_PTR_EXPR, ptr_type_node);
}
@@ -149,14 +157,12 @@ build_exc_ptr ()
exception has been handled. */
static tree
-do_begin_catch ()
+do_begin_catch (void)
{
tree fn;
fn = get_identifier ("__cxa_begin_catch");
- if (IDENTIFIER_GLOBAL_VALUE (fn))
- fn = IDENTIFIER_GLOBAL_VALUE (fn);
- else
+ if (!get_global_value_if_present (fn, &fn))
{
/* Declare void* __cxa_begin_catch (void *). */
tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
@@ -171,8 +177,7 @@ do_begin_catch ()
NULL_TREE for a ... handler) will not throw an exception. */
static int
-dtor_nothrow (type)
- tree type;
+dtor_nothrow (tree type)
{
if (type == NULL_TREE)
return 0;
@@ -187,15 +192,12 @@ dtor_nothrow (type)
for the current catch block if no others are currently using it. */
static tree
-do_end_catch (type)
- tree type;
+do_end_catch (tree type)
{
tree fn, cleanup;
fn = get_identifier ("__cxa_end_catch");
- if (IDENTIFIER_GLOBAL_VALUE (fn))
- fn = IDENTIFIER_GLOBAL_VALUE (fn);
- else
+ if (!get_global_value_if_present (fn, &fn))
{
/* Declare void __cxa_end_catch (). */
fn = push_void_library_fn (fn, void_list_node);
@@ -212,8 +214,7 @@ do_end_catch (type)
/* This routine creates the cleanup for the current exception. */
static void
-push_eh_cleanup (type)
- tree type;
+push_eh_cleanup (tree type)
{
finish_decl_cleanup (NULL_TREE, do_end_catch (type));
}
@@ -222,9 +223,7 @@ push_eh_cleanup (type)
throw. */
static bool
-decl_is_java_type (decl, err)
- tree decl;
- int err;
+decl_is_java_type (tree decl, int err)
{
bool r = (TREE_CODE (decl) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
@@ -271,8 +270,7 @@ decl_is_java_type (decl, err)
__gxx_personality_(sj|v)0 in init_exception_processing - should it
be done here instead? */
void
-choose_personality_routine (lang)
- enum languages lang;
+choose_personality_routine (enum languages lang)
{
static enum {
chose_none,
@@ -297,7 +295,7 @@ choose_personality_routine (lang)
return;
case chose_none:
- ; /* proceed to language selection */
+ ; /* Proceed to language selection. */
}
switch (lang)
@@ -326,9 +324,7 @@ choose_personality_routine (lang)
/* Initialize the catch parameter DECL. */
static void
-initialize_handler_parm (decl, exp)
- tree decl;
- tree exp;
+initialize_handler_parm (tree decl, tree exp)
{
tree init;
tree init_type;
@@ -381,8 +377,7 @@ initialize_handler_parm (decl, exp)
/* Call this to start a catch block. DECL is the catch parameter. */
tree
-expand_start_catch_block (decl)
- tree decl;
+expand_start_catch_block (tree decl)
{
tree exp = NULL_TREE;
tree type;
@@ -449,7 +444,7 @@ expand_start_catch_block (decl)
the label to jump to if this catch block didn't match. */
void
-expand_end_catch_block ()
+expand_end_catch_block (void)
{
if (! doing_eh (1))
return;
@@ -463,7 +458,7 @@ expand_end_catch_block ()
}
tree
-begin_eh_spec_block ()
+begin_eh_spec_block (void)
{
tree r = build_stmt (EH_SPEC_BLOCK, NULL_TREE, NULL_TREE);
add_stmt (r);
@@ -471,9 +466,7 @@ begin_eh_spec_block ()
}
void
-finish_eh_spec_block (raw_raises, eh_spec_block)
- tree raw_raises;
- tree eh_spec_block;
+finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
{
tree raises;
@@ -483,8 +476,13 @@ finish_eh_spec_block (raw_raises, eh_spec_block)
for (raises = NULL_TREE;
raw_raises && TREE_VALUE (raw_raises);
raw_raises = TREE_CHAIN (raw_raises))
- raises = tree_cons (NULL_TREE, prepare_eh_type (TREE_VALUE (raw_raises)),
- raises);
+ {
+ tree type = prepare_eh_type (TREE_VALUE (raw_raises));
+ tree tinfo = eh_type_info (type);
+
+ mark_used (tinfo);
+ raises = tree_cons (NULL_TREE, type, raises);
+ }
EH_SPEC_RAISES (eh_spec_block) = raises;
}
@@ -492,15 +490,12 @@ finish_eh_spec_block (raw_raises, eh_spec_block)
/* Return a pointer to a buffer for an exception object of type TYPE. */
static tree
-do_allocate_exception (type)
- tree type;
+do_allocate_exception (tree type)
{
tree fn;
fn = get_identifier ("__cxa_allocate_exception");
- if (IDENTIFIER_GLOBAL_VALUE (fn))
- fn = IDENTIFIER_GLOBAL_VALUE (fn);
- else
+ if (!get_global_value_if_present (fn, &fn))
{
/* Declare void *__cxa_allocate_exception(size_t). */
tree tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
@@ -511,20 +506,16 @@ do_allocate_exception (type)
NULL_TREE));
}
-#if 0
/* Call __cxa_free_exception from a cleanup. This is never invoked
directly, but see the comment for stabilize_throw_expr. */
static tree
-do_free_exception (ptr)
- tree ptr;
+do_free_exception (tree ptr)
{
tree fn;
fn = get_identifier ("__cxa_free_exception");
- if (IDENTIFIER_GLOBAL_VALUE (fn))
- fn = IDENTIFIER_GLOBAL_VALUE (fn);
- else
+ if (!get_global_value_if_present (fn, &fn))
{
/* Declare void __cxa_free_exception (void *). */
fn = push_void_library_fn (fn, tree_cons (NULL_TREE, ptr_type_node,
@@ -533,16 +524,13 @@ do_free_exception (ptr)
return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
}
-#endif
/* Wrap all cleanups for TARGET_EXPRs in MUST_NOT_THROW_EXPR.
Called from build_throw via walk_tree_without_duplicates. */
static tree
-wrap_cleanups_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+wrap_cleanups_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
{
tree exp = *tp;
tree cleanup;
@@ -559,7 +547,7 @@ wrap_cleanups_r (tp, walk_subtrees, data)
cleanup = TARGET_EXPR_CLEANUP (exp);
if (cleanup)
{
- cleanup = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (cleanup), cleanup);
+ cleanup = build1 (MUST_NOT_THROW_EXPR, void_type_node, cleanup);
TARGET_EXPR_CLEANUP (exp) = cleanup;
}
@@ -567,65 +555,10 @@ wrap_cleanups_r (tp, walk_subtrees, data)
return NULL_TREE;
}
-/* Like stabilize_expr, but specifically for a thrown expression. When
- throwing a temporary class object, we want to construct it directly into
- the thrown exception, so we look past the TARGET_EXPR and stabilize the
- arguments of the call instead.
-
- The case where EXP is a call to a function returning a class is a bit of
- a grey area in the standard; it's unclear whether or not it should be
- allowed to throw. I'm going to say no, as that allows us to optimize
- this case without worrying about deallocating the exception object if it
- does. The alternatives would be either not optimizing this case, or
- wrapping the initialization in a TRY_CATCH_EXPR to call do_free_exception
- rather than in a MUST_NOT_THROW_EXPR, for this case only. */
-
-static tree
-stabilize_throw_expr (exp, initp)
- tree exp;
- tree *initp;
-{
- tree init_expr;
-
- if (TREE_CODE (exp) == TARGET_EXPR
- && TREE_CODE (TARGET_EXPR_INITIAL (exp)) == AGGR_INIT_EXPR
- && flag_elide_constructors)
- {
- tree aggr_init = AGGR_INIT_EXPR_CHECK (TARGET_EXPR_INITIAL (exp));
- tree args = TREE_OPERAND (aggr_init, 1);
- tree newargs = NULL_TREE;
- tree *p = &newargs;
-
- init_expr = void_zero_node;
- for (; args; args = TREE_CHAIN (args))
- {
- tree arg = TREE_VALUE (args);
- tree arg_init_expr;
-
- arg = stabilize_expr (arg, &arg_init_expr);
-
- if (TREE_SIDE_EFFECTS (arg_init_expr))
- init_expr = build (COMPOUND_EXPR, void_type_node, init_expr,
- arg_init_expr);
- *p = tree_cons (NULL_TREE, arg, NULL_TREE);
- p = &TREE_CHAIN (*p);
- }
- TREE_OPERAND (aggr_init, 1) = newargs;
- }
- else
- {
- exp = stabilize_expr (exp, &init_expr);
- }
-
- *initp = init_expr;
- return exp;
-}
-
/* Build a throw expression. */
tree
-build_throw (exp)
- tree exp;
+build_throw (tree exp)
{
tree fn;
@@ -633,7 +566,10 @@ build_throw (exp)
return exp;
if (processing_template_decl)
- return build_min (THROW_EXPR, void_type_node, exp);
+ {
+ current_function_returns_abnormally = 1;
+ return build_min (THROW_EXPR, void_type_node, exp);
+ }
if (exp == null_node)
warning ("throwing NULL, which has integral, not pointer type");
@@ -650,16 +586,19 @@ build_throw (exp)
if (exp && decl_is_java_type (TREE_TYPE (exp), 1))
{
tree fn = get_identifier ("_Jv_Throw");
- if (IDENTIFIER_GLOBAL_VALUE (fn))
- fn = IDENTIFIER_GLOBAL_VALUE (fn);
- else
+ if (!get_global_value_if_present (fn, &fn))
{
/* Declare void _Jv_Throw (void *). */
tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
tmp = build_function_type (ptr_type_node, tmp);
fn = push_throw_library_fn (fn, tmp);
}
-
+ else if (really_overloaded_fn (fn))
+ {
+ error ("`%D' should never be overloaded", fn);
+ return error_mark_node;
+ }
+ fn = OVL_CURRENT (fn);
exp = build_function_call (fn, tree_cons (NULL_TREE, exp, NULL_TREE));
}
else if (exp)
@@ -669,11 +608,10 @@ build_throw (exp)
tree object, ptr;
tree tmp;
tree temp_expr, allocate_expr;
+ bool elided;
fn = get_identifier ("__cxa_throw");
- if (IDENTIFIER_GLOBAL_VALUE (fn))
- fn = IDENTIFIER_GLOBAL_VALUE (fn);
- else
+ if (!get_global_value_if_present (fn, &fn))
{
/* The CLEANUP_TYPE is the internal type of a destructor. */
if (cleanup_type == NULL_TREE)
@@ -711,11 +649,6 @@ build_throw (exp)
the call to __cxa_allocate_exception first (which doesn't
matter, since it can't throw). */
- /* Pre-evaluate the thrown expression first, since if we allocated
- the space first we would have to deal with cleaning it up if
- evaluating this expression throws. */
- exp = stabilize_throw_expr (exp, &temp_expr);
-
/* Allocate the space for the exception. */
allocate_expr = do_allocate_exception (TREE_TYPE (exp));
allocate_expr = get_target_expr (allocate_expr);
@@ -723,6 +656,8 @@ build_throw (exp)
object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
object = build_indirect_ref (object, NULL);
+ elided = (TREE_CODE (exp) == TARGET_EXPR);
+
/* And initialize the exception object. */
exp = build_init (object, exp, LOOKUP_ONLYCONVERTING);
if (exp == error_mark_node)
@@ -731,10 +666,36 @@ build_throw (exp)
return error_mark_node;
}
- exp = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (exp), exp);
+ /* Pre-evaluate the thrown expression first, since if we allocated
+ the space first we would have to deal with cleaning it up if
+ evaluating this expression throws.
+
+ The case where EXP the initializer is a call to a constructor or a
+ function returning a class is a bit of a grey area in the
+ standard; it's unclear whether or not it should be allowed to
+ throw. We used to say no, as that allowed us to optimize this
+ case without worrying about deallocating the exception object if
+ it does. But that conflicted with expectations (PR 13944) and the
+ EDG compiler; now we wrap the initialization in a TRY_CATCH_EXPR
+ to call do_free_exception rather than in a MUST_NOT_THROW_EXPR,
+ for this case only.
+
+ Note that we don't check the return value from stabilize_init
+ because it will only return false in cases where elided is true,
+ and therefore we don't need to work around the failure to
+ preevaluate. */
+ temp_expr = NULL_TREE;
+ stabilize_init (exp, &temp_expr);
+
+ if (elided)
+ exp = build (TRY_CATCH_EXPR, void_type_node, exp,
+ do_free_exception (ptr));
+ else
+ exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
+
/* Prepend the allocation. */
exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
- if (temp_expr != void_zero_node)
+ if (temp_expr)
{
/* Prepend the calculation of the throw expression. Also, force
any cleanups from the expression to be evaluated here so that
@@ -778,9 +739,7 @@ build_throw (exp)
/* Rethrow current exception. */
tree fn = get_identifier ("__cxa_rethrow");
- if (IDENTIFIER_GLOBAL_VALUE (fn))
- fn = IDENTIFIER_GLOBAL_VALUE (fn);
- else
+ if (!get_global_value_if_present (fn, &fn))
{
/* Declare void __cxa_rethrow (void). */
fn = push_throw_library_fn
@@ -803,9 +762,7 @@ build_throw (exp)
the expr or decl from whence TYPE came, if available. */
static int
-complete_ptr_ref_or_void_ptr_p (type, from)
- tree type;
- tree from;
+complete_ptr_ref_or_void_ptr_p (tree type, tree from)
{
int is_ptr;
@@ -833,8 +790,7 @@ complete_ptr_ref_or_void_ptr_p (type, from)
a type or of an abstract class type. */
static bool
-is_admissible_throw_operand (expr)
- tree expr;
+is_admissible_throw_operand (tree expr)
{
tree type = TREE_TYPE (expr);
@@ -871,8 +827,7 @@ is_admissible_throw_operand (expr)
#include "cfns.h"
int
-nothrow_libfn_p (fn)
- tree fn;
+nothrow_libfn_p (tree fn)
{
tree id;
@@ -893,13 +848,10 @@ nothrow_libfn_p (fn)
handler for type TO, as per [except.handle]. */
static int
-can_convert_eh (to, from)
- tree to, from;
+can_convert_eh (tree to, tree from)
{
- if (TREE_CODE (to) == REFERENCE_TYPE)
- to = TREE_TYPE (to);
- if (TREE_CODE (from) == REFERENCE_TYPE)
- from = TREE_TYPE (from);
+ to = non_reference (to);
+ from = non_reference (from);
if (TREE_CODE (to) == POINTER_TYPE && TREE_CODE (from) == POINTER_TYPE)
{
@@ -912,7 +864,7 @@ can_convert_eh (to, from)
if (TREE_CODE (to) == VOID_TYPE)
return 1;
- /* else fall through */
+ /* Else fall through. */
}
if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
@@ -929,9 +881,7 @@ can_convert_eh (to, from)
for B would catch an exception of type C. */
static void
-check_handlers_1 (master, handlers)
- tree master;
- tree handlers;
+check_handlers_1 (tree master, tree handlers)
{
tree type = TREE_TYPE (master);
tree handler;
@@ -940,10 +890,10 @@ check_handlers_1 (master, handlers)
if (TREE_TYPE (handler)
&& can_convert_eh (type, TREE_TYPE (handler)))
{
- lineno = STMT_LINENO (handler);
+ input_line = STMT_LINENO (handler);
warning ("exception of type `%T' will be caught",
TREE_TYPE (handler));
- lineno = STMT_LINENO (master);
+ input_line = STMT_LINENO (master);
warning (" by earlier handler for `%T'", type);
break;
}
@@ -952,23 +902,23 @@ check_handlers_1 (master, handlers)
/* Given a chain of HANDLERs, make sure that they're OK. */
void
-check_handlers (handlers)
- tree handlers;
+check_handlers (tree handlers)
{
tree handler;
- int save_line = lineno;
+ int save_line = input_line;
+
for (handler = handlers; handler; handler = TREE_CHAIN (handler))
{
if (TREE_CHAIN (handler) == NULL_TREE)
/* No more handlers; nothing to shadow. */;
else if (TREE_TYPE (handler) == NULL_TREE)
{
- lineno = STMT_LINENO (handler);
+ input_line = STMT_LINENO (handler);
pedwarn
("`...' handler must be the last handler for its try block");
}
else
check_handlers_1 (handler, TREE_CHAIN (handler));
}
- lineno = save_line;
+ input_line = save_line;
}
diff --git a/contrib/gcc/cp/expr.c b/contrib/gcc/cp/expr.c
index cc9dae93adfe..34e72242633a 100644
--- a/contrib/gcc/cp/expr.c
+++ b/contrib/gcc/cp/expr.c
@@ -1,28 +1,30 @@
/* Convert language-specific tree expression to rtl instructions,
for GNU compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 2000, 2001 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "flags.h"
@@ -36,8 +38,7 @@ Boston, MA 02111-1307, USA. */
constants. */
tree
-cplus_expand_constant (cst)
- tree cst;
+cplus_expand_constant (tree cst)
{
switch (TREE_CODE (cst))
{
@@ -52,8 +53,18 @@ cplus_expand_constant (cst)
if (TREE_CODE (member) == FIELD_DECL)
{
/* Find the offset for the field. */
- tree offset = byte_position (member);
- cst = fold (build1 (NOP_EXPR, type, offset));
+ cst = byte_position (member);
+ while (!same_type_p (DECL_CONTEXT (member),
+ TYPE_PTRMEM_CLASS_TYPE (type)))
+ {
+ /* The MEMBER must have been nestled within an
+ anonymous aggregate contained in TYPE. Find the
+ anonymous aggregate. */
+ member = lookup_anon_field (TYPE_PTRMEM_CLASS_TYPE (type),
+ DECL_CONTEXT (member));
+ cst = size_binop (PLUS_EXPR, cst, byte_position (member));
+ }
+ cst = fold (build_nop (type, cst));
}
else
{
@@ -77,15 +88,12 @@ cplus_expand_constant (cst)
/* Hook used by expand_expr to expand language-specific tree codes. */
rtx
-cxx_expand_expr (exp, target, tmode, modifier)
- tree exp;
- rtx target;
- enum machine_mode tmode;
- int modifier; /* Actually an enum expand_modifier. */
+cxx_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier,
+ rtx *alt_rtl)
{
tree type = TREE_TYPE (exp);
- register enum machine_mode mode = TYPE_MODE (type);
- register enum tree_code code = TREE_CODE (exp);
+ enum machine_mode mode = TYPE_MODE (type);
+ enum tree_code code = TREE_CODE (exp);
rtx ret;
/* No sense saving up arithmetic to be done
@@ -120,8 +128,12 @@ cxx_expand_expr (exp, target, tmode, modifier)
/* We don't need to generate any code for an empty class. */
return const0_rtx;
+ case BASELINK:
+ return expand_expr (BASELINK_FUNCTIONS (exp), target, tmode,
+ modifier);
+
default:
- return c_expand_expr (exp, target, tmode, modifier);
+ return c_expand_expr (exp, target, tmode, modifier, alt_rtl);
}
abort ();
/* NOTREACHED */
diff --git a/contrib/gcc/cp/friend.c b/contrib/gcc/cp/friend.c
index 0727c397cf43..ac24de211e5a 100644
--- a/contrib/gcc/cp/friend.c
+++ b/contrib/gcc/cp/friend.c
@@ -1,25 +1,28 @@
/* Help friends in C++.
- Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "expr.h"
@@ -33,11 +36,10 @@ Boston, MA 02111-1307, USA. */
/* Returns nonzero if SUPPLICANT is a friend of TYPE. */
int
-is_friend (type, supplicant)
- tree type, supplicant;
+is_friend (tree type, tree supplicant)
{
int declp;
- register tree list;
+ tree list;
tree context;
if (supplicant == NULL_TREE || type == NULL_TREE)
@@ -58,29 +60,15 @@ is_friend (type, supplicant)
tree friends = FRIEND_DECLS (list);
for (; friends ; friends = TREE_CHAIN (friends))
{
- if (TREE_VALUE (friends) == NULL_TREE)
- continue;
+ tree friend = TREE_VALUE (friends);
- if (supplicant == TREE_VALUE (friends))
- return 1;
-
- /* We haven't completed the instantiation yet. */
- if (TREE_CODE (supplicant) == TEMPLATE_DECL)
- return 1;
+ if (friend == NULL_TREE)
+ continue;
- /* Temporarily, we are more lenient to deal with
- nested friend functions, for which there can be
- more than one FUNCTION_DECL, despite being the
- same function. When that's fixed, this bit can
- go. */
- if (DECL_FUNCTION_MEMBER_P (supplicant)
- && same_type_p (TREE_TYPE (supplicant),
- TREE_TYPE (TREE_VALUE (friends))))
+ if (supplicant == friend)
return 1;
- if (TREE_CODE (TREE_VALUE (friends)) == TEMPLATE_DECL
- && is_specialization_of (supplicant,
- TREE_VALUE (friends)))
+ if (is_specialization_of_friend (supplicant, friend))
return 1;
}
break;
@@ -129,11 +117,14 @@ is_friend (type, supplicant)
}
/* Add a new friend to the friends of the aggregate type TYPE.
- DECL is the FUNCTION_DECL of the friend being added. */
+ DECL is the FUNCTION_DECL of the friend being added.
+
+ If COMPLAIN is true, warning about duplicate friend is issued.
+ We want to have this diagnostics during parsing but not
+ when a template is being instantiated. */
void
-add_friend (type, decl)
- tree type, decl;
+add_friend (tree type, tree decl, bool complain)
{
tree typedecl;
tree list;
@@ -156,27 +147,33 @@ add_friend (type, decl)
{
if (decl == TREE_VALUE (friends))
{
- warning ("`%D' is already a friend of class `%T'",
- decl, type);
- cp_warning_at ("previous friend declaration of `%D'",
- TREE_VALUE (friends));
+ if (complain)
+ warning ("`%D' is already a friend of class `%T'",
+ decl, type);
return;
}
}
maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
- TREE_VALUE (list) = tree_cons (error_mark_node, decl,
+ TREE_VALUE (list) = tree_cons (NULL_TREE, decl,
TREE_VALUE (list));
return;
}
list = TREE_CHAIN (list);
}
+ if (DECL_CLASS_SCOPE_P (decl))
+ {
+ tree class_binfo = TYPE_BINFO (DECL_CONTEXT (decl));
+ if (!uses_template_parms (BINFO_TYPE (class_binfo)))
+ perform_or_defer_access_check (class_binfo, decl);
+ }
+
maybe_add_class_template_decl_list (type, decl, /*friend_p=*/1);
DECL_FRIENDLIST (typedecl)
- = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl),
+ = tree_cons (DECL_NAME (decl), build_tree_list (NULL_TREE, decl),
DECL_FRIENDLIST (typedecl));
if (!uses_template_parms (type))
DECL_BEFRIENDING_CLASSES (decl)
@@ -192,11 +189,14 @@ add_friend (type, decl)
classes that are not defined. If a type has not yet been defined,
then the DECL_WAITING_FRIENDS contains a list of types
waiting to make it their friend. Note that these two can both
- be in use at the same time! */
+ be in use at the same time!
+
+ If COMPLAIN is true, warning about duplicate friend is issued.
+ We want to have this diagnostics during parsing but not
+ when a template is being instantiated. */
void
-make_friend_class (type, friend_type)
- tree type, friend_type;
+make_friend_class (tree type, tree friend_type, bool complain)
{
tree classes;
int is_template_friend;
@@ -228,8 +228,9 @@ make_friend_class (type, friend_type)
}
else if (same_type_p (type, friend_type))
{
- pedwarn ("class `%T' is implicitly friends with itself",
- type);
+ if (complain)
+ pedwarn ("class `%T' is implicitly friends with itself",
+ type);
return;
}
else
@@ -265,17 +266,36 @@ make_friend_class (type, friend_type)
if (is_template_friend)
friend_type = CLASSTYPE_TI_TEMPLATE (friend_type);
- classes = CLASSTYPE_FRIEND_CLASSES (type);
- while (classes
- /* Stop if we find the same type on the list. */
- && !(TREE_CODE (TREE_VALUE (classes)) == TEMPLATE_DECL ?
- friend_type == TREE_VALUE (classes) :
- same_type_p (TREE_VALUE (classes), friend_type)))
- classes = TREE_CHAIN (classes);
- if (classes)
- warning ("`%T' is already a friend of `%T'",
- TREE_VALUE (classes), type);
- else
+ /* See if it is already a friend. */
+ for (classes = CLASSTYPE_FRIEND_CLASSES (type);
+ classes;
+ classes = TREE_CHAIN (classes))
+ {
+ tree probe = TREE_VALUE (classes);
+
+ if (TREE_CODE (friend_type) == TEMPLATE_DECL)
+ {
+ if (friend_type == probe)
+ {
+ if (complain)
+ warning ("`%D' is already a friend of `%T'",
+ probe, type);
+ break;
+ }
+ }
+ else if (TREE_CODE (probe) != TEMPLATE_DECL)
+ {
+ if (same_type_p (probe, friend_type))
+ {
+ if (complain)
+ warning ("`%T' is already a friend of `%T'",
+ probe, type);
+ break;
+ }
+ }
+ }
+
+ if (!classes)
{
maybe_add_class_template_decl_list (type, friend_type, /*friend_p=*/1);
@@ -290,10 +310,7 @@ make_friend_class (type, friend_type)
}
}
-/* Main friend processor. This is large, and for modularity purposes,
- has been removed from grokdeclarator. It returns `void_type_node'
- to indicate that something happened, though a FIELD_DECL is
- not returned.
+/* Main friend processor.
CTYPE is the class this friend belongs to.
@@ -301,33 +318,22 @@ make_friend_class (type, friend_type)
DECL is the FUNCTION_DECL that the friend is.
- In case we are parsing a friend which is part of an inline
- definition, we will need to store PARM_DECL chain that comes
- with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL.
-
FLAGS is just used for `grokclassfn'.
QUALS say what special qualifies should apply to the object
pointed to by `this'. */
tree
-do_friend (ctype, declarator, decl, parmdecls, attrlist,
- flags, quals, funcdef_flag)
- tree ctype, declarator, decl, parmdecls, attrlist;
- enum overload_flags flags;
- tree quals;
- int funcdef_flag;
+do_friend (tree ctype, tree declarator, tree decl,
+ tree attrlist, enum overload_flags flags, tree quals,
+ int funcdef_flag)
{
- int is_friend_template = 0;
-
/* Every decl that gets here is a friend of something. */
DECL_FRIEND_P (decl) = 1;
if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
{
declarator = TREE_OPERAND (declarator, 0);
- if (TREE_CODE (declarator) == LOOKUP_EXPR)
- declarator = TREE_OPERAND (declarator, 0);
if (is_overloaded_fn (declarator))
declarator = DECL_NAME (get_first_fn (declarator));
}
@@ -335,42 +341,73 @@ do_friend (ctype, declarator, decl, parmdecls, attrlist,
if (TREE_CODE (decl) != FUNCTION_DECL)
abort ();
- is_friend_template = PROCESSING_REAL_TEMPLATE_DECL_P ();
-
if (ctype)
{
+ /* CLASS_TEMPLATE_DEPTH counts the number of template headers for
+ the enclosing class. FRIEND_DEPTH counts the number of template
+ headers used for this friend declaration. TEMPLATE_MEMBER_P is
+ true if a template header in FRIEND_DEPTH is intended for
+ DECLARATOR. For example, the code
+
+ template <class T> struct A {
+ template <class U> struct B {
+ template <class V> template <class W>
+ friend void C<V>::f(W);
+ };
+ };
+
+ will eventually give the following results
+
+ 1. CLASS_TEMPLATE_DEPTH equals 2 (for `T' and `U').
+ 2. FRIEND_DEPTH equals 2 (for `V' and `W').
+ 3. TEMPLATE_MEMBER_P is true (for `W'). */
+
+ int class_template_depth = template_class_depth (current_class_type);
+ int friend_depth = processing_template_decl - class_template_depth;
+ /* We will figure this out later. */
+ bool template_member_p = false;
+
tree cname = TYPE_NAME (ctype);
if (TREE_CODE (cname) == TYPE_DECL)
cname = DECL_NAME (cname);
/* A method friend. */
- if (flags == NO_SPECIAL && ctype && declarator == cname)
+ if (flags == NO_SPECIAL && declarator == cname)
DECL_CONSTRUCTOR_P (decl) = 1;
/* This will set up DECL_ARGUMENTS for us. */
grokclassfn (ctype, decl, flags, quals);
- if (is_friend_template)
- decl = DECL_TI_TEMPLATE (push_template_decl (decl));
- else if (DECL_TEMPLATE_INFO (decl))
- ;
- else if (template_class_depth (current_class_type))
- decl = push_template_decl_real (decl, /*is_friend=*/1);
-
- /* We can't do lookup in a type that involves template
- parameters. Instead, we rely on tsubst_friend_function
- to check the validity of the declaration later. */
- if (processing_template_decl)
- add_friend (current_class_type, decl);
+ if (friend_depth)
+ {
+ if (!uses_template_parms_level (ctype, class_template_depth
+ + friend_depth))
+ template_member_p = true;
+ }
+
/* A nested class may declare a member of an enclosing class
to be a friend, so we do lookup here even if CTYPE is in
the process of being defined. */
- else if (COMPLETE_TYPE_P (ctype) || TYPE_BEING_DEFINED (ctype))
+ if (class_template_depth
+ || COMPLETE_TYPE_P (ctype)
+ || TYPE_BEING_DEFINED (ctype))
{
- decl = check_classfn (ctype, decl);
+ if (DECL_TEMPLATE_INFO (decl))
+ /* DECL is a template specialization. No need to
+ build a new TEMPLATE_DECL. */
+ ;
+ else if (class_template_depth)
+ /* We rely on tsubst_friend_function to check the
+ validity of the declaration later. */
+ decl = push_template_decl_real (decl, /*is_friend=*/1);
+ else
+ decl = check_classfn (ctype, decl, template_member_p);
+
+ if (template_member_p && decl && TREE_CODE (decl) == FUNCTION_DECL)
+ decl = DECL_TI_TEMPLATE (decl);
if (decl)
- add_friend (current_class_type, decl);
+ add_friend (current_class_type, decl, /*complain=*/true);
}
else
error ("member `%D' declared as friend before type `%T' defined",
@@ -380,12 +417,13 @@ do_friend (ctype, declarator, decl, parmdecls, attrlist,
@@ or possibly a friend from a base class ?!? */
else if (TREE_CODE (decl) == FUNCTION_DECL)
{
+ int is_friend_template = PROCESSING_REAL_TEMPLATE_DECL_P ();
+
/* Friends must all go through the overload machinery,
even though they may not technically be overloaded.
Note that because classes all wind up being top-level
in their scope, their friend wind up in top-level scope as well. */
- DECL_ARGUMENTS (decl) = parmdecls;
if (funcdef_flag)
SET_DECL_FRIEND_CONTEXT (decl, current_class_type);
@@ -437,8 +475,12 @@ do_friend (ctype, declarator, decl, parmdecls, attrlist,
}
}
+ if (decl == error_mark_node)
+ return error_mark_node;
+
add_friend (current_class_type,
- is_friend_template ? DECL_TI_TEMPLATE (decl) : decl);
+ is_friend_template ? DECL_TI_TEMPLATE (decl) : decl,
+ /*complain=*/true);
DECL_FRIEND_P (decl) = 1;
}
diff --git a/contrib/gcc/cp/g++spec.c b/contrib/gcc/cp/g++spec.c
index af30f1c409ac..e6c9ee6892a0 100644
--- a/contrib/gcc/cp/g++spec.c
+++ b/contrib/gcc/cp/g++spec.c
@@ -1,25 +1,28 @@
/* Specific flags and argument handling of the C++ front-end.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "gcc.h"
/* This bit is set if we saw a `-xfoo' language specification. */
@@ -44,10 +47,8 @@ Boston, MA 02111-1307, USA. */
#endif
void
-lang_specific_driver (in_argc, in_argv, in_added_libraries)
- int *in_argc;
- const char *const **in_argv;
- int *in_added_libraries;
+lang_specific_driver (int *in_argc, const char *const **in_argv,
+ int *in_added_libraries)
{
int i, j;
@@ -57,14 +58,16 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
/* If nonzero, the user gave us the `-v' flag. */
int saw_verbose_flag = 0;
- /* This will be 0 if we encounter a situation where we should not
- link in libstdc++. */
- int library = 1;
+ /* This is a tristate:
+ -1 means we should not link in libstdc++
+ 0 means we should link in libstdc++ if it is needed
+ 1 means libstdc++ is needed and should be linked in. */
+ int library = 0;
/* The number of arguments being added to what's in argv, other than
libraries. We use this to track the number of times we've inserted
-xc++/-xnone. */
- int added = 2;
+ int added = 0;
/* Used to track options that take arguments, so we don't go wrapping
those with -xc++/-xnone. */
@@ -110,7 +113,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
argv = *in_argv;
added_libraries = *in_added_libraries;
- args = (int *) xcalloc (argc, sizeof (int));
+ args = xcalloc (argc, sizeof (int));
for (i = 1; i < argc; i++)
{
@@ -128,17 +131,14 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
if (argv[i][0] == '-')
{
- if (library != 0 && (strcmp (argv[i], "-nostdlib") == 0
- || strcmp (argv[i], "-nodefaultlibs") == 0))
+ if (strcmp (argv[i], "-nostdlib") == 0
+ || strcmp (argv[i], "-nodefaultlibs") == 0)
{
- library = 0;
+ library = -1;
}
else if (strcmp (argv[i], "-lm") == 0
|| strcmp (argv[i], "-lmath") == 0
|| strcmp (argv[i], MATH_LIBRARY) == 0
-#ifdef ALT_LIBM
- || strcmp (argv[i], ALT_LIBM) == 0
-#endif
)
{
args[i] |= MATHLIB;
@@ -149,31 +149,37 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
else if (strcmp (argv[i], "-pg") == 0 || strcmp (argv[i], "-p") == 0)
saw_profile_flag++;
else if (strcmp (argv[i], "-v") == 0)
+ saw_verbose_flag = 1;
+ else if (strncmp (argv[i], "-x", 2) == 0)
{
- saw_verbose_flag = 1;
- if (argc == 2)
+ if (library == 0)
{
- /* If they only gave us `-v', don't try to link
- in libg++. */
- library = 0;
+ const char * arg;
+ if (argv[i][2] != '\0')
+ arg = argv[i]+2;
+ else if (argv[i+1] != NULL)
+ arg = argv[i+1];
+ else /* Error condition, message will be printed later. */
+ arg = "";
+ if (strcmp (arg, "c++") == 0
+ || strcmp (arg, "c++-cpp-output") == 0)
+ library = 1;
}
+ saw_speclang = 1;
}
- else if (strncmp (argv[i], "-x", 2) == 0)
- saw_speclang = 1;
else if (((argv[i][2] == '\0'
- && (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
+ && strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
|| strcmp (argv[i], "-Xlinker") == 0
|| strcmp (argv[i], "-Tdata") == 0))
quote = argv[i];
- else if (library != 0 && ((argv[i][2] == '\0'
- && (char *) strchr ("cSEM", argv[i][1]) != NULL)
- || strcmp (argv[i], "-MM") == 0
- || strcmp (argv[i], "-fsyntax-only") == 0))
+ else if ((argv[i][2] == '\0'
+ && strchr ("cSEM", argv[i][1]) != NULL)
+ || strcmp (argv[i], "-MM") == 0
+ || strcmp (argv[i], "-fsyntax-only") == 0)
{
/* Don't specify libraries if we won't link, since that would
cause a warning. */
- library = 0;
- added -= 2;
+ library = -1;
}
else if (strcmp (argv[i], "-static-libgcc") == 0
|| strcmp (argv[i], "-static") == 0)
@@ -194,16 +200,28 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
continue;
}
- /* If the filename ends in .c or .i, put options around it.
+ /* If the filename ends in .[chi], put options around it.
But not if a specified -x option is currently active. */
len = strlen (argv[i]);
if (len > 2
- && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i')
+ && (argv[i][len - 1] == 'c'
+ || argv[i][len - 1] == 'i'
+ || argv[i][len - 1] == 'h')
&& argv[i][len - 2] == '.')
{
args[i] |= LANGSPEC;
added += 2;
}
+
+ /* If we don't know that this is a header file, we might
+ need to be linking in the libraries. */
+ if (library == 0)
+ {
+ if ((len <= 2 || strcmp (argv[i] + (len - 2), ".H") != 0)
+ && (len <= 2 || strcmp (argv[i] + (len - 2), ".h") != 0)
+ && (len <= 3 || strcmp (argv[i] + (len - 3), ".hh") != 0))
+ library = 1;
+ }
}
}
@@ -211,7 +229,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
fatal ("argument to `%s' missing\n", quote);
/* If we know we don't have to do anything, bail now. */
- if (! added && ! library)
+ if (! added && library <= 0)
{
free (args);
return;
@@ -224,8 +242,8 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
#endif
/* Make sure to have room for the trailing NULL argument. */
- num_args = argc + added + need_math + shared_libgcc + 1;
- arglist = (const char **) xmalloc (num_args * sizeof (char *));
+ num_args = argc + added + need_math + shared_libgcc + (library > 0) + 1;
+ arglist = xmalloc (num_args * sizeof (char *));
i = 0;
j = 0;
@@ -240,27 +258,37 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
/* Make sure -lstdc++ is before the math library, since libstdc++
itself uses those math routines. */
- if (!saw_math && (args[i] & MATHLIB) && library)
+ if (!saw_math && (args[i] & MATHLIB) && library > 0)
{
--j;
saw_math = argv[i];
}
- if (!saw_libc && (args[i] & WITHLIBC) && library)
+ if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
{
--j;
saw_libc = argv[i];
}
- /* Wrap foo.c and foo.i files in a language specification to
+ /* Wrap foo.[chi] files in a language specification to
force the gcc compiler driver to run cc1plus on them. */
if (args[i] & LANGSPEC)
{
int len = strlen (argv[i]);
- if (argv[i][len - 1] == 'i')
- arglist[j++] = "-xc++-cpp-output";
- else
- arglist[j++] = "-xc++";
+ switch (argv[i][len - 1])
+ {
+ case 'c':
+ arglist[j++] = "-xc++";
+ break;
+ case 'i':
+ arglist[j++] = "-xc++-cpp-output";
+ break;
+ case 'h':
+ arglist[j++] = "-xc++-header";
+ break;
+ default:
+ abort ();
+ }
arglist[j++] = argv[i];
arglist[j] = "-xnone";
}
@@ -270,21 +298,14 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
}
/* Add `-lstdc++' if we haven't already done so. */
- if (library)
+ if (library > 0)
{
arglist[j++] = saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX;
added_libraries++;
-#ifdef USE_LIBUNWIND_EXCEPTIONS
-# ifndef LIBUNWIND
-# define LIBUNWIND "-lunwind"
-# endif
- arglist[j++] = LIBUNWIND;
- added_libraries++;
-#endif
}
if (saw_math)
arglist[j++] = saw_math;
- else if (library && need_math)
+ else if (library > 0 && need_math)
{
arglist[j++] = saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY;
added_libraries++;
@@ -302,7 +323,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
}
/* Called before linking. Returns 0 on success and -1 on failure. */
-int lang_specific_pre_link () /* Not used for C++. */
+int lang_specific_pre_link (void) /* Not used for C++. */
{
return 0;
}
diff --git a/contrib/gcc/cp/init.c b/contrib/gcc/cp/init.c
index 91ea10c16cba..c81736ce35be 100644
--- a/contrib/gcc/cp/init.c
+++ b/contrib/gcc/cp/init.c
@@ -1,22 +1,22 @@
/* Handle initialization things in C++.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -24,6 +24,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "expr.h"
@@ -32,27 +34,28 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "except.h"
#include "toplev.h"
-#include "ggc.h"
+static bool begin_init_stmts (tree *, tree *);
+static tree finish_init_stmts (bool, tree, tree);
static void construct_virtual_base (tree, tree);
-static void expand_aggr_init_1 PARAMS ((tree, tree, tree, tree, int));
-static void expand_default_init PARAMS ((tree, tree, tree, tree, int));
-static tree build_vec_delete_1 PARAMS ((tree, tree, tree, special_function_kind, int));
+static void expand_aggr_init_1 (tree, tree, tree, tree, int);
+static void expand_default_init (tree, tree, tree, tree, int);
+static tree build_vec_delete_1 (tree, tree, tree, special_function_kind, int);
static void perform_member_init (tree, tree);
-static tree build_builtin_delete_call PARAMS ((tree));
-static int member_init_ok_or_else PARAMS ((tree, tree, tree));
-static void expand_virtual_init PARAMS ((tree, tree));
+static tree build_builtin_delete_call (tree);
+static int member_init_ok_or_else (tree, tree, tree);
+static void expand_virtual_init (tree, tree);
static tree sort_mem_initializers (tree, tree);
-static tree initializing_context PARAMS ((tree));
-static void expand_cleanup_for_base PARAMS ((tree, tree));
-static tree get_temp_regvar PARAMS ((tree, tree));
-static tree dfs_initialize_vtbl_ptrs PARAMS ((tree, void *));
-static tree build_default_init PARAMS ((tree, tree));
-static tree build_new_1 PARAMS ((tree));
-static tree get_cookie_size PARAMS ((tree));
-static tree build_dtor_call PARAMS ((tree, special_function_kind, int));
-static tree build_field_list PARAMS ((tree, tree, int *));
-static tree build_vtbl_address PARAMS ((tree));
+static tree initializing_context (tree);
+static void expand_cleanup_for_base (tree, tree);
+static tree get_temp_regvar (tree, tree);
+static tree dfs_initialize_vtbl_ptrs (tree, void *);
+static tree build_default_init (tree, tree);
+static tree build_new_1 (tree);
+static tree get_cookie_size (tree);
+static tree build_dtor_call (tree, special_function_kind, int);
+static tree build_field_list (tree, tree, int *);
+static tree build_vtbl_address (tree);
/* We are about to generate some complex initialization code.
Conceptually, it is all a single expression. However, we may want
@@ -63,45 +66,29 @@ static tree build_vtbl_address PARAMS ((tree));
pass them back to finish_init_stmts when the expression is
complete. */
-void
-begin_init_stmts (stmt_expr_p, compound_stmt_p)
- tree *stmt_expr_p;
- tree *compound_stmt_p;
+static bool
+begin_init_stmts (tree *stmt_expr_p, tree *compound_stmt_p)
{
- if (building_stmt_tree ())
- *stmt_expr_p = begin_stmt_expr ();
- else
- *stmt_expr_p = begin_global_stmt_expr ();
+ bool is_global = !building_stmt_tree ();
- if (building_stmt_tree ())
- *compound_stmt_p = begin_compound_stmt (/*has_no_scope=*/1);
+ *stmt_expr_p = begin_stmt_expr ();
+ *compound_stmt_p = begin_compound_stmt (/*has_no_scope=*/true);
+
+ return is_global;
}
/* Finish out the statement-expression begun by the previous call to
begin_init_stmts. Returns the statement-expression itself. */
-tree
-finish_init_stmts (stmt_expr, compound_stmt)
- tree stmt_expr;
- tree compound_stmt;
-
+static tree
+finish_init_stmts (bool is_global, tree stmt_expr, tree compound_stmt)
{
- if (building_stmt_tree ())
- finish_compound_stmt (/*has_no_scope=*/1, compound_stmt);
-
- if (building_stmt_tree ())
- {
- stmt_expr = finish_stmt_expr (stmt_expr);
- STMT_EXPR_NO_SCOPE (stmt_expr) = true;
- }
- else
- stmt_expr = finish_global_stmt_expr (stmt_expr);
+ finish_compound_stmt (compound_stmt);
- /* To avoid spurious warnings about unused values, we set
- TREE_USED. */
- if (stmt_expr)
- TREE_USED (stmt_expr) = 1;
+ stmt_expr = finish_stmt_expr (stmt_expr, true);
+ my_friendly_assert (!building_stmt_tree () == is_global, 20030726);
+
return stmt_expr;
}
@@ -112,9 +99,7 @@ finish_init_stmts (stmt_expr, compound_stmt)
TREE_LIST whose TREE_VALUE is the this ptr expression. */
static tree
-dfs_initialize_vtbl_ptrs (binfo, data)
- tree binfo;
- void *data;
+dfs_initialize_vtbl_ptrs (tree binfo, void *data)
{
if ((!BINFO_PRIMARY_P (binfo) || TREE_VIA_VIRTUAL (binfo))
&& CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)))
@@ -126,7 +111,7 @@ dfs_initialize_vtbl_ptrs (binfo, data)
expand_virtual_init (binfo, base_ptr);
}
- SET_BINFO_MARKED (binfo);
+ BINFO_MARKED (binfo) = 1;
return NULL_TREE;
}
@@ -135,8 +120,7 @@ dfs_initialize_vtbl_ptrs (binfo, data)
ADDR. */
void
-initialize_vtbl_ptrs (addr)
- tree addr;
+initialize_vtbl_ptrs (tree addr)
{
tree list;
tree type;
@@ -148,10 +132,9 @@ initialize_vtbl_ptrs (addr)
class. We do these in pre-order because we can't find the virtual
bases for a class until we've initialized the vtbl for that
class. */
- dfs_walk_real (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs,
- NULL, dfs_unmarked_real_bases_queue_p, list);
- dfs_walk (TYPE_BINFO (type), dfs_unmark,
- dfs_marked_real_bases_queue_p, type);
+ dfs_walk_real (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs,
+ NULL, unmarkedp, list);
+ dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp, type);
}
/* Return an expression for the zero-initialization of an object with
@@ -207,7 +190,7 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
tree inits;
/* Build a constructor to contain the initializations. */
- init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
+ init = build_constructor (type, NULL_TREE);
/* Iterate over the fields, building initializations. */
inits = NULL_TREE;
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
@@ -239,20 +222,23 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
tree inits;
/* Build a constructor to contain the initializations. */
- init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
+ init = build_constructor (type, NULL_TREE);
/* Iterate over the array elements, building initializations. */
inits = NULL_TREE;
max_index = nelts ? nelts : array_type_nelts (type);
my_friendly_assert (TREE_CODE (max_index) == INTEGER_CST, 20030618);
- for (index = size_zero_node;
- !tree_int_cst_lt (max_index, index);
- index = size_binop (PLUS_EXPR, index, size_one_node))
- inits = tree_cons (index,
- build_zero_init (TREE_TYPE (type),
- /*nelts=*/NULL_TREE,
- static_storage_p),
- inits);
+ /* A zero-sized array, which is accepted as an extension, will
+ have an upper bound of -1. */
+ if (!tree_int_cst_equal (max_index, integer_minus_one_node))
+ for (index = size_zero_node;
+ !tree_int_cst_lt (max_index, index);
+ index = size_binop (PLUS_EXPR, index, size_one_node))
+ inits = tree_cons (index,
+ build_zero_init (TREE_TYPE (type),
+ /*nelts=*/NULL_TREE,
+ static_storage_p),
+ inits);
CONSTRUCTOR_ELTS (init) = nreverse (inits);
}
else if (TREE_CODE (type) == REFERENCE_TYPE)
@@ -275,9 +261,7 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
constructors to be called. */
static tree
-build_default_init (type, nelts)
- tree type;
- tree nelts;
+build_default_init (tree type, tree nelts)
{
/* [dcl.init]:
@@ -311,7 +295,7 @@ build_default_init (type, nelts)
return NULL_TREE;
/* At this point, TYPE is either a POD class type, an array of POD
- classes, or something even more inoccuous. */
+ classes, or something even more innocuous. */
return build_zero_init (type, nelts, /*static_storage_p=*/false);
}
@@ -387,19 +371,14 @@ perform_member_init (tree member, tree init)
/* member traversal: note it leaves init NULL */
else if (TREE_CODE (type) == REFERENCE_TYPE)
pedwarn ("uninitialized reference member `%D'", member);
+ else if (CP_TYPE_CONST_P (type))
+ pedwarn ("uninitialized member `%D' with `const' type `%T'",
+ member, type);
}
else if (TREE_CODE (init) == TREE_LIST)
- {
- /* There was an explicit member initialization. Do some
- work in that case. */
- if (TREE_CHAIN (init))
- {
- warning ("initializer list treated as compound expression");
- init = build_compound_expr (init);
- }
- else
- init = TREE_VALUE (init);
- }
+ /* There was an explicit member initialization. Do some work
+ in that case. */
+ init = build_x_compound_expr_from_list (init, "member initializer");
if (init)
finish_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
@@ -424,10 +403,7 @@ perform_member_init (tree member, tree init)
the FIELD_DECLs on the TYPE_FIELDS list for T, in reverse order. */
static tree
-build_field_list (t, list, uses_unions_p)
- tree t;
- tree list;
- int *uses_unions_p;
+build_field_list (tree t, tree list, int *uses_unions_p)
{
tree fields;
@@ -544,6 +520,7 @@ sort_mem_initializers (tree t, tree mem_inits)
cp_warning_at (" `%#D'", subobject);
else
warning (" base `%T'", subobject);
+ warning (" when initialized here");
}
/* Look again, from the beginning of the list. */
@@ -730,8 +707,7 @@ emit_mem_initializers (tree mem_inits)
assigned to the vptr) for BINFO. */
static tree
-build_vtbl_address (binfo)
- tree binfo;
+build_vtbl_address (tree binfo)
{
tree binfo_for = binfo;
tree vtbl;
@@ -770,8 +746,7 @@ build_vtbl_address (binfo)
multiple inheritance, this might mean "C's A" if C : A, B. */
static void
-expand_virtual_init (binfo, decl)
- tree binfo, decl;
+expand_virtual_init (tree binfo, tree decl)
{
tree vtbl, vtbl_ptr;
tree vtt_index;
@@ -823,9 +798,7 @@ expand_virtual_init (binfo, decl)
destroyed. */
static void
-expand_cleanup_for_base (binfo, flag)
- tree binfo;
- tree flag;
+expand_cleanup_for_base (tree binfo, tree flag)
{
tree expr;
@@ -874,7 +847,7 @@ construct_virtual_base (tree vbase, tree arguments)
flag = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
inner_if_stmt = begin_if_stmt ();
finish_if_stmt_cond (flag, inner_if_stmt);
- compound_stmt = begin_compound_stmt (/*has_no_scope=*/1);
+ compound_stmt = begin_compound_stmt (/*has_no_scope=*/true);
/* Compute the location of the virtual base. If we're
constructing virtual bases, then we must be the most derived
@@ -884,7 +857,7 @@ construct_virtual_base (tree vbase, tree arguments)
expand_aggr_init_1 (vbase, current_class_ref, exp, arguments,
LOOKUP_COMPLAIN);
- finish_compound_stmt (/*has_no_scope=*/1, compound_stmt);
+ finish_compound_stmt (compound_stmt);
finish_then_clause (inner_if_stmt);
finish_if_stmt ();
@@ -894,8 +867,7 @@ construct_virtual_base (tree vbase, tree arguments)
/* Find the context in which this FIELD can be initialized. */
static tree
-initializing_context (field)
- tree field;
+initializing_context (tree field)
{
tree t = DECL_CONTEXT (field);
@@ -914,23 +886,33 @@ initializing_context (field)
MEMBER_NAME is the name of the member. */
static int
-member_init_ok_or_else (field, type, member_name)
- tree field;
- tree type;
- tree member_name;
+member_init_ok_or_else (tree field, tree type, tree member_name)
{
if (field == error_mark_node)
return 0;
- if (field == NULL_TREE || initializing_context (field) != type)
+ if (!field)
{
error ("class `%T' does not have any field named `%D'", type,
- member_name);
+ member_name);
+ return 0;
+ }
+ if (TREE_CODE (field) == VAR_DECL)
+ {
+ error ("`%#D' is a static data member; it can only be "
+ "initialized at its definition",
+ field);
return 0;
}
- if (TREE_STATIC (field))
+ if (TREE_CODE (field) != FIELD_DECL)
{
- error ("field `%#D' is static; the only point of initialization is its definition",
- field);
+ error ("`%#D' is not a non-static data member of `%T'",
+ field, type);
+ return 0;
+ }
+ if (initializing_context (field) != type)
+ {
+ error ("class `%T' does not have any field named `%D'", type,
+ member_name);
return 0;
}
@@ -986,22 +968,50 @@ expand_member_init (tree name)
if (basetype)
{
- tree binfo;
+ tree class_binfo;
+ tree direct_binfo;
+ tree virtual_binfo;
+ int i;
if (current_template_parms)
return basetype;
- binfo = lookup_base (current_class_type, basetype,
- ba_ignore, NULL);
- if (binfo)
+ class_binfo = TYPE_BINFO (current_class_type);
+ direct_binfo = NULL_TREE;
+ virtual_binfo = NULL_TREE;
+
+ /* Look for a direct base. */
+ for (i = 0; i < BINFO_N_BASETYPES (class_binfo); ++i)
+ if (same_type_p (basetype,
+ TYPE_BINFO_BASETYPE (current_class_type, i)))
+ {
+ direct_binfo = BINFO_BASETYPE (class_binfo, i);
+ break;
+ }
+ /* Look for a virtual base -- unless the direct base is itself
+ virtual. */
+ if (!direct_binfo || !TREE_VIA_VIRTUAL (direct_binfo))
+ {
+ virtual_binfo
+ = purpose_member (basetype,
+ CLASSTYPE_VBASECLASSES (current_class_type));
+ if (virtual_binfo)
+ virtual_binfo = TREE_VALUE (virtual_binfo);
+ }
+
+ /* [class.base.init]
+
+ If a mem-initializer-id is ambiguous because it designates
+ both a direct non-virtual base class and an inherited virtual
+ base class, the mem-initializer is ill-formed. */
+ if (direct_binfo && virtual_binfo)
{
- if (TREE_VIA_VIRTUAL (binfo))
- binfo = binfo_for_vbase (basetype, current_class_type);
- else if (BINFO_INHERITANCE_CHAIN (binfo)
- != TYPE_BINFO (current_class_type))
- binfo = NULL_TREE;
+ error ("'%D' is both a direct base and an indirect virtual base",
+ basetype);
+ return NULL_TREE;
}
- if (!binfo)
+
+ if (!direct_binfo && !virtual_binfo)
{
if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))
error ("type `%D' is not a direct or virtual base of `%T'",
@@ -1012,13 +1022,12 @@ expand_member_init (tree name)
return NULL_TREE;
}
- if (binfo)
- return binfo;
+ return direct_binfo ? direct_binfo : virtual_binfo;
}
else
{
if (TREE_CODE (name) == IDENTIFIER_NODE)
- field = lookup_field (current_class_type, name, 1, 0);
+ field = lookup_field (current_class_type, name, 1, false);
else
field = name;
@@ -1061,9 +1070,7 @@ expand_member_init (tree name)
perform the initialization, but not both, as it would be ambiguous. */
tree
-build_aggr_init (exp, init, flags)
- tree exp, init;
- int flags;
+build_aggr_init (tree exp, tree init, int flags)
{
tree stmt_expr;
tree compound_stmt;
@@ -1071,6 +1078,7 @@ build_aggr_init (exp, init, flags)
tree type = TREE_TYPE (exp);
int was_const = TREE_READONLY (exp);
int was_volatile = TREE_THIS_VOLATILE (exp);
+ int is_global;
if (init == error_mark_node)
return error_mark_node;
@@ -1120,16 +1128,16 @@ build_aggr_init (exp, init, flags)
}
if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL)
- /* just know that we've seen something for this node */
+ /* Just know that we've seen something for this node. */
TREE_USED (exp) = 1;
TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
- begin_init_stmts (&stmt_expr, &compound_stmt);
+ is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
destroy_temps = stmts_are_full_exprs_p ();
current_stmt_tree ()->stmts_are_full_exprs_p = 0;
expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
init, LOOKUP_NORMAL|flags);
- stmt_expr = finish_init_stmts (stmt_expr, compound_stmt);
+ stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
TREE_TYPE (exp) = type;
TREE_READONLY (exp) = was_const;
@@ -1141,15 +1149,17 @@ build_aggr_init (exp, init, flags)
/* Like build_aggr_init, but not just for aggregates. */
tree
-build_init (decl, init, flags)
- tree decl, init;
- int flags;
+build_init (tree decl, tree init, int flags)
{
tree expr;
- if (IS_AGGR_TYPE (TREE_TYPE (decl))
- || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
+ if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
expr = build_aggr_init (decl, init, flags);
+ else if (CLASS_TYPE_P (TREE_TYPE (decl)))
+ expr = build_special_member_call (decl, complete_ctor_identifier,
+ build_tree_list (NULL_TREE, init),
+ TYPE_BINFO (TREE_TYPE (decl)),
+ LOOKUP_NORMAL|flags);
else
expr = build (INIT_EXPR, TREE_TYPE (decl), decl, init);
@@ -1157,11 +1167,7 @@ build_init (decl, init, flags)
}
static void
-expand_default_init (binfo, true_exp, exp, init, flags)
- tree binfo;
- tree true_exp, exp;
- tree init;
- int flags;
+expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags)
{
tree type = TREE_TYPE (exp);
tree ctor_name;
@@ -1198,13 +1204,16 @@ expand_default_init (binfo, true_exp, exp, init, flags)
else
init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
- if (TREE_CODE (init) == TRY_CATCH_EXPR)
- /* We need to protect the initialization of a catch parm
- with a call to terminate(), which shows up as a TRY_CATCH_EXPR
+ if (TREE_CODE (init) == MUST_NOT_THROW_EXPR)
+ /* We need to protect the initialization of a catch parm with a
+ call to terminate(), which shows up as a MUST_NOT_THROW_EXPR
around the TARGET_EXPR for the copy constructor. See
- expand_start_catch_block. */
- TREE_OPERAND (init, 0) = build (INIT_EXPR, TREE_TYPE (exp), exp,
- TREE_OPERAND (init, 0));
+ initialize_handler_parm. */
+ {
+ TREE_OPERAND (init, 0) = build (INIT_EXPR, TREE_TYPE (exp), exp,
+ TREE_OPERAND (init, 0));
+ TREE_TYPE (init) = void_type_node;
+ }
else
init = build (INIT_EXPR, TREE_TYPE (exp), exp, init);
TREE_SIDE_EFFECTS (init) = 1;
@@ -1229,12 +1238,7 @@ expand_default_init (binfo, true_exp, exp, init, flags)
rval = build_special_member_call (exp, ctor_name, parms, binfo, flags);
if (TREE_SIDE_EFFECTS (rval))
- {
- if (building_stmt_tree ())
- finish_expr_stmt (rval);
- else
- genrtl_expr_stmt (rval);
- }
+ finish_expr_stmt (convert_to_void (rval, NULL));
}
/* This function is responsible for initializing EXP with INIT
@@ -1254,15 +1258,11 @@ expand_default_init (binfo, true_exp, exp, init, flags)
from TRUE_EXP. In constructors, we don't know anything about
the value being initialized.
- FLAGS is just passes to `build_method_call'. See that function for
- its description. */
+ FLAGS is just passed to `build_new_method_call'. See that function
+ for its description. */
static void
-expand_aggr_init_1 (binfo, true_exp, exp, init, flags)
- tree binfo;
- tree true_exp, exp;
- tree init;
- int flags;
+expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags)
{
tree type = TREE_TYPE (exp);
@@ -1282,8 +1282,9 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, flags)
/* If store_init_value returns NULL_TREE, the INIT has been
record in the DECL_INITIAL for EXP. That means there's
nothing more we have to do. */
- if (store_init_value (exp, init))
- finish_expr_stmt (build (INIT_EXPR, type, exp, init));
+ init = store_init_value (exp, init);
+ if (init)
+ finish_expr_stmt (init);
return;
}
@@ -1296,9 +1297,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, flags)
OR_ELSE is nonzero, give an error message. */
int
-is_aggr_type (type, or_else)
- tree type;
- int or_else;
+is_aggr_type (tree type, int or_else)
{
if (type == error_mark_node)
return 0;
@@ -1317,9 +1316,7 @@ is_aggr_type (type, or_else)
/* Like is_aggr_typedef, but returns typedef if successful. */
tree
-get_aggr_from_typedef (name, or_else)
- tree name;
- int or_else;
+get_aggr_from_typedef (tree name, int or_else)
{
tree type;
@@ -1347,8 +1344,7 @@ get_aggr_from_typedef (name, or_else)
}
tree
-get_type_value (name)
- tree name;
+get_type_value (tree name)
{
if (name == error_mark_node)
return NULL_TREE;
@@ -1359,162 +1355,11 @@ get_type_value (name)
return NULL_TREE;
}
-
-/* This code could just as well go in `class.c', but is placed here for
- modularity. */
-
-/* For an expression of the form TYPE :: NAME (PARMLIST), build
- the appropriate function call. */
-
-tree
-build_member_call (type, name, parmlist)
- tree type, name, parmlist;
-{
- tree t;
- tree method_name;
- tree fns;
- int dtor = 0;
- tree basetype_path, decl;
-
- if (TREE_CODE (name) == TEMPLATE_ID_EXPR
- && TREE_CODE (type) == NAMESPACE_DECL)
- {
- /* 'name' already refers to the decls from the namespace, since we
- hit do_identifier for template_ids. */
- method_name = TREE_OPERAND (name, 0);
- /* FIXME: Since we don't do independent names right yet, the
- name might also be a LOOKUP_EXPR. Once we resolve this to a
- real decl earlier, this can go. This may happen during
- tsubst'ing. */
- if (TREE_CODE (method_name) == LOOKUP_EXPR)
- {
- method_name = lookup_namespace_name
- (type, TREE_OPERAND (method_name, 0));
- TREE_OPERAND (name, 0) = method_name;
- }
- my_friendly_assert (is_overloaded_fn (method_name), 980519);
- return finish_call_expr (name, parmlist, /*disallow_virtual=*/true);
- }
-
- if (DECL_P (name))
- name = DECL_NAME (name);
-
- if (TREE_CODE (type) == NAMESPACE_DECL)
- return finish_call_expr (lookup_namespace_name (type, name),
- parmlist,
- /*disallow_virtual=*/true);
-
- if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- {
- method_name = TREE_OPERAND (name, 0);
- if (TREE_CODE (method_name) == COMPONENT_REF)
- method_name = TREE_OPERAND (method_name, 1);
- if (is_overloaded_fn (method_name))
- method_name = DECL_NAME (OVL_CURRENT (method_name));
- TREE_OPERAND (name, 0) = method_name;
- }
- else
- method_name = name;
-
- if (TREE_CODE (method_name) == BIT_NOT_EXPR)
- {
- method_name = TREE_OPERAND (method_name, 0);
- dtor = 1;
- }
-
- /* This shouldn't be here, and build_member_call shouldn't appear in
- parse.y! (mrs) */
- if (type && TREE_CODE (type) == IDENTIFIER_NODE
- && get_aggr_from_typedef (type, 0) == 0)
- {
- tree ns = lookup_name (type, 0);
- if (ns && TREE_CODE (ns) == NAMESPACE_DECL)
- return finish_call_expr (lookup_namespace_name (ns, name),
- parmlist,
- /*disallow_virtual=*/true);
- }
-
- if (type == NULL_TREE || ! is_aggr_type (type, 1))
- return error_mark_node;
-
- /* An operator we did not like. */
- if (name == NULL_TREE)
- return error_mark_node;
-
- if (dtor)
- {
- error ("cannot call destructor `%T::~%T' without object", type,
- method_name);
- return error_mark_node;
- }
-
- decl = maybe_dummy_object (type, &basetype_path);
-
- fns = lookup_fnfields (basetype_path, method_name, 0);
- if (fns)
- {
- if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
- BASELINK_FUNCTIONS (fns) = build_nt (TEMPLATE_ID_EXPR,
- BASELINK_FUNCTIONS (fns),
- TREE_OPERAND (name, 1));
- return build_new_method_call (decl, fns, parmlist,
- /*conversion_path=*/NULL_TREE,
- LOOKUP_NORMAL|LOOKUP_NONVIRTUAL);
- }
-
- /* Convert 'this' to the specified type to disambiguate conversion
- to the function's context. */
- if (decl == current_class_ref
- /* ??? this is wrong, but if this conversion is invalid we need to
- defer it until we know whether we are calling a static or
- non-static member function. Be conservative for now. */
- && ACCESSIBLY_UNIQUELY_DERIVED_P (type, current_class_type))
- {
- basetype_path = NULL_TREE;
- decl = build_scoped_ref (decl, type, &basetype_path);
- if (decl == error_mark_node)
- return error_mark_node;
- }
-
- if (constructor_name_p (method_name, type))
- return build_functional_cast (type, parmlist);
- if (TREE_CODE (name) == IDENTIFIER_NODE
- && ((t = lookup_field (TYPE_BINFO (type), name, 1, 0))))
- {
- if (t == error_mark_node)
- return error_mark_node;
- if (TREE_CODE (t) == FIELD_DECL)
- {
- if (is_dummy_object (decl))
- {
- error ("invalid use of non-static field `%D'", t);
- return error_mark_node;
- }
- decl = build (COMPONENT_REF, TREE_TYPE (t), decl, t);
- }
- else if (TREE_CODE (t) == VAR_DECL)
- decl = t;
- else
- {
- error ("invalid use of member `%D'", t);
- return error_mark_node;
- }
- if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl)))
- return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, decl,
- parmlist, NULL_TREE);
- return build_function_call (decl, parmlist);
- }
- else
- {
- error ("no method `%T::%D'", type, name);
- return error_mark_node;
- }
-}
-
-/* Build a reference to a member of an aggregate. This is not a
- C++ `&', but really something which can have its address taken,
- and then act as a pointer to member, for example TYPE :: FIELD
- can have its address taken by saying & TYPE :: FIELD.
+/* Build a reference to a member of an aggregate. This is not a C++
+ `&', but really something which can have its address taken, and
+ then act as a pointer to member, for example TYPE :: FIELD can have
+ its address taken by saying & TYPE :: FIELD. ADDRESS_P is true if
+ this expression is the operand of "&".
@@ Prints out lousy diagnostics for operator <typename>
@@ fields.
@@ -1522,10 +1367,9 @@ build_member_call (type, name, parmlist)
@@ This function should be rewritten and placed in search.c. */
tree
-build_offset_ref (type, name)
- tree type, name;
+build_offset_ref (tree type, tree name, bool address_p)
{
- tree decl, t = error_mark_node;
+ tree decl;
tree member;
tree basebinfo = NULL_TREE;
tree orig_name = name;
@@ -1549,16 +1393,10 @@ build_offset_ref (type, name)
name = DECL_NAME (name);
else
{
- if (TREE_CODE (name) == LOOKUP_EXPR)
- /* This can happen during tsubst'ing. */
- name = TREE_OPERAND (name, 0);
- else
- {
- if (TREE_CODE (name) == COMPONENT_REF)
- name = TREE_OPERAND (name, 1);
- if (TREE_CODE (name) == OVERLOAD)
- name = DECL_NAME (OVL_CURRENT (name));
- }
+ if (TREE_CODE (name) == COMPONENT_REF)
+ name = TREE_OPERAND (name, 1);
+ if (TREE_CODE (name) == OVERLOAD)
+ name = DECL_NAME (OVL_CURRENT (name));
}
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0);
@@ -1570,7 +1408,7 @@ build_offset_ref (type, name)
/* Handle namespace names fully here. */
if (TREE_CODE (type) == NAMESPACE_DECL)
{
- t = lookup_namespace_name (type, name);
+ tree t = lookup_namespace_name (type, name);
if (t == error_mark_node)
return t;
if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
@@ -1616,12 +1454,37 @@ build_offset_ref (type, name)
return error_mark_node;
}
+ if (!member)
+ {
+ error ("`%D' is not a member of type `%T'", name, type);
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (member) == TYPE_DECL)
+ {
+ TREE_USED (member) = 1;
+ return member;
+ }
+ /* static class members and class-specific enum
+ values can be returned without further ado. */
+ if (TREE_CODE (member) == VAR_DECL || TREE_CODE (member) == CONST_DECL)
+ {
+ mark_used (member);
+ return convert_from_reference (member);
+ }
+
+ if (TREE_CODE (member) == FIELD_DECL && DECL_C_BIT_FIELD (member))
+ {
+ error ("invalid pointer to bit-field `%D'", member);
+ return error_mark_node;
+ }
+
/* A lot of this logic is now handled in lookup_member. */
- if (member && BASELINK_P (member))
+ if (BASELINK_P (member))
{
/* Go from the TREE_BASELINK to the member function info. */
tree fnfields = member;
- t = BASELINK_FUNCTIONS (fnfields);
+ tree t = BASELINK_FUNCTIONS (fnfields);
if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
{
@@ -1648,200 +1511,122 @@ build_offset_ref (type, name)
if (TREE_CODE (t) != TEMPLATE_ID_EXPR && !really_overloaded_fn (t))
{
- /* Get rid of a potential OVERLOAD around it */
+ /* Get rid of a potential OVERLOAD around it. */
t = OVL_CURRENT (t);
- /* unique functions are handled easily. */
- if (!enforce_access (basebinfo, t))
- return error_mark_node;
+ /* Unique functions are handled easily. */
+
+ /* For non-static member of base class, we need a special rule
+ for access checking [class.protected]:
+
+ If the access is to form a pointer to member, the
+ nested-name-specifier shall name the derived class
+ (or any class derived from that class). */
+ if (address_p && DECL_P (t)
+ && DECL_NONSTATIC_MEMBER_P (t))
+ perform_or_defer_access_check (TYPE_BINFO (type), t);
+ else
+ perform_or_defer_access_check (basebinfo, t);
+
mark_used (t);
if (DECL_STATIC_FUNCTION_P (t))
return t;
- t = build (OFFSET_REF, TREE_TYPE (t), decl, t);
- PTRMEM_OK_P (t) = 1;
- return t;
+ member = t;
}
-
- TREE_TYPE (fnfields) = unknown_type_node;
-
- t = build (OFFSET_REF, unknown_type_node, decl, fnfields);
- PTRMEM_OK_P (t) = 1;
- return t;
- }
-
- t = member;
-
- if (t == NULL_TREE)
- {
- error ("`%D' is not a member of type `%T'", name, type);
- return error_mark_node;
- }
-
- if (TREE_CODE (t) == TYPE_DECL)
- {
- TREE_USED (t) = 1;
- return t;
- }
- /* static class members and class-specific enum
- values can be returned without further ado. */
- if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL)
- {
- mark_used (t);
- return convert_from_reference (t);
- }
-
- if (TREE_CODE (t) == FIELD_DECL && DECL_C_BIT_FIELD (t))
- {
- error ("invalid pointer to bit-field `%D'", t);
- return error_mark_node;
- }
-
- /* static class functions too. */
- if (TREE_CODE (t) == FUNCTION_DECL
- && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
- abort ();
-
- /* In member functions, the form `type::name' is no longer
- equivalent to `this->type::name', at least not until
- resolve_offset_ref. */
- t = build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t);
- PTRMEM_OK_P (t) = 1;
- return t;
-}
-
-/* If a OFFSET_REF made it through to here, then it did
- not have its address taken. */
-
-tree
-resolve_offset_ref (exp)
- tree exp;
-{
- tree type = TREE_TYPE (exp);
- tree base = NULL_TREE;
- tree member;
- tree basetype, addr;
-
- if (TREE_CODE (exp) == OFFSET_REF)
- {
- member = TREE_OPERAND (exp, 1);
- base = TREE_OPERAND (exp, 0);
- }
- else
- {
- my_friendly_assert (TREE_CODE (type) == OFFSET_TYPE, 214);
- if (TYPE_OFFSET_BASETYPE (type) != current_class_type)
+ else
{
- error ("object missing in use of pointer-to-member construct");
- return error_mark_node;
+ TREE_TYPE (fnfields) = unknown_type_node;
+ member = fnfields;
}
- member = exp;
- type = TREE_TYPE (type);
- base = current_class_ref;
- }
-
- if (BASELINK_P (member) || TREE_CODE (member) == TEMPLATE_ID_EXPR)
- return build_unary_op (ADDR_EXPR, exp, 0);
-
- if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE)
- {
- if (!flag_ms_extensions)
- /* A single non-static member, make sure we don't allow a
- pointer-to-member. */
- exp = ovl_cons (member, NULL_TREE);
-
- return build_unary_op (ADDR_EXPR, exp, 0);
- }
-
- if ((TREE_CODE (member) == VAR_DECL
- && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member))
- && ! TYPE_PTRMEM_P (TREE_TYPE (member)))
- || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE)
- {
- /* These were static members. */
- if (!cxx_mark_addressable (member))
- return error_mark_node;
- return member;
- }
-
- if (TREE_CODE (TREE_TYPE (member)) == POINTER_TYPE
- && TREE_CODE (TREE_TYPE (TREE_TYPE (member))) == METHOD_TYPE)
- return member;
-
- /* Syntax error can cause a member which should
- have been seen as static to be grok'd as non-static. */
- if (TREE_CODE (member) == FIELD_DECL && current_class_ref == NULL_TREE)
- {
- cp_error_at ("member `%D' is non-static but referenced as a static member",
- member);
- error ("at this point in file");
- return error_mark_node;
}
+ else if (address_p && TREE_CODE (member) == FIELD_DECL)
+ /* We need additional test besides the one in
+ check_accessibility_of_qualified_id in case it is
+ a pointer to non-static member. */
+ perform_or_defer_access_check (TYPE_BINFO (type), member);
- /* The first case is really just a reference to a member of `this'. */
- if (TREE_CODE (member) == FIELD_DECL
- && (base == current_class_ref || is_dummy_object (base)))
+ if (!address_p)
{
- tree binfo = NULL_TREE;
+ /* If MEMBER is non-static, then the program has fallen afoul of
+ [expr.prim]:
- /* Try to get to basetype from 'this'; if that doesn't work,
- nothing will. */
- base = current_class_ref;
+ An id-expression that denotes a nonstatic data member or
+ nonstatic member function of a class can only be used:
- /* First convert to the intermediate base specified, if appropriate. */
- if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
- base = build_scoped_ref (base, TYPE_OFFSET_BASETYPE (type), &binfo);
+ -- as part of a class member access (_expr.ref_) in which the
+ object-expression refers to the member's class or a class
+ derived from that class, or
- return build_class_member_access_expr (base, member,
- /*access_path=*/NULL_TREE,
- /*preserve_reference=*/false);
- }
+ -- to form a pointer to member (_expr.unary.op_), or
- /* Ensure that we have an object. */
- if (is_dummy_object (base))
- addr = error_mark_node;
- else
- /* If this is a reference to a member function, then return the
- address of the member function (which may involve going
- through the object's vtable), otherwise, return an expression
- for the dereferenced pointer-to-member construct. */
- addr = build_unary_op (ADDR_EXPR, base, 0);
+ -- in the body of a nonstatic member function of that class or
+ of a class derived from that class (_class.mfct.nonstatic_), or
- if (TYPE_PTRMEM_P (TREE_TYPE (member)))
- {
- if (addr == error_mark_node)
+ -- in a mem-initializer for a constructor for that class or for
+ a class derived from that class (_class.base.init_). */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (member))
+ {
+ /* Build a representation of a the qualified name suitable
+ for use as the operand to "&" -- even though the "&" is
+ not actually present. */
+ member = build (OFFSET_REF, TREE_TYPE (member), decl, member);
+ /* In Microsoft mode, treat a non-static member function as if
+ it were a pointer-to-member. */
+ if (flag_ms_extensions)
+ {
+ PTRMEM_OK_P (member) = 1;
+ return build_unary_op (ADDR_EXPR, member, 0);
+ }
+ error ("invalid use of non-static member function `%D'",
+ TREE_OPERAND (member, 1));
+ return member;
+ }
+ else if (TREE_CODE (member) == FIELD_DECL)
{
- error ("object missing in `%E'", exp);
+ error ("invalid use of non-static data member `%D'", member);
return error_mark_node;
}
-
- basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (member)));
- basetype = lookup_base (TREE_TYPE (TREE_TYPE (addr)),
- basetype, ba_check, NULL);
- addr = build_base_path (PLUS_EXPR, addr, basetype, 1);
-
- member = cp_convert (ptrdiff_type_node, member);
-
- addr = build (PLUS_EXPR, build_pointer_type (type), addr, member);
- return build_indirect_ref (addr, 0);
- }
- else if (TYPE_PTRMEMFUNC_P (TREE_TYPE (member)))
- {
- return get_member_function_from_ptrfunc (&addr, member);
+ return member;
}
- abort ();
- /* NOTREACHED */
- return NULL_TREE;
+
+ /* In member functions, the form `type::name' is no longer
+ equivalent to `this->type::name', at least not until
+ resolve_offset_ref. */
+ member = build (OFFSET_REF, TREE_TYPE (member), decl, member);
+ PTRMEM_OK_P (member) = 1;
+ return member;
}
/* If DECL is a `const' declaration, and its value is a known
constant, then return that value. */
tree
-decl_constant_value (decl)
- tree decl;
+decl_constant_value (tree decl)
{
- if (TREE_READONLY_DECL_P (decl)
- && ! TREE_THIS_VOLATILE (decl)
+ /* When we build a COND_EXPR, we don't know whether it will be used
+ as an lvalue or as an rvalue. If it is an lvalue, it's not safe
+ to replace the second and third operands with their
+ initializers. So, we do that here. */
+ if (TREE_CODE (decl) == COND_EXPR)
+ {
+ tree d1;
+ tree d2;
+
+ d1 = decl_constant_value (TREE_OPERAND (decl, 1));
+ d2 = decl_constant_value (TREE_OPERAND (decl, 2));
+
+ if (d1 != TREE_OPERAND (decl, 1) || d2 != TREE_OPERAND (decl, 2))
+ return build (COND_EXPR,
+ TREE_TYPE (decl),
+ TREE_OPERAND (decl, 0), d1, d2);
+ }
+
+ if (DECL_P (decl)
+ && (/* Enumeration constants are constant. */
+ TREE_CODE (decl) == CONST_DECL
+ /* And so are variables with a 'const' type -- unless they
+ are also 'volatile'. */
+ || CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))
&& DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node
/* This is invalid if initial value is not constant.
@@ -1859,8 +1644,7 @@ decl_constant_value (decl)
/* Call the global __builtin_delete to delete ADDR. */
static tree
-build_builtin_delete_call (addr)
- tree addr;
+build_builtin_delete_call (tree addr)
{
mark_used (global_delete_fndecl);
return build_call (global_delete_fndecl, build_tree_list (NULL_TREE, addr));
@@ -1893,10 +1677,7 @@ build_builtin_delete_call (addr)
PLACEMENT is the `placement' list for user-defined operator new (). */
tree
-build_new (placement, decl, init, use_global_new)
- tree placement;
- tree decl, init;
- int use_global_new;
+build_new (tree placement, tree decl, tree init, int use_global_new)
{
tree type, rval;
tree nelts = NULL_TREE, t;
@@ -1926,7 +1707,7 @@ build_new (placement, decl, init, use_global_new)
if (absdcl && TREE_CODE (absdcl) == ARRAY_REF)
{
- /* probably meant to be a vec new */
+ /* Probably meant to be a vec new. */
tree this_nelts;
while (TREE_OPERAND (absdcl, 0)
@@ -1950,7 +1731,7 @@ build_new (placement, decl, init, use_global_new)
else
{
if (build_expr_type_conversion (WANT_INT | WANT_ENUM,
- this_nelts, 0)
+ this_nelts, false)
== NULL_TREE)
pedwarn ("size in array new must have integral type");
@@ -2013,8 +1794,10 @@ build_new (placement, decl, init, use_global_new)
else
t = type;
- rval = build_min_nt (NEW_EXPR, placement, t, init);
+ rval = build_min (NEW_EXPR, build_pointer_type (type),
+ placement, t, init);
NEW_EXPR_USE_GLOBAL (rval) = use_global_new;
+ TREE_SIDE_EFFECTS (rval) = 1;
return rval;
}
@@ -2065,8 +1848,7 @@ build_new (placement, decl, init, use_global_new)
/* Given a Java class, return a decl for the corresponding java.lang.Class. */
tree
-build_java_class_ref (type)
- tree type;
+build_java_class_ref (tree type)
{
tree name = NULL_TREE, class_decl;
static tree CL_suffix = NULL_TREE;
@@ -2081,7 +1863,7 @@ build_java_class_ref (type)
jclass_node = TREE_TYPE (jclass_node);
}
- /* Mangle the class$ field */
+ /* Mangle the class$ field. */
{
tree field;
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
@@ -2115,8 +1897,7 @@ build_java_class_ref (type)
known that a cookie is needed. */
static tree
-get_cookie_size (type)
- tree type;
+get_cookie_size (tree type)
{
tree cookie_size;
@@ -2139,25 +1920,33 @@ get_cookie_size (type)
value is immediately handed to expand_expr. */
static tree
-build_new_1 (exp)
- tree exp;
+build_new_1 (tree exp)
{
tree placement, init;
- tree type, true_type, size, rval, t;
+ tree true_type, size, rval;
+ /* The type of the new-expression. (This type is always a pointer
+ type.) */
+ tree pointer_type;
+ /* The type pointed to by POINTER_TYPE. */
+ tree type;
+ /* The type being allocated. For "new T[...]" this will be an
+ ARRAY_TYPE. */
tree full_type;
+ /* A pointer type pointing to to the FULL_TYPE. */
+ tree full_pointer_type;
tree outer_nelts = NULL_TREE;
tree nelts = NULL_TREE;
- tree alloc_call, alloc_expr, alloc_node;
+ tree alloc_call, alloc_expr;
+ /* The address returned by the call to "operator new". This node is
+ a VAR_DECL and is therefore reusable. */
+ tree alloc_node;
tree alloc_fn;
tree cookie_expr, init_expr;
int has_array = 0;
enum tree_code code;
- int use_cookie, nothrow, check_new;
+ int nothrow, check_new;
/* Nonzero if the user wrote `::new' rather than just `new'. */
int globally_qualified_p;
- /* Nonzero if we're going to call a global operator new, rather than
- a class-specific version. */
- int use_global_new;
int use_java_new = 0;
/* If non-NULL, the number of extra bytes to allocate at the
beginning of the storage allocated for an array-new expression in
@@ -2166,6 +1955,16 @@ build_new_1 (exp)
/* 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;
+ /* The address of the thing allocated, not including any cookie. In
+ particular, if an array cookie is in use, DATA_ADDR is the
+ address of the first array element. This node is a VAR_DECL, and
+ is therefore reusable. */
+ tree data_addr;
+ tree init_preeval_expr = NULL_TREE;
placement = TREE_OPERAND (exp, 0);
type = TREE_OPERAND (exp, 1);
@@ -2200,10 +1999,6 @@ build_new_1 (exp)
if (!complete_type_or_else (true_type, exp))
return error_mark_node;
- size = size_in_bytes (true_type);
- if (has_array)
- size = size_binop (MULT_EXPR, size, convert (sizetype, nelts));
-
if (TREE_CODE (true_type) == VOID_TYPE)
{
error ("invalid type `void' for new");
@@ -2213,42 +2008,18 @@ build_new_1 (exp)
if (abstract_virtuals_error (NULL_TREE, true_type))
return error_mark_node;
- /* Figure out whether or not we're going to use the global operator
- new. */
- if (!globally_qualified_p
- && IS_AGGR_TYPE (true_type)
- && (has_array
- ? TYPE_HAS_ARRAY_NEW_OPERATOR (true_type)
- : TYPE_HAS_NEW_OPERATOR (true_type)))
- use_global_new = 0;
- else
- use_global_new = 1;
-
- /* We only need cookies for arrays containing types for which we
- need cookies. */
- if (!has_array || !TYPE_VEC_NEW_USES_COOKIE (true_type))
- use_cookie = 0;
- /* When using placement new, users may not realize that they need
- the extra storage. We require that the operator called be
- the global placement operator new[]. */
- else if (placement && !TREE_CHAIN (placement)
- && same_type_p (TREE_TYPE (TREE_VALUE (placement)),
- ptr_type_node))
- use_cookie = !use_global_new;
- /* Otherwise, we need the cookie. */
- else
- use_cookie = 1;
-
- /* Compute the number of extra bytes to allocate, now that we know
- whether or not we need the cookie. */
- if (use_cookie)
+ is_initialized = (TYPE_NEEDS_CONSTRUCTING (type) || init);
+ if (CP_TYPE_CONST_P (true_type) && !is_initialized)
{
- cookie_size = get_cookie_size (true_type);
- size = size_binop (PLUS_EXPR, size, cookie_size);
+ error ("uninitialized const in `new' of `%#T'", true_type);
+ return error_mark_node;
}
+ size = size_in_bytes (true_type);
+ if (has_array)
+ size = size_binop (MULT_EXPR, size, convert (sizetype, nelts));
+
/* Allocate the object. */
-
if (! placement && TYPE_FOR_JAVA (true_type))
{
tree class_addr, alloc_decl;
@@ -2256,11 +2027,18 @@ build_new_1 (exp)
tree class_size = size_in_bytes (true_type);
static const char alloc_name[] = "_Jv_AllocObject";
use_java_new = 1;
- alloc_decl = IDENTIFIER_GLOBAL_VALUE (get_identifier (alloc_name));
- if (alloc_decl == NULL_TREE)
- fatal_error ("call to Java constructor with `%s' undefined",
- alloc_name);
-
+ if (!get_global_value_if_present (get_identifier (alloc_name),
+ &alloc_decl))
+ {
+ error ("call to Java constructor with `%s' undefined", alloc_name);
+ return error_mark_node;
+ }
+ else if (really_overloaded_fn (alloc_decl))
+ {
+ error ("`%D' should never be overloaded", alloc_decl);
+ return error_mark_node;
+ }
+ alloc_decl = OVL_CURRENT (alloc_decl);
class_addr = build1 (ADDR_EXPR, jclass_node, class_decl);
alloc_call = (build_function_call
(alloc_decl,
@@ -2270,33 +2048,82 @@ build_new_1 (exp)
else
{
tree fnname;
- tree args;
+ tree fns;
- args = tree_cons (NULL_TREE, size, placement);
fnname = ansi_opname (code);
- if (use_global_new)
- alloc_call = (build_new_function_call
- (lookup_function_nonclass (fnname, args),
- args));
+ if (!globally_qualified_p
+ && CLASS_TYPE_P (true_type)
+ && (has_array
+ ? TYPE_HAS_ARRAY_NEW_OPERATOR (true_type)
+ : TYPE_HAS_NEW_OPERATOR (true_type)))
+ {
+ /* Use a class-specific operator new. */
+ /* If a cookie is required, add some extra space. */
+ if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type))
+ {
+ cookie_size = get_cookie_size (true_type);
+ size = size_binop (PLUS_EXPR, size, cookie_size);
+ }
+ /* Create the argument list. */
+ args = tree_cons (NULL_TREE, size, placement);
+ /* Do name-lookup to find the appropriate operator. */
+ fns = lookup_fnfields (true_type, fnname, /*protect=*/2);
+ if (!fns)
+ {
+ /* See PR 15967. This should never happen (and it is
+ fixed correctly in mainline), but on the release branch
+ we prefer this less-intrusive approacch. */
+ error ("no suitable or ambiguous `%D' found in class `%T'",
+ fnname, true_type);
+ return error_mark_node;
+ }
+ if (TREE_CODE (fns) == TREE_LIST)
+ {
+ error ("request for member `%D' is ambiguous", fnname);
+ print_candidates (fns);
+ return error_mark_node;
+ }
+ alloc_call = build_new_method_call (build_dummy_object (true_type),
+ fns, args,
+ /*conversion_path=*/NULL_TREE,
+ LOOKUP_NORMAL);
+ }
else
- alloc_call = build_method_call (build_dummy_object (true_type),
- fnname, args,
- TYPE_BINFO (true_type),
- LOOKUP_NORMAL);
+ {
+ /* Use a global operator new. */
+ /* See if a cookie might be required. */
+ if (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type))
+ cookie_size = get_cookie_size (true_type);
+ else
+ cookie_size = NULL_TREE;
+
+ alloc_call = build_operator_new_call (fnname, placement,
+ &size, &cookie_size);
+ }
}
if (alloc_call == error_mark_node)
return error_mark_node;
- /* The ALLOC_CALL should be a CALL_EXPR -- or a COMPOUND_EXPR whose
- right-hand-side is ultimately a CALL_EXPR -- and the first
- operand should be the address of a known FUNCTION_DECL. */
- t = alloc_call;
- while (TREE_CODE (t) == COMPOUND_EXPR)
- t = TREE_OPERAND (t, 1);
- alloc_fn = get_callee_fndecl (t);
+ /* In the simple case, we can stop now. */
+ pointer_type = build_pointer_type (type);
+ if (!cookie_size && !is_initialized)
+ return build_nop (pointer_type, alloc_call);
+
+ /* While we're working, use a pointer to the type we've actually
+ allocated. Store the result of the call in a variable so that we
+ can use it more than once. */
+ full_pointer_type = build_pointer_type (full_type);
+ alloc_expr = get_target_expr (build_nop (full_pointer_type, alloc_call));
+ alloc_node = TARGET_EXPR_SLOT (alloc_expr);
+
+ /* Strip any COMPOUND_EXPRs from ALLOC_CALL. */
+ while (TREE_CODE (alloc_call) == COMPOUND_EXPR)
+ alloc_call = TREE_OPERAND (alloc_call, 1);
+ alloc_fn = get_callee_fndecl (alloc_call);
my_friendly_assert (alloc_fn != NULL_TREE, 20020325);
+
/* Now, check to see if this function is actually a placement
allocation function. This can happen even when PLACEMENT is NULL
because we might have something like:
@@ -2311,6 +2138,17 @@ build_new_1 (exp)
= (type_num_arguments (TREE_TYPE (alloc_fn)) > 1
|| varargs_function_p (alloc_fn));
+ /* Preevaluate the placement args so that we don't reevaluate them for a
+ placement delete. */
+ if (placement_allocation_fn_p)
+ {
+ tree inits;
+ stabilize_call (alloc_call, &inits);
+ if (inits)
+ alloc_expr = build (COMPOUND_EXPR, TREE_TYPE (alloc_expr), inits,
+ alloc_expr);
+ }
+
/* unless an allocation function is declared with an empty excep-
tion-specification (_except.spec_), throw(), it indicates failure to
allocate storage by throwing a bad_alloc exception (clause _except_,
@@ -2324,81 +2162,81 @@ build_new_1 (exp)
nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn));
check_new = (flag_check_new || nothrow) && ! use_java_new;
- alloc_expr = alloc_call;
-
- if (use_cookie)
- /* Adjust so we're pointing to the start of the object. */
- alloc_expr = build (PLUS_EXPR, TREE_TYPE (alloc_expr),
- alloc_expr, cookie_size);
-
- /* While we're working, use a pointer to the type we've actually
- allocated. */
- alloc_expr = convert (build_pointer_type (full_type), alloc_expr);
-
- /* Now save the allocation expression so we only evaluate it once. */
- alloc_expr = get_target_expr (alloc_expr);
- alloc_node = TREE_OPERAND (alloc_expr, 0);
-
- /* Now initialize the cookie. */
- if (use_cookie)
+ if (cookie_size)
{
tree cookie;
+ /* Adjust so we're pointing to the start of the object. */
+ data_addr = get_target_expr (build (PLUS_EXPR, full_pointer_type,
+ alloc_node, cookie_size));
+
/* Store the number of bytes allocated so that we can know how
many elements to destroy later. We use the last sizeof
(size_t) bytes to store the number of elements. */
cookie = build (MINUS_EXPR, build_pointer_type (sizetype),
- alloc_node, size_in_bytes (sizetype));
+ data_addr, size_in_bytes (sizetype));
cookie = build_indirect_ref (cookie, NULL);
- cookie_expr = build (MODIFY_EXPR, void_type_node, cookie, nelts);
- TREE_SIDE_EFFECTS (cookie_expr) = 1;
+ cookie_expr = build (MODIFY_EXPR, sizetype, cookie, nelts);
+ data_addr = TARGET_EXPR_SLOT (data_addr);
}
else
- cookie_expr = NULL_TREE;
+ {
+ cookie_expr = NULL_TREE;
+ data_addr = alloc_node;
+ }
- /* Now initialize the allocated object. */
- init_expr = NULL_TREE;
- if (TYPE_NEEDS_CONSTRUCTING (type) || init)
+ /* Now initialize the allocated object. Note that we preevaluate the
+ initialization expression, apart from the actual constructor call or
+ assignment--we do this because we want to delay the allocation as long
+ as possible in order to minimize the size of the exception region for
+ placement delete. */
+ if (is_initialized)
{
- init_expr = build_indirect_ref (alloc_node, NULL);
+ bool stable;
+
+ init_expr = build_indirect_ref (data_addr, NULL);
if (init == void_zero_node)
init = build_default_init (full_type, nelts);
- else if (init && pedantic && has_array)
+ else if (init && has_array)
pedwarn ("ISO C++ forbids initialization in array new");
if (has_array)
- init_expr
- = build_vec_init (init_expr,
- cp_build_binary_op (MINUS_EXPR, outer_nelts,
- integer_one_node),
- init, /*from_array=*/0);
+ {
+ init_expr
+ = build_vec_init (init_expr,
+ cp_build_binary_op (MINUS_EXPR, outer_nelts,
+ integer_one_node),
+ init, /*from_array=*/0);
+
+ /* An array initialization is stable because the initialization
+ of each element is a full-expression, so the temporaries don't
+ leak out. */
+ stable = true;
+ }
else if (TYPE_NEEDS_CONSTRUCTING (type))
- init_expr = build_special_member_call (init_expr,
- complete_ctor_identifier,
- init, TYPE_BINFO (true_type),
- LOOKUP_NORMAL);
+ {
+ init_expr = build_special_member_call (init_expr,
+ complete_ctor_identifier,
+ init, TYPE_BINFO (true_type),
+ LOOKUP_NORMAL);
+ stable = stabilize_init (init_expr, &init_preeval_expr);
+ }
else
{
/* We are processing something like `new int (10)', which
means allocate an int, and initialize it with 10. */
if (TREE_CODE (init) == TREE_LIST)
- {
- if (TREE_CHAIN (init) != NULL_TREE)
- pedwarn
- ("initializer list being treated as compound expression");
- init = build_compound_expr (init);
- }
+ init = build_x_compound_expr_from_list (init, "new initializer");
+
else if (TREE_CODE (init) == CONSTRUCTOR
&& TREE_TYPE (init) == NULL_TREE)
- {
- pedwarn ("ISO C++ forbids aggregate initializer to new");
- init = digest_init (type, init, 0);
- }
+ abort ();
init_expr = build_modify_expr (init_expr, INIT_EXPR, init);
+ stable = stabilize_init (init_expr, &init_preeval_expr);
}
if (init_expr == error_mark_node)
@@ -2418,47 +2256,34 @@ build_new_1 (exp)
tree cleanup;
int flags = (LOOKUP_NORMAL
| (globally_qualified_p * LOOKUP_GLOBAL));
- tree delete_node;
-
- if (use_cookie)
- /* Subtract the padding back out to get to the pointer returned
- from operator new. */
- delete_node = fold (build (MINUS_EXPR, TREE_TYPE (alloc_node),
- alloc_node, cookie_size));
- else
- delete_node = alloc_node;
/* The Standard is unclear here, but the right thing to do
- is to use the same method for finding deallocation
- functions that we use for finding allocation functions. */
+ is to use the same method for finding deallocation
+ functions that we use for finding allocation functions. */
flags |= LOOKUP_SPECULATIVELY;
- cleanup = build_op_delete_call (dcode, delete_node, size, flags,
+ cleanup = build_op_delete_call (dcode, alloc_node, size, flags,
(placement_allocation_fn_p
? alloc_call : NULL_TREE));
- /* Ack! First we allocate the memory. Then we set our sentry
- variable to true, and expand a cleanup that deletes the memory
- if sentry is true. Then we run the constructor, and finally
- clear the sentry.
-
- It would be nice to be able to handle this without the sentry
- variable, perhaps with a TRY_CATCH_EXPR, but this doesn't
- work. We allocate the space first, so if there are any
- temporaries with cleanups in the constructor args we need this
- EH region to extend until end of full-expression to preserve
- nesting.
-
- If the backend had some mechanism so that we could force the
- allocation to be expanded after all the other args to the
- constructor, that would fix the nesting problem and we could
- do away with this complexity. But that would complicate other
- things; in particular, it would make it difficult to bail out
- if the allocation function returns null. Er, no, it wouldn't;
- we just don't run the constructor. The standard says it's
- unspecified whether or not the args are evaluated. */
-
- if (cleanup)
+ if (!cleanup)
+ /* We're done. */;
+ else if (stable)
+ /* This is much simpler if we were able to preevaluate all of
+ the arguments to the constructor call. */
+ init_expr = build (TRY_CATCH_EXPR, void_type_node,
+ init_expr, cleanup);
+ else
+ /* Ack! First we allocate the memory. Then we set our sentry
+ variable to true, and expand a cleanup that deletes the
+ memory if sentry is true. Then we run the constructor, and
+ finally clear the sentry.
+
+ We need to do this because we allocate the space first, so
+ if there are any temporaries with cleanups in the
+ constructor args and we weren't able to preevaluate them, we
+ need this EH region to extend until end of full-expression
+ to preserve nesting. */
{
tree end, sentry, begin;
@@ -2479,14 +2304,15 @@ build_new_1 (exp)
build (COMPOUND_EXPR, void_type_node, init_expr,
end));
}
+
}
}
- else if (CP_TYPE_CONST_P (true_type))
- error ("uninitialized const in `new' of `%#T'", true_type);
+ else
+ init_expr = NULL_TREE;
/* Now build up the return value in reverse order. */
- rval = alloc_node;
+ rval = data_addr;
if (init_expr)
rval = build (COMPOUND_EXPR, TREE_TYPE (rval), init_expr, rval);
@@ -2494,28 +2320,28 @@ build_new_1 (exp)
rval = build (COMPOUND_EXPR, TREE_TYPE (rval), cookie_expr, rval);
if (rval == alloc_node)
- /* If we didn't modify anything, strip the TARGET_EXPR and return the
- (adjusted) call. */
- rval = TREE_OPERAND (alloc_expr, 1);
+ /* If we don't have an initializer or a cookie, strip the TARGET_EXPR
+ and return the call (which doesn't need to be adjusted). */
+ rval = TARGET_EXPR_INITIAL (alloc_expr);
else
{
if (check_new)
{
- tree nullexp;
- tree ifexp;
-
- nullexp = convert (TREE_TYPE (alloc_node),
- use_cookie ? cookie_size : size_zero_node);
- ifexp = cp_build_binary_op (NE_EXPR, alloc_node, nullexp);
+ tree ifexp = cp_build_binary_op (NE_EXPR, alloc_node,
+ integer_zero_node);
rval = build_conditional_expr (ifexp, rval, alloc_node);
}
+ /* Perform the allocation before anything else, so that ALLOC_NODE
+ has been initialized before we start using it. */
rval = build (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval);
}
- /* Now strip the outer ARRAY_TYPE, so we return a pointer to the first
- element. */
- rval = convert (build_pointer_type (type), rval);
+ if (init_preeval_expr)
+ rval = build (COMPOUND_EXPR, TREE_TYPE (rval), init_preeval_expr, rval);
+
+ /* Convert to the final type. */
+ rval = build_nop (pointer_type, rval);
/* A new-expression is never an lvalue. */
if (real_lvalue_p (rval))
@@ -2525,10 +2351,8 @@ build_new_1 (exp)
}
static tree
-build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
- tree base, maxindex, type;
- special_function_kind auto_delete_vec;
- int use_global_delete;
+build_vec_delete_1 (tree base, tree maxindex, tree type,
+ special_function_kind auto_delete_vec, int use_global_delete)
{
tree virtual_size;
tree ptype = build_pointer_type (type = complete_type (type));
@@ -2542,7 +2366,7 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
tree body;
/* This is the LOOP_EXPR that governs the deletion of the elements. */
- tree loop;
+ tree loop = 0;
/* This is the thing that governs what to do after the loop has run. */
tree deallocate_expr = 0;
@@ -2558,10 +2382,7 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
abort ();
if (! IS_AGGR_TYPE (type) || TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
- {
- loop = integer_zero_node;
- goto no_destructor;
- }
+ goto no_destructor;
/* The below is short by the cookie size. */
virtual_size = size_binop (MULT_EXPR, size_exp,
@@ -2576,32 +2397,21 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
controller = build (BIND_EXPR, void_type_node, tbase, NULL_TREE, NULL_TREE);
TREE_SIDE_EFFECTS (controller) = 1;
- body = NULL_TREE;
-
- body = tree_cons (NULL_TREE,
- build_delete (ptype, tbase, sfk_complete_destructor,
- LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1),
- body);
+ body = build (EXIT_EXPR, void_type_node,
+ build (EQ_EXPR, boolean_type_node, base, tbase));
+ body = build_compound_expr
+ (body, build_modify_expr (tbase, NOP_EXPR,
+ build (MINUS_EXPR, ptype, tbase, size_exp)));
+ body = build_compound_expr
+ (body, build_delete (ptype, tbase, sfk_complete_destructor,
+ LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1));
- body = tree_cons (NULL_TREE,
- build_modify_expr (tbase, NOP_EXPR, build (MINUS_EXPR, ptype, tbase, size_exp)),
- body);
-
- body = tree_cons (NULL_TREE,
- build (EXIT_EXPR, void_type_node,
- build (EQ_EXPR, boolean_type_node, base, tbase)),
- body);
-
- loop = build (LOOP_EXPR, void_type_node, build_compound_expr (body));
-
- loop = tree_cons (NULL_TREE, tbase_init,
- tree_cons (NULL_TREE, loop, NULL_TREE));
- loop = build_compound_expr (loop);
+ loop = build (LOOP_EXPR, void_type_node, body);
+ loop = build_compound_expr (tbase_init, loop);
no_destructor:
/* If the delete flag is one, or anything else with the low bit set,
delete the storage. */
- deallocate_expr = integer_zero_node;
if (auto_delete_vec != sfk_base_destructor)
{
tree base_tbd;
@@ -2634,15 +2444,17 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
virtual_size);
}
- if (loop && deallocate_expr != integer_zero_node)
- {
- body = tree_cons (NULL_TREE, loop,
- tree_cons (NULL_TREE, deallocate_expr, NULL_TREE));
- body = build_compound_expr (body);
- }
+ body = loop;
+ if (!deallocate_expr)
+ ;
+ else if (!body)
+ body = deallocate_expr;
else
- body = loop;
-
+ body = build_compound_expr (body, deallocate_expr);
+
+ if (!body)
+ body = integer_zero_node;
+
/* Outermost wrapper: If pointer is null, punt. */
body = fold (build (COND_EXPR, void_type_node,
fold (build (NE_EXPR, boolean_type_node, base,
@@ -2653,25 +2465,27 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete)
if (controller)
{
TREE_OPERAND (controller, 1) = body;
- return controller;
+ body = controller;
}
- else
- return cp_convert (void_type_node, body);
+
+ if (TREE_CODE (base) == SAVE_EXPR)
+ /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR. */
+ body = build (COMPOUND_EXPR, void_type_node, base, body);
+
+ return convert_to_void (body, /*implicit=*/NULL);
}
/* Create an unnamed variable of the indicated TYPE. */
tree
-create_temporary_var (type)
- tree type;
+create_temporary_var (tree type)
{
tree decl;
decl = build_decl (VAR_DECL, NULL_TREE, type);
TREE_USED (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
- DECL_SOURCE_FILE (decl) = input_filename;
- DECL_SOURCE_LINE (decl) = lineno;
+ DECL_SOURCE_LOCATION (decl) = input_location;
DECL_IGNORED_P (decl) = 1;
DECL_CONTEXT (decl) = current_function_decl;
@@ -2686,16 +2500,13 @@ create_temporary_var (type)
"outside" the binding contour of the function). */
static tree
-get_temp_regvar (type, init)
- tree type, init;
+get_temp_regvar (tree type, tree init)
{
tree decl;
decl = create_temporary_var (type);
- if (building_stmt_tree ())
- add_decl_stmt (decl);
- if (!building_stmt_tree ())
- SET_DECL_RTL (decl, assign_temp (type, 2, 0, 1));
+ add_decl_stmt (decl);
+
finish_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
return decl;
@@ -2718,9 +2529,7 @@ get_temp_regvar (type, init)
but use assignment instead of initialization. */
tree
-build_vec_init (base, maxindex, init, from_array)
- tree base, init, maxindex;
- int from_array;
+build_vec_init (tree base, tree maxindex, tree init, int from_array)
{
tree rval;
tree base2 = NULL_TREE;
@@ -2739,7 +2548,8 @@ build_vec_init (base, maxindex, init, from_array)
tree try_block = NULL_TREE;
tree try_body = NULL_TREE;
int num_initialized_elts = 0;
-
+ bool is_global;
+
if (TYPE_DOMAIN (atype))
maxindex = array_type_nelts (atype);
@@ -2769,22 +2579,23 @@ build_vec_init (base, maxindex, init, from_array)
ptype = build_pointer_type (type);
size = size_in_bytes (type);
if (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
- base = cp_convert (ptype, default_conversion (base));
+ base = cp_convert (ptype, decay_conversion (base));
/* The code we are generating looks like:
-
+ ({
T* t1 = (T*) base;
T* rval = t1;
ptrdiff_t iterator = maxindex;
try {
- do {
+ for (; iterator != -1; --iterator) {
... initialize *t1 ...
++t1;
- } while (--iterator != -1);
+ }
} catch (...) {
... destroy elements that were constructed ...
}
- return rval;
+ rval;
+ })
We can omit the try and catch blocks if we know that the
initialization will never throw an exception, or if the array
@@ -2800,7 +2611,7 @@ build_vec_init (base, maxindex, init, from_array)
of whatever cleverness the back-end has for dealing with copies
of blocks of memory. */
- begin_init_stmts (&stmt_expr, &compound_stmt);
+ is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
destroy_temps = stmts_are_full_exprs_p ();
current_stmt_tree ()->stmts_are_full_exprs_p = 0;
rval = get_temp_regvar (ptype, base);
@@ -2814,7 +2625,7 @@ build_vec_init (base, maxindex, init, from_array)
&& from_array != 2)
{
try_block = begin_try_block ();
- try_body = begin_compound_stmt (/*has_no_scope=*/1);
+ try_body = begin_compound_stmt (/*has_no_scope=*/true);
}
if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR)
@@ -2832,11 +2643,13 @@ build_vec_init (base, maxindex, init, from_array)
num_initialized_elts++;
+ current_stmt_tree ()->stmts_are_full_exprs_p = 1;
if (IS_AGGR_TYPE (type) || TREE_CODE (type) == ARRAY_TYPE)
finish_expr_stmt (build_aggr_init (baseref, elt, 0));
else
finish_expr_stmt (build_modify_expr (baseref, NOP_EXPR,
elt));
+ current_stmt_tree ()->stmts_are_full_exprs_p = 0;
finish_expr_stmt (build_unary_op (PREINCREMENT_EXPR, base, 0));
finish_expr_stmt (build_unary_op (PREDECREMENT_EXPR, iterator, 0));
@@ -2852,7 +2665,7 @@ build_vec_init (base, maxindex, init, from_array)
checking. */
if (init)
{
- base2 = default_conversion (init);
+ base2 = decay_conversion (init);
itype = TREE_TYPE (base2);
base2 = get_temp_regvar (itype, base2);
itype = TREE_TYPE (itype);
@@ -2880,33 +2693,20 @@ build_vec_init (base, maxindex, init, from_array)
{
/* If the ITERATOR is equal to -1, then we don't have to loop;
we've already initialized all the elements. */
- tree if_stmt;
- tree do_stmt;
- tree do_body;
+ tree for_stmt;
+ tree for_body;
tree elt_init;
- if_stmt = begin_if_stmt ();
- finish_if_stmt_cond (build (NE_EXPR, boolean_type_node,
- iterator, integer_minus_one_node),
- if_stmt);
+ for_stmt = begin_for_stmt ();
+ finish_for_init_stmt (for_stmt);
+ finish_for_cond (build (NE_EXPR, boolean_type_node,
+ iterator, integer_minus_one_node),
+ for_stmt);
+ finish_for_expr (build_unary_op (PREDECREMENT_EXPR, iterator, 0),
+ for_stmt);
/* Otherwise, loop through the elements. */
- do_stmt = begin_do_stmt ();
- do_body = begin_compound_stmt (/*has_no_scope=*/1);
-
- /* When we're not building a statement-tree, things are a little
- complicated. If, when we recursively call build_aggr_init,
- an expression containing a TARGET_EXPR is expanded, then it
- may get a cleanup. Then, the result of that expression is
- passed to finish_expr_stmt, which will call
- expand_start_target_temps/expand_end_target_temps. However,
- the latter call will not cause the cleanup to run because
- that block will still be on the block stack. So, we call
- expand_start_target_temps here manually; the corresponding
- call to expand_end_target_temps below will cause the cleanup
- to be performed. */
- if (!building_stmt_tree ())
- expand_start_target_temps ();
+ for_body = begin_compound_stmt (/*has_no_scope=*/true);
if (from_array)
{
@@ -2939,33 +2739,16 @@ build_vec_init (base, maxindex, init, from_array)
elt_init = build_aggr_init (build1 (INDIRECT_REF, type, base),
init, 0);
- /* The initialization of each array element is a
- full-expression, as per core issue 124. */
- if (!building_stmt_tree ())
- {
- genrtl_expr_stmt (elt_init);
- expand_end_target_temps ();
- }
- else
- {
- current_stmt_tree ()->stmts_are_full_exprs_p = 1;
- finish_expr_stmt (elt_init);
- current_stmt_tree ()->stmts_are_full_exprs_p = 0;
- }
+ current_stmt_tree ()->stmts_are_full_exprs_p = 1;
+ finish_expr_stmt (elt_init);
+ current_stmt_tree ()->stmts_are_full_exprs_p = 0;
finish_expr_stmt (build_unary_op (PREINCREMENT_EXPR, base, 0));
if (base2)
finish_expr_stmt (build_unary_op (PREINCREMENT_EXPR, base2, 0));
- finish_compound_stmt (/*has_no_scope=*/1, do_body);
- finish_do_body (do_stmt);
- finish_do_stmt (build (NE_EXPR, boolean_type_node,
- build_unary_op (PREDECREMENT_EXPR, iterator, 0),
- integer_minus_one_node),
- do_stmt);
-
- finish_then_clause (if_stmt);
- finish_if_stmt ();
+ finish_compound_stmt (for_body);
+ finish_for_stmt (for_stmt);
}
/* Make sure to cleanup any partially constructed elements. */
@@ -2984,20 +2767,24 @@ build_vec_init (base, maxindex, init, from_array)
type = strip_array_types (type);
}
- finish_compound_stmt (/*has_no_scope=*/1, try_body);
+ finish_compound_stmt (try_body);
finish_cleanup_try_block (try_block);
- e = build_vec_delete_1 (rval, m,
- type,
- sfk_base_destructor,
+ e = build_vec_delete_1 (rval, m, type, sfk_base_destructor,
/*use_global_delete=*/0);
finish_cleanup (e, try_block);
}
- /* The value of the array initialization is the address of the
- first element in the array. */
- finish_expr_stmt (rval);
+ /* The value of the array initialization is the array itself, RVAL
+ is a pointer to the first element. */
+ finish_stmt_expr_expr (rval);
+
+ stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
- stmt_expr = finish_init_stmts (stmt_expr, compound_stmt);
+ /* Now convert make the result have the correct type. */
+ atype = build_pointer_type (atype);
+ stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
+ stmt_expr = build_indirect_ref (stmt_expr, NULL);
+
current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
return stmt_expr;
}
@@ -3017,10 +2804,7 @@ build_vec_init (base, maxindex, init, from_array)
This does not call any destructors. */
tree
-build_x_delete (addr, which_delete, virtual_size)
- tree addr;
- int which_delete;
- tree virtual_size;
+build_x_delete (tree addr, int which_delete, tree virtual_size)
{
int use_global_delete = which_delete & 1;
int use_vec_delete = !!(which_delete & 2);
@@ -3034,13 +2818,10 @@ build_x_delete (addr, which_delete, virtual_size)
build_delete. */
static tree
-build_dtor_call (exp, dtor_kind, flags)
- tree exp;
- special_function_kind dtor_kind;
- int flags;
+build_dtor_call (tree exp, special_function_kind dtor_kind, int flags)
{
tree name;
-
+ tree fn;
switch (dtor_kind)
{
case sfk_complete_destructor:
@@ -3058,8 +2839,13 @@ build_dtor_call (exp, dtor_kind, flags)
default:
abort ();
}
- return build_method_call (exp, name, NULL_TREE,
- TYPE_BINFO (TREE_TYPE (exp)), flags);
+
+ exp = convert_from_reference (exp);
+ fn = lookup_fnfields (TREE_TYPE (exp), name, /*protect=*/2);
+ return build_new_method_call (exp, fn,
+ /*args=*/NULL_TREE,
+ /*conversion_path=*/NULL_TREE,
+ flags);
}
/* Generate a call to a destructor. TYPE is the type to cast ADDR to.
@@ -3072,11 +2858,8 @@ build_dtor_call (exp, dtor_kind, flags)
flags. See cp-tree.h for more info. */
tree
-build_delete (type, addr, auto_delete, flags, use_global_delete)
- tree type, addr;
- special_function_kind auto_delete;
- int flags;
- int use_global_delete;
+build_delete (tree type, tree addr, special_function_kind auto_delete,
+ int flags, int use_global_delete)
{
tree expr;
@@ -3092,27 +2875,39 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
if (TREE_CODE (type) == POINTER_TYPE)
{
+ bool complete_p = true;
+
type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
if (TREE_CODE (type) == ARRAY_TYPE)
goto handle_array;
- if (VOID_TYPE_P (type)
- /* We don't want to warn about delete of void*, only other
- incomplete types. Deleting other incomplete types
- invokes undefined behavior, but it is not ill-formed, so
- compile to something that would even do The Right Thing
- (TM) should the type have a trivial dtor and no delete
- operator. */
- || !complete_type_or_diagnostic (type, addr, 1)
- || !IS_AGGR_TYPE (type))
+ /* We don't want to warn about delete of void*, only other
+ incomplete types. Deleting other incomplete types
+ invokes undefined behavior, but it is not ill-formed, so
+ compile to something that would even do The Right Thing
+ (TM) should the type have a trivial dtor and no delete
+ operator. */
+ if (!VOID_TYPE_P (type))
{
- /* Call the builtin operator delete. */
- return build_builtin_delete_call (addr);
+ complete_type (type);
+ if (!COMPLETE_TYPE_P (type))
+ {
+ warning ("possible problem detected in invocation of "
+ "delete operator:");
+ cxx_incomplete_type_diagnostic (addr, type, 1);
+ inform ("neither the destructor nor the class-specific "
+ "operator delete will be called, even if they are "
+ "declared when the class is defined.");
+ complete_p = false;
+ }
}
+ if (VOID_TYPE_P (type) || !complete_p || !IS_AGGR_TYPE (type))
+ /* Call the builtin operator delete. */
+ return build_builtin_delete_call (addr);
if (TREE_SIDE_EFFECTS (addr))
addr = save_expr (addr);
- /* throw away const and volatile on target type of addr */
+ /* Throw away const and volatile on target type of addr. */
addr = convert_force (build_pointer_type (type), addr, 0);
}
else if (TREE_CODE (type) == ARRAY_TYPE)
@@ -3223,7 +3018,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
Called from begin_destructor_body. */
void
-push_base_cleanups ()
+push_base_cleanups (void)
{
tree binfos;
int i, n_baseclasses;
@@ -3305,28 +3100,26 @@ push_base_cleanups ()
/* For type TYPE, delete the virtual baseclass objects of DECL. */
tree
-build_vbase_delete (type, decl)
- tree type, decl;
+build_vbase_delete (tree type, tree decl)
{
tree vbases = CLASSTYPE_VBASECLASSES (type);
- tree result = NULL_TREE;
+ tree result;
tree addr = build_unary_op (ADDR_EXPR, decl, 0);
my_friendly_assert (addr != error_mark_node, 222);
- while (vbases)
+ for (result = convert_to_void (integer_zero_node, NULL);
+ vbases; vbases = TREE_CHAIN (vbases))
{
- tree this_addr
- = convert_force (build_pointer_type (BINFO_TYPE (TREE_VALUE (vbases))),
- addr, 0);
- result = tree_cons (NULL_TREE,
- build_delete (TREE_TYPE (this_addr), this_addr,
- sfk_base_destructor,
- LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0),
- result);
- vbases = TREE_CHAIN (vbases);
+ tree base_addr = convert_force
+ (build_pointer_type (BINFO_TYPE (TREE_VALUE (vbases))), addr, 0);
+ tree base_delete = build_delete
+ (TREE_TYPE (base_addr), base_addr, sfk_base_destructor,
+ LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0);
+
+ result = build_compound_expr (result, base_delete);
}
- return build_compound_expr (nreverse (result));
+ return result;
}
/* Build a C++ vector delete expression.
@@ -3346,27 +3139,25 @@ build_vbase_delete (type, decl)
be worth bothering.) */
tree
-build_vec_delete (base, maxindex, auto_delete_vec, use_global_delete)
- tree base, maxindex;
- special_function_kind auto_delete_vec;
- int use_global_delete;
+build_vec_delete (tree base, tree maxindex,
+ special_function_kind auto_delete_vec, int use_global_delete)
{
tree type;
-
- if (TREE_CODE (base) == OFFSET_REF)
- base = resolve_offset_ref (base);
+ tree rval;
+ tree base_init = NULL_TREE;
type = TREE_TYPE (base);
- base = stabilize_reference (base);
-
if (TREE_CODE (type) == POINTER_TYPE)
{
/* Step back one from start of vector, and read dimension. */
tree cookie_addr;
if (TREE_SIDE_EFFECTS (base))
- base = save_expr (base);
+ {
+ base_init = get_target_expr (base);
+ base = TARGET_EXPR_SLOT (base_init);
+ }
type = strip_array_types (TREE_TYPE (type));
cookie_addr = build (MINUS_EXPR,
build_pointer_type (sizetype),
@@ -3376,12 +3167,16 @@ build_vec_delete (base, maxindex, auto_delete_vec, use_global_delete)
}
else if (TREE_CODE (type) == ARRAY_TYPE)
{
- /* get the total number of things in the array, maxindex is a bad name */
+ /* Get the total number of things in the array, maxindex is a
+ bad name. */
maxindex = array_type_nelts_total (type);
type = strip_array_types (type);
base = build_unary_op (ADDR_EXPR, base, 1);
if (TREE_SIDE_EFFECTS (base))
- base = save_expr (base);
+ {
+ base_init = get_target_expr (base);
+ base = TARGET_EXPR_SLOT (base_init);
+ }
}
else
{
@@ -3390,6 +3185,10 @@ build_vec_delete (base, maxindex, auto_delete_vec, use_global_delete)
return error_mark_node;
}
- return build_vec_delete_1 (base, maxindex, type, auto_delete_vec,
+ rval = build_vec_delete_1 (base, maxindex, type, auto_delete_vec,
use_global_delete);
+ if (base_init)
+ rval = build (COMPOUND_EXPR, TREE_TYPE (rval), base_init, rval);
+
+ return rval;
}
diff --git a/contrib/gcc/cp/lang-specs.h b/contrib/gcc/cp/lang-specs.h
index f7de6d4fb6de..5815ea57896e 100644
--- a/contrib/gcc/cp/lang-specs.h
+++ b/contrib/gcc/cp/lang-specs.h
@@ -1,21 +1,21 @@
/* Definitions for specs for C++.
- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
- Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -32,14 +32,26 @@ Boston, MA 02111-1307, USA. */
{".cpp", "@c++", 0},
{".c++", "@c++", 0},
{".C", "@c++", 0},
+ {".CPP", "@c++", 0},
+ {".H", "@c++-header", 0},
+ {".hh", "@c++-header", 0},
+ {"@c++-header",
+ "%{E|M|MM:cc1plus -E %(cpp_options) %2 %(cpp_debug_options)}\
+ %{!E:%{!M:%{!MM:\
+ %{save-temps|no-integrated-cpp:cc1plus -E\
+ %(cpp_options) %2 -o %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\
+ cc1plus %{save-temps|no-integrated-cpp:-fpreprocessed %{save-temps:%b.ii} %{!save-temps:%g.ii}}\
+ %{!save-temps:%{!no-integrated-cpp:%(cpp_unique_options)}}\
+ %(cc1_options) %2 %{+e1*}\
+ -o %g.s %{!o*:--output-pch=%i.gch} %W{o*:--output-pch=%*}%V}}}",
+ CPLUSPLUS_CPP_SPEC},
{"@c++",
- "%{E|M|MM:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\
- %(cpp_options) %2 %(cpp_debug_options)}\
+ "%{E|M|MM:cc1plus -E %(cpp_options) %2 %(cpp_debug_options)}\
%{!E:%{!M:%{!MM:\
- %{save-temps|no-integrated-cpp:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\
- %(cpp_options) %2 %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\
+ %{save-temps|no-integrated-cpp:cc1plus -E\
+ %(cpp_options) %2 -o %{save-temps:%b.ii} %{!save-temps:%g.ii} \n}\
cc1plus %{save-temps|no-integrated-cpp:-fpreprocessed %{save-temps:%b.ii} %{!save-temps:%g.ii}}\
- %{!save-temps:%{!no-integrated-cpp:%(cpp_unique_options) %{!no-gcc:-D__GNUG__=%v1}}}\
+ %{!save-temps:%{!no-integrated-cpp:%(cpp_unique_options)}}\
%(cc1_options) %2 %{+e1*}\
%{!fsyntax-only:%(invoke_as)}}}}",
CPLUSPLUS_CPP_SPEC},
diff --git a/contrib/gcc/cp/lex.c b/contrib/gcc/cp/lex.c
index 6660c848bf22..2239c76ca873 100644
--- a/contrib/gcc/cp/lex.c
+++ b/contrib/gcc/cp/lex.c
@@ -1,22 +1,22 @@
/* Separate lexical analyzer for GNU C++.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,71 +25,35 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "input.h"
#include "tree.h"
#include "cp-tree.h"
#include "cpplib.h"
#include "lex.h"
-#include "parse.h"
#include "flags.h"
#include "c-pragma.h"
#include "toplev.h"
#include "output.h"
-#include "ggc.h"
#include "tm_p.h"
#include "timevar.h"
-#include "diagnostic.h"
-#ifdef MULTIBYTE_CHARS
-#include "mbchar.h"
-#include <locale.h>
-#endif
-
-extern void yyprint PARAMS ((FILE *, int, YYSTYPE));
-
-static int interface_strcmp PARAMS ((const char *));
-static int *init_cpp_parse PARAMS ((void));
-static void init_cp_pragma PARAMS ((void));
+static int interface_strcmp (const char *);
+static void init_cp_pragma (void);
-static tree parse_strconst_pragma PARAMS ((const char *, int));
-static void handle_pragma_vtable PARAMS ((cpp_reader *));
-static void handle_pragma_unit PARAMS ((cpp_reader *));
-static void handle_pragma_interface PARAMS ((cpp_reader *));
-static void handle_pragma_implementation PARAMS ((cpp_reader *));
-static void handle_pragma_java_exceptions PARAMS ((cpp_reader *));
+static tree parse_strconst_pragma (const char *, int);
+static void handle_pragma_vtable (cpp_reader *);
+static void handle_pragma_unit (cpp_reader *);
+static void handle_pragma_interface (cpp_reader *);
+static void handle_pragma_implementation (cpp_reader *);
+static void handle_pragma_java_exceptions (cpp_reader *);
-#ifdef GATHER_STATISTICS
-#ifdef REDUCE_LENGTH
-static int reduce_cmp PARAMS ((int *, int *));
-static int token_cmp PARAMS ((int *, int *));
-#endif
-#endif
-static int is_global PARAMS ((tree));
-static void init_operators PARAMS ((void));
-static void copy_lang_type PARAMS ((tree));
+static void init_operators (void);
+static void copy_lang_type (tree);
/* A constraint that can be tested at compile time. */
-#ifdef __STDC__
#define CONSTRAINT(name, expr) extern int constraint_##name [(expr) ? 1 : -1]
-#else
-#define CONSTRAINT(name, expr) extern int constraint_/**/name [(expr) ? 1 : -1]
-#endif
-
-#include "cpplib.h"
-
-extern int yychar; /* the lookahead symbol */
-extern YYSTYPE yylval; /* the semantic value of the */
- /* lookahead symbol */
-
-/* the declaration found for the last IDENTIFIER token read in. yylex
- must look this up to detect typedefs, which get token type
- tTYPENAME, so it is left around in case the identifier is not a
- typedef but is used in a context which makes it a reference to a
- variable. */
-tree lastiddecl;
-
-/* Array for holding counts of the numbers of tokens seen. */
-extern int *token_count;
/* Functions and data structures for #pragma interface.
@@ -128,8 +92,7 @@ static struct impl_files *impl_file_chain;
and whose type is the modifier list. */
tree
-make_pointer_declarator (cv_qualifiers, target)
- tree cv_qualifiers, target;
+make_pointer_declarator (tree cv_qualifiers, tree target)
{
if (target && TREE_CODE (target) == IDENTIFIER_NODE
&& ANON_AGGRNAME_P (target))
@@ -148,32 +111,16 @@ make_pointer_declarator (cv_qualifiers, target)
and whose type is the modifier list. */
tree
-make_reference_declarator (cv_qualifiers, target)
- tree cv_qualifiers, target;
+make_reference_declarator (tree cv_qualifiers, tree target)
{
- if (target)
- {
- if (TREE_CODE (target) == ADDR_EXPR)
- {
- error ("cannot declare references to references");
- return target;
- }
- if (TREE_CODE (target) == INDIRECT_REF)
- {
- error ("cannot declare pointers to references");
- return target;
- }
- if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target))
- error ("type name expected before `&'");
- }
target = build_nt (ADDR_EXPR, target);
TREE_TYPE (target) = cv_qualifiers;
return target;
}
tree
-make_call_declarator (target, parms, cv_qualifiers, exception_specification)
- tree target, parms, cv_qualifiers, exception_specification;
+make_call_declarator (tree target, tree parms, tree cv_qualifiers,
+ tree exception_specification)
{
target = build_nt (CALL_EXPR, target,
tree_cons (parms, cv_qualifiers, NULL_TREE),
@@ -185,8 +132,8 @@ make_call_declarator (target, parms, cv_qualifiers, exception_specification)
}
void
-set_quals_and_spec (call_declarator, cv_qualifiers, exception_specification)
- tree call_declarator, cv_qualifiers, exception_specification;
+set_quals_and_spec (tree call_declarator, tree cv_qualifiers,
+ tree exception_specification)
{
CALL_DECLARATOR_QUALS (call_declarator) = cv_qualifiers;
CALL_DECLARATOR_EXCEPTION_SPEC (call_declarator) = exception_specification;
@@ -198,42 +145,12 @@ int interface_unknown; /* whether or not we know this class
to behave according to #pragma interface. */
-/* Initialization before switch parsing. */
void
-cxx_init_options ()
-{
- c_common_init_options (clk_cplusplus);
-
- /* Default exceptions on. */
- flag_exceptions = 1;
- /* By default wrap lines at 80 characters. Is getenv ("COLUMNS")
- preferable? */
- diagnostic_line_cutoff (global_dc) = 80;
- /* By default, emit location information once for every
- diagnostic message. */
- diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
-}
-
-void
-cxx_finish ()
+cxx_finish (void)
{
c_common_finish ();
}
-static int *
-init_cpp_parse ()
-{
-#ifdef GATHER_STATISTICS
-#ifdef REDUCE_LENGTH
- reduce_count = (int *) xcalloc (sizeof (int), (REDUCE_LENGTH + 1));
- reduce_count += 1;
- token_count = (int *) xcalloc (sizeof (int), (TOKEN_LENGTH + 1));
- token_count += 1;
-#endif
-#endif
- return token_count;
-}
-
/* A mapping from tree codes to operator name information. */
operator_name_info_t operator_name_info[(int) LAST_CPLUS_TREE_CODE];
/* Similar, but for assignment operators. */
@@ -247,7 +164,7 @@ operator_name_info_t assignment_operator_name_info[(int) LAST_CPLUS_TREE_CODE];
#undef DEF_OPERATOR
static void
-init_operators ()
+init_operators (void)
{
tree identifier;
char buffer[256];
@@ -288,8 +205,6 @@ init_operators ()
operator_name_info [(int) FLOOR_MOD_EXPR].name = "(floor %)";
operator_name_info [(int) ROUND_MOD_EXPR].name = "(round %)";
operator_name_info [(int) ABS_EXPR].name = "abs";
- operator_name_info [(int) FFS_EXPR].name = "ffs";
- operator_name_info [(int) BIT_ANDTC_EXPR].name = "&~";
operator_name_info [(int) TRUTH_AND_EXPR].name = "strict &&";
operator_name_info [(int) TRUTH_OR_EXPR].name = "strict ||";
operator_name_info [(int) IN_EXPR].name = "in";
@@ -316,7 +231,7 @@ init_operators ()
struct resword
{
const char *const word;
- const ENUM_BITFIELD(rid) rid : 16;
+ ENUM_BITFIELD(rid) const rid : 16;
const unsigned int disable : 16;
};
@@ -351,6 +266,8 @@ static const struct resword reswords[] =
{ "__inline__", RID_INLINE, 0 },
{ "__label__", RID_LABEL, 0 },
{ "__null", RID_NULL, 0 },
+ { "__offsetof", RID_OFFSETOF, 0 },
+ { "__offsetof__", RID_OFFSETOF, 0 },
{ "__real", RID_REALPART, 0 },
{ "__real__", RID_REALPART, 0 },
{ "__restrict", RID_RESTRICT, 0 },
@@ -429,146 +346,15 @@ static const struct resword reswords[] =
};
-/* Table mapping from RID_* constants to yacc token numbers.
- Unfortunately we have to have entries for all the keywords in all
- three languages. */
-const short rid_to_yy[RID_MAX] =
-{
- /* RID_STATIC */ SCSPEC,
- /* RID_UNSIGNED */ TYPESPEC,
- /* RID_LONG */ TYPESPEC,
- /* RID_CONST */ CV_QUALIFIER,
- /* RID_EXTERN */ SCSPEC,
- /* RID_REGISTER */ SCSPEC,
- /* RID_TYPEDEF */ SCSPEC,
- /* RID_SHORT */ TYPESPEC,
- /* RID_INLINE */ SCSPEC,
- /* RID_VOLATILE */ CV_QUALIFIER,
- /* RID_SIGNED */ TYPESPEC,
- /* RID_AUTO */ SCSPEC,
- /* RID_RESTRICT */ CV_QUALIFIER,
-
- /* C extensions. Bounded pointers are not yet in C++ */
- /* RID_BOUNDED */ 0,
- /* RID_UNBOUNDED */ 0,
- /* RID_COMPLEX */ TYPESPEC,
- /* RID_THREAD */ SCSPEC,
-
- /* C++ */
- /* RID_FRIEND */ SCSPEC,
- /* RID_VIRTUAL */ SCSPEC,
- /* RID_EXPLICIT */ SCSPEC,
- /* RID_EXPORT */ EXPORT,
- /* RID_MUTABLE */ SCSPEC,
-
- /* ObjC */
- /* RID_IN */ 0,
- /* RID_OUT */ 0,
- /* RID_INOUT */ 0,
- /* RID_BYCOPY */ 0,
- /* RID_BYREF */ 0,
- /* RID_ONEWAY */ 0,
-
- /* C */
- /* RID_INT */ TYPESPEC,
- /* RID_CHAR */ TYPESPEC,
- /* RID_FLOAT */ TYPESPEC,
- /* RID_DOUBLE */ TYPESPEC,
- /* RID_VOID */ TYPESPEC,
- /* RID_ENUM */ ENUM,
- /* RID_STRUCT */ AGGR,
- /* RID_UNION */ AGGR,
- /* RID_IF */ IF,
- /* RID_ELSE */ ELSE,
- /* RID_WHILE */ WHILE,
- /* RID_DO */ DO,
- /* RID_FOR */ FOR,
- /* RID_SWITCH */ SWITCH,
- /* RID_CASE */ CASE,
- /* RID_DEFAULT */ DEFAULT,
- /* RID_BREAK */ BREAK,
- /* RID_CONTINUE */ CONTINUE,
- /* RID_RETURN */ RETURN_KEYWORD,
- /* RID_GOTO */ GOTO,
- /* RID_SIZEOF */ SIZEOF,
-
- /* C extensions */
- /* RID_ASM */ ASM_KEYWORD,
- /* RID_TYPEOF */ TYPEOF,
- /* RID_ALIGNOF */ ALIGNOF,
- /* RID_ATTRIBUTE */ ATTRIBUTE,
- /* RID_VA_ARG */ VA_ARG,
- /* RID_EXTENSION */ EXTENSION,
- /* RID_IMAGPART */ IMAGPART,
- /* RID_REALPART */ REALPART,
- /* RID_LABEL */ LABEL,
- /* RID_PTRBASE */ 0,
- /* RID_PTREXTENT */ 0,
- /* RID_PTRVALUE */ 0,
- /* RID_CHOOSE_EXPR */ 0,
- /* RID_TYPES_COMPATIBLE_P */ 0,
-
- /* RID_FUNCTION_NAME */ VAR_FUNC_NAME,
- /* RID_PRETTY_FUNCTION_NAME */ VAR_FUNC_NAME,
- /* RID_c99_FUNCTION_NAME */ VAR_FUNC_NAME,
-
- /* C++ */
- /* RID_BOOL */ TYPESPEC,
- /* RID_WCHAR */ TYPESPEC,
- /* RID_CLASS */ AGGR,
- /* RID_PUBLIC */ VISSPEC,
- /* RID_PRIVATE */ VISSPEC,
- /* RID_PROTECTED */ VISSPEC,
- /* RID_TEMPLATE */ TEMPLATE,
- /* RID_NULL */ CONSTANT,
- /* RID_CATCH */ CATCH,
- /* RID_DELETE */ DELETE,
- /* RID_FALSE */ CXX_FALSE,
- /* RID_NAMESPACE */ NAMESPACE,
- /* RID_NEW */ NEW,
- /* RID_OPERATOR */ OPERATOR,
- /* RID_THIS */ THIS,
- /* RID_THROW */ THROW,
- /* RID_TRUE */ CXX_TRUE,
- /* RID_TRY */ TRY,
- /* RID_TYPENAME */ TYPENAME_KEYWORD,
- /* RID_TYPEID */ TYPEID,
- /* RID_USING */ USING,
-
- /* casts */
- /* RID_CONSTCAST */ CONST_CAST,
- /* RID_DYNCAST */ DYNAMIC_CAST,
- /* RID_REINTCAST */ REINTERPRET_CAST,
- /* RID_STATCAST */ STATIC_CAST,
-
- /* Objective-C */
- /* RID_ID */ 0,
- /* RID_AT_ENCODE */ 0,
- /* RID_AT_END */ 0,
- /* RID_AT_CLASS */ 0,
- /* RID_AT_ALIAS */ 0,
- /* RID_AT_DEFS */ 0,
- /* RID_AT_PRIVATE */ 0,
- /* RID_AT_PROTECTED */ 0,
- /* RID_AT_PUBLIC */ 0,
- /* RID_AT_PROTOCOL */ 0,
- /* RID_AT_SELECTOR */ 0,
- /* RID_AT_INTERFACE */ 0,
- /* RID_AT_IMPLEMENTATION */ 0
-};
-
void
-init_reswords ()
+init_reswords (void)
{
unsigned int i;
tree id;
int mask = ((flag_no_asm ? D_ASM : 0)
| (flag_no_gnu_keywords ? D_EXT : 0));
- /* It is not necessary to register ridpointers as a GC root, because
- all the trees it points to are permanently interned in the
- get_identifier hash anyway. */
- ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree));
+ ridpointers = ggc_calloc ((int) RID_MAX, sizeof (tree));
for (i = 0; i < ARRAY_SIZE (reswords); i++)
{
id = get_identifier (reswords[i].word);
@@ -580,34 +366,37 @@ init_reswords ()
}
static void
-init_cp_pragma ()
+init_cp_pragma (void)
{
- cpp_register_pragma (parse_in, 0, "vtable", handle_pragma_vtable);
- cpp_register_pragma (parse_in, 0, "unit", handle_pragma_unit);
-
- cpp_register_pragma (parse_in, 0, "interface", handle_pragma_interface);
- cpp_register_pragma (parse_in, 0, "implementation",
- handle_pragma_implementation);
-
- cpp_register_pragma (parse_in, "GCC", "interface", handle_pragma_interface);
- cpp_register_pragma (parse_in, "GCC", "implementation",
- handle_pragma_implementation);
- cpp_register_pragma (parse_in, "GCC", "java_exceptions",
- handle_pragma_java_exceptions);
+ c_register_pragma (0, "vtable", handle_pragma_vtable);
+ c_register_pragma (0, "unit", handle_pragma_unit);
+ c_register_pragma (0, "interface", handle_pragma_interface);
+ c_register_pragma (0, "implementation", handle_pragma_implementation);
+ c_register_pragma ("GCC", "interface", handle_pragma_interface);
+ c_register_pragma ("GCC", "implementation", handle_pragma_implementation);
+ c_register_pragma ("GCC", "java_exceptions", handle_pragma_java_exceptions);
}
-
+
/* Initialize the C++ front end. This function is very sensitive to
the exact order that things are done here. It would be nice if the
initialization done by this routine were moved to its subroutines,
and the ordering dependencies clarified and reduced. */
-const char *
-cxx_init (filename)
- const char *filename;
+bool
+cxx_init (void)
{
- input_filename = "<internal>";
+ static const enum tree_code stmt_codes[] = {
+ c_common_stmt_codes,
+ cp_stmt_codes
+ };
+
+ INIT_STATEMENT_CODES (stmt_codes);
+
+ /* We cannot just assign to input_filename because it has already
+ been initialized and will be used later as an N_BINCL for stabs+
+ debugging. */
+ push_srcloc ("<internal>", 0);
init_reswords ();
- init_spew ();
init_tree ();
init_cp_semantics ();
init_operators ();
@@ -616,21 +405,7 @@ cxx_init (filename)
current_function_decl = NULL;
- class_type_node = build_int_2 (class_type, 0);
- TREE_TYPE (class_type_node) = class_type_node;
- ridpointers[(int) RID_CLASS] = class_type_node;
-
- record_type_node = build_int_2 (record_type, 0);
- TREE_TYPE (record_type_node) = record_type_node;
- ridpointers[(int) RID_STRUCT] = record_type_node;
-
- union_type_node = build_int_2 (union_type, 0);
- TREE_TYPE (union_type_node) = union_type_node;
- ridpointers[(int) RID_UNION] = union_type_node;
-
- enum_type_node = build_int_2 (enum_type, 0);
- TREE_TYPE (enum_type_node) = enum_type_node;
- ridpointers[(int) RID_ENUM] = enum_type_node;
+ class_type_node = ridpointers[(int) RID_CLASS];
cxx_init_decl_processing ();
@@ -639,193 +414,31 @@ cxx_init (filename)
TREE_TYPE (null_node) = c_common_type_for_size (POINTER_SIZE, 0);
ridpointers[RID_NULL] = null_node;
- token_count = init_cpp_parse ();
interface_unknown = 1;
- filename = c_common_init (filename);
- if (filename == NULL)
- return NULL;
-
- init_cp_pragma ();
-
- init_repo (filename);
-
- return filename;
-}
-
-inline void
-yyprint (file, yychar, yylval)
- FILE *file;
- int yychar;
- YYSTYPE yylval;
-{
- tree t;
- switch (yychar)
+ if (c_common_init () == false)
{
- case IDENTIFIER:
- case tTYPENAME:
- case TYPESPEC:
- case PTYPENAME:
- case PFUNCNAME:
- case IDENTIFIER_DEFN:
- case TYPENAME_DEFN:
- case PTYPENAME_DEFN:
- case SCSPEC:
- case PRE_PARSED_CLASS_DECL:
- t = yylval.ttype;
- if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == TEMPLATE_DECL)
- {
- fprintf (file, " `%s'", IDENTIFIER_POINTER (DECL_NAME (t)));
- break;
- }
- my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224);
- if (IDENTIFIER_POINTER (t))
- fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
- break;
-
- case AGGR:
- if (yylval.ttype == class_type_node)
- fprintf (file, " `class'");
- else if (yylval.ttype == record_type_node)
- fprintf (file, " `struct'");
- else if (yylval.ttype == union_type_node)
- fprintf (file, " `union'");
- else if (yylval.ttype == enum_type_node)
- fprintf (file, " `enum'");
- else
- abort ();
- break;
-
- case CONSTANT:
- t = yylval.ttype;
- if (TREE_CODE (t) == INTEGER_CST)
- fprintf (file,
-#if HOST_BITS_PER_WIDE_INT == 64
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
- " 0x%x%016x",
-#else
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
- " 0x%lx%016lx",
-#else
- " 0x%llx%016llx",
-#endif
-#endif
-#else
-#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
- " 0x%lx%08lx",
-#else
- " 0x%x%08x",
-#endif
-#endif
- TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t));
- break;
+ pop_srcloc();
+ return false;
}
-}
-
-#if defined(GATHER_STATISTICS) && defined(REDUCE_LENGTH)
-static int *reduce_count;
-#endif
-
-int *token_count;
-
-#if 0
-#define REDUCE_LENGTH ARRAY_SIZE (yyr2)
-#define TOKEN_LENGTH (256 + ARRAY_SIZE (yytname))
-#endif
-
-#ifdef GATHER_STATISTICS
-#ifdef REDUCE_LENGTH
-void
-yyhook (yyn)
- int yyn;
-{
- reduce_count[yyn] += 1;
-}
-
-static int
-reduce_cmp (p, q)
- int *p, *q;
-{
- return reduce_count[*q] - reduce_count[*p];
-}
-static int
-token_cmp (p, q)
- int *p, *q;
-{
- return token_count[*q] - token_count[*p];
-}
-#endif
-#endif
-
-void
-print_parse_statistics ()
-{
-#ifdef GATHER_STATISTICS
-#ifdef REDUCE_LENGTH
-#if YYDEBUG != 0
- int i;
- int maxlen = REDUCE_LENGTH;
- unsigned *sorted;
-
- if (reduce_count[-1] == 0)
- return;
+ init_cp_pragma ();
- if (TOKEN_LENGTH > REDUCE_LENGTH)
- maxlen = TOKEN_LENGTH;
- sorted = (unsigned *) alloca (sizeof (int) * maxlen);
+ init_repo (main_input_filename);
- for (i = 0; i < TOKEN_LENGTH; i++)
- sorted[i] = i;
- qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp);
- for (i = 0; i < TOKEN_LENGTH; i++)
- {
- int idx = sorted[i];
- if (token_count[idx] == 0)
- break;
- if (token_count[idx] < token_count[-1])
- break;
- fprintf (stderr, "token %d, `%s', count = %d\n",
- idx, yytname[YYTRANSLATE (idx)], token_count[idx]);
- }
- fprintf (stderr, "\n");
- for (i = 0; i < REDUCE_LENGTH; i++)
- sorted[i] = i;
- qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp);
- for (i = 0; i < REDUCE_LENGTH; i++)
- {
- int idx = sorted[i];
- if (reduce_count[idx] == 0)
- break;
- if (reduce_count[idx] < reduce_count[-1])
- break;
- fprintf (stderr, "rule %d, line %d, count = %d\n",
- idx, yyrline[idx], reduce_count[idx]);
- }
- fprintf (stderr, "\n");
-#endif
-#endif
-#endif
+ pop_srcloc();
+ return true;
}
-
+
/* Helper function to load global variables with interface
information. */
void
-extract_interface_info ()
+extract_interface_info (void)
{
- struct c_fileinfo *finfo = 0;
-
- if (flag_alt_external_templates)
- {
- tree til = tinst_for_decl ();
-
- if (til)
- finfo = get_fileinfo (TINST_FILE (til));
- }
- if (!finfo)
- finfo = get_fileinfo (input_filename);
+ struct c_fileinfo *finfo;
+ finfo = get_fileinfo (input_filename);
interface_only = finfo->interface_only;
interface_unknown = finfo->interface_unknown;
}
@@ -834,8 +447,7 @@ extract_interface_info ()
INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */
static int
-interface_strcmp (s)
- const char *s;
+interface_strcmp (const char* s)
{
/* Set the interface/implementation bits for this scope. */
struct impl_files *ifiles;
@@ -871,68 +483,12 @@ interface_strcmp (s)
return 1;
}
-/* Heuristic to tell whether the user is missing a semicolon
- after a struct or enum declaration. Emit an error message
- if we know the user has blown it. */
-
-void
-check_for_missing_semicolon (type)
- tree type;
-{
- if (yychar < 0)
- yychar = yylex ();
-
- if ((yychar > 255
- && yychar != SCSPEC
- && yychar != IDENTIFIER
- && yychar != tTYPENAME
- && yychar != CV_QUALIFIER
- && yychar != SELFNAME)
- || yychar == 0 /* EOF */)
- {
- if (TYPE_ANONYMOUS_P (type))
- error ("semicolon missing after %s declaration",
- TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
- else
- error ("semicolon missing after declaration of `%T'", type);
- shadow_tag (build_tree_list (0, type));
- }
- /* Could probably also hack cases where class { ... } f (); appears. */
- clear_anon_tags ();
-}
-
-void
-note_got_semicolon (type)
- tree type;
-{
- if (!TYPE_P (type))
- abort ();
- if (CLASS_TYPE_P (type))
- CLASSTYPE_GOT_SEMICOLON (type) = 1;
-}
-
-void
-note_list_got_semicolon (declspecs)
- tree declspecs;
-{
- tree link;
-
- for (link = declspecs; link; link = TREE_CHAIN (link))
- {
- tree type = TREE_VALUE (link);
- if (type && TYPE_P (type))
- note_got_semicolon (type);
- }
- clear_anon_tags ();
-}
/* Parse a #pragma whose sole argument is a string constant.
If OPT is true, the argument is optional. */
static tree
-parse_strconst_pragma (name, opt)
- const char *name;
- int opt;
+parse_strconst_pragma (const char* name, int opt)
{
tree result, x;
enum cpp_ttype t;
@@ -954,24 +510,21 @@ parse_strconst_pragma (name, opt)
}
static void
-handle_pragma_vtable (dfile)
- cpp_reader *dfile ATTRIBUTE_UNUSED;
+handle_pragma_vtable (cpp_reader* dfile ATTRIBUTE_UNUSED )
{
parse_strconst_pragma ("vtable", 0);
sorry ("#pragma vtable no longer supported");
}
static void
-handle_pragma_unit (dfile)
- cpp_reader *dfile ATTRIBUTE_UNUSED;
+handle_pragma_unit (cpp_reader* dfile ATTRIBUTE_UNUSED )
{
/* Validate syntax, but don't do anything. */
parse_strconst_pragma ("unit", 0);
}
static void
-handle_pragma_interface (dfile)
- cpp_reader *dfile ATTRIBUTE_UNUSED;
+handle_pragma_interface (cpp_reader* dfile ATTRIBUTE_UNUSED )
{
tree fname = parse_strconst_pragma ("interface", 1);
struct c_fileinfo *finfo;
@@ -1013,8 +566,7 @@ handle_pragma_interface (dfile)
a matching #p interface for this to have any effect. */
static void
-handle_pragma_implementation (dfile)
- cpp_reader *dfile ATTRIBUTE_UNUSED;
+handle_pragma_implementation (cpp_reader* dfile ATTRIBUTE_UNUSED )
{
tree fname = parse_strconst_pragma ("implementation", 1);
const char *main_filename;
@@ -1046,7 +598,7 @@ handle_pragma_implementation (dfile)
}
if (ifiles == 0)
{
- ifiles = (struct impl_files*) xmalloc (sizeof (struct impl_files));
+ ifiles = xmalloc (sizeof (struct impl_files));
ifiles->filename = main_filename;
ifiles->next = impl_file_chain;
impl_file_chain = ifiles;
@@ -1055,8 +607,7 @@ handle_pragma_implementation (dfile)
/* Indicate that this file uses Java-personality exception handling. */
static void
-handle_pragma_java_exceptions (dfile)
- cpp_reader *dfile ATTRIBUTE_UNUSED;
+handle_pragma_java_exceptions (cpp_reader* dfile ATTRIBUTE_UNUSED )
{
tree x;
if (c_lex (&x) != CPP_EOF)
@@ -1065,40 +616,10 @@ handle_pragma_java_exceptions (dfile)
choose_personality_routine (lang_java);
}
-void
-do_pending_lang_change ()
-{
- for (; pending_lang_change > 0; --pending_lang_change)
- push_lang_context (lang_name_c);
- for (; pending_lang_change < 0; ++pending_lang_change)
- pop_lang_context ();
-}
-
-/* Return true if d is in a global scope. */
-
-static int
-is_global (d)
- tree d;
-{
- while (1)
- switch (TREE_CODE (d))
- {
- case ERROR_MARK:
- return 1;
-
- case OVERLOAD: d = OVL_FUNCTION (d); continue;
- case TREE_LIST: d = TREE_VALUE (d); continue;
- default:
- my_friendly_assert (DECL_P (d), 980629);
-
- return DECL_NAMESPACE_SCOPE_P (d);
- }
-}
-
/* Issue an error message indicating that the lookup of NAME (an
- IDENTIFIER_NODE) failed. */
+ IDENTIFIER_NODE) failed. Returns the ERROR_MARK_NODE. */
-void
+tree
unqualified_name_lookup_error (tree name)
{
if (IDENTIFIER_OPNAME_P (name))
@@ -1127,218 +648,52 @@ unqualified_name_lookup_error (tree name)
SET_IDENTIFIER_NAMESPACE_VALUE (name, error_mark_node);
SET_IDENTIFIER_ERROR_LOCUS (name, current_function_decl);
}
-}
-
-tree
-do_identifier (token, parsing, args)
- register tree token;
- int parsing;
- tree args;
-{
- register tree id;
- int lexing = (parsing == 1 || parsing == 3);
-
- timevar_push (TV_NAME_LOOKUP);
- if (! lexing)
- id = lookup_name (token, 0);
- else
- id = lastiddecl;
-
- if (lexing && id && TREE_DEPRECATED (id))
- warn_deprecated_use (id);
-
- /* Do Koenig lookup if appropriate (inside templates we build lookup
- expressions instead).
-
- [basic.lookup.koenig]: If the ordinary unqualified lookup of the name
- finds the declaration of a class member function, the associated
- namespaces and classes are not considered. */
-
- if (args && !current_template_parms && (!id || is_global (id)))
- id = lookup_arg_dependent (token, id, args);
-
- /* Remember that this name has been used in the class definition, as per
- [class.scope0] */
- if (id && parsing && parsing != 3)
- maybe_note_name_used_in_class (token, id);
-
- if (id == error_mark_node)
- {
- /* lookup_name quietly returns error_mark_node if we're parsing,
- as we don't want to complain about an identifier that ends up
- being used as a declarator. So we call it again to get the error
- message. */
- id = lookup_name (token, 0);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- }
- if (!id || (TREE_CODE (id) == FUNCTION_DECL
- && DECL_ANTICIPATED (id)))
- {
- if (current_template_parms)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
- build_min_nt (LOOKUP_EXPR, token));
- else if (IDENTIFIER_TYPENAME_P (token))
- /* A templated conversion operator might exist. */
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, token);
- else
- {
- unqualified_name_lookup_error (token);
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
- }
- }
-
- id = check_for_out_of_scope_variable (id);
-
- /* TREE_USED is set in `hack_identifier'. */
- if (TREE_CODE (id) == CONST_DECL)
- {
- /* Check access. */
- if (IDENTIFIER_CLASS_VALUE (token) == id)
- enforce_access (CP_DECL_CONTEXT(id), id);
- if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
- id = DECL_INITIAL (id);
- }
- else
- id = hack_identifier (id, token);
-
- /* We must look up dependent names when the template is
- instantiated, not while parsing it. For now, we don't
- distinguish between dependent and independent names. So, for
- example, we look up all overloaded functions at
- instantiation-time, even though in some cases we should just use
- the DECL we have here. We also use LOOKUP_EXPRs to find things
- like local variables, rather than creating TEMPLATE_DECLs for the
- local variables and then finding matching instantiations. */
- if (current_template_parms
- && (is_overloaded_fn (id)
- || (TREE_CODE (id) == VAR_DECL
- && CP_DECL_CONTEXT (id)
- && TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL)
- || TREE_CODE (id) == PARM_DECL
- || TREE_CODE (id) == RESULT_DECL
- || TREE_CODE (id) == USING_DECL))
- id = build_min_nt (LOOKUP_EXPR, token);
-
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, id);
+ return error_mark_node;
}
+/* Like unqualified_name_lookup_error, but NAME is an unqualified-id
+ used as a function. Returns an appropriate expression for
+ NAME. */
+
tree
-do_scoped_id (token, id)
- tree token;
- tree id;
+unqualified_fn_lookup_error (tree name)
{
- timevar_push (TV_NAME_LOOKUP);
- if (!id || (TREE_CODE (id) == FUNCTION_DECL
- && DECL_ANTICIPATED (id)))
- {
- if (processing_template_decl)
- {
- id = build_min_nt (LOOKUP_EXPR, token);
- LOOKUP_EXPR_GLOBAL (id) = 1;
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, id);
- }
- if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node)
- error ("`::%D' undeclared (first use here)", token);
- id = error_mark_node;
- /* Prevent repeated error messages. */
- SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
- }
- else
- {
- if (TREE_CODE (id) == ADDR_EXPR)
- mark_used (TREE_OPERAND (id, 0));
- else if (TREE_CODE (id) != OVERLOAD)
- mark_used (id);
- }
- if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
- {
- /* XXX CHS - should we set TREE_USED of the constant? */
- id = DECL_INITIAL (id);
- /* This is to prevent an enum whose value is 0
- from being considered a null pointer constant. */
- id = build1 (NOP_EXPR, TREE_TYPE (id), id);
- TREE_CONSTANT (id) = 1;
- }
-
if (processing_template_decl)
{
- if (is_overloaded_fn (id))
+ /* In a template, it is invalid to write "f()" or "f(3)" if no
+ declaration of "f" is available. Historically, G++ and most
+ other compilers accepted that usage since they deferred all name
+ lookup until instantiation time rather than doing unqualified
+ name lookup at template definition time; explain to the user what
+ is going wrong.
+
+ Note that we have the exact wording of the following message in
+ the manual (trouble.texi, node "Name lookup"), so they need to
+ be kept in synch. */
+ pedwarn ("there are no arguments to `%D' that depend on a template "
+ "parameter, so a declaration of `%D' must be available",
+ name, name);
+
+ if (!flag_permissive)
{
- id = build_min_nt (LOOKUP_EXPR, token);
- LOOKUP_EXPR_GLOBAL (id) = 1;
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, id);
+ static bool hint;
+ if (!hint)
+ {
+ error ("(if you use `-fpermissive', G++ will accept your code, "
+ "but allowing the use of an undeclared name is "
+ "deprecated)");
+ hint = true;
+ }
}
- /* else just use the decl */
- }
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, convert_from_reference (id));
-}
-
-tree
-identifier_typedecl_value (node)
- tree node;
-{
- tree t, type;
- type = IDENTIFIER_TYPE_VALUE (node);
- if (type == NULL_TREE)
- return NULL_TREE;
-
- if (IDENTIFIER_BINDING (node))
- {
- t = IDENTIFIER_VALUE (node);
- if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
- return t;
- }
- if (IDENTIFIER_NAMESPACE_VALUE (node))
- {
- t = IDENTIFIER_NAMESPACE_VALUE (node);
- if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
- return t;
+ return name;
}
- /* Will this one ever happen? */
- if (TYPE_MAIN_DECL (type))
- return TYPE_MAIN_DECL (type);
-
- /* We used to do an internal error of 62 here, but instead we will
- handle the return of a null appropriately in the callers. */
- return NULL_TREE;
+ return unqualified_name_lookup_error (name);
}
-#ifdef GATHER_STATISTICS
-/* The original for tree_node_kind is in the toplevel tree.c; changes there
- need to be brought into here, unless this were actually put into a header
- instead. */
-/* Statistics-gathering stuff. */
-typedef enum
-{
- d_kind,
- t_kind,
- b_kind,
- s_kind,
- r_kind,
- e_kind,
- c_kind,
- id_kind,
- op_id_kind,
- perm_list_kind,
- temp_list_kind,
- vec_kind,
- x_kind,
- lang_decl,
- lang_type,
- all_kinds
-} tree_node_kind;
-
-extern int tree_node_counts[];
-extern int tree_node_sizes[];
-#endif
-
tree
-build_lang_decl (code, name, type)
- enum tree_code code;
- tree name;
- tree type;
+build_lang_decl (enum tree_code code, tree name, tree type)
{
tree t;
@@ -1352,8 +707,7 @@ build_lang_decl (code, name, type)
and pushdecl (for functions generated by the backend). */
void
-retrofit_lang_decl (t)
- tree t;
+retrofit_lang_decl (tree t)
{
struct lang_decl *ld;
size_t size;
@@ -1363,7 +717,7 @@ retrofit_lang_decl (t)
else
size = sizeof (struct lang_decl_flags);
- ld = (struct lang_decl *) ggc_alloc_cleared (size);
+ ld = ggc_alloc_cleared (size);
ld->decl_flags.can_be_full = CAN_HAVE_FULL_LANG_DECL_P (t) ? 1 : 0;
ld->decl_flags.u1sel = TREE_CODE (t) == NAMESPACE_DECL ? 1 : 0;
@@ -1372,7 +726,8 @@ retrofit_lang_decl (t)
ld->u.f.u3sel = TREE_CODE (t) == FUNCTION_DECL ? 1 : 0;
DECL_LANG_SPECIFIC (t) = ld;
- if (current_lang_name == lang_name_cplusplus)
+ if (current_lang_name == lang_name_cplusplus
+ || decl_linkage (t) == lk_none)
SET_DECL_LANGUAGE (t, lang_cplusplus);
else if (current_lang_name == lang_name_c)
SET_DECL_LANGUAGE (t, lang_c);
@@ -1387,8 +742,7 @@ retrofit_lang_decl (t)
}
void
-cxx_dup_lang_specific_decl (node)
- tree node;
+cxx_dup_lang_specific_decl (tree node)
{
int size;
struct lang_decl *ld;
@@ -1400,7 +754,7 @@ cxx_dup_lang_specific_decl (node)
size = sizeof (struct lang_decl_flags);
else
size = sizeof (struct lang_decl);
- ld = (struct lang_decl *) ggc_alloc (size);
+ ld = ggc_alloc (size);
memcpy (ld, DECL_LANG_SPECIFIC (node), size);
DECL_LANG_SPECIFIC (node) = ld;
@@ -1413,8 +767,7 @@ cxx_dup_lang_specific_decl (node)
/* Copy DECL, including any language-specific parts. */
tree
-copy_decl (decl)
- tree decl;
+copy_decl (tree decl)
{
tree copy;
@@ -1426,8 +779,7 @@ copy_decl (decl)
/* Replace the shared language-specific parts of NODE with a new copy. */
static void
-copy_lang_type (node)
- tree node;
+copy_lang_type (tree node)
{
int size;
struct lang_type *lt;
@@ -1439,7 +791,7 @@ copy_lang_type (node)
size = sizeof (struct lang_type);
else
size = sizeof (struct lang_type_ptrmem);
- lt = (struct lang_type *) ggc_alloc (size);
+ lt = ggc_alloc (size);
memcpy (lt, TYPE_LANG_SPECIFIC (node), size);
TYPE_LANG_SPECIFIC (node) = lt;
@@ -1452,8 +804,7 @@ copy_lang_type (node)
/* Copy TYPE, including any language-specific parts. */
tree
-copy_type (type)
- tree type;
+copy_type (tree type)
{
tree copy;
@@ -1463,10 +814,9 @@ copy_type (type)
}
tree
-cxx_make_type (code)
- enum tree_code code;
+cxx_make_type (enum tree_code code)
{
- register tree t = make_node (code);
+ tree t = make_node (code);
/* Create lang_type structure. */
if (IS_AGGR_TYPE_CODE (code)
@@ -1474,8 +824,7 @@ cxx_make_type (code)
{
struct lang_type *pi;
- pi = ((struct lang_type *)
- ggc_alloc_cleared (sizeof (struct lang_type)));
+ pi = ggc_alloc_cleared (sizeof (struct lang_type));
TYPE_LANG_SPECIFIC (t) = pi;
pi->u.c.h.is_lang_type_class = 1;
@@ -1516,8 +865,7 @@ cxx_make_type (code)
}
tree
-make_aggr_type (code)
- enum tree_code code;
+make_aggr_type (enum tree_code code)
{
tree t = cxx_make_type (code);
@@ -1531,8 +879,7 @@ make_aggr_type (code)
RID. */
int
-cp_type_qual_from_rid (rid)
- tree rid;
+cp_type_qual_from_rid (tree rid)
{
if (rid == ridpointers[(int) RID_CONST])
return TYPE_QUAL_CONST;
diff --git a/contrib/gcc/cp/lex.h b/contrib/gcc/cp/lex.h
index 15de16866b72..35c3503ea417 100644
--- a/contrib/gcc/cp/lex.h
+++ b/contrib/gcc/cp/lex.h
@@ -1,25 +1,26 @@
-/* Define constants and variables for communication with parse.y.
+/* Define constants and variables for communication with the parser.
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 2000 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
and by Brendan Kehoe (brendan@cygnus.com).
-This file is part of GNU CC.
+ This file is part of GCC.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY. No author or distributor
-accepts responsibility to anyone for the consequences of using it
-or for whether it serves any particular purpose or works at all,
-unless he says so in writing. Refer to the GNU CC General Public
-License for full details.
+ 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 2, 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 COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
-Everyone is granted permission to copy, modify and redistribute
-GNU CC, but only under the conditions described in the
-GNU CC General Public License. A copy of this license is
-supposed to have been given to you along with GNU CC so you
-can know your rights and responsibilities. It should be in a
-file named COPYING. Among other things, the copyright notice
-and this notice must be preserved on all copies. */
#ifndef GCC_CP_LEX_H
#define GCC_CP_LEX_H
@@ -64,24 +65,4 @@ typedef unsigned long RID_BIT_TYPE; /* assumed at least 32 bits */
#define RIDBIT_RESET_ALL(V) do { (V) = 0; } while (0)
#endif
-/* the declaration found for the last IDENTIFIER token read in.
- yylex must look this up to detect typedefs, which get token type TYPENAME,
- so it is left around in case the identifier is not a typedef but is
- used in a context which makes it a reference to a variable. */
-extern GTY(()) tree lastiddecl;
-
-/* Back-door communication channel to the lexer. */
-extern int looking_for_typename;
-extern int looking_for_template;
-
-/* Tell the lexer where to look for names. */
-extern GTY(()) tree got_scope;
-extern GTY(()) tree got_object;
-
-/* Pending language change.
- Positive is push count, negative is pop count. */
-extern int pending_lang_change;
-
-extern int yylex PARAMS ((void));
-
#endif /* ! GCC_CP_LEX_H */
diff --git a/contrib/gcc/cp/mangle.c b/contrib/gcc/cp/mangle.c
index 718064834a14..760d8b348dd7 100644
--- a/contrib/gcc/cp/mangle.c
+++ b/contrib/gcc/cp/mangle.c
@@ -1,21 +1,21 @@
/* Name mangling for the 3.0 C++ ABI.
- Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Written by Alex Samuel <sameul@codesourcery.com>
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify it
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful, but
+ 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 GNU CC; see the file COPYING. If not, write to the Free
+ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
@@ -49,6 +49,8 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "tm_p.h"
#include "cp-tree.h"
@@ -56,7 +58,7 @@
#include "obstack.h"
#include "toplev.h"
#include "varray.h"
-#include "ggc.h"
+#include "flags.h"
/* Debugging support. */
@@ -122,7 +124,7 @@ substitution_identifier_index_t;
/* For quick substitution checks, look up these common identifiers
once only. */
-static tree subst_identifiers[SUBID_MAX];
+static GTY(()) tree subst_identifiers[SUBID_MAX];
/* Single-letter codes for builtin integer types, defined in
<builtin-type>. These are indexed by integer_type_kind values. */
@@ -142,70 +144,74 @@ integer_type_codes[itk_none] =
'y' /* itk_unsigned_long_long */
};
-static int decl_is_template_id PARAMS ((tree, tree*));
+static int decl_is_template_id (const tree, tree* const);
/* Functions for handling substitutions. */
-static inline tree canonicalize_for_substitution PARAMS ((tree));
-static void add_substitution PARAMS ((tree));
-static inline int is_std_substitution PARAMS ((tree, substitution_identifier_index_t));
-static inline int is_std_substitution_char PARAMS ((tree, substitution_identifier_index_t));
-static int find_substitution PARAMS ((tree));
+static inline tree canonicalize_for_substitution (tree);
+static void add_substitution (tree);
+static inline int is_std_substitution (const tree,
+ const substitution_identifier_index_t);
+static inline int is_std_substitution_char (const tree,
+ const substitution_identifier_index_t);
+static int find_substitution (tree);
+static void mangle_call_offset (const tree, const tree);
/* Functions for emitting mangled representations of things. */
-static void write_mangled_name PARAMS ((tree));
-static void write_encoding PARAMS ((tree));
-static void write_name PARAMS ((tree, int));
-static void write_unscoped_name PARAMS ((tree));
-static void write_unscoped_template_name PARAMS ((tree));
-static void write_nested_name PARAMS ((tree));
-static void write_prefix PARAMS ((tree));
-static void write_template_prefix PARAMS ((tree));
-static void write_unqualified_name PARAMS ((tree));
-static void write_conversion_operator_name (tree);
-static void write_source_name PARAMS ((tree));
-static int hwint_to_ascii PARAMS ((unsigned HOST_WIDE_INT, unsigned int, char *, unsigned));
-static void write_number PARAMS ((unsigned HOST_WIDE_INT, int,
- unsigned int));
-static void write_integer_cst PARAMS ((tree));
-static void write_real_cst PARAMS ((tree));
-static void write_identifier PARAMS ((const char *));
-static void write_special_name_constructor PARAMS ((tree));
-static void write_special_name_destructor PARAMS ((tree));
-static void write_type PARAMS ((tree));
-static int write_CV_qualifiers_for_type PARAMS ((tree));
-static void write_builtin_type PARAMS ((tree));
-static void write_function_type PARAMS ((tree));
-static void write_bare_function_type PARAMS ((tree, int, tree));
-static void write_method_parms PARAMS ((tree, int, tree));
-static void write_class_enum_type PARAMS ((tree));
-static void write_template_args PARAMS ((tree));
-static void write_expression PARAMS ((tree));
-static void write_template_arg_literal PARAMS ((tree));
-static void write_template_arg PARAMS ((tree));
-static void write_template_template_arg PARAMS ((tree));
-static void write_array_type PARAMS ((tree));
-static void write_pointer_to_member_type PARAMS ((tree));
-static void write_template_param PARAMS ((tree));
-static void write_template_template_param PARAMS ((tree));
-static void write_substitution PARAMS ((int));
-static int discriminator_for_local_entity PARAMS ((tree));
-static int discriminator_for_string_literal PARAMS ((tree, tree));
-static void write_discriminator PARAMS ((int));
-static void write_local_name PARAMS ((tree, tree, tree));
-static void dump_substitution_candidates PARAMS ((void));
-static const char *mangle_decl_string PARAMS ((tree));
+static void write_mangled_name (const tree, bool);
+static void write_encoding (const tree);
+static void write_name (tree, const int);
+static void write_unscoped_name (const tree);
+static void write_unscoped_template_name (const tree);
+static void write_nested_name (const tree);
+static void write_prefix (const tree);
+static void write_template_prefix (const tree);
+static void write_unqualified_name (const tree);
+static void write_conversion_operator_name (const tree);
+static void write_source_name (tree);
+static int hwint_to_ascii (unsigned HOST_WIDE_INT, const unsigned int, char *,
+ const unsigned int);
+static void write_number (unsigned HOST_WIDE_INT, const int,
+ const unsigned int);
+static void write_integer_cst (const tree);
+static void write_real_cst (const tree);
+static void write_identifier (const char *);
+static void write_special_name_constructor (const tree);
+static void write_special_name_destructor (const tree);
+static void write_type (tree);
+static int write_CV_qualifiers_for_type (const tree);
+static void write_builtin_type (tree);
+static void write_function_type (const tree);
+static void write_bare_function_type (const tree, const int, const tree);
+static void write_method_parms (tree, const int, const tree);
+static void write_class_enum_type (const tree);
+static void write_template_args (tree);
+static void write_expression (tree);
+static void write_template_arg_literal (const tree);
+static void write_template_arg (tree);
+static void write_template_template_arg (const tree);
+static void write_array_type (const tree);
+static void write_pointer_to_member_type (const tree);
+static void write_template_param (const tree);
+static void write_template_template_param (const tree);
+static void write_substitution (const int);
+static int discriminator_for_local_entity (tree);
+static int discriminator_for_string_literal (tree, tree);
+static void write_discriminator (const int);
+static void write_local_name (const tree, const tree, const tree);
+static void dump_substitution_candidates (void);
+static const char *mangle_decl_string (const tree);
/* Control functions. */
-static inline void start_mangling (tree);
-static inline const char *finish_mangling (bool);
-static tree mangle_special_for_type PARAMS ((tree, const char *));
+static inline void start_mangling (const tree);
+static inline const char *finish_mangling (const bool);
+static tree mangle_special_for_type (const tree, const char *);
/* Foreign language functions. */
-static void write_java_integer_type_codes PARAMS ((tree));
+static void write_java_integer_type_codes (const tree);
/* Append a single character to the end of the mangled
representation. */
@@ -242,15 +248,13 @@ static void write_java_integer_type_codes PARAMS ((tree));
Otherwise return zero. */
static int
-decl_is_template_id (decl, template_info)
- tree decl;
- tree* template_info;
+decl_is_template_id (const tree decl, tree* const template_info)
{
if (TREE_CODE (decl) == TYPE_DECL)
{
/* TYPE_DECLs are handled specially. Look at its type to decide
if this is a template instantiation. */
- tree type = TREE_TYPE (decl);
+ const tree type = TREE_TYPE (decl);
if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_ID_P (type))
{
@@ -284,7 +288,7 @@ decl_is_template_id (decl, template_info)
/* Produce debugging output of current substitution candidates. */
static void
-dump_substitution_candidates ()
+dump_substitution_candidates (void)
{
unsigned i;
@@ -316,13 +320,12 @@ dump_substitution_candidates ()
/* Both decls and types can be substitution candidates, but sometimes
they refer to the same thing. For instance, a TYPE_DECL and
RECORD_TYPE for the same class refer to the same thing, and should
- be treated accordinginly in substitutions. This function returns a
+ be treated accordingly in substitutions. This function returns a
canonicalized tree node representing NODE that is used when adding
and substitution candidates and finding matches. */
static inline tree
-canonicalize_for_substitution (node)
- tree node;
+canonicalize_for_substitution (tree node)
{
/* For a TYPE_DECL, use the type instead. */
if (TREE_CODE (node) == TYPE_DECL)
@@ -337,8 +340,7 @@ canonicalize_for_substitution (node)
the list of candidates. */
static void
-add_substitution (node)
- tree node;
+add_substitution (tree node)
{
tree c;
@@ -359,7 +361,7 @@ add_substitution (node)
int i;
for (i = VARRAY_ACTIVE_SIZE (G.substitutions); --i >= 0; )
{
- tree candidate = VARRAY_TREE (G.substitutions, i);
+ const tree candidate = VARRAY_TREE (G.substitutions, i);
if ((DECL_P (node)
&& node == candidate)
|| (TYPE_P (node)
@@ -382,9 +384,8 @@ add_substitution (node)
name of substitution_index[INDEX] in the ::std namespace. */
static inline int
-is_std_substitution (node, index)
- tree node;
- substitution_identifier_index_t index;
+is_std_substitution (const tree node,
+ const substitution_identifier_index_t index)
{
tree type = NULL;
tree decl = NULL;
@@ -416,9 +417,8 @@ is_std_substitution (node, index)
substitution_index[INDEX]. */
static inline int
-is_std_substitution_char (node, index)
- tree node;
- substitution_identifier_index_t index;
+is_std_substitution_char (const tree node,
+ const substitution_identifier_index_t index)
{
tree args;
/* Check NODE's name is ::std::identifier. */
@@ -473,11 +473,10 @@ is_std_substitution_char (node, index)
return nonzero. If none is found, just return zero. */
static int
-find_substitution (node)
- tree node;
+find_substitution (tree node)
{
int i;
- int size = VARRAY_ACTIVE_SIZE (G.substitutions);
+ const int size = VARRAY_ACTIVE_SIZE (G.substitutions);
tree decl;
tree type;
@@ -548,6 +547,7 @@ find_substitution (node)
args <char, std::char_traits<char> > . */
tree args = CLASSTYPE_TI_ARGS (type);
if (TREE_VEC_LENGTH (args) == 2
+ && TYPE_P (TREE_VEC_ELT (args, 0))
&& same_type_p (TREE_VEC_ELT (args, 0), char_type_node)
&& is_std_substitution_char (TREE_VEC_ELT (args, 1),
SUBID_CHAR_TRAITS))
@@ -603,28 +603,66 @@ find_substitution (node)
}
-/* <mangled-name> ::= _Z <encoding> */
+/* TOP_LEVEL is true, if this is being called at outermost level of
+ mangling. It should be false when mangling a decl appearing in an
+ expression within some other mangling.
+
+ <mangled-name> ::= _Z <encoding> */
-static inline void
-write_mangled_name (decl)
- tree decl;
+static void
+write_mangled_name (const tree decl, bool top_level)
{
MANGLE_TRACE_TREE ("mangled-name", decl);
- if (DECL_LANG_SPECIFIC (decl)
- && DECL_EXTERN_C_FUNCTION_P (decl)
- && ! DECL_OVERLOADED_OPERATOR_P (decl))
- /* The standard notes:
- "The <encoding> of an extern "C" function is treated like
- global-scope data, i.e. as its <source-name> without a type."
- We cannot write overloaded operators that way though,
- because it contains characters invalid in assembler. */
- write_source_name (DECL_NAME (decl));
+ if (/* The names of `extern "C"' functions are not mangled. */
+ DECL_EXTERN_C_FUNCTION_P (decl)
+ /* But overloaded operator names *are* mangled. */
+ && !DECL_OVERLOADED_OPERATOR_P (decl))
+ {
+ unmangled_name:;
+
+ if (top_level)
+ write_string (IDENTIFIER_POINTER (DECL_NAME (decl)));
+ else
+ {
+ /* The standard notes: "The <encoding> of an extern "C"
+ function is treated like global-scope data, i.e. as its
+ <source-name> without a type." We cannot write
+ overloaded operators that way though, because it contains
+ characters invalid in assembler. */
+ if (abi_version_at_least (2))
+ write_string ("_Z");
+ else
+ G.need_abi_warning = true;
+ write_source_name (DECL_NAME (decl));
+ }
+ }
+ else if (TREE_CODE (decl) == VAR_DECL
+ /* The names of global variables aren't mangled. */
+ && (CP_DECL_CONTEXT (decl) == global_namespace
+ /* And neither are `extern "C"' variables. */
+ || DECL_EXTERN_C_P (decl)))
+ {
+ if (top_level || abi_version_at_least (2))
+ goto unmangled_name;
+ else
+ {
+ G.need_abi_warning = true;
+ goto mangled_name;
+ }
+ }
else
- /* C++ name; needs to be mangled. */
{
+ mangled_name:;
write_string ("_Z");
write_encoding (decl);
+ if (DECL_LANG_SPECIFIC (decl)
+ && (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)
+ || DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)))
+ /* We need a distinct mangled name for these entities, but
+ we should never actually output it. So, we append some
+ characters the assembler won't like. */
+ write_string (" *INTERNAL* ");
}
}
@@ -632,8 +670,7 @@ write_mangled_name (decl)
::= <data name> */
static void
-write_encoding (decl)
- tree decl;
+write_encoding (const tree decl)
{
MANGLE_TRACE_TREE ("encoding", decl);
@@ -652,18 +689,25 @@ write_encoding (decl)
if (TREE_CODE (decl) == FUNCTION_DECL)
{
tree fn_type;
+ tree d;
if (decl_is_template_id (decl, NULL))
- fn_type = get_mostly_instantiated_function_type (decl);
+ {
+ fn_type = get_mostly_instantiated_function_type (decl);
+ d = NULL_TREE;
+ }
else
- fn_type = TREE_TYPE (decl);
+ {
+ fn_type = TREE_TYPE (decl);
+ d = decl;
+ }
write_bare_function_type (fn_type,
(!DECL_CONSTRUCTOR_P (decl)
&& !DECL_DESTRUCTOR_P (decl)
&& !DECL_CONV_FN_P (decl)
&& decl_is_template_id (decl, NULL)),
- decl);
+ d);
}
}
@@ -679,9 +723,7 @@ write_encoding (decl)
production, to avoid an infinite recursion. */
static void
-write_name (decl, ignore_local_scope)
- tree decl;
- int ignore_local_scope;
+write_name (tree decl, const int ignore_local_scope)
{
tree context;
@@ -763,8 +805,7 @@ write_name (decl, ignore_local_scope)
::= St <unqualified-name> # ::std:: */
static void
-write_unscoped_name (decl)
- tree decl;
+write_unscoped_name (const tree decl)
{
tree context = CP_DECL_CONTEXT (decl);
@@ -790,8 +831,7 @@ write_unscoped_name (decl)
::= <substitution> */
static void
-write_unscoped_template_name (decl)
- tree decl;
+write_unscoped_template_name (const tree decl)
{
MANGLE_TRACE_TREE ("unscoped-template-name", decl);
@@ -809,8 +849,7 @@ write_unscoped_template_name (decl)
<CV-qualifiers> ::= [r] [V] [K] */
static void
-write_nested_name (decl)
- tree decl;
+write_nested_name (const tree decl)
{
tree template_info;
@@ -851,8 +890,7 @@ write_nested_name (decl)
::= <substitution> */
static void
-write_prefix (node)
- tree node;
+write_prefix (const tree node)
{
tree decl;
/* Non-NULL if NODE represents a template-id. */
@@ -917,8 +955,7 @@ write_prefix (node)
::= <substitution> */
static void
-write_template_prefix (node)
- tree node;
+write_template_prefix (const tree node)
{
tree decl = DECL_P (node) ? node : TYPE_NAME (node);
tree type = DECL_P (node) ? TREE_TYPE (node) : node;
@@ -993,8 +1030,7 @@ write_template_prefix (node)
::= <source-name> */
static void
-write_unqualified_name (decl)
- tree decl;
+write_unqualified_name (const tree decl)
{
MANGLE_TRACE_TREE ("unqualified-name", decl);
@@ -1002,6 +1038,8 @@ write_unqualified_name (decl)
write_special_name_constructor (decl);
else if (DECL_LANG_SPECIFIC (decl) != NULL && DECL_DESTRUCTOR_P (decl))
write_special_name_destructor (decl);
+ else if (DECL_NAME (decl) == NULL_TREE)
+ write_source_name (DECL_ASSEMBLER_NAME (decl));
else if (DECL_CONV_FN_P (decl))
{
/* Conversion operator. Handle it right here.
@@ -1033,19 +1071,18 @@ write_unqualified_name (decl)
/* Write the unqualified-name for a conversion operator to TYPE. */
static void
-write_conversion_operator_name (tree type)
+write_conversion_operator_name (const tree type)
{
write_string ("cv");
write_type (type);
}
-/* Non-termial <source-name>. IDENTIFIER is an IDENTIFIER_NODE.
+/* Non-terminal <source-name>. IDENTIFIER is an IDENTIFIER_NODE.
<source-name> ::= </length/ number> <identifier> */
static void
-write_source_name (identifier)
- tree identifier;
+write_source_name (tree identifier)
{
MANGLE_TRACE_TREE ("source-name", identifier);
@@ -1065,11 +1102,8 @@ write_source_name (identifier)
BUFFER points). */
static int
-hwint_to_ascii (number, base, buffer, min_digits)
- unsigned HOST_WIDE_INT number;
- unsigned int base;
- char *buffer;
- unsigned min_digits;
+hwint_to_ascii (unsigned HOST_WIDE_INT number, const unsigned int base,
+ char *buffer, const unsigned int min_digits)
{
static const char base_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
unsigned digits = 0;
@@ -1095,10 +1129,8 @@ hwint_to_ascii (number, base, buffer, min_digits)
<number> ::= [n] </decimal integer/> */
static void
-write_number (number, unsigned_p, base)
- unsigned HOST_WIDE_INT number;
- int unsigned_p;
- unsigned int base;
+write_number (unsigned HOST_WIDE_INT number, const int unsigned_p,
+ const unsigned int base)
{
char buffer[sizeof (HOST_WIDE_INT) * 8];
unsigned count = 0;
@@ -1117,8 +1149,7 @@ write_number (number, unsigned_p, base)
bigger than that, which we must deal with. */
static inline void
-write_integer_cst (cst)
- tree cst;
+write_integer_cst (const tree cst)
{
int sign = tree_int_cst_sgn (cst);
@@ -1161,7 +1192,7 @@ write_integer_cst (cst)
tree d = fold (build (FLOOR_DIV_EXPR, type, n, base));
tree tmp = fold (build (MULT_EXPR, type, d, base));
unsigned c;
-
+
done = integer_zerop (d);
tmp = fold (build (MINUS_EXPR, type, n, tmp));
c = hwint_to_ascii (TREE_INT_CST_LOW (tmp), 10, ptr,
@@ -1208,8 +1239,7 @@ write_integer_cst (cst)
Caller is responsible for the Lx and the E. */
static void
-write_real_cst (value)
- tree value;
+write_real_cst (const tree value)
{
if (abi_version_at_least (2))
{
@@ -1258,8 +1288,7 @@ write_real_cst (value)
<identifier> ::= </unqualified source code identifier> */
static void
-write_identifier (identifier)
- const char *identifier;
+write_identifier (const char *identifier)
{
MANGLE_TRACE ("identifier", identifier);
write_string (identifier);
@@ -1279,8 +1308,7 @@ write_identifier (identifier)
append *INTERNAL* to that, to make sure we never emit it. */
static void
-write_special_name_constructor (ctor)
- tree ctor;
+write_special_name_constructor (const tree ctor)
{
if (DECL_COMPLETE_CONSTRUCTOR_P (ctor)
/* Even though we don't ever emit a definition of the
@@ -1306,8 +1334,7 @@ write_special_name_constructor (ctor)
append *INTERNAL* to that, to make sure we never emit it. */
static void
-write_special_name_destructor (dtor)
- tree dtor;
+write_special_name_destructor (const tree dtor)
{
if (DECL_DELETING_DESTRUCTOR_P (dtor))
write_string ("D0");
@@ -1328,14 +1355,12 @@ write_special_name_destructor (dtor)
entities with the same name in the same FUNCTION. */
static int
-discriminator_for_local_entity (entity)
- tree entity;
+discriminator_for_local_entity (tree entity)
{
tree *type;
- int discriminator;
/* Assume this is the only local entity with this name. */
- discriminator = 0;
+ int discriminator = 0;
if (DECL_DISCRIMINATOR_P (entity) && DECL_LANG_SPECIFIC (entity))
discriminator = DECL_DISCRIMINATOR (entity);
@@ -1353,13 +1378,12 @@ discriminator_for_local_entity (entity)
}
/* Return the discriminator for STRING, a string literal used inside
- FUNCTION. The disciminator is the lexical ordinal of STRING among
+ FUNCTION. The discriminator is the lexical ordinal of STRING among
string literals used in FUNCTION. */
static int
-discriminator_for_string_literal (function, string)
- tree function ATTRIBUTE_UNUSED;
- tree string ATTRIBUTE_UNUSED;
+discriminator_for_string_literal (tree function ATTRIBUTE_UNUSED,
+ tree string ATTRIBUTE_UNUSED)
{
/* For now, we don't discriminate amongst string literals. */
return 0;
@@ -1372,8 +1396,7 @@ discriminator_for_string_literal (function, string)
n - 2, if this is the nth occurrence, in lexical order. */
static void
-write_discriminator (discriminator)
- int discriminator;
+write_discriminator (const int discriminator)
{
/* If discriminator is zero, don't write anything. Otherwise... */
if (discriminator > 0)
@@ -1393,10 +1416,8 @@ write_discriminator (discriminator)
:= Z <function encoding> E s [<discriminator>] */
static void
-write_local_name (function, local_entity, entity)
- tree function;
- tree local_entity;
- tree entity;
+write_local_name (const tree function, const tree local_entity,
+ const tree entity)
{
MANGLE_TRACE_TREE ("local-name", entity);
@@ -1438,8 +1459,7 @@ write_local_name (function, local_entity, entity)
TYPE is a type node. */
static void
-write_type (type)
- tree type;
+write_type (tree type)
{
/* This gets set to nonzero if TYPE turns out to be a (possibly
CV-qualified) builtin type. */
@@ -1456,7 +1476,7 @@ write_type (type)
if (write_CV_qualifiers_for_type (type) > 0)
/* If TYPE was CV-qualified, we just wrote the qualifiers; now
mangle the unqualified type. The recursive call is needed here
- since both the qualified and uqualified types are substitution
+ since both the qualified and unqualified types are substitution
candidates. */
write_type (TYPE_MAIN_VARIANT (type));
else if (TREE_CODE (type) == ARRAY_TYPE)
@@ -1469,7 +1489,9 @@ write_type (type)
/* See through any typedefs. */
type = TYPE_MAIN_VARIANT (type);
- switch (TREE_CODE (type))
+ if (TYPE_PTRMEM_P (type))
+ write_pointer_to_member_type (type);
+ else switch (TREE_CODE (type))
{
case VOID_TYPE:
case BOOLEAN_TYPE:
@@ -1511,15 +1533,8 @@ write_type (type)
break;
case POINTER_TYPE:
- /* A pointer-to-member variable is represented by a POINTER_TYPE
- to an OFFSET_TYPE, so check for this first. */
- if (TYPE_PTRMEM_P (type))
- write_pointer_to_member_type (type);
- else
- {
- write_char ('P');
- write_type (TREE_TYPE (type));
- }
+ write_char ('P');
+ write_type (TREE_TYPE (type));
break;
case REFERENCE_TYPE:
@@ -1542,10 +1557,6 @@ write_type (type)
(TI_ARGS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (type)));
break;
- case OFFSET_TYPE:
- write_pointer_to_member_type (build_pointer_type (type));
- break;
-
case VECTOR_TYPE:
write_string ("U8__vector");
write_type (TREE_TYPE (type));
@@ -1567,8 +1578,7 @@ write_type (type)
<CV-qualifiers> ::= [r] [V] [K] */
static int
-write_CV_qualifiers_for_type (type)
- tree type;
+write_CV_qualifiers_for_type (const tree type)
{
int num_qualifiers = 0;
@@ -1626,8 +1636,7 @@ write_CV_qualifiers_for_type (type)
::= u <source-name> # vendor extended type */
static void
-write_builtin_type (type)
- tree type;
+write_builtin_type (tree type)
{
switch (TREE_CODE (type))
{
@@ -1710,8 +1719,7 @@ write_builtin_type (type)
<function-type> ::= F [Y] <bare-function-type> E */
static void
-write_function_type (type)
- tree type;
+write_function_type (const tree type)
{
MANGLE_TRACE_TREE ("function-type", type);
@@ -1752,10 +1760,8 @@ write_function_type (type)
<bare-function-type> ::= </signature/ type>+ */
static void
-write_bare_function_type (type, include_return_type_p, decl)
- tree type;
- int include_return_type_p;
- tree decl;
+write_bare_function_type (const tree type, const int include_return_type_p,
+ const tree decl)
{
MANGLE_TRACE_TREE ("bare-function-type", type);
@@ -1776,10 +1782,7 @@ write_bare_function_type (type, include_return_type_p, decl)
parameters are being emitted. */
static void
-write_method_parms (parm_types, method_p, decl)
- tree decl;
- tree parm_types;
- int method_p;
+write_method_parms (tree parm_types, const int method_p, const tree decl)
{
tree first_parm_type;
tree parm_decl = decl ? DECL_ARGUMENTS (decl) : NULL_TREE;
@@ -1837,8 +1840,7 @@ write_method_parms (parm_types, method_p, decl)
/* <class-enum-type> ::= <name> */
static void
-write_class_enum_type (type)
- tree type;
+write_class_enum_type (const tree type)
{
write_name (TYPE_NAME (type), /*ignore_local_scope=*/0);
}
@@ -1849,40 +1851,27 @@ write_class_enum_type (type)
<template-args> ::= I <template-arg>+ E */
static void
-write_template_args (args)
- tree args;
+write_template_args (tree args)
{
+ int i;
+ int length = TREE_VEC_LENGTH (args);
+
MANGLE_TRACE_TREE ("template-args", args);
write_char ('I');
- if (TREE_CODE (args) == TREE_VEC)
- {
- int i;
- int length = TREE_VEC_LENGTH (args);
- my_friendly_assert (length > 0, 20000422);
+ my_friendly_assert (length > 0, 20000422);
- if (TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
- {
- /* We have nested template args. We want the innermost template
- argument list. */
- args = TREE_VEC_ELT (args, length - 1);
- length = TREE_VEC_LENGTH (args);
- }
- for (i = 0; i < length; ++i)
- write_template_arg (TREE_VEC_ELT (args, i));
- }
- else
+ if (TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
{
- my_friendly_assert (TREE_CODE (args) == TREE_LIST, 20021014);
-
- while (args)
- {
- write_template_arg (TREE_VALUE (args));
- args = TREE_CHAIN (args);
- }
+ /* We have nested template args. We want the innermost template
+ argument list. */
+ args = TREE_VEC_ELT (args, length - 1);
+ length = TREE_VEC_LENGTH (args);
}
-
+ for (i = 0; i < length; ++i)
+ write_template_arg (TREE_VEC_ELT (args, i));
+
write_char ('E');
}
@@ -1897,8 +1886,7 @@ write_template_args (args)
::= sr <type> <unqualified-name> <template-args> */
static void
-write_expression (expr)
- tree expr;
+write_expression (tree expr)
{
enum tree_code code;
@@ -1942,7 +1930,7 @@ write_expression (expr)
if (code == CONST_DECL)
G.need_abi_warning = 1;
write_char ('L');
- write_mangled_name (expr);
+ write_mangled_name (expr, false);
write_char ('E');
}
else if (TREE_CODE (expr) == SIZEOF_EXPR
@@ -1975,8 +1963,6 @@ write_expression (expr)
{
template_args = TREE_OPERAND (member, 1);
member = TREE_OPERAND (member, 0);
- if (TREE_CODE (member) == LOOKUP_EXPR)
- member = TREE_OPERAND (member, 0);
}
else
template_args = NULL_TREE;
@@ -2068,6 +2054,19 @@ write_expression (expr)
write_type (TREE_OPERAND (expr, 0));
if (TREE_CODE (TREE_OPERAND (expr, 1)) == IDENTIFIER_NODE)
write_source_name (TREE_OPERAND (expr, 1));
+ else if (TREE_CODE (TREE_OPERAND (expr, 1)) == TEMPLATE_ID_EXPR)
+ {
+ tree template_id;
+ tree name;
+
+ template_id = TREE_OPERAND (expr, 1);
+ name = TREE_OPERAND (template_id, 0);
+ /* FIXME: What about operators? */
+ my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE,
+ 20030707);
+ write_source_name (TREE_OPERAND (template_id, 0));
+ write_template_args (TREE_OPERAND (template_id, 1));
+ }
else
{
/* G++ 3.2 incorrectly put out both the "sr" code and
@@ -2079,7 +2078,21 @@ write_expression (expr)
default:
for (i = 0; i < TREE_CODE_LENGTH (code); ++i)
- write_expression (TREE_OPERAND (expr, i));
+ {
+ tree operand = TREE_OPERAND (expr, i);
+ /* As a GNU expression, the middle operand of a
+ conditional may be omitted. Since expression
+ manglings are supposed to represent the input token
+ stream, there's no good way to mangle such an
+ expression without extending the C++ ABI. */
+ if (code == COND_EXPR && i == 1 && !operand)
+ {
+ error ("omitted middle operand to `?:' operand "
+ "cannot be mangled");
+ continue;
+ }
+ write_expression (operand);
+ }
}
}
}
@@ -2092,8 +2105,7 @@ write_expression (expr)
encoded as 0, true as 1." */
static void
-write_template_arg_literal (value)
- tree value;
+write_template_arg_literal (const tree value)
{
tree type = TREE_TYPE (value);
write_char ('L');
@@ -2105,9 +2117,9 @@ write_template_arg_literal (value)
{
if (same_type_p (type, boolean_type_node))
{
- if (value == boolean_false_node || integer_zerop (value))
+ if (integer_zerop (value))
write_unsigned_number (0);
- else if (value == boolean_true_node)
+ else if (integer_onep (value))
write_unsigned_number (1);
else
abort ();
@@ -2131,14 +2143,13 @@ write_template_arg_literal (value)
::= X <expression> E # expression */
static void
-write_template_arg (node)
- tree node;
+write_template_arg (tree node)
{
enum tree_code code = TREE_CODE (node);
MANGLE_TRACE_TREE ("template-arg", node);
- /* A template template paramter's argument list contains TREE_LIST
+ /* A template template parameter's argument list contains TREE_LIST
nodes of which the value field is the the actual argument. */
if (code == TREE_LIST)
{
@@ -2150,6 +2161,20 @@ write_template_arg (node)
code = TREE_CODE (node);
}
}
+
+ if (TREE_CODE (node) == NOP_EXPR
+ && TREE_CODE (TREE_TYPE (node)) == REFERENCE_TYPE)
+ {
+ /* Template parameters can be of reference type. To maintain
+ internal consistency, such arguments use a conversion from
+ address of object to reference type. */
+ my_friendly_assert (TREE_CODE (TREE_OPERAND (node, 0)) == ADDR_EXPR,
+ 20031215);
+ if (abi_version_at_least (2))
+ node = TREE_OPERAND (TREE_OPERAND (node, 0), 0);
+ else
+ G.need_abi_warning = 1;
+ }
if (TYPE_P (node))
write_type (node);
@@ -2183,8 +2208,8 @@ write_template_arg (node)
::= <name>
::= <substitution> */
-void
-write_template_template_arg (tree decl)
+static void
+write_template_template_arg (const tree decl)
{
MANGLE_TRACE_TREE ("template-template-arg", decl);
@@ -2204,9 +2229,8 @@ write_template_template_arg (tree decl)
element type. For variable length arrays, the dimension (but not
the '_' separator) is omitted." */
-static void
-write_array_type (type)
- tree type;
+static void
+write_array_type (const tree type)
{
write_char ('A');
if (TYPE_DOMAIN (type))
@@ -2226,7 +2250,20 @@ write_array_type (type)
write_unsigned_number (tree_low_cst (max, 1));
}
else
- write_expression (TREE_OPERAND (max, 0));
+ {
+ max = TREE_OPERAND (max, 0);
+ if (!abi_version_at_least (2))
+ {
+ /* value_dependent_expression_p presumes nothing is
+ dependent when PROCESSING_TEMPLATE_DECL is zero. */
+ ++processing_template_decl;
+ if (!value_dependent_expression_p (max))
+ G.need_abi_warning = 1;
+ --processing_template_decl;
+ }
+ write_expression (max);
+ }
+
}
write_char ('_');
write_type (TREE_TYPE (type));
@@ -2238,8 +2275,7 @@ write_array_type (type)
<pointer-to-member-type> ::= M </class/ type> </member/ type> */
static void
-write_pointer_to_member_type (type)
- tree type;
+write_pointer_to_member_type (const tree type)
{
write_char ('M');
write_type (TYPE_PTRMEM_CLASS_TYPE (type));
@@ -2250,18 +2286,10 @@ write_pointer_to_member_type (type)
TEMPLATE_TEMPLATE_PARM, BOUND_TEMPLATE_TEMPLATE_PARM or a
TEMPLATE_PARM_INDEX.
- <template-param> ::= T </parameter/ number> _
-
- If we are internally mangling then we distinguish level and, for
- non-type parms, type too. The mangling appends
-
- </level/ number> _ </non-type type/ type> _
-
- This is used by mangle_conv_op_name_for_type. */
+ <template-param> ::= T </parameter/ number> _ */
static void
-write_template_param (parm)
- tree parm;
+write_template_param (const tree parm)
{
int parm_index;
int parm_level;
@@ -2301,8 +2329,7 @@ write_template_param (parm)
::= <substitution> */
static void
-write_template_template_param (parm)
- tree parm;
+write_template_template_param (const tree parm)
{
tree template = NULL_TREE;
@@ -2330,8 +2357,7 @@ write_template_template_param (parm)
::= S_ */
static void
-write_substitution (seq_id)
- int seq_id;
+write_substitution (const int seq_id)
{
MANGLE_TRACE ("substitution", "");
@@ -2344,7 +2370,7 @@ write_substitution (seq_id)
/* Start mangling ENTITY. */
static inline void
-start_mangling (tree entity)
+start_mangling (const tree entity)
{
G.entity = entity;
G.need_abi_warning = false;
@@ -2357,7 +2383,7 @@ start_mangling (tree entity)
future version of the ABI, issue a warning. */
static inline const char *
-finish_mangling (bool warn)
+finish_mangling (const bool warn)
{
if (warn_abi && warn && G.need_abi_warning)
warning ("the mangled name of `%D' will change in a future "
@@ -2376,7 +2402,7 @@ finish_mangling (bool warn)
/* Initialize data structures for mangling. */
void
-init_mangle ()
+init_mangle (void)
{
gcc_obstack_init (&G.name_obstack);
@@ -2393,8 +2419,7 @@ init_mangle ()
/* Generate the mangled name of DECL. */
static const char *
-mangle_decl_string (decl)
- tree decl;
+mangle_decl_string (const tree decl)
{
const char *result;
@@ -2402,29 +2427,9 @@ mangle_decl_string (decl)
if (TREE_CODE (decl) == TYPE_DECL)
write_type (TREE_TYPE (decl));
- else if (/* The names of `extern "C"' functions are not mangled. */
- (DECL_EXTERN_C_FUNCTION_P (decl)
- /* But overloaded operator names *are* mangled. */
- && !DECL_OVERLOADED_OPERATOR_P (decl))
- /* The names of global variables aren't mangled either. */
- || (TREE_CODE (decl) == VAR_DECL
- && CP_DECL_CONTEXT (decl) == global_namespace)
- /* And neither are `extern "C"' variables. */
- || (TREE_CODE (decl) == VAR_DECL
- && DECL_EXTERN_C_P (decl)))
- write_string (IDENTIFIER_POINTER (DECL_NAME (decl)));
else
- {
- write_mangled_name (decl);
- if (DECL_LANG_SPECIFIC (decl)
- && (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)
- || DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)))
- /* We need a distinct mangled name for these entities, but
- we should never actually output it. So, we append some
- characters the assembler won't like. */
- write_string (" *INTERNAL* ");
- }
-
+ write_mangled_name (decl, true);
+
result = finish_mangling (/*warn=*/true);
if (DEBUG_MANGLE)
fprintf (stderr, "mangle_decl_string = '%s'\n\n", result);
@@ -2434,8 +2439,7 @@ mangle_decl_string (decl)
/* Create an identifier for the external mangled name of DECL. */
void
-mangle_decl (decl)
- tree decl;
+mangle_decl (const tree decl)
{
tree id = get_identifier (mangle_decl_string (decl));
@@ -2445,8 +2449,7 @@ mangle_decl (decl)
/* Generate the mangled representation of TYPE. */
const char *
-mangle_type_string (type)
- tree type;
+mangle_type_string (const tree type)
{
const char *result;
@@ -2461,8 +2464,7 @@ mangle_type_string (type)
/* Create an identifier for the mangled representation of TYPE. */
tree
-mangle_type (type)
- tree type;
+mangle_type (const tree type)
{
return get_identifier (mangle_type_string (type));
}
@@ -2472,9 +2474,7 @@ mangle_type (type)
component. */
static tree
-mangle_special_for_type (type, code)
- tree type;
- const char *code;
+mangle_special_for_type (const tree type, const char *code)
{
const char *result;
@@ -2500,8 +2500,7 @@ mangle_special_for_type (type, code)
structure for TYPE. */
tree
-mangle_typeinfo_for_type (type)
- tree type;
+mangle_typeinfo_for_type (const tree type)
{
return mangle_special_for_type (type, "TI");
}
@@ -2510,8 +2509,7 @@ mangle_typeinfo_for_type (type)
the mangled name of TYPE. */
tree
-mangle_typeinfo_string_for_type (type)
- tree type;
+mangle_typeinfo_string_for_type (const tree type)
{
return mangle_special_for_type (type, "TS");
}
@@ -2519,8 +2517,7 @@ mangle_typeinfo_string_for_type (type)
/* Create an identifier for the mangled name of the vtable for TYPE. */
tree
-mangle_vtbl_for_type (type)
- tree type;
+mangle_vtbl_for_type (const tree type)
{
return mangle_special_for_type (type, "TV");
}
@@ -2528,8 +2525,7 @@ mangle_vtbl_for_type (type)
/* Returns an identifier for the mangled name of the VTT for TYPE. */
tree
-mangle_vtt_for_type (type)
- tree type;
+mangle_vtt_for_type (const tree type)
{
return mangle_special_for_type (type, "TT");
}
@@ -2549,9 +2545,7 @@ mangle_vtt_for_type (type)
<special-name> ::= CT <type> <offset number> _ <base type> */
tree
-mangle_ctor_vtbl_for_type (type, binfo)
- tree type;
- tree binfo;
+mangle_ctor_vtbl_for_type (const tree type, const tree binfo)
{
const char *result;
@@ -2570,45 +2564,74 @@ mangle_ctor_vtbl_for_type (type, binfo)
return get_identifier (result);
}
-/* Return an identifier for the mangled name of a thunk to FN_DECL.
- OFFSET is the initial adjustment to this used to find the vptr. If
- VCALL_OFFSET is non-NULL, this is a virtual thunk, and it is the
- vtbl offset in bytes.
+/* Mangle a this pointer or result pointer adjustment.
+
+ <call-offset> ::= h <fixed offset number> _
+ ::= v <fixed offset number> _ <virtual offset number> _ */
+
+static void
+mangle_call_offset (const tree fixed_offset, const tree virtual_offset)
+{
+ write_char (virtual_offset ? 'v' : 'h');
+
+ /* For either flavor, write the fixed offset. */
+ write_integer_cst (fixed_offset);
+ write_char ('_');
+
+ /* For a virtual thunk, add the virtual offset. */
+ if (virtual_offset)
+ {
+ write_integer_cst (virtual_offset);
+ write_char ('_');
+ }
+}
- <special-name> ::= Th <offset number> _ <base encoding>
- ::= Tv <offset number> _ <vcall offset number> _
- <base encoding>
+/* Return an identifier for the mangled name of a this-adjusting or
+ covariant thunk to FN_DECL. FIXED_OFFSET is the initial adjustment
+ to this used to find the vptr. If VIRTUAL_OFFSET is non-NULL, this
+ is a virtual thunk, and it is the vtbl offset in
+ bytes. THIS_ADJUSTING is nonzero for a this adjusting thunk and
+ zero for a covariant thunk. Note, that FN_DECL might be a covariant
+ thunk itself. A covariant thunk name always includes the adjustment
+ for the this pointer, even if there is none.
+
+ <special-name> ::= T <call-offset> <base encoding>
+ ::= Tc <this_adjust call-offset> <result_adjust call-offset>
+ <base encoding>
*/
tree
-mangle_thunk (fn_decl, offset, vcall_offset)
- tree fn_decl;
- tree offset;
- tree vcall_offset;
+mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset,
+ tree virtual_offset)
{
const char *result;
start_mangling (fn_decl);
write_string ("_Z");
- /* The <special-name> for virtual thunks is Tv, for non-virtual
- thunks Th. */
write_char ('T');
- if (vcall_offset != 0)
- write_char ('v');
+
+ if (!this_adjusting)
+ {
+ /* Covariant thunk with no this adjustment */
+ write_char ('c');
+ mangle_call_offset (integer_zero_node, NULL_TREE);
+ mangle_call_offset (fixed_offset, virtual_offset);
+ }
+ else if (!DECL_THUNK_P (fn_decl))
+ /* Plain this adjusting thunk. */
+ mangle_call_offset (fixed_offset, virtual_offset);
else
- write_char ('h');
-
- /* For either flavor, write the offset to this. */
- write_integer_cst (offset);
- write_char ('_');
-
- /* For a virtual thunk, add the vcall offset. */
- if (vcall_offset)
{
- /* Virtual thunk. Write the vcall offset and base type name. */
- write_integer_cst (vcall_offset);
- write_char ('_');
+ /* This adjusting thunk to covariant thunk. */
+ write_char ('c');
+ mangle_call_offset (fixed_offset, virtual_offset);
+ fixed_offset = ssize_int (THUNK_FIXED_OFFSET (fn_decl));
+ virtual_offset = THUNK_VIRTUAL_OFFSET (fn_decl);
+ if (virtual_offset)
+ virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
+ mangle_call_offset (fixed_offset, virtual_offset);
+ fn_decl = THUNK_TARGET (fn_decl);
}
/* Scoped name. */
@@ -2621,8 +2644,8 @@ mangle_thunk (fn_decl, offset, vcall_offset)
}
/* This hash table maps TYPEs to the IDENTIFIER for a conversion
- operator to TYPE. The nodes are TREE_LISTs whose TREE_PURPOSE is
- the TYPE and whose TREE_VALUE is the IDENTIFIER. */
+ operator to TYPE. The nodes are IDENTIFIERs whose TREE_TYPE is the
+ TYPE. */
static GTY ((param_is (union tree_node))) htab_t conv_type_names;
@@ -2631,7 +2654,7 @@ static GTY ((param_is (union tree_node))) htab_t conv_type_names;
static hashval_t
hash_type (const void *val)
{
- return htab_hash_pointer (TREE_PURPOSE ((tree) val));
+ return (hashval_t) TYPE_UID (TREE_TYPE ((tree) val));
}
/* Compare VAL1 (a node in the table) with VAL2 (a TYPE). */
@@ -2639,41 +2662,44 @@ hash_type (const void *val)
static int
compare_type (const void *val1, const void *val2)
{
- return TREE_PURPOSE ((tree) val1) == (tree) val2;
+ return TREE_TYPE ((tree) val1) == (tree) val2;
}
/* Return an identifier for the mangled unqualified name for a
conversion operator to TYPE. This mangling is not specified by the
ABI spec; it is only used internally. */
-
+
tree
mangle_conv_op_name_for_type (const tree type)
{
void **slot;
tree identifier;
- char buffer[64];
-
+
if (conv_type_names == NULL)
conv_type_names = htab_create_ggc (31, &hash_type, &compare_type, NULL);
slot = htab_find_slot_with_hash (conv_type_names, type,
- htab_hash_pointer (type), INSERT);
- if (*slot)
- return TREE_VALUE ((tree) *slot);
-
- /* Create a unique name corresponding to TYPE. */
- sprintf (buffer, "operator %lu",
- (unsigned long) htab_elements (conv_type_names));
- identifier = get_identifier (buffer);
- *slot = build_tree_list (type, identifier);
+ (hashval_t) TYPE_UID (type), INSERT);
+ identifier = (tree)*slot;
+ if (!identifier)
+ {
+ char buffer[64];
+
+ /* Create a unique name corresponding to TYPE. */
+ sprintf (buffer, "operator %lu",
+ (unsigned long) htab_elements (conv_type_names));
+ identifier = get_identifier (buffer);
+ *slot = identifier;
+
+ /* Hang TYPE off the identifier so it can be found easily later
+ when performing conversions. */
+ TREE_TYPE (identifier) = type;
+
+ /* Set bits on the identifier so we know later it's a conversion. */
+ IDENTIFIER_OPNAME_P (identifier) = 1;
+ IDENTIFIER_TYPENAME_P (identifier) = 1;
+ }
- /* Set bits on the identifier so we know later it's a conversion. */
- IDENTIFIER_OPNAME_P (identifier) = 1;
- IDENTIFIER_TYPENAME_P (identifier) = 1;
- /* Hang TYPE off the identifier so it can be found easily later when
- performing conversions. */
- TREE_TYPE (identifier) = type;
-
return identifier;
}
@@ -2681,8 +2707,7 @@ mangle_conv_op_name_for_type (const tree type)
variable for indicated VARIABLE. */
tree
-mangle_guard_variable (variable)
- tree variable;
+mangle_guard_variable (const tree variable)
{
start_mangling (variable);
write_string ("_ZGV");
@@ -2700,8 +2725,7 @@ mangle_guard_variable (variable)
as well call them something readable. */
tree
-mangle_ref_init_variable (variable)
- tree variable;
+mangle_ref_init_variable (const tree variable)
{
start_mangling (variable);
write_string ("_ZGR");
@@ -2715,8 +2739,7 @@ mangle_ref_init_variable (variable)
/* How to write the type codes for the integer Java type. */
static void
-write_java_integer_type_codes (type)
- tree type;
+write_java_integer_type_codes (const tree type)
{
if (type == java_int_type_node)
write_char ('i');
diff --git a/contrib/gcc/cp/method.c b/contrib/gcc/cp/method.c
index 1c2d2ea70616..0f72dc755147 100644
--- a/contrib/gcc/cp/method.c
+++ b/contrib/gcc/cp/method.c
@@ -1,23 +1,23 @@
/* 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 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,6 +25,8 @@ Boston, MA 02111-1307, USA. */
/* Handle method declarations. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "rtl.h"
@@ -32,7 +34,6 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "flags.h"
#include "toplev.h"
-#include "ggc.h"
#include "tm_p.h"
#include "target.h"
@@ -49,22 +50,26 @@ enum mangling_flags
mf_maybe_uninstantiated = 1,
/* When mangling a numeric value, use the form `_XX_' (instead of
just `XX') if the value has more than one digit. */
- mf_use_underscores_around_value = 2,
+ mf_use_underscores_around_value = 2
};
typedef enum mangling_flags mangling_flags;
-static void do_build_assign_ref PARAMS ((tree));
-static void do_build_copy_constructor PARAMS ((tree));
-static tree synthesize_exception_spec PARAMS ((tree, tree (*) (tree, void *), void *));
-static tree locate_dtor PARAMS ((tree, void *));
-static tree locate_ctor PARAMS ((tree, void *));
-static tree locate_copy PARAMS ((tree, void *));
+static tree thunk_adjust (tree, bool, HOST_WIDE_INT, tree);
+static void do_build_assign_ref (tree);
+static void do_build_copy_constructor (tree);
+static tree synthesize_exception_spec (tree, tree (*) (tree, void *), void *);
+static tree locate_dtor (tree, void *);
+static tree locate_ctor (tree, void *);
+static tree locate_copy (tree, void *);
+#ifdef ASM_OUTPUT_DEF
+static tree make_alias_for_thunk (tree);
+#endif
/* Called once to initialize method.c. */
void
-init_method ()
+init_method (void)
{
init_mangle ();
}
@@ -73,8 +78,7 @@ init_method ()
/* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL. */
void
-set_mangled_name_for_decl (decl)
- tree decl;
+set_mangled_name_for_decl (tree decl)
{
if (processing_template_decl)
/* There's no need to mangle the name of a template function. */
@@ -84,248 +88,79 @@ set_mangled_name_for_decl (decl)
}
-/* Given a tree_code CODE, and some arguments (at least one),
- attempt to use an overloaded operator on the arguments.
-
- For unary operators, only the first argument need be checked.
- For binary operators, both arguments may need to be checked.
-
- Member functions can convert class references to class pointers,
- for one-level deep indirection. More than that is not supported.
- Operators [](), ()(), and ->() must be member functions.
-
- We call function call building calls with LOOKUP_COMPLAIN if they
- are our only hope. This is true when we see a vanilla operator
- applied to something of aggregate type. If this fails, we are free
- to return `error_mark_node', because we will have reported the
- error.
-
- Operators NEW and DELETE overload in funny ways: operator new takes
- a single `size' parameter, and operator delete takes a pointer to the
- storage being deleted. When overloading these operators, success is
- assumed. If there is a failure, report an error message and return
- `error_mark_node'. */
-
-/* NOSTRICT */
-tree
-build_opfncall (code, flags, xarg1, xarg2, arg3)
- enum tree_code code;
- int flags;
- tree xarg1, xarg2, arg3;
-{
- return build_new_op (code, flags, xarg1, xarg2, arg3);
-}
-
-/* This function takes an identifier, ID, and attempts to figure out what
- it means. There are a number of possible scenarios, presented in increasing
- order of hair:
-
- 1) not in a class's scope
- 2) in class's scope, member name of the class's method
- 3) in class's scope, but not a member name of the class
- 4) in class's scope, member name of a class's variable
-
- NAME is $1 from the bison rule. It is an IDENTIFIER_NODE.
- VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1)
-
- As a last ditch, try to look up the name as a label and return that
- address.
-
- Values which are declared as being of REFERENCE_TYPE are
- automatically dereferenced here (as a hack to make the
- compiler faster). */
-
-tree
-hack_identifier (value, name)
- tree value, name;
-{
- tree type;
-
- if (value == error_mark_node)
- return error_mark_node;
-
- type = TREE_TYPE (value);
- if (TREE_CODE (value) == FIELD_DECL)
- {
- if (current_class_ptr == NULL_TREE)
- {
- if (current_function_decl
- && DECL_STATIC_FUNCTION_P (current_function_decl))
- error ("invalid use of member `%D' in static member function",
- value);
- else
- /* We can get here when processing a bad default
- argument, like:
- struct S { int a; void f(int i = a); } */
- error ("invalid use of member `%D'", value);
-
- return error_mark_node;
- }
- TREE_USED (current_class_ptr) = 1;
- if (processing_template_decl)
- value = build_min_nt (COMPONENT_REF, current_class_ref, name);
- else
- {
- tree access_type = current_class_type;
-
- while (!DERIVED_FROM_P (context_for_name_lookup (value),
- access_type))
- {
- access_type = TYPE_CONTEXT (access_type);
- while (DECL_P (access_type))
- access_type = DECL_CONTEXT (access_type);
- }
-
- enforce_access (access_type, value);
- value
- = build_class_member_access_expr (current_class_ref, value,
- /*access_path=*/NULL_TREE,
- /*preserve_reference=*/false);
- }
- }
- else if ((TREE_CODE (value) == FUNCTION_DECL
- && DECL_FUNCTION_MEMBER_P (value))
- || (TREE_CODE (value) == OVERLOAD
- && DECL_FUNCTION_MEMBER_P (OVL_CURRENT (value))))
- {
- tree decl;
-
- if (TREE_CODE (value) == OVERLOAD)
- value = OVL_CURRENT (value);
-
- decl = maybe_dummy_object (DECL_CONTEXT (value), 0);
- value = finish_class_member_access_expr (decl, name);
- }
- else if (really_overloaded_fn (value))
- ;
- else if (TREE_CODE (value) == OVERLOAD)
- /* not really overloaded function */
- mark_used (OVL_FUNCTION (value));
- else if (TREE_CODE (value) == TREE_LIST)
- {
- /* Ambiguous reference to base members, possibly other cases?. */
- tree t = value;
- while (t && TREE_CODE (t) == TREE_LIST)
- {
- mark_used (TREE_VALUE (t));
- t = TREE_CHAIN (t);
- }
- }
- else if (TREE_CODE (value) == NAMESPACE_DECL)
- {
- error ("use of namespace `%D' as expression", value);
- return error_mark_node;
- }
- else if (DECL_CLASS_TEMPLATE_P (value))
- {
- error ("use of class template `%T' as expression", value);
- return error_mark_node;
- }
- else
- mark_used (value);
-
- if (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL
- || TREE_CODE (value) == RESULT_DECL)
- {
- tree context = decl_function_context (value);
- if (context != NULL_TREE && context != current_function_decl
- && ! TREE_STATIC (value))
- {
- error ("use of %s from containing function",
- (TREE_CODE (value) == VAR_DECL
- ? "`auto' variable" : "parameter"));
- cp_error_at (" `%#D' declared here", value);
- value = error_mark_node;
- }
- }
-
- if (DECL_P (value) && DECL_NONLOCAL (value))
- {
- if (DECL_CLASS_SCOPE_P (value)
- && DECL_CONTEXT (value) != current_class_type)
- {
- tree path;
- path = currently_open_derived_class (DECL_CONTEXT (value));
- enforce_access (path, value);
- }
- }
- else if (TREE_CODE (value) == TREE_LIST
- && TREE_TYPE (value) == error_mark_node)
- {
- error ("\
-request for member `%D' is ambiguous in multiple inheritance lattice",
- name);
- print_candidates (value);
- return error_mark_node;
- }
-
- if (! processing_template_decl)
- value = convert_from_reference (value);
- return value;
-}
-
-
-/* Return a thunk to FUNCTION. For a virtual thunk, DELTA is the
- offset to this used to locate the vptr, and VCALL_INDEX is used to
- look up the eventual subobject location. For a non-virtual thunk,
- DELTA is the offset to this and VCALL_INDEX is NULL. */
+/* Return a this or result adjusting thunk to FUNCTION. THIS_ADJUSTING
+ indicates whether it is a this or result adjusting thunk.
+ FIXED_OFFSET and VIRTUAL_OFFSET indicate how to do the adjustment
+ (see thunk_adjust). VIRTUAL_OFFSET can be NULL, but FIXED_OFFSET
+ never is. VIRTUAL_OFFSET is the /index/ into the vtable for this
+ adjusting thunks, we scale it to a byte offset. For covariant
+ thunks VIRTUAL_OFFSET is the virtual binfo. You must post process
+ the returned thunk with finish_thunk. */
tree
-make_thunk (function, delta, vcall_index)
- tree function;
- tree delta;
- tree vcall_index;
+make_thunk (tree function, bool this_adjusting,
+ tree fixed_offset, tree virtual_offset)
{
- tree thunk_id;
- tree thunk;
- tree vcall_offset;
HOST_WIDE_INT d;
-
+ tree thunk;
+
my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 20021025);
-
- /* Scale the VCALL_INDEX to be in terms of bytes. */
- if (vcall_index)
- vcall_offset
+ /* We can have this thunks to covariant thunks, but not vice versa. */
+ my_friendly_assert (!DECL_THIS_THUNK_P (function), 20021127);
+ my_friendly_assert (!DECL_RESULT_THUNK_P (function) || this_adjusting,
+ 20031123);
+
+ /* Scale the VIRTUAL_OFFSET to be in terms of bytes. */
+ if (this_adjusting && virtual_offset)
+ virtual_offset
= size_binop (MULT_EXPR,
- vcall_index,
- convert (ssizetype,
- TYPE_SIZE_UNIT (vtable_entry_type)));
- else
- vcall_offset = NULL_TREE;
-
- d = tree_low_cst (delta, 0);
-
- /* See if we already have the thunk in question. */
+ virtual_offset,
+ convert (ssizetype,
+ TYPE_SIZE_UNIT (vtable_entry_type)));
+
+ d = tree_low_cst (fixed_offset, 0);
+
+ /* See if we already have the thunk in question. For this_adjusting
+ thunks VIRTUAL_OFFSET will be an INTEGER_CST, for covariant thunks it
+ will be a BINFO. */
for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk))
- if (THUNK_DELTA (thunk) == d
- && ((THUNK_VCALL_OFFSET (thunk) != NULL_TREE)
- == (vcall_offset != NULL_TREE))
- && (THUNK_VCALL_OFFSET (thunk)
- ? tree_int_cst_equal (THUNK_VCALL_OFFSET (thunk),
- vcall_offset)
- : true))
+ if (DECL_THIS_THUNK_P (thunk) == this_adjusting
+ && THUNK_FIXED_OFFSET (thunk) == d
+ && !virtual_offset == !THUNK_VIRTUAL_OFFSET (thunk)
+ && (!virtual_offset
+ || (this_adjusting
+ ? tree_int_cst_equal (THUNK_VIRTUAL_OFFSET (thunk),
+ virtual_offset)
+ : THUNK_VIRTUAL_OFFSET (thunk) == virtual_offset)))
return thunk;
-
+
/* All thunks must be created before FUNCTION is actually emitted;
the ABI requires that all thunks be emitted together with the
function to which they transfer control. */
my_friendly_assert (!TREE_ASM_WRITTEN (function), 20021025);
+ /* Likewise, we can only be adding thunks to a function declared in
+ the class currently being laid out. */
+ my_friendly_assert (TYPE_SIZE (DECL_CONTEXT (function))
+ && TYPE_BEING_DEFINED (DECL_CONTEXT (function)),
+ 20031211);
- thunk_id = mangle_thunk (function, delta, vcall_offset);
- thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (function));
+ thunk = build_decl (FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
- cxx_dup_lang_specific_decl (function);
- SET_DECL_ASSEMBLER_NAME (thunk, thunk_id);
+ cxx_dup_lang_specific_decl (thunk);
+ DECL_THUNKS (thunk) = NULL_TREE;
+
DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
TREE_READONLY (thunk) = TREE_READONLY (function);
TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (function);
TREE_PUBLIC (thunk) = TREE_PUBLIC (function);
if (flag_weak)
comdat_linkage (thunk);
- SET_DECL_THUNK_P (thunk);
- DECL_INITIAL (thunk) = build1 (ADDR_EXPR, vfunc_ptr_type_node, function);
- THUNK_DELTA (thunk) = d;
- THUNK_VCALL_OFFSET (thunk) = vcall_offset;
+ SET_DECL_THUNK_P (thunk, this_adjusting);
+ THUNK_TARGET (thunk) = function;
+ THUNK_FIXED_OFFSET (thunk) = d;
+ THUNK_VIRTUAL_OFFSET (thunk) = virtual_offset;
+ THUNK_ALIAS (thunk) = NULL_TREE;
+
/* The thunk itself is not a constructor or destructor, even if
the thing it is thunking to is. */
DECL_INTERFACE_KNOWN (thunk) = 1;
@@ -346,6 +181,7 @@ make_thunk (function, delta, vcall_index)
DECL_DECLARED_INLINE_P (thunk) = 0;
/* Nor has it been deferred. */
DECL_DEFERRED_FN (thunk) = 0;
+
/* Add it to the list of thunks associated with FUNCTION. */
TREE_CHAIN (thunk) = DECL_THUNKS (function);
DECL_THUNKS (function) = thunk;
@@ -353,24 +189,170 @@ make_thunk (function, delta, vcall_index)
return thunk;
}
-/* Emit the definition of a C++ multiple inheritance vtable thunk. If
- EMIT_P is nonzero, the thunk is emitted immediately. */
+/* Finish THUNK, a thunk decl. */
void
-use_thunk (thunk_fndecl, emit_p)
- tree thunk_fndecl;
- int emit_p;
+finish_thunk (tree thunk)
{
- tree fnaddr;
- tree function;
- tree vcall_offset;
- HOST_WIDE_INT delta, vcall_value;
+ tree function, name;
+ tree fixed_offset = ssize_int (THUNK_FIXED_OFFSET (thunk));
+ tree virtual_offset = THUNK_VIRTUAL_OFFSET (thunk);
+
+ my_friendly_assert (!DECL_NAME (thunk) && DECL_THUNK_P (thunk), 20021127);
+ if (virtual_offset && DECL_RESULT_THUNK_P (thunk))
+ virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
+ function = THUNK_TARGET (thunk);
+ name = mangle_thunk (function, DECL_THIS_THUNK_P (thunk),
+ fixed_offset, virtual_offset);
+
+ /* We can end up with declarations of (logically) different
+ covariant thunks, that do identical adjustments. The two thunks
+ will be adjusting between within different hierarchies, which
+ happen to have the same layout. We must nullify one of them to
+ refer to the other. */
+ if (DECL_RESULT_THUNK_P (thunk))
+ {
+ tree cov_probe;
+
+ for (cov_probe = DECL_THUNKS (function);
+ cov_probe; cov_probe = TREE_CHAIN (cov_probe))
+ if (DECL_NAME (cov_probe) == name)
+ {
+ my_friendly_assert (!DECL_THUNKS (thunk), 20031023);
+ THUNK_ALIAS (thunk) = (THUNK_ALIAS (cov_probe)
+ ? THUNK_ALIAS (cov_probe) : cov_probe);
+ break;
+ }
+ }
+
+ DECL_NAME (thunk) = name;
+ SET_DECL_ASSEMBLER_NAME (thunk, name);
+}
+
+/* Adjust PTR by the constant FIXED_OFFSET, and by the vtable
+ offset indicated by VIRTUAL_OFFSET, if that is
+ non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
+ zero for a result adjusting thunk. */
+
+static tree
+thunk_adjust (tree ptr, bool this_adjusting,
+ HOST_WIDE_INT fixed_offset, tree virtual_offset)
+{
+ if (this_adjusting)
+ /* Adjust the pointer by the constant. */
+ ptr = fold (build (PLUS_EXPR, TREE_TYPE (ptr), ptr,
+ ssize_int (fixed_offset)));
+
+ /* If there's a virtual offset, look up that value in the vtable and
+ adjust the pointer again. */
+ if (virtual_offset)
+ {
+ tree vtable;
+
+ ptr = save_expr (ptr);
+ /* The vptr is always at offset zero in the object. */
+ vtable = build1 (NOP_EXPR,
+ build_pointer_type (build_pointer_type
+ (vtable_entry_type)),
+ ptr);
+ /* Form the vtable address. */
+ vtable = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (vtable)), vtable);
+ /* Find the entry with the vcall offset. */
+ vtable = build (PLUS_EXPR, TREE_TYPE (vtable), vtable, virtual_offset);
+ /* Get the offset itself. */
+ vtable = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (vtable)), vtable);
+ /* Adjust the `this' pointer. */
+ ptr = fold (build (PLUS_EXPR, TREE_TYPE (ptr), ptr, vtable));
+ }
+
+ if (!this_adjusting)
+ /* Adjust the pointer by the constant. */
+ ptr = fold (build (PLUS_EXPR, TREE_TYPE (ptr), ptr,
+ ssize_int (fixed_offset)));
+
+ return ptr;
+}
+
+/* Garbage collector tables contains thunk_labelno even when places
+ inside ifdef block. */
+static GTY (()) int thunk_labelno;
+#ifdef ASM_OUTPUT_DEF
+
+/* Create a static alias to function. */
+
+static tree
+make_alias_for_thunk (tree function)
+{
+ tree alias;
+ char buf[256];
+
+#if defined (TARGET_IS_PE_COFF)
+ if (DECL_ONE_ONLY (function))
+ return function;
+#endif
+
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LTHUNK", thunk_labelno);
+ thunk_labelno++;
+ alias = build_decl (FUNCTION_DECL, get_identifier (buf),
+ TREE_TYPE (function));
+ DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function);
+ cxx_dup_lang_specific_decl (alias);
+ DECL_CONTEXT (alias) = NULL;
+ TREE_READONLY (alias) = TREE_READONLY (function);
+ TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (function);
+ TREE_PUBLIC (alias) = 0;
+ DECL_INTERFACE_KNOWN (alias) = 1;
+ DECL_NOT_REALLY_EXTERN (alias) = 1;
+ DECL_THIS_STATIC (alias) = 1;
+ DECL_SAVED_FUNCTION_DATA (alias) = NULL;
+ DECL_DESTRUCTOR_P (alias) = 0;
+ DECL_CONSTRUCTOR_P (alias) = 0;
+ DECL_CLONED_FUNCTION (alias) = NULL_TREE;
+ DECL_EXTERNAL (alias) = 0;
+ DECL_ARTIFICIAL (alias) = 1;
+ DECL_NO_STATIC_CHAIN (alias) = 1;
+ DECL_PENDING_INLINE_P (alias) = 0;
+ DECL_INLINE (alias) = 0;
+ DECL_DECLARED_INLINE_P (alias) = 0;
+ DECL_DEFERRED_FN (alias) = 0;
+ DECL_USE_TEMPLATE (alias) = 0;
+ DECL_TEMPLATE_INSTANTIATED (alias) = 0;
+ DECL_TEMPLATE_INFO (alias) = NULL;
+ DECL_INITIAL (alias) = error_mark_node;
+ TREE_ADDRESSABLE (alias) = 1;
+ TREE_USED (alias) = 1;
+ SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
+ TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
+ if (!flag_syntax_only)
+ assemble_alias (alias, DECL_ASSEMBLER_NAME (function));
+ return alias;
+}
+#endif
+
+/* Emit the definition of a C++ multiple inheritance or covariant
+ return vtable thunk. If EMIT_P is nonzero, the thunk is emitted
+ immediately. */
+
+void
+use_thunk (tree thunk_fndecl, bool emit_p)
+{
+ tree function, alias;
+ tree virtual_offset;
+ HOST_WIDE_INT fixed_offset, virtual_value;
+ bool this_adjusting = DECL_THIS_THUNK_P (thunk_fndecl);
+
+ /* We should have called finish_thunk to give it a name. */
+ my_friendly_assert (DECL_NAME (thunk_fndecl), 20021127);
+
+ /* We should never be using an alias, always refer to the
+ aliased thunk. */
+ my_friendly_assert (!THUNK_ALIAS (thunk_fndecl), 20031023);
if (TREE_ASM_WRITTEN (thunk_fndecl))
return;
- fnaddr = DECL_INITIAL (thunk_fndecl);
- if (TREE_CODE (DECL_INITIAL (thunk_fndecl)) != ADDR_EXPR)
+ function = THUNK_TARGET (thunk_fndecl);
+ if (DECL_RESULT (thunk_fndecl))
/* We already turned this thunk into an ordinary function.
There's no need to process this thunk again. */
return;
@@ -380,27 +362,30 @@ use_thunk (thunk_fndecl, emit_p)
/* Figure out what function is being thunked to. It's referenced in
this translation unit. */
- function = TREE_OPERAND (fnaddr, 0);
TREE_ADDRESSABLE (function) = 1;
mark_used (function);
- TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (function)) = 1;
if (!emit_p)
return;
- delta = THUNK_DELTA (thunk_fndecl);
- vcall_offset = THUNK_VCALL_OFFSET (thunk_fndecl);
+#ifdef ASM_OUTPUT_DEF
+ alias = make_alias_for_thunk (function);
+#else
+ alias = function;
+#endif
- if (vcall_offset)
- {
- vcall_value = tree_low_cst (vcall_offset, /*pos=*/0);
+ fixed_offset = THUNK_FIXED_OFFSET (thunk_fndecl);
+ virtual_offset = THUNK_VIRTUAL_OFFSET (thunk_fndecl);
- /* It is expected that a value of zero means no vcall. */
- if (!vcall_value)
- abort ();
+ if (virtual_offset)
+ {
+ if (!this_adjusting)
+ virtual_offset = BINFO_VPTR_FIELD (virtual_offset);
+ virtual_value = tree_low_cst (virtual_offset, /*pos=*/0);
+ my_friendly_assert (virtual_value, 20021026);
}
else
- vcall_value = 0;
-
+ virtual_value = 0;
+
/* And, if we need to emit the thunk, it's used. */
mark_used (thunk_fndecl);
/* This thunk is actually defined. */
@@ -408,6 +393,7 @@ use_thunk (thunk_fndecl, emit_p)
/* The linkage of the function may have changed. FIXME in linkage
rewrite. */
TREE_PUBLIC (thunk_fndecl) = TREE_PUBLIC (function);
+ DECL_VISIBILITY (thunk_fndecl) = DECL_VISIBILITY (function);
if (flag_syntax_only)
{
@@ -417,26 +403,42 @@ use_thunk (thunk_fndecl, emit_p)
push_to_top_level ();
+#if defined (ASM_OUTPUT_DEF) \
+ && !defined (TARGET_IS_PE_COFF)
+ if (targetm.have_named_sections)
+ {
+ resolve_unique_section (function, 0, flag_function_sections);
+
+ if (DECL_SECTION_NAME (function) != NULL && DECL_ONE_ONLY (function))
+ {
+ resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
+
+ /* Output the thunk into the same section as function. */
+ DECL_SECTION_NAME (thunk_fndecl) = DECL_SECTION_NAME (function);
+ }
+ }
+#endif
+
/* The back-end expects DECL_INITIAL to contain a BLOCK, so we
create one. */
DECL_INITIAL (thunk_fndecl) = make_node (BLOCK);
- BLOCK_VARS (DECL_INITIAL (thunk_fndecl))
- = DECL_ARGUMENTS (thunk_fndecl);
-
- if (targetm.asm_out.can_output_mi_thunk (thunk_fndecl, delta,
- vcall_value, function))
+ BLOCK_VARS (DECL_INITIAL (thunk_fndecl)) = DECL_ARGUMENTS (thunk_fndecl);
+
+ if (this_adjusting
+ && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
+ virtual_value, alias))
{
const char *fnname;
current_function_decl = thunk_fndecl;
DECL_RESULT (thunk_fndecl)
= build_decl (RESULT_DECL, 0, integer_type_node);
fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
- init_function_start (thunk_fndecl, input_filename, lineno);
+ init_function_start (thunk_fndecl);
current_function_is_thunk = 1;
assemble_start_function (thunk_fndecl, fnname);
- targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl, delta,
- vcall_value, function);
+ targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
+ fixed_offset, virtual_value, alias);
assemble_end_function (thunk_fndecl, fnname);
current_function_decl = 0;
@@ -448,9 +450,10 @@ use_thunk (thunk_fndecl, emit_p)
}
else
{
- /* If we don't have the necessary code for efficient thunks,
- generate a thunk function that just makes a call to the real
- function. Unfortunately, this doesn't work for varargs. */
+ /* If this is a covariant thunk, or we don't have the necessary
+ code for efficient thunks, generate a thunk function that
+ just makes a call to the real function. Unfortunately, this
+ doesn't work for varargs. */
tree a, t;
@@ -458,13 +461,14 @@ use_thunk (thunk_fndecl, emit_p)
error ("generic thunk code fails for method `%#D' which uses `...'",
function);
- /* Set up clone argument trees for the thunk. */
+ /* Set up cloned argument trees for the thunk. */
t = NULL_TREE;
for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a))
{
tree x = copy_node (a);
TREE_CHAIN (x) = t;
DECL_CONTEXT (x) = thunk_fndecl;
+ SET_DECL_RTL (x, NULL_RTX);
t = x;
}
a = nreverse (t);
@@ -474,42 +478,26 @@ use_thunk (thunk_fndecl, emit_p)
start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED);
/* We don't bother with a body block for thunks. */
- /* Adjust the this pointer by the constant. */
- t = ssize_int (delta);
- t = fold (build (PLUS_EXPR, TREE_TYPE (a), a, t));
-
- /* If there's a vcall offset, look up that value in the vtable and
- adjust the `this' pointer again. */
- if (vcall_offset && !integer_zerop (vcall_offset))
- {
- tree orig_this;
-
- t = save_expr (t);
- orig_this = t;
- /* The vptr is always at offset zero in the object. */
- t = build1 (NOP_EXPR,
- build_pointer_type (build_pointer_type
- (vtable_entry_type)),
- t);
- /* Form the vtable address. */
- t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
- /* Find the entry with the vcall offset. */
- t = build (PLUS_EXPR, TREE_TYPE (t), t, vcall_offset);
- /* Calculate the offset itself. */
- t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
- /* Adjust the `this' pointer. */
- t = fold (build (PLUS_EXPR,
- TREE_TYPE (orig_this),
- orig_this,
- t));
- }
+ /* There's no need to check accessibility inside the thunk body. */
+ push_deferring_access_checks (dk_no_check);
+ t = a;
+ if (this_adjusting)
+ t = thunk_adjust (t, /*this_adjusting=*/1,
+ fixed_offset, virtual_offset);
+
/* Build up the call to the real function. */
t = tree_cons (NULL_TREE, t, NULL_TREE);
for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))
t = tree_cons (NULL_TREE, a, t);
t = nreverse (t);
- t = build_call (function, t);
+ t = build_call (alias, t);
+ CALL_FROM_THUNK_P (t) = 1;
+ t = force_target_expr (TREE_TYPE (t), t);
+ if (!this_adjusting)
+ t = thunk_adjust (t, /*this_adjusting=*/0,
+ fixed_offset, virtual_offset);
+
if (VOID_TYPE_P (TREE_TYPE (t)))
finish_expr_stmt (t);
else
@@ -517,11 +505,14 @@ use_thunk (thunk_fndecl, emit_p)
/* Since we want to emit the thunk, we explicitly mark its name as
referenced. */
- TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (thunk_fndecl)) = 1;
+ mark_referenced (DECL_ASSEMBLER_NAME (thunk_fndecl));
/* But we don't want debugging information about it. */
DECL_IGNORED_P (thunk_fndecl) = 1;
+ /* Re-enable access control. */
+ pop_deferring_access_checks ();
+
expand_body (finish_function (0));
}
@@ -533,8 +524,7 @@ use_thunk (thunk_fndecl, emit_p)
/* Generate code for default X(X&) constructor. */
static void
-do_build_copy_constructor (fndecl)
- tree fndecl;
+do_build_copy_constructor (tree fndecl)
{
tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
tree t;
@@ -637,13 +627,12 @@ do_build_copy_constructor (fndecl)
}
static void
-do_build_assign_ref (fndecl)
- tree fndecl;
+do_build_assign_ref (tree fndecl)
{
tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl));
tree compound_stmt;
- compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
+ compound_stmt = begin_compound_stmt (/*has_no_scope=*/false);
parm = convert_from_reference (parm);
if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type)
@@ -736,16 +725,15 @@ do_build_assign_ref (fndecl)
}
}
finish_return_stmt (current_class_ref);
- finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
+ finish_compound_stmt (compound_stmt);
}
void
-synthesize_method (fndecl)
- tree fndecl;
+synthesize_method (tree fndecl)
{
- int nested = (current_function_decl != NULL_TREE);
+ bool nested = (current_function_decl != NULL_TREE);
tree context = decl_function_context (fndecl);
- int need_body = 1;
+ bool need_body = true;
tree stmt;
if (at_eof)
@@ -760,6 +748,10 @@ synthesize_method (fndecl)
return;
}
+ /* We may be in the middle of deferred access check. Disable
+ it now. */
+ push_deferring_access_checks (dk_no_deferred);
+
if (! context)
push_to_top_level ();
else if (nested)
@@ -771,8 +763,7 @@ synthesize_method (fndecl)
where the attempt to generate the function occurs, giving the
user a hint as to why we are attempting to generate the
function. */
- DECL_SOURCE_LINE (fndecl) = lineno;
- DECL_SOURCE_FILE (fndecl) = input_filename;
+ DECL_SOURCE_LOCATION (fndecl) = input_location;
interface_unknown = 1;
start_function (NULL_TREE, fndecl, NULL_TREE, SF_DEFAULT | SF_PRE_PARSED);
@@ -782,7 +773,7 @@ synthesize_method (fndecl)
if (DECL_OVERLOADED_OPERATOR_P (fndecl) == NOP_EXPR)
{
do_build_assign_ref (fndecl);
- need_body = 0;
+ need_body = false;
}
else if (DECL_CONSTRUCTOR_P (fndecl))
{
@@ -798,18 +789,20 @@ synthesize_method (fndecl)
if (need_body)
{
tree compound_stmt;
- compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
- finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
+ compound_stmt = begin_compound_stmt (/*has_no_scope=*/false);
+ finish_compound_stmt (compound_stmt);
}
finish_function_body (stmt);
- expand_body (finish_function (0));
+ expand_or_defer_fn (finish_function (0));
extract_interface_info ();
if (! context)
pop_from_top_level ();
else if (nested)
pop_function_context_from (context);
+
+ pop_deferring_access_checks ();
}
/* Use EXTRACTOR to locate the relevant function called for each base &
@@ -819,10 +812,8 @@ synthesize_method (fndecl)
variants yet, so we need to look at the main one. */
static tree
-synthesize_exception_spec (type, extractor, client)
- tree type;
- tree (*extractor) (tree, void *);
- void *client;
+synthesize_exception_spec (tree type, tree (*extractor) (tree, void*),
+ void *client)
{
tree raises = empty_except_spec;
tree fields = TYPE_FIELDS (type);
@@ -866,9 +857,7 @@ synthesize_exception_spec (type, extractor, client)
/* Locate the dtor of TYPE. */
static tree
-locate_dtor (type, client)
- tree type;
- void *client ATTRIBUTE_UNUSED;
+locate_dtor (tree type, void *client ATTRIBUTE_UNUSED)
{
tree fns;
@@ -882,9 +871,7 @@ locate_dtor (type, client)
/* Locate the default ctor of TYPE. */
static tree
-locate_ctor (type, client)
- tree type;
- void *client ATTRIBUTE_UNUSED;
+locate_ctor (tree type, void *client ATTRIBUTE_UNUSED)
{
tree fns;
@@ -915,15 +902,13 @@ struct copy_data
and desired qualifiers of the source operand. */
static tree
-locate_copy (type, client_)
- tree type;
- void *client_;
+locate_copy (tree type, void *client_)
{
struct copy_data *client = (struct copy_data *)client_;
tree fns;
int ix = -1;
tree best = NULL_TREE;
- int excess_p = 0;
+ bool excess_p = false;
if (client->name)
{
@@ -947,9 +932,7 @@ locate_copy (type, client_)
parms = TREE_CHAIN (parms);
if (!parms)
continue;
- src_type = TREE_VALUE (parms);
- if (TREE_CODE (src_type) == REFERENCE_TYPE)
- src_type = TREE_TYPE (src_type);
+ src_type = non_reference (TREE_VALUE (parms));
if (!same_type_ignoring_top_level_qualifiers_p (src_type, type))
continue;
if (!sufficient_parms_p (TREE_CHAIN (parms)))
@@ -976,17 +959,14 @@ locate_copy (type, client_)
reference argument or a non-const reference. */
tree
-implicitly_declare_fn (kind, type, const_p)
- special_function_kind kind;
- tree type;
- int const_p;
+implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
{
tree declspecs = NULL_TREE;
tree fn, args = NULL_TREE;
tree raises = empty_except_spec;
- int retref = 0;
- int has_parm = 0;
- tree name = constructor_name (TYPE_IDENTIFIER (type));
+ bool retref = false;
+ bool has_parm = false;
+ tree name = constructor_name (type);
switch (kind)
{
@@ -1009,12 +989,12 @@ implicitly_declare_fn (kind, type, const_p)
struct copy_data data;
tree argtype = type;
- has_parm = 1;
+ has_parm = true;
data.name = NULL;
data.quals = 0;
if (kind == sfk_assignment_operator)
{
- retref = 1;
+ retref = true;
declspecs = build_tree_list (NULL_TREE, type);
name = ansi_assopname (NOP_EXPR);
@@ -1066,8 +1046,7 @@ implicitly_declare_fn (kind, type, const_p)
as there are artificial parms in FN. */
tree
-skip_artificial_parms_for (fn, list)
- tree fn, list;
+skip_artificial_parms_for (tree fn, tree list)
{
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
list = TREE_CHAIN (list);
@@ -1080,3 +1059,5 @@ skip_artificial_parms_for (fn, list)
list = TREE_CHAIN (list);
return list;
}
+
+#include "gt-cp-method.h"
diff --git a/contrib/gcc/cp/name-lookup.c b/contrib/gcc/cp/name-lookup.c
new file mode 100644
index 000000000000..a4e996fa6e31
--- /dev/null
+++ b/contrib/gcc/cp/name-lookup.c
@@ -0,0 +1,4923 @@
+/* Definitions for C++ name lookup routines.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "flags.h"
+#include "tree.h"
+#include "cp-tree.h"
+#include "name-lookup.h"
+#include "timevar.h"
+#include "toplev.h"
+#include "diagnostic.h"
+
+static cxx_scope *innermost_nonclass_level (void);
+static tree select_decl (cxx_binding *, int);
+static cxx_binding *binding_for_name (cxx_scope *, tree);
+static tree lookup_name_current_level (tree);
+static void push_local_binding (tree, tree, int);
+static tree push_overloaded_decl (tree, int);
+static bool lookup_using_namespace (tree, cxx_binding *, tree,
+ tree, int);
+static bool qualified_lookup_using_namespace (tree, tree, cxx_binding *, int);
+static tree lookup_type_current_level (tree);
+static tree push_using_directive (tree);
+
+
+/* The :: namespace. */
+
+tree global_namespace;
+
+/* The name of the anonymous namespace, throughout this translation
+ unit. */
+GTY(()) tree anonymous_namespace_name;
+
+
+/* Compute the chain index of a binding_entry given the HASH value of its
+ name and the total COUNT of chains. COUNT is assumed to be a power
+ of 2. */
+
+#define ENTRY_INDEX(HASH, COUNT) (((HASH) >> 3) & ((COUNT) - 1))
+
+/* A free list of "binding_entry"s awaiting for re-use. */
+
+static GTY((deletable(""))) binding_entry free_binding_entry = NULL;
+
+/* Create a binding_entry object for (NAME, TYPE). */
+
+static inline binding_entry
+binding_entry_make (tree name, tree type)
+{
+ binding_entry entry;
+
+ if (free_binding_entry)
+ {
+ entry = free_binding_entry;
+ free_binding_entry = entry->chain;
+ }
+ else
+ entry = ggc_alloc (sizeof (struct binding_entry_s));
+
+ entry->name = name;
+ entry->type = type;
+ entry->chain = NULL;
+
+ return entry;
+}
+
+/* Put ENTRY back on the free list. */
+
+static inline void
+binding_entry_free (binding_entry entry)
+{
+ entry->name = NULL;
+ entry->type = NULL;
+ entry->chain = free_binding_entry;
+ free_binding_entry = entry;
+}
+
+/* The datatype used to implement the mapping from names to types at
+ a given scope. */
+struct binding_table_s GTY(())
+{
+ /* Array of chains of "binding_entry"s */
+ binding_entry * GTY((length ("%h.chain_count"))) chain;
+
+ /* The number of chains in this table. This is the length of the
+ the member "chain" considered as an array. */
+ size_t chain_count;
+
+ /* Number of "binding_entry"s in this table. */
+ size_t entry_count;
+};
+
+/* Construct TABLE with an initial CHAIN_COUNT. */
+
+static inline void
+binding_table_construct (binding_table table, size_t chain_count)
+{
+ table->chain_count = chain_count;
+ table->entry_count = 0;
+ table->chain = ggc_alloc_cleared
+ (table->chain_count * sizeof (binding_entry));
+}
+
+/* Make TABLE's entries ready for reuse. */
+
+static void
+binding_table_free (binding_table table)
+{
+ size_t i;
+ size_t count;
+
+ if (table == NULL)
+ return;
+
+ for (i = 0, count = table->chain_count; i < count; ++i)
+ {
+ binding_entry temp = table->chain[i];
+ while (temp != NULL)
+ {
+ binding_entry entry = temp;
+ temp = entry->chain;
+ binding_entry_free (entry);
+ }
+ table->chain[i] = NULL;
+ }
+ table->entry_count = 0;
+}
+
+/* Allocate a table with CHAIN_COUNT, assumed to be a power of two. */
+
+static inline binding_table
+binding_table_new (size_t chain_count)
+{
+ binding_table table = ggc_alloc (sizeof (struct binding_table_s));
+ table->chain = NULL;
+ binding_table_construct (table, chain_count);
+ return table;
+}
+
+/* Expand TABLE to twice its current chain_count. */
+
+static void
+binding_table_expand (binding_table table)
+{
+ const size_t old_chain_count = table->chain_count;
+ const size_t old_entry_count = table->entry_count;
+ const size_t new_chain_count = 2 * old_chain_count;
+ binding_entry *old_chains = table->chain;
+ size_t i;
+
+ binding_table_construct (table, new_chain_count);
+ for (i = 0; i < old_chain_count; ++i)
+ {
+ binding_entry entry = old_chains[i];
+ for (; entry != NULL; entry = old_chains[i])
+ {
+ const unsigned int hash = IDENTIFIER_HASH_VALUE (entry->name);
+ const size_t j = ENTRY_INDEX (hash, new_chain_count);
+
+ old_chains[i] = entry->chain;
+ entry->chain = table->chain[j];
+ table->chain[j] = entry;
+ }
+ }
+ table->entry_count = old_entry_count;
+}
+
+/* Insert a binding for NAME to TYPE into TABLE. */
+
+static void
+binding_table_insert (binding_table table, tree name, tree type)
+{
+ const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
+ const size_t i = ENTRY_INDEX (hash, table->chain_count);
+ binding_entry entry = binding_entry_make (name, type);
+
+ entry->chain = table->chain[i];
+ table->chain[i] = entry;
+ ++table->entry_count;
+
+ if (3 * table->chain_count < 5 * table->entry_count)
+ binding_table_expand (table);
+}
+
+/* Return the binding_entry, if any, that maps NAME. */
+
+binding_entry
+binding_table_find (binding_table table, tree name)
+{
+ const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
+ binding_entry entry = table->chain[ENTRY_INDEX (hash, table->chain_count)];
+
+ while (entry != NULL && entry->name != name)
+ entry = entry->chain;
+
+ return entry;
+}
+
+/* Return the binding_entry, if any, that maps NAME to an anonymous type. */
+
+static tree
+binding_table_find_anon_type (binding_table table, tree name)
+{
+ const unsigned int hash = IDENTIFIER_HASH_VALUE (name);
+ binding_entry entry = table->chain[ENTRY_INDEX (hash, table->chain_count)];
+
+ while (entry != NULL && TYPE_IDENTIFIER (entry->type) != name)
+ entry = entry->chain;
+
+ return entry ? entry->type : NULL;
+}
+
+/* Return the binding_entry, if any, that has TYPE as target. If NAME
+ is non-null, then set the domain and rehash that entry. */
+
+static binding_entry
+binding_table_reverse_maybe_remap (binding_table table, tree type, tree name)
+{
+ const size_t chain_count = table->chain_count;
+ binding_entry entry = NULL;
+ binding_entry *p = NULL;
+ size_t i;
+
+ for (i = 0; i < chain_count && entry == NULL; ++i)
+ {
+ p = &table->chain[i];
+ while (*p != NULL && entry == NULL)
+ if ((*p)->type == type)
+ entry = *p;
+ else
+ p = &(*p)->chain;
+ }
+
+ if (entry != NULL && name != NULL && entry->name != name)
+ {
+ /* Remove the bucket from the previous chain. */
+ *p = (*p)->chain;
+
+ /* Remap the name type to type. */
+ i = ENTRY_INDEX (IDENTIFIER_HASH_VALUE (name), chain_count);
+ entry->chain = table->chain[i];
+ entry->name = name;
+ table->chain[i] = entry;
+ }
+
+ return entry;
+}
+
+/* Remove from TABLE all entries that map to anonymous enums or
+ class-types. */
+
+void
+binding_table_remove_anonymous_types (binding_table table)
+{
+ const size_t chain_count = table->chain_count;
+ size_t i;
+
+ for (i = 0; i < chain_count; ++i)
+ {
+ binding_entry *p = &table->chain[i];
+
+ while (*p != NULL)
+ if (ANON_AGGRNAME_P ((*p)->name))
+ {
+ binding_entry e = *p;
+ *p = (*p)->chain;
+ --table->entry_count;
+ binding_entry_free (e);
+ }
+ else
+ p = &(*p)->chain;
+ }
+}
+
+/* Apply PROC -- with DATA -- to all entries in TABLE. */
+
+void
+binding_table_foreach (binding_table table, bt_foreach_proc proc, void *data)
+{
+ const size_t chain_count = table->chain_count;
+ size_t i;
+
+ for (i = 0; i < chain_count; ++i)
+ {
+ binding_entry entry = table->chain[i];
+ for (; entry != NULL; entry = entry->chain)
+ proc (entry, data);
+ }
+}
+
+#ifndef ENABLE_SCOPE_CHECKING
+# define ENABLE_SCOPE_CHECKING 0
+#else
+# define ENABLE_SCOPE_CHECKING 1
+#endif
+
+/* A free list of "cxx_binding"s, connected by their PREVIOUS. */
+
+static GTY((deletable (""))) cxx_binding *free_bindings;
+
+/* Zero out a cxx_binding pointed to by B. */
+#define cxx_binding_clear(B) memset ((B), 0, sizeof (cxx_binding))
+
+/* (GC)-allocate a binding object with VALUE and TYPE member initialized. */
+
+static cxx_binding *
+cxx_binding_make (tree value, tree type)
+{
+ cxx_binding *binding;
+ if (free_bindings)
+ {
+ binding = free_bindings;
+ free_bindings = binding->previous;
+ }
+ else
+ binding = ggc_alloc (sizeof (cxx_binding));
+
+ binding->value = value;
+ binding->type = type;
+ binding->previous = NULL;
+
+ return binding;
+}
+
+/* Put BINDING back on the free list. */
+
+static inline void
+cxx_binding_free (cxx_binding *binding)
+{
+ binding->scope = NULL;
+ binding->previous = free_bindings;
+ free_bindings = binding;
+}
+
+/* Make DECL the innermost binding for ID. The LEVEL is the binding
+ level at which this declaration is being bound. */
+
+static void
+push_binding (tree id, tree decl, cxx_scope* level)
+{
+ cxx_binding *binding = cxx_binding_make (decl, NULL);
+
+ /* Now, fill in the binding information. */
+ binding->previous = IDENTIFIER_BINDING (id);
+ binding->scope = level;
+ INHERITED_VALUE_BINDING_P (binding) = 0;
+ LOCAL_BINDING_P (binding) = (level != class_binding_level);
+
+ /* And put it on the front of the list of bindings for ID. */
+ IDENTIFIER_BINDING (id) = binding;
+}
+
+/* Remove the binding for DECL which should be the innermost binding
+ for ID. */
+
+void
+pop_binding (tree id, tree decl)
+{
+ cxx_binding *binding;
+
+ if (id == NULL_TREE)
+ /* It's easiest to write the loops that call this function without
+ checking whether or not the entities involved have names. We
+ get here for such an entity. */
+ return;
+
+ /* Get the innermost binding for ID. */
+ binding = IDENTIFIER_BINDING (id);
+
+ /* The name should be bound. */
+ my_friendly_assert (binding != NULL, 0);
+
+ /* The DECL will be either the ordinary binding or the type
+ binding for this identifier. Remove that binding. */
+ if (binding->value == decl)
+ binding->value = NULL_TREE;
+ else if (binding->type == decl)
+ binding->type = NULL_TREE;
+ else
+ abort ();
+
+ if (!binding->value && !binding->type)
+ {
+ /* We're completely done with the innermost binding for this
+ identifier. Unhook it from the list of bindings. */
+ IDENTIFIER_BINDING (id) = binding->previous;
+
+ /* Add it to the free list. */
+ cxx_binding_free (binding);
+ }
+}
+
+/* BINDING records an existing declaration for a namein the current scope.
+ But, DECL is another declaration for that same identifier in the
+ same scope. This is the `struct stat' hack whereby a non-typedef
+ class name or enum-name can be bound at the same level as some other
+ kind of entity.
+ 3.3.7/1
+
+ A class name (9.1) or enumeration name (7.2) can be hidden by the
+ name of an object, function, or enumerator declared in the same scope.
+ If a class or enumeration name and an object, function, or enumerator
+ are declared in the same scope (in any order) with the same name, the
+ class or enumeration name is hidden wherever the object, function, or
+ enumerator name is visible.
+
+ It's the responsibility of the caller to check that
+ inserting this name is valid here. Returns nonzero if the new binding
+ was successful. */
+
+static bool
+supplement_binding (cxx_binding *binding, tree decl)
+{
+ tree bval = binding->value;
+ bool ok = true;
+
+ timevar_push (TV_NAME_LOOKUP);
+ if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
+ /* The new name is the type name. */
+ binding->type = decl;
+ else if (/* BVAL is null when push_class_level_binding moves an
+ inherited type-binding out of the way to make room for a
+ new value binding. */
+ !bval
+ /* BVAL is error_mark_node when DECL's name has been used
+ in a non-class scope prior declaration. In that case,
+ we should have already issued a diagnostic; for graceful
+ error recovery purpose, pretend this was the intended
+ declaration for that name. */
+ || bval == error_mark_node
+ /* If BVAL is a built-in that has not yet been declared,
+ pretend it is not there at all. */
+ || (TREE_CODE (bval) == FUNCTION_DECL
+ && DECL_ANTICIPATED (bval)))
+ binding->value = decl;
+ else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval))
+ {
+ /* The old binding was a type name. It was placed in
+ VALUE field because it was thought, at the point it was
+ declared, to be the only entity with such a name. Move the
+ type name into the type slot; it is now hidden by the new
+ binding. */
+ binding->type = bval;
+ binding->value = decl;
+ binding->value_is_inherited = false;
+ }
+ else if (TREE_CODE (bval) == TYPE_DECL
+ && TREE_CODE (decl) == TYPE_DECL
+ && DECL_NAME (decl) == DECL_NAME (bval)
+ && (same_type_p (TREE_TYPE (decl), TREE_TYPE (bval))
+ /* If either type involves template parameters, we must
+ wait until instantiation. */
+ || uses_template_parms (TREE_TYPE (decl))
+ || uses_template_parms (TREE_TYPE (bval))))
+ /* We have two typedef-names, both naming the same type to have
+ the same name. This is OK because of:
+
+ [dcl.typedef]
+
+ In a given scope, a typedef specifier can be used to redefine
+ the name of any type declared in that scope to refer to the
+ type to which it already refers. */
+ ok = false;
+ /* There can be two block-scope declarations of the same variable,
+ so long as they are `extern' declarations. However, there cannot
+ be two declarations of the same static data member:
+
+ [class.mem]
+
+ A member shall not be declared twice in the
+ member-specification. */
+ else if (TREE_CODE (decl) == VAR_DECL && TREE_CODE (bval) == VAR_DECL
+ && DECL_EXTERNAL (decl) && DECL_EXTERNAL (bval)
+ && !DECL_CLASS_SCOPE_P (decl))
+ {
+ duplicate_decls (decl, binding->value);
+ ok = false;
+ }
+ else if (TREE_CODE (decl) == NAMESPACE_DECL
+ && TREE_CODE (bval) == NAMESPACE_DECL
+ && DECL_NAMESPACE_ALIAS (decl)
+ && DECL_NAMESPACE_ALIAS (bval)
+ && ORIGINAL_NAMESPACE (bval) == ORIGINAL_NAMESPACE (decl))
+ /* [namespace.alias]
+
+ In a declarative region, a namespace-alias-definition can be
+ used to redefine a namespace-alias declared in that declarative
+ region to refer only to the namespace to which it already
+ refers. */
+ ok = false;
+ else
+ {
+ error ("declaration of `%#D'", decl);
+ cp_error_at ("conflicts with previous declaration `%#D'", bval);
+ ok = false;
+ }
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
+}
+
+/* Add DECL to the list of things declared in B. */
+
+static void
+add_decl_to_level (tree decl, cxx_scope *b)
+{
+ if (TREE_CODE (decl) == NAMESPACE_DECL
+ && !DECL_NAMESPACE_ALIAS (decl))
+ {
+ TREE_CHAIN (decl) = b->namespaces;
+ b->namespaces = decl;
+ }
+ else if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl))
+ {
+ TREE_CHAIN (decl) = b->vtables;
+ b->vtables = decl;
+ }
+ else
+ {
+ /* We build up the list in reverse order, and reverse it later if
+ necessary. */
+ TREE_CHAIN (decl) = b->names;
+ b->names = decl;
+ b->names_size++;
+
+ /* If appropriate, add decl to separate list of statics. We
+ include extern variables because they might turn out to be
+ static later. It's OK for this list to contain a few false
+ positives. */
+ if (b->kind == sk_namespace)
+ if ((TREE_CODE (decl) == VAR_DECL
+ && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
+ || (TREE_CODE (decl) == FUNCTION_DECL
+ && (!TREE_PUBLIC (decl) || DECL_DECLARED_INLINE_P (decl))))
+ VARRAY_PUSH_TREE (b->static_decls, decl);
+ }
+}
+
+/* Record a decl-node X as belonging to the current lexical scope.
+ Check for errors (such as an incompatible declaration for the same
+ name already seen in the same scope).
+
+ Returns either X or an old decl for the same name.
+ If an old decl is returned, it may have been smashed
+ to agree with what X says. */
+
+tree
+pushdecl (tree x)
+{
+ tree t;
+ tree name;
+ int need_new_binding;
+
+ timevar_push (TV_NAME_LOOKUP);
+
+ need_new_binding = 1;
+
+ if (DECL_TEMPLATE_PARM_P (x))
+ /* Template parameters have no context; they are not X::T even
+ when declared within a class or namespace. */
+ ;
+ else
+ {
+ if (current_function_decl && x != current_function_decl
+ /* A local declaration for a function doesn't constitute
+ nesting. */
+ && TREE_CODE (x) != FUNCTION_DECL
+ /* A local declaration for an `extern' variable is in the
+ scope of the current namespace, not the current
+ function. */
+ && !(TREE_CODE (x) == VAR_DECL && DECL_EXTERNAL (x))
+ && !DECL_CONTEXT (x))
+ DECL_CONTEXT (x) = current_function_decl;
+
+ /* If this is the declaration for a namespace-scope function,
+ but the declaration itself is in a local scope, mark the
+ declaration. */
+ if (TREE_CODE (x) == FUNCTION_DECL
+ && DECL_NAMESPACE_SCOPE_P (x)
+ && current_function_decl
+ && x != current_function_decl)
+ DECL_LOCAL_FUNCTION_P (x) = 1;
+ }
+
+ name = DECL_NAME (x);
+ if (name)
+ {
+ int different_binding_level = 0;
+
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ name = TREE_OPERAND (name, 0);
+
+ /* In case this decl was explicitly namespace-qualified, look it
+ up in its namespace context. */
+ if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())
+ t = namespace_binding (name, DECL_CONTEXT (x));
+ else
+ t = lookup_name_current_level (name);
+
+ /* [basic.link] If there is a visible declaration of an entity
+ with linkage having the same name and type, ignoring entities
+ declared outside the innermost enclosing namespace scope, the
+ block scope declaration declares that same entity and
+ receives the linkage of the previous declaration. */
+ if (! t && current_function_decl && x != current_function_decl
+ && (TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
+ && DECL_EXTERNAL (x))
+ {
+ /* Look in block scope. */
+ t = IDENTIFIER_VALUE (name);
+ /* Or in the innermost namespace. */
+ if (! t)
+ t = namespace_binding (name, DECL_CONTEXT (x));
+ /* Does it have linkage? Note that if this isn't a DECL, it's an
+ OVERLOAD, which is OK. */
+ if (t && DECL_P (t) && ! (TREE_STATIC (t) || DECL_EXTERNAL (t)))
+ t = NULL_TREE;
+ if (t)
+ different_binding_level = 1;
+ }
+
+ /* If we are declaring a function, and the result of name-lookup
+ was an OVERLOAD, look for an overloaded instance that is
+ actually the same as the function we are declaring. (If
+ there is one, we have to merge our declaration with the
+ previous declaration.) */
+ if (t && TREE_CODE (t) == OVERLOAD)
+ {
+ tree match;
+
+ if (TREE_CODE (x) == FUNCTION_DECL)
+ for (match = t; match; match = OVL_NEXT (match))
+ {
+ if (decls_match (OVL_CURRENT (match), x))
+ break;
+ }
+ else
+ /* Just choose one. */
+ match = t;
+
+ if (match)
+ t = OVL_CURRENT (match);
+ else
+ t = NULL_TREE;
+ }
+
+ if (t == error_mark_node)
+ {
+ /* error_mark_node is 0 for a while during initialization! */
+ t = NULL_TREE;
+ cp_error_at ("`%#D' used prior to declaration", x);
+ }
+ else if (t != NULL_TREE)
+ {
+ if (different_binding_level)
+ {
+ if (decls_match (x, t))
+ /* The standard only says that the local extern
+ inherits linkage from the previous decl; in
+ particular, default args are not shared. It would
+ be nice to propagate inlining info, though. FIXME. */
+ TREE_PUBLIC (x) = TREE_PUBLIC (t);
+ }
+ else if (TREE_CODE (t) == PARM_DECL)
+ {
+ if (DECL_CONTEXT (t) == NULL_TREE)
+ /* This is probably caused by too many errors, but calling
+ abort will say that if errors have occurred. */
+ abort ();
+
+ /* Check for duplicate params. */
+ if (duplicate_decls (x, t))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+ }
+ else if ((DECL_EXTERN_C_FUNCTION_P (x)
+ || DECL_FUNCTION_TEMPLATE_P (x))
+ && is_overloaded_fn (t))
+ /* Don't do anything just yet. */;
+ else if (t == wchar_decl_node)
+ {
+ if (pedantic && ! DECL_IN_SYSTEM_HEADER (x))
+ pedwarn ("redeclaration of `wchar_t' as `%T'",
+ TREE_TYPE (x));
+
+ /* Throw away the redeclaration. */
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+ }
+ else
+ {
+ tree olddecl = duplicate_decls (x, t);
+
+ /* If the redeclaration failed, we can stop at this
+ point. */
+ if (olddecl == error_mark_node)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+
+ if (olddecl)
+ {
+ if (TREE_CODE (t) == TYPE_DECL)
+ SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
+ else if (TREE_CODE (t) == FUNCTION_DECL)
+ check_default_args (t);
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+ }
+ else if (DECL_MAIN_P (x) && TREE_CODE (t) == FUNCTION_DECL)
+ {
+ /* A redeclaration of main, but not a duplicate of the
+ previous one.
+
+ [basic.start.main]
+
+ This function shall not be overloaded. */
+ cp_error_at ("invalid redeclaration of `%D'", t);
+ error ("as `%D'", x);
+ /* We don't try to push this declaration since that
+ causes a crash. */
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
+ }
+ }
+ }
+
+ check_template_shadow (x);
+
+ /* If this is a function conjured up by the backend, massage it
+ so it looks friendly. */
+ if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_LANG_SPECIFIC (x))
+ {
+ retrofit_lang_decl (x);
+ SET_DECL_LANGUAGE (x, lang_c);
+ }
+
+ if (DECL_NON_THUNK_FUNCTION_P (x) && ! DECL_FUNCTION_MEMBER_P (x))
+ {
+ t = push_overloaded_decl (x, PUSH_LOCAL);
+ if (t != x)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+ if (!namespace_bindings_p ())
+ /* We do not need to create a binding for this name;
+ push_overloaded_decl will have already done so if
+ necessary. */
+ need_new_binding = 0;
+ }
+ else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x))
+ {
+ t = push_overloaded_decl (x, PUSH_GLOBAL);
+ if (t == x)
+ add_decl_to_level (x, NAMESPACE_LEVEL (CP_DECL_CONTEXT (t)));
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+ }
+
+ /* If declaring a type as a typedef, copy the type (unless we're
+ at line 0), and install this TYPE_DECL as the new type's typedef
+ name. See the extensive comment in ../c-decl.c (pushdecl). */
+ if (TREE_CODE (x) == TYPE_DECL)
+ {
+ tree type = TREE_TYPE (x);
+ if (DECL_SOURCE_LINE (x) == 0)
+ {
+ if (TYPE_NAME (type) == 0)
+ TYPE_NAME (type) = x;
+ }
+ else if (type != error_mark_node && TYPE_NAME (type) != x
+ /* We don't want to copy the type when all we're
+ doing is making a TYPE_DECL for the purposes of
+ inlining. */
+ && (!TYPE_NAME (type)
+ || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x)))
+ {
+ DECL_ORIGINAL_TYPE (x) = type;
+ type = build_type_copy (type);
+ TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
+ TYPE_NAME (type) = x;
+ TREE_TYPE (x) = type;
+ }
+
+ if (type != error_mark_node
+ && TYPE_NAME (type)
+ && TYPE_IDENTIFIER (type))
+ set_identifier_type_value (DECL_NAME (x), x);
+ }
+
+ /* Multiple external decls of the same identifier ought to match.
+
+ We get warnings about inline functions where they are defined.
+ We get warnings about other functions from push_overloaded_decl.
+
+ Avoid duplicate warnings where they are used. */
+ if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL)
+ {
+ tree decl;
+
+ decl = IDENTIFIER_NAMESPACE_VALUE (name);
+ if (decl && TREE_CODE (decl) == OVERLOAD)
+ decl = OVL_FUNCTION (decl);
+
+ if (decl && decl != error_mark_node
+ && (DECL_EXTERNAL (decl) || TREE_PUBLIC (decl))
+ /* If different sort of thing, we already gave an error. */
+ && TREE_CODE (decl) == TREE_CODE (x)
+ && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl)))
+ {
+ pedwarn ("type mismatch with previous external decl of `%#D'", x);
+ cp_pedwarn_at ("previous external decl of `%#D'", decl);
+ }
+ }
+
+ /* This name is new in its binding level.
+ Install the new declaration and return it. */
+ if (namespace_bindings_p ())
+ {
+ /* Install a global value. */
+
+ /* If the first global decl has external linkage,
+ warn if we later see static one. */
+ if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x))
+ TREE_PUBLIC (name) = 1;
+
+ /* Bind the name for the entity. */
+ if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)
+ && t != NULL_TREE)
+ && (TREE_CODE (x) == TYPE_DECL
+ || TREE_CODE (x) == VAR_DECL
+ || TREE_CODE (x) == ALIAS_DECL
+ || TREE_CODE (x) == NAMESPACE_DECL
+ || TREE_CODE (x) == CONST_DECL
+ || TREE_CODE (x) == TEMPLATE_DECL))
+ SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
+
+ /* Don't forget if the function was used via an implicit decl. */
+ if (IDENTIFIER_IMPLICIT_DECL (name)
+ && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name)))
+ TREE_USED (x) = 1;
+
+ /* Don't forget if its address was taken in that way. */
+ if (IDENTIFIER_IMPLICIT_DECL (name)
+ && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name)))
+ TREE_ADDRESSABLE (x) = 1;
+
+ /* Warn about mismatches against previous implicit decl. */
+ if (IDENTIFIER_IMPLICIT_DECL (name) != NULL_TREE
+ /* If this real decl matches the implicit, don't complain. */
+ && ! (TREE_CODE (x) == FUNCTION_DECL
+ && TREE_TYPE (TREE_TYPE (x)) == integer_type_node))
+ warning
+ ("`%D' was previously implicitly declared to return `int'", x);
+
+ /* If new decl is `static' and an `extern' was seen previously,
+ warn about it. */
+ if (x != NULL_TREE && t != NULL_TREE && decls_match (x, t))
+ warn_extern_redeclared_static (x, t);
+ }
+ else
+ {
+ /* Here to install a non-global value. */
+ tree oldlocal = IDENTIFIER_VALUE (name);
+ tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);
+
+ if (need_new_binding)
+ {
+ push_local_binding (name, x, 0);
+ /* Because push_local_binding will hook X on to the
+ current_binding_level's name list, we don't want to
+ do that again below. */
+ need_new_binding = 0;
+ }
+
+ /* If this is a TYPE_DECL, push it into the type value slot. */
+ if (TREE_CODE (x) == TYPE_DECL)
+ set_identifier_type_value (name, x);
+
+ /* Clear out any TYPE_DECL shadowed by a namespace so that
+ we won't think this is a type. The C struct hack doesn't
+ go through namespaces. */
+ if (TREE_CODE (x) == NAMESPACE_DECL)
+ set_identifier_type_value (name, NULL_TREE);
+
+ if (oldlocal)
+ {
+ tree d = oldlocal;
+
+ while (oldlocal
+ && TREE_CODE (oldlocal) == VAR_DECL
+ && DECL_DEAD_FOR_LOCAL (oldlocal))
+ oldlocal = DECL_SHADOWED_FOR_VAR (oldlocal);
+
+ if (oldlocal == NULL_TREE)
+ oldlocal = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (d));
+ }
+
+ /* If this is an extern function declaration, see if we
+ have a global definition or declaration for the function. */
+ if (oldlocal == NULL_TREE
+ && DECL_EXTERNAL (x)
+ && oldglobal != NULL_TREE
+ && TREE_CODE (x) == FUNCTION_DECL
+ && TREE_CODE (oldglobal) == FUNCTION_DECL)
+ {
+ /* We have one. Their types must agree. */
+ if (decls_match (x, oldglobal))
+ /* OK */;
+ else
+ {
+ warning ("extern declaration of `%#D' doesn't match", x);
+ cp_warning_at ("global declaration `%#D'", oldglobal);
+ }
+ }
+ /* If we have a local external declaration,
+ and no file-scope declaration has yet been seen,
+ then if we later have a file-scope decl it must not be static. */
+ if (oldlocal == NULL_TREE
+ && oldglobal == NULL_TREE
+ && DECL_EXTERNAL (x)
+ && TREE_PUBLIC (x))
+ TREE_PUBLIC (name) = 1;
+
+ /* Warn if shadowing an argument at the top level of the body. */
+ if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
+ /* Inline decls shadow nothing. */
+ && !DECL_FROM_INLINE (x)
+ && TREE_CODE (oldlocal) == PARM_DECL
+ /* Don't check the `this' parameter. */
+ && !DECL_ARTIFICIAL (oldlocal))
+ {
+ bool err = false;
+
+ /* Don't complain if it's from an enclosing function. */
+ if (DECL_CONTEXT (oldlocal) == current_function_decl
+ && TREE_CODE (x) != PARM_DECL)
+ {
+ /* Go to where the parms should be and see if we find
+ them there. */
+ struct cp_binding_level *b = current_binding_level->level_chain;
+
+ /* Skip the ctor/dtor cleanup level. */
+ b = b->level_chain;
+
+ /* ARM $8.3 */
+ if (b->kind == sk_function_parms)
+ {
+ error ("declaration of '%#D' shadows a parameter", x);
+ err = true;
+ }
+ }
+
+ if (warn_shadow && !err)
+ {
+ warning ("declaration of '%#D' shadows a parameter", x);
+ warning ("%Jshadowed declaration is here", oldlocal);
+ }
+ }
+
+ /* Maybe warn if shadowing something else. */
+ else if (warn_shadow && !DECL_EXTERNAL (x)
+ /* No shadow warnings for internally generated vars. */
+ && ! DECL_ARTIFICIAL (x)
+ /* No shadow warnings for vars made for inlining. */
+ && ! DECL_FROM_INLINE (x))
+ {
+ if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE
+ && current_class_ptr
+ && !TREE_STATIC (name))
+ {
+ /* Location of previous decl is not useful in this case. */
+ warning ("declaration of '%D' shadows a member of 'this'",
+ x);
+ }
+ else if (oldlocal != NULL_TREE
+ && TREE_CODE (oldlocal) == VAR_DECL)
+ {
+ warning ("declaration of '%D' shadows a previous local", x);
+ warning ("%Jshadowed declaration is here", oldlocal);
+ }
+ else if (oldglobal != NULL_TREE
+ && TREE_CODE (oldglobal) == VAR_DECL)
+ /* XXX shadow warnings in outer-more namespaces */
+ {
+ warning ("declaration of '%D' shadows a global declaration",
+ x);
+ warning ("%Jshadowed declaration is here", oldglobal);
+ }
+ }
+ }
+
+ if (TREE_CODE (x) == FUNCTION_DECL)
+ check_default_args (x);
+
+ if (TREE_CODE (x) == VAR_DECL)
+ maybe_register_incomplete_var (x);
+ }
+
+ if (need_new_binding)
+ add_decl_to_level (x,
+ DECL_NAMESPACE_SCOPE_P (x)
+ ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
+ : current_binding_level);
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
+}
+
+/* Enter DECL into the symbol table, if that's appropriate. Returns
+ DECL, or a modified version thereof. */
+
+tree
+maybe_push_decl (tree decl)
+{
+ tree type = TREE_TYPE (decl);
+
+ /* Add this decl to the current binding level, but not if it comes
+ from another scope, e.g. a static member variable. TEM may equal
+ DECL or it may be a previous decl of the same name. */
+ if (decl == error_mark_node
+ || (TREE_CODE (decl) != PARM_DECL
+ && DECL_CONTEXT (decl) != NULL_TREE
+ /* Definitions of namespace members outside their namespace are
+ possible. */
+ && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
+ || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
+ || TREE_CODE (type) == UNKNOWN_TYPE
+ /* The declaration of a template specialization does not affect
+ the functions available for overload resolution, so we do not
+ call pushdecl. */
+ || (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_TEMPLATE_SPECIALIZATION (decl)))
+ return decl;
+ else
+ return pushdecl (decl);
+}
+
+/* Bind DECL to ID in the current_binding_level, assumed to be a local
+ binding level. If PUSH_USING is set in FLAGS, we know that DECL
+ doesn't really belong to this binding level, that it got here
+ through a using-declaration. */
+
+static void
+push_local_binding (tree id, tree decl, int flags)
+{
+ struct cp_binding_level *b;
+
+ /* Skip over any local classes. This makes sense if we call
+ push_local_binding with a friend decl of a local class. */
+ b = innermost_nonclass_level ();
+
+ if (lookup_name_current_level (id))
+ {
+ /* Supplement the existing binding. */
+ if (!supplement_binding (IDENTIFIER_BINDING (id), decl))
+ /* It didn't work. Something else must be bound at this
+ level. Do not add DECL to the list of things to pop
+ later. */
+ return;
+ }
+ else
+ /* Create a new binding. */
+ push_binding (id, decl, b);
+
+ if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING))
+ /* We must put the OVERLOAD into a TREE_LIST since the
+ TREE_CHAIN of an OVERLOAD is already used. Similarly for
+ decls that got here through a using-declaration. */
+ decl = build_tree_list (NULL_TREE, decl);
+
+ /* And put DECL on the list of things declared by the current
+ binding level. */
+ add_decl_to_level (decl, b);
+}
+
+/* The old ARM scoping rules injected variables declared in the
+ initialization statement of a for-statement into the surrounding
+ scope. We support this usage, in order to be backward-compatible.
+ DECL is a just-declared VAR_DECL; if necessary inject its
+ declaration into the surrounding scope. */
+
+void
+maybe_inject_for_scope_var (tree decl)
+{
+ timevar_push (TV_NAME_LOOKUP);
+ if (!DECL_NAME (decl))
+ {
+ timevar_pop (TV_NAME_LOOKUP);
+ return;
+ }
+
+ /* Declarations of __FUNCTION__ and its ilk appear magically when
+ the variable is first used. If that happens to be inside a
+ for-loop, we don't want to do anything special. */
+ if (DECL_PRETTY_FUNCTION_P (decl))
+ {
+ timevar_pop (TV_NAME_LOOKUP);
+ return;
+ }
+
+ if (current_binding_level->kind == sk_for)
+ {
+ struct cp_binding_level *outer
+ = current_binding_level->level_chain;
+
+ /* Check to see if the same name is already bound at the outer
+ level, either because it was directly declared, or because a
+ dead for-decl got preserved. In either case, the code would
+ not have been valid under the ARM scope rules, so clear
+ is_for_scope for the current_binding_level.
+
+ Otherwise, we need to preserve the temp slot for decl to last
+ into the outer binding level. */
+
+ cxx_binding *outer_binding
+ = IDENTIFIER_BINDING (DECL_NAME (decl))->previous;
+
+ if (outer_binding && outer_binding->scope == outer
+ && (TREE_CODE (outer_binding->value) == VAR_DECL)
+ && DECL_DEAD_FOR_LOCAL (outer_binding->value))
+ {
+ outer_binding->value = DECL_SHADOWED_FOR_VAR (outer_binding->value);
+ current_binding_level->kind = sk_block;
+ }
+ }
+ timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Check to see whether or not DECL is a variable that would have been
+ in scope under the ARM, but is not in scope under the ANSI/ISO
+ standard. If so, issue an error message. If name lookup would
+ work in both cases, but return a different result, this function
+ returns the result of ANSI/ISO lookup. Otherwise, it returns
+ DECL. */
+
+tree
+check_for_out_of_scope_variable (tree decl)
+{
+ tree shadowed;
+
+ /* We only care about out of scope variables. */
+ if (!(TREE_CODE (decl) == VAR_DECL && DECL_DEAD_FOR_LOCAL (decl)))
+ return decl;
+
+ shadowed = DECL_SHADOWED_FOR_VAR (decl);
+ while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
+ && DECL_DEAD_FOR_LOCAL (shadowed))
+ shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
+ if (!shadowed)
+ shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (decl));
+ if (shadowed)
+ {
+ if (!DECL_ERROR_REPORTED (decl))
+ {
+ warning ("name lookup of `%D' changed",
+ DECL_NAME (decl));
+ cp_warning_at (" matches this `%D' under ISO standard rules",
+ shadowed);
+ cp_warning_at (" matches this `%D' under old rules", decl);
+ DECL_ERROR_REPORTED (decl) = 1;
+ }
+ return shadowed;
+ }
+
+ /* If we have already complained about this declaration, there's no
+ need to do it again. */
+ if (DECL_ERROR_REPORTED (decl))
+ return decl;
+
+ DECL_ERROR_REPORTED (decl) = 1;
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+ {
+ error ("name lookup of `%D' changed for new ISO `for' scoping",
+ DECL_NAME (decl));
+ cp_error_at (" cannot use obsolete binding at `%D' because it has a destructor", decl);
+ return error_mark_node;
+ }
+ else
+ {
+ pedwarn ("name lookup of `%D' changed for new ISO `for' scoping",
+ DECL_NAME (decl));
+ cp_pedwarn_at (" using obsolete binding at `%D'", decl);
+ }
+
+ return decl;
+}
+
+/* true means unconditionally make a BLOCK for the next level pushed. */
+
+static bool keep_next_level_flag;
+
+static int binding_depth = 0;
+static int is_class_level = 0;
+
+static void
+indent (int depth)
+{
+ int i;
+
+ for (i = 0; i < depth * 2; i++)
+ putc (' ', stderr);
+}
+
+/* Return a string describing the kind of SCOPE we have. */
+static const char *
+cxx_scope_descriptor (cxx_scope *scope)
+{
+ /* The order of this table must match the "scope_kind"
+ enumerators. */
+ static const char* scope_kind_names[] = {
+ "block-scope",
+ "cleanup-scope",
+ "try-scope",
+ "catch-scope",
+ "for-scope",
+ "function-parameter-scope",
+ "class-scope",
+ "namespace-scope",
+ "template-parameter-scope",
+ "template-explicit-spec-scope"
+ };
+ const scope_kind kind = scope->explicit_spec_p
+ ? sk_template_spec : scope->kind;
+
+ return scope_kind_names[kind];
+}
+
+/* Output a debugging information about SCOPE when performing
+ ACTION at LINE. */
+static void
+cxx_scope_debug (cxx_scope *scope, int line, const char *action)
+{
+ const char *desc = cxx_scope_descriptor (scope);
+ if (scope->this_entity)
+ verbatim ("%s %s(%E) %p %d\n", action, desc,
+ scope->this_entity, (void *) scope, line);
+ else
+ verbatim ("%s %s %p %d\n", action, desc, (void *) scope, line);
+}
+
+/* Return the estimated initial size of the hashtable of a NAMESPACE
+ scope. */
+
+static inline size_t
+namespace_scope_ht_size (tree ns)
+{
+ tree name = DECL_NAME (ns);
+
+ return name == std_identifier
+ ? NAMESPACE_STD_HT_SIZE
+ : (name == global_scope_name
+ ? GLOBAL_SCOPE_HT_SIZE
+ : NAMESPACE_ORDINARY_HT_SIZE);
+}
+
+/* A chain of binding_level structures awaiting reuse. */
+
+static GTY((deletable (""))) struct cp_binding_level *free_binding_level;
+
+/* Create a new KIND scope and make it the top of the active scopes stack.
+ ENTITY is the scope of the associated C++ entity (namespace, class,
+ function); it is NULL otherwise. */
+
+cxx_scope *
+begin_scope (scope_kind kind, tree entity)
+{
+ cxx_scope *scope;
+
+ /* Reuse or create a struct for this binding level. */
+ if (!ENABLE_SCOPE_CHECKING && free_binding_level)
+ {
+ scope = free_binding_level;
+ free_binding_level = scope->level_chain;
+ }
+ else
+ scope = ggc_alloc (sizeof (cxx_scope));
+ memset (scope, 0, sizeof (cxx_scope));
+
+ scope->this_entity = entity;
+ scope->more_cleanups_ok = true;
+ switch (kind)
+ {
+ case sk_cleanup:
+ scope->keep = true;
+ break;
+
+ case sk_template_spec:
+ scope->explicit_spec_p = true;
+ kind = sk_template_parms;
+ /* Fall through. */
+ case sk_template_parms:
+ case sk_block:
+ case sk_try:
+ case sk_catch:
+ case sk_for:
+ case sk_class:
+ case sk_function_parms:
+ scope->keep = keep_next_level_flag;
+ break;
+
+ case sk_namespace:
+ scope->type_decls = binding_table_new (namespace_scope_ht_size (entity));
+ NAMESPACE_LEVEL (entity) = scope;
+ VARRAY_TREE_INIT (scope->static_decls,
+ DECL_NAME (entity) == std_identifier
+ || DECL_NAME (entity) == global_scope_name
+ ? 200 : 10,
+ "Static declarations");
+ break;
+
+ default:
+ /* Should not happen. */
+ my_friendly_assert (false, 20030922);
+ break;
+ }
+ scope->kind = kind;
+
+ /* Add it to the front of currently active scopes stack. */
+ scope->level_chain = current_binding_level;
+ current_binding_level = scope;
+ keep_next_level_flag = false;
+
+ if (ENABLE_SCOPE_CHECKING)
+ {
+ scope->binding_depth = binding_depth;
+ indent (binding_depth);
+ cxx_scope_debug (scope, input_location.line, "push");
+ is_class_level = 0;
+ binding_depth++;
+ }
+
+ return scope;
+}
+
+/* We're about to leave current scope. Pop the top of the stack of
+ currently active scopes. Return the enclosing scope, now active. */
+
+cxx_scope *
+leave_scope (void)
+{
+ cxx_scope *scope = current_binding_level;
+
+ if (scope->kind == sk_namespace && class_binding_level)
+ current_binding_level = class_binding_level;
+
+ /* We cannot leave a scope, if there are none left. */
+ if (NAMESPACE_LEVEL (global_namespace))
+ my_friendly_assert (!global_scope_p (scope), 20030527);
+
+ if (ENABLE_SCOPE_CHECKING)
+ {
+ indent (--binding_depth);
+ cxx_scope_debug (scope, input_location.line, "leave");
+ if (is_class_level != (scope == class_binding_level))
+ {
+ indent (binding_depth);
+ verbatim ("XXX is_class_level != (current_scope == class_scope)\n");
+ }
+ is_class_level = 0;
+ }
+
+ /* Move one nesting level up. */
+ current_binding_level = scope->level_chain;
+
+ /* Namespace-scopes are left most probably temporarily, not completely;
+ they can be reopen later, e.g. in namespace-extension or any name
+ binding activity that requires us to resume a namespace. For other
+ scopes, we just make the structure available for reuse. */
+ if (scope->kind != sk_namespace)
+ {
+ scope->level_chain = free_binding_level;
+ if (scope->kind == sk_class)
+ scope->type_decls = NULL;
+ else
+ binding_table_free (scope->type_decls);
+ my_friendly_assert (!ENABLE_SCOPE_CHECKING
+ || scope->binding_depth == binding_depth,
+ 20030529);
+ free_binding_level = scope;
+ }
+
+ /* Find the innermost enclosing class scope, and reset
+ CLASS_BINDING_LEVEL appropriately. */
+ for (scope = current_binding_level;
+ scope && scope->kind != sk_class;
+ scope = scope->level_chain)
+ ;
+ class_binding_level = scope && scope->kind == sk_class ? scope : NULL;
+
+ return current_binding_level;
+}
+
+static void
+resume_scope (struct cp_binding_level* b)
+{
+ /* Resuming binding levels is meant only for namespaces,
+ and those cannot nest into classes. */
+ my_friendly_assert(!class_binding_level, 386);
+ /* Also, resuming a non-directly nested namespace is a no-no. */
+ my_friendly_assert(b->level_chain == current_binding_level, 386);
+ current_binding_level = b;
+ if (ENABLE_SCOPE_CHECKING)
+ {
+ b->binding_depth = binding_depth;
+ indent (binding_depth);
+ cxx_scope_debug (b, input_location.line, "resume");
+ is_class_level = 0;
+ binding_depth++;
+ }
+}
+
+/* Return the innermost binding level that is not for a class scope. */
+
+static cxx_scope *
+innermost_nonclass_level (void)
+{
+ cxx_scope *b;
+
+ b = current_binding_level;
+ while (b->kind == sk_class)
+ b = b->level_chain;
+
+ return b;
+}
+
+/* We're defining an object of type TYPE. If it needs a cleanup, but
+ we're not allowed to add any more objects with cleanups to the current
+ scope, create a new binding level. */
+
+void
+maybe_push_cleanup_level (tree type)
+{
+ if (type != error_mark_node
+ && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ && current_binding_level->more_cleanups_ok == 0)
+ {
+ begin_scope (sk_cleanup, NULL);
+ clear_last_expr ();
+ add_scope_stmt (/*begin_p=*/1, /*partial_p=*/1);
+ }
+}
+
+/* Nonzero if we are currently in the global binding level. */
+
+int
+global_bindings_p (void)
+{
+ return global_scope_p (current_binding_level);
+}
+
+/* True if we are currently in a toplevel binding level. This
+ means either the global binding level or a namespace in a toplevel
+ binding level. Since there are no non-toplevel namespace levels,
+ this really means any namespace or template parameter level. We
+ also include a class whose context is toplevel. */
+
+bool
+toplevel_bindings_p (void)
+{
+ struct cp_binding_level *b = innermost_nonclass_level ();
+
+ return b->kind == sk_namespace || b->kind == sk_template_parms;
+}
+
+/* True if this is a namespace scope, or if we are defining a class
+ which is itself at namespace scope, or whose enclosing class is
+ such a class, etc. */
+
+bool
+namespace_bindings_p (void)
+{
+ struct cp_binding_level *b = innermost_nonclass_level ();
+
+ return b->kind == sk_namespace;
+}
+
+/* True if the current level needs to have a BLOCK made. */
+
+bool
+kept_level_p (void)
+{
+ return (current_binding_level->blocks != NULL_TREE
+ || current_binding_level->keep
+ || current_binding_level->kind == sk_cleanup
+ || current_binding_level->names != NULL_TREE
+ || current_binding_level->type_decls != NULL);
+}
+
+/* Returns the kind of the innermost scope. */
+
+scope_kind
+innermost_scope_kind (void)
+{
+ return current_binding_level->kind;
+}
+
+/* Returns true if this scope was created to store template parameters. */
+
+bool
+template_parm_scope_p (void)
+{
+ return innermost_scope_kind () == sk_template_parms;
+}
+
+/* If KEEP is true, make a BLOCK node for the next binding level,
+ unconditionally. Otherwise, use the normal logic to decide whether
+ or not to create a BLOCK. */
+
+void
+keep_next_level (bool keep)
+{
+ keep_next_level_flag = keep;
+}
+
+/* Return the list of declarations of the current level.
+ Note that this list is in reverse order unless/until
+ you nreverse it; and when you do nreverse it, you must
+ store the result back using `storedecls' or you will lose. */
+
+tree
+getdecls (void)
+{
+ return current_binding_level->names;
+}
+
+/* Set the current binding TABLE for type declarations.. This is a
+ temporary workaround of the fact that the data structure classtypes
+ does not currently carry its allocated cxx_scope structure. */
+void
+cxx_remember_type_decls (binding_table table)
+{
+ current_binding_level->type_decls = table;
+}
+
+/* For debugging. */
+static int no_print_functions = 0;
+static int no_print_builtins = 0;
+
+/* Called from print_binding_level through binding_table_foreach to
+ print the content of binding ENTRY. DATA is a pointer to line offset
+ marker. */
+static void
+bt_print_entry (binding_entry entry, void *data)
+{
+ int *p = (int *) data;
+ int len;
+
+ if (entry->name == NULL)
+ len = 3;
+ else if (entry->name == TYPE_IDENTIFIER (entry->type))
+ len = 2;
+ else
+ len = 4;
+ len = 4;
+
+ *p += len;
+
+ if (*p > 5)
+ {
+ fprintf (stderr, "\n\t");
+ *p = len;
+ }
+ if (entry->name == NULL)
+ {
+ print_node_brief (stderr, "<unnamed-typedef", entry->type, 0);
+ fprintf (stderr, ">");
+ }
+ else if (entry->name == TYPE_IDENTIFIER (entry->type))
+ print_node_brief (stderr, "", entry->type, 0);
+ else
+ {
+ print_node_brief (stderr, "<typedef", entry->name, 0);
+ print_node_brief (stderr, "", entry->type, 0);
+ fprintf (stderr, ">");
+ }
+}
+
+void
+print_binding_level (struct cp_binding_level* lvl)
+{
+ tree t;
+ int i = 0, len;
+ fprintf (stderr, " blocks=" HOST_PTR_PRINTF, (void *) lvl->blocks);
+ if (lvl->more_cleanups_ok)
+ fprintf (stderr, " more-cleanups-ok");
+ if (lvl->have_cleanups)
+ fprintf (stderr, " have-cleanups");
+ fprintf (stderr, "\n");
+ if (lvl->names)
+ {
+ fprintf (stderr, " names:\t");
+ /* We can probably fit 3 names to a line? */
+ for (t = lvl->names; t; t = TREE_CHAIN (t))
+ {
+ if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL))
+ continue;
+ if (no_print_builtins
+ && (TREE_CODE (t) == TYPE_DECL)
+ && (!strcmp (DECL_SOURCE_FILE (t),"<built-in>")))
+ continue;
+
+ /* Function decls tend to have longer names. */
+ if (TREE_CODE (t) == FUNCTION_DECL)
+ len = 3;
+ else
+ len = 2;
+ i += len;
+ if (i > 6)
+ {
+ fprintf (stderr, "\n\t");
+ i = len;
+ }
+ print_node_brief (stderr, "", t, 0);
+ if (t == error_mark_node)
+ break;
+ }
+ if (i)
+ fprintf (stderr, "\n");
+ }
+ if (lvl->type_decls)
+ {
+ fprintf (stderr, " tags:\t");
+ i = 0;
+ binding_table_foreach (lvl->type_decls, bt_print_entry, &i);
+ if (i)
+ fprintf (stderr, "\n");
+ }
+ if (lvl->class_shadowed)
+ {
+ fprintf (stderr, " class-shadowed:");
+ for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t))
+ {
+ fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
+ }
+ fprintf (stderr, "\n");
+ }
+ if (lvl->type_shadowed)
+ {
+ fprintf (stderr, " type-shadowed:");
+ for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t))
+ {
+ fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t)));
+ }
+ fprintf (stderr, "\n");
+ }
+}
+
+void
+print_other_binding_stack (struct cp_binding_level *stack)
+{
+ struct cp_binding_level *level;
+ for (level = stack; !global_scope_p (level); level = level->level_chain)
+ {
+ fprintf (stderr, "binding level " HOST_PTR_PRINTF "\n", (void *) level);
+ print_binding_level (level);
+ }
+}
+
+void
+print_binding_stack (void)
+{
+ struct cp_binding_level *b;
+ fprintf (stderr, "current_binding_level=" HOST_PTR_PRINTF
+ "\nclass_binding_level=" HOST_PTR_PRINTF
+ "\nNAMESPACE_LEVEL (global_namespace)=" HOST_PTR_PRINTF "\n",
+ (void *) current_binding_level, (void *) class_binding_level,
+ (void *) NAMESPACE_LEVEL (global_namespace));
+ if (class_binding_level)
+ {
+ for (b = class_binding_level; b; b = b->level_chain)
+ if (b == current_binding_level)
+ break;
+ if (b)
+ b = class_binding_level;
+ else
+ b = current_binding_level;
+ }
+ else
+ b = current_binding_level;
+ print_other_binding_stack (b);
+ fprintf (stderr, "global:\n");
+ print_binding_level (NAMESPACE_LEVEL (global_namespace));
+}
+
+/* Return the type associated with id. */
+
+tree
+identifier_type_value (tree id)
+{
+ timevar_push (TV_NAME_LOOKUP);
+ /* There is no type with that name, anywhere. */
+ if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ /* This is not the type marker, but the real thing. */
+ if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, REAL_IDENTIFIER_TYPE_VALUE (id));
+ /* Have to search for it. It must be on the global level, now.
+ Ask lookup_name not to return non-types. */
+ id = lookup_name_real (id, 2, 1, 0, LOOKUP_COMPLAIN);
+ if (id)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_TYPE (id));
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+}
+
+/* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
+ the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++. */
+
+tree
+identifier_global_value (tree t)
+{
+ return IDENTIFIER_GLOBAL_VALUE (t);
+}
+
+/* Push a definition of struct, union or enum tag named ID. into
+ binding_level B. DECL is a TYPE_DECL for the type. We assume that
+ the tag ID is not already defined. */
+
+static void
+set_identifier_type_value_with_scope (tree id, tree decl, cxx_scope *b)
+{
+ tree type;
+
+ if (b->kind != sk_namespace)
+ {
+ /* Shadow the marker, not the real thing, so that the marker
+ gets restored later. */
+ tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
+ b->type_shadowed
+ = tree_cons (id, old_type_value, b->type_shadowed);
+ type = decl ? TREE_TYPE (decl) : NULL_TREE;
+ }
+ else
+ {
+ cxx_binding *binding =
+ binding_for_name (NAMESPACE_LEVEL (current_namespace), id);
+ if (decl)
+ {
+ if (binding->value)
+ supplement_binding (binding, decl);
+ else
+ binding->value = decl;
+ }
+ else
+ abort ();
+ /* Store marker instead of real type. */
+ type = global_type_node;
+ }
+ SET_IDENTIFIER_TYPE_VALUE (id, type);
+}
+
+/* As set_identifier_type_value_with_scope, but using
+ current_binding_level. */
+
+void
+set_identifier_type_value (tree id, tree decl)
+{
+ set_identifier_type_value_with_scope (id, decl, current_binding_level);
+}
+
+/* Return the name for the constructor (or destructor) for the
+ specified class TYPE. When given a template, this routine doesn't
+ lose the specialization. */
+
+tree
+constructor_name_full (tree type)
+{
+ type = TYPE_MAIN_VARIANT (type);
+ if (CLASS_TYPE_P (type) && TYPE_WAS_ANONYMOUS (type)
+ && TYPE_HAS_CONSTRUCTOR (type))
+ return DECL_NAME (OVL_CURRENT (CLASSTYPE_CONSTRUCTORS (type)));
+ else
+ return TYPE_IDENTIFIER (type);
+}
+
+/* Return the name for the constructor (or destructor) for the
+ specified class. When given a template, return the plain
+ unspecialized name. */
+
+tree
+constructor_name (tree type)
+{
+ tree name;
+ name = constructor_name_full (type);
+ if (IDENTIFIER_TEMPLATE (name))
+ name = IDENTIFIER_TEMPLATE (name);
+ return name;
+}
+
+/* Returns TRUE if NAME is the name for the constructor for TYPE. */
+
+bool
+constructor_name_p (tree name, tree type)
+{
+ tree ctor_name;
+
+ if (!name)
+ return false;
+
+ if (TREE_CODE (name) != IDENTIFIER_NODE)
+ return false;
+
+ ctor_name = constructor_name_full (type);
+ if (name == ctor_name)
+ return true;
+ if (IDENTIFIER_TEMPLATE (ctor_name)
+ && name == IDENTIFIER_TEMPLATE (ctor_name))
+ return true;
+ return false;
+}
+
+/* Counter used to create anonymous type names. */
+
+static GTY(()) int anon_cnt;
+
+/* Return an IDENTIFIER which can be used as a name for
+ anonymous structs and unions. */
+
+tree
+make_anon_name (void)
+{
+ char buf[32];
+
+ sprintf (buf, ANON_AGGRNAME_FORMAT, anon_cnt++);
+ return get_identifier (buf);
+}
+
+/* Clear the TREE_PURPOSE slot of UTDs which have anonymous typenames.
+ This keeps dbxout from getting confused. */
+
+void
+clear_anon_tags (void)
+{
+ struct cp_binding_level *b;
+ static int last_cnt = 0;
+
+ /* Fast out if no new anon names were declared. */
+ if (last_cnt == anon_cnt)
+ return;
+
+ b = current_binding_level;
+ while (b->kind == sk_cleanup)
+ b = b->level_chain;
+ if (b->type_decls != NULL)
+ binding_table_remove_anonymous_types (b->type_decls);
+ last_cnt = anon_cnt;
+}
+
+/* Return (from the stack of) the BINDING, if any, established at SCOPE. */
+
+static inline cxx_binding *
+find_binding (cxx_scope *scope, cxx_binding *binding)
+{
+ timevar_push (TV_NAME_LOOKUP);
+
+ for (; binding != NULL; binding = binding->previous)
+ if (binding->scope == scope)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding);
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (cxx_binding *)0);
+}
+
+/* Return the binding for NAME in SCOPE, if any. Otherwise, return NULL. */
+
+static inline cxx_binding *
+cxx_scope_find_binding_for_name (cxx_scope *scope, tree name)
+{
+ cxx_binding *b = IDENTIFIER_NAMESPACE_BINDINGS (name);
+ if (b)
+ {
+ /* Fold-in case where NAME is used only once. */
+ if (scope == b->scope && b->previous == NULL)
+ return b;
+ return find_binding (scope, b);
+ }
+ return NULL;
+}
+
+/* Always returns a binding for name in scope. If no binding is
+ found, make a new one. */
+
+static cxx_binding *
+binding_for_name (cxx_scope *scope, tree name)
+{
+ cxx_binding *result;
+
+ result = cxx_scope_find_binding_for_name (scope, name);
+ if (result)
+ return result;
+ /* Not found, make a new one. */
+ result = cxx_binding_make (NULL, NULL);
+ result->previous = IDENTIFIER_NAMESPACE_BINDINGS (name);
+ result->scope = scope;
+ result->is_local = false;
+ result->value_is_inherited = false;
+ IDENTIFIER_NAMESPACE_BINDINGS (name) = result;
+ return result;
+}
+
+/* Insert another USING_DECL into the current binding level, returning
+ this declaration. If this is a redeclaration, do nothing, and
+ return NULL_TREE if this not in namespace scope (in namespace
+ scope, a using decl might extend any previous bindings). */
+
+tree
+push_using_decl (tree scope, tree name)
+{
+ tree decl;
+
+ timevar_push (TV_NAME_LOOKUP);
+ my_friendly_assert (TREE_CODE (scope) == NAMESPACE_DECL, 383);
+ my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 384);
+ for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl))
+ if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name)
+ break;
+ if (decl)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
+ namespace_bindings_p () ? decl : NULL_TREE);
+ decl = build_lang_decl (USING_DECL, name, void_type_node);
+ DECL_INITIAL (decl) = scope;
+ TREE_CHAIN (decl) = current_binding_level->usings;
+ current_binding_level->usings = decl;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+}
+
+/* Same as pushdecl, but define X in binding-level LEVEL. We rely on the
+ caller to set DECL_CONTEXT properly. */
+
+tree
+pushdecl_with_scope (tree x, cxx_scope *level)
+{
+ struct cp_binding_level *b;
+ tree function_decl = current_function_decl;
+
+ timevar_push (TV_NAME_LOOKUP);
+ current_function_decl = NULL_TREE;
+ if (level->kind == sk_class)
+ {
+ b = class_binding_level;
+ class_binding_level = level;
+ pushdecl_class_level (x);
+ class_binding_level = b;
+ }
+ else
+ {
+ b = current_binding_level;
+ current_binding_level = level;
+ x = pushdecl (x);
+ current_binding_level = b;
+ }
+ current_function_decl = function_decl;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
+}
+
+/* DECL is a FUNCTION_DECL for a non-member function, which may have
+ other definitions already in place. We get around this by making
+ the value of the identifier point to a list of all the things that
+ want to be referenced by that name. It is then up to the users of
+ that name to decide what to do with that list.
+
+ DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its
+ DECL_TEMPLATE_RESULT. It is dealt with the same way.
+
+ FLAGS is a bitwise-or of the following values:
+ PUSH_LOCAL: Bind DECL in the current scope, rather than at
+ namespace scope.
+ PUSH_USING: DECL is being pushed as the result of a using
+ declaration.
+
+ The value returned may be a previous declaration if we guessed wrong
+ about what language DECL should belong to (C or C++). Otherwise,
+ it's always DECL (and never something that's not a _DECL). */
+
+static tree
+push_overloaded_decl (tree decl, int flags)
+{
+ tree name = DECL_NAME (decl);
+ tree old;
+ tree new_binding;
+ int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL));
+
+ timevar_push (TV_NAME_LOOKUP);
+ if (doing_global)
+ old = namespace_binding (name, DECL_CONTEXT (decl));
+ else
+ old = lookup_name_current_level (name);
+
+ if (old)
+ {
+ if (TREE_CODE (old) == TYPE_DECL && DECL_ARTIFICIAL (old))
+ {
+ tree t = TREE_TYPE (old);
+ if (IS_AGGR_TYPE (t) && warn_shadow
+ && (! DECL_IN_SYSTEM_HEADER (decl)
+ || ! DECL_IN_SYSTEM_HEADER (old)))
+ warning ("`%#D' hides constructor for `%#T'", decl, t);
+ old = NULL_TREE;
+ }
+ else if (is_overloaded_fn (old))
+ {
+ tree tmp;
+
+ for (tmp = old; tmp; tmp = OVL_NEXT (tmp))
+ {
+ tree fn = OVL_CURRENT (tmp);
+
+ if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
+ && !(flags & PUSH_USING)
+ && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
+ TYPE_ARG_TYPES (TREE_TYPE (decl))))
+ error ("`%#D' conflicts with previous using declaration `%#D'",
+ decl, fn);
+
+ if (duplicate_decls (decl, fn) == fn)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fn);
+ }
+ }
+ else if (old == error_mark_node)
+ /* Ignore the undefined symbol marker. */
+ old = NULL_TREE;
+ else
+ {
+ cp_error_at ("previous non-function declaration `%#D'", old);
+ error ("conflicts with function declaration `%#D'", decl);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+ }
+ }
+
+ if (old || TREE_CODE (decl) == TEMPLATE_DECL
+ /* If it's a using declaration, we always need to build an OVERLOAD,
+ because it's the only way to remember that the declaration comes
+ from 'using', and have the lookup behave correctly. */
+ || (flags & PUSH_USING))
+ {
+ if (old && TREE_CODE (old) != OVERLOAD)
+ new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE));
+ else
+ new_binding = ovl_cons (decl, old);
+ if (flags & PUSH_USING)
+ OVL_USED (new_binding) = 1;
+ }
+ else
+ /* NAME is not ambiguous. */
+ new_binding = decl;
+
+ if (doing_global)
+ set_namespace_binding (name, current_namespace, new_binding);
+ else
+ {
+ /* We only create an OVERLOAD if there was a previous binding at
+ this level, or if decl is a template. In the former case, we
+ need to remove the old binding and replace it with the new
+ binding. We must also run through the NAMES on the binding
+ level where the name was bound to update the chain. */
+
+ if (TREE_CODE (new_binding) == OVERLOAD && old)
+ {
+ tree *d;
+
+ for (d = &IDENTIFIER_BINDING (name)->scope->names;
+ *d;
+ d = &TREE_CHAIN (*d))
+ if (*d == old
+ || (TREE_CODE (*d) == TREE_LIST
+ && TREE_VALUE (*d) == old))
+ {
+ if (TREE_CODE (*d) == TREE_LIST)
+ /* Just replace the old binding with the new. */
+ TREE_VALUE (*d) = new_binding;
+ else
+ /* Build a TREE_LIST to wrap the OVERLOAD. */
+ *d = tree_cons (NULL_TREE, new_binding,
+ TREE_CHAIN (*d));
+
+ /* And update the cxx_binding node. */
+ IDENTIFIER_BINDING (name)->value = new_binding;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+ }
+
+ /* We should always find a previous binding in this case. */
+ abort ();
+ }
+
+ /* Install the new binding. */
+ push_local_binding (name, new_binding, flags);
+ }
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+}
+
+/* Check a non-member using-declaration. Return the name and scope
+ being used, and the USING_DECL, or NULL_TREE on failure. */
+
+static tree
+validate_nonmember_using_decl (tree decl, tree scope, tree name)
+{
+ if (TREE_CODE (decl) == TEMPLATE_ID_EXPR)
+ {
+ /* 7.3.3/5
+ A using-declaration shall not name a template-id. */
+ error ("a using-declaration cannot specify a template-id. Try `using %D'", name);
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (decl) == NAMESPACE_DECL)
+ {
+ error ("namespace `%D' not allowed in using-declaration", decl);
+ return NULL_TREE;
+ }
+
+ if (TREE_CODE (decl) == SCOPE_REF)
+ {
+ /* It's a nested name with template parameter dependent scope.
+ This can only be using-declaration for class member. */
+ error ("`%T' is not a namespace", TREE_OPERAND (decl, 0));
+ return NULL_TREE;
+ }
+
+ if (is_overloaded_fn (decl))
+ decl = get_first_fn (decl);
+
+ my_friendly_assert (DECL_P (decl), 20020908);
+
+ /* [namespace.udecl]
+ A using-declaration for a class member shall be a
+ member-declaration. */
+ if (TYPE_P (scope))
+ {
+ error ("`%T' is not a namespace", scope);
+ return NULL_TREE;
+ }
+
+ /* Make a USING_DECL. */
+ return push_using_decl (scope, name);
+}
+
+/* Process local and global using-declarations. */
+
+static void
+do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
+ tree *newval, tree *newtype)
+{
+ cxx_binding decls;
+
+ *newval = *newtype = NULL_TREE;
+ cxx_binding_clear (&decls);
+ if (!qualified_lookup_using_namespace (name, scope, &decls, 0))
+ /* Lookup error */
+ return;
+
+ if (!decls.value && !decls.type)
+ {
+ error ("`%D' not declared", name);
+ return;
+ }
+
+ /* Check for using functions. */
+ if (decls.value && is_overloaded_fn (decls.value))
+ {
+ tree tmp, tmp1;
+
+ if (oldval && !is_overloaded_fn (oldval))
+ {
+ if (!DECL_IMPLICIT_TYPEDEF_P (oldval))
+ error ("`%D' is already declared in this scope", name);
+ oldval = NULL_TREE;
+ }
+
+ *newval = oldval;
+ for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
+ {
+ tree new_fn = OVL_CURRENT (tmp);
+
+ /* [namespace.udecl]
+
+ If a function declaration in namespace scope or block
+ scope has the same name and the same parameter types as a
+ function introduced by a using declaration the program is
+ ill-formed. */
+ for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1))
+ {
+ tree old_fn = OVL_CURRENT (tmp1);
+
+ if (new_fn == old_fn)
+ /* The function already exists in the current namespace. */
+ break;
+ else if (OVL_USED (tmp1))
+ continue; /* this is a using decl */
+ else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
+ TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+ {
+ /* There was already a non-using declaration in
+ this scope with the same parameter types. If both
+ are the same extern "C" functions, that's ok. */
+ if (decls_match (new_fn, old_fn))
+ {
+ /* If the OLD_FN was a builtin, there is now a
+ real declaration. */
+ if (DECL_ANTICIPATED (old_fn))
+ DECL_ANTICIPATED (old_fn) = 0;
+ break;
+ }
+ else if (!DECL_ANTICIPATED (old_fn))
+ {
+ /* If the OLD_FN was really declared, the
+ declarations don't match. */
+ error ("`%D' is already declared in this scope", name);
+ break;
+ }
+
+ /* If the OLD_FN was not really there, just ignore
+ it and keep going. */
+ }
+ }
+
+ /* If we broke out of the loop, there's no reason to add
+ this function to the using declarations for this
+ scope. */
+ if (tmp1)
+ continue;
+
+ /* If we are adding to an existing OVERLOAD, then we no
+ longer know the type of the set of functions. */
+ if (*newval && TREE_CODE (*newval) == OVERLOAD)
+ TREE_TYPE (*newval) = unknown_type_node;
+ /* Add this new function to the set. */
+ *newval = build_overload (OVL_CURRENT (tmp), *newval);
+ /* If there is only one function, then we use its type. (A
+ using-declaration naming a single function can be used in
+ contexts where overload resolution cannot be
+ performed.) */
+ if (TREE_CODE (*newval) != OVERLOAD)
+ {
+ *newval = ovl_cons (*newval, NULL_TREE);
+ TREE_TYPE (*newval) = TREE_TYPE (OVL_CURRENT (tmp));
+ }
+ OVL_USED (*newval) = 1;
+ }
+ }
+ else
+ {
+ *newval = decls.value;
+ if (oldval && !decls_match (*newval, oldval))
+ error ("`%D' is already declared in this scope", name);
+ }
+
+ *newtype = decls.type;
+ if (oldtype && *newtype && !same_type_p (oldtype, *newtype))
+ {
+ error ("using declaration `%D' introduced ambiguous type `%T'",
+ name, oldtype);
+ return;
+ }
+}
+
+/* Process a using-declaration at function scope. */
+
+void
+do_local_using_decl (tree decl, tree scope, tree name)
+{
+ tree oldval, oldtype, newval, newtype;
+
+ decl = validate_nonmember_using_decl (decl, scope, name);
+ if (decl == NULL_TREE)
+ return;
+
+ if (building_stmt_tree ()
+ && at_function_scope_p ())
+ add_decl_stmt (decl);
+
+ oldval = lookup_name_current_level (name);
+ oldtype = lookup_type_current_level (name);
+
+ do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
+
+ if (newval)
+ {
+ if (is_overloaded_fn (newval))
+ {
+ tree fn, term;
+
+ /* We only need to push declarations for those functions
+ that were not already bound in the current level.
+ The old value might be NULL_TREE, it might be a single
+ function, or an OVERLOAD. */
+ if (oldval && TREE_CODE (oldval) == OVERLOAD)
+ term = OVL_FUNCTION (oldval);
+ else
+ term = oldval;
+ for (fn = newval; fn && OVL_CURRENT (fn) != term;
+ fn = OVL_NEXT (fn))
+ push_overloaded_decl (OVL_CURRENT (fn),
+ PUSH_LOCAL | PUSH_USING);
+ }
+ else
+ push_local_binding (name, newval, PUSH_USING);
+ }
+ if (newtype)
+ {
+ push_local_binding (name, newtype, PUSH_USING);
+ set_identifier_type_value (name, newtype);
+ }
+}
+
+/* Return the type that should be used when TYPE's name is preceded
+ by a tag such as 'struct' or 'union', or null if the name cannot
+ be used in this way.
+
+ For example, when processing the third line of:
+
+ struct A;
+ typedef struct A A;
+ struct A;
+
+ lookup of A will find the typedef. Given A's typedef, this function
+ will return the type associated with "struct A". For the tag to be
+ anything other than TYPE, TYPE must be a typedef whose original type
+ has the same name and context as TYPE itself.
+
+ It is not valid for a typedef of an anonymous type to be used with
+ an explicit tag:
+
+ typedef struct { ... } B;
+ struct B;
+
+ Return null for this case. */
+
+static tree
+follow_tag_typedef (tree type)
+{
+ tree original;
+
+ original = original_type (type);
+ if (! TYPE_NAME (original))
+ return NULL_TREE;
+ if (TYPE_IDENTIFIER (original) == TYPE_IDENTIFIER (type)
+ && (CP_DECL_CONTEXT (TYPE_NAME (original))
+ == CP_DECL_CONTEXT (TYPE_NAME (type)))
+ && !(CLASS_TYPE_P (original) && TYPE_WAS_ANONYMOUS (original)))
+ return original;
+ else
+ return NULL_TREE;
+}
+
+/* Given NAME, an IDENTIFIER_NODE,
+ return the structure (or union or enum) definition for that name.
+ Searches binding levels from its SCOPE up to the global level.
+ If THISLEVEL_ONLY is nonzero, searches only the specified context
+ (but skips any sk_cleanup contexts to find one that is
+ meaningful for tags).
+ FORM says which kind of type the caller wants;
+ it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE.
+ If the wrong kind of type is found, and it's not a template, an error is
+ reported. */
+
+tree
+lookup_tag (enum tree_code form, tree name,
+ cxx_scope *binding_level, int thislevel_only)
+{
+ struct cp_binding_level *level;
+ /* Nonzero if, we should look past a template parameter level, even
+ if THISLEVEL_ONLY. */
+ int allow_template_parms_p = 1;
+ bool type_is_anonymous = ANON_AGGRNAME_P (name);
+
+ timevar_push (TV_NAME_LOOKUP);
+ for (level = binding_level; level; level = level->level_chain)
+ {
+ tree tail;
+ if (type_is_anonymous && level->type_decls != NULL)
+ {
+ tree type = binding_table_find_anon_type (level->type_decls, name);
+ /* There is no need for error checking here, because
+ anon names are unique throughout the compilation. */
+ if (type != NULL)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
+ }
+ else if (level->kind == sk_namespace)
+ /* Do namespace lookup. */
+ for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail))
+ {
+ cxx_binding *binding =
+ cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (tail), name);
+ tree old;
+
+ /* If we just skipped past a template parameter level,
+ even though THISLEVEL_ONLY, and we find a template
+ class declaration, then we use the _TYPE node for the
+ template. See the example below. */
+ if (thislevel_only && !allow_template_parms_p
+ && binding && binding->value
+ && DECL_CLASS_TEMPLATE_P (binding->value))
+ old = binding->value;
+ else if (binding)
+ old = select_decl (binding, LOOKUP_PREFER_TYPES);
+ else
+ old = NULL_TREE;
+
+ if (old)
+ {
+ /* We've found something at this binding level. If it is
+ a typedef, extract the tag it refers to. Lookup fails
+ if the typedef doesn't refer to a taggable type. */
+ old = TREE_TYPE (old);
+ old = follow_tag_typedef (old);
+ if (!old)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ if (TREE_CODE (old) != form
+ && (form == ENUMERAL_TYPE
+ || TREE_CODE (old) == ENUMERAL_TYPE))
+ {
+ error ("`%#D' redeclared as %C", old, form);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ }
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old);
+ }
+ if (thislevel_only || tail == global_namespace)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ }
+ else if (level->type_decls != NULL)
+ {
+ binding_entry entry = binding_table_find (level->type_decls, name);
+ if (entry != NULL)
+ {
+ enum tree_code code = TREE_CODE (entry->type);
+
+ if (code != form
+ && (form == ENUMERAL_TYPE || code == ENUMERAL_TYPE))
+ {
+ /* Definition isn't the kind we were looking for. */
+ error ("`%#D' redeclared as %C", entry->type, form);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ }
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->type);
+ }
+ }
+ if (thislevel_only && level->kind != sk_cleanup)
+ {
+ if (level->kind == sk_template_parms && allow_template_parms_p)
+ {
+ /* We must deal with cases like this:
+
+ template <class T> struct S;
+ template <class T> struct S {};
+
+ When looking up `S', for the second declaration, we
+ would like to find the first declaration. But, we
+ are in the pseudo-global level created for the
+ template parameters, rather than the (surrounding)
+ namespace level. Thus, we keep going one more level,
+ even though THISLEVEL_ONLY is nonzero. */
+ allow_template_parms_p = 0;
+ continue;
+ }
+ else
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ }
+ }
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+}
+
+/* Given a type, find the tag that was defined for it and return the tag name.
+ Otherwise return 0. However, the value can never be 0
+ in the cases in which this is used.
+
+ C++: If NAME is nonzero, this is the new name to install. This is
+ done when replacing anonymous tags with real tag names. */
+
+tree
+lookup_tag_reverse (tree type, tree name)
+{
+ struct cp_binding_level *level;
+
+ timevar_push (TV_NAME_LOOKUP);
+ for (level = current_binding_level; level; level = level->level_chain)
+ {
+ binding_entry entry = level->type_decls == NULL
+ ? NULL
+ : binding_table_reverse_maybe_remap (level->type_decls, type, name);
+ if (entry)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->name);
+ }
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+}
+
+/* Returns true if ROOT (a namespace, class, or function) encloses
+ CHILD. CHILD may be either a class type or a namespace. */
+
+bool
+is_ancestor (tree root, tree child)
+{
+ my_friendly_assert ((TREE_CODE (root) == NAMESPACE_DECL
+ || TREE_CODE (root) == FUNCTION_DECL
+ || CLASS_TYPE_P (root)), 20030307);
+ my_friendly_assert ((TREE_CODE (child) == NAMESPACE_DECL
+ || CLASS_TYPE_P (child)),
+ 20030307);
+
+ /* The global namespace encloses everything. */
+ if (root == global_namespace)
+ return true;
+
+ while (true)
+ {
+ /* If we've run out of scopes, stop. */
+ if (!child)
+ return false;
+ /* If we've reached the ROOT, it encloses CHILD. */
+ if (root == child)
+ return true;
+ /* Go out one level. */
+ if (TYPE_P (child))
+ child = TYPE_NAME (child);
+ child = DECL_CONTEXT (child);
+ }
+}
+
+/* Enter the class or namespace scope indicated by T. Returns TRUE iff
+ pop_scope should be called later to exit this scope. */
+
+bool
+push_scope (tree t)
+{
+ bool pop = true;
+
+ if (TREE_CODE (t) == NAMESPACE_DECL)
+ push_decl_namespace (t);
+ else if (CLASS_TYPE_P (t))
+ {
+ if (!at_class_scope_p ()
+ || !same_type_p (current_class_type, t))
+ push_nested_class (t);
+ else
+ /* T is the same as the current scope. There is therefore no
+ need to re-enter the scope. Since we are not actually
+ pushing a new scope, our caller should not call
+ pop_scope. */
+ pop = false;
+ }
+
+ return pop;
+}
+
+/* Leave scope pushed by push_scope. */
+
+void
+pop_scope (tree t)
+{
+ if (TREE_CODE (t) == NAMESPACE_DECL)
+ pop_decl_namespace ();
+ else if CLASS_TYPE_P (t)
+ pop_nested_class ();
+}
+
+/* Do a pushlevel for class declarations. */
+
+void
+pushlevel_class (void)
+{
+ if (ENABLE_SCOPE_CHECKING)
+ is_class_level = 1;
+
+ class_binding_level = begin_scope (sk_class, current_class_type);
+}
+
+/* ...and a poplevel for class declarations. */
+
+void
+poplevel_class (void)
+{
+ struct cp_binding_level *level = class_binding_level;
+ tree shadowed;
+
+ timevar_push (TV_NAME_LOOKUP);
+ my_friendly_assert (level != 0, 354);
+
+ /* If we're leaving a toplevel class, don't bother to do the setting
+ of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot
+ shouldn't even be used when current_class_type isn't set, and second,
+ if we don't touch it here, we're able to use the cache effect if the
+ next time we're entering a class scope, it is the same class. */
+ if (current_class_depth != 1)
+ {
+ struct cp_binding_level* b;
+
+ /* Clear out our IDENTIFIER_CLASS_VALUEs. */
+ for (shadowed = level->class_shadowed;
+ shadowed;
+ shadowed = TREE_CHAIN (shadowed))
+ IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = NULL_TREE;
+
+ /* Find the next enclosing class, and recreate
+ IDENTIFIER_CLASS_VALUEs appropriate for that class. */
+ b = level->level_chain;
+ while (b && b->kind != sk_class)
+ b = b->level_chain;
+
+ if (b)
+ for (shadowed = b->class_shadowed;
+ shadowed;
+ shadowed = TREE_CHAIN (shadowed))
+ {
+ cxx_binding *binding;
+
+ binding = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed));
+ while (binding && binding->scope != b)
+ binding = binding->previous;
+
+ if (binding)
+ IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed))
+ = binding->value;
+ }
+ }
+ else
+ /* Remember to save what IDENTIFIER's were bound in this scope so we
+ can recover from cache misses. */
+ {
+ previous_class_type = current_class_type;
+ previous_class_values = class_binding_level->class_shadowed;
+ }
+ for (shadowed = level->type_shadowed;
+ shadowed;
+ shadowed = TREE_CHAIN (shadowed))
+ SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed));
+
+ /* Remove the bindings for all of the class-level declarations. */
+ for (shadowed = level->class_shadowed;
+ shadowed;
+ shadowed = TREE_CHAIN (shadowed))
+ pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed));
+
+ /* Now, pop out of the binding level which we created up in the
+ `pushlevel_class' routine. */
+ if (ENABLE_SCOPE_CHECKING)
+ is_class_level = 1;
+
+ leave_scope ();
+ timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Bind DECL to ID in the class_binding_level. Returns nonzero if the
+ binding was successful. */
+
+int
+push_class_binding (tree id, tree decl)
+{
+ int result = 1;
+ cxx_binding *binding = IDENTIFIER_BINDING (id);
+ tree context;
+
+ timevar_push (TV_NAME_LOOKUP);
+ /* Note that we declared this value so that we can issue an error if
+ this is an invalid redeclaration of a name already used for some
+ other purpose. */
+ note_name_declared_in_class (id, decl);
+
+ if (binding && binding->scope == class_binding_level)
+ /* Supplement the existing binding. */
+ result = supplement_binding (IDENTIFIER_BINDING (id), decl);
+ else
+ /* Create a new binding. */
+ push_binding (id, decl, class_binding_level);
+
+ /* Update the IDENTIFIER_CLASS_VALUE for this ID to be the
+ class-level declaration. Note that we do not use DECL here
+ because of the possibility of the `struct stat' hack; if DECL is
+ a class-name or enum-name we might prefer a field-name, or some
+ such. */
+ IDENTIFIER_CLASS_VALUE (id) = IDENTIFIER_BINDING (id)->value;
+
+ /* If this is a binding from a base class, mark it as such. */
+ binding = IDENTIFIER_BINDING (id);
+ if (binding->value == decl && TREE_CODE (decl) != TREE_LIST)
+ {
+ if (TREE_CODE (decl) == OVERLOAD)
+ context = CP_DECL_CONTEXT (OVL_CURRENT (decl));
+ else
+ {
+ my_friendly_assert (DECL_P (decl), 0);
+ context = context_for_name_lookup (decl);
+ }
+
+ if (is_properly_derived_from (current_class_type, context))
+ INHERITED_VALUE_BINDING_P (binding) = 1;
+ else
+ INHERITED_VALUE_BINDING_P (binding) = 0;
+ }
+ else if (binding->value == decl)
+ /* We only encounter a TREE_LIST when push_class_decls detects an
+ ambiguity. Such an ambiguity can be overridden by a definition
+ in this class. */
+ INHERITED_VALUE_BINDING_P (binding) = 1;
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result);
+}
+
+/* We are entering the scope of a class. Clear IDENTIFIER_CLASS_VALUE
+ for any names in enclosing classes. */
+
+void
+clear_identifier_class_values (void)
+{
+ tree t;
+
+ if (!class_binding_level)
+ return;
+
+ for (t = class_binding_level->class_shadowed;
+ t;
+ t = TREE_CHAIN (t))
+ IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE;
+}
+
+/* Make the declaration of X appear in CLASS scope. */
+
+bool
+pushdecl_class_level (tree x)
+{
+ tree name;
+ bool is_valid = true;
+
+ timevar_push (TV_NAME_LOOKUP);
+ /* Get the name of X. */
+ if (TREE_CODE (x) == OVERLOAD)
+ name = DECL_NAME (get_first_fn (x));
+ else
+ name = DECL_NAME (x);
+
+ if (name)
+ {
+ is_valid = push_class_level_binding (name, x);
+ if (TREE_CODE (x) == TYPE_DECL)
+ set_identifier_type_value (name, x);
+ }
+ else if (ANON_AGGR_TYPE_P (TREE_TYPE (x)))
+ {
+ /* If X is an anonymous aggregate, all of its members are
+ treated as if they were members of the class containing the
+ aggregate, for naming purposes. */
+ tree f;
+
+ for (f = TYPE_FIELDS (TREE_TYPE (x)); f; f = TREE_CHAIN (f))
+ {
+ location_t save_location = input_location;
+ input_location = DECL_SOURCE_LOCATION (f);
+ if (!pushdecl_class_level (f))
+ is_valid = false;
+ input_location = save_location;
+ }
+ }
+ timevar_pop (TV_NAME_LOOKUP);
+
+ return is_valid;
+}
+
+/* Make the declaration(s) of X appear in CLASS scope under the name
+ NAME. Returns true if the binding is valid. */
+
+bool
+push_class_level_binding (tree name, tree x)
+{
+ cxx_binding *binding;
+
+ timevar_push (TV_NAME_LOOKUP);
+ /* The class_binding_level will be NULL if x is a template
+ parameter name in a member template. */
+ if (!class_binding_level)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+
+ /* Make sure that this new member does not have the same name
+ as a template parameter. */
+ if (TYPE_BEING_DEFINED (current_class_type))
+ check_template_shadow (x);
+
+ /* [class.mem]
+
+ If T is the name of a class, then each of the following shall
+ have a name different from T:
+
+ -- every static data member of class T;
+
+ -- every member of class T that is itself a type;
+
+ -- every enumerator of every member of class T that is an
+ enumerated type;
+
+ -- every member of every anonymous union that is a member of
+ class T.
+
+ (Non-static data members were also forbidden to have the same
+ name as T until TC1.) */
+ if ((TREE_CODE (x) == VAR_DECL
+ || TREE_CODE (x) == CONST_DECL
+ || (TREE_CODE (x) == TYPE_DECL
+ && !DECL_SELF_REFERENCE_P (x))
+ /* A data member of an anonymous union. */
+ || (TREE_CODE (x) == FIELD_DECL
+ && DECL_CONTEXT (x) != current_class_type))
+ && DECL_NAME (x) == constructor_name (current_class_type))
+ {
+ tree scope = context_for_name_lookup (x);
+ if (TYPE_P (scope) && same_type_p (scope, current_class_type))
+ {
+ error ("`%D' has the same name as the class in which it is declared",
+ x);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
+ }
+ }
+
+ /* If this declaration shadows a declaration from an enclosing
+ class, then we will need to restore IDENTIFIER_CLASS_VALUE when
+ we leave this class. Record the shadowed declaration here. */
+ binding = IDENTIFIER_BINDING (name);
+ if (binding && binding->value)
+ {
+ tree bval = binding->value;
+ tree old_decl = NULL_TREE;
+
+ if (INHERITED_VALUE_BINDING_P (binding))
+ {
+ /* If the old binding was from a base class, and was for a
+ tag name, slide it over to make room for the new binding.
+ The old binding is still visible if explicitly qualified
+ with a class-key. */
+ if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval)
+ && !(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)))
+ {
+ old_decl = binding->type;
+ binding->type = bval;
+ binding->value = NULL_TREE;
+ INHERITED_VALUE_BINDING_P (binding) = 0;
+ }
+ else
+ old_decl = bval;
+ }
+ else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval))
+ old_decl = bval;
+ else if (TREE_CODE (x) == USING_DECL && TREE_CODE (bval) == USING_DECL)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+ else if (TREE_CODE (x) == USING_DECL && is_overloaded_fn (bval))
+ old_decl = bval;
+ else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+
+ if (old_decl)
+ {
+ tree shadow;
+
+ /* Find the previous binding of name on the class-shadowed
+ list, and update it. */
+ for (shadow = class_binding_level->class_shadowed;
+ shadow;
+ shadow = TREE_CHAIN (shadow))
+ if (TREE_PURPOSE (shadow) == name
+ && TREE_TYPE (shadow) == old_decl)
+ {
+ binding->value = x;
+ INHERITED_VALUE_BINDING_P (binding) = 0;
+ TREE_TYPE (shadow) = x;
+ IDENTIFIER_CLASS_VALUE (name) = x;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+ }
+ }
+ }
+
+ /* If we didn't replace an existing binding, put the binding on the
+ stack of bindings for the identifier, and update the shadowed list. */
+ if (push_class_binding (name, x))
+ {
+ class_binding_level->class_shadowed
+ = tree_cons (name, NULL,
+ class_binding_level->class_shadowed);
+ /* Record the value we are binding NAME to so that we can know
+ what to pop later. */
+ TREE_TYPE (class_binding_level->class_shadowed) = x;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true);
+ }
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
+}
+
+tree
+do_class_using_decl (tree decl)
+{
+ tree name, value, scope, type;
+
+ if (TREE_CODE (decl) != SCOPE_REF
+ || !TREE_OPERAND (decl, 0)
+ || !TYPE_P (TREE_OPERAND (decl, 0)))
+ {
+ error ("using-declaration for non-member at class scope");
+ return NULL_TREE;
+ }
+ scope = TREE_OPERAND (decl, 0);
+ name = TREE_OPERAND (decl, 1);
+ if (TREE_CODE (name) == BIT_NOT_EXPR)
+ {
+ error ("using-declaration cannot name destructor");
+ return NULL_TREE;
+ }
+ if (TREE_CODE (name) == TYPE_DECL)
+ name = DECL_NAME (name);
+ else if (TREE_CODE (name) == TEMPLATE_DECL)
+ name = DECL_NAME (name);
+ else if (BASELINK_P (name))
+ {
+ tree fns = BASELINK_FUNCTIONS (name);
+ name = DECL_NAME (get_first_fn (fns));
+ }
+
+ my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716);
+
+ /* Dependent using decls have a NULL type, non-dependent ones have a
+ void type. */
+ type = dependent_type_p (scope) ? NULL_TREE : void_type_node;
+ value = build_lang_decl (USING_DECL, name, type);
+ DECL_INITIAL (value) = scope;
+ return value;
+}
+
+void
+set_class_shadows (tree shadows)
+{
+ class_binding_level->class_shadowed = shadows;
+}
+
+/* Return the binding value for name in scope. */
+
+tree
+namespace_binding (tree name, tree scope)
+{
+ cxx_binding *binding;
+
+ if (scope == NULL)
+ scope = global_namespace;
+ scope = ORIGINAL_NAMESPACE (scope);
+ binding = cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+
+ return binding ? binding->value : NULL_TREE;
+}
+
+/* Set the binding value for name in scope. */
+
+void
+set_namespace_binding (tree name, tree scope, tree val)
+{
+ cxx_binding *b;
+
+ timevar_push (TV_NAME_LOOKUP);
+ if (scope == NULL_TREE)
+ scope = global_namespace;
+ b = binding_for_name (NAMESPACE_LEVEL (scope), name);
+ if (!b->value || TREE_CODE (val) == OVERLOAD || val == error_mark_node)
+ b->value = val;
+ else
+ supplement_binding (b, val);
+ timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Compute the namespace where a declaration is defined. */
+
+static tree
+decl_namespace (tree decl)
+{
+ timevar_push (TV_NAME_LOOKUP);
+ if (TYPE_P (decl))
+ decl = TYPE_STUB_DECL (decl);
+ while (DECL_CONTEXT (decl))
+ {
+ decl = DECL_CONTEXT (decl);
+ if (TREE_CODE (decl) == NAMESPACE_DECL)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
+ if (TYPE_P (decl))
+ decl = TYPE_STUB_DECL (decl);
+ my_friendly_assert (DECL_P (decl), 390);
+ }
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, global_namespace);
+}
+
+/* Set the context of a declaration to scope. Complain if we are not
+ outside scope. */
+
+void
+set_decl_namespace (tree decl, tree scope, bool friendp)
+{
+ tree old;
+
+ /* Get rid of namespace aliases. */
+ scope = ORIGINAL_NAMESPACE (scope);
+
+ /* It is ok for friends to be qualified in parallel space. */
+ if (!friendp && !is_ancestor (current_namespace, scope))
+ error ("declaration of `%D' not in a namespace surrounding `%D'",
+ decl, scope);
+ DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
+ if (scope != current_namespace)
+ {
+ /* See whether this has been declared in the namespace. */
+ old = namespace_binding (DECL_NAME (decl), scope);
+ if (!old)
+ /* No old declaration at all. */
+ goto complain;
+ /* A template can be explicitly specialized in any namespace. */
+ if (processing_explicit_instantiation)
+ return;
+ if (!is_overloaded_fn (decl))
+ /* Don't compare non-function decls with decls_match here,
+ since it can't check for the correct constness at this
+ point. pushdecl will find those errors later. */
+ return;
+ /* Since decl is a function, old should contain a function decl. */
+ if (!is_overloaded_fn (old))
+ goto complain;
+ if (processing_template_decl || processing_specialization)
+ /* We have not yet called push_template_decl to turn a
+ FUNCTION_DECL into a TEMPLATE_DECL, so the declarations
+ won't match. But, we'll check later, when we construct the
+ template. */
+ return;
+ if (is_overloaded_fn (old))
+ {
+ for (; old; old = OVL_NEXT (old))
+ if (decls_match (decl, OVL_CURRENT (old)))
+ return;
+ }
+ else
+ if (decls_match (decl, old))
+ return;
+ }
+ else
+ return;
+ complain:
+ error ("`%D' should have been declared inside `%D'",
+ decl, scope);
+}
+
+/* Return the namespace where the current declaration is declared. */
+
+tree
+current_decl_namespace (void)
+{
+ tree result;
+ /* If we have been pushed into a different namespace, use it. */
+ if (decl_namespace_list)
+ return TREE_PURPOSE (decl_namespace_list);
+
+ if (current_class_type)
+ result = decl_namespace (TYPE_STUB_DECL (current_class_type));
+ else if (current_function_decl)
+ result = decl_namespace (current_function_decl);
+ else
+ result = current_namespace;
+ return result;
+}
+
+/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we
+ select a name that is unique to this compilation unit. */
+
+void
+push_namespace (tree name)
+{
+ tree d = NULL_TREE;
+ int need_new = 1;
+ int implicit_use = 0;
+ bool anon = !name;
+
+ timevar_push (TV_NAME_LOOKUP);
+
+ /* We should not get here if the global_namespace is not yet constructed
+ nor if NAME designates the global namespace: The global scope is
+ constructed elsewhere. */
+ my_friendly_assert (global_namespace != NULL && name != global_scope_name,
+ 20030531);
+
+ if (anon)
+ {
+ /* The name of anonymous namespace is unique for the translation
+ unit. */
+ if (!anonymous_namespace_name)
+ anonymous_namespace_name = get_file_function_name ('N');
+ name = anonymous_namespace_name;
+ d = IDENTIFIER_NAMESPACE_VALUE (name);
+ if (d)
+ /* Reopening anonymous namespace. */
+ need_new = 0;
+ implicit_use = 1;
+ }
+ else
+ {
+ /* Check whether this is an extended namespace definition. */
+ d = IDENTIFIER_NAMESPACE_VALUE (name);
+ if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL)
+ {
+ need_new = 0;
+ if (DECL_NAMESPACE_ALIAS (d))
+ {
+ error ("namespace alias `%D' not allowed here, assuming `%D'",
+ d, DECL_NAMESPACE_ALIAS (d));
+ d = DECL_NAMESPACE_ALIAS (d);
+ }
+ }
+ }
+
+ if (need_new)
+ {
+ /* Make a new namespace, binding the name to it. */
+ d = build_lang_decl (NAMESPACE_DECL, name, void_type_node);
+ DECL_CONTEXT (d) = FROB_CONTEXT (current_namespace);
+ d = pushdecl (d);
+ if (anon)
+ {
+ /* Clear DECL_NAME for the benefit of debugging back ends. */
+ SET_DECL_ASSEMBLER_NAME (d, name);
+ DECL_NAME (d) = NULL_TREE;
+ }
+ begin_scope (sk_namespace, d);
+ }
+ else
+ resume_scope (NAMESPACE_LEVEL (d));
+
+ if (implicit_use)
+ do_using_directive (d);
+ /* Enter the name space. */
+ current_namespace = d;
+
+ timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Pop from the scope of the current namespace. */
+
+void
+pop_namespace (void)
+{
+ my_friendly_assert (current_namespace != global_namespace, 20010801);
+ current_namespace = CP_DECL_CONTEXT (current_namespace);
+ /* The binding level is not popped, as it might be re-opened later. */
+ leave_scope ();
+}
+
+/* Push into the scope of the namespace NS, even if it is deeply
+ nested within another namespace. */
+
+void
+push_nested_namespace (tree ns)
+{
+ if (ns == global_namespace)
+ push_to_top_level ();
+ else
+ {
+ push_nested_namespace (CP_DECL_CONTEXT (ns));
+ push_namespace (DECL_NAME (ns));
+ }
+}
+
+/* Pop back from the scope of the namespace NS, which was previously
+ entered with push_nested_namespace. */
+
+void
+pop_nested_namespace (tree ns)
+{
+ timevar_push (TV_NAME_LOOKUP);
+ while (ns != global_namespace)
+ {
+ pop_namespace ();
+ ns = CP_DECL_CONTEXT (ns);
+ }
+
+ pop_from_top_level ();
+ timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Temporarily set the namespace for the current declaration. */
+
+void
+push_decl_namespace (tree decl)
+{
+ if (TREE_CODE (decl) != NAMESPACE_DECL)
+ decl = decl_namespace (decl);
+ decl_namespace_list = tree_cons (ORIGINAL_NAMESPACE (decl),
+ NULL_TREE, decl_namespace_list);
+}
+
+/* [namespace.memdef]/2 */
+
+void
+pop_decl_namespace (void)
+{
+ decl_namespace_list = TREE_CHAIN (decl_namespace_list);
+}
+
+/* Return the namespace that is the common ancestor
+ of two given namespaces. */
+
+static tree
+namespace_ancestor (tree ns1, tree ns2)
+{
+ timevar_push (TV_NAME_LOOKUP);
+ if (is_ancestor (ns1, ns2))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ns1);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
+ namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2));
+}
+
+/* Process a namespace-alias declaration. */
+
+void
+do_namespace_alias (tree alias, tree namespace)
+{
+ if (TREE_CODE (namespace) != NAMESPACE_DECL)
+ {
+ /* The parser did not find it, so it's not there. */
+ error ("unknown namespace `%D'", namespace);
+ return;
+ }
+
+ namespace = ORIGINAL_NAMESPACE (namespace);
+
+ /* Build the alias. */
+ alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
+ DECL_NAMESPACE_ALIAS (alias) = namespace;
+ DECL_EXTERNAL (alias) = 1;
+ pushdecl (alias);
+}
+
+/* Like pushdecl, only it places X in the current namespace,
+ if appropriate. */
+
+tree
+pushdecl_namespace_level (tree x)
+{
+ struct cp_binding_level *b = current_binding_level;
+ tree t;
+
+ timevar_push (TV_NAME_LOOKUP);
+ t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace));
+
+ /* Now, the type_shadowed stack may screw us. Munge it so it does
+ what we want. */
+ if (TREE_CODE (x) == TYPE_DECL)
+ {
+ tree name = DECL_NAME (x);
+ tree newval;
+ tree *ptr = (tree *)0;
+ for (; !global_scope_p (b); b = b->level_chain)
+ {
+ tree shadowed = b->type_shadowed;
+ for (; shadowed; shadowed = TREE_CHAIN (shadowed))
+ if (TREE_PURPOSE (shadowed) == name)
+ {
+ ptr = &TREE_VALUE (shadowed);
+ /* Can't break out of the loop here because sometimes
+ a binding level will have duplicate bindings for
+ PT names. It's gross, but I haven't time to fix it. */
+ }
+ }
+ newval = TREE_TYPE (x);
+ if (ptr == (tree *)0)
+ {
+ /* @@ This shouldn't be needed. My test case "zstring.cc" trips
+ up here if this is changed to an assertion. --KR */
+ SET_IDENTIFIER_TYPE_VALUE (name, x);
+ }
+ else
+ {
+ *ptr = newval;
+ }
+ }
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+}
+
+/* Insert USED into the using list of USER. Set INDIRECT_flag if this
+ directive is not directly from the source. Also find the common
+ ancestor and let our users know about the new namespace */
+static void
+add_using_namespace (tree user, tree used, bool indirect)
+{
+ tree t;
+ timevar_push (TV_NAME_LOOKUP);
+ /* Using oneself is a no-op. */
+ if (user == used)
+ {
+ timevar_pop (TV_NAME_LOOKUP);
+ return;
+ }
+ my_friendly_assert (TREE_CODE (user) == NAMESPACE_DECL, 380);
+ my_friendly_assert (TREE_CODE (used) == NAMESPACE_DECL, 380);
+ /* Check if we already have this. */
+ t = purpose_member (used, DECL_NAMESPACE_USING (user));
+ if (t != NULL_TREE)
+ {
+ if (!indirect)
+ /* Promote to direct usage. */
+ TREE_INDIRECT_USING (t) = 0;
+ timevar_pop (TV_NAME_LOOKUP);
+ return;
+ }
+
+ /* Add used to the user's using list. */
+ DECL_NAMESPACE_USING (user)
+ = tree_cons (used, namespace_ancestor (user, used),
+ DECL_NAMESPACE_USING (user));
+
+ TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
+
+ /* Add user to the used's users list. */
+ DECL_NAMESPACE_USERS (used)
+ = tree_cons (user, 0, DECL_NAMESPACE_USERS (used));
+
+ /* Recursively add all namespaces used. */
+ for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t))
+ /* indirect usage */
+ add_using_namespace (user, TREE_PURPOSE (t), 1);
+
+ /* Tell everyone using us about the new used namespaces. */
+ for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t))
+ add_using_namespace (TREE_PURPOSE (t), used, 1);
+ timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Process a using-declaration not appearing in class or local scope. */
+
+void
+do_toplevel_using_decl (tree decl, tree scope, tree name)
+{
+ tree oldval, oldtype, newval, newtype;
+ cxx_binding *binding;
+
+ decl = validate_nonmember_using_decl (decl, scope, name);
+ if (decl == NULL_TREE)
+ return;
+
+ binding = binding_for_name (NAMESPACE_LEVEL (current_namespace), name);
+
+ oldval = binding->value;
+ oldtype = binding->type;
+
+ do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
+
+ /* Copy declarations found. */
+ if (newval)
+ binding->value = newval;
+ if (newtype)
+ binding->type = newtype;
+ return;
+}
+
+/* Process a using-directive. */
+
+void
+do_using_directive (tree namespace)
+{
+ if (building_stmt_tree ())
+ add_stmt (build_stmt (USING_STMT, namespace));
+
+ /* using namespace A::B::C; */
+ if (TREE_CODE (namespace) == SCOPE_REF)
+ namespace = TREE_OPERAND (namespace, 1);
+ if (TREE_CODE (namespace) == IDENTIFIER_NODE)
+ {
+ /* Lookup in lexer did not find a namespace. */
+ if (!processing_template_decl)
+ error ("namespace `%T' undeclared", namespace);
+ return;
+ }
+ if (TREE_CODE (namespace) != NAMESPACE_DECL)
+ {
+ if (!processing_template_decl)
+ error ("`%T' is not a namespace", namespace);
+ return;
+ }
+ namespace = ORIGINAL_NAMESPACE (namespace);
+ if (!toplevel_bindings_p ())
+ push_using_directive (namespace);
+ else
+ /* direct usage */
+ add_using_namespace (current_namespace, namespace, 0);
+}
+
+/* Deal with a using-directive seen by the parser. Currently we only
+ handle attributes here, since they cannot appear inside a template. */
+
+void
+parse_using_directive (tree namespace, tree attribs)
+{
+ tree a;
+
+ do_using_directive (namespace);
+
+ for (a = attribs; a; a = TREE_CHAIN (a))
+ {
+ tree name = TREE_PURPOSE (a);
+ if (is_attribute_p ("strong", name))
+ {
+ if (!toplevel_bindings_p ())
+ error ("strong using only meaningful at namespace scope");
+ else
+ DECL_NAMESPACE_ASSOCIATIONS (namespace)
+ = tree_cons (current_namespace, 0,
+ DECL_NAMESPACE_ASSOCIATIONS (namespace));
+ }
+ else
+ warning ("`%D' attribute directive ignored", name);
+ }
+}
+
+/* Like pushdecl, only it places X in the global scope if appropriate.
+ Calls cp_finish_decl to register the variable, initializing it with
+ *INIT, if INIT is non-NULL. */
+
+static tree
+pushdecl_top_level_1 (tree x, tree *init)
+{
+ timevar_push (TV_NAME_LOOKUP);
+ push_to_top_level ();
+ x = pushdecl_namespace_level (x);
+ if (init)
+ cp_finish_decl (x, *init, NULL_TREE, 0);
+ pop_from_top_level ();
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
+}
+
+/* Like pushdecl, only it places X in the global scope if appropriate. */
+
+tree
+pushdecl_top_level (tree x)
+{
+ return pushdecl_top_level_1 (x, NULL);
+}
+
+/* Like pushdecl, only it places X in the global scope if
+ appropriate. Calls cp_finish_decl to register the variable,
+ initializing it with INIT. */
+
+tree
+pushdecl_top_level_and_finish (tree x, tree init)
+{
+ return pushdecl_top_level_1 (x, &init);
+}
+
+/* Combines two sets of overloaded functions into an OVERLOAD chain, removing
+ duplicates. The first list becomes the tail of the result.
+
+ The algorithm is O(n^2). We could get this down to O(n log n) by
+ doing a sort on the addresses of the functions, if that becomes
+ necessary. */
+
+static tree
+merge_functions (tree s1, tree s2)
+{
+ for (; s2; s2 = OVL_NEXT (s2))
+ {
+ tree fn2 = OVL_CURRENT (s2);
+ tree fns1;
+
+ for (fns1 = s1; fns1; fns1 = OVL_NEXT (fns1))
+ {
+ tree fn1 = OVL_CURRENT (fns1);
+
+ /* If the function from S2 is already in S1, there is no
+ need to add it again. For `extern "C"' functions, we
+ might have two FUNCTION_DECLs for the same function, in
+ different namespaces; again, we only need one of them. */
+ if (fn1 == fn2
+ || (DECL_EXTERN_C_P (fn1) && DECL_EXTERN_C_P (fn2)
+ && DECL_NAME (fn1) == DECL_NAME (fn2)))
+ break;
+ }
+
+ /* If we exhausted all of the functions in S1, FN2 is new. */
+ if (!fns1)
+ s1 = build_overload (fn2, s1);
+ }
+ return s1;
+}
+
+/* This should return an error not all definitions define functions.
+ It is not an error if we find two functions with exactly the
+ same signature, only if these are selected in overload resolution.
+ old is the current set of bindings, new the freshly-found binding.
+ XXX Do we want to give *all* candidates in case of ambiguity?
+ XXX In what way should I treat extern declarations?
+ XXX I don't want to repeat the entire duplicate_decls here */
+
+static cxx_binding *
+ambiguous_decl (tree name, cxx_binding *old, cxx_binding *new, int flags)
+{
+ tree val, type;
+ my_friendly_assert (old != NULL, 393);
+ /* Copy the value. */
+ val = new->value;
+ if (val)
+ switch (TREE_CODE (val))
+ {
+ case TEMPLATE_DECL:
+ /* If we expect types or namespaces, and not templates,
+ or this is not a template class. */
+ if (LOOKUP_QUALIFIERS_ONLY (flags)
+ && !DECL_CLASS_TEMPLATE_P (val))
+ val = NULL_TREE;
+ break;
+ case TYPE_DECL:
+ if (LOOKUP_NAMESPACES_ONLY (flags))
+ val = NULL_TREE;
+ break;
+ case NAMESPACE_DECL:
+ if (LOOKUP_TYPES_ONLY (flags))
+ val = NULL_TREE;
+ break;
+ case FUNCTION_DECL:
+ /* Ignore built-in functions that are still anticipated. */
+ if (LOOKUP_QUALIFIERS_ONLY (flags) || DECL_ANTICIPATED (val))
+ val = NULL_TREE;
+ break;
+ default:
+ if (LOOKUP_QUALIFIERS_ONLY (flags))
+ val = NULL_TREE;
+ }
+
+ if (!old->value)
+ old->value = val;
+ else if (val && val != old->value)
+ {
+ if (is_overloaded_fn (old->value) && is_overloaded_fn (val))
+ old->value = merge_functions (old->value, val);
+ else
+ {
+ /* Some declarations are functions, some are not. */
+ if (flags & LOOKUP_COMPLAIN)
+ {
+ /* If we've already given this error for this lookup,
+ old->value is error_mark_node, so let's not
+ repeat ourselves. */
+ if (old->value != error_mark_node)
+ {
+ error ("use of `%D' is ambiguous", name);
+ cp_error_at (" first declared as `%#D' here",
+ old->value);
+ }
+ cp_error_at (" also declared as `%#D' here", val);
+ }
+ old->value = error_mark_node;
+ }
+ }
+ /* ... and copy the type. */
+ type = new->type;
+ if (LOOKUP_NAMESPACES_ONLY (flags))
+ type = NULL_TREE;
+ if (!old->type)
+ old->type = type;
+ else if (type && old->type != type)
+ {
+ if (flags & LOOKUP_COMPLAIN)
+ {
+ error ("`%D' denotes an ambiguous type",name);
+ error ("%J first type here", TYPE_MAIN_DECL (old->type));
+ error ("%J other type here", TYPE_MAIN_DECL (type));
+ }
+ }
+ return old;
+}
+
+/* Return the declarations that are members of the namespace NS. */
+
+tree
+cp_namespace_decls (tree ns)
+{
+ return NAMESPACE_LEVEL (ns)->names;
+}
+
+/* Combine prefer_type and namespaces_only into flags. */
+
+static int
+lookup_flags (int prefer_type, int namespaces_only)
+{
+ if (namespaces_only)
+ return LOOKUP_PREFER_NAMESPACES;
+ if (prefer_type > 1)
+ return LOOKUP_PREFER_TYPES;
+ if (prefer_type > 0)
+ return LOOKUP_PREFER_BOTH;
+ return 0;
+}
+
+/* Given a lookup that returned VAL, use FLAGS to decide if we want to
+ ignore it or not. Subroutine of lookup_name_real. */
+
+static tree
+qualify_lookup (tree val, int flags)
+{
+ if (val == NULL_TREE)
+ return val;
+ if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL)
+ return val;
+ if ((flags & LOOKUP_PREFER_TYPES)
+ && (TREE_CODE (val) == TYPE_DECL || TREE_CODE (val) == TEMPLATE_DECL))
+ return val;
+ if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES))
+ return NULL_TREE;
+ return val;
+}
+
+/* Look up NAME in the NAMESPACE. */
+
+tree
+lookup_namespace_name (tree namespace, tree name)
+{
+ tree val;
+ tree template_id = NULL_TREE;
+ cxx_binding binding;
+
+ timevar_push (TV_NAME_LOOKUP);
+ my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370);
+
+ if (TREE_CODE (name) == NAMESPACE_DECL)
+ /* This happens for A::B<int> when B is a namespace. */
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, name);
+ else if (TREE_CODE (name) == TEMPLATE_DECL)
+ {
+ /* This happens for A::B where B is a template, and there are no
+ template arguments. */
+ error ("invalid use of `%D'", name);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ }
+
+ namespace = ORIGINAL_NAMESPACE (namespace);
+
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ {
+ template_id = name;
+ name = TREE_OPERAND (name, 0);
+ if (TREE_CODE (name) == OVERLOAD)
+ name = DECL_NAME (OVL_CURRENT (name));
+ else if (DECL_P (name))
+ name = DECL_NAME (name);
+ }
+
+ my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373);
+
+ cxx_binding_clear (&binding);
+ if (!qualified_lookup_using_namespace (name, namespace, &binding, 0))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+
+ if (binding.value)
+ {
+ val = binding.value;
+
+ if (template_id)
+ {
+ if (DECL_CLASS_TEMPLATE_P (val))
+ val = lookup_template_class (val,
+ TREE_OPERAND (template_id, 1),
+ /*in_decl=*/NULL_TREE,
+ /*context=*/NULL_TREE,
+ /*entering_scope=*/0,
+ tf_error | tf_warning);
+ else if (DECL_FUNCTION_TEMPLATE_P (val)
+ || TREE_CODE (val) == OVERLOAD)
+ val = lookup_template_function (val,
+ TREE_OPERAND (template_id, 1));
+ else
+ {
+ error ("`%D::%D' is not a template",
+ namespace, name);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ }
+ }
+
+ /* If we have a single function from a using decl, pull it out. */
+ if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
+ val = OVL_FUNCTION (val);
+
+ /* Ignore built-in functions that haven't been prototyped yet. */
+ if (!val || !DECL_P(val)
+ || !DECL_LANG_SPECIFIC(val)
+ || !DECL_ANTICIPATED (val))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+ }
+
+ error ("`%D' undeclared in namespace `%D'", name, namespace);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+}
+
+/* Select the right _DECL from multiple choices. */
+
+static tree
+select_decl (cxx_binding *binding, int flags)
+{
+ tree val;
+ val = binding->value;
+
+ timevar_push (TV_NAME_LOOKUP);
+ if (LOOKUP_NAMESPACES_ONLY (flags))
+ {
+ /* We are not interested in types. */
+ if (val && TREE_CODE (val) == NAMESPACE_DECL)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ }
+
+ /* If looking for a type, or if there is no non-type binding, select
+ the value binding. */
+ if (binding->type && (!val || (flags & LOOKUP_PREFER_TYPES)))
+ val = binding->type;
+ /* Don't return non-types if we really prefer types. */
+ else if (val && LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL
+ && (TREE_CODE (val) != TEMPLATE_DECL
+ || !DECL_CLASS_TEMPLATE_P (val)))
+ val = NULL_TREE;
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+}
+
+/* Unscoped lookup of a global: iterate over current namespaces,
+ considering using-directives. */
+
+static tree
+unqualified_namespace_lookup (tree name, int flags)
+{
+ tree initial = current_decl_namespace ();
+ tree scope = initial;
+ tree siter;
+ struct cp_binding_level *level;
+ tree val = NULL_TREE;
+ cxx_binding binding;
+
+ timevar_push (TV_NAME_LOOKUP);
+ cxx_binding_clear (&binding);
+
+ for (; !val; scope = CP_DECL_CONTEXT (scope))
+ {
+ cxx_binding *b =
+ cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+
+ if (b)
+ {
+ if (b->value && DECL_P (b->value)
+ && DECL_LANG_SPECIFIC (b->value)
+ && DECL_ANTICIPATED (b->value))
+ /* Ignore anticipated built-in functions. */
+ ;
+ else
+ binding.value = b->value;
+ binding.type = b->type;
+ }
+
+ /* Add all _DECLs seen through local using-directives. */
+ for (level = current_binding_level;
+ level->kind != sk_namespace;
+ level = level->level_chain)
+ if (!lookup_using_namespace (name, &binding, level->using_directives,
+ scope, flags))
+ /* Give up because of error. */
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+
+ /* Add all _DECLs seen through global using-directives. */
+ /* XXX local and global using lists should work equally. */
+ siter = initial;
+ while (1)
+ {
+ if (!lookup_using_namespace (name, &binding,
+ DECL_NAMESPACE_USING (siter),
+ scope, flags))
+ /* Give up because of error. */
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ if (siter == scope) break;
+ siter = CP_DECL_CONTEXT (siter);
+ }
+
+ val = select_decl (&binding, flags);
+ if (scope == global_namespace)
+ break;
+ }
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+}
+
+/* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL
+ or a class TYPE). If IS_TYPE_P is TRUE, then ignore non-type
+ bindings.
+
+ Returns a DECL (or OVERLOAD, or BASELINK) representing the
+ declaration found. If no suitable declaration can be found,
+ ERROR_MARK_NODE is returned. Iif COMPLAIN is true and SCOPE is
+ neither a class-type nor a namespace a diagnostic is issued. */
+
+tree
+lookup_qualified_name (tree scope, tree name, bool is_type_p, bool complain)
+{
+ int flags = 0;
+
+ if (TREE_CODE (scope) == NAMESPACE_DECL)
+ {
+ cxx_binding binding;
+
+ cxx_binding_clear (&binding);
+ flags |= LOOKUP_COMPLAIN;
+ if (is_type_p)
+ flags |= LOOKUP_PREFER_TYPES;
+ if (qualified_lookup_using_namespace (name, scope, &binding, flags))
+ return select_decl (&binding, flags);
+ }
+ else if (is_aggr_type (scope, complain))
+ {
+ tree t;
+ t = lookup_member (scope, name, 0, is_type_p);
+ if (t)
+ return t;
+ }
+
+ return error_mark_node;
+}
+
+/* Subroutine of unqualified_namespace_lookup:
+ Add the bindings of NAME in used namespaces to VAL.
+ We are currently looking for names in namespace SCOPE, so we
+ look through USINGS for using-directives of namespaces
+ which have SCOPE as a common ancestor with the current scope.
+ Returns false on errors. */
+
+static bool
+lookup_using_namespace (tree name, cxx_binding *val, tree usings, tree scope,
+ int flags)
+{
+ tree iter;
+ timevar_push (TV_NAME_LOOKUP);
+ /* Iterate over all used namespaces in current, searching for using
+ directives of scope. */
+ for (iter = usings; iter; iter = TREE_CHAIN (iter))
+ if (TREE_VALUE (iter) == scope)
+ {
+ tree used = ORIGINAL_NAMESPACE (TREE_PURPOSE (iter));
+ cxx_binding *val1 =
+ cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (used), name);
+ /* Resolve ambiguities. */
+ if (val1)
+ val = ambiguous_decl (name, val, val1, flags);
+ }
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
+}
+
+/* [namespace.qual]
+ Accepts the NAME to lookup and its qualifying SCOPE.
+ Returns the name/type pair found into the cxx_binding *RESULT,
+ or false on error. */
+
+static bool
+qualified_lookup_using_namespace (tree name, tree scope, cxx_binding *result,
+ int flags)
+{
+ /* Maintain a list of namespaces visited... */
+ tree seen = NULL_TREE;
+ /* ... and a list of namespace yet to see. */
+ tree todo = NULL_TREE;
+ tree todo_maybe = NULL_TREE;
+ tree usings;
+ timevar_push (TV_NAME_LOOKUP);
+ /* Look through namespace aliases. */
+ scope = ORIGINAL_NAMESPACE (scope);
+ while (scope && result->value != error_mark_node)
+ {
+ cxx_binding *binding =
+ cxx_scope_find_binding_for_name (NAMESPACE_LEVEL (scope), name);
+ seen = tree_cons (scope, NULL_TREE, seen);
+ if (binding)
+ result = ambiguous_decl (name, result, binding, flags);
+
+ /* Consider strong using directives always, and non-strong ones
+ if we haven't found a binding yet. ??? Shouldn't we consider
+ non-strong ones if the initial RESULT is non-NULL, but the
+ binding in the given namespace is? */
+ for (usings = DECL_NAMESPACE_USING (scope); usings;
+ usings = TREE_CHAIN (usings))
+ /* If this was a real directive, and we have not seen it. */
+ if (!TREE_INDIRECT_USING (usings))
+ {
+ /* Try to avoid queuing the same namespace more than once,
+ the exception being when a namespace was already
+ enqueued for todo_maybe and then a strong using is
+ found for it. We could try to remove it from
+ todo_maybe, but it's probably not worth the effort. */
+ if (is_associated_namespace (scope, TREE_PURPOSE (usings))
+ && !purpose_member (TREE_PURPOSE (usings), seen)
+ && !purpose_member (TREE_PURPOSE (usings), todo))
+ todo = tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo);
+ else if ((!result->value && !result->type)
+ && !purpose_member (TREE_PURPOSE (usings), seen)
+ && !purpose_member (TREE_PURPOSE (usings), todo)
+ && !purpose_member (TREE_PURPOSE (usings), todo_maybe))
+ todo_maybe = tree_cons (TREE_PURPOSE (usings), NULL_TREE,
+ todo_maybe);
+ }
+ if (todo)
+ {
+ scope = TREE_PURPOSE (todo);
+ todo = TREE_CHAIN (todo);
+ }
+ else if (todo_maybe
+ && (!result->value && !result->type))
+ {
+ scope = TREE_PURPOSE (todo_maybe);
+ todo = TREE_CHAIN (todo_maybe);
+ todo_maybe = NULL_TREE;
+ }
+ else
+ scope = NULL_TREE; /* If there never was a todo list. */
+ }
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node);
+}
+
+/* Look up NAME in the current binding level and its superiors in the
+ namespace of variables, functions and typedefs. Return a ..._DECL
+ node of some kind representing its definition if there is only one
+ such declaration, or return a TREE_LIST with all the overloaded
+ definitions if there are many, or return 0 if it is undefined.
+
+ If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces.
+ If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces).
+ Otherwise we prefer non-TYPE_DECLs.
+
+ If NONCLASS is nonzero, we don't look for the NAME in class scope,
+ using IDENTIFIER_CLASS_VALUE. */
+
+tree
+lookup_name_real (tree name, int prefer_type, int nonclass,
+ int namespaces_only, int flags)
+{
+ cxx_binding *iter;
+ tree val = NULL_TREE;
+
+ timevar_push (TV_NAME_LOOKUP);
+ /* Conversion operators are handled specially because ordinary
+ unqualified name lookup will not find template conversion
+ operators. */
+ if (IDENTIFIER_TYPENAME_P (name))
+ {
+ struct cp_binding_level *level;
+
+ for (level = current_binding_level;
+ level && level->kind != sk_namespace;
+ level = level->level_chain)
+ {
+ tree class_type;
+ tree operators;
+
+ /* A conversion operator can only be declared in a class
+ scope. */
+ if (level->kind != sk_class)
+ continue;
+
+ /* Lookup the conversion operator in the class. */
+ class_type = level->this_entity;
+ operators = lookup_fnfields (class_type, name, /*protect=*/0);
+ if (operators)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators);
+ }
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+ }
+
+ flags |= lookup_flags (prefer_type, namespaces_only);
+
+ /* First, look in non-namespace scopes. */
+
+ if (current_class_type == NULL_TREE)
+ nonclass = 1;
+
+ for (iter = IDENTIFIER_BINDING (name); iter; iter = iter->previous)
+ {
+ tree binding;
+
+ if (!LOCAL_BINDING_P (iter) && nonclass)
+ /* We're not looking for class-scoped bindings, so keep going. */
+ continue;
+
+ /* If this is the kind of thing we're looking for, we're done. */
+ if (qualify_lookup (iter->value, flags))
+ binding = iter->value;
+ else if ((flags & LOOKUP_PREFER_TYPES)
+ && qualify_lookup (iter->type, flags))
+ binding = iter->type;
+ else
+ binding = NULL_TREE;
+
+ if (binding)
+ {
+ val = binding;
+ break;
+ }
+ }
+
+ /* Now lookup in namespace scopes. */
+ if (!val)
+ {
+ tree t = unqualified_namespace_lookup (name, flags);
+ if (t)
+ val = t;
+ }
+
+ if (val)
+ {
+ /* If we have a single function from a using decl, pull it out. */
+ if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val))
+ val = OVL_FUNCTION (val);
+ }
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
+}
+
+tree
+lookup_name_nonclass (tree name)
+{
+ return lookup_name_real (name, 0, 1, 0, LOOKUP_COMPLAIN);
+}
+
+tree
+lookup_function_nonclass (tree name, tree args)
+{
+ return lookup_arg_dependent (name, lookup_name_nonclass (name), args);
+}
+
+tree
+lookup_name (tree name, int prefer_type)
+{
+ return lookup_name_real (name, prefer_type, 0, 0, LOOKUP_COMPLAIN);
+}
+
+/* Similar to `lookup_name' but look only in the innermost non-class
+ binding level. */
+
+static tree
+lookup_name_current_level (tree name)
+{
+ struct cp_binding_level *b;
+ tree t = NULL_TREE;
+
+ timevar_push (TV_NAME_LOOKUP);
+ b = innermost_nonclass_level ();
+
+ if (b->kind == sk_namespace)
+ {
+ t = IDENTIFIER_NAMESPACE_VALUE (name);
+
+ /* extern "C" function() */
+ if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST)
+ t = TREE_VALUE (t);
+ }
+ else if (IDENTIFIER_BINDING (name)
+ && LOCAL_BINDING_P (IDENTIFIER_BINDING (name)))
+ {
+ while (1)
+ {
+ if (IDENTIFIER_BINDING (name)->scope == b)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, IDENTIFIER_VALUE (name));
+
+ if (b->kind == sk_cleanup)
+ b = b->level_chain;
+ else
+ break;
+ }
+ }
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+}
+
+/* Like lookup_name_current_level, but for types. */
+
+static tree
+lookup_type_current_level (tree name)
+{
+ tree t = NULL_TREE;
+
+ timevar_push (TV_NAME_LOOKUP);
+ my_friendly_assert (current_binding_level->kind != sk_namespace,
+ 980716);
+
+ if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
+ && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node)
+ {
+ struct cp_binding_level *b = current_binding_level;
+ while (1)
+ {
+ if (purpose_member (name, b->type_shadowed))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
+ REAL_IDENTIFIER_TYPE_VALUE (name));
+ if (b->kind == sk_cleanup)
+ b = b->level_chain;
+ else
+ break;
+ }
+ }
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+}
+
+/* [basic.lookup.koenig] */
+/* A nonzero return value in the functions below indicates an error. */
+
+struct arg_lookup
+{
+ tree name;
+ tree namespaces;
+ tree classes;
+ tree functions;
+};
+
+static bool arg_assoc (struct arg_lookup*, tree);
+static bool arg_assoc_args (struct arg_lookup*, tree);
+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);
+static bool arg_assoc_class (struct arg_lookup *, tree);
+static bool arg_assoc_template_arg (struct arg_lookup*, tree);
+
+/* Add a function to the lookup structure.
+ Returns true on error. */
+
+static bool
+add_function (struct arg_lookup *k, tree fn)
+{
+ /* We used to check here to see if the function was already in the list,
+ but that's O(n^2), which is just too expensive for function lookup.
+ Now we deal with the occasional duplicate in joust. In doing this, we
+ assume that the number of duplicates will be small compared to the
+ total number of functions being compared, which should usually be the
+ case. */
+
+ /* We must find only functions, or exactly one non-function. */
+ if (!k->functions)
+ k->functions = fn;
+ else if (fn == k->functions)
+ ;
+ else if (is_overloaded_fn (k->functions) && is_overloaded_fn (fn))
+ k->functions = build_overload (fn, k->functions);
+ else
+ {
+ tree f1 = OVL_CURRENT (k->functions);
+ tree f2 = fn;
+ if (is_overloaded_fn (f1))
+ {
+ fn = f1; f1 = f2; f2 = fn;
+ }
+ cp_error_at ("`%D' is not a function,", f1);
+ cp_error_at (" conflict with `%D'", f2);
+ error (" in call to `%D'", k->name);
+ return true;
+ }
+
+ return false;
+}
+
+/* Returns true iff CURRENT has declared itself to be an associated
+ namespace of SCOPE via a strong using-directive (or transitive chain
+ thereof). Both are namespaces. */
+
+bool
+is_associated_namespace (tree current, tree scope)
+{
+ tree seen = NULL_TREE;
+ tree todo = NULL_TREE;
+ tree t;
+ while (1)
+ {
+ if (scope == current)
+ return true;
+ seen = tree_cons (scope, NULL_TREE, seen);
+ for (t = DECL_NAMESPACE_ASSOCIATIONS (scope); t; t = TREE_CHAIN (t))
+ if (!purpose_member (TREE_PURPOSE (t), seen))
+ todo = tree_cons (TREE_PURPOSE (t), NULL_TREE, todo);
+ if (todo)
+ {
+ scope = TREE_PURPOSE (todo);
+ todo = TREE_CHAIN (todo);
+ }
+ else
+ return false;
+ }
+}
+
+/* Add functions of a namespace to the lookup structure.
+ Returns true on error. */
+
+static bool
+arg_assoc_namespace (struct arg_lookup *k, tree scope)
+{
+ tree value;
+
+ if (purpose_member (scope, k->namespaces))
+ return 0;
+ k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces);
+
+ /* Check out our super-users. */
+ for (value = DECL_NAMESPACE_ASSOCIATIONS (scope); value;
+ value = TREE_CHAIN (value))
+ if (arg_assoc_namespace (k, TREE_PURPOSE (value)))
+ return true;
+
+ value = namespace_binding (k->name, scope);
+ if (!value)
+ return false;
+
+ for (; value; value = OVL_NEXT (value))
+ if (add_function (k, OVL_CURRENT (value)))
+ return true;
+
+ return false;
+}
+
+/* Adds everything associated with a template argument to the lookup
+ structure. Returns true on error. */
+
+static bool
+arg_assoc_template_arg (struct arg_lookup *k, tree arg)
+{
+ /* [basic.lookup.koenig]
+
+ If T is a template-id, its associated namespaces and classes are
+ ... the namespaces and classes associated with the types of the
+ template arguments provided for template type parameters
+ (excluding template template parameters); the namespaces in which
+ any template template arguments are defined; and the classes in
+ which any member templates used as template template arguments
+ are defined. [Note: non-type template arguments do not
+ contribute to the set of associated namespaces. ] */
+
+ /* Consider first template template arguments. */
+ if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE)
+ return false;
+ else if (TREE_CODE (arg) == TEMPLATE_DECL)
+ {
+ tree ctx = CP_DECL_CONTEXT (arg);
+
+ /* It's not a member template. */
+ if (TREE_CODE (ctx) == NAMESPACE_DECL)
+ return arg_assoc_namespace (k, ctx);
+ /* Otherwise, it must be member template. */
+ else
+ return arg_assoc_class (k, ctx);
+ }
+ /* It's not a template template argument, but it is a type template
+ argument. */
+ else if (TYPE_P (arg))
+ return arg_assoc_type (k, arg);
+ /* It's a non-type template argument. */
+ else
+ return false;
+}
+
+/* Adds everything associated with class to the lookup structure.
+ Returns true on error. */
+
+static bool
+arg_assoc_class (struct arg_lookup *k, tree type)
+{
+ tree list, friends, context;
+ int i;
+
+ /* Backend build structures, such as __builtin_va_list, aren't
+ affected by all this. */
+ if (!CLASS_TYPE_P (type))
+ return false;
+
+ if (purpose_member (type, k->classes))
+ return false;
+ k->classes = tree_cons (type, NULL_TREE, k->classes);
+
+ context = decl_namespace (TYPE_MAIN_DECL (type));
+ if (arg_assoc_namespace (k, context))
+ return true;
+
+ /* Process baseclasses. */
+ for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); i++)
+ if (arg_assoc_class (k, TYPE_BINFO_BASETYPE (type, i)))
+ return true;
+
+ /* Process friends. */
+ for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list;
+ list = TREE_CHAIN (list))
+ if (k->name == FRIEND_NAME (list))
+ for (friends = FRIEND_DECLS (list); friends;
+ friends = TREE_CHAIN (friends))
+ {
+ tree fn = TREE_VALUE (friends);
+
+ /* Only interested in global functions with potentially hidden
+ (i.e. unqualified) declarations. */
+ if (CP_DECL_CONTEXT (fn) != context)
+ continue;
+ /* Template specializations are never found by name lookup.
+ (Templates themselves can be found, but not template
+ specializations.) */
+ if (TREE_CODE (fn) == FUNCTION_DECL && DECL_USE_TEMPLATE (fn))
+ continue;
+ if (add_function (k, fn))
+ return true;
+ }
+
+ /* Process template arguments. */
+ if (CLASSTYPE_TEMPLATE_INFO (type))
+ {
+ list = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type));
+ for (i = 0; i < TREE_VEC_LENGTH (list); ++i)
+ arg_assoc_template_arg (k, TREE_VEC_ELT (list, i));
+ }
+
+ return false;
+}
+
+/* Adds everything associated with a given type.
+ Returns 1 on error. */
+
+static bool
+arg_assoc_type (struct arg_lookup *k, tree type)
+{
+ /* As we do not get the type of non-type dependent expressions
+ right, we can end up with such things without a type. */
+ if (!type)
+ return false;
+
+ if (TYPE_PTRMEM_P (type))
+ {
+ /* Pointer to member: associate class type and value type. */
+ if (arg_assoc_type (k, TYPE_PTRMEM_CLASS_TYPE (type)))
+ return true;
+ return arg_assoc_type (k, TYPE_PTRMEM_POINTED_TO_TYPE (type));
+ }
+ else switch (TREE_CODE (type))
+ {
+ case ERROR_MARK:
+ return false;
+ case VOID_TYPE:
+ case INTEGER_TYPE:
+ case REAL_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ case CHAR_TYPE:
+ case BOOLEAN_TYPE:
+ return false;
+ case RECORD_TYPE:
+ if (TYPE_PTRMEMFUNC_P (type))
+ return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type));
+ return arg_assoc_class (k, type);
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ case ARRAY_TYPE:
+ return arg_assoc_type (k, TREE_TYPE (type));
+ case UNION_TYPE:
+ case ENUMERAL_TYPE:
+ return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type)));
+ case METHOD_TYPE:
+ /* The basetype is referenced in the first arg type, so just
+ fall through. */
+ case FUNCTION_TYPE:
+ /* Associate the parameter types. */
+ if (arg_assoc_args (k, TYPE_ARG_TYPES (type)))
+ return true;
+ /* Associate the return type. */
+ return arg_assoc_type (k, TREE_TYPE (type));
+ case TEMPLATE_TYPE_PARM:
+ case BOUND_TEMPLATE_TEMPLATE_PARM:
+ return false;
+ case TYPENAME_TYPE:
+ return false;
+ case LANG_TYPE:
+ if (type == unknown_type_node)
+ return false;
+ /* else fall through */
+ default:
+ abort ();
+ }
+ return false;
+}
+
+/* Adds everything associated with arguments. Returns true on error. */
+
+static bool
+arg_assoc_args (struct arg_lookup *k, tree args)
+{
+ for (; args; args = TREE_CHAIN (args))
+ if (arg_assoc (k, TREE_VALUE (args)))
+ return true;
+ return false;
+}
+
+/* Adds everything associated with a given tree_node. Returns 1 on error. */
+
+static bool
+arg_assoc (struct arg_lookup *k, tree n)
+{
+ if (n == error_mark_node)
+ return false;
+
+ if (TYPE_P (n))
+ return arg_assoc_type (k, n);
+
+ if (! type_unknown_p (n))
+ return arg_assoc_type (k, TREE_TYPE (n));
+
+ if (TREE_CODE (n) == ADDR_EXPR)
+ n = TREE_OPERAND (n, 0);
+ if (TREE_CODE (n) == COMPONENT_REF)
+ n = TREE_OPERAND (n, 1);
+ if (TREE_CODE (n) == OFFSET_REF)
+ n = TREE_OPERAND (n, 1);
+ while (TREE_CODE (n) == TREE_LIST)
+ n = TREE_VALUE (n);
+ if (TREE_CODE (n) == BASELINK)
+ n = BASELINK_FUNCTIONS (n);
+
+ if (TREE_CODE (n) == FUNCTION_DECL)
+ return arg_assoc_type (k, TREE_TYPE (n));
+ if (TREE_CODE (n) == TEMPLATE_ID_EXPR)
+ {
+ /* [basic.lookup.koenig]
+
+ If T is a template-id, its associated namespaces and classes
+ are the namespace in which the template is defined; for
+ member templates, the member template's class... */
+ tree template = TREE_OPERAND (n, 0);
+ tree args = TREE_OPERAND (n, 1);
+ tree ctx;
+ int ix;
+
+ if (TREE_CODE (template) == COMPONENT_REF)
+ template = TREE_OPERAND (template, 1);
+
+ /* First, the template. There may actually be more than one if
+ this is an overloaded function template. But, in that case,
+ we only need the first; all the functions will be in the same
+ namespace. */
+ template = OVL_CURRENT (template);
+
+ ctx = CP_DECL_CONTEXT (template);
+
+ if (TREE_CODE (ctx) == NAMESPACE_DECL)
+ {
+ if (arg_assoc_namespace (k, ctx) == 1)
+ return true;
+ }
+ /* It must be a member template. */
+ else if (arg_assoc_class (k, ctx) == 1)
+ return true;
+
+ /* Now the arguments. */
+ for (ix = TREE_VEC_LENGTH (args); ix--;)
+ if (arg_assoc_template_arg (k, TREE_VEC_ELT (args, ix)) == 1)
+ return true;
+ }
+ else if (TREE_CODE (n) == OVERLOAD)
+ {
+ for (; n; n = OVL_CHAIN (n))
+ if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n))))
+ return true;
+ }
+
+ return false;
+}
+
+/* Performs Koenig lookup depending on arguments, where fns
+ are the functions found in normal lookup. */
+
+tree
+lookup_arg_dependent (tree name, tree fns, tree args)
+{
+ struct arg_lookup k;
+ tree fn = NULL_TREE;
+
+ timevar_push (TV_NAME_LOOKUP);
+ k.name = name;
+ k.functions = fns;
+ k.classes = NULL_TREE;
+
+ /* We've already looked at some namespaces during normal unqualified
+ lookup -- but we don't know exactly which ones. If the functions
+ we found were brought into the current namespace via a using
+ declaration, we have not really checked the namespace from which
+ they came. Therefore, we check all namespaces here -- unless the
+ function we have is from the current namespace. Even then, we
+ must check all namespaces if the function is a local
+ declaration; any other declarations present at namespace scope
+ should be visible during argument-dependent lookup. */
+ if (fns)
+ fn = OVL_CURRENT (fns);
+ if (fn && TREE_CODE (fn) == FUNCTION_DECL
+ && (CP_DECL_CONTEXT (fn) != current_decl_namespace ()
+ || DECL_LOCAL_FUNCTION_P (fn)))
+ k.namespaces = NULL_TREE;
+ else
+ /* Setting NAMESPACES is purely an optimization; it prevents
+ adding functions which are already in FNS. Adding them would
+ be safe -- "joust" will eliminate the duplicates -- but
+ wasteful. */
+ k.namespaces = build_tree_list (current_decl_namespace (), NULL_TREE);
+
+ arg_assoc_args (&k, args);
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, k.functions);
+}
+
+/* Add namespace to using_directives. Return NULL_TREE if nothing was
+ changed (i.e. there was already a directive), or the fresh
+ TREE_LIST otherwise. */
+
+static tree
+push_using_directive (tree used)
+{
+ tree ud = current_binding_level->using_directives;
+ tree iter, ancestor;
+
+ timevar_push (TV_NAME_LOOKUP);
+ /* Check if we already have this. */
+ if (purpose_member (used, ud) != NULL_TREE)
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
+
+ ancestor = namespace_ancestor (current_decl_namespace (), used);
+ ud = current_binding_level->using_directives;
+ ud = tree_cons (used, ancestor, ud);
+ current_binding_level->using_directives = ud;
+
+ /* Recursively add all namespaces used. */
+ for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
+ push_using_directive (TREE_PURPOSE (iter));
+
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ud);
+}
+
+/* The type TYPE is being declared. If it is a class template, or a
+ specialization of a class template, do any processing required and
+ perform error-checking. If IS_FRIEND is nonzero, this TYPE is
+ being declared a friend. B is the binding level at which this TYPE
+ should be bound.
+
+ Returns the TYPE_DECL for TYPE, which may have been altered by this
+ processing. */
+
+static tree
+maybe_process_template_type_declaration (tree type, int globalize,
+ cxx_scope *b)
+{
+ tree decl = TYPE_NAME (type);
+
+ if (processing_template_parmlist)
+ /* You can't declare a new template type in a template parameter
+ list. But, you can declare a non-template type:
+
+ template <class A*> struct S;
+
+ is a forward-declaration of `A'. */
+ ;
+ else
+ {
+ maybe_check_template_type (type);
+
+ my_friendly_assert (IS_AGGR_TYPE (type)
+ || TREE_CODE (type) == ENUMERAL_TYPE, 0);
+
+
+ if (processing_template_decl)
+ {
+ /* This may change after the call to
+ push_template_decl_real, but we want the original value. */
+ tree name = DECL_NAME (decl);
+
+ decl = push_template_decl_real (decl, globalize);
+ /* If the current binding level is the binding level for the
+ template parameters (see the comment in
+ begin_template_parm_list) and the enclosing level is a class
+ scope, and we're not looking at a friend, push the
+ declaration of the member class into the class scope. In the
+ friend case, push_template_decl will already have put the
+ friend into global scope, if appropriate. */
+ if (TREE_CODE (type) != ENUMERAL_TYPE
+ && !globalize && b->kind == sk_template_parms
+ && b->level_chain->kind == sk_class)
+ {
+ finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type));
+ /* Put this UDT in the table of UDTs for the class, since
+ that won't happen below because B is not the class
+ binding level, but is instead the pseudo-global level. */
+ if (b->level_chain->type_decls == NULL)
+ b->level_chain->type_decls =
+ binding_table_new (SCOPE_DEFAULT_HT_SIZE);
+ binding_table_insert (b->level_chain->type_decls, name, type);
+ if (!COMPLETE_TYPE_P (current_class_type))
+ {
+ maybe_add_class_template_decl_list (current_class_type,
+ type, /*friend_p=*/0);
+ CLASSTYPE_NESTED_UTDS (current_class_type) =
+ b->level_chain->type_decls;
+ }
+ }
+ }
+ }
+
+ return decl;
+}
+
+/* Push a tag name NAME for struct/class/union/enum type TYPE.
+ Normally put it into the inner-most non-sk_cleanup scope,
+ but if GLOBALIZE is true, put it in the inner-most non-class scope.
+ The latter is needed for implicit declarations. */
+
+void
+pushtag (tree name, tree type, int globalize)
+{
+ struct cp_binding_level *b;
+
+ timevar_push (TV_NAME_LOOKUP);
+ b = current_binding_level;
+ while (/* Cleanup scopes are not scopes from the point of view of
+ the language. */
+ b->kind == sk_cleanup
+ /* Neither are the scopes used to hold template parameters
+ for an explicit specialization. For an ordinary template
+ declaration, these scopes are not scopes from the point of
+ view of the language -- but we need a place to stash
+ things that will go in the containing namespace when the
+ template is instantiated. */
+ || (b->kind == sk_template_parms && b->explicit_spec_p)
+ || (b->kind == sk_class
+ && (globalize
+ /* We may be defining a new type in the initializer
+ of a static member variable. We allow this when
+ not pedantic, and it is particularly useful for
+ type punning via an anonymous union. */
+ || COMPLETE_TYPE_P (b->this_entity))))
+ b = b->level_chain;
+
+ if (b->type_decls == NULL)
+ b->type_decls = binding_table_new (SCOPE_DEFAULT_HT_SIZE);
+ binding_table_insert (b->type_decls, name, type);
+
+ if (name)
+ {
+ /* Do C++ gratuitous typedefing. */
+ if (IDENTIFIER_TYPE_VALUE (name) != type)
+ {
+ tree d = NULL_TREE;
+ int in_class = 0;
+ tree context = TYPE_CONTEXT (type);
+
+ if (! context)
+ {
+ tree cs = current_scope ();
+
+ if (! globalize)
+ context = cs;
+ else if (cs != NULL_TREE && TYPE_P (cs))
+ /* When declaring a friend class of a local class, we want
+ to inject the newly named class into the scope
+ containing the local class, not the namespace scope. */
+ context = decl_function_context (get_type_decl (cs));
+ }
+ if (!context)
+ context = current_namespace;
+
+ if (b->kind == sk_class
+ || (b->kind == sk_template_parms
+ && b->level_chain->kind == sk_class))
+ in_class = 1;
+
+ if (current_lang_name == lang_name_java)
+ TYPE_FOR_JAVA (type) = 1;
+
+ d = create_implicit_typedef (name, type);
+ DECL_CONTEXT (d) = FROB_CONTEXT (context);
+ if (! in_class)
+ set_identifier_type_value_with_scope (name, d, b);
+
+ d = maybe_process_template_type_declaration (type,
+ globalize, b);
+
+ if (b->kind == sk_class)
+ {
+ if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
+ /* Put this TYPE_DECL on the TYPE_FIELDS list for the
+ class. But if it's a member template class, we
+ want the TEMPLATE_DECL, not the TYPE_DECL, so this
+ is done later. */
+ finish_member_declaration (d);
+ else
+ pushdecl_class_level (d);
+ }
+ else
+ d = pushdecl_with_scope (d, b);
+
+ /* FIXME what if it gets a name from typedef? */
+ if (ANON_AGGRNAME_P (name))
+ DECL_IGNORED_P (d) = 1;
+
+ TYPE_CONTEXT (type) = DECL_CONTEXT (d);
+
+ /* If this is a local class, keep track of it. We need this
+ information for name-mangling, and so that it is possible to find
+ all function definitions in a translation unit in a convenient
+ way. (It's otherwise tricky to find a member function definition
+ it's only pointed to from within a local class.) */
+ if (TYPE_CONTEXT (type)
+ && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL
+ && !processing_template_decl)
+ VARRAY_PUSH_TREE (local_classes, type);
+ }
+ if (b->kind == sk_class
+ && !COMPLETE_TYPE_P (current_class_type))
+ {
+ maybe_add_class_template_decl_list (current_class_type,
+ type, /*friend_p=*/0);
+ CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls;
+ }
+ }
+
+ if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
+ /* Use the canonical TYPE_DECL for this node. */
+ TYPE_STUB_DECL (type) = TYPE_NAME (type);
+ else
+ {
+ /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE
+ will be the tagged type we just added to the current
+ binding level. This fake NULL-named TYPE_DECL node helps
+ dwarfout.c to know when it needs to output a
+ representation of a tagged type, and it also gives us a
+ convenient place to record the "scope start" address for
+ the tagged type. */
+
+ tree d = build_decl (TYPE_DECL, NULL_TREE, type);
+ TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b);
+ }
+ timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Allocate storage for saving a C++ binding. */
+#define cxx_saved_binding_make() \
+ (ggc_alloc (sizeof (cxx_saved_binding)))
+
+struct cxx_saved_binding GTY(())
+{
+ /* Link that chains saved C++ bindings for a given name into a stack. */
+ cxx_saved_binding *previous;
+ /* The name of the current binding. */
+ tree identifier;
+ /* The binding we're saving. */
+ cxx_binding *binding;
+ tree class_value;
+ tree real_type_value;
+};
+
+/* Subroutines for reverting temporarily to top-level for instantiation
+ of templates and such. We actually need to clear out the class- and
+ local-value slots of all identifiers, so that only the global values
+ are at all visible. Simply setting current_binding_level to the global
+ scope isn't enough, because more binding levels may be pushed. */
+struct saved_scope *scope_chain;
+
+static cxx_saved_binding *
+store_bindings (tree names, cxx_saved_binding *old_bindings)
+{
+ tree t;
+ cxx_saved_binding *search_bindings = old_bindings;
+
+ timevar_push (TV_NAME_LOOKUP);
+ for (t = names; t; t = TREE_CHAIN (t))
+ {
+ tree id;
+ cxx_saved_binding *saved;
+ cxx_saved_binding *t1;
+
+ if (TREE_CODE (t) == TREE_LIST)
+ id = TREE_PURPOSE (t);
+ else
+ id = DECL_NAME (t);
+
+ if (!id
+ /* Note that we may have an IDENTIFIER_CLASS_VALUE even when
+ we have no IDENTIFIER_BINDING if we have left the class
+ scope, but cached the class-level declarations. */
+ || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id)))
+ continue;
+
+ for (t1 = search_bindings; t1; t1 = t1->previous)
+ if (t1->identifier == id)
+ goto skip_it;
+
+ my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135);
+ saved = cxx_saved_binding_make ();
+ saved->previous = old_bindings;
+ saved->identifier = id;
+ saved->binding = IDENTIFIER_BINDING (id);
+ saved->class_value = IDENTIFIER_CLASS_VALUE (id);;
+ saved->real_type_value = REAL_IDENTIFIER_TYPE_VALUE (id);
+ IDENTIFIER_BINDING (id) = NULL;
+ IDENTIFIER_CLASS_VALUE (id) = NULL_TREE;
+ old_bindings = saved;
+ skip_it:
+ ;
+ }
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, old_bindings);
+}
+
+void
+push_to_top_level (void)
+{
+ struct saved_scope *s;
+ struct cp_binding_level *b;
+ cxx_saved_binding *old_bindings;
+ int need_pop;
+
+ timevar_push (TV_NAME_LOOKUP);
+ s = ggc_alloc_cleared (sizeof (struct saved_scope));
+
+ b = scope_chain ? current_binding_level : 0;
+
+ /* If we're in the middle of some function, save our state. */
+ if (cfun)
+ {
+ need_pop = 1;
+ push_function_context_to (NULL_TREE);
+ }
+ else
+ need_pop = 0;
+
+ old_bindings = NULL;
+ if (scope_chain && previous_class_type)
+ old_bindings = store_bindings (previous_class_values, old_bindings);
+
+ /* Have to include the global scope, because class-scope decls
+ aren't listed anywhere useful. */
+ for (; b; b = b->level_chain)
+ {
+ tree t;
+
+ /* Template IDs are inserted into the global level. If they were
+ inserted into namespace level, finish_file wouldn't find them
+ when doing pending instantiations. Therefore, don't stop at
+ namespace level, but continue until :: . */
+ if (global_scope_p (b))
+ break;
+
+ old_bindings = store_bindings (b->names, old_bindings);
+ /* We also need to check class_shadowed to save class-level type
+ bindings, since pushclass doesn't fill in b->names. */
+ if (b->kind == sk_class)
+ old_bindings = store_bindings (b->class_shadowed, old_bindings);
+
+ /* Unwind type-value slots back to top level. */
+ for (t = b->type_shadowed; t; t = TREE_CHAIN (t))
+ SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t));
+ }
+ s->prev = scope_chain;
+ s->old_bindings = old_bindings;
+ s->bindings = b;
+ s->need_pop_function_context = need_pop;
+ s->function_decl = current_function_decl;
+
+ scope_chain = s;
+ current_function_decl = NULL_TREE;
+ VARRAY_TREE_INIT (current_lang_base, 10, "current_lang_base");
+ current_lang_name = lang_name_cplusplus;
+ current_namespace = global_namespace;
+ timevar_pop (TV_NAME_LOOKUP);
+}
+
+void
+pop_from_top_level (void)
+{
+ struct saved_scope *s = scope_chain;
+ cxx_saved_binding *saved;
+
+ timevar_push (TV_NAME_LOOKUP);
+ /* Clear out class-level bindings cache. */
+ if (previous_class_type)
+ invalidate_class_lookup_cache ();
+
+ current_lang_base = 0;
+
+ scope_chain = s->prev;
+ for (saved = s->old_bindings; saved; saved = saved->previous)
+ {
+ tree id = saved->identifier;
+
+ IDENTIFIER_BINDING (id) = saved->binding;
+ IDENTIFIER_CLASS_VALUE (id) = saved->class_value;
+ SET_IDENTIFIER_TYPE_VALUE (id, saved->real_type_value);
+ }
+
+ /* If we were in the middle of compiling a function, restore our
+ state. */
+ if (s->need_pop_function_context)
+ pop_function_context_from (NULL_TREE);
+ current_function_decl = s->function_decl;
+ timevar_pop (TV_NAME_LOOKUP);
+}
+
+/* Pop off extraneous binding levels left over due to syntax errors.
+
+ We don't pop past namespaces, as they might be valid. */
+
+void
+pop_everything (void)
+{
+ if (ENABLE_SCOPE_CHECKING)
+ verbatim ("XXX entering pop_everything ()\n");
+ while (!toplevel_bindings_p ())
+ {
+ if (current_binding_level->kind == sk_class)
+ pop_nested_class ();
+ else
+ poplevel (0, 0, 0);
+ }
+ if (ENABLE_SCOPE_CHECKING)
+ verbatim ("XXX leaving pop_everything ()\n");
+}
+
+#include "gt-cp-name-lookup.h"
diff --git a/contrib/gcc/cp/name-lookup.h b/contrib/gcc/cp/name-lookup.h
new file mode 100644
index 000000000000..837757520531
--- /dev/null
+++ b/contrib/gcc/cp/name-lookup.h
@@ -0,0 +1,335 @@
+/* Declarations for C++ name lookup routines.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef GCC_CP_NAME_LOOKUP_H
+#define GCC_CP_NAME_LOOKUP_H
+
+#include "c-common.h"
+
+/* The type of dictionary used to map names to types declared at
+ a given scope. */
+typedef struct binding_table_s *binding_table;
+typedef struct binding_entry_s *binding_entry;
+
+/* The type of a routine repeatedly called by binding_table_foreach. */
+typedef void (*bt_foreach_proc) (binding_entry, void *);
+
+struct binding_entry_s GTY(())
+{
+ binding_entry chain;
+ tree name;
+ tree type;
+};
+
+/* These macros indicate the initial chains count for binding_table. */
+#define SCOPE_DEFAULT_HT_SIZE (1 << 3)
+#define CLASS_SCOPE_HT_SIZE (1 << 3)
+#define NAMESPACE_ORDINARY_HT_SIZE (1 << 5)
+#define NAMESPACE_STD_HT_SIZE (1 << 8)
+#define GLOBAL_SCOPE_HT_SIZE (1 << 8)
+
+extern void binding_table_remove_anonymous_types (binding_table);
+extern void binding_table_foreach (binding_table, bt_foreach_proc, void *);
+extern binding_entry binding_table_find (binding_table, tree);
+extern void cxx_remember_type_decls (binding_table);
+
+/* Datatype used to temporarily save C++ bindings (for implicit
+ instantiations purposes and like). Implemented in decl.c. */
+typedef struct cxx_saved_binding cxx_saved_binding;
+
+/* Datatype that represents binding established by a declaration between
+ a name and a C++ entity. */
+typedef struct cxx_binding cxx_binding;
+
+/* The datatype used to implement C++ scope. */
+typedef struct cp_binding_level cxx_scope;
+
+/* Nonzero if this binding is for a local scope, as opposed to a class
+ or namespace scope. */
+#define LOCAL_BINDING_P(NODE) ((NODE)->is_local)
+
+/* True if NODE->value is from a base class of the class which is
+ currently being defined. */
+#define INHERITED_VALUE_BINDING_P(NODE) ((NODE)->value_is_inherited)
+
+struct cxx_binding GTY(())
+{
+ /* Link to chain together various bindings for this name. */
+ cxx_binding *previous;
+ /* The non-type entity this name is bound to. */
+ tree value;
+ /* The type entity this name is bound to. */
+ tree type;
+ /* The scope at which this binding was made. */
+ cxx_scope *scope;
+ unsigned value_is_inherited : 1;
+ unsigned is_local : 1;
+};
+
+extern tree identifier_type_value (tree);
+extern void set_identifier_type_value (tree, tree);
+extern void pop_binding (tree, tree);
+extern void clear_identifier_class_values (void);
+extern tree constructor_name_full (tree);
+extern tree constructor_name (tree);
+extern bool constructor_name_p (tree, tree);
+
+/* The kinds of scopes we recognize. */
+typedef enum scope_kind {
+ sk_block = 0, /* An ordinary block scope. This enumerator must
+ have the value zero because "cp_binding_level"
+ is initialized by using "memset" to set the
+ contents to zero, and the default scope kind
+ is "sk_block". */
+ sk_cleanup, /* A scope for (pseudo-)scope for cleanup. It is
+ peusdo in that it is transparent to name lookup
+ activities. */
+ sk_try, /* A try-block. */
+ sk_catch, /* A catch-block. */
+ sk_for, /* The scope of the variable declared in a
+ for-init-statement. */
+ sk_function_parms, /* The scope containing function parameters. */
+ sk_class, /* The scope containing the members of a class. */
+ sk_namespace, /* The scope containing the members of a
+ namespace, including the global scope. */
+ sk_template_parms, /* A scope for template parameters. */
+ sk_template_spec /* Like sk_template_parms, but for an explicit
+ specialization. Since, by definition, an
+ explicit specialization is introduced by
+ "template <>", this scope is always empty. */
+} scope_kind;
+
+/* For each binding contour we allocate a binding_level structure
+ which records the names defined in that contour.
+ Contours include:
+ 0) the global one
+ 1) one for each function definition,
+ where internal declarations of the parameters appear.
+ 2) one for each compound statement,
+ to record its declarations.
+
+ The current meaning of a name can be found by searching the levels
+ from the current one out to the global one.
+
+ Off to the side, may be the class_binding_level. This exists only
+ to catch class-local declarations. It is otherwise nonexistent.
+
+ Also there may be binding levels that catch cleanups that must be
+ run when exceptions occur. Thus, to see whether a name is bound in
+ the current scope, it is not enough to look in the
+ CURRENT_BINDING_LEVEL. You should use lookup_name_current_level
+ instead. */
+
+/* Note that the information in the `names' component of the global contour
+ is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */
+
+struct cp_binding_level GTY(())
+ {
+ /* A chain of _DECL nodes for all variables, constants, functions,
+ and typedef types. These are in the reverse of the order
+ supplied. There may be OVERLOADs on this list, too, but they
+ are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */
+ tree names;
+
+ /* Count of elements in names chain. */
+ size_t names_size;
+
+ /* A chain of NAMESPACE_DECL nodes. */
+ tree namespaces;
+
+ /* An array of static functions and variables (for namespaces only) */
+ varray_type static_decls;
+
+ /* A chain of VTABLE_DECL nodes. */
+ tree vtables;
+
+ /* A dictionary for looking up user-defined-types. */
+ binding_table type_decls;
+
+ /* A list of USING_DECL nodes. */
+ tree usings;
+
+ /* A list of used namespaces. PURPOSE is the namespace,
+ VALUE the common ancestor with this binding_level's namespace. */
+ tree using_directives;
+
+ /* If this binding level is the binding level for a class, then
+ class_shadowed is a TREE_LIST. The TREE_PURPOSE of each node
+ is the name of an entity bound in the class. The TREE_TYPE is
+ the DECL bound by this name in the class. */
+ tree class_shadowed;
+
+ /* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and
+ is used for all binding levels. In addition the TREE_VALUE is the
+ IDENTIFIER_TYPE_VALUE before we entered the class. */
+ tree type_shadowed;
+
+ /* A TREE_LIST. Each TREE_VALUE is the LABEL_DECL for a local
+ label in this scope. The TREE_PURPOSE is the previous value of
+ the IDENTIFIER_LABEL VALUE. */
+ tree shadowed_labels;
+
+ /* For each level (except not the global one),
+ a chain of BLOCK nodes for all the levels
+ that were entered and exited one level down. */
+ tree blocks;
+
+ /* The entity (namespace, class, function) the scope of which this
+ binding contour corresponds to. Otherwise NULL. */
+ tree this_entity;
+
+ /* The binding level which this one is contained in (inherits from). */
+ struct cp_binding_level *level_chain;
+
+ /* List of VAR_DECLS saved from a previous for statement.
+ These would be dead in ISO-conforming code, but might
+ be referenced in ARM-era code. These are stored in a
+ TREE_LIST; the TREE_VALUE is the actual declaration. */
+ tree dead_vars_from_for;
+
+ /* Binding depth at which this level began. */
+ int binding_depth;
+
+ /* The kind of scope that this object represents. However, a
+ SK_TEMPLATE_SPEC scope is represented with KIND set to
+ SK_TEMPALTE_PARMS and EXPLICIT_SPEC_P set to true. */
+ ENUM_BITFIELD (scope_kind) kind : 4;
+
+ /* True if this scope is an SK_TEMPLATE_SPEC scope. This field is
+ only valid if KIND == SK_TEMPLATE_PARMS. */
+ BOOL_BITFIELD explicit_spec_p : 1;
+
+ /* true means make a BLOCK for this level regardless of all else. */
+ unsigned keep : 1;
+
+ /* Nonzero if this level can safely have additional
+ cleanup-needing variables added to it. */
+ unsigned more_cleanups_ok : 1;
+ unsigned have_cleanups : 1;
+
+ /* 22 bits left to fill a 32-bit word. */
+ };
+
+/* The binding level currently in effect. */
+
+#define current_binding_level \
+ (*(cfun && cp_function_chain->bindings \
+ ? &cp_function_chain->bindings \
+ : &scope_chain->bindings))
+
+/* The binding level of the current class, if any. */
+
+#define class_binding_level scope_chain->class_bindings
+
+/* The tree node representing the global scope. */
+extern GTY(()) tree global_namespace;
+extern GTY(()) tree global_scope_name;
+
+/* Indicates that there is a type value in some namespace, although
+ that is not necessarily in scope at the moment. */
+
+extern GTY(()) tree global_type_node;
+
+/* True if SCOPE designates the global scope binding contour. */
+#define global_scope_p(SCOPE) \
+ ((SCOPE) == NAMESPACE_LEVEL (global_namespace))
+
+extern cxx_scope *leave_scope (void);
+extern bool kept_level_p (void);
+extern int global_bindings_p (void);
+extern bool toplevel_bindings_p (void);
+extern bool namespace_bindings_p (void);
+extern bool template_parm_scope_p (void);
+extern scope_kind innermost_scope_kind (void);
+extern cxx_scope *begin_scope (scope_kind, tree);
+extern void print_binding_stack (void);
+extern void print_binding_level (cxx_scope *);
+extern void push_to_top_level (void);
+extern void pop_from_top_level (void);
+extern void pop_everything (void);
+extern void keep_next_level (bool);
+extern bool is_ancestor (tree, tree);
+extern bool push_scope (tree);
+extern void pop_scope (tree);
+
+extern void push_namespace (tree);
+extern void pop_namespace (void);
+extern void push_nested_namespace (tree);
+extern void pop_nested_namespace (tree);
+extern void pushlevel_class (void);
+extern void poplevel_class (void);
+extern tree pushdecl_with_scope (tree, cxx_scope *);
+extern tree lookup_tag (enum tree_code, tree, cxx_scope *, int);
+extern tree lookup_tag_reverse (tree, tree);
+extern tree lookup_name (tree, int);
+extern tree lookup_name_real (tree, int, int, int, int);
+extern tree namespace_binding (tree, tree);
+extern void set_namespace_binding (tree, tree, tree);
+extern tree lookup_namespace_name (tree, tree);
+extern tree lookup_qualified_name (tree, tree, bool, bool);
+extern tree lookup_name_nonclass (tree);
+extern tree lookup_function_nonclass (tree, tree);
+extern int push_class_binding (tree, tree);
+extern bool pushdecl_class_level (tree);
+extern tree pushdecl_namespace_level (tree);
+extern bool push_class_level_binding (tree, tree);
+extern void storetags (tree);
+extern tree getdecls (void);
+extern tree cp_namespace_decls (tree);
+extern void set_class_shadows (tree);
+extern void set_decl_namespace (tree, tree, bool);
+extern tree current_decl_namespace (void);
+extern void push_decl_namespace (tree);
+extern void pop_decl_namespace (void);
+extern void do_namespace_alias (tree, tree);
+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);
+extern void do_using_directive (tree);
+extern tree lookup_arg_dependent (tree, tree, tree);
+extern bool is_associated_namespace (tree, tree);
+extern void parse_using_directive (tree, tree);
+
+
+/* Set *DECL to the (non-hidden) declaration for ID at global scope,
+ if present and return true; otherwise return false. */
+
+static inline bool
+get_global_value_if_present (tree id, tree *decl)
+{
+ tree global_value = namespace_binding (id, global_namespace);
+
+ if (global_value)
+ *decl = global_value;
+ return global_value != NULL;
+}
+
+/* True is the binding of IDENTIFIER at global scope names a type. */
+
+static inline bool
+is_typename_at_global_scope (tree id)
+{
+ tree global_value = namespace_binding (id, global_namespace);
+
+ return global_value && TREE_CODE (global_value) == TYPE_DECL;
+}
+
+#endif /* GCC_CP_NAME_LOOKUP_H */
diff --git a/contrib/gcc/cp/operators.def b/contrib/gcc/cp/operators.def
index 42e4a4742c95..16e603d31bfe 100644
--- a/contrib/gcc/cp/operators.def
+++ b/contrib/gcc/cp/operators.def
@@ -3,24 +3,24 @@
This file contains definitions of the various C++ operators,
including both overloadable operators (like `+') and
non-overloadable operators (like the `?:' ternary operator).
- Writtey by Mark Mitchell <mark@codesourcery.com>
+ Written by Mark Mitchell <mark@codesourcery.com>
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -93,8 +93,10 @@ DEF_SIMPLE_OPERATOR ("!", TRUTH_NOT_EXPR, "nt", 1)
DEF_SIMPLE_OPERATOR ("++", PREINCREMENT_EXPR, "pp", 1)
DEF_SIMPLE_OPERATOR ("--", PREDECREMENT_EXPR, "mm", 1)
DEF_SIMPLE_OPERATOR ("sizeof", SIZEOF_EXPR, "sz", 1)
-/* This is an extension. */
+/* These are extensions. */
DEF_SIMPLE_OPERATOR ("alignof", ALIGNOF_EXPR, "v17alignof", 1)
+DEF_SIMPLE_OPERATOR ("__imag__", IMAGPART_EXPR, "v18__imag__", 1)
+DEF_SIMPLE_OPERATOR ("__real__", REALPART_EXPR, "v18__real__", 1)
/* The cast operator. */
DEF_SIMPLE_OPERATOR ("", TYPE_EXPR, "cv", 1)
@@ -131,7 +133,7 @@ DEF_SIMPLE_OPERATOR ("--", POSTDECREMENT_EXPR, "mm", 2)
DEF_SIMPLE_OPERATOR ("<?", MIN_EXPR, "v23min", 2)
DEF_SIMPLE_OPERATOR (">?", MAX_EXPR, "v23max", 2)
/* This one is needed for mangling. */
-DEF_SIMPLE_OPERATOR ("::", SCOPE_REF, "sr", 2);
+DEF_SIMPLE_OPERATOR ("::", SCOPE_REF, "sr", 2)
/* Assignment operators. */
DEF_ASSN_OPERATOR ("=", NOP_EXPR, "aS", 2)
@@ -146,8 +148,8 @@ DEF_ASSN_OPERATOR ("^=", BIT_XOR_EXPR, "eO", 2)
DEF_ASSN_OPERATOR ("<<=", LSHIFT_EXPR, "lS", 2)
DEF_ASSN_OPERATOR (">>=", RSHIFT_EXPR, "rS", 2)
/* These operators are GNU extensions. */
-DEF_ASSN_OPERATOR ("<?=", MIN_EXPR, "v23miN", 2);
-DEF_ASSN_OPERATOR (">?=", MAX_EXPR, "v23maX", 2);
+DEF_ASSN_OPERATOR ("<?=", MIN_EXPR, "v23miN", 2)
+DEF_ASSN_OPERATOR (">?=", MAX_EXPR, "v23maX", 2)
/* Ternary operators. */
DEF_SIMPLE_OPERATOR ("?:", COND_EXPR, "qu", 3)
diff --git a/contrib/gcc/cp/optimize.c b/contrib/gcc/cp/optimize.c
index 654d4cd302a0..5ada1312e59d 100644
--- a/contrib/gcc/cp/optimize.c
+++ b/contrib/gcc/cp/optimize.c
@@ -1,26 +1,29 @@
/* Perform optimizations on tree structure.
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004
+ Free Software Foundation, Inc.
Written by Mark Michell (mark@codesourcery.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify it
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful, but
+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 GNU CC; see the file COPYING. If not, write to the Free
+along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "rtl.h"
@@ -29,7 +32,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "integrate.h"
#include "toplev.h"
#include "varray.h"
-#include "ggc.h"
#include "params.h"
#include "hashtab.h"
#include "debug.h"
@@ -37,29 +39,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Prototypes. */
-static tree calls_setjmp_r PARAMS ((tree *, int *, void *));
-static void update_cloned_parm PARAMS ((tree, tree));
-static void dump_function PARAMS ((enum tree_dump_index, tree));
+static tree calls_setjmp_r (tree *, int *, void *);
+static void update_cloned_parm (tree, tree);
+static void dump_function (enum tree_dump_index, tree);
/* Optimize the body of FN. */
void
-optimize_function (fn)
- tree fn;
+optimize_function (tree fn)
{
dump_function (TDI_original, fn);
- /* While in this function, we may choose to go off and compile
- another function. For example, we might instantiate a function
- in the hopes of inlining it. Normally, that wouldn't trigger any
- actual RTL code-generation -- but it will if the template is
- actually needed. (For example, if it's address is taken, or if
- some other function already refers to the template.) If
- code-generation occurs, then garbage collection will occur, so we
- must protect ourselves, just as we do while building up the body
- of the function. */
- ++function_depth;
-
if (flag_inline_trees
/* We do not inline thunks, as (a) the backend tries to optimize
the call to the thunkee, (b) tree based inlining breaks that
@@ -68,23 +58,17 @@ optimize_function (fn)
&& !DECL_THUNK_P (fn))
{
optimize_inline_calls (fn);
-
dump_function (TDI_inlined, fn);
}
- /* Undo the call to ggc_push_context above. */
- --function_depth;
-
dump_function (TDI_optimized, fn);
}
/* Called from calls_setjmp_p via walk_tree. */
static tree
-calls_setjmp_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+calls_setjmp_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
{
/* We're only interested in FUNCTION_DECLS. */
if (TREE_CODE (*tp) != FUNCTION_DECL)
@@ -98,9 +82,8 @@ calls_setjmp_r (tp, walk_subtrees, data)
occasionally return a nonzero value even when FN does not actually
call `setjmp'. */
-int
-calls_setjmp_p (fn)
- tree fn;
+bool
+calls_setjmp_p (tree fn)
{
return walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
calls_setjmp_r,
@@ -113,9 +96,7 @@ calls_setjmp_p (fn)
debugging generation code will be able to find the original PARM. */
static void
-update_cloned_parm (parm, cloned_parm)
- tree parm;
- tree cloned_parm;
+update_cloned_parm (tree parm, tree cloned_parm)
{
DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
@@ -136,12 +117,10 @@ update_cloned_parm (parm, cloned_parm)
necessary. Returns nonzero if there's no longer any need to
process the main body. */
-int
-maybe_clone_body (fn)
- tree fn;
+bool
+maybe_clone_body (tree fn)
{
tree clone;
- int first = 1;
/* We only clone constructors and destructors. */
if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
@@ -155,7 +134,7 @@ maybe_clone_body (fn)
list. */
for (clone = TREE_CHAIN (fn);
clone && DECL_CLONED_FUNCTION_P (clone);
- clone = TREE_CHAIN (clone), first = 0)
+ clone = TREE_CHAIN (clone))
{
tree parm;
tree clone_parm;
@@ -165,7 +144,6 @@ maybe_clone_body (fn)
/* Update CLONE's source position information to match FN's. */
DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
DECL_INLINE (clone) = DECL_INLINE (fn);
- DID_INLINE_FUNC (clone) = DID_INLINE_FUNC (fn);
DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
DECL_COMDAT (clone) = DECL_COMDAT (fn);
DECL_WEAK (clone) = DECL_WEAK (fn);
@@ -176,6 +154,7 @@ maybe_clone_body (fn)
DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
+ DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn);
/* Adjust the parameter names and locations. */
parm = DECL_ARGUMENTS (fn);
@@ -192,13 +171,8 @@ maybe_clone_body (fn)
clone_parm = TREE_CHAIN (clone_parm);
for (; parm;
parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm))
- {
- /* Update this parameter. */
- update_cloned_parm (parm, clone_parm);
- /* We should only give unused information for one clone. */
- if (!first)
- TREE_USED (clone_parm) = 1;
- }
+ /* Update this parameter. */
+ update_cloned_parm (parm, clone_parm);
/* Start processing the function. */
push_to_top_level ();
@@ -258,10 +232,6 @@ maybe_clone_body (fn)
/* Clone the body. */
clone_body (clone, fn, decl_map);
- /* There are as many statements in the clone as in the
- original. */
- DECL_NUM_STMTS (clone) = DECL_NUM_STMTS (fn);
-
/* Clean up. */
splay_tree_delete (decl_map);
@@ -271,7 +241,7 @@ maybe_clone_body (fn)
/* Now, expand this function into RTL, if appropriate. */
finish_function (0);
BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
- expand_body (clone);
+ expand_or_defer_fn (clone);
pop_from_top_level ();
}
@@ -282,9 +252,7 @@ maybe_clone_body (fn)
/* Dump FUNCTION_DECL FN as tree dump PHASE. */
static void
-dump_function (phase, fn)
- enum tree_dump_index phase;
- tree fn;
+dump_function (enum tree_dump_index phase, tree fn)
{
FILE *stream;
int flags;
@@ -296,7 +264,7 @@ dump_function (phase, fn)
decl_as_string (fn, TFF_DECL_SPECIFIERS));
fprintf (stream, " (%s)\n",
decl_as_string (DECL_ASSEMBLER_NAME (fn), 0));
- fprintf (stream, ";; enabled by -%s\n", dump_flag_name (phase));
+ fprintf (stream, ";; enabled by -fdump-%s\n", dump_flag_name (phase));
fprintf (stream, "\n");
dump_node (fn, TDF_SLIM | flags, stream);
diff --git a/contrib/gcc/cp/parser.c b/contrib/gcc/cp/parser.c
new file mode 100644
index 000000000000..344a8f50dcb2
--- /dev/null
+++ b/contrib/gcc/cp/parser.c
@@ -0,0 +1,15323 @@
+/* C++ Parser.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Written by Mark Mitchell <mark@codesourcery.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 2, 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 COPYING. If not, write to the Free
+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "dyn-string.h"
+#include "varray.h"
+#include "cpplib.h"
+#include "tree.h"
+#include "cp-tree.h"
+#include "c-pragma.h"
+#include "decl.h"
+#include "flags.h"
+#include "diagnostic.h"
+#include "toplev.h"
+#include "output.h"
+
+
+/* The lexer. */
+
+/* Overview
+ --------
+
+ A cp_lexer represents a stream of cp_tokens. It allows arbitrary
+ look-ahead.
+
+ Methodology
+ -----------
+
+ We use a circular buffer to store incoming tokens.
+
+ Some artifacts of the C++ language (such as the
+ expression/declaration ambiguity) require arbitrary look-ahead.
+ The strategy we adopt for dealing with these problems is to attempt
+ to parse one construct (e.g., the declaration) and fall back to the
+ other (e.g., the expression) if that attempt does not succeed.
+ Therefore, we must sometimes store an arbitrary number of tokens.
+
+ The parser routinely peeks at the next token, and then consumes it
+ later. That also requires a buffer in which to store the tokens.
+
+ In order to easily permit adding tokens to the end of the buffer,
+ while removing them from the beginning of the buffer, we use a
+ circular buffer. */
+
+/* A C++ token. */
+
+typedef struct cp_token GTY (())
+{
+ /* The kind of token. */
+ ENUM_BITFIELD (cpp_ttype) type : 8;
+ /* If this token is a keyword, this value indicates which keyword.
+ Otherwise, this value is RID_MAX. */
+ ENUM_BITFIELD (rid) keyword : 8;
+ /* Token flags. */
+ unsigned char flags;
+ /* The value associated with this token, if any. */
+ tree value;
+ /* The location at which this token was found. */
+ location_t location;
+} cp_token;
+
+/* The number of tokens in a single token block.
+ Computed so that cp_token_block fits in a 512B allocation unit. */
+
+#define CP_TOKEN_BLOCK_NUM_TOKENS ((512 - 3*sizeof (char*))/sizeof (cp_token))
+
+/* A group of tokens. These groups are chained together to store
+ large numbers of tokens. (For example, a token block is created
+ when the body of an inline member function is first encountered;
+ the tokens are processed later after the class definition is
+ complete.)
+
+ This somewhat ungainly data structure (as opposed to, say, a
+ variable-length array), is used due to constraints imposed by the
+ current garbage-collection methodology. If it is made more
+ flexible, we could perhaps simplify the data structures involved. */
+
+typedef struct cp_token_block GTY (())
+{
+ /* The tokens. */
+ cp_token tokens[CP_TOKEN_BLOCK_NUM_TOKENS];
+ /* The number of tokens in this block. */
+ size_t num_tokens;
+ /* The next token block in the chain. */
+ struct cp_token_block *next;
+ /* The previous block in the chain. */
+ struct cp_token_block *prev;
+} cp_token_block;
+
+typedef struct cp_token_cache GTY (())
+{
+ /* The first block in the cache. NULL if there are no tokens in the
+ cache. */
+ cp_token_block *first;
+ /* The last block in the cache. NULL If there are no tokens in the
+ cache. */
+ cp_token_block *last;
+} cp_token_cache;
+
+/* Prototypes. */
+
+static cp_token_cache *cp_token_cache_new
+ (void);
+static void cp_token_cache_push_token
+ (cp_token_cache *, cp_token *);
+
+/* Create a new cp_token_cache. */
+
+static cp_token_cache *
+cp_token_cache_new (void)
+{
+ return ggc_alloc_cleared (sizeof (cp_token_cache));
+}
+
+/* Add *TOKEN to *CACHE. */
+
+static void
+cp_token_cache_push_token (cp_token_cache *cache,
+ cp_token *token)
+{
+ cp_token_block *b = cache->last;
+
+ /* See if we need to allocate a new token block. */
+ if (!b || b->num_tokens == CP_TOKEN_BLOCK_NUM_TOKENS)
+ {
+ b = ggc_alloc_cleared (sizeof (cp_token_block));
+ b->prev = cache->last;
+ if (cache->last)
+ {
+ cache->last->next = b;
+ cache->last = b;
+ }
+ else
+ cache->first = cache->last = b;
+ }
+ /* Add this token to the current token block. */
+ b->tokens[b->num_tokens++] = *token;
+}
+
+/* The cp_lexer structure represents the C++ lexer. It is responsible
+ for managing the token stream from the preprocessor and supplying
+ it to the parser. */
+
+typedef struct cp_lexer GTY (())
+{
+ /* The memory allocated for the buffer. Never NULL. */
+ cp_token * GTY ((length ("(%h.buffer_end - %h.buffer)"))) buffer;
+ /* A pointer just past the end of the memory allocated for the buffer. */
+ cp_token * GTY ((skip (""))) buffer_end;
+ /* The first valid token in the buffer, or NULL if none. */
+ cp_token * GTY ((skip (""))) first_token;
+ /* The next available token. If NEXT_TOKEN is NULL, then there are
+ no more available tokens. */
+ cp_token * GTY ((skip (""))) next_token;
+ /* A pointer just past the last available token. If FIRST_TOKEN is
+ NULL, however, there are no available tokens, and then this
+ location is simply the place in which the next token read will be
+ placed. If LAST_TOKEN == FIRST_TOKEN, then the buffer is full.
+ When the LAST_TOKEN == BUFFER, then the last token is at the
+ highest memory address in the BUFFER. */
+ cp_token * GTY ((skip (""))) last_token;
+
+ /* A stack indicating positions at which cp_lexer_save_tokens was
+ called. The top entry is the most recent position at which we
+ began saving tokens. The entries are differences in token
+ position between FIRST_TOKEN and the first saved token.
+
+ If the stack is non-empty, we are saving tokens. When a token is
+ consumed, the NEXT_TOKEN pointer will move, but the FIRST_TOKEN
+ pointer will not. The token stream will be preserved so that it
+ can be reexamined later.
+
+ If the stack is empty, then we are not saving tokens. Whenever a
+ token is consumed, the FIRST_TOKEN pointer will be moved, and the
+ consumed token will be gone forever. */
+ varray_type saved_tokens;
+
+ /* The STRING_CST tokens encountered while processing the current
+ string literal. */
+ varray_type string_tokens;
+
+ /* True if we should obtain more tokens from the preprocessor; false
+ if we are processing a saved token cache. */
+ bool main_lexer_p;
+
+ /* True if we should output debugging information. */
+ bool debugging_p;
+
+ /* The next lexer in a linked list of lexers. */
+ struct cp_lexer *next;
+} cp_lexer;
+
+/* Prototypes. */
+
+static cp_lexer *cp_lexer_new_main
+ (void);
+static cp_lexer *cp_lexer_new_from_tokens
+ (struct cp_token_cache *);
+static int cp_lexer_saving_tokens
+ (const cp_lexer *);
+static cp_token *cp_lexer_next_token
+ (cp_lexer *, cp_token *);
+static cp_token *cp_lexer_prev_token
+ (cp_lexer *, cp_token *);
+static ptrdiff_t cp_lexer_token_difference
+ (cp_lexer *, cp_token *, cp_token *);
+static cp_token *cp_lexer_read_token
+ (cp_lexer *);
+static void cp_lexer_maybe_grow_buffer
+ (cp_lexer *);
+static void cp_lexer_get_preprocessor_token
+ (cp_lexer *, cp_token *);
+static cp_token *cp_lexer_peek_token
+ (cp_lexer *);
+static cp_token *cp_lexer_peek_nth_token
+ (cp_lexer *, size_t);
+static inline bool cp_lexer_next_token_is
+ (cp_lexer *, enum cpp_ttype);
+static bool cp_lexer_next_token_is_not
+ (cp_lexer *, enum cpp_ttype);
+static bool cp_lexer_next_token_is_keyword
+ (cp_lexer *, enum rid);
+static cp_token *cp_lexer_consume_token
+ (cp_lexer *);
+static void cp_lexer_purge_token
+ (cp_lexer *);
+static void cp_lexer_purge_tokens_after
+ (cp_lexer *, cp_token *);
+static void cp_lexer_save_tokens
+ (cp_lexer *);
+static void cp_lexer_commit_tokens
+ (cp_lexer *);
+static void cp_lexer_rollback_tokens
+ (cp_lexer *);
+static inline void cp_lexer_set_source_position_from_token
+ (cp_lexer *, const cp_token *);
+static void cp_lexer_print_token
+ (FILE *, cp_token *);
+static inline bool cp_lexer_debugging_p
+ (cp_lexer *);
+static void cp_lexer_start_debugging
+ (cp_lexer *) ATTRIBUTE_UNUSED;
+static void cp_lexer_stop_debugging
+ (cp_lexer *) ATTRIBUTE_UNUSED;
+
+/* Manifest constants. */
+
+#define CP_TOKEN_BUFFER_SIZE 5
+#define CP_SAVED_TOKENS_SIZE 5
+
+/* A token type for keywords, as opposed to ordinary identifiers. */
+#define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1))
+
+/* A token type for template-ids. If a template-id is processed while
+ parsing tentatively, it is replaced with a CPP_TEMPLATE_ID token;
+ the value of the CPP_TEMPLATE_ID is whatever was returned by
+ cp_parser_template_id. */
+#define CPP_TEMPLATE_ID ((enum cpp_ttype) (CPP_KEYWORD + 1))
+
+/* A token type for nested-name-specifiers. If a
+ nested-name-specifier is processed while parsing tentatively, it is
+ replaced with a CPP_NESTED_NAME_SPECIFIER token; the value of the
+ CPP_NESTED_NAME_SPECIFIER is whatever was returned by
+ cp_parser_nested_name_specifier_opt. */
+#define CPP_NESTED_NAME_SPECIFIER ((enum cpp_ttype) (CPP_TEMPLATE_ID + 1))
+
+/* A token type for tokens that are not tokens at all; these are used
+ to mark the end of a token block. */
+#define CPP_NONE (CPP_NESTED_NAME_SPECIFIER + 1)
+
+/* Variables. */
+
+/* The stream to which debugging output should be written. */
+static FILE *cp_lexer_debug_stream;
+
+/* Create a new main C++ lexer, the lexer that gets tokens from the
+ preprocessor. */
+
+static cp_lexer *
+cp_lexer_new_main (void)
+{
+ cp_lexer *lexer;
+ cp_token first_token;
+
+ /* It's possible that lexing the first token will load a PCH file,
+ which is a GC collection point. So we have to grab the first
+ token before allocating any memory. */
+ cp_lexer_get_preprocessor_token (NULL, &first_token);
+ c_common_no_more_pch ();
+
+ /* Allocate the memory. */
+ lexer = ggc_alloc_cleared (sizeof (cp_lexer));
+
+ /* Create the circular buffer. */
+ lexer->buffer = ggc_calloc (CP_TOKEN_BUFFER_SIZE, sizeof (cp_token));
+ lexer->buffer_end = lexer->buffer + CP_TOKEN_BUFFER_SIZE;
+
+ /* There is one token in the buffer. */
+ lexer->last_token = lexer->buffer + 1;
+ lexer->first_token = lexer->buffer;
+ lexer->next_token = lexer->buffer;
+ memcpy (lexer->buffer, &first_token, sizeof (cp_token));
+
+ /* This lexer obtains more tokens by calling c_lex. */
+ lexer->main_lexer_p = true;
+
+ /* Create the SAVED_TOKENS stack. */
+ VARRAY_INT_INIT (lexer->saved_tokens, CP_SAVED_TOKENS_SIZE, "saved_tokens");
+
+ /* Create the STRINGS array. */
+ VARRAY_TREE_INIT (lexer->string_tokens, 32, "strings");
+
+ /* Assume we are not debugging. */
+ lexer->debugging_p = false;
+
+ return lexer;
+}
+
+/* Create a new lexer whose token stream is primed with the TOKENS.
+ When these tokens are exhausted, no new tokens will be read. */
+
+static cp_lexer *
+cp_lexer_new_from_tokens (cp_token_cache *tokens)
+{
+ cp_lexer *lexer;
+ cp_token *token;
+ cp_token_block *block;
+ ptrdiff_t num_tokens;
+
+ /* Allocate the memory. */
+ lexer = ggc_alloc_cleared (sizeof (cp_lexer));
+
+ /* Create a new buffer, appropriately sized. */
+ num_tokens = 0;
+ for (block = tokens->first; block != NULL; block = block->next)
+ num_tokens += block->num_tokens;
+ lexer->buffer = ggc_alloc (num_tokens * sizeof (cp_token));
+ lexer->buffer_end = lexer->buffer + num_tokens;
+
+ /* Install the tokens. */
+ token = lexer->buffer;
+ for (block = tokens->first; block != NULL; block = block->next)
+ {
+ memcpy (token, block->tokens, block->num_tokens * sizeof (cp_token));
+ token += block->num_tokens;
+ }
+
+ /* The FIRST_TOKEN is the beginning of the buffer. */
+ lexer->first_token = lexer->buffer;
+ /* The next available token is also at the beginning of the buffer. */
+ lexer->next_token = lexer->buffer;
+ /* The buffer is full. */
+ lexer->last_token = lexer->first_token;
+
+ /* This lexer doesn't obtain more tokens. */
+ lexer->main_lexer_p = false;
+
+ /* Create the SAVED_TOKENS stack. */
+ VARRAY_INT_INIT (lexer->saved_tokens, CP_SAVED_TOKENS_SIZE, "saved_tokens");
+
+ /* Create the STRINGS array. */
+ VARRAY_TREE_INIT (lexer->string_tokens, 32, "strings");
+
+ /* Assume we are not debugging. */
+ lexer->debugging_p = false;
+
+ return lexer;
+}
+
+/* Returns nonzero if debugging information should be output. */
+
+static inline bool
+cp_lexer_debugging_p (cp_lexer *lexer)
+{
+ return lexer->debugging_p;
+}
+
+/* Set the current source position from the information stored in
+ TOKEN. */
+
+static inline void
+cp_lexer_set_source_position_from_token (cp_lexer *lexer ATTRIBUTE_UNUSED ,
+ const cp_token *token)
+{
+ /* Ideally, the source position information would not be a global
+ variable, but it is. */
+
+ /* Update the line number. */
+ if (token->type != CPP_EOF)
+ input_location = token->location;
+}
+
+/* TOKEN points into the circular token buffer. Return a pointer to
+ the next token in the buffer. */
+
+static inline cp_token *
+cp_lexer_next_token (cp_lexer* lexer, cp_token* token)
+{
+ token++;
+ if (token == lexer->buffer_end)
+ token = lexer->buffer;
+ return token;
+}
+
+/* TOKEN points into the circular token buffer. Return a pointer to
+ the previous token in the buffer. */
+
+static inline cp_token *
+cp_lexer_prev_token (cp_lexer* lexer, cp_token* token)
+{
+ if (token == lexer->buffer)
+ token = lexer->buffer_end;
+ return token - 1;
+}
+
+/* nonzero if we are presently saving tokens. */
+
+static int
+cp_lexer_saving_tokens (const cp_lexer* lexer)
+{
+ return VARRAY_ACTIVE_SIZE (lexer->saved_tokens) != 0;
+}
+
+/* Return a pointer to the token that is N tokens beyond TOKEN in the
+ buffer. */
+
+static cp_token *
+cp_lexer_advance_token (cp_lexer *lexer, cp_token *token, ptrdiff_t n)
+{
+ token += n;
+ if (token >= lexer->buffer_end)
+ token = lexer->buffer + (token - lexer->buffer_end);
+ return token;
+}
+
+/* Returns the number of times that START would have to be incremented
+ to reach FINISH. If START and FINISH are the same, returns zero. */
+
+static ptrdiff_t
+cp_lexer_token_difference (cp_lexer* lexer, cp_token* start, cp_token* finish)
+{
+ if (finish >= start)
+ return finish - start;
+ else
+ return ((lexer->buffer_end - lexer->buffer)
+ - (start - finish));
+}
+
+/* Obtain another token from the C preprocessor and add it to the
+ token buffer. Returns the newly read token. */
+
+static cp_token *
+cp_lexer_read_token (cp_lexer* lexer)
+{
+ cp_token *token;
+
+ /* Make sure there is room in the buffer. */
+ cp_lexer_maybe_grow_buffer (lexer);
+
+ /* If there weren't any tokens, then this one will be the first. */
+ if (!lexer->first_token)
+ lexer->first_token = lexer->last_token;
+ /* Similarly, if there were no available tokens, there is one now. */
+ if (!lexer->next_token)
+ lexer->next_token = lexer->last_token;
+
+ /* Figure out where we're going to store the new token. */
+ token = lexer->last_token;
+
+ /* Get a new token from the preprocessor. */
+ cp_lexer_get_preprocessor_token (lexer, token);
+
+ /* Increment LAST_TOKEN. */
+ lexer->last_token = cp_lexer_next_token (lexer, token);
+
+ /* Strings should have type `const char []'. Right now, we will
+ have an ARRAY_TYPE that is constant rather than an array of
+ constant elements.
+ FIXME: Make fix_string_type get this right in the first place. */
+ if ((token->type == CPP_STRING || token->type == CPP_WSTRING)
+ && flag_const_strings)
+ {
+ tree type;
+
+ /* Get the current type. It will be an ARRAY_TYPE. */
+ type = TREE_TYPE (token->value);
+ /* Use build_cplus_array_type to rebuild the array, thereby
+ getting the right type. */
+ type = build_cplus_array_type (TREE_TYPE (type), TYPE_DOMAIN (type));
+ /* Reset the type of the token. */
+ TREE_TYPE (token->value) = type;
+ }
+
+ return token;
+}
+
+/* If the circular buffer is full, make it bigger. */
+
+static void
+cp_lexer_maybe_grow_buffer (cp_lexer* lexer)
+{
+ /* If the buffer is full, enlarge it. */
+ if (lexer->last_token == lexer->first_token)
+ {
+ cp_token *new_buffer;
+ cp_token *old_buffer;
+ cp_token *new_first_token;
+ ptrdiff_t buffer_length;
+ size_t num_tokens_to_copy;
+
+ /* Remember the current buffer pointer. It will become invalid,
+ but we will need to do pointer arithmetic involving this
+ value. */
+ old_buffer = lexer->buffer;
+ /* Compute the current buffer size. */
+ buffer_length = lexer->buffer_end - lexer->buffer;
+ /* Allocate a buffer twice as big. */
+ new_buffer = ggc_realloc (lexer->buffer,
+ 2 * buffer_length * sizeof (cp_token));
+
+ /* Because the buffer is circular, logically consecutive tokens
+ are not necessarily placed consecutively in memory.
+ Therefore, we must keep move the tokens that were before
+ FIRST_TOKEN to the second half of the newly allocated
+ buffer. */
+ num_tokens_to_copy = (lexer->first_token - old_buffer);
+ memcpy (new_buffer + buffer_length,
+ new_buffer,
+ num_tokens_to_copy * sizeof (cp_token));
+ /* Clear the rest of the buffer. We never look at this storage,
+ but the garbage collector may. */
+ memset (new_buffer + buffer_length + num_tokens_to_copy, 0,
+ (buffer_length - num_tokens_to_copy) * sizeof (cp_token));
+
+ /* Now recompute all of the buffer pointers. */
+ new_first_token
+ = new_buffer + (lexer->first_token - old_buffer);
+ if (lexer->next_token != NULL)
+ {
+ ptrdiff_t next_token_delta;
+
+ if (lexer->next_token > lexer->first_token)
+ next_token_delta = lexer->next_token - lexer->first_token;
+ else
+ next_token_delta =
+ buffer_length - (lexer->first_token - lexer->next_token);
+ lexer->next_token = new_first_token + next_token_delta;
+ }
+ lexer->last_token = new_first_token + buffer_length;
+ lexer->buffer = new_buffer;
+ lexer->buffer_end = new_buffer + buffer_length * 2;
+ lexer->first_token = new_first_token;
+ }
+}
+
+/* Store the next token from the preprocessor in *TOKEN. */
+
+static void
+cp_lexer_get_preprocessor_token (cp_lexer *lexer ATTRIBUTE_UNUSED ,
+ cp_token *token)
+{
+ bool done;
+
+ /* If this not the main lexer, return a terminating CPP_EOF token. */
+ if (lexer != NULL && !lexer->main_lexer_p)
+ {
+ token->type = CPP_EOF;
+ token->location.line = 0;
+ token->location.file = NULL;
+ token->value = NULL_TREE;
+ token->keyword = RID_MAX;
+
+ return;
+ }
+
+ done = false;
+ /* Keep going until we get a token we like. */
+ while (!done)
+ {
+ /* Get a new token from the preprocessor. */
+ token->type = c_lex_with_flags (&token->value, &token->flags);
+ /* Issue messages about tokens we cannot process. */
+ switch (token->type)
+ {
+ case CPP_ATSIGN:
+ case CPP_HASH:
+ case CPP_PASTE:
+ error ("invalid token");
+ break;
+
+ default:
+ /* This is a good token, so we exit the loop. */
+ done = true;
+ break;
+ }
+ }
+ /* Now we've got our token. */
+ token->location = input_location;
+
+ /* Check to see if this token is a keyword. */
+ if (token->type == CPP_NAME
+ && C_IS_RESERVED_WORD (token->value))
+ {
+ /* Mark this token as a keyword. */
+ token->type = CPP_KEYWORD;
+ /* Record which keyword. */
+ token->keyword = C_RID_CODE (token->value);
+ /* Update the value. Some keywords are mapped to particular
+ entities, rather than simply having the value of the
+ corresponding IDENTIFIER_NODE. For example, `__const' is
+ mapped to `const'. */
+ token->value = ridpointers[token->keyword];
+ }
+ else
+ token->keyword = RID_MAX;
+}
+
+/* Return a pointer to the next token in the token stream, but do not
+ consume it. */
+
+static cp_token *
+cp_lexer_peek_token (cp_lexer* lexer)
+{
+ cp_token *token;
+
+ /* If there are no tokens, read one now. */
+ if (!lexer->next_token)
+ cp_lexer_read_token (lexer);
+
+ /* Provide debugging output. */
+ if (cp_lexer_debugging_p (lexer))
+ {
+ fprintf (cp_lexer_debug_stream, "cp_lexer: peeking at token: ");
+ cp_lexer_print_token (cp_lexer_debug_stream, lexer->next_token);
+ fprintf (cp_lexer_debug_stream, "\n");
+ }
+
+ token = lexer->next_token;
+ cp_lexer_set_source_position_from_token (lexer, token);
+ return token;
+}
+
+/* Return true if the next token has the indicated TYPE. */
+
+static bool
+cp_lexer_next_token_is (cp_lexer* lexer, enum cpp_ttype type)
+{
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (lexer);
+ /* Check to see if it has the indicated TYPE. */
+ return token->type == type;
+}
+
+/* Return true if the next token does not have the indicated TYPE. */
+
+static bool
+cp_lexer_next_token_is_not (cp_lexer* lexer, enum cpp_ttype type)
+{
+ return !cp_lexer_next_token_is (lexer, type);
+}
+
+/* Return true if the next token is the indicated KEYWORD. */
+
+static bool
+cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword)
+{
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (lexer);
+ /* Check to see if it is the indicated keyword. */
+ return token->keyword == keyword;
+}
+
+/* Return a pointer to the Nth token in the token stream. If N is 1,
+ then this is precisely equivalent to cp_lexer_peek_token. */
+
+static cp_token *
+cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n)
+{
+ cp_token *token;
+
+ /* N is 1-based, not zero-based. */
+ my_friendly_assert (n > 0, 20000224);
+
+ /* Skip ahead from NEXT_TOKEN, reading more tokens as necessary. */
+ token = lexer->next_token;
+ /* If there are no tokens in the buffer, get one now. */
+ if (!token)
+ {
+ cp_lexer_read_token (lexer);
+ token = lexer->next_token;
+ }
+
+ /* Now, read tokens until we have enough. */
+ while (--n > 0)
+ {
+ /* Advance to the next token. */
+ token = cp_lexer_next_token (lexer, token);
+ /* If that's all the tokens we have, read a new one. */
+ if (token == lexer->last_token)
+ token = cp_lexer_read_token (lexer);
+ }
+
+ return token;
+}
+
+/* Consume the next token. The pointer returned is valid only until
+ another token is read. Callers should preserve copy the token
+ explicitly if they will need its value for a longer period of
+ time. */
+
+static cp_token *
+cp_lexer_consume_token (cp_lexer* lexer)
+{
+ cp_token *token;
+
+ /* If there are no tokens, read one now. */
+ if (!lexer->next_token)
+ cp_lexer_read_token (lexer);
+
+ /* Remember the token we'll be returning. */
+ token = lexer->next_token;
+
+ /* Increment NEXT_TOKEN. */
+ lexer->next_token = cp_lexer_next_token (lexer,
+ lexer->next_token);
+ /* Check to see if we're all out of tokens. */
+ if (lexer->next_token == lexer->last_token)
+ lexer->next_token = NULL;
+
+ /* If we're not saving tokens, then move FIRST_TOKEN too. */
+ if (!cp_lexer_saving_tokens (lexer))
+ {
+ /* If there are no tokens available, set FIRST_TOKEN to NULL. */
+ if (!lexer->next_token)
+ lexer->first_token = NULL;
+ else
+ lexer->first_token = lexer->next_token;
+ }
+
+ /* Provide debugging output. */
+ if (cp_lexer_debugging_p (lexer))
+ {
+ fprintf (cp_lexer_debug_stream, "cp_lexer: consuming token: ");
+ cp_lexer_print_token (cp_lexer_debug_stream, token);
+ fprintf (cp_lexer_debug_stream, "\n");
+ }
+
+ return token;
+}
+
+/* Permanently remove the next token from the token stream. There
+ must be a valid next token already; this token never reads
+ additional tokens from the preprocessor. */
+
+static void
+cp_lexer_purge_token (cp_lexer *lexer)
+{
+ cp_token *token;
+ cp_token *next_token;
+
+ token = lexer->next_token;
+ while (true)
+ {
+ next_token = cp_lexer_next_token (lexer, token);
+ if (next_token == lexer->last_token)
+ break;
+ *token = *next_token;
+ token = next_token;
+ }
+
+ lexer->last_token = token;
+ /* The token purged may have been the only token remaining; if so,
+ clear NEXT_TOKEN. */
+ if (lexer->next_token == token)
+ lexer->next_token = NULL;
+}
+
+/* Permanently remove all tokens after TOKEN, up to, but not
+ including, the token that will be returned next by
+ cp_lexer_peek_token. */
+
+static void
+cp_lexer_purge_tokens_after (cp_lexer *lexer, cp_token *token)
+{
+ cp_token *peek;
+ cp_token *t1;
+ cp_token *t2;
+
+ if (lexer->next_token)
+ {
+ /* Copy the tokens that have not yet been read to the location
+ immediately following TOKEN. */
+ t1 = cp_lexer_next_token (lexer, token);
+ t2 = peek = cp_lexer_peek_token (lexer);
+ /* Move tokens into the vacant area between TOKEN and PEEK. */
+ while (t2 != lexer->last_token)
+ {
+ *t1 = *t2;
+ t1 = cp_lexer_next_token (lexer, t1);
+ t2 = cp_lexer_next_token (lexer, t2);
+ }
+ /* Now, the next available token is right after TOKEN. */
+ lexer->next_token = cp_lexer_next_token (lexer, token);
+ /* And the last token is wherever we ended up. */
+ lexer->last_token = t1;
+ }
+ else
+ {
+ /* There are no tokens in the buffer, so there is nothing to
+ copy. The last token in the buffer is TOKEN itself. */
+ lexer->last_token = cp_lexer_next_token (lexer, token);
+ }
+}
+
+/* Begin saving tokens. All tokens consumed after this point will be
+ preserved. */
+
+static void
+cp_lexer_save_tokens (cp_lexer* lexer)
+{
+ /* Provide debugging output. */
+ if (cp_lexer_debugging_p (lexer))
+ fprintf (cp_lexer_debug_stream, "cp_lexer: saving tokens\n");
+
+ /* Make sure that LEXER->NEXT_TOKEN is non-NULL so that we can
+ restore the tokens if required. */
+ if (!lexer->next_token)
+ cp_lexer_read_token (lexer);
+
+ VARRAY_PUSH_INT (lexer->saved_tokens,
+ cp_lexer_token_difference (lexer,
+ lexer->first_token,
+ lexer->next_token));
+}
+
+/* Commit to the portion of the token stream most recently saved. */
+
+static void
+cp_lexer_commit_tokens (cp_lexer* lexer)
+{
+ /* Provide debugging output. */
+ if (cp_lexer_debugging_p (lexer))
+ fprintf (cp_lexer_debug_stream, "cp_lexer: committing tokens\n");
+
+ VARRAY_POP (lexer->saved_tokens);
+}
+
+/* Return all tokens saved since the last call to cp_lexer_save_tokens
+ to the token stream. Stop saving tokens. */
+
+static void
+cp_lexer_rollback_tokens (cp_lexer* lexer)
+{
+ size_t delta;
+
+ /* Provide debugging output. */
+ if (cp_lexer_debugging_p (lexer))
+ fprintf (cp_lexer_debug_stream, "cp_lexer: restoring tokens\n");
+
+ /* Find the token that was the NEXT_TOKEN when we started saving
+ tokens. */
+ delta = VARRAY_TOP_INT(lexer->saved_tokens);
+ /* Make it the next token again now. */
+ lexer->next_token = cp_lexer_advance_token (lexer,
+ lexer->first_token,
+ delta);
+ /* It might be the case that there were no tokens when we started
+ saving tokens, but that there are some tokens now. */
+ if (!lexer->next_token && lexer->first_token)
+ lexer->next_token = lexer->first_token;
+
+ /* Stop saving tokens. */
+ VARRAY_POP (lexer->saved_tokens);
+}
+
+/* Print a representation of the TOKEN on the STREAM. */
+
+static void
+cp_lexer_print_token (FILE * stream, cp_token* token)
+{
+ const char *token_type = NULL;
+
+ /* Figure out what kind of token this is. */
+ switch (token->type)
+ {
+ case CPP_EQ:
+ token_type = "EQ";
+ break;
+
+ case CPP_COMMA:
+ token_type = "COMMA";
+ break;
+
+ case CPP_OPEN_PAREN:
+ token_type = "OPEN_PAREN";
+ break;
+
+ case CPP_CLOSE_PAREN:
+ token_type = "CLOSE_PAREN";
+ break;
+
+ case CPP_OPEN_BRACE:
+ token_type = "OPEN_BRACE";
+ break;
+
+ case CPP_CLOSE_BRACE:
+ token_type = "CLOSE_BRACE";
+ break;
+
+ case CPP_SEMICOLON:
+ token_type = "SEMICOLON";
+ break;
+
+ case CPP_NAME:
+ token_type = "NAME";
+ break;
+
+ case CPP_EOF:
+ token_type = "EOF";
+ break;
+
+ case CPP_KEYWORD:
+ token_type = "keyword";
+ break;
+
+ /* This is not a token that we know how to handle yet. */
+ default:
+ break;
+ }
+
+ /* If we have a name for the token, print it out. Otherwise, we
+ simply give the numeric code. */
+ if (token_type)
+ fprintf (stream, "%s", token_type);
+ else
+ fprintf (stream, "%d", token->type);
+ /* And, for an identifier, print the identifier name. */
+ if (token->type == CPP_NAME
+ /* Some keywords have a value that is not an IDENTIFIER_NODE.
+ For example, `struct' is mapped to an INTEGER_CST. */
+ || (token->type == CPP_KEYWORD
+ && TREE_CODE (token->value) == IDENTIFIER_NODE))
+ fprintf (stream, " %s", IDENTIFIER_POINTER (token->value));
+}
+
+/* Start emitting debugging information. */
+
+static void
+cp_lexer_start_debugging (cp_lexer* lexer)
+{
+ ++lexer->debugging_p;
+}
+
+/* Stop emitting debugging information. */
+
+static void
+cp_lexer_stop_debugging (cp_lexer* lexer)
+{
+ --lexer->debugging_p;
+}
+
+
+/* The parser. */
+
+/* Overview
+ --------
+
+ A cp_parser parses the token stream as specified by the C++
+ grammar. Its job is purely parsing, not semantic analysis. For
+ example, the parser breaks the token stream into declarators,
+ expressions, statements, and other similar syntactic constructs.
+ It does not check that the types of the expressions on either side
+ of an assignment-statement are compatible, or that a function is
+ not declared with a parameter of type `void'.
+
+ The parser invokes routines elsewhere in the compiler to perform
+ semantic analysis and to build up the abstract syntax tree for the
+ code processed.
+
+ The parser (and the template instantiation code, which is, in a
+ way, a close relative of parsing) are the only parts of the
+ compiler that should be calling push_scope and pop_scope, or
+ related functions. The parser (and template instantiation code)
+ keeps track of what scope is presently active; everything else
+ should simply honor that. (The code that generates static
+ initializers may also need to set the scope, in order to check
+ access control correctly when emitting the initializers.)
+
+ Methodology
+ -----------
+
+ The parser is of the standard recursive-descent variety. Upcoming
+ tokens in the token stream are examined in order to determine which
+ production to use when parsing a non-terminal. Some C++ constructs
+ require arbitrary look ahead to disambiguate. For example, it is
+ impossible, in the general case, to tell whether a statement is an
+ expression or declaration without scanning the entire statement.
+ Therefore, the parser is capable of "parsing tentatively." When the
+ parser is not sure what construct comes next, it enters this mode.
+ Then, while we attempt to parse the construct, the parser queues up
+ error messages, rather than issuing them immediately, and saves the
+ tokens it consumes. If the construct is parsed successfully, the
+ parser "commits", i.e., it issues any queued error messages and
+ the tokens that were being preserved are permanently discarded.
+ If, however, the construct is not parsed successfully, the parser
+ rolls back its state completely so that it can resume parsing using
+ a different alternative.
+
+ Future Improvements
+ -------------------
+
+ The performance of the parser could probably be improved
+ substantially. Some possible improvements include:
+
+ - The expression parser recurses through the various levels of
+ precedence as specified in the grammar, rather than using an
+ operator-precedence technique. Therefore, parsing a simple
+ identifier requires multiple recursive calls.
+
+ - We could often eliminate the need to parse tentatively by
+ looking ahead a little bit. In some places, this approach
+ might not entirely eliminate the need to parse tentatively, but
+ it might still speed up the average case. */
+
+/* Flags that are passed to some parsing functions. These values can
+ be bitwise-ored together. */
+
+typedef enum cp_parser_flags
+{
+ /* No flags. */
+ CP_PARSER_FLAGS_NONE = 0x0,
+ /* The construct is optional. If it is not present, then no error
+ should be issued. */
+ CP_PARSER_FLAGS_OPTIONAL = 0x1,
+ /* When parsing a type-specifier, do not allow user-defined types. */
+ CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2
+} cp_parser_flags;
+
+/* The different kinds of declarators we want to parse. */
+
+typedef enum cp_parser_declarator_kind
+{
+ /* We want an abstract declartor. */
+ CP_PARSER_DECLARATOR_ABSTRACT,
+ /* We want a named declarator. */
+ CP_PARSER_DECLARATOR_NAMED,
+ /* We don't mind, but the name must be an unqualified-id. */
+ CP_PARSER_DECLARATOR_EITHER
+} cp_parser_declarator_kind;
+
+/* A mapping from a token type to a corresponding tree node type. */
+
+typedef struct cp_parser_token_tree_map_node
+{
+ /* The token type. */
+ ENUM_BITFIELD (cpp_ttype) token_type : 8;
+ /* The corresponding tree code. */
+ ENUM_BITFIELD (tree_code) tree_type : 8;
+} cp_parser_token_tree_map_node;
+
+/* A complete map consists of several ordinary entries, followed by a
+ terminator. The terminating entry has a token_type of CPP_EOF. */
+
+typedef cp_parser_token_tree_map_node cp_parser_token_tree_map[];
+
+/* The status of a tentative parse. */
+
+typedef enum cp_parser_status_kind
+{
+ /* No errors have occurred. */
+ CP_PARSER_STATUS_KIND_NO_ERROR,
+ /* An error has occurred. */
+ CP_PARSER_STATUS_KIND_ERROR,
+ /* We are committed to this tentative parse, whether or not an error
+ has occurred. */
+ CP_PARSER_STATUS_KIND_COMMITTED
+} cp_parser_status_kind;
+
+/* Context that is saved and restored when parsing tentatively. */
+
+typedef struct cp_parser_context GTY (())
+{
+ /* If this is a tentative parsing context, the status of the
+ tentative parse. */
+ enum cp_parser_status_kind status;
+ /* If non-NULL, we have just seen a `x->' or `x.' expression. Names
+ that are looked up in this context must be looked up both in the
+ scope given by OBJECT_TYPE (the type of `x' or `*x') and also in
+ the context of the containing expression. */
+ tree object_type;
+ /* The next parsing context in the stack. */
+ struct cp_parser_context *next;
+} cp_parser_context;
+
+/* Prototypes. */
+
+/* Constructors and destructors. */
+
+static cp_parser_context *cp_parser_context_new
+ (cp_parser_context *);
+
+/* Class variables. */
+
+static GTY((deletable (""))) cp_parser_context* cp_parser_context_free_list;
+
+/* Constructors and destructors. */
+
+/* Construct a new context. The context below this one on the stack
+ is given by NEXT. */
+
+static cp_parser_context *
+cp_parser_context_new (cp_parser_context* next)
+{
+ cp_parser_context *context;
+
+ /* Allocate the storage. */
+ if (cp_parser_context_free_list != NULL)
+ {
+ /* Pull the first entry from the free list. */
+ context = cp_parser_context_free_list;
+ cp_parser_context_free_list = context->next;
+ memset (context, 0, sizeof (*context));
+ }
+ else
+ context = ggc_alloc_cleared (sizeof (cp_parser_context));
+ /* No errors have occurred yet in this context. */
+ context->status = CP_PARSER_STATUS_KIND_NO_ERROR;
+ /* If this is not the bottomost context, copy information that we
+ need from the previous context. */
+ if (next)
+ {
+ /* If, in the NEXT context, we are parsing an `x->' or `x.'
+ expression, then we are parsing one in this context, too. */
+ context->object_type = next->object_type;
+ /* Thread the stack. */
+ context->next = next;
+ }
+
+ return context;
+}
+
+/* The cp_parser structure represents the C++ parser. */
+
+typedef struct cp_parser GTY(())
+{
+ /* The lexer from which we are obtaining tokens. */
+ cp_lexer *lexer;
+
+ /* The scope in which names should be looked up. If NULL_TREE, then
+ we look up names in the scope that is currently open in the
+ source program. If non-NULL, this is either a TYPE or
+ NAMESPACE_DECL for the scope in which we should look.
+
+ This value is not cleared automatically after a name is looked
+ up, so we must be careful to clear it before starting a new look
+ up sequence. (If it is not cleared, then `X::Y' followed by `Z'
+ will look up `Z' in the scope of `X', rather than the current
+ scope.) Unfortunately, it is difficult to tell when name lookup
+ is complete, because we sometimes peek at a token, look it up,
+ and then decide not to consume it. */
+ tree scope;
+
+ /* OBJECT_SCOPE and QUALIFYING_SCOPE give the scopes in which the
+ last lookup took place. OBJECT_SCOPE is used if an expression
+ like "x->y" or "x.y" was used; it gives the type of "*x" or "x",
+ respectively. QUALIFYING_SCOPE is used for an expression of the
+ form "X::Y"; it refers to X. */
+ tree object_scope;
+ tree qualifying_scope;
+
+ /* A stack of parsing contexts. All but the bottom entry on the
+ stack will be tentative contexts.
+
+ We parse tentatively in order to determine which construct is in
+ use in some situations. For example, in order to determine
+ whether a statement is an expression-statement or a
+ declaration-statement we parse it tentatively as a
+ declaration-statement. If that fails, we then reparse the same
+ token stream as an expression-statement. */
+ cp_parser_context *context;
+
+ /* True if we are parsing GNU C++. If this flag is not set, then
+ GNU extensions are not recognized. */
+ bool allow_gnu_extensions_p;
+
+ /* TRUE if the `>' token should be interpreted as the greater-than
+ operator. FALSE if it is the end of a template-id or
+ template-parameter-list. */
+ bool greater_than_is_operator_p;
+
+ /* TRUE if default arguments are allowed within a parameter list
+ that starts at this point. FALSE if only a gnu extension makes
+ them permissible. */
+ bool default_arg_ok_p;
+
+ /* TRUE if we are parsing an integral constant-expression. See
+ [expr.const] for a precise definition. */
+ bool integral_constant_expression_p;
+
+ /* TRUE if we are parsing an integral constant-expression -- but a
+ non-constant expression should be permitted as well. This flag
+ is used when parsing an array bound so that GNU variable-length
+ arrays are tolerated. */
+ bool allow_non_integral_constant_expression_p;
+
+ /* TRUE if ALLOW_NON_CONSTANT_EXPRESSION_P is TRUE and something has
+ been seen that makes the expression non-constant. */
+ bool non_integral_constant_expression_p;
+
+ /* TRUE if we are parsing the argument to "__offsetof__". */
+ bool in_offsetof_p;
+
+ /* TRUE if local variable names and `this' are forbidden in the
+ current context. */
+ bool local_variables_forbidden_p;
+
+ /* TRUE if the declaration we are parsing is part of a
+ linkage-specification of the form `extern string-literal
+ declaration'. */
+ bool in_unbraced_linkage_specification_p;
+
+ /* TRUE if we are presently parsing a declarator, after the
+ direct-declarator. */
+ bool in_declarator_p;
+
+ /* TRUE if we are presently parsing a template-argument-list. */
+ bool in_template_argument_list_p;
+
+ /* TRUE if we are presently parsing the body of an
+ iteration-statement. */
+ bool in_iteration_statement_p;
+
+ /* TRUE if we are presently parsing the body of a switch
+ statement. */
+ bool in_switch_statement_p;
+
+ /* TRUE if we are parsing a type-id in an expression context. In
+ such a situation, both "type (expr)" and "type (type)" are valid
+ alternatives. */
+ bool in_type_id_in_expr_p;
+
+ /* If non-NULL, then we are parsing a construct where new type
+ definitions are not permitted. The string stored here will be
+ issued as an error message if a type is defined. */
+ const char *type_definition_forbidden_message;
+
+ /* A list of lists. The outer list is a stack, used for member
+ functions of local classes. At each level there are two sub-list,
+ one on TREE_VALUE and one on TREE_PURPOSE. Each of those
+ sub-lists has a FUNCTION_DECL or TEMPLATE_DECL on their
+ TREE_VALUE's. The functions are chained in reverse declaration
+ order.
+
+ The TREE_PURPOSE sublist contains those functions with default
+ arguments that need post processing, and the TREE_VALUE sublist
+ contains those functions with definitions that need post
+ processing.
+
+ These lists can only be processed once the outermost class being
+ defined is complete. */
+ tree unparsed_functions_queues;
+
+ /* The number of classes whose definitions are currently in
+ progress. */
+ unsigned num_classes_being_defined;
+
+ /* The number of template parameter lists that apply directly to the
+ current declaration. */
+ unsigned num_template_parameter_lists;
+} cp_parser;
+
+/* The type of a function that parses some kind of expression. */
+typedef tree (*cp_parser_expression_fn) (cp_parser *);
+
+/* Prototypes. */
+
+/* Constructors and destructors. */
+
+static cp_parser *cp_parser_new
+ (void);
+
+/* Routines to parse various constructs.
+
+ Those that return `tree' will return the error_mark_node (rather
+ than NULL_TREE) if a parse error occurs, unless otherwise noted.
+ Sometimes, they will return an ordinary node if error-recovery was
+ attempted, even though a parse error occurred. So, to check
+ whether or not a parse error occurred, you should always use
+ cp_parser_error_occurred. If the construct is optional (indicated
+ either by an `_opt' in the name of the function that does the
+ parsing or via a FLAGS parameter), then NULL_TREE is returned if
+ the construct is not present. */
+
+/* Lexical conventions [gram.lex] */
+
+static tree cp_parser_identifier
+ (cp_parser *);
+
+/* Basic concepts [gram.basic] */
+
+static bool cp_parser_translation_unit
+ (cp_parser *);
+
+/* Expressions [gram.expr] */
+
+static tree cp_parser_primary_expression
+ (cp_parser *, cp_id_kind *, tree *);
+static tree cp_parser_id_expression
+ (cp_parser *, bool, bool, bool *, bool);
+static tree cp_parser_unqualified_id
+ (cp_parser *, bool, bool, bool);
+static tree cp_parser_nested_name_specifier_opt
+ (cp_parser *, bool, bool, bool, bool);
+static tree cp_parser_nested_name_specifier
+ (cp_parser *, bool, bool, bool, bool);
+static tree cp_parser_class_or_namespace_name
+ (cp_parser *, bool, bool, bool, bool, bool);
+static tree cp_parser_postfix_expression
+ (cp_parser *, bool);
+static tree cp_parser_parenthesized_expression_list
+ (cp_parser *, bool, bool *);
+static void cp_parser_pseudo_destructor_name
+ (cp_parser *, tree *, tree *);
+static tree cp_parser_unary_expression
+ (cp_parser *, bool);
+static enum tree_code cp_parser_unary_operator
+ (cp_token *);
+static tree cp_parser_new_expression
+ (cp_parser *);
+static tree cp_parser_new_placement
+ (cp_parser *);
+static tree cp_parser_new_type_id
+ (cp_parser *);
+static tree cp_parser_new_declarator_opt
+ (cp_parser *);
+static tree cp_parser_direct_new_declarator
+ (cp_parser *);
+static tree cp_parser_new_initializer
+ (cp_parser *);
+static tree cp_parser_delete_expression
+ (cp_parser *);
+static tree cp_parser_cast_expression
+ (cp_parser *, bool);
+static tree cp_parser_pm_expression
+ (cp_parser *);
+static tree cp_parser_multiplicative_expression
+ (cp_parser *);
+static tree cp_parser_additive_expression
+ (cp_parser *);
+static tree cp_parser_shift_expression
+ (cp_parser *);
+static tree cp_parser_relational_expression
+ (cp_parser *);
+static tree cp_parser_equality_expression
+ (cp_parser *);
+static tree cp_parser_and_expression
+ (cp_parser *);
+static tree cp_parser_exclusive_or_expression
+ (cp_parser *);
+static tree cp_parser_inclusive_or_expression
+ (cp_parser *);
+static tree cp_parser_logical_and_expression
+ (cp_parser *);
+static tree cp_parser_logical_or_expression
+ (cp_parser *);
+static tree cp_parser_question_colon_clause
+ (cp_parser *, tree);
+static tree cp_parser_assignment_expression
+ (cp_parser *);
+static enum tree_code cp_parser_assignment_operator_opt
+ (cp_parser *);
+static tree cp_parser_expression
+ (cp_parser *);
+static tree cp_parser_constant_expression
+ (cp_parser *, bool, bool *);
+
+/* Statements [gram.stmt.stmt] */
+
+static void cp_parser_statement
+ (cp_parser *, bool);
+static tree cp_parser_labeled_statement
+ (cp_parser *, bool);
+static tree cp_parser_expression_statement
+ (cp_parser *, bool);
+static tree cp_parser_compound_statement
+ (cp_parser *, bool);
+static void cp_parser_statement_seq_opt
+ (cp_parser *, bool);
+static tree cp_parser_selection_statement
+ (cp_parser *);
+static tree cp_parser_condition
+ (cp_parser *);
+static tree cp_parser_iteration_statement
+ (cp_parser *);
+static void cp_parser_for_init_statement
+ (cp_parser *);
+static tree cp_parser_jump_statement
+ (cp_parser *);
+static void cp_parser_declaration_statement
+ (cp_parser *);
+
+static tree cp_parser_implicitly_scoped_statement
+ (cp_parser *);
+static void cp_parser_already_scoped_statement
+ (cp_parser *);
+
+/* Declarations [gram.dcl.dcl] */
+
+static void cp_parser_declaration_seq_opt
+ (cp_parser *);
+static void cp_parser_declaration
+ (cp_parser *);
+static void cp_parser_block_declaration
+ (cp_parser *, bool);
+static void cp_parser_simple_declaration
+ (cp_parser *, bool);
+static tree cp_parser_decl_specifier_seq
+ (cp_parser *, cp_parser_flags, tree *, int *);
+static tree cp_parser_storage_class_specifier_opt
+ (cp_parser *);
+static tree cp_parser_function_specifier_opt
+ (cp_parser *);
+static tree cp_parser_type_specifier
+ (cp_parser *, cp_parser_flags, bool, bool, int *, bool *);
+static tree cp_parser_simple_type_specifier
+ (cp_parser *, cp_parser_flags, bool);
+static tree cp_parser_type_name
+ (cp_parser *);
+static tree cp_parser_elaborated_type_specifier
+ (cp_parser *, bool, bool);
+static tree cp_parser_enum_specifier
+ (cp_parser *);
+static void cp_parser_enumerator_list
+ (cp_parser *, tree);
+static void cp_parser_enumerator_definition
+ (cp_parser *, tree);
+static tree cp_parser_namespace_name
+ (cp_parser *);
+static void cp_parser_namespace_definition
+ (cp_parser *);
+static void cp_parser_namespace_body
+ (cp_parser *);
+static tree cp_parser_qualified_namespace_specifier
+ (cp_parser *);
+static void cp_parser_namespace_alias_definition
+ (cp_parser *);
+static void cp_parser_using_declaration
+ (cp_parser *);
+static void cp_parser_using_directive
+ (cp_parser *);
+static void cp_parser_asm_definition
+ (cp_parser *);
+static void cp_parser_linkage_specification
+ (cp_parser *);
+
+/* Declarators [gram.dcl.decl] */
+
+static tree cp_parser_init_declarator
+ (cp_parser *, tree, tree, bool, bool, int, bool *);
+static tree cp_parser_declarator
+ (cp_parser *, cp_parser_declarator_kind, int *, bool *);
+static tree cp_parser_direct_declarator
+ (cp_parser *, cp_parser_declarator_kind, int *);
+static enum tree_code cp_parser_ptr_operator
+ (cp_parser *, tree *, tree *);
+static tree cp_parser_cv_qualifier_seq_opt
+ (cp_parser *);
+static tree cp_parser_cv_qualifier_opt
+ (cp_parser *);
+static tree cp_parser_declarator_id
+ (cp_parser *);
+static tree cp_parser_type_id
+ (cp_parser *);
+static tree cp_parser_type_specifier_seq
+ (cp_parser *);
+static tree cp_parser_parameter_declaration_clause
+ (cp_parser *);
+static tree cp_parser_parameter_declaration_list
+ (cp_parser *);
+static tree cp_parser_parameter_declaration
+ (cp_parser *, bool, bool *);
+static void cp_parser_function_body
+ (cp_parser *);
+static tree cp_parser_initializer
+ (cp_parser *, bool *, bool *);
+static tree cp_parser_initializer_clause
+ (cp_parser *, bool *);
+static tree cp_parser_initializer_list
+ (cp_parser *, bool *);
+
+static bool cp_parser_ctor_initializer_opt_and_function_body
+ (cp_parser *);
+
+/* Classes [gram.class] */
+
+static tree cp_parser_class_name
+ (cp_parser *, bool, bool, bool, bool, bool, bool);
+static tree cp_parser_class_specifier
+ (cp_parser *);
+static tree cp_parser_class_head
+ (cp_parser *, bool *, tree *);
+static enum tag_types cp_parser_class_key
+ (cp_parser *);
+static void cp_parser_member_specification_opt
+ (cp_parser *);
+static void cp_parser_member_declaration
+ (cp_parser *);
+static tree cp_parser_pure_specifier
+ (cp_parser *);
+static tree cp_parser_constant_initializer
+ (cp_parser *);
+
+/* Derived classes [gram.class.derived] */
+
+static tree cp_parser_base_clause
+ (cp_parser *);
+static tree cp_parser_base_specifier
+ (cp_parser *);
+
+/* Special member functions [gram.special] */
+
+static tree cp_parser_conversion_function_id
+ (cp_parser *);
+static tree cp_parser_conversion_type_id
+ (cp_parser *);
+static tree cp_parser_conversion_declarator_opt
+ (cp_parser *);
+static bool cp_parser_ctor_initializer_opt
+ (cp_parser *);
+static void cp_parser_mem_initializer_list
+ (cp_parser *);
+static tree cp_parser_mem_initializer
+ (cp_parser *);
+static tree cp_parser_mem_initializer_id
+ (cp_parser *);
+
+/* Overloading [gram.over] */
+
+static tree cp_parser_operator_function_id
+ (cp_parser *);
+static tree cp_parser_operator
+ (cp_parser *);
+
+/* Templates [gram.temp] */
+
+static void cp_parser_template_declaration
+ (cp_parser *, bool);
+static tree cp_parser_template_parameter_list
+ (cp_parser *);
+static tree cp_parser_template_parameter
+ (cp_parser *);
+static tree cp_parser_type_parameter
+ (cp_parser *);
+static tree cp_parser_template_id
+ (cp_parser *, bool, bool, bool);
+static tree cp_parser_template_name
+ (cp_parser *, bool, bool, bool, bool *);
+static tree cp_parser_template_argument_list
+ (cp_parser *);
+static tree cp_parser_template_argument
+ (cp_parser *);
+static void cp_parser_explicit_instantiation
+ (cp_parser *);
+static void cp_parser_explicit_specialization
+ (cp_parser *);
+
+/* Exception handling [gram.exception] */
+
+static tree cp_parser_try_block
+ (cp_parser *);
+static bool cp_parser_function_try_block
+ (cp_parser *);
+static void cp_parser_handler_seq
+ (cp_parser *);
+static void cp_parser_handler
+ (cp_parser *);
+static tree cp_parser_exception_declaration
+ (cp_parser *);
+static tree cp_parser_throw_expression
+ (cp_parser *);
+static tree cp_parser_exception_specification_opt
+ (cp_parser *);
+static tree cp_parser_type_id_list
+ (cp_parser *);
+
+/* GNU Extensions */
+
+static tree cp_parser_asm_specification_opt
+ (cp_parser *);
+static tree cp_parser_asm_operand_list
+ (cp_parser *);
+static tree cp_parser_asm_clobber_list
+ (cp_parser *);
+static tree cp_parser_attributes_opt
+ (cp_parser *);
+static tree cp_parser_attribute_list
+ (cp_parser *);
+static bool cp_parser_extension_opt
+ (cp_parser *, int *);
+static void cp_parser_label_declaration
+ (cp_parser *);
+
+/* Utility Routines */
+
+static tree cp_parser_lookup_name
+ (cp_parser *, tree, bool, bool, bool, bool);
+static tree cp_parser_lookup_name_simple
+ (cp_parser *, tree);
+static tree cp_parser_maybe_treat_template_as_class
+ (tree, bool);
+static bool cp_parser_check_declarator_template_parameters
+ (cp_parser *, tree);
+static bool cp_parser_check_template_parameters
+ (cp_parser *, unsigned);
+static tree cp_parser_simple_cast_expression
+ (cp_parser *);
+static tree cp_parser_binary_expression
+ (cp_parser *, const cp_parser_token_tree_map, cp_parser_expression_fn);
+static tree cp_parser_global_scope_opt
+ (cp_parser *, bool);
+static bool cp_parser_constructor_declarator_p
+ (cp_parser *, bool);
+static tree cp_parser_function_definition_from_specifiers_and_declarator
+ (cp_parser *, tree, tree, tree);
+static tree cp_parser_function_definition_after_declarator
+ (cp_parser *, bool);
+static void cp_parser_template_declaration_after_export
+ (cp_parser *, bool);
+static tree cp_parser_single_declaration
+ (cp_parser *, bool, bool *);
+static tree cp_parser_functional_cast
+ (cp_parser *, tree);
+static tree cp_parser_save_member_function_body
+ (cp_parser *, tree, tree, tree);
+static tree cp_parser_enclosed_template_argument_list
+ (cp_parser *);
+static void cp_parser_save_default_args
+ (cp_parser *, tree);
+static void cp_parser_late_parsing_for_member
+ (cp_parser *, tree);
+static void cp_parser_late_parsing_default_args
+ (cp_parser *, tree);
+static tree cp_parser_sizeof_operand
+ (cp_parser *, enum rid);
+static bool cp_parser_declares_only_class_p
+ (cp_parser *);
+static bool cp_parser_friend_p
+ (tree);
+static cp_token *cp_parser_require
+ (cp_parser *, enum cpp_ttype, const char *);
+static cp_token *cp_parser_require_keyword
+ (cp_parser *, enum rid, const char *);
+static bool cp_parser_token_starts_function_definition_p
+ (cp_token *);
+static bool cp_parser_next_token_starts_class_definition_p
+ (cp_parser *);
+static bool cp_parser_next_token_ends_template_argument_p
+ (cp_parser *);
+static bool cp_parser_nth_token_starts_template_argument_list_p
+ (cp_parser *, size_t);
+static enum tag_types cp_parser_token_is_class_key
+ (cp_token *);
+static void cp_parser_check_class_key
+ (enum tag_types, tree type);
+static void cp_parser_check_access_in_redeclaration
+ (tree type);
+static bool cp_parser_optional_template_keyword
+ (cp_parser *);
+static void cp_parser_pre_parsed_nested_name_specifier
+ (cp_parser *);
+static void cp_parser_cache_group
+ (cp_parser *, cp_token_cache *, enum cpp_ttype, unsigned);
+static void cp_parser_parse_tentatively
+ (cp_parser *);
+static void cp_parser_commit_to_tentative_parse
+ (cp_parser *);
+static void cp_parser_abort_tentative_parse
+ (cp_parser *);
+static bool cp_parser_parse_definitely
+ (cp_parser *);
+static inline bool cp_parser_parsing_tentatively
+ (cp_parser *);
+static bool cp_parser_committed_to_tentative_parse
+ (cp_parser *);
+static void cp_parser_error
+ (cp_parser *, const char *);
+static void cp_parser_name_lookup_error
+ (cp_parser *, tree, tree, const char *);
+static bool cp_parser_simulate_error
+ (cp_parser *);
+static void cp_parser_check_type_definition
+ (cp_parser *);
+static void cp_parser_check_for_definition_in_return_type
+ (tree, int);
+static void cp_parser_check_for_invalid_template_id
+ (cp_parser *, tree);
+static bool cp_parser_non_integral_constant_expression
+ (cp_parser *, const char *);
+static bool cp_parser_diagnose_invalid_type_name
+ (cp_parser *);
+static int cp_parser_skip_to_closing_parenthesis
+ (cp_parser *, bool, bool, bool);
+static void cp_parser_skip_to_end_of_statement
+ (cp_parser *);
+static void cp_parser_consume_semicolon_at_end_of_statement
+ (cp_parser *);
+static void cp_parser_skip_to_end_of_block_or_statement
+ (cp_parser *);
+static void cp_parser_skip_to_closing_brace
+ (cp_parser *);
+static void cp_parser_skip_until_found
+ (cp_parser *, enum cpp_ttype, const char *);
+static bool cp_parser_error_occurred
+ (cp_parser *);
+static bool cp_parser_allow_gnu_extensions_p
+ (cp_parser *);
+static bool cp_parser_is_string_literal
+ (cp_token *);
+static bool cp_parser_is_keyword
+ (cp_token *, enum rid);
+
+/* Returns nonzero if we are parsing tentatively. */
+
+static inline bool
+cp_parser_parsing_tentatively (cp_parser* parser)
+{
+ return parser->context->next != NULL;
+}
+
+/* Returns nonzero if TOKEN is a string literal. */
+
+static bool
+cp_parser_is_string_literal (cp_token* token)
+{
+ return (token->type == CPP_STRING || token->type == CPP_WSTRING);
+}
+
+/* Returns nonzero if TOKEN is the indicated KEYWORD. */
+
+static bool
+cp_parser_is_keyword (cp_token* token, enum rid keyword)
+{
+ return token->keyword == keyword;
+}
+
+/* Issue the indicated error MESSAGE. */
+
+static void
+cp_parser_error (cp_parser* parser, const char* message)
+{
+ /* Output the MESSAGE -- unless we're parsing tentatively. */
+ if (!cp_parser_simulate_error (parser))
+ {
+ cp_token *token;
+ token = cp_lexer_peek_token (parser->lexer);
+ c_parse_error (message,
+ /* Because c_parser_error does not understand
+ CPP_KEYWORD, keywords are treated like
+ identifiers. */
+ (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
+ token->value);
+ }
+}
+
+/* Issue an error about name-lookup failing. NAME is the
+ IDENTIFIER_NODE DECL is the result of
+ the lookup (as returned from cp_parser_lookup_name). DESIRED is
+ the thing that we hoped to find. */
+
+static void
+cp_parser_name_lookup_error (cp_parser* parser,
+ tree name,
+ tree decl,
+ const char* desired)
+{
+ /* If name lookup completely failed, tell the user that NAME was not
+ declared. */
+ if (decl == error_mark_node)
+ {
+ if (parser->scope && parser->scope != global_namespace)
+ error ("`%D::%D' has not been declared",
+ parser->scope, name);
+ else if (parser->scope == global_namespace)
+ error ("`::%D' has not been declared", name);
+ else
+ error ("`%D' has not been declared", name);
+ }
+ else if (parser->scope && parser->scope != global_namespace)
+ error ("`%D::%D' %s", parser->scope, name, desired);
+ else if (parser->scope == global_namespace)
+ error ("`::%D' %s", name, desired);
+ else
+ error ("`%D' %s", name, desired);
+}
+
+/* If we are parsing tentatively, remember that an error has occurred
+ during this tentative parse. Returns true if the error was
+ simulated; false if a messgae should be issued by the caller. */
+
+static bool
+cp_parser_simulate_error (cp_parser* parser)
+{
+ if (cp_parser_parsing_tentatively (parser)
+ && !cp_parser_committed_to_tentative_parse (parser))
+ {
+ parser->context->status = CP_PARSER_STATUS_KIND_ERROR;
+ return true;
+ }
+ return false;
+}
+
+/* This function is called when a type is defined. If type
+ definitions are forbidden at this point, an error message is
+ issued. */
+
+static void
+cp_parser_check_type_definition (cp_parser* parser)
+{
+ /* If types are forbidden here, issue a message. */
+ if (parser->type_definition_forbidden_message)
+ /* Use `%s' to print the string in case there are any escape
+ characters in the message. */
+ error ("%s", parser->type_definition_forbidden_message);
+}
+
+/* This function is called when a declaration is parsed. If
+ DECLARATOR is a function declarator and DECLARES_CLASS_OR_ENUM
+ indicates that a type was defined in the decl-specifiers for DECL,
+ then an error is issued. */
+
+static void
+cp_parser_check_for_definition_in_return_type (tree declarator,
+ int declares_class_or_enum)
+{
+ /* [dcl.fct] forbids type definitions in return types.
+ Unfortunately, it's not easy to know whether or not we are
+ processing a return type until after the fact. */
+ while (declarator
+ && (TREE_CODE (declarator) == INDIRECT_REF
+ || TREE_CODE (declarator) == ADDR_EXPR))
+ declarator = TREE_OPERAND (declarator, 0);
+ if (declarator
+ && TREE_CODE (declarator) == CALL_EXPR
+ && declares_class_or_enum & 2)
+ error ("new types may not be defined in a return type");
+}
+
+/* A type-specifier (TYPE) has been parsed which cannot be followed by
+ "<" in any valid C++ program. If the next token is indeed "<",
+ issue a message warning the user about what appears to be an
+ invalid attempt to form a template-id. */
+
+static void
+cp_parser_check_for_invalid_template_id (cp_parser* parser,
+ tree type)
+{
+ ptrdiff_t start;
+ cp_token *token;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
+ {
+ if (TYPE_P (type))
+ error ("`%T' is not a template", type);
+ else if (TREE_CODE (type) == IDENTIFIER_NODE)
+ error ("`%s' is not a template", IDENTIFIER_POINTER (type));
+ else
+ error ("invalid template-id");
+ /* Remember the location of the invalid "<". */
+ if (cp_parser_parsing_tentatively (parser)
+ && !cp_parser_committed_to_tentative_parse (parser))
+ {
+ token = cp_lexer_peek_token (parser->lexer);
+ token = cp_lexer_prev_token (parser->lexer, token);
+ start = cp_lexer_token_difference (parser->lexer,
+ parser->lexer->first_token,
+ token);
+ }
+ else
+ start = -1;
+ /* Consume the "<". */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the template arguments. */
+ cp_parser_enclosed_template_argument_list (parser);
+ /* Permanently remove the invalid template arguments so that
+ this error message is not issued again. */
+ if (start >= 0)
+ {
+ token = cp_lexer_advance_token (parser->lexer,
+ parser->lexer->first_token,
+ start);
+ cp_lexer_purge_tokens_after (parser->lexer, token);
+ }
+ }
+}
+
+/* If parsing an integral constant-expression, issue an error message
+ about the fact that THING appeared and return true. Otherwise,
+ return false, marking the current expression as non-constant. */
+
+static bool
+cp_parser_non_integral_constant_expression (cp_parser *parser,
+ const char *thing)
+{
+ if (parser->integral_constant_expression_p)
+ {
+ if (!parser->allow_non_integral_constant_expression_p)
+ {
+ error ("%s cannot appear in a constant-expression", thing);
+ return true;
+ }
+ parser->non_integral_constant_expression_p = true;
+ }
+ return false;
+}
+
+/* Check for a common situation where a type-name should be present,
+ but is not, and issue a sensible error message. Returns true if an
+ invalid type-name was detected. */
+
+static bool
+cp_parser_diagnose_invalid_type_name (cp_parser *parser)
+{
+ /* If the next two tokens are both identifiers, the code is
+ erroneous. The usual cause of this situation is code like:
+
+ T t;
+
+ where "T" should name a type -- but does not. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME)
+ {
+ tree name;
+
+ /* If parsing tentatively, we should commit; we really are
+ looking at a declaration. */
+ /* Consume the first identifier. */
+ name = cp_lexer_consume_token (parser->lexer)->value;
+ /* Issue an error message. */
+ error ("`%s' does not name a type", IDENTIFIER_POINTER (name));
+ /* If we're in a template class, it's possible that the user was
+ referring to a type from a base class. For example:
+
+ template <typename T> struct A { typedef T X; };
+ template <typename T> struct B : public A<T> { X x; };
+
+ The user should have said "typename A<T>::X". */
+ if (processing_template_decl && current_class_type)
+ {
+ tree b;
+
+ for (b = TREE_CHAIN (TYPE_BINFO (current_class_type));
+ b;
+ b = TREE_CHAIN (b))
+ {
+ tree base_type = BINFO_TYPE (b);
+ if (CLASS_TYPE_P (base_type)
+ && dependent_type_p (base_type))
+ {
+ tree field;
+ /* Go from a particular instantiation of the
+ template (which will have an empty TYPE_FIELDs),
+ to the main version. */
+ base_type = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (base_type);
+ for (field = TYPE_FIELDS (base_type);
+ field;
+ field = TREE_CHAIN (field))
+ if (TREE_CODE (field) == TYPE_DECL
+ && DECL_NAME (field) == name)
+ {
+ error ("(perhaps `typename %T::%s' was intended)",
+ BINFO_TYPE (b), IDENTIFIER_POINTER (name));
+ break;
+ }
+ if (field)
+ break;
+ }
+ }
+ }
+ /* Skip to the end of the declaration; there's no point in
+ trying to process it. */
+ cp_parser_skip_to_end_of_statement (parser);
+
+ return true;
+ }
+
+ return false;
+}
+
+/* Consume tokens up to, and including, the next non-nested closing `)'.
+ Returns 1 iff we found a closing `)'. RECOVERING is true, if we
+ are doing error recovery. Returns -1 if OR_COMMA is true and we
+ found an unnested comma. */
+
+static int
+cp_parser_skip_to_closing_parenthesis (cp_parser *parser,
+ bool recovering,
+ bool or_comma,
+ bool consume_paren)
+{
+ unsigned paren_depth = 0;
+ unsigned brace_depth = 0;
+
+ if (recovering && !or_comma && cp_parser_parsing_tentatively (parser)
+ && !cp_parser_committed_to_tentative_parse (parser))
+ return 0;
+
+ while (true)
+ {
+ cp_token *token;
+
+ /* If we've run out of tokens, then there is no closing `)'. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+ return 0;
+
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* This matches the processing in skip_to_end_of_statement. */
+ if (token->type == CPP_SEMICOLON && !brace_depth)
+ return 0;
+ if (token->type == CPP_OPEN_BRACE)
+ ++brace_depth;
+ if (token->type == CPP_CLOSE_BRACE)
+ {
+ if (!brace_depth--)
+ return 0;
+ }
+ if (recovering && or_comma && token->type == CPP_COMMA
+ && !brace_depth && !paren_depth)
+ return -1;
+
+ if (!brace_depth)
+ {
+ /* If it is an `(', we have entered another level of nesting. */
+ if (token->type == CPP_OPEN_PAREN)
+ ++paren_depth;
+ /* If it is a `)', then we might be done. */
+ else if (token->type == CPP_CLOSE_PAREN && !paren_depth--)
+ {
+ if (consume_paren)
+ cp_lexer_consume_token (parser->lexer);
+ return 1;
+ }
+ }
+
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+}
+
+/* Consume tokens until we reach the end of the current statement.
+ Normally, that will be just before consuming a `;'. However, if a
+ non-nested `}' comes first, then we stop before consuming that. */
+
+static void
+cp_parser_skip_to_end_of_statement (cp_parser* parser)
+{
+ unsigned nesting_depth = 0;
+
+ while (true)
+ {
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If we've run out of tokens, stop. */
+ if (token->type == CPP_EOF)
+ break;
+ /* If the next token is a `;', we have reached the end of the
+ statement. */
+ if (token->type == CPP_SEMICOLON && !nesting_depth)
+ break;
+ /* If the next token is a non-nested `}', then we have reached
+ the end of the current block. */
+ if (token->type == CPP_CLOSE_BRACE)
+ {
+ /* If this is a non-nested `}', stop before consuming it.
+ That way, when confronted with something like:
+
+ { 3 + }
+
+ we stop before consuming the closing `}', even though we
+ have not yet reached a `;'. */
+ if (nesting_depth == 0)
+ break;
+ /* If it is the closing `}' for a block that we have
+ scanned, stop -- but only after consuming the token.
+ That way given:
+
+ void f g () { ... }
+ typedef int I;
+
+ we will stop after the body of the erroneously declared
+ function, but before consuming the following `typedef'
+ declaration. */
+ if (--nesting_depth == 0)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ break;
+ }
+ }
+ /* If it the next token is a `{', then we are entering a new
+ block. Consume the entire block. */
+ else if (token->type == CPP_OPEN_BRACE)
+ ++nesting_depth;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+}
+
+/* This function is called at the end of a statement or declaration.
+ If the next token is a semicolon, it is consumed; otherwise, error
+ recovery is attempted. */
+
+static void
+cp_parser_consume_semicolon_at_end_of_statement (cp_parser *parser)
+{
+ /* Look for the trailing `;'. */
+ if (!cp_parser_require (parser, CPP_SEMICOLON, "`;'"))
+ {
+ /* If there is additional (erroneous) input, skip to the end of
+ the statement. */
+ cp_parser_skip_to_end_of_statement (parser);
+ /* If the next token is now a `;', consume it. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+ }
+}
+
+/* Skip tokens until we have consumed an entire block, or until we
+ have consumed a non-nested `;'. */
+
+static void
+cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser)
+{
+ unsigned nesting_depth = 0;
+
+ while (true)
+ {
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If we've run out of tokens, stop. */
+ if (token->type == CPP_EOF)
+ break;
+ /* If the next token is a `;', we have reached the end of the
+ statement. */
+ if (token->type == CPP_SEMICOLON && !nesting_depth)
+ {
+ /* Consume the `;'. */
+ cp_lexer_consume_token (parser->lexer);
+ break;
+ }
+ /* Consume the token. */
+ token = cp_lexer_consume_token (parser->lexer);
+ /* If the next token is a non-nested `}', then we have reached
+ the end of the current block. */
+ if (token->type == CPP_CLOSE_BRACE
+ && (nesting_depth == 0 || --nesting_depth == 0))
+ break;
+ /* If it the next token is a `{', then we are entering a new
+ block. Consume the entire block. */
+ if (token->type == CPP_OPEN_BRACE)
+ ++nesting_depth;
+ }
+}
+
+/* Skip tokens until a non-nested closing curly brace is the next
+ token. */
+
+static void
+cp_parser_skip_to_closing_brace (cp_parser *parser)
+{
+ unsigned nesting_depth = 0;
+
+ while (true)
+ {
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If we've run out of tokens, stop. */
+ if (token->type == CPP_EOF)
+ break;
+ /* If the next token is a non-nested `}', then we have reached
+ the end of the current block. */
+ if (token->type == CPP_CLOSE_BRACE && nesting_depth-- == 0)
+ break;
+ /* If it the next token is a `{', then we are entering a new
+ block. Consume the entire block. */
+ else if (token->type == CPP_OPEN_BRACE)
+ ++nesting_depth;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+}
+
+/* Create a new C++ parser. */
+
+static cp_parser *
+cp_parser_new (void)
+{
+ cp_parser *parser;
+ cp_lexer *lexer;
+
+ /* cp_lexer_new_main is called before calling ggc_alloc because
+ cp_lexer_new_main might load a PCH file. */
+ lexer = cp_lexer_new_main ();
+
+ parser = ggc_alloc_cleared (sizeof (cp_parser));
+ parser->lexer = lexer;
+ parser->context = cp_parser_context_new (NULL);
+
+ /* For now, we always accept GNU extensions. */
+ parser->allow_gnu_extensions_p = 1;
+
+ /* The `>' token is a greater-than operator, not the end of a
+ template-id. */
+ parser->greater_than_is_operator_p = true;
+
+ parser->default_arg_ok_p = true;
+
+ /* We are not parsing a constant-expression. */
+ parser->integral_constant_expression_p = false;
+ parser->allow_non_integral_constant_expression_p = false;
+ parser->non_integral_constant_expression_p = false;
+
+ /* We are not parsing offsetof. */
+ parser->in_offsetof_p = false;
+
+ /* Local variable names are not forbidden. */
+ parser->local_variables_forbidden_p = false;
+
+ /* We are not processing an `extern "C"' declaration. */
+ parser->in_unbraced_linkage_specification_p = false;
+
+ /* We are not processing a declarator. */
+ parser->in_declarator_p = false;
+
+ /* We are not processing a template-argument-list. */
+ parser->in_template_argument_list_p = false;
+
+ /* We are not in an iteration statement. */
+ parser->in_iteration_statement_p = false;
+
+ /* We are not in a switch statement. */
+ parser->in_switch_statement_p = false;
+
+ /* We are not parsing a type-id inside an expression. */
+ parser->in_type_id_in_expr_p = false;
+
+ /* The unparsed function queue is empty. */
+ parser->unparsed_functions_queues = build_tree_list (NULL_TREE, NULL_TREE);
+
+ /* There are no classes being defined. */
+ parser->num_classes_being_defined = 0;
+
+ /* No template parameters apply. */
+ parser->num_template_parameter_lists = 0;
+
+ return parser;
+}
+
+/* Lexical conventions [gram.lex] */
+
+/* Parse an identifier. Returns an IDENTIFIER_NODE representing the
+ identifier. */
+
+static tree
+cp_parser_identifier (cp_parser* parser)
+{
+ cp_token *token;
+
+ /* Look for the identifier. */
+ token = cp_parser_require (parser, CPP_NAME, "identifier");
+ /* Return the value. */
+ return token ? token->value : error_mark_node;
+}
+
+/* Basic concepts [gram.basic] */
+
+/* Parse a translation-unit.
+
+ translation-unit:
+ declaration-seq [opt]
+
+ Returns TRUE if all went well. */
+
+static bool
+cp_parser_translation_unit (cp_parser* parser)
+{
+ while (true)
+ {
+ cp_parser_declaration_seq_opt (parser);
+
+ /* If there are no tokens left then all went well. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+ break;
+
+ /* Otherwise, issue an error message. */
+ cp_parser_error (parser, "expected declaration");
+ return false;
+ }
+
+ /* Consume the EOF token. */
+ cp_parser_require (parser, CPP_EOF, "end-of-file");
+
+ /* Finish up. */
+ finish_translation_unit ();
+
+ /* All went well. */
+ return true;
+}
+
+/* Expressions [gram.expr] */
+
+/* Parse a primary-expression.
+
+ primary-expression:
+ literal
+ this
+ ( expression )
+ id-expression
+
+ GNU Extensions:
+
+ primary-expression:
+ ( compound-statement )
+ __builtin_va_arg ( assignment-expression , type-id )
+
+ literal:
+ __null
+
+ Returns a representation of the expression.
+
+ *IDK indicates what kind of id-expression (if any) was present.
+
+ *QUALIFYING_CLASS is set to a non-NULL value if the id-expression can be
+ used as the operand of a pointer-to-member. In that case,
+ *QUALIFYING_CLASS gives the class that is used as the qualifying
+ class in the pointer-to-member. */
+
+static tree
+cp_parser_primary_expression (cp_parser *parser,
+ cp_id_kind *idk,
+ tree *qualifying_class)
+{
+ cp_token *token;
+
+ /* Assume the primary expression is not an id-expression. */
+ *idk = CP_ID_KIND_NONE;
+ /* And that it cannot be used as pointer-to-member. */
+ *qualifying_class = NULL_TREE;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ switch (token->type)
+ {
+ /* literal:
+ integer-literal
+ character-literal
+ floating-literal
+ string-literal
+ boolean-literal */
+ case CPP_CHAR:
+ case CPP_WCHAR:
+ case CPP_STRING:
+ case CPP_WSTRING:
+ case CPP_NUMBER:
+ token = cp_lexer_consume_token (parser->lexer);
+ return token->value;
+
+ case CPP_OPEN_PAREN:
+ {
+ tree expr;
+ bool saved_greater_than_is_operator_p;
+
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Within a parenthesized expression, a `>' token is always
+ the greater-than operator. */
+ saved_greater_than_is_operator_p
+ = parser->greater_than_is_operator_p;
+ parser->greater_than_is_operator_p = true;
+ /* If we see `( { ' then we are looking at the beginning of
+ a GNU statement-expression. */
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ /* Statement-expressions are not allowed by the standard. */
+ if (pedantic)
+ pedwarn ("ISO C++ forbids braced-groups within expressions");
+
+ /* And they're not allowed outside of a function-body; you
+ cannot, for example, write:
+
+ int i = ({ int j = 3; j + 1; });
+
+ at class or namespace scope. */
+ if (!at_function_scope_p ())
+ error ("statement-expressions are allowed only inside functions");
+ /* Start the statement-expression. */
+ expr = begin_stmt_expr ();
+ /* Parse the compound-statement. */
+ cp_parser_compound_statement (parser, true);
+ /* Finish up. */
+ expr = finish_stmt_expr (expr, false);
+ }
+ else
+ {
+ /* Parse the parenthesized expression. */
+ expr = cp_parser_expression (parser);
+ /* Let the front end know that this expression was
+ enclosed in parentheses. This matters in case, for
+ example, the expression is of the form `A::B', since
+ `&A::B' might be a pointer-to-member, but `&(A::B)' is
+ not. */
+ finish_parenthesized_expr (expr);
+ }
+ /* The `>' token might be the end of a template-id or
+ template-parameter-list now. */
+ parser->greater_than_is_operator_p
+ = saved_greater_than_is_operator_p;
+ /* Consume the `)'. */
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'"))
+ cp_parser_skip_to_end_of_statement (parser);
+
+ return expr;
+ }
+
+ case CPP_KEYWORD:
+ switch (token->keyword)
+ {
+ /* These two are the boolean literals. */
+ case RID_TRUE:
+ cp_lexer_consume_token (parser->lexer);
+ return boolean_true_node;
+ case RID_FALSE:
+ cp_lexer_consume_token (parser->lexer);
+ return boolean_false_node;
+
+ /* The `__null' literal. */
+ case RID_NULL:
+ cp_lexer_consume_token (parser->lexer);
+ return null_node;
+
+ /* Recognize the `this' keyword. */
+ case RID_THIS:
+ cp_lexer_consume_token (parser->lexer);
+ if (parser->local_variables_forbidden_p)
+ {
+ error ("`this' may not be used in this context");
+ return error_mark_node;
+ }
+ /* Pointers cannot appear in constant-expressions. */
+ if (cp_parser_non_integral_constant_expression (parser,
+ "`this'"))
+ return error_mark_node;
+ return finish_this_expr ();
+
+ /* The `operator' keyword can be the beginning of an
+ id-expression. */
+ case RID_OPERATOR:
+ goto id_expression;
+
+ case RID_FUNCTION_NAME:
+ case RID_PRETTY_FUNCTION_NAME:
+ case RID_C99_FUNCTION_NAME:
+ /* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and
+ __func__ are the names of variables -- but they are
+ treated specially. Therefore, they are handled here,
+ rather than relying on the generic id-expression logic
+ below. Grammatically, these names are id-expressions.
+
+ Consume the token. */
+ token = cp_lexer_consume_token (parser->lexer);
+ /* Look up the name. */
+ return finish_fname (token->value);
+
+ case RID_VA_ARG:
+ {
+ tree expression;
+ tree type;
+
+ /* The `__builtin_va_arg' construct is used to handle
+ `va_arg'. Consume the `__builtin_va_arg' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the opening `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+ /* Now, parse the assignment-expression. */
+ expression = cp_parser_assignment_expression (parser);
+ /* Look for the `,'. */
+ cp_parser_require (parser, CPP_COMMA, "`,'");
+ /* Parse the type-id. */
+ type = cp_parser_type_id (parser);
+ /* Look for the closing `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ /* Using `va_arg' in a constant-expression is not
+ allowed. */
+ if (cp_parser_non_integral_constant_expression (parser,
+ "`va_arg'"))
+ return error_mark_node;
+ return build_x_va_arg (expression, type);
+ }
+
+ case RID_OFFSETOF:
+ {
+ tree expression;
+ bool saved_in_offsetof_p;
+
+ /* Consume the "__offsetof__" token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Consume the opening `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+ /* Parse the parenthesized (almost) constant-expression. */
+ saved_in_offsetof_p = parser->in_offsetof_p;
+ parser->in_offsetof_p = true;
+ expression
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/false,
+ /*non_constant_p=*/NULL);
+ parser->in_offsetof_p = saved_in_offsetof_p;
+ /* Consume the closing ')'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+
+ return expression;
+ }
+
+ default:
+ cp_parser_error (parser, "expected primary-expression");
+ return error_mark_node;
+ }
+
+ /* An id-expression can start with either an identifier, a
+ `::' as the beginning of a qualified-id, or the "operator"
+ keyword. */
+ case CPP_NAME:
+ case CPP_SCOPE:
+ case CPP_TEMPLATE_ID:
+ case CPP_NESTED_NAME_SPECIFIER:
+ {
+ tree id_expression;
+ tree decl;
+ const char *error_msg;
+
+ id_expression:
+ /* Parse the id-expression. */
+ id_expression
+ = cp_parser_id_expression (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*template_p=*/NULL,
+ /*declarator_p=*/false);
+ if (id_expression == error_mark_node)
+ return error_mark_node;
+ /* If we have a template-id, then no further lookup is
+ required. If the template-id was for a template-class, we
+ will sometimes have a TYPE_DECL at this point. */
+ else if (TREE_CODE (id_expression) == TEMPLATE_ID_EXPR
+ || TREE_CODE (id_expression) == TYPE_DECL)
+ decl = id_expression;
+ /* Look up the name. */
+ else
+ {
+ decl = cp_parser_lookup_name_simple (parser, id_expression);
+ /* If name lookup gives us a SCOPE_REF, then the
+ qualifying scope was dependent. Just propagate the
+ name. */
+ if (TREE_CODE (decl) == SCOPE_REF)
+ {
+ if (TYPE_P (TREE_OPERAND (decl, 0)))
+ *qualifying_class = TREE_OPERAND (decl, 0);
+ return decl;
+ }
+ /* Check to see if DECL is a local variable in a context
+ where that is forbidden. */
+ if (parser->local_variables_forbidden_p
+ && local_variable_p (decl))
+ {
+ /* It might be that we only found DECL because we are
+ trying to be generous with pre-ISO scoping rules.
+ For example, consider:
+
+ int i;
+ void g() {
+ for (int i = 0; i < 10; ++i) {}
+ extern void f(int j = i);
+ }
+
+ Here, name look up will originally find the out
+ of scope `i'. We need to issue a warning message,
+ but then use the global `i'. */
+ decl = check_for_out_of_scope_variable (decl);
+ if (local_variable_p (decl))
+ {
+ error ("local variable `%D' may not appear in this context",
+ decl);
+ return error_mark_node;
+ }
+ }
+ }
+
+ decl = finish_id_expression (id_expression, decl, parser->scope,
+ idk, qualifying_class,
+ parser->integral_constant_expression_p,
+ parser->allow_non_integral_constant_expression_p,
+ &parser->non_integral_constant_expression_p,
+ &error_msg);
+ if (error_msg)
+ cp_parser_error (parser, error_msg);
+ return decl;
+ }
+
+ /* Anything else is an error. */
+ default:
+ cp_parser_error (parser, "expected primary-expression");
+ return error_mark_node;
+ }
+}
+
+/* Parse an id-expression.
+
+ id-expression:
+ unqualified-id
+ qualified-id
+
+ qualified-id:
+ :: [opt] nested-name-specifier template [opt] unqualified-id
+ :: identifier
+ :: operator-function-id
+ :: template-id
+
+ Return a representation of the unqualified portion of the
+ identifier. Sets PARSER->SCOPE to the qualifying scope if there is
+ a `::' or nested-name-specifier.
+
+ Often, if the id-expression was a qualified-id, the caller will
+ want to make a SCOPE_REF to represent the qualified-id. This
+ function does not do this in order to avoid wastefully creating
+ SCOPE_REFs when they are not required.
+
+ If TEMPLATE_KEYWORD_P is true, then we have just seen the
+ `template' keyword.
+
+ If CHECK_DEPENDENCY_P is false, then names are looked up inside
+ uninstantiated templates.
+
+ If *TEMPLATE_P is non-NULL, it is set to true iff the
+ `template' keyword is used to explicitly indicate that the entity
+ named is a template.
+
+ If DECLARATOR_P is true, the id-expression is appearing as part of
+ a declarator, rather than as part of an expression. */
+
+static tree
+cp_parser_id_expression (cp_parser *parser,
+ bool template_keyword_p,
+ bool check_dependency_p,
+ bool *template_p,
+ bool declarator_p)
+{
+ bool global_scope_p;
+ bool nested_name_specifier_p;
+
+ /* Assume the `template' keyword was not used. */
+ if (template_p)
+ *template_p = false;
+
+ /* Look for the optional `::' operator. */
+ global_scope_p
+ = (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false)
+ != NULL_TREE);
+ /* Look for the optional nested-name-specifier. */
+ nested_name_specifier_p
+ = (cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ check_dependency_p,
+ /*type_p=*/false,
+ /*is_declarator=*/false)
+ != NULL_TREE);
+ /* If there is a nested-name-specifier, then we are looking at
+ the first qualified-id production. */
+ if (nested_name_specifier_p)
+ {
+ tree saved_scope;
+ tree saved_object_scope;
+ tree saved_qualifying_scope;
+ tree unqualified_id;
+ bool is_template;
+
+ /* See if the next token is the `template' keyword. */
+ if (!template_p)
+ template_p = &is_template;
+ *template_p = cp_parser_optional_template_keyword (parser);
+ /* Name lookup we do during the processing of the
+ unqualified-id might obliterate SCOPE. */
+ saved_scope = parser->scope;
+ saved_object_scope = parser->object_scope;
+ saved_qualifying_scope = parser->qualifying_scope;
+ /* Process the final unqualified-id. */
+ unqualified_id = cp_parser_unqualified_id (parser, *template_p,
+ check_dependency_p,
+ declarator_p);
+ /* Restore the SAVED_SCOPE for our caller. */
+ parser->scope = saved_scope;
+ parser->object_scope = saved_object_scope;
+ parser->qualifying_scope = saved_qualifying_scope;
+
+ return unqualified_id;
+ }
+ /* Otherwise, if we are in global scope, then we are looking at one
+ of the other qualified-id productions. */
+ else if (global_scope_p)
+ {
+ cp_token *token;
+ tree id;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* If it's an identifier, and the next token is not a "<", then
+ we can avoid the template-id case. This is an optimization
+ for this common case. */
+ if (token->type == CPP_NAME
+ && !cp_parser_nth_token_starts_template_argument_list_p
+ (parser, 2))
+ return cp_parser_identifier (parser);
+
+ cp_parser_parse_tentatively (parser);
+ /* Try a template-id. */
+ id = cp_parser_template_id (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ declarator_p);
+ /* If that worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ return id;
+
+ /* Peek at the next token. (Changes in the token buffer may
+ have invalidated the pointer obtained above.) */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_NAME:
+ return cp_parser_identifier (parser);
+
+ case CPP_KEYWORD:
+ if (token->keyword == RID_OPERATOR)
+ return cp_parser_operator_function_id (parser);
+ /* Fall through. */
+
+ default:
+ cp_parser_error (parser, "expected id-expression");
+ return error_mark_node;
+ }
+ }
+ else
+ return cp_parser_unqualified_id (parser, template_keyword_p,
+ /*check_dependency_p=*/true,
+ declarator_p);
+}
+
+/* Parse an unqualified-id.
+
+ unqualified-id:
+ identifier
+ operator-function-id
+ conversion-function-id
+ ~ class-name
+ template-id
+
+ If TEMPLATE_KEYWORD_P is TRUE, we have just seen the `template'
+ keyword, in a construct like `A::template ...'.
+
+ Returns a representation of unqualified-id. For the `identifier'
+ production, an IDENTIFIER_NODE is returned. For the `~ class-name'
+ production a BIT_NOT_EXPR is returned; the operand of the
+ BIT_NOT_EXPR is an IDENTIFIER_NODE for the class-name. For the
+ other productions, see the documentation accompanying the
+ corresponding parsing functions. If CHECK_DEPENDENCY_P is false,
+ names are looked up in uninstantiated templates. If DECLARATOR_P
+ is true, the unqualified-id is appearing as part of a declarator,
+ rather than as part of an expression. */
+
+static tree
+cp_parser_unqualified_id (cp_parser* parser,
+ bool template_keyword_p,
+ bool check_dependency_p,
+ bool declarator_p)
+{
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_NAME:
+ {
+ tree id;
+
+ /* We don't know yet whether or not this will be a
+ template-id. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a template-id. */
+ id = cp_parser_template_id (parser, template_keyword_p,
+ check_dependency_p,
+ declarator_p);
+ /* If it worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ return id;
+ /* Otherwise, it's an ordinary identifier. */
+ return cp_parser_identifier (parser);
+ }
+
+ case CPP_TEMPLATE_ID:
+ return cp_parser_template_id (parser, template_keyword_p,
+ check_dependency_p,
+ declarator_p);
+
+ case CPP_COMPL:
+ {
+ tree type_decl;
+ tree qualifying_scope;
+ tree object_scope;
+ tree scope;
+
+ /* Consume the `~' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the class-name. The standard, as written, seems to
+ say that:
+
+ template <typename T> struct S { ~S (); };
+ template <typename T> S<T>::~S() {}
+
+ is invalid, since `~' must be followed by a class-name, but
+ `S<T>' is dependent, and so not known to be a class.
+ That's not right; we need to look in uninstantiated
+ templates. A further complication arises from:
+
+ template <typename T> void f(T t) {
+ t.T::~T();
+ }
+
+ Here, it is not possible to look up `T' in the scope of `T'
+ itself. We must look in both the current scope, and the
+ scope of the containing complete expression.
+
+ Yet another issue is:
+
+ struct S {
+ int S;
+ ~S();
+ };
+
+ S::~S() {}
+
+ The standard does not seem to say that the `S' in `~S'
+ should refer to the type `S' and not the data member
+ `S::S'. */
+
+ /* DR 244 says that we look up the name after the "~" in the
+ same scope as we looked up the qualifying name. That idea
+ isn't fully worked out; it's more complicated than that. */
+ scope = parser->scope;
+ object_scope = parser->object_scope;
+ qualifying_scope = parser->qualifying_scope;
+
+ /* If the name is of the form "X::~X" it's OK. */
+ if (scope && TYPE_P (scope)
+ && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ == CPP_OPEN_PAREN)
+ && (cp_lexer_peek_token (parser->lexer)->value
+ == TYPE_IDENTIFIER (scope)))
+ {
+ cp_lexer_consume_token (parser->lexer);
+ return build_nt (BIT_NOT_EXPR, scope);
+ }
+
+ /* If there was an explicit qualification (S::~T), first look
+ in the scope given by the qualification (i.e., S). */
+ if (scope)
+ {
+ cp_parser_parse_tentatively (parser);
+ type_decl = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ /*type_p=*/false,
+ /*check_dependency=*/false,
+ /*class_head_p=*/false,
+ declarator_p);
+ if (cp_parser_parse_definitely (parser))
+ return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
+ }
+ /* In "N::S::~S", look in "N" as well. */
+ if (scope && qualifying_scope)
+ {
+ cp_parser_parse_tentatively (parser);
+ parser->scope = qualifying_scope;
+ parser->object_scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ type_decl
+ = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ /*type_p=*/false,
+ /*check_dependency=*/false,
+ /*class_head_p=*/false,
+ declarator_p);
+ if (cp_parser_parse_definitely (parser))
+ return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
+ }
+ /* In "p->S::~T", look in the scope given by "*p" as well. */
+ else if (object_scope)
+ {
+ cp_parser_parse_tentatively (parser);
+ parser->scope = object_scope;
+ parser->object_scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ type_decl
+ = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ /*type_p=*/false,
+ /*check_dependency=*/false,
+ /*class_head_p=*/false,
+ declarator_p);
+ if (cp_parser_parse_definitely (parser))
+ return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
+ }
+ /* Look in the surrounding context. */
+ parser->scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ type_decl
+ = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ /*type_p=*/false,
+ /*check_dependency=*/false,
+ /*class_head_p=*/false,
+ declarator_p);
+ /* If an error occurred, assume that the name of the
+ destructor is the same as the name of the qualifying
+ class. That allows us to keep parsing after running
+ into ill-formed destructor names. */
+ if (type_decl == error_mark_node && scope && TYPE_P (scope))
+ return build_nt (BIT_NOT_EXPR, scope);
+ else if (type_decl == error_mark_node)
+ return error_mark_node;
+
+ /* [class.dtor]
+
+ A typedef-name that names a class shall not be used as the
+ identifier in the declarator for a destructor declaration. */
+ if (declarator_p
+ && !DECL_IMPLICIT_TYPEDEF_P (type_decl)
+ && !DECL_SELF_REFERENCE_P (type_decl))
+ error ("typedef-name `%D' used as destructor declarator",
+ type_decl);
+
+ return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
+ }
+
+ case CPP_KEYWORD:
+ if (token->keyword == RID_OPERATOR)
+ {
+ tree id;
+
+ /* This could be a template-id, so we try that first. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a template-id. */
+ id = cp_parser_template_id (parser, template_keyword_p,
+ /*check_dependency_p=*/true,
+ declarator_p);
+ /* If that worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ return id;
+ /* We still don't know whether we're looking at an
+ operator-function-id or a conversion-function-id. */
+ cp_parser_parse_tentatively (parser);
+ /* Try an operator-function-id. */
+ id = cp_parser_operator_function_id (parser);
+ /* If that didn't work, try a conversion-function-id. */
+ if (!cp_parser_parse_definitely (parser))
+ id = cp_parser_conversion_function_id (parser);
+
+ return id;
+ }
+ /* Fall through. */
+
+ default:
+ cp_parser_error (parser, "expected unqualified-id");
+ return error_mark_node;
+ }
+}
+
+/* Parse an (optional) nested-name-specifier.
+
+ nested-name-specifier:
+ class-or-namespace-name :: nested-name-specifier [opt]
+ class-or-namespace-name :: template nested-name-specifier [opt]
+
+ PARSER->SCOPE should be set appropriately before this function is
+ called. TYPENAME_KEYWORD_P is TRUE if the `typename' keyword is in
+ effect. TYPE_P is TRUE if we non-type bindings should be ignored
+ in name lookups.
+
+ Sets PARSER->SCOPE to the class (TYPE) or namespace
+ (NAMESPACE_DECL) specified by the nested-name-specifier, or leaves
+ it unchanged if there is no nested-name-specifier. Returns the new
+ scope iff there is a nested-name-specifier, or NULL_TREE otherwise.
+
+ If IS_DECLARATION is TRUE, the nested-name-specifier is known to be
+ part of a declaration and/or decl-specifier. */
+
+static tree
+cp_parser_nested_name_specifier_opt (cp_parser *parser,
+ bool typename_keyword_p,
+ bool check_dependency_p,
+ bool type_p,
+ bool is_declaration)
+{
+ bool success = false;
+ tree access_check = NULL_TREE;
+ ptrdiff_t start;
+ cp_token* token;
+
+ /* If the next token corresponds to a nested name specifier, there
+ is no need to reparse it. However, if CHECK_DEPENDENCY_P is
+ false, it may have been true before, in which case something
+ like `A<X>::B<Y>::C' may have resulted in a nested-name-specifier
+ of `A<X>::', where it should now be `A<X>::B<Y>::'. So, when
+ CHECK_DEPENDENCY_P is false, we have to fall through into the
+ main loop. */
+ if (check_dependency_p
+ && cp_lexer_next_token_is (parser->lexer, CPP_NESTED_NAME_SPECIFIER))
+ {
+ cp_parser_pre_parsed_nested_name_specifier (parser);
+ return parser->scope;
+ }
+
+ /* Remember where the nested-name-specifier starts. */
+ if (cp_parser_parsing_tentatively (parser)
+ && !cp_parser_committed_to_tentative_parse (parser))
+ {
+ token = cp_lexer_peek_token (parser->lexer);
+ start = cp_lexer_token_difference (parser->lexer,
+ parser->lexer->first_token,
+ token);
+ }
+ else
+ start = -1;
+
+ push_deferring_access_checks (dk_deferred);
+
+ while (true)
+ {
+ tree new_scope;
+ tree old_scope;
+ tree saved_qualifying_scope;
+ bool template_keyword_p;
+
+ /* Spot cases that cannot be the beginning of a
+ nested-name-specifier. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* If the next token is CPP_NESTED_NAME_SPECIFIER, just process
+ the already parsed nested-name-specifier. */
+ if (token->type == CPP_NESTED_NAME_SPECIFIER)
+ {
+ /* Grab the nested-name-specifier and continue the loop. */
+ cp_parser_pre_parsed_nested_name_specifier (parser);
+ success = true;
+ continue;
+ }
+
+ /* Spot cases that cannot be the beginning of a
+ nested-name-specifier. On the second and subsequent times
+ through the loop, we look for the `template' keyword. */
+ if (success && token->keyword == RID_TEMPLATE)
+ ;
+ /* A template-id can start a nested-name-specifier. */
+ else if (token->type == CPP_TEMPLATE_ID)
+ ;
+ else
+ {
+ /* If the next token is not an identifier, then it is
+ definitely not a class-or-namespace-name. */
+ if (token->type != CPP_NAME)
+ break;
+ /* If the following token is neither a `<' (to begin a
+ template-id), nor a `::', then we are not looking at a
+ nested-name-specifier. */
+ token = cp_lexer_peek_nth_token (parser->lexer, 2);
+ if (token->type != CPP_SCOPE
+ && !cp_parser_nth_token_starts_template_argument_list_p
+ (parser, 2))
+ break;
+ }
+
+ /* The nested-name-specifier is optional, so we parse
+ tentatively. */
+ cp_parser_parse_tentatively (parser);
+
+ /* Look for the optional `template' keyword, if this isn't the
+ first time through the loop. */
+ if (success)
+ template_keyword_p = cp_parser_optional_template_keyword (parser);
+ else
+ template_keyword_p = false;
+
+ /* Save the old scope since the name lookup we are about to do
+ might destroy it. */
+ old_scope = parser->scope;
+ saved_qualifying_scope = parser->qualifying_scope;
+ /* Parse the qualifying entity. */
+ new_scope
+ = cp_parser_class_or_namespace_name (parser,
+ typename_keyword_p,
+ template_keyword_p,
+ check_dependency_p,
+ type_p,
+ is_declaration);
+ /* Look for the `::' token. */
+ cp_parser_require (parser, CPP_SCOPE, "`::'");
+
+ /* If we found what we wanted, we keep going; otherwise, we're
+ done. */
+ if (!cp_parser_parse_definitely (parser))
+ {
+ bool error_p = false;
+
+ /* Restore the OLD_SCOPE since it was valid before the
+ failed attempt at finding the last
+ class-or-namespace-name. */
+ parser->scope = old_scope;
+ parser->qualifying_scope = saved_qualifying_scope;
+ /* If the next token is an identifier, and the one after
+ that is a `::', then any valid interpretation would have
+ found a class-or-namespace-name. */
+ while (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ == CPP_SCOPE)
+ && (cp_lexer_peek_nth_token (parser->lexer, 3)->type
+ != CPP_COMPL))
+ {
+ token = cp_lexer_consume_token (parser->lexer);
+ if (!error_p)
+ {
+ tree decl;
+
+ decl = cp_parser_lookup_name_simple (parser, token->value);
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ error ("`%D' used without template parameters",
+ decl);
+ else
+ cp_parser_name_lookup_error
+ (parser, token->value, decl,
+ "is not a class or namespace");
+ parser->scope = NULL_TREE;
+ error_p = true;
+ /* Treat this as a successful nested-name-specifier
+ due to:
+
+ [basic.lookup.qual]
+
+ If the name found is not a class-name (clause
+ _class_) or namespace-name (_namespace.def_), the
+ program is ill-formed. */
+ success = true;
+ }
+ cp_lexer_consume_token (parser->lexer);
+ }
+ break;
+ }
+
+ /* We've found one valid nested-name-specifier. */
+ success = true;
+ /* Make sure we look in the right scope the next time through
+ the loop. */
+ parser->scope = (TREE_CODE (new_scope) == TYPE_DECL
+ ? TREE_TYPE (new_scope)
+ : new_scope);
+ /* If it is a class scope, try to complete it; we are about to
+ be looking up names inside the class. */
+ if (TYPE_P (parser->scope)
+ /* Since checking types for dependency can be expensive,
+ avoid doing it if the type is already complete. */
+ && !COMPLETE_TYPE_P (parser->scope)
+ /* Do not try to complete dependent types. */
+ && !dependent_type_p (parser->scope))
+ complete_type (parser->scope);
+ }
+
+ /* Retrieve any deferred checks. Do not pop this access checks yet
+ so the memory will not be reclaimed during token replacing below. */
+ access_check = get_deferred_access_checks ();
+
+ /* If parsing tentatively, replace the sequence of tokens that makes
+ up the nested-name-specifier with a CPP_NESTED_NAME_SPECIFIER
+ token. That way, should we re-parse the token stream, we will
+ not have to repeat the effort required to do the parse, nor will
+ we issue duplicate error messages. */
+ if (success && start >= 0)
+ {
+ /* Find the token that corresponds to the start of the
+ template-id. */
+ token = cp_lexer_advance_token (parser->lexer,
+ parser->lexer->first_token,
+ start);
+
+ /* Reset the contents of the START token. */
+ token->type = CPP_NESTED_NAME_SPECIFIER;
+ token->value = build_tree_list (access_check, parser->scope);
+ TREE_TYPE (token->value) = parser->qualifying_scope;
+ token->keyword = RID_MAX;
+ /* Purge all subsequent tokens. */
+ cp_lexer_purge_tokens_after (parser->lexer, token);
+ }
+
+ pop_deferring_access_checks ();
+ return success ? parser->scope : NULL_TREE;
+}
+
+/* Parse a nested-name-specifier. See
+ cp_parser_nested_name_specifier_opt for details. This function
+ behaves identically, except that it will an issue an error if no
+ nested-name-specifier is present, and it will return
+ ERROR_MARK_NODE, rather than NULL_TREE, if no nested-name-specifier
+ is present. */
+
+static tree
+cp_parser_nested_name_specifier (cp_parser *parser,
+ bool typename_keyword_p,
+ bool check_dependency_p,
+ bool type_p,
+ bool is_declaration)
+{
+ tree scope;
+
+ /* Look for the nested-name-specifier. */
+ scope = cp_parser_nested_name_specifier_opt (parser,
+ typename_keyword_p,
+ check_dependency_p,
+ type_p,
+ is_declaration);
+ /* If it was not present, issue an error message. */
+ if (!scope)
+ {
+ cp_parser_error (parser, "expected nested-name-specifier");
+ parser->scope = NULL_TREE;
+ return error_mark_node;
+ }
+
+ return scope;
+}
+
+/* Parse a class-or-namespace-name.
+
+ class-or-namespace-name:
+ class-name
+ namespace-name
+
+ TYPENAME_KEYWORD_P is TRUE iff the `typename' keyword is in effect.
+ TEMPLATE_KEYWORD_P is TRUE iff the `template' keyword is in effect.
+ CHECK_DEPENDENCY_P is FALSE iff dependent names should be looked up.
+ TYPE_P is TRUE iff the next name should be taken as a class-name,
+ even the same name is declared to be another entity in the same
+ scope.
+
+ Returns the class (TYPE_DECL) or namespace (NAMESPACE_DECL)
+ specified by the class-or-namespace-name. If neither is found the
+ ERROR_MARK_NODE is returned. */
+
+static tree
+cp_parser_class_or_namespace_name (cp_parser *parser,
+ bool typename_keyword_p,
+ bool template_keyword_p,
+ bool check_dependency_p,
+ bool type_p,
+ bool is_declaration)
+{
+ tree saved_scope;
+ tree saved_qualifying_scope;
+ tree saved_object_scope;
+ tree scope;
+ bool only_class_p;
+
+ /* Before we try to parse the class-name, we must save away the
+ current PARSER->SCOPE since cp_parser_class_name will destroy
+ it. */
+ saved_scope = parser->scope;
+ saved_qualifying_scope = parser->qualifying_scope;
+ saved_object_scope = parser->object_scope;
+ /* Try for a class-name first. If the SAVED_SCOPE is a type, then
+ there is no need to look for a namespace-name. */
+ only_class_p = template_keyword_p || (saved_scope && TYPE_P (saved_scope));
+ if (!only_class_p)
+ cp_parser_parse_tentatively (parser);
+ scope = cp_parser_class_name (parser,
+ typename_keyword_p,
+ template_keyword_p,
+ type_p,
+ check_dependency_p,
+ /*class_head_p=*/false,
+ is_declaration);
+ /* If that didn't work, try for a namespace-name. */
+ if (!only_class_p && !cp_parser_parse_definitely (parser))
+ {
+ /* Restore the saved scope. */
+ parser->scope = saved_scope;
+ parser->qualifying_scope = saved_qualifying_scope;
+ parser->object_scope = saved_object_scope;
+ /* If we are not looking at an identifier followed by the scope
+ resolution operator, then this is not part of a
+ nested-name-specifier. (Note that this function is only used
+ to parse the components of a nested-name-specifier.) */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)
+ || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
+ return error_mark_node;
+ scope = cp_parser_namespace_name (parser);
+ }
+
+ return scope;
+}
+
+/* Parse a postfix-expression.
+
+ postfix-expression:
+ primary-expression
+ postfix-expression [ expression ]
+ postfix-expression ( expression-list [opt] )
+ simple-type-specifier ( expression-list [opt] )
+ typename :: [opt] nested-name-specifier identifier
+ ( expression-list [opt] )
+ typename :: [opt] nested-name-specifier template [opt] template-id
+ ( expression-list [opt] )
+ postfix-expression . template [opt] id-expression
+ postfix-expression -> template [opt] id-expression
+ postfix-expression . pseudo-destructor-name
+ postfix-expression -> pseudo-destructor-name
+ postfix-expression ++
+ postfix-expression --
+ dynamic_cast < type-id > ( expression )
+ static_cast < type-id > ( expression )
+ reinterpret_cast < type-id > ( expression )
+ const_cast < type-id > ( expression )
+ typeid ( expression )
+ typeid ( type-id )
+
+ GNU Extension:
+
+ postfix-expression:
+ ( type-id ) { initializer-list , [opt] }
+
+ This extension is a GNU version of the C99 compound-literal
+ construct. (The C99 grammar uses `type-name' instead of `type-id',
+ but they are essentially the same concept.)
+
+ If ADDRESS_P is true, the postfix expression is the operand of the
+ `&' operator.
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_postfix_expression (cp_parser *parser, bool address_p)
+{
+ cp_token *token;
+ enum rid keyword;
+ cp_id_kind idk = CP_ID_KIND_NONE;
+ tree postfix_expression = NULL_TREE;
+ /* Non-NULL only if the current postfix-expression can be used to
+ form a pointer-to-member. In that case, QUALIFYING_CLASS is the
+ class used to qualify the member. */
+ tree qualifying_class = NULL_TREE;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Some of the productions are determined by keywords. */
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ case RID_DYNCAST:
+ case RID_STATCAST:
+ case RID_REINTCAST:
+ case RID_CONSTCAST:
+ {
+ tree type;
+ tree expression;
+ const char *saved_message;
+
+ /* All of these can be handled in the same way from the point
+ of view of parsing. Begin by consuming the token
+ identifying the cast. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* New types cannot be defined in the cast. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = "types may not be defined in casts";
+
+ /* Look for the opening `<'. */
+ cp_parser_require (parser, CPP_LESS, "`<'");
+ /* Parse the type to which we are casting. */
+ type = cp_parser_type_id (parser);
+ /* Look for the closing `>'. */
+ cp_parser_require (parser, CPP_GREATER, "`>'");
+ /* Restore the old message. */
+ parser->type_definition_forbidden_message = saved_message;
+
+ /* And the expression which is being cast. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+ expression = cp_parser_expression (parser);
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+
+ /* Only type conversions to integral or enumeration types
+ can be used in constant-expressions. */
+ if (parser->integral_constant_expression_p
+ && !dependent_type_p (type)
+ && !INTEGRAL_OR_ENUMERATION_TYPE_P (type)
+ /* A cast to pointer or reference type is allowed in the
+ implementation of "offsetof". */
+ && !(parser->in_offsetof_p && POINTER_TYPE_P (type))
+ && (cp_parser_non_integral_constant_expression
+ (parser,
+ "a cast to a type other than an integral or "
+ "enumeration type")))
+ return error_mark_node;
+
+ switch (keyword)
+ {
+ case RID_DYNCAST:
+ postfix_expression
+ = build_dynamic_cast (type, expression);
+ break;
+ case RID_STATCAST:
+ postfix_expression
+ = build_static_cast (type, expression);
+ break;
+ case RID_REINTCAST:
+ postfix_expression
+ = build_reinterpret_cast (type, expression);
+ break;
+ case RID_CONSTCAST:
+ postfix_expression
+ = build_const_cast (type, expression);
+ break;
+ default:
+ abort ();
+ }
+ }
+ break;
+
+ case RID_TYPEID:
+ {
+ tree type;
+ const char *saved_message;
+ bool saved_in_type_id_in_expr_p;
+
+ /* Consume the `typeid' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the `(' token. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+ /* Types cannot be defined in a `typeid' expression. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = "types may not be defined in a `typeid\' expression";
+ /* We can't be sure yet whether we're looking at a type-id or an
+ expression. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a type-id first. */
+ saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+ parser->in_type_id_in_expr_p = true;
+ type = cp_parser_type_id (parser);
+ parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
+ /* Look for the `)' token. Otherwise, we can't be sure that
+ we're not looking at an expression: consider `typeid (int
+ (3))', for example. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ /* If all went well, simply lookup the type-id. */
+ if (cp_parser_parse_definitely (parser))
+ postfix_expression = get_typeid (type);
+ /* Otherwise, fall back to the expression variant. */
+ else
+ {
+ tree expression;
+
+ /* Look for an expression. */
+ expression = cp_parser_expression (parser);
+ /* Compute its typeid. */
+ postfix_expression = build_typeid (expression);
+ /* Look for the `)' token. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ }
+ /* `typeid' may not appear in an integral constant expression. */
+ if (cp_parser_non_integral_constant_expression(parser,
+ "`typeid' operator"))
+ return error_mark_node;
+ /* Restore the saved message. */
+ parser->type_definition_forbidden_message = saved_message;
+ }
+ break;
+
+ case RID_TYPENAME:
+ {
+ bool template_p = false;
+ tree id;
+ tree type;
+
+ /* Consume the `typename' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the optional `::' operator. */
+ cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false);
+ /* Look for the nested-name-specifier. */
+ cp_parser_nested_name_specifier (parser,
+ /*typename_keyword_p=*/true,
+ /*check_dependency_p=*/true,
+ /*type_p=*/true,
+ /*is_declaration=*/true);
+ /* Look for the optional `template' keyword. */
+ template_p = cp_parser_optional_template_keyword (parser);
+ /* We don't know whether we're looking at a template-id or an
+ identifier. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a template-id. */
+ id = cp_parser_template_id (parser, template_p,
+ /*check_dependency_p=*/true,
+ /*is_declaration=*/true);
+ /* If that didn't work, try an identifier. */
+ if (!cp_parser_parse_definitely (parser))
+ id = cp_parser_identifier (parser);
+ /* If we look up a template-id in a non-dependent qualifying
+ scope, there's no need to create a dependent type. */
+ if (TREE_CODE (id) == TYPE_DECL
+ && !dependent_type_p (parser->scope))
+ type = TREE_TYPE (id);
+ /* Create a TYPENAME_TYPE to represent the type to which the
+ functional cast is being performed. */
+ else
+ type = make_typename_type (parser->scope, id,
+ /*complain=*/1);
+
+ postfix_expression = cp_parser_functional_cast (parser, type);
+ }
+ break;
+
+ default:
+ {
+ tree type;
+
+ /* If the next thing is a simple-type-specifier, we may be
+ looking at a functional cast. We could also be looking at
+ an id-expression. So, we try the functional cast, and if
+ that doesn't work we fall back to the primary-expression. */
+ cp_parser_parse_tentatively (parser);
+ /* Look for the simple-type-specifier. */
+ type = cp_parser_simple_type_specifier (parser,
+ CP_PARSER_FLAGS_NONE,
+ /*identifier_p=*/false);
+ /* Parse the cast itself. */
+ if (!cp_parser_error_occurred (parser))
+ postfix_expression
+ = cp_parser_functional_cast (parser, type);
+ /* If that worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ break;
+
+ /* If the functional-cast didn't work out, try a
+ compound-literal. */
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ tree initializer_list = NULL_TREE;
+ bool saved_in_type_id_in_expr_p;
+
+ cp_parser_parse_tentatively (parser);
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the type. */
+ saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+ parser->in_type_id_in_expr_p = true;
+ type = cp_parser_type_id (parser);
+ parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ /* Look for the `{'. */
+ cp_parser_require (parser, CPP_OPEN_BRACE, "`{'");
+ /* If things aren't going well, there's no need to
+ keep going. */
+ if (!cp_parser_error_occurred (parser))
+ {
+ bool non_constant_p;
+ /* Parse the initializer-list. */
+ initializer_list
+ = cp_parser_initializer_list (parser, &non_constant_p);
+ /* Allow a trailing `,'. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the final `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, "`}'");
+ }
+ /* If that worked, we're definitely looking at a
+ compound-literal expression. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ /* Warn the user that a compound literal is not
+ allowed in standard C++. */
+ if (pedantic)
+ pedwarn ("ISO C++ forbids compound-literals");
+ /* Form the representation of the compound-literal. */
+ postfix_expression
+ = finish_compound_literal (type, initializer_list);
+ break;
+ }
+ }
+
+ /* It must be a primary-expression. */
+ postfix_expression = cp_parser_primary_expression (parser,
+ &idk,
+ &qualifying_class);
+ }
+ break;
+ }
+
+ /* If we were avoiding committing to the processing of a
+ qualified-id until we knew whether or not we had a
+ pointer-to-member, we now know. */
+ if (qualifying_class)
+ {
+ bool done;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ done = (token->type != CPP_OPEN_SQUARE
+ && token->type != CPP_OPEN_PAREN
+ && token->type != CPP_DOT
+ && token->type != CPP_DEREF
+ && token->type != CPP_PLUS_PLUS
+ && token->type != CPP_MINUS_MINUS);
+
+ postfix_expression = finish_qualified_id_expr (qualifying_class,
+ postfix_expression,
+ done,
+ address_p);
+ if (done)
+ return postfix_expression;
+ }
+
+ /* Keep looping until the postfix-expression is complete. */
+ while (true)
+ {
+ if (idk == CP_ID_KIND_UNQUALIFIED
+ && TREE_CODE (postfix_expression) == IDENTIFIER_NODE
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
+ /* It is not a Koenig lookup function call. */
+ postfix_expression
+ = unqualified_name_lookup_error (postfix_expression);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_OPEN_SQUARE:
+ /* postfix-expression [ expression ] */
+ {
+ tree index;
+
+ /* Consume the `[' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the index expression. */
+ index = cp_parser_expression (parser);
+ /* Look for the closing `]'. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'");
+
+ /* Build the ARRAY_REF. */
+ postfix_expression
+ = grok_array_decl (postfix_expression, index);
+ idk = CP_ID_KIND_NONE;
+ /* Array references are not permitted in
+ constant-expressions (but they are allowed
+ in offsetof). */
+ if (!parser->in_offsetof_p
+ && cp_parser_non_integral_constant_expression
+ (parser, "an array reference"))
+ postfix_expression = error_mark_node;
+ }
+ break;
+
+ case CPP_OPEN_PAREN:
+ /* postfix-expression ( expression-list [opt] ) */
+ {
+ bool koenig_p;
+ tree args = (cp_parser_parenthesized_expression_list
+ (parser, false, /*non_constant_p=*/NULL));
+
+ if (args == error_mark_node)
+ {
+ postfix_expression = error_mark_node;
+ break;
+ }
+
+ /* Function calls are not permitted in
+ constant-expressions. */
+ if (cp_parser_non_integral_constant_expression (parser,
+ "a function call"))
+ {
+ postfix_expression = error_mark_node;
+ break;
+ }
+
+ koenig_p = false;
+ if (idk == CP_ID_KIND_UNQUALIFIED)
+ {
+ /* We do not perform argument-dependent lookup if
+ normal lookup finds a non-function, in accordance
+ with the expected resolution of DR 218. */
+ if (args
+ && (is_overloaded_fn (postfix_expression)
+ || TREE_CODE (postfix_expression) == IDENTIFIER_NODE))
+ {
+ koenig_p = true;
+ postfix_expression
+ = perform_koenig_lookup (postfix_expression, args);
+ }
+ else if (TREE_CODE (postfix_expression) == IDENTIFIER_NODE)
+ postfix_expression
+ = unqualified_fn_lookup_error (postfix_expression);
+ }
+
+ if (TREE_CODE (postfix_expression) == COMPONENT_REF)
+ {
+ tree instance = TREE_OPERAND (postfix_expression, 0);
+ tree fn = TREE_OPERAND (postfix_expression, 1);
+
+ if (processing_template_decl
+ && (type_dependent_expression_p (instance)
+ || (!BASELINK_P (fn)
+ && TREE_CODE (fn) != FIELD_DECL)
+ || type_dependent_expression_p (fn)
+ || any_type_dependent_arguments_p (args)))
+ {
+ postfix_expression
+ = build_min_nt (CALL_EXPR, postfix_expression, args);
+ break;
+ }
+
+ if (BASELINK_P (fn))
+ postfix_expression
+ = (build_new_method_call
+ (instance, fn, args, NULL_TREE,
+ (idk == CP_ID_KIND_QUALIFIED
+ ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL)));
+ else
+ postfix_expression
+ = finish_call_expr (postfix_expression, args,
+ /*disallow_virtual=*/false,
+ /*koenig_p=*/false);
+ }
+ else if (TREE_CODE (postfix_expression) == OFFSET_REF
+ || TREE_CODE (postfix_expression) == MEMBER_REF
+ || TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
+ postfix_expression = (build_offset_ref_call_from_tree
+ (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,
+ /*disallow_virtual=*/true,
+ koenig_p);
+ else
+ /* All other function calls. */
+ postfix_expression
+ = finish_call_expr (postfix_expression, args,
+ /*disallow_virtual=*/false,
+ koenig_p);
+
+ /* The POSTFIX_EXPRESSION is certainly no longer an id. */
+ idk = CP_ID_KIND_NONE;
+ }
+ break;
+
+ case CPP_DOT:
+ case CPP_DEREF:
+ /* postfix-expression . template [opt] id-expression
+ postfix-expression . pseudo-destructor-name
+ postfix-expression -> template [opt] id-expression
+ postfix-expression -> pseudo-destructor-name */
+ {
+ tree name;
+ bool dependent_p;
+ bool template_p;
+ tree scope = NULL_TREE;
+ enum cpp_ttype token_type = token->type;
+
+ /* If this is a `->' operator, dereference the pointer. */
+ if (token->type == CPP_DEREF)
+ postfix_expression = build_x_arrow (postfix_expression);
+ /* Check to see whether or not the expression is
+ type-dependent. */
+ dependent_p = type_dependent_expression_p (postfix_expression);
+ /* The identifier following the `->' or `.' is not
+ qualified. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ idk = CP_ID_KIND_NONE;
+ /* Enter the scope corresponding to the type of the object
+ given by the POSTFIX_EXPRESSION. */
+ if (!dependent_p
+ && TREE_TYPE (postfix_expression) != NULL_TREE)
+ {
+ scope = TREE_TYPE (postfix_expression);
+ /* According to the standard, no expression should
+ ever have reference type. Unfortunately, we do not
+ currently match the standard in this respect in
+ that our internal representation of an expression
+ may have reference type even when the standard says
+ it does not. Therefore, we have to manually obtain
+ the underlying type here. */
+ scope = non_reference (scope);
+ /* The type of the POSTFIX_EXPRESSION must be
+ complete. */
+ scope = complete_type_or_else (scope, NULL_TREE);
+ /* Let the name lookup machinery know that we are
+ processing a class member access expression. */
+ parser->context->object_type = scope;
+ /* If something went wrong, we want to be able to
+ discern that case, as opposed to the case where
+ there was no SCOPE due to the type of expression
+ being dependent. */
+ if (!scope)
+ scope = error_mark_node;
+ /* If the SCOPE was erroneous, make the various
+ semantic analysis functions exit quickly -- and
+ without issuing additional error messages. */
+ if (scope == error_mark_node)
+ postfix_expression = error_mark_node;
+ }
+
+ /* Consume the `.' or `->' operator. */
+ cp_lexer_consume_token (parser->lexer);
+ /* If the SCOPE is not a scalar type, we are looking at an
+ ordinary class member access expression, rather than a
+ pseudo-destructor-name. */
+ if (!scope || !SCALAR_TYPE_P (scope))
+ {
+ template_p = cp_parser_optional_template_keyword (parser);
+ /* Parse the id-expression. */
+ name = cp_parser_id_expression (parser,
+ template_p,
+ /*check_dependency_p=*/true,
+ /*template_p=*/NULL,
+ /*declarator_p=*/false);
+ /* In general, build a SCOPE_REF if the member name is
+ qualified. However, if the name was not dependent
+ and has already been resolved; there is no need to
+ build the SCOPE_REF. For example;
+
+ struct X { void f(); };
+ template <typename T> void f(T* t) { t->X::f(); }
+
+ Even though "t" is dependent, "X::f" is not and has
+ been resolved to a BASELINK; there is no need to
+ include scope information. */
+
+ /* But we do need to remember that there was an explicit
+ scope for virtual function calls. */
+ if (parser->scope)
+ idk = CP_ID_KIND_QUALIFIED;
+
+ if (name != error_mark_node
+ && !BASELINK_P (name)
+ && parser->scope)
+ {
+ name = build_nt (SCOPE_REF, parser->scope, name);
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ }
+ if (scope && name && BASELINK_P (name))
+ adjust_result_of_qualified_name_lookup
+ (name, BINFO_TYPE (BASELINK_BINFO (name)), scope);
+ postfix_expression
+ = finish_class_member_access_expr (postfix_expression, name);
+ }
+ /* Otherwise, try the pseudo-destructor-name production. */
+ else
+ {
+ tree s = NULL_TREE;
+ tree type;
+
+ /* Parse the pseudo-destructor-name. */
+ cp_parser_pseudo_destructor_name (parser, &s, &type);
+ /* Form the call. */
+ postfix_expression
+ = finish_pseudo_destructor_expr (postfix_expression,
+ s, TREE_TYPE (type));
+ }
+
+ /* We no longer need to look up names in the scope of the
+ object on the left-hand side of the `.' or `->'
+ operator. */
+ parser->context->object_type = NULL_TREE;
+ /* These operators may not appear in constant-expressions. */
+ if (/* The "->" operator is allowed in the implementation
+ of "offsetof". The "." operator may appear in the
+ name of the member. */
+ !parser->in_offsetof_p
+ && (cp_parser_non_integral_constant_expression
+ (parser,
+ token_type == CPP_DEREF ? "'->'" : "`.'")))
+ postfix_expression = error_mark_node;
+ }
+ break;
+
+ case CPP_PLUS_PLUS:
+ /* postfix-expression ++ */
+ /* Consume the `++' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Generate a representation for the complete expression. */
+ postfix_expression
+ = finish_increment_expr (postfix_expression,
+ POSTINCREMENT_EXPR);
+ /* Increments may not appear in constant-expressions. */
+ if (cp_parser_non_integral_constant_expression (parser,
+ "an increment"))
+ postfix_expression = error_mark_node;
+ idk = CP_ID_KIND_NONE;
+ break;
+
+ case CPP_MINUS_MINUS:
+ /* postfix-expression -- */
+ /* Consume the `--' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Generate a representation for the complete expression. */
+ postfix_expression
+ = finish_increment_expr (postfix_expression,
+ POSTDECREMENT_EXPR);
+ /* Decrements may not appear in constant-expressions. */
+ if (cp_parser_non_integral_constant_expression (parser,
+ "a decrement"))
+ postfix_expression = error_mark_node;
+ idk = CP_ID_KIND_NONE;
+ break;
+
+ default:
+ return postfix_expression;
+ }
+ }
+
+ /* We should never get here. */
+ abort ();
+ return error_mark_node;
+}
+
+/* Parse a parenthesized expression-list.
+
+ expression-list:
+ assignment-expression
+ expression-list, assignment-expression
+
+ attribute-list:
+ expression-list
+ identifier
+ identifier, expression-list
+
+ 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. */
+
+static tree
+cp_parser_parenthesized_expression_list (cp_parser* parser,
+ bool is_attribute_list,
+ bool *non_constant_p)
+{
+ tree expression_list = NULL_TREE;
+ tree identifier = NULL_TREE;
+
+ /* Assume all the expressions will be constant. */
+ if (non_constant_p)
+ *non_constant_p = false;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, "`('"))
+ return error_mark_node;
+
+ /* Consume expressions until there are no more. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
+ while (true)
+ {
+ tree expr;
+
+ /* At the beginning of attribute lists, check to see if the
+ next token is an identifier. */
+ if (is_attribute_list
+ && cp_lexer_peek_token (parser->lexer)->type == CPP_NAME)
+ {
+ cp_token *token;
+
+ /* Consume the identifier. */
+ token = cp_lexer_consume_token (parser->lexer);
+ /* Save the identifier. */
+ identifier = token->value;
+ }
+ else
+ {
+ /* Parse the next assignment-expression. */
+ if (non_constant_p)
+ {
+ bool expr_non_constant_p;
+ expr = (cp_parser_constant_expression
+ (parser, /*allow_non_constant_p=*/true,
+ &expr_non_constant_p));
+ if (expr_non_constant_p)
+ *non_constant_p = true;
+ }
+ else
+ expr = cp_parser_assignment_expression (parser);
+
+ /* Add it to the list. We add error_mark_node
+ 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);
+
+ if (expr == error_mark_node)
+ goto skip_comma;
+ }
+
+ /* After the first item, attribute lists look the same as
+ expression lists. */
+ is_attribute_list = false;
+
+ get_comma:;
+ /* If the next token isn't a `,', then we are done. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+
+ /* Otherwise, consume the `,' and keep going. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'"))
+ {
+ int ending;
+
+ skip_comma:;
+ /* We try and resync to an unnested comma, as that will give the
+ user better diagnostics. */
+ ending = cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/true,
+ /*consume_paren=*/true);
+ if (ending < 0)
+ goto get_comma;
+ if (!ending)
+ return error_mark_node;
+ }
+
+ /* 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);
+
+ return expression_list;
+}
+
+/* Parse a pseudo-destructor-name.
+
+ pseudo-destructor-name:
+ :: [opt] nested-name-specifier [opt] type-name :: ~ type-name
+ :: [opt] nested-name-specifier template template-id :: ~ type-name
+ :: [opt] nested-name-specifier [opt] ~ type-name
+
+ If either of the first two productions is used, sets *SCOPE to the
+ TYPE specified before the final `::'. Otherwise, *SCOPE is set to
+ NULL_TREE. *TYPE is set to the TYPE_DECL for the final type-name,
+ or ERROR_MARK_NODE if the parse fails. */
+
+static void
+cp_parser_pseudo_destructor_name (cp_parser* parser,
+ tree* scope,
+ tree* type)
+{
+ bool nested_name_specifier_p;
+
+ /* Look for the optional `::' operator. */
+ cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/true);
+ /* Look for the optional nested-name-specifier. */
+ nested_name_specifier_p
+ = (cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/true)
+ != NULL_TREE);
+ /* Now, if we saw a nested-name-specifier, we might be doing the
+ second production. */
+ if (nested_name_specifier_p
+ && cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
+ {
+ /* Consume the `template' keyword. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the template-id. */
+ cp_parser_template_id (parser,
+ /*template_keyword_p=*/true,
+ /*check_dependency_p=*/false,
+ /*is_declaration=*/true);
+ /* Look for the `::' token. */
+ cp_parser_require (parser, CPP_SCOPE, "`::'");
+ }
+ /* If the next token is not a `~', then there might be some
+ additional qualification. */
+ else if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMPL))
+ {
+ /* Look for the type-name. */
+ *scope = TREE_TYPE (cp_parser_type_name (parser));
+
+ /* If we didn't get an aggregate type, or we don't have ::~,
+ then something has gone wrong. Since the only caller of this
+ function is looking for something after `.' or `->' after a
+ scalar type, most likely the program is trying to get a
+ member of a non-aggregate type. */
+ if (*scope == error_mark_node
+ || cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE)
+ || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_COMPL)
+ {
+ cp_parser_error (parser, "request for member of non-aggregate type");
+ *type = error_mark_node;
+ return;
+ }
+
+ /* Look for the `::' token. */
+ cp_parser_require (parser, CPP_SCOPE, "`::'");
+ }
+ else
+ *scope = NULL_TREE;
+
+ /* Look for the `~'. */
+ cp_parser_require (parser, CPP_COMPL, "`~'");
+ /* Look for the type-name again. We are not responsible for
+ checking that it matches the first type-name. */
+ *type = cp_parser_type_name (parser);
+}
+
+/* Parse a unary-expression.
+
+ unary-expression:
+ postfix-expression
+ ++ cast-expression
+ -- cast-expression
+ unary-operator cast-expression
+ sizeof unary-expression
+ sizeof ( type-id )
+ new-expression
+ delete-expression
+
+ GNU Extensions:
+
+ unary-expression:
+ __extension__ cast-expression
+ __alignof__ unary-expression
+ __alignof__ ( type-id )
+ __real__ cast-expression
+ __imag__ cast-expression
+ && identifier
+
+ ADDRESS_P is true iff the unary-expression is appearing as the
+ operand of the `&' operator.
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_unary_expression (cp_parser *parser, bool address_p)
+{
+ cp_token *token;
+ enum tree_code unary_operator;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Some keywords give away the kind of expression. */
+ if (token->type == CPP_KEYWORD)
+ {
+ enum rid keyword = token->keyword;
+
+ switch (keyword)
+ {
+ case RID_ALIGNOF:
+ case RID_SIZEOF:
+ {
+ tree operand;
+ enum tree_code op;
+
+ op = keyword == RID_ALIGNOF ? ALIGNOF_EXPR : SIZEOF_EXPR;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the operand. */
+ operand = cp_parser_sizeof_operand (parser, keyword);
+
+ if (TYPE_P (operand))
+ return cxx_sizeof_or_alignof_type (operand, op, true);
+ else
+ return cxx_sizeof_or_alignof_expr (operand, op);
+ }
+
+ case RID_NEW:
+ return cp_parser_new_expression (parser);
+
+ case RID_DELETE:
+ return cp_parser_delete_expression (parser);
+
+ case RID_EXTENSION:
+ {
+ /* The saved value of the PEDANTIC flag. */
+ int saved_pedantic;
+ tree expr;
+
+ /* Save away the PEDANTIC flag. */
+ cp_parser_extension_opt (parser, &saved_pedantic);
+ /* Parse the cast-expression. */
+ expr = cp_parser_simple_cast_expression (parser);
+ /* Restore the PEDANTIC flag. */
+ pedantic = saved_pedantic;
+
+ return expr;
+ }
+
+ case RID_REALPART:
+ case RID_IMAGPART:
+ {
+ tree expression;
+
+ /* Consume the `__real__' or `__imag__' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the cast-expression. */
+ expression = cp_parser_simple_cast_expression (parser);
+ /* Create the complete representation. */
+ return build_x_unary_op ((keyword == RID_REALPART
+ ? REALPART_EXPR : IMAGPART_EXPR),
+ expression);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* Look for the `:: new' and `:: delete', which also signal the
+ beginning of a new-expression, or delete-expression,
+ respectively. If the next token is `::', then it might be one of
+ these. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+ {
+ enum rid keyword;
+
+ /* See if the token after the `::' is one of the keywords in
+ which we're interested. */
+ keyword = cp_lexer_peek_nth_token (parser->lexer, 2)->keyword;
+ /* If it's `new', we have a new-expression. */
+ if (keyword == RID_NEW)
+ return cp_parser_new_expression (parser);
+ /* Similarly, for `delete'. */
+ else if (keyword == RID_DELETE)
+ return cp_parser_delete_expression (parser);
+ }
+
+ /* Look for a unary operator. */
+ unary_operator = cp_parser_unary_operator (token);
+ /* The `++' and `--' operators can be handled similarly, even though
+ they are not technically unary-operators in the grammar. */
+ if (unary_operator == ERROR_MARK)
+ {
+ if (token->type == CPP_PLUS_PLUS)
+ unary_operator = PREINCREMENT_EXPR;
+ else if (token->type == CPP_MINUS_MINUS)
+ unary_operator = PREDECREMENT_EXPR;
+ /* Handle the GNU address-of-label extension. */
+ else if (cp_parser_allow_gnu_extensions_p (parser)
+ && token->type == CPP_AND_AND)
+ {
+ tree identifier;
+
+ /* Consume the '&&' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the identifier. */
+ identifier = cp_parser_identifier (parser);
+ /* Create an expression representing the address. */
+ return finish_label_address_expr (identifier);
+ }
+ }
+ if (unary_operator != ERROR_MARK)
+ {
+ tree cast_expression;
+ tree expression = error_mark_node;
+ const char *non_constant_p = NULL;
+
+ /* Consume the operator token. */
+ token = cp_lexer_consume_token (parser->lexer);
+ /* Parse the cast-expression. */
+ cast_expression
+ = cp_parser_cast_expression (parser, unary_operator == ADDR_EXPR);
+ /* Now, build an appropriate representation. */
+ switch (unary_operator)
+ {
+ case INDIRECT_REF:
+ non_constant_p = "`*'";
+ expression = build_x_indirect_ref (cast_expression, "unary *");
+ break;
+
+ case ADDR_EXPR:
+ /* The "&" operator is allowed in the implementation of
+ "offsetof". */
+ if (!parser->in_offsetof_p)
+ non_constant_p = "`&'";
+ /* Fall through. */
+ case BIT_NOT_EXPR:
+ expression = build_x_unary_op (unary_operator, cast_expression);
+ break;
+
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ non_constant_p = (unary_operator == PREINCREMENT_EXPR
+ ? "`++'" : "`--'");
+ /* Fall through. */
+ case CONVERT_EXPR:
+ case NEGATE_EXPR:
+ case TRUTH_NOT_EXPR:
+ expression = finish_unary_op_expr (unary_operator, cast_expression);
+ break;
+
+ default:
+ abort ();
+ }
+
+ if (non_constant_p
+ && cp_parser_non_integral_constant_expression (parser,
+ non_constant_p))
+ expression = error_mark_node;
+
+ return expression;
+ }
+
+ return cp_parser_postfix_expression (parser, address_p);
+}
+
+/* Returns ERROR_MARK if TOKEN is not a unary-operator. If TOKEN is a
+ unary-operator, the corresponding tree code is returned. */
+
+static enum tree_code
+cp_parser_unary_operator (cp_token* token)
+{
+ switch (token->type)
+ {
+ case CPP_MULT:
+ return INDIRECT_REF;
+
+ case CPP_AND:
+ return ADDR_EXPR;
+
+ case CPP_PLUS:
+ return CONVERT_EXPR;
+
+ case CPP_MINUS:
+ return NEGATE_EXPR;
+
+ case CPP_NOT:
+ return TRUTH_NOT_EXPR;
+
+ case CPP_COMPL:
+ return BIT_NOT_EXPR;
+
+ default:
+ return ERROR_MARK;
+ }
+}
+
+/* Parse a new-expression.
+
+ new-expression:
+ :: [opt] new new-placement [opt] new-type-id new-initializer [opt]
+ :: [opt] new new-placement [opt] ( type-id ) new-initializer [opt]
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_new_expression (cp_parser* parser)
+{
+ bool global_scope_p;
+ tree placement;
+ tree type;
+ tree initializer;
+
+ /* Look for the optional `::' operator. */
+ global_scope_p
+ = (cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false)
+ != NULL_TREE);
+ /* Look for the `new' operator. */
+ cp_parser_require_keyword (parser, RID_NEW, "`new'");
+ /* There's no easy way to tell a new-placement from the
+ `( type-id )' construct. */
+ cp_parser_parse_tentatively (parser);
+ /* Look for a new-placement. */
+ 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 the next token is a `(', then we have a parenthesized
+ type-id. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the type-id. */
+ type = cp_parser_type_id (parser);
+ /* Look for the closing `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ /* There should not be a direct-new-declarator in this production,
+ but GCC used to allowed this, so we check and emit a sensible error
+ message for this case. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+ {
+ error ("array bound forbidden after parenthesized type-id");
+ inform ("try removing the parentheses around the type-id");
+ cp_parser_direct_new_declarator (parser);
+ }
+ }
+ /* Otherwise, there must be a new-type-id. */
+ else
+ type = cp_parser_new_type_id (parser);
+
+ /* If the next token is a `(', then we have a new-initializer. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ initializer = cp_parser_new_initializer (parser);
+ else
+ initializer = NULL_TREE;
+
+ /* A new-expression may not appear in an integral constant
+ expression. */
+ if (cp_parser_non_integral_constant_expression (parser, "`new'"))
+ return error_mark_node;
+
+ /* Create a representation of the new-expression. */
+ return build_new (placement, type, initializer, global_scope_p);
+}
+
+/* Parse a new-placement.
+
+ new-placement:
+ ( expression-list )
+
+ Returns the same representation as for an expression-list. */
+
+static tree
+cp_parser_new_placement (cp_parser* parser)
+{
+ tree expression_list;
+
+ /* Parse the expression-list. */
+ expression_list = (cp_parser_parenthesized_expression_list
+ (parser, false, /*non_constant_p=*/NULL));
+
+ return expression_list;
+}
+
+/* Parse a new-type-id.
+
+ new-type-id:
+ type-specifier-seq new-declarator [opt]
+
+ Returns a TREE_LIST whose TREE_PURPOSE is the type-specifier-seq,
+ and whose TREE_VALUE is the new-declarator. */
+
+static tree
+cp_parser_new_type_id (cp_parser* parser)
+{
+ tree type_specifier_seq;
+ tree declarator;
+ const char *saved_message;
+
+ /* The type-specifier sequence must not contain type definitions.
+ (It cannot contain declarations of new types either, but if they
+ are not definitions we will catch that because they are not
+ complete.) */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = "types may not be defined in a new-type-id";
+ /* Parse the type-specifier-seq. */
+ type_specifier_seq = cp_parser_type_specifier_seq (parser);
+ /* Restore the old message. */
+ parser->type_definition_forbidden_message = saved_message;
+ /* Parse the new-declarator. */
+ declarator = cp_parser_new_declarator_opt (parser);
+
+ return build_tree_list (type_specifier_seq, declarator);
+}
+
+/* Parse an (optional) new-declarator.
+
+ new-declarator:
+ ptr-operator new-declarator [opt]
+ direct-new-declarator
+
+ Returns a representation of the declarator. See
+ cp_parser_declarator for the representations used. */
+
+static tree
+cp_parser_new_declarator_opt (cp_parser* parser)
+{
+ enum tree_code code;
+ tree type;
+ tree cv_qualifier_seq;
+
+ /* We don't know if there's a ptr-operator next, or not. */
+ cp_parser_parse_tentatively (parser);
+ /* Look for a ptr-operator. */
+ code = cp_parser_ptr_operator (parser, &type, &cv_qualifier_seq);
+ /* If that worked, look for more new-declarators. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ tree declarator;
+
+ /* Parse another optional declarator. */
+ declarator = cp_parser_new_declarator_opt (parser);
+
+ /* Create the representation of the declarator. */
+ if (code == INDIRECT_REF)
+ declarator = make_pointer_declarator (cv_qualifier_seq,
+ declarator);
+ else
+ declarator = make_reference_declarator (cv_qualifier_seq,
+ declarator);
+
+ /* Handle the pointer-to-member case. */
+ if (type)
+ declarator = build_nt (SCOPE_REF, type, declarator);
+
+ return declarator;
+ }
+
+ /* If the next token is a `[', there is a direct-new-declarator. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+ return cp_parser_direct_new_declarator (parser);
+
+ return NULL_TREE;
+}
+
+/* Parse a direct-new-declarator.
+
+ direct-new-declarator:
+ [ expression ]
+ direct-new-declarator [constant-expression]
+
+ Returns an ARRAY_REF, following the same conventions as are
+ documented for cp_parser_direct_declarator. */
+
+static tree
+cp_parser_direct_new_declarator (cp_parser* parser)
+{
+ tree declarator = NULL_TREE;
+
+ while (true)
+ {
+ tree expression;
+
+ /* Look for the opening `['. */
+ cp_parser_require (parser, CPP_OPEN_SQUARE, "`['");
+ /* The first expression is not required to be constant. */
+ if (!declarator)
+ {
+ expression = cp_parser_expression (parser);
+ /* The standard requires that the expression have integral
+ type. DR 74 adds enumeration types. We believe that the
+ real intent is that these expressions be handled like the
+ expression in a `switch' condition, which also allows
+ classes with a single conversion to integral or
+ enumeration type. */
+ if (!processing_template_decl)
+ {
+ expression
+ = build_expr_type_conversion (WANT_INT | WANT_ENUM,
+ expression,
+ /*complain=*/true);
+ if (!expression)
+ {
+ error ("expression in new-declarator must have integral or enumeration type");
+ expression = error_mark_node;
+ }
+ }
+ }
+ /* But all the other expressions must be. */
+ else
+ expression
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant=*/false,
+ NULL);
+ /* Look for the closing `]'. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'");
+
+ /* Add this bound to the declarator. */
+ declarator = build_nt (ARRAY_REF, declarator, expression);
+
+ /* If the next token is not a `[', then there are no more
+ bounds. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_SQUARE))
+ break;
+ }
+
+ return declarator;
+}
+
+/* Parse a new-initializer.
+
+ new-initializer:
+ ( expression-list [opt] )
+
+ Returns a representation of the expression-list. If there is no
+ expression-list, VOID_ZERO_NODE is returned. */
+
+static tree
+cp_parser_new_initializer (cp_parser* parser)
+{
+ tree expression_list;
+
+ expression_list = (cp_parser_parenthesized_expression_list
+ (parser, false, /*non_constant_p=*/NULL));
+ if (!expression_list)
+ expression_list = void_zero_node;
+
+ return expression_list;
+}
+
+/* Parse a delete-expression.
+
+ delete-expression:
+ :: [opt] delete cast-expression
+ :: [opt] delete [ ] cast-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_delete_expression (cp_parser* parser)
+{
+ bool global_scope_p;
+ bool array_p;
+ tree expression;
+
+ /* Look for the optional `::' operator. */
+ global_scope_p
+ = (cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false)
+ != NULL_TREE);
+ /* Look for the `delete' keyword. */
+ cp_parser_require_keyword (parser, RID_DELETE, "`delete'");
+ /* See if the array syntax is in use. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+ {
+ /* Consume the `[' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the `]' token. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'");
+ /* Remember that this is the `[]' construct. */
+ array_p = true;
+ }
+ else
+ array_p = false;
+
+ /* Parse the cast-expression. */
+ expression = cp_parser_simple_cast_expression (parser);
+
+ /* A delete-expression may not appear in an integral constant
+ expression. */
+ if (cp_parser_non_integral_constant_expression (parser, "`delete'"))
+ return error_mark_node;
+
+ return delete_sanity (expression, NULL_TREE, array_p, global_scope_p);
+}
+
+/* Parse a cast-expression.
+
+ cast-expression:
+ unary-expression
+ ( type-id ) cast-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_cast_expression (cp_parser *parser, bool address_p)
+{
+ /* If it's a `(', then we might be looking at a cast. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ tree type = NULL_TREE;
+ tree expr = NULL_TREE;
+ bool compound_literal_p;
+ const char *saved_message;
+
+ /* There's no way to know yet whether or not this is a cast.
+ For example, `(int (3))' is a unary-expression, while `(int)
+ 3' is a cast. So, we resort to parsing tentatively. */
+ cp_parser_parse_tentatively (parser);
+ /* Types may not be defined in a cast. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = "types may not be defined in casts";
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ /* A very tricky bit is that `(struct S) { 3 }' is a
+ compound-literal (which we permit in C++ as an extension).
+ But, that construct is not a cast-expression -- it is a
+ postfix-expression. (The reason is that `(struct S) { 3 }.i'
+ is legal; if the compound-literal were a cast-expression,
+ you'd need an extra set of parentheses.) But, if we parse
+ the type-id, and it happens to be a class-specifier, then we
+ will commit to the parse at that point, because we cannot
+ undo the action that is done when creating a new class. So,
+ then we cannot back up and do a postfix-expression.
+
+ Therefore, we scan ahead to the closing `)', and check to see
+ if the token after the `)' is a `{'. If so, we are not
+ looking at a cast-expression.
+
+ Save tokens so that we can put them back. */
+ cp_lexer_save_tokens (parser->lexer);
+ /* Skip tokens until the next token is a closing parenthesis.
+ If we find the closing `)', and the next token is a `{', then
+ we are looking at a compound-literal. */
+ compound_literal_p
+ = (cp_parser_skip_to_closing_parenthesis (parser, false, false,
+ /*consume_paren=*/true)
+ && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE));
+ /* Roll back the tokens we skipped. */
+ cp_lexer_rollback_tokens (parser->lexer);
+ /* If we were looking at a compound-literal, simulate an error
+ so that the call to cp_parser_parse_definitely below will
+ fail. */
+ if (compound_literal_p)
+ cp_parser_simulate_error (parser);
+ else
+ {
+ bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+ parser->in_type_id_in_expr_p = true;
+ /* Look for the type-id. */
+ type = cp_parser_type_id (parser);
+ /* Look for the closing `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
+ }
+
+ /* Restore the saved message. */
+ parser->type_definition_forbidden_message = saved_message;
+
+ /* If ok so far, parse the dependent expression. We cannot be
+ sure it is a cast. Consider `(T ())'. It is a parenthesized
+ ctor of T, but looks like a cast to function returning T
+ without a dependent expression. */
+ if (!cp_parser_error_occurred (parser))
+ expr = cp_parser_simple_cast_expression (parser);
+
+ if (cp_parser_parse_definitely (parser))
+ {
+ /* Warn about old-style casts, if so requested. */
+ if (warn_old_style_cast
+ && !in_system_header
+ && !VOID_TYPE_P (type)
+ && current_lang_name != lang_name_c)
+ warning ("use of old-style cast");
+
+ /* Only type conversions to integral or enumeration types
+ can be used in constant-expressions. */
+ if (parser->integral_constant_expression_p
+ && !dependent_type_p (type)
+ && !INTEGRAL_OR_ENUMERATION_TYPE_P (type)
+ && (cp_parser_non_integral_constant_expression
+ (parser,
+ "a casts to a type other than an integral or "
+ "enumeration type")))
+ return error_mark_node;
+
+ /* Perform the cast. */
+ expr = build_c_cast (type, expr);
+ return expr;
+ }
+ }
+
+ /* If we get here, then it's not a cast, so it must be a
+ unary-expression. */
+ return cp_parser_unary_expression (parser, address_p);
+}
+
+/* Parse a pm-expression.
+
+ pm-expression:
+ cast-expression
+ pm-expression .* cast-expression
+ pm-expression ->* cast-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_pm_expression (cp_parser* parser)
+{
+ static const cp_parser_token_tree_map map = {
+ { CPP_DEREF_STAR, MEMBER_REF },
+ { CPP_DOT_STAR, DOTSTAR_EXPR },
+ { CPP_EOF, ERROR_MARK }
+ };
+
+ return cp_parser_binary_expression (parser, map,
+ cp_parser_simple_cast_expression);
+}
+
+/* Parse a multiplicative-expression.
+
+ mulitplicative-expression:
+ pm-expression
+ multiplicative-expression * pm-expression
+ multiplicative-expression / pm-expression
+ multiplicative-expression % pm-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_multiplicative_expression (cp_parser* parser)
+{
+ static const cp_parser_token_tree_map map = {
+ { CPP_MULT, MULT_EXPR },
+ { CPP_DIV, TRUNC_DIV_EXPR },
+ { CPP_MOD, TRUNC_MOD_EXPR },
+ { CPP_EOF, ERROR_MARK }
+ };
+
+ return cp_parser_binary_expression (parser,
+ map,
+ cp_parser_pm_expression);
+}
+
+/* Parse an additive-expression.
+
+ additive-expression:
+ multiplicative-expression
+ additive-expression + multiplicative-expression
+ additive-expression - multiplicative-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_additive_expression (cp_parser* parser)
+{
+ static const cp_parser_token_tree_map map = {
+ { CPP_PLUS, PLUS_EXPR },
+ { CPP_MINUS, MINUS_EXPR },
+ { CPP_EOF, ERROR_MARK }
+ };
+
+ return cp_parser_binary_expression (parser,
+ map,
+ cp_parser_multiplicative_expression);
+}
+
+/* Parse a shift-expression.
+
+ shift-expression:
+ additive-expression
+ shift-expression << additive-expression
+ shift-expression >> additive-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_shift_expression (cp_parser* parser)
+{
+ static const cp_parser_token_tree_map map = {
+ { CPP_LSHIFT, LSHIFT_EXPR },
+ { CPP_RSHIFT, RSHIFT_EXPR },
+ { CPP_EOF, ERROR_MARK }
+ };
+
+ return cp_parser_binary_expression (parser,
+ map,
+ cp_parser_additive_expression);
+}
+
+/* Parse a relational-expression.
+
+ relational-expression:
+ shift-expression
+ relational-expression < shift-expression
+ relational-expression > shift-expression
+ relational-expression <= shift-expression
+ relational-expression >= shift-expression
+
+ GNU Extension:
+
+ relational-expression:
+ relational-expression <? shift-expression
+ relational-expression >? shift-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_relational_expression (cp_parser* parser)
+{
+ static const cp_parser_token_tree_map map = {
+ { CPP_LESS, LT_EXPR },
+ { CPP_GREATER, GT_EXPR },
+ { CPP_LESS_EQ, LE_EXPR },
+ { CPP_GREATER_EQ, GE_EXPR },
+ { CPP_MIN, MIN_EXPR },
+ { CPP_MAX, MAX_EXPR },
+ { CPP_EOF, ERROR_MARK }
+ };
+
+ return cp_parser_binary_expression (parser,
+ map,
+ cp_parser_shift_expression);
+}
+
+/* Parse an equality-expression.
+
+ equality-expression:
+ relational-expression
+ equality-expression == relational-expression
+ equality-expression != relational-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_equality_expression (cp_parser* parser)
+{
+ static const cp_parser_token_tree_map map = {
+ { CPP_EQ_EQ, EQ_EXPR },
+ { CPP_NOT_EQ, NE_EXPR },
+ { CPP_EOF, ERROR_MARK }
+ };
+
+ return cp_parser_binary_expression (parser,
+ map,
+ cp_parser_relational_expression);
+}
+
+/* Parse an and-expression.
+
+ and-expression:
+ equality-expression
+ and-expression & equality-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_and_expression (cp_parser* parser)
+{
+ static const cp_parser_token_tree_map map = {
+ { CPP_AND, BIT_AND_EXPR },
+ { CPP_EOF, ERROR_MARK }
+ };
+
+ return cp_parser_binary_expression (parser,
+ map,
+ cp_parser_equality_expression);
+}
+
+/* Parse an exclusive-or-expression.
+
+ exclusive-or-expression:
+ and-expression
+ exclusive-or-expression ^ and-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_exclusive_or_expression (cp_parser* parser)
+{
+ static const cp_parser_token_tree_map map = {
+ { CPP_XOR, BIT_XOR_EXPR },
+ { CPP_EOF, ERROR_MARK }
+ };
+
+ return cp_parser_binary_expression (parser,
+ map,
+ cp_parser_and_expression);
+}
+
+
+/* Parse an inclusive-or-expression.
+
+ inclusive-or-expression:
+ exclusive-or-expression
+ inclusive-or-expression | exclusive-or-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_inclusive_or_expression (cp_parser* parser)
+{
+ static const cp_parser_token_tree_map map = {
+ { CPP_OR, BIT_IOR_EXPR },
+ { CPP_EOF, ERROR_MARK }
+ };
+
+ return cp_parser_binary_expression (parser,
+ map,
+ cp_parser_exclusive_or_expression);
+}
+
+/* Parse a logical-and-expression.
+
+ logical-and-expression:
+ inclusive-or-expression
+ logical-and-expression && inclusive-or-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_logical_and_expression (cp_parser* parser)
+{
+ static const cp_parser_token_tree_map map = {
+ { CPP_AND_AND, TRUTH_ANDIF_EXPR },
+ { CPP_EOF, ERROR_MARK }
+ };
+
+ return cp_parser_binary_expression (parser,
+ map,
+ cp_parser_inclusive_or_expression);
+}
+
+/* Parse a logical-or-expression.
+
+ logical-or-expression:
+ logical-and-expression
+ logical-or-expression || logical-and-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_logical_or_expression (cp_parser* parser)
+{
+ static const cp_parser_token_tree_map map = {
+ { CPP_OR_OR, TRUTH_ORIF_EXPR },
+ { CPP_EOF, ERROR_MARK }
+ };
+
+ return cp_parser_binary_expression (parser,
+ map,
+ cp_parser_logical_and_expression);
+}
+
+/* Parse the `? expression : assignment-expression' part of a
+ conditional-expression. The LOGICAL_OR_EXPR is the
+ logical-or-expression that started the conditional-expression.
+ Returns a representation of the entire conditional-expression.
+
+ This routine is used by cp_parser_assignment_expression.
+
+ ? expression : assignment-expression
+
+ GNU Extensions:
+
+ ? : assignment-expression */
+
+static tree
+cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
+{
+ tree expr;
+ tree assignment_expr;
+
+ /* Consume the `?' token. */
+ 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;
+ else
+ /* Parse the expression. */
+ expr = cp_parser_expression (parser);
+
+ /* The next token should be a `:'. */
+ cp_parser_require (parser, CPP_COLON, "`:'");
+ /* Parse the assignment-expression. */
+ assignment_expr = cp_parser_assignment_expression (parser);
+
+ /* Build the conditional-expression. */
+ return build_x_conditional_expr (logical_or_expr,
+ expr,
+ assignment_expr);
+}
+
+/* Parse an assignment-expression.
+
+ assignment-expression:
+ conditional-expression
+ logical-or-expression assignment-operator assignment_expression
+ throw-expression
+
+ Returns a representation for the expression. */
+
+static tree
+cp_parser_assignment_expression (cp_parser* parser)
+{
+ tree expr;
+
+ /* If the next token is the `throw' keyword, then we're looking at
+ a throw-expression. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_THROW))
+ expr = cp_parser_throw_expression (parser);
+ /* Otherwise, it must be that we are looking at a
+ logical-or-expression. */
+ else
+ {
+ /* Parse the logical-or-expression. */
+ expr = cp_parser_logical_or_expression (parser);
+ /* If the next token is a `?' then we're actually looking at a
+ conditional-expression. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
+ return cp_parser_question_colon_clause (parser, expr);
+ else
+ {
+ enum tree_code assignment_operator;
+
+ /* If it's an assignment-operator, we're using the second
+ production. */
+ assignment_operator
+ = cp_parser_assignment_operator_opt (parser);
+ if (assignment_operator != ERROR_MARK)
+ {
+ tree rhs;
+
+ /* Parse the right-hand side of the assignment. */
+ rhs = cp_parser_assignment_expression (parser);
+ /* An assignment may not appear in a
+ constant-expression. */
+ if (cp_parser_non_integral_constant_expression (parser,
+ "an assignment"))
+ return error_mark_node;
+ /* Build the assignment expression. */
+ expr = build_x_modify_expr (expr,
+ assignment_operator,
+ rhs);
+ }
+ }
+ }
+
+ return expr;
+}
+
+/* Parse an (optional) assignment-operator.
+
+ assignment-operator: one of
+ = *= /= %= += -= >>= <<= &= ^= |=
+
+ GNU Extension:
+
+ assignment-operator: one of
+ <?= >?=
+
+ If the next token is an assignment operator, the corresponding tree
+ code is returned, and the token is consumed. For example, for
+ `+=', PLUS_EXPR is returned. For `=' itself, the code returned is
+ NOP_EXPR. For `/', TRUNC_DIV_EXPR is returned; for `%',
+ TRUNC_MOD_EXPR is returned. If TOKEN is not an assignment
+ operator, ERROR_MARK is returned. */
+
+static enum tree_code
+cp_parser_assignment_operator_opt (cp_parser* parser)
+{
+ enum tree_code op;
+ cp_token *token;
+
+ /* Peek at the next toen. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ switch (token->type)
+ {
+ case CPP_EQ:
+ op = NOP_EXPR;
+ break;
+
+ case CPP_MULT_EQ:
+ op = MULT_EXPR;
+ break;
+
+ case CPP_DIV_EQ:
+ op = TRUNC_DIV_EXPR;
+ break;
+
+ case CPP_MOD_EQ:
+ op = TRUNC_MOD_EXPR;
+ break;
+
+ case CPP_PLUS_EQ:
+ op = PLUS_EXPR;
+ break;
+
+ case CPP_MINUS_EQ:
+ op = MINUS_EXPR;
+ break;
+
+ case CPP_RSHIFT_EQ:
+ op = RSHIFT_EXPR;
+ break;
+
+ case CPP_LSHIFT_EQ:
+ op = LSHIFT_EXPR;
+ break;
+
+ case CPP_AND_EQ:
+ op = BIT_AND_EXPR;
+ break;
+
+ case CPP_XOR_EQ:
+ op = BIT_XOR_EXPR;
+ break;
+
+ case CPP_OR_EQ:
+ op = BIT_IOR_EXPR;
+ break;
+
+ case CPP_MIN_EQ:
+ op = MIN_EXPR;
+ break;
+
+ case CPP_MAX_EQ:
+ op = MAX_EXPR;
+ break;
+
+ default:
+ /* Nothing else is an assignment operator. */
+ op = ERROR_MARK;
+ }
+
+ /* If it was an assignment operator, consume it. */
+ if (op != ERROR_MARK)
+ cp_lexer_consume_token (parser->lexer);
+
+ return op;
+}
+
+/* Parse an expression.
+
+ expression:
+ assignment-expression
+ expression , assignment-expression
+
+ Returns a representation of the expression. */
+
+static tree
+cp_parser_expression (cp_parser* parser)
+{
+ tree expression = NULL_TREE;
+
+ while (true)
+ {
+ tree assignment_expression;
+
+ /* Parse the next assignment-expression. */
+ assignment_expression
+ = cp_parser_assignment_expression (parser);
+ /* If this is the first assignment-expression, we can just
+ save it away. */
+ if (!expression)
+ expression = assignment_expression;
+ else
+ expression = build_x_compound_expr (expression,
+ assignment_expression);
+ /* If the next token is not a comma, then we are done with the
+ expression. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ /* Consume the `,'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* A comma operator cannot appear in a constant-expression. */
+ if (cp_parser_non_integral_constant_expression (parser,
+ "a comma operator"))
+ expression = error_mark_node;
+ }
+
+ return expression;
+}
+
+/* Parse a constant-expression.
+
+ constant-expression:
+ conditional-expression
+
+ If ALLOW_NON_CONSTANT_P a non-constant expression is silently
+ accepted. If ALLOW_NON_CONSTANT_P is true and the expression is not
+ constant, *NON_CONSTANT_P is set to TRUE. If ALLOW_NON_CONSTANT_P
+ is false, NON_CONSTANT_P should be NULL. */
+
+static tree
+cp_parser_constant_expression (cp_parser* parser,
+ bool allow_non_constant_p,
+ bool *non_constant_p)
+{
+ bool saved_integral_constant_expression_p;
+ bool saved_allow_non_integral_constant_expression_p;
+ bool saved_non_integral_constant_expression_p;
+ tree expression;
+
+ /* It might seem that we could simply parse the
+ conditional-expression, and then check to see if it were
+ TREE_CONSTANT. However, an expression that is TREE_CONSTANT is
+ one that the compiler can figure out is constant, possibly after
+ doing some simplifications or optimizations. The standard has a
+ precise definition of constant-expression, and we must honor
+ that, even though it is somewhat more restrictive.
+
+ For example:
+
+ int i[(2, 3)];
+
+ is not a legal declaration, because `(2, 3)' is not a
+ constant-expression. The `,' operator is forbidden in a
+ constant-expression. However, GCC's constant-folding machinery
+ will fold this operation to an INTEGER_CST for `3'. */
+
+ /* Save the old settings. */
+ saved_integral_constant_expression_p = parser->integral_constant_expression_p;
+ saved_allow_non_integral_constant_expression_p
+ = parser->allow_non_integral_constant_expression_p;
+ saved_non_integral_constant_expression_p = parser->non_integral_constant_expression_p;
+ /* We are now parsing a constant-expression. */
+ parser->integral_constant_expression_p = true;
+ parser->allow_non_integral_constant_expression_p = allow_non_constant_p;
+ parser->non_integral_constant_expression_p = false;
+ /* Although the grammar says "conditional-expression", we parse an
+ "assignment-expression", which also permits "throw-expression"
+ and the use of assignment operators. In the case that
+ ALLOW_NON_CONSTANT_P is false, we get better errors than we would
+ otherwise. In the case that ALLOW_NON_CONSTANT_P is true, it is
+ actually essential that we look for an assignment-expression.
+ For example, cp_parser_initializer_clauses uses this function to
+ determine whether a particular assignment-expression is in fact
+ constant. */
+ expression = cp_parser_assignment_expression (parser);
+ /* Restore the old settings. */
+ parser->integral_constant_expression_p = saved_integral_constant_expression_p;
+ parser->allow_non_integral_constant_expression_p
+ = saved_allow_non_integral_constant_expression_p;
+ if (allow_non_constant_p)
+ *non_constant_p = parser->non_integral_constant_expression_p;
+ parser->non_integral_constant_expression_p = saved_non_integral_constant_expression_p;
+
+ return expression;
+}
+
+/* Statements [gram.stmt.stmt] */
+
+/* Parse a statement.
+
+ statement:
+ labeled-statement
+ expression-statement
+ compound-statement
+ selection-statement
+ iteration-statement
+ jump-statement
+ declaration-statement
+ try-block */
+
+static void
+cp_parser_statement (cp_parser* parser, bool in_statement_expr_p)
+{
+ tree statement;
+ cp_token *token;
+ int statement_line_number;
+
+ /* There is no statement yet. */
+ statement = NULL_TREE;
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Remember the line number of the first token in the statement. */
+ statement_line_number = token->location.line;
+ /* If this is a keyword, then that will often determine what kind of
+ statement we have. */
+ if (token->type == CPP_KEYWORD)
+ {
+ enum rid keyword = token->keyword;
+
+ switch (keyword)
+ {
+ case RID_CASE:
+ case RID_DEFAULT:
+ statement = cp_parser_labeled_statement (parser,
+ in_statement_expr_p);
+ break;
+
+ case RID_IF:
+ case RID_SWITCH:
+ statement = cp_parser_selection_statement (parser);
+ break;
+
+ case RID_WHILE:
+ case RID_DO:
+ case RID_FOR:
+ statement = cp_parser_iteration_statement (parser);
+ break;
+
+ case RID_BREAK:
+ case RID_CONTINUE:
+ case RID_RETURN:
+ case RID_GOTO:
+ statement = cp_parser_jump_statement (parser);
+ break;
+
+ case RID_TRY:
+ statement = cp_parser_try_block (parser);
+ break;
+
+ default:
+ /* It might be a keyword like `int' that can start a
+ declaration-statement. */
+ break;
+ }
+ }
+ else if (token->type == CPP_NAME)
+ {
+ /* If the next token is a `:', then we are looking at a
+ labeled-statement. */
+ token = cp_lexer_peek_nth_token (parser->lexer, 2);
+ if (token->type == CPP_COLON)
+ statement = cp_parser_labeled_statement (parser, in_statement_expr_p);
+ }
+ /* Anything that starts with a `{' must be a compound-statement. */
+ else if (token->type == CPP_OPEN_BRACE)
+ statement = cp_parser_compound_statement (parser, false);
+
+ /* Everything else must be a declaration-statement or an
+ expression-statement. Try for the declaration-statement
+ first, unless we are looking at a `;', in which case we know that
+ we have an expression-statement. */
+ if (!statement)
+ {
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ {
+ cp_parser_parse_tentatively (parser);
+ /* Try to parse the declaration-statement. */
+ cp_parser_declaration_statement (parser);
+ /* If that worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ return;
+ }
+ /* Look for an expression-statement instead. */
+ statement = cp_parser_expression_statement (parser, in_statement_expr_p);
+ }
+
+ /* Set the line number for the statement. */
+ if (statement && STATEMENT_CODE_P (TREE_CODE (statement)))
+ STMT_LINENO (statement) = statement_line_number;
+}
+
+/* Parse a labeled-statement.
+
+ labeled-statement:
+ identifier : statement
+ case constant-expression : statement
+ default : statement
+
+ GNU Extension:
+
+ labeled-statement:
+ case constant-expression ... constant-expression : statement
+
+ Returns the new CASE_LABEL, for a `case' or `default' label. For
+ an ordinary label, returns a LABEL_STMT. */
+
+static tree
+cp_parser_labeled_statement (cp_parser* parser, bool in_statement_expr_p)
+{
+ cp_token *token;
+ tree statement = error_mark_node;
+
+ /* The next token should be an identifier. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type != CPP_NAME
+ && token->type != CPP_KEYWORD)
+ {
+ cp_parser_error (parser, "expected labeled-statement");
+ return error_mark_node;
+ }
+
+ switch (token->keyword)
+ {
+ case RID_CASE:
+ {
+ tree expr, expr_hi;
+ cp_token *ellipsis;
+
+ /* Consume the `case' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the constant-expression. */
+ expr = cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/false,
+ NULL);
+
+ ellipsis = cp_lexer_peek_token (parser->lexer);
+ if (ellipsis->type == CPP_ELLIPSIS)
+ {
+ /* Consume the `...' token. */
+ cp_lexer_consume_token (parser->lexer);
+ expr_hi =
+ cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/false,
+ NULL);
+ /* We don't need to emit warnings here, as the common code
+ will do this for us. */
+ }
+ else
+ expr_hi = NULL_TREE;
+
+ if (!parser->in_switch_statement_p)
+ error ("case label `%E' not within a switch statement", expr);
+ else
+ statement = finish_case_label (expr, expr_hi);
+ }
+ break;
+
+ case RID_DEFAULT:
+ /* Consume the `default' token. */
+ cp_lexer_consume_token (parser->lexer);
+ if (!parser->in_switch_statement_p)
+ error ("case label not within a switch statement");
+ else
+ statement = finish_case_label (NULL_TREE, NULL_TREE);
+ break;
+
+ default:
+ /* Anything else must be an ordinary label. */
+ statement = finish_label_stmt (cp_parser_identifier (parser));
+ break;
+ }
+
+ /* Require the `:' token. */
+ cp_parser_require (parser, CPP_COLON, "`:'");
+ /* Parse the labeled statement. */
+ cp_parser_statement (parser, in_statement_expr_p);
+
+ /* Return the label, in the case of a `case' or `default' label. */
+ return statement;
+}
+
+/* Parse an expression-statement.
+
+ expression-statement:
+ expression [opt] ;
+
+ Returns the new EXPR_STMT -- or NULL_TREE if the expression
+ statement consists of nothing more than an `;'. IN_STATEMENT_EXPR_P
+ indicates whether this expression-statement is part of an
+ expression statement. */
+
+static tree
+cp_parser_expression_statement (cp_parser* parser, bool in_statement_expr_p)
+{
+ tree statement = NULL_TREE;
+
+ /* If the next token is a ';', then there is no expression
+ statement. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ statement = cp_parser_expression (parser);
+
+ /* Consume the final `;'. */
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+
+ if (in_statement_expr_p
+ && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
+ {
+ /* This is the final expression statement of a statement
+ expression. */
+ statement = finish_stmt_expr_expr (statement);
+ }
+ else if (statement)
+ statement = finish_expr_stmt (statement);
+ else
+ finish_stmt ();
+
+ return statement;
+}
+
+/* Parse a compound-statement.
+
+ compound-statement:
+ { statement-seq [opt] }
+
+ Returns a COMPOUND_STMT representing the statement. */
+
+static tree
+cp_parser_compound_statement (cp_parser *parser, bool in_statement_expr_p)
+{
+ tree compound_stmt;
+
+ /* Consume the `{'. */
+ if (!cp_parser_require (parser, CPP_OPEN_BRACE, "`{'"))
+ return error_mark_node;
+ /* Begin the compound-statement. */
+ compound_stmt = begin_compound_stmt (/*has_no_scope=*/false);
+ /* Parse an (optional) statement-seq. */
+ cp_parser_statement_seq_opt (parser, in_statement_expr_p);
+ /* Finish the compound-statement. */
+ finish_compound_stmt (compound_stmt);
+ /* Consume the `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, "`}'");
+
+ return compound_stmt;
+}
+
+/* Parse an (optional) statement-seq.
+
+ statement-seq:
+ statement
+ statement-seq [opt] statement */
+
+static void
+cp_parser_statement_seq_opt (cp_parser* parser, bool in_statement_expr_p)
+{
+ /* Scan statements until there aren't any more. */
+ while (true)
+ {
+ /* If we're looking at a `}', then we've run out of statements. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE)
+ || cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+ break;
+
+ /* Parse the statement. */
+ cp_parser_statement (parser, in_statement_expr_p);
+ }
+}
+
+/* Parse a selection-statement.
+
+ selection-statement:
+ if ( condition ) statement
+ if ( condition ) statement else statement
+ switch ( condition ) statement
+
+ Returns the new IF_STMT or SWITCH_STMT. */
+
+static tree
+cp_parser_selection_statement (cp_parser* parser)
+{
+ cp_token *token;
+ enum rid keyword;
+
+ /* Peek at the next token. */
+ token = cp_parser_require (parser, CPP_KEYWORD, "selection-statement");
+
+ /* See what kind of keyword it is. */
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ case RID_IF:
+ case RID_SWITCH:
+ {
+ tree statement;
+ tree condition;
+
+ /* Look for the `('. */
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, "`('"))
+ {
+ cp_parser_skip_to_end_of_statement (parser);
+ return error_mark_node;
+ }
+
+ /* Begin the selection-statement. */
+ if (keyword == RID_IF)
+ statement = begin_if_stmt ();
+ else
+ statement = begin_switch_stmt ();
+
+ /* Parse the condition. */
+ condition = cp_parser_condition (parser);
+ /* Look for the `)'. */
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'"))
+ cp_parser_skip_to_closing_parenthesis (parser, true, false,
+ /*consume_paren=*/true);
+
+ if (keyword == RID_IF)
+ {
+ tree then_stmt;
+
+ /* Add the condition. */
+ finish_if_stmt_cond (condition, statement);
+
+ /* Parse the then-clause. */
+ then_stmt = cp_parser_implicitly_scoped_statement (parser);
+ finish_then_clause (statement);
+
+ /* If the next token is `else', parse the else-clause. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer,
+ RID_ELSE))
+ {
+ tree else_stmt;
+
+ /* Consume the `else' keyword. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the else-clause. */
+ else_stmt
+ = cp_parser_implicitly_scoped_statement (parser);
+ finish_else_clause (statement);
+ }
+
+ /* Now we're all done with the if-statement. */
+ finish_if_stmt ();
+ }
+ else
+ {
+ tree body;
+ bool in_switch_statement_p;
+
+ /* Add the condition. */
+ finish_switch_cond (condition, statement);
+
+ /* Parse the body of the switch-statement. */
+ in_switch_statement_p = parser->in_switch_statement_p;
+ parser->in_switch_statement_p = true;
+ body = cp_parser_implicitly_scoped_statement (parser);
+ parser->in_switch_statement_p = in_switch_statement_p;
+
+ /* Now we're all done with the switch-statement. */
+ finish_switch_stmt (statement);
+ }
+
+ return statement;
+ }
+ break;
+
+ default:
+ cp_parser_error (parser, "expected selection-statement");
+ return error_mark_node;
+ }
+}
+
+/* Parse a condition.
+
+ condition:
+ expression
+ type-specifier-seq declarator = assignment-expression
+
+ GNU Extension:
+
+ condition:
+ type-specifier-seq declarator asm-specification [opt]
+ attributes [opt] = assignment-expression
+
+ Returns the expression that should be tested. */
+
+static tree
+cp_parser_condition (cp_parser* parser)
+{
+ tree type_specifiers;
+ const char *saved_message;
+
+ /* Try the declaration first. */
+ cp_parser_parse_tentatively (parser);
+ /* New types are not allowed in the type-specifier-seq for a
+ condition. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = "types may not be defined in conditions";
+ /* Parse the type-specifier-seq. */
+ type_specifiers = cp_parser_type_specifier_seq (parser);
+ /* Restore the saved message. */
+ parser->type_definition_forbidden_message = saved_message;
+ /* If all is well, we might be looking at a declaration. */
+ if (!cp_parser_error_occurred (parser))
+ {
+ tree decl;
+ tree asm_specification;
+ tree attributes;
+ tree declarator;
+ tree initializer = NULL_TREE;
+
+ /* Parse the declarator. */
+ declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+ /*ctor_dtor_or_conv_p=*/NULL,
+ /*parenthesized_p=*/NULL);
+ /* Parse the attributes. */
+ attributes = cp_parser_attributes_opt (parser);
+ /* Parse the asm-specification. */
+ asm_specification = cp_parser_asm_specification_opt (parser);
+ /* If the next token is not an `=', then we might still be
+ looking at an expression. For example:
+
+ if (A(a).x)
+
+ looks like a decl-specifier-seq and a declarator -- but then
+ there is no `=', so this is an expression. */
+ cp_parser_require (parser, CPP_EQ, "`='");
+ /* If we did see an `=', then we are looking at a declaration
+ for sure. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ /* Create the declaration. */
+ decl = start_decl (declarator, type_specifiers,
+ /*initialized_p=*/true,
+ attributes, /*prefix_attributes=*/NULL_TREE);
+ /* Parse the assignment-expression. */
+ initializer = cp_parser_assignment_expression (parser);
+
+ /* Process the initializer. */
+ cp_finish_decl (decl,
+ initializer,
+ asm_specification,
+ LOOKUP_ONLYCONVERTING);
+
+ return convert_from_reference (decl);
+ }
+ }
+ /* If we didn't even get past the declarator successfully, we are
+ definitely not looking at a declaration. */
+ else
+ cp_parser_abort_tentative_parse (parser);
+
+ /* Otherwise, we are looking at an expression. */
+ return cp_parser_expression (parser);
+}
+
+/* Parse an iteration-statement.
+
+ iteration-statement:
+ while ( condition ) statement
+ do statement while ( expression ) ;
+ for ( for-init-statement condition [opt] ; expression [opt] )
+ statement
+
+ Returns the new WHILE_STMT, DO_STMT, or FOR_STMT. */
+
+static tree
+cp_parser_iteration_statement (cp_parser* parser)
+{
+ cp_token *token;
+ enum rid keyword;
+ tree statement;
+ bool in_iteration_statement_p;
+
+
+ /* Peek at the next token. */
+ token = cp_parser_require (parser, CPP_KEYWORD, "iteration-statement");
+ if (!token)
+ return error_mark_node;
+
+ /* Remember whether or not we are already within an iteration
+ statement. */
+ in_iteration_statement_p = parser->in_iteration_statement_p;
+
+ /* See what kind of keyword it is. */
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ case RID_WHILE:
+ {
+ tree condition;
+
+ /* Begin the while-statement. */
+ statement = begin_while_stmt ();
+ /* Look for the `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+ /* Parse the condition. */
+ condition = cp_parser_condition (parser);
+ finish_while_stmt_cond (condition, statement);
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ /* Parse the dependent statement. */
+ parser->in_iteration_statement_p = true;
+ cp_parser_already_scoped_statement (parser);
+ parser->in_iteration_statement_p = in_iteration_statement_p;
+ /* We're done with the while-statement. */
+ finish_while_stmt (statement);
+ }
+ break;
+
+ case RID_DO:
+ {
+ tree expression;
+
+ /* Begin the do-statement. */
+ statement = begin_do_stmt ();
+ /* Parse the body of the do-statement. */
+ parser->in_iteration_statement_p = true;
+ cp_parser_implicitly_scoped_statement (parser);
+ parser->in_iteration_statement_p = in_iteration_statement_p;
+ finish_do_body (statement);
+ /* Look for the `while' keyword. */
+ cp_parser_require_keyword (parser, RID_WHILE, "`while'");
+ /* Look for the `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+ /* Parse the expression. */
+ expression = cp_parser_expression (parser);
+ /* We're done with the do-statement. */
+ finish_do_stmt (expression, statement);
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ /* Look for the `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+ }
+ break;
+
+ case RID_FOR:
+ {
+ tree condition = NULL_TREE;
+ tree expression = NULL_TREE;
+
+ /* Begin the for-statement. */
+ statement = begin_for_stmt ();
+ /* Look for the `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+ /* Parse the initialization. */
+ cp_parser_for_init_statement (parser);
+ finish_for_init_stmt (statement);
+
+ /* If there's a condition, process it. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ condition = cp_parser_condition (parser);
+ finish_for_cond (condition, statement);
+ /* Look for the `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+
+ /* If there's an expression, process it. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
+ expression = cp_parser_expression (parser);
+ finish_for_expr (expression, statement);
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+
+ /* Parse the body of the for-statement. */
+ parser->in_iteration_statement_p = true;
+ cp_parser_already_scoped_statement (parser);
+ parser->in_iteration_statement_p = in_iteration_statement_p;
+
+ /* We're done with the for-statement. */
+ finish_for_stmt (statement);
+ }
+ break;
+
+ default:
+ cp_parser_error (parser, "expected iteration-statement");
+ statement = error_mark_node;
+ break;
+ }
+
+ return statement;
+}
+
+/* Parse a for-init-statement.
+
+ for-init-statement:
+ expression-statement
+ simple-declaration */
+
+static void
+cp_parser_for_init_statement (cp_parser* parser)
+{
+ /* If the next token is a `;', then we have an empty
+ expression-statement. Grammatically, this is also a
+ simple-declaration, but an invalid one, because it does not
+ declare anything. Therefore, if we did not handle this case
+ specially, we would issue an error message about an invalid
+ declaration. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ {
+ /* We're going to speculatively look for a declaration, falling back
+ to an expression, if necessary. */
+ cp_parser_parse_tentatively (parser);
+ /* Parse the declaration. */
+ cp_parser_simple_declaration (parser,
+ /*function_definition_allowed_p=*/false);
+ /* If the tentative parse failed, then we shall need to look for an
+ expression-statement. */
+ if (cp_parser_parse_definitely (parser))
+ return;
+ }
+
+ cp_parser_expression_statement (parser, false);
+}
+
+/* Parse a jump-statement.
+
+ jump-statement:
+ break ;
+ continue ;
+ return expression [opt] ;
+ goto identifier ;
+
+ GNU extension:
+
+ jump-statement:
+ goto * expression ;
+
+ Returns the new BREAK_STMT, CONTINUE_STMT, RETURN_STMT, or
+ GOTO_STMT. */
+
+static tree
+cp_parser_jump_statement (cp_parser* parser)
+{
+ tree statement = error_mark_node;
+ cp_token *token;
+ enum rid keyword;
+
+ /* Peek at the next token. */
+ token = cp_parser_require (parser, CPP_KEYWORD, "jump-statement");
+ if (!token)
+ return error_mark_node;
+
+ /* See what kind of keyword it is. */
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ case RID_BREAK:
+ if (!parser->in_switch_statement_p
+ && !parser->in_iteration_statement_p)
+ {
+ error ("break statement not within loop or switch");
+ statement = error_mark_node;
+ }
+ else
+ statement = finish_break_stmt ();
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+ break;
+
+ case RID_CONTINUE:
+ if (!parser->in_iteration_statement_p)
+ {
+ error ("continue statement not within a loop");
+ statement = error_mark_node;
+ }
+ else
+ statement = finish_continue_stmt ();
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+ break;
+
+ case RID_RETURN:
+ {
+ tree expr;
+
+ /* If the next token is a `;', then there is no
+ expression. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ expr = cp_parser_expression (parser);
+ else
+ expr = NULL_TREE;
+ /* Build the return-statement. */
+ statement = finish_return_stmt (expr);
+ /* Look for the final `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+ }
+ break;
+
+ case RID_GOTO:
+ /* Create the goto-statement. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_MULT))
+ {
+ /* Issue a warning about this use of a GNU extension. */
+ if (pedantic)
+ pedwarn ("ISO C++ forbids computed gotos");
+ /* Consume the '*' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the dependent expression. */
+ finish_goto_stmt (cp_parser_expression (parser));
+ }
+ else
+ finish_goto_stmt (cp_parser_identifier (parser));
+ /* Look for the final `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+ break;
+
+ default:
+ cp_parser_error (parser, "expected jump-statement");
+ break;
+ }
+
+ return statement;
+}
+
+/* Parse a declaration-statement.
+
+ declaration-statement:
+ block-declaration */
+
+static void
+cp_parser_declaration_statement (cp_parser* parser)
+{
+ /* Parse the block-declaration. */
+ cp_parser_block_declaration (parser, /*statement_p=*/true);
+
+ /* Finish off the statement. */
+ finish_stmt ();
+}
+
+/* Some dependent statements (like `if (cond) statement'), are
+ implicitly in their own scope. In other words, if the statement is
+ a single statement (as opposed to a compound-statement), it is
+ none-the-less treated as if it were enclosed in braces. Any
+ declarations appearing in the dependent statement are out of scope
+ after control passes that point. This function parses a statement,
+ but ensures that is in its own scope, even if it is not a
+ compound-statement.
+
+ Returns the new statement. */
+
+static tree
+cp_parser_implicitly_scoped_statement (cp_parser* parser)
+{
+ tree statement;
+
+ /* If the token is not a `{', then we must take special action. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
+ {
+ /* Create a compound-statement. */
+ statement = begin_compound_stmt (/*has_no_scope=*/false);
+ /* Parse the dependent-statement. */
+ cp_parser_statement (parser, false);
+ /* Finish the dummy compound-statement. */
+ finish_compound_stmt (statement);
+ }
+ /* Otherwise, we simply parse the statement directly. */
+ else
+ statement = cp_parser_compound_statement (parser, false);
+
+ /* Return the statement. */
+ return statement;
+}
+
+/* For some dependent statements (like `while (cond) statement'), we
+ have already created a scope. Therefore, even if the dependent
+ statement is a compound-statement, we do not want to create another
+ scope. */
+
+static void
+cp_parser_already_scoped_statement (cp_parser* parser)
+{
+ /* If the token is not a `{', then we must take special action. */
+ if (cp_lexer_next_token_is_not(parser->lexer, CPP_OPEN_BRACE))
+ {
+ tree statement;
+
+ /* Create a compound-statement. */
+ statement = begin_compound_stmt (/*has_no_scope=*/true);
+ /* Parse the dependent-statement. */
+ cp_parser_statement (parser, false);
+ /* Finish the dummy compound-statement. */
+ finish_compound_stmt (statement);
+ }
+ /* Otherwise, we simply parse the statement directly. */
+ else
+ cp_parser_statement (parser, false);
+}
+
+/* Declarations [gram.dcl.dcl] */
+
+/* Parse an optional declaration-sequence.
+
+ declaration-seq:
+ declaration
+ declaration-seq declaration */
+
+static void
+cp_parser_declaration_seq_opt (cp_parser* parser)
+{
+ while (true)
+ {
+ cp_token *token;
+
+ token = cp_lexer_peek_token (parser->lexer);
+
+ if (token->type == CPP_CLOSE_BRACE
+ || token->type == CPP_EOF)
+ break;
+
+ if (token->type == CPP_SEMICOLON)
+ {
+ /* A declaration consisting of a single semicolon is
+ invalid. Allow it unless we're being pedantic. */
+ if (pedantic && !in_system_header)
+ pedwarn ("extra `;'");
+ cp_lexer_consume_token (parser->lexer);
+ continue;
+ }
+
+ /* The C lexer modifies PENDING_LANG_CHANGE when it wants the
+ parser to enter or exit implicit `extern "C"' blocks. */
+ while (pending_lang_change > 0)
+ {
+ push_lang_context (lang_name_c);
+ --pending_lang_change;
+ }
+ while (pending_lang_change < 0)
+ {
+ pop_lang_context ();
+ ++pending_lang_change;
+ }
+
+ /* Parse the declaration itself. */
+ cp_parser_declaration (parser);
+ }
+}
+
+/* Parse a declaration.
+
+ declaration:
+ block-declaration
+ function-definition
+ template-declaration
+ explicit-instantiation
+ explicit-specialization
+ linkage-specification
+ namespace-definition
+
+ GNU extension:
+
+ declaration:
+ __extension__ declaration */
+
+static void
+cp_parser_declaration (cp_parser* parser)
+{
+ cp_token token1;
+ cp_token token2;
+ int saved_pedantic;
+
+ /* Check for the `__extension__' keyword. */
+ if (cp_parser_extension_opt (parser, &saved_pedantic))
+ {
+ /* Parse the qualified declaration. */
+ cp_parser_declaration (parser);
+ /* Restore the PEDANTIC flag. */
+ pedantic = saved_pedantic;
+
+ return;
+ }
+
+ /* Try to figure out what kind of declaration is present. */
+ token1 = *cp_lexer_peek_token (parser->lexer);
+ if (token1.type != CPP_EOF)
+ token2 = *cp_lexer_peek_nth_token (parser->lexer, 2);
+
+ /* If the next token is `extern' and the following token is a string
+ literal, then we have a linkage specification. */
+ if (token1.keyword == RID_EXTERN
+ && cp_parser_is_string_literal (&token2))
+ cp_parser_linkage_specification (parser);
+ /* If the next token is `template', then we have either a template
+ declaration, an explicit instantiation, or an explicit
+ specialization. */
+ else if (token1.keyword == RID_TEMPLATE)
+ {
+ /* `template <>' indicates a template specialization. */
+ if (token2.type == CPP_LESS
+ && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_GREATER)
+ cp_parser_explicit_specialization (parser);
+ /* `template <' indicates a template declaration. */
+ else if (token2.type == CPP_LESS)
+ cp_parser_template_declaration (parser, /*member_p=*/false);
+ /* Anything else must be an explicit instantiation. */
+ else
+ cp_parser_explicit_instantiation (parser);
+ }
+ /* If the next token is `export', then we have a template
+ declaration. */
+ else if (token1.keyword == RID_EXPORT)
+ cp_parser_template_declaration (parser, /*member_p=*/false);
+ /* If the next token is `extern', 'static' or 'inline' and the one
+ after that is `template', we have a GNU extended explicit
+ instantiation directive. */
+ else if (cp_parser_allow_gnu_extensions_p (parser)
+ && (token1.keyword == RID_EXTERN
+ || token1.keyword == RID_STATIC
+ || token1.keyword == RID_INLINE)
+ && token2.keyword == RID_TEMPLATE)
+ cp_parser_explicit_instantiation (parser);
+ /* If the next token is `namespace', check for a named or unnamed
+ namespace definition. */
+ else if (token1.keyword == RID_NAMESPACE
+ && (/* A named namespace definition. */
+ (token2.type == CPP_NAME
+ && (cp_lexer_peek_nth_token (parser->lexer, 3)->type
+ == CPP_OPEN_BRACE))
+ /* An unnamed namespace definition. */
+ || token2.type == CPP_OPEN_BRACE))
+ cp_parser_namespace_definition (parser);
+ /* We must have either a block declaration or a function
+ definition. */
+ else
+ /* Try to parse a block-declaration, or a function-definition. */
+ cp_parser_block_declaration (parser, /*statement_p=*/false);
+}
+
+/* Parse a block-declaration.
+
+ block-declaration:
+ simple-declaration
+ asm-definition
+ namespace-alias-definition
+ using-declaration
+ using-directive
+
+ GNU Extension:
+
+ block-declaration:
+ __extension__ block-declaration
+ label-declaration
+
+ If STATEMENT_P is TRUE, then this block-declaration is occurring as
+ part of a declaration-statement. */
+
+static void
+cp_parser_block_declaration (cp_parser *parser,
+ bool statement_p)
+{
+ cp_token *token1;
+ int saved_pedantic;
+
+ /* Check for the `__extension__' keyword. */
+ if (cp_parser_extension_opt (parser, &saved_pedantic))
+ {
+ /* Parse the qualified declaration. */
+ cp_parser_block_declaration (parser, statement_p);
+ /* Restore the PEDANTIC flag. */
+ pedantic = saved_pedantic;
+
+ return;
+ }
+
+ /* Peek at the next token to figure out which kind of declaration is
+ present. */
+ token1 = cp_lexer_peek_token (parser->lexer);
+
+ /* If the next keyword is `asm', we have an asm-definition. */
+ if (token1->keyword == RID_ASM)
+ {
+ if (statement_p)
+ cp_parser_commit_to_tentative_parse (parser);
+ cp_parser_asm_definition (parser);
+ }
+ /* If the next keyword is `namespace', we have a
+ namespace-alias-definition. */
+ else if (token1->keyword == RID_NAMESPACE)
+ cp_parser_namespace_alias_definition (parser);
+ /* If the next keyword is `using', we have either a
+ using-declaration or a using-directive. */
+ else if (token1->keyword == RID_USING)
+ {
+ cp_token *token2;
+
+ if (statement_p)
+ cp_parser_commit_to_tentative_parse (parser);
+ /* If the token after `using' is `namespace', then we have a
+ using-directive. */
+ token2 = cp_lexer_peek_nth_token (parser->lexer, 2);
+ if (token2->keyword == RID_NAMESPACE)
+ cp_parser_using_directive (parser);
+ /* Otherwise, it's a using-declaration. */
+ else
+ cp_parser_using_declaration (parser);
+ }
+ /* If the next keyword is `__label__' we have a label declaration. */
+ else if (token1->keyword == RID_LABEL)
+ {
+ if (statement_p)
+ cp_parser_commit_to_tentative_parse (parser);
+ cp_parser_label_declaration (parser);
+ }
+ /* Anything else must be a simple-declaration. */
+ else
+ cp_parser_simple_declaration (parser, !statement_p);
+}
+
+/* Parse a simple-declaration.
+
+ simple-declaration:
+ decl-specifier-seq [opt] init-declarator-list [opt] ;
+
+ init-declarator-list:
+ init-declarator
+ init-declarator-list , init-declarator
+
+ If FUNCTION_DEFINITION_ALLOWED_P is TRUE, then we also recognize a
+ function-definition as a simple-declaration. */
+
+static void
+cp_parser_simple_declaration (cp_parser* parser,
+ bool function_definition_allowed_p)
+{
+ tree decl_specifiers;
+ tree attributes;
+ int declares_class_or_enum;
+ bool saw_declarator;
+
+ /* Defer access checks until we know what is being declared; the
+ checks for names appearing in the decl-specifier-seq should be
+ done as if we were in the scope of the thing being declared. */
+ push_deferring_access_checks (dk_deferred);
+
+ /* Parse the decl-specifier-seq. We have to keep track of whether
+ or not the decl-specifier-seq declares a named class or
+ enumeration type, since that is the only case in which the
+ init-declarator-list is allowed to be empty.
+
+ [dcl.dcl]
+
+ In a simple-declaration, the optional init-declarator-list can be
+ omitted only when declaring a class or enumeration, that is when
+ the decl-specifier-seq contains either a class-specifier, an
+ elaborated-type-specifier, or an enum-specifier. */
+ decl_specifiers
+ = cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_OPTIONAL,
+ &attributes,
+ &declares_class_or_enum);
+ /* We no longer need to defer access checks. */
+ stop_deferring_access_checks ();
+
+ /* In a block scope, a valid declaration must always have a
+ decl-specifier-seq. By not trying to parse declarators, we can
+ resolve the declaration/expression ambiguity more quickly. */
+ if (!function_definition_allowed_p && !decl_specifiers)
+ {
+ cp_parser_error (parser, "expected declaration");
+ goto done;
+ }
+
+ /* If the next two tokens are both identifiers, the code is
+ erroneous. The usual cause of this situation is code like:
+
+ T t;
+
+ where "T" should name a type -- but does not. */
+ if (cp_parser_diagnose_invalid_type_name (parser))
+ {
+ /* If parsing tentatively, we should commit; we really are
+ looking at a declaration. */
+ cp_parser_commit_to_tentative_parse (parser);
+ /* Give up. */
+ goto done;
+ }
+
+ /* Keep going until we hit the `;' at the end of the simple
+ declaration. */
+ saw_declarator = false;
+ while (cp_lexer_next_token_is_not (parser->lexer,
+ CPP_SEMICOLON))
+ {
+ cp_token *token;
+ bool function_definition_p;
+ tree decl;
+
+ saw_declarator = true;
+ /* Parse the init-declarator. */
+ decl = cp_parser_init_declarator (parser, decl_specifiers, attributes,
+ function_definition_allowed_p,
+ /*member_p=*/false,
+ declares_class_or_enum,
+ &function_definition_p);
+ /* If an error occurred while parsing tentatively, exit quickly.
+ (That usually happens when in the body of a function; each
+ statement is treated as a declaration-statement until proven
+ otherwise.) */
+ if (cp_parser_error_occurred (parser))
+ goto done;
+ /* Handle function definitions specially. */
+ if (function_definition_p)
+ {
+ /* If the next token is a `,', then we are probably
+ processing something like:
+
+ void f() {}, *p;
+
+ which is erroneous. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ error ("mixing declarations and function-definitions is forbidden");
+ /* Otherwise, we're done with the list of declarators. */
+ else
+ {
+ pop_deferring_access_checks ();
+ return;
+ }
+ }
+ /* The next token should be either a `,' or a `;'. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's a `,', there are more declarators to come. */
+ if (token->type == CPP_COMMA)
+ cp_lexer_consume_token (parser->lexer);
+ /* If it's a `;', we are done. */
+ else if (token->type == CPP_SEMICOLON)
+ break;
+ /* Anything else is an error. */
+ else
+ {
+ cp_parser_error (parser, "expected `,' or `;'");
+ /* Skip tokens until we reach the end of the statement. */
+ cp_parser_skip_to_end_of_statement (parser);
+ /* If the next token is now a `;', consume it. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+ goto done;
+ }
+ /* After the first time around, a function-definition is not
+ allowed -- even if it was OK at first. For example:
+
+ int i, f() {}
+
+ is not valid. */
+ function_definition_allowed_p = false;
+ }
+
+ /* Issue an error message if no declarators are present, and the
+ decl-specifier-seq does not itself declare a class or
+ enumeration. */
+ if (!saw_declarator)
+ {
+ if (cp_parser_declares_only_class_p (parser))
+ shadow_tag (decl_specifiers);
+ /* Perform any deferred access checks. */
+ perform_deferred_access_checks ();
+ }
+
+ /* Consume the `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+
+ done:
+ pop_deferring_access_checks ();
+}
+
+/* Parse a decl-specifier-seq.
+
+ decl-specifier-seq:
+ decl-specifier-seq [opt] decl-specifier
+
+ decl-specifier:
+ storage-class-specifier
+ type-specifier
+ function-specifier
+ friend
+ typedef
+
+ GNU Extension:
+
+ decl-specifier:
+ attributes
+
+ Returns a TREE_LIST, giving the decl-specifiers in the order they
+ appear in the source code. The TREE_VALUE of each node is the
+ decl-specifier. For a keyword (such as `auto' or `friend'), the
+ TREE_VALUE is simply the corresponding TREE_IDENTIFIER. For the
+ representation of a type-specifier, see cp_parser_type_specifier.
+
+ If there are attributes, they will be stored in *ATTRIBUTES,
+ represented as described above cp_parser_attributes.
+
+ If FRIEND_IS_NOT_CLASS_P is non-NULL, and the `friend' specifier
+ appears, and the entity that will be a friend is not going to be a
+ class, then *FRIEND_IS_NOT_CLASS_P will be set to TRUE. Note that
+ even if *FRIEND_IS_NOT_CLASS_P is FALSE, the entity to which
+ friendship is granted might not be a class.
+
+ *DECLARES_CLASS_OR_ENUM is set to the bitwise or of the following
+ flags:
+
+ 1: one of the decl-specifiers is an elaborated-type-specifier
+ (i.e., a type declaration)
+ 2: one of the decl-specifiers is an enum-specifier or a
+ class-specifier (i.e., a type definition)
+
+ */
+
+static tree
+cp_parser_decl_specifier_seq (cp_parser* parser,
+ cp_parser_flags flags,
+ tree* attributes,
+ int* declares_class_or_enum)
+{
+ tree decl_specs = NULL_TREE;
+ bool friend_p = false;
+ bool constructor_possible_p = !parser->in_declarator_p;
+
+ /* Assume no class or enumeration type is declared. */
+ *declares_class_or_enum = 0;
+
+ /* Assume there are no attributes. */
+ *attributes = NULL_TREE;
+
+ /* Keep reading specifiers until there are no more to read. */
+ while (true)
+ {
+ tree decl_spec = NULL_TREE;
+ bool constructor_p;
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Handle attributes. */
+ if (token->keyword == RID_ATTRIBUTE)
+ {
+ /* Parse the attributes. */
+ decl_spec = cp_parser_attributes_opt (parser);
+ /* Add them to the list. */
+ *attributes = chainon (*attributes, decl_spec);
+ continue;
+ }
+ /* If the next token is an appropriate keyword, we can simply
+ add it to the list. */
+ switch (token->keyword)
+ {
+ case RID_FRIEND:
+ /* decl-specifier:
+ friend */
+ if (friend_p)
+ error ("duplicate `friend'");
+ else
+ friend_p = true;
+ /* The representation of the specifier is simply the
+ appropriate TREE_IDENTIFIER node. */
+ decl_spec = token->value;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ break;
+
+ /* function-specifier:
+ inline
+ virtual
+ explicit */
+ case RID_INLINE:
+ case RID_VIRTUAL:
+ case RID_EXPLICIT:
+ decl_spec = cp_parser_function_specifier_opt (parser);
+ break;
+
+ /* decl-specifier:
+ typedef */
+ case RID_TYPEDEF:
+ /* The representation of the specifier is simply the
+ appropriate TREE_IDENTIFIER node. */
+ decl_spec = token->value;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* A constructor declarator cannot appear in a typedef. */
+ constructor_possible_p = false;
+ /* The "typedef" keyword can only occur in a declaration; we
+ may as well commit at this point. */
+ cp_parser_commit_to_tentative_parse (parser);
+ break;
+
+ /* storage-class-specifier:
+ auto
+ register
+ static
+ extern
+ mutable
+
+ GNU Extension:
+ thread */
+ case RID_AUTO:
+ case RID_REGISTER:
+ case RID_STATIC:
+ case RID_EXTERN:
+ case RID_MUTABLE:
+ case RID_THREAD:
+ decl_spec = cp_parser_storage_class_specifier_opt (parser);
+ break;
+
+ default:
+ break;
+ }
+
+ /* Constructors are a special case. The `S' in `S()' is not a
+ decl-specifier; it is the beginning of the declarator. */
+ constructor_p = (!decl_spec
+ && constructor_possible_p
+ && cp_parser_constructor_declarator_p (parser,
+ friend_p));
+
+ /* If we don't have a DECL_SPEC yet, then we must be looking at
+ a type-specifier. */
+ if (!decl_spec && !constructor_p)
+ {
+ int decl_spec_declares_class_or_enum;
+ bool is_cv_qualifier;
+
+ decl_spec
+ = cp_parser_type_specifier (parser, flags,
+ friend_p,
+ /*is_declaration=*/true,
+ &decl_spec_declares_class_or_enum,
+ &is_cv_qualifier);
+
+ *declares_class_or_enum |= decl_spec_declares_class_or_enum;
+
+ /* If this type-specifier referenced a user-defined type
+ (a typedef, class-name, etc.), then we can't allow any
+ more such type-specifiers henceforth.
+
+ [dcl.spec]
+
+ The longest sequence of decl-specifiers that could
+ possibly be a type name is taken as the
+ decl-specifier-seq of a declaration. The sequence shall
+ be self-consistent as described below.
+
+ [dcl.type]
+
+ As a general rule, at most one type-specifier is allowed
+ in the complete decl-specifier-seq of a declaration. The
+ only exceptions are the following:
+
+ -- const or volatile can be combined with any other
+ type-specifier.
+
+ -- signed or unsigned can be combined with char, long,
+ short, or int.
+
+ -- ..
+
+ Example:
+
+ typedef char* Pc;
+ void g (const int Pc);
+
+ Here, Pc is *not* part of the decl-specifier seq; it's
+ the declarator. Therefore, once we see a type-specifier
+ (other than a cv-qualifier), we forbid any additional
+ user-defined types. We *do* still allow things like `int
+ int' to be considered a decl-specifier-seq, and issue the
+ error message later. */
+ if (decl_spec && !is_cv_qualifier)
+ flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
+ /* A constructor declarator cannot follow a type-specifier. */
+ if (decl_spec)
+ constructor_possible_p = false;
+ }
+
+ /* If we still do not have a DECL_SPEC, then there are no more
+ decl-specifiers. */
+ if (!decl_spec)
+ {
+ /* Issue an error message, unless the entire construct was
+ optional. */
+ if (!(flags & CP_PARSER_FLAGS_OPTIONAL))
+ {
+ cp_parser_error (parser, "expected decl specifier");
+ return error_mark_node;
+ }
+
+ break;
+ }
+
+ /* Add the DECL_SPEC to the list of specifiers. */
+ if (decl_specs == NULL || TREE_VALUE (decl_specs) != error_mark_node)
+ decl_specs = tree_cons (NULL_TREE, decl_spec, decl_specs);
+
+ /* After we see one decl-specifier, further decl-specifiers are
+ always optional. */
+ flags |= CP_PARSER_FLAGS_OPTIONAL;
+ }
+
+ /* Don't allow a friend specifier with a class definition. */
+ if (friend_p && (*declares_class_or_enum & 2))
+ error ("class definition may not be declared a friend");
+
+ /* We have built up the DECL_SPECS in reverse order. Return them in
+ the correct order. */
+ return nreverse (decl_specs);
+}
+
+/* Parse an (optional) storage-class-specifier.
+
+ storage-class-specifier:
+ auto
+ register
+ static
+ extern
+ mutable
+
+ GNU Extension:
+
+ storage-class-specifier:
+ thread
+
+ Returns an IDENTIFIER_NODE corresponding to the keyword used. */
+
+static tree
+cp_parser_storage_class_specifier_opt (cp_parser* parser)
+{
+ switch (cp_lexer_peek_token (parser->lexer)->keyword)
+ {
+ case RID_AUTO:
+ case RID_REGISTER:
+ case RID_STATIC:
+ case RID_EXTERN:
+ case RID_MUTABLE:
+ case RID_THREAD:
+ /* Consume the token. */
+ return cp_lexer_consume_token (parser->lexer)->value;
+
+ default:
+ return NULL_TREE;
+ }
+}
+
+/* Parse an (optional) function-specifier.
+
+ function-specifier:
+ inline
+ virtual
+ explicit
+
+ Returns an IDENTIFIER_NODE corresponding to the keyword used. */
+
+static tree
+cp_parser_function_specifier_opt (cp_parser* parser)
+{
+ switch (cp_lexer_peek_token (parser->lexer)->keyword)
+ {
+ case RID_INLINE:
+ case RID_VIRTUAL:
+ case RID_EXPLICIT:
+ /* Consume the token. */
+ return cp_lexer_consume_token (parser->lexer)->value;
+
+ default:
+ return NULL_TREE;
+ }
+}
+
+/* Parse a linkage-specification.
+
+ linkage-specification:
+ extern string-literal { declaration-seq [opt] }
+ extern string-literal declaration */
+
+static void
+cp_parser_linkage_specification (cp_parser* parser)
+{
+ cp_token *token;
+ tree linkage;
+
+ /* Look for the `extern' keyword. */
+ cp_parser_require_keyword (parser, RID_EXTERN, "`extern'");
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not a string-literal, then there's a problem. */
+ if (!cp_parser_is_string_literal (token))
+ {
+ cp_parser_error (parser, "expected language-name");
+ return;
+ }
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Transform the literal into an identifier. If the literal is a
+ wide-character string, or contains embedded NULs, then we can't
+ handle it as the user wants. */
+ if (token->type == CPP_WSTRING
+ || (strlen (TREE_STRING_POINTER (token->value))
+ != (size_t) (TREE_STRING_LENGTH (token->value) - 1)))
+ {
+ cp_parser_error (parser, "invalid linkage-specification");
+ /* Assume C++ linkage. */
+ linkage = get_identifier ("c++");
+ }
+ /* If it's a simple string constant, things are easier. */
+ else
+ linkage = get_identifier (TREE_STRING_POINTER (token->value));
+
+ /* We're now using the new linkage. */
+ push_lang_context (linkage);
+
+ /* If the next token is a `{', then we're using the first
+ production. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ /* Consume the `{' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the declarations. */
+ cp_parser_declaration_seq_opt (parser);
+ /* Look for the closing `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, "`}'");
+ }
+ /* Otherwise, there's just one declaration. */
+ else
+ {
+ bool saved_in_unbraced_linkage_specification_p;
+
+ saved_in_unbraced_linkage_specification_p
+ = parser->in_unbraced_linkage_specification_p;
+ parser->in_unbraced_linkage_specification_p = true;
+ have_extern_spec = true;
+ cp_parser_declaration (parser);
+ have_extern_spec = false;
+ parser->in_unbraced_linkage_specification_p
+ = saved_in_unbraced_linkage_specification_p;
+ }
+
+ /* We're done with the linkage-specification. */
+ pop_lang_context ();
+}
+
+/* Special member functions [gram.special] */
+
+/* Parse a conversion-function-id.
+
+ conversion-function-id:
+ operator conversion-type-id
+
+ Returns an IDENTIFIER_NODE representing the operator. */
+
+static tree
+cp_parser_conversion_function_id (cp_parser* parser)
+{
+ tree type;
+ tree saved_scope;
+ tree saved_qualifying_scope;
+ tree saved_object_scope;
+ bool pop_p = false;
+
+ /* Look for the `operator' token. */
+ if (!cp_parser_require_keyword (parser, RID_OPERATOR, "`operator'"))
+ return error_mark_node;
+ /* When we parse the conversion-type-id, the current scope will be
+ reset. However, we need that information in able to look up the
+ conversion function later, so we save it here. */
+ saved_scope = parser->scope;
+ saved_qualifying_scope = parser->qualifying_scope;
+ saved_object_scope = parser->object_scope;
+ /* We must enter the scope of the class so that the names of
+ entities declared within the class are available in the
+ conversion-type-id. For example, consider:
+
+ struct S {
+ typedef int I;
+ operator I();
+ };
+
+ S::operator I() { ... }
+
+ In order to see that `I' is a type-name in the definition, we
+ must be in the scope of `S'. */
+ if (saved_scope)
+ pop_p = push_scope (saved_scope);
+ /* Parse the conversion-type-id. */
+ type = cp_parser_conversion_type_id (parser);
+ /* Leave the scope of the class, if any. */
+ if (pop_p)
+ pop_scope (saved_scope);
+ /* Restore the saved scope. */
+ parser->scope = saved_scope;
+ parser->qualifying_scope = saved_qualifying_scope;
+ parser->object_scope = saved_object_scope;
+ /* If the TYPE is invalid, indicate failure. */
+ if (type == error_mark_node)
+ return error_mark_node;
+ return mangle_conv_op_name_for_type (type);
+}
+
+/* Parse a conversion-type-id:
+
+ conversion-type-id:
+ type-specifier-seq conversion-declarator [opt]
+
+ Returns the TYPE specified. */
+
+static tree
+cp_parser_conversion_type_id (cp_parser* parser)
+{
+ tree attributes;
+ tree type_specifiers;
+ tree declarator;
+
+ /* Parse the attributes. */
+ attributes = cp_parser_attributes_opt (parser);
+ /* Parse the type-specifiers. */
+ type_specifiers = cp_parser_type_specifier_seq (parser);
+ /* If that didn't work, stop. */
+ if (type_specifiers == error_mark_node)
+ return error_mark_node;
+ /* Parse the conversion-declarator. */
+ declarator = cp_parser_conversion_declarator_opt (parser);
+
+ return grokdeclarator (declarator, type_specifiers, TYPENAME,
+ /*initialized=*/0, &attributes);
+}
+
+/* Parse an (optional) conversion-declarator.
+
+ conversion-declarator:
+ ptr-operator conversion-declarator [opt]
+
+ Returns a representation of the declarator. See
+ cp_parser_declarator for details. */
+
+static tree
+cp_parser_conversion_declarator_opt (cp_parser* parser)
+{
+ enum tree_code code;
+ tree class_type;
+ tree cv_qualifier_seq;
+
+ /* We don't know if there's a ptr-operator next, or not. */
+ cp_parser_parse_tentatively (parser);
+ /* Try the ptr-operator. */
+ code = cp_parser_ptr_operator (parser, &class_type,
+ &cv_qualifier_seq);
+ /* If it worked, look for more conversion-declarators. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ tree declarator;
+
+ /* Parse another optional declarator. */
+ declarator = cp_parser_conversion_declarator_opt (parser);
+
+ /* Create the representation of the declarator. */
+ if (code == INDIRECT_REF)
+ declarator = make_pointer_declarator (cv_qualifier_seq,
+ declarator);
+ else
+ declarator = make_reference_declarator (cv_qualifier_seq,
+ declarator);
+
+ /* Handle the pointer-to-member case. */
+ if (class_type)
+ declarator = build_nt (SCOPE_REF, class_type, declarator);
+
+ return declarator;
+ }
+
+ return NULL_TREE;
+}
+
+/* Parse an (optional) ctor-initializer.
+
+ ctor-initializer:
+ : mem-initializer-list
+
+ Returns TRUE iff the ctor-initializer was actually present. */
+
+static bool
+cp_parser_ctor_initializer_opt (cp_parser* parser)
+{
+ /* If the next token is not a `:', then there is no
+ ctor-initializer. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
+ {
+ /* Do default initialization of any bases and members. */
+ if (DECL_CONSTRUCTOR_P (current_function_decl))
+ finish_mem_initializers (NULL_TREE);
+
+ return false;
+ }
+
+ /* Consume the `:' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* And the mem-initializer-list. */
+ cp_parser_mem_initializer_list (parser);
+
+ return true;
+}
+
+/* Parse a mem-initializer-list.
+
+ mem-initializer-list:
+ mem-initializer
+ mem-initializer , mem-initializer-list */
+
+static void
+cp_parser_mem_initializer_list (cp_parser* parser)
+{
+ tree mem_initializer_list = NULL_TREE;
+
+ /* Let the semantic analysis code know that we are starting the
+ mem-initializer-list. */
+ if (!DECL_CONSTRUCTOR_P (current_function_decl))
+ error ("only constructors take base initializers");
+
+ /* Loop through the list. */
+ while (true)
+ {
+ tree mem_initializer;
+
+ /* Parse the mem-initializer. */
+ mem_initializer = cp_parser_mem_initializer (parser);
+ /* Add it to the list, unless it was erroneous. */
+ if (mem_initializer)
+ {
+ TREE_CHAIN (mem_initializer) = mem_initializer_list;
+ mem_initializer_list = mem_initializer;
+ }
+ /* If the next token is not a `,', we're done. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ /* Consume the `,' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ /* Perform semantic analysis. */
+ if (DECL_CONSTRUCTOR_P (current_function_decl))
+ finish_mem_initializers (mem_initializer_list);
+}
+
+/* Parse a mem-initializer.
+
+ mem-initializer:
+ mem-initializer-id ( expression-list [opt] )
+
+ GNU extension:
+
+ mem-initializer:
+ ( expression-list [opt] )
+
+ Returns a TREE_LIST. The TREE_PURPOSE is the TYPE (for a base
+ class) or FIELD_DECL (for a non-static data member) to initialize;
+ the TREE_VALUE is the expression-list. */
+
+static tree
+cp_parser_mem_initializer (cp_parser* parser)
+{
+ tree mem_initializer_id;
+ tree expression_list;
+ tree member;
+
+ /* Find out what is being initialized. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
+ {
+ pedwarn ("anachronistic old-style base class initializer");
+ mem_initializer_id = NULL_TREE;
+ }
+ else
+ mem_initializer_id = cp_parser_mem_initializer_id (parser);
+ member = expand_member_init (mem_initializer_id);
+ if (member && !DECL_P (member))
+ in_base_initializer = 1;
+
+ expression_list
+ = cp_parser_parenthesized_expression_list (parser, false,
+ /*non_constant_p=*/NULL);
+ if (!expression_list)
+ expression_list = void_type_node;
+
+ in_base_initializer = 0;
+
+ return member ? build_tree_list (member, expression_list) : NULL_TREE;
+}
+
+/* Parse a mem-initializer-id.
+
+ mem-initializer-id:
+ :: [opt] nested-name-specifier [opt] class-name
+ identifier
+
+ Returns a TYPE indicating the class to be initializer for the first
+ production. Returns an IDENTIFIER_NODE indicating the data member
+ to be initialized for the second production. */
+
+static tree
+cp_parser_mem_initializer_id (cp_parser* parser)
+{
+ bool global_scope_p;
+ bool nested_name_specifier_p;
+ bool template_p = false;
+ tree id;
+
+ /* `typename' is not allowed in this context ([temp.res]). */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
+ {
+ error ("keyword `typename' not allowed in this context (a qualified "
+ "member initializer is implicitly a type)");
+ cp_lexer_consume_token (parser->lexer);
+ }
+ /* Look for the optional `::' operator. */
+ global_scope_p
+ = (cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false)
+ != NULL_TREE);
+ /* Look for the optional nested-name-specifier. The simplest way to
+ implement:
+
+ [temp.res]
+
+ The keyword `typename' is not permitted in a base-specifier or
+ mem-initializer; in these contexts a qualified name that
+ depends on a template-parameter is implicitly assumed to be a
+ type name.
+
+ is to assume that we have seen the `typename' keyword at this
+ point. */
+ nested_name_specifier_p
+ = (cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/true,
+ /*check_dependency_p=*/true,
+ /*type_p=*/true,
+ /*is_declaration=*/true)
+ != NULL_TREE);
+ if (nested_name_specifier_p)
+ template_p = cp_parser_optional_template_keyword (parser);
+ /* If there is a `::' operator or a nested-name-specifier, then we
+ are definitely looking for a class-name. */
+ if (global_scope_p || nested_name_specifier_p)
+ return cp_parser_class_name (parser,
+ /*typename_keyword_p=*/true,
+ /*template_keyword_p=*/template_p,
+ /*type_p=*/false,
+ /*check_dependency_p=*/true,
+ /*class_head_p=*/false,
+ /*is_declaration=*/true);
+ /* Otherwise, we could also be looking for an ordinary identifier. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a class-name. */
+ id = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/true,
+ /*template_keyword_p=*/false,
+ /*type_p=*/false,
+ /*check_dependency_p=*/true,
+ /*class_head_p=*/false,
+ /*is_declaration=*/true);
+ /* If we found one, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ return id;
+ /* Otherwise, look for an ordinary identifier. */
+ return cp_parser_identifier (parser);
+}
+
+/* Overloading [gram.over] */
+
+/* Parse an operator-function-id.
+
+ operator-function-id:
+ operator operator
+
+ Returns an IDENTIFIER_NODE for the operator which is a
+ human-readable spelling of the identifier, e.g., `operator +'. */
+
+static tree
+cp_parser_operator_function_id (cp_parser* parser)
+{
+ /* Look for the `operator' keyword. */
+ if (!cp_parser_require_keyword (parser, RID_OPERATOR, "`operator'"))
+ return error_mark_node;
+ /* And then the name of the operator itself. */
+ return cp_parser_operator (parser);
+}
+
+/* Parse an operator.
+
+ operator:
+ new delete new[] delete[] + - * / % ^ & | ~ ! = < >
+ += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= &&
+ || ++ -- , ->* -> () []
+
+ GNU Extensions:
+
+ operator:
+ <? >? <?= >?=
+
+ Returns an IDENTIFIER_NODE for the operator which is a
+ human-readable spelling of the identifier, e.g., `operator +'. */
+
+static tree
+cp_parser_operator (cp_parser* parser)
+{
+ tree id = NULL_TREE;
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Figure out which operator we have. */
+ switch (token->type)
+ {
+ case CPP_KEYWORD:
+ {
+ enum tree_code op;
+
+ /* The keyword should be either `new' or `delete'. */
+ if (token->keyword == RID_NEW)
+ op = NEW_EXPR;
+ else if (token->keyword == RID_DELETE)
+ op = DELETE_EXPR;
+ else
+ break;
+
+ /* Consume the `new' or `delete' token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's a `[' token then this is the array variant of the
+ operator. */
+ if (token->type == CPP_OPEN_SQUARE)
+ {
+ /* Consume the `[' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the `]' token. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'");
+ id = ansi_opname (op == NEW_EXPR
+ ? VEC_NEW_EXPR : VEC_DELETE_EXPR);
+ }
+ /* Otherwise, we have the non-array variant. */
+ else
+ id = ansi_opname (op);
+
+ return id;
+ }
+
+ case CPP_PLUS:
+ id = ansi_opname (PLUS_EXPR);
+ break;
+
+ case CPP_MINUS:
+ id = ansi_opname (MINUS_EXPR);
+ break;
+
+ case CPP_MULT:
+ id = ansi_opname (MULT_EXPR);
+ break;
+
+ case CPP_DIV:
+ id = ansi_opname (TRUNC_DIV_EXPR);
+ break;
+
+ case CPP_MOD:
+ id = ansi_opname (TRUNC_MOD_EXPR);
+ break;
+
+ case CPP_XOR:
+ id = ansi_opname (BIT_XOR_EXPR);
+ break;
+
+ case CPP_AND:
+ id = ansi_opname (BIT_AND_EXPR);
+ break;
+
+ case CPP_OR:
+ id = ansi_opname (BIT_IOR_EXPR);
+ break;
+
+ case CPP_COMPL:
+ id = ansi_opname (BIT_NOT_EXPR);
+ break;
+
+ case CPP_NOT:
+ id = ansi_opname (TRUTH_NOT_EXPR);
+ break;
+
+ case CPP_EQ:
+ id = ansi_assopname (NOP_EXPR);
+ break;
+
+ case CPP_LESS:
+ id = ansi_opname (LT_EXPR);
+ break;
+
+ case CPP_GREATER:
+ id = ansi_opname (GT_EXPR);
+ break;
+
+ case CPP_PLUS_EQ:
+ id = ansi_assopname (PLUS_EXPR);
+ break;
+
+ case CPP_MINUS_EQ:
+ id = ansi_assopname (MINUS_EXPR);
+ break;
+
+ case CPP_MULT_EQ:
+ id = ansi_assopname (MULT_EXPR);
+ break;
+
+ case CPP_DIV_EQ:
+ id = ansi_assopname (TRUNC_DIV_EXPR);
+ break;
+
+ case CPP_MOD_EQ:
+ id = ansi_assopname (TRUNC_MOD_EXPR);
+ break;
+
+ case CPP_XOR_EQ:
+ id = ansi_assopname (BIT_XOR_EXPR);
+ break;
+
+ case CPP_AND_EQ:
+ id = ansi_assopname (BIT_AND_EXPR);
+ break;
+
+ case CPP_OR_EQ:
+ id = ansi_assopname (BIT_IOR_EXPR);
+ break;
+
+ case CPP_LSHIFT:
+ id = ansi_opname (LSHIFT_EXPR);
+ break;
+
+ case CPP_RSHIFT:
+ id = ansi_opname (RSHIFT_EXPR);
+ break;
+
+ case CPP_LSHIFT_EQ:
+ id = ansi_assopname (LSHIFT_EXPR);
+ break;
+
+ case CPP_RSHIFT_EQ:
+ id = ansi_assopname (RSHIFT_EXPR);
+ break;
+
+ case CPP_EQ_EQ:
+ id = ansi_opname (EQ_EXPR);
+ break;
+
+ case CPP_NOT_EQ:
+ id = ansi_opname (NE_EXPR);
+ break;
+
+ case CPP_LESS_EQ:
+ id = ansi_opname (LE_EXPR);
+ break;
+
+ case CPP_GREATER_EQ:
+ id = ansi_opname (GE_EXPR);
+ break;
+
+ case CPP_AND_AND:
+ id = ansi_opname (TRUTH_ANDIF_EXPR);
+ break;
+
+ case CPP_OR_OR:
+ id = ansi_opname (TRUTH_ORIF_EXPR);
+ break;
+
+ case CPP_PLUS_PLUS:
+ id = ansi_opname (POSTINCREMENT_EXPR);
+ break;
+
+ case CPP_MINUS_MINUS:
+ id = ansi_opname (PREDECREMENT_EXPR);
+ break;
+
+ case CPP_COMMA:
+ id = ansi_opname (COMPOUND_EXPR);
+ break;
+
+ case CPP_DEREF_STAR:
+ id = ansi_opname (MEMBER_REF);
+ break;
+
+ case CPP_DEREF:
+ id = ansi_opname (COMPONENT_REF);
+ break;
+
+ case CPP_OPEN_PAREN:
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the matching `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ return ansi_opname (CALL_EXPR);
+
+ case CPP_OPEN_SQUARE:
+ /* Consume the `['. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the matching `]'. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'");
+ return ansi_opname (ARRAY_REF);
+
+ /* Extensions. */
+ case CPP_MIN:
+ id = ansi_opname (MIN_EXPR);
+ break;
+
+ case CPP_MAX:
+ id = ansi_opname (MAX_EXPR);
+ break;
+
+ case CPP_MIN_EQ:
+ id = ansi_assopname (MIN_EXPR);
+ break;
+
+ case CPP_MAX_EQ:
+ id = ansi_assopname (MAX_EXPR);
+ break;
+
+ default:
+ /* Anything else is an error. */
+ break;
+ }
+
+ /* If we have selected an identifier, we need to consume the
+ operator token. */
+ if (id)
+ cp_lexer_consume_token (parser->lexer);
+ /* Otherwise, no valid operator name was present. */
+ else
+ {
+ cp_parser_error (parser, "expected operator");
+ id = error_mark_node;
+ }
+
+ return id;
+}
+
+/* Parse a template-declaration.
+
+ template-declaration:
+ export [opt] template < template-parameter-list > declaration
+
+ If MEMBER_P is TRUE, this template-declaration occurs within a
+ class-specifier.
+
+ The grammar rule given by the standard isn't correct. What
+ is really meant is:
+
+ template-declaration:
+ export [opt] template-parameter-list-seq
+ decl-specifier-seq [opt] init-declarator [opt] ;
+ export [opt] template-parameter-list-seq
+ function-definition
+
+ template-parameter-list-seq:
+ template-parameter-list-seq [opt]
+ template < template-parameter-list > */
+
+static void
+cp_parser_template_declaration (cp_parser* parser, bool member_p)
+{
+ /* Check for `export'. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXPORT))
+ {
+ /* Consume the `export' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Warn that we do not support `export'. */
+ warning ("keyword `export' not implemented, and will be ignored");
+ }
+
+ cp_parser_template_declaration_after_export (parser, member_p);
+}
+
+/* Parse a template-parameter-list.
+
+ template-parameter-list:
+ template-parameter
+ template-parameter-list , template-parameter
+
+ Returns a TREE_LIST. Each node represents a template parameter.
+ The nodes are connected via their TREE_CHAINs. */
+
+static tree
+cp_parser_template_parameter_list (cp_parser* parser)
+{
+ tree parameter_list = NULL_TREE;
+
+ while (true)
+ {
+ tree parameter;
+ cp_token *token;
+
+ /* Parse the template-parameter. */
+ parameter = cp_parser_template_parameter (parser);
+ /* Add it to the list. */
+ parameter_list = process_template_parm (parameter_list,
+ parameter);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not a `,', we're done. */
+ if (token->type != CPP_COMMA)
+ break;
+ /* Otherwise, consume the `,' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ return parameter_list;
+}
+
+/* Parse a template-parameter.
+
+ template-parameter:
+ type-parameter
+ parameter-declaration
+
+ Returns a TREE_LIST. The TREE_VALUE represents the parameter. The
+ TREE_PURPOSE is the default value, if any. */
+
+static tree
+cp_parser_template_parameter (cp_parser* parser)
+{
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it is `class' or `template', we have a type-parameter. */
+ if (token->keyword == RID_TEMPLATE)
+ return cp_parser_type_parameter (parser);
+ /* If it is `class' or `typename' we do not know yet whether it is a
+ type parameter or a non-type parameter. Consider:
+
+ template <typename T, typename T::X X> ...
+
+ or:
+
+ template <class C, class D*> ...
+
+ Here, the first parameter is a type parameter, and the second is
+ a non-type parameter. We can tell by looking at the token after
+ the identifier -- if it is a `,', `=', or `>' then we have a type
+ parameter. */
+ if (token->keyword == RID_TYPENAME || token->keyword == RID_CLASS)
+ {
+ /* Peek at the token after `class' or `typename'. */
+ token = cp_lexer_peek_nth_token (parser->lexer, 2);
+ /* If it's an identifier, skip it. */
+ if (token->type == CPP_NAME)
+ token = cp_lexer_peek_nth_token (parser->lexer, 3);
+ /* Now, see if the token looks like the end of a template
+ parameter. */
+ if (token->type == CPP_COMMA
+ || token->type == CPP_EQ
+ || token->type == CPP_GREATER)
+ return cp_parser_type_parameter (parser);
+ }
+
+ /* Otherwise, it is a non-type parameter.
+
+ [temp.param]
+
+ When parsing a default template-argument for a non-type
+ template-parameter, the first non-nested `>' is taken as the end
+ of the template parameter-list rather than a greater-than
+ operator. */
+ return
+ cp_parser_parameter_declaration (parser, /*template_parm_p=*/true,
+ /*parenthesized_p=*/NULL);
+}
+
+/* Parse a type-parameter.
+
+ type-parameter:
+ class identifier [opt]
+ class identifier [opt] = type-id
+ typename identifier [opt]
+ typename identifier [opt] = type-id
+ template < template-parameter-list > class identifier [opt]
+ template < template-parameter-list > class identifier [opt]
+ = id-expression
+
+ Returns a TREE_LIST. The TREE_VALUE is itself a TREE_LIST. The
+ TREE_PURPOSE is the default-argument, if any. The TREE_VALUE is
+ the declaration of the parameter. */
+
+static tree
+cp_parser_type_parameter (cp_parser* parser)
+{
+ cp_token *token;
+ tree parameter;
+
+ /* Look for a keyword to tell us what kind of parameter this is. */
+ token = cp_parser_require (parser, CPP_KEYWORD,
+ "`class', `typename', or `template'");
+ if (!token)
+ return error_mark_node;
+
+ switch (token->keyword)
+ {
+ case RID_CLASS:
+ case RID_TYPENAME:
+ {
+ tree identifier;
+ tree default_argument;
+
+ /* If the next token is an identifier, then it names the
+ parameter. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ identifier = cp_parser_identifier (parser);
+ else
+ identifier = NULL_TREE;
+
+ /* Create the parameter. */
+ parameter = finish_template_type_parm (class_type_node, identifier);
+
+ /* If the next token is an `=', we have a default argument. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+ {
+ /* Consume the `=' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the default-argument. */
+ default_argument = cp_parser_type_id (parser);
+ }
+ else
+ default_argument = NULL_TREE;
+
+ /* Create the combined representation of the parameter and the
+ default argument. */
+ parameter = build_tree_list (default_argument, parameter);
+ }
+ break;
+
+ case RID_TEMPLATE:
+ {
+ tree parameter_list;
+ tree identifier;
+ tree default_argument;
+
+ /* Look for the `<'. */
+ cp_parser_require (parser, CPP_LESS, "`<'");
+ /* Parse the template-parameter-list. */
+ begin_template_parm_list ();
+ parameter_list
+ = cp_parser_template_parameter_list (parser);
+ parameter_list = end_template_parm_list (parameter_list);
+ /* Look for the `>'. */
+ cp_parser_require (parser, CPP_GREATER, "`>'");
+ /* Look for the `class' keyword. */
+ cp_parser_require_keyword (parser, RID_CLASS, "`class'");
+ /* If the next token is an `=', then there is a
+ default-argument. If the next token is a `>', we are at
+ the end of the parameter-list. If the next token is a `,',
+ then we are at the end of this parameter. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ identifier = cp_parser_identifier (parser);
+ else
+ identifier = NULL_TREE;
+ /* Create the template parameter. */
+ parameter = finish_template_template_parm (class_type_node,
+ identifier);
+
+ /* If the next token is an `=', then there is a
+ default-argument. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+ {
+ bool is_template;
+
+ /* Consume the `='. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the id-expression. */
+ default_argument
+ = cp_parser_id_expression (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*template_p=*/&is_template,
+ /*declarator_p=*/false);
+ if (TREE_CODE (default_argument) == TYPE_DECL)
+ /* If the id-expression was a template-id that refers to
+ a template-class, we already have the declaration here,
+ so no further lookup is needed. */
+ ;
+ else
+ /* Look up the name. */
+ default_argument
+ = cp_parser_lookup_name (parser, default_argument,
+ /*is_type=*/false,
+ /*is_template=*/is_template,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true);
+ /* See if the default argument is valid. */
+ default_argument
+ = check_template_template_default_arg (default_argument);
+ }
+ else
+ default_argument = NULL_TREE;
+
+ /* Create the combined representation of the parameter and the
+ default argument. */
+ parameter = build_tree_list (default_argument, parameter);
+ }
+ break;
+
+ default:
+ /* Anything else is an error. */
+ cp_parser_error (parser,
+ "expected `class', `typename', or `template'");
+ parameter = error_mark_node;
+ }
+
+ return parameter;
+}
+
+/* Parse a template-id.
+
+ template-id:
+ template-name < template-argument-list [opt] >
+
+ If TEMPLATE_KEYWORD_P is TRUE, then we have just seen the
+ `template' keyword. In this case, a TEMPLATE_ID_EXPR will be
+ returned. Otherwise, if the template-name names a function, or set
+ of functions, returns a TEMPLATE_ID_EXPR. If the template-name
+ names a class, returns a TYPE_DECL for the specialization.
+
+ If CHECK_DEPENDENCY_P is FALSE, names are looked up in
+ uninstantiated templates. */
+
+static tree
+cp_parser_template_id (cp_parser *parser,
+ bool template_keyword_p,
+ bool check_dependency_p,
+ bool is_declaration)
+{
+ tree template;
+ tree arguments;
+ tree template_id;
+ ptrdiff_t start_of_id;
+ tree access_check = NULL_TREE;
+ cp_token *next_token, *next_token_2;
+ bool is_identifier;
+
+ /* If the next token corresponds to a template-id, there is no need
+ to reparse it. */
+ next_token = cp_lexer_peek_token (parser->lexer);
+ if (next_token->type == CPP_TEMPLATE_ID)
+ {
+ tree value;
+ tree check;
+
+ /* Get the stored value. */
+ value = cp_lexer_consume_token (parser->lexer)->value;
+ /* Perform any access checks that were deferred. */
+ for (check = TREE_PURPOSE (value); check; check = TREE_CHAIN (check))
+ perform_or_defer_access_check (TREE_PURPOSE (check),
+ TREE_VALUE (check));
+ /* Return the stored value. */
+ return TREE_VALUE (value);
+ }
+
+ /* Avoid performing name lookup if there is no possibility of
+ finding a template-id. */
+ if ((next_token->type != CPP_NAME && next_token->keyword != RID_OPERATOR)
+ || (next_token->type == CPP_NAME
+ && !cp_parser_nth_token_starts_template_argument_list_p
+ (parser, 2)))
+ {
+ cp_parser_error (parser, "expected template-id");
+ return error_mark_node;
+ }
+
+ /* Remember where the template-id starts. */
+ if (cp_parser_parsing_tentatively (parser)
+ && !cp_parser_committed_to_tentative_parse (parser))
+ {
+ next_token = cp_lexer_peek_token (parser->lexer);
+ start_of_id = cp_lexer_token_difference (parser->lexer,
+ parser->lexer->first_token,
+ next_token);
+ }
+ else
+ start_of_id = -1;
+
+ push_deferring_access_checks (dk_deferred);
+
+ /* Parse the template-name. */
+ is_identifier = false;
+ template = cp_parser_template_name (parser, template_keyword_p,
+ check_dependency_p,
+ is_declaration,
+ &is_identifier);
+ if (template == error_mark_node || is_identifier)
+ {
+ pop_deferring_access_checks ();
+ return template;
+ }
+
+ /* If we find the sequence `[:' after a template-name, it's probably
+ a digraph-typo for `< ::'. Substitute the tokens and check if we can
+ parse correctly the argument list. */
+ next_token = cp_lexer_peek_nth_token (parser->lexer, 1);
+ next_token_2 = cp_lexer_peek_nth_token (parser->lexer, 2);
+ if (next_token->type == CPP_OPEN_SQUARE
+ && next_token->flags & DIGRAPH
+ && next_token_2->type == CPP_COLON
+ && !(next_token_2->flags & PREV_WHITE))
+ {
+ cp_parser_parse_tentatively (parser);
+ /* Change `:' into `::'. */
+ next_token_2->type = CPP_SCOPE;
+ /* Consume the first token (CPP_OPEN_SQUARE - which we pretend it is
+ CPP_LESS. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the arguments. */
+ arguments = cp_parser_enclosed_template_argument_list (parser);
+ if (!cp_parser_parse_definitely (parser))
+ {
+ /* If we couldn't parse an argument list, then we revert our changes
+ and return simply an error. Maybe this is not a template-id
+ after all. */
+ next_token_2->type = CPP_COLON;
+ cp_parser_error (parser, "expected `<'");
+ pop_deferring_access_checks ();
+ return error_mark_node;
+ }
+ /* Otherwise, emit an error about the invalid digraph, but continue
+ parsing because we got our argument list. */
+ pedwarn ("`<::' cannot begin a template-argument list");
+ inform ("`<:' is an alternate spelling for `['. Insert whitespace "
+ "between `<' and `::'");
+ if (!flag_permissive)
+ {
+ static bool hint;
+ if (!hint)
+ {
+ inform ("(if you use `-fpermissive' G++ will accept your code)");
+ hint = true;
+ }
+ }
+ }
+ else
+ {
+ /* Look for the `<' that starts the template-argument-list. */
+ if (!cp_parser_require (parser, CPP_LESS, "`<'"))
+ {
+ pop_deferring_access_checks ();
+ return error_mark_node;
+ }
+ /* Parse the arguments. */
+ arguments = cp_parser_enclosed_template_argument_list (parser);
+ }
+
+ /* Build a representation of the specialization. */
+ if (TREE_CODE (template) == IDENTIFIER_NODE)
+ template_id = build_min_nt (TEMPLATE_ID_EXPR, template, arguments);
+ else if (DECL_CLASS_TEMPLATE_P (template)
+ || DECL_TEMPLATE_TEMPLATE_PARM_P (template))
+ template_id
+ = finish_template_type (template, arguments,
+ cp_lexer_next_token_is (parser->lexer,
+ CPP_SCOPE));
+ else
+ {
+ /* If it's not a class-template or a template-template, it should be
+ a function-template. */
+ my_friendly_assert ((DECL_FUNCTION_TEMPLATE_P (template)
+ || TREE_CODE (template) == OVERLOAD
+ || BASELINK_P (template)),
+ 20010716);
+
+ template_id = lookup_template_function (template, arguments);
+ }
+
+ /* Retrieve any deferred checks. Do not pop this access checks yet
+ so the memory will not be reclaimed during token replacing below. */
+ access_check = get_deferred_access_checks ();
+
+ /* If parsing tentatively, replace the sequence of tokens that makes
+ up the template-id with a CPP_TEMPLATE_ID token. That way,
+ should we re-parse the token stream, we will not have to repeat
+ the effort required to do the parse, nor will we issue duplicate
+ error messages about problems during instantiation of the
+ template. */
+ if (start_of_id >= 0)
+ {
+ cp_token *token;
+
+ /* Find the token that corresponds to the start of the
+ template-id. */
+ token = cp_lexer_advance_token (parser->lexer,
+ parser->lexer->first_token,
+ start_of_id);
+
+ /* Reset the contents of the START_OF_ID token. */
+ token->type = CPP_TEMPLATE_ID;
+ token->value = build_tree_list (access_check, template_id);
+ token->keyword = RID_MAX;
+ /* Purge all subsequent tokens. */
+ cp_lexer_purge_tokens_after (parser->lexer, token);
+ }
+
+ pop_deferring_access_checks ();
+ return template_id;
+}
+
+/* Parse a template-name.
+
+ template-name:
+ identifier
+
+ The standard should actually say:
+
+ template-name:
+ identifier
+ operator-function-id
+
+ A defect report has been filed about this issue.
+
+ A conversion-function-id cannot be a template name because they cannot
+ be part of a template-id. In fact, looking at this code:
+
+ a.operator K<int>()
+
+ the conversion-function-id is "operator K<int>", and K<int> is a type-id.
+ It is impossible to call a templated conversion-function-id with an
+ explicit argument list, since the only allowed template parameter is
+ the type to which it is converting.
+
+ If TEMPLATE_KEYWORD_P is true, then we have just seen the
+ `template' keyword, in a construction like:
+
+ T::template f<3>()
+
+ In that case `f' is taken to be a template-name, even though there
+ is no way of knowing for sure.
+
+ Returns the TEMPLATE_DECL for the template, or an OVERLOAD if the
+ name refers to a set of overloaded functions, at least one of which
+ is a template, or an IDENTIFIER_NODE with the name of the template,
+ if TEMPLATE_KEYWORD_P is true. If CHECK_DEPENDENCY_P is FALSE,
+ names are looked up inside uninstantiated templates. */
+
+static tree
+cp_parser_template_name (cp_parser* parser,
+ bool template_keyword_p,
+ bool check_dependency_p,
+ bool is_declaration,
+ bool *is_identifier)
+{
+ tree identifier;
+ tree decl;
+ tree fns;
+
+ /* If the next token is `operator', then we have either an
+ operator-function-id or a conversion-function-id. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_OPERATOR))
+ {
+ /* We don't know whether we're looking at an
+ operator-function-id or a conversion-function-id. */
+ cp_parser_parse_tentatively (parser);
+ /* Try an operator-function-id. */
+ identifier = cp_parser_operator_function_id (parser);
+ /* If that didn't work, try a conversion-function-id. */
+ if (!cp_parser_parse_definitely (parser))
+ {
+ cp_parser_error (parser, "expected template-name");
+ return error_mark_node;
+ }
+ }
+ /* Look for the identifier. */
+ else
+ identifier = cp_parser_identifier (parser);
+
+ /* If we didn't find an identifier, we don't have a template-id. */
+ if (identifier == error_mark_node)
+ return error_mark_node;
+
+ /* If the name immediately followed the `template' keyword, then it
+ is a template-name. However, if the next token is not `<', then
+ we do not treat it as a template-name, since it is not being used
+ as part of a template-id. This enables us to handle constructs
+ like:
+
+ template <typename T> struct S { S(); };
+ template <typename T> S<T>::S();
+
+ correctly. We would treat `S' as a template -- if it were `S<T>'
+ -- but we do not if there is no `<'. */
+
+ if (processing_template_decl
+ && cp_parser_nth_token_starts_template_argument_list_p (parser, 1))
+ {
+ /* In a declaration, in a dependent context, we pretend that the
+ "template" keyword was present in order to improve error
+ recovery. For example, given:
+
+ template <typename T> void f(T::X<int>);
+
+ we want to treat "X<int>" as a template-id. */
+ if (is_declaration
+ && !template_keyword_p
+ && parser->scope && TYPE_P (parser->scope)
+ && dependent_type_p (parser->scope)
+ /* Do not do this for dtors (or ctors), since they never
+ need the template keyword before their name. */
+ && !constructor_name_p (identifier, parser->scope))
+ {
+ ptrdiff_t start;
+ cp_token* token;
+ /* Explain what went wrong. */
+ error ("non-template `%D' used as template", identifier);
+ inform ("use `%T::template %D' to indicate that it is a template",
+ parser->scope, identifier);
+ /* If parsing tentatively, find the location of the "<"
+ token. */
+ if (cp_parser_parsing_tentatively (parser)
+ && !cp_parser_committed_to_tentative_parse (parser))
+ {
+ cp_parser_simulate_error (parser);
+ token = cp_lexer_peek_token (parser->lexer);
+ token = cp_lexer_prev_token (parser->lexer, token);
+ start = cp_lexer_token_difference (parser->lexer,
+ parser->lexer->first_token,
+ token);
+ }
+ else
+ start = -1;
+ /* Parse the template arguments so that we can issue error
+ messages about them. */
+ cp_lexer_consume_token (parser->lexer);
+ cp_parser_enclosed_template_argument_list (parser);
+ /* Skip tokens until we find a good place from which to
+ continue parsing. */
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/true,
+ /*consume_paren=*/false);
+ /* If parsing tentatively, permanently remove the
+ template argument list. That will prevent duplicate
+ error messages from being issued about the missing
+ "template" keyword. */
+ if (start >= 0)
+ {
+ token = cp_lexer_advance_token (parser->lexer,
+ parser->lexer->first_token,
+ start);
+ cp_lexer_purge_tokens_after (parser->lexer, token);
+ }
+ if (is_identifier)
+ *is_identifier = true;
+ return identifier;
+ }
+
+ /* If the "template" keyword is present, then there is generally
+ no point in doing name-lookup, so we just return IDENTIFIER.
+ But, if the qualifying scope is non-dependent then we can
+ (and must) do name-lookup normally. */
+ if (template_keyword_p
+ && (!parser->scope
+ || (TYPE_P (parser->scope)
+ && dependent_type_p (parser->scope))))
+ return identifier;
+ }
+
+ /* Look up the name. */
+ decl = cp_parser_lookup_name (parser, identifier,
+ /*is_type=*/false,
+ /*is_template=*/false,
+ /*is_namespace=*/false,
+ check_dependency_p);
+ decl = maybe_get_template_decl_from_type_decl (decl);
+
+ /* If DECL is a template, then the name was a template-name. */
+ if (TREE_CODE (decl) == TEMPLATE_DECL)
+ ;
+ else
+ {
+ /* The standard does not explicitly indicate whether a name that
+ names a set of overloaded declarations, some of which are
+ templates, is a template-name. However, such a name should
+ be a template-name; otherwise, there is no way to form a
+ template-id for the overloaded templates. */
+ fns = BASELINK_P (decl) ? BASELINK_FUNCTIONS (decl) : decl;
+ if (TREE_CODE (fns) == OVERLOAD)
+ {
+ tree fn;
+
+ for (fn = fns; fn; fn = OVL_NEXT (fn))
+ if (TREE_CODE (OVL_CURRENT (fn)) == TEMPLATE_DECL)
+ break;
+ }
+ else
+ {
+ /* Otherwise, the name does not name a template. */
+ cp_parser_error (parser, "expected template-name");
+ return error_mark_node;
+ }
+ }
+
+ /* If DECL is dependent, and refers to a function, then just return
+ its name; we will look it up again during template instantiation. */
+ if (DECL_FUNCTION_TEMPLATE_P (decl) || !DECL_P (decl))
+ {
+ tree scope = CP_DECL_CONTEXT (get_first_fn (decl));
+ if (TYPE_P (scope) && dependent_type_p (scope))
+ return identifier;
+ }
+
+ return decl;
+}
+
+/* Parse a template-argument-list.
+
+ template-argument-list:
+ template-argument
+ template-argument-list , template-argument
+
+ Returns a TREE_VEC containing the arguments. */
+
+static tree
+cp_parser_template_argument_list (cp_parser* parser)
+{
+ tree fixed_args[10];
+ unsigned n_args = 0;
+ unsigned alloced = 10;
+ tree *arg_ary = fixed_args;
+ tree vec;
+ bool saved_in_template_argument_list_p;
+
+ saved_in_template_argument_list_p = parser->in_template_argument_list_p;
+ parser->in_template_argument_list_p = true;
+ do
+ {
+ tree argument;
+
+ if (n_args)
+ /* Consume the comma. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Parse the template-argument. */
+ argument = cp_parser_template_argument (parser);
+ if (n_args == alloced)
+ {
+ alloced *= 2;
+
+ if (arg_ary == fixed_args)
+ {
+ arg_ary = xmalloc (sizeof (tree) * alloced);
+ memcpy (arg_ary, fixed_args, sizeof (tree) * n_args);
+ }
+ else
+ arg_ary = xrealloc (arg_ary, sizeof (tree) * alloced);
+ }
+ arg_ary[n_args++] = argument;
+ }
+ while (cp_lexer_next_token_is (parser->lexer, CPP_COMMA));
+
+ vec = make_tree_vec (n_args);
+
+ while (n_args--)
+ TREE_VEC_ELT (vec, n_args) = arg_ary[n_args];
+
+ if (arg_ary != fixed_args)
+ free (arg_ary);
+ parser->in_template_argument_list_p = saved_in_template_argument_list_p;
+ return vec;
+}
+
+/* Parse a template-argument.
+
+ template-argument:
+ assignment-expression
+ type-id
+ id-expression
+
+ The representation is that of an assignment-expression, type-id, or
+ id-expression -- except that the qualified id-expression is
+ evaluated, so that the value returned is either a DECL or an
+ OVERLOAD.
+
+ Although the standard says "assignment-expression", it forbids
+ throw-expressions or assignments in the template argument.
+ Therefore, we use "conditional-expression" instead. */
+
+static tree
+cp_parser_template_argument (cp_parser* parser)
+{
+ tree argument;
+ bool template_p;
+ bool address_p;
+ bool maybe_type_id = false;
+ cp_token *token;
+ cp_id_kind idk;
+ tree qualifying_class;
+
+ /* There's really no way to know what we're looking at, so we just
+ try each alternative in order.
+
+ [temp.arg]
+
+ In a template-argument, an ambiguity between a type-id and an
+ expression is resolved to a type-id, regardless of the form of
+ the corresponding template-parameter.
+
+ Therefore, we try a type-id first. */
+ cp_parser_parse_tentatively (parser);
+ argument = cp_parser_type_id (parser);
+ /* If there was no error parsing the type-id but the next token is a '>>',
+ we probably found a typo for '> >'. But there are type-id which are
+ also valid expressions. For instance:
+
+ struct X { int operator >> (int); };
+ template <int V> struct Foo {};
+ Foo<X () >> 5> r;
+
+ Here 'X()' is a valid type-id of a function type, but the user just
+ wanted to write the expression "X() >> 5". Thus, we remember that we
+ found a valid type-id, but we still try to parse the argument as an
+ expression to see what happens. */
+ if (!cp_parser_error_occurred (parser)
+ && cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT))
+ {
+ maybe_type_id = true;
+ cp_parser_abort_tentative_parse (parser);
+ }
+ else
+ {
+ /* If the next token isn't a `,' or a `>', then this argument wasn't
+ really finished. This means that the argument is not a valid
+ type-id. */
+ if (!cp_parser_next_token_ends_template_argument_p (parser))
+ cp_parser_error (parser, "expected template-argument");
+ /* If that worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ return argument;
+ }
+ /* We're still not sure what the argument will be. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a template. */
+ argument = cp_parser_id_expression (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ &template_p,
+ /*declarator_p=*/false);
+ /* If the next token isn't a `,' or a `>', then this argument wasn't
+ really finished. */
+ if (!cp_parser_next_token_ends_template_argument_p (parser))
+ cp_parser_error (parser, "expected template-argument");
+ if (!cp_parser_error_occurred (parser))
+ {
+ /* Figure out what is being referred to. If the id-expression
+ was for a class template specialization, then we will have a
+ TYPE_DECL at this point. There is no need to do name lookup
+ at this point in that case. */
+ if (TREE_CODE (argument) != TYPE_DECL)
+ argument = cp_parser_lookup_name (parser, argument,
+ /*is_type=*/false,
+ /*is_template=*/template_p,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true);
+ if (TREE_CODE (argument) != TEMPLATE_DECL
+ && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
+ cp_parser_error (parser, "expected template-name");
+ }
+ if (cp_parser_parse_definitely (parser))
+ return argument;
+ /* It must be a non-type argument. There permitted cases are given
+ in [temp.arg.nontype]:
+
+ -- an integral constant-expression of integral or enumeration
+ type; or
+
+ -- the name of a non-type template-parameter; or
+
+ -- the name of an object or function with external linkage...
+
+ -- the address of an object or function with external linkage...
+
+ -- a pointer to member... */
+ /* Look for a non-type template parameter. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ cp_parser_parse_tentatively (parser);
+ argument = cp_parser_primary_expression (parser,
+ &idk,
+ &qualifying_class);
+ if (TREE_CODE (argument) != TEMPLATE_PARM_INDEX
+ || !cp_parser_next_token_ends_template_argument_p (parser))
+ cp_parser_simulate_error (parser);
+ if (cp_parser_parse_definitely (parser))
+ return argument;
+ }
+ /* If the next token is "&", the argument must be the address of an
+ object or function with external linkage. */
+ address_p = cp_lexer_next_token_is (parser->lexer, CPP_AND);
+ if (address_p)
+ cp_lexer_consume_token (parser->lexer);
+ /* See if we might have an id-expression. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_NAME
+ || token->keyword == RID_OPERATOR
+ || token->type == CPP_SCOPE
+ || token->type == CPP_TEMPLATE_ID
+ || token->type == CPP_NESTED_NAME_SPECIFIER)
+ {
+ cp_parser_parse_tentatively (parser);
+ argument = cp_parser_primary_expression (parser,
+ &idk,
+ &qualifying_class);
+ if (cp_parser_error_occurred (parser)
+ || !cp_parser_next_token_ends_template_argument_p (parser))
+ cp_parser_abort_tentative_parse (parser);
+ else
+ {
+ if (qualifying_class)
+ argument = finish_qualified_id_expr (qualifying_class,
+ argument,
+ /*done=*/true,
+ address_p);
+ if (TREE_CODE (argument) == VAR_DECL)
+ {
+ /* A variable without external linkage might still be a
+ valid constant-expression, so no error is issued here
+ if the external-linkage check fails. */
+ if (!DECL_EXTERNAL_LINKAGE_P (argument))
+ cp_parser_simulate_error (parser);
+ }
+ else if (is_overloaded_fn (argument))
+ /* All overloaded functions are allowed; if the external
+ linkage test does not pass, an error will be issued
+ later. */
+ ;
+ else if (address_p
+ && (TREE_CODE (argument) == OFFSET_REF
+ || TREE_CODE (argument) == SCOPE_REF))
+ /* A pointer-to-member. */
+ ;
+ else
+ cp_parser_simulate_error (parser);
+
+ if (cp_parser_parse_definitely (parser))
+ {
+ if (address_p)
+ argument = build_x_unary_op (ADDR_EXPR, argument);
+ return argument;
+ }
+ }
+ }
+ /* If the argument started with "&", there are no other valid
+ alternatives at this point. */
+ if (address_p)
+ {
+ cp_parser_error (parser, "invalid non-type template argument");
+ return error_mark_node;
+ }
+ /* If the argument wasn't successfully parsed as a type-id followed
+ by '>>', the argument can only be a constant expression now.
+ Otherwise, we try parsing the constant-expression tentatively,
+ because the argument could really be a type-id. */
+ if (maybe_type_id)
+ cp_parser_parse_tentatively (parser);
+ argument = cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/false,
+ /*non_constant_p=*/NULL);
+ argument = fold_non_dependent_expr (argument);
+ if (!maybe_type_id)
+ return argument;
+ if (!cp_parser_next_token_ends_template_argument_p (parser))
+ cp_parser_error (parser, "expected template-argument");
+ if (cp_parser_parse_definitely (parser))
+ return argument;
+ /* We did our best to parse the argument as a non type-id, but that
+ was the only alternative that matched (albeit with a '>' after
+ it). We can assume it's just a typo from the user, and a
+ diagnostic will then be issued. */
+ return cp_parser_type_id (parser);
+}
+
+/* Parse an explicit-instantiation.
+
+ explicit-instantiation:
+ template declaration
+
+ Although the standard says `declaration', what it really means is:
+
+ explicit-instantiation:
+ template decl-specifier-seq [opt] declarator [opt] ;
+
+ Things like `template int S<int>::i = 5, int S<double>::j;' are not
+ supposed to be allowed. A defect report has been filed about this
+ issue.
+
+ GNU Extension:
+
+ explicit-instantiation:
+ storage-class-specifier template
+ decl-specifier-seq [opt] declarator [opt] ;
+ function-specifier template
+ decl-specifier-seq [opt] declarator [opt] ; */
+
+static void
+cp_parser_explicit_instantiation (cp_parser* parser)
+{
+ int declares_class_or_enum;
+ tree decl_specifiers;
+ tree attributes;
+ tree extension_specifier = NULL_TREE;
+
+ /* Look for an (optional) storage-class-specifier or
+ function-specifier. */
+ if (cp_parser_allow_gnu_extensions_p (parser))
+ {
+ extension_specifier
+ = cp_parser_storage_class_specifier_opt (parser);
+ if (!extension_specifier)
+ extension_specifier = cp_parser_function_specifier_opt (parser);
+ }
+
+ /* Look for the `template' keyword. */
+ cp_parser_require_keyword (parser, RID_TEMPLATE, "`template'");
+ /* Let the front end know that we are processing an explicit
+ instantiation. */
+ begin_explicit_instantiation ();
+ /* [temp.explicit] says that we are supposed to ignore access
+ control while processing explicit instantiation directives. */
+ push_deferring_access_checks (dk_no_check);
+ /* Parse a decl-specifier-seq. */
+ decl_specifiers
+ = cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_OPTIONAL,
+ &attributes,
+ &declares_class_or_enum);
+ /* If there was exactly one decl-specifier, and it declared a class,
+ and there's no declarator, then we have an explicit type
+ instantiation. */
+ if (declares_class_or_enum && cp_parser_declares_only_class_p (parser))
+ {
+ tree type;
+
+ type = check_tag_decl (decl_specifiers);
+ /* Turn access control back on for names used during
+ template instantiation. */
+ pop_deferring_access_checks ();
+ if (type)
+ do_type_instantiation (type, extension_specifier, /*complain=*/1);
+ }
+ else
+ {
+ tree declarator;
+ tree decl;
+
+ /* Parse the declarator. */
+ declarator
+ = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+ /*ctor_dtor_or_conv_p=*/NULL,
+ /*parenthesized_p=*/NULL);
+ cp_parser_check_for_definition_in_return_type (declarator,
+ declares_class_or_enum);
+ if (declarator != error_mark_node)
+ {
+ decl = grokdeclarator (declarator, decl_specifiers,
+ NORMAL, 0, NULL);
+ /* Turn access control back on for names used during
+ template instantiation. */
+ pop_deferring_access_checks ();
+ /* Do the explicit instantiation. */
+ do_decl_instantiation (decl, extension_specifier);
+ }
+ else
+ {
+ pop_deferring_access_checks ();
+ /* Skip the body of the explicit instantiation. */
+ cp_parser_skip_to_end_of_statement (parser);
+ }
+ }
+ /* We're done with the instantiation. */
+ end_explicit_instantiation ();
+
+ cp_parser_consume_semicolon_at_end_of_statement (parser);
+}
+
+/* Parse an explicit-specialization.
+
+ explicit-specialization:
+ template < > declaration
+
+ Although the standard says `declaration', what it really means is:
+
+ explicit-specialization:
+ template <> decl-specifier [opt] init-declarator [opt] ;
+ template <> function-definition
+ template <> explicit-specialization
+ template <> template-declaration */
+
+static void
+cp_parser_explicit_specialization (cp_parser* parser)
+{
+ /* Look for the `template' keyword. */
+ cp_parser_require_keyword (parser, RID_TEMPLATE, "`template'");
+ /* Look for the `<'. */
+ cp_parser_require (parser, CPP_LESS, "`<'");
+ /* Look for the `>'. */
+ cp_parser_require (parser, CPP_GREATER, "`>'");
+ /* We have processed another parameter list. */
+ ++parser->num_template_parameter_lists;
+ /* Let the front end know that we are beginning a specialization. */
+ begin_specialization ();
+
+ /* If the next keyword is `template', we need to figure out whether
+ or not we're looking a template-declaration. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
+ {
+ if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_LESS
+ && cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_GREATER)
+ cp_parser_template_declaration_after_export (parser,
+ /*member_p=*/false);
+ else
+ cp_parser_explicit_specialization (parser);
+ }
+ else
+ /* Parse the dependent declaration. */
+ cp_parser_single_declaration (parser,
+ /*member_p=*/false,
+ /*friend_p=*/NULL);
+
+ /* We're done with the specialization. */
+ end_specialization ();
+ /* We're done with this parameter list. */
+ --parser->num_template_parameter_lists;
+}
+
+/* Parse a type-specifier.
+
+ type-specifier:
+ simple-type-specifier
+ class-specifier
+ enum-specifier
+ elaborated-type-specifier
+ cv-qualifier
+
+ GNU Extension:
+
+ type-specifier:
+ __complex__
+
+ Returns a representation of the type-specifier. If the
+ type-specifier is a keyword (like `int' or `const', or
+ `__complex__') then the corresponding IDENTIFIER_NODE is returned.
+ For a class-specifier, enum-specifier, or elaborated-type-specifier
+ a TREE_TYPE is returned; otherwise, a TYPE_DECL is returned.
+
+ If IS_FRIEND is TRUE then this type-specifier is being declared a
+ `friend'. If IS_DECLARATION is TRUE, then this type-specifier is
+ appearing in a decl-specifier-seq.
+
+ If DECLARES_CLASS_OR_ENUM is non-NULL, and the type-specifier is a
+ class-specifier, enum-specifier, or elaborated-type-specifier, then
+ *DECLARES_CLASS_OR_ENUM is set to a nonzero value. The value is 1
+ if a type is declared; 2 if it is defined. Otherwise, it is set to
+ zero.
+
+ If IS_CV_QUALIFIER is non-NULL, and the type-specifier is a
+ cv-qualifier, then IS_CV_QUALIFIER is set to TRUE. Otherwise, it
+ is set to FALSE. */
+
+static tree
+cp_parser_type_specifier (cp_parser* parser,
+ cp_parser_flags flags,
+ bool is_friend,
+ bool is_declaration,
+ int* declares_class_or_enum,
+ bool* is_cv_qualifier)
+{
+ tree type_spec = NULL_TREE;
+ cp_token *token;
+ enum rid keyword;
+
+ /* Assume this type-specifier does not declare a new type. */
+ if (declares_class_or_enum)
+ *declares_class_or_enum = 0;
+ /* And that it does not specify a cv-qualifier. */
+ if (is_cv_qualifier)
+ *is_cv_qualifier = false;
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* If we're looking at a keyword, we can use that to guide the
+ production we choose. */
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ /* Any of these indicate either a class-specifier, or an
+ elaborated-type-specifier. */
+ case RID_CLASS:
+ case RID_STRUCT:
+ case RID_UNION:
+ case RID_ENUM:
+ /* Parse tentatively so that we can back up if we don't find a
+ class-specifier or enum-specifier. */
+ cp_parser_parse_tentatively (parser);
+ /* Look for the class-specifier or enum-specifier. */
+ if (keyword == RID_ENUM)
+ type_spec = cp_parser_enum_specifier (parser);
+ else
+ type_spec = cp_parser_class_specifier (parser);
+
+ /* If that worked, we're done. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ if (declares_class_or_enum)
+ *declares_class_or_enum = 2;
+ return type_spec;
+ }
+
+ /* Fall through. */
+
+ case RID_TYPENAME:
+ /* Look for an elaborated-type-specifier. */
+ type_spec = cp_parser_elaborated_type_specifier (parser,
+ is_friend,
+ is_declaration);
+ /* We're declaring a class or enum -- unless we're using
+ `typename'. */
+ if (declares_class_or_enum && keyword != RID_TYPENAME)
+ *declares_class_or_enum = 1;
+ return type_spec;
+
+ case RID_CONST:
+ case RID_VOLATILE:
+ case RID_RESTRICT:
+ type_spec = cp_parser_cv_qualifier_opt (parser);
+ /* Even though we call a routine that looks for an optional
+ qualifier, we know that there should be one. */
+ my_friendly_assert (type_spec != NULL, 20000328);
+ /* This type-specifier was a cv-qualified. */
+ if (is_cv_qualifier)
+ *is_cv_qualifier = true;
+
+ return type_spec;
+
+ case RID_COMPLEX:
+ /* The `__complex__' keyword is a GNU extension. */
+ return cp_lexer_consume_token (parser->lexer)->value;
+
+ default:
+ break;
+ }
+
+ /* If we do not already have a type-specifier, assume we are looking
+ at a simple-type-specifier. */
+ type_spec = cp_parser_simple_type_specifier (parser, flags,
+ /*identifier_p=*/true);
+
+ /* If we didn't find a type-specifier, and a type-specifier was not
+ optional in this context, issue an error message. */
+ if (!type_spec && !(flags & CP_PARSER_FLAGS_OPTIONAL))
+ {
+ cp_parser_error (parser, "expected type specifier");
+ return error_mark_node;
+ }
+
+ return type_spec;
+}
+
+/* Parse a simple-type-specifier.
+
+ simple-type-specifier:
+ :: [opt] nested-name-specifier [opt] type-name
+ :: [opt] nested-name-specifier template template-id
+ char
+ wchar_t
+ bool
+ short
+ int
+ long
+ signed
+ unsigned
+ float
+ double
+ void
+
+ GNU Extension:
+
+ simple-type-specifier:
+ __typeof__ unary-expression
+ __typeof__ ( type-id )
+
+ For the various keywords, the value returned is simply the
+ TREE_IDENTIFIER representing the keyword if IDENTIFIER_P is true.
+ For the first two productions, and if IDENTIFIER_P is false, the
+ value returned is the indicated TYPE_DECL. */
+
+static tree
+cp_parser_simple_type_specifier (cp_parser* parser, cp_parser_flags flags,
+ bool identifier_p)
+{
+ tree type = NULL_TREE;
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* If we're looking at a keyword, things are easy. */
+ switch (token->keyword)
+ {
+ case RID_CHAR:
+ type = char_type_node;
+ break;
+ case RID_WCHAR:
+ type = wchar_type_node;
+ break;
+ case RID_BOOL:
+ type = boolean_type_node;
+ break;
+ case RID_SHORT:
+ type = short_integer_type_node;
+ break;
+ case RID_INT:
+ type = integer_type_node;
+ break;
+ case RID_LONG:
+ type = long_integer_type_node;
+ break;
+ case RID_SIGNED:
+ type = integer_type_node;
+ break;
+ case RID_UNSIGNED:
+ type = unsigned_type_node;
+ break;
+ case RID_FLOAT:
+ type = float_type_node;
+ break;
+ case RID_DOUBLE:
+ type = double_type_node;
+ break;
+ case RID_VOID:
+ type = void_type_node;
+ break;
+
+ case RID_TYPEOF:
+ {
+ tree operand;
+
+ /* Consume the `typeof' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the operand to `typeof'. */
+ operand = cp_parser_sizeof_operand (parser, RID_TYPEOF);
+ /* If it is not already a TYPE, take its type. */
+ if (!TYPE_P (operand))
+ operand = finish_typeof (operand);
+
+ return operand;
+ }
+
+ default:
+ break;
+ }
+
+ /* If the type-specifier was for a built-in type, we're done. */
+ if (type)
+ {
+ tree id;
+
+ /* Consume the token. */
+ id = cp_lexer_consume_token (parser->lexer)->value;
+
+ /* There is no valid C++ program where a non-template type is
+ followed by a "<". That usually indicates that the user thought
+ that the type was a template. */
+ cp_parser_check_for_invalid_template_id (parser, type);
+
+ return identifier_p ? id : TYPE_NAME (type);
+ }
+
+ /* The type-specifier must be a user-defined type. */
+ if (!(flags & CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES))
+ {
+ bool qualified_p;
+ bool global_p;
+
+ /* Don't gobble tokens or issue error messages if this is an
+ optional type-specifier. */
+ if (flags & CP_PARSER_FLAGS_OPTIONAL)
+ cp_parser_parse_tentatively (parser);
+
+ /* Look for the optional `::' operator. */
+ global_p
+ = (cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false)
+ != NULL_TREE);
+ /* Look for the nested-name specifier. */
+ qualified_p
+ = (cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/false)
+ != NULL_TREE);
+ /* If we have seen a nested-name-specifier, and the next token
+ is `template', then we are using the template-id production. */
+ if (parser->scope
+ && cp_parser_optional_template_keyword (parser))
+ {
+ /* Look for the template-id. */
+ type = cp_parser_template_id (parser,
+ /*template_keyword_p=*/true,
+ /*check_dependency_p=*/true,
+ /*is_declaration=*/false);
+ /* If the template-id did not name a type, we are out of
+ luck. */
+ if (TREE_CODE (type) != TYPE_DECL)
+ {
+ cp_parser_error (parser, "expected template-id for type");
+ type = NULL_TREE;
+ }
+ }
+ /* Otherwise, look for a type-name. */
+ else
+ type = cp_parser_type_name (parser);
+ /* Keep track of all name-lookups performed in class scopes. */
+ if (type
+ && !global_p
+ && !qualified_p
+ && TREE_CODE (type) == TYPE_DECL
+ && TREE_CODE (DECL_NAME (type)) == IDENTIFIER_NODE)
+ maybe_note_name_used_in_class (DECL_NAME (type), type);
+ /* If it didn't work out, we don't have a TYPE. */
+ if ((flags & CP_PARSER_FLAGS_OPTIONAL)
+ && !cp_parser_parse_definitely (parser))
+ type = NULL_TREE;
+ }
+
+ /* If we didn't get a type-name, issue an error message. */
+ if (!type && !(flags & CP_PARSER_FLAGS_OPTIONAL))
+ {
+ cp_parser_error (parser, "expected type-name");
+ return error_mark_node;
+ }
+
+ /* There is no valid C++ program where a non-template type is
+ followed by a "<". That usually indicates that the user thought
+ that the type was a template. */
+ if (type && type != error_mark_node)
+ cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type));
+
+ return type;
+}
+
+/* Parse a type-name.
+
+ type-name:
+ class-name
+ enum-name
+ typedef-name
+
+ enum-name:
+ identifier
+
+ typedef-name:
+ identifier
+
+ Returns a TYPE_DECL for the the type. */
+
+static tree
+cp_parser_type_name (cp_parser* parser)
+{
+ tree type_decl;
+ tree identifier;
+
+ /* We can't know yet whether it is a class-name or not. */
+ cp_parser_parse_tentatively (parser);
+ /* Try a class-name. */
+ type_decl = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ /*type_p=*/false,
+ /*check_dependency_p=*/true,
+ /*class_head_p=*/false,
+ /*is_declaration=*/false);
+ /* If it's not a class-name, keep looking. */
+ if (!cp_parser_parse_definitely (parser))
+ {
+ /* It must be a typedef-name or an enum-name. */
+ identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ return error_mark_node;
+
+ /* Look up the type-name. */
+ type_decl = cp_parser_lookup_name_simple (parser, identifier);
+ /* Issue an error if we did not find a type-name. */
+ if (TREE_CODE (type_decl) != TYPE_DECL)
+ {
+ if (!cp_parser_simulate_error (parser))
+ cp_parser_name_lookup_error (parser, identifier, type_decl,
+ "is not a type");
+ type_decl = error_mark_node;
+ }
+ /* Remember that the name was used in the definition of the
+ current class so that we can check later to see if the
+ meaning would have been different after the class was
+ entirely defined. */
+ else if (type_decl != error_mark_node
+ && !parser->scope)
+ maybe_note_name_used_in_class (identifier, type_decl);
+ }
+
+ return type_decl;
+}
+
+
+/* Parse an elaborated-type-specifier. Note that the grammar given
+ here incorporates the resolution to DR68.
+
+ elaborated-type-specifier:
+ class-key :: [opt] nested-name-specifier [opt] identifier
+ class-key :: [opt] nested-name-specifier [opt] template [opt] template-id
+ enum :: [opt] nested-name-specifier [opt] identifier
+ typename :: [opt] nested-name-specifier identifier
+ typename :: [opt] nested-name-specifier template [opt]
+ template-id
+
+ GNU extension:
+
+ elaborated-type-specifier:
+ class-key attributes :: [opt] nested-name-specifier [opt] identifier
+ class-key attributes :: [opt] nested-name-specifier [opt]
+ template [opt] template-id
+ enum attributes :: [opt] nested-name-specifier [opt] identifier
+
+ If IS_FRIEND is TRUE, then this elaborated-type-specifier is being
+ declared `friend'. If IS_DECLARATION is TRUE, then this
+ elaborated-type-specifier appears in a decl-specifiers-seq, i.e.,
+ something is being declared.
+
+ Returns the TYPE specified. */
+
+static tree
+cp_parser_elaborated_type_specifier (cp_parser* parser,
+ bool is_friend,
+ bool is_declaration)
+{
+ enum tag_types tag_type;
+ tree identifier;
+ tree type = NULL_TREE;
+ tree attributes = NULL_TREE;
+
+ /* See if we're looking at the `enum' keyword. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM))
+ {
+ /* Consume the `enum' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Remember that it's an enumeration type. */
+ tag_type = enum_type;
+ /* Parse the attributes. */
+ attributes = cp_parser_attributes_opt (parser);
+ }
+ /* Or, it might be `typename'. */
+ else if (cp_lexer_next_token_is_keyword (parser->lexer,
+ RID_TYPENAME))
+ {
+ /* Consume the `typename' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Remember that it's a `typename' type. */
+ tag_type = typename_type;
+ /* The `typename' keyword is only allowed in templates. */
+ if (!processing_template_decl)
+ pedwarn ("using `typename' outside of template");
+ }
+ /* Otherwise it must be a class-key. */
+ else
+ {
+ tag_type = cp_parser_class_key (parser);
+ if (tag_type == none_type)
+ return error_mark_node;
+ /* Parse the attributes. */
+ attributes = cp_parser_attributes_opt (parser);
+ }
+
+ /* Look for the `::' operator. */
+ cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false);
+ /* Look for the nested-name-specifier. */
+ if (tag_type == typename_type)
+ {
+ if (cp_parser_nested_name_specifier (parser,
+ /*typename_keyword_p=*/true,
+ /*check_dependency_p=*/true,
+ /*type_p=*/true,
+ is_declaration)
+ == error_mark_node)
+ return error_mark_node;
+ }
+ else
+ /* Even though `typename' is not present, the proposed resolution
+ to Core Issue 180 says that in `class A<T>::B', `B' should be
+ considered a type-name, even if `A<T>' is dependent. */
+ cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/true,
+ /*check_dependency_p=*/true,
+ /*type_p=*/true,
+ is_declaration);
+ /* For everything but enumeration types, consider a template-id. */
+ if (tag_type != enum_type)
+ {
+ bool template_p = false;
+ tree decl;
+
+ /* Allow the `template' keyword. */
+ template_p = cp_parser_optional_template_keyword (parser);
+ /* If we didn't see `template', we don't know if there's a
+ template-id or not. */
+ if (!template_p)
+ cp_parser_parse_tentatively (parser);
+ /* Parse the template-id. */
+ decl = cp_parser_template_id (parser, template_p,
+ /*check_dependency_p=*/true,
+ is_declaration);
+ /* If we didn't find a template-id, look for an ordinary
+ identifier. */
+ if (!template_p && !cp_parser_parse_definitely (parser))
+ ;
+ /* If DECL is a TEMPLATE_ID_EXPR, and the `typename' keyword is
+ in effect, then we must assume that, upon instantiation, the
+ template will correspond to a class. */
+ else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
+ && tag_type == typename_type)
+ type = make_typename_type (parser->scope, decl,
+ /*complain=*/1);
+ else
+ type = TREE_TYPE (decl);
+ }
+
+ /* For an enumeration type, consider only a plain identifier. */
+ if (!type)
+ {
+ identifier = cp_parser_identifier (parser);
+
+ if (identifier == error_mark_node)
+ {
+ parser->scope = NULL_TREE;
+ return error_mark_node;
+ }
+
+ /* For a `typename', we needn't call xref_tag. */
+ if (tag_type == typename_type)
+ return make_typename_type (parser->scope, identifier,
+ /*complain=*/1);
+ /* Look up a qualified name in the usual way. */
+ if (parser->scope)
+ {
+ tree decl;
+
+ /* In an elaborated-type-specifier, names are assumed to name
+ types, so we set IS_TYPE to TRUE when calling
+ cp_parser_lookup_name. */
+ decl = cp_parser_lookup_name (parser, identifier,
+ /*is_type=*/true,
+ /*is_template=*/false,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true);
+
+ /* If we are parsing friend declaration, DECL may be a
+ TEMPLATE_DECL tree node here. However, we need to check
+ whether this TEMPLATE_DECL results in valid code. Consider
+ the following example:
+
+ namespace N {
+ template <class T> class C {};
+ }
+ class X {
+ template <class T> friend class N::C; // #1, valid code
+ };
+ template <class T> class Y {
+ friend class N::C; // #2, invalid code
+ };
+
+ For both case #1 and #2, we arrive at a TEMPLATE_DECL after
+ name lookup of `N::C'. We see that friend declaration must
+ be template for the code to be valid. Note that
+ processing_template_decl does not work here since it is
+ always 1 for the above two cases. */
+
+ decl = (cp_parser_maybe_treat_template_as_class
+ (decl, /*tag_name_p=*/is_friend
+ && parser->num_template_parameter_lists));
+
+ if (TREE_CODE (decl) != TYPE_DECL)
+ {
+ error ("expected type-name");
+ return error_mark_node;
+ }
+
+ if (TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE)
+ check_elaborated_type_specifier
+ (tag_type, decl,
+ (parser->num_template_parameter_lists
+ || DECL_SELF_REFERENCE_P (decl)));
+
+ type = TREE_TYPE (decl);
+ }
+ else
+ {
+ /* An elaborated-type-specifier sometimes introduces a new type and
+ sometimes names an existing type. Normally, the rule is that it
+ introduces a new type only if there is not an existing type of
+ the same name already in scope. For example, given:
+
+ struct S {};
+ void f() { struct S s; }
+
+ the `struct S' in the body of `f' is the same `struct S' as in
+ the global scope; the existing definition is used. However, if
+ there were no global declaration, this would introduce a new
+ local class named `S'.
+
+ An exception to this rule applies to the following code:
+
+ namespace N { struct S; }
+
+ Here, the elaborated-type-specifier names a new type
+ unconditionally; even if there is already an `S' in the
+ containing scope this declaration names a new type.
+ This exception only applies if the elaborated-type-specifier
+ forms the complete declaration:
+
+ [class.name]
+
+ A declaration consisting solely of `class-key identifier ;' is
+ either a redeclaration of the name in the current scope or a
+ forward declaration of the identifier as a class name. It
+ introduces the name into the current scope.
+
+ We are in this situation precisely when the next token is a `;'.
+
+ An exception to the exception is that a `friend' declaration does
+ *not* name a new type; i.e., given:
+
+ struct S { friend struct T; };
+
+ `T' is not a new type in the scope of `S'.
+
+ Also, `new struct S' or `sizeof (struct S)' never results in the
+ definition of a new type; a new type can only be declared in a
+ declaration context. */
+
+ /* Warn about attributes. They are ignored. */
+ if (attributes)
+ warning ("type attributes are honored only at type definition");
+
+ type = xref_tag (tag_type, identifier,
+ (is_friend
+ || !is_declaration
+ || cp_lexer_next_token_is_not (parser->lexer,
+ CPP_SEMICOLON)),
+ parser->num_template_parameter_lists);
+ }
+ }
+ if (tag_type != enum_type)
+ cp_parser_check_class_key (tag_type, type);
+
+ /* A "<" cannot follow an elaborated type specifier. If that
+ happens, the user was probably trying to form a template-id. */
+ cp_parser_check_for_invalid_template_id (parser, type);
+
+ return type;
+}
+
+/* Parse an enum-specifier.
+
+ enum-specifier:
+ enum identifier [opt] { enumerator-list [opt] }
+
+ Returns an ENUM_TYPE representing the enumeration. */
+
+static tree
+cp_parser_enum_specifier (cp_parser* parser)
+{
+ cp_token *token;
+ tree identifier = NULL_TREE;
+ tree type;
+
+ /* Look for the `enum' keyword. */
+ if (!cp_parser_require_keyword (parser, RID_ENUM, "`enum'"))
+ return error_mark_node;
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* See if it is an identifier. */
+ if (token->type == CPP_NAME)
+ identifier = cp_parser_identifier (parser);
+
+ /* Look for the `{'. */
+ if (!cp_parser_require (parser, CPP_OPEN_BRACE, "`{'"))
+ return error_mark_node;
+
+ /* At this point, we're going ahead with the enum-specifier, even
+ if some other problem occurs. */
+ cp_parser_commit_to_tentative_parse (parser);
+
+ /* Issue an error message if type-definitions are forbidden here. */
+ cp_parser_check_type_definition (parser);
+
+ /* Create the new type. */
+ type = start_enum (identifier ? identifier : make_anon_name ());
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not a `}', then there are some enumerators. */
+ if (token->type != CPP_CLOSE_BRACE)
+ cp_parser_enumerator_list (parser, type);
+ /* Look for the `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, "`}'");
+
+ /* Finish up the enumeration. */
+ finish_enum (type);
+
+ return type;
+}
+
+/* Parse an enumerator-list. The enumerators all have the indicated
+ TYPE.
+
+ enumerator-list:
+ enumerator-definition
+ enumerator-list , enumerator-definition */
+
+static void
+cp_parser_enumerator_list (cp_parser* parser, tree type)
+{
+ while (true)
+ {
+ cp_token *token;
+
+ /* Parse an enumerator-definition. */
+ cp_parser_enumerator_definition (parser, type);
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not a `,', then we've reached the end of the
+ list. */
+ if (token->type != CPP_COMMA)
+ break;
+ /* Otherwise, consume the `,' and keep going. */
+ cp_lexer_consume_token (parser->lexer);
+ /* If the next token is a `}', there is a trailing comma. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
+ {
+ if (pedantic && !in_system_header)
+ pedwarn ("comma at end of enumerator list");
+ break;
+ }
+ }
+}
+
+/* Parse an enumerator-definition. The enumerator has the indicated
+ TYPE.
+
+ enumerator-definition:
+ enumerator
+ enumerator = constant-expression
+
+ enumerator:
+ identifier */
+
+static void
+cp_parser_enumerator_definition (cp_parser* parser, tree type)
+{
+ cp_token *token;
+ tree identifier;
+ tree value;
+
+ /* Look for the identifier. */
+ identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ return;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's an `=', then there's an explicit value. */
+ if (token->type == CPP_EQ)
+ {
+ /* Consume the `=' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the value. */
+ value = cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/false,
+ NULL);
+ }
+ else
+ value = NULL_TREE;
+
+ /* Create the enumerator. */
+ build_enumerator (identifier, value, type);
+}
+
+/* Parse a namespace-name.
+
+ namespace-name:
+ original-namespace-name
+ namespace-alias
+
+ Returns the NAMESPACE_DECL for the namespace. */
+
+static tree
+cp_parser_namespace_name (cp_parser* parser)
+{
+ tree identifier;
+ tree namespace_decl;
+
+ /* Get the name of the namespace. */
+ identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ return error_mark_node;
+
+ /* Look up the identifier in the currently active scope. Look only
+ for namespaces, due to:
+
+ [basic.lookup.udir]
+
+ When looking up a namespace-name in a using-directive or alias
+ definition, only namespace names are considered.
+
+ And:
+
+ [basic.lookup.qual]
+
+ During the lookup of a name preceding the :: scope resolution
+ operator, object, function, and enumerator names are ignored.
+
+ (Note that cp_parser_class_or_namespace_name only calls this
+ function if the token after the name is the scope resolution
+ operator.) */
+ namespace_decl = cp_parser_lookup_name (parser, identifier,
+ /*is_type=*/false,
+ /*is_template=*/false,
+ /*is_namespace=*/true,
+ /*check_dependency=*/true);
+ /* If it's not a namespace, issue an error. */
+ if (namespace_decl == error_mark_node
+ || TREE_CODE (namespace_decl) != NAMESPACE_DECL)
+ {
+ cp_parser_error (parser, "expected namespace-name");
+ namespace_decl = error_mark_node;
+ }
+
+ return namespace_decl;
+}
+
+/* Parse a namespace-definition.
+
+ namespace-definition:
+ named-namespace-definition
+ unnamed-namespace-definition
+
+ named-namespace-definition:
+ original-namespace-definition
+ extension-namespace-definition
+
+ original-namespace-definition:
+ namespace identifier { namespace-body }
+
+ extension-namespace-definition:
+ namespace original-namespace-name { namespace-body }
+
+ unnamed-namespace-definition:
+ namespace { namespace-body } */
+
+static void
+cp_parser_namespace_definition (cp_parser* parser)
+{
+ tree identifier;
+
+ /* Look for the `namespace' keyword. */
+ cp_parser_require_keyword (parser, RID_NAMESPACE, "`namespace'");
+
+ /* Get the name of the namespace. We do not attempt to distinguish
+ between an original-namespace-definition and an
+ extension-namespace-definition at this point. The semantic
+ analysis routines are responsible for that. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ identifier = cp_parser_identifier (parser);
+ else
+ identifier = NULL_TREE;
+
+ /* Look for the `{' to start the namespace. */
+ cp_parser_require (parser, CPP_OPEN_BRACE, "`{'");
+ /* Start the namespace. */
+ push_namespace (identifier);
+ /* Parse the body of the namespace. */
+ cp_parser_namespace_body (parser);
+ /* Finish the namespace. */
+ pop_namespace ();
+ /* Look for the final `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, "`}'");
+}
+
+/* Parse a namespace-body.
+
+ namespace-body:
+ declaration-seq [opt] */
+
+static void
+cp_parser_namespace_body (cp_parser* parser)
+{
+ cp_parser_declaration_seq_opt (parser);
+}
+
+/* Parse a namespace-alias-definition.
+
+ namespace-alias-definition:
+ namespace identifier = qualified-namespace-specifier ; */
+
+static void
+cp_parser_namespace_alias_definition (cp_parser* parser)
+{
+ tree identifier;
+ tree namespace_specifier;
+
+ /* Look for the `namespace' keyword. */
+ cp_parser_require_keyword (parser, RID_NAMESPACE, "`namespace'");
+ /* Look for the identifier. */
+ identifier = cp_parser_identifier (parser);
+ if (identifier == error_mark_node)
+ return;
+ /* Look for the `=' token. */
+ cp_parser_require (parser, CPP_EQ, "`='");
+ /* Look for the qualified-namespace-specifier. */
+ namespace_specifier
+ = cp_parser_qualified_namespace_specifier (parser);
+ /* Look for the `;' token. */
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+
+ /* Register the alias in the symbol table. */
+ do_namespace_alias (identifier, namespace_specifier);
+}
+
+/* Parse a qualified-namespace-specifier.
+
+ qualified-namespace-specifier:
+ :: [opt] nested-name-specifier [opt] namespace-name
+
+ Returns a NAMESPACE_DECL corresponding to the specified
+ namespace. */
+
+static tree
+cp_parser_qualified_namespace_specifier (cp_parser* parser)
+{
+ /* Look for the optional `::'. */
+ cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false);
+
+ /* Look for the optional nested-name-specifier. */
+ cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/true);
+
+ return cp_parser_namespace_name (parser);
+}
+
+/* Parse a using-declaration.
+
+ using-declaration:
+ using typename [opt] :: [opt] nested-name-specifier unqualified-id ;
+ using :: unqualified-id ; */
+
+static void
+cp_parser_using_declaration (cp_parser* parser)
+{
+ cp_token *token;
+ bool typename_p = false;
+ bool global_scope_p;
+ tree decl;
+ tree identifier;
+ tree scope;
+ tree qscope;
+
+ /* Look for the `using' keyword. */
+ cp_parser_require_keyword (parser, RID_USING, "`using'");
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* See if it's `typename'. */
+ if (token->keyword == RID_TYPENAME)
+ {
+ /* Remember that we've seen it. */
+ typename_p = true;
+ /* Consume the `typename' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ /* Look for the optional global scope qualification. */
+ global_scope_p
+ = (cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false)
+ != NULL_TREE);
+
+ /* If we saw `typename', or didn't see `::', then there must be a
+ nested-name-specifier present. */
+ if (typename_p || !global_scope_p)
+ qscope = cp_parser_nested_name_specifier (parser, typename_p,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/true);
+ /* Otherwise, we could be in either of the two productions. In that
+ case, treat the nested-name-specifier as optional. */
+ else
+ qscope = cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/true);
+ if (!qscope)
+ qscope = global_namespace;
+
+ /* Parse the unqualified-id. */
+ identifier = cp_parser_unqualified_id (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*declarator_p=*/true);
+
+ /* The function we call to handle a using-declaration is different
+ depending on what scope we are in. */
+ if (identifier == error_mark_node)
+ ;
+ else if (TREE_CODE (identifier) != IDENTIFIER_NODE
+ && TREE_CODE (identifier) != BIT_NOT_EXPR)
+ /* [namespace.udecl]
+
+ A using declaration shall not name a template-id. */
+ error ("a template-id may not appear in a using-declaration");
+ else
+ {
+ scope = current_scope ();
+ if (scope && TYPE_P (scope))
+ {
+ /* Create the USING_DECL. */
+ decl = do_class_using_decl (build_nt (SCOPE_REF,
+ parser->scope,
+ identifier));
+ /* Add it to the list of members in this class. */
+ finish_member_declaration (decl);
+ }
+ else
+ {
+ decl = cp_parser_lookup_name_simple (parser, identifier);
+ if (decl == error_mark_node)
+ cp_parser_name_lookup_error (parser, identifier, decl, NULL);
+ else if (scope)
+ do_local_using_decl (decl, qscope, identifier);
+ else
+ do_toplevel_using_decl (decl, qscope, identifier);
+ }
+ }
+
+ /* Look for the final `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+}
+
+/* Parse a using-directive.
+
+ using-directive:
+ using namespace :: [opt] nested-name-specifier [opt]
+ namespace-name ; */
+
+static void
+cp_parser_using_directive (cp_parser* parser)
+{
+ tree namespace_decl;
+ tree attribs;
+
+ /* Look for the `using' keyword. */
+ cp_parser_require_keyword (parser, RID_USING, "`using'");
+ /* And the `namespace' keyword. */
+ cp_parser_require_keyword (parser, RID_NAMESPACE, "`namespace'");
+ /* Look for the optional `::' operator. */
+ cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
+ /* And the optional nested-name-specifier. */
+ cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/true);
+ /* Get the namespace being used. */
+ namespace_decl = cp_parser_namespace_name (parser);
+ /* And any specified attributes. */
+ attribs = cp_parser_attributes_opt (parser);
+ /* Update the symbol table. */
+ parse_using_directive (namespace_decl, attribs);
+ /* Look for the final `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+}
+
+/* Parse an asm-definition.
+
+ asm-definition:
+ asm ( string-literal ) ;
+
+ GNU Extension:
+
+ asm-definition:
+ asm volatile [opt] ( string-literal ) ;
+ asm volatile [opt] ( string-literal : asm-operand-list [opt] ) ;
+ asm volatile [opt] ( string-literal : asm-operand-list [opt]
+ : asm-operand-list [opt] ) ;
+ asm volatile [opt] ( string-literal : asm-operand-list [opt]
+ : asm-operand-list [opt]
+ : asm-operand-list [opt] ) ; */
+
+static void
+cp_parser_asm_definition (cp_parser* parser)
+{
+ cp_token *token;
+ tree string;
+ tree outputs = NULL_TREE;
+ tree inputs = NULL_TREE;
+ tree clobbers = NULL_TREE;
+ tree asm_stmt;
+ bool volatile_p = false;
+ bool extended_p = false;
+
+ /* Look for the `asm' keyword. */
+ cp_parser_require_keyword (parser, RID_ASM, "`asm'");
+ /* See if the next token is `volatile'. */
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && cp_lexer_next_token_is_keyword (parser->lexer, RID_VOLATILE))
+ {
+ /* Remember that we saw the `volatile' keyword. */
+ volatile_p = true;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+ /* Look for the opening `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+ /* Look for the string. */
+ token = cp_parser_require (parser, CPP_STRING, "asm body");
+ if (!token)
+ return;
+ string = token->value;
+ /* If we're allowing GNU extensions, check for the extended assembly
+ syntax. Unfortunately, the `:' tokens need not be separated by
+ a space in C, and so, for compatibility, we tolerate that here
+ too. Doing that means that we have to treat the `::' operator as
+ two `:' tokens. */
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && at_function_scope_p ()
+ && (cp_lexer_next_token_is (parser->lexer, CPP_COLON)
+ || cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)))
+ {
+ bool inputs_p = false;
+ bool clobbers_p = false;
+
+ /* The extended syntax was used. */
+ extended_p = true;
+
+ /* Look for outputs. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ {
+ /* Consume the `:'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the output-operands. */
+ if (cp_lexer_next_token_is_not (parser->lexer,
+ CPP_COLON)
+ && cp_lexer_next_token_is_not (parser->lexer,
+ CPP_SCOPE)
+ && cp_lexer_next_token_is_not (parser->lexer,
+ CPP_CLOSE_PAREN))
+ outputs = cp_parser_asm_operand_list (parser);
+ }
+ /* If the next token is `::', there are no outputs, and the
+ next token is the beginning of the inputs. */
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+ {
+ /* Consume the `::' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* The inputs are coming next. */
+ inputs_p = true;
+ }
+
+ /* Look for inputs. */
+ if (inputs_p
+ || cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ {
+ if (!inputs_p)
+ /* Consume the `:'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the output-operands. */
+ if (cp_lexer_next_token_is_not (parser->lexer,
+ CPP_COLON)
+ && cp_lexer_next_token_is_not (parser->lexer,
+ CPP_SCOPE)
+ && cp_lexer_next_token_is_not (parser->lexer,
+ CPP_CLOSE_PAREN))
+ inputs = cp_parser_asm_operand_list (parser);
+ }
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+ /* The clobbers are coming next. */
+ clobbers_p = true;
+
+ /* Look for clobbers. */
+ if (clobbers_p
+ || cp_lexer_next_token_is (parser->lexer, CPP_COLON))
+ {
+ if (!clobbers_p)
+ /* Consume the `:'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the clobbers. */
+ if (cp_lexer_next_token_is_not (parser->lexer,
+ CPP_CLOSE_PAREN))
+ clobbers = cp_parser_asm_clobber_list (parser);
+ }
+ }
+ /* Look for the closing `)'. */
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'"))
+ cp_parser_skip_to_closing_parenthesis (parser, true, false,
+ /*consume_paren=*/true);
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+
+ /* Create the ASM_STMT. */
+ if (at_function_scope_p ())
+ {
+ asm_stmt =
+ finish_asm_stmt (volatile_p
+ ? ridpointers[(int) RID_VOLATILE] : NULL_TREE,
+ string, outputs, inputs, clobbers);
+ /* If the extended syntax was not used, mark the ASM_STMT. */
+ if (!extended_p)
+ ASM_INPUT_P (asm_stmt) = 1;
+ }
+ else
+ assemble_asm (string);
+}
+
+/* Declarators [gram.dcl.decl] */
+
+/* Parse an init-declarator.
+
+ init-declarator:
+ declarator initializer [opt]
+
+ GNU Extension:
+
+ init-declarator:
+ declarator asm-specification [opt] attributes [opt] initializer [opt]
+
+ function-definition:
+ decl-specifier-seq [opt] declarator ctor-initializer [opt]
+ function-body
+ decl-specifier-seq [opt] declarator function-try-block
+
+ GNU Extension:
+
+ function-definition:
+ __extension__ function-definition
+
+ The DECL_SPECIFIERS and PREFIX_ATTRIBUTES apply to this declarator.
+ Returns a representation of the entity declared. If MEMBER_P is TRUE,
+ then this declarator appears in a class scope. The new DECL created
+ by this declarator is returned.
+
+ If FUNCTION_DEFINITION_ALLOWED_P then we handle the declarator and
+ for a function-definition here as well. If the declarator is a
+ declarator for a function-definition, *FUNCTION_DEFINITION_P will
+ be TRUE upon return. By that point, the function-definition will
+ have been completely parsed.
+
+ FUNCTION_DEFINITION_P may be NULL if FUNCTION_DEFINITION_ALLOWED_P
+ is FALSE. */
+
+static tree
+cp_parser_init_declarator (cp_parser* parser,
+ tree decl_specifiers,
+ tree prefix_attributes,
+ bool function_definition_allowed_p,
+ bool member_p,
+ int declares_class_or_enum,
+ bool* function_definition_p)
+{
+ cp_token *token;
+ tree declarator;
+ tree attributes;
+ tree asm_specification;
+ tree initializer;
+ tree decl = NULL_TREE;
+ tree scope;
+ bool is_initialized;
+ bool is_parenthesized_init;
+ bool is_non_constant_init;
+ int ctor_dtor_or_conv_p;
+ bool friend_p;
+ bool pop_p = false;
+
+ /* Assume that this is not the declarator for a function
+ definition. */
+ if (function_definition_p)
+ *function_definition_p = false;
+
+ /* Defer access checks while parsing the declarator; we cannot know
+ what names are accessible until we know what is being
+ declared. */
+ resume_deferring_access_checks ();
+
+ /* Parse the declarator. */
+ declarator
+ = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+ &ctor_dtor_or_conv_p,
+ /*parenthesized_p=*/NULL);
+ /* Gather up the deferred checks. */
+ stop_deferring_access_checks ();
+
+ /* If the DECLARATOR was erroneous, there's no need to go
+ further. */
+ if (declarator == error_mark_node)
+ return error_mark_node;
+
+ cp_parser_check_for_definition_in_return_type (declarator,
+ declares_class_or_enum);
+
+ /* Figure out what scope the entity declared by the DECLARATOR is
+ located in. `grokdeclarator' sometimes changes the scope, so
+ we compute it now. */
+ scope = get_scope_of_declarator (declarator);
+
+ /* If we're allowing GNU extensions, look for an asm-specification
+ and attributes. */
+ if (cp_parser_allow_gnu_extensions_p (parser))
+ {
+ /* Look for an asm-specification. */
+ asm_specification = cp_parser_asm_specification_opt (parser);
+ /* And attributes. */
+ attributes = cp_parser_attributes_opt (parser);
+ }
+ else
+ {
+ asm_specification = NULL_TREE;
+ attributes = NULL_TREE;
+ }
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Check to see if the token indicates the start of a
+ function-definition. */
+ if (cp_parser_token_starts_function_definition_p (token))
+ {
+ if (!function_definition_allowed_p)
+ {
+ /* If a function-definition should not appear here, issue an
+ error message. */
+ cp_parser_error (parser,
+ "a function-definition is not allowed here");
+ return error_mark_node;
+ }
+ else
+ {
+ /* Neither attributes nor an asm-specification are allowed
+ on a function-definition. */
+ if (asm_specification)
+ error ("an asm-specification is not allowed on a function-definition");
+ if (attributes)
+ error ("attributes are not allowed on a function-definition");
+ /* This is a function-definition. */
+ *function_definition_p = true;
+
+ /* Parse the function definition. */
+ if (member_p)
+ decl = cp_parser_save_member_function_body (parser,
+ decl_specifiers,
+ declarator,
+ prefix_attributes);
+ else
+ decl
+ = (cp_parser_function_definition_from_specifiers_and_declarator
+ (parser, decl_specifiers, prefix_attributes, declarator));
+
+ return decl;
+ }
+ }
+
+ /* [dcl.dcl]
+
+ Only in function declarations for constructors, destructors, and
+ type conversions can the decl-specifier-seq be omitted.
+
+ We explicitly postpone this check past the point where we handle
+ function-definitions because we tolerate function-definitions
+ that are missing their return types in some modes. */
+ if (!decl_specifiers && ctor_dtor_or_conv_p <= 0)
+ {
+ cp_parser_error (parser,
+ "expected constructor, destructor, or type conversion");
+ return error_mark_node;
+ }
+
+ /* An `=' or an `(' indicates an initializer. */
+ is_initialized = (token->type == CPP_EQ
+ || token->type == CPP_OPEN_PAREN);
+ /* If the init-declarator isn't initialized and isn't followed by a
+ `,' or `;', it's not a valid init-declarator. */
+ if (!is_initialized
+ && token->type != CPP_COMMA
+ && token->type != CPP_SEMICOLON)
+ {
+ cp_parser_error (parser, "expected init-declarator");
+ return error_mark_node;
+ }
+
+ /* Because start_decl has side-effects, we should only call it if we
+ know we're going ahead. By this point, we know that we cannot
+ possibly be looking at any other construct. */
+ cp_parser_commit_to_tentative_parse (parser);
+
+ /* If the decl specifiers were bad, issue an error now that we're
+ sure this was intended to be a declarator. Then continue
+ declaring the variable(s), as int, to try to cut down on further
+ errors. */
+ if (decl_specifiers != NULL
+ && TREE_VALUE (decl_specifiers) == error_mark_node)
+ {
+ cp_parser_error (parser, "invalid type in declaration");
+ TREE_VALUE (decl_specifiers) = integer_type_node;
+ }
+
+ /* Check to see whether or not this declaration is a friend. */
+ friend_p = cp_parser_friend_p (decl_specifiers);
+
+ /* Check that the number of template-parameter-lists is OK. */
+ if (!cp_parser_check_declarator_template_parameters (parser, declarator))
+ return error_mark_node;
+
+ /* Enter the newly declared entry in the symbol table. If we're
+ processing a declaration in a class-specifier, we wait until
+ after processing the initializer. */
+ if (!member_p)
+ {
+ if (parser->in_unbraced_linkage_specification_p)
+ {
+ decl_specifiers = tree_cons (error_mark_node,
+ get_identifier ("extern"),
+ decl_specifiers);
+ have_extern_spec = false;
+ }
+ decl = start_decl (declarator, decl_specifiers,
+ is_initialized, attributes, prefix_attributes);
+ }
+
+ /* Enter the SCOPE. That way unqualified names appearing in the
+ initializer will be looked up in SCOPE. */
+ if (scope)
+ pop_p = push_scope (scope);
+
+ /* Perform deferred access control checks, now that we know in which
+ SCOPE the declared entity resides. */
+ if (!member_p && decl)
+ {
+ tree saved_current_function_decl = NULL_TREE;
+
+ /* If the entity being declared is a function, pretend that we
+ are in its scope. If it is a `friend', it may have access to
+ things that would not otherwise be accessible. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ saved_current_function_decl = current_function_decl;
+ current_function_decl = decl;
+ }
+
+ /* Perform the access control checks for the declarator and the
+ the decl-specifiers. */
+ perform_deferred_access_checks ();
+
+ /* Restore the saved value. */
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ current_function_decl = saved_current_function_decl;
+ }
+
+ /* Parse the initializer. */
+ if (is_initialized)
+ initializer = cp_parser_initializer (parser,
+ &is_parenthesized_init,
+ &is_non_constant_init);
+ else
+ {
+ initializer = NULL_TREE;
+ is_parenthesized_init = false;
+ is_non_constant_init = true;
+ }
+
+ /* The old parser allows attributes to appear after a parenthesized
+ initializer. Mark Mitchell proposed removing this functionality
+ on the GCC mailing lists on 2002-08-13. This parser accepts the
+ attributes -- but ignores them. */
+ if (cp_parser_allow_gnu_extensions_p (parser) && is_parenthesized_init)
+ if (cp_parser_attributes_opt (parser))
+ warning ("attributes after parenthesized initializer ignored");
+
+ /* Leave the SCOPE, now that we have processed the initializer. It
+ is important to do this before calling cp_finish_decl because it
+ makes decisions about whether to create DECL_STMTs or not based
+ on the current scope. */
+ if (pop_p)
+ pop_scope (scope);
+
+ /* For an in-class declaration, use `grokfield' to create the
+ declaration. */
+ if (member_p)
+ {
+ decl = grokfield (declarator, decl_specifiers,
+ initializer, /*asmspec=*/NULL_TREE,
+ /*attributes=*/NULL_TREE);
+ if (decl && TREE_CODE (decl) == FUNCTION_DECL)
+ cp_parser_save_default_args (parser, decl);
+ }
+
+ /* Finish processing the declaration. But, skip friend
+ declarations. */
+ if (!friend_p && decl)
+ cp_finish_decl (decl,
+ initializer,
+ asm_specification,
+ /* If the initializer is in parentheses, then this is
+ a direct-initialization, which means that an
+ `explicit' constructor is OK. Otherwise, an
+ `explicit' constructor cannot be used. */
+ ((is_parenthesized_init || !is_initialized)
+ ? 0 : LOOKUP_ONLYCONVERTING));
+
+ /* Remember whether or not variables were initialized by
+ constant-expressions. */
+ if (decl && TREE_CODE (decl) == VAR_DECL
+ && is_initialized && !is_non_constant_init)
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
+
+ return decl;
+}
+
+/* Parse a declarator.
+
+ declarator:
+ direct-declarator
+ ptr-operator declarator
+
+ abstract-declarator:
+ ptr-operator abstract-declarator [opt]
+ direct-abstract-declarator
+
+ GNU Extensions:
+
+ declarator:
+ attributes [opt] direct-declarator
+ attributes [opt] ptr-operator declarator
+
+ abstract-declarator:
+ attributes [opt] ptr-operator abstract-declarator [opt]
+ attributes [opt] direct-abstract-declarator
+
+ Returns a representation of the declarator. If the declarator has
+ the form `* declarator', then an INDIRECT_REF is returned, whose
+ only operand is the sub-declarator. Analogously, `& declarator' is
+ represented as an ADDR_EXPR. For `X::* declarator', a SCOPE_REF is
+ used. The first operand is the TYPE for `X'. The second operand
+ is an INDIRECT_REF whose operand is the sub-declarator.
+
+ Otherwise, the representation is as for a direct-declarator.
+
+ (It would be better to define a structure type to represent
+ declarators, rather than abusing `tree' nodes to represent
+ declarators. That would be much clearer and save some memory.
+ There is no reason for declarators to be garbage-collected, for
+ example; they are created during parser and no longer needed after
+ `grokdeclarator' has been called.)
+
+ For a ptr-operator that has the optional cv-qualifier-seq,
+ cv-qualifiers will be stored in the TREE_TYPE of the INDIRECT_REF
+ node.
+
+ If CTOR_DTOR_OR_CONV_P is not NULL, *CTOR_DTOR_OR_CONV_P is used to
+ detect constructor, destructor or conversion operators. It is set
+ to -1 if the declarator is a name, and +1 if it is a
+ function. Otherwise it is set to zero. Usually you just want to
+ test for >0, but internally the negative value is used.
+
+ (The reason for CTOR_DTOR_OR_CONV_P is that a declaration must have
+ a decl-specifier-seq unless it declares a constructor, destructor,
+ or conversion. It might seem that we could check this condition in
+ semantic analysis, rather than parsing, but that makes it difficult
+ to handle something like `f()'. We want to notice that there are
+ no decl-specifiers, and therefore realize that this is an
+ expression, not a declaration.)
+
+ If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff
+ the declarator is a direct-declarator of the form "(...)". */
+
+static tree
+cp_parser_declarator (cp_parser* parser,
+ cp_parser_declarator_kind dcl_kind,
+ int* ctor_dtor_or_conv_p,
+ bool* parenthesized_p)
+{
+ cp_token *token;
+ tree declarator;
+ enum tree_code code;
+ tree cv_qualifier_seq;
+ tree class_type;
+ tree attributes = NULL_TREE;
+
+ /* Assume this is not a constructor, destructor, or type-conversion
+ operator. */
+ if (ctor_dtor_or_conv_p)
+ *ctor_dtor_or_conv_p = 0;
+
+ if (cp_parser_allow_gnu_extensions_p (parser))
+ attributes = cp_parser_attributes_opt (parser);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* Check for the ptr-operator production. */
+ cp_parser_parse_tentatively (parser);
+ /* Parse the ptr-operator. */
+ code = cp_parser_ptr_operator (parser,
+ &class_type,
+ &cv_qualifier_seq);
+ /* If that worked, then we have a ptr-operator. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ /* If a ptr-operator was found, then this declarator was not
+ parenthesized. */
+ if (parenthesized_p)
+ *parenthesized_p = true;
+ /* The dependent declarator is optional if we are parsing an
+ abstract-declarator. */
+ if (dcl_kind != CP_PARSER_DECLARATOR_NAMED)
+ cp_parser_parse_tentatively (parser);
+
+ /* Parse the dependent declarator. */
+ declarator = cp_parser_declarator (parser, dcl_kind,
+ /*ctor_dtor_or_conv_p=*/NULL,
+ /*parenthesized_p=*/NULL);
+
+ /* If we are parsing an abstract-declarator, we must handle the
+ case where the dependent declarator is absent. */
+ if (dcl_kind != CP_PARSER_DECLARATOR_NAMED
+ && !cp_parser_parse_definitely (parser))
+ declarator = NULL_TREE;
+
+ /* Build the representation of the ptr-operator. */
+ if (code == INDIRECT_REF)
+ declarator = make_pointer_declarator (cv_qualifier_seq,
+ declarator);
+ else
+ declarator = make_reference_declarator (cv_qualifier_seq,
+ declarator);
+ /* Handle the pointer-to-member case. */
+ if (class_type)
+ declarator = build_nt (SCOPE_REF, class_type, declarator);
+ }
+ /* Everything else is a direct-declarator. */
+ else
+ {
+ if (parenthesized_p)
+ *parenthesized_p = cp_lexer_next_token_is (parser->lexer,
+ CPP_OPEN_PAREN);
+ declarator = cp_parser_direct_declarator (parser, dcl_kind,
+ ctor_dtor_or_conv_p);
+ }
+
+ if (attributes && declarator != error_mark_node)
+ declarator = tree_cons (attributes, declarator, NULL_TREE);
+
+ return declarator;
+}
+
+/* Parse a direct-declarator or direct-abstract-declarator.
+
+ direct-declarator:
+ declarator-id
+ direct-declarator ( parameter-declaration-clause )
+ cv-qualifier-seq [opt]
+ exception-specification [opt]
+ direct-declarator [ constant-expression [opt] ]
+ ( declarator )
+
+ direct-abstract-declarator:
+ direct-abstract-declarator [opt]
+ ( parameter-declaration-clause )
+ cv-qualifier-seq [opt]
+ exception-specification [opt]
+ direct-abstract-declarator [opt] [ constant-expression [opt] ]
+ ( abstract-declarator )
+
+ Returns a representation of the declarator. DCL_KIND is
+ CP_PARSER_DECLARATOR_ABSTRACT, if we are parsing a
+ direct-abstract-declarator. It is CP_PARSER_DECLARATOR_NAMED, if
+ we are parsing a direct-declarator. It is
+ CP_PARSER_DECLARATOR_EITHER, if we can accept either - in the case
+ of ambiguity we prefer an abstract declarator, as per
+ [dcl.ambig.res]. CTOR_DTOR_OR_CONV_P is as for
+ cp_parser_declarator.
+
+ For the declarator-id production, the representation is as for an
+ id-expression, except that a qualified name is represented as a
+ SCOPE_REF. A function-declarator is represented as a CALL_EXPR;
+ see the documentation of the FUNCTION_DECLARATOR_* macros for
+ information about how to find the various declarator components.
+ An array-declarator is represented as an ARRAY_REF. The
+ direct-declarator is the first operand; the constant-expression
+ indicating the size of the array is the second operand. */
+
+static tree
+cp_parser_direct_declarator (cp_parser* parser,
+ cp_parser_declarator_kind dcl_kind,
+ int* ctor_dtor_or_conv_p)
+{
+ cp_token *token;
+ tree declarator = NULL_TREE;
+ tree scope = NULL_TREE;
+ bool saved_default_arg_ok_p = parser->default_arg_ok_p;
+ bool saved_in_declarator_p = parser->in_declarator_p;
+ bool first = true;
+ bool pop_p = false;
+
+ while (true)
+ {
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_OPEN_PAREN)
+ {
+ /* This is either a parameter-declaration-clause, or a
+ parenthesized declarator. When we know we are parsing a
+ named declarator, it must be a parenthesized declarator
+ if FIRST is true. For instance, `(int)' is a
+ parameter-declaration-clause, with an omitted
+ direct-abstract-declarator. But `((*))', is a
+ parenthesized abstract declarator. Finally, when T is a
+ template parameter `(T)' is a
+ parameter-declaration-clause, and not a parenthesized
+ named declarator.
+
+ We first try and parse a parameter-declaration-clause,
+ and then try a nested declarator (if FIRST is true).
+
+ It is not an error for it not to be a
+ parameter-declaration-clause, even when FIRST is
+ false. Consider,
+
+ int i (int);
+ int i (3);
+
+ The first is the declaration of a function while the
+ second is a the definition of a variable, including its
+ initializer.
+
+ Having seen only the parenthesis, we cannot know which of
+ these two alternatives should be selected. Even more
+ complex are examples like:
+
+ int i (int (a));
+ int i (int (3));
+
+ The former is a function-declaration; the latter is a
+ variable initialization.
+
+ Thus again, we try a parameter-declaration-clause, and if
+ that fails, we back out and return. */
+
+ if (!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
+ {
+ tree params;
+ unsigned saved_num_template_parameter_lists;
+
+ cp_parser_parse_tentatively (parser);
+
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ if (first)
+ {
+ /* If this is going to be an abstract declarator, we're
+ in a declarator and we can't have default args. */
+ parser->default_arg_ok_p = false;
+ parser->in_declarator_p = true;
+ }
+
+ /* Inside the function parameter list, surrounding
+ template-parameter-lists do not apply. */
+ saved_num_template_parameter_lists
+ = parser->num_template_parameter_lists;
+ parser->num_template_parameter_lists = 0;
+
+ /* Parse the parameter-declaration-clause. */
+ params = cp_parser_parameter_declaration_clause (parser);
+
+ parser->num_template_parameter_lists
+ = saved_num_template_parameter_lists;
+
+ /* If all went well, parse the cv-qualifier-seq and the
+ exception-specification. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ tree cv_qualifiers;
+ tree exception_specification;
+
+ if (ctor_dtor_or_conv_p)
+ *ctor_dtor_or_conv_p = *ctor_dtor_or_conv_p < 0;
+ first = false;
+ /* Consume the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+
+ /* Parse the cv-qualifier-seq. */
+ cv_qualifiers = cp_parser_cv_qualifier_seq_opt (parser);
+ /* And the exception-specification. */
+ exception_specification
+ = cp_parser_exception_specification_opt (parser);
+
+ /* Create the function-declarator. */
+ declarator = make_call_declarator (declarator,
+ params,
+ cv_qualifiers,
+ exception_specification);
+ /* Any subsequent parameter lists are to do with
+ return type, so are not those of the declared
+ function. */
+ parser->default_arg_ok_p = false;
+
+ /* Repeat the main loop. */
+ continue;
+ }
+ }
+
+ /* If this is the first, we can try a parenthesized
+ declarator. */
+ if (first)
+ {
+ bool saved_in_type_id_in_expr_p;
+
+ parser->default_arg_ok_p = saved_default_arg_ok_p;
+ parser->in_declarator_p = saved_in_declarator_p;
+
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the nested declarator. */
+ saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+ parser->in_type_id_in_expr_p = true;
+ declarator
+ = cp_parser_declarator (parser, dcl_kind, ctor_dtor_or_conv_p,
+ /*parenthesized_p=*/NULL);
+ parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
+ first = false;
+ /* Expect a `)'. */
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'"))
+ declarator = error_mark_node;
+ if (declarator == error_mark_node)
+ break;
+
+ goto handle_declarator;
+ }
+ /* Otherwise, we must be done. */
+ else
+ break;
+ }
+ else if ((!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
+ && token->type == CPP_OPEN_SQUARE)
+ {
+ /* Parse an array-declarator. */
+ tree bounds;
+
+ if (ctor_dtor_or_conv_p)
+ *ctor_dtor_or_conv_p = 0;
+
+ first = false;
+ parser->default_arg_ok_p = false;
+ parser->in_declarator_p = true;
+ /* Consume the `['. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If the next token is `]', then there is no
+ constant-expression. */
+ if (token->type != CPP_CLOSE_SQUARE)
+ {
+ bool non_constant_p;
+
+ bounds
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant=*/true,
+ &non_constant_p);
+ if (!non_constant_p)
+ bounds = fold_non_dependent_expr (bounds);
+ }
+ else
+ bounds = NULL_TREE;
+ /* Look for the closing `]'. */
+ if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'"))
+ {
+ declarator = error_mark_node;
+ break;
+ }
+
+ declarator = build_nt (ARRAY_REF, declarator, bounds);
+ }
+ else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
+ {
+ /* Parse a declarator-id */
+ if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
+ cp_parser_parse_tentatively (parser);
+ declarator = cp_parser_declarator_id (parser);
+ if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
+ {
+ if (!cp_parser_parse_definitely (parser))
+ declarator = error_mark_node;
+ else if (TREE_CODE (declarator) != IDENTIFIER_NODE)
+ {
+ cp_parser_error (parser, "expected unqualified-id");
+ declarator = error_mark_node;
+ }
+ }
+
+ if (declarator == error_mark_node)
+ break;
+
+ if (TREE_CODE (declarator) == SCOPE_REF
+ && !current_scope ())
+ {
+ tree scope = TREE_OPERAND (declarator, 0);
+
+ /* 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. */
+ if (TREE_CODE (scope) == TYPENAME_TYPE)
+ {
+ tree type;
+
+ /* Resolve the TYPENAME_TYPE. */
+ type = resolve_typename_type (scope,
+ /*only_current_p=*/false);
+ /* If that failed, the declarator is invalid. */
+ if (type == error_mark_node)
+ error ("`%T::%D' is not a type",
+ TYPE_CONTEXT (scope),
+ TYPE_IDENTIFIER (scope));
+ /* Build a new DECLARATOR. */
+ declarator = build_nt (SCOPE_REF,
+ type,
+ TREE_OPERAND (declarator, 1));
+ }
+ }
+
+ /* Check to see whether the declarator-id names a constructor,
+ destructor, or conversion. */
+ if (declarator && ctor_dtor_or_conv_p
+ && ((TREE_CODE (declarator) == SCOPE_REF
+ && CLASS_TYPE_P (TREE_OPERAND (declarator, 0)))
+ || (TREE_CODE (declarator) != SCOPE_REF
+ && at_class_scope_p ())))
+ {
+ tree unqualified_name;
+ tree class_type;
+
+ /* Get the unqualified part of the name. */
+ if (TREE_CODE (declarator) == SCOPE_REF)
+ {
+ class_type = TREE_OPERAND (declarator, 0);
+ unqualified_name = TREE_OPERAND (declarator, 1);
+ }
+ else
+ {
+ class_type = current_class_type;
+ unqualified_name = declarator;
+ }
+
+ /* See if it names ctor, dtor or conv. */
+ if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR
+ || IDENTIFIER_TYPENAME_P (unqualified_name)
+ || constructor_name_p (unqualified_name, class_type)
+ || (TREE_CODE (unqualified_name) == TYPE_DECL
+ && same_type_p (TREE_TYPE (unqualified_name),
+ class_type)))
+ *ctor_dtor_or_conv_p = -1;
+ }
+
+ handle_declarator:;
+ scope = get_scope_of_declarator (declarator);
+ if (scope)
+ /* Any names that appear after the declarator-id for a
+ member are looked up in the containing scope. */
+ pop_p = push_scope (scope);
+ parser->in_declarator_p = true;
+ if ((ctor_dtor_or_conv_p && *ctor_dtor_or_conv_p)
+ || (declarator
+ && (TREE_CODE (declarator) == SCOPE_REF
+ || TREE_CODE (declarator) == IDENTIFIER_NODE)))
+ /* Default args are only allowed on function
+ declarations. */
+ parser->default_arg_ok_p = saved_default_arg_ok_p;
+ else
+ parser->default_arg_ok_p = false;
+
+ first = false;
+ }
+ /* We're done. */
+ else
+ break;
+ }
+
+ /* For an abstract declarator, we might wind up with nothing at this
+ point. That's an error; the declarator is not optional. */
+ if (!declarator)
+ cp_parser_error (parser, "expected declarator");
+
+ /* If we entered a scope, we must exit it now. */
+ if (pop_p)
+ pop_scope (scope);
+
+ parser->default_arg_ok_p = saved_default_arg_ok_p;
+ parser->in_declarator_p = saved_in_declarator_p;
+
+ return declarator;
+}
+
+/* Parse a ptr-operator.
+
+ ptr-operator:
+ * cv-qualifier-seq [opt]
+ &
+ :: [opt] nested-name-specifier * cv-qualifier-seq [opt]
+
+ GNU Extension:
+
+ ptr-operator:
+ & cv-qualifier-seq [opt]
+
+ Returns INDIRECT_REF if a pointer, or pointer-to-member, was
+ used. Returns ADDR_EXPR if a reference was used. In the
+ case of a pointer-to-member, *TYPE is filled in with the
+ TYPE containing the member. *CV_QUALIFIER_SEQ is filled in
+ with the cv-qualifier-seq, or NULL_TREE, if there are no
+ cv-qualifiers. Returns ERROR_MARK if an error occurred. */
+
+static enum tree_code
+cp_parser_ptr_operator (cp_parser* parser,
+ tree* type,
+ tree* cv_qualifier_seq)
+{
+ enum tree_code code = ERROR_MARK;
+ cp_token *token;
+
+ /* Assume that it's not a pointer-to-member. */
+ *type = NULL_TREE;
+ /* And that there are no cv-qualifiers. */
+ *cv_qualifier_seq = NULL_TREE;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's a `*' or `&' we have a pointer or reference. */
+ if (token->type == CPP_MULT || token->type == CPP_AND)
+ {
+ /* Remember which ptr-operator we were processing. */
+ code = (token->type == CPP_AND ? ADDR_EXPR : INDIRECT_REF);
+
+ /* Consume the `*' or `&'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* A `*' can be followed by a cv-qualifier-seq, and so can a
+ `&', if we are allowing GNU extensions. (The only qualifier
+ that can legally appear after `&' is `restrict', but that is
+ enforced during semantic analysis. */
+ if (code == INDIRECT_REF
+ || cp_parser_allow_gnu_extensions_p (parser))
+ *cv_qualifier_seq = cp_parser_cv_qualifier_seq_opt (parser);
+ }
+ else
+ {
+ /* Try the pointer-to-member case. */
+ cp_parser_parse_tentatively (parser);
+ /* Look for the optional `::' operator. */
+ cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false);
+ /* Look for the nested-name specifier. */
+ cp_parser_nested_name_specifier (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*type_p=*/false,
+ /*is_declaration=*/false);
+ /* If we found it, and the next token is a `*', then we are
+ indeed looking at a pointer-to-member operator. */
+ if (!cp_parser_error_occurred (parser)
+ && cp_parser_require (parser, CPP_MULT, "`*'"))
+ {
+ /* The type of which the member is a member is given by the
+ current SCOPE. */
+ *type = parser->scope;
+ /* The next name will not be qualified. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ /* Indicate that the `*' operator was used. */
+ code = INDIRECT_REF;
+ /* Look for the optional cv-qualifier-seq. */
+ *cv_qualifier_seq = cp_parser_cv_qualifier_seq_opt (parser);
+ }
+ /* If that didn't work we don't have a ptr-operator. */
+ if (!cp_parser_parse_definitely (parser))
+ cp_parser_error (parser, "expected ptr-operator");
+ }
+
+ return code;
+}
+
+/* Parse an (optional) cv-qualifier-seq.
+
+ cv-qualifier-seq:
+ cv-qualifier cv-qualifier-seq [opt]
+
+ Returns a TREE_LIST. The TREE_VALUE of each node is the
+ representation of a cv-qualifier. */
+
+static tree
+cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
+{
+ tree cv_qualifiers = NULL_TREE;
+
+ while (true)
+ {
+ tree cv_qualifier;
+
+ /* Look for the next cv-qualifier. */
+ cv_qualifier = cp_parser_cv_qualifier_opt (parser);
+ /* If we didn't find one, we're done. */
+ if (!cv_qualifier)
+ break;
+
+ /* Add this cv-qualifier to the list. */
+ cv_qualifiers
+ = tree_cons (NULL_TREE, cv_qualifier, cv_qualifiers);
+ }
+
+ /* We built up the list in reverse order. */
+ return nreverse (cv_qualifiers);
+}
+
+/* Parse an (optional) cv-qualifier.
+
+ cv-qualifier:
+ const
+ volatile
+
+ GNU Extension:
+
+ cv-qualifier:
+ __restrict__ */
+
+static tree
+cp_parser_cv_qualifier_opt (cp_parser* parser)
+{
+ cp_token *token;
+ tree cv_qualifier = NULL_TREE;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* See if it's a cv-qualifier. */
+ switch (token->keyword)
+ {
+ case RID_CONST:
+ case RID_VOLATILE:
+ case RID_RESTRICT:
+ /* Save the value of the token. */
+ cv_qualifier = token->value;
+ /* Consume the token. */
+ cp_lexer_consume_token (parser->lexer);
+ break;
+
+ default:
+ break;
+ }
+
+ return cv_qualifier;
+}
+
+/* Parse a declarator-id.
+
+ declarator-id:
+ id-expression
+ :: [opt] nested-name-specifier [opt] type-name
+
+ In the `id-expression' case, the value returned is as for
+ cp_parser_id_expression if the id-expression was an unqualified-id.
+ If the id-expression was a qualified-id, then a SCOPE_REF is
+ returned. The first operand is the scope (either a NAMESPACE_DECL
+ or TREE_TYPE), but the second is still just a representation of an
+ unqualified-id. */
+
+static tree
+cp_parser_declarator_id (cp_parser* parser)
+{
+ tree id_expression;
+
+ /* The expression must be an id-expression. Assume that qualified
+ names are the names of types so that:
+
+ template <class T>
+ int S<T>::R::i = 3;
+
+ will work; we must treat `S<T>::R' as the name of a type.
+ Similarly, assume that qualified names are templates, where
+ required, so that:
+
+ template <class T>
+ int S<T>::R<T>::i = 3;
+
+ will work, too. */
+ id_expression = cp_parser_id_expression (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/false,
+ /*template_p=*/NULL,
+ /*declarator_p=*/true);
+ /* If the name was qualified, create a SCOPE_REF to represent
+ that. */
+ if (parser->scope)
+ {
+ id_expression = build_nt (SCOPE_REF, parser->scope, id_expression);
+ parser->scope = NULL_TREE;
+ }
+
+ return id_expression;
+}
+
+/* Parse a type-id.
+
+ type-id:
+ type-specifier-seq abstract-declarator [opt]
+
+ Returns the TYPE specified. */
+
+static tree
+cp_parser_type_id (cp_parser* parser)
+{
+ tree type_specifier_seq;
+ tree abstract_declarator;
+
+ /* Parse the type-specifier-seq. */
+ type_specifier_seq
+ = cp_parser_type_specifier_seq (parser);
+ if (type_specifier_seq == error_mark_node)
+ return error_mark_node;
+
+ /* There might or might not be an abstract declarator. */
+ cp_parser_parse_tentatively (parser);
+ /* Look for the declarator. */
+ abstract_declarator
+ = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_ABSTRACT, NULL,
+ /*parenthesized_p=*/NULL);
+ /* Check to see if there really was a declarator. */
+ if (!cp_parser_parse_definitely (parser))
+ abstract_declarator = NULL_TREE;
+
+ return groktypename (build_tree_list (type_specifier_seq,
+ abstract_declarator));
+}
+
+/* Parse a type-specifier-seq.
+
+ type-specifier-seq:
+ type-specifier type-specifier-seq [opt]
+
+ GNU extension:
+
+ type-specifier-seq:
+ attributes type-specifier-seq [opt]
+
+ Returns a TREE_LIST. Either the TREE_VALUE of each node is a
+ type-specifier, or the TREE_PURPOSE is a list of attributes. */
+
+static tree
+cp_parser_type_specifier_seq (cp_parser* parser)
+{
+ bool seen_type_specifier = false;
+ tree type_specifier_seq = NULL_TREE;
+
+ /* Parse the type-specifiers and attributes. */
+ while (true)
+ {
+ tree type_specifier;
+
+ /* Check for attributes first. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
+ {
+ type_specifier_seq = tree_cons (cp_parser_attributes_opt (parser),
+ NULL_TREE,
+ type_specifier_seq);
+ continue;
+ }
+
+ /* After the first type-specifier, others are optional. */
+ if (seen_type_specifier)
+ cp_parser_parse_tentatively (parser);
+ /* Look for the type-specifier. */
+ type_specifier = cp_parser_type_specifier (parser,
+ CP_PARSER_FLAGS_NONE,
+ /*is_friend=*/false,
+ /*is_declaration=*/false,
+ NULL,
+ NULL);
+ /* If the first type-specifier could not be found, this is not a
+ type-specifier-seq at all. */
+ if (!seen_type_specifier && type_specifier == error_mark_node)
+ return error_mark_node;
+ /* If subsequent type-specifiers could not be found, the
+ type-specifier-seq is complete. */
+ else if (seen_type_specifier && !cp_parser_parse_definitely (parser))
+ break;
+
+ /* Add the new type-specifier to the list. */
+ type_specifier_seq
+ = tree_cons (NULL_TREE, type_specifier, type_specifier_seq);
+ seen_type_specifier = true;
+ }
+
+ /* We built up the list in reverse order. */
+ return nreverse (type_specifier_seq);
+}
+
+/* Parse a parameter-declaration-clause.
+
+ parameter-declaration-clause:
+ parameter-declaration-list [opt] ... [opt]
+ parameter-declaration-list , ...
+
+ Returns a representation for the parameter declarations. Each node
+ is a TREE_LIST. (See cp_parser_parameter_declaration for the exact
+ representation.) If the parameter-declaration-clause ends with an
+ ellipsis, PARMLIST_ELLIPSIS_P will hold of the first node in the
+ list. A return value of NULL_TREE indicates a
+ parameter-declaration-clause consisting only of an ellipsis. */
+
+static tree
+cp_parser_parameter_declaration_clause (cp_parser* parser)
+{
+ tree parameters;
+ cp_token *token;
+ bool ellipsis_p;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Check for trivial parameter-declaration-clauses. */
+ if (token->type == CPP_ELLIPSIS)
+ {
+ /* Consume the `...' token. */
+ cp_lexer_consume_token (parser->lexer);
+ return NULL_TREE;
+ }
+ else if (token->type == CPP_CLOSE_PAREN)
+ /* There are no parameters. */
+ {
+#ifndef NO_IMPLICIT_EXTERN_C
+ if (in_system_header && current_class_type == NULL
+ && current_lang_name == lang_name_c)
+ return NULL_TREE;
+ else
+#endif
+ return void_list_node;
+ }
+ /* Check for `(void)', too, which is a special case. */
+ else if (token->keyword == RID_VOID
+ && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ == CPP_CLOSE_PAREN))
+ {
+ /* Consume the `void' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* There are no parameters. */
+ return void_list_node;
+ }
+
+ /* Parse the parameter-declaration-list. */
+ parameters = cp_parser_parameter_declaration_list (parser);
+ /* If a parse error occurred while parsing the
+ parameter-declaration-list, then the entire
+ parameter-declaration-clause is erroneous. */
+ if (parameters == error_mark_node)
+ return error_mark_node;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's a `,', the clause should terminate with an ellipsis. */
+ if (token->type == CPP_COMMA)
+ {
+ /* Consume the `,'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Expect an ellipsis. */
+ ellipsis_p
+ = (cp_parser_require (parser, CPP_ELLIPSIS, "`...'") != NULL);
+ }
+ /* It might also be `...' if the optional trailing `,' was
+ omitted. */
+ else if (token->type == CPP_ELLIPSIS)
+ {
+ /* Consume the `...' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* And remember that we saw it. */
+ ellipsis_p = true;
+ }
+ else
+ ellipsis_p = false;
+
+ /* Finish the parameter list. */
+ return finish_parmlist (parameters, ellipsis_p);
+}
+
+/* Parse a parameter-declaration-list.
+
+ parameter-declaration-list:
+ parameter-declaration
+ parameter-declaration-list , parameter-declaration
+
+ Returns a representation of the parameter-declaration-list, as for
+ cp_parser_parameter_declaration_clause. However, the
+ `void_list_node' is never appended to the list. */
+
+static tree
+cp_parser_parameter_declaration_list (cp_parser* parser)
+{
+ tree parameters = NULL_TREE;
+
+ /* Look for more parameters. */
+ while (true)
+ {
+ tree parameter;
+ bool parenthesized_p;
+ /* Parse the parameter. */
+ parameter
+ = cp_parser_parameter_declaration (parser,
+ /*template_parm_p=*/false,
+ &parenthesized_p);
+
+ /* If a parse error occurred parsing the parameter declaration,
+ then the entire parameter-declaration-list is erroneous. */
+ if (parameter == error_mark_node)
+ {
+ parameters = error_mark_node;
+ break;
+ }
+ /* Add the new parameter to the list. */
+ TREE_CHAIN (parameter) = parameters;
+ parameters = parameter;
+
+ /* Peek at the next token. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)
+ || cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ /* The parameter-declaration-list is complete. */
+ break;
+ else if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ {
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_nth_token (parser->lexer, 2);
+ /* If it's an ellipsis, then the list is complete. */
+ if (token->type == CPP_ELLIPSIS)
+ break;
+ /* Otherwise, there must be more parameters. Consume the
+ `,'. */
+ cp_lexer_consume_token (parser->lexer);
+ /* When parsing something like:
+
+ int i(float f, double d)
+
+ we can tell after seeing the declaration for "f" that we
+ are not looking at an initialization of a variable "i",
+ but rather at the declaration of a function "i".
+
+ Due to the fact that the parsing of template arguments
+ (as specified to a template-id) requires backtracking we
+ cannot use this technique when inside a template argument
+ list. */
+ if (!parser->in_template_argument_list_p
+ && !parser->in_type_id_in_expr_p
+ && cp_parser_parsing_tentatively (parser)
+ && !cp_parser_committed_to_tentative_parse (parser)
+ /* However, a parameter-declaration of the form
+ "foat(f)" (which is a valid declaration of a
+ parameter "f") can also be interpreted as an
+ expression (the conversion of "f" to "float"). */
+ && !parenthesized_p)
+ cp_parser_commit_to_tentative_parse (parser);
+ }
+ else
+ {
+ cp_parser_error (parser, "expected `,' or `...'");
+ if (!cp_parser_parsing_tentatively (parser)
+ || cp_parser_committed_to_tentative_parse (parser))
+ cp_parser_skip_to_closing_parenthesis (parser,
+ /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/false);
+ break;
+ }
+ }
+
+ /* We built up the list in reverse order; straighten it out now. */
+ return nreverse (parameters);
+}
+
+/* Parse a parameter declaration.
+
+ parameter-declaration:
+ decl-specifier-seq declarator
+ decl-specifier-seq declarator = assignment-expression
+ decl-specifier-seq abstract-declarator [opt]
+ decl-specifier-seq abstract-declarator [opt] = assignment-expression
+
+ If TEMPLATE_PARM_P is TRUE, then this parameter-declaration
+ declares a template parameter. (In that case, a non-nested `>'
+ token encountered during the parsing of the assignment-expression
+ is not interpreted as a greater-than operator.)
+
+ Returns a TREE_LIST representing the parameter-declaration. The
+ TREE_PURPOSE is the default argument expression, or NULL_TREE if
+ there is no default argument. The TREE_VALUE is a representation
+ of the decl-specifier-seq and declarator. In particular, the
+ TREE_VALUE will be a TREE_LIST whose TREE_PURPOSE represents the
+ decl-specifier-seq and whose TREE_VALUE represents the declarator.
+ If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff
+ the declarator is of the form "(p)". */
+
+static tree
+cp_parser_parameter_declaration (cp_parser *parser,
+ bool template_parm_p,
+ bool *parenthesized_p)
+{
+ int declares_class_or_enum;
+ bool greater_than_is_operator_p;
+ tree decl_specifiers;
+ tree attributes;
+ tree declarator;
+ tree default_argument;
+ tree parameter;
+ cp_token *token;
+ const char *saved_message;
+
+ /* In a template parameter, `>' is not an operator.
+
+ [temp.param]
+
+ When parsing a default template-argument for a non-type
+ template-parameter, the first non-nested `>' is taken as the end
+ of the template parameter-list rather than a greater-than
+ operator. */
+ greater_than_is_operator_p = !template_parm_p;
+
+ /* Type definitions may not appear in parameter types. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = "types may not be defined in parameter types";
+
+ /* Parse the declaration-specifiers. */
+ decl_specifiers
+ = cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_NONE,
+ &attributes,
+ &declares_class_or_enum);
+ /* If an error occurred, there's no reason to attempt to parse the
+ rest of the declaration. */
+ if (cp_parser_error_occurred (parser))
+ {
+ parser->type_definition_forbidden_message = saved_message;
+ return error_mark_node;
+ }
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If the next token is a `)', `,', `=', `>', or `...', then there
+ is no declarator. */
+ if (token->type == CPP_CLOSE_PAREN
+ || token->type == CPP_COMMA
+ || token->type == CPP_EQ
+ || token->type == CPP_ELLIPSIS
+ || token->type == CPP_GREATER)
+ {
+ declarator = NULL_TREE;
+ if (parenthesized_p)
+ *parenthesized_p = false;
+ }
+ /* Otherwise, there should be a declarator. */
+ else
+ {
+ bool saved_default_arg_ok_p = parser->default_arg_ok_p;
+ parser->default_arg_ok_p = false;
+
+ /* After seeing a decl-specifier-seq, if the next token is not a
+ "(", there is no possibility that the code is a valid
+ expression. Therefore, if parsing tentatively, we commit at
+ this point. */
+ if (!parser->in_template_argument_list_p
+ /* In an expression context, having seen:
+
+ (int((char ...
+
+ we cannot be sure whether we are looking at a
+ function-type (taking a "char" as a parameter) or a cast
+ of some object of type "char" to "int". */
+ && !parser->in_type_id_in_expr_p
+ && cp_parser_parsing_tentatively (parser)
+ && !cp_parser_committed_to_tentative_parse (parser)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
+ cp_parser_commit_to_tentative_parse (parser);
+ /* Parse the declarator. */
+ declarator = cp_parser_declarator (parser,
+ CP_PARSER_DECLARATOR_EITHER,
+ /*ctor_dtor_or_conv_p=*/NULL,
+ parenthesized_p);
+ parser->default_arg_ok_p = saved_default_arg_ok_p;
+ /* After the declarator, allow more attributes. */
+ attributes = chainon (attributes, cp_parser_attributes_opt (parser));
+ }
+
+ /* The restriction on defining new types applies only to the type
+ of the parameter, not to the default argument. */
+ parser->type_definition_forbidden_message = saved_message;
+
+ /* If the next token is `=', then process a default argument. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+ {
+ bool saved_greater_than_is_operator_p;
+ /* Consume the `='. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* If we are defining a class, then the tokens that make up the
+ default argument must be saved and processed later. */
+ if (!template_parm_p && at_class_scope_p ()
+ && TYPE_BEING_DEFINED (current_class_type))
+ {
+ unsigned depth = 0;
+
+ /* Create a DEFAULT_ARG to represented the unparsed default
+ argument. */
+ default_argument = make_node (DEFAULT_ARG);
+ DEFARG_TOKENS (default_argument) = cp_token_cache_new ();
+
+ /* Add tokens until we have processed the entire default
+ argument. */
+ while (true)
+ {
+ bool done = false;
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* What we do depends on what token we have. */
+ switch (token->type)
+ {
+ /* In valid code, a default argument must be
+ immediately followed by a `,' `)', or `...'. */
+ case CPP_COMMA:
+ case CPP_CLOSE_PAREN:
+ case CPP_ELLIPSIS:
+ /* If we run into a non-nested `;', `}', or `]',
+ then the code is invalid -- but the default
+ argument is certainly over. */
+ case CPP_SEMICOLON:
+ case CPP_CLOSE_BRACE:
+ case CPP_CLOSE_SQUARE:
+ if (depth == 0)
+ done = true;
+ /* Update DEPTH, if necessary. */
+ else if (token->type == CPP_CLOSE_PAREN
+ || token->type == CPP_CLOSE_BRACE
+ || token->type == CPP_CLOSE_SQUARE)
+ --depth;
+ break;
+
+ case CPP_OPEN_PAREN:
+ case CPP_OPEN_SQUARE:
+ case CPP_OPEN_BRACE:
+ ++depth;
+ break;
+
+ case CPP_GREATER:
+ /* If we see a non-nested `>', and `>' is not an
+ operator, then it marks the end of the default
+ argument. */
+ if (!depth && !greater_than_is_operator_p)
+ done = true;
+ break;
+
+ /* If we run out of tokens, issue an error message. */
+ case CPP_EOF:
+ error ("file ends in default argument");
+ done = true;
+ break;
+
+ case CPP_NAME:
+ case CPP_SCOPE:
+ /* In these cases, we should look for template-ids.
+ For example, if the default argument is
+ `X<int, double>()', we need to do name lookup to
+ figure out whether or not `X' is a template; if
+ so, the `,' does not end the default argument.
+
+ That is not yet done. */
+ break;
+
+ default:
+ break;
+ }
+
+ /* If we've reached the end, stop. */
+ if (done)
+ break;
+
+ /* Add the token to the token block. */
+ token = cp_lexer_consume_token (parser->lexer);
+ cp_token_cache_push_token (DEFARG_TOKENS (default_argument),
+ token);
+ }
+ }
+ /* Outside of a class definition, we can just parse the
+ assignment-expression. */
+ else
+ {
+ bool saved_local_variables_forbidden_p;
+
+ /* Make sure that PARSER->GREATER_THAN_IS_OPERATOR_P is
+ set correctly. */
+ saved_greater_than_is_operator_p
+ = parser->greater_than_is_operator_p;
+ parser->greater_than_is_operator_p = greater_than_is_operator_p;
+ /* Local variable names (and the `this' keyword) may not
+ appear in a default argument. */
+ saved_local_variables_forbidden_p
+ = parser->local_variables_forbidden_p;
+ parser->local_variables_forbidden_p = true;
+ /* Parse the assignment-expression. */
+ default_argument = cp_parser_assignment_expression (parser);
+ /* Restore saved state. */
+ parser->greater_than_is_operator_p
+ = saved_greater_than_is_operator_p;
+ parser->local_variables_forbidden_p
+ = saved_local_variables_forbidden_p;
+ }
+ if (!parser->default_arg_ok_p)
+ {
+ if (!flag_pedantic_errors)
+ warning ("deprecated use of default argument for parameter of non-function");
+ else
+ {
+ error ("default arguments are only permitted for function parameters");
+ default_argument = NULL_TREE;
+ }
+ }
+ }
+ else
+ default_argument = NULL_TREE;
+
+ /* Create the representation of the parameter. */
+ if (attributes)
+ decl_specifiers = tree_cons (attributes, NULL_TREE, decl_specifiers);
+ parameter = build_tree_list (default_argument,
+ build_tree_list (decl_specifiers,
+ declarator));
+
+ return parameter;
+}
+
+/* Parse a function-body.
+
+ function-body:
+ compound_statement */
+
+static void
+cp_parser_function_body (cp_parser *parser)
+{
+ cp_parser_compound_statement (parser, false);
+}
+
+/* Parse a ctor-initializer-opt followed by a function-body. Return
+ true if a ctor-initializer was present. */
+
+static bool
+cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser)
+{
+ tree body;
+ bool ctor_initializer_p;
+
+ /* Begin the function body. */
+ body = begin_function_body ();
+ /* Parse the optional ctor-initializer. */
+ ctor_initializer_p = cp_parser_ctor_initializer_opt (parser);
+ /* Parse the function-body. */
+ cp_parser_function_body (parser);
+ /* Finish the function body. */
+ finish_function_body (body);
+
+ return ctor_initializer_p;
+}
+
+/* Parse an initializer.
+
+ initializer:
+ = initializer-clause
+ ( expression-list )
+
+ Returns a expression representing the initializer. If no
+ initializer is present, NULL_TREE is returned.
+
+ *IS_PARENTHESIZED_INIT is set to TRUE if the `( expression-list )'
+ production is used, and zero otherwise. *IS_PARENTHESIZED_INIT is
+ set to FALSE if there is no initializer present. If there is an
+ initializer, and it is not a constant-expression, *NON_CONSTANT_P
+ is set to true; otherwise it is set to false. */
+
+static tree
+cp_parser_initializer (cp_parser* parser, bool* is_parenthesized_init,
+ bool* non_constant_p)
+{
+ cp_token *token;
+ tree init;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* Let our caller know whether or not this initializer was
+ parenthesized. */
+ *is_parenthesized_init = (token->type == CPP_OPEN_PAREN);
+ /* Assume that the initializer is constant. */
+ *non_constant_p = false;
+
+ if (token->type == CPP_EQ)
+ {
+ /* Consume the `='. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the initializer-clause. */
+ init = cp_parser_initializer_clause (parser, non_constant_p);
+ }
+ else if (token->type == CPP_OPEN_PAREN)
+ init = cp_parser_parenthesized_expression_list (parser, false,
+ non_constant_p);
+ else
+ {
+ /* Anything else is an error. */
+ cp_parser_error (parser, "expected initializer");
+ init = error_mark_node;
+ }
+
+ return init;
+}
+
+/* Parse an initializer-clause.
+
+ initializer-clause:
+ assignment-expression
+ { initializer-list , [opt] }
+ { }
+
+ Returns an expression representing the initializer.
+
+ If the `assignment-expression' production is used the value
+ returned is simply a representation for the expression.
+
+ Otherwise, a CONSTRUCTOR is returned. The CONSTRUCTOR_ELTS will be
+ the elements of the initializer-list (or NULL_TREE, if the last
+ production is used). The TREE_TYPE for the CONSTRUCTOR will be
+ NULL_TREE. There is no way to detect whether or not the optional
+ trailing `,' was provided. NON_CONSTANT_P is as for
+ cp_parser_initializer. */
+
+static tree
+cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
+{
+ tree initializer;
+
+ /* If it is not a `{', then we are looking at an
+ assignment-expression. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
+ {
+ initializer
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant_p=*/true,
+ non_constant_p);
+ if (!*non_constant_p)
+ initializer = fold_non_dependent_expr (initializer);
+ }
+ else
+ {
+ /* Consume the `{' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Create a CONSTRUCTOR to represent the braced-initializer. */
+ initializer = make_node (CONSTRUCTOR);
+ /* Mark it with TREE_HAS_CONSTRUCTOR. This should not be
+ necessary, but check_initializer depends upon it, for
+ now. */
+ TREE_HAS_CONSTRUCTOR (initializer) = 1;
+ /* If it's not a `}', then there is a non-trivial initializer. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
+ {
+ /* Parse the initializer list. */
+ CONSTRUCTOR_ELTS (initializer)
+ = cp_parser_initializer_list (parser, non_constant_p);
+ /* A trailing `,' token is allowed. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ }
+ /* Now, there should be a trailing `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, "`}'");
+ }
+
+ return initializer;
+}
+
+/* Parse an initializer-list.
+
+ initializer-list:
+ initializer-clause
+ initializer-list , initializer-clause
+
+ GNU Extension:
+
+ initializer-list:
+ identifier : initializer-clause
+ initializer-list, identifier : initializer-clause
+
+ Returns a TREE_LIST. The TREE_VALUE of each node is an expression
+ for the initializer. If the TREE_PURPOSE is non-NULL, it is the
+ IDENTIFIER_NODE naming the field to initialize. NON_CONSTANT_P is
+ as for cp_parser_initializer. */
+
+static tree
+cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
+{
+ tree initializers = NULL_TREE;
+
+ /* Assume all of the expressions are constant. */
+ *non_constant_p = false;
+
+ /* Parse the rest of the list. */
+ while (true)
+ {
+ cp_token *token;
+ tree identifier;
+ tree initializer;
+ bool clause_non_constant_p;
+
+ /* If the next token is an identifier and the following one is a
+ colon, we are looking at the GNU designated-initializer
+ syntax. */
+ if (cp_parser_allow_gnu_extensions_p (parser)
+ && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
+ {
+ /* Consume the identifier. */
+ identifier = cp_lexer_consume_token (parser->lexer)->value;
+ /* Consume the `:'. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+ else
+ identifier = NULL_TREE;
+
+ /* Parse the initializer. */
+ initializer = cp_parser_initializer_clause (parser,
+ &clause_non_constant_p);
+ /* If any clause is non-constant, so is the entire initializer. */
+ if (clause_non_constant_p)
+ *non_constant_p = true;
+ /* Add it to the list. */
+ initializers = tree_cons (identifier, initializer, initializers);
+
+ /* If the next token is not a comma, we have reached the end of
+ the list. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_nth_token (parser->lexer, 2);
+ /* If the next token is a `}', then we're still done. An
+ initializer-clause can have a trailing `,' after the
+ initializer-list and before the closing `}'. */
+ if (token->type == CPP_CLOSE_BRACE)
+ break;
+
+ /* Consume the `,' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ /* The initializers were built up in reverse order, so we need to
+ reverse them now. */
+ return nreverse (initializers);
+}
+
+/* Classes [gram.class] */
+
+/* Parse a class-name.
+
+ class-name:
+ identifier
+ template-id
+
+ TYPENAME_KEYWORD_P is true iff the `typename' keyword has been used
+ to indicate that names looked up in dependent types should be
+ assumed to be types. TEMPLATE_KEYWORD_P is true iff the `template'
+ keyword has been used to indicate that the name that appears next
+ is a template. TYPE_P is true iff the next name should be treated
+ as class-name, even if it is declared to be some other kind of name
+ as well. If CHECK_DEPENDENCY_P is FALSE, names are looked up in
+ dependent scopes. If CLASS_HEAD_P is TRUE, this class is the class
+ being defined in a class-head.
+
+ Returns the TYPE_DECL representing the class. */
+
+static tree
+cp_parser_class_name (cp_parser *parser,
+ bool typename_keyword_p,
+ bool template_keyword_p,
+ bool type_p,
+ bool check_dependency_p,
+ bool class_head_p,
+ bool is_declaration)
+{
+ tree decl;
+ tree scope;
+ bool typename_p;
+ cp_token *token;
+
+ /* All class-names start with an identifier. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type != CPP_NAME && token->type != CPP_TEMPLATE_ID)
+ {
+ cp_parser_error (parser, "expected class-name");
+ return error_mark_node;
+ }
+
+ /* PARSER->SCOPE can be cleared when parsing the template-arguments
+ to a template-id, so we save it here. */
+ scope = parser->scope;
+ if (scope == error_mark_node)
+ return error_mark_node;
+
+ /* Any name names a type if we're following the `typename' keyword
+ in a qualified name where the enclosing scope is type-dependent. */
+ typename_p = (typename_keyword_p && scope && TYPE_P (scope)
+ && dependent_type_p (scope));
+ /* Handle the common case (an identifier, but not a template-id)
+ efficiently. */
+ if (token->type == CPP_NAME
+ && !cp_parser_nth_token_starts_template_argument_list_p (parser, 2))
+ {
+ tree identifier;
+
+ /* Look for the identifier. */
+ identifier = cp_parser_identifier (parser);
+ /* If the next token isn't an identifier, we are certainly not
+ looking at a class-name. */
+ if (identifier == error_mark_node)
+ decl = error_mark_node;
+ /* If we know this is a type-name, there's no need to look it
+ up. */
+ else if (typename_p)
+ decl = identifier;
+ else
+ {
+ /* If the next token is a `::', then the name must be a type
+ name.
+
+ [basic.lookup.qual]
+
+ During the lookup for a name preceding the :: scope
+ resolution operator, object, function, and enumerator
+ names are ignored. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+ type_p = true;
+ /* Look up the name. */
+ decl = cp_parser_lookup_name (parser, identifier,
+ type_p,
+ /*is_template=*/false,
+ /*is_namespace=*/false,
+ check_dependency_p);
+ }
+ }
+ else
+ {
+ /* Try a template-id. */
+ decl = cp_parser_template_id (parser, template_keyword_p,
+ check_dependency_p,
+ is_declaration);
+ if (decl == error_mark_node)
+ return error_mark_node;
+ }
+
+ decl = cp_parser_maybe_treat_template_as_class (decl, class_head_p);
+
+ /* If this is a typename, create a TYPENAME_TYPE. */
+ if (typename_p && decl != error_mark_node)
+ {
+ decl = make_typename_type (scope, decl, /*complain=*/1);
+ if (decl != error_mark_node)
+ decl = TYPE_NAME (decl);
+ }
+
+ /* Check to see that it is really the name of a class. */
+ if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
+ && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE
+ && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
+ /* Situations like this:
+
+ template <typename T> struct A {
+ typename T::template X<int>::I i;
+ };
+
+ are problematic. Is `T::template X<int>' a class-name? The
+ standard does not seem to be definitive, but there is no other
+ valid interpretation of the following `::'. Therefore, those
+ names are considered class-names. */
+ decl = TYPE_NAME (make_typename_type (scope, decl, tf_error));
+ else if (decl == error_mark_node
+ || TREE_CODE (decl) != TYPE_DECL
+ || !IS_AGGR_TYPE (TREE_TYPE (decl)))
+ {
+ cp_parser_error (parser, "expected class-name");
+ return error_mark_node;
+ }
+
+ return decl;
+}
+
+/* Parse a class-specifier.
+
+ class-specifier:
+ class-head { member-specification [opt] }
+
+ Returns the TREE_TYPE representing the class. */
+
+static tree
+cp_parser_class_specifier (cp_parser* parser)
+{
+ cp_token *token;
+ tree type;
+ tree attributes;
+ int has_trailing_semicolon;
+ bool nested_name_specifier_p;
+ unsigned saved_num_template_parameter_lists;
+ bool pop_p = false;
+
+ push_deferring_access_checks (dk_no_deferred);
+
+ /* Parse the class-head. */
+ type = cp_parser_class_head (parser,
+ &nested_name_specifier_p,
+ &attributes);
+ /* If the class-head was a semantic disaster, skip the entire body
+ of the class. */
+ if (!type)
+ {
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ pop_deferring_access_checks ();
+ return error_mark_node;
+ }
+
+ /* Look for the `{'. */
+ if (!cp_parser_require (parser, CPP_OPEN_BRACE, "`{'"))
+ {
+ pop_deferring_access_checks ();
+ return error_mark_node;
+ }
+
+ /* Issue an error message if type-definitions are forbidden here. */
+ cp_parser_check_type_definition (parser);
+ /* Remember that we are defining one more class. */
+ ++parser->num_classes_being_defined;
+ /* Inside the class, surrounding template-parameter-lists do not
+ apply. */
+ saved_num_template_parameter_lists
+ = parser->num_template_parameter_lists;
+ parser->num_template_parameter_lists = 0;
+
+ /* Start the class. */
+ if (nested_name_specifier_p)
+ pop_p = push_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
+ type = begin_class_definition (type);
+ if (type == error_mark_node)
+ /* If the type is erroneous, skip the entire body of the class. */
+ cp_parser_skip_to_closing_brace (parser);
+ else
+ /* Parse the member-specification. */
+ cp_parser_member_specification_opt (parser);
+ /* Look for the trailing `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, "`}'");
+ /* We get better error messages by noticing a common problem: a
+ missing trailing `;'. */
+ token = cp_lexer_peek_token (parser->lexer);
+ has_trailing_semicolon = (token->type == CPP_SEMICOLON);
+ /* Look for trailing attributes to apply to this class. */
+ if (cp_parser_allow_gnu_extensions_p (parser))
+ {
+ tree sub_attr = cp_parser_attributes_opt (parser);
+ attributes = chainon (attributes, sub_attr);
+ }
+ if (type != error_mark_node)
+ type = finish_struct (type, attributes);
+ if (pop_p)
+ pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (type)));
+ /* If this class is not itself within the scope of another class,
+ then we need to parse the bodies of all of the queued function
+ definitions. Note that the queued functions defined in a class
+ are not always processed immediately following the
+ class-specifier for that class. Consider:
+
+ struct A {
+ struct B { void f() { sizeof (A); } };
+ };
+
+ If `f' were processed before the processing of `A' were
+ completed, there would be no way to compute the size of `A'.
+ Note that the nesting we are interested in here is lexical --
+ not the semantic nesting given by TYPE_CONTEXT. In particular,
+ for:
+
+ struct A { struct B; };
+ struct A::B { void f() { } };
+
+ there is no need to delay the parsing of `A::B::f'. */
+ if (--parser->num_classes_being_defined == 0)
+ {
+ tree queue_entry;
+ tree fn;
+
+ /* In a first pass, parse default arguments to the functions.
+ Then, in a second pass, parse the bodies of the functions.
+ This two-phased approach handles cases like:
+
+ struct S {
+ void f() { g(); }
+ void g(int i = 3);
+ };
+
+ */
+ for (TREE_PURPOSE (parser->unparsed_functions_queues)
+ = nreverse (TREE_PURPOSE (parser->unparsed_functions_queues));
+ (queue_entry = TREE_PURPOSE (parser->unparsed_functions_queues));
+ TREE_PURPOSE (parser->unparsed_functions_queues)
+ = TREE_CHAIN (TREE_PURPOSE (parser->unparsed_functions_queues)))
+ {
+ fn = TREE_VALUE (queue_entry);
+ /* Make sure that any template parameters are in scope. */
+ maybe_begin_member_template_processing (fn);
+ /* If there are default arguments that have not yet been processed,
+ take care of them now. */
+ cp_parser_late_parsing_default_args (parser, fn);
+ /* Remove any template parameters from the symbol table. */
+ maybe_end_member_template_processing ();
+ }
+ /* Now parse the body of the functions. */
+ for (TREE_VALUE (parser->unparsed_functions_queues)
+ = nreverse (TREE_VALUE (parser->unparsed_functions_queues));
+ (queue_entry = TREE_VALUE (parser->unparsed_functions_queues));
+ TREE_VALUE (parser->unparsed_functions_queues)
+ = TREE_CHAIN (TREE_VALUE (parser->unparsed_functions_queues)))
+ {
+ /* Figure out which function we need to process. */
+ fn = TREE_VALUE (queue_entry);
+
+ /* A hack to prevent garbage collection. */
+ function_depth++;
+
+ /* Parse the function. */
+ cp_parser_late_parsing_for_member (parser, fn);
+ function_depth--;
+ }
+
+ }
+
+ /* Put back any saved access checks. */
+ pop_deferring_access_checks ();
+
+ /* Restore the count of active template-parameter-lists. */
+ parser->num_template_parameter_lists
+ = saved_num_template_parameter_lists;
+
+ return type;
+}
+
+/* Parse a class-head.
+
+ class-head:
+ class-key identifier [opt] base-clause [opt]
+ class-key nested-name-specifier identifier base-clause [opt]
+ class-key nested-name-specifier [opt] template-id
+ base-clause [opt]
+
+ GNU Extensions:
+ class-key attributes identifier [opt] base-clause [opt]
+ class-key attributes nested-name-specifier identifier base-clause [opt]
+ class-key attributes nested-name-specifier [opt] template-id
+ base-clause [opt]
+
+ Returns the TYPE of the indicated class. Sets
+ *NESTED_NAME_SPECIFIER_P to TRUE iff one of the productions
+ involving a nested-name-specifier was used, and FALSE otherwise.
+
+ Returns NULL_TREE if the class-head is syntactically valid, but
+ semantically invalid in a way that means we should skip the entire
+ body of the class. */
+
+static tree
+cp_parser_class_head (cp_parser* parser,
+ bool* nested_name_specifier_p,
+ tree *attributes_p)
+{
+ cp_token *token;
+ tree nested_name_specifier;
+ enum tag_types class_key;
+ tree id = NULL_TREE;
+ tree type = NULL_TREE;
+ tree attributes;
+ bool template_id_p = false;
+ bool qualified_p = false;
+ bool invalid_nested_name_p = false;
+ bool invalid_explicit_specialization_p = false;
+ bool pop_p = false;
+ unsigned num_templates;
+
+ /* Assume no nested-name-specifier will be present. */
+ *nested_name_specifier_p = false;
+ /* Assume no template parameter lists will be used in defining the
+ type. */
+ num_templates = 0;
+
+ /* Look for the class-key. */
+ class_key = cp_parser_class_key (parser);
+ if (class_key == none_type)
+ return error_mark_node;
+
+ /* Parse the attributes. */
+ attributes = cp_parser_attributes_opt (parser);
+
+ /* If the next token is `::', that is invalid -- but sometimes
+ people do try to write:
+
+ struct ::S {};
+
+ Handle this gracefully by accepting the extra qualifier, and then
+ issuing an error about it later if this really is a
+ class-head. If it turns out just to be an elaborated type
+ specifier, remain silent. */
+ if (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false))
+ qualified_p = true;
+
+ push_deferring_access_checks (dk_no_check);
+
+ /* Determine the name of the class. Begin by looking for an
+ optional nested-name-specifier. */
+ nested_name_specifier
+ = cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/false,
+ /*type_p=*/false,
+ /*is_declaration=*/false);
+ /* If there was a nested-name-specifier, then there *must* be an
+ identifier. */
+ if (nested_name_specifier)
+ {
+ /* Although the grammar says `identifier', it really means
+ `class-name' or `template-name'. You are only allowed to
+ define a class that has already been declared with this
+ syntax.
+
+ The proposed resolution for Core Issue 180 says that whever
+ you see `class T::X' you should treat `X' as a type-name.
+
+ It is OK to define an inaccessible class; for example:
+
+ class A { class B; };
+ class A::B {};
+
+ We do not know if we will see a class-name, or a
+ template-name. We look for a class-name first, in case the
+ class-name is a template-id; if we looked for the
+ template-name first we would stop after the template-name. */
+ cp_parser_parse_tentatively (parser);
+ type = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ /*type_p=*/true,
+ /*check_dependency_p=*/false,
+ /*class_head_p=*/true,
+ /*is_declaration=*/false);
+ /* If that didn't work, ignore the nested-name-specifier. */
+ if (!cp_parser_parse_definitely (parser))
+ {
+ invalid_nested_name_p = true;
+ id = cp_parser_identifier (parser);
+ if (id == error_mark_node)
+ id = NULL_TREE;
+ }
+ /* If we could not find a corresponding TYPE, treat this
+ declaration like an unqualified declaration. */
+ if (type == error_mark_node)
+ nested_name_specifier = NULL_TREE;
+ /* Otherwise, count the number of templates used in TYPE and its
+ containing scopes. */
+ else
+ {
+ tree scope;
+
+ for (scope = TREE_TYPE (type);
+ scope && TREE_CODE (scope) != NAMESPACE_DECL;
+ scope = (TYPE_P (scope)
+ ? TYPE_CONTEXT (scope)
+ : DECL_CONTEXT (scope)))
+ if (TYPE_P (scope)
+ && CLASS_TYPE_P (scope)
+ && CLASSTYPE_TEMPLATE_INFO (scope)
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope))
+ && !CLASSTYPE_TEMPLATE_SPECIALIZATION (scope))
+ ++num_templates;
+ }
+ }
+ /* Otherwise, the identifier is optional. */
+ else
+ {
+ /* We don't know whether what comes next is a template-id,
+ an identifier, or nothing at all. */
+ cp_parser_parse_tentatively (parser);
+ /* Check for a template-id. */
+ id = cp_parser_template_id (parser,
+ /*template_keyword_p=*/false,
+ /*check_dependency_p=*/true,
+ /*is_declaration=*/true);
+ /* If that didn't work, it could still be an identifier. */
+ if (!cp_parser_parse_definitely (parser))
+ {
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ id = cp_parser_identifier (parser);
+ else
+ id = NULL_TREE;
+ }
+ else
+ {
+ template_id_p = true;
+ ++num_templates;
+ }
+ }
+
+ pop_deferring_access_checks ();
+
+ if (id)
+ cp_parser_check_for_invalid_template_id (parser, id);
+
+ /* If it's not a `:' or a `{' then we can't really be looking at a
+ class-head, since a class-head only appears as part of a
+ class-specifier. We have to detect this situation before calling
+ xref_tag, since that has irreversible side-effects. */
+ if (!cp_parser_next_token_starts_class_definition_p (parser))
+ {
+ cp_parser_error (parser, "expected `{' or `:'");
+ return error_mark_node;
+ }
+
+ /* At this point, we're going ahead with the class-specifier, even
+ if some other problem occurs. */
+ cp_parser_commit_to_tentative_parse (parser);
+ /* Issue the error about the overly-qualified name now. */
+ if (qualified_p)
+ cp_parser_error (parser,
+ "global qualification of class name is invalid");
+ else if (invalid_nested_name_p)
+ cp_parser_error (parser,
+ "qualified name does not name a class");
+ else if (nested_name_specifier)
+ {
+ tree scope;
+ /* Figure out in what scope the declaration is being placed. */
+ scope = current_scope ();
+ if (!scope)
+ scope = current_namespace;
+ /* If that scope does not contain the scope in which the
+ class was originally declared, the program is invalid. */
+ if (scope && !is_ancestor (scope, nested_name_specifier))
+ {
+ error ("declaration of `%D' in `%D' which does not "
+ "enclose `%D'", type, scope, nested_name_specifier);
+ type = NULL_TREE;
+ goto done;
+ }
+ /* [dcl.meaning]
+
+ A declarator-id shall not be qualified exception of the
+ definition of a ... nested class outside of its class
+ ... [or] a the definition or explicit instantiation of a
+ class member of a namespace outside of its namespace. */
+ if (scope == nested_name_specifier)
+ {
+ pedwarn ("extra qualification ignored");
+ nested_name_specifier = NULL_TREE;
+ num_templates = 0;
+ }
+ }
+ /* An explicit-specialization must be preceded by "template <>". If
+ it is not, try to recover gracefully. */
+ if (at_namespace_scope_p ()
+ && parser->num_template_parameter_lists == 0
+ && template_id_p)
+ {
+ error ("an explicit specialization must be preceded by 'template <>'");
+ invalid_explicit_specialization_p = true;
+ /* Take the same action that would have been taken by
+ cp_parser_explicit_specialization. */
+ ++parser->num_template_parameter_lists;
+ begin_specialization ();
+ }
+ /* There must be no "return" statements between this point and the
+ end of this function; set "type "to the correct return value and
+ use "goto done;" to return. */
+ /* Make sure that the right number of template parameters were
+ present. */
+ if (!cp_parser_check_template_parameters (parser, num_templates))
+ {
+ /* If something went wrong, there is no point in even trying to
+ process the class-definition. */
+ type = NULL_TREE;
+ goto done;
+ }
+
+ /* Look up the type. */
+ if (template_id_p)
+ {
+ type = TREE_TYPE (id);
+ maybe_process_partial_specialization (type);
+ }
+ else if (!nested_name_specifier)
+ {
+ /* If the class was unnamed, create a dummy name. */
+ if (!id)
+ id = make_anon_name ();
+ type = xref_tag (class_key, id, /*globalize=*/false,
+ parser->num_template_parameter_lists);
+ }
+ else
+ {
+ tree class_type;
+ bool pop_p = false;
+
+ /* Given:
+
+ template <typename T> struct S { struct T };
+ template <typename T> struct S<T>::T { };
+
+ we will get a TYPENAME_TYPE when processing the definition of
+ `S::T'. We need to resolve it to the actual type before we
+ try to define it. */
+ if (TREE_CODE (TREE_TYPE (type)) == TYPENAME_TYPE)
+ {
+ class_type = resolve_typename_type (TREE_TYPE (type),
+ /*only_current_p=*/false);
+ if (class_type != error_mark_node)
+ type = TYPE_NAME (class_type);
+ else
+ {
+ cp_parser_error (parser, "could not resolve typename type");
+ type = error_mark_node;
+ }
+ }
+
+ maybe_process_partial_specialization (TREE_TYPE (type));
+ class_type = current_class_type;
+ /* Enter the scope indicated by the nested-name-specifier. */
+ if (nested_name_specifier)
+ pop_p = push_scope (nested_name_specifier);
+ /* Get the canonical version of this type. */
+ type = TYPE_MAIN_DECL (TREE_TYPE (type));
+ if (PROCESSING_REAL_TEMPLATE_DECL_P ()
+ && !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (type)))
+ type = push_template_decl (type);
+ type = TREE_TYPE (type);
+ if (nested_name_specifier)
+ {
+ *nested_name_specifier_p = true;
+ if (pop_p)
+ pop_scope (nested_name_specifier);
+ }
+ }
+ /* Indicate whether this class was declared as a `class' or as a
+ `struct'. */
+ if (TREE_CODE (type) == RECORD_TYPE)
+ CLASSTYPE_DECLARED_CLASS (type) = (class_key == class_type);
+ cp_parser_check_class_key (class_key, type);
+
+ /* Enter the scope containing the class; the names of base classes
+ should be looked up in that context. For example, given:
+
+ struct A { struct B {}; struct C; };
+ struct A::C : B {};
+
+ is valid. */
+ if (nested_name_specifier)
+ pop_p = push_scope (nested_name_specifier);
+ /* Now, look for the base-clause. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type == CPP_COLON)
+ {
+ tree bases;
+
+ /* Get the list of base-classes. */
+ bases = cp_parser_base_clause (parser);
+ /* Process them. */
+ xref_basetypes (type, bases);
+ }
+ /* Leave the scope given by the nested-name-specifier. We will
+ enter the class scope itself while processing the members. */
+ if (pop_p)
+ pop_scope (nested_name_specifier);
+
+ done:
+ if (invalid_explicit_specialization_p)
+ {
+ end_specialization ();
+ --parser->num_template_parameter_lists;
+ }
+ *attributes_p = attributes;
+ return type;
+}
+
+/* Parse a class-key.
+
+ class-key:
+ class
+ struct
+ union
+
+ Returns the kind of class-key specified, or none_type to indicate
+ error. */
+
+static enum tag_types
+cp_parser_class_key (cp_parser* parser)
+{
+ cp_token *token;
+ enum tag_types tag_type;
+
+ /* Look for the class-key. */
+ token = cp_parser_require (parser, CPP_KEYWORD, "class-key");
+ if (!token)
+ return none_type;
+
+ /* Check to see if the TOKEN is a class-key. */
+ tag_type = cp_parser_token_is_class_key (token);
+ if (!tag_type)
+ cp_parser_error (parser, "expected class-key");
+ return tag_type;
+}
+
+/* Parse an (optional) member-specification.
+
+ member-specification:
+ member-declaration member-specification [opt]
+ access-specifier : member-specification [opt] */
+
+static void
+cp_parser_member_specification_opt (cp_parser* parser)
+{
+ while (true)
+ {
+ cp_token *token;
+ enum rid keyword;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's a `}', or EOF then we've seen all the members. */
+ if (token->type == CPP_CLOSE_BRACE || token->type == CPP_EOF)
+ break;
+
+ /* See if this token is a keyword. */
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ case RID_PUBLIC:
+ case RID_PROTECTED:
+ case RID_PRIVATE:
+ /* Consume the access-specifier. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Remember which access-specifier is active. */
+ current_access_specifier = token->value;
+ /* Look for the `:'. */
+ cp_parser_require (parser, CPP_COLON, "`:'");
+ break;
+
+ default:
+ /* Otherwise, the next construction must be a
+ member-declaration. */
+ cp_parser_member_declaration (parser);
+ }
+ }
+}
+
+/* Parse a member-declaration.
+
+ member-declaration:
+ decl-specifier-seq [opt] member-declarator-list [opt] ;
+ function-definition ; [opt]
+ :: [opt] nested-name-specifier template [opt] unqualified-id ;
+ using-declaration
+ template-declaration
+
+ member-declarator-list:
+ member-declarator
+ member-declarator-list , member-declarator
+
+ member-declarator:
+ declarator pure-specifier [opt]
+ declarator constant-initializer [opt]
+ identifier [opt] : constant-expression
+
+ GNU Extensions:
+
+ member-declaration:
+ __extension__ member-declaration
+
+ member-declarator:
+ declarator attributes [opt] pure-specifier [opt]
+ declarator attributes [opt] constant-initializer [opt]
+ identifier [opt] attributes [opt] : constant-expression */
+
+static void
+cp_parser_member_declaration (cp_parser* parser)
+{
+ tree decl_specifiers;
+ tree prefix_attributes;
+ tree decl;
+ int declares_class_or_enum;
+ bool friend_p;
+ cp_token *token;
+ int saved_pedantic;
+
+ /* Check for the `__extension__' keyword. */
+ if (cp_parser_extension_opt (parser, &saved_pedantic))
+ {
+ /* Recurse. */
+ cp_parser_member_declaration (parser);
+ /* Restore the old value of the PEDANTIC flag. */
+ pedantic = saved_pedantic;
+
+ return;
+ }
+
+ /* Check for a template-declaration. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
+ {
+ /* Parse the template-declaration. */
+ cp_parser_template_declaration (parser, /*member_p=*/true);
+
+ return;
+ }
+
+ /* Check for a using-declaration. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
+ {
+ /* Parse the using-declaration. */
+ cp_parser_using_declaration (parser);
+
+ return;
+ }
+
+ /* Parse the decl-specifier-seq. */
+ decl_specifiers
+ = cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_OPTIONAL,
+ &prefix_attributes,
+ &declares_class_or_enum);
+ /* Check for an invalid type-name. */
+ if (cp_parser_diagnose_invalid_type_name (parser))
+ return;
+ /* If there is no declarator, then the decl-specifier-seq should
+ specify a type. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ {
+ /* If there was no decl-specifier-seq, and the next token is a
+ `;', then we have something like:
+
+ struct S { ; };
+
+ [class.mem]
+
+ Each member-declaration shall declare at least one member
+ name of the class. */
+ if (!decl_specifiers)
+ {
+ if (pedantic)
+ pedwarn ("extra semicolon");
+ }
+ else
+ {
+ tree type;
+
+ /* See if this declaration is a friend. */
+ friend_p = cp_parser_friend_p (decl_specifiers);
+ /* If there were decl-specifiers, check to see if there was
+ a class-declaration. */
+ type = check_tag_decl (decl_specifiers);
+ /* Nested classes have already been added to the class, but
+ a `friend' needs to be explicitly registered. */
+ if (friend_p)
+ {
+ /* If the `friend' keyword was present, the friend must
+ be introduced with a class-key. */
+ if (!declares_class_or_enum)
+ error ("a class-key must be used when declaring a friend");
+ /* In this case:
+
+ template <typename T> struct A {
+ friend struct A<T>::B;
+ };
+
+ A<T>::B will be represented by a TYPENAME_TYPE, and
+ therefore not recognized by check_tag_decl. */
+ if (!type)
+ {
+ tree specifier;
+
+ for (specifier = decl_specifiers;
+ specifier;
+ specifier = TREE_CHAIN (specifier))
+ {
+ tree s = TREE_VALUE (specifier);
+
+ if (TREE_CODE (s) == IDENTIFIER_NODE)
+ get_global_value_if_present (s, &type);
+ if (TREE_CODE (s) == TYPE_DECL)
+ s = TREE_TYPE (s);
+ if (TYPE_P (s))
+ {
+ type = s;
+ break;
+ }
+ }
+ }
+ if (!type || !TYPE_P (type))
+ error ("friend declaration does not name a class or "
+ "function");
+ else
+ make_friend_class (current_class_type, type,
+ /*complain=*/true);
+ }
+ /* If there is no TYPE, an error message will already have
+ been issued. */
+ else if (!type)
+ ;
+ /* An anonymous aggregate has to be handled specially; such
+ a declaration really declares a data member (with a
+ particular type), as opposed to a nested class. */
+ else if (ANON_AGGR_TYPE_P (type))
+ {
+ /* Remove constructors and such from TYPE, now that we
+ know it is an anonymous aggregate. */
+ fixup_anonymous_aggr (type);
+ /* And make the corresponding data member. */
+ decl = build_decl (FIELD_DECL, NULL_TREE, type);
+ /* Add it to the class. */
+ finish_member_declaration (decl);
+ }
+ else
+ cp_parser_check_access_in_redeclaration (TYPE_NAME (type));
+ }
+ }
+ else
+ {
+ /* See if these declarations will be friends. */
+ friend_p = cp_parser_friend_p (decl_specifiers);
+
+ /* Keep going until we hit the `;' at the end of the
+ declaration. */
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
+ {
+ tree attributes = NULL_TREE;
+ tree first_attribute;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+
+ /* Check for a bitfield declaration. */
+ if (token->type == CPP_COLON
+ || (token->type == CPP_NAME
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type
+ == CPP_COLON))
+ {
+ tree identifier;
+ tree width;
+
+ /* Get the name of the bitfield. Note that we cannot just
+ check TOKEN here because it may have been invalidated by
+ the call to cp_lexer_peek_nth_token above. */
+ if (cp_lexer_peek_token (parser->lexer)->type != CPP_COLON)
+ identifier = cp_parser_identifier (parser);
+ else
+ identifier = NULL_TREE;
+
+ /* Consume the `:' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Get the width of the bitfield. */
+ width
+ = cp_parser_constant_expression (parser,
+ /*allow_non_constant=*/false,
+ NULL);
+
+ /* Look for attributes that apply to the bitfield. */
+ attributes = cp_parser_attributes_opt (parser);
+ /* Remember which attributes are prefix attributes and
+ which are not. */
+ first_attribute = attributes;
+ /* Combine the attributes. */
+ attributes = chainon (prefix_attributes, attributes);
+
+ /* Create the bitfield declaration. */
+ decl = grokbitfield (identifier,
+ decl_specifiers,
+ width);
+ /* Apply the attributes. */
+ cplus_decl_attributes (&decl, attributes, /*flags=*/0);
+ }
+ else
+ {
+ tree declarator;
+ tree initializer;
+ tree asm_specification;
+ int ctor_dtor_or_conv_p;
+
+ /* Parse the declarator. */
+ declarator
+ = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
+ &ctor_dtor_or_conv_p,
+ /*parenthesized_p=*/NULL);
+
+ /* If something went wrong parsing the declarator, make sure
+ that we at least consume some tokens. */
+ if (declarator == error_mark_node)
+ {
+ /* Skip to the end of the statement. */
+ cp_parser_skip_to_end_of_statement (parser);
+ /* If the next token is not a semicolon, that is
+ probably because we just skipped over the body of
+ a function. So, we consume a semicolon if
+ present, but do not issue an error message if it
+ is not present. */
+ if (cp_lexer_next_token_is (parser->lexer,
+ CPP_SEMICOLON))
+ cp_lexer_consume_token (parser->lexer);
+ return;
+ }
+
+ cp_parser_check_for_definition_in_return_type
+ (declarator, declares_class_or_enum);
+
+ /* Look for an asm-specification. */
+ asm_specification = cp_parser_asm_specification_opt (parser);
+ /* Look for attributes that apply to the declaration. */
+ attributes = cp_parser_attributes_opt (parser);
+ /* Remember which attributes are prefix attributes and
+ which are not. */
+ first_attribute = attributes;
+ /* Combine the attributes. */
+ attributes = chainon (prefix_attributes, attributes);
+
+ /* If it's an `=', then we have a constant-initializer or a
+ pure-specifier. It is not correct to parse the
+ initializer before registering the member declaration
+ since the member declaration should be in scope while
+ its initializer is processed. However, the rest of the
+ front end does not yet provide an interface that allows
+ us to handle this correctly. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
+ {
+ /* In [class.mem]:
+
+ A pure-specifier shall be used only in the declaration of
+ a virtual function.
+
+ A member-declarator can contain a constant-initializer
+ only if it declares a static member of integral or
+ enumeration type.
+
+ Therefore, if the DECLARATOR is for a function, we look
+ for a pure-specifier; otherwise, we look for a
+ constant-initializer. When we call `grokfield', it will
+ perform more stringent semantics checks. */
+ if (TREE_CODE (declarator) == CALL_EXPR)
+ initializer = cp_parser_pure_specifier (parser);
+ else
+ /* Parse the initializer. */
+ initializer = cp_parser_constant_initializer (parser);
+ }
+ /* Otherwise, there is no initializer. */
+ else
+ initializer = NULL_TREE;
+
+ /* See if we are probably looking at a function
+ definition. We are certainly not looking at at a
+ member-declarator. Calling `grokfield' has
+ side-effects, so we must not do it unless we are sure
+ that we are looking at a member-declarator. */
+ if (cp_parser_token_starts_function_definition_p
+ (cp_lexer_peek_token (parser->lexer)))
+ {
+ /* The grammar does not allow a pure-specifier to be
+ used when a member function is defined. (It is
+ possible that this fact is an oversight in the
+ standard, since a pure function may be defined
+ outside of the class-specifier. */
+ if (initializer)
+ error ("pure-specifier on function-definition");
+ decl = cp_parser_save_member_function_body (parser,
+ decl_specifiers,
+ declarator,
+ attributes);
+ /* If the member was not a friend, declare it here. */
+ if (!friend_p)
+ finish_member_declaration (decl);
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If the next token is a semicolon, consume it. */
+ if (token->type == CPP_SEMICOLON)
+ cp_lexer_consume_token (parser->lexer);
+ return;
+ }
+ else
+ {
+ /* Create the declaration. */
+ decl = grokfield (declarator, decl_specifiers,
+ initializer, asm_specification,
+ attributes);
+ /* Any initialization must have been from a
+ constant-expression. */
+ if (decl && TREE_CODE (decl) == VAR_DECL && initializer)
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
+ }
+ }
+
+ /* Reset PREFIX_ATTRIBUTES. */
+ while (attributes && TREE_CHAIN (attributes) != first_attribute)
+ attributes = TREE_CHAIN (attributes);
+ if (attributes)
+ TREE_CHAIN (attributes) = NULL_TREE;
+
+ /* If there is any qualification still in effect, clear it
+ now; we will be starting fresh with the next declarator. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ /* If it's a `,', then there are more declarators. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
+ cp_lexer_consume_token (parser->lexer);
+ /* If the next token isn't a `;', then we have a parse error. */
+ else if (cp_lexer_next_token_is_not (parser->lexer,
+ CPP_SEMICOLON))
+ {
+ cp_parser_error (parser, "expected `;'");
+ /* Skip tokens until we find a `;'. */
+ cp_parser_skip_to_end_of_statement (parser);
+
+ break;
+ }
+
+ if (decl)
+ {
+ /* Add DECL to the list of members. */
+ if (!friend_p)
+ finish_member_declaration (decl);
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ cp_parser_save_default_args (parser, decl);
+ }
+ }
+ }
+
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+}
+
+/* Parse a pure-specifier.
+
+ pure-specifier:
+ = 0
+
+ Returns INTEGER_ZERO_NODE if a pure specifier is found.
+ Otherwise, ERROR_MARK_NODE is returned. */
+
+static tree
+cp_parser_pure_specifier (cp_parser* parser)
+{
+ cp_token *token;
+
+ /* Look for the `=' token. */
+ if (!cp_parser_require (parser, CPP_EQ, "`='"))
+ return error_mark_node;
+ /* Look for the `0' token. */
+ token = cp_parser_require (parser, CPP_NUMBER, "`0'");
+ /* Unfortunately, this will accept `0L' and `0x00' as well. We need
+ to get information from the lexer about how the number was
+ spelled in order to fix this problem. */
+ if (!token || !integer_zerop (token->value))
+ return error_mark_node;
+
+ return integer_zero_node;
+}
+
+/* Parse a constant-initializer.
+
+ constant-initializer:
+ = constant-expression
+
+ Returns a representation of the constant-expression. */
+
+static tree
+cp_parser_constant_initializer (cp_parser* parser)
+{
+ /* Look for the `=' token. */
+ if (!cp_parser_require (parser, CPP_EQ, "`='"))
+ return error_mark_node;
+
+ /* It is invalid to write:
+
+ struct S { static const int i = { 7 }; };
+
+ */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
+ {
+ cp_parser_error (parser,
+ "a brace-enclosed initializer is not allowed here");
+ /* Consume the opening brace. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Skip the initializer. */
+ cp_parser_skip_to_closing_brace (parser);
+ /* Look for the trailing `}'. */
+ cp_parser_require (parser, CPP_CLOSE_BRACE, "`}'");
+
+ return error_mark_node;
+ }
+
+ return cp_parser_constant_expression (parser,
+ /*allow_non_constant=*/false,
+ NULL);
+}
+
+/* Derived classes [gram.class.derived] */
+
+/* Parse a base-clause.
+
+ base-clause:
+ : base-specifier-list
+
+ base-specifier-list:
+ base-specifier
+ base-specifier-list , base-specifier
+
+ Returns a TREE_LIST representing the base-classes, in the order in
+ which they were declared. The representation of each node is as
+ described by cp_parser_base_specifier.
+
+ In the case that no bases are specified, this function will return
+ NULL_TREE, not ERROR_MARK_NODE. */
+
+static tree
+cp_parser_base_clause (cp_parser* parser)
+{
+ tree bases = NULL_TREE;
+
+ /* Look for the `:' that begins the list. */
+ cp_parser_require (parser, CPP_COLON, "`:'");
+
+ /* Scan the base-specifier-list. */
+ while (true)
+ {
+ cp_token *token;
+ tree base;
+
+ /* Look for the base-specifier. */
+ base = cp_parser_base_specifier (parser);
+ /* Add BASE to the front of the list. */
+ if (base != error_mark_node)
+ {
+ TREE_CHAIN (base) = bases;
+ bases = base;
+ }
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not a comma, then the list is complete. */
+ if (token->type != CPP_COMMA)
+ break;
+ /* Consume the `,'. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ /* PARSER->SCOPE may still be non-NULL at this point, if the last
+ base class had a qualified name. However, the next name that
+ appears is certainly not qualified. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+
+ return nreverse (bases);
+}
+
+/* Parse a base-specifier.
+
+ base-specifier:
+ :: [opt] nested-name-specifier [opt] class-name
+ virtual access-specifier [opt] :: [opt] nested-name-specifier
+ [opt] class-name
+ access-specifier virtual [opt] :: [opt] nested-name-specifier
+ [opt] class-name
+
+ Returns a TREE_LIST. The TREE_PURPOSE will be one of
+ ACCESS_{DEFAULT,PUBLIC,PROTECTED,PRIVATE}_[VIRTUAL]_NODE to
+ indicate the specifiers provided. The TREE_VALUE will be a TYPE
+ (or the ERROR_MARK_NODE) indicating the type that was specified. */
+
+static tree
+cp_parser_base_specifier (cp_parser* parser)
+{
+ cp_token *token;
+ bool done = false;
+ bool virtual_p = false;
+ bool duplicate_virtual_error_issued_p = false;
+ bool duplicate_access_error_issued_p = false;
+ bool class_scope_p, template_p;
+ tree access = access_default_node;
+ tree type;
+
+ /* Process the optional `virtual' and `access-specifier'. */
+ while (!done)
+ {
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Process `virtual'. */
+ switch (token->keyword)
+ {
+ case RID_VIRTUAL:
+ /* If `virtual' appears more than once, issue an error. */
+ if (virtual_p && !duplicate_virtual_error_issued_p)
+ {
+ cp_parser_error (parser,
+ "`virtual' specified more than once in base-specified");
+ duplicate_virtual_error_issued_p = true;
+ }
+
+ virtual_p = true;
+
+ /* Consume the `virtual' token. */
+ cp_lexer_consume_token (parser->lexer);
+
+ break;
+
+ case RID_PUBLIC:
+ case RID_PROTECTED:
+ case RID_PRIVATE:
+ /* If more than one access specifier appears, issue an
+ error. */
+ if (access != access_default_node
+ && !duplicate_access_error_issued_p)
+ {
+ cp_parser_error (parser,
+ "more than one access specifier in base-specified");
+ duplicate_access_error_issued_p = true;
+ }
+
+ access = ridpointers[(int) token->keyword];
+
+ /* Consume the access-specifier. */
+ cp_lexer_consume_token (parser->lexer);
+
+ break;
+
+ default:
+ done = true;
+ break;
+ }
+ }
+ /* It is not uncommon to see programs mechanically, errouneously, use
+ the 'typename' keyword to denote (dependent) qualified types
+ as base classes. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
+ {
+ if (!processing_template_decl)
+ error ("keyword `typename' not allowed outside of templates");
+ else
+ error ("keyword `typename' not allowed in this context "
+ "(the base class is implicitly a type)");
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ /* Look for the optional `::' operator. */
+ cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
+ /* Look for the nested-name-specifier. The simplest way to
+ implement:
+
+ [temp.res]
+
+ The keyword `typename' is not permitted in a base-specifier or
+ mem-initializer; in these contexts a qualified name that
+ depends on a template-parameter is implicitly assumed to be a
+ type name.
+
+ is to pretend that we have seen the `typename' keyword at this
+ point. */
+ cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/true,
+ /*check_dependency_p=*/true,
+ /*type_p=*/true,
+ /*is_declaration=*/true);
+ /* If the base class is given by a qualified name, assume that names
+ we see are type names or templates, as appropriate. */
+ class_scope_p = (parser->scope && TYPE_P (parser->scope));
+ template_p = class_scope_p && cp_parser_optional_template_keyword (parser);
+
+ /* Finally, look for the class-name. */
+ type = cp_parser_class_name (parser,
+ class_scope_p,
+ template_p,
+ /*type_p=*/true,
+ /*check_dependency_p=*/true,
+ /*class_head_p=*/false,
+ /*is_declaration=*/true);
+
+ if (type == error_mark_node)
+ return error_mark_node;
+
+ return finish_base_specifier (TREE_TYPE (type), access, virtual_p);
+}
+
+/* Exception handling [gram.exception] */
+
+/* Parse an (optional) exception-specification.
+
+ exception-specification:
+ throw ( type-id-list [opt] )
+
+ Returns a TREE_LIST representing the exception-specification. The
+ TREE_VALUE of each node is a type. */
+
+static tree
+cp_parser_exception_specification_opt (cp_parser* parser)
+{
+ cp_token *token;
+ tree type_id_list;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not `throw', then there's no exception-specification. */
+ if (!cp_parser_is_keyword (token, RID_THROW))
+ return NULL_TREE;
+
+ /* Consume the `throw'. */
+ cp_lexer_consume_token (parser->lexer);
+
+ /* Look for the `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not a `)', then there is a type-id-list. */
+ if (token->type != CPP_CLOSE_PAREN)
+ {
+ const char *saved_message;
+
+ /* Types may not be defined in an exception-specification. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = "types may not be defined in an exception-specification";
+ /* Parse the type-id-list. */
+ type_id_list = cp_parser_type_id_list (parser);
+ /* Restore the saved message. */
+ parser->type_definition_forbidden_message = saved_message;
+ }
+ else
+ type_id_list = empty_except_spec;
+
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+
+ return type_id_list;
+}
+
+/* Parse an (optional) type-id-list.
+
+ type-id-list:
+ type-id
+ type-id-list , type-id
+
+ Returns a TREE_LIST. The TREE_VALUE of each node is a TYPE,
+ in the order that the types were presented. */
+
+static tree
+cp_parser_type_id_list (cp_parser* parser)
+{
+ tree types = NULL_TREE;
+
+ while (true)
+ {
+ cp_token *token;
+ tree type;
+
+ /* Get the next type-id. */
+ type = cp_parser_type_id (parser);
+ /* Add it to the list. */
+ types = add_exception_specifier (types, type, /*complain=*/1);
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it is not a `,', we are done. */
+ if (token->type != CPP_COMMA)
+ break;
+ /* Consume the `,'. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ return nreverse (types);
+}
+
+/* Parse a try-block.
+
+ try-block:
+ try compound-statement handler-seq */
+
+static tree
+cp_parser_try_block (cp_parser* parser)
+{
+ tree try_block;
+
+ cp_parser_require_keyword (parser, RID_TRY, "`try'");
+ try_block = begin_try_block ();
+ cp_parser_compound_statement (parser, false);
+ finish_try_block (try_block);
+ cp_parser_handler_seq (parser);
+ finish_handler_sequence (try_block);
+
+ return try_block;
+}
+
+/* Parse a function-try-block.
+
+ function-try-block:
+ try ctor-initializer [opt] function-body handler-seq */
+
+static bool
+cp_parser_function_try_block (cp_parser* parser)
+{
+ tree try_block;
+ bool ctor_initializer_p;
+
+ /* Look for the `try' keyword. */
+ if (!cp_parser_require_keyword (parser, RID_TRY, "`try'"))
+ return false;
+ /* Let the rest of the front-end know where we are. */
+ try_block = begin_function_try_block ();
+ /* Parse the function-body. */
+ ctor_initializer_p
+ = cp_parser_ctor_initializer_opt_and_function_body (parser);
+ /* We're done with the `try' part. */
+ finish_function_try_block (try_block);
+ /* Parse the handlers. */
+ cp_parser_handler_seq (parser);
+ /* We're done with the handlers. */
+ finish_function_handler_sequence (try_block);
+
+ return ctor_initializer_p;
+}
+
+/* Parse a handler-seq.
+
+ handler-seq:
+ handler handler-seq [opt] */
+
+static void
+cp_parser_handler_seq (cp_parser* parser)
+{
+ while (true)
+ {
+ cp_token *token;
+
+ /* Parse the handler. */
+ cp_parser_handler (parser);
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not `catch' then there are no more handlers. */
+ if (!cp_parser_is_keyword (token, RID_CATCH))
+ break;
+ }
+}
+
+/* Parse a handler.
+
+ handler:
+ catch ( exception-declaration ) compound-statement */
+
+static void
+cp_parser_handler (cp_parser* parser)
+{
+ tree handler;
+ tree declaration;
+
+ cp_parser_require_keyword (parser, RID_CATCH, "`catch'");
+ handler = begin_handler ();
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+ declaration = cp_parser_exception_declaration (parser);
+ finish_handler_parms (declaration, handler);
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ cp_parser_compound_statement (parser, false);
+ finish_handler (handler);
+}
+
+/* Parse an exception-declaration.
+
+ exception-declaration:
+ type-specifier-seq declarator
+ type-specifier-seq abstract-declarator
+ type-specifier-seq
+ ...
+
+ Returns a VAR_DECL for the declaration, or NULL_TREE if the
+ ellipsis variant is used. */
+
+static tree
+cp_parser_exception_declaration (cp_parser* parser)
+{
+ tree type_specifiers;
+ tree declarator;
+ const char *saved_message;
+
+ /* If it's an ellipsis, it's easy to handle. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+ {
+ /* Consume the `...' token. */
+ cp_lexer_consume_token (parser->lexer);
+ return NULL_TREE;
+ }
+
+ /* Types may not be defined in exception-declarations. */
+ saved_message = parser->type_definition_forbidden_message;
+ parser->type_definition_forbidden_message
+ = "types may not be defined in exception-declarations";
+
+ /* Parse the type-specifier-seq. */
+ type_specifiers = cp_parser_type_specifier_seq (parser);
+ /* If it's a `)', then there is no declarator. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
+ declarator = NULL_TREE;
+ else
+ declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER,
+ /*ctor_dtor_or_conv_p=*/NULL,
+ /*parenthesized_p=*/NULL);
+
+ /* Restore the saved message. */
+ parser->type_definition_forbidden_message = saved_message;
+
+ return start_handler_parms (type_specifiers, declarator);
+}
+
+/* Parse a throw-expression.
+
+ throw-expression:
+ throw assignment-expression [opt]
+
+ Returns a THROW_EXPR representing the throw-expression. */
+
+static tree
+cp_parser_throw_expression (cp_parser* parser)
+{
+ tree expression;
+ cp_token* token;
+
+ cp_parser_require_keyword (parser, RID_THROW, "`throw'");
+ token = cp_lexer_peek_token (parser->lexer);
+ /* Figure out whether or not there is an assignment-expression
+ following the "throw" keyword. */
+ if (token->type == CPP_COMMA
+ || token->type == CPP_SEMICOLON
+ || token->type == CPP_CLOSE_PAREN
+ || token->type == CPP_CLOSE_SQUARE
+ || token->type == CPP_CLOSE_BRACE
+ || token->type == CPP_COLON)
+ expression = NULL_TREE;
+ else
+ expression = cp_parser_assignment_expression (parser);
+
+ return build_throw (expression);
+}
+
+/* GNU Extensions */
+
+/* Parse an (optional) asm-specification.
+
+ asm-specification:
+ asm ( string-literal )
+
+ If the asm-specification is present, returns a STRING_CST
+ corresponding to the string-literal. Otherwise, returns
+ NULL_TREE. */
+
+static tree
+cp_parser_asm_specification_opt (cp_parser* parser)
+{
+ cp_token *token;
+ tree asm_specification;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If the next token isn't the `asm' keyword, then there's no
+ asm-specification. */
+ if (!cp_parser_is_keyword (token, RID_ASM))
+ return NULL_TREE;
+
+ /* Consume the `asm' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+
+ /* Look for the string-literal. */
+ token = cp_parser_require (parser, CPP_STRING, "string-literal");
+ if (token)
+ asm_specification = token->value;
+ else
+ asm_specification = NULL_TREE;
+
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`('");
+
+ return asm_specification;
+}
+
+/* Parse an asm-operand-list.
+
+ asm-operand-list:
+ asm-operand
+ asm-operand-list , asm-operand
+
+ asm-operand:
+ string-literal ( expression )
+ [ string-literal ] string-literal ( expression )
+
+ Returns a TREE_LIST representing the operands. The TREE_VALUE of
+ each node is the expression. The TREE_PURPOSE is itself a
+ TREE_LIST whose TREE_PURPOSE is a STRING_CST for the bracketed
+ string-literal (or NULL_TREE if not present) and whose TREE_VALUE
+ is a STRING_CST for the string literal before the parenthesis. */
+
+static tree
+cp_parser_asm_operand_list (cp_parser* parser)
+{
+ tree asm_operands = NULL_TREE;
+
+ while (true)
+ {
+ tree string_literal;
+ tree expression;
+ tree name;
+ cp_token *token;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
+ {
+ /* Consume the `[' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Read the operand name. */
+ name = cp_parser_identifier (parser);
+ if (name != error_mark_node)
+ name = build_string (IDENTIFIER_LENGTH (name),
+ IDENTIFIER_POINTER (name));
+ /* Look for the closing `]'. */
+ cp_parser_require (parser, CPP_CLOSE_SQUARE, "`]'");
+ }
+ else
+ name = NULL_TREE;
+ /* Look for the string-literal. */
+ token = cp_parser_require (parser, CPP_STRING, "string-literal");
+ string_literal = token ? token->value : error_mark_node;
+ /* Look for the `('. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+ /* Parse the expression. */
+ expression = cp_parser_expression (parser);
+ /* Look for the `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ /* Add this operand to the list. */
+ asm_operands = tree_cons (build_tree_list (name, string_literal),
+ expression,
+ asm_operands);
+ /* If the next token is not a `,', there are no more
+ operands. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ /* Consume the `,'. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ return nreverse (asm_operands);
+}
+
+/* Parse an asm-clobber-list.
+
+ asm-clobber-list:
+ string-literal
+ asm-clobber-list , string-literal
+
+ Returns a TREE_LIST, indicating the clobbers in the order that they
+ appeared. The TREE_VALUE of each node is a STRING_CST. */
+
+static tree
+cp_parser_asm_clobber_list (cp_parser* parser)
+{
+ tree clobbers = NULL_TREE;
+
+ while (true)
+ {
+ cp_token *token;
+ tree string_literal;
+
+ /* Look for the string literal. */
+ token = cp_parser_require (parser, CPP_STRING, "string-literal");
+ string_literal = token ? token->value : error_mark_node;
+ /* Add it to the list. */
+ clobbers = tree_cons (NULL_TREE, string_literal, clobbers);
+ /* If the next token is not a `,', then the list is
+ complete. */
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
+ break;
+ /* Consume the `,' token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ return clobbers;
+}
+
+/* Parse an (optional) series of attributes.
+
+ attributes:
+ attributes attribute
+
+ attribute:
+ __attribute__ (( attribute-list [opt] ))
+
+ The return value is as for cp_parser_attribute_list. */
+
+static tree
+cp_parser_attributes_opt (cp_parser* parser)
+{
+ tree attributes = NULL_TREE;
+
+ while (true)
+ {
+ cp_token *token;
+ tree attribute_list;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's not `__attribute__', then we're done. */
+ if (token->keyword != RID_ATTRIBUTE)
+ break;
+
+ /* Consume the `__attribute__' keyword. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the two `(' tokens. */
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+ cp_parser_require (parser, CPP_OPEN_PAREN, "`('");
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type != CPP_CLOSE_PAREN)
+ /* Parse the attribute-list. */
+ attribute_list = cp_parser_attribute_list (parser);
+ else
+ /* If the next token is a `)', then there is no attribute
+ list. */
+ attribute_list = NULL;
+
+ /* Look for the two `)' tokens. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+
+ /* Add these new attributes to the list. */
+ attributes = chainon (attributes, attribute_list);
+ }
+
+ return attributes;
+}
+
+/* Parse an attribute-list.
+
+ attribute-list:
+ attribute
+ attribute-list , attribute
+
+ attribute:
+ identifier
+ identifier ( identifier )
+ identifier ( identifier , expression-list )
+ identifier ( expression-list )
+
+ Returns a TREE_LIST. Each node corresponds to an attribute. THe
+ TREE_PURPOSE of each node is the identifier indicating which
+ attribute is in use. The TREE_VALUE represents the arguments, if
+ any. */
+
+static tree
+cp_parser_attribute_list (cp_parser* parser)
+{
+ tree attribute_list = NULL_TREE;
+
+ while (true)
+ {
+ cp_token *token;
+ tree identifier;
+ tree attribute;
+
+ /* Look for the identifier. We also allow keywords here; for
+ example `__attribute__ ((const))' is legal. */
+ token = cp_lexer_peek_token (parser->lexer);
+ if (token->type != CPP_NAME
+ && token->type != CPP_KEYWORD)
+ return error_mark_node;
+ /* Consume the token. */
+ token = cp_lexer_consume_token (parser->lexer);
+
+ /* Save away the identifier that indicates which attribute this is. */
+ identifier = token->value;
+ attribute = build_tree_list (identifier, NULL_TREE);
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If it's an `(', then parse the attribute arguments. */
+ if (token->type == CPP_OPEN_PAREN)
+ {
+ tree arguments;
+
+ arguments = (cp_parser_parenthesized_expression_list
+ (parser, true, /*non_constant_p=*/NULL));
+ /* Save the identifier and arguments away. */
+ TREE_VALUE (attribute) = arguments;
+ }
+
+ /* Add this attribute to the list. */
+ TREE_CHAIN (attribute) = attribute_list;
+ attribute_list = attribute;
+
+ /* Now, look for more attributes. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If the next token isn't a `,', we're done. */
+ if (token->type != CPP_COMMA)
+ break;
+
+ /* Consume the comma and keep going. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+
+ /* We built up the list in reverse order. */
+ return nreverse (attribute_list);
+}
+
+/* Parse an optional `__extension__' keyword. Returns TRUE if it is
+ present, and FALSE otherwise. *SAVED_PEDANTIC is set to the
+ current value of the PEDANTIC flag, regardless of whether or not
+ the `__extension__' keyword is present. The caller is responsible
+ for restoring the value of the PEDANTIC flag. */
+
+static bool
+cp_parser_extension_opt (cp_parser* parser, int* saved_pedantic)
+{
+ /* Save the old value of the PEDANTIC flag. */
+ *saved_pedantic = pedantic;
+
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXTENSION))
+ {
+ /* Consume the `__extension__' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* We're not being pedantic while the `__extension__' keyword is
+ in effect. */
+ pedantic = 0;
+
+ return true;
+ }
+
+ return false;
+}
+
+/* Parse a label declaration.
+
+ label-declaration:
+ __label__ label-declarator-seq ;
+
+ label-declarator-seq:
+ identifier , label-declarator-seq
+ identifier */
+
+static void
+cp_parser_label_declaration (cp_parser* parser)
+{
+ /* Look for the `__label__' keyword. */
+ cp_parser_require_keyword (parser, RID_LABEL, "`__label__'");
+
+ while (true)
+ {
+ tree identifier;
+
+ /* Look for an identifier. */
+ identifier = cp_parser_identifier (parser);
+ /* Declare it as a lobel. */
+ finish_label_decl (identifier);
+ /* If the next token is a `;', stop. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ break;
+ /* Look for the `,' separating the label declarations. */
+ cp_parser_require (parser, CPP_COMMA, "`,'");
+ }
+
+ /* Look for the final `;'. */
+ cp_parser_require (parser, CPP_SEMICOLON, "`;'");
+}
+
+/* Support Functions */
+
+/* Looks up NAME in the current scope, as given by PARSER->SCOPE.
+ NAME should have one of the representations used for an
+ id-expression. If NAME is the ERROR_MARK_NODE, the ERROR_MARK_NODE
+ is returned. If PARSER->SCOPE is a dependent type, then a
+ SCOPE_REF is returned.
+
+ If NAME is a TEMPLATE_ID_EXPR, then it will be immediately
+ returned; the name was already resolved when the TEMPLATE_ID_EXPR
+ was formed. Abstractly, such entities should not be passed to this
+ function, because they do not need to be looked up, but it is
+ simpler to check for this special case here, rather than at the
+ call-sites.
+
+ In cases not explicitly covered above, this function returns a
+ DECL, OVERLOAD, or baselink representing the result of the lookup.
+ If there was no entity with the indicated NAME, the ERROR_MARK_NODE
+ is returned.
+
+ If IS_TYPE is TRUE, bindings that do not refer to types are
+ ignored.
+
+ If IS_TEMPLATE is TRUE, bindings that do not refer to templates are
+ ignored.
+
+ If IS_NAMESPACE is TRUE, bindings that do not refer to namespaces
+ are ignored.
+
+ If CHECK_DEPENDENCY is TRUE, names are not looked up in dependent
+ types. */
+
+static tree
+cp_parser_lookup_name (cp_parser *parser, tree name,
+ bool is_type, bool is_template, bool is_namespace,
+ bool check_dependency)
+{
+ tree decl;
+ tree object_type = parser->context->object_type;
+
+ /* Now that we have looked up the name, the OBJECT_TYPE (if any) is
+ no longer valid. Note that if we are parsing tentatively, and
+ the parse fails, OBJECT_TYPE will be automatically restored. */
+ parser->context->object_type = NULL_TREE;
+
+ if (name == error_mark_node)
+ return error_mark_node;
+
+ /* A template-id has already been resolved; there is no lookup to
+ do. */
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ return name;
+ if (BASELINK_P (name))
+ {
+ my_friendly_assert ((TREE_CODE (BASELINK_FUNCTIONS (name))
+ == TEMPLATE_ID_EXPR),
+ 20020909);
+ return name;
+ }
+
+ /* A BIT_NOT_EXPR is used to represent a destructor. By this point,
+ it should already have been checked to make sure that the name
+ used matches the type being destroyed. */
+ if (TREE_CODE (name) == BIT_NOT_EXPR)
+ {
+ tree type;
+
+ /* Figure out to which type this destructor applies. */
+ if (parser->scope)
+ type = parser->scope;
+ else if (object_type)
+ type = object_type;
+ else
+ type = current_class_type;
+ /* If that's not a class type, there is no destructor. */
+ if (!type || !CLASS_TYPE_P (type))
+ return error_mark_node;
+ if (!CLASSTYPE_DESTRUCTORS (type))
+ return error_mark_node;
+ /* If it was a class type, return the destructor. */
+ return CLASSTYPE_DESTRUCTORS (type);
+ }
+
+ /* By this point, the NAME should be an ordinary identifier. If
+ the id-expression was a qualified name, the qualifying scope is
+ stored in PARSER->SCOPE at this point. */
+ my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE,
+ 20000619);
+
+ /* Perform the lookup. */
+ if (parser->scope)
+ {
+ bool dependent_p;
+
+ if (parser->scope == error_mark_node)
+ return error_mark_node;
+
+ /* If the SCOPE is dependent, the lookup must be deferred until
+ the template is instantiated -- unless we are explicitly
+ looking up names in uninstantiated templates. Even then, we
+ cannot look up the name if the scope is not a class type; it
+ might, for example, be a template type parameter. */
+ dependent_p = (TYPE_P (parser->scope)
+ && !(parser->in_declarator_p
+ && currently_open_class (parser->scope))
+ && dependent_type_p (parser->scope));
+ if ((check_dependency || !CLASS_TYPE_P (parser->scope))
+ && dependent_p)
+ {
+ if (is_type)
+ /* The resolution to Core Issue 180 says that `struct A::B'
+ should be considered a type-name, even if `A' is
+ dependent. */
+ decl = TYPE_NAME (make_typename_type (parser->scope,
+ name,
+ /*complain=*/1));
+ else if (is_template)
+ decl = make_unbound_class_template (parser->scope,
+ name,
+ /*complain=*/1);
+ else
+ decl = build_nt (SCOPE_REF, parser->scope, name);
+ }
+ else
+ {
+ bool pop_p = false;
+
+ /* If PARSER->SCOPE is a dependent type, then it must be a
+ class type, and we must not be checking dependencies;
+ otherwise, we would have processed this lookup above. So
+ that PARSER->SCOPE is not considered a dependent base by
+ lookup_member, we must enter the scope here. */
+ if (dependent_p)
+ pop_p = push_scope (parser->scope);
+ /* If the PARSER->SCOPE is a a template specialization, it
+ may be instantiated during name lookup. In that case,
+ errors may be issued. Even if we rollback the current
+ tentative parse, those errors are valid. */
+ decl = lookup_qualified_name (parser->scope, name, is_type,
+ /*complain=*/true);
+ if (pop_p)
+ pop_scope (parser->scope);
+ }
+ parser->qualifying_scope = parser->scope;
+ parser->object_scope = NULL_TREE;
+ }
+ else if (object_type)
+ {
+ tree object_decl = NULL_TREE;
+ /* Look up the name in the scope of the OBJECT_TYPE, unless the
+ OBJECT_TYPE is not a class. */
+ if (CLASS_TYPE_P (object_type))
+ /* If the OBJECT_TYPE is a template specialization, it may
+ be instantiated during name lookup. In that case, errors
+ may be issued. Even if we rollback the current tentative
+ parse, those errors are valid. */
+ object_decl = lookup_member (object_type,
+ name,
+ /*protect=*/0, is_type);
+ /* Look it up in the enclosing context, too. */
+ decl = lookup_name_real (name, is_type, /*nonclass=*/0,
+ is_namespace,
+ /*flags=*/0);
+ parser->object_scope = object_type;
+ parser->qualifying_scope = NULL_TREE;
+ if (object_decl)
+ decl = object_decl;
+ }
+ else
+ {
+ decl = lookup_name_real (name, is_type, /*nonclass=*/0,
+ is_namespace,
+ /*flags=*/0);
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ }
+
+ /* If the lookup failed, let our caller know. */
+ if (!decl
+ || decl == error_mark_node
+ || (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_ANTICIPATED (decl)))
+ return error_mark_node;
+
+ /* If it's a TREE_LIST, the result of the lookup was ambiguous. */
+ if (TREE_CODE (decl) == TREE_LIST)
+ {
+ /* The error message we have to print is too complicated for
+ cp_parser_error, so we incorporate its actions directly. */
+ if (!cp_parser_simulate_error (parser))
+ {
+ error ("reference to `%D' is ambiguous", name);
+ print_candidates (decl);
+ }
+ return error_mark_node;
+ }
+
+ my_friendly_assert (DECL_P (decl)
+ || TREE_CODE (decl) == OVERLOAD
+ || TREE_CODE (decl) == SCOPE_REF
+ || TREE_CODE (decl) == UNBOUND_CLASS_TEMPLATE
+ || BASELINK_P (decl),
+ 20000619);
+
+ /* If we have resolved the name of a member declaration, check to
+ see if the declaration is accessible. When the name resolves to
+ set of overloaded functions, accessibility is checked when
+ overload resolution is done.
+
+ During an explicit instantiation, access is not checked at all,
+ as per [temp.explicit]. */
+ if (DECL_P (decl))
+ check_accessibility_of_qualified_id (decl, object_type, parser->scope);
+
+ return decl;
+}
+
+/* Like cp_parser_lookup_name, but for use in the typical case where
+ CHECK_ACCESS is TRUE, IS_TYPE is FALSE, IS_TEMPLATE is FALSE,
+ IS_NAMESPACE is FALSE, and CHECK_DEPENDENCY is TRUE. */
+
+static tree
+cp_parser_lookup_name_simple (cp_parser* parser, tree name)
+{
+ return cp_parser_lookup_name (parser, name,
+ /*is_type=*/false,
+ /*is_template=*/false,
+ /*is_namespace=*/false,
+ /*check_dependency=*/true);
+}
+
+/* If DECL is a TEMPLATE_DECL that can be treated like a TYPE_DECL in
+ the current context, return the TYPE_DECL. If TAG_NAME_P is
+ true, the DECL indicates the class being defined in a class-head,
+ or declared in an elaborated-type-specifier.
+
+ Otherwise, return DECL. */
+
+static tree
+cp_parser_maybe_treat_template_as_class (tree decl, bool tag_name_p)
+{
+ /* If the TEMPLATE_DECL is being declared as part of a class-head,
+ the translation from TEMPLATE_DECL to TYPE_DECL occurs:
+
+ struct A {
+ template <typename T> struct B;
+ };
+
+ template <typename T> struct A::B {};
+
+ Similarly, in a elaborated-type-specifier:
+
+ namespace N { struct X{}; }
+
+ struct A {
+ template <typename T> friend struct N::X;
+ };
+
+ However, if the DECL refers to a class type, and we are in
+ the scope of the class, then the name lookup automatically
+ finds the TYPE_DECL created by build_self_reference rather
+ than a TEMPLATE_DECL. For example, in:
+
+ template <class T> struct S {
+ S s;
+ };
+
+ there is no need to handle such case. */
+
+ if (DECL_CLASS_TEMPLATE_P (decl) && tag_name_p)
+ return DECL_TEMPLATE_RESULT (decl);
+
+ return decl;
+}
+
+/* If too many, or too few, template-parameter lists apply to the
+ declarator, issue an error message. Returns TRUE if all went well,
+ and FALSE otherwise. */
+
+static bool
+cp_parser_check_declarator_template_parameters (cp_parser* parser,
+ tree declarator)
+{
+ unsigned num_templates;
+
+ /* We haven't seen any classes that involve template parameters yet. */
+ num_templates = 0;
+
+ switch (TREE_CODE (declarator))
+ {
+ case CALL_EXPR:
+ case ARRAY_REF:
+ case INDIRECT_REF:
+ case ADDR_EXPR:
+ {
+ tree main_declarator = TREE_OPERAND (declarator, 0);
+ return
+ cp_parser_check_declarator_template_parameters (parser,
+ main_declarator);
+ }
+
+ case SCOPE_REF:
+ {
+ tree scope;
+ tree member;
+
+ scope = TREE_OPERAND (declarator, 0);
+ member = TREE_OPERAND (declarator, 1);
+
+ /* If this is a pointer-to-member, then we are not interested
+ in the SCOPE, because it does not qualify the thing that is
+ being declared. */
+ if (TREE_CODE (member) == INDIRECT_REF)
+ return (cp_parser_check_declarator_template_parameters
+ (parser, member));
+
+ while (scope && CLASS_TYPE_P (scope))
+ {
+ /* You're supposed to have one `template <...>'
+ for every template class, but you don't need one
+ for a full specialization. For example:
+
+ template <class T> struct S{};
+ template <> struct S<int> { void f(); };
+ void S<int>::f () {}
+
+ is correct; there shouldn't be a `template <>' for
+ the definition of `S<int>::f'. */
+ if (CLASSTYPE_TEMPLATE_INFO (scope)
+ && (CLASSTYPE_TEMPLATE_INSTANTIATION (scope)
+ || uses_template_parms (CLASSTYPE_TI_ARGS (scope)))
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (scope)))
+ ++num_templates;
+
+ scope = TYPE_CONTEXT (scope);
+ }
+ }
+
+ /* Fall through. */
+
+ default:
+ /* If the DECLARATOR has the form `X<y>' then it uses one
+ additional level of template parameters. */
+ if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
+ ++num_templates;
+
+ return cp_parser_check_template_parameters (parser,
+ num_templates);
+ }
+}
+
+/* NUM_TEMPLATES were used in the current declaration. If that is
+ invalid, return FALSE and issue an error messages. Otherwise,
+ return TRUE. */
+
+static bool
+cp_parser_check_template_parameters (cp_parser* parser,
+ unsigned num_templates)
+{
+ /* If there are more template classes than parameter lists, we have
+ something like:
+
+ template <class T> void S<T>::R<T>::f (); */
+ if (parser->num_template_parameter_lists < num_templates)
+ {
+ error ("too few template-parameter-lists");
+ return false;
+ }
+ /* If there are the same number of template classes and parameter
+ lists, that's OK. */
+ if (parser->num_template_parameter_lists == num_templates)
+ return true;
+ /* If there are more, but only one more, then we are referring to a
+ member template. That's OK too. */
+ if (parser->num_template_parameter_lists == num_templates + 1)
+ return true;
+ /* Otherwise, there are too many template parameter lists. We have
+ something like:
+
+ template <class T> template <class U> void S::f(); */
+ error ("too many template-parameter-lists");
+ return false;
+}
+
+/* Parse a binary-expression of the general form:
+
+ binary-expression:
+ <expr>
+ binary-expression <token> <expr>
+
+ The TOKEN_TREE_MAP maps <token> types to <expr> codes. FN is used
+ to parser the <expr>s. If the first production is used, then the
+ value returned by FN is returned directly. Otherwise, a node with
+ the indicated EXPR_TYPE is returned, with operands corresponding to
+ the two sub-expressions. */
+
+static tree
+cp_parser_binary_expression (cp_parser* parser,
+ const cp_parser_token_tree_map token_tree_map,
+ cp_parser_expression_fn fn)
+{
+ tree lhs;
+
+ /* Parse the first expression. */
+ lhs = (*fn) (parser);
+ /* Now, look for more expressions. */
+ while (true)
+ {
+ cp_token *token;
+ const cp_parser_token_tree_map_node *map_node;
+ tree rhs;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If the token is `>', and that's not an operator at the
+ moment, then we're done. */
+ if (token->type == CPP_GREATER
+ && !parser->greater_than_is_operator_p)
+ break;
+ /* If we find one of the tokens we want, build the corresponding
+ tree representation. */
+ for (map_node = token_tree_map;
+ map_node->token_type != CPP_EOF;
+ ++map_node)
+ if (map_node->token_type == token->type)
+ {
+ /* Assume that an overloaded operator will not be used. */
+ bool overloaded_p = false;
+
+ /* Consume the operator token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the right-hand side of the expression. */
+ rhs = (*fn) (parser);
+ /* Build the binary tree node. */
+ lhs = build_x_binary_op (map_node->tree_type, lhs, rhs,
+ &overloaded_p);
+ /* If the binary operator required the use of an
+ overloaded operator, then this expression cannot be an
+ integral constant-expression. An overloaded operator
+ can be used even if both operands are otherwise
+ permissible in an integral constant-expression if at
+ least one of the operands is of enumeration type. */
+ if (overloaded_p
+ && (cp_parser_non_integral_constant_expression
+ (parser, "calls to overloaded operators")))
+ lhs = error_mark_node;
+ break;
+ }
+
+ /* If the token wasn't one of the ones we want, we're done. */
+ if (map_node->token_type == CPP_EOF)
+ break;
+ }
+
+ return lhs;
+}
+
+/* Parse an optional `::' token indicating that the following name is
+ from the global namespace. If so, PARSER->SCOPE is set to the
+ GLOBAL_NAMESPACE. Otherwise, PARSER->SCOPE is set to NULL_TREE,
+ unless CURRENT_SCOPE_VALID_P is TRUE, in which case it is left alone.
+ Returns the new value of PARSER->SCOPE, if the `::' token is
+ present, and NULL_TREE otherwise. */
+
+static tree
+cp_parser_global_scope_opt (cp_parser* parser, bool current_scope_valid_p)
+{
+ cp_token *token;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If we're looking at a `::' token then we're starting from the
+ global namespace, not our current location. */
+ if (token->type == CPP_SCOPE)
+ {
+ /* Consume the `::' token. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Set the SCOPE so that we know where to start the lookup. */
+ parser->scope = global_namespace;
+ parser->qualifying_scope = global_namespace;
+ parser->object_scope = NULL_TREE;
+
+ return parser->scope;
+ }
+ else if (!current_scope_valid_p)
+ {
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ }
+
+ return NULL_TREE;
+}
+
+/* Returns TRUE if the upcoming token sequence is the start of a
+ constructor declarator. If FRIEND_P is true, the declarator is
+ preceded by the `friend' specifier. */
+
+static bool
+cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p)
+{
+ bool constructor_p;
+ tree type_decl = NULL_TREE;
+ bool nested_name_p;
+ cp_token *next_token;
+
+ /* The common case is that this is not a constructor declarator, so
+ try to avoid doing lots of work if at all possible. It's not
+ valid declare a constructor at function scope. */
+ if (at_function_scope_p ())
+ return false;
+ /* And only certain tokens can begin a constructor declarator. */
+ next_token = cp_lexer_peek_token (parser->lexer);
+ if (next_token->type != CPP_NAME
+ && next_token->type != CPP_SCOPE
+ && next_token->type != CPP_NESTED_NAME_SPECIFIER
+ && next_token->type != CPP_TEMPLATE_ID)
+ return false;
+
+ /* Parse tentatively; we are going to roll back all of the tokens
+ consumed here. */
+ cp_parser_parse_tentatively (parser);
+ /* Assume that we are looking at a constructor declarator. */
+ constructor_p = true;
+
+ /* Look for the optional `::' operator. */
+ cp_parser_global_scope_opt (parser,
+ /*current_scope_valid_p=*/false);
+ /* Look for the nested-name-specifier. */
+ nested_name_p
+ = (cp_parser_nested_name_specifier_opt (parser,
+ /*typename_keyword_p=*/false,
+ /*check_dependency_p=*/false,
+ /*type_p=*/false,
+ /*is_declaration=*/false)
+ != NULL_TREE);
+ /* Outside of a class-specifier, there must be a
+ nested-name-specifier. */
+ if (!nested_name_p &&
+ (!at_class_scope_p () || !TYPE_BEING_DEFINED (current_class_type)
+ || friend_p))
+ constructor_p = false;
+ /* If we still think that this might be a constructor-declarator,
+ look for a class-name. */
+ if (constructor_p)
+ {
+ /* If we have:
+
+ template <typename T> struct S { S(); };
+ template <typename T> S<T>::S ();
+
+ we must recognize that the nested `S' names a class.
+ Similarly, for:
+
+ template <typename T> S<T>::S<T> ();
+
+ we must recognize that the nested `S' names a template. */
+ type_decl = cp_parser_class_name (parser,
+ /*typename_keyword_p=*/false,
+ /*template_keyword_p=*/false,
+ /*type_p=*/false,
+ /*check_dependency_p=*/false,
+ /*class_head_p=*/false,
+ /*is_declaration=*/false);
+ /* If there was no class-name, then this is not a constructor. */
+ constructor_p = !cp_parser_error_occurred (parser);
+ }
+
+ /* If we're still considering a constructor, we have to see a `(',
+ to begin the parameter-declaration-clause, followed by either a
+ `)', an `...', or a decl-specifier. We need to check for a
+ type-specifier to avoid being fooled into thinking that:
+
+ S::S (f) (int);
+
+ is a constructor. (It is actually a function named `f' that
+ takes one parameter (of type `int') and returns a value of type
+ `S::S'. */
+ if (constructor_p
+ && cp_parser_require (parser, CPP_OPEN_PAREN, "`('"))
+ {
+ if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_ELLIPSIS)
+ /* A parameter declaration begins with a decl-specifier,
+ which is either the "attribute" keyword, a storage class
+ specifier, or (usually) a type-specifier. */
+ && !cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE)
+ && !cp_parser_storage_class_specifier_opt (parser))
+ {
+ tree type;
+ bool pop_p = false;
+ unsigned saved_num_template_parameter_lists;
+
+ /* Names appearing in the type-specifier should be looked up
+ in the scope of the class. */
+ if (current_class_type)
+ type = NULL_TREE;
+ else
+ {
+ type = TREE_TYPE (type_decl);
+ if (TREE_CODE (type) == TYPENAME_TYPE)
+ {
+ type = resolve_typename_type (type,
+ /*only_current_p=*/false);
+ if (type == error_mark_node)
+ {
+ cp_parser_abort_tentative_parse (parser);
+ return false;
+ }
+ }
+ pop_p = push_scope (type);
+ }
+
+ /* Inside the constructor parameter list, surrounding
+ template-parameter-lists do not apply. */
+ saved_num_template_parameter_lists
+ = parser->num_template_parameter_lists;
+ parser->num_template_parameter_lists = 0;
+
+ /* Look for the type-specifier. */
+ cp_parser_type_specifier (parser,
+ CP_PARSER_FLAGS_NONE,
+ /*is_friend=*/false,
+ /*is_declarator=*/true,
+ /*declares_class_or_enum=*/NULL,
+ /*is_cv_qualifier=*/NULL);
+
+ parser->num_template_parameter_lists
+ = saved_num_template_parameter_lists;
+
+ /* Leave the scope of the class. */
+ if (pop_p)
+ pop_scope (type);
+
+ constructor_p = !cp_parser_error_occurred (parser);
+ }
+ }
+ else
+ constructor_p = false;
+ /* We did not really want to consume any tokens. */
+ cp_parser_abort_tentative_parse (parser);
+
+ return constructor_p;
+}
+
+/* Parse the definition of the function given by the DECL_SPECIFIERS,
+ ATTRIBUTES, and DECLARATOR. The access checks have been deferred;
+ they must be performed once we are in the scope of the function.
+
+ Returns the function defined. */
+
+static tree
+cp_parser_function_definition_from_specifiers_and_declarator
+ (cp_parser* parser,
+ tree decl_specifiers,
+ tree attributes,
+ tree declarator)
+{
+ tree fn;
+ bool success_p;
+
+ /* Begin the function-definition. */
+ success_p = begin_function_definition (decl_specifiers,
+ attributes,
+ declarator);
+
+ /* If there were names looked up in the decl-specifier-seq that we
+ did not check, check them now. We must wait until we are in the
+ scope of the function to perform the checks, since the function
+ might be a friend. */
+ perform_deferred_access_checks ();
+
+ if (!success_p)
+ {
+ /* If begin_function_definition didn't like the definition, skip
+ the entire function. */
+ error ("invalid function declaration");
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ fn = error_mark_node;
+ }
+ else
+ fn = cp_parser_function_definition_after_declarator (parser,
+ /*inline_p=*/false);
+
+ return fn;
+}
+
+/* Parse the part of a function-definition that follows the
+ declarator. INLINE_P is TRUE iff this function is an inline
+ function defined with a class-specifier.
+
+ Returns the function defined. */
+
+static tree
+cp_parser_function_definition_after_declarator (cp_parser* parser,
+ bool inline_p)
+{
+ tree fn;
+ bool ctor_initializer_p = false;
+ bool saved_in_unbraced_linkage_specification_p;
+ unsigned saved_num_template_parameter_lists;
+
+ /* If the next token is `return', then the code may be trying to
+ make use of the "named return value" extension that G++ used to
+ support. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_RETURN))
+ {
+ /* Consume the `return' keyword. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Look for the identifier that indicates what value is to be
+ returned. */
+ cp_parser_identifier (parser);
+ /* Issue an error message. */
+ error ("named return values are no longer supported");
+ /* Skip tokens until we reach the start of the function body. */
+ while (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_EOF))
+ cp_lexer_consume_token (parser->lexer);
+ }
+ /* The `extern' in `extern "C" void f () { ... }' does not apply to
+ anything declared inside `f'. */
+ saved_in_unbraced_linkage_specification_p
+ = parser->in_unbraced_linkage_specification_p;
+ parser->in_unbraced_linkage_specification_p = false;
+ /* Inside the function, surrounding template-parameter-lists do not
+ apply. */
+ saved_num_template_parameter_lists
+ = parser->num_template_parameter_lists;
+ parser->num_template_parameter_lists = 0;
+ /* If the next token is `try', then we are looking at a
+ function-try-block. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
+ ctor_initializer_p = cp_parser_function_try_block (parser);
+ /* A function-try-block includes the function-body, so we only do
+ this next part if we're not processing a function-try-block. */
+ else
+ ctor_initializer_p
+ = cp_parser_ctor_initializer_opt_and_function_body (parser);
+
+ /* Finish the function. */
+ fn = finish_function ((ctor_initializer_p ? 1 : 0) |
+ (inline_p ? 2 : 0));
+ /* Generate code for it, if necessary. */
+ expand_or_defer_fn (fn);
+ /* Restore the saved values. */
+ parser->in_unbraced_linkage_specification_p
+ = saved_in_unbraced_linkage_specification_p;
+ parser->num_template_parameter_lists
+ = saved_num_template_parameter_lists;
+
+ return fn;
+}
+
+/* Parse a template-declaration, assuming that the `export' (and
+ `extern') keywords, if present, has already been scanned. MEMBER_P
+ is as for cp_parser_template_declaration. */
+
+static void
+cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
+{
+ tree decl = NULL_TREE;
+ tree parameter_list;
+ bool friend_p = false;
+
+ /* Look for the `template' keyword. */
+ if (!cp_parser_require_keyword (parser, RID_TEMPLATE, "`template'"))
+ return;
+
+ /* And the `<'. */
+ if (!cp_parser_require (parser, CPP_LESS, "`<'"))
+ return;
+
+ /* If the next token is `>', then we have an invalid
+ specialization. Rather than complain about an invalid template
+ parameter, issue an error message here. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER))
+ {
+ cp_parser_error (parser, "invalid explicit specialization");
+ begin_specialization ();
+ parameter_list = NULL_TREE;
+ }
+ else
+ {
+ /* Parse the template parameters. */
+ begin_template_parm_list ();
+ parameter_list = cp_parser_template_parameter_list (parser);
+ parameter_list = end_template_parm_list (parameter_list);
+ }
+
+ /* Look for the `>'. */
+ cp_parser_skip_until_found (parser, CPP_GREATER, "`>'");
+ /* We just processed one more parameter list. */
+ ++parser->num_template_parameter_lists;
+ /* If the next token is `template', there are more template
+ parameters. */
+ if (cp_lexer_next_token_is_keyword (parser->lexer,
+ RID_TEMPLATE))
+ cp_parser_template_declaration_after_export (parser, member_p);
+ else
+ {
+ decl = cp_parser_single_declaration (parser,
+ member_p,
+ &friend_p);
+
+ /* If this is a member template declaration, let the front
+ end know. */
+ if (member_p && !friend_p && decl)
+ {
+ if (TREE_CODE (decl) == TYPE_DECL)
+ cp_parser_check_access_in_redeclaration (decl);
+
+ decl = finish_member_template_decl (decl);
+ }
+ else if (friend_p && decl && TREE_CODE (decl) == TYPE_DECL)
+ make_friend_class (current_class_type, TREE_TYPE (decl),
+ /*complain=*/true);
+ }
+ /* We are done with the current parameter list. */
+ --parser->num_template_parameter_lists;
+
+ /* Finish up. */
+ finish_template_decl (parameter_list);
+
+ /* Register member declarations. */
+ if (member_p && !friend_p && decl && !DECL_CLASS_TEMPLATE_P (decl))
+ finish_member_declaration (decl);
+
+ /* If DECL is a function template, we must return to parse it later.
+ (Even though there is no definition, there might be default
+ arguments that need handling.) */
+ if (member_p && decl
+ && (TREE_CODE (decl) == FUNCTION_DECL
+ || DECL_FUNCTION_TEMPLATE_P (decl)))
+ TREE_VALUE (parser->unparsed_functions_queues)
+ = tree_cons (NULL_TREE, decl,
+ TREE_VALUE (parser->unparsed_functions_queues));
+}
+
+/* Parse a `decl-specifier-seq [opt] init-declarator [opt] ;' or
+ `function-definition' sequence. MEMBER_P is true, this declaration
+ appears in a class scope.
+
+ Returns the DECL for the declared entity. If FRIEND_P is non-NULL,
+ *FRIEND_P is set to TRUE iff the declaration is a friend. */
+
+static tree
+cp_parser_single_declaration (cp_parser* parser,
+ bool member_p,
+ bool* friend_p)
+{
+ int declares_class_or_enum;
+ tree decl = NULL_TREE;
+ tree decl_specifiers;
+ tree attributes;
+ bool function_definition_p = false;
+
+ /* Defer access checks until we know what is being declared. */
+ push_deferring_access_checks (dk_deferred);
+
+ /* Try the `decl-specifier-seq [opt] init-declarator [opt]'
+ alternative. */
+ decl_specifiers
+ = cp_parser_decl_specifier_seq (parser,
+ CP_PARSER_FLAGS_OPTIONAL,
+ &attributes,
+ &declares_class_or_enum);
+ if (friend_p)
+ *friend_p = cp_parser_friend_p (decl_specifiers);
+ /* Gather up the access checks that occurred the
+ decl-specifier-seq. */
+ stop_deferring_access_checks ();
+
+ /* Check for the declaration of a template class. */
+ if (declares_class_or_enum)
+ {
+ if (cp_parser_declares_only_class_p (parser))
+ {
+ decl = shadow_tag (decl_specifiers);
+ if (decl)
+ decl = TYPE_NAME (decl);
+ else
+ decl = error_mark_node;
+ }
+ }
+ else
+ decl = NULL_TREE;
+ /* If it's not a template class, try for a template function. If
+ the next token is a `;', then this declaration does not declare
+ anything. But, if there were errors in the decl-specifiers, then
+ the error might well have come from an attempted class-specifier.
+ In that case, there's no need to warn about a missing declarator. */
+ if (!decl
+ && (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
+ || !value_member (error_mark_node, decl_specifiers)))
+ decl = cp_parser_init_declarator (parser,
+ decl_specifiers,
+ attributes,
+ /*function_definition_allowed_p=*/true,
+ member_p,
+ declares_class_or_enum,
+ &function_definition_p);
+
+ pop_deferring_access_checks ();
+
+ /* Clear any current qualification; whatever comes next is the start
+ of something new. */
+ parser->scope = NULL_TREE;
+ parser->qualifying_scope = NULL_TREE;
+ parser->object_scope = NULL_TREE;
+ /* Look for a trailing `;' after the declaration. */
+ if (!function_definition_p
+ && !cp_parser_require (parser, CPP_SEMICOLON, "`;'"))
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+
+ return decl;
+}
+
+/* Parse a cast-expression that is not the operand of a unary "&". */
+
+static tree
+cp_parser_simple_cast_expression (cp_parser *parser)
+{
+ return cp_parser_cast_expression (parser, /*address_p=*/false);
+}
+
+/* Parse a functional cast to TYPE. Returns an expression
+ representing the cast. */
+
+static tree
+cp_parser_functional_cast (cp_parser* parser, tree type)
+{
+ tree expression_list;
+ tree cast;
+
+ expression_list
+ = cp_parser_parenthesized_expression_list (parser, false,
+ /*non_constant_p=*/NULL);
+
+ cast = build_functional_cast (type, expression_list);
+ /* [expr.const]/1: In an integral constant expression "only type
+ conversions to integral or enumeration type can be used". */
+ if (cast != error_mark_node && !type_dependent_expression_p (type)
+ && !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (type)))
+ {
+ if (cp_parser_non_integral_constant_expression
+ (parser, "a call to a constructor"))
+ return error_mark_node;
+ }
+ return cast;
+}
+
+/* Save the tokens that make up the body of a member function defined
+ in a class-specifier. The DECL_SPECIFIERS and DECLARATOR have
+ already been parsed. The ATTRIBUTES are any GNU "__attribute__"
+ specifiers applied to the declaration. Returns the FUNCTION_DECL
+ for the member function. */
+
+static tree
+cp_parser_save_member_function_body (cp_parser* parser,
+ tree decl_specifiers,
+ tree declarator,
+ tree attributes)
+{
+ cp_token_cache *cache;
+ tree fn;
+
+ /* Create the function-declaration. */
+ fn = start_method (decl_specifiers, declarator, attributes);
+ /* If something went badly wrong, bail out now. */
+ if (fn == error_mark_node)
+ {
+ /* If there's a function-body, skip it. */
+ if (cp_parser_token_starts_function_definition_p
+ (cp_lexer_peek_token (parser->lexer)))
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return error_mark_node;
+ }
+
+ /* Remember it, if there default args to post process. */
+ cp_parser_save_default_args (parser, fn);
+
+ /* Create a token cache. */
+ cache = cp_token_cache_new ();
+ /* Save away the tokens that make up the body of the
+ function. */
+ cp_parser_cache_group (parser, cache, CPP_CLOSE_BRACE, /*depth=*/0);
+ /* Handle function try blocks. */
+ while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH))
+ cp_parser_cache_group (parser, cache, CPP_CLOSE_BRACE, /*depth=*/0);
+
+ /* Save away the inline definition; we will process it when the
+ class is complete. */
+ DECL_PENDING_INLINE_INFO (fn) = cache;
+ DECL_PENDING_INLINE_P (fn) = 1;
+
+ /* We need to know that this was defined in the class, so that
+ friend templates are handled correctly. */
+ DECL_INITIALIZED_IN_CLASS_P (fn) = 1;
+
+ /* We're done with the inline definition. */
+ finish_method (fn);
+
+ /* Add FN to the queue of functions to be parsed later. */
+ TREE_VALUE (parser->unparsed_functions_queues)
+ = tree_cons (NULL_TREE, fn,
+ TREE_VALUE (parser->unparsed_functions_queues));
+
+ return fn;
+}
+
+/* Parse a template-argument-list, as well as the trailing ">" (but
+ not the opening ">"). See cp_parser_template_argument_list for the
+ return value. */
+
+static tree
+cp_parser_enclosed_template_argument_list (cp_parser* parser)
+{
+ tree arguments;
+ tree saved_scope;
+ tree saved_qualifying_scope;
+ tree saved_object_scope;
+ bool saved_greater_than_is_operator_p;
+
+ /* [temp.names]
+
+ When parsing a template-id, the first non-nested `>' is taken as
+ the end of the template-argument-list rather than a greater-than
+ operator. */
+ saved_greater_than_is_operator_p
+ = parser->greater_than_is_operator_p;
+ parser->greater_than_is_operator_p = false;
+ /* Parsing the argument list may modify SCOPE, so we save it
+ here. */
+ saved_scope = parser->scope;
+ saved_qualifying_scope = parser->qualifying_scope;
+ saved_object_scope = parser->object_scope;
+ /* Parse the template-argument-list itself. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER))
+ arguments = NULL_TREE;
+ else
+ arguments = cp_parser_template_argument_list (parser);
+ /* Look for the `>' that ends the template-argument-list. If we find
+ a '>>' instead, it's probably just a typo. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT))
+ {
+ if (!saved_greater_than_is_operator_p)
+ {
+ /* If we're in a nested template argument list, the '>>' has to be
+ a typo for '> >'. We emit the error message, but we continue
+ parsing and we push a '>' as next token, so that the argument
+ list will be parsed correctly.. */
+ cp_token* token;
+ error ("`>>' should be `> >' within a nested template argument list");
+ token = cp_lexer_peek_token (parser->lexer);
+ token->type = CPP_GREATER;
+ }
+ else
+ {
+ /* If this is not a nested template argument list, the '>>' is
+ a typo for '>'. Emit an error message and continue. */
+ error ("spurious `>>', use `>' to terminate a template argument list");
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
+ else if (!cp_parser_require (parser, CPP_GREATER, "`>'"))
+ error ("missing `>' to terminate the template argument list");
+ /* The `>' token might be a greater-than operator again now. */
+ parser->greater_than_is_operator_p
+ = saved_greater_than_is_operator_p;
+ /* Restore the SAVED_SCOPE. */
+ parser->scope = saved_scope;
+ parser->qualifying_scope = saved_qualifying_scope;
+ parser->object_scope = saved_object_scope;
+
+ return arguments;
+}
+
+/* MEMBER_FUNCTION is a member function, or a friend. If default
+ arguments, or the body of the function have not yet been parsed,
+ parse them now. */
+
+static void
+cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
+{
+ cp_lexer *saved_lexer;
+
+ /* If this member is a template, get the underlying
+ FUNCTION_DECL. */
+ if (DECL_FUNCTION_TEMPLATE_P (member_function))
+ member_function = DECL_TEMPLATE_RESULT (member_function);
+
+ /* There should not be any class definitions in progress at this
+ point; the bodies of members are only parsed outside of all class
+ definitions. */
+ my_friendly_assert (parser->num_classes_being_defined == 0, 20010816);
+ /* While we're parsing the member functions we might encounter more
+ classes. We want to handle them right away, but we don't want
+ them getting mixed up with functions that are currently in the
+ queue. */
+ parser->unparsed_functions_queues
+ = tree_cons (NULL_TREE, NULL_TREE, parser->unparsed_functions_queues);
+
+ /* Make sure that any template parameters are in scope. */
+ maybe_begin_member_template_processing (member_function);
+
+ /* If the body of the function has not yet been parsed, parse it
+ now. */
+ if (DECL_PENDING_INLINE_P (member_function))
+ {
+ tree function_scope;
+ cp_token_cache *tokens;
+
+ /* The function is no longer pending; we are processing it. */
+ tokens = DECL_PENDING_INLINE_INFO (member_function);
+ DECL_PENDING_INLINE_INFO (member_function) = NULL;
+ DECL_PENDING_INLINE_P (member_function) = 0;
+ /* If this was an inline function in a local class, enter the scope
+ of the containing function. */
+ function_scope = decl_function_context (member_function);
+ if (function_scope)
+ push_function_context_to (function_scope);
+
+ /* Save away the current lexer. */
+ saved_lexer = parser->lexer;
+ /* Make a new lexer to feed us the tokens saved for this function. */
+ parser->lexer = cp_lexer_new_from_tokens (tokens);
+ parser->lexer->next = saved_lexer;
+
+ /* Set the current source position to be the location of the first
+ token in the saved inline body. */
+ cp_lexer_peek_token (parser->lexer);
+
+ /* Let the front end know that we going to be defining this
+ function. */
+ start_function (NULL_TREE, member_function, NULL_TREE,
+ SF_PRE_PARSED | SF_INCLASS_INLINE);
+
+ /* Now, parse the body of the function. */
+ cp_parser_function_definition_after_declarator (parser,
+ /*inline_p=*/true);
+
+ /* Leave the scope of the containing function. */
+ if (function_scope)
+ pop_function_context_from (function_scope);
+ /* Restore the lexer. */
+ parser->lexer = saved_lexer;
+ }
+
+ /* Remove any template parameters from the symbol table. */
+ maybe_end_member_template_processing ();
+
+ /* Restore the queue. */
+ parser->unparsed_functions_queues
+ = TREE_CHAIN (parser->unparsed_functions_queues);
+}
+
+/* If DECL contains any default args, remember it on the unparsed
+ functions queue. */
+
+static void
+cp_parser_save_default_args (cp_parser* parser, tree decl)
+{
+ tree probe;
+
+ for (probe = TYPE_ARG_TYPES (TREE_TYPE (decl));
+ probe;
+ probe = TREE_CHAIN (probe))
+ if (TREE_PURPOSE (probe))
+ {
+ TREE_PURPOSE (parser->unparsed_functions_queues)
+ = tree_cons (NULL_TREE, decl,
+ TREE_PURPOSE (parser->unparsed_functions_queues));
+ break;
+ }
+ return;
+}
+
+/* FN is a FUNCTION_DECL which may contains a parameter with an
+ unparsed DEFAULT_ARG. Parse the default args now. */
+
+static void
+cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
+{
+ cp_lexer *saved_lexer;
+ cp_token_cache *tokens;
+ bool saved_local_variables_forbidden_p;
+ tree parameters;
+
+ /* While we're parsing the default args, we might (due to the
+ statement expression extension) encounter more classes. We want
+ to handle them right away, but we don't want them getting mixed
+ up with default args that are currently in the queue. */
+ parser->unparsed_functions_queues
+ = tree_cons (NULL_TREE, NULL_TREE, parser->unparsed_functions_queues);
+
+ for (parameters = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ parameters;
+ parameters = TREE_CHAIN (parameters))
+ {
+ if (!TREE_PURPOSE (parameters)
+ || TREE_CODE (TREE_PURPOSE (parameters)) != DEFAULT_ARG)
+ continue;
+
+ /* Save away the current lexer. */
+ saved_lexer = parser->lexer;
+ /* Create a new one, using the tokens we have saved. */
+ tokens = DEFARG_TOKENS (TREE_PURPOSE (parameters));
+ parser->lexer = cp_lexer_new_from_tokens (tokens);
+
+ /* Set the current source position to be the location of the
+ first token in the default argument. */
+ cp_lexer_peek_token (parser->lexer);
+
+ /* Local variable names (and the `this' keyword) may not appear
+ in a default argument. */
+ saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
+ parser->local_variables_forbidden_p = true;
+ /* Parse the assignment-expression. */
+ if (DECL_CLASS_SCOPE_P (fn))
+ push_nested_class (DECL_CONTEXT (fn));
+ TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser);
+ if (DECL_CLASS_SCOPE_P (fn))
+ pop_nested_class ();
+
+ /* If the token stream has not been completely used up, then
+ there was extra junk after the end of the default
+ argument. */
+ if (!cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+ cp_parser_error (parser, "expected `,'");
+
+ /* Restore saved state. */
+ parser->lexer = saved_lexer;
+ parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;
+ }
+
+ /* Restore the queue. */
+ parser->unparsed_functions_queues
+ = TREE_CHAIN (parser->unparsed_functions_queues);
+}
+
+/* Parse the operand of `sizeof' (or a similar operator). Returns
+ either a TYPE or an expression, depending on the form of the
+ input. The KEYWORD indicates which kind of expression we have
+ encountered. */
+
+static tree
+cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
+{
+ static const char *format;
+ tree expr = NULL_TREE;
+ const char *saved_message;
+ bool saved_integral_constant_expression_p;
+
+ /* Initialize FORMAT the first time we get here. */
+ if (!format)
+ format = "types may not be defined in `%s' expressions";
+
+ /* Types cannot be defined in a `sizeof' expression. Save away the
+ old message. */
+ saved_message = parser->type_definition_forbidden_message;
+ /* And create the new one. */
+ parser->type_definition_forbidden_message
+ = xmalloc (strlen (format)
+ + strlen (IDENTIFIER_POINTER (ridpointers[keyword]))
+ + 1 /* `\0' */);
+ sprintf ((char *) parser->type_definition_forbidden_message,
+ format, IDENTIFIER_POINTER (ridpointers[keyword]));
+
+ /* The restrictions on constant-expressions do not apply inside
+ sizeof expressions. */
+ saved_integral_constant_expression_p = parser->integral_constant_expression_p;
+ parser->integral_constant_expression_p = false;
+
+ /* Do not actually evaluate the expression. */
+ ++skip_evaluation;
+ /* 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))
+ {
+ tree type;
+ bool saved_in_type_id_in_expr_p;
+
+ /* We can't be sure yet whether we're looking at a type-id or an
+ expression. */
+ cp_parser_parse_tentatively (parser);
+ /* Consume the `('. */
+ cp_lexer_consume_token (parser->lexer);
+ /* Parse the type-id. */
+ saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
+ parser->in_type_id_in_expr_p = true;
+ type = cp_parser_type_id (parser);
+ parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
+ /* Now, look for the trailing `)'. */
+ cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
+ /* If all went well, then we're done. */
+ if (cp_parser_parse_definitely (parser))
+ {
+ /* Build a list of decl-specifiers; right now, we have only
+ a single type-specifier. */
+ type = build_tree_list (NULL_TREE,
+ type);
+
+ /* Call grokdeclarator to figure out what type this is. */
+ expr = grokdeclarator (NULL_TREE,
+ type,
+ TYPENAME,
+ /*initialized=*/0,
+ /*attrlist=*/NULL);
+ }
+ }
+
+ /* If the type-id production did not work out, then we must be
+ looking at the unary-expression production. */
+ if (!expr)
+ expr = cp_parser_unary_expression (parser, /*address_p=*/false);
+ /* Go back to evaluating expressions. */
+ --skip_evaluation;
+
+ /* Free the message we created. */
+ free ((char *) parser->type_definition_forbidden_message);
+ /* And restore the old one. */
+ parser->type_definition_forbidden_message = saved_message;
+ parser->integral_constant_expression_p = saved_integral_constant_expression_p;
+
+ return expr;
+}
+
+/* If the current declaration has no declarator, return true. */
+
+static bool
+cp_parser_declares_only_class_p (cp_parser *parser)
+{
+ /* If the next token is a `;' or a `,' then there is no
+ declarator. */
+ return (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
+ || cp_lexer_next_token_is (parser->lexer, CPP_COMMA));
+}
+
+/* DECL_SPECIFIERS is the representation of a decl-specifier-seq.
+ Returns TRUE iff `friend' appears among the DECL_SPECIFIERS. */
+
+static bool
+cp_parser_friend_p (tree decl_specifiers)
+{
+ while (decl_specifiers)
+ {
+ /* See if this decl-specifier is `friend'. */
+ if (TREE_CODE (TREE_VALUE (decl_specifiers)) == IDENTIFIER_NODE
+ && C_RID_CODE (TREE_VALUE (decl_specifiers)) == RID_FRIEND)
+ return true;
+
+ /* Go on to the next decl-specifier. */
+ decl_specifiers = TREE_CHAIN (decl_specifiers);
+ }
+
+ return false;
+}
+
+/* If the next token is of the indicated TYPE, consume it. Otherwise,
+ issue an error message indicating that TOKEN_DESC was expected.
+
+ Returns the token consumed, if the token had the appropriate type.
+ Otherwise, returns NULL. */
+
+static cp_token *
+cp_parser_require (cp_parser* parser,
+ enum cpp_ttype type,
+ const char* token_desc)
+{
+ if (cp_lexer_next_token_is (parser->lexer, type))
+ return cp_lexer_consume_token (parser->lexer);
+ else
+ {
+ /* Output the MESSAGE -- unless we're parsing tentatively. */
+ if (!cp_parser_simulate_error (parser))
+ {
+ char *message = concat ("expected ", token_desc, NULL);
+ cp_parser_error (parser, message);
+ free (message);
+ }
+ return NULL;
+ }
+}
+
+/* Like cp_parser_require, except that tokens will be skipped until
+ the desired token is found. An error message is still produced if
+ the next token is not as expected. */
+
+static void
+cp_parser_skip_until_found (cp_parser* parser,
+ enum cpp_ttype type,
+ const char* token_desc)
+{
+ cp_token *token;
+ unsigned nesting_depth = 0;
+
+ if (cp_parser_require (parser, type, token_desc))
+ return;
+
+ /* Skip tokens until the desired token is found. */
+ while (true)
+ {
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* If we've reached the token we want, consume it and
+ stop. */
+ if (token->type == type && !nesting_depth)
+ {
+ cp_lexer_consume_token (parser->lexer);
+ return;
+ }
+ /* If we've run out of tokens, stop. */
+ if (token->type == CPP_EOF)
+ return;
+ if (token->type == CPP_OPEN_BRACE
+ || token->type == CPP_OPEN_PAREN
+ || token->type == CPP_OPEN_SQUARE)
+ ++nesting_depth;
+ else if (token->type == CPP_CLOSE_BRACE
+ || token->type == CPP_CLOSE_PAREN
+ || token->type == CPP_CLOSE_SQUARE)
+ {
+ if (nesting_depth-- == 0)
+ return;
+ }
+ /* Consume this token. */
+ cp_lexer_consume_token (parser->lexer);
+ }
+}
+
+/* If the next token is the indicated keyword, consume it. Otherwise,
+ issue an error message indicating that TOKEN_DESC was expected.
+
+ Returns the token consumed, if the token had the appropriate type.
+ Otherwise, returns NULL. */
+
+static cp_token *
+cp_parser_require_keyword (cp_parser* parser,
+ enum rid keyword,
+ const char* token_desc)
+{
+ cp_token *token = cp_parser_require (parser, CPP_KEYWORD, token_desc);
+
+ if (token && token->keyword != keyword)
+ {
+ dyn_string_t error_msg;
+
+ /* Format the error message. */
+ error_msg = dyn_string_new (0);
+ dyn_string_append_cstr (error_msg, "expected ");
+ dyn_string_append_cstr (error_msg, token_desc);
+ cp_parser_error (parser, error_msg->s);
+ dyn_string_delete (error_msg);
+ return NULL;
+ }
+
+ return token;
+}
+
+/* Returns TRUE iff TOKEN is a token that can begin the body of a
+ function-definition. */
+
+static bool
+cp_parser_token_starts_function_definition_p (cp_token* token)
+{
+ return (/* An ordinary function-body begins with an `{'. */
+ token->type == CPP_OPEN_BRACE
+ /* A ctor-initializer begins with a `:'. */
+ || token->type == CPP_COLON
+ /* A function-try-block begins with `try'. */
+ || token->keyword == RID_TRY
+ /* The named return value extension begins with `return'. */
+ || token->keyword == RID_RETURN);
+}
+
+/* Returns TRUE iff the next token is the ":" or "{" beginning a class
+ definition. */
+
+static bool
+cp_parser_next_token_starts_class_definition_p (cp_parser *parser)
+{
+ cp_token *token;
+
+ token = cp_lexer_peek_token (parser->lexer);
+ return (token->type == CPP_OPEN_BRACE || token->type == CPP_COLON);
+}
+
+/* Returns TRUE iff the next token is the "," or ">" ending a
+ template-argument. ">>" is also accepted (after the full
+ argument was parsed) because it's probably a typo for "> >",
+ and there is a specific diagnostic for this. */
+
+static bool
+cp_parser_next_token_ends_template_argument_p (cp_parser *parser)
+{
+ cp_token *token;
+
+ token = cp_lexer_peek_token (parser->lexer);
+ return (token->type == CPP_COMMA || token->type == CPP_GREATER
+ || token->type == CPP_RSHIFT);
+}
+
+/* Returns TRUE iff the n-th token is a ">", or the n-th is a "[" and the
+ (n+1)-th is a ":" (which is a possible digraph typo for "< ::"). */
+
+static bool
+cp_parser_nth_token_starts_template_argument_list_p (cp_parser * parser,
+ size_t n)
+{
+ cp_token *token;
+
+ token = cp_lexer_peek_nth_token (parser->lexer, n);
+ if (token->type == CPP_LESS)
+ return true;
+ /* Check for the sequence `<::' in the original code. It would be lexed as
+ `[:', where `[' is a digraph, and there is no whitespace before
+ `:'. */
+ if (token->type == CPP_OPEN_SQUARE && token->flags & DIGRAPH)
+ {
+ cp_token *token2;
+ token2 = cp_lexer_peek_nth_token (parser->lexer, n+1);
+ if (token2->type == CPP_COLON && !(token2->flags & PREV_WHITE))
+ return true;
+ }
+ return false;
+}
+
+/* Returns the kind of tag indicated by TOKEN, if it is a class-key,
+ or none_type otherwise. */
+
+static enum tag_types
+cp_parser_token_is_class_key (cp_token* token)
+{
+ switch (token->keyword)
+ {
+ case RID_CLASS:
+ return class_type;
+ case RID_STRUCT:
+ return record_type;
+ case RID_UNION:
+ return union_type;
+
+ default:
+ return none_type;
+ }
+}
+
+/* Issue an error message if the CLASS_KEY does not match the TYPE. */
+
+static void
+cp_parser_check_class_key (enum tag_types class_key, tree type)
+{
+ if ((TREE_CODE (type) == UNION_TYPE) != (class_key == union_type))
+ pedwarn ("`%s' tag used in naming `%#T'",
+ class_key == union_type ? "union"
+ : class_key == record_type ? "struct" : "class",
+ type);
+}
+
+/* Issue an error message if DECL is redeclared with different
+ access than its original declaration [class.access.spec/3].
+ This applies to nested classes and nested class templates.
+ [class.mem/1]. */
+
+static void cp_parser_check_access_in_redeclaration (tree decl)
+{
+ if (!CLASS_TYPE_P (TREE_TYPE (decl)))
+ return;
+
+ if ((TREE_PRIVATE (decl)
+ != (current_access_specifier == access_private_node))
+ || (TREE_PROTECTED (decl)
+ != (current_access_specifier == access_protected_node)))
+ error ("%D redeclared with different access", decl);
+}
+
+/* Look for the `template' keyword, as a syntactic disambiguator.
+ Return TRUE iff it is present, in which case it will be
+ consumed. */
+
+static bool
+cp_parser_optional_template_keyword (cp_parser *parser)
+{
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
+ {
+ /* The `template' keyword can only be used within templates;
+ outside templates the parser can always figure out what is a
+ template and what is not. */
+ if (!processing_template_decl)
+ {
+ error ("`template' (as a disambiguator) is only allowed "
+ "within templates");
+ /* If this part of the token stream is rescanned, the same
+ error message would be generated. So, we purge the token
+ from the stream. */
+ cp_lexer_purge_token (parser->lexer);
+ return false;
+ }
+ else
+ {
+ /* Consume the `template' keyword. */
+ cp_lexer_consume_token (parser->lexer);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* The next token is a CPP_NESTED_NAME_SPECIFIER. Consume the token,
+ set PARSER->SCOPE, and perform other related actions. */
+
+static void
+cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
+{
+ tree value;
+ tree check;
+
+ /* Get the stored value. */
+ value = cp_lexer_consume_token (parser->lexer)->value;
+ /* Perform any access checks that were deferred. */
+ for (check = TREE_PURPOSE (value); check; check = TREE_CHAIN (check))
+ perform_or_defer_access_check (TREE_PURPOSE (check), TREE_VALUE (check));
+ /* Set the scope from the stored value. */
+ parser->scope = TREE_VALUE (value);
+ parser->qualifying_scope = TREE_TYPE (value);
+ parser->object_scope = NULL_TREE;
+}
+
+/* Add tokens to CACHE until an non-nested END token appears. */
+
+static void
+cp_parser_cache_group (cp_parser *parser,
+ cp_token_cache *cache,
+ enum cpp_ttype end,
+ unsigned depth)
+{
+ while (true)
+ {
+ cp_token *token;
+
+ /* Abort a parenthesized expression if we encounter a brace. */
+ if ((end == CPP_CLOSE_PAREN || depth == 0)
+ && cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
+ return;
+ /* If we've reached the end of the file, stop. */
+ if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
+ return;
+ /* Consume the next token. */
+ token = cp_lexer_consume_token (parser->lexer);
+ /* Add this token to the tokens we are saving. */
+ cp_token_cache_push_token (cache, token);
+ /* See if it starts a new group. */
+ if (token->type == CPP_OPEN_BRACE)
+ {
+ cp_parser_cache_group (parser, cache, CPP_CLOSE_BRACE, depth + 1);
+ if (depth == 0)
+ return;
+ }
+ else if (token->type == CPP_OPEN_PAREN)
+ cp_parser_cache_group (parser, cache, CPP_CLOSE_PAREN, depth + 1);
+ else if (token->type == end)
+ return;
+ }
+}
+
+/* Begin parsing tentatively. We always save tokens while parsing
+ tentatively so that if the tentative parsing fails we can restore the
+ tokens. */
+
+static void
+cp_parser_parse_tentatively (cp_parser* parser)
+{
+ /* Enter a new parsing context. */
+ parser->context = cp_parser_context_new (parser->context);
+ /* Begin saving tokens. */
+ cp_lexer_save_tokens (parser->lexer);
+ /* In order to avoid repetitive access control error messages,
+ access checks are queued up until we are no longer parsing
+ tentatively. */
+ push_deferring_access_checks (dk_deferred);
+}
+
+/* Commit to the currently active tentative parse. */
+
+static void
+cp_parser_commit_to_tentative_parse (cp_parser* parser)
+{
+ cp_parser_context *context;
+ cp_lexer *lexer;
+
+ /* Mark all of the levels as committed. */
+ lexer = parser->lexer;
+ for (context = parser->context; context->next; context = context->next)
+ {
+ if (context->status == CP_PARSER_STATUS_KIND_COMMITTED)
+ break;
+ context->status = CP_PARSER_STATUS_KIND_COMMITTED;
+ while (!cp_lexer_saving_tokens (lexer))
+ lexer = lexer->next;
+ cp_lexer_commit_tokens (lexer);
+ }
+}
+
+/* Abort the currently active tentative parse. All consumed tokens
+ will be rolled back, and no diagnostics will be issued. */
+
+static void
+cp_parser_abort_tentative_parse (cp_parser* parser)
+{
+ cp_parser_simulate_error (parser);
+ /* Now, pretend that we want to see if the construct was
+ successfully parsed. */
+ cp_parser_parse_definitely (parser);
+}
+
+/* Stop parsing tentatively. If a parse error has occurred, restore the
+ token stream. Otherwise, commit to the tokens we have consumed.
+ Returns true if no error occurred; false otherwise. */
+
+static bool
+cp_parser_parse_definitely (cp_parser* parser)
+{
+ bool error_occurred;
+ cp_parser_context *context;
+
+ /* Remember whether or not an error occurred, since we are about to
+ destroy that information. */
+ error_occurred = cp_parser_error_occurred (parser);
+ /* Remove the topmost context from the stack. */
+ context = parser->context;
+ parser->context = context->next;
+ /* If no parse errors occurred, commit to the tentative parse. */
+ if (!error_occurred)
+ {
+ /* Commit to the tokens read tentatively, unless that was
+ already done. */
+ if (context->status != CP_PARSER_STATUS_KIND_COMMITTED)
+ cp_lexer_commit_tokens (parser->lexer);
+
+ pop_to_parent_deferring_access_checks ();
+ }
+ /* Otherwise, if errors occurred, roll back our state so that things
+ are just as they were before we began the tentative parse. */
+ else
+ {
+ cp_lexer_rollback_tokens (parser->lexer);
+ pop_deferring_access_checks ();
+ }
+ /* Add the context to the front of the free list. */
+ context->next = cp_parser_context_free_list;
+ cp_parser_context_free_list = context;
+
+ return !error_occurred;
+}
+
+/* Returns true if we are parsing tentatively -- but have decided that
+ we will stick with this tentative parse, even if errors occur. */
+
+static bool
+cp_parser_committed_to_tentative_parse (cp_parser* parser)
+{
+ return (cp_parser_parsing_tentatively (parser)
+ && parser->context->status == CP_PARSER_STATUS_KIND_COMMITTED);
+}
+
+/* Returns nonzero iff an error has occurred during the most recent
+ tentative parse. */
+
+static bool
+cp_parser_error_occurred (cp_parser* parser)
+{
+ return (cp_parser_parsing_tentatively (parser)
+ && parser->context->status == CP_PARSER_STATUS_KIND_ERROR);
+}
+
+/* Returns nonzero if GNU extensions are allowed. */
+
+static bool
+cp_parser_allow_gnu_extensions_p (cp_parser* parser)
+{
+ return parser->allow_gnu_extensions_p;
+}
+
+
+
+/* The parser. */
+
+static GTY (()) cp_parser *the_parser;
+
+/* External interface. */
+
+/* Parse one entire translation unit. */
+
+void
+c_parse_file (void)
+{
+ bool error_occurred;
+
+ the_parser = cp_parser_new ();
+ push_deferring_access_checks (flag_access_control
+ ? dk_no_deferred : dk_no_check);
+ error_occurred = cp_parser_translation_unit (the_parser);
+ the_parser = NULL;
+}
+
+/* This variable must be provided by every front end. */
+
+int yydebug;
+
+#include "gt-cp-parser.h"
diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c
index 64d44284d006..c5c8e3257014 100644
--- a/contrib/gcc/cp/pt.c
+++ b/contrib/gcc/cp/pt.c
@@ -1,23 +1,23 @@
/* Handle parameterized types (templates) for GNU C++.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
Rewritten by Jason Merrill (jason@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -28,34 +28,33 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "obstack.h"
#include "tree.h"
#include "flags.h"
#include "cp-tree.h"
#include "tree-inline.h"
#include "decl.h"
-#include "parse.h"
#include "lex.h"
#include "output.h"
#include "except.h"
#include "toplev.h"
#include "rtl.h"
-#include "ggc.h"
#include "timevar.h"
/* The type of functions taking a tree, and some additional data, and
returning an int. */
-typedef int (*tree_fn_t) PARAMS ((tree, void*));
+typedef int (*tree_fn_t) (tree, void*);
/* The PENDING_TEMPLATES is a TREE_LIST of templates whose
instantiations have been deferred, either because their definitions
- were not yet available, or because we were putting off doing the
- work. The TREE_PURPOSE of each entry is a SRCLOC indicating where
- the instantiate request occurred; the TREE_VALUE is either a DECL
- (for a function or static data member), or a TYPE (for a class)
- indicating what we are hoping to instantiate. */
+ were not yet available, or because we were putting off doing the work.
+ The TREE_PURPOSE of each entry is either a DECL (for a function or
+ static data member), or a TYPE (for a class) indicating what we are
+ hoping to instantiate. The TREE_VALUE is not used. */
static GTY(()) tree pending_templates;
-static tree last_pending_template;
+static GTY(()) tree last_pending_template;
int processing_template_parmlist;
static int template_header_count;
@@ -89,134 +88,104 @@ static htab_t local_specializations;
#define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current
type with the desired type. */
-static void push_access_scope_real PARAMS ((tree, tree, tree));
-static void push_access_scope PARAMS ((tree));
-static void pop_access_scope PARAMS ((tree));
-static int resolve_overloaded_unification PARAMS ((tree, tree, tree, tree,
- unification_kind_t, int));
-static int try_one_overload PARAMS ((tree, tree, tree, tree, tree,
- unification_kind_t, int, bool));
-static int unify PARAMS ((tree, tree, tree, tree, int));
-static void add_pending_template PARAMS ((tree));
-static void reopen_tinst_level PARAMS ((tree));
-static tree classtype_mangled_name PARAMS ((tree));
-static char *mangle_class_name_for_template PARAMS ((const char *,
- tree, tree));
-static tree tsubst_initializer_list PARAMS ((tree, tree));
-static int list_eq PARAMS ((tree, tree));
-static tree get_class_bindings PARAMS ((tree, tree, tree));
-static tree coerce_template_parms PARAMS ((tree, tree, tree,
- tsubst_flags_t, int));
-static void tsubst_enum PARAMS ((tree, tree, tree));
-static tree add_to_template_args PARAMS ((tree, tree));
-static tree add_outermost_template_args PARAMS ((tree, tree));
-static int maybe_adjust_types_for_deduction PARAMS ((unification_kind_t, tree*,
- tree*));
-static int type_unification_real PARAMS ((tree, tree, tree, tree,
- int, unification_kind_t, int, int));
-static void note_template_header PARAMS ((int));
-static tree maybe_fold_nontype_arg PARAMS ((tree));
-static tree convert_nontype_argument PARAMS ((tree, tree));
-static tree convert_template_argument PARAMS ((tree, tree, tree,
- tsubst_flags_t, int, tree));
-static tree get_bindings_overload PARAMS ((tree, tree, tree));
-static int for_each_template_parm PARAMS ((tree, tree_fn_t, void*, htab_t));
-static tree build_template_parm_index PARAMS ((int, int, int, tree, tree));
-static int inline_needs_template_parms PARAMS ((tree));
-static void push_inline_template_parms_recursive PARAMS ((tree, int));
-static tree retrieve_specialization PARAMS ((tree, tree));
-static tree retrieve_local_specialization PARAMS ((tree));
-static tree register_specialization PARAMS ((tree, tree, tree));
-static void register_local_specialization PARAMS ((tree, tree));
-static int reregister_specialization PARAMS ((tree, tree, tree));
-static tree reduce_template_parm_level PARAMS ((tree, tree, int));
-static tree build_template_decl PARAMS ((tree, tree));
-static int mark_template_parm PARAMS ((tree, void *));
-static int template_parm_this_level_p PARAMS ((tree, void *));
-static tree tsubst_friend_function PARAMS ((tree, tree));
-static tree tsubst_friend_class PARAMS ((tree, tree));
-static int can_complete_type_without_circularity PARAMS ((tree));
-static tree get_bindings_real PARAMS ((tree, tree, tree, int, int, int));
-static int template_decl_level PARAMS ((tree));
-static tree maybe_get_template_decl_from_type_decl PARAMS ((tree));
-static int check_cv_quals_for_unify PARAMS ((int, tree, tree));
-static tree tsubst_template_arg_vector PARAMS ((tree, tree, tsubst_flags_t));
-static tree tsubst_template_parms PARAMS ((tree, tree, tsubst_flags_t));
-static void regenerate_decl_from_template PARAMS ((tree, tree));
-static tree most_specialized PARAMS ((tree, tree, tree));
-static tree most_specialized_class PARAMS ((tree, tree));
-static int template_class_depth_real PARAMS ((tree, int));
-static tree tsubst_aggr_type PARAMS ((tree, tree, tsubst_flags_t, tree, int));
-static tree tsubst_decl PARAMS ((tree, tree, tree, tsubst_flags_t));
-static tree tsubst_arg_types PARAMS ((tree, tree, tsubst_flags_t, tree));
-static tree tsubst_function_type PARAMS ((tree, tree, tsubst_flags_t, tree));
-static void check_specialization_scope PARAMS ((void));
-static tree process_partial_specialization PARAMS ((tree));
-static void set_current_access_from_decl PARAMS ((tree));
-static void check_default_tmpl_args PARAMS ((tree, tree, int, int));
-static tree tsubst_call_declarator_parms PARAMS ((tree, tree,
- tsubst_flags_t, tree));
-static tree get_template_base_recursive PARAMS ((tree, tree,
- tree, tree, tree, int));
-static tree get_template_base PARAMS ((tree, tree, tree, tree));
-static int verify_class_unification PARAMS ((tree, tree, tree));
-static tree try_class_unification PARAMS ((tree, tree, tree, tree));
-static int coerce_template_template_parms PARAMS ((tree, tree, tsubst_flags_t,
- tree, tree));
-static tree determine_specialization PARAMS ((tree, tree, tree *, int));
-static int template_args_equal PARAMS ((tree, tree));
-static void tsubst_default_arguments PARAMS ((tree));
-static tree for_each_template_parm_r PARAMS ((tree *, int *, void *));
-static tree copy_default_args_to_explicit_spec_1 PARAMS ((tree, tree));
-static void copy_default_args_to_explicit_spec PARAMS ((tree));
-static int invalid_nontype_parm_type_p PARAMS ((tree, tsubst_flags_t));
+static void push_access_scope (tree);
+static void pop_access_scope (tree);
+static int resolve_overloaded_unification (tree, tree, tree, tree,
+ unification_kind_t, int);
+static int try_one_overload (tree, tree, tree, tree, tree,
+ unification_kind_t, int, bool);
+static int unify (tree, tree, tree, tree, int);
+static void add_pending_template (tree);
+static void reopen_tinst_level (tree);
+static tree classtype_mangled_name (tree);
+static char* mangle_class_name_for_template (const char *, tree, tree);
+static tree tsubst_initializer_list (tree, tree);
+static tree get_class_bindings (tree, tree, tree);
+static tree coerce_template_parms (tree, tree, tree, tsubst_flags_t, int);
+static void tsubst_enum (tree, tree, tree);
+static tree add_to_template_args (tree, tree);
+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*);
+static int type_unification_real (tree, tree, tree, tree,
+ int, unification_kind_t, int, int);
+static void note_template_header (int);
+static tree convert_nontype_argument (tree, tree);
+static tree convert_template_argument (tree, tree, tree,
+ tsubst_flags_t, int, tree);
+static tree get_bindings_overload (tree, tree, tree);
+static int for_each_template_parm (tree, tree_fn_t, void*, htab_t);
+static tree build_template_parm_index (int, int, int, tree, tree);
+static int inline_needs_template_parms (tree);
+static void push_inline_template_parms_recursive (tree, int);
+static tree retrieve_specialization (tree, tree);
+static tree retrieve_local_specialization (tree);
+static tree register_specialization (tree, tree, tree);
+static void register_local_specialization (tree, tree);
+static tree reduce_template_parm_level (tree, tree, int);
+static tree build_template_decl (tree, tree);
+static int mark_template_parm (tree, void *);
+static int template_parm_this_level_p (tree, void *);
+static tree tsubst_friend_function (tree, tree);
+static tree tsubst_friend_class (tree, tree);
+static int can_complete_type_without_circularity (tree);
+static tree get_bindings (tree, tree, tree);
+static tree get_bindings_real (tree, tree, tree, int, int, int);
+static int template_decl_level (tree);
+static int check_cv_quals_for_unify (int, tree, tree);
+static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
+static void regenerate_decl_from_template (tree, tree);
+static tree most_specialized (tree, tree, tree);
+static tree most_specialized_class (tree, tree);
+static int template_class_depth_real (tree, int);
+static tree tsubst_aggr_type (tree, tree, tsubst_flags_t, tree, int);
+static tree tsubst_decl (tree, tree, tree, tsubst_flags_t);
+static tree tsubst_arg_types (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
+static void check_specialization_scope (void);
+static tree process_partial_specialization (tree);
+static void set_current_access_from_decl (tree);
+static void check_default_tmpl_args (tree, tree, int, int);
+static tree tsubst_call_declarator_parms (tree, tree, tsubst_flags_t, tree);
+static tree get_template_base_recursive (tree, tree, tree, tree, tree, int);
+static tree get_template_base (tree, tree, tree, tree);
+static int verify_class_unification (tree, tree, tree);
+static tree try_class_unification (tree, tree, tree, tree);
+static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
+ tree, tree);
+static tree determine_specialization (tree, tree, tree *, int);
+static int template_args_equal (tree, tree);
+static void tsubst_default_arguments (tree);
+static tree for_each_template_parm_r (tree *, int *, void *);
+static tree copy_default_args_to_explicit_spec_1 (tree, tree);
+static void copy_default_args_to_explicit_spec (tree);
+static int invalid_nontype_parm_type_p (tree, tsubst_flags_t);
+static int eq_local_specializations (const void *, const void *);
+static bool dependent_type_p_r (tree);
+static tree tsubst (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_expr (tree, tree, tsubst_flags_t, tree);
+static tree tsubst_copy (tree, tree, tsubst_flags_t, tree);
/* Make the current scope suitable for access checking when we are
processing T. T can be FUNCTION_DECL for instantiated function
- template, TEMPLATE_DECL for uninstantiated one, or VAR_DECL for
- static member variable (need by instantiate_decl). ARGS is the
- template argument for TEMPLATE_DECL. If CONTEXT is not NULL_TREE,
- this is used instead of the context of T. */
+ template, or VAR_DECL for static member variable (need by
+ instantiate_decl). */
-void
-push_access_scope_real (t, args, context)
- tree t, args, context;
+static void
+push_access_scope (tree t)
{
- if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t))
- {
- /* When we are processing specialization `foo<Outer>' for code like
-
- template <class U> typename U::Inner foo ();
- class Outer {
- struct Inner {};
- friend Outer::Inner foo<Outer> ();
- };
-
- `T' is a TEMPLATE_DECL, but `Outer' is only a friend of one of
- its specialization. We can get the FUNCTION_DECL with the right
- information because this specialization has already been
- registered by the friend declaration above. */
-
- if (DECL_FUNCTION_TEMPLATE_P (t) && args)
- {
- tree full_args = tsubst_template_arg_vector
- (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t)), args, tf_none);
- tree spec = NULL_TREE;
- if (full_args != error_mark_node)
- spec = retrieve_specialization (t, full_args);
- if (spec)
- t = spec;
- }
- }
+ my_friendly_assert (TREE_CODE (t) == FUNCTION_DECL
+ || TREE_CODE (t) == VAR_DECL,
+ 0);
- if (!context)
- context = DECL_CONTEXT (t);
- if (context && TYPE_P (context))
- push_nested_class (context, 2);
+ if (DECL_CLASS_SCOPE_P (t))
+ push_nested_class (DECL_CONTEXT (t));
else
push_to_top_level ();
- if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t))
+ if (TREE_CODE (t) == FUNCTION_DECL)
{
saved_access_scope = tree_cons
(NULL_TREE, current_function_decl, saved_access_scope);
@@ -224,23 +193,13 @@ push_access_scope_real (t, args, context)
}
}
-/* Like push_access_scope_real, but always uses DECL_CONTEXT. */
-
-void
-push_access_scope (t)
- tree t;
-{
- push_access_scope_real (t, NULL_TREE, NULL_TREE);
-}
-
/* Restore the scope set up by push_access_scope. T is the node we
are processing. */
-void
-pop_access_scope (t)
- tree t;
+static void
+pop_access_scope (tree t)
{
- if (TREE_CODE (t) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (t))
+ if (TREE_CODE (t) == FUNCTION_DECL)
{
current_function_decl = TREE_VALUE (saved_access_scope);
saved_access_scope = TREE_CHAIN (saved_access_scope);
@@ -252,29 +211,29 @@ pop_access_scope (t)
pop_from_top_level ();
}
-/* Do any processing required when DECL (a member template declaration
- using TEMPLATE_PARAMETERS as its innermost parameter list) is
- finished. Returns the TEMPLATE_DECL corresponding to DECL, unless
- it is a specialization, in which case the DECL itself is returned. */
+/* Do any processing required when DECL (a member template
+ declaration) is finished. Returns the TEMPLATE_DECL corresponding
+ to DECL, unless it is a specialization, in which case the DECL
+ itself is returned. */
tree
-finish_member_template_decl (decl)
- tree decl;
+finish_member_template_decl (tree decl)
{
- if (decl == NULL_TREE || decl == void_type_node)
- return NULL_TREE;
- else if (decl == error_mark_node)
- /* By returning NULL_TREE, the parser will just ignore this
- declaration. We have already issued the error. */
- return NULL_TREE;
- else if (TREE_CODE (decl) == TREE_LIST)
+ if (decl == error_mark_node)
+ return error_mark_node;
+
+ my_friendly_assert (DECL_P (decl), 20020812);
+
+ if (TREE_CODE (decl) == TYPE_DECL)
{
- /* Assume that the class is the only declspec. */
- decl = TREE_VALUE (decl);
- if (IS_AGGR_TYPE (decl) && CLASSTYPE_TEMPLATE_INFO (decl)
- && ! CLASSTYPE_TEMPLATE_SPECIALIZATION (decl))
+ tree type;
+
+ type = TREE_TYPE (decl);
+ if (IS_AGGR_TYPE (type)
+ && CLASSTYPE_TEMPLATE_INFO (type)
+ && !CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
{
- tree tmpl = CLASSTYPE_TI_TEMPLATE (decl);
+ tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
check_member_template (tmpl);
return tmpl;
}
@@ -318,9 +277,7 @@ finish_member_template_decl (decl)
always safe. */
static int
-template_class_depth_real (type, count_specializations)
- tree type;
- int count_specializations;
+template_class_depth_real (tree type, int count_specializations)
{
int depth;
@@ -357,8 +314,7 @@ template_class_depth_real (type, count_specializations)
the depth. */
int
-template_class_depth (type)
- tree type;
+template_class_depth (tree type)
{
return template_class_depth_real (type, /*count_specializations=*/0);
}
@@ -367,8 +323,7 @@ template_class_depth (type)
needs us to push template parms. */
static int
-inline_needs_template_parms (decl)
- tree decl;
+inline_needs_template_parms (tree decl)
{
if (! DECL_TEMPLATE_INFO (decl))
return 0;
@@ -383,9 +338,7 @@ inline_needs_template_parms (decl)
innermost first. */
static void
-push_inline_template_parms_recursive (parmlist, levels)
- tree parmlist;
- int levels;
+push_inline_template_parms_recursive (tree parmlist, int levels)
{
tree parms = TREE_VALUE (parmlist);
int i;
@@ -399,7 +352,8 @@ push_inline_template_parms_recursive (parmlist, levels)
parms, current_template_parms);
TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1;
- pushlevel (0);
+ begin_scope (TREE_VEC_LENGTH (parms) ? sk_template_parms : sk_template_spec,
+ NULL);
for (i = 0; i < TREE_VEC_LENGTH (parms); ++i)
{
tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
@@ -421,6 +375,7 @@ push_inline_template_parms_recursive (parmlist, levels)
tree decl = build_decl (CONST_DECL, DECL_NAME (parm),
TREE_TYPE (parm));
DECL_ARTIFICIAL (decl) = 1;
+ TREE_CONSTANT (decl) = TREE_READONLY (decl) = 1;
DECL_INITIAL (decl) = DECL_INITIAL (parm);
SET_DECL_TEMPLATE_PARM_P (decl);
pushdecl (decl);
@@ -437,8 +392,7 @@ push_inline_template_parms_recursive (parmlist, levels)
a friend template defined in a class definition. */
void
-maybe_begin_member_template_processing (decl)
- tree decl;
+maybe_begin_member_template_processing (tree decl)
{
tree parms;
int levels = 0;
@@ -470,7 +424,7 @@ maybe_begin_member_template_processing (decl)
/* Undo the effects of begin_member_template_processing. */
void
-maybe_end_member_template_processing ()
+maybe_end_member_template_processing (void)
{
int i;
@@ -504,8 +458,7 @@ maybe_end_member_template_processing ()
C<int>::f(U)' is considered a member template. */
int
-is_member_template (t)
- tree t;
+is_member_template (tree t)
{
if (!DECL_FUNCTION_TEMPLATE_P (t))
/* Anything that isn't a function or a template function is
@@ -530,8 +483,7 @@ is_member_template (t)
a member template. */
int
-is_member_template_class (t)
- tree t;
+is_member_template_class (tree t)
{
if (!DECL_CLASS_TEMPLATE_P (t))
/* Anything that isn't a class template, is certainly not a member
@@ -555,9 +507,7 @@ is_member_template_class (t)
but has as its innermost set of arguments the EXTRA_ARGS. */
static tree
-add_to_template_args (args, extra_args)
- tree args;
- tree extra_args;
+add_to_template_args (tree args, tree extra_args)
{
tree new_args;
int extra_depth;
@@ -584,9 +534,7 @@ add_to_template_args (args, extra_args)
partial instantiation. */
static tree
-add_outermost_template_args (args, extra_args)
- tree args;
- tree extra_args;
+add_outermost_template_args (tree args, tree extra_args)
{
tree new_args;
@@ -614,9 +562,7 @@ add_outermost_template_args (args, extra_args)
/* Return the N levels of innermost template arguments from the ARGS. */
tree
-get_innermost_template_args (args, n)
- tree args;
- int n;
+get_innermost_template_args (tree args, int n)
{
tree new_args;
int extra_levels;
@@ -648,7 +594,7 @@ get_innermost_template_args (args, n)
the parms. */
void
-begin_template_parm_list ()
+begin_template_parm_list (void)
{
/* We use a non-tag-transparent scope here, which causes pushtag to
put tags in this scope, rather than in the enclosing class or
@@ -664,7 +610,7 @@ begin_template_parm_list ()
pushtag contains special code to call pushdecl_with_scope on the
TEMPLATE_DECL for S2. */
- begin_scope (sk_template_parms);
+ begin_scope (sk_template_parms, NULL);
++processing_template_decl;
++processing_template_parmlist;
note_template_header (0);
@@ -674,7 +620,7 @@ begin_template_parm_list ()
invalid to declare a specialization here, an error is reported. */
static void
-check_specialization_scope ()
+check_specialization_scope (void)
{
tree scope = current_scope ();
@@ -706,9 +652,9 @@ check_specialization_scope ()
/* We've just seen template <>. */
void
-begin_specialization ()
+begin_specialization (void)
{
- begin_scope (sk_template_spec);
+ begin_scope (sk_template_spec, NULL);
note_template_header (1);
check_specialization_scope ();
}
@@ -717,7 +663,7 @@ begin_specialization ()
template<>. */
void
-end_specialization ()
+end_specialization (void)
{
finish_scope ();
reset_specialization ();
@@ -727,7 +673,7 @@ end_specialization ()
function specialization. */
void
-reset_specialization ()
+reset_specialization (void)
{
processing_specialization = 0;
template_header_count = 0;
@@ -737,8 +683,7 @@ reset_specialization ()
it was of the form template <>. */
static void
-note_template_header (specialization)
- int specialization;
+note_template_header (int specialization)
{
processing_specialization = specialization;
template_header_count++;
@@ -747,25 +692,25 @@ note_template_header (specialization)
/* We're beginning an explicit instantiation. */
void
-begin_explicit_instantiation ()
+begin_explicit_instantiation (void)
{
- ++processing_explicit_instantiation;
+ my_friendly_assert (!processing_explicit_instantiation, 20020913);
+ processing_explicit_instantiation = true;
}
void
-end_explicit_instantiation ()
+end_explicit_instantiation (void)
{
- my_friendly_assert(processing_explicit_instantiation > 0, 0);
- --processing_explicit_instantiation;
+ my_friendly_assert(processing_explicit_instantiation, 20020913);
+ processing_explicit_instantiation = false;
}
/* The TYPE is being declared. If it is a template type, that means it
is a partial specialization. Do appropriate error-checking. */
void
-maybe_process_partial_specialization (type)
- tree type;
+maybe_process_partial_specialization (tree type)
{
/* TYPE maybe an ERROR_MARK_NODE. */
tree context = TYPE_P (type) ? TYPE_CONTEXT (type) : NULL_TREE;
@@ -786,8 +731,10 @@ maybe_process_partial_specialization (type)
if (CLASSTYPE_IMPLICIT_INSTANTIATION (type)
&& !COMPLETE_TYPE_P (type))
{
- if (current_namespace
- != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type)))
+ tree tpl_ns = decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type));
+ if (is_associated_namespace (current_namespace, tpl_ns))
+ /* Same or super-using namespace. */;
+ else
{
pedwarn ("specializing `%#T' in different namespace", type);
cp_pedwarn_at (" from definition of `%#D'",
@@ -868,9 +815,7 @@ maybe_process_partial_specialization (type)
templates with more than one level of parameters. */
static tree
-retrieve_specialization (tmpl, args)
- tree tmpl;
- tree args;
+retrieve_specialization (tree tmpl, tree args)
{
tree s;
@@ -894,18 +839,17 @@ retrieve_specialization (tmpl, args)
/* Like retrieve_specialization, but for local declarations. */
static tree
-retrieve_local_specialization (tmpl)
- tree tmpl;
+retrieve_local_specialization (tree tmpl)
{
- return (tree) htab_find (local_specializations, tmpl);
+ tree spec = htab_find_with_hash (local_specializations, tmpl,
+ htab_hash_pointer (tmpl));
+ return spec ? TREE_PURPOSE (spec) : NULL_TREE;
}
/* Returns nonzero iff DECL is a specialization of TMPL. */
int
-is_specialization_of (decl, tmpl)
- tree decl;
- tree tmpl;
+is_specialization_of (tree decl, tree tmpl)
{
tree t;
@@ -932,15 +876,146 @@ is_specialization_of (decl, tmpl)
return 0;
}
+/* Returns nonzero iff DECL is a specialization of friend declaration
+ FRIEND according to [temp.friend]. */
+
+bool
+is_specialization_of_friend (tree decl, tree friend)
+{
+ bool need_template = true;
+ int template_depth;
+
+ my_friendly_assert (TREE_CODE (decl) == FUNCTION_DECL, 0);
+
+ /* For [temp.friend/6] when FRIEND is an ordinary member function
+ of a template class, we want to check if DECL is a specialization
+ if this. */
+ if (TREE_CODE (friend) == FUNCTION_DECL
+ && DECL_TEMPLATE_INFO (friend)
+ && !DECL_USE_TEMPLATE (friend))
+ {
+ friend = DECL_TI_TEMPLATE (friend);
+ need_template = false;
+ }
+
+ /* There is nothing to do if this is not a template friend. */
+ if (TREE_CODE (friend) != TEMPLATE_DECL)
+ return 0;
+
+ if (is_specialization_of (decl, friend))
+ return 1;
+
+ /* [temp.friend/6]
+ A member of a class template may be declared to be a friend of a
+ non-template class. In this case, the corresponding member of
+ every specialization of the class template is a friend of the
+ class granting friendship.
+
+ For example, given a template friend declaration
+
+ template <class T> friend void A<T>::f();
+
+ the member function below is considered a friend
+
+ template <> struct A<int> {
+ void f();
+ };
+
+ For this type of template friend, TEMPLATE_DEPTH below will be
+ nonzero. To determine if DECL is a friend of FRIEND, we first
+ check if the enclosing class is a specialization of another. */
+
+ template_depth = template_class_depth (DECL_CONTEXT (friend));
+ if (template_depth
+ && DECL_CLASS_SCOPE_P (decl)
+ && is_specialization_of (TYPE_NAME (DECL_CONTEXT (decl)),
+ CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (friend))))
+ {
+ /* Next, we check the members themselves. In order to handle
+ a few tricky cases like
+
+ template <class T> friend void A<T>::g(T t);
+ template <class T> template <T t> friend void A<T>::h();
+
+ we need to figure out what ARGS is (corresponding to `T' in above
+ examples) from DECL for later processing. */
+
+ tree context = DECL_CONTEXT (decl);
+ tree args = NULL_TREE;
+ int current_depth = 0;
+ while (current_depth < template_depth)
+ {
+ if (CLASSTYPE_TEMPLATE_INFO (context))
+ {
+ if (current_depth == 0)
+ args = TYPE_TI_ARGS (context);
+ else
+ args = add_to_template_args (TYPE_TI_ARGS (context), args);
+ current_depth++;
+ }
+ context = TYPE_CONTEXT (context);
+ }
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ {
+ bool is_template;
+ tree friend_type;
+ tree decl_type;
+ tree friend_args_type;
+ tree decl_args_type;
+
+ /* Make sure that both DECL and FRIEND are templates or
+ non-templates. */
+ is_template = DECL_TEMPLATE_INFO (decl)
+ && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl));
+ if (need_template ^ is_template)
+ return 0;
+ else if (is_template)
+ {
+ /* If both are templates, check template parameter list. */
+ tree friend_parms
+ = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend),
+ args, tf_none);
+ if (!comp_template_parms
+ (DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (decl)),
+ friend_parms))
+ return 0;
+
+ decl_type = TREE_TYPE (DECL_TI_TEMPLATE (decl));
+ }
+ else
+ decl_type = TREE_TYPE (decl);
+
+ friend_type = tsubst_function_type (TREE_TYPE (friend), args,
+ tf_none, NULL_TREE);
+ if (friend_type == error_mark_node)
+ return 0;
+
+ /* Check if return types match. */
+ if (!same_type_p (TREE_TYPE (decl_type), TREE_TYPE (friend_type)))
+ return 0;
+
+ /* Check if function parameter types match, ignoring the
+ `this' parameter. */
+ friend_args_type = TYPE_ARG_TYPES (friend_type);
+ decl_args_type = TYPE_ARG_TYPES (decl_type);
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (friend))
+ friend_args_type = TREE_CHAIN (friend_args_type);
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
+ decl_args_type = TREE_CHAIN (decl_args_type);
+ if (compparms (decl_args_type, friend_args_type))
+ return 1;
+ }
+ }
+ return 0;
+}
+
/* Register the specialization SPEC as a specialization of TMPL with
the indicated ARGS. Returns SPEC, or an equivalent prior
declaration, if available. */
static tree
-register_specialization (spec, tmpl, args)
- tree spec;
- tree tmpl;
- tree args;
+register_specialization (tree spec, tree tmpl, tree args)
{
tree s;
@@ -960,7 +1035,7 @@ register_specialization (spec, tmpl, args)
the default argument expression is not substituted for in an
instantiation unless and until it is actually needed. */
return spec;
-
+
/* There should be as many levels of arguments as there are
levels of parameters. */
my_friendly_assert (TMPL_ARGS_DEPTH (args)
@@ -1027,7 +1102,12 @@ register_specialization (spec, tmpl, args)
}
else if (DECL_TEMPLATE_SPECIALIZATION (fn))
{
- duplicate_decls (spec, fn);
+ if (!duplicate_decls (spec, fn) && DECL_INITIAL (spec))
+ /* Dup decl failed, but this is a new
+ definition. Set the line number so any errors
+ match this new definition. */
+ DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (spec);
+
return fn;
}
}
@@ -1044,7 +1124,7 @@ register_specialization (spec, tmpl, args)
Replace it with NEW_SPEC, if NEW_SPEC is non-NULL. Returns true
if the SPEC was listed as a specialization of TMPL. */
-static int
+bool
reregister_specialization (tree spec, tree tmpl, tree new_spec)
{
tree* s;
@@ -1064,25 +1144,41 @@ reregister_specialization (tree spec, tree tmpl, tree new_spec)
return 0;
}
+/* Compare an entry in the local specializations hash table P1 (which
+ is really a pointer to a TREE_LIST) with P2 (which is really a
+ DECL). */
+
+static int
+eq_local_specializations (const void *p1, const void *p2)
+{
+ return TREE_VALUE ((tree) p1) == (tree) p2;
+}
+
+/* Hash P1, an entry in the local specializations table. */
+
+static hashval_t
+hash_local_specialization (const void* p1)
+{
+ return htab_hash_pointer (TREE_VALUE ((tree) p1));
+}
+
/* Like register_specialization, but for local declarations. We are
registering SPEC, an instantiation of TMPL. */
static void
-register_local_specialization (spec, tmpl)
- tree spec;
- tree tmpl;
+register_local_specialization (tree spec, tree tmpl)
{
void **slot;
- slot = htab_find_slot (local_specializations, tmpl, INSERT);
- *slot = spec;
+ slot = htab_find_slot_with_hash (local_specializations, tmpl,
+ htab_hash_pointer (tmpl), INSERT);
+ *slot = build_tree_list (spec, tmpl);
}
/* Print the list of candidate FNS in an error message. */
void
-print_candidates (fns)
- tree fns;
+print_candidates (tree fns)
{
tree fn;
@@ -1114,12 +1210,10 @@ print_candidates (fns)
issued. The error_mark_node is returned to indicate failure. */
static tree
-determine_specialization (template_id, decl, targs_out,
- need_member_template)
- tree template_id;
- tree decl;
- tree* targs_out;
- int need_member_template;
+determine_specialization (tree template_id,
+ tree decl,
+ tree* targs_out,
+ int need_member_template)
{
tree fns;
tree targs;
@@ -1155,6 +1249,7 @@ determine_specialization (template_id, decl, targs_out,
if (TREE_CODE (fn) == TEMPLATE_DECL)
{
tree decl_arg_types;
+ tree fn_arg_types;
/* DECL might be a specialization of FN. */
@@ -1171,8 +1266,16 @@ determine_specialization (template_id, decl, targs_out,
The specialization f<int> is invalid but is not caught
by get_bindings below. */
- if (list_length (TYPE_ARG_TYPES (TREE_TYPE (fn)))
- != list_length (decl_arg_types))
+ fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ if (list_length (fn_arg_types) != list_length (decl_arg_types))
+ continue;
+
+ /* For a non-static member function, we need to make sure that
+ the const qualification is the same. This can be done by
+ checking the 'this' in the argument list. */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && !same_type_p (TREE_VALUE (fn_arg_types),
+ TREE_VALUE (decl_arg_types)))
continue;
/* See whether this function might be a specialization of this
@@ -1326,10 +1429,8 @@ determine_specialization (template_id, decl, targs_out,
TMPL_TYPES. */
static tree
-copy_default_args_to_explicit_spec_1 (spec_types,
- tmpl_types)
- tree spec_types;
- tree tmpl_types;
+copy_default_args_to_explicit_spec_1 (tree spec_types,
+ tree tmpl_types)
{
tree new_spec_types;
@@ -1362,8 +1463,7 @@ copy_default_args_to_explicit_spec_1 (spec_types,
is consistent with how implicit instantiations are handled. */
static void
-copy_default_args_to_explicit_spec (decl)
- tree decl;
+copy_default_args_to_explicit_spec (tree decl)
{
tree tmpl;
tree spec_types;
@@ -1428,15 +1528,15 @@ copy_default_args_to_explicit_spec (decl)
TREE_VALUE (in_charge),
new_spec_types);
- new_type = build_cplus_method_type (object_type,
- TREE_TYPE (old_type),
- new_spec_types);
+ new_type = build_method_type_directly (object_type,
+ TREE_TYPE (old_type),
+ new_spec_types);
}
else
new_type = build_function_type (TREE_TYPE (old_type),
new_spec_types);
- new_type = build_type_attribute_variant (new_type,
- TYPE_ATTRIBUTES (old_type));
+ new_type = cp_build_type_attribute_variant (new_type,
+ TYPE_ATTRIBUTES (old_type));
new_type = build_exception_variant (new_type,
TYPE_RAISES_EXCEPTIONS (old_type));
TREE_TYPE (decl) = new_type;
@@ -1480,11 +1580,10 @@ copy_default_args_to_explicit_spec (decl)
for that template. */
tree
-check_explicit_specialization (declarator, decl, template_count, flags)
- tree declarator;
- tree decl;
- int template_count;
- int flags;
+check_explicit_specialization (tree declarator,
+ tree decl,
+ int template_count,
+ int flags)
{
int have_def = flags & 2;
int is_friend = flags & 4;
@@ -1638,15 +1737,21 @@ check_explicit_specialization (declarator, decl, template_count, flags)
{
tree fns;
- my_friendly_assert (TREE_CODE (declarator) == IDENTIFIER_NODE,
- 0);
- if (!ctype)
- fns = IDENTIFIER_NAMESPACE_VALUE (dname);
- else
+ my_friendly_assert (TREE_CODE (declarator) == IDENTIFIER_NODE, 0);
+ if (ctype)
fns = dname;
+ else
+ {
+ /* If there is no class context, the explicit instantiation
+ must be at namespace scope. */
+ my_friendly_assert (DECL_NAMESPACE_SCOPE_P (decl), 20030625);
+
+ /* Find the namespace binding, using the declaration
+ context. */
+ fns = namespace_binding (dname, CP_DECL_CONTEXT (decl));
+ }
- declarator =
- lookup_template_function (fns, NULL_TREE);
+ declarator = lookup_template_function (fns, NULL_TREE);
}
if (declarator == error_mark_node)
@@ -1678,15 +1783,6 @@ check_explicit_specialization (declarator, decl, template_count, flags)
return decl;
}
- else if (TREE_CODE (TREE_OPERAND (declarator, 0)) == LOOKUP_EXPR)
- {
- /* A friend declaration. We can't do much, because we don't
- know what this resolves to, yet. */
- my_friendly_assert (is_friend != 0, 0);
- my_friendly_assert (!explicit_instantiation, 0);
- SET_DECL_IMPLICIT_INSTANTIATION (decl);
- return decl;
- }
else if (ctype != NULL_TREE
&& (TREE_CODE (TREE_OPERAND (declarator, 0)) ==
IDENTIFIER_NODE))
@@ -1809,20 +1905,15 @@ check_explicit_specialization (declarator, decl, template_count, flags)
targs = new_targs;
}
- return instantiate_template (tmpl, targs);
+ return instantiate_template (tmpl, targs, tf_error);
}
/* If we thought that the DECL was a member function, but it
turns out to be specializing a static member function,
- make DECL a static member function as well. We also have
- to adjust last_function_parms to avoid confusing
- start_function later. */
+ make DECL a static member function as well. */
if (DECL_STATIC_FUNCTION_P (tmpl)
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
- {
- revert_static_member_fn (decl);
- last_function_parms = TREE_CHAIN (last_function_parms);
- }
+ revert_static_member_fn (decl);
/* If this is a specialization of a member template of a
template class. In we want to return the TEMPLATE_DECL,
@@ -1831,6 +1922,12 @@ check_explicit_specialization (declarator, decl, template_count, flags)
{
SET_DECL_TEMPLATE_SPECIALIZATION (tmpl);
DECL_INITIAL (DECL_TEMPLATE_RESULT (tmpl)) = NULL_TREE;
+ if (have_def)
+ {
+ DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
+ DECL_SOURCE_LOCATION (DECL_TEMPLATE_RESULT (tmpl))
+ = DECL_SOURCE_LOCATION (decl);
+ }
return tmpl;
}
@@ -1870,8 +1967,7 @@ check_explicit_specialization (declarator, decl, template_count, flags)
and such is reasonable. Issue error messages if not. */
void
-maybe_check_template_type (type)
- tree type;
+maybe_check_template_type (tree type)
{
if (template_header_count)
{
@@ -1914,9 +2010,7 @@ maybe_check_template_type (type)
parameters. These are represented in the same format used for
DECL_TEMPLATE_PARMS. */
-int comp_template_parms (parms1, parms2)
- tree parms1;
- tree parms2;
+int comp_template_parms (tree parms1, tree parms2)
{
tree p1;
tree p2;
@@ -1967,8 +2061,7 @@ int comp_template_parms (parms1, parms2)
scope (including nested scopes). */
void
-check_template_shadow (decl)
- tree decl;
+check_template_shadow (tree decl)
{
tree olddecl;
@@ -2009,12 +2102,11 @@ check_template_shadow (decl)
ORIG_LEVEL, DECL, and TYPE. */
static tree
-build_template_parm_index (index, level, orig_level, decl, type)
- int index;
- int level;
- int orig_level;
- tree decl;
- tree type;
+build_template_parm_index (int index,
+ int level,
+ int orig_level,
+ tree decl,
+ tree type)
{
tree t = make_node (TEMPLATE_PARM_INDEX);
TEMPLATE_PARM_IDX (t) = index;
@@ -2022,6 +2114,8 @@ build_template_parm_index (index, level, orig_level, decl, type)
TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level;
TEMPLATE_PARM_DECL (t) = decl;
TREE_TYPE (t) = type;
+ TREE_CONSTANT (t) = TREE_CONSTANT (decl);
+ TREE_READONLY (t) = TREE_READONLY (decl);
return t;
}
@@ -2032,29 +2126,27 @@ build_template_parm_index (index, level, orig_level, decl, type)
new one is created. */
static tree
-reduce_template_parm_level (index, type, levels)
- tree index;
- tree type;
- int levels;
+reduce_template_parm_level (tree index, tree type, int levels)
{
if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE
|| (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index))
!= TEMPLATE_PARM_LEVEL (index) - levels))
{
- tree decl
- = build_decl (TREE_CODE (TEMPLATE_PARM_DECL (index)),
- DECL_NAME (TEMPLATE_PARM_DECL (index)),
- type);
- tree t
- = build_template_parm_index (TEMPLATE_PARM_IDX (index),
+ tree orig_decl = TEMPLATE_PARM_DECL (index);
+ tree decl, t;
+
+ decl = build_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;
+ SET_DECL_TEMPLATE_PARM_P (decl);
+
+ t = build_template_parm_index (TEMPLATE_PARM_IDX (index),
TEMPLATE_PARM_LEVEL (index) - levels,
TEMPLATE_PARM_ORIG_LEVEL (index),
decl, type);
TEMPLATE_PARM_DESCENDANTS (index) = t;
- DECL_ARTIFICIAL (decl) = 1;
- SET_DECL_TEMPLATE_PARM_P (decl);
-
/* Template template parameters need this. */
DECL_TEMPLATE_PARMS (decl)
= DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index));
@@ -2067,8 +2159,7 @@ reduce_template_parm_level (index, type, levels)
LIST being built. */
tree
-process_template_parm (list, next)
- tree list, next;
+process_template_parm (tree list, tree next)
{
tree parm;
tree decl = 0;
@@ -2109,10 +2200,11 @@ process_template_parm (list, next)
TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm));
/* A template parameter is not modifiable. */
- TREE_READONLY (parm) = 1;
+ TREE_READONLY (parm) = TREE_CONSTANT (parm) = 1;
if (invalid_nontype_parm_type_p (TREE_TYPE (parm), 1))
TREE_TYPE (parm) = void_type_node;
decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
+ TREE_CONSTANT (decl) = TREE_READONLY (decl) = 1;
DECL_INITIAL (parm) = DECL_INITIAL (decl)
= build_template_parm_index (idx, processing_template_decl,
processing_template_decl,
@@ -2135,7 +2227,7 @@ process_template_parm (list, next)
else
{
t = make_aggr_type (TEMPLATE_TYPE_PARM);
- /* parm is either IDENTIFIER_NODE or NULL_TREE */
+ /* parm is either IDENTIFIER_NODE or NULL_TREE. */
decl = build_decl (TYPE_DECL, parm, t);
}
@@ -2160,8 +2252,7 @@ process_template_parm (list, next)
as PARM_DECLs. */
tree
-end_template_parm_list (parms)
- tree parms;
+end_template_parm_list (tree parms)
{
int nparms;
tree parm, next;
@@ -2186,7 +2277,7 @@ end_template_parm_list (parms)
/* end_template_decl is called after a template declaration is seen. */
void
-end_template_decl ()
+end_template_decl (void)
{
reset_specialization ();
@@ -2204,7 +2295,7 @@ end_template_decl ()
The innermost PARMS are given first. */
tree
-current_template_args ()
+current_template_args (void)
{
tree header;
tree args = NULL_TREE;
@@ -2256,9 +2347,7 @@ current_template_args ()
template PARMS. Used by push_template_decl below. */
static tree
-build_template_decl (decl, parms)
- tree decl;
- tree parms;
+build_template_decl (tree decl, tree parms)
{
tree tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE);
DECL_TEMPLATE_PARMS (tmpl) = parms;
@@ -2306,9 +2395,7 @@ struct template_parm_data
appropriately. */
static int
-mark_template_parm (t, data)
- tree t;
- void* data;
+mark_template_parm (tree t, void* data)
{
int level;
int idx;
@@ -2339,8 +2426,7 @@ mark_template_parm (t, data)
/* Process the partial specialization DECL. */
static tree
-process_partial_specialization (decl)
- tree decl;
+process_partial_specialization (tree decl)
{
tree type = TREE_TYPE (decl);
tree maintmpl = CLASSTYPE_TI_TEMPLATE (type);
@@ -2387,10 +2473,10 @@ process_partial_specialization (decl)
or some such would have been OK. */
tpd.level = TMPL_PARMS_DEPTH (current_template_parms);
tpd.parms = alloca (sizeof (int) * ntparms);
- memset ((PTR) tpd.parms, 0, sizeof (int) * ntparms);
+ memset (tpd.parms, 0, sizeof (int) * ntparms);
tpd.arg_uses_template_parms = alloca (sizeof (int) * nargs);
- memset ((PTR) tpd.arg_uses_template_parms, 0, sizeof (int) * nargs);
+ memset (tpd.arg_uses_template_parms, 0, sizeof (int) * nargs);
for (i = 0; i < nargs; ++i)
{
tpd.current_arg = i;
@@ -2461,11 +2547,11 @@ process_partial_specialization (decl)
{
/* We haven't yet initialized TPD2. Do so now. */
tpd2.arg_uses_template_parms
- = (int*) alloca (sizeof (int) * nargs);
+ = alloca (sizeof (int) * nargs);
/* The number of parameters here is the number in the
main template, which, as checked in the assertion
above, is NARGS. */
- tpd2.parms = (int*) alloca (sizeof (int) * nargs);
+ tpd2.parms = alloca (sizeof (int) * nargs);
tpd2.level =
TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl));
}
@@ -2475,7 +2561,7 @@ process_partial_specialization (decl)
template, not in the specialization. */
tpd2.current_arg = i;
tpd2.arg_uses_template_parms[i] = 0;
- memset ((PTR) tpd2.parms, 0, sizeof (int) * nargs);
+ memset (tpd2.parms, 0, sizeof (int) * nargs);
for_each_template_parm (type,
&mark_template_parm,
&tpd2,
@@ -2518,11 +2604,7 @@ process_partial_specialization (decl)
IS_PARTIAL is nonzero if DECL is a partial specialization. */
static void
-check_default_tmpl_args (decl, parms, is_primary, is_partial)
- tree decl;
- tree parms;
- int is_primary;
- int is_partial;
+check_default_tmpl_args (tree decl, tree parms, int is_primary, int is_partial)
{
const char *msg;
int last_level_to_check;
@@ -2546,14 +2628,15 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
&& DECL_LANG_SPECIFIC (decl)
/* If this is either a friend defined in the scope of the class
or a member function. */
- && ((DECL_CONTEXT (decl)
- && same_type_p (DECL_CONTEXT (decl), current_class_type))
- || (DECL_FRIEND_CONTEXT (decl)
- && same_type_p (DECL_FRIEND_CONTEXT (decl),
- current_class_type)))
+ && (DECL_FUNCTION_MEMBER_P (decl)
+ ? same_type_p (DECL_CONTEXT (decl), current_class_type)
+ : DECL_FRIEND_CONTEXT (decl)
+ ? same_type_p (DECL_FRIEND_CONTEXT (decl), current_class_type)
+ : false)
/* And, if it was a member function, it really was defined in
the scope of the class. */
- && (!DECL_FUNCTION_MEMBER_P (decl) || DECL_INITIALIZED_IN_CLASS_P (decl)))
+ && (!DECL_FUNCTION_MEMBER_P (decl)
+ || DECL_INITIALIZED_IN_CLASS_P (decl)))
/* We already checked these parameters when the template was
declared, so there's no need to do it again now. This function
was defined in class scope, but we're processing it's body now
@@ -2665,9 +2748,7 @@ check_default_tmpl_args (decl, parms, is_primary, is_partial)
parameter of that level, return nonzero. */
static int
-template_parm_this_level_p (t, data)
- tree t;
- void *data;
+template_parm_this_level_p (tree t, void* data)
{
int this_level = *(int *)data;
int level;
@@ -2687,9 +2768,7 @@ template_parm_this_level_p (t, data)
If IS_FRIEND is nonzero, DECL is a friend declaration. */
tree
-push_template_decl_real (decl, is_friend)
- tree decl;
- int is_friend;
+push_template_decl_real (tree decl, int is_friend)
{
tree tmpl;
tree args;
@@ -2736,13 +2815,25 @@ push_template_decl_real (decl, is_friend)
else if (TREE_CODE (decl) == TYPE_DECL
&& ANON_AGGRNAME_P (DECL_NAME (decl)))
error ("template class without a name");
+ else if (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_DESTRUCTOR_P (decl))
+ {
+ /* [temp.mem]
+
+ A destructor shall not be a member template. */
+ error ("destructor `%D' declared as member template", decl);
+ return error_mark_node;
+ }
else if ((DECL_IMPLICIT_TYPEDEF_P (decl)
&& CLASS_TYPE_P (TREE_TYPE (decl)))
|| (TREE_CODE (decl) == VAR_DECL && ctx && CLASS_TYPE_P (ctx))
|| TREE_CODE (decl) == FUNCTION_DECL)
/* OK */;
else
- error ("template declaration of `%#D'", decl);
+ {
+ error ("template declaration of `%#D'", decl);
+ return error_mark_node;
+ }
}
/* Check to see that the rules regarding the use of default
@@ -2757,9 +2848,7 @@ push_template_decl_real (decl, is_friend)
if (!ctx
|| TREE_CODE (ctx) == FUNCTION_DECL
- || (TREE_CODE (ctx) != TEMPLATE_TYPE_PARM
- && TREE_CODE (ctx) != BOUND_TEMPLATE_TEMPLATE_PARM
- && TYPE_BEING_DEFINED (ctx))
+ || (CLASS_TYPE_P (ctx) && TYPE_BEING_DEFINED (ctx))
|| (is_friend && !DECL_TEMPLATE_INFO (decl)))
{
if (DECL_LANG_SPECIFIC (decl)
@@ -2824,10 +2913,10 @@ push_template_decl_real (decl, is_friend)
else
tmpl = DECL_TI_TEMPLATE (decl);
- if (is_member_template (tmpl)
- && DECL_FUNCTION_TEMPLATE_P (tmpl)
+ if (DECL_FUNCTION_TEMPLATE_P (tmpl)
&& DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
- && DECL_TEMPLATE_SPECIALIZATION (decl))
+ && DECL_TEMPLATE_SPECIALIZATION (decl)
+ && is_member_template (tmpl))
{
tree new_tmpl;
@@ -2910,14 +2999,19 @@ push_template_decl_real (decl, is_friend)
/* It is a conversion operator. See if the type converted to
depends on innermost template operands. */
- if (for_each_template_parm (TREE_TYPE (TREE_TYPE (tmpl)),
- template_parm_this_level_p,
- &depth,
- NULL))
+ if (uses_template_parms_level (TREE_TYPE (TREE_TYPE (tmpl)),
+ depth))
DECL_TEMPLATE_CONV_FN_P (tmpl) = 1;
}
}
+ /* The DECL_TI_ARGS of DECL contains full set of arguments refering
+ back to its most general template. If TMPL is a specialization,
+ ARGS may only have the innermost set of arguments. Add the missing
+ argument levels if necessary. */
+ if (DECL_TEMPLATE_INFO (tmpl))
+ args = add_outermost_template_args (DECL_TI_ARGS (tmpl), args);
+
info = tree_cons (tmpl, args, NULL_TREE);
if (DECL_IMPLICIT_TYPEDEF_P (decl))
@@ -2936,8 +3030,7 @@ push_template_decl_real (decl, is_friend)
}
tree
-push_template_decl (decl)
- tree decl;
+push_template_decl (tree decl)
{
return push_template_decl_real (decl, 0);
}
@@ -2949,9 +3042,7 @@ push_template_decl (decl)
template <class T> struct S {}; */
void
-redeclare_class_template (type, parms)
- tree type;
- tree parms;
+redeclare_class_template (tree type, tree parms)
{
tree tmpl;
tree tmpl_parms;
@@ -3004,7 +3095,7 @@ redeclare_class_template (type, parms)
A template-parameter may not be given default arguments
by two different declarations in the same scope. */
error ("redefinition of default argument for `%#D'", parm);
- cp_error_at (" original definition appeared here", tmpl_parm);
+ error ("%J original definition appeared here", tmpl_parm);
return;
}
@@ -3019,22 +3110,60 @@ redeclare_class_template (type, parms)
}
}
+/* Simplify EXPR if it is a non-dependent expression. Returns the
+ (possibly simplified) expression. */
+
+tree
+fold_non_dependent_expr (tree expr)
+{
+ /* If we're in a template, but EXPR isn't value dependent, simplify
+ it. We're supposed to treat:
+
+ template <typename T> void f(T[1 + 1]);
+ template <typename T> void f(T[2]);
+
+ as two declarations of the same function, for example. */
+ if (processing_template_decl
+ && !type_dependent_expression_p (expr)
+ && !value_dependent_expression_p (expr))
+ {
+ HOST_WIDE_INT saved_processing_template_decl;
+
+ saved_processing_template_decl = processing_template_decl;
+ processing_template_decl = 0;
+ expr = tsubst_copy_and_build (expr,
+ /*args=*/NULL_TREE,
+ tf_error,
+ /*in_decl=*/NULL_TREE,
+ /*function_p=*/false);
+ processing_template_decl = saved_processing_template_decl;
+ }
+ return expr;
+}
+
/* Attempt to convert the non-type template parameter EXPR to the
indicated TYPE. If the conversion is successful, return the
converted value. If the conversion is unsuccessful, return
NULL_TREE if we issued an error message, or error_mark_node if we
did not. We issue error messages for out-and-out bad template
parameters, but not simply because the conversion failed, since we
- might be just trying to do argument deduction. By the time this
- function is called, neither TYPE nor EXPR may make use of template
- parameters. */
+ might be just trying to do argument deduction. Both TYPE and EXPR
+ must be non-dependent. */
static tree
-convert_nontype_argument (type, expr)
- tree type;
- tree expr;
+convert_nontype_argument (tree type, tree expr)
{
- tree expr_type = TREE_TYPE (expr);
+ tree expr_type;
+
+ /* If we are in a template, EXPR may be non-dependent, but still
+ have a syntactic, rather than semantic, form. For example, EXPR
+ might be a SCOPE_REF, rather than the VAR_DECL to which the
+ SCOPE_REF refers. Preserving the qualifying scope is necessary
+ so that access checking can be performed when the template is
+ instantiated -- but here we need the resolved form so that we can
+ convert the argument. */
+ expr = fold_non_dependent_expr (expr);
+ expr_type = TREE_TYPE (expr);
/* A template-argument for a non-type, non-template
template-parameter shall be one of:
@@ -3058,26 +3187,43 @@ convert_nontype_argument (type, expr)
--a pointer to member expressed as described in _expr.unary.op_. */
/* An integral constant-expression can include const variables or
- enumerators. Simplify things by folding them to their values,
+. enumerators. Simplify things by folding them to their values,
unless we're about to bind the declaration to a reference
parameter. */
- if (INTEGRAL_TYPE_P (expr_type)
- && TREE_CODE (type) != REFERENCE_TYPE)
- expr = decl_constant_value (expr);
+ if (INTEGRAL_TYPE_P (expr_type) && TREE_CODE (type) != REFERENCE_TYPE)
+ while (true)
+ {
+ tree const_expr = decl_constant_value (expr);
+ /* In a template, the initializer for a VAR_DECL may not be
+ marked as TREE_CONSTANT, in which case decl_constant_value
+ will not return the initializer. Handle that special case
+ here. */
+ if (expr == const_expr
+ && TREE_CODE (expr) == VAR_DECL
+ && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (expr)
+ && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (expr))
+ /* DECL_INITIAL can be NULL if we are processing a
+ variable initialized to an expression involving itself.
+ We know it is initialized to a constant -- but not what
+ constant, yet. */
+ && DECL_INITIAL (expr))
+ const_expr = DECL_INITIAL (expr);
+ if (expr == const_expr)
+ break;
+ expr = fold_non_dependent_expr (const_expr);
+ }
if (is_overloaded_fn (expr))
/* OK for now. We'll check that it has external linkage later.
Check this first since if expr_type is the unknown_type_node
we would otherwise complain below. */
;
- else if (TYPE_PTRMEM_P (expr_type)
- || TYPE_PTRMEMFUNC_P (expr_type))
+ else if (TYPE_PTR_TO_MEMBER_P (expr_type))
{
if (TREE_CODE (expr) != PTRMEM_CST)
goto bad_argument;
}
else if (TYPE_PTR_P (expr_type)
- || TYPE_PTRMEM_P (expr_type)
|| TREE_CODE (expr_type) == ARRAY_TYPE
|| TREE_CODE (type) == REFERENCE_TYPE
/* If expr is the address of an overloaded function, we
@@ -3105,8 +3251,7 @@ convert_nontype_argument (type, expr)
else
error ("it must be the address of an object with external linkage");
}
- else if (TYPE_PTRMEM_P (expr_type)
- || TYPE_PTRMEMFUNC_P (expr_type))
+ else if (TYPE_PTR_TO_MEMBER_P (expr_type))
error ("it must be a pointer-to-member of the form `&X::Y'");
return NULL_TREE;
@@ -3123,6 +3268,9 @@ convert_nontype_argument (type, expr)
return NULL_TREE;
}
+ if (TREE_CODE (referent) == SCOPE_REF)
+ referent = TREE_OPERAND (referent, 1);
+
if (is_overloaded_fn (referent))
/* We'll check that it has external linkage later. */
;
@@ -3134,9 +3282,7 @@ convert_nontype_argument (type, expr)
return error_mark_node;
}
}
- else if (INTEGRAL_TYPE_P (expr_type)
- || TYPE_PTRMEM_P (expr_type)
- || TYPE_PTRMEMFUNC_P (expr_type))
+ else if (INTEGRAL_TYPE_P (expr_type) || TYPE_PTR_TO_MEMBER_P (expr_type))
{
if (! TREE_CONSTANT (expr))
{
@@ -3148,7 +3294,14 @@ convert_nontype_argument (type, expr)
}
else
{
- error ("object `%E' cannot be used as template argument", expr);
+ if (TYPE_P (expr))
+ error ("type '%T' cannot be used as a value for a non-type "
+ "template-parameter", expr);
+ else if (DECL_P (expr))
+ error ("invalid use of '%D' as a non-type template-argument", expr);
+ else
+ error ("invalid use of '%E' as a non-type template-argument", expr);
+
return NULL_TREE;
}
@@ -3174,31 +3327,32 @@ convert_nontype_argument (type, expr)
goto non_constant;
return expr;
-
+
+ case OFFSET_TYPE:
+ {
+ tree e;
+
+ /* For a non-type template-parameter of type pointer to data
+ member, qualification conversions (_conv.qual_) are
+ applied. */
+ e = perform_qualification_conversions (type, expr);
+ if (TREE_CODE (e) == NOP_EXPR)
+ /* The call to perform_qualification_conversions will
+ insert a NOP_EXPR over EXPR to do express conversion,
+ if necessary. But, that will confuse us if we use
+ this (converted) template parameter to instantiate
+ another template; then the thing will not look like a
+ valid template argument. So, just make a new
+ constant, of the appropriate type. */
+ e = make_ptrmem_cst (type, PTRMEM_CST_MEMBER (expr));
+ return e;
+ }
+
case POINTER_TYPE:
{
tree type_pointed_to = TREE_TYPE (type);
- if (TYPE_PTRMEM_P (type))
- {
- tree e;
-
- /* For a non-type template-parameter of type pointer to data
- member, qualification conversions (_conv.qual_) are
- applied. */
- e = perform_qualification_conversions (type, expr);
- if (TREE_CODE (e) == NOP_EXPR)
- /* The call to perform_qualification_conversions will
- insert a NOP_EXPR over EXPR to do express conversion,
- if necessary. But, that will confuse us if we use
- this (converted) template parameter to instantiate
- another template; then the thing will not look like a
- valid template argument. So, just make a new
- constant, of the appropriate type. */
- e = make_ptrmem_cst (type, PTRMEM_CST_MEMBER (expr));
- return e;
- }
- else if (TREE_CODE (type_pointed_to) == FUNCTION_TYPE)
+ if (TREE_CODE (type_pointed_to) == FUNCTION_TYPE)
{
/* For a non-type template-parameter of type pointer to
function, only the function-to-pointer conversion
@@ -3262,9 +3416,12 @@ convert_nontype_argument (type, expr)
tree type_referred_to = TREE_TYPE (type);
/* If this expression already has reference type, get the
- underling object. */
+ underlying object. */
if (TREE_CODE (expr_type) == REFERENCE_TYPE)
{
+ if (TREE_CODE (expr) == NOP_EXPR
+ && TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
+ STRIP_NOPS (expr);
my_friendly_assert (TREE_CODE (expr) == ADDR_EXPR, 20000604);
expr = TREE_OPERAND (expr, 0);
expr_type = TREE_TYPE (expr);
@@ -3318,7 +3475,7 @@ convert_nontype_argument (type, expr)
}
cxx_mark_addressable (expr);
- return build1 (ADDR_EXPR, type, expr);
+ return build_nop (type, build_address (expr));
}
break;
@@ -3353,8 +3510,9 @@ convert_nontype_argument (type, expr)
if (expr == error_mark_node)
return error_mark_node;
- my_friendly_assert (same_type_p (type, TREE_TYPE (expr)),
- 0);
+ if (!same_type_p (type, TREE_TYPE (expr)))
+ return error_mark_node;
+
return expr;
}
break;
@@ -3386,11 +3544,11 @@ convert_nontype_argument (type, expr)
substitute the TT parameter. */
static int
-coerce_template_template_parms (parm_parms, arg_parms, complain,
- in_decl, outer_args)
- tree parm_parms, arg_parms;
- tsubst_flags_t complain;
- tree in_decl, outer_args;
+coerce_template_template_parms (tree parm_parms,
+ tree arg_parms,
+ tsubst_flags_t complain,
+ tree in_decl,
+ tree outer_args)
{
int nparms, nargs, i;
tree parm, arg;
@@ -3432,9 +3590,8 @@ coerce_template_template_parms (parm_parms, arg_parms, complain,
tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
- if (!coerce_template_template_parms (parmparm, argparm,
- complain, in_decl,
- outer_args))
+ if (!coerce_template_template_parms
+ (parmparm, argparm, complain, in_decl, outer_args))
return 0;
}
break;
@@ -3443,9 +3600,9 @@ coerce_template_template_parms (parm_parms, arg_parms, complain,
/* The tsubst call is used to handle cases such as
template <class T, template <T> class TT> class D;
i.e. the parameter list of TT depends on earlier parameters. */
- if (!same_type_p (tsubst (TREE_TYPE (parm), outer_args,
- complain, in_decl),
- TREE_TYPE (arg)))
+ if (!same_type_p
+ (tsubst (TREE_TYPE (parm), outer_args, complain, in_decl),
+ TREE_TYPE (arg)))
return 0;
break;
@@ -3464,13 +3621,12 @@ coerce_template_template_parms (parm_parms, arg_parms, complain,
the full set of template arguments deduced so far. */
static tree
-convert_template_argument (parm, arg, args, complain, i, in_decl)
- tree parm;
- tree arg;
- tree args;
- tsubst_flags_t complain;
- int i;
- tree in_decl;
+convert_template_argument (tree parm,
+ tree arg,
+ tree args,
+ tsubst_flags_t complain,
+ int i,
+ tree in_decl)
{
tree val;
tree inner_args;
@@ -3479,8 +3635,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
inner_args = INNERMOST_TEMPLATE_ARGS (args);
if (TREE_CODE (arg) == TREE_LIST
- && TREE_TYPE (arg) != NULL_TREE
- && TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
+ && TREE_CODE (TREE_VALUE (arg)) == OFFSET_REF)
{
/* The template argument was the name of some
member function. That's usually
@@ -3495,28 +3650,15 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
requires_type = (TREE_CODE (parm) == TYPE_DECL
|| requires_tmpl_type);
- if (TREE_CODE (arg) != RECORD_TYPE)
- is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL
- && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
- || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
- || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
- else if (CLASSTYPE_IS_TEMPLATE (arg)
- && is_base_of_enclosing_class (arg, current_class_type))
- /* This is a template name used within the scope of the
- template. It could be the template, or it could be the
- instantiation. Choose whichever makes sense. */
- is_tmpl_type = requires_tmpl_type;
- else
- /* It is a non-template class, or a specialization of a template
- class, or a non-template member of a template class. */
- is_tmpl_type = 0;
+ is_tmpl_type = ((TREE_CODE (arg) == TEMPLATE_DECL
+ && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL)
+ || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
+ || TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE);
if (is_tmpl_type
&& (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM
|| TREE_CODE (arg) == UNBOUND_CLASS_TEMPLATE))
arg = TYPE_STUB_DECL (arg);
- else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE)
- arg = CLASSTYPE_TI_TEMPLATE (arg);
is_type = TYPE_P (arg) || is_tmpl_type;
@@ -3542,6 +3684,8 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
error (" expected a constant of type `%T', got `%T'",
TREE_TYPE (parm),
(is_tmpl_type ? DECL_NAME (arg) : arg));
+ else if (requires_tmpl_type)
+ error (" expected a class template, got `%E'", arg);
else
error (" expected a type, got `%E'", arg);
}
@@ -3601,39 +3745,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
}
}
else
- {
- val = groktypename (arg);
- if (! processing_template_decl)
- {
- /* [basic.link]: A name with no linkage (notably, the
- name of a class or enumeration declared in a local
- scope) shall not be used to declare an entity with
- linkage. This implies that names with no linkage
- cannot be used as template arguments. */
- tree t = no_linkage_check (val);
- if (t)
- {
- if (TYPE_ANONYMOUS_P (t))
- pedwarn
- ("template-argument `%T' uses anonymous type", val);
- else
- error
- ("template-argument `%T' uses local type `%T'",
- val, t);
- return error_mark_node;
- }
-
- /* In order to avoid all sorts of complications, we do
- not allow variably-modified types as template
- arguments. */
- if (variably_modified_type_p (val))
- {
- error ("template-argument `%T' is a variably modified type",
- val);
- return error_mark_node;
- }
- }
- }
+ val = groktypename (arg);
}
else
{
@@ -3642,9 +3754,6 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
if (invalid_nontype_parm_type_p (t, complain))
return error_mark_node;
- if (processing_template_decl)
- arg = maybe_fold_nontype_arg (arg);
-
if (!uses_template_parms (arg) && !uses_template_parms (t))
/* We used to call digest_init here. However, digest_init
will report errors, which we don't want when complain
@@ -3673,9 +3782,7 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
/* Convert all template arguments to their appropriate types, and
return a vector containing the innermost resulting template
arguments. If any error occurs, return error_mark_node. Error and
- warning messages are issued under control of COMPLAIN. Some error
- messages are issued even if COMPLAIN is zero; for instance, if a
- template argument is composed from a local class.
+ warning messages are issued under control of COMPLAIN.
If REQUIRE_ALL_ARGUMENTS is nonzero, all arguments must be
provided in ARGLIST, or else trailing parameters must have default
@@ -3683,13 +3790,11 @@ convert_template_argument (parm, arg, args, complain, i, in_decl)
deduction for any unspecified trailing arguments. */
static tree
-coerce_template_parms (parms, args, in_decl,
- complain,
- require_all_arguments)
- tree parms, args;
- tree in_decl;
- tsubst_flags_t complain;
- int require_all_arguments;
+coerce_template_parms (tree parms,
+ tree args,
+ tree in_decl,
+ tsubst_flags_t complain,
+ int require_all_arguments)
{
int nparms, nargs, i, lost = 0;
tree inner_args;
@@ -3697,7 +3802,7 @@ coerce_template_parms (parms, args, in_decl,
tree new_inner_args;
inner_args = INNERMOST_TEMPLATE_ARGS (args);
- nargs = NUM_TMPL_ARGS (inner_args);
+ nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
nparms = TREE_VEC_LENGTH (parms);
if (nargs > nparms
@@ -3728,39 +3833,18 @@ coerce_template_parms (parms, args, in_decl,
parm = TREE_VEC_ELT (parms, i);
/* Calculate the Ith argument. */
- if (inner_args && TREE_CODE (inner_args) == TREE_LIST)
- {
- arg = TREE_VALUE (inner_args);
- inner_args = TREE_CHAIN (inner_args);
- }
- else if (i < nargs)
+ if (i < nargs)
arg = TREE_VEC_ELT (inner_args, i);
- /* If no template argument was supplied, look for a default
- value. */
- else if (TREE_PURPOSE (parm) == NULL_TREE)
- {
- /* There was no default value. */
- my_friendly_assert (!require_all_arguments, 0);
- break;
- }
- else if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL)
- arg = tsubst (TREE_PURPOSE (parm), new_args, complain, in_decl);
+ else if (require_all_arguments)
+ /* There must be a default arg in this case. */
+ arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args,
+ complain, in_decl);
else
- arg = tsubst_expr (TREE_PURPOSE (parm), new_args, complain,
- in_decl);
-
- /* Now, convert the Ith argument, as necessary. */
- if (arg == NULL_TREE)
- /* We're out of arguments. */
- {
- my_friendly_assert (!require_all_arguments, 0);
- break;
- }
- else if (arg == error_mark_node)
- {
- error ("template argument %d is invalid", i + 1);
- arg = error_mark_node;
- }
+ break;
+
+ my_friendly_assert (arg, 20030727);
+ if (arg == error_mark_node)
+ error ("template argument %d is invalid", i + 1);
else
arg = convert_template_argument (TREE_VALUE (parm),
arg, new_args, complain, i,
@@ -3780,8 +3864,7 @@ coerce_template_parms (parms, args, in_decl,
/* Returns 1 if template args OT and NT are equivalent. */
static int
-template_args_equal (ot, nt)
- tree ot, nt;
+template_args_equal (tree ot, tree nt)
{
if (nt == ot)
return 1;
@@ -3794,15 +3877,14 @@ template_args_equal (ot, nt)
else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
return 0;
else
- return (cp_tree_equal (ot, nt) > 0);
+ return cp_tree_equal (ot, nt);
}
/* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets
of template arguments. Returns 0 otherwise. */
int
-comp_template_args (oldargs, newargs)
- tree oldargs, newargs;
+comp_template_args (tree oldargs, tree newargs)
{
int i;
@@ -3824,9 +3906,7 @@ comp_template_args (oldargs, newargs)
for the instantiation. */
static char *
-mangle_class_name_for_template (name, parms, arglist)
- const char *name;
- tree parms, arglist;
+mangle_class_name_for_template (const char* name, tree parms, tree arglist)
{
static struct obstack scratch_obstack;
static char *scratch_firstobj;
@@ -3879,20 +3959,13 @@ mangle_class_name_for_template (name, parms, arglist)
cat (IDENTIFIER_POINTER (DECL_NAME (arg)));
}
else
- /* Output the parameter declaration */
+ /* Output the parameter declaration. */
cat (type_as_string (arg, TFF_CHASE_TYPEDEF));
continue;
}
else
my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269);
- if (TREE_CODE (arg) == TREE_LIST)
- {
- /* New list cell was built because old chain link was in
- use. */
- my_friendly_assert (TREE_PURPOSE (arg) == NULL_TREE, 270);
- arg = TREE_VALUE (arg);
- }
/* No need to check arglist against parmlist here; we did that
in coerce_template_parms, called from lookup_template_class. */
cat (expr_as_string (arg, TFF_PLAIN_IDENTIFIER));
@@ -3914,8 +3987,7 @@ mangle_class_name_for_template (name, parms, arglist)
}
static tree
-classtype_mangled_name (t)
- tree t;
+classtype_mangled_name (tree t)
{
if (CLASSTYPE_TEMPLATE_INFO (t)
/* Specializations have already had their names set up in
@@ -3943,8 +4015,7 @@ classtype_mangled_name (t)
}
static void
-add_pending_template (d)
- tree d;
+add_pending_template (tree d)
{
tree ti = (TYPE_P (d)
? CLASSTYPE_TEMPLATE_INFO (d)
@@ -3983,15 +4054,15 @@ add_pending_template (d)
documentation for TEMPLATE_ID_EXPR. */
tree
-lookup_template_function (fns, arglist)
- tree fns, arglist;
+lookup_template_function (tree fns, tree arglist)
{
tree type;
if (fns == error_mark_node || arglist == error_mark_node)
return error_mark_node;
- if (fns == NULL_TREE
+ my_friendly_assert (!arglist || TREE_CODE (arglist) == TREE_VEC, 20030726);
+ if (fns == NULL_TREE
|| TREE_CODE (fns) == FUNCTION_DECL)
{
error ("non-template used as template");
@@ -4001,8 +4072,7 @@ lookup_template_function (fns, arglist)
my_friendly_assert (TREE_CODE (fns) == TEMPLATE_DECL
|| TREE_CODE (fns) == OVERLOAD
|| BASELINK_P (fns)
- || TREE_CODE (fns) == IDENTIFIER_NODE
- || TREE_CODE (fns) == LOOKUP_EXPR,
+ || TREE_CODE (fns) == IDENTIFIER_NODE,
20020730);
if (BASELINK_P (fns))
@@ -4028,9 +4098,8 @@ lookup_template_function (fns, arglist)
return the associated TEMPLATE_DECL. Otherwise, the original
DECL is returned. */
-static tree
-maybe_get_template_decl_from_type_decl (decl)
- tree decl;
+tree
+maybe_get_template_decl_from_type_decl (tree decl)
{
return (decl != NULL_TREE
&& TREE_CODE (decl) == TYPE_DECL
@@ -4044,9 +4113,6 @@ maybe_get_template_decl_from_type_decl (decl)
parameters, find the desired type.
D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments.
- (Actually ARGLIST may be either a TREE_LIST or a TREE_VEC. It will
- be a TREE_LIST if called directly from the parser, and a TREE_VEC
- otherwise.)
IN_DECL, if non-NULL, is the template declaration we are trying to
instantiate.
@@ -4061,17 +4127,18 @@ maybe_get_template_decl_from_type_decl (decl)
being instantiated. */
tree
-lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
- tree d1, arglist;
- tree in_decl;
- tree context;
- int entering_scope;
- tsubst_flags_t complain;
+lookup_template_class (tree d1,
+ tree arglist,
+ tree in_decl,
+ tree context,
+ int entering_scope,
+ tsubst_flags_t complain)
{
tree template = NULL_TREE, parmlist;
tree t;
-
+
timevar_push (TV_NAME_LOOKUP);
+
if (TREE_CODE (d1) == IDENTIFIER_NODE)
{
if (IDENTIFIER_VALUE (d1)
@@ -4088,20 +4155,10 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
}
if (template)
context = DECL_CONTEXT (template);
- if (template
- && TREE_CODE (template) == TYPE_DECL
- && IS_AGGR_TYPE (TREE_TYPE (template))
- && TREE_CODE (TREE_TYPE (template)) != TEMPLATE_TYPE_PARM)
- {
- d1 = template;
- goto type_decl;
- }
}
else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE (d1)))
{
- tree type;
- type_decl:
- type = TREE_TYPE (d1);
+ tree type = TREE_TYPE (d1);
/* If we are declaring a constructor, say A<T>::A<T>, we will get
an implicit typename for the second A. Deal with it. */
@@ -4141,11 +4198,10 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
}
if (TREE_CODE (template) != TEMPLATE_DECL
- /* If we're called from the parser, make sure it's a user visible
- template. */
- || ((!arglist || TREE_CODE (arglist) == TREE_LIST)
- && !DECL_TEMPLATE_PARM_P (template)
- && !PRIMARY_TEMPLATE_P (template)))
+ /* Make sure it's a user visible template, if it was named by
+ the user. */
+ || ((complain & tf_user) && !DECL_TEMPLATE_PARM_P (template)
+ && !PRIMARY_TEMPLATE_P (template)))
{
if (complain & tf_error)
{
@@ -4156,6 +4212,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
}
+ complain &= ~tf_user;
+
if (DECL_TEMPLATE_TEMPLATE_PARM_P (template))
{
/* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store
@@ -4187,8 +4245,10 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
arglist2 = coerce_template_parms (parmlist, arglist, template,
complain, /*require_all_args=*/1);
- if (arglist2 == error_mark_node)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ if (arglist2 == error_mark_node
+ || (!uses_template_parms (arglist2)
+ && check_instantiated_args (template, arglist2, complain)))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
parm = bind_template_template_parm (TREE_TYPE (template), arglist2);
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, parm);
@@ -4255,6 +4315,15 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
tree a = coerce_template_parms (TREE_VALUE (t),
arglist, template,
complain, /*require_all_args=*/1);
+
+ /* Don't process further if one of the levels fails. */
+ if (a == error_mark_node)
+ {
+ /* Restore the ARGLIST to its full size. */
+ TREE_VEC_LENGTH (arglist) = saved_depth;
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+ }
+
SET_TMPL_ARGS_LEVEL (bound_args, i, a);
/* We temporarily reduce the length of the ARGLIST so
@@ -4297,21 +4366,18 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
{
tree ctx;
- /* Note that we use DECL_CONTEXT, rather than
- CP_DECL_CONTEXT, so that the termination test is
- always just `ctx'. We're not interested in namespace
- scopes. */
for (ctx = current_class_type;
- ctx;
- ctx = (TYPE_P (ctx)) ? TYPE_CONTEXT (ctx) : DECL_CONTEXT (ctx))
- if (same_type_p (ctx, template_type))
- break;
+ ctx && TREE_CODE (ctx) != NAMESPACE_DECL;
+ ctx = (TYPE_P (ctx)
+ ? TYPE_CONTEXT (ctx)
+ : DECL_CONTEXT (ctx)))
+ if (TYPE_P (ctx) && same_type_p (ctx, template_type))
+ goto found_ctx;
- if (!ctx)
- /* We're not in the scope of the class, so the
- TEMPLATE_TYPE is not the type we want after
- all. */
- found = NULL_TREE;
+ /* We're not in the scope of the class, so the
+ TEMPLATE_TYPE is not the type we want after all. */
+ found = NULL_TREE;
+ found_ctx:;
}
}
if (found)
@@ -4340,6 +4406,14 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
well. */
is_partial_instantiation = uses_template_parms (arglist);
+ /* If the deduced arguments are invalid, then the binding
+ failed. */
+ if (!is_partial_instantiation
+ && check_instantiated_args (template,
+ INNERMOST_TEMPLATE_ARGS (arglist),
+ complain))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+
if (!is_partial_instantiation
&& !PRIMARY_TEMPLATE_P (template)
&& TREE_CODE (CP_DECL_CONTEXT (template)) == NAMESPACE_DECL)
@@ -4375,7 +4449,6 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
t = make_aggr_type (TREE_CODE (template_type));
CLASSTYPE_DECLARED_CLASS (t)
= CLASSTYPE_DECLARED_CLASS (template_type);
- CLASSTYPE_GOT_SEMICOLON (t) = 1;
SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);
TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA (template_type);
@@ -4486,19 +4559,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope, complain)
is set up. */
if (TREE_CODE (t) != ENUMERAL_TYPE)
DECL_NAME (type_decl) = classtype_mangled_name (t);
- if (!is_partial_instantiation)
- {
- /* For backwards compatibility; code that uses
- -fexternal-templates expects looking up a template to
- instantiate it. I think DDD still relies on this.
- (jason 8/20/1998) */
- if (TREE_CODE (t) != ENUMERAL_TYPE
- && flag_external_templates
- && CLASSTYPE_INTERFACE_KNOWN (TREE_TYPE (template))
- && ! CLASSTYPE_INTERFACE_ONLY (TREE_TYPE (template)))
- add_pending_template (t);
- }
- else
+ if (is_partial_instantiation)
/* If the type makes use of template parameters, the
code that generates debugging information will crash. */
DECL_IGNORED_P (TYPE_STUB_DECL (t)) = 1;
@@ -4518,26 +4579,12 @@ struct pair_fn_data
/* Called from for_each_template_parm via walk_tree. */
static tree
-for_each_template_parm_r (tp, walk_subtrees, d)
- tree *tp;
- int *walk_subtrees;
- void *d;
+for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d)
{
tree t = *tp;
struct pair_fn_data *pfd = (struct pair_fn_data *) d;
tree_fn_t fn = pfd->fn;
void *data = pfd->data;
- void **slot;
-
- /* If we have already visited this tree, there's no need to walk
- subtrees. Otherwise, add it to the visited table. */
- slot = htab_find_slot (pfd->visited, *tp, INSERT);
- if (*slot)
- {
- *walk_subtrees = 0;
- return NULL_TREE;
- }
- *slot = *tp;
if (TYPE_P (t)
&& for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited))
@@ -4592,6 +4639,12 @@ for_each_template_parm_r (tp, walk_subtrees, d)
}
break;
+ case TYPEOF_TYPE:
+ if (for_each_template_parm (TYPE_FIELDS (t), fn, data,
+ pfd->visited))
+ return error_mark_node;
+ break;
+
case FUNCTION_DECL:
case VAR_DECL:
if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
@@ -4600,8 +4653,12 @@ for_each_template_parm_r (tp, walk_subtrees, d)
return error_mark_node;
/* Fall through. */
- case CONST_DECL:
case PARM_DECL:
+ case CONST_DECL:
+ if (TREE_CODE (t) == CONST_DECL && DECL_TEMPLATE_PARM_P (t)
+ && for_each_template_parm (DECL_INITIAL (t), fn, data,
+ pfd->visited))
+ return error_mark_node;
if (DECL_CONTEXT (t)
&& for_each_template_parm (DECL_CONTEXT (t), fn, data,
pfd->visited))
@@ -4624,7 +4681,7 @@ for_each_template_parm_r (tp, walk_subtrees, d)
break;
case TEMPLATE_DECL:
- /* A template template parameter is encountered */
+ /* A template template parameter is encountered. */
if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)
&& for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited))
return error_mark_node;
@@ -4665,7 +4722,6 @@ for_each_template_parm_r (tp, walk_subtrees, d)
case ARROW_EXPR:
case DOTSTAR_EXPR:
case TYPEID_EXPR:
- case LOOKUP_EXPR:
case PSEUDO_DTOR_EXPR:
if (!fn)
return error_mark_node;
@@ -4699,11 +4755,7 @@ for_each_template_parm_r (tp, walk_subtrees, d)
considered to be the function which always returns 1. */
static int
-for_each_template_parm (t, fn, data, visited)
- tree t;
- tree_fn_t fn;
- void* data;
- htab_t visited;
+for_each_template_parm (tree t, tree_fn_t fn, void* data, htab_t visited)
{
struct pair_fn_data pfd;
int result;
@@ -4725,7 +4777,7 @@ for_each_template_parm (t, fn, data, visited)
result = walk_tree (&t,
for_each_template_parm_r,
&pfd,
- NULL) != NULL_TREE;
+ pfd.visited) != NULL_TREE;
/* Clean up. */
if (!visited)
@@ -4734,11 +4786,47 @@ for_each_template_parm (t, fn, data, visited)
return result;
}
+/* Returns true if T depends on any template parameter. */
+
+int
+uses_template_parms (tree t)
+{
+ bool dependent_p;
+ int saved_processing_template_decl;
+
+ saved_processing_template_decl = processing_template_decl;
+ if (!saved_processing_template_decl)
+ processing_template_decl = 1;
+ if (TYPE_P (t))
+ dependent_p = dependent_type_p (t);
+ else if (TREE_CODE (t) == TREE_VEC)
+ dependent_p = any_dependent_template_arguments_p (t);
+ else if (TREE_CODE (t) == TREE_LIST)
+ dependent_p = (uses_template_parms (TREE_VALUE (t))
+ || uses_template_parms (TREE_CHAIN (t)));
+ else if (DECL_P (t)
+ || EXPR_P (t)
+ || TREE_CODE (t) == TEMPLATE_PARM_INDEX
+ || TREE_CODE (t) == OVERLOAD
+ || TREE_CODE (t) == BASELINK
+ || TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
+ dependent_p = (type_dependent_expression_p (t)
+ || value_dependent_expression_p (t));
+ else if (t == error_mark_node)
+ dependent_p = false;
+ else
+ abort ();
+ processing_template_decl = saved_processing_template_decl;
+
+ return dependent_p;
+}
+
+/* Returns true if T depends on any template parameter with level LEVEL. */
+
int
-uses_template_parms (t)
- tree t;
+uses_template_parms_level (tree t, int level)
{
- return for_each_template_parm (t, 0, 0, NULL);
+ return for_each_template_parm (t, template_parm_this_level_p, &level, NULL);
}
static int tinst_depth;
@@ -4753,8 +4841,7 @@ static int last_template_error_tick;
for diagnostics and to restore it later. */
int
-push_tinst_level (d)
- tree d;
+push_tinst_level (tree d)
{
tree new;
@@ -4775,7 +4862,7 @@ push_tinst_level (d)
return 0;
}
- new = build_expr_wfl (d, input_filename, lineno, 0);
+ new = build_expr_wfl (d, input_filename, input_line, 0);
TREE_CHAIN (new) = current_tinst_level;
current_tinst_level = new;
@@ -4793,13 +4880,13 @@ push_tinst_level (d)
context. */
void
-pop_tinst_level ()
+pop_tinst_level (void)
{
tree old = current_tinst_level;
/* Restore the filename and line number stashed away when we started
this instantiation. */
- lineno = TINST_LINE (old);
+ input_line = TINST_LINE (old);
input_filename = TINST_FILE (old);
extract_interface_info ();
@@ -4813,8 +4900,7 @@ pop_tinst_level ()
is one step out from LEVEL. */
static void
-reopen_tinst_level (level)
- tree level;
+reopen_tinst_level (tree level)
{
tree t;
@@ -4830,7 +4916,7 @@ reopen_tinst_level (level)
-falt-external-templates. */
tree
-tinst_for_decl ()
+tinst_for_decl (void)
{
tree p = current_tinst_level;
@@ -4846,16 +4932,12 @@ tinst_for_decl ()
Returns an appropriate tsubst'd friend declaration. */
static tree
-tsubst_friend_function (decl, args)
- tree decl;
- tree args;
+tsubst_friend_function (tree decl, tree args)
{
tree new_friend;
- int line = lineno;
- const char *file = input_filename;
+ location_t saved_loc = input_location;
- lineno = DECL_SOURCE_LINE (decl);
- input_filename = DECL_SOURCE_FILE (decl);
+ input_location = DECL_SOURCE_LOCATION (decl);
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_TEMPLATE_INSTANTIATION (decl)
@@ -4889,7 +4971,7 @@ tsubst_friend_function (decl, args)
tmpl = determine_specialization (template_id, new_friend,
&new_args,
/*need_member_template=*/0);
- new_friend = instantiate_template (tmpl, new_args);
+ new_friend = instantiate_template (tmpl, new_args, tf_error);
goto done;
}
@@ -4905,6 +4987,9 @@ tsubst_friend_function (decl, args)
Then, in S<int>, template <class U> void f(int, U) is not an
instantiation of anything. */
+ if (new_friend == error_mark_node)
+ return error_mark_node;
+
DECL_USE_TEMPLATE (new_friend) = 0;
if (TREE_CODE (decl) == TEMPLATE_DECL)
{
@@ -4935,21 +5020,20 @@ tsubst_friend_function (decl, args)
duplicate decls since that function will free NEW_FRIEND if
possible. */
new_friend_template_info = DECL_TEMPLATE_INFO (new_friend);
+ new_friend_is_defn =
+ (DECL_INITIAL (DECL_TEMPLATE_RESULT
+ (template_for_substitution (new_friend)))
+ != NULL_TREE);
if (TREE_CODE (new_friend) == TEMPLATE_DECL)
{
/* This declaration is a `primary' template. */
DECL_PRIMARY_TEMPLATE (new_friend) = new_friend;
- new_friend_is_defn
- = DECL_INITIAL (DECL_TEMPLATE_RESULT (new_friend)) != NULL_TREE;
new_friend_result_template_info
= DECL_TEMPLATE_INFO (DECL_TEMPLATE_RESULT (new_friend));
}
else
- {
- new_friend_is_defn = DECL_INITIAL (new_friend) != NULL_TREE;
- new_friend_result_template_info = NULL_TREE;
- }
+ new_friend_result_template_info = NULL_TREE;
/* Inside pushdecl_namespace_level, we will push into the
current namespace. However, the friend function should go
@@ -5056,15 +5140,14 @@ tsubst_friend_function (decl, args)
/* Check to see that the declaration is really present, and,
possibly obtain an improved declaration. */
tree fn = check_classfn (DECL_CONTEXT (new_friend),
- new_friend);
+ new_friend, false);
if (fn)
new_friend = fn;
}
done:
- lineno = line;
- input_filename = file;
+ input_location = saved_loc;
return new_friend;
}
@@ -5075,9 +5158,7 @@ tsubst_friend_function (decl, args)
failure. */
static tree
-tsubst_friend_class (friend_tmpl, args)
- tree friend_tmpl;
- tree args;
+tsubst_friend_class (tree friend_tmpl, tree args)
{
tree friend_type;
tree tmpl;
@@ -5090,7 +5171,7 @@ tsubst_friend_class (friend_tmpl, args)
if (TREE_CODE (context) == NAMESPACE_DECL)
push_nested_namespace (context);
else
- push_nested_class (tsubst (context, args, tf_none, NULL_TREE), 2);
+ push_nested_class (tsubst (context, args, tf_none, NULL_TREE));
}
/* First, we look for a class template. */
@@ -5146,6 +5227,8 @@ tsubst_friend_class (friend_tmpl, args)
DECL_USE_TEMPLATE (tmpl) = 0;
DECL_TEMPLATE_INFO (tmpl) = NULL_TREE;
CLASSTYPE_USE_TEMPLATE (TREE_TYPE (tmpl)) = 0;
+ CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl))
+ = INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (TREE_TYPE (tmpl)));
/* Inject this template into the global scope. */
friend_type = TREE_TYPE (pushdecl_top_level (tmpl));
@@ -5166,8 +5249,7 @@ tsubst_friend_class (friend_tmpl, args)
Otherwise returns one. */
static int
-can_complete_type_without_circularity (type)
- tree type;
+can_complete_type_without_circularity (tree type)
{
if (type == NULL_TREE || type == error_mark_node)
return 0;
@@ -5175,23 +5257,26 @@ can_complete_type_without_circularity (type)
return 1;
else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
return can_complete_type_without_circularity (TREE_TYPE (type));
- else if (CLASS_TYPE_P (type) && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type)))
+ else if (CLASS_TYPE_P (type)
+ && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type)))
return 0;
else
return 1;
}
tree
-instantiate_class_template (type)
- tree type;
+instantiate_class_template (tree type)
{
tree template, args, pattern, t, member;
tree typedecl;
-
+ tree pbinfo;
+
if (type == error_mark_node)
return error_mark_node;
- if (TYPE_BEING_DEFINED (type) || COMPLETE_TYPE_P (type))
+ if (TYPE_BEING_DEFINED (type)
+ || COMPLETE_TYPE_P (type)
+ || dependent_type_p (type))
return type;
/* Figure out which template is being instantiated. */
@@ -5201,63 +5286,25 @@ instantiate_class_template (type)
/* Figure out which arguments are being used to do the
instantiation. */
args = CLASSTYPE_TI_ARGS (type);
- PARTIAL_INSTANTIATION_P (type) = uses_template_parms (args);
-
- if (pedantic && PARTIAL_INSTANTIATION_P (type))
- /* If this is a partial instantiation, then we can't instantiate
- the type; there's no telling whether or not one of the
- template parameters might eventually be instantiated to some
- value that results in a specialization being used. For
- example, consider:
-
- template <class T>
- struct S {};
-
- template <class U>
- void f(S<U>);
-
- template <>
- struct S<int> {};
-
- Now, the `S<U>' in `f<int>' is the specialization, not an
- instantiation of the original template. */
- return type;
/* Determine what specialization of the original template to
instantiate. */
- if (PARTIAL_INSTANTIATION_P (type))
- /* There's no telling which specialization is appropriate at this
- point. Since all peeking at the innards of this partial
- instantiation are extensions (like the "implicit typename"
- extension, which allows users to omit the keyword `typename' on
- names that are declared as types in template base classes), we
- are free to do what we please.
-
- Trying to figure out which partial instantiation to use can
- cause a crash. (Some of the template arguments don't even have
- types.) So, we just use the most general version. */
- t = NULL_TREE;
- else
+ t = most_specialized_class (template, args);
+ if (t == error_mark_node)
{
- t = most_specialized_class (template, args);
-
- if (t == error_mark_node)
+ const char *str = "candidates are:";
+ error ("ambiguous class template instantiation for `%#T'", type);
+ for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t;
+ t = TREE_CHAIN (t))
{
- const char *str = "candidates are:";
- error ("ambiguous class template instantiation for `%#T'", type);
- for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t;
- t = TREE_CHAIN (t))
+ if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args))
{
- if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t),
- args))
- {
- cp_error_at ("%s %+#T", str, TREE_TYPE (t));
- str = " ";
- }
+ cp_error_at ("%s %+#T", str, TREE_TYPE (t));
+ str = " ";
}
- TYPE_BEING_DEFINED (type) = 1;
- return error_mark_node;
}
+ TYPE_BEING_DEFINED (type) = 1;
+ return error_mark_node;
}
if (t)
@@ -5270,26 +5317,6 @@ instantiate_class_template (type)
if (!COMPLETE_TYPE_P (pattern))
return type;
- /* If this is a partial instantiation, don't tsubst anything. We will
- only use this type for implicit typename, so the actual contents don't
- matter. All that matters is whether a particular name is a type. */
- if (PARTIAL_INSTANTIATION_P (type))
- {
- /* The fields set here must be kept in sync with those cleared
- in begin_class_definition. */
- TYPE_BINFO_BASETYPES (type) = TYPE_BINFO_BASETYPES (pattern);
- TYPE_FIELDS (type) = TYPE_FIELDS (pattern);
- TYPE_METHODS (type) = TYPE_METHODS (pattern);
- CLASSTYPE_DECL_LIST (type) = CLASSTYPE_DECL_LIST (pattern);
- CLASSTYPE_NESTED_UDTS (type) = CLASSTYPE_NESTED_UDTS (pattern);
- CLASSTYPE_VBASECLASSES (type) = CLASSTYPE_VBASECLASSES (pattern);
-
- /* Pretend that the type is complete, so that we will look
- inside it during name lookup and such. */
- TYPE_SIZE (type) = bitsize_zero_node;
- return type;
- }
-
/* If we've recursively instantiated too many templates, stop. */
if (! push_tinst_level (type))
return type;
@@ -5298,7 +5325,11 @@ instantiate_class_template (type)
the process of being defined. */
TYPE_BEING_DEFINED (type) = 1;
- maybe_push_to_top_level (uses_template_parms (type));
+ /* We may be in the middle of deferred access check. Disable
+ it now. */
+ push_deferring_access_checks (dk_no_deferred);
+
+ push_to_top_level ();
if (t)
{
@@ -5328,30 +5359,14 @@ instantiate_class_template (type)
args = inner_args;
}
- if (flag_external_templates)
- {
- if (flag_alt_external_templates)
- {
- CLASSTYPE_INTERFACE_ONLY (type) = interface_only;
- SET_CLASSTYPE_INTERFACE_UNKNOWN_X (type, interface_unknown);
- }
- else
- {
- CLASSTYPE_INTERFACE_ONLY (type) = CLASSTYPE_INTERFACE_ONLY (pattern);
- SET_CLASSTYPE_INTERFACE_UNKNOWN_X
- (type, CLASSTYPE_INTERFACE_UNKNOWN (pattern));
- }
- }
- else
- {
- SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
- }
+ SET_CLASSTYPE_INTERFACE_UNKNOWN (type);
+
+ /* Set the input location to the template definition. This is needed
+ if tsubsting causes an error. */
+ input_location = DECL_SOURCE_LOCATION (TYPE_NAME (pattern));
TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern);
TYPE_HAS_DESTRUCTOR (type) = TYPE_HAS_DESTRUCTOR (pattern);
- TYPE_OVERLOADS_CALL_EXPR (type) = TYPE_OVERLOADS_CALL_EXPR (pattern);
- TYPE_OVERLOADS_ARRAY_REF (type) = TYPE_OVERLOADS_ARRAY_REF (pattern);
- TYPE_OVERLOADS_ARROW (type) = TYPE_OVERLOADS_ARROW (pattern);
TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
TYPE_HAS_ARRAY_NEW_OPERATOR (type) = TYPE_HAS_ARRAY_NEW_OPERATOR (pattern);
TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern);
@@ -5375,16 +5390,33 @@ instantiate_class_template (type)
if (ANON_AGGR_TYPE_P (pattern))
SET_ANON_AGGR_TYPE_P (type);
- if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (pattern)))
- /* First instantiate our enclosing class. */
- complete_type (TYPE_CONTEXT (type));
+ pbinfo = TYPE_BINFO (pattern);
+
+#ifdef ENABLE_CHECKING
+ if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (pattern))
+ && ! COMPLETE_TYPE_P (TYPE_CONTEXT (type))
+ && ! TYPE_BEING_DEFINED (TYPE_CONTEXT (type)))
+ /* We should never instantiate a nested class before its enclosing
+ class; we need to look up the nested class by name before we can
+ instantiate it, and that lookup should instantiate the enclosing
+ class. */
+ abort ();
+#endif
- if (TYPE_BINFO_BASETYPES (pattern))
+ if (BINFO_BASETYPES (pbinfo))
{
tree base_list = NULL_TREE;
- tree pbases = TYPE_BINFO_BASETYPES (pattern);
+ tree pbases = BINFO_BASETYPES (pbinfo);
+ tree paccesses = BINFO_BASEACCESSES (pbinfo);
+ tree context = TYPE_CONTEXT (type);
+ bool pop_p;
int i;
+ /* We must enter the scope containing the type, as that is where
+ the accessibility of types named in dependent bases are
+ looked up from. */
+ pop_p = push_scope (context ? context : global_namespace);
+
/* Substitute into each of the bases to determine the actual
basetypes. */
for (i = 0; i < TREE_VEC_LENGTH (pbases); ++i)
@@ -5394,33 +5426,15 @@ instantiate_class_template (type)
tree pbase;
pbase = TREE_VEC_ELT (pbases, i);
+ access = TREE_VEC_ELT (paccesses, i);
/* Substitute to figure out the base class. */
base = tsubst (BINFO_TYPE (pbase), args, tf_error, NULL_TREE);
if (base == error_mark_node)
continue;
-
- /* Calculate the correct access node. */
- if (TREE_VIA_VIRTUAL (pbase))
- {
- if (TREE_VIA_PUBLIC (pbase))
- access = access_public_virtual_node;
- else if (TREE_VIA_PROTECTED (pbase))
- access = access_protected_virtual_node;
- else
- access = access_private_virtual_node;
- }
- else
- {
- if (TREE_VIA_PUBLIC (pbase))
- access = access_public_node;
- else if (TREE_VIA_PROTECTED (pbase))
- access = access_protected_node;
- else
- access = access_private_node;
- }
-
+
base_list = tree_cons (access, base, base_list);
+ TREE_VIA_VIRTUAL (base_list) = TREE_VIA_VIRTUAL (pbase);
}
/* The list is now in reverse order; correct that. */
@@ -5429,6 +5443,9 @@ instantiate_class_template (type)
/* Now call xref_basetypes to set up all the base-class
information. */
xref_basetypes (type, base_list);
+
+ if (pop_p)
+ pop_scope (context ? context : global_namespace);
}
/* Now that our base classes are set up, enter the scope of the
@@ -5436,10 +5453,11 @@ instantiate_class_template (type)
correctly. This is precisely analogous to what we do in
begin_class_definition when defining an ordinary non-template
class. */
- pushclass (type, 1);
+ pushclass (type);
/* Now members are processed in the order of declaration. */
- for (member = CLASSTYPE_DECL_LIST (pattern); member; member = TREE_CHAIN (member))
+ for (member = CLASSTYPE_DECL_LIST (pattern);
+ member; member = TREE_CHAIN (member))
{
tree t = TREE_VALUE (member);
@@ -5447,25 +5465,29 @@ instantiate_class_template (type)
{
if (TYPE_P (t))
{
- /* Build new CLASSTYPE_NESTED_UDTS. */
+ /* Build new CLASSTYPE_NESTED_UTDS. */
tree tag = t;
tree name = TYPE_IDENTIFIER (tag);
tree newtag;
newtag = tsubst (tag, args, tf_error, NULL_TREE);
- my_friendly_assert (newtag != error_mark_node, 20010206);
+ if (newtag == error_mark_node)
+ continue;
+
if (TREE_CODE (newtag) != ENUMERAL_TYPE)
{
if (TYPE_LANG_SPECIFIC (tag) && CLASSTYPE_IS_TEMPLATE (tag))
/* Unfortunately, lookup_template_class sets
CLASSTYPE_IMPLICIT_INSTANTIATION for a partial
- instantiation (i.e., for the type of a member template
- class nested within a template class.) This behavior is
- required for maybe_process_partial_specialization to work
- correctly, but is not accurate in this case; the TAG is not
- an instantiation of anything. (The corresponding
- TEMPLATE_DECL is an instantiation, but the TYPE is not.) */
+ instantiation (i.e., for the type of a member
+ template class nested within a template class.)
+ This behavior is required for
+ maybe_process_partial_specialization to work
+ correctly, but is not accurate in this case;
+ the TAG is not an instantiation of anything.
+ (The corresponding TEMPLATE_DECL is an
+ instantiation, but the TYPE is not.) */
CLASSTYPE_USE_TEMPLATE (newtag) = 0;
/* Now, we call pushtag to put this NEWTAG into the scope of
@@ -5482,8 +5504,13 @@ instantiate_class_template (type)
|| DECL_FUNCTION_TEMPLATE_P (t))
{
/* Build new TYPE_METHODS. */
-
- tree r = tsubst (t, args, tf_error, NULL_TREE);
+ tree r;
+
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ ++processing_template_decl;
+ r = tsubst (t, args, tf_error, NULL_TREE);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ --processing_template_decl;
set_current_access_from_decl (r);
grok_special_member_properties (r);
finish_member_declaration (r);
@@ -5496,13 +5523,17 @@ instantiate_class_template (type)
{
tree r;
- /* The the file and line for this declaration, to assist
- in error message reporting. Since we called
- push_tinst_level above, we don't need to restore these. */
- lineno = DECL_SOURCE_LINE (t);
- input_filename = DECL_SOURCE_FILE (t);
+ /* The the file and line for this declaration, to
+ assist in error message reporting. Since we
+ called push_tinst_level above, we don't need to
+ restore these. */
+ input_location = DECL_SOURCE_LOCATION (t);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ ++processing_template_decl;
r = tsubst (t, args, tf_error | tf_warning, NULL_TREE);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ --processing_template_decl;
if (TREE_CODE (r) == VAR_DECL)
{
tree init;
@@ -5513,9 +5544,8 @@ instantiate_class_template (type)
else
init = NULL_TREE;
- finish_static_data_member_decl (r, init,
- /*asmspec_tree=*/NULL_TREE,
- /*flags=*/0);
+ finish_static_data_member_decl
+ (r, init, /*asmspec_tree=*/NULL_TREE, /*flags=*/0);
if (DECL_INITIALIZED_IN_CLASS_P (r))
check_static_variable_definition (r, TREE_TYPE (r));
@@ -5540,7 +5570,7 @@ instantiate_class_template (type)
/* If it is a TYPE_DECL for a class-scoped ENUMERAL_TYPE,
such a thing will already have been added to the field
list by tsubst_enum in finish_member_declaration in the
- CLASSTYPE_NESTED_UDTS case above. */
+ CLASSTYPE_NESTED_UTDS case above. */
if (!(TREE_CODE (r) == TYPE_DECL
&& TREE_CODE (TREE_TYPE (r)) == ENUMERAL_TYPE
&& DECL_ARTIFICIAL (r)))
@@ -5565,6 +5595,8 @@ instantiate_class_template (type)
else if (uses_template_parms (friend_type))
new_friend_type = tsubst (friend_type, args,
tf_error | tf_warning, NULL_TREE);
+ else if (CLASSTYPE_USE_TEMPLATE (friend_type))
+ new_friend_type = friend_type;
else
{
tree ns = decl_namespace_context (TYPE_MAIN_DECL (friend_type));
@@ -5586,14 +5618,24 @@ instantiate_class_template (type)
++processing_template_decl;
if (new_friend_type != error_mark_node)
- make_friend_class (type, new_friend_type);
+ make_friend_class (type, new_friend_type,
+ /*complain=*/false);
if (TREE_CODE (friend_type) == TEMPLATE_DECL)
--processing_template_decl;
}
else
- /* Build new DECL_FRIENDLIST. */
- add_friend (type, tsubst_friend_function (t, args));
+ {
+ /* Build new DECL_FRIENDLIST. */
+ tree r;
+
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ ++processing_template_decl;
+ r = tsubst_friend_function (t, args);
+ if (TREE_CODE (t) == TEMPLATE_DECL)
+ --processing_template_decl;
+ add_friend (type, r, /*complain=*/false);
+ }
}
}
@@ -5602,12 +5644,10 @@ instantiate_class_template (type)
implicit functions at a predictable point, and the same point
that would be used for non-template classes. */
typedecl = TYPE_MAIN_DECL (type);
- lineno = DECL_SOURCE_LINE (typedecl);
- input_filename = DECL_SOURCE_FILE (typedecl);
-
+ input_location = DECL_SOURCE_LOCATION (typedecl);
+
unreverse_member_declarations (type);
finish_struct_1 (type);
- CLASSTYPE_GOT_SEMICOLON (type) = 1;
/* Clear this now so repo_template_used is happy. */
TYPE_BEING_DEFINED (type) = 0;
@@ -5627,6 +5667,7 @@ instantiate_class_template (type)
popclass ();
pop_from_top_level ();
+ pop_deferring_access_checks ();
pop_tinst_level ();
if (TYPE_CONTAINS_VPTR_P (type))
@@ -5635,89 +5676,78 @@ instantiate_class_template (type)
return type;
}
-static int
-list_eq (t1, t2)
- tree t1, t2;
+static tree
+tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
- if (t1 == NULL_TREE)
- return t2 == NULL_TREE;
- if (t2 == NULL_TREE)
- return 0;
- /* Don't care if one declares its arg const and the other doesn't -- the
- main variant of the arg type is all that matters. */
- if (TYPE_MAIN_VARIANT (TREE_VALUE (t1))
- != TYPE_MAIN_VARIANT (TREE_VALUE (t2)))
- return 0;
- return list_eq (TREE_CHAIN (t1), TREE_CHAIN (t2));
-}
-
-/* If arg is a non-type template parameter that does not depend on template
- arguments, fold it like we weren't in the body of a template. */
+ tree r;
+
+ if (!t)
+ r = t;
+ else if (TYPE_P (t))
+ r = tsubst (t, args, complain, in_decl);
+ else
+ {
+ r = tsubst_expr (t, args, complain, in_decl);
-static tree
-maybe_fold_nontype_arg (arg)
- tree arg;
-{
- if (arg && !TYPE_P (arg) && !uses_template_parms (arg))
- {
- /* Sometimes, one of the args was an expression involving a
- template constant parameter, like N - 1. Now that we've
- tsubst'd, we might have something like 2 - 1. This will
- confuse lookup_template_class, so we do constant folding
- here. We have to unset processing_template_decl, to
- fool build_expr_from_tree() into building an actual
- tree. */
-
- /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
- as simple as it's going to get, and trying to reprocess
- the trees will break. */
- if (!TREE_TYPE (arg))
+ if (!uses_template_parms (r))
{
- int saved_processing_template_decl = processing_template_decl;
- processing_template_decl = 0;
- arg = build_expr_from_tree (arg);
- processing_template_decl = saved_processing_template_decl;
+ /* Sometimes, one of the args was an expression involving a
+ template constant parameter, like N - 1. Now that we've
+ tsubst'd, we might have something like 2 - 1. This will
+ confuse lookup_template_class, so we do constant folding
+ here. We have to unset processing_template_decl, to fool
+ tsubst_copy_and_build() into building an actual tree. */
+
+ /* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
+ as simple as it's going to get, and trying to reprocess
+ the trees will break. Once tsubst_expr et al DTRT for
+ non-dependent exprs, this code can go away, as the type
+ will always be set. */
+ if (!TREE_TYPE (r))
+ {
+ int saved_processing_template_decl = processing_template_decl;
+ processing_template_decl = 0;
+ r = tsubst_copy_and_build (r, /*args=*/NULL_TREE,
+ tf_error, /*in_decl=*/NULL_TREE,
+ /*function_p=*/false);
+ processing_template_decl = saved_processing_template_decl;
+ }
+ r = fold (r);
}
-
- arg = fold (arg);
}
- return arg;
+ return r;
}
-/* Substitute ARGS into the vector of template arguments T. */
+/* Substitute ARGS into the vector or list of template arguments T. */
static tree
-tsubst_template_arg_vector (t, args, complain)
- tree t;
- tree args;
- tsubst_flags_t complain;
+tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
- int len = TREE_VEC_LENGTH (t), need_new = 0, i;
- tree *elts = (tree *) alloca (len * sizeof (tree));
-
- memset ((char *) elts, 0, len * sizeof (tree));
+ int len = TREE_VEC_LENGTH (t);
+ int need_new = 0, i;
+ tree *elts = alloca (len * sizeof (tree));
for (i = 0; i < len; i++)
{
- if (TREE_VEC_ELT (t, i) != NULL_TREE
- && TREE_CODE (TREE_VEC_ELT (t, i)) == TREE_VEC)
- elts[i] = tsubst_template_arg_vector (TREE_VEC_ELT (t, i),
- args, complain);
+ tree orig_arg = TREE_VEC_ELT (t, i);
+ tree new_arg;
+
+ if (TREE_CODE (orig_arg) == TREE_VEC)
+ new_arg = tsubst_template_args (orig_arg, args, complain, in_decl);
else
- elts[i] = maybe_fold_nontype_arg
- (tsubst_expr (TREE_VEC_ELT (t, i), args, complain,
- NULL_TREE));
+ new_arg = tsubst_template_arg (orig_arg, args, complain, in_decl);
- if (elts[i] == error_mark_node)
+ if (new_arg == error_mark_node)
return error_mark_node;
- if (elts[i] != TREE_VEC_ELT (t, i))
+ elts[i] = new_arg;
+ if (new_arg != orig_arg)
need_new = 1;
}
if (!need_new)
return t;
-
+
t = make_tree_vec (len);
for (i = 0; i < len; i++)
TREE_VEC_ELT (t, i) = elts[i];
@@ -5733,10 +5763,7 @@ tsubst_template_arg_vector (t, args, complain)
result will be `template <int*, double, class V>'. */
static tree
-tsubst_template_parms (parms, args, complain)
- tree parms;
- tree args;
- tsubst_flags_t complain;
+tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
{
tree r = NULL_TREE;
tree* new_parms;
@@ -5757,10 +5784,10 @@ tsubst_template_parms (parms, args, complain)
tree parm_decl = TREE_VALUE (tuple);
parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
- default_value = tsubst_expr (default_value, args,
- complain, NULL_TREE);
- tuple = build_tree_list (maybe_fold_nontype_arg (default_value),
- parm_decl);
+ default_value = tsubst_template_arg (default_value, args,
+ complain, NULL_TREE);
+
+ tuple = build_tree_list (default_value, parm_decl);
TREE_VEC_ELT (new_vec, i) = tuple;
}
@@ -5780,12 +5807,11 @@ tsubst_template_parms (parms, args, complain)
we are presently tsubst'ing. Return the substituted value. */
static tree
-tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
- tree t;
- tree args;
- tsubst_flags_t complain;
- tree in_decl;
- int entering_scope;
+tsubst_aggr_type (tree t,
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl,
+ int entering_scope)
{
if (t == NULL_TREE)
return NULL_TREE;
@@ -5796,7 +5822,7 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
if (TYPE_PTRMEMFUNC_P (t))
return tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, complain, in_decl);
- /* else fall through */
+ /* Else fall through. */
case ENUMERAL_TYPE:
case UNION_TYPE:
if (TYPE_TEMPLATE_INFO (t))
@@ -5807,12 +5833,10 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
/* First, determine the context for the type we are looking
up. */
- if (TYPE_CONTEXT (t) != NULL_TREE)
- context = tsubst_aggr_type (TYPE_CONTEXT (t), args,
- complain,
+ context = TYPE_CONTEXT (t);
+ if (context)
+ context = tsubst_aggr_type (context, args, complain,
in_decl, /*entering_scope=*/1);
- else
- context = NULL_TREE;
/* Then, figure out what arguments are appropriate for the
type we are trying to find. For example, given:
@@ -5823,8 +5847,8 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
and supposing that we are instantiating f<int, double>,
then our ARGS will be {int, double}, but, when looking up
S we only want {double}. */
- argvec = tsubst_template_arg_vector (TYPE_TI_ARGS (t), args,
- complain);
+ argvec = tsubst_template_args (TYPE_TI_ARGS (t), args,
+ complain, in_decl);
if (argvec == error_mark_node)
return error_mark_node;
@@ -5846,10 +5870,7 @@ tsubst_aggr_type (t, args, complain, in_decl, entering_scope)
FN), which has the indicated TYPE. */
tree
-tsubst_default_argument (fn, type, arg)
- tree fn;
- tree type;
- tree arg;
+tsubst_default_argument (tree fn, tree type, tree arg)
{
/* This default argument came from a template. Instantiate the
default argument here, not in tsubst. In the case of
@@ -5862,18 +5883,18 @@ tsubst_default_argument (fn, type, arg)
};
we must be careful to do name lookup in the scope of S<T>,
- rather than in the current class.
-
- ??? current_class_type affects a lot more than name lookup. This is
- very fragile. Fortunately, it will go away when we do 2-phase name
- binding properly. */
-
- /* FN is already the desired FUNCTION_DECL. */
+ rather than in the current class. */
push_access_scope (fn);
+ /* The default argument expression should not be considered to be
+ within the scope of FN. Since push_access_scope sets
+ current_function_decl, we must explicitly clear it here. */
+ current_function_decl = NULL_TREE;
+ push_deferring_access_checks(dk_no_deferred);
arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
tf_error | tf_warning, NULL_TREE);
-
+ pop_deferring_access_checks();
+
pop_access_scope (fn);
/* Make sure the default argument is reasonable. */
@@ -5885,8 +5906,7 @@ tsubst_default_argument (fn, type, arg)
/* Substitute into all the default arguments for FN. */
static void
-tsubst_default_arguments (fn)
- tree fn;
+tsubst_default_arguments (tree fn)
{
tree arg;
tree tmpl_args;
@@ -5913,22 +5933,15 @@ tsubst_default_arguments (fn)
and warning messages under control of COMPLAIN. */
static tree
-tsubst_decl (t, args, type, complain)
- tree t;
- tree args;
- tree type;
- tsubst_flags_t complain;
-{
- int saved_lineno;
- const char *saved_filename;
+tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
+{
+ location_t saved_loc;
tree r = NULL_TREE;
tree in_decl = t;
/* Set the filename and linenumber to improve error-reporting. */
- saved_lineno = lineno;
- saved_filename = input_filename;
- lineno = DECL_SOURCE_LINE (t);
- input_filename = DECL_SOURCE_FILE (t);
+ saved_loc = input_location;
+ input_location = DECL_SOURCE_LOCATION (t);
switch (TREE_CODE (t))
{
@@ -5951,10 +5964,10 @@ tsubst_decl (t, args, type, complain)
: DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t));
tree full_args;
- full_args = tsubst_template_arg_vector (tmpl_args, args,
- complain);
+ full_args = tsubst_template_args (tmpl_args, args,
+ complain, in_decl);
- /* tsubst_template_arg_vector doesn't copy the vector if
+ /* tsubst_template_args doesn't copy the vector if
nothing changed. But, *something* should have
changed. */
my_friendly_assert (full_args != tmpl_args, 0);
@@ -5993,6 +6006,9 @@ tsubst_decl (t, args, type, complain)
if (TREE_CODE (decl) == TYPE_DECL)
{
tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ if (new_type == error_mark_node)
+ return error_mark_node;
+
TREE_TYPE (r) = new_type;
CLASSTYPE_TI_TEMPLATE (new_type) = r;
DECL_TEMPLATE_RESULT (r) = TYPE_MAIN_DECL (new_type);
@@ -6001,6 +6017,8 @@ tsubst_decl (t, args, type, complain)
else
{
tree new_decl = tsubst (decl, args, complain, in_decl);
+ if (new_decl == error_mark_node)
+ return error_mark_node;
DECL_TEMPLATE_RESULT (r) = new_decl;
DECL_TI_TEMPLATE (new_decl) = r;
@@ -6022,14 +6040,10 @@ tsubst_decl (t, args, type, complain)
if (PRIMARY_TEMPLATE_P (t))
DECL_PRIMARY_TEMPLATE (r) = r;
- /* We don't partially instantiate partial specializations. */
- if (TREE_CODE (decl) == TYPE_DECL)
- break;
-
- /* Record this partial instantiation. */
- register_specialization (r, t,
- DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)));
-
+ if (TREE_CODE (decl) != TYPE_DECL)
+ /* Record this non-type partial instantiation. */
+ register_specialization (r, t,
+ DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)));
}
break;
@@ -6049,19 +6063,25 @@ tsubst_decl (t, args, type, complain)
if (TREE_CODE (DECL_TI_TEMPLATE (t)) == TEMPLATE_DECL)
{
tree spec;
-
- /* If T is not dependent, just return it. */
- if (!uses_template_parms (DECL_TI_ARGS (t)))
+ bool dependent_p;
+
+ /* If T is not dependent, just return it. We have to
+ increment PROCESSING_TEMPLATE_DECL because
+ value_dependent_expression_p assumes that nothing is
+ dependent when PROCESSING_TEMPLATE_DECL is zero. */
+ ++processing_template_decl;
+ dependent_p = value_dependent_expression_p (t);
+ --processing_template_decl;
+ if (!dependent_p)
return t;
/* Calculate the most general template of which R is a
specialization, and the complete set of arguments used to
specialize R. */
gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t));
- argvec
- = tsubst_template_arg_vector (DECL_TI_ARGS
- (DECL_TEMPLATE_RESULT (gen_tmpl)),
- args, complain);
+ argvec = tsubst_template_args (DECL_TI_ARGS
+ (DECL_TEMPLATE_RESULT (gen_tmpl)),
+ args, complain, in_decl);
/* Check to see if we already have this specialization. */
spec = retrieve_specialization (gen_tmpl, argvec);
@@ -6120,14 +6140,10 @@ tsubst_decl (t, args, type, complain)
};
Here, the DECL_TI_TEMPLATE for the friend declaration
- will be a LOOKUP_EXPR or an IDENTIFIER_NODE. We are
- being called from tsubst_friend_function, and we want
- only to create a new decl (R) with appropriate types so
- that we can call determine_specialization. */
- my_friendly_assert ((TREE_CODE (DECL_TI_TEMPLATE (t))
- == LOOKUP_EXPR)
- || (TREE_CODE (DECL_TI_TEMPLATE (t))
- == IDENTIFIER_NODE), 0);
+ will be an IDENTIFIER_NODE. We are being called from
+ tsubst_friend_function, and we want only to create a
+ new decl (R) with appropriate types so that we can call
+ determine_specialization. */
gen_tmpl = NULL_TREE;
}
@@ -6138,8 +6154,7 @@ tsubst_decl (t, args, type, complain)
else
member = 1;
ctx = tsubst_aggr_type (DECL_CONTEXT (t), args,
- complain, t,
- /*entering_scope=*/1);
+ complain, t, /*entering_scope=*/1);
}
else
{
@@ -6160,7 +6175,7 @@ tsubst_decl (t, args, type, complain)
/* Clear out the mangled name and RTL for the instantiation. */
SET_DECL_ASSEMBLER_NAME (r, NULL_TREE);
SET_DECL_RTL (r, NULL_RTX);
-
+ DECL_INITIAL (r) = NULL_TREE;
DECL_CONTEXT (r) = ctx;
if (member && DECL_CONV_FN_P (r))
@@ -6240,7 +6255,13 @@ tsubst_decl (t, args, type, complain)
clone_function_decl (r, /*update_method_vec_p=*/0);
}
else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
- grok_op_properties (r, DECL_FRIEND_P (r));
+ grok_op_properties (r, DECL_FRIEND_P (r),
+ (complain & tf_error) != 0);
+
+ if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t))
+ SET_DECL_FRIEND_CONTEXT (r,
+ tsubst (DECL_FRIEND_CONTEXT (t),
+ args, complain, in_decl));
}
break;
@@ -6253,11 +6274,14 @@ tsubst_decl (t, args, type, complain)
TREE_TYPE (r) = type;
c_apply_type_quals_to_decl (cp_type_quals (type), r);
- if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
- DECL_INITIAL (r) = TREE_TYPE (r);
- else
- DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
- complain, in_decl);
+ if (DECL_INITIAL (r))
+ {
+ if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX)
+ DECL_INITIAL (r) = TREE_TYPE (r);
+ else
+ DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args,
+ complain, in_decl);
+ }
DECL_CONTEXT (r) = NULL_TREE;
@@ -6288,8 +6312,12 @@ tsubst_decl (t, args, type, complain)
case USING_DECL:
{
r = copy_node (t);
+ /* It is not a dependent using decl any more. */
+ TREE_TYPE (r) = void_type_node;
DECL_INITIAL (r)
= tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
+ DECL_NAME (r)
+ = tsubst_copy (DECL_NAME (t), args, complain, in_decl);
TREE_CHAIN (r) = NULL_TREE;
}
break;
@@ -6352,7 +6380,11 @@ tsubst_decl (t, args, type, complain)
r = copy_decl (t);
if (TREE_CODE (r) == VAR_DECL)
- type = complete_type (type);
+ {
+ type = complete_type (type);
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
+ = DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t);
+ }
else if (DECL_SELF_REFERENCE_P (t))
SET_DECL_SELF_REFERENCE_P (r);
TREE_TYPE (r) = type;
@@ -6404,20 +6436,18 @@ tsubst_decl (t, args, type, complain)
}
/* Restore the file and line information. */
- lineno = saved_lineno;
- input_filename = saved_filename;
+ input_location = saved_loc;
return r;
}
-/* Substitue into the ARG_TYPES of a function type. */
+/* Substitute into the ARG_TYPES of a function type. */
static tree
-tsubst_arg_types (arg_types, args, complain, in_decl)
- tree arg_types;
- tree args;
- tsubst_flags_t complain;
- tree in_decl;
+tsubst_arg_types (tree arg_types,
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl)
{
tree remaining_arg_types;
tree type;
@@ -6474,11 +6504,10 @@ tsubst_arg_types (arg_types, args, complain, in_decl)
results in an invalid type.] */
static tree
-tsubst_function_type (t, args, complain, in_decl)
- tree t;
- tree args;
- tsubst_flags_t complain;
- tree in_decl;
+tsubst_function_type (tree t,
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl)
{
tree return_type;
tree arg_types;
@@ -6492,7 +6521,7 @@ tsubst_function_type (t, args, complain, in_decl)
if (return_type == error_mark_node)
return error_mark_node;
- /* Substitue the argument types. */
+ /* Substitute the argument types. */
arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args,
complain, in_decl);
if (arg_types == error_mark_node)
@@ -6519,11 +6548,11 @@ tsubst_function_type (t, args, complain, in_decl)
return error_mark_node;
}
- fntype = build_cplus_method_type (r, return_type, TREE_CHAIN
- (arg_types));
+ fntype = build_method_type_directly (r, return_type,
+ TREE_CHAIN (arg_types));
}
fntype = cp_build_qualified_type_real (fntype, TYPE_QUALS (t), complain);
- fntype = build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
+ fntype = cp_build_type_attribute_variant (fntype, TYPE_ATTRIBUTES (t));
return fntype;
}
@@ -6531,11 +6560,10 @@ tsubst_function_type (t, args, complain, in_decl)
/* Substitute into the PARMS of a call-declarator. */
static tree
-tsubst_call_declarator_parms (parms, args, complain, in_decl)
- tree parms;
- tree args;
- tsubst_flags_t complain;
- tree in_decl;
+tsubst_call_declarator_parms (tree parms,
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl)
{
tree new_parms;
tree type;
@@ -6581,11 +6609,8 @@ tsubst_call_declarator_parms (parms, args, complain, in_decl)
This function is used for dealing with types, decls and the like;
for expressions, use tsubst_expr or tsubst_copy. */
-tree
-tsubst (t, args, complain, in_decl)
- tree t, args;
- tsubst_flags_t complain;
- tree in_decl;
+static tree
+tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
tree type, r;
@@ -6600,8 +6625,8 @@ tsubst (t, args, complain, in_decl)
type = IDENTIFIER_TYPE_VALUE (t);
else
type = TREE_TYPE (t);
- if (type == unknown_type_node)
- abort ();
+
+ my_friendly_assert (type != unknown_type_node, 20030716);
if (type && TREE_CODE (t) != FUNCTION_DECL
&& TREE_CODE (t) != TYPENAME_TYPE
@@ -6647,32 +6672,12 @@ tsubst (t, args, complain, in_decl)
{
tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
- max = tsubst_expr (omax, args, complain, in_decl);
- if (max == error_mark_node)
- return error_mark_node;
-
- /* See if we can reduce this expression to something simpler. */
- max = maybe_fold_nontype_arg (max);
+ /* The array dimension behaves like a non-type template arg,
+ in that we want to fold it as much as possible. */
+ max = tsubst_template_arg (omax, args, complain, in_decl);
if (!processing_template_decl)
max = decl_constant_value (max);
- if (processing_template_decl
- /* When providing explicit arguments to a template
- function, but leaving some arguments for subsequent
- deduction, MAX may be template-dependent even if we're
- not PROCESSING_TEMPLATE_DECL. We still need to check for
- template parms, though; MAX won't be an INTEGER_CST for
- dynamic arrays, either. */
- || (TREE_CODE (max) != INTEGER_CST
- && uses_template_parms (max)))
- {
- tree itype = make_node (INTEGER_TYPE);
- TYPE_MIN_VALUE (itype) = size_zero_node;
- TYPE_MAX_VALUE (itype) = build_min (MINUS_EXPR, sizetype, max,
- integer_one_node);
- return itype;
- }
-
if (integer_zerop (omax))
{
/* Still allow an explicit array of size zero. */
@@ -6745,7 +6750,7 @@ tsubst (t, args, complain, in_decl)
else if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
{
/* We are processing a type constructed from
- a template template parameter */
+ a template template parameter. */
tree argvec = tsubst (TYPE_TI_ARGS (t),
args, complain, in_decl);
if (argvec == error_mark_node)
@@ -6896,7 +6901,7 @@ tsubst (t, args, complain, in_decl)
}
/* Otherwise, a vector of template arguments. */
- return tsubst_template_arg_vector (t, args, complain);
+ return tsubst_template_args (t, args, complain, in_decl);
case POINTER_TYPE:
case REFERENCE_TYPE:
@@ -6920,14 +6925,14 @@ tsubst (t, args, complain, in_decl)
if (TREE_CODE (type) == REFERENCE_TYPE
|| (code == REFERENCE_TYPE && TREE_CODE (type) == VOID_TYPE))
{
- static int last_line = 0;
- static const char* last_file = 0;
+ static location_t last_loc;
/* We keep track of the last time we issued this error
message to avoid spewing a ton of messages during a
single bad template instantiation. */
if (complain & tf_error
- && (last_line != lineno || last_file != input_filename))
+ && (last_loc.line != input_line
+ || last_loc.file != input_filename))
{
if (TREE_CODE (type) == VOID_TYPE)
error ("forming reference to void");
@@ -6935,8 +6940,7 @@ tsubst (t, args, complain, in_decl)
error ("forming %s to reference type `%T'",
(code == POINTER_TYPE) ? "pointer" : "reference",
type);
- last_line = lineno;
- last_file = input_filename;
+ last_loc = input_location;
}
return error_mark_node;
@@ -6982,21 +6986,28 @@ tsubst (t, args, complain, in_decl)
}
my_friendly_assert (TREE_CODE (type) != METHOD_TYPE, 20011231);
if (TREE_CODE (type) == FUNCTION_TYPE)
- /* This is really a method type. The cv qualifiers of the
- this pointer should _not_ be determined by the cv
- qualifiers of the class type. They should be held
- somewhere in the FUNCTION_TYPE, but we don't do that at
- the moment. Consider
- typedef void (Func) () const;
-
- template <typename T1> void Foo (Func T1::*);
-
- */
- return build_cplus_method_type (TYPE_MAIN_VARIANT (r),
- TREE_TYPE (type),
- TYPE_ARG_TYPES (type));
+ {
+ /* This is really a method type. The cv qualifiers of the
+ this pointer should _not_ be determined by the cv
+ qualifiers of the class type. They should be held
+ somewhere in the FUNCTION_TYPE, but we don't do that at
+ the moment. Consider
+ typedef void (Func) () const;
+
+ template <typename T1> void Foo (Func T1::*);
+
+ */
+ tree method_type;
+
+ method_type = build_method_type_directly (TYPE_MAIN_VARIANT (r),
+ TREE_TYPE (type),
+ TYPE_ARG_TYPES (type));
+ return build_ptrmemfunc_type (build_pointer_type (method_type));
+ }
else
- return build_offset_type (r, type);
+ return cp_build_qualified_type_real (build_ptrmem_type (r, type),
+ TYPE_QUALS (t),
+ complain);
}
case FUNCTION_TYPE:
case METHOD_TYPE:
@@ -7008,7 +7019,7 @@ tsubst (t, args, complain, in_decl)
if (fntype == error_mark_node)
return error_mark_node;
- /* Substitue the exception specification. */
+ /* Substitute the exception specification. */
raises = TYPE_RAISES_EXCEPTIONS (t);
if (raises)
{
@@ -7048,7 +7059,8 @@ tsubst (t, args, complain, in_decl)
The deduction may fail for any of the following reasons:
-- Attempting to create an array with an element type that
- is void, a function type, or a reference type. */
+ is void, a function type, or a reference type, or [DR337]
+ an abstract class type. */
if (TREE_CODE (type) == VOID_TYPE
|| TREE_CODE (type) == FUNCTION_TYPE
|| TREE_CODE (type) == REFERENCE_TYPE)
@@ -7057,6 +7069,13 @@ tsubst (t, args, complain, in_decl)
error ("creating array of `%T'", type);
return error_mark_node;
}
+ if (CLASS_TYPE_P (type) && CLASSTYPE_PURE_VIRTUALS (type))
+ {
+ if (complain & tf_error)
+ error ("creating array of `%T', which is an abstract class type",
+ type);
+ return error_mark_node;
+ }
r = build_cplus_array_type (type, domain);
return r;
@@ -7169,7 +7188,7 @@ tsubst (t, args, complain, in_decl)
if (e1 == error_mark_node || e2 == error_mark_node)
return error_mark_node;
- return build_nt (ARRAY_REF, e1, e2, tsubst_expr);
+ return build_nt (ARRAY_REF, e1, e2);
}
case CALL_EXPR:
@@ -7199,13 +7218,13 @@ tsubst (t, args, complain, in_decl)
case TYPEOF_TYPE:
{
- tree e1 = tsubst_expr (TYPE_FIELDS (t), args, complain, in_decl);
- if (e1 == error_mark_node)
- return error_mark_node;
+ tree type;
- return cp_build_qualified_type_real (TREE_TYPE (e1),
+ type = finish_typeof (tsubst_expr (TYPE_FIELDS (t), args, complain,
+ in_decl));
+ return cp_build_qualified_type_real (type,
cp_type_quals (t)
- | cp_type_quals (TREE_TYPE (e1)),
+ | cp_type_quals (type),
complain);
}
@@ -7216,15 +7235,150 @@ tsubst (t, args, complain, in_decl)
}
}
+/* Like tsubst_expr for a BASELINK. OBJECT_TYPE, if non-NULL, is the
+ type of the expression on the left-hand side of the "." or "->"
+ operator. */
+
+static tree
+tsubst_baselink (tree baselink, tree object_type,
+ tree args, tsubst_flags_t complain, tree in_decl)
+{
+ tree name;
+ tree qualifying_scope;
+ tree fns;
+ tree template_args = 0;
+ bool template_id_p = false;
+
+ /* A baselink indicates a function from a base class. The
+ BASELINK_ACCESS_BINFO and BASELINK_BINFO are going to have
+ non-dependent types; otherwise, the lookup could not have
+ succeeded. However, they may indicate bases of the template
+ class, rather than the instantiated class.
+
+ In addition, lookups that were not ambiguous before may be
+ ambiguous now. Therefore, we perform the lookup again. */
+ qualifying_scope = BINFO_TYPE (BASELINK_ACCESS_BINFO (baselink));
+ fns = BASELINK_FUNCTIONS (baselink);
+ if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
+ {
+ template_id_p = true;
+ template_args = TREE_OPERAND (fns, 1);
+ fns = TREE_OPERAND (fns, 0);
+ if (template_args)
+ template_args = tsubst_template_args (template_args, args,
+ complain, in_decl);
+ }
+ name = DECL_NAME (get_first_fn (fns));
+ baselink = lookup_fnfields (qualifying_scope, name, /*protect=*/1);
+ if (BASELINK_P (baselink) && template_id_p)
+ BASELINK_FUNCTIONS (baselink)
+ = build_nt (TEMPLATE_ID_EXPR,
+ BASELINK_FUNCTIONS (baselink),
+ template_args);
+ if (!object_type)
+ object_type = current_class_type;
+ return adjust_result_of_qualified_name_lookup (baselink,
+ qualifying_scope,
+ object_type);
+}
+
+/* Like tsubst_expr for a SCOPE_REF, given by QUALIFIED_ID. DONE is
+ true if the qualified-id will be a postfix-expression in-and-of
+ itself; false if more of the postfix-expression follows the
+ QUALIFIED_ID. ADDRESS_P is true if the qualified-id is the operand
+ of "&". */
+
+static tree
+tsubst_qualified_id (tree qualified_id, tree args,
+ tsubst_flags_t complain, tree in_decl,
+ bool done, bool address_p)
+{
+ tree expr;
+ tree scope;
+ tree name;
+ bool is_template;
+ tree template_args;
+
+ my_friendly_assert (TREE_CODE (qualified_id) == SCOPE_REF, 20030706);
+
+ /* Figure out what name to look up. */
+ name = TREE_OPERAND (qualified_id, 1);
+ if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
+ {
+ is_template = true;
+ template_args = TREE_OPERAND (name, 1);
+ if (template_args)
+ template_args = tsubst_template_args (template_args, args,
+ complain, in_decl);
+ name = TREE_OPERAND (name, 0);
+ }
+ else
+ {
+ is_template = false;
+ template_args = NULL_TREE;
+ }
+
+ /* Substitute into the qualifying scope. When there are no ARGS, we
+ are just trying to simplify a non-dependent expression. In that
+ case the qualifying scope may be dependent, and, in any case,
+ substituting will not help. */
+ scope = TREE_OPERAND (qualified_id, 0);
+ if (args)
+ {
+ scope = tsubst (scope, args, complain, in_decl);
+ expr = tsubst_copy (name, args, complain, in_decl);
+ }
+ else
+ expr = name;
+
+ if (dependent_type_p (scope))
+ return build_nt (SCOPE_REF, scope, expr);
+
+ if (!BASELINK_P (name) && !DECL_P (expr))
+ {
+ expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false);
+ if (TREE_CODE (TREE_CODE (expr) == TEMPLATE_DECL
+ ? DECL_TEMPLATE_RESULT (expr) : expr) == TYPE_DECL)
+ {
+ if (complain & tf_error)
+ {
+ error ("dependent-name `%E' is parsed as a non-type, but "
+ "instantiation yields a type", qualified_id);
+ inform ("say `typename %E' if a type is meant", qualified_id);
+ }
+ return error_mark_node;
+ }
+ }
+
+ if (DECL_P (expr))
+ check_accessibility_of_qualified_id (expr, /*object_type=*/NULL_TREE,
+ scope);
+
+ /* Remember that there was a reference to this entity. */
+ if (DECL_P (expr))
+ mark_used (expr);
+
+ if (is_template)
+ expr = lookup_template_function (expr, template_args);
+
+ if (expr == error_mark_node && complain & tf_error)
+ qualified_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1));
+ else if (TYPE_P (scope))
+ {
+ expr = (adjust_result_of_qualified_name_lookup
+ (expr, scope, current_class_type));
+ expr = finish_qualified_id_expr (scope, expr, done, address_p);
+ }
+
+ return expr;
+}
+
/* Like tsubst, but deals with expressions. This function just replaces
template parms; to finish processing the resultant expression, use
tsubst_expr. */
-tree
-tsubst_copy (t, args, complain, in_decl)
- tree t, args;
- tsubst_flags_t complain;
- tree in_decl;
+static tree
+tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
enum tree_code code;
tree r;
@@ -7237,16 +7391,25 @@ tsubst_copy (t, args, complain, in_decl)
switch (code)
{
case PARM_DECL:
- return do_identifier (DECL_NAME (t), 0, NULL_TREE);
+ r = retrieve_local_specialization (t);
+ my_friendly_assert (r != NULL, 20020903);
+ mark_used (r);
+ return r;
case CONST_DECL:
{
tree enum_type;
tree v;
- if (!DECL_CONTEXT (t))
- /* This is a global enumeration constant. */
+ if (DECL_TEMPLATE_PARM_P (t))
+ return tsubst_copy (DECL_INITIAL (t), args, complain, in_decl);
+ /* There is no need to substitute into namespace-scope
+ enumerators. */
+ if (DECL_NAMESPACE_SCOPE_P (t))
return t;
+ /* If ARGS is NULL, then T is known to be non-dependent. */
+ if (args == NULL_TREE)
+ return decl_constant_value (t);
/* Unfortunately, we cannot just call lookup_name here.
Consider:
@@ -7283,41 +7446,51 @@ tsubst_copy (t, args, complain, in_decl)
ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, complain, in_decl,
/*entering_scope=*/1);
if (ctx != DECL_CONTEXT (t))
- return lookup_field (ctx, DECL_NAME (t), 0, 0);
+ return lookup_field (ctx, DECL_NAME (t), 0, false);
}
return t;
case VAR_DECL:
case FUNCTION_DECL:
- if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
+ if ((DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t))
+ || local_variable_p (t))
t = tsubst (t, args, complain, in_decl);
mark_used (t);
return t;
+ case BASELINK:
+ return tsubst_baselink (t, current_class_type, args, complain, in_decl);
+
case TEMPLATE_DECL:
- if (is_member_template (t))
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
+ return tsubst (TREE_TYPE (DECL_TEMPLATE_RESULT (t)),
+ args, complain, in_decl);
+ else if (is_member_template (t))
return tsubst (t, args, complain, in_decl);
- else
- return t;
+ else if (DECL_CLASS_SCOPE_P (t)
+ && uses_template_parms (DECL_CONTEXT (t)))
+ {
+ /* Template template argument like the following example need
+ special treatment:
- case LOOKUP_EXPR:
- {
- /* We must tsubst into a LOOKUP_EXPR in case the names to
- which it refers is a conversion operator; in that case the
- name will change. We avoid making unnecessary copies,
- however. */
-
- tree id = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+ template <template <class> class TT> struct C {};
+ template <class T> struct D {
+ template <class U> struct E {};
+ C<E> c; // #1
+ };
+ D<int> d; // #2
- if (id != TREE_OPERAND (t, 0))
- {
- r = build_nt (LOOKUP_EXPR, id);
- LOOKUP_EXPR_GLOBAL (r) = LOOKUP_EXPR_GLOBAL (t);
- t = r;
- }
+ We are processing the template argument `E' in #1 for
+ the template instantiation #2. Originally, `E' is a
+ TEMPLATE_DECL with `D<T>' as its DECL_CONTEXT. Now we
+ have to substitute this with one having context `D<int>'. */
+ tree context = tsubst (DECL_CONTEXT (t), args, complain, in_decl);
+ return lookup_field (context, DECL_NAME(t), 0, false);
+ }
+ else
+ /* Ordinary template template argument. */
return t;
- }
case CAST_EXPR:
case REINTERPRET_CAST_EXPR:
@@ -7346,6 +7519,40 @@ tsubst_copy (t, args, complain, in_decl)
(code, tsubst (TREE_TYPE (t), args, complain, in_decl),
tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl));
+ case COMPONENT_REF:
+ {
+ tree object;
+ tree name;
+
+ object = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
+ name = TREE_OPERAND (t, 1);
+ if (TREE_CODE (name) == BIT_NOT_EXPR)
+ {
+ name = tsubst_copy (TREE_OPERAND (name, 0), args,
+ complain, in_decl);
+ name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
+ }
+ else if (TREE_CODE (name) == SCOPE_REF
+ && TREE_CODE (TREE_OPERAND (name, 1)) == BIT_NOT_EXPR)
+ {
+ tree base = tsubst_copy (TREE_OPERAND (name, 0), args,
+ complain, in_decl);
+ name = TREE_OPERAND (name, 1);
+ name = tsubst_copy (TREE_OPERAND (name, 0), args,
+ complain, in_decl);
+ name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
+ name = build_nt (SCOPE_REF, base, name);
+ }
+ else if (TREE_CODE (name) == BASELINK)
+ name = tsubst_baselink (name,
+ non_reference (TREE_TYPE (object)),
+ args, complain,
+ in_decl);
+ else
+ name = tsubst_copy (name, args, complain, in_decl);
+ return build_nt (COMPONENT_REF, object, name);
+ }
+
case PLUS_EXPR:
case MINUS_EXPR:
case MULT_EXPR:
@@ -7355,7 +7562,6 @@ tsubst_copy (t, args, complain, in_decl)
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
case BIT_AND_EXPR:
- case BIT_ANDTC_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
case TRUNC_MOD_EXPR:
@@ -7376,7 +7582,6 @@ tsubst_copy (t, args, complain, in_decl)
case GE_EXPR:
case LT_EXPR:
case GT_EXPR:
- case COMPONENT_REF:
case ARRAY_REF:
case COMPOUND_EXPR:
case SCOPE_REF:
@@ -7391,60 +7596,25 @@ tsubst_copy (t, args, complain, in_decl)
tsubst_copy (TREE_OPERAND (t, 1), args, complain, in_decl));
case CALL_EXPR:
- {
- tree fn = TREE_OPERAND (t, 0);
- if (is_overloaded_fn (fn))
- fn = tsubst_copy (get_first_fn (fn), args, complain, in_decl);
- else
- /* Sometimes FN is a LOOKUP_EXPR. */
- fn = tsubst_copy (fn, args, complain, in_decl);
- return build_nt
- (code, fn, tsubst_copy (TREE_OPERAND (t, 1), args, complain,
- in_decl),
- NULL_TREE);
- }
-
- case METHOD_CALL_EXPR:
- {
- tree name = TREE_OPERAND (t, 0);
- if (TREE_CODE (name) == BIT_NOT_EXPR)
- {
- name = tsubst_copy (TREE_OPERAND (name, 0), args,
- complain, in_decl);
- name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
- }
- else if (TREE_CODE (name) == SCOPE_REF
- && TREE_CODE (TREE_OPERAND (name, 1)) == BIT_NOT_EXPR)
- {
- tree base = tsubst_copy (TREE_OPERAND (name, 0), args,
- complain, in_decl);
- name = TREE_OPERAND (TREE_OPERAND (name, 1), 0);
- if (TREE_CODE (name) == TYPE_DECL)
- name = TREE_TYPE (name);
- name = tsubst_copy (name, args, complain, in_decl);
- name = build1 (BIT_NOT_EXPR, NULL_TREE, name);
- name = build_nt (SCOPE_REF, base, name);
- }
- else
- name = tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl);
- return build_nt
- (code, name, tsubst_copy (TREE_OPERAND (t, 1), args,
+ return build_nt (code,
+ tsubst_copy (TREE_OPERAND (t, 0), args,
complain, in_decl),
- tsubst_copy (TREE_OPERAND (t, 2), args, complain, in_decl),
- NULL_TREE);
- }
+ tsubst_copy (TREE_OPERAND (t, 1), args, complain,
+ in_decl),
+ NULL_TREE);
case STMT_EXPR:
- /* This processing should really occur in tsubst_expr, However,
+ /* This processing should really occur in tsubst_expr. However,
tsubst_expr does not recurse into expressions, since it
- assumes that there aren't any statements inside them.
- Instead, it simply calls build_expr_from_tree. So, we need
- to expand the STMT_EXPR here. */
+ assumes that there aren't any statements inside them. So, we
+ need to expand the STMT_EXPR here. */
if (!processing_template_decl)
{
tree stmt_expr = begin_stmt_expr ();
- tsubst_expr (STMT_EXPR_STMT (t), args, complain, in_decl);
- return finish_stmt_expr (stmt_expr);
+
+ tsubst_expr (STMT_EXPR_STMT (t), args,
+ complain | tf_stmt_expr_cmpd, in_decl);
+ return finish_stmt_expr (stmt_expr, false);
}
return t;
@@ -7483,25 +7653,14 @@ tsubst_copy (t, args, complain, in_decl)
case TEMPLATE_ID_EXPR:
{
/* Substituted template arguments */
- tree targs = tsubst_copy (TREE_OPERAND (t, 1), args, complain,
- in_decl);
-
- if (targs && TREE_CODE (targs) == TREE_LIST)
- {
- tree chain;
- for (chain = targs; chain; chain = TREE_CHAIN (chain))
- TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain));
- }
- else if (targs)
- {
- int i;
- for (i = 0; i < TREE_VEC_LENGTH (targs); ++i)
- TREE_VEC_ELT (targs, i)
- = maybe_fold_nontype_arg (TREE_VEC_ELT (targs, i));
- }
+ tree fn = TREE_OPERAND (t, 0);
+ tree targs = TREE_OPERAND (t, 1);
- return lookup_template_function
- (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), targs);
+ fn = tsubst_copy (fn, args, complain, in_decl);
+ if (targs)
+ targs = tsubst_template_args (targs, args, complain, in_decl);
+
+ return lookup_template_function (fn, targs);
}
case TREE_LIST:
@@ -7558,10 +7717,9 @@ tsubst_copy (t, args, complain, in_decl)
case CONSTRUCTOR:
{
- r = build
- (CONSTRUCTOR, tsubst (TREE_TYPE (t), args, complain, in_decl),
- NULL_TREE, tsubst_copy (CONSTRUCTOR_ELTS (t), args,
- complain, in_decl));
+ r = build_constructor
+ (tsubst (TREE_TYPE (t), args, complain, in_decl),
+ tsubst_copy (CONSTRUCTOR_ELTS (t), args, complain, in_decl));
TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
return r;
}
@@ -7576,34 +7734,26 @@ tsubst_copy (t, args, complain, in_decl)
}
}
-/* Like tsubst_copy, but also does semantic processing. */
+/* Like tsubst_copy for expressions, etc. but also does semantic
+ processing. */
-tree
-tsubst_expr (t, args, complain, in_decl)
- tree t, args;
- tsubst_flags_t complain;
- tree in_decl;
+static tree
+tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
tree stmt, tmp;
+ tsubst_flags_t stmt_expr
+ = complain & (tf_stmt_expr_cmpd | tf_stmt_expr_body);
+ complain ^= stmt_expr;
if (t == NULL_TREE || t == error_mark_node)
return t;
- if (processing_template_decl)
- return tsubst_copy (t, args, complain, in_decl);
-
- if (!statement_code_p (TREE_CODE (t)))
- return build_expr_from_tree (tsubst_copy (t, args, complain, in_decl));
+ if (!STATEMENT_CODE_P (TREE_CODE (t)))
+ return tsubst_copy_and_build (t, args, complain, in_decl,
+ /*function_p=*/false);
switch (TREE_CODE (t))
{
- case RETURN_INIT:
- prep_stmt (t);
- finish_named_return_value
- (TREE_OPERAND (t, 0),
- tsubst_expr (TREE_OPERAND (t, 1), args, complain, in_decl));
- break;
-
case CTOR_INITIALIZER:
prep_stmt (t);
finish_mem_initializers (tsubst_initializer_list
@@ -7617,10 +7767,18 @@ tsubst_expr (t, args, complain, in_decl)
break;
case EXPR_STMT:
- prep_stmt (t);
- finish_expr_stmt (tsubst_expr (EXPR_STMT_EXPR (t),
- args, complain, in_decl));
- break;
+ {
+ tree r;
+
+ prep_stmt (t);
+
+ r = tsubst_expr (EXPR_STMT_EXPR (t), args, complain, in_decl);
+ if (stmt_expr & tf_stmt_expr_body && !TREE_CHAIN (t))
+ finish_stmt_expr_expr (r);
+ else
+ finish_expr_stmt (r);
+ break;
+ }
case USING_STMT:
prep_stmt (t);
@@ -7641,9 +7799,16 @@ tsubst_expr (t, args, complain, in_decl)
{
tree scope = DECL_INITIAL (decl);
tree name = DECL_NAME (decl);
+ tree decl;
scope = tsubst_expr (scope, args, complain, in_decl);
- do_local_using_decl (build_nt (SCOPE_REF, scope, name));
+ decl = lookup_qualified_name (scope, name,
+ /*is_type_p=*/false,
+ /*complain=*/false);
+ if (decl == error_mark_node)
+ qualified_name_lookup_error (scope, name);
+ else
+ do_local_using_decl (decl, scope, name);
}
else
{
@@ -7667,14 +7832,14 @@ tsubst_expr (t, args, complain, in_decl)
else
{
maybe_push_decl (decl);
- if (DECL_PRETTY_FUNCTION_P (decl))
+ if (TREE_CODE (decl) == VAR_DECL
+ && DECL_PRETTY_FUNCTION_P (decl))
{
/* For __PRETTY_FUNCTION__ we have to adjust the
initializer. */
const char *const name
= cxx_printable_name (current_function_decl, 2);
- init = cp_fname_init (name);
- TREE_TYPE (decl) = TREE_TYPE (init);
+ init = cp_fname_init (name, &TREE_TYPE (decl));
}
else
init = tsubst_expr (init, args, complain, in_decl);
@@ -7765,12 +7930,14 @@ tsubst_expr (t, args, complain, in_decl)
else
stmt = begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
- tsubst_expr (COMPOUND_BODY (t), args, complain, in_decl);
+ tsubst_expr (COMPOUND_BODY (t), args,
+ complain | ((stmt_expr & tf_stmt_expr_cmpd) << 1),
+ in_decl);
if (COMPOUND_STMT_BODY_BLOCK (t))
finish_function_body (stmt);
else
- finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), stmt);
+ finish_compound_stmt (stmt);
}
break;
@@ -7805,7 +7972,7 @@ tsubst_expr (t, args, complain, in_decl)
break;
case LABEL_STMT:
- lineno = STMT_LINENO (t);
+ input_line = STMT_LINENO (t);
finish_label_stmt (DECL_NAME (LABEL_STMT_LABEL (t)));
break;
@@ -7903,21 +8070,585 @@ tsubst_expr (t, args, complain, in_decl)
abort ();
}
- return tsubst_expr (TREE_CHAIN (t), args, complain, in_decl);
+ return tsubst_expr (TREE_CHAIN (t), args, complain | stmt_expr, in_decl);
+}
+
+/* T is a postfix-expression that is not being used in a function
+ call. Return the substituted version of T. */
+
+static tree
+tsubst_non_call_postfix_expression (tree t, tree args,
+ tsubst_flags_t complain,
+ tree in_decl)
+{
+ if (TREE_CODE (t) == SCOPE_REF)
+ t = tsubst_qualified_id (t, args, complain, in_decl,
+ /*done=*/false, /*address_p=*/false);
+ else
+ t = tsubst_copy_and_build (t, args, complain, in_decl,
+ /*function_p=*/false);
+
+ return t;
+}
+
+/* Like tsubst but deals with expressions and performs semantic
+ analysis. FUNCTION_P is true if T is the "F" in "F (ARGS)". */
+
+tree
+tsubst_copy_and_build (tree t,
+ tree args,
+ tsubst_flags_t complain,
+ tree in_decl,
+ bool function_p)
+{
+#define RECUR(NODE) \
+ tsubst_copy_and_build (NODE, args, complain, in_decl, /*function_p=*/false)
+
+ tree op1;
+
+ if (t == NULL_TREE || t == error_mark_node)
+ return t;
+
+ switch (TREE_CODE (t))
+ {
+ case USING_DECL:
+ t = DECL_NAME (t);
+ /* Fallthrough. */
+ case IDENTIFIER_NODE:
+ {
+ tree decl;
+ cp_id_kind idk;
+ tree qualifying_class;
+ bool non_integral_constant_expression_p;
+ const char *error_msg;
+
+ if (IDENTIFIER_TYPENAME_P (t))
+ {
+ tree new_type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ t = mangle_conv_op_name_for_type (new_type);
+ }
+
+ /* Look up the name. */
+ decl = lookup_name (t, 0);
+
+ /* By convention, expressions use ERROR_MARK_NODE to indicate
+ failure, not NULL_TREE. */
+ if (decl == NULL_TREE)
+ decl = error_mark_node;
+
+ decl = finish_id_expression (t, decl, NULL_TREE,
+ &idk,
+ &qualifying_class,
+ /*integral_constant_expression_p=*/false,
+ /*allow_non_integral_constant_expression_p=*/false,
+ &non_integral_constant_expression_p,
+ &error_msg);
+ if (error_msg)
+ error (error_msg);
+ if (!function_p && TREE_CODE (decl) == IDENTIFIER_NODE)
+ decl = unqualified_name_lookup_error (decl);
+ return decl;
+ }
+
+ case TEMPLATE_ID_EXPR:
+ {
+ tree object;
+ tree template = RECUR (TREE_OPERAND (t, 0));
+ tree targs = TREE_OPERAND (t, 1);
+
+ if (targs)
+ targs = tsubst_template_args (targs, args, complain, in_decl);
+
+ if (TREE_CODE (template) == COMPONENT_REF)
+ {
+ object = TREE_OPERAND (template, 0);
+ template = TREE_OPERAND (template, 1);
+ }
+ else
+ object = NULL_TREE;
+ template = lookup_template_function (template, targs);
+
+ if (object)
+ return build (COMPONENT_REF, TREE_TYPE (template),
+ object, template);
+ else
+ return template;
+ }
+
+ case INDIRECT_REF:
+ return build_x_indirect_ref (RECUR (TREE_OPERAND (t, 0)), "unary *");
+
+ case NOP_EXPR:
+ return build_nop
+ (tsubst (TREE_TYPE (t), args, complain, in_decl),
+ RECUR (TREE_OPERAND (t, 0)));
+
+ case CAST_EXPR:
+ return build_functional_cast
+ (tsubst (TREE_TYPE (t), args, complain, in_decl),
+ RECUR (TREE_OPERAND (t, 0)));
+
+ case REINTERPRET_CAST_EXPR:
+ return build_reinterpret_cast
+ (tsubst (TREE_TYPE (t), args, complain, in_decl),
+ RECUR (TREE_OPERAND (t, 0)));
+
+ case CONST_CAST_EXPR:
+ return build_const_cast
+ (tsubst (TREE_TYPE (t), args, complain, in_decl),
+ RECUR (TREE_OPERAND (t, 0)));
+
+ case DYNAMIC_CAST_EXPR:
+ return build_dynamic_cast
+ (tsubst (TREE_TYPE (t), args, complain, in_decl),
+ RECUR (TREE_OPERAND (t, 0)));
+
+ case STATIC_CAST_EXPR:
+ return build_static_cast
+ (tsubst (TREE_TYPE (t), args, complain, in_decl),
+ RECUR (TREE_OPERAND (t, 0)));
+
+ case POSTDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
+ args, complain, in_decl);
+ return build_x_unary_op (TREE_CODE (t), op1);
+
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case NEGATE_EXPR:
+ case BIT_NOT_EXPR:
+ case ABS_EXPR:
+ case TRUTH_NOT_EXPR:
+ case CONVERT_EXPR: /* Unary + */
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0)));
+
+ case ADDR_EXPR:
+ op1 = TREE_OPERAND (t, 0);
+ if (TREE_CODE (op1) == SCOPE_REF)
+ op1 = tsubst_qualified_id (op1, args, complain, in_decl,
+ /*done=*/true, /*address_p=*/true);
+ else
+ op1 = tsubst_non_call_postfix_expression (op1, args, complain,
+ in_decl);
+ if (TREE_CODE (op1) == LABEL_DECL)
+ return finish_label_address_expr (DECL_NAME (op1));
+ return build_x_unary_op (ADDR_EXPR, op1);
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case TRUNC_MOD_EXPR:
+ case FLOOR_MOD_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ case RSHIFT_EXPR:
+ case LSHIFT_EXPR:
+ case RROTATE_EXPR:
+ case LROTATE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case MAX_EXPR:
+ case MIN_EXPR:
+ case LE_EXPR:
+ case GE_EXPR:
+ case LT_EXPR:
+ case GT_EXPR:
+ case MEMBER_REF:
+ case DOTSTAR_EXPR:
+ return build_x_binary_op
+ (TREE_CODE (t),
+ RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
+ /*overloaded_p=*/NULL);
+
+ case SCOPE_REF:
+ return tsubst_qualified_id (t, args, complain, in_decl, /*done=*/true,
+ /*address_p=*/false);
+
+ case ARRAY_REF:
+ if (tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl)
+ == NULL_TREE)
+ /* new-type-id */
+ return build_nt (ARRAY_REF, NULL_TREE, RECUR (TREE_OPERAND (t, 1)));
+
+ op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
+ args, complain, in_decl);
+ /* Remember that there was a reference to this entity. */
+ if (DECL_P (op1))
+ mark_used (op1);
+ return grok_array_decl (op1, RECUR (TREE_OPERAND (t, 1)));
+
+ case SIZEOF_EXPR:
+ case ALIGNOF_EXPR:
+ op1 = TREE_OPERAND (t, 0);
+ if (!args)
+ {
+ /* When there are no ARGS, we are trying to evaluate a
+ non-dependent expression from the parser. Trying to do
+ the substitutions may not work. */
+ if (!TYPE_P (op1))
+ op1 = TREE_TYPE (op1);
+ }
+ else
+ {
+ ++skip_evaluation;
+ op1 = RECUR (op1);
+ --skip_evaluation;
+ }
+ if (TYPE_P (op1))
+ return cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), true);
+ else
+ return cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t));
+
+ case MODOP_EXPR:
+ return build_x_modify_expr
+ (RECUR (TREE_OPERAND (t, 0)),
+ TREE_CODE (TREE_OPERAND (t, 1)),
+ RECUR (TREE_OPERAND (t, 2)));
+
+ case ARROW_EXPR:
+ op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
+ args, complain, in_decl);
+ /* Remember that there was a reference to this entity. */
+ if (DECL_P (op1))
+ mark_used (op1);
+ return build_x_arrow (op1);
+
+ case NEW_EXPR:
+ return build_new
+ (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
+ RECUR (TREE_OPERAND (t, 2)),
+ NEW_EXPR_USE_GLOBAL (t));
+
+ case DELETE_EXPR:
+ return delete_sanity
+ (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
+ DELETE_EXPR_USE_VEC (t),
+ DELETE_EXPR_USE_GLOBAL (t));
+
+ case COMPOUND_EXPR:
+ return build_x_compound_expr (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)));
+
+ case CALL_EXPR:
+ {
+ tree function;
+ tree call_args;
+ bool qualified_p;
+ bool koenig_p;
+
+ function = TREE_OPERAND (t, 0);
+ /* When we parsed the expression, we determined whether or
+ not Koenig lookup should be performed. */
+ koenig_p = KOENIG_LOOKUP_P (t);
+ if (TREE_CODE (function) == SCOPE_REF)
+ {
+ qualified_p = true;
+ function = tsubst_qualified_id (function, args, complain, in_decl,
+ /*done=*/false,
+ /*address_p=*/false);
+ }
+ else
+ {
+ qualified_p = (TREE_CODE (function) == COMPONENT_REF
+ && (TREE_CODE (TREE_OPERAND (function, 1))
+ == SCOPE_REF));
+ function = tsubst_copy_and_build (function, args, complain,
+ in_decl,
+ !qualified_p);
+ if (BASELINK_P (function))
+ qualified_p = true;
+ }
+
+ call_args = RECUR (TREE_OPERAND (t, 1));
+
+ /* We do not perform argument-dependent lookup if normal
+ lookup finds a non-function, in accordance with the
+ expected resolution of DR 218. */
+ if (koenig_p
+ && (is_overloaded_fn (function)
+ || TREE_CODE (function) == IDENTIFIER_NODE))
+ function = perform_koenig_lookup (function, call_args);
+
+ if (TREE_CODE (function) == IDENTIFIER_NODE)
+ {
+ unqualified_name_lookup_error (function);
+ return error_mark_node;
+ }
+
+ /* Remember that there was a reference to this entity. */
+ if (DECL_P (function))
+ mark_used (function);
+
+ function = convert_from_reference (function);
+
+ if (TREE_CODE (function) == OFFSET_REF)
+ return build_offset_ref_call_from_tree (function, call_args);
+ if (TREE_CODE (function) == COMPONENT_REF)
+ {
+ if (!BASELINK_P (TREE_OPERAND (function, 1)))
+ return finish_call_expr (function, call_args,
+ /*disallow_virtual=*/false,
+ /*koenig_p=*/false);
+ else
+ return (build_new_method_call
+ (TREE_OPERAND (function, 0),
+ TREE_OPERAND (function, 1),
+ call_args, NULL_TREE,
+ qualified_p ? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL));
+ }
+ return finish_call_expr (function, call_args,
+ /*disallow_virtual=*/qualified_p,
+ koenig_p);
+ }
+
+ case COND_EXPR:
+ return build_x_conditional_expr
+ (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
+ RECUR (TREE_OPERAND (t, 2)));
+
+ case PSEUDO_DTOR_EXPR:
+ return finish_pseudo_destructor_expr
+ (RECUR (TREE_OPERAND (t, 0)),
+ RECUR (TREE_OPERAND (t, 1)),
+ RECUR (TREE_OPERAND (t, 2)));
+
+ case TREE_LIST:
+ {
+ tree purpose, value, chain;
+
+ if (t == void_list_node)
+ return t;
+
+ purpose = TREE_PURPOSE (t);
+ if (purpose)
+ purpose = RECUR (purpose);
+ value = TREE_VALUE (t);
+ if (value)
+ value = RECUR (value);
+ chain = TREE_CHAIN (t);
+ if (chain && chain != void_type_node)
+ chain = RECUR (chain);
+ if (purpose == TREE_PURPOSE (t)
+ && value == TREE_VALUE (t)
+ && chain == TREE_CHAIN (t))
+ return t;
+ return tree_cons (purpose, value, chain);
+ }
+
+ case COMPONENT_REF:
+ {
+ tree object;
+ tree member;
+
+ object = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0),
+ args, complain, in_decl);
+ /* Remember that there was a reference to this entity. */
+ if (DECL_P (object))
+ mark_used (object);
+
+ member = TREE_OPERAND (t, 1);
+ if (BASELINK_P (member))
+ member = tsubst_baselink (member,
+ non_reference (TREE_TYPE (object)),
+ args, complain, in_decl);
+ else
+ member = tsubst_copy (member, args, complain, in_decl);
+
+ if (!CLASS_TYPE_P (TREE_TYPE (object)))
+ {
+ if (TREE_CODE (member) == BIT_NOT_EXPR)
+ return finish_pseudo_destructor_expr (object,
+ NULL_TREE,
+ TREE_TYPE (object));
+ else if (TREE_CODE (member) == SCOPE_REF
+ && (TREE_CODE (TREE_OPERAND (member, 1)) == BIT_NOT_EXPR))
+ return finish_pseudo_destructor_expr (object,
+ object,
+ TREE_TYPE (object));
+ }
+ else if (TREE_CODE (member) == SCOPE_REF
+ && TREE_CODE (TREE_OPERAND (member, 1)) == TEMPLATE_ID_EXPR)
+ {
+ tree tmpl;
+ tree args;
+
+ /* Lookup the template functions now that we know what the
+ scope is. */
+ tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0);
+ args = TREE_OPERAND (TREE_OPERAND (member, 1), 1);
+ member = lookup_qualified_name (TREE_OPERAND (member, 0), tmpl,
+ /*is_type_p=*/false,
+ /*complain=*/false);
+ if (BASELINK_P (member))
+ BASELINK_FUNCTIONS (member)
+ = build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
+ args);
+ else
+ {
+ qualified_name_lookup_error (TREE_TYPE (object), tmpl);
+ return error_mark_node;
+ }
+ }
+ else if (TREE_CODE (member) == FIELD_DECL)
+ return finish_non_static_data_member (member, object, NULL_TREE);
+
+ return finish_class_member_access_expr (object, member);
+ }
+
+ case THROW_EXPR:
+ return build_throw
+ (RECUR (TREE_OPERAND (t, 0)));
+
+ case CONSTRUCTOR:
+ {
+ tree r;
+ tree elts;
+ tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ bool purpose_p;
+
+ /* digest_init will do the wrong thing if we let it. */
+ if (type && TYPE_PTRMEMFUNC_P (type))
+ return t;
+
+ r = NULL_TREE;
+ /* We do not want to process the purpose of aggregate
+ initializers as they are identifier nodes which will be
+ looked up by digest_init. */
+ purpose_p = !(type && IS_AGGR_TYPE (type));
+ for (elts = CONSTRUCTOR_ELTS (t);
+ elts;
+ elts = TREE_CHAIN (elts))
+ {
+ tree purpose = TREE_PURPOSE (elts);
+ tree value = TREE_VALUE (elts);
+
+ if (purpose && purpose_p)
+ purpose = RECUR (purpose);
+ value = RECUR (value);
+ r = tree_cons (purpose, value, r);
+ }
+
+ r = build_constructor (NULL_TREE, nreverse (r));
+ TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t);
+
+ if (type)
+ return digest_init (type, r, 0);
+ return r;
+ }
+
+ case TYPEID_EXPR:
+ {
+ tree operand_0 = RECUR (TREE_OPERAND (t, 0));
+ if (TYPE_P (operand_0))
+ return get_typeid (operand_0);
+ return build_typeid (operand_0);
+ }
+
+ case PARM_DECL:
+ return convert_from_reference (tsubst_copy (t, args, complain, in_decl));
+
+ case VAR_DECL:
+ if (args)
+ t = tsubst_copy (t, args, complain, in_decl);
+ return convert_from_reference (t);
+
+ case VA_ARG_EXPR:
+ return build_x_va_arg (RECUR (TREE_OPERAND (t, 0)),
+ tsubst_copy (TREE_TYPE (t), args, complain,
+ in_decl));
+
+ default:
+ return tsubst_copy (t, args, complain, in_decl);
+ }
+
+#undef RECUR
+}
+
+/* Verify that the instantiated ARGS are valid. For type arguments,
+ make sure that the type's linkage is ok. For non-type arguments,
+ make sure they are constants if they are integral or enumerations.
+ Emit an error under control of COMPLAIN, and return TRUE on error. */
+
+static bool
+check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain)
+{
+ int ix, len = DECL_NTPARMS (tmpl);
+ bool result = false;
+
+ for (ix = 0; ix != len; ix++)
+ {
+ tree t = TREE_VEC_ELT (args, ix);
+
+ if (TYPE_P (t))
+ {
+ /* [basic.link]: A name with no linkage (notably, the name
+ of a class or enumeration declared in a local scope)
+ shall not be used to declare an entity with linkage.
+ This implies that names with no linkage cannot be used as
+ template arguments. */
+ tree nt = no_linkage_check (t);
+
+ if (nt)
+ {
+ if (!(complain & tf_error))
+ /*OK*/;
+ else if (TYPE_ANONYMOUS_P (nt))
+ error ("`%T' uses anonymous type", t);
+ else
+ error ("`%T' uses local type `%T'", t, nt);
+ result = true;
+ }
+ /* In order to avoid all sorts of complications, we do not
+ allow variably-modified types as template arguments. */
+ else if (variably_modified_type_p (t))
+ {
+ if (complain & tf_error)
+ error ("`%T' is a variably modified type", t);
+ result = true;
+ }
+ }
+ /* A non-type argument of integral or enumerated type must be a
+ constant. */
+ else if (TREE_TYPE (t)
+ && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (t))
+ && !TREE_CONSTANT (t))
+ {
+ if (complain & tf_error)
+ error ("integral expression `%E' is not constant", t);
+ result = true;
+ }
+ }
+ if (result && complain & tf_error)
+ error (" trying to instantiate `%D'", tmpl);
+ return result;
}
/* Instantiate the indicated variable or function template TMPL with
the template arguments in TARG_PTR. */
tree
-instantiate_template (tmpl, targ_ptr)
- tree tmpl, targ_ptr;
+instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
{
tree fndecl;
tree gen_tmpl;
tree spec;
- int i, len;
- tree inner_args;
if (tmpl == error_mark_node)
return error_mark_node;
@@ -7927,9 +8658,14 @@ instantiate_template (tmpl, targ_ptr)
/* If this function is a clone, handle it specially. */
if (DECL_CLONED_FUNCTION_P (tmpl))
{
- tree spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), targ_ptr);
+ tree spec;
tree clone;
+ spec = instantiate_template (DECL_CLONED_FUNCTION (tmpl), targ_ptr,
+ complain);
+ if (spec == error_mark_node)
+ return error_mark_node;
+
/* Look for the clone. */
for (clone = TREE_CHAIN (spec);
clone && DECL_CLONED_FUNCTION_P (clone);
@@ -7961,44 +8697,32 @@ instantiate_template (tmpl, targ_ptr)
return spec;
}
- len = DECL_NTPARMS (gen_tmpl);
- inner_args = INNERMOST_TEMPLATE_ARGS (targ_ptr);
- i = len;
- while (i--)
- {
- tree t = TREE_VEC_ELT (inner_args, i);
- if (TYPE_P (t))
- {
- tree nt = target_type (t);
- if (IS_AGGR_TYPE (nt) && decl_function_context (TYPE_MAIN_DECL (nt)))
- {
- error ("type `%T' composed from a local class is not a valid template-argument", t);
- error (" trying to instantiate `%D'", gen_tmpl);
- return error_mark_node;
- }
- }
- }
-
- /* Make sure that we can see identifiers, and compute access
- correctly. The desired FUNCTION_DECL for FNDECL may or may not be
- created earlier. Let push_access_scope_real figure that out. */
- push_access_scope_real
- (gen_tmpl, targ_ptr, tsubst (DECL_CONTEXT (gen_tmpl), targ_ptr,
- tf_error, gen_tmpl));
-
- /* substitute template parameters */
+ if (check_instantiated_args (gen_tmpl, INNERMOST_TEMPLATE_ARGS (targ_ptr),
+ complain))
+ return error_mark_node;
+
+ /* We are building a FUNCTION_DECL, during which the access of its
+ parameters and return types have to be checked. However this
+ FUNCTION_DECL which is the desired context for access checking
+ is not built yet. We solve this chicken-and-egg problem by
+ deferring all checks until we have the FUNCTION_DECL. */
+ push_deferring_access_checks (dk_deferred);
+
+ /* Substitute template parameters. */
fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl),
- targ_ptr, tf_error, gen_tmpl);
+ targ_ptr, complain, gen_tmpl);
- pop_access_scope (gen_tmpl);
+ /* Now we know the specialization, compute access previously
+ deferred. */
+ push_access_scope (fndecl);
+ perform_deferred_access_checks ();
+ pop_access_scope (fndecl);
+ pop_deferring_access_checks ();
/* The DECL_TI_TEMPLATE should always be the immediate parent
template, not the most general template. */
DECL_TI_TEMPLATE (fndecl) = tmpl;
- if (flag_external_templates)
- add_pending_template (fndecl);
-
/* If we've just instantiated the main entry point for a function,
instantiate all the alternate entry points as well. We do this
by cloning the instantiation of the main entry point, not by
@@ -8051,11 +8775,13 @@ instantiate_template (tmpl, targ_ptr)
partial ordering in [temp.func.order]/6). */
int
-fn_type_unification (fn, explicit_targs, targs, args, return_type,
- strict, len)
- tree fn, explicit_targs, targs, args, return_type;
- unification_kind_t strict;
- int len;
+fn_type_unification (tree fn,
+ tree explicit_targs,
+ tree targs,
+ tree args,
+ tree return_type,
+ unification_kind_t strict,
+ int len)
{
tree parms;
tree fntype;
@@ -8085,6 +8811,7 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
template results in an invalid type, type deduction fails. */
int i;
tree converted_args;
+ bool incomplete;
converted_args
= (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (fn),
@@ -8093,12 +8820,22 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
if (converted_args == error_mark_node)
return 1;
+ /* Substitute the explicit args into the function type. This is
+ necessary so that, for instance, explicitly declared function
+ arguments can match null pointed constants. If we were given
+ an incomplete set of explicit args, we must not do semantic
+ processing during substitution as we could create partial
+ instantiations. */
+ incomplete = NUM_TMPL_ARGS (explicit_targs) != NUM_TMPL_ARGS (targs);
+ processing_template_decl += incomplete;
fntype = tsubst (fntype, converted_args, tf_none, NULL_TREE);
+ processing_template_decl -= incomplete;
+
if (fntype == error_mark_node)
return 1;
/* Place the explicitly specified arguments in TARGS. */
- for (i = 0; i < TREE_VEC_LENGTH (targs); i++)
+ for (i = NUM_TMPL_ARGS (converted_args); i--;)
TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (converted_args, i);
}
@@ -8149,10 +8886,9 @@ fn_type_unification (fn, explicit_targs, targs, args, return_type,
initialized with the result of the conversion function. */
static int
-maybe_adjust_types_for_deduction (strict, parm, arg)
- unification_kind_t strict;
- tree* parm;
- tree* arg;
+maybe_adjust_types_for_deduction (unification_kind_t strict,
+ tree* parm,
+ tree* arg)
{
int result = 0;
@@ -8256,12 +8992,14 @@ maybe_adjust_types_for_deduction (strict, parm, arg)
template). */
static int
-type_unification_real (tparms, targs, xparms, xargs, subr,
- strict, allow_incomplete, xlen)
- tree tparms, targs, xparms, xargs;
- int subr;
- unification_kind_t strict;
- int allow_incomplete, xlen;
+type_unification_real (tree tparms,
+ tree targs,
+ tree xparms,
+ tree xargs,
+ int subr,
+ unification_kind_t strict,
+ int allow_incomplete,
+ int xlen)
{
tree parm, arg;
int i;
@@ -8274,9 +9012,7 @@ type_unification_real (tparms, targs, xparms, xargs, subr,
my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289);
my_friendly_assert (xparms == NULL_TREE
|| TREE_CODE (xparms) == TREE_LIST, 290);
- /* ARGS could be NULL. */
- if (xargs)
- my_friendly_assert (TREE_CODE (xargs) == TREE_LIST, 291);
+ my_friendly_assert (!xargs || TREE_CODE (xargs) == TREE_LIST, 291);
my_friendly_assert (ntparms > 0, 292);
switch (strict)
@@ -8331,17 +9067,14 @@ type_unification_real (tparms, targs, xparms, xargs, subr,
corresponds with a function parameter that contains only
non-deducible template parameters and explicitly specified
template parameters. */
- if (! uses_template_parms (parm))
+ if (!uses_template_parms (parm))
{
tree type;
if (!TYPE_P (arg))
type = TREE_TYPE (arg);
else
- {
- type = arg;
- arg = NULL_TREE;
- }
+ type = arg;
if (strict == DEDUCE_EXACT || strict == DEDUCE_ORDER)
{
@@ -8375,6 +9108,8 @@ type_unification_real (tparms, targs, xparms, xargs, subr,
continue;
}
arg = TREE_TYPE (arg);
+ if (arg == error_mark_node)
+ return 1;
}
{
@@ -8395,7 +9130,7 @@ type_unification_real (tparms, targs, xparms, xargs, subr,
are present, and the parm list isn't variadic. */
if (args && args != void_list_node && parms == void_list_node)
return 1;
- /* Fail if parms are left and they don't have default values. */
+ /* Fail if parms are left and they don't have default values. */
if (parms
&& parms != void_list_node
&& TREE_PURPOSE (parms) == NULL_TREE)
@@ -8430,11 +9165,12 @@ type_unification_real (tparms, targs, xparms, xargs, subr,
succeeds, we go with that. Modifies TARGS and returns 0 on success. */
static int
-resolve_overloaded_unification (tparms, targs, parm, arg, strict,
- sub_strict)
- tree tparms, targs, parm, arg;
- unification_kind_t strict;
- int sub_strict;
+resolve_overloaded_unification (tree tparms,
+ tree targs,
+ tree parm,
+ tree arg,
+ unification_kind_t strict,
+ int sub_strict)
{
tree tempargs = copy_node (targs);
int good = 0;
@@ -8529,11 +9265,11 @@ resolve_overloaded_unification (tparms, targs, parm, arg, strict,
static int
try_one_overload (tree tparms,
- tree orig_targs,
- tree targs,
- tree parm,
- tree arg,
- unification_kind_t strict,
+ tree orig_targs,
+ tree targs,
+ tree parm,
+ tree arg,
+ unification_kind_t strict,
int sub_strict,
bool addr_p)
{
@@ -8618,8 +9354,7 @@ try_one_overload (tree tparms,
ARGS contains template arguments from all levels. */
static int
-verify_class_unification (targs, parms, args)
- tree targs, parms, args;
+verify_class_unification (tree targs, tree parms, tree args)
{
parms = tsubst (parms, add_outermost_template_args (args, targs),
tf_none, NULL_TREE);
@@ -8635,11 +9370,7 @@ verify_class_unification (targs, parms, args)
TARGS are as for unify. */
static tree
-try_class_unification (tparms, targs, parm, arg)
- tree tparms;
- tree targs;
- tree parm;
- tree arg;
+try_class_unification (tree tparms, tree targs, tree parm, tree arg)
{
tree copy_of_targs;
@@ -8693,14 +9424,12 @@ try_class_unification (tparms, targs, parm, arg)
for the base class of ARG that we are currently examining. */
static tree
-get_template_base_recursive (tparms, targs, parm,
- arg_binfo, rval, flags)
- tree tparms;
- tree targs;
- tree arg_binfo;
- tree rval;
- tree parm;
- int flags;
+get_template_base_recursive (tree tparms,
+ tree targs,
+ tree parm,
+ tree arg_binfo,
+ tree rval,
+ int flags)
{
tree binfos;
int i, n_baselinks;
@@ -8744,7 +9473,7 @@ get_template_base_recursive (tparms, targs, parm,
/* When searching for a non-virtual, we cannot mark virtually
found binfos. */
if (! this_virtual)
- SET_BINFO_MARKED (base_binfo);
+ BINFO_MARKED (base_binfo) = 1;
rval = get_template_base_recursive (tparms, targs,
parm,
@@ -8769,11 +9498,7 @@ get_template_base_recursive (tparms, targs, parm,
as well as a plain template type. Used by unify. */
static tree
-get_template_base (tparms, targs, parm, arg)
- tree tparms;
- tree targs;
- tree parm;
- tree arg;
+get_template_base (tree tparms, tree targs, tree parm, tree arg)
{
tree rval;
tree arg_binfo;
@@ -8796,8 +9521,7 @@ get_template_base (tparms, targs, parm, arg)
/* Returns the level of DECL, which declares a template parameter. */
static int
-template_decl_level (decl)
- tree decl;
+template_decl_level (tree decl)
{
switch (TREE_CODE (decl))
{
@@ -8816,28 +9540,34 @@ template_decl_level (decl)
/* Decide whether ARG can be unified with PARM, considering only the
cv-qualifiers of each type, given STRICT as documented for unify.
- Returns nonzero iff the unification is OK on that basis.*/
+ Returns nonzero iff the unification is OK on that basis. */
static int
-check_cv_quals_for_unify (strict, arg, parm)
- int strict;
- tree arg;
- tree parm;
+check_cv_quals_for_unify (int strict, tree arg, tree parm)
{
int arg_quals = cp_type_quals (arg);
int parm_quals = cp_type_quals (parm);
- if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM)
- {
- /* If the cvr quals of parm will not unify with ARG, they'll be
- ignored in instantiation, so we have to do the same here. */
- if (TREE_CODE (arg) == REFERENCE_TYPE)
- parm_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- if (!POINTER_TYPE_P (arg) &&
- TREE_CODE (arg) != TEMPLATE_TYPE_PARM)
- parm_quals &= ~TYPE_QUAL_RESTRICT;
+ if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM
+ && !(strict & UNIFY_ALLOW_OUTER_MORE_CV_QUAL))
+ {
+ /* Although a CVR qualifier is ignored when being applied to a
+ substituted template parameter ([8.3.2]/1 for example), that
+ does not apply during deduction [14.8.2.4]/1, (even though
+ that is not explicitly mentioned, [14.8.2.4]/9 indicates
+ this). Except when we're allowing additional CV qualifiers
+ at the outer level [14.8.2.1]/3,1st bullet. */
+ if ((TREE_CODE (arg) == REFERENCE_TYPE
+ || TREE_CODE (arg) == FUNCTION_TYPE
+ || TREE_CODE (arg) == METHOD_TYPE)
+ && (parm_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)))
+ return 0;
+
+ if ((!POINTER_TYPE_P (arg) && TREE_CODE (arg) != TEMPLATE_TYPE_PARM)
+ && (parm_quals & TYPE_QUAL_RESTRICT))
+ return 0;
}
-
+
if (!(strict & (UNIFY_ALLOW_MORE_CV_QUAL | UNIFY_ALLOW_OUTER_MORE_CV_QUAL))
&& (arg_quals & parm_quals) != parm_quals)
return 0;
@@ -8889,9 +9619,7 @@ check_cv_quals_for_unify (strict, arg, parm)
folding PARM. */
static int
-unify (tparms, targs, parm, arg, strict)
- tree tparms, targs, parm, arg;
- int strict;
+unify (tree tparms, tree targs, tree parm, tree arg, int strict)
{
int idx;
tree targ;
@@ -9036,12 +9764,6 @@ unify (tparms, targs, parm, arg, strict)
}
else
{
- /* If ARG is an offset type, we're trying to unify '*T' with
- 'U C::*', which is ill-formed. See the comment in the
- POINTER_TYPE case about this ugliness. */
- if (TREE_CODE (arg) == OFFSET_TYPE)
- return 1;
-
/* If PARM is `const T' and ARG is only `int', we don't have
a match unless we are allowing additional qualification.
If ARG is `const int' and PARM is just `T' that's OK;
@@ -9084,22 +9806,14 @@ unify (tparms, targs, parm, arg, strict)
!= template_decl_level (tparm))
/* The PARM is not one we're trying to unify. Just check
to see if it matches ARG. */
- return (TREE_CODE (arg) == TREE_CODE (parm)
- && cp_tree_equal (parm, arg) > 0) ? 0 : 1;
+ return !(TREE_CODE (arg) == TREE_CODE (parm)
+ && cp_tree_equal (parm, arg));
idx = TEMPLATE_PARM_IDX (parm);
targ = TREE_VEC_ELT (targs, idx);
if (targ)
- {
- int i = (cp_tree_equal (targ, arg) > 0);
- if (i == 1)
- return 0;
- else if (i == 0)
- return 1;
- else
- abort ();
- }
+ return !cp_tree_equal (targ, arg);
/* [temp.deduct.type] If, in the declaration of a function template
with a non-type template-parameter, the non-type
@@ -9130,6 +9844,27 @@ unify (tparms, targs, parm, arg, strict)
TREE_VEC_ELT (targs, idx) = arg;
return 0;
+ case PTRMEM_CST:
+ {
+ /* A pointer-to-member constant can be unified only with
+ another constant. */
+ if (TREE_CODE (arg) != PTRMEM_CST)
+ return 1;
+
+ /* Just unify the class member. It would be useless (and possibly
+ wrong, depending on the strict flags) to unify also
+ PTRMEM_CST_CLASS, because we want to be sure that both parm and
+ arg refer to the same variable, even if through different
+ classes. For instance:
+
+ struct A { int x; };
+ struct B : A { };
+
+ Unification of &A::x and &B::x must succeed. */
+ return unify (tparms, targs, PTRMEM_CST_MEMBER (parm),
+ PTRMEM_CST_MEMBER (arg), strict);
+ }
+
case POINTER_TYPE:
{
if (TREE_CODE (arg) != POINTER_TYPE)
@@ -9150,18 +9885,6 @@ unify (tparms, targs, parm, arg, strict)
level of pointers. */
strict |= (strict_in & UNIFY_ALLOW_DERIVED);
- if (TREE_CODE (TREE_TYPE (parm)) == OFFSET_TYPE
- && TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
- {
- /* Avoid getting confused about cv-quals; don't recurse here.
- Pointers to members should really be just OFFSET_TYPE, not
- this two-level nonsense... */
-
- parm = TREE_TYPE (parm);
- arg = TREE_TYPE (arg);
- goto offset;
- }
-
return unify (tparms, targs, TREE_TYPE (parm),
TREE_TYPE (arg), strict);
}
@@ -9315,7 +10038,6 @@ unify (tparms, targs, parm, arg, strict)
DEDUCE_EXACT, 0, -1);
case OFFSET_TYPE:
- offset:
if (TREE_CODE (arg) != OFFSET_TYPE)
return 1;
if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
@@ -9325,10 +10047,13 @@ unify (tparms, targs, parm, arg, strict)
strict);
case CONST_DECL:
+ if (DECL_TEMPLATE_PARM_P (parm))
+ return unify (tparms, targs, DECL_INITIAL (parm), arg, strict);
if (arg != decl_constant_value (parm))
return 1;
return 0;
+ case FIELD_DECL:
case TEMPLATE_DECL:
/* Matched cases are handled by the ARG == PARM test above. */
return 1;
@@ -9352,7 +10077,7 @@ unify (tparms, targs, parm, arg, strict)
return unify (tparms, targs, t1, t, strict);
}
- /* else fall through */
+ /* Else fall through. */
default:
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (parm))))
@@ -9396,9 +10121,7 @@ unify (tparms, targs, parm, arg, strict)
instantiation of RESULT has been assigned to this file. */
void
-mark_decl_instantiated (result, extern_p)
- tree result;
- int extern_p;
+mark_decl_instantiated (tree result, int extern_p)
{
/* We used to set this unconditionally; we moved that to
do_decl_instantiation so it wouldn't get set on members of
@@ -9450,14 +10173,15 @@ mark_decl_instantiated (result, extern_p)
LEN is passed through to fn_type_unification. */
int
-more_specialized (pat1, pat2, deduce, len)
- tree pat1, pat2;
- int deduce;
- int len;
+more_specialized (tree pat1, tree pat2, int deduce, int len)
{
tree targs;
int winner = 0;
+ /* If template argument deduction succeeds, we substitute the
+ resulting arguments into non-deduced contexts. While doing that,
+ we must be aware that we may encounter dependent types. */
+ ++processing_template_decl;
targs = get_bindings_real (pat1, DECL_TEMPLATE_RESULT (pat2),
NULL_TREE, 0, deduce, len);
if (targs)
@@ -9467,6 +10191,7 @@ more_specialized (pat1, pat2, deduce, len)
NULL_TREE, 0, deduce, len);
if (targs)
++winner;
+ --processing_template_decl;
return winner;
}
@@ -9481,12 +10206,16 @@ more_specialized (pat1, pat2, deduce, len)
partial ordering. */
int
-more_specialized_class (pat1, pat2, full_args)
- tree pat1, pat2, full_args;
+more_specialized_class (tree pat1, tree pat2, tree full_args)
{
tree targs;
int winner = 0;
+ /* Just like what happens for functions, if we are ordering between
+ different class template specializations, we may encounter dependent
+ types in the arguments, and we need our dependency check functions
+ to behave correctly. */
+ ++processing_template_decl;
targs = get_class_bindings (TREE_VALUE (pat1), TREE_PURPOSE (pat1),
add_outermost_template_args (full_args, TREE_PURPOSE (pat2)));
if (targs)
@@ -9496,6 +10225,7 @@ more_specialized_class (pat1, pat2, full_args)
add_outermost_template_args (full_args, TREE_PURPOSE (pat1)));
if (targs)
++winner;
+ --processing_template_decl;
return winner;
}
@@ -9507,9 +10237,12 @@ more_specialized_class (pat1, pat2, full_args)
found. DEDUCE and LEN are passed through to fn_type_unification. */
static tree
-get_bindings_real (fn, decl, explicit_args, check_rettype, deduce, len)
- tree fn, decl, explicit_args;
- int check_rettype, deduce, len;
+get_bindings_real (tree fn,
+ tree decl,
+ tree explicit_args,
+ int check_rettype,
+ int deduce,
+ int len)
{
int ntparms = DECL_NTPARMS (fn);
tree targs = make_tree_vec (ntparms);
@@ -9563,9 +10296,8 @@ get_bindings_real (fn, decl, explicit_args, check_rettype, deduce, len)
/* For most uses, we want to check the return type. */
-tree
-get_bindings (fn, decl, explicit_args)
- tree fn, decl, explicit_args;
+static tree
+get_bindings (tree fn, tree decl, tree explicit_args)
{
return get_bindings_real (fn, decl, explicit_args, 1, DEDUCE_EXACT, -1);
}
@@ -9574,8 +10306,7 @@ get_bindings (fn, decl, explicit_args)
types. */
static tree
-get_bindings_overload (fn, decl, explicit_args)
- tree fn, decl, explicit_args;
+get_bindings_overload (tree fn, tree decl, tree explicit_args)
{
return get_bindings_real (fn, decl, explicit_args, 0, DEDUCE_EXACT, -1);
}
@@ -9596,8 +10327,7 @@ get_bindings_overload (fn, decl, explicit_args)
is bound to `double'. */
static tree
-get_class_bindings (tparms, parms, args)
- tree tparms, parms, args;
+get_class_bindings (tree tparms, tree parms, tree args)
{
int i, ntparms = TREE_VEC_LENGTH (tparms);
tree vec = make_tree_vec (ntparms);
@@ -9624,8 +10354,7 @@ get_class_bindings (tparms, parms, args)
NULL_TREE is returned. */
tree
-most_specialized_instantiation (instantiations)
- tree instantiations;
+most_specialized_instantiation (tree instantiations)
{
tree fn, champ;
int fate;
@@ -9668,8 +10397,7 @@ most_specialized_instantiation (instantiations)
arguments EXPLICIT_ARGS. */
static tree
-most_specialized (fns, decl, explicit_args)
- tree fns, decl, explicit_args;
+most_specialized (tree fns, tree decl, tree explicit_args)
{
tree candidates = NULL_TREE;
tree fn, args;
@@ -9703,8 +10431,7 @@ most_specialized (fns, decl, explicit_args)
`template <class T> template <class U> S<T*>::f(U)'. */
tree
-most_general_template (decl)
- tree decl;
+most_general_template (tree decl)
{
/* If DECL is a FUNCTION_DECL, find the TEMPLATE_DECL of which it is
an immediate specialization. */
@@ -9724,8 +10451,8 @@ most_general_template (decl)
/* Look for more and more general templates. */
while (DECL_TEMPLATE_INFO (decl))
{
- /* The DECL_TI_TEMPLATE can be a LOOKUP_EXPR or IDENTIFIER_NODE
- in some cases. (See cp-tree.h for details.) */
+ /* The DECL_TI_TEMPLATE can be an IDENTIFIER_NODE in some cases.
+ (See cp-tree.h for details.) */
if (TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL)
break;
@@ -9750,9 +10477,7 @@ most_general_template (decl)
error_mark_node if the choice is ambiguous. */
static tree
-most_specialized_class (tmpl, args)
- tree tmpl;
- tree args;
+most_specialized_class (tree tmpl, tree args)
{
tree list = NULL_TREE;
tree t;
@@ -9831,10 +10556,10 @@ do_decl_instantiation (tree decl, tree storage)
VAR_DECLs so we do the lookup here. Probably, grokdeclarator
should handle VAR_DECLs as it currently handles
FUNCTION_DECLs. */
- result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, 0);
- if (result && TREE_CODE (result) != VAR_DECL)
+ result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, false);
+ if (!result || TREE_CODE (result) != VAR_DECL)
{
- error ("no matching template for `%D' found", result);
+ error ("no matching template for `%D' found", decl);
return;
}
}
@@ -9894,9 +10619,6 @@ do_decl_instantiation (tree decl, tree storage)
return;
}
- if (flag_external_templates)
- return;
-
if (storage == NULL_TREE)
;
else if (storage == ridpointers[(int) RID_EXTERN])
@@ -9917,9 +10639,7 @@ do_decl_instantiation (tree decl, tree storage)
}
void
-mark_class_instantiated (t, extern_p)
- tree t;
- int extern_p;
+mark_class_instantiated (tree t, int extern_p)
{
SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t);
SET_CLASSTYPE_INTERFACE_KNOWN (t);
@@ -9933,7 +10653,7 @@ mark_class_instantiated (t, extern_p)
}
/* Called from do_type_instantiation through binding_table_foreach to
- do recursive instantiation for the type bound in ENTRY. */
+ do recursive instantiation for the type bound in ENTRY. */
static void
bt_instantiate_type_proc (binding_entry entry, void *data)
{
@@ -9950,9 +10670,7 @@ bt_instantiate_type_proc (binding_entry entry, void *data)
since the standard is unclear (as detailed below). */
void
-do_type_instantiation (t, storage, complain)
- tree t, storage;
- tsubst_flags_t complain;
+do_type_instantiation (tree t, tree storage, tsubst_flags_t complain)
{
int extern_p = 0;
int nomem_p = 0;
@@ -9969,11 +10687,6 @@ do_type_instantiation (t, storage, complain)
complete_type (t);
- /* With -fexternal-templates, explicit instantiations are treated the same
- as implicit ones. */
- if (flag_external_templates)
- return;
-
if (!COMPLETE_TYPE_P (t))
{
if (complain & tf_error)
@@ -10084,8 +10797,8 @@ do_type_instantiation (t, storage, complain)
instantiate_decl (tmp, /*defer_ok=*/1);
}
- if (CLASSTYPE_NESTED_UDTS (t))
- binding_table_foreach (CLASSTYPE_NESTED_UDTS (t),
+ if (CLASSTYPE_NESTED_UTDS (t))
+ binding_table_foreach (CLASSTYPE_NESTED_UTDS (t),
bt_instantiate_type_proc, &storage);
}
}
@@ -10111,9 +10824,7 @@ do_type_instantiation (t, storage, complain)
to instantiate the DECL, we regenerate it. */
static void
-regenerate_decl_from_template (decl, tmpl)
- tree decl;
- tree tmpl;
+regenerate_decl_from_template (tree decl, tree tmpl)
{
/* The most general version of TMPL. */
tree gen_tmpl;
@@ -10122,7 +10833,7 @@ regenerate_decl_from_template (decl, tmpl)
tree args;
tree code_pattern;
tree new_decl;
- int unregistered;
+ bool unregistered;
args = DECL_TI_ARGS (decl);
code_pattern = DECL_TEMPLATE_RESULT (tmpl);
@@ -10133,14 +10844,17 @@ regenerate_decl_from_template (decl, tmpl)
instantiation of a specialization, which it isn't: it's a full
instantiation. */
gen_tmpl = most_general_template (tmpl);
- push_access_scope_real (gen_tmpl, args, DECL_CONTEXT (decl));
- unregistered = reregister_specialization (decl, gen_tmpl, NULL_TREE);
+ unregistered = reregister_specialization (decl, gen_tmpl,
+ /*new_spec=*/NULL_TREE);
/* If the DECL was not unregistered then something peculiar is
happening: we created a specialization but did not call
register_specialization for it. */
my_friendly_assert (unregistered, 0);
+ /* Make sure that we can see identifiers, and compute access
+ correctly. */
+ push_access_scope (decl);
/* Do the substitution to get the new declaration. */
new_decl = tsubst (code_pattern, args, tf_error, NULL_TREE);
@@ -10183,14 +10897,71 @@ regenerate_decl_from_template (decl, tmpl)
register_specialization (decl, gen_tmpl, args);
}
+/* Return the TEMPLATE_DECL into which DECL_TI_ARGS(DECL) should be
+ substituted to get DECL. */
+
+tree
+template_for_substitution (tree decl)
+{
+ tree tmpl = DECL_TI_TEMPLATE (decl);
+
+ /* Set TMPL to the template whose DECL_TEMPLATE_RESULT is the pattern
+ for the instantiation. This is not always the most general
+ template. Consider, for example:
+
+ template <class T>
+ struct S { template <class U> void f();
+ template <> void f<int>(); };
+
+ and an instantiation of S<double>::f<int>. We want TD to be the
+ specialization S<T>::f<int>, not the more general S<T>::f<U>. */
+ while (/* An instantiation cannot have a definition, so we need a
+ more general template. */
+ DECL_TEMPLATE_INSTANTIATION (tmpl)
+ /* We must also deal with friend templates. Given:
+
+ template <class T> struct S {
+ template <class U> friend void f() {};
+ };
+
+ S<int>::f<U> say, is not an instantiation of S<T>::f<U>,
+ so far as the language is concerned, but that's still
+ where we get the pattern for the instantiation from. On
+ other hand, if the definition comes outside the class, say:
+
+ template <class T> struct S {
+ template <class U> friend void f();
+ };
+ template <class U> friend void f() {}
+
+ we don't need to look any further. That's what the check for
+ DECL_INITIAL is for. */
+ || (TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (tmpl)
+ && !DECL_INITIAL (DECL_TEMPLATE_RESULT (tmpl))))
+ {
+ /* The present template, TD, should not be a definition. If it
+ were a definition, we should be using it! Note that we
+ cannot restructure the loop to just keep going until we find
+ a template with a definition, since that might go too far if
+ a specialization was declared, but not defined. */
+ my_friendly_assert (!(TREE_CODE (decl) == VAR_DECL
+ && !DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (tmpl))),
+ 0);
+
+ /* Fetch the more general template. */
+ tmpl = DECL_TI_TEMPLATE (tmpl);
+ }
+
+ return tmpl;
+}
+
/* Produce the definition of D, a _DECL generated from a template. If
DEFER_OK is nonzero, then we don't have to actually do the
instantiation now; we just have to do it sometime. */
tree
-instantiate_decl (d, defer_ok)
- tree d;
- int defer_ok;
+instantiate_decl (tree d, int defer_ok)
{
tree tmpl = DECL_TI_TEMPLATE (d);
tree gen_args;
@@ -10200,15 +10971,19 @@ instantiate_decl (d, defer_ok)
tree spec;
tree gen_tmpl;
int pattern_defined;
- int line = lineno;
int need_push;
- const char *file = input_filename;
-
+ location_t saved_loc = input_location;
+
/* This function should only be used to instantiate templates for
functions and static member variables. */
my_friendly_assert (TREE_CODE (d) == FUNCTION_DECL
|| TREE_CODE (d) == VAR_DECL, 0);
+ /* Variables are never deferred; if instantiation is required, they
+ are instantiated right away. That allows for better code in the
+ case that an expression refers to the value of the variable --
+ if the variable has a constant value the referring expression can
+ take advantage of that fact. */
if (TREE_CODE (d) == VAR_DECL)
defer_ok = 0;
@@ -10242,55 +11017,12 @@ instantiate_decl (d, defer_ok)
timevar_push (TV_PARSE);
- /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern
- for the instantiation. This is not always the most general
- template. Consider, for example:
-
- template <class T>
- struct S { template <class U> void f();
- template <> void f<int>(); };
-
- and an instantiation of S<double>::f<int>. We want TD to be the
- specialization S<T>::f<int>, not the more general S<T>::f<U>. */
- td = tmpl;
- while (/* An instantiation cannot have a definition, so we need a
- more general template. */
- DECL_TEMPLATE_INSTANTIATION (td)
- /* We must also deal with friend templates. Given:
-
- template <class T> struct S {
- template <class U> friend void f() {};
- };
-
- S<int>::f<U> say, is not an instantiation of S<T>::f<U>,
- so far as the language is concerned, but that's still
- where we get the pattern for the instantiation from. On
- other hand, if the definition comes outside the class, say:
-
- template <class T> struct S {
- template <class U> friend void f();
- };
- template <class U> friend void f() {}
-
- we don't need to look any further. That's what the check for
- DECL_INITIAL is for. */
- || (TREE_CODE (d) == FUNCTION_DECL
- && DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (td)
- && !DECL_INITIAL (DECL_TEMPLATE_RESULT (td))))
- {
- /* The present template, TD, should not be a definition. If it
- were a definition, we should be using it! Note that we
- cannot restructure the loop to just keep going until we find
- a template with a definition, since that might go too far if
- a specialization was declared, but not defined. */
- my_friendly_assert (!(TREE_CODE (d) == VAR_DECL
- && !DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (td))),
- 0);
-
- /* Fetch the more general template. */
- td = DECL_TI_TEMPLATE (td);
- }
+ /* We may be in the middle of deferred access check. Disable it now. */
+ push_deferring_access_checks (dk_no_deferred);
+ /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern
+ for the instantiation. */
+ td = template_for_substitution (d);
code_pattern = DECL_TEMPLATE_RESULT (td);
if ((DECL_NAMESPACE_SCOPE_P (d) && !DECL_INITIALIZED_IN_CLASS_P (d))
@@ -10308,8 +11040,7 @@ instantiate_decl (d, defer_ok)
else
pattern_defined = ! DECL_IN_AGGR_P (code_pattern);
- lineno = DECL_SOURCE_LINE (d);
- input_filename = DECL_SOURCE_FILE (d);
+ input_location = DECL_SOURCE_LOCATION (d);
if (pattern_defined)
{
@@ -10333,22 +11064,6 @@ instantiate_decl (d, defer_ok)
else
repo_template_used (d);
- if (flag_external_templates && ! DECL_INTERFACE_KNOWN (d))
- {
- if (flag_alt_external_templates)
- {
- if (interface_unknown)
- warn_if_unknown_interface (d);
- }
- else if (DECL_INTERFACE_KNOWN (code_pattern))
- {
- DECL_INTERFACE_KNOWN (d) = 1;
- DECL_NOT_REALLY_EXTERN (d) = ! DECL_EXTERNAL (code_pattern);
- }
- else
- warn_if_unknown_interface (code_pattern);
- }
-
if (at_eof)
import_export_decl (d);
}
@@ -10396,8 +11111,7 @@ instantiate_decl (d, defer_ok)
because it's used by add_pending_template. */
else if (! pattern_defined || defer_ok)
{
- lineno = line;
- input_filename = file;
+ input_location = saved_loc;
if (at_eof && !pattern_defined
&& DECL_EXPLICIT_INSTANTIATION (d))
@@ -10419,14 +11133,18 @@ instantiate_decl (d, defer_ok)
if (need_push)
push_to_top_level ();
+ /* Mark D as instantiated so that recursive calls to
+ instantiate_decl do not try to instantiate it again. */
+ DECL_TEMPLATE_INSTANTIATED (d) = 1;
+
/* Regenerate the declaration in case the template has been modified
by a subsequent redeclaration. */
regenerate_decl_from_template (d, td);
/* We already set the file and line above. Reset them now in case
- they changed as a result of calling regenerate_decl_from_template. */
- lineno = DECL_SOURCE_LINE (d);
- input_filename = DECL_SOURCE_FILE (d);
+ they changed as a result of calling
+ regenerate_decl_from_template. */
+ input_location = DECL_SOURCE_LOCATION (d);
if (TREE_CODE (d) == VAR_DECL)
{
@@ -10445,7 +11163,7 @@ instantiate_decl (d, defer_ok)
(1) D is a template static data member, for which a
definition is available.
- (2) An implicit or explicit instantiation has occured.
+ (2) An implicit or explicit instantiation has occurred.
(3) We are not going to emit a definition of the static
data member at this time.
@@ -10455,22 +11173,38 @@ instantiate_decl (d, defer_ok)
instantiation. There, we cannot implicitly instantiate a
defined static data member in more than one translation
unit, so import_export_decl marks the declaration as
- external; we must rely on explicit instantiation. */
+ external; we must rely on explicit instantiation.
+
+ Reset instantiated marker to make sure that later
+ explicit instantiation will be processed. */
+ DECL_TEMPLATE_INSTANTIATED (d) = 0;
}
else
{
- /* Mark D as instantiated so that recursive calls to
- instantiate_decl do not try to instantiate it again. */
- DECL_TEMPLATE_INSTANTIATED (d) = 1;
+ /* This is done in analogous to `start_decl'. It is
+ required for correct access checking. */
+ push_nested_class (DECL_CONTEXT (d));
cp_finish_decl (d,
(!DECL_INITIALIZED_IN_CLASS_P (d)
? DECL_INITIAL (d) : NULL_TREE),
NULL_TREE, 0);
+ /* Normally, pop_nested_class is called by cp_finish_decl
+ above. But when instantiate_decl is triggered during
+ instantiate_class_template processing, its DECL_CONTEXT
+ is still not completed yet, and pop_nested_class isn't
+ called. */
+ if (!COMPLETE_TYPE_P (DECL_CONTEXT (d)))
+ pop_nested_class ();
}
+ /* We're not deferring instantiation any more. */
+ TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0;
}
else if (TREE_CODE (d) == FUNCTION_DECL)
{
htab_t saved_local_specializations;
+ tree subst_decl;
+ tree tmpl_parm;
+ tree spec_parm;
/* Mark D as instantiated so that recursive calls to
instantiate_decl do not try to instantiate it again. */
@@ -10482,14 +11216,32 @@ instantiate_decl (d, defer_ok)
/* Set up the list of local specializations. */
local_specializations = htab_create (37,
- htab_hash_pointer,
- htab_eq_pointer,
+ hash_local_specialization,
+ eq_local_specializations,
NULL);
/* Set up context. */
import_export_decl (d);
start_function (NULL_TREE, d, NULL_TREE, SF_PRE_PARSED);
+ /* Create substitution entries for the parameters. */
+ subst_decl = DECL_TEMPLATE_RESULT (template_for_substitution (d));
+ tmpl_parm = DECL_ARGUMENTS (subst_decl);
+ spec_parm = DECL_ARGUMENTS (d);
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (d))
+ {
+ register_local_specialization (spec_parm, tmpl_parm);
+ spec_parm = skip_artificial_parms_for (d, spec_parm);
+ tmpl_parm = skip_artificial_parms_for (subst_decl, tmpl_parm);
+ }
+ while (tmpl_parm)
+ {
+ register_local_specialization (spec_parm, tmpl_parm);
+ tmpl_parm = TREE_CHAIN (tmpl_parm);
+ spec_parm = TREE_CHAIN (spec_parm);
+ }
+ my_friendly_assert (!spec_parm, 20020813);
+
/* Substitute into the body of the function. */
tsubst_expr (DECL_SAVED_TREE (code_pattern), args,
tf_error | tf_warning, tmpl);
@@ -10498,21 +11250,20 @@ instantiate_decl (d, defer_ok)
htab_delete (local_specializations);
local_specializations = saved_local_specializations;
+ /* We're not deferring instantiation any more. */
+ TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0;
+
/* Finish the function. */
d = finish_function (0);
- expand_body (d);
+ expand_or_defer_fn (d);
}
- /* We're not deferring instantiation any more. */
- TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0;
-
if (need_push)
pop_from_top_level ();
out:
- lineno = line;
- input_filename = file;
-
+ input_location = saved_loc;
+ pop_deferring_access_checks ();
pop_tinst_level ();
timevar_pop (TV_PARSE);
@@ -10524,12 +11275,13 @@ out:
instantiate, and instantiate any we can. */
int
-instantiate_pending_templates ()
+instantiate_pending_templates (void)
{
tree *t;
tree last = NULL_TREE;
int instantiated_something = 0;
int reconsider;
+ location_t saved_loc = input_location;
do
{
@@ -10604,6 +11356,7 @@ instantiate_pending_templates ()
}
while (reconsider);
+ input_location = saved_loc;
return instantiated_something;
}
@@ -10613,8 +11366,7 @@ instantiate_pending_templates ()
instantiate_decl. */
static tree
-tsubst_initializer_list (t, argvec)
- tree t, argvec;
+tsubst_initializer_list (tree t, tree argvec)
{
tree inits = NULL_TREE;
@@ -10655,8 +11407,7 @@ tsubst_initializer_list (t, argvec)
/* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL. */
static void
-set_current_access_from_decl (decl)
- tree decl;
+set_current_access_from_decl (tree decl)
{
if (TREE_PRIVATE (decl))
current_access_specifier = access_private_node;
@@ -10671,28 +11422,27 @@ set_current_access_from_decl (decl)
start_enum) and ARGS are the template arguments to use. */
static void
-tsubst_enum (tag, newtag, args)
- tree tag;
- tree newtag;
- tree args;
+tsubst_enum (tree tag, tree newtag, tree args)
{
tree e;
for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e))
{
tree value;
-
+ tree decl;
+
+ decl = TREE_VALUE (e);
/* Note that in a template enum, the TREE_VALUE is the
CONST_DECL, not the corresponding INTEGER_CST. */
- value = tsubst_expr (DECL_INITIAL (TREE_VALUE (e)),
+ value = tsubst_expr (DECL_INITIAL (decl),
args, tf_error | tf_warning,
NULL_TREE);
/* Give this enumeration constant the correct access. */
- set_current_access_from_decl (TREE_VALUE (e));
+ set_current_access_from_decl (decl);
/* Actually build the enumerator itself. */
- build_enumerator (TREE_PURPOSE (e), value, newtag);
+ build_enumerator (DECL_NAME (decl), value, newtag);
}
finish_enum (newtag);
@@ -10706,8 +11456,7 @@ tsubst_enum (tag, newtag, args)
the type. */
tree
-get_mostly_instantiated_function_type (decl)
- tree decl;
+get_mostly_instantiated_function_type (tree decl)
{
tree fn_type;
tree tmpl;
@@ -10751,9 +11500,11 @@ get_mostly_instantiated_function_type (decl)
specialized or not. */
push_access_scope (decl);
+ ++processing_template_decl;
/* Now, do the (partial) substitution to figure out the
appropriate function type. */
fn_type = tsubst (fn_type, partial_args, tf_error, NULL_TREE);
+ --processing_template_decl;
/* Substitute into the template parameters to obtain the real
innermost set of parameters. This step is important if the
@@ -10771,20 +11522,20 @@ get_mostly_instantiated_function_type (decl)
/* Return truthvalue if we're processing a template different from
the last one involved in diagnostics. */
int
-problematic_instantiation_changed ()
+problematic_instantiation_changed (void)
{
return last_template_error_tick != tinst_level_tick;
}
/* Remember current template involved in diagnostics. */
void
-record_last_problematic_instantiation ()
+record_last_problematic_instantiation (void)
{
last_template_error_tick = tinst_level_tick;
}
tree
-current_instantiation ()
+current_instantiation (void)
{
return current_tinst_level;
}
@@ -10794,17 +11545,13 @@ current_instantiation ()
warning messages under control of COMPLAIN. */
static int
-invalid_nontype_parm_type_p (type, complain)
- tree type;
- tsubst_flags_t complain;
+invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain)
{
if (INTEGRAL_TYPE_P (type))
return 0;
else if (POINTER_TYPE_P (type))
return 0;
- else if (TYPE_PTRMEM_P (type))
- return 0;
- else if (TYPE_PTRMEMFUNC_P (type))
+ else if (TYPE_PTR_TO_MEMBER_P (type))
return 0;
else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
return 0;
@@ -10817,4 +11564,657 @@ invalid_nontype_parm_type_p (type, complain)
return 1;
}
+/* Returns TRUE if TYPE is dependent, in the sense of [temp.dep.type].
+ Assumes that TYPE really is a type, and not the ERROR_MARK_NODE.*/
+
+static bool
+dependent_type_p_r (tree type)
+{
+ tree scope;
+
+ /* [temp.dep.type]
+
+ A type is dependent if it is:
+
+ -- a template parameter. Template template parameters are
+ types for us (since TYPE_P holds true for them) so we
+ handle them here. */
+ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
+ || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
+ return true;
+ /* -- a qualified-id with a nested-name-specifier which contains a
+ class-name that names a dependent type or whose unqualified-id
+ names a dependent type. */
+ if (TREE_CODE (type) == TYPENAME_TYPE)
+ return true;
+ /* -- a cv-qualified type where the cv-unqualified type is
+ dependent. */
+ type = TYPE_MAIN_VARIANT (type);
+ /* -- a compound type constructed from any dependent type. */
+ if (TYPE_PTR_TO_MEMBER_P (type))
+ return (dependent_type_p (TYPE_PTRMEM_CLASS_TYPE (type))
+ || dependent_type_p (TYPE_PTRMEM_POINTED_TO_TYPE
+ (type)));
+ else if (TREE_CODE (type) == POINTER_TYPE
+ || TREE_CODE (type) == REFERENCE_TYPE)
+ return dependent_type_p (TREE_TYPE (type));
+ else if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)
+ {
+ tree arg_type;
+
+ if (dependent_type_p (TREE_TYPE (type)))
+ return true;
+ for (arg_type = TYPE_ARG_TYPES (type);
+ arg_type;
+ arg_type = TREE_CHAIN (arg_type))
+ if (dependent_type_p (TREE_VALUE (arg_type)))
+ return true;
+ return false;
+ }
+ /* -- an array type constructed from any dependent type or whose
+ size is specified by a constant expression that is
+ value-dependent. */
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ if (TYPE_DOMAIN (type)
+ && ((value_dependent_expression_p
+ (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
+ || (type_dependent_expression_p
+ (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))))
+ return true;
+ return dependent_type_p (TREE_TYPE (type));
+ }
+
+ /* -- a template-id in which either the template name is a template
+ parameter ... */
+ if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ return true;
+ /* ... or any of the template arguments is a dependent type or
+ an expression that is type-dependent or value-dependent. */
+ else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type)
+ && (any_dependent_template_arguments_p
+ (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type)))))
+ return true;
+
+ /* All TYPEOF_TYPEs are dependent; if the argument of the `typeof'
+ expression is not type-dependent, then it should already been
+ have resolved. */
+ if (TREE_CODE (type) == TYPEOF_TYPE)
+ return true;
+
+ /* The standard does not specifically mention types that are local
+ to template functions or local classes, but they should be
+ considered dependent too. For example:
+
+ template <int I> void f() {
+ enum E { a = I };
+ S<sizeof (E)> s;
+ }
+
+ The size of `E' cannot be known until the value of `I' has been
+ determined. Therefore, `E' must be considered dependent. */
+ scope = TYPE_CONTEXT (type);
+ if (scope && TYPE_P (scope))
+ return dependent_type_p (scope);
+ else if (scope && TREE_CODE (scope) == FUNCTION_DECL)
+ return type_dependent_expression_p (scope);
+
+ /* Other types are non-dependent. */
+ return false;
+}
+
+/* Returns TRUE if TYPE is dependent, in the sense of
+ [temp.dep.type]. */
+
+bool
+dependent_type_p (tree type)
+{
+ /* If there are no template parameters in scope, then there can't be
+ any dependent types. */
+ if (!processing_template_decl)
+ return false;
+
+ /* If the type is NULL, we have not computed a type for the entity
+ in question; in that case, the type is dependent. */
+ if (!type)
+ return true;
+
+ /* Erroneous types can be considered non-dependent. */
+ if (type == error_mark_node)
+ return false;
+
+ /* If we have not already computed the appropriate value for TYPE,
+ do so now. */
+ if (!TYPE_DEPENDENT_P_VALID (type))
+ {
+ TYPE_DEPENDENT_P (type) = dependent_type_p_r (type);
+ TYPE_DEPENDENT_P_VALID (type) = 1;
+ }
+
+ return TYPE_DEPENDENT_P (type);
+}
+
+/* Returns TRUE if EXPRESSION is dependent, according to CRITERION. */
+
+static bool
+dependent_scope_ref_p (tree expression, bool criterion (tree))
+{
+ tree scope;
+ tree name;
+
+ my_friendly_assert (TREE_CODE (expression) == SCOPE_REF, 20030714);
+
+ if (!TYPE_P (TREE_OPERAND (expression, 0)))
+ return true;
+
+ scope = TREE_OPERAND (expression, 0);
+ name = TREE_OPERAND (expression, 1);
+
+ /* [temp.dep.expr]
+
+ An id-expression is type-dependent if it contains a
+ nested-name-specifier that contains a class-name that names a
+ dependent type. */
+ /* The suggested resolution to Core Issue 2 implies that if the
+ qualifying type is the current class, then we must peek
+ inside it. */
+ if (DECL_P (name)
+ && currently_open_class (scope)
+ && !criterion (name))
+ return false;
+ if (dependent_type_p (scope))
+ return true;
+
+ return false;
+}
+
+/* Returns TRUE if the EXPRESSION is value-dependent, in the sense of
+ [temp.dep.constexpr] */
+
+bool
+value_dependent_expression_p (tree expression)
+{
+ if (!processing_template_decl)
+ return false;
+
+ /* A name declared with a dependent type. */
+ if (TREE_CODE (expression) == IDENTIFIER_NODE
+ || (DECL_P (expression)
+ && type_dependent_expression_p (expression)))
+ return true;
+ /* A non-type template parameter. */
+ if ((TREE_CODE (expression) == CONST_DECL
+ && DECL_TEMPLATE_PARM_P (expression))
+ || TREE_CODE (expression) == TEMPLATE_PARM_INDEX)
+ return true;
+ /* A constant with integral or enumeration type and is initialized
+ with an expression that is value-dependent. */
+ if (TREE_CODE (expression) == VAR_DECL
+ && DECL_INITIAL (expression)
+ && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (expression))
+ && value_dependent_expression_p (DECL_INITIAL (expression)))
+ return true;
+ /* These expressions are value-dependent if the type to which the
+ cast occurs is dependent or the expression being casted is
+ value-dependent. */
+ if (TREE_CODE (expression) == DYNAMIC_CAST_EXPR
+ || TREE_CODE (expression) == STATIC_CAST_EXPR
+ || TREE_CODE (expression) == CONST_CAST_EXPR
+ || TREE_CODE (expression) == REINTERPRET_CAST_EXPR
+ || TREE_CODE (expression) == CAST_EXPR)
+ {
+ tree type = TREE_TYPE (expression);
+ if (dependent_type_p (type))
+ return true;
+ /* A functional cast has a list of operands. */
+ expression = TREE_OPERAND (expression, 0);
+ if (!expression)
+ {
+ /* If there are no operands, it must be an expression such
+ as "int()". This should not happen for aggregate types
+ because it would form non-constant expressions. */
+ my_friendly_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type),
+ 20040318);
+
+ return false;
+ }
+ if (TREE_CODE (expression) == TREE_LIST)
+ {
+ do
+ {
+ if (value_dependent_expression_p (TREE_VALUE (expression)))
+ return true;
+ expression = TREE_CHAIN (expression);
+ }
+ while (expression);
+ return false;
+ }
+ else
+ return value_dependent_expression_p (expression);
+ }
+ /* A `sizeof' expression is value-dependent if the operand is
+ type-dependent. */
+ if (TREE_CODE (expression) == SIZEOF_EXPR
+ || TREE_CODE (expression) == ALIGNOF_EXPR)
+ {
+ expression = TREE_OPERAND (expression, 0);
+ if (TYPE_P (expression))
+ return dependent_type_p (expression);
+ return type_dependent_expression_p (expression);
+ }
+ if (TREE_CODE (expression) == SCOPE_REF)
+ return dependent_scope_ref_p (expression, value_dependent_expression_p);
+ if (TREE_CODE (expression) == COMPONENT_REF)
+ return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
+ || value_dependent_expression_p (TREE_OPERAND (expression, 1)));
+ /* A constant expression is value-dependent if any subexpression is
+ value-dependent. */
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression))))
+ {
+ switch (TREE_CODE_CLASS (TREE_CODE (expression)))
+ {
+ case '1':
+ return (value_dependent_expression_p
+ (TREE_OPERAND (expression, 0)));
+ case '<':
+ case '2':
+ return ((value_dependent_expression_p
+ (TREE_OPERAND (expression, 0)))
+ || (value_dependent_expression_p
+ (TREE_OPERAND (expression, 1))));
+ case 'e':
+ {
+ int i;
+ for (i = 0; i < first_rtl_op (TREE_CODE (expression)); ++i)
+ /* In some cases, some of the operands may be missing.
+ (For example, in the case of PREDECREMENT_EXPR, the
+ amount to increment by may be missing.) That doesn't
+ make the expression dependent. */
+ if (TREE_OPERAND (expression, i)
+ && (value_dependent_expression_p
+ (TREE_OPERAND (expression, i))))
+ return true;
+ return false;
+ }
+ }
+ }
+
+ /* The expression is not value-dependent. */
+ return false;
+}
+
+/* Returns TRUE if the EXPRESSION is type-dependent, in the sense of
+ [temp.dep.expr]. */
+
+bool
+type_dependent_expression_p (tree expression)
+{
+ if (!processing_template_decl)
+ return false;
+
+ if (expression == error_mark_node)
+ return false;
+
+ /* An unresolved name is always dependent. */
+ if (TREE_CODE (expression) == IDENTIFIER_NODE)
+ return true;
+
+ /* Some expression forms are never type-dependent. */
+ if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR
+ || TREE_CODE (expression) == SIZEOF_EXPR
+ || TREE_CODE (expression) == ALIGNOF_EXPR
+ || TREE_CODE (expression) == TYPEID_EXPR
+ || TREE_CODE (expression) == DELETE_EXPR
+ || TREE_CODE (expression) == VEC_DELETE_EXPR
+ || TREE_CODE (expression) == THROW_EXPR)
+ return false;
+
+ /* The types of these expressions depends only on the type to which
+ the cast occurs. */
+ if (TREE_CODE (expression) == DYNAMIC_CAST_EXPR
+ || TREE_CODE (expression) == STATIC_CAST_EXPR
+ || TREE_CODE (expression) == CONST_CAST_EXPR
+ || TREE_CODE (expression) == REINTERPRET_CAST_EXPR
+ || TREE_CODE (expression) == CAST_EXPR)
+ return dependent_type_p (TREE_TYPE (expression));
+
+ /* The types of these expressions depends only on the type created
+ by the expression. */
+ if (TREE_CODE (expression) == NEW_EXPR
+ || TREE_CODE (expression) == VEC_NEW_EXPR)
+ {
+ /* For NEW_EXPR tree nodes created inside a template, either
+ the object type itself or a TREE_LIST may appear as the
+ operand 1. */
+ tree type = TREE_OPERAND (expression, 1);
+ if (TREE_CODE (type) == TREE_LIST)
+ /* This is an array type. We need to check array dimensions
+ as well. */
+ return dependent_type_p (TREE_VALUE (TREE_PURPOSE (type)))
+ || value_dependent_expression_p
+ (TREE_OPERAND (TREE_VALUE (type), 1));
+ else
+ return dependent_type_p (type);
+ }
+
+ if (TREE_CODE (expression) == SCOPE_REF
+ && dependent_scope_ref_p (expression,
+ type_dependent_expression_p))
+ return true;
+
+ if (TREE_CODE (expression) == FUNCTION_DECL
+ && DECL_LANG_SPECIFIC (expression)
+ && DECL_TEMPLATE_INFO (expression)
+ && (any_dependent_template_arguments_p
+ (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
+ return true;
+
+ if (TREE_CODE (expression) == TEMPLATE_DECL
+ && !DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
+ return false;
+
+ if (TREE_TYPE (expression) == unknown_type_node)
+ {
+ if (TREE_CODE (expression) == ADDR_EXPR)
+ return type_dependent_expression_p (TREE_OPERAND (expression, 0));
+ if (TREE_CODE (expression) == COMPONENT_REF
+ || TREE_CODE (expression) == OFFSET_REF)
+ {
+ if (type_dependent_expression_p (TREE_OPERAND (expression, 0)))
+ return true;
+ expression = TREE_OPERAND (expression, 1);
+ if (TREE_CODE (expression) == IDENTIFIER_NODE)
+ return false;
+ }
+
+ if (TREE_CODE (expression) == BASELINK)
+ expression = BASELINK_FUNCTIONS (expression);
+ if (TREE_CODE (expression) == TEMPLATE_ID_EXPR)
+ {
+ if (any_dependent_template_arguments_p
+ (TREE_OPERAND (expression, 1)))
+ return true;
+ expression = TREE_OPERAND (expression, 0);
+ }
+ if (TREE_CODE (expression) == OVERLOAD)
+ {
+ while (expression)
+ {
+ if (type_dependent_expression_p (OVL_CURRENT (expression)))
+ return true;
+ expression = OVL_NEXT (expression);
+ }
+ return false;
+ }
+ abort ();
+ }
+
+ return (dependent_type_p (TREE_TYPE (expression)));
+}
+
+/* Returns TRUE if ARGS (a TREE_LIST of arguments to a function call)
+ contains a type-dependent expression. */
+
+bool
+any_type_dependent_arguments_p (tree args)
+{
+ while (args)
+ {
+ tree arg = TREE_VALUE (args);
+
+ if (type_dependent_expression_p (arg))
+ return true;
+ args = TREE_CHAIN (args);
+ }
+ return false;
+}
+
+/* Returns TRUE if the ARG (a template argument) is dependent. */
+
+static bool
+dependent_template_arg_p (tree arg)
+{
+ if (!processing_template_decl)
+ return false;
+
+ if (TREE_CODE (arg) == TEMPLATE_DECL
+ || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+ return dependent_template_p (arg);
+ else if (TYPE_P (arg))
+ return dependent_type_p (arg);
+ else
+ return (type_dependent_expression_p (arg)
+ || value_dependent_expression_p (arg));
+}
+
+/* Returns true if ARGS (a collection of template arguments) contains
+ any dependent arguments. */
+
+bool
+any_dependent_template_arguments_p (tree args)
+{
+ int i;
+ int j;
+
+ if (!args)
+ return false;
+
+ for (i = 0; i < TMPL_ARGS_DEPTH (args); ++i)
+ {
+ tree level = TMPL_ARGS_LEVEL (args, i + 1);
+ for (j = 0; j < TREE_VEC_LENGTH (level); ++j)
+ if (dependent_template_arg_p (TREE_VEC_ELT (level, j)))
+ return true;
+ }
+
+ return false;
+}
+
+/* Returns TRUE if the template TMPL is dependent. */
+
+bool
+dependent_template_p (tree tmpl)
+{
+ if (TREE_CODE (tmpl) == OVERLOAD)
+ {
+ while (tmpl)
+ {
+ if (dependent_template_p (OVL_FUNCTION (tmpl)))
+ return true;
+ tmpl = OVL_CHAIN (tmpl);
+ }
+ return false;
+ }
+
+ /* Template template parameters are dependent. */
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)
+ || TREE_CODE (tmpl) == TEMPLATE_TEMPLATE_PARM)
+ return true;
+ /* So are qualified names that have not been looked up. */
+ if (TREE_CODE (tmpl) == SCOPE_REF)
+ return true;
+ /* So are member templates of dependent classes. */
+ if (TYPE_P (CP_DECL_CONTEXT (tmpl)))
+ return dependent_type_p (DECL_CONTEXT (tmpl));
+ return false;
+}
+
+/* Returns TRUE if the specialization TMPL<ARGS> is dependent. */
+
+bool
+dependent_template_id_p (tree tmpl, tree args)
+{
+ return (dependent_template_p (tmpl)
+ || any_dependent_template_arguments_p (args));
+}
+
+/* TYPE is a TYPENAME_TYPE. Returns the ordinary TYPE to which the
+ TYPENAME_TYPE corresponds. Returns ERROR_MARK_NODE if no such TYPE
+ can be found. Note that this function peers inside uninstantiated
+ templates and therefore should be used only in extremely limited
+ situations. */
+
+tree
+resolve_typename_type (tree type, bool only_current_p)
+{
+ tree scope;
+ tree name;
+ tree decl;
+ int quals;
+ bool pop_p;
+
+ my_friendly_assert (TREE_CODE (type) == TYPENAME_TYPE,
+ 20010702);
+
+ scope = TYPE_CONTEXT (type);
+ name = TYPE_IDENTIFIER (type);
+
+ /* If the SCOPE is itself a TYPENAME_TYPE, then we need to resolve
+ it first before we can figure out what NAME refers to. */
+ if (TREE_CODE (scope) == TYPENAME_TYPE)
+ scope = resolve_typename_type (scope, only_current_p);
+ /* If we don't know what SCOPE refers to, then we cannot resolve the
+ TYPENAME_TYPE. */
+ if (scope == error_mark_node || TREE_CODE (scope) == TYPENAME_TYPE)
+ return error_mark_node;
+ /* If the SCOPE is a template type parameter, we have no way of
+ resolving the name. */
+ if (TREE_CODE (scope) == TEMPLATE_TYPE_PARM)
+ return type;
+ /* If the SCOPE is not the current instantiation, there's no reason
+ to look inside it. */
+ if (only_current_p && !currently_open_class (scope))
+ return error_mark_node;
+ /* If SCOPE is a partial instantiation, it will not have a valid
+ TYPE_FIELDS list, so use the original template. */
+ scope = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (scope);
+ /* Enter the SCOPE so that name lookup will be resolved as if we
+ were in the class definition. In particular, SCOPE will no
+ longer be considered a dependent type. */
+ pop_p = push_scope (scope);
+ /* Look up the declaration. */
+ decl = lookup_member (scope, name, /*protect=*/0, /*want_type=*/true);
+ /* Obtain the set of qualifiers applied to the TYPE. */
+ quals = cp_type_quals (type);
+ /* For a TYPENAME_TYPE like "typename X::template Y<T>", we want to
+ find a TEMPLATE_DECL. Otherwise, we want to find a TYPE_DECL. */
+ if (!decl)
+ type = error_mark_node;
+ else if (TREE_CODE (TYPENAME_TYPE_FULLNAME (type)) == IDENTIFIER_NODE
+ && TREE_CODE (decl) == TYPE_DECL)
+ type = TREE_TYPE (decl);
+ else if (TREE_CODE (TYPENAME_TYPE_FULLNAME (type)) == TEMPLATE_ID_EXPR
+ && DECL_CLASS_TEMPLATE_P (decl))
+ {
+ tree tmpl;
+ tree args;
+ /* Obtain the template and the arguments. */
+ tmpl = TREE_OPERAND (TYPENAME_TYPE_FULLNAME (type), 0);
+ args = TREE_OPERAND (TYPENAME_TYPE_FULLNAME (type), 1);
+ /* Instantiate the template. */
+ type = lookup_template_class (tmpl, args, NULL_TREE, NULL_TREE,
+ /*entering_scope=*/0, tf_error | tf_user);
+ }
+ else
+ type = error_mark_node;
+ /* Qualify the resulting type. */
+ if (type != error_mark_node && quals)
+ type = cp_build_qualified_type (type, quals);
+ /* Leave the SCOPE. */
+ if (pop_p)
+ pop_scope (scope);
+
+ return type;
+}
+
+/* EXPR is an expression which is not type-dependent. Return a proxy
+ for EXPR that can be used to compute the types of larger
+ expressions containing EXPR. */
+
+tree
+build_non_dependent_expr (tree expr)
+{
+ tree inner_expr;
+
+ /* Preserve null pointer constants so that the type of things like
+ "p == 0" where "p" is a pointer can be determined. */
+ if (null_ptr_cst_p (expr))
+ return expr;
+ /* Preserve OVERLOADs; the functions must be available to resolve
+ types. */
+ inner_expr = (TREE_CODE (expr) == ADDR_EXPR ?
+ TREE_OPERAND (expr, 0) : expr);
+ if (TREE_CODE (inner_expr) == OVERLOAD
+ || TREE_CODE (inner_expr) == FUNCTION_DECL
+ || TREE_CODE (inner_expr) == TEMPLATE_DECL
+ || TREE_CODE (inner_expr) == TEMPLATE_ID_EXPR)
+ return expr;
+ /* Preserve string constants; conversions from string constants to
+ "char *" are allowed, even though normally a "const char *"
+ cannot be used to initialize a "char *". */
+ if (TREE_CODE (expr) == STRING_CST)
+ return expr;
+ /* Preserve arithmetic constants, as an optimization -- there is no
+ reason to create a new node. */
+ if (TREE_CODE (expr) == INTEGER_CST || TREE_CODE (expr) == REAL_CST)
+ return expr;
+ /* Preserve THROW_EXPRs -- all throw-expressions have type "void".
+ There is at least one place where we want to know that a
+ particular expression is a throw-expression: when checking a ?:
+ expression, there are special rules if the second or third
+ argument is a throw-expresion. */
+ if (TREE_CODE (expr) == THROW_EXPR)
+ return expr;
+
+ if (TREE_CODE (expr) == COND_EXPR)
+ return build (COND_EXPR,
+ TREE_TYPE (expr),
+ TREE_OPERAND (expr, 0),
+ (TREE_OPERAND (expr, 1)
+ ? build_non_dependent_expr (TREE_OPERAND (expr, 1))
+ : build_non_dependent_expr (TREE_OPERAND (expr, 0))),
+ build_non_dependent_expr (TREE_OPERAND (expr, 2)));
+ if (TREE_CODE (expr) == COMPOUND_EXPR
+ && !COMPOUND_EXPR_OVERLOADED (expr))
+ return build (COMPOUND_EXPR,
+ TREE_TYPE (expr),
+ TREE_OPERAND (expr, 0),
+ build_non_dependent_expr (TREE_OPERAND (expr, 1)));
+
+ /* Otherwise, build a NON_DEPENDENT_EXPR.
+
+ REFERENCE_TYPEs are not stripped for expressions in templates
+ because doing so would play havoc with mangling. Consider, for
+ example:
+
+ template <typename T> void f<T& g>() { g(); }
+
+ In the body of "f", the expression for "g" will have
+ REFERENCE_TYPE, even though the standard says that it should
+ not. The reason is that we must preserve the syntactic form of
+ the expression so that mangling (say) "f<g>" inside the body of
+ "f" works out correctly. Therefore, the REFERENCE_TYPE is
+ stripped here. */
+ 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. */
+
+tree
+build_non_dependent_args (tree args)
+{
+ tree a;
+ tree new_args;
+
+ 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);
+}
+
#include "gt-cp-pt.h"
diff --git a/contrib/gcc/cp/ptree.c b/contrib/gcc/cp/ptree.c
index 6a7b26cbbdc1..7979504e3fd8 100644
--- a/contrib/gcc/cp/ptree.c
+++ b/contrib/gcc/cp/ptree.c
@@ -1,36 +1,35 @@
/* Prints out trees in human readable form.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998,
- 1999 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
void
-cxx_print_decl (file, node, indent)
- FILE *file;
- tree node;
- int indent;
+cxx_print_decl (FILE *file, tree node, int indent)
{
if (TREE_CODE (node) == FIELD_DECL)
{
@@ -47,29 +46,20 @@ cxx_print_decl (file, node, indent)
indent_to (file, indent + 3);
if (TREE_CODE (node) == FUNCTION_DECL
&& DECL_PENDING_INLINE_INFO (node))
- {
- fprintf (file, " pending-inline-info ");
- fprintf (file, HOST_PTR_PRINTF, DECL_PENDING_INLINE_INFO (node));
- }
+ fprintf (file, " pending-inline-info " HOST_PTR_PRINTF,
+ (void *) DECL_PENDING_INLINE_INFO (node));
if (TREE_CODE (node) == TYPE_DECL
&& DECL_SORTED_FIELDS (node))
- {
- fprintf (file, " sorted-fields ");
- fprintf (file, HOST_PTR_PRINTF, DECL_SORTED_FIELDS (node));
- }
+ fprintf (file, " sorted-fields " HOST_PTR_PRINTF,
+ (void *) DECL_SORTED_FIELDS (node));
if ((TREE_CODE (node) == FUNCTION_DECL || TREE_CODE (node) == VAR_DECL)
&& DECL_TEMPLATE_INFO (node))
- {
- fprintf (file, " template-info ");
- fprintf (file, HOST_PTR_PRINTF, DECL_TEMPLATE_INFO (node));
- }
+ fprintf (file, " template-info " HOST_PTR_PRINTF,
+ (void *) DECL_TEMPLATE_INFO (node));
}
void
-cxx_print_type (file, node, indent)
- FILE *file;
- register tree node;
- int indent;
+cxx_print_type (FILE *file, tree node, int indent)
{
switch (TREE_CODE (node))
{
@@ -77,12 +67,10 @@ cxx_print_type (file, node, indent)
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
indent_to (file, indent + 3);
- fputs ("index ", file);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_TYPE_IDX (node));
- fputs (" level ", file);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_TYPE_LEVEL (node));
- fputs (" orig_level ", file);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_TYPE_ORIG_LEVEL (node));
+ fprintf (file, "index " HOST_WIDE_INT_PRINT_DEC " level "
+ HOST_WIDE_INT_PRINT_DEC " orig_level " HOST_WIDE_INT_PRINT_DEC,
+ TEMPLATE_TYPE_IDX (node), TEMPLATE_TYPE_LEVEL (node),
+ TEMPLATE_TYPE_ORIG_LEVEL (node));
return;
case FUNCTION_TYPE:
@@ -135,12 +123,6 @@ cxx_print_type (file, node, indent)
fputs (" delete[]", file);
if (TYPE_HAS_ASSIGN_REF (node))
fputs (" this=(X&)", file);
- if (TYPE_OVERLOADS_CALL_EXPR (node))
- fputs (" op()", file);
- if (TYPE_OVERLOADS_ARRAY_REF (node))
- fputs (" op[]", file);
- if (TYPE_OVERLOADS_ARROW (node))
- fputs (" op->", file);
if (TYPE_USES_MULTIPLE_INHERITANCE (node))
fputs (" uses-multiple-inheritance", file);
@@ -157,22 +139,21 @@ cxx_print_type (file, node, indent)
}
}
+
static void
cxx_print_binding (FILE *stream, cxx_binding *binding, const char *prefix)
{
- fprintf (stream, "%s <", prefix);
- fprintf (stream, HOST_PTR_PRINTF, (char *) binding);
- fprintf (stream, ">");
+ fprintf (stream, "%s <" HOST_PTR_PRINTF ">",
+ prefix, (void *) binding);
}
void
-cxx_print_identifier (file, node, indent)
- FILE *file;
- tree node;
- int indent;
+cxx_print_identifier (FILE *file, tree node, int indent)
{
+ indent_to (file, indent);
cxx_print_binding (file, IDENTIFIER_NAMESPACE_BINDINGS (node), "bindings");
print_node (file, "class", IDENTIFIER_CLASS_VALUE (node), indent + 4);
+ indent_to (file, indent);
cxx_print_binding (file, IDENTIFIER_BINDING (node), "local bindings");
print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
print_node (file, "template", IDENTIFIER_TEMPLATE (node), indent + 4);
@@ -181,10 +162,7 @@ cxx_print_identifier (file, node, indent)
}
void
-cxx_print_xnode (file, node, indent)
- FILE *file;
- tree node;
- int indent;
+cxx_print_xnode (FILE *file, tree node, int indent)
{
switch (TREE_CODE (node))
{
@@ -194,12 +172,10 @@ cxx_print_xnode (file, node, indent)
break;
case TEMPLATE_PARM_INDEX:
indent_to (file, indent + 3);
- fputs ("index ", file);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_PARM_IDX (node));
- fputs (" level ", file);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_PARM_LEVEL (node));
- fputs (" orig_level ", file);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_PARM_ORIG_LEVEL (node));
+ fprintf (file, "index " HOST_WIDE_INT_PRINT_DEC " level "
+ HOST_WIDE_INT_PRINT_DEC " orig_level " HOST_WIDE_INT_PRINT_DEC,
+ TEMPLATE_PARM_IDX (node), TEMPLATE_PARM_LEVEL (node),
+ TEMPLATE_PARM_ORIG_LEVEL (node));
break;
default:
break;
diff --git a/contrib/gcc/cp/repo.c b/contrib/gcc/cp/repo.c
index 64c6ec873fcc..a9a5b35c293b 100644
--- a/contrib/gcc/cp/repo.c
+++ b/contrib/gcc/cp/repo.c
@@ -1,21 +1,22 @@
/* Code to maintain a C++ template repository.
- Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
Contributed by Jason Merrill (jason@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -27,20 +28,21 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "input.h"
#include "obstack.h"
#include "toplev.h"
-#include "ggc.h"
#include "diagnostic.h"
-static tree repo_get_id PARAMS ((tree));
-static char *extract_string PARAMS ((char **));
-static const char *get_base_filename PARAMS ((const char *));
-static void open_repo_file PARAMS ((const char *));
-static char *afgets PARAMS ((FILE *));
-static void reopen_repo_file_for_write PARAMS ((void));
+static tree repo_get_id (tree);
+static char *extract_string (char **);
+static const char *get_base_filename (const char *);
+static void open_repo_file (const char *);
+static char *afgets (FILE *);
+static void reopen_repo_file_for_write (void);
static GTY(()) tree pending_repo;
static GTY(()) tree original_repo;
@@ -58,9 +60,7 @@ static struct obstack temporary_obstack;
/* Record the flags used to compile this translation unit. */
void
-repo_compile_flags (argc, argv)
- int argc;
- char **argv;
+repo_compile_flags (int argc, char **argv)
{
}
@@ -69,30 +69,26 @@ repo_compile_flags (argc, argv)
definition at link time. */
void
-repo_template_declared (t)
- tree t;
+repo_template_declared (tree t)
{}
/* Note where the definition of a template lives so that instantiations can
be generated later. */
void
-repo_template_defined (t)
- tree t;
+repo_template_defined (tree t)
{}
/* Note where the definition of a class lives to that template
instantiations can use it. */
void
-repo_class_defined (t)
- tree t;
+repo_class_defined (tree t)
{}
#endif
static tree
-repo_get_id (t)
- tree t;
+repo_get_id (tree t)
{
if (TYPE_P (t))
{
@@ -117,8 +113,7 @@ repo_get_id (t)
to emit it. */
void
-repo_template_used (t)
- tree t;
+repo_template_used (tree t)
{
tree id;
@@ -159,8 +154,7 @@ repo_template_used (t)
/* Note that the vtable for a class has been used, and offer to emit it. */
static void
-repo_vtable_used (t)
- tree t;
+repo_vtable_used (tree t)
{
if (! flag_use_repository)
return;
@@ -172,8 +166,7 @@ repo_vtable_used (t)
emit it. */
void
-repo_inline_used (fn)
- tree fn;
+repo_inline_used (tree fn)
{
if (! flag_use_repository)
return;
@@ -193,16 +186,13 @@ repo_inline_used (fn)
emit it. */
void
-repo_tinfo_used (ti)
- tree ti;
+repo_tinfo_used (tree ti)
{
}
#endif
void
-repo_template_instantiated (t, extern_p)
- tree t;
- int extern_p;
+repo_template_instantiated (tree t, bool extern_p)
{
if (! extern_p)
{
@@ -215,8 +205,7 @@ repo_template_instantiated (t, extern_p)
/* Parse a reasonable subset of shell quoting syntax. */
static char *
-extract_string (pp)
- char **pp;
+extract_string (char **pp)
{
char *p = *pp;
int backquote = 0;
@@ -245,9 +234,8 @@ extract_string (pp)
return obstack_finish (&temporary_obstack);
}
-const char *
-get_base_filename (filename)
- const char *filename;
+static const char *
+get_base_filename (const char *filename)
{
char *p = getenv ("COLLECT_GCC_OPTIONS");
char *output = NULL;
@@ -277,10 +265,9 @@ get_base_filename (filename)
}
static void
-open_repo_file (filename)
- const char *filename;
+open_repo_file (const char *filename)
{
- register const char *p;
+ const char *p;
const char *s = get_base_filename (filename);
if (s == NULL)
@@ -299,8 +286,7 @@ open_repo_file (filename)
}
static char *
-afgets (stream)
- FILE *stream;
+afgets (FILE *stream)
{
int c;
while ((c = getc (stream)) != EOF && c != '\n')
@@ -312,8 +298,7 @@ afgets (stream)
}
void
-init_repo (filename)
- const char *filename;
+init_repo (const char *filename)
{
char *buf;
@@ -365,7 +350,7 @@ init_repo (filename)
}
static void
-reopen_repo_file_for_write ()
+reopen_repo_file_for_write (void)
{
if (repo_file)
fclose (repo_file);
@@ -381,13 +366,13 @@ reopen_repo_file_for_write ()
/* Emit any pending repos. */
void
-finish_repo ()
+finish_repo (void)
{
tree t;
- int repo_changed = 0;
+ bool repo_changed = false;
char *dir, *args;
- if (! flag_use_repository)
+ if (!flag_use_repository)
return;
/* Do we have to write out a new info file? */
@@ -397,10 +382,10 @@ finish_repo ()
for (t = original_repo; t; t = TREE_CHAIN (t))
{
- if (! IDENTIFIER_REPO_USED (TREE_VALUE (t))
- || (! TREE_PURPOSE (t) && IDENTIFIER_REPO_CHOSEN (TREE_VALUE (t))))
+ if (!IDENTIFIER_REPO_USED (TREE_VALUE (t))
+ || (!TREE_PURPOSE (t) && IDENTIFIER_REPO_CHOSEN (TREE_VALUE (t))))
{
- repo_changed = 1;
+ repo_changed = true;
break;
}
IDENTIFIER_REPO_USED (TREE_VALUE (t)) = 0;
@@ -408,12 +393,12 @@ finish_repo ()
/* Are there any templates that are newly used? */
- if (! repo_changed)
+ if (!repo_changed)
for (t = pending_repo; t; t = TREE_CHAIN (t))
{
if (IDENTIFIER_REPO_USED (TREE_VALUE (t)))
{
- repo_changed = 1;
+ repo_changed = true;
break;
}
}
@@ -421,14 +406,14 @@ finish_repo ()
dir = getpwd ();
args = getenv ("COLLECT_GCC_OPTIONS");
- if (! repo_changed && pending_repo)
+ if (!repo_changed && pending_repo)
if (strcmp (old_main, main_input_filename) != 0
|| strcmp (old_dir, dir) != 0
|| (args == NULL) != (old_args == NULL)
|| (args && strcmp (old_args, args) != 0))
- repo_changed = 1;
+ repo_changed = true;
- if (! repo_changed || errorcount || sorrycount)
+ if (!repo_changed || errorcount || sorrycount)
goto out;
reopen_repo_file_for_write ();
diff --git a/contrib/gcc/cp/rtti.c b/contrib/gcc/cp/rtti.c
index 7b4a248f0561..e9c06160bbe9 100644
--- a/contrib/gcc/cp/rtti.c
+++ b/contrib/gcc/cp/rtti.c
@@ -1,34 +1,37 @@
/* RunTime Type Identification
- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Mostly written by Jason Merrill (jason@cygnus.com).
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "flags.h"
#include "output.h"
#include "assert.h"
#include "toplev.h"
+#include "convert.h"
/* C++ returns type information to the user in struct type_info
objects. We also use type information to implement dynamic_cast and
@@ -71,30 +74,34 @@ Boston, MA 02111-1307, USA. */
/* The IDENTIFIER_NODE naming the real class. */
#define TINFO_REAL_NAME(NODE) TREE_PURPOSE (NODE)
-static tree build_headof PARAMS((tree));
-static tree ifnonnull PARAMS((tree, tree));
-static tree tinfo_name PARAMS((tree));
-static tree build_dynamic_cast_1 PARAMS((tree, tree));
-static tree throw_bad_cast PARAMS((void));
-static tree throw_bad_typeid PARAMS((void));
-static tree get_tinfo_decl_dynamic PARAMS((tree));
-static tree get_tinfo_ptr PARAMS((tree));
-static bool typeid_ok_p PARAMS((void));
-static int qualifier_flags PARAMS((tree));
-static int target_incomplete_p PARAMS((tree));
-static tree tinfo_base_init PARAMS((tree, tree));
-static tree generic_initializer PARAMS((tree, tree));
-static tree ptr_initializer PARAMS((tree, tree, int *));
-static tree ptm_initializer PARAMS((tree, tree, int *));
-static tree dfs_class_hint_mark PARAMS ((tree, void *));
-static tree dfs_class_hint_unmark PARAMS ((tree, void *));
-static int class_hint_flags PARAMS((tree));
-static tree class_initializer PARAMS((tree, tree, tree));
-static tree create_pseudo_type_info PARAMS((const char *, int, ...));
-static tree get_pseudo_ti_init PARAMS ((tree, tree, int *));
-static tree get_pseudo_ti_desc PARAMS((tree));
-static void create_tinfo_types PARAMS((void));
-static int typeinfo_in_lib_p PARAMS((tree));
+/* A varray of all tinfo decls that haven't yet been emitted. */
+varray_type unemitted_tinfo_decls;
+
+static tree build_headof (tree);
+static tree ifnonnull (tree, tree);
+static tree tinfo_name (tree);
+static tree build_dynamic_cast_1 (tree, tree);
+static tree throw_bad_cast (void);
+static tree throw_bad_typeid (void);
+static tree get_tinfo_decl_dynamic (tree);
+static tree get_tinfo_ptr (tree);
+static bool typeid_ok_p (void);
+static int qualifier_flags (tree);
+static bool target_incomplete_p (tree);
+static tree tinfo_base_init (tree, tree);
+static tree generic_initializer (tree, tree);
+static tree ptr_initializer (tree, tree, bool *);
+static tree ptm_initializer (tree, tree, bool *);
+static tree dfs_class_hint_mark (tree, void *);
+static tree dfs_class_hint_unmark (tree, void *);
+static int class_hint_flags (tree);
+static tree class_initializer (tree, tree, tree);
+static tree create_pseudo_type_info (const char *, int, ...);
+static tree get_pseudo_ti_init (tree, tree, bool *);
+static tree get_pseudo_ti_desc (tree);
+static void create_tinfo_types (void);
+static bool typeinfo_in_lib_p (tree);
+static bool unemitted_tinfo_decl_p (tree);
static int doing_runtime = 0;
@@ -106,16 +113,21 @@ static int doing_runtime = 0;
the internal versions of the ABI types. */
void
-init_rtti_processing ()
+init_rtti_processing (void)
{
+ tree const_type_info_type;
+
push_namespace (std_identifier);
type_info_type_node
= xref_tag (class_type, get_identifier ("type_info"),
- /*attributes=*/NULL_TREE, 1);
+ true, false);
pop_namespace ();
- type_info_ptr_type =
- build_pointer_type
- (build_qualified_type (type_info_type_node, TYPE_QUAL_CONST));
+ const_type_info_type = build_qualified_type (type_info_type_node,
+ TYPE_QUAL_CONST);
+ type_info_ptr_type = build_pointer_type (const_type_info_type);
+ type_info_ref_type = build_reference_type (const_type_info_type);
+
+ VARRAY_TREE_INIT (unemitted_tinfo_decls, 10, "RTTI decls");
create_tinfo_types ();
}
@@ -126,8 +138,7 @@ init_rtti_processing ()
expression. */
static tree
-build_headof (exp)
- tree exp;
+build_headof (tree exp)
{
tree type = TREE_TYPE (exp);
tree offset;
@@ -149,8 +160,8 @@ build_headof (exp)
type = build_qualified_type (ptr_type_node,
cp_type_quals (TREE_TYPE (exp)));
- return build (PLUS_EXPR, type, exp,
- cp_convert (ptrdiff_type_node, offset));
+ return build (PLUS_EXPR, type, exp,
+ convert_to_integer (ptrdiff_type_node, offset));
}
/* Get a bad_cast node for the program to throw...
@@ -158,52 +169,49 @@ build_headof (exp)
See libstdc++/exception.cc for __throw_bad_cast */
static tree
-throw_bad_cast ()
+throw_bad_cast (void)
{
tree fn = get_identifier ("__cxa_bad_cast");
- if (IDENTIFIER_GLOBAL_VALUE (fn))
- fn = IDENTIFIER_GLOBAL_VALUE (fn);
- else
+ if (!get_global_value_if_present (fn, &fn))
fn = push_throw_library_fn (fn, build_function_type (ptr_type_node,
void_list_node));
return build_cxx_call (fn, NULL_TREE, NULL_TREE);
}
+/* Return an expression for "__cxa_bad_typeid()". The expression
+ returned is an lvalue of type "const std::type_info". */
+
static tree
-throw_bad_typeid ()
+throw_bad_typeid (void)
{
tree fn = get_identifier ("__cxa_bad_typeid");
- if (IDENTIFIER_GLOBAL_VALUE (fn))
- fn = IDENTIFIER_GLOBAL_VALUE (fn);
- else
+ if (!get_global_value_if_present (fn, &fn))
{
tree t = build_qualified_type (type_info_type_node, TYPE_QUAL_CONST);
t = build_function_type (build_reference_type (t), void_list_node);
fn = push_throw_library_fn (fn, t);
}
- return build_cxx_call (fn, NULL_TREE, NULL_TREE);
+ return convert_from_reference (build_cxx_call (fn, NULL_TREE, NULL_TREE));
}
-/* Return a pointer to type_info function associated with the expression EXP.
- If EXP is a reference to a polymorphic class, return the dynamic type;
+/* Return an lvalue expression whose type is "const std::type_info"
+ and whose value indicates the type of the expression EXP. If EXP
+ is a reference to a polymorphic class, return the dynamic type;
otherwise return the static type of the expression. */
static tree
-get_tinfo_decl_dynamic (exp)
- tree exp;
+get_tinfo_decl_dynamic (tree exp)
{
tree type;
+ tree t;
if (exp == error_mark_node)
return error_mark_node;
- type = TREE_TYPE (exp);
-
/* peel back references, so they match. */
- if (TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
+ type = non_reference (TREE_TYPE (exp));
/* Peel off cv qualifiers. */
type = TYPE_MAIN_VARIANT (type);
@@ -218,22 +226,22 @@ get_tinfo_decl_dynamic (exp)
if (TYPE_POLYMORPHIC_P (type) && ! resolves_to_fixed_type_p (exp, 0))
{
/* build reference to type_info from vtable. */
- tree t;
tree index;
/* The RTTI information is at index -1. */
index = build_int_2 (-1 * TARGET_VTABLE_DATA_ENTRY_DISTANCE, -1);
t = build_vtbl_ref (exp, index);
TREE_TYPE (t) = type_info_ptr_type;
- return t;
}
+ else
+ /* Otherwise return the type_info for the static type of the expr. */
+ t = get_tinfo_ptr (TYPE_MAIN_VARIANT (type));
- /* Otherwise return the type_info for the static type of the expr. */
- return get_tinfo_ptr (TYPE_MAIN_VARIANT (type));
+ return build_indirect_ref (t, NULL);
}
static bool
-typeid_ok_p ()
+typeid_ok_p (void)
{
if (! flag_rtti)
{
@@ -250,9 +258,11 @@ typeid_ok_p ()
return true;
}
+/* Return an expression for "typeid(EXP)". The expression returned is
+ an lvalue of type "const std::type_info". */
+
tree
-build_typeid (exp)
- tree exp;
+build_typeid (tree exp)
{
tree cond = NULL_TREE;
int nonnull = 0;
@@ -261,7 +271,7 @@ build_typeid (exp)
return error_mark_node;
if (processing_template_decl)
- return build_min_nt (TYPEID_EXPR, exp);
+ return build_min (TYPEID_EXPR, type_info_ref_type, exp);
if (TREE_CODE (exp) == INDIRECT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
@@ -278,8 +288,6 @@ build_typeid (exp)
if (exp == error_mark_node)
return error_mark_node;
- exp = build_indirect_ref (exp, NULL);
-
if (cond)
{
tree bad = throw_bad_typeid ();
@@ -287,13 +295,12 @@ build_typeid (exp)
exp = build (COND_EXPR, TREE_TYPE (exp), cond, exp, bad);
}
- return convert_from_reference (exp);
+ return exp;
}
/* Generate the NTBS name of a type. */
static tree
-tinfo_name (type)
- tree type;
+tinfo_name (tree type)
{
const char *name;
tree name_string;
@@ -308,8 +315,7 @@ tinfo_name (type)
it --- decls in vtables are only used if the vtable is output. */
tree
-get_tinfo_decl (type)
- tree type;
+get_tinfo_decl (tree type)
{
tree name;
tree d;
@@ -322,8 +328,6 @@ get_tinfo_decl (type)
return error_mark_node;
}
- if (TREE_CODE (type) == OFFSET_TYPE)
- type = TREE_TYPE (type);
if (TREE_CODE (type) == METHOD_TYPE)
type = build_function_type (TREE_TYPE (type),
TREE_CHAIN (TYPE_ARG_TYPES (type)));
@@ -350,8 +354,9 @@ get_tinfo_decl (type)
TREE_READONLY (d) = 1;
TREE_STATIC (d) = 1;
DECL_EXTERNAL (d) = 1;
- SET_DECL_ASSEMBLER_NAME (d, name);
DECL_COMDAT (d) = 1;
+ TREE_PUBLIC (d) = 1;
+ SET_DECL_ASSEMBLER_NAME (d, name);
pushdecl_top_level_and_finish (d, NULL_TREE);
@@ -360,6 +365,10 @@ get_tinfo_decl (type)
/* Remember the type it is for. */
TREE_TYPE (name) = type;
+
+ /* Add decl to the global array of tinfo decls. */
+ my_friendly_assert (unemitted_tinfo_decls != 0, 20030312);
+ VARRAY_PUSH_TREE (unemitted_tinfo_decls, d);
}
return d;
@@ -369,35 +378,30 @@ get_tinfo_decl (type)
cast to the language defined type. */
static tree
-get_tinfo_ptr (type)
- tree type;
+get_tinfo_ptr (tree type)
{
- tree exp = get_tinfo_decl (type);
-
- /* Convert to type_info type. */
- exp = build_unary_op (ADDR_EXPR, exp, 0);
- exp = ocp_convert (type_info_ptr_type, exp, CONV_REINTERPRET, 0);
+ tree decl = get_tinfo_decl (type);
- return exp;
+ mark_used (decl);
+ return build_nop (type_info_ptr_type,
+ build_address (decl));
}
/* Return the type_info object for TYPE. */
tree
-get_typeid (type)
- tree type;
+get_typeid (tree type)
{
if (type == error_mark_node || !typeid_ok_p ())
return error_mark_node;
if (processing_template_decl)
- return build_min_nt (TYPEID_EXPR, type);
+ return build_min (TYPEID_EXPR, type_info_ref_type, type);
/* If the type of the type-id is a reference type, the result of the
typeid expression refers to a type_info object representing the
referenced type. */
- if (TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
+ type = non_reference (type);
/* The top-level cv-qualifiers of the lvalue expression or the type-id
that is the operand of typeid are always ignored. */
@@ -416,8 +420,7 @@ get_typeid (type)
RESULT, it must have previously had a save_expr applied to it. */
static tree
-ifnonnull (test, result)
- tree test, result;
+ifnonnull (tree test, tree result)
{
return build (COND_EXPR, TREE_TYPE (result),
build (EQ_EXPR, boolean_type_node, test, integer_zero_node),
@@ -429,8 +432,7 @@ ifnonnull (test, result)
paper. */
static tree
-build_dynamic_cast_1 (type, expr)
- tree type, expr;
+build_dynamic_cast_1 (tree type, tree expr)
{
enum tree_code tc = TREE_CODE (type);
tree exprtype = TREE_TYPE (expr);
@@ -463,12 +465,6 @@ build_dynamic_cast_1 (type, expr)
goto fail;
}
- if (TREE_CODE (expr) == OFFSET_REF)
- {
- expr = resolve_offset_ref (expr);
- exprtype = TREE_TYPE (expr);
- }
-
if (tc == POINTER_TYPE)
expr = convert_from_reference (expr);
else if (TREE_CODE (exprtype) != REFERENCE_TYPE)
@@ -605,8 +601,12 @@ build_dynamic_cast_1 (type, expr)
target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
- td2 = build_unary_op (ADDR_EXPR, get_tinfo_decl (target_type), 0);
- td3 = build_unary_op (ADDR_EXPR, get_tinfo_decl (static_type), 0);
+ td2 = get_tinfo_decl (target_type);
+ mark_used (td2);
+ td2 = build_unary_op (ADDR_EXPR, td2, 0);
+ td3 = get_tinfo_decl (static_type);
+ mark_used (td3);
+ td3 = build_unary_op (ADDR_EXPR, td3, 0);
/* Determine how T and V are related. */
boff = get_dynamic_cast_base_type (static_type, target_type);
@@ -635,8 +635,7 @@ build_dynamic_cast_1 (type, expr)
push_nested_namespace (ns);
tinfo_ptr = xref_tag (class_type,
get_identifier ("__class_type_info"),
- /*attributes=*/NULL_TREE,
- 1);
+ true, false);
tinfo_ptr = build_pointer_type
(build_qualified_type
@@ -649,6 +648,7 @@ build_dynamic_cast_1 (type, expr)
(NULL_TREE, ptrdiff_type_node, void_list_node))));
tmp = build_function_type (ptr_type_node, tmp);
dcast_fn = build_library_fn_ptr (name, tmp);
+ DECL_IS_PURE (dcast_fn) = 1;
pop_nested_namespace (ns);
dynamic_cast_node = dcast_fn;
}
@@ -677,14 +677,18 @@ build_dynamic_cast_1 (type, expr)
}
tree
-build_dynamic_cast (type, expr)
- tree type, expr;
+build_dynamic_cast (tree type, tree expr)
{
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
if (processing_template_decl)
- return build_min (DYNAMIC_CAST_EXPR, type, expr);
+ {
+ expr = build_min (DYNAMIC_CAST_EXPR, type, expr);
+ TREE_SIDE_EFFECTS (expr) = 1;
+
+ return expr;
+ }
return convert_from_reference (build_dynamic_cast_1 (type, expr));
}
@@ -692,8 +696,7 @@ build_dynamic_cast (type, expr)
/* Return the runtime bit mask encoding the qualifiers of TYPE. */
static int
-qualifier_flags (type)
- tree type;
+qualifier_flags (tree type)
{
int flags = 0;
int quals = cp_type_quals (type);
@@ -707,26 +710,23 @@ qualifier_flags (type)
return flags;
}
-/* Return nonzero, if the pointer chain TYPE ends at an incomplete type, or
+/* Return true, if the pointer chain TYPE ends at an incomplete type, or
contains a pointer to member of an incomplete class. */
-static int
-target_incomplete_p (type)
- tree type;
+static bool
+target_incomplete_p (tree type)
{
- while (TREE_CODE (type) == POINTER_TYPE)
+ while (true)
if (TYPE_PTRMEM_P (type))
{
- if (!COMPLETE_TYPE_P (TYPE_PTRMEM_CLASS_TYPE (type)))
- return 1;
- type = TYPE_PTRMEM_POINTED_TO_TYPE (type);
+ if (!COMPLETE_TYPE_P (TYPE_PTRMEM_CLASS_TYPE (type)))
+ return true;
+ type = TYPE_PTRMEM_POINTED_TO_TYPE (type);
}
- else
+ else if (TREE_CODE (type) == POINTER_TYPE)
type = TREE_TYPE (type);
- if (!COMPLETE_OR_VOID_TYPE_P (type))
- return 1;
-
- return 0;
+ else
+ return !COMPLETE_OR_VOID_TYPE_P (type);
}
/* Return a CONSTRUCTOR for the common part of the type_info objects. This
@@ -736,9 +736,7 @@ target_incomplete_p (type)
as comdat, because of pointers to incomplete.) */
static tree
-tinfo_base_init (desc, target)
- tree desc;
- tree target;
+tinfo_base_init (tree desc, tree target)
{
tree init = NULL_TREE;
tree name_decl;
@@ -761,12 +759,13 @@ tinfo_base_init (desc, target)
TREE_STATIC (name_decl) = 1;
DECL_EXTERNAL (name_decl) = 0;
TREE_PUBLIC (name_decl) = 1;
- comdat_linkage (name_decl);
+ import_export_tinfo (name_decl, target, typeinfo_in_lib_p (target));
/* External name of the string containing the type's name has a
special name. */
SET_DECL_ASSEMBLER_NAME (name_decl,
mangle_typeinfo_string_for_type (target));
DECL_INITIAL (name_decl) = name_string;
+ mark_used (name_decl);
pushdecl_top_level_and_finish (name_decl, name_string);
}
@@ -777,7 +776,7 @@ tinfo_base_init (desc, target)
push_nested_namespace (abi_node);
real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
- /*attributes=*/NULL_TREE, 1);
+ true, false);
pop_nested_namespace (abi_node);
if (!COMPLETE_TYPE_P (real_type))
@@ -807,7 +806,7 @@ tinfo_base_init (desc, target)
init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
- init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
+ init = build_constructor (NULL_TREE, nreverse (init));
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
init = tree_cons (NULL_TREE, init, NULL_TREE);
@@ -819,13 +818,11 @@ tinfo_base_init (desc, target)
additional fields to the type_info base. */
static tree
-generic_initializer (desc, target)
- tree desc;
- tree target;
+generic_initializer (tree desc, tree target)
{
tree init = tinfo_base_init (desc, target);
- init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init);
+ init = build_constructor (NULL_TREE, init);
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
return init;
}
@@ -835,27 +832,24 @@ generic_initializer (desc, target)
which adds target type and qualifier flags members to the type_info base. */
static tree
-ptr_initializer (desc, target, non_public_ptr)
- tree desc;
- tree target;
- int *non_public_ptr;
+ptr_initializer (tree desc, tree target, bool *non_public_ptr)
{
tree init = tinfo_base_init (desc, target);
tree to = TREE_TYPE (target);
int flags = qualifier_flags (to);
- int incomplete = target_incomplete_p (to);
+ bool incomplete = target_incomplete_p (to);
if (incomplete)
{
flags |= 8;
- *non_public_ptr = 1;
+ *non_public_ptr = true;
}
init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
init = tree_cons (NULL_TREE,
get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
init);
- init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
+ init = build_constructor (NULL_TREE, nreverse (init));
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
return init;
}
@@ -866,26 +860,23 @@ ptr_initializer (desc, target, non_public_ptr)
base. */
static tree
-ptm_initializer (desc, target, non_public_ptr)
- tree desc;
- tree target;
- int *non_public_ptr;
+ptm_initializer (tree desc, tree target, bool *non_public_ptr)
{
tree init = tinfo_base_init (desc, target);
tree to = TYPE_PTRMEM_POINTED_TO_TYPE (target);
tree klass = TYPE_PTRMEM_CLASS_TYPE (target);
int flags = qualifier_flags (to);
- int incomplete = target_incomplete_p (to);
+ bool incomplete = target_incomplete_p (to);
if (incomplete)
{
flags |= 0x8;
- *non_public_ptr = 1;
+ *non_public_ptr = true;
}
if (!COMPLETE_TYPE_P (klass))
{
flags |= 0x10;
- *non_public_ptr = 1;
+ *non_public_ptr = true;
}
init = tree_cons (NULL_TREE, build_int_2 (flags, 0), init);
init = tree_cons (NULL_TREE,
@@ -895,7 +886,7 @@ ptm_initializer (desc, target, non_public_ptr)
get_tinfo_ptr (klass),
init);
- init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, nreverse (init));
+ init = build_constructor (NULL_TREE, nreverse (init));
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
return init;
}
@@ -906,9 +897,7 @@ ptm_initializer (desc, target, non_public_ptr)
possible for a type to be both a virtual and non-virtual base. */
static tree
-dfs_class_hint_mark (binfo, data)
- tree binfo;
- void *data;
+dfs_class_hint_mark (tree binfo, void *data)
{
tree basetype = BINFO_TYPE (binfo);
int *hint = (int *) data;
@@ -927,17 +916,13 @@ dfs_class_hint_mark (binfo, data)
*hint |= 1;
SET_CLASSTYPE_MARKED (basetype);
}
- if (!TREE_VIA_PUBLIC (binfo) && TYPE_BINFO (basetype) != binfo)
- *hint |= 4;
return NULL_TREE;
-};
+}
/* Clear the base's dfs marks, after searching for duplicate bases. */
static tree
-dfs_class_hint_unmark (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
+dfs_class_hint_unmark (tree binfo, void *data ATTRIBUTE_UNUSED)
{
tree basetype = BINFO_TYPE (binfo);
@@ -949,22 +934,13 @@ dfs_class_hint_unmark (binfo, data)
/* Determine the hint flags describing the features of a class's hierarchy. */
static int
-class_hint_flags (type)
- tree type;
+class_hint_flags (tree type)
{
int hint_flags = 0;
- int i;
dfs_walk (TYPE_BINFO (type), dfs_class_hint_mark, NULL, &hint_flags);
dfs_walk (TYPE_BINFO (type), dfs_class_hint_unmark, NULL, NULL);
- for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); ++i)
- {
- tree base_binfo = BINFO_BASETYPE (TYPE_BINFO (type), i);
-
- if (TREE_VIA_PUBLIC (base_binfo))
- hint_flags |= 0x8;
- }
return hint_flags;
}
@@ -973,25 +949,21 @@ class_hint_flags (type)
which adds hint flags and TRAIL initializers to the type_info base. */
static tree
-class_initializer (desc, target, trail)
- tree desc;
- tree target;
- tree trail;
+class_initializer (tree desc, tree target, tree trail)
{
tree init = tinfo_base_init (desc, target);
TREE_CHAIN (init) = trail;
- init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init);
+ init = build_constructor (NULL_TREE, init);
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
return init;
}
-/* Returns nonzero if the typeinfo for type should be placed in
+/* Returns true if the typeinfo for type should be placed in
the runtime library. */
-static int
-typeinfo_in_lib_p (type)
- tree type;
+static bool
+typeinfo_in_lib_p (tree type)
{
/* The typeinfo objects for `T*' and `const T*' are in the runtime
library for simple types T. */
@@ -1007,10 +979,10 @@ typeinfo_in_lib_p (type)
case CHAR_TYPE:
case REAL_TYPE:
case VOID_TYPE:
- return 1;
+ return true;
default:
- return 0;
+ return false;
}
}
@@ -1021,20 +993,15 @@ typeinfo_in_lib_p (type)
types will be completed. */
static tree
-get_pseudo_ti_init (type, var_desc, non_public_p)
- tree type;
- tree var_desc;
- int *non_public_p;
+get_pseudo_ti_init (tree type, tree var_desc, bool *non_public_p)
{
my_friendly_assert (at_eof, 20021120);
switch (TREE_CODE (type))
{
+ case OFFSET_TYPE:
+ return ptm_initializer (var_desc, type, non_public_p);
case POINTER_TYPE:
- if (TYPE_PTRMEM_P (type))
- return ptm_initializer (var_desc, type, non_public_p);
- else
- return ptr_initializer (var_desc, type, non_public_p);
- break;
+ return ptr_initializer (var_desc, type, non_public_p);
case ENUMERAL_TYPE:
return generic_initializer (var_desc, type);
break;
@@ -1052,7 +1019,7 @@ get_pseudo_ti_init (type, var_desc, non_public_p)
{
if (!COMPLETE_TYPE_P (type))
/* Emit a non-public class_type_info. */
- *non_public_p = 1;
+ *non_public_p = true;
return class_initializer (var_desc, type, NULL_TREE);
}
else if (var_desc == si_class_desc_type_node)
@@ -1070,6 +1037,7 @@ get_pseudo_ti_init (type, var_desc, non_public_p)
tree binfo = TYPE_BINFO (type);
int nbases = BINFO_N_BASETYPES (binfo);
tree base_binfos = BINFO_BASETYPES (binfo);
+ tree base_accesses = BINFO_BASEACCESSES (binfo);
tree base_inits = NULL_TREE;
int ix;
@@ -1082,34 +1050,32 @@ get_pseudo_ti_init (type, var_desc, non_public_p)
tree tinfo;
tree offset;
- if (TREE_PUBLIC (base_binfo))
+ if (TREE_VEC_ELT (base_accesses, ix) == access_public_node)
flags |= 2;
tinfo = get_tinfo_ptr (BINFO_TYPE (base_binfo));
if (TREE_VIA_VIRTUAL (base_binfo))
{
/* We store the vtable offset at which the virtual
base offset can be found. */
- offset = BINFO_VPTR_FIELD
- (binfo_for_vbase (BINFO_TYPE (base_binfo), type));
+ offset = BINFO_VPTR_FIELD (base_binfo);
offset = convert (sizetype, offset);
flags |= 1;
}
else
offset = BINFO_OFFSET (base_binfo);
- /* combine offset and flags into one field */
+ /* Combine offset and flags into one field. */
offset = cp_build_binary_op (LSHIFT_EXPR, offset,
build_int_2 (8, 0));
offset = cp_build_binary_op (BIT_IOR_EXPR, offset,
build_int_2 (flags, 0));
base_init = tree_cons (NULL_TREE, offset, base_init);
base_init = tree_cons (NULL_TREE, tinfo, base_init);
- base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
+ base_init = build_constructor (NULL_TREE, base_init);
TREE_HAS_CONSTRUCTOR (base_init) = 1;
base_inits = tree_cons (NULL_TREE, base_init, base_inits);
}
- base_inits = build (CONSTRUCTOR,
- NULL_TREE, NULL_TREE, base_inits);
+ base_inits = build_constructor (NULL_TREE, base_inits);
TREE_HAS_CONSTRUCTOR (base_inits) = 1;
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
/* Prepend the number of bases. */
@@ -1144,36 +1110,37 @@ get_pseudo_ti_init (type, var_desc, non_public_p)
NULL. */
static tree
-create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
+create_pseudo_type_info (const char *real_name, int ident, ...)
{
tree pseudo_type;
char *pseudo_name;
- int ix;
- tree fields[10];
+ tree fields;
tree field_decl;
tree result;
+ va_list ap;
- VA_OPEN (ap, ident);
- VA_FIXEDARG (ap, const char *, real_name);
- VA_FIXEDARG (ap, int, ident);
+ va_start (ap, ident);
/* Generate the pseudo type name. */
- pseudo_name = (char *)alloca (strlen (real_name) + 30);
+ pseudo_name = alloca (strlen (real_name) + 30);
strcpy (pseudo_name, real_name);
strcat (pseudo_name, "_pseudo");
if (ident)
sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
/* First field is the pseudo type_info base class. */
- fields[0] = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
+ fields = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
/* Now add the derived fields. */
- for (ix = 0; (field_decl = va_arg (ap, tree));)
- fields[++ix] = field_decl;
+ while ((field_decl = va_arg (ap, tree)))
+ {
+ TREE_CHAIN (field_decl) = fields;
+ fields = field_decl;
+ }
/* Create the pseudo type. */
pseudo_type = make_aggr_type (RECORD_TYPE);
- finish_builtin_type (pseudo_type, pseudo_name, fields, ix, ptr_type_node);
+ finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
@@ -1181,7 +1148,7 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
TINFO_PSEUDO_TYPE (result) =
cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
- VA_CLOSE (ap);
+ va_end (ap);
return result;
}
@@ -1190,13 +1157,14 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
translation unit. */
static tree
-get_pseudo_ti_desc (type)
- tree type;
+get_pseudo_ti_desc (tree type)
{
switch (TREE_CODE (type))
{
+ case OFFSET_TYPE:
+ return ptm_desc_type_node;
case POINTER_TYPE:
- return TYPE_PTRMEM_P (type) ? ptm_desc_type_node : ptr_desc_type_node;
+ return ptr_desc_type_node;
case ENUMERAL_TYPE:
return enum_desc_type_node;
case FUNCTION_TYPE:
@@ -1217,12 +1185,14 @@ get_pseudo_ti_desc (type)
return class_desc_type_node;
else
{
- tree base_binfo =
- TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), 0);
- int num_bases = BINFO_N_BASETYPES (TYPE_BINFO (type));
+ tree binfo = TYPE_BINFO (type);
+ tree base_binfos = BINFO_BASETYPES (binfo);
+ tree base_accesses = BINFO_BASEACCESSES (binfo);
+ tree base_binfo = TREE_VEC_ELT (base_binfos, 0);
+ int num_bases = TREE_VEC_LENGTH (base_binfos);
if (num_bases == 1
- && TREE_PUBLIC (base_binfo)
+ && TREE_VEC_ELT (base_accesses, 0) == access_public_node
&& !TREE_VIA_VIRTUAL (base_binfo)
&& integer_zerop (BINFO_OFFSET (base_binfo)))
/* single non-virtual public. */
@@ -1246,9 +1216,14 @@ get_pseudo_ti_desc (type)
if (var_desc)
return var_desc;
- /* Add number of bases and trailing array of
- base_class_type_info. */
- array_domain = build_index_type (size_int (num_bases));
+ /* Create the array of __base_class_type_info entries.
+ G++ 3.2 allocated an array that had one too many
+ entries, and then filled that extra entries with
+ zeros. */
+ if (abi_version_at_least (2))
+ array_domain = build_index_type (size_int (num_bases - 1));
+ else
+ array_domain = build_index_type (size_int (num_bases));
base_array =
build_array_type (base_desc_type_node, array_domain);
@@ -1274,7 +1249,7 @@ get_pseudo_ti_desc (type)
varable definitions. */
static void
-create_tinfo_types ()
+create_tinfo_types (void)
{
my_friendly_assert (!ti_desc_type_node, 20020609);
@@ -1283,13 +1258,18 @@ create_tinfo_types ()
/* Create the internal type_info structure. This is used as a base for
the other structures. */
{
- tree fields[2];
+ tree field, fields;
ti_desc_type_node = make_aggr_type (RECORD_TYPE);
- fields[0] = build_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node);
- fields[1] = build_decl (FIELD_DECL, NULL_TREE, const_string_type_node);
- finish_builtin_type (ti_desc_type_node, "__type_info_pseudo",
- fields, 1, ptr_type_node);
+ field = build_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node);
+ fields = field;
+
+ field = build_decl (FIELD_DECL, NULL_TREE, const_string_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+
+ finish_builtin_struct (ti_desc_type_node, "__type_info_pseudo",
+ fields, NULL_TREE);
TYPE_HAS_CONSTRUCTOR (ti_desc_type_node) = 1;
}
@@ -1324,13 +1304,18 @@ create_tinfo_types ()
/* Base class internal helper. Pointer to base type, offset to base,
flags. */
{
- tree fields[2];
+ tree field, fields;
+
+ field = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type);
+ fields = field;
- fields[0] = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type);
- fields[1] = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
+ field = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+
base_desc_type_node = make_aggr_type (RECORD_TYPE);
- finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
- fields, 1, ptr_type_node);
+ finish_builtin_struct (base_desc_type_node, "__base_class_type_info_pseudo",
+ fields, NULL_TREE);
TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
}
@@ -1366,7 +1351,7 @@ create_tinfo_types ()
destructor is defined, then the runtime is being built. */
void
-emit_support_tinfos ()
+emit_support_tinfos (void)
{
static tree *const fundamentals[] =
{
@@ -1387,8 +1372,7 @@ emit_support_tinfos ()
push_nested_namespace (abi_node);
bltn_type = xref_tag (class_type,
get_identifier ("__fundamental_type_info"),
- /*attributes=*/NULL_TREE,
- 1);
+ true, false);
pop_nested_namespace (abi_node);
if (!COMPLETE_TYPE_P (bltn_type))
return;
@@ -1418,17 +1402,17 @@ emit_support_tinfos ()
}
}
-/* Return nonzero, iff T is a type_info variable which has not had a
+/* Return true, iff T is a type_info variable which has not had a
definition emitted for it. */
-int
-unemitted_tinfo_decl_p (t, data)
- tree t;
- void *data ATTRIBUTE_UNUSED;
+static bool
+unemitted_tinfo_decl_p (tree t)
{
if (/* It's a var decl */
TREE_CODE (t) == VAR_DECL
- /* whos name points back to itself */
+ /* which has a name */
+ && DECL_NAME (t)
+ /* whose name points back to itself */
&& IDENTIFIER_GLOBAL_VALUE (DECL_NAME (t)) == t
/* whose name's type is non-null */
&& TREE_TYPE (DECL_NAME (t))
@@ -1438,33 +1422,32 @@ unemitted_tinfo_decl_p (t, data)
&& TYPE_FIELDS (TREE_TYPE (t))
/* which is our pseudo type info */
&& TREE_TYPE (TYPE_FIELDS (TREE_TYPE (t))) == ti_desc_type_node)
- return 1;
- return 0;
+ return true;
+ return false;
}
/* Finish a type info decl. DECL_PTR is a pointer to an unemitted
tinfo decl. Determine whether it needs emitting, and if so
generate the initializer. */
-int
-emit_tinfo_decl (decl_ptr, data)
- tree *decl_ptr;
- void *data ATTRIBUTE_UNUSED;
+bool
+emit_tinfo_decl (tree decl)
{
- tree decl = *decl_ptr;
tree type = TREE_TYPE (DECL_NAME (decl));
- int non_public;
+ bool non_public;
int in_library = typeinfo_in_lib_p (type);
tree var_desc, var_init;
+
+ my_friendly_assert (unemitted_tinfo_decl_p (decl), 20030307);
import_export_tinfo (decl, type, in_library);
if (DECL_REALLY_EXTERN (decl) || !DECL_NEEDED_P (decl))
- return 0;
+ return false;
if (!doing_runtime && in_library)
- return 0;
+ return false;
- non_public = 0;
+ non_public = false;
var_desc = get_pseudo_ti_desc (type);
var_init = get_pseudo_ti_init (type, var_desc, &non_public);
@@ -1474,11 +1457,12 @@ emit_tinfo_decl (decl_ptr, data)
DECL_COMDAT (decl) = 0;
DECL_INITIAL (decl) = var_init;
+ mark_used (decl);
cp_finish_decl (decl, var_init, NULL_TREE, 0);
/* cp_finish_decl will have dealt with linkage. */
/* Say we've dealt with it. */
TREE_TYPE (DECL_NAME (decl)) = NULL_TREE;
- return 1;
+ return true;
}
diff --git a/contrib/gcc/cp/search.c b/contrib/gcc/cp/search.c
index c43dd212a58f..65ed660cee7f 100644
--- a/contrib/gcc/cp/search.c
+++ b/contrib/gcc/cp/search.c
@@ -4,20 +4,20 @@
1999, 2000, 2002, 2003 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -25,13 +25,14 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "obstack.h"
#include "flags.h"
#include "rtl.h"
#include "output.h"
-#include "ggc.h"
#include "toplev.h"
#include "stack.h"
@@ -42,10 +43,8 @@ static struct obstack search_obstack;
/* Methods for pushing and popping objects to and from obstacks. */
struct stack_level *
-push_stack_level (obstack, tp, size)
- struct obstack *obstack;
- char *tp; /* Sony NewsOS 5.0 compiler doesn't like void * here. */
- int size;
+push_stack_level (struct obstack *obstack, char *tp,/* Sony NewsOS 5.0 compiler doesn't like void * here. */
+ int size)
{
struct stack_level *stack;
obstack_grow (obstack, tp, size);
@@ -58,8 +57,7 @@ push_stack_level (obstack, tp, size)
}
struct stack_level *
-pop_stack_level (stack)
- struct stack_level *stack;
+pop_stack_level (struct stack_level *stack)
{
struct stack_level *tem = stack;
struct obstack *obstack = tem->obstack;
@@ -80,59 +78,41 @@ struct vbase_info
tree inits;
};
-static int is_subobject_of_p PARAMS ((tree, tree, tree));
-static int is_subobject_of_p_1 PARAMS ((tree, tree, tree));
-static tree dfs_check_overlap PARAMS ((tree, void *));
-static tree dfs_no_overlap_yet PARAMS ((tree, void *));
-static base_kind lookup_base_r
- PARAMS ((tree, tree, base_access, int, tree *));
-static int dynamic_cast_base_recurse PARAMS ((tree, tree, int, tree *));
-static tree marked_pushdecls_p PARAMS ((tree, void *));
-static tree unmarked_pushdecls_p PARAMS ((tree, void *));
-static tree dfs_debug_unmarkedp PARAMS ((tree, void *));
-static tree dfs_debug_mark PARAMS ((tree, void *));
-static tree dfs_get_vbase_types PARAMS ((tree, void *));
-static tree dfs_push_type_decls PARAMS ((tree, void *));
-static tree dfs_push_decls PARAMS ((tree, void *));
-static tree dfs_unuse_fields PARAMS ((tree, void *));
-static tree add_conversions PARAMS ((tree, void *));
-static int covariant_return_p PARAMS ((tree, tree));
-static int look_for_overrides_r PARAMS ((tree, tree));
-static struct search_level *push_search_level
- PARAMS ((struct stack_level *, struct obstack *));
-static struct search_level *pop_search_level
- PARAMS ((struct stack_level *));
-static tree bfs_walk
- PARAMS ((tree, tree (*) (tree, void *), tree (*) (tree, void *),
- void *));
-static tree lookup_field_queue_p PARAMS ((tree, void *));
-static int shared_member_p PARAMS ((tree));
-static tree lookup_field_r PARAMS ((tree, void *));
-static tree canonical_binfo PARAMS ((tree));
-static tree shared_marked_p PARAMS ((tree, void *));
-static tree shared_unmarked_p PARAMS ((tree, void *));
-static int dependent_base_p PARAMS ((tree));
-static tree dfs_accessible_queue_p PARAMS ((tree, void *));
-static tree dfs_accessible_p PARAMS ((tree, void *));
-static tree dfs_access_in_type PARAMS ((tree, void *));
-static access_kind access_in_type PARAMS ((tree, tree));
-static tree dfs_canonical_queue PARAMS ((tree, void *));
-static tree dfs_assert_unmarked_p PARAMS ((tree, void *));
-static void assert_canonical_unmarked PARAMS ((tree));
-static int protected_accessible_p PARAMS ((tree, tree, tree));
-static int friend_accessible_p PARAMS ((tree, tree, tree));
-static void setup_class_bindings PARAMS ((tree, int));
-static int template_self_reference_p PARAMS ((tree, tree));
-static tree dfs_find_vbase_instance PARAMS ((tree, void *));
-static tree dfs_get_pure_virtuals PARAMS ((tree, void *));
-static tree dfs_build_inheritance_graph_order PARAMS ((tree, void *));
+static tree dfs_check_overlap (tree, void *);
+static tree dfs_no_overlap_yet (tree, int, void *);
+static base_kind lookup_base_r (tree, tree, base_access, bool, tree *);
+static int dynamic_cast_base_recurse (tree, tree, bool, tree *);
+static tree marked_pushdecls_p (tree, int, void *);
+static tree unmarked_pushdecls_p (tree, int, void *);
+static tree dfs_debug_unmarkedp (tree, int, void *);
+static tree dfs_debug_mark (tree, void *);
+static tree dfs_push_type_decls (tree, void *);
+static tree dfs_push_decls (tree, void *);
+static tree dfs_unuse_fields (tree, void *);
+static tree add_conversions (tree, void *);
+static int look_for_overrides_r (tree, tree);
+static struct search_level *push_search_level (struct stack_level *,
+ struct obstack *);
+static struct search_level *pop_search_level (struct stack_level *);
+static tree bfs_walk (tree, tree (*) (tree, void *),
+ tree (*) (tree, int, void *), void *);
+static tree lookup_field_queue_p (tree, int, void *);
+static int shared_member_p (tree);
+static tree lookup_field_r (tree, void *);
+static tree dfs_accessible_queue_p (tree, int, void *);
+static tree dfs_accessible_p (tree, void *);
+static tree dfs_access_in_type (tree, void *);
+static access_kind access_in_type (tree, tree);
+static int protected_accessible_p (tree, tree, tree);
+static int friend_accessible_p (tree, tree, tree);
+static void setup_class_bindings (tree, int);
+static int template_self_reference_p (tree, tree);
+static tree dfs_get_pure_virtuals (tree, void *);
/* Allocate a level of searching. */
static struct search_level *
-push_search_level (stack, obstack)
- struct stack_level *stack;
- struct obstack *obstack;
+push_search_level (struct stack_level *stack, struct obstack *obstack)
{
struct search_level tem;
@@ -143,10 +123,9 @@ push_search_level (stack, obstack)
/* Discard a level of search allocation. */
static struct search_level *
-pop_search_level (obstack)
- struct stack_level *obstack;
+pop_search_level (struct stack_level *obstack)
{
- register struct search_level *stack = pop_stack_level (obstack);
+ struct search_level *stack = pop_stack_level (obstack);
return stack;
}
@@ -175,14 +154,12 @@ static int n_contexts_saved;
Otherwise BINFO's bases are searched. */
static base_kind
-lookup_base_r (binfo, base, access, is_virtual, binfo_ptr)
- tree binfo, base;
- base_access access;
- int is_virtual; /* inside a virtual part */
- tree *binfo_ptr;
+lookup_base_r (tree binfo, tree base, base_access access,
+ bool is_virtual, /* inside a virtual part */
+ tree *binfo_ptr)
{
int i;
- tree bases;
+ tree bases, accesses;
base_kind found = bk_not_base;
if (same_type_p (BINFO_TYPE (binfo), base))
@@ -195,8 +172,7 @@ lookup_base_r (binfo, base, access, is_virtual, binfo_ptr)
if (!*binfo_ptr)
*binfo_ptr = binfo;
- else if (!is_virtual || !tree_int_cst_equal (BINFO_OFFSET (binfo),
- BINFO_OFFSET (*binfo_ptr)))
+ else if (binfo != *binfo_ptr)
{
if (access != ba_any)
*binfo_ptr = NULL;
@@ -210,6 +186,7 @@ lookup_base_r (binfo, base, access, is_virtual, binfo_ptr)
}
bases = BINFO_BASETYPES (binfo);
+ accesses = BINFO_BASEACCESSES (binfo);
if (!bases)
return bk_not_base;
@@ -255,7 +232,7 @@ lookup_base_r (binfo, base, access, is_virtual, binfo_ptr)
}
/* Returns true if type BASE is accessible in T. (BASE is known to be
- a base class of T.) */
+ a (possibly non-proper) base class of T.) */
bool
accessible_base_p (tree t, tree base)
@@ -265,7 +242,12 @@ accessible_base_p (tree t, tree base)
/* [class.access.base]
A base class is said to be accessible if an invented public
- member of the base class is accessible. */
+ member of the base class is accessible.
+
+ If BASE is a non-proper base, this condition is trivially
+ true. */
+ if (same_type_p (t, base))
+ return true;
/* Rather than inventing a public member, we use the implicit
public typedef created in the scope of every class. */
decl = TYPE_FIELDS (base);
@@ -277,9 +259,9 @@ accessible_base_p (tree t, tree base)
}
/* Lookup BASE in the hierarchy dominated by T. Do access checking as
- ACCESS specifies. Return the binfo we discover (which might not be
- canonical). If KIND_PTR is non-NULL, fill with information about
- what kind of base we discovered.
+ ACCESS specifies. Return the binfo we discover. If KIND_PTR is
+ non-NULL, fill with information about what kind of base we
+ discovered.
If the base is inaccessible, or ambiguous, and the ba_quiet bit is
not set in ACCESS, then an error is issued and error_mark_node is
@@ -287,10 +269,7 @@ accessible_base_p (tree t, tree base)
NULL_TREE is returned. */
tree
-lookup_base (t, base, access, kind_ptr)
- tree t, base;
- base_access access;
- base_kind *kind_ptr;
+lookup_base (tree t, tree base, base_access access, base_kind *kind_ptr)
{
tree binfo = NULL; /* The binfo we've found so far. */
tree t_binfo = NULL;
@@ -366,19 +345,16 @@ lookup_base (t, base, access, kind_ptr)
/* Worker function for get_dynamic_cast_base_type. */
static int
-dynamic_cast_base_recurse (subtype, binfo, via_virtual, offset_ptr)
- tree subtype;
- tree binfo;
- int via_virtual;
- tree *offset_ptr;
+dynamic_cast_base_recurse (tree subtype, tree binfo, bool is_via_virtual,
+ tree *offset_ptr)
{
- tree binfos;
+ tree binfos, accesses;
int i, n_baselinks;
int worst = -2;
if (BINFO_TYPE (binfo) == subtype)
{
- if (via_virtual)
+ if (is_via_virtual)
return -1;
else
{
@@ -388,17 +364,19 @@ dynamic_cast_base_recurse (subtype, binfo, via_virtual, offset_ptr)
}
binfos = BINFO_BASETYPES (binfo);
+ accesses = BINFO_BASEACCESSES (binfo);
n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
for (i = 0; i < n_baselinks; i++)
{
tree base_binfo = TREE_VEC_ELT (binfos, i);
+ tree base_access = TREE_VEC_ELT (accesses, i);
int rval;
- if (!TREE_VIA_PUBLIC (base_binfo))
+ if (base_access != access_public_node)
continue;
rval = dynamic_cast_base_recurse
(subtype, base_binfo,
- via_virtual || TREE_VIA_VIRTUAL (base_binfo), offset_ptr);
+ is_via_virtual || TREE_VIA_VIRTUAL (base_binfo), offset_ptr);
if (worst == -2)
worst = rval;
else if (rval >= 0)
@@ -423,13 +401,11 @@ dynamic_cast_base_recurse (subtype, binfo, via_virtual, offset_ptr)
BOFF == -3, SUBTYPE occurs as multiple public non-virtual bases. */
tree
-get_dynamic_cast_base_type (subtype, target)
- tree subtype;
- tree target;
+get_dynamic_cast_base_type (tree subtype, tree target)
{
tree offset = NULL_TREE;
int boff = dynamic_cast_base_recurse (subtype, TYPE_BINFO (target),
- 0, &offset);
+ false, &offset);
if (!boff)
return offset;
@@ -438,10 +414,11 @@ get_dynamic_cast_base_type (subtype, target)
return offset;
}
-/* Search for a member with name NAME in a multiple inheritance lattice
- specified by TYPE. If it does not exist, return NULL_TREE.
+/* Search for a member with name NAME in a multiple inheritance
+ lattice specified by TYPE. If it does not exist, return NULL_TREE.
If the member is ambiguously referenced, return `error_mark_node'.
- Otherwise, return the FIELD_DECL. */
+ Otherwise, return a DECL with the indicated name. If WANT_TYPE is
+ true, type declarations are preferred. */
/* Do a 1-level search for NAME as a member of TYPE. The caller must
figure out whether it can access this field. (Since it is only one
@@ -450,7 +427,7 @@ get_dynamic_cast_base_type (subtype, target)
tree
lookup_field_1 (tree type, tree name, bool want_type)
{
- register tree field;
+ tree field;
if (TREE_CODE (type) == TEMPLATE_TYPE_PARM
|| TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
@@ -467,8 +444,8 @@ lookup_field_1 (tree type, tree name, bool want_type)
&& DECL_LANG_SPECIFIC (TYPE_NAME (type))
&& DECL_SORTED_FIELDS (TYPE_NAME (type)))
{
- tree *fields = &TREE_VEC_ELT (DECL_SORTED_FIELDS (TYPE_NAME (type)), 0);
- int lo = 0, hi = TREE_VEC_LENGTH (DECL_SORTED_FIELDS (TYPE_NAME (type)));
+ tree *fields = &DECL_SORTED_FIELDS (TYPE_NAME (type))->elts[0];
+ int lo = 0, hi = DECL_SORTED_FIELDS (TYPE_NAME (type))->len;
int i;
while (lo < hi)
@@ -571,7 +548,7 @@ lookup_field_1 (tree type, tree name, bool want_type)
function. If so, we know to put the decls into the class's scope. */
tree
-current_scope ()
+current_scope (void)
{
if (current_function_decl == NULL_TREE)
return current_class_type;
@@ -593,7 +570,7 @@ current_scope ()
not within a member function body of the local class. */
int
-at_function_scope_p ()
+at_function_scope_p (void)
{
tree cs = current_scope ();
return cs && TREE_CODE (cs) == FUNCTION_DECL;
@@ -602,17 +579,26 @@ at_function_scope_p ()
/* Returns true if the innermost active scope is a class scope. */
bool
-at_class_scope_p ()
+at_class_scope_p (void)
{
tree cs = current_scope ();
return cs && TYPE_P (cs);
}
+/* Returns true if the innermost active scope is a namespace scope. */
+
+bool
+at_namespace_scope_p (void)
+{
+ /* We are in a namespace scope if we are not it a class scope or a
+ function scope. */
+ return !current_scope();
+}
+
/* Return the scope of DECL, as appropriate when doing name-lookup. */
tree
-context_for_name_lookup (decl)
- tree decl;
+context_for_name_lookup (tree decl)
{
/* [class.union]
@@ -630,92 +616,23 @@ context_for_name_lookup (decl)
return context;
}
-/* Return a canonical BINFO if BINFO is a virtual base, or just BINFO
- otherwise. */
-
-static tree
-canonical_binfo (binfo)
- tree binfo;
-{
- return (TREE_VIA_VIRTUAL (binfo)
- ? TYPE_BINFO (BINFO_TYPE (binfo)) : binfo);
-}
-
-/* A queue function that simply ensures that we walk into the
- canonical versions of virtual bases. */
-
-static tree
-dfs_canonical_queue (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
-{
- return canonical_binfo (binfo);
-}
-
-/* Called via dfs_walk from assert_canonical_unmarked. */
-
-static tree
-dfs_assert_unmarked_p (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
-{
- my_friendly_assert (!BINFO_MARKED (binfo), 0);
- return NULL_TREE;
-}
-
-/* Asserts that all the nodes below BINFO (using the canonical
- versions of virtual bases) are unmarked. */
-
-static void
-assert_canonical_unmarked (binfo)
- tree binfo;
-{
- dfs_walk (binfo, dfs_assert_unmarked_p, dfs_canonical_queue, 0);
-}
-
-/* If BINFO is marked, return a canonical version of BINFO.
- Otherwise, return NULL_TREE. */
-
-static tree
-shared_marked_p (binfo, data)
- tree binfo;
- void *data;
-{
- binfo = canonical_binfo (binfo);
- return markedp (binfo, data);
-}
-
-/* If BINFO is not marked, return a canonical version of BINFO.
- Otherwise, return NULL_TREE. */
-
-static tree
-shared_unmarked_p (binfo, data)
- tree binfo;
- void *data;
-{
- binfo = canonical_binfo (binfo);
- return unmarkedp (binfo, data);
-}
-
/* The accessibility routines use BINFO_ACCESS for scratch space
- during the computation of the accssibility of some declaration. */
+ during the computation of the accessibility of some declaration. */
#define BINFO_ACCESS(NODE) \
- ((access_kind) ((TREE_LANG_FLAG_1 (NODE) << 1) | TREE_LANG_FLAG_6 (NODE)))
+ ((access_kind) ((TREE_PUBLIC (NODE) << 1) | TREE_PRIVATE (NODE)))
/* Set the access associated with NODE to ACCESS. */
#define SET_BINFO_ACCESS(NODE, ACCESS) \
- ((TREE_LANG_FLAG_1 (NODE) = ((ACCESS) & 2) != 0), \
- (TREE_LANG_FLAG_6 (NODE) = ((ACCESS) & 1) != 0))
+ ((TREE_PUBLIC (NODE) = ((ACCESS) & 2) != 0), \
+ (TREE_PRIVATE (NODE) = ((ACCESS) & 1) != 0))
/* Called from access_in_type via dfs_walk. Calculate the access to
DATA (which is really a DECL) in BINFO. */
static tree
-dfs_access_in_type (binfo, data)
- tree binfo;
- void *data;
+dfs_access_in_type (tree binfo, void *data)
{
tree decl = (tree) data;
tree type = BINFO_TYPE (binfo);
@@ -723,7 +640,7 @@ dfs_access_in_type (binfo, data)
if (context_for_name_lookup (decl) == type)
{
- /* If we have desceneded to the scope of DECL, just note the
+ /* If we have descended to the scope of DECL, just note the
appropriate access. */
if (TREE_PRIVATE (decl))
access = ak_private;
@@ -741,51 +658,59 @@ dfs_access_in_type (binfo, data)
if (DECL_LANG_SPECIFIC (decl) && !DECL_DISCRIMINATOR_P (decl))
{
tree decl_access = purpose_member (type, DECL_ACCESS (decl));
+
if (decl_access)
- access = ((access_kind)
- TREE_INT_CST_LOW (TREE_VALUE (decl_access)));
+ {
+ decl_access = TREE_VALUE (decl_access);
+
+ if (decl_access == access_public_node)
+ access = ak_public;
+ else if (decl_access == access_protected_node)
+ access = ak_protected;
+ else if (decl_access == access_private_node)
+ access = ak_private;
+ else
+ my_friendly_assert (false, 20030217);
+ }
}
if (!access)
{
int i;
int n_baselinks;
- tree binfos;
+ tree binfos, accesses;
/* Otherwise, scan our baseclasses, and pick the most favorable
access. */
binfos = BINFO_BASETYPES (binfo);
+ accesses = BINFO_BASEACCESSES (binfo);
n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
for (i = 0; i < n_baselinks; ++i)
{
tree base_binfo = TREE_VEC_ELT (binfos, i);
- access_kind base_access
- = BINFO_ACCESS (canonical_binfo (base_binfo));
+ tree base_access = TREE_VEC_ELT (accesses, i);
+ access_kind base_access_now = BINFO_ACCESS (base_binfo);
- if (base_access == ak_none || base_access == ak_private)
+ if (base_access_now == ak_none || base_access_now == ak_private)
/* If it was not accessible in the base, or only
accessible as a private member, we can't access it
all. */
- base_access = ak_none;
- else if (TREE_VIA_PROTECTED (base_binfo))
- /* Public and protected members in the base are
+ base_access_now = ak_none;
+ else if (base_access == access_protected_node)
+ /* Public and protected members in the base become
protected here. */
- base_access = ak_protected;
- else if (!TREE_VIA_PUBLIC (base_binfo))
- /* Public and protected members in the base are
+ base_access_now = ak_protected;
+ else if (base_access == access_private_node)
+ /* Public and protected members in the base become
private here. */
- base_access = ak_private;
+ base_access_now = ak_private;
/* See if the new access, via this base, gives more
access than our previous best access. */
- if (base_access != ak_none
- && (base_access == ak_public
- || (base_access == ak_protected
- && access != ak_public)
- || (base_access == ak_private
- && access == ak_none)))
+ if (base_access_now != ak_none
+ && (access == ak_none || base_access_now < access))
{
- access = base_access;
+ access = base_access_now;
/* If the new access is public, we can't do better. */
if (access == ak_public)
@@ -800,7 +725,7 @@ dfs_access_in_type (binfo, data)
/* Mark TYPE as visited so that if we reach it again we do not
duplicate our efforts here. */
- SET_BINFO_MARKED (binfo);
+ BINFO_MARKED (binfo) = 1;
return NULL_TREE;
}
@@ -808,9 +733,7 @@ dfs_access_in_type (binfo, data)
/* Return the access to DECL in TYPE. */
static access_kind
-access_in_type (type, decl)
- tree type;
- tree decl;
+access_in_type (tree type, tree decl)
{
tree binfo = TYPE_BINFO (type);
@@ -825,62 +748,52 @@ access_in_type (type, decl)
The algorithm we use is to make a post-order depth-first traversal
of the base-class hierarchy. As we come up the tree, we annotate
each node with the most lenient access. */
- dfs_walk_real (binfo, 0, dfs_access_in_type, shared_unmarked_p, decl);
- dfs_walk (binfo, dfs_unmark, shared_marked_p, 0);
- assert_canonical_unmarked (binfo);
+ dfs_walk_real (binfo, 0, dfs_access_in_type, unmarkedp, decl);
+ dfs_walk (binfo, dfs_unmark, markedp, 0);
return BINFO_ACCESS (binfo);
}
-/* Called from dfs_accessible_p via dfs_walk. */
+/* Called from accessible_p via dfs_walk. */
static tree
-dfs_accessible_queue_p (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
+dfs_accessible_queue_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED)
{
+ tree binfo = BINFO_BASETYPE (derived, ix);
+
if (BINFO_MARKED (binfo))
return NULL_TREE;
/* If this class is inherited via private or protected inheritance,
- then we can't see it, unless we are a friend of the subclass. */
- if (!TREE_VIA_PUBLIC (binfo)
- && !is_friend (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)),
- current_scope ()))
+ then we can't see it, unless we are a friend of the derived class. */
+ if (BINFO_BASEACCESS (derived, ix) != access_public_node
+ && !is_friend (BINFO_TYPE (derived), current_scope ()))
return NULL_TREE;
- return canonical_binfo (binfo);
+ return binfo;
}
-/* Called from dfs_accessible_p via dfs_walk. */
+/* Called from accessible_p via dfs_walk. */
static tree
-dfs_accessible_p (binfo, data)
- tree binfo;
- void *data;
+dfs_accessible_p (tree binfo, void *data ATTRIBUTE_UNUSED)
{
- int protected_ok = data != 0;
access_kind access;
- SET_BINFO_MARKED (binfo);
+ BINFO_MARKED (binfo) = 1;
access = BINFO_ACCESS (binfo);
- if (access == ak_public || (access == ak_protected && protected_ok))
- return binfo;
- else if (access != ak_none
- && is_friend (BINFO_TYPE (binfo), current_scope ()))
+ if (access != ak_none
+ && is_friend (BINFO_TYPE (binfo), current_scope ()))
return binfo;
return NULL_TREE;
}
/* Returns nonzero if it is OK to access DECL through an object
- indiated by BINFO in the context of DERIVED. */
+ indicated by BINFO in the context of DERIVED. */
static int
-protected_accessible_p (decl, derived, binfo)
- tree decl;
- tree derived;
- tree binfo;
+protected_accessible_p (tree decl, tree derived, tree binfo)
{
access_kind access;
@@ -940,10 +853,7 @@ protected_accessible_p (decl, derived, binfo)
to access DECL through the object indicated by BINFO. */
static int
-friend_accessible_p (scope, decl, binfo)
- tree scope;
- tree decl;
- tree binfo;
+friend_accessible_p (tree scope, tree decl, tree binfo)
{
tree befriending_classes;
tree t;
@@ -989,41 +899,6 @@ friend_accessible_p (scope, decl, binfo)
return 0;
}
-/* Perform access control on TYPE_DECL or TEMPLATE_DECL VAL, which was
- looked up in TYPE. This is fairly complex, so here's the design:
-
- The lang_extdef nonterminal sets type_lookups to NULL_TREE before we
- start to process a top-level declaration.
- As we process the decl-specifier-seq for the declaration, any types we
- see that might need access control are passed to type_access_control,
- which defers checking by adding them to type_lookups.
- When we are done with the decl-specifier-seq, we record the lookups we've
- seen in the lookups field of the typed_declspecs nonterminal.
- When we process the first declarator, either in parse_decl or
- begin_function_definition, we call save_type_access_control,
- which stores the lookups from the decl-specifier-seq in
- current_type_lookups.
- As we finish with each declarator, we process everything in type_lookups
- via decl_type_access_control, which resets type_lookups to the value of
- current_type_lookups for subsequent declarators.
- When we enter a function, we set type_lookups to error_mark_node, so all
- lookups are processed immediately. */
-
-void
-type_access_control (type, val)
- tree type, val;
-{
- if (val == NULL_TREE
- || (TREE_CODE (val) != TEMPLATE_DECL && TREE_CODE (val) != TYPE_DECL)
- || ! DECL_CLASS_SCOPE_P (val))
- return;
-
- if (type_lookups == error_mark_node)
- enforce_access (type, val);
- else if (! accessible_p (type, val))
- type_lookups = tree_cons (type, val, type_lookups);
-}
-
/* DECL is a declaration from a base class of TYPE, which was the
class used to name DECL. Return nonzero if, in the current
context, DECL is accessible. If TYPE is actually a BINFO node,
@@ -1031,27 +906,34 @@ type_access_control (type, val)
at the most derived class along the path indicated by BINFO. */
int
-accessible_p (type, decl)
- tree type;
- tree decl;
-
+accessible_p (tree type, tree decl)
{
tree binfo;
tree t;
+ tree scope;
+ access_kind access;
/* Nonzero if it's OK to access DECL if it has protected
accessibility in TYPE. */
int protected_ok = 0;
- /* If we're not checking access, everything is accessible. */
- if (!flag_access_control)
- return 1;
-
/* If this declaration is in a block or namespace scope, there's no
access control. */
if (!TYPE_P (context_for_name_lookup (decl)))
return 1;
+ /* There is no need to perform access checks inside a thunk. */
+ scope = current_scope ();
+ if (scope && DECL_THUNK_P (scope))
+ return 1;
+
+ /* In a template declaration, we cannot be sure whether the
+ particular specialization that is instantiated will be a friend
+ or not. Therefore, all access checks are deferred until
+ instantiation. */
+ if (processing_template_decl)
+ return 1;
+
if (!TYPE_P (type))
{
binfo = type;
@@ -1087,7 +969,7 @@ accessible_p (type, decl)
/* Now, loop through the classes of which we are a friend. */
if (!protected_ok)
- protected_ok = friend_accessible_p (current_scope (), decl, binfo);
+ protected_ok = friend_accessible_p (scope, decl, binfo);
/* Standardize the binfo that access_in_type will use. We don't
need to know what path was chosen from this point onwards. */
@@ -1095,83 +977,22 @@ accessible_p (type, decl)
/* Compute the accessibility of DECL in the class hierarchy
dominated by type. */
- access_in_type (type, decl);
- /* Walk the hierarchy again, looking for a base class that allows
- access. */
- t = dfs_walk (binfo, dfs_accessible_p,
- dfs_accessible_queue_p,
- protected_ok ? &protected_ok : 0);
- /* Clear any mark bits. Note that we have to walk the whole tree
- here, since we have aborted the previous walk from some point
- deep in the tree. */
- dfs_walk (binfo, dfs_unmark, dfs_canonical_queue, 0);
- assert_canonical_unmarked (binfo);
-
- return t != NULL_TREE;
-}
-
-/* Recursive helper funciton for is_subobject_of_p; see that routine
- for documentation of the parameters. */
-
-static int
-is_subobject_of_p_1 (parent, binfo, most_derived)
- tree parent, binfo, most_derived;
-{
- tree binfos;
- int i, n_baselinks;
-
- if (parent == binfo)
+ access = access_in_type (type, decl);
+ if (access == ak_public
+ || (access == ak_protected && protected_ok))
return 1;
-
- binfos = BINFO_BASETYPES (binfo);
- n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
-
- /* Iterate through the base types. */
- for (i = 0; i < n_baselinks; i++)
+ else
{
- tree base_binfo = TREE_VEC_ELT (binfos, i);
- tree base_type;
-
- base_type = TREE_TYPE (base_binfo);
- if (!CLASS_TYPE_P (base_type))
- /* If we see a TEMPLATE_TYPE_PARM, or some such, as a base
- class there's no way to descend into it. */
- continue;
-
- /* Avoid walking into the same virtual base more than once. */
- if (TREE_VIA_VIRTUAL (base_binfo))
- {
- if (CLASSTYPE_MARKED4 (base_type))
- continue;
- SET_CLASSTYPE_MARKED4 (base_type);
- base_binfo = binfo_for_vbase (base_type, most_derived);
- }
-
- if (is_subobject_of_p_1 (parent, base_binfo, most_derived))
- return 1;
+ /* Walk the hierarchy again, looking for a base class that allows
+ access. */
+ t = dfs_walk (binfo, dfs_accessible_p, dfs_accessible_queue_p, 0);
+ /* Clear any mark bits. Note that we have to walk the whole tree
+ here, since we have aborted the previous walk from some point
+ deep in the tree. */
+ dfs_walk (binfo, dfs_unmark, 0, 0);
+
+ return t != NULL_TREE;
}
- return 0;
-}
-
-/* Routine to see if the sub-object denoted by the binfo PARENT can be
- found as a base class and sub-object of the object denoted by
- BINFO. MOST_DERIVED is the most derived type of the hierarchy being
- searched. */
-
-static int
-is_subobject_of_p (tree parent, tree binfo, tree most_derived)
-{
- int result;
- tree vbase;
-
- result = is_subobject_of_p_1 (parent, binfo, most_derived);
- /* Clear the mark bits on virtual bases. */
- for (vbase = CLASSTYPE_VBASECLASSES (most_derived);
- vbase;
- vbase = TREE_CHAIN (vbase))
- CLEAR_CLASSTYPE_MARKED4 (TREE_TYPE (TREE_VALUE (vbase)));
-
- return result;
}
struct lookup_field_info {
@@ -1188,8 +1009,6 @@ struct lookup_field_info {
tree ambiguous;
/* If nonzero, we are looking for types, not data members. */
int want_type;
- /* If nonzero, RVAL was found by looking through a dependent base. */
- int from_dep_base_p;
/* If something went wrong, a message indicating what. */
const char *errstr;
};
@@ -1200,10 +1019,9 @@ struct lookup_field_info {
lookup_field via breadth_first_search. */
static tree
-lookup_field_queue_p (binfo, data)
- tree binfo;
- void *data;
+lookup_field_queue_p (tree derived, int ix, void *data)
{
+ tree binfo = BINFO_BASETYPE (derived, ix);
struct lookup_field_info *lfi = (struct lookup_field_info *) data;
/* Don't look for constructors or destructors in base classes. */
@@ -1212,11 +1030,13 @@ lookup_field_queue_p (binfo, data)
/* If this base class is hidden by the best-known value so far, we
don't need to look. */
- binfo = CANONICAL_BINFO (binfo, lfi->type);
- if (!lfi->from_dep_base_p && lfi->rval_binfo
- && is_subobject_of_p (binfo, lfi->rval_binfo, lfi->type))
+ if (lfi->rval_binfo && original_binfo (binfo, lfi->rval_binfo))
return NULL_TREE;
+ /* If this is a dependent base, don't look in it. */
+ if (BINFO_DEPENDENT_BASE_P (binfo))
+ return NULL_TREE;
+
return binfo;
}
@@ -1229,9 +1049,7 @@ lookup_field_queue_p (binfo, data)
Returns nonzero if DECL is such a declaration in a class TYPE. */
static int
-template_self_reference_p (type, decl)
- tree type;
- tree decl;
+template_self_reference_p (tree type, tree decl)
{
return (CLASSTYPE_USE_TEMPLATE (type)
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))
@@ -1252,8 +1070,7 @@ template_self_reference_p (type, decl)
This function checks that T contains no nonstatic members. */
static int
-shared_member_p (t)
- tree t;
+shared_member_p (tree t)
{
if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == TYPE_DECL \
|| TREE_CODE (t) == CONST_DECL)
@@ -1277,14 +1094,11 @@ shared_member_p (t)
lookup_field via breadth_first_search. */
static tree
-lookup_field_r (binfo, data)
- tree binfo;
- void *data;
+lookup_field_r (tree binfo, void *data)
{
struct lookup_field_info *lfi = (struct lookup_field_info *) data;
tree type = BINFO_TYPE (binfo);
tree nval = NULL_TREE;
- int from_dep_base_p;
/* First, look for a function. There can't be a function and a data
member with the same name, and if there's a function and a type
@@ -1323,9 +1137,9 @@ lookup_field_r (binfo, data)
}
else
nval = NULL_TREE;
- if (!nval && CLASSTYPE_NESTED_UDTS (type) != NULL)
+ if (!nval && CLASSTYPE_NESTED_UTDS (type) != NULL)
{
- binding_entry e = binding_table_find (CLASSTYPE_NESTED_UDTS (type),
+ binding_entry e = binding_table_find (CLASSTYPE_NESTED_UTDS (type),
lfi->name);
if (e != NULL)
nval = TYPE_MAIN_DECL (e->type);
@@ -1339,40 +1153,14 @@ lookup_field_r (binfo, data)
&& template_self_reference_p (type, nval))
return NULL_TREE;
- from_dep_base_p = dependent_base_p (binfo);
- if (lfi->from_dep_base_p && !from_dep_base_p)
- {
- /* If the new declaration is not found via a dependent base, and
- the old one was, then we must prefer the new one. We weren't
- really supposed to be able to find the old one, so we don't
- want to be affected by a specialization. Consider:
-
- struct B { typedef int I; };
- template <typename T> struct D1 : virtual public B {};
- template <typename T> struct D :
- public D1, virtual pubic B { I i; };
-
- The `I' in `D<T>' is unambigousuly `B::I', regardless of how
- D1 is specialized. */
- lfi->from_dep_base_p = 0;
- lfi->rval = NULL_TREE;
- lfi->rval_binfo = NULL_TREE;
- lfi->ambiguous = NULL_TREE;
- lfi->errstr = 0;
- }
- else if (lfi->rval_binfo && !lfi->from_dep_base_p && from_dep_base_p)
- /* Similarly, if the old declaration was not found via a dependent
- base, and the new one is, ignore the new one. */
- return NULL_TREE;
-
/* If the lookup already found a match, and the new value doesn't
hide the old one, we might have an ambiguity. */
- if (lfi->rval_binfo && !is_subobject_of_p (lfi->rval_binfo, binfo, lfi->type))
+ if (lfi->rval_binfo && !original_binfo (lfi->rval_binfo, binfo))
{
if (nval == lfi->rval && shared_member_p (nval))
/* The two things are really the same. */
;
- else if (is_subobject_of_p (binfo, lfi->rval_binfo, lfi->type))
+ else if (original_binfo (binfo, lfi->rval_binfo))
/* The previous value hides the new one. */
;
else
@@ -1396,18 +1184,7 @@ lookup_field_r (binfo, data)
}
else
{
- if (from_dep_base_p && TREE_CODE (nval) != TYPE_DECL
- /* We need to return a member template class so we can
- define partial specializations. Is there a better
- way? */
- && !DECL_CLASS_TEMPLATE_P (nval))
- /* The thing we're looking for isn't a type, so the implicit
- typename extension doesn't apply, so we just pretend we
- didn't find anything. */
- return NULL_TREE;
-
lfi->rval = nval;
- lfi->from_dep_base_p = from_dep_base_p;
lfi->rval_binfo = binfo;
}
@@ -1431,8 +1208,8 @@ build_baselink (tree binfo, tree access_binfo, tree functions, tree optype)
my_friendly_assert (!optype || TYPE_P (optype), 20020730);
my_friendly_assert (TREE_TYPE (functions), 20020805);
- baselink = build (BASELINK, TREE_TYPE (functions), NULL_TREE,
- NULL_TREE, NULL_TREE);
+ baselink = make_node (BASELINK);
+ TREE_TYPE (baselink) = TREE_TYPE (functions);
BASELINK_BINFO (baselink) = binfo;
BASELINK_ACCESS_BINFO (baselink) = access_binfo;
BASELINK_FUNCTIONS (baselink) = functions;
@@ -1454,9 +1231,7 @@ build_baselink (tree binfo, tree access_binfo, tree functions, tree optype)
If nothing can be found return NULL_TREE and do not issue an error. */
tree
-lookup_member (xbasetype, name, protect, want_type)
- register tree xbasetype, name;
- int protect, want_type;
+lookup_member (tree xbasetype, tree name, int protect, bool want_type)
{
tree rval, rval_binfo = NULL_TREE;
tree type = NULL_TREE, basetype_path = NULL_TREE;
@@ -1471,31 +1246,31 @@ lookup_member (xbasetype, name, protect, want_type)
const char *errstr = 0;
- if (xbasetype == current_class_type && TYPE_BEING_DEFINED (xbasetype)
- && IDENTIFIER_CLASS_VALUE (name))
- {
- tree field = IDENTIFIER_CLASS_VALUE (name);
- if (! is_overloaded_fn (field)
- && ! (want_type && TREE_CODE (field) != TYPE_DECL))
- /* We're in the scope of this class, and the value has already
- been looked up. Just return the cached value. */
- return field;
- }
+ my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 20030624);
if (TREE_CODE (xbasetype) == TREE_VEC)
{
type = BINFO_TYPE (xbasetype);
basetype_path = xbasetype;
}
- else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)))
+ else
{
+ my_friendly_assert (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)), 20030624);
type = xbasetype;
basetype_path = TYPE_BINFO (type);
- my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE,
- 980827);
+ my_friendly_assert (!BINFO_INHERITANCE_CHAIN (basetype_path), 980827);
+ }
+
+ if (type == current_class_type && TYPE_BEING_DEFINED (type)
+ && IDENTIFIER_CLASS_VALUE (name))
+ {
+ tree field = IDENTIFIER_CLASS_VALUE (name);
+ if (! is_overloaded_fn (field)
+ && ! (want_type && TREE_CODE (field) != TYPE_DECL))
+ /* We're in the scope of this class, and the value has already
+ been looked up. Just return the cached value. */
+ return field;
}
- else
- abort ();
complete_type (type);
@@ -1503,7 +1278,7 @@ lookup_member (xbasetype, name, protect, want_type)
n_calls_lookup_field++;
#endif /* GATHER_STATISTICS */
- memset ((PTR) &lfi, 0, sizeof (lfi));
+ memset (&lfi, 0, sizeof (lfi));
lfi.type = type;
lfi.name = name;
lfi.want_type = want_type;
@@ -1531,9 +1306,8 @@ lookup_member (xbasetype, name, protect, want_type)
In the case of overloaded function names, access control is
applied to the function selected by overloaded resolution. */
- if (rval && protect && !is_overloaded_fn (rval)
- && !enforce_access (xbasetype, rval))
- return error_mark_node;
+ if (rval && protect && !is_overloaded_fn (rval))
+ perform_or_defer_access_check (basetype_path, rval);
if (errstr && protect)
{
@@ -1543,13 +1317,6 @@ lookup_member (xbasetype, name, protect, want_type)
rval = error_mark_node;
}
- /* If the thing we found was found via the implicit typename
- extension, build the typename type. */
- if (rval && lfi.from_dep_base_p && !DECL_CLASS_TEMPLATE_P (rval))
- rval = TYPE_STUB_DECL (build_typename_type (BINFO_TYPE (basetype_path),
- name, name,
- TREE_TYPE (rval)));
-
if (rval && is_overloaded_fn (rval))
rval = build_baselink (rval_binfo, basetype_path, rval,
(IDENTIFIER_TYPENAME_P (name)
@@ -1561,9 +1328,7 @@ lookup_member (xbasetype, name, protect, want_type)
return NULL_TREE. */
tree
-lookup_field (xbasetype, name, protect, want_type)
- register tree xbasetype, name;
- int protect, want_type;
+lookup_field (tree xbasetype, tree name, int protect, bool want_type)
{
tree rval = lookup_member (xbasetype, name, protect, want_type);
@@ -1578,11 +1343,9 @@ lookup_field (xbasetype, name, protect, want_type)
return NULL_TREE. */
tree
-lookup_fnfields (xbasetype, name, protect)
- register tree xbasetype, name;
- int protect;
+lookup_fnfields (tree xbasetype, tree name, int protect)
{
- tree rval = lookup_member (xbasetype, name, protect, /*want_type=*/0);
+ tree rval = lookup_member (xbasetype, name, protect, /*want_type=*/false);
/* Ignore non-functions. */
if (rval && !BASELINK_P (rval))
@@ -1591,70 +1354,6 @@ lookup_fnfields (xbasetype, name, protect)
return rval;
}
-/* Try to find NAME inside a nested class. */
-
-tree
-lookup_nested_field (name, complain)
- tree name;
- int complain;
-{
- register tree t;
-
- tree id = NULL_TREE;
- if (TYPE_MAIN_DECL (current_class_type))
- {
- /* Climb our way up the nested ladder, seeing if we're trying to
- modify a field in an enclosing class. If so, we should only
- be able to modify if it's static. */
- for (t = TYPE_MAIN_DECL (current_class_type);
- t && DECL_CONTEXT (t);
- t = TYPE_MAIN_DECL (DECL_CONTEXT (t)))
- {
- if (TREE_CODE (DECL_CONTEXT (t)) != RECORD_TYPE)
- break;
-
- /* N.B.: lookup_field will do the access checking for us */
- id = lookup_field (DECL_CONTEXT (t), name, complain, 0);
- if (id == error_mark_node)
- {
- id = NULL_TREE;
- continue;
- }
-
- if (id != NULL_TREE)
- {
- if (TREE_CODE (id) == FIELD_DECL
- && ! TREE_STATIC (id)
- && TREE_TYPE (id) != error_mark_node)
- {
- if (complain)
- {
- /* At parse time, we don't want to give this error, since
- we won't have enough state to make this kind of
- decision properly. But there are times (e.g., with
- enums in nested classes) when we do need to call
- this fn at parse time. So, in those cases, we pass
- complain as a 0 and just return a NULL_TREE. */
- error ("assignment to non-static member `%D' of enclosing class `%T'",
- id, DECL_CONTEXT (t));
- /* Mark this for do_identifier(). It would otherwise
- claim that the variable was undeclared. */
- TREE_TYPE (id) = error_mark_node;
- }
- else
- {
- id = NULL_TREE;
- continue;
- }
- }
- break;
- }
- }
- }
-
- return id;
-}
-
/* Return the index in the CLASSTYPE_METHOD_VEC for CLASS_TYPE
corresponding to "operator TYPE ()", or -1 if there is no such
operator. Only CLASS_TYPE itself is searched; this routine does
@@ -1685,7 +1384,7 @@ lookup_conversion_operator (tree class_type, tree type)
fn = OVL_CURRENT (fn);
if (!DECL_CONV_FN_P (fn))
break;
-
+
if (pass == 0)
{
/* On the first pass we only consider exact matches. If
@@ -1771,7 +1470,7 @@ lookup_fnfields_1 (tree type, tree name)
tmp = methods[i];
/* This slot may be empty; we allocate more slots than we
need. In that case, the entry we're looking for is
- closer to the beginning of the list. */
+ closer to the beginning of the list. */
if (tmp)
tmp = DECL_NAME (OVL_CURRENT (tmp));
if (!tmp || tmp > name)
@@ -1788,7 +1487,7 @@ lookup_fnfields_1 (tree type, tree name)
#ifdef GATHER_STATISTICS
n_outer_fields_searched++;
#endif /* GATHER_STATISTICS */
-
+
tmp = OVL_CURRENT (methods[i]);
if (DECL_NAME (tmp) == name)
return i;
@@ -1797,11 +1496,11 @@ lookup_fnfields_1 (tree type, tree name)
return -1;
}
-/* DECL is the result of a qualified name lookup. QUALIFYING_CLASS
- was the class used to qualify the name. CONTEXT_CLASS is the class
- corresponding to the object in which DECL will be used. Return a
- possibly modified version of DECL that takes into account the
- CONTEXT_CLASS.
+/* DECL is the result of a qualified name lookup. QUALIFYING_SCOPE is
+ the class or namespace used to qualify the name. CONTEXT_CLASS is
+ the class corresponding to the object in which DECL will be used.
+ Return a possibly modified version of DECL that takes into account
+ the CONTEXT_CLASS.
In particular, consider an expression like `B::m' in the context of
a derived class `D'. If `B::m' has been resolved to a BASELINK,
@@ -1810,23 +1509,23 @@ lookup_fnfields_1 (tree type, tree name)
tree
adjust_result_of_qualified_name_lookup (tree decl,
- tree qualifying_class,
+ tree qualifying_scope,
tree context_class)
{
- my_friendly_assert (CLASS_TYPE_P (qualifying_class), 20020808);
- my_friendly_assert (CLASS_TYPE_P (context_class), 20020808);
-
- if (BASELINK_P (decl)
- && DERIVED_FROM_P (qualifying_class, context_class))
+ if (context_class && CLASS_TYPE_P (qualifying_scope)
+ && DERIVED_FROM_P (qualifying_scope, context_class)
+ && BASELINK_P (decl))
{
tree base;
- /* Look for the QUALIFYING_CLASS as a base of the CONTEXT_CLASS.
+ my_friendly_assert (CLASS_TYPE_P (context_class), 20020808);
+
+ /* Look for the QUALIFYING_SCOPE as a base of the CONTEXT_CLASS.
Because we do not yet know which function will be chosen by
overload resolution, we cannot yet check either accessibility
or ambiguity -- in either case, the choice of a static member
function might make the usage valid. */
- base = lookup_base (context_class, qualifying_class,
+ base = lookup_base (context_class, qualifying_scope,
ba_ignore | ba_quiet, NULL);
if (base)
{
@@ -1846,69 +1545,91 @@ adjust_result_of_qualified_name_lookup (tree decl,
type in the hierarchy, in a breadth-first preorder traversal.
If it ever returns a non-NULL value, that value is immediately
returned and the walk is terminated. At each node, FN is passed a
- BINFO indicating the path from the curently visited base-class to
+ BINFO indicating the path from the currently visited base-class to
TYPE. Before each base-class is walked QFN is called. If the
value returned is nonzero, the base-class is walked; otherwise it
is not. If QFN is NULL, it is treated as a function which always
returns 1. Both FN and QFN are passed the DATA whenever they are
- called. */
+ called.
+
+ Implementation notes: Uses a circular queue, which starts off on
+ the stack but gets moved to the malloc arena if it needs to be
+ enlarged. The underflow and overflow conditions are
+ indistinguishable except by context: if head == tail and we just
+ moved the head pointer, the queue is empty, but if we just moved
+ the tail pointer, the queue is full.
+ Start with enough room for ten concurrent base classes. That
+ will be enough for most hierarchies. */
+#define BFS_WALK_INITIAL_QUEUE_SIZE 10
static tree
-bfs_walk (binfo, fn, qfn, data)
- tree binfo;
- tree (*fn) PARAMS ((tree, void *));
- tree (*qfn) PARAMS ((tree, void *));
- void *data;
-{
- size_t head;
- size_t tail;
+bfs_walk (tree binfo,
+ tree (*fn) (tree, void *),
+ tree (*qfn) (tree, int, void *),
+ void *data)
+{
tree rval = NULL_TREE;
- /* An array of the base classes of BINFO. These will be built up in
- breadth-first order, except where QFN prunes the search. */
- varray_type bfs_bases;
- /* Start with enough room for ten base classes. That will be enough
- for most hierarchies. */
- VARRAY_TREE_INIT (bfs_bases, 10, "search_stack");
+ tree bases_initial[BFS_WALK_INITIAL_QUEUE_SIZE];
+ /* A circular queue of the base classes of BINFO. These will be
+ built up in breadth-first order, except where QFN prunes the
+ search. */
+ size_t head, tail;
+ size_t base_buffer_size = BFS_WALK_INITIAL_QUEUE_SIZE;
+ tree *base_buffer = bases_initial;
- /* Put the first type into the stack. */
- VARRAY_TREE (bfs_bases, 0) = binfo;
- tail = 1;
+ head = tail = 0;
+ base_buffer[tail++] = binfo;
- for (head = 0; head < tail; ++head)
+ while (head != tail)
{
- int i;
- int n_baselinks;
- tree binfos;
-
- /* Pull the next type out of the queue. */
- binfo = VARRAY_TREE (bfs_bases, head);
+ int n_bases, ix;
+ tree binfo = base_buffer[head++];
+ if (head == base_buffer_size)
+ head = 0;
- /* If this is the one we're looking for, we're done. */
- rval = (*fn) (binfo, data);
+ /* Is this the one we're looking for? If so, we're done. */
+ rval = fn (binfo, data);
if (rval)
- break;
+ goto done;
- /* Queue up the base types. */
- binfos = BINFO_BASETYPES (binfo);
- n_baselinks = binfos ? TREE_VEC_LENGTH (binfos): 0;
- for (i = 0; i < n_baselinks; i++)
+ n_bases = BINFO_N_BASETYPES (binfo);
+ for (ix = 0; ix != n_bases; ix++)
{
- tree base_binfo = TREE_VEC_ELT (binfos, i);
-
+ tree base_binfo;
+
if (qfn)
- base_binfo = (*qfn) (base_binfo, data);
-
- if (base_binfo)
+ base_binfo = (*qfn) (binfo, ix, data);
+ else
+ base_binfo = BINFO_BASETYPE (binfo, ix);
+
+ if (base_binfo)
{
- if (tail == VARRAY_SIZE (bfs_bases))
- VARRAY_GROW (bfs_bases, 2 * VARRAY_SIZE (bfs_bases));
- VARRAY_TREE (bfs_bases, tail) = base_binfo;
- ++tail;
+ base_buffer[tail++] = base_binfo;
+ if (tail == base_buffer_size)
+ tail = 0;
+ if (tail == head)
+ {
+ tree *new_buffer = xmalloc (2 * base_buffer_size
+ * sizeof (tree));
+ memcpy (&new_buffer[0], &base_buffer[0],
+ tail * sizeof (tree));
+ memcpy (&new_buffer[head + base_buffer_size],
+ &base_buffer[head],
+ (base_buffer_size - head) * sizeof (tree));
+ if (base_buffer_size != BFS_WALK_INITIAL_QUEUE_SIZE)
+ free (base_buffer);
+ base_buffer = new_buffer;
+ head += base_buffer_size;
+ base_buffer_size *= 2;
+ }
}
}
}
+ done:
+ if (base_buffer_size != BFS_WALK_INITIAL_QUEUE_SIZE)
+ free (base_buffer);
return rval;
}
@@ -1917,16 +1638,12 @@ bfs_walk (binfo, fn, qfn, data)
in postorder. */
tree
-dfs_walk_real (binfo, prefn, postfn, qfn, data)
- tree binfo;
- tree (*prefn) PARAMS ((tree, void *));
- tree (*postfn) PARAMS ((tree, void *));
- tree (*qfn) PARAMS ((tree, void *));
- void *data;
+dfs_walk_real (tree binfo,
+ tree (*prefn) (tree, void *),
+ tree (*postfn) (tree, void *),
+ tree (*qfn) (tree, int, void *),
+ void *data)
{
- int i;
- int n_baselinks;
- tree binfos;
tree rval = NULL_TREE;
/* Call the pre-order walking function. */
@@ -1938,20 +1655,24 @@ dfs_walk_real (binfo, prefn, postfn, qfn, data)
}
/* Process the basetypes. */
- binfos = BINFO_BASETYPES (binfo);
- n_baselinks = BINFO_N_BASETYPES (binfo);
- for (i = 0; i < n_baselinks; i++)
+ if (BINFO_BASETYPES (binfo))
{
- tree base_binfo = TREE_VEC_ELT (binfos, i);
-
- if (qfn)
- base_binfo = (*qfn) (base_binfo, data);
-
- if (base_binfo)
+ int i, n = TREE_VEC_LENGTH (BINFO_BASETYPES (binfo));
+ for (i = 0; i != n; i++)
{
- rval = dfs_walk_real (base_binfo, prefn, postfn, qfn, data);
- if (rval)
- return rval;
+ tree base_binfo;
+
+ if (qfn)
+ base_binfo = (*qfn) (binfo, i, data);
+ else
+ base_binfo = BINFO_BASETYPE (binfo, i);
+
+ if (base_binfo)
+ {
+ rval = dfs_walk_real (base_binfo, prefn, postfn, qfn, data);
+ if (rval)
+ return rval;
+ }
}
}
@@ -1966,73 +1687,19 @@ dfs_walk_real (binfo, prefn, postfn, qfn, data)
performed. */
tree
-dfs_walk (binfo, fn, qfn, data)
- tree binfo;
- tree (*fn) PARAMS ((tree, void *));
- tree (*qfn) PARAMS ((tree, void *));
- void *data;
+dfs_walk (tree binfo,
+ tree (*fn) (tree, void *),
+ tree (*qfn) (tree, int, void *),
+ void *data)
{
return dfs_walk_real (binfo, 0, fn, qfn, data);
}
-/* Returns > 0 if a function with type DRETTYPE overriding a function
- with type BRETTYPE is covariant, as defined in [class.virtual].
-
- Returns 1 if trivial covariance, 2 if non-trivial (requiring runtime
- adjustment), or -1 if pedantically invalid covariance. */
-
-static int
-covariant_return_p (brettype, drettype)
- tree brettype, drettype;
-{
- tree binfo;
- base_kind kind;
-
- if (TREE_CODE (brettype) == FUNCTION_DECL)
- {
- brettype = TREE_TYPE (TREE_TYPE (brettype));
- drettype = TREE_TYPE (TREE_TYPE (drettype));
- }
- else if (TREE_CODE (brettype) == METHOD_TYPE)
- {
- brettype = TREE_TYPE (brettype);
- drettype = TREE_TYPE (drettype);
- }
-
- if (same_type_p (brettype, drettype))
- return 0;
-
- if (! (TREE_CODE (brettype) == TREE_CODE (drettype)
- && (TREE_CODE (brettype) == POINTER_TYPE
- || TREE_CODE (brettype) == REFERENCE_TYPE)
- && TYPE_QUALS (brettype) == TYPE_QUALS (drettype)))
- return 0;
-
- if (! can_convert (brettype, drettype))
- return 0;
-
- brettype = TREE_TYPE (brettype);
- drettype = TREE_TYPE (drettype);
-
- /* If not pedantic, allow any standard pointer conversion. */
- if (! IS_AGGR_TYPE (drettype) || ! IS_AGGR_TYPE (brettype))
- return -1;
-
- binfo = lookup_base (drettype, brettype, ba_check | ba_quiet, &kind);
-
- if (!binfo)
- return 0;
- if (BINFO_OFFSET_ZEROP (binfo) && kind != bk_via_virtual)
- return 1;
- return 2;
-}
-
/* Check that virtual overrider OVERRIDER is acceptable for base function
BASEFN. Issue diagnostic, and return zero, if unacceptable. */
int
-check_final_overrider (overrider, basefn)
- tree overrider, basefn;
+check_final_overrider (tree overrider, tree basefn)
{
tree over_type = TREE_TYPE (overrider);
tree base_type = TREE_TYPE (basefn);
@@ -2040,32 +1707,72 @@ check_final_overrider (overrider, basefn)
tree base_return = TREE_TYPE (base_type);
tree over_throw = TYPE_RAISES_EXCEPTIONS (over_type);
tree base_throw = TYPE_RAISES_EXCEPTIONS (base_type);
- int i;
+ int fail = 0;
if (same_type_p (base_return, over_return))
/* OK */;
- else if ((i = covariant_return_p (base_return, over_return)))
+ else if ((CLASS_TYPE_P (over_return) && CLASS_TYPE_P (base_return))
+ || (TREE_CODE (base_return) == TREE_CODE (over_return)
+ && POINTER_TYPE_P (base_return)))
{
- if (i == 2)
- sorry ("adjusting pointers for covariant returns");
+ /* Potentially covariant. */
+ unsigned base_quals, over_quals;
+
+ fail = !POINTER_TYPE_P (base_return);
+ if (!fail)
+ {
+ fail = cp_type_quals (base_return) != cp_type_quals (over_return);
+
+ base_return = TREE_TYPE (base_return);
+ over_return = TREE_TYPE (over_return);
+ }
+ base_quals = cp_type_quals (base_return);
+ over_quals = cp_type_quals (over_return);
- if (pedantic && i == -1)
+ if ((base_quals & over_quals) != over_quals)
+ fail = 1;
+
+ if (CLASS_TYPE_P (base_return) && CLASS_TYPE_P (over_return))
{
- cp_pedwarn_at ("invalid covariant return type for `%#D'", overrider);
- cp_pedwarn_at (" overriding `%#D' (must be pointer or reference to class)", basefn);
+ tree binfo = lookup_base (over_return, base_return,
+ ba_check | ba_quiet, NULL);
+
+ if (!binfo)
+ fail = 1;
}
+ else if (!pedantic
+ && can_convert (TREE_TYPE (base_type), TREE_TYPE (over_type)))
+ /* GNU extension, allow trivial pointer conversions such as
+ converting to void *, or qualification conversion. */
+ {
+ /* can_convert will permit user defined conversion from a
+ (reference to) class type. We must reject them. */
+ over_return = non_reference (TREE_TYPE (over_type));
+ if (CLASS_TYPE_P (over_return))
+ fail = 2;
+ }
+ else
+ fail = 2;
}
- else if (IS_AGGR_TYPE_2 (base_return, over_return)
- && same_or_base_type_p (base_return, over_return))
- {
- cp_error_at ("invalid covariant return type for `%#D'", overrider);
- cp_error_at (" overriding `%#D' (must use pointer or reference)", basefn);
- return 0;
- }
- else if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider)) == NULL_TREE)
+ else
+ fail = 2;
+ if (!fail)
+ /* OK */;
+ else if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider)))
+ return 0;
+ else
{
- cp_error_at ("conflicting return type specified for `%#D'", overrider);
- cp_error_at (" overriding `%#D'", basefn);
+ if (fail == 1)
+ {
+ cp_error_at ("invalid covariant return type for `%#D'", overrider);
+ cp_error_at (" overriding `%#D'", basefn);
+ }
+ else
+ {
+ cp_error_at ("conflicting return type specified for `%#D'",
+ overrider);
+ cp_error_at (" overriding `%#D'", basefn);
+ }
SET_IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider),
DECL_CONTEXT (overrider));
return 0;
@@ -2074,10 +1781,16 @@ check_final_overrider (overrider, basefn)
/* Check throw specifier is at least as strict. */
if (!comp_except_specs (base_throw, over_throw, 0))
{
- cp_error_at ("looser throw specifier for `%#F'", overrider);
- cp_error_at (" overriding `%#F'", basefn);
+ if (!IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider)))
+ {
+ cp_error_at ("looser throw specifier for `%#F'", overrider);
+ cp_error_at (" overriding `%#F'", basefn);
+ SET_IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider),
+ DECL_CONTEXT (overrider));
+ }
return 0;
}
+
return 1;
}
@@ -2092,8 +1805,7 @@ check_final_overrider (overrider, basefn)
overridden. */
int
-look_for_overrides (type, fndecl)
- tree type, fndecl;
+look_for_overrides (tree type, tree fndecl)
{
tree binfo = TYPE_BINFO (type);
tree basebinfos = BINFO_BASETYPES (binfo);
@@ -2115,8 +1827,7 @@ look_for_overrides (type, fndecl)
FNDECL. */
tree
-look_for_overrides_here (type, fndecl)
- tree type, fndecl;
+look_for_overrides_here (tree type, tree fndecl)
{
int ix;
@@ -2154,8 +1865,7 @@ look_for_overrides_here (type, fndecl)
TYPE itself and its bases. */
static int
-look_for_overrides_r (type, fndecl)
- tree type, fndecl;
+look_for_overrides_r (tree type, tree fndecl)
{
tree fn = look_for_overrides_here (type, fndecl);
if (fn)
@@ -2180,71 +1890,10 @@ look_for_overrides_r (type, fndecl)
return look_for_overrides (type, fndecl);
}
-/* A queue function to use with dfs_walk that only walks into
- canonical bases. DATA should be the type of the complete object,
- or a TREE_LIST whose TREE_PURPOSE is the type of the complete
- object. By using this function as a queue function, you will walk
- over exactly those BINFOs that actually exist in the complete
- object, including those for virtual base classes. If you
- SET_BINFO_MARKED for each binfo you process, you are further
- guaranteed that you will walk into each virtual base class exactly
- once. */
-
-tree
-dfs_unmarked_real_bases_queue_p (binfo, data)
- tree binfo;
- void *data;
-{
- if (TREE_VIA_VIRTUAL (binfo))
- {
- tree type = (tree) data;
-
- if (TREE_CODE (type) == TREE_LIST)
- type = TREE_PURPOSE (type);
- binfo = binfo_for_vbase (BINFO_TYPE (binfo), type);
- }
- return unmarkedp (binfo, NULL);
-}
-
-/* Like dfs_unmarked_real_bases_queue_p but walks only into things
- that are marked, rather than unmarked. */
-
-tree
-dfs_marked_real_bases_queue_p (binfo, data)
- tree binfo;
- void *data;
-{
- if (TREE_VIA_VIRTUAL (binfo))
- {
- tree type = (tree) data;
-
- if (TREE_CODE (type) == TREE_LIST)
- type = TREE_PURPOSE (type);
- binfo = binfo_for_vbase (BINFO_TYPE (binfo), type);
- }
- return markedp (binfo, NULL);
-}
-
-/* A queue function that skips all virtual bases (and their
- bases). */
-
-tree
-dfs_skip_vbases (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
-{
- if (TREE_VIA_VIRTUAL (binfo))
- return NULL_TREE;
-
- return binfo;
-}
-
/* Called via dfs_walk from dfs_get_pure_virtuals. */
static tree
-dfs_get_pure_virtuals (binfo, data)
- tree binfo;
- void *data;
+dfs_get_pure_virtuals (tree binfo, void *data)
{
tree type = (tree) data;
@@ -2264,7 +1913,7 @@ dfs_get_pure_virtuals (binfo, data)
CLASSTYPE_PURE_VIRTUALS (type));
}
- SET_BINFO_MARKED (binfo);
+ BINFO_MARKED (binfo) = 1;
return NULL_TREE;
}
@@ -2272,8 +1921,7 @@ dfs_get_pure_virtuals (binfo, data)
/* Set CLASSTYPE_PURE_VIRTUALS for TYPE. */
void
-get_pure_virtuals (type)
- tree type;
+get_pure_virtuals (tree type)
{
tree vbases;
@@ -2286,10 +1934,8 @@ get_pure_virtuals (type)
(A primary base is not interesting because the derived class of
which it is a primary base will contain vtable entries for the
pure virtuals in the base class. */
- dfs_walk (TYPE_BINFO (type), dfs_get_pure_virtuals,
- dfs_unmarked_real_bases_queue_p, type);
- dfs_walk (TYPE_BINFO (type), dfs_unmark,
- dfs_marked_real_bases_queue_p, type);
+ dfs_walk (TYPE_BINFO (type), dfs_get_pure_virtuals, unmarkedp, type);
+ dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp, type);
/* Put the pure virtuals in dfs order. */
CLASSTYPE_PURE_VIRTUALS (type) = nreverse (CLASSTYPE_PURE_VIRTUALS (type));
@@ -2314,52 +1960,36 @@ get_pure_virtuals (type)
/* DEPTH-FIRST SEARCH ROUTINES. */
tree
-markedp (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
-{
+markedp (tree derived, int ix, void *data ATTRIBUTE_UNUSED)
+{
+ tree binfo = BINFO_BASETYPE (derived, ix);
+
return BINFO_MARKED (binfo) ? binfo : NULL_TREE;
}
tree
-unmarkedp (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
+unmarkedp (tree derived, int ix, void *data ATTRIBUTE_UNUSED)
{
- return !BINFO_MARKED (binfo) ? binfo : NULL_TREE;
-}
-
-tree
-marked_vtable_pathp (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
-{
- return BINFO_VTABLE_PATH_MARKED (binfo) ? binfo : NULL_TREE;
-}
-
-tree
-unmarked_vtable_pathp (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
-{
- return !BINFO_VTABLE_PATH_MARKED (binfo) ? binfo : NULL_TREE;
+ tree binfo = BINFO_BASETYPE (derived, ix);
+
+ return !BINFO_MARKED (binfo) ? binfo : NULL_TREE;
}
static tree
-marked_pushdecls_p (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
+marked_pushdecls_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED)
{
- return (CLASS_TYPE_P (BINFO_TYPE (binfo))
+ tree binfo = BINFO_BASETYPE (derived, ix);
+
+ return (!BINFO_DEPENDENT_BASE_P (binfo)
&& BINFO_PUSHDECLS_MARKED (binfo)) ? binfo : NULL_TREE;
}
static tree
-unmarked_pushdecls_p (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
+unmarked_pushdecls_p (tree derived, int ix, void *data ATTRIBUTE_UNUSED)
{
- return (CLASS_TYPE_P (BINFO_TYPE (binfo))
+ tree binfo = BINFO_BASETYPE (derived, ix);
+
+ return (!BINFO_DEPENDENT_BASE_P (binfo)
&& !BINFO_PUSHDECLS_MARKED (binfo)) ? binfo : NULL_TREE;
}
@@ -2368,111 +1998,12 @@ unmarked_pushdecls_p (binfo, data)
a predicate function (above). */
tree
-dfs_unmark (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
-{
- CLEAR_BINFO_MARKED (binfo);
- return NULL_TREE;
-}
-
-/* get virtual base class types.
- This adds type to the vbase_types list in reverse dfs order.
- Ordering is very important, so don't change it. */
-
-static tree
-dfs_get_vbase_types (binfo, data)
- tree binfo;
- void *data;
-{
- tree type = (tree) data;
-
- if (TREE_VIA_VIRTUAL (binfo))
- CLASSTYPE_VBASECLASSES (type)
- = tree_cons (BINFO_TYPE (binfo),
- binfo,
- CLASSTYPE_VBASECLASSES (type));
- SET_BINFO_MARKED (binfo);
- return NULL_TREE;
-}
-
-/* Called via dfs_walk from mark_primary_bases. Builds the
- inheritance graph order list of BINFOs. */
-
-static tree
-dfs_build_inheritance_graph_order (binfo, data)
- tree binfo;
- void *data;
-{
- tree *last_binfo = (tree *) data;
-
- if (*last_binfo)
- TREE_CHAIN (*last_binfo) = binfo;
- *last_binfo = binfo;
- SET_BINFO_MARKED (binfo);
- return NULL_TREE;
-}
-
-/* Set CLASSTYPE_VBASECLASSES for TYPE. */
-
-void
-get_vbase_types (type)
- tree type;
-{
- tree last_binfo;
-
- CLASSTYPE_VBASECLASSES (type) = NULL_TREE;
- dfs_walk (TYPE_BINFO (type), dfs_get_vbase_types, unmarkedp, type);
- /* Rely upon the reverse dfs ordering from dfs_get_vbase_types, and now
- reverse it so that we get normal dfs ordering. */
- CLASSTYPE_VBASECLASSES (type) = nreverse (CLASSTYPE_VBASECLASSES (type));
- dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp, 0);
- /* Thread the BINFOs in inheritance-graph order. */
- last_binfo = NULL;
- dfs_walk_real (TYPE_BINFO (type),
- dfs_build_inheritance_graph_order,
- NULL,
- unmarkedp,
- &last_binfo);
- dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp, NULL);
-}
-
-/* Called from find_vbase_instance via dfs_walk. */
-
-static tree
-dfs_find_vbase_instance (binfo, data)
- tree binfo;
- void *data;
+dfs_unmark (tree binfo, void *data ATTRIBUTE_UNUSED)
{
- tree base = TREE_VALUE ((tree) data);
-
- if (BINFO_PRIMARY_P (binfo)
- && same_type_p (BINFO_TYPE (binfo), base))
- return binfo;
-
+ BINFO_MARKED (binfo) = 0;
return NULL_TREE;
}
-/* Find the real occurrence of the virtual BASE (a class type) in the
- hierarchy dominated by TYPE. */
-
-tree
-find_vbase_instance (base, type)
- tree base;
- tree type;
-{
- tree instance;
-
- instance = binfo_for_vbase (base, type);
- if (!BINFO_PRIMARY_P (instance))
- return instance;
-
- return dfs_walk (TYPE_BINFO (type),
- dfs_find_vbase_instance,
- NULL,
- build_tree_list (type, base));
-}
-
/* Debug info for C++ classes can get very large; try to avoid
emitting it everywhere.
@@ -2482,8 +2013,7 @@ find_vbase_instance (base, type)
linker. */
void
-maybe_suppress_debug_info (t)
- tree t;
+maybe_suppress_debug_info (tree t)
{
/* We can't do the usual TYPE_DECL_SUPPRESS_DEBUG thing with DWARF, which
does not support name references between translation units. It supports
@@ -2525,9 +2055,7 @@ maybe_suppress_debug_info (t)
information anyway. */
static tree
-dfs_debug_mark (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
+dfs_debug_mark (tree binfo, void *data ATTRIBUTE_UNUSED)
{
tree t = BINFO_TYPE (binfo);
@@ -2540,10 +2068,10 @@ dfs_debug_mark (binfo, data)
info for this base class. */
static tree
-dfs_debug_unmarkedp (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
-{
+dfs_debug_unmarkedp (tree derived, int ix, void *data ATTRIBUTE_UNUSED)
+{
+ tree binfo = BINFO_BASETYPE (derived, ix);
+
return (!CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo))
? binfo : NULL_TREE);
}
@@ -2556,8 +2084,7 @@ dfs_debug_unmarkedp (binfo, data)
the vtables themselves, were optimized away. */
void
-note_debug_info_needed (type)
- tree type;
+note_debug_info_needed (tree type)
{
if (TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (type)))
{
@@ -2570,27 +2097,8 @@ note_debug_info_needed (type)
/* Subroutines of push_class_decls (). */
-/* Returns 1 iff BINFO is a base we shouldn't really be able to see into,
- because it (or one of the intermediate bases) depends on template parms. */
-
-static int
-dependent_base_p (binfo)
- tree binfo;
-{
- for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo))
- {
- if (currently_open_class (TREE_TYPE (binfo)))
- break;
- if (uses_template_parms (TREE_TYPE (binfo)))
- return 1;
- }
- return 0;
-}
-
static void
-setup_class_bindings (name, type_binding_p)
- tree name;
- int type_binding_p;
+setup_class_bindings (tree name, int type_binding_p)
{
tree type_binding = NULL_TREE;
tree value_binding;
@@ -2604,8 +2112,7 @@ setup_class_bindings (name, type_binding_p)
if (type_binding_p)
{
type_binding = lookup_member (current_class_type, name,
- /*protect=*/2,
- /*want_type=*/1);
+ /*protect=*/2, /*want_type=*/true);
if (TREE_CODE (type_binding) == TREE_LIST
&& TREE_TYPE (type_binding) == error_mark_node)
/* NAME is ambiguous. */
@@ -2616,8 +2123,7 @@ setup_class_bindings (name, type_binding_p)
/* Now, do the value binding. */
value_binding = lookup_member (current_class_type, name,
- /*protect=*/2,
- /*want_type=*/0);
+ /*protect=*/2, /*want_type=*/false);
if (type_binding_p
&& (TREE_CODE (value_binding) == TYPE_DECL
@@ -2663,9 +2169,7 @@ setup_class_bindings (name, type_binding_p)
are TYPE_DECLS. */
static tree
-dfs_push_type_decls (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
+dfs_push_type_decls (tree binfo, void *data ATTRIBUTE_UNUSED)
{
tree type;
tree fields;
@@ -2679,7 +2183,7 @@ dfs_push_type_decls (binfo, data)
/* We can't just use BINFO_MARKED because envelope_add_decl uses
DERIVED_FROM_P, which calls get_base_distance. */
- SET_BINFO_PUSHDECLS_MARKED (binfo);
+ BINFO_PUSHDECLS_MARKED (binfo) = 1;
return NULL_TREE;
}
@@ -2688,50 +2192,41 @@ dfs_push_type_decls (binfo, data)
are not TYPE_DECLS. */
static tree
-dfs_push_decls (binfo, data)
- tree binfo;
- void *data;
+dfs_push_decls (tree binfo, void *data)
{
- tree type;
+ tree type = BINFO_TYPE (binfo);
tree method_vec;
- int dep_base_p;
-
- type = BINFO_TYPE (binfo);
- dep_base_p = (processing_template_decl && type != current_class_type
- && dependent_base_p (binfo));
- if (!dep_base_p)
+ tree fields;
+
+ for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
+ if (DECL_NAME (fields)
+ && TREE_CODE (fields) != TYPE_DECL
+ && TREE_CODE (fields) != USING_DECL
+ && !DECL_ARTIFICIAL (fields))
+ setup_class_bindings (DECL_NAME (fields), /*type_binding_p=*/0);
+ else if (TREE_CODE (fields) == FIELD_DECL
+ && ANON_AGGR_TYPE_P (TREE_TYPE (fields)))
+ dfs_push_decls (TYPE_BINFO (TREE_TYPE (fields)), data);
+
+ method_vec = (CLASS_TYPE_P (type)
+ ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE);
+
+ if (method_vec && TREE_VEC_LENGTH (method_vec) >= 3)
{
- tree fields;
- for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
- if (DECL_NAME (fields)
- && TREE_CODE (fields) != TYPE_DECL
- && TREE_CODE (fields) != USING_DECL
- && !DECL_ARTIFICIAL (fields))
- setup_class_bindings (DECL_NAME (fields), /*type_binding_p=*/0);
- else if (TREE_CODE (fields) == FIELD_DECL
- && ANON_AGGR_TYPE_P (TREE_TYPE (fields)))
- dfs_push_decls (TYPE_BINFO (TREE_TYPE (fields)), data);
-
- method_vec = (CLASS_TYPE_P (type)
- ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE);
-
- if (method_vec && TREE_VEC_LENGTH (method_vec) >= 3)
- {
- tree *methods;
- tree *end;
-
- /* Farm out constructors and destructors. */
- end = TREE_VEC_END (method_vec);
-
- for (methods = &TREE_VEC_ELT (method_vec, 2);
- methods < end && *methods;
- methods++)
- setup_class_bindings (DECL_NAME (OVL_CURRENT (*methods)),
- /*type_binding_p=*/0);
- }
+ tree *methods;
+ tree *end;
+
+ /* Farm out constructors and destructors. */
+ end = TREE_VEC_END (method_vec);
+
+ for (methods = &TREE_VEC_ELT (method_vec, 2);
+ methods < end && *methods;
+ methods++)
+ setup_class_bindings (DECL_NAME (OVL_CURRENT (*methods)),
+ /*type_binding_p=*/0);
}
- CLEAR_BINFO_PUSHDECLS_MARKED (binfo);
+ BINFO_PUSHDECLS_MARKED (binfo) = 0;
return NULL_TREE;
}
@@ -2744,8 +2239,7 @@ dfs_push_decls (binfo, data)
message. */
void
-push_class_decls (type)
- tree type;
+push_class_decls (tree type)
{
search_stack = push_search_level (search_stack, &search_obstack);
@@ -2759,9 +2253,7 @@ push_class_decls (type)
/* Here's a subroutine we need because C lacks lambdas. */
static tree
-dfs_unuse_fields (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
+dfs_unuse_fields (tree binfo, void *data ATTRIBUTE_UNUSED)
{
tree type = TREE_TYPE (binfo);
tree fields;
@@ -2781,14 +2273,13 @@ dfs_unuse_fields (binfo, data)
}
void
-unuse_fields (type)
- tree type;
+unuse_fields (tree type)
{
dfs_walk (TYPE_BINFO (type), dfs_unuse_fields, unmarkedp, 0);
}
void
-pop_class_decls ()
+pop_class_decls (void)
{
/* We haven't pushed a search level when dealing with cached classes,
so we'd better not try to pop it. */
@@ -2797,7 +2288,7 @@ pop_class_decls ()
}
void
-print_search_statistics ()
+print_search_statistics (void)
{
#ifdef GATHER_STATISTICS
fprintf (stderr, "%d fields searched in %d[%d] calls to lookup_field[_1]\n",
@@ -2811,13 +2302,13 @@ print_search_statistics ()
}
void
-init_search_processing ()
+init_search_processing (void)
{
gcc_obstack_init (&search_obstack);
}
void
-reinit_search_statistics ()
+reinit_search_statistics (void)
{
#ifdef GATHER_STATISTICS
n_fields_searched = 0;
@@ -2830,9 +2321,7 @@ reinit_search_statistics ()
}
static tree
-add_conversions (binfo, data)
- tree binfo;
- void *data;
+add_conversions (tree binfo, void *data)
{
int i;
tree method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo));
@@ -2888,8 +2377,7 @@ add_conversions (binfo, data)
from which the conversion functions in this node were selected. */
tree
-lookup_conversions (type)
- tree type;
+lookup_conversions (tree type)
{
tree t;
tree conversions = NULL_TREE;
@@ -2913,9 +2401,7 @@ struct overlap_info
at offset 0 in COMPARE_TYPE, and set found_overlap if so. */
static tree
-dfs_check_overlap (empty_binfo, data)
- tree empty_binfo;
- void *data;
+dfs_check_overlap (tree empty_binfo, void *data)
{
struct overlap_info *oi = (struct overlap_info *) data;
tree binfo;
@@ -2938,11 +2424,11 @@ dfs_check_overlap (empty_binfo, data)
/* Trivial function to stop base traversal when we find something. */
static tree
-dfs_no_overlap_yet (binfo, data)
- tree binfo;
- void *data;
+dfs_no_overlap_yet (tree derived, int ix, void *data)
{
+ tree binfo = BINFO_BASETYPE (derived, ix);
struct overlap_info *oi = (struct overlap_info *) data;
+
return !oi->found_overlap ? binfo : NULL_TREE;
}
@@ -2950,8 +2436,7 @@ dfs_no_overlap_yet (binfo, data)
offset 0 in NEXT_TYPE. Used in laying out empty base class subobjects. */
int
-types_overlap_p (empty_type, next_type)
- tree empty_type, next_type;
+types_overlap_p (tree empty_type, tree next_type)
{
struct overlap_info oi;
@@ -2970,8 +2455,7 @@ types_overlap_p (empty_type, next_type)
FIXME: This does not work with the new ABI. */
tree
-binfo_for_vtable (var)
- tree var;
+binfo_for_vtable (tree var)
{
tree main_binfo = TYPE_BINFO (DECL_CONTEXT (var));
tree binfos = TYPE_BINFO_BASETYPES (BINFO_TYPE (main_binfo));
@@ -2997,8 +2481,7 @@ binfo_for_vtable (var)
from BINFO, or NULL if binfo is not via virtual. */
tree
-binfo_from_vbase (binfo)
- tree binfo;
+binfo_from_vbase (tree binfo)
{
for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo))
{
@@ -3013,9 +2496,7 @@ binfo_from_vbase (binfo)
via virtual. */
tree
-binfo_via_virtual (binfo, limit)
- tree binfo;
- tree limit;
+binfo_via_virtual (tree binfo, tree limit)
{
for (; binfo && (!limit || !same_type_p (BINFO_TYPE (binfo), limit));
binfo = BINFO_INHERITANCE_CHAIN (binfo))
@@ -3026,16 +2507,99 @@ binfo_via_virtual (binfo, limit)
return NULL_TREE;
}
-/* Returns the BINFO (if any) for the virtual baseclass T of the class
- C from the CLASSTYPE_VBASECLASSES list. */
+/* BINFO is a base binfo in the complete type BINFO_TYPE (HERE).
+ Find the equivalent binfo within whatever graph HERE is located.
+ This is the inverse of original_binfo. */
tree
-binfo_for_vbase (basetype, classtype)
- tree basetype;
- tree classtype;
+copied_binfo (tree binfo, tree here)
{
- tree binfo;
+ tree result = NULL_TREE;
+
+ if (TREE_VIA_VIRTUAL (binfo))
+ {
+ tree t;
+
+ for (t = here; BINFO_INHERITANCE_CHAIN (t);
+ t = BINFO_INHERITANCE_CHAIN (t))
+ continue;
+
+ result = purpose_member (BINFO_TYPE (binfo),
+ CLASSTYPE_VBASECLASSES (BINFO_TYPE (t)));
+ result = TREE_VALUE (result);
+ }
+ else if (BINFO_INHERITANCE_CHAIN (binfo))
+ {
+ tree base_binfos;
+ int ix, n;
+
+ base_binfos = copied_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
+ base_binfos = BINFO_BASETYPES (base_binfos);
+ n = TREE_VEC_LENGTH (base_binfos);
+ for (ix = 0; ix != n; ix++)
+ {
+ tree base = TREE_VEC_ELT (base_binfos, ix);
+
+ if (BINFO_TYPE (base) == BINFO_TYPE (binfo))
+ {
+ result = base;
+ break;
+ }
+ }
+ }
+ else
+ {
+ my_friendly_assert (BINFO_TYPE (here) == BINFO_TYPE (binfo), 20030202);
+ result = here;
+ }
- binfo = purpose_member (basetype, CLASSTYPE_VBASECLASSES (classtype));
- return binfo ? TREE_VALUE (binfo) : NULL_TREE;
+ my_friendly_assert (result, 20030202);
+ return result;
}
+
+/* BINFO is some base binfo of HERE, within some other
+ hierarchy. Return the equivalent binfo, but in the hierarchy
+ dominated by HERE. This is the inverse of copied_binfo. If BINFO
+ is not a base binfo of HERE, returns NULL_TREE. */
+
+tree
+original_binfo (tree binfo, tree here)
+{
+ tree result = NULL;
+
+ if (BINFO_TYPE (binfo) == BINFO_TYPE (here))
+ result = here;
+ else if (TREE_VIA_VIRTUAL (binfo))
+ {
+ result = purpose_member (BINFO_TYPE (binfo),
+ CLASSTYPE_VBASECLASSES (BINFO_TYPE (here)));
+ if (result)
+ result = TREE_VALUE (result);
+ }
+ else if (BINFO_INHERITANCE_CHAIN (binfo))
+ {
+ tree base_binfos;
+
+ base_binfos = original_binfo (BINFO_INHERITANCE_CHAIN (binfo), here);
+ if (base_binfos)
+ {
+ int ix, n;
+
+ base_binfos = BINFO_BASETYPES (base_binfos);
+ n = TREE_VEC_LENGTH (base_binfos);
+ for (ix = 0; ix != n; ix++)
+ {
+ tree base = TREE_VEC_ELT (base_binfos, ix);
+
+ if (BINFO_TYPE (base) == BINFO_TYPE (binfo))
+ {
+ result = base;
+ break;
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
diff --git a/contrib/gcc/cp/semantics.c b/contrib/gcc/cp/semantics.c
index 110eb3a9e7ab..966b004ddfa5 100644
--- a/contrib/gcc/cp/semantics.c
+++ b/contrib/gcc/cp/semantics.c
@@ -3,29 +3,32 @@
building RTL. These routines are used both during actual parsing
and during the instantiation of template functions.
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004 Free Software Foundation, Inc.
Written by Mark Mitchell (mmitchell@usa.net) based on code found
formerly in parse.y and pt.c.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify it
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful, but
+ 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 GNU CC; see the file COPYING. If not, write to the Free
+ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "tree-inline.h"
@@ -33,12 +36,12 @@
#include "lex.h"
#include "toplev.h"
#include "flags.h"
-#include "ggc.h"
#include "rtl.h"
#include "expr.h"
#include "output.h"
#include "timevar.h"
#include "debug.h"
+#include "cgraph.h"
/* There routines provide a modular interface to perform many parsing
operations. They may therefore be used during actual parsing, or
@@ -49,18 +52,14 @@
parsing into this file; that will make implementing the new parser
much easier since it will be able to make use of these routines. */
-static tree maybe_convert_cond PARAMS ((tree));
-static tree simplify_aggr_init_exprs_r PARAMS ((tree *, int *, void *));
-static void deferred_type_access_control PARAMS ((void));
-static void emit_associated_thunks PARAMS ((tree));
-static void genrtl_try_block PARAMS ((tree));
-static void genrtl_eh_spec_block PARAMS ((tree));
-static void genrtl_handler PARAMS ((tree));
-static void genrtl_named_return_value PARAMS ((void));
-static void cp_expand_stmt PARAMS ((tree));
-static void genrtl_start_function PARAMS ((tree));
-static void genrtl_finish_function PARAMS ((tree));
-static tree clear_decl_rtl PARAMS ((tree *, int *, void *));
+static tree maybe_convert_cond (tree);
+static tree simplify_aggr_init_exprs_r (tree *, int *, void *);
+static void emit_associated_thunks (tree);
+static void genrtl_try_block (tree);
+static void genrtl_eh_spec_block (tree);
+static void genrtl_handler (tree);
+static void cp_expand_stmt (tree);
+
/* Finish processing the COND, the SUBSTMT condition for STMT. */
@@ -79,12 +78,233 @@ static tree clear_decl_rtl PARAMS ((tree *, int *, void *));
(SUBSTMT) = (COND); \
} while (0)
+/* Deferred Access Checking Overview
+ ---------------------------------
+
+ Most C++ expressions and declarations require access checking
+ to be performed during parsing. However, in several cases,
+ this has to be treated differently.
+
+ For member declarations, access checking has to be deferred
+ until more information about the declaration is known. For
+ example:
+
+ class A {
+ typedef int X;
+ public:
+ X f();
+ };
+
+ A::X A::f();
+ A::X g();
+
+ When we are parsing the function return type `A::X', we don't
+ really know if this is allowed until we parse the function name.
+
+ Furthermore, some contexts require that access checking is
+ never performed at all. These include class heads, and template
+ instantiations.
+
+ Typical use of access checking functions is described here:
+
+ 1. When we enter a context that requires certain access checking
+ mode, the function `push_deferring_access_checks' is called with
+ DEFERRING argument specifying the desired mode. Access checking
+ may be performed immediately (dk_no_deferred), deferred
+ (dk_deferred), or not performed (dk_no_check).
+
+ 2. When a declaration such as a type, or a variable, is encountered,
+ the function `perform_or_defer_access_check' is called. It
+ maintains a TREE_LIST of all deferred checks.
+
+ 3. The global `current_class_type' or `current_function_decl' is then
+ setup by the parser. `enforce_access' relies on these information
+ to check access.
+
+ 4. Upon exiting the context mentioned in step 1,
+ `perform_deferred_access_checks' is called to check all declaration
+ stored in the TREE_LIST. `pop_deferring_access_checks' is then
+ called to restore the previous access checking mode.
+
+ In case of parsing error, we simply call `pop_deferring_access_checks'
+ without `perform_deferred_access_checks'. */
+
+/* Data for deferred access checking. */
+static GTY(()) deferred_access *deferred_access_stack;
+static GTY(()) deferred_access *deferred_access_free_list;
+
+/* Save the current deferred access states and start deferred
+ access checking iff DEFER_P is true. */
+
+void
+push_deferring_access_checks (deferring_kind deferring)
+{
+ deferred_access *d;
+
+ /* For context like template instantiation, access checking
+ disabling applies to all nested context. */
+ if (deferred_access_stack
+ && deferred_access_stack->deferring_access_checks_kind == dk_no_check)
+ deferring = dk_no_check;
+
+ /* Recycle previously used free store if available. */
+ if (deferred_access_free_list)
+ {
+ d = deferred_access_free_list;
+ deferred_access_free_list = d->next;
+ }
+ else
+ d = ggc_alloc (sizeof (deferred_access));
+
+ d->next = deferred_access_stack;
+ d->deferred_access_checks = NULL_TREE;
+ d->deferring_access_checks_kind = deferring;
+ deferred_access_stack = d;
+}
+
+/* Resume deferring access checks again after we stopped doing
+ this previously. */
+
+void
+resume_deferring_access_checks (void)
+{
+ if (deferred_access_stack->deferring_access_checks_kind == dk_no_deferred)
+ deferred_access_stack->deferring_access_checks_kind = dk_deferred;
+}
+
+/* Stop deferring access checks. */
+
+void
+stop_deferring_access_checks (void)
+{
+ if (deferred_access_stack->deferring_access_checks_kind == dk_deferred)
+ deferred_access_stack->deferring_access_checks_kind = dk_no_deferred;
+}
+
+/* Discard the current deferred access checks and restore the
+ previous states. */
+
+void
+pop_deferring_access_checks (void)
+{
+ deferred_access *d = deferred_access_stack;
+ deferred_access_stack = d->next;
+
+ /* Remove references to access checks TREE_LIST. */
+ d->deferred_access_checks = NULL_TREE;
+
+ /* Store in free list for later use. */
+ d->next = deferred_access_free_list;
+ deferred_access_free_list = d;
+}
+
+/* Returns a TREE_LIST representing the deferred checks.
+ The TREE_PURPOSE of each node is the type through which the
+ access occurred; the TREE_VALUE is the declaration named.
+ */
+
+tree
+get_deferred_access_checks (void)
+{
+ return deferred_access_stack->deferred_access_checks;
+}
+
+/* Take current deferred checks and combine with the
+ previous states if we also defer checks previously.
+ Otherwise perform checks now. */
+
+void
+pop_to_parent_deferring_access_checks (void)
+{
+ tree deferred_check = get_deferred_access_checks ();
+ deferred_access *d1 = deferred_access_stack;
+ deferred_access *d2 = deferred_access_stack->next;
+ deferred_access *d3 = deferred_access_stack->next->next;
+
+ /* Temporary swap the order of the top two states, just to make
+ sure the garbage collector will not reclaim the memory during
+ processing below. */
+ deferred_access_stack = d2;
+ d2->next = d1;
+ d1->next = d3;
+
+ for ( ; deferred_check; deferred_check = TREE_CHAIN (deferred_check))
+ /* Perform deferred check if required. */
+ perform_or_defer_access_check (TREE_PURPOSE (deferred_check),
+ TREE_VALUE (deferred_check));
+
+ deferred_access_stack = d1;
+ d1->next = d2;
+ d2->next = d3;
+ pop_deferring_access_checks ();
+}
+
+/* Perform the deferred access checks.
+
+ After performing the checks, we still have to keep the list
+ `deferred_access_stack->deferred_access_checks' since we may want
+ to check access for them again later in a different context.
+ For example:
+
+ class A {
+ typedef int X;
+ static X a;
+ };
+ A::X A::a, x; // No error for `A::a', error for `x'
+
+ We have to perform deferred access of `A::X', first with `A::a',
+ next with `x'. */
+
+void
+perform_deferred_access_checks (void)
+{
+ tree deferred_check;
+ for (deferred_check = deferred_access_stack->deferred_access_checks;
+ deferred_check;
+ deferred_check = TREE_CHAIN (deferred_check))
+ /* Check access. */
+ enforce_access (TREE_PURPOSE (deferred_check),
+ TREE_VALUE (deferred_check));
+}
+
+/* Defer checking the accessibility of DECL, when looked up in
+ BINFO. */
+
+void
+perform_or_defer_access_check (tree binfo, tree decl)
+{
+ tree check;
+
+ my_friendly_assert (TREE_CODE (binfo) == TREE_VEC, 20030623);
+
+ /* If we are not supposed to defer access checks, just check now. */
+ if (deferred_access_stack->deferring_access_checks_kind == dk_no_deferred)
+ {
+ enforce_access (binfo, decl);
+ return;
+ }
+ /* Exit if we are in a context that no access checking is performed. */
+ else if (deferred_access_stack->deferring_access_checks_kind == dk_no_check)
+ return;
+
+ /* See if we are already going to perform this check. */
+ for (check = deferred_access_stack->deferred_access_checks;
+ check;
+ check = TREE_CHAIN (check))
+ if (TREE_VALUE (check) == decl && TREE_PURPOSE (check) == binfo)
+ return;
+ /* If not, record the check. */
+ deferred_access_stack->deferred_access_checks
+ = tree_cons (binfo, decl,
+ deferred_access_stack->deferred_access_checks);
+}
+
/* Returns nonzero if the current statement is a full expression,
i.e. temporaries created during that statement should be destroyed
at the end of the statement. */
int
-stmts_are_full_exprs_p ()
+stmts_are_full_exprs_p (void)
{
return current_stmt_tree ()->stmts_are_full_exprs_p;
}
@@ -94,7 +314,7 @@ stmts_are_full_exprs_p ()
returned. */
stmt_tree
-current_stmt_tree ()
+current_stmt_tree (void)
{
return (cfun
? &cfun->language->base.x_stmt_tree
@@ -106,8 +326,7 @@ current_stmt_tree ()
declared is not an anonymous union" [class.union]. */
int
-anon_aggr_type_p (node)
- tree node;
+anon_aggr_type_p (tree node)
{
return ANON_AGGR_TYPE_P (node);
}
@@ -115,7 +334,7 @@ anon_aggr_type_p (node)
/* Finish a scope. */
tree
-do_poplevel ()
+do_poplevel (void)
{
tree block = NULL_TREE;
@@ -123,14 +342,17 @@ do_poplevel ()
{
tree scope_stmts = NULL_TREE;
- if (!processing_template_decl)
- scope_stmts = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
-
block = poplevel (kept_level_p (), 1, 0);
- if (block && !processing_template_decl)
+ if (!processing_template_decl)
{
- SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block;
- SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block;
+ /* This needs to come after the poplevel so that partial scopes
+ are properly nested. */
+ scope_stmts = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
+ if (block)
+ {
+ SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmts)) = block;
+ SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmts)) = block;
+ }
}
}
@@ -140,21 +362,20 @@ do_poplevel ()
/* Begin a new scope. */
void
-do_pushlevel ()
+do_pushlevel (scope_kind sk)
{
if (stmts_are_full_exprs_p ())
{
- pushlevel (0);
if (!processing_template_decl)
add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
+ begin_scope (sk, NULL);
}
}
/* Finish a goto-statement. */
tree
-finish_goto_stmt (destination)
- tree destination;
+finish_goto_stmt (tree destination)
{
if (TREE_CODE (destination) == IDENTIFIER_NODE)
destination = lookup_label (destination);
@@ -163,13 +384,17 @@ finish_goto_stmt (destination)
mark the used labels as used. */
if (TREE_CODE (destination) == LABEL_DECL)
TREE_USED (destination) = 1;
-
- if (TREE_CODE (destination) != LABEL_DECL)
- /* We don't inline calls to functions with computed gotos.
- Those functions are typically up to some funny business,
- and may be depending on the labels being at particular
- addresses, or some such. */
- DECL_UNINLINABLE (current_function_decl) = 1;
+ else
+ {
+ /* The DESTINATION is being used as an rvalue. */
+ if (!processing_template_decl)
+ destination = decay_conversion (destination);
+ /* We don't inline calls to functions with computed gotos.
+ Those functions are typically up to some funny business,
+ and may be depending on the labels being at particular
+ addresses, or some such. */
+ DECL_UNINLINABLE (current_function_decl) = 1;
+ }
check_goto (destination);
@@ -179,9 +404,8 @@ finish_goto_stmt (destination)
/* COND is the condition-expression for an if, while, etc.,
statement. Convert it to a boolean value, if appropriate. */
-tree
-maybe_convert_cond (cond)
- tree cond;
+static tree
+maybe_convert_cond (tree cond)
{
/* Empty conditions remain empty. */
if (!cond)
@@ -199,36 +423,22 @@ maybe_convert_cond (cond)
/* Finish an expression-statement, whose EXPRESSION is as indicated. */
tree
-finish_expr_stmt (expr)
- tree expr;
+finish_expr_stmt (tree expr)
{
tree r = NULL_TREE;
- tree expr_type = NULL_TREE;;
if (expr != NULL_TREE)
{
- if (!processing_template_decl
- && !(stmts_are_full_exprs_p ())
- && ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE
- && lvalue_p (expr))
- || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE))
- expr = default_conversion (expr);
-
- /* Remember the type of the expression. */
- expr_type = TREE_TYPE (expr);
-
- if (stmts_are_full_exprs_p ())
+ if (!processing_template_decl)
expr = convert_to_void (expr, "statement");
+ else if (!type_dependent_expression_p (expr))
+ convert_to_void (build_non_dependent_expr (expr), "statement");
r = add_stmt (build_stmt (EXPR_STMT, expr));
}
finish_stmt ();
- /* This was an expression-statement, so we save the type of the
- expression. */
- last_expr_type = expr_type;
-
return r;
}
@@ -237,10 +447,10 @@ finish_expr_stmt (expr)
appropriate. */
tree
-begin_if_stmt ()
+begin_if_stmt (void)
{
tree r;
- do_pushlevel ();
+ do_pushlevel (sk_block);
r = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
add_stmt (r);
return r;
@@ -250,9 +460,7 @@ begin_if_stmt ()
IF_STMT. */
void
-finish_if_stmt_cond (cond, if_stmt)
- tree cond;
- tree if_stmt;
+finish_if_stmt_cond (tree cond, tree if_stmt)
{
cond = maybe_convert_cond (cond);
FINISH_COND (cond, if_stmt, IF_COND (if_stmt));
@@ -262,8 +470,7 @@ finish_if_stmt_cond (cond, if_stmt)
IF_STMT. */
tree
-finish_then_clause (if_stmt)
- tree if_stmt;
+finish_then_clause (tree if_stmt)
{
RECHAIN_STMTS (if_stmt, THEN_CLAUSE (if_stmt));
return if_stmt;
@@ -272,7 +479,7 @@ finish_then_clause (if_stmt)
/* Begin the else-clause of an if-statement. */
void
-begin_else_clause ()
+begin_else_clause (void)
{
}
@@ -280,8 +487,7 @@ begin_else_clause ()
IF_STMT. */
void
-finish_else_clause (if_stmt)
- tree if_stmt;
+finish_else_clause (tree if_stmt)
{
RECHAIN_STMTS (if_stmt, ELSE_CLAUSE (if_stmt));
}
@@ -289,7 +495,7 @@ finish_else_clause (if_stmt)
/* Finish an if-statement. */
void
-finish_if_stmt ()
+finish_if_stmt (void)
{
finish_stmt ();
do_poplevel ();
@@ -299,12 +505,12 @@ finish_if_stmt ()
appropriate. */
tree
-begin_while_stmt ()
+begin_while_stmt (void)
{
tree r;
r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE);
add_stmt (r);
- do_pushlevel ();
+ do_pushlevel (sk_block);
return r;
}
@@ -312,9 +518,7 @@ begin_while_stmt ()
WHILE_STMT. */
void
-finish_while_stmt_cond (cond, while_stmt)
- tree cond;
- tree while_stmt;
+finish_while_stmt_cond (tree cond, tree while_stmt)
{
cond = maybe_convert_cond (cond);
if (processing_template_decl)
@@ -345,8 +549,7 @@ finish_while_stmt_cond (cond, while_stmt)
/* Finish a while-statement, which may be given by WHILE_STMT. */
void
-finish_while_stmt (while_stmt)
- tree while_stmt;
+finish_while_stmt (tree while_stmt)
{
do_poplevel ();
RECHAIN_STMTS (while_stmt, WHILE_BODY (while_stmt));
@@ -357,7 +560,7 @@ finish_while_stmt (while_stmt)
appropriate. */
tree
-begin_do_stmt ()
+begin_do_stmt (void)
{
tree r = build_stmt (DO_STMT, NULL_TREE, NULL_TREE);
add_stmt (r);
@@ -367,8 +570,7 @@ begin_do_stmt ()
/* Finish the body of a do-statement, which may be given by DO_STMT. */
void
-finish_do_body (do_stmt)
- tree do_stmt;
+finish_do_body (tree do_stmt)
{
RECHAIN_STMTS (do_stmt, DO_BODY (do_stmt));
}
@@ -377,9 +579,7 @@ finish_do_body (do_stmt)
COND is as indicated. */
void
-finish_do_stmt (cond, do_stmt)
- tree cond;
- tree do_stmt;
+finish_do_stmt (tree cond, tree do_stmt)
{
cond = maybe_convert_cond (cond);
DO_COND (do_stmt) = cond;
@@ -390,13 +590,11 @@ finish_do_stmt (cond, do_stmt)
indicated. */
tree
-finish_return_stmt (expr)
- tree expr;
+finish_return_stmt (tree expr)
{
tree r;
- if (!processing_template_decl)
- expr = check_return_expr (expr);
+ expr = check_return_expr (expr);
if (!processing_template_decl)
{
if (DECL_DESTRUCTOR_P (current_function_decl))
@@ -417,7 +615,7 @@ finish_return_stmt (expr)
/* Begin a for-statement. Returns a new FOR_STMT if appropriate. */
tree
-begin_for_stmt ()
+begin_for_stmt (void)
{
tree r;
@@ -425,10 +623,7 @@ begin_for_stmt ()
NULL_TREE, NULL_TREE);
NEW_FOR_SCOPE_P (r) = flag_new_for_scope > 0;
if (NEW_FOR_SCOPE_P (r))
- {
- do_pushlevel ();
- note_level_for_for ();
- }
+ do_pushlevel (sk_for);
add_stmt (r);
return r;
@@ -438,21 +633,18 @@ begin_for_stmt ()
given by FOR_STMT. */
void
-finish_for_init_stmt (for_stmt)
- tree for_stmt;
+finish_for_init_stmt (tree for_stmt)
{
if (last_tree != for_stmt)
RECHAIN_STMTS (for_stmt, FOR_INIT_STMT (for_stmt));
- do_pushlevel ();
+ do_pushlevel (sk_block);
}
/* Finish the COND of a for-statement, which may be given by
FOR_STMT. */
void
-finish_for_cond (cond, for_stmt)
- tree cond;
- tree for_stmt;
+finish_for_cond (tree cond, tree for_stmt)
{
cond = maybe_convert_cond (cond);
if (processing_template_decl)
@@ -484,10 +676,15 @@ finish_for_cond (cond, for_stmt)
given by FOR_STMT. */
void
-finish_for_expr (expr, for_stmt)
- tree expr;
- tree for_stmt;
+finish_for_expr (tree expr, tree for_stmt)
{
+ /* If EXPR is an overloaded function, issue an error; there is no
+ context available to use to perform overload resolution. */
+ if (expr && type_unknown_p (expr))
+ {
+ cxx_incomplete_type_error (expr, TREE_TYPE (expr));
+ expr = error_mark_node;
+ }
FOR_EXPR (for_stmt) = expr;
}
@@ -496,8 +693,7 @@ finish_for_expr (expr, for_stmt)
provided. */
void
-finish_for_stmt (for_stmt)
- tree for_stmt;
+finish_for_stmt (tree for_stmt)
{
/* Pop the scope for the body of the loop. */
do_poplevel ();
@@ -510,7 +706,7 @@ finish_for_stmt (for_stmt)
/* Finish a break-statement. */
tree
-finish_break_stmt ()
+finish_break_stmt (void)
{
return add_stmt (build_break_stmt ());
}
@@ -518,7 +714,7 @@ finish_break_stmt ()
/* Finish a continue-statement. */
tree
-finish_continue_stmt ()
+finish_continue_stmt (void)
{
return add_stmt (build_continue_stmt ());
}
@@ -527,10 +723,10 @@ finish_continue_stmt ()
appropriate. */
tree
-begin_switch_stmt ()
+begin_switch_stmt (void)
{
tree r;
- do_pushlevel ();
+ do_pushlevel (sk_block);
r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE, NULL_TREE);
add_stmt (r);
return r;
@@ -539,9 +735,7 @@ begin_switch_stmt ()
/* Finish the cond of a switch-statement. */
void
-finish_switch_cond (cond, switch_stmt)
- tree cond;
- tree switch_stmt;
+finish_switch_cond (tree cond, tree switch_stmt)
{
tree orig_type = NULL;
if (!processing_template_decl)
@@ -549,7 +743,7 @@ finish_switch_cond (cond, switch_stmt)
tree index;
/* Convert the condition to an integer or enumeration type. */
- cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, 1);
+ cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true);
if (cond == NULL_TREE)
{
error ("switch quantity not an integer");
@@ -558,7 +752,10 @@ finish_switch_cond (cond, switch_stmt)
orig_type = TREE_TYPE (cond);
if (cond != error_mark_node)
{
- cond = default_conversion (cond);
+ /* [stmt.switch]
+
+ Integral promotions are performed. */
+ cond = perform_integral_promotions (cond);
cond = fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (cond), cond));
}
@@ -583,8 +780,7 @@ finish_switch_cond (cond, switch_stmt)
SWITCH_STMT. The COND to switch on is indicated. */
void
-finish_switch_stmt (switch_stmt)
- tree switch_stmt;
+finish_switch_stmt (tree switch_stmt)
{
RECHAIN_STMTS (switch_stmt, SWITCH_BODY (switch_stmt));
pop_switch ();
@@ -595,8 +791,7 @@ finish_switch_stmt (switch_stmt)
/* Generate the RTL for T, which is a TRY_BLOCK. */
static void
-genrtl_try_block (t)
- tree t;
+genrtl_try_block (tree t)
{
if (CLEANUP_P (t))
{
@@ -607,7 +802,7 @@ genrtl_try_block (t)
else
{
if (!FN_TRY_BLOCK_P (t))
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
expand_eh_region_start ();
expand_stmt (TRY_STMTS (t));
@@ -632,8 +827,7 @@ genrtl_try_block (t)
/* Generate the RTL for T, which is an EH_SPEC_BLOCK. */
static void
-genrtl_eh_spec_block (t)
- tree t;
+genrtl_eh_spec_block (tree t)
{
expand_eh_region_start ();
expand_stmt (EH_SPEC_STMTS (t));
@@ -648,7 +842,7 @@ genrtl_eh_spec_block (t)
appropriate. */
tree
-begin_try_block ()
+begin_try_block (void)
{
tree r = build_stmt (TRY_BLOCK, NULL_TREE, NULL_TREE);
add_stmt (r);
@@ -658,7 +852,7 @@ begin_try_block ()
/* Likewise, for a function-try-block. */
tree
-begin_function_try_block ()
+begin_function_try_block (void)
{
tree r = build_stmt (TRY_BLOCK, NULL_TREE, NULL_TREE);
FN_TRY_BLOCK_P (r) = 1;
@@ -669,8 +863,7 @@ begin_function_try_block ()
/* Finish a try-block, which may be given by TRY_BLOCK. */
void
-finish_try_block (try_block)
- tree try_block;
+finish_try_block (tree try_block)
{
RECHAIN_STMTS (try_block, TRY_STMTS (try_block));
}
@@ -679,8 +872,7 @@ finish_try_block (try_block)
TRY_BLOCK. */
void
-finish_cleanup_try_block (try_block)
- tree try_block;
+finish_cleanup_try_block (tree try_block)
{
RECHAIN_STMTS (try_block, TRY_STMTS (try_block));
}
@@ -689,9 +881,7 @@ finish_cleanup_try_block (try_block)
by CLEANUP. */
void
-finish_cleanup (cleanup, try_block)
- tree cleanup;
- tree try_block;
+finish_cleanup (tree cleanup, tree try_block)
{
TRY_HANDLERS (try_block) = cleanup;
CLEANUP_P (try_block) = 1;
@@ -700,8 +890,7 @@ finish_cleanup (cleanup, try_block)
/* Likewise, for a function-try-block. */
void
-finish_function_try_block (try_block)
- tree try_block;
+finish_function_try_block (tree try_block)
{
if (TREE_CHAIN (try_block)
&& TREE_CODE (TREE_CHAIN (try_block)) == CTOR_INITIALIZER)
@@ -720,8 +909,7 @@ finish_function_try_block (try_block)
TRY_BLOCK. */
void
-finish_handler_sequence (try_block)
- tree try_block;
+finish_handler_sequence (tree try_block)
{
RECHAIN_STMTS (try_block, TRY_HANDLERS (try_block));
check_handlers (TRY_HANDLERS (try_block));
@@ -730,8 +918,7 @@ finish_handler_sequence (try_block)
/* Likewise, for a function-try-block. */
void
-finish_function_handler_sequence (try_block)
- tree try_block;
+finish_function_handler_sequence (tree try_block)
{
in_function_try_handler = 0;
RECHAIN_STMTS (try_block, TRY_HANDLERS (try_block));
@@ -741,8 +928,7 @@ finish_function_handler_sequence (try_block)
/* Generate the RTL for T, which is a HANDLER. */
static void
-genrtl_handler (t)
- tree t;
+genrtl_handler (tree t)
{
genrtl_do_pushlevel ();
if (!processing_template_decl)
@@ -755,15 +941,14 @@ genrtl_handler (t)
/* Begin a handler. Returns a HANDLER if appropriate. */
tree
-begin_handler ()
+begin_handler (void)
{
tree r;
r = build_stmt (HANDLER, NULL_TREE, NULL_TREE);
add_stmt (r);
/* Create a binding level for the eh_info and the exception object
cleanup. */
- do_pushlevel ();
- note_level_for_catch ();
+ do_pushlevel (sk_catch);
return r;
}
@@ -772,9 +957,7 @@ begin_handler ()
if this is a `catch (...)' clause. */
void
-finish_handler_parms (decl, handler)
- tree decl;
- tree handler;
+finish_handler_parms (tree decl, tree handler)
{
tree type = NULL_TREE;
if (processing_template_decl)
@@ -792,14 +975,15 @@ finish_handler_parms (decl, handler)
type = expand_start_catch_block (decl);
HANDLER_TYPE (handler) = type;
+ if (!processing_template_decl && type)
+ mark_used (eh_type_info (type));
}
/* Finish a handler, which may be given by HANDLER. The BLOCKs are
the return value from the matching call to finish_handler_parms. */
void
-finish_handler (handler)
- tree handler;
+finish_handler (tree handler)
{
if (!processing_template_decl)
expand_end_catch_block ();
@@ -807,13 +991,12 @@ finish_handler (handler)
RECHAIN_STMTS (handler, HANDLER_BODY (handler));
}
-/* Begin a compound-statement. If HAS_NO_SCOPE is nonzero, the
+/* Begin a compound-statement. If HAS_NO_SCOPE is true, the
compound-statement does not define a scope. Returns a new
- COMPOUND_STMT if appropriate. */
+ COMPOUND_STMT. */
tree
-begin_compound_stmt (has_no_scope)
- int has_no_scope;
+begin_compound_stmt (bool has_no_scope)
{
tree r;
int is_try = 0;
@@ -830,37 +1013,29 @@ begin_compound_stmt (has_no_scope)
last_expr_type = NULL_TREE;
if (!has_no_scope)
- {
- do_pushlevel ();
- if (is_try)
- note_level_for_try ();
- }
+ do_pushlevel (is_try ? sk_try : sk_block);
else
/* Normally, we try hard to keep the BLOCK for a
statement-expression. But, if it's a statement-expression with
a scopeless block, there's nothing to keep, and we don't want
to accidentally keep a block *inside* the scopeless block. */
- keep_next_level (0);
+ keep_next_level (false);
return r;
}
-/* Finish a compound-statement, which may be given by COMPOUND_STMT.
- If HAS_NO_SCOPE is nonzero, the compound statement does not define
- a scope. */
+/* Finish a compound-statement, which is given by COMPOUND_STMT. */
tree
-finish_compound_stmt (has_no_scope, compound_stmt)
- int has_no_scope;
- tree compound_stmt;
+finish_compound_stmt (tree compound_stmt)
{
tree r;
tree t;
- if (!has_no_scope)
- r = do_poplevel ();
- else
+ if (COMPOUND_STMT_NO_SCOPE (compound_stmt))
r = NULL_TREE;
+ else
+ r = do_poplevel ();
RECHAIN_STMTS (compound_stmt, COMPOUND_BODY (compound_stmt));
@@ -880,13 +1055,11 @@ finish_compound_stmt (has_no_scope, compound_stmt)
CLOBBERS. */
tree
-finish_asm_stmt (cv_qualifier, string, output_operands,
- input_operands, clobbers)
- tree cv_qualifier;
- tree string;
- tree output_operands;
- tree input_operands;
- tree clobbers;
+finish_asm_stmt (tree cv_qualifier,
+ tree string,
+ tree output_operands,
+ tree input_operands,
+ tree clobbers)
{
tree r;
tree t;
@@ -943,9 +1116,9 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
&allows_reg,
&is_inout))
{
- /* By marking the type as erroneous, we will not try to
- process this operand again in expand_asm_operands. */
- TREE_TYPE (operand) = error_mark_node;
+ /* By marking this operand as erroneous, we will not try
+ to process this operand again in expand_asm_operands. */
+ TREE_VALUE (t) = error_mark_node;
continue;
}
@@ -968,12 +1141,11 @@ finish_asm_stmt (cv_qualifier, string, output_operands,
/* Finish a label with the indicated NAME. */
-void
-finish_label_stmt (name)
- tree name;
+tree
+finish_label_stmt (tree name)
{
- tree decl = define_label (input_filename, lineno, name);
- add_stmt (build_stmt (LABEL_STMT, decl));
+ tree decl = define_label (input_location, name);
+ return add_stmt (build_stmt (LABEL_STMT, decl));
}
/* Finish a series of declarations for local labels. G++ allows users
@@ -981,8 +1153,7 @@ finish_label_stmt (name)
is useful when writing code involving statement-expressions. */
void
-finish_label_decl (name)
- tree name;
+finish_label_decl (tree name)
{
tree decl = declare_local_label (name);
add_decl_stmt (decl);
@@ -991,9 +1162,7 @@ finish_label_decl (name)
/* When DECL goes out of scope, make sure that CLEANUP is executed. */
void
-finish_decl_cleanup (decl, cleanup)
- tree decl;
- tree cleanup;
+finish_decl_cleanup (tree decl, tree cleanup)
{
add_stmt (build_stmt (CLEANUP_STMT, decl, cleanup));
}
@@ -1001,105 +1170,13 @@ finish_decl_cleanup (decl, cleanup)
/* If the current scope exits with an exception, run CLEANUP. */
void
-finish_eh_cleanup (cleanup)
- tree cleanup;
+finish_eh_cleanup (tree cleanup)
{
tree r = build_stmt (CLEANUP_STMT, NULL_TREE, cleanup);
CLEANUP_EH_ONLY (r) = 1;
add_stmt (r);
}
-/* Generate the RTL for a RETURN_INIT. */
-
-static void
-genrtl_named_return_value ()
-{
- tree decl = DECL_RESULT (current_function_decl);
-
- /* If this named return value comes in a register, put it in a
- pseudo-register. */
- if (DECL_REGISTER (decl))
- {
- /* Note that the mode of the old DECL_RTL may be wider than the
- mode of DECL_RESULT, depending on the calling conventions for
- the processor. For example, on the Alpha, a 32-bit integer
- is returned in a DImode register -- the DECL_RESULT has
- SImode but the DECL_RTL for the DECL_RESULT has DImode. So,
- here, we use the mode the back-end has already assigned for
- the return value. */
- SET_DECL_RTL (decl, gen_reg_rtx (GET_MODE (DECL_RTL (decl))));
- if (TREE_ADDRESSABLE (decl))
- put_var_into_stack (decl, /*rescan=*/true);
- }
-
- emit_local_var (decl);
-}
-
-/* Bind a name and initialization to the return value of
- the current function. */
-
-void
-finish_named_return_value (return_id, init)
- tree return_id, init;
-{
- tree decl = DECL_RESULT (current_function_decl);
-
- /* Give this error as many times as there are occurrences, so that
- users can use Emacs compilation buffers to find and fix all such
- places. */
- if (pedantic)
- pedwarn ("ISO C++ does not permit named return values");
- cp_deprecated ("the named return value extension");
-
- if (return_id != NULL_TREE)
- {
- if (DECL_NAME (decl) == NULL_TREE)
- DECL_NAME (decl) = return_id;
- else
- {
- error ("return identifier `%D' already in place", return_id);
- return;
- }
- }
-
- /* Can't let this happen for constructors. */
- if (DECL_CONSTRUCTOR_P (current_function_decl))
- {
- error ("can't redefine default return value for constructors");
- return;
- }
-
- /* If we have a named return value, put that in our scope as well. */
- if (DECL_NAME (decl) != NULL_TREE)
- {
- /* Let `cp_finish_decl' know that this initializer is ok. */
- DECL_INITIAL (decl) = init;
- if (doing_semantic_analysis_p ())
- pushdecl (decl);
- if (!processing_template_decl)
- {
- cp_finish_decl (decl, init, NULL_TREE, 0);
- add_stmt (build_stmt (RETURN_INIT, NULL_TREE, NULL_TREE));
- }
- else
- add_stmt (build_stmt (RETURN_INIT, return_id, init));
- }
-
- /* Don't use tree-inlining for functions with named return values.
- That doesn't work properly because we don't do any translation of
- the RETURN_INITs when they are copied. */
- DECL_UNINLINABLE (current_function_decl) = 1;
-}
-
-/* Begin processing a mem-initializer-list. */
-
-void
-begin_mem_initializers ()
-{
- if (! DECL_CONSTRUCTOR_P (current_function_decl))
- error ("only constructors take base initializers");
-}
-
/* The MEM_INITS is a list of mem-initializers, in reverse of the
order they were written by the user. Each node is as for
emit_mem_initializers. */
@@ -1120,7 +1197,7 @@ finish_mem_initializers (tree mem_inits)
/* Returns the stack of SCOPE_STMTs for the current function. */
tree *
-current_scope_stmt_stack ()
+current_scope_stmt_stack (void)
{
return &cfun->language->base.x_scope_stmt_stack;
}
@@ -1128,8 +1205,7 @@ current_scope_stmt_stack ()
/* Finish a parenthesized expression EXPR. */
tree
-finish_parenthesized_expr (expr)
- tree expr;
+finish_parenthesized_expr (tree expr)
{
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expr))))
/* This inhibits warnings in c_common_truthvalue_conversion. */
@@ -1142,11 +1218,209 @@ finish_parenthesized_expr (expr)
return expr;
}
+/* Finish a reference to a non-static data member (DECL) that is not
+ preceded by `.' or `->'. */
+
+tree
+finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
+{
+ my_friendly_assert (TREE_CODE (decl) == FIELD_DECL, 20020909);
+
+ if (!object)
+ {
+ if (current_function_decl
+ && DECL_STATIC_FUNCTION_P (current_function_decl))
+ cp_error_at ("invalid use of member `%D' in static member function",
+ decl);
+ else
+ cp_error_at ("invalid use of non-static data member `%D'", decl);
+ error ("from this location");
+
+ return error_mark_node;
+ }
+ TREE_USED (current_class_ptr) = 1;
+ if (processing_template_decl && !qualifying_scope)
+ {
+ tree type = TREE_TYPE (decl);
+
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ type = TREE_TYPE (type);
+ else
+ {
+ /* Set the cv qualifiers. */
+ int quals = cp_type_quals (TREE_TYPE (current_class_ref));
+
+ if (DECL_MUTABLE_P (decl))
+ quals &= ~TYPE_QUAL_CONST;
+
+ quals |= cp_type_quals (TREE_TYPE (decl));
+ type = cp_build_qualified_type (type, quals);
+ }
+
+ return build_min (COMPONENT_REF, type, object, decl);
+ }
+ else
+ {
+ tree access_type = TREE_TYPE (object);
+ tree lookup_context = context_for_name_lookup (decl);
+
+ while (!DERIVED_FROM_P (lookup_context, access_type))
+ {
+ access_type = TYPE_CONTEXT (access_type);
+ while (access_type && DECL_P (access_type))
+ access_type = DECL_CONTEXT (access_type);
+
+ if (!access_type)
+ {
+ cp_error_at ("object missing in reference to `%D'", decl);
+ error ("from this location");
+ return error_mark_node;
+ }
+ }
+
+ /* If PROCESSING_TEMPLATE_DECL is nonzero here, then
+ QUALIFYING_SCOPE is also non-null. Wrap this in a SCOPE_REF
+ for now. */
+ if (processing_template_decl)
+ return build_min (SCOPE_REF, TREE_TYPE (decl),
+ qualifying_scope, DECL_NAME (decl));
+
+ perform_or_defer_access_check (TYPE_BINFO (access_type), decl);
+
+ /* If the data member was named `C::M', convert `*this' to `C'
+ first. */
+ if (qualifying_scope)
+ {
+ tree binfo = NULL_TREE;
+ object = build_scoped_ref (object, qualifying_scope,
+ &binfo);
+ }
+
+ return build_class_member_access_expr (object, decl,
+ /*access_path=*/NULL_TREE,
+ /*preserve_reference=*/false);
+ }
+}
+
+/* DECL was the declaration to which a qualified-id resolved. Issue
+ an error message if it is not accessible. If OBJECT_TYPE is
+ non-NULL, we have just seen `x->' or `x.' and OBJECT_TYPE is the
+ type of `*x', or `x', respectively. If the DECL was named as
+ `A::B' then NESTED_NAME_SPECIFIER is `A'. */
+
+void
+check_accessibility_of_qualified_id (tree decl,
+ tree object_type,
+ tree nested_name_specifier)
+{
+ tree scope;
+ tree qualifying_type = NULL_TREE;
+
+ /* Determine the SCOPE of DECL. */
+ scope = context_for_name_lookup (decl);
+ /* If the SCOPE is not a type, then DECL is not a member. */
+ if (!TYPE_P (scope))
+ return;
+ /* Compute the scope through which DECL is being accessed. */
+ if (object_type
+ /* OBJECT_TYPE might not be a class type; consider:
+
+ class A { typedef int I; };
+ I *p;
+ p->A::I::~I();
+
+ In this case, we will have "A::I" as the DECL, but "I" as the
+ OBJECT_TYPE. */
+ && CLASS_TYPE_P (object_type)
+ && DERIVED_FROM_P (scope, object_type))
+ /* If we are processing a `->' or `.' expression, use the type of the
+ left-hand side. */
+ qualifying_type = object_type;
+ else if (nested_name_specifier)
+ {
+ /* If the reference is to a non-static member of the
+ current class, treat it as if it were referenced through
+ `this'. */
+ if (DECL_NONSTATIC_MEMBER_P (decl)
+ && current_class_ptr
+ && DERIVED_FROM_P (scope, current_class_type))
+ qualifying_type = current_class_type;
+ /* Otherwise, use the type indicated by the
+ nested-name-specifier. */
+ else
+ qualifying_type = nested_name_specifier;
+ }
+ else
+ /* Otherwise, the name must be from the current class or one of
+ its bases. */
+ qualifying_type = currently_open_derived_class (scope);
+
+ if (qualifying_type)
+ perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl);
+}
+
+/* EXPR is the result of a qualified-id. The QUALIFYING_CLASS was the
+ class named to the left of the "::" operator. DONE is true if this
+ expression is a complete postfix-expression; it is false if this
+ expression is followed by '->', '[', '(', etc. ADDRESS_P is true
+ iff this expression is the operand of '&'. */
+
+tree
+finish_qualified_id_expr (tree qualifying_class, tree expr, bool done,
+ bool address_p)
+{
+ if (error_operand_p (expr))
+ return error_mark_node;
+
+ /* If EXPR occurs as the operand of '&', use special handling that
+ permits a pointer-to-member. */
+ if (address_p && done)
+ {
+ if (TREE_CODE (expr) == SCOPE_REF)
+ expr = TREE_OPERAND (expr, 1);
+ expr = build_offset_ref (qualifying_class, expr,
+ /*address_p=*/true);
+ return expr;
+ }
+
+ if (TREE_CODE (expr) == FIELD_DECL)
+ expr = finish_non_static_data_member (expr, current_class_ref,
+ qualifying_class);
+ else if (BASELINK_P (expr) && !processing_template_decl)
+ {
+ tree fn;
+ tree fns;
+
+ /* See if any of the functions are non-static members. */
+ fns = BASELINK_FUNCTIONS (expr);
+ if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
+ fns = TREE_OPERAND (fns, 0);
+ for (fn = fns; fn; fn = OVL_NEXT (fn))
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+ break;
+ /* If so, the expression may be relative to the current
+ class. */
+ if (fn && current_class_type
+ && DERIVED_FROM_P (qualifying_class, current_class_type))
+ expr = (build_class_member_access_expr
+ (maybe_dummy_object (qualifying_class, NULL),
+ expr,
+ BASELINK_ACCESS_BINFO (expr),
+ /*preserve_reference=*/false));
+ else if (done)
+ /* The expression is a qualified name whose address is not
+ being taken. */
+ expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false);
+ }
+
+ return expr;
+}
+
/* Begin a statement-expression. The value returned must be passed to
finish_stmt_expr. */
tree
-begin_stmt_expr ()
+begin_stmt_expr (void)
{
/* If we're outside a function, we won't have a statement-tree to
work with. But, if we see a statement-expression we need to
@@ -1154,61 +1428,102 @@ begin_stmt_expr ()
if (! cfun && !last_tree)
begin_stmt_tree (&scope_chain->x_saved_tree);
- keep_next_level (1);
- /* If we're building a statement tree, then the upcoming compound
- statement will be chained onto the tree structure, starting at
- last_tree. We return last_tree so that we can later unhook the
- compound statement. */
+ last_expr_type = NULL_TREE;
+
+ keep_next_level (true);
+
return last_tree;
}
-/* Used when beginning a statement-expression outside function scope.
- For example, when handling a file-scope initializer, we use this
- function. */
+/* Process the final expression of a statement expression. EXPR can be
+ NULL, if the final expression is empty. Build up a TARGET_EXPR so
+ that the result value can be safely returned to the enclosing
+ expression. */
tree
-begin_global_stmt_expr ()
+finish_stmt_expr_expr (tree expr)
{
- if (! cfun && !last_tree)
- begin_stmt_tree (&scope_chain->x_saved_tree);
-
- keep_next_level (1);
-
- return last_tree ? last_tree : expand_start_stmt_expr(/*has_scope=*/1);
-}
+ tree result = NULL_TREE;
+ tree type = void_type_node;
-/* Finish the STMT_EXPR last begun with begin_global_stmt_expr. */
+ if (expr)
+ {
+ type = TREE_TYPE (expr);
+
+ if (!processing_template_decl && !VOID_TYPE_P (TREE_TYPE (expr)))
+ {
+ if (TREE_CODE (type) == ARRAY_TYPE
+ || TREE_CODE (type) == FUNCTION_TYPE)
+ expr = decay_conversion (expr);
+
+ expr = convert_from_reference (expr);
+ expr = require_complete_type (expr);
+
+ /* Build a TARGET_EXPR for this aggregate. finish_stmt_expr
+ will then pull it apart so the lifetime of the target is
+ within the scope of the expression containing this statement
+ expression. */
+ if (TREE_CODE (expr) == TARGET_EXPR)
+ ;
+ else if (!IS_AGGR_TYPE (type) || TYPE_HAS_TRIVIAL_INIT_REF (type))
+ expr = build_target_expr_with_type (expr, type);
+ else
+ {
+ /* Copy construct. */
+ expr = build_special_member_call
+ (NULL_TREE, complete_ctor_identifier,
+ build_tree_list (NULL_TREE, expr),
+ TYPE_BINFO (type), LOOKUP_NORMAL);
+ expr = build_cplus_new (type, expr);
+ my_friendly_assert (TREE_CODE (expr) == TARGET_EXPR, 20030729);
+ }
+ }
-tree
-finish_global_stmt_expr (stmt_expr)
- tree stmt_expr;
-{
- stmt_expr = expand_end_stmt_expr (stmt_expr);
+ if (expr != error_mark_node)
+ {
+ result = build_stmt (EXPR_STMT, expr);
+ add_stmt (result);
+ }
+ }
- if (! cfun
- && TREE_CHAIN (scope_chain->x_saved_tree) == NULL_TREE)
- finish_stmt_tree (&scope_chain->x_saved_tree);
+ finish_stmt ();
- return stmt_expr;
+ /* Remember the last expression so that finish_stmt_expr can pull it
+ apart. */
+ last_expr_type = result ? result : void_type_node;
+
+ return result;
}
-/* Finish a statement-expression. RTL_EXPR should be the value
- returned by the previous begin_stmt_expr; EXPR is the
- statement-expression. Returns an expression representing the
- statement-expression. */
+/* Finish a statement-expression. EXPR should be the value returned
+ by the previous begin_stmt_expr. Returns an expression
+ representing the statement-expression. */
tree
-finish_stmt_expr (rtl_expr)
- tree rtl_expr;
+finish_stmt_expr (tree rtl_expr, bool has_no_scope)
{
tree result;
-
- /* If the last thing in the statement-expression was not an
- expression-statement, then it has type `void'. */
+ tree result_stmt = last_expr_type;
+ tree type;
+
if (!last_expr_type)
- last_expr_type = void_type_node;
- result = build_min (STMT_EXPR, last_expr_type, last_tree);
+ type = void_type_node;
+ else
+ {
+ if (result_stmt == void_type_node)
+ {
+ type = void_type_node;
+ result_stmt = NULL_TREE;
+ }
+ else
+ type = TREE_TYPE (EXPR_STMT_EXPR (result_stmt));
+ }
+
+ result = build_min (STMT_EXPR, type, last_tree);
TREE_SIDE_EFFECTS (result) = 1;
+ STMT_EXPR_NO_SCOPE (result) = has_no_scope;
+
+ last_expr_type = NULL_TREE;
/* Remove the compound statement from the tree structure; it is
now saved in the STMT_EXPR. */
@@ -1221,9 +1536,67 @@ finish_stmt_expr (rtl_expr)
&& TREE_CHAIN (scope_chain->x_saved_tree) == NULL_TREE)
finish_stmt_tree (&scope_chain->x_saved_tree);
+ if (processing_template_decl)
+ return result;
+
+ if (!VOID_TYPE_P (type))
+ {
+ /* Pull out the TARGET_EXPR that is the final expression. Put
+ the target's init_expr as the final expression and then put
+ the statement expression itself as the target's init
+ expr. Finally, return the target expression. */
+ tree last_expr = EXPR_STMT_EXPR (result_stmt);
+
+ my_friendly_assert (TREE_CODE (last_expr) == TARGET_EXPR, 20030729);
+ EXPR_STMT_EXPR (result_stmt) = TREE_OPERAND (last_expr, 1);
+ TREE_OPERAND (last_expr, 1) = result;
+ result = last_expr;
+ }
return result;
}
+/* Perform Koenig lookup. FN is the postfix-expression representing
+ the function (or functions) to call; ARGS are the arguments to the
+ call. Returns the functions to be considered by overload
+ resolution. */
+
+tree
+perform_koenig_lookup (tree fn, tree args)
+{
+ tree identifier = NULL_TREE;
+ tree functions = NULL_TREE;
+
+ /* Find the name of the overloaded function. */
+ if (TREE_CODE (fn) == IDENTIFIER_NODE)
+ identifier = fn;
+ else if (is_overloaded_fn (fn))
+ {
+ functions = fn;
+ identifier = DECL_NAME (get_first_fn (functions));
+ }
+ else if (DECL_P (fn))
+ {
+ functions = fn;
+ identifier = DECL_NAME (fn);
+ }
+
+ /* A call to a namespace-scope function using an unqualified name.
+
+ Do Koenig lookup -- unless any of the arguments are
+ type-dependent. */
+ if (!any_type_dependent_arguments_p (args))
+ {
+ fn = lookup_arg_dependent (identifier, functions, args);
+ if (!fn)
+ /* The unqualified name could not be resolved. */
+ fn = unqualified_fn_lookup_error (identifier);
+ }
+ else
+ fn = identifier;
+
+ return fn;
+}
+
/* Generate an expression for `FN (ARGS)'.
If DISALLOW_VIRTUAL is true, the call to FN will be not generated
@@ -1235,18 +1608,60 @@ finish_stmt_expr (rtl_expr)
Returns code for the call. */
tree
-finish_call_expr (tree fn, tree args, bool disallow_virtual)
+finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
{
+ tree result;
+ tree orig_fn;
+ tree orig_args;
+
if (fn == error_mark_node || args == error_mark_node)
return error_mark_node;
- if (processing_template_decl)
- return build_nt (CALL_EXPR, fn, args, NULL_TREE);
-
/* ARGS should be a list of arguments. */
my_friendly_assert (!args || TREE_CODE (args) == TREE_LIST,
20020712);
+ orig_fn = fn;
+ orig_args = args;
+
+ if (processing_template_decl)
+ {
+ if (type_dependent_expression_p (fn)
+ || any_type_dependent_arguments_p (args))
+ {
+ result = build_nt (CALL_EXPR, fn, args);
+ KOENIG_LOOKUP_P (result) = koenig_p;
+ return result;
+ }
+ 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);
+ }
+
+ /* A reference to a member function will appear as an overloaded
+ function (rather than a BASELINK) if an unqualified name was used
+ to refer to it. */
+ if (!BASELINK_P (fn) && is_overloaded_fn (fn))
+ {
+ tree f = fn;
+
+ if (TREE_CODE (f) == TEMPLATE_ID_EXPR)
+ f = TREE_OPERAND (f, 0);
+ f = get_first_fn (f);
+ if (DECL_FUNCTION_MEMBER_P (f))
+ {
+ tree type = currently_open_derived_class (DECL_CONTEXT (f));
+ if (!type)
+ type = DECL_CONTEXT (f);
+ fn = build_baselink (TYPE_BINFO (type),
+ TYPE_BINFO (type),
+ fn, /*optype=*/NULL_TREE);
+ }
+ }
+
+ result = NULL_TREE;
if (BASELINK_P (fn))
{
tree object;
@@ -1286,25 +1701,46 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
object = build_dummy_object (DECL_CONTEXT (representative_fn));
}
- return build_new_method_call (object, fn, args, NULL_TREE,
- (disallow_virtual
- ? LOOKUP_NONVIRTUAL : 0));
+ if (processing_template_decl)
+ {
+ if (type_dependent_expression_p (object))
+ return build_nt (CALL_EXPR, orig_fn, orig_args);
+ object = build_non_dependent_expr (object);
+ }
+
+ result = build_new_method_call (object, fn, args, NULL_TREE,
+ (disallow_virtual
+ ? LOOKUP_NONVIRTUAL : 0));
}
else if (is_overloaded_fn (fn))
/* A call to a namespace-scope function. */
- return build_new_function_call (fn, args);
- else if (CLASS_TYPE_P (TREE_TYPE (fn)))
+ result = build_new_function_call (fn, args);
+ else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
{
- /* If the "function" is really an object of class type, it might
- have an overloaded `operator ()'. */
- tree result;
- result = build_opfncall (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE);
- if (result)
- return result;
+ if (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. */
+ result = build1 (NOP_EXPR,
+ void_type_node,
+ TREE_OPERAND (fn, 0));
+ TREE_SIDE_EFFECTS (result) = 1;
}
+ 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);
+ if (!result)
+ /* A call where the function is unknown. */
+ result = build_function_call (fn, args);
- /* A call where the function is unknown. */
- return build_function_call (fn, args);
+ if (processing_template_decl)
+ {
+ result = build (CALL_EXPR, TREE_TYPE (result), orig_fn, orig_args);
+ KOENIG_LOOKUP_P (result) = koenig_p;
+ }
+ return result;
}
/* Finish a call to a postfix increment or decrement or EXPR. (Which
@@ -1312,24 +1748,15 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
POSTDECREMENT_EXPR.) */
tree
-finish_increment_expr (expr, code)
- tree expr;
- enum tree_code code;
+finish_increment_expr (tree expr, enum tree_code code)
{
- /* If we get an OFFSET_REF, turn it into what it really means (e.g.,
- a COMPONENT_REF). This way if we've got, say, a reference to a
- static member that's being operated on, we don't end up trying to
- find a member operator for the class it's in. */
-
- if (TREE_CODE (expr) == OFFSET_REF)
- expr = resolve_offset_ref (expr);
return build_x_unary_op (code, expr);
}
/* Finish a use of `this'. Returns an expression for `this'. */
tree
-finish_this_expr ()
+finish_this_expr (void)
{
tree result;
@@ -1355,84 +1782,55 @@ finish_this_expr ()
return result;
}
-/* Finish a member function call using OBJECT and ARGS as arguments to
- FN. Returns an expression for the call. */
+/* Finish a pseudo-destructor expression. If SCOPE is NULL, the
+ expression was of the form `OBJECT.~DESTRUCTOR' where DESTRUCTOR is
+ the TYPE for the type given. If SCOPE is non-NULL, the expression
+ was of the form `OBJECT.SCOPE::~DESTRUCTOR'. */
tree
-finish_object_call_expr (fn, object, args)
- tree fn;
- tree object;
- tree args;
+finish_pseudo_destructor_expr (tree object, tree scope, tree destructor)
{
- if (DECL_DECLARES_TYPE_P (fn))
- {
- if (processing_template_decl)
- /* This can happen on code like:
+ if (destructor == error_mark_node)
+ return error_mark_node;
- class X;
- template <class T> void f(T t) {
- t.X();
- }
+ my_friendly_assert (TYPE_P (destructor), 20010905);
- We just grab the underlying IDENTIFIER. */
- fn = DECL_NAME (fn);
- else
+ if (!processing_template_decl)
+ {
+ if (scope == error_mark_node)
{
- error ("calling type `%T' like a method", fn);
+ error ("invalid qualifying scope in pseudo-destructor name");
return error_mark_node;
}
- }
-
- if (processing_template_decl || name_p (fn))
- return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
- else
- return build_new_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL);
-}
-
-/* Finish a qualified member function call using OBJECT and ARGS as
- arguments to FN. Returns an expression for the call. */
-
-tree
-finish_qualified_object_call_expr (fn, object, args)
- tree fn;
- tree object;
- tree args;
-{
- return build_scoped_method_call (object, TREE_OPERAND (fn, 0),
- TREE_OPERAND (fn, 1), args);
-}
+
+ /* [expr.pseudo] says both:
-/* Finish a pseudo-destructor call expression of OBJECT, with SCOPE
- being the scope, if any, of DESTRUCTOR. Returns an expression for
- the call. */
+ The type designated by the pseudo-destructor-name shall be
+ the same as the object type.
-tree
-finish_pseudo_destructor_call_expr (object, scope, destructor)
- tree object;
- tree scope;
- tree destructor;
-{
- if (processing_template_decl)
- return build_min_nt (PSEUDO_DTOR_EXPR, object, scope, destructor);
+ and:
- if (scope && scope != destructor)
- error ("destructor specifier `%T::~%T()' must have matching names",
- scope, destructor);
+ The cv-unqualified versions of the object type and of the
+ type designated by the pseudo-destructor-name shall be the
+ same type.
- if ((scope == NULL_TREE || IDENTIFIER_GLOBAL_VALUE (destructor))
- && (TREE_CODE (TREE_TYPE (object)) !=
- TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (destructor)))))
- error ("`%E' is not of type `%T'", object, destructor);
+ We implement the more generous second sentence, since that is
+ what most other compilers do. */
+ if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (object),
+ destructor))
+ {
+ error ("`%E' is not of type `%T'", object, destructor);
+ return error_mark_node;
+ }
+ }
- return cp_convert (void_type_node, object);
+ return build (PSEUDO_DTOR_EXPR, void_type_node, object, scope, destructor);
}
/* Finish an expression of the form CODE EXPR. */
tree
-finish_unary_op_expr (code, expr)
- enum tree_code code;
- tree expr;
+finish_unary_op_expr (enum tree_code code, tree expr)
{
tree result = build_x_unary_op (code, expr);
/* Inside a template, build_x_unary_op does not fold the
@@ -1447,18 +1845,35 @@ finish_unary_op_expr (code, expr)
return result;
}
-/* Finish an id-expression. */
+/* Finish a compound-literal expression. TYPE is the type to which
+ the INITIALIZER_LIST is being cast. */
tree
-finish_id_expr (expr)
- tree expr;
+finish_compound_literal (tree type, tree initializer_list)
{
- if (TREE_CODE (expr) == IDENTIFIER_NODE)
- expr = do_identifier (expr, 1, NULL_TREE);
+ tree compound_literal;
- if (TREE_TYPE (expr) == error_mark_node)
- expr = error_mark_node;
- return expr;
+ /* Build a CONSTRUCTOR for the INITIALIZER_LIST. */
+ compound_literal = build_constructor (NULL_TREE, initializer_list);
+ /* Mark it as a compound-literal. */
+ TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
+ if (processing_template_decl)
+ TREE_TYPE (compound_literal) = type;
+ else
+ {
+ /* Check the initialization. */
+ compound_literal = digest_init (type, compound_literal, NULL);
+ /* If the TYPE was an array type with an unknown bound, then we can
+ figure out the dimension now. For example, something like:
+
+ `(int []) { 2, 3 }'
+
+ implies that the array has two elements. */
+ if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
+ complete_array_type (type, compound_literal, 1);
+ }
+
+ return compound_literal;
}
/* Return the declaration for the function-name variable indicated by
@@ -1471,83 +1886,20 @@ finish_fname (tree id)
decl = fname_decl (C_RID_CODE (id), id);
if (processing_template_decl)
- decl = build_min_nt (LOOKUP_EXPR, DECL_NAME (decl));
+ decl = DECL_NAME (decl);
return decl;
}
-static tree current_type_lookups;
-
-/* Perform deferred access control for types used in the type of a
- declaration. */
-
-static void
-deferred_type_access_control ()
-{
- tree lookup = type_lookups;
-
- if (lookup == error_mark_node)
- return;
-
- for (; lookup; lookup = TREE_CHAIN (lookup))
- enforce_access (TREE_PURPOSE (lookup), TREE_VALUE (lookup));
-}
-
-void
-decl_type_access_control (decl)
- tree decl;
-{
- tree save_fn;
-
- if (type_lookups == error_mark_node)
- return;
-
- save_fn = current_function_decl;
-
- if (decl && TREE_CODE (decl) == FUNCTION_DECL)
- current_function_decl = decl;
-
- deferred_type_access_control ();
-
- current_function_decl = save_fn;
-
- /* Now strip away the checks for the current declarator; they were
- added to type_lookups after typed_declspecs saved the copy that
- ended up in current_type_lookups. */
- type_lookups = current_type_lookups;
-}
-
-void
-save_type_access_control (lookups)
- tree lookups;
-{
- current_type_lookups = lookups;
-}
-
-/* Reset the deferred access control. */
-
-void
-reset_type_access_control ()
-{
- type_lookups = NULL_TREE;
- current_type_lookups = NULL_TREE;
-}
-
/* Begin a function definition declared with DECL_SPECS, ATTRIBUTES,
and DECLARATOR. Returns nonzero if the function-declaration is
valid. */
int
-begin_function_definition (decl_specs, attributes, declarator)
- tree decl_specs;
- tree attributes;
- tree declarator;
+begin_function_definition (tree decl_specs, tree attributes, tree declarator)
{
if (!start_function (decl_specs, declarator, attributes, SF_DEFAULT))
return 0;
- deferred_type_access_control ();
- type_lookups = error_mark_node;
-
/* The things we're about to see are not directly qualified by any
template headers we've seen thus far. */
reset_specialization ();
@@ -1555,38 +1907,10 @@ begin_function_definition (decl_specs, attributes, declarator)
return 1;
}
-/* Begin a constructor declarator of the form `SCOPE::NAME'. Returns
- a SCOPE_REF. */
-
-tree
-begin_constructor_declarator (scope, name)
- tree scope;
- tree name;
-{
- tree result = build_nt (SCOPE_REF, scope, name);
- enter_scope_of (result);
- return result;
-}
-
-/* Finish an init-declarator. Returns a DECL. */
-
-tree
-finish_declarator (declarator, declspecs, attributes,
- prefix_attributes, initialized)
- tree declarator;
- tree declspecs;
- tree attributes;
- tree prefix_attributes;
- int initialized;
-{
- return start_decl (declarator, declspecs, initialized, attributes,
- prefix_attributes);
-}
-
/* Finish a translation unit. */
void
-finish_translation_unit ()
+finish_translation_unit (void)
{
/* In case there were missing closebraces,
get us back to the global binding level. */
@@ -1596,17 +1920,13 @@ finish_translation_unit ()
/* Do file scope __FUNCTION__ et al. */
finish_fname_decls ();
-
- finish_file ();
}
/* Finish a template type parameter, specified as AGGR IDENTIFIER.
Returns the parameter. */
tree
-finish_template_type_parm (aggr, identifier)
- tree aggr;
- tree identifier;
+finish_template_type_parm (tree aggr, tree identifier)
{
if (aggr != class_type_node)
{
@@ -1621,9 +1941,7 @@ finish_template_type_parm (aggr, identifier)
Returns the parameter. */
tree
-finish_template_template_parm (aggr, identifier)
- tree aggr;
- tree identifier;
+finish_template_template_parm (tree aggr, tree identifier)
{
tree decl = build_decl (TYPE_DECL, identifier, NULL_TREE);
tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE);
@@ -1646,10 +1964,24 @@ check_template_template_default_arg (tree argument)
{
if (TREE_CODE (argument) != TEMPLATE_DECL
&& TREE_CODE (argument) != TEMPLATE_TEMPLATE_PARM
- && TREE_CODE (argument) != TYPE_DECL
&& TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
{
- error ("invalid default template argument");
+ if (TREE_CODE (argument) == TYPE_DECL)
+ {
+ tree t = TREE_TYPE (argument);
+
+ /* Try to emit a slightly smarter error message if we detect
+ that the user is using a template instantiation. */
+ if (CLASSTYPE_TEMPLATE_INFO (t)
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (t))
+ error ("invalid use of type `%T' as a default value for a "
+ "template template-parameter", t);
+ else
+ error ("invalid use of `%D' as a default value for a template "
+ "template-parameter", argument);
+ }
+ else
+ error ("invalid default argument for a template template parameter");
return error_mark_node;
}
@@ -1660,9 +1992,7 @@ check_template_template_default_arg (tree argument)
nonzero, the parameter list was terminated by a `...'. */
tree
-finish_parmlist (parms, ellipsis)
- tree parms;
- int ellipsis;
+finish_parmlist (tree parms, int ellipsis)
{
if (parms)
{
@@ -1679,26 +2009,16 @@ finish_parmlist (parms, ellipsis)
/* Begin a class definition, as indicated by T. */
tree
-begin_class_definition (t)
- tree t;
+begin_class_definition (tree t)
{
if (t == error_mark_node)
return error_mark_node;
- /* Check the bases are accessible. */
- decl_type_access_control (TYPE_NAME (t));
- reset_type_access_control ();
-
if (processing_template_parmlist)
{
error ("definition of `%#T' inside template parameter list", t);
return error_mark_node;
}
-
- /* In a definition of a member class template, we will get here with
- an implicit typename. */
- if (IMPLICIT_TYPENAME_P (t))
- t = TREE_TYPE (t);
/* A non-implicit typename comes from code like:
template <typename T> struct A {
@@ -1717,61 +2037,17 @@ begin_class_definition (t)
pushtag (make_anon_name (), t, 0);
}
- /* If we generated a partial instantiation of this type, but now
- we're seeing a real definition, we're actually looking at a
- partial specialization. Consider:
-
- template <class T, class U>
- struct Y {};
-
- template <class T>
- struct X {};
-
- template <class T, class U>
- void f()
- {
- typename X<Y<T, U> >::A a;
- }
-
- template <class T, class U>
- struct X<Y<T, U> >
- {
- };
-
- We have to undo the effects of the previous partial
- instantiation. */
- if (PARTIAL_INSTANTIATION_P (t))
- {
- if (!pedantic)
- {
- /* Unfortunately, when we're not in pedantic mode, we
- attempt to actually fill in some of the fields of the
- partial instantiation, in order to support the implicit
- typename extension. Clear those fields now, in
- preparation for the definition here. The fields cleared
- here must match those set in instantiate_class_template.
- Look for a comment mentioning begin_class_definition
- there. */
- TYPE_BINFO_BASETYPES (t) = NULL_TREE;
- TYPE_FIELDS (t) = NULL_TREE;
- TYPE_METHODS (t) = NULL_TREE;
- CLASSTYPE_DECL_LIST (t) = NULL_TREE;
- CLASSTYPE_NESTED_UDTS (t) = NULL;
- CLASSTYPE_VBASECLASSES (t) = NULL_TREE;
- TYPE_SIZE (t) = NULL_TREE;
- }
-
- /* This isn't a partial instantiation any more. */
- PARTIAL_INSTANTIATION_P (t) = 0;
- }
/* If this type was already complete, and we see another definition,
that's an error. */
- else if (COMPLETE_TYPE_P (t))
- duplicate_tag_error (t);
+ if (COMPLETE_TYPE_P (t))
+ {
+ error ("redefinition of `%#T'", t);
+ cp_error_at ("previous definition of `%#T'", t);
+ return error_mark_node;
+ }
/* Update the location of the decl. */
- DECL_SOURCE_FILE (TYPE_NAME (t)) = input_filename;
- DECL_SOURCE_LINE (TYPE_NAME (t)) = lineno;
+ DECL_SOURCE_LOCATION (TYPE_NAME (t)) = input_location;
if (TYPE_BEING_DEFINED (t))
{
@@ -1779,9 +2055,18 @@ begin_class_definition (t)
pushtag (TYPE_IDENTIFIER (t), t, 0);
}
maybe_process_partial_specialization (t);
- pushclass (t, 1);
+ pushclass (t);
TYPE_BEING_DEFINED (t) = 1;
- TYPE_PACKED (t) = flag_pack_struct;
+ if (flag_pack_struct)
+ {
+ tree v;
+ TYPE_PACKED (t) = 1;
+ /* Even though the type is being defined for the first time
+ here, there might have been a forward declaration, so there
+ might be cv-qualified variants of T. */
+ for (v = TYPE_NEXT_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
+ TYPE_PACKED (v) = 1;
+ }
/* Reset the interface data, at the earliest possible
moment, as it might have been set via a class foo;
before. */
@@ -1802,8 +2087,7 @@ begin_class_definition (t)
/* Finish the member declaration given by DECL. */
void
-finish_member_declaration (decl)
- tree decl;
+finish_member_declaration (tree decl)
{
if (decl == error_mark_node || decl == NULL_TREE)
return;
@@ -1854,7 +2138,8 @@ finish_member_declaration (decl)
/*friend_p=*/0);
}
/* Enter the DECL into the scope of the class. */
- else if (TREE_CODE (decl) == USING_DECL || pushdecl_class_level (decl))
+ else if ((TREE_CODE (decl) == USING_DECL && TREE_TYPE (decl))
+ || pushdecl_class_level (decl))
{
/* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields
go at the beginning. The reason is that lookup_field_1
@@ -1887,65 +2172,11 @@ finish_member_declaration (decl)
}
}
-/* Finish a class definition T with the indicate ATTRIBUTES. If SEMI,
- the definition is immediately followed by a semicolon. Returns the
- type. */
-
-tree
-finish_class_definition (t, attributes, semi, pop_scope_p)
- tree t;
- tree attributes;
- int semi;
- int pop_scope_p;
-{
- if (t == error_mark_node)
- return error_mark_node;
-
- /* finish_struct nukes this anyway; if finish_exception does too,
- then it can go. */
- if (semi)
- note_got_semicolon (t);
-
- /* If we got any attributes in class_head, xref_tag will stick them in
- TREE_TYPE of the type. Grab them now. */
- attributes = chainon (TYPE_ATTRIBUTES (t), attributes);
- TYPE_ATTRIBUTES (t) = NULL_TREE;
-
- if (TREE_CODE (t) == ENUMERAL_TYPE)
- ;
- else
- {
- t = finish_struct (t, attributes);
- if (semi)
- note_got_semicolon (t);
- }
-
- if (! semi)
- check_for_missing_semicolon (t);
- if (pop_scope_p)
- pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL (t)));
- if (current_scope () == current_function_decl)
- do_pending_defargs ();
-
- return t;
-}
-
-/* Finish processing the default argument expressions cached during
- the processing of a class definition. */
-
-void
-begin_inline_definitions ()
-{
- if (current_scope () == current_function_decl)
- do_pending_inlines ();
-}
-
/* Finish processing the declaration of a member class template
TYPES whose template parameters are given by PARMS. */
tree
-finish_member_class_template (types)
- tree types;
+finish_member_class_template (tree types)
{
tree t;
@@ -1956,7 +2187,6 @@ finish_member_class_template (types)
if (IS_AGGR_TYPE_CODE (TREE_CODE (TREE_VALUE (t))))
maybe_process_partial_specialization (TREE_VALUE (t));
- note_list_got_semicolon (types);
grok_x_components (types);
if (TYPE_CONTEXT (TREE_VALUE (types)) != current_class_type)
/* The component was in fact a friend declaration. We avoid
@@ -1976,8 +2206,7 @@ finish_member_class_template (types)
the template parameters. */
void
-finish_template_decl (parms)
- tree parms;
+finish_template_decl (tree parms)
{
if (parms)
end_template_decl ();
@@ -1991,50 +2220,19 @@ finish_template_decl (parms)
the scope of template-id indicated. */
tree
-finish_template_type (name, args, entering_scope)
- tree name;
- tree args;
- int entering_scope;
+finish_template_type (tree name, tree args, int entering_scope)
{
tree decl;
decl = lookup_template_class (name, args,
- NULL_TREE, NULL_TREE,
- entering_scope, /*complain=*/1);
+ NULL_TREE, NULL_TREE, entering_scope,
+ tf_error | tf_warning | tf_user);
if (decl != error_mark_node)
decl = TYPE_STUB_DECL (decl);
return decl;
}
-/* SR is a SCOPE_REF node. Enter the scope of SR, whether it is a
- namespace scope or a class scope. */
-
-void
-enter_scope_of (sr)
- tree sr;
-{
- tree scope = TREE_OPERAND (sr, 0);
-
- if (TREE_CODE (scope) == NAMESPACE_DECL)
- {
- push_decl_namespace (scope);
- TREE_COMPLEXITY (sr) = -1;
- }
- else if (scope != current_class_type)
- {
- if (TREE_CODE (scope) == TYPENAME_TYPE)
- {
- /* In a declarator for a template class member, the scope will
- get here as an implicit typename, a TYPENAME_TYPE with a type. */
- scope = TREE_TYPE (scope);
- TREE_OPERAND (sr, 0) = scope;
- }
- push_nested_class (scope, 3);
- TREE_COMPLEXITY (sr) = current_class_depth;
- }
-}
-
/* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER.
Return a TREE_LIST containing the ACCESS_SPECIFIER and the
BASE_CLASS, or NULL_TREE if an error occurred. The
@@ -2042,37 +2240,36 @@ enter_scope_of (sr)
access_{default,public,protected_private}[_virtual]_node.*/
tree
-finish_base_specifier (access_specifier, base_class)
- tree access_specifier;
- tree base_class;
+finish_base_specifier (tree base, tree access, bool virtual_p)
{
tree result;
- if (base_class == error_mark_node)
+ if (base == error_mark_node)
{
error ("invalid base-class specification");
result = NULL_TREE;
}
- else if (! is_aggr_type (base_class, 1))
+ else if (! is_aggr_type (base, 1))
result = NULL_TREE;
else
{
- if (cp_type_quals (base_class) != 0)
+ if (cp_type_quals (base) != 0)
{
- error ("base class `%T' has cv qualifiers", base_class);
- base_class = TYPE_MAIN_VARIANT (base_class);
+ error ("base class `%T' has cv qualifiers", base);
+ base = TYPE_MAIN_VARIANT (base);
}
- result = build_tree_list (access_specifier, base_class);
+ result = build_tree_list (access, base);
+ TREE_VIA_VIRTUAL (result) = virtual_p;
}
return result;
}
/* Called when multiple declarators are processed. If that is not
- premitted in this context, an error is issued. */
+ permitted in this context, an error is issued. */
void
-check_multiple_declarators ()
+check_multiple_declarators (void)
{
/* [temp]
@@ -2093,16 +2290,420 @@ check_multiple_declarators ()
error ("multiple declarators in template declaration");
}
+/* Issue a diagnostic that NAME cannot be found in SCOPE. */
+
+void
+qualified_name_lookup_error (tree scope, tree name)
+{
+ if (TYPE_P (scope))
+ {
+ if (!COMPLETE_TYPE_P (scope))
+ error ("incomplete type `%T' used in nested name specifier", scope);
+ else
+ error ("`%D' is not a member of `%T'", name, scope);
+ }
+ else if (scope != global_namespace)
+ error ("`%D' is not a member of `%D'", name, scope);
+ else
+ error ("`::%D' has not been declared", name);
+}
+
+/* ID_EXPRESSION is a representation of parsed, but unprocessed,
+ id-expression. (See cp_parser_id_expression for details.) SCOPE,
+ if non-NULL, is the type or namespace used to explicitly qualify
+ ID_EXPRESSION. DECL is the entity to which that name has been
+ resolved.
+
+ *CONSTANT_EXPRESSION_P is true if we are presently parsing a
+ constant-expression. In that case, *NON_CONSTANT_EXPRESSION_P will
+ be set to true if this expression isn't permitted in a
+ constant-expression, but it is otherwise not set by this function.
+ *ALLOW_NON_CONSTANT_EXPRESSION_P is true if we are parsing a
+ constant-expression, but a non-constant expression is also
+ permissible.
+
+ If an error occurs, and it is the kind of error that might cause
+ the parser to abort a tentative parse, *ERROR_MSG is filled in. It
+ is the caller's responsibility to issue the message. *ERROR_MSG
+ will be a string with static storage duration, so the caller need
+ not "free" it.
+
+ Return an expression for the entity, after issuing appropriate
+ diagnostics. This function is also responsible for transforming a
+ reference to a non-static member into a COMPONENT_REF that makes
+ the use of "this" explicit.
+
+ Upon return, *IDK will be filled in appropriately. */
+
+tree
+finish_id_expression (tree id_expression,
+ tree decl,
+ tree scope,
+ cp_id_kind *idk,
+ tree *qualifying_class,
+ bool integral_constant_expression_p,
+ bool allow_non_integral_constant_expression_p,
+ bool *non_integral_constant_expression_p,
+ const char **error_msg)
+{
+ /* Initialize the output parameters. */
+ *idk = CP_ID_KIND_NONE;
+ *error_msg = NULL;
+
+ if (id_expression == error_mark_node)
+ return error_mark_node;
+ /* If we have a template-id, then no further lookup is
+ required. If the template-id was for a template-class, we
+ will sometimes have a TYPE_DECL at this point. */
+ else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
+ || TREE_CODE (decl) == TYPE_DECL)
+ ;
+ /* Look up the name. */
+ else
+ {
+ if (decl == error_mark_node)
+ {
+ /* Name lookup failed. */
+ if (scope
+ && (!TYPE_P (scope)
+ || (!dependent_type_p (scope)
+ && !(TREE_CODE (id_expression) == IDENTIFIER_NODE
+ && IDENTIFIER_TYPENAME_P (id_expression)
+ && dependent_type_p (TREE_TYPE (id_expression))))))
+ {
+ /* If the qualifying type is non-dependent (and the name
+ does not name a conversion operator to a dependent
+ type), issue an error. */
+ qualified_name_lookup_error (scope, id_expression);
+ return error_mark_node;
+ }
+ else if (!scope)
+ {
+ /* It may be resolved via Koenig lookup. */
+ *idk = CP_ID_KIND_UNQUALIFIED;
+ return id_expression;
+ }
+ else
+ decl = id_expression;
+ }
+ /* If DECL is a variable that would be out of scope under
+ ANSI/ISO rules, but in scope in the ARM, name lookup
+ will succeed. Issue a diagnostic here. */
+ else
+ decl = check_for_out_of_scope_variable (decl);
+
+ /* Remember that the name was used in the definition of
+ the current class so that we can check later to see if
+ the meaning would have been different after the class
+ was entirely defined. */
+ if (!scope && decl != error_mark_node)
+ maybe_note_name_used_in_class (id_expression, decl);
+ }
+
+ /* If we didn't find anything, or what we found was a type,
+ then this wasn't really an id-expression. */
+ if (TREE_CODE (decl) == TEMPLATE_DECL
+ && !DECL_FUNCTION_TEMPLATE_P (decl))
+ {
+ *error_msg = "missing template arguments";
+ return error_mark_node;
+ }
+ else if (TREE_CODE (decl) == TYPE_DECL
+ || TREE_CODE (decl) == NAMESPACE_DECL)
+ {
+ *error_msg = "expected primary-expression";
+ return error_mark_node;
+ }
+
+ /* If the name resolved to a template parameter, there is no
+ need to look it up again later. */
+ if ((TREE_CODE (decl) == CONST_DECL && DECL_TEMPLATE_PARM_P (decl))
+ || TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
+ {
+ *idk = CP_ID_KIND_NONE;
+ if (TREE_CODE (decl) == TEMPLATE_PARM_INDEX)
+ decl = TEMPLATE_PARM_DECL (decl);
+ if (integral_constant_expression_p
+ && !dependent_type_p (TREE_TYPE (decl))
+ && !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl)))
+ {
+ if (!allow_non_integral_constant_expression_p)
+ error ("template parameter `%D' of type `%T' is not allowed in "
+ "an integral constant expression because it is not of "
+ "integral or enumeration type", decl, TREE_TYPE (decl));
+ *non_integral_constant_expression_p = true;
+ }
+ return DECL_INITIAL (decl);
+ }
+ /* Similarly, we resolve enumeration constants to their
+ underlying values. */
+ else if (TREE_CODE (decl) == CONST_DECL)
+ {
+ *idk = CP_ID_KIND_NONE;
+ if (!processing_template_decl)
+ return DECL_INITIAL (decl);
+ return decl;
+ }
+ else
+ {
+ bool dependent_p;
+
+ /* If the declaration was explicitly qualified indicate
+ that. The semantics of `A::f(3)' are different than
+ `f(3)' if `f' is virtual. */
+ *idk = (scope
+ ? CP_ID_KIND_QUALIFIED
+ : (TREE_CODE (decl) == TEMPLATE_ID_EXPR
+ ? CP_ID_KIND_TEMPLATE_ID
+ : CP_ID_KIND_UNQUALIFIED));
+
+
+ /* [temp.dep.expr]
+
+ An id-expression is type-dependent if it contains an
+ identifier that was declared with a dependent type.
+
+ The standard is not very specific about an id-expression that
+ names a set of overloaded functions. What if some of them
+ have dependent types and some of them do not? Presumably,
+ such a name should be treated as a dependent name. */
+ /* Assume the name is not dependent. */
+ dependent_p = false;
+ if (!processing_template_decl)
+ /* No names are dependent outside a template. */
+ ;
+ /* A template-id where the name of the template was not resolved
+ is definitely dependent. */
+ else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
+ && (TREE_CODE (TREE_OPERAND (decl, 0))
+ == IDENTIFIER_NODE))
+ dependent_p = true;
+ /* For anything except an overloaded function, just check its
+ type. */
+ else if (!is_overloaded_fn (decl))
+ dependent_p
+ = dependent_type_p (TREE_TYPE (decl));
+ /* For a set of overloaded functions, check each of the
+ functions. */
+ else
+ {
+ tree fns = decl;
+
+ if (BASELINK_P (fns))
+ fns = BASELINK_FUNCTIONS (fns);
+
+ /* For a template-id, check to see if the template
+ arguments are dependent. */
+ if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
+ {
+ tree args = TREE_OPERAND (fns, 1);
+ dependent_p = any_dependent_template_arguments_p (args);
+ /* The functions are those referred to by the
+ template-id. */
+ fns = TREE_OPERAND (fns, 0);
+ }
+
+ /* If there are no dependent template arguments, go through
+ the overloaded functions. */
+ while (fns && !dependent_p)
+ {
+ tree fn = OVL_CURRENT (fns);
+
+ /* Member functions of dependent classes are
+ dependent. */
+ if (TREE_CODE (fn) == FUNCTION_DECL
+ && type_dependent_expression_p (fn))
+ dependent_p = true;
+ else if (TREE_CODE (fn) == TEMPLATE_DECL
+ && dependent_template_p (fn))
+ dependent_p = true;
+
+ fns = OVL_NEXT (fns);
+ }
+ }
+
+ /* If the name was dependent on a template parameter, we will
+ resolve the name at instantiation time. */
+ if (dependent_p)
+ {
+ /* Create a SCOPE_REF for qualified names, if the scope is
+ dependent. */
+ if (scope)
+ {
+ if (TYPE_P (scope))
+ *qualifying_class = scope;
+ /* Since this name was dependent, the expression isn't
+ constant -- yet. No error is issued because it might
+ be constant when things are instantiated. */
+ if (integral_constant_expression_p)
+ *non_integral_constant_expression_p = true;
+ if (TYPE_P (scope) && dependent_type_p (scope))
+ return build_nt (SCOPE_REF, scope, id_expression);
+ else if (TYPE_P (scope) && DECL_P (decl))
+ return build (SCOPE_REF, TREE_TYPE (decl), scope,
+ id_expression);
+ else
+ return decl;
+ }
+ /* A TEMPLATE_ID already contains all the information we
+ need. */
+ if (TREE_CODE (id_expression) == TEMPLATE_ID_EXPR)
+ return id_expression;
+ /* Since this name was dependent, the expression isn't
+ constant -- yet. No error is issued because it might be
+ constant when things are instantiated. */
+ if (integral_constant_expression_p)
+ *non_integral_constant_expression_p = true;
+ *idk = CP_ID_KIND_UNQUALIFIED_DEPENDENT;
+ /* If we found a variable, then name lookup during the
+ instantiation will always resolve to the same VAR_DECL
+ (or an instantiation thereof). */
+ if (TREE_CODE (decl) == VAR_DECL
+ || TREE_CODE (decl) == PARM_DECL)
+ return decl;
+ return id_expression;
+ }
+
+ /* Only certain kinds of names are allowed in constant
+ expression. Enumerators and template parameters
+ have already been handled above. */
+ if (integral_constant_expression_p)
+ {
+ /* Const variables or static data members of integral or
+ enumeration types initialized with constant expressions
+ are OK. */
+ if (TREE_CODE (decl) == VAR_DECL
+ && CP_TYPE_CONST_P (TREE_TYPE (decl))
+ && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl))
+ && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
+ ;
+ else
+ {
+ if (!allow_non_integral_constant_expression_p)
+ {
+ error ("`%D' cannot appear in a constant-expression", decl);
+ return error_mark_node;
+ }
+ *non_integral_constant_expression_p = true;
+ }
+ }
+
+ if (TREE_CODE (decl) == NAMESPACE_DECL)
+ {
+ error ("use of namespace `%D' as expression", decl);
+ return error_mark_node;
+ }
+ else if (DECL_CLASS_TEMPLATE_P (decl))
+ {
+ error ("use of class template `%T' as expression", decl);
+ return error_mark_node;
+ }
+ else if (TREE_CODE (decl) == TREE_LIST)
+ {
+ /* Ambiguous reference to base members. */
+ error ("request for member `%D' is ambiguous in "
+ "multiple inheritance lattice", id_expression);
+ print_candidates (decl);
+ return error_mark_node;
+ }
+
+ /* Mark variable-like entities as used. Functions are similarly
+ marked either below or after overload resolution. */
+ if (TREE_CODE (decl) == VAR_DECL
+ || TREE_CODE (decl) == PARM_DECL
+ || TREE_CODE (decl) == RESULT_DECL)
+ mark_used (decl);
+
+ if (scope)
+ {
+ decl = (adjust_result_of_qualified_name_lookup
+ (decl, scope, current_class_type));
+
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ mark_used (decl);
+
+ if (TREE_CODE (decl) == FIELD_DECL || BASELINK_P (decl))
+ *qualifying_class = scope;
+ else if (!processing_template_decl)
+ decl = convert_from_reference (decl);
+ else if (TYPE_P (scope))
+ decl = build (SCOPE_REF, TREE_TYPE (decl), scope, decl);
+ }
+ else if (TREE_CODE (decl) == FIELD_DECL)
+ decl = finish_non_static_data_member (decl, current_class_ref,
+ /*qualifying_scope=*/NULL_TREE);
+ else if (is_overloaded_fn (decl))
+ {
+ tree first_fn = OVL_CURRENT (decl);
+
+ if (TREE_CODE (first_fn) == TEMPLATE_DECL)
+ first_fn = DECL_TEMPLATE_RESULT (first_fn);
+
+ if (!really_overloaded_fn (decl))
+ mark_used (first_fn);
+
+ if (TREE_CODE (first_fn) == FUNCTION_DECL
+ && DECL_FUNCTION_MEMBER_P (first_fn))
+ {
+ /* A set of member functions. */
+ decl = maybe_dummy_object (DECL_CONTEXT (first_fn), 0);
+ return finish_class_member_access_expr (decl, id_expression);
+ }
+ }
+ else
+ {
+ if (TREE_CODE (decl) == VAR_DECL
+ || TREE_CODE (decl) == PARM_DECL
+ || TREE_CODE (decl) == RESULT_DECL)
+ {
+ tree context = decl_function_context (decl);
+
+ if (context != NULL_TREE && context != current_function_decl
+ && ! TREE_STATIC (decl))
+ {
+ error ("use of %s from containing function",
+ (TREE_CODE (decl) == VAR_DECL
+ ? "`auto' variable" : "parameter"));
+ cp_error_at (" `%#D' declared here", decl);
+ return error_mark_node;
+ }
+ }
+
+ if (DECL_P (decl) && DECL_NONLOCAL (decl)
+ && DECL_CLASS_SCOPE_P (decl)
+ && DECL_CONTEXT (decl) != current_class_type)
+ {
+ tree path;
+
+ path = currently_open_derived_class (DECL_CONTEXT (decl));
+ perform_or_defer_access_check (TYPE_BINFO (path), decl);
+ }
+
+ if (! processing_template_decl)
+ decl = convert_from_reference (decl);
+ }
+
+ /* Resolve references to variables of anonymous unions
+ into COMPONENT_REFs. */
+ if (TREE_CODE (decl) == ALIAS_DECL)
+ decl = DECL_INITIAL (decl);
+ }
+
+ if (TREE_DEPRECATED (decl))
+ warn_deprecated_use (decl);
+
+ return decl;
+}
+
/* Implement the __typeof keyword: Return the type of EXPR, suitable for
use as a type-specifier. */
tree
-finish_typeof (expr)
- tree expr;
+finish_typeof (tree expr)
{
tree type;
- if (processing_template_decl)
+ if (type_dependent_expression_p (expr))
{
type = make_aggr_type (TYPEOF_TYPE);
TYPE_FIELDS (type) = expr;
@@ -2110,9 +2711,6 @@ finish_typeof (expr)
return type;
}
- if (TREE_CODE (expr) == OFFSET_REF)
- expr = resolve_offset_ref (expr);
-
type = TREE_TYPE (expr);
if (!type || type == unknown_type_node)
@@ -2124,37 +2722,11 @@ finish_typeof (expr)
return type;
}
-/* Compute the value of the `sizeof' operator. */
-
-tree
-finish_sizeof (t)
- tree t;
-{
- if (processing_template_decl)
- return build_min_nt (SIZEOF_EXPR, t);
-
- return TYPE_P (t) ? cxx_sizeof (t) : expr_sizeof (t);
-}
-
-/* Implement the __alignof keyword: Return the minimum required
- alignment of T, measured in bytes. */
-
-tree
-finish_alignof (t)
- tree t;
-{
- if (processing_template_decl)
- return build_min_nt (ALIGNOF_EXPR, t);
-
- return TYPE_P (t) ? cxx_alignof (t) : c_alignof_expr (t);
-}
-
/* Generate RTL for the statement T, and its substatements, and any
other statements at its nesting level. */
static void
-cp_expand_stmt (t)
- tree t;
+cp_expand_stmt (tree t)
{
switch (TREE_CODE (t))
{
@@ -2170,10 +2742,6 @@ cp_expand_stmt (t)
genrtl_handler (t);
break;
- case RETURN_INIT:
- genrtl_named_return_value ();
- break;
-
case USING_STMT:
break;
@@ -2187,95 +2755,120 @@ cp_expand_stmt (t)
will equivalent CALL_EXPRs. */
static tree
-simplify_aggr_init_exprs_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+simplify_aggr_init_exprs_r (tree* tp,
+ int* walk_subtrees,
+ void* data ATTRIBUTE_UNUSED)
{
- tree aggr_init_expr;
- tree call_expr;
- tree fn;
- tree args;
- tree slot;
- tree type;
- int copy_from_buffer_p;
-
- aggr_init_expr = *tp;
/* We don't need to walk into types; there's nothing in a type that
needs simplification. (And, furthermore, there are places we
actively don't want to go. For example, we don't want to wander
into the default arguments for a FUNCTION_DECL that appears in a
CALL_EXPR.) */
- if (TYPE_P (aggr_init_expr))
+ if (TYPE_P (*tp))
{
*walk_subtrees = 0;
return NULL_TREE;
}
/* Only AGGR_INIT_EXPRs are interesting. */
- else if (TREE_CODE (aggr_init_expr) != AGGR_INIT_EXPR)
+ else if (TREE_CODE (*tp) != AGGR_INIT_EXPR)
return NULL_TREE;
+ simplify_aggr_init_expr (tp);
+
+ /* Keep iterating. */
+ return NULL_TREE;
+}
+
+/* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. This
+ function is broken out from the above for the benefit of the tree-ssa
+ project. */
+
+void
+simplify_aggr_init_expr (tree *tp)
+{
+ tree aggr_init_expr = *tp;
+
/* Form an appropriate CALL_EXPR. */
- fn = TREE_OPERAND (aggr_init_expr, 0);
- args = TREE_OPERAND (aggr_init_expr, 1);
- slot = TREE_OPERAND (aggr_init_expr, 2);
- type = TREE_TYPE (aggr_init_expr);
+ tree fn = TREE_OPERAND (aggr_init_expr, 0);
+ tree args = TREE_OPERAND (aggr_init_expr, 1);
+ tree slot = TREE_OPERAND (aggr_init_expr, 2);
+ tree type = TREE_TYPE (aggr_init_expr);
+
+ tree call_expr;
+ enum style_t { ctor, arg, pcc } style;
+
if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr))
+ style = ctor;
+#ifdef PCC_STATIC_STRUCT_RETURN
+ else if (1)
+ style = pcc;
+#endif
+ else if (TREE_ADDRESSABLE (type))
+ style = arg;
+ else
+ /* We shouldn't build an AGGR_INIT_EXPR if we don't need any special
+ handling. See build_cplus_new. */
+ abort ();
+
+ if (style == ctor || style == arg)
{
- /* Replace the first argument with the address of the third
- argument to the AGGR_INIT_EXPR. */
+ /* Pass the address of the slot. If this is a constructor, we
+ replace the first argument; otherwise, we tack on a new one. */
+ tree addr;
+
+ if (style == ctor)
+ args = TREE_CHAIN (args);
+
cxx_mark_addressable (slot);
- args = tree_cons (NULL_TREE,
- build1 (ADDR_EXPR,
- build_pointer_type (TREE_TYPE (slot)),
- slot),
- TREE_CHAIN (args));
+ addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (slot)), slot);
+ if (style == arg)
+ {
+ /* The return type might have different cv-quals from the slot. */
+ tree fntype = TREE_TYPE (TREE_TYPE (fn));
+#ifdef ENABLE_CHECKING
+ if (TREE_CODE (fntype) != FUNCTION_TYPE
+ && TREE_CODE (fntype) != METHOD_TYPE)
+ abort ();
+#endif
+ addr = convert (build_pointer_type (TREE_TYPE (fntype)), addr);
+ }
+
+ args = tree_cons (NULL_TREE, addr, args);
}
+
call_expr = build (CALL_EXPR,
TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
fn, args, NULL_TREE);
- TREE_SIDE_EFFECTS (call_expr) = 1;
- /* If we're using the non-reentrant PCC calling convention, then we
- need to copy the returned value out of the static buffer into the
- SLOT. */
- copy_from_buffer_p = 0;
-#ifdef PCC_STATIC_STRUCT_RETURN
- if (!AGGR_INIT_VIA_CTOR_P (aggr_init_expr) && aggregate_value_p (type))
+ if (style == arg)
+ /* Tell the backend that we've added our return slot to the argument
+ list. */
+ CALL_EXPR_HAS_RETURN_SLOT_ADDR (call_expr) = 1;
+ else if (style == pcc)
{
- int old_ac = flag_access_control;
-
- flag_access_control = 0;
+ /* If we're using the non-reentrant PCC calling convention, then we
+ need to copy the returned value out of the static buffer into the
+ SLOT. */
+ push_deferring_access_checks (dk_no_check);
call_expr = build_aggr_init (slot, call_expr,
DIRECT_BIND | LOOKUP_ONLYCONVERTING);
- flag_access_control = old_ac;
- copy_from_buffer_p = 1;
+ pop_deferring_access_checks ();
}
-#endif
- /* If this AGGR_INIT_EXPR indicates the value returned by a
- function, then we want to use the value of the initialized
- location as the result. */
- if (AGGR_INIT_VIA_CTOR_P (aggr_init_expr) || copy_from_buffer_p)
- {
- call_expr = build (COMPOUND_EXPR, type,
- call_expr, slot);
- TREE_SIDE_EFFECTS (call_expr) = 1;
- }
+ /* We want to use the value of the initialized location as the
+ result. */
+ call_expr = build (COMPOUND_EXPR, type,
+ call_expr, slot);
/* Replace the AGGR_INIT_EXPR with the CALL_EXPR. */
TREE_CHAIN (call_expr) = TREE_CHAIN (aggr_init_expr);
*tp = call_expr;
-
- /* Keep iterating. */
- return NULL_TREE;
}
/* Emit all thunks to FN that should be emitted when FN is emitted. */
static void
-emit_associated_thunks (fn)
- tree fn;
+emit_associated_thunks (tree fn)
{
/* When we use vcall offsets, we emit thunks with the virtual
functions to which they thunk. The whole point of vcall offsets
@@ -2285,30 +2878,104 @@ emit_associated_thunks (fn)
if (DECL_VIRTUAL_P (fn))
{
tree thunk;
+
for (thunk = DECL_THUNKS (fn); thunk; thunk = TREE_CHAIN (thunk))
- use_thunk (thunk, /*emit_p=*/1);
+ {
+ if (!THUNK_ALIAS (thunk))
+ {
+ use_thunk (thunk, /*emit_p=*/1);
+ if (DECL_RESULT_THUNK_P (thunk))
+ {
+ tree probe;
+
+ for (probe = DECL_THUNKS (thunk);
+ probe; probe = TREE_CHAIN (probe))
+ use_thunk (probe, /*emit_p=*/1);
+ }
+ }
+ else
+ my_friendly_assert (!DECL_THUNKS (thunk), 20031023);
+ }
}
}
/* Generate RTL for FN. */
void
-expand_body (fn)
- tree fn;
+expand_body (tree fn)
{
- int saved_lineno;
- const char *saved_input_filename;
tree saved_function;
+
+ /* Compute the appropriate object-file linkage for inline
+ functions. */
+ if (DECL_DECLARED_INLINE_P (fn))
+ import_export_decl (fn);
+
+ /* If FN is external, then there's no point in generating RTL for
+ it. This situation can arise with an inline function under
+ `-fexternal-templates'; we instantiate the function, even though
+ we're not planning on emitting it, in case we get a chance to
+ inline it. */
+ if (DECL_EXTERNAL (fn))
+ return;
+
+ /* ??? When is this needed? */
+ saved_function = current_function_decl;
+
+ /* Emit any thunks that should be emitted at the same time as FN. */
+ emit_associated_thunks (fn);
+
+ timevar_push (TV_INTEGRATION);
+ optimize_function (fn);
+ timevar_pop (TV_INTEGRATION);
+
+ tree_rest_of_compilation (fn, function_depth > 1);
+
+ current_function_decl = saved_function;
+
+ extract_interface_info ();
+ /* If this function is marked with the constructor attribute, add it
+ to the list of functions to be called along with constructors
+ from static duration objects. */
+ if (DECL_STATIC_CONSTRUCTOR (fn))
+ static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
+
+ /* If this function is marked with the destructor attribute, add it
+ to the list of functions to be called along with destructors from
+ static duration objects. */
+ if (DECL_STATIC_DESTRUCTOR (fn))
+ static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
+
+ if (DECL_CLONED_FUNCTION_P (fn))
+ {
+ /* If this is a clone, go through the other clones now and mark
+ their parameters used. We have to do that here, as we don't
+ know whether any particular clone will be expanded, and
+ therefore cannot pick one arbitrarily. */
+ tree probe;
+
+ for (probe = TREE_CHAIN (DECL_CLONED_FUNCTION (fn));
+ probe && DECL_CLONED_FUNCTION_P (probe);
+ probe = TREE_CHAIN (probe))
+ {
+ tree parms;
+
+ for (parms = DECL_ARGUMENTS (probe);
+ parms; parms = TREE_CHAIN (parms))
+ TREE_USED (parms) = 1;
+ }
+ }
+}
+
+/* Generate RTL for FN. */
+
+void
+expand_or_defer_fn (tree fn)
+{
/* When the parser calls us after finishing the body of a template
- function, we don't really want to expand the body. When we're
- processing an in-class definition of an inline function,
- PROCESSING_TEMPLATE_DECL will no longer be set here, so we have
- to look at the function itself. */
- if (processing_template_decl
- || (DECL_LANG_SPECIFIC (fn)
- && DECL_TEMPLATE_INFO (fn)
- && uses_template_parms (DECL_TI_ARGS (fn))))
+ function, we don't really want to expand the body. */
+ if (processing_template_decl)
{
/* Normally, collection only occurs in rest_of_compilation. So,
if we don't collect here, we never collect junk generated
@@ -2338,102 +3005,16 @@ expand_body (fn)
if (flag_syntax_only)
return;
- /* If possible, avoid generating RTL for this function. Instead,
- just record it as an inline function, and wait until end-of-file
- to decide whether to write it out or not. */
- if (/* We have to generate RTL if it's not an inline function. */
- (DECL_INLINE (fn) || DECL_COMDAT (fn))
- /* Or if we have to emit code for inline functions anyhow. */
- && !flag_keep_inline_functions
- /* Or if we actually have a reference to the function. */
- && !DECL_NEEDED_P (fn))
- {
- /* Set DECL_EXTERNAL so that assemble_external will be called as
- necessary. We'll clear it again in finish_file. */
- if (!DECL_EXTERNAL (fn))
- {
- DECL_NOT_REALLY_EXTERN (fn) = 1;
- DECL_EXTERNAL (fn) = 1;
- }
- /* Remember this function. In finish_file we'll decide if
- we actually need to write this function out. */
- defer_fn (fn);
- /* Let the back-end know that this function exists. */
- (*debug_hooks->deferred_inline_function) (fn);
- return;
- }
-
- /* Compute the appropriate object-file linkage for inline
- functions. */
+ /* Compute the appropriate object-file linkage for inline functions. */
if (DECL_DECLARED_INLINE_P (fn))
import_export_decl (fn);
- /* If FN is external, then there's no point in generating RTL for
- it. This situation can arise with an inline function under
- `-fexternal-templates'; we instantiate the function, even though
- we're not planning on emitting it, in case we get a chance to
- inline it. */
- if (DECL_EXTERNAL (fn))
- return;
-
- /* Save the current file name and line number. When we expand the
- body of the function, we'll set LINENO and INPUT_FILENAME so that
- error-mesages come out in the right places. */
- saved_lineno = lineno;
- saved_input_filename = input_filename;
- saved_function = current_function_decl;
- lineno = DECL_SOURCE_LINE (fn);
- input_filename = DECL_SOURCE_FILE (fn);
- current_function_decl = fn;
+ function_depth++;
- timevar_push (TV_INTEGRATION);
-
- /* Optimize the body of the function before expanding it. */
- optimize_function (fn);
-
- timevar_pop (TV_INTEGRATION);
- timevar_push (TV_EXPAND);
+ /* Expand or defer, at the whim of the compilation unit manager. */
+ cgraph_finalize_function (fn, function_depth > 1);
- genrtl_start_function (fn);
- current_function_is_thunk = DECL_THUNK_P (fn);
-
- /* Expand the body. */
- expand_stmt (DECL_SAVED_TREE (fn));
-
- /* Statements should always be full-expressions at the outermost set
- of curly braces for a function. */
- my_friendly_assert (stmts_are_full_exprs_p (), 19990831);
-
- /* The outermost statement for a function contains the line number
- recorded when we finished processing the function. */
- lineno = STMT_LINENO (DECL_SAVED_TREE (fn));
-
- /* Generate code for the function. */
- genrtl_finish_function (fn);
-
- /* If possible, obliterate the body of the function so that it can
- be garbage collected. */
- if (dump_enabled_p (TDI_all))
- /* Keep the body; we're going to dump it. */
- ;
- else if (DECL_INLINE (fn) && flag_inline_trees)
- /* We might need the body of this function so that we can expand
- it inline somewhere else. */
- ;
- else
- /* We don't need the body; blow it away. */
- DECL_SAVED_TREE (fn) = NULL_TREE;
-
- /* And restore the current source position. */
- current_function_decl = saved_function;
- lineno = saved_lineno;
- input_filename = saved_input_filename;
- extract_interface_info ();
-
- timevar_pop (TV_EXPAND);
-
- /* Emit any thunks that should be emitted at the same time as FN. */
- emit_associated_thunks (fn);
+ function_depth--;
}
/* Helper function for walk_tree, used by finish_function to override all
@@ -2441,10 +3022,7 @@ expand_body (fn)
value optimization. */
tree
-nullify_returns_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees;
- void *data;
+nullify_returns_r (tree* tp, int* walk_subtrees, void* data)
{
tree nrv = (tree) data;
@@ -2464,206 +3042,20 @@ nullify_returns_r (tp, walk_subtrees, data)
/* Start generating the RTL for FN. */
-static void
-genrtl_start_function (fn)
- tree fn;
-{
- /* Tell everybody what function we're processing. */
- current_function_decl = fn;
- /* Get the RTL machinery going for this function. */
- init_function_start (fn, DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn));
- /* Let everybody know that we're expanding this function, not doing
- semantic analysis. */
- expanding_p = 1;
-
- /* Even though we're inside a function body, we still don't want to
- call expand_expr to calculate the size of a variable-sized array.
- We haven't necessarily assigned RTL to all variables yet, so it's
- not safe to try to expand expressions involving them. */
- immediate_size_expand = 0;
- cfun->x_dont_save_pending_sizes_p = 1;
-
- /* Let the user know we're compiling this function. */
- announce_function (fn);
-
- /* Initialize the per-function data. */
- my_friendly_assert (!DECL_PENDING_INLINE_P (fn), 20000911);
- if (DECL_SAVED_FUNCTION_DATA (fn))
- {
- /* If we already parsed this function, and we're just expanding it
- now, restore saved state. */
- *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (fn);
-
- /* This function is being processed in whole-function mode; we
- already did semantic analysis. */
- cfun->x_whole_function_mode_p = 1;
-
- /* If we decided that we didn't want to inline this function,
- make sure the back-end knows that. */
- if (!current_function_cannot_inline)
- current_function_cannot_inline = cp_function_chain->cannot_inline;
-
- /* We don't need the saved data anymore. Unless this is an inline
- function; we need the named return value info for
- cp_copy_res_decl_for_inlining. */
- if (! DECL_INLINE (fn))
- DECL_SAVED_FUNCTION_DATA (fn) = NULL;
- }
-
- /* Keep track of how many functions we're presently expanding. */
- ++function_depth;
-
- /* Create a binding level for the parameters. */
- expand_function_start (fn, /*parms_have_cleanups=*/0);
- /* If this function is `main'. */
- if (DECL_MAIN_P (fn))
- expand_main_function ();
-
+void
+cxx_expand_function_start (void)
+{
/* Give our named return value the same RTL as our RESULT_DECL. */
if (current_function_return_value)
- COPY_DECL_RTL (DECL_RESULT (fn), current_function_return_value);
-}
-
-/* Finish generating the RTL for FN. */
-
-static void
-genrtl_finish_function (fn)
- tree fn;
-{
- tree t;
-
-#if 0
- if (write_symbols != NO_DEBUG)
- {
- /* Keep this code around in case we later want to control debug info
- based on whether a type is "used". (jason 1999-11-11) */
-
- tree ttype = target_type (fntype);
- tree parmdecl;
-
- if (IS_AGGR_TYPE (ttype))
- /* Let debugger know it should output info for this type. */
- note_debug_info_needed (ttype);
-
- for (parmdecl = DECL_ARGUMENTS (fndecl); parmdecl; parmdecl = TREE_CHAIN (parmdecl))
- {
- ttype = target_type (TREE_TYPE (parmdecl));
- if (IS_AGGR_TYPE (ttype))
- /* Let debugger know it should output info for this type. */
- note_debug_info_needed (ttype);
- }
- }
-#endif
-
- /* Clean house because we will need to reorder insns here. */
- do_pending_stack_adjust ();
-
- /* If we have a named return value, we need to force a return so that
- the return register is USEd. */
- if (DECL_NAME (DECL_RESULT (fn)))
- emit_jump (return_label);
-
- /* We hard-wired immediate_size_expand to zero in start_function.
- Expand_function_end will decrement this variable. So, we set the
- variable to one here, so that after the decrement it will remain
- zero. */
- immediate_size_expand = 1;
-
- /* Generate rtl for function exit. */
- expand_function_end (input_filename, lineno, 0);
-
- /* If this is a nested function (like a template instantiation that
- we're compiling in the midst of compiling something else), push a
- new GC context. That will keep local variables on the stack from
- being collected while we're doing the compilation of this
- function. */
- if (function_depth > 1)
- ggc_push_context ();
-
- /* There's no need to defer outputting this function any more; we
- know we want to output it. */
- DECL_DEFER_OUTPUT (fn) = 0;
-
- /* Run the optimizers and output the assembler code for this
- function. */
- rest_of_compilation (fn);
-
- /* Undo the call to ggc_push_context above. */
- if (function_depth > 1)
- ggc_pop_context ();
-
-#if 0
- /* Keep this code around in case we later want to control debug info
- based on whether a type is "used". (jason 1999-11-11) */
-
- if (ctype && TREE_ASM_WRITTEN (fn))
- note_debug_info_needed (ctype);
-#endif
-
- /* If this function is marked with the constructor attribute, add it
- to the list of functions to be called along with constructors
- from static duration objects. */
- if (DECL_STATIC_CONSTRUCTOR (fn))
- static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
-
- /* If this function is marked with the destructor attribute, add it
- to the list of functions to be called along with destructors from
- static duration objects. */
- if (DECL_STATIC_DESTRUCTOR (fn))
- static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
-
- --function_depth;
-
- /* In C++, we should never be saving RTL for the function. */
- my_friendly_assert (!DECL_SAVED_INSNS (fn), 20010903);
-
- /* Since we don't need the RTL for this function anymore, stop
- pointing to it. That's especially important for LABEL_DECLs,
- since you can reach all the instructions in the function from the
- CODE_LABEL stored in the DECL_RTL for the LABEL_DECL. Walk the
- BLOCK-tree, clearing DECL_RTL for LABEL_DECLs and non-static
- local variables. */
- walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
- clear_decl_rtl,
- NULL);
-
- /* Clear out the RTL for the arguments. */
- for (t = DECL_ARGUMENTS (fn); t; t = TREE_CHAIN (t))
- {
- SET_DECL_RTL (t, NULL_RTX);
- DECL_INCOMING_RTL (t) = NULL_RTX;
- }
-
- if (!(flag_inline_trees && DECL_INLINE (fn)))
- /* DECL_INITIAL must remain nonzero so we know this was an
- actual function definition. */
- DECL_INITIAL (fn) = error_mark_node;
-
- /* Let the error reporting routines know that we're outside a
- function. For a nested function, this value is used in
- pop_cp_function_context and then reset via pop_function_context. */
- current_function_decl = NULL_TREE;
-}
-
-/* Clear out the DECL_RTL for the non-static variables in BLOCK and
- its sub-blocks. */
-
-static tree
-clear_decl_rtl (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
-{
- if (nonstatic_local_decl_p (*tp))
- SET_DECL_RTL (*tp, NULL_RTX);
-
- return NULL_TREE;
+ COPY_DECL_RTL (DECL_RESULT (cfun->decl), current_function_return_value);
}
/* Perform initialization related to this module. */
void
-init_cp_semantics ()
+init_cp_semantics (void)
{
lang_expand_stmt = cp_expand_stmt;
}
+
+#include "gt-cp-semantics.h"
diff --git a/contrib/gcc/cp/tree.c b/contrib/gcc/cp/tree.c
index 1551df051079..d39ff7677aaa 100644
--- a/contrib/gcc/cp/tree.c
+++ b/contrib/gcc/cp/tree.c
@@ -1,69 +1,67 @@
/* Language-dependent node constructors for parse phase of GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "flags.h"
#include "real.h"
#include "rtl.h"
#include "toplev.h"
-#include "ggc.h"
#include "insn-config.h"
#include "integrate.h"
#include "tree-inline.h"
#include "target.h"
-static tree bot_manip PARAMS ((tree *, int *, void *));
-static tree bot_replace PARAMS ((tree *, int *, void *));
-static tree build_cplus_array_type_1 PARAMS ((tree, tree));
-static int list_hash_eq PARAMS ((const void *, const void *));
-static hashval_t list_hash_pieces PARAMS ((tree, tree, tree));
-static hashval_t list_hash PARAMS ((const void *));
-static cp_lvalue_kind lvalue_p_1 PARAMS ((tree, int, int));
-static tree no_linkage_helper PARAMS ((tree *, int *, void *));
-static tree build_srcloc PARAMS ((const char *, int));
-static tree mark_local_for_remap_r PARAMS ((tree *, int *, void *));
-static tree cp_unsave_r PARAMS ((tree *, int *, void *));
-static tree build_target_expr PARAMS ((tree, tree));
-static tree count_trees_r PARAMS ((tree *, int *, void *));
-static tree verify_stmt_tree_r PARAMS ((tree *, int *, void *));
-static tree find_tree_r PARAMS ((tree *, int *, void *));
-extern int cp_statement_code_p PARAMS ((enum tree_code));
-
-static tree handle_java_interface_attribute PARAMS ((tree *, tree, tree, int, bool *));
-static tree handle_com_interface_attribute PARAMS ((tree *, tree, tree, int, bool *));
-static tree handle_init_priority_attribute PARAMS ((tree *, tree, tree, int, bool *));
+static tree bot_manip (tree *, int *, void *);
+static tree bot_replace (tree *, int *, void *);
+static tree build_cplus_array_type_1 (tree, tree);
+static int list_hash_eq (const void *, const void *);
+static hashval_t list_hash_pieces (tree, tree, tree);
+static hashval_t list_hash (const void *);
+static cp_lvalue_kind lvalue_p_1 (tree, int);
+static tree no_linkage_helper (tree *, int *, void *);
+static tree mark_local_for_remap_r (tree *, int *, void *);
+static tree cp_unsave_r (tree *, int *, void *);
+static tree build_target_expr (tree, tree);
+static tree count_trees_r (tree *, int *, void *);
+static tree verify_stmt_tree_r (tree *, int *, void *);
+static tree find_tree_r (tree *, int *, void *);
+static tree build_local_temp (tree);
+
+static tree handle_java_interface_attribute (tree *, tree, tree, int, bool *);
+static tree handle_com_interface_attribute (tree *, tree, tree, int, bool *);
+static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *);
/* If REF is an lvalue, returns the kind of lvalue that REF is.
Otherwise, returns clk_none. If TREAT_CLASS_RVALUES_AS_LVALUES is
nonzero, rvalues of class type are considered lvalues. */
static cp_lvalue_kind
-lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
- tree ref;
- int treat_class_rvalues_as_lvalues;
- int allow_cast_as_lvalue;
+lvalue_p_1 (tree ref,
+ int treat_class_rvalues_as_lvalues)
{
cp_lvalue_kind op1_lvalue_kind = clk_none;
cp_lvalue_kind op2_lvalue_kind = clk_none;
@@ -87,39 +85,31 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
case REALPART_EXPR:
case IMAGPART_EXPR:
return lvalue_p_1 (TREE_OPERAND (ref, 0),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
-
- case NOP_EXPR:
- /* If expression doesn't change the type, we consider it as an
- lvalue even when cast_as_lvalue extension isn't selected.
- That's because parts of the compiler are alleged to be sloppy
- about sticking in NOP_EXPR node for no good reason. */
- if (allow_cast_as_lvalue ||
- same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ref)),
- TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (ref, 0)))))
- return lvalue_p_1 (TREE_OPERAND (ref, 0),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
- else
- return clk_none;
+ treat_class_rvalues_as_lvalues);
case COMPONENT_REF:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
- if (op1_lvalue_kind
- /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
- situations. */
- && TREE_CODE (TREE_OPERAND (ref, 1)) == FIELD_DECL
- && DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
+ treat_class_rvalues_as_lvalues);
+ /* In an expression of the form "X.Y", the packed-ness of the
+ expression does not depend on "X". */
+ op1_lvalue_kind &= ~clk_packed;
+ /* Look at the member designator. */
+ if (!op1_lvalue_kind
+ /* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
+ situations. */
+ || TREE_CODE (TREE_OPERAND (ref, 1)) != FIELD_DECL)
+ ;
+ else if (DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
{
/* Clear the ordinary bit. If this object was a class
rvalue we want to preserve that information. */
op1_lvalue_kind &= ~clk_ordinary;
- /* The lvalue is for a btifield. */
+ /* The lvalue is for a bitfield. */
op1_lvalue_kind |= clk_bitfield;
}
+ else if (DECL_PACKED (TREE_OPERAND (ref, 1)))
+ op1_lvalue_kind |= clk_packed;
+
return op1_lvalue_kind;
case STRING_CST:
@@ -141,27 +131,19 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
/* A currently unresolved scope ref. */
case SCOPE_REF:
abort ();
- case OFFSET_REF:
- if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL)
- return clk_ordinary;
- /* Fall through. */
case MAX_EXPR:
case MIN_EXPR:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 0),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
+ treat_class_rvalues_as_lvalues);
op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
+ treat_class_rvalues_as_lvalues);
break;
case COND_EXPR:
op1_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 1),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
+ treat_class_rvalues_as_lvalues);
op2_lvalue_kind = lvalue_p_1 (TREE_OPERAND (ref, 2),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
+ treat_class_rvalues_as_lvalues);
break;
case MODIFY_EXPR:
@@ -169,17 +151,15 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
case COMPOUND_EXPR:
return lvalue_p_1 (TREE_OPERAND (ref, 1),
- treat_class_rvalues_as_lvalues,
- allow_cast_as_lvalue);
+ treat_class_rvalues_as_lvalues);
case TARGET_EXPR:
return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
case CALL_EXPR:
case VA_ARG_EXPR:
- return ((treat_class_rvalues_as_lvalues
- && IS_AGGR_TYPE (TREE_TYPE (ref)))
- ? clk_class : clk_none);
+ /* Any class-valued call would be wrapped in a TARGET_EXPR. */
+ return clk_none;
case FUNCTION_DECL:
/* All functions (except non-static-member functions) are
@@ -187,6 +167,14 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
return (DECL_NONSTATIC_MEMBER_FUNCTION_P (ref)
? clk_none : clk_ordinary);
+ case NON_DEPENDENT_EXPR:
+ /* We must consider NON_DEPENDENT_EXPRs to be lvalues so that
+ things like "&E" where "E" is an expression with a
+ non-dependent type work. It is safe to be lenient because an
+ error will be issued when the template is instantiated if "E"
+ is not an lvalue. */
+ return clk_ordinary;
+
default:
break;
}
@@ -206,82 +194,45 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue)
return op1_lvalue_kind;
}
-/* If REF is an lvalue, returns the kind of lvalue that REF is.
- Otherwise, returns clk_none. Lvalues can be assigned, unless they
- have TREE_READONLY, or unless they are FUNCTION_DECLs. Lvalues can
- have their address taken, unless they have DECL_REGISTER. */
-
-cp_lvalue_kind
-real_lvalue_p (ref)
- tree ref;
-{
- return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/ 0, /*cast*/ 1);
-}
-
/* Returns the kind of lvalue that REF is, in the sense of
[basic.lval]. This function should really be named lvalue_p; it
computes the C++ definition of lvalue. */
cp_lvalue_kind
-real_non_cast_lvalue_p (tree ref)
+real_lvalue_p (tree ref)
{
return lvalue_p_1 (ref,
- /*treat_class_rvalues_as_lvalues=*/0,
- /*allow_cast_as_lvalue=*/0);
+ /*treat_class_rvalues_as_lvalues=*/0);
}
/* This differs from real_lvalue_p in that class rvalues are
considered lvalues. */
int
-lvalue_p (ref)
- tree ref;
-{
- return
- (lvalue_p_1 (ref, /*class rvalue ok*/ 1, /*cast*/ 1) != clk_none);
-}
-
-int
-non_cast_lvalue_p (ref)
- tree ref;
+lvalue_p (tree ref)
{
return
- (lvalue_p_1 (ref, /*class rvalue ok*/ 1, /*cast*/ 0) != clk_none);
+ (lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);
}
/* Return nonzero if REF is an lvalue valid for this language;
otherwise, print an error message and return zero. */
int
-lvalue_or_else (ref, string)
- tree ref;
- const char *string;
+lvalue_or_else (tree ref, const char* string)
{
- int ret = lvalue_p_1 (ref, /* class rvalue ok */ 1, /* cast ok */ 1);
- int win = (ret != clk_none);
- if (! win)
- error ("non-lvalue in %s", string);
- return win;
-}
-
-int
-non_cast_lvalue_or_else (ref, string)
- tree ref;
- const char *string;
-{
- int ret = lvalue_p_1 (ref, /* class rvalue ok */ 1, /* cast ok */ 0);
- int win = (ret != clk_none);
- if (! win)
- error ("non-lvalue in %s", string);
- return win;
+ if (!lvalue_p (ref))
+ {
+ error ("non-lvalue in %s", string);
+ return 0;
+ }
+ return 1;
}
/* Build a TARGET_EXPR, initializing the DECL with the VALUE. */
static tree
-build_target_expr (decl, value)
- tree decl;
- tree value;
+build_target_expr (tree decl, tree value)
{
tree t;
@@ -296,6 +247,19 @@ build_target_expr (decl, value)
return t;
}
+/* Return an undeclared local temporary of type TYPE for use in building a
+ TARGET_EXPR. */
+
+static tree
+build_local_temp (tree type)
+{
+ tree slot = build_decl (VAR_DECL, NULL_TREE, type);
+ DECL_ARTIFICIAL (slot) = 1;
+ DECL_CONTEXT (slot) = current_function_decl;
+ layout_decl (slot, 0);
+ return slot;
+}
+
/* INIT is a CALL_EXPR which needs info about its target.
TYPE is the type that this initialization should appear to have.
@@ -304,13 +268,12 @@ build_target_expr (decl, value)
and language-specific expression expanders. */
tree
-build_cplus_new (type, init)
- tree type;
- tree init;
+build_cplus_new (tree type, tree init)
{
tree fn;
tree slot;
tree rval;
+ int is_ctor;
/* Make sure that we're not trying to create an instance of an
abstract class. */
@@ -319,10 +282,12 @@ build_cplus_new (type, init)
if (TREE_CODE (init) != CALL_EXPR && TREE_CODE (init) != AGGR_INIT_EXPR)
return convert (type, init);
- slot = build (VAR_DECL, type);
- DECL_ARTIFICIAL (slot) = 1;
- DECL_CONTEXT (slot) = current_function_decl;
- layout_decl (slot, 0);
+ fn = TREE_OPERAND (init, 0);
+ is_ctor = (TREE_CODE (fn) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
+ && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
+
+ slot = build_local_temp (type);
/* We split the CALL_EXPR into its function and its arguments here.
Then, in expand_expr, we put them back together. The reason for
@@ -332,13 +297,18 @@ build_cplus_new (type, init)
replaces every AGGR_INIT_EXPR with a copy that uses a fresh
temporary slot. Then, expand_expr builds up a call-expression
using the new slot. */
- fn = TREE_OPERAND (init, 0);
- rval = build (AGGR_INIT_EXPR, type, fn, TREE_OPERAND (init, 1), slot);
- TREE_SIDE_EFFECTS (rval) = 1;
- AGGR_INIT_VIA_CTOR_P (rval)
- = (TREE_CODE (fn) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
- && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));
+
+ /* If we don't need to use a constructor to create an object of this
+ type, don't mess with AGGR_INIT_EXPR. */
+ if (is_ctor || TREE_ADDRESSABLE (type))
+ {
+ rval = build (AGGR_INIT_EXPR, type, fn, TREE_OPERAND (init, 1), slot);
+ TREE_SIDE_EFFECTS (rval) = 1;
+ AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
+ }
+ else
+ rval = init;
+
rval = build_target_expr (slot, rval);
return rval;
@@ -348,98 +318,58 @@ build_cplus_new (type, init)
indicated TYPE. */
tree
-build_target_expr_with_type (init, type)
- tree init;
- tree type;
+build_target_expr_with_type (tree init, tree type)
{
tree slot;
- tree rval;
if (TREE_CODE (init) == TARGET_EXPR)
return init;
else if (CLASS_TYPE_P (type) && !TYPE_HAS_TRIVIAL_INIT_REF (type)
&& TREE_CODE (init) != COND_EXPR
- && TREE_CODE (init) != CONSTRUCTOR)
+ && TREE_CODE (init) != CONSTRUCTOR
+ && TREE_CODE (init) != VA_ARG_EXPR)
/* We need to build up a copy constructor call. COND_EXPR is a special
case because we already have copies on the arms and we don't want
another one here. A CONSTRUCTOR is aggregate initialization, which
- is handled separately. */
+ is handled separately. A VA_ARG_EXPR is magic creation of an
+ aggregate; there's no additional work to be done. */
return force_rvalue (init);
- slot = build (VAR_DECL, type);
- DECL_ARTIFICIAL (slot) = 1;
- DECL_CONTEXT (slot) = current_function_decl;
- layout_decl (slot, 0);
- rval = build_target_expr (slot, init);
-
- return rval;
+ slot = build_local_temp (type);
+ return build_target_expr (slot, init);
}
-/* Like build_target_expr_with_type, but use the type of INIT. */
+/* Like the above function, but without the checking. This function should
+ only be used by code which is deliberately trying to subvert the type
+ system, such as call_builtin_trap. */
tree
-get_target_expr (init)
- tree init;
+force_target_expr (tree type, tree init)
{
- return build_target_expr_with_type (init, TREE_TYPE (init));
+ tree slot = build_local_temp (type);
+ return build_target_expr (slot, init);
}
-
-/* Construct, lay out and return the type of methods belonging to class
- BASETYPE and whose arguments are described by ARGTYPES and whose values
- are described by RETTYPE. If each type exists already, reuse it. */
+
+/* Like build_target_expr_with_type, but use the type of INIT. */
tree
-build_cplus_method_type (basetype, rettype, argtypes)
- tree basetype, rettype, argtypes;
+get_target_expr (tree init)
{
- register tree t;
- tree ptype;
- int hashcode;
-
- /* Make a node of the sort we want. */
- t = make_node (METHOD_TYPE);
-
- TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
- TREE_TYPE (t) = rettype;
- ptype = build_pointer_type (basetype);
-
- /* The actual arglist for this function includes a "hidden" argument
- which is "this". Put it into the list of argument types. */
- argtypes = tree_cons (NULL_TREE, ptype, argtypes);
- TYPE_ARG_TYPES (t) = argtypes;
- TREE_SIDE_EFFECTS (argtypes) = 1; /* Mark first argtype as "artificial". */
-
- /* If we already have such a type, use the old one and free this one.
- Note that it also frees up the above cons cell if found. */
- hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) +
- type_hash_list (argtypes);
-
- t = type_hash_canon (hashcode, t);
-
- if (!COMPLETE_TYPE_P (t))
- layout_type (t);
-
- return t;
+ return build_target_expr_with_type (init, TREE_TYPE (init));
}
+
static tree
-build_cplus_array_type_1 (elt_type, index_type)
- tree elt_type;
- tree index_type;
+build_cplus_array_type_1 (tree elt_type, tree index_type)
{
tree t;
if (elt_type == error_mark_node || index_type == error_mark_node)
return error_mark_node;
- /* Don't do the minimal thing just because processing_template_decl is
- set; we want to give string constants the right type immediately, so
- we don't have to fix them up at instantiation time. */
- if ((processing_template_decl
- && index_type && TYPE_MAX_VALUE (index_type)
- && TREE_CODE (TYPE_MAX_VALUE (index_type)) != INTEGER_CST)
- || uses_template_parms (elt_type)
- || (index_type && uses_template_parms (index_type)))
+ if (dependent_type_p (elt_type)
+ || (index_type
+ && value_dependent_expression_p (TYPE_MAX_VALUE (index_type))))
{
t = make_node (ARRAY_TYPE);
TREE_TYPE (t) = elt_type;
@@ -458,22 +388,18 @@ build_cplus_array_type_1 (elt_type, index_type)
}
tree
-build_cplus_array_type (elt_type, index_type)
- tree elt_type;
- tree index_type;
+build_cplus_array_type (tree elt_type, tree index_type)
{
tree t;
int type_quals = cp_type_quals (elt_type);
- int cv_quals = type_quals & (TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
- int other_quals = type_quals & ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
- if (cv_quals)
- elt_type = cp_build_qualified_type (elt_type, other_quals);
+ if (type_quals != TYPE_UNQUALIFIED)
+ elt_type = cp_build_qualified_type (elt_type, TYPE_UNQUALIFIED);
t = build_cplus_array_type_1 (elt_type, index_type);
- if (cv_quals)
- t = cp_build_qualified_type (t, cv_quals);
+ if (type_quals != TYPE_UNQUALIFIED)
+ t = cp_build_qualified_type (t, type_quals);
return t;
}
@@ -495,22 +421,16 @@ build_cplus_array_type (elt_type, index_type)
via a typedef or template type argument. [dcl.ref] No such
dispensation is provided for qualifying a function type. [dcl.fct]
DR 295 queries this and the proposed resolution brings it into line
- with qualifiying a reference. We implement the DR. We also behave
+ with qualifying a reference. We implement the DR. We also behave
in a similar manner for restricting non-pointer types. */
tree
-cp_build_qualified_type_real (type, type_quals, complain)
- tree type;
- int type_quals;
- tsubst_flags_t complain;
+cp_build_qualified_type_real (tree type,
+ int type_quals,
+ tsubst_flags_t complain)
{
tree result;
int bad_quals = TYPE_UNQUALIFIED;
- /* We keep bad function qualifiers separate, so that we can decide
- whether to implement DR 295 or not. DR 295 break existing code,
- unfortunately. Remove this variable to implement the defect
- report. */
- int bad_func_quals = TYPE_UNQUALIFIED;
if (type == error_mark_node)
return type;
@@ -518,54 +438,6 @@ cp_build_qualified_type_real (type, type_quals, complain)
if (type_quals == cp_type_quals (type))
return type;
- /* A reference, fucntion or method type shall not be cv qualified.
- [dcl.ref], [dct.fct] */
- if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
- && (TREE_CODE (type) == REFERENCE_TYPE
- || TREE_CODE (type) == FUNCTION_TYPE
- || TREE_CODE (type) == METHOD_TYPE))
- {
- bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- if (TREE_CODE (type) != REFERENCE_TYPE)
- bad_func_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
- }
-
- /* A restrict-qualified type must be a pointer (or reference)
- to object or incomplete type. */
- if ((type_quals & TYPE_QUAL_RESTRICT)
- && TREE_CODE (type) != TEMPLATE_TYPE_PARM
- && TREE_CODE (type) != TYPENAME_TYPE
- && !POINTER_TYPE_P (type))
- {
- bad_quals |= TYPE_QUAL_RESTRICT;
- type_quals &= ~TYPE_QUAL_RESTRICT;
- }
-
- if (bad_quals == TYPE_UNQUALIFIED)
- /*OK*/;
- else if (!(complain & (tf_error | tf_ignore_bad_quals)))
- return error_mark_node;
- else if (bad_func_quals && !(complain & tf_error))
- return error_mark_node;
- else
- {
- if (complain & tf_ignore_bad_quals)
- /* We're not going to warn about constifying things that can't
- be constified. */
- bad_quals &= ~TYPE_QUAL_CONST;
- bad_quals |= bad_func_quals;
- if (bad_quals)
- {
- tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
-
- if (!(complain & tf_ignore_bad_quals)
- || bad_func_quals)
- error ("`%V' qualifiers cannot be applied to `%T'",
- bad_type, type);
- }
- }
-
if (TREE_CODE (type) == ARRAY_TYPE)
{
/* In C++, the qualification really applies to the array element
@@ -620,6 +492,48 @@ cp_build_qualified_type_real (type, type_quals, complain)
return build_ptrmemfunc_type (t);
}
+ /* A reference, function or method type shall not be cv qualified.
+ [dcl.ref], [dct.fct] */
+ if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
+ && (TREE_CODE (type) == REFERENCE_TYPE
+ || TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE))
+ {
+ bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ }
+
+ /* A restrict-qualified type must be a pointer (or reference)
+ to object or incomplete type. */
+ if ((type_quals & TYPE_QUAL_RESTRICT)
+ && TREE_CODE (type) != TEMPLATE_TYPE_PARM
+ && TREE_CODE (type) != TYPENAME_TYPE
+ && !POINTER_TYPE_P (type))
+ {
+ bad_quals |= TYPE_QUAL_RESTRICT;
+ type_quals &= ~TYPE_QUAL_RESTRICT;
+ }
+
+ if (bad_quals == TYPE_UNQUALIFIED)
+ /*OK*/;
+ else if (!(complain & (tf_error | tf_ignore_bad_quals)))
+ return error_mark_node;
+ else
+ {
+ if (complain & tf_ignore_bad_quals)
+ /* We're not going to warn about constifying things that can't
+ be constified. */
+ bad_quals &= ~TYPE_QUAL_CONST;
+ if (bad_quals)
+ {
+ tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
+
+ if (!(complain & tf_ignore_bad_quals))
+ error ("`%V' qualifiers cannot be applied to `%T'",
+ bad_type, type);
+ }
+ }
+
/* Retrieve (or create) the appropriately qualified variant. */
result = build_qualified_type (type, type_quals);
@@ -641,43 +555,85 @@ cp_build_qualified_type_real (type, type_quals, complain)
compatible types. */
tree
-canonical_type_variant (t)
- tree t;
+canonical_type_variant (tree t)
{
return cp_build_qualified_type (TYPE_MAIN_VARIANT (t), cp_type_quals (t));
}
-/* Makes new binfos for the indirect bases under BINFO, and updates
- BINFO_OFFSET for them and their bases. */
+/* Makes new binfos for the indirect bases under BINFO. T is the most
+ derived TYPE. PREV is the previous binfo, whose TREE_CHAIN we make
+ point to this binfo. We return the last BINFO created.
-void
-unshare_base_binfos (binfo)
- tree binfo;
+ The CLASSTYPE_VBASECLASSES list of T is constructed in reverse
+ order (pre-order, depth-first, right-to-left). You must nreverse it.
+
+ The BINFO_INHERITANCE of a virtual base class points to the binfo
+ og the most derived type.
+
+ The binfo's TREE_CHAIN is set to inheritance graph order, but bases
+ for non-class types are not included (i.e. those which are
+ dependent bases in non-instantiated templates). */
+
+tree
+copy_base_binfos (tree binfo, tree t, tree prev)
{
tree binfos = BINFO_BASETYPES (binfo);
- tree new_binfo;
- int j;
+ int n, ix;
+ if (prev)
+ TREE_CHAIN (prev) = binfo;
+ prev = binfo;
+
if (binfos == NULL_TREE)
- return;
+ return prev;
- /* Now unshare the structure beneath BINFO. */
- for (j = TREE_VEC_LENGTH (binfos)-1;
- j >= 0; j--)
+ n = TREE_VEC_LENGTH (binfos);
+
+ /* Now copy the structure beneath BINFO. */
+ for (ix = 0; ix != n; ix++)
{
- tree base_binfo = TREE_VEC_ELT (binfos, j);
- new_binfo = TREE_VEC_ELT (binfos, j)
- = make_binfo (BINFO_OFFSET (base_binfo),
- base_binfo,
- BINFO_VTABLE (base_binfo),
- BINFO_VIRTUALS (base_binfo));
- TREE_VIA_PUBLIC (new_binfo) = TREE_VIA_PUBLIC (base_binfo);
- TREE_VIA_PROTECTED (new_binfo) = TREE_VIA_PROTECTED (base_binfo);
- TREE_VIA_VIRTUAL (new_binfo) = TREE_VIA_VIRTUAL (base_binfo);
- BINFO_INHERITANCE_CHAIN (new_binfo) = binfo;
- BINFO_PRIMARY_BASE_OF (new_binfo) = NULL_TREE;
- unshare_base_binfos (new_binfo);
+ tree base_binfo = TREE_VEC_ELT (binfos, ix);
+ tree new_binfo = NULL_TREE;
+
+ if (!CLASS_TYPE_P (BINFO_TYPE (base_binfo)))
+ {
+ my_friendly_assert (binfo == TYPE_BINFO (t), 20030204);
+
+ new_binfo = base_binfo;
+ TREE_CHAIN (prev) = new_binfo;
+ prev = new_binfo;
+ BINFO_INHERITANCE_CHAIN (new_binfo) = binfo;
+ BINFO_DEPENDENT_BASE_P (new_binfo) = 1;
+ }
+ else if (TREE_VIA_VIRTUAL (base_binfo))
+ {
+ new_binfo = purpose_member (BINFO_TYPE (base_binfo),
+ CLASSTYPE_VBASECLASSES (t));
+ if (new_binfo)
+ new_binfo = TREE_VALUE (new_binfo);
+ }
+
+ if (!new_binfo)
+ {
+ new_binfo = make_binfo (BINFO_OFFSET (base_binfo),
+ base_binfo, NULL_TREE,
+ BINFO_VIRTUALS (base_binfo));
+ prev = copy_base_binfos (new_binfo, t, prev);
+ if (TREE_VIA_VIRTUAL (base_binfo))
+ {
+ CLASSTYPE_VBASECLASSES (t)
+ = tree_cons (BINFO_TYPE (new_binfo), new_binfo,
+ CLASSTYPE_VBASECLASSES (t));
+ TREE_VIA_VIRTUAL (new_binfo) = 1;
+ BINFO_INHERITANCE_CHAIN (new_binfo) = TYPE_BINFO (t);
+ }
+ else
+ BINFO_INHERITANCE_CHAIN (new_binfo) = binfo;
+ }
+ TREE_VEC_ELT (binfos, ix) = new_binfo;
}
+
+ return prev;
}
@@ -703,9 +659,7 @@ struct list_proxy
for a node we are thinking about adding). */
static int
-list_hash_eq (entry, data)
- const void *entry;
- const void *data;
+list_hash_eq (const void* entry, const void* data)
{
tree t = (tree) entry;
struct list_proxy *proxy = (struct list_proxy *) data;
@@ -720,10 +674,7 @@ list_hash_eq (entry, data)
TREE_COMMON slots), by adding the hash codes of the individual entries. */
static hashval_t
-list_hash_pieces (purpose, value, chain)
- tree purpose;
- tree value;
- tree chain;
+list_hash_pieces (tree purpose, tree value, tree chain)
{
hashval_t hashcode = 0;
@@ -744,8 +695,7 @@ list_hash_pieces (purpose, value, chain)
/* Hash an already existing TREE_LIST. */
static hashval_t
-list_hash (p)
- const void *p;
+list_hash (const void* p)
{
tree t = (tree) p;
return list_hash_pieces (TREE_PURPOSE (t),
@@ -758,11 +708,10 @@ list_hash (p)
new one, and record it as the canonical object. */
tree
-hash_tree_cons (purpose, value, chain)
- tree purpose, value, chain;
+hash_tree_cons (tree purpose, tree value, tree chain)
{
int hashcode = 0;
- PTR* slot;
+ void **slot;
struct list_proxy proxy;
/* Hash the list node. */
@@ -777,15 +726,14 @@ hash_tree_cons (purpose, value, chain)
INSERT);
/* If not, create a new node. */
if (!*slot)
- *slot = (PTR) tree_cons (purpose, value, chain);
+ *slot = tree_cons (purpose, value, chain);
return *slot;
}
/* Constructor for hashed lists. */
tree
-hash_tree_chain (value, chain)
- tree value, chain;
+hash_tree_chain (tree value, tree chain)
{
return hash_tree_cons (NULL_TREE, value, chain);
}
@@ -793,8 +741,7 @@ hash_tree_chain (value, chain)
/* Similar, but used for concatenating two lists. */
tree
-hash_chainon (list1, list2)
- tree list1, list2;
+hash_chainon (tree list1, tree list2)
{
if (list2 == 0)
return list1;
@@ -822,19 +769,21 @@ hash_chainon (list1, list2)
VIRTUALS are the virtual functions sitting in VTABLE. */
tree
-make_binfo (offset, binfo, vtable, virtuals)
- tree offset, binfo;
- tree vtable, virtuals;
+make_binfo (tree offset, tree binfo, tree vtable, tree virtuals)
{
- tree new_binfo = make_tree_vec (11);
+ tree new_binfo = make_tree_vec (BINFO_LANG_ELTS);
tree type;
if (TREE_CODE (binfo) == TREE_VEC)
- type = BINFO_TYPE (binfo);
+ {
+ type = BINFO_TYPE (binfo);
+ BINFO_DEPENDENT_BASE_P (new_binfo) = BINFO_DEPENDENT_BASE_P (binfo);
+ }
else
{
type = binfo;
- binfo = CLASS_TYPE_P (type) ? TYPE_BINFO (binfo) : NULL_TREE;
+ binfo = NULL_TREE;
+ BINFO_DEPENDENT_BASE_P (new_binfo) = 1;
}
TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);
@@ -842,45 +791,26 @@ make_binfo (offset, binfo, vtable, virtuals)
BINFO_VTABLE (new_binfo) = vtable;
BINFO_VIRTUALS (new_binfo) = virtuals;
- if (binfo && BINFO_BASETYPES (binfo) != NULL_TREE)
- BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo));
- return new_binfo;
-}
-
-/* Return a TREE_LIST whose TREE_VALUE nodes along the
- BINFO_INHERITANCE_CHAIN for BINFO, but in the opposite order. In
- other words, while the BINFO_INHERITANCE_CHAIN goes from base
- classes to derived classes, the reversed path goes from derived
- classes to base classes. */
-
-tree
-reverse_path (binfo)
- tree binfo;
-{
- tree reversed_path;
-
- reversed_path = NULL_TREE;
- while (binfo)
+ if (binfo && !BINFO_DEPENDENT_BASE_P (binfo)
+ && BINFO_BASETYPES (binfo) != NULL_TREE)
{
- reversed_path = tree_cons (NULL_TREE, binfo, reversed_path);
- binfo = BINFO_INHERITANCE_CHAIN (binfo);
+ BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo));
+ /* We do not need to copy the accesses, as they are read only. */
+ BINFO_BASEACCESSES (new_binfo) = BINFO_BASEACCESSES (binfo);
}
-
- return reversed_path;
+ return new_binfo;
}
void
-debug_binfo (elem)
- tree elem;
+debug_binfo (tree elem)
{
HOST_WIDE_INT n;
tree virtuals;
- fprintf (stderr, "type \"%s\", offset = ",
- TYPE_NAME_STRING (BINFO_TYPE (elem)));
- fprintf (stderr, HOST_WIDE_INT_PRINT_DEC,
+ fprintf (stderr, "type \"%s\", offset = " HOST_WIDE_INT_PRINT_DEC
+ "\nvtable type:\n",
+ TYPE_NAME_STRING (BINFO_TYPE (elem)),
TREE_INT_CST_LOW (BINFO_OFFSET (elem)));
- fprintf (stderr, "\nvtable type:\n");
debug_tree (BINFO_TYPE (elem));
if (BINFO_VTABLE (elem))
fprintf (stderr, "vtable decl \"%s\"\n",
@@ -903,15 +833,14 @@ debug_binfo (elem)
}
int
-count_functions (t)
- tree t;
+count_functions (tree t)
{
int i;
if (TREE_CODE (t) == FUNCTION_DECL)
return 1;
else if (TREE_CODE (t) == OVERLOAD)
{
- for (i=0; t; t = OVL_CHAIN (t))
+ for (i = 0; t; t = OVL_CHAIN (t))
i++;
return i;
}
@@ -921,8 +850,7 @@ count_functions (t)
}
int
-is_overloaded_fn (x)
- tree x;
+is_overloaded_fn (tree x)
{
/* A baselink is also considered an overloaded function. */
if (TREE_CODE (x) == OFFSET_REF)
@@ -936,8 +864,7 @@ is_overloaded_fn (x)
}
int
-really_overloaded_fn (x)
- tree x;
+really_overloaded_fn (tree x)
{
/* A baselink is also considered an overloaded function. */
if (TREE_CODE (x) == OFFSET_REF)
@@ -950,23 +877,8 @@ really_overloaded_fn (x)
|| TREE_CODE (x) == TEMPLATE_ID_EXPR);
}
-/* Return the OVERLOAD or FUNCTION_DECL inside FNS. FNS can be an
- OVERLOAD, FUNCTION_DECL, TEMPLATE_ID_EXPR, or baselink. */
-
tree
-get_overloaded_fn (fns)
- tree fns;
-{
- if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
- fns = TREE_OPERAND (fns, 0);
- if (BASELINK_P (fns))
- fns = BASELINK_FUNCTIONS (fns);
- return fns;
-}
-
-tree
-get_first_fn (from)
- tree from;
+get_first_fn (tree from)
{
my_friendly_assert (is_overloaded_fn (from), 9);
/* A baselink is also considered an overloaded function. */
@@ -979,8 +891,7 @@ get_first_fn (from)
member function. */
int
-bound_pmf_p (t)
- tree t;
+bound_pmf_p (tree t)
{
return (TREE_CODE (t) == OFFSET_REF
&& TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (t, 1))));
@@ -989,9 +900,7 @@ bound_pmf_p (t)
/* Return a new OVL node, concatenating it with the old one. */
tree
-ovl_cons (decl, chain)
- tree decl;
- tree chain;
+ovl_cons (tree decl, tree chain)
{
tree result = make_node (OVERLOAD);
TREE_TYPE (result) = unknown_type_node;
@@ -1005,9 +914,7 @@ ovl_cons (decl, chain)
just return it; otherwise, ovl_cons the _DECLs */
tree
-build_overload (decl, chain)
- tree decl;
- tree chain;
+build_overload (tree decl, tree chain)
{
if (! chain && TREE_CODE (decl) != TEMPLATE_DECL)
return decl;
@@ -1016,43 +923,11 @@ build_overload (decl, chain)
return ovl_cons (decl, chain);
}
-int
-is_aggr_type_2 (t1, t2)
- tree t1, t2;
-{
- if (TREE_CODE (t1) != TREE_CODE (t2))
- return 0;
- return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2);
-}
-
-/* Returns nonzero if CODE is the code for a statement. */
-
-int
-cp_statement_code_p (code)
- enum tree_code code;
-{
- switch (code)
- {
- case CTOR_INITIALIZER:
- case RETURN_INIT:
- case TRY_BLOCK:
- case HANDLER:
- case EH_SPEC_BLOCK:
- case USING_STMT:
- case TAG_DEFN:
- return 1;
-
- default:
- return 0;
- }
-}
#define PRINT_RING_SIZE 4
const char *
-cxx_printable_name (decl, v)
- tree decl;
- int v;
+cxx_printable_name (tree decl, int v)
{
static tree decl_ring[PRINT_RING_SIZE];
static char *print_ring[PRINT_RING_SIZE];
@@ -1096,16 +971,15 @@ cxx_printable_name (decl, v)
listed in RAISES. */
tree
-build_exception_variant (type, raises)
- tree type;
- tree raises;
+build_exception_variant (tree type, tree raises)
{
tree v = TYPE_MAIN_VARIANT (type);
int type_quals = TYPE_QUALS (type);
for (; v; v = TYPE_NEXT_VARIANT (v))
if (TYPE_QUALS (v) == type_quals
- && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), 1))
+ && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (v), 1)
+ && (*targetm.comp_type_attributes) (type, v))
return v;
/* Need to build a new variant. */
@@ -1119,9 +993,7 @@ build_exception_variant (type, raises)
arguments. */
tree
-bind_template_template_parm (t, newargs)
- tree t;
- tree newargs;
+bind_template_template_parm (tree t, tree newargs)
{
tree decl = TYPE_NAME (t);
tree t2;
@@ -1148,10 +1020,9 @@ bind_template_template_parm (t, newargs)
/* Called from count_trees via walk_tree. */
static tree
-count_trees_r (tp, walk_subtrees, data)
- tree *tp ATTRIBUTE_UNUSED;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data;
+count_trees_r (tree* tp ATTRIBUTE_UNUSED ,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data)
{
++ *((int*) data);
return NULL_TREE;
@@ -1161,8 +1032,7 @@ count_trees_r (tp, walk_subtrees, data)
representation. */
int
-count_trees (t)
- tree t;
+count_trees (tree t)
{
int n_trees = 0;
walk_tree_without_duplicates (&t, count_trees_r, &n_trees);
@@ -1172,16 +1042,15 @@ count_trees (t)
/* Called from verify_stmt_tree via walk_tree. */
static tree
-verify_stmt_tree_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data;
+verify_stmt_tree_r (tree* tp,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data)
{
tree t = *tp;
htab_t *statements = (htab_t *) data;
void **slot;
- if (!statement_code_p (TREE_CODE (t)))
+ if (!STATEMENT_CODE_P (TREE_CODE (t)))
return NULL_TREE;
/* If this statement is already present in the hash table, then
@@ -1200,8 +1069,7 @@ verify_stmt_tree_r (tp, walk_subtrees, data)
circularities. */
void
-verify_stmt_tree (t)
- tree t;
+verify_stmt_tree (tree t)
{
htab_t statements;
statements = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
@@ -1212,10 +1080,9 @@ verify_stmt_tree (t)
/* Called from find_tree via walk_tree. */
static tree
-find_tree_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data;
+find_tree_r (tree* tp,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data)
{
if (*tp == (tree) data)
return (tree) data;
@@ -1226,9 +1093,7 @@ find_tree_r (tp, walk_subtrees, data)
/* Returns X if X appears in the tree structure rooted at T. */
tree
-find_tree (t, x)
- tree t;
- tree x;
+find_tree (tree t, tree x)
{
return walk_tree_without_duplicates (&t, find_tree_r, x);
}
@@ -1236,10 +1101,9 @@ find_tree (t, x)
/* Passed to walk_tree. Checks for the use of types with no linkage. */
static tree
-no_linkage_helper (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+no_linkage_helper (tree* tp,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data ATTRIBUTE_UNUSED )
{
tree t = *tp;
@@ -1255,8 +1119,7 @@ no_linkage_helper (tp, walk_subtrees, data)
it. */
tree
-no_linkage_check (t)
- tree t;
+no_linkage_check (tree t)
{
/* There's no point in checking linkage on template functions; we
can't know their complete types. */
@@ -1274,7 +1137,7 @@ extern int depth_reached;
#endif
void
-cxx_print_statistics ()
+cxx_print_statistics (void)
{
print_search_statistics ();
print_class_statistics ();
@@ -1289,8 +1152,7 @@ cxx_print_statistics ()
array. */
tree
-array_type_nelts_top (type)
- tree type;
+array_type_nelts_top (tree type)
{
return fold (build (PLUS_EXPR, sizetype,
array_type_nelts (type),
@@ -1302,8 +1164,7 @@ array_type_nelts_top (type)
ARRAY_TYPEs that are clumped together. */
tree
-array_type_nelts_total (type)
- tree type;
+array_type_nelts_total (tree type)
{
tree sz = array_type_nelts_top (type);
type = TREE_TYPE (type);
@@ -1319,10 +1180,7 @@ array_type_nelts_total (type)
/* Called from break_out_target_exprs via mapcar. */
static tree
-bot_manip (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees;
- void *data;
+bot_manip (tree* tp, int* walk_subtrees, void* data)
{
splay_tree target_remap = ((splay_tree) data);
tree t = *tp;
@@ -1376,10 +1234,9 @@ bot_manip (tp, walk_subtrees, data)
variables. */
static tree
-bot_replace (t, walk_subtrees, data)
- tree *t;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data;
+bot_replace (tree* t,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data)
{
splay_tree target_remap = ((splay_tree) data);
@@ -1400,8 +1257,7 @@ bot_replace (t, walk_subtrees, data)
we must replace the temporaries with appropriate local versions. */
tree
-break_out_target_exprs (t)
- tree t;
+break_out_target_exprs (tree t)
{
static int target_remap_count;
static splay_tree target_remap;
@@ -1422,25 +1278,22 @@ break_out_target_exprs (t)
return t;
}
-/* Obstack used for allocating nodes in template function and variable
- definitions. */
-
-/* Similar to `build_nt', except that we set TREE_COMPLEXITY to be the
- current line number. */
+/* Similar to `build_nt', but for template definitions of dependent
+ expressions */
tree
-build_min_nt VPARAMS ((enum tree_code code, ...))
+build_min_nt (enum tree_code code, ...)
{
- register tree t;
- register int length;
- register int i;
+ tree t;
+ int length;
+ int i;
+ va_list p;
- VA_OPEN (p, code);
- VA_FIXEDARG (p, enum tree_code, code);
+ va_start (p, code);
t = make_node (code);
length = TREE_CODE_LENGTH (code);
- TREE_COMPLEXITY (t) = lineno;
+ TREE_COMPLEXITY (t) = input_line;
for (i = 0; i < length; i++)
{
@@ -1448,28 +1301,58 @@ build_min_nt VPARAMS ((enum tree_code code, ...))
TREE_OPERAND (t, i) = x;
}
- VA_CLOSE (p);
+ va_end (p);
return t;
}
-/* Similar to `build', except we set TREE_COMPLEXITY to the current
- line-number. */
+/* Similar to `build', but for template definitions. */
tree
-build_min VPARAMS ((enum tree_code code, tree tt, ...))
+build_min (enum tree_code code, tree tt, ...)
{
- register tree t;
- register int length;
- register int i;
+ tree t;
+ int length;
+ int i;
+ va_list p;
- VA_OPEN (p, tt);
- VA_FIXEDARG (p, enum tree_code, code);
- VA_FIXEDARG (p, tree, tt);
+ va_start (p, tt);
t = make_node (code);
length = TREE_CODE_LENGTH (code);
TREE_TYPE (t) = tt;
- TREE_COMPLEXITY (t) = lineno;
+ TREE_COMPLEXITY (t) = input_line;
+
+ for (i = 0; i < length; i++)
+ {
+ tree x = va_arg (p, tree);
+ TREE_OPERAND (t, i) = x;
+ if (x && TREE_SIDE_EFFECTS (x))
+ TREE_SIDE_EFFECTS (t) = 1;
+ }
+
+ va_end (p);
+ return t;
+}
+
+/* Similar to `build', but for template definitions of non-dependent
+ expressions. NON_DEP is the non-dependent expression that has been
+ built. */
+
+tree
+build_min_non_dep (enum tree_code code, tree non_dep, ...)
+{
+ tree t;
+ int length;
+ int i;
+ va_list p;
+
+ va_start (p, non_dep);
+
+ t = make_node (code);
+ length = TREE_CODE_LENGTH (code);
+ TREE_TYPE (t) = TREE_TYPE (non_dep);
+ TREE_COMPLEXITY (t) = input_line;
+ TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
for (i = 0; i < length; i++)
{
@@ -1477,7 +1360,12 @@ build_min VPARAMS ((enum tree_code code, tree tt, ...))
TREE_OPERAND (t, i) = x;
}
- VA_CLOSE (p);
+ if (code == COMPOUND_EXPR && TREE_CODE (non_dep) != COMPOUND_EXPR)
+ /* This should not be considered a COMPOUND_EXPR, because it
+ resolves to an overload. */
+ COMPOUND_EXPR_OVERLOADED (t) = 1;
+
+ va_end (p);
return t;
}
@@ -1489,8 +1377,7 @@ build_min VPARAMS ((enum tree_code code, tree tt, ...))
static GTY(()) tree shared_int_cache[256];
tree
-build_shared_int_cst (i)
- int i;
+build_shared_int_cst (int i)
{
if (i >= 256)
return build_int_2 (i, 0);
@@ -1502,8 +1389,7 @@ build_shared_int_cst (i)
}
tree
-get_type_decl (t)
- tree t;
+get_type_decl (tree t)
{
if (TREE_CODE (t) == TYPE_DECL)
return t;
@@ -1522,8 +1408,7 @@ get_type_decl (t)
Return 0 if ELEM is not in VEC. VEC may be NULL_TREE. */
tree
-vec_binfo_member (elem, vec)
- tree elem, vec;
+vec_binfo_member (tree elem, tree vec)
{
int i;
@@ -1539,8 +1424,7 @@ vec_binfo_member (elem, vec)
indirectly. */
tree
-decl_namespace_context (decl)
- tree decl;
+decl_namespace_context (tree decl)
{
while (1)
{
@@ -1554,39 +1438,35 @@ decl_namespace_context (decl)
}
/* Return truthvalue of whether T1 is the same tree structure as T2.
- Return 1 if they are the same.
- Return 0 if they are understandably different.
- Return -1 if either contains tree structure not understood by
- this function. */
+ Return 1 if they are the same. Return 0 if they are different. */
-int
-cp_tree_equal (t1, t2)
- tree t1, t2;
+bool
+cp_tree_equal (tree t1, tree t2)
{
- register enum tree_code code1, code2;
- int cmp;
+ enum tree_code code1, code2;
if (t1 == t2)
- return 1;
- if (t1 == 0 || t2 == 0)
- return 0;
-
- code1 = TREE_CODE (t1);
- code2 = TREE_CODE (t2);
-
- if (code1 == NOP_EXPR || code1 == CONVERT_EXPR || code1 == NON_LVALUE_EXPR)
- {
- if (code2 == NOP_EXPR || code2 == CONVERT_EXPR || code2 == NON_LVALUE_EXPR)
- return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- else
- return cp_tree_equal (TREE_OPERAND (t1, 0), t2);
- }
- else if (code2 == NOP_EXPR || code2 == CONVERT_EXPR
- || code2 == NON_LVALUE_EXPR)
- return cp_tree_equal (t1, TREE_OPERAND (t2, 0));
-
+ return true;
+ if (!t1 || !t2)
+ return false;
+
+ for (code1 = TREE_CODE (t1);
+ code1 == NOP_EXPR || code1 == CONVERT_EXPR
+ || code1 == NON_LVALUE_EXPR;
+ code1 = TREE_CODE (t1))
+ t1 = TREE_OPERAND (t1, 0);
+ for (code2 = TREE_CODE (t2);
+ code2 == NOP_EXPR || code2 == CONVERT_EXPR
+ || code1 == NON_LVALUE_EXPR;
+ code2 = TREE_CODE (t2))
+ t2 = TREE_OPERAND (t2, 0);
+
+ /* They might have become equal now. */
+ if (t1 == t2)
+ return true;
+
if (code1 != code2)
- return 0;
+ return false;
switch (code1)
{
@@ -1600,7 +1480,7 @@ cp_tree_equal (t1, t2)
case STRING_CST:
return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
&& !memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
- TREE_STRING_LENGTH (t1));
+ TREE_STRING_LENGTH (t1));
case CONSTRUCTOR:
/* We need to do this when determining whether or not two
@@ -1609,61 +1489,62 @@ cp_tree_equal (t1, t2)
if (!(same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
/* The first operand is RTL. */
&& TREE_OPERAND (t1, 0) == TREE_OPERAND (t2, 0)))
- return 0;
+ return false;
return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
case TREE_LIST:
- cmp = cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2));
- if (cmp <= 0)
- return cmp;
- cmp = cp_tree_equal (TREE_VALUE (t1), TREE_VALUE (t2));
- if (cmp <= 0)
- return cmp;
+ if (!cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)))
+ return false;
+ if (!cp_tree_equal (TREE_VALUE (t1), TREE_VALUE (t2)))
+ return false;
return cp_tree_equal (TREE_CHAIN (t1), TREE_CHAIN (t2));
case SAVE_EXPR:
return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
case CALL_EXPR:
- cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- if (cmp <= 0)
- return cmp;
- return simple_cst_list_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
-
- case TARGET_EXPR:
- /* Special case: if either target is an unallocated VAR_DECL,
- it means that it's going to be unified with whatever the
- TARGET_EXPR is really supposed to initialize, so treat it
- as being equivalent to anything. */
- if ((TREE_CODE (TREE_OPERAND (t1, 0)) == VAR_DECL
- && DECL_NAME (TREE_OPERAND (t1, 0)) == NULL_TREE
- && !DECL_RTL_SET_P (TREE_OPERAND (t1, 0)))
- || (TREE_CODE (TREE_OPERAND (t2, 0)) == VAR_DECL
- && DECL_NAME (TREE_OPERAND (t2, 0)) == NULL_TREE
- && !DECL_RTL_SET_P (TREE_OPERAND (t2, 0))))
- cmp = 1;
- else
- cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- if (cmp <= 0)
- return cmp;
+ if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+ return false;
return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
+ case TARGET_EXPR:
+ {
+ tree o1 = TREE_OPERAND (t1, 0);
+ tree o2 = TREE_OPERAND (t2, 0);
+
+ /* Special case: if either target is an unallocated VAR_DECL,
+ it means that it's going to be unified with whatever the
+ TARGET_EXPR is really supposed to initialize, so treat it
+ as being equivalent to anything. */
+ if (TREE_CODE (o1) == VAR_DECL && DECL_NAME (o1) == NULL_TREE
+ && !DECL_RTL_SET_P (o1))
+ /*Nop*/;
+ else if (TREE_CODE (o2) == VAR_DECL && DECL_NAME (o2) == NULL_TREE
+ && !DECL_RTL_SET_P (o2))
+ /*Nop*/;
+ else if (!cp_tree_equal (o1, o2))
+ return false;
+
+ return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
+ }
+
case WITH_CLEANUP_EXPR:
- cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- if (cmp <= 0)
- return cmp;
+ if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+ return false;
return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t1, 1));
case COMPONENT_REF:
- if (TREE_OPERAND (t1, 1) == TREE_OPERAND (t2, 1))
- return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- return 0;
+ if (TREE_OPERAND (t1, 1) != TREE_OPERAND (t2, 1))
+ return false;
+ return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
case VAR_DECL:
case PARM_DECL:
case CONST_DECL:
case FUNCTION_DECL:
- return 0;
+ case TEMPLATE_DECL:
+ case IDENTIFIER_NODE:
+ return false;
case TEMPLATE_PARM_INDEX:
return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
@@ -1671,19 +1552,51 @@ cp_tree_equal (t1, t2)
&& same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)),
TREE_TYPE (TEMPLATE_PARM_DECL (t2))));
+ case TEMPLATE_ID_EXPR:
+ {
+ unsigned ix;
+ tree vec1, vec2;
+
+ if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
+ return false;
+ vec1 = TREE_OPERAND (t1, 1);
+ vec2 = TREE_OPERAND (t2, 1);
+
+ if (!vec1 || !vec2)
+ return !vec1 && !vec2;
+
+ if (TREE_VEC_LENGTH (vec1) != TREE_VEC_LENGTH (vec2))
+ return false;
+
+ for (ix = TREE_VEC_LENGTH (vec1); ix--;)
+ if (!cp_tree_equal (TREE_VEC_ELT (vec1, ix),
+ TREE_VEC_ELT (vec2, ix)))
+ return false;
+
+ return true;
+ }
+
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
- if (TREE_CODE (TREE_OPERAND (t1, 0)) != TREE_CODE (TREE_OPERAND (t2, 0)))
- return 0;
- if (TYPE_P (TREE_OPERAND (t1, 0)))
- return same_type_p (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
- break;
-
+ {
+ tree o1 = TREE_OPERAND (t1, 0);
+ tree o2 = TREE_OPERAND (t2, 0);
+
+ if (TREE_CODE (o1) != TREE_CODE (o2))
+ return false;
+ if (TYPE_P (o1))
+ return same_type_p (o1, o2);
+ else
+ return cp_tree_equal (o1, o2);
+ }
+
case PTRMEM_CST:
/* Two pointer-to-members are the same if they point to the same
field or function in the same class. */
- return (PTRMEM_CST_MEMBER (t1) == PTRMEM_CST_MEMBER (t2)
- && same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2)));
+ if (PTRMEM_CST_MEMBER (t1) != PTRMEM_CST_MEMBER (t2))
+ return false;
+
+ return same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2));
default:
break;
@@ -1700,64 +1613,38 @@ cp_tree_equal (t1, t2)
{
int i;
- cmp = 1;
for (i = 0; i < TREE_CODE_LENGTH (code1); ++i)
- {
- cmp = cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i));
- if (cmp <= 0)
- return cmp;
- }
- return cmp;
+ if (!cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i)))
+ return false;
+
+ return true;
}
- case 't':
- return same_type_p (t1, t2) ? 1 : 0;
+ case 't':
+ return same_type_p (t1, t2);
}
- return -1;
+ my_friendly_assert (0, 20030617);
+ return false;
}
/* Build a wrapper around a 'struct z_candidate' so we can use it as a
tree. */
tree
-build_zc_wrapper (ptr)
- struct z_candidate *ptr;
+build_zc_wrapper (struct z_candidate* ptr)
{
tree t = make_node (WRAPPER);
WRAPPER_ZC (t) = ptr;
return t;
}
-static tree
-build_srcloc (file, line)
- const char *file;
- int line;
-{
- tree t;
-
- t = make_node (SRCLOC);
- SRCLOC_FILE (t) = file;
- SRCLOC_LINE (t) = line;
-
- return t;
-}
-
-tree
-build_srcloc_here ()
-{
- return build_srcloc (input_filename, lineno);
-}
-
/* The type of ARG when used as an lvalue. */
tree
-lvalue_type (arg)
- tree arg;
+lvalue_type (tree arg)
{
tree type = TREE_TYPE (arg);
- if (TREE_CODE (arg) == OVERLOAD)
- type = unknown_type_node;
return type;
}
@@ -1765,12 +1652,14 @@ lvalue_type (arg)
reference types. */
tree
-error_type (arg)
- tree arg;
+error_type (tree arg)
{
tree type = TREE_TYPE (arg);
+
if (TREE_CODE (type) == ARRAY_TYPE)
;
+ else if (TREE_CODE (type) == ERROR_MARK)
+ ;
else if (real_lvalue_p (arg))
type = build_reference_type (lvalue_type (arg));
else if (IS_AGGR_TYPE (type))
@@ -1782,8 +1671,7 @@ error_type (arg)
/* Does FUNCTION use a variable-length argument list? */
int
-varargs_function_p (function)
- tree function;
+varargs_function_p (tree function)
{
tree parm = TYPE_ARG_TYPES (TREE_TYPE (function));
for (; parm; parm = TREE_CHAIN (parm))
@@ -1795,8 +1683,7 @@ varargs_function_p (function)
/* Returns 1 if decl is a member of a class. */
int
-member_p (decl)
- tree decl;
+member_p (tree decl)
{
const tree ctx = DECL_CONTEXT (decl);
return (ctx && TYPE_P (ctx));
@@ -1806,8 +1693,7 @@ member_p (decl)
object that the access is against. */
tree
-build_dummy_object (type)
- tree type;
+build_dummy_object (tree type)
{
tree decl = build1 (NOP_EXPR, build_pointer_type (type), void_zero_node);
return build_indirect_ref (decl, NULL);
@@ -1818,9 +1704,7 @@ build_dummy_object (type)
binfo path from current_class_type to TYPE, or 0. */
tree
-maybe_dummy_object (type, binfop)
- tree type;
- tree *binfop;
+maybe_dummy_object (tree type, tree* binfop)
{
tree decl, context;
tree binfo;
@@ -1855,8 +1739,7 @@ maybe_dummy_object (type, binfop)
/* Returns 1 if OB is a placeholder object, or a pointer to one. */
int
-is_dummy_object (ob)
- tree ob;
+is_dummy_object (tree ob)
{
if (TREE_CODE (ob) == INDIRECT_REF)
ob = TREE_OPERAND (ob, 0);
@@ -1867,8 +1750,7 @@ is_dummy_object (ob)
/* Returns 1 iff type T is a POD type, as defined in [basic.types]. */
int
-pod_type_p (t)
- tree t;
+pod_type_p (tree t)
{
t = strip_array_types (t);
@@ -1880,10 +1762,8 @@ pod_type_p (t)
return 1;
if (TYPE_PTR_P (t))
return 1; /* pointer to non-member */
- if (TYPE_PTRMEM_P (t))
- return 1; /* pointer to member object */
- if (TYPE_PTRMEMFUNC_P (t))
- return 1; /* pointer to member function */
+ if (TYPE_PTR_TO_MEMBER_P (t))
+ return 1; /* pointer to member */
if (! CLASS_TYPE_P (t))
return 0; /* other non-class type (reference or function) */
@@ -1896,8 +1776,7 @@ pod_type_p (t)
zeros in it. */
int
-zero_init_p (t)
- tree t;
+zero_init_p (tree t)
{
t = strip_array_types (t);
@@ -1929,12 +1808,11 @@ const struct attribute_spec cxx_attribute_table[] =
/* Handle a "java_interface" attribute; arguments as in
struct attribute_spec.handler. */
static tree
-handle_java_interface_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags;
- bool *no_add_attrs;
+handle_java_interface_attribute (tree* node,
+ tree name,
+ tree args ATTRIBUTE_UNUSED ,
+ int flags,
+ bool* no_add_attrs)
{
if (DECL_P (*node)
|| !CLASS_TYPE_P (*node)
@@ -1955,12 +1833,11 @@ handle_java_interface_attribute (node, name, args, flags, no_add_attrs)
/* Handle a "com_interface" attribute; arguments as in
struct attribute_spec.handler. */
static tree
-handle_com_interface_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args ATTRIBUTE_UNUSED;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_com_interface_attribute (tree* node,
+ tree name,
+ tree args ATTRIBUTE_UNUSED ,
+ int flags ATTRIBUTE_UNUSED ,
+ bool* no_add_attrs)
{
static int warned;
@@ -1985,12 +1862,11 @@ handle_com_interface_attribute (node, name, args, flags, no_add_attrs)
/* Handle an "init_priority" attribute; arguments as in
struct attribute_spec.handler. */
static tree
-handle_init_priority_attribute (node, name, args, flags, no_add_attrs)
- tree *node;
- tree name;
- tree args;
- int flags ATTRIBUTE_UNUSED;
- bool *no_add_attrs;
+handle_init_priority_attribute (tree* node,
+ tree name,
+ tree args,
+ int flags ATTRIBUTE_UNUSED ,
+ bool* no_add_attrs)
{
tree initp_expr = TREE_VALUE (args);
tree decl = *node;
@@ -2061,9 +1937,7 @@ handle_init_priority_attribute (node, name, args, flags, no_add_attrs)
thing pointed to by the constant. */
tree
-make_ptrmem_cst (type, member)
- tree type;
- tree member;
+make_ptrmem_cst (tree type, tree member)
{
tree ptrmem_cst = make_node (PTRMEM_CST);
/* If would seem a great convenience if make_node would set
@@ -2074,16 +1948,32 @@ make_ptrmem_cst (type, member)
return ptrmem_cst;
}
+/* Build a variant of TYPE that has the indicated ATTRIBUTES. May
+ return an existing type of an appropriate type already exists. */
+
+tree
+cp_build_type_attribute_variant (tree type, tree attributes)
+{
+ tree new_type;
+
+ new_type = build_type_attribute_variant (type, attributes);
+ if (TREE_CODE (new_type) == FUNCTION_TYPE
+ && (TYPE_RAISES_EXCEPTIONS (new_type)
+ != TYPE_RAISES_EXCEPTIONS (type)))
+ new_type = build_exception_variant (new_type,
+ TYPE_RAISES_EXCEPTIONS (type));
+ return new_type;
+}
+
/* Apply FUNC to all language-specific sub-trees of TP in a pre-order
traversal. Called from walk_tree(). */
tree
-cp_walk_subtrees (tp, walk_subtrees_p, func, data, htab)
- tree *tp;
- int *walk_subtrees_p;
- walk_tree_fn func;
- void *data;
- void *htab;
+cp_walk_subtrees (tree* tp,
+ int* walk_subtrees_p,
+ walk_tree_fn func,
+ void* data,
+ void* htab)
{
enum tree_code code = TREE_CODE (*tp);
tree result;
@@ -2109,7 +1999,8 @@ cp_walk_subtrees (tp, walk_subtrees_p, func, data, htab)
case TEMPLATE_TYPE_PARM:
case TYPENAME_TYPE:
case TYPEOF_TYPE:
- /* None of thse have subtrees other than those already walked
+ case BASELINK:
+ /* None of these have subtrees other than those already walked
above. */
*walk_subtrees_p = 0;
break;
@@ -2120,9 +2011,7 @@ cp_walk_subtrees (tp, walk_subtrees_p, func, data, htab)
break;
case TREE_LIST:
- /* A BASELINK_P's TREE_PURPOSE is a BINFO, and hence circular. */
- if (!BASELINK_P (*tp))
- WALK_SUBTREE (TREE_PURPOSE (*tp));
+ WALK_SUBTREE (TREE_PURPOSE (*tp));
break;
case OVERLOAD:
@@ -2150,25 +2039,31 @@ cp_walk_subtrees (tp, walk_subtrees_p, func, data, htab)
function as a tree. */
int
-cp_cannot_inline_tree_fn (fnp)
- tree *fnp;
+cp_cannot_inline_tree_fn (tree* fnp)
{
tree fn = *fnp;
- if (flag_really_no_inline
- && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
- return 1;
-
/* We can inline a template instantiation only if it's fully
instantiated. */
if (DECL_TEMPLATE_INFO (fn)
&& TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
{
+ /* Don't instantiate functions that are not going to be
+ inlined. */
+ if (!DECL_INLINE (DECL_TEMPLATE_RESULT
+ (template_for_substitution (fn))))
+ return 1;
+
fn = *fnp = instantiate_decl (fn, /*defer_ok=*/0);
+
if (TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
return 1;
}
+ if (flag_really_no_inline
+ && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
+ return 1;
+
/* Don't auto-inline anything that might not be bound within
this unit of translation. */
if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
@@ -2197,9 +2092,7 @@ cp_cannot_inline_tree_fn (fnp)
return the latest function added to the array, PREV_FN. */
tree
-cp_add_pending_fn_decls (fns_p, prev_fn)
- void *fns_p;
- tree prev_fn;
+cp_add_pending_fn_decls (void* fns_p, tree prev_fn)
{
varray_type *fnsp = (varray_type *)fns_p;
struct saved_scope *s;
@@ -2219,8 +2112,7 @@ cp_add_pending_fn_decls (fns_p, prev_fn)
function. */
int
-cp_is_overload_p (t)
- tree t;
+cp_is_overload_p (tree t)
{
return TREE_CODE (t) == OVERLOAD;
}
@@ -2229,8 +2121,7 @@ cp_is_overload_p (t)
function FN. */
int
-cp_auto_var_in_fn_p (var, fn)
- tree var, fn;
+cp_auto_var_in_fn_p (tree var, tree fn)
{
return (DECL_P (var) && DECL_CONTEXT (var) == fn
&& nonstatic_local_decl_p (var));
@@ -2241,34 +2132,33 @@ cp_auto_var_in_fn_p (var, fn)
to be used. */
tree
-cp_copy_res_decl_for_inlining (result, fn, caller, decl_map_,
- need_decl, target_exprs)
- tree result, fn, caller;
- void *decl_map_;
- int *need_decl;
- void *target_exprs;
+cp_copy_res_decl_for_inlining (tree result,
+ tree fn,
+ tree caller,
+ void* decl_map_,
+ int* need_decl,
+ tree return_slot_addr)
{
splay_tree decl_map = (splay_tree)decl_map_;
- varray_type *texps = (varray_type *)target_exprs;
tree var;
- int aggregate_return_p;
-
- /* Figure out whether or not FN returns an aggregate. */
- aggregate_return_p = IS_AGGR_TYPE (TREE_TYPE (result));
- *need_decl = ! aggregate_return_p;
- /* If FN returns an aggregate then the caller will always create the
- temporary (using a TARGET_EXPR) and the call will be the
- initializing expression for the TARGET_EXPR. If we were just to
+ /* If FN returns an aggregate then the caller will always pass the
+ address of the return slot explicitly. If we were just to
create a new VAR_DECL here, then the result of this function
would be copied (bitwise) into the variable initialized by the
TARGET_EXPR. That's incorrect, so we must transform any
references to the RESULT into references to the target. */
- if (aggregate_return_p)
+
+ /* We should have an explicit return slot iff the return type is
+ TREE_ADDRESSABLE. See simplify_aggr_init_expr. */
+ if (TREE_ADDRESSABLE (TREE_TYPE (result))
+ != (return_slot_addr != NULL_TREE))
+ abort ();
+
+ *need_decl = !return_slot_addr;
+ if (return_slot_addr)
{
- if (VARRAY_ACTIVE_SIZE (*texps) == 0)
- abort ();
- var = TREE_OPERAND (VARRAY_TOP_TREE (*texps), 0);
+ var = build_indirect_ref (return_slot_addr, "");
if (! same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (var),
TREE_TYPE (result)))
abort ();
@@ -2285,13 +2175,19 @@ cp_copy_res_decl_for_inlining (result, fn, caller, decl_map_,
/* We have a named return value; copy the name and source
position so we can get reasonable debugging information, and
register the return variable as its equivalent. */
- DECL_NAME (var) = DECL_NAME (nrv);
- DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv);
- DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv);
- /* Don't lose initialization info. */
- DECL_INITIAL (var) = DECL_INITIAL (nrv);
- /* Don't forget that it needs to go in the stack. */
- TREE_ADDRESSABLE (var) = TREE_ADDRESSABLE (nrv);
+ if (TREE_CODE (var) == VAR_DECL
+ /* But not if we're initializing a variable from the
+ enclosing function which already has its own name. */
+ && DECL_NAME (var) == NULL_TREE)
+ {
+ DECL_NAME (var) = DECL_NAME (nrv);
+ DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv);
+ DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv);
+ /* Don't lose initialization info. */
+ DECL_INITIAL (var) = DECL_INITIAL (nrv);
+ /* Don't forget that it needs to go in the stack. */
+ TREE_ADDRESSABLE (var) = TREE_ADDRESSABLE (nrv);
+ }
splay_tree_insert (decl_map,
(splay_tree_key) nrv,
@@ -2302,36 +2198,11 @@ cp_copy_res_decl_for_inlining (result, fn, caller, decl_map_,
return var;
}
-/* Record that we're about to start inlining FN, and return nonzero if
- that's OK. Used for lang_hooks.tree_inlining.start_inlining. */
-
-int
-cp_start_inlining (fn)
- tree fn;
-{
- if (DECL_TEMPLATE_INSTANTIATION (fn))
- return push_tinst_level (fn);
- else
- return 1;
-}
-
-/* Record that we're done inlining FN. Used for
- lang_hooks.tree_inlining.end_inlining. */
-
-void
-cp_end_inlining (fn)
- tree fn ATTRIBUTE_UNUSED;
-{
- if (DECL_TEMPLATE_INSTANTIATION (fn))
- pop_tinst_level ();
-}
-
/* Initialize tree.c. */
void
-init_tree ()
+init_tree (void)
{
- lang_statement_code_p = cp_statement_code_p;
list_hash_table = htab_create_ggc (31, list_hash, list_hash_eq, NULL);
}
@@ -2340,10 +2211,9 @@ init_tree ()
pointed to by DATA (which is really a `splay_tree *'). */
static tree
-mark_local_for_remap_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data;
+mark_local_for_remap_r (tree* tp,
+ int* walk_subtrees ATTRIBUTE_UNUSED ,
+ void* data)
{
tree t = *tp;
splay_tree st = (splay_tree) data;
@@ -2386,10 +2256,9 @@ mark_local_for_remap_r (tp, walk_subtrees, data)
remaps all local declarations to appropriate replacements. */
static tree
-cp_unsave_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees;
- void *data;
+cp_unsave_r (tree* tp,
+ int* walk_subtrees,
+ void* data)
{
splay_tree st = (splay_tree) data;
splay_tree_node n;
@@ -2421,8 +2290,7 @@ cp_unsave_r (tp, walk_subtrees, data)
/* Called whenever an expression needs to be unsaved. */
tree
-cxx_unsave_expr_now (tp)
- tree tp;
+cxx_unsave_expr_now (tree tp)
{
splay_tree st;
@@ -2447,8 +2315,7 @@ cxx_unsave_expr_now (tp)
predicate to test whether or not DECL is a special function. */
special_function_kind
-special_function_p (decl)
- tree decl;
+special_function_p (tree decl)
{
/* Rather than doing all this stuff with magic names, we should
probably have a field of type `special_function_kind' in
@@ -2492,8 +2359,7 @@ name_p (tree node)
/* Returns nonzero if TYPE is a character type, including wchar_t. */
int
-char_type_p (type)
- tree type;
+char_type_p (tree type)
{
return (same_type_p (type, char_type_node)
|| same_type_p (type, unsigned_char_type_node)
@@ -2509,8 +2375,7 @@ char_type_p (type)
as a global symbol when you run `nm' on the resulting object file. */
linkage_kind
-decl_linkage (decl)
- tree decl;
+decl_linkage (tree decl)
{
/* This function doesn't attempt to calculate the linkage from first
principles as given in [basic.link]. Instead, it makes use of
@@ -2549,15 +2414,13 @@ decl_linkage (decl)
expression to use the precalculated result. */
tree
-stabilize_expr (exp, initp)
- tree exp;
- tree *initp;
+stabilize_expr (tree exp, tree* initp)
{
tree init_expr;
if (!TREE_SIDE_EFFECTS (exp))
{
- init_expr = void_zero_node;
+ init_expr = NULL_TREE;
}
else if (!real_lvalue_p (exp)
|| !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (exp)))
@@ -2576,16 +2439,87 @@ stabilize_expr (exp, initp)
*initp = init_expr;
return exp;
}
+
+/* Like stabilize_expr, but for a call whose args we want to
+ pre-evaluate. */
+
+void
+stabilize_call (tree call, tree *initp)
+{
+ tree inits = NULL_TREE;
+ tree t;
+
+ if (call == error_mark_node)
+ return;
+
+ if (TREE_CODE (call) != CALL_EXPR
+ && TREE_CODE (call) != AGGR_INIT_EXPR)
+ abort ();
+
+ for (t = TREE_OPERAND (call, 1); t; t = TREE_CHAIN (t))
+ if (TREE_SIDE_EFFECTS (TREE_VALUE (t)))
+ {
+ tree init;
+ TREE_VALUE (t) = stabilize_expr (TREE_VALUE (t), &init);
+ if (!init)
+ /* Nothing. */;
+ else if (inits)
+ inits = build (COMPOUND_EXPR, void_type_node, inits, init);
+ else
+ inits = init;
+ }
+
+ *initp = inits;
+}
+
+/* Like stabilize_expr, but for an initialization. If we are initializing
+ an object of class type, we don't want to introduce an extra temporary,
+ so we look past the TARGET_EXPR and stabilize the arguments of the call
+ instead. */
+
+bool
+stabilize_init (tree init, tree *initp)
+{
+ tree t = init;
+
+ if (t == error_mark_node)
+ return true;
+
+ if (TREE_CODE (t) == INIT_EXPR
+ && TREE_CODE (TREE_OPERAND (t, 1)) != TARGET_EXPR)
+ TREE_OPERAND (t, 1) = stabilize_expr (TREE_OPERAND (t, 1), initp);
+ else
+ {
+ if (TREE_CODE (t) == INIT_EXPR)
+ t = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) == TARGET_EXPR)
+ t = TARGET_EXPR_INITIAL (t);
+ if (TREE_CODE (t) == CONSTRUCTOR
+ && CONSTRUCTOR_ELTS (t) == NULL_TREE)
+ {
+ /* Default-initialization. */
+ *initp = NULL_TREE;
+ return true;
+ }
+
+ /* If the initializer is a COND_EXPR, we can't preevaluate
+ anything. */
+ if (TREE_CODE (t) == COND_EXPR)
+ return false;
+
+ stabilize_call (t, initp);
+ }
+
+ return true;
+}
+
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
/* Complain that some language-specific thing hanging off a tree
node has been accessed improperly. */
void
-lang_check_failed (file, line, function)
- const char *file;
- int line;
- const char *function;
+lang_check_failed (const char* file, int line, const char* function)
{
internal_error ("lang_* check: failed in %s, at %s:%d",
function, trim_filename (file), line);
diff --git a/contrib/gcc/cp/typeck.c b/contrib/gcc/cp/typeck.c
index 4b36cc2ceaa6..5044db435731 100644
--- a/contrib/gcc/cp/typeck.c
+++ b/contrib/gcc/cp/typeck.c
@@ -1,22 +1,22 @@
/* Build expressions with type checking for C++ compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -32,6 +32,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "expr.h"
@@ -42,43 +44,35 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "diagnostic.h"
#include "target.h"
-
-static tree convert_for_assignment PARAMS ((tree, tree, const char *, tree,
- int));
-static tree cp_pointer_int_sum PARAMS ((enum tree_code, tree, tree));
-static tree rationalize_conditional_expr PARAMS ((enum tree_code, tree));
-static int comp_target_parms PARAMS ((tree, tree));
-static int comp_ptr_ttypes_real PARAMS ((tree, tree, int));
-static int comp_ptr_ttypes_const PARAMS ((tree, tree));
-static int comp_ptr_ttypes_reinterpret PARAMS ((tree, tree));
-static int comp_except_types PARAMS ((tree, tree, int));
-static int comp_array_types PARAMS ((int (*) (tree, tree, int), tree,
- tree, int));
-static tree common_base_type PARAMS ((tree, tree));
-static tree lookup_anon_field PARAMS ((tree, tree));
-static tree pointer_diff PARAMS ((tree, tree, tree));
-static tree qualify_type_recursive PARAMS ((tree, tree));
-static tree get_delta_difference PARAMS ((tree, tree, int));
-static int comp_cv_target_types PARAMS ((tree, tree, int));
-static void casts_away_constness_r PARAMS ((tree *, tree *));
-static int casts_away_constness PARAMS ((tree, tree));
-static void maybe_warn_about_returning_address_of_local PARAMS ((tree));
-static tree strip_all_pointer_quals PARAMS ((tree));
+#include "convert.h"
+
+static tree convert_for_assignment (tree, tree, const char *, tree, int);
+static tree cp_pointer_int_sum (enum tree_code, tree, tree);
+static tree rationalize_conditional_expr (enum tree_code, tree);
+static int comp_ptr_ttypes_real (tree, tree, int);
+static int comp_ptr_ttypes_const (tree, tree);
+static bool comp_except_types (tree, tree, bool);
+static bool comp_array_types (tree, tree, bool);
+static tree common_base_type (tree, tree);
+static tree pointer_diff (tree, tree, tree);
+static tree get_delta_difference (tree, tree, int);
+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);
/* Return the target type of TYPE, which means return T for:
T*, T&, T[], T (...), and otherwise, just T. */
tree
-target_type (type)
- tree type;
+target_type (tree type)
{
- if (TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
+ type = non_reference (type);
while (TREE_CODE (type) == POINTER_TYPE
|| TREE_CODE (type) == ARRAY_TYPE
|| TREE_CODE (type) == FUNCTION_TYPE
|| TREE_CODE (type) == METHOD_TYPE
- || TREE_CODE (type) == OFFSET_TYPE)
+ || TYPE_PTRMEM_P (type))
type = TREE_TYPE (type);
return type;
}
@@ -89,8 +83,7 @@ target_type (type)
complete type when this function returns. */
tree
-require_complete_type (value)
- tree value;
+require_complete_type (tree value)
{
tree type;
@@ -106,17 +99,6 @@ require_complete_type (value)
if (COMPLETE_TYPE_P (type))
return value;
- /* If we see X::Y, we build an OFFSET_TYPE which has
- not been laid out. Try to avoid an error by interpreting
- it as this->X::Y, if reasonable. */
- if (TREE_CODE (value) == OFFSET_REF
- && current_class_ref != 0
- && TREE_OPERAND (value, 0) == current_class_ref)
- {
- value = resolve_offset_ref (value);
- return require_complete_type (value);
- }
-
if (complete_type_or_else (type, value))
return value;
else
@@ -129,8 +111,7 @@ require_complete_type (value)
horribly wrong, in which case the error_mark_node is returned. */
tree
-complete_type (type)
- tree type;
+complete_type (tree type)
{
if (type == NULL_TREE)
/* Rather than crash, we return something sure to cause an error
@@ -142,7 +123,7 @@ complete_type (type)
else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
{
tree t = complete_type (TREE_TYPE (type));
- if (COMPLETE_TYPE_P (t) && ! processing_template_decl)
+ if (COMPLETE_TYPE_P (t) && !dependent_type_p (type))
layout_type (type);
TYPE_NEEDS_CONSTRUCTING (type)
= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
@@ -161,10 +142,7 @@ complete_type (type)
Returns NULL_TREE if the type cannot be made complete. */
tree
-complete_type_or_diagnostic (type, value, diag_type)
- tree type;
- tree value;
- int diag_type;
+complete_type_or_diagnostic (tree type, tree value, int diag_type)
{
type = complete_type (type);
if (type == error_mark_node)
@@ -182,58 +160,12 @@ complete_type_or_diagnostic (type, value, diag_type)
/* Return truthvalue of whether type of EXP is instantiated. */
int
-type_unknown_p (exp)
- tree exp;
+type_unknown_p (tree exp)
{
- return (TREE_CODE (exp) == OVERLOAD
- || TREE_CODE (exp) == TREE_LIST
- || TREE_TYPE (exp) == unknown_type_node
- || (TREE_CODE (TREE_TYPE (exp)) == OFFSET_TYPE
- && TREE_TYPE (TREE_TYPE (exp)) == unknown_type_node));
+ return (TREE_CODE (exp) == TREE_LIST
+ || TREE_TYPE (exp) == unknown_type_node);
}
-/* Return a pointer or pointer to member type similar to T1, with a
- cv-qualification signature that is the union of the cv-qualification
- signatures of T1 and T2: [expr.rel], [expr.eq]. */
-
-static tree
-qualify_type_recursive (t1, t2)
- tree t1, t2;
-{
- if ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2))
- || (TYPE_PTRMEM_P (t1) && TYPE_PTRMEM_P (t2)))
- {
- tree tt1;
- tree tt2;
- tree b1;
- int type_quals;
- tree tgt;
- tree attributes = (*targetm.merge_type_attributes) (t1, t2);
-
- if (TYPE_PTRMEM_P (t1))
- {
- b1 = TYPE_PTRMEM_CLASS_TYPE (t1);
- tt1 = TYPE_PTRMEM_POINTED_TO_TYPE (t1);
- tt2 = TYPE_PTRMEM_POINTED_TO_TYPE (t2);
- }
- else
- {
- b1 = NULL_TREE;
- tt1 = TREE_TYPE (t1);
- tt2 = TREE_TYPE (t2);
- }
-
- type_quals = (cp_type_quals (tt1) | cp_type_quals (tt2));
- tgt = qualify_type_recursive (tt1, tt2);
- tgt = cp_build_qualified_type (tgt, type_quals);
- if (b1)
- t1 = build_ptrmem_type (b1, tgt);
- else
- t1 = build_pointer_type (tgt);
- t1 = build_type_attribute_variant (t1, attributes);
- }
- return t1;
-}
/* Return the common type of two parameter lists.
We assume that comptypes has already been done and returned 1;
@@ -243,8 +175,7 @@ qualify_type_recursive (t1, t2)
lists are already common. */
tree
-commonparms (p1, p2)
- tree p1, p2;
+commonparms (tree p1, tree p2)
{
tree oldargs = p1, newargs, n;
int i, len;
@@ -305,8 +236,7 @@ commonparms (p1, p2)
/* Given a type, perhaps copied for a typedef,
find the "original" version of it. */
tree
-original_type (t)
- tree t;
+original_type (tree t)
{
while (TYPE_NAME (t) != NULL_TREE)
{
@@ -326,9 +256,7 @@ original_type (t)
T2 as described in [expr]. */
tree
-type_after_usual_arithmetic_conversions (t1, t2)
- tree t1;
- tree t2;
+type_after_usual_arithmetic_conversions (tree t1, tree t2)
{
enum tree_code code1 = TREE_CODE (t1);
enum tree_code code2 = TREE_CODE (t2);
@@ -466,20 +394,86 @@ type_after_usual_arithmetic_conversions (t1, t2)
}
}
+/* Subroutine of composite_pointer_type to implement the recursive
+ case. See that function for documentation fo the parameters. */
+
+static tree
+composite_pointer_type_r (tree t1, tree t2, const char* location)
+{
+ tree pointee1;
+ tree pointee2;
+ tree result_type;
+ tree attributes;
+
+ /* Determine the types pointed to by T1 and T2. */
+ if (TREE_CODE (t1) == POINTER_TYPE)
+ {
+ pointee1 = TREE_TYPE (t1);
+ pointee2 = TREE_TYPE (t2);
+ }
+ else
+ {
+ pointee1 = TYPE_PTRMEM_POINTED_TO_TYPE (t1);
+ pointee2 = TYPE_PTRMEM_POINTED_TO_TYPE (t2);
+ }
+
+ /* [expr.rel]
+
+ Otherwise, the composite pointer type is a pointer type
+ similar (_conv.qual_) to the type of one of the operands,
+ with a cv-qualification signature (_conv.qual_) that is the
+ union of the cv-qualification signatures of the operand
+ types. */
+ if (same_type_ignoring_top_level_qualifiers_p (pointee1, pointee2))
+ result_type = pointee1;
+ else if ((TREE_CODE (pointee1) == POINTER_TYPE
+ && TREE_CODE (pointee2) == POINTER_TYPE)
+ || (TYPE_PTR_TO_MEMBER_P (pointee1)
+ && TYPE_PTR_TO_MEMBER_P (pointee2)))
+ result_type = composite_pointer_type_r (pointee1, pointee2, location);
+ else
+ {
+ pedwarn ("%s between distinct pointer types `%T' and `%T' "
+ "lacks a cast",
+ location, t1, t2);
+ result_type = void_type_node;
+ }
+ result_type = cp_build_qualified_type (result_type,
+ (cp_type_quals (pointee1)
+ | cp_type_quals (pointee2)));
+ /* If the original types were pointers to members, so is the
+ result. */
+ if (TYPE_PTR_TO_MEMBER_P (t1))
+ {
+ if (!same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
+ TYPE_PTRMEM_CLASS_TYPE (t2)))
+ pedwarn ("%s between distinct pointer types `%T' and `%T' "
+ "lacks a cast",
+ location, t1, t2);
+ result_type = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
+ result_type);
+ }
+ else
+ result_type = build_pointer_type (result_type);
+
+ /* Merge the attributes. */
+ attributes = (*targetm.merge_type_attributes) (t1, t2);
+ return build_type_attribute_variant (result_type, attributes);
+}
+
/* Return the composite pointer type (see [expr.rel]) for T1 and T2.
ARG1 and ARG2 are the values with those types. The LOCATION is a
- string describing the current location, in case an error occurs. */
+ string describing the current location, in case an error occurs.
+
+ This routine also implements the computation of a common type for
+ pointers-to-members as per [expr.eq]. */
tree
-composite_pointer_type (t1, t2, arg1, arg2, location)
- tree t1;
- tree t2;
- tree arg1;
- tree arg2;
- const char* location;
+composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
+ const char* location)
{
- tree result_type;
- tree attributes;
+ tree class1;
+ tree class2;
/* [expr.rel]
@@ -490,16 +484,6 @@ composite_pointer_type (t1, t2, arg1, arg2, location)
if (null_ptr_cst_p (arg2))
return t1;
- /* Deal with pointer-to-member functions in the same way as we deal
- with pointers to functions. */
- if (TYPE_PTRMEMFUNC_P (t1))
- t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
- if (TYPE_PTRMEMFUNC_P (t2))
- t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
-
- /* Merge the attributes. */
- attributes = (*targetm.merge_type_attributes) (t1, t2);
-
/* We have:
[expr.rel]
@@ -510,45 +494,78 @@ composite_pointer_type (t1, t2, arg1, arg2, location)
and cv2.
If either type is a pointer to void, make sure it is T1. */
- if (VOID_TYPE_P (TREE_TYPE (t2)))
+ if (TREE_CODE (t2) == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (t2)))
{
tree t;
t = t1;
t1 = t2;
t2 = t;
}
+
/* Now, if T1 is a pointer to void, merge the qualifiers. */
- if (VOID_TYPE_P (TREE_TYPE (t1)))
+ if (TREE_CODE (t1) == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (t1)))
{
+ tree attributes;
+ tree result_type;
+
if (pedantic && TYPE_PTRFN_P (t2))
pedwarn ("ISO C++ forbids %s between pointer of type `void *' and pointer-to-function", location);
- t1 = TREE_TYPE (t1);
- t2 = TREE_TYPE (t2);
- result_type = cp_build_qualified_type (void_type_node,
- (cp_type_quals (t1)
- | cp_type_quals (t2)));
+ result_type
+ = cp_build_qualified_type (void_type_node,
+ (cp_type_quals (TREE_TYPE (t1))
+ | cp_type_quals (TREE_TYPE (t2))));
result_type = build_pointer_type (result_type);
+ /* Merge the attributes. */
+ attributes = (*targetm.merge_type_attributes) (t1, t2);
+ return build_type_attribute_variant (result_type, attributes);
+ }
+
+ /* [expr.eq] permits the application of a pointer conversion to
+ bring the pointers to a common type. */
+ if (TREE_CODE (t1) == POINTER_TYPE && TREE_CODE (t2) == POINTER_TYPE
+ && CLASS_TYPE_P (TREE_TYPE (t1))
+ && CLASS_TYPE_P (TREE_TYPE (t2))
+ && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (t1),
+ TREE_TYPE (t2)))
+ {
+ class1 = TREE_TYPE (t1);
+ class2 = TREE_TYPE (t2);
+
+ if (DERIVED_FROM_P (class1, class2))
+ t2 = (build_pointer_type
+ (cp_build_qualified_type (class1, TYPE_QUALS (class2))));
+ else if (DERIVED_FROM_P (class2, class1))
+ t1 = (build_pointer_type
+ (cp_build_qualified_type (class2, TYPE_QUALS (class1))));
+ else
+ {
+ error ("%s between distinct pointer types `%T' and `%T' "
+ "lacks a cast", location, t1, t2);
+ return error_mark_node;
+ }
}
- else
+ /* [expr.eq] permits the application of a pointer-to-member
+ conversion to change the class type of one of the types. */
+ else if (TYPE_PTR_TO_MEMBER_P (t1)
+ && !same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
+ TYPE_PTRMEM_CLASS_TYPE (t2)))
{
- tree full1 = qualify_type_recursive (t1, t2);
- tree full2 = qualify_type_recursive (t2, t1);
+ class1 = TYPE_PTRMEM_CLASS_TYPE (t1);
+ class2 = TYPE_PTRMEM_CLASS_TYPE (t2);
- int val = comp_target_types (full1, full2, 1);
-
- if (val > 0)
- result_type = full1;
- else if (val < 0)
- result_type = full2;
+ if (DERIVED_FROM_P (class1, class2))
+ t1 = build_ptrmem_type (class2, TYPE_PTRMEM_POINTED_TO_TYPE (t1));
+ else if (DERIVED_FROM_P (class2, class1))
+ t2 = build_ptrmem_type (class1, TYPE_PTRMEM_POINTED_TO_TYPE (t2));
else
{
- pedwarn ("%s between distinct pointer types `%T' and `%T' lacks a cast",
- location, t1, t2);
- result_type = ptr_type_node;
+ error ("%s between distinct pointer-to-member types `%T' and `%T' "
+ "lacks a cast", location, t1, t2);
+ return error_mark_node;
}
}
- return build_type_attribute_variant (result_type, attributes);
+ return composite_pointer_type_r (t1, t2, location);
}
/* Return the merged type of two types.
@@ -559,11 +576,10 @@ composite_pointer_type (t1, t2, arg1, arg2, location)
differences would cause the two types to compare unalike. */
tree
-merge_types (t1, t2)
- tree t1, t2;
+merge_types (tree t1, tree t2)
{
- register enum tree_code code1;
- register enum tree_code code2;
+ enum tree_code code1;
+ enum tree_code code2;
tree attributes;
/* Save time if the two types are the same. */
@@ -581,8 +597,6 @@ merge_types (t1, t2)
/* Merge the attributes. */
attributes = (*targetm.merge_type_attributes) (t1, t2);
- /* Treat an enum type as the unsigned integer type of the same width. */
-
if (TYPE_PTRMEMFUNC_P (t1))
t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
if (TYPE_PTRMEMFUNC_P (t2))
@@ -615,9 +629,14 @@ merge_types (t1, t2)
case OFFSET_TYPE:
{
- tree base = TYPE_OFFSET_BASETYPE (t1);
- tree target = merge_types (TREE_TYPE (t1), TREE_TYPE (t2));
- t1 = build_offset_type (base, target);
+ int quals;
+ tree pointee;
+ quals = cp_type_quals (t1);
+ pointee = merge_types (TYPE_PTRMEM_POINTED_TO_TYPE (t1),
+ TYPE_PTRMEM_POINTED_TO_TYPE (t2));
+ t1 = build_ptrmem_type (TYPE_PTRMEM_CLASS_TYPE (t1),
+ pointee);
+ t1 = cp_build_qualified_type (t1, quals);
break;
}
@@ -646,9 +665,9 @@ merge_types (t1, t2)
/* Save space: see if the result is identical to one of the args. */
if (valtype == TREE_TYPE (t1) && ! p2)
- return build_type_attribute_variant (t1, attributes);
+ return cp_build_type_attribute_variant (t1, attributes);
if (valtype == TREE_TYPE (t2) && ! p1)
- return build_type_attribute_variant (t2, attributes);
+ return cp_build_type_attribute_variant (t2, attributes);
/* Simple way if one arg fails to specify argument types. */
if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node)
@@ -656,7 +675,7 @@ merge_types (t1, t2)
rval = build_function_type (valtype, p2);
if ((raises = TYPE_RAISES_EXCEPTIONS (t2)))
rval = build_exception_variant (rval, raises);
- return build_type_attribute_variant (rval, attributes);
+ return cp_build_type_attribute_variant (rval, attributes);
}
raises = TYPE_RAISES_EXCEPTIONS (t1);
if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node)
@@ -664,7 +683,7 @@ merge_types (t1, t2)
rval = build_function_type (valtype, p1);
if (raises)
rval = build_exception_variant (rval, raises);
- return build_type_attribute_variant (rval, attributes);
+ return cp_build_type_attribute_variant (rval, attributes);
}
rval = build_function_type (valtype, commonparms (p1, p2));
@@ -688,15 +707,21 @@ merge_types (t1, t2)
t2 = build_function_type (TREE_TYPE (t2),
TREE_CHAIN (TYPE_ARG_TYPES (t2)));
t3 = merge_types (t1, t2);
- t3 = build_cplus_method_type (basetype, TREE_TYPE (t3),
- TYPE_ARG_TYPES (t3));
+ t3 = build_method_type_directly (basetype, TREE_TYPE (t3),
+ TYPE_ARG_TYPES (t3));
t1 = build_exception_variant (t3, raises);
break;
}
+ case TYPENAME_TYPE:
+ /* There is no need to merge attributes into a TYPENAME_TYPE.
+ When the type is instantiated it will have whatever
+ attributes result from the instantiation. */
+ return t1;
+
default:;
}
- return build_type_attribute_variant (t1, attributes);
+ return cp_build_type_attribute_variant (t1, attributes);
}
/* Return the common type of two types.
@@ -707,8 +732,7 @@ merge_types (t1, t2)
if the operands have the given two types. */
tree
-common_type (t1, t2)
- tree t1, t2;
+common_type (tree t1, tree t2)
{
enum tree_code code1;
enum tree_code code2;
@@ -731,18 +755,18 @@ common_type (t1, t2)
|| (TYPE_PTRMEMFUNC_P (t1) && TYPE_PTRMEMFUNC_P (t2)))
return composite_pointer_type (t1, t2, error_mark_node, error_mark_node,
"conversion");
-
else
abort ();
}
/* Compare two exception specifier types for exactness or subsetness, if
- allowed. Returns 0 for mismatch, 1 for same, 2 if B is allowed by A.
+ allowed. Returns false for mismatch, true for match (same, or
+ derived and !exact).
[except.spec] "If a class X ... objects of class X or any class publicly
- and unambigously derrived from X. Similarly, if a pointer type Y * ...
+ and unambiguously derived from X. Similarly, if a pointer type Y * ...
exceptions of type Y * or that are pointers to any type publicly and
- unambigously derrived from Y. Otherwise a function only allows exceptions
+ unambiguously derived from Y. Otherwise a function only allows exceptions
that have the same type ..."
This does not mention cv qualifiers and is different to what throw
[except.throw] and catch [except.catch] will do. They will ignore the
@@ -751,17 +775,15 @@ common_type (t1, t2)
We implement the letter of the standard. */
-static int
-comp_except_types (a, b, exact)
- tree a, b;
- int exact;
+static bool
+comp_except_types (tree a, tree b, bool exact)
{
if (same_type_p (a, b))
- return 1;
+ return true;
else if (!exact)
{
if (cp_type_quals (a) || cp_type_quals (b))
- return 0;
+ return false;
if (TREE_CODE (a) == POINTER_TYPE
&& TREE_CODE (b) == POINTER_TYPE)
@@ -769,43 +791,41 @@ comp_except_types (a, b, exact)
a = TREE_TYPE (a);
b = TREE_TYPE (b);
if (cp_type_quals (a) || cp_type_quals (b))
- return 0;
+ return false;
}
if (TREE_CODE (a) != RECORD_TYPE
|| TREE_CODE (b) != RECORD_TYPE)
- return 0;
+ return false;
if (ACCESSIBLY_UNIQUELY_DERIVED_P (a, b))
- return 2;
+ return true;
}
- return 0;
+ return false;
}
-/* Return 1 if TYPE1 and TYPE2 are equivalent exception specifiers.
- If EXACT is 0, T2 can be stricter than T1 (according to 15.4/7),
+/* Return true if TYPE1 and TYPE2 are equivalent exception specifiers.
+ If EXACT is false, T2 can be stricter than T1 (according to 15.4/7),
otherwise it must be exact. Exception lists are unordered, but
we've already filtered out duplicates. Most lists will be in order,
we should try to make use of that. */
-int
-comp_except_specs (t1, t2, exact)
- tree t1, t2;
- int exact;
+bool
+comp_except_specs (tree t1, tree t2, bool exact)
{
tree probe;
tree base;
int length = 0;
if (t1 == t2)
- return 1;
+ return true;
if (t1 == NULL_TREE) /* T1 is ... */
return t2 == NULL_TREE || !exact;
if (!TREE_VALUE (t1)) /* t1 is EMPTY */
return t2 != NULL_TREE && !TREE_VALUE (t2);
if (t2 == NULL_TREE) /* T2 is ... */
- return 0;
+ return false;
if (TREE_VALUE (t1) && !TREE_VALUE (t2)) /* T2 is EMPTY, T1 is not */
return !exact;
@@ -829,37 +849,33 @@ comp_except_specs (t1, t2, exact)
}
}
if (probe == NULL_TREE)
- return 0;
+ return false;
}
return !exact || base == NULL_TREE || length == list_length (t1);
}
-/* Compare the array types T1 and T2, using CMP as the type comparison
- function for the element types. STRICT is as for comptypes. */
+/* Compare the array types T1 and T2. ALLOW_REDECLARATION is true if
+ [] can match [size]. */
-static int
-comp_array_types (cmp, t1, t2, strict)
- register int (*cmp) PARAMS ((tree, tree, int));
- tree t1, t2;
- int strict;
+static bool
+comp_array_types (tree t1, tree t2, bool allow_redeclaration)
{
tree d1;
tree d2;
+ tree max1, max2;
if (t1 == t2)
- return 1;
+ return true;
/* The type of the array elements must be the same. */
- if (!(TREE_TYPE (t1) == TREE_TYPE (t2)
- || (*cmp) (TREE_TYPE (t1), TREE_TYPE (t2),
- strict & ~COMPARE_REDECLARATION)))
- return 0;
+ if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
d1 = TYPE_DOMAIN (t1);
d2 = TYPE_DOMAIN (t2);
if (d1 == d2)
- return 1;
+ return true;
/* If one of the arrays is dimensionless, and the other has a
dimension, they are of different types. However, it is valid to
@@ -874,68 +890,75 @@ comp_array_types (cmp, t1, t2, strict)
array types that differ by the presence or absence of a major
array bound (_dcl.array_). */
if (!d1 || !d2)
- return strict & COMPARE_REDECLARATION;
+ return allow_redeclaration;
/* Check that the dimensions are the same. */
- return (cp_tree_equal (TYPE_MIN_VALUE (d1),
- TYPE_MIN_VALUE (d2))
- && cp_tree_equal (TYPE_MAX_VALUE (d1),
- TYPE_MAX_VALUE (d2)));
-}
-
-/* Return 1 if T1 and T2 are compatible types for assignment or
- various other operations. STRICT is a bitwise-or of the COMPARE_*
- flags. */
-int
-comptypes (t1, t2, strict)
- tree t1;
- tree t2;
- int strict;
-{
- int attrval, val;
- int orig_strict = strict;
+ if (!cp_tree_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2)))
+ return false;
+ max1 = TYPE_MAX_VALUE (d1);
+ max2 = TYPE_MAX_VALUE (d2);
+ if (processing_template_decl && !abi_version_at_least (2)
+ && !value_dependent_expression_p (max1)
+ && !value_dependent_expression_p (max2))
+ {
+ /* With abi-1 we do not fold non-dependent array bounds, (and
+ consequently mangle them incorrectly). We must therefore
+ fold them here, to verify the domains have the same
+ value. */
+ max1 = fold (max1);
+ max2 = fold (max2);
+ }
- /* The special exemption for redeclaring array types without an
- array bound only applies at the top level:
+ if (!cp_tree_equal (max1, max2))
+ return false;
- extern int (*i)[];
- int (*i)[8];
+ return true;
+}
- is invalid, for example. */
- strict &= ~COMPARE_REDECLARATION;
+/* Return true if T1 and T2 are related as allowed by STRICT. STRICT
+ is a bitwise-or of the COMPARE_* flags. */
- /* Suppress errors caused by previously reported errors */
+bool
+comptypes (tree t1, tree t2, int strict)
+{
if (t1 == t2)
- return 1;
+ return true;
- /* Suppress errors caused by previously reported errors */
+ /* Suppress errors caused by previously reported errors. */
if (t1 == error_mark_node || t2 == error_mark_node)
- return 0;
+ return false;
+
+ my_friendly_assert (TYPE_P (t1) && TYPE_P (t2), 20030623);
+
+ /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
+ current instantiation. */
+ if (TREE_CODE (t1) == TYPENAME_TYPE)
+ {
+ tree resolved = resolve_typename_type (t1, /*only_current_p=*/true);
+
+ if (resolved != error_mark_node)
+ t1 = resolved;
+ }
+
+ if (TREE_CODE (t2) == TYPENAME_TYPE)
+ {
+ tree resolved = resolve_typename_type (t2, /*only_current_p=*/true);
+
+ if (resolved != error_mark_node)
+ t2 = resolved;
+ }
- /* If either type is the internal version of sizetype, return the
+ /* If either type is the internal version of sizetype, use the
language version. */
if (TREE_CODE (t1) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t1)
- && TYPE_DOMAIN (t1) != 0)
+ && TYPE_DOMAIN (t1))
t1 = TYPE_DOMAIN (t1);
if (TREE_CODE (t2) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t2)
- && TYPE_DOMAIN (t2) != 0)
+ && TYPE_DOMAIN (t2))
t2 = TYPE_DOMAIN (t2);
- if (strict & COMPARE_RELAXED)
- {
- /* Treat an enum type as the unsigned integer type of the same width. */
-
- if (TREE_CODE (t1) == ENUMERAL_TYPE)
- t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
- if (TREE_CODE (t2) == ENUMERAL_TYPE)
- t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
-
- if (t1 == t2)
- return 1;
- }
-
if (TYPE_PTRMEMFUNC_P (t1))
t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
if (TYPE_PTRMEMFUNC_P (t2))
@@ -943,30 +966,26 @@ comptypes (t1, t2, strict)
/* Different classes of types can't be compatible. */
if (TREE_CODE (t1) != TREE_CODE (t2))
- return 0;
+ return false;
- /* Qualifiers must match. */
- if (cp_type_quals (t1) != cp_type_quals (t2))
- return 0;
- if (strict == COMPARE_STRICT
- && TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
- return 0;
+ /* Qualifiers must match. For array types, we will check when we
+ recur on the array element types. */
+ if (TREE_CODE (t1) != ARRAY_TYPE
+ && TYPE_QUALS (t1) != TYPE_QUALS (t2))
+ return false;
+ if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
+ return false;
/* Allow for two different type nodes which have essentially the same
definition. Note that we already checked for equality of the type
qualifiers (just above). */
- if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
- return 1;
+ if (TREE_CODE (t1) != ARRAY_TYPE
+ && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
+ return true;
- if (strict & COMPARE_NO_ATTRIBUTES)
- attrval = 1;
- /* 1 if no need for warning yet, 2 if warning cause has been seen. */
- else if (! (attrval = (*targetm.comp_type_attributes) (t1, t2)))
- return 0;
-
- /* 1 if no need for warning yet, 2 if warning cause has been seen. */
- val = 0;
+ if (!(*targetm.comp_type_attributes) (t1, t2))
+ return false;
switch (TREE_CODE (t1))
{
@@ -974,79 +993,65 @@ comptypes (t1, t2, strict)
case BOUND_TEMPLATE_TEMPLATE_PARM:
if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
|| TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2))
- return 0;
- if (! comp_template_parms
- (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
- DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
- return 0;
+ return false;
+ if (!comp_template_parms
+ (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
+ DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
+ return false;
if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
- return 1;
+ return true;
/* Don't check inheritance. */
strict = COMPARE_STRICT;
- /* fall through */
+ /* Fall through. */
case RECORD_TYPE:
case UNION_TYPE:
if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
&& (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
- || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM))
- val = comp_template_args (TYPE_TI_ARGS (t1),
- TYPE_TI_ARGS (t2));
- look_hard:
+ || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ && comp_template_args (TYPE_TI_ARGS (t1), TYPE_TI_ARGS (t2)))
+ return true;
+
if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
- val = 1;
- else if ((strict & COMPARE_RELAXED) && DERIVED_FROM_P (t2, t1))
- val = 1;
- break;
+ return true;
+ else if ((strict & COMPARE_DERIVED) && DERIVED_FROM_P (t2, t1))
+ return true;
+
+ return false;
case OFFSET_TYPE:
- val = (comptypes (build_pointer_type (TYPE_OFFSET_BASETYPE (t1)),
- build_pointer_type (TYPE_OFFSET_BASETYPE (t2)), strict)
- && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict));
- break;
+ if (!comptypes (TYPE_OFFSET_BASETYPE (t1), TYPE_OFFSET_BASETYPE (t2),
+ strict & ~COMPARE_REDECLARATION))
+ return false;
+ /* Fall through. */
case POINTER_TYPE:
case REFERENCE_TYPE:
- t1 = TREE_TYPE (t1);
- t2 = TREE_TYPE (t2);
- /* first, check whether the referred types match with the
- required level of strictness */
- val = comptypes (t1, t2, strict);
- if (val)
- break;
- if (TREE_CODE (t1) == RECORD_TYPE
- && TREE_CODE (t2) == RECORD_TYPE)
- goto look_hard;
- break;
+ return same_type_p (TREE_TYPE (t1), TREE_TYPE (t2));
case METHOD_TYPE:
case FUNCTION_TYPE:
- val = ((TREE_TYPE (t1) == TREE_TYPE (t2)
- || comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict))
- && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)));
- break;
+ if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+ return false;
+ return compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2));
case ARRAY_TYPE:
- /* Target types must match incl. qualifiers. We use ORIG_STRICT
- here since this is the one place where
- COMPARE_REDECLARATION should be used. */
- val = comp_array_types (comptypes, t1, t2, orig_strict);
- break;
+ /* Target types must match incl. qualifiers. */
+ return comp_array_types (t1, t2, !!(strict & COMPARE_REDECLARATION));
case TEMPLATE_TYPE_PARM:
- return TEMPLATE_TYPE_IDX (t1) == TEMPLATE_TYPE_IDX (t2)
- && TEMPLATE_TYPE_LEVEL (t1) == TEMPLATE_TYPE_LEVEL (t2);
+ return (TEMPLATE_TYPE_IDX (t1) == TEMPLATE_TYPE_IDX (t2)
+ && TEMPLATE_TYPE_LEVEL (t1) == TEMPLATE_TYPE_LEVEL (t2));
case TYPENAME_TYPE:
- if (cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1),
- TYPENAME_TYPE_FULLNAME (t2)) < 1)
- return 0;
+ if (!cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1),
+ TYPENAME_TYPE_FULLNAME (t2)))
+ return false;
return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2));
case UNBOUND_CLASS_TEMPLATE:
- if (cp_tree_equal (TYPE_IDENTIFIER (t1),
- TYPE_IDENTIFIER (t2)) < 1)
- return 0;
+ if (!cp_tree_equal (TYPE_IDENTIFIER (t1), TYPE_IDENTIFIER (t2)))
+ return false;
return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2));
case COMPLEX_TYPE:
@@ -1055,254 +1060,47 @@ comptypes (t1, t2, strict)
default:
break;
}
- return attrval == 2 && val == 1 ? 2 : val;
-}
-
-/* Subroutine of comp_target-types. Make sure that the cv-quals change
- only in the same direction as the target type. */
-
-static int
-comp_cv_target_types (ttl, ttr, nptrs)
- tree ttl, ttr;
- int nptrs;
-{
- int t;
-
- if (!at_least_as_qualified_p (ttl, ttr)
- && !at_least_as_qualified_p (ttr, ttl))
- /* The qualifications are incomparable. */
- return 0;
-
- if (TYPE_MAIN_VARIANT (ttl) == TYPE_MAIN_VARIANT (ttr))
- return more_qualified_p (ttr, ttl) ? -1 : 1;
-
- t = comp_target_types (ttl, ttr, nptrs);
- if ((t == 1 && at_least_as_qualified_p (ttl, ttr))
- || (t == -1 && at_least_as_qualified_p (ttr, ttl)))
- return t;
-
- return 0;
-}
-
-/* Return 1 or -1 if TTL and TTR are pointers to types that are equivalent,
- ignoring their qualifiers, 0 if not. Return 1 means that TTR can be
- converted to TTL. Return -1 means that TTL can be converted to TTR but
- not vice versa.
-
- NPTRS is the number of pointers we can strip off and keep cool.
- This is used to permit (for aggr A, aggr B) A, B* to convert to A*,
- but to not permit B** to convert to A**.
-
- This should go away. Callers should use can_convert or something
- similar instead. (jason 17 Apr 1997) */
-
-int
-comp_target_types (ttl, ttr, nptrs)
- tree ttl, ttr;
- int nptrs;
-{
- ttl = TYPE_MAIN_VARIANT (ttl);
- ttr = TYPE_MAIN_VARIANT (ttr);
- if (same_type_p (ttl, ttr))
- return 1;
-
- if (TREE_CODE (ttr) != TREE_CODE (ttl))
- return 0;
-
- if ((TREE_CODE (ttr) == POINTER_TYPE
- || TREE_CODE (ttr) == REFERENCE_TYPE)
- /* If we get a pointer with nptrs == 0, we don't allow any tweaking
- of the type pointed to. This is necessary for reference init
- semantics. We won't get here from a previous call with nptrs == 1;
- for multi-level pointers we end up in comp_ptr_ttypes. */
- && nptrs > 0)
- {
- int is_ptr = TREE_CODE (ttr) == POINTER_TYPE;
-
- ttl = TREE_TYPE (ttl);
- ttr = TREE_TYPE (ttr);
-
- if (is_ptr)
- {
- if (TREE_CODE (ttl) == UNKNOWN_TYPE
- || TREE_CODE (ttr) == UNKNOWN_TYPE)
- return 1;
- else if (TREE_CODE (ttl) == VOID_TYPE
- && TREE_CODE (ttr) != FUNCTION_TYPE
- && TREE_CODE (ttr) != METHOD_TYPE
- && TREE_CODE (ttr) != OFFSET_TYPE)
- return 1;
- else if (TREE_CODE (ttr) == VOID_TYPE
- && TREE_CODE (ttl) != FUNCTION_TYPE
- && TREE_CODE (ttl) != METHOD_TYPE
- && TREE_CODE (ttl) != OFFSET_TYPE)
- return -1;
- else if (TREE_CODE (ttl) == POINTER_TYPE
- || TREE_CODE (ttl) == ARRAY_TYPE)
- {
- if (comp_ptr_ttypes (ttl, ttr))
- return 1;
- else if (comp_ptr_ttypes (ttr, ttl))
- return -1;
- return 0;
- }
- }
-
- /* Const and volatile mean something different for function types,
- so the usual checks are not appropriate. */
- if (TREE_CODE (ttl) == FUNCTION_TYPE || TREE_CODE (ttl) == METHOD_TYPE)
- return comp_target_types (ttl, ttr, nptrs - 1);
-
- return comp_cv_target_types (ttl, ttr, nptrs - 1);
- }
-
- if (TREE_CODE (ttr) == ARRAY_TYPE)
- return comp_array_types (comp_target_types, ttl, ttr, COMPARE_STRICT);
- else if (TREE_CODE (ttr) == FUNCTION_TYPE || TREE_CODE (ttr) == METHOD_TYPE)
- {
- tree argsl, argsr;
- int saw_contra = 0;
-
- if (pedantic)
- {
- if (!same_type_p (TREE_TYPE (ttl), TREE_TYPE (ttr)))
- return 0;
- }
- else
- {
- switch (comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), -1))
- {
- case 0:
- return 0;
- case -1:
- saw_contra = 1;
- }
- }
-
- argsl = TYPE_ARG_TYPES (ttl);
- argsr = TYPE_ARG_TYPES (ttr);
-
- /* Compare 'this' here, not in comp_target_parms. */
- if (TREE_CODE (ttr) == METHOD_TYPE)
- {
- tree tl = TYPE_METHOD_BASETYPE (ttl);
- tree tr = TYPE_METHOD_BASETYPE (ttr);
-
- if (!same_or_base_type_p (tr, tl))
- {
- if (same_or_base_type_p (tl, tr))
- saw_contra = 1;
- else
- return 0;
- }
-
- argsl = TREE_CHAIN (argsl);
- argsr = TREE_CHAIN (argsr);
- }
-
- switch (comp_target_parms (argsl, argsr))
- {
- case 0:
- return 0;
- case -1:
- saw_contra = 1;
- }
-
- return saw_contra ? -1 : 1;
- }
- /* for C++ */
- else if (TREE_CODE (ttr) == OFFSET_TYPE)
- {
- int base;
-
- /* Contravariance: we can assign a pointer to base member to a pointer
- to derived member. Note difference from simple pointer case, where
- we can pass a pointer to derived to a pointer to base. */
- if (same_or_base_type_p (TYPE_OFFSET_BASETYPE (ttr),
- TYPE_OFFSET_BASETYPE (ttl)))
- base = 1;
- else if (same_or_base_type_p (TYPE_OFFSET_BASETYPE (ttl),
- TYPE_OFFSET_BASETYPE (ttr)))
- {
- tree tmp = ttl;
- ttl = ttr;
- ttr = tmp;
- base = -1;
- }
- else
- return 0;
-
- ttl = TREE_TYPE (ttl);
- ttr = TREE_TYPE (ttr);
-
- if (TREE_CODE (ttl) == POINTER_TYPE
- || TREE_CODE (ttl) == ARRAY_TYPE)
- {
- if (comp_ptr_ttypes (ttl, ttr))
- return base;
- return 0;
- }
- else
- {
- if (comp_cv_target_types (ttl, ttr, nptrs) == 1)
- return base;
- return 0;
- }
- }
- else if (IS_AGGR_TYPE (ttl))
- {
- if (nptrs < 0)
- return 0;
- if (same_or_base_type_p (build_pointer_type (ttl),
- build_pointer_type (ttr)))
- return 1;
- if (same_or_base_type_p (build_pointer_type (ttr),
- build_pointer_type (ttl)))
- return -1;
- return 0;
- }
-
- return 0;
+ return false;
}
/* Returns 1 if TYPE1 is at least as qualified as TYPE2. */
-int
-at_least_as_qualified_p (type1, type2)
- tree type1;
- tree type2;
+bool
+at_least_as_qualified_p (tree type1, tree type2)
{
+ int q1 = cp_type_quals (type1);
+ int q2 = cp_type_quals (type2);
+
/* All qualifiers for TYPE2 must also appear in TYPE1. */
- return ((cp_type_quals (type1) & cp_type_quals (type2))
- == cp_type_quals (type2));
+ return (q1 & q2) == q2;
}
/* Returns 1 if TYPE1 is more qualified than TYPE2. */
-int
-more_qualified_p (type1, type2)
- tree type1;
- tree type2;
+bool
+more_qualified_p (tree type1, tree type2)
{
- return (cp_type_quals (type1) != cp_type_quals (type2)
- && at_least_as_qualified_p (type1, type2));
+ int q1 = cp_type_quals (type1);
+ int q2 = cp_type_quals (type2);
+
+ return q1 != q2 && (q1 & q2) == q2;
}
/* Returns 1 if TYPE1 is more cv-qualified than TYPE2, -1 if TYPE2 is
more cv-qualified that TYPE1, and 0 otherwise. */
int
-comp_cv_qualification (type1, type2)
- tree type1;
- tree type2;
+comp_cv_qualification (tree type1, tree type2)
{
- if (cp_type_quals (type1) == cp_type_quals (type2))
+ int q1 = cp_type_quals (type1);
+ int q2 = cp_type_quals (type2);
+
+ if (q1 == q2)
return 0;
- if (at_least_as_qualified_p (type1, type2))
+ if ((q1 & q2) == q2)
return 1;
-
- else if (at_least_as_qualified_p (type2, type1))
+ else if ((q1 & q2) == q1)
return -1;
return 0;
@@ -1313,9 +1111,7 @@ comp_cv_qualification (type1, type2)
are similar. Returns -1 if the other way 'round, and 0 otherwise. */
int
-comp_cv_qual_signature (type1, type2)
- tree type1;
- tree type2;
+comp_cv_qual_signature (tree type1, tree type2)
{
if (comp_ptr_ttypes_real (type2, type1, -1))
return 1;
@@ -1330,8 +1126,7 @@ comp_cv_qual_signature (type1, type2)
returns ERROR_MARK_NODE. */
static tree
-common_base_type (tt1, tt2)
- tree tt1, tt2;
+common_base_type (tree tt1, tree tt2)
{
tree best = NULL_TREE;
int i;
@@ -1379,133 +1174,58 @@ common_base_type (tt1, tt2)
/* Subroutines of `comptypes'. */
-/* Return 1 if two parameter type lists PARMS1 and PARMS2 are
+/* Return true if two parameter type lists PARMS1 and PARMS2 are
equivalent in the sense that functions with those parameter types
can have equivalent types. The two lists must be equivalent,
- element by element.
-
- C++: See comment above about TYPE1, TYPE2. */
+ element by element. */
-int
-compparms (parms1, parms2)
- tree parms1, parms2;
+bool
+compparms (tree parms1, tree parms2)
{
- register tree t1 = parms1, t2 = parms2;
+ tree t1, t2;
/* An unspecified parmlist matches any specified parmlist
whose argument types don't need default promotions. */
- while (1)
+ for (t1 = parms1, t2 = parms2;
+ t1 || t2;
+ t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
{
- if (t1 == 0 && t2 == 0)
- return 1;
/* If one parmlist is shorter than the other,
they fail to match. */
- if (t1 == 0 || t2 == 0)
- return 0;
+ if (!t1 || !t2)
+ return false;
if (!same_type_p (TREE_VALUE (t1), TREE_VALUE (t2)))
- return 0;
-
- t1 = TREE_CHAIN (t1);
- t2 = TREE_CHAIN (t2);
+ return false;
}
+ return true;
}
-/* This really wants return whether or not parameter type lists
- would make their owning functions assignment compatible or not.
-
- The return value is like for comp_target_types.
-
- This should go away, possibly with the exception of the empty parmlist
- conversion; there are no conversions between function types in C++.
- (jason 17 Apr 1997) */
-
-static int
-comp_target_parms (parms1, parms2)
- tree parms1, parms2;
-{
- register tree t1 = parms1, t2 = parms2;
- int warn_contravariance = 0;
-
- /* In C, an unspecified parmlist matches any specified parmlist
- whose argument types don't need default promotions. This is not
- true for C++, but let's do it anyway for unfixed headers. */
-
- if (t1 == 0 && t2 != 0)
- {
- pedwarn ("ISO C++ prohibits conversion from `%#T' to `(...)'",
- parms2);
- return self_promoting_args_p (t2);
- }
- if (t2 == 0)
- return self_promoting_args_p (t1);
-
- for (; t1 || t2; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
- {
- tree p1, p2;
-
- /* If one parmlist is shorter than the other,
- they fail to match, unless STRICT is <= 0. */
- if (t1 == 0 || t2 == 0)
- return 0;
- p1 = TREE_VALUE (t1);
- p2 = TREE_VALUE (t2);
- if (same_type_p (p1, p2))
- continue;
-
- if (pedantic)
- return 0;
-
- if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE)
- || (TREE_CODE (p1) == REFERENCE_TYPE
- && TREE_CODE (p2) == REFERENCE_TYPE))
- {
- /* The following is wrong for contravariance,
- but many programs depend on it. */
- if (TREE_TYPE (p1) == void_type_node)
- continue;
- if (TREE_TYPE (p2) == void_type_node)
- {
- warn_contravariance = 1;
- continue;
- }
- if (IS_AGGR_TYPE (TREE_TYPE (p1))
- && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (p1),
- TREE_TYPE (p2)))
- return 0;
- }
- /* Note backwards order due to contravariance. */
- if (comp_target_types (p2, p1, 1) <= 0)
- {
- if (comp_target_types (p1, p2, 1) > 0)
- {
- warn_contravariance = 1;
- continue;
- }
- return 0;
- }
- }
- return warn_contravariance ? -1 : 1;
-}
+/* Process a sizeof or alignof expression where the operand is a
+ type. */
+
tree
-cxx_sizeof_or_alignof_type (type, op, complain)
- tree type;
- enum tree_code op;
- int complain;
+cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
{
enum tree_code type_code;
tree value;
const char *op_name;
my_friendly_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR, 20020720);
+ if (type == error_mark_node)
+ return error_mark_node;
+
if (processing_template_decl)
- return build_min_nt (op, type);
+ {
+ value = build_min (op, size_type_node, type);
+ TREE_READONLY (value) = 1;
+ return value;
+ }
op_name = operator_name_info[(int) op].name;
-
- if (TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
+
+ type = non_reference (type);
type_code = TREE_CODE (type);
if (type_code == METHOD_TYPE)
@@ -1514,66 +1234,94 @@ cxx_sizeof_or_alignof_type (type, op, complain)
pedwarn ("invalid application of `%s' to a member function", op_name);
value = size_one_node;
}
- else if (type_code == OFFSET_TYPE)
- {
- if (complain)
- error ("invalid application of `%s' to non-static member", op_name);
- value = size_zero_node;
- }
else
value = c_sizeof_or_alignof_type (complete_type (type), op, complain);
return value;
}
+/* Process a sizeof or alignof expression where the operand is an
+ expression. */
+
tree
-expr_sizeof (e)
- tree e;
+cxx_sizeof_or_alignof_expr (tree e, enum tree_code op)
{
+ const char *op_name = operator_name_info[(int) op].name;
+
+ if (e == error_mark_node)
+ return error_mark_node;
+
if (processing_template_decl)
- return build_min_nt (SIZEOF_EXPR, e);
-
+ {
+ e = build_min (op, size_type_node, e);
+ TREE_SIDE_EFFECTS (e) = 0;
+ TREE_READONLY (e) = 1;
+
+ return e;
+ }
+
if (TREE_CODE (e) == COMPONENT_REF
+ && TREE_CODE (TREE_OPERAND (e, 1)) == FIELD_DECL
&& DECL_C_BIT_FIELD (TREE_OPERAND (e, 1)))
- error ("sizeof applied to a bit-field");
- if (is_overloaded_fn (e))
{
- pedwarn ("ISO C++ forbids applying `sizeof' to an expression of function type");
- return c_sizeof (char_type_node);
+ error ("invalid application of `%s' to a bit-field", op_name);
+ e = char_type_node;
+ }
+ else if (is_overloaded_fn (e))
+ {
+ pedwarn ("ISO C++ forbids applying `%s' to an expression of function type", op_name);
+ e = char_type_node;
}
else if (type_unknown_p (e))
{
cxx_incomplete_type_error (e, TREE_TYPE (e));
- return c_sizeof (char_type_node);
+ e = char_type_node;
}
- /* It's invalid to say `sizeof (X::i)' for `i' a non-static data
- member unless you're in a non-static member of X. So hand off to
- resolve_offset_ref. [expr.prim] */
- else if (TREE_CODE (e) == OFFSET_REF)
- e = resolve_offset_ref (e);
-
- if (e == error_mark_node)
- return e;
-
- return cxx_sizeof (TREE_TYPE (e));
+ else
+ e = TREE_TYPE (e);
+
+ return cxx_sizeof_or_alignof_type (e, op, true);
}
-/* Perform the array-to-pointer and function-to-pointer conversions
- for EXP.
+/* EXPR is being used in a context that is not a function call.
+ Enforce:
- In addition, references are converted to lvalues and manifest
- constants are replaced by their values. */
+ [expr.ref]
-tree
-decay_conversion (exp)
- tree exp;
+ The expression can be used only as the left-hand operand of a
+ member function call.
+
+ [expr.mptr.operator]
+
+ If the result of .* or ->* is a function, then that result can be
+ used only as the operand for the function call operator ().
+
+ by issuing an error message if appropriate. Returns true iff EXPR
+ violates these rules. */
+
+bool
+invalid_nonstatic_memfn_p (tree expr)
{
- register tree type;
- register enum tree_code code;
+ if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE)
+ {
+ error ("invalid use of non-static member function");
+ return true;
+ }
+ return false;
+}
+
+/* Perform the conversions in [expr] that apply when an lvalue appears
+ in an rvalue context: the lvalue-to-rvalue, array-to-pointer, and
+ function-to-pointer conversions.
- if (TREE_CODE (exp) == OFFSET_REF)
- exp = resolve_offset_ref (exp);
+ In addition manifest constants are replaced by their values. */
+
+tree
+decay_conversion (tree exp)
+{
+ tree type;
+ enum tree_code code;
type = TREE_TYPE (exp);
code = TREE_CODE (type);
@@ -1615,30 +1363,18 @@ decay_conversion (exp)
error ("void value not ignored as it ought to be");
return error_mark_node;
}
- if (code == METHOD_TYPE)
- abort ();
+ if (invalid_nonstatic_memfn_p (exp))
+ return error_mark_node;
if (code == FUNCTION_TYPE || is_overloaded_fn (exp))
return build_unary_op (ADDR_EXPR, exp, 0);
if (code == ARRAY_TYPE)
{
- register tree adr;
+ tree adr;
tree ptrtype;
if (TREE_CODE (exp) == INDIRECT_REF)
- {
- /* Stripping away the INDIRECT_REF is not the right
- thing to do for references... */
- tree inner = TREE_OPERAND (exp, 0);
- if (TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE)
- {
- inner = build1 (CONVERT_EXPR,
- build_pointer_type (TREE_TYPE
- (TREE_TYPE (inner))),
- inner);
- TREE_CONSTANT (inner) = TREE_CONSTANT (TREE_OPERAND (inner, 0));
- }
- return cp_convert (build_pointer_type (TREE_TYPE (type)), inner);
- }
+ return build_nop (build_pointer_type (TREE_TYPE (type)),
+ TREE_OPERAND (exp, 0));
if (TREE_CODE (exp) == COMPOUND_EXPR)
{
@@ -1658,14 +1394,9 @@ decay_conversion (exp)
if (TREE_CODE (exp) == VAR_DECL)
{
- /* ??? This is not really quite correct
- in that the type of the operand of ADDR_EXPR
- is not the target type of the type of the ADDR_EXPR itself.
- Question is, can this lossage be avoided? */
- adr = build1 (ADDR_EXPR, ptrtype, exp);
if (!cxx_mark_addressable (exp))
return error_mark_node;
- TREE_CONSTANT (adr) = staticp (exp);
+ adr = build_nop (ptrtype, build_address (exp));
TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */
return adr;
}
@@ -1684,33 +1415,39 @@ decay_conversion (exp)
}
tree
-default_conversion (exp)
- tree exp;
+default_conversion (tree exp)
{
- tree type;
- enum tree_code code;
-
exp = decay_conversion (exp);
- type = TREE_TYPE (exp);
- code = TREE_CODE (type);
-
- if (INTEGRAL_CODE_P (code))
- {
- tree t = type_promotes_to (type);
- if (t != type)
- return cp_convert (t, exp);
- }
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
+ exp = perform_integral_promotions (exp);
return exp;
}
+/* EXPR is an expression with an integral or enumeration type.
+ Perform the integral promotions in [conv.prom], and return the
+ converted value. */
+
+tree
+perform_integral_promotions (tree expr)
+{
+ tree type;
+ tree promoted_type;
+
+ type = TREE_TYPE (expr);
+ my_friendly_assert (INTEGRAL_OR_ENUMERATION_TYPE_P (type), 20030703);
+ promoted_type = type_promotes_to (type);
+ if (type != promoted_type)
+ expr = cp_convert (promoted_type, expr);
+ return expr;
+}
+
/* Take the address of an inline function without setting TREE_ADDRESSABLE
or TREE_USED. */
tree
-inline_conversion (exp)
- tree exp;
+inline_conversion (tree exp)
{
if (TREE_CODE (exp) == FUNCTION_DECL)
exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
@@ -1722,9 +1459,7 @@ inline_conversion (exp)
decay_conversion to one. */
int
-string_conv_p (totype, exp, warn)
- tree totype, exp;
- int warn;
+string_conv_p (tree totype, tree exp, int warn)
{
tree t;
@@ -1770,9 +1505,7 @@ string_conv_p (totype, exp, warn)
get it there. */
static tree
-rationalize_conditional_expr (code, t)
- enum tree_code code;
- tree t;
+rationalize_conditional_expr (enum tree_code code, tree t)
{
/* For MIN_EXPR or MAX_EXPR, fold-const.c has arranged things so that
the first operand is always the one to be used if both operands
@@ -1783,7 +1516,8 @@ rationalize_conditional_expr (code, t)
build_conditional_expr (build_x_binary_op ((TREE_CODE (t) == MIN_EXPR
? LE_EXPR : GE_EXPR),
TREE_OPERAND (t, 0),
- TREE_OPERAND (t, 1)),
+ TREE_OPERAND (t, 1),
+ /*overloaded_p=*/NULL),
build_unary_op (code, TREE_OPERAND (t, 0), 0),
build_unary_op (code, TREE_OPERAND (t, 1), 0));
}
@@ -1799,9 +1533,8 @@ rationalize_conditional_expr (code, t)
anonymous unions can nest, we must also search all anonymous unions
that are directly reachable. */
-static tree
-lookup_anon_field (t, type)
- tree t, type;
+tree
+lookup_anon_field (tree t, tree type)
{
tree field;
@@ -1854,36 +1587,19 @@ build_class_member_access_expr (tree object, tree member,
if (object == error_mark_node || member == error_mark_node)
return error_mark_node;
+ if (TREE_CODE (member) == PSEUDO_DTOR_EXPR)
+ return member;
+
my_friendly_assert (DECL_P (member) || BASELINK_P (member),
20020801);
- /* Transform `(a, b).x' into `a, b.x' and `(a ? b : c).x' into
- `a ? b.x : c.x'. These transformations should not really be
- necessary, but they are. */
- if (TREE_CODE (object) == COMPOUND_EXPR)
- {
- result = build_class_member_access_expr (TREE_OPERAND (object, 1),
- member, access_path,
- preserve_reference);
- return build (COMPOUND_EXPR, TREE_TYPE (result),
- TREE_OPERAND (object, 0), result);
- }
- else if (TREE_CODE (object) == COND_EXPR)
- return (build_conditional_expr
- (TREE_OPERAND (object, 0),
- build_class_member_access_expr (TREE_OPERAND (object, 1),
- member, access_path,
- preserve_reference),
- build_class_member_access_expr (TREE_OPERAND (object, 2),
- member, access_path,
- preserve_reference)));
-
/* [expr.ref]
The type of the first expression shall be "class object" (of a
complete type). */
object_type = TREE_TYPE (object);
- if (!complete_type_or_else (object_type, object))
+ if (!currently_open_class (object_type)
+ && !complete_type_or_else (object_type, object))
return error_mark_node;
if (!CLASS_TYPE_P (object_type))
{
@@ -1913,10 +1629,22 @@ build_class_member_access_expr (tree object, tree member,
member_scope = TYPE_CONTEXT (member_scope);
if (!member_scope || !DERIVED_FROM_P (member_scope, object_type))
{
- error ("`%D' is not a member of `%T'", member, object_type);
+ if (TREE_CODE (member) == FIELD_DECL)
+ error ("invalid use of nonstatic data member '%E'", member);
+ else
+ error ("`%D' is not a member of `%T'", member, object_type);
return error_mark_node;
}
+ /* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x' into
+ `(*(a ? &b : &c)).x', and so on. A COND_EXPR is only an lvalue
+ in the frontend; only _DECLs and _REFs are lvalues in the backend. */
+ {
+ tree temp = unary_complex_lvalue (ADDR_EXPR, object);
+ if (temp)
+ object = build_indirect_ref (temp, NULL);
+ }
+
/* In [expr.ref], there is an explicit list of the valid choices for
MEMBER. We check for each of those cases here. */
if (TREE_CODE (member) == VAR_DECL)
@@ -1973,7 +1701,8 @@ build_class_member_access_expr (tree object, tree member,
give the right answer. Note that we complain whether or not they
actually used the offsetof macro, since there's no way to know at this
point. So we just give a warning, instead of a pedwarn. */
- if (null_object_p && CLASSTYPE_NON_POD_P (object_type))
+ if (null_object_p && warn_invalid_offsetof
+ && CLASSTYPE_NON_POD_P (object_type))
{
warning ("invalid access to non-static data member `%D' of NULL object",
member);
@@ -2034,6 +1763,7 @@ build_class_member_access_expr (tree object, tree member,
{
/* The member is a (possibly overloaded) member function. */
tree functions;
+ tree type;
/* If the MEMBER is exactly one static member function, then we
know the type of the expression. Otherwise, we must wait
@@ -2041,19 +1771,12 @@ build_class_member_access_expr (tree object, tree member,
functions = BASELINK_FUNCTIONS (member);
if (TREE_CODE (functions) == FUNCTION_DECL
&& DECL_STATIC_FUNCTION_P (functions))
- {
- /* A static member function. */
- result = functions;
- mark_used (result);
- /* If OBJECT has side-effects, they are supposed to occur. */
- if (TREE_SIDE_EFFECTS (object))
- result = build (COMPOUND_EXPR, TREE_TYPE (result),
- object, result);
- }
+ type = TREE_TYPE (functions);
else
- /* Note that we do not convert OBJECT to the BASELINK_BINFO
- base. That will happen when the function is called. */
- result = build (COMPONENT_REF, unknown_type_node, object, member);
+ type = unknown_type_node;
+ /* Note that we do not convert OBJECT to the BASELINK_BINFO
+ base. That will happen when the function is called. */
+ result = build (COMPONENT_REF, type, object, member);
}
else if (TREE_CODE (member) == CONST_DECL)
{
@@ -2080,6 +1803,38 @@ build_class_member_access_expr (tree object, tree member,
return result;
}
+/* Return the destructor denoted by OBJECT.SCOPE::~DTOR_NAME, or, if
+ SCOPE is NULL, by OBJECT.~DTOR_NAME. */
+
+static tree
+lookup_destructor (tree object, tree scope, tree dtor_name)
+{
+ tree object_type = TREE_TYPE (object);
+ tree dtor_type = TREE_OPERAND (dtor_name, 0);
+ tree expr;
+
+ if (scope && !check_dtor_name (scope, dtor_name))
+ {
+ error ("qualified type `%T' does not match destructor name `~%T'",
+ scope, dtor_type);
+ return error_mark_node;
+ }
+ if (!DERIVED_FROM_P (dtor_type, TYPE_MAIN_VARIANT (object_type)))
+ {
+ error ("the type being destroyed is `%T', but the destructor refers to `%T'",
+ TYPE_MAIN_VARIANT (object_type), dtor_type);
+ return error_mark_node;
+ }
+ if (!TYPE_HAS_DESTRUCTOR (dtor_type))
+ return build (PSEUDO_DTOR_EXPR, void_type_node, object, scope,
+ dtor_type);
+ expr = lookup_member (dtor_type, complete_dtor_identifier,
+ /*protect=*/1, /*want_type=*/false);
+ expr = (adjust_result_of_qualified_name_lookup
+ (expr, dtor_type, object_type));
+ return expr;
+}
+
/* This function is called by the parser to process a class member
access expression of the form OBJECT.NAME. NAME is a node used by
the parser to represent a name; it is not yet a DECL. It may,
@@ -2091,20 +1846,39 @@ build_class_member_access_expr (tree object, tree member,
tree
finish_class_member_access_expr (tree object, tree name)
{
+ tree expr;
tree object_type;
tree member;
tree access_path = NULL_TREE;
+ tree orig_object = object;
+ tree orig_name = name;
if (object == error_mark_node || name == error_mark_node)
return error_mark_node;
+ object_type = TREE_TYPE (object);
+
if (processing_template_decl)
- return build_min_nt (COMPONENT_REF, object, name);
+ {
+ if (/* If OBJECT_TYPE is dependent, so is OBJECT.NAME. */
+ dependent_type_p (object_type)
+ /* If NAME is just an IDENTIFIER_NODE, then the expression
+ is dependent. */
+ || TREE_CODE (object) == IDENTIFIER_NODE
+ /* If NAME is "f<args>", where either 'f' or 'args' is
+ dependent, then the expression is dependent. */
+ || (TREE_CODE (name) == TEMPLATE_ID_EXPR
+ && dependent_template_id_p (TREE_OPERAND (name, 0),
+ TREE_OPERAND (name, 1)))
+ /* If NAME is "T::X" where "T" is dependent, then the
+ expression is dependent. */
+ || (TREE_CODE (name) == SCOPE_REF
+ && TYPE_P (TREE_OPERAND (name, 0))
+ && dependent_type_p (TREE_OPERAND (name, 0))))
+ return build_min_nt (COMPONENT_REF, object, name);
+ object = build_non_dependent_expr (object);
+ }
- if (TREE_CODE (object) == OFFSET_REF)
- object = resolve_offset_ref (object);
-
- object_type = TREE_TYPE (object);
if (TREE_CODE (object_type) == REFERENCE_TYPE)
{
object = convert_from_reference (object);
@@ -2115,7 +1889,8 @@ finish_class_member_access_expr (tree object, tree name)
The type of the first expression shall be "class object" (of a
complete type). */
- if (!complete_type_or_else (object_type, object))
+ if (!currently_open_class (object_type)
+ && !complete_type_or_else (object_type, object))
return error_mark_node;
if (!CLASS_TYPE_P (object_type))
{
@@ -2136,18 +1911,22 @@ finish_class_member_access_expr (tree object, tree name)
{
bool is_template_id = false;
tree template_args = NULL_TREE;
+ tree scope;
if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
{
is_template_id = true;
template_args = TREE_OPERAND (name, 1);
name = TREE_OPERAND (name, 0);
+
+ if (TREE_CODE (name) == OVERLOAD)
+ name = DECL_NAME (get_first_fn (name));
+ else if (DECL_P (name))
+ name = DECL_NAME (name);
}
if (TREE_CODE (name) == SCOPE_REF)
{
- tree scope;
-
/* A qualified name. The qualifying class or namespace `S' has
already been looked up; it is either a TYPE or a
NAMESPACE_DECL. The member name is either an IDENTIFIER_NODE
@@ -2179,66 +1958,35 @@ finish_class_member_access_expr (tree object, tree name)
error ("`%T' is not a base of `%T'", scope, object_type);
return error_mark_node;
}
-
- /* Look up the member. */
- member = lookup_member (access_path, name, /*protect=*/1,
- /*want_type=*/0);
- if (member == NULL_TREE)
- {
- error ("'%D' has no member named '%E'", object_type, name);
- return error_mark_node;
- }
- else if (member == error_mark_node)
- return error_mark_node;
}
- else if (TREE_CODE (name) == BIT_NOT_EXPR)
+ else
{
- /* A destructor. */
- if (TYPE_IDENTIFIER (object_type) != TREE_OPERAND (name, 0))
- {
- error ("destructor specifier `%T::~%T' must have matching names",
- object_type, TREE_OPERAND (name, 0));
- return error_mark_node;
- }
- if (! TYPE_HAS_DESTRUCTOR (object_type))
- {
- error ("type `%T' has no destructor", object_type);
- return error_mark_node;
- }
- member = CLASSTYPE_DESTRUCTORS (object_type);
+ scope = NULL_TREE;
+ access_path = object_type;
}
- else if (TREE_CODE (name) == IDENTIFIER_NODE)
+
+ if (TREE_CODE (name) == BIT_NOT_EXPR)
+ member = lookup_destructor (object, scope, name);
+ else
{
- /* An unqualified name. */
- member = lookup_member (object_type, name, /*protect=*/1,
- /*want_type=*/0);
+ /* Look up the member. */
+ member = lookup_member (access_path, name, /*protect=*/1,
+ /*want_type=*/false);
if (member == NULL_TREE)
{
error ("'%D' has no member named '%E'", object_type, name);
return error_mark_node;
}
- else if (member == error_mark_node)
+ if (member == error_mark_node)
return error_mark_node;
}
- else
- {
- /* The YACC parser sometimes gives us things that are not names.
- These always indicate errors. The recursive-descent parser
- does not do this, so this code can go away once that parser
- replaces the YACC parser. */
- error ("invalid use of `%D'", name);
- return error_mark_node;
- }
if (is_template_id)
{
tree template = member;
if (BASELINK_P (template))
- BASELINK_FUNCTIONS (template)
- = build_nt (TEMPLATE_ID_EXPR,
- BASELINK_FUNCTIONS (template),
- template_args);
+ template = lookup_template_function (template, template_args);
else
{
error ("`%D' is not a member template function", name);
@@ -2247,8 +1995,15 @@ finish_class_member_access_expr (tree object, tree name)
}
}
- return build_class_member_access_expr (object, member, access_path,
+ if (TREE_DEPRECATED (member))
+ warn_deprecated_use (member);
+
+ expr = build_class_member_access_expr (object, member, access_path,
/*preserve_reference=*/false);
+ if (processing_template_decl && expr != error_mark_node)
+ return build_min_non_dep (COMPONENT_REF, expr,
+ orig_object, orig_name);
+ return expr;
}
/* Return an expression for the MEMBER_NAME field in the internal
@@ -2272,7 +2027,7 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
ptrmem_type = TREE_TYPE (ptrmem);
my_friendly_assert (TYPE_PTRMEMFUNC_P (ptrmem_type), 20020804);
member = lookup_member (ptrmem_type, member_name, /*protect=*/0,
- /*want_type=*/0);
+ /*want_type=*/false);
member_type = cp_build_qualified_type (TREE_TYPE (member),
cp_type_quals (ptrmem_type));
return fold (build (COMPONENT_REF, member_type, ptrmem, member));
@@ -2286,28 +2041,33 @@ build_ptrmemfunc_access_expr (tree ptrmem, tree member_name)
Must also handle REFERENCE_TYPEs for C++. */
tree
-build_x_indirect_ref (ptr, errorstring)
- tree ptr;
- const char *errorstring;
+build_x_indirect_ref (tree expr, const char *errorstring)
{
+ tree orig_expr = expr;
tree rval;
if (processing_template_decl)
- return build_min_nt (INDIRECT_REF, ptr);
+ {
+ if (type_dependent_expression_p (expr))
+ return build_min_nt (INDIRECT_REF, expr);
+ expr = build_non_dependent_expr (expr);
+ }
- rval = build_opfncall (INDIRECT_REF, LOOKUP_NORMAL, ptr, NULL_TREE,
- NULL_TREE);
- if (rval)
+ rval = build_new_op (INDIRECT_REF, LOOKUP_NORMAL, expr, NULL_TREE,
+ NULL_TREE, /*overloaded_p=*/NULL);
+ if (!rval)
+ rval = build_indirect_ref (expr, errorstring);
+
+ if (processing_template_decl && rval != error_mark_node)
+ return build_min_non_dep (INDIRECT_REF, rval, orig_expr);
+ else
return rval;
- return build_indirect_ref (ptr, errorstring);
}
tree
-build_indirect_ref (ptr, errorstring)
- tree ptr;
- const char *errorstring;
+build_indirect_ref (tree ptr, const char *errorstring)
{
- register tree pointer, type;
+ tree pointer, type;
if (ptr == error_mark_node)
return error_mark_node;
@@ -2316,7 +2076,7 @@ build_indirect_ref (ptr, errorstring)
return current_class_ref;
pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE
- ? ptr : default_conversion (ptr));
+ ? ptr : decay_conversion (ptr));
type = TREE_TYPE (pointer);
if (TYPE_PTR_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
@@ -2339,7 +2099,6 @@ build_indirect_ref (ptr, errorstring)
return error_mark_node;
}
else if (TREE_CODE (pointer) == ADDR_EXPR
- && !flag_volatile
&& same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))))
/* The POINTER was something like `&x'. We simplify `*&x' to
`x'. */
@@ -2354,14 +2113,13 @@ build_indirect_ref (ptr, errorstring)
TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
TREE_SIDE_EFFECTS (ref)
- = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer)
- || flag_volatile);
+ = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer));
return ref;
}
}
/* `pointer' won't be an error_mark_node if we were given a
pointer to member, so it's cool to check for this here. */
- else if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type))
+ else if (TYPE_PTR_TO_MEMBER_P (type))
error ("invalid use of `%s' on pointer to member", errorstring);
else if (pointer != error_mark_node)
{
@@ -2387,8 +2145,7 @@ build_indirect_ref (ptr, errorstring)
will inherit the type of the array, which will be some pointer type. */
tree
-build_array_ref (array, idx)
- tree array, idx;
+build_array_ref (tree array, tree idx)
{
if (idx == 0)
{
@@ -2436,15 +2193,19 @@ build_array_ref (array, idx)
&& TYPE_MAIN_VARIANT (TREE_TYPE (idx)) == char_type_node)
warning ("array subscript has type `char'");
- /* Apply default promotions *after* noticing character types. */
- idx = default_conversion (idx);
-
- if (TREE_CODE (TREE_TYPE (idx)) != INTEGER_TYPE)
+ if (!INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (idx)))
{
error ("array subscript is not an integer");
return error_mark_node;
}
+ /* Apply integral promotions *after* noticing character types.
+ (It is unclear why we do these promotions -- the standard
+ does not say that we should. In fact, the natual thing would
+ seem to be to convert IDX to ptrdiff_t; we're performing
+ pointer arithmetic.) */
+ idx = perform_integral_promotions (idx);
+
/* An array that is indexed by a non-constant
cannot be stored in a register; we must be able to do
address arithmetic on its address.
@@ -2540,9 +2301,7 @@ build_array_ref (array, idx)
later has the right member. */
tree
-get_member_function_from_ptrfunc (instance_ptrptr, function)
- tree *instance_ptrptr;
- tree function;
+get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
{
if (TREE_CODE (function) == OFFSET_REF)
function = TREE_OPERAND (function, 1);
@@ -2644,12 +2403,10 @@ get_member_function_from_ptrfunc (instance_ptrptr, function)
}
tree
-build_function_call_real (function, params, flags)
- tree function, params;
- int flags;
+build_function_call (tree function, tree params)
{
- register tree fntype, fndecl;
- register tree coerced_params;
+ tree fntype, fndecl;
+ tree coerced_params;
tree result;
tree name = NULL_TREE, assembler_name = NULL_TREE;
int is_method;
@@ -2719,20 +2476,10 @@ build_function_call_real (function, params, flags)
/* Convert the parameters to the types declared in the
function prototype, or apply default promotions. */
- if (flags & LOOKUP_COMPLAIN)
- coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
- params, fndecl, LOOKUP_NORMAL);
- else
- coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
- params, fndecl, 0);
-
+ coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype),
+ params, fndecl, LOOKUP_NORMAL);
if (coerced_params == error_mark_node)
- {
- if (flags & LOOKUP_SPECULATIVELY)
- return NULL_TREE;
- else
- return error_mark_node;
- }
+ return error_mark_node;
/* Check for errors in format strings. */
@@ -2755,13 +2502,6 @@ build_function_call_real (function, params, flags)
return build_cxx_call (function, params, coerced_params);
}
-
-tree
-build_function_call (function, params)
- tree function, params;
-{
- return build_function_call_real (function, params, LOOKUP_NORMAL);
-}
/* Convert the actual parameter expressions in the list VALUES
to the types in the list TYPELIST.
@@ -2781,12 +2521,10 @@ build_function_call (function, params)
default arguments, if such were specified. Do so here. */
tree
-convert_arguments (typelist, values, fndecl, flags)
- tree typelist, values, fndecl;
- int flags;
+convert_arguments (tree typelist, tree values, tree fndecl, int flags)
{
- register tree typetail, valtail;
- register tree result = NULL_TREE;
+ tree typetail, valtail;
+ tree result = NULL_TREE;
const char *called_thing = 0;
int i = 0;
@@ -2811,8 +2549,8 @@ convert_arguments (typelist, values, fndecl, flags)
valtail;
valtail = TREE_CHAIN (valtail), i++)
{
- register tree type = typetail ? TREE_VALUE (typetail) : 0;
- register tree val = TREE_VALUE (valtail);
+ tree type = typetail ? TREE_VALUE (typetail) : 0;
+ tree val = TREE_VALUE (valtail);
if (val == error_mark_node)
return error_mark_node;
@@ -2834,9 +2572,6 @@ convert_arguments (typelist, values, fndecl, flags)
break;
}
- if (TREE_CODE (val) == OFFSET_REF)
- val = resolve_offset_ref (val);
-
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
Strip such NOP_EXPRs, since VAL is used in non-lvalue context. */
if (TREE_CODE (val) == NOP_EXPR
@@ -2849,7 +2584,7 @@ convert_arguments (typelist, values, fndecl, flags)
if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE)
- val = default_conversion (val);
+ val = decay_conversion (val);
}
if (val == error_mark_node)
@@ -2862,8 +2597,12 @@ convert_arguments (typelist, values, fndecl, flags)
if (!COMPLETE_TYPE_P (complete_type (type)))
{
- error ("parameter type of called function is incomplete");
- parmval = val;
+ if (fndecl)
+ error ("parameter %P of `%D' has incomplete type `%T'",
+ i, fndecl, type);
+ else
+ error ("parameter %P has incomplete type `%T'", i, type);
+ parmval = error_mark_node;
}
else
{
@@ -2901,8 +2640,9 @@ convert_arguments (typelist, values, fndecl, flags)
if (typetail != 0 && typetail != void_list_node)
{
- /* See if there are default arguments that can be used */
- if (TREE_PURPOSE (typetail))
+ /* See if there are default arguments that can be used. */
+ if (TREE_PURPOSE (typetail)
+ && TREE_CODE (TREE_PURPOSE (typetail)) != DEFAULT_ARG)
{
for (; typetail != void_list_node; ++i)
{
@@ -2942,14 +2682,35 @@ convert_arguments (typelist, values, fndecl, flags)
conversions on the operands. CODE is the kind of expression to build. */
tree
-build_x_binary_op (code, arg1, arg2)
- enum tree_code code;
- tree arg1, arg2;
+build_x_binary_op (enum tree_code code, tree arg1, tree arg2,
+ bool *overloaded_p)
{
+ tree orig_arg1;
+ tree orig_arg2;
+ tree expr;
+
+ orig_arg1 = arg1;
+ orig_arg2 = arg2;
+
if (processing_template_decl)
- return build_min_nt (code, arg1, arg2);
+ {
+ if (type_dependent_expression_p (arg1)
+ || type_dependent_expression_p (arg2))
+ return build_min_nt (code, arg1, arg2);
+ arg1 = build_non_dependent_expr (arg1);
+ arg2 = build_non_dependent_expr (arg2);
+ }
- return build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE);
+ if (code == DOTSTAR_EXPR)
+ expr = build_m_component_ref (arg1, arg2);
+ else
+ expr = build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE,
+ overloaded_p);
+
+ if (processing_template_decl && expr != error_mark_node)
+ return build_min_non_dep (code, expr, orig_arg1, orig_arg2);
+
+ return expr;
}
/* Build a binary-operation expression without default conversions.
@@ -2971,23 +2732,21 @@ build_x_binary_op (code, arg1, arg2)
multiple inheritance, and deal with pointer to member functions. */
tree
-build_binary_op (code, orig_op0, orig_op1, convert_p)
- enum tree_code code;
- tree orig_op0, orig_op1;
- int convert_p ATTRIBUTE_UNUSED;
+build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
+ int convert_p ATTRIBUTE_UNUSED)
{
tree op0, op1;
- register enum tree_code code0, code1;
+ enum tree_code code0, code1;
tree type0, type1;
/* Expression code to give to the expression when it is built.
Normally this is CODE, which is what the caller asked for,
but in some special cases we change it. */
- register enum tree_code resultcode = code;
+ enum tree_code resultcode = code;
/* Data type in which the computation is to be performed.
In the simplest cases this is the common type of the arguments. */
- register tree result_type = NULL;
+ tree result_type = NULL;
/* Nonzero means operands have already been type-converted
in whatever way is necessary.
@@ -3099,7 +2858,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
/* 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, 1))
+ && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
+ TREE_TYPE (type1)))
return pointer_diff (op0, op1, common_type (type0, type1));
/* Handle pointer minus int. Just like pointer plus int. */
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
@@ -3145,7 +2905,6 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
break;
case BIT_AND_EXPR:
- case BIT_ANDTC_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
@@ -3261,12 +3020,15 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|| code1 == COMPLEX_TYPE))
short_compare = 1;
- else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
+ else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE)
+ || (TYPE_PTRMEM_P (type0) && TYPE_PTRMEM_P (type1)))
result_type = composite_pointer_type (type0, type1, op0, op1,
"comparison");
- else if (code0 == POINTER_TYPE && null_ptr_cst_p (op1))
+ else if ((code0 == POINTER_TYPE || TYPE_PTRMEM_P (type0))
+ && null_ptr_cst_p (op1))
result_type = type0;
- else if (code1 == POINTER_TYPE && null_ptr_cst_p (op0))
+ else if ((code1 == POINTER_TYPE || TYPE_PTRMEM_P (type1))
+ && null_ptr_cst_p (op0))
result_type = type1;
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
@@ -3535,7 +3297,10 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
}
if ((short_compare || code == MIN_EXPR || code == MAX_EXPR)
- && warn_sign_compare)
+ && warn_sign_compare
+ /* Do not warn until the template is instantiated; we cannot
+ bound the ranges of the arguments until that point. */
+ && !processing_template_decl)
{
int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
@@ -3690,8 +3455,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
build_type = result_type;
{
- register tree result = build (resultcode, build_type, op0, op1);
- register tree folded;
+ tree result = build (resultcode, build_type, op0, op1);
+ tree folded;
folded = fold (result);
if (folded == result)
@@ -3706,9 +3471,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
of pointer PTROP and integer INTOP. */
static tree
-cp_pointer_int_sum (resultcode, ptrop, intop)
- enum tree_code resultcode;
- register tree ptrop, intop;
+cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
{
tree res_type = TREE_TYPE (ptrop);
@@ -3726,11 +3489,9 @@ cp_pointer_int_sum (resultcode, ptrop, intop)
The resulting tree has type int. */
static tree
-pointer_diff (op0, op1, ptrtype)
- register tree op0, op1;
- register tree ptrtype;
+pointer_diff (tree op0, tree op1, tree ptrtype)
{
- register tree result, folded;
+ tree result, folded;
tree restype = ptrdiff_type_node;
tree target_type = TREE_TYPE (ptrtype);
@@ -3745,8 +3506,6 @@ pointer_diff (op0, op1, ptrtype)
pedwarn ("ISO C++ forbids using pointer to a function in subtraction");
if (TREE_CODE (target_type) == METHOD_TYPE)
pedwarn ("ISO C++ forbids using pointer to a method in subtraction");
- if (TREE_CODE (target_type) == OFFSET_TYPE)
- pedwarn ("ISO C++ forbids using pointer to a member in subtraction");
}
/* First do the subtraction as integers;
@@ -3760,12 +3519,9 @@ pointer_diff (op0, op1, ptrtype)
if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
error ("invalid use of a pointer to an incomplete type in pointer arithmetic");
- op1 = ((TREE_CODE (target_type) == VOID_TYPE
- || TREE_CODE (target_type) == FUNCTION_TYPE
- || TREE_CODE (target_type) == METHOD_TYPE
- || TREE_CODE (target_type) == OFFSET_TYPE)
- ? integer_one_node
- : size_in_bytes (target_type));
+ op1 = (TYPE_PTROB_P (ptrtype)
+ ? size_in_bytes (target_type)
+ : integer_one_node);
/* Do the division. */
@@ -3782,34 +3538,39 @@ pointer_diff (op0, op1, ptrtype)
and XARG is the operand. */
tree
-build_x_unary_op (code, xarg)
- enum tree_code code;
- tree xarg;
+build_x_unary_op (enum tree_code code, tree xarg)
{
+ tree orig_expr = xarg;
tree exp;
int ptrmem = 0;
if (processing_template_decl)
- return build_min_nt (code, xarg, NULL_TREE);
+ {
+ if (type_dependent_expression_p (xarg))
+ return build_min_nt (code, xarg, NULL_TREE);
+ xarg = build_non_dependent_expr (xarg);
+ }
+
+ exp = NULL_TREE;
+
+ /* [expr.unary.op] says:
- /* & rec, on incomplete RECORD_TYPEs is the simple opr &, not an
- error message. */
+ The address of an object of incomplete type can be taken.
+
+ (And is just the ordinary address operator, not an overloaded
+ "operator &".) However, if the type is a template
+ specialization, we must complete the type at this point so that
+ an overloaded "operator &" will be available if required. */
if (code == ADDR_EXPR
&& TREE_CODE (xarg) != TEMPLATE_ID_EXPR
- && ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (xarg)))
- && !COMPLETE_TYPE_P (TREE_TYPE (xarg)))
+ && ((CLASS_TYPE_P (TREE_TYPE (xarg))
+ && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg))))
|| (TREE_CODE (xarg) == OFFSET_REF)))
- /* don't look for a function */;
+ /* Don't look for a function. */;
else
- {
- tree rval;
-
- rval = build_new_op (code, LOOKUP_NORMAL, xarg,
- NULL_TREE, NULL_TREE);
- if (rval || code != ADDR_EXPR)
- return rval;
- }
- if (code == ADDR_EXPR)
+ exp = build_new_op (code, LOOKUP_NORMAL, xarg, NULL_TREE, NULL_TREE,
+ /*overloaded_p=*/NULL);
+ if (!exp && code == ADDR_EXPR)
{
/* A pointer to member-function can be formed only by saying
&X::mf. */
@@ -3843,16 +3604,18 @@ build_x_unary_op (code, xarg)
TREE_OPERAND (xarg, 0),
ovl_cons (TREE_OPERAND (xarg, 1), NULL_TREE));
PTRMEM_OK_P (xarg) = ptrmem;
- }
-
+ }
}
else if (TREE_CODE (xarg) == TARGET_EXPR)
warning ("taking address of temporary");
+ exp = build_unary_op (ADDR_EXPR, xarg, 0);
+ if (TREE_CODE (exp) == ADDR_EXPR)
+ PTRMEM_OK_P (exp) = ptrmem;
}
- exp = build_unary_op (code, xarg, 0);
- if (TREE_CODE (exp) == ADDR_EXPR)
- PTRMEM_OK_P (exp) = ptrmem;
+ if (processing_template_decl && exp != error_mark_node)
+ return build_min_non_dep (code, exp, orig_expr,
+ /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
return exp;
}
@@ -3861,8 +3624,7 @@ build_x_unary_op (code, xarg)
-1. */
tree
-cp_truthvalue_conversion (expr)
- tree expr;
+cp_truthvalue_conversion (tree expr)
{
tree type = TREE_TYPE (expr);
if (TYPE_PTRMEM_P (type))
@@ -3874,14 +3636,11 @@ cp_truthvalue_conversion (expr)
/* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR. */
tree
-condition_conversion (expr)
- tree expr;
+condition_conversion (tree expr)
{
tree t;
if (processing_template_decl)
return expr;
- if (TREE_CODE (expr) == OFFSET_REF)
- expr = resolve_offset_ref (expr);
t = perform_implicit_conversion (boolean_type_node, expr);
t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t));
return t;
@@ -3899,9 +3658,7 @@ build_address (tree t)
if (error_operand_p (t) || !cxx_mark_addressable (t))
return error_mark_node;
- addr = build1 (ADDR_EXPR,
- build_pointer_type (TREE_TYPE (t)),
- t);
+ addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
if (staticp (t))
TREE_CONSTANT (addr) = 1;
@@ -3935,14 +3692,11 @@ build_nop (tree type, tree expr)
(such as from short to int). */
tree
-build_unary_op (code, xarg, noconvert)
- enum tree_code code;
- tree xarg;
- int noconvert;
+build_unary_op (enum tree_code code, tree xarg, int noconvert)
{
/* No default_conversion here. It causes trouble for ADDR_EXPR. */
- register tree arg = xarg;
- register tree argtype = 0;
+ tree arg = xarg;
+ tree argtype = 0;
const char *errstring = NULL;
tree val;
@@ -3956,7 +3710,7 @@ build_unary_op (code, xarg, noconvert)
is enough to prevent anybody from looking inside for
associativity, but won't generate any code. */
if (!(arg = build_expr_type_conversion
- (WANT_ARITH | WANT_ENUM | WANT_POINTER, arg, 1)))
+ (WANT_ARITH | WANT_ENUM | WANT_POINTER, arg, true)))
errstring = "wrong type argument to unary plus";
else
{
@@ -3968,10 +3722,10 @@ build_unary_op (code, xarg, noconvert)
break;
case NEGATE_EXPR:
- if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, 1)))
+ if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
errstring = "wrong type argument to unary minus";
- else if (!noconvert)
- arg = default_conversion (arg);
+ else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
+ arg = perform_integral_promotions (arg);
break;
case BIT_NOT_EXPR:
@@ -3982,14 +3736,14 @@ build_unary_op (code, xarg, noconvert)
arg = default_conversion (arg);
}
else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM,
- arg, 1)))
+ arg, true)))
errstring = "wrong type argument to bit-complement";
else if (!noconvert)
- arg = default_conversion (arg);
+ arg = perform_integral_promotions (arg);
break;
case ABS_EXPR:
- if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, 1)))
+ if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
errstring = "wrong type argument to abs";
else if (!noconvert)
arg = default_conversion (arg);
@@ -3997,14 +3751,14 @@ build_unary_op (code, xarg, noconvert)
case CONJ_EXPR:
/* Conjugating a real value is a no-op, but allow it anyway. */
- if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, 1)))
+ if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true)))
errstring = "wrong type argument to conjugation";
else if (!noconvert)
arg = default_conversion (arg);
break;
case TRUTH_NOT_EXPR:
- arg = cp_convert (boolean_type_node, arg);
+ arg = perform_implicit_conversion (boolean_type_node, arg);
val = invert_truthvalue (arg);
if (arg != error_mark_node)
return val;
@@ -4057,7 +3811,7 @@ build_unary_op (code, xarg, noconvert)
/* Report invalid types. */
if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_POINTER,
- arg, 1)))
+ arg, true)))
{
if (code == PREINCREMENT_EXPR)
errstring ="no pre-increment operator for type";
@@ -4080,7 +3834,7 @@ build_unary_op (code, xarg, noconvert)
0);
{
- register tree inc;
+ tree inc;
tree result_type = TREE_TYPE (arg);
arg = get_unwidened (arg, 0);
@@ -4096,7 +3850,6 @@ build_unary_op (code, xarg, noconvert)
if (TREE_CODE (argtype) == POINTER_TYPE)
{
- enum tree_code tmp = TREE_CODE (TREE_TYPE (argtype));
tree type = complete_type (TREE_TYPE (argtype));
if (!COMPLETE_OR_VOID_TYPE_P (type))
@@ -4105,8 +3858,7 @@ build_unary_op (code, xarg, noconvert)
|| code == POSTINCREMENT_EXPR)
? "increment" : "decrement"), TREE_TYPE (argtype));
else if ((pedantic || warn_pointer_arith)
- && (tmp == FUNCTION_TYPE || tmp == METHOD_TYPE
- || tmp == VOID_TYPE || tmp == OFFSET_TYPE))
+ && !TYPE_PTROB_P (argtype))
pedwarn ("ISO C++ forbids %sing a pointer of type `%T'",
((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
@@ -4169,13 +3921,7 @@ build_unary_op (code, xarg, noconvert)
error ("invalid use of `--' on bool variable `%D'", arg);
return error_mark_node;
}
-#if 0
- /* This will only work if someone can convince Kenner to accept
- my patch to expand_increment. (jason) */
- val = build (code, TREE_TYPE (arg), arg, inc);
-#else
val = boolean_increment (code, arg);
-#endif
}
else
val = build (code, TREE_TYPE (arg), arg, inc);
@@ -4189,6 +3935,10 @@ build_unary_op (code, xarg, noconvert)
regardless of NOCONVERT. */
argtype = lvalue_type (arg);
+
+ if (TREE_CODE (arg) == OFFSET_REF)
+ goto offset_ref;
+
if (TREE_CODE (argtype) == REFERENCE_TYPE)
{
arg = build1
@@ -4223,8 +3973,12 @@ build_unary_op (code, xarg, noconvert)
return arg;
}
- /* For &x[y], return x+y */
- if (TREE_CODE (arg) == ARRAY_REF)
+ /* For &x[y], return x+y. But, in a template, ARG may be an
+ ARRAY_REF representing a non-dependent expression. In that
+ case, there may be an overloaded "operator []" that will be
+ chosen at instantiation time; we must not try to optimize
+ here. */
+ if (TREE_CODE (arg) == ARRAY_REF && !processing_template_decl)
{
if (!cxx_mark_addressable (TREE_OPERAND (arg, 0)))
return error_mark_node;
@@ -4258,7 +4012,11 @@ build_unary_op (code, xarg, noconvert)
We could defer this in non-MS mode, but it's easier to give
a useful error here. */
- tree base = TREE_TYPE (TREE_OPERAND (arg, 0));
+ /* Inside constant member functions, the `this' pointer
+ contains an extra const qualifier. TYPE_MAIN_VARIANT
+ is used here to remove this const from the diagnostics
+ and the created OFFSET_REF. */
+ tree base = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (arg, 0)));
tree name = DECL_NAME (get_first_fn (TREE_OPERAND (arg, 1)));
if (! flag_ms_extensions)
@@ -4266,13 +4024,20 @@ build_unary_op (code, xarg, noconvert)
if (current_class_type
&& TREE_OPERAND (arg, 0) == current_class_ref)
/* An expression like &memfn. */
- pedwarn ("ISO C++ forbids taking the address of an unqualified non-static member function to form a pointer to member function. Say `&%T::%D'", base, name);
+ pedwarn ("ISO C++ forbids taking the address of an unqualified"
+ " or parenthesized non-static member function to form"
+ " a pointer to member function. Say `&%T::%D'",
+ base, name);
else
- pedwarn ("ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say `&%T::%D'", base, name);
+ pedwarn ("ISO C++ forbids taking the address of a bound member"
+ " function to form a pointer to member function."
+ " Say `&%T::%D'",
+ base, name);
}
- arg = build_offset_ref (base, name);
+ arg = build_offset_ref (base, name, /*address_p=*/true);
}
-
+
+ offset_ref:
if (type_unknown_p (arg))
return build1 (ADDR_EXPR, unknown_type_node, arg);
@@ -4294,7 +4059,11 @@ build_unary_op (code, xarg, noconvert)
if (! lvalue_p (arg) && pedantic)
pedwarn ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
break;
-
+
+ case OVERLOAD:
+ arg = OVL_CURRENT (arg);
+ break;
+
default:
break;
}
@@ -4308,7 +4077,7 @@ build_unary_op (code, xarg, noconvert)
is an error. */
else if (TREE_CODE (argtype) != FUNCTION_TYPE
&& TREE_CODE (argtype) != METHOD_TYPE
- && !non_cast_lvalue_or_else (arg, "unary `&'"))
+ && !lvalue_or_else (arg, "unary `&'"))
return error_mark_node;
if (argtype != error_mark_node)
@@ -4317,8 +4086,28 @@ build_unary_op (code, xarg, noconvert)
{
tree addr;
- if (TREE_CODE (arg) != COMPONENT_REF)
+ if (TREE_CODE (arg) != COMPONENT_REF
+ /* Inside a template, we are processing a non-dependent
+ expression so we can just form an ADDR_EXPR with the
+ correct type. */
+ || processing_template_decl)
addr = build_address (arg);
+ else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
+ {
+ tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
+
+ /* We can only get here with a single static member
+ function. */
+ my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_STATIC_FUNCTION_P (fn),
+ 20030906);
+ mark_used (fn);
+ addr = build_address (fn);
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
+ /* Do not lose object's side effects. */
+ addr = build (COMPOUND_EXPR, TREE_TYPE (addr),
+ TREE_OPERAND (arg, 0), addr);
+ }
else if (DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
{
error ("attempt to take address of bit-field structure member `%D'",
@@ -4337,8 +4126,7 @@ build_unary_op (code, xarg, noconvert)
ba_check, NULL);
rval = build_base_path (PLUS_EXPR, rval, binfo, 1);
- rval = build1 (NOP_EXPR, argtype, rval);
- TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0));
+ rval = build_nop (argtype, rval);
addr = fold (build (PLUS_EXPR, argtype, rval,
cp_convert (argtype, byte_position (field))));
}
@@ -4375,9 +4163,7 @@ build_unary_op (code, xarg, noconvert)
If ARG is not a kind of expression we can handle, return zero. */
tree
-unary_complex_lvalue (code, arg)
- enum tree_code code;
- tree arg;
+unary_complex_lvalue (enum tree_code code, tree arg)
{
/* Handle (a, b) used as an "lvalue". */
if (TREE_CODE (arg) == COMPOUND_EXPR)
@@ -4423,11 +4209,8 @@ unary_complex_lvalue (code, arg)
if (TREE_CODE (TREE_TYPE (arg)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (arg)) == METHOD_TYPE
- || TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
+ || TREE_CODE (arg) == OFFSET_REF)
{
- /* The representation of something of type OFFSET_TYPE
- is really the representation of a pointer to it.
- Here give the representation its true type. */
tree t;
my_friendly_assert (TREE_CODE (arg) != SCOPE_REF, 313);
@@ -4458,15 +4241,7 @@ unary_complex_lvalue (code, arg)
return error_mark_node;
}
if (!PTRMEM_OK_P (arg))
- {
- /* This cannot form a pointer to method, so we must
- resolve the offset ref, and take the address of the
- result. For instance,
- &(C::m) */
- arg = resolve_offset_ref (arg);
-
- return build_unary_op (code, arg, 0);
- }
+ return build_unary_op (code, arg, 0);
if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
{
@@ -4474,7 +4249,8 @@ unary_complex_lvalue (code, arg)
return error_mark_node;
}
- type = build_ptrmem_type (DECL_FIELD_CONTEXT (t), TREE_TYPE (t));
+ type = build_ptrmem_type (context_for_name_lookup (t),
+ TREE_TYPE (t));
t = make_ptrmem_cst (type, TREE_OPERAND (arg, 1));
return t;
}
@@ -4514,10 +4290,9 @@ unary_complex_lvalue (code, arg)
C++: we do not allow `current_class_ptr' to be addressable. */
bool
-cxx_mark_addressable (exp)
- tree exp;
+cxx_mark_addressable (tree exp)
{
- register tree x = exp;
+ tree x = exp;
while (1)
switch (TREE_CODE (x))
@@ -4534,10 +4309,10 @@ cxx_mark_addressable (exp)
if (x == current_class_ptr)
{
error ("cannot take the address of `this', which is an rvalue expression");
- TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later */
+ TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later. */
return true;
}
- /* FALLTHRU */
+ /* Fall through. */
case VAR_DECL:
/* Caller should not be trying to mark initialized
@@ -4546,7 +4321,7 @@ cxx_mark_addressable (exp)
|| DECL_IN_AGGR_P (x) == 0
|| TREE_STATIC (x)
|| DECL_EXTERNAL (x), 314);
- /* FALLTHRU */
+ /* Fall through. */
case CONST_DECL:
case RESULT_DECL:
@@ -4580,114 +4355,128 @@ cxx_mark_addressable (exp)
/* Build and return a conditional expression IFEXP ? OP1 : OP2. */
tree
-build_x_conditional_expr (ifexp, op1, op2)
- tree ifexp, op1, op2;
+build_x_conditional_expr (tree ifexp, tree op1, tree op2)
{
- if (processing_template_decl)
- return build_min_nt (COND_EXPR, ifexp, op1, op2);
+ tree orig_ifexp = ifexp;
+ tree orig_op1 = op1;
+ tree orig_op2 = op2;
+ tree expr;
- return build_conditional_expr (ifexp, op1, op2);
+ if (processing_template_decl)
+ {
+ /* The standard says that the expression is type-dependent if
+ IFEXP is type-dependent, even though the eventual type of the
+ expression doesn't dependent on IFEXP. */
+ if (type_dependent_expression_p (ifexp)
+ /* As a GNU extension, the middle operand may be omitted. */
+ || (op1 && type_dependent_expression_p (op1))
+ || type_dependent_expression_p (op2))
+ return build_min_nt (COND_EXPR, ifexp, op1, op2);
+ ifexp = build_non_dependent_expr (ifexp);
+ if (op1)
+ op1 = build_non_dependent_expr (op1);
+ op2 = build_non_dependent_expr (op2);
+ }
+
+ expr = build_conditional_expr (ifexp, op1, op2);
+ if (processing_template_decl && expr != error_mark_node)
+ return build_min_non_dep (COND_EXPR, expr,
+ orig_ifexp, orig_op1, orig_op2);
+ return expr;
}
-/* Handle overloading of the ',' operator when needed. Otherwise,
- this function just builds an expression list. */
+/* Given a list of expressions, return a compound expression
+ that performs them all and returns the value of the last of them. */
+
+tree build_x_compound_expr_from_list (tree list, const char *msg)
+{
+ tree expr = TREE_VALUE (list);
+
+ if (TREE_CHAIN (list))
+ {
+ if (msg)
+ pedwarn ("%s expression list treated as compound expression", msg);
+
+ for (list = TREE_CHAIN (list); list; list = TREE_CHAIN (list))
+ expr = build_x_compound_expr (expr, TREE_VALUE (list));
+ }
+
+ return expr;
+}
+
+/* Handle overloading of the ',' operator when needed. */
tree
-build_x_compound_expr (list)
- tree list;
+build_x_compound_expr (tree op1, tree op2)
{
- tree rest = TREE_CHAIN (list);
tree result;
+ tree orig_op1 = op1;
+ tree orig_op2 = op2;
if (processing_template_decl)
- return build_min_nt (COMPOUND_EXPR, list, NULL_TREE);
+ {
+ if (type_dependent_expression_p (op1)
+ || type_dependent_expression_p (op2))
+ return build_min_nt (COMPOUND_EXPR, op1, op2);
+ op1 = build_non_dependent_expr (op1);
+ op2 = build_non_dependent_expr (op2);
+ }
- if (rest == NULL_TREE)
- return build_compound_expr (list);
+ result = build_new_op (COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2, NULL_TREE,
+ /*overloaded_p=*/NULL);
+ if (!result)
+ result = build_compound_expr (op1, op2);
- result = build_opfncall (COMPOUND_EXPR, LOOKUP_NORMAL,
- TREE_VALUE (list), TREE_VALUE (rest), NULL_TREE);
- if (result)
- return build_x_compound_expr (tree_cons (NULL_TREE, result,
- TREE_CHAIN (rest)));
-
- if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
- {
- /* FIXME: This test should be in the implicit cast to void of the LHS. */
- /* the left-hand operand of a comma expression is like an expression
- statement: we should warn if it doesn't have any side-effects,
- unless it was explicitly cast to (void). */
- if ((extra_warnings || warn_unused_value)
- && !(TREE_CODE (TREE_VALUE(list)) == CONVERT_EXPR
- && VOID_TYPE_P (TREE_TYPE (TREE_VALUE(list)))))
- warning("left-hand operand of comma expression has no effect");
- }
-#if 0 /* this requires a gcc backend patch to export warn_if_unused_value */
- else if (warn_unused_value)
- warn_if_unused_value (TREE_VALUE(list));
-#endif
-
- return build_compound_expr
- (tree_cons (NULL_TREE, TREE_VALUE (list),
- build_tree_list (NULL_TREE,
- build_x_compound_expr (rest))));
+ if (processing_template_decl && result != error_mark_node)
+ return build_min_non_dep (COMPOUND_EXPR, result, orig_op1, orig_op2);
+
+ return result;
}
-/* Given a list of expressions, return a compound expression
- that performs them all and returns the value of the last of them. */
+/* Build a compound expression. */
tree
-build_compound_expr (list)
- tree list;
+build_compound_expr (tree lhs, tree rhs)
{
- register tree rest;
- tree first;
-
- TREE_VALUE (list) = decl_constant_value (TREE_VALUE (list));
-
- if (TREE_CHAIN (list) == 0)
+ lhs = decl_constant_value (lhs);
+ lhs = convert_to_void (lhs, "left-hand operand of comma");
+
+ if (lhs == error_mark_node || rhs == error_mark_node)
+ return error_mark_node;
+
+ if (TREE_CODE (rhs) == TARGET_EXPR)
{
- /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
- Strip such NOP_EXPRs, since LIST is used in non-lvalue context. */
- if (TREE_CODE (list) == NOP_EXPR
- && TREE_TYPE (list) == TREE_TYPE (TREE_OPERAND (list, 0)))
- list = TREE_OPERAND (list, 0);
-
- return TREE_VALUE (list);
+ /* If the rhs is a TARGET_EXPR, then build the compound
+ expression inside the target_expr's initializer. This
+ helps the compiler to eliminate unnecessary temporaries. */
+ tree init = TREE_OPERAND (rhs, 1);
+
+ init = build (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
+ TREE_OPERAND (rhs, 1) = init;
+
+ return rhs;
}
-
- first = TREE_VALUE (list);
- first = convert_to_void (first, "left-hand operand of comma");
- if (first == error_mark_node)
- return error_mark_node;
- rest = build_compound_expr (TREE_CHAIN (list));
- if (rest == error_mark_node)
- return error_mark_node;
-
- /* When pedantic, a compound expression cannot be a constant expression. */
- if (! TREE_SIDE_EFFECTS (first) && ! pedantic)
- return rest;
-
- return build (COMPOUND_EXPR, TREE_TYPE (rest), first, rest);
+ return build (COMPOUND_EXPR, TREE_TYPE (rhs), lhs, rhs);
}
/* Issue an error message if casting from SRC_TYPE to DEST_TYPE casts
- away constness. */
+ away constness. DESCRIPTION explains what operation is taking
+ place. */
static void
-check_for_casting_away_constness (tree src_type, tree dest_type)
+check_for_casting_away_constness (tree src_type, tree dest_type,
+ const char *description)
{
if (casts_away_constness (src_type, dest_type))
- error ("static_cast from type `%T' to type `%T' casts away constness",
- src_type, dest_type);
+ error ("%s from type `%T' to type `%T' casts away constness",
+ description, src_type, dest_type);
}
/* Return an expression representing static_cast<TYPE>(EXPR). */
tree
-build_static_cast (type, expr)
- tree type, expr;
+build_static_cast (tree type, tree expr)
{
tree intype;
tree result;
@@ -4695,13 +4484,12 @@ build_static_cast (type, expr)
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
- if (TREE_CODE (expr) == OFFSET_REF)
- expr = resolve_offset_ref (expr);
-
if (processing_template_decl)
{
- tree t = build_min (STATIC_CAST_EXPR, type, expr);
- return t;
+ expr = build_min (STATIC_CAST_EXPR, type, expr);
+ /* We don't know if it will or will not have side effects. */
+ TREE_SIDE_EFFECTS (expr) = 1;
+ return expr;
}
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
@@ -4735,7 +4523,7 @@ build_static_cast (type, expr)
if (TREE_CODE (type) == REFERENCE_TYPE
&& CLASS_TYPE_P (TREE_TYPE (type))
&& CLASS_TYPE_P (intype)
- && real_non_cast_lvalue_p (expr)
+ && real_lvalue_p (expr)
&& DERIVED_FROM_P (intype, TREE_TYPE (type))
&& can_convert (build_pointer_type (TYPE_MAIN_VARIANT (intype)),
build_pointer_type (TYPE_MAIN_VARIANT
@@ -4764,7 +4552,17 @@ build_static_cast (type, expr)
t. */
result = perform_direct_initialization_if_possible (type, expr);
if (result)
- return convert_from_reference (result);
+ {
+ result = convert_from_reference (result);
+ /* [expr.static.cast]
+
+ If T is a reference type, the result is an lvalue; otherwise,
+ the result is an rvalue. */
+ if (TREE_CODE (type) != REFERENCE_TYPE
+ && real_lvalue_p (result))
+ result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
+ return result;
+ }
/* [expr.static.cast]
@@ -4792,9 +4590,10 @@ build_static_cast (type, expr)
converted to an enumeration type. */
|| (INTEGRAL_OR_ENUMERATION_TYPE_P (type)
&& INTEGRAL_OR_ENUMERATION_TYPE_P (intype)))
- /* Really, build_c_cast should defer to this function rather
- than the other way around. */
- return build_c_cast (type, expr);
+ /* Really, build_c_cast should defer to this function rather
+ than the other way around. */
+ return build_c_cast (type, expr);
+
if (TYPE_PTR_P (type) && TYPE_PTR_P (intype)
&& CLASS_TYPE_P (TREE_TYPE (type))
&& CLASS_TYPE_P (TREE_TYPE (intype))
@@ -4805,11 +4604,12 @@ build_static_cast (type, expr)
{
tree base;
- check_for_casting_away_constness (intype, type);
- base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
- ba_check, NULL);
+ check_for_casting_away_constness (intype, type, "static_cast");
+ base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype), ba_check,
+ NULL);
return build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false);
}
+
if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
|| (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
{
@@ -4837,15 +4637,18 @@ build_static_cast (type, expr)
}
if (can_convert (t1, t2))
{
- check_for_casting_away_constness (intype, type);
+ check_for_casting_away_constness (intype, type, "static_cast");
if (TYPE_PTRMEM_P (type))
{
+ tree delta;
+
if (TREE_CODE (expr) == PTRMEM_CST)
expr = cplus_expand_constant (expr);
- expr = cp_build_binary_op (PLUS_EXPR,
- cp_convert (ptrdiff_type_node, expr),
- get_delta_difference (c1, c2,
- /*force=*/1));
+ delta = get_delta_difference (c1, c2, /*force=*/1);
+ if (!integer_zerop (delta))
+ expr = cp_build_binary_op (PLUS_EXPR,
+ build_nop (ptrdiff_type_node, expr),
+ delta);
return build_nop (type, expr);
}
else
@@ -4864,7 +4667,7 @@ build_static_cast (type, expr)
&& VOID_TYPE_P (TREE_TYPE (intype))
&& TYPE_PTROB_P (type))
{
- check_for_casting_away_constness (intype, type);
+ check_for_casting_away_constness (intype, type, "static_cast");
return build_nop (type, expr);
}
@@ -4873,20 +4676,21 @@ build_static_cast (type, expr)
}
tree
-build_reinterpret_cast (type, expr)
- tree type, expr;
+build_reinterpret_cast (tree type, tree expr)
{
tree intype;
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
- if (TREE_CODE (expr) == OFFSET_REF)
- expr = resolve_offset_ref (expr);
-
if (processing_template_decl)
{
tree t = build_min (REINTERPRET_CAST_EXPR, type, expr);
+
+ if (!TREE_SIDE_EFFECTS (t)
+ && type_dependent_expression_p (expr))
+ /* There might turn out to be side effects inside expr. */
+ TREE_SIDE_EFFECTS (t) = 1;
return t;
}
@@ -4939,10 +4743,7 @@ build_reinterpret_cast (type, expr)
else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
|| (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype)))
{
- if (! comp_ptr_ttypes_reinterpret (TREE_TYPE (type), TREE_TYPE (intype)))
- pedwarn ("reinterpret_cast from `%T' to `%T' casts away const (or volatile)",
- intype, type);
-
+ check_for_casting_away_constness (intype, type, "reinterpret_cast");
expr = decl_constant_value (expr);
return fold (build1 (NOP_EXPR, type, expr));
}
@@ -4964,24 +4765,25 @@ build_reinterpret_cast (type, expr)
}
tree
-build_const_cast (type, expr)
- tree type, expr;
+build_const_cast (tree type, tree expr)
{
tree intype;
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
- if (TREE_CODE (expr) == OFFSET_REF)
- expr = resolve_offset_ref (expr);
-
if (processing_template_decl)
{
tree t = build_min (CONST_CAST_EXPR, type, expr);
+
+ if (!TREE_SIDE_EFFECTS (t)
+ && type_dependent_expression_p (expr))
+ /* There might turn out to be side effects inside expr. */
+ TREE_SIDE_EFFECTS (t) = 1;
return t;
}
- if (!POINTER_TYPE_P (type))
+ if (!POINTER_TYPE_P (type) && !TYPE_PTRMEM_P (type))
error ("invalid use of const_cast with type `%T', which is not a pointer, reference, nor a pointer-to-data-member type", type);
else if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
{
@@ -5019,8 +4821,9 @@ build_const_cast (type, expr)
return convert_from_reference (expr);
}
}
- else if (TREE_CODE (type) == POINTER_TYPE
- && TREE_CODE (intype) == POINTER_TYPE
+ else if (((TREE_CODE (type) == POINTER_TYPE
+ && TREE_CODE (intype) == POINTER_TYPE)
+ || (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)))
&& comp_ptr_ttypes_const (TREE_TYPE (type), TREE_TYPE (intype)))
return cp_convert (type, expr);
@@ -5034,10 +4837,9 @@ build_const_cast (type, expr)
when doing the cast. */
tree
-build_c_cast (type, expr)
- tree type, expr;
+build_c_cast (tree type, tree expr)
{
- register tree value = expr;
+ tree value = expr;
tree otype;
if (type == error_mark_node || expr == error_mark_node)
@@ -5047,6 +4849,8 @@ build_c_cast (type, expr)
{
tree t = build_min (CAST_EXPR, type,
tree_cons (NULL_TREE, value, NULL_TREE));
+ /* We don't know if it will or will not have side effects. */
+ TREE_SIDE_EFFECTS (t) = 1;
return t;
}
@@ -5057,9 +4861,6 @@ build_c_cast (type, expr)
&& TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0)))
value = TREE_OPERAND (value, 0);
- if (TREE_CODE (value) == OFFSET_REF)
- value = resolve_offset_ref (value);
-
if (TREE_CODE (type) == ARRAY_TYPE)
{
/* Allow casting from T1* to T2[] because Cfront allows it.
@@ -5117,7 +4918,7 @@ build_c_cast (type, expr)
&& bound_pmf_p (value)))
|| TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
- value = default_conversion (value);
+ value = decay_conversion (value);
}
else if (TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE)
/* However, even for class types, we still need to strip away
@@ -5139,11 +4940,11 @@ build_c_cast (type, expr)
otype, type);
if (TREE_CODE (type) == INTEGER_TYPE
- && TREE_CODE (otype) == POINTER_TYPE
+ && TYPE_PTR_P (otype)
&& TYPE_PRECISION (type) != TYPE_PRECISION (otype))
warning ("cast from pointer to integer of different size");
- if (TREE_CODE (type) == POINTER_TYPE
+ if (TYPE_PTR_P (type)
&& TREE_CODE (otype) == INTEGER_TYPE
&& TYPE_PRECISION (type) != TYPE_PRECISION (otype)
/* Don't warn about converting any constant. */
@@ -5201,16 +5002,13 @@ build_c_cast (type, expr)
C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed. */
tree
-build_modify_expr (lhs, modifycode, rhs)
- tree lhs;
- enum tree_code modifycode;
- tree rhs;
+build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
{
- register tree result;
+ tree result;
tree newrhs = rhs;
tree lhstype = TREE_TYPE (lhs);
tree olhstype = lhstype;
- tree olhs = lhs;
+ tree olhs = NULL_TREE;
/* Avoid duplicate error messages from operands that had errors. */
if (lhs == error_mark_node || rhs == error_mark_node)
@@ -5219,7 +5017,7 @@ build_modify_expr (lhs, modifycode, rhs)
/* Handle control structure constructs used as "lvalues". */
switch (TREE_CODE (lhs))
{
- /* Handle --foo = 5; as these are valid constructs in C++ */
+ /* Handle --foo = 5; as these are valid constructs in C++. */
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
@@ -5279,15 +5077,11 @@ build_modify_expr (lhs, modifycode, rhs)
return cond;
/* Make sure the code to compute the rhs comes out
before the split. */
- return build (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
+ if (preeval)
+ cond = build (COMPOUND_EXPR, TREE_TYPE (lhs), preeval, cond);
+ return cond;
}
- case OFFSET_REF:
- lhs = resolve_offset_ref (lhs);
- if (lhs == error_mark_node)
- return error_mark_node;
- olhstype = lhstype = TREE_TYPE (lhs);
-
default:
break;
}
@@ -5304,7 +5098,7 @@ build_modify_expr (lhs, modifycode, rhs)
return result;
}
else if (! IS_AGGR_TYPE (lhstype))
- /* Do the default thing */;
+ /* Do the default thing. */;
else
{
result = build_special_member_call (lhs, complete_ctor_identifier,
@@ -5331,11 +5125,12 @@ build_modify_expr (lhs, modifycode, rhs)
{
/* `operator=' is not an inheritable operator. */
if (! IS_AGGR_TYPE (lhstype))
- /* Do the default thing */;
+ /* Do the default thing. */;
else
{
- result = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL,
- lhs, rhs, make_node (NOP_EXPR));
+ result = build_new_op (MODIFY_EXPR, LOOKUP_NORMAL,
+ lhs, rhs, make_node (NOP_EXPR),
+ /*overloaded_p=*/NULL);
if (result == NULL_TREE)
return error_mark_node;
return result;
@@ -5391,7 +5186,7 @@ build_modify_expr (lhs, modifycode, rhs)
|| TREE_CODE (TREE_TYPE (newrhs)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (newrhs)) == METHOD_TYPE
|| TREE_CODE (TREE_TYPE (newrhs)) == OFFSET_TYPE)
- newrhs = default_conversion (newrhs);
+ newrhs = decay_conversion (newrhs);
/* ISO C++ 5.4/1: The result is an lvalue if T is a reference
type, otherwise the result is an rvalue. */
@@ -5426,7 +5221,7 @@ build_modify_expr (lhs, modifycode, rhs)
|| TREE_CODE (TREE_TYPE (lhs)) == METHOD_TYPE
/* If it's an aggregate and any field is const, then it is
effectively const. */
- || (IS_AGGR_TYPE_CODE (TREE_CODE (lhstype))
+ || (CLASS_TYPE_P (lhstype)
&& C_TYPE_FIELDS_READONLY (lhstype))))
readonly_error (lhs, "assignment", 0);
@@ -5446,6 +5241,15 @@ build_modify_expr (lhs, modifycode, rhs)
if (lhstype != TREE_TYPE (lhs))
{
+ /* Avoid warnings converting integral types back into enums for
+ enum bit fields. */
+ if (TREE_CODE (lhstype) == INTEGER_TYPE
+ && TREE_CODE (olhstype) == ENUMERAL_TYPE)
+ {
+ if (TREE_SIDE_EFFECTS (lhs))
+ lhs = stabilize_reference (lhs);
+ olhs = lhs;
+ }
lhs = copy_node (lhs);
TREE_TYPE (lhs) = lhstype;
}
@@ -5518,10 +5322,7 @@ build_modify_expr (lhs, modifycode, rhs)
if (olhstype == TREE_TYPE (result))
return result;
- /* Avoid warnings converting integral types back into enums
- for enum bit fields. */
- if (TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE
- && TREE_CODE (olhstype) == ENUMERAL_TYPE)
+ if (olhs)
{
result = build (COMPOUND_EXPR, olhstype, result, olhs);
TREE_NO_UNUSED_WARNING (result) = 1;
@@ -5532,10 +5333,7 @@ build_modify_expr (lhs, modifycode, rhs)
}
tree
-build_x_modify_expr (lhs, modifycode, rhs)
- tree lhs;
- enum tree_code modifycode;
- tree rhs;
+build_x_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
{
if (processing_template_decl)
return build_min_nt (MODOP_EXPR, lhs,
@@ -5543,8 +5341,9 @@ build_x_modify_expr (lhs, modifycode, rhs)
if (modifycode != NOP_EXPR)
{
- tree rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs,
- make_node (modifycode));
+ tree rval = build_new_op (MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs,
+ make_node (modifycode),
+ /*overloaded_p=*/NULL);
if (rval)
return rval;
}
@@ -5553,8 +5352,9 @@ build_x_modify_expr (lhs, modifycode, rhs)
/* Get difference in deltas for different pointer to member function
- types. Return integer_zero_node, if FROM cannot be converted to a
- TO type. If FORCE is true, then allow reverse conversions as well.
+ types. Returns an integer constant of type PTRDIFF_TYPE_NODE. If
+ the conversion is invalid, the constant is zero. If FORCE is true,
+ then allow reverse conversions as well.
Note that the naming of FROM and TO is kind of backwards; the return
value is what we add to a TO in order to get a FROM. They are named
@@ -5562,11 +5362,8 @@ build_x_modify_expr (lhs, modifycode, rhs)
a pointer to member of FROM to a pointer to member of TO. */
static tree
-get_delta_difference (from, to, force)
- tree from, to;
- int force;
+get_delta_difference (tree from, tree to, int force)
{
- tree delta = integer_zero_node;
tree binfo;
tree virt_binfo;
base_kind kind;
@@ -5575,7 +5372,7 @@ get_delta_difference (from, to, force)
if (kind == bk_inaccessible || kind == bk_ambig)
{
error (" in pointer to member function conversion");
- return delta;
+ goto error;
}
if (!binfo)
{
@@ -5583,55 +5380,45 @@ get_delta_difference (from, to, force)
{
error_not_base_type (from, to);
error (" in pointer to member conversion");
- return delta;
+ goto error;
}
binfo = lookup_base (from, to, ba_check, &kind);
- if (binfo == 0)
- return delta;
+ if (!binfo)
+ goto error;
virt_binfo = binfo_from_vbase (binfo);
-
if (virt_binfo)
{
/* This is a reinterpret cast, we choose to do nothing. */
- warning ("pointer to member cast via virtual base `%T' of `%T'",
- BINFO_TYPE (virt_binfo),
- BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)));
- return delta;
+ warning ("pointer to member cast via virtual base `%T'",
+ BINFO_TYPE (virt_binfo));
+ goto error;
}
- delta = BINFO_OFFSET (binfo);
- delta = cp_convert (ptrdiff_type_node, delta);
- delta = cp_build_binary_op (MINUS_EXPR,
- integer_zero_node,
- delta);
-
- return delta;
+ return fold (convert_to_integer (ptrdiff_type_node,
+ size_diffop (size_zero_node,
+ BINFO_OFFSET (binfo))));
}
virt_binfo = binfo_from_vbase (binfo);
- if (virt_binfo)
- {
- /* This is a reinterpret cast, we choose to do nothing. */
- if (force)
- warning ("pointer to member cast via virtual base `%T' of `%T'",
- BINFO_TYPE (virt_binfo),
- BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)));
- else
- error ("pointer to member conversion via virtual base `%T' of `%T'",
- BINFO_TYPE (virt_binfo),
- BINFO_TYPE (BINFO_INHERITANCE_CHAIN (virt_binfo)));
- return delta;
- }
- delta = BINFO_OFFSET (binfo);
+ if (!virt_binfo)
+ return fold (convert_to_integer (ptrdiff_type_node, BINFO_OFFSET (binfo)));
+
+ /* This is a reinterpret cast, we choose to do nothing. */
+ if (force)
+ warning ("pointer to member cast via virtual base `%T'",
+ BINFO_TYPE (virt_binfo));
+ else
+ error ("pointer to member conversion via virtual base `%T'",
+ BINFO_TYPE (virt_binfo));
- return cp_convert (ptrdiff_type_node, delta);
+ error:
+ return fold (convert_to_integer(ptrdiff_type_node, integer_zero_node));
}
/* Return a constructor for the pointer-to-member-function TYPE using
the other components as specified. */
tree
-build_ptrmemfunc1 (type, delta, pfn)
- tree type, delta, pfn;
+build_ptrmemfunc1 (tree type, tree delta, tree pfn)
{
tree u = NULL_TREE;
tree delta_field;
@@ -5647,7 +5434,7 @@ build_ptrmemfunc1 (type, delta, pfn)
/* Finish creating the initializer. */
u = tree_cons (pfn_field, pfn,
build_tree_list (delta_field, delta));
- u = build (CONSTRUCTOR, type, NULL_TREE, u);
+ u = build_constructor (type, u);
TREE_CONSTANT (u) = TREE_CONSTANT (pfn) && TREE_CONSTANT (delta);
TREE_STATIC (u) = (TREE_CONSTANT (u)
&& (initializer_constant_valid_p (pfn, TREE_TYPE (pfn))
@@ -5669,9 +5456,7 @@ build_ptrmemfunc1 (type, delta, pfn)
Return error_mark_node, if something goes wrong. */
tree
-build_ptrmemfunc (type, pfn, force)
- tree type, pfn;
- int force;
+build_ptrmemfunc (tree type, tree pfn, int force)
{
tree fn;
tree pfn_type;
@@ -5724,7 +5509,7 @@ build_ptrmemfunc (type, pfn, force)
}
/* Just adjust the DELTA field. */
- delta = cp_convert (ptrdiff_type_node, delta);
+ my_friendly_assert (TREE_TYPE (delta) == ptrdiff_type_node, 20030727);
if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_delta)
n = cp_build_binary_op (LSHIFT_EXPR, n, integer_one_node);
delta = cp_build_binary_op (PLUS_EXPR, delta, n);
@@ -5756,10 +5541,7 @@ build_ptrmemfunc (type, pfn, force)
integer_type_node. */
void
-expand_ptrmemfunc_cst (cst, delta, pfn)
- tree cst;
- tree *delta;
- tree *pfn;
+expand_ptrmemfunc_cst (tree cst, tree *delta, tree *pfn)
{
tree type = TREE_TYPE (cst);
tree fn = PTRMEM_CST_MEMBER (cst);
@@ -5822,8 +5604,7 @@ expand_ptrmemfunc_cst (cst, delta, pfn)
given by T. */
tree
-pfn_from_ptrmemfunc (t)
- tree t;
+pfn_from_ptrmemfunc (tree t)
{
if (TREE_CODE (t) == PTRMEM_CST)
{
@@ -5843,15 +5624,10 @@ pfn_from_ptrmemfunc (t)
marked EXPR. */
tree
-dubious_conversion_warnings (type, expr, errtype, fndecl, parmnum)
- tree type;
- tree expr;
- const char *errtype;
- tree fndecl;
- int parmnum;
+dubious_conversion_warnings (tree type, tree expr,
+ const char *errtype, tree fndecl, int parmnum)
{
- if (TREE_CODE (type) == REFERENCE_TYPE)
- type = TREE_TYPE (type);
+ type = non_reference (type);
/* Issue warnings about peculiar, but valid, uses of NULL. */
if (ARITHMETIC_TYPE_P (type) && expr == null_node)
@@ -5903,21 +5679,11 @@ dubious_conversion_warnings (type, expr, errtype, fndecl, parmnum)
FNDECL. */
static tree
-convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
- tree type, rhs;
- const char *errtype;
- tree fndecl;
- int parmnum;
+convert_for_assignment (tree type, tree rhs,
+ const char *errtype, tree fndecl, int parmnum)
{
- register enum tree_code codel = TREE_CODE (type);
- register tree rhstype;
- register enum tree_code coder;
-
- if (codel == OFFSET_TYPE)
- abort ();
-
- if (TREE_CODE (rhs) == OFFSET_REF)
- rhs = resolve_offset_ref (rhs);
+ tree rhstype;
+ enum tree_code coder;
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
if (TREE_CODE (rhs) == NON_LVALUE_EXPR)
@@ -5926,13 +5692,16 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
rhstype = TREE_TYPE (rhs);
coder = TREE_CODE (rhstype);
+ if (TREE_CODE (type) == VECTOR_TYPE && coder == VECTOR_TYPE
+ && ((*targetm.vector_opaque_p) (type)
+ || (*targetm.vector_opaque_p) (rhstype)))
+ return convert (type, rhs);
+
if (rhs == error_mark_node || rhstype == error_mark_node)
return error_mark_node;
if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)
return error_mark_node;
- rhs = dubious_conversion_warnings (type, rhs, errtype, fndecl, parmnum);
-
/* The RHS of an assignment cannot have void type. */
if (coder == VOID_TYPE)
{
@@ -6007,16 +5776,12 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
If flags doesn't include LOOKUP_COMPLAIN, don't complain about anything. */
tree
-convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
- tree exp, type, rhs;
- int flags;
- const char *errtype;
- tree fndecl;
- int parmnum;
+convert_for_initialization (tree exp, tree type, tree rhs, int flags,
+ const char *errtype, tree fndecl, int parmnum)
{
- register enum tree_code codel = TREE_CODE (type);
- register tree rhstype;
- register enum tree_code coder;
+ enum tree_code codel = TREE_CODE (type);
+ tree rhstype;
+ enum tree_code coder;
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
Strip such NOP_EXPRs, since RHS is used in non-lvalue context. */
@@ -6029,13 +5794,6 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
|| (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node))
return error_mark_node;
- if (TREE_CODE (rhs) == OFFSET_REF)
- {
- rhs = resolve_offset_ref (rhs);
- if (rhs == error_mark_node)
- return error_mark_node;
- }
-
if (TREE_CODE (TREE_TYPE (rhs)) == REFERENCE_TYPE)
rhs = convert_from_reference (rhs);
@@ -6047,7 +5805,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
&& (TREE_CODE (type) != REFERENCE_TYPE
|| TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE))
|| TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE)
- rhs = default_conversion (rhs);
+ rhs = decay_conversion (rhs);
rhstype = TREE_TYPE (rhs);
coder = TREE_CODE (rhstype);
@@ -6082,8 +5840,7 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
if (exp == error_mark_node)
return error_mark_node;
- if (TREE_CODE (rhstype) == REFERENCE_TYPE)
- rhstype = TREE_TYPE (rhstype);
+ rhstype = non_reference (rhstype);
type = complete_type (type);
@@ -6103,17 +5860,14 @@ convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum)
up operands that are expected to be in memory. */
void
-c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
- tree string, outputs, inputs, clobbers;
- int vol;
- const char *filename;
- int line;
+c_expand_asm_operands (tree string, tree outputs, tree inputs, tree clobbers,
+ int vol, location_t locus)
{
int noutputs = list_length (outputs);
- register int i;
+ int i;
/* o[I] is the place that output number I should be written. */
- register tree *o = (tree *) alloca (noutputs * sizeof (tree));
- register tree tail;
+ tree *o = alloca (noutputs * sizeof (tree));
+ tree tail;
/* Record the contents of OUTPUTS before it is modified. */
for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
@@ -6122,7 +5876,7 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
/* Generate the ASM_OPERANDS insn;
store into the TREE_VALUEs of OUTPUTS some trees for
where the values were actually stored. */
- expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line);
+ expand_asm_operands (string, outputs, inputs, clobbers, vol, locus);
/* Copy all the intermediate outputs into the specified outputs. */
for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
@@ -6144,8 +5898,7 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
tree type = TREE_TYPE (o[i]);
if (type != error_mark_node
&& (CP_TYPE_CONST_P (type)
- || (IS_AGGR_TYPE_CODE (TREE_CODE (type))
- && C_TYPE_FIELDS_READONLY (type))))
+ || (CLASS_TYPE_P (type) && C_TYPE_FIELDS_READONLY (type))))
readonly_error (o[i], "modification by `asm'", 1);
}
}
@@ -6155,11 +5908,10 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
}
/* If RETVAL is the address of, or a reference to, a local variable or
- temporary give an appropraite warning. */
+ temporary give an appropriate warning. */
static void
-maybe_warn_about_returning_address_of_local (retval)
- tree retval;
+maybe_warn_about_returning_address_of_local (tree retval)
{
tree valtype = TREE_TYPE (DECL_RESULT (current_function_decl));
tree whats_returned = retval;
@@ -6185,8 +5937,6 @@ maybe_warn_about_returning_address_of_local (retval)
if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
|| TREE_CODE (whats_returned) == TARGET_EXPR)
{
- /* Get the target. */
- whats_returned = TREE_OPERAND (whats_returned, 0);
warning ("returning reference to temporary");
return;
}
@@ -6221,8 +5971,7 @@ maybe_warn_about_returning_address_of_local (retval)
the DECL_RESULT for the function. */
tree
-check_return_expr (retval)
- tree retval;
+check_return_expr (tree retval)
{
tree result;
/* The type actually returned by the function, after any
@@ -6255,6 +6004,12 @@ check_return_expr (retval)
return NULL_TREE;
}
+ if (processing_template_decl)
+ {
+ current_function_returns_value = 1;
+ return retval;
+ }
+
/* When no explicit return-value is given in a function with a named
return value, the named return value is used. */
result = DECL_RESULT (current_function_decl);
@@ -6268,7 +6023,8 @@ check_return_expr (retval)
that's supposed to return a value. */
if (!retval && fn_returns_value_p)
{
- pedwarn ("return-statement with no value, in function declared with a non-void return type");
+ pedwarn ("return-statement with no value, in function returning '%T'",
+ valtype);
/* Clear this, so finish_function won't say that we reach the
end of a non-void function (which we don't, we gave a
return!). */
@@ -6284,7 +6040,8 @@ check_return_expr (retval)
its side-effects. */
finish_expr_stmt (retval);
else
- pedwarn ("return-statement with a value, in function declared with a void return type");
+ pedwarn ("return-statement with a value, in function "
+ "returning 'void'");
current_function_returns_null = 1;
@@ -6330,8 +6087,9 @@ check_return_expr (retval)
returned expression uses the chosen variable somehow. And people expect
this restriction, anyway. (jason 2000-11-19)
- See finish_function, genrtl_start_function, and declare_return_variable
- for other pieces of this optimization. */
+ See finish_function, cxx_expand_function_start, and
+ cp_copy_res_decl_for_inlining for other pieces of this
+ optimization. */
if (fn_returns_value_p && flag_elide_constructors)
{
@@ -6404,11 +6162,9 @@ check_return_expr (retval)
const-qualified. */
static int
-comp_ptr_ttypes_real (to, from, constp)
- tree to, from;
- int constp;
+comp_ptr_ttypes_real (tree to, tree from, int constp)
{
- int to_more_cv_qualified = 0;
+ bool to_more_cv_qualified = false;
for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
{
@@ -6416,9 +6172,9 @@ comp_ptr_ttypes_real (to, from, constp)
return 0;
if (TREE_CODE (from) == OFFSET_TYPE
- && same_type_p (TYPE_OFFSET_BASETYPE (from),
- TYPE_OFFSET_BASETYPE (to)))
- continue;
+ && !same_type_p (TYPE_OFFSET_BASETYPE (from),
+ TYPE_OFFSET_BASETYPE (to)))
+ return 0;
/* Const and volatile mean something different for function types,
so the usual checks are not appropriate. */
@@ -6431,28 +6187,25 @@ comp_ptr_ttypes_real (to, from, constp)
{
if (constp == 0)
return 0;
- else
- ++to_more_cv_qualified;
+ to_more_cv_qualified = true;
}
if (constp > 0)
constp &= TYPE_READONLY (to);
}
- if (TREE_CODE (to) != POINTER_TYPE)
- return
- same_type_ignoring_top_level_qualifiers_p (to, from)
- && (constp >= 0 || to_more_cv_qualified);
+ if (TREE_CODE (to) != POINTER_TYPE && !TYPE_PTRMEM_P (to))
+ return ((constp >= 0 || to_more_cv_qualified)
+ && same_type_ignoring_top_level_qualifiers_p (to, from));
}
}
-/* When comparing, say, char ** to char const **, this function takes the
- 'char *' and 'char const *'. Do not pass non-pointer types to this
- function. */
+/* When comparing, say, char ** to char const **, this function takes
+ the 'char *' and 'char const *'. Do not pass non-pointer/reference
+ types to this function. */
int
-comp_ptr_ttypes (to, from)
- tree to, from;
+comp_ptr_ttypes (tree to, tree from)
{
return comp_ptr_ttypes_real (to, from, 1);
}
@@ -6461,8 +6214,7 @@ comp_ptr_ttypes (to, from)
type or inheritance-related types, regardless of cv-quals. */
int
-ptr_reasonably_similar (to, from)
- tree to, from;
+ptr_reasonably_similar (tree to, tree from)
{
for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
{
@@ -6477,7 +6229,7 @@ ptr_reasonably_similar (to, from)
if (TREE_CODE (from) == OFFSET_TYPE
&& comptypes (TYPE_OFFSET_BASETYPE (to),
TYPE_OFFSET_BASETYPE (from),
- COMPARE_BASE | COMPARE_RELAXED))
+ COMPARE_BASE | COMPARE_DERIVED))
continue;
if (TREE_CODE (to) == INTEGER_TYPE
@@ -6490,15 +6242,14 @@ ptr_reasonably_similar (to, from)
if (TREE_CODE (to) != POINTER_TYPE)
return comptypes
(TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from),
- COMPARE_BASE | COMPARE_RELAXED);
+ COMPARE_BASE | COMPARE_DERIVED);
}
}
/* Like comp_ptr_ttypes, for const_cast. */
static int
-comp_ptr_ttypes_const (to, from)
- tree to, from;
+comp_ptr_ttypes_const (tree to, tree from)
{
for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
{
@@ -6515,47 +6266,11 @@ comp_ptr_ttypes_const (to, from)
}
}
-/* Like comp_ptr_ttypes, for reinterpret_cast. */
-
-static int
-comp_ptr_ttypes_reinterpret (to, from)
- tree to, from;
-{
- int constp = 1;
-
- for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
- {
- if (TREE_CODE (from) == OFFSET_TYPE)
- from = TREE_TYPE (from);
- if (TREE_CODE (to) == OFFSET_TYPE)
- to = TREE_TYPE (to);
-
- /* Const and volatile mean something different for function types,
- so the usual checks are not appropriate. */
- if (TREE_CODE (from) != FUNCTION_TYPE && TREE_CODE (from) != METHOD_TYPE
- && TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
- {
- if (!at_least_as_qualified_p (to, from))
- return 0;
-
- if (! constp
- && !at_least_as_qualified_p (from, to))
- return 0;
- constp &= TYPE_READONLY (to);
- }
-
- if (TREE_CODE (from) != POINTER_TYPE
- || TREE_CODE (to) != POINTER_TYPE)
- return 1;
- }
-}
-
/* Returns the type qualifiers for this type, including the qualifiers on the
elements for an array type. */
int
-cp_type_quals (type)
- tree type;
+cp_type_quals (tree type)
{
type = strip_array_types (type);
if (type == error_mark_node)
@@ -6563,11 +6278,10 @@ cp_type_quals (type)
return TYPE_QUALS (type);
}
-/* Returns nonzero if the TYPE contains a mutable member */
+/* Returns nonzero if the TYPE contains a mutable member. */
-int
-cp_has_mutable_p (type)
- tree type;
+bool
+cp_has_mutable_p (tree type)
{
type = strip_array_types (type);
@@ -6579,9 +6293,7 @@ cp_has_mutable_p (type)
if and only if there is no implicit conversion from T1 to T2. */
static void
-casts_away_constness_r (t1, t2)
- tree *t1;
- tree *t2;
+casts_away_constness_r (tree *t1, tree *t2)
{
int quals1;
int quals2;
@@ -6593,9 +6305,9 @@ casts_away_constness_r (t1, t2)
pointer to member level is ignored when determining if a const
cv-qualifier has been cast away. */
if (TYPE_PTRMEM_P (*t1))
- *t1 = build_pointer_type (TREE_TYPE (TREE_TYPE (*t1)));
+ *t1 = build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (*t1));
if (TYPE_PTRMEM_P (*t2))
- *t2 = build_pointer_type (TREE_TYPE (TREE_TYPE (*t2)));
+ *t2 = build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (*t2));
/* [expr.const.cast]
@@ -6639,10 +6351,8 @@ casts_away_constness_r (t1, t2)
/* Returns nonzero if casting from TYPE1 to TYPE2 casts away
constness. */
-static int
-casts_away_constness (t1, t2)
- tree t1;
- tree t2;
+static bool
+casts_away_constness (tree t1, tree t2)
{
if (TREE_CODE (t2) == REFERENCE_TYPE)
{
@@ -6652,8 +6362,7 @@ casts_away_constness (t1, t2)
using a reference cast casts away constness if a cast from an
rvalue of type "pointer to T1" to the type "pointer to T2"
casts away constness. */
- t1 = (TREE_CODE (t1) == REFERENCE_TYPE
- ? TREE_TYPE (t1) : t1);
+ t1 = (TREE_CODE (t1) == REFERENCE_TYPE ? TREE_TYPE (t1) : t1);
return casts_away_constness (build_pointer_type (t1),
build_pointer_type (TREE_TYPE (t2)));
}
@@ -6667,39 +6376,32 @@ casts_away_constness (t1, t2)
"pointer to T1" to the type "pointer to T2" casts away
constness. */
return casts_away_constness
- (build_pointer_type (TREE_TYPE (TREE_TYPE (t1))),
- build_pointer_type (TREE_TYPE (TREE_TYPE (t2))));
+ (build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t1)),
+ build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (t2)));
/* Casting away constness is only something that makes sense for
pointer or reference types. */
if (TREE_CODE (t1) != POINTER_TYPE
|| TREE_CODE (t2) != POINTER_TYPE)
- return 0;
+ return false;
/* Top-level qualifiers don't matter. */
t1 = TYPE_MAIN_VARIANT (t1);
t2 = TYPE_MAIN_VARIANT (t2);
casts_away_constness_r (&t1, &t2);
if (!can_convert (t2, t1))
- return 1;
+ return true;
- return 0;
+ return false;
}
-/* Returns TYPE with its cv qualifiers removed
- TYPE is T cv* .. *cv where T is not a pointer type,
- returns T * .. *. (If T is an array type, then the cv qualifiers
- above are those of the array members.) */
+/* If T is a REFERENCE_TYPE return the type to which T refers.
+ Otherwise, return T itself. */
-static tree
-strip_all_pointer_quals (type)
- tree type;
+tree
+non_reference (tree t)
{
- if (TREE_CODE (type) == POINTER_TYPE)
- return build_pointer_type (strip_all_pointer_quals (TREE_TYPE (type)));
- else if (TREE_CODE (type) == OFFSET_TYPE)
- return build_offset_type (TYPE_OFFSET_BASETYPE (type),
- strip_all_pointer_quals (TREE_TYPE (type)));
- else
- return TYPE_MAIN_VARIANT (type);
+ if (TREE_CODE (t) == REFERENCE_TYPE)
+ t = TREE_TYPE (t);
+ return t;
}
diff --git a/contrib/gcc/cp/typeck2.c b/contrib/gcc/cp/typeck2.c
index b063f42a9f98..300e8e64255b 100644
--- a/contrib/gcc/cp/typeck2.c
+++ b/contrib/gcc/cp/typeck2.c
@@ -1,23 +1,23 @@
/* Report error messages, build initializers, and perform
some front-end optimizations for C++ compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -33,6 +33,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "cp-tree.h"
#include "flags.h"
@@ -40,14 +42,13 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "diagnostic.h"
-static tree process_init_constructor PARAMS ((tree, tree, tree *));
+static tree process_init_constructor (tree, tree, tree *);
/* Print an error message stemming from an attempt to use
BASETYPE as a base class for TYPE. */
tree
-error_not_base_type (basetype, type)
- tree basetype, type;
+error_not_base_type (tree basetype, tree type)
{
if (TREE_CODE (basetype) == FUNCTION_DECL)
basetype = DECL_CONTEXT (basetype);
@@ -56,8 +57,7 @@ error_not_base_type (basetype, type)
}
tree
-binfo_or_else (base, type)
- tree base, type;
+binfo_or_else (tree base, tree type)
{
tree binfo = lookup_base (type, base, ba_ignore, NULL);
@@ -74,13 +74,10 @@ binfo_or_else (base, type)
example, conversions to references.) */
void
-readonly_error (arg, string, soft)
- tree arg;
- const char *string;
- int soft;
+readonly_error (tree arg, const char* string, int soft)
{
const char *fmt;
- void (*fn) PARAMS ((const char *, ...));
+ void (*fn) (const char *, ...);
if (soft)
fn = pedwarn;
@@ -126,19 +123,11 @@ readonly_error (arg, string, soft)
occurred; zero if all was well. */
int
-abstract_virtuals_error (decl, type)
- tree decl;
- tree type;
+abstract_virtuals_error (tree decl, tree type)
{
tree u;
tree tu;
- if (processing_template_decl)
- /* If we are processing a template, TYPE may be a template
- class where CLASSTYPE_PURE_VIRTUALS always contains
- inline friends. */
- return 0;
-
if (!CLASS_TYPE_P (type) || !CLASSTYPE_PURE_VIRTUALS (type))
return 0;
@@ -147,6 +136,11 @@ abstract_virtuals_error (decl, type)
CLASSTYPE_PURE_VIRTUALS holds the inline friends. */
return 0;
+ if (dependent_type_p (type))
+ /* For a dependent type, we do not yet know which functions are pure
+ virtuals. */
+ return 0;
+
u = CLASSTYPE_PURE_VIRTUALS (type);
if (decl)
{
@@ -193,14 +187,11 @@ abstract_virtuals_error (decl, type)
pedwarn. */
void
-cxx_incomplete_type_diagnostic (value, type, diag_type)
- tree value;
- tree type;
- int diag_type;
+cxx_incomplete_type_diagnostic (tree value, tree type, int diag_type)
{
int decl = 0;
- void (*p_msg) PARAMS ((const char *, ...));
- void (*p_msg_at) PARAMS ((const char *, ...));
+ void (*p_msg) (const char *, ...);
+ void (*p_msg_at) (const char *, ...);
if (diag_type == 1)
{
@@ -279,8 +270,7 @@ retry:
break;
default:
- (*p_msg) ("invalid use of incomplete type");
- break;
+ abort ();
}
}
@@ -288,14 +278,115 @@ retry:
required by ../tree.c. */
#undef cxx_incomplete_type_error
void
-cxx_incomplete_type_error (value, type)
- tree value;
- tree type;
+cxx_incomplete_type_error (tree value, tree type)
{
cxx_incomplete_type_diagnostic (value, type, 0);
}
+/* The recursive part of split_nonconstant_init. DEST is an lvalue
+ expression to which INIT should be assigned. INIT is a CONSTRUCTOR.
+ PCODE is a pointer to the tail of a chain of statements being emitted.
+ The return value is the new tail of that chain after new statements
+ are generated. */
+
+static tree *
+split_nonconstant_init_1 (tree dest, tree init, tree *pcode)
+{
+ tree *pelt, elt, type = TREE_TYPE (dest);
+ tree sub, code, inner_type = NULL;
+ bool array_type_p = false;
+
+ pelt = &CONSTRUCTOR_ELTS (init);
+ switch (TREE_CODE (type))
+ {
+ case ARRAY_TYPE:
+ inner_type = TREE_TYPE (type);
+ array_type_p = true;
+ /* FALLTHRU */
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ while ((elt = *pelt))
+ {
+ tree field_index = TREE_PURPOSE (elt);
+ tree value = TREE_VALUE (elt);
+
+ if (!array_type_p)
+ inner_type = TREE_TYPE (field_index);
+
+ if (TREE_CODE (value) == CONSTRUCTOR)
+ {
+ if (array_type_p)
+ sub = build (ARRAY_REF, inner_type, dest, field_index);
+ else
+ sub = build (COMPONENT_REF, inner_type, dest, field_index);
+
+ pcode = split_nonconstant_init_1 (sub, value, pcode);
+ }
+ else if (!initializer_constant_valid_p (value, inner_type))
+ {
+ *pelt = TREE_CHAIN (elt);
+
+ if (array_type_p)
+ sub = build (ARRAY_REF, inner_type, dest, field_index);
+ else
+ sub = build (COMPONENT_REF, inner_type, dest, field_index);
+
+ code = build (MODIFY_EXPR, inner_type, sub, value);
+ code = build_stmt (EXPR_STMT, code);
+
+ *pcode = code;
+ pcode = &TREE_CHAIN (code);
+ continue;
+ }
+ pelt = &TREE_CHAIN (elt);
+ }
+ break;
+
+ case VECTOR_TYPE:
+ if (!initializer_constant_valid_p (init, type))
+ {
+ CONSTRUCTOR_ELTS (init) = NULL;
+ code = build (MODIFY_EXPR, type, dest, init);
+ code = build_stmt (EXPR_STMT, code);
+ pcode = &TREE_CHAIN (code);
+ }
+ break;
+
+ default:
+ abort ();
+ }
+
+ return pcode;
+}
+
+/* A subroutine of store_init_value. Splits non-constant static
+ initializer INIT into a constant part and generates code to
+ perform the non-constant part of the initialization to DEST.
+ Returns the code for the runtime init. */
+
+static tree
+split_nonconstant_init (tree dest, tree init)
+{
+ tree code;
+
+ if (TREE_CODE (init) == CONSTRUCTOR)
+ {
+ code = build_stmt (COMPOUND_STMT, NULL_TREE);
+ split_nonconstant_init_1 (dest, init, &COMPOUND_BODY (code));
+ code = build1 (STMT_EXPR, void_type_node, code);
+ TREE_SIDE_EFFECTS (code) = 1;
+ DECL_INITIAL (dest) = init;
+ TREE_READONLY (dest) = 0;
+ }
+ else
+ code = build (INIT_EXPR, TREE_TYPE (dest), dest, init);
+
+ return code;
+}
+
/* Perform appropriate conversions on the initial value of a variable,
store it in the declaration DECL,
and print any error messages that are appropriate.
@@ -311,15 +402,13 @@ cxx_incomplete_type_error (value, type)
into a CONSTRUCTOR and use standard initialization techniques.
Perhaps a warning should be generated?
- Returns value of initializer if initialization could not be
- performed for static variable. In that case, caller must do
- the storing. */
+ Returns code to be executed if initialization could not be performed
+ for static variable. In that case, caller must emit the code. */
tree
-store_init_value (decl, init)
- tree decl, init;
+store_init_value (tree decl, tree init)
{
- register tree value, type;
+ tree value, type;
/* If variable's type was invalidly declared, just ignore it. */
@@ -336,22 +425,15 @@ store_init_value (decl, init)
if (TREE_CODE (init) == TREE_LIST)
{
error ("constructor syntax used, but no constructor declared for type `%T'", type);
- init = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (init));
+ init = build_constructor (NULL_TREE, nreverse (init));
}
}
else if (TREE_CODE (init) == TREE_LIST
&& TREE_TYPE (init) != unknown_type_node)
{
if (TREE_CODE (decl) == RESULT_DECL)
- {
- if (TREE_CHAIN (init))
- {
- warning ("comma expression used to initialize return value");
- init = build_compound_expr (init);
- }
- else
- init = TREE_VALUE (init);
- }
+ init = build_x_compound_expr_from_list (init,
+ "return value initializer");
else if (TREE_CODE (init) == TREE_LIST
&& TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
{
@@ -359,17 +441,8 @@ store_init_value (decl, init)
return NULL_TREE;
}
else
- {
- /* We get here with code like `int a (2);' */
-
- if (TREE_CHAIN (init) != NULL_TREE)
- {
- pedwarn ("initializer list being treated as compound expression");
- init = build_compound_expr (init);
- }
- else
- init = TREE_VALUE (init);
- }
+ /* We get here with code like `int a (2);' */
+ init = build_x_compound_expr_from_list (init, "initializer");
}
/* End of special C++ code. */
@@ -385,11 +458,11 @@ store_init_value (decl, init)
constructing never make it into DECL_INITIAL, and passes 'init' to
build_aggr_init without checking DECL_INITIAL. So just return. */
else if (TYPE_NEEDS_CONSTRUCTING (type))
- return value;
+ return build (INIT_EXPR, type, decl, value);
else if (TREE_STATIC (decl)
&& (! TREE_CONSTANT (value)
|| ! initializer_constant_valid_p (value, TREE_TYPE (value))))
- return value;
+ return split_nonconstant_init (decl, value);
/* Store the VALUE in DECL_INITIAL. If we're building a
statement-tree we will actually expand the initialization later
@@ -409,8 +482,7 @@ store_init_value (decl, init)
TYPE is an aggregate and INIT is not a constructor. */
tree
-digest_init (type, init, tail)
- tree type, init, *tail;
+digest_init (tree type, tree init, tree* tail)
{
enum tree_code code = TREE_CODE (type);
tree element = NULL_TREE;
@@ -500,8 +572,7 @@ digest_init (type, init, tail)
if (TYPE_DOMAIN (type) != 0
&& TREE_CONSTANT (TYPE_SIZE (type)))
{
- register int size
- = TREE_INT_CST_LOW (TYPE_SIZE (type));
+ int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
/* In C it is ok to subtract 1 from the length of the string
because it's ok to ignore the terminating null char that is
@@ -520,7 +591,7 @@ digest_init (type, init, tail)
if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE
|| code == ENUMERAL_TYPE || code == REFERENCE_TYPE
|| code == BOOLEAN_TYPE || code == COMPLEX_TYPE
- || TYPE_PTRMEMFUNC_P (type))
+ || TYPE_PTR_TO_MEMBER_P (type))
{
if (raw_constructor)
{
@@ -605,14 +676,13 @@ digest_init (type, init, tail)
constants that the assembler and linker can compute them. */
static tree
-process_init_constructor (type, init, elts)
- tree type, init, *elts;
+process_init_constructor (tree type, tree init, tree* elts)
{
- register tree tail;
+ tree tail;
/* List of the elements of the result constructor,
in reverse order. */
- register tree members = NULL;
- register tree next1;
+ tree members = NULL;
+ tree next1;
tree result;
int allconstant = 1;
int allsimple = 1;
@@ -636,8 +706,8 @@ process_init_constructor (type, init, elts)
if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
{
- register long len;
- register int i;
+ long len;
+ int i;
if (TREE_CODE (type) == ARRAY_TYPE)
{
@@ -647,7 +717,7 @@ process_init_constructor (type, init, elts)
- TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain))
+ 1);
else
- len = -1; /* Take as many as there are */
+ len = -1; /* Take as many as there are. */
}
else
{
@@ -704,7 +774,7 @@ process_init_constructor (type, init, elts)
if (IS_AGGR_TYPE (TREE_TYPE (type)))
next1 = build_functional_cast (TREE_TYPE (type), NULL_TREE);
else
- next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
+ next1 = build_constructor (NULL_TREE, NULL_TREE);
next1 = digest_init (TREE_TYPE (type), next1, 0);
}
else if (! zero_init_p (TREE_TYPE (type)))
@@ -727,7 +797,7 @@ process_init_constructor (type, init, elts)
}
else if (TREE_CODE (type) == RECORD_TYPE)
{
- register tree field;
+ tree field;
if (tail)
{
@@ -797,8 +867,7 @@ process_init_constructor (type, init, elts)
NULL_TREE);
else
{
- next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE,
- NULL_TREE);
+ next1 = build_constructor (NULL_TREE, NULL_TREE);
if (init)
TREE_HAS_CONSTRUCTOR (next1)
= TREE_HAS_CONSTRUCTOR (init);
@@ -849,7 +918,7 @@ process_init_constructor (type, init, elts)
/* If the initializer was empty, use default zero initialization. */
&& tail)
{
- register tree field = TYPE_FIELDS (type);
+ tree field = TYPE_FIELDS (type);
/* Find the first named field. ANSI decided in September 1990
that only named fields count here. */
@@ -926,7 +995,7 @@ process_init_constructor (type, init, elts)
if (erroneous)
return error_mark_node;
- result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (members));
+ result = build_constructor (type, nreverse (members));
if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
complete_array_type (type, result, /*do_default=*/0);
if (init)
@@ -965,10 +1034,7 @@ process_init_constructor (type, init, elts)
binfo for the specific base subobject we want to convert to. */
tree
-build_scoped_ref (datum, basetype, binfo_p)
- tree datum;
- tree basetype;
- tree *binfo_p;
+build_scoped_ref (tree datum, tree basetype, tree* binfo_p)
{
tree binfo;
@@ -999,51 +1065,49 @@ build_scoped_ref (datum, basetype, binfo_p)
delegation is detected. */
tree
-build_x_arrow (datum)
- tree datum;
+build_x_arrow (tree expr)
{
+ tree orig_expr = expr;
tree types_memoized = NULL_TREE;
- register tree rval = datum;
- tree type = TREE_TYPE (rval);
+ tree type = TREE_TYPE (expr);
tree last_rval = NULL_TREE;
if (type == error_mark_node)
return error_mark_node;
if (processing_template_decl)
- return build_min_nt (ARROW_EXPR, rval);
-
- if (TREE_CODE (rval) == OFFSET_REF)
{
- rval = resolve_offset_ref (datum);
- type = TREE_TYPE (rval);
+ if (type_dependent_expression_p (expr))
+ return build_min_nt (ARROW_EXPR, expr);
+ expr = build_non_dependent_expr (expr);
}
if (TREE_CODE (type) == REFERENCE_TYPE)
{
- rval = convert_from_reference (rval);
- type = TREE_TYPE (rval);
+ expr = convert_from_reference (expr);
+ type = TREE_TYPE (expr);
}
if (IS_AGGR_TYPE (type))
{
- while ((rval = build_opfncall (COMPONENT_REF, LOOKUP_NORMAL, rval,
- NULL_TREE, NULL_TREE)))
+ while ((expr = build_new_op (COMPONENT_REF, LOOKUP_NORMAL, expr,
+ NULL_TREE, NULL_TREE,
+ /*overloaded_p=*/NULL)))
{
- if (rval == error_mark_node)
+ if (expr == error_mark_node)
return error_mark_node;
- if (value_member (TREE_TYPE (rval), types_memoized))
+ if (value_member (TREE_TYPE (expr), types_memoized))
{
error ("circular pointer delegation detected");
return error_mark_node;
}
else
{
- types_memoized = tree_cons (NULL_TREE, TREE_TYPE (rval),
+ types_memoized = tree_cons (NULL_TREE, TREE_TYPE (expr),
types_memoized);
}
- last_rval = rval;
+ last_rval = expr;
}
if (last_rval == NULL_TREE)
@@ -1056,10 +1120,20 @@ build_x_arrow (datum)
last_rval = convert_from_reference (last_rval);
}
else
- last_rval = default_conversion (rval);
+ last_rval = decay_conversion (expr);
if (TREE_CODE (TREE_TYPE (last_rval)) == POINTER_TYPE)
- return build_indirect_ref (last_rval, NULL);
+ {
+ if (processing_template_decl)
+ {
+ expr = build_min_non_dep (ARROW_EXPR, last_rval, orig_expr);
+ /* It will be dereferenced. */
+ TREE_TYPE (expr) = TREE_TYPE (TREE_TYPE (last_rval));
+ return expr;
+ }
+
+ return build_indirect_ref (last_rval, NULL);
+ }
if (types_memoized)
error ("result of `operator->()' yields non-pointer result");
@@ -1068,73 +1142,31 @@ build_x_arrow (datum)
return error_mark_node;
}
-/* Make an expression to refer to the COMPONENT field of
- structure or union value DATUM. COMPONENT is an arbitrary
- expression. DATUM has not already been checked out to be of
- aggregate type.
-
- For C++, COMPONENT may be a TREE_LIST. This happens when we must
- return an object of member type to a method of the current class,
- but there is not yet enough typing information to know which one.
- As a special case, if there is only one method by that name,
- it is returned. Otherwise we return an expression which other
- routines will have to know how to deal with later. */
+/* Return an expression for "DATUM .* COMPONENT". DATUM has not
+ already been checked out to be of aggregate type. */
tree
-build_m_component_ref (datum, component)
- tree datum, component;
+build_m_component_ref (tree datum, tree component)
{
- tree type;
+ tree ptrmem_type;
tree objtype;
- tree field_type;
- int type_quals;
+ tree type;
tree binfo;
- if (processing_template_decl)
- return build_min_nt (DOTSTAR_EXPR, datum, component);
-
datum = decay_conversion (datum);
if (datum == error_mark_node || component == error_mark_node)
return error_mark_node;
- objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
-
- if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component)))
- {
- type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (component)));
- field_type = type;
- }
- else if (TYPE_PTRMEM_P (TREE_TYPE (component)))
- {
- type = TREE_TYPE (TREE_TYPE (component));
- field_type = TREE_TYPE (type);
-
- /* Compute the type of the field, as described in [expr.ref]. */
- type_quals = TYPE_UNQUALIFIED;
- if (TREE_CODE (field_type) == REFERENCE_TYPE)
- /* The standard says that the type of the result should be the
- type referred to by the reference. But for now, at least,
- we do the conversion from reference type later. */
- ;
- else
- {
- type_quals = (cp_type_quals (field_type)
- | cp_type_quals (TREE_TYPE (datum)));
-
- /* There's no such thing as a mutable pointer-to-member, so
- things are not as complex as they are for references to
- non-static data members. */
- field_type = cp_build_qualified_type (field_type, type_quals);
- }
- }
- else
+ ptrmem_type = TREE_TYPE (component);
+ if (!TYPE_PTR_TO_MEMBER_P (ptrmem_type))
{
error ("`%E' cannot be used as a member pointer, since it is of type `%T'",
- component, TREE_TYPE (component));
+ component, ptrmem_type);
return error_mark_node;
}
-
+
+ objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
if (! IS_AGGR_TYPE (objtype))
{
error ("cannot apply member pointer `%E' to `%E', which is of non-aggregate type `%T'",
@@ -1142,29 +1174,43 @@ build_m_component_ref (datum, component)
return error_mark_node;
}
- binfo = lookup_base (objtype, TYPE_METHOD_BASETYPE (type),
+ type = TYPE_PTRMEM_POINTED_TO_TYPE (ptrmem_type);
+ binfo = lookup_base (objtype, TYPE_PTRMEM_CLASS_TYPE (ptrmem_type),
ba_check, NULL);
if (!binfo)
{
error ("member type `%T::' incompatible with object type `%T'",
- TYPE_METHOD_BASETYPE (type), objtype);
+ type, objtype);
return error_mark_node;
}
else if (binfo == error_mark_node)
return error_mark_node;
- component = build (OFFSET_REF, field_type, datum, component);
- if (TREE_CODE (type) == OFFSET_TYPE)
- component = resolve_offset_ref (component);
- return component;
+ if (TYPE_PTRMEM_P (ptrmem_type))
+ {
+ /* Compute the type of the field, as described in [expr.ref].
+ There's no such thing as a mutable pointer-to-member, so
+ things are not as complex as they are for references to
+ non-static data members. */
+ type = cp_build_qualified_type (type,
+ (cp_type_quals (type)
+ | cp_type_quals (TREE_TYPE (datum))));
+ /* Build an expression for "object + offset" where offset is the
+ value stored in the pointer-to-data-member. */
+ datum = build (PLUS_EXPR, build_pointer_type (type),
+ build_base_path (PLUS_EXPR, build_address (datum),
+ binfo, 1),
+ build_nop (ptrdiff_type_node, component));
+ return build_indirect_ref (datum, 0);
+ }
+ else
+ return build (OFFSET_REF, type, datum, component);
}
/* Return a tree node for the expression TYPENAME '(' PARMS ')'. */
tree
-build_functional_cast (exp, parms)
- tree exp;
- tree parms;
+build_functional_cast (tree exp, tree parms)
{
/* This is either a call to a constructor,
or a C cast in C++'s `functional' notation. */
@@ -1173,41 +1219,26 @@ build_functional_cast (exp, parms)
if (exp == error_mark_node || parms == error_mark_node)
return error_mark_node;
- if (TREE_CODE (exp) == IDENTIFIER_NODE)
- {
- if (IDENTIFIER_HAS_TYPE_VALUE (exp))
- /* Either an enum or an aggregate type. */
- type = IDENTIFIER_TYPE_VALUE (exp);
- else
- {
- type = lookup_name (exp, 1);
- if (!type || TREE_CODE (type) != TYPE_DECL)
- {
- error ("`%T' fails to be a typedef or built-in type", exp);
- return error_mark_node;
- }
- type = TREE_TYPE (type);
- }
- }
- else if (TREE_CODE (exp) == TYPE_DECL)
+ if (TREE_CODE (exp) == TYPE_DECL)
type = TREE_TYPE (exp);
else
type = exp;
if (processing_template_decl)
- return build_min (CAST_EXPR, type, parms);
+ {
+ tree t = build_min (CAST_EXPR, type, parms);
+ /* We don't know if it will or will not have side effects. */
+ TREE_SIDE_EFFECTS (t) = 1;
+ return t;
+ }
if (! IS_AGGR_TYPE (type))
{
- /* this must build a C cast */
+ /* This must build a C cast. */
if (parms == NULL_TREE)
parms = integer_zero_node;
else
- {
- if (TREE_CHAIN (parms) != NULL_TREE)
- pedwarn ("initializer list being treated as compound expression");
- parms = build_compound_expr (parms);
- }
+ parms = build_x_compound_expr_from_list (parms, "functional cast");
return build_c_cast (type, parms);
}
@@ -1232,7 +1263,7 @@ build_functional_cast (exp, parms)
if (parms == NULL_TREE && !TYPE_NEEDS_CONSTRUCTING (type)
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
{
- exp = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
+ exp = build_constructor (type, NULL_TREE);
return get_target_expr (exp);
}
@@ -1246,32 +1277,17 @@ build_functional_cast (exp, parms)
}
-/* Complain about defining new types in inappropriate places. We give an
- exception for C-style casts, to accommodate GNU C stylings. */
-
-void
-check_for_new_type (string, inptree)
- const char *string;
- flagged_type_tree inptree;
-{
- if (inptree.new_type_flag
- && (pedantic || strcmp (string, "cast") != 0))
- pedwarn ("ISO C++ forbids defining types within %s", string);
-}
-
/* Add new exception specifier SPEC, to the LIST we currently have.
If it's already in LIST then do nothing.
Moan if it's bad and we're allowed to. COMPLAIN < 0 means we
know what we're doing. */
tree
-add_exception_specifier (list, spec, complain)
- tree list, spec;
- int complain;
+add_exception_specifier (tree list, tree spec, int complain)
{
- int ok;
+ bool ok;
tree core = spec;
- int is_ptr;
+ bool is_ptr;
int diag_type = -1; /* none */
if (spec == error_mark_node)
@@ -1286,16 +1302,16 @@ add_exception_specifier (list, spec, complain)
if (is_ptr || TREE_CODE (core) == REFERENCE_TYPE)
core = TREE_TYPE (core);
if (complain < 0)
- ok = 1;
+ ok = true;
else if (VOID_TYPE_P (core))
ok = is_ptr;
else if (TREE_CODE (core) == TEMPLATE_TYPE_PARM)
- ok = 1;
+ ok = true;
else if (processing_template_decl)
- ok = 1;
+ ok = true;
else
{
- ok = 1;
+ ok = true;
/* 15.4/1 says that types in an exception specifier must be complete,
but it seems more reasonable to only require this on definitions
and calls. So just give a pedwarn at this point; we will give an
@@ -1327,8 +1343,7 @@ add_exception_specifier (list, spec, complain)
their union. */
tree
-merge_exception_specifiers (list, add)
- tree list, add;
+merge_exception_specifiers (tree list, tree add)
{
if (!list || !add)
return NULL_TREE;
@@ -1366,8 +1381,7 @@ merge_exception_specifiers (list, add)
function is defined or called. See also add_exception_specifier. */
void
-require_complete_eh_spec_types (fntype, decl)
- tree fntype, decl;
+require_complete_eh_spec_types (tree fntype, tree decl)
{
tree raises;
/* Don't complain about calls to op new. */
diff --git a/contrib/gcc/cplus-dem.c b/contrib/gcc/cplus-dem.c
index 199f767736db..f3c4464f184a 100644
--- a/contrib/gcc/cplus-dem.c
+++ b/contrib/gcc/cplus-dem.c
@@ -1,6 +1,6 @@
/* Demangler for GNU C++
Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
@@ -1073,7 +1073,7 @@ ada_demangle (mangled, option)
/* This function performs most of what cplus_demangle use to do, but
to be able to demangle a name with a B, K or n code, we need to
have a longer term memory of what types have been seen. The original
- now intializes and cleans up the squangle code info, while internal
+ now initializes and cleans up the squangle code info, while internal
calls go directly to this routine to avoid resetting that info. */
static char *
@@ -1438,6 +1438,7 @@ demangle_signature (work, mangled, declp)
{
string_append (&s, SCOPE_STRING (work));
string_prepends (declp, &s);
+ string_delete (&s);
}
oldmangled = NULL;
expect_func = 1;
@@ -1517,7 +1518,6 @@ demangle_signature (work, mangled, declp)
{
/* Read the return type. */
string return_type;
- string_init (&return_type);
(*mangled)++;
success = do_type (work, mangled, &return_type);
@@ -1797,31 +1797,34 @@ demangle_integral_value (work, mangled, s)
success = 0;
- /* Negative numbers are indicated with a leading `m'. */
- if (**mangled == 'm')
- {
- string_appendn (s, "-", 1);
- (*mangled)++;
- }
- else if (mangled[0][0] == '_' && mangled[0][1] == 'm')
- {
- /* Since consume_count_with_underscores does not handle the
- `m'-prefix we must do it here, using consume_count and
- adjusting underscores: we have to consume the underscore
- matching the prepended one. */
- multidigit_without_leading_underscore = 1;
- string_appendn (s, "-", 1);
- (*mangled) += 2;
- }
- else if (**mangled == '_')
- {
- /* Do not consume a following underscore;
- multidigit_without_leading_underscore will consume what should be
- consumed. */
- leave_following_underscore = 1;
+ if (**mangled == '_')
+ {
+ if (mangled[0][1] == 'm')
+ {
+ /* Since consume_count_with_underscores does not handle the
+ `m'-prefix we must do it here, using consume_count and
+ adjusting underscores: we have to consume the underscore
+ matching the prepended one. */
+ multidigit_without_leading_underscore = 1;
+ string_appendn (s, "-", 1);
+ (*mangled) += 2;
+ }
+ else
+ {
+ /* Do not consume a following underscore;
+ consume_count_with_underscores will consume what
+ should be consumed. */
+ leave_following_underscore = 1;
+ }
}
else
{
+ /* Negative numbers are indicated with a leading `m'. */
+ if (**mangled == 'm')
+ {
+ string_appendn (s, "-", 1);
+ (*mangled)++;
+ }
/* Since consume_count_with_underscores does not handle
multi-digit numbers that do not start with an underscore,
and this number can be an integer template parameter,
@@ -1862,7 +1865,7 @@ demangle_integral_value (work, mangled, s)
/* All is well. */
success = 1;
}
- }
+ }
return success;
}
@@ -2040,13 +2043,10 @@ demangle_template (work, mangled, tname, trawname, is_type, remember)
const char *start;
int is_java_array = 0;
string temp;
- int bindex = 0;
(*mangled)++;
if (is_type)
{
- if (remember)
- bindex = register_Btype (work);
start = *mangled;
/* get template name */
if (**mangled == 'z')
@@ -2223,7 +2223,10 @@ demangle_template (work, mangled, tname, trawname, is_type, remember)
}
if (is_type && remember)
- remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
+ {
+ const int bindex = register_Btype (work);
+ remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
+ }
/*
if (work -> static_type)
@@ -2315,6 +2318,7 @@ demangle_arm_hp_template (work, mangled, n, declp)
if (HP_DEMANGLING && ((*mangled)[n] == 'X'))
{
char *start_spec_args = NULL;
+ int hold_options;
/* First check for and omit template specialization pseudo-arguments,
such as in "Spec<#1,#1.*>" */
@@ -2327,10 +2331,16 @@ demangle_arm_hp_template (work, mangled, n, declp)
string_init (&arg);
if (work->temp_start == -1) /* non-recursive call */
work->temp_start = declp->p - declp->b;
+
+ /* We want to unconditionally demangle parameter types in
+ template parameters. */
+ hold_options = work->options;
+ work->options |= DMGL_PARAMS;
+
string_append (declp, "<");
while (1)
{
- string_clear (&arg);
+ string_delete (&arg);
switch (**mangled)
{
case 'T':
@@ -2373,21 +2383,29 @@ demangle_arm_hp_template (work, mangled, n, declp)
string_delete (&arg);
if (**mangled == '_')
(*mangled)++;
+ work->options = hold_options;
return;
}
/* ARM template? (Also handles HP cfront extensions) */
else if (arm_pt (work, *mangled, n, &p, &args))
{
+ int hold_options;
string type_str;
string_init (&arg);
string_appendn (declp, *mangled, p - *mangled);
if (work->temp_start == -1) /* non-recursive call */
work->temp_start = declp->p - declp->b;
+
+ /* We want to unconditionally demangle parameter types in
+ template parameters. */
+ hold_options = work->options;
+ work->options |= DMGL_PARAMS;
+
string_append (declp, "<");
/* should do error checking here */
while (args < e) {
- string_clear (&arg);
+ string_delete (&arg);
/* Check for type or literal here */
switch (*args)
@@ -2402,6 +2420,7 @@ demangle_arm_hp_template (work, mangled, n, declp)
goto cfront_template_args_done;
string_append (&arg, "(");
string_appends (&arg, &type_str);
+ string_delete (&type_str);
string_append (&arg, ")");
if (*args != 'L')
goto cfront_template_args_done;
@@ -2426,7 +2445,10 @@ demangle_arm_hp_template (work, mangled, n, declp)
/* Fail if we didn't make any progress: prevent infinite loop. */
if (args == old_args)
- return;
+ {
+ work->options = hold_options;
+ return;
+ }
}
}
string_appends (declp, &arg);
@@ -2437,6 +2459,7 @@ demangle_arm_hp_template (work, mangled, n, declp)
if (args >= e)
--declp->p; /* remove extra comma */
string_append (declp, ">");
+ work->options = hold_options;
}
else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0
&& (*mangled)[9] == 'N'
@@ -3359,6 +3382,7 @@ demangle_qualified (work, mangled, result, isfuncname, append)
}
else
{
+ string_delete (&last_name);
success = do_type (work, mangled, &last_name);
if (!success)
break;
@@ -3501,10 +3525,8 @@ do_type (work, mangled, result)
string decl;
const char *remembered_type;
int type_quals;
- string btype;
type_kind_t tk = tk_none;
- string_init (&btype);
string_init (&decl);
string_init (result);
@@ -3622,6 +3644,7 @@ do_type (work, mangled, result)
string temp;
do_type (work, mangled, &temp);
string_prepends (&decl, &temp);
+ string_delete (&temp);
}
else if (**mangled == 't')
{
@@ -3632,7 +3655,7 @@ do_type (work, mangled, result)
if (success)
{
string_prependn (&decl, temp.b, temp.p - temp.b);
- string_clear (&temp);
+ string_delete (&temp);
}
else
break;
@@ -3812,11 +3835,8 @@ demangle_fund_type (work, mangled, result)
int success = 1;
char buf[10];
unsigned int dec = 0;
- string btype;
type_kind_t tk = tk_integral;
- string_init (&btype);
-
/* First pick off any type qualifiers. There can be more than one. */
while (!done)
@@ -3988,8 +4008,11 @@ demangle_fund_type (work, mangled, result)
}
case 't':
{
+ string btype;
+ string_init (&btype);
success = demangle_template (work, mangled, &btype, 0, 1, 1);
string_appends (result, &btype);
+ string_delete (&btype);
break;
}
default:
@@ -4191,12 +4214,9 @@ do_arg (work, mangled, result)
do not want to add additional types to the back-referenceable
type vector when processing a repeated type. */
if (work->previous_argument)
- string_clear (work->previous_argument);
+ string_delete (work->previous_argument);
else
- {
- work->previous_argument = (string*) xmalloc (sizeof (string));
- string_init (work->previous_argument);
- }
+ work->previous_argument = (string*) xmalloc (sizeof (string));
if (!do_type (work, mangled, work->previous_argument))
return 0;
@@ -4560,7 +4580,10 @@ demangle_nested_args (work, mangled, declp)
/* Restore the previous_argument field. */
if (work->previous_argument)
- string_delete (work->previous_argument);
+ {
+ string_delete (work->previous_argument);
+ free ((char *) work->previous_argument);
+ }
work->previous_argument = saved_previous_argument;
--work->forgetting_types;
work->nrepeats = saved_nrepeats;
diff --git a/contrib/gcc/cppcharset.c b/contrib/gcc/cppcharset.c
new file mode 100644
index 000000000000..a6a65ed7986a
--- /dev/null
+++ b/contrib/gcc/cppcharset.c
@@ -0,0 +1,1411 @@
+/* CPP Library - charsets
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+
+ Broken out of c-lex.c Apr 2003, adding valid C99 UCN ranges.
+
+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 2, 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, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "cpphash.h"
+#include "cppucnid.h"
+
+/* Character set handling for C-family languages.
+
+ Terminological note: In what follows, "charset" or "character set"
+ will be taken to mean both an abstract set of characters and an
+ encoding for that set.
+
+ The C99 standard discusses two character sets: source and execution.
+ The source character set is used for internal processing in translation
+ phases 1 through 4; the execution character set is used thereafter.
+ Both are required by 5.2.1.2p1 to be multibyte encodings, not wide
+ character encodings (see 3.7.2, 3.7.3 for the standardese meanings
+ of these terms). Furthermore, the "basic character set" (listed in
+ 5.2.1p3) is to be encoded in each with values one byte wide, and is
+ to appear in the initial shift state.
+
+ It is not explicitly mentioned, but there is also a "wide execution
+ character set" used to encode wide character constants and wide
+ string literals; this is supposed to be the result of applying the
+ standard library function mbstowcs() to an equivalent narrow string
+ (6.4.5p5). However, the behavior of hexadecimal and octal
+ \-escapes is at odds with this; they are supposed to be translated
+ directly to wchar_t values (6.4.4.4p5,6).
+
+ The source character set is not necessarily the character set used
+ to encode physical source files on disk; translation phase 1 converts
+ from whatever that encoding is to the source character set.
+
+ The presence of universal character names in C99 (6.4.3 et seq.)
+ forces the source character set to be isomorphic to ISO 10646,
+ that is, Unicode. There is no such constraint on the execution
+ character set; note also that the conversion from source to
+ execution character set does not occur for identifiers (5.1.1.2p1#5).
+
+ For convenience of implementation, the source character set's
+ encoding of the basic character set should be identical to the
+ execution character set OF THE HOST SYSTEM's encoding of the basic
+ character set, and it should not be a state-dependent encoding.
+
+ cpplib uses UTF-8 or UTF-EBCDIC for the source character set,
+ depending on whether the host is based on ASCII or EBCDIC (see
+ respectively Unicode section 2.3/ISO10646 Amendment 2, and Unicode
+ Technical Report #16). With limited exceptions, it relies on the
+ system library's iconv() primitive to do charset conversion
+ (specified in SUSv2). */
+
+#if !HAVE_ICONV
+/* Make certain that the uses of iconv(), iconv_open(), iconv_close()
+ below, which are guarded only by if statements with compile-time
+ constant conditions, do not cause link errors. */
+#define iconv_open(x, y) (errno = EINVAL, (iconv_t)-1)
+#define iconv(a,b,c,d,e) (errno = EINVAL, (size_t)-1)
+#define iconv_close(x) (void)0
+#define ICONV_CONST
+#endif
+
+#if HOST_CHARSET == HOST_CHARSET_ASCII
+#define SOURCE_CHARSET "UTF-8"
+#elif HOST_CHARSET == HOST_CHARSET_EBCDIC
+#define SOURCE_CHARSET "UTF-EBCDIC"
+#else
+#error "Unrecognized basic host character set"
+#endif
+
+#ifndef EILSEQ
+#define EILSEQ EINVAL
+#endif
+
+/* This structure is used for a resizable string buffer throughout. */
+/* Don't call it strbuf, as that conflicts with unistd.h on systems
+ such as DYNIX/ptx where unistd.h includes stropts.h. */
+struct _cpp_strbuf
+{
+ uchar *text;
+ size_t asize;
+ size_t len;
+};
+
+/* This is enough to hold any string that fits on a single 80-column
+ line, even if iconv quadruples its size (e.g. conversion from
+ ASCII to UTF-32) rounded up to a power of two. */
+#define OUTBUF_BLOCK_SIZE 256
+
+/* Conversions between UTF-8 and UTF-16/32 are implemented by custom
+ logic. This is because a depressing number of systems lack iconv,
+ or have have iconv libraries that do not do these conversions, so
+ we need a fallback implementation for them. To ensure the fallback
+ doesn't break due to neglect, it is used on all systems.
+
+ UTF-32 encoding is nice and simple: a four-byte binary number,
+ constrained to the range 00000000-7FFFFFFF to avoid questions of
+ signedness. We do have to cope with big- and little-endian
+ variants.
+
+ UTF-16 encoding uses two-byte binary numbers, again in big- and
+ little-endian variants, for all values in the 00000000-0000FFFF
+ range. Values in the 00010000-0010FFFF range are encoded as pairs
+ of two-byte numbers, called "surrogate pairs": given a number S in
+ this range, it is mapped to a pair (H, L) as follows:
+
+ H = (S - 0x10000) / 0x400 + 0xD800
+ L = (S - 0x10000) % 0x400 + 0xDC00
+
+ Two-byte values in the D800...DFFF range are ill-formed except as a
+ component of a surrogate pair. Even if the encoding within a
+ two-byte value is little-endian, the H member of the surrogate pair
+ comes first.
+
+ There is no way to encode values in the 00110000-7FFFFFFF range,
+ which is not currently a problem as there are no assigned code
+ points in that range; however, the author expects that it will
+ eventually become necessary to abandon UTF-16 due to this
+ limitation. Note also that, because of these pairs, UTF-16 does
+ not meet the requirements of the C standard for a wide character
+ encoding (see 3.7.3 and 6.4.4.4p11).
+
+ UTF-8 encoding looks like this:
+
+ value range encoded as
+ 00000000-0000007F 0xxxxxxx
+ 00000080-000007FF 110xxxxx 10xxxxxx
+ 00000800-0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
+ 00010000-001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ 00200000-03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+ 04000000-7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+
+ Values in the 0000D800 ... 0000DFFF range (surrogates) are invalid,
+ which means that three-byte sequences ED xx yy, with A0 <= xx <= BF,
+ never occur. Note also that any value that can be encoded by a
+ given row of the table can also be encoded by all successive rows,
+ but this is not done; only the shortest possible encoding for any
+ given value is valid. For instance, the character 07C0 could be
+ encoded as any of DF 80, E0 9F 80, F0 80 9F 80, F8 80 80 9F 80, or
+ FC 80 80 80 9F 80. Only the first is valid.
+
+ An implementation note: the transformation from UTF-16 to UTF-8, or
+ vice versa, is easiest done by using UTF-32 as an intermediary. */
+
+/* Internal primitives which go from an UTF-8 byte stream to native-endian
+ UTF-32 in a cppchar_t, or vice versa; this avoids an extra marshal/unmarshal
+ operation in several places below. */
+static inline int
+one_utf8_to_cppchar (const uchar **inbufp, size_t *inbytesleftp,
+ cppchar_t *cp)
+{
+ static const uchar masks[6] = { 0x7F, 0x1F, 0x0F, 0x07, 0x02, 0x01 };
+ static const uchar patns[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+ cppchar_t c;
+ const uchar *inbuf = *inbufp;
+ size_t nbytes, i;
+
+ if (*inbytesleftp < 1)
+ return EINVAL;
+
+ c = *inbuf;
+ if (c < 0x80)
+ {
+ *cp = c;
+ *inbytesleftp -= 1;
+ *inbufp += 1;
+ return 0;
+ }
+
+ /* The number of leading 1-bits in the first byte indicates how many
+ bytes follow. */
+ for (nbytes = 2; nbytes < 7; nbytes++)
+ if ((c & ~masks[nbytes-1]) == patns[nbytes-1])
+ goto found;
+ return EILSEQ;
+ found:
+
+ if (*inbytesleftp < nbytes)
+ return EINVAL;
+
+ c = (c & masks[nbytes-1]);
+ inbuf++;
+ for (i = 1; i < nbytes; i++)
+ {
+ cppchar_t n = *inbuf++;
+ if ((n & 0xC0) != 0x80)
+ return EILSEQ;
+ c = ((c << 6) + (n & 0x3F));
+ }
+
+ /* Make sure the shortest possible encoding was used. */
+ if (c <= 0x7F && nbytes > 1) return EILSEQ;
+ if (c <= 0x7FF && nbytes > 2) return EILSEQ;
+ if (c <= 0xFFFF && nbytes > 3) return EILSEQ;
+ if (c <= 0x1FFFFF && nbytes > 4) return EILSEQ;
+ if (c <= 0x3FFFFFF && nbytes > 5) return EILSEQ;
+
+ /* Make sure the character is valid. */
+ if (c > 0x7FFFFFFF || (c >= 0xD800 && c <= 0xDFFF)) return EILSEQ;
+
+ *cp = c;
+ *inbufp = inbuf;
+ *inbytesleftp -= nbytes;
+ return 0;
+}
+
+static inline int
+one_cppchar_to_utf8 (cppchar_t c, uchar **outbufp, size_t *outbytesleftp)
+{
+ static const uchar masks[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+ static const uchar limits[6] = { 0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
+ size_t nbytes;
+ uchar buf[6], *p = &buf[6];
+ uchar *outbuf = *outbufp;
+
+ nbytes = 1;
+ if (c < 0x80)
+ *--p = c;
+ else
+ {
+ do
+ {
+ *--p = ((c & 0x3F) | 0x80);
+ c >>= 6;
+ nbytes++;
+ }
+ while (c >= 0x3F || (c & limits[nbytes-1]));
+ *--p = (c | masks[nbytes-1]);
+ }
+
+ if (*outbytesleftp < nbytes)
+ return E2BIG;
+
+ while (p < &buf[6])
+ *outbuf++ = *p++;
+ *outbytesleftp -= nbytes;
+ *outbufp = outbuf;
+ return 0;
+}
+
+/* The following four functions transform one character between the two
+ encodings named in the function name. All have the signature
+ int (*)(iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp,
+ uchar **outbufp, size_t *outbytesleftp)
+
+ BIGEND must have the value 0 or 1, coerced to (iconv_t); it is
+ interpreted as a boolean indicating whether big-endian or
+ little-endian encoding is to be used for the member of the pair
+ that is not UTF-8.
+
+ INBUFP, INBYTESLEFTP, OUTBUFP, OUTBYTESLEFTP work exactly as they
+ do for iconv.
+
+ The return value is either 0 for success, or an errno value for
+ failure, which may be E2BIG (need more space), EILSEQ (ill-formed
+ input sequence), ir EINVAL (incomplete input sequence). */
+
+static inline int
+one_utf8_to_utf32 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp,
+ uchar **outbufp, size_t *outbytesleftp)
+{
+ uchar *outbuf;
+ cppchar_t s = 0;
+ int rval;
+
+ /* Check for space first, since we know exactly how much we need. */
+ if (*outbytesleftp < 4)
+ return E2BIG;
+
+ rval = one_utf8_to_cppchar (inbufp, inbytesleftp, &s);
+ if (rval)
+ return rval;
+
+ outbuf = *outbufp;
+ outbuf[bigend ? 3 : 0] = (s & 0x000000FF);
+ outbuf[bigend ? 2 : 1] = (s & 0x0000FF00) >> 8;
+ outbuf[bigend ? 1 : 2] = (s & 0x00FF0000) >> 16;
+ outbuf[bigend ? 0 : 3] = (s & 0xFF000000) >> 24;
+
+ *outbufp += 4;
+ *outbytesleftp -= 4;
+ return 0;
+}
+
+static inline int
+one_utf32_to_utf8 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp,
+ uchar **outbufp, size_t *outbytesleftp)
+{
+ cppchar_t s;
+ int rval;
+ const uchar *inbuf;
+
+ if (*inbytesleftp < 4)
+ return EINVAL;
+
+ inbuf = *inbufp;
+
+ s = inbuf[bigend ? 0 : 3] << 24;
+ s += inbuf[bigend ? 1 : 2] << 16;
+ s += inbuf[bigend ? 2 : 1] << 8;
+ s += inbuf[bigend ? 3 : 0];
+
+ if (s >= 0x7FFFFFFF || (s >= 0xD800 && s <= 0xDFFF))
+ return EILSEQ;
+
+ rval = one_cppchar_to_utf8 (s, outbufp, outbytesleftp);
+ if (rval)
+ return rval;
+
+ *inbufp += 4;
+ *inbytesleftp -= 4;
+ return 0;
+}
+
+static inline int
+one_utf8_to_utf16 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp,
+ uchar **outbufp, size_t *outbytesleftp)
+{
+ int rval;
+ cppchar_t s = 0;
+ const uchar *save_inbuf = *inbufp;
+ size_t save_inbytesleft = *inbytesleftp;
+ uchar *outbuf = *outbufp;
+
+ rval = one_utf8_to_cppchar (inbufp, inbytesleftp, &s);
+ if (rval)
+ return rval;
+
+ if (s > 0x0010FFFF)
+ {
+ *inbufp = save_inbuf;
+ *inbytesleftp = save_inbytesleft;
+ return EILSEQ;
+ }
+
+ if (s < 0xFFFF)
+ {
+ if (*outbytesleftp < 2)
+ {
+ *inbufp = save_inbuf;
+ *inbytesleftp = save_inbytesleft;
+ return E2BIG;
+ }
+ outbuf[bigend ? 1 : 0] = (s & 0x00FF);
+ outbuf[bigend ? 0 : 1] = (s & 0xFF00) >> 8;
+
+ *outbufp += 2;
+ *outbytesleftp -= 2;
+ return 0;
+ }
+ else
+ {
+ cppchar_t hi, lo;
+
+ if (*outbytesleftp < 4)
+ {
+ *inbufp = save_inbuf;
+ *inbytesleftp = save_inbytesleft;
+ return E2BIG;
+ }
+
+ hi = (s - 0x10000) / 0x400 + 0xD800;
+ lo = (s - 0x10000) % 0x400 + 0xDC00;
+
+ /* Even if we are little-endian, put the high surrogate first.
+ ??? Matches practice? */
+ outbuf[bigend ? 1 : 0] = (hi & 0x00FF);
+ outbuf[bigend ? 0 : 1] = (hi & 0xFF00) >> 8;
+ outbuf[bigend ? 3 : 2] = (lo & 0x00FF);
+ outbuf[bigend ? 2 : 3] = (lo & 0xFF00) >> 8;
+
+ *outbufp += 4;
+ *outbytesleftp -= 4;
+ return 0;
+ }
+}
+
+static inline int
+one_utf16_to_utf8 (iconv_t bigend, const uchar **inbufp, size_t *inbytesleftp,
+ uchar **outbufp, size_t *outbytesleftp)
+{
+ cppchar_t s;
+ const uchar *inbuf = *inbufp;
+ int rval;
+
+ if (*inbytesleftp < 2)
+ return EINVAL;
+ s = inbuf[bigend ? 0 : 1] << 8;
+ s += inbuf[bigend ? 1 : 0];
+
+ /* Low surrogate without immediately preceding high surrogate is invalid. */
+ if (s >= 0xDC00 && s <= 0xDFFF)
+ return EILSEQ;
+ /* High surrogate must have a following low surrogate. */
+ else if (s >= 0xD800 && s <= 0xDBFF)
+ {
+ cppchar_t hi = s, lo;
+ if (*inbytesleftp < 4)
+ return EINVAL;
+
+ lo = inbuf[bigend ? 2 : 3] << 8;
+ lo += inbuf[bigend ? 3 : 2];
+
+ if (lo < 0xDC00 || lo > 0xDFFF)
+ return EILSEQ;
+
+ s = (hi - 0xD800) * 0x400 + (lo - 0xDC00) + 0x10000;
+ }
+
+ rval = one_cppchar_to_utf8 (s, outbufp, outbytesleftp);
+ if (rval)
+ return rval;
+
+ /* Success - update the input pointers (one_cppchar_to_utf8 has done
+ the output pointers for us). */
+ if (s <= 0xFFFF)
+ {
+ *inbufp += 2;
+ *inbytesleftp -= 2;
+ }
+ else
+ {
+ *inbufp += 4;
+ *inbytesleftp -= 4;
+ }
+ return 0;
+}
+
+/* Helper routine for the next few functions. The 'const' on
+ one_conversion means that we promise not to modify what function is
+ pointed to, which lets the inliner see through it. */
+
+static inline bool
+conversion_loop (int (*const one_conversion)(iconv_t, const uchar **, size_t *,
+ uchar **, size_t *),
+ iconv_t cd, const uchar *from, size_t flen, struct _cpp_strbuf *to)
+{
+ const uchar *inbuf;
+ uchar *outbuf;
+ size_t inbytesleft, outbytesleft;
+ int rval;
+
+ inbuf = from;
+ inbytesleft = flen;
+ outbuf = to->text + to->len;
+ outbytesleft = to->asize - to->len;
+
+ for (;;)
+ {
+ do
+ rval = one_conversion (cd, &inbuf, &inbytesleft,
+ &outbuf, &outbytesleft);
+ while (inbytesleft && !rval);
+
+ if (__builtin_expect (inbytesleft == 0, 1))
+ {
+ to->len = to->asize - outbytesleft;
+ return true;
+ }
+ if (rval != E2BIG)
+ {
+ errno = rval;
+ return false;
+ }
+
+ outbytesleft += OUTBUF_BLOCK_SIZE;
+ to->asize += OUTBUF_BLOCK_SIZE;
+ to->text = xrealloc (to->text, to->asize);
+ outbuf = to->text + to->asize - outbytesleft;
+ }
+}
+
+
+/* These functions convert entire strings between character sets.
+ They all have the signature
+
+ bool (*)(iconv_t cd, const uchar *from, size_t flen, struct _cpp_strbuf *to);
+
+ The input string FROM is converted as specified by the function
+ name plus the iconv descriptor CD (which may be fake), and the
+ result appended to TO. On any error, false is returned, otherwise true. */
+
+/* These four use the custom conversion code above. */
+static bool
+convert_utf8_utf16 (iconv_t cd, const uchar *from, size_t flen,
+ struct _cpp_strbuf *to)
+{
+ return conversion_loop (one_utf8_to_utf16, cd, from, flen, to);
+}
+
+static bool
+convert_utf8_utf32 (iconv_t cd, const uchar *from, size_t flen,
+ struct _cpp_strbuf *to)
+{
+ return conversion_loop (one_utf8_to_utf32, cd, from, flen, to);
+}
+
+static bool
+convert_utf16_utf8 (iconv_t cd, const uchar *from, size_t flen,
+ struct _cpp_strbuf *to)
+{
+ return conversion_loop (one_utf16_to_utf8, cd, from, flen, to);
+}
+
+static bool
+convert_utf32_utf8 (iconv_t cd, const uchar *from, size_t flen,
+ struct _cpp_strbuf *to)
+{
+ return conversion_loop (one_utf32_to_utf8, cd, from, flen, to);
+}
+
+/* Identity conversion, used when we have no alternative. */
+static bool
+convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED,
+ const uchar *from, size_t flen, struct _cpp_strbuf *to)
+{
+ if (to->len + flen > to->asize)
+ {
+ to->asize = to->len + flen;
+ to->text = xrealloc (to->text, to->asize);
+ }
+ memcpy (to->text + to->len, from, flen);
+ to->len += flen;
+ return true;
+}
+
+/* And this one uses the system iconv primitive. It's a little
+ different, since iconv's interface is a little different. */
+#if HAVE_ICONV
+static bool
+convert_using_iconv (iconv_t cd, const uchar *from, size_t flen,
+ struct _cpp_strbuf *to)
+{
+ ICONV_CONST char *inbuf;
+ char *outbuf;
+ size_t inbytesleft, outbytesleft;
+
+ /* Reset conversion descriptor and check that it is valid. */
+ if (iconv (cd, 0, 0, 0, 0) == (size_t)-1)
+ return false;
+
+ inbuf = (ICONV_CONST char *)from;
+ inbytesleft = flen;
+ outbuf = (char *)to->text + to->len;
+ outbytesleft = to->asize - to->len;
+
+ for (;;)
+ {
+ iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
+ if (__builtin_expect (inbytesleft == 0, 1))
+ {
+ to->len = to->asize - outbytesleft;
+ return true;
+ }
+ if (errno != E2BIG)
+ return false;
+
+ outbytesleft += OUTBUF_BLOCK_SIZE;
+ to->asize += OUTBUF_BLOCK_SIZE;
+ to->text = xrealloc (to->text, to->asize);
+ outbuf = (char *)to->text + to->asize - outbytesleft;
+ }
+}
+#else
+#define convert_using_iconv 0 /* prevent undefined symbol error below */
+#endif
+
+/* Arrange for the above custom conversion logic to be used automatically
+ when conversion between a suitable pair of character sets is requested. */
+
+#define APPLY_CONVERSION(CONVERTER, FROM, FLEN, TO) \
+ CONVERTER.func (CONVERTER.cd, FROM, FLEN, TO)
+
+struct conversion
+{
+ const char *pair;
+ convert_f func;
+ iconv_t fake_cd;
+};
+static const struct conversion conversion_tab[] = {
+ { "UTF-8/UTF-32LE", convert_utf8_utf32, (iconv_t)0 },
+ { "UTF-8/UTF-32BE", convert_utf8_utf32, (iconv_t)1 },
+ { "UTF-8/UTF-16LE", convert_utf8_utf16, (iconv_t)0 },
+ { "UTF-8/UTF-16BE", convert_utf8_utf16, (iconv_t)1 },
+ { "UTF-32LE/UTF-8", convert_utf32_utf8, (iconv_t)0 },
+ { "UTF-32BE/UTF-8", convert_utf32_utf8, (iconv_t)1 },
+ { "UTF-16LE/UTF-8", convert_utf16_utf8, (iconv_t)0 },
+ { "UTF-16BE/UTF-8", convert_utf16_utf8, (iconv_t)1 },
+};
+
+/* Subroutine of cpp_init_iconv: initialize and return a
+ cset_converter structure for conversion from FROM to TO. If
+ iconv_open() fails, issue an error and return an identity
+ converter. Silently return an identity converter if FROM and TO
+ are identical. */
+static struct cset_converter
+init_iconv_desc (cpp_reader *pfile, const char *to, const char *from)
+{
+ struct cset_converter ret;
+ char *pair;
+ size_t i;
+
+ if (!strcasecmp (to, from))
+ {
+ ret.func = convert_no_conversion;
+ ret.cd = (iconv_t) -1;
+ return ret;
+ }
+
+ pair = alloca(strlen(to) + strlen(from) + 2);
+
+ strcpy(pair, from);
+ strcat(pair, "/");
+ strcat(pair, to);
+ for (i = 0; i < ARRAY_SIZE (conversion_tab); i++)
+ if (!strcasecmp (pair, conversion_tab[i].pair))
+ {
+ ret.func = conversion_tab[i].func;
+ ret.cd = conversion_tab[i].fake_cd;
+ return ret;
+ }
+
+ /* No custom converter - try iconv. */
+ if (HAVE_ICONV)
+ {
+ ret.func = convert_using_iconv;
+ ret.cd = iconv_open (to, from);
+
+ if (ret.cd == (iconv_t) -1)
+ {
+ if (errno == EINVAL)
+ cpp_error (pfile, CPP_DL_ERROR, /* XXX should be DL_SORRY */
+ "conversion from %s to %s not supported by iconv",
+ from, to);
+ else
+ cpp_errno (pfile, CPP_DL_ERROR, "iconv_open");
+
+ ret.func = convert_no_conversion;
+ }
+ }
+ else
+ {
+ cpp_error (pfile, CPP_DL_ERROR, /* XXX should be DL_SORRY */
+ "no iconv implementation, cannot convert from %s to %s",
+ from, to);
+ ret.func = convert_no_conversion;
+ ret.cd = (iconv_t) -1;
+ }
+ return ret;
+}
+
+/* If charset conversion is requested, initialize iconv(3) descriptors
+ for conversion from the source character set to the execution
+ character sets. If iconv is not present in the C library, and
+ conversion is requested, issue an error. */
+
+void
+cpp_init_iconv (cpp_reader *pfile)
+{
+ const char *ncset = CPP_OPTION (pfile, narrow_charset);
+ const char *wcset = CPP_OPTION (pfile, wide_charset);
+ const char *default_wcset;
+
+ bool be = CPP_OPTION (pfile, bytes_big_endian);
+
+ if (CPP_OPTION (pfile, wchar_precision) >= 32)
+ default_wcset = be ? "UTF-32BE" : "UTF-32LE";
+ else if (CPP_OPTION (pfile, wchar_precision) >= 16)
+ default_wcset = be ? "UTF-16BE" : "UTF-16LE";
+ else
+ /* This effectively means that wide strings are not supported,
+ so don't do any conversion at all. */
+ default_wcset = SOURCE_CHARSET;
+
+ if (!ncset)
+ ncset = SOURCE_CHARSET;
+ if (!wcset)
+ wcset = default_wcset;
+
+ pfile->narrow_cset_desc = init_iconv_desc (pfile, ncset, SOURCE_CHARSET);
+ pfile->wide_cset_desc = init_iconv_desc (pfile, wcset, SOURCE_CHARSET);
+}
+
+void
+_cpp_destroy_iconv (cpp_reader *pfile)
+{
+ if (HAVE_ICONV)
+ {
+ if (pfile->narrow_cset_desc.func == convert_using_iconv)
+ iconv_close (pfile->narrow_cset_desc.cd);
+ if (pfile->wide_cset_desc.func == convert_using_iconv)
+ iconv_close (pfile->wide_cset_desc.cd);
+ }
+}
+
+
+/* Utility routine that computes a mask of the form 0000...111... with
+ WIDTH 1-bits. */
+static inline size_t
+width_to_mask (size_t width)
+{
+ width = MIN (width, BITS_PER_CPPCHAR_T);
+ if (width >= CHAR_BIT * sizeof (size_t))
+ return ~(size_t) 0;
+ else
+ return ((size_t) 1 << width) - 1;
+}
+
+
+
+/* Returns 1 if C is valid in an identifier, 2 if C is valid except at
+ the start of an identifier, and 0 if C is not valid in an
+ identifier. We assume C has already gone through the checks of
+ _cpp_valid_ucn. The algorithm is a simple binary search on the
+ table defined in cppucnid.h. */
+
+static int
+ucn_valid_in_identifier (cpp_reader *pfile, cppchar_t c)
+{
+ int mn, mx, md;
+
+ mn = -1;
+ mx = ARRAY_SIZE (ucnranges);
+ while (mx - mn > 1)
+ {
+ md = (mn + mx) / 2;
+ if (c < ucnranges[md].lo)
+ mx = md;
+ else if (c > ucnranges[md].hi)
+ mn = md;
+ else
+ goto found;
+ }
+ return 0;
+
+ found:
+ /* When -pedantic, we require the character to have been listed by
+ the standard for the current language. Otherwise, we accept the
+ union of the acceptable sets for C++98 and C99. */
+ if (CPP_PEDANTIC (pfile)
+ && ((CPP_OPTION (pfile, c99) && !(ucnranges[md].flags & C99))
+ || (CPP_OPTION (pfile, cplusplus)
+ && !(ucnranges[md].flags & CXX))))
+ return 0;
+
+ /* In C99, UCN digits may not begin identifiers. */
+ if (CPP_OPTION (pfile, c99) && (ucnranges[md].flags & DIG))
+ return 2;
+
+ return 1;
+}
+
+/* [lex.charset]: The character designated by the universal character
+ name \UNNNNNNNN is that character whose character short name in
+ ISO/IEC 10646 is NNNNNNNN; the character designated by the
+ universal character name \uNNNN is that character whose character
+ short name in ISO/IEC 10646 is 0000NNNN. If the hexadecimal value
+ for a universal character name is less than 0x20 or in the range
+ 0x7F-0x9F (inclusive), or if the universal character name
+ designates a character in the basic source character set, then the
+ program is ill-formed.
+
+ *PSTR must be preceded by "\u" or "\U"; it is assumed that the
+ buffer end is delimited by a non-hex digit. Returns zero if UCNs
+ are not part of the relevant standard, or if the string beginning
+ at *PSTR doesn't syntactically match the form 'NNNN' or 'NNNNNNNN'.
+
+ Otherwise the nonzero value of the UCN, whether valid or invalid,
+ is returned. Diagnostics are emitted for invalid values. PSTR
+ is updated to point one beyond the UCN, or to the syntactically
+ invalid character.
+
+ IDENTIFIER_POS is 0 when not in an identifier, 1 for the start of
+ an identifier, or 2 otherwise.
+*/
+
+cppchar_t
+_cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr,
+ const uchar *limit, int identifier_pos)
+{
+ cppchar_t result, c;
+ unsigned int length;
+ const uchar *str = *pstr;
+ const uchar *base = str - 2;
+
+ if (!CPP_OPTION (pfile, cplusplus) && !CPP_OPTION (pfile, c99))
+ cpp_error (pfile, CPP_DL_WARNING,
+ "universal character names are only valid in C++ and C99");
+ else if (CPP_WTRADITIONAL (pfile) && identifier_pos == 0)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "the meaning of '\\%c' is different in traditional C",
+ (int) str[-1]);
+
+ if (str[-1] == 'u')
+ length = 4;
+ else if (str[-1] == 'U')
+ length = 8;
+ else
+ abort();
+
+ result = 0;
+ do
+ {
+ c = *str;
+ if (!ISXDIGIT (c))
+ break;
+ str++;
+ result = (result << 4) + hex_value (c);
+ }
+ while (--length && str < limit);
+
+ *pstr = str;
+ if (length)
+ {
+ /* We'll error when we try it out as the start of an identifier. */
+ cpp_error (pfile, CPP_DL_ERROR,
+ "incomplete universal character name %.*s",
+ (int) (str - base), base);
+ result = 1;
+ }
+ /* The standard permits $, @ and ` to be specified as UCNs. We use
+ hex escapes so that this also works with EBCDIC hosts. */
+ else if ((result < 0xa0
+ && (result != 0x24 && result != 0x40 && result != 0x60))
+ || (result & 0x80000000)
+ || (result >= 0xD800 && result <= 0xDFFF))
+ {
+ cpp_error (pfile, CPP_DL_ERROR,
+ "%.*s is not a valid universal character",
+ (int) (str - base), base);
+ result = 1;
+ }
+ else if (identifier_pos)
+ {
+ int validity = ucn_valid_in_identifier (pfile, result);
+
+ if (validity == 0)
+ cpp_error (pfile, CPP_DL_ERROR,
+ "universal character %.*s is not valid in an identifier",
+ (int) (str - base), base);
+ else if (validity == 2 && identifier_pos == 1)
+ cpp_error (pfile, CPP_DL_ERROR,
+ "universal character %.*s is not valid at the start of an identifier",
+ (int) (str - base), base);
+ }
+
+ if (result == 0)
+ result = 1;
+
+ return result;
+}
+
+/* Convert an UCN, pointed to by FROM, to UTF-8 encoding, then translate
+ it to the execution character set and write the result into TBUF.
+ An advanced pointer is returned. Issues all relevant diagnostics. */
+
+
+static const uchar *
+convert_ucn (cpp_reader *pfile, const uchar *from, const uchar *limit,
+ struct _cpp_strbuf *tbuf, bool wide)
+{
+ cppchar_t ucn;
+ uchar buf[6];
+ uchar *bufp = buf;
+ size_t bytesleft = 6;
+ int rval;
+ struct cset_converter cvt
+ = wide ? pfile->wide_cset_desc : pfile->narrow_cset_desc;
+
+ from++; /* Skip u/U. */
+ ucn = _cpp_valid_ucn (pfile, &from, limit, 0);
+
+ rval = one_cppchar_to_utf8 (ucn, &bufp, &bytesleft);
+ if (rval)
+ {
+ errno = rval;
+ cpp_errno (pfile, CPP_DL_ERROR,
+ "converting UCN to source character set");
+ }
+ else if (!APPLY_CONVERSION (cvt, buf, 6 - bytesleft, tbuf))
+ cpp_errno (pfile, CPP_DL_ERROR,
+ "converting UCN to execution character set");
+
+ return from;
+}
+
+static void
+emit_numeric_escape (cpp_reader *pfile, cppchar_t n,
+ struct _cpp_strbuf *tbuf, bool wide)
+{
+ if (wide)
+ {
+ /* We have to render this into the target byte order, which may not
+ be our byte order. */
+ bool bigend = CPP_OPTION (pfile, bytes_big_endian);
+ size_t width = CPP_OPTION (pfile, wchar_precision);
+ size_t cwidth = CPP_OPTION (pfile, char_precision);
+ size_t cmask = width_to_mask (cwidth);
+ size_t nbwc = width / cwidth;
+ size_t i;
+ size_t off = tbuf->len;
+ cppchar_t c;
+
+ if (tbuf->len + nbwc > tbuf->asize)
+ {
+ tbuf->asize += OUTBUF_BLOCK_SIZE;
+ tbuf->text = xrealloc (tbuf->text, tbuf->asize);
+ }
+
+ for (i = 0; i < nbwc; i++)
+ {
+ c = n & cmask;
+ n >>= cwidth;
+ tbuf->text[off + (bigend ? nbwc - i - 1 : i)] = c;
+ }
+ tbuf->len += nbwc;
+ }
+ else
+ {
+ if (tbuf->len + 1 > tbuf->asize)
+ {
+ tbuf->asize += OUTBUF_BLOCK_SIZE;
+ tbuf->text = xrealloc (tbuf->text, tbuf->asize);
+ }
+ tbuf->text[tbuf->len++] = n;
+ }
+}
+
+/* Convert a hexadecimal escape, pointed to by FROM, to the execution
+ character set and write it into the string buffer TBUF. Returns an
+ advanced pointer, and issues diagnostics as necessary.
+ No character set translation occurs; this routine always produces the
+ execution-set character with numeric value equal to the given hex
+ number. You can, e.g. generate surrogate pairs this way. */
+static const uchar *
+convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit,
+ struct _cpp_strbuf *tbuf, bool wide)
+{
+ cppchar_t c, n = 0, overflow = 0;
+ int digits_found = 0;
+ size_t width = (wide ? CPP_OPTION (pfile, wchar_precision)
+ : CPP_OPTION (pfile, char_precision));
+ size_t mask = width_to_mask (width);
+
+ if (CPP_WTRADITIONAL (pfile))
+ cpp_error (pfile, CPP_DL_WARNING,
+ "the meaning of '\\x' is different in traditional C");
+
+ from++; /* Skip 'x'. */
+ while (from < limit)
+ {
+ c = *from;
+ if (! hex_p (c))
+ break;
+ from++;
+ overflow |= n ^ (n << 4 >> 4);
+ n = (n << 4) + hex_value (c);
+ digits_found = 1;
+ }
+
+ if (!digits_found)
+ {
+ cpp_error (pfile, CPP_DL_ERROR,
+ "\\x used with no following hex digits");
+ return from;
+ }
+
+ if (overflow | (n != (n & mask)))
+ {
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "hex escape sequence out of range");
+ n &= mask;
+ }
+
+ emit_numeric_escape (pfile, n, tbuf, wide);
+
+ return from;
+}
+
+/* Convert an octal escape, pointed to by FROM, to the execution
+ character set and write it into the string buffer TBUF. Returns an
+ advanced pointer, and issues diagnostics as necessary.
+ No character set translation occurs; this routine always produces the
+ execution-set character with numeric value equal to the given octal
+ number. */
+static const uchar *
+convert_oct (cpp_reader *pfile, const uchar *from, const uchar *limit,
+ struct _cpp_strbuf *tbuf, bool wide)
+{
+ size_t count = 0;
+ cppchar_t c, n = 0;
+ size_t width = (wide ? CPP_OPTION (pfile, wchar_precision)
+ : CPP_OPTION (pfile, char_precision));
+ size_t mask = width_to_mask (width);
+ bool overflow = false;
+
+ while (from < limit && count++ < 3)
+ {
+ c = *from;
+ if (c < '0' || c > '7')
+ break;
+ from++;
+ overflow |= n ^ (n << 3 >> 3);
+ n = (n << 3) + c - '0';
+ }
+
+ if (n != (n & mask))
+ {
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "octal escape sequence out of range");
+ n &= mask;
+ }
+
+ emit_numeric_escape (pfile, n, tbuf, wide);
+
+ return from;
+}
+
+/* Convert an escape sequence (pointed to by FROM) to its value on
+ the target, and to the execution character set. Do not scan past
+ LIMIT. Write the converted value into TBUF. Returns an advanced
+ pointer. Handles all relevant diagnostics. */
+static const uchar *
+convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit,
+ struct _cpp_strbuf *tbuf, bool wide)
+{
+ /* Values of \a \b \e \f \n \r \t \v respectively. */
+#if HOST_CHARSET == HOST_CHARSET_ASCII
+ static const uchar charconsts[] = { 7, 8, 27, 12, 10, 13, 9, 11 };
+#elif HOST_CHARSET == HOST_CHARSET_EBCDIC
+ static const uchar charconsts[] = { 47, 22, 39, 12, 21, 13, 5, 11 };
+#else
+#error "unknown host character set"
+#endif
+
+ uchar c;
+ struct cset_converter cvt
+ = wide ? pfile->wide_cset_desc : pfile->narrow_cset_desc;
+
+ c = *from;
+ switch (c)
+ {
+ /* UCNs, hex escapes, and octal escapes are processed separately. */
+ case 'u': case 'U':
+ return convert_ucn (pfile, from, limit, tbuf, wide);
+
+ case 'x':
+ return convert_hex (pfile, from, limit, tbuf, wide);
+ break;
+
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ return convert_oct (pfile, from, limit, tbuf, wide);
+
+ /* Various letter escapes. Get the appropriate host-charset
+ value into C. */
+ case '\\': case '\'': case '"': case '?': break;
+
+ case '(': case '{': case '[': case '%':
+ /* '\(', etc, can be used at the beginning of a line in a long
+ string split onto multiple lines with \-newline, to prevent
+ Emacs or other text editors from getting confused. '\%' can
+ be used to prevent SCCS from mangling printf format strings. */
+ if (CPP_PEDANTIC (pfile))
+ goto unknown;
+ break;
+
+ case 'b': c = charconsts[1]; break;
+ case 'f': c = charconsts[3]; break;
+ case 'n': c = charconsts[4]; break;
+ case 'r': c = charconsts[5]; break;
+ case 't': c = charconsts[6]; break;
+ case 'v': c = charconsts[7]; break;
+
+ case 'a':
+ if (CPP_WTRADITIONAL (pfile))
+ cpp_error (pfile, CPP_DL_WARNING,
+ "the meaning of '\\a' is different in traditional C");
+ c = charconsts[0];
+ break;
+
+ case 'e': case 'E':
+ if (CPP_PEDANTIC (pfile))
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "non-ISO-standard escape sequence, '\\%c'", (int) c);
+ c = charconsts[2];
+ break;
+
+ default:
+ unknown:
+ if (ISGRAPH (c))
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "unknown escape sequence '\\%c'", (int) c);
+ else
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "unknown escape sequence: '\\%03o'", (int) c);
+ }
+
+ /* Now convert what we have to the execution character set. */
+ if (!APPLY_CONVERSION (cvt, &c, 1, tbuf))
+ cpp_errno (pfile, CPP_DL_ERROR,
+ "converting escape sequence to execution character set");
+
+ return from + 1;
+}
+
+/* FROM is an array of cpp_string structures of length COUNT. These
+ are to be converted from the source to the execution character set,
+ escape sequences translated, and finally all are to be
+ concatenated. WIDE indicates whether or not to produce a wide
+ string. The result is written into TO. Returns true for success,
+ false for failure. */
+bool
+cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count,
+ cpp_string *to, bool wide)
+{
+ struct _cpp_strbuf tbuf;
+ const uchar *p, *base, *limit;
+ size_t i;
+ struct cset_converter cvt
+ = wide ? pfile->wide_cset_desc : pfile->narrow_cset_desc;
+
+ tbuf.asize = MAX (OUTBUF_BLOCK_SIZE, from->len);
+ tbuf.text = xmalloc (tbuf.asize);
+ tbuf.len = 0;
+
+ for (i = 0; i < count; i++)
+ {
+ p = from[i].text;
+ if (*p == 'L') p++;
+ p++; /* Skip leading quote. */
+ limit = from[i].text + from[i].len - 1; /* Skip trailing quote. */
+
+ for (;;)
+ {
+ base = p;
+ while (p < limit && *p != '\\')
+ p++;
+ if (p > base)
+ {
+ /* We have a run of normal characters; these can be fed
+ directly to convert_cset. */
+ if (!APPLY_CONVERSION (cvt, base, p - base, &tbuf))
+ goto fail;
+ }
+ if (p == limit)
+ break;
+
+ p = convert_escape (pfile, p + 1, limit, &tbuf, wide);
+ }
+ }
+ /* NUL-terminate the 'to' buffer and translate it to a cpp_string
+ structure. */
+ emit_numeric_escape (pfile, 0, &tbuf, wide);
+ tbuf.text = xrealloc (tbuf.text, tbuf.len);
+ to->text = tbuf.text;
+ to->len = tbuf.len;
+ return true;
+
+ fail:
+ cpp_errno (pfile, CPP_DL_ERROR, "converting to execution character set");
+ free (tbuf.text);
+ return false;
+}
+
+/* Subroutine of do_line and do_linemarker. Convert escape sequences
+ in a string, but do not perform character set conversion. */
+bool
+_cpp_interpret_string_notranslate (cpp_reader *pfile, const cpp_string *in,
+ cpp_string *out)
+{
+ struct cset_converter save_narrow_cset_desc = pfile->narrow_cset_desc;
+ bool retval;
+
+ pfile->narrow_cset_desc.func = convert_no_conversion;
+ pfile->narrow_cset_desc.cd = (iconv_t) -1;
+
+ retval = cpp_interpret_string (pfile, in, 1, out, false);
+
+ pfile->narrow_cset_desc = save_narrow_cset_desc;
+ return retval;
+}
+
+
+/* Subroutine of cpp_interpret_charconst which performs the conversion
+ to a number, for narrow strings. STR is the string structure returned
+ by cpp_interpret_string. PCHARS_SEEN and UNSIGNEDP are as for
+ cpp_interpret_charconst. */
+static cppchar_t
+narrow_str_to_charconst (cpp_reader *pfile, cpp_string str,
+ unsigned int *pchars_seen, int *unsignedp)
+{
+ size_t width = CPP_OPTION (pfile, char_precision);
+ size_t max_chars = CPP_OPTION (pfile, int_precision) / width;
+ size_t mask = width_to_mask (width);
+ size_t i;
+ cppchar_t result, c;
+ bool unsigned_p;
+
+ /* The value of a multi-character character constant, or a
+ single-character character constant whose representation in the
+ execution character set is more than one byte long, is
+ implementation defined. This implementation defines it to be the
+ number formed by interpreting the byte sequence in memory as a
+ big-endian binary number. If overflow occurs, the high bytes are
+ lost, and a warning is issued.
+
+ We don't want to process the NUL terminator handed back by
+ cpp_interpret_string. */
+ result = 0;
+ for (i = 0; i < str.len - 1; i++)
+ {
+ c = str.text[i] & mask;
+ if (width < BITS_PER_CPPCHAR_T)
+ result = (result << width) | c;
+ else
+ result = c;
+ }
+
+ if (i > max_chars)
+ {
+ i = max_chars;
+ cpp_error (pfile, CPP_DL_WARNING,
+ "character constant too long for its type");
+ }
+ else if (i > 1 && CPP_OPTION (pfile, warn_multichar))
+ cpp_error (pfile, CPP_DL_WARNING, "multi-character character constant");
+
+ /* Multichar constants are of type int and therefore signed. */
+ if (i > 1)
+ unsigned_p = 0;
+ else
+ unsigned_p = CPP_OPTION (pfile, unsigned_char);
+
+ /* Truncate the constant to its natural width, and simultaneously
+ sign- or zero-extend to the full width of cppchar_t.
+ For single-character constants, the value is WIDTH bits wide.
+ For multi-character constants, the value is INT_PRECISION bits wide. */
+ if (i > 1)
+ width = CPP_OPTION (pfile, int_precision);
+ if (width < BITS_PER_CPPCHAR_T)
+ {
+ mask = ((cppchar_t) 1 << width) - 1;
+ if (unsigned_p || !(result & (1 << (width - 1))))
+ result &= mask;
+ else
+ result |= ~mask;
+ }
+ *pchars_seen = i;
+ *unsignedp = unsigned_p;
+ return result;
+}
+
+/* Subroutine of cpp_interpret_charconst which performs the conversion
+ to a number, for wide strings. STR is the string structure returned
+ by cpp_interpret_string. PCHARS_SEEN and UNSIGNEDP are as for
+ cpp_interpret_charconst. */
+static cppchar_t
+wide_str_to_charconst (cpp_reader *pfile, cpp_string str,
+ unsigned int *pchars_seen, int *unsignedp)
+{
+ bool bigend = CPP_OPTION (pfile, bytes_big_endian);
+ size_t width = CPP_OPTION (pfile, wchar_precision);
+ size_t cwidth = CPP_OPTION (pfile, char_precision);
+ size_t mask = width_to_mask (width);
+ size_t cmask = width_to_mask (cwidth);
+ size_t nbwc = width / cwidth;
+ size_t off, i;
+ cppchar_t result = 0, c;
+
+ /* This is finicky because the string is in the target's byte order,
+ which may not be our byte order. Only the last character, ignoring
+ the NUL terminator, is relevant. */
+ off = str.len - (nbwc * 2);
+ result = 0;
+ for (i = 0; i < nbwc; i++)
+ {
+ c = bigend ? str.text[off + i] : str.text[off + nbwc - i - 1];
+ result = (result << cwidth) | (c & cmask);
+ }
+
+ /* Wide character constants have type wchar_t, and a single
+ character exactly fills a wchar_t, so a multi-character wide
+ character constant is guaranteed to overflow. */
+ if (off > 0)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "character constant too long for its type");
+
+ /* Truncate the constant to its natural width, and simultaneously
+ sign- or zero-extend to the full width of cppchar_t. */
+ if (width < BITS_PER_CPPCHAR_T)
+ {
+ if (CPP_OPTION (pfile, unsigned_wchar) || !(result & (1 << (width - 1))))
+ result &= mask;
+ else
+ result |= ~mask;
+ }
+
+ *unsignedp = CPP_OPTION (pfile, unsigned_wchar);
+ *pchars_seen = 1;
+ return result;
+}
+
+/* Interpret a (possibly wide) character constant in TOKEN.
+ PCHARS_SEEN points to a variable that is filled in with the number
+ of characters seen, and UNSIGNEDP to a variable that indicates
+ whether the result has signed type. */
+cppchar_t
+cpp_interpret_charconst (cpp_reader *pfile, const cpp_token *token,
+ unsigned int *pchars_seen, int *unsignedp)
+{
+ cpp_string str = { 0, 0 };
+ bool wide = (token->type == CPP_WCHAR);
+ cppchar_t result;
+
+ /* an empty constant will appear as L'' or '' */
+ if (token->val.str.len == (size_t) (2 + wide))
+ {
+ cpp_error (pfile, CPP_DL_ERROR, "empty character constant");
+ return 0;
+ }
+ else if (!cpp_interpret_string (pfile, &token->val.str, 1, &str, wide))
+ return 0;
+
+ if (wide)
+ result = wide_str_to_charconst (pfile, str, pchars_seen, unsignedp);
+ else
+ result = narrow_str_to_charconst (pfile, str, pchars_seen, unsignedp);
+
+ if (str.text != token->val.str.text)
+ free ((void *)str.text);
+
+ return result;
+}
+
+uchar *
+_cpp_convert_input (cpp_reader *pfile, const char *input_charset,
+ uchar *input, size_t size, size_t len, off_t *st_size)
+{
+ struct cset_converter input_cset;
+ struct _cpp_strbuf to;
+
+ input_cset = init_iconv_desc (pfile, SOURCE_CHARSET, input_charset);
+ if (input_cset.func == convert_no_conversion)
+ {
+ to.text = input;
+ to.asize = size;
+ to.len = len;
+ }
+ else
+ {
+ to.asize = MAX (65536, len);
+ to.text = xmalloc (to.asize);
+ to.len = 0;
+
+ if (!APPLY_CONVERSION (input_cset, input, len, &to))
+ cpp_error (pfile, CPP_DL_ERROR,
+ "failure to convert %s to %s",
+ CPP_OPTION (pfile, input_charset), SOURCE_CHARSET);
+
+ free (input);
+ }
+
+ /* Clean up the mess. */
+ if (input_cset.func == convert_using_iconv)
+ iconv_close (input_cset.cd);
+
+ /* Resize buffer if we allocated substantially too much, or if we
+ haven't enough space for the \n-terminator. */
+ if (to.len + 4096 < to.asize || to.len >= to.asize)
+ to.text = xrealloc (to.text, to.len + 1);
+
+ to.text[to.len] = '\n';
+ *st_size = to.len;
+ return to.text;
+}
+
+const char *
+_cpp_default_encoding (void)
+{
+ const char *current_encoding = NULL;
+
+#if defined (HAVE_LOCALE_H) && defined (HAVE_LANGINFO_CODESET)
+ setlocale (LC_CTYPE, "");
+ current_encoding = nl_langinfo (CODESET);
+#endif
+ if (current_encoding == NULL || *current_encoding == '\0')
+ current_encoding = SOURCE_CHARSET;
+
+ return current_encoding;
+}
diff --git a/contrib/gcc/cppdefault.c b/contrib/gcc/cppdefault.c
index 81ee564ec7ee..cc96da7f6db3 100644
--- a/contrib/gcc/cppdefault.c
+++ b/contrib/gcc/cppdefault.c
@@ -1,6 +1,6 @@
/* CPP Library.
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2003 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -19,13 +19,28 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* This file contains data definitions shared between cpplib and
- tradcpp. */
-
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "cppdefault.h"
+#ifndef STANDARD_INCLUDE_DIR
+#define STANDARD_INCLUDE_DIR "/usr/include"
+#endif
+
+#ifndef STANDARD_INCLUDE_COMPONENT
+#define STANDARD_INCLUDE_COMPONENT 0
+#endif
+
+#if defined (CROSS_COMPILE) && !defined (TARGET_SYSTEM_ROOT)
+# undef LOCAL_INCLUDE_DIR
+# undef SYSTEM_INCLUDE_DIR
+# undef STANDARD_INCLUDE_DIR
+#else
+# undef CROSS_INCLUDE_DIR
+#endif
+
const struct default_include cpp_include_defaults[]
#ifdef INCLUDE_DEFAULTS
= INCLUDE_DEFAULTS;
@@ -33,44 +48,44 @@ const struct default_include cpp_include_defaults[]
= {
#ifdef GPLUSPLUS_INCLUDE_DIR
/* Pick up GNU C++ generic include files. */
- { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 },
+ { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0 },
#endif
#ifdef GPLUSPLUS_TOOL_INCLUDE_DIR
/* Pick up GNU C++ target-dependent include files. */
- { GPLUSPLUS_TOOL_INCLUDE_DIR, "G++", 1, 1 },
+ { GPLUSPLUS_TOOL_INCLUDE_DIR, "G++", 1, 1, 0 },
#endif
#ifdef GPLUSPLUS_BACKWARD_INCLUDE_DIR
/* Pick up GNU C++ backward and deprecated include files. */
- { GPLUSPLUS_BACKWARD_INCLUDE_DIR, "G++", 1, 1 },
+ { GPLUSPLUS_BACKWARD_INCLUDE_DIR, "G++", 1, 1, 0 },
#endif
#ifdef LOCAL_INCLUDE_DIR
/* /usr/local/include comes before the fixincluded header files. */
- { LOCAL_INCLUDE_DIR, 0, 0, 1 },
+ { LOCAL_INCLUDE_DIR, 0, 0, 1, 1 },
#endif
#ifdef PREFIX_INCLUDE_DIR
- { PREFIX_INCLUDE_DIR, 0, 0, 1 },
+ { PREFIX_INCLUDE_DIR, 0, 0, 1, 0 },
#endif
#ifdef GCC_INCLUDE_DIR
/* This is the dir for fixincludes and for gcc's private headers. */
- { GCC_INCLUDE_DIR, "GCC", 0, 0 },
+ { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 },
#endif
#ifdef CROSS_INCLUDE_DIR
/* One place the target system's headers might be. */
- { CROSS_INCLUDE_DIR, "GCC", 0, 0 },
+ { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0 },
#endif
#ifdef TOOL_INCLUDE_DIR
/* Another place the target system's headers might be. */
- { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1 },
+ { TOOL_INCLUDE_DIR, "BINUTILS", 0, 1, 0 },
#endif
#ifdef SYSTEM_INCLUDE_DIR
/* Some systems have an extra dir of include files. */
- { SYSTEM_INCLUDE_DIR, 0, 0, 0 },
+ { SYSTEM_INCLUDE_DIR, 0, 0, 0, 1 },
#endif
#ifdef STANDARD_INCLUDE_DIR
/* /usr/include comes dead last. */
- { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0 },
+ { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 1 },
#endif
- { 0, 0, 0, 0 }
+ { 0, 0, 0, 0, 0 }
};
#endif /* no INCLUDE_DEFAULTS */
@@ -81,3 +96,9 @@ const size_t cpp_GCC_INCLUDE_DIR_len = sizeof GCC_INCLUDE_DIR - 8;
const char cpp_GCC_INCLUDE_DIR[] = "";
const size_t cpp_GCC_INCLUDE_DIR_len = 0;
#endif
+
+#ifdef TARGET_SYSTEM_ROOT
+const char *cpp_SYSROOT = TARGET_SYSTEM_ROOT;
+#else
+const char *cpp_SYSROOT = "";
+#endif
diff --git a/contrib/gcc/cppdefault.h b/contrib/gcc/cppdefault.h
index 40a860964a83..368e082c79d9 100644
--- a/contrib/gcc/cppdefault.h
+++ b/contrib/gcc/cppdefault.h
@@ -1,6 +1,6 @@
/* CPP Library.
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2003 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -22,26 +22,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef GCC_CPPDEFAULT_H
#define GCC_CPPDEFAULT_H
-/* This header contains declarations and/or #defines for all the
- hard-wired defaults in cpp. Note it's used by both cpplib and
- tradcpp. */
-
-#ifndef STANDARD_INCLUDE_DIR
-#define STANDARD_INCLUDE_DIR "/usr/include"
-#endif
-
-#ifndef STANDARD_INCLUDE_COMPONENT
-#define STANDARD_INCLUDE_COMPONENT 0
-#endif
-
-#ifdef CROSS_COMPILE
-#undef LOCAL_INCLUDE_DIR
-#undef SYSTEM_INCLUDE_DIR
-#undef STANDARD_INCLUDE_DIR
-#else
-#undef CROSS_INCLUDE_DIR
-#endif
-
/* This is the default list of directories to search for include files.
It may be overridden by the various -I and -ixxx options.
@@ -57,14 +37,18 @@ struct default_include
const char *const fname; /* The name of the directory. */
const char *const component; /* The component containing the directory
(see update_path in prefix.c) */
- const int cplusplus; /* Only look here if we're compiling C++. */
- const int cxx_aware; /* Includes in this directory don't need to
+ const char cplusplus; /* Only look here if we're compiling C++. */
+ const char cxx_aware; /* Includes in this directory don't need to
be wrapped in extern "C" when compiling
C++. */
+ const char add_sysroot; /* FNAME should be prefixed by
+ cpp_SYSROOT. */
};
extern const struct default_include cpp_include_defaults[];
extern const char cpp_GCC_INCLUDE_DIR[];
extern const size_t cpp_GCC_INCLUDE_DIR_len;
+extern const char *cpp_SYSROOT;
+
#endif /* ! GCC_CPPDEFAULT_H */
diff --git a/contrib/gcc/cpperror.c b/contrib/gcc/cpperror.c
index 360bc8ccef36..61763cc1826f 100644
--- a/contrib/gcc/cpperror.c
+++ b/contrib/gcc/cpperror.c
@@ -29,36 +29,35 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "cpphash.h"
#include "intl.h"
-static void print_location PARAMS ((cpp_reader *, unsigned int, unsigned int));
+static void print_location (cpp_reader *, fileline, unsigned int);
/* Print the logical file location (LINE, COL) in preparation for a
diagnostic. Outputs the #include chain if it has changed. A line
of zero suppresses the include stack, and outputs the program name
instead. */
static void
-print_location (pfile, line, col)
- cpp_reader *pfile;
- unsigned int line, col;
+print_location (cpp_reader *pfile, fileline line, unsigned int col)
{
- if (!pfile->buffer || line == 0)
+ if (line == 0)
fprintf (stderr, "%s: ", progname);
else
{
const struct line_map *map;
+ unsigned int lin;
- map = lookup_line (&pfile->line_maps, line);
- print_containing_files (&pfile->line_maps, map);
+ map = linemap_lookup (&pfile->line_maps, line);
+ linemap_print_containing_files (&pfile->line_maps, map);
- line = SOURCE_LINE (map, line);
+ lin = SOURCE_LINE (map, line);
if (col == 0)
col = 1;
- if (line == 0)
+ if (lin == 0)
fprintf (stderr, "%s:", map->to_file);
else if (CPP_OPTION (pfile, show_column) == 0)
- fprintf (stderr, "%s:%u:", map->to_file, line);
+ fprintf (stderr, "%s:%u:", map->to_file, lin);
else
- fprintf (stderr, "%s:%u:%u:", map->to_file, line, col);
+ fprintf (stderr, "%s:%u:%u:", map->to_file, lin, col);
fputc (' ', stderr);
}
@@ -70,48 +69,46 @@ print_location (pfile, line, col)
the correct place by default. Returns 0 if the error has been
suppressed. */
int
-_cpp_begin_message (pfile, code, line, column)
- cpp_reader *pfile;
- int code;
- unsigned int line, column;
+_cpp_begin_message (cpp_reader *pfile, int code, fileline line,
+ unsigned int column)
{
- int level = DL_EXTRACT (code);
+ int level = CPP_DL_EXTRACT (code);
switch (level)
{
- case DL_WARNING:
- case DL_PEDWARN:
+ case CPP_DL_WARNING:
+ case CPP_DL_PEDWARN:
if (CPP_IN_SYSTEM_HEADER (pfile)
&& ! CPP_OPTION (pfile, warn_system_headers))
return 0;
/* Fall through. */
- case DL_WARNING_SYSHDR:
+ case CPP_DL_WARNING_SYSHDR:
if (CPP_OPTION (pfile, warnings_are_errors)
- || (level == DL_PEDWARN && CPP_OPTION (pfile, pedantic_errors)))
+ || (level == CPP_DL_PEDWARN && CPP_OPTION (pfile, pedantic_errors)))
{
if (CPP_OPTION (pfile, inhibit_errors))
return 0;
- level = DL_ERROR;
+ level = CPP_DL_ERROR;
pfile->errors++;
}
else if (CPP_OPTION (pfile, inhibit_warnings))
return 0;
break;
- case DL_ERROR:
+ case CPP_DL_ERROR:
if (CPP_OPTION (pfile, inhibit_errors))
return 0;
/* ICEs cannot be inhibited. */
- case DL_ICE:
+ case CPP_DL_ICE:
pfile->errors++;
break;
}
print_location (pfile, line, column);
- if (DL_WARNING_P (level))
+ if (CPP_DL_WARNING_P (level))
fputs (_("warning: "), stderr);
- else if (level == DL_ICE)
+ else if (level == CPP_DL_ICE)
fputs (_("internal error: "), stderr);
return 1;
@@ -126,64 +123,52 @@ _cpp_begin_message (pfile, code, line, column)
/* Print an error at the location of the previously lexed token. */
void
-cpp_error VPARAMS ((cpp_reader * pfile, int level, const char *msgid, ...))
+cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
{
- unsigned int line, column;
+ fileline line;
+ unsigned int column;
+ va_list ap;
+
+ va_start (ap, msgid);
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, cpp_reader *, pfile);
- VA_FIXEDARG (ap, int, level);
- VA_FIXEDARG (ap, const char *, msgid);
-
- if (pfile->buffer)
+ if (CPP_OPTION (pfile, traditional))
{
- if (CPP_OPTION (pfile, traditional))
- {
- if (pfile->state.in_directive)
- line = pfile->directive_line;
- else
- line = pfile->line;
- column = 0;
- }
+ if (pfile->state.in_directive)
+ line = pfile->directive_line;
else
- {
- line = pfile->cur_token[-1].line;
- column = pfile->cur_token[-1].col;
- }
+ line = pfile->line;
+ column = 0;
}
else
- line = column = 0;
+ {
+ line = pfile->cur_token[-1].line;
+ column = pfile->cur_token[-1].col;
+ }
if (_cpp_begin_message (pfile, level, line, column))
v_message (msgid, ap);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Print an error at a specific location. */
void
-cpp_error_with_line VPARAMS ((cpp_reader *pfile, int level,
- unsigned int line, unsigned int column,
- const char *msgid, ...))
+cpp_error_with_line (cpp_reader *pfile, int level,
+ fileline line, unsigned int column,
+ const char *msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, cpp_reader *, pfile);
- VA_FIXEDARG (ap, int, level);
- VA_FIXEDARG (ap, unsigned int, line);
- VA_FIXEDARG (ap, unsigned int, column);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_list ap;
+
+ va_start (ap, msgid);
if (_cpp_begin_message (pfile, level, line, column))
v_message (msgid, ap);
- VA_CLOSE (ap);
+ va_end (ap);
}
void
-cpp_errno (pfile, level, msgid)
- cpp_reader *pfile;
- int level;
- const char *msgid;
+cpp_errno (cpp_reader *pfile, int level, const char *msgid)
{
if (msgid[0] == '\0')
msgid = _("stdout");
diff --git a/contrib/gcc/cppexp.c b/contrib/gcc/cppexp.c
index 12919f6f88f1..cb35b6c782fd 100644
--- a/contrib/gcc/cppexp.c
+++ b/contrib/gcc/cppexp.c
@@ -38,34 +38,31 @@ struct op
/* Some simple utility routines on double integers. */
#define num_zerop(num) ((num.low | num.high) == 0)
#define num_eq(num1, num2) (num1.low == num2.low && num1.high == num2.high)
-static bool num_positive PARAMS ((cpp_num, size_t));
-static bool num_greater_eq PARAMS ((cpp_num, cpp_num, size_t));
-static cpp_num num_trim PARAMS ((cpp_num, size_t));
-static cpp_num num_part_mul PARAMS ((cpp_num_part, cpp_num_part));
-
-static cpp_num num_unary_op PARAMS ((cpp_reader *, cpp_num, enum cpp_ttype));
-static cpp_num num_binary_op PARAMS ((cpp_reader *, cpp_num, cpp_num,
- enum cpp_ttype));
-static cpp_num num_negate PARAMS ((cpp_num, size_t));
-static cpp_num num_bitwise_op PARAMS ((cpp_reader *, cpp_num, cpp_num,
- enum cpp_ttype));
-static cpp_num num_inequality_op PARAMS ((cpp_reader *, cpp_num, cpp_num,
- enum cpp_ttype));
-static cpp_num num_equality_op PARAMS ((cpp_reader *, cpp_num, cpp_num,
- enum cpp_ttype));
-static cpp_num num_mul PARAMS ((cpp_reader *, cpp_num, cpp_num));
-static cpp_num num_div_op PARAMS ((cpp_reader *, cpp_num, cpp_num,
- enum cpp_ttype));
-static cpp_num num_lshift PARAMS ((cpp_num, size_t, size_t));
-static cpp_num num_rshift PARAMS ((cpp_num, size_t, size_t));
-
-static cpp_num append_digit PARAMS ((cpp_num, int, int, size_t));
-static cpp_num parse_defined PARAMS ((cpp_reader *));
-static cpp_num eval_token PARAMS ((cpp_reader *, const cpp_token *));
-static struct op *reduce PARAMS ((cpp_reader *, struct op *, enum cpp_ttype));
-static unsigned int interpret_float_suffix PARAMS ((const uchar *, size_t));
-static unsigned int interpret_int_suffix PARAMS ((const uchar *, size_t));
-static void check_promotion PARAMS ((cpp_reader *, const struct op *));
+static bool num_positive (cpp_num, size_t);
+static bool num_greater_eq (cpp_num, cpp_num, size_t);
+static cpp_num num_trim (cpp_num, size_t);
+static cpp_num num_part_mul (cpp_num_part, cpp_num_part);
+
+static cpp_num num_unary_op (cpp_reader *, cpp_num, enum cpp_ttype);
+static cpp_num num_binary_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype);
+static cpp_num num_negate (cpp_num, size_t);
+static cpp_num num_bitwise_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype);
+static cpp_num num_inequality_op (cpp_reader *, cpp_num, cpp_num,
+ enum cpp_ttype);
+static cpp_num num_equality_op (cpp_reader *, cpp_num, cpp_num,
+ enum cpp_ttype);
+static cpp_num num_mul (cpp_reader *, cpp_num, cpp_num);
+static cpp_num num_div_op (cpp_reader *, cpp_num, cpp_num, enum cpp_ttype);
+static cpp_num num_lshift (cpp_num, size_t, size_t);
+static cpp_num num_rshift (cpp_num, size_t, size_t);
+
+static cpp_num append_digit (cpp_num, int, int, size_t);
+static cpp_num parse_defined (cpp_reader *);
+static cpp_num eval_token (cpp_reader *, const cpp_token *);
+static struct op *reduce (cpp_reader *, struct op *, enum cpp_ttype);
+static unsigned int interpret_float_suffix (const uchar *, size_t);
+static unsigned int interpret_int_suffix (const uchar *, size_t);
+static void check_promotion (cpp_reader *, const struct op *);
/* Token type abuse to create unary plus and minus operators. */
#define CPP_UPLUS (CPP_LAST_CPP_OP + 1)
@@ -74,17 +71,16 @@ static void check_promotion PARAMS ((cpp_reader *, const struct op *));
/* With -O2, gcc appears to produce nice code, moving the error
message load and subsequent jump completely out of the main path. */
#define SYNTAX_ERROR(msgid) \
- do { cpp_error (pfile, DL_ERROR, msgid); goto syntax_error; } while(0)
+ do { cpp_error (pfile, CPP_DL_ERROR, msgid); goto syntax_error; } while(0)
#define SYNTAX_ERROR2(msgid, arg) \
- do { cpp_error (pfile, DL_ERROR, msgid, arg); goto syntax_error; } while(0)
+ do { cpp_error (pfile, CPP_DL_ERROR, msgid, arg); goto syntax_error; } \
+ while(0)
/* Subroutine of cpp_classify_number. S points to a float suffix of
length LEN, possibly zero. Returns 0 for an invalid suffix, or a
flag vector describing the suffix. */
static unsigned int
-interpret_float_suffix (s, len)
- const uchar *s;
- size_t len;
+interpret_float_suffix (const uchar *s, size_t len)
{
size_t f = 0, l = 0, i = 0;
@@ -111,9 +107,7 @@ interpret_float_suffix (s, len)
of length LEN, possibly zero. Returns 0 for an invalid suffix, or a
flag vector describing the suffix. */
static unsigned int
-interpret_int_suffix (s, len)
- const uchar *s;
- size_t len;
+interpret_int_suffix (const uchar *s, size_t len)
{
size_t u, l, i;
@@ -147,9 +141,7 @@ interpret_int_suffix (s, len)
floating point, or invalid), radix (decimal, octal, hexadecimal),
and type suffixes. */
unsigned int
-cpp_classify_number (pfile, token)
- cpp_reader *pfile;
- const cpp_token *token;
+cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
{
const uchar *str = token->val.str.text;
const uchar *limit;
@@ -173,7 +165,8 @@ cpp_classify_number (pfile, token)
str++;
/* Require at least one hex digit to classify it as hex. */
- if ((*str == 'x' || *str == 'X') && ISXDIGIT (str[1]))
+ if ((*str == 'x' || *str == 'X')
+ && (str[1] == '.' || ISXDIGIT (str[1])))
{
radix = 16;
str++;
@@ -221,7 +214,7 @@ cpp_classify_number (pfile, token)
if (float_flag != NOT_FLOAT)
{
if (radix == 16 && CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, c99))
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"use of C99 hexadecimal floating constant");
if (float_flag == AFTER_EXPON)
@@ -243,7 +236,7 @@ cpp_classify_number (pfile, token)
result = interpret_float_suffix (str, limit - str);
if (result == 0)
{
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"invalid suffix \"%.*s\" on floating constant",
(int) (limit - str), str);
return CPP_N_INVALID;
@@ -253,7 +246,7 @@ cpp_classify_number (pfile, token)
if (limit != str
&& CPP_WTRADITIONAL (pfile)
&& ! cpp_sys_macro_p (pfile))
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"traditional C rejects the \"%.*s\" suffix",
(int) (limit - str), str);
@@ -264,7 +257,7 @@ cpp_classify_number (pfile, token)
result = interpret_int_suffix (str, limit - str);
if (result == 0)
{
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"invalid suffix \"%.*s\" on integer constant",
(int) (limit - str), str);
return CPP_N_INVALID;
@@ -278,7 +271,7 @@ cpp_classify_number (pfile, token)
int large = (result & CPP_N_WIDTH) == CPP_N_LARGE;
if (u_or_i || (large && CPP_OPTION (pfile, warn_long_long)))
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"traditional C rejects the \"%.*s\" suffix",
(int) (limit - str), str);
}
@@ -286,13 +279,15 @@ cpp_classify_number (pfile, token)
if ((result & CPP_N_WIDTH) == CPP_N_LARGE
&& ! CPP_OPTION (pfile, c99)
&& CPP_OPTION (pfile, warn_long_long))
- cpp_error (pfile, DL_PEDWARN, "use of C99 long long integer constant");
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "use of C99 long long integer constant");
result |= CPP_N_INTEGER;
}
if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
- cpp_error (pfile, DL_PEDWARN, "imaginary constants are a GCC extension");
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "imaginary constants are a GCC extension");
if (radix == 10)
result |= CPP_N_DECIMAL;
@@ -311,13 +306,11 @@ cpp_classify_number (pfile, token)
of precision options->precision.
We do not provide any interface for decimal->float conversion,
- because the preprocessor doesn't need it and the floating point
- handling in GCC proper is too ugly to speak of. */
+ because the preprocessor doesn't need it and we don't want to
+ drag in GCC's floating point emulator. */
cpp_num
-cpp_interpret_integer (pfile, token, type)
- cpp_reader *pfile;
- const cpp_token *token;
- unsigned int type;
+cpp_interpret_integer (cpp_reader *pfile, const cpp_token *token,
+ unsigned int type)
{
const uchar *p, *end;
cpp_num result;
@@ -379,7 +372,7 @@ cpp_interpret_integer (pfile, token, type)
}
if (overflow)
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"integer constant is too large for its type");
/* If too big to be signed, consider it unsigned. Only warn for
decimal numbers. Traditional numbers were always signed (but
@@ -391,7 +384,7 @@ cpp_interpret_integer (pfile, token, type)
&& !num_positive (result, precision))
{
if (base == 10)
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"integer constant is so large that it is unsigned");
result.unsignedp = true;
}
@@ -400,13 +393,9 @@ cpp_interpret_integer (pfile, token, type)
return result;
}
-/* Append DIGIT to NUM, a number of PRECISION bits being read in base
- BASE. */
+/* Append DIGIT to NUM, a number of PRECISION bits being read in base BASE. */
static cpp_num
-append_digit (num, digit, base, precision)
- cpp_num num;
- int digit, base;
- size_t precision;
+append_digit (cpp_num num, int digit, int base, size_t precision)
{
cpp_num result;
unsigned int shift = 3 + (base == 16);
@@ -455,8 +444,7 @@ append_digit (num, digit, base, precision)
/* Handle meeting "defined" in a preprocessor expression. */
static cpp_num
-parse_defined (pfile)
- cpp_reader *pfile;
+parse_defined (cpp_reader *pfile)
{
cpp_num result;
int paren = 0;
@@ -479,13 +467,13 @@ parse_defined (pfile)
node = token->val.node;
if (paren && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN)
{
- cpp_error (pfile, DL_ERROR, "missing ')' after \"defined\"");
+ cpp_error (pfile, CPP_DL_ERROR, "missing ')' after \"defined\"");
node = 0;
}
}
else
{
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"operator \"defined\" requires an identifier");
if (token->flags & NAMED_OP)
{
@@ -493,7 +481,7 @@ parse_defined (pfile)
op.flags = 0;
op.type = token->type;
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"(\"%s\" is an alternative token for \"%s\" in C++)",
cpp_token_as_text (pfile, token),
cpp_token_as_text (pfile, &op));
@@ -503,7 +491,7 @@ parse_defined (pfile)
if (node)
{
if (pfile->context != initial_context && CPP_PEDANTIC (pfile))
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"this use of \"defined\" may not be portable");
_cpp_mark_macro_used (node);
@@ -526,9 +514,7 @@ parse_defined (pfile)
number or character constant, or the result of the "defined" or "#"
operators). */
static cpp_num
-eval_token (pfile, token)
- cpp_reader *pfile;
- const cpp_token *token;
+eval_token (cpp_reader *pfile, const cpp_token *token)
{
cpp_num result;
unsigned int temp;
@@ -541,13 +527,13 @@ eval_token (pfile, token)
switch (temp & CPP_N_CATEGORY)
{
case CPP_N_FLOATING:
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"floating constant in preprocessor expression");
break;
case CPP_N_INTEGER:
if (!(temp & CPP_N_IMAGINARY))
return cpp_interpret_integer (pfile, token, temp);
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"imaginary number in preprocessor expression");
break;
@@ -587,21 +573,13 @@ eval_token (pfile, token)
{
result.high = 0;
result.low = (token->val.node == pfile->spec_nodes.n_true);
-
- /* Warn about use of true or false in #if when pedantic
- and stdbool.h has not been included. */
- if (CPP_PEDANTIC (pfile)
- && ! cpp_defined (pfile, DSC("__bool_true_false_are_defined")))
- cpp_error (pfile, DL_PEDWARN,
- "ISO C++ does not permit \"%s\" in #if",
- NODE_NAME (token->val.node));
}
else
{
result.high = 0;
result.low = 0;
if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval)
- cpp_error (pfile, DL_WARNING, "\"%s\" is not defined",
+ cpp_error (pfile, CPP_DL_WARNING, "\"%s\" is not defined",
NODE_NAME (token->val.node));
}
break;
@@ -631,7 +609,7 @@ already on the stack.
The remaining cases are '(' and ')'. We handle '(' by skipping the
reduction phase completely. ')' is given lower priority than
everything else, including '(', effectively forcing a reduction of the
-parenthesised expression. If there is a matching '(', the routine
+parenthesized expression. If there is a matching '(', the routine
reduce() exits immediately. If the normal exit route sees a ')', then
there cannot have been a matching '(' and an error message is output.
@@ -700,8 +678,7 @@ static const struct operator
stored in the 'value' field of the stack element of the operator
that precedes it. */
bool
-_cpp_parse_expr (pfile)
- cpp_reader *pfile;
+_cpp_parse_expr (cpp_reader *pfile)
{
struct op *top = pfile->op_stack;
unsigned int lex_count;
@@ -751,12 +728,6 @@ _cpp_parse_expr (pfile)
if (want_value)
op.op = CPP_UMINUS;
break;
- case CPP_OTHER:
- if (ISGRAPH (op.token->val.c))
- SYNTAX_ERROR2 ("invalid character '%c' in #if", op.token->val.c);
- else
- SYNTAX_ERROR2 ("invalid character '\\%03o' in #if",
- op.token->val.c);
default:
if ((int) op.op <= (int) CPP_EQ || (int) op.op >= (int) CPP_PLUS_EQ)
@@ -774,18 +745,22 @@ _cpp_parse_expr (pfile)
}
else if (want_value)
{
- /* Ordering here is subtle and intended to favor the
- missing parenthesis diagnostics over alternatives. */
- if (op.op == CPP_CLOSE_PAREN)
- {
- if (top->op == CPP_OPEN_PAREN)
- SYNTAX_ERROR ("void expression between '(' and ')'");
- }
- else if (top->op == CPP_EOF)
+ /* We want a number (or expression) and haven't got one.
+ Try to emit a specific diagnostic. */
+ if (op.op == CPP_CLOSE_PAREN && top->op == CPP_OPEN_PAREN)
+ SYNTAX_ERROR ("missing expression between '(' and ')'");
+
+ if (op.op == CPP_EOF && top->op == CPP_EOF)
SYNTAX_ERROR ("#if with no expression");
+
if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN)
SYNTAX_ERROR2 ("operator '%s' has no right operand",
cpp_token_as_text (pfile, top->token));
+ else if (op.op == CPP_CLOSE_PAREN || op.op == CPP_EOF)
+ /* Complain about missing paren during reduction. */;
+ else
+ SYNTAX_ERROR2 ("operator '%s' has no left operand",
+ cpp_token_as_text (pfile, op.token));
}
top = reduce (pfile, top, op.op);
@@ -837,7 +812,7 @@ _cpp_parse_expr (pfile)
if (top != pfile->op_stack)
{
- cpp_error (pfile, DL_ICE, "unbalanced stack in #if");
+ cpp_error (pfile, CPP_DL_ICE, "unbalanced stack in #if");
syntax_error:
return false; /* Return false on syntax error. */
}
@@ -849,17 +824,14 @@ _cpp_parse_expr (pfile)
pushing operator OP. Returns NULL on error, otherwise the top of
the stack. */
static struct op *
-reduce (pfile, top, op)
- cpp_reader *pfile;
- struct op *top;
- enum cpp_ttype op;
+reduce (cpp_reader *pfile, struct op *top, enum cpp_ttype op)
{
unsigned int prio;
if (top->op <= CPP_EQ || top->op > CPP_LAST_CPP_OP + 2)
{
bad_op:
- cpp_error (pfile, DL_ICE, "impossible operator '%u'", top->op);
+ cpp_error (pfile, CPP_DL_ICE, "impossible operator '%u'", top->op);
return 0;
}
@@ -951,7 +923,7 @@ reduce (pfile, top, op)
case CPP_OPEN_PAREN:
if (op != CPP_CLOSE_PAREN)
{
- cpp_error (pfile, DL_ERROR, "missing ')' in expression");
+ cpp_error (pfile, CPP_DL_ERROR, "missing ')' in expression");
return 0;
}
top--;
@@ -972,7 +944,7 @@ reduce (pfile, top, op)
continue;
case CPP_QUERY:
- cpp_error (pfile, DL_ERROR, "'?' without following ':'");
+ cpp_error (pfile, CPP_DL_ERROR, "'?' without following ':'");
return 0;
default:
@@ -981,13 +953,13 @@ reduce (pfile, top, op)
top--;
if (top->value.overflow && !pfile->state.skip_eval)
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"integer overflow in preprocessor expression");
}
if (op == CPP_CLOSE_PAREN)
{
- cpp_error (pfile, DL_ERROR, "missing '(' in expression");
+ cpp_error (pfile, CPP_DL_ERROR, "missing '(' in expression");
return 0;
}
@@ -996,14 +968,12 @@ reduce (pfile, top, op)
/* Returns the position of the old top of stack after expansion. */
struct op *
-_cpp_expand_op_stack (pfile)
- cpp_reader *pfile;
+_cpp_expand_op_stack (cpp_reader *pfile)
{
size_t old_size = (size_t) (pfile->op_limit - pfile->op_stack);
size_t new_size = old_size * 2 + 20;
- pfile->op_stack = (struct op *) xrealloc (pfile->op_stack,
- new_size * sizeof (struct op));
+ pfile->op_stack = xrealloc (pfile->op_stack, new_size * sizeof (struct op));
pfile->op_limit = pfile->op_stack + new_size;
return pfile->op_stack + old_size;
@@ -1012,9 +982,7 @@ _cpp_expand_op_stack (pfile)
/* Emits a warning if the effective sign of either operand of OP
changes because of integer promotions. */
static void
-check_promotion (pfile, op)
- cpp_reader *pfile;
- const struct op *op;
+check_promotion (cpp_reader *pfile, const struct op *op)
{
if (op->value.unsignedp == op[-1].value.unsignedp)
return;
@@ -1022,21 +990,19 @@ check_promotion (pfile, op)
if (op->value.unsignedp)
{
if (!num_positive (op[-1].value, CPP_OPTION (pfile, precision)))
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"the left operand of \"%s\" changes sign when promoted",
cpp_token_as_text (pfile, op->token));
}
else if (!num_positive (op->value, CPP_OPTION (pfile, precision)))
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"the right operand of \"%s\" changes sign when promoted",
cpp_token_as_text (pfile, op->token));
}
/* Clears the unused high order bits of the number pointed to by PNUM. */
static cpp_num
-num_trim (num, precision)
- cpp_num num;
- size_t precision;
+num_trim (cpp_num num, size_t precision)
{
if (precision > PART_PRECISION)
{
@@ -1056,9 +1022,7 @@ num_trim (num, precision)
/* True iff A (presumed signed) >= 0. */
static bool
-num_positive (num, precision)
- cpp_num num;
- size_t precision;
+num_positive (cpp_num num, size_t precision)
{
if (precision > PART_PRECISION)
{
@@ -1072,9 +1036,7 @@ num_positive (num, precision)
/* Sign extend a number, with PRECISION significant bits and all
others assumed clear, to fill out a cpp_num structure. */
cpp_num
-cpp_num_sign_extend (num, precision)
- cpp_num num;
- size_t precision;
+cpp_num_sign_extend (cpp_num num, size_t precision)
{
if (!num.unsignedp)
{
@@ -1098,9 +1060,7 @@ cpp_num_sign_extend (num, precision)
/* Returns the negative of NUM. */
static cpp_num
-num_negate (num, precision)
- cpp_num num;
- size_t precision;
+num_negate (cpp_num num, size_t precision)
{
cpp_num copy;
@@ -1117,9 +1077,7 @@ num_negate (num, precision)
/* Returns true if A >= B. */
static bool
-num_greater_eq (pa, pb, precision)
- cpp_num pa, pb;
- size_t precision;
+num_greater_eq (cpp_num pa, cpp_num pb, size_t precision)
{
bool unsignedp;
@@ -1142,10 +1100,8 @@ num_greater_eq (pa, pb, precision)
/* Returns LHS OP RHS, where OP is a bit-wise operation. */
static cpp_num
-num_bitwise_op (pfile, lhs, rhs, op)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
- cpp_num lhs, rhs;
- enum cpp_ttype op;
+num_bitwise_op (cpp_reader *pfile ATTRIBUTE_UNUSED,
+ cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
{
lhs.overflow = false;
lhs.unsignedp = lhs.unsignedp || rhs.unsignedp;
@@ -1173,10 +1129,8 @@ num_bitwise_op (pfile, lhs, rhs, op)
/* Returns LHS OP RHS, where OP is an inequality. */
static cpp_num
-num_inequality_op (pfile, lhs, rhs, op)
- cpp_reader *pfile;
- cpp_num lhs, rhs;
- enum cpp_ttype op;
+num_inequality_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs,
+ enum cpp_ttype op)
{
bool gte = num_greater_eq (lhs, rhs, CPP_OPTION (pfile, precision));
@@ -1197,10 +1151,8 @@ num_inequality_op (pfile, lhs, rhs, op)
/* Returns LHS OP RHS, where OP is == or !=. */
static cpp_num
-num_equality_op (pfile, lhs, rhs, op)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
- cpp_num lhs, rhs;
- enum cpp_ttype op;
+num_equality_op (cpp_reader *pfile ATTRIBUTE_UNUSED,
+ cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
{
/* Work around a 3.0.4 bug; see PR 6950. */
bool eq = num_eq (lhs, rhs);
@@ -1215,9 +1167,7 @@ num_equality_op (pfile, lhs, rhs, op)
/* Shift NUM, of width PRECISION, right by N bits. */
static cpp_num
-num_rshift (num, precision, n)
- cpp_num num;
- size_t precision, n;
+num_rshift (cpp_num num, size_t precision, size_t n)
{
cpp_num_part sign_mask;
@@ -1257,9 +1207,7 @@ num_rshift (num, precision, n)
/* Shift NUM, of width PRECISION, left by N bits. */
static cpp_num
-num_lshift (num, precision, n)
- cpp_num num;
- size_t precision, n;
+num_lshift (cpp_num num, size_t precision, size_t n)
{
if (n >= precision)
{
@@ -1299,16 +1247,13 @@ num_lshift (num, precision, n)
/* The four unary operators: +, -, ! and ~. */
static cpp_num
-num_unary_op (pfile, num, op)
- cpp_reader *pfile;
- cpp_num num;
- enum cpp_ttype op;
+num_unary_op (cpp_reader *pfile, cpp_num num, enum cpp_ttype op)
{
switch (op)
{
case CPP_UPLUS:
if (CPP_WTRADITIONAL (pfile) && !pfile->state.skip_eval)
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"traditional C rejects the unary plus operator");
num.overflow = false;
break;
@@ -1337,10 +1282,7 @@ num_unary_op (pfile, num, op)
/* The various binary operators. */
static cpp_num
-num_binary_op (pfile, lhs, rhs, op)
- cpp_reader *pfile;
- cpp_num lhs, rhs;
- enum cpp_ttype op;
+num_binary_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
{
cpp_num result;
size_t precision = CPP_OPTION (pfile, precision);
@@ -1409,8 +1351,9 @@ num_binary_op (pfile, lhs, rhs, op)
/* Comma. */
default: /* case CPP_COMMA: */
- if (CPP_PEDANTIC (pfile) && !pfile->state.skip_eval)
- cpp_error (pfile, DL_PEDWARN,
+ if (CPP_PEDANTIC (pfile) && (!CPP_OPTION (pfile, c99)
+ || !pfile->state.skip_eval))
+ cpp_error (pfile, CPP_DL_PEDWARN,
"comma operator in operand of #if");
lhs = rhs;
break;
@@ -1422,8 +1365,7 @@ num_binary_op (pfile, lhs, rhs, op)
/* Multiplies two unsigned cpp_num_parts to give a cpp_num. This
cannot overflow. */
static cpp_num
-num_part_mul (lhs, rhs)
- cpp_num_part lhs, rhs;
+num_part_mul (cpp_num_part lhs, cpp_num_part rhs)
{
cpp_num result;
cpp_num_part middle[2], temp;
@@ -1453,9 +1395,7 @@ num_part_mul (lhs, rhs)
/* Multiply two preprocessing numbers. */
static cpp_num
-num_mul (pfile, lhs, rhs)
- cpp_reader *pfile;
- cpp_num lhs, rhs;
+num_mul (cpp_reader *pfile, cpp_num lhs, cpp_num rhs)
{
cpp_num result, temp;
bool unsignedp = lhs.unsignedp || rhs.unsignedp;
@@ -1505,10 +1445,7 @@ num_mul (pfile, lhs, rhs)
/* Divide two preprocessing numbers, returning the answer or the
remainder depending upon OP. */
static cpp_num
-num_div_op (pfile, lhs, rhs, op)
- cpp_reader *pfile;
- cpp_num lhs, rhs;
- enum cpp_ttype op;
+num_div_op (cpp_reader *pfile, cpp_num lhs, cpp_num rhs, enum cpp_ttype op)
{
cpp_num result, sub;
cpp_num_part mask;
@@ -1548,7 +1485,7 @@ num_div_op (pfile, lhs, rhs, op)
else
{
if (!pfile->state.skip_eval)
- cpp_error (pfile, DL_ERROR, "division by zero in #if");
+ cpp_error (pfile, CPP_DL_ERROR, "division by zero in #if");
return lhs;
}
diff --git a/contrib/gcc/cppfiles.c b/contrib/gcc/cppfiles.c
index 2e11912934ad..1ca793d5fb84 100644
--- a/contrib/gcc/cppfiles.c
+++ b/contrib/gcc/cppfiles.c
@@ -1,10 +1,11 @@
-/* Part of CPP library. (include file handling)
+/* Part of CPP library. File handling.
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Written by Per Bothner, 1994.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
Split out of cpplib.c, Zack Weinberg, Oct 1998
+ Reimplemented, Neil Booth, Jul 2003
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
@@ -26,377 +27,440 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "cpphash.h"
#include "intl.h"
#include "mkdeps.h"
-#include "splay-tree.h"
-#ifdef ENABLE_VALGRIND_CHECKING
-#include <valgrind.h>
+#include "hashtab.h"
+#include <dirent.h>
+
+/* Variable length record files on VMS will have a stat size that includes
+ record control characters that won't be included in the read size. */
+#ifdef VMS
+# define FAB_C_VAR 2 /* variable length records (see Starlet fabdef.h) */
+# define STAT_SIZE_RELIABLE(ST) ((ST).st_fab_rfm != FAB_C_VAR)
#else
-/* Avoid #ifdef:s when we can help it. */
-#define VALGRIND_DISCARD(x)
+# define STAT_SIZE_RELIABLE(ST) true
#endif
-#ifdef HAVE_MMAP_FILE
-# include <sys/mman.h>
-# ifndef MMAP_THRESHOLD
-# define MMAP_THRESHOLD 3 /* Minimum page count to mmap the file. */
-# endif
-# if MMAP_THRESHOLD
-# define TEST_THRESHOLD(size, pagesize) \
- (size / pagesize >= MMAP_THRESHOLD && (size % pagesize) != 0)
- /* Use mmap if the file is big enough to be worth it (controlled
- by MMAP_THRESHOLD) and if we can safely count on there being
- at least one readable NUL byte after the end of the file's
- contents. This is true for all tested operating systems when
- the file size is not an exact multiple of the page size. */
-# ifndef __CYGWIN__
-# define SHOULD_MMAP(size, pagesize) TEST_THRESHOLD (size, pagesize)
-# else
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
- /* Cygwin can't correctly emulate mmap under Windows 9x style systems so
- disallow use of mmap on those systems. Windows 9x does not zero fill
- memory at EOF and beyond, as required. */
-# define SHOULD_MMAP(size, pagesize) ((GetVersion() & 0x80000000) \
- ? 0 : TEST_THRESHOLD (size, pagesize))
-# endif
-# endif
-
-#else /* No MMAP_FILE */
-# undef MMAP_THRESHOLD
-# define MMAP_THRESHOLD 0
+#ifdef __DJGPP__
+ /* For DJGPP redirected input is opened in text mode. */
+# define set_stdin_to_binary_mode() \
+ if (! isatty (0)) setmode (0, O_BINARY)
+#else
+# define set_stdin_to_binary_mode() /* Nothing */
#endif
#ifndef O_BINARY
# define O_BINARY 0
#endif
-/* If errno is inspected immediately after a system call fails, it will be
- nonzero, and no error number will ever be zero. */
-#ifndef ENOENT
-# define ENOENT 0
-#endif
-#ifndef ENOTDIR
-# define ENOTDIR 0
-#endif
+/* This structure represents a file searched for by CPP, whether it
+ exists or not. An instance may be pointed to by more than one
+ file_hash_entry; at present no reference count is kept. */
+struct _cpp_file
+{
+ /* Filename as given to #include or command line switch. */
+ const char *name;
-/* Suppress warning about function macros used w/o arguments in traditional
- C. It is unlikely that glibc's strcmp macro helps this file at all. */
-#undef strcmp
-
-/* This structure is used for the table of all includes. */
-struct include_file {
- const char *name; /* actual path name of file */
- const cpp_hashnode *cmacro; /* macro, if any, preventing reinclusion. */
- const struct search_path *foundhere;
- /* location in search path where file was
- found, for #include_next and sysp. */
- const unsigned char *buffer; /* pointer to cached file contents */
- struct stat st; /* copy of stat(2) data for file */
- int fd; /* fd open on file (short term storage only) */
- int err_no; /* errno obtained if opening a file failed */
- unsigned short include_count; /* number of times file has been read */
- unsigned short refcnt; /* number of stacked buffers using this file */
- unsigned char mapped; /* file buffer is mmapped */
-};
+ /* The full path used to find the file. */
+ const char *path;
-/* Variable length record files on VMS will have a stat size that includes
- record control characters that won't be included in the read size. */
-#ifdef VMS
-# define FAB_C_VAR 2 /* variable length records (see Starlet fabdef.h) */
-# define STAT_SIZE_TOO_BIG(ST) ((ST).st_fab_rfm == FAB_C_VAR)
-#else
-# define STAT_SIZE_TOO_BIG(ST) 0
-#endif
+ /* The full path of the pch file. */
+ const char *pchname;
-/* The cmacro works like this: If it's NULL, the file is to be
- included again. If it's NEVER_REREAD, the file is never to be
- included again. Otherwise it is a macro hashnode, and the file is
- to be included again if the macro is defined. */
-#define NEVER_REREAD ((const cpp_hashnode *) -1)
-#define DO_NOT_REREAD(inc) \
-((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \
- || (inc)->cmacro->type == NT_MACRO))
-#define NO_INCLUDE_PATH ((struct include_file *) -1)
-
-static struct file_name_map *read_name_map
- PARAMS ((cpp_reader *, const char *));
-static char *read_filename_string PARAMS ((int, FILE *));
-static char *remap_filename PARAMS ((cpp_reader *, char *,
- struct search_path *));
-static struct search_path *search_from PARAMS ((cpp_reader *,
- enum include_type));
-static struct include_file *
- find_include_file PARAMS ((cpp_reader *, const cpp_token *,
- enum include_type));
-static struct include_file *open_file PARAMS ((cpp_reader *, const char *));
-static int read_include_file PARAMS ((cpp_reader *, struct include_file *));
-static bool stack_include_file PARAMS ((cpp_reader *, struct include_file *));
-static void purge_cache PARAMS ((struct include_file *));
-static void destroy_node PARAMS ((splay_tree_value));
-static int report_missing_guard PARAMS ((splay_tree_node, void *));
-static splay_tree_node find_or_create_entry PARAMS ((cpp_reader *,
- const char *));
-static void handle_missing_header PARAMS ((cpp_reader *, const char *, int));
-static int remove_component_p PARAMS ((const char *));
-
-/* Set up the splay tree we use to store information about all the
- file names seen in this compilation. We also have entries for each
- file we tried to open but failed; this saves system calls since we
- don't try to open it again in future.
-
- The key of each node is the file name, after processing by
- _cpp_simplify_pathname. The path name may or may not be absolute.
- The path string has been malloced, as is automatically freed by
- registering free () as the splay tree key deletion function.
-
- A node's value is a pointer to a struct include_file, and is never
- NULL. */
-void
-_cpp_init_includes (pfile)
- cpp_reader *pfile;
-{
- pfile->all_include_files
- = splay_tree_new ((splay_tree_compare_fn) strcmp,
- (splay_tree_delete_key_fn) free,
- destroy_node);
-}
+ /* The file's path with the basename stripped. NULL if it hasn't
+ been calculated yet. */
+ const char *dir_name;
-/* Tear down the splay tree. */
-void
-_cpp_cleanup_includes (pfile)
- cpp_reader *pfile;
-{
- splay_tree_delete (pfile->all_include_files);
-}
+ /* Chain through all files. */
+ struct _cpp_file *next_file;
-/* Free a node. The path string is automatically freed. */
-static void
-destroy_node (v)
- splay_tree_value v;
-{
- struct include_file *f = (struct include_file *) v;
+ /* The contents of NAME after calling read_file(). */
+ const uchar *buffer;
- if (f)
- {
- purge_cache (f);
- free (f);
- }
-}
+ /* The macro, if any, preventing re-inclusion. */
+ const cpp_hashnode *cmacro;
-/* Mark a file to not be reread (e.g. #import, read failure). */
-void
-_cpp_never_reread (file)
- struct include_file *file;
-{
- file->cmacro = NEVER_REREAD;
-}
+ /* The directory in the search path where FILE was found. Used for
+ #include_next and determining whether a header is a system
+ header. */
+ cpp_dir *dir;
-/* Lookup a filename, which is simplified after making a copy, and
- create an entry if none exists. errno is nonzero iff a (reported)
- stat() error occurred during simplification. */
-static splay_tree_node
-find_or_create_entry (pfile, fname)
- cpp_reader *pfile;
- const char *fname;
-{
- splay_tree_node node;
- struct include_file *file;
- char *name = xstrdup (fname);
-
- _cpp_simplify_pathname (name);
- node = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) name);
- if (node)
- free (name);
- else
- {
- file = xcnew (struct include_file);
- file->name = name;
- file->err_no = errno;
- node = splay_tree_insert (pfile->all_include_files,
- (splay_tree_key) file->name,
- (splay_tree_value) file);
- }
+ /* As filled in by stat(2) for the file. */
+ struct stat st;
- return node;
-}
+ /* File descriptor. Invalid if -1, otherwise open. */
+ int fd;
-/* Enter a file name in the splay tree, for the sake of cpp_included. */
-void
-_cpp_fake_include (pfile, fname)
- cpp_reader *pfile;
- const char *fname;
-{
- find_or_create_entry (pfile, fname);
-}
-
-/* Given a file name, look it up in the cache; if there is no entry,
- create one with a non-NULL value (regardless of success in opening
- the file). If the file doesn't exist or is inaccessible, this
- entry is flagged so we don't attempt to open it again in the
- future. If the file isn't open, open it. The empty string is
- interpreted as stdin.
-
- Returns an include_file structure with an open file descriptor on
- success, or NULL on failure. */
-static struct include_file *
-open_file (pfile, filename)
- cpp_reader *pfile;
- const char *filename;
-{
- splay_tree_node nd = find_or_create_entry (pfile, filename);
- struct include_file *file = (struct include_file *) nd->value;
+ /* Zero if this file was successfully opened and stat()-ed,
+ otherwise errno obtained from failure. */
+ int err_no;
- if (file->err_no)
- {
- /* Ugh. handle_missing_header () needs errno to be set. */
- errno = file->err_no;
- return 0;
- }
+ /* Number of times the file has been stacked for preprocessing. */
+ unsigned short stack_count;
- /* Don't reopen an idempotent file. */
- if (DO_NOT_REREAD (file))
- return file;
+ /* If opened with #import or contains #pragma once. */
+ bool once_only;
- /* Don't reopen one which is already loaded. */
- if (file->buffer != NULL)
- return file;
+ /* If read() failed before. */
+ bool dont_read;
- /* We used to open files in nonblocking mode, but that caused more
- problems than it solved. Do take care not to acquire a
- controlling terminal by mistake (this can't happen on sane
- systems, but paranoia is a virtue).
+ /* If this file is the main file. */
+ bool main_file;
- Use the three-argument form of open even though we aren't
- specifying O_CREAT, to defend against broken system headers.
+ /* If BUFFER above contains the true contents of the file. */
+ bool buffer_valid;
- O_BINARY tells some runtime libraries (notably DJGPP) not to do
- newline translation; we can handle DOS line breaks just fine
- ourselves.
+ /* 0: file not known to be a PCH.
+ 1: file is a PCH (on return from find_include_file).
+ 2: file is not and never will be a valid precompiled header.
+ 3: file is always a valid precompiled header. */
+ uchar pch;
+};
- Special case: the empty string is translated to stdin. */
+/* A singly-linked list for all searches for a given file name, with
+ its head pointed to by a slot in FILE_HASH. The file name is what
+ appeared between the quotes in a #include directive; it can be
+ determined implicitly from the hash table location or explicitly
+ from FILE->name.
+
+ FILE is a structure containing details about the file that was
+ found with that search, or details of how the search failed.
+
+ START_DIR is the starting location of the search in the include
+ chain. The current directories for "" includes are also hashed in
+ the hash table and therefore unique. Files that are looked up
+ without using a search path, such as absolute filenames and file
+ names from the command line share a special starting directory so
+ they don't cause cache hits with normal include-chain lookups.
+
+ If START_DIR is NULL then the entry is for a directory, not a file,
+ and the directory is in DIR. Since the starting point in a file
+ lookup chain is never NULL, this means that simple pointer
+ comparisons against START_DIR can be made to determine cache hits
+ in file lookups.
+
+ If a cache lookup fails because of e.g. an extra "./" in the path,
+ then nothing will break. It is just less efficient as CPP will
+ have to do more work re-preprocessing the file, and/or comparing
+ its contents against earlier once-only files.
+*/
+struct file_hash_entry
+{
+ struct file_hash_entry *next;
+ cpp_dir *start_dir;
+ union
+ {
+ _cpp_file *file;
+ cpp_dir *dir;
+ } u;
+};
- if (filename[0] == '\0')
+static bool open_file (_cpp_file *file);
+static bool pch_open_file (cpp_reader *pfile, _cpp_file *file,
+ bool *invalid_pch);
+static bool find_file_in_dir (cpp_reader *pfile, _cpp_file *file,
+ bool *invalid_pch);
+static bool read_file_guts (cpp_reader *pfile, _cpp_file *file);
+static bool read_file (cpp_reader *pfile, _cpp_file *file);
+static bool should_stack_file (cpp_reader *, _cpp_file *file, bool import);
+static struct cpp_dir *search_path_head (cpp_reader *, const char *fname,
+ int angle_brackets, enum include_type);
+static const char *dir_name_of_file (_cpp_file *file);
+static void open_file_failed (cpp_reader *pfile, _cpp_file *file);
+static struct file_hash_entry *search_cache (struct file_hash_entry *head,
+ const cpp_dir *start_dir);
+static _cpp_file *make_cpp_file (cpp_reader *, cpp_dir *, const char *fname);
+static cpp_dir *make_cpp_dir (cpp_reader *, const char *dir_name, int sysp);
+static void allocate_file_hash_entries (cpp_reader *pfile);
+static struct file_hash_entry *new_file_hash_entry (cpp_reader *pfile);
+static int report_missing_guard (void **slot, void *b);
+static hashval_t file_hash_hash (const void *p);
+static int file_hash_eq (const void *p, const void *q);
+static char *read_filename_string (int ch, FILE *f);
+static void read_name_map (cpp_dir *dir);
+static char *remap_filename (cpp_reader *pfile, _cpp_file *file);
+static char *append_file_to_dir (const char *fname, cpp_dir *dir);
+static bool validate_pch (cpp_reader *, _cpp_file *file, const char *pchname);
+static bool include_pch_p (_cpp_file *file);
+
+/* Given a filename in FILE->PATH, with the empty string interpreted
+ as <stdin>, open it.
+
+ On success FILE contains an open file descriptor and stat
+ information for the file. On failure the file descriptor is -1 and
+ the appropriate errno is also stored in FILE. Returns TRUE iff
+ successful.
+
+ We used to open files in nonblocking mode, but that caused more
+ problems than it solved. Do take care not to acquire a controlling
+ terminal by mistake (this can't happen on sane systems, but
+ paranoia is a virtue).
+
+ Use the three-argument form of open even though we aren't
+ specifying O_CREAT, to defend against broken system headers.
+
+ O_BINARY tells some runtime libraries (notably DJGPP) not to do
+ newline translation; we can handle DOS line breaks just fine
+ ourselves. */
+static bool
+open_file (_cpp_file *file)
+{
+ if (file->path[0] == '\0')
{
file->fd = 0;
-#ifdef __DJGPP__
- /* For DJGPP redirected input is opened in text mode. Change it
- to binary mode. */
- if (! isatty (file->fd))
- setmode (file->fd, O_BINARY);
-#endif
+ set_stdin_to_binary_mode ();
}
else
- file->fd = open (file->name, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
+ file->fd = open (file->path, O_RDONLY | O_NOCTTY | O_BINARY, 0666);
- if (file->fd != -1 && fstat (file->fd, &file->st) == 0)
+ if (file->fd != -1)
{
- if (!S_ISDIR (file->st.st_mode))
- return file;
+ if (fstat (file->fd, &file->st) == 0)
+ {
+ if (!S_ISDIR (file->st.st_mode))
+ {
+ file->err_no = 0;
+ return true;
+ }
+
+ /* Ignore a directory and continue the search. The file we're
+ looking for may be elsewhere in the search path. */
+ errno = ENOENT;
+ }
- /* If it's a directory, we return null and continue the search
- as the file we're looking for may appear elsewhere in the
- search path. */
- errno = ENOENT;
close (file->fd);
file->fd = -1;
}
+ else if (errno == ENOTDIR)
+ errno = ENOENT;
file->err_no = errno;
- return 0;
+
+ return false;
}
-/* Place the file referenced by INC into a new buffer on the buffer
- stack, unless there are errors, or the file is not re-included
- because of e.g. multiple-include guards. Returns true if a buffer
- is stacked. */
+/* Temporary PCH intercept of opening a file. Try to find a PCH file
+ based on FILE->name and FILE->dir, and test those found for
+ validity using PFILE->cb.valid_pch. Return true iff a valid file is
+ found. Set *INVALID_PCH if a PCH file is found but wasn't valid. */
+
static bool
-stack_include_file (pfile, inc)
- cpp_reader *pfile;
- struct include_file *inc;
+pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
{
- cpp_buffer *fp;
- int sysp;
- const char *filename;
-
- if (DO_NOT_REREAD (inc))
+ static const char extension[] = ".gch";
+ const char *path = file->path;
+ size_t len, flen;
+ char *pchname;
+ struct stat st;
+ bool valid = false;
+
+ /* No PCH on <stdin> or if not requested. */
+ if (file->name[0] == '\0' || !pfile->cb.valid_pch)
return false;
- sysp = MAX ((pfile->map ? pfile->map->sysp : 0),
- (inc->foundhere ? inc->foundhere->sysp : 0));
+ flen = strlen (path);
+ len = flen + sizeof (extension);
+ pchname = xmalloc (len);
+ memcpy (pchname, path, flen);
+ memcpy (pchname + flen, extension, sizeof (extension));
- /* Add the file to the dependencies on its first inclusion. */
- if (CPP_OPTION (pfile, deps.style) > !!sysp && !inc->include_count)
+ if (stat (pchname, &st) == 0)
{
- if (pfile->buffer || CPP_OPTION (pfile, deps.ignore_main_file) == 0)
- deps_add_dep (pfile->deps, inc->name);
- }
+ DIR *pchdir;
+ struct dirent *d;
+ size_t dlen, plen = len;
- /* Not in cache? */
- if (! inc->buffer)
- {
- if (read_include_file (pfile, inc))
+ if (!S_ISDIR (st.st_mode))
+ valid = validate_pch (pfile, file, pchname);
+ else if ((pchdir = opendir (pchname)) != NULL)
{
- /* If an error occurs, do not try to read this file again. */
- _cpp_never_reread (inc);
- return false;
+ pchname[plen - 1] = '/';
+ while ((d = readdir (pchdir)) != NULL)
+ {
+ dlen = strlen (d->d_name) + 1;
+ if ((strcmp (d->d_name, ".") == 0)
+ || (strcmp (d->d_name, "..") == 0))
+ continue;
+ if (dlen + plen > len)
+ {
+ len += dlen + 64;
+ pchname = xrealloc (pchname, len);
+ }
+ memcpy (pchname + plen, d->d_name, dlen);
+ valid = validate_pch (pfile, file, pchname);
+ if (valid)
+ break;
+ }
+ closedir (pchdir);
}
- /* Mark a regular, zero-length file never-reread. We read it,
- NUL-terminate it, and stack it once, so preprocessing a main
- file of zero length does not raise an error. */
- if (S_ISREG (inc->st.st_mode) && inc->st.st_size == 0)
- _cpp_never_reread (inc);
- close (inc->fd);
- inc->fd = -1;
+ if (valid)
+ file->pch = true;
+ else
+ *invalid_pch = true;
}
- if (pfile->buffer)
- /* We don't want MI guard advice for the main file. */
- inc->include_count++;
+ if (valid)
+ file->pchname = pchname;
+ else
+ free (pchname);
- /* Push a buffer. */
- fp = cpp_push_buffer (pfile, inc->buffer, inc->st.st_size,
- /* from_stage3 */ CPP_OPTION (pfile, preprocessed), 0);
- fp->inc = inc;
- fp->inc->refcnt++;
+ return valid;
+}
- /* Initialize controlling macro state. */
- pfile->mi_valid = true;
- pfile->mi_cmacro = 0;
+/* Try to open the path FILE->name appended to FILE->dir. This is
+ where remap and PCH intercept the file lookup process. Return true
+ if the file was found, whether or not the open was successful.
+ Set *INVALID_PCH to true if a PCH file is found but wasn't valid. */
- /* Generate the call back. */
- filename = inc->name;
- if (*filename == '\0')
- filename = "<stdin>";
- _cpp_do_file_change (pfile, LC_ENTER, filename, 1, sysp);
+static bool
+find_file_in_dir (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
+{
+ char *path;
- return true;
+ if (CPP_OPTION (pfile, remap) && (path = remap_filename (pfile, file)))
+ ;
+ else
+ path = append_file_to_dir (file->name, file->dir);
+
+ file->path = path;
+ if (pch_open_file (pfile, file, invalid_pch))
+ return true;
+
+ if (open_file (file))
+ return true;
+
+ if (file->err_no != ENOENT)
+ {
+ open_file_failed (pfile, file);
+ return true;
+ }
+
+ free (path);
+ file->path = file->name;
+ return false;
}
-/* Read the file referenced by INC into the file cache.
+bool
+_cpp_find_failed (_cpp_file *file)
+{
+ return file->err_no != 0;
+}
+
+/* Given a filename FNAME search for such a file in the include path
+ starting from START_DIR. If FNAME is the empty string it is
+ interpreted as STDIN if START_DIR is PFILE->no_seach_path.
+
+ If the file is not found in the file cache fall back to the O/S and
+ add the result to our cache.
+
+ If the file was not found in the filesystem, or there was an error
+ opening it, then ERR_NO is nonzero and FD is -1. If the file was
+ found, then ERR_NO is zero and FD could be -1 or an open file
+ descriptor. FD can be -1 if the file was found in the cache and
+ had previously been closed. To open it again pass the return value
+ to open_file().
+*/
+_cpp_file *
+_cpp_find_file (cpp_reader *pfile, const char *fname, cpp_dir *start_dir, bool fake)
+{
+ struct file_hash_entry *entry, **hash_slot;
+ _cpp_file *file;
+ bool invalid_pch = false;
+
+ /* Ensure we get no confusion between cached files and directories. */
+ if (start_dir == NULL)
+ cpp_error (pfile, CPP_DL_ICE, "NULL directory in find_file");
+
+ hash_slot = (struct file_hash_entry **)
+ htab_find_slot_with_hash (pfile->file_hash, fname,
+ htab_hash_string (fname),
+ INSERT);
+
+ /* First check the cache before we resort to memory allocation. */
+ entry = search_cache (*hash_slot, start_dir);
+ if (entry)
+ return entry->u.file;
- If fd points to a plain file, we might be able to mmap it; we can
- definitely allocate the buffer all at once. If fd is a pipe or
- terminal, we can't do either. If fd is something weird, like a
- block device, we don't want to read it at all.
+ file = make_cpp_file (pfile, start_dir, fname);
- Unfortunately, different systems use different st.st_mode values
- for pipes: some have S_ISFIFO, some S_ISSOCK, some are buggy and
- zero the entire struct stat except a couple fields. Hence we don't
- even try to figure out what something is, except for plain files
- and block devices.
+ /* Try each path in the include chain. */
+ for (; !fake ;)
+ {
+ if (find_file_in_dir (pfile, file, &invalid_pch))
+ break;
+
+ file->dir = file->dir->next;
+ if (file->dir == NULL)
+ {
+ open_file_failed (pfile, file);
+ if (invalid_pch)
+ {
+ cpp_error (pfile, CPP_DL_ERROR,
+ "one or more PCH files were found, but they were invalid");
+ if (!cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_ERROR,
+ "use -Winvalid-pch for more information");
+ }
+ break;
+ }
+
+ /* Only check the cache for the starting location (done above)
+ and the quote and bracket chain heads because there are no
+ other possible starting points for searches. */
+ if (file->dir != pfile->bracket_include
+ && file->dir != pfile->quote_include)
+ continue;
+
+ entry = search_cache (*hash_slot, file->dir);
+ if (entry)
+ break;
+ }
+
+ if (entry)
+ {
+ /* Cache for START_DIR too, sharing the _cpp_file structure. */
+ free ((char *) file->name);
+ free (file);
+ file = entry->u.file;
+ }
+ else
+ {
+ /* This is a new file; put it in the list. */
+ file->next_file = pfile->all_files;
+ pfile->all_files = file;
+ }
+
+ /* Store this new result in the hash table. */
+ entry = new_file_hash_entry (pfile);
+ entry->next = *hash_slot;
+ entry->start_dir = start_dir;
+ entry->u.file = file;
+ *hash_slot = entry;
+
+ return file;
+}
+
+/* Read a file into FILE->buffer, returning true on success.
+
+ If FILE->fd is something weird, like a block device, we don't want
+ to read it at all. Don't even try to figure out what something is,
+ except for plain files and block devices, since there is no
+ reliable portable way of doing this.
FIXME: Flush file cache and try again if we run out of memory. */
-static int
-read_include_file (pfile, inc)
- cpp_reader *pfile;
- struct include_file *inc;
+static bool
+read_file_guts (cpp_reader *pfile, _cpp_file *file)
{
- ssize_t size, offset, count;
+ ssize_t size, total, count;
uchar *buf;
-#if MMAP_THRESHOLD
- static int pagesize = -1;
-#endif
+ bool regular;
+
+ if (S_ISBLK (file->st.st_mode))
+ {
+ cpp_error (pfile, CPP_DL_ERROR, "%s is a block device", file->path);
+ return false;
+ }
- if (S_ISREG (inc->st.st_mode))
+ regular = S_ISREG (file->st.st_mode);
+ if (regular)
{
/* off_t might have a wider range than ssize_t - in other words,
the max size of a file might be bigger than the address
@@ -406,231 +470,455 @@ read_include_file (pfile, inc)
SSIZE_MAX to be much smaller than the actual range of the
type. Use INTTYPE_MAXIMUM unconditionally to ensure this
does not bite us. */
- if (inc->st.st_size > INTTYPE_MAXIMUM (ssize_t))
+ if (file->st.st_size > INTTYPE_MAXIMUM (ssize_t))
{
- cpp_error (pfile, DL_ERROR, "%s is too large", inc->name);
- goto fail;
+ cpp_error (pfile, CPP_DL_ERROR, "%s is too large", file->path);
+ return false;
}
- size = inc->st.st_size;
-
- inc->mapped = 0;
-#if MMAP_THRESHOLD
- if (pagesize == -1)
- pagesize = getpagesize ();
-
- if (SHOULD_MMAP (size, pagesize))
- {
- buf = (uchar *) mmap (0, size, PROT_READ, MAP_PRIVATE, inc->fd, 0);
- if (buf == (uchar *) -1)
- goto perror_fail;
- /* We must tell Valgrind that the byte at buf[size] is actually
- readable. Discard the handle to avoid handle leak. */
- VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (buf + size, 1));
-
- inc->mapped = 1;
- }
- else
-#endif
- {
- buf = (uchar *) xmalloc (size + 1);
- offset = 0;
- while (offset < size)
- {
- count = read (inc->fd, buf + offset, size - offset);
- if (count < 0)
- goto perror_fail;
- if (count == 0)
- {
- if (!STAT_SIZE_TOO_BIG (inc->st))
- cpp_error (pfile, DL_WARNING,
- "%s is shorter than expected", inc->name);
- size = offset;
- buf = xrealloc (buf, size + 1);
- inc->st.st_size = size;
- break;
- }
- offset += count;
- }
- /* The lexer requires that the buffer be NUL-terminated. */
- buf[size] = '\0';
- }
- }
- else if (S_ISBLK (inc->st.st_mode))
- {
- cpp_error (pfile, DL_ERROR, "%s is a block device", inc->name);
- goto fail;
+ size = file->st.st_size;
}
else
+ /* 8 kilobytes is a sensible starting size. It ought to be bigger
+ than the kernel pipe buffer, and it's definitely bigger than
+ the majority of C source files. */
+ size = 8 * 1024;
+
+ buf = xmalloc (size + 1);
+ total = 0;
+ while ((count = read (file->fd, buf + total, size - total)) > 0)
{
- /* 8 kilobytes is a sensible starting size. It ought to be
- bigger than the kernel pipe buffer, and it's definitely
- bigger than the majority of C source files. */
- size = 8 * 1024;
-
- buf = (uchar *) xmalloc (size + 1);
- offset = 0;
- while ((count = read (inc->fd, buf + offset, size - offset)) > 0)
+ total += count;
+
+ if (total == size)
{
- offset += count;
- if (offset == size)
- {
- size *= 2;
- buf = xrealloc (buf, size + 1);
- }
+ if (regular)
+ break;
+ size *= 2;
+ buf = xrealloc (buf, size + 1);
}
- if (count < 0)
- goto perror_fail;
-
- if (offset + 1 < size)
- buf = xrealloc (buf, offset + 1);
+ }
- /* The lexer requires that the buffer be NUL-terminated. */
- buf[offset] = '\0';
- inc->st.st_size = offset;
+ if (count < 0)
+ {
+ cpp_errno (pfile, CPP_DL_ERROR, file->path);
+ return false;
}
- inc->buffer = buf;
- return 0;
+ if (regular && total != size && STAT_SIZE_RELIABLE (file->st))
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s is shorter than expected", file->path);
+
+ file->buffer = _cpp_convert_input (pfile, CPP_OPTION (pfile, input_charset),
+ buf, size, total, &file->st.st_size);
+ file->buffer_valid = true;
- perror_fail:
- cpp_errno (pfile, DL_ERROR, inc->name);
- fail:
- return 1;
+ return true;
}
-/* Drop INC's buffer from memory, if we are unlikely to need it again. */
-static void
-purge_cache (inc)
- struct include_file *inc;
+/* Convenience wrapper around read_file_guts that opens the file if
+ necessary and closes the file descriptor after reading. FILE must
+ have been passed through find_file() at some stage. */
+static bool
+read_file (cpp_reader *pfile, _cpp_file *file)
{
- if (inc->buffer)
+ /* If we already have its contents in memory, succeed immediately. */
+ if (file->buffer_valid)
+ return true;
+
+ /* If an earlier read failed for some reason don't try again. */
+ if (file->dont_read || file->err_no)
+ return false;
+
+ if (file->fd == -1 && !open_file (file))
{
-#if MMAP_THRESHOLD
- if (inc->mapped)
- {
- /* Undo the previous annotation for the
- known-zero-byte-after-mmap. Discard the handle to avoid
- handle leak. */
- VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS (inc->buffer
- + inc->st.st_size, 1));
- munmap ((PTR) inc->buffer, inc->st.st_size);
- }
- else
-#endif
- free ((PTR) inc->buffer);
- inc->buffer = NULL;
+ open_file_failed (pfile, file);
+ return false;
}
+
+ file->dont_read = !read_file_guts (pfile, file);
+ close (file->fd);
+ file->fd = -1;
+
+ return !file->dont_read;
}
-/* Return 1 if the file named by FNAME has been included before in
- any context, 0 otherwise. */
-int
-cpp_included (pfile, fname)
- cpp_reader *pfile;
- const char *fname;
+/* Returns TRUE if FILE's contents have been successfully placed in
+ FILE->buffer and the file should be stacked, otherwise false. */
+static bool
+should_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
{
- struct search_path *path;
- char *name, *n;
- splay_tree_node nd;
+ _cpp_file *f;
- if (IS_ABSOLUTE_PATHNAME (fname))
+ /* Skip once-only files. */
+ if (file->once_only)
+ return false;
+
+ /* We must mark the file once-only if #import now, before header
+ guard checks. Otherwise, undefining the header guard might
+ cause the file to be re-stacked. */
+ if (import)
{
- /* Just look it up. */
- nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) fname);
- return (nd && nd->value);
+ _cpp_mark_file_once_only (pfile, file);
+
+ /* Don't stack files that have been stacked before. */
+ if (file->stack_count)
+ return false;
}
- /* Search directory path for the file. */
- name = (char *) alloca (strlen (fname) + pfile->max_include_len + 2);
- for (path = CPP_OPTION (pfile, quote_include); path; path = path->next)
+ /* Skip if the file had a header guard and the macro is defined.
+ PCH relies on this appearing before the PCH handler below. */
+ if (file->cmacro && file->cmacro->type == NT_MACRO)
+ return false;
+
+ /* Handle PCH files immediately; don't stack them. */
+ if (include_pch_p (file))
{
- memcpy (name, path->name, path->len);
- name[path->len] = '/';
- strcpy (&name[path->len + 1], fname);
- if (CPP_OPTION (pfile, remap))
- n = remap_filename (pfile, name, path);
- else
- n = name;
+ pfile->cb.read_pch (pfile, file->path, file->fd, file->pchname);
+ close (file->fd);
+ file->fd = -1;
+ return false;
+ }
+
+ if (!read_file (pfile, file))
+ return false;
+
+ /* Now we've read the file's contents, we can stack it if there
+ are no once-only files. */
+ if (!pfile->seen_once_only)
+ return true;
- nd = splay_tree_lookup (pfile->all_include_files, (splay_tree_key) n);
- if (nd && nd->value)
- return 1;
+ /* We may have read the file under a different name. Look
+ for likely candidates and compare file contents to be sure. */
+ for (f = pfile->all_files; f; f = f->next_file)
+ {
+ if (f == file)
+ continue;
+
+ if ((import || f->once_only)
+ && f->err_no == 0
+ && f->st.st_mtime == file->st.st_mtime
+ && f->st.st_size == file->st.st_size
+ && read_file (pfile, f)
+ /* Size might have changed in read_file(). */
+ && f->st.st_size == file->st.st_size
+ && !memcmp (f->buffer, file->buffer, f->st.st_size))
+ break;
}
- return 0;
+
+ return f == NULL;
+}
+
+/* Place the file referenced by FILE into a new buffer on the buffer
+ stack if possible. IMPORT is true if this stacking attempt is
+ because of a #import directive. Returns true if a buffer is
+ stacked. */
+bool
+_cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import)
+{
+ cpp_buffer *buffer;
+ int sysp;
+
+ if (!should_stack_file (pfile, file, import))
+ return false;
+
+ sysp = MAX ((pfile->map ? pfile->map->sysp : 0),
+ (file->dir ? file->dir->sysp : 0));
+
+ /* Add the file to the dependencies on its first inclusion. */
+ if (CPP_OPTION (pfile, deps.style) > !!sysp && !file->stack_count)
+ {
+ if (!file->main_file || !CPP_OPTION (pfile, deps.ignore_main_file))
+ deps_add_dep (pfile->deps, file->path);
+ }
+
+ /* Clear buffer_valid since _cpp_clean_line messes it up. */
+ file->buffer_valid = false;
+ file->stack_count++;
+
+ /* Stack the buffer. */
+ buffer = cpp_push_buffer (pfile, file->buffer, file->st.st_size,
+ CPP_OPTION (pfile, preprocessed));
+ buffer->file = file;
+
+ /* Initialize controlling macro state. */
+ pfile->mi_valid = true;
+ pfile->mi_cmacro = 0;
+
+ /* Generate the call back. */
+ _cpp_do_file_change (pfile, LC_ENTER, file->path, 1, sysp);
+
+ return true;
+}
+
+/* Mark FILE to be included once only. */
+void
+_cpp_mark_file_once_only (cpp_reader *pfile, _cpp_file *file)
+{
+ pfile->seen_once_only = true;
+ file->once_only = true;
}
-/* Search for HEADER. Return 0 if there is no such file (or it's
- un-openable), in which case an error code will be in errno. If
- there is no include path to use it returns NO_INCLUDE_PATH,
- otherwise an include_file structure. If this request originates
- from a directive of TYPE #include_next, set INCLUDE_NEXT to true. */
-static struct include_file *
-find_include_file (pfile, header, type)
- cpp_reader *pfile;
- const cpp_token *header;
- enum include_type type;
+/* Return the directory from which searching for FNAME should start,
+ considering the directive TYPE and ANGLE_BRACKETS. If there is
+ nothing left in the path, returns NULL. */
+static struct cpp_dir *
+search_path_head (cpp_reader *pfile, const char *fname, int angle_brackets,
+ enum include_type type)
{
- const char *fname = (const char *) header->val.str.text;
- struct search_path *path;
- struct include_file *file;
- char *name, *n;
+ cpp_dir *dir;
+ _cpp_file *file;
- if (IS_ABSOLUTE_PATHNAME (fname))
- return open_file (pfile, fname);
+ if (IS_ABSOLUTE_PATH (fname))
+ return &pfile->no_search_path;
+
+ /* pfile->buffer is NULL when processing an -include command-line flag. */
+ file = pfile->buffer == NULL ? pfile->main_file : pfile->buffer->file;
/* For #include_next, skip in the search path past the dir in which
the current file was found, but if it was found via an absolute
path use the normal search logic. */
- if (type == IT_INCLUDE_NEXT && pfile->buffer->inc->foundhere)
- path = pfile->buffer->inc->foundhere->next;
- else if (header->type == CPP_HEADER_NAME)
- path = CPP_OPTION (pfile, bracket_include);
+ if (type == IT_INCLUDE_NEXT && file->dir)
+ dir = file->dir->next;
+ else if (angle_brackets)
+ dir = pfile->bracket_include;
+ else if (type == IT_CMDLINE)
+ /* -include and -imacros use the #include "" chain with the
+ preprocessor's cwd prepended. */
+ return make_cpp_dir (pfile, "./", false);
+ else if (pfile->quote_ignores_source_dir)
+ dir = pfile->quote_include;
else
- path = search_from (pfile, type);
+ return make_cpp_dir (pfile, dir_name_of_file (file), pfile->map->sysp);
+
+ if (dir == NULL)
+ cpp_error (pfile, CPP_DL_ERROR,
+ "no include path in which to search for %s", fname);
+
+ return dir;
+}
- if (path == NULL)
+/* Strip the basename from the file's path. It ends with a slash if
+ of nonzero length. Note that this procedure also works for
+ <stdin>, which is represented by the empty string. */
+static const char *
+dir_name_of_file (_cpp_file *file)
+{
+ if (!file->dir_name)
{
- cpp_error (pfile, DL_ERROR, "no include path in which to find %s",
- fname);
- return NO_INCLUDE_PATH;
+ size_t len = lbasename (file->path) - file->path;
+ char *dir_name = xmalloc (len + 1);
+
+ memcpy (dir_name, file->path, len);
+ dir_name[len] = '\0';
+ file->dir_name = dir_name;
}
- /* Search directory path for the file. */
- name = (char *) alloca (strlen (fname) + pfile->max_include_len + 2);
- for (; path; path = path->next)
+ return file->dir_name;
+}
+
+/* Handles #include-family directives (distinguished by TYPE),
+ including HEADER, and the command line -imacros and -include.
+ Returns true if a buffer was stacked. */
+bool
+_cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
+ enum include_type type)
+{
+ struct cpp_dir *dir;
+
+ dir = search_path_head (pfile, fname, angle_brackets, type);
+ if (!dir)
+ return false;
+
+ return _cpp_stack_file (pfile, _cpp_find_file (pfile, fname, dir, false),
+ type == IT_IMPORT);
+}
+
+/* Could not open FILE. The complication is dependency output. */
+static void
+open_file_failed (cpp_reader *pfile, _cpp_file *file)
+{
+ int sysp = pfile->map ? pfile->map->sysp: 0;
+ bool print_dep = CPP_OPTION (pfile, deps.style) > !!sysp;
+
+ errno = file->err_no;
+ if (print_dep && CPP_OPTION (pfile, deps.missing_files) && errno == ENOENT)
+ deps_add_dep (pfile->deps, file->name);
+ else
{
- int len = path->len;
- memcpy (name, path->name, len);
- /* Don't turn / into // or // into ///; // may be a namespace
- escape. */
- if (name[len-1] == '/')
- len--;
- name[len] = '/';
- strcpy (&name[len + 1], fname);
- if (CPP_OPTION (pfile, remap))
- n = remap_filename (pfile, name, path);
+ /* If we are outputting dependencies but not for this file then
+ don't error because we can still produce correct output. */
+ if (CPP_OPTION (pfile, deps.style) && ! print_dep)
+ cpp_errno (pfile, CPP_DL_WARNING, file->path);
else
- n = name;
-
- file = open_file (pfile, n);
- if (file)
- {
- file->foundhere = path;
- return file;
- }
+ cpp_errno (pfile, CPP_DL_ERROR, file->path);
}
+}
- return 0;
+/* Search in the chain beginning at HEAD for a file whose search path
+ started at START_DIR != NULL. */
+static struct file_hash_entry *
+search_cache (struct file_hash_entry *head, const cpp_dir *start_dir)
+{
+ while (head && head->start_dir != start_dir)
+ head = head->next;
+
+ return head;
+}
+
+/* Allocate a new _cpp_file structure. */
+static _cpp_file *
+make_cpp_file (cpp_reader *pfile, cpp_dir *dir, const char *fname)
+{
+ _cpp_file *file;
+
+ file = xcalloc (1, sizeof (_cpp_file));
+ file->main_file = !pfile->buffer;
+ file->fd = -1;
+ file->dir = dir;
+ file->name = xstrdup (fname);
+
+ return file;
+}
+
+/* A hash of directory names. The directory names are the path names
+ of files which contain a #include "", the included file name is
+ appended to this directories.
+
+ To avoid duplicate entries we follow the convention that all
+ non-empty directory names should end in a '/'. DIR_NAME must be
+ stored in permanently allocated memory. */
+static cpp_dir *
+make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp)
+{
+ struct file_hash_entry *entry, **hash_slot;
+ cpp_dir *dir;
+
+ hash_slot = (struct file_hash_entry **)
+ htab_find_slot_with_hash (pfile->dir_hash, dir_name,
+ htab_hash_string (dir_name),
+ INSERT);
+
+ /* Have we already hashed this directory? */
+ for (entry = *hash_slot; entry; entry = entry->next)
+ if (entry->start_dir == NULL)
+ return entry->u.dir;
+
+ dir = xcalloc (1, sizeof (cpp_dir));
+ dir->next = pfile->quote_include;
+ dir->name = (char *) dir_name;
+ dir->len = strlen (dir_name);
+ dir->sysp = sysp;
+
+ /* Store this new result in the hash table. */
+ entry = new_file_hash_entry (pfile);
+ entry->next = *hash_slot;
+ entry->start_dir = NULL;
+ entry->u.dir = dir;
+ *hash_slot = entry;
+
+ return dir;
+}
+
+/* Create a new block of memory for file hash entries. */
+static void
+allocate_file_hash_entries (cpp_reader *pfile)
+{
+ pfile->file_hash_entries_used = 0;
+ pfile->file_hash_entries_allocated = 127;
+ pfile->file_hash_entries = xmalloc
+ (pfile->file_hash_entries_allocated * sizeof (struct file_hash_entry));
+}
+
+/* Return a new file hash entry. */
+static struct file_hash_entry *
+new_file_hash_entry (cpp_reader *pfile)
+{
+ if (pfile->file_hash_entries_used == pfile->file_hash_entries_allocated)
+ allocate_file_hash_entries (pfile);
+
+ return &pfile->file_hash_entries[pfile->file_hash_entries_used++];
+}
+
+/* Returns TRUE if a file FNAME has ever been successfully opened.
+ This routine is not intended to correctly handle filenames aliased
+ by links or redundant . or .. traversals etc. */
+bool
+cpp_included (cpp_reader *pfile, const char *fname)
+{
+ struct file_hash_entry *entry;
+
+ entry = htab_find_with_hash (pfile->file_hash, fname,
+ htab_hash_string (fname));
+
+ while (entry && (entry->start_dir == NULL || entry->u.file->err_no))
+ entry = entry->next;
+
+ return entry != NULL;
+}
+
+/* Calculate the hash value of a file hash entry P. */
+
+static hashval_t
+file_hash_hash (const void *p)
+{
+ struct file_hash_entry *entry = (struct file_hash_entry *) p;
+ const char *hname;
+ if (entry->start_dir)
+ hname = entry->u.file->name;
+ else
+ hname = entry->u.dir->name;
+
+ return htab_hash_string (hname);
+}
+
+/* Compare a string Q against a file hash entry P. */
+static int
+file_hash_eq (const void *p, const void *q)
+{
+ struct file_hash_entry *entry = (struct file_hash_entry *) p;
+ const char *fname = (const char *) q;
+ const char *hname;
+
+ if (entry->start_dir)
+ hname = entry->u.file->name;
+ else
+ hname = entry->u.dir->name;
+
+ return strcmp (hname, fname) == 0;
+}
+
+/* Initialize everything in this source file. */
+void
+_cpp_init_files (cpp_reader *pfile)
+{
+ pfile->file_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
+ NULL, xcalloc, free);
+ pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq,
+ NULL, xcalloc, free);
+ allocate_file_hash_entries (pfile);
+}
+
+/* Finalize everything in this source file. */
+void
+_cpp_cleanup_files (cpp_reader *pfile)
+{
+ htab_delete (pfile->file_hash);
+ htab_delete (pfile->dir_hash);
+}
+
+/* Enter a file name in the hash for the sake of cpp_included. */
+void
+_cpp_fake_include (cpp_reader *pfile, const char *fname)
+{
+ _cpp_find_file (pfile, fname, pfile->buffer->file->dir, true);
}
/* Not everyone who wants to set system-header-ness on a buffer can
see the details of a buffer. This is an exported interface because
fix-header needs it. */
void
-cpp_make_system_header (pfile, syshdr, externc)
- cpp_reader *pfile;
- int syshdr, externc;
+cpp_make_system_header (cpp_reader *pfile, int syshdr, int externc)
{
int flags = 0;
@@ -641,226 +929,158 @@ cpp_make_system_header (pfile, syshdr, externc)
SOURCE_LINE (pfile->map, pfile->line), flags);
}
-/* Report on all files that might benefit from a multiple include guard.
- Triggered by -H. */
+/* Allow the client to change the current file. Used by the front end
+ to achieve pseudo-file names like <built-in>.
+ If REASON is LC_LEAVE, then NEW_NAME must be NULL. */
void
-_cpp_report_missing_guards (pfile)
- cpp_reader *pfile;
+cpp_change_file (cpp_reader *pfile, enum lc_reason reason,
+ const char *new_name)
{
- int banner = 0;
- splay_tree_foreach (pfile->all_include_files, report_missing_guard,
- (PTR) &banner);
+ _cpp_do_file_change (pfile, reason, new_name, 1, 0);
}
-/* Callback function for splay_tree_foreach(). */
+/* Callback function for htab_traverse. */
static int
-report_missing_guard (n, b)
- splay_tree_node n;
- void *b;
+report_missing_guard (void **slot, void *b)
{
- struct include_file *f = (struct include_file *) n->value;
+ struct file_hash_entry *entry = (struct file_hash_entry *) *slot;
int *bannerp = (int *) b;
- if (f && f->cmacro == 0 && f->include_count == 1)
+ /* Skip directories. */
+ if (entry->start_dir != NULL)
{
- if (*bannerp == 0)
+ _cpp_file *file = entry->u.file;
+
+ /* We don't want MI guard advice for the main file. */
+ if (file->cmacro == NULL && file->stack_count == 1 && !file->main_file)
{
- fputs (_("Multiple include guards may be useful for:\n"), stderr);
- *bannerp = 1;
+ if (*bannerp == 0)
+ {
+ fputs (_("Multiple include guards may be useful for:\n"),
+ stderr);
+ *bannerp = 1;
+ }
+
+ fputs (entry->u.file->path, stderr);
+ putc ('\n', stderr);
}
- fputs (f->name, stderr);
- putc ('\n', stderr);
}
- return 0;
-}
-/* Create a dependency for file FNAME, or issue an error message as
- appropriate. ANGLE_BRACKETS is nonzero if the file was bracketed
- like <..>. */
-static void
-handle_missing_header (pfile, fname, angle_brackets)
- cpp_reader *pfile;
- const char *fname;
- int angle_brackets;
-{
- bool print_dep
- = CPP_OPTION (pfile, deps.style) > (angle_brackets || pfile->map->sysp);
-
- if (CPP_OPTION (pfile, deps.missing_files) && print_dep)
- deps_add_dep (pfile->deps, fname);
- /* If -M was specified, then don't count this as an error, because
- we can still produce correct output. Otherwise, we can't produce
- correct output, because there may be dependencies we need inside
- the missing file, and we don't know what directory this missing
- file exists in. */
- else
- cpp_errno (pfile, CPP_OPTION (pfile, deps.style) && ! print_dep
- ? DL_WARNING: DL_ERROR, fname);
+ return 0;
}
-/* Handles #include-family directives (distinguished by TYPE),
- including HEADER, and the command line -imacros and -include.
- Returns true if a buffer was stacked. */
-bool
-_cpp_execute_include (pfile, header, type)
- cpp_reader *pfile;
- const cpp_token *header;
- enum include_type type;
+/* Report on all files that might benefit from a multiple include guard.
+ Triggered by -H. */
+void
+_cpp_report_missing_guards (cpp_reader *pfile)
{
- bool stacked = false;
- struct include_file *inc = find_include_file (pfile, header, type);
-
- if (inc == 0)
- handle_missing_header (pfile, (const char *) header->val.str.text,
- header->type == CPP_HEADER_NAME);
- else if (inc != NO_INCLUDE_PATH)
- {
- stacked = stack_include_file (pfile, inc);
-
- if (type == IT_IMPORT)
- _cpp_never_reread (inc);
- }
+ int banner = 0;
- return stacked;
+ htab_traverse (pfile->file_hash, report_missing_guard, &banner);
}
/* Locate HEADER, and determine whether it is newer than the current
- file. If it cannot be located or dated, return -1, if it is newer
+ file. If it cannot be located or dated, return -1, if it is
newer, return 1, otherwise 0. */
int
-_cpp_compare_file_date (pfile, header)
- cpp_reader *pfile;
- const cpp_token *header;
+_cpp_compare_file_date (cpp_reader *pfile, const char *fname,
+ int angle_brackets)
{
- struct include_file *inc = find_include_file (pfile, header, 0);
+ _cpp_file *file;
+ struct cpp_dir *dir;
+
+ dir = search_path_head (pfile, fname, angle_brackets, IT_INCLUDE);
+ if (!dir)
+ return -1;
- if (inc == NULL || inc == NO_INCLUDE_PATH)
+ file = _cpp_find_file (pfile, fname, dir, false);
+ if (file->err_no)
return -1;
- if (inc->fd > 0)
+ if (file->fd != -1)
{
- close (inc->fd);
- inc->fd = -1;
+ close (file->fd);
+ file->fd = -1;
}
- return inc->st.st_mtime > pfile->buffer->inc->st.st_mtime;
+ return file->st.st_mtime > pfile->buffer->file->st.st_mtime;
}
-
-/* Push an input buffer and load it up with the contents of FNAME. If
- FNAME is "", read standard input. Return true if a buffer was
- stacked. */
+/* Pushes the given file onto the buffer stack. Returns nonzero if
+ successful. */
bool
-_cpp_read_file (pfile, fname)
- cpp_reader *pfile;
- const char *fname;
+cpp_push_include (cpp_reader *pfile, const char *fname)
{
- struct include_file *f = open_file (pfile, fname);
-
- if (f == NULL)
- {
- cpp_errno (pfile, DL_ERROR, fname);
- return false;
- }
-
- return stack_include_file (pfile, f);
+ /* Make the command line directive take up a line. */
+ pfile->line++;
+ return _cpp_stack_include (pfile, fname, false, IT_CMDLINE);
}
/* Do appropriate cleanup when a file INC's buffer is popped off the
input stack. */
void
-_cpp_pop_file_buffer (pfile, inc)
- cpp_reader *pfile;
- struct include_file *inc;
+_cpp_pop_file_buffer (cpp_reader *pfile, _cpp_file *file)
{
/* Record the inclusion-preventing macro, which could be NULL
meaning no controlling macro. */
- if (pfile->mi_valid && inc->cmacro == NULL)
- inc->cmacro = pfile->mi_cmacro;
+ if (pfile->mi_valid && file->cmacro == NULL)
+ file->cmacro = pfile->mi_cmacro;
/* Invalidate control macros in the #including file. */
pfile->mi_valid = false;
- inc->refcnt--;
- if (inc->refcnt == 0 && DO_NOT_REREAD (inc))
- purge_cache (inc);
+ if (file->buffer)
+ {
+ free ((void *) file->buffer);
+ file->buffer = NULL;
+ }
}
-/* Returns the first place in the include chain to start searching for
- "" includes. This involves stripping away the basename of the
- current file, unless -I- was specified.
+/* Set the include chain for "" to QUOTE, for <> to BRACKET. If
+ QUOTE_IGNORES_SOURCE_DIR, then "" includes do not look in the
+ directory of the including file.
- If we're handling -include or -imacros, use the "" chain, but with
- the preprocessor's cwd prepended. */
-static struct search_path *
-search_from (pfile, type)
- cpp_reader *pfile;
- enum include_type type;
+ If BRACKET does not lie in the QUOTE chain, it is set to QUOTE. */
+void
+cpp_set_include_chains (cpp_reader *pfile, cpp_dir *quote, cpp_dir *bracket,
+ int quote_ignores_source_dir)
{
- cpp_buffer *buffer = pfile->buffer;
- unsigned int dlen;
+ pfile->quote_include = quote;
+ pfile->bracket_include = quote;
+ pfile->quote_ignores_source_dir = quote_ignores_source_dir;
- /* Command line uses the cwd, and does not cache the result. */
- if (type == IT_CMDLINE)
- goto use_cwd;
-
- /* Ignore the current file's directory if -I- was given. */
- if (CPP_OPTION (pfile, ignore_srcdir))
- return CPP_OPTION (pfile, quote_include);
-
- if (! buffer->search_cached)
+ for (; quote; quote = quote->next)
{
- buffer->search_cached = 1;
-
- dlen = lbasename (buffer->inc->name) - buffer->inc->name;
-
- if (dlen)
- {
- /* We don't guarantee NAME is null-terminated. This saves
- allocating and freeing memory. Drop a trailing '/'. */
- buffer->dir.name = buffer->inc->name;
- if (dlen > 1)
- dlen--;
- }
- else
- {
- use_cwd:
- buffer->dir.name = ".";
- dlen = 1;
- }
-
- if (dlen > pfile->max_include_len)
- pfile->max_include_len = dlen;
-
- buffer->dir.len = dlen;
- buffer->dir.next = CPP_OPTION (pfile, quote_include);
- buffer->dir.sysp = pfile->map->sysp;
+ quote->name_map = NULL;
+ quote->len = strlen (quote->name);
+ if (quote == bracket)
+ pfile->bracket_include = bracket;
}
-
- return &buffer->dir;
}
-/* The file_name_map structure holds a mapping of file names for a
- particular directory. This mapping is read from the file named
- FILE_NAME_MAP_FILE in that directory. Such a file can be used to
- map filenames on a file system with severe filename restrictions,
- such as DOS. The format of the file name map file is just a series
- of lines with two tokens on each line. The first token is the name
- to map, and the second token is the actual name to use. */
-struct file_name_map {
- struct file_name_map *map_next;
- char *map_from;
- char *map_to;
-};
+/* Append the file name to the directory to create the path, but don't
+ turn / into // or // into ///; // may be a namespace escape. */
+static char *
+append_file_to_dir (const char *fname, cpp_dir *dir)
+{
+ size_t dlen, flen;
+ char *path;
-#define FILE_NAME_MAP_FILE "header.gcc"
+ dlen = dir->len;
+ flen = strlen (fname);
+ path = xmalloc (dlen + 1 + flen + 1);
+ memcpy (path, dir->name, dlen);
+ if (dlen && path[dlen - 1] != '/')
+ path[dlen++] = '/';
+ memcpy (&path[dlen], fname, flen + 1);
+
+ return path;
+}
/* Read a space delimited string of unlimited length from a stdio
file F. */
static char *
-read_filename_string (ch, f)
- int ch;
- FILE *f;
+read_filename_string (int ch, FILE *f)
{
char *alloc, *set;
int len;
@@ -886,43 +1106,25 @@ read_filename_string (ch, f)
return alloc;
}
-/* This structure holds a linked list of file name maps, one per directory. */
-struct file_name_map_list {
- struct file_name_map_list *map_list_next;
- char *map_list_name;
- struct file_name_map *map_list_map;
-};
-
-/* Read the file name map file for DIRNAME. */
-static struct file_name_map *
-read_name_map (pfile, dirname)
- cpp_reader *pfile;
- const char *dirname;
+/* Read the file name map file for DIR. */
+static void
+read_name_map (cpp_dir *dir)
{
- struct file_name_map_list *map_list_ptr;
+ static const char FILE_NAME_MAP_FILE[] = "header.gcc";
char *name;
FILE *f;
-
- /* Check the cache of directories, and mappings in their remap file. */
- for (map_list_ptr = CPP_OPTION (pfile, map_list); map_list_ptr;
- map_list_ptr = map_list_ptr->map_list_next)
- if (! strcmp (map_list_ptr->map_list_name, dirname))
- return map_list_ptr->map_list_map;
-
- map_list_ptr = ((struct file_name_map_list *)
- xmalloc (sizeof (struct file_name_map_list)));
- map_list_ptr->map_list_name = xstrdup (dirname);
-
- /* The end of the list ends in NULL. */
- map_list_ptr->map_list_map = NULL;
-
- name = (char *) alloca (strlen (dirname) + strlen (FILE_NAME_MAP_FILE) + 2);
- strcpy (name, dirname);
- if (*dirname)
- strcat (name, "/");
- strcat (name, FILE_NAME_MAP_FILE);
+ size_t len, count = 0, room = 9;
+
+ len = dir->len;
+ name = alloca (len + sizeof (FILE_NAME_MAP_FILE) + 1);
+ memcpy (name, dir->name, len);
+ if (len && name[len - 1] != '/')
+ name[len++] = '/';
+ strcpy (name + len, FILE_NAME_MAP_FILE);
f = fopen (name, "r");
+ dir->name_map = xmalloc (room * sizeof (char *));
+
/* Silently return NULL if we cannot open. */
if (f)
{
@@ -930,253 +1132,116 @@ read_name_map (pfile, dirname)
while ((ch = getc (f)) != EOF)
{
- char *from, *to;
- struct file_name_map *ptr;
+ char *to;
if (is_space (ch))
continue;
- from = read_filename_string (ch, f);
+
+ if (count + 2 > room)
+ {
+ room += 8;
+ dir->name_map = xrealloc (dir->name_map, room * sizeof (char *));
+ }
+
+ dir->name_map[count] = read_filename_string (ch, f);
while ((ch = getc (f)) != EOF && is_hspace (ch))
;
- to = read_filename_string (ch, f);
-
- ptr = ((struct file_name_map *)
- xmalloc (sizeof (struct file_name_map)));
- ptr->map_from = from;
- /* Make the real filename absolute. */
- if (IS_ABSOLUTE_PATHNAME (to))
- ptr->map_to = to;
+ to = read_filename_string (ch, f);
+ if (IS_ABSOLUTE_PATH (to))
+ dir->name_map[count + 1] = to;
else
{
- ptr->map_to = concat (dirname, "/", to, NULL);
+ dir->name_map[count + 1] = append_file_to_dir (to, dir);
free (to);
}
- ptr->map_next = map_list_ptr->map_list_map;
- map_list_ptr->map_list_map = ptr;
-
+ count += 2;
while ((ch = getc (f)) != '\n')
if (ch == EOF)
break;
}
+
fclose (f);
}
- /* Add this information to the cache. */
- map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list);
- CPP_OPTION (pfile, map_list) = map_list_ptr;
-
- return map_list_ptr->map_list_map;
+ /* Terminate the list of maps. */
+ dir->name_map[count] = NULL;
}
-/* Remap an unsimplified path NAME based on the file_name_map (if any)
- for LOC. */
+/* Remap a FILE's name based on the file_name_map, if any, for
+ FILE->dir. If the file name has any directory separators,
+ recursively check those directories too. */
static char *
-remap_filename (pfile, name, loc)
- cpp_reader *pfile;
- char *name;
- struct search_path *loc;
+remap_filename (cpp_reader *pfile, _cpp_file *file)
{
- struct file_name_map *map;
- const char *from, *p;
- char *dir;
-
- if (! loc->name_map)
- {
- /* Get a null-terminated path. */
- char *dname = alloca (loc->len + 1);
- memcpy (dname, loc->name, loc->len);
- dname[loc->len] = '\0';
-
- loc->name_map = read_name_map (pfile, dname);
- if (! loc->name_map)
- return name;
- }
-
- /* This works since NAME has not been simplified yet. */
- from = name + loc->len + 1;
+ const char *fname, *p;
+ char *new_dir;
+ cpp_dir *dir;
+ size_t index, len;
- for (map = loc->name_map; map; map = map->map_next)
- if (!strcmp (map->map_from, from))
- return map->map_to;
+ dir = file->dir;
+ fname = file->name;
- /* Try to find a mapping file for the particular directory we are
- looking in. Thus #include <sys/types.h> will look up sys/types.h
- in /usr/include/header.gcc and look up types.h in
- /usr/include/sys/header.gcc. */
- p = strrchr (name, '/');
- if (!p)
- return name;
+ for (;;)
+ {
+ if (!dir->name_map)
+ read_name_map (dir);
- /* We know p != name as absolute paths don't call remap_filename. */
- if (p == name)
- cpp_error (pfile, DL_ICE, "absolute file name in remap_filename");
+ for (index = 0; dir->name_map[index]; index += 2)
+ if (!strcmp (dir->name_map[index], fname))
+ return xstrdup (dir->name_map[index + 1]);
- dir = (char *) alloca (p - name + 1);
- memcpy (dir, name, p - name);
- dir[p - name] = '\0';
- from = p + 1;
+ p = strchr (fname, '/');
+ if (!p || p == fname)
+ return NULL;
- for (map = read_name_map (pfile, dir); map; map = map->map_next)
- if (! strcmp (map->map_from, from))
- return map->map_to;
+ len = dir->len + (p - fname + 1);
+ new_dir = xmalloc (len + 1);
+ memcpy (new_dir, dir->name, dir->len);
+ memcpy (new_dir + dir->len, fname, p - fname + 1);
+ new_dir[len] = '\0';
- return name;
+ dir = make_cpp_dir (pfile, new_dir, dir->sysp);
+ fname = p + 1;
+ }
}
-/* Returns true if it is safe to remove the final component of path,
- when it is followed by a ".." component. We use lstat to avoid
- symlinks if we have it. If not, we can still catch errors with
- stat (). */
-static int
-remove_component_p (path)
- const char *path;
+/* Return true if FILE is usable by PCH. */
+static bool
+include_pch_p (_cpp_file *file)
{
- struct stat s;
- int result;
-
-#ifdef HAVE_LSTAT
- result = lstat (path, &s);
-#else
- result = stat (path, &s);
-#endif
-
- /* There's no guarantee that errno will be unchanged, even on
- success. Cygwin's lstat(), for example, will often set errno to
- ENOSYS. In case of success, reset errno to zero. */
- if (result == 0)
- errno = 0;
-
- return result == 0 && S_ISDIR (s.st_mode);
+ return file->pch & 1;
}
-/* Simplify a path name in place, deleting redundant components. This
- reduces OS overhead and guarantees that equivalent paths compare
- the same (modulo symlinks).
-
- Transforms made:
- foo/bar/../quux foo/quux
- foo/./bar foo/bar
- foo//bar foo/bar
- /../quux /quux
- //quux //quux (POSIX allows leading // as a namespace escape)
-
- Guarantees no trailing slashes. All transforms reduce the length
- of the string. Returns PATH. errno is 0 if no error occurred;
- nonzero if an error occurred when using stat () or lstat (). */
-char *
-_cpp_simplify_pathname (path)
- char *path;
+/* Returns true if PCHNAME is a valid PCH file for FILE. */
+static bool
+validate_pch (cpp_reader *pfile, _cpp_file *file, const char *pchname)
{
-#ifndef VMS
- char *from, *to;
- char *base, *orig_base;
- int absolute = 0;
-
- errno = 0;
- /* Don't overflow the empty path by putting a '.' in it below. */
- if (*path == '\0')
- return path;
-
-#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
- /* Convert all backslashes to slashes. */
- for (from = path; *from; from++)
- if (*from == '\\') *from = '/';
-
- /* Skip over leading drive letter if present. */
- if (ISALPHA (path[0]) && path[1] == ':')
- from = to = &path[2];
- else
- from = to = path;
-#else
- from = to = path;
-#endif
+ const char *saved_path = file->path;
+ bool valid = false;
- /* Remove redundant leading /s. */
- if (*from == '/')
+ file->path = pchname;
+ if (open_file (file))
{
- absolute = 1;
- to++;
- from++;
- if (*from == '/')
+ valid = 1 & pfile->cb.valid_pch (pfile, pchname, file->fd);
+
+ if (!valid)
{
- if (*++from == '/')
- /* 3 or more initial /s are equivalent to 1 /. */
- while (*++from == '/');
- else
- /* On some hosts // differs from /; Posix allows this. */
- to++;
+ close (file->fd);
+ file->fd = -1;
}
- }
-
- base = orig_base = to;
- for (;;)
- {
- int move_base = 0;
- while (*from == '/')
- from++;
-
- if (*from == '\0')
- break;
-
- if (*from == '.')
+ if (CPP_OPTION (pfile, print_include_names))
{
- if (from[1] == '\0')
- break;
- if (from[1] == '/')
- {
- from += 2;
- continue;
- }
- else if (from[1] == '.' && (from[2] == '/' || from[2] == '\0'))
- {
- /* Don't simplify if there was no previous component. */
- if (absolute && orig_base == to)
- {
- from += 2;
- continue;
- }
- /* Don't simplify if the previous component was "../",
- or if an error has already occurred with (l)stat. */
- if (base != to && errno == 0)
- {
- /* We don't back up if it's a symlink. */
- *to = '\0';
- if (remove_component_p (path))
- {
- while (to > base && *to != '/')
- to--;
- from += 2;
- continue;
- }
- }
- move_base = 1;
- }
+ unsigned int i;
+ for (i = 1; i < pfile->line_maps.depth; i++)
+ putc ('.', stderr);
+ fprintf (stderr, "%c %s\n",
+ valid ? '!' : 'x', pchname);
}
-
- /* Add the component separator. */
- if (to > orig_base)
- *to++ = '/';
-
- /* Copy this component until the trailing null or '/'. */
- while (*from != '\0' && *from != '/')
- *to++ = *from++;
-
- if (move_base)
- base = to;
}
- /* Change the empty string to "." so that it is not treated as stdin.
- Null terminate. */
- if (to == path)
- *to++ = '.';
- *to = '\0';
-
- return path;
-#else /* VMS */
- errno = 0;
- return path;
-#endif /* !VMS */
+ file->path = saved_path;
+ return valid;
}
diff --git a/contrib/gcc/cpphash.c b/contrib/gcc/cpphash.c
index 98d51be0a4c0..1e07f41f7ac3 100644
--- a/contrib/gcc/cpphash.c
+++ b/contrib/gcc/cpphash.c
@@ -28,28 +28,24 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "cpplib.h"
#include "cpphash.h"
-static cpp_hashnode *alloc_node PARAMS ((hash_table *));
+static cpp_hashnode *alloc_node (hash_table *);
/* Return an identifier node for hashtable.c. Used by cpplib except
when integrated with the C front ends. */
static cpp_hashnode *
-alloc_node (table)
- hash_table *table;
+alloc_node (hash_table *table)
{
cpp_hashnode *node;
- node = (cpp_hashnode *) obstack_alloc (&table->pfile->hash_ob,
- sizeof (cpp_hashnode));
- memset ((PTR) node, 0, sizeof (cpp_hashnode));
+ node = obstack_alloc (&table->pfile->hash_ob, sizeof (cpp_hashnode));
+ memset (node, 0, sizeof (cpp_hashnode));
return node;
}
/* Set up the identifier hash table. Use TABLE if non-null, otherwise
create our own. */
void
-_cpp_init_hashtable (pfile, table)
- cpp_reader *pfile;
- hash_table *table;
+_cpp_init_hashtable (cpp_reader *pfile, hash_table *table)
{
struct spec_nodes *s;
@@ -57,8 +53,11 @@ _cpp_init_hashtable (pfile, table)
{
pfile->our_hashtable = 1;
table = ht_create (13); /* 8K (=2^13) entries. */
- table->alloc_node = (hashnode (*) PARAMS ((hash_table *))) alloc_node;
- gcc_obstack_init (&pfile->hash_ob);
+ table->alloc_node = (hashnode (*) (hash_table *)) alloc_node;
+
+ _obstack_begin (&pfile->hash_ob, 0, 0,
+ (void *(*) (long)) xmalloc,
+ (void (*) (void *)) free);
}
table->pfile = pfile;
@@ -78,8 +77,7 @@ _cpp_init_hashtable (pfile, table)
/* Tear down the identifier hash table. */
void
-_cpp_destroy_hashtable (pfile)
- cpp_reader *pfile;
+_cpp_destroy_hashtable (cpp_reader *pfile)
{
if (pfile->our_hashtable)
{
@@ -91,10 +89,7 @@ _cpp_destroy_hashtable (pfile)
/* Returns the hash entry for the STR of length LEN, creating one
if necessary. */
cpp_hashnode *
-cpp_lookup (pfile, str, len)
- cpp_reader *pfile;
- const unsigned char *str;
- unsigned int len;
+cpp_lookup (cpp_reader *pfile, const unsigned char *str, unsigned int len)
{
/* ht_lookup cannot return NULL. */
return CPP_HASHNODE (ht_lookup (pfile->hash_table, str, len, HT_ALLOC));
@@ -102,10 +97,7 @@ cpp_lookup (pfile, str, len)
/* Determine whether the str STR, of length LEN, is a defined macro. */
int
-cpp_defined (pfile, str, len)
- cpp_reader *pfile;
- const unsigned char *str;
- int len;
+cpp_defined (cpp_reader *pfile, const unsigned char *str, int len)
{
cpp_hashnode *node;
@@ -118,10 +110,7 @@ cpp_defined (pfile, str, len)
/* For all nodes in the hashtable, callback CB with parameters PFILE,
the node, and V. */
void
-cpp_forall_identifiers (pfile, cb, v)
- cpp_reader *pfile;
- cpp_cb cb;
- PTR v;
+cpp_forall_identifiers (cpp_reader *pfile, cpp_cb cb, void *v)
{
/* We don't need a proxy since the hash table's identifier comes
first in cpp_hashnode. */
diff --git a/contrib/gcc/cpphash.h b/contrib/gcc/cpphash.h
index a8e0b871fa1b..e30cdcad63aa 100644
--- a/contrib/gcc/cpphash.h
+++ b/contrib/gcc/cpphash.h
@@ -1,5 +1,5 @@
/* Part of CPP library.
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@@ -25,11 +25,29 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "hashtable.h"
+#if defined HAVE_ICONV_H && defined HAVE_ICONV
+#include <iconv.h>
+#else
+#define HAVE_ICONV 0
+typedef int iconv_t; /* dummy */
+#endif
+
struct directive; /* Deliberately incomplete. */
struct pending_option;
struct op;
+struct _cpp_strbuf;
+typedef bool (*convert_f) (iconv_t, const unsigned char *, size_t,
+ struct _cpp_strbuf *);
+struct cset_converter
+{
+ convert_f func;
+ iconv_t cd;
+};
+
+#ifndef HAVE_UCHAR
typedef unsigned char uchar;
+#endif
#define U (const uchar *) /* Intended use: U"string" */
#define BITS_PER_CPPCHAR_T (CHAR_BIT * sizeof (cppchar_t))
@@ -43,7 +61,7 @@ typedef unsigned char uchar;
#define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION)
#define CPP_BUFFER(PFILE) ((PFILE)->buffer)
-#define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base + (BUF)->col_adjust)
+#define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base)
#define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur)
/* Maximum nesting of cpp_buffers. We use a static limit, partly for
@@ -82,7 +100,7 @@ struct cpp_macro
} exp;
/* Definition line number. */
- unsigned int line;
+ fileline line;
/* Number of tokens in expansion, or bytes for traditional macros. */
unsigned int count;
@@ -115,39 +133,18 @@ struct _cpp_buff
unsigned char *base, *cur, *limit;
};
-extern _cpp_buff *_cpp_get_buff PARAMS ((cpp_reader *, size_t));
-extern void _cpp_release_buff PARAMS ((cpp_reader *, _cpp_buff *));
-extern void _cpp_extend_buff PARAMS ((cpp_reader *, _cpp_buff **, size_t));
-extern _cpp_buff *_cpp_append_extend_buff PARAMS ((cpp_reader *, _cpp_buff *,
- size_t));
-extern void _cpp_free_buff PARAMS ((_cpp_buff *));
-extern unsigned char *_cpp_aligned_alloc PARAMS ((cpp_reader *, size_t));
-extern unsigned char *_cpp_unaligned_alloc PARAMS ((cpp_reader *, size_t));
+extern _cpp_buff *_cpp_get_buff (cpp_reader *, size_t);
+extern void _cpp_release_buff (cpp_reader *, _cpp_buff *);
+extern void _cpp_extend_buff (cpp_reader *, _cpp_buff **, size_t);
+extern _cpp_buff *_cpp_append_extend_buff (cpp_reader *, _cpp_buff *, size_t);
+extern void _cpp_free_buff (_cpp_buff *);
+extern unsigned char *_cpp_aligned_alloc (cpp_reader *, size_t);
+extern unsigned char *_cpp_unaligned_alloc (cpp_reader *, size_t);
#define BUFF_ROOM(BUFF) (size_t) ((BUFF)->limit - (BUFF)->cur)
#define BUFF_FRONT(BUFF) ((BUFF)->cur)
#define BUFF_LIMIT(BUFF) ((BUFF)->limit)
-/* List of directories to look for include files in. */
-struct search_path
-{
- struct search_path *next;
-
- /* NOTE: NAME may not be null terminated for the case of the current
- file's directory! */
- const char *name;
- unsigned int len;
- /* We use these to tell if the directory mentioned here is a duplicate
- of an earlier directory on the search path. */
- ino_t ino;
- dev_t dev;
- /* Nonzero if it is a system include directory. */
- int sysp;
- /* Mapping of file names for this directory. Only used on MS-DOS
- and related platforms. */
- struct file_name_map *name_map;
-};
-
/* #include types. */
enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE};
@@ -230,9 +227,6 @@ struct lexer_state
all directives apart from #define. */
unsigned char save_comments;
- /* Nonzero if we're mid-comment. */
- unsigned char lexing_comment;
-
/* Nonzero if lexing __VA_ARGS__ is valid. */
unsigned char va_args_ok;
@@ -258,47 +252,45 @@ struct spec_nodes
cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */
};
-/* Encapsulates state used to convert a stream of tokens into a text
- file. */
-struct printer
+typedef struct _cpp_line_note _cpp_line_note;
+struct _cpp_line_note
{
- FILE *outf; /* Stream to write to. */
- const struct line_map *map; /* Logical to physical line mappings. */
- const cpp_token *prev; /* Previous token. */
- const cpp_token *source; /* Source token for spacing. */
- unsigned int line; /* Line currently being written. */
- unsigned char printed; /* Nonzero if something output at line. */
+ /* Location in the clean line the note refers to. */
+ const uchar *pos;
+
+ /* Type of note. The 9 'from' trigraph characters represent those
+ trigraphs, '\\' an escaped newline, ' ' an escaped newline with
+ intervening space, and anything else is invalid. */
+ unsigned int type;
};
/* Represents the contents of a file cpplib has read in. */
struct cpp_buffer
{
- const unsigned char *cur; /* current position */
- const unsigned char *backup_to; /* if peeked character is not wanted */
- const unsigned char *rlimit; /* end of valid data */
- const unsigned char *line_base; /* start of current line */
+ const uchar *cur; /* Current location. */
+ const uchar *line_base; /* Start of current physical line. */
+ const uchar *next_line; /* Start of to-be-cleaned logical line. */
- struct cpp_buffer *prev;
+ const uchar *buf; /* Entire character buffer. */
+ const uchar *rlimit; /* Writable byte at end of file. */
- const unsigned char *buf; /* Entire character buffer. */
+ _cpp_line_note *notes; /* Array of notes. */
+ unsigned int cur_note; /* Next note to process. */
+ unsigned int notes_used; /* Number of notes. */
+ unsigned int notes_cap; /* Size of allocated array. */
- /* Pointer into the include table; non-NULL if this is a file
- buffer. Used for include_next and to record control macros. */
- struct include_file *inc;
+ struct cpp_buffer *prev;
+
+ /* Pointer into the file table; non-NULL if this is a file buffer.
+ Used for include_next and to record control macros. */
+ struct _cpp_file *file;
/* Value of if_stack at start of this file.
Used to prohibit unmatched #endif (etc) in an include file. */
struct if_stack *if_stack;
- /* Token column position adjustment owing to tabs in whitespace. */
- unsigned int col_adjust;
-
- /* Contains PREV_WHITE and/or AVOID_LPASTE. */
- unsigned char saved_flags;
-
- /* Because of the way the lexer works, -Wtrigraphs can sometimes
- warn twice for the same trigraph. This helps prevent that. */
- const unsigned char *last_Wtrigraphs;
+ /* True if we need to get the next clean line. */
+ bool need_line;
/* True if we have already warned about C++ comments in this file.
The warning happens only for C89 extended mode with -pedantic on,
@@ -311,18 +303,14 @@ struct cpp_buffer
buffers. */
unsigned char from_stage3;
- /* Nonzero means that the directory to start searching for ""
- include files has been calculated and stored in "dir" below. */
- unsigned char search_cached;
-
/* At EOF, a buffer is automatically popped. If RETURN_AT_EOF is
true, a CPP_EOF token is then returned. Otherwise, the next
token from the enclosing buffer is returned. */
- bool return_at_eof;
+ unsigned int return_at_eof : 1;
/* The directory of the this buffer's file. Its NAME member is not
allocated, so we don't need to worry about freeing it. */
- struct search_path dir;
+ struct cpp_dir dir;
/* Used for buffer overlays by cpptrad.c. */
const uchar *saved_cur, *saved_rlimit;
@@ -345,10 +333,10 @@ struct cpp_reader
/* Source line tracking. */
struct line_maps line_maps;
const struct line_map *map;
- unsigned int line;
+ fileline line;
/* The line of the '#' of the current directive. */
- unsigned int directive_line;
+ fileline directive_line;
/* Memory buffers. */
_cpp_buff *a_buff; /* Aligned permanent storage. */
@@ -362,12 +350,31 @@ struct cpp_reader
/* If in_directive, the directive if known. */
const struct directive *directive;
- /* The next -include-d file; NULL if they all are done. If it
- points to NULL, the last one is in progress, and
- _cpp_maybe_push_include_file has yet to restore the line map. */
- struct pending_option **next_include_file;
+ /* Search paths for include files. */
+ struct cpp_dir *quote_include; /* "" */
+ struct cpp_dir *bracket_include; /* <> */
+ struct cpp_dir no_search_path; /* No path. */
+
+ /* Chain of all hashed _cpp_file instances. */
+ struct _cpp_file *all_files;
+
+ struct _cpp_file *main_file;
+
+ /* File and directory hash table. */
+ struct htab *file_hash;
+ struct htab *dir_hash;
+ struct file_hash_entry *file_hash_entries;
+ unsigned int file_hash_entries_allocated, file_hash_entries_used;
- /* Multiple inlcude optimisation. */
+ /* Nonzero means don't look for #include "foo" the source-file
+ directory. */
+ bool quote_ignores_source_dir;
+
+ /* Nonzero if any file has contained #pragma once or #import has
+ been used. */
+ bool seen_once_only;
+
+ /* Multiple include optimization. */
const cpp_hashnode *mi_cmacro;
const cpp_hashnode *mi_ind_cmacro;
bool mi_valid;
@@ -387,15 +394,13 @@ struct cpp_reader
unsigned char *macro_buffer;
unsigned int macro_buffer_len;
- /* Tree of other included files. See cppfiles.c. */
- struct splay_tree_s *all_include_files;
-
- /* Current maximum length of directory names in the search path
- for include files. (Altered as we get more of them.) */
- unsigned int max_include_len;
+ /* Descriptor for converting from the source character set to the
+ execution character set. */
+ struct cset_converter narrow_cset_desc;
- /* Macros on or after this line are warned about if unused. */
- unsigned int first_unused_line;
+ /* Descriptor for converting from the source character set to the
+ wide execution character set. */
+ struct cset_converter wide_cset_desc;
/* Date and time text. Calculated together if either is requested. */
const uchar *date;
@@ -420,7 +425,7 @@ struct cpp_reader
list of recognized pragmas. */
struct pragma_entry *pragmas;
- /* Call backs. */
+ /* Call backs to cpplib client. */
struct cpp_callbacks cb;
/* Identifier hash table. */
@@ -436,11 +441,8 @@ struct cpp_reader
preprocessor. */
struct spec_nodes spec_nodes;
- /* Used when doing preprocessed output. */
- struct printer print;
-
/* Whether cpplib owns the hashtable. */
- unsigned char our_hashtable;
+ bool our_hashtable;
/* Traditional preprocessing output buffer (a logical line). */
struct
@@ -448,12 +450,16 @@ struct cpp_reader
uchar *base;
uchar *limit;
uchar *cur;
- unsigned int first_line;
+ fileline first_line;
} out;
/* Used to save the original line number during traditional
preprocessing. */
unsigned int saved_line;
+
+ /* A saved list of the defined macros, for dependency checking
+ of precompiled headers. */
+ struct cpp_savedstate *savedstate;
};
/* Character classes. Based on the more primitive macros in safe-ctype.h.
@@ -490,81 +496,92 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1];
#define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, warn_traditional)
/* In cpperror.c */
-extern int _cpp_begin_message PARAMS ((cpp_reader *, int,
- unsigned int, unsigned int));
+extern int _cpp_begin_message (cpp_reader *, int, fileline, unsigned int);
/* In cppmacro.c */
-extern void _cpp_free_definition PARAMS ((cpp_hashnode *));
-extern bool _cpp_create_definition PARAMS ((cpp_reader *, cpp_hashnode *));
-extern void _cpp_pop_context PARAMS ((cpp_reader *));
-extern void _cpp_push_text_context PARAMS ((cpp_reader *, cpp_hashnode *,
- const uchar *, size_t));
-extern bool _cpp_save_parameter PARAMS ((cpp_reader *, cpp_macro *,
- cpp_hashnode *));
-extern bool _cpp_arguments_ok PARAMS ((cpp_reader *, cpp_macro *,
- const cpp_hashnode *,
- unsigned int));
-extern const uchar *_cpp_builtin_macro_text PARAMS ((cpp_reader *,
- cpp_hashnode *));
-int _cpp_warn_if_unused_macro PARAMS ((cpp_reader *, cpp_hashnode *,
- void *));
+extern void _cpp_free_definition (cpp_hashnode *);
+extern bool _cpp_create_definition (cpp_reader *, cpp_hashnode *);
+extern void _cpp_pop_context (cpp_reader *);
+extern void _cpp_push_text_context (cpp_reader *, cpp_hashnode *,
+ const uchar *, size_t);
+extern bool _cpp_save_parameter (cpp_reader *, cpp_macro *, cpp_hashnode *);
+extern bool _cpp_arguments_ok (cpp_reader *, cpp_macro *, const cpp_hashnode *,
+ unsigned int);
+extern const uchar *_cpp_builtin_macro_text (cpp_reader *, cpp_hashnode *);
+int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *);
/* In cpphash.c */
-extern void _cpp_init_hashtable PARAMS ((cpp_reader *, hash_table *));
-extern void _cpp_destroy_hashtable PARAMS ((cpp_reader *));
+extern void _cpp_init_hashtable (cpp_reader *, hash_table *);
+extern void _cpp_destroy_hashtable (cpp_reader *);
/* In cppfiles.c */
-extern void _cpp_fake_include PARAMS ((cpp_reader *, const char *));
-extern void _cpp_never_reread PARAMS ((struct include_file *));
-extern char *_cpp_simplify_pathname PARAMS ((char *));
-extern bool _cpp_read_file PARAMS ((cpp_reader *, const char *));
-extern bool _cpp_execute_include PARAMS ((cpp_reader *,
- const cpp_token *,
- enum include_type));
-extern int _cpp_compare_file_date PARAMS ((cpp_reader *,
- const cpp_token *));
-extern void _cpp_report_missing_guards PARAMS ((cpp_reader *));
-extern void _cpp_init_includes PARAMS ((cpp_reader *));
-extern void _cpp_cleanup_includes PARAMS ((cpp_reader *));
-extern void _cpp_pop_file_buffer PARAMS ((cpp_reader *,
- struct include_file *));
+typedef struct _cpp_file _cpp_file;
+extern _cpp_file *_cpp_find_file (cpp_reader *, const char *fname,
+ cpp_dir *start_dir, bool fake);
+extern bool _cpp_find_failed (_cpp_file *);
+extern void _cpp_mark_file_once_only (cpp_reader *, struct _cpp_file *);
+extern void _cpp_fake_include (cpp_reader *, const char *);
+extern bool _cpp_stack_file (cpp_reader *, _cpp_file*, bool);
+extern bool _cpp_stack_include (cpp_reader *, const char *, int,
+ enum include_type);
+extern int _cpp_compare_file_date (cpp_reader *, const char *, int);
+extern void _cpp_report_missing_guards (cpp_reader *);
+extern void _cpp_init_files (cpp_reader *);
+extern void _cpp_cleanup_files (cpp_reader *);
+extern void _cpp_pop_file_buffer (cpp_reader *, struct _cpp_file *);
/* In cppexp.c */
-extern bool _cpp_parse_expr PARAMS ((cpp_reader *));
-extern struct op *_cpp_expand_op_stack PARAMS ((cpp_reader *));
+extern bool _cpp_parse_expr (cpp_reader *);
+extern struct op *_cpp_expand_op_stack (cpp_reader *);
/* In cpplex.c */
-extern cpp_token *_cpp_temp_token PARAMS ((cpp_reader *));
-extern const cpp_token *_cpp_lex_token PARAMS ((cpp_reader *));
-extern cpp_token *_cpp_lex_direct PARAMS ((cpp_reader *));
-extern int _cpp_equiv_tokens PARAMS ((const cpp_token *,
- const cpp_token *));
-extern void _cpp_init_tokenrun PARAMS ((tokenrun *, unsigned int));
+extern void _cpp_process_line_notes (cpp_reader *, int);
+extern void _cpp_clean_line (cpp_reader *);
+extern bool _cpp_get_fresh_line (cpp_reader *);
+extern bool _cpp_skip_block_comment (cpp_reader *);
+extern cpp_token *_cpp_temp_token (cpp_reader *);
+extern const cpp_token *_cpp_lex_token (cpp_reader *);
+extern cpp_token *_cpp_lex_direct (cpp_reader *);
+extern int _cpp_equiv_tokens (const cpp_token *, const cpp_token *);
+extern void _cpp_init_tokenrun (tokenrun *, unsigned int);
/* In cppinit.c. */
-extern void _cpp_maybe_push_include_file PARAMS ((cpp_reader *));
+extern void _cpp_maybe_push_include_file (cpp_reader *);
/* In cpplib.c */
-extern int _cpp_test_assertion PARAMS ((cpp_reader *, unsigned int *));
-extern int _cpp_handle_directive PARAMS ((cpp_reader *, int));
-extern void _cpp_define_builtin PARAMS ((cpp_reader *, const char *));
-extern void _cpp_do__Pragma PARAMS ((cpp_reader *));
-extern void _cpp_init_directives PARAMS ((cpp_reader *));
-extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *));
-extern void _cpp_do_file_change PARAMS ((cpp_reader *, enum lc_reason,
- const char *,
- unsigned int, unsigned int));
-extern void _cpp_pop_buffer PARAMS ((cpp_reader *));
+extern int _cpp_test_assertion (cpp_reader *, unsigned int *);
+extern int _cpp_handle_directive (cpp_reader *, int);
+extern void _cpp_define_builtin (cpp_reader *, const char *);
+extern char ** _cpp_save_pragma_names (cpp_reader *);
+extern void _cpp_restore_pragma_names (cpp_reader *, char **);
+extern void _cpp_do__Pragma (cpp_reader *);
+extern void _cpp_init_directives (cpp_reader *);
+extern void _cpp_init_internal_pragmas (cpp_reader *);
+extern void _cpp_do_file_change (cpp_reader *, enum lc_reason, const char *,
+ unsigned int, unsigned int);
+extern void _cpp_pop_buffer (cpp_reader *);
/* In cpptrad.c. */
-extern bool _cpp_read_logical_line_trad PARAMS ((cpp_reader *));
-extern void _cpp_overlay_buffer PARAMS ((cpp_reader *pfile, const uchar *,
- size_t));
-extern void _cpp_remove_overlay PARAMS ((cpp_reader *));
-extern bool _cpp_create_trad_definition PARAMS ((cpp_reader *, cpp_macro *));
-extern bool _cpp_expansions_different_trad PARAMS ((const cpp_macro *,
- const cpp_macro *));
-extern uchar *_cpp_copy_replacement_text PARAMS ((const cpp_macro *, uchar *));
-extern size_t _cpp_replacement_text_len PARAMS ((const cpp_macro *));
+extern bool _cpp_scan_out_logical_line (cpp_reader *, cpp_macro *);
+extern bool _cpp_read_logical_line_trad (cpp_reader *);
+extern void _cpp_overlay_buffer (cpp_reader *pfile, const uchar *, size_t);
+extern void _cpp_remove_overlay (cpp_reader *);
+extern bool _cpp_create_trad_definition (cpp_reader *, cpp_macro *);
+extern bool _cpp_expansions_different_trad (const cpp_macro *,
+ const cpp_macro *);
+extern uchar *_cpp_copy_replacement_text (const cpp_macro *, uchar *);
+extern size_t _cpp_replacement_text_len (const cpp_macro *);
+
+/* In cppcharset.c. */
+extern cppchar_t _cpp_valid_ucn (cpp_reader *, const uchar **,
+ const uchar *, int);
+extern void _cpp_destroy_iconv (cpp_reader *);
+extern bool _cpp_interpret_string_notranslate (cpp_reader *,
+ const cpp_string *,
+ cpp_string *);
+extern uchar *_cpp_convert_input (cpp_reader *, const char *, uchar *,
+ size_t, size_t, off_t *);
+extern const char *_cpp_default_encoding (void);
+
/* Utility routines and macros. */
#define DSC(str) (const uchar *)str, sizeof str - 1
@@ -576,55 +593,45 @@ extern size_t _cpp_replacement_text_len PARAMS ((const cpp_macro *));
/* These are inline functions instead of macros so we can get type
checking. */
-static inline int ustrcmp PARAMS ((const uchar *, const uchar *));
-static inline int ustrncmp PARAMS ((const uchar *, const uchar *,
- size_t));
-static inline size_t ustrlen PARAMS ((const uchar *));
-static inline uchar *uxstrdup PARAMS ((const uchar *));
-static inline uchar *ustrchr PARAMS ((const uchar *, int));
-static inline int ufputs PARAMS ((const uchar *, FILE *));
+static inline int ustrcmp (const uchar *, const uchar *);
+static inline int ustrncmp (const uchar *, const uchar *, size_t);
+static inline size_t ustrlen (const uchar *);
+static inline uchar *uxstrdup (const uchar *);
+static inline uchar *ustrchr (const uchar *, int);
+static inline int ufputs (const uchar *, FILE *);
static inline int
-ustrcmp (s1, s2)
- const uchar *s1, *s2;
+ustrcmp (const uchar *s1, const uchar *s2)
{
return strcmp ((const char *)s1, (const char *)s2);
}
static inline int
-ustrncmp (s1, s2, n)
- const uchar *s1, *s2;
- size_t n;
+ustrncmp (const uchar *s1, const uchar *s2, size_t n)
{
return strncmp ((const char *)s1, (const char *)s2, n);
}
static inline size_t
-ustrlen (s1)
- const uchar *s1;
+ustrlen (const uchar *s1)
{
return strlen ((const char *)s1);
}
static inline uchar *
-uxstrdup (s1)
- const uchar *s1;
+uxstrdup (const uchar *s1)
{
return (uchar *) xstrdup ((const char *)s1);
}
static inline uchar *
-ustrchr (s1, c)
- const uchar *s1;
- int c;
+ustrchr (const uchar *s1, int c)
{
return (uchar *) strchr ((const char *)s1, c);
}
static inline int
-ufputs (s, f)
- const uchar *s;
- FILE *f;
+ufputs (const uchar *s, FILE *f)
{
return fputs ((const char *)s, f);
}
diff --git a/contrib/gcc/cppinit.c b/contrib/gcc/cppinit.c
index d8e622bca4e4..ae30568699c5 100644
--- a/contrib/gcc/cppinit.c
+++ b/contrib/gcc/cppinit.c
@@ -1,6 +1,6 @@
/* CPP Library.
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -23,99 +23,13 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "system.h"
#include "cpplib.h"
#include "cpphash.h"
-#include "prefix.h"
-#include "intl.h"
#include "mkdeps.h"
-#include "cppdefault.h"
-
-/* Windows does not natively support inodes, and neither does MSDOS.
- Cygwin's emulation can generate non-unique inodes, so don't use it.
- VMS has non-numeric inodes. */
-#ifdef VMS
-# define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A)))
-# define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC))
-#else
-# if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__
-# define INO_T_EQ(A, B) 0
-# else
-# define INO_T_EQ(A, B) ((A) == (B))
-# endif
-# define INO_T_COPY(DEST, SRC) (DEST) = (SRC)
-#endif
-
-/* Internal structures and prototypes. */
-
-/* A `struct pending_option' remembers one -D, -A, -U, -include, or
- -imacros switch. */
-typedef void (* cl_directive_handler) PARAMS ((cpp_reader *, const char *));
-struct pending_option
-{
- struct pending_option *next;
- const char *arg;
- cl_directive_handler handler;
-};
-
-/* The `pending' structure accumulates all the options that are not
- actually processed until we hit cpp_read_main_file. It consists of
- several lists, one for each type of option. We keep both head and
- tail pointers for quick insertion. */
-struct cpp_pending
-{
- struct pending_option *directive_head, *directive_tail;
- struct search_path *quote_head, *quote_tail;
- struct search_path *brack_head, *brack_tail;
- struct search_path *systm_head, *systm_tail;
- struct search_path *after_head, *after_tail;
-
- struct pending_option *imacros_head, *imacros_tail;
- struct pending_option *include_head, *include_tail;
-};
-
-#ifdef __STDC__
-#define APPEND(pend, list, elt) \
- do { if (!(pend)->list##_head) (pend)->list##_head = (elt); \
- else (pend)->list##_tail->next = (elt); \
- (pend)->list##_tail = (elt); \
- } while (0)
-#else
-#define APPEND(pend, list, elt) \
- do { if (!(pend)->list/**/_head) (pend)->list/**/_head = (elt); \
- else (pend)->list/**/_tail->next = (elt); \
- (pend)->list/**/_tail = (elt); \
- } while (0)
-#endif
-
-static void path_include PARAMS ((cpp_reader *,
- char *, int));
-static void init_library PARAMS ((void));
-static void init_builtins PARAMS ((cpp_reader *));
-static void mark_named_operators PARAMS ((cpp_reader *));
-static void append_include_chain PARAMS ((cpp_reader *,
- char *, int, int));
-static struct search_path * remove_dup_dir PARAMS ((cpp_reader *,
- struct search_path *,
- struct search_path **));
-static struct search_path * remove_dup_nonsys_dirs PARAMS ((cpp_reader *,
- struct search_path **,
- struct search_path *));
-static struct search_path * remove_dup_dirs PARAMS ((cpp_reader *,
- struct search_path **));
-static void merge_include_chains PARAMS ((cpp_reader *));
-static bool push_include PARAMS ((cpp_reader *,
- struct pending_option *));
-static void free_chain PARAMS ((struct pending_option *));
-static void init_standard_includes PARAMS ((cpp_reader *));
-static void read_original_filename PARAMS ((cpp_reader *));
-static void new_pending_directive PARAMS ((struct cpp_pending *,
- const char *,
- cl_directive_handler));
-static int parse_option PARAMS ((const char *));
-static void post_options PARAMS ((cpp_reader *));
-
-/* Fourth argument to append_include_chain: chain to use.
- Note it's never asked to append to the quote chain. */
-enum { BRACKET = 0, SYSTEM, AFTER };
+static void init_library (void);
+static void mark_named_operators (cpp_reader *);
+static void read_original_filename (cpp_reader *);
+static void read_original_directory (cpp_reader *);
+static void post_options (cpp_reader *);
/* If we have designated initializers (GCC >2.7) these tables can be
initialized, constant data. Otherwise, they have to be filled in at
@@ -132,7 +46,7 @@ __extension__ const uchar _cpp_trigraph_map[UCHAR_MAX + 1] = {
#else
#define TRIGRAPH_MAP uchar _cpp_trigraph_map[UCHAR_MAX + 1] = { 0 }; \
- static void init_trigraph_map PARAMS ((void)) { \
+ static void init_trigraph_map (void) { \
unsigned char *x = _cpp_trigraph_map;
#define END }
@@ -150,281 +64,6 @@ END
#undef END
#undef TRIGRAPH_MAP
-/* Given a colon-separated list of file names PATH,
- add all the names to the search path for include files. */
-static void
-path_include (pfile, list, path)
- cpp_reader *pfile;
- char *list;
- int path;
-{
- char *p, *q, *name;
-
- p = list;
-
- do
- {
- /* Find the end of this name. */
- q = p;
- while (*q != 0 && *q != PATH_SEPARATOR) q++;
- if (q == p)
- {
- /* An empty name in the path stands for the current directory. */
- name = (char *) xmalloc (2);
- name[0] = '.';
- name[1] = 0;
- }
- else
- {
- /* Otherwise use the directory that is named. */
- name = (char *) xmalloc (q - p + 1);
- memcpy (name, p, q - p);
- name[q - p] = 0;
- }
-
- append_include_chain (pfile, name, path, path == SYSTEM);
-
- /* Advance past this name. */
- if (*q == 0)
- break;
- p = q + 1;
- }
- while (1);
-}
-
-/* Append DIR to include path PATH. DIR must be allocated on the
- heap; this routine takes responsibility for freeing it. CXX_AWARE
- is nonzero if the header contains extern "C" guards for C++,
- otherwise it is zero. */
-static void
-append_include_chain (pfile, dir, path, cxx_aware)
- cpp_reader *pfile;
- char *dir;
- int path;
- int cxx_aware;
-{
- struct cpp_pending *pend = CPP_OPTION (pfile, pending);
- struct search_path *new;
- struct stat st;
- unsigned int len;
-
- if (*dir == '\0')
- {
- free (dir);
- dir = xstrdup (".");
- }
- _cpp_simplify_pathname (dir);
-
- if (stat (dir, &st))
- {
- /* Dirs that don't exist are silently ignored. */
- if (errno != ENOENT)
- cpp_errno (pfile, DL_ERROR, dir);
- else if (CPP_OPTION (pfile, verbose))
- fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"), dir);
- free (dir);
- return;
- }
-
- if (!S_ISDIR (st.st_mode))
- {
- cpp_error_with_line (pfile, DL_ERROR, 0, 0, "%s: Not a directory", dir);
- free (dir);
- return;
- }
-
- len = strlen (dir);
- if (len > pfile->max_include_len)
- pfile->max_include_len = len;
-
- new = (struct search_path *) xmalloc (sizeof (struct search_path));
- new->name = dir;
- new->len = len;
- INO_T_COPY (new->ino, st.st_ino);
- new->dev = st.st_dev;
- /* Both systm and after include file lists should be treated as system
- include files since these two lists are really just a concatenation
- of one "system" list. */
- if (path == SYSTEM || path == AFTER)
- new->sysp = cxx_aware ? 1 : 2;
- else
- new->sysp = 0;
- new->name_map = NULL;
- new->next = NULL;
-
- switch (path)
- {
- case BRACKET: APPEND (pend, brack, new); break;
- case SYSTEM: APPEND (pend, systm, new); break;
- case AFTER: APPEND (pend, after, new); break;
- }
-}
-
-/* Handle a duplicated include path. PREV is the link in the chain
- before the duplicate, or NULL if the duplicate is at the head of
- the chain. The duplicate is removed from the chain and freed.
- Returns PREV. */
-static struct search_path *
-remove_dup_dir (pfile, prev, head_ptr)
- cpp_reader *pfile;
- struct search_path *prev;
- struct search_path **head_ptr;
-{
- struct search_path *cur;
-
- if (prev != NULL)
- {
- cur = prev->next;
- prev->next = cur->next;
- }
- else
- {
- cur = *head_ptr;
- *head_ptr = cur->next;
- }
-
- if (CPP_OPTION (pfile, verbose))
- fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), cur->name);
-
- free ((PTR) cur->name);
- free (cur);
-
- return prev;
-}
-
-/* Remove duplicate non-system directories for which there is an equivalent
- system directory latter in the chain. The range for removal is between
- *HEAD_PTR and END. Returns the directory before END, or NULL if none.
- This algorithm is quadratic in the number system directories, which is
- acceptable since there aren't usually that many of them. */
-static struct search_path *
-remove_dup_nonsys_dirs (pfile, head_ptr, end)
- cpp_reader *pfile;
- struct search_path **head_ptr;
- struct search_path *end;
-{
- int sysdir = 0;
- struct search_path *prev = NULL, *cur, *other;
-
- for (cur = *head_ptr; cur; cur = cur->next)
- {
- if (cur->sysp)
- {
- sysdir = 1;
- for (other = *head_ptr, prev = NULL;
- other != end;
- other = other ? other->next : *head_ptr)
- {
- if (!other->sysp
- && INO_T_EQ (cur->ino, other->ino)
- && cur->dev == other->dev)
- {
- other = remove_dup_dir (pfile, prev, head_ptr);
- if (CPP_OPTION (pfile, verbose))
- fprintf (stderr,
- _(" as it is a non-system directory that duplicates a system directory\n"));
- }
- prev = other;
- }
- }
- }
-
- if (!sysdir)
- for (cur = *head_ptr; cur != end; cur = cur->next)
- prev = cur;
-
- return prev;
-}
-
-/* Remove duplicate directories from a chain. Returns the tail of the
- chain, or NULL if the chain is empty. This algorithm is quadratic
- in the number of -I switches, which is acceptable since there
- aren't usually that many of them. */
-static struct search_path *
-remove_dup_dirs (pfile, head_ptr)
- cpp_reader *pfile;
- struct search_path **head_ptr;
-{
- struct search_path *prev = NULL, *cur, *other;
-
- for (cur = *head_ptr; cur; cur = cur->next)
- {
- for (other = *head_ptr; other != cur; other = other->next)
- if (INO_T_EQ (cur->ino, other->ino) && cur->dev == other->dev)
- {
- cur = remove_dup_dir (pfile, prev, head_ptr);
- break;
- }
- prev = cur;
- }
-
- return prev;
-}
-
-/* Merge the four include chains together in the order quote, bracket,
- system, after. Remove duplicate dirs (as determined by
- INO_T_EQ()). The system_include and after_include chains are never
- referred to again after this function; all access is through the
- bracket_include path. */
-static void
-merge_include_chains (pfile)
- cpp_reader *pfile;
-{
- struct search_path *quote, *brack, *systm, *qtail;
-
- struct cpp_pending *pend = CPP_OPTION (pfile, pending);
-
- quote = pend->quote_head;
- brack = pend->brack_head;
- systm = pend->systm_head;
- qtail = pend->quote_tail;
-
- /* Paste together bracket, system, and after include chains. */
- if (systm)
- pend->systm_tail->next = pend->after_head;
- else
- systm = pend->after_head;
-
- if (brack)
- pend->brack_tail->next = systm;
- else
- brack = systm;
-
- /* This is a bit tricky. First we drop non-system dupes of system
- directories from the merged bracket-include list. Next we drop
- dupes from the bracket and quote include lists. Then we drop
- non-system dupes from the merged quote-include list. Finally,
- if qtail and brack are the same directory, we cut out brack and
- move brack up to point to qtail.
-
- We can't just merge the lists and then uniquify them because
- then we may lose directories from the <> search path that should
- be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however
- safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written
- -Ibar -I- -Ifoo -Iquux. */
-
- remove_dup_nonsys_dirs (pfile, &brack, systm);
- remove_dup_dirs (pfile, &brack);
-
- if (quote)
- {
- qtail = remove_dup_dirs (pfile, &quote);
- qtail->next = brack;
-
- qtail = remove_dup_nonsys_dirs (pfile, &quote, brack);
-
- /* If brack == qtail, remove brack as it's simpler. */
- if (qtail && brack && INO_T_EQ (qtail->ino, brack->ino)
- && qtail->dev == brack->dev)
- brack = remove_dup_dir (pfile, qtail, &quote);
- }
- else
- quote = brack;
-
- CPP_OPTION (pfile, quote_include) = quote;
- CPP_OPTION (pfile, bracket_include) = brack;
-}
-
/* A set of booleans indicating what CPP features each source language
requires. */
struct lang_flags
@@ -433,29 +72,25 @@ struct lang_flags
char cplusplus;
char extended_numbers;
char std;
- char dollars_in_ident;
char cplusplus_comments;
char digraphs;
};
-/* ??? Enable $ in identifiers in assembly? */
static const struct lang_flags lang_defaults[] =
-{ /* c99 c++ xnum std dollar c++comm digr */
- /* GNUC89 */ { 0, 0, 1, 0, 1, 1, 1 },
- /* GNUC99 */ { 1, 0, 1, 0, 1, 1, 1 },
- /* STDC89 */ { 0, 0, 0, 1, 0, 0, 0 },
- /* STDC94 */ { 0, 0, 0, 1, 0, 0, 1 },
- /* STDC99 */ { 1, 0, 1, 1, 0, 1, 1 },
- /* GNUCXX */ { 0, 1, 1, 0, 1, 1, 1 },
- /* CXX98 */ { 0, 1, 1, 1, 0, 1, 1 },
- /* ASM */ { 0, 0, 1, 0, 0, 1, 0 }
+{ /* c99 c++ xnum std // digr */
+ /* GNUC89 */ { 0, 0, 1, 0, 1, 1 },
+ /* GNUC99 */ { 1, 0, 1, 0, 1, 1 },
+ /* STDC89 */ { 0, 0, 0, 1, 0, 0 },
+ /* STDC94 */ { 0, 0, 0, 1, 0, 1 },
+ /* STDC99 */ { 1, 0, 1, 1, 1, 1 },
+ /* GNUCXX */ { 0, 1, 1, 0, 1, 1 },
+ /* CXX98 */ { 0, 1, 1, 1, 1, 1 },
+ /* ASM */ { 0, 0, 1, 0, 1, 0 }
};
/* Sets internal flags correctly for a given language. */
void
-cpp_set_lang (pfile, lang)
- cpp_reader *pfile;
- enum c_lang lang;
+cpp_set_lang (cpp_reader *pfile, enum c_lang lang)
{
const struct lang_flags *l = &lang_defaults[(int) lang];
@@ -466,28 +101,13 @@ cpp_set_lang (pfile, lang)
CPP_OPTION (pfile, extended_numbers) = l->extended_numbers;
CPP_OPTION (pfile, std) = l->std;
CPP_OPTION (pfile, trigraphs) = l->std;
- CPP_OPTION (pfile, dollars_in_ident) = l->dollars_in_ident;
CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments;
CPP_OPTION (pfile, digraphs) = l->digraphs;
}
-#ifdef HOST_EBCDIC
-static int opt_comp PARAMS ((const void *, const void *));
-
-/* Run-time sorting of options array. */
-static int
-opt_comp (p1, p2)
- const void *p1, *p2;
-{
- return strcmp (((struct cl_option *) p1)->opt_text,
- ((struct cl_option *) p2)->opt_text);
-}
-#endif
-
-/* init initializes library global state. It might not need to
- do anything depending on the platform and compiler. */
+/* Initialize library global state. */
static void
-init_library ()
+init_library (void)
{
static int initialized = 0;
@@ -495,12 +115,6 @@ init_library ()
{
initialized = 1;
-#ifdef HOST_EBCDIC
- /* For non-ASCII hosts, the cl_options array needs to be sorted at
- runtime. */
- qsort (cl_options, N_OPTS, sizeof (struct cl_option), opt_comp);
-#endif
-
/* Set up the trigraph map. This doesn't need to do anything if
we were compiled with a compiler that supports C99 designated
initializers. */
@@ -510,29 +124,28 @@ init_library ()
/* Initialize a cpp_reader structure. */
cpp_reader *
-cpp_create_reader (lang)
- enum c_lang lang;
+cpp_create_reader (enum c_lang lang, hash_table *table)
{
cpp_reader *pfile;
/* Initialize this instance of the library if it hasn't been already. */
init_library ();
- pfile = (cpp_reader *) xcalloc (1, sizeof (cpp_reader));
+ pfile = xcalloc (1, sizeof (cpp_reader));
cpp_set_lang (pfile, lang);
- CPP_OPTION (pfile, warn_import) = 1;
CPP_OPTION (pfile, warn_multichar) = 1;
CPP_OPTION (pfile, discard_comments) = 1;
CPP_OPTION (pfile, discard_comments_in_macro_exp) = 1;
CPP_OPTION (pfile, show_column) = 1;
CPP_OPTION (pfile, tabstop) = 8;
CPP_OPTION (pfile, operator_names) = 1;
+ CPP_OPTION (pfile, warn_trigraphs) = 2;
CPP_OPTION (pfile, warn_endif_labels) = 1;
+ CPP_OPTION (pfile, warn_deprecated) = 1;
CPP_OPTION (pfile, warn_long_long) = !CPP_OPTION (pfile, c99);
-
- CPP_OPTION (pfile, pending) =
- (struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending));
+ CPP_OPTION (pfile, dollars_in_ident) = 1;
+ CPP_OPTION (pfile, warn_dollars) = 1;
/* Default CPP arithmetic to something sensible for the host for the
benefit of dumb users like fix-header. */
@@ -542,10 +155,22 @@ cpp_create_reader (lang)
CPP_OPTION (pfile, int_precision) = CHAR_BIT * sizeof (int);
CPP_OPTION (pfile, unsigned_char) = 0;
CPP_OPTION (pfile, unsigned_wchar) = 1;
+ CPP_OPTION (pfile, bytes_big_endian) = 1; /* does not matter */
+
+ /* Default to locale/UTF-8. */
+ CPP_OPTION (pfile, narrow_charset) = _cpp_default_encoding ();
+ CPP_OPTION (pfile, wide_charset) = 0;
+ CPP_OPTION (pfile, input_charset) = _cpp_default_encoding ();
+
+ /* A fake empty "directory" used as the starting point for files
+ looked up without a search path. Name cannot be '/' because we
+ don't want to prepend anything at all to filenames using it. All
+ other entries are correct zero-initialized. */
+ pfile->no_search_path.name = (char *) "";
/* Initialize the line map. Start at logical line 1, so we can use
a line number of zero for special states. */
- init_line_maps (&pfile->line_maps);
+ linemap_init (&pfile->line_maps);
pfile->line = 1;
/* Initialize lexer state. */
@@ -575,9 +200,13 @@ cpp_create_reader (lang)
_cpp_expand_op_stack (pfile);
/* Initialize the buffer obstack. */
- gcc_obstack_init (&pfile->buffer_ob);
+ _obstack_begin (&pfile->buffer_ob, 0, 0,
+ (void *(*) (long)) xmalloc,
+ (void (*) (void *)) free);
+
+ _cpp_init_files (pfile);
- _cpp_init_includes (pfile);
+ _cpp_init_hashtable (pfile, table);
return pfile;
}
@@ -585,15 +214,11 @@ cpp_create_reader (lang)
/* Free resources used by PFILE. Accessing PFILE after this function
returns leads to undefined behavior. Returns the error count. */
void
-cpp_destroy (pfile)
- cpp_reader *pfile;
+cpp_destroy (cpp_reader *pfile)
{
- struct search_path *dir, *dirn;
cpp_context *context, *contextn;
tokenrun *run, *runn;
- free_chain (CPP_OPTION (pfile, pending)->include_head);
- free (CPP_OPTION (pfile, pending));
free (pfile->op_stack);
while (CPP_BUFFER (pfile) != NULL)
@@ -604,7 +229,7 @@ cpp_destroy (pfile)
if (pfile->macro_buffer)
{
- free ((PTR) pfile->macro_buffer);
+ free (pfile->macro_buffer);
pfile->macro_buffer = NULL;
pfile->macro_buffer_len = 0;
}
@@ -614,7 +239,8 @@ cpp_destroy (pfile)
obstack_free (&pfile->buffer_ob, 0);
_cpp_destroy_hashtable (pfile);
- _cpp_cleanup_includes (pfile);
+ _cpp_cleanup_files (pfile);
+ _cpp_destroy_iconv (pfile);
_cpp_free_buff (pfile->a_buff);
_cpp_free_buff (pfile->u_buff);
@@ -628,20 +254,13 @@ cpp_destroy (pfile)
free (run);
}
- for (dir = CPP_OPTION (pfile, quote_include); dir; dir = dirn)
- {
- dirn = dir->next;
- free ((PTR) dir->name);
- free (dir);
- }
-
for (context = pfile->base_context.next; context; context = contextn)
{
contextn = context->next;
free (context);
}
- free_line_maps (&pfile->line_maps);
+ linemap_free (&pfile->line_maps);
free (pfile);
}
@@ -699,8 +318,7 @@ static const struct builtin operator_array[] =
/* Mark the C++ named operators in the hash table. */
static void
-mark_named_operators (pfile)
- cpp_reader *pfile;
+mark_named_operators (cpp_reader *pfile)
{
const struct builtin *b;
@@ -710,15 +328,16 @@ mark_named_operators (pfile)
{
cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
hp->flags |= NODE_OPERATOR;
- hp->value.operator = b->value;
+ hp->is_directive = 0;
+ hp->directive_index = b->value;
}
}
-/* Subroutine of cpp_read_main_file; reads the builtins table above and
- enters them, and language-specific macros, into the hash table. */
-static void
-init_builtins (pfile)
- cpp_reader *pfile;
+/* Read the builtins table above and enter them, and language-specific
+ macros, into the hash table. HOSTED is true if this is a hosted
+ environment. */
+void
+cpp_init_builtins (cpp_reader *pfile, int hosted)
{
const struct builtin *b;
size_t n = ARRAY_SIZE (builtin_array);
@@ -743,143 +362,20 @@ init_builtins (pfile)
else if (CPP_OPTION (pfile, c99))
_cpp_define_builtin (pfile, "__STDC_VERSION__ 199901L");
+ if (hosted)
+ _cpp_define_builtin (pfile, "__STDC_HOSTED__ 1");
+ else
+ _cpp_define_builtin (pfile, "__STDC_HOSTED__ 0");
+
if (CPP_OPTION (pfile, objc))
_cpp_define_builtin (pfile, "__OBJC__ 1");
-
- if (pfile->cb.register_builtins)
- (*pfile->cb.register_builtins) (pfile);
-}
-
-/* And another subroutine. This one sets up the standard include path. */
-static void
-init_standard_includes (pfile)
- cpp_reader *pfile;
-{
- char *path;
- const struct default_include *p;
- const char *specd_prefix = CPP_OPTION (pfile, include_prefix);
-
- /* Several environment variables may add to the include search path.
- CPATH specifies an additional list of directories to be searched
- as if specified with -I, while C_INCLUDE_PATH, CPLUS_INCLUDE_PATH,
- etc. specify an additional list of directories to be searched as
- if specified with -isystem, for the language indicated. */
-
- GET_ENVIRONMENT (path, "CPATH");
- if (path != 0 && *path != 0)
- path_include (pfile, path, BRACKET);
-
- switch ((CPP_OPTION (pfile, objc) << 1) + CPP_OPTION (pfile, cplusplus))
- {
- case 0:
- GET_ENVIRONMENT (path, "C_INCLUDE_PATH");
- break;
- case 1:
- GET_ENVIRONMENT (path, "CPLUS_INCLUDE_PATH");
- break;
- case 2:
- GET_ENVIRONMENT (path, "OBJC_INCLUDE_PATH");
- break;
- case 3:
- GET_ENVIRONMENT (path, "OBJCPLUS_INCLUDE_PATH");
- break;
- }
- if (path != 0 && *path != 0)
- path_include (pfile, path, SYSTEM);
-
- /* Search "translated" versions of GNU directories.
- These have /usr/local/lib/gcc... replaced by specd_prefix. */
- if (specd_prefix != 0 && cpp_GCC_INCLUDE_DIR_len)
- {
- /* Remove the `include' from /usr/local/lib/gcc.../include.
- GCC_INCLUDE_DIR will always end in /include. */
- int default_len = cpp_GCC_INCLUDE_DIR_len;
- char *default_prefix = (char *) alloca (default_len + 1);
- int specd_len = strlen (specd_prefix);
-
- memcpy (default_prefix, cpp_GCC_INCLUDE_DIR, default_len);
- default_prefix[default_len] = '\0';
-
- for (p = cpp_include_defaults; p->fname; p++)
- {
- /* Some standard dirs are only for C++. */
- if (!p->cplusplus
- || (CPP_OPTION (pfile, cplusplus)
- && !CPP_OPTION (pfile, no_standard_cplusplus_includes)))
- {
- /* Does this dir start with the prefix? */
- if (!strncmp (p->fname, default_prefix, default_len))
- {
- /* Yes; change prefix and add to search list. */
- int flen = strlen (p->fname);
- int this_len = specd_len + flen - default_len;
- char *str = (char *) xmalloc (this_len + 1);
- memcpy (str, specd_prefix, specd_len);
- memcpy (str + specd_len,
- p->fname + default_len,
- flen - default_len + 1);
-
- append_include_chain (pfile, str, SYSTEM, p->cxx_aware);
- }
- }
- }
- }
-
- /* Search ordinary names for GNU include directories. */
- for (p = cpp_include_defaults; p->fname; p++)
- {
- /* Some standard dirs are only for C++. */
- if (!p->cplusplus
- || (CPP_OPTION (pfile, cplusplus)
- && !CPP_OPTION (pfile, no_standard_cplusplus_includes)))
- {
- char *str = update_path (p->fname, p->component);
- append_include_chain (pfile, str, SYSTEM, p->cxx_aware);
- }
- }
-}
-
-/* Pushes a command line -imacro and -include file indicated by P onto
- the buffer stack. Returns nonzero if successful. */
-static bool
-push_include (pfile, p)
- cpp_reader *pfile;
- struct pending_option *p;
-{
- cpp_token header;
-
- /* Later: maybe update this to use the #include "" search path
- if cpp_read_file fails. */
- header.type = CPP_STRING;
- header.val.str.text = (const unsigned char *) p->arg;
- header.val.str.len = strlen (p->arg);
- /* Make the command line directive take up a line. */
- pfile->line++;
-
- return _cpp_execute_include (pfile, &header, IT_CMDLINE);
-}
-
-/* Frees a pending_option chain. */
-static void
-free_chain (head)
- struct pending_option *head;
-{
- struct pending_option *next;
-
- while (head)
- {
- next = head->next;
- free (head);
- head = next;
- }
}
/* Sanity-checks are dependent on command-line options, so it is
called as a subroutine of cpp_read_main_file (). */
#if ENABLE_CHECKING
-static void sanity_checks PARAMS ((cpp_reader *));
-static void sanity_checks (pfile)
- cpp_reader *pfile;
+static void sanity_checks (cpp_reader *);
+static void sanity_checks (cpp_reader *pfile)
{
cppchar_t test = 0;
size_t max_precision = 2 * CHAR_BIT * sizeof (cpp_num_part);
@@ -888,36 +384,39 @@ static void sanity_checks (pfile)
type precisions made by cpplib. */
test--;
if (test < 1)
- cpp_error (pfile, DL_ICE, "cppchar_t must be an unsigned type");
+ cpp_error (pfile, CPP_DL_ICE, "cppchar_t must be an unsigned type");
if (CPP_OPTION (pfile, precision) > max_precision)
- cpp_error (pfile, DL_ICE,
- "preprocessor arithmetic has maximum precision of %lu bits; target requires %lu bits",
+ cpp_error (pfile, CPP_DL_ICE,
+ "preprocessor arithmetic has maximum precision of %lu bits;"
+ " target requires %lu bits",
(unsigned long) max_precision,
(unsigned long) CPP_OPTION (pfile, precision));
if (CPP_OPTION (pfile, precision) < CPP_OPTION (pfile, int_precision))
- cpp_error (pfile, DL_ICE,
+ cpp_error (pfile, CPP_DL_ICE,
"CPP arithmetic must be at least as precise as a target int");
if (CPP_OPTION (pfile, char_precision) < 8)
- cpp_error (pfile, DL_ICE, "target char is less than 8 bits wide");
+ cpp_error (pfile, CPP_DL_ICE, "target char is less than 8 bits wide");
if (CPP_OPTION (pfile, wchar_precision) < CPP_OPTION (pfile, char_precision))
- cpp_error (pfile, DL_ICE,
+ cpp_error (pfile, CPP_DL_ICE,
"target wchar_t is narrower than target char");
if (CPP_OPTION (pfile, int_precision) < CPP_OPTION (pfile, char_precision))
- cpp_error (pfile, DL_ICE,
+ cpp_error (pfile, CPP_DL_ICE,
"target int is narrower than target char");
/* This is assumed in eval_token() and could be fixed if necessary. */
if (sizeof (cppchar_t) > sizeof (cpp_num_part))
- cpp_error (pfile, DL_ICE, "CPP half-integer narrower than CPP character");
+ cpp_error (pfile, CPP_DL_ICE,
+ "CPP half-integer narrower than CPP character");
if (CPP_OPTION (pfile, wchar_precision) > BITS_PER_CPPCHAR_T)
- cpp_error (pfile, DL_ICE,
- "CPP on this host cannot handle wide character constants over %lu bits, but the target requires %lu bits",
+ cpp_error (pfile, CPP_DL_ICE,
+ "CPP on this host cannot handle wide character constants over"
+ " %lu bits, but the target requires %lu bits",
(unsigned long) BITS_PER_CPPCHAR_T,
(unsigned long) CPP_OPTION (pfile, wchar_precision));
}
@@ -929,10 +428,7 @@ static void sanity_checks (pfile)
cpp_read_main_file(). If no targets have been added before
cpp_read_main_file(), then the default target is used. */
void
-cpp_add_dependency_target (pfile, target, quote)
- cpp_reader *pfile;
- const char *target;
- int quote;
+cpp_add_dependency_target (cpp_reader *pfile, const char *target, int quote)
{
if (!pfile->deps)
pfile->deps = deps_init ();
@@ -941,44 +437,25 @@ cpp_add_dependency_target (pfile, target, quote)
}
/* This is called after options have been parsed, and partially
- processed. Setup for processing input from the file named FNAME,
- or stdin if it is the empty string. Return the original filename
- on success (e.g. foo.i->foo.c), or NULL on failure. */
-const char *
-cpp_read_main_file (pfile, fname, table)
- cpp_reader *pfile;
- const char *fname;
- hash_table *table;
+ processed. */
+void
+cpp_post_options (cpp_reader *pfile)
{
sanity_checks (pfile);
post_options (pfile);
- /* The front ends don't set up the hash table until they have
- finished processing the command line options, so initializing the
- hashtable is deferred until now. */
- _cpp_init_hashtable (pfile, table);
-
- /* Set up the include search path now. */
- if (! CPP_OPTION (pfile, no_standard_includes))
- init_standard_includes (pfile);
-
- merge_include_chains (pfile);
-
- /* With -v, print the list of dirs to search. */
- if (CPP_OPTION (pfile, verbose))
- {
- struct search_path *l;
- fprintf (stderr, _("#include \"...\" search starts here:\n"));
- for (l = CPP_OPTION (pfile, quote_include); l; l = l->next)
- {
- if (l == CPP_OPTION (pfile, bracket_include))
- fprintf (stderr, _("#include <...> search starts here:\n"));
- fprintf (stderr, " %s\n", l->name);
- }
- fprintf (stderr, _("End of search list.\n"));
- }
+ /* Mark named operators before handling command line macros. */
+ if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names))
+ mark_named_operators (pfile);
+}
+/* Setup for processing input from the file named FNAME, or stdin if
+ it is the empty string. Return the original filename
+ on success (e.g. foo.i->foo.c), or NULL on failure. */
+const char *
+cpp_read_main_file (cpp_reader *pfile, const char *fname)
+{
if (CPP_OPTION (pfile, deps.style) != DEPS_NONE)
{
if (!pfile->deps)
@@ -988,21 +465,21 @@ cpp_read_main_file (pfile, fname, table)
deps_add_default_target (pfile->deps, fname);
}
- /* Open the main input file. */
- if (!_cpp_read_file (pfile, fname))
+ pfile->main_file
+ = _cpp_find_file (pfile, fname, &pfile->no_search_path, false);
+ if (_cpp_find_failed (pfile->main_file))
return NULL;
- /* Set this here so the client can change the option if it wishes,
- and after stacking the main file so we don't trace the main
- file. */
- pfile->line_maps.trace_includes = CPP_OPTION (pfile, print_include_names);
+ _cpp_stack_file (pfile, pfile->main_file, false);
/* For foo.i, read the original filename foo.c now, for the benefit
of the front ends. */
if (CPP_OPTION (pfile, preprocessed))
- read_original_filename (pfile);
-
- return pfile->map->to_file;
+ {
+ read_original_filename (pfile);
+ fname = pfile->map->to_file;
+ }
+ return fname;
}
/* For preprocessed files, if the first tokens are of the form # NUM.
@@ -1010,8 +487,7 @@ cpp_read_main_file (pfile, fname, table)
generate file_change callbacks, which the front ends must handle
appropriately given their state of initialization. */
static void
-read_original_filename (pfile)
- cpp_reader *pfile;
+read_original_filename (cpp_reader *pfile)
{
const cpp_token *token, *token1;
@@ -1027,6 +503,7 @@ read_original_filename (pfile)
if (token1->type == CPP_NUMBER)
{
_cpp_handle_directive (pfile, token->flags & PREV_WHITE);
+ read_original_directory (pfile);
return;
}
}
@@ -1035,83 +512,62 @@ read_original_filename (pfile)
_cpp_backup_tokens (pfile, 1);
}
-/* Handle pending command line options: -D, -U, -A, -imacros and
- -include. This should be called after debugging has been properly
- set up in the front ends. */
-void
-cpp_finish_options (pfile)
- cpp_reader *pfile;
+/* For preprocessed files, if the tokens following the first filename
+ line is of the form # <line> "/path/name//", handle the
+ directive so we know the original current directory. */
+static void
+read_original_directory (cpp_reader *pfile)
{
- /* Mark named operators before handling command line macros. */
- if (CPP_OPTION (pfile, cplusplus) && CPP_OPTION (pfile, operator_names))
- mark_named_operators (pfile);
+ const cpp_token *hash, *token;
- /* Install builtins and process command line macros etc. in the order
- they appeared, but only if not already preprocessed. */
- if (! CPP_OPTION (pfile, preprocessed))
+ /* Lex ahead; if the first tokens are of the form # NUM, then
+ process the directive, otherwise back up. */
+ hash = _cpp_lex_direct (pfile);
+ if (hash->type != CPP_HASH)
{
- struct pending_option *p;
-
- /* Prevent -Wunused-macros with command-line redefinitions. */
- pfile->first_unused_line = (unsigned int) -1;
- _cpp_do_file_change (pfile, LC_RENAME, _("<built-in>"), 1, 0);
- init_builtins (pfile);
- _cpp_do_file_change (pfile, LC_RENAME, _("<command line>"), 1, 0);
- for (p = CPP_OPTION (pfile, pending)->directive_head; p; p = p->next)
- (*p->handler) (pfile, p->arg);
-
- /* Scan -imacros files after -D, -U, but before -include.
- pfile->next_include_file is NULL, so _cpp_pop_buffer does not
- push -include files. */
- for (p = CPP_OPTION (pfile, pending)->imacros_head; p; p = p->next)
- if (push_include (pfile, p))
- cpp_scan_nooutput (pfile);
-
- pfile->next_include_file = &CPP_OPTION (pfile, pending)->include_head;
- _cpp_maybe_push_include_file (pfile);
+ _cpp_backup_tokens (pfile, 1);
+ return;
}
- pfile->first_unused_line = pfile->line;
-
- free_chain (CPP_OPTION (pfile, pending)->imacros_head);
- free_chain (CPP_OPTION (pfile, pending)->directive_head);
-}
+ token = _cpp_lex_direct (pfile);
-/* Push the next buffer on the stack given by -include, if any. */
-void
-_cpp_maybe_push_include_file (pfile)
- cpp_reader *pfile;
-{
- if (pfile->next_include_file)
+ if (token->type != CPP_NUMBER)
{
- struct pending_option *head = *pfile->next_include_file;
+ _cpp_backup_tokens (pfile, 2);
+ return;
+ }
- while (head && !push_include (pfile, head))
- head = head->next;
+ token = _cpp_lex_direct (pfile);
- if (head)
- pfile->next_include_file = &head->next;
- else
- {
- /* All done; restore the line map from <command line>. */
- _cpp_do_file_change (pfile, LC_RENAME,
- pfile->line_maps.maps[0].to_file, 1, 0);
- /* Don't come back here again. */
- pfile->next_include_file = NULL;
- }
+ if (token->type != CPP_STRING
+ || ! (token->val.str.len >= 5
+ && token->val.str.text[token->val.str.len-2] == '/'
+ && token->val.str.text[token->val.str.len-3] == '/'))
+ {
+ _cpp_backup_tokens (pfile, 3);
+ return;
}
+
+ if (pfile->cb.dir_change)
+ {
+ char *debugdir = alloca (token->val.str.len - 3);
+
+ memcpy (debugdir, (const char *) token->val.str.text + 1,
+ token->val.str.len - 4);
+ debugdir[token->val.str.len - 4] = '\0';
+
+ pfile->cb.dir_change (pfile, debugdir);
+ }
}
/* This is called at the end of preprocessing. It pops the last
buffer and writes dependency output, and returns the number of
errors.
-
+
Maybe it should also reset state, such that you could call
cpp_start_read with a new filename to restart processing. */
int
-cpp_finish (pfile, deps_stream)
- cpp_reader *pfile;
- FILE *deps_stream;
+cpp_finish (cpp_reader *pfile, FILE *deps_stream)
{
/* Warn about unused macros before popping the final buffer. */
if (CPP_OPTION (pfile, warn_unused_macros))
@@ -1142,308 +598,8 @@ cpp_finish (pfile, deps_stream)
return pfile->errors;
}
-/* Add a directive to be handled later in the initialization phase. */
-static void
-new_pending_directive (pend, text, handler)
- struct cpp_pending *pend;
- const char *text;
- cl_directive_handler handler;
-{
- struct pending_option *o = (struct pending_option *)
- xmalloc (sizeof (struct pending_option));
-
- o->arg = text;
- o->next = NULL;
- o->handler = handler;
- APPEND (pend, directive, o);
-}
-
-/* Irix6 "cc -n32" and OSF4 cc have problems with char foo[] = ("string");
- I.e. a const string initializer with parens around it. That is
- what N_("string") resolves to, so we make no_* be macros instead. */
-#define no_ass N_("assertion missing after %s")
-#define no_dir N_("directory name missing after %s")
-#define no_fil N_("file name missing after %s")
-#define no_mac N_("macro name missing after %s")
-#define no_pth N_("path name missing after %s")
-
-/* This is the list of all command line options, with the leading
- "-" removed. It must be sorted in ASCII collating order. */
-#define COMMAND_LINE_OPTIONS \
- DEF_OPT("A", no_ass, OPT_A) \
- DEF_OPT("D", no_mac, OPT_D) \
- DEF_OPT("I", no_dir, OPT_I) \
- DEF_OPT("U", no_mac, OPT_U) \
- DEF_OPT("idirafter", no_dir, OPT_idirafter) \
- DEF_OPT("imacros", no_fil, OPT_imacros) \
- DEF_OPT("include", no_fil, OPT_include) \
- DEF_OPT("iprefix", no_pth, OPT_iprefix) \
- DEF_OPT("isystem", no_dir, OPT_isystem) \
- DEF_OPT("iwithprefix", no_dir, OPT_iwithprefix) \
- DEF_OPT("iwithprefixbefore", no_dir, OPT_iwithprefixbefore)
-
-#define DEF_OPT(text, msg, code) code,
-enum opt_code
-{
- COMMAND_LINE_OPTIONS
- N_OPTS
-};
-#undef DEF_OPT
-
-struct cl_option
-{
- const char *opt_text;
- const char *msg;
- size_t opt_len;
- enum opt_code opt_code;
-};
-
-#define DEF_OPT(text, msg, code) { text, msg, sizeof(text) - 1, code },
-#ifdef HOST_EBCDIC
-static struct cl_option cl_options[] =
-#else
-static const struct cl_option cl_options[] =
-#endif
-{
- COMMAND_LINE_OPTIONS
-};
-#undef DEF_OPT
-#undef COMMAND_LINE_OPTIONS
-
-/* Perform a binary search to find which, if any, option the given
- command-line matches. Returns its index in the option array,
- negative on failure. Complications arise since some options can be
- suffixed with an argument, and multiple complete matches can occur,
- e.g. -pedantic and -pedantic-errors. */
-static int
-parse_option (input)
- const char *input;
-{
- unsigned int md, mn, mx;
- size_t opt_len;
- int comp;
-
- mn = 0;
- mx = N_OPTS;
-
- while (mx > mn)
- {
- md = (mn + mx) / 2;
-
- opt_len = cl_options[md].opt_len;
- comp = strncmp (input, cl_options[md].opt_text, opt_len);
-
- if (comp > 0)
- mn = md + 1;
- else if (comp < 0)
- mx = md;
- else
- {
- if (input[opt_len] == '\0')
- return md;
- /* We were passed more text. If the option takes an argument,
- we may match a later option or we may have been passed the
- argument. The longest possible option match succeeds.
- If the option takes no arguments we have not matched and
- continue the search (e.g. input="stdc++" match was "stdc"). */
- mn = md + 1;
- if (cl_options[md].msg)
- {
- /* Scan forwards. If we get an exact match, return it.
- Otherwise, return the longest option-accepting match.
- This loops no more than twice with current options. */
- mx = md;
- for (; mn < (unsigned int) N_OPTS; mn++)
- {
- opt_len = cl_options[mn].opt_len;
- if (strncmp (input, cl_options[mn].opt_text, opt_len))
- break;
- if (input[opt_len] == '\0')
- return mn;
- if (cl_options[mn].msg)
- mx = mn;
- }
- return mx;
- }
- }
- }
-
- return -1;
-}
-
-/* Handle one command-line option in (argc, argv).
- Can be called multiple times, to handle multiple sets of options.
- Returns number of strings consumed. */
-int
-cpp_handle_option (pfile, argc, argv)
- cpp_reader *pfile;
- int argc;
- char **argv;
-{
- int i = 0;
- struct cpp_pending *pend = CPP_OPTION (pfile, pending);
-
- {
- enum opt_code opt_code;
- int opt_index;
- const char *arg = 0;
-
- /* Skip over '-'. */
- opt_index = parse_option (&argv[i][1]);
- if (opt_index < 0)
- return i;
-
- opt_code = cl_options[opt_index].opt_code;
- if (cl_options[opt_index].msg)
- {
- arg = &argv[i][cl_options[opt_index].opt_len + 1];
- if (arg[0] == '\0')
- {
- arg = argv[++i];
- if (!arg)
- {
- cpp_error (pfile, DL_ERROR,
- cl_options[opt_index].msg, argv[i - 1]);
- return argc;
- }
- }
- }
-
- switch (opt_code)
- {
- case N_OPTS: /* Shut GCC up. */
- break;
-
- case OPT_D:
- new_pending_directive (pend, arg, cpp_define);
- break;
- case OPT_iprefix:
- CPP_OPTION (pfile, include_prefix) = arg;
- CPP_OPTION (pfile, include_prefix_len) = strlen (arg);
- break;
-
- case OPT_A:
- if (arg[0] == '-')
- new_pending_directive (pend, arg + 1, cpp_unassert);
- else
- new_pending_directive (pend, arg, cpp_assert);
- break;
- case OPT_U:
- new_pending_directive (pend, arg, cpp_undef);
- break;
- case OPT_I: /* Add directory to path for includes. */
- if (!strcmp (arg, "-"))
- {
- /* -I- means:
- Use the preceding -I directories for #include "..."
- but not #include <...>.
- Don't search the directory of the present file
- for #include "...". (Note that -I. -I- is not the same as
- the default setup; -I. uses the compiler's working dir.) */
- if (! CPP_OPTION (pfile, ignore_srcdir))
- {
- pend->quote_head = pend->brack_head;
- pend->quote_tail = pend->brack_tail;
- pend->brack_head = 0;
- pend->brack_tail = 0;
- CPP_OPTION (pfile, ignore_srcdir) = 1;
- }
- else
- {
- cpp_error (pfile, DL_ERROR, "-I- specified twice");
- return argc;
- }
- }
- else
- append_include_chain (pfile, xstrdup (arg), BRACKET, 0);
- break;
- case OPT_isystem:
- /* Add directory to beginning of system include path, as a system
- include directory. */
- append_include_chain (pfile, xstrdup (arg), SYSTEM, 0);
- break;
- case OPT_include:
- case OPT_imacros:
- {
- struct pending_option *o = (struct pending_option *)
- xmalloc (sizeof (struct pending_option));
- o->arg = arg;
- o->next = NULL;
-
- if (opt_code == OPT_include)
- APPEND (pend, include, o);
- else
- APPEND (pend, imacros, o);
- }
- break;
- case OPT_iwithprefix:
- /* Add directory to end of path for includes,
- with the default prefix at the front of its name. */
- /* fall through */
- case OPT_iwithprefixbefore:
- /* Add directory to main path for includes,
- with the default prefix at the front of its name. */
- {
- char *fname;
- int len;
-
- len = strlen (arg);
-
- if (CPP_OPTION (pfile, include_prefix) != 0)
- {
- size_t ipl = CPP_OPTION (pfile, include_prefix_len);
- fname = xmalloc (ipl + len + 1);
- memcpy (fname, CPP_OPTION (pfile, include_prefix), ipl);
- memcpy (fname + ipl, arg, len + 1);
- }
- else if (cpp_GCC_INCLUDE_DIR_len)
- {
- fname = xmalloc (cpp_GCC_INCLUDE_DIR_len + len + 1);
- memcpy (fname, cpp_GCC_INCLUDE_DIR, cpp_GCC_INCLUDE_DIR_len);
- memcpy (fname + cpp_GCC_INCLUDE_DIR_len, arg, len + 1);
- }
- else
- fname = xstrdup (arg);
-
- append_include_chain (pfile, fname,
- opt_code == OPT_iwithprefix ? SYSTEM: BRACKET, 0);
- }
- break;
- case OPT_idirafter:
- /* Add directory to end of path for includes. */
- append_include_chain (pfile, xstrdup (arg), AFTER, 0);
- break;
- }
- }
- return i + 1;
-}
-
-/* Handle command-line options in (argc, argv).
- Can be called multiple times, to handle multiple sets of options.
- Returns if an unrecognized option is seen.
- Returns number of strings consumed. */
-int
-cpp_handle_options (pfile, argc, argv)
- cpp_reader *pfile;
- int argc;
- char **argv;
-{
- int i;
- int strings_processed;
-
- for (i = 0; i < argc; i += strings_processed)
- {
- strings_processed = cpp_handle_option (pfile, argc - i, argv + i);
- if (strings_processed == 0)
- break;
- }
-
- return i;
-}
-
static void
-post_options (pfile)
- cpp_reader *pfile;
+post_options (cpp_reader *pfile)
{
/* -Wtraditional is not useful in C++ mode. */
if (CPP_OPTION (pfile, cplusplus))
@@ -1457,7 +613,16 @@ post_options (pfile)
CPP_OPTION (pfile, traditional) = 0;
}
- /* Traditional CPP does not accurately track column information. */
+ if (CPP_OPTION (pfile, warn_trigraphs) == 2)
+ CPP_OPTION (pfile, warn_trigraphs) = !CPP_OPTION (pfile, trigraphs);
+
if (CPP_OPTION (pfile, traditional))
- CPP_OPTION (pfile, show_column) = 0;
+ {
+ CPP_OPTION (pfile, cplusplus_comments) = 0;
+
+ /* Traditional CPP does not accurately track column information. */
+ CPP_OPTION (pfile, show_column) = 0;
+ CPP_OPTION (pfile, trigraphs) = 0;
+ CPP_OPTION (pfile, warn_trigraphs) = 0;
+ }
}
diff --git a/contrib/gcc/cpplex.c b/contrib/gcc/cpplex.c
index 7db6b24b2538..5e92a2146b81 100644
--- a/contrib/gcc/cpplex.c
+++ b/contrib/gcc/cpplex.c
@@ -1,10 +1,9 @@
/* CPP Library - lexical analysis.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
Broken out to separate file, Zack Weinberg, Mar 2000
- Single-pass line tokenization by Neil Booth, April 2000
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
@@ -25,20 +24,11 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "cpplib.h"
#include "cpphash.h"
-#ifdef MULTIBYTE_CHARS
-#include "mbchar.h"
-#include <locale.h>
-#endif
-
-/* Tokens with SPELL_STRING store their spelling in the token list,
- and it's length in the token->val.name.len. */
enum spell_type
{
SPELL_OPERATOR = 0,
- SPELL_CHAR,
SPELL_IDENT,
- SPELL_NUMBER,
- SPELL_STRING,
+ SPELL_LITERAL,
SPELL_NONE
};
@@ -52,49 +42,37 @@ static const unsigned char *const digraph_spellings[] =
{ U"%:", U"%:%:", U"<:", U":>", U"<%", U"%>" };
#define OP(e, s) { SPELL_OPERATOR, U s },
-#define TK(e, s) { s, U STRINGX (e) },
+#define TK(e, s) { s, U #e },
static const struct token_spelling token_spellings[N_TTYPES] = { TTYPE_TABLE };
#undef OP
#undef TK
#define TOKEN_SPELL(token) (token_spellings[(token)->type].category)
#define TOKEN_NAME(token) (token_spellings[(token)->type].name)
-#define BACKUP() do {buffer->cur = buffer->backup_to;} while (0)
-
-static void handle_newline PARAMS ((cpp_reader *));
-static cppchar_t skip_escaped_newlines PARAMS ((cpp_reader *));
-static cppchar_t get_effective_char PARAMS ((cpp_reader *));
-
-static int skip_block_comment PARAMS ((cpp_reader *));
-static int skip_line_comment PARAMS ((cpp_reader *));
-static void adjust_column PARAMS ((cpp_reader *));
-static int skip_whitespace PARAMS ((cpp_reader *, cppchar_t));
-static cpp_hashnode *parse_identifier PARAMS ((cpp_reader *));
-static uchar *parse_slow PARAMS ((cpp_reader *, const uchar *, int,
- unsigned int *));
-static void parse_number PARAMS ((cpp_reader *, cpp_string *, int));
-static int unescaped_terminator_p PARAMS ((cpp_reader *, const uchar *));
-static void parse_string PARAMS ((cpp_reader *, cpp_token *, cppchar_t));
-static bool trigraph_p PARAMS ((cpp_reader *));
-static void save_comment PARAMS ((cpp_reader *, cpp_token *, const uchar *,
- cppchar_t));
-static bool continue_after_nul PARAMS ((cpp_reader *));
-static int name_p PARAMS ((cpp_reader *, const cpp_string *));
-static int maybe_read_ucs PARAMS ((cpp_reader *, const unsigned char **,
- const unsigned char *, cppchar_t *));
-static tokenrun *next_tokenrun PARAMS ((tokenrun *));
-
-static unsigned int hex_digit_value PARAMS ((unsigned int));
-static _cpp_buff *new_buff PARAMS ((size_t));
+
+static void add_line_note (cpp_buffer *, const uchar *, unsigned int);
+static int skip_line_comment (cpp_reader *);
+static void skip_whitespace (cpp_reader *, cppchar_t);
+static cpp_hashnode *lex_identifier (cpp_reader *, const uchar *);
+static void lex_number (cpp_reader *, cpp_string *);
+static bool forms_identifier_p (cpp_reader *, int);
+static void lex_string (cpp_reader *, cpp_token *, const uchar *);
+static void save_comment (cpp_reader *, cpp_token *, const uchar *, cppchar_t);
+static void create_literal (cpp_reader *, cpp_token *, const uchar *,
+ unsigned int, enum cpp_ttype);
+static bool warn_in_comment (cpp_reader *, _cpp_line_note *);
+static int name_p (cpp_reader *, const cpp_string *);
+static tokenrun *next_tokenrun (tokenrun *);
+
+static _cpp_buff *new_buff (size_t);
+
/* Utility routine:
Compares, the token TOKEN to the NUL-terminated string STRING.
TOKEN must be a CPP_NAME. Returns 1 for equal, 0 for unequal. */
int
-cpp_ideq (token, string)
- const cpp_token *token;
- const char *string;
+cpp_ideq (const cpp_token *token, const char *string)
{
if (token->type != CPP_NAME)
return 0;
@@ -102,302 +80,323 @@ cpp_ideq (token, string)
return !ustrcmp (NODE_NAME (token->val.node), (const uchar *) string);
}
-/* Call when meeting a newline, assumed to be in buffer->cur[-1].
- Returns with buffer->cur pointing to the character immediately
- following the newline (combination). */
+/* Record a note TYPE at byte POS into the current cleaned logical
+ line. */
static void
-handle_newline (pfile)
- cpp_reader *pfile;
+add_line_note (cpp_buffer *buffer, const uchar *pos, unsigned int type)
{
- cpp_buffer *buffer = pfile->buffer;
-
- /* Handle CR-LF and LF-CR. Most other implementations (e.g. java)
- only accept CR-LF; maybe we should fall back to that behavior? */
- if (buffer->cur[-1] + buffer->cur[0] == '\r' + '\n')
- buffer->cur++;
-
- buffer->line_base = buffer->cur;
- buffer->col_adjust = 0;
- pfile->line++;
-}
-
-/* Subroutine of skip_escaped_newlines; called when a 3-character
- sequence beginning with "??" is encountered. buffer->cur points to
- the second '?'.
-
- Warn if necessary, and returns true if the sequence forms a
- trigraph and the trigraph should be honored. */
-static bool
-trigraph_p (pfile)
- cpp_reader *pfile;
-{
- cpp_buffer *buffer = pfile->buffer;
- cppchar_t from_char = buffer->cur[1];
- bool accept;
-
- if (!_cpp_trigraph_map[from_char])
- return false;
-
- accept = CPP_OPTION (pfile, trigraphs);
-
- /* Don't warn about trigraphs in comments. */
- if (CPP_OPTION (pfile, warn_trigraphs) && !pfile->state.lexing_comment)
+ if (buffer->notes_used == buffer->notes_cap)
{
- if (accept)
- cpp_error_with_line (pfile, DL_WARNING,
- pfile->line, CPP_BUF_COL (buffer) - 1,
- "trigraph ??%c converted to %c",
- (int) from_char,
- (int) _cpp_trigraph_map[from_char]);
- else if (buffer->cur != buffer->last_Wtrigraphs)
- {
- buffer->last_Wtrigraphs = buffer->cur;
- cpp_error_with_line (pfile, DL_WARNING,
- pfile->line, CPP_BUF_COL (buffer) - 1,
- "trigraph ??%c ignored", (int) from_char);
- }
+ buffer->notes_cap = buffer->notes_cap * 2 + 200;
+ buffer->notes = xrealloc (buffer->notes,
+ buffer->notes_cap * sizeof (_cpp_line_note));
}
- return accept;
+ buffer->notes[buffer->notes_used].pos = pos;
+ buffer->notes[buffer->notes_used].type = type;
+ buffer->notes_used++;
}
-/* Skips any escaped newlines introduced by '?' or a '\\', assumed to
- lie in buffer->cur[-1]. Returns the next byte, which will be in
- buffer->cur[-1]. This routine performs preprocessing stages 1 and
- 2 of the ISO C standard. */
-static cppchar_t
-skip_escaped_newlines (pfile)
- cpp_reader *pfile;
+/* Returns with a logical line that contains no escaped newlines or
+ trigraphs. This is a time-critical inner loop. */
+void
+_cpp_clean_line (cpp_reader *pfile)
{
- cpp_buffer *buffer = pfile->buffer;
- cppchar_t next = buffer->cur[-1];
+ cpp_buffer *buffer;
+ const uchar *s;
+ uchar c, *d, *p;
+
+ buffer = pfile->buffer;
+ buffer->cur_note = buffer->notes_used = 0;
+ buffer->cur = buffer->line_base = buffer->next_line;
+ buffer->need_line = false;
+ s = buffer->next_line - 1;
- /* Only do this if we apply stages 1 and 2. */
if (!buffer->from_stage3)
{
- const unsigned char *saved_cur;
- cppchar_t next1;
-
- do
+ /* Short circuit for the common case of an un-escaped line with
+ no trigraphs. The primary win here is by not writing any
+ data back to memory until we have to. */
+ for (;;)
{
- if (next == '?')
+ c = *++s;
+ if (c == '\n' || c == '\r')
{
- if (buffer->cur[0] != '?' || !trigraph_p (pfile))
- break;
-
- /* Translate the trigraph. */
- next = _cpp_trigraph_map[buffer->cur[1]];
- buffer->cur += 2;
- if (next != '\\')
- break;
+ d = (uchar *) s;
+
+ if (s == buffer->rlimit)
+ goto done;
+
+ /* DOS line ending? */
+ if (c == '\r' && s[1] == '\n')
+ s++;
+
+ if (s == buffer->rlimit)
+ goto done;
+
+ /* check for escaped newline */
+ p = d;
+ while (p != buffer->next_line && is_nvspace (p[-1]))
+ p--;
+ if (p == buffer->next_line || p[-1] != '\\')
+ goto done;
+
+ /* Have an escaped newline; process it and proceed to
+ the slow path. */
+ add_line_note (buffer, p - 1, p != d ? ' ' : '\\');
+ d = p - 2;
+ buffer->next_line = p - 1;
+ break;
+ }
+ if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]])
+ {
+ /* Have a trigraph. We may or may not have to convert
+ it. Add a line note regardless, for -Wtrigraphs. */
+ add_line_note (buffer, s, s[2]);
+ if (CPP_OPTION (pfile, trigraphs))
+ {
+ /* We do, and that means we have to switch to the
+ slow path. */
+ d = (uchar *) s;
+ *d = _cpp_trigraph_map[s[2]];
+ s += 2;
+ break;
+ }
}
+ }
- if (buffer->cur == buffer->rlimit)
- break;
- /* We have a backslash, and room for at least one more
- character. Skip horizontal whitespace. */
- saved_cur = buffer->cur;
- do
- next1 = *buffer->cur++;
- while (is_nvspace (next1) && buffer->cur < buffer->rlimit);
+ for (;;)
+ {
+ c = *++s;
+ *++d = c;
- if (!is_vspace (next1))
+ if (c == '\n' || c == '\r')
{
- buffer->cur = saved_cur;
- break;
- }
+ /* Handle DOS line endings. */
+ if (c == '\r' && s != buffer->rlimit && s[1] == '\n')
+ s++;
+ if (s == buffer->rlimit)
+ break;
- if (saved_cur != buffer->cur - 1
- && !pfile->state.lexing_comment)
- cpp_error (pfile, DL_WARNING,
- "backslash and newline separated by space");
+ /* Escaped? */
+ p = d;
+ while (p != buffer->next_line && is_nvspace (p[-1]))
+ p--;
+ if (p == buffer->next_line || p[-1] != '\\')
+ break;
- handle_newline (pfile);
- buffer->backup_to = buffer->cur;
- if (buffer->cur == buffer->rlimit)
+ add_line_note (buffer, p - 1, p != d ? ' ': '\\');
+ d = p - 2;
+ buffer->next_line = p - 1;
+ }
+ else if (c == '?' && s[1] == '?' && _cpp_trigraph_map[s[2]])
{
- cpp_error (pfile, DL_PEDWARN,
- "backslash-newline at end of file");
- next = EOF;
+ /* Add a note regardless, for the benefit of -Wtrigraphs. */
+ add_line_note (buffer, d, s[2]);
+ if (CPP_OPTION (pfile, trigraphs))
+ {
+ *d = _cpp_trigraph_map[s[2]];
+ s += 2;
+ }
}
- else
- next = *buffer->cur++;
}
- while (next == '\\' || next == '?');
}
+ else
+ {
+ do
+ s++;
+ while (*s != '\n' && *s != '\r');
+ d = (uchar *) s;
+
+ /* Handle DOS line endings. */
+ if (*s == '\r' && s != buffer->rlimit && s[1] == '\n')
+ s++;
+ }
+
+ done:
+ *d = '\n';
+ /* A sentinel note that should never be processed. */
+ add_line_note (buffer, d + 1, '\n');
+ buffer->next_line = s + 1;
+}
+
+/* Return true if the trigraph indicated by NOTE should be warned
+ about in a comment. */
+static bool
+warn_in_comment (cpp_reader *pfile, _cpp_line_note *note)
+{
+ const uchar *p;
+
+ /* Within comments we don't warn about trigraphs, unless the
+ trigraph forms an escaped newline, as that may change
+ behavior. */
+ if (note->type != '/')
+ return false;
+
+ /* If -trigraphs, then this was an escaped newline iff the next note
+ is coincident. */
+ if (CPP_OPTION (pfile, trigraphs))
+ return note[1].pos == note->pos;
- return next;
+ /* Otherwise, see if this forms an escaped newline. */
+ p = note->pos + 3;
+ while (is_nvspace (*p))
+ p++;
+
+ /* There might have been escaped newlines between the trigraph and the
+ newline we found. Hence the position test. */
+ return (*p == '\n' && p < note[1].pos);
}
-/* Obtain the next character, after trigraph conversion and skipping
- an arbitrarily long string of escaped newlines. The common case of
- no trigraphs or escaped newlines falls through quickly. On return,
- buffer->backup_to points to where to return to if the character is
- not to be processed. */
-static cppchar_t
-get_effective_char (pfile)
- cpp_reader *pfile;
+/* Process the notes created by add_line_note as far as the current
+ location. */
+void
+_cpp_process_line_notes (cpp_reader *pfile, int in_comment)
{
- cppchar_t next;
cpp_buffer *buffer = pfile->buffer;
- buffer->backup_to = buffer->cur;
- next = *buffer->cur++;
- if (__builtin_expect (next == '?' || next == '\\', 0))
- next = skip_escaped_newlines (pfile);
+ for (;;)
+ {
+ _cpp_line_note *note = &buffer->notes[buffer->cur_note];
+ unsigned int col;
+
+ if (note->pos > buffer->cur)
+ break;
+
+ buffer->cur_note++;
+ col = CPP_BUF_COLUMN (buffer, note->pos + 1);
- return next;
+ if (note->type == '\\' || note->type == ' ')
+ {
+ if (note->type == ' ' && !in_comment)
+ cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line, col,
+ "backslash and newline separated by space");
+
+ if (buffer->next_line > buffer->rlimit)
+ {
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line, col,
+ "backslash-newline at end of file");
+ /* Prevent "no newline at end of file" warning. */
+ buffer->next_line = buffer->rlimit;
+ }
+
+ buffer->line_base = note->pos;
+ pfile->line++;
+ }
+ else if (_cpp_trigraph_map[note->type])
+ {
+ if (CPP_OPTION (pfile, warn_trigraphs)
+ && (!in_comment || warn_in_comment (pfile, note)))
+ {
+ if (CPP_OPTION (pfile, trigraphs))
+ cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line, col,
+ "trigraph ??%c converted to %c",
+ note->type,
+ (int) _cpp_trigraph_map[note->type]);
+ else
+ {
+ cpp_error_with_line
+ (pfile, CPP_DL_WARNING, pfile->line, col,
+ "trigraph ??%c ignored, use -trigraphs to enable",
+ note->type);
+ }
+ }
+ }
+ else
+ abort ();
+ }
}
/* Skip a C-style block comment. We find the end of the comment by
seeing if an asterisk is before every '/' we encounter. Returns
- nonzero if comment terminated by EOF, zero otherwise. */
-static int
-skip_block_comment (pfile)
- cpp_reader *pfile;
+ nonzero if comment terminated by EOF, zero otherwise.
+
+ Buffer->cur points to the initial asterisk of the comment. */
+bool
+_cpp_skip_block_comment (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
- cppchar_t c = EOF, prevc = EOF;
+ const uchar *cur = buffer->cur;
+ uchar c;
- pfile->state.lexing_comment = 1;
- while (buffer->cur != buffer->rlimit)
- {
- prevc = c, c = *buffer->cur++;
-
- /* FIXME: For speed, create a new character class of characters
- of interest inside block comments. */
- if (c == '?' || c == '\\')
- c = skip_escaped_newlines (pfile);
+ cur++;
+ if (*cur == '/')
+ cur++;
+ for (;;)
+ {
/* People like decorating comments with '*', so check for '/'
instead for efficiency. */
+ c = *cur++;
+
if (c == '/')
{
- if (prevc == '*')
+ if (cur[-2] == '*')
break;
/* Warn about potential nested comments, but not if the '/'
comes immediately before the true comment delimiter.
Don't bother to get it right across escaped newlines. */
if (CPP_OPTION (pfile, warn_comments)
- && buffer->cur[0] == '*' && buffer->cur[1] != '/')
- cpp_error_with_line (pfile, DL_WARNING,
- pfile->line, CPP_BUF_COL (buffer),
- "\"/*\" within comment");
+ && cur[0] == '*' && cur[1] != '/')
+ {
+ buffer->cur = cur;
+ cpp_error_with_line (pfile, CPP_DL_WARNING,
+ pfile->line, CPP_BUF_COL (buffer),
+ "\"/*\" within comment");
+ }
+ }
+ else if (c == '\n')
+ {
+ buffer->cur = cur - 1;
+ _cpp_process_line_notes (pfile, true);
+ if (buffer->next_line >= buffer->rlimit)
+ return true;
+ _cpp_clean_line (pfile);
+ pfile->line++;
+ cur = buffer->cur;
}
- else if (is_vspace (c))
- handle_newline (pfile);
- else if (c == '\t')
- adjust_column (pfile);
}
- pfile->state.lexing_comment = 0;
- return c != '/' || prevc != '*';
+ buffer->cur = cur;
+ _cpp_process_line_notes (pfile, true);
+ return false;
}
/* Skip a C++ line comment, leaving buffer->cur pointing to the
terminating newline. Handles escaped newlines. Returns nonzero
if a multiline comment. */
static int
-skip_line_comment (pfile)
- cpp_reader *pfile;
+skip_line_comment (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
unsigned int orig_line = pfile->line;
- cppchar_t c;
-#ifdef MULTIBYTE_CHARS
- wchar_t wc;
- int char_len;
-#endif
-
- pfile->state.lexing_comment = 1;
-#ifdef MULTIBYTE_CHARS
- /* Reset multibyte conversion state. */
- (void) local_mbtowc (NULL, NULL, 0);
-#endif
- do
- {
- if (buffer->cur == buffer->rlimit)
- goto at_eof;
-#ifdef MULTIBYTE_CHARS
- char_len = local_mbtowc (&wc, (const char *) buffer->cur,
- buffer->rlimit - buffer->cur);
- if (char_len == -1)
- {
- cpp_error (pfile, DL_WARNING,
- "ignoring invalid multibyte character");
- char_len = 1;
- c = *buffer->cur++;
- }
- else
- {
- buffer->cur += char_len;
- c = wc;
- }
-#else
- c = *buffer->cur++;
-#endif
- if (c == '?' || c == '\\')
- c = skip_escaped_newlines (pfile);
- }
- while (!is_vspace (c));
-
- /* Step back over the newline, except at EOF. */
- buffer->cur--;
- at_eof:
+ while (*buffer->cur != '\n')
+ buffer->cur++;
- pfile->state.lexing_comment = 0;
+ _cpp_process_line_notes (pfile, true);
return orig_line != pfile->line;
}
-/* pfile->buffer->cur is one beyond the \t character. Update
- col_adjust so we track the column correctly. */
+/* Skips whitespace, saving the next non-whitespace character. */
static void
-adjust_column (pfile)
- cpp_reader *pfile;
-{
- cpp_buffer *buffer = pfile->buffer;
- unsigned int col = CPP_BUF_COL (buffer) - 1; /* Zero-based column. */
-
- /* Round it up to multiple of the tabstop, but subtract 1 since the
- tab itself occupies a character position. */
- buffer->col_adjust += (CPP_OPTION (pfile, tabstop)
- - col % CPP_OPTION (pfile, tabstop)) - 1;
-}
-
-/* Skips whitespace, saving the next non-whitespace character.
- Adjusts pfile->col_adjust to account for tabs. Without this,
- tokens might be assigned an incorrect column. */
-static int
-skip_whitespace (pfile, c)
- cpp_reader *pfile;
- cppchar_t c;
+skip_whitespace (cpp_reader *pfile, cppchar_t c)
{
cpp_buffer *buffer = pfile->buffer;
- unsigned int warned = 0;
+ bool saw_NUL = false;
do
{
/* Horizontal space always OK. */
- if (c == ' ')
+ if (c == ' ' || c == '\t')
;
- else if (c == '\t')
- adjust_column (pfile);
/* Just \f \v or \0 left. */
else if (c == '\0')
- {
- if (buffer->cur - 1 == buffer->rlimit)
- return 0;
- if (!warned)
- {
- cpp_error (pfile, DL_WARNING, "null character(s) ignored");
- warned = 1;
- }
- }
+ saw_NUL = true;
else if (pfile->state.in_directive && CPP_PEDANTIC (pfile))
- cpp_error_with_line (pfile, DL_PEDWARN, pfile->line,
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line,
CPP_BUF_COL (buffer),
"%s in preprocessing directive",
c == '\f' ? "form feed" : "vertical tab");
@@ -407,16 +406,16 @@ skip_whitespace (pfile, c)
/* We only want non-vertical space, i.e. ' ' \t \f \v \0. */
while (is_nvspace (c));
+ if (saw_NUL)
+ cpp_error (pfile, CPP_DL_WARNING, "null character(s) ignored");
+
buffer->cur--;
- return 1;
}
/* See if the characters of a number token are valid in a name (no
'.', '+' or '-'). */
static int
-name_p (pfile, string)
- cpp_reader *pfile;
- const cpp_string *string;
+name_p (cpp_reader *pfile, const cpp_string *string)
{
unsigned int i;
@@ -427,315 +426,183 @@ name_p (pfile, string)
return 1;
}
-/* Parse an identifier, skipping embedded backslash-newlines. This is
- a critical inner loop. The common case is an identifier which has
- not been split by backslash-newline, does not contain a dollar
- sign, and has already been scanned (roughly 10:1 ratio of
- seen:unseen identifiers in normal code; the distribution is
- Poisson-like). Second most common case is a new identifier, not
- split and no dollar sign. The other possibilities are rare and
- have been relegated to parse_slow. */
-static cpp_hashnode *
-parse_identifier (pfile)
- cpp_reader *pfile;
+/* Returns TRUE if the sequence starting at buffer->cur is invalid in
+ an identifier. FIRST is TRUE if this starts an identifier. */
+static bool
+forms_identifier_p (cpp_reader *pfile, int first)
{
- cpp_hashnode *result;
- const uchar *cur, *base;
-
- /* Fast-path loop. Skim over a normal identifier.
- N.B. ISIDNUM does not include $. */
- cur = pfile->buffer->cur;
- while (ISIDNUM (*cur))
- cur++;
+ cpp_buffer *buffer = pfile->buffer;
- /* Check for slow-path cases. */
- if (*cur == '?' || *cur == '\\' || *cur == '$')
+ if (*buffer->cur == '$')
{
- unsigned int len;
+ if (!CPP_OPTION (pfile, dollars_in_ident))
+ return false;
- base = parse_slow (pfile, cur, 0, &len);
- result = (cpp_hashnode *)
- ht_lookup (pfile->hash_table, base, len, HT_ALLOCED);
+ buffer->cur++;
+ if (CPP_OPTION (pfile, warn_dollars) && !pfile->state.skipping)
+ {
+ CPP_OPTION (pfile, warn_dollars) = 0;
+ cpp_error (pfile, CPP_DL_PEDWARN, "'$' in identifier or number");
+ }
+
+ return true;
}
- else
+
+ /* Is this a syntactically valid UCN? */
+ if (0 && *buffer->cur == '\\'
+ && (buffer->cur[1] == 'u' || buffer->cur[1] == 'U'))
{
- base = pfile->buffer->cur - 1;
+ buffer->cur += 2;
+ if (_cpp_valid_ucn (pfile, &buffer->cur, buffer->rlimit, 1 + !first))
+ return true;
+ buffer->cur -= 2;
+ }
+
+ return false;
+}
+
+/* Lex an identifier starting at BUFFER->CUR - 1. */
+static cpp_hashnode *
+lex_identifier (cpp_reader *pfile, const uchar *base)
+{
+ cpp_hashnode *result;
+ const uchar *cur;
+
+ do
+ {
+ cur = pfile->buffer->cur;
+
+ /* N.B. ISIDNUM does not include $. */
+ while (ISIDNUM (*cur))
+ cur++;
+
pfile->buffer->cur = cur;
- result = (cpp_hashnode *)
- ht_lookup (pfile->hash_table, base, cur - base, HT_ALLOC);
}
+ while (forms_identifier_p (pfile, false));
- /* Rarely, identifiers require diagnostics when lexed.
- XXX Has to be forced out of the fast path. */
+ result = (cpp_hashnode *)
+ ht_lookup (pfile->hash_table, base, cur - base, HT_ALLOC);
+
+ /* Rarely, identifiers require diagnostics when lexed. */
if (__builtin_expect ((result->flags & NODE_DIAGNOSTIC)
&& !pfile->state.skipping, 0))
{
/* It is allowed to poison the same identifier twice. */
if ((result->flags & NODE_POISONED) && !pfile->state.poisoned_ok)
- cpp_error (pfile, DL_ERROR, "attempt to use poisoned \"%s\"",
+ cpp_error (pfile, CPP_DL_ERROR, "attempt to use poisoned \"%s\"",
NODE_NAME (result));
/* Constraint 6.10.3.5: __VA_ARGS__ should only appear in the
replacement list of a variadic macro. */
if (result == pfile->spec_nodes.n__VA_ARGS__
&& !pfile->state.va_args_ok)
- cpp_error (pfile, DL_PEDWARN,
- "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro");
+ cpp_error (pfile, CPP_DL_PEDWARN,
+ "__VA_ARGS__ can only appear in the expansion"
+ " of a C99 variadic macro");
}
return result;
}
-/* Slow path. This handles numbers and identifiers which have been
- split, or contain dollar signs. The part of the token from
- PFILE->buffer->cur-1 to CUR has already been scanned. NUMBER_P is
- 1 if it's a number, and 2 if it has a leading period. Returns a
- pointer to the token's NUL-terminated spelling in permanent
- storage, and sets PLEN to its length. */
-static uchar *
-parse_slow (pfile, cur, number_p, plen)
- cpp_reader *pfile;
- const uchar *cur;
- int number_p;
- unsigned int *plen;
-{
- cpp_buffer *buffer = pfile->buffer;
- const uchar *base = buffer->cur - 1;
- struct obstack *stack = &pfile->hash_table->stack;
- unsigned int c, prevc, saw_dollar = 0;
-
- /* Place any leading period. */
- if (number_p == 2)
- obstack_1grow (stack, '.');
-
- /* Copy the part of the token which is known to be okay. */
- obstack_grow (stack, base, cur - base);
-
- /* Now process the part which isn't. We are looking at one of
- '$', '\\', or '?' on entry to this loop. */
- prevc = cur[-1];
- c = *cur++;
- buffer->cur = cur;
- for (;;)
- {
- /* Potential escaped newline? */
- buffer->backup_to = buffer->cur - 1;
- if (c == '?' || c == '\\')
- c = skip_escaped_newlines (pfile);
-
- if (!is_idchar (c))
- {
- if (!number_p)
- break;
- if (c != '.' && !VALID_SIGN (c, prevc))
- break;
- }
-
- /* Handle normal identifier characters in this loop. */
- do
- {
- prevc = c;
- obstack_1grow (stack, c);
-
- if (c == '$')
- saw_dollar++;
-
- c = *buffer->cur++;
- }
- while (is_idchar (c));
- }
-
- /* Step back over the unwanted char. */
- BACKUP ();
-
- /* $ is not an identifier character in the standard, but is commonly
- accepted as an extension. Don't warn about it in skipped
- conditional blocks. */
- if (saw_dollar && CPP_PEDANTIC (pfile) && ! pfile->state.skipping)
- cpp_error (pfile, DL_PEDWARN, "'$' character(s) in identifier or number");
-
- /* Identifiers and numbers are null-terminated. */
- *plen = obstack_object_size (stack);
- obstack_1grow (stack, '\0');
- return obstack_finish (stack);
-}
-
-/* Parse a number, beginning with character C, skipping embedded
- backslash-newlines. LEADING_PERIOD is nonzero if there was a "."
- before C. Place the result in NUMBER. */
+/* Lex a number to NUMBER starting at BUFFER->CUR - 1. */
static void
-parse_number (pfile, number, leading_period)
- cpp_reader *pfile;
- cpp_string *number;
- int leading_period;
+lex_number (cpp_reader *pfile, cpp_string *number)
{
const uchar *cur;
+ const uchar *base;
+ uchar *dest;
- /* Fast-path loop. Skim over a normal number.
- N.B. ISIDNUM does not include $. */
- cur = pfile->buffer->cur;
- while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1]))
- cur++;
-
- /* Check for slow-path cases. */
- if (*cur == '?' || *cur == '\\' || *cur == '$')
- number->text = parse_slow (pfile, cur, 1 + leading_period, &number->len);
- else
+ base = pfile->buffer->cur - 1;
+ do
{
- const uchar *base = pfile->buffer->cur - 1;
- uchar *dest;
+ cur = pfile->buffer->cur;
- number->len = cur - base + leading_period;
- dest = _cpp_unaligned_alloc (pfile, number->len + 1);
- dest[number->len] = '\0';
- number->text = dest;
+ /* N.B. ISIDNUM does not include $. */
+ while (ISIDNUM (*cur) || *cur == '.' || VALID_SIGN (*cur, cur[-1]))
+ cur++;
- if (leading_period)
- *dest++ = '.';
- memcpy (dest, base, cur - base);
pfile->buffer->cur = cur;
}
+ while (forms_identifier_p (pfile, false));
+
+ number->len = cur - base;
+ dest = _cpp_unaligned_alloc (pfile, number->len + 1);
+ memcpy (dest, base, number->len);
+ dest[number->len] = '\0';
+ number->text = dest;
}
-/* Subroutine of parse_string. */
-static int
-unescaped_terminator_p (pfile, dest)
- cpp_reader *pfile;
- const unsigned char *dest;
+/* Create a token of type TYPE with a literal spelling. */
+static void
+create_literal (cpp_reader *pfile, cpp_token *token, const uchar *base,
+ unsigned int len, enum cpp_ttype type)
{
- const unsigned char *start, *temp;
-
- /* In #include-style directives, terminators are not escapeable. */
- if (pfile->state.angled_headers)
- return 1;
-
- start = BUFF_FRONT (pfile->u_buff);
+ uchar *dest = _cpp_unaligned_alloc (pfile, len + 1);
- /* An odd number of consecutive backslashes represents an escaped
- terminator. */
- for (temp = dest; temp > start && temp[-1] == '\\'; temp--)
- ;
-
- return ((dest - temp) & 1) == 0;
+ memcpy (dest, base, len);
+ dest[len] = '\0';
+ token->type = type;
+ token->val.str.len = len;
+ token->val.str.text = dest;
}
-/* Parses a string, character constant, or angle-bracketed header file
- name. Handles embedded trigraphs and escaped newlines. The stored
- string is guaranteed NUL-terminated, but it is not guaranteed that
- this is the first NUL since embedded NULs are preserved.
+/* Lexes a string, character constant, or angle-bracketed header file
+ name. The stored string contains the spelling, including opening
+ quote and leading any leading 'L'. It returns the type of the
+ literal, or CPP_OTHER if it was not properly terminated.
- When this function returns, buffer->cur points to the next
- character to be processed. */
+ The spelling is NUL-terminated, but it is not guaranteed that this
+ is the first NUL since embedded NULs are preserved. */
static void
-parse_string (pfile, token, terminator)
- cpp_reader *pfile;
- cpp_token *token;
- cppchar_t terminator;
+lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
{
- cpp_buffer *buffer = pfile->buffer;
- unsigned char *dest, *limit;
- cppchar_t c;
- bool warned_nulls = false;
-#ifdef MULTIBYTE_CHARS
- wchar_t wc;
- int char_len;
-#endif
-
- dest = BUFF_FRONT (pfile->u_buff);
- limit = BUFF_LIMIT (pfile->u_buff);
+ bool saw_NUL = false;
+ const uchar *cur;
+ cppchar_t terminator;
+ enum cpp_ttype type;
+
+ cur = base;
+ terminator = *cur++;
+ if (terminator == 'L')
+ terminator = *cur++;
+ if (terminator == '\"')
+ type = *base == 'L' ? CPP_WSTRING: CPP_STRING;
+ else if (terminator == '\'')
+ type = *base == 'L' ? CPP_WCHAR: CPP_CHAR;
+ else
+ terminator = '>', type = CPP_HEADER_NAME;
-#ifdef MULTIBYTE_CHARS
- /* Reset multibyte conversion state. */
- (void) local_mbtowc (NULL, NULL, 0);
-#endif
for (;;)
{
- /* We need room for another char, possibly the terminating NUL. */
- if ((size_t) (limit - dest) < 1)
- {
- size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
- _cpp_extend_buff (pfile, &pfile->u_buff, 2);
- dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
- limit = BUFF_LIMIT (pfile->u_buff);
- }
+ cppchar_t c = *cur++;
-#ifdef MULTIBYTE_CHARS
- char_len = local_mbtowc (&wc, (const char *) buffer->cur,
- buffer->rlimit - buffer->cur);
- if (char_len == -1)
- {
- cpp_error (pfile, DL_WARNING,
- "ignoring invalid multibyte character");
- char_len = 1;
- c = *buffer->cur++;
- }
- else
- {
- buffer->cur += char_len;
- c = wc;
- }
-#else
- c = *buffer->cur++;
-#endif
-
- /* Handle trigraphs, escaped newlines etc. */
- if (c == '?' || c == '\\')
- c = skip_escaped_newlines (pfile);
-
- if (c == terminator)
- {
- if (unescaped_terminator_p (pfile, dest))
- break;
- }
- else if (is_vspace (c))
+ /* In #include-style directives, terminators are not escapable. */
+ if (c == '\\' && !pfile->state.angled_headers && *cur != '\n')
+ cur++;
+ else if (c == terminator)
+ break;
+ else if (c == '\n')
{
- /* No string literal may extend over multiple lines. In
- assembly language, suppress the error except for <>
- includes. This is a kludge around not knowing where
- comments are. */
- unterminated:
- if (CPP_OPTION (pfile, lang) != CLK_ASM || terminator == '>')
- cpp_error (pfile, DL_ERROR, "missing terminating %c character",
- (int) terminator);
- buffer->cur--;
+ cur--;
+ type = CPP_OTHER;
break;
}
else if (c == '\0')
- {
- if (buffer->cur - 1 == buffer->rlimit)
- goto unterminated;
- if (!warned_nulls)
- {
- warned_nulls = true;
- cpp_error (pfile, DL_WARNING,
- "null character(s) preserved in literal");
- }
- }
-#ifdef MULTIBYTE_CHARS
- if (char_len > 1)
- {
- for ( ; char_len > 0; --char_len)
- *dest++ = (*buffer->cur - char_len);
- }
- else
-#endif
- *dest++ = c;
+ saw_NUL = true;
}
- *dest = '\0';
+ if (saw_NUL && !pfile->state.skipping)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "null character(s) preserved in literal");
- token->val.str.text = BUFF_FRONT (pfile->u_buff);
- token->val.str.len = dest - BUFF_FRONT (pfile->u_buff);
- BUFF_FRONT (pfile->u_buff) = dest + 1;
+ pfile->buffer->cur = cur;
+ create_literal (pfile, token, base, cur - base, type);
}
/* The stored comment includes the comment start and any terminator. */
static void
-save_comment (pfile, token, from, type)
- cpp_reader *pfile;
- cpp_token *token;
- const unsigned char *from;
- cppchar_t type;
+save_comment (cpp_reader *pfile, cpp_token *token, const unsigned char *from,
+ cppchar_t type)
{
unsigned char *buffer;
unsigned int len, clen;
@@ -775,9 +642,7 @@ save_comment (pfile, token, from, type)
/* Allocate COUNT tokens for RUN. */
void
-_cpp_init_tokenrun (run, count)
- tokenrun *run;
- unsigned int count;
+_cpp_init_tokenrun (tokenrun *run, unsigned int count)
{
run->base = xnewvec (cpp_token, count);
run->limit = run->base + count;
@@ -786,8 +651,7 @@ _cpp_init_tokenrun (run, count)
/* Returns the next tokenrun, or creates one if there is none. */
static tokenrun *
-next_tokenrun (run)
- tokenrun *run;
+next_tokenrun (tokenrun *run)
{
if (run->next == NULL)
{
@@ -804,8 +668,7 @@ next_tokenrun (run)
same as the last lexed token, so that diagnostics appear in the
right place. */
cpp_token *
-_cpp_temp_token (pfile)
- cpp_reader *pfile;
+_cpp_temp_token (cpp_reader *pfile)
{
cpp_token *old, *result;
@@ -826,8 +689,7 @@ _cpp_temp_token (pfile)
like directive handling, token lookahead, multiple include
optimization and skipping. */
const cpp_token *
-_cpp_lex_token (pfile)
- cpp_reader *pfile;
+_cpp_lex_token (cpp_reader *pfile)
{
cpp_token *result;
@@ -859,7 +721,7 @@ _cpp_lex_token (pfile)
&& _cpp_handle_directive (pfile, result->flags & PREV_WHITE))
continue;
if (pfile->cb.line_change && !pfile->state.skipping)
- (*pfile->cb.line_change)(pfile, result, pfile->state.parsing_args);
+ pfile->cb.line_change (pfile, result, pfile->state.parsing_args);
}
/* We don't skip tokens in directives. */
@@ -868,7 +730,7 @@ _cpp_lex_token (pfile)
/* Outside a directive, invalidate controlling macros. At file
EOF, _cpp_lex_direct takes care of popping the buffer, so we never
- get here and MI optimisation works. */
+ get here and MI optimization works. */
pfile->mi_valid = false;
if (!pfile->state.skipping || result->type == CPP_EOF)
@@ -878,73 +740,66 @@ _cpp_lex_token (pfile)
return result;
}
-/* A NUL terminates the current buffer. For ISO preprocessing this is
- EOF, but for traditional preprocessing it indicates we need a line
- refill. Returns TRUE to continue preprocessing a new buffer, FALSE
- to return a CPP_EOF to the caller. */
-static bool
-continue_after_nul (pfile)
- cpp_reader *pfile;
+/* Returns true if a fresh line has been loaded. */
+bool
+_cpp_get_fresh_line (cpp_reader *pfile)
{
- cpp_buffer *buffer = pfile->buffer;
- bool more = false;
+ int return_at_eof;
- buffer->saved_flags = BOL;
- if (CPP_OPTION (pfile, traditional))
- {
- if (pfile->state.in_directive)
- return false;
+ /* We can't get a new line until we leave the current directive. */
+ if (pfile->state.in_directive)
+ return false;
- _cpp_remove_overlay (pfile);
- more = _cpp_read_logical_line_trad (pfile);
- _cpp_overlay_buffer (pfile, pfile->out.base,
- pfile->out.cur - pfile->out.base);
- pfile->line = pfile->out.first_line;
- }
- else
+ for (;;)
{
- /* Stop parsing arguments with a CPP_EOF. When we finally come
- back here, do the work of popping the buffer. */
- if (!pfile->state.parsing_args)
+ cpp_buffer *buffer = pfile->buffer;
+
+ if (!buffer->need_line)
+ return true;
+
+ if (buffer->next_line < buffer->rlimit)
{
- if (buffer->cur != buffer->line_base)
- {
- /* Non-empty files should end in a newline. Don't warn
- for command line and _Pragma buffers. */
- if (!buffer->from_stage3)
- cpp_error (pfile, DL_PEDWARN, "no newline at end of file");
- handle_newline (pfile);
- }
+ _cpp_clean_line (pfile);
+ return true;
+ }
- /* Similarly, finish an in-progress directive with CPP_EOF
- before popping the buffer. */
- if (!pfile->state.in_directive && buffer->prev)
- {
- more = !buffer->return_at_eof;
- _cpp_pop_buffer (pfile);
- }
+ /* First, get out of parsing arguments state. */
+ if (pfile->state.parsing_args)
+ return false;
+
+ /* End of buffer. Non-empty files should end in a newline. */
+ if (buffer->buf != buffer->rlimit
+ && buffer->next_line > buffer->rlimit
+ && !buffer->from_stage3)
+ {
+ /* Only warn once. */
+ buffer->next_line = buffer->rlimit;
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->line - 1,
+ CPP_BUF_COLUMN (buffer, buffer->cur),
+ "no newline at end of file");
}
- }
- return more;
+ return_at_eof = buffer->return_at_eof;
+ _cpp_pop_buffer (pfile);
+ if (pfile->buffer == NULL || return_at_eof)
+ return false;
+ }
}
-#define IF_NEXT_IS(CHAR, THEN_TYPE, ELSE_TYPE) \
- do { \
- if (get_effective_char (pfile) == CHAR) \
- result->type = THEN_TYPE; \
- else \
- { \
- BACKUP (); \
- result->type = ELSE_TYPE; \
- } \
- } while (0)
+#define IF_NEXT_IS(CHAR, THEN_TYPE, ELSE_TYPE) \
+ do \
+ { \
+ result->type = ELSE_TYPE; \
+ if (*buffer->cur == CHAR) \
+ buffer->cur++, result->type = THEN_TYPE; \
+ } \
+ while (0)
/* Lex a token into pfile->cur_token, which is also incremented, to
get diagnostics pointing to the correct location.
Does not handle issues such as token lookahead, multiple-include
- optimisation, directives, skipping etc. This function is only
+ optimization, directives, skipping etc. This function is only
suitable for use by _cpp_lex_token, and in special cases like
lex_expansion_token which doesn't care for any of these issues.
@@ -952,8 +807,7 @@ continue_after_nul (pfile)
otherwise returns to the start of the token buffer if permissible.
Returns the location of the lexed token. */
cpp_token *
-_cpp_lex_direct (pfile)
- cpp_reader *pfile;
+_cpp_lex_direct (cpp_reader *pfile)
{
cppchar_t c;
cpp_buffer *buffer;
@@ -961,98 +815,72 @@ _cpp_lex_direct (pfile)
cpp_token *result = pfile->cur_token++;
fresh_line:
+ result->flags = 0;
+ buffer = pfile->buffer;
+ if (buffer->need_line)
+ {
+ if (!_cpp_get_fresh_line (pfile))
+ {
+ result->type = CPP_EOF;
+ if (!pfile->state.in_directive)
+ {
+ /* Tell the compiler the line number of the EOF token. */
+ result->line = pfile->line;
+ result->flags = BOL;
+ }
+ return result;
+ }
+ if (!pfile->keep_tokens)
+ {
+ pfile->cur_run = &pfile->base_run;
+ result = pfile->base_run.base;
+ pfile->cur_token = result + 1;
+ }
+ result->flags = BOL;
+ if (pfile->state.parsing_args == 2)
+ result->flags |= PREV_WHITE;
+ }
buffer = pfile->buffer;
- result->flags = buffer->saved_flags;
- buffer->saved_flags = 0;
update_tokens_line:
result->line = pfile->line;
skipped_white:
+ if (buffer->cur >= buffer->notes[buffer->cur_note].pos
+ && !pfile->overlaid_buffer)
+ {
+ _cpp_process_line_notes (pfile, false);
+ result->line = pfile->line;
+ }
c = *buffer->cur++;
result->col = CPP_BUF_COLUMN (buffer, buffer->cur);
- trigraph:
switch (c)
{
case ' ': case '\t': case '\f': case '\v': case '\0':
result->flags |= PREV_WHITE;
- if (skip_whitespace (pfile, c))
- goto skipped_white;
-
- /* End of buffer. */
- buffer->cur--;
- if (continue_after_nul (pfile))
- goto fresh_line;
- result->type = CPP_EOF;
- break;
+ skip_whitespace (pfile, c);
+ goto skipped_white;
- case '\n': case '\r':
- handle_newline (pfile);
- buffer->saved_flags = BOL;
- if (! pfile->state.in_directive)
- {
- if (pfile->state.parsing_args == 2)
- buffer->saved_flags |= PREV_WHITE;
- if (!pfile->keep_tokens)
- {
- pfile->cur_run = &pfile->base_run;
- result = pfile->base_run.base;
- pfile->cur_token = result + 1;
- }
- goto fresh_line;
- }
- result->type = CPP_EOF;
- break;
-
- case '?':
- case '\\':
- /* These could start an escaped newline, or '?' a trigraph. Let
- skip_escaped_newlines do all the work. */
- {
- unsigned int line = pfile->line;
-
- c = skip_escaped_newlines (pfile);
- if (line != pfile->line)
- {
- buffer->cur--;
- /* We had at least one escaped newline of some sort.
- Update the token's line and column. */
- goto update_tokens_line;
- }
- }
-
- /* We are either the original '?' or '\\', or a trigraph. */
- if (c == '?')
- result->type = CPP_QUERY;
- else if (c == '\\')
- goto random_char;
- else
- goto trigraph;
- break;
+ case '\n':
+ pfile->line++;
+ buffer->need_line = true;
+ goto fresh_line;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
result->type = CPP_NUMBER;
- parse_number (pfile, &result->val.str, 0);
+ lex_number (pfile, &result->val.str);
break;
case 'L':
/* 'L' may introduce wide characters or strings. */
- {
- const unsigned char *pos = buffer->cur;
-
- c = get_effective_char (pfile);
- if (c == '\'' || c == '"')
- {
- result->type = (c == '"' ? CPP_WSTRING: CPP_WCHAR);
- parse_string (pfile, result, c);
- break;
- }
- buffer->cur = pos;
- }
+ if (*buffer->cur == '\'' || *buffer->cur == '"')
+ {
+ lex_string (pfile, result, buffer->cur - 1);
+ break;
+ }
/* Fall through. */
- start_ident:
case '_':
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
@@ -1065,31 +893,30 @@ _cpp_lex_direct (pfile)
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
case 'Y': case 'Z':
result->type = CPP_NAME;
- result->val.node = parse_identifier (pfile);
+ result->val.node = lex_identifier (pfile, buffer->cur - 1);
/* Convert named operators to their proper types. */
if (result->val.node->flags & NODE_OPERATOR)
{
result->flags |= NAMED_OP;
- result->type = result->val.node->value.operator;
+ result->type = result->val.node->directive_index;
}
break;
case '\'':
case '"':
- result->type = c == '"' ? CPP_STRING: CPP_CHAR;
- parse_string (pfile, result, c);
+ lex_string (pfile, result, buffer->cur - 1);
break;
case '/':
/* A potential block or line comment. */
comment_start = buffer->cur;
- c = get_effective_char (pfile);
-
+ c = *buffer->cur;
+
if (c == '*')
{
- if (skip_block_comment (pfile))
- cpp_error (pfile, DL_ERROR, "unterminated comment");
+ if (_cpp_skip_block_comment (pfile))
+ cpp_error (pfile, CPP_DL_ERROR, "unterminated comment");
}
else if (c == '/' && (CPP_OPTION (pfile, cplusplus_comments)
|| CPP_IN_SYSTEM_HEADER (pfile)))
@@ -1099,24 +926,24 @@ _cpp_lex_direct (pfile)
if (CPP_OPTION (pfile, lang) == CLK_GNUC89 && CPP_PEDANTIC (pfile)
&& ! buffer->warned_cplusplus_comments)
{
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"C++ style comments are not allowed in ISO C90");
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"(this will be reported only once per input file)");
buffer->warned_cplusplus_comments = 1;
}
if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments))
- cpp_error (pfile, DL_WARNING, "multi-line comment");
+ cpp_error (pfile, CPP_DL_WARNING, "multi-line comment");
}
else if (c == '=')
{
+ buffer->cur++;
result->type = CPP_DIV_EQ;
break;
}
else
{
- BACKUP ();
result->type = CPP_DIV;
break;
}
@@ -1134,183 +961,141 @@ _cpp_lex_direct (pfile)
case '<':
if (pfile->state.angled_headers)
{
- result->type = CPP_HEADER_NAME;
- parse_string (pfile, result, '>');
+ lex_string (pfile, result, buffer->cur - 1);
break;
}
- c = get_effective_char (pfile);
- if (c == '=')
- result->type = CPP_LESS_EQ;
- else if (c == '<')
- IF_NEXT_IS ('=', CPP_LSHIFT_EQ, CPP_LSHIFT);
- else if (c == '?' && CPP_OPTION (pfile, cplusplus))
- IF_NEXT_IS ('=', CPP_MIN_EQ, CPP_MIN);
- else if (c == ':' && CPP_OPTION (pfile, digraphs))
+ result->type = CPP_LESS;
+ if (*buffer->cur == '=')
+ buffer->cur++, result->type = CPP_LESS_EQ;
+ else if (*buffer->cur == '<')
{
- result->type = CPP_OPEN_SQUARE;
- result->flags |= DIGRAPH;
+ buffer->cur++;
+ IF_NEXT_IS ('=', CPP_LSHIFT_EQ, CPP_LSHIFT);
}
- else if (c == '%' && CPP_OPTION (pfile, digraphs))
+ else if (*buffer->cur == '?' && CPP_OPTION (pfile, cplusplus))
{
- result->type = CPP_OPEN_BRACE;
- result->flags |= DIGRAPH;
+ buffer->cur++;
+ IF_NEXT_IS ('=', CPP_MIN_EQ, CPP_MIN);
}
- else
+ else if (CPP_OPTION (pfile, digraphs))
{
- BACKUP ();
- result->type = CPP_LESS;
+ if (*buffer->cur == ':')
+ {
+ buffer->cur++;
+ result->flags |= DIGRAPH;
+ result->type = CPP_OPEN_SQUARE;
+ }
+ else if (*buffer->cur == '%')
+ {
+ buffer->cur++;
+ result->flags |= DIGRAPH;
+ result->type = CPP_OPEN_BRACE;
+ }
}
break;
case '>':
- c = get_effective_char (pfile);
- if (c == '=')
- result->type = CPP_GREATER_EQ;
- else if (c == '>')
- IF_NEXT_IS ('=', CPP_RSHIFT_EQ, CPP_RSHIFT);
- else if (c == '?' && CPP_OPTION (pfile, cplusplus))
- IF_NEXT_IS ('=', CPP_MAX_EQ, CPP_MAX);
- else
+ result->type = CPP_GREATER;
+ if (*buffer->cur == '=')
+ buffer->cur++, result->type = CPP_GREATER_EQ;
+ else if (*buffer->cur == '>')
{
- BACKUP ();
- result->type = CPP_GREATER;
+ buffer->cur++;
+ IF_NEXT_IS ('=', CPP_RSHIFT_EQ, CPP_RSHIFT);
+ }
+ else if (*buffer->cur == '?' && CPP_OPTION (pfile, cplusplus))
+ {
+ buffer->cur++;
+ IF_NEXT_IS ('=', CPP_MAX_EQ, CPP_MAX);
}
break;
case '%':
- c = get_effective_char (pfile);
- if (c == '=')
- result->type = CPP_MOD_EQ;
- else if (CPP_OPTION (pfile, digraphs) && c == ':')
+ result->type = CPP_MOD;
+ if (*buffer->cur == '=')
+ buffer->cur++, result->type = CPP_MOD_EQ;
+ else if (CPP_OPTION (pfile, digraphs))
{
- result->flags |= DIGRAPH;
- result->type = CPP_HASH;
- if (get_effective_char (pfile) == '%')
+ if (*buffer->cur == ':')
{
- const unsigned char *pos = buffer->cur;
-
- if (get_effective_char (pfile) == ':')
- result->type = CPP_PASTE;
- else
- buffer->cur = pos - 1;
+ buffer->cur++;
+ result->flags |= DIGRAPH;
+ result->type = CPP_HASH;
+ if (*buffer->cur == '%' && buffer->cur[1] == ':')
+ buffer->cur += 2, result->type = CPP_PASTE;
+ }
+ else if (*buffer->cur == '>')
+ {
+ buffer->cur++;
+ result->flags |= DIGRAPH;
+ result->type = CPP_CLOSE_BRACE;
}
- else
- BACKUP ();
- }
- else if (CPP_OPTION (pfile, digraphs) && c == '>')
- {
- result->flags |= DIGRAPH;
- result->type = CPP_CLOSE_BRACE;
- }
- else
- {
- BACKUP ();
- result->type = CPP_MOD;
}
break;
case '.':
result->type = CPP_DOT;
- c = get_effective_char (pfile);
- if (c == '.')
- {
- const unsigned char *pos = buffer->cur;
-
- if (get_effective_char (pfile) == '.')
- result->type = CPP_ELLIPSIS;
- else
- buffer->cur = pos - 1;
- }
- /* All known character sets have 0...9 contiguous. */
- else if (ISDIGIT (c))
+ if (ISDIGIT (*buffer->cur))
{
result->type = CPP_NUMBER;
- parse_number (pfile, &result->val.str, 1);
+ lex_number (pfile, &result->val.str);
}
- else if (c == '*' && CPP_OPTION (pfile, cplusplus))
- result->type = CPP_DOT_STAR;
- else
- BACKUP ();
+ else if (*buffer->cur == '.' && buffer->cur[1] == '.')
+ buffer->cur += 2, result->type = CPP_ELLIPSIS;
+ else if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus))
+ buffer->cur++, result->type = CPP_DOT_STAR;
break;
case '+':
- c = get_effective_char (pfile);
- if (c == '+')
- result->type = CPP_PLUS_PLUS;
- else if (c == '=')
- result->type = CPP_PLUS_EQ;
- else
- {
- BACKUP ();
- result->type = CPP_PLUS;
- }
+ result->type = CPP_PLUS;
+ if (*buffer->cur == '+')
+ buffer->cur++, result->type = CPP_PLUS_PLUS;
+ else if (*buffer->cur == '=')
+ buffer->cur++, result->type = CPP_PLUS_EQ;
break;
case '-':
- c = get_effective_char (pfile);
- if (c == '>')
+ result->type = CPP_MINUS;
+ if (*buffer->cur == '>')
{
+ buffer->cur++;
result->type = CPP_DEREF;
- if (CPP_OPTION (pfile, cplusplus))
- {
- if (get_effective_char (pfile) == '*')
- result->type = CPP_DEREF_STAR;
- else
- BACKUP ();
- }
- }
- else if (c == '-')
- result->type = CPP_MINUS_MINUS;
- else if (c == '=')
- result->type = CPP_MINUS_EQ;
- else
- {
- BACKUP ();
- result->type = CPP_MINUS;
+ if (*buffer->cur == '*' && CPP_OPTION (pfile, cplusplus))
+ buffer->cur++, result->type = CPP_DEREF_STAR;
}
+ else if (*buffer->cur == '-')
+ buffer->cur++, result->type = CPP_MINUS_MINUS;
+ else if (*buffer->cur == '=')
+ buffer->cur++, result->type = CPP_MINUS_EQ;
break;
case '&':
- c = get_effective_char (pfile);
- if (c == '&')
- result->type = CPP_AND_AND;
- else if (c == '=')
- result->type = CPP_AND_EQ;
- else
- {
- BACKUP ();
- result->type = CPP_AND;
- }
+ result->type = CPP_AND;
+ if (*buffer->cur == '&')
+ buffer->cur++, result->type = CPP_AND_AND;
+ else if (*buffer->cur == '=')
+ buffer->cur++, result->type = CPP_AND_EQ;
break;
case '|':
- c = get_effective_char (pfile);
- if (c == '|')
- result->type = CPP_OR_OR;
- else if (c == '=')
- result->type = CPP_OR_EQ;
- else
- {
- BACKUP ();
- result->type = CPP_OR;
- }
+ result->type = CPP_OR;
+ if (*buffer->cur == '|')
+ buffer->cur++, result->type = CPP_OR_OR;
+ else if (*buffer->cur == '=')
+ buffer->cur++, result->type = CPP_OR_EQ;
break;
case ':':
- c = get_effective_char (pfile);
- if (c == ':' && CPP_OPTION (pfile, cplusplus))
- result->type = CPP_SCOPE;
- else if (c == '>' && CPP_OPTION (pfile, digraphs))
+ result->type = CPP_COLON;
+ if (*buffer->cur == ':' && CPP_OPTION (pfile, cplusplus))
+ buffer->cur++, result->type = CPP_SCOPE;
+ else if (*buffer->cur == '>' && CPP_OPTION (pfile, digraphs))
{
+ buffer->cur++;
result->flags |= DIGRAPH;
result->type = CPP_CLOSE_SQUARE;
}
- else
- {
- BACKUP ();
- result->type = CPP_COLON;
- }
break;
case '*': IF_NEXT_IS ('=', CPP_MULT_EQ, CPP_MULT); break;
@@ -1319,6 +1104,7 @@ _cpp_lex_direct (pfile)
case '^': IF_NEXT_IS ('=', CPP_XOR_EQ, CPP_XOR); break;
case '#': IF_NEXT_IS ('#', CPP_PASTE, CPP_HASH); break;
+ case '?': result->type = CPP_QUERY; break;
case '~': result->type = CPP_COMPL; break;
case ',': result->type = CPP_COMMA; break;
case '(': result->type = CPP_OPEN_PAREN; break;
@@ -1333,48 +1119,51 @@ _cpp_lex_direct (pfile)
case '@': result->type = CPP_ATSIGN; break;
case '$':
- if (CPP_OPTION (pfile, dollars_in_ident))
- goto start_ident;
- /* Fall through... */
+ case '\\':
+ {
+ const uchar *base = --buffer->cur;
+
+ if (forms_identifier_p (pfile, true))
+ {
+ result->type = CPP_NAME;
+ result->val.node = lex_identifier (pfile, base);
+ break;
+ }
+ buffer->cur++;
+ }
- random_char:
default:
- result->type = CPP_OTHER;
- result->val.c = c;
+ create_literal (pfile, result, buffer->cur - 1, 1, CPP_OTHER);
break;
}
return result;
}
-/* An upper bound on the number of bytes needed to spell TOKEN,
- including preceding whitespace. */
+/* An upper bound on the number of bytes needed to spell TOKEN.
+ Does not include preceding whitespace. */
unsigned int
-cpp_token_len (token)
- const cpp_token *token;
+cpp_token_len (const cpp_token *token)
{
unsigned int len;
switch (TOKEN_SPELL (token))
{
- default: len = 0; break;
- case SPELL_NUMBER:
- case SPELL_STRING: len = token->val.str.len; break;
+ default: len = 4; break;
+ case SPELL_LITERAL: len = token->val.str.len; break;
case SPELL_IDENT: len = NODE_LEN (token->val.node); break;
}
- /* 1 for whitespace, 4 for comment delimiters. */
- return len + 5;
+
+ return len;
}
/* Write the spelling of a token TOKEN to BUFFER. The buffer must
already contain the enough space to hold the token's spelling.
- Returns a pointer to the character after the last character
- written. */
+ Returns a pointer to the character after the last character written.
+ FIXME: Would be nice if we didn't need the PFILE argument. */
unsigned char *
-cpp_spell_token (pfile, token, buffer)
- cpp_reader *pfile; /* Would be nice to be rid of this... */
- const cpp_token *token;
- unsigned char *buffer;
+cpp_spell_token (cpp_reader *pfile, const cpp_token *token,
+ unsigned char *buffer)
{
switch (TOKEN_SPELL (token))
{
@@ -1396,46 +1185,20 @@ cpp_spell_token (pfile, token, buffer)
}
break;
- case SPELL_CHAR:
- *buffer++ = token->val.c;
- break;
-
spell_ident:
case SPELL_IDENT:
memcpy (buffer, NODE_NAME (token->val.node), NODE_LEN (token->val.node));
buffer += NODE_LEN (token->val.node);
break;
- case SPELL_NUMBER:
+ case SPELL_LITERAL:
memcpy (buffer, token->val.str.text, token->val.str.len);
buffer += token->val.str.len;
break;
- case SPELL_STRING:
- {
- int left, right, tag;
- switch (token->type)
- {
- case CPP_STRING: left = '"'; right = '"'; tag = '\0'; break;
- case CPP_WSTRING: left = '"'; right = '"'; tag = 'L'; break;
- case CPP_CHAR: left = '\''; right = '\''; tag = '\0'; break;
- case CPP_WCHAR: left = '\''; right = '\''; tag = 'L'; break;
- case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break;
- default:
- cpp_error (pfile, DL_ICE, "unknown string token %s\n",
- TOKEN_NAME (token));
- return buffer;
- }
- if (tag) *buffer++ = tag;
- *buffer++ = left;
- memcpy (buffer, token->val.str.text, token->val.str.len);
- buffer += token->val.str.len;
- *buffer++ = right;
- }
- break;
-
case SPELL_NONE:
- cpp_error (pfile, DL_ICE, "unspellable token %s", TOKEN_NAME (token));
+ cpp_error (pfile, CPP_DL_ICE,
+ "unspellable token %s", TOKEN_NAME (token));
break;
}
@@ -1445,11 +1208,9 @@ cpp_spell_token (pfile, token, buffer)
/* Returns TOKEN spelt as a null-terminated string. The string is
freed when the reader is destroyed. Useful for diagnostics. */
unsigned char *
-cpp_token_as_text (pfile, token)
- cpp_reader *pfile;
- const cpp_token *token;
-{
- unsigned int len = cpp_token_len (token);
+cpp_token_as_text (cpp_reader *pfile, const cpp_token *token)
+{
+ unsigned int len = cpp_token_len (token) + 1;
unsigned char *start = _cpp_unaligned_alloc (pfile, len), *end;
end = cpp_spell_token (pfile, token, start);
@@ -1461,8 +1222,7 @@ cpp_token_as_text (pfile, token)
/* Used by C front ends, which really should move to using
cpp_token_as_text. */
const char *
-cpp_type2name (type)
- enum cpp_ttype type;
+cpp_type2name (enum cpp_ttype type)
{
return (const char *) token_spellings[type].name;
}
@@ -1471,9 +1231,7 @@ cpp_type2name (type)
Separated from cpp_spell_token for efficiency - to avoid stdio
double-buffering. */
void
-cpp_output_token (token, fp)
- const cpp_token *token;
- FILE *fp;
+cpp_output_token (const cpp_token *token, FILE *fp)
{
switch (TOKEN_SPELL (token))
{
@@ -1497,40 +1255,15 @@ cpp_output_token (token, fp)
}
break;
- case SPELL_CHAR:
- putc (token->val.c, fp);
- break;
-
spell_ident:
case SPELL_IDENT:
fwrite (NODE_NAME (token->val.node), 1, NODE_LEN (token->val.node), fp);
break;
- case SPELL_NUMBER:
+ case SPELL_LITERAL:
fwrite (token->val.str.text, 1, token->val.str.len, fp);
break;
- case SPELL_STRING:
- {
- int left, right, tag;
- switch (token->type)
- {
- case CPP_STRING: left = '"'; right = '"'; tag = '\0'; break;
- case CPP_WSTRING: left = '"'; right = '"'; tag = 'L'; break;
- case CPP_CHAR: left = '\''; right = '\''; tag = '\0'; break;
- case CPP_WCHAR: left = '\''; right = '\''; tag = 'L'; break;
- case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break;
- default:
- fprintf (stderr, "impossible STRING token %s\n", TOKEN_NAME (token));
- return;
- }
- if (tag) putc (tag, fp);
- putc (left, fp);
- fwrite (token->val.str.text, 1, token->val.str.len, fp);
- putc (right, fp);
- }
- break;
-
case SPELL_NONE:
/* An error, most probably. */
break;
@@ -1539,8 +1272,7 @@ cpp_output_token (token, fp)
/* Compare two tokens. */
int
-_cpp_equiv_tokens (a, b)
- const cpp_token *a, *b;
+_cpp_equiv_tokens (const cpp_token *a, const cpp_token *b)
{
if (a->type == b->type && a->flags == b->flags)
switch (TOKEN_SPELL (a))
@@ -1548,14 +1280,11 @@ _cpp_equiv_tokens (a, b)
default: /* Keep compiler happy. */
case SPELL_OPERATOR:
return 1;
- case SPELL_CHAR:
- return a->val.c == b->val.c; /* Character. */
case SPELL_NONE:
return (a->type != CPP_MACRO_ARG || a->val.arg_no == b->val.arg_no);
case SPELL_IDENT:
return a->val.node == b->val.node;
- case SPELL_NUMBER:
- case SPELL_STRING:
+ case SPELL_LITERAL:
return (a->val.str.len == b->val.str.len
&& !memcmp (a->val.str.text, b->val.str.text,
a->val.str.len));
@@ -1569,9 +1298,8 @@ _cpp_equiv_tokens (a, b)
conservative, and occasionally advises a space where one is not
needed, e.g. "." and ".2". */
int
-cpp_avoid_paste (pfile, token1, token2)
- cpp_reader *pfile;
- const cpp_token *token1, *token2;
+cpp_avoid_paste (cpp_reader *pfile, const cpp_token *token1,
+ const cpp_token *token2)
{
enum cpp_ttype a = token1->type, b = token2->type;
cppchar_t c;
@@ -1611,9 +1339,12 @@ cpp_avoid_paste (pfile, token1, token2)
|| b == CPP_CHAR || b == CPP_STRING); /* L */
case CPP_NUMBER: return (b == CPP_NUMBER || b == CPP_NAME
|| c == '.' || c == '+' || c == '-');
- case CPP_OTHER: return (CPP_OPTION (pfile, objc)
- && token1->val.c == '@'
- && (b == CPP_NAME || b == CPP_STRING));
+ /* UCNs */
+ case CPP_OTHER: return ((token1->val.str.text[0] == '\\'
+ && b == CPP_NAME)
+ || (CPP_OPTION (pfile, objc)
+ && token1->val.str.text[0] == '@'
+ && (b == CPP_NAME || b == CPP_STRING)));
default: break;
}
@@ -1624,9 +1355,7 @@ cpp_avoid_paste (pfile, token1, token2)
character, to FP. Leading whitespace is removed. If there are
macros, special token padding is not performed. */
void
-cpp_output_line (pfile, fp)
- cpp_reader *pfile;
- FILE *fp;
+cpp_output_line (cpp_reader *pfile, FILE *fp)
{
const cpp_token *token;
@@ -1642,369 +1371,6 @@ cpp_output_line (pfile, fp)
putc ('\n', fp);
}
-/* Returns the value of a hexadecimal digit. */
-static unsigned int
-hex_digit_value (c)
- unsigned int c;
-{
- if (hex_p (c))
- return hex_value (c);
- else
- abort ();
-}
-
-/* Parse a '\uNNNN' or '\UNNNNNNNN' sequence. Returns 1 to indicate
- failure if cpplib is not parsing C++ or C99. Such failure is
- silent, and no variables are updated. Otherwise returns 0, and
- warns if -Wtraditional.
-
- [lex.charset]: The character designated by the universal character
- name \UNNNNNNNN is that character whose character short name in
- ISO/IEC 10646 is NNNNNNNN; the character designated by the
- universal character name \uNNNN is that character whose character
- short name in ISO/IEC 10646 is 0000NNNN. If the hexadecimal value
- for a universal character name is less than 0x20 or in the range
- 0x7F-0x9F (inclusive), or if the universal character name
- designates a character in the basic source character set, then the
- program is ill-formed.
-
- We assume that wchar_t is Unicode, so we don't need to do any
- mapping. Is this ever wrong?
-
- PC points to the 'u' or 'U', PSTR is points to the byte after PC,
- LIMIT is the end of the string or charconst. PSTR is updated to
- point after the UCS on return, and the UCS is written into PC. */
-
-static int
-maybe_read_ucs (pfile, pstr, limit, pc)
- cpp_reader *pfile;
- const unsigned char **pstr;
- const unsigned char *limit;
- cppchar_t *pc;
-{
- const unsigned char *p = *pstr;
- unsigned int code = 0;
- unsigned int c = *pc, length;
-
- /* Only attempt to interpret a UCS for C++ and C99. */
- if (! (CPP_OPTION (pfile, cplusplus) || CPP_OPTION (pfile, c99)))
- return 1;
-
- if (CPP_WTRADITIONAL (pfile))
- cpp_error (pfile, DL_WARNING,
- "the meaning of '\\%c' is different in traditional C", c);
-
- length = (c == 'u' ? 4: 8);
-
- if ((size_t) (limit - p) < length)
- {
- cpp_error (pfile, DL_ERROR, "incomplete universal-character-name");
- /* Skip to the end to avoid more diagnostics. */
- p = limit;
- }
- else
- {
- for (; length; length--, p++)
- {
- c = *p;
- if (ISXDIGIT (c))
- code = (code << 4) + hex_digit_value (c);
- else
- {
- cpp_error (pfile, DL_ERROR,
- "non-hex digit '%c' in universal-character-name", c);
- /* We shouldn't skip in case there are multibyte chars. */
- break;
- }
- }
- }
-
-#ifdef TARGET_EBCDIC
- cpp_error (pfile, DL_ERROR, "universal-character-name on EBCDIC target");
- code = 0x3f; /* EBCDIC invalid character */
-#else
- /* True extended characters are OK. */
- if (code >= 0xa0
- && !(code & 0x80000000)
- && !(code >= 0xD800 && code <= 0xDFFF))
- ;
- /* The standard permits $, @ and ` to be specified as UCNs. We use
- hex escapes so that this also works with EBCDIC hosts. */
- else if (code == 0x24 || code == 0x40 || code == 0x60)
- ;
- /* Don't give another error if one occurred above. */
- else if (length == 0)
- cpp_error (pfile, DL_ERROR, "universal-character-name out of range");
-#endif
-
- *pstr = p;
- *pc = code;
- return 0;
-}
-
-/* Returns the value of an escape sequence, truncated to the correct
- target precision. PSTR points to the input pointer, which is just
- after the backslash. LIMIT is how much text we have. WIDE is true
- if the escape sequence is part of a wide character constant or
- string literal. Handles all relevant diagnostics. */
-cppchar_t
-cpp_parse_escape (pfile, pstr, limit, wide)
- cpp_reader *pfile;
- const unsigned char **pstr;
- const unsigned char *limit;
- int wide;
-{
- int unknown = 0;
- const unsigned char *str = *pstr;
- cppchar_t c, mask;
- unsigned int width;
-
- if (wide)
- width = CPP_OPTION (pfile, wchar_precision);
- else
- width = CPP_OPTION (pfile, char_precision);
- if (width < BITS_PER_CPPCHAR_T)
- mask = ((cppchar_t) 1 << width) - 1;
- else
- mask = ~0;
-
- c = *str++;
- switch (c)
- {
- case '\\': case '\'': case '"': case '?': break;
- case 'b': c = TARGET_BS; break;
- case 'f': c = TARGET_FF; break;
- case 'n': c = TARGET_NEWLINE; break;
- case 'r': c = TARGET_CR; break;
- case 't': c = TARGET_TAB; break;
- case 'v': c = TARGET_VT; break;
-
- case '(': case '{': case '[': case '%':
- /* '\(', etc, are used at beginning of line to avoid confusing Emacs.
- '\%' is used to prevent SCCS from getting confused. */
- unknown = CPP_PEDANTIC (pfile);
- break;
-
- case 'a':
- if (CPP_WTRADITIONAL (pfile))
- cpp_error (pfile, DL_WARNING,
- "the meaning of '\\a' is different in traditional C");
- c = TARGET_BELL;
- break;
-
- case 'e': case 'E':
- if (CPP_PEDANTIC (pfile))
- cpp_error (pfile, DL_PEDWARN,
- "non-ISO-standard escape sequence, '\\%c'", (int) c);
- c = TARGET_ESC;
- break;
-
- case 'u': case 'U':
- unknown = maybe_read_ucs (pfile, &str, limit, &c);
- break;
-
- case 'x':
- if (CPP_WTRADITIONAL (pfile))
- cpp_error (pfile, DL_WARNING,
- "the meaning of '\\x' is different in traditional C");
-
- {
- cppchar_t i = 0, overflow = 0;
- int digits_found = 0;
-
- while (str < limit)
- {
- c = *str;
- if (! ISXDIGIT (c))
- break;
- str++;
- overflow |= i ^ (i << 4 >> 4);
- i = (i << 4) + hex_digit_value (c);
- digits_found = 1;
- }
-
- if (!digits_found)
- cpp_error (pfile, DL_ERROR,
- "\\x used with no following hex digits");
-
- if (overflow | (i != (i & mask)))
- {
- cpp_error (pfile, DL_PEDWARN,
- "hex escape sequence out of range");
- i &= mask;
- }
- c = i;
- }
- break;
-
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7':
- {
- size_t count = 0;
- cppchar_t i = c - '0';
-
- while (str < limit && ++count < 3)
- {
- c = *str;
- if (c < '0' || c > '7')
- break;
- str++;
- i = (i << 3) + c - '0';
- }
-
- if (i != (i & mask))
- {
- cpp_error (pfile, DL_PEDWARN,
- "octal escape sequence out of range");
- i &= mask;
- }
- c = i;
- }
- break;
-
- default:
- unknown = 1;
- break;
- }
-
- if (unknown)
- {
- if (ISGRAPH (c))
- cpp_error (pfile, DL_PEDWARN,
- "unknown escape sequence '\\%c'", (int) c);
- else
- cpp_error (pfile, DL_PEDWARN,
- "unknown escape sequence: '\\%03o'", (int) c);
- }
-
- if (c > mask)
- {
- cpp_error (pfile, DL_PEDWARN, "escape sequence out of range for its type");
- c &= mask;
- }
-
- *pstr = str;
- return c;
-}
-
-/* Interpret a (possibly wide) character constant in TOKEN.
- WARN_MULTI warns about multi-character charconsts. PCHARS_SEEN
- points to a variable that is filled in with the number of
- characters seen, and UNSIGNEDP to a variable that indicates whether
- the result has signed type. */
-cppchar_t
-cpp_interpret_charconst (pfile, token, pchars_seen, unsignedp)
- cpp_reader *pfile;
- const cpp_token *token;
- unsigned int *pchars_seen;
- int *unsignedp;
-{
- const unsigned char *str = token->val.str.text;
- const unsigned char *limit = str + token->val.str.len;
- unsigned int chars_seen = 0;
- size_t width, max_chars;
- cppchar_t c, mask, result = 0;
- bool unsigned_p;
-
-#ifdef MULTIBYTE_CHARS
- (void) local_mbtowc (NULL, NULL, 0);
-#endif
-
- /* Width in bits. */
- if (token->type == CPP_CHAR)
- {
- width = CPP_OPTION (pfile, char_precision);
- max_chars = CPP_OPTION (pfile, int_precision) / width;
- unsigned_p = CPP_OPTION (pfile, unsigned_char);
- }
- else
- {
- width = CPP_OPTION (pfile, wchar_precision);
- max_chars = 1;
- unsigned_p = CPP_OPTION (pfile, unsigned_wchar);
- }
-
- if (width < BITS_PER_CPPCHAR_T)
- mask = ((cppchar_t) 1 << width) - 1;
- else
- mask = ~0;
-
- while (str < limit)
- {
-#ifdef MULTIBYTE_CHARS
- wchar_t wc;
- int char_len;
-
- char_len = local_mbtowc (&wc, str, limit - str);
- if (char_len == -1)
- {
- cpp_error (pfile, DL_WARNING,
- "ignoring invalid multibyte character");
- c = *str++;
- }
- else
- {
- str += char_len;
- c = wc;
- }
-#else
- c = *str++;
-#endif
-
- if (c == '\\')
- c = cpp_parse_escape (pfile, &str, limit, token->type == CPP_WCHAR);
-
-#ifdef MAP_CHARACTER
- if (ISPRINT (c))
- c = MAP_CHARACTER (c);
-#endif
-
- chars_seen++;
-
- /* Truncate the character, scale the result and merge the two. */
- c &= mask;
- if (width < BITS_PER_CPPCHAR_T)
- result = (result << width) | c;
- else
- result = c;
- }
-
- if (chars_seen == 0)
- cpp_error (pfile, DL_ERROR, "empty character constant");
- else if (chars_seen > 1)
- {
- /* Multichar charconsts are of type int and therefore signed. */
- unsigned_p = 0;
-
- if (chars_seen > max_chars)
- {
- chars_seen = max_chars;
- cpp_error (pfile, DL_WARNING,
- "character constant too long for its type");
- }
- else if (CPP_OPTION (pfile, warn_multichar))
- cpp_error (pfile, DL_WARNING, "multi-character character constant");
- }
-
- /* Sign-extend or truncate the constant to cppchar_t. The value is
- in WIDTH bits, but for multi-char charconsts it's value is the
- full target type's width. */
- if (chars_seen > 1)
- width *= max_chars;
- if (width < BITS_PER_CPPCHAR_T)
- {
- mask = ((cppchar_t) 1 << width) - 1;
- if (unsigned_p || !(result & (1 << (width - 1))))
- result &= mask;
- else
- result |= ~mask;
- }
-
- *pchars_seen = chars_seen;
- *unsignedp = unsigned_p;
- return result;
-}
-
/* Memory buffers. Changing these three constants can have a dramatic
effect on performance. The values here are reasonable defaults,
but might be tuned. If you adjust them, be sure to test across a
@@ -2023,8 +1389,7 @@ cpp_interpret_charconst (pfile, token, pchars_seen, unsignedp)
/* Create a new allocation buffer. Place the control block at the end
of the buffer, so that buffer overflows will cause immediate chaos. */
static _cpp_buff *
-new_buff (len)
- size_t len;
+new_buff (size_t len)
{
_cpp_buff *result;
unsigned char *base;
@@ -2044,9 +1409,7 @@ new_buff (len)
/* Place a chain of unwanted allocation buffers on the free list. */
void
-_cpp_release_buff (pfile, buff)
- cpp_reader *pfile;
- _cpp_buff *buff;
+_cpp_release_buff (cpp_reader *pfile, _cpp_buff *buff)
{
_cpp_buff *end = buff;
@@ -2058,9 +1421,7 @@ _cpp_release_buff (pfile, buff)
/* Return a free buffer of size at least MIN_SIZE. */
_cpp_buff *
-_cpp_get_buff (pfile, min_size)
- cpp_reader *pfile;
- size_t min_size;
+_cpp_get_buff (cpp_reader *pfile, size_t min_size)
{
_cpp_buff *result, **p;
@@ -2089,10 +1450,7 @@ _cpp_get_buff (pfile, min_size)
the excess bytes to the new buffer. Chains the new buffer after
BUFF, and returns the new buffer. */
_cpp_buff *
-_cpp_append_extend_buff (pfile, buff, min_extra)
- cpp_reader *pfile;
- _cpp_buff *buff;
- size_t min_extra;
+_cpp_append_extend_buff (cpp_reader *pfile, _cpp_buff *buff, size_t min_extra)
{
size_t size = EXTENDED_BUFF_SIZE (buff, min_extra);
_cpp_buff *new_buff = _cpp_get_buff (pfile, size);
@@ -2108,10 +1466,7 @@ _cpp_append_extend_buff (pfile, buff, min_extra)
Chains the new buffer before the buffer pointed to by BUFF, and
updates the pointer to point to the new buffer. */
void
-_cpp_extend_buff (pfile, pbuff, min_extra)
- cpp_reader *pfile;
- _cpp_buff **pbuff;
- size_t min_extra;
+_cpp_extend_buff (cpp_reader *pfile, _cpp_buff **pbuff, size_t min_extra)
{
_cpp_buff *new_buff, *old_buff = *pbuff;
size_t size = EXTENDED_BUFF_SIZE (old_buff, min_extra);
@@ -2124,8 +1479,7 @@ _cpp_extend_buff (pfile, pbuff, min_extra)
/* Free a chain of buffers starting at BUFF. */
void
-_cpp_free_buff (buff)
- _cpp_buff *buff;
+_cpp_free_buff (_cpp_buff *buff)
{
_cpp_buff *next;
@@ -2138,9 +1492,7 @@ _cpp_free_buff (buff)
/* Allocate permanent, unaligned storage of length LEN. */
unsigned char *
-_cpp_unaligned_alloc (pfile, len)
- cpp_reader *pfile;
- size_t len;
+_cpp_unaligned_alloc (cpp_reader *pfile, size_t len)
{
_cpp_buff *buff = pfile->u_buff;
unsigned char *result = buff->cur;
@@ -2168,9 +1520,7 @@ _cpp_unaligned_alloc (pfile, len)
All existing other uses clearly fit this restriction: storing
registered pragmas during initialization. */
unsigned char *
-_cpp_aligned_alloc (pfile, len)
- cpp_reader *pfile;
- size_t len;
+_cpp_aligned_alloc (cpp_reader *pfile, size_t len)
{
_cpp_buff *buff = pfile->a_buff;
unsigned char *result = buff->cur;
diff --git a/contrib/gcc/cpplib.c b/contrib/gcc/cpplib.c
index e18564e8739c..60a86e3e3988 100644
--- a/contrib/gcc/cpplib.c
+++ b/contrib/gcc/cpplib.c
@@ -21,7 +21,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
-
#include "cpplib.h"
#include "cpphash.h"
#include "obstack.h"
@@ -43,11 +42,11 @@ struct if_stack
const cpp_hashnode *mi_cmacro;/* macro name for #ifndef around entire file */
bool skip_elses; /* Can future #else / #elif be skipped? */
bool was_skipping; /* If were skipping on entry. */
- int type; /* Most recent conditional, for diagnostics. */
+ int type; /* Most recent conditional for diagnostics. */
};
/* Contains a registered pragma or pragma namespace. */
-typedef void (*pragma_cb) PARAMS ((cpp_reader *));
+typedef void (*pragma_cb) (cpp_reader *);
struct pragma_entry
{
struct pragma_entry *next;
@@ -80,7 +79,7 @@ struct pragma_entry
#define EXPAND (1 << 4)
/* Defines one #-directive, including how to handle it. */
-typedef void (*directive_handler) PARAMS ((cpp_reader *));
+typedef void (*directive_handler) (cpp_reader *);
typedef struct directive directive;
struct directive
{
@@ -93,46 +92,44 @@ struct directive
/* Forward declarations. */
-static void skip_rest_of_line PARAMS ((cpp_reader *));
-static void check_eol PARAMS ((cpp_reader *));
-static void start_directive PARAMS ((cpp_reader *));
-static void prepare_directive_trad PARAMS ((cpp_reader *));
-static void end_directive PARAMS ((cpp_reader *, int));
-static void directive_diagnostics
- PARAMS ((cpp_reader *, const directive *, int));
-static void run_directive PARAMS ((cpp_reader *, int,
- const char *, size_t));
-static const cpp_token *glue_header_name PARAMS ((cpp_reader *));
-static const cpp_token *parse_include PARAMS ((cpp_reader *));
-static void push_conditional PARAMS ((cpp_reader *, int, int,
- const cpp_hashnode *));
-static unsigned int read_flag PARAMS ((cpp_reader *, unsigned int));
-static uchar *dequote_string PARAMS ((cpp_reader *, const uchar *,
- unsigned int));
-static int strtoul_for_line PARAMS ((const uchar *, unsigned int,
- unsigned long *));
-static void do_diagnostic PARAMS ((cpp_reader *, int, int));
-static cpp_hashnode *lex_macro_node PARAMS ((cpp_reader *));
-static void do_include_common PARAMS ((cpp_reader *, enum include_type));
-static struct pragma_entry *lookup_pragma_entry
- PARAMS ((struct pragma_entry *, const cpp_hashnode *pragma));
-static struct pragma_entry *insert_pragma_entry
- PARAMS ((cpp_reader *, struct pragma_entry **, const cpp_hashnode *,
- pragma_cb));
-static void do_pragma_once PARAMS ((cpp_reader *));
-static void do_pragma_poison PARAMS ((cpp_reader *));
-static void do_pragma_system_header PARAMS ((cpp_reader *));
-static void do_pragma_dependency PARAMS ((cpp_reader *));
-static void do_linemarker PARAMS ((cpp_reader *));
-static const cpp_token *get_token_no_padding PARAMS ((cpp_reader *));
-static const cpp_token *get__Pragma_string PARAMS ((cpp_reader *));
-static void destringize_and_run PARAMS ((cpp_reader *, const cpp_string *));
-static int parse_answer PARAMS ((cpp_reader *, struct answer **, int));
-static cpp_hashnode *parse_assertion PARAMS ((cpp_reader *, struct answer **,
- int));
-static struct answer ** find_answer PARAMS ((cpp_hashnode *,
- const struct answer *));
-static void handle_assertion PARAMS ((cpp_reader *, const char *, int));
+static void skip_rest_of_line (cpp_reader *);
+static void check_eol (cpp_reader *);
+static void start_directive (cpp_reader *);
+static void prepare_directive_trad (cpp_reader *);
+static void end_directive (cpp_reader *, int);
+static void directive_diagnostics (cpp_reader *, const directive *, int);
+static void run_directive (cpp_reader *, int, const char *, size_t);
+static char *glue_header_name (cpp_reader *);
+static const char *parse_include (cpp_reader *, int *);
+static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *);
+static unsigned int read_flag (cpp_reader *, unsigned int);
+static int strtoul_for_line (const uchar *, unsigned int, unsigned long *);
+static void do_diagnostic (cpp_reader *, int, int);
+static cpp_hashnode *lex_macro_node (cpp_reader *);
+static int undefine_macros (cpp_reader *, cpp_hashnode *, void *);
+static void do_include_common (cpp_reader *, enum include_type);
+static struct pragma_entry *lookup_pragma_entry (struct pragma_entry *,
+ const cpp_hashnode *);
+static struct pragma_entry *insert_pragma_entry (cpp_reader *,
+ struct pragma_entry **,
+ const cpp_hashnode *,
+ pragma_cb);
+static int count_registered_pragmas (struct pragma_entry *);
+static char ** save_registered_pragmas (struct pragma_entry *, char **);
+static char ** restore_registered_pragmas (cpp_reader *, struct pragma_entry *,
+ char **);
+static void do_pragma_once (cpp_reader *);
+static void do_pragma_poison (cpp_reader *);
+static void do_pragma_system_header (cpp_reader *);
+static void do_pragma_dependency (cpp_reader *);
+static void do_linemarker (cpp_reader *);
+static const cpp_token *get_token_no_padding (cpp_reader *);
+static const cpp_token *get__Pragma_string (cpp_reader *);
+static void destringize_and_run (cpp_reader *, const cpp_string *);
+static int parse_answer (cpp_reader *, struct answer **, int);
+static cpp_hashnode *parse_assertion (cpp_reader *, struct answer **, int);
+static struct answer ** find_answer (cpp_hashnode *, const struct answer *);
+static void handle_assertion (cpp_reader *, const char *, int);
/* This is the table of directive handlers. It is ordered by
frequency of occurrence; the numbers at the end are directive
@@ -167,8 +164,7 @@ D(sccs, T_SCCS, EXTENSION, 0) /* 0 SVR4? */
/* Use the table to generate a series of prototypes, an enum for the
directive names, and an array of directive handlers. */
-/* Don't invoke CONCAT2 with any whitespace or K&R cc will fail. */
-#define D(name, t, o, f) static void CONCAT2(do_,name) PARAMS ((cpp_reader *));
+#define D(name, t, o, f) static void do_##name (cpp_reader *);
DIRECTIVE_TABLE
#undef D
@@ -180,10 +176,9 @@ enum
};
#undef D
-/* Don't invoke CONCAT2 with any whitespace or K&R cc will fail. */
#define D(name, t, origin, flags) \
-{ CONCAT2(do_,name), (const uchar *) STRINGX(name), \
- sizeof STRINGX(name) - 1, origin, flags },
+{ do_##name, (const uchar *) #name, \
+ sizeof #name - 1, origin, flags },
static const directive dtable[] =
{
DIRECTIVE_TABLE
@@ -203,8 +198,7 @@ static const directive linemarker_dir =
/* Skip any remaining tokens in a directive. */
static void
-skip_rest_of_line (pfile)
- cpp_reader *pfile;
+skip_rest_of_line (cpp_reader *pfile)
{
/* Discard all stacked contexts. */
while (pfile->context->prev)
@@ -218,18 +212,16 @@ skip_rest_of_line (pfile)
/* Ensure there are no stray tokens at the end of a directive. */
static void
-check_eol (pfile)
- cpp_reader *pfile;
+check_eol (cpp_reader *pfile)
{
if (! SEEN_EOL () && _cpp_lex_token (pfile)->type != CPP_EOF)
- cpp_error (pfile, DL_PEDWARN, "extra tokens at end of #%s directive",
+ cpp_error (pfile, CPP_DL_PEDWARN, "extra tokens at end of #%s directive",
pfile->directive->name);
}
/* Called when entering a directive, _Pragma or command-line directive. */
static void
-start_directive (pfile)
- cpp_reader *pfile;
+start_directive (cpp_reader *pfile)
{
/* Setup in-directive state. */
pfile->state.in_directive = 1;
@@ -241,9 +233,7 @@ start_directive (pfile)
/* Called when leaving a directive, _Pragma or command-line directive. */
static void
-end_directive (pfile, skip_line)
- cpp_reader *pfile;
- int skip_line;
+end_directive (cpp_reader *pfile, int skip_line)
{
if (CPP_OPTION (pfile, traditional))
{
@@ -274,8 +264,7 @@ end_directive (pfile, skip_line)
/* Prepare to handle the directive in pfile->directive. */
static void
-prepare_directive_trad (pfile)
- cpp_reader *pfile;
+prepare_directive_trad (cpp_reader *pfile)
{
if (pfile->directive != &dtable[T_DEFINE])
{
@@ -283,14 +272,17 @@ prepare_directive_trad (pfile)
&& ! (pfile->directive->flags & EXPAND));
bool was_skipping = pfile->state.skipping;
- pfile->state.skipping = false;
pfile->state.in_expression = (pfile->directive == &dtable[T_IF]
|| pfile->directive == &dtable[T_ELIF]);
+ if (pfile->state.in_expression)
+ pfile->state.skipping = false;
+
if (no_expand)
pfile->state.prevent_expansion++;
- _cpp_read_logical_line_trad (pfile);
+ _cpp_scan_out_logical_line (pfile, NULL);
if (no_expand)
pfile->state.prevent_expansion--;
+
pfile->state.skipping = was_skipping;
_cpp_overlay_buffer (pfile, pfile->out.base,
pfile->out.cur - pfile->out.base);
@@ -303,16 +295,13 @@ prepare_directive_trad (pfile)
/* Output diagnostics for a directive DIR. INDENTED is nonzero if
the '#' was indented. */
static void
-directive_diagnostics (pfile, dir, indented)
- cpp_reader *pfile;
- const directive *dir;
- int indented;
+directive_diagnostics (cpp_reader *pfile, const directive *dir, int indented)
{
/* Issue -pedantic warnings for extensions. */
if (CPP_PEDANTIC (pfile)
&& ! pfile->state.skipping
&& dir->origin == EXTENSION)
- cpp_error (pfile, DL_PEDWARN, "#%s is a GCC extension", dir->name);
+ cpp_error (pfile, CPP_DL_PEDWARN, "#%s is a GCC extension", dir->name);
/* Traditionally, a directive is ignored unless its # is in
column 1. Therefore in code intended to work with K+R
@@ -323,14 +312,14 @@ directive_diagnostics (pfile, dir, indented)
if (CPP_WTRADITIONAL (pfile))
{
if (dir == &dtable[T_ELIF])
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"suggest not using #elif in traditional C");
else if (indented && dir->origin == KANDR)
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"traditional C ignores #%s with the # indented",
dir->name);
else if (!indented && dir->origin != KANDR)
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"suggest hiding #%s from traditional C with an indented #",
dir->name);
}
@@ -342,9 +331,7 @@ directive_diagnostics (pfile, dir, indented)
nonzero if the line of tokens has been handled, zero if we should
continue processing the line. */
int
-_cpp_handle_directive (pfile, indented)
- cpp_reader *pfile;
- int indented;
+_cpp_handle_directive (cpp_reader *pfile, int indented)
{
const directive *dir = 0;
const cpp_token *dname;
@@ -354,7 +341,7 @@ _cpp_handle_directive (pfile, indented)
if (was_parsing_args)
{
if (CPP_OPTION (pfile, pedantic))
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"embedding a directive within macro arguments is not portable");
pfile->state.parsing_args = 0;
pfile->state.prevent_expansion = 0;
@@ -364,8 +351,8 @@ _cpp_handle_directive (pfile, indented)
if (dname->type == CPP_NAME)
{
- if (dname->val.node->directive_index)
- dir = &dtable[dname->val.node->directive_index - 1];
+ if (dname->val.node->is_directive)
+ dir = &dtable[dname->val.node->directive_index];
}
/* We do not recognize the # followed by a number extension in
assembler code. */
@@ -374,7 +361,7 @@ _cpp_handle_directive (pfile, indented)
dir = &linemarker_dir;
if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, preprocessed)
&& ! pfile->state.skipping)
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"style of line directive is a GCC extension");
}
@@ -425,7 +412,7 @@ _cpp_handle_directive (pfile, indented)
if (CPP_OPTION (pfile, lang) == CLK_ASM)
skip = 0;
else if (!pfile->state.skipping)
- cpp_error (pfile, DL_ERROR, "invalid preprocessing directive #%s",
+ cpp_error (pfile, CPP_DL_ERROR, "invalid preprocessing directive #%s",
cpp_token_as_text (pfile, dname));
}
@@ -434,7 +421,7 @@ _cpp_handle_directive (pfile, indented)
prepare_directive_trad (pfile);
if (dir)
- (*pfile->directive->handler) (pfile);
+ pfile->directive->handler (pfile);
else if (skip == 0)
_cpp_backup_tokens (pfile, 1);
@@ -444,43 +431,40 @@ _cpp_handle_directive (pfile, indented)
/* Restore state when within macro args. */
pfile->state.parsing_args = 2;
pfile->state.prevent_expansion = 1;
- pfile->buffer->saved_flags |= PREV_WHITE;
}
return skip;
}
/* Directive handler wrapper used by the command line option
- processor. */
+ processor. BUF is \n terminated. */
static void
-run_directive (pfile, dir_no, buf, count)
- cpp_reader *pfile;
- int dir_no;
- const char *buf;
- size_t count;
+run_directive (cpp_reader *pfile, int dir_no, const char *buf, size_t count)
{
cpp_push_buffer (pfile, (const uchar *) buf, count,
- /* from_stage3 */ true, 1);
+ /* from_stage3 */ true);
/* Disgusting hack. */
if (dir_no == T_PRAGMA)
- pfile->buffer->inc = pfile->buffer->prev->inc;
+ pfile->buffer->file = pfile->buffer->prev->file;
start_directive (pfile);
- /* We don't want a leading # to be interpreted as a directive. */
- pfile->buffer->saved_flags = 0;
+
+ /* This is a short-term fix to prevent a leading '#' being
+ interpreted as a directive. */
+ _cpp_clean_line (pfile);
+
pfile->directive = &dtable[dir_no];
if (CPP_OPTION (pfile, traditional))
prepare_directive_trad (pfile);
- (void) (*pfile->directive->handler) (pfile);
+ pfile->directive->handler (pfile);
end_directive (pfile, 1);
if (dir_no == T_PRAGMA)
- pfile->buffer->inc = NULL;
+ pfile->buffer->file = NULL;
_cpp_pop_buffer (pfile);
}
/* Checks for validity the macro name in #define, #undef, #ifdef and
#ifndef directives. */
static cpp_hashnode *
-lex_macro_node (pfile)
- cpp_reader *pfile;
+lex_macro_node (cpp_reader *pfile)
{
const cpp_token *token = _cpp_lex_token (pfile);
@@ -496,28 +480,27 @@ lex_macro_node (pfile)
cpp_hashnode *node = token->val.node;
if (node == pfile->spec_nodes.n_defined)
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"\"defined\" cannot be used as a macro name");
else if (! (node->flags & NODE_POISONED))
return node;
}
else if (token->flags & NAMED_OP)
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"\"%s\" cannot be used as a macro name as it is an operator in C++",
NODE_NAME (token->val.node));
else if (token->type == CPP_EOF)
- cpp_error (pfile, DL_ERROR, "no macro name given in #%s directive",
+ cpp_error (pfile, CPP_DL_ERROR, "no macro name given in #%s directive",
pfile->directive->name);
else
- cpp_error (pfile, DL_ERROR, "macro names must be identifiers");
+ cpp_error (pfile, CPP_DL_ERROR, "macro names must be identifiers");
return NULL;
}
/* Process a #define directive. Most work is done in cppmacro.c. */
static void
-do_define (pfile)
- cpp_reader *pfile;
+do_define (cpp_reader *pfile)
{
cpp_hashnode *node = lex_macro_node (pfile);
@@ -530,188 +513,217 @@ do_define (pfile)
if (_cpp_create_definition (pfile, node))
if (pfile->cb.define)
- (*pfile->cb.define) (pfile, pfile->directive_line, node);
+ pfile->cb.define (pfile, pfile->directive_line, node);
}
}
/* Handle #undef. Mark the identifier NT_VOID in the hash table. */
static void
-do_undef (pfile)
- cpp_reader *pfile;
+do_undef (cpp_reader *pfile)
{
cpp_hashnode *node = lex_macro_node (pfile);
- /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified identifier
- is not currently defined as a macro name. */
- if (node && node->type == NT_MACRO)
+ if (node)
{
if (pfile->cb.undef)
- (*pfile->cb.undef) (pfile, pfile->directive_line, node);
+ pfile->cb.undef (pfile, pfile->directive_line, node);
- if (node->flags & NODE_WARN)
- cpp_error (pfile, DL_WARNING, "undefining \"%s\"", NODE_NAME (node));
+ /* 6.10.3.5 paragraph 2: [#undef] is ignored if the specified
+ identifier is not currently defined as a macro name. */
+ if (node->type == NT_MACRO)
+ {
+ if (node->flags & NODE_WARN)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "undefining \"%s\"", NODE_NAME (node));
- if (CPP_OPTION (pfile, warn_unused_macros))
- _cpp_warn_if_unused_macro (pfile, node, NULL);
+ if (CPP_OPTION (pfile, warn_unused_macros))
+ _cpp_warn_if_unused_macro (pfile, node, NULL);
- _cpp_free_definition (node);
+ _cpp_free_definition (node);
+ }
}
+
check_eol (pfile);
}
+/* Undefine a single macro/assertion/whatever. */
+
+static int
+undefine_macros (cpp_reader *pfile, cpp_hashnode *h,
+ void *data_p ATTRIBUTE_UNUSED)
+{
+ switch (h->type)
+ {
+ case NT_VOID:
+ break;
+
+ case NT_MACRO:
+ if (pfile->cb.undef)
+ (*pfile->cb.undef) (pfile, pfile->directive_line, h);
+
+ if (CPP_OPTION (pfile, warn_unused_macros))
+ _cpp_warn_if_unused_macro (pfile, h, NULL);
+
+ /* And fall through.... */
+ case NT_ASSERTION:
+ _cpp_free_definition (h);
+ break;
+
+ default:
+ abort ();
+ }
+ h->flags &= ~NODE_POISONED;
+ return 1;
+}
+
+/* Undefine all macros and assertions. */
+
+void
+cpp_undef_all (cpp_reader *pfile)
+{
+ cpp_forall_identifiers (pfile, undefine_macros, NULL);
+}
+
+
/* Helper routine used by parse_include. Reinterpret the current line
as an h-char-sequence (< ... >); we are looking at the first token
- after the <. Returns the header as a token, or NULL on failure. */
-static const cpp_token *
-glue_header_name (pfile)
- cpp_reader *pfile;
+ after the <. Returns a malloced filename. */
+static char *
+glue_header_name (cpp_reader *pfile)
{
- cpp_token *header = NULL;
const cpp_token *token;
- unsigned char *buffer;
+ char *buffer;
size_t len, total_len = 0, capacity = 1024;
/* To avoid lexed tokens overwriting our glued name, we can only
allocate from the string pool once we've lexed everything. */
- buffer = (unsigned char *) xmalloc (capacity);
+ buffer = xmalloc (capacity);
for (;;)
{
token = get_token_no_padding (pfile);
- if (token->type == CPP_GREATER || token->type == CPP_EOF)
+ if (token->type == CPP_GREATER)
break;
+ if (token->type == CPP_EOF)
+ {
+ cpp_error (pfile, CPP_DL_ERROR, "missing terminating > character");
+ break;
+ }
- len = cpp_token_len (token);
+ len = cpp_token_len (token) + 2; /* Leading space, terminating \0. */
if (total_len + len > capacity)
{
capacity = (capacity + len) * 2;
- buffer = (unsigned char *) xrealloc (buffer, capacity);
+ buffer = xrealloc (buffer, capacity);
}
if (token->flags & PREV_WHITE)
buffer[total_len++] = ' ';
- total_len = cpp_spell_token (pfile, token, &buffer[total_len]) - buffer;
- }
-
- if (token->type == CPP_EOF)
- cpp_error (pfile, DL_ERROR, "missing terminating > character");
- else
- {
- unsigned char *token_mem = _cpp_unaligned_alloc (pfile, total_len + 1);
- memcpy (token_mem, buffer, total_len);
- token_mem[total_len] = '\0';
-
- header = _cpp_temp_token (pfile);
- header->type = CPP_HEADER_NAME;
- header->flags = 0;
- header->val.str.len = total_len;
- header->val.str.text = token_mem;
+ total_len = (cpp_spell_token (pfile, token, (uchar *) &buffer[total_len])
+ - (uchar *) buffer);
}
- free ((PTR) buffer);
- return header;
+ buffer[total_len] = '\0';
+ return buffer;
}
-/* Returns the header string of #include, #include_next, #import and
- #pragma dependency. Returns NULL on error. */
-static const cpp_token *
-parse_include (pfile)
- cpp_reader *pfile;
+/* Returns the file name of #include, #include_next, #import and
+ #pragma dependency. The string is malloced and the caller should
+ free it. Returns NULL on error. */
+static const char *
+parse_include (cpp_reader *pfile, int *pangle_brackets)
{
- const unsigned char *dir;
+ char *fname;
const cpp_token *header;
- if (pfile->directive == &dtable[T_PRAGMA])
- dir = U"pragma dependency";
- else
- dir = pfile->directive->name;
-
/* Allow macro expansion. */
header = get_token_no_padding (pfile);
- if (header->type != CPP_STRING && header->type != CPP_HEADER_NAME)
+ if (header->type == CPP_STRING || header->type == CPP_HEADER_NAME)
{
- if (header->type != CPP_LESS)
- {
- cpp_error (pfile, DL_ERROR,
- "#%s expects \"FILENAME\" or <FILENAME>", dir);
- return NULL;
- }
-
- header = glue_header_name (pfile);
- if (header == NULL)
- return header;
+ fname = xmalloc (header->val.str.len - 1);
+ memcpy (fname, header->val.str.text + 1, header->val.str.len - 2);
+ fname[header->val.str.len - 2] = '\0';
+ *pangle_brackets = header->type == CPP_HEADER_NAME;
}
-
- if (header->val.str.len == 0)
+ else if (header->type == CPP_LESS)
+ {
+ fname = glue_header_name (pfile);
+ *pangle_brackets = 1;
+ }
+ else
{
- cpp_error (pfile, DL_ERROR, "empty file name in #%s", dir);
+ const unsigned char *dir;
+
+ if (pfile->directive == &dtable[T_PRAGMA])
+ dir = U"pragma dependency";
+ else
+ dir = pfile->directive->name;
+ cpp_error (pfile, CPP_DL_ERROR, "#%s expects \"FILENAME\" or <FILENAME>",
+ dir);
+
return NULL;
}
- return header;
+ check_eol (pfile);
+ return fname;
}
/* Handle #include, #include_next and #import. */
static void
-do_include_common (pfile, type)
- cpp_reader *pfile;
- enum include_type type;
+do_include_common (cpp_reader *pfile, enum include_type type)
{
- const cpp_token *header;
+ const char *fname;
+ int angle_brackets;
- /* For #include_next, if this is the primary source file, warn and
- use the normal search logic. */
- if (type == IT_INCLUDE_NEXT && ! pfile->buffer->prev)
- {
- cpp_error (pfile, DL_WARNING, "#include_next in primary source file");
- type = IT_INCLUDE;
- }
- else if (type == IT_IMPORT && CPP_OPTION (pfile, warn_import))
- {
- CPP_OPTION (pfile, warn_import) = 0;
- cpp_error (pfile, DL_WARNING,
- "#import is obsolete, use an #ifndef wrapper in the header file");
- }
+ fname = parse_include (pfile, &angle_brackets);
+ if (!fname)
+ return;
- header = parse_include (pfile);
- if (header)
+ /* Prevent #include recursion. */
+ if (pfile->line_maps.depth >= CPP_STACK_MAX)
+ cpp_error (pfile, CPP_DL_ERROR, "#include nested too deeply");
+ else
{
- /* Prevent #include recursion. */
- if (pfile->line_maps.depth >= CPP_STACK_MAX)
- cpp_error (pfile, DL_ERROR, "#include nested too deeply");
- else
- {
- check_eol (pfile);
- /* Get out of macro context, if we are. */
- skip_rest_of_line (pfile);
- if (pfile->cb.include)
- (*pfile->cb.include) (pfile, pfile->directive_line,
- pfile->directive->name, header);
- _cpp_execute_include (pfile, header, type);
- }
+ /* Get out of macro context, if we are. */
+ skip_rest_of_line (pfile);
+
+ if (pfile->cb.include)
+ pfile->cb.include (pfile, pfile->directive_line,
+ pfile->directive->name, fname, angle_brackets);
+
+ _cpp_stack_include (pfile, fname, angle_brackets, type);
}
+
+ free ((void *) fname);
}
static void
-do_include (pfile)
- cpp_reader *pfile;
+do_include (cpp_reader *pfile)
{
do_include_common (pfile, IT_INCLUDE);
}
static void
-do_import (pfile)
- cpp_reader *pfile;
+do_import (cpp_reader *pfile)
{
do_include_common (pfile, IT_IMPORT);
}
static void
-do_include_next (pfile)
- cpp_reader *pfile;
+do_include_next (cpp_reader *pfile)
{
- do_include_common (pfile, IT_INCLUDE_NEXT);
+ enum include_type type = IT_INCLUDE_NEXT;
+
+ /* If this is the primary source file, warn and use the normal
+ search logic. */
+ if (! pfile->buffer->prev)
+ {
+ cpp_error (pfile, CPP_DL_WARNING,
+ "#include_next in primary source file");
+ type = IT_INCLUDE;
+ }
+ do_include_common (pfile, type);
}
/* Subroutine of do_linemarker. Read possible flags after file name.
@@ -719,9 +731,7 @@ do_include_next (pfile)
flag if it is valid, 0 at the end of the directive. Otherwise
complain. */
static unsigned int
-read_flag (pfile, last)
- cpp_reader *pfile;
- unsigned int last;
+read_flag (cpp_reader *pfile, unsigned int last)
{
const cpp_token *token = _cpp_lex_token (pfile);
@@ -736,45 +746,16 @@ read_flag (pfile, last)
}
if (token->type != CPP_EOF)
- cpp_error (pfile, DL_ERROR, "invalid flag \"%s\" in line directive",
+ cpp_error (pfile, CPP_DL_ERROR, "invalid flag \"%s\" in line directive",
cpp_token_as_text (pfile, token));
return 0;
}
-/* Subroutine of do_line and do_linemarker. Returns a version of STR
- which has a NUL terminator and all escape sequences converted to
- their equivalents. Temporary, hopefully. */
-static uchar *
-dequote_string (pfile, str, len)
- cpp_reader *pfile;
- const uchar *str;
- unsigned int len;
-{
- uchar *result = _cpp_unaligned_alloc (pfile, len + 1);
- uchar *dst = result;
- const uchar *limit = str + len;
- cppchar_t c;
-
- while (str < limit)
- {
- c = *str++;
- if (c != '\\')
- *dst++ = c;
- else
- *dst++ = cpp_parse_escape (pfile, &str, limit, 0);
- }
- *dst++ = '\0';
- return result;
-}
-
/* Subroutine of do_line and do_linemarker. Convert a number in STR,
of length LEN, to binary; store it in NUMP, and return 0 if the
number was well-formed, 1 if not. Temporary, hopefully. */
static int
-strtoul_for_line (str, len, nump)
- const uchar *str;
- unsigned int len;
- unsigned long *nump;
+strtoul_for_line (const uchar *str, unsigned int len, long unsigned int *nump)
{
unsigned long reg = 0;
uchar c;
@@ -794,8 +775,7 @@ strtoul_for_line (str, len, nump)
Note that the filename string (if any) is a true string constant
(escapes are interpreted), unlike in #line. */
static void
-do_line (pfile)
- cpp_reader *pfile;
+do_line (cpp_reader *pfile)
{
const cpp_token *token;
const char *new_file = pfile->map->to_file;
@@ -810,25 +790,26 @@ do_line (pfile)
|| strtoul_for_line (token->val.str.text, token->val.str.len,
&new_lineno))
{
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"\"%s\" after #line is not a positive integer",
cpp_token_as_text (pfile, token));
return;
}
if (CPP_PEDANTIC (pfile) && (new_lineno == 0 || new_lineno > cap))
- cpp_error (pfile, DL_PEDWARN, "line number out of range");
+ cpp_error (pfile, CPP_DL_PEDWARN, "line number out of range");
token = cpp_get_token (pfile);
if (token->type == CPP_STRING)
{
- new_file = (const char *) dequote_string (pfile, token->val.str.text,
- token->val.str.len);
+ cpp_string s = { 0, 0 };
+ if (_cpp_interpret_string_notranslate (pfile, &token->val.str, &s))
+ new_file = (const char *)s.text;
check_eol (pfile);
}
else if (token->type != CPP_EOF)
{
- cpp_error (pfile, DL_ERROR, "\"%s\" is not a valid filename",
+ cpp_error (pfile, CPP_DL_ERROR, "\"%s\" is not a valid filename",
cpp_token_as_text (pfile, token));
return;
}
@@ -842,8 +823,7 @@ do_line (pfile)
different syntax and semantics from #line: Flags are allowed,
and we never complain about the line number being too big. */
static void
-do_linemarker (pfile)
- cpp_reader *pfile;
+do_linemarker (cpp_reader *pfile)
{
const cpp_token *token;
const char *new_file = pfile->map->to_file;
@@ -863,7 +843,8 @@ do_linemarker (pfile)
|| strtoul_for_line (token->val.str.text, token->val.str.len,
&new_lineno))
{
- cpp_error (pfile, DL_ERROR, "\"%s\" after # is not a positive integer",
+ cpp_error (pfile, CPP_DL_ERROR,
+ "\"%s\" after # is not a positive integer",
cpp_token_as_text (pfile, token));
return;
}
@@ -871,8 +852,10 @@ do_linemarker (pfile)
token = cpp_get_token (pfile);
if (token->type == CPP_STRING)
{
- new_file = (const char *) dequote_string (pfile, token->val.str.text,
- token->val.str.len);
+ cpp_string s = { 0, 0 };
+ if (_cpp_interpret_string_notranslate (pfile, &token->val.str, &s))
+ new_file = (const char *)s.text;
+
new_sysp = 0;
flag = read_flag (pfile, 0);
if (flag == 1)
@@ -899,7 +882,7 @@ do_linemarker (pfile)
}
else if (token->type != CPP_EOF)
{
- cpp_error (pfile, DL_ERROR, "\"%s\" is not a valid filename",
+ cpp_error (pfile, CPP_DL_ERROR, "\"%s\" is not a valid filename",
cpp_token_as_text (pfile, token));
return;
}
@@ -913,27 +896,21 @@ do_linemarker (pfile)
header, 2 for a system header that needs to be extern "C" protected,
and zero otherwise. */
void
-_cpp_do_file_change (pfile, reason, to_file, file_line, sysp)
- cpp_reader *pfile;
- enum lc_reason reason;
- const char *to_file;
- unsigned int file_line;
- unsigned int sysp;
+_cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
+ const char *to_file, unsigned int file_line,
+ unsigned int sysp)
{
- pfile->map = add_line_map (&pfile->line_maps, reason, sysp,
- pfile->line, to_file, file_line);
+ pfile->map = linemap_add (&pfile->line_maps, reason, sysp,
+ pfile->line, to_file, file_line);
if (pfile->cb.file_change)
- (*pfile->cb.file_change) (pfile, pfile->map);
+ pfile->cb.file_change (pfile, pfile->map);
}
/* Report a warning or error detected by the program we are
processing. Use the directive's tokens in the error message. */
static void
-do_diagnostic (pfile, code, print_dir)
- cpp_reader *pfile;
- int code;
- int print_dir;
+do_diagnostic (cpp_reader *pfile, int code, int print_dir)
{
if (_cpp_begin_message (pfile, code,
pfile->cur_token[-1].line,
@@ -948,31 +925,28 @@ do_diagnostic (pfile, code, print_dir)
}
static void
-do_error (pfile)
- cpp_reader *pfile;
+do_error (cpp_reader *pfile)
{
- do_diagnostic (pfile, DL_ERROR, 1);
+ do_diagnostic (pfile, CPP_DL_ERROR, 1);
}
static void
-do_warning (pfile)
- cpp_reader *pfile;
+do_warning (cpp_reader *pfile)
{
/* We want #warning diagnostics to be emitted in system headers too. */
- do_diagnostic (pfile, DL_WARNING_SYSHDR, 1);
+ do_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, 1);
}
/* Report program identification. */
static void
-do_ident (pfile)
- cpp_reader *pfile;
+do_ident (cpp_reader *pfile)
{
const cpp_token *str = cpp_get_token (pfile);
if (str->type != CPP_STRING)
- cpp_error (pfile, DL_ERROR, "invalid #ident directive");
+ cpp_error (pfile, CPP_DL_ERROR, "invalid #ident directive");
else if (pfile->cb.ident)
- (*pfile->cb.ident) (pfile, pfile->directive_line, &str->val.str);
+ pfile->cb.ident (pfile, pfile->directive_line, &str->val.str);
check_eol (pfile);
}
@@ -981,9 +955,7 @@ do_ident (pfile)
matching entry, or NULL if none is found. The returned entry could
be the start of a namespace chain, or a pragma. */
static struct pragma_entry *
-lookup_pragma_entry (chain, pragma)
- struct pragma_entry *chain;
- const cpp_hashnode *pragma;
+lookup_pragma_entry (struct pragma_entry *chain, const cpp_hashnode *pragma)
{
while (chain && chain->pragma != pragma)
chain = chain->next;
@@ -995,11 +967,8 @@ lookup_pragma_entry (chain, pragma)
singly-linked CHAIN. If handler is NULL, it is a namespace,
otherwise it is a pragma and its handler. */
static struct pragma_entry *
-insert_pragma_entry (pfile, chain, pragma, handler)
- cpp_reader *pfile;
- struct pragma_entry **chain;
- const cpp_hashnode *pragma;
- pragma_cb handler;
+insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain,
+ const cpp_hashnode *pragma, pragma_cb handler)
{
struct pragma_entry *new;
@@ -1026,11 +995,8 @@ insert_pragma_entry (pfile, chain, pragma, handler)
goes in the global namespace. HANDLER is the handler it will call,
which must be non-NULL. */
void
-cpp_register_pragma (pfile, space, name, handler)
- cpp_reader *pfile;
- const char *space;
- const char *name;
- pragma_cb handler;
+cpp_register_pragma (cpp_reader *pfile, const char *space, const char *name,
+ pragma_cb handler)
{
struct pragma_entry **chain = &pfile->pragmas;
struct pragma_entry *entry;
@@ -1057,14 +1023,14 @@ cpp_register_pragma (pfile, space, name, handler)
{
if (entry->is_nspace)
clash:
- cpp_error (pfile, DL_ICE,
+ cpp_error (pfile, CPP_DL_ICE,
"registering \"%s\" as both a pragma and a pragma namespace",
NODE_NAME (node));
else if (space)
- cpp_error (pfile, DL_ICE, "#pragma %s %s is already registered",
+ cpp_error (pfile, CPP_DL_ICE, "#pragma %s %s is already registered",
space, name);
else
- cpp_error (pfile, DL_ICE, "#pragma %s is already registered", name);
+ cpp_error (pfile, CPP_DL_ICE, "#pragma %s is already registered", name);
}
else
insert_pragma_entry (pfile, chain, node, handler);
@@ -1072,8 +1038,7 @@ cpp_register_pragma (pfile, space, name, handler)
/* Register the pragmas the preprocessor itself handles. */
void
-_cpp_init_internal_pragmas (pfile)
- cpp_reader *pfile;
+_cpp_init_internal_pragmas (cpp_reader *pfile)
{
/* Pragmas in the global namespace. */
cpp_register_pragma (pfile, 0, "once", do_pragma_once);
@@ -1084,14 +1049,84 @@ _cpp_init_internal_pragmas (pfile)
cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency);
}
+/* Return the number of registered pragmas in PE. */
+
+static int
+count_registered_pragmas (struct pragma_entry *pe)
+{
+ int ct = 0;
+ for (; pe != NULL; pe = pe->next)
+ {
+ if (pe->is_nspace)
+ ct += count_registered_pragmas (pe->u.space);
+ ct++;
+ }
+ return ct;
+}
+
+/* Save into SD the names of the registered pragmas referenced by PE,
+ and return a pointer to the next free space in SD. */
+
+static char **
+save_registered_pragmas (struct pragma_entry *pe, char **sd)
+{
+ for (; pe != NULL; pe = pe->next)
+ {
+ if (pe->is_nspace)
+ sd = save_registered_pragmas (pe->u.space, sd);
+ *sd++ = xmemdup (HT_STR (&pe->pragma->ident),
+ HT_LEN (&pe->pragma->ident),
+ HT_LEN (&pe->pragma->ident) + 1);
+ }
+ return sd;
+}
+
+/* Return a newly-allocated array which saves the names of the
+ registered pragmas. */
+
+char **
+_cpp_save_pragma_names (cpp_reader *pfile)
+{
+ int ct = count_registered_pragmas (pfile->pragmas);
+ char **result = xnewvec (char *, ct);
+ (void) save_registered_pragmas (pfile->pragmas, result);
+ return result;
+}
+
+/* Restore from SD the names of the registered pragmas referenced by PE,
+ and return a pointer to the next unused name in SD. */
+
+static char **
+restore_registered_pragmas (cpp_reader *pfile, struct pragma_entry *pe,
+ char **sd)
+{
+ for (; pe != NULL; pe = pe->next)
+ {
+ if (pe->is_nspace)
+ sd = restore_registered_pragmas (pfile, pe->u.space, sd);
+ pe->pragma = cpp_lookup (pfile, U *sd, strlen (*sd));
+ free (*sd);
+ sd++;
+ }
+ return sd;
+}
+
+/* Restore the names of the registered pragmas from SAVED. */
+
+void
+_cpp_restore_pragma_names (cpp_reader *pfile, char **saved)
+{
+ (void) restore_registered_pragmas (pfile, pfile->pragmas, saved);
+ free (saved);
+}
+
/* Pragmata handling. We handle some, and pass the rest on to the
front end. C99 defines three pragmas and says that no macro
expansion is to be performed on them; whether or not macro
expansion happens for other pragmas is implementation defined.
This implementation never macro-expands the text after #pragma. */
static void
-do_pragma (pfile)
- cpp_reader *pfile;
+do_pragma (cpp_reader *pfile)
{
const struct pragma_entry *p = NULL;
const cpp_token *token, *pragma_token = pfile->cur_token;
@@ -1122,14 +1157,11 @@ do_pragma (pfile)
if (pfile->cb.line_change)
(*pfile->cb.line_change) (pfile, pragma_token, false);
(*p->u.handler) (pfile);
- if (pfile->cb.line_change)
- (*pfile->cb.line_change) (pfile, pfile->cur_token, false);
-
}
else if (pfile->cb.def_pragma)
{
_cpp_backup_tokens (pfile, count);
- (*pfile->cb.def_pragma) (pfile, pfile->directive_line);
+ pfile->cb.def_pragma (pfile, pfile->directive_line);
}
pfile->state.prevent_expansion--;
@@ -1137,24 +1169,19 @@ do_pragma (pfile)
/* Handle #pragma once. */
static void
-do_pragma_once (pfile)
- cpp_reader *pfile;
+do_pragma_once (cpp_reader *pfile)
{
- cpp_error (pfile, DL_WARNING, "#pragma once is obsolete");
-
if (pfile->buffer->prev == NULL)
- cpp_error (pfile, DL_WARNING, "#pragma once in main file");
- else
- _cpp_never_reread (pfile->buffer->inc);
+ cpp_error (pfile, CPP_DL_WARNING, "#pragma once in main file");
check_eol (pfile);
+ _cpp_mark_file_once_only (pfile, pfile->buffer->file);
}
/* Handle #pragma GCC poison, to poison one or more identifiers so
that the lexer produces a hard error for each subsequent usage. */
static void
-do_pragma_poison (pfile)
- cpp_reader *pfile;
+do_pragma_poison (cpp_reader *pfile)
{
const cpp_token *tok;
cpp_hashnode *hp;
@@ -1167,7 +1194,8 @@ do_pragma_poison (pfile)
break;
if (tok->type != CPP_NAME)
{
- cpp_error (pfile, DL_ERROR, "invalid #pragma GCC poison directive");
+ cpp_error (pfile, CPP_DL_ERROR,
+ "invalid #pragma GCC poison directive");
break;
}
@@ -1176,7 +1204,7 @@ do_pragma_poison (pfile)
continue;
if (hp->type == NT_MACRO)
- cpp_error (pfile, DL_WARNING, "poisoning existing macro \"%s\"",
+ cpp_error (pfile, CPP_DL_WARNING, "poisoning existing macro \"%s\"",
NODE_NAME (hp));
_cpp_free_definition (hp);
hp->flags |= NODE_POISONED | NODE_DIAGNOSTIC;
@@ -1191,13 +1219,12 @@ do_pragma_poison (pfile)
system include directory. To prevent abuse, it is rejected in the
primary source file. */
static void
-do_pragma_system_header (pfile)
- cpp_reader *pfile;
+do_pragma_system_header (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
if (buffer->prev == 0)
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"#pragma system_header ignored outside include file");
else
{
@@ -1211,36 +1238,35 @@ do_pragma_system_header (pfile)
file. Issue a diagnostic, if the specified file is newer. We use this to
determine if a fixed header should be refixed. */
static void
-do_pragma_dependency (pfile)
- cpp_reader *pfile;
+do_pragma_dependency (cpp_reader *pfile)
{
- const cpp_token *header;
- int ordering;
+ const char *fname;
+ int angle_brackets, ordering;
- header = parse_include (pfile);
- if (!header)
+ fname = parse_include (pfile, &angle_brackets);
+ if (!fname)
return;
- ordering = _cpp_compare_file_date (pfile, header);
+ ordering = _cpp_compare_file_date (pfile, fname, angle_brackets);
if (ordering < 0)
- cpp_error (pfile, DL_WARNING, "cannot find source %s",
- cpp_token_as_text (pfile, header));
+ cpp_error (pfile, CPP_DL_WARNING, "cannot find source file %s", fname);
else if (ordering > 0)
{
- cpp_error (pfile, DL_WARNING, "current file is older than %s",
- cpp_token_as_text (pfile, header));
+ cpp_error (pfile, CPP_DL_WARNING,
+ "current file is older than %s", fname);
if (cpp_get_token (pfile)->type != CPP_EOF)
{
_cpp_backup_tokens (pfile, 1);
- do_diagnostic (pfile, DL_WARNING, 0);
+ do_diagnostic (pfile, CPP_DL_WARNING, 0);
}
}
+
+ free ((void *) fname);
}
/* Get a token but skip padding. */
static const cpp_token *
-get_token_no_padding (pfile)
- cpp_reader *pfile;
+get_token_no_padding (cpp_reader *pfile)
{
for (;;)
{
@@ -1253,8 +1279,7 @@ get_token_no_padding (pfile)
/* Check syntax is "(string-literal)". Returns the string on success,
or NULL on failure. */
static const cpp_token *
-get__Pragma_string (pfile)
- cpp_reader *pfile;
+get__Pragma_string (cpp_reader *pfile)
{
const cpp_token *string;
@@ -1274,22 +1299,22 @@ get__Pragma_string (pfile)
/* Destringize IN into a temporary buffer, by removing the first \ of
\" and \\ sequences, and process the result as a #pragma directive. */
static void
-destringize_and_run (pfile, in)
- cpp_reader *pfile;
- const cpp_string *in;
+destringize_and_run (cpp_reader *pfile, const cpp_string *in)
{
const unsigned char *src, *limit;
char *dest, *result;
- dest = result = alloca (in->len + 1);
- for (src = in->text, limit = src + in->len; src < limit;)
+ dest = result = alloca (in->len - 1);
+ src = in->text + 1 + (in->text[0] == 'L');
+ limit = in->text + in->len - 1;
+ while (src < limit)
{
/* We know there is a character following the backslash. */
if (*src == '\\' && (src[1] == '\\' || src[1] == '"'))
src++;
*dest++ = *src++;
}
- *dest = '\0';
+ *dest = '\n';
/* Ugh; an awful kludge. We are really not set up to be lexing
tokens when in the middle of a macro expansion. Use a new
@@ -1329,34 +1354,31 @@ destringize_and_run (pfile, in)
Getting the line markers is a little tricky. */
if (pfile->cb.line_change)
- (*pfile->cb.line_change) (pfile, pfile->cur_token, false);
+ pfile->cb.line_change (pfile, pfile->cur_token, false);
}
/* Handle the _Pragma operator. */
void
-_cpp_do__Pragma (pfile)
- cpp_reader *pfile;
+_cpp_do__Pragma (cpp_reader *pfile)
{
const cpp_token *string = get__Pragma_string (pfile);
if (string)
destringize_and_run (pfile, &string->val.str);
else
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"_Pragma takes a parenthesized string literal");
}
-/* Just ignore #sccs on all systems. */
+/* Ignore #sccs on all systems. */
static void
-do_sccs (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
+do_sccs (cpp_reader *pfile ATTRIBUTE_UNUSED)
{
}
/* Handle #ifdef. */
static void
-do_ifdef (pfile)
- cpp_reader *pfile;
+do_ifdef (cpp_reader *pfile)
{
int skip = 1;
@@ -1377,8 +1399,7 @@ do_ifdef (pfile)
/* Handle #ifndef. */
static void
-do_ifndef (pfile)
- cpp_reader *pfile;
+do_ifndef (cpp_reader *pfile)
{
int skip = 1;
const cpp_hashnode *node = 0;
@@ -1400,12 +1421,11 @@ do_ifndef (pfile)
/* _cpp_parse_expr puts a macro in a "#if !defined ()" expression in
pfile->mi_ind_cmacro so we can handle multiple-include
- optimisations. If macro expansion occurs in the expression, we
+ optimizations. If macro expansion occurs in the expression, we
cannot treat it as a controlling conditional, since the expansion
could change in the future. That is handled by cpp_get_token. */
static void
-do_if (pfile)
- cpp_reader *pfile;
+do_if (cpp_reader *pfile)
{
int skip = 1;
@@ -1419,20 +1439,19 @@ do_if (pfile)
if_stack; this is so that the error message for missing #endif's
etc. will point to the original #if. */
static void
-do_else (pfile)
- cpp_reader *pfile;
+do_else (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
struct if_stack *ifs = buffer->if_stack;
if (ifs == NULL)
- cpp_error (pfile, DL_ERROR, "#else without #if");
+ cpp_error (pfile, CPP_DL_ERROR, "#else without #if");
else
{
if (ifs->type == T_ELSE)
{
- cpp_error (pfile, DL_ERROR, "#else after #else");
- cpp_error_with_line (pfile, DL_ERROR, ifs->line, 0,
+ cpp_error (pfile, CPP_DL_ERROR, "#else after #else");
+ cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0,
"the conditional began here");
}
ifs->type = T_ELSE;
@@ -1453,20 +1472,19 @@ do_else (pfile)
/* Handle a #elif directive by not changing if_stack either. See the
comment above do_else. */
static void
-do_elif (pfile)
- cpp_reader *pfile;
+do_elif (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
struct if_stack *ifs = buffer->if_stack;
if (ifs == NULL)
- cpp_error (pfile, DL_ERROR, "#elif without #if");
+ cpp_error (pfile, CPP_DL_ERROR, "#elif without #if");
else
{
if (ifs->type == T_ELSE)
{
- cpp_error (pfile, DL_ERROR, "#elif after #else");
- cpp_error_with_line (pfile, DL_ERROR, ifs->line, 0,
+ cpp_error (pfile, CPP_DL_ERROR, "#elif after #else");
+ cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0,
"the conditional began here");
}
ifs->type = T_ELIF;
@@ -1489,14 +1507,13 @@ do_elif (pfile)
/* #endif pops the if stack and resets pfile->state.skipping. */
static void
-do_endif (pfile)
- cpp_reader *pfile;
+do_endif (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
struct if_stack *ifs = buffer->if_stack;
if (ifs == NULL)
- cpp_error (pfile, DL_ERROR, "#endif without #if");
+ cpp_error (pfile, CPP_DL_ERROR, "#endif without #if");
else
{
/* Only check EOL if was not originally skipping. */
@@ -1521,11 +1538,8 @@ do_endif (pfile)
is #if or #ifndef, CMACRO is a potentially controlling macro, and
we need to check here that we are at the top of the file. */
static void
-push_conditional (pfile, skip, type, cmacro)
- cpp_reader *pfile;
- int skip;
- int type;
- const cpp_hashnode *cmacro;
+push_conditional (cpp_reader *pfile, int skip, int type,
+ const cpp_hashnode *cmacro)
{
struct if_stack *ifs;
cpp_buffer *buffer = pfile->buffer;
@@ -1551,10 +1565,7 @@ push_conditional (pfile, skip, type, cmacro)
storage, i.e. the #assert case. Returns 0 on success, and sets
ANSWERP to point to the answer. */
static int
-parse_answer (pfile, answerp, type)
- cpp_reader *pfile;
- struct answer **answerp;
- int type;
+parse_answer (cpp_reader *pfile, struct answer **answerp, int type)
{
const cpp_token *paren;
struct answer *answer;
@@ -1579,7 +1590,7 @@ parse_answer (pfile, answerp, type)
if (type == T_UNASSERT && paren->type == CPP_EOF)
return 0;
- cpp_error (pfile, DL_ERROR, "missing '(' after predicate");
+ cpp_error (pfile, CPP_DL_ERROR, "missing '(' after predicate");
return 1;
}
@@ -1594,7 +1605,7 @@ parse_answer (pfile, answerp, type)
if (token->type == CPP_EOF)
{
- cpp_error (pfile, DL_ERROR, "missing ')' to complete answer");
+ cpp_error (pfile, CPP_DL_ERROR, "missing ')' to complete answer");
return 1;
}
@@ -1614,7 +1625,7 @@ parse_answer (pfile, answerp, type)
if (acount == 0)
{
- cpp_error (pfile, DL_ERROR, "predicate's answer is empty");
+ cpp_error (pfile, CPP_DL_ERROR, "predicate's answer is empty");
return 1;
}
@@ -1630,10 +1641,7 @@ parse_answer (pfile, answerp, type)
the hash node of the predicate, or 0 on error. If an answer was
supplied, it is placed in ANSWERP, otherwise it is set to 0. */
static cpp_hashnode *
-parse_assertion (pfile, answerp, type)
- cpp_reader *pfile;
- struct answer **answerp;
- int type;
+parse_assertion (cpp_reader *pfile, struct answer **answerp, int type)
{
cpp_hashnode *result = 0;
const cpp_token *predicate;
@@ -1644,9 +1652,9 @@ parse_assertion (pfile, answerp, type)
*answerp = 0;
predicate = cpp_get_token (pfile);
if (predicate->type == CPP_EOF)
- cpp_error (pfile, DL_ERROR, "assertion without predicate");
+ cpp_error (pfile, CPP_DL_ERROR, "assertion without predicate");
else if (predicate->type != CPP_NAME)
- cpp_error (pfile, DL_ERROR, "predicate must be an identifier");
+ cpp_error (pfile, CPP_DL_ERROR, "predicate must be an identifier");
else if (parse_answer (pfile, answerp, type) == 0)
{
unsigned int len = NODE_LEN (predicate->val.node);
@@ -1665,9 +1673,7 @@ parse_assertion (pfile, answerp, type)
/* Returns a pointer to the pointer to CANDIDATE in the answer chain,
or a pointer to NULL if the answer is not in the chain. */
static struct answer **
-find_answer (node, candidate)
- cpp_hashnode *node;
- const struct answer *candidate;
+find_answer (cpp_hashnode *node, const struct answer *candidate)
{
unsigned int i;
struct answer **result;
@@ -1694,9 +1700,7 @@ find_answer (node, candidate)
nonzero on failure, zero on success. On success, the result of
the test is written into VALUE, otherwise the value 0. */
int
-_cpp_test_assertion (pfile, value)
- cpp_reader *pfile;
- unsigned int *value;
+_cpp_test_assertion (cpp_reader *pfile, unsigned int *value)
{
struct answer *answer;
cpp_hashnode *node;
@@ -1719,8 +1723,7 @@ _cpp_test_assertion (pfile, value)
/* Handle #assert. */
static void
-do_assert (pfile)
- cpp_reader *pfile;
+do_assert (cpp_reader *pfile)
{
struct answer *new_answer;
cpp_hashnode *node;
@@ -1735,7 +1738,7 @@ do_assert (pfile)
{
if (*find_answer (node, new_answer))
{
- cpp_error (pfile, DL_WARNING, "\"%s\" re-asserted",
+ cpp_error (pfile, CPP_DL_WARNING, "\"%s\" re-asserted",
NODE_NAME (node) + 1);
return;
}
@@ -1753,8 +1756,7 @@ do_assert (pfile)
/* Handle #unassert. */
static void
-do_unassert (pfile)
- cpp_reader *pfile;
+do_unassert (cpp_reader *pfile)
{
cpp_hashnode *node;
struct answer *answer;
@@ -1792,9 +1794,7 @@ do_unassert (pfile)
If STR has anything after the identifier, then it should
be identifier=definition. */
void
-cpp_define (pfile, str)
- cpp_reader *pfile;
- const char *str;
+cpp_define (cpp_reader *pfile, const char *str)
{
char *buf, *p;
size_t count;
@@ -1804,7 +1804,7 @@ cpp_define (pfile, str)
tack " 1" on the end. */
count = strlen (str);
- buf = (char *) alloca (count + 3);
+ buf = alloca (count + 3);
memcpy (buf, str, count);
p = strchr (str, '=');
@@ -1815,110 +1815,101 @@ cpp_define (pfile, str)
buf[count++] = ' ';
buf[count++] = '1';
}
- buf[count] = '\0';
+ buf[count] = '\n';
run_directive (pfile, T_DEFINE, buf, count);
}
/* Slight variant of the above for use by initialize_builtins. */
void
-_cpp_define_builtin (pfile, str)
- cpp_reader *pfile;
- const char *str;
+_cpp_define_builtin (cpp_reader *pfile, const char *str)
{
- run_directive (pfile, T_DEFINE, str, strlen (str));
+ size_t len = strlen (str);
+ char *buf = alloca (len + 1);
+ memcpy (buf, str, len);
+ buf[len] = '\n';
+ run_directive (pfile, T_DEFINE, buf, len);
}
/* Process MACRO as if it appeared as the body of an #undef. */
void
-cpp_undef (pfile, macro)
- cpp_reader *pfile;
- const char *macro;
+cpp_undef (cpp_reader *pfile, const char *macro)
{
- run_directive (pfile, T_UNDEF, macro, strlen (macro));
+ size_t len = strlen (macro);
+ char *buf = alloca (len + 1);
+ memcpy (buf, macro, len);
+ buf[len] = '\n';
+ run_directive (pfile, T_UNDEF, buf, len);
}
/* Process the string STR as if it appeared as the body of a #assert. */
void
-cpp_assert (pfile, str)
- cpp_reader *pfile;
- const char *str;
+cpp_assert (cpp_reader *pfile, const char *str)
{
handle_assertion (pfile, str, T_ASSERT);
}
/* Process STR as if it appeared as the body of an #unassert. */
void
-cpp_unassert (pfile, str)
- cpp_reader *pfile;
- const char *str;
+cpp_unassert (cpp_reader *pfile, const char *str)
{
handle_assertion (pfile, str, T_UNASSERT);
}
/* Common code for cpp_assert (-A) and cpp_unassert (-A-). */
static void
-handle_assertion (pfile, str, type)
- cpp_reader *pfile;
- const char *str;
- int type;
+handle_assertion (cpp_reader *pfile, const char *str, int type)
{
size_t count = strlen (str);
const char *p = strchr (str, '=');
+ /* Copy the entire option so we can modify it. Change the first
+ "=" in the string to a '(', and tack a ')' on the end. */
+ char *buf = alloca (count + 2);
+
+ memcpy (buf, str, count);
if (p)
{
- /* Copy the entire option so we can modify it. Change the first
- "=" in the string to a '(', and tack a ')' on the end. */
- char *buf = (char *) alloca (count + 2);
-
- memcpy (buf, str, count);
buf[p - str] = '(';
buf[count++] = ')';
- buf[count] = '\0';
- str = buf;
}
+ buf[count] = '\n';
+ str = buf;
run_directive (pfile, type, str, count);
}
/* The number of errors for a given reader. */
unsigned int
-cpp_errors (pfile)
- cpp_reader *pfile;
+cpp_errors (cpp_reader *pfile)
{
return pfile->errors;
}
/* The options structure. */
cpp_options *
-cpp_get_options (pfile)
- cpp_reader *pfile;
+cpp_get_options (cpp_reader *pfile)
{
return &pfile->opts;
}
/* The callbacks structure. */
cpp_callbacks *
-cpp_get_callbacks (pfile)
- cpp_reader *pfile;
+cpp_get_callbacks (cpp_reader *pfile)
{
return &pfile->cb;
}
/* The line map set. */
-const struct line_maps *
-cpp_get_line_maps (pfile)
- cpp_reader *pfile;
+struct line_maps *
+cpp_get_line_maps (cpp_reader *pfile)
{
return &pfile->line_maps;
}
/* Copy the given callbacks structure to our own. */
void
-cpp_set_callbacks (pfile, cb)
- cpp_reader *pfile;
- cpp_callbacks *cb;
+cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb)
{
pfile->cb = *cb;
}
@@ -1927,44 +1918,37 @@ cpp_set_callbacks (pfile, cb)
doesn't fail. It does not generate a file change call back; that
is the responsibility of the caller. */
cpp_buffer *
-cpp_push_buffer (pfile, buffer, len, from_stage3, return_at_eof)
- cpp_reader *pfile;
- const uchar *buffer;
- size_t len;
- int from_stage3;
- int return_at_eof;
+cpp_push_buffer (cpp_reader *pfile, const uchar *buffer, size_t len,
+ int from_stage3)
{
cpp_buffer *new = xobnew (&pfile->buffer_ob, cpp_buffer);
/* Clears, amongst other things, if_stack and mi_cmacro. */
memset (new, 0, sizeof (cpp_buffer));
- new->line_base = new->buf = new->cur = buffer;
+ new->next_line = new->buf = buffer;
new->rlimit = buffer + len;
- new->from_stage3 = from_stage3 || CPP_OPTION (pfile, traditional);
+ new->from_stage3 = from_stage3;
new->prev = pfile->buffer;
- new->return_at_eof = return_at_eof;
- new->saved_flags = BOL;
+ new->need_line = true;
pfile->buffer = new;
-
return new;
}
/* Pops a single buffer, with a file change call-back if appropriate.
Then pushes the next -include file, if any remain. */
void
-_cpp_pop_buffer (pfile)
- cpp_reader *pfile;
+_cpp_pop_buffer (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->buffer;
- struct include_file *inc = buffer->inc;
+ struct _cpp_file *inc = buffer->file;
struct if_stack *ifs;
/* Walk back up the conditional stack till we reach its level at
entry to this file, issuing error messages. */
for (ifs = buffer->if_stack; ifs; ifs = ifs->next)
- cpp_error_with_line (pfile, DL_ERROR, ifs->line, 0,
+ cpp_error_with_line (pfile, CPP_DL_ERROR, ifs->line, 0,
"unterminated #%s", dtable[ifs->type].name);
/* In case of a missing #endif. */
@@ -1973,6 +1957,8 @@ _cpp_pop_buffer (pfile)
/* _cpp_do_file_change expects pfile->buffer to be the new one. */
pfile->buffer = buffer->prev;
+ free (buffer->notes);
+
/* Free the buffer object now; we may want to push a new buffer
in _cpp_push_next_include_file. */
obstack_free (&pfile->buffer_ob, buffer);
@@ -1981,23 +1967,13 @@ _cpp_pop_buffer (pfile)
{
_cpp_pop_file_buffer (pfile, inc);
- /* Don't generate a callback for popping the main file. */
- if (pfile->buffer)
- {
- _cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0);
-
- /* If this is the main file, there may be some -include
- files left to push. */
- if (!pfile->buffer->prev)
- _cpp_maybe_push_include_file (pfile);
- }
+ _cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0);
}
}
/* Enter all recognized directives in the hash table. */
void
-_cpp_init_directives (pfile)
- cpp_reader *pfile;
+_cpp_init_directives (cpp_reader *pfile)
{
unsigned int i;
cpp_hashnode *node;
@@ -2005,6 +1981,7 @@ _cpp_init_directives (pfile)
for (i = 0; i < (unsigned int) N_DIRECTIVES; i++)
{
node = cpp_lookup (pfile, dtable[i].name, dtable[i].length);
- node->directive_index = i + 1;
+ node->is_directive = 1;
+ node->directive_index = i;
}
}
diff --git a/contrib/gcc/cpplib.h b/contrib/gcc/cpplib.h
index 7b3a54a3576e..3ea4b6b1856a 100644
--- a/contrib/gcc/cpplib.h
+++ b/contrib/gcc/cpplib.h
@@ -1,5 +1,5 @@
/* Definitions for CPP library.
- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Per Bothner, 1994-95.
@@ -31,10 +31,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern "C" {
#endif
-/* For complex reasons, cpp_reader is also typedefed in c-pragma.h. */
-#ifndef GCC_C_PRAGMA_H
typedef struct cpp_reader cpp_reader;
-#endif
typedef struct cpp_buffer cpp_buffer;
typedef struct cpp_options cpp_options;
typedef struct cpp_token cpp_token;
@@ -42,9 +39,9 @@ typedef struct cpp_string cpp_string;
typedef struct cpp_hashnode cpp_hashnode;
typedef struct cpp_macro cpp_macro;
typedef struct cpp_callbacks cpp_callbacks;
+typedef struct cpp_dir cpp_dir;
struct answer;
-struct file_name_map_list;
/* The first three groups, apart from '=', can appear in preprocessor
expressions (+= and -= are used to indicate unary + and - resp.).
@@ -126,18 +123,20 @@ struct file_name_map_list;
OP(CPP_ATSIGN, "@") /* used in Objective-C */ \
\
TK(CPP_NAME, SPELL_IDENT) /* word */ \
- TK(CPP_NUMBER, SPELL_NUMBER) /* 34_be+ta */ \
+ TK(CPP_AT_NAME, SPELL_IDENT) /* @word - Objective-C */ \
+ TK(CPP_NUMBER, SPELL_LITERAL) /* 34_be+ta */ \
\
- TK(CPP_CHAR, SPELL_STRING) /* 'char' */ \
- TK(CPP_WCHAR, SPELL_STRING) /* L'char' */ \
- TK(CPP_OTHER, SPELL_CHAR) /* stray punctuation */ \
+ TK(CPP_CHAR, SPELL_LITERAL) /* 'char' */ \
+ TK(CPP_WCHAR, SPELL_LITERAL) /* L'char' */ \
+ TK(CPP_OTHER, SPELL_LITERAL) /* stray punctuation */ \
\
- TK(CPP_STRING, SPELL_STRING) /* "string" */ \
- TK(CPP_WSTRING, SPELL_STRING) /* L"string" */ \
- TK(CPP_HEADER_NAME, SPELL_STRING) /* <stdio.h> in #include */ \
+ TK(CPP_STRING, SPELL_LITERAL) /* "string" */ \
+ TK(CPP_WSTRING, SPELL_LITERAL) /* L"string" */ \
+ TK(CPP_OBJC_STRING, SPELL_LITERAL) /* @"string" - Objective-C */ \
+ TK(CPP_HEADER_NAME, SPELL_LITERAL) /* <stdio.h> in #include */ \
\
- TK(CPP_COMMENT, SPELL_NUMBER) /* Only if output comments. */ \
- /* SPELL_NUMBER happens to DTRT. */ \
+ TK(CPP_COMMENT, SPELL_LITERAL) /* Only if output comments. */ \
+ /* SPELL_LITERAL happens to DTRT. */ \
TK(CPP_MACRO_ARG, SPELL_NONE) /* Macro argument. */ \
TK(CPP_PADDING, SPELL_NONE) /* Whitespace for cpp0. */
@@ -175,7 +174,7 @@ struct cpp_string
occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */
struct cpp_token
{
- unsigned int line; /* Logical line of first char of token. */
+ fileline line; /* Logical line of first char of token. */
unsigned short col; /* Column of first char of token. */
ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */
unsigned char flags; /* flags - see above */
@@ -186,37 +185,27 @@ struct cpp_token
const cpp_token *source; /* Inherit padding from this token. */
struct cpp_string str; /* A string, or number. */
unsigned int arg_no; /* Argument no. for a CPP_MACRO_ARG. */
- unsigned char c; /* Character represented by CPP_OTHER. */
} val;
};
/* A type wide enough to hold any multibyte source character.
cpplib's character constant interpreter requires an unsigned type.
- Also, a typedef for the signed equivalent. */
-#ifndef MAX_WCHAR_TYPE_SIZE
-# define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE
-#endif
-#if CHAR_BIT * SIZEOF_INT >= MAX_WCHAR_TYPE_SIZE
+ Also, a typedef for the signed equivalent.
+ The width of this type is capped at 32 bits; there do exist targets
+ where wchar_t is 64 bits, but only in a non-default mode, and there
+ would be no meaningful interpretation for a wchar_t value greater
+ than 2^32 anyway -- the widest wide-character encoding around is
+ ISO 10646, which stops at 2^31. */
+#if CHAR_BIT * SIZEOF_INT >= 32
# define CPPCHAR_SIGNED_T int
+#elif CHAR_BIT * SIZEOF_LONG >= 32
+# define CPPCHAR_SIGNED_T long
#else
-# if CHAR_BIT * SIZEOF_LONG >= MAX_WCHAR_TYPE_SIZE || !HAVE_LONG_LONG
-# define CPPCHAR_SIGNED_T long
-# else
-# define CPPCHAR_SIGNED_T long long
-# endif
+# error "Cannot find a least-32-bit signed integer type"
#endif
typedef unsigned CPPCHAR_SIGNED_T cppchar_t;
typedef CPPCHAR_SIGNED_T cppchar_signed_t;
-/* Values for opts.dump_macros.
- dump_only means inhibit output of the preprocessed text
- and instead output the definitions of all user-defined
- macros in a form suitable for use as input to cpp.
- dump_names means pass #define and the macro name through to output.
- dump_definitions means pass the whole definition (plus #define) through
-*/
-enum { dump_none = 0, dump_only, dump_names, dump_definitions };
-
/* This structure is nested inside struct cpp_reader, and
carries all the options visible to the command line. */
struct cpp_options
@@ -224,32 +213,13 @@ struct cpp_options
/* Characters between tab stops. */
unsigned int tabstop;
- /* Pending options - -D, -U, -A, -I, -ixxx. */
- struct cpp_pending *pending;
-
- /* Search paths for include files. */
- struct search_path *quote_include; /* "" */
- struct search_path *bracket_include; /* <> */
-
- /* Map between header names and file names, used only on DOS where
- file names are limited in length. */
- struct file_name_map_list *map_list;
-
- /* Directory prefix that should replace `/usr/lib/gcc-lib/TARGET/VERSION'
- in the standard include file directories. */
- const char *include_prefix;
- unsigned int include_prefix_len;
-
/* The language we're preprocessing. */
enum c_lang lang;
- /* Non-0 means -v, so print the full set of include dirs. */
- unsigned char verbose;
-
/* Nonzero means use extra default include directories for C++. */
unsigned char cplusplus;
- /* Nonzero means handle cplusplus style comments */
+ /* Nonzero means handle cplusplus style comments. */
unsigned char cplusplus_comments;
/* Nonzero means define __OBJC__, treat @ as a special token, and
@@ -281,6 +251,9 @@ struct cpp_options
/* Nonzero means don't print warning messages. */
unsigned char inhibit_warnings;
+ /* Nonzero means complain about deprecated features. */
+ unsigned char warn_deprecated;
+
/* Nonzero means don't suppress warnings from system headers. */
unsigned char warn_system_headers;
@@ -294,9 +267,6 @@ struct cpp_options
/* Nonzero means warn if there are any trigraphs. */
unsigned char warn_trigraphs;
- /* Nonzero means warn if #import is used. */
- unsigned char warn_import;
-
/* Nonzero means warn about multicharacter charconsts. */
unsigned char warn_multichar;
@@ -317,24 +287,17 @@ struct cpp_options
/* Nonzero means turn warnings into errors. */
unsigned char warnings_are_errors;
- /* Nonzero causes output not to be done, but directives such as
- #define that have side effects are still obeyed. */
- unsigned char no_output;
-
/* Nonzero means we should look for header.gcc files that remap file
names. */
unsigned char remap;
- /* Nonzero means don't output line number information. */
- unsigned char no_line_commands;
-
- /* Nonzero means -I- has been seen, so don't look for #include "foo"
- the source-file directory. */
- unsigned char ignore_srcdir;
-
/* Zero means dollar signs are punctuation. */
unsigned char dollars_in_ident;
+ /* True if we should warn about dollars in identifiers or numbers
+ for this translation unit. */
+ unsigned char warn_dollars;
+
/* Nonzero means warn if undefined identifiers are evaluated in an #if. */
unsigned char warn_undef;
@@ -354,18 +317,6 @@ struct cpp_options
bother trying to do macro expansion and whatnot. */
unsigned char preprocessed;
- /* Nonzero disables all the standard directories for headers. */
- unsigned char no_standard_includes;
-
- /* Nonzero disables the C++-specific standard directories for headers. */
- unsigned char no_standard_cplusplus_includes;
-
- /* Nonzero means dump macros in some fashion - see above. */
- unsigned char dump_macros;
-
- /* Nonzero means pass #include lines through to the output. */
- unsigned char dump_includes;
-
/* Print column number in error messages. */
unsigned char show_column;
@@ -375,6 +326,21 @@ struct cpp_options
/* True for traditional preprocessing. */
unsigned char traditional;
+ /* Holds the name of the target (execution) character set. */
+ const char *narrow_charset;
+
+ /* Holds the name of the target wide character set. */
+ const char *wide_charset;
+
+ /* Holds the name of the input character set. */
+ const char *input_charset;
+
+ /* True to warn about precompiled header files we couldn't use. */
+ bool warn_invalid_pch;
+
+ /* True if dependencies should be restored from a precompiled header. */
+ bool restore_pch_deps;
+
/* Dependency generation. */
struct
{
@@ -401,25 +367,59 @@ struct cpp_options
/* True means chars (wide chars) are unsigned. */
bool unsigned_char, unsigned_wchar;
+ /* True if the most significant byte in a word has the lowest
+ address in memory. */
+ bool bytes_big_endian;
+
/* Nonzero means __STDC__ should have the value 0 in system headers. */
unsigned char stdc_0_in_system_headers;
};
-/* Call backs. */
+/* Call backs to cpplib client. */
struct cpp_callbacks
{
/* Called when a new line of preprocessed output is started. */
- void (*line_change) PARAMS ((cpp_reader *, const cpp_token *, int));
- void (*file_change) PARAMS ((cpp_reader *, const struct line_map *));
- void (*include) PARAMS ((cpp_reader *, unsigned int,
- const unsigned char *, const cpp_token *));
- void (*define) PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
- void (*undef) PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
- void (*ident) PARAMS ((cpp_reader *, unsigned int, const cpp_string *));
- void (*def_pragma) PARAMS ((cpp_reader *, unsigned int));
- /* Called when the client has a chance to properly register
- built-ins with cpp_define() and cpp_assert(). */
- void (*register_builtins) PARAMS ((cpp_reader *));
+ void (*line_change) (cpp_reader *, const cpp_token *, int);
+
+ /* Called when switching to/from a new file.
+ The line_map is for the new file. It is NULL if there is no new file.
+ (In C this happens when done with <built-in>+<command line> and also
+ when done with a main file.) This can be used for resource cleanup. */
+ void (*file_change) (cpp_reader *, const struct line_map *);
+
+ void (*dir_change) (cpp_reader *, const char *);
+ void (*include) (cpp_reader *, unsigned int, const unsigned char *,
+ const char *, int);
+ void (*define) (cpp_reader *, unsigned int, cpp_hashnode *);
+ void (*undef) (cpp_reader *, unsigned int, cpp_hashnode *);
+ void (*ident) (cpp_reader *, unsigned int, const cpp_string *);
+ void (*def_pragma) (cpp_reader *, unsigned int);
+ int (*valid_pch) (cpp_reader *, const char *, int);
+ void (*read_pch) (cpp_reader *, const char *, int, const char *);
+};
+
+/* Chain of directories to look for include files in. */
+struct cpp_dir
+{
+ /* NULL-terminated singly-linked list. */
+ struct cpp_dir *next;
+
+ /* NAME of the directory, NUL-terminated. */
+ char *name;
+ unsigned int len;
+
+ /* One if a system header, two if a system header that has extern
+ "C" guards for C++. */
+ unsigned char sysp;
+
+ /* Mapping of file names for this directory for MS-DOS and related
+ platforms. A NULL-terminated array of (from, to) pairs. */
+ const char **name_map;
+
+ /* The C front end uses these to recognize duplicated
+ directories in the search path. */
+ ino_t ino;
+ dev_t dev;
};
/* Name under which this program was invoked. */
@@ -429,7 +429,7 @@ extern const char *progname;
entries for all identifiers: either macros defined by #define
commands (type NT_MACRO), assertions created with #assert
(NT_ASSERTION), or neither of the above (NT_VOID). Builtin macros
- like __LINE__ are flagged NODE_BUILTIN. Poisioned identifiers are
+ like __LINE__ are flagged NODE_BUILTIN. Poisoned identifiers are
flagged NODE_POISONED. NODE_OPERATOR (C++ only) indicates an
identifier that behaves like an operator such as "xor".
NODE_DIAGNOSTIC is for speed in lex_token: it indicates a
@@ -443,6 +443,7 @@ extern const char *progname;
#define NODE_DIAGNOSTIC (1 << 3) /* Possible diagnostic when lexed. */
#define NODE_WARN (1 << 4) /* Warn if redefined or undefined. */
#define NODE_DISABLED (1 << 5) /* A disabled macro. */
+#define NODE_MACRO_ARG (1 << 6) /* Used during #define processing. */
/* Different flavors of hash node. */
enum node_type
@@ -474,124 +475,127 @@ enum builtin_type
/* The common part of an identifier node shared amongst all 3 C front
ends. Also used to store CPP identifiers, which are a superset of
identifiers in the grammatical sense. */
-struct cpp_hashnode
+struct cpp_hashnode GTY(())
{
struct ht_identifier ident;
- unsigned short arg_index; /* Macro argument index. */
- unsigned char directive_index; /* Index into directive table. */
+ unsigned int is_directive : 1;
+ unsigned int directive_index : 7; /* If is_directive,
+ then index into directive table.
+ Otherwise, a NODE_OPERATOR. */
unsigned char rid_code; /* Rid code - for front ends. */
ENUM_BITFIELD(node_type) type : 8; /* CPP node type. */
unsigned char flags; /* CPP flags. */
- union
+ union _cpp_hashnode_value
{
- cpp_macro *macro; /* If a macro. */
- struct answer *answers; /* Answers to an assertion. */
- enum cpp_ttype operator; /* Code for a named operator. */
- enum builtin_type builtin; /* Code for a builtin macro. */
- } value;
+ /* If a macro. */
+ cpp_macro * GTY((skip (""))) macro;
+ /* Answers to an assertion. */
+ struct answer * GTY ((skip (""))) answers;
+ /* Code for a builtin macro. */
+ enum builtin_type GTY ((tag ("1"))) builtin;
+ /* Macro argument index. */
+ unsigned short GTY ((tag ("0"))) arg_index;
+ } GTY ((desc ("0"))) value;
};
-/* Call this first to get a handle to pass to other functions. */
-extern cpp_reader *cpp_create_reader PARAMS ((enum c_lang));
+/* Call this first to get a handle to pass to other functions.
+
+ If you want cpplib to manage its own hashtable, pass in a NULL
+ pointer. Otherwise you should pass in an initialized hash table
+ that cpplib will share; this technique is used by the C front
+ ends. */
+extern cpp_reader *cpp_create_reader (enum c_lang, struct ht *);
/* Call this to change the selected language standard (e.g. because of
command line options). */
-extern void cpp_set_lang PARAMS ((cpp_reader *, enum c_lang));
+extern void cpp_set_lang (cpp_reader *, enum c_lang);
/* Add a dependency TARGET. Quote it for "make" if QUOTE. Can be
called any number of times before cpp_read_main_file(). If no
targets have been added before cpp_read_main_file(), then the
default target is used. */
-extern void cpp_add_dependency_target PARAMS ((cpp_reader *,
- const char * target,
- int quote));
+extern void cpp_add_dependency_target (cpp_reader *, const char *, int);
+
+/* Set the include paths. */
+extern void cpp_set_include_chains (cpp_reader *, cpp_dir *, cpp_dir *, int);
/* Call these to get pointers to the options and callback structures
for a given reader. These pointers are good until you call
cpp_finish on that reader. You can either edit the callbacks
through the pointer returned from cpp_get_callbacks, or set them
with cpp_set_callbacks. */
-extern cpp_options *cpp_get_options PARAMS ((cpp_reader *));
-extern const struct line_maps *cpp_get_line_maps PARAMS ((cpp_reader *));
-extern cpp_callbacks *cpp_get_callbacks PARAMS ((cpp_reader *));
-extern void cpp_set_callbacks PARAMS ((cpp_reader *, cpp_callbacks *));
-
-/* Now call cpp_handle_option[s] to handle 1[or more] switches. The
- return value is the number of arguments used. If
- cpp_handle_options returns without using all arguments, it couldn't
- understand the next switch. Options processing is not completed
- until you call cpp_finish_options. */
-extern int cpp_handle_options PARAMS ((cpp_reader *, int, char **));
-extern int cpp_handle_option PARAMS ((cpp_reader *, int, char **));
+extern cpp_options *cpp_get_options (cpp_reader *);
+extern struct line_maps *cpp_get_line_maps (cpp_reader *);
+extern cpp_callbacks *cpp_get_callbacks (cpp_reader *);
+extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *);
/* This function reads the file, but does not start preprocessing. It
returns the name of the original file; this is the same as the
input file, except for preprocessed input. This will generate at
least one file change callback, and possibly a line change callback
- too. If there was an error opening the file, it returns NULL.
+ too. If there was an error opening the file, it returns NULL. */
+extern const char *cpp_read_main_file (cpp_reader *, const char *);
- If you want cpplib to manage its own hashtable, pass in a NULL
- pointer. Otherise you should pass in an initialized hash table
- that cpplib will share; this technique is used by the C front
- ends. */
-extern const char *cpp_read_main_file PARAMS ((cpp_reader *, const char *,
- struct ht *));
+/* Set up built-ins like __FILE__. */
+extern void cpp_init_builtins (cpp_reader *, int);
+
+/* This is called after options have been parsed, and partially
+ processed. */
+extern void cpp_post_options (cpp_reader *);
-/* Deferred handling of command line options that can generate debug
- callbacks, such as -D and -imacros. Call this after
- cpp_read_main_file. The front ends need this separation so they
- can initialize debug output with the original file name, returned
- from cpp_read_main_file, before they get debug callbacks. */
-extern void cpp_finish_options PARAMS ((cpp_reader *));
+/* Set up translation to the target character set. */
+extern void cpp_init_iconv (cpp_reader *);
/* Call this to finish preprocessing. If you requested dependency
generation, pass an open stream to write the information to,
otherwise NULL. It is your responsibility to close the stream.
Returns cpp_errors (pfile). */
-extern int cpp_finish PARAMS ((cpp_reader *, FILE *deps_stream));
+extern int cpp_finish (cpp_reader *, FILE *deps_stream);
/* Call this to release the handle at the end of preprocessing. Any
use of the handle after this function returns is invalid. Returns
cpp_errors (pfile). */
-extern void cpp_destroy PARAMS ((cpp_reader *));
+extern void cpp_destroy (cpp_reader *);
/* Error count. */
-extern unsigned int cpp_errors PARAMS ((cpp_reader *));
-
-extern unsigned int cpp_token_len PARAMS ((const cpp_token *));
-extern unsigned char *cpp_token_as_text PARAMS ((cpp_reader *,
- const cpp_token *));
-extern unsigned char *cpp_spell_token PARAMS ((cpp_reader *, const cpp_token *,
- unsigned char *));
-extern void cpp_register_pragma PARAMS ((cpp_reader *,
- const char *, const char *,
- void (*) PARAMS ((cpp_reader *))));
-
-extern int cpp_avoid_paste PARAMS ((cpp_reader *, const cpp_token *,
- const cpp_token *));
-extern const cpp_token *cpp_get_token PARAMS ((cpp_reader *));
-extern const unsigned char *cpp_macro_definition PARAMS ((cpp_reader *,
- const cpp_hashnode *));
-extern void _cpp_backup_tokens PARAMS ((cpp_reader *, unsigned int));
+extern unsigned int cpp_errors (cpp_reader *);
+
+extern unsigned int cpp_token_len (const cpp_token *);
+extern unsigned char *cpp_token_as_text (cpp_reader *, const cpp_token *);
+extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *,
+ unsigned char *);
+extern void cpp_register_pragma (cpp_reader *, const char *, const char *,
+ void (*) (cpp_reader *));
+extern int cpp_avoid_paste (cpp_reader *, const cpp_token *,
+ const cpp_token *);
+extern const cpp_token *cpp_get_token (cpp_reader *);
+extern const unsigned char *cpp_macro_definition (cpp_reader *,
+ const cpp_hashnode *);
+extern void _cpp_backup_tokens (cpp_reader *, unsigned int);
/* Evaluate a CPP_CHAR or CPP_WCHAR token. */
-extern cppchar_t
-cpp_interpret_charconst PARAMS ((cpp_reader *, const cpp_token *,
- unsigned int *, int *));
-
-/* Used to register builtins during the register_builtins callback.
+extern cppchar_t cpp_interpret_charconst (cpp_reader *, const cpp_token *,
+ unsigned int *, int *);
+/* Evaluate a vector of CPP_STRING or CPP_WSTRING tokens. */
+extern bool cpp_interpret_string (cpp_reader *,
+ const cpp_string *, size_t,
+ cpp_string *, bool);
+
+/* Used to register macros and assertions, perhaps from the command line.
The text is the same as the command line argument. */
-extern void cpp_define PARAMS ((cpp_reader *, const char *));
-extern void cpp_assert PARAMS ((cpp_reader *, const char *));
-extern void cpp_undef PARAMS ((cpp_reader *, const char *));
-extern void cpp_unassert PARAMS ((cpp_reader *, const char *));
+extern void cpp_define (cpp_reader *, const char *);
+extern void cpp_assert (cpp_reader *, const char *);
+extern void cpp_undef (cpp_reader *, const char *);
+extern void cpp_unassert (cpp_reader *, const char *);
-extern cpp_buffer *cpp_push_buffer PARAMS ((cpp_reader *,
- const unsigned char *, size_t,
- int, int));
-extern int cpp_defined PARAMS ((cpp_reader *, const unsigned char *, int));
+/* Undefine all macros and assertions. */
+extern void cpp_undef_all (cpp_reader *);
+
+extern cpp_buffer *cpp_push_buffer (cpp_reader *, const unsigned char *,
+ size_t, int);
+extern int cpp_defined (cpp_reader *, const unsigned char *, int);
/* A preprocessing number. Code assumes that any unused high bits of
the double integer are set to zero. */
@@ -632,36 +636,36 @@ struct cpp_num
/* Classify a CPP_NUMBER token. The return value is a combination of
the flags from the above sets. */
-extern unsigned cpp_classify_number PARAMS ((cpp_reader *, const cpp_token *));
+extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *);
/* Evaluate a token classified as category CPP_N_INTEGER. */
-extern cpp_num cpp_interpret_integer PARAMS ((cpp_reader *, const cpp_token *,
- unsigned int type));
+extern cpp_num cpp_interpret_integer (cpp_reader *, const cpp_token *,
+ unsigned int type);
/* Sign extend a number, with PRECISION significant bits and all
others assumed clear, to fill out a cpp_num structure. */
-cpp_num cpp_num_sign_extend PARAMS ((cpp_num, size_t));
+cpp_num cpp_num_sign_extend (cpp_num, size_t);
-/* Diagnostic levels. To get a dianostic without associating a
+/* Diagnostic levels. To get a diagnostic without associating a
position in the translation unit with it, use cpp_error_with_line
with a line number of zero. */
/* Warning, an error with -Werror. */
-#define DL_WARNING 0x00
-/* Same as DL_WARNING, except it is not suppressed in system headers. */
-#define DL_WARNING_SYSHDR 0x01
+#define CPP_DL_WARNING 0x00
+/* Same as CPP_DL_WARNING, except it is not suppressed in system headers. */
+#define CPP_DL_WARNING_SYSHDR 0x01
/* Warning, an error with -pedantic-errors or -Werror. */
-#define DL_PEDWARN 0x02
+#define CPP_DL_PEDWARN 0x02
/* An error. */
-#define DL_ERROR 0x03
+#define CPP_DL_ERROR 0x03
/* An internal consistency check failed. Prints "internal error: ",
- otherwise the same as DL_ERROR. */
-#define DL_ICE 0x04
+ otherwise the same as CPP_DL_ERROR. */
+#define CPP_DL_ICE 0x04
/* Extracts a diagnostic level from an int. */
-#define DL_EXTRACT(l) (l & 0xf)
+#define CPP_DL_EXTRACT(l) (l & 0xf)
/* Nonzero if a diagnostic level is one of the warnings. */
-#define DL_WARNING_P(l) (DL_EXTRACT (l) >= DL_WARNING \
- && DL_EXTRACT (l) <= DL_PEDWARN)
+#define CPP_DL_WARNING_P(l) (CPP_DL_EXTRACT (l) >= CPP_DL_WARNING \
+ && CPP_DL_EXTRACT (l) <= CPP_DL_PEDWARN)
/* N.B. The error-message-printer prototypes have not been nicely
formatted because exgettext needs to see 'msgid' on the same line
@@ -670,60 +674,63 @@ cpp_num cpp_num_sign_extend PARAMS ((cpp_num, size_t));
getting ridiculously oversized. */
/* Output a diagnostic of some kind. */
-extern void cpp_error PARAMS ((cpp_reader *, int, const char *msgid, ...))
+extern void cpp_error (cpp_reader *, int, const char *msgid, ...)
ATTRIBUTE_PRINTF_3;
-/* Output a diagnostic of severity LEVEL, with "MSG: " preceding the
+/* Output a diagnostic with "MSGID: " preceding the
error string of errno. No location is printed. */
-extern void cpp_errno PARAMS ((cpp_reader *, int level, const char *msg));
+extern void cpp_errno (cpp_reader *, int, const char *msgid);
/* Same as cpp_error, except additionally specifies a position as a
(translation unit) physical line and physical column. If the line is
zero, then no location is printed. */
-extern void cpp_error_with_line PARAMS ((cpp_reader *, int, unsigned, unsigned, const char *msgid, ...))
- ATTRIBUTE_PRINTF_5;
+extern void cpp_error_with_line (cpp_reader *, int, fileline, unsigned,
+ const char *msgid, ...) ATTRIBUTE_PRINTF_5;
/* In cpplex.c */
-extern int cpp_ideq PARAMS ((const cpp_token *,
- const char *));
-extern void cpp_output_line PARAMS ((cpp_reader *, FILE *));
-extern void cpp_output_token PARAMS ((const cpp_token *, FILE *));
-extern const char *cpp_type2name PARAMS ((enum cpp_ttype));
+extern int cpp_ideq (const cpp_token *, const char *);
+extern void cpp_output_line (cpp_reader *, FILE *);
+extern void cpp_output_token (const cpp_token *, FILE *);
+extern const char *cpp_type2name (enum cpp_ttype);
/* Returns the value of an escape sequence, truncated to the correct
target precision. PSTR points to the input pointer, which is just
after the backslash. LIMIT is how much text we have. WIDE is true
if the escape sequence is part of a wide character constant or
string literal. Handles all relevant diagnostics. */
-extern cppchar_t cpp_parse_escape PARAMS ((cpp_reader *,
- const unsigned char ** pstr,
- const unsigned char *limit,
- int wide));
+extern cppchar_t cpp_parse_escape (cpp_reader *, const unsigned char ** pstr,
+ const unsigned char *limit, int wide);
/* In cpphash.c */
/* Lookup an identifier in the hashtable. Puts the identifier in the
table if it is not already there. */
-extern cpp_hashnode *cpp_lookup PARAMS ((cpp_reader *,
- const unsigned char *,
- unsigned int));
+extern cpp_hashnode *cpp_lookup (cpp_reader *, const unsigned char *,
+ unsigned int);
-typedef int (*cpp_cb) PARAMS ((cpp_reader *, cpp_hashnode *, void *));
-extern void cpp_forall_identifiers PARAMS ((cpp_reader *,
- cpp_cb, void *));
+typedef int (*cpp_cb) (cpp_reader *, cpp_hashnode *, void *);
+extern void cpp_forall_identifiers (cpp_reader *, cpp_cb, void *);
/* In cppmacro.c */
-extern void cpp_scan_nooutput PARAMS ((cpp_reader *));
-extern int cpp_sys_macro_p PARAMS ((cpp_reader *));
-extern unsigned char *cpp_quote_string PARAMS ((unsigned char *,
- const unsigned char *,
- unsigned int));
+extern void cpp_scan_nooutput (cpp_reader *);
+extern int cpp_sys_macro_p (cpp_reader *);
+extern unsigned char *cpp_quote_string (unsigned char *, const unsigned char *,
+ unsigned int);
/* In cppfiles.c */
-extern int cpp_included PARAMS ((cpp_reader *, const char *));
-extern void cpp_make_system_header PARAMS ((cpp_reader *, int, int));
-
-/* In cppmain.c */
-extern void cpp_preprocess_file PARAMS ((cpp_reader *, const char *, FILE *));
+extern bool cpp_included (cpp_reader *, const char *);
+extern void cpp_make_system_header (cpp_reader *, int, int);
+extern bool cpp_push_include (cpp_reader *, const char *);
+extern void cpp_change_file (cpp_reader *, enum lc_reason, const char *);
+
+/* In cpppch.c */
+struct save_macro_data;
+extern int cpp_save_state (cpp_reader *, FILE *);
+extern int cpp_write_pch_deps (cpp_reader *, FILE *);
+extern int cpp_write_pch_state (cpp_reader *, FILE *);
+extern int cpp_valid_state (cpp_reader *, const char *, int);
+extern void cpp_prepare_state (cpp_reader *, struct save_macro_data **);
+extern int cpp_read_state (cpp_reader *, const char *, FILE *,
+ struct save_macro_data *);
#ifdef __cplusplus
}
diff --git a/contrib/gcc/cppmacro.c b/contrib/gcc/cppmacro.c
index b97fe811c71b..11ac09f12e1d 100644
--- a/contrib/gcc/cppmacro.c
+++ b/contrib/gcc/cppmacro.c
@@ -1,6 +1,6 @@
/* Part of CPP library. (Macro and #define handling.)
Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Written by Per Bothner, 1994.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -40,57 +40,48 @@ struct macro_arg
/* Macro expansion. */
-static int enter_macro_context PARAMS ((cpp_reader *, cpp_hashnode *));
-static int builtin_macro PARAMS ((cpp_reader *, cpp_hashnode *));
-static void push_token_context
- PARAMS ((cpp_reader *, cpp_hashnode *, const cpp_token *, unsigned int));
-static void push_ptoken_context
- PARAMS ((cpp_reader *, cpp_hashnode *, _cpp_buff *,
- const cpp_token **, unsigned int));
-static _cpp_buff *collect_args PARAMS ((cpp_reader *, const cpp_hashnode *));
-static cpp_context *next_context PARAMS ((cpp_reader *));
-static const cpp_token *padding_token
- PARAMS ((cpp_reader *, const cpp_token *));
-static void expand_arg PARAMS ((cpp_reader *, macro_arg *));
-static const cpp_token *new_string_token PARAMS ((cpp_reader *, uchar *,
- unsigned int));
-static const cpp_token *stringify_arg PARAMS ((cpp_reader *, macro_arg *));
-static void paste_all_tokens PARAMS ((cpp_reader *, const cpp_token *));
-static bool paste_tokens PARAMS ((cpp_reader *, const cpp_token **,
- const cpp_token *));
-static void replace_args PARAMS ((cpp_reader *, cpp_hashnode *, cpp_macro *,
- macro_arg *));
-static _cpp_buff *funlike_invocation_p PARAMS ((cpp_reader *, cpp_hashnode *));
-static bool create_iso_definition PARAMS ((cpp_reader *, cpp_macro *));
+static int enter_macro_context (cpp_reader *, cpp_hashnode *);
+static int builtin_macro (cpp_reader *, cpp_hashnode *);
+static void push_token_context (cpp_reader *, cpp_hashnode *,
+ const cpp_token *, unsigned int);
+static void push_ptoken_context (cpp_reader *, cpp_hashnode *, _cpp_buff *,
+ const cpp_token **, unsigned int);
+static _cpp_buff *collect_args (cpp_reader *, const cpp_hashnode *);
+static cpp_context *next_context (cpp_reader *);
+static const cpp_token *padding_token (cpp_reader *, const cpp_token *);
+static void expand_arg (cpp_reader *, macro_arg *);
+static const cpp_token *new_string_token (cpp_reader *, uchar *, unsigned int);
+static const cpp_token *stringify_arg (cpp_reader *, macro_arg *);
+static void paste_all_tokens (cpp_reader *, const cpp_token *);
+static bool paste_tokens (cpp_reader *, const cpp_token **, const cpp_token *);
+static void replace_args (cpp_reader *, cpp_hashnode *, cpp_macro *,
+ macro_arg *);
+static _cpp_buff *funlike_invocation_p (cpp_reader *, cpp_hashnode *);
+static bool create_iso_definition (cpp_reader *, cpp_macro *);
/* #define directive parsing and handling. */
-static cpp_token *alloc_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
-static cpp_token *lex_expansion_token PARAMS ((cpp_reader *, cpp_macro *));
-static bool warn_of_redefinition PARAMS ((cpp_reader *, const cpp_hashnode *,
- const cpp_macro *));
-static bool parse_params PARAMS ((cpp_reader *, cpp_macro *));
-static void check_trad_stringification PARAMS ((cpp_reader *,
- const cpp_macro *,
- const cpp_string *));
+static cpp_token *alloc_expansion_token (cpp_reader *, cpp_macro *);
+static cpp_token *lex_expansion_token (cpp_reader *, cpp_macro *);
+static bool warn_of_redefinition (cpp_reader *, const cpp_hashnode *,
+ const cpp_macro *);
+static bool parse_params (cpp_reader *, cpp_macro *);
+static void check_trad_stringification (cpp_reader *, const cpp_macro *,
+ const cpp_string *);
/* Emits a warning if NODE is a macro defined in the main file that
has not been used. */
int
-_cpp_warn_if_unused_macro (pfile, node, v)
- cpp_reader *pfile;
- cpp_hashnode *node;
- void *v ATTRIBUTE_UNUSED;
+_cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node,
+ void *v ATTRIBUTE_UNUSED)
{
if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
{
cpp_macro *macro = node->value.macro;
if (!macro->used
- /* Skip front-end built-ins and command line macros. */
- && macro->line >= pfile->first_unused_line
- && MAIN_FILE_P (lookup_line (&pfile->line_maps, macro->line)))
- cpp_error_with_line (pfile, DL_WARNING, macro->line, 0,
+ && MAIN_FILE_P (linemap_lookup (&pfile->line_maps, macro->line)))
+ cpp_error_with_line (pfile, CPP_DL_WARNING, macro->line, 0,
"macro \"%s\" is not used", NODE_NAME (node));
}
@@ -100,10 +91,7 @@ _cpp_warn_if_unused_macro (pfile, node, v)
/* Allocates and returns a CPP_STRING token, containing TEXT of length
LEN, after null-terminating it. TEXT must be in permanent storage. */
static const cpp_token *
-new_string_token (pfile, text, len)
- cpp_reader *pfile;
- unsigned char *text;
- unsigned int len;
+new_string_token (cpp_reader *pfile, unsigned char *text, unsigned int len)
{
cpp_token *token = _cpp_temp_token (pfile);
@@ -126,9 +114,7 @@ static const char * const monthnames[] =
is created. Returns 1 if it generates a new token context, 0 to
return the token to the caller. */
const uchar *
-_cpp_builtin_macro_text (pfile, node)
- cpp_reader *pfile;
- cpp_hashnode *node;
+_cpp_builtin_macro_text (cpp_reader *pfile, cpp_hashnode *node)
{
const uchar *result = NULL;
unsigned int number = 1;
@@ -136,7 +122,7 @@ _cpp_builtin_macro_text (pfile, node)
switch (node->value.builtin)
{
default:
- cpp_error (pfile, DL_ICE, "invalid built-in macro \"%s\"",
+ cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"",
NODE_NAME (node));
break;
@@ -221,7 +207,8 @@ _cpp_builtin_macro_text (pfile, node)
pfile->date = _cpp_unaligned_alloc (pfile,
sizeof ("\"Oct 11 1347\""));
sprintf ((char *) pfile->date, "\"%s %2d %4d\"",
- monthnames[tb->tm_mon], tb->tm_mday, tb->tm_year + 1900);
+ monthnames[tb->tm_mon], tb->tm_mday,
+ tb->tm_year + 1900);
pfile->time = _cpp_unaligned_alloc (pfile,
sizeof ("\"12:34:56\""));
@@ -230,7 +217,7 @@ _cpp_builtin_macro_text (pfile, node)
}
else
{
- cpp_errno (pfile, DL_WARNING,
+ cpp_errno (pfile, CPP_DL_WARNING,
"could not determine date and time");
pfile->date = U"\"??? ?? ????\"";
@@ -260,11 +247,11 @@ _cpp_builtin_macro_text (pfile, node)
created. Returns 1 if it generates a new token context, 0 to
return the token to the caller. */
static int
-builtin_macro (pfile, node)
- cpp_reader *pfile;
- cpp_hashnode *node;
+builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
{
const uchar *buf;
+ size_t len;
+ char *nbuf;
if (node->value.builtin == BT_PRAGMA)
{
@@ -278,20 +265,19 @@ builtin_macro (pfile, node)
}
buf = _cpp_builtin_macro_text (pfile, node);
+ len = ustrlen (buf);
+ nbuf = alloca (len + 1);
+ memcpy (nbuf, buf, len);
+ nbuf[len]='\n';
- cpp_push_buffer (pfile, buf, ustrlen (buf), /* from_stage3 */ true, 1);
-
- /* Tweak the column number the lexer will report. */
- pfile->buffer->col_adjust = pfile->cur_token[-1].col - 1;
-
- /* We don't want a leading # to be interpreted as a directive. */
- pfile->buffer->saved_flags = 0;
+ cpp_push_buffer (pfile, (uchar *) nbuf, len, /* from_stage3 */ true);
+ _cpp_clean_line (pfile);
/* Set pfile->cur_token as required by _cpp_lex_direct. */
pfile->cur_token = _cpp_temp_token (pfile);
push_token_context (pfile, NULL, _cpp_lex_direct (pfile), 1);
if (pfile->buffer->cur != pfile->buffer->rlimit)
- cpp_error (pfile, DL_ICE, "invalid built-in macro \"%s\"",
+ cpp_error (pfile, CPP_DL_ICE, "invalid built-in macro \"%s\"",
NODE_NAME (node));
_cpp_pop_buffer (pfile);
@@ -303,10 +289,7 @@ builtin_macro (pfile, node)
converted to octal. DEST must be of sufficient size. Returns
a pointer to the end of the string. */
uchar *
-cpp_quote_string (dest, src, len)
- uchar *dest;
- const uchar *src;
- unsigned int len;
+cpp_quote_string (uchar *dest, const uchar *src, unsigned int len)
{
while (len--)
{
@@ -335,15 +318,18 @@ cpp_quote_string (dest, src, len)
/* Convert a token sequence ARG to a single string token according to
the rules of the ISO C #-operator. */
static const cpp_token *
-stringify_arg (pfile, arg)
- cpp_reader *pfile;
- macro_arg *arg;
+stringify_arg (cpp_reader *pfile, macro_arg *arg)
{
- unsigned char *dest = BUFF_FRONT (pfile->u_buff);
+ unsigned char *dest;
unsigned int i, escape_it, backslash_count = 0;
const cpp_token *source = NULL;
size_t len;
+ if (BUFF_ROOM (pfile->u_buff) < 3)
+ _cpp_extend_buff (pfile, &pfile->u_buff, 3);
+ dest = BUFF_FRONT (pfile->u_buff);
+ *dest++ = '"';
+
/* Loop, reading in the argument's tokens. */
for (i = 0; i < arg->count; i++)
{
@@ -360,11 +346,11 @@ stringify_arg (pfile, arg)
|| token->type == CPP_CHAR || token->type == CPP_WCHAR);
/* Room for each char being written in octal, initial space and
- final NUL. */
+ final quote and NUL. */
len = cpp_token_len (token);
if (escape_it)
len *= 4;
- len += 2;
+ len += 3;
if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < len)
{
@@ -374,7 +360,7 @@ stringify_arg (pfile, arg)
}
/* Leading white space? */
- if (dest != BUFF_FRONT (pfile->u_buff))
+ if (dest - 1 != BUFF_FRONT (pfile->u_buff))
{
if (source == NULL)
source = token;
@@ -394,7 +380,7 @@ stringify_arg (pfile, arg)
else
dest = cpp_spell_token (pfile, token, dest);
- if (token->type == CPP_OTHER && token->val.c == '\\')
+ if (token->type == CPP_OTHER && token->val.str.text[0] == '\\')
backslash_count++;
else
backslash_count = 0;
@@ -403,18 +389,13 @@ stringify_arg (pfile, arg)
/* Ignore the final \ of invalid string literals. */
if (backslash_count & 1)
{
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"invalid string literal, ignoring final '\\'");
dest--;
}
/* Commit the memory, including NUL, and return the token. */
- if ((size_t) (BUFF_LIMIT (pfile->u_buff) - dest) < 1)
- {
- size_t len_so_far = dest - BUFF_FRONT (pfile->u_buff);
- _cpp_extend_buff (pfile, &pfile->u_buff, 1);
- dest = BUFF_FRONT (pfile->u_buff) + len_so_far;
- }
+ *dest++ = '"';
len = dest - BUFF_FRONT (pfile->u_buff);
BUFF_FRONT (pfile->u_buff) = dest + 1;
return new_string_token (pfile, dest - len, len);
@@ -424,9 +405,7 @@ stringify_arg (pfile, arg)
case, PLHS is updated to point to the pasted token, which is
guaranteed to not have the PASTE_LEFT flag set. */
static bool
-paste_tokens (pfile, plhs, rhs)
- cpp_reader *pfile;
- const cpp_token **plhs, *rhs;
+paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
{
unsigned char *buf, *end;
const cpp_token *lhs;
@@ -435,7 +414,7 @@ paste_tokens (pfile, plhs, rhs)
lhs = *plhs;
len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1;
- buf = (unsigned char *) alloca (len);
+ buf = alloca (len);
end = cpp_spell_token (pfile, lhs, buf);
/* Avoid comment headers, since they are still processed in stage 3.
@@ -445,15 +424,10 @@ paste_tokens (pfile, plhs, rhs)
if (lhs->type == CPP_DIV && rhs->type != CPP_EQ)
*end++ = ' ';
end = cpp_spell_token (pfile, rhs, end);
- *end = '\0';
-
- cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true, 1);
-
- /* Tweak the column number the lexer will report. */
- pfile->buffer->col_adjust = pfile->cur_token[-1].col - 1;
+ *end = '\n';
- /* We don't want a leading # to be interpreted as a directive. */
- pfile->buffer->saved_flags = 0;
+ cpp_push_buffer (pfile, buf, end - buf, /* from_stage3 */ true);
+ _cpp_clean_line (pfile);
/* Set pfile->cur_token as required by _cpp_lex_direct. */
pfile->cur_token = _cpp_temp_token (pfile);
@@ -472,9 +446,7 @@ paste_tokens (pfile, plhs, rhs)
successful pastes, with the effect that the RHS appears in the
output stream after the pasted LHS normally. */
static void
-paste_all_tokens (pfile, lhs)
- cpp_reader *pfile;
- const cpp_token *lhs;
+paste_all_tokens (cpp_reader *pfile, const cpp_token *lhs)
{
const cpp_token *rhs;
cpp_context *context = pfile->context;
@@ -500,7 +472,7 @@ paste_all_tokens (pfile, lhs)
/* Mandatory error for all apart from assembler. */
if (CPP_OPTION (pfile, lang) != CLK_ASM)
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"pasting \"%s\" and \"%s\" does not give a valid preprocessing token",
cpp_token_as_text (pfile, lhs),
cpp_token_as_text (pfile, rhs));
@@ -520,11 +492,7 @@ paste_all_tokens (pfile, lhs)
Note that MACRO cannot necessarily be deduced from NODE, in case
NODE was redefined whilst collecting arguments. */
bool
-_cpp_arguments_ok (pfile, macro, node, argc)
- cpp_reader *pfile;
- cpp_macro *macro;
- const cpp_hashnode *node;
- unsigned int argc;
+_cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node, unsigned int argc)
{
if (argc == macro->paramc)
return true;
@@ -542,17 +510,17 @@ _cpp_arguments_ok (pfile, macro, node, argc)
if (argc + 1 == macro->paramc && macro->variadic)
{
if (CPP_PEDANTIC (pfile) && ! macro->syshdr)
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"ISO C99 requires rest arguments to be used");
return true;
}
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"macro \"%s\" requires %u arguments, but only %u given",
NODE_NAME (node), macro->paramc, argc);
}
else
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"macro \"%s\" passed %u arguments, but takes just %u",
NODE_NAME (node), argc, macro->paramc);
@@ -565,9 +533,7 @@ _cpp_arguments_ok (pfile, macro, node, argc)
NULL. Each argument is terminated by a CPP_EOF token, for the
future benefit of expand_arg(). */
static _cpp_buff *
-collect_args (pfile, node)
- cpp_reader *pfile;
- const cpp_hashnode *node;
+collect_args (cpp_reader *pfile, const cpp_hashnode *node)
{
_cpp_buff *buff, *base_buff;
cpp_macro *macro;
@@ -665,7 +631,7 @@ collect_args (pfile, node)
callers at the end of an -include-d file. */
if (pfile->context->prev || pfile->state.in_directive)
_cpp_backup_tokens (pfile, 1);
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"unterminated argument list invoking macro \"%s\"",
NODE_NAME (node));
}
@@ -701,9 +667,7 @@ collect_args (pfile, node)
intervening padding tokens. If we find the parenthesis, collect
the arguments and return the buffer containing them. */
static _cpp_buff *
-funlike_invocation_p (pfile, node)
- cpp_reader *pfile;
- cpp_hashnode *node;
+funlike_invocation_p (cpp_reader *pfile, cpp_hashnode *node)
{
const cpp_token *token, *padding = NULL;
@@ -743,9 +707,7 @@ funlike_invocation_p (pfile, node)
containing its yet-to-be-rescanned replacement list and return one.
Otherwise, we don't push a context and return zero. */
static int
-enter_macro_context (pfile, node)
- cpp_reader *pfile;
- cpp_hashnode *node;
+enter_macro_context (cpp_reader *pfile, cpp_hashnode *node)
{
/* The presence of a macro invalidates a file's controlling macro. */
pfile->mi_valid = false;
@@ -772,7 +734,7 @@ enter_macro_context (pfile, node)
if (buff == NULL)
{
if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"function-like macro \"%s\" must be used with arguments in traditional C",
NODE_NAME (node));
@@ -804,11 +766,7 @@ enter_macro_context (pfile, node)
Expand each argument before replacing, unless it is operated upon
by the # or ## operators. */
static void
-replace_args (pfile, node, macro, args)
- cpp_reader *pfile;
- cpp_hashnode *node;
- cpp_macro *macro;
- macro_arg *args;
+replace_args (cpp_reader *pfile, cpp_hashnode *node, cpp_macro *macro, macro_arg *args)
{
unsigned int i, total;
const cpp_token *src, *limit;
@@ -940,9 +898,7 @@ replace_args (pfile, node, macro, args)
/* Return a special padding token, with padding inherited from SOURCE. */
static const cpp_token *
-padding_token (pfile, source)
- cpp_reader *pfile;
- const cpp_token *source;
+padding_token (cpp_reader *pfile, const cpp_token *source)
{
cpp_token *result = _cpp_temp_token (pfile);
@@ -955,8 +911,7 @@ padding_token (pfile, source)
/* Get a new uninitialized context. Create a new one if we cannot
re-use an old one. */
static cpp_context *
-next_context (pfile)
- cpp_reader *pfile;
+next_context (cpp_reader *pfile)
{
cpp_context *result = pfile->context->next;
@@ -974,12 +929,8 @@ next_context (pfile)
/* Push a list of pointers to tokens. */
static void
-push_ptoken_context (pfile, macro, buff, first, count)
- cpp_reader *pfile;
- cpp_hashnode *macro;
- _cpp_buff *buff;
- const cpp_token **first;
- unsigned int count;
+push_ptoken_context (cpp_reader *pfile, cpp_hashnode *macro, _cpp_buff *buff,
+ const cpp_token **first, unsigned int count)
{
cpp_context *context = next_context (pfile);
@@ -992,11 +943,8 @@ push_ptoken_context (pfile, macro, buff, first, count)
/* Push a list of tokens. */
static void
-push_token_context (pfile, macro, first, count)
- cpp_reader *pfile;
- cpp_hashnode *macro;
- const cpp_token *first;
- unsigned int count;
+push_token_context (cpp_reader *pfile, cpp_hashnode *macro,
+ const cpp_token *first, unsigned int count)
{
cpp_context *context = next_context (pfile);
@@ -1009,11 +957,8 @@ push_token_context (pfile, macro, first, count)
/* Push a traditional macro's replacement text. */
void
-_cpp_push_text_context (pfile, macro, start, len)
- cpp_reader *pfile;
- cpp_hashnode *macro;
- const uchar *start;
- size_t len;
+_cpp_push_text_context (cpp_reader *pfile, cpp_hashnode *macro,
+ const uchar *start, size_t len)
{
cpp_context *context = next_context (pfile);
@@ -1032,9 +977,7 @@ _cpp_push_text_context (pfile, macro, start, len)
has terminated the argument's tokens with a CPP_EOF so that we know
when we have fully expanded the argument. */
static void
-expand_arg (pfile, arg)
- cpp_reader *pfile;
- macro_arg *arg;
+expand_arg (cpp_reader *pfile, macro_arg *arg)
{
unsigned int capacity;
bool saved_warn_trad;
@@ -1048,8 +991,7 @@ expand_arg (pfile, arg)
/* Loop, reading in the arguments. */
capacity = 256;
- arg->expanded = (const cpp_token **)
- xmalloc (capacity * sizeof (cpp_token *));
+ arg->expanded = xmalloc (capacity * sizeof (cpp_token *));
push_ptoken_context (pfile, NULL, NULL, arg->first, arg->count + 1);
for (;;)
@@ -1059,8 +1001,8 @@ expand_arg (pfile, arg)
if (arg->expanded_count + 1 >= capacity)
{
capacity *= 2;
- arg->expanded = (const cpp_token **)
- xrealloc (arg->expanded, capacity * sizeof (cpp_token *));
+ arg->expanded = xrealloc (arg->expanded,
+ capacity * sizeof (cpp_token *));
}
token = cpp_get_token (pfile);
@@ -1080,8 +1022,7 @@ expand_arg (pfile, arg)
context represented a macro's replacement list. The context
structure is not freed so that we can re-use it later. */
void
-_cpp_pop_context (pfile)
- cpp_reader *pfile;
+_cpp_pop_context (cpp_reader *pfile)
{
cpp_context *context = pfile->context;
@@ -1094,9 +1035,9 @@ _cpp_pop_context (pfile)
pfile->context = context->prev;
}
-/* Eternal routine to get a token. Also used nearly everywhere
+/* External routine to get a token. Also used nearly everywhere
internally, except for places where we know we can safely call
- the lexer directly, such as lexing a directive name.
+ _cpp_lex_token directly, such as lexing a directive name.
Macro expansions and directives are transparently handled,
including entering included files. Thus tokens are post-macro
@@ -1106,8 +1047,7 @@ _cpp_pop_context (pfile)
state.in_directive is still 1, and at the end of argument
pre-expansion. */
const cpp_token *
-cpp_get_token (pfile)
- cpp_reader *pfile;
+cpp_get_token (cpp_reader *pfile)
{
const cpp_token *result;
@@ -1184,8 +1124,7 @@ cpp_get_token (pfile)
defined in a system header. Just checks the macro at the top of
the stack. Used for diagnostic suppression. */
int
-cpp_sys_macro_p (pfile)
- cpp_reader *pfile;
+cpp_sys_macro_p (cpp_reader *pfile)
{
cpp_hashnode *node = pfile->context->macro;
@@ -1195,8 +1134,7 @@ cpp_sys_macro_p (pfile)
/* Read each token in, until end of the current file. Directives are
transparently processed. */
void
-cpp_scan_nooutput (pfile)
- cpp_reader *pfile;
+cpp_scan_nooutput (cpp_reader *pfile)
{
/* Request a CPP_EOF token at the end of this file, rather than
transparently continuing with the including file. */
@@ -1213,9 +1151,7 @@ cpp_scan_nooutput (pfile)
/* Step back one (or more) tokens. Can only step mack more than 1 if
they are from the lexer, and not from macro expansion. */
void
-_cpp_backup_tokens (pfile, count)
- cpp_reader *pfile;
- unsigned int count;
+_cpp_backup_tokens (cpp_reader *pfile, unsigned int count)
{
if (pfile->context->prev == NULL)
{
@@ -1247,10 +1183,8 @@ _cpp_backup_tokens (pfile, count)
/* Returns nonzero if a macro redefinition warning is required. */
static bool
-warn_of_redefinition (pfile, node, macro2)
- cpp_reader *pfile;
- const cpp_hashnode *node;
- const cpp_macro *macro2;
+warn_of_redefinition (cpp_reader *pfile, const cpp_hashnode *node,
+ const cpp_macro *macro2)
{
const cpp_macro *macro1;
unsigned int i;
@@ -1291,8 +1225,7 @@ warn_of_redefinition (pfile, node, macro2)
/* Free the definition of hashnode H. */
void
-_cpp_free_definition (h)
- cpp_hashnode *h;
+_cpp_free_definition (cpp_hashnode *h)
{
/* Macros and assertions no longer have anything to free. */
h->type = NT_VOID;
@@ -1303,15 +1236,13 @@ _cpp_free_definition (h)
/* Save parameter NODE to the parameter list of macro MACRO. Returns
zero on success, nonzero if the parameter is a duplicate. */
bool
-_cpp_save_parameter (pfile, macro, node)
- cpp_reader *pfile;
- cpp_macro *macro;
- cpp_hashnode *node;
+_cpp_save_parameter (cpp_reader *pfile, cpp_macro *macro, cpp_hashnode *node)
{
+ unsigned int len;
/* Constraint 6.10.3.6 - duplicate parameter names. */
- if (node->arg_index)
+ if (node->flags & NODE_MACRO_ARG)
{
- cpp_error (pfile, DL_ERROR, "duplicate macro parameter \"%s\"",
+ cpp_error (pfile, CPP_DL_ERROR, "duplicate macro parameter \"%s\"",
NODE_NAME (node));
return true;
}
@@ -1321,16 +1252,24 @@ _cpp_save_parameter (pfile, macro, node)
_cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_hashnode *));
((cpp_hashnode **) BUFF_FRONT (pfile->a_buff))[macro->paramc++] = node;
- node->arg_index = macro->paramc;
+ node->flags |= NODE_MACRO_ARG;
+ len = macro->paramc * sizeof (union _cpp_hashnode_value);
+ if (len > pfile->macro_buffer_len)
+ {
+ pfile->macro_buffer = xrealloc (pfile->macro_buffer, len);
+ pfile->macro_buffer_len = len;
+ }
+ ((union _cpp_hashnode_value *) pfile->macro_buffer)[macro->paramc - 1]
+ = node->value;
+
+ node->value.arg_index = macro->paramc;
return false;
}
/* Check the syntax of the parameters in a MACRO definition. Returns
false if an error occurs. */
static bool
-parse_params (pfile, macro)
- cpp_reader *pfile;
- cpp_macro *macro;
+parse_params (cpp_reader *pfile, cpp_macro *macro)
{
unsigned int prev_ident = 0;
@@ -1347,7 +1286,7 @@ parse_params (pfile, macro)
&& ! CPP_OPTION (pfile, discard_comments_in_macro_exp))
continue;
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"\"%s\" may not appear in macro parameter list",
cpp_token_as_text (pfile, token));
return false;
@@ -1355,7 +1294,7 @@ parse_params (pfile, macro)
case CPP_NAME:
if (prev_ident)
{
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"macro parameters must be comma-separated");
return false;
}
@@ -1373,7 +1312,7 @@ parse_params (pfile, macro)
case CPP_COMMA:
if (!prev_ident)
{
- cpp_error (pfile, DL_ERROR, "parameter name missing");
+ cpp_error (pfile, CPP_DL_ERROR, "parameter name missing");
return false;
}
prev_ident = 0;
@@ -1387,11 +1326,11 @@ parse_params (pfile, macro)
pfile->spec_nodes.n__VA_ARGS__);
pfile->state.va_args_ok = 1;
if (! CPP_OPTION (pfile, c99) && CPP_OPTION (pfile, pedantic))
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"anonymous variadic macros were introduced in C99");
}
else if (CPP_OPTION (pfile, pedantic))
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"ISO C does not permit named variadic macros");
/* We're at the end, and just expect a closing parenthesis. */
@@ -1401,7 +1340,7 @@ parse_params (pfile, macro)
/* Fall through. */
case CPP_EOF:
- cpp_error (pfile, DL_ERROR, "missing ')' in macro parameter list");
+ cpp_error (pfile, CPP_DL_ERROR, "missing ')' in macro parameter list");
return false;
}
}
@@ -1409,9 +1348,7 @@ parse_params (pfile, macro)
/* Allocate room for a token from a macro's replacement list. */
static cpp_token *
-alloc_expansion_token (pfile, macro)
- cpp_reader *pfile;
- cpp_macro *macro;
+alloc_expansion_token (cpp_reader *pfile, cpp_macro *macro)
{
if (BUFF_ROOM (pfile->a_buff) < (macro->count + 1) * sizeof (cpp_token))
_cpp_extend_buff (pfile, &pfile->a_buff, sizeof (cpp_token));
@@ -1422,9 +1359,7 @@ alloc_expansion_token (pfile, macro)
/* Lex a token from the expansion of MACRO, but mark parameters as we
find them and warn of traditional stringification. */
static cpp_token *
-lex_expansion_token (pfile, macro)
- cpp_reader *pfile;
- cpp_macro *macro;
+lex_expansion_token (cpp_reader *pfile, cpp_macro *macro)
{
cpp_token *token;
@@ -1432,10 +1367,11 @@ lex_expansion_token (pfile, macro)
token = _cpp_lex_direct (pfile);
/* Is this a parameter? */
- if (token->type == CPP_NAME && token->val.node->arg_index)
+ if (token->type == CPP_NAME
+ && (token->val.node->flags & NODE_MACRO_ARG) != 0)
{
token->type = CPP_MACRO_ARG;
- token->val.arg_no = token->val.node->arg_index;
+ token->val.arg_no = token->val.node->value.arg_index;
}
else if (CPP_WTRADITIONAL (pfile) && macro->paramc > 0
&& (token->type == CPP_STRING || token->type == CPP_CHAR))
@@ -1445,9 +1381,7 @@ lex_expansion_token (pfile, macro)
}
static bool
-create_iso_definition (pfile, macro)
- cpp_reader *pfile;
- cpp_macro *macro;
+create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
{
cpp_token *token;
const cpp_token *ctoken;
@@ -1468,7 +1402,7 @@ create_iso_definition (pfile, macro)
macro->fun_like = 1;
}
else if (ctoken->type != CPP_EOF && !(ctoken->flags & PREV_WHITE))
- cpp_error (pfile, DL_PEDWARN,
+ cpp_error (pfile, CPP_DL_PEDWARN,
"ISO C requires whitespace after the macro name");
if (macro->fun_like)
@@ -1496,7 +1430,7 @@ create_iso_definition (pfile, macro)
/* Let assembler get away with murder. */
else if (CPP_OPTION (pfile, lang) != CLK_ASM)
{
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"'#' is not followed by a macro parameter");
return false;
}
@@ -1515,8 +1449,8 @@ create_iso_definition (pfile, macro)
if (macro->count == 0 || token->type == CPP_EOF)
{
- cpp_error (pfile, DL_ERROR,
- "'##' cannot appear at either end of a macro expansion");
+ cpp_error (pfile, CPP_DL_ERROR,
+ "'##' cannot appear at either end of a macro expansion");
return false;
}
@@ -1543,9 +1477,7 @@ create_iso_definition (pfile, macro)
/* Parse a macro and save its expansion. Returns nonzero on success. */
bool
-_cpp_create_definition (pfile, node)
- cpp_reader *pfile;
- cpp_hashnode *node;
+_cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
{
cpp_macro *macro;
unsigned int i;
@@ -1556,7 +1488,7 @@ _cpp_create_definition (pfile, node)
macro->params = 0;
macro->paramc = 0;
macro->variadic = 0;
- macro->used = 0;
+ macro->used = !CPP_OPTION (pfile, warn_unused_macros);
macro->count = 0;
macro->fun_like = 0;
/* To suppress some diagnostics. */
@@ -1585,7 +1517,11 @@ _cpp_create_definition (pfile, node)
/* Clear the fast argument lookup indices. */
for (i = macro->paramc; i-- > 0; )
- macro->params[i]->arg_index = 0;
+ {
+ struct cpp_hashnode *node = macro->params[i];
+ node->flags &= ~ NODE_MACRO_ARG;
+ node->value = ((union _cpp_hashnode_value *) pfile->macro_buffer)[i];
+ }
if (!ok)
return ok;
@@ -1597,11 +1533,11 @@ _cpp_create_definition (pfile, node)
if (warn_of_redefinition (pfile, node, macro))
{
- cpp_error_with_line (pfile, DL_PEDWARN, pfile->directive_line, 0,
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN, pfile->directive_line, 0,
"\"%s\" redefined", NODE_NAME (node));
if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
- cpp_error_with_line (pfile, DL_PEDWARN,
+ cpp_error_with_line (pfile, CPP_DL_PEDWARN,
node->value.macro->line, 0,
"this is the location of the previous definition");
}
@@ -1622,16 +1558,15 @@ _cpp_create_definition (pfile, node)
/* Warn if a token in STRING matches one of a function-like MACRO's
parameters. */
static void
-check_trad_stringification (pfile, macro, string)
- cpp_reader *pfile;
- const cpp_macro *macro;
- const cpp_string *string;
+check_trad_stringification (cpp_reader *pfile, const cpp_macro *macro,
+ const cpp_string *string)
{
unsigned int i, len;
- const uchar *p, *q, *limit = string->text + string->len;
+ const uchar *p, *q, *limit;
/* Loop over the string. */
- for (p = string->text; p < limit; p = q)
+ limit = string->text + string->len - 1;
+ for (p = string->text + 1; p < limit; p = q)
{
/* Find the start of an identifier. */
while (p < limit && !is_idstart (*p))
@@ -1653,7 +1588,7 @@ check_trad_stringification (pfile, macro, string)
if (NODE_LEN (node) == len
&& !memcmp (p, NODE_NAME (node), len))
{
- cpp_error (pfile, DL_WARNING,
+ cpp_error (pfile, CPP_DL_WARNING,
"macro argument \"%s\" would be stringified in traditional C",
NODE_NAME (node));
break;
@@ -1668,9 +1603,7 @@ check_trad_stringification (pfile, macro, string)
Caller is expected to generate the "#define" bit if needed. The
returned text is temporary, and automatically freed later. */
const unsigned char *
-cpp_macro_definition (pfile, node)
- cpp_reader *pfile;
- const cpp_hashnode *node;
+cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
{
unsigned int i, len;
const cpp_macro *macro = node->value.macro;
@@ -1678,7 +1611,7 @@ cpp_macro_definition (pfile, node)
if (node->type != NT_MACRO || (node->flags & NODE_BUILTIN))
{
- cpp_error (pfile, DL_ICE,
+ cpp_error (pfile, CPP_DL_ICE,
"invalid hash type %d in cpp_macro_definition", node->type);
return 0;
}
@@ -1704,7 +1637,7 @@ cpp_macro_definition (pfile, node)
if (token->type == CPP_MACRO_ARG)
len += NODE_LEN (macro->params[token->val.arg_no - 1]);
else
- len += cpp_token_len (token); /* Includes room for ' '. */
+ len += cpp_token_len (token) + 1; /* Includes room for ' '. */
if (token->flags & STRINGIFY_ARG)
len++; /* "#" */
if (token->flags & PASTE_LEFT)
@@ -1714,7 +1647,7 @@ cpp_macro_definition (pfile, node)
if (len > pfile->macro_buffer_len)
{
- pfile->macro_buffer = (uchar *) xrealloc (pfile->macro_buffer, len);
+ pfile->macro_buffer = xrealloc (pfile->macro_buffer, len);
pfile->macro_buffer_len = len;
}
diff --git a/contrib/gcc/cpppch.c b/contrib/gcc/cpppch.c
new file mode 100644
index 000000000000..872908de0bd5
--- /dev/null
+++ b/contrib/gcc/cpppch.c
@@ -0,0 +1,717 @@
+/* Part of CPP library. (Precompiled header reading/writing.)
+ Copyright (C) 2000, 2001, 2002 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 2, 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, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "cpphash.h"
+#include "intl.h"
+#include "hashtab.h"
+#include "mkdeps.h"
+
+static int write_macdef (cpp_reader *, cpp_hashnode *, void *);
+static int save_idents (cpp_reader *, cpp_hashnode *, void *);
+static hashval_t hashmem (const void *, size_t);
+static hashval_t cpp_string_hash (const void *);
+static int cpp_string_eq (const void *, const void *);
+static int count_defs (cpp_reader *, cpp_hashnode *, void *);
+static int comp_hashnodes (const void *, const void *);
+static int collect_ht_nodes (cpp_reader *, cpp_hashnode *, void *);
+static int write_defs (cpp_reader *, cpp_hashnode *, void *);
+static int save_macros (cpp_reader *, cpp_hashnode *, void *);
+
+/* This structure represents a macro definition on disk. */
+struct macrodef_struct
+{
+ unsigned int definition_length;
+ unsigned short name_length;
+ unsigned short flags;
+};
+
+/* This is how we write out a macro definition.
+ Suitable for being called by cpp_forall_identifiers. */
+
+static int
+write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p)
+{
+ FILE *f = (FILE *) file_p;
+ switch (hn->type)
+ {
+ case NT_VOID:
+ if (! (hn->flags & NODE_POISONED))
+ return 1;
+
+ case NT_MACRO:
+ if ((hn->flags & NODE_BUILTIN))
+ return 1;
+
+ {
+ struct macrodef_struct s;
+ const unsigned char *defn;
+
+ s.name_length = NODE_LEN (hn);
+ s.flags = hn->flags & NODE_POISONED;
+
+ if (hn->type == NT_MACRO)
+ {
+ defn = cpp_macro_definition (pfile, hn);
+ s.definition_length = ustrlen (defn);
+ }
+ else
+ {
+ defn = NODE_NAME (hn);
+ s.definition_length = s.name_length;
+ }
+
+ if (fwrite (&s, sizeof (s), 1, f) != 1
+ || fwrite (defn, 1, s.definition_length, f) != s.definition_length)
+ {
+ cpp_errno (pfile, CPP_DL_ERROR,
+ "while writing precompiled header");
+ return 0;
+ }
+ }
+ return 1;
+
+ case NT_ASSERTION:
+ /* Not currently implemented. */
+ return 1;
+
+ default:
+ abort ();
+ }
+}
+
+/* This structure records the names of the defined macros.
+ It's also used as a callback structure for size_initial_idents
+ and save_idents. */
+
+struct cpp_savedstate
+{
+ /* A hash table of the defined identifiers. */
+ htab_t definedhash;
+ /* The size of the definitions of those identifiers (the size of
+ 'definedstrs'). */
+ size_t hashsize;
+ /* Number of definitions */
+ size_t n_defs;
+ /* Array of definitions. In cpp_write_pch_deps it is used for sorting. */
+ cpp_hashnode **defs;
+ /* Space for the next definition. Definitions are null-terminated
+ strings. */
+ unsigned char *definedstrs;
+};
+
+/* Save this identifier into the state: put it in the hash table,
+ put the definition in 'definedstrs'. */
+
+static int
+save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
+{
+ struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
+
+ if (hn->type != NT_VOID)
+ {
+ struct cpp_string news;
+ void **slot;
+
+ news.len = NODE_LEN (hn);
+ news.text= NODE_NAME (hn);
+ slot = htab_find_slot (ss->definedhash, &news, INSERT);
+ if (*slot == NULL)
+ {
+ struct cpp_string *sp;
+ unsigned char *text;
+
+ sp = xmalloc (sizeof (struct cpp_string));
+ *slot = sp;
+
+ sp->len = NODE_LEN (hn);
+ sp->text = text = xmalloc (NODE_LEN (hn));
+ memcpy (text, NODE_NAME (hn), NODE_LEN (hn));
+ }
+ }
+
+ return 1;
+}
+
+/* Hash some memory in a generic way. */
+
+static hashval_t
+hashmem (const void *p_p, size_t sz)
+{
+ const unsigned char *p = (const unsigned char *)p_p;
+ size_t i;
+ hashval_t h;
+
+ h = 0;
+ for (i = 0; i < sz; i++)
+ h = h * 67 - (*p++ - 113);
+ return h;
+}
+
+/* Hash a cpp string for the hashtable machinery. */
+
+static hashval_t
+cpp_string_hash (const void *a_p)
+{
+ const struct cpp_string *a = (const struct cpp_string *) a_p;
+ return hashmem (a->text, a->len);
+}
+
+/* Compare two cpp strings for the hashtable machinery. */
+
+static int
+cpp_string_eq (const void *a_p, const void *b_p)
+{
+ const struct cpp_string *a = (const struct cpp_string *) a_p;
+ const struct cpp_string *b = (const struct cpp_string *) b_p;
+ return (a->len == b->len
+ && memcmp (a->text, b->text, a->len) == 0);
+}
+
+/* Save the current definitions of the cpp_reader for dependency
+ checking purposes. When writing a precompiled header, this should
+ be called at the same point in the compilation as cpp_valid_state
+ would be called when reading the precompiled header back in. */
+
+int
+cpp_save_state (cpp_reader *r, FILE *f)
+{
+ /* Save the list of non-void identifiers for the dependency checking. */
+ r->savedstate = xmalloc (sizeof (struct cpp_savedstate));
+ r->savedstate->definedhash = htab_create (100, cpp_string_hash,
+ cpp_string_eq, NULL);
+ cpp_forall_identifiers (r, save_idents, r->savedstate);
+
+ /* Write out the list of defined identifiers. */
+ cpp_forall_identifiers (r, write_macdef, f);
+
+ return 0;
+}
+
+/* Calculate the 'hashsize' field of the saved state. */
+
+static int
+count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
+{
+ struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
+
+ switch (hn->type)
+ {
+ case NT_MACRO:
+ if (hn->flags & NODE_BUILTIN)
+ return 1;
+
+ /* else fall through. */
+
+ case NT_VOID:
+ {
+ struct cpp_string news;
+ void **slot;
+
+ news.len = NODE_LEN (hn);
+ news.text = NODE_NAME (hn);
+ slot = htab_find (ss->definedhash, &news);
+ if (slot == NULL)
+ {
+ ss->hashsize += NODE_LEN (hn) + 1;
+ ss->n_defs += 1;
+ }
+ }
+ return 1;
+
+ case NT_ASSERTION:
+ /* Not currently implemented. */
+ return 1;
+
+ default:
+ abort ();
+ }
+}
+
+/* Collect the identifiers into the state's string table. */
+static int
+write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
+{
+ struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
+
+ switch (hn->type)
+ {
+ case NT_MACRO:
+ if (hn->flags & NODE_BUILTIN)
+ return 1;
+
+ /* else fall through. */
+
+ case NT_VOID:
+ {
+ struct cpp_string news;
+ void **slot;
+
+ news.len = NODE_LEN (hn);
+ news.text = NODE_NAME (hn);
+ slot = htab_find (ss->definedhash, &news);
+ if (slot == NULL)
+ {
+ ss->defs[ss->n_defs] = hn;
+ ss->n_defs += 1;
+ }
+ }
+ return 1;
+
+ case NT_ASSERTION:
+ /* Not currently implemented. */
+ return 1;
+
+ default:
+ abort ();
+ }
+}
+
+/* Comparison function for qsort. The arguments point to pointers of
+ type ht_hashnode *. */
+static int
+comp_hashnodes (const void *px, const void *py)
+{
+ cpp_hashnode *x = *(cpp_hashnode **) px;
+ cpp_hashnode *y = *(cpp_hashnode **) py;
+ return ustrcmp (NODE_NAME (x), NODE_NAME (y));
+}
+
+/* Write out the remainder of the dependency information. This should be
+ called after the PCH is ready to be saved. */
+
+int
+cpp_write_pch_deps (cpp_reader *r, FILE *f)
+{
+ struct macrodef_struct z;
+ struct cpp_savedstate *const ss = r->savedstate;
+ unsigned char *definedstrs;
+ size_t i;
+
+ /* Collect the list of identifiers which have been seen and
+ weren't defined to anything previously. */
+ ss->hashsize = 0;
+ ss->n_defs = 0;
+ cpp_forall_identifiers (r, count_defs, ss);
+
+ ss->defs = xmalloc (ss->n_defs * sizeof (cpp_hashnode *));
+ ss->n_defs = 0;
+ cpp_forall_identifiers (r, write_defs, ss);
+
+ /* Sort the list, copy it into a buffer, and write it out. */
+ qsort (ss->defs, ss->n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);
+ definedstrs = ss->definedstrs = xmalloc (ss->hashsize);
+ for (i = 0; i < ss->n_defs; ++i)
+ {
+ size_t len = NODE_LEN (ss->defs[i]);
+ memcpy (definedstrs, NODE_NAME (ss->defs[i]), len + 1);
+ definedstrs += len + 1;
+ }
+
+ memset (&z, 0, sizeof (z));
+ z.definition_length = ss->hashsize;
+ if (fwrite (&z, sizeof (z), 1, f) != 1
+ || fwrite (ss->definedstrs, ss->hashsize, 1, f) != 1)
+ {
+ cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
+ return -1;
+ }
+ free (ss->definedstrs);
+
+ /* Free the saved state. */
+ free (ss);
+ r->savedstate = NULL;
+ return 0;
+}
+
+/* Write out the definitions of the preprocessor, in a form suitable for
+ cpp_read_state. */
+
+int
+cpp_write_pch_state (cpp_reader *r, FILE *f)
+{
+ struct macrodef_struct z;
+
+ /* Write out the list of defined identifiers. */
+ cpp_forall_identifiers (r, write_macdef, f);
+ memset (&z, 0, sizeof (z));
+ if (fwrite (&z, sizeof (z), 1, f) != 1)
+ {
+ cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
+ return -1;
+ }
+
+ if (!r->deps)
+ r->deps = deps_init ();
+
+ if (deps_save (r->deps, f) != 0)
+ {
+ cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/* Data structure to transform hash table nodes into a sorted list */
+
+struct ht_node_list
+{
+ /* Array of nodes */
+ cpp_hashnode **defs;
+ /* Number of nodes in the array */
+ size_t n_defs;
+ /* Size of the allocated array */
+ size_t asize;
+};
+
+/* Callback for collecting identifiers from hash table */
+
+static int
+collect_ht_nodes (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn,
+ void *nl_p)
+{
+ struct ht_node_list *const nl = (struct ht_node_list *)nl_p;
+
+ if (hn->type != NT_VOID || hn->flags & NODE_POISONED)
+ {
+ if (nl->n_defs == nl->asize)
+ {
+ nl->asize *= 2;
+ nl->defs = xrealloc (nl->defs, nl->asize * sizeof (cpp_hashnode *));
+ }
+
+ nl->defs[nl->n_defs] = hn;
+ ++nl->n_defs;
+ }
+ return 1;
+}
+
+
+/* Return nonzero if FD is a precompiled header which is consistent
+ with the preprocessor's current definitions. It will be consistent
+ when:
+
+ - anything that was defined just before the PCH was generated
+ is defined the same way now; and
+ - anything that was not defined then, but is defined now, was not
+ used by the PCH.
+
+ NAME is used to print warnings if `warn_invalid_pch' is set in the
+ reader's flags.
+*/
+
+int
+cpp_valid_state (cpp_reader *r, const char *name, int fd)
+{
+ struct macrodef_struct m;
+ size_t namebufsz = 256;
+ unsigned char *namebuf = xmalloc (namebufsz);
+ unsigned char *undeftab = NULL;
+ struct ht_node_list nl = { 0, 0, 0 };
+ unsigned char *first, *last;
+ unsigned int i;
+
+ /* Read in the list of identifiers that must be defined
+ Check that they are defined in the same way. */
+ for (;;)
+ {
+ cpp_hashnode *h;
+ const unsigned char *newdefn;
+
+ if (read (fd, &m, sizeof (m)) != sizeof (m))
+ goto error;
+
+ if (m.name_length == 0)
+ break;
+
+ if (m.definition_length > namebufsz)
+ {
+ free (namebuf);
+ namebufsz = m.definition_length + 256;
+ namebuf = xmalloc (namebufsz);
+ }
+
+ if ((size_t)read (fd, namebuf, m.definition_length)
+ != m.definition_length)
+ goto error;
+
+ h = cpp_lookup (r, namebuf, m.name_length);
+ if (m.flags & NODE_POISONED
+ || h->type != NT_MACRO
+ || h->flags & NODE_POISONED)
+ {
+ if (CPP_OPTION (r, warn_invalid_pch))
+ cpp_error (r, CPP_DL_WARNING_SYSHDR,
+ "%s: not used because `%.*s' not defined",
+ name, m.name_length, namebuf);
+ goto fail;
+ }
+
+ newdefn = cpp_macro_definition (r, h);
+
+ if (m.definition_length != ustrlen (newdefn)
+ || memcmp (namebuf, newdefn, m.definition_length) != 0)
+ {
+ if (CPP_OPTION (r, warn_invalid_pch))
+ cpp_error (r, CPP_DL_WARNING_SYSHDR,
+ "%s: not used because `%.*s' defined as `%s' not `%.*s'",
+ name, m.name_length, namebuf, newdefn + m.name_length,
+ m.definition_length - m.name_length,
+ namebuf + m.name_length);
+ goto fail;
+ }
+ }
+ free (namebuf);
+ namebuf = NULL;
+
+ /* Read in the list of identifiers that must not be defined.
+ Check that they really aren't. */
+ undeftab = xmalloc (m.definition_length);
+ if ((size_t) read (fd, undeftab, m.definition_length) != m.definition_length)
+ goto error;
+
+ /* Collect identifiers from the current hash table. */
+ nl.n_defs = 0;
+ nl.asize = 10;
+ nl.defs = xmalloc (nl.asize * sizeof (cpp_hashnode *));
+ cpp_forall_identifiers (r, &collect_ht_nodes, &nl);
+ qsort (nl.defs, nl.n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);
+
+ /* Loop through nl.defs and undeftab, both of which are sorted lists.
+ There should be no matches. */
+ first = undeftab;
+ last = undeftab + m.definition_length;
+ i = 0;
+
+ while (first < last && i < nl.n_defs)
+ {
+ int cmp = ustrcmp (first, NODE_NAME (nl.defs[i]));
+
+ if (cmp < 0)
+ first += ustrlen (first) + 1;
+ else if (cmp > 0)
+ ++i;
+ else
+ {
+ if (CPP_OPTION (r, warn_invalid_pch))
+ cpp_error (r, CPP_DL_WARNING_SYSHDR,
+ "%s: not used because `%s' is defined",
+ name, first);
+ goto fail;
+ }
+ }
+
+ free(nl.defs);
+ free (undeftab);
+
+ /* We win! */
+ return 0;
+
+ error:
+ cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header");
+ return -1;
+
+ fail:
+ if (namebuf != NULL)
+ free (namebuf);
+ if (undeftab != NULL)
+ free (undeftab);
+ if (nl.defs != NULL)
+ free (nl.defs);
+ return 1;
+}
+
+/* Save all the existing macros and assertions.
+ This code assumes that there might be hundreds, but not thousands of
+ existing definitions. */
+
+struct save_macro_item {
+ struct save_macro_item *next;
+ struct cpp_hashnode macs[64];
+};
+
+struct save_macro_data
+{
+ struct save_macro_item *macros;
+ size_t count;
+ char **saved_pragmas;
+};
+
+/* Save the definition of a single macro, so that it will persist across
+ a PCH restore. */
+
+static int
+save_macros (cpp_reader *r ATTRIBUTE_UNUSED, cpp_hashnode *h, void *data_p)
+{
+ struct save_macro_data *data = (struct save_macro_data *)data_p;
+ if (h->type != NT_VOID
+ && (h->flags & NODE_BUILTIN) == 0)
+ {
+ cpp_hashnode *save;
+ if (data->count == ARRAY_SIZE (data->macros->macs))
+ {
+ struct save_macro_item *d = data->macros;
+ data->macros = xmalloc (sizeof (struct save_macro_item));
+ data->macros->next = d;
+ data->count = 0;
+ }
+ save = data->macros->macs + data->count;
+ data->count++;
+ memcpy (save, h, sizeof (struct cpp_hashnode));
+ HT_STR (&save->ident) = xmemdup (HT_STR (HT_NODE (save)),
+ HT_LEN (HT_NODE (save)),
+ HT_LEN (HT_NODE (save)) + 1);
+ }
+ return 1;
+}
+
+/* Prepare to restore the state, by saving the currently-defined
+ macros in 'data'. */
+
+void
+cpp_prepare_state (cpp_reader *r, struct save_macro_data **data)
+{
+ struct save_macro_data *d = xmalloc (sizeof (struct save_macro_data));
+
+ d->macros = NULL;
+ d->count = ARRAY_SIZE (d->macros->macs);
+ cpp_forall_identifiers (r, save_macros, d);
+ d->saved_pragmas = _cpp_save_pragma_names (r);
+ *data = d;
+}
+
+/* Given a precompiled header that was previously determined to be valid,
+ apply all its definitions (and undefinitions) to the current state.
+ DEPNAME is passed to deps_restore. */
+
+int
+cpp_read_state (cpp_reader *r, const char *name, FILE *f,
+ struct save_macro_data *data)
+{
+ struct macrodef_struct m;
+ size_t defnlen = 256;
+ unsigned char *defn = xmalloc (defnlen);
+ struct lexer_state old_state;
+ struct save_macro_item *d;
+ size_t i, mac_count;
+ int saved_line = r->line;
+
+ /* Restore spec_nodes, which will be full of references to the old
+ hashtable entries and so will now be invalid. */
+ {
+ struct spec_nodes *s = &r->spec_nodes;
+ s->n_defined = cpp_lookup (r, DSC("defined"));
+ s->n_true = cpp_lookup (r, DSC("true"));
+ s->n_false = cpp_lookup (r, DSC("false"));
+ s->n__VA_ARGS__ = cpp_lookup (r, DSC("__VA_ARGS__"));
+ }
+
+ /* Run through the carefully-saved macros, insert them. */
+ d = data->macros;
+ mac_count = data->count;
+ while (d)
+ {
+ struct save_macro_item *nextd;
+ for (i = 0; i < mac_count; i++)
+ {
+ cpp_hashnode *h;
+
+ h = cpp_lookup (r, HT_STR (HT_NODE (&d->macs[i])),
+ HT_LEN (HT_NODE (&d->macs[i])));
+ h->type = d->macs[i].type;
+ h->flags = d->macs[i].flags;
+ h->value = d->macs[i].value;
+ free ((void *)HT_STR (HT_NODE (&d->macs[i])));
+ }
+ nextd = d->next;
+ free (d);
+ d = nextd;
+ mac_count = ARRAY_SIZE (d->macs);
+ }
+
+ _cpp_restore_pragma_names (r, data->saved_pragmas);
+
+ free (data);
+
+ old_state = r->state;
+
+ r->state.in_directive = 1;
+ r->state.prevent_expansion = 1;
+ r->state.angled_headers = 0;
+
+ /* Read in the identifiers that must be defined. */
+ for (;;)
+ {
+ cpp_hashnode *h;
+
+ if (fread (&m, sizeof (m), 1, f) != 1)
+ goto error;
+
+ if (m.name_length == 0)
+ break;
+
+ if (defnlen < m.definition_length + 1)
+ {
+ defnlen = m.definition_length + 256;
+ defn = xrealloc (defn, defnlen);
+ }
+
+ if (fread (defn, 1, m.definition_length, f) != m.definition_length)
+ goto error;
+ defn[m.definition_length] = '\n';
+
+ h = cpp_lookup (r, defn, m.name_length);
+
+ if (h->type == NT_MACRO)
+ _cpp_free_definition (h);
+ if (m.flags & NODE_POISONED)
+ h->flags |= NODE_POISONED | NODE_DIAGNOSTIC;
+ else if (m.name_length != m.definition_length)
+ {
+ if (cpp_push_buffer (r, defn + m.name_length,
+ m.definition_length - m.name_length, true)
+ != NULL)
+ {
+ _cpp_clean_line (r);
+ if (!_cpp_create_definition (r, h))
+ abort ();
+ _cpp_pop_buffer (r);
+ }
+ else
+ abort ();
+ }
+ }
+
+ r->state = old_state;
+ r->line = saved_line;
+ free (defn);
+ defn = NULL;
+
+ if (deps_restore (r->deps, f, CPP_OPTION (r, restore_pch_deps) ? name : NULL)
+ != 0)
+ goto error;
+
+ return 0;
+
+ error:
+ cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header");
+ return -1;
+}
diff --git a/contrib/gcc/cppspec.c b/contrib/gcc/cppspec.c
index d5b49d019a34..f53cff2a5c1a 100644
--- a/contrib/gcc/cppspec.c
+++ b/contrib/gcc/cppspec.c
@@ -20,6 +20,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "gcc.h"
/* The `cpp' executable installed in $(bindir) and $(cpp_install_dir)
@@ -49,10 +51,8 @@ static const char *const known_suffixes[] =
/* Filter argc and argv before processing by the gcc driver proper. */
void
-lang_specific_driver (in_argc, in_argv, in_added_libraries)
- int *in_argc;
- const char *const **in_argv;
- int *in_added_libraries ATTRIBUTE_UNUSED;
+lang_specific_driver (int *in_argc, const char *const **in_argv,
+ int *in_added_libraries ATTRIBUTE_UNUSED)
{
int argc = *in_argc;
const char *const *argv = *in_argv;
@@ -63,9 +63,6 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
/* Do we need to insert -E? */
int need_E = 1;
- /* Do we need to insert -no-gcc? */
- int need_no_gcc = 1;
-
/* Have we seen an input file? */
int seen_input = 0;
@@ -120,8 +117,6 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
}
else if (argv[i][1] == 'x')
need_fixups = 0;
- else if (argv[i][1] == 'g' && !strcmp(&argv[i][2], "cc"))
- need_no_gcc = 0;
else if (WORD_SWITCH_TAKES_ARG (&argv[i][1]))
quote = 1;
}
@@ -170,14 +165,14 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
/* If we don't need to edit the command line, we can bail early. */
- new_argc = argc + need_E + need_no_gcc + read_stdin
+ new_argc = argc + need_E + read_stdin
+ !!o_here + !!lang_c_here + !!lang_S_here;
if (new_argc == argc)
return;
/* One more slot for a terminating null. */
- new_argv = (const char **) xmalloc ((new_argc + 1) * sizeof(char *));
+ new_argv = xmalloc ((new_argc + 1) * sizeof(char *));
new_argv[0] = argv[0];
j = 1;
@@ -185,9 +180,6 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
if (need_E)
new_argv[j++] = "-E";
- if (need_no_gcc)
- new_argv[j++] = "-no-gcc";
-
for (i = 1; i < argc; i++, j++)
{
if (i == lang_c_here)
@@ -209,7 +201,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
}
/* Called before linking. Returns 0 on success and -1 on failure. */
-int lang_specific_pre_link ()
+int lang_specific_pre_link (void)
{
return 0; /* Not used for cpp. */
}
diff --git a/contrib/gcc/cpptrad.c b/contrib/gcc/cpptrad.c
index 5c66659f02b1..6315b1074f51 100644
--- a/contrib/gcc/cpptrad.c
+++ b/contrib/gcc/cpptrad.c
@@ -1,5 +1,5 @@
/* CPP Library - traditional lexical analysis and macro expansion.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 Free Software Foundation, Inc.
Contributed by Neil Booth, May 2002
This program is free software; you can redistribute it and/or modify it
@@ -79,33 +79,24 @@ enum ls {ls_none = 0, /* Normal state. */
/* Lexing TODO: Maybe handle space in escaped newlines. Stop cpplex.c
from recognizing comments and directives during its lexing pass. */
-static const uchar *handle_newline PARAMS ((cpp_reader *, const uchar *));
-static const uchar *skip_escaped_newlines PARAMS ((cpp_reader *,
- const uchar *));
-static const uchar *skip_whitespace PARAMS ((cpp_reader *, const uchar *,
- int));
-static cpp_hashnode *lex_identifier PARAMS ((cpp_reader *, const uchar *));
-static const uchar *copy_comment PARAMS ((cpp_reader *, const uchar *, int));
-static void scan_out_logical_line PARAMS ((cpp_reader *pfile, cpp_macro *));
-static void check_output_buffer PARAMS ((cpp_reader *, size_t));
-static void push_replacement_text PARAMS ((cpp_reader *, cpp_hashnode *));
-static bool scan_parameters PARAMS ((cpp_reader *, cpp_macro *));
-static bool recursive_macro PARAMS ((cpp_reader *, cpp_hashnode *));
-static void save_replacement_text PARAMS ((cpp_reader *, cpp_macro *,
- unsigned int));
-static void maybe_start_funlike PARAMS ((cpp_reader *, cpp_hashnode *,
- const uchar *, struct fun_macro *));
-static void save_argument PARAMS ((struct fun_macro *, size_t));
-static void replace_args_and_push PARAMS ((cpp_reader *, struct fun_macro *));
-static size_t canonicalize_text PARAMS ((uchar *, const uchar *, size_t,
- uchar *));
+static const uchar *skip_whitespace (cpp_reader *, const uchar *, int);
+static cpp_hashnode *lex_identifier (cpp_reader *, const uchar *);
+static const uchar *copy_comment (cpp_reader *, const uchar *, int);
+static void check_output_buffer (cpp_reader *, size_t);
+static void push_replacement_text (cpp_reader *, cpp_hashnode *);
+static bool scan_parameters (cpp_reader *, cpp_macro *);
+static bool recursive_macro (cpp_reader *, cpp_hashnode *);
+static void save_replacement_text (cpp_reader *, cpp_macro *, unsigned int);
+static void maybe_start_funlike (cpp_reader *, cpp_hashnode *, const uchar *,
+ struct fun_macro *);
+static void save_argument (struct fun_macro *, size_t);
+static void replace_args_and_push (cpp_reader *, struct fun_macro *);
+static size_t canonicalize_text (uchar *, const uchar *, size_t, uchar *);
/* Ensures we have N bytes' space in the output buffer, and
reallocates it if not. */
static void
-check_output_buffer (pfile, n)
- cpp_reader *pfile;
- size_t n;
+check_output_buffer (cpp_reader *pfile, size_t n)
{
/* We might need two bytes to terminate an unterminated comment, and
one more to terminate the line with a NUL. */
@@ -116,48 +107,29 @@ check_output_buffer (pfile, n)
size_t size = pfile->out.cur - pfile->out.base;
size_t new_size = (size + n) * 3 / 2;
- pfile->out.base
- = (uchar *) xrealloc (pfile->out.base, new_size);
+ pfile->out.base = xrealloc (pfile->out.base, new_size);
pfile->out.limit = pfile->out.base + new_size;
pfile->out.cur = pfile->out.base + size;
}
}
-/* To be called whenever a newline character is encountered in the
- input file, at CUR. Handles DOS, Mac and Unix ends of line, and
- increments pfile->line.
-
- Returns a pointer the character after the newline sequence. */
-static const uchar *
-handle_newline (pfile, cur)
- cpp_reader *pfile;
- const uchar *cur;
-{
- pfile->line++;
- if (cur[0] + cur[1] == '\r' + '\n')
- cur++;
- return cur + 1;
-}
-
-/* CUR points to any character in the current context, not necessarily
- a backslash. Advances CUR until all escaped newlines are skipped,
- and returns the new position without updating the context.
-
- Warns if a file buffer ends in an escaped newline. */
-static const uchar *
-skip_escaped_newlines (pfile, cur)
- cpp_reader *pfile;
- const uchar *cur;
+/* Skip a C-style block comment in a macro as a result of -CC.
+ Buffer->cur points to the initial asterisk of the comment. */
+static void
+skip_macro_block_comment (cpp_reader *pfile)
{
- const uchar *orig_cur = cur;
+ const uchar *cur = pfile->buffer->cur;
- while (*cur == '\\' && is_vspace (cur[1]))
- cur = handle_newline (pfile, cur + 1);
+ cur++;
+ if (*cur == '/')
+ cur++;
- if (cur != orig_cur && cur == RLIMIT (pfile->context) && pfile->buffer->inc)
- cpp_error (pfile, DL_PEDWARN, "backslash-newline at end of file");
+ /* People like decorating comments with '*', so check for '/'
+ instead for efficiency. */
+ while(! (*cur++ == '/' && cur[-2] == '*') )
+ ;
- return cur;
+ pfile->buffer->cur = cur;
}
/* CUR points to the asterisk introducing a comment in the current
@@ -173,48 +145,22 @@ skip_escaped_newlines (pfile, cur)
Returns a pointer to the first character after the comment in the
input buffer. */
static const uchar *
-copy_comment (pfile, cur, in_define)
- cpp_reader *pfile;
- const uchar *cur;
- int in_define;
+copy_comment (cpp_reader *pfile, const uchar *cur, int in_define)
{
+ bool unterminated, copy = false;
unsigned int from_line = pfile->line;
- const uchar *limit = RLIMIT (pfile->context);
- uchar *out = pfile->out.cur;
-
- do
- {
- unsigned int c = *cur++;
- *out++ = c;
-
- if (c == '/')
- {
- /* An immediate slash does not terminate the comment. */
- if (out[-2] == '*' && out - 2 > pfile->out.cur)
- goto done;
-
- if (*cur == '*' && cur[1] != '/'
- && CPP_OPTION (pfile, warn_comments))
- cpp_error_with_line (pfile, DL_WARNING, pfile->line, 0,
- "\"/*\" within comment");
- }
- else if (is_vspace (c))
- {
- cur = handle_newline (pfile, cur - 1);
- /* Canonicalize newline sequences and skip escaped ones. */
- if (out[-2] == '\\')
- out -= 2;
- else
- out[-1] = '\n';
- }
- }
- while (cur < limit);
+ cpp_buffer *buffer = pfile->buffer;
- cpp_error_with_line (pfile, DL_ERROR, from_line, 0, "unterminated comment");
- *out++ = '*';
- *out++ = '/';
+ buffer->cur = cur;
+ if (pfile->context->prev)
+ unterminated = false, skip_macro_block_comment (pfile);
+ else
+ unterminated = _cpp_skip_block_comment (pfile);
+
+ if (unterminated)
+ cpp_error_with_line (pfile, CPP_DL_ERROR, from_line, 0,
+ "unterminated comment");
- done:
/* Comments in directives become spaces so that tokens are properly
separated when the ISO preprocessor re-lexes the line. The
exception is #define. */
@@ -225,7 +171,7 @@ copy_comment (pfile, cur, in_define)
if (CPP_OPTION (pfile, discard_comments_in_macro_exp))
pfile->out.cur--;
else
- pfile->out.cur = out;
+ copy = true;
}
else
pfile->out.cur[-1] = ' ';
@@ -233,9 +179,21 @@ copy_comment (pfile, cur, in_define)
else if (CPP_OPTION (pfile, discard_comments))
pfile->out.cur--;
else
- pfile->out.cur = out;
+ copy = true;
+
+ if (copy)
+ {
+ size_t len = (size_t) (buffer->cur - cur);
+ memcpy (pfile->out.cur, cur, len);
+ pfile->out.cur += len;
+ if (unterminated)
+ {
+ *pfile->out.cur++ = '*';
+ *pfile->out.cur++ = '/';
+ }
+ }
- return cur;
+ return buffer->cur;
}
/* CUR points to any character in the input buffer. Skips over all
@@ -251,10 +209,7 @@ copy_comment (pfile, cur, in_define)
Returns a pointer to the first character after the whitespace in
the input buffer. */
static const uchar *
-skip_whitespace (pfile, cur, skip_comments)
- cpp_reader *pfile;
- const uchar *cur;
- int skip_comments;
+skip_whitespace (cpp_reader *pfile, const uchar *cur, int skip_comments)
{
uchar *out = pfile->out.cur;
@@ -263,31 +218,18 @@ skip_whitespace (pfile, cur, skip_comments)
unsigned int c = *cur++;
*out++ = c;
- if (is_nvspace (c) && c)
+ if (is_nvspace (c))
continue;
- if (!c && cur - 1 != RLIMIT (pfile->context))
- continue;
-
- if (c == '/' && skip_comments)
- {
- const uchar *tmp = skip_escaped_newlines (pfile, cur);
- if (*tmp == '*')
- {
- pfile->out.cur = out;
- cur = copy_comment (pfile, tmp, false /* in_define */);
- out = pfile->out.cur;
- continue;
- }
- }
-
- out--;
- if (c == '\\' && is_vspace (*cur))
+ if (c == '/' && *cur == '*' && skip_comments)
{
- cur = skip_escaped_newlines (pfile, cur - 1);
+ pfile->out.cur = out;
+ cur = copy_comment (pfile, cur, false /* in_define */);
+ out = pfile->out.cur;
continue;
}
+ out--;
break;
}
@@ -299,21 +241,14 @@ skip_whitespace (pfile, cur, skip_comments)
to point to a valid first character of an identifier. Returns
the hashnode, and updates out.cur. */
static cpp_hashnode *
-lex_identifier (pfile, cur)
- cpp_reader *pfile;
- const uchar *cur;
+lex_identifier (cpp_reader *pfile, const uchar *cur)
{
size_t len;
uchar *out = pfile->out.cur;
cpp_hashnode *result;
do
- {
- do
- *out++ = *cur++;
- while (is_numchar (*cur));
- cur = skip_escaped_newlines (pfile, cur);
- }
+ *out++ = *cur++;
while (is_numchar (*cur));
CUR (pfile->context) = cur;
@@ -328,74 +263,54 @@ lex_identifier (pfile, cur)
starting at START. The true buffer is restored upon calling
restore_buff(). */
void
-_cpp_overlay_buffer (pfile, start, len)
- cpp_reader *pfile;
- const uchar *start;
- size_t len;
+_cpp_overlay_buffer (cpp_reader *pfile, const uchar *start, size_t len)
{
cpp_buffer *buffer = pfile->buffer;
pfile->overlaid_buffer = buffer;
buffer->saved_cur = buffer->cur;
buffer->saved_rlimit = buffer->rlimit;
+ /* Prevent the ISO lexer from scanning a fresh line. */
+ pfile->saved_line = pfile->line--;
+ buffer->need_line = false;
buffer->cur = start;
buffer->rlimit = start + len;
-
- pfile->saved_line = pfile->line;
}
/* Restores a buffer overlaid by _cpp_overlay_buffer(). */
void
-_cpp_remove_overlay (pfile)
- cpp_reader *pfile;
+_cpp_remove_overlay (cpp_reader *pfile)
{
cpp_buffer *buffer = pfile->overlaid_buffer;
buffer->cur = buffer->saved_cur;
buffer->rlimit = buffer->saved_rlimit;
+ buffer->need_line = true;
+ pfile->overlaid_buffer = NULL;
pfile->line = pfile->saved_line;
}
/* Reads a logical line into the output buffer. Returns TRUE if there
is more text left in the buffer. */
bool
-_cpp_read_logical_line_trad (pfile)
- cpp_reader *pfile;
+_cpp_read_logical_line_trad (cpp_reader *pfile)
{
do
{
- if (pfile->buffer->cur == pfile->buffer->rlimit)
- {
- bool stop = true;
-
- /* Don't pop the last buffer. */
- if (pfile->buffer->prev)
- {
- stop = pfile->buffer->return_at_eof;
- _cpp_pop_buffer (pfile);
- }
-
- if (stop)
- return false;
- }
-
- scan_out_logical_line (pfile, NULL);
+ if (pfile->buffer->need_line && !_cpp_get_fresh_line (pfile))
+ return false;
}
- while (pfile->state.skipping);
+ while (!_cpp_scan_out_logical_line (pfile, NULL) || pfile->state.skipping);
- return true;
+ return pfile->buffer != NULL;
}
/* Set up state for finding the opening '(' of a function-like
macro. */
static void
-maybe_start_funlike (pfile, node, start, macro)
- cpp_reader *pfile;
- cpp_hashnode *node;
- const uchar *start;
- struct fun_macro *macro;
+maybe_start_funlike (cpp_reader *pfile, cpp_hashnode *node, const uchar *start, struct fun_macro *macro)
{
unsigned int n = node->value.macro->paramc + 1;
@@ -410,9 +325,7 @@ maybe_start_funlike (pfile, node, start, macro)
/* Save the OFFSET of the start of the next argument to MACRO. */
static void
-save_argument (macro, offset)
- struct fun_macro *macro;
- size_t offset;
+save_argument (struct fun_macro *macro, size_t offset)
{
macro->argc++;
if (macro->argc <= macro->node->value.macro->paramc)
@@ -426,11 +339,10 @@ save_argument (macro, offset)
If MACRO is non-NULL, then we are scanning the replacement list of
MACRO, and we call save_replacement_text() every time we meet an
argument. */
-static void
-scan_out_logical_line (pfile, macro)
- cpp_reader *pfile;
- cpp_macro *macro;
+bool
+_cpp_scan_out_logical_line (cpp_reader *pfile, cpp_macro *macro)
{
+ bool result = true;
cpp_context *context;
const uchar *cur;
uchar *out;
@@ -438,16 +350,19 @@ scan_out_logical_line (pfile, macro)
unsigned int c, paren_depth = 0, quote;
enum ls lex_state = ls_none;
bool header_ok;
+ const uchar *start_of_input_line;
fmacro.buff = NULL;
- start_logical_line:
quote = 0;
header_ok = pfile->state.angled_headers;
CUR (pfile->context) = pfile->buffer->cur;
RLIMIT (pfile->context) = pfile->buffer->rlimit;
pfile->out.cur = pfile->out.base;
pfile->out.first_line = pfile->line;
+ /* start_of_input_line is needed to make sure that directives really,
+ really start at the first character of the line. */
+ start_of_input_line = pfile->buffer->cur;
new_context:
context = pfile->context;
cur = CUR (context);
@@ -456,6 +371,12 @@ scan_out_logical_line (pfile, macro)
for (;;)
{
+ if (!context->prev
+ && cur >= pfile->buffer->notes[pfile->buffer->cur_note].pos)
+ {
+ pfile->buffer->cur = cur;
+ _cpp_process_line_notes (pfile, false);
+ }
c = *cur++;
*out++ = c;
@@ -467,12 +388,10 @@ scan_out_logical_line (pfile, macro)
case '\t':
case '\f':
case '\v':
- continue;
-
case '\0':
- if (cur - 1 != RLIMIT (context))
- continue;
+ continue;
+ case '\n':
/* If this is a macro's expansion, pop it. */
if (context->prev)
{
@@ -481,22 +400,21 @@ scan_out_logical_line (pfile, macro)
goto new_context;
}
- /* Premature end of file. Fake a new line. */
- cur--;
- if (!pfile->buffer->from_stage3)
- cpp_error (pfile, DL_PEDWARN, "no newline at end of file");
+ /* Omit the newline from the output buffer. */
+ pfile->out.cur = out - 1;
+ pfile->buffer->cur = cur;
+ pfile->buffer->need_line = true;
pfile->line++;
- goto done;
- case '\r': case '\n':
- cur = handle_newline (pfile, cur - 1);
if ((lex_state == ls_fun_open || lex_state == ls_fun_close)
- && !pfile->state.in_directive)
+ && !pfile->state.in_directive
+ && _cpp_get_fresh_line (pfile))
{
/* Newlines in arguments become a space, but we don't
clear any in-progress quote. */
if (lex_state == ls_fun_close)
out[-1] = ' ';
+ cur = pfile->buffer->cur;
continue;
}
goto done;
@@ -519,35 +437,20 @@ scan_out_logical_line (pfile, macro)
break;
case '\\':
- if (is_vspace (*cur))
- {
- out--;
- cur = skip_escaped_newlines (pfile, cur - 1);
- continue;
- }
- else
- {
- /* Skip escaped quotes here, it's easier than above, but
- take care to first skip escaped newlines. */
- cur = skip_escaped_newlines (pfile, cur);
- if (*cur == '\\' || *cur == '"' || *cur == '\'')
- *out++ = *cur++;
- }
+ /* Skip escaped quotes here, it's easier than above. */
+ if (*cur == '\\' || *cur == '"' || *cur == '\'')
+ *out++ = *cur++;
break;
case '/':
/* Traditional CPP does not recognize comments within
literals. */
- if (!quote)
+ if (!quote && *cur == '*')
{
- cur = skip_escaped_newlines (pfile, cur);
- if (*cur == '*')
- {
- pfile->out.cur = out;
- cur = copy_comment (pfile, cur, macro != 0);
- out = pfile->out.cur;
- continue;
- }
+ pfile->out.cur = out;
+ cur = copy_comment (pfile, cur, macro != 0);
+ out = pfile->out.cur;
+ continue;
}
break;
@@ -597,12 +500,12 @@ scan_out_logical_line (pfile, macro)
goto new_context;
}
}
- else if (macro && node->arg_index)
+ else if (macro && (node->flags & NODE_MACRO_ARG) != 0)
{
/* Found a parameter in the replacement text of a
#define. Remove its name from the output. */
pfile->out.cur = out_start;
- save_replacement_text (pfile, macro, node->arg_index);
+ save_replacement_text (pfile, macro, node->value.arg_index);
out = pfile->out.base;
}
else if (lex_state == ls_hash)
@@ -682,7 +585,7 @@ scan_out_logical_line (pfile, macro)
break;
case '#':
- if (out - 1 == pfile->out.base
+ if (cur - 1 == start_of_input_line
/* A '#' from a macro doesn't start a directive. */
&& !pfile->context->prev
&& !pfile->state.in_directive)
@@ -697,12 +600,14 @@ scan_out_logical_line (pfile, macro)
cur = skip_whitespace (pfile, cur, true /* skip_comments */);
out = pfile->out.cur;
- if (is_vspace (*cur))
+ if (*cur == '\n')
{
/* Null directive. Ignore it and don't invalidate
the MI optimization. */
- out = pfile->out.base;
- continue;
+ pfile->buffer->need_line = true;
+ pfile->line++;
+ result = false;
+ goto done;
}
else
{
@@ -714,7 +619,7 @@ scan_out_logical_line (pfile, macro)
else if (is_idstart (*cur))
/* Check whether we know this directive, but don't
advance. */
- do_it = lex_identifier (pfile, cur)->directive_index != 0;
+ do_it = lex_identifier (pfile, cur)->is_directive;
if (do_it || CPP_OPTION (pfile, lang) != CLK_ASM)
{
@@ -722,9 +627,8 @@ scan_out_logical_line (pfile, macro)
preprocessor lex the next token. */
pfile->buffer->cur = cur;
_cpp_handle_directive (pfile, false /* indented */);
- /* #include changes pfile->buffer so we need to
- update the limits of the current context. */
- goto start_logical_line;
+ result = false;
+ goto done;
}
}
}
@@ -763,33 +667,34 @@ scan_out_logical_line (pfile, macro)
}
done:
- out[-1] = '\0';
- pfile->buffer->cur = cur;
- pfile->out.cur = out - 1;
if (fmacro.buff)
_cpp_release_buff (pfile, fmacro.buff);
if (lex_state == ls_fun_close)
- cpp_error_with_line (pfile, DL_ERROR, fmacro.line, 0,
+ cpp_error_with_line (pfile, CPP_DL_ERROR, fmacro.line, 0,
"unterminated argument list invoking macro \"%s\"",
NODE_NAME (fmacro.node));
+ return result;
}
/* Push a context holding the replacement text of the macro NODE on
the context stack. NODE is either object-like, or a function-like
macro with no arguments. */
static void
-push_replacement_text (pfile, node)
- cpp_reader *pfile;
- cpp_hashnode *node;
+push_replacement_text (cpp_reader *pfile, cpp_hashnode *node)
{
size_t len;
const uchar *text;
+ uchar *buf;
if (node->flags & NODE_BUILTIN)
{
text = _cpp_builtin_macro_text (pfile, node);
len = ustrlen (text);
+ buf = _cpp_unaligned_alloc (pfile, len + 1);
+ memcpy (buf, text, len);
+ buf[len]='\n';
+ text = buf;
}
else
{
@@ -804,9 +709,7 @@ push_replacement_text (pfile, node)
/* Returns TRUE if traditional macro recursion is detected. */
static bool
-recursive_macro (pfile, node)
- cpp_reader *pfile;
- cpp_hashnode *node;
+recursive_macro (cpp_reader *pfile, cpp_hashnode *node)
{
bool recursing = !!(node->flags & NODE_DISABLED);
@@ -837,7 +740,7 @@ recursive_macro (pfile, node)
}
if (recursing)
- cpp_error (pfile, DL_ERROR,
+ cpp_error (pfile, CPP_DL_ERROR,
"detected recursion whilst expanding macro \"%s\"",
NODE_NAME (node));
@@ -847,8 +750,7 @@ recursive_macro (pfile, node)
/* Return the length of the replacement text of a function-like or
object-like non-builtin macro. */
size_t
-_cpp_replacement_text_len (macro)
- const cpp_macro *macro;
+_cpp_replacement_text_len (const cpp_macro *macro)
{
size_t len;
@@ -878,9 +780,7 @@ _cpp_replacement_text_len (macro)
sufficient size. It is not NUL-terminated. The next character is
returned. */
uchar *
-_cpp_copy_replacement_text (macro, dest)
- const cpp_macro *macro;
- uchar *dest;
+_cpp_copy_replacement_text (const cpp_macro *macro, uchar *dest)
{
if (macro->fun_like && (macro->paramc != 0))
{
@@ -914,9 +814,7 @@ _cpp_copy_replacement_text (macro, dest)
the context stack. NODE is either object-like, or a function-like
macro with no arguments. */
static void
-replace_args_and_push (pfile, fmacro)
- cpp_reader *pfile;
- struct fun_macro *fmacro;
+replace_args_and_push (cpp_reader *pfile, struct fun_macro *fmacro)
{
cpp_macro *macro = fmacro->node->value.macro;
@@ -942,7 +840,7 @@ replace_args_and_push (pfile, fmacro)
exp += BLOCK_LEN (b->text_len);
}
- /* Allocate room for the expansion plus NUL. */
+ /* Allocate room for the expansion plus \n. */
buff = _cpp_get_buff (pfile, len + 1);
/* Copy the expansion and replace arguments. */
@@ -964,8 +862,8 @@ replace_args_and_push (pfile, fmacro)
exp += BLOCK_LEN (b->text_len);
}
- /* NUL-terminate. */
- *p = '\0';
+ /* \n-terminate. */
+ *p = '\n';
_cpp_push_text_context (pfile, fmacro->node, BUFF_FRONT (buff), len);
/* So we free buffer allocation when macro is left. */
@@ -980,9 +878,7 @@ replace_args_and_push (pfile, fmacro)
duplicate parameter). On success, CUR (pfile->context) is just
past the closing parenthesis. */
static bool
-scan_parameters (pfile, macro)
- cpp_reader *pfile;
- cpp_macro *macro;
+scan_parameters (cpp_reader *pfile, cpp_macro *macro)
{
const uchar *cur = CUR (pfile->context) + 1;
bool ok;
@@ -1011,6 +907,9 @@ scan_parameters (pfile, macro)
break;
}
+ if (!ok)
+ cpp_error (pfile, CPP_DL_ERROR, "syntax error in macro parameter list");
+
CUR (pfile->context) = cur + (*cur == ')');
return ok;
@@ -1021,10 +920,8 @@ scan_parameters (pfile, macro)
ARG_INDEX, with zero indicating the end of the replacement
text. */
static void
-save_replacement_text (pfile, macro, arg_index)
- cpp_reader *pfile;
- cpp_macro *macro;
- unsigned int arg_index;
+save_replacement_text (cpp_reader *pfile, cpp_macro *macro,
+ unsigned int arg_index)
{
size_t len = pfile->out.cur - pfile->out.base;
uchar *exp;
@@ -1032,10 +929,10 @@ save_replacement_text (pfile, macro, arg_index)
if (macro->paramc == 0)
{
/* Object-like and function-like macros without parameters
- simply store their NUL-terminated replacement text. */
+ simply store their \n-terminated replacement text. */
exp = _cpp_unaligned_alloc (pfile, len + 1);
memcpy (exp, pfile->out.base, len);
- exp[len] = '\0';
+ exp[len] = '\n';
macro->exp.text = exp;
macro->count = len;
}
@@ -1072,9 +969,7 @@ save_replacement_text (pfile, macro, arg_index)
/* Analyze and save the replacement text of a macro. Returns true on
success. */
bool
-_cpp_create_trad_definition (pfile, macro)
- cpp_reader *pfile;
- cpp_macro *macro;
+_cpp_create_trad_definition (cpp_reader *pfile, cpp_macro *macro)
{
const uchar *cur;
uchar *limit;
@@ -1090,14 +985,17 @@ _cpp_create_trad_definition (pfile, macro)
/* Is this a function-like macro? */
if (* CUR (context) == '(')
{
+ bool ok = scan_parameters (pfile, macro);
+
+ /* Remember the params so we can clear NODE_MACRO_ARG flags. */
+ macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
+
/* Setting macro to NULL indicates an error occurred, and
- prevents unnecessary work in scan_out_logical_line. */
- if (!scan_parameters (pfile, macro))
+ prevents unnecessary work in _cpp_scan_out_logical_line. */
+ if (!ok)
macro = NULL;
else
{
- /* Success. Commit the parameter array. */
- macro->params = (cpp_hashnode **) BUFF_FRONT (pfile->a_buff);
BUFF_FRONT (pfile->a_buff) = (uchar *) &macro->params[macro->paramc];
macro->fun_like = 1;
}
@@ -1109,7 +1007,7 @@ _cpp_create_trad_definition (pfile, macro)
CPP_OPTION (pfile, discard_comments_in_macro_exp));
pfile->state.prevent_expansion++;
- scan_out_logical_line (pfile, macro);
+ _cpp_scan_out_logical_line (pfile, macro);
pfile->state.prevent_expansion--;
if (!macro)
@@ -1131,11 +1029,7 @@ _cpp_create_trad_definition (pfile, macro)
quote currently in effect is pointed to by PQUOTE, and is updated
by the function. Returns the number of bytes copied. */
static size_t
-canonicalize_text (dest, src, len, pquote)
- uchar *dest;
- const uchar *src;
- size_t len;
- uchar *pquote;
+canonicalize_text (uchar *dest, const uchar *src, size_t len, uchar *pquote)
{
uchar *orig_dest = dest;
uchar quote = *pquote;
@@ -1169,8 +1063,8 @@ canonicalize_text (dest, src, len, pquote)
/* Returns true if MACRO1 and MACRO2 have expansions different other
than in the form of their whitespace. */
bool
-_cpp_expansions_different_trad (macro1, macro2)
- const cpp_macro *macro1, *macro2;
+_cpp_expansions_different_trad (const cpp_macro *macro1,
+ const cpp_macro *macro2)
{
uchar *p1 = xmalloc (macro1->count + macro2->count);
uchar *p2 = p1 + macro1->count;
diff --git a/contrib/gcc/cppucnid.h b/contrib/gcc/cppucnid.h
new file mode 100644
index 000000000000..1cac7df0a941
--- /dev/null
+++ b/contrib/gcc/cppucnid.h
@@ -0,0 +1,336 @@
+/* Table of UCNs which are valid in identifiers.
+ Copyright (C) 2003 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 2, 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, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Automatically generated from cppucnid.tab, do not edit */
+
+/* This file reproduces the table in ISO/IEC 9899:1999 (C99) Annex
+ D, which is itself a reproduction from ISO/IEC TR 10176:1998, and
+ the similar table from ISO/IEC 14882:1988 (C++98) Annex E, which is
+ a reproduction of ISO/IEC PDTR 10176. Unfortunately these tables
+ are not identical. */
+
+#ifndef CPPUCNID_H
+#define CPPUCNID_H
+
+#define C99 1
+#define CXX 2
+#define DIG 4
+
+struct ucnrange
+{
+ unsigned short lo, hi;
+ unsigned short flags;
+};
+
+static const struct ucnrange ucnranges[] = {
+ { 0x00aa, 0x00aa, C99 }, /* Latin */
+ { 0x00b5, 0x00b5, C99 }, /* Special characters */
+ { 0x00b7, 0x00b7, C99 },
+ { 0x00ba, 0x00ba, C99 }, /* Latin */
+ { 0x00c0, 0x00d6, CXX|C99 },
+ { 0x00d8, 0x00f6, CXX|C99 },
+ { 0x00f8, 0x01f5, CXX|C99 },
+ { 0x01fa, 0x0217, CXX|C99 },
+ { 0x0250, 0x02a8, CXX|C99 },
+ { 0x02b0, 0x02b8, C99 }, /* Special characters */
+ { 0x02bb, 0x02bb, C99 },
+ { 0x02bd, 0x02c1, C99 },
+ { 0x02d0, 0x02d1, C99 },
+ { 0x02e0, 0x02e4, C99 },
+ { 0x037a, 0x037a, C99 },
+ { 0x0384, 0x0384, CXX }, /* Greek */
+ { 0x0386, 0x0386, C99 },
+ { 0x0388, 0x038a, CXX|C99 },
+ { 0x038c, 0x038c, CXX|C99 },
+ { 0x038e, 0x03a1, CXX|C99 },
+ { 0x03a3, 0x03ce, CXX|C99 },
+ { 0x03d0, 0x03d6, CXX|C99 },
+ { 0x03da, 0x03da, CXX|C99 },
+ { 0x03dc, 0x03dc, CXX|C99 },
+ { 0x03de, 0x03de, CXX|C99 },
+ { 0x03e0, 0x03e0, CXX|C99 },
+ { 0x03e2, 0x03f3, CXX|C99 },
+ { 0x0401, 0x040c, CXX|C99 }, /* Cyrillic */
+ { 0x040d, 0x040d, CXX },
+ { 0x040e, 0x040e, C99 },
+ { 0x040f, 0x044f, CXX|C99 },
+ { 0x0451, 0x045c, CXX|C99 },
+ { 0x045e, 0x0481, CXX|C99 },
+ { 0x0490, 0x04c4, CXX|C99 },
+ { 0x04c7, 0x04c8, CXX|C99 },
+ { 0x04cb, 0x04cc, CXX|C99 },
+ { 0x04d0, 0x04eb, CXX|C99 },
+ { 0x04ee, 0x04f5, CXX|C99 },
+ { 0x04f8, 0x04f9, CXX|C99 },
+ { 0x0531, 0x0556, CXX|C99 }, /* Armenian */
+ { 0x0559, 0x0559, C99 }, /* Special characters */
+ { 0x0561, 0x0587, CXX|C99 }, /* Armenian */
+ { 0x05b0, 0x05b9, C99 }, /* Hebrew */
+ { 0x05bb, 0x05bd, C99 },
+ { 0x05bf, 0x05bf, C99 },
+ { 0x05c1, 0x05c2, C99 },
+ { 0x05d0, 0x05ea, CXX|C99 },
+ { 0x05f0, 0x05f2, CXX|C99 },
+ { 0x05f3, 0x05f4, CXX },
+ { 0x0621, 0x063a, CXX|C99 }, /* Arabic */
+ { 0x0640, 0x0652, CXX|C99 },
+ { 0x0660, 0x0669, C99|DIG }, /* Digits */
+ { 0x0670, 0x06b7, CXX|C99 }, /* Arabic */
+ { 0x06ba, 0x06be, CXX|C99 },
+ { 0x06c0, 0x06ce, CXX|C99 },
+ { 0x06d0, 0x06dc, C99 },
+ { 0x06e5, 0x06e7, CXX|C99 },
+ { 0x06e8, 0x06e8, C99 },
+ { 0x06ea, 0x06ed, C99 },
+ { 0x06f0, 0x06f9, C99|DIG }, /* Digits */
+ { 0x0901, 0x0903, C99 }, /* Devanagari */
+ { 0x0905, 0x0939, CXX|C99 },
+ { 0x093d, 0x093d, C99 }, /* Special characters */
+ { 0x093e, 0x094d, C99 }, /* Devanagari */
+ { 0x0950, 0x0952, C99 },
+ { 0x0958, 0x0962, CXX|C99 },
+ { 0x0963, 0x0963, C99 },
+ { 0x0966, 0x096f, C99|DIG }, /* Digits */
+ { 0x0981, 0x0983, C99 }, /* Bengali */
+ { 0x0985, 0x098c, CXX|C99 },
+ { 0x098f, 0x0990, CXX|C99 },
+ { 0x0993, 0x09a8, CXX|C99 },
+ { 0x09aa, 0x09b0, CXX|C99 },
+ { 0x09b2, 0x09b2, CXX|C99 },
+ { 0x09b6, 0x09b9, CXX|C99 },
+ { 0x09be, 0x09c4, C99 },
+ { 0x09c7, 0x09c8, C99 },
+ { 0x09cb, 0x09cd, C99 },
+ { 0x09dc, 0x09dd, CXX|C99 },
+ { 0x09df, 0x09e1, CXX|C99 },
+ { 0x09e2, 0x09e3, C99 },
+ { 0x09e6, 0x09ef, C99|DIG }, /* Digits */
+ { 0x09f0, 0x09f1, CXX|C99 }, /* Bengali */
+ { 0x0a02, 0x0a02, C99 }, /* Gurmukhi */
+ { 0x0a05, 0x0a0a, CXX|C99 },
+ { 0x0a0f, 0x0a10, CXX|C99 },
+ { 0x0a13, 0x0a28, CXX|C99 },
+ { 0x0a2a, 0x0a30, CXX|C99 },
+ { 0x0a32, 0x0a33, CXX|C99 },
+ { 0x0a35, 0x0a36, CXX|C99 },
+ { 0x0a38, 0x0a39, CXX|C99 },
+ { 0x0a3e, 0x0a42, C99 },
+ { 0x0a47, 0x0a48, C99 },
+ { 0x0a4b, 0x0a4d, C99 },
+ { 0x0a59, 0x0a5c, CXX|C99 },
+ { 0x0a5e, 0x0a5e, CXX|C99 },
+ { 0x0a66, 0x0a6f, C99|DIG }, /* Digits */
+ { 0x0a74, 0x0a74, C99 }, /* Gurmukhi */
+ { 0x0a81, 0x0a83, C99 }, /* Gujarati */
+ { 0x0a85, 0x0a8b, CXX|C99 },
+ { 0x0a8d, 0x0a8d, CXX|C99 },
+ { 0x0a8f, 0x0a91, CXX|C99 },
+ { 0x0a93, 0x0aa8, CXX|C99 },
+ { 0x0aaa, 0x0ab0, CXX|C99 },
+ { 0x0ab2, 0x0ab3, CXX|C99 },
+ { 0x0ab5, 0x0ab9, CXX|C99 },
+ { 0x0abd, 0x0ac5, C99 },
+ { 0x0ac7, 0x0ac9, C99 },
+ { 0x0acb, 0x0acd, C99 },
+ { 0x0ad0, 0x0ad0, C99 },
+ { 0x0ae0, 0x0ae0, CXX|C99 },
+ { 0x0ae6, 0x0aef, C99|DIG }, /* Digits */
+ { 0x0b01, 0x0b03, C99 }, /* Oriya */
+ { 0x0b05, 0x0b0c, CXX|C99 },
+ { 0x0b0f, 0x0b10, CXX|C99 },
+ { 0x0b13, 0x0b28, CXX|C99 },
+ { 0x0b2a, 0x0b30, CXX|C99 },
+ { 0x0b32, 0x0b33, CXX|C99 },
+ { 0x0b36, 0x0b39, CXX|C99 },
+ { 0x0b3d, 0x0b3d, C99 }, /* Special characters */
+ { 0x0b3e, 0x0b43, C99 }, /* Oriya */
+ { 0x0b47, 0x0b48, C99 },
+ { 0x0b4b, 0x0b4d, C99 },
+ { 0x0b5c, 0x0b5d, CXX|C99 },
+ { 0x0b5f, 0x0b61, CXX|C99 },
+ { 0x0b66, 0x0b6f, C99|DIG }, /* Digits */
+ { 0x0b82, 0x0b83, C99 }, /* Tamil */
+ { 0x0b85, 0x0b8a, CXX|C99 },
+ { 0x0b8e, 0x0b90, CXX|C99 },
+ { 0x0b92, 0x0b95, CXX|C99 },
+ { 0x0b99, 0x0b9a, CXX|C99 },
+ { 0x0b9c, 0x0b9c, CXX|C99 },
+ { 0x0b9e, 0x0b9f, CXX|C99 },
+ { 0x0ba3, 0x0ba4, CXX|C99 },
+ { 0x0ba8, 0x0baa, CXX|C99 },
+ { 0x0bae, 0x0bb5, CXX|C99 },
+ { 0x0bb7, 0x0bb9, CXX|C99 },
+ { 0x0bbe, 0x0bc2, C99 },
+ { 0x0bc6, 0x0bc8, C99 },
+ { 0x0bca, 0x0bcd, C99 },
+ { 0x0be7, 0x0bef, C99|DIG }, /* Digits */
+ { 0x0c01, 0x0c03, C99 }, /* Telugu */
+ { 0x0c05, 0x0c0c, CXX|C99 },
+ { 0x0c0e, 0x0c10, CXX|C99 },
+ { 0x0c12, 0x0c28, CXX|C99 },
+ { 0x0c2a, 0x0c33, CXX|C99 },
+ { 0x0c35, 0x0c39, CXX|C99 },
+ { 0x0c3e, 0x0c44, C99 },
+ { 0x0c46, 0x0c48, C99 },
+ { 0x0c4a, 0x0c4d, C99 },
+ { 0x0c60, 0x0c61, CXX|C99 },
+ { 0x0c66, 0x0c6f, C99|DIG }, /* Digits */
+ { 0x0c82, 0x0c83, C99 }, /* Kannada */
+ { 0x0c85, 0x0c8c, CXX|C99 },
+ { 0x0c8e, 0x0c90, CXX|C99 },
+ { 0x0c92, 0x0ca8, CXX|C99 },
+ { 0x0caa, 0x0cb3, CXX|C99 },
+ { 0x0cb5, 0x0cb9, CXX|C99 },
+ { 0x0cbe, 0x0cc4, C99 },
+ { 0x0cc6, 0x0cc8, C99 },
+ { 0x0cca, 0x0ccd, C99 },
+ { 0x0cde, 0x0cde, C99 },
+ { 0x0ce0, 0x0ce1, CXX|C99 },
+ { 0x0ce6, 0x0cef, C99|DIG }, /* Digits */
+ { 0x0d02, 0x0d03, C99 }, /* Malayalam */
+ { 0x0d05, 0x0d0c, CXX|C99 },
+ { 0x0d0e, 0x0d10, CXX|C99 },
+ { 0x0d12, 0x0d28, CXX|C99 },
+ { 0x0d2a, 0x0d39, CXX|C99 },
+ { 0x0d3e, 0x0d43, C99 },
+ { 0x0d46, 0x0d48, C99 },
+ { 0x0d4a, 0x0d4d, C99 },
+ { 0x0d60, 0x0d61, CXX|C99 },
+ { 0x0d66, 0x0d6f, C99|DIG }, /* Digits */
+ { 0x0e01, 0x0e30, CXX|C99 }, /* Thai */
+ { 0x0e31, 0x0e31, C99 },
+ { 0x0e32, 0x0e33, CXX|C99 },
+ { 0x0e34, 0x0e3a, C99 },
+ { 0x0e40, 0x0e46, CXX|C99 },
+ { 0x0e47, 0x0e49, C99 },
+ { 0x0e50, 0x0e59, CXX|C99|DIG }, /* Digits */
+ { 0x0e5a, 0x0e5b, CXX|C99 }, /* Thai */
+ { 0x0e81, 0x0e82, CXX|C99 }, /* Lao */
+ { 0x0e84, 0x0e84, CXX|C99 },
+ { 0x0e87, 0x0e88, CXX|C99 },
+ { 0x0e8a, 0x0e8a, CXX|C99 },
+ { 0x0e8d, 0x0e8d, CXX|C99 },
+ { 0x0e94, 0x0e97, CXX|C99 },
+ { 0x0e99, 0x0e9f, CXX|C99 },
+ { 0x0ea1, 0x0ea3, CXX|C99 },
+ { 0x0ea5, 0x0ea5, CXX|C99 },
+ { 0x0ea7, 0x0ea7, CXX|C99 },
+ { 0x0eaa, 0x0eab, CXX|C99 },
+ { 0x0ead, 0x0eae, CXX|C99 },
+ { 0x0eaf, 0x0eaf, CXX },
+ { 0x0eb0, 0x0eb0, CXX|C99 },
+ { 0x0eb1, 0x0eb1, C99 },
+ { 0x0eb2, 0x0eb3, CXX|C99 },
+ { 0x0eb4, 0x0eb9, C99 },
+ { 0x0ebb, 0x0ebc, C99 },
+ { 0x0ebd, 0x0ebd, CXX|C99 },
+ { 0x0ec0, 0x0ec4, CXX|C99 },
+ { 0x0ec6, 0x0ec6, CXX|C99 },
+ { 0x0ec8, 0x0ecd, C99 },
+ { 0x0ed0, 0x0ed9, C99|DIG }, /* Digits */
+ { 0x0edc, 0x0edd, C99 }, /* Lao */
+ { 0x0f00, 0x0f00, C99 }, /* Tibetan */
+ { 0x0f18, 0x0f19, C99 },
+ { 0x0f20, 0x0f33, C99|DIG }, /* Digits */
+ { 0x0f35, 0x0f35, C99 }, /* Tibetan */
+ { 0x0f37, 0x0f37, C99 },
+ { 0x0f39, 0x0f39, C99 },
+ { 0x0f3e, 0x0f47, C99 },
+ { 0x0f49, 0x0f69, C99 },
+ { 0x0f71, 0x0f84, C99 },
+ { 0x0f86, 0x0f8b, C99 },
+ { 0x0f90, 0x0f95, C99 },
+ { 0x0f97, 0x0f97, C99 },
+ { 0x0f99, 0x0fad, C99 },
+ { 0x0fb1, 0x0fb7, C99 },
+ { 0x0fb9, 0x0fb9, C99 },
+ { 0x10a0, 0x10c5, CXX|C99 }, /* Georgian */
+ { 0x10d0, 0x10f6, CXX|C99 },
+ { 0x1100, 0x1159, CXX }, /* Hangul */
+ { 0x1161, 0x11a2, CXX },
+ { 0x11a8, 0x11f9, CXX },
+ { 0x1e00, 0x1e9a, CXX|C99 }, /* Latin */
+ { 0x1e9b, 0x1e9b, C99 },
+ { 0x1ea0, 0x1ef9, CXX|C99 },
+ { 0x1f00, 0x1f15, CXX|C99 }, /* Greek */
+ { 0x1f18, 0x1f1d, CXX|C99 },
+ { 0x1f20, 0x1f45, CXX|C99 },
+ { 0x1f48, 0x1f4d, CXX|C99 },
+ { 0x1f50, 0x1f57, CXX|C99 },
+ { 0x1f59, 0x1f59, CXX|C99 },
+ { 0x1f5b, 0x1f5b, CXX|C99 },
+ { 0x1f5d, 0x1f5d, CXX|C99 },
+ { 0x1f5f, 0x1f7d, CXX|C99 },
+ { 0x1f80, 0x1fb4, CXX|C99 },
+ { 0x1fb6, 0x1fbc, CXX|C99 },
+ { 0x1fbe, 0x1fbe, C99 }, /* Special characters */
+ { 0x1fc2, 0x1fc4, CXX|C99 }, /* Greek */
+ { 0x1fc6, 0x1fcc, CXX|C99 },
+ { 0x1fd0, 0x1fd3, CXX|C99 },
+ { 0x1fd6, 0x1fdb, CXX|C99 },
+ { 0x1fe0, 0x1fec, CXX|C99 },
+ { 0x1ff2, 0x1ff4, CXX|C99 },
+ { 0x1ff6, 0x1ffc, CXX|C99 },
+ { 0x203f, 0x2040, C99 }, /* Special characters */
+ { 0x207f, 0x207f, C99 }, /* Latin */
+ { 0x2102, 0x2102, C99 }, /* Special characters */
+ { 0x2107, 0x2107, C99 },
+ { 0x210a, 0x2113, C99 },
+ { 0x2115, 0x2115, C99 },
+ { 0x2118, 0x211d, C99 },
+ { 0x2124, 0x2124, C99 },
+ { 0x2126, 0x2126, C99 },
+ { 0x2128, 0x2128, C99 },
+ { 0x212a, 0x2131, C99 },
+ { 0x2133, 0x2138, C99 },
+ { 0x2160, 0x2182, C99 },
+ { 0x3005, 0x3007, C99 },
+ { 0x3021, 0x3029, C99 },
+ { 0x3041, 0x3093, CXX|C99 }, /* Hiragana */
+ { 0x3094, 0x3094, CXX },
+ { 0x309b, 0x309c, CXX|C99 },
+ { 0x309d, 0x309e, CXX },
+ { 0x30a1, 0x30f6, CXX|C99 }, /* Katakana */
+ { 0x30f7, 0x30fa, CXX },
+ { 0x30fb, 0x30fc, CXX|C99 },
+ { 0x30fd, 0x30fe, CXX },
+ { 0x3105, 0x312c, CXX|C99 }, /* Bopomofo */
+ { 0x4e00, 0x9fa5, CXX|C99 }, /* CJK Unified Ideographs */
+ { 0xac00, 0xd7a3, C99 }, /* Hangul */
+ { 0xf900, 0xfa2d, CXX }, /* CJK Unified Ideographs */
+ { 0xfb1f, 0xfb36, CXX },
+ { 0xfb38, 0xfb3c, CXX },
+ { 0xfb3e, 0xfb3e, CXX },
+ { 0xfb40, 0xfb44, CXX },
+ { 0xfb46, 0xfbb1, CXX },
+ { 0xfbd3, 0xfd3f, CXX },
+ { 0xfd50, 0xfd8f, CXX },
+ { 0xfd92, 0xfdc7, CXX },
+ { 0xfdf0, 0xfdfb, CXX },
+ { 0xfe70, 0xfe72, CXX },
+ { 0xfe74, 0xfe74, CXX },
+ { 0xfe76, 0xfefc, CXX },
+ { 0xff21, 0xff3a, CXX },
+ { 0xff41, 0xff5a, CXX },
+ { 0xff66, 0xffbe, CXX },
+ { 0xffc2, 0xffc7, CXX },
+ { 0xffca, 0xffcf, CXX },
+ { 0xffd2, 0xffd7, CXX },
+ { 0xffda, 0xffdc, CXX },
+};
+
+#endif /* cppucnid.h */
diff --git a/contrib/gcc/cppucnid.pl b/contrib/gcc/cppucnid.pl
new file mode 100644
index 000000000000..eb8bbcac627b
--- /dev/null
+++ b/contrib/gcc/cppucnid.pl
@@ -0,0 +1,130 @@
+#! /usr/bin/perl -w
+use strict;
+
+# Convert cppucnid.tab to cppucnid.h. We use two arrays of length
+# 65536 to represent the table, since this is nice and simple. The
+# first array holds the tags indicating which ranges are valid in
+# which contexts. The second array holds the language name associated
+# with each element.
+
+our(@tags, @names);
+@tags = ("") x 65536;
+@names = ("") x 65536;
+
+
+# Array mapping tag numbers to standard #defines
+our @stds;
+
+# Current standard and language
+our($curstd, $curlang);
+
+# First block of the file is a template to be saved for later.
+our @template;
+
+while (<>) {
+ chomp;
+ last if $_ eq '%%';
+ push @template, $_;
+};
+
+# Second block of the file is the UCN tables.
+# The format looks like this:
+#
+# [std]
+#
+# ; language
+# xxxx-xxxx xxxx xxxx-xxxx ....
+#
+# with comment lines starting with #.
+
+while (<>) {
+ chomp;
+ /^#/ and next;
+ /^\s*$/ and next;
+ /^\[(.+)\]$/ and do {
+ $curstd = $1;
+ next;
+ };
+ /^; (.+)$/ and do {
+ $curlang = $1;
+ next;
+ };
+
+ process_range(split);
+}
+
+# Print out the template, inserting as requested.
+$\ = "\n";
+for (@template) {
+ print("/* Automatically generated from cppucnid.tab, do not edit */"),
+ next if $_ eq "[dne]";
+ print_table(), next if $_ eq "[table]";
+ print;
+}
+
+sub print_table {
+ my($lo, $hi);
+ my $prevname = "";
+
+ for ($lo = 0; $lo <= $#tags; $lo = $hi) {
+ $hi = $lo;
+ $hi++ while $hi <= $#tags
+ && $tags[$hi] eq $tags[$lo]
+ && $names[$hi] eq $names[$lo];
+
+ # Range from $lo to $hi-1.
+ # Don't make entries for ranges that are not valid idchars.
+ next if ($tags[$lo] eq "");
+ my $tag = $tags[$lo];
+ $tag = " ".$tag if $tag =~ /^C99/;
+
+ if ($names[$lo] eq $prevname) {
+ printf(" { 0x%04x, 0x%04x, %-11s },\n",
+ $lo, $hi-1, $tag);
+ } else {
+ printf(" { 0x%04x, 0x%04x, %-11s }, /* %s */\n",
+ $lo, $hi-1, $tag, $names[$lo]);
+ }
+ $prevname = $names[$lo];
+ }
+}
+
+# The line is a list of four-digit hexadecimal numbers or
+# pairs of such numbers. Each is a valid identifier character
+# from the given language, under the given standard.
+sub process_range {
+ for my $range (@_) {
+ if ($range =~ /^[0-9a-f]{4}$/) {
+ my $i = hex($range);
+ if ($tags[$i] eq "") {
+ $tags[$i] = $curstd;
+ } else {
+ $tags[$i] = $curstd . "|" . $tags[$i];
+ }
+ if ($names[$i] ne "" && $names[$i] ne $curlang) {
+ warn sprintf ("language overlap: %s/%s at %x (tag %d)",
+ $names[$i], $curlang, $i, $tags[$i]);
+ next;
+ }
+ $names[$i] = $curlang;
+ } elsif ($range =~ /^ ([0-9a-f]{4}) - ([0-9a-f]{4}) $/x) {
+ my ($start, $end) = (hex($1), hex($2));
+ my $i;
+ for ($i = $start; $i <= $end; $i++) {
+ if ($tags[$i] eq "") {
+ $tags[$i] = $curstd;
+ } else {
+ $tags[$i] = $curstd . "|" . $tags[$i];
+ }
+ if ($names[$i] ne "" && $names[$i] ne $curlang) {
+ warn sprintf ("language overlap: %s/%s at %x (tag %d)",
+ $names[$i], $curlang, $i, $tags[$i]);
+ next;
+ }
+ $names[$i] = $curlang;
+ }
+ } else {
+ warn "malformed range expression $range";
+ }
+ }
+}
diff --git a/contrib/gcc/cppucnid.tab b/contrib/gcc/cppucnid.tab
new file mode 100644
index 000000000000..4a7a0f4094cf
--- /dev/null
+++ b/contrib/gcc/cppucnid.tab
@@ -0,0 +1,239 @@
+/* Table of UCNs which are valid in identifiers.
+ Copyright (C) 2003 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 2, 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, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+[dne]
+
+/* This file reproduces the table in ISO/IEC 9899:1999 (C99) Annex
+ D, which is itself a reproduction from ISO/IEC TR 10176:1998, and
+ the similar table from ISO/IEC 14882:1988 (C++98) Annex E, which is
+ a reproduction of ISO/IEC PDTR 10176. Unfortunately these tables
+ are not identical. */
+
+#ifndef CPPUCNID_H
+#define CPPUCNID_H
+
+#define C99 1
+#define CXX 2
+#define DIG 4
+
+struct ucnrange
+{
+ unsigned short lo, hi;
+ unsigned short flags;
+};
+
+static const struct ucnrange ucnranges[] = {
+[table]
+};
+
+#endif /* cppucnid.h */
+%%
+
+[C99]
+
+; Latin
+00aa 00ba 00c0-00d6 00d8-00f6 00f8-01f5 01fa-0217 0250-02a8 1e00-1e9b
+1ea0-1ef9 207f
+
+; Greek
+0386 0388-038a 038c 038e-03a1 03a3-03ce 03d0-03d6 03da 03dc 03de 03e0
+03e2-03f3 1f00-1f15 1f18-1f1d 1f20-1f45 1f48-1f4d 1f50-1f57 1f59 1f5b
+1f5d 1f5f-1f7d 1f80-1fb4 1fb6-1fbc 1fc2-1fc4 1fc6-1fcc 1fd0-1fd3
+1fd6-1fdb 1fe0-1fec 1ff2-1ff4 1ff6-1ffc
+
+; Cyrillic
+0401-040c 040e-044f 0451-045c 045e-0481 0490-04c4 04c7-04c8 04cb-04cc
+04d0-04eb 04ee-04f5 04f8-04f9
+
+; Armenian
+0531-0556 0561-0587
+
+; Hebrew
+05b0-05b9 05bb-05bd 05bf 05c1-05c2 05d0-05ea 05f0-05f2
+
+; Arabic
+0621-063a 0640-0652 0670-06b7 06ba-06be 06c0-06ce 06d0-06dc 06e5-06e8
+06ea-06ed
+
+; Devanagari
+0901-0903 0905-0939 093e-094d 0950-0952 0958-0963
+
+; Bengali
+0981-0983 0985-098c 098f-0990 0993-09a8 09aa-09b0 09b2 09b6-09b9
+09be-09c4 09c7-09c8 09cb-09cd 09dc-09dd 09df-09e3 09f0-09f1
+
+; Gurmukhi
+0a02 0a05-0a0a 0a0f-0a10 0a13-0a28 0a2a-0a30 0a32-0a33 0a35-0a36
+0a38-0a39 0a3e-0a42 0a47-0a48 0a4b-0a4d 0a59-0a5c 0a5e 0a74
+
+; Gujarati
+0a81-0a83 0a85-0a8b 0a8d 0a8f-0a91 0a93-0aa8 0aaa-0ab0 0ab2-0ab3
+0ab5-0ab9 0abd-0ac5 0ac7-0ac9 0acb-0acd 0ad0 0ae0
+
+; Oriya
+0b01-0b03 0b05-0b0c 0b0f-0b10 0b13-0b28 0b2a-0b30 0b32-0b33 0b36-0b39
+0b3e-0b43 0b47-0b48 0b4b-0b4d 0b5c-0b5d 0b5f-0b61
+
+; Tamil
+0b82-0b83 0b85-0b8a 0b8e-0b90 0b92-0b95 0b99-0b9a 0b9c 0b9e-0b9f
+0ba3-0ba4 0ba8-0baa 0bae-0bb5 0bb7-0bb9 0bbe-0bc2 0bc6-0bc8 0bca-0bcd
+
+; Telugu
+0c01-0c03 0c05-0c0c 0c0e-0c10 0c12-0c28 0c2a-0c33 0c35-0c39 0c3e-0c44
+0c46-0c48 0c4a-0c4d 0c60-0c61
+
+; Kannada
+0c82-0c83 0c85-0c8c 0c8e-0c90 0c92-0ca8 0caa-0cb3 0cb5-0cb9 0cbe-0cc4
+0cc6-0cc8 0cca-0ccd 0cde 0ce0-0ce1
+
+; Malayalam
+0d02-0d03 0d05-0d0c 0d0e-0d10 0d12-0d28 0d2a-0d39 0d3e-0d43 0d46-0d48
+0d4a-0d4d 0d60-0d61
+
+# CORRECTION: exclude 0e50-0e59 from the Thai range as it also appears
+# in the Digits range below.
+; Thai
+0e01-0e3a 0e40-0e49 0e5a-0e5b
+
+; Lao
+0e81-0e82 0e84 0e87-0e88 0e8a 0e8d 0e94-0e97 0e99-0e9f 0ea1-0ea3 0ea5
+0ea7 0eaa-0eab 0ead-0eae 0eb0-0eb9 0ebb-0ebd 0ec0-0ec4 0ec6 0ec8-0ecd
+0edc-0edd
+
+; Tibetan
+0f00 0f18-0f19 0f35 0f37 0f39 0f3e-0f47 0f49-0f69 0f71-0f84 0f86-0f8b
+0f90-0f95 0f97 0f99-0fad 0fb1-0fb7 0fb9
+
+; Georgian
+10a0-10c5 10d0-10f6
+
+; Hiragana
+3041-3093 309b-309c
+
+; Katakana
+30a1-30f6 30fb-30fc
+
+; Bopomofo
+3105-312c
+
+; CJK Unified Ideographs
+4e00-9fa5
+
+; Hangul
+ac00-d7a3
+
+; Special characters
+00b5 00b7 02b0-02b8 02bb 02bd-02c1 02d0-02d1 02e0-02e4 037a 0559 093d
+0b3d 1fbe 203f-2040 2102 2107 210a-2113 2115 2118-211d 2124 2126 2128
+212a-2131 2133-2138 2160-2182 3005-3007 3021-3029
+
+[C99|DIG]
+; Digits
+0660-0669 06f0-06f9 0966-096f 09e6-09ef 0a66-0a6f 0ae6-0aef 0b66-0b6f
+0be7-0bef 0c66-0c6f 0ce6-0cef 0d66-0d6f 0e50-0e59 0ed0-0ed9 0f20-0f33
+
+[CXX]
+
+; Latin
+00c0-00d6 00d8-00f6 00f8-01f5 01fa-0217 0250-02a8 1e00-1e9a 1ea0-1ef9
+
+; Greek
+0384 0388-038a 038c 038e-03a1 03a3-03ce 03d0-03d6 03da 03dc 03de 03e0
+03e2-03f3 1f00-1f15 1f18-1f1d 1f20-1f45 1f48-1f4d 1f50-1f57 1f59 1f5b
+1f5d 1f5f-1f7d 1f80-1fb4 1fb6-1fbc 1fc2-1fc4 1fc6-1fcc 1fd0-1fd3
+1fd6-1fdb 1fe0-1fec 1ff2-1ff4 1ff6-1ffc
+
+; Cyrillic
+0401-040d 040f-044f 0451-045c 045e-0481 0490-04c4 04c7-04c8 04cb-04cc
+04d0-04eb 04ee-04f5 04f8-04f9
+
+; Armenian
+0531-0556 0561-0587
+
+; Hebrew
+05d0-05ea 05f0-05f4
+
+; Arabic
+0621-063a 0640-0652 0670-06b7 06ba-06be 06c0-06ce 06e5-06e7
+
+; Devanagari
+0905-0939 0958-0962
+
+; Bengali
+0985-098c 098f-0990 0993-09a8 09aa-09b0 09b2 09b6-09b9 09dc-09dd
+09df-09e1 09f0-09f1
+
+; Gurmukhi
+0a05-0a0a 0a0f-0a10 0a13-0a28 0a2a-0a30 0a32-0a33 0a35-0a36 0a38-0a39
+0a59-0a5c 0a5e
+
+; Gujarati
+0a85-0a8b 0a8d 0a8f-0a91 0a93-0aa8 0aaa-0ab0 0ab2-0ab3 0ab5-0ab9 0ae0
+
+; Oriya
+0b05-0b0c 0b0f-0b10 0b13-0b28 0b2a-0b30 0b32-0b33 0b36-0b39 0b5c-0b5d
+0b5f-0b61
+
+; Tamil
+0b85-0b8a 0b8e-0b90 0b92-0b95 0b99-0b9a 0b9c 0b9e-0b9f 0ba3-0ba4
+0ba8-0baa 0bae-0bb5 0bb7-0bb9
+
+; Telugu
+0c05-0c0c 0c0e-0c10 0c12-0c28 0c2a-0c33 0c35-0c39 0c60-0c61
+
+; Kannada
+0c85-0c8c 0c8e-0c90 0c92-0ca8 0caa-0cb3 0cb5-0cb9 0ce0-0ce1
+
+; Malayalam
+0d05-0d0c 0d0e-0d10 0d12-0d28 0d2a-0d39 0d60-0d61
+
+# CORRECTION: Exclude 0e50-0e59 from the Thai range and make a fake
+# Digits range for it, to match C99. cppcharset.c knows that C++
+# doesn't distinguish digits from other UCNs valid in identifiers.
+; Thai
+0e01-0e30 0e32-0e33 0e40-0e46 0e4f-0e49 0e5a-0e5b
+
+; Digits
+0e50-0e59
+
+# CORRECTION: Change 0e0d to 0e8d (typo in standard; see C++ DR 131)
+; Lao
+0e81-0e82 0e84 0e87-0e88 0e8a 0e8d 0e94-0e97 0e99-0e9f 0ea1-0ea3 0ea5
+0ea7 0eaa-0eab 0ead-0eb0 0eb2 0eb3 0ebd 0ec0-0ec4 0ec6
+
+; Georgian
+10a0-10c5 10d0-10f6
+
+; Hiragana
+3041-3094 309b-309e
+
+; Katakana
+30a1-30fe
+
+# CORRECTION: language spelled "Bopmofo" in C++98.
+; Bopomofo
+3105-312c
+
+; Hangul
+1100-1159 1161-11a2 11a8-11f9
+
+; CJK Unified Ideographs
+f900-fa2d fb1f-fb36 fb38-fb3c fb3e fb40-fb41 fb42-fb44 fb46-fbb1
+fbd3-fd3f fd50-fd8f fd92-fdc7 fdf0-fdfb fe70-fe72 fe74 fe76-fefc
+ff21-ff3a ff41-ff5a ff66-ffbe ffc2-ffc7 ffca-ffcf ffd2-ffd7
+ffda-ffdc 4e00-9fa5
+
diff --git a/contrib/gcc/crtstuff.c b/contrib/gcc/crtstuff.c
index cdc447d248d7..b9a29a0ba607 100644
--- a/contrib/gcc/crtstuff.c
+++ b/contrib/gcc/crtstuff.c
@@ -1,7 +1,7 @@
/* Specialized bits of code needed to support construction and
destruction of file-scope objects in C++ code.
Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com).
This file is part of GCC.
@@ -60,6 +60,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "auto-host.h"
#include "tconfig.h"
#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
#include "unwind-dw2-fde.h"
#ifndef FORCE_CODE_SECTION_ALIGN
@@ -118,15 +120,16 @@ call_ ## FUNC (void) \
/* References to __register_frame_info and __deregister_frame_info should
be weak in this file if at all possible. */
-extern void __register_frame_info (void *, struct object *)
+extern void __register_frame_info (const void *, struct object *)
TARGET_ATTRIBUTE_WEAK;
-extern void __register_frame_info_bases (void *, struct object *,
+extern void __register_frame_info_bases (const void *, struct object *,
void *, void *)
TARGET_ATTRIBUTE_WEAK;
-extern void *__deregister_frame_info (void *)
+extern void *__deregister_frame_info (const void *)
TARGET_ATTRIBUTE_WEAK;
-extern void *__deregister_frame_info_bases (void *)
+extern void *__deregister_frame_info_bases (const void *)
TARGET_ATTRIBUTE_WEAK;
+extern void __do_global_ctors_1 (void);
/* Likewise for _Jv_RegisterClasses. */
extern void _Jv_RegisterClasses (void *) TARGET_ATTRIBUTE_WEAK;
@@ -270,7 +273,7 @@ __do_global_dtors_aux (void)
}
#ifdef USE_EH_FRAME_REGISTRY
-#if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
+#ifdef CRT_GET_RFIB_DATA
/* If we used the new __register_frame_info_bases interface,
make sure that we deregister from the same place. */
if (__deregister_frame_info_bases)
@@ -297,24 +300,16 @@ frame_dummy (void)
{
#ifdef USE_EH_FRAME_REGISTRY
static struct object object;
-#if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA)
+#ifdef CRT_GET_RFIB_DATA
void *tbase, *dbase;
-#ifdef CRT_GET_RFIB_TEXT
- CRT_GET_RFIB_TEXT (tbase);
-#else
tbase = 0;
-#endif
-#ifdef CRT_GET_RFIB_DATA
CRT_GET_RFIB_DATA (dbase);
-#else
- dbase = 0;
-#endif
if (__register_frame_info_bases)
__register_frame_info_bases (__EH_FRAME_BEGIN__, &object, tbase, dbase);
#else
if (__register_frame_info)
__register_frame_info (__EH_FRAME_BEGIN__, &object);
-#endif
+#endif /* CRT_GET_RFIB_DATA */
#endif /* USE_EH_FRAME_REGISTRY */
#ifdef JCR_SECTION_NAME
if (__JCR_LIST__[0] && _Jv_RegisterClasses)
@@ -349,16 +344,6 @@ __do_global_ctors (void)
asm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
-/* On some svr4 systems, the initial .init section preamble code provided in
- crti.o may do something, such as bump the stack, which we have to
- undo before we reach the function prologue code for __do_global_ctors
- (directly below). For such systems, define the macro INIT_SECTION_PREAMBLE
- to expand into the code needed to undo the actions of the crti.o file. */
-
-#ifdef INIT_SECTION_PREAMBLE
- INIT_SECTION_PREAMBLE;
-#endif
-
/* A routine to invoke all of the global constructors upon entry to the
program. We put this into the .init section (for systems that have
such a thing) so that we can properly perform the construction of
@@ -377,6 +362,8 @@ __do_global_ctors_aux (void) /* prologue goes in .init section */
#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
+extern void __do_global_dtors (void);
+
/* This case is used by the Irix 6 port, which supports named sections but
not an SVR4-style .fini section. __do_global_dtors can be non-static
in this case because we protect it with -hidden_symbol. */
@@ -523,10 +510,11 @@ asm (TEXT_SECTION_ASM_OP);
#elif defined(HAS_INIT_SECTION) /* ! INIT_SECTION_ASM_OP */
+extern void __do_global_ctors (void);
+
/* This case is used by the Irix 6 port, which supports named sections but
not an SVR4-style .init section. __do_global_ctors can be non-static
in this case because we protect it with -hidden_symbol. */
-extern void __do_global_ctors_1(void);
void
__do_global_ctors (void)
{
diff --git a/contrib/gcc/cse.c b/contrib/gcc/cse.c
index 9566865debef..50819265946d 100644
--- a/contrib/gcc/cse.c
+++ b/contrib/gcc/cse.c
@@ -1,6 +1,6 @@
/* Common subexpression elimination for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
/* stdio.h must precede rtl.h for FFS. */
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
@@ -38,6 +40,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "output.h"
#include "ggc.h"
#include "timevar.h"
+#include "except.h"
+#include "target.h"
+#include "params.h"
/* The basic idea of common subexpression elimination is to go
through the code, keeping a record of expressions that would
@@ -247,8 +252,10 @@ struct qty_table_elem
rtx comparison_const;
int comparison_qty;
unsigned int first_reg, last_reg;
- enum machine_mode mode;
- enum rtx_code comparison_code;
+ /* The sizes of these fields should match the sizes of the
+ code and mode fields of struct rtx_def (see rtl.h). */
+ ENUM_BITFIELD(rtx_code) comparison_code : 16;
+ ENUM_BITFIELD(machine_mode) mode : 8;
};
/* The table of all qtys, indexed by qty number. */
@@ -266,11 +273,11 @@ static struct qty_table_elem *qty_table;
static rtx prev_insn_cc0;
static enum machine_mode prev_insn_cc0_mode;
-#endif
/* Previous actual insn. 0 if at first insn of basic block. */
static rtx prev_insn;
+#endif
/* Insn being scanned. */
@@ -458,7 +465,9 @@ struct table_elt
struct table_elt *related_value;
int cost;
int regcost;
- enum machine_mode mode;
+ /* The size of this field should match the size
+ of the mode field of struct rtx_def (see rtl.h). */
+ ENUM_BITFIELD(machine_mode) mode : 8;
char in_memory;
char is_const;
char flag;
@@ -494,9 +503,9 @@ struct table_elt
a cost of 2. Aside from these special cases, call `rtx_cost'. */
#define CHEAP_REGNO(N) \
- ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \
- || (N) == STACK_POINTER_REGNUM || (N) == ARG_POINTER_REGNUM \
- || ((N) >= FIRST_VIRTUAL_REGISTER && (N) <= LAST_VIRTUAL_REGISTER) \
+ ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \
+ || (N) == STACK_POINTER_REGNUM || (N) == ARG_POINTER_REGNUM \
+ || ((N) >= FIRST_VIRTUAL_REGISTER && (N) <= LAST_VIRTUAL_REGISTER) \
|| ((N) < FIRST_PSEUDO_REGISTER \
&& FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))
@@ -505,7 +514,7 @@ struct table_elt
/* Get the info associated with register N. */
-#define GET_CSE_REG_INFO(N) \
+#define GET_CSE_REG_INFO(N) \
(((N) == cached_regno && cached_cse_reg_info) \
? cached_cse_reg_info : get_cse_reg_info ((N)))
@@ -560,10 +569,7 @@ static struct table_elt *last_jump_equiv_class;
the insn. */
static int constant_pool_entries_cost;
-
-/* Define maximum length of a branch path. */
-
-#define PATHLENGTH 10
+static int constant_pool_entries_regcost;
/* This data describes a block that will be processed by cse_basic_block. */
@@ -588,125 +594,110 @@ struct cse_basic_block_data
except that it is used when the destination label is not preceded
by a BARRIER. */
enum taken {TAKEN, NOT_TAKEN, AROUND} status;
- } path[PATHLENGTH];
+ } *path;
};
+static bool fixed_base_plus_p (rtx x);
+static int notreg_cost (rtx, enum rtx_code);
+static int approx_reg_cost_1 (rtx *, void *);
+static int approx_reg_cost (rtx);
+static int preferrable (int, int, int, int);
+static void new_basic_block (void);
+static void make_new_qty (unsigned int, enum machine_mode);
+static void make_regs_eqv (unsigned int, unsigned int);
+static void delete_reg_equiv (unsigned int);
+static int mention_regs (rtx);
+static int insert_regs (rtx, struct table_elt *, int);
+static void remove_from_table (struct table_elt *, 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 (rtx, struct table_elt *, unsigned,
+ enum machine_mode);
+static void merge_equiv_classes (struct table_elt *, struct table_elt *);
+static void invalidate (rtx, enum machine_mode);
+static int cse_rtx_varies_p (rtx, int);
+static void remove_invalid_refs (unsigned int);
+static void remove_invalid_subreg_refs (unsigned int, unsigned int,
+ enum machine_mode);
+static void rehash_using_reg (rtx);
+static void invalidate_memory (void);
+static void invalidate_for_call (void);
+static rtx use_related_value (rtx, struct table_elt *);
+static unsigned canon_hash (rtx, enum machine_mode);
+static unsigned canon_hash_string (const char *);
+static unsigned safe_hash (rtx, enum machine_mode);
+static int exp_equiv_p (rtx, rtx, int, int);
+static rtx canon_reg (rtx, rtx);
+static void find_best_addr (rtx, rtx *, enum machine_mode);
+static enum rtx_code find_comparison_args (enum rtx_code, rtx *, rtx *,
+ enum machine_mode *,
+ enum machine_mode *);
+static rtx fold_rtx (rtx, rtx);
+static rtx equiv_constant (rtx);
+static void record_jump_equiv (rtx, int);
+static void record_jump_cond (enum rtx_code, enum machine_mode, rtx, rtx,
+ int);
+static void cse_insn (rtx, rtx);
+static int addr_affects_sp_p (rtx);
+static void invalidate_from_clobbers (rtx);
+static rtx cse_process_notes (rtx, rtx);
+static void cse_around_loop (rtx);
+static void invalidate_skipped_set (rtx, rtx, void *);
+static void invalidate_skipped_block (rtx);
+static void cse_check_loop_start (rtx, rtx, void *);
+static void cse_set_around_loop (rtx, rtx, rtx);
+static rtx cse_basic_block (rtx, rtx, struct branch_path *, int);
+static void count_reg_usage (rtx, int *, int);
+static int check_for_label_ref (rtx *, void *);
+extern void dump_class (struct table_elt*);
+static struct cse_reg_info * get_cse_reg_info (unsigned int);
+static int check_dependence (rtx *, void *);
+
+static void flush_hash_table (void);
+static bool insn_live_p (rtx, int *);
+static bool set_live_p (rtx, rtx, int *);
+static bool dead_libcall_p (rtx, int *);
+static int cse_change_cc_mode (rtx *, void *);
+static void cse_change_cc_mode_insns (rtx, rtx, rtx);
+static enum machine_mode cse_cc_succs (basic_block, rtx, rtx, bool);
+
/* Nonzero if X has the form (PLUS frame-pointer integer). We check for
virtual regs here because the simplify_*_operation routines are called
- by integrate.c, which is called before virtual register instantiation.
-
- ?!? FIXED_BASE_PLUS_P and NONZERO_BASE_PLUS_P need to move into
- a header file so that their definitions can be shared with the
- simplification routines in simplify-rtx.c. Until then, do not
- change these macros without also changing the copy in simplify-rtx.c. */
-
-#define FIXED_BASE_PLUS_P(X) \
- ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx \
- || ((X) == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])\
- || (X) == virtual_stack_vars_rtx \
- || (X) == virtual_incoming_args_rtx \
- || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (XEXP (X, 0) == frame_pointer_rtx \
- || XEXP (X, 0) == hard_frame_pointer_rtx \
- || ((X) == arg_pointer_rtx \
- && fixed_regs[ARG_POINTER_REGNUM]) \
- || XEXP (X, 0) == virtual_stack_vars_rtx \
- || XEXP (X, 0) == virtual_incoming_args_rtx)) \
- || GET_CODE (X) == ADDRESSOF)
-
-/* Similar, but also allows reference to the stack pointer.
-
- This used to include FIXED_BASE_PLUS_P, however, we can't assume that
- arg_pointer_rtx by itself is nonzero, because on at least one machine,
- the i960, the arg pointer is zero when it is unused. */
-
-#define NONZERO_BASE_PLUS_P(X) \
- ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx \
- || (X) == virtual_stack_vars_rtx \
- || (X) == virtual_incoming_args_rtx \
- || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (XEXP (X, 0) == frame_pointer_rtx \
- || XEXP (X, 0) == hard_frame_pointer_rtx \
- || ((X) == arg_pointer_rtx \
- && fixed_regs[ARG_POINTER_REGNUM]) \
- || XEXP (X, 0) == virtual_stack_vars_rtx \
- || XEXP (X, 0) == virtual_incoming_args_rtx)) \
- || (X) == stack_pointer_rtx \
- || (X) == virtual_stack_dynamic_rtx \
- || (X) == virtual_outgoing_args_rtx \
- || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (XEXP (X, 0) == stack_pointer_rtx \
- || XEXP (X, 0) == virtual_stack_dynamic_rtx \
- || XEXP (X, 0) == virtual_outgoing_args_rtx)) \
- || GET_CODE (X) == ADDRESSOF)
-
-static int notreg_cost PARAMS ((rtx, enum rtx_code));
-static int approx_reg_cost_1 PARAMS ((rtx *, void *));
-static int approx_reg_cost PARAMS ((rtx));
-static int preferrable PARAMS ((int, int, int, int));
-static void new_basic_block PARAMS ((void));
-static void make_new_qty PARAMS ((unsigned int, enum machine_mode));
-static void make_regs_eqv PARAMS ((unsigned int, unsigned int));
-static void delete_reg_equiv PARAMS ((unsigned int));
-static int mention_regs PARAMS ((rtx));
-static int insert_regs PARAMS ((rtx, struct table_elt *, int));
-static void remove_from_table PARAMS ((struct table_elt *, unsigned));
-static struct table_elt *lookup PARAMS ((rtx, unsigned, enum machine_mode)),
- *lookup_for_remove PARAMS ((rtx, unsigned, enum machine_mode));
-static rtx lookup_as_function PARAMS ((rtx, enum rtx_code));
-static struct table_elt *insert PARAMS ((rtx, struct table_elt *, unsigned,
- enum machine_mode));
-static void merge_equiv_classes PARAMS ((struct table_elt *,
- struct table_elt *));
-static void invalidate PARAMS ((rtx, enum machine_mode));
-static int cse_rtx_varies_p PARAMS ((rtx, int));
-static void remove_invalid_refs PARAMS ((unsigned int));
-static void remove_invalid_subreg_refs PARAMS ((unsigned int, unsigned int,
- enum machine_mode));
-static void rehash_using_reg PARAMS ((rtx));
-static void invalidate_memory PARAMS ((void));
-static void invalidate_for_call PARAMS ((void));
-static rtx use_related_value PARAMS ((rtx, struct table_elt *));
-static unsigned canon_hash PARAMS ((rtx, enum machine_mode));
-static unsigned canon_hash_string PARAMS ((const char *));
-static unsigned safe_hash PARAMS ((rtx, enum machine_mode));
-static int exp_equiv_p PARAMS ((rtx, rtx, int, int));
-static rtx canon_reg PARAMS ((rtx, rtx));
-static void find_best_addr PARAMS ((rtx, rtx *, enum machine_mode));
-static enum rtx_code find_comparison_args PARAMS ((enum rtx_code, rtx *, rtx *,
- enum machine_mode *,
- enum machine_mode *));
-static rtx fold_rtx PARAMS ((rtx, rtx));
-static rtx equiv_constant PARAMS ((rtx));
-static void record_jump_equiv PARAMS ((rtx, int));
-static void record_jump_cond PARAMS ((enum rtx_code, enum machine_mode,
- rtx, rtx, int));
-static void cse_insn PARAMS ((rtx, rtx));
-static int addr_affects_sp_p PARAMS ((rtx));
-static void invalidate_from_clobbers PARAMS ((rtx));
-static rtx cse_process_notes PARAMS ((rtx, rtx));
-static void cse_around_loop PARAMS ((rtx));
-static void invalidate_skipped_set PARAMS ((rtx, rtx, void *));
-static void invalidate_skipped_block PARAMS ((rtx));
-static void cse_check_loop_start PARAMS ((rtx, rtx, void *));
-static void cse_set_around_loop PARAMS ((rtx, rtx, rtx));
-static rtx cse_basic_block PARAMS ((rtx, rtx, struct branch_path *, int));
-static void count_reg_usage PARAMS ((rtx, int *, rtx, int));
-static int check_for_label_ref PARAMS ((rtx *, void *));
-extern void dump_class PARAMS ((struct table_elt*));
-static struct cse_reg_info * get_cse_reg_info PARAMS ((unsigned int));
-static int check_dependence PARAMS ((rtx *, void *));
-
-static void flush_hash_table PARAMS ((void));
-static bool insn_live_p PARAMS ((rtx, int *));
-static bool set_live_p PARAMS ((rtx, rtx, int *));
-static bool dead_libcall_p PARAMS ((rtx, int *));
-
+ by integrate.c, which is called before virtual register instantiation. */
+
+static bool
+fixed_base_plus_p (rtx x)
+{
+ switch (GET_CODE (x))
+ {
+ case REG:
+ if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx)
+ return true;
+ if (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM])
+ return true;
+ if (REGNO (x) >= FIRST_VIRTUAL_REGISTER
+ && REGNO (x) <= LAST_VIRTUAL_REGISTER)
+ return true;
+ return false;
+
+ case PLUS:
+ if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+ return false;
+ return fixed_base_plus_p (XEXP (x, 0));
+
+ case ADDRESSOF:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
/* Dump the expressions in the equivalence class indicated by CLASSP.
This function is used only for debugging. */
void
-dump_class (classp)
- struct table_elt *classp;
+dump_class (struct table_elt *classp)
{
struct table_elt *elt;
@@ -724,9 +715,7 @@ dump_class (classp)
/* Subroutine of approx_reg_cost; called through for_each_rtx. */
static int
-approx_reg_cost_1 (xp, data)
- rtx *xp;
- void *data;
+approx_reg_cost_1 (rtx *xp, void *data)
{
rtx x = *xp;
int *cost_p = data;
@@ -757,8 +746,7 @@ approx_reg_cost_1 (xp, data)
0. If any other hard register reference occurs, return MAX_COST. */
static int
-approx_reg_cost (x)
- rtx x;
+approx_reg_cost (rtx x)
{
int cost = 0;
@@ -773,8 +761,7 @@ approx_reg_cost (x)
Return a positive value if A is less desirable, or 0 if the two are
equally good. */
static int
-preferrable (cost_a, regcost_a, cost_b, regcost_b)
- int cost_a, regcost_a, cost_b, regcost_b;
+preferrable (int cost_a, int regcost_a, int cost_b, int regcost_b)
{
/* First, get rid of cases involving expressions that are entirely
unwanted. */
@@ -808,9 +795,7 @@ preferrable (cost_a, regcost_a, cost_b, regcost_b)
from COST macro to keep it simple. */
static int
-notreg_cost (x, outer)
- rtx x;
- enum rtx_code outer;
+notreg_cost (rtx x, enum rtx_code outer)
{
return ((GET_CODE (x) == SUBREG
&& GET_CODE (SUBREG_REG (x)) == REG
@@ -831,9 +816,7 @@ notreg_cost (x, outer)
Other uses like the latter are expected in the future. */
int
-rtx_cost (x, outer_code)
- rtx x;
- enum rtx_code outer_code ATTRIBUTE_UNUSED;
+rtx_cost (rtx x, enum rtx_code outer_code ATTRIBUTE_UNUSED)
{
int i, j;
enum rtx_code code;
@@ -844,7 +827,7 @@ rtx_cost (x, outer_code)
return 0;
/* Compute the default costs of certain things.
- Note that RTX_COSTS can override the defaults. */
+ Note that targetm.rtx_costs can override the defaults. */
code = GET_CODE (x);
switch (code)
@@ -879,17 +862,9 @@ rtx_cost (x, outer_code)
+ GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD);
break;
-#ifdef RTX_COSTS
- RTX_COSTS (x, code, outer_code);
-#endif
-#ifdef CONST_COSTS
- CONST_COSTS (x, code, outer_code);
-#endif
-
default:
-#ifdef DEFAULT_RTX_COSTS
- DEFAULT_RTX_COSTS (x, code, outer_code);
-#endif
+ if ((*targetm.rtx_costs) (x, code, outer_code, &total))
+ return total;
break;
}
@@ -911,11 +886,9 @@ rtx_cost (x, outer_code)
Expect that X is properly formed address reference. */
int
-address_cost (x, mode)
- rtx x;
- enum machine_mode mode;
+address_cost (rtx x, enum machine_mode mode)
{
- /* The ADDRESS_COST macro does not deal with ADDRESSOF nodes. But,
+ /* The address_cost target hook does not deal with ADDRESSOF nodes. But,
during CSE, such nodes are present. Using an ADDRESSOF node which
refers to the address of a REG is a good thing because we can then
turn (MEM (ADDRESSSOF (REG))) into just plain REG. */
@@ -925,21 +898,24 @@ address_cost (x, mode)
/* We may be asked for cost of various unusual addresses, such as operands
of push instruction. It is not worthwhile to complicate writing
- of ADDRESS_COST macro by such cases. */
+ of the target hook by such cases. */
if (!memory_address_p (mode, x))
return 1000;
-#ifdef ADDRESS_COST
- return ADDRESS_COST (x);
-#else
- return rtx_cost (x, MEM);
-#endif
+
+ return (*targetm.address_cost) (x);
}
+/* If the target doesn't override, compute the cost as with arithmetic. */
+
+int
+default_address_cost (rtx x)
+{
+ return rtx_cost (x, MEM);
+}
static struct cse_reg_info *
-get_cse_reg_info (regno)
- unsigned int regno;
+get_cse_reg_info (unsigned int regno)
{
struct cse_reg_info **hash_head = &reg_hash[REGHASH_FN (regno)];
struct cse_reg_info *p;
@@ -957,7 +933,7 @@ get_cse_reg_info (regno)
cse_reg_info_free_list = p->next;
}
else
- p = (struct cse_reg_info *) xmalloc (sizeof (struct cse_reg_info));
+ p = xmalloc (sizeof (struct cse_reg_info));
/* Insert into hash table. */
p->hash_next = *hash_head;
@@ -987,7 +963,7 @@ get_cse_reg_info (regno)
for a new basic block. */
static void
-new_basic_block ()
+new_basic_block (void)
{
int i;
@@ -995,7 +971,7 @@ new_basic_block ()
/* Clear out hash table state for this pass. */
- memset ((char *) reg_hash, 0, sizeof reg_hash);
+ memset (reg_hash, 0, sizeof reg_hash);
if (cse_reg_info_used_list)
{
@@ -1032,9 +1008,8 @@ new_basic_block ()
}
}
- prev_insn = 0;
-
#ifdef HAVE_cc0
+ prev_insn = 0;
prev_insn_cc0 = 0;
#endif
}
@@ -1043,9 +1018,7 @@ new_basic_block ()
register before and initialize that quantity. */
static void
-make_new_qty (reg, mode)
- unsigned int reg;
- enum machine_mode mode;
+make_new_qty (unsigned int reg, enum machine_mode mode)
{
int q;
struct qty_table_elem *ent;
@@ -1070,8 +1043,7 @@ make_new_qty (reg, mode)
OLD is not changing; NEW is. */
static void
-make_regs_eqv (new, old)
- unsigned int new, old;
+make_regs_eqv (unsigned int new, unsigned int old)
{
unsigned int lastr, firstr;
int q = REG_QTY (old);
@@ -1134,8 +1106,7 @@ make_regs_eqv (new, old)
/* Remove REG from its equivalence class. */
static void
-delete_reg_equiv (reg)
- unsigned int reg;
+delete_reg_equiv (unsigned int reg)
{
struct qty_table_elem *ent;
int q = REG_QTY (reg);
@@ -1175,8 +1146,7 @@ delete_reg_equiv (reg)
of X. */
static int
-mention_regs (x)
- rtx x;
+mention_regs (rtx x)
{
enum rtx_code code;
int i, j;
@@ -1285,10 +1255,7 @@ mention_regs (x)
so X's hash code may be different. */
static int
-insert_regs (x, classp, modified)
- rtx x;
- struct table_elt *classp;
- int modified;
+insert_regs (rtx x, struct table_elt *classp, int modified)
{
if (GET_CODE (x) == REG)
{
@@ -1365,9 +1332,7 @@ insert_regs (x, classp, modified)
and we save much time not recomputing it. */
static void
-remove_from_table (elt, hash)
- struct table_elt *elt;
- unsigned hash;
+remove_from_table (struct table_elt *elt, unsigned int hash)
{
if (elt == 0)
return;
@@ -1450,10 +1415,7 @@ remove_from_table (elt, hash)
looks like X. */
static struct table_elt *
-lookup (x, hash, mode)
- rtx x;
- unsigned hash;
- enum machine_mode mode;
+lookup (rtx x, unsigned int hash, enum machine_mode mode)
{
struct table_elt *p;
@@ -1469,10 +1431,7 @@ lookup (x, hash, mode)
Also ignore discrepancies in the machine mode of a register. */
static struct table_elt *
-lookup_for_remove (x, hash, mode)
- rtx x;
- unsigned hash;
- enum machine_mode mode;
+lookup_for_remove (rtx x, unsigned int hash, enum machine_mode mode)
{
struct table_elt *p;
@@ -1501,9 +1460,7 @@ lookup_for_remove (x, hash, mode)
If one is found, return that expression. */
static rtx
-lookup_as_function (x, code)
- rtx x;
- enum rtx_code code;
+lookup_as_function (rtx x, enum rtx_code code)
{
struct table_elt *p
= lookup (x, safe_hash (x, VOIDmode) & HASH_MASK, GET_MODE (x));
@@ -1559,11 +1516,7 @@ lookup_as_function (x, code)
(preferrable ((X)->cost, (X)->regcost, (Y)->cost, (Y)->regcost) < 0)
static struct table_elt *
-insert (x, classp, hash, mode)
- rtx x;
- struct table_elt *classp;
- unsigned hash;
- enum machine_mode mode;
+insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mode)
{
struct table_elt *elt;
@@ -1591,7 +1544,7 @@ insert (x, classp, hash, mode)
else
{
n_elements_made++;
- elt = (struct table_elt *) xmalloc (sizeof (struct table_elt));
+ elt = xmalloc (sizeof (struct table_elt));
}
elt->exp = x;
@@ -1611,7 +1564,7 @@ insert (x, classp, hash, mode)
|| (GET_CODE (x) == REG
&& RTX_UNCHANGING_P (x)
&& REGNO (x) >= FIRST_PSEUDO_REGISTER)
- || FIXED_BASE_PLUS_P (x));
+ || fixed_base_plus_p (x));
if (table[hash])
table[hash]->prev_same_hash = elt;
@@ -1622,7 +1575,7 @@ insert (x, classp, hash, mode)
{
classp = classp->first_same_value;
if (CHEAPER (elt, classp))
- /* Insert at the head of the class */
+ /* Insert at the head of the class. */
{
struct table_elt *p;
elt->next_same_value = classp;
@@ -1749,8 +1702,7 @@ insert (x, classp, hash, mode)
Any invalid entries in CLASS2 will not be copied. */
static void
-merge_equiv_classes (class1, class2)
- struct table_elt *class1, *class2;
+merge_equiv_classes (struct table_elt *class1, struct table_elt *class2)
{
struct table_elt *elt, *next, *new;
@@ -1775,15 +1727,20 @@ merge_equiv_classes (class1, class2)
hash code (it also isn't necessary). */
if (GET_CODE (exp) == REG || exp_equiv_p (exp, exp, 1, 0))
{
+ bool need_rehash = false;
+
hash_arg_in_memory = 0;
hash = HASH (exp, mode);
if (GET_CODE (exp) == REG)
- delete_reg_equiv (REGNO (exp));
+ {
+ need_rehash = (unsigned) REG_QTY (REGNO (exp)) != REGNO (exp);
+ delete_reg_equiv (REGNO (exp));
+ }
remove_from_table (elt, hash);
- if (insert_regs (exp, class1, 0))
+ if (insert_regs (exp, class1, 0) || need_rehash)
{
rehash_using_reg (exp);
hash = HASH (exp, mode);
@@ -1797,7 +1754,7 @@ merge_equiv_classes (class1, class2)
/* Flush the entire hash table. */
static void
-flush_hash_table ()
+flush_hash_table (void)
{
int i;
struct table_elt *p;
@@ -1819,16 +1776,16 @@ struct check_dependence_data
{
enum machine_mode mode;
rtx exp;
+ rtx addr;
};
static int
-check_dependence (x, data)
- rtx *x;
- void *data;
+check_dependence (rtx *x, void *data)
{
struct check_dependence_data *d = (struct check_dependence_data *) data;
if (*x && GET_CODE (*x) == MEM)
- return true_dependence (d->exp, d->mode, *x, cse_rtx_varies_p);
+ return canon_true_dependence (d->exp, d->mode, d->addr, *x,
+ cse_rtx_varies_p);
else
return 0;
}
@@ -1846,12 +1803,11 @@ check_dependence (x, data)
or it may be either of those plus a numeric offset. */
static void
-invalidate (x, full_mode)
- rtx x;
- enum machine_mode full_mode;
+invalidate (rtx x, enum machine_mode full_mode)
{
int i;
struct table_elt *p;
+ rtx addr;
switch (GET_CODE (x))
{
@@ -1942,6 +1898,7 @@ invalidate (x, full_mode)
return;
case MEM:
+ addr = canon_rtx (get_addr (XEXP (x, 0)));
/* Calculate the canonical version of X here so that
true_dependence doesn't generate new RTL for X on each call. */
x = canon_rtx (x);
@@ -1969,6 +1926,7 @@ invalidate (x, full_mode)
if (!p->canon_exp)
p->canon_exp = canon_rtx (p->exp);
d.exp = x;
+ d.addr = addr;
d.mode = full_mode;
if (for_each_rtx (&p->canon_exp, check_dependence, &d))
remove_from_table (p, i);
@@ -1988,8 +1946,7 @@ invalidate (x, full_mode)
expressions to reappear as valid. */
static void
-remove_invalid_refs (regno)
- unsigned int regno;
+remove_invalid_refs (unsigned int regno)
{
unsigned int i;
struct table_elt *p, *next;
@@ -2007,10 +1964,8 @@ remove_invalid_refs (regno)
/* Likewise for a subreg with subreg_reg REGNO, subreg_byte OFFSET,
and mode MODE. */
static void
-remove_invalid_subreg_refs (regno, offset, mode)
- unsigned int regno;
- unsigned int offset;
- enum machine_mode mode;
+remove_invalid_subreg_refs (unsigned int regno, unsigned int offset,
+ enum machine_mode mode)
{
unsigned int i;
struct table_elt *p, *next;
@@ -2040,8 +1995,7 @@ remove_invalid_subreg_refs (regno, offset, mode)
This is called when we make a jump equivalence. */
static void
-rehash_using_reg (x)
- rtx x;
+rehash_using_reg (rtx x)
{
unsigned int i;
struct table_elt *p, *next;
@@ -2059,14 +2013,13 @@ rehash_using_reg (x)
return;
/* Scan all hash chains looking for valid entries that mention X.
- If we find one and it is in the wrong hash chain, move it. We can skip
- objects that are registers, since they are handled specially. */
+ If we find one and it is in the wrong hash chain, move it. */
for (i = 0; i < HASH_SIZE; i++)
for (p = table[i]; p; p = next)
{
next = p->next_same_hash;
- if (GET_CODE (p->exp) != REG && reg_mentioned_p (x, p->exp)
+ if (reg_mentioned_p (x, p->exp)
&& exp_equiv_p (p->exp, p->exp, 1, 0)
&& i != (hash = safe_hash (p->exp, p->mode) & HASH_MASK))
{
@@ -2091,7 +2044,7 @@ rehash_using_reg (x)
register. Also update their TICK values. */
static void
-invalidate_for_call ()
+invalidate_for_call (void)
{
unsigned int regno, endregno;
unsigned int i;
@@ -2150,9 +2103,7 @@ invalidate_for_call ()
If none can be found, return 0. */
static rtx
-use_related_value (x, elt)
- rtx x;
- struct table_elt *elt;
+use_related_value (rtx x, struct table_elt *elt)
{
struct table_elt *relt = 0;
struct table_elt *p, *q;
@@ -2220,8 +2171,7 @@ use_related_value (x, elt)
/* Hash a string. Just add its bytes up. */
static inline unsigned
-canon_hash_string (ps)
- const char *ps;
+canon_hash_string (const char *ps)
{
unsigned hash = 0;
const unsigned char *p = (const unsigned char *) ps;
@@ -2247,9 +2197,7 @@ canon_hash_string (ps)
is just (int) MEM plus the hash code of the address. */
static unsigned
-canon_hash (x, mode)
- rtx x;
- enum machine_mode mode;
+canon_hash (rtx x, enum machine_mode mode)
{
int i, j;
unsigned hash = 0;
@@ -2301,7 +2249,7 @@ canon_hash (x, mode)
record = false;
else
record = true;
-
+
if (!record)
{
do_not_record = 1;
@@ -2378,10 +2326,9 @@ canon_hash (x, mode)
do_not_record = 1;
return 0;
}
- if (! RTX_UNCHANGING_P (x) || FIXED_BASE_PLUS_P (XEXP (x, 0)))
- {
- hash_arg_in_memory = 1;
- }
+ if (! RTX_UNCHANGING_P (x) || fixed_base_plus_p (XEXP (x, 0)))
+ hash_arg_in_memory = 1;
+
/* Now that we have already found this special case,
might as well speed it up as much as possible. */
hash += (unsigned) MEM;
@@ -2399,7 +2346,7 @@ canon_hash (x, mode)
hash += (unsigned) USE;
x = XEXP (x, 0);
- if (! RTX_UNCHANGING_P (x) || FIXED_BASE_PLUS_P (XEXP (x, 0)))
+ if (! RTX_UNCHANGING_P (x) || fixed_base_plus_p (XEXP (x, 0)))
hash_arg_in_memory = 1;
/* Now that we have already found this special case,
@@ -2502,9 +2449,7 @@ canon_hash (x, mode)
/* Like canon_hash but with no side effects. */
static unsigned
-safe_hash (x, mode)
- rtx x;
- enum machine_mode mode;
+safe_hash (rtx x, enum machine_mode mode)
{
int save_do_not_record = do_not_record;
int save_hash_arg_in_memory = hash_arg_in_memory;
@@ -2530,10 +2475,7 @@ safe_hash (x, mode)
is the same as that of the given value is pure luck. */
static int
-exp_equiv_p (x, y, validate, equal_values)
- rtx x, y;
- int validate;
- int equal_values;
+exp_equiv_p (rtx x, rtx y, int validate, int equal_values)
{
int i, j;
enum rtx_code code;
@@ -2725,9 +2667,7 @@ exp_equiv_p (x, y, validate, equal_values)
against certain constants or near-constants. */
static int
-cse_rtx_varies_p (x, from_alias)
- rtx x;
- int from_alias;
+cse_rtx_varies_p (rtx x, int from_alias)
{
/* We need not check for X and the equivalence class being of the same
mode because if X is equivalent to a constant in some mode, it
@@ -2795,9 +2735,7 @@ cse_rtx_varies_p (x, from_alias)
generally be discarded since the changes we are making are optional. */
static rtx
-canon_reg (x, insn)
- rtx x;
- rtx insn;
+canon_reg (rtx x, rtx insn)
{
int i;
enum rtx_code code;
@@ -2886,26 +2824,20 @@ canon_reg (x, insn)
is a good approximation for that cost. However, most RISC machines have
only a few (usually only one) memory reference formats. If an address is
valid at all, it is often just as cheap as any other address. Hence, for
- RISC machines, we use the configuration macro `ADDRESS_COST' to compare the
- costs of various addresses. For two addresses of equal cost, choose the one
- with the highest `rtx_cost' value as that has the potential of eliminating
- the most insns. For equal costs, we choose the first in the equivalence
- class. Note that we ignore the fact that pseudo registers are cheaper
- than hard registers here because we would also prefer the pseudo registers.
- */
+ RISC machines, we use `address_cost' to compare the costs of various
+ addresses. For two addresses of equal cost, choose the one with the
+ highest `rtx_cost' value as that has the potential of eliminating the
+ most insns. For equal costs, we choose the first in the equivalence
+ class. Note that we ignore the fact that pseudo registers are cheaper than
+ hard registers here because we would also prefer the pseudo registers. */
static void
-find_best_addr (insn, loc, mode)
- rtx insn;
- rtx *loc;
- enum machine_mode mode;
+find_best_addr (rtx insn, rtx *loc, enum machine_mode mode)
{
struct table_elt *elt;
rtx addr = *loc;
-#ifdef ADDRESS_COST
struct table_elt *p;
int found_better = 1;
-#endif
int save_do_not_record = do_not_record;
int save_hash_arg_in_memory = hash_arg_in_memory;
int addr_volatile;
@@ -2969,22 +2901,6 @@ find_best_addr (insn, loc, mode)
elt = lookup (addr, hash, Pmode);
-#ifndef ADDRESS_COST
- if (elt)
- {
- int our_cost = elt->cost;
-
- /* Find the lowest cost below ours that works. */
- for (elt = elt->first_same_value; elt; elt = elt->next_same_value)
- if (elt->cost < our_cost
- && (GET_CODE (elt->exp) == REG
- || exp_equiv_p (elt->exp, elt->exp, 1, 0))
- && validate_change (insn, loc,
- canon_reg (copy_rtx (elt->exp), NULL_RTX), 0))
- return;
- }
-#else
-
if (elt)
{
/* We need to find the best (under the criteria documented above) entry
@@ -3043,10 +2959,9 @@ find_best_addr (insn, loc, mode)
if (flag_expensive_optimizations
&& (GET_RTX_CLASS (GET_CODE (*loc)) == '2'
|| GET_RTX_CLASS (GET_CODE (*loc)) == 'c')
- && GET_CODE (XEXP (*loc, 0)) == REG
- && GET_CODE (XEXP (*loc, 1)) == CONST_INT)
+ && GET_CODE (XEXP (*loc, 0)) == REG)
{
- rtx c = XEXP (*loc, 1);
+ rtx op1 = XEXP (*loc, 1);
do_not_record = 0;
hash = HASH (XEXP (*loc, 0), Pmode);
@@ -3088,7 +3003,7 @@ find_best_addr (insn, loc, mode)
|| exp_equiv_p (p->exp, p->exp, 1, 0)))
{
rtx new = simplify_gen_binary (GET_CODE (*loc), Pmode,
- p->exp, c);
+ p->exp, op1);
int new_cost;
new_cost = address_cost (new, mode);
@@ -3115,7 +3030,6 @@ find_best_addr (insn, loc, mode)
}
}
}
-#endif
}
/* Given an operation (CODE, *PARG1, *PARG2), where code is a comparison
@@ -3131,10 +3045,8 @@ find_best_addr (insn, loc, mode)
A or the code corresponding to the inverse of the comparison. */
static enum rtx_code
-find_comparison_args (code, parg1, parg2, pmode1, pmode2)
- enum rtx_code code;
- rtx *parg1, *parg2;
- enum machine_mode *pmode1, *pmode2;
+find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
+ enum machine_mode *pmode1, enum machine_mode *pmode2)
{
rtx arg1, arg2;
@@ -3276,9 +3188,10 @@ find_comparison_args (code, parg1, parg2, pmode1, pmode2)
break;
}
- /* If this is fp + constant, the equivalent is a better operand since
- it may let us predict the value of the comparison. */
- else if (NONZERO_BASE_PLUS_P (p->exp))
+ /* If this non-trapping address, e.g. fp + constant, the
+ equivalent is a better operand since it may let us predict
+ the value of the comparison. */
+ else if (!rtx_addr_can_trap_p (p->exp))
{
arg1 = p->exp;
continue;
@@ -3328,9 +3241,7 @@ find_comparison_args (code, parg1, parg2, pmode1, pmode2)
of X before modifying it. */
static rtx
-fold_rtx (x, insn)
- rtx x;
- rtx insn;
+fold_rtx (rtx x, rtx insn)
{
enum rtx_code code;
enum machine_mode mode;
@@ -3387,17 +3298,11 @@ fold_rtx (x, insn)
/* If the next insn is a CODE_LABEL followed by a jump table,
PC's value is a LABEL_REF pointing to that label. That
lets us fold switch statements on the VAX. */
- if (insn && GET_CODE (insn) == JUMP_INSN)
- {
- rtx next = next_nonnote_insn (insn);
-
- if (next && GET_CODE (next) == CODE_LABEL
- && NEXT_INSN (next) != 0
- && GET_CODE (NEXT_INSN (next)) == JUMP_INSN
- && (GET_CODE (PATTERN (NEXT_INSN (next))) == ADDR_VEC
- || GET_CODE (PATTERN (NEXT_INSN (next))) == ADDR_DIFF_VEC))
- return gen_rtx_LABEL_REF (Pmode, next);
- }
+ {
+ rtx next;
+ if (insn && tablejump_p (insn, &next, NULL))
+ return gen_rtx_LABEL_REF (Pmode, next);
+ }
break;
case SUBREG:
@@ -3637,7 +3542,10 @@ fold_rtx (x, insn)
rtx new;
if (CONSTANT_P (constant) && GET_CODE (constant) != CONST_INT)
- constant_pool_entries_cost = COST (constant);
+ {
+ constant_pool_entries_cost = COST (constant);
+ constant_pool_entries_regcost = approx_reg_cost (constant);
+ }
/* If we are loading the full constant, we have an equivalence. */
if (offset == 0 && mode == const_mode)
@@ -3850,6 +3758,23 @@ fold_rtx (x, insn)
|| (new_cost == old_cost && CONSTANT_P (XEXP (x, i))))
break;
+ /* It's not safe to substitute the operand of a conversion
+ operator with a constant, as the conversion's identity
+ depends upon the mode of it's operand. This optimization
+ is handled by the call to simplify_unary_operation. */
+ if (GET_RTX_CLASS (code) == '1'
+ && GET_MODE (replacements[j]) != mode_arg0
+ && (code == ZERO_EXTEND
+ || code == SIGN_EXTEND
+ || code == TRUNCATE
+ || code == FLOAT_TRUNCATE
+ || code == FLOAT_EXTEND
+ || code == FLOAT
+ || code == FIX
+ || code == UNSIGNED_FLOAT
+ || code == UNSIGNED_FIX))
+ continue;
+
if (validate_change (insn, &XEXP (x, i), replacements[j], 0))
break;
@@ -3891,10 +3816,11 @@ fold_rtx (x, insn)
|| code == LTGT || code == UNEQ || code == ORDERED
|| code == UNORDERED)
{
- if (must_swap || (const_arg0
- && (const_arg1 == 0
- || (GET_CODE (const_arg0) == CONST_INT
- && GET_CODE (const_arg1) != CONST_INT))))
+ if (must_swap
+ || swap_commutative_operands_p (const_arg0 ? const_arg0
+ : XEXP (x, 0),
+ const_arg1 ? const_arg1
+ : XEXP (x, 1)))
{
rtx tem = XEXP (x, 0);
@@ -3979,17 +3905,10 @@ fold_rtx (x, insn)
comparison. */
if (const_arg0 == 0 || const_arg1 == 0)
{
- /* Is FOLDED_ARG0 frame-pointer plus a constant? Or
- non-explicit constant? These aren't zero, but we
- don't know their sign. */
+ /* Some addresses are known to be nonzero. We don't know
+ their sign, but equality comparisons are known. */
if (const_arg1 == const0_rtx
- && (NONZERO_BASE_PLUS_P (folded_arg0)
-#if 0 /* Sad to say, on sysvr4, #pragma weak can make a symbol address
- come out as 0. */
- || GET_CODE (folded_arg0) == SYMBOL_REF
-#endif
- || GET_CODE (folded_arg0) == LABEL_REF
- || GET_CODE (folded_arg0) == CONST))
+ && nonzero_address_p (folded_arg0))
{
if (code == EQ)
return false_rtx;
@@ -4267,7 +4186,7 @@ fold_rtx (x, insn)
with a pre- or post-increment. Similarly for two subtracts of
identical powers of two with post decrement. */
- if (code == PLUS && INTVAL (const_arg1) == INTVAL (inner_const)
+ if (code == PLUS && const_arg1 == inner_const
&& ((HAVE_PRE_INCREMENT
&& exact_log2 (INTVAL (const_arg1)) >= 0)
|| (HAVE_POST_INCREMENT
@@ -4353,9 +4272,14 @@ fold_rtx (x, insn)
break;
case 'x':
- /* Always eliminate CONSTANT_P_RTX at this stage. */
+ /* Eliminate CONSTANT_P_RTX if its constant. */
if (code == CONSTANT_P_RTX)
- return (const_arg0 ? const1_rtx : const0_rtx);
+ {
+ if (const_arg0)
+ return const1_rtx;
+ if (optimize == 0 || !flag_gcse)
+ return const0_rtx;
+ }
break;
}
@@ -4366,8 +4290,7 @@ fold_rtx (x, insn)
Return 0 if we don't know one. */
static rtx
-equiv_constant (x)
- rtx x;
+equiv_constant (rtx x)
{
if (GET_CODE (x) == REG
&& REGNO_QTY_VALID_P (REGNO (x)))
@@ -4417,9 +4340,7 @@ equiv_constant (x)
This is similar to gen_lowpart in emit-rtl.c. */
rtx
-gen_lowpart_if_possible (mode, x)
- enum machine_mode mode;
- rtx x;
+gen_lowpart_if_possible (enum machine_mode mode, rtx x)
{
rtx result = gen_lowpart_common (mode, x);
@@ -4455,16 +4376,14 @@ gen_lowpart_if_possible (mode, x)
In certain cases, this can cause us to add an equivalence. For example,
if we are following the taken case of
- if (i == 2)
+ if (i == 2)
we can add the fact that `i' and '2' are now equivalent.
In any case, we can record that this comparison was passed. If the same
comparison is seen later, we will know its value. */
static void
-record_jump_equiv (insn, taken)
- rtx insn;
- int taken;
+record_jump_equiv (rtx insn, int taken)
{
int cond_known_true;
rtx op0, op1;
@@ -4515,11 +4434,8 @@ record_jump_equiv (insn, taken)
above function and called recursively. */
static void
-record_jump_cond (code, mode, op0, op1, reversed_nonequality)
- enum rtx_code code;
- enum machine_mode mode;
- rtx op0, op1;
- int reversed_nonequality;
+record_jump_cond (enum rtx_code code, enum machine_mode mode, rtx op0,
+ rtx op1, int reversed_nonequality)
{
unsigned op0_hash, op1_hash;
int op0_in_memory, op1_in_memory;
@@ -4755,8 +4671,10 @@ struct set
/* Nonzero if the SET_SRC contains something
whose value cannot be predicted and understood. */
char src_volatile;
- /* Original machine mode, in case it becomes a CONST_INT. */
- enum machine_mode mode;
+ /* Original machine mode, in case it becomes a CONST_INT.
+ The size of this field should match the size of the mode
+ field of struct rtx_def (see rtl.h). */
+ ENUM_BITFIELD(machine_mode) mode : 8;
/* A constant equivalent for SET_SRC, if any. */
rtx src_const;
/* Original SET_SRC value used for libcall notes. */
@@ -4768,9 +4686,7 @@ struct set
};
static void
-cse_insn (insn, libcall_insn)
- rtx insn;
- rtx libcall_insn;
+cse_insn (rtx insn, rtx libcall_insn)
{
rtx x = PATTERN (insn);
int i;
@@ -4810,7 +4726,7 @@ cse_insn (insn, libcall_insn)
if (GET_CODE (x) == SET)
{
- sets = (struct set *) alloca (sizeof (struct set));
+ sets = alloca (sizeof (struct set));
sets[0].rtl = x;
/* Ignore SETs that are unconditional jumps.
@@ -4845,7 +4761,7 @@ cse_insn (insn, libcall_insn)
{
int lim = XVECLEN (x, 0);
- sets = (struct set *) alloca (lim * sizeof (struct set));
+ sets = alloca (lim * sizeof (struct set));
/* Find all regs explicitly clobbered in this insn,
and ensure they are not replaced with any other regs
@@ -5529,7 +5445,11 @@ cse_insn (insn, libcall_insn)
{
trial = src_folded, src_folded_cost = MAX_COST;
if (src_folded_force_flag)
- trial = force_const_mem (mode, trial);
+ {
+ rtx forced = force_const_mem (mode, trial);
+ if (forced)
+ trial = forced;
+ }
}
else if (src
&& preferrable (src_cost, src_regcost,
@@ -5578,6 +5498,8 @@ cse_insn (insn, libcall_insn)
/* Look for a substitution that makes a valid insn. */
else if (validate_change (insn, &SET_SRC (sets[i].rtl), trial, 0))
{
+ rtx new = canon_reg (SET_SRC (sets[i].rtl), insn);
+
/* If we just made a substitution inside a libcall, then we
need to make the same substitution in any notes attached
to the RETVAL insn. */
@@ -5585,15 +5507,13 @@ cse_insn (insn, libcall_insn)
&& (GET_CODE (sets[i].orig_src) == REG
|| GET_CODE (sets[i].orig_src) == SUBREG
|| GET_CODE (sets[i].orig_src) == MEM))
- replace_rtx (REG_NOTES (libcall_insn), sets[i].orig_src,
- canon_reg (SET_SRC (sets[i].rtl), insn));
+ simplify_replace_rtx (REG_NOTES (libcall_insn),
+ sets[i].orig_src, copy_rtx (new));
/* The result of apply_change_group can be ignored; see
canon_reg. */
- validate_change (insn, &SET_SRC (sets[i].rtl),
- canon_reg (SET_SRC (sets[i].rtl), insn),
- 1);
+ validate_change (insn, &SET_SRC (sets[i].rtl), new, 1);
apply_change_group ();
break;
}
@@ -5624,6 +5544,7 @@ cse_insn (insn, libcall_insn)
src_folded_force_flag = 1;
src_folded = trial;
src_folded_cost = constant_pool_entries_cost;
+ src_folded_regcost = constant_pool_entries_regcost;
}
}
@@ -5706,46 +5627,15 @@ cse_insn (insn, libcall_insn)
&& GET_CODE (XEXP (XEXP (src_const, 0), 0)) == LABEL_REF
&& GET_CODE (XEXP (XEXP (src_const, 0), 1)) == LABEL_REF))
{
- /* Make sure that the rtx is not shared with any other insn. */
- src_const = copy_rtx (src_const);
-
- /* Record the actual constant value in a REG_EQUAL note, making
- a new one if one does not already exist. */
- set_unique_reg_note (insn, REG_EQUAL, src_const);
-
- /* If storing a constant value in a register that
- previously held the constant value 0,
- record this fact with a REG_WAS_0 note on this insn.
-
- Note that the *register* is required to have previously held 0,
- not just any register in the quantity and we must point to the
- insn that set that register to zero.
-
- Rather than track each register individually, we just see if
- the last set for this quantity was for this register. */
-
- if (REGNO_QTY_VALID_P (REGNO (dest)))
+ /* We only want a REG_EQUAL note if src_const != src. */
+ if (! rtx_equal_p (src, src_const))
{
- int dest_q = REG_QTY (REGNO (dest));
- struct qty_table_elem *dest_ent = &qty_table[dest_q];
-
- if (dest_ent->const_rtx == const0_rtx)
- {
- /* See if we previously had a REG_WAS_0 note. */
- rtx note = find_reg_note (insn, REG_WAS_0, NULL_RTX);
- rtx const_insn = dest_ent->const_insn;
+ /* Make sure that the rtx is not shared. */
+ src_const = copy_rtx (src_const);
- if ((tem = single_set (const_insn)) != 0
- && rtx_equal_p (SET_DEST (tem), dest))
- {
- if (note)
- XEXP (note, 0) = const_insn;
- else
- REG_NOTES (insn)
- = gen_rtx_INSN_LIST (REG_WAS_0, const_insn,
- REG_NOTES (insn));
- }
- }
+ /* Record the actual constant value in a REG_EQUAL note,
+ making a new one if one does not already exist. */
+ set_unique_reg_note (insn, REG_EQUAL, src_const);
}
}
@@ -5966,6 +5856,16 @@ cse_insn (insn, libcall_insn)
enum machine_mode mode
= GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);
+ /* It's possible that we have a source value known to be
+ constant but don't have a REG_EQUAL note on the insn.
+ Lack of a note will mean src_eqv_elt will be NULL. This
+ can happen where we've generated a SUBREG to access a
+ CONST_INT that is already in a register in a wider mode.
+ Ensure that the source expression is put in the proper
+ constant class. */
+ if (!classp)
+ classp = sets[i].src_const_elt;
+
if (sets[i].src_elt == 0)
{
/* Don't put a hard register source into the table if this is
@@ -6189,7 +6089,7 @@ cse_insn (insn, libcall_insn)
elt->in_memory = (GET_CODE (sets[i].inner_dest) == MEM
&& (! RTX_UNCHANGING_P (sets[i].inner_dest)
- || FIXED_BASE_PLUS_P (XEXP (sets[i].inner_dest,
+ || fixed_base_plus_p (XEXP (sets[i].inner_dest,
0))));
/* If we have (set (subreg:m1 (reg:m2 foo) 0) (bar:m1)), M1 is no
@@ -6325,7 +6225,7 @@ cse_insn (insn, libcall_insn)
}
while (prev && GET_CODE (prev) == NOTE
&& NOTE_LINE_NUMBER (prev) != NOTE_INSN_BASIC_BLOCK);
-
+
/* Do not swap the registers around if the previous instruction
attaches a REG_EQUIV note to REG1.
@@ -6352,20 +6252,6 @@ cse_insn (insn, libcall_insn)
validate_change (insn, &SET_SRC (sets[0].rtl), dest, 1);
apply_change_group ();
- /* If there was a REG_WAS_0 note on PREV, remove it. Move
- any REG_WAS_0 note on INSN to PREV. */
- note = find_reg_note (prev, REG_WAS_0, NULL_RTX);
- if (note)
- remove_note (prev, note);
-
- note = find_reg_note (insn, REG_WAS_0, NULL_RTX);
- if (note)
- {
- remove_note (insn, note);
- XEXP (note, 1) = REG_NOTES (prev);
- REG_NOTES (prev) = note;
- }
-
/* If INSN has a REG_EQUAL note, and this note mentions
REG0, then we must delete it, because the value in
REG0 has changed. If the note's value is REG1, we must
@@ -6400,15 +6286,14 @@ cse_insn (insn, libcall_insn)
prev_insn_cc0 = this_insn_cc0;
prev_insn_cc0_mode = this_insn_cc0_mode;
-#endif
-
prev_insn = insn;
+#endif
}
/* Remove from the hash table all expressions that reference memory. */
static void
-invalidate_memory ()
+invalidate_memory (void)
{
int i;
struct table_elt *p, *next;
@@ -6426,8 +6311,7 @@ invalidate_memory ()
1 and update the register tables to show the effect. Else, return 0. */
static int
-addr_affects_sp_p (addr)
- rtx addr;
+addr_affects_sp_p (rtx addr)
{
if (GET_RTX_CLASS (GET_CODE (addr)) == 'a'
&& GET_CODE (XEXP (addr, 0)) == REG
@@ -6458,8 +6342,7 @@ addr_affects_sp_p (addr)
X is the pattern of the insn. */
static void
-invalidate_from_clobbers (x)
- rtx x;
+invalidate_from_clobbers (rtx x)
{
if (GET_CODE (x) == CLOBBER)
{
@@ -6504,9 +6387,7 @@ invalidate_from_clobbers (x)
Return the replacement for X. */
static rtx
-cse_process_notes (x, object)
- rtx x;
- rtx object;
+cse_process_notes (rtx x, rtx object)
{
enum rtx_code code = GET_CODE (x);
const char *fmt = GET_RTX_FORMAT (code);
@@ -6598,8 +6479,7 @@ cse_process_notes (x, object)
jumps to a label used only once. */
static void
-cse_around_loop (loop_start)
- rtx loop_start;
+cse_around_loop (rtx loop_start)
{
rtx insn;
int i;
@@ -6670,10 +6550,7 @@ cse_around_loop (loop_start)
since they are done elsewhere. This function is called via note_stores. */
static void
-invalidate_skipped_set (dest, set, data)
- rtx set;
- rtx dest;
- void *data ATTRIBUTE_UNUSED;
+invalidate_skipped_set (rtx dest, rtx set, void *data ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (dest);
@@ -6692,9 +6569,7 @@ invalidate_skipped_set (dest, set, data)
}
if (GET_CODE (set) == CLOBBER
-#ifdef HAVE_cc0
- || dest == cc0_rtx
-#endif
+ || CC0_P (dest)
|| dest == pc_rtx)
return;
@@ -6709,8 +6584,7 @@ invalidate_skipped_set (dest, set, data)
conditionally executed. */
static void
-invalidate_skipped_block (start)
- rtx start;
+invalidate_skipped_block (rtx start)
{
rtx insn;
@@ -6737,10 +6611,7 @@ invalidate_skipped_block (start)
NULL_RTX. */
static void
-cse_check_loop_start (x, set, data)
- rtx x;
- rtx set ATTRIBUTE_UNUSED;
- void *data;
+cse_check_loop_start (rtx x, rtx set ATTRIBUTE_UNUSED, void *data)
{
rtx *cse_check_loop_start_value = (rtx *) data;
@@ -6771,10 +6642,7 @@ cse_check_loop_start (x, set, data)
In any event, we invalidate whatever this SET or CLOBBER modifies. */
static void
-cse_set_around_loop (x, insn, loop_start)
- rtx x;
- rtx insn;
- rtx loop_start;
+cse_set_around_loop (rtx x, rtx insn, rtx loop_start)
{
struct table_elt *src_elt;
@@ -6826,6 +6694,8 @@ cse_set_around_loop (x, insn, loop_start)
SET_SRC, add an insn after P to copy its destination
to what we will be replacing SET_SRC with. */
if (cse_check_loop_start_value
+ && single_set (p)
+ && !can_throw_internal (insn)
&& validate_change (insn, &SET_SRC (x),
src_elt->exp, 0))
{
@@ -6845,6 +6715,10 @@ cse_set_around_loop (x, insn, loop_start)
}
else
{
+ if (CONSTANT_P (SET_SRC (set))
+ && ! find_reg_equal_equiv_note (insn))
+ set_unique_reg_note (insn, REG_EQUAL,
+ SET_SRC (set));
if (control_flow_insn_p (p))
/* p can cause a control flow transfer so it
is the last insn of a basic block. We can't
@@ -6887,12 +6761,8 @@ cse_set_around_loop (x, insn, loop_start)
to construct the output branch path. */
void
-cse_end_of_basic_block (insn, data, follow_jumps, after_loop, skip_blocks)
- rtx insn;
- struct cse_basic_block_data *data;
- int follow_jumps;
- int after_loop;
- int skip_blocks;
+cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
+ int follow_jumps, int after_loop, int skip_blocks)
{
rtx p = insn, q;
int nsets = 0;
@@ -6989,7 +6859,7 @@ cse_end_of_basic_block (insn, data, follow_jumps, after_loop, skip_blocks)
In this case invalidate_skipped_block will be called to invalidate any
registers set in the block when following the jump. */
- else if ((follow_jumps || skip_blocks) && path_size < PATHLENGTH - 1
+ else if ((follow_jumps || skip_blocks) && path_size < PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH) - 1
&& GET_CODE (p) == JUMP_INSN
&& GET_CODE (PATTERN (p)) == SET
&& GET_CODE (SET_SRC (PATTERN (p))) == IF_THEN_ELSE
@@ -7109,19 +6979,19 @@ cse_end_of_basic_block (insn, data, follow_jumps, after_loop, skip_blocks)
in conditional jump instructions. */
int
-cse_main (f, nregs, after_loop, file)
- rtx f;
- int nregs;
- int after_loop;
- FILE *file;
+cse_main (rtx f, int nregs, int after_loop, FILE *file)
{
struct cse_basic_block_data val;
rtx insn = f;
int i;
+ val.path = xmalloc (sizeof (struct branch_path)
+ * PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH));
+
cse_jumps_altered = 0;
recorded_label_ref = 0;
constant_pool_entries_cost = 0;
+ constant_pool_entries_regcost = 0;
val.path_size = 0;
init_recog ();
@@ -7131,8 +7001,7 @@ cse_main (f, nregs, after_loop, file)
max_insn_uid = get_max_uid ();
- reg_eqv_table = (struct reg_eqv_elem *)
- xmalloc (nregs * sizeof (struct reg_eqv_elem));
+ reg_eqv_table = xmalloc (nregs * sizeof (struct reg_eqv_elem));
#ifdef LOAD_EXTEND_OP
@@ -7148,7 +7017,7 @@ cse_main (f, nregs, after_loop, file)
/* Find the largest uid. */
max_uid = get_max_uid ();
- uid_cuid = (int *) xcalloc (max_uid + 1, sizeof (int));
+ uid_cuid = xcalloc (max_uid + 1, sizeof (int));
/* Compute the mapping from uids to cuids.
CUIDs are numbers assigned to insns, like uids,
@@ -7242,6 +7111,7 @@ cse_main (f, nregs, after_loop, file)
end_alias_analysis ();
free (uid_cuid);
free (reg_eqv_table);
+ free (val.path);
return cse_jumps_altered || recorded_label_ref;
}
@@ -7255,22 +7125,19 @@ cse_main (f, nregs, after_loop, file)
block and this CSE pass is before loop.c. */
static rtx
-cse_basic_block (from, to, next_branch, around_loop)
- rtx from, to;
- struct branch_path *next_branch;
- int around_loop;
+cse_basic_block (rtx from, rtx to, struct branch_path *next_branch,
+ int around_loop)
{
rtx insn;
int to_usage = 0;
rtx libcall_insn = NULL_RTX;
int num_insns = 0;
+ int no_conflict = 0;
/* This array is undefined before max_reg, so only allocate
the space actually needed and adjust the start. */
- qty_table
- = (struct qty_table_elem *) xmalloc ((max_qty - max_reg)
- * sizeof (struct qty_table_elem));
+ qty_table = xmalloc ((max_qty - max_reg) * sizeof (struct qty_table_elem));
qty_table -= max_reg;
new_basic_block ();
@@ -7314,8 +7181,8 @@ cse_basic_block (from, to, next_branch, around_loop)
Then follow this branch. */
#ifdef HAVE_cc0
prev_insn_cc0 = 0;
-#endif
prev_insn = insn;
+#endif
insn = JUMP_LABEL (insn);
continue;
}
@@ -7345,11 +7212,26 @@ cse_basic_block (from, to, next_branch, around_loop)
if ((p = find_reg_note (insn, REG_LIBCALL, NULL_RTX)))
libcall_insn = XEXP (p, 0);
else if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
- libcall_insn = 0;
+ {
+ /* Keep libcall_insn for the last SET insn of a no-conflict
+ block to prevent changing the destination. */
+ if (! no_conflict)
+ libcall_insn = 0;
+ else
+ no_conflict = -1;
+ }
+ else if (find_reg_note (insn, REG_NO_CONFLICT, NULL_RTX))
+ no_conflict = 1;
}
cse_insn (insn, libcall_insn);
+ if (no_conflict == -1)
+ {
+ libcall_insn = 0;
+ no_conflict = 0;
+ }
+
/* If we haven't already found an insn where we added a LABEL_REF,
check this one. */
if (GET_CODE (insn) == INSN && ! recorded_label_ref
@@ -7419,7 +7301,10 @@ cse_basic_block (from, to, next_branch, around_loop)
following branches in this case. */
to_usage = 0;
val.path_size = 0;
+ val.path = xmalloc (sizeof (struct branch_path)
+ * PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH));
cse_end_of_basic_block (insn, &val, 0, 0, 0);
+ free (val.path);
/* If the tables we allocated have enough space left
to handle all the SETs in the next basic block,
@@ -7468,9 +7353,7 @@ cse_basic_block (from, to, next_branch, around_loop)
there isn't a REG_LABEL note. Return one if so. DATA is the insn. */
static int
-check_for_label_ref (rtl, data)
- rtx *rtl;
- void *data;
+check_for_label_ref (rtx *rtl, void *data)
{
rtx insn = (rtx) data;
@@ -7487,18 +7370,10 @@ check_for_label_ref (rtl, data)
/* Count the number of times registers are used (not set) in X.
COUNTS is an array in which we accumulate the count, INCR is how much
- we count each register usage.
-
- Don't count a usage of DEST, which is the SET_DEST of a SET which
- contains X in its SET_SRC. This is because such a SET does not
- modify the liveness of DEST. */
+ we count each register usage. */
static void
-count_reg_usage (x, counts, dest, incr)
- rtx x;
- int *counts;
- rtx dest;
- int incr;
+count_reg_usage (rtx x, int *counts, int incr)
{
enum rtx_code code;
rtx note;
@@ -7511,8 +7386,7 @@ count_reg_usage (x, counts, dest, incr)
switch (code = GET_CODE (x))
{
case REG:
- if (x != dest)
- counts[REGNO (x)] += incr;
+ counts[REGNO (x)] += incr;
return;
case PC:
@@ -7529,39 +7403,61 @@ count_reg_usage (x, counts, dest, incr)
/* If we are clobbering a MEM, mark any registers inside the address
as being used. */
if (GET_CODE (XEXP (x, 0)) == MEM)
- count_reg_usage (XEXP (XEXP (x, 0), 0), counts, NULL_RTX, incr);
+ count_reg_usage (XEXP (XEXP (x, 0), 0), counts, incr);
return;
case SET:
/* Unless we are setting a REG, count everything in SET_DEST. */
if (GET_CODE (SET_DEST (x)) != REG)
- count_reg_usage (SET_DEST (x), counts, NULL_RTX, incr);
-
- /* If SRC has side-effects, then we can't delete this insn, so the
- usage of SET_DEST inside SRC counts.
-
- ??? Strictly-speaking, we might be preserving this insn
- because some other SET has side-effects, but that's hard
- to do and can't happen now. */
- count_reg_usage (SET_SRC (x), counts,
- side_effects_p (SET_SRC (x)) ? NULL_RTX : SET_DEST (x),
- incr);
+ count_reg_usage (SET_DEST (x), counts, incr);
+ count_reg_usage (SET_SRC (x), counts, incr);
return;
case CALL_INSN:
- count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, NULL_RTX, incr);
+ count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, incr);
/* Fall through. */
case INSN:
case JUMP_INSN:
- count_reg_usage (PATTERN (x), counts, NULL_RTX, incr);
+ count_reg_usage (PATTERN (x), counts, incr);
/* Things used in a REG_EQUAL note aren't dead since loop may try to
use them. */
note = find_reg_equal_equiv_note (x);
if (note)
- count_reg_usage (XEXP (note, 0), counts, NULL_RTX, incr);
+ {
+ rtx eqv = XEXP (note, 0);
+
+ if (GET_CODE (eqv) == EXPR_LIST)
+ /* This REG_EQUAL note describes the result of a function call.
+ Process all the arguments. */
+ do
+ {
+ count_reg_usage (XEXP (eqv, 0), counts, incr);
+ eqv = XEXP (eqv, 1);
+ }
+ while (eqv && GET_CODE (eqv) == EXPR_LIST);
+ else
+ count_reg_usage (eqv, counts, incr);
+ }
+ return;
+
+ case EXPR_LIST:
+ if (REG_NOTE_KIND (x) == REG_EQUAL
+ || (REG_NOTE_KIND (x) != REG_NONNEG && GET_CODE (XEXP (x,0)) == USE)
+ /* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)),
+ involving registers in the address. */
+ || GET_CODE (XEXP (x, 0)) == CLOBBER)
+ count_reg_usage (XEXP (x, 0), counts, incr);
+
+ count_reg_usage (XEXP (x, 1), counts, incr);
+ return;
+
+ case ASM_OPERANDS:
+ /* Iterate over just the inputs, not the constraints as well. */
+ for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
+ count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, incr);
return;
case INSN_LIST:
@@ -7575,19 +7471,17 @@ count_reg_usage (x, counts, dest, incr)
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
- count_reg_usage (XEXP (x, i), counts, dest, incr);
+ count_reg_usage (XEXP (x, i), counts, incr);
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- count_reg_usage (XVECEXP (x, i, j), counts, dest, incr);
+ count_reg_usage (XVECEXP (x, i, j), counts, incr);
}
}
/* Return true if set is live. */
static bool
-set_live_p (set, insn, counts)
- rtx set;
- rtx insn ATTRIBUTE_UNUSED; /* Only used with HAVE_cc0. */
- int *counts;
+set_live_p (rtx set, rtx insn ATTRIBUTE_UNUSED, /* Only used with HAVE_cc0. */
+ int *counts)
{
#ifdef HAVE_cc0
rtx tem;
@@ -7620,9 +7514,7 @@ set_live_p (set, insn, counts)
/* Return true if insn is live. */
static bool
-insn_live_p (insn, counts)
- rtx insn;
- int *counts;
+insn_live_p (rtx insn, int *counts)
{
int i;
if (flag_non_call_exceptions && may_trap_p (PATTERN (insn)))
@@ -7652,37 +7544,51 @@ insn_live_p (insn, counts)
/* Return true if libcall is dead as a whole. */
static bool
-dead_libcall_p (insn, counts)
- rtx insn;
- int *counts;
+dead_libcall_p (rtx insn, int *counts)
{
- rtx note;
+ rtx note, set, new;
+
/* See if there's a REG_EQUAL note on this insn and try to
replace the source with the REG_EQUAL expression.
We assume that insns with REG_RETVALs can only be reg->reg
copies at this point. */
note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
- if (note)
- {
- rtx set = single_set (insn);
- rtx new = simplify_rtx (XEXP (note, 0));
+ if (!note)
+ return false;
- if (!new)
- new = XEXP (note, 0);
+ set = single_set (insn);
+ if (!set)
+ return false;
+
+ new = simplify_rtx (XEXP (note, 0));
+ if (!new)
+ new = XEXP (note, 0);
- /* While changing insn, we must update the counts accordingly. */
- count_reg_usage (insn, counts, NULL_RTX, -1);
+ /* While changing insn, we must update the counts accordingly. */
+ count_reg_usage (insn, counts, -1);
+
+ if (validate_change (insn, &SET_SRC (set), new, 0))
+ {
+ count_reg_usage (insn, counts, 1);
+ remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
+ remove_note (insn, note);
+ return true;
+ }
- if (set && validate_change (insn, &SET_SRC (set), new, 0))
+ if (CONSTANT_P (new))
+ {
+ new = force_const_mem (GET_MODE (SET_DEST (set)), new);
+ if (new && validate_change (insn, &SET_SRC (set), new, 0))
{
- count_reg_usage (insn, counts, NULL_RTX, 1);
+ count_reg_usage (insn, counts, 1);
remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
remove_note (insn, note);
return true;
}
- count_reg_usage (insn, counts, NULL_RTX, 1);
}
+
+ count_reg_usage (insn, counts, 1);
return false;
}
@@ -7695,9 +7601,7 @@ dead_libcall_p (insn, counts)
remaining passes of the compilation are also sped up. */
int
-delete_trivially_dead_insns (insns, nreg)
- rtx insns;
- int nreg;
+delete_trivially_dead_insns (rtx insns, int nreg)
{
int *counts;
rtx insn, prev;
@@ -7706,9 +7610,9 @@ delete_trivially_dead_insns (insns, nreg)
timevar_push (TV_DELETE_TRIVIALLY_DEAD);
/* First count the number of times each register is used. */
- counts = (int *) xcalloc (nreg, sizeof (int));
+ counts = xcalloc (nreg, sizeof (int));
for (insn = next_real_insn (insns); insn; insn = next_real_insn (insn))
- count_reg_usage (insn, counts, NULL_RTX, 1);
+ count_reg_usage (insn, counts, 1);
do
{
@@ -7752,7 +7656,7 @@ delete_trivially_dead_insns (insns, nreg)
if (! live_insn)
{
- count_reg_usage (insn, counts, NULL_RTX, -1);
+ count_reg_usage (insn, counts, -1);
delete_insn_and_edges (insn);
ndead++;
}
@@ -7774,3 +7678,350 @@ delete_trivially_dead_insns (insns, nreg)
timevar_pop (TV_DELETE_TRIVIALLY_DEAD);
return ndead;
}
+
+/* This function is called via for_each_rtx. The argument, NEWREG, is
+ a condition code register with the desired mode. If we are looking
+ at the same register in a different mode, replace it with
+ NEWREG. */
+
+static int
+cse_change_cc_mode (rtx *loc, void *data)
+{
+ rtx newreg = (rtx) data;
+
+ if (*loc
+ && GET_CODE (*loc) == REG
+ && REGNO (*loc) == REGNO (newreg)
+ && GET_MODE (*loc) != GET_MODE (newreg))
+ {
+ *loc = newreg;
+ return -1;
+ }
+ return 0;
+}
+
+/* Change the mode of any reference to the register REGNO (NEWREG) to
+ GET_MODE (NEWREG), starting at START. Stop before END. Stop at
+ any instruction which modifies NEWREG. */
+
+static void
+cse_change_cc_mode_insns (rtx start, rtx end, rtx newreg)
+{
+ rtx insn;
+
+ for (insn = start; insn != end; insn = NEXT_INSN (insn))
+ {
+ if (! INSN_P (insn))
+ continue;
+
+ if (reg_set_p (newreg, insn))
+ return;
+
+ for_each_rtx (&PATTERN (insn), cse_change_cc_mode, newreg);
+ for_each_rtx (&REG_NOTES (insn), cse_change_cc_mode, newreg);
+ }
+}
+
+/* BB is a basic block which finishes with CC_REG as a condition code
+ register which is set to CC_SRC. Look through the successors of BB
+ to find blocks which have a single predecessor (i.e., this one),
+ and look through those blocks for an assignment to CC_REG which is
+ equivalent to CC_SRC. CAN_CHANGE_MODE indicates whether we are
+ permitted to change the mode of CC_SRC to a compatible mode. This
+ returns VOIDmode if no equivalent assignments were found.
+ Otherwise it returns the mode which CC_SRC should wind up with.
+
+ The main complexity in this function is handling the mode issues.
+ We may have more than one duplicate which we can eliminate, and we
+ try to find a mode which will work for multiple duplicates. */
+
+static enum machine_mode
+cse_cc_succs (basic_block bb, rtx cc_reg, rtx cc_src, bool can_change_mode)
+{
+ bool found_equiv;
+ enum machine_mode mode;
+ unsigned int insn_count;
+ edge e;
+ rtx insns[2];
+ enum machine_mode modes[2];
+ rtx last_insns[2];
+ unsigned int i;
+ rtx newreg;
+
+ /* We expect to have two successors. Look at both before picking
+ the final mode for the comparison. If we have more successors
+ (i.e., some sort of table jump, although that seems unlikely),
+ then we require all beyond the first two to use the same
+ mode. */
+
+ found_equiv = false;
+ mode = GET_MODE (cc_src);
+ insn_count = 0;
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ rtx insn;
+ rtx end;
+
+ if (e->flags & EDGE_COMPLEX)
+ continue;
+
+ if (! e->dest->pred
+ || e->dest->pred->pred_next
+ || e->dest == EXIT_BLOCK_PTR)
+ continue;
+
+ end = NEXT_INSN (BB_END (e->dest));
+ for (insn = BB_HEAD (e->dest); insn != end; insn = NEXT_INSN (insn))
+ {
+ rtx set;
+
+ if (! INSN_P (insn))
+ continue;
+
+ /* If CC_SRC is modified, we have to stop looking for
+ something which uses it. */
+ if (modified_in_p (cc_src, insn))
+ break;
+
+ /* Check whether INSN sets CC_REG to CC_SRC. */
+ set = single_set (insn);
+ if (set
+ && GET_CODE (SET_DEST (set)) == REG
+ && REGNO (SET_DEST (set)) == REGNO (cc_reg))
+ {
+ bool found;
+ enum machine_mode set_mode;
+ enum machine_mode comp_mode;
+
+ found = false;
+ set_mode = GET_MODE (SET_SRC (set));
+ comp_mode = set_mode;
+ if (rtx_equal_p (cc_src, SET_SRC (set)))
+ found = true;
+ else if (GET_CODE (cc_src) == COMPARE
+ && GET_CODE (SET_SRC (set)) == COMPARE
+ && mode != set_mode
+ && rtx_equal_p (XEXP (cc_src, 0),
+ XEXP (SET_SRC (set), 0))
+ && rtx_equal_p (XEXP (cc_src, 1),
+ XEXP (SET_SRC (set), 1)))
+
+ {
+ comp_mode = (*targetm.cc_modes_compatible) (mode, set_mode);
+ if (comp_mode != VOIDmode
+ && (can_change_mode || comp_mode == mode))
+ found = true;
+ }
+
+ if (found)
+ {
+ found_equiv = true;
+ if (insn_count < ARRAY_SIZE (insns))
+ {
+ insns[insn_count] = insn;
+ modes[insn_count] = set_mode;
+ last_insns[insn_count] = end;
+ ++insn_count;
+
+ if (mode != comp_mode)
+ {
+ if (! can_change_mode)
+ abort ();
+ mode = comp_mode;
+ PUT_MODE (cc_src, mode);
+ }
+ }
+ else
+ {
+ if (set_mode != mode)
+ {
+ /* We found a matching expression in the
+ wrong mode, but we don't have room to
+ store it in the array. Punt. This case
+ should be rare. */
+ break;
+ }
+ /* INSN sets CC_REG to a value equal to CC_SRC
+ with the right mode. We can simply delete
+ it. */
+ delete_insn (insn);
+ }
+
+ /* We found an instruction to delete. Keep looking,
+ in the hopes of finding a three-way jump. */
+ continue;
+ }
+
+ /* We found an instruction which sets the condition
+ code, so don't look any farther. */
+ break;
+ }
+
+ /* If INSN sets CC_REG in some other way, don't look any
+ farther. */
+ if (reg_set_p (cc_reg, insn))
+ break;
+ }
+
+ /* If we fell off the bottom of the block, we can keep looking
+ through successors. We pass CAN_CHANGE_MODE as false because
+ we aren't prepared to handle compatibility between the
+ further blocks and this block. */
+ if (insn == end)
+ {
+ enum machine_mode submode;
+
+ submode = cse_cc_succs (e->dest, cc_reg, cc_src, false);
+ if (submode != VOIDmode)
+ {
+ if (submode != mode)
+ abort ();
+ found_equiv = true;
+ can_change_mode = false;
+ }
+ }
+ }
+
+ if (! found_equiv)
+ return VOIDmode;
+
+ /* Now INSN_COUNT is the number of instructions we found which set
+ CC_REG to a value equivalent to CC_SRC. The instructions are in
+ INSNS. The modes used by those instructions are in MODES. */
+
+ newreg = NULL_RTX;
+ for (i = 0; i < insn_count; ++i)
+ {
+ if (modes[i] != mode)
+ {
+ /* We need to change the mode of CC_REG in INSNS[i] and
+ subsequent instructions. */
+ if (! newreg)
+ {
+ if (GET_MODE (cc_reg) == mode)
+ newreg = cc_reg;
+ else
+ newreg = gen_rtx_REG (mode, REGNO (cc_reg));
+ }
+ cse_change_cc_mode_insns (NEXT_INSN (insns[i]), last_insns[i],
+ newreg);
+ }
+
+ delete_insn (insns[i]);
+ }
+
+ return mode;
+}
+
+/* If we have a fixed condition code register (or two), walk through
+ the instructions and try to eliminate duplicate assignments. */
+
+void
+cse_condition_code_reg (void)
+{
+ unsigned int cc_regno_1;
+ unsigned int cc_regno_2;
+ rtx cc_reg_1;
+ rtx cc_reg_2;
+ basic_block bb;
+
+ if (! (*targetm.fixed_condition_code_regs) (&cc_regno_1, &cc_regno_2))
+ return;
+
+ cc_reg_1 = gen_rtx_REG (CCmode, cc_regno_1);
+ if (cc_regno_2 != INVALID_REGNUM)
+ cc_reg_2 = gen_rtx_REG (CCmode, cc_regno_2);
+ else
+ cc_reg_2 = NULL_RTX;
+
+ FOR_EACH_BB (bb)
+ {
+ rtx last_insn;
+ rtx cc_reg;
+ rtx insn;
+ rtx cc_src_insn;
+ rtx cc_src;
+ enum machine_mode mode;
+ enum machine_mode orig_mode;
+
+ /* Look for blocks which end with a conditional jump based on a
+ condition code register. Then look for the instruction which
+ sets the condition code register. Then look through the
+ successor blocks for instructions which set the condition
+ code register to the same value. There are other possible
+ uses of the condition code register, but these are by far the
+ most common and the ones which we are most likely to be able
+ to optimize. */
+
+ last_insn = BB_END (bb);
+ if (GET_CODE (last_insn) != JUMP_INSN)
+ continue;
+
+ if (reg_referenced_p (cc_reg_1, PATTERN (last_insn)))
+ cc_reg = cc_reg_1;
+ else if (cc_reg_2 && reg_referenced_p (cc_reg_2, PATTERN (last_insn)))
+ cc_reg = cc_reg_2;
+ else
+ continue;
+
+ cc_src_insn = NULL_RTX;
+ cc_src = NULL_RTX;
+ for (insn = PREV_INSN (last_insn);
+ insn && insn != PREV_INSN (BB_HEAD (bb));
+ insn = PREV_INSN (insn))
+ {
+ rtx set;
+
+ if (! INSN_P (insn))
+ continue;
+ set = single_set (insn);
+ if (set
+ && GET_CODE (SET_DEST (set)) == REG
+ && REGNO (SET_DEST (set)) == REGNO (cc_reg))
+ {
+ cc_src_insn = insn;
+ cc_src = SET_SRC (set);
+ break;
+ }
+ else if (reg_set_p (cc_reg, insn))
+ break;
+ }
+
+ if (! cc_src_insn)
+ continue;
+
+ if (modified_between_p (cc_src, cc_src_insn, NEXT_INSN (last_insn)))
+ continue;
+
+ /* Now CC_REG is a condition code register used for a
+ conditional jump at the end of the block, and CC_SRC, in
+ CC_SRC_INSN, is the value to which that condition code
+ register is set, and CC_SRC is still meaningful at the end of
+ the basic block. */
+
+ orig_mode = GET_MODE (cc_src);
+ mode = cse_cc_succs (bb, cc_reg, cc_src, true);
+ if (mode != VOIDmode)
+ {
+ if (mode != GET_MODE (cc_src))
+ abort ();
+ if (mode != orig_mode)
+ {
+ rtx newreg = gen_rtx_REG (mode, REGNO (cc_reg));
+
+ /* Change the mode of CC_REG in CC_SRC_INSN to
+ GET_MODE (NEWREG). */
+ for_each_rtx (&PATTERN (cc_src_insn), cse_change_cc_mode,
+ newreg);
+ for_each_rtx (&REG_NOTES (cc_src_insn), cse_change_cc_mode,
+ newreg);
+
+ /* Do the same in the following insns that use the
+ current value of CC_REG within BB. */
+ cse_change_cc_mode_insns (NEXT_INSN (cc_src_insn),
+ NEXT_INSN (last_insn),
+ newreg);
+ }
+ }
+ }
+}
diff --git a/contrib/gcc/cselib.c b/contrib/gcc/cselib.c
index e3b228cc27d4..95b4cc7c639f 100644
--- a/contrib/gcc/cselib.c
+++ b/contrib/gcc/cselib.c
@@ -1,6 +1,6 @@
/* Common subexpression elimination library for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
@@ -37,36 +39,30 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "hashtab.h"
#include "cselib.h"
-
-static int entry_and_rtx_equal_p PARAMS ((const void *, const void *));
-static hashval_t get_value_hash PARAMS ((const void *));
-static struct elt_list *new_elt_list PARAMS ((struct elt_list *,
- cselib_val *));
-static struct elt_loc_list *new_elt_loc_list PARAMS ((struct elt_loc_list *,
- rtx));
-static void unchain_one_value PARAMS ((cselib_val *));
-static void unchain_one_elt_list PARAMS ((struct elt_list **));
-static void unchain_one_elt_loc_list PARAMS ((struct elt_loc_list **));
-static void clear_table PARAMS ((int));
-static int discard_useless_locs PARAMS ((void **, void *));
-static int discard_useless_values PARAMS ((void **, void *));
-static void remove_useless_values PARAMS ((void));
-static rtx wrap_constant PARAMS ((enum machine_mode, rtx));
-static unsigned int hash_rtx PARAMS ((rtx, enum machine_mode, int));
-static cselib_val *new_cselib_val PARAMS ((unsigned int,
- enum machine_mode));
-static void add_mem_for_addr PARAMS ((cselib_val *, cselib_val *,
- rtx));
-static cselib_val *cselib_lookup_mem PARAMS ((rtx, int));
-static void cselib_invalidate_regno PARAMS ((unsigned int,
- enum machine_mode));
-static int cselib_mem_conflict_p PARAMS ((rtx, rtx));
-static int cselib_invalidate_mem_1 PARAMS ((void **, void *));
-static void cselib_invalidate_mem PARAMS ((rtx));
-static void cselib_invalidate_rtx PARAMS ((rtx, rtx, void *));
-static void cselib_record_set PARAMS ((rtx, cselib_val *,
- cselib_val *));
-static void cselib_record_sets PARAMS ((rtx));
+#include "params.h"
+#include "alloc-pool.h"
+
+static int entry_and_rtx_equal_p (const void *, const void *);
+static hashval_t get_value_hash (const void *);
+static struct elt_list *new_elt_list (struct elt_list *, cselib_val *);
+static struct elt_loc_list *new_elt_loc_list (struct elt_loc_list *, rtx);
+static void unchain_one_value (cselib_val *);
+static void unchain_one_elt_list (struct elt_list **);
+static void unchain_one_elt_loc_list (struct elt_loc_list **);
+static void clear_table (void);
+static int discard_useless_locs (void **, void *);
+static int discard_useless_values (void **, void *);
+static void remove_useless_values (void);
+static rtx wrap_constant (enum machine_mode, rtx);
+static unsigned int hash_rtx (rtx, enum machine_mode, int);
+static cselib_val *new_cselib_val (unsigned int, enum machine_mode);
+static void add_mem_for_addr (cselib_val *, cselib_val *, rtx);
+static cselib_val *cselib_lookup_mem (rtx, int);
+static void cselib_invalidate_regno (unsigned int, enum machine_mode);
+static void cselib_invalidate_mem (rtx);
+static void cselib_invalidate_rtx (rtx, rtx, void *);
+static void cselib_record_set (rtx, cselib_val *, cselib_val *);
+static void cselib_record_sets (rtx);
/* There are three ways in which cselib can look up an rtx:
- for a REG, the reg_values table (which is indexed by regno) is used
@@ -98,9 +94,13 @@ static int n_useless_values;
/* Number of useless values before we remove them from the hash table. */
#define MAX_USELESS_VALUES 32
-/* This table maps from register number to values. It does not contain
- pointers to cselib_val structures, but rather elt_lists. The purpose is
- to be able to refer to the same register in different modes. */
+/* This table maps from register number to values. It does not
+ contain pointers to cselib_val structures, but rather elt_lists.
+ The purpose is to be able to refer to the same register in
+ different modes. The first element of the list defines the mode in
+ which the register was set; if the mode is unknown or the value is
+ no longer valid in that mode, ELT will be NULL for the first
+ element. */
static GTY(()) varray_type reg_values;
static GTY((deletable (""))) varray_type reg_values_old;
#define REG_VALUES(I) VARRAY_ELT_LIST (reg_values, (I))
@@ -118,30 +118,29 @@ static GTY((deletable (""))) varray_type used_regs_old;
memory for a non-const call instruction. */
static GTY(()) rtx callmem;
-/* Caches for unused structures. */
-static GTY((deletable (""))) cselib_val *empty_vals;
-static GTY((deletable (""))) struct elt_list *empty_elt_lists;
-static GTY((deletable (""))) struct elt_loc_list *empty_elt_loc_lists;
-
/* Set by discard_useless_locs if it deleted the last location of any
value. */
static int values_became_useless;
+
+/* Used as stop element of the containing_mem list so we can check
+ presence in the list by checking the next pointer. */
+static cselib_val dummy_val;
+
+/* Used to list all values that contain memory reference.
+ May or may not contain the useless values - the list is compacted
+ each time memory is invalidated. */
+static cselib_val *first_containing_mem = &dummy_val;
+static alloc_pool elt_loc_list_pool, elt_list_pool, cselib_val_pool, value_pool;
/* Allocate a struct elt_list and fill in its two elements with the
arguments. */
-static struct elt_list *
-new_elt_list (next, elt)
- struct elt_list *next;
- cselib_val *elt;
+static inline struct elt_list *
+new_elt_list (struct elt_list *next, cselib_val *elt)
{
- struct elt_list *el = empty_elt_lists;
-
- if (el)
- empty_elt_lists = el->next;
- else
- el = (struct elt_list *) ggc_alloc (sizeof (struct elt_list));
+ struct elt_list *el;
+ el = pool_alloc (elt_list_pool);
el->next = next;
el->elt = elt;
return el;
@@ -150,19 +149,14 @@ new_elt_list (next, elt)
/* Allocate a struct elt_loc_list and fill in its two elements with the
arguments. */
-static struct elt_loc_list *
-new_elt_loc_list (next, loc)
- struct elt_loc_list *next;
- rtx loc;
+static inline struct elt_loc_list *
+new_elt_loc_list (struct elt_loc_list *next, rtx loc)
{
- struct elt_loc_list *el = empty_elt_loc_lists;
-
- if (el)
- empty_elt_loc_lists = el->next;
- else
- el = (struct elt_loc_list *) ggc_alloc (sizeof (struct elt_loc_list));
+ struct elt_loc_list *el;
+ el = pool_alloc (elt_loc_list_pool);
el->next = next;
el->loc = loc;
+ el->canon_loc = NULL;
el->setting_insn = cselib_current_insn;
el->in_libcall = cselib_current_insn_in_libcall;
return el;
@@ -171,42 +165,36 @@ new_elt_loc_list (next, loc)
/* The elt_list at *PL is no longer needed. Unchain it and free its
storage. */
-static void
-unchain_one_elt_list (pl)
- struct elt_list **pl;
+static inline void
+unchain_one_elt_list (struct elt_list **pl)
{
struct elt_list *l = *pl;
*pl = l->next;
- l->next = empty_elt_lists;
- empty_elt_lists = l;
+ pool_free (elt_list_pool, l);
}
/* Likewise for elt_loc_lists. */
static void
-unchain_one_elt_loc_list (pl)
- struct elt_loc_list **pl;
+unchain_one_elt_loc_list (struct elt_loc_list **pl)
{
struct elt_loc_list *l = *pl;
*pl = l->next;
- l->next = empty_elt_loc_lists;
- empty_elt_loc_lists = l;
+ pool_free (elt_loc_list_pool, l);
}
/* Likewise for cselib_vals. This also frees the addr_list associated with
V. */
static void
-unchain_one_value (v)
- cselib_val *v;
+unchain_one_value (cselib_val *v)
{
while (v->addr_list)
unchain_one_elt_list (&v->addr_list);
- v->u.next_free = empty_vals;
- empty_vals = v;
+ pool_free (cselib_val_pool, v);
}
/* Remove all entries from the hash table. Also used during
@@ -214,17 +202,12 @@ unchain_one_value (v)
which are known to have been used. */
static void
-clear_table (clear_all)
- int clear_all;
+clear_table (void)
{
unsigned int i;
- if (clear_all)
- for (i = 0; i < cselib_nregs; i++)
- REG_VALUES (i) = 0;
- else
- for (i = 0; i < VARRAY_ACTIVE_SIZE (used_regs); i++)
- REG_VALUES (VARRAY_UINT (used_regs, i)) = 0;
+ for (i = 0; i < VARRAY_ACTIVE_SIZE (used_regs); i++)
+ REG_VALUES (VARRAY_UINT (used_regs, i)) = 0;
max_value_regs = 0;
@@ -235,6 +218,8 @@ clear_table (clear_all)
n_useless_values = 0;
next_unknown_value = 0;
+
+ first_containing_mem = &dummy_val;
}
/* The equality test for our hash table. The first argument ENTRY is a table
@@ -243,8 +228,7 @@ clear_table (clear_all)
CONST of an appropriate mode. */
static int
-entry_and_rtx_equal_p (entry, x_arg)
- const void *entry, *x_arg;
+entry_and_rtx_equal_p (const void *entry, const void *x_arg)
{
struct elt_loc_list *l;
const cselib_val *v = (const cselib_val *) entry;
@@ -262,7 +246,7 @@ entry_and_rtx_equal_p (entry, x_arg)
&& (GET_CODE (XEXP (x, 0)) == CONST_INT
|| GET_CODE (XEXP (x, 0)) == CONST_DOUBLE))
x = XEXP (x, 0);
-
+
/* We don't guarantee that distinct rtx's have different hash values,
so we need to do a comparison. */
for (l = v->locs; l; l = l->next)
@@ -277,8 +261,7 @@ entry_and_rtx_equal_p (entry, x_arg)
value from a cselib_val structure. */
static hashval_t
-get_value_hash (entry)
- const void *entry;
+get_value_hash (const void *entry)
{
const cselib_val *v = (const cselib_val *) entry;
return v->value;
@@ -290,9 +273,7 @@ get_value_hash (entry)
removed. */
int
-references_value_p (x, only_useless)
- rtx x;
- int only_useless;
+references_value_p (rtx x, int only_useless)
{
enum rtx_code code = GET_CODE (x);
const char *fmt = GET_RTX_FORMAT (code);
@@ -320,9 +301,7 @@ references_value_p (x, only_useless)
htab_traverse. */
static int
-discard_useless_locs (x, info)
- void **x;
- void *info ATTRIBUTE_UNUSED;
+discard_useless_locs (void **x, void *info ATTRIBUTE_UNUSED)
{
cselib_val *v = (cselib_val *)*x;
struct elt_loc_list **p = &v->locs;
@@ -347,14 +326,13 @@ discard_useless_locs (x, info)
/* If X is a value with no locations, remove it from the hashtable. */
static int
-discard_useless_values (x, info)
- void **x;
- void *info ATTRIBUTE_UNUSED;
+discard_useless_values (void **x, void *info ATTRIBUTE_UNUSED)
{
cselib_val *v = (cselib_val *)*x;
if (v->locs == 0)
{
+ CSELIB_VAL_PTR (v->u.val_rtx) = NULL;
htab_clear_slot (hash_table, x);
unchain_one_value (v);
n_useless_values--;
@@ -367,8 +345,9 @@ discard_useless_values (x, info)
associated with them) from the hash table. */
static void
-remove_useless_values ()
+remove_useless_values (void)
{
+ cselib_val **p, *v;
/* First pass: eliminate locations that reference the value. That in
turn can make more values useless. */
do
@@ -379,23 +358,49 @@ remove_useless_values ()
while (values_became_useless);
/* Second pass: actually remove the values. */
+ p = &first_containing_mem;
+ for (v = *p; v != &dummy_val; v = v->next_containing_mem)
+ if (v->locs)
+ {
+ *p = v;
+ p = &(*p)->next_containing_mem;
+ }
+ *p = &dummy_val;
+
htab_traverse (hash_table, discard_useless_values, 0);
if (n_useless_values != 0)
abort ();
}
+/* Return the mode in which a register was last set. If X is not a
+ register, return its mode. If the mode in which the register was
+ set is not known, or the value was already clobbered, return
+ VOIDmode. */
+
+enum machine_mode
+cselib_reg_set_mode (rtx x)
+{
+ if (GET_CODE (x) != REG)
+ return GET_MODE (x);
+
+ if (REG_VALUES (REGNO (x)) == NULL
+ || REG_VALUES (REGNO (x))->elt == NULL)
+ return VOIDmode;
+
+ return GET_MODE (REG_VALUES (REGNO (x))->elt->u.val_rtx);
+}
+
/* Return nonzero if we can prove that X and Y contain the same value, taking
our gathered information into account. */
int
-rtx_equal_for_cselib_p (x, y)
- rtx x, y;
+rtx_equal_for_cselib_p (rtx x, rtx y)
{
enum rtx_code code;
const char *fmt;
int i;
-
+
if (GET_CODE (x) == REG || GET_CODE (x) == MEM)
{
cselib_val *e = cselib_lookup (x, GET_MODE (x), 0);
@@ -433,7 +438,7 @@ rtx_equal_for_cselib_p (x, y)
else if (rtx_equal_for_cselib_p (t, y))
return 1;
}
-
+
return 0;
}
@@ -451,7 +456,7 @@ rtx_equal_for_cselib_p (x, y)
else if (rtx_equal_for_cselib_p (x, t))
return 1;
}
-
+
return 0;
}
@@ -461,7 +466,7 @@ rtx_equal_for_cselib_p (x, y)
/* This won't be handled correctly by the code below. */
if (GET_CODE (x) == LABEL_REF)
return XEXP (x, 0) == XEXP (y, 0);
-
+
code = GET_CODE (x);
fmt = GET_RTX_FORMAT (code);
@@ -528,9 +533,7 @@ rtx_equal_for_cselib_p (x, y)
functions. For that purpose, wrap them in a CONST of the appropriate
mode. */
static rtx
-wrap_constant (mode, x)
- enum machine_mode mode;
- rtx x;
+wrap_constant (enum machine_mode mode, rtx x)
{
if (GET_CODE (x) != CONST_INT
&& (GET_CODE (x) != CONST_DOUBLE || GET_MODE (x) != VOIDmode))
@@ -550,10 +553,7 @@ wrap_constant (mode, x)
otherwise the mode of X is used. */
static unsigned int
-hash_rtx (x, mode, create)
- rtx x;
- enum machine_mode mode;
- int create;
+hash_rtx (rtx x, enum machine_mode mode, int create)
{
cselib_val *e;
int i, j;
@@ -633,7 +633,7 @@ hash_rtx (x, mode, create)
return 0;
break;
-
+
default:
break;
}
@@ -684,26 +684,27 @@ hash_rtx (x, mode, create)
/* Create a new value structure for VALUE and initialize it. The mode of the
value is MODE. */
-static cselib_val *
-new_cselib_val (value, mode)
- unsigned int value;
- enum machine_mode mode;
+static inline cselib_val *
+new_cselib_val (unsigned int value, enum machine_mode mode)
{
- cselib_val *e = empty_vals;
-
- if (e)
- empty_vals = e->u.next_free;
- else
- e = (cselib_val *) ggc_alloc (sizeof (cselib_val));
+ cselib_val *e = pool_alloc (cselib_val_pool);
+#ifdef ENABLE_CHECKING
if (value == 0)
abort ();
+#endif
e->value = value;
- e->u.val_rtx = gen_rtx_VALUE (mode);
+ /* We use custom method to allocate this RTL construct because it accounts
+ about 8% of overall memory usage. */
+ e->u.val_rtx = pool_alloc (value_pool);
+ memset (e->u.val_rtx, 0, RTX_HDR_SIZE);
+ PUT_CODE (e->u.val_rtx, VALUE);
+ PUT_MODE (e->u.val_rtx, mode);
CSELIB_VAL_PTR (e->u.val_rtx) = e;
e->addr_list = 0;
e->locs = 0;
+ e->next_containing_mem = 0;
return e;
}
@@ -712,9 +713,7 @@ new_cselib_val (value, mode)
value. Update the two value structures to represent this situation. */
static void
-add_mem_for_addr (addr_elt, mem_elt, x)
- cselib_val *addr_elt, *mem_elt;
- rtx x;
+add_mem_for_addr (cselib_val *addr_elt, cselib_val *mem_elt, rtx x)
{
struct elt_loc_list *l;
@@ -728,15 +727,18 @@ add_mem_for_addr (addr_elt, mem_elt, x)
mem_elt->locs
= new_elt_loc_list (mem_elt->locs,
replace_equiv_address_nv (x, addr_elt->u.val_rtx));
+ if (mem_elt->next_containing_mem == NULL)
+ {
+ mem_elt->next_containing_mem = first_containing_mem;
+ first_containing_mem = mem_elt;
+ }
}
/* Subroutine of cselib_lookup. Return a value for X, which is a MEM rtx.
If CREATE, make a new one if we haven't seen it before. */
static cselib_val *
-cselib_lookup_mem (x, create)
- rtx x;
- int create;
+cselib_lookup_mem (rtx x, int create)
{
enum machine_mode mode = GET_MODE (x);
void **slot;
@@ -776,8 +778,7 @@ cselib_lookup_mem (x, create)
allocated. However, the return value can share rtl with X. */
rtx
-cselib_subst_to_values (x)
- rtx x;
+cselib_subst_to_values (rtx x)
{
enum rtx_code code = GET_CODE (x);
const char *fmt = GET_RTX_FORMAT (code);
@@ -789,7 +790,10 @@ cselib_subst_to_values (x)
switch (code)
{
case REG:
- for (l = REG_VALUES (REGNO (x)); l; l = l->next)
+ l = REG_VALUES (REGNO (x));
+ if (l && l->elt == NULL)
+ l = l->next;
+ for (; l; l = l->next)
if (GET_MODE (l->elt->u.val_rtx) == GET_MODE (x))
return l->elt->u.val_rtx;
@@ -818,7 +822,7 @@ cselib_subst_to_values (x)
case PRE_MODIFY:
e = new_cselib_val (++next_unknown_value, GET_MODE (x));
return e->u.val_rtx;
-
+
default:
break;
}
@@ -866,10 +870,7 @@ cselib_subst_to_values (x)
(i.e. because it's a constant). */
cselib_val *
-cselib_lookup (x, mode, create)
- rtx x;
- enum machine_mode mode;
- int create;
+cselib_lookup (rtx x, enum machine_mode mode, int create)
{
void **slot;
cselib_val *e;
@@ -886,7 +887,10 @@ cselib_lookup (x, mode, create)
struct elt_list *l;
unsigned int i = REGNO (x);
- for (l = REG_VALUES (i); l; l = l->next)
+ l = REG_VALUES (i);
+ if (l && l->elt == NULL)
+ l = l->next;
+ for (; l; l = l->next)
if (mode == GET_MODE (l->elt->u.val_rtx))
return l->elt;
@@ -904,8 +908,14 @@ cselib_lookup (x, mode, create)
e = new_cselib_val (++next_unknown_value, GET_MODE (x));
e->locs = new_elt_loc_list (e->locs, x);
if (REG_VALUES (i) == 0)
- VARRAY_PUSH_UINT (used_regs, i);
- REG_VALUES (i) = new_elt_list (REG_VALUES (i), e);
+ {
+ /* Maintain the invariant that the first entry of
+ REG_VALUES, if present, must be the value used to set the
+ register, or NULL. */
+ VARRAY_PUSH_UINT (used_regs, i);
+ REG_VALUES (i) = new_elt_list (REG_VALUES (i), NULL);
+ }
+ REG_VALUES (i)->next = new_elt_list (REG_VALUES (i)->next, e);
slot = htab_find_slot_with_hash (hash_table, x, e->value, INSERT);
*slot = e;
return e;
@@ -945,9 +955,7 @@ cselib_lookup (x, mode, create)
invalidating call clobbered registers across a call. */
static void
-cselib_invalidate_regno (regno, mode)
- unsigned int regno;
- enum machine_mode mode;
+cselib_invalidate_regno (unsigned int regno, enum machine_mode mode)
{
unsigned int endregno;
unsigned int i;
@@ -965,7 +973,7 @@ cselib_invalidate_regno (regno, mode)
{
if (mode == VOIDmode)
abort ();
-
+
if (regno < max_value_regs)
i = 0;
else
@@ -991,17 +999,28 @@ cselib_invalidate_regno (regno, mode)
struct elt_loc_list **p;
unsigned int this_last = i;
- if (i < FIRST_PSEUDO_REGISTER)
+ if (i < FIRST_PSEUDO_REGISTER && v != NULL)
this_last += HARD_REGNO_NREGS (i, GET_MODE (v->u.val_rtx)) - 1;
- if (this_last < regno)
+ if (this_last < regno || v == NULL)
{
l = &(*l)->next;
continue;
}
/* We have an overlap. */
- unchain_one_elt_list (l);
+ if (*l == REG_VALUES (i))
+ {
+ /* Maintain the invariant that the first entry of
+ REG_VALUES, if present, must be the value used to set
+ the register, or NULL. This is also nice because
+ then we won't push the same regno onto user_regs
+ multiple times. */
+ (*l)->elt = NULL;
+ l = &(*l)->next;
+ }
+ else
+ unchain_one_elt_list (l);
/* Now, we clear the mapping from value to reg. It must exist, so
this code will crash intentionally if it doesn't. */
@@ -1020,127 +1039,100 @@ cselib_invalidate_regno (regno, mode)
}
}
}
-
-/* The memory at address MEM_BASE is being changed.
- Return whether this change will invalidate VAL. */
+
+/* Return 1 if X has a value that can vary even between two
+ executions of the program. 0 means X can be compared reliably
+ against certain constants or near-constants. */
static int
-cselib_mem_conflict_p (mem_base, val)
- rtx mem_base;
- rtx val;
+cselib_rtx_varies_p (rtx x ATTRIBUTE_UNUSED, int from_alias ATTRIBUTE_UNUSED)
{
- enum rtx_code code;
- const char *fmt;
- int i, j;
-
- code = GET_CODE (val);
- switch (code)
- {
- /* Get rid of a few simple cases quickly. */
- case REG:
- case PC:
- case CC0:
- case SCRATCH:
- case CONST:
- case CONST_INT:
- case CONST_DOUBLE:
- case CONST_VECTOR:
- case SYMBOL_REF:
- case LABEL_REF:
- return 0;
-
- case MEM:
- if (GET_MODE (mem_base) == BLKmode
- || GET_MODE (val) == BLKmode
- || anti_dependence (val, mem_base))
- return 1;
-
- /* The address may contain nested MEMs. */
- break;
-
- default:
- break;
- }
-
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e')
- {
- if (cselib_mem_conflict_p (mem_base, XEXP (val, i)))
- return 1;
- }
- else if (fmt[i] == 'E')
- for (j = 0; j < XVECLEN (val, i); j++)
- if (cselib_mem_conflict_p (mem_base, XVECEXP (val, i, j)))
- return 1;
- }
-
+ /* We actually don't need to verify very hard. This is because
+ if X has actually changed, we invalidate the memory anyway,
+ so assume that all common memory addresses are
+ invariant. */
return 0;
}
-/* For the value found in SLOT, walk its locations to determine if any overlap
- INFO (which is a MEM rtx). */
+/* Invalidate any locations in the table which are changed because of a
+ store to MEM_RTX. If this is called because of a non-const call
+ instruction, MEM_RTX is (mem:BLK const0_rtx). */
-static int
-cselib_invalidate_mem_1 (slot, info)
- void **slot;
- void *info;
+static void
+cselib_invalidate_mem (rtx mem_rtx)
{
- cselib_val *v = (cselib_val *) *slot;
- rtx mem_rtx = (rtx) info;
- struct elt_loc_list **p = &v->locs;
- int had_locs = v->locs != 0;
+ cselib_val **vp, *v, *next;
+ int num_mems = 0;
+ rtx mem_addr;
- while (*p)
+ mem_addr = canon_rtx (get_addr (XEXP (mem_rtx, 0)));
+ mem_rtx = canon_rtx (mem_rtx);
+
+ vp = &first_containing_mem;
+ for (v = *vp; v != &dummy_val; v = next)
{
- rtx x = (*p)->loc;
- cselib_val *addr;
- struct elt_list **mem_chain;
-
- /* MEMs may occur in locations only at the top level; below
- that every MEM or REG is substituted by its VALUE. */
- if (GET_CODE (x) != MEM
- || ! cselib_mem_conflict_p (mem_rtx, x))
- {
- p = &(*p)->next;
- continue;
- }
+ bool has_mem = false;
+ struct elt_loc_list **p = &v->locs;
+ int had_locs = v->locs != 0;
- /* This one overlaps. */
- /* We must have a mapping from this MEM's address to the
- value (E). Remove that, too. */
- addr = cselib_lookup (XEXP (x, 0), VOIDmode, 0);
- mem_chain = &addr->addr_list;
- for (;;)
+ while (*p)
{
- if ((*mem_chain)->elt == v)
+ rtx x = (*p)->loc;
+ rtx canon_x = (*p)->canon_loc;
+ cselib_val *addr;
+ struct elt_list **mem_chain;
+
+ /* MEMs may occur in locations only at the top level; below
+ that every MEM or REG is substituted by its VALUE. */
+ if (GET_CODE (x) != MEM)
+ {
+ p = &(*p)->next;
+ continue;
+ }
+ if (!canon_x)
+ canon_x = (*p)->canon_loc = canon_rtx (x);
+ if (num_mems < PARAM_VALUE (PARAM_MAX_CSELIB_MEMORY_LOCATIONS)
+ && ! canon_true_dependence (mem_rtx, GET_MODE (mem_rtx), mem_addr,
+ x, cselib_rtx_varies_p))
{
- unchain_one_elt_list (mem_chain);
- break;
+ has_mem = true;
+ num_mems++;
+ p = &(*p)->next;
+ continue;
}
- mem_chain = &(*mem_chain)->next;
- }
-
- unchain_one_elt_loc_list (p);
- }
+ /* This one overlaps. */
+ /* We must have a mapping from this MEM's address to the
+ value (E). Remove that, too. */
+ addr = cselib_lookup (XEXP (x, 0), VOIDmode, 0);
+ mem_chain = &addr->addr_list;
+ for (;;)
+ {
+ if ((*mem_chain)->elt == v)
+ {
+ unchain_one_elt_list (mem_chain);
+ break;
+ }
- if (had_locs && v->locs == 0)
- n_useless_values++;
+ mem_chain = &(*mem_chain)->next;
+ }
- return 1;
-}
+ unchain_one_elt_loc_list (p);
+ }
-/* Invalidate any locations in the table which are changed because of a
- store to MEM_RTX. If this is called because of a non-const call
- instruction, MEM_RTX is (mem:BLK const0_rtx). */
+ if (had_locs && v->locs == 0)
+ n_useless_values++;
-static void
-cselib_invalidate_mem (mem_rtx)
- rtx mem_rtx;
-{
- htab_traverse (hash_table, cselib_invalidate_mem_1, mem_rtx);
+ next = v->next_containing_mem;
+ if (has_mem)
+ {
+ *vp = v;
+ vp = &(*vp)->next_containing_mem;
+ }
+ else
+ v->next_containing_mem = NULL;
+ }
+ *vp = &dummy_val;
}
/* Invalidate DEST, which is being assigned to or clobbered. The second and
@@ -1148,10 +1140,8 @@ cselib_invalidate_mem (mem_rtx)
note_stores; they are ignored. */
static void
-cselib_invalidate_rtx (dest, ignore, data)
- rtx dest;
- rtx ignore ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+cselib_invalidate_rtx (rtx dest, rtx ignore ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
{
while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SIGN_EXTRACT
|| GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SUBREG)
@@ -1175,9 +1165,7 @@ cselib_invalidate_rtx (dest, ignore, data)
describes its address. */
static void
-cselib_record_set (dest, src_elt, dest_addr_elt)
- rtx dest;
- cselib_val *src_elt, *dest_addr_elt;
+cselib_record_set (rtx dest, cselib_val *src_elt, cselib_val *dest_addr_elt)
{
int dreg = GET_CODE (dest) == REG ? (int) REGNO (dest) : -1;
@@ -1186,9 +1174,6 @@ cselib_record_set (dest, src_elt, dest_addr_elt)
if (dreg >= 0)
{
- if (REG_VALUES (dreg) == 0)
- VARRAY_PUSH_UINT (used_regs, dreg);
-
if (dreg < FIRST_PSEUDO_REGISTER)
{
unsigned int n = HARD_REGNO_NREGS (dreg, GET_MODE (dest));
@@ -1197,7 +1182,20 @@ cselib_record_set (dest, src_elt, dest_addr_elt)
max_value_regs = n;
}
- REG_VALUES (dreg) = new_elt_list (REG_VALUES (dreg), src_elt);
+ if (REG_VALUES (dreg) == 0)
+ {
+ VARRAY_PUSH_UINT (used_regs, dreg);
+ REG_VALUES (dreg) = new_elt_list (REG_VALUES (dreg), src_elt);
+ }
+ else
+ {
+ if (REG_VALUES (dreg)->elt == 0)
+ REG_VALUES (dreg)->elt = src_elt;
+ else
+ /* The register should have been invalidated. */
+ abort ();
+ }
+
if (src_elt->locs == 0)
n_useless_values--;
src_elt->locs = new_elt_loc_list (src_elt->locs, dest);
@@ -1225,8 +1223,7 @@ struct set
/* Record the effects of any sets in INSN. */
static void
-cselib_record_sets (insn)
- rtx insn;
+cselib_record_sets (rtx insn)
{
int n_sets = 0;
int i;
@@ -1295,6 +1292,29 @@ cselib_record_sets (insn)
locations may go away. */
note_stores (body, cselib_invalidate_rtx, NULL);
+ /* If this is an asm, look for duplicate sets. This can happen when the
+ user uses the same value as an output multiple times. This is valid
+ if the outputs are not actually used thereafter. Treat this case as
+ if the value isn't actually set. We do this by smashing the destination
+ to pc_rtx, so that we won't record the value later. */
+ if (n_sets >= 2 && asm_noperands (body) >= 0)
+ {
+ for (i = 0; i < n_sets; i++)
+ {
+ rtx dest = sets[i].dest;
+ if (GET_CODE (dest) == REG || GET_CODE (dest) == MEM)
+ {
+ int j;
+ for (j = i + 1; j < n_sets; j++)
+ if (rtx_equal_p (dest, sets[j].dest))
+ {
+ sets[i].dest = pc_rtx;
+ sets[j].dest = pc_rtx;
+ }
+ }
+ }
+ }
+
/* Now enter the equivalences in our tables. */
for (i = 0; i < n_sets; i++)
{
@@ -1307,8 +1327,7 @@ cselib_record_sets (insn)
/* Record the effects of INSN. */
void
-cselib_process_insn (insn)
- rtx insn;
+cselib_process_insn (rtx insn)
{
int i;
rtx x;
@@ -1327,7 +1346,7 @@ cselib_process_insn (insn)
&& GET_CODE (PATTERN (insn)) == ASM_OPERANDS
&& MEM_VOLATILE_P (PATTERN (insn))))
{
- clear_table (0);
+ clear_table ();
return;
}
@@ -1378,7 +1397,7 @@ cselib_process_insn (insn)
it must be called by the user if it allocated new registers. */
void
-cselib_update_varray_sizes ()
+cselib_update_varray_sizes (void)
{
unsigned int nregs = max_reg_num ();
@@ -1394,8 +1413,16 @@ cselib_update_varray_sizes ()
init_alias_analysis. */
void
-cselib_init ()
+cselib_init (void)
{
+ elt_list_pool = create_alloc_pool ("elt_list",
+ sizeof (struct elt_list), 10);
+ elt_loc_list_pool = create_alloc_pool ("elt_loc_list",
+ sizeof (struct elt_loc_list), 10);
+ cselib_val_pool = create_alloc_pool ("cselib_val_list",
+ sizeof (cselib_val), 10);
+ value_pool = create_alloc_pool ("value",
+ RTX_SIZE (VALUE), 10);
/* This is only created once. */
if (! callmem)
callmem = gen_rtx_MEM (BLKmode, const0_rtx);
@@ -1405,25 +1432,27 @@ cselib_init ()
{
reg_values = reg_values_old;
used_regs = used_regs_old;
- VARRAY_CLEAR (reg_values);
- VARRAY_CLEAR (used_regs);
}
else
{
VARRAY_ELT_LIST_INIT (reg_values, cselib_nregs, "reg_values");
VARRAY_UINT_INIT (used_regs, cselib_nregs, "used_regs");
}
- hash_table = htab_create_ggc (31, get_value_hash, entry_and_rtx_equal_p,
+ hash_table = htab_create_ggc (31, get_value_hash, entry_and_rtx_equal_p,
NULL);
- clear_table (1);
cselib_current_insn_in_libcall = false;
}
/* Called when the current user is done with cselib. */
void
-cselib_finish ()
+cselib_finish (void)
{
+ free_alloc_pool (elt_list_pool);
+ free_alloc_pool (elt_loc_list_pool);
+ free_alloc_pool (cselib_val_pool);
+ free_alloc_pool (value_pool);
+ clear_table ();
reg_values_old = reg_values;
reg_values = 0;
used_regs_old = used_regs;
diff --git a/contrib/gcc/cselib.h b/contrib/gcc/cselib.h
index f29ee8de04e8..f86f6572419a 100644
--- a/contrib/gcc/cselib.h
+++ b/contrib/gcc/cselib.h
@@ -1,6 +1,6 @@
/* Common subexpression elimination for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999 Free Software Foundation, Inc.
+ 1999, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -38,6 +38,8 @@ typedef struct cselib_val_struct GTY(())
/* If this value is used as an address, points to a list of values that
use it as an address in a MEM. */
struct elt_list *addr_list;
+
+ struct cselib_val_struct *next_containing_mem;
} cselib_val;
/* A list of rtl expressions that hold the same value. */
@@ -47,6 +49,7 @@ struct elt_loc_list GTY(())
struct elt_loc_list *next;
/* An rtl expression that holds the value. */
rtx loc;
+ rtx canon_loc;
/* The insn that made the equivalence. */
rtx setting_insn;
/* True when setting insn is inside libcall. */
@@ -60,11 +63,12 @@ struct elt_list GTY(())
cselib_val *elt;
};
-extern cselib_val *cselib_lookup PARAMS ((rtx, enum machine_mode, int));
-extern void cselib_update_varray_sizes PARAMS ((void));
-extern void cselib_init PARAMS ((void));
-extern void cselib_finish PARAMS ((void));
-extern void cselib_process_insn PARAMS ((rtx));
-extern int rtx_equal_for_cselib_p PARAMS ((rtx, rtx));
-extern int references_value_p PARAMS ((rtx, int));
-extern rtx cselib_subst_to_values PARAMS ((rtx));
+extern cselib_val *cselib_lookup (rtx, enum machine_mode, int);
+extern void cselib_update_varray_sizes (void);
+extern void cselib_init (void);
+extern void cselib_finish (void);
+extern void cselib_process_insn (rtx);
+extern enum machine_mode cselib_reg_set_mode (rtx);
+extern int rtx_equal_for_cselib_p (rtx, rtx);
+extern int references_value_p (rtx, int);
+extern rtx cselib_subst_to_values (rtx);
diff --git a/contrib/gcc/dbxout.c b/contrib/gcc/dbxout.c
index 8a8b5616082b..5a3c1354b950 100644
--- a/contrib/gcc/dbxout.c
+++ b/contrib/gcc/dbxout.c
@@ -1,6 +1,6 @@
/* Output dbx-format symbol table information from GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -70,6 +70,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
@@ -91,6 +93,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "xcoffout.h"
#endif
+#undef DBXOUT_DECR_NESTING
+#define DBXOUT_DECR_NESTING \
+ if (--debug_nesting == 0 && symbol_queue_index > 0) \
+ { emit_pending_bincls_if_required (); debug_flush_symbol_queue (); }
+
+#undef DBXOUT_DECR_NESTING_AND_RETURN
+#define DBXOUT_DECR_NESTING_AND_RETURN(x) \
+ do {--debug_nesting; return (x);} while (0)
+
#ifndef ASM_STABS_OP
#define ASM_STABS_OP "\t.stabs\t"
#endif
@@ -135,65 +146,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define STABS_GCC_MARKER "gcc2_compiled."
#endif
-/* Typical USG systems don't have stab.h, and they also have
- no use for DBX-format debugging info. */
-
-#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
-
-/* Nonzero if we have actually used any of the GDB extensions
- to the debugging format. The idea is that we use them for the
- first time only if there's a strong reason, but once we have done that,
- we use them whenever convenient. */
-
-static int have_used_extensions = 0;
-
-/* Number for the next N_SOL filename stabs label. The number 0 is reserved
- for the N_SO filename stabs label. */
-
-#if defined (DBX_DEBUGGING_INFO) && !defined (DBX_OUTPUT_SOURCE_FILENAME)
-static int source_label_number = 1;
-#endif
-
-#ifdef DEBUG_SYMS_TEXT
-#define FORCE_TEXT function_section (current_function_decl);
-#else
-#define FORCE_TEXT
-#endif
-
-#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) \
- (GET_CODE (DECL_INCOMING_RTL (PARM)) == MEM)
-
-/* A C expression for the integer offset value of an automatic variable
- (N_LSYM) having address X (an RTX). */
-#ifndef DEBUGGER_AUTO_OFFSET
-#define DEBUGGER_AUTO_OFFSET(X) \
- (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0)
-#endif
-
-/* A C expression for the integer offset value of an argument (N_PSYM)
- having address X (an RTX). The nominal offset is OFFSET. */
-#ifndef DEBUGGER_ARG_OFFSET
-#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET)
-#endif
-
-/* Stream for writing to assembler file. */
-
-static FILE *asmfile;
-
-/* Last source file name mentioned in a NOTE insn. */
-
-static const char *lastfile;
-
-/* Current working directory. */
-
-static const char *cwd;
-
enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED};
/* Structure recording information about a C data type.
@@ -203,13 +155,11 @@ enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED};
The file_number and type_number elements are used if DBX_USE_BINCL
is defined. */
-struct typeinfo
+struct typeinfo GTY(())
{
enum typestatus status;
-#ifdef DBX_USE_BINCL
int file_number;
int type_number;
-#endif
};
/* Vector recording information about C data types.
@@ -217,19 +167,19 @@ struct typeinfo
we assign it a number using next_type_number.
That is its index in this vector. */
-struct typeinfo *typevec;
+static GTY ((length ("typevec_len"))) struct typeinfo *typevec;
/* Number of elements of space allocated in `typevec'. */
-static int typevec_len;
+static GTY(()) int typevec_len;
/* In dbx output, each type gets a unique number.
This is the number for the next type output.
The number, once assigned, is in the TYPE_SYMTAB_ADDRESS field. */
-static int next_type_number;
+static GTY(()) int next_type_number;
-#ifdef DBX_USE_BINCL
+enum binclstatus {BINCL_NOT_REQUIRED, BINCL_PENDING, BINCL_PROCESSED};
/* When using N_BINCL in dbx output, each type number is actually a
pair of the file number and the type number within the file.
@@ -240,17 +190,104 @@ struct dbx_file
struct dbx_file *next;
int file_number;
int next_type_number;
+ enum binclstatus bincl_status; /* Keep track of lazy bincl. */
+ const char *pending_bincl_name; /* Name of bincl. */
+ struct dbx_file *prev; /* Chain to traverse all pending bincls. */
};
-/* This is the top of the stack. */
+/* This is the top of the stack.
+
+ This is not saved for PCH, because restoring a PCH should not change it.
+ next_file_number does have to be saved, because the PCH may use some
+ file numbers; however, just before restoring a PCH, next_file_number
+ should always be 0 because we should not have needed any file numbers
+ yet. */
+#if (defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)) \
+ && defined (DBX_USE_BINCL)
static struct dbx_file *current_file;
+#endif
/* This is the next file number to use. */
-static int next_file_number;
+static GTY(()) int next_file_number;
+
+/* A counter for dbxout_function_end. */
+
+static GTY(()) int scope_labelno;
+
+/* A counter for dbxout_source_line. */
+
+static GTY(()) int dbxout_source_line_counter;
+
+/* Nonzero if we have actually used any of the GDB extensions
+ to the debugging format. The idea is that we use them for the
+ first time only if there's a strong reason, but once we have done that,
+ we use them whenever convenient. */
+
+static GTY(()) int have_used_extensions = 0;
+
+/* Number for the next N_SOL filename stabs label. The number 0 is reserved
+ for the N_SO filename stabs label. */
+
+static GTY(()) int source_label_number = 1;
+
+/* Last source file name mentioned in a NOTE insn. */
+
+static GTY(()) const char *lastfile;
+
+/* Used by PCH machinery to detect if 'lastfile' should be reset to
+ base_input_file. */
+static GTY(()) int lastfile_is_base;
+
+/* Typical USG systems don't have stab.h, and they also have
+ no use for DBX-format debugging info. */
+
+#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
+
+#ifdef DBX_USE_BINCL
+/* If zero then there is no pending BINCL. */
+static int pending_bincls = 0;
+#endif
-#endif /* DBX_USE_BINCL */
+/* The original input file name. */
+static const char *base_input_file;
+
+/* Current working directory. */
+
+static const char *cwd;
+
+#ifdef DEBUG_SYMS_TEXT
+#define FORCE_TEXT function_section (current_function_decl);
+#else
+#define FORCE_TEXT
+#endif
+
+#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) \
+ (GET_CODE (DECL_INCOMING_RTL (PARM)) == MEM)
+
+/* A C expression for the integer offset value of an automatic variable
+ (N_LSYM) having address X (an RTX). */
+#ifndef DEBUGGER_AUTO_OFFSET
+#define DEBUGGER_AUTO_OFFSET(X) \
+ (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0)
+#endif
+
+/* A C expression for the integer offset value of an argument (N_PSYM)
+ having address X (an RTX). The nominal offset is OFFSET. */
+#ifndef DEBUGGER_ARG_OFFSET
+#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET)
+#endif
+
+/* Stream for writing to assembler file. */
+
+static FILE *asmfile;
/* These variables are for dbxout_symbol to communicate to
dbxout_finish_symbol.
@@ -289,44 +326,51 @@ static int current_sym_nchars;
#define CONTIN do { } while (0)
#endif
-static void dbxout_init PARAMS ((const char *));
-static void dbxout_finish PARAMS ((const char *));
-static void dbxout_start_source_file PARAMS ((unsigned, const char *));
-static void dbxout_end_source_file PARAMS ((unsigned));
-static void dbxout_typedefs PARAMS ((tree));
-static void dbxout_fptype_value PARAMS ((tree));
-static void dbxout_type_index PARAMS ((tree));
+#ifdef DBX_USE_BINCL
+static void emit_bincl_stab (const char *c);
+static void emit_pending_bincls (void);
+#endif
+static inline void emit_pending_bincls_if_required (void);
+
+static void dbxout_init (const char *);
+static void dbxout_finish (const char *);
+static void dbxout_start_source_file (unsigned, const char *);
+static void dbxout_end_source_file (unsigned);
+static void dbxout_typedefs (tree);
+static void dbxout_type_index (tree);
#if DBX_CONTIN_LENGTH > 0
-static void dbxout_continue PARAMS ((void));
+static void dbxout_continue (void);
#endif
-static void dbxout_args PARAMS ((tree));
-static void dbxout_type_fields PARAMS ((tree));
-static void dbxout_type_method_1 PARAMS ((tree, const char *));
-static void dbxout_type_methods PARAMS ((tree));
-static void dbxout_range_type PARAMS ((tree));
-static void dbxout_type PARAMS ((tree, int));
-static void print_int_cst_octal PARAMS ((tree));
-static void print_octal PARAMS ((unsigned HOST_WIDE_INT, int));
-static void print_wide_int PARAMS ((HOST_WIDE_INT));
-static void dbxout_type_name PARAMS ((tree));
-static void dbxout_class_name_qualifiers PARAMS ((tree));
-static int dbxout_symbol_location PARAMS ((tree, tree, const char *, rtx));
-static void dbxout_symbol_name PARAMS ((tree, const char *, int));
-static void dbxout_prepare_symbol PARAMS ((tree));
-static void dbxout_finish_symbol PARAMS ((tree));
-static void dbxout_block PARAMS ((tree, int, tree));
-static void dbxout_global_decl PARAMS ((tree));
+static void dbxout_args (tree);
+static void dbxout_type_fields (tree);
+static void dbxout_type_method_1 (tree, const char *);
+static void dbxout_type_methods (tree);
+static void dbxout_range_type (tree);
+static void dbxout_type (tree, int);
+static bool print_int_cst_bounds_in_octal_p (tree);
+static void print_int_cst_octal (tree);
+static void print_octal (unsigned HOST_WIDE_INT, int);
+static void print_wide_int (HOST_WIDE_INT);
+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_prepare_symbol (tree);
+static void dbxout_finish_symbol (tree);
+static void dbxout_block (tree, int, tree);
+static void dbxout_global_decl (tree);
+static void dbxout_handle_pch (unsigned);
/* The debug hooks structure. */
#if defined (DBX_DEBUGGING_INFO)
-static void dbxout_source_line PARAMS ((unsigned int, const char *));
-static void dbxout_source_file PARAMS ((FILE *, const char *));
-static void dbxout_function_end PARAMS ((void));
-static void dbxout_begin_function PARAMS ((tree));
-static void dbxout_begin_block PARAMS ((unsigned, unsigned));
-static void dbxout_end_block PARAMS ((unsigned, unsigned));
-static void dbxout_function_decl PARAMS ((tree));
+static void dbxout_source_line (unsigned int, const char *);
+static void dbxout_source_file (FILE *, const char *);
+static void dbxout_function_end (void);
+static void dbxout_begin_function (tree);
+static void dbxout_begin_block (unsigned, unsigned);
+static void dbxout_end_block (unsigned, unsigned);
+static void dbxout_function_decl (tree);
const struct gcc_debug_hooks dbx_debug_hooks =
{
@@ -353,7 +397,8 @@ const struct gcc_debug_hooks dbx_debug_hooks =
dbxout_global_decl, /* global_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
- debug_nothing_rtx /* label */
+ debug_nothing_rtx, /* label */
+ dbxout_handle_pch /* handle_pch */
};
#endif /* DBX_DEBUGGING_INFO */
@@ -379,21 +424,21 @@ const struct gcc_debug_hooks xcoff_debug_hooks =
dbxout_global_decl, /* global_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
- debug_nothing_rtx /* label */
+ debug_nothing_rtx, /* label */
+ dbxout_handle_pch /* handle_pch */
};
#endif /* XCOFF_DEBUGGING_INFO */
#if defined (DBX_DEBUGGING_INFO)
static void
-dbxout_function_end ()
+dbxout_function_end (void)
{
- static int scope_labelno = 0;
char lscope_label_name[100];
/* Convert Ltext into the appropriate format for local labels in case
the system doesn't insert underscores in front of user generated
labels. */
ASM_GENERATE_INTERNAL_LABEL (lscope_label_name, "Lscope", scope_labelno);
- ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Lscope", scope_labelno);
+ (*targetm.asm_out.internal_label) (asmfile, "Lscope", scope_labelno);
scope_labelno++;
/* By convention, GCC will mark the end of a function with an N_FUN
@@ -414,8 +459,7 @@ dbxout_function_end ()
Initialize `typevec' and output the standard data types of C. */
static void
-dbxout_init (input_file_name)
- const char *input_file_name;
+dbxout_init (const char *input_file_name)
{
char ltext_label_name[100];
tree syms = (*lang_hooks.decls.getdecls) ();
@@ -423,7 +467,7 @@ dbxout_init (input_file_name)
asmfile = asm_out_file;
typevec_len = 100;
- typevec = (struct typeinfo *) xcalloc (typevec_len, sizeof typevec[0]);
+ typevec = ggc_calloc (typevec_len, sizeof typevec[0]);
/* Convert Ltext into the appropriate format for local labels in case
the system doesn't insert underscores in front of user generated
@@ -431,12 +475,10 @@ dbxout_init (input_file_name)
ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);
/* Put the current working directory in an N_SO symbol. */
-#ifndef DBX_WORKING_DIRECTORY /* Only some versions of DBX want this,
- but GDB always does. */
if (use_gnu_debug_info_extensions)
-#endif
{
- if (!cwd && (cwd = getpwd ()) && (!*cwd || cwd[strlen (cwd) - 1] != '/'))
+ if (!cwd && (cwd = get_src_pwd ())
+ && (!*cwd || cwd[strlen (cwd) - 1] != '/'))
cwd = concat (cwd, FILE_NAME_JOINER, NULL);
if (cwd)
{
@@ -453,8 +495,6 @@ dbxout_init (input_file_name)
}
#ifdef DBX_OUTPUT_MAIN_SOURCE_FILENAME
- /* This should NOT be DBX_OUTPUT_SOURCE_FILENAME. That
- would give us an N_SOL, and we want an N_SO. */
DBX_OUTPUT_MAIN_SOURCE_FILENAME (asmfile, input_file_name);
#else /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */
/* We include outputting `Ltext:' here,
@@ -466,7 +506,7 @@ dbxout_init (input_file_name)
assemble_name (asmfile, ltext_label_name);
fputc ('\n', asmfile);
text_section ();
- ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Ltext", 0);
+ (*targetm.asm_out.internal_label) (asmfile, "Ltext", 0);
#endif /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */
#ifdef DBX_OUTPUT_GCC_MARKER
@@ -477,16 +517,19 @@ dbxout_init (input_file_name)
ASM_STABS_OP, STABS_GCC_MARKER, N_OPT);
#endif
- lastfile = input_file_name;
+ base_input_file = lastfile = input_file_name;
next_type_number = 1;
#ifdef DBX_USE_BINCL
- current_file = (struct dbx_file *) xmalloc (sizeof *current_file);
+ current_file = xmalloc (sizeof *current_file);
current_file->next = NULL;
current_file->file_number = 0;
current_file->next_type_number = 1;
next_file_number = 1;
+ current_file->prev = NULL;
+ current_file->bincl_status = BINCL_NOT_REQUIRED;
+ current_file->pending_bincl_name = NULL;
#endif
/* Make sure that types `int' and `char' have numbers 1 and 2.
@@ -498,27 +541,22 @@ dbxout_init (input_file_name)
#ifdef DBX_OUTPUT_STANDARD_TYPES
DBX_OUTPUT_STANDARD_TYPES (syms);
-#else
- dbxout_symbol (TYPE_NAME (integer_type_node), 0);
- dbxout_symbol (TYPE_NAME (char_type_node), 0);
#endif
- /* Get all permanent types that have typedef names,
- and output them all, except for those already output. */
-
+ /* Get all permanent types that have typedef names, and output them
+ all, except for those already output. Some language front ends
+ put these declarations in the top-level scope; some do not. */
+ dbxout_typedefs ((*lang_hooks.decls.builtin_type_decls) ());
dbxout_typedefs (syms);
}
-/* Output any typedef names for types described by TYPE_DECLs in SYMS,
- in the reverse order from that which is found in SYMS. */
+/* Output any typedef names for types described by TYPE_DECLs in SYMS. */
static void
-dbxout_typedefs (syms)
- tree syms;
+dbxout_typedefs (tree syms)
{
- if (syms)
+ for (; syms != NULL_TREE; syms = TREE_CHAIN (syms))
{
- dbxout_typedefs (TREE_CHAIN (syms));
if (TREE_CODE (syms) == TYPE_DECL)
{
tree type = TREE_TYPE (syms);
@@ -531,55 +569,140 @@ dbxout_typedefs (syms)
}
}
+#ifdef DBX_USE_BINCL
+/* Emit BINCL stab using given name. */
+static void
+emit_bincl_stab (const char *name)
+{
+ fprintf (asmfile, "%s", ASM_STABS_OP);
+ output_quoted_string (asmfile, name);
+ fprintf (asmfile, ",%d,0,0,0\n", N_BINCL);
+}
+
+/* If there are pending bincls then it is time to emit all of them. */
+
+static inline void
+emit_pending_bincls_if_required (void)
+{
+ if (pending_bincls)
+ emit_pending_bincls ();
+}
+
+/* Emit all pending bincls. */
+
+static void
+emit_pending_bincls (void)
+{
+ struct dbx_file *f = current_file;
+
+ /* Find first pending bincl. */
+ while (f->bincl_status == BINCL_PENDING)
+ f = f->next;
+
+ /* Now emit all bincls. */
+ f = f->prev;
+
+ while (f)
+ {
+ if (f->bincl_status == BINCL_PENDING)
+ {
+ emit_bincl_stab (f->pending_bincl_name);
+
+ /* Update file number and status. */
+ f->file_number = next_file_number++;
+ f->bincl_status = BINCL_PROCESSED;
+ }
+ if (f == current_file)
+ break;
+ f = f->prev;
+ }
+
+ /* All pending bincls have been emitted. */
+ pending_bincls = 0;
+}
+
+#else
+
+static inline void
+emit_pending_bincls_if_required (void) {}
+#endif
+
/* Change to reading from a new source file. Generate a N_BINCL stab. */
static void
-dbxout_start_source_file (line, filename)
- unsigned int line ATTRIBUTE_UNUSED;
- const char *filename ATTRIBUTE_UNUSED;
+dbxout_start_source_file (unsigned int line ATTRIBUTE_UNUSED,
+ const char *filename ATTRIBUTE_UNUSED)
{
#ifdef DBX_USE_BINCL
- struct dbx_file *n = (struct dbx_file *) xmalloc (sizeof *n);
+ struct dbx_file *n = xmalloc (sizeof *n);
n->next = current_file;
- n->file_number = next_file_number++;
n->next_type_number = 1;
+ /* Do not assign file number now.
+ Delay it until we actually emit BINCL. */
+ n->file_number = 0;
+ n->prev = NULL;
+ current_file->prev = n;
+ n->bincl_status = BINCL_PENDING;
+ n->pending_bincl_name = filename;
+ pending_bincls = 1;
current_file = n;
- fprintf (asmfile, "%s", ASM_STABS_OP);
- output_quoted_string (asmfile, filename);
- fprintf (asmfile, ",%d,0,0,0\n", N_BINCL);
#endif
}
/* Revert to reading a previous source file. Generate a N_EINCL stab. */
static void
-dbxout_end_source_file (line)
- unsigned int line ATTRIBUTE_UNUSED;
+dbxout_end_source_file (unsigned int line ATTRIBUTE_UNUSED)
{
#ifdef DBX_USE_BINCL
- struct dbx_file *next;
-
- fprintf (asmfile, "%s%d,0,0,0\n", ASM_STABN_OP, N_EINCL);
- next = current_file->next;
- free (current_file);
- current_file = next;
+ /* Emit EINCL stab only if BINCL is not pending. */
+ if (current_file->bincl_status == BINCL_PROCESSED)
+ fprintf (asmfile, "%s%d,0,0,0\n", ASM_STABN_OP, N_EINCL);
+ current_file->bincl_status = BINCL_NOT_REQUIRED;
+ current_file = current_file->next;
#endif
}
+/* Handle a few odd cases that occur when trying to make PCH files work. */
+
+static void
+dbxout_handle_pch (unsigned at_end)
+{
+ if (! at_end)
+ {
+ /* When using the PCH, this file will be included, so we need to output
+ a BINCL. */
+ dbxout_start_source_file (0, lastfile);
+
+ /* The base file when using the PCH won't be the same as
+ the base file when it's being generated. */
+ lastfile = NULL;
+ }
+ else
+ {
+ /* ... and an EINCL. */
+ dbxout_end_source_file (0);
+
+ /* Deal with cases where 'lastfile' was never actually changed. */
+ lastfile_is_base = lastfile == NULL;
+ }
+}
+
#if defined (DBX_DEBUGGING_INFO)
/* Output debugging info to FILE to switch to sourcefile FILENAME. */
static void
-dbxout_source_file (file, filename)
- FILE *file;
- const char *filename;
+dbxout_source_file (FILE *file, const char *filename)
{
+ if (lastfile == 0 && lastfile_is_base)
+ {
+ lastfile = base_input_file;
+ lastfile_is_base = 0;
+ }
+
if (filename && (lastfile == 0 || strcmp (filename, lastfile)))
{
-#ifdef DBX_OUTPUT_SOURCE_FILENAME
- DBX_OUTPUT_SOURCE_FILENAME (file, filename);
-#else
char ltext_label_name[100];
ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext",
@@ -594,9 +717,8 @@ dbxout_source_file (file, filename)
; /* Don't change section amid function. */
else
text_section ();
- ASM_OUTPUT_INTERNAL_LABEL (file, "Ltext", source_label_number);
+ (*targetm.asm_out.internal_label) (file, "Ltext", source_label_number);
source_label_number++;
-#endif
lastfile = filename;
}
}
@@ -605,14 +727,13 @@ dbxout_source_file (file, filename)
number LINENO. */
static void
-dbxout_source_line (lineno, filename)
- unsigned int lineno;
- const char *filename;
+dbxout_source_line (unsigned int lineno, const char *filename)
{
dbxout_source_file (asmfile, filename);
#ifdef ASM_OUTPUT_SOURCE_LINE
- ASM_OUTPUT_SOURCE_LINE (asmfile, lineno);
+ dbxout_source_line_counter += 1;
+ ASM_OUTPUT_SOURCE_LINE (asmfile, lineno, dbxout_source_line_counter);
#else
fprintf (asmfile, "%s%d,0,%d\n", ASM_STABD_OP, N_SLINE, lineno);
#endif
@@ -621,21 +742,19 @@ dbxout_source_line (lineno, filename)
/* Describe the beginning of an internal block within a function. */
static void
-dbxout_begin_block (line, n)
- unsigned int line ATTRIBUTE_UNUSED;
- unsigned int n;
+dbxout_begin_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int n)
{
- ASM_OUTPUT_INTERNAL_LABEL (asmfile, "LBB", n);
+ emit_pending_bincls_if_required ();
+ (*targetm.asm_out.internal_label) (asmfile, "LBB", n);
}
/* Describe the end line-number of an internal block within a function. */
static void
-dbxout_end_block (line, n)
- unsigned int line ATTRIBUTE_UNUSED;
- unsigned int n;
+dbxout_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int n)
{
- ASM_OUTPUT_INTERNAL_LABEL (asmfile, "LBE", n);
+ emit_pending_bincls_if_required ();
+ (*targetm.asm_out.internal_label) (asmfile, "LBE", n);
}
/* Output dbx data for a function definition.
@@ -645,9 +764,9 @@ dbxout_end_block (line, n)
(including all the auto variables of the function). */
static void
-dbxout_function_decl (decl)
- tree decl;
+dbxout_function_decl (tree decl)
{
+ emit_pending_bincls_if_required ();
#ifndef DBX_FUNCTION_FIRST
dbxout_begin_function (decl);
#endif
@@ -668,13 +787,17 @@ dbxout_function_decl (decl)
/* Debug information for a global DECL. Called from toplev.c after
compilation proper has finished. */
static void
-dbxout_global_decl (decl)
- tree decl;
+dbxout_global_decl (tree decl)
{
if (TREE_CODE (decl) == VAR_DECL
&& ! DECL_EXTERNAL (decl)
&& DECL_RTL_SET_P (decl)) /* Not necessary? */
- dbxout_symbol (decl, 0);
+ {
+ int saved_tree_used = TREE_USED (decl);
+ TREE_USED (decl) = 1;
+ dbxout_symbol (decl, 0);
+ TREE_USED (decl) = saved_tree_used;
+ }
}
/* At the end of compilation, finish writing the symbol table.
@@ -682,74 +805,19 @@ dbxout_global_decl (decl)
to do nothing. */
static void
-dbxout_finish (filename)
- const char *filename ATTRIBUTE_UNUSED;
+dbxout_finish (const char *filename ATTRIBUTE_UNUSED)
{
#ifdef DBX_OUTPUT_MAIN_SOURCE_FILE_END
DBX_OUTPUT_MAIN_SOURCE_FILE_END (asmfile, filename);
#endif /* DBX_OUTPUT_MAIN_SOURCE_FILE_END */
-}
-
-/* Output floating point type values used by the 'R' stab letter.
- These numbers come from include/aout/stab_gnu.h in binutils/gdb.
-
- There are only 3 real/complex types defined, and we need 7/6.
- We use NF_SINGLE as a generic float type, and NF_COMPLEX as a generic
- complex type. Since we have the type size anyways, we don't really need
- to distinguish between different FP types, we only need to distinguish
- between float and complex. This works fine with gdb.
-
- We only use this for complex types, to avoid breaking backwards
- compatibility for real types. complex types aren't in ISO C90, so it is
- OK if old debuggers don't understand the debug info we emit for them. */
-
-/* ??? These are supposed to be IEEE types, but we don't check for that.
- We could perhaps add additional numbers for non-IEEE types if we need
- them. */
-
-static void
-dbxout_fptype_value (type)
- tree type;
-{
- char value = '0';
- enum machine_mode mode = TYPE_MODE (type);
-
- if (TREE_CODE (type) == REAL_TYPE)
- {
- if (mode == SFmode)
- value = '1';
- else if (mode == DFmode)
- value = '2';
- else if (mode == TFmode || mode == XFmode)
- value = '6';
- else
- /* Use NF_SINGLE as a generic real type for other sizes. */
- value = '1';
- }
- else if (TREE_CODE (type) == COMPLEX_TYPE)
- {
- if (mode == SCmode)
- value = '3';
- else if (mode == DCmode)
- value = '4';
- else if (mode == TCmode || mode == XCmode)
- value = '5';
- else
- /* Use NF_COMPLEX as a generic complex type for other sizes. */
- value = '3';
- }
- else
- abort ();
- putc (value, asmfile);
- CHARS (1);
+ debug_free_queue ();
}
/* Output the index of a type. */
static void
-dbxout_type_index (type)
- tree type;
+dbxout_type_index (tree type)
{
#ifndef DBX_USE_BINCL
fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
@@ -769,8 +837,9 @@ dbxout_type_index (type)
.stabs "...rest",code,0,value */
static void
-dbxout_continue ()
+dbxout_continue (void)
{
+ emit_pending_bincls_if_required ();
#ifdef DBX_CONTIN_CHAR
fprintf (asmfile, "%c", DBX_CONTIN_CHAR);
#else
@@ -787,8 +856,7 @@ dbxout_continue ()
recursive calls. */
static void
-dbxout_type_fields (type)
- tree type;
+dbxout_type_fields (tree type)
{
tree tem;
@@ -796,6 +864,11 @@ dbxout_type_fields (type)
field that we can support. */
for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
{
+
+ /* If on of the nodes is an error_mark or its type is then return early. */
+ if (tem == error_mark_node || TREE_TYPE (tem) == error_mark_node)
+ return;
+
/* Omit here local type decls until we know how to support them. */
if (TREE_CODE (tem) == TYPE_DECL
/* Omit fields whose position or size are variable or too large to
@@ -878,9 +951,7 @@ dbxout_type_fields (type)
now. */
static void
-dbxout_type_method_1 (decl, debug_name)
- tree decl;
- const char *debug_name;
+dbxout_type_method_1 (tree decl, const char *debug_name)
{
char c1 = 'A', c2;
@@ -925,8 +996,7 @@ dbxout_type_method_1 (decl, debug_name)
in TYPE. */
static void
-dbxout_type_methods (type)
- tree type;
+dbxout_type_methods (tree type)
{
/* C++: put out the method names and their parameter lists */
tree methods = TYPE_METHODS (type);
@@ -1031,8 +1101,7 @@ dbxout_type_methods (type)
TYPE is an INTEGER_TYPE. */
static void
-dbxout_range_type (type)
- tree type;
+dbxout_range_type (tree type)
{
fprintf (asmfile, "r");
if (TREE_TYPE (type))
@@ -1064,7 +1133,10 @@ dbxout_range_type (type)
{
putc (';', asmfile);
CHARS (1);
- print_wide_int (tree_low_cst (TYPE_MIN_VALUE (type), 0));
+ if (print_int_cst_bounds_in_octal_p (type))
+ print_int_cst_octal (TYPE_MIN_VALUE (type));
+ else
+ print_wide_int (tree_low_cst (TYPE_MIN_VALUE (type), 0));
}
else
{
@@ -1077,7 +1149,10 @@ dbxout_range_type (type)
{
putc (';', asmfile);
CHARS (1);
- print_wide_int (tree_low_cst (TYPE_MAX_VALUE (type), 0));
+ if (print_int_cst_bounds_in_octal_p (type))
+ print_int_cst_octal (TYPE_MAX_VALUE (type));
+ else
+ print_wide_int (tree_low_cst (TYPE_MAX_VALUE (type), 0));
putc (';', asmfile);
CHARS (1);
}
@@ -1088,6 +1163,7 @@ dbxout_range_type (type)
}
}
+
/* Output a reference to a type. If the type has not yet been
described in the dbx output, output its definition now.
For a type already defined, just refer to its definition
@@ -1099,9 +1175,7 @@ dbxout_range_type (type)
using the number previously allocated. */
static void
-dbxout_type (type, full)
- tree type;
- int full;
+dbxout_type (tree type, int full)
{
tree tem;
tree main_variant;
@@ -1147,14 +1221,13 @@ dbxout_type (type, full)
if (next_type_number == typevec_len)
{
typevec
- = (struct typeinfo *) xrealloc (typevec,
- typevec_len * 2 * sizeof typevec[0]);
- memset ((char *) (typevec + typevec_len), 0,
- typevec_len * sizeof typevec[0]);
+ = ggc_realloc (typevec, (typevec_len * 2 * sizeof typevec[0]));
+ memset (typevec + typevec_len, 0, typevec_len * sizeof typevec[0]);
typevec_len *= 2;
}
#ifdef DBX_USE_BINCL
+ emit_pending_bincls_if_required ();
typevec[TYPE_SYMTAB_ADDRESS (type)].file_number
= current_file->file_number;
typevec[TYPE_SYMTAB_ADDRESS (type)].type_number
@@ -1162,6 +1235,21 @@ dbxout_type (type, full)
#endif
}
+ if (flag_debug_only_used_symbols)
+ {
+ if ((TREE_CODE (type) == RECORD_TYPE
+ || TREE_CODE (type) == UNION_TYPE
+ || TREE_CODE (type) == QUAL_UNION_TYPE
+ || TREE_CODE (type) == ENUMERAL_TYPE)
+ && TYPE_STUB_DECL (type)
+ && TREE_CODE_CLASS (TREE_CODE (TYPE_STUB_DECL (type))) == 'd'
+ && ! DECL_IGNORED_P (TYPE_STUB_DECL (type)))
+ debug_queue_symbol (TYPE_STUB_DECL (type));
+ else if (TYPE_NAME (type)
+ && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
+ debug_queue_symbol (TYPE_NAME (type));
+ }
+
/* Output the number of this type, to refer to it. */
dbxout_type_index (type);
@@ -1245,6 +1333,18 @@ dbxout_type (type, full)
}
else if (main_variant != TYPE_MAIN_VARIANT (type))
{
+ if (flag_debug_only_used_symbols)
+ {
+ tree orig_type = DECL_ORIGINAL_TYPE (TYPE_NAME (type));
+
+ if ((TREE_CODE (orig_type) == RECORD_TYPE
+ || TREE_CODE (orig_type) == UNION_TYPE
+ || TREE_CODE (orig_type) == QUAL_UNION_TYPE
+ || TREE_CODE (orig_type) == ENUMERAL_TYPE)
+ && TYPE_STUB_DECL (orig_type)
+ && ! DECL_IGNORED_P (TYPE_STUB_DECL (orig_type)))
+ debug_queue_symbol (TYPE_STUB_DECL (orig_type));
+ }
/* 'type' is a typedef; output the type it refers to. */
dbxout_type (DECL_ORIGINAL_TYPE (TYPE_NAME (type)), 0);
return;
@@ -1310,34 +1410,21 @@ dbxout_type (type, full)
CHARS (5);
}
- /* 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 the bounds the usual way, write them in
- octal. Note the test is for the *target's* size of "long",
- not that of the host. The host test is just to make sure we
- can write it out in case the host wide int is narrower than the
- target "long". */
-
- /* For unsigned types, we use octal if they are the same size or
- larger. This is because we print the bounds as signed decimal,
- and hence they 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
- && (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)
- || ((TYPE_PRECISION (type)
- == TYPE_PRECISION (integer_type_node))
- && TREE_UNSIGNED (type))
- || TYPE_PRECISION (type) > HOST_BITS_PER_WIDE_INT
- || (TYPE_PRECISION (type) == HOST_BITS_PER_WIDE_INT
- && TREE_UNSIGNED (type))))
+ if (print_int_cst_bounds_in_octal_p (type))
{
fprintf (asmfile, "r");
CHARS (1);
- dbxout_type_index (type);
+
+ /* If this type derives from another type, output type index of
+ parent type. This is particularly important when parent type
+ is an enumerated type, because not generating the parent type
+ index would transform the definition of this enumerated type
+ into a plain unsigned type. */
+ if (TREE_TYPE (type) != 0)
+ dbxout_type_index (TREE_TYPE (type));
+ else
+ dbxout_type_index (type);
+
fprintf (asmfile, ";");
CHARS (1);
print_int_cst_octal (TYPE_MIN_VALUE (type));
@@ -1414,15 +1501,14 @@ dbxout_type (type, full)
break;
case COMPLEX_TYPE:
- /* Differs from the REAL_TYPE by its new data type number */
+ /* Differs from the REAL_TYPE by its new data type number.
+ R3 is NF_COMPLEX. We don't try to use any of the other NF_*
+ codes since gdb doesn't care anyway. */
if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
{
- putc ('R', asmfile);
- CHARS (1);
- dbxout_fptype_value (type);
- putc (';', asmfile);
- CHARS (1);
+ fputs ("R3;", asmfile);
+ CHARS (3);
print_wide_int (2 * int_size_in_bytes (TREE_TYPE (type)));
fputs (";0;", asmfile);
CHARS (3);
@@ -1584,15 +1670,21 @@ dbxout_type (type, full)
}
for (i = 0; i < n_baseclasses; i++)
{
- tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i);
+ tree binfo = TYPE_BINFO (type);
+ tree child = BINFO_BASETYPE (binfo, i);
+ tree access = (BINFO_BASEACCESSES (binfo)
+ ? BINFO_BASEACCESS (binfo, i) : access_public_node);
if (use_gnu_debug_info_extensions)
{
have_used_extensions = 1;
- putc (TREE_VIA_VIRTUAL (child) ? '1' : '0', asmfile);
- putc (TREE_VIA_PUBLIC (child) ? '2' : '0', asmfile);
+ putc (TREE_VIA_VIRTUAL (child) ? '1' : '0', asmfile);
+ putc (access == access_public_node ? '2' :
+ (access == access_protected_node ? '1' :'0'),
+ asmfile);
CHARS (2);
- if (TREE_VIA_VIRTUAL (child) && strcmp (lang_hooks.name, "GNU C++") == 0)
+ if (TREE_VIA_VIRTUAL (child)
+ && strcmp (lang_hooks.name, "GNU C++") == 0)
/* For a virtual base, print the (negative) offset within
the vtable where we must look to find the necessary
adjustment. */
@@ -1685,9 +1777,6 @@ dbxout_type (type, full)
CHARS (1);
return;
}
-#ifdef DBX_OUTPUT_ENUM
- DBX_OUTPUT_ENUM (asmfile, type);
-#else
if (use_gnu_debug_info_extensions
&& TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node))
{
@@ -1717,7 +1806,6 @@ dbxout_type (type, full)
putc (';', asmfile);
CHARS (1);
-#endif
break;
case POINTER_TYPE:
@@ -1782,12 +1870,44 @@ dbxout_type (type, full)
}
}
+/* Return nonzero if the given type represents an integer whose bounds
+ should be printed in octal format. */
+
+static bool
+print_int_cst_bounds_in_octal_p (tree type)
+{
+ /* 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
+ the bounds the usual way, write them in octal. Note the test is for
+ the *target's* size of "long", not that of the host. The host test
+ is just to make sure we can write it out in case the host wide int
+ is narrower than the target "long".
+
+ For unsigned types, we use octal if they are the same size or larger.
+ This is because we print the bounds as signed decimal, and hence they
+ 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
+ && (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)
+ || ((TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
+ && TREE_UNSIGNED (type))
+ || TYPE_PRECISION (type) > HOST_BITS_PER_WIDE_INT
+ || (TYPE_PRECISION (type) == HOST_BITS_PER_WIDE_INT
+ && TREE_UNSIGNED (type))))
+ return TRUE;
+ else
+ return FALSE;
+}
+
/* Print the value of integer constant C, in octal,
handling double precision. */
static void
-print_int_cst_octal (c)
- tree c;
+print_int_cst_octal (tree c)
{
unsigned HOST_WIDE_INT high = TREE_INT_CST_HIGH (c);
unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (c);
@@ -1832,9 +1952,7 @@ print_int_cst_octal (c)
}
static void
-print_octal (value, digits)
- unsigned HOST_WIDE_INT value;
- int digits;
+print_octal (unsigned HOST_WIDE_INT value, int digits)
{
int i;
@@ -1847,8 +1965,7 @@ print_octal (value, digits)
/* Output C in decimal while adjusting the number of digits written. */
static void
-print_wide_int (c)
- HOST_WIDE_INT c;
+print_wide_int (HOST_WIDE_INT c)
{
int digs = 0;
@@ -1868,8 +1985,7 @@ print_wide_int (c)
or by struct, enum and union tags. */
static void
-dbxout_type_name (type)
- tree type;
+dbxout_type_name (tree type)
{
tree t;
if (TYPE_NAME (type) == 0)
@@ -1893,19 +2009,20 @@ dbxout_type_name (type)
type whose scope is limited to a struct or class. */
static void
-dbxout_class_name_qualifiers (decl)
- tree decl;
+dbxout_class_name_qualifiers (tree decl)
{
tree context = decl_type_context (decl);
- if (context != NULL_TREE
+ if (context != NULL_TREE
&& TREE_CODE(context) == RECORD_TYPE
- && TYPE_NAME (context) != 0
+ && TYPE_NAME (context) != 0
&& (TREE_CODE (TYPE_NAME (context)) == IDENTIFIER_NODE
|| (DECL_NAME (TYPE_NAME (context)) != 0)))
{
tree name = TYPE_NAME (context);
+ emit_pending_bincls_if_required ();
+
if (TREE_CODE (name) == TYPE_DECL)
{
dbxout_class_name_qualifiers (name);
@@ -1923,24 +2040,77 @@ dbxout_class_name_qualifiers (decl)
Return 1 if a stabs might have been emitted. */
int
-dbxout_symbol (decl, local)
- tree decl;
- int local ATTRIBUTE_UNUSED;
+dbxout_symbol (tree decl, int local ATTRIBUTE_UNUSED)
{
tree type = TREE_TYPE (decl);
tree context = NULL_TREE;
int result = 0;
- /* Cast avoids warning in old compilers. */
- current_sym_code = (STAB_CODE_TYPE) 0;
- current_sym_value = 0;
- current_sym_addr = 0;
+ /* "Intercept" dbxout_symbol() calls like we do all debug_hooks. */
+ ++debug_nesting;
/* Ignore nameless syms, but don't ignore type tags. */
if ((DECL_NAME (decl) == 0 && TREE_CODE (decl) != TYPE_DECL)
|| DECL_IGNORED_P (decl))
- return 0;
+ DBXOUT_DECR_NESTING_AND_RETURN (0);
+
+ /* If we are to generate only the symbols actually used then such
+ symbol nodees are flagged with TREE_USED. Ignore any that
+ aren't flaged as TREE_USED. */
+
+ if (flag_debug_only_used_symbols)
+ {
+ tree t;
+
+ if (!TREE_USED (decl)
+ && (TREE_CODE (decl) != VAR_DECL || !DECL_INITIAL (decl)))
+ DBXOUT_DECR_NESTING_AND_RETURN (0);
+
+ /* We now have a used symbol. We need to generate the info for
+ the symbol's type in addition to the symbol itself. These
+ type symbols are queued to be generated after were done with
+ the symbol itself (done because the symbol's info is generated
+ with fprintf's, etc. as it determines what's needed).
+
+ Note, because the TREE_TYPE(type) might be something like a
+ pointer to a named type we need to look for the first name
+ we see following the TREE_TYPE chain. */
+
+ t = type;
+ while (POINTER_TYPE_P (t))
+ t = TREE_TYPE (t);
+
+ /* RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE, and ENUMERAL_TYPE
+ need special treatment. The TYPE_STUB_DECL field in these
+ types generally represents the tag name type we want to
+ output. In addition there could be a typedef type with
+ a different name. In that case we also want to output
+ that. */
+
+ if ((TREE_CODE (t) == RECORD_TYPE
+ || TREE_CODE (t) == UNION_TYPE
+ || TREE_CODE (t) == QUAL_UNION_TYPE
+ || TREE_CODE (t) == ENUMERAL_TYPE)
+ && TYPE_STUB_DECL (t)
+ && TYPE_STUB_DECL (t) != decl
+ && TREE_CODE_CLASS (TREE_CODE (TYPE_STUB_DECL (t))) == 'd'
+ && ! DECL_IGNORED_P (TYPE_STUB_DECL (t)))
+ {
+ debug_queue_symbol (TYPE_STUB_DECL (t));
+ if (TYPE_NAME (t)
+ && TYPE_NAME (t) != TYPE_STUB_DECL (t)
+ && TYPE_NAME (t) != decl
+ && TREE_CODE_CLASS (TREE_CODE (TYPE_NAME (t))) == 'd')
+ debug_queue_symbol (TYPE_NAME (t));
+ }
+ else if (TYPE_NAME (t)
+ && TYPE_NAME (t) != decl
+ && TREE_CODE_CLASS (TREE_CODE (TYPE_NAME (t))) == 'd')
+ debug_queue_symbol (TYPE_NAME (t));
+ }
+
+ emit_pending_bincls_if_required ();
dbxout_prepare_symbol (decl);
@@ -1958,7 +2128,7 @@ dbxout_symbol (decl, local)
case FUNCTION_DECL:
if (DECL_RTL (decl) == 0)
- return 0;
+ DBXOUT_DECR_NESTING_AND_RETURN (0);
if (DECL_EXTERNAL (decl))
break;
/* Don't mention a nested function under its parent. */
@@ -1995,22 +2165,10 @@ dbxout_symbol (decl, local)
break;
case TYPE_DECL:
-#if 0
- /* This seems all wrong. Outputting most kinds of types gives no name
- at all. A true definition gives no name; a cross-ref for a
- structure can give the tag name, but not a type name.
- It seems that no typedef name is defined by outputting a type. */
-
- /* If this typedef name was defined by outputting the type,
- don't duplicate it. */
- if (typevec[TYPE_SYMTAB_ADDRESS (type)].status == TYPE_DEFINED
- && TYPE_NAME (TREE_TYPE (decl)) == decl)
- return 0;
-#endif
/* Don't output the same typedef twice.
And don't output what language-specific stuff doesn't want output. */
if (TREE_ASM_WRITTEN (decl) || TYPE_DECL_SUPPRESS_DEBUG (decl))
- return 0;
+ DBXOUT_DECR_NESTING_AND_RETURN (0);
FORCE_TEXT;
result = 1;
@@ -2036,6 +2194,8 @@ dbxout_symbol (decl, local)
/* Distinguish the implicit typedefs of C++
from explicit ones that might be found in C. */
&& DECL_ARTIFICIAL (decl)
+ /* Do not generate a tag for incomplete records. */
+ && COMPLETE_TYPE_P (type)
/* Do not generate a tag for records of variable size,
since this type can not be properly described in the
DBX format, and it confuses some tools such as objdump. */
@@ -2157,7 +2317,7 @@ dbxout_symbol (decl, local)
/* Named return value, treat like a VAR_DECL. */
case VAR_DECL:
if (! DECL_RTL_SET_P (decl))
- return 0;
+ DBXOUT_DECR_NESTING_AND_RETURN (0);
/* Don't mention a variable that is external.
Let the file that defines it describe it. */
if (DECL_EXTERNAL (decl))
@@ -2181,19 +2341,15 @@ dbxout_symbol (decl, local)
|| TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
{
HOST_WIDE_INT ival = tree_low_cst (DECL_INITIAL (decl), 0);
-#ifdef DBX_OUTPUT_CONSTANT_SYMBOL
- DBX_OUTPUT_CONSTANT_SYMBOL (asmfile, name, ival);
-#else
- fprintf (asmfile, "%s\"%s:c=i", ASM_STABS_OP, name);
-
- fprintf (asmfile, HOST_WIDE_INT_PRINT_DEC, ival);
- fprintf (asmfile, "\",0x%x,0,0,0\n", N_LSYM);
-#endif
+ fprintf (asmfile, "%s\"%s:c=i" HOST_WIDE_INT_PRINT_DEC
+ "\",0x%x,0,0,0\n",
+ ASM_STABS_OP, name, ival, N_LSYM);
+ DBXOUT_DECR_NESTING;
return 1;
}
else if (TREE_CODE (TREE_TYPE (decl)) == REAL_TYPE)
{
- /* don't know how to do this yet. */
+ /* Don't know how to do this yet. */
}
break;
}
@@ -2212,6 +2368,7 @@ dbxout_symbol (decl, local)
default:
break;
}
+ DBXOUT_DECR_NESTING;
return result;
}
@@ -2222,14 +2379,13 @@ dbxout_symbol (decl, local)
Returns 1 if the stab was really emitted. */
static int
-dbxout_symbol_location (decl, type, suffix, home)
- tree decl, type;
- const char *suffix;
- rtx home;
+dbxout_symbol_location (tree decl, tree type, const char *suffix, rtx home)
{
int letter = 0;
int regno = -1;
+ emit_pending_bincls_if_required ();
+
/* Don't mention a variable at all
if it was completely optimized into nothingness.
@@ -2305,11 +2461,27 @@ dbxout_symbol_location (decl, type, suffix, home)
if (GET_CODE (current_sym_addr) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (current_sym_addr))
{
- rtx tmp = get_pool_constant (current_sym_addr);
+ bool marked;
+ rtx tmp = get_pool_constant_mark (current_sym_addr, &marked);
+
+ if (GET_CODE (tmp) == SYMBOL_REF)
+ {
+ current_sym_addr = tmp;
+ if (CONSTANT_POOL_ADDRESS_P (current_sym_addr))
+ get_pool_constant_mark (current_sym_addr, &marked);
+ else
+ marked = true;
+ }
+ else if (GET_CODE (tmp) == LABEL_REF)
+ {
+ current_sym_addr = tmp;
+ marked = true;
+ }
- if (GET_CODE (tmp) == SYMBOL_REF
- || GET_CODE (tmp) == LABEL_REF)
- current_sym_addr = tmp;
+ /* If all references to the constant pool were optimized
+ out, we just ignore the symbol. */
+ if (!marked)
+ return 0;
}
/* Ultrix `as' seems to need this. */
@@ -2419,10 +2591,6 @@ dbxout_symbol_location (decl, type, suffix, home)
else
dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 0));
- /* Cast avoids warning in old compilers. */
- current_sym_code = (STAB_CODE_TYPE) 0;
- current_sym_value = 0;
- current_sym_addr = 0;
dbxout_prepare_symbol (decl);
if (WORDS_BIG_ENDIAN)
@@ -2458,16 +2626,15 @@ dbxout_symbol_location (decl, type, suffix, home)
Then output LETTER to indicate the kind of location the symbol has. */
static void
-dbxout_symbol_name (decl, suffix, letter)
- tree decl;
- const char *suffix;
- int letter;
+dbxout_symbol_name (tree decl, const char *suffix, int letter)
{
const char *name;
- if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
- /* One slight hitch: if this is a VAR_DECL which is a static
- class member, we must put out the mangled name instead of the
+ if (DECL_CONTEXT (decl)
+ && (TYPE_P (DECL_CONTEXT (decl))
+ || TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL))
+ /* One slight hitch: if this is a VAR_DECL which is a class member
+ or a namespace member, we must put out the mangled name instead of the
DECL_NAME. Note also that static member (variable) names DO NOT begin
with underscores in .stabs directives. */
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
@@ -2486,19 +2653,25 @@ dbxout_symbol_name (decl, suffix, letter)
}
static void
-dbxout_prepare_symbol (decl)
- tree decl ATTRIBUTE_UNUSED;
+dbxout_prepare_symbol (tree decl ATTRIBUTE_UNUSED)
{
#ifdef WINNING_GDB
const char *filename = DECL_SOURCE_FILE (decl);
dbxout_source_file (asmfile, filename);
#endif
+
+ /* Initialize variables used to communicate each symbol's debug
+ information to dbxout_finish_symbol with zeroes. */
+
+ /* Cast avoids warning in old compilers. */
+ current_sym_code = (STAB_CODE_TYPE) 0;
+ current_sym_value = 0;
+ current_sym_addr = 0;
}
static void
-dbxout_finish_symbol (sym)
- tree sym;
+dbxout_finish_symbol (tree sym)
{
#ifdef DBX_FINISH_SYMBOL
DBX_FINISH_SYMBOL (sym);
@@ -2520,8 +2693,7 @@ dbxout_finish_symbol (sym)
anything was output */
int
-dbxout_syms (syms)
- tree syms;
+dbxout_syms (tree syms)
{
int result = 0;
while (syms)
@@ -2545,9 +2717,12 @@ dbxout_syms (syms)
of all the parms in PARMS, which is a chain of PARM_DECL nodes. */
void
-dbxout_parms (parms)
- tree parms;
+dbxout_parms (tree parms)
{
+ ++debug_nesting;
+
+ emit_pending_bincls_if_required ();
+
for (; parms; parms = TREE_CHAIN (parms))
if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node)
{
@@ -2805,6 +2980,7 @@ dbxout_parms (parms)
dbxout_finish_symbol (parms);
}
}
+ DBXOUT_DECR_NESTING;
}
/* Output definitions for the places where parms live during the function,
@@ -2819,9 +2995,10 @@ dbxout_parms (parms)
PARMS is a chain of PARM_DECL nodes. */
void
-dbxout_reg_parms (parms)
- tree parms;
+dbxout_reg_parms (tree parms)
{
+ ++debug_nesting;
+
for (; parms; parms = TREE_CHAIN (parms))
if (DECL_NAME (parms) && PARM_PASSED_IN_MEMORY (parms))
{
@@ -2842,14 +3019,14 @@ dbxout_reg_parms (parms)
dbxout_symbol_location (parms, TREE_TYPE (parms),
0, DECL_RTL (parms));
}
+ DBXOUT_DECR_NESTING;
}
/* Given a chain of ..._TYPE nodes (as come in a parameter list),
output definitions of those names, in raw form */
static void
-dbxout_args (args)
- tree args;
+dbxout_args (tree args)
{
while (args)
{
@@ -2878,10 +3055,7 @@ dbxout_args (args)
We handle them all in sequence. */
static void
-dbxout_block (block, depth, args)
- tree block;
- int depth;
- tree args;
+dbxout_block (tree block, int depth, tree args)
{
int blocknum = -1;
@@ -2900,9 +3074,6 @@ dbxout_block (block, depth, args)
{
int did_output;
-#ifdef DBX_LBRAC_FIRST
- did_output = 1;
-#else
/* In dbx format, the syms of a block come before the N_LBRAC.
If nothing is output, we don't need the N_LBRAC, either. */
did_output = 0;
@@ -2910,7 +3081,6 @@ dbxout_block (block, depth, args)
did_output = dbxout_syms (BLOCK_VARS (block));
if (args)
dbxout_reg_parms (args);
-#endif
/* Now output an N_LBRAC symbol to represent the beginning of
the block. Use the block's tree-walk order to generate
@@ -2928,14 +3098,10 @@ dbxout_block (block, depth, args)
tree decl = BLOCK_VARS (block);
while (decl)
{
-#ifdef DBX_OUTPUT_CATCH
- DBX_OUTPUT_CATCH (asmfile, decl, buf);
-#else
fprintf (asmfile, "%s\"%s:C1\",%d,0,0,", ASM_STABS_OP,
IDENTIFIER_POINTER (DECL_NAME (decl)), N_CATCH);
assemble_name (asmfile, buf);
fprintf (asmfile, "\n");
-#endif
decl = TREE_CHAIN (decl);
}
}
@@ -2953,15 +3119,6 @@ dbxout_block (block, depth, args)
#endif
}
-#ifdef DBX_LBRAC_FIRST
- /* On some weird machines, the syms of a block
- come after the N_LBRAC. */
- if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0)
- dbxout_syms (BLOCK_VARS (block));
- if (args)
- dbxout_reg_parms (args);
-#endif
-
/* Output the subblocks. */
dbxout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE);
@@ -2993,10 +3150,21 @@ dbxout_block (block, depth, args)
#if defined (DBX_DEBUGGING_INFO)
static void
-dbxout_begin_function (decl)
- tree decl;
+dbxout_begin_function (tree decl)
{
- dbxout_symbol (decl, 0);
+ int saved_tree_used1 = TREE_USED (decl);
+ TREE_USED (decl) = 1;
+ if (DECL_NAME (DECL_RESULT (decl)) != 0)
+ {
+ int saved_tree_used2 = TREE_USED (DECL_RESULT (decl));
+ TREE_USED (DECL_RESULT (decl)) = 1;
+ dbxout_symbol (decl, 0);
+ TREE_USED (DECL_RESULT (decl)) = saved_tree_used2;
+ }
+ else
+ dbxout_symbol (decl, 0);
+ TREE_USED (decl) = saved_tree_used1;
+
dbxout_parms (DECL_ARGUMENTS (decl));
if (DECL_NAME (DECL_RESULT (decl)) != 0)
dbxout_symbol (DECL_RESULT (decl), 1);
@@ -3004,3 +3172,5 @@ dbxout_begin_function (decl)
#endif /* DBX_DEBUGGING_INFO */
#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
+
+#include "gt-dbxout.h"
diff --git a/contrib/gcc/dbxout.h b/contrib/gcc/dbxout.h
index 101eae9d07c5..bf0e741fe457 100644
--- a/contrib/gcc/dbxout.h
+++ b/contrib/gcc/dbxout.h
@@ -1,5 +1,6 @@
/* dbxout.h - Various declarations for functions found in dbxout.c
- Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -18,7 +19,7 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-extern int dbxout_symbol PARAMS ((tree, int));
-extern void dbxout_parms PARAMS ((tree));
-extern void dbxout_reg_parms PARAMS ((tree));
-extern int dbxout_syms PARAMS ((tree));
+extern int dbxout_symbol (tree, int);
+extern void dbxout_parms (tree);
+extern void dbxout_reg_parms (tree);
+extern int dbxout_syms (tree);
diff --git a/contrib/gcc/debug.c b/contrib/gcc/debug.c
index 682f6ed1be30..e18ce55448c3 100644
--- a/contrib/gcc/debug.c
+++ b/contrib/gcc/debug.c
@@ -1,5 +1,5 @@
/* Do-nothing debug hooks for GCC.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003 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
@@ -17,6 +17,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "debug.h"
/* The do-nothing debug hooks. */
@@ -41,58 +43,52 @@ const struct gcc_debug_hooks do_nothing_debug_hooks =
debug_nothing_tree, /* global_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
- debug_nothing_rtx /* label */
+ debug_nothing_rtx, /* label */
+ debug_nothing_int /* handle_pch */
};
/* This file contains implementations of each debug hook that do
nothing. */
void
-debug_nothing_void ()
+debug_nothing_void (void)
{
}
void
-debug_nothing_tree (decl)
- tree decl ATTRIBUTE_UNUSED;
+debug_nothing_tree (tree decl ATTRIBUTE_UNUSED)
{
}
bool
-debug_true_tree (block)
- tree block ATTRIBUTE_UNUSED;
+debug_true_tree (tree block ATTRIBUTE_UNUSED)
{
return true;
}
void
-debug_nothing_rtx (insn)
- rtx insn ATTRIBUTE_UNUSED;
+debug_nothing_rtx (rtx insn ATTRIBUTE_UNUSED)
{
}
void
-debug_nothing_charstar (main_filename)
- const char *main_filename ATTRIBUTE_UNUSED;
+debug_nothing_charstar (const char *main_filename ATTRIBUTE_UNUSED)
{
}
void
-debug_nothing_int_charstar (line, text)
- unsigned int line ATTRIBUTE_UNUSED;
- const char *text ATTRIBUTE_UNUSED;
+debug_nothing_int_charstar (unsigned int line ATTRIBUTE_UNUSED,
+ const char *text ATTRIBUTE_UNUSED)
{
}
void
-debug_nothing_int (line)
- unsigned int line ATTRIBUTE_UNUSED;
+debug_nothing_int (unsigned int line ATTRIBUTE_UNUSED)
{
}
void
-debug_nothing_int_int (line, n)
- unsigned int line ATTRIBUTE_UNUSED;
- unsigned int n ATTRIBUTE_UNUSED;
+debug_nothing_int_int (unsigned int line ATTRIBUTE_UNUSED,
+ unsigned int n ATTRIBUTE_UNUSED)
{
}
diff --git a/contrib/gcc/debug.h b/contrib/gcc/debug.h
index 11c996fddd05..22d837835c62 100644
--- a/contrib/gcc/debug.h
+++ b/contrib/gcc/debug.h
@@ -1,5 +1,5 @@
/* Debug hooks for GCC.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003 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
@@ -25,103 +25,99 @@ struct gcc_debug_hooks
{
/* Initialize debug output. MAIN_FILENAME is the name of the main
input file. */
- void (* init) PARAMS ((const char *main_filename));
+ void (* init) (const char *main_filename);
/* Output debug symbols. */
- void (* finish) PARAMS ((const char *main_filename));
+ void (* finish) (const char *main_filename);
/* Macro defined on line LINE with name and expansion TEXT. */
- void (* define) PARAMS ((unsigned int line, const char *text));
+ void (* define) (unsigned int line, const char *text);
/* MACRO undefined on line LINE. */
- void (* undef) PARAMS ((unsigned int line, const char *macro));
+ void (* undef) (unsigned int line, const char *macro);
/* Record the beginning of a new source file FILE from LINE number
in the previous one. */
- void (* start_source_file) PARAMS ((unsigned int line, const char *file));
+ void (* start_source_file) (unsigned int line, const char *file);
/* Record the resumption of a source file. LINE is the line number
in the source file we are returning to. */
- void (* end_source_file) PARAMS ((unsigned int line));
+ void (* end_source_file) (unsigned int line);
/* Record the beginning of block N, counting from 1 and not
including the function-scope block, at LINE. */
- void (* begin_block) PARAMS ((unsigned int line, unsigned int n));
+ void (* begin_block) (unsigned int line, unsigned int n);
/* Record the end of a block. Arguments as for begin_block. */
- void (* end_block) PARAMS ((unsigned int line, unsigned int n));
+ void (* end_block) (unsigned int line, unsigned int n);
/* Returns nonzero if it is appropriate not to emit any debugging
information for BLOCK, because it doesn't contain any
instructions. This may not be the case for blocks containing
nested functions, since we may actually call such a function even
though the BLOCK information is messed up. Defaults to true. */
- bool (* ignore_block) PARAMS ((tree));
+ bool (* ignore_block) (tree);
/* Record a source file location at (FILE, LINE). */
- void (* source_line) PARAMS ((unsigned int line, const char *file));
+ void (* source_line) (unsigned int line, const char *file);
/* Called at start of prologue code. LINE is the first line in the
function. This has been given the same prototype as source_line,
so that the source_line hook can be substituted if appropriate. */
- void (* begin_prologue) PARAMS ((unsigned int line, const char *file));
+ void (* begin_prologue) (unsigned int line, const char *file);
/* Called at end of prologue code. LINE is the first line in the
function. */
- void (* end_prologue) PARAMS ((unsigned int line, const char *file));
+ void (* end_prologue) (unsigned int line, const char *file);
/* Record end of epilogue code. */
- void (* end_epilogue) PARAMS ((unsigned int line, const char *file));
+ void (* end_epilogue) (unsigned int line, const char *file);
/* Called at start of function DECL, before it is declared. */
- void (* begin_function) PARAMS ((tree decl));
+ void (* begin_function) (tree decl);
/* Record end of function. LINE is highest line number in function. */
- void (* end_function) PARAMS ((unsigned int line));
+ void (* end_function) (unsigned int line);
/* Debug information for a function DECL. This might include the
function name (a symbol), its parameters, and the block that
makes up the function's body, and the local variables of the
function. */
- void (* function_decl) PARAMS ((tree decl));
+ void (* function_decl) (tree decl);
/* Debug information for a global DECL. Called from toplev.c after
compilation proper has finished. */
- void (* global_decl) PARAMS ((tree decl));
+ void (* global_decl) (tree decl);
/* DECL is an inline function, whose body is present, but which is
not being output at this point. */
- void (* deferred_inline_function) PARAMS ((tree decl));
+ void (* deferred_inline_function) (tree decl);
/* DECL is an inline function which is about to be emitted out of
line. The hook is useful to, e.g., emit abstract debug info for
the inline before it gets mangled by optimization. */
- void (* outlining_inline_function) PARAMS ((tree decl));
+ void (* outlining_inline_function) (tree decl);
/* Called from final_scan_insn for any CODE_LABEL insn whose
LABEL_NAME is non-null. */
- void (* label) PARAMS ((rtx));
+ void (* label) (rtx);
+
+ /* Called after the start and before the end of writing a PCH file.
+ The parameter is 0 if after the start, 1 if before the end. */
+ void (* handle_pch) (unsigned int);
};
extern const struct gcc_debug_hooks *debug_hooks;
/* The do-nothing hooks. */
-extern void debug_nothing_void
- PARAMS ((void));
-extern void debug_nothing_charstar
- PARAMS ((const char *));
-extern void debug_nothing_int_charstar
- PARAMS ((unsigned int, const char *));
-extern void debug_nothing_int
- PARAMS ((unsigned int));
-extern void debug_nothing_int_int
- PARAMS ((unsigned int, unsigned int));
-extern void debug_nothing_tree
- PARAMS ((tree));
-extern bool debug_true_tree
- PARAMS ((tree));
-extern void debug_nothing_rtx
- PARAMS ((rtx));
+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 (unsigned int);
+extern void debug_nothing_int_int (unsigned int, unsigned int);
+extern void debug_nothing_tree (tree);
+extern bool debug_true_tree (tree);
+extern void debug_nothing_rtx (rtx);
/* Hooks for various debug formats. */
extern const struct gcc_debug_hooks do_nothing_debug_hooks;
@@ -134,12 +130,18 @@ extern const struct gcc_debug_hooks vmsdbg_debug_hooks;
/* Dwarf2 frame information. */
-extern void dwarf2out_begin_prologue PARAMS ((unsigned int, const char *));
-extern void dwarf2out_end_epilogue PARAMS ((unsigned int, const char *));
-extern void dwarf2out_frame_init PARAMS ((void));
-extern void dwarf2out_frame_finish PARAMS ((void));
+extern void dwarf2out_begin_prologue (unsigned int, const char *);
+extern void dwarf2out_end_epilogue (unsigned int, const char *);
+extern void dwarf2out_frame_init (void);
+extern void dwarf2out_frame_finish (void);
/* Decide whether we want to emit frame unwind information for the current
translation unit. */
-extern int dwarf2out_do_frame PARAMS ((void));
+extern int dwarf2out_do_frame (void);
+
+extern void debug_flush_symbol_queue (void);
+extern void debug_queue_symbol (tree);
+extern void debug_free_queue (void);
+extern int debug_nesting;
+extern int symbol_queue_index;
#endif /* !GCC_DEBUG_H */
diff --git a/contrib/gcc/defaults.h b/contrib/gcc/defaults.h
index 0c71996c4205..fff782f21bad 100644
--- a/contrib/gcc/defaults.h
+++ b/contrib/gcc/defaults.h
@@ -1,5 +1,5 @@
/* Definitions of various defaults for tm.h macros.
- Copyright (C) 1992, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1992, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@monkeys.com)
@@ -27,8 +27,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define GET_ENVIRONMENT(VALUE, NAME) do { (VALUE) = getenv (NAME); } while (0)
#endif
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
+#define obstack_chunk_alloc ((void *(*) (long)) xmalloc)
+#define obstack_chunk_free ((void (*) (void *)) free)
+#define OBSTACK_CHUNK_SIZE 0
+#define gcc_obstack_init(OBSTACK) \
+ _obstack_begin ((OBSTACK), OBSTACK_CHUNK_SIZE, 0, \
+ obstack_chunk_alloc, \
+ obstack_chunk_free)
/* Define default standard character escape sequences. */
#ifndef TARGET_BELL
@@ -42,33 +47,27 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
# define TARGET_ESC 033
#endif
-/* When removal of CPP_PREDEFINES is complete, TARGET_CPU_CPP_BULITINS
- can also be removed from here. */
-#ifndef TARGET_OS_CPP_BUILTINS
-# define TARGET_OS_CPP_BUILTINS()
-#endif
-#ifndef TARGET_CPU_CPP_BUILTINS
-# define TARGET_CPU_CPP_BUILTINS()
-#endif
-#ifndef CPP_PREDEFINES
-# define CPP_PREDEFINES ""
-#endif
-
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable or function named NAME.
+/* Store in OUTPUT a string (made with alloca) containing an
+ assembler-name for a local static variable or function named NAME.
LABELNO is an integer which is different for each call. */
+#ifndef ASM_PN_FORMAT
+# ifndef NO_DOT_IN_LABEL
+# define ASM_PN_FORMAT "%s.%lu"
+# else
+# ifndef NO_DOLLAR_IN_LABEL
+# define ASM_PN_FORMAT "%s$%lu"
+# else
+# define ASM_PN_FORMAT "__%s_%lu"
+# endif
+# endif
+#endif /* ! ASM_PN_FORMAT */
+
#ifndef ASM_FORMAT_PRIVATE_NAME
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
- do { \
- int len = strlen (NAME); \
- char *temp = (char *) alloca (len + 3); \
- temp[0] = 'L'; \
- strcpy (&temp[1], (NAME)); \
- temp[len + 1] = '.'; \
- temp[len + 2] = 0; \
- (OUTPUT) = (char *) alloca (strlen (NAME) + 11); \
- ASM_GENERATE_INTERNAL_LABEL (OUTPUT, temp, LABELNO); \
+# define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
+ do { const char *const name_ = (NAME); \
+ char *const output_ = (OUTPUT) = alloca (strlen (name_) + 32);\
+ sprintf (output_, ASM_PN_FORMAT, name_, (unsigned long)(LABELNO)); \
} while (0)
#endif
@@ -82,12 +81,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef ASM_OUTPUT_ADDR_VEC_ELT
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
do { fputs (integer_asm_op (POINTER_SIZE / UNITS_PER_WORD, TRUE), FILE); \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, "L", (VALUE)); \
+ (*targetm.asm_out.internal_label) (FILE, "L", (VALUE)); \
fputc ('\n', FILE); \
} while (0)
#endif
-/* choose a reasonable default for ASM_OUTPUT_ASCII. */
+/* Choose a reasonable default for ASM_OUTPUT_ASCII. */
#ifndef ASM_OUTPUT_ASCII
#define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
@@ -160,7 +159,7 @@ do { fputs (integer_asm_op (POINTER_SIZE / UNITS_PER_WORD, TRUE), FILE); \
#ifndef ASM_OUTPUT_DEBUG_LABEL
#define ASM_OUTPUT_DEBUG_LABEL(FILE, PREFIX, NUM) \
- ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM)
+ (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM)
#endif
/* This is how we tell the assembler that a symbol is weak. */
@@ -202,9 +201,7 @@ do { fputs (integer_asm_op (POINTER_SIZE / UNITS_PER_WORD, TRUE), FILE); \
HOST_WIDE_INT size_ = (SIZE); \
fputs (SIZE_ASM_OP, STREAM); \
assemble_name (STREAM, NAME); \
- fputs (", ", STREAM); \
- fprintf (STREAM, HOST_WIDE_INT_PRINT_DEC, size_); \
- putc ('\n', STREAM); \
+ fprintf (STREAM, ", " HOST_WIDE_INT_PRINT_DEC "\n", size_); \
} \
while (0)
@@ -385,23 +382,10 @@ do { fputs (integer_asm_op (POINTER_SIZE / UNITS_PER_WORD, TRUE), FILE); \
#define POINTER_SIZE BITS_PER_WORD
#endif
-#ifndef BUILD_VA_LIST_TYPE
-#define BUILD_VA_LIST_TYPE(X) ((X) = ptr_type_node)
-#endif
-
#ifndef PIC_OFFSET_TABLE_REGNUM
#define PIC_OFFSET_TABLE_REGNUM INVALID_REGNUM
#endif
-/* Type used by GCOV counters. Use 64bit data type if target supports
- it. */
-#if LONG_TYPE_SIZE >= 64
-#define GCOV_TYPE_SIZE LONG_TYPE_SIZE
-#else
-#define GCOV_TYPE_SIZE LONG_LONG_TYPE_SIZE
-#endif
-
-
/* By default, the preprocessor should be invoked the same way in C++
as in C. */
#ifndef CPLUSPLUS_CPP_SPEC
@@ -423,6 +407,26 @@ do { fputs (integer_asm_op (POINTER_SIZE / UNITS_PER_WORD, TRUE), FILE); \
#endif
#endif
+/* Decide whether a function's arguments should be processed
+ from first to last or from last to first.
+
+ They should if the stack and args grow in opposite directions, but
+ only if we have push insns. */
+
+#ifdef PUSH_ROUNDING
+
+#ifndef PUSH_ARGS_REVERSED
+#if defined (STACK_GROWS_DOWNWARD) != defined (ARGS_GROW_DOWNWARD)
+#define PUSH_ARGS_REVERSED PUSH_ARGS
+#endif
+#endif
+
+#endif
+
+#ifndef PUSH_ARGS_REVERSED
+#define PUSH_ARGS_REVERSED 0
+#endif
+
/* If PREFERRED_STACK_BOUNDARY is not defined, set it to STACK_BOUNDARY.
STACK_BOUNDARY is required. */
#ifndef PREFERRED_STACK_BOUNDARY
@@ -481,7 +485,7 @@ do { fputs (integer_asm_op (POINTER_SIZE / UNITS_PER_WORD, TRUE), FILE); \
PREFERRED_DEBUGGING_TYPE to choose a format in a system-dependent way.
This is one long line cause VAXC can't handle a \-newline. */
-#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO) + defined (VMS_DEBUGGING_INFO))
+#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO) + defined (VMS_DEBUGGING_INFO))
#ifndef PREFERRED_DEBUGGING_TYPE
You Lose! You must define PREFERRED_DEBUGGING_TYPE!
#endif /* no PREFERRED_DEBUGGING_TYPE */
@@ -566,9 +570,12 @@ You Lose! You must define PREFERRED_DEBUGGING_TYPE!
&& !ROUND_TOWARDS_ZERO)
#endif
-/* If FLOAT_WORDS_BIG_ENDIAN and HOST_FLOAT_WORDS_BIG_ENDIAN are not defined
- in the header files, then this implies the word-endianness is the same as
- for integers. */
+#ifndef FLOAT_LIB_COMPARE_RETURNS_BOOL
+#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) false
+#endif
+
+/* If FLOAT_WORDS_BIG_ENDIAN is not defined in the header files,
+ then the word-endianness is the same as for integers. */
#ifndef FLOAT_WORDS_BIG_ENDIAN
#define FLOAT_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
#endif
@@ -598,13 +605,89 @@ You Lose! You must define PREFERRED_DEBUGGING_TYPE!
/* Determine whether extra constraint letter should be handled
via address reload (like 'o'). */
#ifndef EXTRA_MEMORY_CONSTRAINT
-#define EXTRA_MEMORY_CONSTRAINT(C) 0
+#define EXTRA_MEMORY_CONSTRAINT(C,STR) 0
#endif
/* Determine whether extra constraint letter should be handled
as an address (like 'p'). */
#ifndef EXTRA_ADDRESS_CONSTRAINT
-#define EXTRA_ADDRESS_CONSTRAINT(C) 0
+#define EXTRA_ADDRESS_CONSTRAINT(C,STR) 0
+#endif
+
+/* When a port defines CONSTRAINT_LEN, it should use DEFAULT_CONSTRAINT_LEN
+ for all the characters that it does not want to change, so things like the
+ 'length' of a digit in a matching constraint is an implementation detail,
+ and not part of the interface. */
+#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
+
+#ifndef CONSTRAINT_LEN
+#define CONSTRAINT_LEN(C,STR) DEFAULT_CONSTRAINT_LEN (C, STR)
+#endif
+
+#if defined (CONST_OK_FOR_LETTER_P) && ! defined (CONST_OK_FOR_CONSTRAINT_P)
+#define CONST_OK_FOR_CONSTRAINT_P(VAL,C,STR) CONST_OK_FOR_LETTER_P (VAL, C)
+#endif
+
+#if defined (CONST_DOUBLE_OK_FOR_LETTER_P) && ! defined (CONST_DOUBLE_OK_FOR_CONSTRAINT_P)
+#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(OP,C,STR) \
+ CONST_DOUBLE_OK_FOR_LETTER_P (OP, C)
+#endif
+
+#ifndef REG_CLASS_FROM_CONSTRAINT
+#define REG_CLASS_FROM_CONSTRAINT(C,STR) REG_CLASS_FROM_LETTER (C)
+#endif
+
+#if defined (EXTRA_CONSTRAINT) && ! defined (EXTRA_CONSTRAINT_STR)
+#define EXTRA_CONSTRAINT_STR(OP, C,STR) EXTRA_CONSTRAINT (OP, C)
+#endif
+
+#ifndef REGISTER_MOVE_COST
+#define REGISTER_MOVE_COST(m, x, y) 2
+#endif
+
+/* Determine whether the the entire c99 runtime
+ is present in the runtime library. */
+#ifndef TARGET_C99_FUNCTIONS
+#define TARGET_C99_FUNCTIONS 0
+#endif
+
+/* Indicate that CLZ and CTZ are undefined at zero. */
+#ifndef CLZ_DEFINED_VALUE_AT_ZERO
+#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) 0
+#endif
+#ifndef CTZ_DEFINED_VALUE_AT_ZERO
+#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) 0
+#endif
+
+/* Provide a default value for STORE_FLAG_VALUE. */
+#ifndef STORE_FLAG_VALUE
+#define STORE_FLAG_VALUE 1
+#endif
+
+/* This macro is used to determine what the largest unit size that
+ move_by_pieces can use is. */
+
+/* MOVE_MAX_PIECES is the number of bytes at a time which we can
+ move efficiently, as opposed to MOVE_MAX which is the maximum
+ number of bytes we can move with a single instruction. */
+
+#ifndef MOVE_MAX_PIECES
+#define MOVE_MAX_PIECES MOVE_MAX
+#endif
+
+#ifndef STACK_POINTER_OFFSET
+#define STACK_POINTER_OFFSET 0
+#endif
+
+#ifndef LOCAL_REGNO
+#define LOCAL_REGNO(REGNO) 0
+#endif
+
+/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
+ the stack pointer does not matter. The value is tested only in
+ functions that have frame pointers. */
+#ifndef EXIT_IGNORE_STACK
+#define EXIT_IGNORE_STACK 0
#endif
#endif /* ! GCC_DEFAULTS_H */
diff --git a/contrib/gcc/demangle.h b/contrib/gcc/demangle.h
index bff266931c81..6e995e4817d8 100644
--- a/contrib/gcc/demangle.h
+++ b/contrib/gcc/demangle.h
@@ -1,6 +1,6 @@
/* Defs for interface to demanglers.
- Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002
- Free Software Foundation, Inc.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002,
+ 2003, 2004 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
@@ -21,7 +21,7 @@
#if !defined (DEMANGLE_H)
#define DEMANGLE_H
-#include "ansidecl.h"
+#include "libiberty.h"
#ifdef __cplusplus
extern "C" {
@@ -164,6 +164,368 @@ enum gnu_v3_dtor_kinds {
extern enum gnu_v3_dtor_kinds
is_gnu_v3_mangled_dtor PARAMS ((const char *name));
+/* The V3 demangler works in two passes. The first pass builds a tree
+ representation of the mangled name, and the second pass turns the
+ tree representation into a demangled string. Here we define an
+ interface to permit a caller to build their own tree
+ representation, which they can pass to the demangler to get a
+ demangled string. This can be used to canonicalize user input into
+ something which the demangler might output. It could also be used
+ by other demanglers in the future. */
+
+/* These are the component types which may be found in the tree. Many
+ component types have one or two subtrees, referred to as left and
+ right (a component type with only one subtree puts it in the left
+ subtree). */
+
+enum demangle_component_type
+{
+ /* A name, with a length and a pointer to a string. */
+ DEMANGLE_COMPONENT_NAME,
+ /* A qualified name. The left subtree is a class or namespace or
+ some such thing, and the right subtree is a name qualified by
+ that class. */
+ DEMANGLE_COMPONENT_QUAL_NAME,
+ /* A local name. The left subtree describes a function, and the
+ right subtree is a name which is local to that function. */
+ DEMANGLE_COMPONENT_LOCAL_NAME,
+ /* A typed name. The left subtree is a name, and the right subtree
+ describes that name as a function. */
+ DEMANGLE_COMPONENT_TYPED_NAME,
+ /* A template. The left subtree is a template name, and the right
+ subtree is a template argument list. */
+ DEMANGLE_COMPONENT_TEMPLATE,
+ /* A template parameter. This holds a number, which is the template
+ parameter index. */
+ DEMANGLE_COMPONENT_TEMPLATE_PARAM,
+ /* A constructor. This holds a name and the kind of
+ constructor. */
+ DEMANGLE_COMPONENT_CTOR,
+ /* A destructor. This holds a name and the kind of destructor. */
+ DEMANGLE_COMPONENT_DTOR,
+ /* A vtable. This has one subtree, the type for which this is a
+ vtable. */
+ DEMANGLE_COMPONENT_VTABLE,
+ /* A VTT structure. This has one subtree, the type for which this
+ is a VTT. */
+ DEMANGLE_COMPONENT_VTT,
+ /* A construction vtable. The left subtree is the type for which
+ this is a vtable, and the right subtree is the derived type for
+ which this vtable is built. */
+ DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE,
+ /* A typeinfo structure. This has one subtree, the type for which
+ this is the tpeinfo structure. */
+ DEMANGLE_COMPONENT_TYPEINFO,
+ /* A typeinfo name. This has one subtree, the type for which this
+ is the typeinfo name. */
+ DEMANGLE_COMPONENT_TYPEINFO_NAME,
+ /* A typeinfo function. This has one subtree, the type for which
+ this is the tpyeinfo function. */
+ DEMANGLE_COMPONENT_TYPEINFO_FN,
+ /* A thunk. This has one subtree, the name for which this is a
+ thunk. */
+ DEMANGLE_COMPONENT_THUNK,
+ /* A virtual thunk. This has one subtree, the name for which this
+ is a virtual thunk. */
+ DEMANGLE_COMPONENT_VIRTUAL_THUNK,
+ /* A covariant thunk. This has one subtree, the name for which this
+ is a covariant thunk. */
+ DEMANGLE_COMPONENT_COVARIANT_THUNK,
+ /* A Java class. This has one subtree, the type. */
+ DEMANGLE_COMPONENT_JAVA_CLASS,
+ /* A guard variable. This has one subtree, the name for which this
+ is a guard variable. */
+ DEMANGLE_COMPONENT_GUARD,
+ /* A reference temporary. This has one subtree, the name for which
+ this is a temporary. */
+ DEMANGLE_COMPONENT_REFTEMP,
+ /* A standard substitution. This holds the name of the
+ substitution. */
+ DEMANGLE_COMPONENT_SUB_STD,
+ /* The restrict qualifier. The one subtree is the type which is
+ being qualified. */
+ DEMANGLE_COMPONENT_RESTRICT,
+ /* The volatile qualifier. The one subtree is the type which is
+ being qualified. */
+ DEMANGLE_COMPONENT_VOLATILE,
+ /* The const qualifier. The one subtree is the type which is being
+ qualified. */
+ DEMANGLE_COMPONENT_CONST,
+ /* The restrict qualifier modifying a member function. The one
+ subtree is the type which is being qualified. */
+ DEMANGLE_COMPONENT_RESTRICT_THIS,
+ /* The volatile qualifier modifying a member function. The one
+ subtree is the type which is being qualified. */
+ DEMANGLE_COMPONENT_VOLATILE_THIS,
+ /* The const qualifier modifying a member function. The one subtree
+ is the type which is being qualified. */
+ DEMANGLE_COMPONENT_CONST_THIS,
+ /* A vendor qualifier. The left subtree is the type which is being
+ qualified, and the right subtree is the name of the
+ qualifier. */
+ DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
+ /* A pointer. The one subtree is the type which is being pointed
+ to. */
+ DEMANGLE_COMPONENT_POINTER,
+ /* A reference. The one subtree is the type which is being
+ referenced. */
+ DEMANGLE_COMPONENT_REFERENCE,
+ /* A complex type. The one subtree is the base type. */
+ DEMANGLE_COMPONENT_COMPLEX,
+ /* An imaginary type. The one subtree is the base type. */
+ DEMANGLE_COMPONENT_IMAGINARY,
+ /* A builtin type. This holds the builtin type information. */
+ DEMANGLE_COMPONENT_BUILTIN_TYPE,
+ /* A vendor's builtin type. This holds the name of the type. */
+ DEMANGLE_COMPONENT_VENDOR_TYPE,
+ /* A function type. The left subtree is the return type. The right
+ subtree is a list of ARGLIST nodes. Either or both may be
+ NULL. */
+ DEMANGLE_COMPONENT_FUNCTION_TYPE,
+ /* An array type. The left subtree is the dimension, which may be
+ NULL, or a string (represented as DEMANGLE_COMPONENT_NAME), or an
+ expression. The right subtree is the element type. */
+ DEMANGLE_COMPONENT_ARRAY_TYPE,
+ /* A pointer to member type. The left subtree is the class type,
+ and the right subtree is the member type. CV-qualifiers appear
+ on the latter. */
+ DEMANGLE_COMPONENT_PTRMEM_TYPE,
+ /* An argument list. The left subtree is the current argument, and
+ the right subtree is either NULL or another ARGLIST node. */
+ DEMANGLE_COMPONENT_ARGLIST,
+ /* A template argument list. The left subtree is the current
+ template argument, and the right subtree is either NULL or
+ another TEMPLATE_ARGLIST node. */
+ DEMANGLE_COMPONENT_TEMPLATE_ARGLIST,
+ /* An operator. This holds information about a standard
+ operator. */
+ DEMANGLE_COMPONENT_OPERATOR,
+ /* An extended operator. This holds the number of arguments, and
+ the name of the extended operator. */
+ DEMANGLE_COMPONENT_EXTENDED_OPERATOR,
+ /* A typecast, represented as a unary operator. The one subtree is
+ the type to which the argument should be cast. */
+ DEMANGLE_COMPONENT_CAST,
+ /* A unary expression. The left subtree is the operator, and the
+ right subtree is the single argument. */
+ DEMANGLE_COMPONENT_UNARY,
+ /* A binary expression. The left subtree is the operator, and the
+ right subtree is a BINARY_ARGS. */
+ DEMANGLE_COMPONENT_BINARY,
+ /* Arguments to a binary expression. The left subtree is the first
+ argument, and the right subtree is the second argument. */
+ DEMANGLE_COMPONENT_BINARY_ARGS,
+ /* A trinary expression. The left subtree is the operator, and the
+ right subtree is a TRINARY_ARG1. */
+ DEMANGLE_COMPONENT_TRINARY,
+ /* Arguments to a trinary expression. The left subtree is the first
+ argument, and the right subtree is a TRINARY_ARG2. */
+ DEMANGLE_COMPONENT_TRINARY_ARG1,
+ /* More arguments to a trinary expression. The left subtree is the
+ second argument, and the right subtree is the third argument. */
+ DEMANGLE_COMPONENT_TRINARY_ARG2,
+ /* A literal. The left subtree is the type, and the right subtree
+ is the value, represented as a DEMANGLE_COMPONENT_NAME. */
+ DEMANGLE_COMPONENT_LITERAL,
+ /* A negative literal. Like LITERAL, but the value is negated.
+ This is a minor hack: the NAME used for LITERAL points directly
+ to the mangled string, but since negative numbers are mangled
+ using 'n' instead of '-', we want a way to indicate a negative
+ number which involves neither modifying the mangled string nor
+ allocating a new copy of the literal in memory. */
+ DEMANGLE_COMPONENT_LITERAL_NEG
+};
+
+/* Types which are only used internally. */
+
+struct demangle_operator_info;
+struct demangle_builtin_type_info;
+
+/* A node in the tree representation is an instance of a struct
+ demangle_component. Note that the field names of the struct are
+ not well protected against macros defined by the file including
+ this one. We can fix this if it ever becomes a problem. */
+
+struct demangle_component
+{
+ /* The type of this component. */
+ enum demangle_component_type type;
+
+ union
+ {
+ /* For DEMANGLE_COMPONENT_NAME. */
+ struct
+ {
+ /* A pointer to the name (which need not NULL terminated) and
+ its length. */
+ const char *s;
+ int len;
+ } s_name;
+
+ /* For DEMANGLE_COMPONENT_OPERATOR. */
+ struct
+ {
+ /* Operator. */
+ const struct demangle_operator_info *op;
+ } s_operator;
+
+ /* For DEMANGLE_COMPONENT_EXTENDED_OPERATOR. */
+ struct
+ {
+ /* Number of arguments. */
+ int args;
+ /* Name. */
+ struct demangle_component *name;
+ } s_extended_operator;
+
+ /* For DEMANGLE_COMPONENT_CTOR. */
+ struct
+ {
+ /* Kind of constructor. */
+ enum gnu_v3_ctor_kinds kind;
+ /* Name. */
+ struct demangle_component *name;
+ } s_ctor;
+
+ /* For DEMANGLE_COMPONENT_DTOR. */
+ struct
+ {
+ /* Kind of destructor. */
+ enum gnu_v3_dtor_kinds kind;
+ /* Name. */
+ struct demangle_component *name;
+ } s_dtor;
+
+ /* For DEMANGLE_COMPONENT_BUILTIN_TYPE. */
+ struct
+ {
+ /* Builtin type. */
+ const struct demangle_builtin_type_info *type;
+ } s_builtin;
+
+ /* For DEMANGLE_COMPONENT_SUB_STD. */
+ struct
+ {
+ /* Standard substitution string. */
+ const char* string;
+ /* Length of string. */
+ int len;
+ } s_string;
+
+ /* For DEMANGLE_COMPONENT_TEMPLATE_PARAM. */
+ struct
+ {
+ /* Template parameter index. */
+ long number;
+ } s_number;
+
+ /* For other types. */
+ struct
+ {
+ /* Left (or only) subtree. */
+ struct demangle_component *left;
+ /* Right subtree. */
+ struct demangle_component *right;
+ } s_binary;
+
+ } u;
+};
+
+/* People building mangled trees are expected to allocate instances of
+ struct demangle_component themselves. They can then call one of
+ the following functions to fill them in. */
+
+/* Fill in most component types with a left subtree and a right
+ subtree. Returns non-zero on success, zero on failure, such as an
+ unrecognized or inappropriate component type. */
+
+extern int
+cplus_demangle_fill_component PARAMS ((struct demangle_component *fill,
+ enum demangle_component_type,
+ struct demangle_component *left,
+ struct demangle_component *right));
+
+/* Fill in a DEMANGLE_COMPONENT_NAME. Returns non-zero on success,
+ zero for bad arguments. */
+
+extern int
+cplus_demangle_fill_name PARAMS ((struct demangle_component *fill,
+ const char *, int));
+
+/* Fill in a DEMANGLE_COMPONENT_BUILTIN_TYPE, using the name of the
+ builtin type (e.g., "int", etc.). Returns non-zero on success,
+ zero if the type is not recognized. */
+
+extern int
+cplus_demangle_fill_builtin_type PARAMS ((struct demangle_component *fill,
+ const char *typename));
+
+/* Fill in a DEMANGLE_COMPONENT_OPERATOR, using the name of the
+ operator and the number of arguments which it takes (the latter is
+ used to disambiguate operators which can be both binary and unary,
+ such as '-'). Returns non-zero on success, zero if the operator is
+ not recognized. */
+
+extern int
+cplus_demangle_fill_operator PARAMS ((struct demangle_component *fill,
+ const char *opname, int args));
+
+/* Fill in a DEMANGLE_COMPONENT_EXTENDED_OPERATOR, providing the
+ number of arguments and the name. Returns non-zero on success,
+ zero for bad arguments. */
+
+extern int
+cplus_demangle_fill_extended_operator PARAMS ((struct demangle_component *fill,
+ int numargs,
+ struct demangle_component *nm));
+
+/* Fill in a DEMANGLE_COMPONENT_CTOR. Returns non-zero on success,
+ zero for bad arguments. */
+
+extern int
+cplus_demangle_fill_ctor PARAMS ((struct demangle_component *fill,
+ enum gnu_v3_ctor_kinds kind,
+ struct demangle_component *name));
+
+/* Fill in a DEMANGLE_COMPONENT_DTOR. Returns non-zero on success,
+ zero for bad arguments. */
+
+extern int
+cplus_demangle_fill_dtor PARAMS ((struct demangle_component *fill,
+ enum gnu_v3_dtor_kinds kind,
+ struct demangle_component *name));
+
+/* This function translates a mangled name into a struct
+ demangle_component tree. The first argument is the mangled name.
+ The second argument is DMGL_* options. This returns a pointer to a
+ tree on success, or NULL on failure. On success, the third
+ argument is set to a block of memory allocated by malloc. This
+ block should be passed to free when the tree is no longer
+ needed. */
+
+extern struct demangle_component *
+cplus_demangle_v3_components PARAMS ((const char *mangled,
+ int options,
+ void **mem));
+
+/* This function takes a struct demangle_component tree and returns
+ the corresponding demangled string. The first argument is DMGL_*
+ options. The second is the tree to demangle. The third is a guess
+ at the length of the demangled string, used to initially allocate
+ the return buffer. The fourth is a pointer to a size_t. On
+ success, this function returns a buffer allocated by malloc(), and
+ sets the size_t pointed to by the fourth argument to the size of
+ the allocated buffer (not the length of the returned string). On
+ failure, this function returns NULL, and sets the size_t pointed to
+ by the fourth argument to 0 for an invalid tree, or to 1 for a
+ memory allocation error. */
+
+extern char *
+cplus_demangle_print PARAMS ((int options,
+ const struct demangle_component *tree,
+ int estimated_length,
+ size_t *p_allocated_size));
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/contrib/gcc/df.c b/contrib/gcc/df.c
index fb434ff588b5..d91f95e37d09 100644
--- a/contrib/gcc/df.c
+++ b/contrib/gcc/df.c
@@ -1,5 +1,6 @@
/* Dataflow support routines.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz,
mhayes@redhat.com)
@@ -54,7 +55,8 @@ Here's an example of using the dataflow routines.
df_init simply creates a poor man's object (df) that needs to be
passed to all the dataflow routines. df_finish destroys this
-object and frees up any allocated memory.
+object and frees up any allocated memory. DF_ALL says to analyse
+everything.
df_analyse performs the following:
@@ -112,6 +114,7 @@ rather than searching the def or use bitmaps.
If the insns are in SSA form then the reg-def and use-def lists
should only contain the single defining ref.
+
TODO:
1) Incremental dataflow analysis.
@@ -129,9 +132,7 @@ insns so when df_analyse is called we can easily determine all the new
or deleted refs. Currently the global dataflow information is
recomputed from scratch but this could be propagated more efficiently.
-2) Improved global data flow computation using depth first search.
-
-3) Reduced memory requirements.
+2) Reduced memory requirements.
We could operate a pool of ref structures. When a ref is deleted it
gets returned to the pool (say by linking on to a chain of free refs).
@@ -140,28 +141,47 @@ tell which ones have been changed. Alternatively, we could
periodically squeeze the def and use tables and associated bitmaps and
renumber the def and use ids.
-4) Ordering of reg-def and reg-use lists.
+3) Ordering of reg-def and reg-use lists.
Should the first entry in the def list be the first def (within a BB)?
Similarly, should the first entry in the use list be the last use
(within a BB)?
-5) Working with a sub-CFG.
+4) Working with a sub-CFG.
-Often the whole CFG does not need to be analysed, for example,
-when optimising a loop, only certain registers are of interest.
+Often the whole CFG does not need to be analyzed, for example,
+when optimizing a loop, only certain registers are of interest.
Perhaps there should be a bitmap argument to df_analyse to specify
- which registers should be analysed? */
+which registers should be analyzed?
+
+
+NOTES:
+
+Embedded addressing side-effects, such as POST_INC or PRE_INC, generate
+both a use and a def. These are both marked read/write to show that they
+are dependent. For example, (set (reg 40) (mem (post_inc (reg 42))))
+will generate a use of reg 42 followed by a def of reg 42 (both marked
+read/write). Similarly, (set (reg 40) (mem (pre_dec (reg 41))))
+generates a use of reg 41 then a def of reg 41 (both marked read/write),
+even though reg 41 is decremented before it is used for the memory
+address in this second example.
+
+A set to a REG inside a ZERO_EXTRACT, SIGN_EXTRACT, or SUBREG invokes
+a read-modify write operation. We generate both a use and a def
+and again mark them read/write.
+*/
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "insn-config.h"
#include "recog.h"
#include "function.h"
#include "regs.h"
-#include "obstack.h"
+#include "alloc-pool.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "sbitmap.h"
@@ -178,120 +198,107 @@ Perhaps there should be a bitmap argument to df_analyse to specify
} \
while (0)
-static struct obstack df_ref_obstack;
+static alloc_pool df_ref_pool;
+static alloc_pool df_link_pool;
static struct df *ddf;
-static void df_reg_table_realloc PARAMS((struct df *, int));
+static void df_reg_table_realloc (struct df *, int);
+static void df_insn_table_realloc (struct df *, unsigned int);
+static void df_bitmaps_alloc (struct df *, int);
+static void df_bitmaps_free (struct df *, int);
+static void df_free (struct df *);
+static void df_alloc (struct df *, int);
+
+static rtx df_reg_clobber_gen (unsigned int);
+static rtx df_reg_use_gen (unsigned int);
+
+static inline struct df_link *df_link_create (struct ref *, struct df_link *);
+static struct df_link *df_ref_unlink (struct df_link **, struct ref *);
+static void df_def_unlink (struct df *, struct ref *);
+static void df_use_unlink (struct df *, struct ref *);
+static void df_insn_refs_unlink (struct df *, basic_block, rtx);
#if 0
-static void df_def_table_realloc PARAMS((struct df *, int));
-#endif
-static void df_insn_table_realloc PARAMS((struct df *, unsigned int));
-static void df_bitmaps_alloc PARAMS((struct df *, int));
-static void df_bitmaps_free PARAMS((struct df *, int));
-static void df_free PARAMS((struct df *));
-static void df_alloc PARAMS((struct df *, int));
-
-static rtx df_reg_clobber_gen PARAMS((unsigned int));
-static rtx df_reg_use_gen PARAMS((unsigned int));
-
-static inline struct df_link *df_link_create PARAMS((struct ref *,
- struct df_link *));
-static struct df_link *df_ref_unlink PARAMS((struct df_link **, struct ref *));
-static void df_def_unlink PARAMS((struct df *, struct ref *));
-static void df_use_unlink PARAMS((struct df *, struct ref *));
-static void df_insn_refs_unlink PARAMS ((struct df *, basic_block, rtx));
-#if 0
-static void df_bb_refs_unlink PARAMS ((struct df *, basic_block));
-static void df_refs_unlink PARAMS ((struct df *, bitmap));
+static void df_bb_refs_unlink (struct df *, basic_block);
+static void df_refs_unlink (struct df *, bitmap);
#endif
-static struct ref *df_ref_create PARAMS((struct df *,
- rtx, rtx *, rtx,
- enum df_ref_type, enum df_ref_flags));
-static void df_ref_record_1 PARAMS((struct df *, rtx, rtx *,
- rtx, enum df_ref_type,
- enum df_ref_flags));
-static void df_ref_record PARAMS((struct df *, rtx, rtx *,
- rtx, enum df_ref_type,
- enum df_ref_flags));
-static void df_def_record_1 PARAMS((struct df *, rtx, basic_block, rtx));
-static void df_defs_record PARAMS((struct df *, rtx, basic_block, rtx));
-static void df_uses_record PARAMS((struct df *, rtx *,
- enum df_ref_type, basic_block, rtx,
- enum df_ref_flags));
-static void df_insn_refs_record PARAMS((struct df *, basic_block, rtx));
-static void df_bb_refs_record PARAMS((struct df *, basic_block));
-static void df_refs_record PARAMS((struct df *, bitmap));
-
-static void df_bb_reg_def_chain_create PARAMS((struct df *, basic_block));
-static void df_reg_def_chain_create PARAMS((struct df *, bitmap));
-static void df_bb_reg_use_chain_create PARAMS((struct df *, basic_block));
-static void df_reg_use_chain_create PARAMS((struct df *, bitmap));
-static void df_bb_du_chain_create PARAMS((struct df *, basic_block, bitmap));
-static void df_du_chain_create PARAMS((struct df *, bitmap));
-static void df_bb_ud_chain_create PARAMS((struct df *, basic_block));
-static void df_ud_chain_create PARAMS((struct df *, bitmap));
-static void df_bb_rd_local_compute PARAMS((struct df *, basic_block));
-static void df_rd_local_compute PARAMS((struct df *, bitmap));
-static void df_bb_ru_local_compute PARAMS((struct df *, basic_block));
-static void df_ru_local_compute PARAMS((struct df *, bitmap));
-static void df_bb_lr_local_compute PARAMS((struct df *, basic_block));
-static void df_lr_local_compute PARAMS((struct df *, bitmap));
-static void df_bb_reg_info_compute PARAMS((struct df *, basic_block, bitmap));
-static void df_reg_info_compute PARAMS((struct df *, bitmap));
-
-static int df_bb_luids_set PARAMS((struct df *df, basic_block));
-static int df_luids_set PARAMS((struct df *df, bitmap));
-
-static int df_modified_p PARAMS ((struct df *, bitmap));
-static int df_refs_queue PARAMS ((struct df *));
-static int df_refs_process PARAMS ((struct df *));
-static int df_bb_refs_update PARAMS ((struct df *, basic_block));
-static int df_refs_update PARAMS ((struct df *));
-static void df_analyse_1 PARAMS((struct df *, bitmap, int, int));
-
-static void df_insns_modify PARAMS((struct df *, basic_block,
- rtx, rtx));
-static int df_rtx_mem_replace PARAMS ((rtx *, void *));
-static int df_rtx_reg_replace PARAMS ((rtx *, void *));
-void df_refs_reg_replace PARAMS ((struct df *, bitmap,
- struct df_link *, rtx, rtx));
-
-static int df_def_dominates_all_uses_p PARAMS((struct df *, struct ref *def));
-static int df_def_dominates_uses_p PARAMS((struct df *,
- struct ref *def, bitmap));
-static struct ref *df_bb_regno_last_use_find PARAMS((struct df *, basic_block,
- unsigned int));
-static struct ref *df_bb_regno_first_def_find PARAMS((struct df *, basic_block,
- unsigned int));
-static struct ref *df_bb_insn_regno_last_use_find PARAMS((struct df *,
- basic_block,
- rtx, unsigned int));
-static struct ref *df_bb_insn_regno_first_def_find PARAMS((struct df *,
- basic_block,
- rtx, unsigned int));
-
-static void df_chain_dump PARAMS((struct df_link *, FILE *file));
-static void df_chain_dump_regno PARAMS((struct df_link *, FILE *file));
-static void df_regno_debug PARAMS ((struct df *, unsigned int, FILE *));
-static void df_ref_debug PARAMS ((struct df *, struct ref *, FILE *));
-static void df_rd_transfer_function PARAMS ((int, int *, bitmap, bitmap,
- bitmap, bitmap, void *));
-static void df_ru_transfer_function PARAMS ((int, int *, bitmap, bitmap,
- bitmap, bitmap, void *));
-static void df_lr_transfer_function PARAMS ((int, int *, bitmap, bitmap,
- bitmap, bitmap, void *));
-static void hybrid_search_bitmap PARAMS ((basic_block, bitmap *, bitmap *,
- bitmap *, bitmap *, enum df_flow_dir,
- enum df_confluence_op,
- transfer_function_bitmap,
- sbitmap, sbitmap, void *));
-static void hybrid_search_sbitmap PARAMS ((basic_block, sbitmap *, sbitmap *,
- sbitmap *, sbitmap *, enum df_flow_dir,
- enum df_confluence_op,
- transfer_function_sbitmap,
- sbitmap, sbitmap, void *));
-static inline bool read_modify_subreg_p PARAMS ((rtx));
+static struct ref *df_ref_create (struct df *, rtx, rtx *, rtx,
+ enum df_ref_type, enum df_ref_flags);
+static void df_ref_record_1 (struct df *, rtx, rtx *, rtx, enum df_ref_type,
+ enum df_ref_flags);
+static void df_ref_record (struct df *, rtx, rtx *, rtx, enum df_ref_type,
+ enum df_ref_flags);
+static void df_def_record_1 (struct df *, rtx, basic_block, rtx);
+static void df_defs_record (struct df *, rtx, basic_block, rtx);
+static void df_uses_record (struct df *, rtx *, enum df_ref_type,
+ basic_block, rtx, enum df_ref_flags);
+static void df_insn_refs_record (struct df *, basic_block, rtx);
+static void df_bb_refs_record (struct df *, basic_block);
+static void df_refs_record (struct df *, bitmap);
+
+static void df_bb_reg_def_chain_create (struct df *, basic_block);
+static void df_reg_def_chain_create (struct df *, bitmap);
+static void df_bb_reg_use_chain_create (struct df *, basic_block);
+static void df_reg_use_chain_create (struct df *, bitmap);
+static void df_bb_du_chain_create (struct df *, basic_block, bitmap);
+static void df_du_chain_create (struct df *, bitmap);
+static void df_bb_ud_chain_create (struct df *, basic_block);
+static void df_ud_chain_create (struct df *, bitmap);
+static void df_bb_rd_local_compute (struct df *, basic_block);
+static void df_rd_local_compute (struct df *, bitmap);
+static void df_bb_ru_local_compute (struct df *, basic_block);
+static void df_ru_local_compute (struct df *, bitmap);
+static void df_bb_lr_local_compute (struct df *, basic_block);
+static void df_lr_local_compute (struct df *, bitmap);
+static void df_bb_reg_info_compute (struct df *, basic_block, bitmap);
+static void df_reg_info_compute (struct df *, bitmap);
+
+static int df_bb_luids_set (struct df *df, basic_block);
+static int df_luids_set (struct df *df, bitmap);
+
+static int df_modified_p (struct df *, bitmap);
+static int df_refs_queue (struct df *);
+static int df_refs_process (struct df *);
+static int df_bb_refs_update (struct df *, basic_block);
+static int df_refs_update (struct df *);
+static void df_analyse_1 (struct df *, bitmap, int, int);
+
+static void df_insns_modify (struct df *, basic_block, rtx, rtx);
+static int df_rtx_mem_replace (rtx *, void *);
+static int df_rtx_reg_replace (rtx *, void *);
+void df_refs_reg_replace (struct df *, bitmap, struct df_link *, rtx, rtx);
+
+static int df_def_dominates_all_uses_p (struct df *, struct ref *def);
+static int df_def_dominates_uses_p (struct df *, struct ref *def, bitmap);
+static struct ref *df_bb_regno_last_use_find (struct df *, basic_block,
+ unsigned int);
+static struct ref *df_bb_regno_first_def_find (struct df *, basic_block,
+ unsigned int);
+static struct ref *df_bb_insn_regno_last_use_find (struct df *, basic_block,
+ rtx, unsigned int);
+static struct ref *df_bb_insn_regno_first_def_find (struct df *, basic_block,
+ rtx, unsigned int);
+
+static void df_chain_dump (struct df_link *, FILE *file);
+static void df_chain_dump_regno (struct df_link *, FILE *file);
+static void df_regno_debug (struct df *, unsigned int, FILE *);
+static void df_ref_debug (struct df *, struct ref *, FILE *);
+static void df_rd_transfer_function (int, int *, bitmap, bitmap, bitmap,
+ bitmap, void *);
+static void df_ru_transfer_function (int, int *, bitmap, bitmap, bitmap,
+ bitmap, void *);
+static void df_lr_transfer_function (int, int *, bitmap, bitmap, bitmap,
+ bitmap, void *);
+static void hybrid_search_bitmap (basic_block, bitmap *, bitmap *,
+ bitmap *, bitmap *, enum df_flow_dir,
+ enum df_confluence_op,
+ transfer_function_bitmap,
+ sbitmap, sbitmap, void *);
+static void hybrid_search_sbitmap (basic_block, sbitmap *, sbitmap *,
+ sbitmap *, sbitmap *, enum df_flow_dir,
+ enum df_confluence_op,
+ transfer_function_sbitmap,
+ sbitmap, sbitmap, void *);
/* Local memory allocation/deallocation routines. */
@@ -300,20 +307,17 @@ static inline bool read_modify_subreg_p PARAMS ((rtx));
/* Increase the insn info table to have space for at least SIZE + 1
elements. */
static void
-df_insn_table_realloc (df, size)
- struct df *df;
- unsigned int size;
+df_insn_table_realloc (struct df *df, unsigned int size)
{
size++;
if (size <= df->insn_size)
return;
- /* Make the table a little larger than requested, so we don't need
+ /* Make the table a little larger than requested, so we do not need
to enlarge it so often. */
size += df->insn_size / 4;
- df->insns = (struct insn_info *)
- xrealloc (df->insns, size * sizeof (struct insn_info));
+ df->insns = xrealloc (df->insns, size * sizeof (struct insn_info));
memset (df->insns + df->insn_size, 0,
(size - df->insn_size) * sizeof (struct insn_info));
@@ -330,9 +334,7 @@ df_insn_table_realloc (df, size)
/* Increase the reg info table by SIZE more elements. */
static void
-df_reg_table_realloc (df, size)
- struct df *df;
- int size;
+df_reg_table_realloc (struct df *df, int size)
{
/* Make table 25 percent larger by default. */
if (! size)
@@ -342,8 +344,7 @@ df_reg_table_realloc (df, size)
if (size < max_reg_num ())
size = max_reg_num ();
- df->regs = (struct reg_info *)
- xrealloc (df->regs, size * sizeof (struct reg_info));
+ df->regs = xrealloc (df->regs, size * sizeof (struct reg_info));
/* Zero the new entries. */
memset (df->regs + df->reg_size, 0,
@@ -353,43 +354,9 @@ df_reg_table_realloc (df, size)
}
-#if 0
-/* Not currently used. */
-static void
-df_def_table_realloc (df, size)
- struct df *df;
- int size;
-{
- int i;
- struct ref *refs;
-
- /* Make table 25 percent larger by default. */
- if (! size)
- size = df->def_size / 4;
-
- df->def_size += size;
- df->defs = xrealloc (df->defs,
- df->def_size * sizeof (*df->defs));
-
- /* Allocate a new block of memory and link into list of blocks
- that will need to be freed later. */
-
- refs = xmalloc (size * sizeof (*refs));
-
- /* Link all the new refs together, overloading the chain field. */
- for (i = 0; i < size - 1; i++)
- refs[i].chain = (struct df_link *) (refs + i + 1);
- refs[size - 1].chain = 0;
-}
-#endif
-
-
-
/* Allocate bitmaps for each basic block. */
static void
-df_bitmaps_alloc (df, flags)
- struct df *df;
- int flags;
+df_bitmaps_alloc (struct df *df, int flags)
{
int dflags = 0;
basic_block bb;
@@ -454,9 +421,7 @@ df_bitmaps_alloc (df, flags)
/* Free bitmaps for each basic block. */
static void
-df_bitmaps_free (df, flags)
- struct df *df ATTRIBUTE_UNUSED;
- int flags;
+df_bitmaps_free (struct df *df, int flags)
{
basic_block bb;
@@ -512,14 +477,14 @@ df_bitmaps_free (df, flags)
/* Allocate and initialize dataflow memory. */
static void
-df_alloc (df, n_regs)
- struct df *df;
- int n_regs;
+df_alloc (struct df *df, int n_regs)
{
int n_insns;
basic_block bb;
- gcc_obstack_init (&df_ref_obstack);
+ df_link_pool = create_alloc_pool ("df_link pool", sizeof (struct df_link),
+ 100);
+ df_ref_pool = create_alloc_pool ("df_ref pool", sizeof (struct ref), 100);
/* Perhaps we should use LUIDs to save memory for the insn_refs
table. This is only a small saving; a few pointers. */
@@ -562,8 +527,7 @@ df_alloc (df, n_regs)
/* Free all the dataflow info. */
static void
-df_free (df)
- struct df *df;
+df_free (struct df *df)
{
df_bitmaps_free (df, DF_ALL);
@@ -604,14 +568,15 @@ df_free (df)
BITMAP_XFREE (df->all_blocks);
df->all_blocks = 0;
- obstack_free (&df_ref_obstack, NULL);
+ free_alloc_pool (df_ref_pool);
+ free_alloc_pool (df_link_pool);
+
}
/* Local miscellaneous routines. */
/* Return a USE for register REGNO. */
-static rtx df_reg_use_gen (regno)
- unsigned int regno;
+static rtx df_reg_use_gen (unsigned int regno)
{
rtx reg;
rtx use;
@@ -624,8 +589,7 @@ static rtx df_reg_use_gen (regno)
/* Return a CLOBBER for register REGNO. */
-static rtx df_reg_clobber_gen (regno)
- unsigned int regno;
+static rtx df_reg_clobber_gen (unsigned int regno)
{
rtx reg;
rtx use;
@@ -640,14 +604,11 @@ static rtx df_reg_clobber_gen (regno)
/* Create a link in a def-use or use-def chain. */
static inline struct df_link *
-df_link_create (ref, next)
- struct ref *ref;
- struct df_link *next;
+df_link_create (struct ref *ref, struct df_link *next)
{
struct df_link *link;
- link = (struct df_link *) obstack_alloc (&df_ref_obstack,
- sizeof (*link));
+ link = pool_alloc (df_link_pool);
link->next = next;
link->ref = ref;
return link;
@@ -656,9 +617,7 @@ df_link_create (ref, next)
/* Add REF to chain head pointed to by PHEAD. */
static struct df_link *
-df_ref_unlink (phead, ref)
- struct df_link **phead;
- struct ref *ref;
+df_ref_unlink (struct df_link **phead, struct ref *ref)
{
struct df_link *link = *phead;
@@ -700,9 +659,7 @@ df_ref_unlink (phead, ref)
/* Unlink REF from all def-use/use-def chains, etc. */
int
-df_ref_remove (df, ref)
- struct df *df;
- struct ref *ref;
+df_ref_remove (struct df *df, struct ref *ref)
{
if (DF_REF_REG_DEF_P (ref))
{
@@ -720,9 +677,7 @@ df_ref_remove (df, ref)
/* Unlink DEF from use-def and reg-def chains. */
static void
-df_def_unlink (df, def)
- struct df *df ATTRIBUTE_UNUSED;
- struct ref *def;
+df_def_unlink (struct df *df ATTRIBUTE_UNUSED, struct ref *def)
{
struct df_link *du_link;
unsigned int dregno = DF_REF_REGNO (def);
@@ -746,9 +701,7 @@ df_def_unlink (df, def)
/* Unlink use from def-use and reg-use chains. */
static void
-df_use_unlink (df, use)
- struct df *df ATTRIBUTE_UNUSED;
- struct ref *use;
+df_use_unlink (struct df *df ATTRIBUTE_UNUSED, struct ref *use)
{
struct df_link *ud_link;
unsigned int uregno = DF_REF_REGNO (use);
@@ -775,26 +728,18 @@ df_use_unlink (df, use)
/* Create a new ref of type DF_REF_TYPE for register REG at address
LOC within INSN of BB. */
static struct ref *
-df_ref_create (df, reg, loc, insn, ref_type, ref_flags)
- struct df *df;
- rtx reg;
- rtx *loc;
- rtx insn;
- enum df_ref_type ref_type;
- enum df_ref_flags ref_flags;
+df_ref_create (struct df *df, rtx reg, rtx *loc, rtx insn,
+ enum df_ref_type ref_type, enum df_ref_flags ref_flags)
{
struct ref *this_ref;
- unsigned int uid;
- this_ref = (struct ref *) obstack_alloc (&df_ref_obstack,
- sizeof (*this_ref));
+ this_ref = pool_alloc (df_ref_pool);
DF_REF_REG (this_ref) = reg;
DF_REF_LOC (this_ref) = loc;
DF_REF_INSN (this_ref) = insn;
DF_REF_CHAIN (this_ref) = 0;
DF_REF_TYPE (this_ref) = ref_type;
DF_REF_FLAGS (this_ref) = ref_flags;
- uid = INSN_UID (insn);
if (ref_type == DF_REF_REG_DEF)
{
@@ -827,13 +772,8 @@ df_ref_create (df, reg, loc, insn, ref_type, ref_flags)
/* Create a new reference of type DF_REF_TYPE for a single register REG,
used inside the LOC rtx of INSN. */
static void
-df_ref_record_1 (df, reg, loc, insn, ref_type, ref_flags)
- struct df *df;
- rtx reg;
- rtx *loc;
- rtx insn;
- enum df_ref_type ref_type;
- enum df_ref_flags ref_flags;
+df_ref_record_1 (struct df *df, rtx reg, rtx *loc, rtx insn,
+ enum df_ref_type ref_type, enum df_ref_flags ref_flags)
{
df_ref_create (df, reg, loc, insn, ref_type, ref_flags);
}
@@ -842,13 +782,8 @@ df_ref_record_1 (df, reg, loc, insn, ref_type, ref_flags)
/* Create new references of type DF_REF_TYPE for each part of register REG
at address LOC within INSN of BB. */
static void
-df_ref_record (df, reg, loc, insn, ref_type, ref_flags)
- struct df *df;
- rtx reg;
- rtx *loc;
- rtx insn;
- enum df_ref_type ref_type;
- enum df_ref_flags ref_flags;
+df_ref_record (struct df *df, rtx reg, rtx *loc, rtx insn,
+ enum df_ref_type ref_type, enum df_ref_flags ref_flags)
{
unsigned int regno;
@@ -867,6 +802,7 @@ df_ref_record (df, reg, loc, insn, ref_type, ref_flags)
{
loc = &SUBREG_REG (reg);
reg = *loc;
+ ref_flags |= DF_REF_STRIPPED;
}
regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
@@ -878,9 +814,9 @@ df_ref_record (df, reg, loc, insn, ref_type, ref_flags)
if (! (df->flags & DF_HARD_REGS))
return;
- /* GET_MODE (reg) is correct here. We don't want to go into a SUBREG
+ /* GET_MODE (reg) is correct here. We do not want to go into a SUBREG
for the mode, because we only want to add references to regs, which
- are really referenced. E.g. a (subreg:SI (reg:DI 0) 0) does _not_
+ are really referenced. E.g., a (subreg:SI (reg:DI 0) 0) does _not_
reference the whole reg 0 in DI mode (which would also include
reg 1, at least, if 0 and 1 are SImode registers). */
endregno = HARD_REGNO_NREGS (regno, GET_MODE (reg));
@@ -899,39 +835,38 @@ df_ref_record (df, reg, loc, insn, ref_type, ref_flags)
}
}
-/* Writes to paradoxical subregs, or subregs which are too narrow
- are read-modify-write. */
-static inline bool
-read_modify_subreg_p (x)
- rtx x;
+/* Return nonzero if writes to paradoxical SUBREGs, or SUBREGs which
+ are too narrow, are read-modify-write. */
+bool
+read_modify_subreg_p (rtx x)
{
unsigned int isize, osize;
if (GET_CODE (x) != SUBREG)
return false;
isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
osize = GET_MODE_SIZE (GET_MODE (x));
- if (isize <= osize)
- return true;
- if (isize <= UNITS_PER_WORD)
- return false;
- if (osize >= UNITS_PER_WORD)
- return false;
- return true;
+ /* Paradoxical subreg writes don't leave a trace of the old content. */
+ return (isize > osize && isize > UNITS_PER_WORD);
}
+
/* Process all the registers defined in the rtx, X. */
static void
-df_def_record_1 (df, x, bb, insn)
- struct df *df;
- rtx x;
- basic_block bb;
- rtx insn;
-{
- rtx *loc = &SET_DEST (x);
- rtx dst = *loc;
+df_def_record_1 (struct df *df, rtx x, basic_block bb, rtx insn)
+{
+ rtx *loc;
+ rtx dst;
enum df_ref_flags flags = 0;
+ /* We may recursively call ourselves on EXPR_LIST when dealing with PARALLEL
+ construct. */
+ if (GET_CODE (x) == EXPR_LIST || GET_CODE (x) == CLOBBER)
+ loc = &XEXP (x, 0);
+ else
+ loc = &SET_DEST (x);
+ dst = *loc;
+
/* Some targets place small structures in registers for
return values of functions. */
if (GET_CODE (dst) == PARALLEL && GET_MODE (dst) == BLKmode)
@@ -939,37 +874,30 @@ df_def_record_1 (df, x, bb, insn)
int i;
for (i = XVECLEN (dst, 0) - 1; i >= 0; i--)
- df_def_record_1 (df, XVECEXP (dst, 0, i), bb, insn);
+ {
+ rtx temp = XVECEXP (dst, 0, i);
+ if (GET_CODE (temp) == EXPR_LIST || GET_CODE (temp) == CLOBBER
+ || GET_CODE (temp) == SET)
+ df_def_record_1 (df, temp, bb, insn);
+ }
return;
}
-#ifdef CLASS_CANNOT_CHANGE_MODE
- if (GET_CODE (dst) == SUBREG
- && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (dst)),
- GET_MODE (dst)))
- flags |= DF_REF_MODE_CHANGE;
-#endif
-
- /* May be, we should flag the use of strict_low_part somehow. Might be
- handy for the reg allocator. */
+ /* Maybe, we should flag the use of STRICT_LOW_PART somehow. It might
+ be handy for the reg allocator. */
while (GET_CODE (dst) == STRICT_LOW_PART
|| GET_CODE (dst) == ZERO_EXTRACT
|| GET_CODE (dst) == SIGN_EXTRACT
- || read_modify_subreg_p (dst))
+ || ((df->flags & DF_FOR_REGALLOC) == 0
+ && read_modify_subreg_p (dst)))
{
- /* Strict low part always contains SUBREG, but we don't want to make
+ /* Strict low part always contains SUBREG, but we do not want to make
it appear outside, as whole register is always considered. */
if (GET_CODE (dst) == STRICT_LOW_PART)
{
loc = &XEXP (dst, 0);
dst = *loc;
}
-#ifdef CLASS_CANNOT_CHANGE_MODE
- if (GET_CODE (dst) == SUBREG
- && CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (dst)),
- GET_MODE (dst)))
- flags |= DF_REF_MODE_CHANGE;
-#endif
loc = &XEXP (dst, 0);
dst = *loc;
flags |= DF_REF_READ_WRITE;
@@ -983,11 +911,7 @@ df_def_record_1 (df, x, bb, insn)
/* Process all the registers defined in the pattern rtx, X. */
static void
-df_defs_record (df, x, bb, insn)
- struct df *df;
- rtx x;
- basic_block bb;
- rtx insn;
+df_defs_record (struct df *df, rtx x, basic_block bb, rtx insn)
{
RTX_CODE code = GET_CODE (x);
@@ -1013,13 +937,8 @@ df_defs_record (df, x, bb, insn)
/* Process all the registers used in the rtx at address LOC. */
static void
-df_uses_record (df, loc, ref_type, bb, insn, flags)
- struct df *df;
- rtx *loc;
- enum df_ref_type ref_type;
- basic_block bb;
- rtx insn;
- enum df_ref_flags flags;
+df_uses_record (struct df *df, rtx *loc, enum df_ref_type ref_type,
+ basic_block bb, rtx insn, enum df_ref_flags flags)
{
RTX_CODE code;
rtx x;
@@ -1053,29 +972,22 @@ df_uses_record (df, loc, ref_type, bb, insn, flags)
return;
case MEM:
- df_uses_record (df, &XEXP (x, 0), DF_REF_REG_MEM_LOAD, bb, insn, flags);
+ df_uses_record (df, &XEXP (x, 0), DF_REF_REG_MEM_LOAD, bb, insn, 0);
return;
case SUBREG:
/* While we're here, optimize this case. */
- /* In case the SUBREG is not of a register, don't optimize. */
+ /* In case the SUBREG is not of a REG, do not optimize. */
if (GET_CODE (SUBREG_REG (x)) != REG)
{
loc = &SUBREG_REG (x);
df_uses_record (df, loc, ref_type, bb, insn, flags);
return;
}
-#ifdef CLASS_CANNOT_CHANGE_MODE
- if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (x),
- GET_MODE (SUBREG_REG (x))))
- flags |= DF_REF_MODE_CHANGE;
-#endif
-
/* ... Fall through ... */
case REG:
- /* See a register (or subreg) other than being set. */
df_ref_record (df, x, loc, insn, ref_type, flags);
return;
@@ -1087,21 +999,15 @@ df_uses_record (df, loc, ref_type, bb, insn, flags)
switch (GET_CODE (dst))
{
- enum df_ref_flags use_flags;
case SUBREG:
- if (read_modify_subreg_p (dst))
+ if ((df->flags & DF_FOR_REGALLOC) == 0
+ && read_modify_subreg_p (dst))
{
- use_flags = DF_REF_READ_WRITE;
-#ifdef CLASS_CANNOT_CHANGE_MODE
- if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst),
- GET_MODE (SUBREG_REG (dst))))
- use_flags |= DF_REF_MODE_CHANGE;
-#endif
df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb,
- insn, use_flags);
+ insn, DF_REF_READ_WRITE);
break;
}
- /* ... FALLTHRU ... */
+ /* Fall through. */
case REG:
case PARALLEL:
case PC:
@@ -1113,18 +1019,12 @@ df_uses_record (df, loc, ref_type, bb, insn, flags)
bb, insn, 0);
break;
case STRICT_LOW_PART:
- /* A strict_low_part uses the whole reg not only the subreg. */
+ /* A strict_low_part uses the whole REG and not just the SUBREG. */
dst = XEXP (dst, 0);
if (GET_CODE (dst) != SUBREG)
abort ();
- use_flags = DF_REF_READ_WRITE;
-#ifdef CLASS_CANNOT_CHANGE_MODE
- if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst),
- GET_MODE (SUBREG_REG (dst))))
- use_flags |= DF_REF_MODE_CHANGE;
-#endif
df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb,
- insn, use_flags);
+ insn, DF_REF_READ_WRITE);
break;
case ZERO_EXTRACT:
case SIGN_EXTRACT:
@@ -1221,10 +1121,7 @@ df_uses_record (df, loc, ref_type, bb, insn, flags)
/* Record all the df within INSN of basic block BB. */
static void
-df_insn_refs_record (df, bb, insn)
- struct df *df;
- basic_block bb;
- rtx insn;
+df_insn_refs_record (struct df *df, basic_block bb, rtx insn)
{
int i;
@@ -1232,7 +1129,7 @@ df_insn_refs_record (df, bb, insn)
{
rtx note;
- /* Record register defs */
+ /* Record register defs. */
df_defs_record (df, PATTERN (insn), bb, insn);
if (df->flags & DF_EQUIV_NOTES)
@@ -1286,7 +1183,6 @@ df_insn_refs_record (df, bb, insn)
df_uses_record (df, &PATTERN (insn),
DF_REF_REG_USE, bb, insn, 0);
-
if (GET_CODE (insn) == CALL_INSN)
{
rtx note;
@@ -1315,21 +1211,19 @@ df_insn_refs_record (df, bb, insn)
/* Record all the refs within the basic block BB. */
static void
-df_bb_refs_record (df, bb)
- struct df *df;
- basic_block bb;
+df_bb_refs_record (struct df *df, basic_block bb)
{
rtx insn;
/* Scan the block an insn at a time from beginning to end. */
- for (insn = bb->head; ; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
{
if (INSN_P (insn))
{
/* Record defs within INSN. */
df_insn_refs_record (df, bb, insn);
}
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
}
}
@@ -1337,9 +1231,7 @@ df_bb_refs_record (df, bb)
/* Record all the refs in the basic blocks specified by BLOCKS. */
static void
-df_refs_record (df, blocks)
- struct df *df;
- bitmap blocks;
+df_refs_record (struct df *df, bitmap blocks)
{
basic_block bb;
@@ -1355,9 +1247,7 @@ df_refs_record (df, blocks)
/* Create reg-def chains for basic block BB. These are a list of
definitions for each register. */
static void
-df_bb_reg_def_chain_create (df, bb)
- struct df *df;
- basic_block bb;
+df_bb_reg_def_chain_create (struct df *df, basic_block bb)
{
rtx insn;
@@ -1366,7 +1256,7 @@ df_bb_reg_def_chain_create (df, bb)
scan the basic blocks in reverse order so that the first defs
appear at the start of the chain. */
- for (insn = bb->end; insn && insn != PREV_INSN (bb->head);
+ for (insn = BB_END (bb); insn && insn != PREV_INSN (BB_HEAD (bb));
insn = PREV_INSN (insn))
{
struct df_link *link;
@@ -1379,9 +1269,11 @@ df_bb_reg_def_chain_create (df, bb)
{
struct ref *def = link->ref;
unsigned int dregno = DF_REF_REGNO (def);
- /* Don't add ref's to the chain two times. I.e. only add
- new refs. XXX the same could be done by testing if the current
- insn is a modified (or a new) one. This would be faster. */
+
+ /* Do not add ref's to the chain twice, i.e., only add new
+ refs. XXX the same could be done by testing if the
+ current insn is a modified (or a new) one. This would be
+ faster. */
if (DF_REF_ID (def) < df->def_id_save)
continue;
@@ -1395,9 +1287,7 @@ df_bb_reg_def_chain_create (df, bb)
/* Create reg-def chains for each basic block within BLOCKS. These
are a list of definitions for each register. */
static void
-df_reg_def_chain_create (df, blocks)
- struct df *df;
- bitmap blocks;
+df_reg_def_chain_create (struct df *df, bitmap blocks)
{
basic_block bb;
@@ -1411,16 +1301,14 @@ df_reg_def_chain_create (df, blocks)
/* Create reg-use chains for basic block BB. These are a list of uses
for each register. */
static void
-df_bb_reg_use_chain_create (df, bb)
- struct df *df;
- basic_block bb;
+df_bb_reg_use_chain_create (struct df *df, basic_block bb)
{
rtx insn;
- /* Scan in forward order so that the last uses appear at the
- start of the chain. */
+ /* Scan in forward order so that the last uses appear at the start
+ of the chain. */
- for (insn = bb->head; insn && insn != NEXT_INSN (bb->end);
+ for (insn = BB_HEAD (bb); insn && insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
{
struct df_link *link;
@@ -1433,9 +1321,11 @@ df_bb_reg_use_chain_create (df, bb)
{
struct ref *use = link->ref;
unsigned int uregno = DF_REF_REGNO (use);
- /* Don't add ref's to the chain two times. I.e. only add
- new refs. XXX the same could be done by testing if the current
- insn is a modified (or a new) one. This would be faster. */
+
+ /* Do not add ref's to the chain twice, i.e., only add new
+ refs. XXX the same could be done by testing if the
+ current insn is a modified (or a new) one. This would be
+ faster. */
if (DF_REF_ID (use) < df->use_id_save)
continue;
@@ -1449,9 +1339,7 @@ df_bb_reg_use_chain_create (df, bb)
/* Create reg-use chains for each basic block within BLOCKS. These
are a list of uses for each register. */
static void
-df_reg_use_chain_create (df, blocks)
- struct df *df;
- bitmap blocks;
+df_reg_use_chain_create (struct df *df, bitmap blocks)
{
basic_block bb;
@@ -1464,10 +1352,7 @@ df_reg_use_chain_create (df, blocks)
/* Create def-use chains from reaching use bitmaps for basic block BB. */
static void
-df_bb_du_chain_create (df, bb, ru)
- struct df *df;
- basic_block bb;
- bitmap ru;
+df_bb_du_chain_create (struct df *df, basic_block bb, bitmap ru)
{
struct bb_info *bb_info = DF_BB_INFO (df, bb);
rtx insn;
@@ -1476,7 +1361,7 @@ df_bb_du_chain_create (df, bb, ru)
/* For each def in BB create a linked list (chain) of uses
reached from the def. */
- for (insn = bb->end; insn && insn != PREV_INSN (bb->head);
+ for (insn = BB_END (bb); insn && insn != PREV_INSN (BB_HEAD (bb));
insn = PREV_INSN (insn))
{
struct df_link *def_link;
@@ -1525,9 +1410,7 @@ df_bb_du_chain_create (df, bb, ru)
/* Create def-use chains from reaching use bitmaps for basic blocks
in BLOCKS. */
static void
-df_du_chain_create (df, blocks)
- struct df *df;
- bitmap blocks;
+df_du_chain_create (struct df *df, bitmap blocks)
{
bitmap ru;
basic_block bb;
@@ -1545,9 +1428,7 @@ df_du_chain_create (df, blocks)
/* Create use-def chains from reaching def bitmaps for basic block BB. */
static void
-df_bb_ud_chain_create (df, bb)
- struct df *df;
- basic_block bb;
+df_bb_ud_chain_create (struct df *df, basic_block bb)
{
struct bb_info *bb_info = DF_BB_INFO (df, bb);
struct ref **reg_def_last = df->reg_def_last;
@@ -1557,7 +1438,7 @@ df_bb_ud_chain_create (df, bb)
/* For each use in BB create a linked list (chain) of defs
that reach the use. */
- for (insn = bb->head; insn && insn != NEXT_INSN (bb->end);
+ for (insn = BB_HEAD (bb); insn && insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
{
unsigned int uid = INSN_UID (insn);
@@ -1606,7 +1487,7 @@ df_bb_ud_chain_create (df, bb)
}
- /* For each def in insn...record the last def of each reg. */
+ /* For each def in insn... record the last def of each reg. */
for (def_link = df->insns[uid].defs; def_link; def_link = def_link->next)
{
struct ref *def = def_link->ref;
@@ -1621,9 +1502,7 @@ df_bb_ud_chain_create (df, bb)
/* Create use-def chains from reaching def bitmaps for basic blocks
within BLOCKS. */
static void
-df_ud_chain_create (df, blocks)
- struct df *df;
- bitmap blocks;
+df_ud_chain_create (struct df *df, bitmap blocks)
{
basic_block bb;
@@ -1636,30 +1515,27 @@ df_ud_chain_create (df, blocks)
static void
-df_rd_transfer_function (bb, changed, in, out, gen, kill, data)
- int bb ATTRIBUTE_UNUSED;
- int *changed;
- bitmap in, out, gen, kill;
- void *data ATTRIBUTE_UNUSED;
+df_rd_transfer_function (int bb ATTRIBUTE_UNUSED, int *changed, bitmap in,
+ bitmap out, bitmap gen, bitmap kill,
+ void *data ATTRIBUTE_UNUSED)
{
*changed = bitmap_union_of_diff (out, gen, in, kill);
}
+
+
static void
-df_ru_transfer_function (bb, changed, in, out, gen, kill, data)
- int bb ATTRIBUTE_UNUSED;
- int *changed;
- bitmap in, out, gen, kill;
- void *data ATTRIBUTE_UNUSED;
+df_ru_transfer_function (int bb ATTRIBUTE_UNUSED, int *changed, bitmap in,
+ bitmap out, bitmap gen, bitmap kill,
+ void *data ATTRIBUTE_UNUSED)
{
*changed = bitmap_union_of_diff (in, gen, out, kill);
}
+
static void
-df_lr_transfer_function (bb, changed, in, out, use, def, data)
- int bb ATTRIBUTE_UNUSED;
- int *changed;
- bitmap in, out, use, def;
- void *data ATTRIBUTE_UNUSED;
+df_lr_transfer_function (int bb ATTRIBUTE_UNUSED, int *changed, bitmap in,
+ bitmap out, bitmap use, bitmap def,
+ void *data ATTRIBUTE_UNUSED)
{
*changed = bitmap_union_of_diff (in, use, out, def);
}
@@ -1667,14 +1543,12 @@ df_lr_transfer_function (bb, changed, in, out, use, def, data)
/* Compute local reaching def info for basic block BB. */
static void
-df_bb_rd_local_compute (df, bb)
- struct df *df;
- basic_block bb;
+df_bb_rd_local_compute (struct df *df, basic_block bb)
{
struct bb_info *bb_info = DF_BB_INFO (df, bb);
rtx insn;
- for (insn = bb->head; insn && insn != NEXT_INSN (bb->end);
+ for (insn = BB_HEAD (bb); insn && insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
{
unsigned int uid = INSN_UID (insn);
@@ -1714,9 +1588,7 @@ df_bb_rd_local_compute (df, bb)
/* Compute local reaching def info for each basic block within BLOCKS. */
static void
-df_rd_local_compute (df, blocks)
- struct df *df;
- bitmap blocks;
+df_rd_local_compute (struct df *df, bitmap blocks)
{
basic_block bb;
@@ -1730,9 +1602,7 @@ df_rd_local_compute (df, blocks)
/* Compute local reaching use (upward exposed use) info for basic
block BB. */
static void
-df_bb_ru_local_compute (df, bb)
- struct df *df;
- basic_block bb;
+df_bb_ru_local_compute (struct df *df, basic_block bb)
{
/* This is much more tricky than computing reaching defs. With
reaching defs, defs get killed by other defs. With upwards
@@ -1742,7 +1612,7 @@ df_bb_ru_local_compute (df, bb)
rtx insn;
- for (insn = bb->end; insn && insn != PREV_INSN (bb->head);
+ for (insn = BB_END (bb); insn && insn != PREV_INSN (BB_HEAD (bb));
insn = PREV_INSN (insn))
{
unsigned int uid = INSN_UID (insn);
@@ -1787,9 +1657,7 @@ df_bb_ru_local_compute (df, bb)
/* Compute local reaching use (upward exposed use) info for each basic
block within BLOCKS. */
static void
-df_ru_local_compute (df, blocks)
- struct df *df;
- bitmap blocks;
+df_ru_local_compute (struct df *df, bitmap blocks)
{
basic_block bb;
@@ -1802,14 +1670,12 @@ df_ru_local_compute (df, blocks)
/* Compute local live variable info for basic block BB. */
static void
-df_bb_lr_local_compute (df, bb)
- struct df *df;
- basic_block bb;
+df_bb_lr_local_compute (struct df *df, basic_block bb)
{
struct bb_info *bb_info = DF_BB_INFO (df, bb);
rtx insn;
- for (insn = bb->end; insn && insn != PREV_INSN (bb->head);
+ for (insn = BB_END (bb); insn && insn != PREV_INSN (BB_HEAD (bb));
insn = PREV_INSN (insn))
{
unsigned int uid = INSN_UID (insn);
@@ -1842,9 +1708,7 @@ df_bb_lr_local_compute (df, bb)
/* Compute local live variable info for each basic block within BLOCKS. */
static void
-df_lr_local_compute (df, blocks)
- struct df *df;
- bitmap blocks;
+df_lr_local_compute (struct df *df, bitmap blocks)
{
basic_block bb;
@@ -1858,10 +1722,7 @@ df_lr_local_compute (df, blocks)
/* Compute register info: lifetime, bb, and number of defs and uses
for basic block BB. */
static void
-df_bb_reg_info_compute (df, bb, live)
- struct df *df;
- basic_block bb;
- bitmap live;
+df_bb_reg_info_compute (struct df *df, basic_block bb, bitmap live)
{
struct reg_info *reg_info = df->regs;
struct bb_info *bb_info = DF_BB_INFO (df, bb);
@@ -1869,7 +1730,7 @@ df_bb_reg_info_compute (df, bb, live)
bitmap_copy (live, bb_info->lr_out);
- for (insn = bb->end; insn && insn != PREV_INSN (bb->head);
+ for (insn = BB_END (bb); insn && insn != PREV_INSN (BB_HEAD (bb));
insn = PREV_INSN (insn))
{
unsigned int uid = INSN_UID (insn);
@@ -1910,9 +1771,7 @@ df_bb_reg_info_compute (df, bb, live)
/* Compute register info: lifetime, bb, and number of defs and uses. */
static void
-df_reg_info_compute (df, blocks)
- struct df *df;
- bitmap blocks;
+df_reg_info_compute (struct df *df, bitmap blocks)
{
basic_block bb;
bitmap live;
@@ -1930,22 +1789,20 @@ df_reg_info_compute (df, blocks)
/* Assign LUIDs for BB. */
static int
-df_bb_luids_set (df, bb)
- struct df *df;
- basic_block bb;
+df_bb_luids_set (struct df *df, basic_block bb)
{
rtx insn;
int luid = 0;
/* The LUIDs are monotonically increasing for each basic block. */
- for (insn = bb->head; ; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
{
if (INSN_P (insn))
DF_INSN_LUID (df, insn) = luid++;
DF_INSN_LUID (df, insn) = luid;
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
}
return luid;
@@ -1954,9 +1811,7 @@ df_bb_luids_set (df, bb)
/* Assign LUIDs for each basic block within BLOCKS. */
static int
-df_luids_set (df, blocks)
- struct df *df;
- bitmap blocks;
+df_luids_set (struct df *df, bitmap blocks)
{
basic_block bb;
int total = 0;
@@ -1968,14 +1823,11 @@ df_luids_set (df, blocks)
return total;
}
+
/* Perform dataflow analysis using existing DF structure for blocks
within BLOCKS. If BLOCKS is zero, use all basic blocks in the CFG. */
static void
-df_analyse_1 (df, blocks, flags, update)
- struct df *df;
- bitmap blocks;
- int flags;
- int update;
+df_analyse_1 (struct df *df, bitmap blocks, int flags, int update)
{
int aflags;
int dflags;
@@ -2077,7 +1929,7 @@ df_analyse_1 (df, blocks, flags, update)
kill[bb->index] = DF_BB_INFO (df, bb)->rd_kill;
}
iterative_dataflow_bitmap (in, out, gen, kill, df->all_blocks,
- FORWARD, UNION, df_rd_transfer_function,
+ DF_FORWARD, DF_UNION, df_rd_transfer_function,
df->inverse_rc_map, NULL);
free (in);
free (out);
@@ -2113,7 +1965,7 @@ df_analyse_1 (df, blocks, flags, update)
kill[bb->index] = DF_BB_INFO (df, bb)->ru_kill;
}
iterative_dataflow_bitmap (in, out, gen, kill, df->all_blocks,
- BACKWARD, UNION, df_ru_transfer_function,
+ DF_BACKWARD, DF_UNION, df_ru_transfer_function,
df->inverse_rts_map, NULL);
free (in);
free (out);
@@ -2152,7 +2004,7 @@ df_analyse_1 (df, blocks, flags, update)
def[bb->index] = DF_BB_INFO (df, bb)->lr_def;
}
iterative_dataflow_bitmap (in, out, use, def, df->all_blocks,
- BACKWARD, UNION, df_lr_transfer_function,
+ DF_BACKWARD, DF_UNION, df_lr_transfer_function,
df->inverse_rts_map, NULL);
free (in);
free (out);
@@ -2165,6 +2017,7 @@ df_analyse_1 (df, blocks, flags, update)
{
df_reg_info_compute (df, df->all_blocks);
}
+
free (df->dfs_order);
free (df->rc_order);
free (df->rts_order);
@@ -2176,7 +2029,7 @@ df_analyse_1 (df, blocks, flags, update)
/* Initialize dataflow analysis. */
struct df *
-df_init ()
+df_init (void)
{
struct df *df;
@@ -2191,8 +2044,7 @@ df_init ()
/* Start queuing refs. */
static int
-df_refs_queue (df)
- struct df *df;
+df_refs_queue (struct df *df)
{
df->def_id_save = df->def_id;
df->use_id_save = df->use_id;
@@ -2204,8 +2056,7 @@ df_refs_queue (df)
/* Process queued refs. */
static int
-df_refs_process (df)
- struct df *df;
+df_refs_process (struct df *df)
{
unsigned int i;
@@ -2236,19 +2087,17 @@ df_refs_process (df)
/* Update refs for basic block BB. */
static int
-df_bb_refs_update (df, bb)
- struct df *df;
- basic_block bb;
+df_bb_refs_update (struct df *df, basic_block bb)
{
rtx insn;
int count = 0;
- /* While we have to scan the chain of insns for this BB, we don't
+ /* While we have to scan the chain of insns for this BB, we do not
need to allocate and queue a long chain of BB/INSN pairs. Using
a bitmap for insns_modified saves memory and avoids queuing
duplicates. */
- for (insn = bb->head; ; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
{
unsigned int uid;
@@ -2264,7 +2113,7 @@ df_bb_refs_update (df, bb)
count++;
}
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
}
return count;
@@ -2273,8 +2122,7 @@ df_bb_refs_update (df, bb)
/* Process all the modified/deleted insns that were queued. */
static int
-df_refs_update (df)
- struct df *df;
+df_refs_update (struct df *df)
{
basic_block bb;
int count = 0;
@@ -2297,9 +2145,7 @@ df_refs_update (df)
/* Return nonzero if any of the requested blocks in the bitmap
BLOCKS have been modified. */
static int
-df_modified_p (df, blocks)
- struct df *df;
- bitmap blocks;
+df_modified_p (struct df *df, bitmap blocks)
{
int update = 0;
basic_block bb;
@@ -2319,14 +2165,11 @@ df_modified_p (df, blocks)
}
-/* Analyse dataflow info for the basic blocks specified by the bitmap
+/* Analyze dataflow info for the basic blocks specified by the bitmap
BLOCKS, or for the whole CFG if BLOCKS is zero, or just for the
modified blocks if BLOCKS is -1. */
int
-df_analyse (df, blocks, flags)
- struct df *df;
- bitmap blocks;
- int flags;
+df_analyse (struct df *df, bitmap blocks, int flags)
{
int update;
@@ -2369,8 +2212,7 @@ df_analyse (df, blocks, flags)
/* Free all the dataflow info and the DF structure. */
void
-df_finish (df)
- struct df *df;
+df_finish (struct df *df)
{
df_free (df);
free (df);
@@ -2379,10 +2221,7 @@ df_finish (df)
/* Unlink INSN from its reference information. */
static void
-df_insn_refs_unlink (df, bb, insn)
- struct df *df;
- basic_block bb ATTRIBUTE_UNUSED;
- rtx insn;
+df_insn_refs_unlink (struct df *df, basic_block bb ATTRIBUTE_UNUSED, rtx insn)
{
struct df_link *link;
unsigned int uid;
@@ -2405,21 +2244,19 @@ df_insn_refs_unlink (df, bb, insn)
#if 0
/* Unlink all the insns within BB from their reference information. */
static void
-df_bb_refs_unlink (df, bb)
- struct df *df;
- basic_block bb;
+df_bb_refs_unlink (struct df *df, basic_block bb)
{
rtx insn;
/* Scan the block an insn at a time from beginning to end. */
- for (insn = bb->head; ; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
{
if (INSN_P (insn))
{
/* Unlink refs for INSN. */
df_insn_refs_unlink (df, bb, insn);
}
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
}
}
@@ -2428,9 +2265,7 @@ df_bb_refs_unlink (df, bb)
/* Unlink all the refs in the basic blocks specified by BLOCKS.
Not currently used. */
static void
-df_refs_unlink (df, blocks)
- struct df *df;
- bitmap blocks;
+df_refs_unlink (struct df *df, bitmap blocks)
{
basic_block bb;
@@ -2454,16 +2289,13 @@ df_refs_unlink (df, blocks)
/* Delete INSN and all its reference information. */
rtx
-df_insn_delete (df, bb, insn)
- struct df *df;
- basic_block bb ATTRIBUTE_UNUSED;
- rtx insn;
+df_insn_delete (struct df *df, basic_block bb ATTRIBUTE_UNUSED, rtx insn)
{
/* If the insn is a jump, we should perhaps call delete_insn to
handle the JUMP_LABEL? */
/* We should not be deleting the NOTE_INSN_BASIC_BLOCK or label. */
- if (insn == bb->head)
+ if (insn == BB_HEAD (bb))
abort ();
/* Delete the insn. */
@@ -2480,10 +2312,7 @@ df_insn_delete (df, bb, insn)
harm calling this function if the insn wasn't changed; it will just
slow down the rescanning of refs. */
void
-df_insn_modify (df, bb, insn)
- struct df *df;
- basic_block bb;
- rtx insn;
+df_insn_modify (struct df *df, basic_block bb, rtx insn)
{
unsigned int uid;
@@ -2502,7 +2331,8 @@ df_insn_modify (df, bb, insn)
}
-typedef struct replace_args {
+typedef struct replace_args
+{
rtx match;
rtx replacement;
rtx insn;
@@ -2515,9 +2345,7 @@ typedef struct replace_args {
instruction currently being scanned and the MEM we are currently
replacing. */
static int
-df_rtx_mem_replace (px, data)
- rtx *px;
- void *data;
+df_rtx_mem_replace (rtx *px, void *data)
{
replace_args *args = (replace_args *) data;
rtx mem = *px;
@@ -2553,12 +2381,7 @@ df_rtx_mem_replace (px, data)
int
-df_insn_mem_replace (df, bb, insn, mem, reg)
- struct df *df;
- basic_block bb;
- rtx insn;
- rtx mem;
- rtx reg;
+df_insn_mem_replace (struct df *df, basic_block bb, rtx insn, rtx mem, rtx reg)
{
replace_args args;
@@ -2586,9 +2409,7 @@ df_insn_mem_replace (df, bb, insn, mem, reg)
points to the rtx being scanned. DATA is actually a pointer to a
structure of arguments. */
static int
-df_rtx_reg_replace (px, data)
- rtx *px;
- void *data;
+df_rtx_reg_replace (rtx *px, void *data)
{
rtx x = *px;
replace_args *args = (replace_args *) data;
@@ -2610,12 +2431,7 @@ df_rtx_reg_replace (px, data)
BLOCKS of basic blocks with NEWREG. Also update the regs within
REG_NOTES. */
void
-df_refs_reg_replace (df, blocks, chain, oldreg, newreg)
- struct df *df;
- bitmap blocks;
- struct df_link *chain;
- rtx oldreg;
- rtx newreg;
+df_refs_reg_replace (struct df *df, bitmap blocks, struct df_link *chain, rtx oldreg, rtx newreg)
{
struct df_link *link;
replace_args args;
@@ -2663,11 +2479,7 @@ df_refs_reg_replace (df, blocks, chain, oldreg, newreg)
OLDREG in the REG_NOTES but only for insns containing OLDREG. This
routine expects the reg-use and reg-def chains to be valid. */
int
-df_reg_replace (df, blocks, oldreg, newreg)
- struct df *df;
- bitmap blocks;
- rtx oldreg;
- rtx newreg;
+df_reg_replace (struct df *df, bitmap blocks, rtx oldreg, rtx newreg)
{
unsigned int oldregno = REGNO (oldreg);
@@ -2680,11 +2492,7 @@ df_reg_replace (df, blocks, oldreg, newreg)
/* Try replacing the reg within REF with NEWREG. Do not modify
def-use/use-def chains. */
int
-df_ref_reg_replace (df, ref, oldreg, newreg)
- struct df *df;
- struct ref *ref;
- rtx oldreg;
- rtx newreg;
+df_ref_reg_replace (struct df *df, struct ref *ref, rtx oldreg, rtx newreg)
{
/* Check that insn was deleted by being converted into a NOTE. If
so ignore this insn. */
@@ -2703,12 +2511,7 @@ df_ref_reg_replace (df, ref, oldreg, newreg)
struct ref*
-df_bb_def_use_swap (df, bb, def_insn, use_insn, regno)
- struct df * df;
- basic_block bb;
- rtx def_insn;
- rtx use_insn;
- unsigned int regno;
+df_bb_def_use_swap (struct df *df, basic_block bb, rtx def_insn, rtx use_insn, unsigned int regno)
{
struct ref *def;
struct ref *use;
@@ -2752,11 +2555,7 @@ df_bb_def_use_swap (df, bb, def_insn, use_insn, regno)
/* Record df between FIRST_INSN and LAST_INSN inclusive. All new
insns must be processed by this routine. */
static void
-df_insns_modify (df, bb, first_insn, last_insn)
- struct df *df;
- basic_block bb;
- rtx first_insn;
- rtx last_insn;
+df_insns_modify (struct df *df, basic_block bb, rtx first_insn, rtx last_insn)
{
rtx insn;
@@ -2787,17 +2586,13 @@ df_insns_modify (df, bb, first_insn, last_insn)
/* Emit PATTERN before INSN within BB. */
rtx
-df_pattern_emit_before (df, pattern, bb, insn)
- struct df *df ATTRIBUTE_UNUSED;
- rtx pattern;
- basic_block bb;
- rtx insn;
+df_pattern_emit_before (struct df *df, rtx pattern, basic_block bb, rtx insn)
{
rtx ret_insn;
rtx prev_insn = PREV_INSN (insn);
/* We should not be inserting before the start of the block. */
- if (insn == bb->head)
+ if (insn == BB_HEAD (bb))
abort ();
ret_insn = emit_insn_before (pattern, insn);
if (ret_insn == insn)
@@ -2810,11 +2605,7 @@ df_pattern_emit_before (df, pattern, bb, insn)
/* Emit PATTERN after INSN within BB. */
rtx
-df_pattern_emit_after (df, pattern, bb, insn)
- struct df *df;
- rtx pattern;
- basic_block bb;
- rtx insn;
+df_pattern_emit_after (struct df *df, rtx pattern, basic_block bb, rtx insn)
{
rtx ret_insn;
@@ -2829,11 +2620,7 @@ df_pattern_emit_after (df, pattern, bb, insn)
/* Emit jump PATTERN after INSN within BB. */
rtx
-df_jump_pattern_emit_after (df, pattern, bb, insn)
- struct df *df;
- rtx pattern;
- basic_block bb;
- rtx insn;
+df_jump_pattern_emit_after (struct df *df, rtx pattern, basic_block bb, rtx insn)
{
rtx ret_insn;
@@ -2852,12 +2639,7 @@ df_jump_pattern_emit_after (df, pattern, bb, insn)
out of a loop where it has been proven that the def-use info
will still be valid. */
rtx
-df_insn_move_before (df, bb, insn, before_bb, before_insn)
- struct df *df;
- basic_block bb;
- rtx insn;
- basic_block before_bb;
- rtx before_insn;
+df_insn_move_before (struct df *df, basic_block bb, rtx insn, basic_block before_bb, rtx before_insn)
{
struct df_link *link;
unsigned int uid;
@@ -2887,11 +2669,8 @@ df_insn_move_before (df, bb, insn, before_bb, before_insn)
int
-df_insn_regno_def_p (df, bb, insn, regno)
- struct df *df;
- basic_block bb ATTRIBUTE_UNUSED;
- rtx insn;
- unsigned int regno;
+df_insn_regno_def_p (struct df *df, basic_block bb ATTRIBUTE_UNUSED,
+ rtx insn, unsigned int regno)
{
unsigned int uid;
struct df_link *link;
@@ -2911,9 +2690,7 @@ df_insn_regno_def_p (df, bb, insn, regno)
static int
-df_def_dominates_all_uses_p (df, def)
- struct df *df ATTRIBUTE_UNUSED;
- struct ref *def;
+df_def_dominates_all_uses_p (struct df *df ATTRIBUTE_UNUSED, struct ref *def)
{
struct df_link *du_link;
@@ -2933,10 +2710,8 @@ df_def_dominates_all_uses_p (df, def)
int
-df_insn_dominates_all_uses_p (df, bb, insn)
- struct df *df;
- basic_block bb ATTRIBUTE_UNUSED;
- rtx insn;
+df_insn_dominates_all_uses_p (struct df *df, basic_block bb ATTRIBUTE_UNUSED,
+ rtx insn)
{
unsigned int uid;
struct df_link *link;
@@ -2958,10 +2733,8 @@ df_insn_dominates_all_uses_p (df, bb, insn)
/* Return nonzero if all DF dominates all the uses within the bitmap
BLOCKS. */
static int
-df_def_dominates_uses_p (df, def, blocks)
- struct df *df ATTRIBUTE_UNUSED;
- struct ref *def;
- bitmap blocks;
+df_def_dominates_uses_p (struct df *df ATTRIBUTE_UNUSED, struct ref *def,
+ bitmap blocks)
{
struct df_link *du_link;
@@ -2989,11 +2762,8 @@ df_def_dominates_uses_p (df, def, blocks)
/* Return nonzero if all the defs of INSN within BB dominates
all the corresponding uses. */
int
-df_insn_dominates_uses_p (df, bb, insn, blocks)
- struct df *df;
- basic_block bb ATTRIBUTE_UNUSED;
- rtx insn;
- bitmap blocks;
+df_insn_dominates_uses_p (struct df *df, basic_block bb ATTRIBUTE_UNUSED,
+ rtx insn, bitmap blocks)
{
unsigned int uid;
struct df_link *link;
@@ -3016,9 +2786,7 @@ df_insn_dominates_uses_p (df, bb, insn, blocks)
/* Return the basic block that REG referenced in or NULL if referenced
in multiple basic blocks. */
basic_block
-df_regno_bb (df, regno)
- struct df *df;
- unsigned int regno;
+df_regno_bb (struct df *df, unsigned int regno)
{
struct df_link *defs = df->regs[regno].defs;
struct df_link *uses = df->regs[regno].uses;
@@ -3035,9 +2803,7 @@ df_regno_bb (df, regno)
/* Return nonzero if REG used in multiple basic blocks. */
int
-df_reg_global_p (df, reg)
- struct df *df;
- rtx reg;
+df_reg_global_p (struct df *df, rtx reg)
{
return df_regno_bb (df, REGNO (reg)) != 0;
}
@@ -3045,9 +2811,7 @@ df_reg_global_p (df, reg)
/* Return total lifetime (in insns) of REG. */
int
-df_reg_lifetime (df, reg)
- struct df *df;
- rtx reg;
+df_reg_lifetime (struct df *df, rtx reg)
{
return df->regs[REGNO (reg)].lifetime;
}
@@ -3055,10 +2819,7 @@ df_reg_lifetime (df, reg)
/* Return nonzero if REG live at start of BB. */
int
-df_bb_reg_live_start_p (df, bb, reg)
- struct df *df ATTRIBUTE_UNUSED;
- basic_block bb;
- rtx reg;
+df_bb_reg_live_start_p (struct df *df, basic_block bb, rtx reg)
{
struct bb_info *bb_info = DF_BB_INFO (df, bb);
@@ -3073,10 +2834,7 @@ df_bb_reg_live_start_p (df, bb, reg)
/* Return nonzero if REG live at end of BB. */
int
-df_bb_reg_live_end_p (df, bb, reg)
- struct df *df ATTRIBUTE_UNUSED;
- basic_block bb;
- rtx reg;
+df_bb_reg_live_end_p (struct df *df, basic_block bb, rtx reg)
{
struct bb_info *bb_info = DF_BB_INFO (df, bb);
@@ -3092,11 +2850,7 @@ df_bb_reg_live_end_p (df, bb, reg)
/* Return -1 if life of REG1 before life of REG2, 1 if life of REG1
after life of REG2, or 0, if the lives overlap. */
int
-df_bb_regs_lives_compare (df, bb, reg1, reg2)
- struct df *df;
- basic_block bb;
- rtx reg1;
- rtx reg2;
+df_bb_regs_lives_compare (struct df *df, basic_block bb, rtx reg1, rtx reg2)
{
unsigned int regno1 = REGNO (reg1);
unsigned int regno2 = REGNO (reg2);
@@ -3131,10 +2885,7 @@ df_bb_regs_lives_compare (df, bb, reg1, reg2)
/* Return last use of REGNO within BB. */
static struct ref *
-df_bb_regno_last_use_find (df, bb, regno)
- struct df * df;
- basic_block bb ATTRIBUTE_UNUSED;
- unsigned int regno;
+df_bb_regno_last_use_find (struct df *df, basic_block bb, unsigned int regno)
{
struct df_link *link;
@@ -3155,10 +2906,7 @@ df_bb_regno_last_use_find (df, bb, regno)
/* Return first def of REGNO within BB. */
static struct ref *
-df_bb_regno_first_def_find (df, bb, regno)
- struct df * df;
- basic_block bb ATTRIBUTE_UNUSED;
- unsigned int regno;
+df_bb_regno_first_def_find (struct df *df, basic_block bb, unsigned int regno)
{
struct df_link *link;
@@ -3179,11 +2927,9 @@ df_bb_regno_first_def_find (df, bb, regno)
/* Return first use of REGNO inside INSN within BB. */
static struct ref *
-df_bb_insn_regno_last_use_find (df, bb, insn, regno)
- struct df * df;
- basic_block bb ATTRIBUTE_UNUSED;
- rtx insn;
- unsigned int regno;
+df_bb_insn_regno_last_use_find (struct df *df,
+ basic_block bb ATTRIBUTE_UNUSED, rtx insn,
+ unsigned int regno)
{
unsigned int uid;
struct df_link *link;
@@ -3204,11 +2950,9 @@ df_bb_insn_regno_last_use_find (df, bb, insn, regno)
/* Return first def of REGNO inside INSN within BB. */
static struct ref *
-df_bb_insn_regno_first_def_find (df, bb, insn, regno)
- struct df * df;
- basic_block bb ATTRIBUTE_UNUSED;
- rtx insn;
- unsigned int regno;
+df_bb_insn_regno_first_def_find (struct df *df,
+ basic_block bb ATTRIBUTE_UNUSED, rtx insn,
+ unsigned int regno)
{
unsigned int uid;
struct df_link *link;
@@ -3230,11 +2974,7 @@ df_bb_insn_regno_first_def_find (df, bb, insn, regno)
/* Return insn using REG if the BB contains only a single
use and def of REG. */
rtx
-df_bb_single_def_use_insn_find (df, bb, insn, reg)
- struct df * df;
- basic_block bb;
- rtx insn;
- rtx reg;
+df_bb_single_def_use_insn_find (struct df *df, basic_block bb, rtx insn, rtx reg)
{
struct ref *def;
struct ref *use;
@@ -3268,9 +3008,7 @@ df_bb_single_def_use_insn_find (df, bb, insn, reg)
/* Dump a def-use or use-def chain for REF to FILE. */
static void
-df_chain_dump (link, file)
- struct df_link *link;
- FILE *file;
+df_chain_dump (struct df_link *link, FILE *file)
{
fprintf (file, "{ ");
for (; link; link = link->next)
@@ -3282,10 +3020,10 @@ df_chain_dump (link, file)
fprintf (file, "}");
}
+
+/* Dump a chain of refs with the associated regno. */
static void
-df_chain_dump_regno (link, file)
- struct df_link *link;
- FILE *file;
+df_chain_dump_regno (struct df_link *link, FILE *file)
{
fprintf (file, "{ ");
for (; link; link = link->next)
@@ -3298,12 +3036,10 @@ df_chain_dump_regno (link, file)
fprintf (file, "}");
}
+
/* Dump dataflow info. */
void
-df_dump (df, flags, file)
- struct df *df;
- int flags;
- FILE *file;
+df_dump (struct df *df, int flags, FILE *file)
{
unsigned int j;
basic_block bb;
@@ -3474,10 +3210,7 @@ df_dump (df, flags, file)
void
-df_insn_debug (df, insn, file)
- struct df *df;
- rtx insn;
- FILE *file;
+df_insn_debug (struct df *df, rtx insn, FILE *file)
{
unsigned int uid;
int bbi;
@@ -3501,11 +3234,9 @@ df_insn_debug (df, insn, file)
fprintf (file, "\n");
}
+
void
-df_insn_debug_regno (df, insn, file)
- struct df *df;
- rtx insn;
- FILE *file;
+df_insn_debug_regno (struct df *df, rtx insn, FILE *file)
{
unsigned int uid;
int bbi;
@@ -3529,11 +3260,9 @@ df_insn_debug_regno (df, insn, file)
fprintf (file, "\n");
}
+
static void
-df_regno_debug (df, regno, file)
- struct df *df;
- unsigned int regno;
- FILE *file;
+df_regno_debug (struct df *df, unsigned int regno, FILE *file)
{
if (regno >= df->reg_size)
return;
@@ -3548,10 +3277,7 @@ df_regno_debug (df, regno, file)
static void
-df_ref_debug (df, ref, file)
- struct df *df;
- struct ref *ref;
- FILE *file;
+df_ref_debug (struct df *df, struct ref *ref, FILE *file)
{
fprintf (file, "%c%d ",
DF_REF_REG_DEF_P (ref) ? 'd' : 'u',
@@ -3564,11 +3290,11 @@ df_ref_debug (df, ref, file)
df_chain_dump (DF_REF_CHAIN (ref), file);
fprintf (file, "\n");
}
-
+
+/* Functions for debugging from GDB. */
void
-debug_df_insn (insn)
- rtx insn;
+debug_df_insn (rtx insn)
{
df_insn_debug (ddf, insn, stderr);
debug_rtx (insn);
@@ -3576,78 +3302,68 @@ debug_df_insn (insn)
void
-debug_df_reg (reg)
- rtx reg;
+debug_df_reg (rtx reg)
{
df_regno_debug (ddf, REGNO (reg), stderr);
}
void
-debug_df_regno (regno)
- unsigned int regno;
+debug_df_regno (unsigned int regno)
{
df_regno_debug (ddf, regno, stderr);
}
void
-debug_df_ref (ref)
- struct ref *ref;
+debug_df_ref (struct ref *ref)
{
df_ref_debug (ddf, ref, stderr);
}
void
-debug_df_defno (defno)
- unsigned int defno;
+debug_df_defno (unsigned int defno)
{
df_ref_debug (ddf, ddf->defs[defno], stderr);
}
void
-debug_df_useno (defno)
- unsigned int defno;
+debug_df_useno (unsigned int defno)
{
df_ref_debug (ddf, ddf->uses[defno], stderr);
}
void
-debug_df_chain (link)
- struct df_link *link;
+debug_df_chain (struct df_link *link)
{
df_chain_dump (link, stderr);
fputc ('\n', stderr);
}
+
/* Hybrid search algorithm from "Implementation Techniques for
Efficient Data-Flow Analysis of Large Programs". */
static void
-hybrid_search_bitmap (block, in, out, gen, kill, dir,
- conf_op, transfun, visited, pending,
- data)
- basic_block block;
- bitmap *in, *out, *gen, *kill;
- enum df_flow_dir dir;
- enum df_confluence_op conf_op;
- transfer_function_bitmap transfun;
- sbitmap visited;
- sbitmap pending;
- void *data;
+hybrid_search_bitmap (basic_block block, bitmap *in, bitmap *out, bitmap *gen,
+ bitmap *kill, enum df_flow_dir dir,
+ enum df_confluence_op conf_op,
+ transfer_function_bitmap transfun, sbitmap visited,
+ sbitmap pending, void *data)
{
int changed;
int i = block->index;
edge e;
basic_block bb = block;
+
SET_BIT (visited, block->index);
if (TEST_BIT (pending, block->index))
{
- if (dir == FORWARD)
+ if (dir == DF_FORWARD)
{
- /* Calculate <conf_op> of predecessor_outs */
+ /* Calculate <conf_op> of predecessor_outs. */
bitmap_zero (in[i]);
for (e = bb->pred; e != 0; e = e->pred_next)
{
@@ -3655,10 +3371,10 @@ hybrid_search_bitmap (block, in, out, gen, kill, dir,
continue;
switch (conf_op)
{
- case UNION:
+ case DF_UNION:
bitmap_a_or_b (in[i], in[i], out[e->src->index]);
break;
- case INTERSECTION:
+ case DF_INTERSECTION:
bitmap_a_and_b (in[i], in[i], out[e->src->index]);
break;
}
@@ -3666,7 +3382,7 @@ hybrid_search_bitmap (block, in, out, gen, kill, dir,
}
else
{
- /* Calculate <conf_op> of successor ins */
+ /* Calculate <conf_op> of successor ins. */
bitmap_zero (out[i]);
for (e = bb->succ; e != 0; e = e->succ_next)
{
@@ -3674,10 +3390,10 @@ hybrid_search_bitmap (block, in, out, gen, kill, dir,
continue;
switch (conf_op)
{
- case UNION:
+ case DF_UNION:
bitmap_a_or_b (out[i], out[i], in[e->dest->index]);
break;
- case INTERSECTION:
+ case DF_INTERSECTION:
bitmap_a_and_b (out[i], out[i], in[e->dest->index]);
break;
}
@@ -3688,7 +3404,7 @@ hybrid_search_bitmap (block, in, out, gen, kill, dir,
RESET_BIT (pending, i);
if (changed)
{
- if (dir == FORWARD)
+ if (dir == DF_FORWARD)
{
for (e = bb->succ; e != 0; e = e->succ_next)
{
@@ -3708,7 +3424,7 @@ hybrid_search_bitmap (block, in, out, gen, kill, dir,
}
}
}
- if (dir == FORWARD)
+ if (dir == DF_FORWARD)
{
for (e = bb->succ; e != 0; e = e->succ_next)
{
@@ -3737,28 +3453,23 @@ hybrid_search_bitmap (block, in, out, gen, kill, dir,
/* Hybrid search for sbitmaps, rather than bitmaps. */
static void
-hybrid_search_sbitmap (block, in, out, gen, kill, dir,
- conf_op, transfun, visited, pending,
- data)
- basic_block block;
- sbitmap *in, *out, *gen, *kill;
- enum df_flow_dir dir;
- enum df_confluence_op conf_op;
- transfer_function_sbitmap transfun;
- sbitmap visited;
- sbitmap pending;
- void *data;
+hybrid_search_sbitmap (basic_block block, sbitmap *in, sbitmap *out,
+ sbitmap *gen, sbitmap *kill, enum df_flow_dir dir,
+ enum df_confluence_op conf_op,
+ transfer_function_sbitmap transfun, sbitmap visited,
+ sbitmap pending, void *data)
{
int changed;
int i = block->index;
edge e;
basic_block bb = block;
+
SET_BIT (visited, block->index);
if (TEST_BIT (pending, block->index))
{
- if (dir == FORWARD)
+ if (dir == DF_FORWARD)
{
- /* Calculate <conf_op> of predecessor_outs */
+ /* Calculate <conf_op> of predecessor_outs. */
sbitmap_zero (in[i]);
for (e = bb->pred; e != 0; e = e->pred_next)
{
@@ -3766,10 +3477,10 @@ hybrid_search_sbitmap (block, in, out, gen, kill, dir,
continue;
switch (conf_op)
{
- case UNION:
+ case DF_UNION:
sbitmap_a_or_b (in[i], in[i], out[e->src->index]);
break;
- case INTERSECTION:
+ case DF_INTERSECTION:
sbitmap_a_and_b (in[i], in[i], out[e->src->index]);
break;
}
@@ -3777,7 +3488,7 @@ hybrid_search_sbitmap (block, in, out, gen, kill, dir,
}
else
{
- /* Calculate <conf_op> of successor ins */
+ /* Calculate <conf_op> of successor ins. */
sbitmap_zero (out[i]);
for (e = bb->succ; e != 0; e = e->succ_next)
{
@@ -3785,21 +3496,21 @@ hybrid_search_sbitmap (block, in, out, gen, kill, dir,
continue;
switch (conf_op)
{
- case UNION:
+ case DF_UNION:
sbitmap_a_or_b (out[i], out[i], in[e->dest->index]);
break;
- case INTERSECTION:
+ case DF_INTERSECTION:
sbitmap_a_and_b (out[i], out[i], in[e->dest->index]);
break;
}
}
}
- /* Common part */
+ /* Common part. */
(*transfun)(i, &changed, in[i], out[i], gen[i], kill[i], data);
RESET_BIT (pending, i);
if (changed)
{
- if (dir == FORWARD)
+ if (dir == DF_FORWARD)
{
for (e = bb->succ; e != 0; e = e->succ_next)
{
@@ -3819,7 +3530,7 @@ hybrid_search_sbitmap (block, in, out, gen, kill, dir,
}
}
}
- if (dir == FORWARD)
+ if (dir == DF_FORWARD)
{
for (e = bb->succ; e != 0; e = e->succ_next)
{
@@ -3846,8 +3557,6 @@ hybrid_search_sbitmap (block, in, out, gen, kill, dir,
}
-
-
/* gen = GEN set.
kill = KILL set.
in, out = Filled in by function.
@@ -3869,34 +3578,34 @@ hybrid_search_sbitmap (block, in, out, gen, kill, dir,
block number to rc_order (like df->inverse_rc_map).
*/
void
-iterative_dataflow_sbitmap (in, out, gen, kill, blocks,
- dir, conf_op, transfun, order, data)
- sbitmap *in, *out, *gen, *kill;
- bitmap blocks;
- enum df_flow_dir dir;
- enum df_confluence_op conf_op;
- transfer_function_sbitmap transfun;
- int *order;
- void *data;
+iterative_dataflow_sbitmap (sbitmap *in, sbitmap *out, sbitmap *gen,
+ sbitmap *kill, bitmap blocks,
+ enum df_flow_dir dir,
+ enum df_confluence_op conf_op,
+ transfer_function_sbitmap transfun, int *order,
+ void *data)
{
int i;
fibheap_t worklist;
basic_block bb;
sbitmap visited, pending;
+
pending = sbitmap_alloc (last_basic_block);
visited = sbitmap_alloc (last_basic_block);
sbitmap_zero (pending);
sbitmap_zero (visited);
worklist = fibheap_new ();
+
EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i,
{
fibheap_insert (worklist, order[i], (void *) (size_t) i);
SET_BIT (pending, i);
- if (dir == FORWARD)
+ if (dir == DF_FORWARD)
sbitmap_copy (out[i], gen[i]);
else
sbitmap_copy (in[i], gen[i]);
});
+
while (sbitmap_first_set_bit (pending) != -1)
{
while (!fibheap_empty (worklist))
@@ -3907,6 +3616,7 @@ iterative_dataflow_sbitmap (in, out, gen, kill, blocks,
hybrid_search_sbitmap (bb, in, out, gen, kill, dir,
conf_op, transfun, visited, pending, data);
}
+
if (sbitmap_first_set_bit (pending) != -1)
{
EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i,
@@ -3920,42 +3630,43 @@ iterative_dataflow_sbitmap (in, out, gen, kill, blocks,
break;
}
}
+
sbitmap_free (pending);
sbitmap_free (visited);
fibheap_delete (worklist);
}
+
/* Exactly the same as iterative_dataflow_sbitmap, except it works on
- bitmaps instead */
+ bitmaps instead. */
void
-iterative_dataflow_bitmap (in, out, gen, kill, blocks,
- dir, conf_op, transfun, order, data)
- bitmap *in, *out, *gen, *kill;
- bitmap blocks;
- enum df_flow_dir dir;
- enum df_confluence_op conf_op;
- transfer_function_bitmap transfun;
- int *order;
- void *data;
+iterative_dataflow_bitmap (bitmap *in, bitmap *out, bitmap *gen, bitmap *kill,
+ bitmap blocks, enum df_flow_dir dir,
+ enum df_confluence_op conf_op,
+ transfer_function_bitmap transfun, int *order,
+ void *data)
{
int i;
fibheap_t worklist;
basic_block bb;
sbitmap visited, pending;
+
pending = sbitmap_alloc (last_basic_block);
visited = sbitmap_alloc (last_basic_block);
sbitmap_zero (pending);
sbitmap_zero (visited);
worklist = fibheap_new ();
+
EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i,
{
fibheap_insert (worklist, order[i], (void *) (size_t) i);
SET_BIT (pending, i);
- if (dir == FORWARD)
+ if (dir == DF_FORWARD)
bitmap_copy (out[i], gen[i]);
else
bitmap_copy (in[i], gen[i]);
});
+
while (sbitmap_first_set_bit (pending) != -1)
{
while (!fibheap_empty (worklist))
@@ -3966,6 +3677,7 @@ iterative_dataflow_bitmap (in, out, gen, kill, blocks,
hybrid_search_bitmap (bb, in, out, gen, kill, dir,
conf_op, transfun, visited, pending, data);
}
+
if (sbitmap_first_set_bit (pending) != -1)
{
EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i,
diff --git a/contrib/gcc/df.h b/contrib/gcc/df.h
index 59f314384a22..9838aa834adf 100644
--- a/contrib/gcc/df.h
+++ b/contrib/gcc/df.h
@@ -1,6 +1,6 @@
/* Form lists of pseudo register references for autoinc optimization
- for GNU compiler. This is part of flow optimization.
- Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ for GNU compiler. This is part of flow optimization.
+ Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
This file is part of GCC.
@@ -29,18 +29,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define DF_RD_CHAIN 64 /* Reg-def chain. */
#define DF_RU_CHAIN 128 /* Reg-use chain. */
#define DF_ALL 255
-#define DF_HARD_REGS 1024
+#define DF_HARD_REGS 1024 /* Mark hard registers. */
#define DF_EQUIV_NOTES 2048 /* Mark uses present in EQUIV/EQUAL notes. */
+#define DF_FOR_REGALLOC 4096 /* If called for the register allocator. */
enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, DF_REF_REG_MEM_LOAD,
DF_REF_REG_MEM_STORE};
#define DF_REF_TYPE_NAMES {"def", "use", "mem load", "mem store"}
-/* ???> Perhaps all these data structures should be made private
- to enforce the interface. */
-
-
/* Link on a def-use or use-def chain. */
struct df_link
{
@@ -50,27 +47,42 @@ struct df_link
enum df_ref_flags
{
+ /* Read-modify-write refs generate both a use and a def and
+ these are marked with this flag to show that they are not
+ independent. */
DF_REF_READ_WRITE = 1,
- /* This flag is set on register references itself representing a or
- being inside a subreg on machines which have CLASS_CANNOT_CHANGE_MODE
- and where the mode change of that subreg expression is invalid for
- this class. Note, that this flag can also be set on df_refs
- representing the REG itself (i.e. one might not see the subreg
- anyore). Also note, that this flag is set also for hardreg refs.
- I.e. you must check yourself if it's a pseudo. */
- DF_REF_MODE_CHANGE = 2
+ /* This flag is set on register references inside a subreg on
+ machines which have CANNOT_CHANGE_MODE_CLASS.
+ Note, that this flag can also be set on df_refs representing
+ the REG itself (i.e., one might not see the subreg anyore).
+ Also note, that this flag is set also for hardreg refs, i.e.,
+ you must check yourself if it's a pseudo. */
+ DF_REF_MODE_CHANGE = 2,
+
+ /* This flag is set, if we stripped the subreg from the reference.
+ In this case we must make conservative guesses, at what the
+ outer mode was. */
+ DF_REF_STRIPPED = 4,
+
+ /* This flag is set during register allocation if it's okay for
+ the reference's INSN to have one of its operands replaced with a
+ memory reference. */
+ DF_REF_MEM_OK = 8
};
-/* Define a register reference structure. */
+
+/* Define a register reference structure. One of these is allocated
+ for every register reference (use or def). Note some register
+ references (e.g., post_inc, subreg) generate both a def and a use. */
struct ref
{
rtx reg; /* The register referenced. */
rtx insn; /* Insn containing ref. */
- rtx *loc; /* Loc is the location of the reg. */
+ rtx *loc; /* The location of the reg. */
struct df_link *chain; /* Head of def-use or use-def chain. */
- enum df_ref_type type; /* Type of ref. */
unsigned int id; /* Ref index. */
+ enum df_ref_type type; /* Type of ref. */
enum df_ref_flags flags; /* Various flags. */
};
@@ -80,12 +92,9 @@ struct insn_info
{
struct df_link *defs; /* Head of insn-def chain. */
struct df_link *uses; /* Head of insn-use chain. */
- /* ???? The following luid field should be considerd private so that
+ /* ???? The following luid field should be considered private so that
we can change it on the fly to accommodate new insns? */
int luid; /* Logical UID. */
-#if 0
- rtx insn; /* Backpointer to the insn. */
-#endif
};
@@ -148,15 +157,15 @@ struct df
bitmap insns_modified; /* Insns that (may) have changed. */
bitmap bbs_modified; /* Blocks that (may) have changed. */
bitmap all_blocks; /* All blocks in CFG. */
- /* The sbitmap vector of dominators or NULL if not computed.
+ /* The sbitmap vector of dominators or NULL if not computed.
Ideally, this should be a pointer to a CFG object. */
sbitmap *dom;
- int * dfs_order; /* DFS order -> block number */
- int * rc_order; /* reverse completion order -> block number */
- int * rts_order; /* reverse top sort order -> block number */
- int * inverse_rc_map; /* block number -> reverse completion order */
- int * inverse_dfs_map; /* block number -> DFS order */
- int * inverse_rts_map; /* block number -> reverse top-sort order */
+ int *dfs_order; /* DFS order -> block number. */
+ int *rc_order; /* Reverse completion order -> block number. */
+ int *rts_order; /* Reverse top sort order -> block number. */
+ int *inverse_rc_map; /* Block number -> reverse completion order. */
+ int *inverse_dfs_map; /* Block number -> DFS order. */
+ int *inverse_rts_map; /* Block number -> reverse top-sort order. */
};
@@ -171,18 +180,14 @@ struct df_map
/* Macros to access the elements within the ref structure. */
+
#define DF_REF_REAL_REG(REF) (GET_CODE ((REF)->reg) == SUBREG \
? SUBREG_REG ((REF)->reg) : ((REF)->reg))
#define DF_REF_REGNO(REF) REGNO (DF_REF_REAL_REG (REF))
#define DF_REF_REAL_LOC(REF) (GET_CODE ((REF)->reg) == SUBREG \
? &SUBREG_REG ((REF)->reg) : ((REF)->loc))
-#ifdef OLD_DF_INTERFACE
-#define DF_REF_REG(REF) DF_REF_REAL_REG(REF)
-#define DF_REF_LOC(REF) DF_REF_REAL_LOC(REF)
-#else
#define DF_REF_REG(REF) ((REF)->reg)
#define DF_REF_LOC(REF) ((REF)->loc)
-#endif
#define DF_REF_BB(REF) (BLOCK_FOR_INSN ((REF)->insn))
#define DF_REF_BBNO(REF) (BLOCK_FOR_INSN ((REF)->insn)->index)
#define DF_REF_INSN(REF) ((REF)->insn)
@@ -199,7 +204,7 @@ struct df_map
#define DF_REF_REG_MEM_STORE_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_MEM_STORE)
#define DF_REF_REG_MEM_LOAD_P(REF) (DF_REF_TYPE (REF) == DF_REF_REG_MEM_LOAD)
#define DF_REF_REG_MEM_P(REF) (DF_REF_REG_MEM_STORE_P (REF) \
- || DF_REF_REG_MEM_LOAD_P (REF))
+ || DF_REF_REG_MEM_LOAD_P (REF))
/* Macros to access the elements within the reg_info structure table. */
@@ -226,120 +231,121 @@ struct df_map
/* Functions to build and analyse dataflow information. */
-extern struct df *df_init PARAMS ((void));
+extern struct df *df_init (void);
+
+extern int df_analyse (struct df *, bitmap, int);
-extern int df_analyse PARAMS ((struct df *, bitmap, int));
+extern void df_finish (struct df *);
-extern void df_finish PARAMS ((struct df *));
+extern void df_dump (struct df *, int, FILE *);
-extern void df_dump PARAMS ((struct df *, int, FILE *));
/* Functions to modify insns. */
-extern void df_insn_modify PARAMS ((struct df *, basic_block, rtx));
+extern void df_insn_modify (struct df *, basic_block, rtx);
-extern rtx df_insn_delete PARAMS ((struct df *, basic_block, rtx));
+extern rtx df_insn_delete (struct df *, basic_block, rtx);
-extern rtx df_pattern_emit_before PARAMS ((struct df *, rtx,
- basic_block, rtx));
+extern rtx df_pattern_emit_before (struct df *, rtx, basic_block, rtx);
-extern rtx df_jump_pattern_emit_after PARAMS ((struct df *, rtx,
- basic_block, rtx));
+extern rtx df_jump_pattern_emit_after (struct df *, rtx, basic_block, rtx);
-extern rtx df_pattern_emit_after PARAMS ((struct df *, rtx,
- basic_block, rtx));
+extern rtx df_pattern_emit_after (struct df *, rtx, basic_block, rtx);
-extern rtx df_insn_move_before PARAMS ((struct df *, basic_block, rtx,
- basic_block, rtx));
+extern rtx df_insn_move_before (struct df *, basic_block, rtx, basic_block,
+ rtx);
-extern int df_reg_replace PARAMS ((struct df *, bitmap, rtx, rtx));
+extern int df_reg_replace (struct df *, bitmap, rtx, rtx);
-extern int df_ref_reg_replace PARAMS ((struct df *, struct ref *, rtx, rtx));
+extern int df_ref_reg_replace (struct df *, struct ref *, rtx, rtx);
-extern int df_ref_remove PARAMS ((struct df *, struct ref *));
+extern int df_ref_remove (struct df *, struct ref *);
-extern int df_insn_reg_replace PARAMS ((struct df *, basic_block,
- rtx, rtx, rtx));
+extern int df_insn_reg_replace (struct df *, basic_block, rtx, rtx, rtx);
-extern int df_insn_mem_replace PARAMS ((struct df *, basic_block,
- rtx, rtx, rtx));
+extern int df_insn_mem_replace (struct df *, basic_block, rtx, rtx, rtx);
-extern struct ref *df_bb_def_use_swap PARAMS ((struct df *, basic_block,
- rtx, rtx, unsigned int));
+extern struct ref *df_bb_def_use_swap (struct df *, basic_block, rtx, rtx,
+ unsigned int);
/* Functions to query dataflow information. */
-extern basic_block df_regno_bb PARAMS((struct df *, unsigned int));
+extern basic_block df_regno_bb (struct df *, unsigned int);
-extern int df_reg_lifetime PARAMS ((struct df *, rtx));
+extern int df_reg_lifetime (struct df *, rtx);
-extern int df_reg_global_p PARAMS ((struct df *, rtx));
+extern int df_reg_global_p (struct df *, rtx);
-extern int df_insn_regno_def_p PARAMS ((struct df *,
- basic_block, rtx, unsigned int));
+extern int df_insn_regno_def_p (struct df *, basic_block, rtx, unsigned int);
-extern int df_insn_dominates_all_uses_p PARAMS ((struct df *,
- basic_block, rtx));
+extern int df_insn_dominates_all_uses_p (struct df *, basic_block, rtx);
-extern int df_insn_dominates_uses_p PARAMS ((struct df *, basic_block,
- rtx, bitmap));
+extern int df_insn_dominates_uses_p (struct df *, basic_block, rtx, bitmap);
-extern int df_bb_reg_live_start_p PARAMS ((struct df *, basic_block, rtx));
+extern int df_bb_reg_live_start_p (struct df *, basic_block, rtx);
-extern int df_bb_reg_live_end_p PARAMS ((struct df *, basic_block, rtx));
+extern int df_bb_reg_live_end_p (struct df *, basic_block, rtx);
-extern int df_bb_regs_lives_compare PARAMS ((struct df *, basic_block,
- rtx, rtx));
+extern int df_bb_regs_lives_compare (struct df *, basic_block, rtx, rtx);
-extern rtx df_bb_single_def_use_insn_find PARAMS((struct df *, basic_block,
- rtx, rtx));
+extern rtx df_bb_single_def_use_insn_find (struct df *, basic_block, rtx,
+ rtx);
/* Functions for debugging from GDB. */
-extern void debug_df_insn PARAMS ((rtx));
+extern void debug_df_insn (rtx);
+
+extern void debug_df_regno (unsigned int);
+
+extern void debug_df_reg (rtx);
-extern void debug_df_regno PARAMS ((unsigned int));
+extern void debug_df_defno (unsigned int);
-extern void debug_df_reg PARAMS ((rtx));
+extern void debug_df_useno (unsigned int);
-extern void debug_df_defno PARAMS ((unsigned int));
+extern void debug_df_ref (struct ref *);
-extern void debug_df_useno PARAMS ((unsigned int));
+extern void debug_df_chain (struct df_link *);
-extern void debug_df_ref PARAMS ((struct ref *));
+extern void df_insn_debug (struct df *, rtx, FILE *);
-extern void debug_df_chain PARAMS ((struct df_link *));
-extern void df_insn_debug PARAMS ((struct df *, rtx, FILE *));
-extern void df_insn_debug_regno PARAMS ((struct df *, rtx, FILE *));
-/* Meet over any path (UNION) or meet over all paths (INTERSECTION) */
+extern void df_insn_debug_regno (struct df *, rtx, FILE *);
+
+
+/* Meet over any path (UNION) or meet over all paths (INTERSECTION). */
enum df_confluence_op
{
- UNION,
- INTERSECTION
+ DF_UNION,
+ DF_INTERSECTION
};
-/* Dataflow direction */
+
+
+/* Dataflow direction. */
enum df_flow_dir
{
- FORWARD,
- BACKWARD
+ DF_FORWARD,
+ DF_BACKWARD
};
-typedef void (*transfer_function_sbitmap) PARAMS ((int, int *, sbitmap, sbitmap,
- sbitmap, sbitmap, void *));
-typedef void (*transfer_function_bitmap) PARAMS ((int, int *, bitmap, bitmap,
- bitmap, bitmap, void *));
-
-extern void iterative_dataflow_sbitmap PARAMS ((sbitmap *, sbitmap *,
- sbitmap *, sbitmap *,
- bitmap, enum df_flow_dir,
- enum df_confluence_op,
- transfer_function_sbitmap,
- int *, void *));
-extern void iterative_dataflow_bitmap PARAMS ((bitmap *, bitmap *, bitmap *,
- bitmap *, bitmap,
- enum df_flow_dir,
- enum df_confluence_op,
- transfer_function_bitmap,
- int *, void *));
+
+typedef void (*transfer_function_sbitmap) (int, int *, sbitmap, sbitmap,
+ sbitmap, sbitmap, void *);
+
+typedef void (*transfer_function_bitmap) (int, int *, bitmap, bitmap,
+ bitmap, bitmap, void *);
+
+extern void iterative_dataflow_sbitmap (sbitmap *, sbitmap *, sbitmap *,
+ sbitmap *, bitmap, enum df_flow_dir,
+ enum df_confluence_op,
+ transfer_function_sbitmap,
+ int *, void *);
+
+extern void iterative_dataflow_bitmap (bitmap *, bitmap *, bitmap *,
+ bitmap *, bitmap,
+ enum df_flow_dir,
+ enum df_confluence_op,
+ transfer_function_bitmap,
+ int *, void *);
+extern bool read_modify_subreg_p (rtx);
diff --git a/contrib/gcc/diagnostic.c b/contrib/gcc/diagnostic.c
index a7f2d2c368ec..c29867a60b35 100644
--- a/contrib/gcc/diagnostic.c
+++ b/contrib/gcc/diagnostic.c
@@ -1,5 +1,5 @@
/* Language-independent diagnostic subroutines for the GNU Compiler Collection
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
This file is part of GCC.
@@ -27,6 +27,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#undef FLOAT /* This is for hpux. They should change hpux. */
#undef FFS /* Some systems define this in param.h. */
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "tm_p.h"
#include "flags.h"
@@ -37,770 +39,90 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "langhooks.h"
#include "langhooks-def.h"
-#define output_text_length(BUFFER) (BUFFER)->line_length
-#define is_starting_newline(BUFFER) (output_text_length (BUFFER) == 0)
-#define line_wrap_cutoff(BUFFER) (BUFFER)->state.maximum_length
-#define prefix_was_emitted_for(BUFFER) (BUFFER)->state.emitted_prefix_p
/* Prototypes. */
-static void output_flush PARAMS ((output_buffer *));
-static void output_do_verbatim PARAMS ((output_buffer *, text_info *));
-static void output_buffer_to_stream PARAMS ((output_buffer *));
-static void output_format PARAMS ((output_buffer *, text_info *));
-static void output_indent PARAMS ((output_buffer *));
-
-static char *vbuild_message_string PARAMS ((const char *, va_list))
- ATTRIBUTE_PRINTF (1, 0);
-static char *build_message_string PARAMS ((const char *, ...))
- ATTRIBUTE_PRINTF_1;
-static void format_with_decl PARAMS ((output_buffer *, text_info *, tree));
-static void diagnostic_for_decl PARAMS ((diagnostic_info *, tree));
-static void set_real_maximum_length PARAMS ((output_buffer *));
-
-static void output_unsigned_decimal PARAMS ((output_buffer *, unsigned int));
-static void output_long_decimal PARAMS ((output_buffer *, long int));
-static void output_long_unsigned_decimal PARAMS ((output_buffer *,
- long unsigned int));
-static void output_octal PARAMS ((output_buffer *, unsigned int));
-static void output_long_octal PARAMS ((output_buffer *, unsigned long int));
-static void output_hexadecimal PARAMS ((output_buffer *, unsigned int));
-static void output_long_hexadecimal PARAMS ((output_buffer *,
- unsigned long int));
-static void output_pointer PARAMS ((output_buffer *, void *));
-static void output_append_r PARAMS ((output_buffer *, const char *, int));
-static void wrap_text PARAMS ((output_buffer *, const char *, const char *));
-static void maybe_wrap_text PARAMS ((output_buffer *, const char *,
- const char *));
-static void output_clear_data PARAMS ((output_buffer *));
-
-static void default_diagnostic_starter PARAMS ((diagnostic_context *,
- diagnostic_info *));
-static void default_diagnostic_finalizer PARAMS ((diagnostic_context *,
- diagnostic_info *));
-
-static void error_recursion PARAMS ((diagnostic_context *)) ATTRIBUTE_NORETURN;
-static bool text_specifies_location PARAMS ((text_info *, location_t *));
+static char *build_message_string (const char *, ...) ATTRIBUTE_PRINTF_1;
+
+static void default_diagnostic_starter (diagnostic_context *,
+ diagnostic_info *);
+static void default_diagnostic_finalizer (diagnostic_context *,
+ diagnostic_info *);
+
+static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
+static bool text_specifies_location (text_info *, location_t *);
+static bool diagnostic_count_diagnostic (diagnostic_context *,
+ diagnostic_info *);
+static void diagnostic_action_after_output (diagnostic_context *,
+ diagnostic_info *);
+static void real_abort (void) ATTRIBUTE_NORETURN;
extern int rtl_dump_and_exit;
-extern int warnings_are_errors;
/* A diagnostic_context surrogate for stderr. */
static diagnostic_context global_diagnostic_context;
diagnostic_context *global_dc = &global_diagnostic_context;
-
-/* Subroutine of output_set_maximum_length. Set up BUFFER's
- internal maximum characters per line. */
-static void
-set_real_maximum_length (buffer)
- output_buffer *buffer;
-{
- /* If we're told not to wrap lines then do the obvious thing. In case
- we'll emit prefix only once per diagnostic message, it is appropriate
- not to increase unnecessarily the line-length cut-off. */
- if (!output_is_line_wrapping (buffer)
- || output_prefixing_rule (buffer) == DIAGNOSTICS_SHOW_PREFIX_ONCE
- || output_prefixing_rule (buffer) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
- line_wrap_cutoff (buffer) = output_line_cutoff (buffer);
- else
- {
- int prefix_length = buffer->state.prefix ?
- strlen (buffer->state.prefix) : 0;
- /* If the prefix is ridiculously too long, output at least
- 32 characters. */
- if (output_line_cutoff (buffer) - prefix_length < 32)
- line_wrap_cutoff (buffer) = output_line_cutoff (buffer) + 32;
- else
- line_wrap_cutoff (buffer) = output_line_cutoff (buffer);
- }
-}
-
-/* Sets the number of maximum characters per line BUFFER can output
- in line-wrapping mode. A LENGTH value 0 suppresses line-wrapping. */
-void
-output_set_maximum_length (buffer, length)
- output_buffer *buffer;
- int length;
-{
- output_line_cutoff (buffer) = length;
- set_real_maximum_length (buffer);
-}
-
-/* Sets BUFFER's PREFIX. */
-void
-output_set_prefix (buffer, prefix)
- output_buffer *buffer;
- const char *prefix;
-{
- buffer->state.prefix = prefix;
- set_real_maximum_length (buffer);
- prefix_was_emitted_for (buffer) = false;
- output_indentation (buffer) = 0;
-}
-
-/* Return a pointer to the last character emitted in the output
- BUFFER area. A NULL pointer means no character available. */
-const char *
-output_last_position (buffer)
- const output_buffer *buffer;
-{
- const char *p = NULL;
-
- if (obstack_base (&buffer->obstack) != obstack_next_free (&buffer->obstack))
- p = ((const char *) obstack_next_free (&buffer->obstack)) - 1;
- return p;
-}
-
-/* Free BUFFER's prefix, a previously malloc'd string. */
-void
-output_destroy_prefix (buffer)
- output_buffer *buffer;
-{
- if (buffer->state.prefix != NULL)
- {
- free ((char *) buffer->state.prefix);
- buffer->state.prefix = NULL;
- }
-}
-
-/* Zero out any text output so far in BUFFER. */
-void
-output_clear_message_text (buffer)
- output_buffer *buffer;
-{
- obstack_free (&buffer->obstack, obstack_base (&buffer->obstack));
- output_text_length (buffer) = 0;
-}
-
-/* Zero out any formatting data used so far by BUFFER. */
-static void
-output_clear_data (buffer)
- output_buffer *buffer;
-{
- prefix_was_emitted_for (buffer) = false;
- output_indentation (buffer) = 0;
-}
-
-/* Construct an output BUFFER with PREFIX and of MAXIMUM_LENGTH
- characters per line. */
-void
-init_output_buffer (buffer, prefix, maximum_length)
- output_buffer *buffer;
- const char *prefix;
- int maximum_length;
-{
- memset (buffer, 0, sizeof (output_buffer));
- obstack_init (&buffer->obstack);
- output_buffer_attached_stream (buffer) = stderr;
- output_line_cutoff (buffer) = maximum_length;
- output_prefixing_rule (buffer) = diagnostic_prefixing_rule (global_dc);
- output_set_prefix (buffer, prefix);
- output_text_length (buffer) = 0;
- output_clear_data (buffer);
-}
-
-/* Reinitialize BUFFER. */
-void
-output_clear (buffer)
- output_buffer *buffer;
-{
- output_clear_message_text (buffer);
- output_clear_data (buffer);
-}
-
-/* Finishes constructing a NULL-terminated character string representing
- the BUFFERed message. */
-const char *
-output_finalize_message (buffer)
- output_buffer *buffer;
-{
- obstack_1grow (&buffer->obstack, '\0');
- return output_message_text (buffer);
-}
-
-/* Return the amount of characters BUFFER can accept to
- make a full line. */
-int
-output_space_left (buffer)
- const output_buffer *buffer;
-{
- return line_wrap_cutoff (buffer) - output_text_length (buffer);
-}
-
-/* Write out BUFFER's prefix. */
-void
-output_emit_prefix (buffer)
- output_buffer *buffer;
-{
- if (buffer->state.prefix != NULL)
- {
- switch (output_prefixing_rule (buffer))
- {
- default:
- case DIAGNOSTICS_SHOW_PREFIX_NEVER:
- break;
-
- case DIAGNOSTICS_SHOW_PREFIX_ONCE:
- if (prefix_was_emitted_for (buffer))
- {
- output_indent (buffer);
- break;
- }
- output_indentation (buffer) += 3;
- /* Fall through. */
-
- case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
- {
- int prefix_length = strlen (buffer->state.prefix);
- output_append_r (buffer, buffer->state.prefix, prefix_length);
- prefix_was_emitted_for (buffer) = true;
- }
- break;
- }
- }
-}
-
-/* Have BUFFER start a new line. */
-void
-output_add_newline (buffer)
- output_buffer *buffer;
-{
- obstack_1grow (&buffer->obstack, '\n');
- output_text_length (buffer) = 0;
-}
-
-/* Appends a character to BUFFER. */
-void
-output_add_character (buffer, c)
- output_buffer *buffer;
- int c;
-{
- if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
- output_add_newline (buffer);
- obstack_1grow (&buffer->obstack, c);
- ++output_text_length (buffer);
-}
-
-/* Adds a space to BUFFER. */
-void
-output_add_space (buffer)
- output_buffer *buffer;
-{
- if (output_is_line_wrapping (buffer) && output_space_left (buffer) <= 0)
- {
- output_add_newline (buffer);
- return;
- }
- obstack_1grow (&buffer->obstack, ' ');
- ++output_text_length (buffer);
-}
-
-/* These functions format an INTEGER into BUFFER as suggested by their
- names. */
-void
-output_decimal (buffer, i)
- output_buffer *buffer;
- int i;
-{
- output_formatted_scalar (buffer, "%d", i);
-}
-
-static void
-output_long_decimal (buffer, i)
- output_buffer *buffer;
- long int i;
-{
- output_formatted_scalar (buffer, "%ld", i);
-}
-
-static void
-output_unsigned_decimal (buffer, i)
- output_buffer *buffer;
- unsigned int i;
-{
- output_formatted_scalar (buffer, "%u", i);
-}
-
-static void
-output_long_unsigned_decimal (buffer, i)
- output_buffer *buffer;
- long unsigned int i;
-{
- output_formatted_scalar (buffer, "%lu", i);
-}
-
-static void
-output_octal (buffer, i)
- output_buffer *buffer;
- unsigned int i;
-{
- output_formatted_scalar (buffer, "%o", i);
-}
-
-static void
-output_long_octal (buffer, i)
- output_buffer *buffer;
- unsigned long int i;
-{
- output_formatted_scalar (buffer, "%lo", i);
-}
-
-static void
-output_hexadecimal (buffer, i)
- output_buffer *buffer;
- unsigned int i;
-{
- output_formatted_scalar (buffer, "%x", i);
-}
-
-static void
-output_long_hexadecimal (buffer, i)
- output_buffer *buffer;
- unsigned long int i;
-{
- output_formatted_scalar (buffer, "%lx", i);
-}
-
-static void
-output_pointer (buffer, p)
- output_buffer *buffer;
- void *p;
-{
- output_formatted_scalar (buffer, HOST_PTR_PRINTF, p);
-}
-
-/* Append to BUFFER a string specified by its STARTING character
- and LENGTH. */
-static void
-output_append_r (buffer, start, length)
- output_buffer *buffer;
- const char *start;
- int length;
-{
- obstack_grow (&buffer->obstack, start, length);
- output_text_length (buffer) += length;
-}
-
-/* Append a string deliminated by START and END to BUFFER. No wrapping is
- done. However, if beginning a new line then emit BUFFER->state.prefix
- and skip any leading whitespace if appropriate. The caller must ensure
- that it is safe to do so. */
-void
-output_append (buffer, start, end)
- output_buffer *buffer;
- const char *start;
- const char *end;
-{
- /* Emit prefix and skip whitespace if we're starting a new line. */
- if (is_starting_newline (buffer))
- {
- output_emit_prefix (buffer);
- if (output_is_line_wrapping (buffer))
- while (start != end && *start == ' ')
- ++start;
- }
- output_append_r (buffer, start, end - start);
-}
-
-static void
-output_indent (buffer)
- output_buffer *buffer;
-{
- int n = output_indentation (buffer);
- int i;
-
- for (i = 0; i < n; ++i)
- output_add_character (buffer, ' ');
-}
-
-/* Wrap a text delimited by START and END into BUFFER. */
-static void
-wrap_text (buffer, start, end)
- output_buffer *buffer;
- const char *start;
- const char *end;
-{
- bool is_wrapping = output_is_line_wrapping (buffer);
-
- while (start != end)
- {
- /* Dump anything bordered by whitespaces. */
- {
- const char *p = start;
- while (p != end && *p != ' ' && *p != '\n')
- ++p;
- if (is_wrapping && p - start >= output_space_left (buffer))
- output_add_newline (buffer);
- output_append (buffer, start, p);
- start = p;
- }
-
- if (start != end && *start == ' ')
- {
- output_add_space (buffer);
- ++start;
- }
- if (start != end && *start == '\n')
- {
- output_add_newline (buffer);
- ++start;
- }
- }
-}
-
-/* Same as wrap_text but wrap text only when in line-wrapping mode. */
-static void
-maybe_wrap_text (buffer, start, end)
- output_buffer *buffer;
- const char *start;
- const char *end;
-{
- if (output_is_line_wrapping (buffer))
- wrap_text (buffer, start, end);
- else
- output_append (buffer, start, end);
-}
-
-
-/* Append a STRING to BUFFER; the STRING might be line-wrapped if in
- appropriate mode. */
-void
-output_add_string (buffer, str)
- output_buffer *buffer;
- const char *str;
-{
- maybe_wrap_text (buffer, str, str + (str ? strlen (str) : 0));
-}
-
-/* Append an identifier ID to BUFFER. */
-void
-output_add_identifier (buffer, id)
- output_buffer *buffer;
- tree id;
-{
- output_append (buffer, IDENTIFIER_POINTER (id),
- IDENTIFIER_POINTER (id) + IDENTIFIER_LENGTH (id));
-}
-
-/* Flush the content of BUFFER onto the attached stream,
- and reinitialize. */
-
-static void
-output_buffer_to_stream (buffer)
- output_buffer *buffer;
-{
- const char *text = output_finalize_message (buffer);
- fputs (text, output_buffer_attached_stream (buffer));
- output_clear_message_text (buffer);
-}
-
-/* Format a message pointed to by TEXT. The following format specifiers are
- recognized as being language independent:
- %d, %i: (signed) integer in base ten.
- %u: unsigned integer in base ten.
- %o: unsigned integer in base eight.
- %x: unsigned integer in base sixteen.
- %ld, %li, %lo, %lu, %lx: long versions of the above.
- %c: character.
- %s: string.
- %p: pointer.
- %%: `%'.
- %*.s: a substring the length of which is specified by an integer.
- %H: location_t. */
-static void
-output_format (buffer, text)
- output_buffer *buffer;
- text_info *text;
-{
- for (; *text->format_spec; ++text->format_spec)
- {
- bool long_integer = 0;
-
- /* Ignore text. */
- {
- const char *p = text->format_spec;
- while (*p && *p != '%')
- ++p;
- wrap_text (buffer, text->format_spec, p);
- text->format_spec = p;
- }
-
- if (*text->format_spec == '\0')
- break;
-
- /* We got a '%'. Let's see what happens. Record whether we're
- parsing a long integer format specifier. */
- if (*++text->format_spec == 'l')
- {
- long_integer = true;
- ++text->format_spec;
- }
-
- /* Handle %c, %d, %i, %ld, %li, %lo, %lu, %lx, %o, %s, %u,
- %x, %.*s; %%. And nothing else. Front-ends should install
- printers to grok language specific format specifiers. */
- switch (*text->format_spec)
- {
- case 'c':
- output_add_character (buffer, va_arg (*text->args_ptr, int));
- break;
-
- case 'd':
- case 'i':
- if (long_integer)
- output_long_decimal (buffer, va_arg (*text->args_ptr, long int));
- else
- output_decimal (buffer, va_arg (*text->args_ptr, int));
- break;
-
- case 'o':
- if (long_integer)
- output_long_octal (buffer,
- va_arg (*text->args_ptr, unsigned long int));
- else
- output_octal (buffer, va_arg (*text->args_ptr, unsigned int));
- break;
-
- case 's':
- output_add_string (buffer, va_arg (*text->args_ptr, const char *));
- break;
-
- case 'p':
- output_pointer (buffer, va_arg (*text->args_ptr, void *));
- break;
-
- case 'u':
- if (long_integer)
- output_long_unsigned_decimal
- (buffer, va_arg (*text->args_ptr, long unsigned int));
- else
- output_unsigned_decimal
- (buffer, va_arg (*text->args_ptr, unsigned int));
- break;
-
- case 'x':
- if (long_integer)
- output_long_hexadecimal
- (buffer, va_arg (*text->args_ptr, unsigned long int));
- else
- output_hexadecimal
- (buffer, va_arg (*text->args_ptr, unsigned int));
- break;
-
- case '%':
- output_add_character (buffer, '%');
- break;
-
- case 'H':
- {
- const location_t *locus = va_arg (*text->args_ptr, location_t *);
- output_add_string (buffer, "file '");
- output_add_string (buffer, locus->file);
- output_add_string (buffer, "', line ");
- output_decimal (buffer, locus->line);
- }
- break;
-
- case '.':
- {
- int n;
- const char *s;
- /* We handle no precision specifier but `%.*s'. */
- if (*++text->format_spec != '*')
- abort ();
- else if (*++text->format_spec != 's')
- abort ();
- n = va_arg (*text->args_ptr, int);
- s = va_arg (*text->args_ptr, const char *);
- output_append (buffer, s, s + n);
- }
- break;
-
- default:
- if (!buffer->format_decoder
- || !(*buffer->format_decoder) (buffer, text))
- {
- /* Hmmm. The front-end failed to install a format translator
- but called us with an unrecognized format. Sorry. */
- abort ();
- }
- }
- }
-}
+/* Boilerplate text used in two locations. */
+#define bug_report_request \
+"Please submit a full bug report,\n\
+with preprocessed source if appropriate.\n\
+See %s for instructions.\n"
+
+/* Return a malloc'd string containing MSG formatted a la printf. The
+ caller is responsible for freeing the memory. */
static char *
-vbuild_message_string (msg, ap)
- const char *msg;
- va_list ap;
+build_message_string (const char *msg, ...)
{
char *str;
+ va_list ap;
+ va_start (ap, msg);
vasprintf (&str, msg, ap);
- return str;
-}
-
-/* Return a malloc'd string containing MSG formatted a la
- printf. The caller is responsible for freeing the memory. */
-static char *
-build_message_string VPARAMS ((const char *msg, ...))
-{
- char *str;
-
- VA_OPEN (ap, msg);
- VA_FIXEDARG (ap, const char *, msg);
-
- str = vbuild_message_string (msg, ap);
-
- VA_CLOSE (ap);
+ va_end (ap);
return str;
}
-/* Same as diagnsotic_build_prefix, but only the source FILE is given. */
+/* Same as diagnostic_build_prefix, but only the source FILE is given. */
char *
-file_name_as_prefix (f)
- const char *f;
+file_name_as_prefix (const char *f)
{
return build_message_string ("%s: ", f);
}
-/* Format a message into BUFFER a la printf. */
-void
-output_printf VPARAMS ((struct output_buffer *buffer, const char *msgid, ...))
-{
- text_info text;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, output_buffer *, buffer);
- VA_FIXEDARG (ap, const char *, msgid);
-
- text.args_ptr = &ap;
- text.format_spec = _(msgid);
- output_format (buffer, &text);
- VA_CLOSE (ap);
-}
-
-/* Print a message relevant to the given DECL. */
-static void
-format_with_decl (buffer, text, decl)
- output_buffer *buffer;
- text_info *text;
- tree decl;
-{
- const char *p;
-
- /* Do magic to get around lack of varargs support for insertion
- of arguments into existing list. We know that the decl is first;
- we ass_u_me that it will be printed with "%s". */
- for (p = text->format_spec; *p; ++p)
- {
- if (*p == '%')
- {
- if (*(p + 1) == '%')
- ++p;
- else if (*(p + 1) != 's')
- abort ();
- else
- break;
- }
- }
-
- /* Print the left-hand substring. */
- maybe_wrap_text (buffer, text->format_spec, p);
-
- if (*p == '%') /* Print the name. */
- {
- const char *const n = (DECL_NAME (decl)
- ? (*lang_hooks.decl_printable_name) (decl, 2)
- : _("((anonymous))"));
- output_add_string (buffer, n);
- while (*p)
- {
- ++p;
- if (ISALPHA (*(p - 1) & 0xFF))
- break;
- }
- }
-
- if (*p) /* Print the rest of the message. */
- {
- text->format_spec = p;
- output_format (buffer, text);
- }
-}
-
-/* Flush the content of BUFFER onto the attached stream. */
-static void
-output_flush (buffer)
- output_buffer *buffer;
-{
- output_buffer_to_stream (buffer);
- output_clear_data (buffer);
- fputc ('\n', output_buffer_attached_stream (buffer));
- fflush (output_buffer_attached_stream (buffer));
-}
-
-/* Helper subroutine of output_verbatim and verbatim. Do the appropriate
- settings needed by BUFFER for a verbatim formatting. */
-static void
-output_do_verbatim (buffer, text)
- output_buffer *buffer;
- text_info *text;
-{
- diagnostic_prefixing_rule_t rule = output_prefixing_rule (buffer);
- int line_cutoff = output_line_cutoff (buffer);
-
- /* Set verbatim mode. */
- output_prefixing_rule (buffer) = DIAGNOSTICS_SHOW_PREFIX_NEVER;
- output_line_cutoff (buffer) = 0;
- /* Do the actual formatting. */
- output_format (buffer, text);
- /* Restore previous settings. */
- output_prefixing_rule (buffer) = rule;
- output_line_cutoff (buffer) = line_cutoff;
-}
-
-/* Output MESSAGE verbatim into BUFFER. */
-void
-output_verbatim VPARAMS ((output_buffer *buffer, const char *msgid, ...))
-{
- text_info text;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, output_buffer *, buffer);
- VA_FIXEDARG (ap, const char *, msgid);
-
- text.format_spec = msgid;
- text.args_ptr = &ap;
- output_do_verbatim (buffer, &text);
- VA_CLOSE (ap);
-}
/* Initialize the diagnostic message outputting machinery. */
void
-diagnostic_initialize (context)
- diagnostic_context *context;
+diagnostic_initialize (diagnostic_context *context)
{
- memset (context, 0, sizeof *context);
- obstack_init (&context->buffer.obstack);
-
+ /* Allocate a basic pretty-printer. Clients will replace this a
+ much more elaborated pretty-printer if they wish. */
+ context->printer = xmalloc (sizeof (pretty_printer));
+ pp_construct (context->printer, NULL, 0);
/* By default, diagnostics are sent to stderr. */
- output_buffer_attached_stream (&context->buffer) = stderr;
-
+ context->printer->buffer->stream = stderr;
/* By default, we emit prefixes once per message. */
- diagnostic_prefixing_rule (context) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
+ context->printer->prefixing_rule = DIAGNOSTICS_SHOW_PREFIX_ONCE;
+ memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
+ context->warnings_are_errors_message = warnings_are_errors;
+ context->abort_on_error = false;
+ context->internal_error = NULL;
diagnostic_starter (context) = default_diagnostic_starter;
diagnostic_finalizer (context) = default_diagnostic_finalizer;
- context->warnings_are_errors_message = warnings_are_errors;
+ context->last_module = 0;
+ context->last_function = NULL;
+ context->lock = 0;
+ context->x_data = NULL;
}
/* Returns true if the next format specifier in TEXT is a format specifier
for a location_t. If so, update the object pointed by LOCUS to reflect
the specified location in *TEXT->args_ptr. */
static bool
-text_specifies_location (text, locus)
- text_info *text;
- location_t *locus;
+text_specifies_location (text_info *text, location_t *locus)
{
const char *p;
/* Skip any leading text. */
@@ -808,10 +130,17 @@ text_specifies_location (text, locus)
;
/* Extract the location information if any. */
- if (*p == '%' && *++p == 'H')
+ if (p[0] == '%' && p[1] == 'H')
{
*locus = *va_arg (*text->args_ptr, location_t *);
- text->format_spec = p + 1;
+ text->format_spec = p + 2;
+ return true;
+ }
+ else if (p[0] == '%' && p[1] == 'J')
+ {
+ tree t = va_arg (*text->args_ptr, tree);
+ *locus = DECL_SOURCE_LOCATION (t);
+ text->format_spec = p + 2;
return true;
}
@@ -819,31 +148,24 @@ text_specifies_location (text, locus)
}
void
-diagnostic_set_info (diagnostic, msgid, args, file, line, kind)
- diagnostic_info *diagnostic;
- const char *msgid;
- va_list *args;
- const char *file;
- int line;
- diagnostic_t kind;
+diagnostic_set_info (diagnostic_info *diagnostic, const char *msgid,
+ va_list *args, location_t location,
+ diagnostic_t kind)
{
- diagnostic->message.format_spec = msgid;
+ diagnostic->message.err_no = errno;
diagnostic->message.args_ptr = args;
- /* If the diagnostic message doesn't specify a loccation,
- use FILE and LINE. */
+ diagnostic->message.format_spec = _(msgid);
+ /* If the diagnostic message doesn't specify a location,
+ use LOCATION. */
if (!text_specifies_location (&diagnostic->message, &diagnostic->location))
- {
- diagnostic->location.file = file;
- diagnostic->location.line = line;
- }
+ diagnostic->location = location;
diagnostic->kind = kind;
}
/* Return a malloc'd string describing a location. The caller is
responsible for freeing the memory. */
char *
-diagnostic_build_prefix (diagnostic)
- diagnostic_info *diagnostic;
+diagnostic_build_prefix (diagnostic_info *diagnostic)
{
static const char *const diagnostic_kind_text[] = {
#define DEFINE_DIAGNOSTIC_KIND(K, T) (T),
@@ -863,50 +185,38 @@ diagnostic_build_prefix (diagnostic)
_(diagnostic_kind_text[diagnostic->kind]));
}
-/* Report a diagnostic MESSAGE at the declaration DECL.
- MSG is a format string which uses %s to substitute the declaration
- name; subsequent substitutions are a la output_format. */
-static void
-diagnostic_for_decl (diagnostic, decl)
- diagnostic_info *diagnostic;
- tree decl;
-{
- if (global_dc->lock++)
- error_recursion (global_dc);
-
- if (diagnostic_count_diagnostic (global_dc, diagnostic->kind))
- {
- diagnostic_report_current_function (global_dc);
- output_set_prefix
- (&global_dc->buffer, diagnostic_build_prefix (diagnostic));
- format_with_decl (&global_dc->buffer, &diagnostic->message, decl);
- output_flush (&global_dc->buffer);
- output_destroy_prefix (&global_dc->buffer);
- }
- global_dc->lock--;
-}
-
-void
-diagnostic_flush_buffer (context)
- diagnostic_context *context;
-{
- output_buffer_to_stream (&context->buffer);
- fflush (output_buffer_attached_stream (&context->buffer));
-}
-
/* Count a diagnostic. Return true if the message should be printed. */
-bool
-diagnostic_count_diagnostic (context, kind)
- diagnostic_context *context;
- diagnostic_t kind;
+static bool
+diagnostic_count_diagnostic (diagnostic_context *context,
+ diagnostic_info *diagnostic)
{
+ diagnostic_t kind = diagnostic->kind;
switch (kind)
{
default:
abort();
break;
- case DK_FATAL: case DK_ICE: case DK_SORRY:
+ case DK_ICE:
+#ifndef ENABLE_CHECKING
+ /* When not checking, ICEs are converted to fatal errors when an
+ error has already occurred. This is counteracted by
+ abort_on_error. */
+ if ((diagnostic_kind_count (context, DK_ERROR) > 0
+ || diagnostic_kind_count (context, DK_SORRY) > 0)
+ && !context->abort_on_error)
+ {
+ fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
+ diagnostic->location.file, diagnostic->location.line);
+ exit (FATAL_EXIT_CODE);
+ }
+#endif
+ if (context->internal_error)
+ (*context->internal_error) (diagnostic->message.format_spec,
+ diagnostic->message.args_ptr);
+ /* Fall through. */
+
+ case DK_FATAL: case DK_SORRY:
case DK_ANACHRONISM: case DK_NOTE:
++diagnostic_kind_count (context, kind);
break;
@@ -914,20 +224,22 @@ diagnostic_count_diagnostic (context, kind)
case DK_WARNING:
if (!diagnostic_report_warnings_p ())
return false;
- else if (!warnings_are_errors)
+
+ if (!warnings_are_errors)
{
++diagnostic_kind_count (context, DK_WARNING);
break;
}
- /* else fall through. */
- case DK_ERROR:
- if (kind == DK_WARNING && context->warnings_are_errors_message)
+ if (context->warnings_are_errors_message)
{
- output_verbatim (&context->buffer,
- "%s: warnings being treated as errors\n", progname);
+ pp_verbatim (context->printer,
+ "%s: warnings being treated as errors\n", progname);
context->warnings_are_errors_message = false;
}
+
+ /* And fall through. */
+ case DK_ERROR:
++diagnostic_kind_count (context, DK_ERROR);
break;
}
@@ -935,164 +247,42 @@ diagnostic_count_diagnostic (context, kind)
return true;
}
-/* Print a diagnostic MSGID on FILE. This is just fprintf, except it
- runs its second argument through gettext. */
-void
-fnotice VPARAMS ((FILE *file, const char *msgid, ...))
-{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, FILE *, file);
- VA_FIXEDARG (ap, const char *, msgid);
-
- vfprintf (file, _(msgid), ap);
- VA_CLOSE (ap);
-}
-
-
-/* Print a fatal I/O error message. Argument are like printf.
- Also include a system error message based on `errno'. */
-void
-fatal_io_error VPARAMS ((const char *msgid, ...))
-{
- text_info text;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
- text.format_spec = _(msgid);
- text.args_ptr = &ap;
- output_printf (&global_dc->buffer, "%s: %s: ", progname, xstrerror (errno));
- output_format (&global_dc->buffer, &text);
- output_flush (&global_dc->buffer);
- VA_CLOSE (ap);
- exit (FATAL_EXIT_CODE);
-}
-
-/* Issue a pedantic warning MSGID. */
-void
-pedwarn VPARAMS ((const char *msgid, ...))
-{
- diagnostic_info diagnostic;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
- diagnostic_set_info (&diagnostic, _(msgid), &ap, input_filename, lineno,
- pedantic_error_kind ());
- report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
-}
-
-/* Issue a pedantic warning about DECL. */
-void
-pedwarn_with_decl VPARAMS ((tree decl, const char *msgid, ...))
-{
- diagnostic_info diagnostic;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, tree, decl);
- VA_FIXEDARG (ap, const char *, msgid);
-
- diagnostic_set_info (&diagnostic, _(msgid), &ap,
- DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
- pedantic_error_kind ());
-
- /* We don't want -pedantic-errors to cause the compilation to fail from
- "errors" in system header files. Sometimes fixincludes can't fix what's
- broken (eg: unsigned char bitfields - fixing it may change the alignment
- which will cause programs to mysteriously fail because the C library
- or kernel uses the original layout). There's no point in issuing a
- warning either, it's just unnecessary noise. */
- if (!DECL_IN_SYSTEM_HEADER (decl))
- diagnostic_for_decl (&diagnostic, decl);
- VA_CLOSE (ap);
-}
-
-/* Same as above but within the context FILE and LINE. */
-void
-pedwarn_with_file_and_line VPARAMS ((const char *file, int line,
- const char *msgid, ...))
-{
- diagnostic_info diagnostic;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, file);
- VA_FIXEDARG (ap, int, line);
- VA_FIXEDARG (ap, const char *, msgid);
-
- diagnostic_set_info (&diagnostic, _(msgid), &ap, file, line,
- pedantic_error_kind ());
- report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
-}
-
-/* Just apologize with MSGID. */
-void
-sorry VPARAMS ((const char *msgid, ...))
+/* Take any action which is expected to happen after the diagnostic
+ is written out. This function does not always return. */
+static void
+diagnostic_action_after_output (diagnostic_context *context,
+ diagnostic_info *diagnostic)
{
- diagnostic_info diagnostic;
-
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
- ++sorrycount;
- diagnostic_set_info (&diagnostic, _(msgid), &ap,
- input_filename, lineno, DK_SORRY);
+ switch (diagnostic->kind)
+ {
+ case DK_DEBUG:
+ case DK_NOTE:
+ case DK_ANACHRONISM:
+ case DK_WARNING:
+ break;
- output_set_prefix
- (&global_dc->buffer, diagnostic_build_prefix (&diagnostic));
- output_format (&global_dc->buffer, &diagnostic.message);
- output_flush (&global_dc->buffer);
- VA_CLOSE (ap);
-}
+ case DK_ERROR:
+ case DK_SORRY:
+ if (context->abort_on_error)
+ real_abort ();
+ break;
-/* Called when the start of a function definition is parsed,
- this function prints on stderr the name of the function. */
-void
-announce_function (decl)
- tree decl;
-{
- if (!quiet_flag)
- {
- if (rtl_dump_and_exit)
- verbatim ("%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
- else
- verbatim (" %s", (*lang_hooks.decl_printable_name) (decl, 2));
- fflush (stderr);
- output_needs_newline (&global_dc->buffer) = true;
- diagnostic_set_last_function (global_dc);
- }
-}
+ case DK_ICE:
+ if (context->abort_on_error)
+ real_abort ();
-/* The default function to print out name of current function that caused
- an error. */
-void
-lhd_print_error_function (context, file)
- diagnostic_context *context;
- const char *file;
-{
- if (diagnostic_last_function_changed (context))
- {
- const char *old_prefix = output_prefix (&context->buffer);
- char *new_prefix = file ? build_message_string ("%s: ", file) : NULL;
+ fnotice (stderr, bug_report_request, bug_report_url);
+ exit (FATAL_EXIT_CODE);
- output_set_prefix (&context->buffer, new_prefix);
+ case DK_FATAL:
+ if (context->abort_on_error)
+ real_abort ();
- if (current_function_decl == NULL)
- output_add_string (&context->buffer, _("At top level:"));
- else
- {
- if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
- output_printf
- (&context->buffer, "In member function `%s':",
- (*lang_hooks.decl_printable_name) (current_function_decl, 2));
- else
- output_printf
- (&context->buffer, "In function `%s':",
- (*lang_hooks.decl_printable_name) (current_function_decl, 2));
- }
- output_add_newline (&context->buffer);
+ fnotice (stderr, "compilation terminated.\n");
+ exit (FATAL_EXIT_CODE);
- diagnostic_set_last_function (context);
- output_buffer_to_stream (&context->buffer);
- context->buffer.state.prefix = old_prefix;
- free ((char*) new_prefix);
+ default:
+ real_abort ();
}
}
@@ -1101,176 +291,51 @@ lhd_print_error_function (context, file)
We ignore the FILE parameter, as it cannot be relied upon. */
void
-diagnostic_report_current_function (context)
- diagnostic_context *context;
+diagnostic_report_current_function (diagnostic_context *context)
{
diagnostic_report_current_module (context);
(*lang_hooks.print_error_function) (context, input_filename);
}
void
-error_with_file_and_line VPARAMS ((const char *file, int line,
- const char *msgid, ...))
-{
- diagnostic_info diagnostic;
-
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, file);
- VA_FIXEDARG (ap, int, line);
- VA_FIXEDARG (ap, const char *, msgid);
-
- diagnostic_set_info (&diagnostic, msgid, &ap, file, line, DK_ERROR);
- report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
-}
-
-void
-error_with_decl VPARAMS ((tree decl, const char *msgid, ...))
-{
- diagnostic_info diagnostic;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, tree, decl);
- VA_FIXEDARG (ap, const char *, msgid);
-
- diagnostic_set_info (&diagnostic, msgid, &ap,
- DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
- DK_ERROR);
- diagnostic_for_decl (&diagnostic, decl);
- VA_CLOSE (ap);
-}
-
-
-/* Report an error message. The arguments are like that of printf. */
-
-void
-error VPARAMS ((const char *msgid, ...))
-{
- diagnostic_info diagnostic;
-
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
- diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
- DK_ERROR);
- report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
-}
-
-/* Likewise, except that the compilation is terminated after printing the
- error message. */
-
-void
-fatal_error VPARAMS ((const char *msgid, ...))
+diagnostic_report_current_module (diagnostic_context *context)
{
- diagnostic_info diagnostic;
-
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
- diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
- DK_FATAL);
- report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
-
- fnotice (stderr, "compilation terminated.\n");
- exit (FATAL_EXIT_CODE);
-}
-
-void
-internal_error VPARAMS ((const char *msgid, ...))
-{
- diagnostic_info diagnostic;
-
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
- if (global_dc->lock)
- error_recursion (global_dc);
+ struct file_stack *p;
-#ifndef ENABLE_CHECKING
- if (errorcount > 0 || sorrycount > 0)
+ if (pp_needs_newline (context->printer))
{
- fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
- input_filename, lineno);
- exit (FATAL_EXIT_CODE);
+ pp_newline (context->printer);
+ pp_needs_newline (context->printer) = false;
}
-#endif
-
- if (global_dc->internal_error != 0)
- (*global_dc->internal_error) (_(msgid), &ap);
-
- diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
- DK_ICE);
- report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
-
- fnotice (stderr,
-"Please submit a full bug report,\n\
-with preprocessed source if appropriate.\n\
-See %s for instructions.\n", bug_report_url);
- exit (FATAL_EXIT_CODE);
-}
-
-void
-warning_with_file_and_line VPARAMS ((const char *file, int line,
- const char *msgid, ...))
-{
- diagnostic_info diagnostic;
-
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, file);
- VA_FIXEDARG (ap, int, line);
- VA_FIXEDARG (ap, const char *, msgid);
-
- diagnostic_set_info (&diagnostic, msgid, &ap, file, line, DK_WARNING);
- report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
-}
-void
-warning_with_decl VPARAMS ((tree decl, const char *msgid, ...))
-{
- diagnostic_info diagnostic;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, tree, decl);
- VA_FIXEDARG (ap, const char *, msgid);
-
- diagnostic_set_info (&diagnostic, msgid, &ap,
- DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
- DK_WARNING);
- diagnostic_for_decl (&diagnostic, decl);
- VA_CLOSE (ap);
+ if (input_file_stack && diagnostic_last_module_changed (context))
+ {
+ p = input_file_stack;
+ pp_verbatim (context->printer,
+ "In file included from %s:%d",
+ p->location.file, p->location.line);
+ while ((p = p->next) != NULL)
+ pp_verbatim (context->printer,
+ ",\n from %s:%d",
+ p->location.file, p->location.line);
+ pp_verbatim (context->printer, ":\n");
+ diagnostic_set_last_module (context);
+ }
}
-void
-warning VPARAMS ((const char *msgid, ...))
+static void
+default_diagnostic_starter (diagnostic_context *context,
+ diagnostic_info *diagnostic)
{
- diagnostic_info diagnostic;
-
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
- diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
- DK_WARNING);
- report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
+ diagnostic_report_current_function (context);
+ pp_set_prefix (context->printer, diagnostic_build_prefix (diagnostic));
}
-
-/* Same as above but use diagnostic_buffer. */
-
-void
-verbatim VPARAMS ((const char *msgid, ...))
+static void
+default_diagnostic_finalizer (diagnostic_context *context,
+ diagnostic_info *diagnostic __attribute__((unused)))
{
- text_info text;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
- text.format_spec = _(msgid);
- text.args_ptr = &ap;
- output_do_verbatim (&global_dc->buffer, &text);
- output_buffer_to_stream (&global_dc->buffer);
- VA_CLOSE (ap);
+ pp_destroy_prefix (context->printer);
}
/* Report a diagnostic message (an error or a warning) as specified by
@@ -1280,43 +345,22 @@ verbatim VPARAMS ((const char *msgid, ...))
in the documentation of output_format. */
void
-diagnostic_report_diagnostic (context, diagnostic)
- diagnostic_context *context;
- diagnostic_info *diagnostic;
+diagnostic_report_diagnostic (diagnostic_context *context,
+ diagnostic_info *diagnostic)
{
- if (context->lock++)
+ if (context->lock++ && diagnostic->kind < DK_SORRY)
error_recursion (context);
- if (diagnostic_count_diagnostic (context, diagnostic->kind))
+ if (diagnostic_count_diagnostic (context, diagnostic))
{
(*diagnostic_starter (context)) (context, diagnostic);
- output_format (&context->buffer, &diagnostic->message);
+ pp_format_text (context->printer, &diagnostic->message);
(*diagnostic_finalizer (context)) (context, diagnostic);
- output_flush (&context->buffer);
+ pp_flush (context->printer);
+ diagnostic_action_after_output (context, diagnostic);
}
- --context->lock;
-}
-
-/* Inform the user that an error occurred while trying to report some
- other error. This indicates catastrophic internal inconsistencies,
- so give up now. But do try to flush out the previous error.
- This mustn't use internal_error, that will cause infinite recursion. */
-
-static void
-error_recursion (context)
- diagnostic_context *context;
-{
- if (context->lock < 3)
- output_flush (&context->buffer);
-
- fnotice (stderr,
- "Internal compiler error: Error reporting routines re-entered.\n");
- fnotice (stderr,
-"Please submit a full bug report,\n\
-with preprocessed source if appropriate.\n\
-See %s for instructions.\n", bug_report_url);
- exit (FATAL_EXIT_CODE);
+ context->lock--;
}
/* Given a partial pathname as input, return another pathname that
@@ -1325,8 +369,7 @@ See %s for instructions.\n", bug_report_url);
instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */
const char *
-trim_filename (name)
- const char *name;
+trim_filename (const char *name)
{
static const char this_file[] = __FILE__;
const char *p = name, *q = this_file;
@@ -1363,111 +406,190 @@ trim_filename (name)
return p;
}
+
+/* Standard error reporting routines in increasing order of severity.
+ All of these take arguments like printf. */
+
+/* Text to be emitted verbatim to the error message stream; this
+ produces no prefix and disables line-wrapping. Use rarely. */
+void
+verbatim (const char *msgid, ...)
+{
+ text_info text;
+ va_list ap;
-/* Report an internal compiler error in a friendly manner and without
- dumping core. */
+ va_start (ap, msgid);
+ text.err_no = errno;
+ text.args_ptr = &ap;
+ text.format_spec = _(msgid);
+ pp_format_verbatim (global_dc->printer, &text);
+ pp_flush (global_dc->printer);
+ va_end (ap);
+}
+/* An informative note. Use this for additional details on an error
+ message. */
void
-fancy_abort (file, line, function)
- const char *file;
- int line;
- const char *function;
+inform (const char *msgid, ...)
{
- internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
+ diagnostic_info diagnostic;
+ va_list ap;
+
+ va_start (ap, msgid);
+ diagnostic_set_info (&diagnostic, msgid, &ap, input_location, DK_NOTE);
+ report_diagnostic (&diagnostic);
+ va_end (ap);
}
+/* A warning. Use this for code which is correct according to the
+ relevant language specification but is likely to be buggy anyway. */
void
-diagnostic_report_current_module (context)
- diagnostic_context *context;
+warning (const char *msgid, ...)
{
- struct file_stack *p;
+ diagnostic_info diagnostic;
+ va_list ap;
- if (output_needs_newline (&context->buffer))
- {
- output_add_newline (&context->buffer);
- output_needs_newline (&context->buffer) = false;
- }
+ va_start (ap, msgid);
+ diagnostic_set_info (&diagnostic, msgid, &ap, input_location, DK_WARNING);
+ report_diagnostic (&diagnostic);
+ va_end (ap);
+}
- if (input_file_stack && input_file_stack->next != 0
- && diagnostic_last_module_changed (context))
- {
- for (p = input_file_stack->next; p; p = p->next)
- if (p == input_file_stack->next)
- output_verbatim (&context->buffer,
- "In file included from %s:%d", p->name, p->line);
- else
- output_verbatim (&context->buffer,
- ",\n from %s:%d", p->name, p->line);
- output_verbatim (&context->buffer, ":\n");
- diagnostic_set_last_module (context);
- }
+/* A "pedantic" warning: issues a warning unless -pedantic-errors was
+ given on the command line, in which case it issues an error. Use
+ this for diagnostics required by the relevant language standard,
+ if you have chosen not to make them errors.
+
+ Note that these diagnostics are issued independent of the setting
+ of the -pedantic command-line switch. To get a warning enabled
+ only with that switch, write "if (pedantic) pedwarn (...);" */
+void
+pedwarn (const char *msgid, ...)
+{
+ diagnostic_info diagnostic;
+ va_list ap;
+
+ va_start (ap, msgid);
+ diagnostic_set_info (&diagnostic, msgid, &ap, input_location,
+ pedantic_error_kind ());
+ report_diagnostic (&diagnostic);
+ va_end (ap);
}
-static void
-default_diagnostic_starter (context, diagnostic)
- diagnostic_context *context;
- diagnostic_info *diagnostic;
+/* A hard error: the code is definitely ill-formed, and an object file
+ will not be produced. */
+void
+error (const char *msgid, ...)
{
- diagnostic_report_current_function (context);
- output_set_prefix (&context->buffer, diagnostic_build_prefix (diagnostic));
+ diagnostic_info diagnostic;
+ va_list ap;
+
+ va_start (ap, msgid);
+ diagnostic_set_info (&diagnostic, msgid, &ap, input_location, DK_ERROR);
+ report_diagnostic (&diagnostic);
+ va_end (ap);
}
-static void
-default_diagnostic_finalizer (context, diagnostic)
- diagnostic_context *context;
- diagnostic_info *diagnostic __attribute__((unused));
+/* "Sorry, not implemented." Use for a language feature which is
+ required by the relevant specification but not implemented by GCC.
+ An object file will not be produced. */
+void
+sorry (const char *msgid, ...)
{
- output_destroy_prefix (&context->buffer);
+ diagnostic_info diagnostic;
+ va_list ap;
+
+ va_start (ap, msgid);
+ diagnostic_set_info (&diagnostic, msgid, &ap, input_location, DK_SORRY);
+ report_diagnostic (&diagnostic);
+ va_end (ap);
}
+/* An error which is severe enough that we make no attempt to
+ continue. Do not use this for internal consistency checks; that's
+ internal_error. Use of this function should be rare. */
void
-inform VPARAMS ((const char *msgid, ...))
+fatal_error (const char *msgid, ...)
{
diagnostic_info diagnostic;
+ va_list ap;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_start (ap, msgid);
+ diagnostic_set_info (&diagnostic, msgid, &ap, input_location, DK_FATAL);
+ report_diagnostic (&diagnostic);
+ va_end (ap);
- diagnostic_set_info (&diagnostic, msgid, &ap, input_filename, lineno,
- DK_NOTE);
+ /* NOTREACHED */
+ real_abort ();
+}
+
+/* An internal consistency check has failed. We make no attempt to
+ continue. Note that unless there is debugging value to be had from
+ a more specific message, or some other good reason, you should use
+ abort () instead of calling this function directly. */
+void
+internal_error (const char *msgid, ...)
+{
+ diagnostic_info diagnostic;
+ va_list ap;
+
+ va_start (ap, msgid);
+ diagnostic_set_info (&diagnostic, msgid, &ap, input_location, DK_ICE);
report_diagnostic (&diagnostic);
- VA_CLOSE (ap);
+ va_end (ap);
+
+ /* NOTREACHED */
+ real_abort ();
}
+
+/* Special case error functions. Most are implemented in terms of the
+ above, or should be. */
+/* Print a diagnostic MSGID on FILE. This is just fprintf, except it
+ runs its second argument through gettext. */
void
-warn_deprecated_use (node)
- tree node;
+fnotice (FILE *file, const char *msgid, ...)
{
- if (node == 0 || !warn_deprecated_decl)
- return;
-
- if (DECL_P (node))
- warning ("`%s' is deprecated (declared at %s:%d)",
- IDENTIFIER_POINTER (DECL_NAME (node)),
- DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
- else if (TYPE_P (node))
- {
- const char *what = NULL;
- tree decl = TYPE_STUB_DECL (node);
+ va_list ap;
- if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
- what = IDENTIFIER_POINTER (TYPE_NAME (node));
- else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
- && DECL_NAME (TYPE_NAME (node)))
- what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node)));
+ va_start (ap, msgid);
+ vfprintf (file, _(msgid), ap);
+ va_end (ap);
+}
- if (what)
- {
- if (decl)
- warning ("`%s' is deprecated (declared at %s:%d)", what,
- DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
- else
- warning ("`%s' is deprecated", what);
- }
- else if (decl)
- warning ("type is deprecated (declared at %s:%d)",
- DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
- else
- warning ("type is deprecated");
- }
+/* Inform the user that an error occurred while trying to report some
+ other error. This indicates catastrophic internal inconsistencies,
+ so give up now. But do try to flush out the previous error.
+ This mustn't use internal_error, that will cause infinite recursion. */
+
+static void
+error_recursion (diagnostic_context *context)
+{
+ if (context->lock < 3)
+ pp_flush (context->printer);
+
+ fnotice (stderr,
+ "Internal compiler error: Error reporting routines re-entered.\n");
+ fnotice (stderr, bug_report_request, bug_report_url);
+ exit (FATAL_EXIT_CODE);
+}
+
+/* Report an internal compiler error in a friendly manner. This is
+ the function that gets called upon use of abort() in the source
+ code generally, thanks to a special macro. */
+
+void
+fancy_abort (const char *file, int line, const char *function)
+{
+ internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
+}
+
+/* Really call the system 'abort'. This has to go right at the end of
+ this file, so that there are no functions after it that call abort
+ and get the system abort instead of our macro. */
+#undef abort
+static void
+real_abort (void)
+{
+ abort ();
}
diff --git a/contrib/gcc/diagnostic.def b/contrib/gcc/diagnostic.def
index 83e5d9cae72f..6820bb72e9fe 100644
--- a/contrib/gcc/diagnostic.def
+++ b/contrib/gcc/diagnostic.def
@@ -1,7 +1,7 @@
DEFINE_DIAGNOSTIC_KIND (DK_FATAL, "fatal error: ")
DEFINE_DIAGNOSTIC_KIND (DK_ICE, "internal compiler error: ")
-DEFINE_DIAGNOSTIC_KIND (DK_SORRY, "sorry, unimplemented: ")
DEFINE_DIAGNOSTIC_KIND (DK_ERROR, "error: ")
+DEFINE_DIAGNOSTIC_KIND (DK_SORRY, "sorry, unimplemented: ")
DEFINE_DIAGNOSTIC_KIND (DK_WARNING, "warning: ")
DEFINE_DIAGNOSTIC_KIND (DK_ANACHRONISM, "anachronism: ")
DEFINE_DIAGNOSTIC_KIND (DK_NOTE, "note: ")
diff --git a/contrib/gcc/diagnostic.h b/contrib/gcc/diagnostic.h
index e0888916b6ed..daf24279d5e9 100644
--- a/contrib/gcc/diagnostic.h
+++ b/contrib/gcc/diagnostic.h
@@ -1,5 +1,5 @@
/* Various declarations for language-independent diagnostics subroutines.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
This file is part of GCC.
@@ -22,21 +22,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_DIAGNOSTIC_H
#define GCC_DIAGNOSTIC_H
-#include "obstack.h"
-#include "location.h"
+#include "pretty-print.h"
-/* The type of a text to be formatted according a format specification
- along with a list of things. */
-typedef struct
-{
- const char *format_spec;
- va_list *args_ptr;
-} text_info;
-
-/* Contants used to discreminate diagnostics. */
+/* Constants used to discriminate diagnostics. */
typedef enum
{
-#define DEFINE_DIAGNOSTIC_KIND(K, M) K,
+#define DEFINE_DIAGNOSTIC_KIND(K, msgid) K,
#include "diagnostic.def"
#undef DEFINE_DIAGNOSTIC_KIND
DK_LAST_DIAGNOSTIC_KIND
@@ -55,133 +46,19 @@ typedef struct
#define pedantic_error_kind() (flag_pedantic_errors ? DK_ERROR : DK_WARNING)
-/* How often diagnostics are prefixed by their locations:
- o DIAGNOSTICS_SHOW_PREFIX_NEVER: never - not yet supported;
- o DIAGNOSTICS_SHOW_PREFIX_ONCE: emit only once;
- o DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE: emit each time a physical
- line is started. */
-typedef enum
-{
- DIAGNOSTICS_SHOW_PREFIX_ONCE = 0x0,
- DIAGNOSTICS_SHOW_PREFIX_NEVER = 0x1,
- DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE = 0x2
-} diagnostic_prefixing_rule_t;
-
-/* This data structure encapsulates an output_buffer's state. */
-typedef struct
-{
- /* The prefix for each new line. */
- const char *prefix;
-
- /* The real upper bound of number of characters per line, taking into
- account the case of a very very looong prefix. */
- int maximum_length;
-
- /* The ideal upper bound of number of characters per line, as suggested
- by front-end. */
- int ideal_maximum_length;
-
- /* Indentation count. */
- int indent_skip;
-
- /* Nonzero if current PREFIX was emitted at least once. */
- bool emitted_prefix_p;
-
- /* Nonzero means one should emit a newline before outputing anything. */
- bool need_newline_p;
-
- /* Current prefixing rule. */
- diagnostic_prefixing_rule_t prefixing_rule;
-} output_state;
-
-/* The type of a hook that formats client-specific data (trees mostly) into
- an output_buffer. A client-supplied formatter returns true if everything
- goes well. */
-typedef struct output_buffer output_buffer;
-typedef bool (*printer_fn) PARAMS ((output_buffer *, text_info *));
-
-/* The output buffer datatype. This is best seen as an abstract datatype
- whose fields should not be accessed directly by clients. */
-struct output_buffer
-{
- /* The current state of the buffer. */
- output_state state;
-
- /* Where to output formatted text. */
- FILE* stream;
-
- /* The obstack where the text is built up. */
- struct obstack obstack;
-
- /* The amount of characters output so far. */
- int line_length;
-
- /* This must be large enough to hold any printed integer or
- floating-point value. */
- char digit_buffer[128];
-
- /* If non-NULL, this function formats a TEXT into the BUFFER. When called,
- TEXT->format_spec points to a format code. FORMAT_DECODER should call
- output_add_string (and related functions) to add data to the BUFFER.
- FORMAT_DECODER can read arguments from *TEXT->args_pts using VA_ARG.
- If the BUFFER needs additional characters from the format string, it
- should advance the TEXT->format_spec as it goes. When FORMAT_DECODER
- returns, TEXT->format_spec should point to the last character processed.
- */
- printer_fn format_decoder;
-} ;
-
-#define output_prefix(BUFFER) (BUFFER)->state.prefix
-
-/* The stream attached to the output_buffer, where the formatted
- diagnostics will ultimately go. Works only on `output_buffer *'. */
-#define output_buffer_attached_stream(BUFFER) (BUFFER)->stream
-
-/* In line-wrapping mode, whether we should start a new line. */
-#define output_needs_newline(BUFFER) (BUFFER)->state.need_newline_p
-
-/* The amount of whitespace to be emitted when starting a new line. */
-#define output_indentation(BUFFER) (BUFFER)->state.indent_skip
-
-/* A pointer to the formatted diagnostic message. */
-#define output_message_text(BUFFER) \
- ((const char *) obstack_base (&(BUFFER)->obstack))
-
-/* Client supplied function used to decode formats. */
-#define output_format_decoder(BUFFER) (BUFFER)->format_decoder
-
-/* Prefixing rule used in formatting a diagnostic message. */
-#define output_prefixing_rule(BUFFER) (BUFFER)->state.prefixing_rule
-
-/* Maximum characters per line in automatic line wrapping mode.
- Zero means don't wrap lines. */
-#define output_line_cutoff(BUFFER) (BUFFER)->state.ideal_maximum_length
-
-/* True if BUFFER is in line-wrapping mode. */
-#define output_is_line_wrapping(BUFFER) (output_line_cutoff (BUFFER) > 0)
-
-#define output_formatted_scalar(BUFFER, FORMAT, INTEGER) \
- do \
- { \
- sprintf ((BUFFER)->digit_buffer, FORMAT, INTEGER); \
- output_add_string (BUFFER, (BUFFER)->digit_buffer); \
- } \
- while (0)
/* Forward declarations. */
typedef struct diagnostic_context diagnostic_context;
-typedef void (*diagnostic_starter_fn) PARAMS ((diagnostic_context *,
- diagnostic_info *));
+typedef void (*diagnostic_starter_fn) (diagnostic_context *,
+ diagnostic_info *);
typedef diagnostic_starter_fn diagnostic_finalizer_fn;
/* This data structure bundles altogether any information relevant to
the context of a diagnostic message. */
struct diagnostic_context
{
- /* Where most of the diagnostic formatting work is done. In Object
- Oriented terms, we'll say that diagnostic_context is a sub-class of
- output_buffer. */
- output_buffer buffer;
+ /* Where most of the diagnostic formatting work is done. */
+ pretty_printer *printer;
/* The number of times we have issued diagnostics. */
int diagnostic_count[DK_LAST_DIAGNOSTIC_KIND];
@@ -190,6 +67,9 @@ struct diagnostic_context
message, usually displayed once per compiler run. */
bool warnings_are_errors_message;
+ /* True if we should raise a SIGABRT on errors. */
+ bool abort_on_error;
+
/* This function is called before any message is printed out. It is
responsible for preparing message prefix and such. For example, it
might say:
@@ -203,7 +83,7 @@ struct diagnostic_context
diagnostic_finalizer_fn end_diagnostic;
/* Client hook to report an internal error. */
- void (*internal_error) PARAMS ((const char *, va_list *));
+ void (*internal_error) (const char *, va_list *);
/* Function of last diagnostic message; more generally, function such that
if next diagnostic message is in it then we don't have to mention the
@@ -229,15 +109,17 @@ struct diagnostic_context
/* Extension hook for client. */
#define diagnostic_auxiliary_data(DC) (DC)->x_data
-/* Same as output_format_decoder. Works on 'diagnostic_context *'. */
-#define diagnostic_format_decoder(DC) output_format_decoder (&(DC)->buffer)
+/* Same as pp_format_decoder. Works on 'diagnostic_context *'. */
+#define diagnostic_format_decoder(DC) ((DC)->printer->format_decoder)
/* Same as output_prefixing_rule. Works on 'diagnostic_context *'. */
-#define diagnostic_prefixing_rule(DC) output_prefixing_rule (&(DC)->buffer)
+#define diagnostic_prefixing_rule(DC) ((DC)->printer->prefixing_rule)
/* Maximum characters per line in automatic line wrapping mode.
Zero means don't wrap lines. */
-#define diagnostic_line_cutoff(DC) output_line_cutoff (&(DC)->buffer)
+#define diagnostic_line_cutoff(DC) ((DC)->printer->ideal_maximum_length)
+
+#define diagnostic_flush_buffer(DC) pp_base_flush ((DC)->printer)
/* True if the last function in which a diagnostic was reported is
different from the current one. */
@@ -259,12 +141,16 @@ struct diagnostic_context
#define diagnostic_set_last_module(DC) \
(DC)->last_module = input_file_stack_tick
+/* Raise SIGABRT on any diagnostic of severity DK_ERROR or higher. */
+#define diagnostic_abort_on_error(DC) \
+ (DC)->abort_on_error = true
+
/* This diagnostic_context is used by front-ends that directly output
diagnostic messages without going through `error', `warning',
and similar functions. */
extern diagnostic_context *global_dc;
-/* The total count of a KIND of diagnostics meitted so far. */
+/* The total count of a KIND of diagnostics emitted so far. */
#define diagnostic_kind_count(DC, DK) (DC)->diagnostic_count[(int) (DK)]
/* The number of errors that have been issued so far. Ideally, these
@@ -282,49 +168,18 @@ extern diagnostic_context *global_dc;
#define report_diagnostic(D) diagnostic_report_diagnostic (global_dc, D)
-/* Dignostic related functions. */
-extern void diagnostic_initialize PARAMS ((diagnostic_context *));
-extern void diagnostic_report_current_module PARAMS ((diagnostic_context *));
-extern void diagnostic_report_current_function PARAMS ((diagnostic_context *));
-extern void diagnostic_flush_buffer PARAMS ((diagnostic_context *));
-extern bool diagnostic_count_diagnostic PARAMS ((diagnostic_context *,
- diagnostic_t));
-extern void diagnostic_report_diagnostic PARAMS ((diagnostic_context *,
- diagnostic_info *));
-extern void diagnostic_set_info PARAMS ((diagnostic_info *,
- const char *, va_list *,
- const char *, int,
- diagnostic_t));
-extern char *diagnostic_build_prefix PARAMS ((diagnostic_info *));
+/* Diagnostic related functions. */
+extern void diagnostic_initialize (diagnostic_context *);
+extern void diagnostic_report_current_module (diagnostic_context *);
+extern void diagnostic_report_current_function (diagnostic_context *);
+extern void diagnostic_report_diagnostic (diagnostic_context *,
+ diagnostic_info *);
+extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *,
+ location_t, diagnostic_t);
+extern char *diagnostic_build_prefix (diagnostic_info *);
/* Pure text formatting support functions. */
-extern void init_output_buffer PARAMS ((output_buffer *,
- const char *, int));
-extern void output_clear PARAMS ((output_buffer *));
-extern const char *output_last_position PARAMS ((const output_buffer *));
-extern void output_set_prefix PARAMS ((output_buffer *,
- const char *));
-extern void output_destroy_prefix PARAMS ((output_buffer *));
-extern void output_set_maximum_length PARAMS ((output_buffer *, int));
-extern void output_emit_prefix PARAMS ((output_buffer *));
-extern void output_add_newline PARAMS ((output_buffer *));
-extern void output_add_space PARAMS ((output_buffer *));
-extern int output_space_left PARAMS ((const output_buffer *));
-extern void output_append PARAMS ((output_buffer *, const char *,
- const char *));
-extern void output_add_character PARAMS ((output_buffer *, int));
-extern void output_decimal PARAMS ((output_buffer *, int));
-extern void output_add_string PARAMS ((output_buffer *,
- const char *));
-extern void output_add_identifier PARAMS ((output_buffer *, tree));
-extern const char *output_finalize_message PARAMS ((output_buffer *));
-extern void output_clear_message_text PARAMS ((output_buffer *));
-extern void output_printf PARAMS ((output_buffer *, const char *,
- ...)) ATTRIBUTE_PRINTF_2;
-extern void output_verbatim PARAMS ((output_buffer *, const char *,
- ...));
-extern void verbatim PARAMS ((const char *, ...));
-extern char *file_name_as_prefix PARAMS ((const char *));
-extern void inform PARAMS ((const char *, ...));
+extern void verbatim (const char *, ...);
+extern char *file_name_as_prefix (const char *);
#endif /* ! GCC_DIAGNOSTIC_H */
diff --git a/contrib/gcc/doc/bugreport.texi b/contrib/gcc/doc/bugreport.texi
index d9613ef6d1cc..9e10af910dc3 100644
--- a/contrib/gcc/doc/bugreport.texi
+++ b/contrib/gcc/doc/bugreport.texi
@@ -1,5 +1,5 @@
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-@c 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
+@c 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -76,8 +76,8 @@ compiler bug.
@item
If the compiler does not produce an error message for invalid input,
that is a compiler bug. However, you should note that your idea of
-``invalid input'' might be my idea of ``an extension'' or ``support
-for traditional practice''.
+``invalid input'' might be someone else's idea of ``an extension'' or
+``support for traditional practice''.
@item
If you are an experienced user of one of the languages GCC supports, your
@@ -88,7 +88,7 @@ suggestions for improvement of GCC are welcome in any case.
@section How and where to Report Bugs
@cindex compiler bugs, reporting
-Bugs should be reported to our bug database. Please refer to
+Bugs should be reported to the GCC bug database. Please refer to
@uref{http://gcc.gnu.org/bugs.html} for up-to-date instructions how to
submit bug reports. Copies of this file in HTML (@file{bugs.html}) and
plain text (@file{BUGS}) are also part of GCC releases.
diff --git a/contrib/gcc/doc/c-tree.texi b/contrib/gcc/doc/c-tree.texi
index fbc90fa34f2f..d1afe655c761 100644
--- a/contrib/gcc/doc/c-tree.texi
+++ b/contrib/gcc/doc/c-tree.texi
@@ -1,4 +1,4 @@
-@c Copyright (c) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+@c Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
@c Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -98,24 +98,24 @@ Many macros behave as predicates. Many, although not all, of these
predicates end in @samp{_P}. Do not rely on the result type of these
macros being of any particular type. You may, however, rely on the fact
that the type can be compared to @code{0}, so that statements like
-@example
+@smallexample
if (TEST_P (t) && !TEST_P (y))
x = 1;
-@end example
+@end smallexample
@noindent
and
-@example
+@smallexample
int i = (TEST_P (t) != 0);
-@end example
+@end smallexample
@noindent
are legal. Macros that return @code{int} values now may be changed to
return @code{tree} values, or other pointers in the future. Even those
that continue to return @code{int} may return multiple nonzero codes
where previously they returned only zero and one. Therefore, you should
not write code like
-@example
+@smallexample
if (TEST_P (t) == 1)
-@end example
+@end smallexample
@noindent
as this code is not guaranteed to work correctly in the future.
@@ -124,7 +124,7 @@ functions described here. In particular, no guarantee is given that the
values are lvalues.
In general, the names of macros are all in uppercase, while the names of
-functions are entirely in lower case. There are rare exceptions to this
+functions are entirely in lowercase. There are rare exceptions to this
rule. You should assume that any macro or function whose name is made
up entirely of uppercase letters may evaluate its arguments more than
once. You may assume that a macro or function whose name is made up
@@ -555,11 +555,9 @@ This node is used to represent a type the knowledge of which is
insufficient for a sound processing.
@item OFFSET_TYPE
-This node is used to represent a data member; for example a
-pointer-to-data-member is represented by a @code{POINTER_TYPE} whose
-@code{TREE_TYPE} is an @code{OFFSET_TYPE}. For a data member @code{X::m}
-the @code{TYPE_OFFSET_BASETYPE} is @code{X} and the @code{TREE_TYPE} is
-the type of @code{m}.
+This node is used to represent a pointer-to-data member. For a data
+member @code{X::m} the @code{TYPE_OFFSET_BASETYPE} is @code{X} and the
+@code{TREE_TYPE} is the type of @code{m}.
@item TYPENAME_TYPE
Used to represent a construct of the form @code{typename T::A}. The
@@ -790,7 +788,7 @@ This predicate holds whenever its argument represents a class-type with
default constructor.
@item CLASSTYPE_HAS_MUTABLE
-@item TYPE_HAS_MUTABLE_P
+@itemx TYPE_HAS_MUTABLE_P
These predicates hold for a class-type having a mutable data member.
@item CLASSTYPE_NON_POD_P
@@ -873,15 +871,15 @@ This predicate holds if the declaration was implicitly generated by the
compiler. For example, this predicate will hold of an implicitly
declared member function, or of the @code{TYPE_DECL} implicitly
generated for a class type. Recall that in C++ code like:
-@example
+@smallexample
struct S @{@};
-@end example
+@end smallexample
@noindent
is roughly equivalent to C code like:
-@example
+@smallexample
struct S @{@};
typedef struct S S;
-@end example
+@end smallexample
The implicitly generated @code{typedef} declaration is represented by a
@code{TYPE_DECL} for which @code{DECL_ARTIFICIAL} holds.
@@ -1021,34 +1019,35 @@ will always return the function itself, and @code{OVL_NEXT} will always
be @code{NULL_TREE}.
To determine the scope of a function, you can use the
-@code{DECL_REAL_CONTEXT} macro. This macro will return the class
+@code{DECL_CONTEXT} macro. This macro will return the class
(either a @code{RECORD_TYPE} or a @code{UNION_TYPE}) or namespace (a
@code{NAMESPACE_DECL}) of which the function is a member. For a virtual
function, this macro returns the class in which the function was
actually defined, not the base class in which the virtual declaration
-occurred. If a friend function is defined in a class scope, the
-@code{DECL_CLASS_CONTEXT} macro can be used to determine the class in
+occurred.
+
+If a friend function is defined in a class scope, the
+@code{DECL_FRIEND_CONTEXT} macro can be used to determine the class in
which it was defined. For example, in
-@example
+@smallexample
class C @{ friend void f() @{@} @};
-@end example
-the @code{DECL_REAL_CONTEXT} for @code{f} will be the
-@code{global_namespace}, but the @code{DECL_CLASS_CONTEXT} will be the
+@end smallexample
+@noindent
+the @code{DECL_CONTEXT} for @code{f} will be the
+@code{global_namespace}, but the @code{DECL_FRIEND_CONTEXT} will be the
@code{RECORD_TYPE} for @code{C}.
-The @code{DECL_REAL_CONTEXT} and @code{DECL_CLASS_CONTEXT} are not
-available in C; instead you should simply use @code{DECL_CONTEXT}. In C,
-the @code{DECL_CONTEXT} for a function maybe another function. This
-representation indicates that the GNU nested function extension is in
-use. For details on the semantics of nested functions, see the GCC
-Manual. The nested function can refer to local variables in its
+In C, the @code{DECL_CONTEXT} for a function maybe another function.
+This representation indicates that the GNU nested function extension
+is in use. For details on the semantics of nested functions, see the
+GCC Manual. The nested function can refer to local variables in its
containing function. Such references are not explicitly marked in the
tree structure; back ends must look at the @code{DECL_CONTEXT} for the
referenced @code{VAR_DECL}. If the @code{DECL_CONTEXT} for the
referenced @code{VAR_DECL} is not the same as the function currently
-being processed, and neither @code{DECL_EXTERNAL} nor @code{DECL_STATIC}
-hold, then the reference is to a local variable in a containing
-function, and the back end must take appropriate action.
+being processed, and neither @code{DECL_EXTERNAL} nor
+@code{DECL_STATIC} hold, then the reference is to a local variable in
+a containing function, and the back end must take appropriate action.
@menu
* Function Basics:: Function names, linkage, and so forth.
@@ -1379,7 +1378,7 @@ the expression has been omitted. A substatement may in fact be a list
of statements, connected via their @code{TREE_CHAIN}s. So, you should
always process the statement tree by looping over substatements, like
this:
-@example
+@smallexample
void process_stmt (stmt)
tree stmt;
@{
@@ -1398,7 +1397,7 @@ void process_stmt (stmt)
stmt = TREE_CHAIN (stmt);
@}
@}
-@end example
+@end smallexample
In other words, while the @code{then} clause of an @code{if} statement
in C++ can be only one statement (although that one statement may be a
compound statement), the intermediate representation will sometimes use
@@ -1409,18 +1408,18 @@ several statements chained together.
Used to represent an inline assembly statement. For an inline assembly
statement like:
-@example
+@smallexample
asm ("mov x, y");
-@end example
+@end smallexample
The @code{ASM_STRING} macro will return a @code{STRING_CST} node for
@code{"mov x, y"}. If the original statement made use of the
extended-assembly syntax, then @code{ASM_OUTPUTS},
@code{ASM_INPUTS}, and @code{ASM_CLOBBERS} will be the outputs, inputs,
and clobbers for the statement, represented as @code{STRING_CST} nodes.
The extended-assembly syntax looks like:
-@example
+@smallexample
asm ("fsinx %1,%0" : "=f" (result) : "f" (angle));
-@end example
+@end smallexample
The first string is the @code{ASM_STRING}, containing the instruction
template. The next two strings are the output and inputs, respectively;
this statement has no clobbers. As this example indicates, ``plain''
@@ -1452,9 +1451,9 @@ the same type as the condition expression in the switch statement.
Otherwise, if both @code{CASE_LOW} and @code{CASE_HIGH} are defined, the
statement is a range of case labels. Such statements originate with the
extension that allows users to write things of the form:
-@example
+@smallexample
case 2 ... 5:
-@end example
+@end smallexample
The first value will be @code{CASE_LOW}, while the second will be
@code{CASE_HIGH}.
@@ -1547,10 +1546,10 @@ This is used for branch prediction.
Used to represent a C++ @code{catch} block. The @code{HANDLER_TYPE}
is the type of exception that will be caught by this handler; it is
-equal (by pointer equality) to @code{CATCH_ALL_TYPE} if this handler
-is for all types. @code{HANDLER_PARMS} is the @code{DECL_STMT} for
-the catch parameter, and @code{HANDLER_BODY} is the
-@code{COMPOUND_STMT} for the block itself.
+equal (by pointer equality) to @code{NULL} if this handler is for all
+types. @code{HANDLER_PARMS} is the @code{DECL_STMT} for the catch
+parameter, and @code{HANDLER_BODY} is the @code{COMPOUND_STMT} for the
+block itself.
@item IF_STMT
@@ -1563,9 +1562,9 @@ evaluated, the statement should be executed. Then, the
@code{TREE_VALUE} should be used as the conditional expression itself.
This representation is used to handle C++ code like this:
-@example
+@smallexample
if (int i = 7) @dots{}
-@end example
+@end smallexample
where there is a new local variable (or variables) declared within the
condition.
@@ -1585,9 +1584,9 @@ the @code{LABEL_DECL} with @code{DECL_NAME}.
If the function uses the G++ ``named return value'' extension, meaning
that the function has been defined like:
-@example
+@smallexample
S f(int) return s @{@dots{}@}
-@end example
+@end smallexample
then there will be a @code{RETURN_INIT}. There is never a named
returned value for a constructor. The first argument to the
@code{RETURN_INIT} is the name of the object returned; the second
@@ -1602,9 +1601,9 @@ constructed in the place where the object will be returned.
Used to represent a @code{return} statement. The @code{RETURN_EXPR} is
the expression returned; it will be @code{NULL_TREE} if the statement
was just
-@example
+@smallexample
return;
-@end example
+@end smallexample
@item SCOPE_STMT
@@ -1721,6 +1720,7 @@ This macro returns the attributes on the type @var{type}.
@findex PTRMEM_CST_MEMBER
@tindex VAR_DECL
@tindex NEGATE_EXPR
+@tindex ABS_EXPR
@tindex BIT_NOT_EXPR
@tindex TRUTH_NOT_EXPR
@tindex ADDR_EXPR
@@ -1803,9 +1803,9 @@ noted otherwise, the operands to an expression are accessed using the
@code{TREE_OPERAND} macro. For example, to access the first operand to
a binary plus expression @code{expr}, use:
-@example
+@smallexample
TREE_OPERAND (expr, 0)
-@end example
+@end smallexample
@noindent
As this example indicates, the operands are zero-indexed.
@@ -1819,10 +1819,11 @@ These nodes represent integer constants. Note that the type of these
constants is obtained with @code{TREE_TYPE}; they are not always of type
@code{int}. In particular, @code{char} constants are represented with
@code{INTEGER_CST} nodes. The value of the integer constant @code{e} is
-given by @example
+given by
+@smallexample
((TREE_INT_CST_HIGH (e) << HOST_BITS_PER_WIDE_INT)
+ TREE_INST_CST_LOW (e))
-@end example
+@end smallexample
@noindent
HOST_BITS_PER_WIDE_INT is at least thirty-two on all platforms. Both
@code{TREE_INT_CST_HIGH} and @code{TREE_INT_CST_LOW} return a
@@ -1893,11 +1894,11 @@ or @code{UNION_TYPE} within which the pointer points), and the
Note that the @code{DECL_CONTEXT} for the @code{PTRMEM_CST_MEMBER} is in
general different from the @code{PTRMEM_CST_CLASS}. For example,
given:
-@example
+@smallexample
struct B @{ int i; @};
struct D : public B @{@};
int D::*dp = &D::i;
-@end example
+@end smallexample
@noindent
The @code{PTRMEM_CST_CLASS} for @code{&D::i} is @code{D}, even though
the @code{DECL_CONTEXT} for the @code{PTRMEM_CST_MEMBER} is @code{B},
@@ -1913,6 +1914,23 @@ These nodes represent unary negation of the single operand, for both
integer and floating-point types. The type of negation can be
determined by looking at the type of the expression.
+The behavior of this operation on signed arithmetic overflow is
+controlled by the @code{flag_wrapv} and @code{flag_trapv} variables.
+
+@item ABS_EXPR
+These nodes represent the absolute value of the single operand, for
+both integer and floating-point types. This is typically used to
+implement the @code{abs}, @code{labs} and @code{llabs} builtins for
+integer types, and the @code{fabs}, @code{fabsf} and @code{fabsl}
+builtins for floating point types. The type of abs operation can
+be determined by looking at the type of the expression.
+
+This node is not used for complex types. To represent the modulus
+or complex abs of a complex value, use the @code{BUILT_IN_CABS},
+@code{BUILT_IN_CABSF} or @code{BUILT_IN_CABSL} builtins, as used
+to implement the C99 @code{cabs}, @code{cabsf} and @code{cabsl}
+built-in functions.
+
@item BIT_NOT_EXPR
These nodes represent bitwise complement, and will always have integral
type. The only operand is the value to be complemented.
@@ -1974,7 +1992,7 @@ real part and the second operand is the imaginary part.
These nodes represent the conjugate of their operand.
@item REALPART_EXPR
-@item IMAGPART_EXPR
+@itemx IMAGPART_EXPR
These nodes represent respectively the real and the imaginary parts
of complex numbers (their sole argument).
@@ -2066,6 +2084,9 @@ The @code{TRUNC_MOD_EXPR} of two operands @code{a} and @code{b} is
always @code{a - (a/b)*b} where the division is as if computed by a
@code{TRUNC_DIV_EXPR}.
+The behavior of these operations on signed arithmetic overflow is
+controlled by the @code{flag_wrapv} and @code{flag_trapv} variables.
+
@item ARRAY_REF
These nodes represent array accesses. The first operand is the array;
the second is the index. To calculate the address of the memory
@@ -2161,9 +2182,9 @@ sites.
@item STMT_EXPR
These nodes are used to represent GCC's statement-expression extension.
The statement-expression extension allows code like this:
-@example
+@smallexample
int f() @{ return (@{ int j; j = 3; j + 7; @}); @}
-@end example
+@end smallexample
In other words, an sequence of statements may occur where a single
expression would normally appear. The @code{STMT_EXPR} node represents
such an expression. The @code{STMT_EXPR_STMT} gives the statement
@@ -2172,13 +2193,13 @@ value of the expression is the value of the last sub-statement in the
@code{COMPOUND_STMT}. More precisely, the value is the value computed
by the last @code{EXPR_STMT} in the outermost scope of the
@code{COMPOUND_STMT}. For example, in:
-@example
+@smallexample
(@{ 3; @})
-@end example
+@end smallexample
the value is @code{3} while in:
-@example
+@smallexample
(@{ if (x) @{ 3; @} @})
-@end example
+@end smallexample
(represented by a nested @code{COMPOUND_STMT}), there is no value. If
the @code{STMT_EXPR} does not yield a value, it's type will be
@code{void}.
@@ -2214,10 +2235,7 @@ second operand is a @code{TREE_LIST}. If the @code{TREE_TYPE} of the
@code{CONSTRUCTOR} is a @code{RECORD_TYPE} or @code{UNION_TYPE}, then
the @code{TREE_PURPOSE} of each node in the @code{TREE_LIST} will be a
@code{FIELD_DECL} and the @code{TREE_VALUE} of each node will be the
-expression used to initialize that field. You should not depend on the
-fields appearing in any particular order, nor should you assume that all
-fields will be represented. Unrepresented fields may be assigned any
-value.
+expression used to initialize that field.
If the @code{TREE_TYPE} of the @code{CONSTRUCTOR} is an
@code{ARRAY_TYPE}, then the @code{TREE_PURPOSE} of each element in the
@@ -2227,8 +2245,10 @@ again, the @code{TREE_VALUE} is the corresponding initializer. If the
@code{TREE_PURPOSE} is @code{NULL_TREE}, then the initializer is for the
next available array element.
-Conceptually, before any initialization is done, the entire area of
-storage is initialized to zero.
+In the front end, you should not depend on the fields appearing in any
+particular order. However, in the middle end, fields must appear in
+declaration order. You should not assume that all fields will be
+represented. Unrepresented fields will be set to zero.
@item COMPOUND_LITERAL_EXPR
@findex COMPOUND_LITERAL_EXPR_DECL_STMT
diff --git a/contrib/gcc/doc/compat.texi b/contrib/gcc/doc/compat.texi
index 274368a20e39..5b02ebcac710 100644
--- a/contrib/gcc/doc/compat.texi
+++ b/contrib/gcc/doc/compat.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 2002 Free Software Foundation, Inc.
+@c Copyright (C) 2002, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -133,9 +133,9 @@ build was configured, but can be seen by using the G++ @option{-v} option.
With default configuration options for G++ 3.3 the compile line for a
different C++ compiler needs to include
-@example
+@smallexample
-I@var{gcc_install_directory}/include/c++/3.3
-@end example
+@end smallexample
Similarly, compiling code with G++ that must use a C++ library other
than the GNU C++ library requires specifying the location of the header
diff --git a/contrib/gcc/doc/configfiles.texi b/contrib/gcc/doc/configfiles.texi
index c6c60bbe802a..f24b85d719ac 100644
--- a/contrib/gcc/doc/configfiles.texi
+++ b/contrib/gcc/doc/configfiles.texi
@@ -50,7 +50,7 @@ the files listed in @code{outputs} there are also generated.
The following configuration headers are created from the Makefile,
using @file{mkconfig.sh}, rather than directly by @file{configure}.
-@file{config.h}, @file{hconfig.h} and @file{tconfig.h} all contain the
+@file{config.h}, @file{bconfig.h} and @file{tconfig.h} all contain the
@file{xm-@var{machine}.h} header, if any, appropriate to the host,
build and target machines respectively, the configuration headers for
the target, and some definitions; for the host and build machines,
@@ -63,7 +63,7 @@ these include the autoconfigured headers generated by
@item
@file{config.h}, for use in programs that run on the host machine.
@item
-@file{hconfig.h}, for use in programs that run on the build machine.
+@file{bconfig.h}, for use in programs that run on the build machine.
@item
@file{tconfig.h}, for use in programs and libraries for the target
machine.
diff --git a/contrib/gcc/doc/configterms.texi b/contrib/gcc/doc/configterms.texi
index 39b3152d5286..f97de5bd0966 100644
--- a/contrib/gcc/doc/configterms.texi
+++ b/contrib/gcc/doc/configterms.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+@c Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -34,8 +34,8 @@ different system. Some people call this a @dfn{host-x-host},
@dfn{crossed native}, or @dfn{cross-built native}. If build and target
are the same, but host is different, you are using a cross compiler to
build a cross compiler that produces code for the machine you're
-building on. This is rare, so there is no common way of describing it
-(although I propose calling it a @dfn{crossback}).
+building on. This is rare, so there is no common way of describing it.
+There is a proposal to call this a @dfn{crossback}.
If build and host are the same, the GCC you are building will also be
used to build the target libraries (like @code{libstdc++}). If build and host
diff --git a/contrib/gcc/doc/contrib.texi b/contrib/gcc/doc/contrib.texi
index 3eb3b227f394..8c2419377ea6 100644
--- a/contrib/gcc/doc/contrib.texi
+++ b/contrib/gcc/doc/contrib.texi
@@ -1,5 +1,5 @@
@c Copyright (C) 1988,1989,1992,1993,1994,1995,1996,1997,1998,1999,2000,
-@c 2001,2002,2003 Free Software Foundation, Inc.
+@c 2001,2002,2003,2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -29,12 +29,20 @@ James van Artsdalen wrote the code that makes efficient use of
the Intel 80387 register stack.
@item
+Abramo and Roberto Bagnara for the SysV68 Motorola 3300 Delta Series
+port.
+
+@item
Alasdair Baird for various bug fixes.
@item
Giovanni Bajo for analyzing lots of complicated C++ problem reports.
@item
+Peter Barada for his work to improve code generation for new
+ColdFire cores.
+
+@item
Gerald Baumgartner added the signature extension to the C++ front end.
@item
@@ -47,11 +55,11 @@ Scott Bambrough for help porting the Java compiler.
Wolfgang Bangerth for processing tons of bug reports.
@item
-Jon Beniston for his Windows port of Java.
+Jon Beniston for his Microsoft Windows port of Java.
@item
Daniel Berlin for better DWARF2 support, faster/better optimizations,
-improved alias analysis, plus migrating us to Bugzilla.
+improved alias analysis, plus migrating GCC to Bugzilla.
@item
Geoff Berry for his Java object serialization work and various patches.
@@ -76,7 +84,7 @@ Eric Botcazou for fixing middle- and backend bugs left and right.
@item
Per Bothner for his direction via the steering committee and various
-improvements to our infrastructure for supporting new languages. Chill
+improvements to the infrastructure for supporting new languages. Chill
front end implementation. Initial implementations of
cpplib, fix-header, config.guess, libio, and past C++ library (libg++)
maintainer. Dreaming up, designing and implementing much of GCJ.
@@ -113,8 +121,8 @@ Stephan Buys for contributing Doxygen notes for libstdc++.
@item
Paolo Carlini for libstdc++ work: lots of efficiency improvements to
-the string class, hard detective work on the frustrating localization
-issues, and keeping up with the problem reports.
+the C++ strings, streambufs and formatted I/O, hard detective work on
+the frustrating localization issues, and keeping up with the problem reports.
@item
John Carr for his alias work, SPARC hacking, infrastructure improvements,
@@ -143,7 +151,7 @@ Eric Christopher for his Java porting help and clean-ups.
Branko Cibej for more warning contributions.
@item
-The @uref{http://www.classpath.org,,GNU Classpath project}
+The @uref{http://www.gnu.org/software/classpath/,,GNU Classpath project}
for all of their merged runtime code.
@item
@@ -154,6 +162,10 @@ other random hacking.
Michael Cook for libstdc++ cleanup patches to reduce warnings.
@item
+R. Kelley Cook for making GCC buildable from a read-only directory as
+well as other miscellaneous build process and documentation clean-ups.
+
+@item
Ralf Corsepius for SH testing and minor bugfixing.
@item
@@ -167,6 +179,10 @@ Alex Crain provided changes for the 3b1.
Ian Dall for major improvements to the NS32k port.
@item
+Paul Dale for his work to add uClinux platform support to the
+m68k backend.
+
+@item
Dario Dariol contributed the four varieties of sample programs
that print a copy of their source.
@@ -181,7 +197,7 @@ DJ Delorie for the DJGPP port, build and libiberty maintenance, and
various bug fixes.
@item
-Gabriel Dos Reis for contributions to g++, contributions and
+Gabriel Dos Reis for contributions to G++, contributions and
maintenance of GCC diagnostics infrastructure, libstdc++-v3,
including valarray<>, complex<>, maintaining the numerics library
(including that pesky <limits> :-) and keeping up-to-date anything
@@ -273,7 +289,7 @@ via the steering committee.
Anthony Green for his @option{-Os} contributions and Java front end work.
@item
-Stu Grossman for gdb hacking, allowing GCJ developers to debug our code.
+Stu Grossman for gdb hacking, allowing GCJ developers to debug Java code.
@item
Michael K. Gschwind contributed the port to the PDP-11.
@@ -303,7 +319,7 @@ fixes.
Dara Hazeghi for wading through myriads of target-specific bug reports.
@item
-Kate Hedstrom for staking the g77 folks with an initial testsuite.
+Kate Hedstrom for staking the G77 folks with an initial testsuite.
@item
Richard Henderson for his ongoing SPARC, alpha, ia32, and ia64 work, loop
@@ -324,7 +340,7 @@ Kazu Hirata for caring and feeding the Renesas H8/300 port and various fixes.
@item
Manfred Hollstein for his ongoing work to keep the m88k alive, lots
-of testing and bug fixing, particularly of our configury code.
+of testing and bug fixing, particularly of GCC configury code.
@item
Steve Holmgren for MachTen patches.
@@ -336,6 +352,10 @@ Jan Hubicka for his x86 port improvements.
Falk Hueffner for working on C and optimization bug reports.
@item
+Bernardo Innocenti for his m68k work, including merging of
+ColdFire improvements and uClinux support.
+
+@item
Christian Iseli for various bug fixes.
@item
@@ -381,7 +401,7 @@ Geoffrey Keating for his ongoing work to make the PPC work for GNU/Linux
and his automatic regression tester.
@item
-Brendan Kehoe for his ongoing work with g++ and for a lot of early work
+Brendan Kehoe for his ongoing work with G++ and for a lot of early work
in just about every part of libstdc++.
@item
@@ -401,7 +421,7 @@ head maintainer of GCC for several years.
@item
Mumit Khan for various contributions to the Cygwin and Mingw32 ports and
-maintaining binary releases for Windows hosts, and for massive libstdc++
+maintaining binary releases for Microsoft Windows hosts, and for massive libstdc++
porting work to Cygwin/Mingw32.
@item
@@ -417,7 +437,7 @@ Thomas Koenig for various bug fixes.
Bruce Korb for the new and improved fixincludes code.
@item
-Benjamin Kosnik for his g++ work and for leading the libstdc++-v3 effort.
+Benjamin Kosnik for his G++ work and for leading the libstdc++-v3 effort.
@item
Charles LaBrec contributed the support for the Integrated Solutions
@@ -499,7 +519,7 @@ for Java test code.
Bryce McKinlay for numerous GCJ and libgcj fixes and improvements.
@item
-Adam Megacz for his work on the Windows port of GCJ.
+Adam Megacz for his work on the Microsoft Windows port of GCJ.
@item
Michael Meissner for LRS framework, ia32, m32r, v850, m88k, MIPS,
@@ -507,7 +527,7 @@ powerpc, haifa, ECOFF debug support, and other assorted hacking.
@item
Jason Merrill for his direction via the steering committee and leading
-the g++ effort.
+the G++ effort.
@item
David Miller for his direction via the steering committee, lots of
@@ -548,7 +568,8 @@ Linux kernels.
Mike Moreton for his various Java patches.
@item
-David Mosberger-Tang for various Alpha improvements.
+David Mosberger-Tang for various Alpha improvements, and for the initial
+IA-64 port.
@item
Stephen Moshier contributed the floating point emulator that assists in
@@ -606,7 +627,7 @@ amazing testing work, including keeping libtool issues sane and happy.
Melissa O'Neill for various NeXT fixes.
@item
-Rainer Orth for random MIPS work, including improvements to our o32
+Rainer Orth for random MIPS work, including improvements to GCC's o32
ABI support, improvements to dejagnu's MIPS support, Java configuration
clean-ups and porting work, etc.
@@ -636,6 +657,9 @@ Ovidiu Predescu for his work on the Objective-C front end and runtime
libraries.
@item
+Jerry Quinn for major performance improvements in C++ formatted I/O.
+
+@item
Ken Raeburn for various improvements to checker, MIPS ports and various
cleanups in the compiler.
@@ -666,12 +690,16 @@ Craig Rodrigues for processing tons of bug reports.
Gavin Romig-Koch for lots of behind the scenes MIPS work.
@item
-Ken Rose for fixes to our delay slot filling code.
+Ken Rose for fixes to GCC's delay slot filling code.
@item
Paul Rubin wrote most of the preprocessor.
@item
+P@'etur Run@'olfsson for major performance improvements in C++ formatted I/O and
+large file support in C++ filebuf.
+
+@item
Chip Salzenberg for libstdc++ patches and improvements to locales, traits,
Makefiles, libio, libtool hackery, and ``long long'' support.
@@ -724,11 +752,11 @@ folding and help with the original VAX & m68k ports.
@item
Kenny Simpson for prompting libstdc++ fixes due to defect reports from
-the LWG (thereby keeping us in line with updates from the ISO).
+the LWG (thereby keeping GCC in line with updates from the ISO).
@item
Franz Sirl for his ongoing work with making the PPC port stable
-for linux.
+for GNU/Linux.
@item
Andrey Slepuhin for assorted AIX hacking.
@@ -750,7 +778,7 @@ testsuite entries.
Brad Spencer for contributions to the GLIBCPP_FORCE_NEW technique.
@item
-Richard Stallman, for writing the original gcc and launching the GNU project.
+Richard Stallman, for writing the original GCC and launching the GNU project.
@item
Jan Stein of the Chalmers Computer Society provided support for
@@ -769,7 +797,7 @@ Graham Stott for various infrastructure improvements.
John Stracke for his Java HTTP protocol fixes.
@item
-Mike Stump for his Elxsi port, g++ contributions over the years and more
+Mike Stump for his Elxsi port, G++ contributions over the years and more
recently his vxworks contributions
@item
diff --git a/contrib/gcc/doc/contribute.texi b/contrib/gcc/doc/contribute.texi
index 0aec26842b8f..a90c048326de 100644
--- a/contrib/gcc/doc/contribute.texi
+++ b/contrib/gcc/doc/contribute.texi
@@ -1,5 +1,5 @@
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-@c 1999, 2000, 2001 Free Software Foundation, Inc.
+@c 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -7,7 +7,7 @@
@chapter Contributing to GCC Development
If you would like to help pretest GCC releases to assure they work well,
-our current development sources are available by CVS (see
+current development sources are available by CVS (see
@uref{http://gcc.gnu.org/cvs.html}). Source and binary snapshots are
also available for FTP; see @uref{http://gcc.gnu.org/snapshots.html}.
diff --git a/contrib/gcc/doc/cpp.texi b/contrib/gcc/doc/cpp.texi
index 070e31c89ab1..36978878f4bf 100644
--- a/contrib/gcc/doc/cpp.texi
+++ b/contrib/gcc/doc/cpp.texi
@@ -9,7 +9,7 @@
@copying
@c man begin COPYRIGHT
Copyright @copyright{} 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996,
-1997, 1998, 1999, 2000, 2001, 2002, 2003
+1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
@@ -104,6 +104,7 @@ useful on its own.
Overview
+* Character sets::
* Initial processing::
* Tokenization::
* The preprocessing language::
@@ -233,11 +234,62 @@ manual refer to GNU CPP.
@c man end
@menu
+* Character sets::
* Initial processing::
* Tokenization::
* The preprocessing language::
@end menu
+@node Character sets
+@section Character sets
+
+Source code character set processing in C and related languages is
+rather complicated. The C standard discusses two character sets, but
+there are really at least four.
+
+The files input to CPP might be in any character set at all. CPP's
+very first action, before it even looks for line boundaries, is to
+convert the file into the character set it uses for internal
+processing. That set is what the C standard calls the @dfn{source}
+character set. It must be isomorphic with ISO 10646, also known as
+Unicode. CPP uses the UTF-8 encoding of Unicode.
+
+At present, GNU CPP does not implement conversion from arbitrary file
+encodings to the source character set. Use of any encoding other than
+plain ASCII or UTF-8, except in comments, will cause errors. Use of
+encodings that are not strict supersets of ASCII, such as Shift JIS,
+may cause errors even if non-ASCII characters appear only in comments.
+We plan to fix this in the near future.
+
+All preprocessing work (the subject of the rest of this manual) is
+carried out in the source character set. If you request textual
+output from the preprocessor with the @option{-E} option, it will be
+in UTF-8.
+
+After preprocessing is complete, string and character constants are
+converted again, into the @dfn{execution} character set. This
+character set is under control of the user; the default is UTF-8,
+matching the source character set. Wide string and character
+constants have their own character set, which is not called out
+specifically in the standard. Again, it is under control of the user.
+The default is UTF-16 or UTF-32, whichever fits in the target's
+@code{wchar_t} type, in the target machine's byte
+order.@footnote{UTF-16 does not meet the requirements of the C
+standard for a wide character set, but the choice of 16-bit
+@code{wchar_t} is enshrined in some system ABIs so we cannot fix
+this.} Octal and hexadecimal escape sequences do not undergo
+conversion; @t{'\x12'} has the value 0x12 regardless of the currently
+selected execution character set. All other escapes are replaced by
+the character in the source character set that they represent, then
+converted to the execution character set, just like unescaped
+characters.
+
+GCC does not permit the use of characters outside the ASCII range, nor
+@samp{\u} and @samp{\U} escapes, in identifiers. We hope this will
+change eventually, but there are problems with the standard semantics
+of such ``extended identifiers'' which must be resolved through the
+ISO C and C++ committees first.
+
@node Initial processing
@section Initial processing
@@ -251,28 +303,19 @@ standard.
@enumerate
@item
-@cindex character sets
@cindex line endings
The input file is read into memory and broken into lines.
-CPP expects its input to be a text file, that is, an unstructured
-stream of ASCII characters, with some characters indicating the end of a
-line of text. Extended ASCII character sets, such as ISO Latin-1 or
-Unicode encoded in UTF-8, are also acceptable. Character sets that are
-not strict supersets of seven-bit ASCII will not work. We plan to add
-complete support for international character sets in a future release.
-
Different systems use different conventions to indicate the end of a
line. GCC accepts the ASCII control sequences @kbd{LF}, @kbd{@w{CR
-LF}}, @kbd{CR}, and @kbd{@w{LF CR}} as end-of-line markers. The first
-three are the canonical sequences used by Unix, DOS and VMS, and the
-classic Mac OS (before OSX) respectively. You may therefore safely copy
-source code written on any of those systems to a different one and use
-it without conversion. (GCC may lose track of the current line number
-if a file doesn't consistently use one convention, as sometimes happens
-when it is edited on computers with different conventions that share a
-network file system.) @kbd{@w{LF CR}} is included because it has been
-reported as an end-of-line marker under exotic conditions.
+LF}} and @kbd{CR} as end-of-line markers. These are the canonical
+sequences used by Unix, DOS and VMS, and the classic Mac OS (before
+OSX) respectively. You may therefore safely copy source code written
+on any of those systems to a different one and use it without
+conversion. (GCC may lose track of the current line number if a file
+doesn't consistently use one convention, as sometimes happens when it
+is edited on computers with different conventions that share a network
+file system.)
If the last line of any input file lacks an end-of-line marker, the end
of the file is considered to implicitly supply one. The C standard says
@@ -293,23 +336,25 @@ obsolete systems that lack some of C's punctuation to use C@. For
example, @samp{??/} stands for @samp{\}, so @t{'??/n'} is a character
constant for a newline.
-Trigraphs are not popular and many compilers implement them incorrectly.
-Portable code should not rely on trigraphs being either converted or
-ignored. If you use the @option{-Wall} or @option{-Wtrigraphs} options,
-GCC will warn you when a trigraph would change the meaning of your
-program if it were converted.
+Trigraphs are not popular and many compilers implement them
+incorrectly. Portable code should not rely on trigraphs being either
+converted or ignored. With @option{-Wtrigraphs} GCC will warn you
+when a trigraph may change the meaning of your program if it were
+converted. @xref{Wtrigraphs}.
-In a string constant, you can prevent a sequence of question marks from
-being confused with a trigraph by inserting a backslash between the
-question marks. @t{"(??\?)"} is the string @samp{(???)}, not
-@samp{(?]}. Traditional C compilers do not recognize this idiom.
+In a string constant, you can prevent a sequence of question marks
+from being confused with a trigraph by inserting a backslash between
+the question marks, or by separating the string literal at the
+trigraph and making use of string literal concatenation. @t{"(??\?)"}
+is the string @samp{(???)}, not @samp{(?]}. Traditional C compilers
+do not recognize these idioms.
The nine trigraphs and their replacements are
-@example
+@smallexample
Trigraph: ??( ??) ??< ??> ??= ??/ ??' ??! ??-
Replacement: [ ] @{ @} # \ ^ | ~
-@end example
+@end smallexample
@item
@cindex continued lines
@@ -340,23 +385,23 @@ There are two kinds of comments. @dfn{Block comments} begin with
@samp{/*} and continue until the next @samp{*/}. Block comments do not
nest:
-@example
+@smallexample
/* @r{this is} /* @r{one comment} */ @r{text outside comment}
-@end example
+@end smallexample
@dfn{Line comments} begin with @samp{//} and continue to the end of the
current line. Line comments do not nest either, but it does not matter,
because they would end in the same place anyway.
-@example
+@smallexample
// @r{this is} // @r{one comment}
@r{text outside comment}
-@end example
+@end smallexample
@end enumerate
It is safe to put line comments inside block comments, or vice versa.
-@example
+@smallexample
@group
/* @r{block comment}
// @r{contains line comment}
@@ -365,19 +410,19 @@ It is safe to put line comments inside block comments, or vice versa.
// @r{line comment} /* @r{contains block comment} */
@end group
-@end example
+@end smallexample
But beware of commenting out one end of a block comment with a line
comment.
-@example
+@smallexample
@group
// @r{l.c.} /* @r{block comment begins}
@r{oops! this isn't a comment anymore} */
@end group
-@end example
+@end smallexample
-Comments are not recognized within string literals.
+Comments are not recognized within string literals.
@t{@w{"/* blah */"}} is the string constant @samp{@w{/* blah */}}, not
an empty string.
@@ -392,7 +437,7 @@ next line with backslash-newline. You can even split @samp{/*},
@samp{*/}, and @samp{//} onto multiple lines with backslash-newline.
For example:
-@example
+@smallexample
@group
/\
*
@@ -402,7 +447,7 @@ ne FO\
O 10\
20
@end group
-@end example
+@end smallexample
@noindent
is equivalent to @code{@w{#define FOO 1020}}. All these tricks are
@@ -437,7 +482,7 @@ Once the input file is broken into tokens, the token boundaries never
change, except when the @samp{##} preprocessing operator is used to paste
tokens together. @xref{Concatenation}. For example,
-@example
+@smallexample
@group
#define foo() bar
foo()baz
@@ -445,7 +490,7 @@ foo()baz
@emph{not}
@expansion{} barbaz
@end group
-@end example
+@end smallexample
The compiler does not re-tokenize the preprocessor's output. Each
preprocessing token becomes one compiler token.
@@ -545,10 +590,10 @@ punctuation in obsolete systems. It has no negative side effects,
unlike trigraphs, but does not cover as much ground. The digraphs and
their corresponding normal punctuators are:
-@example
+@smallexample
Digraph: <% %> <: :> %: %:%:
Punctuator: @{ @} [ ] # ##
-@end example
+@end smallexample
@cindex other tokens
Any other single character is considered ``other.'' It is passed on to
@@ -568,10 +613,10 @@ silently ignored, just as any other character would be. In running
text, NUL is considered white space. For example, these two directives
have the same meaning.
-@example
+@smallexample
#define X^@@1
#define X 1
-@end example
+@end smallexample
@noindent
(where @samp{^@@} is ASCII NUL)@. Within string or character constants,
@@ -746,15 +791,15 @@ file, followed by the output that comes from the text after the
@samp{#include} directive. For example, if you have a header file
@file{header.h} as follows,
-@example
+@smallexample
char *test (void);
-@end example
+@end smallexample
@noindent
and a main program called @file{program.c} that uses the header file,
like this,
-@example
+@smallexample
int x;
#include "header.h"
@@ -763,13 +808,13 @@ main (void)
@{
puts (test ());
@}
-@end example
+@end smallexample
@noindent
the compiler will see the same token stream as it would if
@file{program.c} read
-@example
+@smallexample
int x;
char *test (void);
@@ -778,7 +823,7 @@ main (void)
@{
puts (test ());
@}
-@end example
+@end smallexample
Included files are not limited to declarations and macro definitions;
those are merely the typical uses. Any fragment of a C program can be
@@ -805,12 +850,12 @@ GCC looks in several different places for headers. On a normal Unix
system, if you do not instruct it otherwise, it will look for headers
requested with @code{@w{#include <@var{file}>}} in:
-@example
+@smallexample
/usr/local/include
-/usr/lib/gcc-lib/@var{target}/@var{version}/include
+@var{libdir}/gcc/@var{target}/@var{version}/include
/usr/@var{target}/include
/usr/include
-@end example
+@end smallexample
For C++ programs, it will also look in @file{/usr/include/g++-v3},
first. In the above, @var{target} is the canonical name of the system
@@ -881,7 +926,7 @@ it will certainly waste time.
The standard way to prevent this is to enclose the entire real contents
of the file in a conditional, like this:
-@example
+@smallexample
@group
/* File foo. */
#ifndef FILE_FOO_SEEN
@@ -891,7 +936,7 @@ of the file in a conditional, like this:
#endif /* !FILE_FOO_SEEN */
@end group
-@end example
+@end smallexample
This construct is commonly known as a @dfn{wrapper #ifndef}.
When the header is included again, the conditional will be false,
@@ -926,7 +971,7 @@ files to be included into your program. They might specify
configuration parameters to be used on different sorts of operating
systems, for instance. You could do this with a series of conditionals,
-@example
+@smallexample
#if SYSTEM_1
# include "system_1.h"
#elif SYSTEM_2
@@ -934,18 +979,18 @@ systems, for instance. You could do this with a series of conditionals,
#elif SYSTEM_3
@dots{}
#endif
-@end example
+@end smallexample
That rapidly becomes tedious. Instead, the preprocessor offers the
ability to use a macro for the header name. This is called a
@dfn{computed include}. Instead of writing a header name as the direct
argument of @samp{#include}, you simply put a macro name there instead:
-@example
+@smallexample
#define SYSTEM_H "system_1.h"
@dots{}
#include SYSTEM_H
-@end example
+@end smallexample
@noindent
@code{SYSTEM_H} will be expanded, and the preprocessor will look for
@@ -970,10 +1015,10 @@ string constant are the file to be included. CPP does not re-examine the
string for embedded quotes, but neither does it process backslash
escapes in the string. Therefore
-@example
+@smallexample
#define HEADER "a\"b"
#include HEADER
-@end example
+@end smallexample
@noindent
looks for a file named @file{a\"b}. CPP searches for the file according
@@ -1018,9 +1063,9 @@ header is not protected from multiple inclusion (@pxref{Once-Only
Headers}), it will recurse infinitely and cause a fatal error.
You could include the old header with an absolute pathname:
-@example
+@smallexample
#include "/usr/include/old-header.h"
-@end example
+@end smallexample
@noindent
This works, but is not clean; should the system headers ever move, you
would have to edit the new headers to match.
@@ -1139,29 +1184,29 @@ followed by the name of the macro and then the token sequence it should
be an abbreviation for, which is variously referred to as the macro's
@dfn{body}, @dfn{expansion} or @dfn{replacement list}. For example,
-@example
+@smallexample
#define BUFFER_SIZE 1024
-@end example
+@end smallexample
@noindent
defines a macro named @code{BUFFER_SIZE} as an abbreviation for the
token @code{1024}. If somewhere after this @samp{#define} directive
there comes a C statement of the form
-@example
+@smallexample
foo = (char *) malloc (BUFFER_SIZE);
-@end example
+@end smallexample
@noindent
then the C preprocessor will recognize and @dfn{expand} the macro
@code{BUFFER_SIZE}. The C compiler will see the same tokens as it would
if you had written
-@example
+@smallexample
foo = (char *) malloc (1024);
-@end example
+@end smallexample
-By convention, macro names are written in upper case. Programs are
+By convention, macro names are written in uppercase. Programs are
easier to read when it is possible to tell at a glance which names are
macros.
@@ -1170,13 +1215,13 @@ continue the definition onto multiple lines, if necessary, using
backslash-newline. When the macro is expanded, however, it will all
come out on one line. For example,
-@example
+@smallexample
#define NUMBERS 1, \
2, \
3
int x[] = @{ NUMBERS @};
@expansion{} int x[] = @{ 1, 2, 3 @};
-@end example
+@end smallexample
@noindent
The most common visible consequence of this is surprising line numbers
@@ -1191,25 +1236,25 @@ The C preprocessor scans your program sequentially. Macro definitions
take effect at the place you write them. Therefore, the following input
to the C preprocessor
-@example
+@smallexample
foo = X;
#define X 4
bar = X;
-@end example
+@end smallexample
@noindent
produces
-@example
+@smallexample
foo = X;
bar = 4;
-@end example
+@end smallexample
When the preprocessor expands a macro name, the macro's expansion
replaces the macro invocation, then the expansion is examined for more
macros to expand. For example,
-@example
+@smallexample
@group
#define TABLESIZE BUFSIZE
#define BUFSIZE 1024
@@ -1217,7 +1262,7 @@ TABLESIZE
@expansion{} BUFSIZE
@expansion{} 1024
@end group
-@end example
+@end smallexample
@noindent
@code{TABLESIZE} is expanded first to produce @code{BUFSIZE}, then that
@@ -1235,12 +1280,12 @@ at some point in the source file. @code{TABLESIZE}, defined as shown,
will always expand using the definition of @code{BUFSIZE} that is
currently in effect:
-@example
+@smallexample
#define BUFSIZE 1020
#define TABLESIZE BUFSIZE
#undef BUFSIZE
#define BUFSIZE 37
-@end example
+@end smallexample
@noindent
Now @code{TABLESIZE} expands (in two stages) to @code{37}.
@@ -1259,24 +1304,24 @@ are called @dfn{function-like macros}. To define a function-like macro,
you use the same @samp{#define} directive, but you put a pair of
parentheses immediately after the macro name. For example,
-@example
+@smallexample
#define lang_init() c_init()
lang_init()
@expansion{} c_init()
-@end example
+@end smallexample
A function-like macro is only expanded if its name appears with a pair
of parentheses after it. If you write just the name, it is left alone.
This can be useful when you have a function and a macro of the same
name, and you wish to use the function sometimes.
-@example
+@smallexample
extern void foo(void);
#define foo() /* optimized inline version */
@dots{}
foo();
funcptr = foo;
-@end example
+@end smallexample
Here the call to @code{foo()} will use the macro, but the function
pointer will get the address of the real function. If the macro were to
@@ -1287,11 +1332,11 @@ macro definition, that does not define a function-like macro, it defines
an object-like macro whose expansion happens to begin with a pair of
parentheses.
-@example
+@smallexample
#define lang_init () c_init()
lang_init()
@expansion{} () c_init()()
-@end example
+@end smallexample
The first two pairs of parentheses in this expansion come from the
macro. The third is the pair that was originally after the macro
@@ -1323,12 +1368,12 @@ macro body.)
As an example, here is a macro that computes the minimum of two numeric
values, as it is defined in many C programs, and some uses.
-@example
+@smallexample
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
x = min(a, b); @expansion{} x = ((a) < (b) ? (a) : (b));
y = min(1, 2); @expansion{} y = ((1) < (2) ? (1) : (2));
z = min(a + 28, *p); @expansion{} z = ((a + 28) < (*p) ? (a + 28) : (*p));
-@end example
+@end smallexample
@noindent
(In this small example you can already see several of the dangers of
@@ -1341,9 +1386,9 @@ such parentheses does not end the argument. However, there is no
requirement for square brackets or braces to balance, and they do not
prevent a comma from separating arguments. Thus,
-@example
+@smallexample
macro (array[x = y, x + 1])
-@end example
+@end smallexample
@noindent
passes two arguments to @code{macro}: @code{array[x = y} and @code{x +
@@ -1361,20 +1406,20 @@ Prescan}, for detailed discussion.
For example, @code{min (min (a, b), c)} is first expanded to
-@example
+@smallexample
min (((a) < (b) ? (a) : (b)), (c))
-@end example
+@end smallexample
@noindent
and then to
-@example
+@smallexample
@group
((((a) < (b) ? (a) : (b))) < (c)
? (((a) < (b) ? (a) : (b)))
: (c))
@end group
-@end example
+@end smallexample
@noindent
(Line breaks shown here for clarity would not actually be generated.)
@@ -1386,7 +1431,7 @@ You cannot leave out arguments entirely; if a macro takes two arguments,
there must be exactly one comma at the top level of its argument list.
Here are some silly examples using @code{min}:
-@example
+@smallexample
min(, b) @expansion{} (( ) < (b) ? ( ) : (b))
min(a, ) @expansion{} ((a ) < ( ) ? (a ) : ( ))
min(,) @expansion{} (( ) < ( ) ? ( ) : ( ))
@@ -1394,7 +1439,7 @@ min((,),) @expansion{} (((,)) < ( ) ? ((,)) : ( ))
min() @error{} macro "min" requires 2 arguments, but only 1 given
min(,,) @error{} macro "min" passed 3 arguments, but takes just 2
-@end example
+@end smallexample
Whitespace is not a preprocessing token, so if a macro @code{foo} takes
one argument, @code{@w{foo ()}} and @code{@w{foo ( )}} both supply it an
@@ -1406,10 +1451,10 @@ empty argument was required.
Macro parameters appearing inside string literals are not replaced by
their corresponding actual arguments.
-@example
+@smallexample
#define foo(x) x, "x"
foo(bar) @expansion{} bar, "x"
-@end example
+@end smallexample
@node Stringification
@section Stringification
@@ -1433,7 +1478,7 @@ long string.
Here is an example of a macro definition that uses stringification:
-@example
+@smallexample
@group
#define WARN_IF(EXP) \
do @{ if (EXP) \
@@ -1443,7 +1488,7 @@ WARN_IF (x == 0);
@expansion{} do @{ if (x == 0)
fprintf (stderr, "Warning: " "x == 0" "\n"); @} while (0);
@end group
-@end example
+@end smallexample
@noindent
The argument for @code{EXP} is substituted once, as-is, into the
@@ -1476,7 +1521,7 @@ There is no way to convert a macro argument into a character constant.
If you want to stringify the result of expansion of a macro argument,
you have to use two levels of macros.
-@example
+@smallexample
#define xstr(s) str(s)
#define str(s) #s
#define foo 4
@@ -1486,7 +1531,7 @@ xstr (foo)
@expansion{} xstr (4)
@expansion{} str (4)
@expansion{} "4"
-@end example
+@end smallexample
@code{s} is stringified when it is used in @code{str}, so it is not
macro-expanded first. But @code{s} is an ordinary argument to
@@ -1543,7 +1588,7 @@ Consider a C program that interprets named commands. There probably
needs to be a table of commands, perhaps an array of structures declared
as follows:
-@example
+@smallexample
@group
struct command
@{
@@ -1560,7 +1605,7 @@ struct command commands[] =
@dots{}
@};
@end group
-@end example
+@end smallexample
It would be cleaner not to have to give each command name twice, once in
the string constant and once in the function name. A macro which takes the
@@ -1568,7 +1613,7 @@ name of a command as an argument can make this unnecessary. The string
constant can be created with stringification, and the function name by
concatenating the argument with @samp{_command}. Here is how it is done:
-@example
+@smallexample
#define COMMAND(NAME) @{ #NAME, NAME ## _command @}
struct command commands[] =
@@ -1577,7 +1622,7 @@ struct command commands[] =
COMMAND (help),
@dots{}
@};
-@end example
+@end smallexample
@node Variadic Macros
@section Variadic Macros
@@ -1589,9 +1634,9 @@ A macro can be declared to accept a variable number of arguments much as
a function can. The syntax for defining the macro is similar to that of
a function. Here is an example:
-@example
+@smallexample
#define eprintf(@dots{}) fprintf (stderr, __VA_ARGS__)
-@end example
+@end smallexample
This kind of macro is called @dfn{variadic}. When the macro is invoked,
all the tokens in its argument list after the last named argument (this
@@ -1600,10 +1645,10 @@ argument}. This sequence of tokens replaces the identifier
@code{@w{__VA_ARGS__}} in the macro body wherever it appears. Thus, we
have this expansion:
-@example
+@smallexample
eprintf ("%s:%d: ", input_file, lineno)
@expansion{} fprintf (stderr, "%s:%d: ", input_file, lineno)
-@end example
+@end smallexample
The variable argument is completely macro-expanded before it is inserted
into the macro expansion, just like an ordinary argument. You may use
@@ -1617,9 +1662,9 @@ this, as an extension. You may write an argument name immediately
before the @samp{@dots{}}; that name is used for the variable argument.
The @code{eprintf} macro above could be written
-@example
+@smallexample
#define eprintf(args@dots{}) fprintf (stderr, args)
-@end example
+@end smallexample
@noindent
using this extension. You cannot use @code{@w{__VA_ARGS__}} and this
@@ -1628,9 +1673,9 @@ extension in the same macro.
You can have named arguments as well as variable arguments in a variadic
macro. We could define @code{eprintf} like this, instead:
-@example
+@smallexample
#define eprintf(format, @dots{}) fprintf (stderr, format, __VA_ARGS__)
-@end example
+@end smallexample
@noindent
This formulation looks more descriptive, but unfortunately it is less
@@ -1640,26 +1685,26 @@ argument from the variable arguments. Furthermore, if you leave the
variable argument empty, you will get a syntax error, because
there will be an extra comma after the format string.
-@example
+@smallexample
eprintf("success!\n", );
@expansion{} fprintf(stderr, "success!\n", );
-@end example
+@end smallexample
GNU CPP has a pair of extensions which deal with this problem. First,
you are allowed to leave the variable argument out entirely:
-@example
+@smallexample
eprintf ("success!\n")
@expansion{} fprintf(stderr, "success!\n", );
-@end example
+@end smallexample
@noindent
Second, the @samp{##} token paste operator has a special meaning when
placed between a comma and a variable argument. If you write
-@example
+@smallexample
#define eprintf(format, @dots{}) fprintf (stderr, format, ##__VA_ARGS__)
-@end example
+@end smallexample
@noindent
and the variable argument is left out when the @code{eprintf} macro is
@@ -1667,10 +1712,10 @@ used, then the comma before the @samp{##} will be deleted. This does
@emph{not} happen if you pass an empty argument, nor does it happen if
the token preceding @samp{##} is anything other than a comma.
-@example
+@smallexample
eprintf ("success!\n")
@expansion{} fprintf(stderr, "success!\n");
-@end example
+@end smallexample
@noindent
The above explanation is ambiguous about the case where the only macro
@@ -1703,9 +1748,9 @@ previous versions of GCC, the token preceding the special @samp{##} must
be a comma, and there must be white space between that comma and
whatever comes immediately before it:
-@example
+@smallexample
#define eprintf(format, args@dots{}) fprintf (stderr, format , ##args)
-@end example
+@end smallexample
@noindent
@xref{Differences from previous versions}, for the gory details.
@@ -1758,12 +1803,12 @@ message to report an inconsistency detected by the program; the message
can state the source line at which the inconsistency was detected. For
example,
-@example
+@smallexample
fprintf (stderr, "Internal error: "
"negative string length "
"%d at %s, line %d.",
length, __FILE__, __LINE__);
-@end example
+@end smallexample
An @samp{#include} directive changes the expansions of @code{__FILE__}
and @code{__LINE__} to correspond to the included file. At the end of
@@ -1849,7 +1894,8 @@ or a C++ compiler. This macro is similar to @code{__STDC_VERSION__}, in
that it expands to a version number. A fully conforming implementation
of the 1998 C++ standard will define this macro to @code{199711L}. The
GNU C++ compiler is not yet fully conforming, so it uses @code{1}
-instead. We hope to complete our implementation in the near future.
+instead. It is hoped to complete the implementation of standard C++
+in the near future.
@item __OBJC__
This macro is defined, with value 1, when the Objective-C compiler is in
@@ -1897,26 +1943,26 @@ minor version and patch level are reset. If you wish to use the
predefined macros directly in the conditional, you will need to write it
like this:
-@example
+@smallexample
/* @r{Test for GCC > 3.2.0} */
#if __GNUC__ > 3 || \
(__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \
(__GNUC_MINOR__ == 2 && \
__GNUC_PATCHLEVEL__ > 0))
-@end example
+@end smallexample
@noindent
Another approach is to use the predefined macros to
calculate a single number, then compare that against a threshold:
-@example
+@smallexample
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
@dots{}
/* @r{Test for GCC > 3.2.0} */
#if GCC_VERSION > 30200
-@end example
+@end smallexample
@noindent
Many people find this form easier to understand.
@@ -2022,7 +2068,7 @@ this macro directly; instead, include the appropriate headers.
@itemx __INT_MAX__
@itemx __LONG_MAX__
@itemx __LONG_LONG_MAX__
-Defined to the maximum value of the @code{signed char}, @code{wchar_t},
+Defined to the maximum value of the @code{signed char}, @code{wchar_t},
@code{signed short},
@code{signed int}, @code{signed long}, and @code{signed long long} types
respectively. They exist to make the standard header given numerical limits
@@ -2041,7 +2087,7 @@ runtime is used, this macro is not defined, so that you can use this
macro to determine which runtime (NeXT or GNU) is being used.
@item __LP64__
-@item _LP64
+@itemx _LP64
These macros are defined, with value 1, if (and only if) the compilation
is for a target where @code{long int} and pointer both use 64-bits and
@code{int} uses 32-bit.
@@ -2131,12 +2177,12 @@ macro is function-like. It is an error if anything appears on the line
after the macro name. @samp{#undef} has no effect if the name is not a
macro.
-@example
+@smallexample
#define FOO 4
x = FOO; @expansion{} x = 4;
#undef FOO
x = FOO; @expansion{} x = FOO;
-@end example
+@end smallexample
Once a macro has been undefined, that identifier may be @dfn{redefined}
as a macro by a subsequent @samp{#define} directive. The new definition
@@ -2156,19 +2202,19 @@ count as whitespace.
@noindent
These definitions are effectively the same:
-@example
+@smallexample
#define FOUR (2 + 2)
#define FOUR (2 + 2)
#define FOUR (2 /* two */ + 2)
-@end example
+@end smallexample
@noindent
but these are not:
-@example
+@smallexample
#define FOUR (2 + 2)
#define FOUR ( 2+2 )
#define FOUR (2 * 2)
#define FOUR(score,and,seven,years,ago) (2 + 2)
-@end example
+@end smallexample
If a macro is redefined with a definition that is not effectively the
same as the old one, the preprocessor issues a warning and changes the
@@ -2249,25 +2295,25 @@ the input file, for more macro calls. It is possible to piece together
a macro call coming partially from the macro body and partially from the
arguments. For example,
-@example
+@smallexample
#define twice(x) (2*(x))
#define call_with_1(x) x(1)
call_with_1 (twice)
@expansion{} twice(1)
@expansion{} (2*(1))
-@end example
+@end smallexample
Macro definitions do not have to have balanced parentheses. By writing
an unbalanced open parenthesis in a macro body, it is possible to create
a macro call that begins inside the macro body but ends outside of it.
For example,
-@example
+@smallexample
#define strange(file) fprintf (file, "%s %d",
@dots{}
strange(stderr) p, 35)
@expansion{} fprintf (stderr, "%s %d", p, 35)
-@end example
+@end smallexample
The ability to piece together a macro call can be useful, but the use of
unbalanced open parentheses in a macro body is just confusing, and
@@ -2285,41 +2331,41 @@ way.
Suppose you define a macro as follows,
-@example
+@smallexample
#define ceil_div(x, y) (x + y - 1) / y
-@end example
+@end smallexample
@noindent
whose purpose is to divide, rounding up. (One use for this operation is
to compute how many @code{int} objects are needed to hold a certain
number of @code{char} objects.) Then suppose it is used as follows:
-@example
+@smallexample
a = ceil_div (b & c, sizeof (int));
@expansion{} a = (b & c + sizeof (int) - 1) / sizeof (int);
-@end example
+@end smallexample
@noindent
This does not do what is intended. The operator-precedence rules of
C make it equivalent to this:
-@example
+@smallexample
a = (b & (c + sizeof (int) - 1)) / sizeof (int);
-@end example
+@end smallexample
@noindent
What we want is this:
-@example
+@smallexample
a = ((b & c) + sizeof (int) - 1)) / sizeof (int);
-@end example
+@end smallexample
@noindent
Defining the macro as
-@example
+@smallexample
#define ceil_div(x, y) ((x) + (y) - 1) / (y)
-@end example
+@end smallexample
@noindent
provides the desired result.
@@ -2329,9 +2375,9 @@ ceil_div(1, 2)}. That has the appearance of a C expression that would
compute the size of the type of @code{ceil_div (1, 2)}, but in fact it
means something very different. Here is what it expands to:
-@example
+@smallexample
sizeof ((1) + (2) - 1) / (2)
-@end example
+@end smallexample
@noindent
This would take the size of an integer and divide it by two. The
@@ -2341,9 +2387,9 @@ was intended to be inside.
Parentheses around the entire macro definition prevent such problems.
Here, then, is the recommended way to define @code{ceil_div}:
-@example
+@smallexample
#define ceil_div(x, y) (((x) + (y) - 1) / (y))
-@end example
+@end smallexample
@node Swallowing the Semicolon
@subsection Swallowing the Semicolon
@@ -2354,13 +2400,13 @@ statement. Consider, for example, the following macro, that advances a
pointer (the argument @code{p} says where to find it) across whitespace
characters:
-@example
+@smallexample
#define SKIP_SPACES(p, limit) \
@{ char *lim = (limit); \
while (p < lim) @{ \
if (*p++ != ' ') @{ \
p--; break; @}@}@}
-@end example
+@end smallexample
@noindent
Here backslash-newline is used to split the macro definition, which must
@@ -2377,11 +2423,11 @@ like a function call, writing a semicolon afterward, as in
This can cause trouble before @code{else} statements, because the
semicolon is actually a null statement. Suppose you write
-@example
+@smallexample
if (*p != 0)
SKIP_SPACES (p, lim);
else @dots{}
-@end example
+@end smallexample
@noindent
The presence of two statements---the compound statement and a null
@@ -2391,20 +2437,20 @@ makes invalid C code.
The definition of the macro @code{SKIP_SPACES} can be altered to solve
this problem, using a @code{do @dots{} while} statement. Here is how:
-@example
+@smallexample
#define SKIP_SPACES(p, limit) \
do @{ char *lim = (limit); \
while (p < lim) @{ \
if (*p++ != ' ') @{ \
p--; break; @}@}@} \
while (0)
-@end example
+@end smallexample
Now @code{SKIP_SPACES (p, lim);} expands into
-@example
+@smallexample
do @{@dots{}@} while (0);
-@end example
+@end smallexample
@noindent
which is one statement. The loop executes exactly once; most compilers
@@ -2417,23 +2463,23 @@ generate no extra code for it.
@cindex unsafe macros
Many C programs define a macro @code{min}, for ``minimum'', like this:
-@example
+@smallexample
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
-@end example
+@end smallexample
When you use this macro with an argument containing a side effect,
as shown here,
-@example
+@smallexample
next = min (x + y, foo (z));
-@end example
+@end smallexample
@noindent
it expands as follows:
-@example
+@smallexample
next = ((x + y) < (foo (z)) ? (x + y) : (foo (z)));
-@end example
+@end smallexample
@noindent
where @code{x + y} has been substituted for @code{X} and @code{foo (z)}
@@ -2451,12 +2497,12 @@ computes the value of @code{foo (z)} only once. The C language offers
no standard way to do this, but it can be done with GNU extensions as
follows:
-@example
+@smallexample
#define min(X, Y) \
(@{ typeof (X) x_ = (X); \
typeof (Y) y_ = (Y); \
(x_ < y_) ? x_ : y_; @})
-@end example
+@end smallexample
The @samp{(@{ @dots{} @})} notation produces a compound statement that
acts as an expression. Its value is the value of its last statement.
@@ -2470,7 +2516,7 @@ careful when @emph{using} the macro @code{min}. For example, you can
calculate the value of @code{foo (z)}, save it in a variable, and use
that variable in @code{min}:
-@example
+@smallexample
@group
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
@dots{}
@@ -2479,7 +2525,7 @@ that variable in @code{min}:
next = min (x + y, tem);
@}
@end group
-@end example
+@end smallexample
@noindent
(where we assume that @code{foo} returns type @code{int}).
@@ -2493,11 +2539,11 @@ definition. Recall that all macro definitions are rescanned for more
macros to replace. If the self-reference were considered a use of the
macro, it would produce an infinitely large expansion. To prevent this,
the self-reference is not considered a macro call. It is passed into
-the preprocessor output unchanged. Let's consider an example:
+the preprocessor output unchanged. Consider an example:
-@example
+@smallexample
#define foo (4 + foo)
-@end example
+@end smallexample
@noindent
where @code{foo} is also a variable in your program.
@@ -2520,9 +2566,9 @@ of the variable @code{foo}, whereas in fact the value is four greater.
One common, useful use of self-reference is to create a macro which
expands to itself. If you write
-@example
+@smallexample
#define EPERM EPERM
-@end example
+@end smallexample
@noindent
then the macro @code{EPERM} expands to @code{EPERM}. Effectively, it is
@@ -2536,15 +2582,15 @@ If a macro @code{x} expands to use a macro @code{y}, and the expansion of
self-reference} of @code{x}. @code{x} is not expanded in this case
either. Thus, if we have
-@example
+@smallexample
#define x (4 + y)
#define y (2 * x)
-@end example
+@end smallexample
@noindent
then @code{x} and @code{y} expand as follows:
-@example
+@smallexample
@group
x @expansion{} (4 + y)
@expansion{} (4 + (2 * x))
@@ -2552,7 +2598,7 @@ x @expansion{} (4 + y)
y @expansion{} (2 * x)
@expansion{} (2 * (4 + y))
@end group
-@end example
+@end smallexample
@noindent
Each macro is expanded when it appears in the definition of the other
@@ -2613,12 +2659,12 @@ concatenate its expansion, you can do that by causing one macro to call
another macro that does the stringification or concatenation. For
instance, if you have
-@example
+@smallexample
#define AFTERX(x) X_ ## x
#define XAFTERX(x) AFTERX(x)
#define TABLESIZE 1024
#define BUFSIZE TABLESIZE
-@end example
+@end smallexample
then @code{AFTERX(BUFSIZE)} expands to @code{X_BUFSIZE}, and
@code{XAFTERX(BUFSIZE)} expands to @code{X_1024}. (Not to
@@ -2630,11 +2676,11 @@ Macros used in arguments, whose expansions contain unshielded commas.
This can cause a macro expanded on the second scan to be called with the
wrong number of arguments. Here is an example:
-@example
+@smallexample
#define foo a,b
#define bar(x) lose(x)
#define lose(x) (1 + (x))
-@end example
+@end smallexample
We would like @code{bar(foo)} to turn into @code{(1 + (foo))}, which
would then turn into @code{(1 + (a,b))}. Instead, @code{bar(foo)}
@@ -2643,11 +2689,11 @@ requires a single argument. In this case, the problem is easily solved
by the same parentheses that ought to be used to prevent misnesting of
arithmetic operations:
-@example
+@smallexample
#define foo (a,b)
@exdent or
#define bar(x) lose((x))
-@end example
+@end smallexample
The extra pair of parentheses prevents the comma in @code{foo}'s
definition from being interpreted as an argument separator.
@@ -2666,13 +2712,13 @@ different to the line containing the argument causing the problem.
Here is an example illustrating this:
-@example
+@smallexample
#define ignore_second_arg(a,b,c) a; c
ignore_second_arg (foo (),
ignored (),
syntax error);
-@end example
+@end smallexample
@noindent
The syntax error triggered by the tokens @code{syntax error} results in
@@ -2773,7 +2819,7 @@ directive}: @samp{#if}, @samp{#ifdef} or @samp{#ifndef}.
The simplest sort of conditional is
-@example
+@smallexample
@group
#ifdef @var{MACRO}
@@ -2781,7 +2827,7 @@ The simplest sort of conditional is
#endif /* @var{MACRO} */
@end group
-@end example
+@end smallexample
@cindex conditional group
This block is called a @dfn{conditional group}. @var{controlled text}
@@ -2854,7 +2900,7 @@ automated by a tool such as @command{autoconf}, or done by hand.
The @samp{#if} directive allows you to test the value of an arithmetic
expression, rather than the mere existence of one macro. Its syntax is
-@example
+@smallexample
@group
#if @var{expression}
@@ -2862,7 +2908,7 @@ expression, rather than the mere existence of one macro. Its syntax is
#endif /* @var{expression} */
@end group
-@end example
+@end smallexample
@var{expression} is a C expression of integer type, subject to stringent
restrictions. It may contain
@@ -2915,9 +2961,6 @@ expression, and may give different results in some cases. If the value
comes out to be nonzero, the @samp{#if} succeeds and the @var{controlled
text} is included; otherwise it is skipped.
-If @var{expression} is not correctly formed, GCC issues an error and
-treats the conditional as having failed.
-
@node Defined
@subsection Defined
@@ -2932,9 +2975,9 @@ defined MACRO}} is precisely equivalent to @code{@w{#ifdef MACRO}}.
@code{defined} is useful when you wish to test more than one macro for
existence at once. For example,
-@example
+@smallexample
#if defined (__vax__) || defined (__ns16000__)
-@end example
+@end smallexample
@noindent
would succeed if either of the names @code{__vax__} or
@@ -2942,9 +2985,9 @@ would succeed if either of the names @code{__vax__} or
Conditionals written like this:
-@example
+@smallexample
#if defined BUFSIZE && BUFSIZE >= 1024
-@end example
+@end smallexample
@noindent
can generally be simplified to just @code{@w{#if BUFSIZE >= 1024}},
@@ -2965,7 +3008,7 @@ The @samp{#else} directive can be added to a conditional to provide
alternative text to be used if the condition fails. This is what it
looks like:
-@example
+@smallexample
@group
#if @var{expression}
@var{text-if-true}
@@ -2973,7 +3016,7 @@ looks like:
@var{text-if-false}
#endif /* Not @var{expression} */
@end group
-@end example
+@end smallexample
@noindent
If @var{expression} is nonzero, the @var{text-if-true} is included and
@@ -2989,7 +3032,7 @@ You can use @samp{#else} with @samp{#ifdef} and @samp{#ifndef}, too.
One common case of nested conditionals is used to check for more than two
possible alternatives. For example, you might have
-@example
+@smallexample
#if X == 1
@dots{}
#else /* X != 1 */
@@ -2999,12 +3042,12 @@ possible alternatives. For example, you might have
@dots{}
#endif /* X != 2 */
#endif /* X != 1 */
-@end example
+@end smallexample
Another conditional directive, @samp{#elif}, allows this to be
abbreviated as follows:
-@example
+@smallexample
#if X == 1
@dots{}
#elif X == 2
@@ -3012,7 +3055,7 @@ abbreviated as follows:
#else /* X != 2 and X != 1*/
@dots{}
#endif /* X != 2 and X != 1*/
-@end example
+@end smallexample
@samp{#elif} stands for ``else if''. Like @samp{#else}, it goes in the
middle of a conditional group and subdivides it; it does not require a
@@ -3072,23 +3115,23 @@ combination of parameters which you know the program does not properly
support. For example, if you know that the program will not run
properly on a VAX, you might write
-@example
+@smallexample
@group
#ifdef __vax__
#error "Won't work on VAXen. See comments at get_last_object."
#endif
@end group
-@end example
+@end smallexample
If you have several configuration parameters that must be set up by
the installation in a consistent way, you can use conditionals to detect
an inconsistency and report it with @samp{#error}. For example,
-@example
+@smallexample
#if !defined(UNALIGNED_INT_ASM_OP) && defined(DWARF2_DEBUGGING_INFO)
#error "DWARF2_DEBUGGING_INFO requires UNALIGNED_INT_ASM_OP."
#endif
-@end example
+@end smallexample
@findex #warning
The directive @samp{#warning} is like @samp{#error}, but causes the
@@ -3222,18 +3265,18 @@ literal. It is destringized, by replacing all @samp{\\} with a single
processed as if it had appeared as the right hand side of a
@samp{#pragma} directive. For example,
-@example
+@smallexample
_Pragma ("GCC dependency \"parse.y\"")
-@end example
+@end smallexample
@noindent
has the same effect as @code{#pragma GCC dependency "parse.y"}. The
same effect could be achieved using macros, for example
-@example
+@smallexample
#define DO_PRAGMA(x) _Pragma (#x)
DO_PRAGMA (GCC dependency "parse.y")
-@end example
+@end smallexample
The standard is unclear on where a @code{_Pragma} operator can appear.
The preprocessor does not accept it within a preprocessing conditional
@@ -3255,10 +3298,10 @@ other file is searched for using the normal include search path.
Optional trailing text can be used to give more information in the
warning message.
-@example
+@smallexample
#pragma GCC dependency "parse.y"
#pragma GCC dependency "/usr/include/time.h" rerun fixincludes
-@end example
+@end smallexample
@item #pragma GCC poison
Sometimes, there is an identifier that you want to remove completely
@@ -3268,10 +3311,10 @@ enforce this, you can @dfn{poison} the identifier with this pragma.
poison. If any of those identifiers appears anywhere in the source
after the directive, it is a hard error. For example,
-@example
+@smallexample
#pragma GCC poison printf sprintf fprintf
sprintf(some_string, "hello");
-@end example
+@end smallexample
@noindent
will produce an error.
@@ -3283,11 +3326,11 @@ about system headers defining macros that use it.
For example,
-@example
+@smallexample
#define strrchr rindex
#pragma GCC poison rindex
strrchr(some_string, 'h');
-@end example
+@end smallexample
@noindent
will not produce an error.
@@ -3356,9 +3399,9 @@ necessary to prevent an accidental token paste.
Source file name and line number information is conveyed by lines
of the form
-@example
+@smallexample
# @var{linenum} @var{filename} @var{flags}
-@end example
+@end smallexample
@noindent
These are called @dfn{linemarkers}. They are inserted as needed into
@@ -3706,8 +3749,30 @@ and stick to it.
@item The mapping of physical source file multi-byte characters to the
execution character set.
-Currently, GNU cpp only supports character sets that are strict supersets
-of ASCII, and performs no translation of characters.
+Currently, CPP requires its input to be ASCII or UTF-8. The execution
+character set may be controlled by the user, with the
+@code{-ftarget-charset} and @code{-ftarget-wide-charset} options.
+
+@item Identifier characters.
+@anchor{Identifier characters}
+
+The C and C++ standards allow identifiers to be composed of @samp{_}
+and the alphanumeric characters. C++ and C99 also allow universal
+character names (not implemented in GCC), and C99 further permits
+implementation-defined characters.
+
+GCC allows the @samp{$} character in identifiers as an extension for
+most targets. This is true regardless of the @option{std=} switch,
+since this extension cannot conflict with standards-conforming
+programs. When preprocessing assembler, however, dollars are not
+identifier characters by default.
+
+Currently the targets that by default do not permit @samp{$} are AVR,
+IP2K, MMIX, MIPS Irix 3, ARM aout, and PowerPC targets for the AIX and
+BeOS operating systems.
+
+You can override the default with @option{-fdollars-in-identifiers} or
+@option{fno-dollars-in-identifiers}. @xref{fdollars-in-identifiers}.
@item Non-empty sequences of whitespace characters.
@@ -3765,10 +3830,10 @@ pragmas.
CPP has a small number of internal limits. This section lists the
limits which the C standard requires to be no lower than some minimum,
-and all the others we are aware of. We intend there to be as few limits
+and all the others known. It is intended that there should be as few limits
as possible. If you encounter an undocumented or inconvenient limit,
-please report that to us as a bug. (See the section on reporting bugs in
-the GCC manual.)
+please report that as a bug. @xref{Bugs, , Reporting Bugs, gcc, Using
+the GNU Compiler Collection (GCC)}.
Where we say something is limited @dfn{only by available memory}, that
means that internal data structures impose no intrinsic limit, and space
@@ -3857,9 +3922,9 @@ all.
@cindex predicates
An assertion looks like this:
-@example
+@smallexample
#@var{predicate} (@var{answer})
-@end example
+@end smallexample
@noindent
@var{predicate} must be a single identifier. @var{answer} can be any
@@ -3875,26 +3940,26 @@ To test an assertion, you write it in an @samp{#if}. For example, this
conditional succeeds if either @code{vax} or @code{ns16000} has been
asserted as an answer for @code{machine}.
-@example
+@smallexample
#if #machine (vax) || #machine (ns16000)
-@end example
+@end smallexample
@noindent
You can test whether @emph{any} answer is asserted for a predicate by
omitting the answer in the conditional:
-@example
+@smallexample
#if #machine
-@end example
+@end smallexample
@findex #assert
Assertions are made with the @samp{#assert} directive. Its sole
argument is the assertion to make, without the leading @samp{#} that
identifies assertions in conditionals.
-@example
+@smallexample
#assert @var{predicate} (@var{answer})
-@end example
+@end smallexample
@noindent
You may make several assertions with the same predicate and different
@@ -3910,9 +3975,9 @@ answer which was specified on the @samp{#unassert} line; other answers
for that predicate remain true. You can cancel an entire predicate by
leaving out the answer:
-@example
+@smallexample
#unassert @var{predicate}
-@end example
+@end smallexample
@noindent
In either form, if no such assertion has been made, @samp{#unassert} has
@@ -4066,7 +4131,9 @@ without notice.
cpp [@option{-D}@var{macro}[=@var{defn}]@dots{}] [@option{-U}@var{macro}]
[@option{-I}@var{dir}@dots{}] [@option{-W}@var{warn}@dots{}]
[@option{-M}|@option{-MM}] [@option{-MG}] [@option{-MF} @var{filename}]
- [@option{-MP}] [@option{-MQ} @var{target}@dots{}] [@option{-MT} @var{target}@dots{}]
+ [@option{-MP}] [@option{-MQ} @var{target}@dots{}]
+ [@option{-MT} @var{target}@dots{}]
+ [@option{-P}] [@option{-fno-working-directory}]
[@option{-x} @var{language}] [@option{-std=}@var{standard}]
@var{infile} @var{outfile}
@@ -4119,7 +4186,7 @@ Note that you can also specify places to search using options such as
@option{-M} (@pxref{Invocation}). These take precedence over
environment variables, which in turn take precedence over the
configuration of GCC@.
-
+
@include cppenv.texi
@c man end
diff --git a/contrib/gcc/doc/cppenv.texi b/contrib/gcc/doc/cppenv.texi
index 7a913f15903c..bb29cb2d1407 100644
--- a/contrib/gcc/doc/cppenv.texi
+++ b/contrib/gcc/doc/cppenv.texi
@@ -1,4 +1,4 @@
-@c Copyright (c) 1999, 2000, 2001, 2002
+@c Copyright (c) 1999, 2000, 2001, 2002, 2004
@c Free Software Foundation, Inc.
@c This is part of the CPP and GCC manuals.
@c For copying conditions, see the file gcc.texi.
@@ -20,7 +20,7 @@
Each variable's value is a list of directories separated by a special
character, much like @env{PATH}, in which to look for header files.
The special character, @code{PATH_SEPARATOR}, is target-dependent and
-determined at GCC build time. For Windows-based targets it is a
+determined at GCC build time. For Microsoft Windows-based targets it is a
semicolon, and for almost all other targets it is a colon.
@env{CPATH} specifies a list of directories to be searched as if
diff --git a/contrib/gcc/doc/cppinternals.texi b/contrib/gcc/doc/cppinternals.texi
index 3f3d9af00517..9f5863c3b702 100644
--- a/contrib/gcc/doc/cppinternals.texi
+++ b/contrib/gcc/doc/cppinternals.texi
@@ -16,7 +16,7 @@
@ifinfo
This file documents the internals of the GNU C Preprocessor.
-Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+Copyright 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -47,7 +47,7 @@ into another language, under the above conditions for modified versions.
@page
@vskip 0pt plus 1filll
@c man begin COPYRIGHT
-Copyright @copyright{} 2000, 2001, 2002
+Copyright @copyright{} 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
@@ -226,7 +226,7 @@ foo
@end smallexample
This is a good example of the subtlety of getting token spacing correct
-in the preprocessor; there are plenty of tests in the test suite for
+in the preprocessor; there are plenty of tests in the testsuite for
corner cases like this.
The lexer is written to treat each of @samp{\r}, @samp{\n}, @samp{\r\n}
@@ -368,8 +368,8 @@ chaining a new token run on to the end of the existing one.
The tokens forming a macro's replacement list are collected by the
@code{#define} handler, and placed in storage that is only freed by
-@code{cpp_destroy}. So if a macro is expanded in our line of tokens,
-the pointers to the tokens of its expansion that we return will always
+@code{cpp_destroy}. So if a macro is expanded in the line of tokens,
+the pointers to the tokens of its expansion that are returned will always
remain valid. However, macros are a little trickier than that, since
they give rise to three sources of fresh tokens. They are the built-in
macros like @code{__LINE__}, and the @samp{#} and @samp{##} operators
@@ -640,8 +640,8 @@ is safe.
@cindex spacing
@cindex token spacing
-First, let's look at an issue that only concerns the stand-alone
-preprocessor: we want to guarantee that re-reading its preprocessed
+First, consider an issue that only concerns the stand-alone
+preprocessor: there needs to be a guarantee that re-reading its preprocessed
output results in an identical token stream. Without taking special
measures, this might not be the case because of macro substitution.
For example:
@@ -670,7 +670,7 @@ expansion, but accidental pasting can occur in many places: both before
and after each macro replacement, each argument replacement, and
additionally each token created by the @samp{#} and @samp{##} operators.
-Let's look at how the preprocessor gets whitespace output correct
+Look at how the preprocessor gets whitespace output correct
normally. The @code{cpp_token} structure contains a flags byte, and one
of those flags is @code{PREV_WHITE}. This is flagged by the lexer, and
indicates that the token was preceded by whitespace of some form other
@@ -719,11 +719,11 @@ a macro's first replacement token expands straight into another macro.
Here, two padding tokens are generated with sources the @samp{foo} token
between the brackets, and the @samp{bar} token from foo's replacement
-list, respectively. Clearly the first padding token is the one we
-should use, so our output code should contain a rule that the first
+list, respectively. Clearly the first padding token is the one to
+use, so the output code should contain a rule that the first
padding token in a sequence is the one that matters.
-But what if we happen to leave a macro expansion? Adjusting the above
+But what if a macro expansion is left? Adjusting the above
example slightly:
@smallexample
diff --git a/contrib/gcc/doc/cppopts.texi b/contrib/gcc/doc/cppopts.texi
index 1cc688a4730f..6e784de1f501 100644
--- a/contrib/gcc/doc/cppopts.texi
+++ b/contrib/gcc/doc/cppopts.texi
@@ -1,4 +1,4 @@
-@c Copyright (c) 1999, 2000, 2001, 2002
+@c Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004
@c Free Software Foundation, Inc.
@c This is part of the CPP and GCC manuals.
@c For copying conditions, see the file gcc.texi.
@@ -17,10 +17,14 @@ Predefine @var{name} as a macro, with definition @code{1}.
@item -D @var{name}=@var{definition}
Predefine @var{name} as a macro, with definition @var{definition}.
-There are no restrictions on the contents of @var{definition}, but if
-you are invoking the preprocessor from a shell or shell-like program you
-may need to use the shell's quoting syntax to protect characters such as
-spaces that have a meaning in the shell syntax.
+The contents of @var{definition} are tokenized and processed as if
+they appeared during translation phase three in a @samp{#define}
+directive. In particular, the definition will be truncated by
+embedded newline characters.
+
+If you are invoking the preprocessor from a shell or shell-like
+program you may need to use the shell's quoting syntax to protect
+characters such as spaces that have a meaning in the shell syntax.
If you wish to define a function-like macro on the command line, write
its argument list with surrounding parentheses before the equals sign
@@ -72,10 +76,12 @@ use @option{-o} to specify the output file.
@item -Wall
@opindex Wall
-Turns on all optional warnings which are desirable for normal code. At
-present this is @option{-Wcomment} and @option{-Wtrigraphs}. Note that
-many of the preprocessor's warnings are on by default and have no
-options to control them.
+Turns on all optional warnings which are desirable for normal code.
+At present this is @option{-Wcomment}, @option{-Wtrigraphs},
+@option{-Wmultichar} and a warning about integer promotion causing a
+change of sign in @code{#if} expressions. Note that many of the
+preprocessor's warnings are on by default and have no options to
+control them.
@item -Wcomment
@itemx -Wcomments
@@ -87,10 +93,17 @@ comment, or whenever a backslash-newline appears in a @samp{//} comment.
@item -Wtrigraphs
@opindex Wtrigraphs
-Warn if any trigraphs are encountered. This option used to take effect
-only if @option{-trigraphs} was also specified, but now works
-independently. Warnings are not given for trigraphs within comments, as
-they do not affect the meaning of the program.
+@anchor{Wtrigraphs}
+Most trigraphs in comments cannot affect the meaning of the program.
+However, a trigraph that would form an escaped newline (@samp{??/} at
+the end of a line) can, by changing where the comment begins or ends.
+Therefore, only trigraphs that would form escaped newlines produce
+warnings inside a comment.
+
+This option is implied by @option{-Wall}. If @option{-Wall} is not
+given, this option is still enabled unless trigraphs are enabled. To
+get trigraph conversion without warnings, but get the other
+@option{-Wall} warnings, use @samp{-trigraphs -Wall -Wno-trigraphs}.
@item -Wtraditional
@opindex Wtraditional
@@ -214,9 +227,9 @@ This implies that the choice of angle brackets or double quotes in an
header will appear in @option{-MM} dependency output. This is a
slight change in semantics from GCC versions 3.0 and earlier.
+@anchor{dashMF}
@item -MF @var{file}
@opindex MF
-@anchor{-MF}
When used with @option{-M} or @option{-MM}, specifies a
file to write the dependencies to. If no @option{-MF} switch is given
the preprocessor sends the rules to the same place it would have sent
@@ -246,11 +259,11 @@ files without updating the @file{Makefile} to match.
This is typical output:
-@example
+@smallexample
test.o: test.c test.h
test.h:
-@end example
+@end smallexample
@item -MT @var{target}
@opindex MT
@@ -266,9 +279,9 @@ argument to @option{-MT}, or use multiple @option{-MT} options.
For example, @option{@w{-MT '$(objpfx)foo.o'}} might give
-@example
+@smallexample
$(objpfx)foo.o: foo.c
-@end example
+@end smallexample
@item -MQ @var{target}
@opindex MQ
@@ -276,9 +289,9 @@ $(objpfx)foo.o: foo.c
Same as @option{-MT}, but it quotes any characters which are special to
Make. @option{@w{-MQ '$(objpfx)foo.o'}} gives
-@example
+@smallexample
$$(objpfx)foo.o: foo.c
-@end example
+@end smallexample
The default target is automatically quoted, as if it were given with
@option{-MQ}.
@@ -293,7 +306,7 @@ basename of the input file and applies a @file{.d} suffix.
If @option{-MD} is used in conjunction with @option{-E}, any
@option{-o} switch is understood to specify the dependency output file
-(but @pxref{-MF}), but if used without @option{-E}, each @option{-o}
+(but @pxref{dashMF,,-MF}), but if used without @option{-E}, each @option{-o}
is understood to specify a target object file.
Since @option{-E} is not implied, @option{-MD} can be used to generate
@@ -304,6 +317,17 @@ a dependency output file as a side-effect of the compilation process.
Like @option{-MD} except mention only user header files, not system
-header files.
+@ifclear cppmanual
+@item -fpch-deps
+@opindex fpch-deps
+When using precompiled headers (@pxref{Precompiled Headers}), this flag
+will cause the dependency-output flags to also list the files from the
+precompiled header's dependencies. If not specified only the
+precompiled header would be listed and not the files that were used to
+create it because those files are not consulted when a precompiled
+header is used.
+
+@end ifclear
@item -x c
@itemx -x c++
@itemx -x objective-c
@@ -436,8 +460,6 @@ Append @var{dir} to the prefix specified previously with
path. @option{-iwithprefixbefore} puts it in the same place @option{-I}
would; @option{-iwithprefix} puts it where @option{-idirafter} would.
-Use of these options is discouraged.
-
@item -isystem @var{dir}
@opindex isystem
Search @var{dir} for header files, after all directories specified by
@@ -448,6 +470,14 @@ is applied to the standard system directories.
@xref{System Headers}.
@end ifset
+@item -fdollars-in-identifiers
+@opindex fdollars-in-identifiers
+@anchor{fdollars-in-identifiers}
+Accept @samp{$} in identifiers.
+@ifset cppmanual
+ @xref{Identifier characters}.
+@end ifset
+
@item -fpreprocessed
@opindex fpreprocessed
Indicate to the preprocessor that the input file has already been
@@ -470,6 +500,47 @@ correct column numbers in warnings or errors, even if tabs appear on the
line. If the value is less than 1 or greater than 100, the option is
ignored. The default is 8.
+@item -fexec-charset=@var{charset}
+@opindex fexec-charset
+Set the execution character set, used for string and character
+constants. The default is UTF-8. @var{charset} can be any encoding
+supported by the system's @code{iconv} library routine.
+
+@item -fwide-exec-charset=@var{charset}
+@opindex fwide-exec-charset
+Set the wide execution character set, used for wide string and
+character constants. The default is UTF-32 or UTF-16, whichever
+corresponds to the width of @code{wchar_t}. As with
+@option{-ftarget-charset}, @var{charset} can be any encoding supported
+by the system's @code{iconv} library routine; however, you will have
+problems with encodings that do not fit exactly in @code{wchar_t}.
+
+@item -finput-charset=@var{charset}
+@opindex finput-charset
+Set the input character set, used for translation from the character
+set of the input file to the source character set used by GCC. If the
+locale does not specify, or GCC cannot get this information from the
+locale, the default is UTF-8. This can be overridden by either the locale
+or this command line option. Currently the command line option takes
+precedence if there's a conflict. @var{charset} can be any encoding
+supported by the system's @code{iconv} library routine.
+
+@item -fworking-directory
+@opindex fworking-directory
+@opindex fno-working-directory
+Enable generation of linemarkers in the preprocessor output that will
+let the compiler know the current working directory at the time of
+preprocessing. When this option is enabled, the preprocessor will
+emit, after the initial linemarker, a second linemarker with the
+current working directory followed by two slashes. GCC will use this
+directory, when it's present in the preprocessed input, as the
+directory emitted as the current working directory in some debugging
+information formats. This option is implicitly enabled if debugging
+information is enabled, but this can be inhibited with the negated
+form @option{-fno-working-directory}. If the @option{-P} flag is
+present in the command line, this option has no effect, since no
+@code{#line} directives are emitted whatsoever.
+
@item -fno-show-column
@opindex fno-show-column
Do not print column numbers in diagnostics. This may be necessary if
@@ -506,9 +577,9 @@ preprocessor, including predefined macros. This gives you a way of
finding out what is predefined in your version of the preprocessor.
Assuming you have no file @file{foo.h}, the command
-@example
+@smallexample
touch foo.h; cpp -dM foo.h
-@end example
+@end smallexample
@noindent
will show all the predefined macros.
@@ -616,7 +687,9 @@ execution, and report the final form of the include path.
@opindex H
Print the name of each header file used, in addition to other normal
activities. Each name is indented to show how deep in the
-@samp{#include} stack it is.
+@samp{#include} stack it is. Precompiled header files are also
+printed, even if they are found to be invalid; an invalid precompiled
+header file is printed with @samp{...x} and a valid one with @samp{...!} .
@item -version
@itemx --version
diff --git a/contrib/gcc/doc/extend.texi b/contrib/gcc/doc/extend.texi
index f2aca2abd81f..3785ceefb1e2 100644
--- a/contrib/gcc/doc/extend.texi
+++ b/contrib/gcc/doc/extend.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 1988,1989,1992,1993,1994,1996,1998,1999,2000,2001,2002, 2003
+@c Copyright (C) 1988,1989,1992,1993,1994,1996,1998,1999,2000,2001,2002,2003,2004
@c Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -253,7 +253,7 @@ The @code{register} specifier affects code generation only in these ways:
@itemize @bullet
@item
-When used as part of the register variable extension, see
+When used as part of the register variable extension, see
@ref{Explicit Reg Vars}.
@item
@@ -424,7 +424,7 @@ extensions, accepted by GCC in C89 mode and in C++.
@menu
* Statement Exprs:: Putting statements and declarations inside expressions.
-* Local Labels:: Labels local to a statement-expression.
+* Local Labels:: Labels local to a block.
* Labels as Values:: Getting pointers to labels, and computed gotos.
* Nested Functions:: As in Algol and Pascal, lexical scoping of functions.
* Constructing Calls:: Dispatching a call to another function.
@@ -494,12 +494,12 @@ Recall that a compound statement is a sequence of statements surrounded
by braces; in this construct, parentheses go around the braces. For
example:
-@example
+@smallexample
(@{ int y = foo (); int z;
if (y > 0) z = y;
else z = - y;
z; @})
-@end example
+@end smallexample
@noindent
is a valid (though slightly more complex than necessary) expression
@@ -516,21 +516,21 @@ that they evaluate each operand exactly once). For example, the
``maximum'' function is commonly defined as a macro in standard C as
follows:
-@example
+@smallexample
#define max(a,b) ((a) > (b) ? (a) : (b))
-@end example
+@end smallexample
@noindent
@cindex side effects, macro argument
But this definition computes either @var{a} or @var{b} twice, with bad
results if the operand has side effects. In GNU C, if you know the
-type of the operands (here let's assume @code{int}), you can define
+type of the operands (here taken as @code{int}), you can define
the macro safely as follows:
-@example
+@smallexample
#define maxint(a,b) \
(@{int _a = (a), _b = (b); _a > _b ? _a : _b; @})
-@end example
+@end smallexample
Embedded statements are not allowed in constant expressions, such as
the value of an enumeration constant, the width of a bit-field, or
@@ -539,32 +539,46 @@ the initial value of a static variable.
If you don't know the type of the operand, you can still do this, but you
must use @code{typeof} (@pxref{Typeof}).
-Statement expressions are not supported fully in G++, and their fate
-there is unclear. (It is possible that they will become fully supported
-at some point, or that they will be deprecated, or that the bugs that
-are present will continue to exist indefinitely.) Presently, statement
-expressions do not work well as default arguments.
+In G++, the result value of a statement expression undergoes array and
+function pointer decay, and is returned by value to the enclosing
+expression. For instance, if @code{A} is a class, then
-In addition, there are semantic issues with statement-expressions in
-C++. If you try to use statement-expressions instead of inline
-functions in C++, you may be surprised at the way object destruction is
-handled. For example:
+@smallexample
+ A a;
-@example
-#define foo(a) (@{int b = (a); b + 3; @})
-@end example
+ (@{a;@}).Foo ()
+@end smallexample
@noindent
-does not work the same way as:
+will construct a temporary @code{A} object to hold the result of the
+statement expression, and that will be used to invoke @code{Foo}.
+Therefore the @code{this} pointer observed by @code{Foo} will not be the
+address of @code{a}.
+
+Any temporaries created within a statement within a statement expression
+will be destroyed at the statement's end. This makes statement
+expressions inside macros slightly different from function calls. In
+the latter case temporaries introduced during argument evaluation will
+be destroyed at the end of the statement that includes the function
+call. In the statement expression case they will be destroyed during
+the statement expression. For instance,
-@example
-inline int foo(int a) @{ int b = a; return b + 3; @}
-@end example
+@smallexample
+#define macro(a) (@{__typeof__(a) b = (a); b + 3; @})
+template<typename T> T function(T a) @{ T b = a; return b + 3; @}
+
+void foo ()
+@{
+ macro (X ());
+ function (X ());
+@}
+@end smallexample
@noindent
-In particular, if the expression passed into @code{foo} involves the
-creation of temporaries, the destructors for those temporaries will be
-run earlier in the case of the macro than in the case of the function.
+will have different places where temporaries are destroyed. For the
+@code{macro} case, the temporary @code{X} will be destroyed just after
+the initialization of @code{b}. In the @code{function} case that
+temporary will be destroyed when the function returns.
These considerations mean that it is probably a bad idea to use
statement-expressions of this form in header files that are designed to
@@ -577,41 +591,58 @@ bug.)
@cindex local labels
@cindex macros, local labels
-Each statement expression is a scope in which @dfn{local labels} can be
-declared. A local label is simply an identifier; you can jump to it
-with an ordinary @code{goto} statement, but only from within the
-statement expression it belongs to.
+GCC allows you to declare @dfn{local labels} in any nested block
+scope. A local label is just like an ordinary label, but you can
+only reference it (with a @code{goto} statement, or by taking its
+address) within the block in which it was declared.
A local label declaration looks like this:
-@example
+@smallexample
__label__ @var{label};
-@end example
+@end smallexample
@noindent
or
-@example
+@smallexample
__label__ @var{label1}, @var{label2}, /* @r{@dots{}} */;
-@end example
+@end smallexample
-Local label declarations must come at the beginning of the statement
-expression, right after the @samp{(@{}, before any ordinary
-declarations.
+Local label declarations must come at the beginning of the block,
+before any ordinary declarations or statements.
The label declaration defines the label @emph{name}, but does not define
the label itself. You must do this in the usual way, with
@code{@var{label}:}, within the statements of the statement expression.
-The local label feature is useful because statement expressions are
-often used in macros. If the macro contains nested loops, a @code{goto}
-can be useful for breaking out of them. However, an ordinary label
-whose scope is the whole function cannot be used: if the macro can be
-expanded several times in one function, the label will be multiply
-defined in that function. A local label avoids this problem. For
-example:
+The local label feature is useful for complex macros. If a macro
+contains nested loops, a @code{goto} can be useful for breaking out of
+them. However, an ordinary label whose scope is the whole function
+cannot be used: if the macro can be expanded several times in one
+function, the label will be multiply defined in that function. A
+local label avoids this problem. For example:
-@example
+@smallexample
+#define SEARCH(value, array, target) \
+do @{ \
+ __label__ found; \
+ typeof (target) _SEARCH_target = (target); \
+ typeof (*(array)) *_SEARCH_array = (array); \
+ int i, j; \
+ int value; \
+ for (i = 0; i < max; i++) \
+ for (j = 0; j < max; j++) \
+ if (_SEARCH_array[i][j] == _SEARCH_target) \
+ @{ (value) = i; goto found; @} \
+ (value) = -1; \
+ found:; \
+@} while (0)
+@end smallexample
+
+This could also be written using a statement-expression:
+
+@smallexample
#define SEARCH(array, target) \
(@{ \
__label__ found; \
@@ -627,7 +658,10 @@ example:
found: \
value; \
@})
-@end example
+@end smallexample
+
+Local label declarations also make the labels they declare visible to
+nested functions, if there are any. @xref{Nested Functions}, for details.
@node Labels as Values
@section Labels as Values
@@ -641,11 +675,11 @@ You can get the address of a label defined in the current function
value has type @code{void *}. This value is a constant and can be used
wherever a constant of that type is valid. For example:
-@example
+@smallexample
void *ptr;
/* @r{@dots{}} */
ptr = &&foo;
-@end example
+@end smallexample
To use these values, you need to be able to jump to one. This is done
with the computed goto statement@footnote{The analogous feature in
@@ -653,9 +687,9 @@ Fortran is called an assigned goto, but that name seems inappropriate in
C, where one can do more than simply store label addresses in label
variables.}, @code{goto *@var{exp};}. For example,
-@example
+@smallexample
goto *ptr;
-@end example
+@end smallexample
@noindent
Any expression of type @code{void *} is allowed.
@@ -663,15 +697,15 @@ Any expression of type @code{void *} is allowed.
One way of using these constants is in initializing a static array that
will serve as a jump table:
-@example
+@smallexample
static void *array[] = @{ &&foo, &&bar, &&hack @};
-@end example
+@end smallexample
Then you can select a label with indexing, like this:
-@example
+@smallexample
goto *array[i];
-@end example
+@end smallexample
@noindent
Note that this does not check whether the subscript is in bounds---array
@@ -693,11 +727,11 @@ never pass it as an argument.
An alternate way to write the above example is
-@example
+@smallexample
static const int array[] = @{ &&foo - &&foo, &&bar - &&foo,
&&hack - &&foo @};
goto *(&&foo + array[i]);
-@end example
+@end smallexample
@noindent
This is more friendly to code living in shared libraries, as it reduces
@@ -715,7 +749,7 @@ A @dfn{nested function} is a function defined inside another function.
name is local to the block where it is defined. For example, here we
define a nested function named @code{square}, and call it twice:
-@example
+@smallexample
@group
foo (double a, double b)
@{
@@ -724,14 +758,14 @@ foo (double a, double b)
return square (a) + square (b);
@}
@end group
-@end example
+@end smallexample
The nested function can access all the variables of the containing
function that are visible at the point of its definition. This is
called @dfn{lexical scoping}. For example, here we show a nested
function which uses an inherited variable named @code{offset}:
-@example
+@smallexample
@group
bar (int *array, int offset, int size)
@{
@@ -743,7 +777,7 @@ bar (int *array, int offset, int size)
/* @r{@dots{}} */ access (array, i) /* @r{@dots{}} */
@}
@end group
-@end example
+@end smallexample
Nested function definitions are permitted within functions in the places
where variable definitions are allowed; that is, in any block, before
@@ -752,7 +786,7 @@ the first statement in the block.
It is possible to call the nested function from outside the scope of its
name by storing its address or passing the address to another function:
-@example
+@smallexample
hack (int *array, int size)
@{
void store (int index, int value)
@@ -760,7 +794,7 @@ hack (int *array, int size)
intermediate (store, size);
@}
-@end example
+@end smallexample
Here, the function @code{intermediate} receives the address of
@code{store} as an argument. If @code{intermediate} calls @code{store},
@@ -788,7 +822,7 @@ function (@pxref{Local Labels}). Such a jump returns instantly to the
containing function, exiting the nested function which did the
@code{goto} and any intermediate functions as well. Here is an example:
-@example
+@smallexample
@group
bar (int *array, int offset, int size)
@{
@@ -812,14 +846,14 @@ bar (int *array, int offset, int size)
return -1;
@}
@end group
-@end example
+@end smallexample
A nested function always has internal linkage. Declaring one with
@code{extern} is erroneous. If you need to declare the nested function
before its definition, use @code{auto} (which is otherwise meaningless
for function declarations).
-@example
+@smallexample
bar (int *array, int offset, int size)
@{
__label__ failure;
@@ -833,7 +867,7 @@ bar (int *array, int offset, int size)
@}
/* @r{@dots{}} */
@}
-@end example
+@end smallexample
@node Constructing Calls
@section Constructing Function Calls
@@ -850,6 +884,11 @@ and later return that value, without knowing what data type
the function tried to return (as long as your caller expects
that data type).
+However, these built-in functions may interact badly with some
+sophisticated features or other extensions of the language. It
+is, therefore, not recommended to use them outside very simple
+functions acting as mere forwarders for their arguments.
+
@deftypefn {Built-in Function} {void *} __builtin_apply_args ()
This built-in function returns a pointer to data
describing how to perform a call with the same arguments as were passed
@@ -899,9 +938,9 @@ construct acts semantically like a type name defined with @code{typedef}.
There are two ways of writing the argument to @code{typeof}: with an
expression or with a type. Here is an example with an expression:
-@example
+@smallexample
typeof (x[0](1))
-@end example
+@end smallexample
@noindent
This assumes that @code{x} is an array of pointers to functions;
@@ -909,9 +948,9 @@ the type described is that of the values of the functions.
Here is an example with a typename as the argument:
-@example
+@smallexample
typeof (int *)
-@end example
+@end smallexample
@noindent
Here the type described is that of pointers to @code{int}.
@@ -929,12 +968,12 @@ statements-within-expressions feature. Here is how the two together can
be used to define a safe ``maximum'' macro that operates on any
arithmetic type and evaluates each of its arguments exactly once:
-@example
+@smallexample
#define max(a,b) \
(@{ typeof (a) _a = (a); \
typeof (b) _b = (b); \
_a > _b ? _a : _b; @})
-@end example
+@end smallexample
@cindex underscores in variables in macros
@cindex @samp{_} in variables in macros
@@ -956,45 +995,45 @@ Some more examples of the use of @code{typeof}:
@item
This declares @code{y} with the type of what @code{x} points to.
-@example
+@smallexample
typeof (*x) y;
-@end example
+@end smallexample
@item
This declares @code{y} as an array of such values.
-@example
+@smallexample
typeof (*x) y[4];
-@end example
+@end smallexample
@item
This declares @code{y} as an array of pointers to characters:
-@example
+@smallexample
typeof (typeof (char *)[4]) y;
-@end example
+@end smallexample
@noindent
It is equivalent to the following traditional C declaration:
-@example
+@smallexample
char *y[4];
-@end example
+@end smallexample
To see the meaning of the declaration using @code{typeof}, and why it
-might be a useful way to write, let's rewrite it with these macros:
+might be a useful way to write, rewrite it with these macros:
-@example
+@smallexample
#define pointer(T) typeof(T *)
#define array(T, N) typeof(T [N])
-@end example
+@end smallexample
@noindent
Now the declaration can be rewritten this way:
-@example
+@smallexample
array (pointer (char), 4) y;
-@end example
+@end smallexample
@noindent
Thus, @code{array (pointer (char), 4)} is the type of arrays of 4
@@ -1004,9 +1043,9 @@ pointers to @code{char}.
@emph{Compatibility Note:} In addition to @code{typeof}, GCC 2 supported
a more limited extension which permitted one to write
-@example
+@smallexample
typedef @var{T} = @var{expr};
-@end example
+@end smallexample
@noindent
with the effect of declaring @var{T} to have the type of the expression
@@ -1014,9 +1053,9 @@ with the effect of declaring @var{T} to have the type of the expression
3.0 and 3.2 will crash; 3.2.1 and later give an error). Code which
relies on it should be rewritten to use @code{typeof}:
-@example
+@smallexample
typedef typeof(@var{expr}) @var{T};
-@end example
+@end smallexample
@noindent
This will work with all versions of GCC@.
@@ -1035,39 +1074,41 @@ This will work with all versions of GCC@.
Compound expressions, conditional expressions and casts are allowed as
lvalues provided their operands are lvalues. This means that you can take
-their addresses or store values into them.
+their addresses or store values into them. All these extensions are
+deprecated.
-Standard C++ allows compound expressions and conditional expressions as
-lvalues, and permits casts to reference type, so use of this extension
-is deprecated for C++ code.
+Standard C++ allows compound expressions and conditional expressions
+as lvalues, and permits casts to reference type, so use of this
+extension is not supported for C++ code.
For example, a compound expression can be assigned, provided the last
expression in the sequence is an lvalue. These two expressions are
equivalent:
-@example
+@smallexample
(a, b) += 5
a, (b += 5)
-@end example
+@end smallexample
Similarly, the address of the compound expression can be taken. These two
expressions are equivalent:
-@example
+@smallexample
&(a, b)
a, &b
-@end example
+@end smallexample
A conditional expression is a valid lvalue if its type is not void and the
true and false branches are both valid lvalues. For example, these two
expressions are equivalent:
-@example
+@smallexample
(a ? b : c) = 5
(a ? b = 5 : (c = 5))
-@end example
+@end smallexample
-A cast is a valid lvalue if its operand is an lvalue. A simple
+A cast is a valid lvalue if its operand is an lvalue. This extension
+is deprecated. A simple
assignment whose left-hand side is a cast works by converting the
right-hand side first to the specified type, then to the type of the
inner left-hand side expression. After this is stored, the value is
@@ -1075,20 +1116,20 @@ converted back to the specified type to become the value of the
assignment. Thus, if @code{a} has type @code{char *}, the following two
expressions are equivalent:
-@example
+@smallexample
(int)a = 5
(int)(a = (char *)(int)5)
-@end example
+@end smallexample
An assignment-with-arithmetic operation such as @samp{+=} applied to a cast
performs the arithmetic using the type resulting from the cast, and then
continues as in the previous case. Therefore, these two expressions are
equivalent:
-@example
+@smallexample
(int)a += 5
(int)(a = (char *)(int) ((int)a + 5))
-@end example
+@end smallexample
You cannot take the address of an lvalue cast, because the use of its
address would not work out coherently. Suppose that @code{&(int)f} were
@@ -1096,9 +1137,9 @@ permitted, where @code{f} has type @code{float}. Then the following
statement would try to store an integer bit-pattern where a floating
point number belongs:
-@example
+@smallexample
*&(int)f = 1;
-@end example
+@end smallexample
This is quite different from what @code{(int)f = 1} would do---that
would convert 1 to floating point and store it. Rather than cause this
@@ -1121,9 +1162,9 @@ expression.
Therefore, the expression
-@example
+@smallexample
x ? : y
-@end example
+@end smallexample
@noindent
has the value of @code{x} if that is nonzero; otherwise, the value of
@@ -1131,9 +1172,9 @@ has the value of @code{x} if that is nonzero; otherwise, the value of
This example is perfectly equivalent to
-@example
+@smallexample
x ? x : y
-@end example
+@end smallexample
@cindex side effect in ?:
@cindex ?: side effect
@@ -1271,7 +1312,7 @@ Zero-length arrays are allowed in GNU C@. They are very useful as the
last element of a structure which is really a header for a variable-length
object:
-@example
+@smallexample
struct line @{
int length;
char contents[0];
@@ -1280,7 +1321,7 @@ struct line @{
struct line *thisline = (struct line *)
malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
-@end example
+@end smallexample
In ISO C90, you would have to give @code{contents} a length of 1, which
means either you waste space or complicate the argument to @code{malloc}.
@@ -1324,7 +1365,7 @@ structure followed by an array of sufficient size to contain the data.
I.e.@: in the following, @code{f1} is constructed as if it were declared
like @code{f2}.
-@example
+@smallexample
struct f1 @{
int x; int y[];
@} f1 = @{ 1, @{ 2, 3, 4 @} @};
@@ -1332,7 +1373,7 @@ struct f1 @{
struct f2 @{
struct f1 f1; int data[3];
@} f2 = @{ @{ 1 @}, @{ 2, 3, 4 @} @};
-@end example
+@end smallexample
@noindent
The convenience of this extension is that @code{f1} has the desired
@@ -1348,7 +1389,7 @@ with initialization of deeply nested arrays, we simply disallow any
non-empty initialization except when the structure is the top-level
object. For example:
-@example
+@smallexample
struct foo @{ int x; int y[]; @};
struct bar @{ struct foo z; @};
@@ -1356,7 +1397,7 @@ struct foo a = @{ 1, @{ 2, 3, 4 @} @}; // @r{Valid.}
struct bar b = @{ @{ 1, @{ 2, 3, 4 @} @} @}; // @r{Invalid.}
struct bar c = @{ @{ 1, @{ @} @} @}; // @r{Valid.}
struct foo d[1] = @{ @{ 1 @{ 2, 3, 4 @} @} @}; // @r{Invalid.}
-@end example
+@end smallexample
@node Empty Structures
@section Structures With No Members
@@ -1365,10 +1406,10 @@ struct foo d[1] = @{ @{ 1 @{ 2, 3, 4 @} @} @}; // @r{Invalid.}
GCC permits a C structure to have no members:
-@example
+@smallexample
struct empty @{
@};
-@end example
+@end smallexample
The structure will have size zero. In C++, empty structures are part
of the language. G++ treats empty structures as if they had a single
@@ -1389,7 +1430,7 @@ a constant expression. The storage is allocated at the point of
declaration and deallocated when the brace-level is exited. For
example:
-@example
+@smallexample
FILE *
concat_fopen (char *s1, char *s2, char *mode)
@{
@@ -1398,7 +1439,7 @@ concat_fopen (char *s1, char *s2, char *mode)
strcat (str, s2);
return fopen (str, mode);
@}
-@end example
+@end smallexample
@cindex scope of a variable length array
@cindex variable-length array scope
@@ -1422,13 +1463,13 @@ will also deallocate anything more recently allocated with @code{alloca}.)
You can also use variable-length arrays as arguments to functions:
-@example
+@smallexample
struct entry
tester (int len, char data[len][len])
@{
/* @r{@dots{}} */
@}
-@end example
+@end smallexample
The length of an array is computed once when the storage is allocated
and is remembered for the scope of the array in case you access it with
@@ -1437,13 +1478,13 @@ and is remembered for the scope of the array in case you access it with
If you want to pass the array first and the length afterward, you can
use a forward declaration in the parameter list---another GNU extension.
-@example
+@smallexample
struct entry
tester (int len; char data[len][len], int len)
@{
/* @r{@dots{}} */
@}
-@end example
+@end smallexample
@cindex parameter forward declaration
The @samp{int len} before the semicolon is a @dfn{parameter forward
@@ -1483,9 +1524,9 @@ GCC has long supported variadic macros, and used a different syntax that
allowed you to give a name to the variable arguments just like any other
argument. Here is an example:
-@example
+@smallexample
#define debug(format, args...) fprintf (stderr, format, args)
-@end example
+@end smallexample
This is in all ways equivalent to the ISO C example above, but arguably
more readable and descriptive.
@@ -1498,9 +1539,9 @@ entirely; but you are allowed to pass an empty argument. For example,
this invocation is invalid in ISO C, because there is no comma after
the string:
-@example
+@smallexample
debug ("A message")
-@end example
+@end smallexample
GNU CPP permits you to completely omit the variable arguments in this
way. In the above examples, the compiler would complain, though since
@@ -1551,7 +1592,7 @@ subscripted in C89 mode, though otherwise they do not decay to
pointers outside C99 mode. For example,
this is valid in GNU C though not valid in C89:
-@example
+@smallexample
@group
struct foo @{int a[4];@};
@@ -1562,7 +1603,7 @@ bar (int index)
return f().a[index];
@}
@end group
-@end example
+@end smallexample
@node Pointer Arith
@section Arithmetic on @code{void}- and Function-Pointers
@@ -1591,13 +1632,13 @@ As in standard C++ and ISO C99, the elements of an aggregate initializer for an
automatic variable are not required to be constant expressions in GNU C@.
Here is an example of an initializer with run-time varying elements:
-@example
+@smallexample
foo (float f, float g)
@{
float beat_freqs[2] = @{ f-g, f+g @};
/* @r{@dots{}} */
@}
-@end example
+@end smallexample
@node Compound Literals
@section Compound Literals
@@ -1617,26 +1658,26 @@ compound literals in C89 mode and in C++.
Usually, the specified type is a structure. Assume that
@code{struct foo} and @code{structure} are declared as shown:
-@example
+@smallexample
struct foo @{int a; char b[2];@} structure;
-@end example
+@end smallexample
@noindent
Here is an example of constructing a @code{struct foo} with a compound literal:
-@example
+@smallexample
structure = ((struct foo) @{x + y, 'a', 0@});
-@end example
+@end smallexample
@noindent
This is equivalent to writing the following:
-@example
+@smallexample
@{
struct foo temp = @{x + y, 'a', 0@};
structure = temp;
@}
-@end example
+@end smallexample
You can also construct an array. If all the elements of the compound literal
are (made up of) simple constant expressions, suitable for use in
@@ -1644,9 +1685,9 @@ initializers of objects of static storage duration, then the compound
literal can be coerced to a pointer to its first element and used in
such an initializer, as shown here:
-@example
+@smallexample
char **foo = (char *[]) @{ "x", "y", "z" @};
-@end example
+@end smallexample
Compound literals for scalar types and union types are is
also allowed, but then the compound literal is equivalent
@@ -1661,19 +1702,19 @@ The initializer list of the compound literal must be constant.
If the object being initialized has array type of unknown size, the size is
determined by compound literal size.
-@example
+@smallexample
static struct foo x = (struct foo) @{1, 'a', 'b'@};
static int y[] = (int []) @{1, 2, 3@};
static int z[] = (int [3]) @{1@};
-@end example
+@end smallexample
@noindent
The above lines are equivalent to the following:
-@example
+@smallexample
static struct foo x = @{1, 'a', 'b'@};
static int y[] = @{1, 2, 3@};
static int z[] = @{1, 0, 0@};
-@end example
+@end smallexample
@node Designated Inits
@section Designated Initializers
@@ -1694,16 +1735,16 @@ implemented in GNU C++.
To specify an array index, write
@samp{[@var{index}] =} before the element value. For example,
-@example
+@smallexample
int a[6] = @{ [4] = 29, [2] = 15 @};
-@end example
+@end smallexample
@noindent
is equivalent to
-@example
+@smallexample
int a[6] = @{ 0, 0, 15, 0, 29, 0 @};
-@end example
+@end smallexample
@noindent
The index values must be constant expressions, even if the array being
@@ -1717,9 +1758,9 @@ To initialize a range of elements to the same value, write
@samp{[@var{first} ... @var{last}] = @var{value}}. This is a GNU
extension. For example,
-@example
+@smallexample
int widths[] = @{ [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 @};
-@end example
+@end smallexample
@noindent
If the value in it has side-effects, the side-effects will happen only once,
@@ -1733,30 +1774,30 @@ In a structure initializer, specify the name of a field to initialize
with @samp{.@var{fieldname} =} before the element value. For example,
given the following structure,
-@example
+@smallexample
struct point @{ int x, y; @};
-@end example
+@end smallexample
@noindent
the following initialization
-@example
+@smallexample
struct point p = @{ .y = yvalue, .x = xvalue @};
-@end example
+@end smallexample
@noindent
is equivalent to
-@example
+@smallexample
struct point p = @{ xvalue, yvalue @};
-@end example
+@end smallexample
Another syntax which has the same meaning, obsolete since GCC 2.5, is
@samp{@var{fieldname}:}, as shown here:
-@example
+@smallexample
struct point p = @{ y: yvalue, x: xvalue @};
-@end example
+@end smallexample
@cindex designators
The @samp{[@var{index}]} or @samp{.@var{fieldname}} is known as a
@@ -1764,11 +1805,11 @@ The @samp{[@var{index}]} or @samp{.@var{fieldname}} is known as a
syntax) when initializing a union, to specify which element of the union
should be used. For example,
-@example
+@smallexample
union foo @{ int i; double d; @};
union foo f = @{ .d = 4 @};
-@end example
+@end smallexample
@noindent
will convert 4 to a @code{double} to store it in the union using
@@ -1781,26 +1822,26 @@ initialization of successive elements. Each initializer element that
does not have a designator applies to the next consecutive element of the
array or structure. For example,
-@example
+@smallexample
int a[6] = @{ [1] = v1, v2, [4] = v4 @};
-@end example
+@end smallexample
@noindent
is equivalent to
-@example
+@smallexample
int a[6] = @{ 0, v1, v2, 0, v4, 0 @};
-@end example
+@end smallexample
Labeling the elements of an array initializer is especially useful
when the indices are characters or belong to an @code{enum} type.
For example:
-@example
+@smallexample
int whitespace[256]
= @{ [' '] = 1, ['\t'] = 1, ['\h'] = 1,
['\f'] = 1, ['\n'] = 1, ['\r'] = 1 @};
-@end example
+@end smallexample
@cindex designator lists
You can also write a series of @samp{.@var{fieldname}} and
@@ -1817,7 +1858,7 @@ struct point ptarray[10] = @{ [2].y = yv2, [2].x = xv2, [0].x = xv0 @};
If the same field is initialized multiple times, it will have value from
the last initialization. If any such overridden initialization has
side-effect, it is unspecified whether the side-effect happens or not.
-Currently, gcc will discard them and issue a warning.
+Currently, GCC will discard them and issue a warning.
@node Case Ranges
@section Case Ranges
@@ -1827,9 +1868,9 @@ Currently, gcc will discard them and issue a warning.
You can specify a range of consecutive values in a single @code{case} label,
like this:
-@example
+@smallexample
case @var{low} ... @var{high}:
-@end example
+@end smallexample
@noindent
This has the same effect as the proper number of individual @code{case}
@@ -1837,24 +1878,24 @@ labels, one for each integer value from @var{low} to @var{high}, inclusive.
This feature is especially useful for ranges of ASCII character codes:
-@example
+@smallexample
case 'A' ... 'Z':
-@end example
+@end smallexample
@strong{Be careful:} Write spaces around the @code{...}, for otherwise
it may be parsed wrong when you use it with integer values. For example,
write this:
-@example
+@smallexample
case 1 ... 5:
-@end example
+@end smallexample
@noindent
rather than this:
-@example
+@smallexample
case 1...5:
-@end example
+@end smallexample
@node Cast to Union
@section Cast to a Union Type
@@ -1870,11 +1911,11 @@ normal casts. (@xref{Compound Literals}.)
The types that may be cast to the union type are those of the members
of the union. Thus, given the following union and variables:
-@example
+@smallexample
union foo @{ int i; double d; @};
int x;
double y;
-@end example
+@end smallexample
@noindent
both @code{x} and @code{y} can be cast to type @code{union foo}.
@@ -1882,20 +1923,20 @@ both @code{x} and @code{y} can be cast to type @code{union foo}.
Using the cast as the right-hand side of an assignment to a variable of
union type is equivalent to storing in a member of the union:
-@example
+@smallexample
union foo u;
/* @r{@dots{}} */
u = (union foo) x @equiv{} u.i = x
u = (union foo) y @equiv{} u.d = y
-@end example
+@end smallexample
You can also use the union cast as a function argument:
-@example
+@smallexample
void hack (union foo);
/* @r{@dots{}} */
hack ((union foo) x);
-@end example
+@end smallexample
@node Mixed Declarations
@section Mixed Declarations and Code
@@ -1907,12 +1948,12 @@ ISO C99 and ISO C++ allow declarations and code to be freely mixed
within compound statements. As an extension, GCC also allows this in
C89 mode. For example, you could do:
-@example
+@smallexample
int i;
/* @r{@dots{}} */
i++;
int j = i + 2;
-@end example
+@end smallexample
Each identifier is visible from where it is declared until the end of
the enclosing block.
@@ -1946,9 +1987,9 @@ attributes are currently defined for functions on all targets:
@code{format}, @code{format_arg}, @code{no_instrument_function},
@code{section}, @code{constructor}, @code{destructor}, @code{used},
@code{unused}, @code{deprecated}, @code{weak}, @code{malloc},
-@code{alias}, and @code{nonnull}. Several other attributes are defined
-for functions on particular target systems. Other attributes, including
-@code{section} are supported for variables declarations
+@code{alias}, @code{warn_unused_result} and @code{nonnull}. Several other
+attributes are defined for functions on particular target systems. Other
+attributes, including @code{section} are supported for variables declarations
(@pxref{Variable Attributes}) and for types (@pxref{Type Attributes}).
You may also specify attributes with @samp{__} preceding and following
@@ -1986,6 +2027,10 @@ would happen if @code{fatal} ever did return. This makes slightly
better code. More importantly, it helps avoid spurious warnings of
uninitialized variables.
+The @code{noreturn} keyword does not affect the exceptional path when that
+applies: a @code{noreturn}-marked function may still return to the caller
+by throwing an exception.
+
Do not assume that registers saved by the calling function are
restored before calling the @code{noreturn} function.
@@ -2248,8 +2293,7 @@ These attributes are not currently implemented for Objective-C@.
@item unused
This attribute, attached to a function, means that the function is meant
to be possibly unused. GCC will not produce a warning for this
-function. GNU C++ does not currently support this attribute as
-definitions without parameters are valid in C++.
+function.
@cindex @code{used} attribute.
@item used
@@ -2279,6 +2323,26 @@ results in a warning on line 3 but not line 2.
The @code{deprecated} attribute can also be used for variables and
types (@pxref{Variable Attributes}, @pxref{Type Attributes}.)
+@item warn_unused_result
+@cindex @code{warn_unused_result} attribute
+The @code{warn_unused_result} attribute causes a warning to be emitted
+if a caller of the function with this attribute does not use its
+return value. This is useful for functions where not checking
+the result is either a security problem or always a bug, such as
+@code{realloc}.
+
+@smallexample
+int fn () __attribute__ ((warn_unused_result));
+int foo ()
+@{
+ if (fn () < 0) return -1;
+ fn ();
+ return 0;
+@}
+@end smallexample
+
+results in warning on line 5.
+
@item weak
@cindex @code{weak} attribute
The @code{weak} attribute causes the declaration to be emitted as a weak
@@ -2291,9 +2355,14 @@ and linker.
@item malloc
@cindex @code{malloc} attribute
The @code{malloc} attribute is used to tell the compiler that a function
-may be treated as if it were the malloc function. The compiler assumes
-that calls to malloc result in pointers that cannot alias anything.
+may be treated as if any non-@code{NULL} pointer it returns cannot
+alias any other pointer valid when the function returns.
This will often improve optimization.
+Standard functions with this property include @code{malloc} and
+@code{calloc}. @code{realloc}-like functions have this property as
+long as the old pointer is never referred to (including comparing it
+to the new pointer) after the function returns a non-@code{NULL}
+value.
@item alias ("@var{target}")
@cindex @code{alias} attribute
@@ -2325,7 +2394,7 @@ See the ELF gABI for complete details, but the short story is:
@table @dfn
@item default
-Default visibility is the normal case for ELF. This value is
+Default visibility is the normal case for ELF. This value is
available for the visibility attribute to override other options
that may change the assumed visibility of symbols.
@@ -2343,11 +2412,11 @@ by another module.
@item internal
Internal visibility is like hidden visibility, but with additional
processor specific semantics. Unless otherwise specified by the psABI,
-gcc defines internal visibility to mean that the function is @emph{never}
+GCC defines internal visibility to mean that the function is @emph{never}
called from another module. Note that hidden symbols, while they cannot
be referenced directly by other modules, can be referenced indirectly via
function pointers. By indicating that a symbol cannot be called from
-outside the module, gcc may for instance omit the load of a PIC register
+outside the module, GCC may for instance omit the load of a PIC register
since it is known that the calling function loaded the correct value.
@end table
@@ -2378,6 +2447,13 @@ On the Intel 386, the @code{stdcall} attribute causes the compiler to
assume that the called function will pop off the stack space used to
pass arguments, unless it takes a variable number of arguments.
+@item fastcall
+@cindex functions that pop the argument stack on the 386
+On the Intel 386, the @code{fastcall} attribute causes the compiler to
+pass the first two arguments in the registers ECX and EDX. Subsequent
+arguments are passed on the stack. The called function will pop the
+arguments off the stack. If the number of arguments is variable all
+arguments are pushed on the stack.
@item cdecl
@cindex functions that do pop the argument stack on the 386
@@ -2412,24 +2488,24 @@ instruction directly.
@item function_vector
@cindex calling functions through the function vector on the H8/300 processors
-Use this attribute on the H8/300 and H8/300H to indicate that the specified
+Use this attribute on the H8/300, H8/300H, and H8S to indicate that the specified
function should be called through the function vector. Calling a
function through the function vector will reduce code size, however;
the function vector has a limited size (maximum 128 entries on the H8/300
-and 64 entries on the H8/300H) and shares space with the interrupt vector.
+and 64 entries on the H8/300H and H8S) and shares space with the interrupt vector.
You must use GAS and GLD from GNU binutils version 2.7 or later for
this attribute to work correctly.
@item interrupt
@cindex interrupt handler functions
-Use this attribute on the ARM, AVR, M32R/D and Xstormy16 ports to indicate
+Use this attribute on the ARM, AVR, C4x, M32R/D and Xstormy16 ports to indicate
that the specified function is an interrupt handler. The compiler will
generate function entry and exit sequences suitable for use in an
interrupt handler when this attribute is present.
-Note, interrupt handlers for the H8/300, H8/300H and SH processors can
-be specified via the @code{interrupt_handler} attribute.
+Note, interrupt handlers for the m68k, H8/300, H8/300H, H8S, and SH processors
+can be specified via the @code{interrupt_handler} attribute.
Note, on the AVR, interrupts will be enabled inside the function.
@@ -2443,9 +2519,9 @@ void f () __attribute__ ((interrupt ("IRQ")));
Permissible values for this parameter are: IRQ, FIQ, SWI, ABORT and UNDEF@.
@item interrupt_handler
-@cindex interrupt handler functions on the H8/300 and SH processors
-Use this attribute on the H8/300, H8/300H and SH to indicate that the
-specified function is an interrupt handler. The compiler will generate
+@cindex interrupt handler functions on the m68k, H8/300 and SH processors
+Use this attribute on the m68k, H8/300, H8/300H, H8S, and SH to indicate that
+the specified function is an interrupt handler. The compiler will generate
function entry and exit sequences suitable for use in an interrupt
handler when this attribute is present.
@@ -2462,13 +2538,13 @@ void f () __attribute__ ((interrupt_handler,
@end smallexample
@item trap_exit
-Use this attribute on the SH for an @code{interrupt_handle} to return using
+Use this attribute on the SH for an @code{interrupt_handler} to return using
@code{trapa} instead of @code{rte}. This attribute expects an integer
argument specifying the trap number to be used.
@item eightbit_data
-@cindex eight bit data on the H8/300 and H8/300H
-Use this attribute on the H8/300 and H8/300H to indicate that the specified
+@cindex eight bit data on the H8/300, H8/300H, and H8S
+Use this attribute on the H8/300, H8/300H, and H8S to indicate that the specified
variable should be placed into the eight bit data section.
The compiler will generate more efficient code for certain operations
on data in the eight bit data area. Note the eight bit data area is limited to
@@ -2478,13 +2554,19 @@ You must use GAS and GLD from GNU binutils version 2.7 or later for
this attribute to work correctly.
@item tiny_data
-@cindex tiny data section on the H8/300H
-Use this attribute on the H8/300H to indicate that the specified
+@cindex tiny data section on the H8/300H and H8S
+Use this attribute on the H8/300H and H8S to indicate that the specified
variable should be placed into the tiny data section.
The compiler will generate more efficient code for loads and stores
on data in the tiny data section. Note the tiny data area is limited to
slightly under 32kbytes of data.
+@item saveall
+@cindex save all registers on the H8/300, H8/300H, and H8S
+Use this attribute on the H8/300, H8/300H, and H8S to indicate that
+all registers except the stack pointer should be saved in the prologue
+regardless of whether they are used or not.
+
@item signal
@cindex signal handler functions on the AVR processors
Use this attribute on the AVR to indicate that the specified
@@ -2494,16 +2576,18 @@ attribute is present. Interrupts will be disabled inside the function.
@item naked
@cindex function without a prologue/epilogue code
-Use this attribute on the ARM, AVR and IP2K ports to indicate that the
+Use this attribute on the ARM, AVR, C4x and IP2K ports to indicate that the
specified function does not need prologue/epilogue sequences generated by
the compiler. It is up to the programmer to provide these sequences.
@item model (@var{model-name})
@cindex function addressability on the M32R/D
-Use this attribute on the M32R/D to set the addressability of an object,
-and of the code generated for a function.
-The identifier @var{model-name} is one of @code{small}, @code{medium},
-or @code{large}, representing each of the code models.
+@cindex variable addressability on the IA-64
+
+On the M32R/D, use this attribute to set the addressability of an
+object, and of the code generated for a function. The identifier
+@var{model-name} is one of @code{small}, @code{medium}, or
+@code{large}, representing each of the code models.
Small model objects live in the lower 16MB of memory (so that their
addresses can be loaded with the @code{ld24} instruction), and are
@@ -2518,6 +2602,14 @@ compiler will generate @code{seth/add3} instructions to load their addresses),
and may not be reachable with the @code{bl} instruction (the compiler will
generate the much slower @code{seth/add3/jl} instruction sequence).
+On IA-64, use this attribute to set the addressability of an object.
+At present, the only supported identifier for @var{model-name} is
+@code{small}, indicating addressability via ``small'' (22-bit)
+addresses (so that their addresses can be loaded with the @code{addl}
+instruction). Caveat: such addressing is by definition not position
+independent and hence this attribute must not be used for objects
+defined by shared libraries.
+
@item far
@cindex functions which handle memory bank switching
On 68HC11 and 68HC12 the @code{far} attribute causes the compiler to
@@ -2544,9 +2636,9 @@ option.
@item dllimport
@cindex @code{__declspec(dllimport)}
-On Windows targets, the @code{dllimport} attribute causes the compiler
+On Microsoft Windows targets, the @code{dllimport} attribute causes the compiler
to reference a function or variable via a global pointer to a pointer
-that is set up by the Windows dll library. The pointer name is formed by
+that is set up by the Microsoft Windows dll library. The pointer name is formed by
combining @code{_imp__} and the function or variable name. The attribute
implies @code{extern} storage.
@@ -2555,7 +2647,7 @@ attribute is applied to a symbol @emph{definition}, an error is reported.
If a symbol previously declared @code{dllimport} is later defined, the
attribute is ignored in subsequent references, and a warning is emitted.
The attribute is also overridden by a subsequent declaration as
-@code{dllexport}.
+@code{dllexport}.
When applied to C++ classes, the attribute marks non-inlined
member functions and static data members as imports. However, the
@@ -2564,14 +2656,14 @@ using thunks.
On cygwin, mingw and arm-pe targets, @code{__declspec(dllimport)} is
recognized as a synonym for @code{__attribute__ ((dllimport))} for
-compatibility with other Windows compilers.
+compatibility with other Microsoft Windows compilers.
The use of the @code{dllimport} attribute on functions is not necessary,
but provides a small performance benefit by eliminating a thunk in the
dll. The use of the @code{dllimport} attribute on imported variables was
required on older versions of GNU ld, but can now be avoided by passing
the @option{--enable-auto-import} switch to ld. As with functions, using
-the attribute for a variable eliminates a thunk in the dll.
+the attribute for a variable eliminates a thunk in the dll.
One drawback to using this attribute is that a pointer to a function or
variable marked as dllimport cannot be used as a constant address. The
@@ -2580,7 +2672,7 @@ attribute can be disabled for functions by setting the
@item dllexport
@cindex @code{__declspec(dllexport)}
-On Windows targets the @code{dllexport} attribute causes the compiler to
+On Microsoft Windows targets the @code{dllexport} attribute causes the compiler to
provide a global pointer to a pointer in a dll, so that it can be
referenced with the @code{dllimport} attribute. The pointer name is
formed by combining @code{_imp__} and the function or variable name.
@@ -2597,7 +2689,7 @@ out-of-class.
On cygwin, mingw and arm-pe targets, @code{__declspec(dllexport)} is
recognized as a synonym for @code{__attribute__ ((dllexport))} for
-compatibility with other Windows compilers.
+compatibility with other Microsoft Windows compilers.
Alternative methods for including the symbol in the dll's export table
are to use a .def file with an @code{EXPORTS} section or, with GNU ld,
@@ -2698,14 +2790,18 @@ with the list being a single string constant.
An @dfn{attribute specifier list} is a sequence of one or more attribute
specifiers, not separated by any other tokens.
-An attribute specifier list may appear after the colon following a
+In GNU C, an attribute specifier list may appear after the colon following a
label, other than a @code{case} or @code{default} label. The only
attribute it makes sense to use after a label is @code{unused}. This
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.
+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.
An attribute specifier list may appear as part of a @code{struct},
@code{union} or @code{enum} specifier. It may go either immediately
@@ -2878,7 +2974,7 @@ to the function type.
GNU C extends ISO C to allow a function prototype to override a later
old-style non-prototype definition. Consider the following example:
-@example
+@smallexample
/* @r{Use prototypes unless the compiler is old-fashioned.} */
#ifdef __STDC__
#define P(x) x
@@ -2896,7 +2992,7 @@ isroot (x) /* ??? lossage here ??? */
@{
return x == 0;
@}
-@end example
+@end smallexample
Suppose the type @code{uid_t} happens to be @code{short}. ISO C does
not allow this example, because subword arguments in old-style
@@ -2914,7 +3010,7 @@ by a later old-style definition if the former type is the same as the
latter type before promotion. Thus in GNU C the above example is
equivalent to the following:
-@example
+@smallexample
int isroot (uid_t);
int
@@ -2922,7 +3018,7 @@ isroot (uid_t x)
@{
return x == 0;
@}
-@end example
+@end smallexample
@noindent
GNU C++ does not support old-style function definitions, so this
@@ -2983,9 +3079,9 @@ any minimum alignment specified with GCC's @code{__attribute__}
extension (@pxref{Variable Attributes}). For example, after this
declaration:
-@example
+@smallexample
struct foo @{ int x; char y; @} foo1;
-@end example
+@end smallexample
@noindent
the value of @code{__alignof__ (foo1.y)} is 1, even though its actual
@@ -3100,7 +3196,7 @@ The @code{common} attribute requests GCC to place a variable in
``common'' storage. The @code{nocommon} attribute requests the
opposite -- to allocate space for it directly.
-These attributes override the default chosen by the
+These attributes override the default chosen by the
@option{-fno-common} and @option{-fcommon} flags respectively.
@item deprecated
@@ -3145,13 +3241,13 @@ and one bit for a field, unless you specify a larger value with the
Here is a structure in which the field @code{x} is packed, so that it
immediately follows @code{a}:
-@example
+@smallexample
struct foo
@{
char a;
int x[2] __attribute__ ((packed));
@};
-@end example
+@end smallexample
@item section ("@var{section-name}")
@cindex @code{section} variable attribute
@@ -3203,7 +3299,7 @@ section, consider using the facilities of the linker instead.
@item shared
@cindex @code{shared} variable attribute
-On Windows, in addition to putting variable definitions in a named
+On Microsoft Windows, in addition to putting variable definitions in a named
section, the section can also be shared among all running copies of an
executable or DLL@. For example, this small program defines shared data
by putting it in a named section @code{shared} and marking the section
@@ -3226,7 +3322,7 @@ You may only use the @code{shared} attribute along with @code{section}
attribute with a fully initialized global definition because of the way
linkers work. See @code{section} attribute for more information.
-The @code{shared} attribute is only available on Windows@.
+The @code{shared} attribute is only available on Microsoft Windows@.
@item tls_model ("@var{tls_model}")
@cindex @code{tls_model} attribute
@@ -3284,6 +3380,19 @@ the @code{int}.
@item weak
The @code{weak} attribute is described in @xref{Function Attributes}.
+@item dllimport
+The @code{dllimport} attribute is described in @xref{Function Attributes}.
+
+@item dlexport
+The @code{dllexport} attribute is described in @xref{Function Attributes}.
+
+@end table
+
+@subsection M32R/D Variable Attributes
+
+One attribute is currently defined for the M32R/D.
+
+@table @code
@item model (@var{model-name})
@cindex variable addressability on the M32R/D
Use this attribute on the M32R/D to set the addressability of an object.
@@ -3296,19 +3405,30 @@ addresses can be loaded with the @code{ld24} instruction).
Medium and large model objects may live anywhere in the 32-bit address space
(the compiler will generate @code{seth/add3} instructions to load their
addresses).
+@end table
-@item dllimport
-The @code{dllimport} attribute is described in @xref{Function Attributes}.
+@subsection i386 Variable Attributes
-@item dlexport
-The @code{dllexport} attribute is described in @xref{Function Attributes}.
+Two attributes are currently defined for i386 configurations:
+@code{ms_struct} and @code{gcc_struct}
+@table @code
+@item ms_struct
+@itemx gcc_struct
+@cindex @code{ms_struct} attribute
+@cindex @code{gcc_struct} attribute
+
+If @code{packed} is used on a structure, or if bit-fields are used
+it may be that the Microsoft ABI packs them differently
+than GCC would normally pack them. Particularly when moving packed
+data between functions compiled with GCC and the native Microsoft compiler
+(either via function call or as data in a file), it may be necessary to access
+either format.
+
+Currently @option{-m[no-]ms-bitfields} is provided for the Microsoft Windows X86
+compilers to match the native Microsoft compiler.
@end table
-To specify multiple attributes, separate them by commas within the
-double parentheses: for example, @samp{__attribute__ ((aligned (16),
-packed))}.
-
@node Type Attributes
@section Specifying Attributes of Types
@cindex attribute of types
@@ -3422,9 +3542,10 @@ in an @code{__attribute__} will still only provide you with 8 byte
alignment. See your linker documentation for further information.
@item packed
-This attribute, attached to an @code{enum}, @code{struct}, or
-@code{union} type definition, specifies that the minimum required memory
-be used to represent the type.
+This attribute, attached to @code{struct} or @code{union} type
+definition, specifies that each member of the structure or union is
+placed to minimize the memory required. When attached to an @code{enum}
+definition, it indicates that the smallest integral type should be used.
@opindex fshort-enums
Specifying this attribute for @code{struct} and @code{union} types is
@@ -3433,9 +3554,29 @@ structure or union members. Specifying the @option{-fshort-enums}
flag on the line is equivalent to specifying the @code{packed}
attribute on all @code{enum} definitions.
-You may only specify this attribute after a closing curly brace on an
-@code{enum} definition, not in a @code{typedef} declaration, unless that
-declaration also contains the definition of the @code{enum}.
+In the following example @code{struct my_packed_struct}'s members are
+packed closely together, but the internal layout of its @code{s} member
+is not packed -- to do that, @code{struct my_unpacked_struct} would need to
+be packed too.
+
+@smallexample
+struct my_unpacked_struct
+ @{
+ char c;
+ int i;
+ @};
+
+struct my_packed_struct __attribute__ ((__packed__))
+ @{
+ char c;
+ int i;
+ struct my_unpacked_struct s;
+ @};
+@end smallexample
+
+You may only specify this attribute on the definition of a @code{enum},
+@code{struct} or @code{union}, not on a @code{typedef} which does not
+also define the enumerated type, structure or union.
@item transparent_union
This attribute, attached to a @code{union} type definition, indicates
@@ -3481,19 +3622,19 @@ This interface allows either @code{int *} or @code{union wait *}
arguments to be passed, using the @code{int *} calling convention.
The program can call @code{wait} with arguments of either type:
-@example
+@smallexample
int w1 () @{ int w; return wait (&w); @}
int w2 () @{ union wait w; return wait (&w); @}
-@end example
+@end smallexample
With this interface, @code{wait}'s implementation might look like this:
-@example
+@smallexample
pid_t wait (wait_status_ptr_t p)
@{
return waitpid (-1, p.__ip, 0);
@}
-@end example
+@end smallexample
@item unused
When attached to a type (including a @code{union} or a @code{struct}),
@@ -3562,6 +3703,26 @@ If you replaced @code{short_a} with @code{short} in the variable
declaration, the above program would abort when compiled with
@option{-fstrict-aliasing}, which is on by default at @option{-O2} or
above in recent GCC versions.
+
+@subsection i386 Type Attributes
+
+Two attributes are currently defined for i386 configurations:
+@code{ms_struct} and @code{gcc_struct}
+
+@item ms_struct
+@itemx gcc_struct
+@cindex @code{ms_struct}
+@cindex @code{gcc_struct}
+
+If @code{packed} is used on a structure, or if bit-fields are used
+it may be that the Microsoft ABI packs them differently
+than GCC would normally pack them. Particularly when moving packed
+data between functions compiled with GCC and the native Microsoft compiler
+(either via function call or as data in a file), it may be necessary to access
+either format.
+
+Currently @option{-m[no-]ms-bitfields} is provided for the Microsoft Windows X86
+compilers to match the native Microsoft compiler.
@end table
To specify multiple attributes, separate them by commas within the
@@ -3593,13 +3754,13 @@ the ISO C99 standard requires.
To declare a function inline, use the @code{inline} keyword in its
declaration, like this:
-@example
+@smallexample
inline int
inc (int *a)
@{
(*a)++;
@}
-@end example
+@end smallexample
(If you are writing a header file to be included in ISO C programs, write
@code{__inline__} instead of @code{inline}. @xref{Alternate Keywords}.)
@@ -3674,10 +3835,10 @@ that will implement the C99 semantics, though it does not do so yet.)
GCC does not inline any functions when not optimizing unless you specify
the @samp{always_inline} attribute for the function, like this:
-@example
+@smallexample
/* Prototype. */
inline void foo (const char) __attribute__((always_inline));
-@end example
+@end smallexample
@node Extended Asm
@section Assembler Instructions with C Expression Operands
@@ -3697,9 +3858,9 @@ each operand.
For example, here is how to use the 68881's @code{fsinx} instruction:
-@example
+@smallexample
asm ("fsinx %1,%0" : "=f" (result) : "f" (angle));
-@end example
+@end smallexample
@noindent
Here @code{angle} is the C expression for the input operand while
@@ -3729,11 +3890,11 @@ assembler code using @code{%[@var{name}]} instead of a percentage sign
followed by the operand number. Using named operands the above example
could look like:
-@example
+@smallexample
asm ("fsinx %[angle],%[output]"
: [output] "=f" (result)
: [angle] "f" (angle));
-@end example
+@end smallexample
@noindent
Note that the symbolic operand names have no relation whatsoever to
@@ -3757,22 +3918,23 @@ The ordinary output operands must be write-only; GCC will assume that
the values in these operands before the instruction are dead and need
not be generated. Extended asm supports input-output or read-write
operands. Use the constraint character @samp{+} to indicate such an
-operand and list it with the output operands.
-
-When the constraints for the read-write operand (or the operand in which
-only some of the bits are to be changed) allows a register, you may, as
-an alternative, logically split its function into two separate operands,
-one input operand and one write-only output operand. The connection
-between them is expressed by constraints which say they need to be in
-the same location when the instruction executes. You can use the same C
-expression for both operands, or different expressions. For example,
-here we write the (fictitious) @samp{combine} instruction with
-@code{bar} as its read-only source operand and @code{foo} as its
-read-write destination:
+operand and list it with the output operands. You should only use
+read-write operands when the constraints for the operand (or the
+operand in which only some of the bits are to be changed) allow a
+register.
+
+You may, as an alternative, logically split its function into two
+separate operands, one input operand and one write-only output
+operand. The connection between them is expressed by constraints
+which say they need to be in the same location when the instruction
+executes. You can use the same C expression for both operands, or
+different expressions. For example, here we write the (fictitious)
+@samp{combine} instruction with @code{bar} as its read-only source
+operand and @code{foo} as its read-write destination:
-@example
+@smallexample
asm ("combine %2,%0" : "=r" (foo) : "0" (foo), "g" (bar));
-@end example
+@end smallexample
@noindent
The constraint @samp{"0"} for operand 1 says that it must occupy the
@@ -3785,9 +3947,9 @@ of both operands is not enough to guarantee that they will be in the
same place in the generated assembler code. The following would not
work reliably:
-@example
+@smallexample
asm ("combine %2,%0" : "=r" (foo) : "r" (foo), "g" (bar));
-@end example
+@end smallexample
Various optimizations or reloading could cause operands 0 and 1 to be in
different registers; GCC knows no reason not to do so. For example, the
@@ -3800,23 +3962,23 @@ code, the result will not work, but GCC can't tell that.
As of GCC version 3.1, one may write @code{[@var{name}]} instead of
the operand number for a matching constraint. For example:
-@example
+@smallexample
asm ("cmoveq %1,%2,%[result]"
: [result] "=r"(result)
: "r" (test), "r"(new), "[result]"(old));
-@end example
+@end smallexample
Some instructions clobber specific hard registers. To describe this,
write a third colon after the input operands, followed by the names of
the clobbered hard registers (given as strings). Here is a realistic
example for the VAX:
-@example
+@smallexample
asm volatile ("movc3 %0,%1,%2"
: /* no outputs */
: "g" (from), "g" (to), "g" (count)
: "r0", "r1", "r2", "r3", "r4", "r5");
-@end example
+@end smallexample
You may not write a clobber description in a way that overlaps with an
input or output operand. For example, you may not have an operand
@@ -3844,13 +4006,35 @@ represents the condition codes as a specific hardware register;
condition code is handled differently, and specifying @samp{cc} has no
effect. But it is valid no matter what the machine.
-If your assembler instruction modifies memory in an unpredictable
+If your assembler instructions access memory in an unpredictable
fashion, add @samp{memory} to the list of clobbered registers. This
-will cause GCC to not keep memory values cached in registers across
-the assembler instruction. You will also want to add the
-@code{volatile} keyword if the memory affected is not listed in the
-inputs or outputs of the @code{asm}, as the @samp{memory} clobber does
-not count as a side-effect of the @code{asm}.
+will cause GCC to not keep memory values cached in registers across the
+assembler instruction and not optimize stores or loads to that memory.
+You will also want to add the @code{volatile} keyword if the memory
+affected is not listed in the inputs or outputs of the @code{asm}, as
+the @samp{memory} clobber does not count as a side-effect of the
+@code{asm}. If you know how large the accessed memory is, you can add
+it as input or output but if this is not known, you should add
+@samp{memory}. As an example, if you access ten bytes of a string, you
+can use a memory input like:
+
+@example
+@{"m"( (@{ struct @{ char x[10]; @} *p = (void *)ptr ; *p; @}) )@}.
+@end example
+
+Note that in the following example the memory input is necessary,
+otherwise GCC might optimize the store to @code{x} away:
+@example
+int foo ()
+@{
+ int x = 42;
+ int *y = &x;
+ int result;
+ asm ("magic stuff accessing an 'int' pointed to by '%1'"
+ "=&d" (r) : "a" (y), "m" (*y));
+ return result;
+@}
+@end example
You can put multiple assembler instructions together in a single
@code{asm} template, separated by the characters normally used in assembly
@@ -3865,12 +4049,12 @@ read and write the clobbered registers as many times as you like. Here
is an example of multiple instructions in a template; it assumes the
subroutine @code{_foo} accepts arguments in registers 9 and 10:
-@example
+@smallexample
asm ("movl %0,r9\n\tmovl %1,r10\n\tcall _foo"
: /* no outputs */
: "g" (from), "g" (to)
: "r9", "r10");
-@end example
+@end smallexample
Unless an output operand has the @samp{&} constraint modifier, GCC
may allocate it in the same register as an unrelated input operand, on
@@ -3883,11 +4067,11 @@ If you want to test the condition code produced by an assembler
instruction, you must include a branch and a label in the @code{asm}
construct, as follows:
-@example
+@smallexample
asm ("clr %0\n\tfrob %1\n\tbeq 0f\n\tmov #1,%0\n0:"
: "g" (result)
: "g" (input));
-@end example
+@end smallexample
@noindent
This assumes your assembler supports local labels, as the GNU assembler
@@ -3902,12 +4086,12 @@ optimize.
Usually the most convenient way to use these @code{asm} instructions is to
encapsulate them in macros that look like functions. For example,
-@example
+@smallexample
#define sin(x) \
(@{ double __value, __arg = (x); \
asm ("fsinx %1,%0": "=f" (__value): "f" (__arg)); \
__value; @})
-@end example
+@end smallexample
@noindent
Here the variable @code{__arg} is used to make sure that the instruction
@@ -3936,13 +4120,13 @@ You can prevent an @code{asm} instruction from being deleted, moved
significantly, or combined, by writing the keyword @code{volatile} after
the @code{asm}. For example:
-@example
+@smallexample
#define get_and_set_priority(new) \
(@{ int __old; \
asm volatile ("get_and_set_priority %0, %1" \
: "=g" (__old) : "g" (new)); \
__old; @})
-@end example
+@end smallexample
@noindent
If you write an @code{asm} instruction with no outputs, GCC will know
@@ -3956,10 +4140,10 @@ prove that control-flow will never reach the location of the
instruction.) In addition, GCC will not reschedule instructions
across a volatile @code{asm} instruction. For example:
-@example
+@smallexample
*(volatile int *)addr = foo;
asm volatile ("eieio" : : );
-@end example
+@end smallexample
@noindent
Assume @code{addr} contains the address of a memory mapped device
@@ -3997,6 +4181,26 @@ If you are writing a header file that should be includable in ISO C
programs, write @code{__asm__} instead of @code{asm}. @xref{Alternate
Keywords}.
+@subsection Size of an @code{asm}
+
+Some targets require that GCC track the size of each instruction used in
+order to generate correct code. Because the final length of an
+@code{asm} is only known by the assembler, GCC must make an estimate as
+to how big it will be. The estimate is formed by counting the number of
+statements in the pattern of the @code{asm} and multiplying that by the
+length of the longest instruction on that processor. Statements in the
+@code{asm} are identified by newline characters and whatever statement
+separator characters are supported by the assembler; on most processors
+this is the `@code{;}' character.
+
+Normally, GCC's estimate is perfectly adequate to ensure that correct
+code is generated, but it is possible to confuse the compiler if you use
+pseudo instructions or assembler macros that expand into multiple real
+instructions or if you use assembler directives that expand to more
+space in the object file than would be needed for a single instruction.
+If this happens then the assembler will produce a diagnostic saying that
+a label is unreachable.
+
@subsection i386 floating point asm operands
There are several rules on the usage of stack-like regs in
@@ -4027,9 +4231,9 @@ the reg-stack than any input that is not implicitly popped.
It is possible that if an input dies in an insn, reload might
use the input reg for an output reload. Consider this example:
-@example
+@smallexample
asm ("foo" : "=t" (a) : "f" (b));
-@end example
+@end smallexample
This asm says that input B is not popped by the asm, and that
the asm pushes a result onto the reg-stack, i.e., the stack is one
@@ -4042,9 +4246,9 @@ constraints must use the @code{&} earlyclobber.
The asm above would be written as
-@example
+@smallexample
asm ("foo" : "=&t" (a) : "f" (b));
-@end example
+@end smallexample
@item
Some operands need to be in particular places on the stack. All
@@ -4075,17 +4279,17 @@ unrelated to the inputs and outputs.
Here are a couple of reasonable asms to want to write. This asm
takes one input, which is internally popped, and produces two outputs.
-@example
+@smallexample
asm ("fsincos" : "=t" (cos), "=u" (sin) : "0" (inp));
-@end example
+@end smallexample
This asm takes two inputs, which are popped by the @code{fyl2xp1} opcode,
and replaces them with one output. The user must code the @code{st(1)}
clobber for reg-stack.c to know that @code{fyl2xp1} pops both inputs.
-@example
+@smallexample
asm ("fyl2xp1" : "=t" (result) : "0" (x), "u" (y) : "st(1)");
-@end example
+@end smallexample
@include md.texi
@@ -4099,9 +4303,9 @@ You can specify the name to be used in the assembler code for a C
function or variable by writing the @code{asm} (or @code{__asm__})
keyword after the declarator as follows:
-@example
+@smallexample
int foo asm ("myfoo") = 2;
-@end example
+@end smallexample
@noindent
This specifies that the name to be used for the variable @code{foo} in
@@ -4123,13 +4327,13 @@ You cannot use @code{asm} in this way in a function @emph{definition}; but
you can get the same effect by writing a declaration for the function
before its definition and putting @code{asm} there, like this:
-@example
+@smallexample
extern func () asm ("FUNC");
func (x, y)
int x, y;
/* @r{@dots{}} */
-@end example
+@end smallexample
It is up to you to make sure that the assembler names you choose do not
conflict with any other assembler symbols. Also, you must not use a
@@ -4182,9 +4386,9 @@ specified for that operand in the @code{asm}.)
You can define a global register variable in GNU C like this:
-@example
+@smallexample
register int *foo asm ("a5");
-@end example
+@end smallexample
@noindent
Here @code{a5} is the name of the register which should be used. Choose a
@@ -4281,9 +4485,9 @@ Of course, it will not do to use more than a few of those.
You can define a local register variable with a specified register
like this:
-@example
+@smallexample
register int *foo asm ("a5");
-@end example
+@end smallexample
@noindent
Here @code{a5} is the name of the register which should be used. Note
@@ -4340,11 +4544,11 @@ Other C compilers won't accept these alternative keywords; if you want to
compile with another compiler, you can define the alternate keywords as
macros to replace them with the customary keywords. It looks like this:
-@example
+@smallexample
#ifndef __GNUC__
#define __asm__ asm
#endif
-@end example
+@end smallexample
@findex __extension__
@opindex pedantic
@@ -4373,18 +4577,47 @@ This extension is not supported by GNU C++.
@node Function Names
@section Function Names as Strings
+@cindex @code{__func__} identifier
@cindex @code{__FUNCTION__} identifier
@cindex @code{__PRETTY_FUNCTION__} identifier
-@cindex @code{__func__} identifier
-GCC predefines two magic identifiers to hold the name of the current
-function. The identifier @code{__FUNCTION__} holds the name of the function
-as it appears in the source. The identifier @code{__PRETTY_FUNCTION__}
-holds the name of the function pretty printed in a language specific
-fashion.
+GCC provides three magic variables which hold the name of the current
+function, as a string. The first of these is @code{__func__}, which
+is part of the C99 standard:
+
+@display
+The identifier @code{__func__} is implicitly declared by the translator
+as if, immediately following the opening brace of each function
+definition, the declaration
+
+@smallexample
+static const char __func__[] = "function-name";
+@end smallexample
+
+appeared, where function-name is the name of the lexically-enclosing
+function. This name is the unadorned name of the function.
+@end display
-These names are always the same in a C function, but in a C++ function
-they may be different. For example, this program:
+@code{__FUNCTION__} is another name for @code{__func__}. Older
+versions of GCC recognize only this name. However, it is not
+standardized. For maximum portability, we recommend you use
+@code{__func__}, but provide a fallback definition with the
+preprocessor:
+
+@smallexample
+#if __STDC_VERSION__ < 199901L
+# if __GNUC__ >= 2
+# define __func__ __FUNCTION__
+# else
+# define __func__ "<unknown>"
+# endif
+#endif
+@end smallexample
+
+In C, @code{__PRETTY_FUNCTION__} is yet another name for
+@code{__func__}. However, in C++, @code{__PRETTY_FUNCTION__} contains
+the type signature of the function as well as its bare name. For
+example, this program:
@smallexample
extern "C" @{
@@ -4393,7 +4626,7 @@ extern int printf (char *, ...);
class a @{
public:
- sub (int i)
+ void sub (int i)
@{
printf ("__FUNCTION__ = %s\n", __FUNCTION__);
printf ("__PRETTY_FUNCTION__ = %s\n", __PRETTY_FUNCTION__);
@@ -4414,46 +4647,16 @@ gives this output:
@smallexample
__FUNCTION__ = sub
-__PRETTY_FUNCTION__ = int a::sub (int)
+__PRETTY_FUNCTION__ = void a::sub(int)
@end smallexample
-The compiler automagically replaces the identifiers with a string
-literal containing the appropriate name. Thus, they are neither
-preprocessor macros, like @code{__FILE__} and @code{__LINE__}, nor
-variables. This means that they catenate with other string literals, and
-that they can be used to initialize char arrays. For example
-
-@smallexample
-char here[] = "Function " __FUNCTION__ " in " __FILE__;
-@end smallexample
-
-On the other hand, @samp{#ifdef __FUNCTION__} does not have any special
-meaning inside a function, since the preprocessor does not do anything
-special with the identifier @code{__FUNCTION__}.
-
-Note that these semantics are deprecated, and that GCC 3.2 will handle
-@code{__FUNCTION__} and @code{__PRETTY_FUNCTION__} the same way as
-@code{__func__}. @code{__func__} is defined by the ISO standard C99:
-
-@display
-The identifier @code{__func__} is implicitly declared by the translator
-as if, immediately following the opening brace of each function
-definition, the declaration
-
-@smallexample
-static const char __func__[] = "function-name";
-@end smallexample
-
-appeared, where function-name is the name of the lexically-enclosing
-function. This name is the unadorned name of the function.
-@end display
-
-By this definition, @code{__func__} is a variable, not a string literal.
-In particular, @code{__func__} does not catenate with other string
-literals.
-
-In @code{C++}, @code{__FUNCTION__} and @code{__PRETTY_FUNCTION__} are
-variables, declared in the same way as @code{__func__}.
+These identifiers are not preprocessor macros. In GCC 3.3 and
+earlier, in C only, @code{__FUNCTION__} and @code{__PRETTY_FUNCTION__}
+were treated as string literals; they could be used to initialize
+@code{char} arrays, and they could be concatenated with other string
+literals. GCC 3.4 and later treat them as variables, like
+@code{__func__}. In C++, @code{__FUNCTION__} and
+@code{__PRETTY_FUNCTION__} have always been variables.
@node Return Address
@section Getting the Return or Frame Address of a Function
@@ -4519,9 +4722,9 @@ this way.
The first step in using these extensions is to provide the necessary data
types. This should be done using an appropriate @code{typedef}:
-@example
+@smallexample
typedef int v4si __attribute__ ((mode(V4SI)));
-@end example
+@end smallexample
The base type @code{int} is effectively ignored by the compiler, the
actual properties of the new type @code{v4si} are defined by the
@@ -4546,14 +4749,14 @@ A floating point value, as wide as a DI mode integer, usually 64 bits.
@end table
Specifying a combination that is not valid for the current architecture
-will cause gcc to synthesize the instructions using a narrower mode.
+will cause GCC to synthesize the instructions using a narrower mode.
For example, if you specify a variable of type @code{V4SI} and your
-architecture does not allow for this specific SIMD type, gcc will
+architecture does not allow for this specific SIMD type, GCC will
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}@.
+operations. Currently, GCC will allow using the following operators
+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
@@ -4561,17 +4764,18 @@ example, in the code below, each of the 4 elements in @var{a} will be
added to the corresponding 4 elements in @var{b} and the resulting
vector will be stored in @var{c}.
-@example
+@smallexample
typedef int v4si __attribute__ ((mode(V4SI)));
v4si a, b, c;
c = a + b;
-@end example
+@end smallexample
-Subtraction, multiplication, and division operate in a similar manner.
-Likewise, the result of using the unary minus operator on a vector type
-is a vector whose elements are the negative value of the corresponding
+Subtraction, multiplication, division, and the logical operations
+operate in a similar manner. Likewise, the result of using the unary
+minus or complement operators on a vector type is a vector whose
+elements are the negative or complemented values of the corresponding
elements in the operand.
You can declare variables and use them in function calls and returns, as
@@ -4589,14 +4793,14 @@ of built-in functions that can be used to operate on vectors. For
example, a function to add two vectors and multiply the result by a
third could look like this:
-@example
+@smallexample
v4si f (v4si a, v4si b, v4si c)
@{
v4si tmp = __builtin_addv4si (a, b);
return __builtin_mulv4si (tmp, c);
@}
-@end example
+@end smallexample
@node Other Builtins
@section Other built-in functions provided by GCC
@@ -4607,55 +4811,283 @@ v4si f (v4si a, v4si b, v4si c)
@findex __builtin_islessequal
@findex __builtin_islessgreater
@findex __builtin_isunordered
+@findex _Exit
+@findex _exit
@findex abort
@findex abs
+@findex acos
+@findex acosf
+@findex acosh
+@findex acoshf
+@findex acoshl
+@findex acosl
@findex alloca
+@findex asin
+@findex asinf
+@findex asinh
+@findex asinhf
+@findex asinhl
+@findex asinl
+@findex atan
+@findex atan2
+@findex atan2f
+@findex atan2l
+@findex atanf
+@findex atanh
+@findex atanhf
+@findex atanhl
+@findex atanl
@findex bcmp
@findex bzero
+@findex cabs
+@findex cabsf
+@findex cabsl
+@findex cacos
+@findex cacosf
+@findex cacosh
+@findex cacoshf
+@findex cacoshl
+@findex cacosl
+@findex calloc
+@findex carg
+@findex cargf
+@findex cargl
+@findex casin
+@findex casinf
+@findex casinh
+@findex casinhf
+@findex casinhl
+@findex casinl
+@findex catan
+@findex catanf
+@findex catanh
+@findex catanhf
+@findex catanhl
+@findex catanl
+@findex cbrt
+@findex cbrtf
+@findex cbrtl
+@findex ccos
+@findex ccosf
+@findex ccosh
+@findex ccoshf
+@findex ccoshl
+@findex ccosl
+@findex ceil
+@findex ceilf
+@findex ceill
+@findex cexp
+@findex cexpf
+@findex cexpl
@findex cimag
@findex cimagf
@findex cimagl
@findex conj
@findex conjf
@findex conjl
+@findex copysign
+@findex copysignf
+@findex copysignl
@findex cos
@findex cosf
+@findex cosh
+@findex coshf
+@findex coshl
@findex cosl
+@findex cpow
+@findex cpowf
+@findex cpowl
+@findex cproj
+@findex cprojf
+@findex cprojl
@findex creal
@findex crealf
@findex creall
+@findex csin
+@findex csinf
+@findex csinh
+@findex csinhf
+@findex csinhl
+@findex csinl
+@findex csqrt
+@findex csqrtf
+@findex csqrtl
+@findex ctan
+@findex ctanf
+@findex ctanh
+@findex ctanhf
+@findex ctanhl
+@findex ctanl
+@findex dcgettext
+@findex dgettext
+@findex drem
+@findex dremf
+@findex dreml
+@findex erf
+@findex erfc
+@findex erfcf
+@findex erfcl
+@findex erff
+@findex erfl
@findex exit
-@findex _exit
-@findex _Exit
@findex exp
+@findex exp10
+@findex exp10f
+@findex exp10l
+@findex exp2
+@findex exp2f
+@findex exp2l
@findex expf
@findex expl
+@findex expm1
+@findex expm1f
+@findex expm1l
@findex fabs
@findex fabsf
@findex fabsl
+@findex fdim
+@findex fdimf
+@findex fdiml
@findex ffs
+@findex floor
+@findex floorf
+@findex floorl
+@findex fma
+@findex fmaf
+@findex fmal
+@findex fmax
+@findex fmaxf
+@findex fmaxl
+@findex fmin
+@findex fminf
+@findex fminl
+@findex fmod
+@findex fmodf
+@findex fmodl
@findex fprintf
@findex fprintf_unlocked
@findex fputs
@findex fputs_unlocked
+@findex frexp
+@findex frexpf
+@findex frexpl
+@findex fscanf
+@findex gamma
+@findex gammaf
+@findex gammal
+@findex gettext
+@findex hypot
+@findex hypotf
+@findex hypotl
+@findex ilogb
+@findex ilogbf
+@findex ilogbl
@findex imaxabs
@findex index
+@findex j0
+@findex j0f
+@findex j0l
+@findex j1
+@findex j1f
+@findex j1l
+@findex jn
+@findex jnf
+@findex jnl
@findex labs
+@findex ldexp
+@findex ldexpf
+@findex ldexpl
+@findex lgamma
+@findex lgammaf
+@findex lgammal
@findex llabs
+@findex llrint
+@findex llrintf
+@findex llrintl
+@findex llround
+@findex llroundf
+@findex llroundl
@findex log
+@findex log10
+@findex log10f
+@findex log10l
+@findex log1p
+@findex log1pf
+@findex log1pl
+@findex log2
+@findex log2f
+@findex log2l
+@findex logb
+@findex logbf
+@findex logbl
@findex logf
@findex logl
+@findex lrint
+@findex lrintf
+@findex lrintl
+@findex lround
+@findex lroundf
+@findex lroundl
+@findex malloc
@findex memcmp
@findex memcpy
+@findex mempcpy
@findex memset
+@findex modf
+@findex modff
+@findex modfl
+@findex nearbyint
+@findex nearbyintf
+@findex nearbyintl
+@findex nextafter
+@findex nextafterf
+@findex nextafterl
+@findex nexttoward
+@findex nexttowardf
+@findex nexttowardl
+@findex pow
+@findex pow10
+@findex pow10f
+@findex pow10l
+@findex powf
+@findex powl
@findex printf
@findex printf_unlocked
@findex putchar
@findex puts
+@findex remainder
+@findex remainderf
+@findex remainderl
+@findex remquo
+@findex remquof
+@findex remquol
@findex rindex
-@findex scanf
+@findex rint
+@findex rintf
+@findex rintl
+@findex round
+@findex roundf
+@findex roundl
+@findex scalb
+@findex scalbf
+@findex scalbl
+@findex scalbln
+@findex scalblnf
+@findex scalblnf
+@findex scalbn
+@findex scalbnf
+@findex scanfnl
+@findex significand
+@findex significandf
+@findex significandl
@findex sin
+@findex sincos
+@findex sincosf
+@findex sincosl
@findex sinf
+@findex sinh
+@findex sinhf
+@findex sinhl
@findex sinl
@findex snprintf
@findex sprintf
@@ -4663,11 +5095,15 @@ v4si f (v4si a, v4si b, v4si c)
@findex sqrtf
@findex sqrtl
@findex sscanf
+@findex stpcpy
@findex strcat
@findex strchr
@findex strcmp
@findex strcpy
@findex strcspn
+@findex strdup
+@findex strfmon
+@findex strftime
@findex strlen
@findex strncat
@findex strncmp
@@ -4676,11 +5112,34 @@ v4si f (v4si a, v4si b, v4si c)
@findex strrchr
@findex strspn
@findex strstr
+@findex tan
+@findex tanf
+@findex tanh
+@findex tanhf
+@findex tanhl
+@findex tanl
+@findex tgamma
+@findex tgammaf
+@findex tgammal
+@findex trunc
+@findex truncf
+@findex truncl
+@findex vfprintf
+@findex vfscanf
@findex vprintf
@findex vscanf
@findex vsnprintf
@findex vsprintf
@findex vsscanf
+@findex y0
+@findex y0f
+@findex y0l
+@findex y1
+@findex y1f
+@findex y1l
+@findex yn
+@findex ynf
+@findex ynl
GCC provides a large number of built-in functions other than the ones
mentioned above. Some of these are for internal use in the processing
@@ -4701,47 +5160,102 @@ be emitted.
@opindex ansi
@opindex std
-The functions @code{abort}, @code{exit}, @code{_Exit} and @code{_exit}
-are recognized and presumed not to return, but otherwise are not built
-in. @code{_exit} is not recognized in strict ISO C mode (@option{-ansi},
-@option{-std=c89} or @option{-std=c99}). @code{_Exit} is not recognized in
-strict C89 mode (@option{-ansi} or @option{-std=c89}). All these functions
-have corresponding versions prefixed with @code{__builtin_}, which may be
-used even in strict C89 mode.
-
-Outside strict ISO C mode, the functions @code{alloca}, @code{bcmp},
-@code{bzero}, @code{index}, @code{rindex}, @code{ffs}, @code{fputs_unlocked},
-@code{printf_unlocked} and @code{fprintf_unlocked} may be handled as
-built-in functions. All these functions have corresponding versions
+Outside strict ISO C mode (@option{-ansi}, @option{-std=c89} or
+@option{-std=c99}), the functions
+@code{_exit}, @code{alloca}, @code{bcmp}, @code{bzero},
+@code{dcgettext}, @code{dgettext}, @code{dremf}, @code{dreml},
+@code{drem}, @code{exp10f}, @code{exp10l}, @code{exp10}, @code{ffsll},
+@code{ffsl}, @code{ffs}, @code{fprintf_unlocked}, @code{fputs_unlocked},
+@code{gammaf}, @code{gammal}, @code{gamma}, @code{gettext},
+@code{index}, @code{j0f}, @code{j0l}, @code{j0}, @code{j1f}, @code{j1l},
+@code{j1}, @code{jnf}, @code{jnl}, @code{jn}, @code{mempcpy},
+@code{pow10f}, @code{pow10l}, @code{pow10}, @code{printf_unlocked},
+@code{rindex}, @code{scalbf}, @code{scalbl}, @code{scalb},
+@code{significandf}, @code{significandl}, @code{significand},
+@code{sincosf}, @code{sincosl}, @code{sincos}, @code{stpcpy},
+@code{strdup}, @code{strfmon}, @code{y0f}, @code{y0l}, @code{y0},
+@code{y1f}, @code{y1l}, @code{y1}, @code{ynf}, @code{ynl} and @code{yn}
+may be handled as built-in functions.
+All these functions have corresponding versions
prefixed with @code{__builtin_}, which may be used even in strict C89
mode.
-The ISO C99 functions @code{conj}, @code{conjf}, @code{conjl},
-@code{creal}, @code{crealf}, @code{creall}, @code{cimag}, @code{cimagf},
-@code{cimagl}, @code{imaxabs}, @code{llabs}, @code{snprintf},
-@code{vscanf}, @code{vsnprintf} and @code{vsscanf} are handled as built-in
-functions except in strict ISO C90 mode. There are also built-in
-versions of the ISO C99 functions @code{cosf}, @code{cosl},
-@code{expf}, @code{expl}, @code{fabsf}, @code{fabsl},
-@code{logf}, @code{logl}, @code{sinf}, @code{sinl}, @code{sqrtf}, and
-@code{sqrtl}, that are recognized in any mode since ISO C90 reserves
-these names for the purpose to which ISO C99 puts them. All these
-functions have corresponding versions prefixed with @code{__builtin_}.
-
-The ISO C90 functions @code{abs}, @code{cos}, @code{exp}, @code{fabs},
-@code{fprintf}, @code{fputs}, @code{labs}, @code{log},
-@code{memcmp}, @code{memcpy},
-@code{memset}, @code{printf}, @code{putchar}, @code{puts}, @code{scanf},
-@code{sin}, @code{snprintf}, @code{sprintf}, @code{sqrt}, @code{sscanf},
-@code{strcat},
-@code{strchr}, @code{strcmp}, @code{strcpy}, @code{strcspn},
-@code{strlen}, @code{strncat}, @code{strncmp}, @code{strncpy},
-@code{strpbrk}, @code{strrchr}, @code{strspn}, @code{strstr},
-@code{vprintf} and @code{vsprintf} are all
-recognized as built-in functions unless @option{-fno-builtin} is
-specified (or @option{-fno-builtin-@var{function}} is specified for an
-individual function). All of these functions have corresponding
-versions prefixed with @code{__builtin_}.
+The ISO C99 functions
+@code{_Exit}, @code{acoshf}, @code{acoshl}, @code{acosh}, @code{asinhf},
+@code{asinhl}, @code{asinh}, @code{atanhf}, @code{atanhl}, @code{atanh},
+@code{cabsf}, @code{cabsl}, @code{cabs}, @code{cacosf}, @code{cacoshf},
+@code{cacoshl}, @code{cacosh}, @code{cacosl}, @code{cacos},
+@code{cargf}, @code{cargl}, @code{carg}, @code{casinf}, @code{casinhf},
+@code{casinhl}, @code{casinh}, @code{casinl}, @code{casin},
+@code{catanf}, @code{catanhf}, @code{catanhl}, @code{catanh},
+@code{catanl}, @code{catan}, @code{cbrtf}, @code{cbrtl}, @code{cbrt},
+@code{ccosf}, @code{ccoshf}, @code{ccoshl}, @code{ccosh}, @code{ccosl},
+@code{ccos}, @code{cexpf}, @code{cexpl}, @code{cexp}, @code{cimagf},
+@code{cimagl}, @code{cimag},
+@code{conjf}, @code{conjl}, @code{conj}, @code{copysignf},
+@code{copysignl}, @code{copysign}, @code{cpowf}, @code{cpowl},
+@code{cpow}, @code{cprojf}, @code{cprojl}, @code{cproj}, @code{crealf},
+@code{creall}, @code{creal}, @code{csinf}, @code{csinhf}, @code{csinhl},
+@code{csinh}, @code{csinl}, @code{csin}, @code{csqrtf}, @code{csqrtl},
+@code{csqrt}, @code{ctanf}, @code{ctanhf}, @code{ctanhl}, @code{ctanh},
+@code{ctanl}, @code{ctan}, @code{erfcf}, @code{erfcl}, @code{erfc},
+@code{erff}, @code{erfl}, @code{erf}, @code{exp2f}, @code{exp2l},
+@code{exp2}, @code{expm1f}, @code{expm1l}, @code{expm1}, @code{fdimf},
+@code{fdiml}, @code{fdim}, @code{fmaf}, @code{fmal}, @code{fmaxf},
+@code{fmaxl}, @code{fmax}, @code{fma}, @code{fminf}, @code{fminl},
+@code{fmin}, @code{hypotf}, @code{hypotl}, @code{hypot}, @code{ilogbf},
+@code{ilogbl}, @code{ilogb}, @code{imaxabs}, @code{lgammaf},
+@code{lgammal}, @code{lgamma}, @code{llabs}, @code{llrintf},
+@code{llrintl}, @code{llrint}, @code{llroundf}, @code{llroundl},
+@code{llround}, @code{log1pf}, @code{log1pl}, @code{log1p},
+@code{log2f}, @code{log2l}, @code{log2}, @code{logbf}, @code{logbl},
+@code{logb}, @code{lrintf}, @code{lrintl}, @code{lrint}, @code{lroundf},
+@code{lroundl}, @code{lround}, @code{nearbyintf}, @code{nearbyintl},
+@code{nearbyint}, @code{nextafterf}, @code{nextafterl},
+@code{nextafter}, @code{nexttowardf}, @code{nexttowardl},
+@code{nexttoward}, @code{remainderf}, @code{remainderl},
+@code{remainder}, @code{remquof}, @code{remquol}, @code{remquo},
+@code{rintf}, @code{rintl}, @code{rint}, @code{roundf}, @code{roundl},
+@code{round}, @code{scalblnf}, @code{scalblnl}, @code{scalbln},
+@code{scalbnf}, @code{scalbnl}, @code{scalbn}, @code{snprintf},
+@code{tgammaf}, @code{tgammal}, @code{tgamma}, @code{truncf},
+@code{truncl}, @code{trunc}, @code{vfscanf}, @code{vscanf},
+@code{vsnprintf} and @code{vsscanf}
+are handled as built-in functions
+except in strict ISO C90 mode (@option{-ansi} or @option{-std=c89}).
+
+There are also built-in versions of the ISO C99 functions
+@code{acosf}, @code{acosl}, @code{asinf}, @code{asinl}, @code{atan2f},
+@code{atan2l}, @code{atanf}, @code{atanl}, @code{ceilf}, @code{ceill},
+@code{cosf}, @code{coshf}, @code{coshl}, @code{cosl}, @code{expf},
+@code{expl}, @code{fabsf}, @code{fabsl}, @code{floorf}, @code{floorl},
+@code{fmodf}, @code{fmodl}, @code{frexpf}, @code{frexpl}, @code{ldexpf},
+@code{ldexpl}, @code{log10f}, @code{log10l}, @code{logf}, @code{logl},
+@code{modfl}, @code{modf}, @code{powf}, @code{powl}, @code{sinf},
+@code{sinhf}, @code{sinhl}, @code{sinl}, @code{sqrtf}, @code{sqrtl},
+@code{tanf}, @code{tanhf}, @code{tanhl} and @code{tanl}
+that are recognized in any mode since ISO C90 reserves these names for
+the purpose to which ISO C99 puts them. All these functions have
+corresponding versions prefixed with @code{__builtin_}.
+
+The ISO C90 functions
+@code{abort}, @code{abs}, @code{acos}, @code{asin}, @code{atan2},
+@code{atan}, @code{calloc}, @code{ceil}, @code{cosh}, @code{cos},
+@code{exit}, @code{exp}, @code{fabs}, @code{floor}, @code{fmod},
+@code{fprintf}, @code{fputs}, @code{frexp}, @code{fscanf}, @code{labs},
+@code{ldexp}, @code{log10}, @code{log}, @code{malloc}, @code{memcmp},
+@code{memcpy}, @code{memset}, @code{modf}, @code{pow}, @code{printf},
+@code{putchar}, @code{puts}, @code{scanf}, @code{sinh}, @code{sin},
+@code{snprintf}, @code{sprintf}, @code{sqrt}, @code{sscanf},
+@code{strcat}, @code{strchr}, @code{strcmp}, @code{strcpy},
+@code{strcspn}, @code{strlen}, @code{strncat}, @code{strncmp},
+@code{strncpy}, @code{strpbrk}, @code{strrchr}, @code{strspn},
+@code{strstr}, @code{tanh}, @code{tan}, @code{vfprintf}, @code{vprintf}
+and @code{vsprintf}
+are all recognized as built-in functions unless
+@option{-fno-builtin} is specified (or @option{-fno-builtin-@var{function}}
+is specified for an individual function). All of these functions have
+corresponding versions prefixed with @code{__builtin_}.
GCC provides built-in versions of the ISO C99 floating point comparison
macros that avoid raising exceptions for unordered operands. They have
@@ -4773,8 +5287,10 @@ similarity. Consequently, @code{short *} is not similar to
@code{short **}. Furthermore, two types that are typedefed are
considered compatible if their underlying types are compatible.
-An @code{enum} type is considered to be compatible with another
-@code{enum} type. For example, @code{enum @{foo, bar@}} is similar to
+An @code{enum} type is not considered to be compatible with another
+@code{enum} type even if both are compatible with the same integer
+type; this is what the C standard specifies.
+For example, @code{enum @{foo, bar@}} is not similar to
@code{enum @{hot, dog@}}.
You would typically use this function in code whose execution varies
@@ -5007,7 +5523,7 @@ do not implement, a description of the parsing is in order. The string
is parsed as by @code{strtol}; that is, the base is recognized by
leading @samp{0} or @samp{0x} prefixes. The number parsed is placed
in the significand such that the least significant bit of the number
-is at the least significant bit of the significand. The number is
+is at the least significant bit of the significand. The number is
truncated to fit the significand field provided. The significand is
forced to be a quiet NaN.
@@ -5024,9 +5540,9 @@ Similar to @code{__builtin_nan}, except the return type is @code{long double}.
@end deftypefn
@deftypefn {Built-in Function} double __builtin_nans (const char *str)
-Similar to @code{__builtin_nan}, except the significand is forced
+Similar to @code{__builtin_nan}, except the significand is forced
to be a signaling NaN. The @code{nans} function is proposed by
-@uref{http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/n965.htm,,WG14 N965}.
+@uref{http://www.open-std.org/jtc1/sc22/wg14/www/docs/n965.htm,,WG14 N965}.
@end deftypefn
@deftypefn {Built-in Function} float __builtin_nansf (const char *str)
@@ -5037,6 +5553,81 @@ Similar to @code{__builtin_nans}, except the return type is @code{float}.
Similar to @code{__builtin_nans}, except the return type is @code{long double}.
@end deftypefn
+@deftypefn {Built-in Function} int __builtin_ffs (unsigned int x)
+Returns one plus the index of the least significant 1-bit of @var{x}, or
+if @var{x} is zero, returns zero.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_clz (unsigned int x)
+Returns the number of leading 0-bits in @var{x}, starting at the most
+significant bit position. If @var{x} is 0, the result is undefined.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_ctz (unsigned int x)
+Returns the number of trailing 0-bits in @var{x}, starting at the least
+significant bit position. If @var{x} is 0, the result is undefined.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_popcount (unsigned int x)
+Returns the number of 1-bits in @var{x}.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_parity (unsigned int x)
+Returns the parity of @var{x}, i.@:e. the number of 1-bits in @var{x}
+modulo 2.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_ffsl (unsigned long)
+Similar to @code{__builtin_ffs}, except the argument type is
+@code{unsigned long}.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_clzl (unsigned long)
+Similar to @code{__builtin_clz}, except the argument type is
+@code{unsigned long}.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_ctzl (unsigned long)
+Similar to @code{__builtin_ctz}, except the argument type is
+@code{unsigned long}.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_popcountl (unsigned long)
+Similar to @code{__builtin_popcount}, except the argument type is
+@code{unsigned long}.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_parityl (unsigned long)
+Similar to @code{__builtin_parity}, except the argument type is
+@code{unsigned long}.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_ffsll (unsigned long long)
+Similar to @code{__builtin_ffs}, except the argument type is
+@code{unsigned long long}.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_clzll (unsigned long long)
+Similar to @code{__builtin_clz}, except the argument type is
+@code{unsigned long long}.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_ctzll (unsigned long long)
+Similar to @code{__builtin_ctz}, except the argument type is
+@code{unsigned long long}.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_popcountll (unsigned long long)
+Similar to @code{__builtin_popcount}, except the argument type is
+@code{unsigned long long}.
+@end deftypefn
+
+@deftypefn {Built-in Function} int __builtin_parityll (unsigned long long)
+Similar to @code{__builtin_parity}, except the argument type is
+@code{unsigned long long}.
+@end deftypefn
+
+
@node Target Builtins
@section Built-in Functions Specific to Particular Target Machines
@@ -5046,6 +5637,7 @@ instructions, but allow the compiler to schedule those calls.
@menu
* Alpha Built-in Functions::
+* ARM Built-in Functions::
* X86 Built-in Functions::
* PowerPC AltiVec Built-in Functions::
@end menu
@@ -5059,7 +5651,7 @@ processors, depending on the command-line switches used.
The following built-in functions are always available. They
all generate the machine instruction that is part of the name.
-@example
+@smallexample
long __builtin_alpha_implver (void)
long __builtin_alpha_rpcc (void)
long __builtin_alpha_amask (long)
@@ -5088,14 +5680,14 @@ long __builtin_alpha_mskqh (long, long)
long __builtin_alpha_umulh (long, long)
long __builtin_alpha_zap (long, long)
long __builtin_alpha_zapnot (long, long)
-@end example
+@end smallexample
The following built-in functions are always with @option{-mmax}
or @option{-mcpu=@var{cpu}} where @var{cpu} is @code{pca56} or
later. They all generate the machine instruction that is part
of the name.
-@example
+@smallexample
long __builtin_alpha_pklb (long)
long __builtin_alpha_pkwb (long)
long __builtin_alpha_unpkbl (long)
@@ -5109,28 +5701,175 @@ long __builtin_alpha_maxsb8 (long, long)
long __builtin_alpha_maxuw4 (long, long)
long __builtin_alpha_maxsw4 (long, long)
long __builtin_alpha_perr (long, long)
-@end example
+@end smallexample
The following built-in functions are always with @option{-mcix}
or @option{-mcpu=@var{cpu}} where @var{cpu} is @code{ev67} or
later. They all generate the machine instruction that is part
of the name.
-@example
+@smallexample
long __builtin_alpha_cttz (long)
long __builtin_alpha_ctlz (long)
long __builtin_alpha_ctpop (long)
-@end example
+@end smallexample
The following builtins are available on systems that use the OSF/1
PALcode. Normally they invoke the @code{rduniq} and @code{wruniq}
PAL calls, but when invoked with @option{-mtls-kernel}, they invoke
@code{rdval} and @code{wrval}.
-@example
+@smallexample
void *__builtin_thread_pointer (void)
void __builtin_set_thread_pointer (void *)
-@end example
+@end smallexample
+
+@node ARM Built-in Functions
+@subsection ARM Built-in Functions
+
+These built-in functions are available for the ARM family of
+processors, when the @option{-mcpu=iwmmxt} switch is used:
+
+@smallexample
+typedef int v2si __attribute__ ((vector_size (8)));
+typedef short v4hi __attribute__ ((vector_size (8)));
+typedef char v8qi __attribute__ ((vector_size (8)));
+
+int __builtin_arm_getwcx (int)
+void __builtin_arm_setwcx (int, int)
+int __builtin_arm_textrmsb (v8qi, int)
+int __builtin_arm_textrmsh (v4hi, int)
+int __builtin_arm_textrmsw (v2si, int)
+int __builtin_arm_textrmub (v8qi, int)
+int __builtin_arm_textrmuh (v4hi, int)
+int __builtin_arm_textrmuw (v2si, int)
+v8qi __builtin_arm_tinsrb (v8qi, int)
+v4hi __builtin_arm_tinsrh (v4hi, int)
+v2si __builtin_arm_tinsrw (v2si, int)
+long long __builtin_arm_tmia (long long, int, int)
+long long __builtin_arm_tmiabb (long long, int, int)
+long long __builtin_arm_tmiabt (long long, int, int)
+long long __builtin_arm_tmiaph (long long, int, int)
+long long __builtin_arm_tmiatb (long long, int, int)
+long long __builtin_arm_tmiatt (long long, int, int)
+int __builtin_arm_tmovmskb (v8qi)
+int __builtin_arm_tmovmskh (v4hi)
+int __builtin_arm_tmovmskw (v2si)
+long long __builtin_arm_waccb (v8qi)
+long long __builtin_arm_wacch (v4hi)
+long long __builtin_arm_waccw (v2si)
+v8qi __builtin_arm_waddb (v8qi, v8qi)
+v8qi __builtin_arm_waddbss (v8qi, v8qi)
+v8qi __builtin_arm_waddbus (v8qi, v8qi)
+v4hi __builtin_arm_waddh (v4hi, v4hi)
+v4hi __builtin_arm_waddhss (v4hi, v4hi)
+v4hi __builtin_arm_waddhus (v4hi, v4hi)
+v2si __builtin_arm_waddw (v2si, v2si)
+v2si __builtin_arm_waddwss (v2si, v2si)
+v2si __builtin_arm_waddwus (v2si, v2si)
+v8qi __builtin_arm_walign (v8qi, v8qi, int)
+long long __builtin_arm_wand(long long, long long)
+long long __builtin_arm_wandn (long long, long long)
+v8qi __builtin_arm_wavg2b (v8qi, v8qi)
+v8qi __builtin_arm_wavg2br (v8qi, v8qi)
+v4hi __builtin_arm_wavg2h (v4hi, v4hi)
+v4hi __builtin_arm_wavg2hr (v4hi, v4hi)
+v8qi __builtin_arm_wcmpeqb (v8qi, v8qi)
+v4hi __builtin_arm_wcmpeqh (v4hi, v4hi)
+v2si __builtin_arm_wcmpeqw (v2si, v2si)
+v8qi __builtin_arm_wcmpgtsb (v8qi, v8qi)
+v4hi __builtin_arm_wcmpgtsh (v4hi, v4hi)
+v2si __builtin_arm_wcmpgtsw (v2si, v2si)
+v8qi __builtin_arm_wcmpgtub (v8qi, v8qi)
+v4hi __builtin_arm_wcmpgtuh (v4hi, v4hi)
+v2si __builtin_arm_wcmpgtuw (v2si, v2si)
+long long __builtin_arm_wmacs (long long, v4hi, v4hi)
+long long __builtin_arm_wmacsz (v4hi, v4hi)
+long long __builtin_arm_wmacu (long long, v4hi, v4hi)
+long long __builtin_arm_wmacuz (v4hi, v4hi)
+v4hi __builtin_arm_wmadds (v4hi, v4hi)
+v4hi __builtin_arm_wmaddu (v4hi, v4hi)
+v8qi __builtin_arm_wmaxsb (v8qi, v8qi)
+v4hi __builtin_arm_wmaxsh (v4hi, v4hi)
+v2si __builtin_arm_wmaxsw (v2si, v2si)
+v8qi __builtin_arm_wmaxub (v8qi, v8qi)
+v4hi __builtin_arm_wmaxuh (v4hi, v4hi)
+v2si __builtin_arm_wmaxuw (v2si, v2si)
+v8qi __builtin_arm_wminsb (v8qi, v8qi)
+v4hi __builtin_arm_wminsh (v4hi, v4hi)
+v2si __builtin_arm_wminsw (v2si, v2si)
+v8qi __builtin_arm_wminub (v8qi, v8qi)
+v4hi __builtin_arm_wminuh (v4hi, v4hi)
+v2si __builtin_arm_wminuw (v2si, v2si)
+v4hi __builtin_arm_wmulsm (v4hi, v4hi)
+v4hi __builtin_arm_wmulul (v4hi, v4hi)
+v4hi __builtin_arm_wmulum (v4hi, v4hi)
+long long __builtin_arm_wor (long long, long long)
+v2si __builtin_arm_wpackdss (long long, long long)
+v2si __builtin_arm_wpackdus (long long, long long)
+v8qi __builtin_arm_wpackhss (v4hi, v4hi)
+v8qi __builtin_arm_wpackhus (v4hi, v4hi)
+v4hi __builtin_arm_wpackwss (v2si, v2si)
+v4hi __builtin_arm_wpackwus (v2si, v2si)
+long long __builtin_arm_wrord (long long, long long)
+long long __builtin_arm_wrordi (long long, int)
+v4hi __builtin_arm_wrorh (v4hi, long long)
+v4hi __builtin_arm_wrorhi (v4hi, int)
+v2si __builtin_arm_wrorw (v2si, long long)
+v2si __builtin_arm_wrorwi (v2si, int)
+v2si __builtin_arm_wsadb (v8qi, v8qi)
+v2si __builtin_arm_wsadbz (v8qi, v8qi)
+v2si __builtin_arm_wsadh (v4hi, v4hi)
+v2si __builtin_arm_wsadhz (v4hi, v4hi)
+v4hi __builtin_arm_wshufh (v4hi, int)
+long long __builtin_arm_wslld (long long, long long)
+long long __builtin_arm_wslldi (long long, int)
+v4hi __builtin_arm_wsllh (v4hi, long long)
+v4hi __builtin_arm_wsllhi (v4hi, int)
+v2si __builtin_arm_wsllw (v2si, long long)
+v2si __builtin_arm_wsllwi (v2si, int)
+long long __builtin_arm_wsrad (long long, long long)
+long long __builtin_arm_wsradi (long long, int)
+v4hi __builtin_arm_wsrah (v4hi, long long)
+v4hi __builtin_arm_wsrahi (v4hi, int)
+v2si __builtin_arm_wsraw (v2si, long long)
+v2si __builtin_arm_wsrawi (v2si, int)
+long long __builtin_arm_wsrld (long long, long long)
+long long __builtin_arm_wsrldi (long long, int)
+v4hi __builtin_arm_wsrlh (v4hi, long long)
+v4hi __builtin_arm_wsrlhi (v4hi, int)
+v2si __builtin_arm_wsrlw (v2si, long long)
+v2si __builtin_arm_wsrlwi (v2si, int)
+v8qi __builtin_arm_wsubb (v8qi, v8qi)
+v8qi __builtin_arm_wsubbss (v8qi, v8qi)
+v8qi __builtin_arm_wsubbus (v8qi, v8qi)
+v4hi __builtin_arm_wsubh (v4hi, v4hi)
+v4hi __builtin_arm_wsubhss (v4hi, v4hi)
+v4hi __builtin_arm_wsubhus (v4hi, v4hi)
+v2si __builtin_arm_wsubw (v2si, v2si)
+v2si __builtin_arm_wsubwss (v2si, v2si)
+v2si __builtin_arm_wsubwus (v2si, v2si)
+v4hi __builtin_arm_wunpckehsb (v8qi)
+v2si __builtin_arm_wunpckehsh (v4hi)
+long long __builtin_arm_wunpckehsw (v2si)
+v4hi __builtin_arm_wunpckehub (v8qi)
+v2si __builtin_arm_wunpckehuh (v4hi)
+long long __builtin_arm_wunpckehuw (v2si)
+v4hi __builtin_arm_wunpckelsb (v8qi)
+v2si __builtin_arm_wunpckelsh (v4hi)
+long long __builtin_arm_wunpckelsw (v2si)
+v4hi __builtin_arm_wunpckelub (v8qi)
+v2si __builtin_arm_wunpckeluh (v4hi)
+long long __builtin_arm_wunpckeluw (v2si)
+v8qi __builtin_arm_wunpckihb (v8qi, v8qi)
+v4hi __builtin_arm_wunpckihh (v4hi, v4hi)
+v2si __builtin_arm_wunpckihw (v2si, v2si)
+v8qi __builtin_arm_wunpckilb (v8qi, v8qi)
+v4hi __builtin_arm_wunpckilh (v4hi, v4hi)
+v2si __builtin_arm_wunpckilw (v2si, v2si)
+long long __builtin_arm_wxor (long long, long long)
+long long __builtin_arm_wzero ()
+@end smallexample
@node X86 Built-in Functions
@subsection X86 Built-in Functions
@@ -5156,7 +5895,7 @@ entire vector register, interpreting it as a 128-bit integer, these use mode
The following built-in functions are made available by @option{-mmmx}.
All of them generate the machine instruction that is part of the name.
-@example
+@smallexample
v8qi __builtin_ia32_paddb (v8qi, v8qi)
v4hi __builtin_ia32_paddw (v4hi, v4hi)
v2si __builtin_ia32_paddd (v2si, v2si)
@@ -5192,14 +5931,14 @@ v2si __builtin_ia32_punpckldq (v2si, v2si)
v8qi __builtin_ia32_packsswb (v4hi, v4hi)
v4hi __builtin_ia32_packssdw (v2si, v2si)
v8qi __builtin_ia32_packuswb (v4hi, v4hi)
-@end example
+@end smallexample
The following built-in functions are made available either with
@option{-msse}, or with a combination of @option{-m3dnow} and
@option{-march=athlon}. All of them generate the machine
instruction that is part of the name.
-@example
+@smallexample
v4hi __builtin_ia32_pmulhuw (v4hi, v4hi)
v8qi __builtin_ia32_pavgb (v8qi, v8qi)
v4hi __builtin_ia32_pavgw (v4hi, v4hi)
@@ -5214,12 +5953,12 @@ int __builtin_ia32_pmovmskb (v8qi)
void __builtin_ia32_maskmovq (v8qi, v8qi, char *)
void __builtin_ia32_movntq (di *, di)
void __builtin_ia32_sfence (void)
-@end example
+@end smallexample
The following built-in functions are available when @option{-msse} is used.
All of them generate the machine instruction that is part of the name.
-@example
+@smallexample
int __builtin_ia32_comieq (v4sf, v4sf)
int __builtin_ia32_comineq (v4sf, v4sf)
int __builtin_ia32_comilt (v4sf, v4sf)
@@ -5288,7 +6027,7 @@ v4sf __builtin_ia32_sqrtss (v4sf)
v4sf __builtin_ia32_shufps (v4sf, v4sf, int)
void __builtin_ia32_movntps (float *, v4sf)
int __builtin_ia32_movmskps (v4sf)
-@end example
+@end smallexample
The following built-in functions are available when @option{-msse} is used.
@@ -5315,10 +6054,10 @@ Generates the @code{movhps} machine instruction as a store to memory.
Generates the @code{movlps} machine instruction as a store to memory.
@end table
-The following built-in functions are available when @option{-mpni} is used.
+The following built-in functions are available when @option{-msse3} is used.
All of them generate the machine instruction that is part of the name.
-@example
+@smallexample
v2df __builtin_ia32_addsubpd (v2df, v2df)
v2df __builtin_ia32_addsubps (v2df, v2df)
v2df __builtin_ia32_haddpd (v2df, v2df)
@@ -5331,9 +6070,9 @@ v2df __builtin_ia32_movddup (v2df)
v4sf __builtin_ia32_movshdup (v4sf)
v4sf __builtin_ia32_movsldup (v4sf)
void __builtin_ia32_mwait (unsigned int, unsigned int)
-@end example
+@end smallexample
-The following built-in functions are available when @option{-mpni} is used.
+The following built-in functions are available when @option{-msse3} is used.
@table @code
@item v2df __builtin_ia32_loadddup (double const *)
@@ -5343,7 +6082,7 @@ Generates the @code{movddup} machine instruction as a load from memory.
The following built-in functions are available when @option{-m3dnow} is used.
All of them generate the machine instruction that is part of the name.
-@example
+@smallexample
void __builtin_ia32_femms (void)
v8qi __builtin_ia32_pavgusb (v8qi, v8qi)
v2si __builtin_ia32_pf2id (v2sf)
@@ -5364,20 +6103,20 @@ v2sf __builtin_ia32_pfsub (v2sf, v2sf)
v2sf __builtin_ia32_pfsubr (v2sf, v2sf)
v2sf __builtin_ia32_pi2fd (v2si)
v4hi __builtin_ia32_pmulhrw (v4hi, v4hi)
-@end example
+@end smallexample
The following built-in functions are available when both @option{-m3dnow}
and @option{-march=athlon} are used. All of them generate the machine
instruction that is part of the name.
-@example
+@smallexample
v2si __builtin_ia32_pf2iw (v2sf)
v2sf __builtin_ia32_pfnacc (v2sf, v2sf)
v2sf __builtin_ia32_pfpnacc (v2sf, v2sf)
v2sf __builtin_ia32_pi2fw (v2si)
v2sf __builtin_ia32_pswapdsf (v2sf)
v2si __builtin_ia32_pswapdsi (v2si)
-@end example
+@end smallexample
@node PowerPC AltiVec Built-in Functions
@subsection PowerPC AltiVec Built-in Functions
@@ -6618,7 +7357,7 @@ For compatibility with other compilers, GCC allows you to define
a structure or union that contains, as fields, structures and unions
without names. For example:
-@example
+@smallexample
struct @{
int a;
union @{
@@ -6627,7 +7366,7 @@ struct @{
@};
int d;
@} foo;
-@end example
+@end smallexample
In this example, the user would be able to access members of the unnamed
union with code like @samp{foo.b}. Note that only unnamed structs and
@@ -6637,14 +7376,14 @@ unions are allowed, you may not have, for example, an unnamed
You must never create such structures that cause ambiguous field definitions.
For example, this structure:
-@example
+@smallexample
struct @{
int a;
struct @{
int a;
@};
@} foo;
-@end example
+@end smallexample
It is ambiguous which @code{a} is being referred to with @samp{foo.a}.
Such constructs are not supported and must be avoided. In the future,
@@ -6668,11 +7407,11 @@ is not available everywhere.
At the user level, the extension is visible with a new storage
class keyword: @code{__thread}. For example:
-@example
+@smallexample
__thread int i;
extern __thread struct state s;
static __thread char *p;
-@end example
+@end smallexample
The @code{__thread} specifier may be used alone, with the @code{extern}
or @code{static} specifiers, but with no other storage class specifier.
@@ -6935,8 +7674,10 @@ Predefined Macros,cpp,The GNU C Preprocessor}).
* Bound member functions:: You can extract a function pointer to the
method denoted by a @samp{->*} or @samp{.*} expression.
* C++ Attributes:: Variable, function, and type attributes for C++ only.
+* Strong Using:: Strong using-directives for namespace composition.
+* Offsetof:: Special syntax for implementing @code{offsetof}.
* Java Exceptions:: Tweaking exception handling to work with Java.
-* Deprecated Features:: Things might disappear from g++.
+* Deprecated Features:: Things will disappear from g++.
* Backwards Compatibility:: Compatibilities with earlier definitions of C++.
@end menu
@@ -6964,9 +7705,9 @@ These operations are not primitive in ordinary C++, since you can
use a macro to return the minimum of two things in C++, as in the
following example.
-@example
+@smallexample
#define MIN(X,Y) ((X) < (Y) ? : (X) : (Y))
-@end example
+@end smallexample
@noindent
You might then use @w{@samp{int min = MIN (i, j);}} to set @var{min} to
@@ -7011,11 +7752,11 @@ within a sequence point.
In most expressions, it is intuitively obvious what is a read and what is
a write. For instance
-@example
+@smallexample
volatile int *dst = @var{somevalue};
volatile int *src = @var{someothervalue};
*dst = *src;
-@end example
+@end smallexample
@noindent
will cause a read of the volatile object pointed to by @var{src} and stores the
@@ -7026,10 +7767,10 @@ larger than @code{int}.
Less obvious expressions are where something which looks like an access
is used in a void context. An example would be,
-@example
+@smallexample
volatile int *src = @var{somevalue};
*src;
-@end example
+@end smallexample
With C, such expressions are rvalues, and as rvalues cause a read of
the object, GCC interprets this as a read of the volatile being pointed
@@ -7044,14 +7785,14 @@ pointer to volatile object of complete type in a void context as a read
of the object. When the object has incomplete type, G++ issues a
warning.
-@example
+@smallexample
struct S;
struct T @{int m;@};
volatile S *ptr1 = @var{somevalue};
volatile T *ptr2 = @var{somevalue};
*ptr1;
*ptr2;
-@end example
+@end smallexample
In this example, a warning is issued for @code{*ptr1}, and @code{*ptr2}
causes a read of the object pointed to. If you wish to force an error on
@@ -7072,7 +7813,7 @@ an rvalue.
@cindex restricted references
@cindex restricted this pointer
-As with gcc, g++ understands the C99 feature of restricted pointers,
+As with the C front end, G++ understands the C99 feature of restricted pointers,
specified with the @code{__restrict__}, or @code{__restrict} type
qualifier. Because you cannot compile C++ by specifying the @option{-std=c99}
language flag, @code{restrict} is not a keyword in C++.
@@ -7081,12 +7822,12 @@ In addition to allowing restricted pointers, you can specify restricted
references, which indicate that the reference is not aliased in the local
context.
-@example
+@smallexample
void fn (int *__restrict__ rptr, int &__restrict__ rref)
@{
/* @r{@dots{}} */
@}
-@end example
+@end smallexample
@noindent
In the body of @code{fn}, @var{rptr} points to an unaliased integer and
@@ -7095,12 +7836,12 @@ In the body of @code{fn}, @var{rptr} points to an unaliased integer and
You may also specify whether a member function's @var{this} pointer is
unaliased by using @code{__restrict__} as a member function qualifier.
-@example
+@smallexample
void T::fn () __restrict__
@{
/* @r{@dots{}} */
@}
-@end example
+@end smallexample
@noindent
Within the body of @code{T::fn}, @var{this} will have the effective
@@ -7175,7 +7916,7 @@ but there are other options as well.
@end table
When used with GNU ld version 2.8 or later on an ELF system such as
-Linux/GNU or Solaris 2, or on Microsoft Windows, duplicate copies of
+GNU/Linux or Solaris 2, or on Microsoft Windows, duplicate copies of
these constructs will be discarded at link time. This is known as
COMDAT support.
@@ -7193,37 +7934,24 @@ almost certainly break things.
another way to control placement of these constructs.
@node C++ Interface
-@section Declarations and Definitions in One Header
+@section #pragma interface and implementation
@cindex interface and implementation headers, C++
@cindex C++ interface and implementation headers
-C++ object definitions can be quite complex. In principle, your source
-code will need two kinds of things for each object that you use across
-more than one source file. First, you need an @dfn{interface}
-specification, describing its structure with type declarations and
-function prototypes. Second, you need the @dfn{implementation} itself.
-It can be tedious to maintain a separate interface description in a
-header file, in parallel to the actual implementation. It is also
-dangerous, since separate interface and implementation definitions may
-not remain parallel.
-
@cindex pragmas, interface and implementation
-With GNU C++, you can use a single header file for both purposes.
-@quotation
-@emph{Warning:} The mechanism to specify this is in transition. For the
-nonce, you must use one of two @code{#pragma} commands; in a future
-release of GNU C++, an alternative mechanism will make these
-@code{#pragma} commands unnecessary.
-@end quotation
+@code{#pragma interface} and @code{#pragma implementation} provide the
+user with a way of explicitly directing the compiler to emit entities
+with vague linkage (and debugging information) in a particular
+translation unit.
-The header file contains the full definitions, but is marked with
-@samp{#pragma interface} in the source code. This allows the compiler
-to use the header file only as an interface specification when ordinary
-source files incorporate it with @code{#include}. In the single source
-file where the full implementation belongs, you can use either a naming
-convention or @samp{#pragma implementation} to indicate this alternate
-use of the header file.
+@emph{Note:} As of GCC 2.7.2, these @code{#pragma}s are not useful in
+most cases, because of COMDAT support and the ``key method'' heuristic
+mentioned in @ref{Vague Linkage}. Using them can actually cause your
+program to grow due to unnecesary out-of-line copies of inline
+functions. Currently the only benefit of these @code{#pragma}s is
+reduced duplication of debugging information, and that should be
+addressed soon on DWARF 2 targets with the use of COMDAT sections.
@table @code
@item #pragma interface
@@ -7273,9 +8001,6 @@ an implementation file whenever you would include it from
implementation}. This was deemed to be more trouble than it was worth,
however, and disabled.
-If you use an explicit @samp{#pragma implementation}, it must appear in
-your source file @emph{before} you include the affected header files.
-
Use the string argument if you want a single implementation file to
include code from multiple header files. (You must also use
@samp{#include} to include the header file; @samp{#pragma
@@ -7293,10 +8018,10 @@ multiple implementation files.
effect on function inlining.
If you define a class in a header file marked with @samp{#pragma
-interface}, the effect on a function defined in that class is similar to
-an explicit @code{extern} declaration---the compiler emits no code at
-all to define an independent version of the function. Its definition
-is used only for inlining with its callers.
+interface}, the effect on an inline function defined in that class is
+similar to an explicit @code{extern} declaration---the compiler emits
+no code at all to define an independent version of the function. Its
+definition is used only for inlining with its callers.
@opindex fno-implement-inlines
Conversely, when you include the same header file in a main source file
@@ -7316,7 +8041,7 @@ intelligence from the environment than one usually finds on a UNIX
system. Somehow the compiler and linker have to make sure that each
template instance occurs exactly once in the executable if it is needed,
and not at all otherwise. There are two basic approaches to this
-problem, which I will refer to as the Borland model and the Cfront model.
+problem, which are referred to as the Borland model and the Cfront model.
@table @asis
@item Borland model
@@ -7352,11 +8077,11 @@ compiled separately.
@end table
When used with GNU ld version 2.8 or later on an ELF system such as
-Linux/GNU or Solaris 2, or on Microsoft Windows, g++ supports the
-Borland model. On other systems, g++ implements neither automatic
+GNU/Linux or Solaris 2, or on Microsoft Windows, G++ supports the
+Borland model. On other systems, G++ implements neither automatic
model.
-A future version of g++ will support a hybrid model whereby the compiler
+A future version of G++ will support a hybrid model whereby the compiler
will emit any instantiations for which the template definition is
included in the compile, and store template definitions and
instantiation context information into the object file for the rest.
@@ -7406,14 +8131,14 @@ that define the templates themselves; you can put all of the explicit
instantiations you need into one big file; or you can create small files
like
-@example
+@smallexample
#include "Foo.h"
#include "Foo.cc"
template class Foo<int>;
template ostream& operator <<
(ostream&, const Foo<int>&);
-@end example
+@end smallexample
for each of the instances you need, and create a template instantiation
library from those.
@@ -7427,7 +8152,7 @@ compile it without @option{-fno-implicit-templates} so you get all of the
instances required by your explicit instantiations (but not by any
other files) without having to specify them as well.
-g++ has extended the template instantiation syntax given in the ISO
+G++ has extended the template instantiation syntax given in the ISO
standard to allow forward declaration of explicit instantiations
(with @code{extern}), instantiation of the compiler support data for a
template class (i.e.@: the vtable) without instantiating any of its
@@ -7435,21 +8160,18 @@ members (with @code{inline}), and instantiation of only the static data
members of a template class, without the support data or member
functions (with (@code{static}):
-@example
+@smallexample
extern template int max (int, int);
inline template class Foo<int>;
static template class Foo<int>;
-@end example
+@end smallexample
@item
-Do nothing. Pretend g++ does implement automatic instantiation
+Do nothing. Pretend G++ does implement automatic instantiation
management. Code written for the Borland model will work fine, but
each translation unit will contain instances of each of the templates it
uses. In a large program, this can lead to an unacceptable amount of code
duplication.
-
-@xref{C++ Interface,,Declarations and Definitions in One Header}, for
-more discussion of these pragmas.
@end enumerate
@node Bound member functions
@@ -7475,21 +8197,21 @@ virtual function calls.
The syntax for this extension is
-@example
+@smallexample
extern A a;
extern int (A::*fp)();
typedef int (*fptr)(A *);
fptr p = (fptr)(a.*fp);
-@end example
+@end smallexample
For PMF constants (i.e.@: expressions of the form @samp{&Klasse::Member}),
no object is needed to obtain the address of the function. They can be
converted to function pointers directly:
-@example
+@smallexample
fptr p1 = (fptr)(&A::foo);
-@end example
+@end smallexample
@opindex Wno-pmf-conversions
You must specify @option{-Wno-pmf-conversions} to use this extension.
@@ -7535,6 +8257,69 @@ interface table mechanism, instead of regular virtual table dispatch.
@end table
+See also @xref{Strong Using}.
+
+@node Strong Using
+@section Strong Using
+
+@strong{Caution:} The semantics of this extension are not fully
+defined. Users should refrain from using this extension as its
+semantics may change subtly over time. It is possible that this
+extension wil be removed in future versions of G++.
+
+A using-directive with @code{__attribute ((strong))} is stronger
+than a normal using-directive in two ways:
+
+@itemize @bullet
+@item
+Templates from the used namespace can be specialized as though they were members of the using namespace.
+
+@item
+The using namespace is considered an associated namespace of all
+templates in the used namespace for purposes of argument-dependent
+name lookup.
+@end itemize
+
+This is useful for composing a namespace transparently from
+implementation namespaces. For example:
+
+@smallexample
+namespace std @{
+ namespace debug @{
+ template <class T> struct A @{ @};
+ @}
+ using namespace debug __attribute ((__strong__));
+ template <> struct A<int> @{ @}; // ok to specialize
+
+ template <class T> void f (A<T>);
+@}
+
+int main()
+@{
+ f (std::A<float>()); // lookup finds std::f
+ f (std::A<int>());
+@}
+@end smallexample
+
+@node Offsetof
+@section Offsetof
+
+G++ uses a syntactic extension to implement the @code{offsetof} macro.
+
+In particular:
+
+@smallexample
+ __offsetof__ (expression)
+@end smallexample
+
+is equivalent to the parenthesized expression, except that the
+expression is considered an integral constant expression even if it
+contains certain operators that are not normally permitted in an
+integral constant expression. Users should never use
+@code{__offsetof__} directly; the only valid use of
+@code{__offsetof__} is to implement the @code{offsetof} macro in
+@code{<stddef.h>}.
+
@node Java Exceptions
@section Java Exceptions
@@ -7586,10 +8371,10 @@ that are now deprecated:
@table @code
@item -fexternal-templates
@itemx -falt-external-templates
-These are two of the many ways for g++ to implement template
+These are two of the many ways for G++ to implement template
instantiation. @xref{Template Instantiation}. The C++ standard clearly
defines how template definitions have to be organized across
-implementation units. g++ has an implicit instantiation mechanism that
+implementation units. G++ has an implicit instantiation mechanism that
should work just fine for standard-conforming code.
@item -fstrict-prototype
@@ -7601,18 +8386,20 @@ it is required for backwards compatibility @xref{Backwards Compatibility}.
@end table
The named return value extension has been deprecated, and is now
-removed from g++.
+removed from G++.
The use of initializer lists with new expressions has been deprecated,
-and is now removed from g++.
+and is now removed from G++.
Floating and complex non-type template parameters have been deprecated,
-and are now removed from g++.
+and are now removed from G++.
+
+The implicit typename extension has been deprecated and is now
+removed from G++.
-The implicit typename extension has been deprecated and will be removed
-from g++ at some point. In some cases g++ determines that a dependent
-type such as @code{TPL<T>::X} is a type without needing a
-@code{typename} keyword, contrary to the standard.
+The use of default arguments in function pointers, function typedefs and
+and other places where they are not permitted by the standard is
+deprecated and will be removed from a future version of G++.
@node Backwards Compatibility
@section Backwards Compatibility
diff --git a/contrib/gcc/doc/fragments.texi b/contrib/gcc/doc/fragments.texi
index c9ebcf9145d6..160ffed15b97 100644
--- a/contrib/gcc/doc/fragments.texi
+++ b/contrib/gcc/doc/fragments.texi
@@ -13,7 +13,8 @@ construct the file @file{Makefile} from the template file
fragments from the @file{config} directory. These are used to set
Makefile parameters that are not amenable to being calculated by
autoconf. The list of fragments to incorporate is set by
-@file{config.gcc}; @xref{System Config}.
+@file{config.gcc} (and occasionally @file{config.build}
+and @file{config.host}); @xref{System Config}.
Fragments are named either @file{t-@var{target}} or @file{x-@var{host}},
depending on whether they are relevant to configuring GCC to produce
diff --git a/contrib/gcc/doc/frontends.texi b/contrib/gcc/doc/frontends.texi
index 1ee56856df38..0e4dfe5427a9 100644
--- a/contrib/gcc/doc/frontends.texi
+++ b/contrib/gcc/doc/frontends.texi
@@ -1,70 +1,61 @@
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-@c 1999, 2000, 2001 Free Software Foundation, Inc.
+@c 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@node G++ and GCC
-@chapter Compile C, C++, Objective-C, Ada, Fortran, Java, or treelang
+@chapter Programming Languages Supported by GCC
-@cindex Objective-C
+@cindex GCC
+@cindex GNU Compiler Collection
+@cindex GNU C Compiler
+@cindex Ada
@cindex Fortran
@cindex Java
-@cindex Ada
+@cindex Objective-C
@cindex treelang
-Several versions of the compiler (C, C++, Objective-C, Ada,
-Fortran, Java and treelang) are integrated; this is why we use the name
-``GNU Compiler Collection''. GCC can compile programs written in any of these
-languages. The Ada, Fortran, Java and treelang compilers are described in
-separate manuals.
-
-@cindex GCC
-``GCC'' is a common shorthand term for the GNU Compiler Collection. This is both
-the most general name for the compiler, and the name used when the
-emphasis is on compiling C programs (as the abbreviation formerly
-stood for ``GNU C Compiler'').
+GCC stands for ``GNU Compiler Collection''. GCC is an integrated
+distribution of compilers for several major programming languages. These
+languages currently include C, C++, Objective-C, Java, Fortran, and Ada.
+
+The abbreviation @dfn{GCC} has multiple meanings in common use. The
+current official meaning is ``GNU Compiler Collection'', which refers
+generically to the complete suite of tools. The name historically stood
+for ``GNU C Compiler'', and this usage is still common when the emphasis
+is on compiling C programs. Finally, the name is also used when speaking
+of the @dfn{language-independent} component of GCC: code shared among the
+compilers for all supported languages.
+
+The language-independent component of GCC includes the majority of the
+optimizers, as well as the ``back ends'' that generate machine code for
+various processors.
+
+@cindex COBOL
+@cindex Mercury
+@cindex Pascal
+The part of a compiler that is specific to a particular language is
+called the ``front end''. In addition to the front ends that are
+integrated components of GCC, there are several other front ends that
+are maintained separately. These support languages such as Pascal,
+Mercury, and COBOL. To use these, they must be built together with
+GCC proper.
@cindex C++
@cindex G++
-When referring to C++ compilation, it is usual to call the compiler
-``G++''. Since there is only one compiler, it is also accurate to call
-it ``GCC'' no matter what the language context; however, the term
-``G++'' is more useful when the emphasis is on compiling C++ programs.
-
@cindex Ada
@cindex GNAT
-Similarly, when we talk about Ada compilation, we usually call the
-compiler ``GNAT'', for the same reasons.
-
-We use the name ``GCC'' to refer to the compilation system as a
-whole, and more specifically to the language-independent part of the
-compiler. For example, we refer to the optimization options as
-affecting the behavior of ``GCC'' or sometimes just ``the compiler''.
-
-Front ends for other languages, such as Mercury and Pascal exist but
-have not yet been integrated into GCC@. These front ends, like that for C++,
-are built in subdirectories of GCC and link to it. The result is an
-integrated compiler that can compile programs written in C, C++,
-Objective-C, or any of the languages for which you have installed front
-ends.
-
-In this manual, we only discuss the options for the C, Objective-C, and
-C++ compilers and those of the GCC core. Consult the documentation
-of the other front ends for the options to use when compiling programs
-written in other languages.
+Most of the compilers for languages other than C have their own names.
+The C++ compiler is G++, the Ada compiler is GNAT, and so on. When we
+talk about compiling one of those languages, we might refer to that
+compiler by its own name, or as GCC@. Either is correct.
@cindex compiler compared to C++ preprocessor
@cindex intermediate C version, nonexistent
@cindex C intermediate output, nonexistent
-G++ is a @emph{compiler}, not merely a preprocessor. G++ builds object
-code directly from your C++ program source. There is no intermediate C
-version of the program. (By contrast, for example, some other
-implementations use a program that generates a C program from your C++
-source.) Avoiding an intermediate C representation of the program means
-that you get better object code, and better debugging information. The
-GNU debugger, GDB, works with this information in the object code to
-give you comprehensive C++ source-level editing capabilities
-(@pxref{C,,C and C++,gdb.info, Debugging with GDB}).
-
-@c FIXME! Someone who knows something about Objective-C ought to put in
-@c a paragraph or two about it here, and move the index entry down when
-@c there is more to point to than the general mention in the 1st par.
+Historically, compilers for many languages, including C++ and Fortran,
+have been implemented as ``preprocessors'' which emit another high
+level language such as C@. None of the compilers included in GCC are
+implemented this way; they all generate machine code directly. This
+sort of preprocessor should not be confused with the @dfn{C
+preprocessor}, which is an integral feature of the C, C++, and
+Objective-C languages.
diff --git a/contrib/gcc/doc/gcc.texi b/contrib/gcc/doc/gcc.texi
index 721150ac8a1e..07dfd08e4d3b 100644
--- a/contrib/gcc/doc/gcc.texi
+++ b/contrib/gcc/doc/gcc.texi
@@ -35,34 +35,13 @@
@syncodeindex pg cp
@syncodeindex tp cp
-@c %**end of header
-
-@c Use with @@smallbook.
-
-@c Cause even numbered pages to be printed on the left hand side of
-@c the page and odd numbered pages to be printed on the right hand
-@c side of the page. Using this, you can print on both sides of a
-@c sheet of paper and have the text on the same part of the sheet.
+@paragraphindent 1
-@c The text on right hand pages is pushed towards the right hand
-@c margin and the text on left hand pages is pushed toward the left
-@c hand margin.
-@c (To provide the reverse effect, set bindingoffset to -0.75in.)
-
-@c @tex
-@c \global\bindingoffset=0.75in
-@c \global\normaloffset =0.75in
-@c @end tex
-
-@c Change the font used for @def... commands, since the default
-@c proportional one used is bad for names starting __.
-@tex
-\global\setfont\defbf\ttbshape{10}{\magstep1}
-@end tex
+@c %**end of header
@copying
Copyright @copyright{} 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
@@ -89,21 +68,18 @@ included in the section entitled ``GNU Free Documentation License''.
@end direntry
This file documents the use of the GNU compilers.
@sp 1
-Published by the Free Software Foundation@*
-59 Temple Place - Suite 330@*
-Boston, MA 02111-1307 USA
-@sp 1
@insertcopying
@sp 1
@end ifnottex
@setchapternewpage odd
+@shorttitlepage Using the GNU Compiler Collection (GCC)
@titlepage
@center @titlefont{Using the GNU Compiler Collection}
@sp 2
-@center Richard M. Stallman
+@center by Richard M. Stallman and the GCC Developer Community
@sp 3
-@center Last updated 30 December 2002
+@center Last updated 23 May 2004
@sp 1
@center for GCC @value{version-GCC}
@@ -111,15 +87,30 @@ Boston, MA 02111-1307 USA
@vskip 0pt plus 1filll
For GCC Version @value{version-GCC}@*
@sp 1
-Published by the Free Software Foundation @*
-59 Temple Place---Suite 330@*
-Boston, MA 02111-1307, USA@*
-Last printed April, 1998.@*
-Printed copies are available for $50 each.@*
-@c Update this ISBN when printing a new edition.
+Published by:
+@multitable @columnfractions 0.5 0.5
+@item GNU Press
+@tab Website: www.gnupress.org
+@item a division of the
+@tab General: @tex press@@gnu.org @end tex
+@item Free Software Foundation
+@tab Orders: @tex sales@@gnu.org @end tex
+@item 59 Temple Place Suite 330
+@tab Tel 617-542-5942
+@item Boston, MA 02111-1307 USA
+@tab Fax 617-542-2652
+@end multitable
+@sp 2
@ifset FSFPRINT
-ISBN 1-882114-37-X
+@c Update this ISBN when printing a new edition.
+@acronym{ISBN} 1-882114-39-6
+
+Cover art by Gary M. Torrisi. Cover design by Jonathan Richard.
@end ifset
+@ifclear FSFPRINT
+Last printed October 2003 for GCC 3.3.1.@*
+Printed copies are available for $45 each.
+@end ifclear
@sp 1
@insertcopying
@end titlepage
diff --git a/contrib/gcc/doc/gccint.texi b/contrib/gcc/doc/gccint.texi
index b6bec095fa0a..5864e5fcf4a1 100644
--- a/contrib/gcc/doc/gccint.texi
+++ b/contrib/gcc/doc/gccint.texi
@@ -23,29 +23,6 @@
@c %**end of header
-@c Use with @@smallbook.
-
-@c Cause even numbered pages to be printed on the left hand side of
-@c the page and odd numbered pages to be printed on the right hand
-@c side of the page. Using this, you can print on both sides of a
-@c sheet of paper and have the text on the same part of the sheet.
-
-@c The text on right hand pages is pushed towards the right hand
-@c margin and the text on left hand pages is pushed toward the left
-@c hand margin.
-@c (To provide the reverse effect, set bindingoffset to -0.75in.)
-
-@c @tex
-@c \global\bindingoffset=0.75in
-@c \global\normaloffset =0.75in
-@c @end tex
-
-@c Change the font used for @def... commands, since the default
-@c proportional one used is bad for names starting __.
-@tex
-\global\setfont\defbf\ttbshape{10}{\magstep1}
-@end tex
-
@copying
Copyright @copyright{} 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
@@ -75,10 +52,6 @@ included in the section entitled ``GNU Free Documentation License''.
@end direntry
This file documents the internals of the GNU compilers.
@sp 1
-Published by the Free Software Foundation@*
-59 Temple Place - Suite 330@*
-Boston, MA 02111-1307 USA
-@sp 1
@insertcopying
@end ifnottex
@@ -86,9 +59,9 @@ Boston, MA 02111-1307 USA
@titlepage
@center @titlefont{GNU Compiler Collection Internals}
@sp 2
-@center Richard M. Stallman
+@center by Richard M. Stallman and the GCC Developer Community
@sp 3
-@center Last updated 28 December 2002
+@center Last updated 23 May 2004
@sp 1
@center for GCC @value{version-GCC}
@@ -96,16 +69,6 @@ Boston, MA 02111-1307 USA
@vskip 0pt plus 1filll
For GCC Version @value{version-GCC}@*
@sp 1
-Published by the Free Software Foundation @*
-59 Temple Place---Suite 330@*
-Boston, MA 02111-1307, USA@*
-Last printed April, 1998.@*
-Printed copies are available for $50 each.@*
-@c Update this ISBN when printing a new edition.
-@ifset FSFPRINT
-ISBN 1-882114-37-X
-@end ifset
-@sp 1
@insertcopying
@end titlepage
@summarycontents
@@ -140,6 +103,7 @@ Additional tutorial information is linked to from
* Contributing:: How to contribute to testing and developing GCC.
* Portability:: Goals of GCC's portability features.
* Interface:: Function-call interface of GCC output.
+* Libgcc:: Low-level runtime library used by GCC.
* Languages:: Languages for which GCC front ends are written.
* Source Tree:: GCC source tree structure and build system.
* Passes:: Order of passes, what they do, and what each file is for.
@@ -168,6 +132,7 @@ Additional tutorial information is linked to from
@include contribute.texi
@include portability.texi
@include interface.texi
+@include libgcc.texi
@include languages.texi
@include sourcebuild.texi
@include passes.texi
diff --git a/contrib/gcc/doc/gcov.texi b/contrib/gcc/doc/gcov.texi
index 85d528982e1b..cd47f68fadca 100644
--- a/contrib/gcc/doc/gcov.texi
+++ b/contrib/gcc/doc/gcov.texi
@@ -1,5 +1,5 @@
@c Copyright (C) 1996, 1997, 1999, 2000, 2001,
-@c 2002, 2003 Free Software Foundation, Inc.
+@c 2002, 2003, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -120,6 +120,7 @@ gcov @r{[}@var{options}@r{]} @var{sourcefile}
@ignore
@c man begin SYNOPSIS
gcov [@option{-v}|@option{--version}] [@option{-h}|@option{--help}]
+ [@option{-a}|@option{--all-blocks}]
[@option{-b}|@option{--branch-probabilities}]
[@option{-c}|@option{--branch-counts}]
[@option{-n}|@option{--no-output}]
@@ -127,6 +128,7 @@ gcov [@option{-v}|@option{--version}] [@option{-h}|@option{--help}]
[@option{-p}|@option{--preserve-paths}]
[@option{-f}|@option{--function-summaries}]
[@option{-o}|@option{--object-directory} @var{directory|file}] @var{sourcefile}
+ [@option{-u}|@option{--unconditional-branches}]
@c man end
@c man begin SEEALSO
gpl(7), gfdl(7), fsf-funding(7), gcc(1) and the Info entry for @file{gcc}.
@@ -145,11 +147,19 @@ exit without doing any further processing.
Display the @command{gcov} version number (on the standard output),
and exit without doing any further processing.
+@item -a
+@itemx --all-blocks
+Write individual execution counts for every basic block. Normally gcov
+outputs execution counts only for the main blocks of a line. With this
+option you can determine if blocks within a single line are not being
+executed.
+
@item -b
@itemx --branch-probabilities
Write branch frequencies to the output file, and write branch summary
info to the standard output. This option allows you to see how often
-each branch in your program was taken.
+each branch in your program was taken. Unconditional branches will not
+be shown, unless the @option{-u} option is given.
@item -c
@itemx --branch-counts
@@ -166,7 +176,9 @@ Create long file names for included source files. For example, if the
header file @file{x.h} contains code, and was included in the file
@file{a.c}, then running @command{gcov} on the file @file{a.c} will produce
an output file called @file{a.c##x.h.gcov} instead of @file{x.h.gcov}.
-This can be useful if @file{x.h} is included in multiple source files.
+This can be useful if @file{x.h} is included in multiple source
+files. If you uses the @samp{-p} option, both the including and
+included file names will be complete path names.
@item -p
@itemx --preserve-paths
@@ -185,24 +197,33 @@ Output summaries for each function in addition to the file level summary.
@itemx --object-directory @var{directory}
@itemx --object-file @var{file}
Specify either the directory containing the gcov data files, or the
-object path name. The @file{.bb}, @file{.bbg}, and
-@file{.da} data files are searched for using this option. If a directory
+object path name. The @file{.gcno}, and
+@file{.gcda} data files are searched for using this option. If a directory
is specified, the data files are in that directory and named after the
source file name, without its extension. If a file is specified here,
the data files are named after that file, without its extension. If this
option is not supplied, it defaults to the current directory.
+@item -u
+@itemx --unconditional-branches
+When branch counts are given, include those of unconditional branches.
+Unconditional branches are normally not interesting.
+
@end table
-@command{gcov} should be run with the current directory the same as that
-when you invoked the compiler. Otherwise it will not be able to locate
-the source files. @command{gcov} produces files called
-@file{@var{mangledname}.gcov} in the current directory. These contain
-the coverage information of the source file they correspond to.
-One @file{.gcov} file is produced for each source file containing code,
-which was compiled to produce the data files. The @file{.gcov} files
-contain the ':' separated fields along with program source code. The
-format is
+@command{gcov} should be run with the current directory the same as that
+when you invoked the compiler. Otherwise it will not be able to locate
+the source files. @command{gcov} produces files called
+@file{@var{mangledname}.gcov} in the current directory. These contain
+the coverage information of the source file they correspond to.
+One @file{.gcov} file is produced for each source file containing code,
+which was compiled to produce the data files. The @var{mangledname} part
+of the output file name is usually simply the source file name, but can
+be something more complicated if the @samp{-l} or @samp{-p} options are
+given. Refer to those options for details.
+
+The @file{.gcov} files contain the ':' separated fields along with
+program source code. The format is
@smallexample
@var{execution_count}:@var{line_number}:@var{source line text}
@@ -228,8 +249,8 @@ information needed by gcov. These additional files are placed in the
directory where the object file is located.
Running the program will cause profile output to be generated. For each
-source file compiled with @option{-fprofile-arcs}, an accompanying @file{.da}
-file will be placed in the object file directory.
+source file compiled with @option{-fprofile-arcs}, an accompanying
+@file{.gcda} file will be placed in the object file directory.
Running @command{gcov} with your program's source file names as arguments
will now produce a listing of the code along with frequency of execution
@@ -249,26 +270,79 @@ Here is a sample:
@smallexample
-: 0:Source:tmp.c
- -: 0:Object:tmp.bb
+ -: 0:Graph:tmp.gcno
+ -: 0:Data:tmp.gcda
+ -: 0:Runs:1
+ -: 0:Programs:1
+ -: 1:#include <stdio.h>
+ -: 2:
+ -: 3:int main (void)
+function main called 1 returned 1 blocks executed 75%
+ 1: 4:@{
+ 1: 5: int i, total;
+ -: 6:
+ 1: 7: total = 0;
+ -: 8:
+ 11: 9: for (i = 0; i < 10; i++)
+ 10: 10: total += i;
+ -: 11:
+ 1: 12: if (total != 45)
+ #####: 13: printf ("Failure\n");
+ -: 14: else
+ 1: 15: printf ("Success\n");
+ 1: 16: return 0;
+ -: 17:@}
+@end smallexample
+
+When you use the @option{-a} option, you will get individual block
+counts, and the output looks like this:
+
+@smallexample
+ -: 0:Source:tmp.c
+ -: 0:Graph:tmp.gcno
+ -: 0:Data:tmp.gcda
+ -: 0:Runs:1
+ -: 0:Programs:1
-: 1:#include <stdio.h>
-: 2:
-: 3:int main (void)
+function main called 1 returned 1 blocks executed 75%
1: 4:@{
+ 1: 4-block 0
1: 5: int i, total;
- -: 6:
+ -: 6:
1: 7: total = 0;
- -: 8:
+ -: 8:
11: 9: for (i = 0; i < 10; i++)
+ 11: 9-block 0
10: 10: total += i;
- -: 11:
+ 10: 10-block 0
+ -: 11:
1: 12: if (total != 45)
+ 1: 12-block 0
#####: 13: printf ("Failure\n");
+ $$$$$: 13-block 0
-: 14: else
1: 15: printf ("Success\n");
+ 1: 15-block 0
1: 16: return 0;
- 1: 17:@}
+ 1: 16-block 0
+ -: 17:@}
@end smallexample
+In this mode, each basic block is only shown on one line -- the last
+line of the block. A multi-line block will only contribute to the
+execution count of that last line, and other lines will not be shown
+to contain code, unless previous blocks end on those lines.
+The total execution count of a line is shown and subsequent lines show
+the execution counts for individual blocks that end on that line. After each
+block, the branch and call counts of the block will be shown, if the
+@option{-b} option is given.
+
+Because of the way GCC instruments calls, a call count can be shown
+after a line with no individual blocks.
+As you can see, line 13 contains a basic block that was not executed.
+
@need 450
When you use the @option{-b} option, your output looks like this:
@@ -285,31 +359,34 @@ Here is a sample of a resulting @file{tmp.c.gcov} file:
@smallexample
-: 0:Source:tmp.c
- -: 0:Object:tmp.bb
+ -: 0:Graph:tmp.gcno
+ -: 0:Data:tmp.gcda
+ -: 0:Runs:1
+ -: 0:Programs:1
-: 1:#include <stdio.h>
-: 2:
-: 3:int main (void)
+function main called 1 returned 1 blocks executed 75%
1: 4:@{
1: 5: int i, total;
- -: 6:
+ -: 6:
1: 7: total = 0;
- -: 8:
+ -: 8:
11: 9: for (i = 0; i < 10; i++)
-branch 0: taken 90%
-branch 1: taken 100%
-branch 2: taken 100%
+branch 0 taken 91% (fallthrough)
+branch 1 taken 9%
10: 10: total += i;
- -: 11:
+ -: 11:
1: 12: if (total != 45)
-branch 0: taken 100%
+branch 0 taken 0% (fallthrough)
+branch 1 taken 100%
#####: 13: printf ("Failure\n");
-call 0: never executed
-branch 1: never executed
+call 0 never executed
-: 14: else
1: 15: printf ("Success\n");
-call 0: returns 100%
+call 0 called 1 returned 100%
1: 16: return 0;
- 1: 17:@}
+ -: 17:@}
@end smallexample
For each basic block, a line is printed after the last line of the basic
@@ -333,7 +410,7 @@ of times the call was executed will be printed. This will usually be
and thus may not return every time they are called.
The execution counts are cumulative. If the example program were
-executed again without removing the @file{.da} file, the count for the
+executed again without removing the @file{.gcda} file, the count for the
number of times each line in the source was executed would be added to
the results of the previous run(s). This is potentially useful in
several ways. For example, it could be used to accumulate data over a
@@ -341,9 +418,9 @@ number of program runs as part of a test verification suite, or to
provide more accurate long-term information over a large number of
program runs.
-The data in the @file{.da} files is saved immediately before the program
+The data in the @file{.gcda} files is saved immediately before the program
exits. For each source file compiled with @option{-fprofile-arcs}, the
-profiling code first attempts to read in an existing @file{.da} file; if
+profiling code first attempts to read in an existing @file{.gcda} file; if
the file doesn't match the executable (differing number of basic block
counts) it will ignore the contents of the file. It then adds in the
new execution counts and finally writes the data to the file.
@@ -386,119 +463,50 @@ executed 100 times. In one sense this result is correct, because there
was only one instruction representing all four of these lines. However,
the output does not indicate how many times the result was 0 and how
many times the result was 1.
+
+Inlineable functions can create unexpected line counts. Line counts are
+shown for the source code of the inlineable function, but what is shown
+depends on where the function is inlined, or if it is not inlined at all.
+
+If the function is not inlined, the compiler must emit an out of line
+copy of the function, in any object file that needs it. If
+@file{fileA.o} and @file{fileB.o} both contain out of line bodies of a
+particular inlineable function, they will also both contain coverage
+counts for that function. When @file{fileA.o} and @file{fileB.o} are
+linked together, the linker will, on many systems, select one of those
+out of line bodies for all calls to that function, and remove or ignore
+the other. Unfortunately, it will not remove the coverage counters for
+the unused function body. Hence when instrumented, all but one use of
+that function will show zero counts.
+
+If the function is inlined in several places, the block structure in
+each location might not be the same. For instance, a condition might
+now be calculable at compile time in some instances. Because the
+coverage of all the uses of the inline function will be shown for the
+same source lines, the line counts themselves might seem inconsistent.
+
@c man end
@node Gcov Data Files
@section Brief description of @command{gcov} data files
-@command{gcov} uses three files for doing profiling. The names of these
-files are derived from the original @emph{source} file by substituting
-the file suffix with either @file{.bb}, @file{.bbg}, or @file{.da}. All
-of these files are placed in the same directory as the source file, and
-contain data stored in a platform-independent method.
-
-The @file{.bb} and @file{.bbg} files are generated when the source file
-is compiled with the GCC @option{-ftest-coverage} option. The
-@file{.bb} file contains a list of source files (including headers),
-functions within those files, and line numbers corresponding to each
-basic block in the source file.
-
-The @file{.bb} file format consists of several lists of 4-byte integers
-which correspond to the line numbers of each basic block in the file.
-Each list is terminated by a line number of 0. A line number of
-@minus{}1 is used to designate that the source file name (padded to a
-4-byte boundary and followed by another @minus{}1) follows. In
-addition, a line number of @minus{}2 is used to designate that the name
-of a function (also padded to a 4-byte boundary and followed by a
-@minus{}2) follows.
-
-The @file{.bbg} file is used to reconstruct the program flow graph for
-the source file. It contains a list of the program flow arcs (possible
-branches taken from one basic block to another) for each function which,
-in combination with the @file{.bb} file, enables gcov to reconstruct the
-program flow.
-
-In the @file{.bbg} file, the format is:
-@smallexample
- name of function #0
- checksum of function #0
- number of basic blocks for function #0 (4-byte number)
- total number of arcs for function #0 (4-byte number)
- count of arcs in basic block #0 (4-byte number)
- destination basic block of arc #0 (4-byte number)
- flag bits (4-byte number)
- destination basic block of arc #1 (4-byte number)
- flag bits (4-byte number)
- @dots{}
- destination basic block of arc #N (4-byte number)
- flag bits (4-byte number)
- count of arcs in basic block #1 (4-byte number)
- destination basic block of arc #0 (4-byte number)
- flag bits (4-byte number)
- @dots{}
-@end smallexample
-
-A @minus{}1 (stored as a 4-byte number) is used to separate each function's
-list of basic blocks, and to verify that the file has been read
-correctly.
-
-The function name is stored as a @minus{}1 (4 bytes), the length (4 bytes),
-the name itself (padded to 4-byte boundary) followed by a @minus{}1 (4 bytes).
-
-The flags are defined as follows:
-@itemize
-@item bit0
-On function spanning tree
+@command{gcov} uses two files for profiling. The names of these files
+are derived from the original @emph{object} file by substituting the
+file suffix with either @file{.gcno}, or @file{.gcda}. All of these files
+are placed in the same directory as the object file, and contain data
+stored in a platform-independent format.
-@item bit1
-Is a fake edge
+The @file{.gcno} file is generated when the source file is compiled with
+the GCC @option{-ftest-coverage} option. It contains information to
+reconstruct the basic block graphs and assign source line numbers to
+blocks.
-@item bit2
-Is the fall through edge from one block to its immediate successor.
-
-@item bit3-bit31
-For future expansion
-
-@end itemize
-
-The @file{.da} file is generated when a program containing object files
+The @file{.gcda} file is generated when a program containing object files
built with the GCC @option{-fprofile-arcs} option is executed. A
-separate @file{.da} file is created for each source file compiled with
-this option, and the name of the @file{.da} file is stored as an
-absolute pathname in the resulting object file. This path name is
-derived from the object file name by substituting a @file{.da} suffix.
-
-The @file{.da} consists of one or more blocks with the following
-structure:
-@smallexample
- "magic" number @minus{}123 (4-byte number)
- number of functions (4-byte number)
- length of the "extension block" in bytes
- extension block (variable length)
- name of function #0 (the same format as in .bbg file)
- checksum of function #0
- number of instrumented arcs (4-byte number)
- count of arc #0 (8-byte number)
- count of arc #1 (8-byte number)
- @dots{}
- count of arc #M_0 (8-byte number)
- name of function #1 (the same format as in .bbg file)
- checksum of function #1
- @dots{}
-@end smallexample
-Multiple program runs might merge data into a single block, or might
-append a new block. The current structure of the extension block is as
-follows:
-@smallexample
- number of instrumented arcs in whole program (4-byte number)
- sum all of instrumented arcs in whole program (8-byte number)
- maximal value of counter in whole program (8-byte number)
- number of instrumented arcs in the object file (4-byte number)
- sum all of instrumented arcs in the object file (8-byte number)
- maximal value of counter in the object file (8-byte number)
-@end smallexample
-
-All three of these files use the functions in @file{gcov-io.h} to store
-integers; the functions in this header provide a machine-independent
-mechanism for storing and retrieving data from a stream.
+separate @file{.gcda} file is created for each object file compiled with
+this option. It contains arc transition counts, and some summary
+information.
+The full details of the file format is specified in @file{gcov-io.h},
+and functions provided in that header file should be used to access the
+coverage files.
diff --git a/contrib/gcc/doc/gty.texi b/contrib/gcc/doc/gty.texi
index 31d52522553a..2dc5b86dce3a 100644
--- a/contrib/gcc/doc/gty.texi
+++ b/contrib/gcc/doc/gty.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 2002, 2003
+@c Copyright (C) 2002, 2003, 2004
@c Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -10,7 +10,8 @@
GCC uses some fairly sophisticated memory management techniques, which
involve determining information about GCC's data structures from GCC's
-source code and using this information to perform garbage collection.
+source code and using this information to perform garbage collection and
+implement precompiled headers.
A full C parser would be too overcomplicated for this task, so a limited
subset of C is interpreted and special markers are used to determine
@@ -47,7 +48,7 @@ These markers can be placed:
@item
In a structure definition, before the open brace;
@item
-In a global variable declaration, after the keyword @code{static} or
+In a global variable declaration, after the keyword @code{static} or
@code{extern}; and
@item
In a structure field definition, before the name of the field.
@@ -131,8 +132,19 @@ field really isn't ever used.
@itemx default
The type machinery needs to be told which field of a @code{union} is
-currently active. This is done by giving each field a constant @code{tag}
-value, and then specifying a discriminator using @code{desc}. For example,
+currently active. This is done by giving each field a constant
+@code{tag} value, and then specifying a discriminator using @code{desc}.
+The value of the expression given by @code{desc} is compared against
+each @code{tag} value, each of which should be different. If no
+@code{tag} is matched, the field marked with @code{default} is used if
+there is one, otherwise no field in the union will be marked.
+
+In the @code{desc} option, the ``current structure'' is the union that
+it discriminates. Use @code{%1} to mean the structure containing it.
+(There are no escapes available to the @code{tag} option, since it's
+supposed to be a constant.)
+
+For example,
@smallexample
struct tree_binding GTY(())
@{
@@ -140,19 +152,15 @@ struct tree_binding GTY(())
union tree_binding_u @{
tree GTY ((tag ("0"))) scope;
struct cp_binding_level * GTY ((tag ("1"))) level;
- @} GTY ((desc ("BINDING_HAS_LEVEL_P ((tree)&%0)"))) scope;
+ @} GTY ((desc ("BINDING_HAS_LEVEL_P ((tree)&%0)"))) xscope;
tree value;
@};
@end smallexample
-In the @code{desc} option, the ``current structure'' is the union that
-it discriminates. Use @code{%1} to mean the structure containing it.
-(There are no escapes available to the @code{tag} option, since it's
-supposed to be a constant.)
-
-Each @code{tag} should be different. If no @code{tag} is matched,
-the field marked with @code{default} is used if there is one, otherwise
-no field in the union will be marked.
+In this example, the value of BINDING_HAS_LEVEL_P when applied to a
+@code{struct tree_binding *} is presumed to be 0 or 1. If 1, the type
+mechanism will treat the field @code{level} as being present and if 0,
+will treat the field @code{scope} as being present.
@findex param_is
@findex use_param
@@ -227,6 +235,39 @@ this field is always @code{NULL}. This is used to avoid requiring
backends to define certain optional structures. It doesn't work with
language frontends.
+@findex chain_next
+@findex chain_prev
+@item chain_next
+@itemx chain_prev
+
+It's helpful for the type machinery to know if objects are often
+chained together in long lists; this lets it generate code that uses
+less stack space by iterating along the list instead of recursing down
+it. @code{chain_next} is an expression for the next item in the list,
+@code{chain_prev} is an expression for the previous item. The
+machinery requires that taking the next item of the previous item
+gives the original item.
+
+@findex reorder
+@item reorder
+
+Some data structures depend on the relative ordering of pointers. If
+the type machinery needs to change that ordering, it will call the
+function referenced by the @code{reorder} option, before changing the
+pointers in the object that's pointed to by the field the option
+applies to. The function must be of the type @code{void ()(void *,
+void *, gt_pointer_operator, void *)}. The second parameter is the
+pointed-to object; the third parameter is a routine that, given a
+pointer, can update it to its new value. The fourth parameter is a
+cookie to be passed to the third parameter. The first parameter is
+the structure that contains the object, or the object itself if it is
+a structure.
+
+No data structure may depend on the absolute value of pointers. Even
+relying on relative orderings and using @code{reorder} functions can
+be expensive. It is better to depend on properties of the data, like
+an ID number or the hash of a string instead.
+
@findex special
@item special
@@ -270,19 +311,19 @@ things you need to do:
@enumerate
@item
You need to add the file to the list of source files the type
-machinery scans. There are three cases:
+machinery scans. There are three cases:
@enumerate a
@item
For a back-end file, this is usually done
automatically; if not, you should add it to @code{target_gtfiles} in
-the appropriate port's entries in @file{config.gcc}.
+the appropriate port's entries in @file{config.gcc}.
@item
For files shared by all front ends, this is done by adding the
filename to the @code{GTFILES} variable in @file{Makefile.in}.
-@item
+@item
For any other file used by a front end, this is done by adding the
filename to the @code{gtfiles} variable defined in
@file{config-lang.in}. For C, the file is @file{c-config-lang.in}.
@@ -301,7 +342,7 @@ header file, this should be done automatically. For a front-end header
file, it needs to be included by the same file that includes
@file{gtype-@var{lang}.h}. For other header files, it needs to be
included in @file{gtype-desc.c}, which is a generated file, so add it to
-@code{ifiles} in @code{open_base_file} in @file{gengtype.c}.
+@code{ifiles} in @code{open_base_file} in @file{gengtype.c}.
For source files that aren't header files, the machinery will generate a
header file that should be included in the source file you just changed.
diff --git a/contrib/gcc/doc/hostconfig.texi b/contrib/gcc/doc/hostconfig.texi
index 33c0a3bb28bb..5c38313efd21 100644
--- a/contrib/gcc/doc/hostconfig.texi
+++ b/contrib/gcc/doc/hostconfig.texi
@@ -1,72 +1,119 @@
-@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-@c 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+@c 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
@c This is part of the GCC manual.
-@c For copying conditions, see the file gcc.texi.
+@c For copying conditions, see the file gccint.texi.
@node Host Config
-@chapter Host Configuration Headers
+@chapter Host Configuration
+@cindex host configuration
+
+Most details about the machine and system on which the compiler is
+actually running are detected by the @command{configure} script. Some
+things are impossible for @command{configure} to detect; these are
+described in two ways, either by macros defined in a file named
+@file{xm-@var{machine}.h} or by hook functions in the file specified
+by the @var{out_host_hook_obj} variable in @file{config.gcc}. (The
+intention is that very few hosts will need a header file but nearly
+every fully supported host will need to override some hooks.)
+
+If you need to define only a few macros, and they have simple
+definitions, consider using the @code{xm_defines} variable in your
+@file{config.gcc} entry instead of creating a host configuration
+header. @xref{System Config}.
+
+@menu
+* Host Common:: Things every host probably needs implemented.
+* Filesystem:: Your host can't have the letter `a' in filenames?
+* Host Misc:: Rare configuration options for hosts.
+@end menu
+
+@node Host Common
+@section Host Common
+@cindex host hooks
+@cindex host functions
+
+Some things are just not portable, even between similar operating systems,
+and are too difficult for autoconf to detect. They get implemented using
+hook functions in the file specified by the @var{host_hook_obj}
+variable in @file{config.gcc}.
+
+@deftypefn {Host Hook} void HOST_HOOKS_EXTRA_SIGNALS (void)
+This host hook is used to set up handling for extra signals. The most
+common thing to do in this hook is to detect stack overflow.
+@end deftypefn
+
+@deftypefn {Host Hook} void * HOST_HOOKS_GT_PCH_GET_ADDRESS (size_t @var{size})
+This host hook returns the address of some space in which a PCH may be
+loaded with @samp{HOST_HOOKS_PCH_LOAD_PCH}. The space will need to
+have @var{size} bytes. If insufficient space is available,
+@samp{NULL} may be returned; the PCH machinery will try to find a
+suitable address using a heuristic.
+
+The memory does not have to be available now. In fact, usually
+@samp{HOST_HOOKS_PCH_LOAD_PCH} will already have been called. The memory
+need only be available in future invocations of GCC.
+@end deftypefn
+
+@deftypefn {Host Hook} bool HOST_HOOKS_GT_PCH_USE_ADDRESS (size_t @var{size}, void * @var{address})
+This host hook is called when a PCH file is about to be loaded. If
+@var{address} is the address that would have been returned by
+@samp{HOST_HOOKS_PCH_MEMORY_ADDRESS}, and @var{size} is smaller than
+the maximum than @samp{HOST_HOOKS_PCH_MEMORY_ADDRESS} would have
+accepted, return true, otherwise return false.
+
+In addition, free any address space reserved that isn't needed to hold
+@var{size} bytes (whether or not true is returned). The PCH machinery will
+use @samp{mmap} with @samp{MAP_FIXED} to load the PCH if @samp{HAVE_MMAP_FILE},
+or will use @samp{fread} otherwise.
+
+If no PCH will be loaded, this hook may be called with @var{size}
+zero, in which case all reserved address space should be freed.
+
+Do not try to handle values of @var{address} that could not have been
+returned by this executable; just return false. Such values usually
+indicate an out-of-date PCH file (built by some other GCC executable),
+and such a PCH file won't work.
+@end deftypefn
+
+@node Filesystem
+@section Host Filesystem
@cindex configuration file
@cindex @file{xm-@var{machine}.h}
-Host configuration headers contain macro definitions that describe the
-machine and system on which the compiler is running. They are usually
-unnecessary. Most of the things GCC needs to know about the host
-system can be deduced by the @command{configure} script.
-
-If your host does need a special configuration header, it should be
-named @file{xm-@var{machine}.h}, where @var{machine} is a short mnemonic
-for the machine. Here are some macros which this header can define.
+GCC needs to know a number of things about the semantics of the host
+machine's filesystem. Filesystems with Unix and MS-DOS semantics are
+automatically detected. For other systems, you can define the
+following macros in @file{xm-@var{machine}.h}.
@ftable @code
-@item VMS
-Define this macro if the host system is VMS@.
-
-@item FATAL_EXIT_CODE
-A C expression for the status code to be returned when the compiler
-exits after serious errors. The default is the system-provided macro
-@samp{EXIT_FAILURE}, or @samp{1} if the system doesn't define that
-macro. Define this macro only if these defaults are incorrect.
-
-@item SUCCESS_EXIT_CODE
-A C expression for the status code to be returned when the compiler
-exits without serious errors. (Warnings are not serious errors.) The
-default is the system-provided macro @samp{EXIT_SUCCESS}, or @samp{0} if
-the system doesn't define that macro. Define this macro only if these
-defaults are incorrect.
-
-@item USE_C_ALLOCA
-Define this macro if GCC should use the C implementation of @code{alloca}
-provided by @file{libiberty.a}. This only affects how some parts of the
-compiler itself allocate memory. It does not change code generation.
-
-When GCC is built with a compiler other than itself, the C @code{alloca}
-is always used. This is because most other implementations have serious
-bugs. You should define this macro only on a system where no
-stack-based @code{alloca} can possibly work. For instance, if a system
-has a small limit on the size of the stack, GCC's builtin @code{alloca}
-will not work reliably.
-
@item HAVE_DOS_BASED_FILE_SYSTEM
-Define this macro if the host file system obeys the semantics defined by
-MS-DOS instead of Unix. DOS file systems are case insensitive, file
-specifications may begin with a drive letter, and both forward slash and
-backslash (@samp{/} and @samp{\}) are directory separators. If you
-define this macro, you probably need to define the next three macros too.
-
-@item PATH_SEPARATOR
-If defined, this macro should expand to a character constant specifying
-the separator for elements of search paths. The default value is a
-colon (@samp{:}). DOS-based systems usually use semicolon (@samp{;}).
+This macro is automatically defined by @file{system.h} if the host
+file system obeys the semantics defined by MS-DOS instead of Unix.
+DOS file systems are case insensitive, file specifications may begin
+with a drive letter, and both forward slash and backslash (@samp{/}
+and @samp{\}) are directory separators.
@item DIR_SEPARATOR
@itemx DIR_SEPARATOR_2
If defined, these macros expand to character constants specifying
-separators for directory names within a file specification. They are
-used somewhat inconsistently throughout the compiler. If your system
-behaves like Unix (only forward slash separates pathnames), define
-neither of them. If your system behaves like DOS (both forward and
-backward slash can be used), define @code{DIR_SEPARATOR} to @samp{/}
-and @code{DIR_SEPARATOR_2} to @samp{\}.
+separators for directory names within a file specification.
+@file{system.h} will automatically give them appropriate values on
+Unix and MS-DOS file systems. If your file system is neither of
+these, define one or both appropriately in @file{xm-@var{machine}.h}.
+
+However, operating systems like VMS, where constructing a pathname is
+more complicated than just stringing together directory names
+separated by a special character, should not define either of these
+macros.
+
+@item PATH_SEPARATOR
+If defined, this macro should expand to a character constant
+specifying the separator for elements of search paths. The default
+value is a colon (@samp{:}). DOS-based systems usually, but not
+always, use semicolon (@samp{;}).
+
+@item VMS
+Define this macro if the host system is VMS@.
@item HOST_OBJECT_SUFFIX
Define this macro to be a C string representing the suffix for object
@@ -86,14 +133,6 @@ you do not define this macro, GCC will use @samp{/dev/null} as the bit
bucket. If the host does not support a bit bucket, define this macro to
an invalid filename.
-@item COLLECT2_HOST_INITIALIZATION
-If defined, a C statement (sans semicolon) that performs host-dependent
-initialization when @code{collect2} is being initialized.
-
-@item GCC_DRIVER_HOST_INITIALIZATION
-If defined, a C statement (sans semicolon) that performs host-dependent
-initialization when a compilation driver is being initialized.
-
@item UPDATE_PATH_HOST_CANONICALIZE (@var{path})
If defined, a C statement (sans semicolon) that performs host-dependent
canonicalization when a path used in a compilation driver or
@@ -112,6 +151,46 @@ unique to each dump file kind, e.g. @samp{rtl}.
If you do not define this macro, GCC will use @samp{.%02d.}. You should
define this macro if using the default will create an invalid file name.
+@end ftable
+
+@node Host Misc
+@section Host Misc
+@cindex configuration file
+@cindex @file{xm-@var{machine}.h}
+
+@ftable @code
+@item FATAL_EXIT_CODE
+A C expression for the status code to be returned when the compiler
+exits after serious errors. The default is the system-provided macro
+@samp{EXIT_FAILURE}, or @samp{1} if the system doesn't define that
+macro. Define this macro only if these defaults are incorrect.
+
+@item SUCCESS_EXIT_CODE
+A C expression for the status code to be returned when the compiler
+exits without serious errors. (Warnings are not serious errors.) The
+default is the system-provided macro @samp{EXIT_SUCCESS}, or @samp{0} if
+the system doesn't define that macro. Define this macro only if these
+defaults are incorrect.
+
+@item USE_C_ALLOCA
+Define this macro if GCC should use the C implementation of @code{alloca}
+provided by @file{libiberty.a}. This only affects how some parts of the
+compiler itself allocate memory. It does not change code generation.
+
+When GCC is built with a compiler other than itself, the C @code{alloca}
+is always used. This is because most other implementations have serious
+bugs. You should define this macro only on a system where no
+stack-based @code{alloca} can possibly work. For instance, if a system
+has a small limit on the size of the stack, GCC's builtin @code{alloca}
+will not work reliably.
+
+@item COLLECT2_HOST_INITIALIZATION
+If defined, a C statement (sans semicolon) that performs host-dependent
+initialization when @code{collect2} is being initialized.
+
+@item GCC_DRIVER_HOST_INITIALIZATION
+If defined, a C statement (sans semicolon) that performs host-dependent
+initialization when a compilation driver is being initialized.
@item SMALL_ARG_MAX
Define this macro if the host system has a small limit on the total
@@ -123,8 +202,3 @@ In addition, if @command{configure} generates an incorrect definition of
any of the macros in @file{auto-host.h}, you can override that
definition in a host configuration header. If you need to do this,
first see if it is possible to fix @command{configure}.
-
-If you need to define only a few of these macros, and they have simple
-definitions, consider using the @code{xm_defines} variable in your
-@file{config.gcc} entry instead of creating a host configuration header.
-@xref{System Config}.
diff --git a/contrib/gcc/doc/include/gcc-common.texi b/contrib/gcc/doc/include/gcc-common.texi
index 0d2cae653b22..49725ab9ad1b 100644
--- a/contrib/gcc/doc/include/gcc-common.texi
+++ b/contrib/gcc/doc/include/gcc-common.texi
@@ -1,10 +1,10 @@
-@c Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+@c Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@c Common values used in the GCC manuals:
-@set version-GCC 3.3.3
+@set version-GCC 3.4.2
@c DEVELOPMENT is set to indicate an in-development version,
@c as compared to a release version. When making a release
@@ -32,10 +32,23 @@
@end macro
@end ifnottex
-@c For FSF printing, define FSFPRINT. Also update the ISBNs and last
-@c printing dates in gcc.texi and gccint.texi.
+@c For FSF printing, define FSFPRINT. Also update the ISBN and last
+@c printing date for the manual being printed.
@c @set FSFPRINT
@ifset FSFPRINT
@smallbook
@finalout
+@c Cause even numbered pages to be printed on the left hand side of
+@c the page and odd numbered pages to be printed on the right hand
+@c side of the page. Using this, you can print on both sides of a
+@c sheet of paper and have the text on the same part of the sheet.
+
+@c The text on right hand pages is pushed towards the right hand
+@c margin and the text on left hand pages is pushed toward the left
+@c hand margin.
+@c (To provide the reverse effect, set bindingoffset to -0.75in.)
+@tex
+\global\bindingoffset=0.75in
+\global\normaloffset =0.75in
+@end tex
@end ifset
diff --git a/contrib/gcc/doc/include/texinfo.tex b/contrib/gcc/doc/include/texinfo.tex
index e9293f3b9d5f..9500f1867b48 100644
--- a/contrib/gcc/doc/include/texinfo.tex
+++ b/contrib/gcc/doc/include/texinfo.tex
@@ -3,7 +3,7 @@
% Load plain if necessary, i.e., if running under initex.
\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
%
-\def\texinfoversion{2003-05-04.08}
+\def\texinfoversion{2003-12-21.10}
%
% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
@@ -23,21 +23,16 @@
% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
% Boston, MA 02111-1307, USA.
%
-% In other words, you are welcome to use, share and improve this program.
-% You are forbidden to forbid anyone else to use, share and improve
-% what you give them. Help stamp out software-hoarding!
-%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction. (This has been our intent since Texinfo was invented.)
+%
% Please try the latest version of texinfo.tex before submitting bug
% reports; you can get the latest version from:
-% ftp://ftp.gnu.org/gnu/texinfo/texinfo.tex
-% (and all GNU mirrors, see http://www.gnu.org/order/ftp.html)
+% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
% ftp://tug.org/tex/texinfo.tex
-% (and all CTAN mirrors, see http://www.ctan.org),
-% and /home/gd/gnu/doc/texinfo.tex on the GNU machines.
-%
-% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
-%
-% The texinfo.tex in any given Texinfo distribution could well be out
+% (and all CTAN mirrors, see http://www.ctan.org).
+% The texinfo.tex in any given distribution could well be out
% of date, so if that's what you're using, please check.
%
% Send bug reports to bug-texinfo@gnu.org. Please include including a
@@ -59,6 +54,9 @@
% It is possible to adapt texinfo.tex for other languages, to some
% extent. You can get the existing language-specific files from the
% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
\message{Loading texinfo [version \texinfoversion]:}
@@ -85,10 +83,13 @@
\let\ptexend=\end
\let\ptexequiv=\equiv
\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
\let\ptexgtr=>
\let\ptexhat=^
\let\ptexi=\i
\let\ptexindent=\indent
+\let\ptexnoindent=\noindent
+\let\ptexinsert=\insert
\let\ptexlbrace=\{
\let\ptexless=<
\let\ptexplus=+
@@ -101,6 +102,15 @@
% starts a new line in the output.
\newlinechar = `^^J
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+ \let\linenumber = \empty % Pre-3.0.
+\else
+ \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
% Set up fixed words for English if not already set.
\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
@@ -139,30 +149,28 @@
\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi
\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi
\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi
-\ifx\putwordDeftypevar\undefined\gdef\putwordDeftypevar{Variable}\fi
\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
-\ifx\putwordDeftypefun\undefined\gdef\putwordDeftypefun{Function}\fi
% In some macros, we cannot use the `\? notation---the left quote is
% in some cases the escape char.
\chardef\colonChar = `\:
\chardef\commaChar = `\,
\chardef\dotChar = `\.
-\chardef\equalChar = `\=
\chardef\exclamChar= `\!
\chardef\questChar = `\?
\chardef\semiChar = `\;
-\chardef\spaceChar = `\ %
\chardef\underChar = `\_
+\chardef\spaceChar = `\ %
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode\spaceChar=\spacecat}
+
% Ignore a token.
%
\def\gobble#1{}
-% True if #1 is the empty string, i.e., called like `\ifempty{}'.
-%
-\def\ifempty#1{\ifemptyx #1\emptymarkA\emptymarkB}%
-\def\ifemptyx#1#2\emptymarkB{\ifx #1\emptymarkA}%
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
% Hyphenation fixes.
\hyphenation{ap-pen-dix}
@@ -176,6 +184,41 @@
\newdimen\normaloffset
\newdimen\pagewidth \newdimen\pageheight
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
% Sometimes it is convenient to have everything in the transcript file
% and nothing on the terminal. We don't just call \tracingall here,
% since that produces some useless output on the terminal. We also make
@@ -200,7 +243,7 @@
\tracingassigns1
\fi
\tracingcommands3 % 3 gives us more in etex
- \errorcontextlines\maxdimen
+ \errorcontextlines16
}%
% add check for \lastpenalty to plain's definitions. If the last thing
@@ -258,7 +301,7 @@
% the page break happens to be in the middle of an example.
\shipout\vbox{%
% Do this early so pdf references go to the beginning of the page.
- \ifpdfmakepagedest \pdfmkdest{\the\pageno} \fi
+ \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
%
\ifcropmarks \vbox to \outervsize\bgroup
\hsize = \outerhsize
@@ -339,132 +382,162 @@
% the input line (except we remove a trailing comment). #1 should be a
% macro which expects an ordinary undelimited TeX argument.
%
-\def\parsearg#1{%
- \let\next = #1%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+ \def\next{#2}%
\begingroup
\obeylines
- \futurelet\temp\parseargx
-}
-
-% If the next token is an obeyed space (from an @example environment or
-% the like), remove it and recurse. Otherwise, we're done.
-\def\parseargx{%
- % \obeyedspace is defined far below, after the definition of \sepspaces.
- \ifx\obeyedspace\temp
- \expandafter\parseargdiscardspace
- \else
- \expandafter\parseargline
- \fi
+ \spaceisspace
+ #1%
+ \parseargline\empty% Insert the \empty token, see \finishparsearg below.
}
-% Remove a single space (as the delimiter token to the macro call).
-{\obeyspaces %
- \gdef\parseargdiscardspace {\futurelet\temp\parseargx}}
-
{\obeylines %
\gdef\parseargline#1^^M{%
\endgroup % End of the group started in \parsearg.
- %
- % First remove any @c comment, then any @comment.
- % Result of each macro is put in \toks0.
- \argremovec #1\c\relax %
- \expandafter\argremovecomment \the\toks0 \comment\relax %
- %
- % Call the caller's macro, saved as \next in \parsearg.
- \expandafter\next\expandafter{\the\toks0}%
+ \argremovecomment #1\comment\ArgTerm%
}%
}
-% Since all \c{,omment} does is throw away the argument, we can let TeX
-% do that for us. The \relax here is matched by the \relax in the call
-% in \parseargline; it could be more or less anything, its purpose is
-% just to delimit the argument to the \c.
-\def\argremovec#1\c#2\relax{\toks0 = {#1}}
-\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}}
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
-% \argremovec{,omment} might leave us with trailing spaces, though; e.g.,
+% Each occurence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
% @end itemize @c foo
-% will have two active spaces as part of the argument with the
-% `itemize'. Here we remove all active spaces from #1, and assign the
-% result to \toks0.
-%
-% This loses if there are any *other* active characters besides spaces
-% in the argument -- _ ^ +, for example -- since they get expanded.
-% Fortunately, Texinfo does not define any such commands. (If it ever
-% does, the catcode of the characters in questionwill have to be changed
-% here.) But this means we cannot call \removeactivespaces as part of
-% \argremovec{,omment}, since @c uses \parsearg, and thus the argument
-% that \parsearg gets might well have any character at all in it.
-%
-\def\removeactivespaces#1{%
- \begingroup
- \ignoreactivespaces
- \edef\temp{#1}%
- \global\toks0 = \expandafter{\temp}%
- \endgroup
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+ \def\temp{#3}%
+ \ifx\temp\empty
+ % We cannot use \next here, as it holds the macro to run;
+ % thus we reuse \temp.
+ \let\temp\finishparsearg
+ \else
+ \let\temp\argcheckspaces
+ \fi
+ % Put the space token in:
+ \temp#1 #3\ArgTerm
}
-% Change the active space to expand to nothing.
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \next.
+% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
%
-\begingroup
- \obeyspaces
- \gdef\ignoreactivespaces{\obeyspaces\let =\empty}
-\endgroup
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\next\expandafter{#1}}
+% \parseargdef\foo{...}
+% is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick. --kasal, 16nov03
-\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+\def\parseargdef#1{%
+ \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+ \def#2{\parsearg#1}%
+ \def#1##1%
+}
-%% These are used to keep @begin/@end levels from running away
-%% Call \inENV within environments (after a \begingroup)
-\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi}
-\def\ENVcheck{%
-\ifENV\errmessage{Still within an environment; press RETURN to continue}
-\endgroup\fi} % This is not perfect, but it should reduce lossage
+% Several utility definitions with active space:
+{
+ \obeyspaces
+ \gdef\obeyedspace{ }
-% @begin foo is the same as @foo, for now.
-\newhelp\EMsimple{Press RETURN to continue.}
+ % Make each space character in the input produce a normal interword
+ % space in the output. Don't allow a line break at this space, as this
+ % is used only in environments like @example, where each line of input
+ % should produce a line of output anyway.
+ %
+ \gdef\sepspaces{\obeyspaces\let =\tie}
-\outer\def\begin{\parsearg\beginxxx}
+ % If an index command is used in an @example environment, any spaces
+ % therein should become regular spaces in the raw index file, not the
+ % expansion of \tie (\leavevmode \penalty \@M \ ).
+ \gdef\unsepspaces{\let =\space}
+}
-\def\beginxxx #1{%
-\expandafter\ifx\csname #1\endcsname\relax
-{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else
-\csname #1\endcsname\fi}
-% @end foo executes the definition of \Efoo.
-%
-\def\end{\parsearg\endxxx}
-\def\endxxx #1{%
- \removeactivespaces{#1}%
- \edef\endthing{\the\toks0}%
- %
- \expandafter\ifx\csname E\endthing\endcsname\relax
- \expandafter\ifx\csname \endthing\endcsname\relax
- % There's no \foo, i.e., no ``environment'' foo.
- \errhelp = \EMsimple
- \errmessage{Undefined command `@end \endthing'}%
- \else
- \unmatchedenderror\endthing
- \fi
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex. It's used like this:
+%
+% \envdef\foo{...}
+% \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo. \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches. The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as enviroments; they don't open a group. (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At runtime, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+ \def\temp{#1}%
+ \ifx\thisenv\temp
\else
- % Everything's ok; the right environment has been started.
- \csname E\endthing\endcsname
+ \badenverr
\fi
}
-% There is an environment #1, but it hasn't been started. Give an error.
-%
-\def\unmatchedenderror#1{%
+% Evironment mismatch, #1 expected:
+\def\badenverr{%
\errhelp = \EMsimple
- \errmessage{This `@end #1' doesn't have a matching `@#1'}%
+ \errmessage{This command can appear only \inenvironment\temp,
+ not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+ \ifx#1\empty
+ out of any environment%
+ \else
+ in environment \expandafter\string#1%
+ \fi
}
-% Define the control sequence \E#1 to give an unmatched @end error.
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
%
-\def\defineunmatchedend#1{%
- \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}%
+\parseargdef\end{%
+ \if 1\csname iscond.#1\endcsname
+ \else
+ % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+ \expandafter\checkenv\csname#1\endcsname
+ \csname E#1\endcsname
+ \endgroup
+ \fi
}
+\newhelp\EMsimple{Press RETURN to continue.}
+
%% Simple single-character @ commands
@@ -496,6 +569,9 @@
!gdef!rbraceatcmd[@}]%
!endgroup
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
\let\, = \c
@@ -505,10 +581,12 @@
\let\ubaraccent = \b
\let\udotaccent = \d
-% Other special characters: @questiondown @exclamdown
+% Other special characters: @questiondown @exclamdown @ordf @ordm
% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
\def\questiondown{?`}
\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
% Dotless i and dotless j, used for accents.
\def\imacro{i}
@@ -521,6 +599,20 @@
\fi\fi
}
+% @LaTeX{} logo. (@TeX{} is defined in plain.tex.)
+% Not quite the same results as the definition in latex.ltx, since we
+% use a different font for the raised A; it's most convenient for us to
+% go two sizes down, rather than using the \scriptstyle font (since we
+% don't reset \scriptstyle and \scriptscriptstyle).
+%
+\def\LaTeX{%
+ L\kern-.36em
+ {\setbox0=\hbox{T}%
+ \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
+ \kern-.15em
+ \TeX
+}
+
% Be sure we're in horizontal mode when doing a tie, since we make space
% equivalent to this in @example-like environments. Otherwise, a space
% at the beginning of a line will start with \penalty -- and
@@ -574,59 +666,14 @@
\newbox\groupbox
\def\vfilllimit{0.7}
%
-\def\group{\begingroup
- \ifnum\catcode13=\active \else
+\envdef\group{%
+ \ifnum\catcode`\^^M=\active \else
\errhelp = \groupinvalidhelp
\errmessage{@group invalid in context where filling is enabled}%
\fi
- %
- % The \vtop we start below produces a box with normal height and large
- % depth; thus, TeX puts \baselineskip glue before it, and (when the
- % next line of text is done) \lineskip glue after it. (See p.82 of
- % the TeXbook.) Thus, space below is not quite equal to space
- % above. But it's pretty close.
- \def\Egroup{%
- \egroup % End the \vtop.
- % \dimen0 is the vertical size of the group's box.
- \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox
- % \dimen2 is how much space is left on the page (more or less).
- \dimen2 = \pageheight \advance\dimen2 by -\pagetotal
- % if the group doesn't fit on the current page, and it's a big big
- % group, force a page break.
- \ifdim \dimen0 > \dimen2
- \ifdim \pagetotal < \vfilllimit\pageheight
- \page
- \fi
- \fi
- \copy\groupbox
- \endgroup % End the \group.
- }%
+ \startsavinginserts
%
\setbox\groupbox = \vtop\bgroup
- % We have to put a strut on the last line in case the @group is in
- % the midst of an example, rather than completely enclosing it.
- % Otherwise, the interline space between the last line of the group
- % and the first line afterwards is too small. But we can't put the
- % strut in \Egroup, since there it would be on a line by itself.
- % Hence this just inserts a strut at the beginning of each line.
- \everypar = {\strut}%
- %
- % Since we have a strut on every line, we don't need any of TeX's
- % normal interline spacing.
- \offinterlineskip
- %
- % OK, but now we have to do something about blank
- % lines in the input in @example-like environments, which normally
- % just turn into \lisppar, which will insert no space now that we've
- % turned off the interline space. Simplest is to make them be an
- % empty paragraph.
- \ifx\par\lisppar
- \edef\par{\leavevmode \par}%
- %
- % Reset ^^M's definition to new definition of \par.
- \obeylines
- \fi
- %
% Do @comment since we are called inside an environment such as
% @example, where each end-of-line in the input causes an
% end-of-line in the output. We don't want the end-of-line after
@@ -636,6 +683,32 @@
\comment
}
%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it. Thus, space below is not quite equal to space
+% above. But it's pretty close.
+\def\Egroup{%
+ % To get correct interline space between the last line of the group
+ % and the first line afterwards, we have to propagate \prevdepth.
+ \endgraf % Not \par, as it may have been set to \lisppar.
+ \global\dimen1 = \prevdepth
+ \egroup % End the \vtop.
+ % \dimen0 is the vertical size of the group's box.
+ \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox
+ % \dimen2 is how much space is left on the page (more or less).
+ \dimen2 = \pageheight \advance\dimen2 by -\pagetotal
+ % if the group doesn't fit on the current page, and it's a big big
+ % group, force a page break.
+ \ifdim \dimen0 > \dimen2
+ \ifdim \pagetotal < \vfilllimit\pageheight
+ \page
+ \fi
+ \fi
+ \box\groupbox
+ \prevdepth = \dimen1
+ \checkinserts
+}
+%
% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
% message, so this ends up printing `@group can only ...'.
%
@@ -648,10 +721,8 @@ where each line of input produces a line of output.}
\newdimen\mil \mil=0.001in
-\def\need{\parsearg\needx}
-
% Old definition--didn't work.
-%\def\needx #1{\par %
+%\parseargdef\need{\par %
%% This method tries to make TeX break the page naturally
%% if the depth of the box does not fit.
%{\baselineskip=0pt%
@@ -659,7 +730,7 @@ where each line of input produces a line of output.}
%\prevdepth=-1000pt
%}}
-\def\needx#1{%
+\parseargdef\need{%
% Ensure vertical mode, so we don't make a big box in the middle of a
% paragraph.
\par
@@ -698,35 +769,10 @@ where each line of input produces a line of output.}
\fi
}
-% @br forces paragraph break
+% @br forces paragraph break (and is undocumented).
\let\br = \par
-% @dots{} output an ellipsis using the current font.
-% We do .5em per period so that it has the same spacing in a typewriter
-% font as three actual period characters.
-%
-\def\dots{%
- \leavevmode
- \hbox to 1.5em{%
- \hskip 0pt plus 0.25fil minus 0.25fil
- .\hss.\hss.%
- \hskip 0pt plus 0.5fil minus 0.5fil
- }%
-}
-
-% @enddots{} is an end-of-sentence ellipsis.
-%
-\def\enddots{%
- \leavevmode
- \hbox to 2em{%
- \hskip 0pt plus 0.25fil minus 0.25fil
- .\hss.\hss.\hss.%
- \hskip 0pt plus 0.5fil minus 0.5fil
- }%
- \spacefactor=3000
-}
-
% @page forces the start of a new page.
%
\def\page{\par\vfill\supereject}
@@ -739,13 +785,11 @@ where each line of input produces a line of output.}
\newskip\exdentamount
% This defn is used inside fill environments such as @defun.
-\def\exdent{\parsearg\exdentyyy}
-\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}}
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
% This defn is used inside nofill environments such as @example.
-\def\nofillexdent{\parsearg\nofillexdentyyy}
-\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount
-\leftline{\hskip\leftskip{\rm#1}}}}
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+ \leftline{\hskip\leftskip{\rm#1}}}}
% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
% paragraph. For more general purposes, use the \margin insertion
@@ -797,8 +841,19 @@ where each line of input produces a line of output.}
}
% @include file insert text of that file as input.
-% Allow normal characters that we make active in the argument (a file name).
-\def\include{\begingroup
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+ \pushthisfilestack
+ \def\thisfile{#1}%
+ {%
+ \makevalueexpandable
+ \def\temp{\input #1 }%
+ \expandafter
+ }\temp
+ \popthisfilestack
+}
+\def\filenamecatcodes{%
\catcode`\\=\other
\catcode`~=\other
\catcode`^=\other
@@ -807,33 +862,50 @@ where each line of input produces a line of output.}
\catcode`<=\other
\catcode`>=\other
\catcode`+=\other
- \parsearg\includezzz}
-% Restore active chars for included file.
-\def\includezzz#1{\endgroup\begingroup
- % Read the included file in a group so nested @include's work.
- \def\thisfile{#1}%
- \let\value=\expandablevalue
- \input\thisfile
-\endgroup}
+ \catcode`-=\other
+}
+
+\def\pushthisfilestack{%
+ \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+ \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+ \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+ the stack of filenames is empty.}}
\def\thisfile{}
% @center line
% outputs that line, centered.
%
-\def\center{\parsearg\docenter}
-\def\docenter#1{{%
- \ifhmode \hfil\break \fi
- \advance\hsize by -\leftskip
- \advance\hsize by -\rightskip
- \line{\hfil \ignorespaces#1\unskip \hfil}%
- \ifhmode \break \fi
-}}
+\parseargdef\center{%
+ \ifhmode
+ \let\next\centerH
+ \else
+ \let\next\centerV
+ \fi
+ \next{\hfil \ignorespaces#1\unskip \hfil}%
+}
+\def\centerH#1{%
+ {%
+ \hfil\break
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{#1}%
+ \break
+ }%
+}
+\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
% @sp n outputs n lines of vertical space
-\def\sp{\parsearg\spxxx}
-\def\spxxx #1{\vskip #1\baselineskip}
+\parseargdef\sp{\vskip #1\baselineskip}
% @comment ...line which is ignored...
% @c is the same as @comment
@@ -854,8 +926,7 @@ where each line of input produces a line of output.}
\def\asisword{asis} % no translation, these are keywords
\def\noneword{none}
%
-\def\paragraphindent{\parsearg\doparagraphindent}
-\def\doparagraphindent#1{%
+\parseargdef\paragraphindent{%
\def\temp{#1}%
\ifx\temp\asisword
\else
@@ -872,8 +943,7 @@ where each line of input produces a line of output.}
% We'll use ems for NCHARS like @paragraphindent.
% It seems @exampleindent asis isn't necessary, but
% I preserve it to make it similar to @paragraphindent.
-\def\exampleindent{\parsearg\doexampleindent}
-\def\doexampleindent#1{%
+\parseargdef\exampleindent{%
\def\temp{#1}%
\ifx\temp\asisword
\else
@@ -887,21 +957,20 @@ where each line of input produces a line of output.}
% @firstparagraphindent WORD
% If WORD is `none', then suppress indentation of the first paragraph
-% after a section heading. If WORD is `insert', then do indentat such
+% after a section heading. If WORD is `insert', then do indent at such
% paragraphs.
%
% The paragraph indentation is suppressed or not by calling
-% \suppressfirstparagraphindent, which the sectioning commands do. We
-% switch the definition of this back and forth according to WORD. By
-% default, we suppress indentation.
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
%
\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
\newdimen\currentparindent
%
\def\insertword{insert}
%
-\def\firstparagraphindent{\parsearg\dofirstparagraphindent}
-\def\dofirstparagraphindent#1{%
+\parseargdef\firstparagraphindent{%
\def\temp{#1}%
\ifx\temp\noneword
\let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
@@ -921,15 +990,24 @@ where each line of input produces a line of output.}
%
\gdef\dosuppressfirstparagraphindent{%
\gdef\indent{%
- \global\let\indent=\ptexindent
- \global\everypar = {}%
+ \restorefirstparagraphindent
+ \indent
+ }%
+ \gdef\noindent{%
+ \restorefirstparagraphindent
+ \noindent
}%
\global\everypar = {%
- \kern-\parindent
- \global\let\indent=\ptexindent
- \global\everypar = {}%
+ \kern -\parindent
+ \restorefirstparagraphindent
}%
-}%
+}
+
+\gdef\restorefirstparagraphindent{%
+ \global \let \indent = \ptexindent
+ \global \let \noindent = \ptexnoindent
+ \global \everypar = {}%
+}
% @asis just yields its argument. Used with @table, for example.
@@ -937,23 +1015,18 @@ where each line of input produces a line of output.}
\def\asis#1{#1}
% @math outputs its argument in math mode.
-% We don't use $'s directly in the definition of \math because we need
-% to set catcodes according to plain TeX first, to allow for subscripts,
-% superscripts, special math chars, etc.
-%
-\let\implicitmath = $%$ font-lock fix
%
% One complication: _ usually means subscripts, but it could also mean
% an actual _ character, as in @math{@var{some_variable} + 1}. So make
-% _ within @math be active (mathcode "8000), and distinguish by seeing
-% if the current family is \slfam, which is what @var uses.
-%
-{\catcode\underChar = \active
-\gdef\mathunderscore{%
- \catcode\underChar=\active
- \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
-}}
-%
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+ \catcode\underChar = \active
+ \gdef\mathunderscore{%
+ \catcode\underChar=\active
+ \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+ }
+}
% Another complication: we want \\ (and @\) to output a \ character.
% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
% this is not advertised and we don't care. Texinfo does not
@@ -964,15 +1037,16 @@ where each line of input produces a line of output.}
%
\def\math{%
\tex
- \mathcode`\_="8000 \mathunderscore
+ \mathunderscore
\let\\ = \mathbackslash
\mathactive
- \implicitmath\finishmath}
-\def\finishmath#1{#1\implicitmath\Etex}
+ $\finishmath
+}
+\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
% Some active characters (such as <) are spaced differently in math.
-% We have to reset their definitions in case the @math was an
-% argument to a command which set the catcodes (such as @item or @section).
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
%
{
\catcode`^ = \active
@@ -988,8 +1062,33 @@ where each line of input produces a line of output.}
}
% @bullet and @minus need the same treatment as @math, just above.
-\def\bullet{\implicitmath\ptexbullet\implicitmath}
-\def\minus{\implicitmath-\implicitmath}
+\def\bullet{$\ptexbullet$}
+\def\minus{$-$}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in a typewriter
+% font as three actual period characters.
+%
+\def\dots{%
+ \leavevmode
+ \hbox to 1.5em{%
+ \hskip 0pt plus 0.25fil
+ .\hfil.\hfil.%
+ \hskip 0pt plus 0.5fil
+ }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \dots
+ \spacefactor=3000
+}
+
+% @comma{} is so commas can be inserted into text without messing up
+% Texinfo's parsing.
+%
+\let\comma = ,
% @refill is a no-op.
\let\refill=\relax
@@ -1006,7 +1105,9 @@ where each line of input produces a line of output.}
% This makes it possible to make a .fmt file for texinfo.
\def\setfilename{%
\iflinks
- \readauxfile
+ \tryauxfile
+ % Open the new aux file. TeX will close it automatically at exit.
+ \immediate\openout\auxfile=\jobname.aux
\fi % \openindices needs to do some work in any case.
\openindices
\fixbackslash % Turn off hack to swallow `\input texinfo'.
@@ -1014,11 +1115,9 @@ where each line of input produces a line of output.}
%
% If texinfo.cnf is present on the system, read it.
% Useful for site-wide @afourpaper, etc.
- % Just to be on the safe side, close the input stream before the \input.
\openin 1 texinfo.cnf
- \ifeof1 \let\temp=\relax \else \def\temp{\input texinfo.cnf }\fi
- \closein1
- \temp
+ \ifeof 1 \else \input texinfo.cnf \fi
+ \closein 1
%
\comment % Ignore the actual filename.
}
@@ -1065,6 +1164,7 @@ where each line of input produces a line of output.}
\pdftrue
\pdfoutput = 1
\input pdfcolor
+ \pdfcatalog{/PageMode /UseOutlines}%
\def\dopdfimage#1#2#3{%
\def\imagewidth{#2}%
\def\imageheight{#3}%
@@ -1085,7 +1185,13 @@ where each line of input produces a line of output.}
\ifnum\pdftexversion < 14 \else
\pdfrefximage \pdflastximage
\fi}
- \def\pdfmkdest#1{{\normalturnoffactive \pdfdest name{#1} xyz}}
+ \def\pdfmkdest#1{{%
+ % We have to set dummies so commands such as @code in a section title
+ % aren't expanded.
+ \atdummies
+ \normalturnoffactive
+ \pdfdest name{#1} xyz%
+ }}
\def\pdfmkpgn#1{#1}
\let\linkcolor = \Blue % was Cyan, but that seems light?
\def\endlink{\Black\pdfendlink}
@@ -1094,48 +1200,86 @@ where each line of input produces a line of output.}
\def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
\else \csname#1\endcsname \fi}
\def\advancenumber#1{\tempnum=\expnumber{#1}\relax
- \advance\tempnum by1
+ \advance\tempnum by 1
\expandafter\xdef\csname#1\endcsname{\the\tempnum}}
- \def\pdfmakeoutlines{{%
- \openin 1 \jobname.toc
- \ifeof 1\else\begingroup
- \closein 1
+ %
+ % #1 is the section text. #2 is the pdf expression for the number
+ % of subentries (or empty, for subsubsections). #3 is the node
+ % text, which might be empty if this toc entry had no
+ % corresponding node. #4 is the page number.
+ %
+ \def\dopdfoutline#1#2#3#4{%
+ % Generate a link to the node text if that exists; else, use the
+ % page number. We could generate a destination for the section
+ % text in the case where a section has no node, but it doesn't
+ % seem worthwhile, since most documents are normally structured.
+ \def\pdfoutlinedest{#3}%
+ \ifx\pdfoutlinedest\empty \def\pdfoutlinedest{#4}\fi
+ %
+ \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{#1}%
+ }
+ %
+ \def\pdfmakeoutlines{%
+ \begingroup
% Thanh's hack / proper braces in bookmarks
\edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
\edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
%
- \def\chapentry ##1##2##3{}
- \def\secentry ##1##2##3##4{\advancenumber{chap##2}}
- \def\subsecentry ##1##2##3##4##5{\advancenumber{sec##2.##3}}
- \def\subsubsecentry ##1##2##3##4##5##6{\advancenumber{subsec##2.##3.##4}}
- \let\appendixentry = \chapentry
- \let\unnumbchapentry = \chapentry
- \let\unnumbsecentry = \secentry
- \let\unnumbsubsecentry = \subsecentry
- \let\unnumbsubsubsecentry = \subsubsecentry
+ % Read toc silently, to get counts of subentries for \pdfoutline.
+ \def\numchapentry##1##2##3##4{%
+ \def\thischapnum{##2}%
+ \let\thissecnum\empty
+ \let\thissubsecnum\empty
+ }%
+ \def\numsecentry##1##2##3##4{%
+ \advancenumber{chap\thischapnum}%
+ \def\thissecnum{##2}%
+ \let\thissubsecnum\empty
+ }%
+ \def\numsubsecentry##1##2##3##4{%
+ \advancenumber{sec\thissecnum}%
+ \def\thissubsecnum{##2}%
+ }%
+ \def\numsubsubsecentry##1##2##3##4{%
+ \advancenumber{subsec\thissubsecnum}%
+ }%
+ \let\thischapnum\empty
+ \let\thissecnum\empty
+ \let\thissubsecnum\empty
+ %
+ % use \def rather than \let here because we redefine \chapentry et
+ % al. a second time, below.
+ \def\appentry{\numchapentry}%
+ \def\appsecentry{\numsecentry}%
+ \def\appsubsecentry{\numsubsecentry}%
+ \def\appsubsubsecentry{\numsubsubsecentry}%
+ \def\unnchapentry{\numchapentry}%
+ \def\unnsecentry{\numsecentry}%
+ \def\unnsubsecentry{\numsubsecentry}%
+ \def\unnsubsubsecentry{\numsubsubsecentry}%
\input \jobname.toc
- \def\chapentry ##1##2##3{%
- \pdfoutline goto name{\pdfmkpgn{##3}}count-\expnumber{chap##2}{##1}}
- \def\secentry ##1##2##3##4{%
- \pdfoutline goto name{\pdfmkpgn{##4}}count-\expnumber{sec##2.##3}{##1}}
- \def\subsecentry ##1##2##3##4##5{%
- \pdfoutline goto name{\pdfmkpgn{##5}}count-\expnumber{subsec##2.##3.##4}{##1}}
- \def\subsubsecentry ##1##2##3##4##5##6{%
- \pdfoutline goto name{\pdfmkpgn{##6}}{##1}}
- \let\appendixentry = \chapentry
- \let\unnumbchapentry = \chapentry
- \let\unnumbsecentry = \secentry
- \let\unnumbsubsecentry = \subsecentry
- \let\unnumbsubsubsecentry = \subsubsecentry
%
- % Make special characters normal for writing to the pdf file.
+ % Read toc second time, this time actually producing the outlines.
+ % The `-' means take the \expnumber as the absolute number of
+ % subentries, which we calculated on our first read of the .toc above.
+ %
+ % We use the node names as the destinations.
+ \def\numchapentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+ \def\numsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+ \def\numsubsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+ \def\numsubsubsecentry##1##2##3##4{% count is always zero
+ \dopdfoutline{##1}{}{##3}{##4}}%
%
+ % Make special characters normal for writing to the pdf file.
\indexnofonts
- \let\tt=\relax
\turnoffactive
\input \jobname.toc
- \endgroup\fi
- }}
+ \endgroup
+ }
+ %
\def\makelinks #1,{%
\def\params{#1}\def\E{END}%
\ifx\params\E
@@ -1184,7 +1328,7 @@ where each line of input produces a line of output.}
\def\pdfurl#1{%
\begingroup
\normalturnoffactive\def\@{@}%
- \let\value=\expandablevalue
+ \makevalueexpandable
\leavevmode\Red
\startlink attr{/Border [0 0 0]}%
user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
@@ -1219,16 +1363,34 @@ where each line of input produces a line of output.}
\message{fonts,}
-% Font-change commands.
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+ \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+ \csname ten#1\endcsname % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
% Texinfo sort of supports the sans serif font style, which plain TeX does not.
-% So we set up a \sf analogous to plain's \rm, etc.
+% So we set up a \sf.
\newfam\sffam
-\def\sf{\fam=\sffam \tensf}
+\def\sf{\fam=\sffam \setfontstyle{sf}}
\let\li = \sf % Sometimes we call it \li, not \sf.
-% We don't need math for this one.
-\def\ttsl{\tenttsl}
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
% Default leading.
\newdimen\textleading \textleading = 13.2pt
@@ -1279,6 +1441,7 @@ where each line of input produces a line of output.}
\def\scshape{csc}
\def\scbshape{csc}
+% Text fonts (11.2pt, magstep1).
\newcount\mainmagstep
\ifx\bigger\relax
% not really supported.
@@ -1290,10 +1453,6 @@ where each line of input produces a line of output.}
\setfont\textrm\rmshape{10}{\mainmagstep}
\setfont\texttt\ttshape{10}{\mainmagstep}
\fi
-% Instead of cmb10, you may want to use cmbx10.
-% cmbx10 is a prettier font on its own, but cmb10
-% looks better when embedded in a line with cmr10
-% (in Bob's opinion).
\setfont\textbf\bfshape{10}{\mainmagstep}
\setfont\textit\itshape{10}{\mainmagstep}
\setfont\textsl\slshape{10}{\mainmagstep}
@@ -1303,10 +1462,11 @@ where each line of input produces a line of output.}
\font\texti=cmmi10 scaled \mainmagstep
\font\textsy=cmsy10 scaled \mainmagstep
-% A few fonts for @defun, etc.
-\setfont\defbf\bxshape{10}{\magstep1} %was 1314
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}
\setfont\deftt\ttshape{10}{\magstep1}
-\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf}
+\setfont\defttsl\ttslshape{10}{\magstep1}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
% Fonts for indices, footnotes, small examples (9pt).
\setfont\smallrm\rmshape{9}{1000}
@@ -1332,7 +1492,7 @@ where each line of input produces a line of output.}
\font\smalleri=cmmi8
\font\smallersy=cmsy8
-% Fonts for title page:
+% Fonts for title page (20.4pt):
\setfont\titlerm\rmbshape{12}{\magstep3}
\setfont\titleit\itbshape{10}{\magstep4}
\setfont\titlesl\slbshape{10}{\magstep4}
@@ -1378,11 +1538,21 @@ where each line of input produces a line of output.}
\setfont\ssecttsl\ttslshape{10}{1315}
\setfont\ssecsf\sfbshape{12}{\magstephalf}
\let\ssecbf\ssecrm
-\setfont\ssecsc\scbshape{10}{\magstep1}
+\setfont\ssecsc\scbshape{10}{1315}
\font\sseci=cmmi12 scaled \magstephalf
\font\ssecsy=cmsy10 scaled 1315
-% The smallcaps and symbol fonts should actually be scaled \magstep1.5,
-% but that is not a standard magnification.
+
+% Reduced fonts for @acro in text (10pt).
+\setfont\reducedrm\rmshape{10}{1000}
+\setfont\reducedtt\ttshape{10}{1000}
+\setfont\reducedbf\bfshape{10}{1000}
+\setfont\reducedit\itshape{10}{1000}
+\setfont\reducedsl\slshape{10}{1000}
+\setfont\reducedsf\sfshape{10}{1000}
+\setfont\reducedsc\scshape{10}{1000}
+\setfont\reducedttsl\ttslshape{10}{1000}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
% In order for the font changes to affect most math symbols and letters,
% we have to define the \textfont of the standard families. Since
@@ -1397,50 +1567,72 @@ where each line of input produces a line of output.}
}
% The font-changing commands redefine the meanings of \tenSTYLE, instead
-% of just \STYLE. We do this so that font changes will continue to work
-% in math mode, where it is the current \fam that is relevant in most
-% cases, not the current font. Plain TeX does \def\bf{\fam=\bffam
-% \tenbf}, for example. By redefining \tenbf, we obviate the need to
-% redefine \bf itself.
+% of just \STYLE. We do this because \STYLE needs to also set the
+% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower). These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
\def\textfonts{%
\let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
\let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
- \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy \let\tenttsl=\textttsl
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+ \let\tenttsl=\textttsl
+ \def\lsize{reduced}\def\lllsize{smaller}%
\resetmathfonts \setleading{\textleading}}
\def\titlefonts{%
\let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
\let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
\let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
\let\tenttsl=\titlettsl
+ \def\lsize{chap}\def\lllsize{subsec}%
\resetmathfonts \setleading{25pt}}
\def\titlefont#1{{\titlefonts\rm #1}}
\def\chapfonts{%
\let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
\let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
\let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy \let\tenttsl=\chapttsl
+ \def\lsize{sec}\def\lllsize{text}%
\resetmathfonts \setleading{19pt}}
\def\secfonts{%
\let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
\let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
- \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy \let\tenttsl=\secttsl
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+ \let\tenttsl=\secttsl
+ \def\lsize{subsec}\def\lllsize{reduced}%
\resetmathfonts \setleading{16pt}}
\def\subsecfonts{%
\let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
\let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
- \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy \let\tenttsl=\ssecttsl
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+ \let\tenttsl=\ssecttsl
+ \def\lsize{text}\def\lllsize{small}%
\resetmathfonts \setleading{15pt}}
-\let\subsubsecfonts = \subsecfonts % Maybe make sssec fonts scaled magstephalf?
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+ \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+ \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+ \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+ \let\tenttsl=\reducedttsl
+ \def\lsize{small}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
\def\smallfonts{%
\let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
\let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
\let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
\let\tenttsl=\smallttsl
+ \def\lsize{smaller}\def\lllsize{smaller}%
\resetmathfonts \setleading{10.5pt}}
\def\smallerfonts{%
\let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
\let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
\let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
\let\tenttsl=\smallerttsl
+ \def\lsize{smaller}\def\lllsize{smaller}%
\resetmathfonts \setleading{9.5pt}}
% Set the fonts to use with the @small... environments.
@@ -1449,7 +1641,7 @@ where each line of input produces a line of output.}
% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample
% can fit this many characters:
% 8.5x11=86 smallbook=72 a4=90 a5=69
-% If we use \smallerfonts (8pt), then we can fit this many characters:
+% If we use \scriptfonts (8pt), then we can fit this many characters:
% 8.5x11=90+ smallbook=80 a4=90+ a5=77
% For me, subjectively, the few extra characters that fit aren't worth
% the additional smallness of 8pt. So I'm making the default 9pt.
@@ -1457,14 +1649,13 @@ where each line of input produces a line of output.}
% By the way, for comparison, here's what fits with @example (10pt):
% 8.5x11=71 smallbook=60 a4=75 a5=58
%
-% I wish we used A4 paper on this side of the Atlantic.
-%
+% I wish the USA used A4 paper.
% --karl, 24jan03.
% Set up the default fonts, so we can use them for creating boxes.
%
-\textfonts
+\textfonts \rm
% Define these so they can be easily changed for other fonts.
\def\angleleft{$\langle$}
@@ -1475,7 +1666,7 @@ where each line of input produces a line of output.}
% Fonts for short table of contents.
\setfont\shortcontrm\rmshape{12}{1000}
-\setfont\shortcontbf\bxshape{12}{1000}
+\setfont\shortcontbf\bfshape{10}{\magstep1} % no cmb12
\setfont\shortcontsl\slshape{12}{1000}
\setfont\shortconttt\ttshape{12}{1000}
@@ -1489,11 +1680,18 @@ where each line of input produces a line of output.}
\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
+% like \smartslanted except unconditionally uses \ttsl.
+% @var is set to this for defun arguments.
+\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally use \sl. We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+
\let\i=\smartitalic
\let\var=\smartslanted
\let\dfn=\smartslanted
\let\emph=\smartitalic
-\let\cite=\smartslanted
\def\b#1{{\bf #1}}
\let\strong=\b
@@ -1520,7 +1718,6 @@ where each line of input produces a line of output.}
{\tt \rawbackslash \frenchspacing #1}%
\null
}
-\let\ttfont=\t
\def\samp#1{`\tclose{#1}'\null}
\setfont\keyrm\rmshape{8}{1000}
\font\keysy=cmsy9
@@ -1561,7 +1758,7 @@ where each line of input produces a line of output.}
\null
}
-% We *must* turn on hyphenation at `-' and `_' in \code.
+% We *must* turn on hyphenation at `-' and `_' in @code.
% Otherwise, it is too hard to avoid overfull hboxes
% in the Emacs manual, the Library manual, etc.
@@ -1579,10 +1776,6 @@ where each line of input produces a line of output.}
\catcode`\_=\active \let_\codeunder
\codex
}
- %
- % If we end up with any active - characters when handling the index,
- % just treat them as a normal -.
- \global\def\indexbreaks{\catcode`\-=\active \let-\realdash}
}
\def\realdash{-}
@@ -1606,8 +1799,7 @@ where each line of input produces a line of output.}
% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
% `example' (@kbd uses ttsl only inside of @example and friends),
% or `code' (@kbd uses normal tty font always).
-\def\kbdinputstyle{\parsearg\kbdinputstylexxx}
-\def\kbdinputstylexxx#1{%
+\parseargdef\kbdinputstyle{%
\def\arg{#1}%
\ifx\arg\worddistinct
\gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
@@ -1707,19 +1899,26 @@ where each line of input produces a line of output.}
\def\sc#1{{\smallcaps#1}} % smallcaps font
\def\ii#1{{\it #1}} % italic font
-% @acronym downcases the argument and prints in smallcaps.
-\def\acronym#1{{\smallcaps \lowercase{#1}}}
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+ {\selectfonts\lsize #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+}
-% @pounds{} is a sterling sign.
+% @pounds{} is a sterling sign, which is in the CM italic font.
+%
\def\pounds{{\it\$}}
-% @registeredsymbol - R in a circle. For now, only works in text size;
-% we'd have to redo the font mechanism to change the \scriptstyle and
-% \scriptscriptstyle font sizes to make it look right in headings.
+% @registeredsymbol - R in a circle. The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
% Adapted from the plain.tex definition of \copyright.
%
\def\registeredsymbol{%
- $^{{\ooalign{\hfil\raise.07ex\hbox{$\scriptstyle\rm R$}\hfil\crcr\Orb}}%
+ $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+ \hfil\crcr\Orb}}%
}$%
}
@@ -1741,87 +1940,102 @@ where each line of input produces a line of output.}
\newif\ifsetshortcontentsaftertitlepage
\let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
-\def\shorttitlepage{\parsearg\shorttitlepagezzz}
-\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
\endgroup\page\hbox{}\page}
-\def\titlepage{\begingroup \parindent=0pt \textfonts
- \let\subtitlerm=\tenrm
- \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}%
- %
- \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
- \let\tt=\authortt}%
- %
- % Leave some space at the very top of the page.
- \vglue\titlepagetopglue
- %
- % Now you can print the title using @title.
- \def\title{\parsearg\titlezzz}%
- \def\titlezzz##1{\leftline{\titlefonts\rm ##1}
- % print a rule at the page bottom also.
- \finishedtitlepagefalse
- \vskip4pt \hrule height 4pt width \hsize \vskip4pt}%
- % No rule at page bottom unless we print one at the top with @title.
- \finishedtitlepagetrue
- %
- % Now you can put text using @subtitle.
- \def\subtitle{\parsearg\subtitlezzz}%
- \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}%
- %
- % @author should come last, but may come many times.
- \def\author{\parsearg\authorzzz}%
- \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi
- {\authorfont \leftline{##1}}}%
- %
- % Most title ``pages'' are actually two pages long, with space
- % at the top of the second. We don't want the ragged left on the second.
- \let\oldpage = \page
- \def\page{%
+\envdef\titlepage{%
+ % Open one extra group, as we want to close it in the middle of \Etitlepage.
+ \begingroup
+ \parindent=0pt \textfonts
+ % Leave some space at the very top of the page.
+ \vglue\titlepagetopglue
+ % No rule at page bottom unless we print one at the top with @title.
+ \finishedtitlepagetrue
+ %
+ % Most title ``pages'' are actually two pages long, with space
+ % at the top of the second. We don't want the ragged left on the second.
+ \let\oldpage = \page
+ \def\page{%
\iffinishedtitlepage\else
- \finishtitlepage
+ \finishtitlepage
\fi
- \oldpage
\let\page = \oldpage
- \hbox{}}%
-% \def\page{\oldpage \hbox{}}
+ \page
+ \null
+ }%
}
\def\Etitlepage{%
- \iffinishedtitlepage\else
- \finishtitlepage
- \fi
- % It is important to do the page break before ending the group,
- % because the headline and footline are only empty inside the group.
- % If we use the new definition of \page, we always get a blank page
- % after the title page, which we certainly don't want.
- \oldpage
- \endgroup
- %
- % Need this before the \...aftertitlepage checks so that if they are
- % in effect the toc pages will come out with page numbers.
- \HEADINGSon
- %
- % If they want short, they certainly want long too.
- \ifsetshortcontentsaftertitlepage
- \shortcontents
- \contents
- \global\let\shortcontents = \relax
- \global\let\contents = \relax
- \fi
- %
- \ifsetcontentsaftertitlepage
- \contents
- \global\let\contents = \relax
- \global\let\shortcontents = \relax
- \fi
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ % It is important to do the page break before ending the group,
+ % because the headline and footline are only empty inside the group.
+ % If we use the new definition of \page, we always get a blank page
+ % after the title page, which we certainly don't want.
+ \oldpage
+ \endgroup
+ %
+ % Need this before the \...aftertitlepage checks so that if they are
+ % in effect the toc pages will come out with page numbers.
+ \HEADINGSon
+ %
+ % If they want short, they certainly want long too.
+ \ifsetshortcontentsaftertitlepage
+ \shortcontents
+ \contents
+ \global\let\shortcontents = \relax
+ \global\let\contents = \relax
+ \fi
+ %
+ \ifsetcontentsaftertitlepage
+ \contents
+ \global\let\contents = \relax
+ \global\let\shortcontents = \relax
+ \fi
}
\def\finishtitlepage{%
- \vskip4pt \hrule height 2pt width \hsize
- \vskip\titlepagebottomglue
- \finishedtitlepagetrue
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
}
+%%% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
+ \let\tt=\authortt}
+
+\parseargdef\title{%
+ \checkenv\titlepage
+ \leftline{\titlefonts\rm #1}
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+ \checkenv\titlepage
+ {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+\parseargdef\author{%
+ \def\temp{\quotation}%
+ \ifx\thisenv\temp
+ This edition of the manual is dedicated to Karl Berry who should
+ really make affiliations work.
+ \else
+ \checkenv\titlepage
+ \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+ {\authorfont \leftline{#1}}%
+ \fi
+}
+
+
%%% Set up page headings and footings.
\let\thispage=\folio
@@ -1831,7 +2045,7 @@ where each line of input produces a line of output.}
\newtoks\evenfootline % footline on even pages
\newtoks\oddfootline % footline on odd pages
-% Now make Tex use those variables
+% Now make TeX use those variables
\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
\else \the\evenheadline \fi}}
\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
@@ -1845,32 +2059,27 @@ where each line of input produces a line of output.}
% @evenfooting @thisfile||
% @oddfooting ||@thisfile
-\def\evenheading{\parsearg\evenheadingxxx}
-\def\oddheading{\parsearg\oddheadingxxx}
-\def\everyheading{\parsearg\everyheadingxxx}
-\def\evenfooting{\parsearg\evenfootingxxx}
-\def\oddfooting{\parsearg\oddfootingxxx}
-\def\everyfooting{\parsearg\everyfootingxxx}
-
-{\catcode`\@=0 %
-
-\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish}
-\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{%
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
-\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish}
-\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{%
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
-\gdef\everyheadingxxx#1{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
-\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish}
-\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{%
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
-\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish}
-\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{%
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
\global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
%
% Leave some space for the footline. Hopefully ok to assume
@@ -1879,9 +2088,8 @@ where each line of input produces a line of output.}
\global\advance\vsize by -\baselineskip
}
-\gdef\everyfootingxxx#1{\oddfootingxxx{#1}\evenfootingxxx{#1}}
-%
-}% unbind the catcode of @.
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
% @headings double turns headings on for double-sided printing.
% @headings single turns headings on for single-sided printing.
@@ -1895,7 +2103,7 @@ where each line of input produces a line of output.}
\def\headings #1 {\csname HEADINGS#1\endcsname}
-\def\HEADINGSoff{
+\def\HEADINGSoff{%
\global\evenheadline={\hfil} \global\evenfootline={\hfil}
\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
\HEADINGSoff
@@ -1904,7 +2112,7 @@ where each line of input produces a line of output.}
% chapter name on inside top of right hand pages, document
% title on inside top of left hand pages, and page numbers on outside top
% edge of all pages.
-\def\HEADINGSdouble{
+\def\HEADINGSdouble{%
\global\pageno=1
\global\evenfootline={\hfil}
\global\oddfootline={\hfil}
@@ -1916,7 +2124,7 @@ where each line of input produces a line of output.}
% For single-sided printing, chapter title goes across top left of page,
% page number on top right.
-\def\HEADINGSsingle{
+\def\HEADINGSsingle{%
\global\pageno=1
\global\evenfootline={\hfil}
\global\oddfootline={\hfil}
@@ -1963,12 +2171,11 @@ where each line of input produces a line of output.}
% @settitle line... specifies the title of the document, for headings.
% It generates no output of its own.
\def\thistitle{\putwordNoTitle}
-\def\settitle{\parsearg\settitlezzz}
-\def\settitlezzz #1{\gdef\thistitle{#1}}
+\def\settitle{\parsearg{\gdef\thistitle}}
\message{tables,}
-% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x).
+% Tables -- @table, @ftable, @vtable, @item(x).
% default indentation of table text
\newdimen\tableindent \tableindent=.8in
@@ -1980,7 +2187,7 @@ where each line of input produces a line of output.}
% used internally for \itemindent minus \itemmargin
\newdimen\itemmax
-% Note @table, @vtable, and @vtable define @item, @itemx, etc., with
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
% these defs.
% They also define \itemindex
% to index the item name in whatever manner is desired (perhaps none).
@@ -1992,22 +2199,10 @@ where each line of input produces a line of output.}
\def\internalBitem{\smallbreak \parsearg\itemzzz}
\def\internalBitemx{\itemxpar \parsearg\itemzzz}
-\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz}
-\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz}
-
-\def\internalBkitem{\smallbreak \parsearg\kitemzzz}
-\def\internalBkitemx{\itemxpar \parsearg\kitemzzz}
-
-\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}%
- \itemzzz {#1}}
-
-\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}%
- \itemzzz {#1}}
-
\def\itemzzz #1{\begingroup %
\advance\hsize by -\rightskip
\advance\hsize by -\tableindent
- \setbox0=\hbox{\itemfont{#1}}%
+ \setbox0=\hbox{\itemindicate{#1}}%
\itemindex{#1}%
\nobreak % This prevents a break before @itemx.
%
@@ -2061,81 +2256,63 @@ where each line of input produces a line of output.}
\fi
}
-\def\item{\errmessage{@item while not in a table}}
-\def\itemx{\errmessage{@itemx while not in a table}}
-\def\kitem{\errmessage{@kitem while not in a table}}
-\def\kitemx{\errmessage{@kitemx while not in a table}}
-\def\xitem{\errmessage{@xitem while not in a table}}
-\def\xitemx{\errmessage{@xitemx while not in a table}}
-
-% Contains a kludge to get @end[description] to work.
-\def\description{\tablez{\dontindex}{1}{}{}{}{}}
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
% @table, @ftable, @vtable.
-\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex}
-{\obeylines\obeyspaces%
-\gdef\tablex #1^^M{%
-\tabley\dontindex#1 \endtabley}}
-
-\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex}
-{\obeylines\obeyspaces%
-\gdef\ftablex #1^^M{%
-\tabley\fnitemindex#1 \endtabley
-\def\Eftable{\endgraf\afterenvbreak\endgroup}%
-\let\Etable=\relax}}
-
-\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex}
-{\obeylines\obeyspaces%
-\gdef\vtablex #1^^M{%
-\tabley\vritemindex#1 \endtabley
-\def\Evtable{\endgraf\afterenvbreak\endgroup}%
-\let\Etable=\relax}}
-
-\def\dontindex #1{}
-\def\fnitemindex #1{\doind {fn}{\code{#1}}}%
-\def\vritemindex #1{\doind {vr}{\code{#1}}}%
-
-{\obeyspaces %
-\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup%
-\tablez{#1}{#2}{#3}{#4}{#5}{#6}}}
-
-\def\tablez #1#2#3#4#5#6{%
-\aboveenvbreak %
-\begingroup %
-\def\Edescription{\Etable}% Necessary kludge.
-\let\itemindex=#1%
-\ifnum 0#3>0 \advance \leftskip by #3\mil \fi %
-\ifnum 0#4>0 \tableindent=#4\mil \fi %
-\ifnum 0#5>0 \advance \rightskip by #5\mil \fi %
-\def\itemfont{#2}%
-\itemmax=\tableindent %
-\advance \itemmax by -\itemmargin %
-\advance \leftskip by \tableindent %
-\exdentamount=\tableindent
-\parindent = 0pt
-\parskip = \smallskipamount
-\ifdim \parskip=0pt \parskip=2pt \fi%
-\def\Etable{\endgraf\afterenvbreak\endgroup}%
-\let\item = \internalBitem %
-\let\itemx = \internalBitemx %
-\let\kitem = \internalBkitem %
-\let\kitemx = \internalBkitemx %
-\let\xitem = \internalBxitem %
-\let\xitemx = \internalBxitemx %
+\envdef\table{%
+ \let\itemindex\gobble
+ \tablex
+}
+\envdef\ftable{%
+ \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+ \tablex
+}
+\envdef\vtable{%
+ \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+ \tablex
+}
+\def\tablex#1{%
+ \def\itemindicate{#1}%
+ \parsearg\tabley
+}
+\def\tabley#1{%
+ {%
+ \makevalueexpandable
+ \edef\temp{\noexpand\tablez #1\space\space\space}%
+ \expandafter
+ }\temp \endtablez
}
+\def\tablez #1 #2 #3 #4\endtablez{%
+ \aboveenvbreak
+ \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+ \ifnum 0#2>0 \tableindent=#2\mil \fi
+ \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+ \itemmax=\tableindent
+ \advance \itemmax by -\itemmargin
+ \advance \leftskip by \tableindent
+ \exdentamount=\tableindent
+ \parindent = 0pt
+ \parskip = \smallskipamount
+ \ifdim \parskip=0pt \parskip=2pt \fi
+ \let\item = \internalBitem
+ \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
% This is the counter used by @enumerate, which is really @itemize
\newcount \itemno
-\def\itemize{\parsearg\itemizezzz}
-
-\def\itemizezzz #1{%
- \begingroup % ended by the @end itemize
- \itemizey {#1}{\Eitemize}
+\envdef\itemize{%
+ \parsearg\itemizey
}
-\def\itemizey#1#2{%
+\def\itemizey#1{%
\aboveenvbreak
\itemmax=\itemindent
\advance\itemmax by -\itemmargin
@@ -2144,7 +2321,6 @@ where each line of input produces a line of output.}
\parindent=0pt
\parskip=\smallskipamount
\ifdim\parskip=0pt \parskip=2pt \fi
- \def#2{\endgraf\afterenvbreak\endgroup}%
\def\itemcontents{#1}%
% @itemize with no arg is equivalent to @itemize @bullet.
\ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
@@ -2160,11 +2336,8 @@ where each line of input produces a line of output.}
% or number, to specify the first label in the enumerated list. No
% argument is the same as `1'.
%
-\def\enumerate{\parsearg\enumeratezzz}
-\def\enumeratezzz #1{\enumeratey #1 \endenumeratey}
+\envparseargdef\enumerate{\enumeratey #1 \endenumeratey}
\def\enumeratey #1 #2\endenumeratey{%
- \begingroup % ended by the @end enumerate
- %
% If we were given no argument, pretend we were given `1'.
\def\thearg{#1}%
\ifx\thearg\empty \def\thearg{1}\fi
@@ -2241,7 +2414,7 @@ where each line of input produces a line of output.}
%
\def\startenumeration#1{%
\advance\itemno by -1
- \itemizey{#1.}\Eenumerate\flushcr
+ \itemizey{#1.}\flushcr
}
% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
@@ -2288,24 +2461,14 @@ where each line of input produces a line of output.}
% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
% @item ...
% using the widest term desired in each column.
-%
-% For those who want to use more than one line's worth of words in
-% the preamble, break the line within one argument and it
-% will parse correctly, i.e.,
-%
-% @multitable {Column 1 template} {Column 2 template} {Column 3
-% template}
-% Not:
-% @multitable {Column 1 template} {Column 2 template}
-% {Column 3 template}
% Each new table line starts with @item, each subsequent new column
% starts with @tab. Empty columns may be produced by supplying @tab's
% with nothing between them for as many times as empty columns are needed,
% ie, @tab@tab@tab will produce two empty columns.
-% @item, @tab, @multitable or @end multitable do not need to be on their
-% own lines, but it will not hurt if they are.
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
% Sample multitable:
@@ -2388,18 +2551,30 @@ where each line of input produces a line of output.}
\go
}
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry. Note that \everycr resets \everytab.
+\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}%
+%
+% A \tab used to include \hskip1sp. But then the space in a template
+% line is not enough. That is bad. So let's go back to just `&' until
+% we encounter the problem it was intended to solve again.
+% --karl, nathan@acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
% @multitable ... @end multitable definitions:
%
-\def\multitable{\parsearg\dotable}
-\def\dotable#1{\bgroup
+\newtoks\everytab % insert after every tab.
+%
+\envdef\multitable{%
\vskip\parskip
- \let\item=\crcrwithfootnotes
- % A \tab used to include \hskip1sp. But then the space in a template
- % line is not enough. That is bad. So let's go back to just & until
- % we encounter the problem it was intended to solve again. --karl,
- % nathan@acm.org, 20apr99.
- \let\tab=&%
- \let\startfootins=\startsavedfootnote
+ \startsavinginserts
+ %
+ % @item within a multitable starts a normal row.
+ \let\item\crcr
+ %
\tolerance=9500
\hbadness=9500
\setmultitablespacing
@@ -2407,70 +2582,80 @@ where each line of input produces a line of output.}
\parindent=\multitableparindent
\overfullrule=0pt
\global\colcount=0
- \def\Emultitable{%
- \global\setpercentfalse
- \crcrwithfootnotes\crcr
- \egroup\egroup
+ %
+ \everycr = {%
+ \noalign{%
+ \global\everytab={}%
+ \global\colcount=0 % Reset the column counter.
+ % Check for saved footnotes, etc.
+ \checkinserts
+ % Keeps underfull box messages off when table breaks over pages.
+ %\filbreak
+ % Maybe so, but it also creates really weird page breaks when the
+ % table breaks over pages. Wouldn't \vfil be better? Wait until the
+ % problem manifests itself, so it can be fixed for real --karl.
+ }%
}%
%
+ \parsearg\domultitable
+}
+\def\domultitable#1{%
% To parse everything between @multitable and @item:
\setuptable#1 \endsetuptable
%
- % \everycr will reset column counter, \colcount, at the end of
- % each line. Every column entry will cause \colcount to advance by one.
- % The table preamble
- % looks at the current \colcount to find the correct column width.
- \everycr{\noalign{%
- %
- % \filbreak%% keeps underfull box messages off when table breaks over pages.
- % Maybe so, but it also creates really weird page breaks when the table
- % breaks over pages. Wouldn't \vfil be better? Wait until the problem
- % manifests itself, so it can be fixed for real --karl.
- \global\colcount=0\relax}}%
- %
% This preamble sets up a generic column definition, which will
% be used as many times as user calls for columns.
% \vtop will set a single line and will also let text wrap and
% continue for many paragraphs if desired.
- \halign\bgroup&\global\advance\colcount by 1\relax
- \multistrut\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname
- %
- % In order to keep entries from bumping into each other
- % we will add a \leftskip of \multitablecolspace to all columns after
- % the first one.
- %
- % If a template has been used, we will add \multitablecolspace
- % to the width of each template entry.
- %
- % If the user has set preamble in terms of percent of \hsize we will
- % use that dimension as the width of the column, and the \leftskip
- % will keep entries from bumping into each other. Table will start at
- % left margin and final column will justify at right margin.
- %
- % Make sure we don't inherit \rightskip from the outer environment.
- \rightskip=0pt
- \ifnum\colcount=1
- % The first column will be indented with the surrounding text.
- \advance\hsize by\leftskip
- \else
- \ifsetpercent \else
- % If user has not set preamble in terms of percent of \hsize
- % we will advance \hsize by \multitablecolspace.
- \advance\hsize by \multitablecolspace
- \fi
- % In either case we will make \leftskip=\multitablecolspace:
- \leftskip=\multitablecolspace
- \fi
- % Ignoring space at the beginning and end avoids an occasional spurious
- % blank line, when TeX decides to break the line at the space before the
- % box from the multistrut, so the strut ends up on a line by itself.
- % For example:
- % @multitable @columnfractions .11 .89
- % @item @code{#}
- % @tab Legal holiday which is valid in major parts of the whole country.
- % Is automatically provided with highlighting sequences respectively marking
- % characters.
- \noindent\ignorespaces##\unskip\multistrut}\cr
+ \halign\bgroup &%
+ \global\advance\colcount by 1
+ \multistrut
+ \vtop{%
+ % Use the current \colcount to find the correct column width:
+ \hsize=\expandafter\csname col\the\colcount\endcsname
+ %
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \multitablecolspace to all columns after
+ % the first one.
+ %
+ % If a template has been used, we will add \multitablecolspace
+ % to the width of each template entry.
+ %
+ % If the user has set preamble in terms of percent of \hsize we will
+ % use that dimension as the width of the column, and the \leftskip
+ % will keep entries from bumping into each other. Table will start at
+ % left margin and final column will justify at right margin.
+ %
+ % Make sure we don't inherit \rightskip from the outer environment.
+ \rightskip=0pt
+ \ifnum\colcount=1
+ % The first column will be indented with the surrounding text.
+ \advance\hsize by\leftskip
+ \else
+ \ifsetpercent \else
+ % If user has not set preamble in terms of percent of \hsize
+ % we will advance \hsize by \multitablecolspace.
+ \advance\hsize by \multitablecolspace
+ \fi
+ % In either case we will make \leftskip=\multitablecolspace:
+ \leftskip=\multitablecolspace
+ \fi
+ % Ignoring space at the beginning and end avoids an occasional spurious
+ % blank line, when TeX decides to break the line at the space before the
+ % box from the multistrut, so the strut ends up on a line by itself.
+ % For example:
+ % @multitable @columnfractions .11 .89
+ % @item @code{#}
+ % @tab Legal holiday which is valid in major parts of the whole country.
+ % Is automatically provided with highlighting sequences respectively
+ % marking characters.
+ \noindent\ignorespaces##\unskip\multistrut
+ }\cr
+}
+\def\Emultitable{%
+ \crcr
+ \egroup % end the \halign
+ \global\setpercentfalse
}
\def\setmultitablespacing{% test to see if user has set \multitablelinespace.
@@ -2500,163 +2685,33 @@ width0pt\relax} \fi
%% than skip between lines in the table.
\fi}
-% In case a @footnote appears inside an alignment, save the footnote
-% text to a box and make the \insert when a row of the table is
-% finished. Otherwise, the insertion is lost, it never migrates to the
-% main vertical list. --kasal, 22jan03.
-%
-\newbox\savedfootnotes
-%
-% \dotable \let's \startfootins to this, so that \dofootnote will call
-% it instead of starting the insertion right away.
-\def\startsavedfootnote{%
- \global\setbox\savedfootnotes = \vbox\bgroup
- \unvbox\savedfootnotes
-}
-\def\crcrwithfootnotes{%
- \crcr
- \ifvoid\savedfootnotes \else
- \noalign{\insert\footins{\box\savedfootnotes}}%
- \fi
-}
\message{conditionals,}
-% Prevent errors for section commands.
-% Used in @ignore and in failing conditionals.
-\def\ignoresections{%
- \let\chapter=\relax
- \let\unnumbered=\relax
- \let\top=\relax
- \let\unnumberedsec=\relax
- \let\unnumberedsection=\relax
- \let\unnumberedsubsec=\relax
- \let\unnumberedsubsection=\relax
- \let\unnumberedsubsubsec=\relax
- \let\unnumberedsubsubsection=\relax
- \let\section=\relax
- \let\subsec=\relax
- \let\subsubsec=\relax
- \let\subsection=\relax
- \let\subsubsection=\relax
- \let\appendix=\relax
- \let\appendixsec=\relax
- \let\appendixsection=\relax
- \let\appendixsubsec=\relax
- \let\appendixsubsection=\relax
- \let\appendixsubsubsec=\relax
- \let\appendixsubsubsection=\relax
- \let\contents=\relax
- \let\smallbook=\relax
- \let\titlepage=\relax
-}
-
-% Used in nested conditionals, where we have to parse the Texinfo source
-% and so want to turn off most commands, in case they are used
-% incorrectly.
-%
-% We use \empty instead of \relax for the @def... commands, so that \end
-% doesn't throw an error. For instance:
-% @ignore
-% @deffn ...
-% @end deffn
-% @end ignore
-%
-% The @end deffn is going to get expanded, because we're trying to allow
-% nested conditionals. But we don't want to expand the actual @deffn,
-% since it might be syntactically correct and intended to be ignored.
-% Since \end checks for \relax, using \empty does not cause an error.
-%
-\def\ignoremorecommands{%
- \let\defcodeindex = \relax
- \let\defcv = \empty
- \let\defcvx = \empty
- \let\Edefcv = \empty
- \let\deffn = \empty
- \let\deffnx = \empty
- \let\Edeffn = \empty
- \let\defindex = \relax
- \let\defivar = \empty
- \let\defivarx = \empty
- \let\Edefivar = \empty
- \let\defmac = \empty
- \let\defmacx = \empty
- \let\Edefmac = \empty
- \let\defmethod = \empty
- \let\defmethodx = \empty
- \let\Edefmethod = \empty
- \let\defop = \empty
- \let\defopx = \empty
- \let\Edefop = \empty
- \let\defopt = \empty
- \let\defoptx = \empty
- \let\Edefopt = \empty
- \let\defspec = \empty
- \let\defspecx = \empty
- \let\Edefspec = \empty
- \let\deftp = \empty
- \let\deftpx = \empty
- \let\Edeftp = \empty
- \let\deftypefn = \empty
- \let\deftypefnx = \empty
- \let\Edeftypefn = \empty
- \let\deftypefun = \empty
- \let\deftypefunx = \empty
- \let\Edeftypefun = \empty
- \let\deftypeivar = \empty
- \let\deftypeivarx = \empty
- \let\Edeftypeivar = \empty
- \let\deftypemethod = \empty
- \let\deftypemethodx = \empty
- \let\Edeftypemethod = \empty
- \let\deftypeop = \empty
- \let\deftypeopx = \empty
- \let\Edeftypeop = \empty
- \let\deftypevar = \empty
- \let\deftypevarx = \empty
- \let\Edeftypevar = \empty
- \let\deftypevr = \empty
- \let\deftypevrx = \empty
- \let\Edeftypevr = \empty
- \let\defun = \empty
- \let\defunx = \empty
- \let\Edefun = \empty
- \let\defvar = \empty
- \let\defvarx = \empty
- \let\Edefvar = \empty
- \let\defvr = \empty
- \let\defvrx = \empty
- \let\Edefvr = \empty
- \let\clear = \relax
- \let\down = \relax
- \let\evenfooting = \relax
- \let\evenheading = \relax
- \let\everyfooting = \relax
- \let\everyheading = \relax
- \let\headings = \relax
- \let\include = \relax
- \let\item = \relax
- \let\lowersections = \relax
- \let\oddfooting = \relax
- \let\oddheading = \relax
- \let\printindex = \relax
- \let\pxref = \relax
- \let\raisesections = \relax
- \let\ref = \relax
- \let\set = \relax
- \let\setchapternewpage = \relax
- \let\setchapterstyle = \relax
- \let\settitle = \relax
- \let\up = \relax
- \let\verbatiminclude = \relax
- \let\xref = \relax
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed. They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested. But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+ \expandafter\let\csname #1\endcsname = \relax
+ \expandafter\let\csname iscond.#1\endcsname = 1
}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
% Ignore @ignore, @ifhtml, @ifinfo, and the like.
%
\def\direntry{\doignore{direntry}}
-\def\documentdescriptionword{documentdescription}
\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
\def\ifhtml{\doignore{ifhtml}}
\def\ifinfo{\doignore{ifinfo}}
\def\ifnottex{\doignore{ifnottex}}
@@ -2666,198 +2721,133 @@ width0pt\relax} \fi
\def\menu{\doignore{menu}}
\def\xml{\doignore{xml}}
-% @dircategory CATEGORY -- specify a category of the dir file
-% which this file should belong to. Ignore this in TeX.
-\let\dircategory = \comment
-
-% Ignore text until a line `@end #1'.
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
\def\doignore#1{\begingroup
- % Don't complain about control sequences we have declared \outer.
- \ignoresections
- %
- % Define a command to swallow text until we reach `@end #1'.
- % This @ is a catcode 12 token (that is the normal catcode of @ in
- % this texinfo.tex file). We change the catcode of @ below to match.
- \long\def\doignoretext##1@end #1{\enddoignore}%
+ % Scan in ``verbatim'' mode:
+ \catcode`\@ = \other
+ \catcode`\{ = \other
+ \catcode`\} = \other
%
% Make sure that spaces turn into tokens that match what \doignoretext wants.
- \catcode\spaceChar = 10
- %
- % Ignore braces, too, so mismatched braces don't cause trouble.
- \catcode`\{ = 9
- \catcode`\} = 9
+ \spaceisspace
%
- % We must not have @c interpreted as a control sequence.
- \catcode`\@ = 12
- %
- \def\ignoreword{#1}%
- \ifx\ignoreword\documentdescriptionword
- % The c kludge breaks documentdescription, since
- % `documentdescription' contains a `c'. Means not everything will
- % be ignored inside @documentdescription, but oh well...
- \else
- % Make the letter c a comment character so that the rest of the line
- % will be ignored. This way, the document can have (for example)
- % @c @end ifinfo
- % and the @end ifinfo will be properly ignored.
- % (We've just changed @ to catcode 12.)
- \catcode`\c = 14
- \fi
+ % Count number of #1's that we've seen.
+ \doignorecount = 0
%
- % And now expand the command defined above.
- \doignoretext
-}
-
-% What we do to finish off ignored text.
-%
-\def\enddoignore{\endgroup\ignorespaces}%
-
-\newif\ifwarnedobs\warnedobsfalse
-\def\obstexwarn{%
- \ifwarnedobs\relax\else
- % We need to warn folks that they may have trouble with TeX 3.0.
- % This uses \immediate\write16 rather than \message to get newlines.
- \immediate\write16{}
- \immediate\write16{WARNING: for users of Unix TeX 3.0!}
- \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).}
- \immediate\write16{If you are running another version of TeX, relax.}
- \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.}
- \immediate\write16{ Then upgrade your TeX installation if you can.}
- \immediate\write16{ (See ftp://ftp.gnu.org/non-gnu/TeX.README.)}
- \immediate\write16{If you are stuck with version 3.0, run the}
- \immediate\write16{ script ``tex3patch'' from the Texinfo distribution}
- \immediate\write16{ to use a workaround.}
- \immediate\write16{}
- \global\warnedobstrue
- \fi
+ % Swallow text until we reach the matching `@end #1'.
+ \dodoignore {#1}%
}
-% **In TeX 3.0, setting text in \nullfont hangs tex. For a
-% workaround (which requires the file ``dummy.tfm'' to be installed),
-% uncomment the following line:
-%%%%%\font\nullfont=dummy\let\obstexwarn=\relax
-
-% Ignore text, except that we keep track of conditional commands for
-% purposes of nesting, up to an `@end #1' command.
-%
-\def\nestedignore#1{%
- \obstexwarn
- % We must actually expand the ignored text to look for the @end
- % command, so that nested ignore constructs work. Thus, we put the
- % text into a \vbox and then do nothing with the result. To minimize
- % the chance of memory overflow, we follow the approach outlined on
- % page 401 of the TeXbook.
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+ \obeylines %
%
- \setbox0 = \vbox\bgroup
- % Don't complain about control sequences we have declared \outer.
- \ignoresections
- %
- % Define `@end #1' to end the box, which will in turn undefine the
- % @end command again.
- \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}%
- %
- % We are going to be parsing Texinfo commands. Most cause no
- % trouble when they are used incorrectly, but some commands do
- % complicated argument parsing or otherwise get confused, so we
- % undefine them.
- %
- % We can't do anything about stray @-signs, unfortunately;
- % they'll produce `undefined control sequence' errors.
- \ignoremorecommands
- %
- % Set the current font to be \nullfont, a TeX primitive, and define
- % all the font commands to also use \nullfont. We don't use
- % dummy.tfm, as suggested in the TeXbook, because some sites
- % might not have that installed. Therefore, math mode will still
- % produce output, but that should be an extremely small amount of
- % stuff compared to the main input.
+ \gdef\dodoignore#1{%
+ % #1 contains the string `ifinfo'.
%
- \nullfont
- \let\tenrm=\nullfont \let\tenit=\nullfont \let\tensl=\nullfont
- \let\tenbf=\nullfont \let\tentt=\nullfont \let\smallcaps=\nullfont
- \let\tensf=\nullfont
- % Similarly for index fonts.
- \let\smallrm=\nullfont \let\smallit=\nullfont \let\smallsl=\nullfont
- \let\smallbf=\nullfont \let\smalltt=\nullfont \let\smallsc=\nullfont
- \let\smallsf=\nullfont
- % Similarly for smallexample fonts.
- \let\smallerrm=\nullfont \let\smallerit=\nullfont \let\smallersl=\nullfont
- \let\smallerbf=\nullfont \let\smallertt=\nullfont \let\smallersc=\nullfont
- \let\smallersf=\nullfont
+ % Define a command to find the next `@end #1', which must be on a line
+ % by itself.
+ \long\def\doignoretext##1^^M@end #1{\doignoretextyyy##1^^M@#1\_STOP_}%
+ % And this command to find another #1 command, at the beginning of a
+ % line. (Otherwise, we would consider a line `@c @ifset', for
+ % example, to count as an @ifset for nesting.)
+ \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
%
- % Don't complain when characters are missing from the fonts.
- \tracinglostchars = 0
- %
- % Don't bother to do space factor calculations.
- \frenchspacing
- %
- % Don't report underfull hboxes.
- \hbadness = 10000
- %
- % Do minimal line-breaking.
- \pretolerance = 10000
- %
- % Do not execute instructions in @tex.
- \def\tex{\doignore{tex}}%
- % Do not execute macro definitions.
- % `c' is a comment character, so the word `macro' will get cut off.
- \def\macro{\doignore{ma}}%
+ % And now expand that command.
+ \obeylines %
+ \doignoretext ^^M%
+ }%
}
+\def\doignoreyyy#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty % Nothing found.
+ \let\next\doignoretextzzz
+ \else % Found a nested condition, ...
+ \advance\doignorecount by 1
+ \let\next\doignoretextyyy % ..., look for another.
+ % If we're here, #1 ends with ^^M\ifinfo (for example).
+ \fi
+ \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+ \ifnum\doignorecount = 0 % We have just found the outermost @end.
+ \let\next\enddoignore
+ \else % Still inside a nested condition.
+ \advance\doignorecount by -1
+ \let\next\doignoretext % Look for the next @end.
+ \fi
+ \next
+}
+
+% Finish off ignored text.
+\def\enddoignore{\endgroup\ignorespaces}
+
+
% @set VAR sets the variable VAR to an empty value.
% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
%
% Since we want to separate VAR from REST-OF-LINE (which might be
% empty), we can't just use \parsearg; we have to insert a space of our
% own to delimit the rest of the line, and then take it out again if we
-% didn't need it. Make sure the catcode of space is correct to avoid
-% losing inside @example, for instance.
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
%
-\def\set{\begingroup\catcode` =10
- \catcode`\-=12 \catcode`\_=12 % Allow - and _ in VAR.
- \parsearg\setxxx}
-\def\setxxx#1{\setyyy#1 \endsetyyy}
+\parseargdef\set{\setyyy#1 \endsetyyy}
\def\setyyy#1 #2\endsetyyy{%
- \def\temp{#2}%
- \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty
- \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted.
- \fi
- \endgroup
+ {%
+ \makevalueexpandable
+ \def\temp{#2}%
+ \edef\next{\gdef\makecsname{SET#1}}%
+ \ifx\temp\empty
+ \next{}%
+ \else
+ \setzzz#2\endsetzzz
+ \fi
+ }%
}
-% Can't use \xdef to pre-expand #2 and save some time, since \temp or
-% \next or other control sequences that we've defined might get us into
-% an infinite loop. Consider `@set foo @cite{bar}'.
-\def\setzzz#1#2 \endsetzzz{\expandafter\gdef\csname SET#1\endcsname{#2}}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
% @clear VAR clears (i.e., unsets) the variable VAR.
%
-\def\clear{\parsearg\clearxxx}
-\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax}
+\parseargdef\clear{%
+ {%
+ \makevalueexpandable
+ \global\expandafter\let\csname SET#1\endcsname=\relax
+ }%
+}
% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
{
- \catcode`\_ = \active
+ \catcode`\- = \active \catcode`\_ = \active
%
- % We might end up with active _ or - characters in the argument if
- % we're called from @code, as @code{@value{foo-bar_}}. So \let any
- % such active characters to their normal equivalents.
- \gdef\value{\begingroup
+ \gdef\makevalueexpandable{%
+ \let\value = \expandablevalue
+ % We don't want these characters active, ...
\catcode`\-=\other \catcode`\_=\other
- \indexbreaks \let_\normalunderscore
- \valuexxx}
+ % ..., but we might end up with active ones in the argument if
+ % we're called from @code, as @code{@value{foo-bar_}}, though.
+ % So \let them to their normal equivalents.
+ \let-\realdash \let_\normalunderscore
+ }
}
-\def\valuexxx#1{\expandablevalue{#1}\endgroup}
% We have this subroutine so that we can handle at least some @value's
-% properly in indexes (we \let\value to this in \indexdummies). Ones
-% whose names contain - or _ still won't work, but we can't do anything
-% about that. The command has to be fully expandable (if the variable
-% is set), since the result winds up in the index file. This means that
-% if the variable's value contains other Texinfo commands, it's almost
-% certain it will fail (although perhaps we could fix that with
-% sufficient work to do a one-level expansion on the result, instead of
-% complete).
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file. This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
%
\def\expandablevalue#1{%
\expandafter\ifx\csname SET#1\endcsname\relax
@@ -2871,55 +2861,36 @@ width0pt\relax} \fi
% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
% with @set.
%
-\def\ifset{\parsearg\doifset}
-\def\doifset#1{%
- \expandafter\ifx\csname SET#1\endcsname\relax
- \let\next=\ifsetfail
- \else
- \let\next=\ifsetsucceed
- \fi
- \next
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+ {%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname SET#2\endcsname\relax
+ #1% If not set, redefine \next.
+ \fi
+ \expandafter
+ }\next
}
-\def\ifsetsucceed{\conditionalsucceed{ifset}}
-\def\ifsetfail{\nestedignore{ifset}}
-\defineunmatchedend{ifset}
+\def\ifsetfail{\doignore{ifset}}
% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
% defined with @set, or has been undefined with @clear.
%
-\def\ifclear{\parsearg\doifclear}
-\def\doifclear#1{%
- \expandafter\ifx\csname SET#1\endcsname\relax
- \let\next=\ifclearsucceed
- \else
- \let\next=\ifclearfail
- \fi
- \next
-}
-\def\ifclearsucceed{\conditionalsucceed{ifclear}}
-\def\ifclearfail{\nestedignore{ifclear}}
-\defineunmatchedend{ifclear}
-
-% @iftex, @ifnothtml, @ifnotinfo, @ifnotplaintext always succeed; we
-% read the text following, through the first @end iftex (etc.). Make
-% `@end iftex' (etc.) valid only after an @iftex.
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
%
-\def\iftex{\conditionalsucceed{iftex}}
-\def\ifnothtml{\conditionalsucceed{ifnothtml}}
-\def\ifnotinfo{\conditionalsucceed{ifnotinfo}}
-\def\ifnotplaintext{\conditionalsucceed{ifnotplaintext}}
-\defineunmatchedend{iftex}
-\defineunmatchedend{ifnothtml}
-\defineunmatchedend{ifnotinfo}
-\defineunmatchedend{ifnotplaintext}
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
-% True conditional. Since \set globally defines its variables, we can
-% just start and end a group (to keep the @end definition undefined at
-% the outer level).
-%
-\def\conditionalsucceed#1{\begingroup
- \expandafter\def\csname E#1\endcsname{\endgroup}%
-}
+% @dircategory CATEGORY -- specify a category of the dir file
+% which this file should belong to. Ignore this in TeX.
+\let\dircategory=\comment
% @defininfoenclose.
\let\definfoenclose=\comment
@@ -3109,6 +3080,10 @@ width0pt\relax} \fi
\definedummyword{oe}%
\definedummyword{o}%
\definedummyword{ss}%
+ \definedummyword{exclamdown}%
+ \definedummyword{questiondown}%
+ \definedummyword{ordm}%
+ \definedummyword{ordf}%
%
% Although these internal commands shouldn't show up, sometimes they do.
\definedummyword{bf}%
@@ -3127,6 +3102,7 @@ width0pt\relax} \fi
\definedummyword{sc}%
\definedummyword{t}%
%
+ \definedummyword{LaTeX}%
\definedummyword{TeX}%
\definedummyword{acronym}%
\definedummyword{cite}%
@@ -3146,11 +3122,13 @@ width0pt\relax} \fi
\definedummyword{uref}%
\definedummyword{url}%
\definedummyword{var}%
+ \definedummyword{verb}%
\definedummyword{w}%
%
% Assorted special characters.
\definedummyword{bullet}%
\definedummyword{copyright}%
+ \definedummyword{registeredsymbol}%
\definedummyword{dots}%
\definedummyword{enddots}%
\definedummyword{equiv}%
@@ -3162,10 +3140,9 @@ width0pt\relax} \fi
\definedummyword{print}%
\definedummyword{result}%
%
- % Handle some cases of @value -- where the variable name does not
- % contain - or _, and the value does not contain any
+ % Handle some cases of @value -- where it does not contain any
% (non-fully-expandable) commands.
- \let\value = \expandablevalue
+ \makevalueexpandable
%
% Normal spaces, not active ones.
\unsepspaces
@@ -3174,18 +3151,13 @@ width0pt\relax} \fi
\turnoffmacros
}
-% If an index command is used in an @example environment, any spaces
-% therein should become regular spaces in the raw index file, not the
-% expansion of \tie (\leavevmode \penalty \@M \ ).
-{\obeyspaces
- \gdef\unsepspaces{\obeyspaces\let =\space}}
-
% \indexnofonts is used when outputting the strings to sort the index
% by, and when constructing control sequence names. It eliminates all
% control sequences and just writes whatever the best ASCII sort string
% would be for a given command (usually its argument).
%
+\def\indexdummylatex{LaTeX}
\def\indexdummytex{TeX}
\def\indexdummydots{...}
%
@@ -3226,6 +3198,8 @@ width0pt\relax} \fi
\def\ss{ss}%
\def\exclamdown{!}%
\def\questiondown{?}%
+ \def\ordf{a}%
+ \def\ordm{o}%
%
% Don't no-op \tt, since it isn't a user-level command
% and is used in the definitions of the active chars like <, >, |, etc.
@@ -3239,6 +3213,7 @@ width0pt\relax} \fi
\let\sc=\asis
\let\t=\asis
%
+ \let\LaTeX=\indexdummylatex
\let\TeX=\indexdummytex
\let\acronym=\asis
\let\cite=\asis
@@ -3258,98 +3233,145 @@ width0pt\relax} \fi
\let\uref=\asis
\let\url=\asis
\let\var=\asis
+ \let\verb=\asis
\let\w=\asis
}
\let\indexbackslash=0 %overridden during \printindex.
\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
-% For \ifx comparisons.
-\def\emptymacro{\empty}
-
% Most index entries go through here, but \dosubind is the general case.
-%
-\def\doind#1#2{\dosubind{#1}{#2}\empty}
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
% Workhorse for all \fooindexes.
% #1 is name of index, #2 is stuff to put there, #3 is subentry --
-% \empty if called from \doind, as we usually are. The main exception
-% is with defuns, which call us directly.
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
%
\def\dosubind#1#2#3{%
+ \iflinks
+ {%
+ % Store the main index entry text (including the third arg).
+ \toks0 = {#2}%
+ % If third arg is present, precede it with a space.
+ \def\thirdarg{#3}%
+ \ifx\thirdarg\empty \else
+ \toks0 = \expandafter{\the\toks0 \space #3}%
+ \fi
+ %
+ \edef\writeto{\csname#1indfile\endcsname}%
+ %
+ \ifvmode
+ \dosubindsanitize
+ \else
+ \dosubindwrite
+ \fi
+ }%
+ \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
% Put the index entry in the margin if desired.
\ifx\SETmarginindex\relax\else
- \insert\margin{\hbox{\vrule height8pt depth3pt width0pt #2}}%
+ \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
\fi
- {%
- \count255=\lastpenalty
- {%
- \indexdummies % Must do this here, since \bf, etc expand at this stage
- \escapechar=`\\
- {%
- \let\folio = 0% We will expand all macros now EXCEPT \folio.
- \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now
- % so it will be output as is; and it will print as backslash.
- %
- % The main index entry text.
- \toks0 = {#2}%
- %
- % If third arg is present, precede it with space in sort key.
- \def\thirdarg{#3}%
- \ifx\thirdarg\emptymacro \else
- % If the third (subentry) arg is present, add it to the index
- % line to write.
- \toks0 = \expandafter{\the\toks0 \space #3}%
- \fi
- %
- % Process the index entry with all font commands turned off, to
- % get the string to sort by.
- {\indexnofonts
- \edef\temp{\the\toks0}% need full expansion
- \xdef\indexsorttmp{\temp}%
- }%
- %
- % Set up the complete index entry, with both the sort key and
- % the original text, including any font commands. We write
- % three arguments to \entry to the .?? file (four in the
- % subentry case), texindex reduces to two when writing the .??s
- % sorted result.
- \edef\temp{%
- \write\csname#1indfile\endcsname{%
- \realbackslash entry{\indexsorttmp}{\folio}{\the\toks0}}%
- }%
- %
- % If a skip is the last thing on the list now, preserve it
- % by backing up by \lastskip, doing the \write, then inserting
- % the skip again. Otherwise, the whatsit generated by the
- % \write will make \lastskip zero. The result is that sequences
- % like this:
- % @end defun
- % @tindex whatever
- % @defun ...
- % will have extra space inserted, because the \medbreak in the
- % start of the @defun won't see the skip inserted by the @end of
- % the previous defun.
- %
- % But don't do any of this if we're not in vertical mode. We
- % don't want to do a \vskip and prematurely end a paragraph.
- %
- % Avoid page breaks due to these extra skips, too.
- %
- \iflinks
- \ifvmode
- \skip0 = \lastskip
- \ifdim\lastskip = 0pt \else \nobreak\vskip-\skip0 \fi
- \fi
- %
- \temp % do the write
- %
- \ifvmode \ifdim\skip0 = 0pt \else \nobreak\vskip\skip0 \fi \fi
- \fi
- }%
- }%
- \penalty\count255
+ %
+ % Remember, we are within a group.
+ \indexdummies % Must do this here, since \bf, etc expand at this stage
+ \escapechar=`\\
+ \def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now
+ % so it will be output as is; and it will print as backslash.
+ %
+ % Process the index entry with all font commands turned off, to
+ % get the string to sort by.
+ {\indexnofonts
+ \edef\temp{\the\toks0}% need full expansion
+ \xdef\indexsorttmp{\temp}%
+ }%
+ %
+ % Set up the complete index entry, with both the sort key and
+ % the original text, including any font commands. We write
+ % three arguments to \entry to the .?? file (four in the
+ % subentry case), texindex reduces to two when writing the .??s
+ % sorted result.
+ \edef\temp{%
+ \write\writeto{%
+ \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
}%
+ \temp
+}
+
+% Take care of unwanted page breaks:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again. Otherwise, the whatsit generated by the
+% \write will make \lastskip zero. The result is that sequences
+% like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode. We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip. \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip. The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+% ..., ready, GO:
+%
+\def\dosubindsanitize{%
+ % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+ \skip0 = \lastskip
+ \edef\lastskipmacro{\the\lastskip}%
+ \count255 = \lastpenalty
+ %
+ % If \lastskip is nonzero, that means the last item was a
+ % skip. And since a skip is discardable, that means this
+ % -\skip0 glue we're inserting is preceded by a
+ % non-discardable item, therefore it is not a potential
+ % breakpoint, therefore no \nobreak needed.
+ \ifx\lastskipmacro\zeroskipmacro
+ \else
+ \vskip-\skip0
+ \fi
+ %
+ \dosubindwrite
+ %
+ \ifx\lastskipmacro\zeroskipmacro
+ % if \lastskip was zero, perhaps the last item was a
+ % penalty, and perhaps it was >=10000, e.g., a \nobreak.
+ % In that case, we want to re-insert the penalty; since we
+ % just inserted a non-discardable item, any following glue
+ % (such as a \parskip) would be a breakpoint. For example:
+ % @deffn deffn-whatever
+ % @vindex index-whatever
+ % Description.
+ % would allow a break between the index-whatever whatsit
+ % and the "Description." paragraph.
+ \ifnum\count255>9999 \nobreak \fi
+ \else
+ % On the other hand, if we had a nonzero \lastskip,
+ % this make-up glue would be preceded by a non-discardable item
+ % (the whatsit from the \write), so we must insert a \nobreak.
+ \nobreak\vskip\skip0
+ \fi
}
% The index entry written in the file actually looks like
@@ -3387,14 +3409,12 @@ width0pt\relax} \fi
% @printindex causes a particular index (the ??s file) to get printed.
% It does not print any chapter heading (usually an @unnumbered).
%
-\def\printindex{\parsearg\doprintindex}
-\def\doprintindex#1{\begingroup
+\parseargdef\printindex{\begingroup
\dobreak \chapheadingskip{10000}%
%
\smallfonts \rm
\tolerance = 9500
\everypar = {}% don't want the \kern\-parindent from indentation suppression.
- \indexbreaks
%
% See if the index file exists and is nonempty.
% Change catcode of @ here so that if the index file contains
@@ -3459,74 +3479,94 @@ width0pt\relax} \fi
\nobreak
}}
-% This typesets a paragraph consisting of #1, dot leaders, and then #2
-% flush to the right margin. It is used for index and table of contents
-% entries. The paragraph is indented by \leftskip.
-%
-\def\entry#1#2{\begingroup
- %
- % Start a new paragraph if necessary, so our assignments below can't
- % affect previous text.
- \par
- %
- % Do not fill out the last line with white space.
- \parfillskip = 0in
- %
- % No extra space above this paragraph.
- \parskip = 0in
- %
- % Do not prefer a separate line ending with a hyphen to fewer lines.
- \finalhyphendemerits = 0
- %
- % \hangindent is only relevant when the entry text and page number
- % don't both fit on one line. In that case, bob suggests starting the
- % dots pretty far over on the line. Unfortunately, a large
- % indentation looks wrong when the entry text itself is broken across
- % lines. So we use a small indentation and put up with long leaders.
- %
- % \hangafter is reset to 1 (which is the value we want) at the start
- % of each paragraph, so we need not do anything with that.
- \hangindent = 2em
- %
- % When the entry text needs to be broken, just fill out the first line
- % with blank space.
- \rightskip = 0pt plus1fil
- %
- % A bit of stretch before each entry for the benefit of balancing columns.
- \vskip 0pt plus1pt
- %
- % Start a ``paragraph'' for the index entry so the line breaking
- % parameters we've set above will have an effect.
- \noindent
- %
- % Insert the text of the index entry. TeX will do line-breaking on it.
- #1%
- % The following is kludged to not output a line of dots in the index if
- % there are no page numbers. The next person who breaks this will be
- % cursed by a Unix daemon.
- \def\tempa{{\rm }}%
- \def\tempb{#2}%
- \edef\tempc{\tempa}%
- \edef\tempd{\tempb}%
- \ifx\tempc\tempd\ \else%
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin. It is used for index
+% and table of contents entries. The paragraph is indented by \leftskip.
+%
+% A straigtforward implementation would start like this:
+% \def\entry#1#2{...
+% But this frozes the catcodes in the argument, and can cause problems to
+% @code, which set's active ``-''. This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't what we really
+% want.
+% The right solution is to prevent \entry from swallowing the whole text.
+% --kasal, 21nov03
+\def\entry{%
+ \begingroup
+ %
+ % Start a new paragraph if necessary, so our assignments below can't
+ % affect previous text.
+ \par
+ %
+ % Do not fill out the last line with white space.
+ \parfillskip = 0in
+ %
+ % No extra space above this paragraph.
+ \parskip = 0in
+ %
+ % Do not prefer a separate line ending with a hyphen to fewer lines.
+ \finalhyphendemerits = 0
%
- % If we must, put the page number on a line of its own, and fill out
- % this line with blank space. (The \hfil is overwhelmed with the
- % fill leaders glue in \indexdotfill if the page number does fit.)
- \hfil\penalty50
- \null\nobreak\indexdotfill % Have leaders before the page number.
+ % \hangindent is only relevant when the entry text and page number
+ % don't both fit on one line. In that case, bob suggests starting the
+ % dots pretty far over on the line. Unfortunately, a large
+ % indentation looks wrong when the entry text itself is broken across
+ % lines. So we use a small indentation and put up with long leaders.
%
- % The `\ ' here is removed by the implicit \unskip that TeX does as
- % part of (the primitive) \par. Without it, a spurious underfull
- % \hbox ensues.
- \ifpdf
- \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+ % \hangafter is reset to 1 (which is the value we want) at the start
+ % of each paragraph, so we need not do anything with that.
+ \hangindent = 2em
+ %
+ % When the entry text needs to be broken, just fill out the first line
+ % with blank space.
+ \rightskip = 0pt plus1fil
+ %
+ % A bit of stretch before each entry for the benefit of balancing
+ % columns.
+ \vskip 0pt plus1pt
+ %
+ % Swallow the left brace of the text (first parameter):
+ \afterassignment\doentry
+ \let\temp =
+}
+\def\doentry{%
+ \bgroup % Instead of the swallowed brace.
+ \noindent
+ \aftergroup\finishentry
+ % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+ % #1 is the page number.
+ %
+ % The following is kludged to not output a line of dots in the index if
+ % there are no page numbers. The next person who breaks this will be
+ % cursed by a Unix daemon.
+ \def\tempa{{\rm }}%
+ \def\tempb{#1}%
+ \edef\tempc{\tempa}%
+ \edef\tempd{\tempb}%
+ \ifx\tempc\tempd
+ \ %
\else
- \ #2% The page number ends the paragraph.
+ %
+ % If we must, put the page number on a line of its own, and fill out
+ % this line with blank space. (The \hfil is overwhelmed with the
+ % fill leaders glue in \indexdotfill if the page number does fit.)
+ \hfil\penalty50
+ \null\nobreak\indexdotfill % Have leaders before the page number.
+ %
+ % The `\ ' here is removed by the implicit \unskip that TeX does as
+ % part of (the primitive) \par. Without it, a spurious underfull
+ % \hbox ensues.
+ \ifpdf
+ \pdfgettoks#1.\ \the\toksA
+ \else
+ \ #1%
+ \fi
\fi
- \fi%
- \par
-\endgroup}
+ \par
+ \endgroup
+}
% Like \dotfill except takes at least 1 em.
\def\indexdotfill{\cleaders
@@ -3695,6 +3735,12 @@ width0pt\relax} \fi
\message{sectioning,}
% Chapters, sections, etc.
+% \unnumberedno is an oxymoron, of course. But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number". We avoid collisions with chapter
+% numbers by starting them at 10000. (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
\newcount\chapno
\newcount\secno \secno=0
\newcount\subsecno \subsecno=0
@@ -3702,9 +3748,12 @@ width0pt\relax} \fi
% This counter is funny since it counts through charcodes of letters A, B, ...
\newcount\appendixno \appendixno = `\@
+%
% \def\appendixletter{\char\the\appendixno}
-% We do the following for the sake of pdftex, which needs the actual
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
% letter in the expansion, not just typeset.
+%
\def\appendixletter{%
\ifnum\appendixno=`A A%
\else\ifnum\appendixno=`B B%
@@ -3742,11 +3791,12 @@ width0pt\relax} \fi
% Each @chapter defines this as the name of the chapter.
% page headings and footings can use it. @section does likewise.
+% However, they are not reliable, because we don't use marks.
\def\thischapter{}
\def\thissection{}
\newcount\absseclevel % used to calculate proper heading level
-\newcount\secbase\secbase=0 % @raise/lowersections modify this count
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
% @raisesections: treat @section as chapter, @subsection as section, etc.
\def\raisesections{\global\advance\secbase by -1}
@@ -3761,116 +3811,105 @@ width0pt\relax} \fi
% #2 is text for heading
\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
\ifcase\absseclevel
- \chapterzzz{#2}
-\or
- \seczzz{#2}
-\or
- \numberedsubseczzz{#2}
-\or
- \numberedsubsubseczzz{#2}
-\else
- \ifnum \absseclevel<0
- \chapterzzz{#2}
+ \chapterzzz{#2}%
+ \or \seczzz{#2}%
+ \or \numberedsubseczzz{#2}%
+ \or \numberedsubsubseczzz{#2}%
\else
- \numberedsubsubseczzz{#2}
+ \ifnum \absseclevel<0 \chapterzzz{#2}%
+ \else \numberedsubsubseczzz{#2}%
+ \fi
\fi
-\fi
-\suppressfirstparagraphindent
+ \suppressfirstparagraphindent
}
% like \numhead, but chooses appendix heading levels
\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
\ifcase\absseclevel
- \appendixzzz{#2}
-\or
- \appendixsectionzzz{#2}
-\or
- \appendixsubseczzz{#2}
-\or
- \appendixsubsubseczzz{#2}
-\else
- \ifnum \absseclevel<0
- \appendixzzz{#2}
+ \appendixzzz{#2}%
+ \or \appendixsectionzzz{#2}%
+ \or \appendixsubseczzz{#2}%
+ \or \appendixsubsubseczzz{#2}%
\else
- \appendixsubsubseczzz{#2}
+ \ifnum \absseclevel<0 \appendixzzz{#2}%
+ \else \appendixsubsubseczzz{#2}%
+ \fi
\fi
-\fi
-\suppressfirstparagraphindent
+ \suppressfirstparagraphindent
}
% like \numhead, but chooses numberless heading levels
\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
-\ifcase\absseclevel
- \unnumberedzzz{#2}
-\or
- \unnumberedseczzz{#2}
-\or
- \unnumberedsubseczzz{#2}
-\or
- \unnumberedsubsubseczzz{#2}
-\else
- \ifnum \absseclevel<0
- \unnumberedzzz{#2}
+ \ifcase\absseclevel
+ \unnumberedzzz{#2}%
+ \or \unnumberedseczzz{#2}%
+ \or \unnumberedsubseczzz{#2}%
+ \or \unnumberedsubsubseczzz{#2}%
\else
- \unnumberedsubsubseczzz{#2}
+ \ifnum \absseclevel<0 \unnumberedzzz{#2}%
+ \else \unnumberedsubsubseczzz{#2}%
+ \fi
\fi
-\fi
-\suppressfirstparagraphindent
-}
-
-% @chapter, @appendix, @unnumbered.
-\def\thischaptername{No Chapter Title}
-\outer\def\chapter{\parsearg\chapteryyy}
-\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz
-\def\chapterzzz #1{%
- \secno=0 \subsecno=0 \subsubsecno=0
- \global\advance \chapno by 1 \message{\putwordChapter\space \the\chapno}%
- \chapmacro {#1}{\the\chapno}%
- \gdef\thissection{#1}%
- \gdef\thischaptername{#1}%
- % We don't substitute the actual chapter name into \thischapter
- % because we don't want its macros evaluated now.
- \xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}%
- \writetocentry{chap}{#1}{{\the\chapno}}
- \donoderef
+ \suppressfirstparagraphindent
+}
+
+% @chapter, @appendix, @unnumbered. Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v. By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+ % section resetting is \global in case the chapter is in a group, such
+ % as an @include file.
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\chapno by 1
+ %
+ % Used for \float.
+ \gdef\chaplevelprefix{\the\chapno.}%
+ \resetallfloatnos
+ %
+ \message{\putwordChapter\space \the\chapno}%
+ %
+ % Write the actual heading.
+ \chapmacro{#1}{Ynumbered}{\the\chapno}%
+ %
+ % So @section and the like are numbered underneath this chapter.
\global\let\section = \numberedsec
\global\let\subsection = \numberedsubsec
\global\let\subsubsection = \numberedsubsubsec
}
-% we use \chapno to avoid indenting back
-\def\appendixbox#1{%
- \setbox0 = \hbox{\putwordAppendix{} \the\chapno}%
- \hbox to \wd0{#1\hss}}
-
-\outer\def\appendix{\parsearg\appendixyyy}
-\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz
-\def\appendixzzz #1{%
- \secno=0 \subsecno=0 \subsubsecno=0
- \global\advance \appendixno by 1
- \message{\putwordAppendix\space \appendixletter}%
- \chapmacro {#1}{\appendixbox{\putwordAppendix{} \appendixletter}}%
- \gdef\thissection{#1}%
- \gdef\thischaptername{#1}%
- \xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}%
- \writetocentry{appendix}{#1}{{\appendixletter}}
- \appendixnoderef
+\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\appendixno by 1
+ \gdef\chaplevelprefix{\appendixletter.}%
+ \resetallfloatnos
+ %
+ \def\appendixnum{\putwordAppendix\space \appendixletter}%
+ \message{\appendixnum}%
+ %
+ \chapmacro{#1}{Yappendix}{\appendixletter}%
+ %
\global\let\section = \appendixsec
\global\let\subsection = \appendixsubsec
\global\let\subsubsection = \appendixsubsubsec
}
% @centerchap is like @unnumbered, but the heading is centered.
-\outer\def\centerchap{\parsearg\centerchapyyy}
-\def\centerchapyyy #1{{\let\unnumbchapmacro=\centerchapmacro \unnumberedyyy{#1}}}
+\outer\parseargdef\centerchap{{\unnumberedyyy{#1}}}
-% @top is like @unnumbered.
-\outer\def\top{\parsearg\unnumberedyyy}
-
-\outer\def\unnumbered{\parsearg\unnumberedyyy}
-\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
-\def\unnumberedzzz #1{%
- \secno=0 \subsecno=0 \subsubsecno=0
+\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\unnumberedno by 1
+ %
+ % Since an unnumbered has no number, no prefix for figures.
+ \global\let\chaplevelprefix = \empty
+ \resetallfloatnos
%
% This used to be simply \message{#1}, but TeX fully expands the
% argument to \message. Therefore, if #1 contained @-commands, TeX
@@ -3883,112 +3922,84 @@ width0pt\relax} \fi
% \the<toks register> to achieve this: TeX expands \the<toks> only once,
% simply yielding the contents of <toks register>. (We also do this for
% the toc entries.)
- \toks0 = {#1}\message{(\the\toks0)}%
+ \toks0 = {#1}%
+ \message{(\the\toks0)}%
+ %
+ \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
%
- \unnumbchapmacro {#1}%
- \gdef\thischapter{#1}\gdef\thissection{#1}%
- \writetocentry{unnumbchap}{#1}{{\the\chapno}}
- \unnumbnoderef
\global\let\section = \unnumberedsec
\global\let\subsection = \unnumberedsubsec
\global\let\subsubsection = \unnumberedsubsubsec
}
+% @top is like @unnumbered.
+\let\top\unnumbered
+
% Sections.
-\outer\def\numberedsec{\parsearg\secyyy}
-\def\secyyy #1{\numhead1{#1}} % normally calls seczzz
-\def\seczzz #1{%
- \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
- \gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}%
- \writetocentry{sec}{#1}{{\the\chapno}{\the\secno}}
- \donoderef
- \nobreak
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
}
-\outer\def\appendixsection{\parsearg\appendixsecyyy}
-\outer\def\appendixsec{\parsearg\appendixsecyyy}
-\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz
-\def\appendixsectionzzz #1{%
- \subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
- \gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}%
- \writetocentry{sec}{#1}{{\appendixletter}{\the\secno}}
- \appendixnoderef
- \nobreak
+\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
}
+\let\appendixsec\appendixsection
-\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy}
-\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz
-\def\unnumberedseczzz #1{%
- \plainsecheading {#1}\gdef\thissection{#1}%
- \writetocentry{unnumbsec}{#1}{{\the\chapno}{\the\secno}}
- \unnumbnoderef
- \nobreak
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
}
% Subsections.
-\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy}
-\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz
-\def\numberedsubseczzz #1{%
- \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
- \subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}%
- \writetocentry{subsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}}
- \donoderef
- \nobreak
+\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
}
-\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy}
-\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz
-\def\appendixsubseczzz #1{%
- \gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
- \subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}%
- \writetocentry{subsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}}
- \appendixnoderef
- \nobreak
+\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno}%
}
-\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy}
-\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
-\def\unnumberedsubseczzz #1{%
- \plainsubsecheading {#1}\gdef\thissection{#1}%
- \writetocentry{unnumbsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}}
- \unnumbnoderef
- \nobreak
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno}%
}
% Subsubsections.
-\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy}
-\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz
-\def\numberedsubsubseczzz #1{%
- \gdef\thissection{#1}\global\advance \subsubsecno by 1 %
- \subsubsecheading {#1}
- {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
- \writetocentry{subsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}
- \donoderef
- \nobreak
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynumbered}%
+ {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
}
-\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy}
-\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz
-\def\appendixsubsubseczzz #1{%
- \gdef\thissection{#1}\global\advance \subsubsecno by 1 %
- \subsubsecheading {#1}
- {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
- \writetocentry{subsubsec}{#1}{{\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}}
- \appendixnoderef
- \nobreak
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
}
-\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy}
-\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
-\def\unnumberedsubsubseczzz #1{%
- \plainsubsubsecheading {#1}\gdef\thissection{#1}%
- \writetocentry{unnumbsubsubsec}{#1}{{\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}}
- \unnumbnoderef
- \nobreak
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
}
% These are variants which are not "outer", so they can appear in @ifinfo.
-% Actually, they should now be obsolete; ordinary section commands should work.
+% Actually, they are now be obsolete; ordinary section commands should work.
\def\infotop{\parsearg\unnumberedzzz}
\def\infounnumbered{\parsearg\unnumberedzzz}
\def\infounnumberedsec{\parsearg\unnumberedseczzz}
@@ -4008,9 +4019,9 @@ width0pt\relax} \fi
% These macros control what the section commands do, according
% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
% Define them by default for a numbered chapter.
-\global\let\section = \numberedsec
-\global\let\subsection = \numberedsubsec
-\global\let\subsubsection = \numberedsubsubsec
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
% Define @majorheading, @heading and @subheading
@@ -4023,23 +4034,27 @@ width0pt\relax} \fi
% if justification is not attempted. Hence \raggedright.
-\def\majorheading{\parsearg\majorheadingzzz}
-\def\majorheadingzzz #1{%
+\def\majorheading{%
{\advance\chapheadingskip by 10pt \chapbreak }%
- {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
- \parindent=0pt\raggedright
- \rm #1\hfill}}\bigskip \par\penalty 200}
+ \parsearg\chapheadingzzz
+}
-\def\chapheading{\parsearg\chapheadingzzz}
-\def\chapheadingzzz #1{\chapbreak %
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
\parindent=0pt\raggedright
- \rm #1\hfill}}\bigskip \par\penalty 200}
+ \rm #1\hfill}}%
+ \bigskip \par\penalty 200\relax
+ \suppressfirstparagraphindent
+}
% @heading, @subheading, @subsubheading.
-\def\heading{\parsearg\plainsecheading}
-\def\subheading{\parsearg\plainsubsecheading}
-\def\subsubheading{\parsearg\plainsubsubsecheading}
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
% These macros generate a chapter, section, etc. heading only
% (including whitespace, linebreaking, etc. around it),
@@ -4072,7 +4087,7 @@ width0pt\relax} \fi
\global\let\pagealignmacro=\chappager
\global\def\HEADINGSon{\HEADINGSsingle}}
-\def\CHAPPAGodd{
+\def\CHAPPAGodd{%
\global\let\contentsalignmacro = \chapoddpage
\global\let\pchapsepmacro=\chapoddpage
\global\let\pagealignmacro=\chapoddpage
@@ -4080,30 +4095,79 @@ width0pt\relax} \fi
\CHAPPAGon
-\def\CHAPFplain{
+\def\CHAPFplain{%
\global\let\chapmacro=\chfplain
-\global\let\unnumbchapmacro=\unnchfplain
\global\let\centerchapmacro=\centerchfplain}
-% Plain chapter opening.
-% #1 is the text, #2 the chapter number or empty if unnumbered.
-\def\chfplain#1#2{%
+% Normal chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chfplain#1#2#3{%
\pchapsepmacro
{%
\chapfonts \rm
- \def\chapnum{#2}%
- \setbox0 = \hbox{#2\ifx\chapnum\empty\else\enspace\fi}%
+ %
+ % Have to define \thissection before calling \donoderef, because the
+ % xref code eventually uses it. On the other hand, it has to be called
+ % after \pchapsepmacro, or the headline will change too soon.
+ \gdef\thissection{#1}%
+ \gdef\thischaptername{#1}%
+ %
+ % Only insert the separating space if we have a chapter/appendix
+ % number, and don't print the unnumbered ``number''.
+ \def\temptype{#2}%
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unnchap}%
+ \def\thischapter{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+ \def\toctype{omit}%
+ \xdef\thischapter{}%
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+ \def\toctype{app}%
+ % We don't substitute the actual chapter name into \thischapter
+ % because we don't want its macros evaluated now. And we don't
+ % use \thissection because that changes with each section.
+ %
+ \xdef\thischapter{\putwordAppendix{} \appendixletter:
+ \noexpand\thischaptername}%
+ \else
+ \setbox0 = \hbox{#3\enspace}%
+ \def\toctype{numchap}%
+ \xdef\thischapter{\putwordChapter{} \the\chapno:
+ \noexpand\thischaptername}%
+ \fi\fi\fi
+ %
+ % Write the toc entry for this chapter. Must come before the
+ % \donoderef, because we include the current node name in the toc
+ % entry, and \donoderef resets it to empty.
+ \writetocentry{\toctype}{#1}{#3}%
+ %
+ % For pdftex, we have to write out the node definition (aka, make
+ % the pdfdest) after any page break, but before the actual text has
+ % been typeset. If the destination for the pdf outline is after the
+ % text, then jumping from the outline may wind up with the text not
+ % being visible, for instance under high magnification.
+ \donoderef{#2}%
+ %
+ % Typeset the actual heading.
\vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
- \hangindent = \wd0 \centerparametersmaybe
+ \hangindent=\wd0 \centerparametersmaybe
\unhbox0 #1\par}%
}%
\nobreak\bigskip % no page break after a chapter title
\nobreak
}
-% Plain opening for unnumbered.
-\def\unnchfplain#1{\chfplain{#1}{}}
-
% @centerchap -- centered and unnumbered.
\let\centerparametersmaybe = \relax
\def\centerchfplain#1{{%
@@ -4112,11 +4176,14 @@ width0pt\relax} \fi
\leftskip = \rightskip
\parfillskip = 0pt
}%
- \chfplain{#1}{}%
+ \chfplain{#1}{Ynothing}{}%
}}
\CHAPFplain % The default
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff. We'll see. --karl, 11aug03.
+%
\def\unnchfopen #1{%
\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
\parindent=0pt\raggedright
@@ -4134,61 +4201,95 @@ width0pt\relax} \fi
\hfill {\rm #1}\hfill}}\bigskip \par\nobreak
}
-\def\CHAPFopen{
+\def\CHAPFopen{%
\global\let\chapmacro=\chfopen
-\global\let\unnumbchapmacro=\unnchfopen
\global\let\centerchapmacro=\centerchfopen}
-% Section titles.
+% Section titles. These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
\newskip\secheadingskip
-\def\secheadingbreak{\dobreak \secheadingskip {-1000}}
-\def\secheading#1#2#3{\sectionheading{sec}{#2.#3}{#1}}
-\def\plainsecheading#1{\sectionheading{sec}{}{#1}}
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
% Subsection titles.
-\newskip \subsecheadingskip
-\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}}
-\def\subsecheading#1#2#3#4{\sectionheading{subsec}{#2.#3.#4}{#1}}
-\def\plainsubsecheading#1{\sectionheading{subsec}{}{#1}}
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
% Subsubsection titles.
-\let\subsubsecheadingskip = \subsecheadingskip
-\let\subsubsecheadingbreak = \subsecheadingbreak
-\def\subsubsecheading#1#2#3#4#5{\sectionheading{subsubsec}{#2.#3.#4.#5}{#1}}
-\def\plainsubsubsecheading#1{\sectionheading{subsubsec}{}{#1}}
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
-% Print any size section title.
-%
-% #1 is the section type (sec/subsec/subsubsec), #2 is the section
-% number (maybe empty), #3 the text.
-\def\sectionheading#1#2#3{%
- {%
- \expandafter\advance\csname #1headingskip\endcsname by \parskip
- \csname #1headingbreak\endcsname
- }%
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\sectionheading#1#2#3#4{%
{%
% Switch to the right set of fonts.
- \csname #1fonts\endcsname \rm
+ \csname #2fonts\endcsname \rm
+ %
+ % Insert space above the heading.
+ \csname #2headingbreak\endcsname
%
- % Only insert the separating space if we have a section number.
- \def\secnum{#2}%
- \setbox0 = \hbox{#2\ifx\secnum\empty\else\enspace\fi}%
+ % Only insert the space after the number if we have a section number.
+ \def\sectionlevel{#2}%
+ \def\temptype{#3}%
+ %
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unn}%
+ \gdef\thissection{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ % for @headings -- no section number, don't include in toc,
+ % and don't redefine \thissection.
+ \setbox0 = \hbox{}%
+ \def\toctype{omit}%
+ \let\sectionlevel=\empty
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{app}%
+ \gdef\thissection{#1}%
+ \else
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{num}%
+ \gdef\thissection{#1}%
+ \fi\fi\fi
%
+ % Write the toc entry (before \donoderef). See comments in \chfplain.
+ \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+ %
+ % Write the node reference (= pdf destination for pdftex).
+ % Again, see comments in \chfplain.
+ \donoderef{#3}%
+ %
+ % Output the actual section heading.
\vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
- \hangindent = \wd0 % zero if no section number
- \unhbox0 #3}%
+ \hangindent=\wd0 % zero if no section number
+ \unhbox0 #1}%
}%
- % Add extra space after the heading -- either a line space or a
- % paragraph space, whichever is more. (Some people like to set
- % \parskip to large values for some reason.) Don't allow stretch, though.
+ % Add extra space after the heading -- half of whatever came above it.
+ % Don't allow stretch, though.
+ \kern .5 \csname #2headingskip\endcsname
+ %
+ % Do not let the kern be a potential breakpoint, as it would be if it
+ % was followed by glue.
\nobreak
- \ifdim\parskip>\normalbaselineskip
- \kern\parskip
- \else
- \kern\normalbaselineskip
- \fi
+ %
+ % We'll almost certainly start a paragraph next, so don't let that
+ % glue accumulate. (Not a breakpoint because it's preceded by a
+ % discardable item.)
+ \vskip-\parskip
+ %
+ % This \nobreak is purely so the last item on the list is a \penalty
+ % of 10000. This is so other code, for instance \parsebodycommon, can
+ % check for and avoid allowing breakpoints. Otherwise, it would
+ % insert a valid breakpoint between:
+ % @section sec-whatever
+ % @deffn def-whatever
\nobreak
}
@@ -4198,119 +4299,152 @@ width0pt\relax} \fi
\newwrite\tocfile
% Write an entry to the toc file, opening it if necessary.
-% Called from @chapter, etc. We supply {\folio} at the end of the
-% argument, which will end up as the last argument to the \...entry macro.
-%
-% Usage: \writetocentry{chap}{The Name of The Game}{{\the\chapno}}
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this. The node name is used in the pdf outlines as the
+% destination to jump to.
+%
% We open the .toc file for writing here instead of at @setfilename (or
% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything. This is used for the
+% table of contents chapter openings themselves.
%
\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
\def\writetocentry#1#2#3{%
- \iftocfileopened\else
- \immediate\openout\tocfile = \jobname.toc
- \global\tocfileopenedtrue
- \fi
- %
- \iflinks
- \toks0 = {#2}%
- \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}#3{\folio}}}%
- \temp
+ \edef\writetoctype{#1}%
+ \ifx\writetoctype\omitkeyword \else
+ \iftocfileopened\else
+ \immediate\openout\tocfile = \jobname.toc
+ \global\tocfileopenedtrue
+ \fi
+ %
+ \iflinks
+ \toks0 = {#2}%
+ \toks2 = \expandafter{\lastnode}%
+ \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}{#3}%
+ {\the\toks2}{\noexpand\folio}}}%
+ \temp
+ \fi
\fi
%
- % Tell \shipout to create a page destination if we're doing pdf, which
- % will be the target of the links in the table of contents. We can't
- % just do it on every page because the title pages are numbered 1 and
- % 2 (the page numbers aren't printed), and so are the first two pages
- % of the document. Thus, we'd have two destinations named `1', and
- % two named `2'.
- \ifpdf \pdfmakepagedesttrue \fi
+ % Tell \shipout to create a pdf destination on each page, if we're
+ % writing pdf. These are used in the table of contents. We can't
+ % just write one on every page because the title pages are numbered
+ % 1 and 2 (the page numbers aren't printed), and so are the first
+ % two pages of the document. Thus, we'd have two destinations named
+ % `1', and two named `2'.
+ \ifpdf \global\pdfmakepagedesttrue \fi
}
\newskip\contentsrightmargin \contentsrightmargin=1in
\newcount\savepageno
\newcount\lastnegativepageno \lastnegativepageno = -1
-% Finish up the main text and prepare to read what we've written
-% to \tocfile.
+% Prepare to read what we've written to \tocfile.
%
\def\startcontents#1{%
- % If @setchapternewpage on, and @headings double, the contents should
- % start on an odd page, unlike chapters. Thus, we maintain
- % \contentsalignmacro in parallel with \pagealignmacro.
- % From: Torbjorn Granlund <tege@matematik.su.se>
- \contentsalignmacro
- \immediate\closeout\tocfile
- %
- % Don't need to put `Contents' or `Short Contents' in the headline.
- % It is abundantly clear what they are.
- \unnumbchapmacro{#1}\def\thischapter{}%
- \savepageno = \pageno
- \begingroup % Set up to handle contents files properly.
- \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11
- % We can't do this, because then an actual ^ in a section
- % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97.
- %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
- \raggedbottom % Worry more about breakpoints than the bottom.
- \advance\hsize by -\contentsrightmargin % Don't use the full line length.
- %
- % Roman numerals for page numbers.
- \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+ % If @setchapternewpage on, and @headings double, the contents should
+ % start on an odd page, unlike chapters. Thus, we maintain
+ % \contentsalignmacro in parallel with \pagealignmacro.
+ % From: Torbjorn Granlund <tege@matematik.su.se>
+ \contentsalignmacro
+ \immediate\closeout\tocfile
+ %
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \def\thischapter{}%
+ \chapmacro{#1}{Yomitfromtoc}{}%
+ %
+ \savepageno = \pageno
+ \begingroup % Set up to handle contents files properly.
+ \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11
+ % We can't do this, because then an actual ^ in a section
+ % title fails, e.g., @chapter ^ -- exponentiation. --karl, 9jul97.
+ %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
+ \raggedbottom % Worry more about breakpoints than the bottom.
+ \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+ %
+ % Roman numerals for page numbers.
+ \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
}
% Normal (long) toc.
\def\contents{%
- \startcontents{\putwordTOC}%
- \openin 1 \jobname.toc
- \ifeof 1 \else
- \closein 1
- \input \jobname.toc
- \fi
- \vfill \eject
- \contentsalignmacro % in case @setchapternewpage odd is in effect
- \pdfmakeoutlines
- \endgroup
- \lastnegativepageno = \pageno
- \global\pageno = \savepageno
+ \startcontents{\putwordTOC}%
+ \openin 1 \jobname.toc
+ \ifeof 1 \else
+ \input \jobname.toc
+ \fi
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \ifeof 1 \else
+ \pdfmakeoutlines
+ \fi
+ \closein 1
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
}
% And just the chapters.
\def\summarycontents{%
- \startcontents{\putwordShortTOC}%
- %
- \let\chapentry = \shortchapentry
- \let\appendixentry = \shortappendixentry
- \let\unnumbchapentry = \shortunnumberedentry
- % We want a true roman here for the page numbers.
- \secfonts
- \let\rm=\shortcontrm \let\bf=\shortcontbf
- \let\sl=\shortcontsl \let\tt=\shortconttt
- \rm
- \hyphenpenalty = 10000
- \advance\baselineskip by 1pt % Open it up a little.
- \def\secentry ##1##2##3##4{}
- \def\subsecentry ##1##2##3##4##5{}
- \def\subsubsecentry ##1##2##3##4##5##6{}
- \let\unnumbsecentry = \secentry
- \let\unnumbsubsecentry = \subsecentry
- \let\unnumbsubsubsecentry = \subsubsecentry
- \openin 1 \jobname.toc
- \ifeof 1 \else
- \closein 1
- \input \jobname.toc
- \fi
- \vfill \eject
- \contentsalignmacro % in case @setchapternewpage odd is in effect
- \endgroup
- \lastnegativepageno = \pageno
- \global\pageno = \savepageno
+ \startcontents{\putwordShortTOC}%
+ %
+ \let\numchapentry = \shortchapentry
+ \let\appentry = \shortchapentry
+ \let\unnchapentry = \shortunnchapentry
+ % We want a true roman here for the page numbers.
+ \secfonts
+ \let\rm=\shortcontrm \let\bf=\shortcontbf
+ \let\sl=\shortcontsl \let\tt=\shortconttt
+ \rm
+ \hyphenpenalty = 10000
+ \advance\baselineskip by 1pt % Open it up a little.
+ \def\numsecentry##1##2##3##4{}
+ \let\appsecentry = \numsecentry
+ \let\unnsecentry = \numsecentry
+ \let\numsubsecentry = \numsecentry
+ \let\appsubsecentry = \numsecentry
+ \let\unnsubsecentry = \numsecentry
+ \let\numsubsubsecentry = \numsecentry
+ \let\appsubsubsecentry = \numsecentry
+ \let\unnsubsubsecentry = \numsecentry
+ \openin 1 \jobname.toc
+ \ifeof 1 \else
+ \input \jobname.toc
+ \fi
+ \closein 1
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
}
\let\shortcontents = \summarycontents
-\ifpdf
- \pdfcatalog{/PageMode /UseOutlines}%
-\fi
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+ % This space should be enough, since a single number is .5em, and the
+ % widest letter (M) is 1em, at least in the Computer Modern fonts.
+ % But use \hss just in case.
+ % (This space doesn't include the extra space that gets added after
+ % the label; that gets put in by \shortchapentry above.)
+ %
+ % We'd like to right-justify chapter numbers, but that looks strange
+ % with appendix letters. And right-justifying numbers and
+ % left-justifying letters looks strange when there is less than 10
+ % chapters. Have to read the whole toc once to know how many chapters
+ % there are before deciding ...
+ \hbox to 1em{#1\hss}%
+}
% These macros generate individual entries in the table of contents.
% The first argument is the chapter or section name.
@@ -4318,58 +4452,45 @@ width0pt\relax} \fi
% The arguments in between are the chapter number, section number, ...
% Chapters, in the main contents.
-\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}}
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
%
% Chapters, in the short toc.
% See comments in \dochapentry re vbox and related settings.
-\def\shortchapentry#1#2#3{%
- \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#3\egroup}%
+\def\shortchapentry#1#2#3#4{%
+ \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
}
% Appendices, in the main contents.
-\def\appendixentry#1#2#3{%
- \dochapentry{\appendixbox{\putwordAppendix{} #2}\labelspace#1}{#3}}
-%
-% Appendices, in the short toc.
-\let\shortappendixentry = \shortchapentry
-
-% Typeset the label for a chapter or appendix for the short contents.
-% The arg is, e.g., `Appendix A' for an appendix, or `3' for a chapter.
-% We could simplify the code here by writing out an \appendixentry
-% command in the toc file for appendices, instead of using \chapentry
-% for both, but it doesn't seem worth it.
-%
-\newdimen\shortappendixwidth
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+ % We use M since it's probably the widest letter.
+ \setbox0 = \hbox{\putwordAppendix{} M}%
+ \hbox to \wd0{\putwordAppendix{} #1\hss}}
%
-\def\shortchaplabel#1{%
- % This space should be enough, since a single number is .5em, and the
- % widest letter (M) is 1em, at least in the Computer Modern fonts.
- % But use \hss just in case.
- % (This space doesn't include the extra space that gets added after
- % the label; that gets put in by \shortchapentry above.)
- \dimen0 = 1em
- \hbox to \dimen0{#1\hss}%
-}
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
% Unnumbered chapters.
-\def\unnumbchapentry#1#2#3{\dochapentry{#1}{#3}}
-\def\shortunnumberedentry#1#2#3{\tocentry{#1}{\doshortpageno\bgroup#3\egroup}}
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
% Sections.
-\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}}
-\def\unnumbsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
% Subsections.
-\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}}
-\def\unnumbsubsecentry#1#2#3#4#5{\dosubsecentry{#1}{#5}}
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
% And subsubsections.
-\def\subsubsecentry#1#2#3#4#5#6{%
- \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}}
-\def\unnumbsubsubsecentry#1#2#3#4#5#6{\dosubsubsecentry{#1}{#6}}
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
% This parameter controls the indentation of the various levels.
-\newdimen\tocindent \tocindent = 3pc
+\newdimen\tocindent \tocindent = 2pc
% Now for the actual typesetting. In all these, #1 is the text and #2 is the
% page number.
@@ -4400,17 +4521,8 @@ width0pt\relax} \fi
\tocentry{#1}{\dopageno\bgroup#2\egroup}%
\endgroup}
-% Final typesetting of a toc entry; we use the same \entry macro as for
-% the index entries, but we want to suppress hyphenation here. (We
-% can't do that in the \entry macro, since index entries might consist
-% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.)
-\def\tocentry#1#2{\begingroup
- \vskip 0pt plus1pt % allow a little stretch for the sake of nice page breaks
- % Do not use \turnoffactive in these arguments. Since the toc is
- % typeset in cmr, characters such as _ would come out wrong; we
- % have to do the usual translation tricks.
- \entry{#1}{#2}%
-\endgroup}
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
% Space between chapter (or whatever) number and the title.
\def\labelspace{\hskip1em \relax}
@@ -4420,8 +4532,8 @@ width0pt\relax} \fi
\def\chapentryfonts{\secfonts \rm}
\def\secentryfonts{\textfonts}
-\let\subsecentryfonts = \textfonts
-\let\subsubsecentryfonts = \textfonts
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
\message{environments,}
@@ -4448,10 +4560,10 @@ width0pt\relax} \fi
% The text. (`r' is open on the right, `e' somewhat less so on the left.)
\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
%
-\global\setbox\errorbox=\hbox to \dimen0{\hfil
+\setbox\errorbox=\hbox to \dimen0{\hfil
\hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
\advance\hsize by -2\dimen2 % Rules.
- \vbox{
+ \vbox{%
\hrule height\dimen2
\hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
\vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
@@ -4465,14 +4577,13 @@ width0pt\relax} \fi
% One exception: @ is still an escape character, so that @end tex works.
% But \@ or @@ will get a plain tex @ character.
-\def\tex{\begingroup
+\envdef\tex{%
\catcode `\\=0 \catcode `\{=1 \catcode `\}=2
\catcode `\$=3 \catcode `\&=4 \catcode `\#=6
\catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
\catcode `\%=14
\catcode `\+=\other
\catcode `\"=\other
- \catcode `\==\other
\catcode `\|=\other
\catcode `\<=\other
\catcode `\>=\other
@@ -4488,6 +4599,7 @@ width0pt\relax} \fi
\let\!=\ptexexclam
\let\i=\ptexi
\let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
\let\{=\ptexlbrace
\let\+=\tabalign
\let\}=\ptexrbrace
@@ -4498,10 +4610,11 @@ width0pt\relax} \fi
\def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
\def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
\def\@{@}%
-\let\Etex=\endgroup}
+}
+% There is no need to define \Etex.
% Define @lisp ... @end lisp.
-% @lisp does a \begingroup so it can rebind things,
+% @lisp environment forms a group so it can rebind things,
% including the definition of @end lisp (which normally is erroneous).
% Amount to narrow the margins by for @lisp.
@@ -4512,19 +4625,6 @@ width0pt\relax} \fi
% have any width.
\def\lisppar{\null\endgraf}
-% Make each space character in the input produce a normal interword
-% space in the output. Don't allow a line break at this space, as this
-% is used only in environments like @example, where each line of input
-% should produce a line of output anyway.
-%
-{\obeyspaces %
-\gdef\sepspaces{\obeyspaces\let =\tie}}
-
-% Define \obeyedspace to be our active space, whatever it is. This is
-% for use in \parsearg.
-{\sepspaces%
-\global\let\obeyedspace= }
-
% This space is always present above and below environments.
\newskip\envskipamount \envskipamount = 0pt
@@ -4574,52 +4674,52 @@ width0pt\relax} \fi
%
\newskip\lskip\newskip\rskip
-\def\cartouche{%
-\par % can't be in the midst of a paragraph.
-\begingroup
- \lskip=\leftskip \rskip=\rightskip
- \leftskip=0pt\rightskip=0pt %we want these *outside*.
- \cartinner=\hsize \advance\cartinner by-\lskip
- \advance\cartinner by-\rskip
- \cartouter=\hsize
- \advance\cartouter by 18.4pt % allow for 3pt kerns on either
-% side, and for 6pt waste from
-% each corner char, and rule thickness
- \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
- % Flag to tell @lisp, etc., not to narrow margin.
- \let\nonarrowing=\comment
- \vbox\bgroup
- \baselineskip=0pt\parskip=0pt\lineskip=0pt
- \carttop
- \hbox\bgroup
- \hskip\lskip
- \vrule\kern3pt
- \vbox\bgroup
- \hsize=\cartinner
- \kern3pt
- \begingroup
- \baselineskip=\normbskip
- \lineskip=\normlskip
- \parskip=\normpskip
- \vskip -\parskip
+\envdef\cartouche{%
+ \ifhmode\par\fi % can't be in the midst of a paragraph.
+ \startsavinginserts
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt % we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+ % side, and for 6pt waste from
+ % each corner char, and rule thickness
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ % Flag to tell @lisp, etc., not to narrow margin.
+ \let\nonarrowing=\comment
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \kern3pt
+ \hsize=\cartinner
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
+ \comment % For explanation, see the end of \def\group.
+}
\def\Ecartouche{%
- \endgroup
- \kern3pt
- \egroup
- \kern3pt\vrule
- \hskip\rskip
- \egroup
- \cartbot
- \egroup
-\endgroup
-}}
+ \ifhmode\par\fi
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
+ \checkinserts
+}
% This macro is called at the beginning of all the @example variants,
% inside a group.
\def\nonfillstart{%
\aboveenvbreak
- \inENV % This group ends at the end of the body
\hfuzz = 12pt % Don't be fussy
\sepspaces % Make spaces be word-separators rather than space tokens.
\let\par = \lisppar % don't ignore blank lines
@@ -4632,103 +4732,71 @@ width0pt\relax} \fi
\ifx\nonarrowing\relax
\advance \leftskip by \lispnarrowing
\exdentamount=\lispnarrowing
- \let\exdent=\nofillexdent
- \let\nonarrowing=\relax
\fi
+ \let\exdent=\nofillexdent
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it by one command:
+\def\makedispenv #1#2{
+ \expandafter\envdef\csname#1\endcsname{#2}
+ \expandafter\envdef\csname small#1\endcsname
+ {\smallexamplefonts \rm #2}
+ \expandafter\let\csname E#1\endcsname \afterenvbreak
+ \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% And there are often two synonyms:
+\def\maketwodispenvs #1#2#3{
+ \makedispenv{#1}{#3}
+ \makedispenv{#2}{#3}
}
-% Define the \E... control sequence only if we are inside the particular
-% environment, so the error checking in \end will work.
+% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
%
-% To end an @example-like environment, we first end the paragraph (via
-% \afterenvbreak's vertical glue), and then the group. That way we keep
-% the zero \parskip that the environments set -- \parskip glue will be
-% inserted at the beginning of the next paragraph in the document, after
-% the environment.
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
%
-\def\nonfillfinish{\afterenvbreak\endgroup}
-
-% @lisp: indented, narrowed, typewriter font.
-\def\lisp{\begingroup
+\maketwodispenvs {lisp}{example}{%
\nonfillstart
- \let\Elisp = \nonfillfinish
\tt
\let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
\gobble % eat return
}
-% @example: Same as @lisp.
-\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp}
-
-% @smallexample and @smalllisp: use smaller fonts.
-% Originally contributed by Pavel@xerox.
-\def\smalllisp{\begingroup
- \def\Esmalllisp{\nonfillfinish\endgroup}%
- \def\Esmallexample{\nonfillfinish\endgroup}%
- \smallexamplefonts
- \lisp
-}
-\let\smallexample = \smalllisp
-
-
-% @display: same as @lisp except keep current font.
+% @display/@smalldisplay: same as @lisp except keep current font.
%
-\def\display{\begingroup
+\makedispenv {display}{%
\nonfillstart
- \let\Edisplay = \nonfillfinish
\gobble
}
-%
-% @smalldisplay: @display plus smaller fonts.
-%
-\def\smalldisplay{\begingroup
- \def\Esmalldisplay{\nonfillfinish\endgroup}%
- \smallexamplefonts \rm
- \display
-}
-% @format: same as @display except don't narrow margins.
+% @format/@smallformat: same as @display except don't narrow margins.
+% @flushleft (same as @format). (Note: @smallflushleft not documeted.)
%
-\def\format{\begingroup
- \let\nonarrowing = t
+\maketwodispenvs {format}{flushleft}{%
+ \let\nonarrowing = t%
\nonfillstart
- \let\Eformat = \nonfillfinish
\gobble
}
-%
-% @smallformat: @format plus smaller fonts.
-%
-\def\smallformat{\begingroup
- \def\Esmallformat{\nonfillfinish\endgroup}%
- \smallexamplefonts \rm
- \format
-}
-
-% @flushleft (same as @format).
-%
-\def\flushleft{\begingroup \def\Eflushleft{\nonfillfinish\endgroup}\format}
% @flushright.
%
-\def\flushright{\begingroup
- \let\nonarrowing = t
+\envdef\flushright{%
+ \let\nonarrowing = t%
\nonfillstart
- \let\Eflushright = \nonfillfinish
\advance\leftskip by 0pt plus 1fill
\gobble
}
+\let\Eflushright = \afterenvbreak
% @quotation does normal linebreaking (hence we can't use \nonfillstart)
% and narrows the margins.
%
-\def\quotation{%
- \begingroup\inENV %This group ends at the end of the @quotation body
+\envdef\quotation{%
{\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
\parindent=0pt
- % We have retained a nonzero parskip for the environment, since we're
- % doing normal filling. So to avoid extra space below the environment...
- \def\Equotation{\parskip = 0pt \nonfillfinish}%
%
% @cartouche defines \nonarrowing to inhibit narrowing at next level down.
\ifx\nonarrowing\relax
@@ -4737,6 +4805,19 @@ width0pt\relax} \fi
\exdentamount = \lispnarrowing
\let\nonarrowing = \relax
\fi
+ \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling. So to avoid extra space below the environment...
+\def\Equotation{\parskip = 0pt \afterenvbreak}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty \else
+ {\bf #1: }%
+ \fi
}
@@ -4758,7 +4839,7 @@ width0pt\relax} \fi
%
% [Knuth] p. 380
\def\uncatcodespecials{%
- \def\do##1{\catcode`##1=12}\dospecials}
+ \def\do##1{\catcode`##1=\other}\dospecials}
%
% [Knuth] pp. 380,381,391
% Disable Spanish ligatures ?` and !` of \tt font
@@ -4806,6 +4887,8 @@ width0pt\relax} \fi
}
\endgroup
\def\setupverbatim{%
+ \nonfillstart
+ \advance\leftskip by -\defbodyindent
% Easiest (and conventionally used) font for verbatim
\tt
\def\par{\leavevmode\egroup\box0\endgraf}%
@@ -4827,7 +4910,7 @@ width0pt\relax} \fi
%
% [Knuth] p. 382; only eat outer {}
\begingroup
- \catcode`[=1\catcode`]=2\catcode`\{=12\catcode`\}=12
+ \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
\gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
\endgroup
%
@@ -4844,13 +4927,6 @@ width0pt\relax} \fi
% we need not redefine '\', '{' and '}'.
%
% Inspired by LaTeX's verbatim command set [latex.ltx]
-%% Include LaTeX hack for completeness -- never know
-%% \begingroup
-%% \catcode`|=0 \catcode`[=1
-%% \catcode`]=2\catcode`\{=12\catcode`\}=12\catcode`\ =\active
-%% \catcode`\\=12|gdef|doverbatim#1@end verbatim[
-%% #1|endgroup|def|Everbatim[]|end[verbatim]]
-%% |endgroup
%
\begingroup
\catcode`\ =\active
@@ -4858,49 +4934,28 @@ width0pt\relax} \fi
% ignore everything up to the first ^^M, that's the newline at the end
% of the @verbatim input line itself. Otherwise we get an extra blank
% line in the output.
- \gdef\doverbatim#1^^M#2@end verbatim{#2\end{verbatim}}%
+ \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+ % We really want {...\end verbatim} in the body of the macro, but
+ % without the active space; thus we have to use \xdef and \gobble.
\endgroup
%
-\def\verbatim{%
- \def\Everbatim{\nonfillfinish\endgroup}%
- \begingroup
- \nonfillstart
- \advance\leftskip by -\defbodyindent
- \begingroup\setupverbatim\doverbatim
+\envdef\verbatim{%
+ \setupverbatim\doverbatim
}
+\let\Everbatim = \afterenvbreak
+
% @verbatiminclude FILE - insert text of file in verbatim environment.
%
-% Allow normal characters that we make active in the argument (a file name).
-\def\verbatiminclude{%
- \begingroup
- \catcode`\\=\other
- \catcode`~=\other
- \catcode`^=\other
- \catcode`_=\other
- \catcode`|=\other
- \catcode`<=\other
- \catcode`>=\other
- \catcode`+=\other
- \parsearg\doverbatiminclude
-}
-\def\setupverbatiminclude{%
- \begingroup
- \nonfillstart
- \advance\leftskip by -\defbodyindent
- \begingroup\setupverbatim
-}
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
%
\def\doverbatiminclude#1{%
- % Restore active chars for included file.
- \endgroup
- \begingroup
- \let\value=\expandablevalue
- \def\thisfile{#1}%
- \expandafter\expandafter\setupverbatiminclude\input\thisfile
- \endgroup
- \nonfillfinish
- \endgroup
+ {%
+ \makevalueexpandable
+ \setupverbatim
+ \input #1
+ \afterenvbreak
+ }%
}
% @copying ... @end copying.
@@ -4975,581 +5030,335 @@ width0pt\relax} \fi
\message{defuns,}
% @defun etc.
-% Allow user to change definition object font (\df) internally
-\def\setdeffont#1 {\csname DEF#1\endcsname}
-
\newskip\defbodyindent \defbodyindent=.4in
\newskip\defargsindent \defargsindent=50pt
\newskip\deflastargmargin \deflastargmargin=18pt
-\newcount\parencount
-
-% We want ()&[] to print specially on the defun line.
-%
-\def\activeparens{%
- \catcode`\(=\active \catcode`\)=\active
- \catcode`\&=\active
- \catcode`\[=\active \catcode`\]=\active
-}
-
-% Make control sequences which act like normal parenthesis chars.
-\let\lparen = ( \let\rparen = )
-
-{\activeparens % Now, smart parens don't turn on until &foo (see \amprm)
-
-% Be sure that we always have a definition for `(', etc. For example,
-% if the fn name has parens in it, \boldbrax will not be in effect yet,
-% so TeX would otherwise complain about undefined control sequence.
-\global\let(=\lparen \global\let)=\rparen
-\global\let[=\lbrack \global\let]=\rbrack
-
-\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 }
-\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
-% This is used to turn on special parens
-% but make & act ordinary (given that it's active).
-\gdef\boldbraxnoamp{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb\let&=\ampnr}
-
-% Definitions of (, ) and & used in args for functions.
-% This is the definition of ( outside of all parentheses.
-\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested
- \global\advance\parencount by 1
-}
-%
-% This is the definition of ( when already inside a level of parens.
-\gdef\opnested{\char`\(\global\advance\parencount by 1 }
-%
-\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0.
- % also in that case restore the outer-level definition of (.
- \ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi
- \global\advance \parencount by -1 }
-% If we encounter &foo, then turn on ()-hacking afterwards
-\gdef\amprm#1 {{\rm\&#1}\let(=\oprm \let)=\clrm\ }
-%
-\gdef\normalparens{\boldbrax\let&=\ampnr}
-} % End of definition inside \activeparens
-%% These parens (in \boldbrax) actually are a little bolder than the
-%% contained text. This is especially needed for [ and ]
-\def\opnr{{\sf\char`\(}\global\advance\parencount by 1 }
-\def\clnr{{\sf\char`\)}\global\advance\parencount by -1 }
-\let\ampnr = \&
-\def\lbrb{{\bf\char`\[}}
-\def\rbrb{{\bf\char`\]}}
-
-% Active &'s sneak into the index arguments, so make sure it's defined.
-{
- \catcode`& = \active
- \global\let& = \ampnr
-}
-
-% \defname, which formats the name of the @def (not the args).
-% #1 is the function name.
-% #2 is the type of definition, such as "Function".
-%
-\def\defname#1#2{%
- % How we'll output the type name. Putting it in brackets helps
- % distinguish it from the body text that may end up on the next line
- % just below it.
- \ifempty{#2}%
- \def\defnametype{}%
+% Start the processing of @deffn:
+\def\startdefun{%
+ \ifnum\lastpenalty<10000
+ \medbreak
\else
- \def\defnametype{[\rm #2]}%
+ % If there are two @def commands in a row, we'll have a \nobreak,
+ % which is there to keep the function description together with its
+ % header. But if there's nothing but headers, we need to allow a
+ % break somewhere. Check for penalty 10002 (inserted by
+ % \defargscommonending) instead of 10000, since the sectioning
+ % commands insert a \penalty10000, and we don't want to allow a break
+ % between a section heading and a defun.
+ \ifnum\lastpenalty=10002 \penalty2000 \fi
+ %
+ % Similarly, after a section heading, do not allow a break.
+ % But do insert the glue.
+ \medskip % preceded by discardable penalty, so not a breakpoint
\fi
%
- % Get the values of \leftskip and \rightskip as they were outside the @def...
- \dimen2=\leftskip
- \advance\dimen2 by -\defbodyindent
- %
- % Figure out values for the paragraph shape.
- \setbox0=\hbox{\hskip \deflastargmargin{\defnametype}}%
- \dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line
- \dimen1=\hsize \advance \dimen1 by -\defargsindent % size for continuations
- \parshape 2 0in \dimen0 \defargsindent \dimen1
- %
- % Output arg 2 ("Function" or some such) but stuck inside a box of
- % width 0 so it does not interfere with linebreaking.
- \noindent
- %
- {% Adjust \hsize to exclude the ambient margins,
- % so that \rightline will obey them.
- \advance \hsize by -\dimen2
- \dimen3 = 0pt % was -1.25pc
- \rlap{\rightline{\defnametype\kern\dimen3}}%
- }%
- %
- % Allow all lines to be underfull without complaint:
- \tolerance=10000 \hbadness=10000
- \advance\leftskip by -\defbodyindent
- \exdentamount=\defbodyindent
- {\df #1}\enskip % output function name
- % \defunargs will be called next to output the arguments, if any.
-}
-
-% Common pieces to start any @def...
-% #1 is the \E... control sequence to end the definition (which we define).
-% #2 is the \...x control sequence (which our caller defines).
-% #3 is the control sequence to process the header, such as \defunheader.
-%
-\def\parsebodycommon#1#2#3{%
- \begingroup\inENV
- % If there are two @def commands in a row, we'll have a \nobreak,
- % which is there to keep the function description together with its
- % header. But if there's nothing but headers, we want to allow a
- % break after all. Check for penalty 10002 (inserted by
- % \defargscommonending) instead of 10000, since the sectioning
- % commands insert a \penalty10000, and we don't want to allow a break
- % between a section heading and a defun.
- \ifnum\lastpenalty=10002 \penalty0 \fi
- \medbreak
- %
- % Define the \E... end token that this defining construct specifies
- % so that it will exit this group.
- \def#1{\endgraf\endgroup\medbreak}%
- %
\parindent=0in
\advance\leftskip by \defbodyindent
\exdentamount=\defbodyindent
}
-% Common part of the \...x definitions.
-%
-\def\defxbodycommon{%
- % As with \parsebodycommon above, allow line break if we have multiple
- % x headers in a row. It's not a great place, though.
- \ifnum\lastpenalty=10000 \penalty1000 \fi
+\def\dodefunx#1{%
+ % First, check whether we are in the right environment:
+ \checkenv#1%
+ %
+ % As above, allow line break if we have multiple x headers in a row.
+ % It's not a great place, though.
+ \ifnum\lastpenalty=10002 \penalty3000 \fi
%
- \begingroup\obeylines
+ % And now, it's time to reuse the body of the original defun:
+ \expandafter\gobbledefun#1%
}
+\def\gobbledefun#1\startdefun{}
-% Process body of @defun, @deffn, @defmac, etc.
+% \printdefunline \deffnheader{text}
%
-\def\defparsebody#1#2#3{%
- \parsebodycommon{#1}{#2}{#3}%
- \def#2{\defxbodycommon \activeparens \spacesplit#3}%
- \catcode\equalChar=\active
- \begingroup\obeylines\activeparens
- \spacesplit#3%
+\def\printdefunline#1#2{%
+ \begingroup
+ % call \deffnheader:
+ #1#2 \endheader
+ % common ending:
+ \interlinepenalty = 10000
+ \advance\rightskip by 0pt plus 1fil
+ \endgraf
+ \nobreak\vskip -\parskip
+ \penalty 10002 % signal to \startdefun and \dodefunx
+ % Some of the @defun-type tags do not enable magic parentheses,
+ % rendering the following check redundant. But we don't optimize.
+ \checkparencounts
+ \endgroup
}
-% #1, #2, #3 are the common arguments (see \parsebodycommon above).
-% #4, delimited by the space, is the class name.
-%
-\def\defmethparsebody#1#2#3#4 {%
- \parsebodycommon{#1}{#2}{#3}%
- \def#2##1 {\defxbodycommon \activeparens \spacesplit{#3{##1}}}%
- \begingroup\obeylines\activeparens
- % The \empty here prevents misinterpretation of a construct such as
- % @deffn {whatever} {Enharmonic comma}
- % See comments at \deftpparsebody, although in our case we don't have
- % to remove the \empty afterwards, since it is empty.
- \spacesplit{#3{#4}}\empty
-}
+\def\Edefun{\endgraf\medbreak}
-% Used for @deftypemethod and @deftypeivar.
-% #1, #2, #3 are the common arguments (see \defparsebody).
-% #4, delimited by a space, is the class name.
-% #5 is the method's return type.
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remainnig is to define \deffnheader.
%
-\def\deftypemethparsebody#1#2#3#4 #5 {%
- \parsebodycommon{#1}{#2}{#3}%
- \def#2##1 ##2 {\defxbodycommon \activeparens \spacesplit{#3{##1}{##2}}}%
- \begingroup\obeylines\activeparens
- \spacesplit{#3{#4}{#5}}%
+\def\makedefun#1{%
+ \expandafter\let\csname E#1\endcsname = \Edefun
+ \edef\temp{\noexpand\domakedefun
+ \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+ \temp
}
-% Used for @deftypeop. The change from \deftypemethparsebody is an
-% extra argument at the beginning which is the `category', instead of it
-% being the hardwired string `Method' or `Instance Variable'. We have
-% to account for this both in the \...x definition and in parsing the
-% input at hand. Thus also need a control sequence (passed as #5) for
-% the \E... definition to assign the category name to.
+% \domakedefun \deffn \deffnx \deffnheader
%
-\def\deftypeopparsebody#1#2#3#4#5 #6 {%
- \parsebodycommon{#1}{#2}{#3}%
- \def#2##1 ##2 ##3 {\def#4{##1}%
- \defxbodycommon \activeparens \spacesplit{#3{##2}{##3}}}%
- \begingroup\obeylines\activeparens
- \spacesplit{#3{#5}{#6}}%
-}
-
-% For @defop.
-\def\defopparsebody #1#2#3#4#5 {%
- \parsebodycommon{#1}{#2}{#3}%
- \def#2##1 ##2 {\def#4{##1}%
- \defxbodycommon \activeparens \spacesplit{#3{##2}}}%
- \begingroup\obeylines\activeparens
- \spacesplit{#3{#5}}%
-}
-
-% These parsing functions are similar to the preceding ones
-% except that they do not make parens into active characters.
-% These are used for "variables" since they have no arguments.
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
%
-\def\defvarparsebody #1#2#3{%
- \parsebodycommon{#1}{#2}{#3}%
- \def#2{\defxbodycommon \spacesplit#3}%
- \catcode\equalChar=\active
- \begingroup\obeylines
- \spacesplit#3%
+\def\domakedefun#1#2#3{%
+ \envdef#1{%
+ \startdefun
+ \parseargusing\activeparens{\printdefunline#3}%
+ }%
+ \def#2{\dodefunx#1}%
+ \def#3%
}
-% @defopvar.
-\def\defopvarparsebody #1#2#3#4#5 {%
- \parsebodycommon{#1}{#2}{#3}%
- \def#2##1 ##2 {\def#4{##1}%
- \defxbodycommon \spacesplit{#3{##2}}}%
- \begingroup\obeylines
- \spacesplit{#3{#5}}%
-}
+%%% Untyped functions:
-\def\defvrparsebody#1#2#3#4 {%
- \parsebodycommon{#1}{#2}{#3}%
- \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}%
- \begingroup\obeylines
- \spacesplit{#3{#4}}%
-}
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
-% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the
-% type is just `struct', because we lose the braces in `{struct
-% termios}' when \spacesplit reads its undelimited argument. Sigh.
-% \let\deftpparsebody=\defvrparsebody
-%
-% So, to get around this, we put \empty in with the type name. That
-% way, TeX won't find exactly `{...}' as an undelimited argument, and
-% won't strip off the braces.
-%
-\def\deftpparsebody #1#2#3#4 {%
- \parsebodycommon{#1}{#2}{#3}%
- \def#2##1 {\defxbodycommon \spacesplit{#3{##1}}}%
- \begingroup\obeylines
- \spacesplit{\parsetpheaderline{#3{#4}}}\empty
-}
-
-% Fine, but then we have to eventually remove the \empty *and* the
-% braces (if any). That's what this does.
-%
-\def\removeemptybraces\empty#1\relax{#1}
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
-% After \spacesplit has done its work, this is called -- #1 is the final
-% thing to call, #2 the type name (which starts with \empty), and #3
-% (which might be empty) the arguments.
-%
-\def\parsetpheaderline#1#2#3{%
- #1{\removeemptybraces#2\relax}{#3}%
-}%
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
-% Split up #2 (the rest of the input line) at the first space token.
-% call #1 with two arguments:
-% the first is all of #2 before the space token,
-% the second is all of #2 after that space token.
-% If #2 contains no space token, all of it is passed as the first arg
-% and the second is passed as empty.
+% \deffngeneral {subind}category name args
%
-{\obeylines %
- \gdef\spacesplit#1#2^^M{\endgroup\spacesplitx{#1}#2 \relax\spacesplitx}%
- \long\gdef\spacesplitx#1#2 #3#4\spacesplitx{%
- \ifx\relax #3%
- #1{#2}{}%
- \else %
- #1{#2}{#3#4}%
- \fi}%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+ % Remember that \dosubin{fn}{xxx}{} is equivalent to \doind{fn}{xxx}.
+ \dosubind{fn}{\code{#3}}{#1}%
+ \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
}
-% Define @defun.
+%%% Typed functions:
-% This is called to end the arguments processing for all the @def... commands.
-%
-\def\defargscommonending{%
- \interlinepenalty = 10000
- \advance\rightskip by 0pt plus 1fil
- \endgraf
- \nobreak\vskip -\parskip
- \penalty 10002 % signal to \parsebodycommon.
-}
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
-% This expands the args and terminates the paragraph they comprise.
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
%
-\def\defunargs#1{\functionparens \sl
-% Expand, preventing hyphenation at `-' chars.
-% Note that groups don't affect changes in \hyphenchar.
-% Set the font temporarily and use \font in case \setfont made \tensl a macro.
-{\tensl\hyphenchar\font=0}%
-#1%
-{\tensl\hyphenchar\font=45}%
-\ifnum\parencount=0 \else \errmessage{Unbalanced parentheses in @def}\fi%
- \defargscommonending
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{fn}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
}
-\def\deftypefunargs #1{%
-% Expand, preventing hyphenation at `-' chars.
-% Note that groups don't affect changes in \hyphenchar.
-% Use \boldbraxnoamp, not \functionparens, so that & is not special.
-\boldbraxnoamp
-\tclose{#1}% avoid \code because of side effects on active chars
- \defargscommonending
-}
+%%% Typed variables:
-% Do complete processing of one @defun or @defunx line already parsed.
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
-% @deffn Command forward-char nchars
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
-\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader}
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
-\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}%
-\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup %
-\catcode\equalChar=\other % Turn off change made in \defparsebody
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{vr}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
}
-% @defun == @deffn Function
-
-\def\defun{\defparsebody\Edefun\defunx\defunheader}
+%%% Untyped variables:
-\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
-\begingroup\defname {#1}{\putwordDeffunc}%
-\defunargs {#2}\endgroup %
-\catcode\equalChar=\other % Turn off change made in \defparsebody
-}
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
-% @deftypefun int foobar (int @var{foo}, float @var{bar})
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
-\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader}
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
-% #1 is the data type. #2 is the name and args.
-\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax}
-% #1 is the data type, #2 the name, #3 the args.
-\def\deftypefunheaderx #1#2 #3\relax{%
-\doind {fn}{\code{#2}}% Make entry in function index
-\begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypefun}%
-\deftypefunargs {#3}\endgroup %
-\catcode\equalChar=\other % Turn off change made in \defparsebody
+%%% Type:
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+ \doind{tp}{\code{#2}}%
+ \defname{#1}{}{#2}\defunargs{#3\unskip}%
}
-% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar})
-
-\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader}
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
-% \defheaderxcond#1\relax$.$
-% puts #1 in @code, followed by a space, but does nothing if #1 is null.
-\def\defheaderxcond#1#2$.${\ifx#1\relax\else\code{#1#2} \fi}
-
-% #1 is the classification. #2 is the data type. #3 is the name and args.
-\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax}
-% #1 is the classification, #2 the data type, #3 the name, #4 the args.
-\def\deftypefnheaderx #1#2#3 #4\relax{%
-\doind {fn}{\code{#3}}% Make entry in function index
-\begingroup
-\normalparens % notably, turn off `&' magic, which prevents
-% at least some C++ text from working
-\defname {\defheaderxcond#2\relax$.$#3}{#1}%
-\deftypefunargs {#4}\endgroup %
-\catcode\equalChar=\other % Turn off change made in \defparsebody
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+ % Get the values of \leftskip and \rightskip as they were outside the @def...
+ \advance\leftskip by -\defbodyindent
+ %
+ % How we'll format the type name. Putting it in brackets helps
+ % distinguish it from the body text that may end up on the next line
+ % just below it.
+ \def\temp{#1}%
+ \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+ %
+ % Figure out line sizes for the paragraph shape.
+ % The first line needs space for \box0; but if \rightskip is nonzero,
+ % we need only space for the part of \box0 which exceeds it:
+ \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip
+ % The continuations:
+ \dimen2=\hsize \advance\dimen2 by -\defargsindent
+ % (plain.tex says that \dimen1 should be used only as global.)
+ \parshape 2 0in \dimen0 \defargsindent \dimen2
+ %
+ % Put the type name to the right margin.
+ \noindent
+ \hbox to 0pt{%
+ \hfil\box0 \kern-\hsize
+ % \hsize has to be shortened this way:
+ \kern\leftskip
+ % Intentionally do not respect \rightskip, since we need the space.
+ }%
+ %
+ % Allow all lines to be underfull without complaint:
+ \tolerance=10000 \hbadness=10000
+ \exdentamount=\defbodyindent
+ {%
+ % defun fonts. We use typewriter by default (used to be bold) because:
+ % . we're printing identifiers, they should be in tt in principle.
+ % . in languages with many accents, such as Czech or French, it's
+ % common to leave accents off identifiers. The result looks ok in
+ % tt, but exceedingly strange in rm.
+ % . we don't want -- and --- to be treated as ligatures.
+ % . this still does not fix the ?` and !` ligatures, but so far no
+ % one has made identifiers using them :).
+ \df \tt
+ \def\temp{#2}% return value type
+ \ifx\temp\empty\else \tclose{\temp} \fi
+ #3% output function name
+ }%
+ {\rm\enskip}% hskip 0.5 em of \tenrm
+ %
+ \boldbrax
+ % arguments will be output next, if any.
+}
+
+% Print arguments in slanted typewriter, prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+ % use sl by default (not ttsl), inconsistently with using tt for the
+ % name. This is because literal text is sometimes needed in the
+ % argument list (groff manual), and ttsl and tt are not very
+ % distinguishable.
+ % tt for the names.
+ \df \sl \hyphenchar\font=0
+ % On the other hand, if an argument has two dashes (for instance), we
+ % want a way to get ttsl. Let's try @var for that.
+ \let\var=\ttslanted
+ #1%
+ \sl\hyphenchar\font=45
}
-% @defmac == @deffn Macro
-
-\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader}
-
-\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
-\begingroup\defname {#1}{\putwordDefmac}%
-\defunargs {#2}\endgroup %
-\catcode\equalChar=\other % Turn off change made in \defparsebody
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+ \catcode`\(=\active \catcode`\)=\active
+ \catcode`\[=\active \catcode`\]=\active
+ \catcode`\&=\active
}
-% @defspec == @deffn Special Form
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
-\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader}
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+ \activeparens
+ \global\let(=\lparen \global\let)=\rparen
+ \global\let[=\lbrack \global\let]=\rbrack
+ \global\let& = \&
-\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
-\begingroup\defname {#1}{\putwordDefspec}%
-\defunargs {#2}\endgroup %
-\catcode\equalChar=\other % Turn off change made in \defparsebody
+ \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+ \gdef\magicamp{\let&=\amprm}
}
-% @defop CATEGORY CLASS OPERATION ARG...
-%
-\def\defop #1 {\def\defoptype{#1}%
-\defopparsebody\Edefop\defopx\defopheader\defoptype}
-%
-\def\defopheader#1#2#3{%
- \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% function index entry
- \begingroup
- \defname{#2}{\defoptype\ \putwordon\ #1}%
- \defunargs{#3}%
- \endgroup
-}
+\newcount\parencount
-% @deftypeop CATEGORY CLASS TYPE OPERATION ARG...
-%
-\def\deftypeop #1 {\def\deftypeopcategory{#1}%
- \deftypeopparsebody\Edeftypeop\deftypeopx\deftypeopheader
- \deftypeopcategory}
-%
-% #1 is the class name, #2 the data type, #3 the operation name, #4 the args.
-\def\deftypeopheader#1#2#3#4{%
- \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index
- \begingroup
- \defname{\defheaderxcond#2\relax$.$#3}
- {\deftypeopcategory\ \putwordon\ \code{#1}}%
- \deftypefunargs{#4}%
- \endgroup
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+ \ifampseen
+ % At the first level, print parens in roman,
+ % otherwise use the default font.
+ \ifnum \parencount=1 \rm \fi
+ \else
+ % The \sf parens (in \boldbrax) actually are a little bolder than
+ % the contained text. This is especially needed for [ and ] .
+ \sf
+ \fi
}
-
-% @deftypemethod CLASS TYPE METHOD ARG...
-%
-\def\deftypemethod{%
- \deftypemethparsebody\Edeftypemethod\deftypemethodx\deftypemethodheader}
-%
-% #1 is the class name, #2 the data type, #3 the method name, #4 the args.
-\def\deftypemethodheader#1#2#3#4{%
- \dosubind{fn}{\code{#3}}{\putwordon\ \code{#1}}% entry in function index
- \begingroup
- \defname{\defheaderxcond#2\relax$.$#3}{\putwordMethodon\ \code{#1}}%
- \deftypefunargs{#4}%
- \endgroup
+\def\infirstlevel#1{%
+ \ifampseen
+ \ifnum\parencount=1
+ #1%
+ \fi
+ \fi
}
+\def\bfafterword#1 {#1 \bf}
-% @deftypeivar CLASS TYPE VARNAME
-%
-\def\deftypeivar{%
- \deftypemethparsebody\Edeftypeivar\deftypeivarx\deftypeivarheader}
-%
-% #1 is the class name, #2 the data type, #3 the variable name.
-\def\deftypeivarheader#1#2#3{%
- \dosubind{vr}{\code{#3}}{\putwordof\ \code{#1}}% entry in variable index
- \begingroup
- \defname{\defheaderxcond#2\relax$.$#3}
- {\putwordInstanceVariableof\ \code{#1}}%
- \defvarargs{#3}%
- \endgroup
+\def\opnr{%
+ \global\advance\parencount by 1
+ {\parenfont(}%
+ \infirstlevel \bfafterword
}
-
-% @defmethod == @defop Method
-%
-\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader}
-%
-% #1 is the class name, #2 the method name, #3 the args.
-\def\defmethodheader#1#2#3{%
- \dosubind{fn}{\code{#2}}{\putwordon\ \code{#1}}% entry in function index
- \begingroup
- \defname{#2}{\putwordMethodon\ \code{#1}}%
- \defunargs{#3}%
- \endgroup
+\def\clnr{%
+ {\parenfont)}%
+ \infirstlevel \sl
+ \global\advance\parencount by -1
}
-% @defcv {Class Option} foo-class foo-flag
-
-\def\defcv #1 {\def\defcvtype{#1}%
-\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype}
-
-\def\defcvarheader #1#2#3{%
- \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% variable index entry
- \begingroup
- \defname{#2}{\defcvtype\ \putwordof\ #1}%
- \defvarargs{#3}%
- \endgroup
+\newcount\brackcount
+\def\lbrb{%
+ \global\advance\brackcount by 1
+ {\bf[}%
}
-
-% @defivar CLASS VARNAME == @defcv {Instance Variable} CLASS VARNAME
-%
-\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader}
-%
-\def\defivarheader#1#2#3{%
- \dosubind{vr}{\code{#2}}{\putwordof\ \code{#1}}% entry in var index
- \begingroup
- \defname{#2}{\putwordInstanceVariableof\ #1}%
- \defvarargs{#3}%
- \endgroup
+\def\rbrb{%
+ {\bf]}%
+ \global\advance\brackcount by -1
}
-% @defvar
-% First, define the processing that is wanted for arguments of @defvar.
-% This is actually simple: just print them in roman.
-% This must expand the args and terminate the paragraph they make up
-\def\defvarargs #1{\normalparens #1%
- \defargscommonending
+\def\checkparencounts{%
+ \ifnum\parencount=0 \else \badparencount \fi
+ \ifnum\brackcount=0 \else \badbrackcount \fi
}
-
-% @defvr Counter foo-count
-
-\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader}
-
-\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}%
-\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup}
-
-% @defvar == @defvr Variable
-
-\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader}
-
-\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
-\begingroup\defname {#1}{\putwordDefvar}%
-\defvarargs {#2}\endgroup %
+\def\badparencount{%
+ \errmessage{Unbalanced parentheses in @def}%
+ \global\parencount=0
}
-
-% @defopt == @defvr {User Option}
-
-\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader}
-
-\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
-\begingroup\defname {#1}{\putwordDefopt}%
-\defvarargs {#2}\endgroup %
+\def\badbrackcount{%
+ \errmessage{Unbalanced square braces in @def}%
+ \global\brackcount=0
}
-% @deftypevar int foobar
-
-\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader}
-
-% #1 is the data type. #2 is the name, perhaps followed by text that
-% is actually part of the data type, which should not be put into the index.
-\def\deftypevarheader #1#2{%
-\dovarind#2 \relax% Make entry in variables index
-\begingroup\defname {\defheaderxcond#1\relax$.$#2}{\putwordDeftypevar}%
- \defargscommonending
-\endgroup}
-\def\dovarind#1 #2\relax{\doind{vr}{\code{#1}}}
-
-% @deftypevr {Global Flag} int enable
-
-\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader}
-
-\def\deftypevrheader #1#2#3{\dovarind#3 \relax%
-\begingroup\defname {\defheaderxcond#2\relax$.$#3}{#1}
- \defargscommonending
-\endgroup}
-
-% Now define @deftp
-% Args are printed in bold, a slight difference from @defvar.
-
-\def\deftpargs #1{\bf \defvarargs{#1}}
-
-% @deftp Class window height width ...
-
-\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader}
-
-\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}%
-\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup}
-
-% These definitions are used if you use @defunx (etc.)
-% anywhere other than immediately after a @defun or @defunx.
-%
-\def\defcvx#1 {\errmessage{@defcvx in invalid context}}
-\def\deffnx#1 {\errmessage{@deffnx in invalid context}}
-\def\defivarx#1 {\errmessage{@defivarx in invalid context}}
-\def\defmacx#1 {\errmessage{@defmacx in invalid context}}
-\def\defmethodx#1 {\errmessage{@defmethodx in invalid context}}
-\def\defoptx #1 {\errmessage{@defoptx in invalid context}}
-\def\defopx#1 {\errmessage{@defopx in invalid context}}
-\def\defspecx#1 {\errmessage{@defspecx in invalid context}}
-\def\deftpx#1 {\errmessage{@deftpx in invalid context}}
-\def\deftypefnx#1 {\errmessage{@deftypefnx in invalid context}}
-\def\deftypefunx#1 {\errmessage{@deftypefunx in invalid context}}
-\def\deftypeivarx#1 {\errmessage{@deftypeivarx in invalid context}}
-\def\deftypemethodx#1 {\errmessage{@deftypemethodx in invalid context}}
-\def\deftypeopx#1 {\errmessage{@deftypeopx in invalid context}}
-\def\deftypevarx#1 {\errmessage{@deftypevarx in invalid context}}
-\def\deftypevrx#1 {\errmessage{@deftypevrx in invalid context}}
-\def\defunx#1 {\errmessage{@defunx in invalid context}}
-\def\defvarx#1 {\errmessage{@defvarx in invalid context}}
-\def\defvrx#1 {\errmessage{@defvrx in invalid context}}
-
\message{macros,}
% @macro.
@@ -5557,28 +5366,33 @@ width0pt\relax} \fi
% To do this right we need a feature of e-TeX, \scantokens,
% which we arrange to emulate with a temporary file in ordinary TeX.
\ifx\eTeXversion\undefined
- \newwrite\macscribble
- \def\scanmacro#1{%
- \begingroup \newlinechar`\^^M
- % Undo catcode changes of \startcontents and \doprintindex
- \catcode`\@=0 \catcode`\\=\other \escapechar=`\@
- % Append \endinput to make sure that TeX does not see the ending newline.
- \toks0={#1\endinput}%
- \immediate\openout\macscribble=\jobname.tmp
- \immediate\write\macscribble{\the\toks0}%
- \immediate\closeout\macscribble
- \let\xeatspaces\eatspaces
- \input \jobname.tmp
- \endgroup
-}
-\else
-\def\scanmacro#1{%
-\begingroup \newlinechar`\^^M
-% Undo catcode changes of \startcontents and \doprintindex
-\catcode`\@=0 \catcode`\\=\other \escapechar=`\@
-\let\xeatspaces\eatspaces\scantokens{#1\endinput}\endgroup}
+ \newwrite\macscribble
+ \def\scantokens#1{%
+ \toks0={#1\endinput}%
+ \immediate\openout\macscribble=\jobname.tmp
+ \immediate\write\macscribble{\the\toks0}%
+ \immediate\closeout\macscribble
+ \input \jobname.tmp
+ }
\fi
+\def\scanmacro#1{%
+ \begingroup
+ \newlinechar`\^^M
+ \let\xeatspaces\eatspaces
+ % Undo catcode changes of \startcontents and \doprintindex
+ \catcode`\@=0 \catcode`\\=\other \escapechar=`\@
+ % ... and \example
+ \spaceisspace
+ %
+ % Append \endinput to make sure that TeX does not see the ending newline.
+ %
+ % I've verified that it is necessary both for e-TeX and for ordinary TeX
+ % --kasal, 29nov03
+ \scantokens{#1\endinput}%
+ \endgroup
+}
+
\newcount\paramno % Count of parameters
\newtoks\macname % Macro name
\newif\ifrecursive % Is it recursive?
@@ -5586,7 +5400,7 @@ width0pt\relax} \fi
% \do\macro1\do\macro2...
% Utility routines.
-% Thisdoes \let #1 = #2, except with \csnames.
+% This does \let #1 = #2, except with \csnames.
\def\cslet#1#2{%
\expandafter\expandafter
\expandafter\let
@@ -5683,8 +5497,7 @@ width0pt\relax} \fi
\else \expandafter\parsemacbody
\fi}
-\def\unmacro{\parsearg\dounmacro}
-\def\dounmacro#1{%
+\parseargdef\unmacro{%
\if1\csname ismacro.#1\endcsname
\global\cslet{#1}{macsave.#1}%
\global\expandafter\let \csname ismacro.#1\endcsname=0%
@@ -5834,16 +5647,18 @@ width0pt\relax} \fi
% @alias.
% We need some trickery to remove the optional spaces around the equal
% sign. Just make them active and then expand them all to nothing.
-\def\alias{\begingroup\obeyspaces\parsearg\aliasxxx}
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
\def\aliasxxx #1{\aliasyyy#1\relax}
-\def\aliasyyy #1=#2\relax{\ignoreactivespaces
-\edef\next{\global\let\expandafter\noexpand\csname#1\endcsname=%
- \expandafter\noexpand\csname#2\endcsname}%
-\expandafter\endgroup\next}
+\def\aliasyyy #1=#2\relax{%
+ {%
+ \expandafter\let\obeyedspace=\empty
+ \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+ }%
+ \next
+}
\message{cross references,}
-% @xref etc.
\newwrite\auxfile
@@ -5855,64 +5670,62 @@ width0pt\relax} \fi
\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
node \samp{\ignorespaces#1{}}}
-% @node's job is to define \lastnode.
-\def\node{\ENVcheck\parsearg\nodezzz}
-\def\nodezzz#1{\nodexxx #1,\finishnodeparse}
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references.
+\parseargdef\node{\checkenv{}\nodexxx #1,\finishnodeparse}
\def\nodexxx#1,#2\finishnodeparse{\gdef\lastnode{#1}}
\let\nwnode=\node
-\let\lastnode=\relax
-
-% The sectioning commands (@chapter, etc.) call these.
-\def\donoderef{%
- \ifx\lastnode\relax\else
- \expandafter\expandafter\expandafter\setref{\lastnode}%
- {Ysectionnumberandtype}%
- \global\let\lastnode=\relax
- \fi
-}
-\def\unnumbnoderef{%
- \ifx\lastnode\relax\else
- \expandafter\expandafter\expandafter\setref{\lastnode}{Ynothing}%
- \global\let\lastnode=\relax
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node. #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+ \ifx\lastnode\empty\else
+ \setref{\lastnode}{#1}%
+ \global\let\lastnode=\empty
\fi
}
-\def\appendixnoderef{%
- \ifx\lastnode\relax\else
- \expandafter\expandafter\expandafter\setref{\lastnode}%
- {Yappendixletterandtype}%
- \global\let\lastnode=\relax
- \fi
-}
-
% @anchor{NAME} -- define xref target at arbitrary point.
%
\newcount\savesfregister
-\gdef\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
-\gdef\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
-\gdef\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
-% anchor), namely NAME-title (the corresponding @chapter/etc. name),
-% NAME-pg (the page number), and NAME-snt (section number and type).
-% Called from \foonoderef.
-%
-% We have to set \indexdummies so commands such as @code in a section
-% title aren't expanded. It would be nicer not to expand the titles in
-% the first place, but there's so many layers that that is hard to do.
-%
-% Likewise, use \turnoffactive so that punctuation chars such as underscore
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name, taken from \thissection;
+% 2) NAME-snt - section number and type, defined as the SNT arg;
+% 3) NAME-pg - the page number.
+% This is called from \donoderef, \anchor, and \dofloat.
+%
+% We take care not to fully expand the title, since it may contain
+% arbitrary macros.
+%
+% Use \turnoffactive so that punctuation chars such as underscore
% and backslash work in node names.
%
-\def\setref#1#2{{%
- \atdummies
+\def\setref#1#2{%
\pdfmkdest{#1}%
- %
- \turnoffactive
- \dosetq{#1-title}{Ytitle}%
- \dosetq{#1-pg}{Ypagenumber}%
- \dosetq{#1-snt}{#2}%
-}}
+ \iflinks
+ {%
+ \indexnofonts
+ \turnoffactive
+ \otherbackslash
+ \edef\writexrdef##1##2{%
+ \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+ ##1}{##2}}% these are parameters of \writexrdef
+ }%
+ \toks0 = \expandafter{\thissection}%
+ \immediate \writexrdef{title}{\the\toks0 }%
+ \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+ \writexrdef{pg}{\folio}% will be written later, during \shipout
+ }%
+ \fi
+}
% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is
% the node name, #2 the name of the Info cross-reference, #3 the printed
@@ -5925,38 +5738,33 @@ width0pt\relax} \fi
\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
\unsepspaces
\def\printedmanual{\ignorespaces #5}%
- \def\printednodename{\ignorespaces #3}%
- \setbox1=\hbox{\printedmanual}%
- \setbox0=\hbox{\printednodename}%
+ \def\printedrefname{\ignorespaces #3}%
+ \setbox1=\hbox{\printedmanual\unskip}%
+ \setbox0=\hbox{\printedrefname\unskip}%
\ifdim \wd0 = 0pt
% No printed node name was explicitly given.
\expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
% Use the node name inside the square brackets.
- \def\printednodename{\ignorespaces #1}%
+ \def\printedrefname{\ignorespaces #1}%
\else
% Use the actual chapter/section title appear inside
% the square brackets. Use the real section title if we have it.
\ifdim \wd1 > 0pt
% It is in another manual, so we don't have it.
- \def\printednodename{\ignorespaces #1}%
+ \def\printedrefname{\ignorespaces #1}%
\else
\ifhavexrefs
% We know the real title if we have the xref values.
- \def\printednodename{\refx{#1-title}{}}%
+ \def\printedrefname{\refx{#1-title}{}}%
\else
% Otherwise just copy the Info node name.
- \def\printednodename{\ignorespaces #1}%
+ \def\printedrefname{\ignorespaces #1}%
\fi%
\fi
\fi
\fi
%
- % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
- % insert empty discretionaries after hyphens, which means that it will
- % not find a line break at a hyphen in a node names. Since some manuals
- % are best written with fairly long node names, containing hyphens, this
- % is a loss. Therefore, we give the text of the node name again, so it
- % is as if TeX is seeing it for the first time.
+ % Make link in pdf output.
\ifpdf
\leavevmode
\getfilename{#4}%
@@ -5966,64 +5774,86 @@ width0pt\relax} \fi
goto file{\the\filename.pdf} name{#1}%
\else
\startlink attr{/Border [0 0 0]}%
- goto name{#1}%
+ goto name{\pdfmkpgn{#1}}%
\fi
}%
\linkcolor
\fi
%
- \ifdim \wd1 > 0pt
- \putwordsection{} ``\printednodename'' \putwordin{} \cite{\printedmanual}%
- \else
- % _ (for example) has to be the character _ for the purposes of the
- % control sequence corresponding to the node, but it has to expand
- % into the usual \leavevmode...\vrule stuff for purposes of
- % printing. So we \turnoffactive for the \refx-snt, back on for the
- % printing, back off for the \refx-pg.
- {\turnoffactive \otherbackslash
- % Only output a following space if the -snt ref is nonempty; for
- % @unnumbered and @anchor, it won't be.
- \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
- \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
- }%
- % output the `[mynode]' via a macro.
- \xrefprintnodename\printednodename
- %
- % But we always want a comma and a space:
- ,\space
+ % Float references are printed completely differently: "Figure 1.2"
+ % instead of "[somenode], p.3". We distinguish them by the
+ % LABEL-title being set to a magic string.
+ {%
+ % Have to otherify everything special to allow the \csname to
+ % include an _ in the xref name, etc.
+ \indexnofonts
+ \turnoffactive
+ \otherbackslash
+ \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+ \csname X#1-title\endcsname
+ }%
+ \ifx \Xthisreftitle \floatmagic
+ % If the user specified the print name (third arg) to the ref,
+ % print it instead of our usual "Figure 1.2".
+ \ifdim\wd0 = 0pt
+ \refx{#1-snt}%
+ \else
+ \printedrefname
+ \fi
%
- % output the `page 3'.
- \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}%
+ % if the user also gave the printed manual name (fifth arg), append
+ % "in MANUALNAME".
+ \ifdim \wd1 > 0pt
+ \space \putwordin{} \cite{\printedmanual}%
+ \fi
+ \else
+ % node/anchor (non-float) references.
+ %
+ % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+ % insert empty discretionaries after hyphens, which means that it will
+ % not find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens, this
+ % is a loss. Therefore, we give the text of the node name again, so it
+ % is as if TeX is seeing it for the first time.
+ \ifdim \wd1 > 0pt
+ \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
+ \else
+ % _ (for example) has to be the character _ for the purposes of the
+ % control sequence corresponding to the node, but it has to expand
+ % into the usual \leavevmode...\vrule stuff for purposes of
+ % printing. So we \turnoffactive for the \refx-snt, back on for the
+ % printing, back off for the \refx-pg.
+ {\turnoffactive \otherbackslash
+ % Only output a following space if the -snt ref is nonempty; for
+ % @unnumbered and @anchor, it won't be.
+ \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+ \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+ }%
+ % output the `[mynode]' via a macro so it can be overridden.
+ \xrefprintnodename\printedrefname
+ %
+ % But we always want a comma and a space:
+ ,\space
+ %
+ % output the `page 3'.
+ \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}%
+ \fi
\fi
\endlink
\endgroup}
% This macro is called from \xrefX for the `[nodename]' part of xref
% output. It's a separate macro only so it can be changed more easily,
-% since not square brackets don't work in some documents. Particularly
+% since square brackets don't work well in some documents. Particularly
% one that Bob is working on :).
%
\def\xrefprintnodename#1{[#1]}
-% \dosetq is called from \setref to do the actual \write (\iflinks).
+% Things referred to by \setref.
%
-\def\dosetq#1#2{%
- {\let\folio=0%
- \edef\next{\write\auxfile{\internalsetq{#1}{#2}}}%
- \iflinks \next \fi
- }%
-}
-
-% \internalsetq{foo}{page} expands into
-% CHARACTERS @xrdef{foo}{...expansion of \page...}
-\def\internalsetq#1#2{@xrdef{#1}{\csname #2\endcsname}}
-
-% Things to be expanded by \internalsetq.
-%
-\def\Ypagenumber{\folio}
-\def\Ytitle{\thissection}
\def\Ynothing{}
-\def\Ysectionnumberandtype{%
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
\ifnum\secno=0
\putwordChapter@tie \the\chapno
\else \ifnum\subsecno=0
@@ -6034,8 +5864,7 @@ width0pt\relax} \fi
\putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
\fi\fi\fi
}
-
-\def\Yappendixletterandtype{%
+\def\Yappendix{%
\ifnum\secno=0
\putwordAppendix@tie @char\the\appendixno{}%
\else \ifnum\subsecno=0
@@ -6048,15 +5877,6 @@ width0pt\relax} \fi
\fi\fi\fi
}
-% Use TeX 3.0's \inputlineno to get the line number, for better error
-% messages, but if we're using an old version of TeX, don't do anything.
-%
-\ifx\inputlineno\thisisundefined
- \let\linenumber = \empty % Pre-3.0.
-\else
- \def\linenumber{\the\inputlineno:\space}
-\fi
-
% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
% If its value is nonempty, SUFFIX is output afterward.
%
@@ -6092,6 +5912,16 @@ width0pt\relax} \fi
\def\xrdef#1{\expandafter\gdef\csname X#1\endcsname}
% Read the last existing aux file, if any. No error if none exists.
+%
+\def\tryauxfile{%
+ \openin 1 \jobname.aux
+ \ifeof 1 \else
+ \readauxfile
+ \global\havexrefstrue
+ \fi
+ \closein 1
+}
+
\def\readauxfile{\begingroup
\catcode`\^^@=\other
\catcode`\^^A=\other
@@ -6160,31 +5990,17 @@ width0pt\relax} \fi
}%
}%
%
- % Turn off \ as an escape so we do not lose on
- % entries which were dumped with control sequences in their names.
- % For example, @xrdef{$\leq $-fun}{page ...} made by @defun ^^
- % Reference to such entries still does not work the way one would wish,
- % but at least they do not bomb out when the aux file is read in.
- \catcode`\\=\other
- %
% @ is our escape character in .aux files.
\catcode`\{=1
\catcode`\}=2
\catcode`\@=0
%
- \openin 1 \jobname.aux
- \ifeof 1 \else
- \closein 1
- \input \jobname.aux
- \global\havexrefstrue
- \global\warnedobstrue
- \fi
- % Open the new aux file. TeX will close it automatically at exit.
- \openout\auxfile=\jobname.aux
+ \input \jobname.aux
\endgroup}
-% Footnotes.
+\message{insertions,}
+% including footnotes.
\newcount \footnoteno
@@ -6198,13 +6014,12 @@ width0pt\relax} \fi
% @footnotestyle is meaningful for info output only.
\let\footnotestyle=\comment
-\let\ptexfootnote=\footnote
-
{\catcode `\@=11
%
% Auto-number footnotes. Otherwise like plain.
\gdef\footnote{%
\let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
\global\advance\footnoteno by \@ne
\edef\thisfootno{$^{\the\footnoteno}$}%
%
@@ -6222,17 +6037,12 @@ width0pt\relax} \fi
% Don't bother with the trickery in plain.tex to not require the
% footnote text as a parameter. Our footnotes don't need to be so general.
%
-% Oh yes, they do; otherwise, @ifset and anything else that uses
-% \parseargline fail inside footnotes because the tokens are fixed when
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
% the footnote is read. --karl, 16nov96.
%
-% The start of the footnote looks usually like this:
-\gdef\startfootins{\insert\footins\bgroup}
-%
-% ... but this macro is redefined inside @multitable.
-%
\gdef\dofootnote{%
- \startfootins
+ \insert\footins\bgroup
% We want to typeset this text as a normal paragraph, even if the
% footnote reference occurs in (for example) a display environment.
% So reset some parameters.
@@ -6268,40 +6078,66 @@ width0pt\relax} \fi
}
}%end \catcode `\@=11
-% @| inserts a changebar to the left of the current line. It should
-% surround any changed text. This approach does *not* work if the
-% change spans more than two lines of output. To handle that, we would
-% have adopt a much more difficult approach (putting marks into the main
-% vertical list for the beginning and end of each change).
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished. Otherwise, the insertion
+% would be lost.
+% Similarily, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes. --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
%
-\def\|{%
- % \vadjust can only be used in horizontal mode.
- \leavevmode
- %
- % Append this vertical mode material after the current line in the output.
- \vadjust{%
- % We want to insert a rule with the height and depth of the current
- % leading; that is exactly what \strutbox is supposed to record.
- \vskip-\baselineskip
- %
- % \vadjust-items are inserted at the left edge of the type. So
- % the \llap here moves out into the left-hand margin.
- \llap{%
- %
- % For a thicker or thinner bar, change the `1pt'.
- \vrule height\baselineskip width1pt
- %
- % This is the space between the bar and the text.
- \hskip 12pt
- }%
- }%
+\def\startsavinginserts{%
+ \ifx \insert\ptexinsert
+ \let\insert\saveinsert
+ \else
+ \let\checkinserts\relax
+ \fi
}
-% For a final copy, take out the rectangles
-% that mark overfull boxes (in case you have decided
-% that the text looks ok even though it passes the margin).
+% This \insert replacements works for both \insert\footins{xx} and
+% \insert\footins\bgroup xx\egroup, but it doesn't work for \insert27{xx}.
%
-\def\finalout{\overfullrule=0pt}
+\def\saveinsert#1{%
+ \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+ \afterassignment\next
+ % swallow the left brace
+ \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+ \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+ {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+ \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-)
+ \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+ \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+ \next
+}
+\def\newsaveinsX #1{%
+ \csname newbox\endcsname #1%
+ \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+ \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
% @image. We use the macros from epsf.tex to support this.
% If epsf.tex is not installed and @image is used, we complain.
@@ -6311,12 +6147,12 @@ width0pt\relax} \fi
% undone and the next image would fail.
\openin 1 = epsf.tex
\ifeof 1 \else
- \closein 1
% Do not bother showing banner with epsf.tex v2.7k (available in
% doc/epsf.tex and on ctan).
\def\epsfannounce{\toks0 = }%
\input epsf.tex
\fi
+\closein 1
%
% We will only complain once about lack of epsf.tex.
\newif\ifwarnednoepsf
@@ -6372,6 +6208,129 @@ width0pt\relax} \fi
\endgroup}
+% @float FLOATTYPE,LOC ... @end float for displayed figures, tables, etc.
+% We don't actually implement floating yet, we just plop the float "here".
+% But it seemed the best name for the future.
+%
+\envparseargdef\float{\dofloat #1,,,\finish}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc. Can't contain commas. If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label. Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored. It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+ % don't lose footnotes inside @float.
+ \startsavinginserts
+ %
+ \vtop\bgroup
+ \def\floattype{#1}%
+ \def\floatlabel{#2}%
+ \def\floatloc{#3}% we do nothing with this yet.
+ % xx should we indent the whole thing? center it?
+ %
+ \ifx\floattype\empty \else
+ % For now, assume the FLOATTYPE is entirely letters, so we just use it
+ % in a control sequence name literally. We want each FLOATTYPE to be
+ % numbered separately (Figure 1, Table 1, Figure 2, ...).
+ \expandafter\getfloatno\csname\floattype floatno\endcsname
+ \global\advance\floatno by 1
+ %
+ \ifx\floatlabel\empty \else
+ {%
+ % This magic value for \thissection is output by \setref as the
+ % XREFLABEL-title value. \xrefX uses it to distinguish float
+ % labels (which have a completely different output format) from
+ % nodes and xref labels.
+ %
+ \let\thissection=\floatmagic
+ \setref{\floatlabel}{Yfloat}%
+ }%
+ \fi
+ \fi
+}
+
+% we have four possibilities:
+% @float Foo & @caption{Cap}: Foo 1.1: Cap
+% @float Foo & no caption: Foo 1.1
+% @float & @caption{Cap}: Cap
+% @float & no caption:
+%
+\def\Efloat{%
+ \let\printedsomething = \empty
+ %
+ \ifx\floattype\empty \else
+ \vskip.5\parskip % space above caption
+ %
+ % Print the float number preceded by the chapter-level number
+ % (empty in the case of unnumbered). Although there are other
+ % styles of float numbering, we hardwire this one.
+ \floattype\space\chaplevelprefix\the\floatno
+ \let\printedsomething = t%
+ \fi
+ %
+ \ifx\thiscaption\empty \else
+ \ifx\printedsomething\empty
+ \vskip.5\parskip % space above caption
+ \else
+ :\space % had a number, so print a colon.
+ \fi
+ %
+ % Print caption text.
+ \thiscaption
+ \let\printedsomething = t%
+ \fi
+ %
+ % Space below caption, if we printed anything.
+ \ifx\printedsomething\empty \else \vskip\parskip \fi
+ %
+ \egroup % end of \vtop
+ \checkinserts
+}
+
+\def\caption#1{\checkenv\float \def\thiscaption{#1}}
+\def\shortcaption#1{\checkenv\float \def\thisshortcaption{#1}}
+\let\thiscaption=\empty
+\let\thisshortcaption=\empty
+
+% The parameter is the control sequence identifying the counter we are
+% going to use. Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+ \ifx#1\relax
+ % Haven't seen this figure type before.
+ \csname newcount\endcsname #1%
+ %
+ % Remember to reset this floatno at the next chap.
+ \expandafter\gdef\expandafter\resetallfloatnos
+ \expandafter{\resetallfloatnos #1=0 }%
+ \fi
+ \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value. We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype @tie{}\chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+\parseargdef\listoffloats{%xx
+}
+
+
\message{localization,}
% and i18n.
@@ -6380,19 +6339,17 @@ width0pt\relax} \fi
% properly. Single argument is the language abbreviation.
% It would be nice if we could set up a hyphenation file here.
%
-\def\documentlanguage{\parsearg\dodocumentlanguage}
-\def\dodocumentlanguage#1{%
+\parseargdef\documentlanguage{%
\tex % read txi-??.tex file in plain TeX.
- % Read the file if it exists.
- \openin 1 txi-#1.tex
- \ifeof1
- \errhelp = \nolanghelp
- \errmessage{Cannot read language file txi-#1.tex}%
- \let\temp = \relax
- \else
- \def\temp{\input txi-#1.tex }%
- \fi
- \temp
+ % Read the file if it exists.
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \errhelp = \nolanghelp
+ \errmessage{Cannot read language file txi-#1.tex}%
+ \else
+ \input txi-#1.tex
+ \fi
+ \closein 1
\endgroup
}
\newhelp\nolanghelp{The given language definition file cannot be found or
@@ -6575,8 +6532,7 @@ should work if nowhere else does.}
% Perhaps we should allow setting the margins, \topskip, \parskip,
% and/or leading, also. Or perhaps we should compute them somehow.
%
-\def\pagesizes{\parsearg\pagesizesxxx}
-\def\pagesizesxxx#1{\pagesizesyyy #1,,\finish}
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
\def\pagesizesyyy#1,#2,#3\finish{{%
\setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
\globaldefs = 1
@@ -6623,8 +6579,8 @@ should work if nowhere else does.}
\def\normalplus{+}
\def\normaldollar{$}%$ font-lock fix
-% This macro is used to make a character print one way in ttfont
-% where it can probably just be output, and another way in other fonts,
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
% where something hairier probably needs to be done.
%
% #1 is what to print if we are indeed using \tt; #2 is what to print
@@ -6672,13 +6628,6 @@ should work if nowhere else does.}
\catcode`\$=\active
\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
-% Set up an active definition for =, but don't enable it most of the time.
-{\catcode`\==\active
-\global\def={{\tt \char 61}}}
-
-\catcode`+=\active
-\catcode`\_=\active
-
% If a .fmt file is being used, characters that might appear in a file
% name cannot be active until we have parsed the command line.
% So turn them off again, and have \everyjob (or @setfilename) turn them on.
@@ -6720,6 +6669,7 @@ should work if nowhere else does.}
@let>=@normalgreater
@let+=@normalplus
@let$=@normaldollar %$ font-lock fix
+ @unsepspaces
}
% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
@@ -6759,10 +6709,6 @@ should work if nowhere else does.}
@catcode`@# = @other
@catcode`@% = @other
-@c Set initial fonts.
-@textfonts
-@rm
-
@c Local variables:
@c eval: (add-hook 'write-file-hooks 'time-stamp)
@@ -6771,3 +6717,9 @@ should work if nowhere else does.}
@c time-stamp-format: "%:y-%02m-%02d.%02H"
@c time-stamp-end: "}"
@c End:
+
+@c vim:sw=2:
+
+@ignore
+ arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
diff --git a/contrib/gcc/doc/interface.texi b/contrib/gcc/doc/interface.texi
index c554434c4475..b55293d863c5 100644
--- a/contrib/gcc/doc/interface.texi
+++ b/contrib/gcc/doc/interface.texi
@@ -1,5 +1,5 @@
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-@c 1999, 2000, 2001 Free Software Foundation, Inc.
+@c 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -28,8 +28,8 @@ long in the same registers used for @code{int} or @code{double} return
values. (GCC typically allocates variables of such types in
registers also.) Structures and unions of other sizes are returned by
storing them into an address passed by the caller (usually in a
-register). The machine-description macros @code{STRUCT_VALUE} and
-@code{STRUCT_INCOMING_VALUE} tell GCC where to pass this address.
+register). The target hook @code{TARGET_STRUCT_VALUE_RTX}
+tells GCC where to pass this address.
By contrast, PCC on most target machines returns structures and unions
of any size by copying the data into an area of static storage, and then
@@ -76,27 +76,10 @@ just take the address of the variable. If a variable's address is ever
taken, even if just to compute it and ignore it, then the variable cannot
go in a register:
-@example
+@smallexample
@{
int careful;
&careful;
@dots{}
@}
-@end example
-
-@cindex arithmetic libraries
-@cindex math libraries
-@opindex msoft-float
-Code compiled with GCC may call certain library routines. Most of
-them handle arithmetic for which there are no instructions. This
-includes multiply and divide on some machines, and floating point
-operations on any machine for which floating point support is disabled
-with @option{-msoft-float}. Some standard parts of the C library, such as
-@code{bcopy} or @code{memcpy}, are also called automatically. The usual
-function call interface is used for calling the library routines.
-
-Some of these routines can be defined in mostly machine-independent C;
-they appear in @file{libgcc2.c}. Others must be hand-written in
-assembly language for each processor. Wherever they are defined, they
-are compiled into the support library, @file{libgcc.a}, which is
-automatically searched when you link programs with GCC@.
+@end smallexample
diff --git a/contrib/gcc/doc/invoke.texi b/contrib/gcc/doc/invoke.texi
index 6a128907536f..7e88bd55e73d 100644
--- a/contrib/gcc/doc/invoke.texi
+++ b/contrib/gcc/doc/invoke.texi
@@ -1,12 +1,12 @@
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-@c 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+@c 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@ignore
@c man begin COPYRIGHT
Copyright @copyright{} 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
-1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
@@ -140,6 +140,7 @@ only one of these two forms, whichever one is not the default.
* Code Gen Options:: Specifying conventions for function calls, data layout
and register usage.
* Environment Variables:: Env vars that affect GCC.
+* Precompiled Headers:: Compiling a header once, and using it many times.
* Running Protoize:: Automatically adding or removing function prototypes.
@end menu
@@ -171,10 +172,9 @@ in the following sections.
@item C++ Language Options
@xref{C++ Dialect Options,,Options Controlling C++ Dialect}.
@gccoptlist{-fabi-version=@var{n} -fno-access-control -fcheck-new @gol
--fconserve-space -fno-const-strings -fdollars-in-identifiers @gol
+-fconserve-space -fno-const-strings @gol
-fno-elide-constructors @gol
--fno-enforce-eh-specs -fexternal-templates @gol
--falt-external-templates @gol
+-fno-enforce-eh-specs @gol
-ffor-scope -fno-for-scope -fno-gnu-keywords @gol
-fno-implicit-templates @gol
-fno-implicit-inline-templates @gol
@@ -182,7 +182,7 @@ in the following sections.
-fno-nonansi-builtins -fno-operator-names @gol
-fno-optional-diags -fpermissive @gol
-frepo -fno-rtti -fstats -ftemplate-depth-@var{n} @gol
--fuse-cxa-atexit -fvtable-gc -fno-weak -nostdinc++ @gol
+-fuse-cxa-atexit -fno-weak -nostdinc++ @gol
-fno-default-inline -Wabi -Wctor-dtor-privacy @gol
-Wnon-virtual-dtor -Wreorder @gol
-Weffc++ -Wno-deprecated @gol
@@ -192,33 +192,39 @@ in the following sections.
@item Objective-C Language Options
@xref{Objective-C Dialect Options,,Options Controlling Objective-C Dialect}.
-@gccoptlist{-fconstant-string-class=@var{class-name} @gol
--fgnu-runtime -fnext-runtime -gen-decls @gol
--Wno-protocol -Wselector -Wundeclared-selector}
+@gccoptlist{
+-fconstant-string-class=@var{class-name} @gol
+-fgnu-runtime -fnext-runtime @gol
+-fno-nil-receivers @gol
+-fobjc-exceptions @gol
+-freplace-objc-classes @gol
+-fzero-link @gol
+-gen-decls @gol
+-Wno-protocol -Wselector -Wundeclared-selector}
@item Language Independent Options
@xref{Language Independent Options,,Options to Control Diagnostic Messages Formatting}.
-@gccoptlist{-fmessage-length=@var{n} @gol
+@gccoptlist{-fmessage-length=@var{n} @gol
-fdiagnostics-show-location=@r{[}once@r{|}every-line@r{]}}
@item Warning Options
@xref{Warning Options,,Options to Request or Suppress Warnings}.
@gccoptlist{-fsyntax-only -pedantic -pedantic-errors @gol
--w -W -Wall -Waggregate-return @gol
+-w -Wextra -Wall -Waggregate-return @gol
-Wcast-align -Wcast-qual -Wchar-subscripts -Wcomment @gol
-Wconversion -Wno-deprecated-declarations @gol
--Wdisabled-optimization -Wno-div-by-zero -Werror @gol
+-Wdisabled-optimization -Wno-div-by-zero -Wendif-labels @gol
+-Werror -Werror-implicit-function-declaration @gol
-Wfloat-equal -Wformat -Wformat=2 @gol
--Wformat-nonliteral -Wformat-security @gol
--Wimplicit -Wimplicit-int @gol
--Wimplicit-function-declaration @gol
--Werror-implicit-function-declaration @gol
--Wimport -Winline -Wno-endif-labels @gol
+-Wno-format-extra-args -Wformat-nonliteral @gol
+-Wformat-security -Wformat-y2k @gol
+-Wimplicit -Wimplicit-function-declaration -Wimplicit-int @gol
+-Wimport -Wno-import -Winit-self -Winline @gol
+-Wno-invalid-offsetof -Winvalid-pch @gol
-Wlarger-than-@var{len} -Wlong-long @gol
-Wmain -Wmissing-braces @gol
-Wmissing-format-attribute -Wmissing-noreturn @gol
--Wno-multichar -Wno-format-extra-args -Wno-format-y2k @gol
--Wno-import -Wnonnull -Wpacked -Wpadded @gol
+-Wno-multichar -Wnonnull -Wpacked -Wpadded @gol
-Wparentheses -Wpointer-arith -Wredundant-decls @gol
-Wreturn-type -Wsequence-point -Wshadow @gol
-Wsign-compare -Wstrict-aliasing @gol
@@ -230,8 +236,9 @@ in the following sections.
@item C-only Warning Options
@gccoptlist{-Wbad-function-cast -Wmissing-declarations @gol
--Wmissing-prototypes -Wnested-externs @gol
--Wstrict-prototypes -Wtraditional}
+-Wmissing-prototypes -Wnested-externs -Wold-style-definition @gol
+-Wstrict-prototypes -Wtraditional @gol
+-Wdeclaration-after-statement}
@item Debugging Options
@xref{Debugging Options,,Options for Debugging Your Program or GCC}.
@@ -241,10 +248,11 @@ in the following sections.
-fdump-tree-original@r{[}-@var{n}@r{]} @gol
-fdump-tree-optimized@r{[}-@var{n}@r{]} @gol
-fdump-tree-inlined@r{[}-@var{n}@r{]} @gol
--feliminate-dwarf2-dups -fmem-report @gol
--fprofile-arcs -frandom-seed=@var{n} @gol
--fsched-verbose=@var{n} -ftest-coverage -ftime-report @gol
--g -g@var{level} -gcoff -gdwarf -gdwarf-1 -gdwarf-1+ -gdwarf-2 @gol
+-feliminate-dwarf2-dups -feliminate-unused-debug-types @gol
+-feliminate-unused-debug-symbols -fmem-report -fprofile-arcs @gol
+-frandom-seed=@var{string} -fsched-verbose=@var{n} @gol
+-ftest-coverage -ftime-report @gol
+-g -g@var{level} -gcoff -gdwarf-2 @gol
-ggdb -gstabs -gstabs+ -gvms -gxcoff -gxcoff+ @gol
-p -pg -print-file-name=@var{library} -print-libgcc-file-name @gol
-print-multi-directory -print-multi-lib @gol
@@ -255,13 +263,14 @@ in the following sections.
@xref{Optimize Options,,Options that Control Optimization}.
@gccoptlist{-falign-functions=@var{n} -falign-jumps=@var{n} @gol
-falign-labels=@var{n} -falign-loops=@var{n} @gol
--fbranch-probabilities -fcaller-saves -fcprop-registers @gol
+-fbranch-probabilities -fprofile-values -fvpt -fbranch-target-load-optimize @gol
+-fbranch-target-load-optimize2 -fcaller-saves -fcprop-registers @gol
-fcse-follow-jumps -fcse-skip-blocks -fdata-sections @gol
-fdelayed-branch -fdelete-null-pointer-checks @gol
-fexpensive-optimizations -ffast-math -ffloat-store @gol
-fforce-addr -fforce-mem -ffunction-sections @gol
--fgcse -fgcse-lm -fgcse-sm -floop-optimize -fcrossjumping @gol
--fif-conversion -fif-conversion2 @gol
+-fgcse -fgcse-lm -fgcse-sm -fgcse-las -floop-optimize @gol
+-fcrossjumping -fif-conversion -fif-conversion2 @gol
-finline-functions -finline-limit=@var{n} -fkeep-inline-functions @gol
-fkeep-static-consts -fmerge-constants -fmerge-all-constants @gol
-fmove-all-movables -fnew-ra -fno-branch-count-reg @gol
@@ -272,21 +281,26 @@ in the following sections.
-fno-trapping-math -fno-zero-initialized-in-bss @gol
-fomit-frame-pointer -foptimize-register-move @gol
-foptimize-sibling-calls -fprefetch-loop-arrays @gol
+-fprofile-generate -fprofile-use @gol
-freduce-all-givs -fregmove -frename-registers @gol
-freorder-blocks -freorder-functions @gol
-frerun-cse-after-loop -frerun-loop-opt @gol
--fschedule-insns -fschedule-insns2 @gol
+-frounding-math -fschedule-insns -fschedule-insns2 @gol
-fno-sched-interblock -fno-sched-spec -fsched-spec-load @gol
--fsched-spec-load-dangerous -fsignaling-nans @gol
--fsingle-precision-constant -fssa -fssa-ccp -fssa-dce @gol
+-fsched-spec-load-dangerous @gol
+-fsched-stalled-insns=@var{n} -sched-stalled-insns-dep=@var{n} @gol
+-fsched2-use-superblocks @gol
+-fsched2-use-traces -fsignaling-nans @gol
+-fsingle-precision-constant @gol
-fstrength-reduce -fstrict-aliasing -ftracer -fthread-jumps @gol
--funroll-all-loops -funroll-loops @gol
---param @var{name}=@var{value} @gol
+-funroll-all-loops -funroll-loops -fpeel-loops @gol
+-funswitch-loops -fold-unroll-loops -fold-unroll-all-loops @gol
+--param @var{name}=@var{value}
-O -O0 -O1 -O2 -O3 -Os}
@item Preprocessor Options
@xref{Preprocessor Options,,Options Controlling the Preprocessor}.
-@gccoptlist{-$ -A@var{question}=@var{answer} @gol
+@gccoptlist{-A@var{question}=@var{answer} @gol
-A-@var{question}@r{[}=@var{answer}@r{]} @gol
-C -dD -dI -dM -dN @gol
-D@var{macro}@r{[}=@var{defn}@r{]} -E -H @gol
@@ -294,17 +308,19 @@ in the following sections.
-include @var{file} -imacros @var{file} @gol
-iprefix @var{file} -iwithprefix @var{dir} @gol
-iwithprefixbefore @var{dir} -isystem @var{dir} @gol
--M -MM -MF -MG -MP -MQ -MT -nostdinc -P -remap @gol
--trigraphs -undef -U@var{macro} -Wp,@var{option}}
+-M -MM -MF -MG -MP -MQ -MT -nostdinc @gol
+-P -fworking-directory -remap @gol
+-trigraphs -undef -U@var{macro} -Wp,@var{option} @gol
+-Xpreprocessor @var{option}}
@item Assembler Option
@xref{Assembler Options,,Passing Options to the Assembler}.
-@gccoptlist{-Wa,@var{option}}
+@gccoptlist{-Wa,@var{option} -Xassembler @var{option}}
@item Linker Options
@xref{Link Options,,Options for Linking}.
@gccoptlist{@var{object-file-name} -l@var{library} @gol
--nostartfiles -nodefaultlibs -nostdlib @gol
+-nostartfiles -nodefaultlibs -nostdlib -pie @gol
-s -static -static-libgcc -shared -shared-libgcc -symbolic @gol
-Wl,@var{option} -Xlinker @var{option} @gol
-u @var{symbol}}
@@ -324,11 +340,12 @@ in the following sections.
@emph{M680x0 Options}
@gccoptlist{-m68000 -m68020 -m68020-40 -m68020-60 -m68030 -m68040 @gol
-m68060 -mcpu32 -m5200 -m68881 -mbitfield -mc68000 -mc68020 @gol
--mfpa -mnobitfield -mrtd -mshort -msoft-float -mpcrel @gol
--malign-int -mstrict-align}
+-mnobitfield -mrtd -mshort -msoft-float -mpcrel @gol
+-malign-int -mstrict-align -msep-data -mno-sep-data @gol
+-mshared-library-id=n -mid-shared-library -mno-id-shared-library}
@emph{M68hc1x Options}
-@gccoptlist{-m6811 -m6812 -m68hc11 -m68hc12 -m68hcs12 @gol
+@gccoptlist{-m6811 -m6812 -m68hc11 -m68hc12 -m68hcs12 @gol
-mauto-incdec -minmax -mlong-calls -mshort @gol
-msoft-reg-count=@var{count}}
@@ -339,15 +356,18 @@ in the following sections.
@gccoptlist{-mcpu=@var{cpu-type} @gol
-mtune=@var{cpu-type} @gol
-mcmodel=@var{code-model} @gol
--m32 -m64 @gol
--mapp-regs -mbroken-saverestore -mcypress @gol
--mfaster-structs -mflat @gol
--mfpu -mhard-float -mhard-quad-float @gol
--mimpure-text -mlittle-endian -mlive-g0 -mno-app-regs @gol
--mno-faster-structs -mno-flat -mno-fpu @gol
--mno-impure-text -mno-stack-bias -mno-unaligned-doubles @gol
--msoft-float -msoft-quad-float -msparclite -mstack-bias @gol
--msupersparc -munaligned-doubles -mv8}
+-m32 -m64 -mapp-regs -mno-app-regs @gol
+-mfaster-structs -mno-faster-structs @gol
+-mflat -mno-flat -mfpu -mno-fpu @gol
+-mhard-float -msoft-float @gol
+-mhard-quad-float -msoft-quad-float @gol
+-mimpure-text -mno-impure-text -mlittle-endian @gol
+-mstack-bias -mno-stack-bias @gol
+-munaligned-doubles -mno-unaligned-doubles @gol
+-mv8plus -mno-v8plus -mvis -mno-vis @gol
+-mcypress -mf930 -mf934 @gol
+-msparclite -msupersparc -mv8
+-threads -pthreads}
@emph{ARM Options}
@gccoptlist{-mapcs-frame -mno-apcs-frame @gol
@@ -367,34 +387,29 @@ in the following sections.
-msingle-pic-base -mno-single-pic-base @gol
-mpic-register=@var{reg} @gol
-mnop-fun-dllimport @gol
+-mcirrus-fix-invalid-insns -mno-cirrus-fix-invalid-insns @gol
-mpoke-function-name @gol
-mthumb -marm @gol
-mtpcs-frame -mtpcs-leaf-frame @gol
-mcaller-super-interworking -mcallee-super-interworking}
-@emph{MN10200 Options}
-@gccoptlist{-mrelax}
-
@emph{MN10300 Options}
@gccoptlist{-mmult-bug -mno-mult-bug @gol
-mam33 -mno-am33 @gol
+-mam33-2 -mno-am33-2 @gol
-mno-crt0 -mrelax}
@emph{M32R/D Options}
-@gccoptlist{-m32rx -m32r -mcode-model=@var{model-type} @gol
--msdata=@var{sdata-type} -G @var{num}}
-
-@emph{M88K Options}
-@gccoptlist{-m88000 -m88100 -m88110 -mbig-pic @gol
--mcheck-zero-division -mhandle-large-shift @gol
--midentify-revision -mno-check-zero-division @gol
--mno-ocs-debug-info -mno-ocs-frame-position @gol
--mno-optimize-arg-area -mno-serialize-volatile @gol
--mno-underscores -mocs-debug-info @gol
--mocs-frame-position -moptimize-arg-area @gol
--mserialize-volatile -mshort-data-@var{num} -msvr3 @gol
--msvr4 -mtrap-large-shift -muse-div-instruction @gol
--mversion-03.00 -mwarn-passed-structs}
+@gccoptlist{-m32r2 -m32rx -m32r @gol
+-mdebug @gol
+-malign-loops -mno-align-loops @gol
+-missue-rate=@var{number} @gol
+-mbranch-cost=@var{number} @gol
+-mmodel=@var{code-size-model-type} @gol
+-msdata=@var{sdata-type} @gol
+-mno-flush-func -mflush-func=@var{name} @gol
+-mno-flush-trap -mflush-trap=@var{number} @gol
+-G @var{num}}
@emph{RS/6000 and PowerPC Options}
@gccoptlist{-mcpu=@var{cpu-type} @gol
@@ -407,85 +422,88 @@ in the following sections.
-mnew-mnemonics -mold-mnemonics @gol
-mfull-toc -mminimal-toc -mno-fp-in-toc -mno-sum-in-toc @gol
-m64 -m32 -mxl-call -mno-xl-call -mpe @gol
+-malign-power -malign-natural @gol
-msoft-float -mhard-float -mmultiple -mno-multiple @gol
-mstring -mno-string -mupdate -mno-update @gol
-mfused-madd -mno-fused-madd -mbit-align -mno-bit-align @gol
-mstrict-align -mno-strict-align -mrelocatable @gol
-mno-relocatable -mrelocatable-lib -mno-relocatable-lib @gol
-mtoc -mno-toc -mlittle -mlittle-endian -mbig -mbig-endian @gol
--mcall-aix -mcall-sysv -mcall-netbsd @gol
+-mdynamic-no-pic @gol
+-mprioritize-restricted-insns=@var{priority} @gol
+-msched-costly-dep=@var{dependence_type} @gol
+-minsert-sched-nops=@var{scheme} @gol
+-mcall-sysv -mcall-netbsd @gol
-maix-struct-return -msvr4-struct-return @gol
-mabi=altivec -mabi=no-altivec @gol
-mabi=spe -mabi=no-spe @gol
-misel=yes -misel=no @gol
+-mspe=yes -mspe=no @gol
+-mfloat-gprs=yes -mfloat-gprs=no @gol
-mprototype -mno-prototype @gol
-msim -mmvme -mads -myellowknife -memb -msdata @gol
-msdata=@var{opt} -mvxworks -mwindiss -G @var{num} -pthread}
@emph{Darwin Options}
-@gccoptlist{
--all_load -allowable_client -arch -arch_errors_fatal @gol
--arch_only -bind_at_load -bundle -bundle_loader @gol
--client_name -compatibility_version -current_version @gol
--dependency-file -dylib_file -dylinker_install_name @gol
--dynamic -dynamiclib -exported_symbols_list @gol
--filelist -flat_namespace -force_cpusubtype_ALL @gol
--force_flat_namespace -headerpad_max_install_names @gol
--image_base -init -install_name -keep_private_externs @gol
--multi_module -multiply_defined -multiply_defined_unused @gol
--noall_load -nomultidefs -noprebind -noseglinkedit @gol
--pagezero_size -prebind -prebind_all_twolevel_modules @gol
--private_bundle -read_only_relocs -sectalign @gol
--sectobjectsymbols -whyload -seg1addr @gol
--sectcreate -sectobjectsymbols -sectorder @gol
--seg_addr_table -seg_addr_table_filename -seglinkedit @gol
--segprot -segs_read_only_addr -segs_read_write_addr @gol
--single_module -static -sub_library -sub_umbrella @gol
--twolevel_namespace -umbrella -undefined @gol
--unexported_symbols_list -weak_reference_mismatches -whatsloaded}
-
-@emph{RT Options}
-@gccoptlist{-mcall-lib-mul -mfp-arg-in-fpregs -mfp-arg-in-gregs @gol
--mfull-fp-blocks -mhc-struct-return -min-line-mul @gol
--mminimum-fp-blocks -mnohc-struct-return}
+@gccoptlist{-all_load -allowable_client -arch -arch_errors_fatal @gol
+-arch_only -bind_at_load -bundle -bundle_loader @gol
+-client_name -compatibility_version -current_version @gol
+-dependency-file -dylib_file -dylinker_install_name @gol
+-dynamic -dynamiclib -exported_symbols_list @gol
+-filelist -flat_namespace -force_cpusubtype_ALL @gol
+-force_flat_namespace -headerpad_max_install_names @gol
+-image_base -init -install_name -keep_private_externs @gol
+-multi_module -multiply_defined -multiply_defined_unused @gol
+-noall_load -nofixprebinding -nomultidefs -noprebind -noseglinkedit @gol
+-pagezero_size -prebind -prebind_all_twolevel_modules @gol
+-private_bundle -read_only_relocs -sectalign @gol
+-sectobjectsymbols -whyload -seg1addr @gol
+-sectcreate -sectobjectsymbols -sectorder @gol
+-seg_addr_table -seg_addr_table_filename -seglinkedit @gol
+-segprot -segs_read_only_addr -segs_read_write_addr @gol
+-single_module -static -sub_library -sub_umbrella @gol
+-twolevel_namespace -umbrella -undefined @gol
+-unexported_symbols_list -weak_reference_mismatches @gol
+-whatsloaded}
@emph{MIPS Options}
-@gccoptlist{-mabicalls -march=@var{cpu-type} -mtune=@var{cpu=type} @gol
--mcpu=@var{cpu-type} -membedded-data -muninit-const-in-rodata @gol
--membedded-pic -mfp32 -mfp64 -mfused-madd -mno-fused-madd @gol
--mgas -mgp32 -mgp64 @gol
--mgpopt -mhalf-pic -mhard-float -mint64 -mips1 @gol
--mips2 -mips3 -mips4 -mlong64 -mlong32 -mlong-calls -mmemcpy @gol
--mmips-as -mmips-tfile -mno-abicalls @gol
--mno-embedded-data -mno-uninit-const-in-rodata @gol
--mno-embedded-pic -mno-gpopt -mno-long-calls @gol
--mno-memcpy -mno-mips-tfile -mno-rnames -mno-stats @gol
--mrnames -msoft-float @gol
--m4650 -msingle-float -mmad @gol
--mstats -EL -EB -G @var{num} -nocpp @gol
--mabi=32 -mabi=n32 -mabi=64 -mabi=eabi @gol
--mfix7000 -mno-crt0 -mflush-func=@var{func} -mno-flush-func @gol
--mbranch-likely -mno-branch-likely}
+@gccoptlist{-EL -EB -march=@var{arch} -mtune=@var{arch} @gol
+-mips1 -mips2 -mips3 -mips4 -mips32 -mips32r2 -mips64 @gol
+-mips16 -mno-mips16 -mabi=@var{abi} -mabicalls -mno-abicalls @gol
+-mxgot -mno-xgot -membedded-pic -mno-embedded-pic @gol
+-mgp32 -mgp64 -mfp32 -mfp64 -mhard-float -msoft-float @gol
+-msingle-float -mdouble-float -mint64 -mlong64 -mlong32 @gol
+-G@var{num} -membedded-data -mno-embedded-data @gol
+-muninit-const-in-rodata -mno-uninit-const-in-rodata @gol
+-msplit-addresses -mno-split-addresses @gol
+-mexplicit-relocs -mno-explicit-relocs @gol
+-mrnames -mno-rnames @gol
+-mcheck-zero-division -mno-check-zero-division @gol
+-mmemcpy -mno-memcpy -mlong-calls -mno-long-calls @gol
+-mmad -mno-mad -mfused-madd -mno-fused-madd -nocpp @gol
+-mfix-sb1 -mno-fix-sb1 -mflush-func=@var{func} @gol
+-mno-flush-func -mbranch-likely -mno-branch-likely}
@emph{i386 and x86-64 Options}
-@gccoptlist{-mcpu=@var{cpu-type} -march=@var{cpu-type} @gol
--mfpmath=@var{unit} -masm=@var{dialect} -mno-fancy-math-387 @gol
+@gccoptlist{-mtune=@var{cpu-type} -march=@var{cpu-type} @gol
+-mfpmath=@var{unit} @gol
+-masm=@var{dialect} -mno-fancy-math-387 @gol
-mno-fp-ret-in-387 -msoft-float -msvr3-shlib @gol
-mno-wide-multiply -mrtd -malign-double @gol
-mpreferred-stack-boundary=@var{num} @gol
--mmmx -msse -msse2 -mpni -m3dnow @gol
+-mmmx -msse -msse2 -msse3 -m3dnow @gol
-mthreads -mno-align-stringops -minline-all-stringops @gol
-mpush-args -maccumulate-outgoing-args -m128bit-long-double @gol
-m96bit-long-double -mregparm=@var{num} -momit-leaf-frame-pointer @gol
--mno-red-zone@gol
+-mno-red-zone -mno-tls-direct-seg-refs @gol
-mcmodel=@var{code-model} @gol
-m32 -m64}
@emph{HPPA Options}
@gccoptlist{-march=@var{architecture-type} @gol
-mbig-switch -mdisable-fpregs -mdisable-indexing @gol
--mfast-indirect-calls -mgas -mgnu-ld -mhp-ld @gol
--mjump-in-delay -mlinker-opt -mlong-calls @gol
+-mfast-indirect-calls -mgas -mgnu-ld -mhp-ld @gol
+-mjump-in-delay -mlinker-opt -mlong-calls @gol
-mlong-load-store -mno-big-switch -mno-disable-fpregs @gol
-mno-disable-indexing -mno-fast-indirect-calls -mno-gas @gol
-mno-jump-in-delay -mno-long-load-store @gol
@@ -514,6 +532,7 @@ in the following sections.
-mbwx -mmax -mfix -mcix @gol
-mfloat-vax -mfloat-ieee @gol
-mexplicit-relocs -msmall-data -mlarge-data @gol
+-msmall-text -mlarge-text @gol
-mmemory-latency=@var{time}}
@emph{DEC Alpha/VMS Options}
@@ -523,7 +542,7 @@ in the following sections.
@gccoptlist{-mrelax -mh -ms -mn -mint32 -malign-300}
@emph{SH Options}
-@gccoptlist{-m1 -m2 -m3 -m3e @gol
+@gccoptlist{-m1 -m2 -m2e -m3 -m3e @gol
-m4-nofpu -m4-single-only -m4-single -m4 @gol
-m5-64media -m5-64media-nofpu @gol
-m5-32media -m5-32media-nofpu @gol
@@ -553,6 +572,7 @@ in the following sections.
-mtda=@var{n} -msda=@var{n} -mzda=@var{n} @gol
-mapp-regs -mno-app-regs @gol
-mdisable-callt -mno-disable-callt @gol
+-mv850e1 @gol
-mv850e @gol
-mv850 -mbig-switch}
@@ -593,9 +613,10 @@ in the following sections.
-masm-optimize -mbranch-cost=@var{n} -mcond-exec=@var{n}}
@emph{S/390 and zSeries Options}
-@gccoptlist{-mhard-float -msoft-float -mbackchain -mno-backchain @gol
--msmall-exec -mno-small-exec -mmvcle -mno-mvcle @gol
--m64 -m31 -mdebug -mno-debug}
+@gccoptlist{-mtune=@var{cpu-type} -march=@var{cpu-type} @gol
+-mhard-float -msoft-float -mbackchain -mno-backchain @gol
+-msmall-exec -mno-small-exec -mmvcle -mno-mvcle @gol
+-m64 -m31 -mdebug -mno-debug -mesa -mzarch -mfused-madd -mno-fused-madd}
@emph{CRIS Options}
@gccoptlist{-mcpu=@var{cpu} -march=@var{cpu} -mtune=@var{cpu} @gol
@@ -603,7 +624,8 @@ in the following sections.
-metrax4 -metrax100 -mpdebug -mcc-init -mno-side-effects @gol
-mstack-align -mdata-align -mconst-align @gol
-m32-bit -m16-bit -m8-bit -mno-prologue-epilogue -mno-gotplt @gol
--melf -maout -melinux -mlinux -sim -sim2}
+-melf -maout -melinux -mlinux -sim -sim2 @gol
+-mmul-bug-workaround -mno-mul-bug-workaround}
@emph{PDP-11 Options}
@gccoptlist{-mfpu -msoft-float -mac0 -mno-ac0 -m40 -m45 -m10 @gol
@@ -617,36 +639,26 @@ in the following sections.
@gccoptlist{-msim}
@emph{Xtensa Options}
-@gccoptlist{-mbig-endian -mlittle-endian @gol
--mdensity -mno-density @gol
--mmac16 -mno-mac16 @gol
--mmul16 -mno-mul16 @gol
--mmul32 -mno-mul32 @gol
--mnsa -mno-nsa @gol
--mminmax -mno-minmax @gol
--msext -mno-sext @gol
--mbooleans -mno-booleans @gol
--mhard-float -msoft-float @gol
+@gccoptlist{-mconst16 -mno-const16 @gol
-mfused-madd -mno-fused-madd @gol
--mserialize-volatile -mno-serialize-volatile @gol
-mtext-section-literals -mno-text-section-literals @gol
-mtarget-align -mno-target-align @gol
-mlongcalls -mno-longcalls}
@emph{FRV Options}
@gccoptlist{-mgpr-32 -mgpr-64 -mfpr-32 -mfpr-64 @gol
--mhard-float -msoft-float -malloc-cc -mfixed-cc @gol
--mdword -mno-dword -mdouble -mno-double @gol
--mmedia -mno-media -mmuladd -mno-muladd -mlibrary-pic @gol
--macc-4 -macc-8 -mpack -mno-pack -mno-eflags @gol
--mcond-move -mno-cond-move -mscc -mno-scc @gol
--mcond-exec -mno-cond-exec -mvliw-branch -mno-vliw-branch @gol
+-mhard-float -msoft-float @gol
+-malloc-cc -mfixed-cc -mdword -mno-dword @gol
+-mdouble -mno-double @gol
+-mmedia -mno-media -mmuladd -mno-muladd @gol
+-mlibrary-pic -macc-4 -macc-8 @gol
+-mpack -mno-pack -mno-eflags -mcond-move -mno-cond-move @gol
+-mscc -mno-scc -mcond-exec -mno-cond-exec @gol
+-mvliw-branch -mno-vliw-branch @gol
-mmulti-cond-exec -mno-multi-cond-exec -mnested-cond-exec @gol
-mno-nested-cond-exec -mtomcat-stats @gol
-mcpu=@var{cpu}}
-
-
@item Code Generation Options
@xref{Code Gen Options,,Options for Code Generation Conventions}.
@gccoptlist{-fcall-saved-@var{reg} -fcall-used-@var{reg} @gol
@@ -654,17 +666,16 @@ in the following sections.
-fnon-call-exceptions -funwind-tables @gol
-fasynchronous-unwind-tables @gol
-finhibit-size-directive -finstrument-functions @gol
--fno-common -fno-ident -fno-gnu-linker @gol
--fpcc-struct-return -fpic -fPIC @gol
+-fno-common -fno-ident @gol
+-fpcc-struct-return -fpic -fPIC -fpie -fPIE @gol
-freg-struct-return -fshared-data -fshort-enums @gol
--fshort-double -fshort-wchar -fvolatile @gol
--fvolatile-global -fvolatile-static @gol
+-fshort-double -fshort-wchar @gol
-fverbose-asm -fpack-struct -fstack-check @gol
-fstack-limit-register=@var{reg} -fstack-limit-symbol=@var{sym} @gol
-fargument-alias -fargument-noalias @gol
-fargument-noalias-global -fleading-underscore @gol
-ftls-model=@var{model} @gol
--ftrapv -fbounds-check}
+-ftrapv -fwrapv -fbounds-check}
@end table
@menu
@@ -693,10 +704,12 @@ in the following sections.
@section Options Controlling the Kind of Output
Compilation can involve up to four stages: preprocessing, compilation
-proper, assembly and linking, always in that order. The first three
-stages apply to an individual source file, and end by producing an
-object file; linking combines all the object files (those newly
-compiled, and those specified as input) into an executable file.
+proper, assembly and linking, always in that order. GCC is capable of
+preprocessing and compiling several files either into several
+assembler input files, or into one assembler input file; then each
+assembler input file produces an object file, and linking combines all
+the object files (those newly compiled, and those specified as input)
+into an executable file.
@cindex file name suffix
For any given input file, the file name suffix determines what kind of
@@ -720,18 +733,23 @@ Objective-C source code. Note that you must link with the library
Objective-C source code which should not be preprocessed.
@item @var{file}.h
-C header file (not to be compiled or linked).
+C or C++ header file to be turned into a precompiled header.
@item @var{file}.cc
@itemx @var{file}.cp
@itemx @var{file}.cxx
@itemx @var{file}.cpp
+@itemx @var{file}.CPP
@itemx @var{file}.c++
@itemx @var{file}.C
C++ source code which must be preprocessed. Note that in @samp{.cxx},
the last two letters must both be literally @samp{x}. Likewise,
@samp{.C} refers to a literal capital C@.
+@item @var{file}.hh
+@itemx @var{file}.H
+C++ header file to be turned into a precompiled header.
+
@item @var{file}.f
@itemx @var{file}.for
@itemx @var{file}.FOR
@@ -793,16 +811,16 @@ Specify explicitly the @var{language} for the following input files
(rather than letting the compiler choose a default based on the file
name suffix). This option applies to all following input files until
the next @option{-x} option. Possible values for @var{language} are:
-@example
+@smallexample
c c-header cpp-output
-c++ c++-cpp-output
-objective-c objc-cpp-output
+c++ c++-header c++-cpp-output
+objective-c objective-c-header objc-cpp-output
assembler assembler-with-cpp
ada
f77 f77-cpp-input ratfor
java
treelang
-@end example
+@end smallexample
@item -x none
Turn off any specification of a language, so that subsequent files are
@@ -863,9 +881,9 @@ Place output in file @var{file}. This applies regardless to whatever
sort of output is being produced, whether it be an executable file,
an object file, an assembler file or preprocessed C code.
-Since only one output file can be specified, it does not make sense to
-use @option{-o} when compiling more than one input file, unless you are
-producing an executable file as output.
+If you specify @option{-o} when compiling more than one input file, or
+you are producing an executable file as output, all the source files
+on the command line will be compiled at once.
If @option{-o} is not specified, the default is to put an executable file
in @file{a.out}, the object file for @file{@var{source}.@var{suffix}} in
@@ -897,7 +915,7 @@ Print (on the standard output) a description of the command line options
understood by @command{gcc}. If the @option{-v} option is also specified
then @option{--help} will also be passed on to the various processes
invoked by @command{gcc}, so that they can display the command line options
-they accept. If the @option{-W} option is also specified then command
+they accept. If the @option{-Wextra} option is also specified then command
line options which have no documentation associated with them will also
be displayed.
@@ -917,22 +935,24 @@ Display the version number and copyrights of the invoked GCC.
@cindex suffixes for C++ source
@cindex C++ source file suffixes
C++ source files conventionally use one of the suffixes @samp{.C},
-@samp{.cc}, @samp{.cpp}, @samp{.c++}, @samp{.cp}, or @samp{.cxx};
+@samp{.cc}, @samp{.cpp}, @samp{.CPP}, @samp{.c++}, @samp{.cp}, or
+@samp{.cxx}; C++ header files often use @samp{.hh} or @samp{.H}; and
preprocessed C++ files use the suffix @samp{.ii}. GCC recognizes
files with these names and compiles them as C++ programs even if you
-call the compiler the same way as for compiling C programs (usually with
-the name @command{gcc}).
+call the compiler the same way as for compiling C programs (usually
+with the name @command{gcc}).
@findex g++
@findex c++
However, C++ programs often require class libraries as well as a
compiler that understands the C++ language---and under some
-circumstances, you might want to compile programs from standard input,
-or otherwise without a suffix that flags them as C++ programs.
-@command{g++} is a program that calls GCC with the default language
-set to C++, and automatically specifies linking against the C++
-library. On many systems, @command{g++} is also
-installed with the name @command{c++}.
+circumstances, you might want to compile programs or header files from
+standard input, or otherwise without a suffix that flags them as C++
+programs. You might also like to precompile a C header file with a
+@samp{.h} extension to be used in C++ compilations. @command{g++} is a
+program that calls GCC with the default language set to C++, and
+automatically specifies linking against the C++ library. On many
+systems, @command{g++} is also installed with the name @command{c++}.
@cindex invoking @command{g++}
When you compile C++ programs, you may specify many of the same
@@ -1013,14 +1033,14 @@ ISO C90 as modified in amendment 1.
@itemx iso9899:1999
@itemx iso9899:199x
ISO C99. Note that this standard is not yet fully supported; see
-@w{@uref{http://gcc.gnu.org/gcc-3.3/c99status.html}} for more information. The
+@w{@uref{http://gcc.gnu.org/gcc-3.4/c99status.html}} for more information. The
names @samp{c9x} and @samp{iso9899:199x} are deprecated.
@item gnu89
Default, ISO C90 plus GNU extensions (including some C99 features).
@item gnu99
-@item gnu9x
+@itemx gnu9x
ISO C99 plus GNU extensions. When ISO C99 is fully implemented in GCC,
this will become the default. The name @samp{gnu9x} is deprecated.
@@ -1216,6 +1236,8 @@ write into string constants.
Writing into string constants is a very bad idea; ``constants'' should
be constant.
+
+This option is deprecated.
@end table
@node C++ Dialect Options
@@ -1229,9 +1251,9 @@ for C++ programs; but you can also use most of the GNU compiler options
regardless of what language your program is in. For example, you
might compile a file @code{firstClass.C} like this:
-@example
+@smallexample
g++ -g -frepo -O -c firstClass.C
-@end example
+@end smallexample
@noindent
In this example, only @option{-frepo} is an option meant
@@ -1244,13 +1266,14 @@ Here is a list of options that are @emph{only} for compiling C++ programs:
@item -fabi-version=@var{n}
@opindex fabi-version
-Use version @var{n} of the C++ ABI. Version 1 is the version of the C++
-ABI that first appeared in G++ 3.2. Version 0 will always be the
-version that conforms most closely to the C++ ABI specification.
-Therefore, the ABI obtained using version 0 will change as ABI bugs are
-fixed.
+Use version @var{n} of the C++ ABI. Version 2 is the version of the
+C++ ABI that first appeared in G++ 3.4. Version 1 is the version of
+the C++ ABI that first appeared in G++ 3.2. Version 0 will always be
+the version that conforms most closely to the C++ ABI specification.
+Therefore, the ABI obtained using version 0 will change as ABI bugs
+are fixed.
-The default is version 1.
+The default is version 2.
@item -fno-access-control
@opindex fno-access-control
@@ -1293,14 +1316,6 @@ This option might be removed in a future release of G++. For maximum
portability, you should structure your code so that it works with
string constants that have type @code{const char *}.
-@item -fdollars-in-identifiers
-@opindex fdollars-in-identifiers
-Accept @samp{$} in identifiers. You can also explicitly prohibit use of
-@samp{$} with the option @option{-fno-dollars-in-identifiers}. (GNU C allows
-@samp{$} by default on most target systems, but there are a few exceptions.)
-Traditional C allowed the character @samp{$} to form part of
-identifiers. However, ISO C and C++ forbid @samp{$} in identifiers.
-
@item -fno-elide-constructors
@opindex fno-elide-constructors
The C++ standard allows an implementation to omit creating a temporary
@@ -1315,24 +1330,6 @@ option violates the C++ standard, but may be useful for reducing code
size in production builds, much like defining @samp{NDEBUG}. The compiler
will still optimize based on the exception specifications.
-@item -fexternal-templates
-@opindex fexternal-templates
-
-Cause @samp{#pragma interface} and @samp{implementation} to apply to
-template instantiation; template instances are emitted or not according
-to the location of the template definition. @xref{Template
-Instantiation}, for more information.
-
-This option is deprecated.
-
-@item -falt-external-templates
-@opindex falt-external-templates
-Similar to @option{-fexternal-templates}, but template instances are
-emitted or not according to the place where they are first instantiated.
-@xref{Template Instantiation}, for more information.
-
-This option is deprecated.
-
@item -ffor-scope
@itemx -fno-for-scope
@opindex ffor-scope
@@ -1437,17 +1434,6 @@ This option is required for fully standards-compliant handling of static
destructors, but will only work if your C library supports
@code{__cxa_atexit}.
-@item -fvtable-gc
-@opindex fvtable-gc
-Emit special relocations for vtables and virtual function references
-so that the linker can identify unused virtual functions and zero out
-vtable slots that refer to them. This is most useful with
-@option{-ffunction-sections} and @option{-Wl,--gc-sections}, in order to
-also discard the functions themselves.
-
-This optimization requires GNU as and GNU ld. Not all systems support
-this option. @option{-Wl,--gc-sections} is ignored without @option{-static}.
-
@item -fno-weak
@opindex fno-weak
Do not use weak symbol support, even if it is provided by the linker.
@@ -1478,7 +1464,7 @@ inlined by default.
@opindex Wabi
Warn when G++ generates code that is probably not compatible with the
vendor-neutral C++ ABI. Although an effort has been made to warn about
-all such cases, there are probably some cases that are not warned about,
+all such cases, there are probably some cases that are not warned about,
even though G++ is generating incompatible code. There may also be
cases where warnings are emitted even though the code that is generated
will be compatible.
@@ -1502,7 +1488,7 @@ struct B : public A @{ int f2 : 1; @};
@noindent
In this case, G++ will place @code{B::f2} into the same byte
-as@code{A::f1}; other compilers will not. You can avoid this problem
+as@code{A::f1}; other compilers will not. You can avoid this problem
by explicitly padding @code{A} so that its size is a multiple of the
byte size on your platform; that will cause G++ and other compilers to
layout @code{B} identically.
@@ -1539,7 +1525,7 @@ union too small by the number of bits in an @code{int}.
@item
Empty classes can be placed at incorrect offsets. For example:
-
+
@smallexample
struct A @{@};
@@ -1577,7 +1563,7 @@ Instantiations of these templates may be mangled incorrectly.
@opindex Wctor-dtor-privacy
Warn when a class seems unusable because all the constructors or
destructors in that class are private, and it has neither friends nor
-public static member functions. This warning is enabled by default.
+public static member functions.
@item -Wnon-virtual-dtor @r{(C++ only)}
@opindex Wnon-virtual-dtor
@@ -1632,7 +1618,7 @@ Item 23: Don't try to return a reference when you must return an object.
@end itemize
-Also warn about violations of the following style guidelines from
+Also warn about violations of the following style guidelines from
Scott Meyers' @cite{More Effective C++} book:
@itemize @bullet
@@ -1711,7 +1697,7 @@ to a plain pointer.
@item -Wsign-promo @r{(C++ only)}
@opindex Wsign-promo
Warn when overload resolution chooses a promotion from unsigned or
-enumeral type to a signed type, over a conversion to an unsigned type of
+enumerated type to a signed type, over a conversion to an unsigned type of
the same size. Previous versions of G++ would try to preserve
unsignedness, but the standard mandates the current behavior.
@@ -1745,14 +1731,17 @@ In this example, G++ will synthesize a default @samp{A& operator =
@cindex compiler options, Objective-C
@cindex Objective-C options, command line
@cindex options, Objective-C
+(NOTE: This manual does not describe the Objective-C language itself. See
+@w{@uref{http://gcc.gnu.org/readings.html}} for references.)
+
This section describes the command-line options that are only meaningful
for Objective-C programs, but you can also use most of the GNU compiler
options regardless of what language your program is in. For example,
you might compile a file @code{some_class.m} like this:
-@example
+@smallexample
gcc -g -fgnu-runtime -O -c some_class.m
-@end example
+@end smallexample
@noindent
In this example, @option{-fgnu-runtime} is an option meant only for
@@ -1767,7 +1756,11 @@ programs:
@opindex fconstant-string-class
Use @var{class-name} as the name of the class to instantiate for each
literal string specified with the syntax @code{@@"@dots{}"}. The default
-class name is @code{NXConstantString}.
+class name is @code{NXConstantString} if the GNU runtime is being used, and
+@code{NSConstantString} if the NeXT runtime is being used (see below). The
+@option{-fconstant-cfstrings} option, if also present, will override the
+@option{-fconstant-string-class} setting and cause @code{@@"@dots{}"} literals
+to be laid out as constant CoreFoundation strings.
@item -fgnu-runtime
@opindex fgnu-runtime
@@ -1781,6 +1774,127 @@ for NeXT-based systems, including Darwin and Mac OS X@. The macro
@code{__NEXT_RUNTIME__} is predefined if (and only if) this option is
used.
+@item -fno-nil-receivers
+@opindex fno-nil-receivers
+Assume that all Objective-C message dispatches (e.g.,
+@code{[receiver message:arg]}) in this translation unit ensure that the receiver
+is not @code{nil}. This allows for more efficient entry points in the runtime to be
+used. Currently, this option is only available in conjunction with
+the NeXT runtime on Mac OS X 10.3 and later.
+
+@item -fobjc-exceptions
+@opindex fobjc-exceptions
+Enable syntactic support for structured exception handling in Objective-C,
+similar to what is offered by C++ and Java. Currently, this option is only
+available in conjunction with the NeXT runtime on Mac OS X 10.3 and later.
+
+@smallexample
+ @@try @{
+ @dots{}
+ @@throw expr;
+ @dots{}
+ @}
+ @@catch (AnObjCClass *exc) @{
+ @dots{}
+ @@throw expr;
+ @dots{}
+ @@throw;
+ @dots{}
+ @}
+ @@catch (AnotherClass *exc) @{
+ @dots{}
+ @}
+ @@catch (id allOthers) @{
+ @dots{}
+ @}
+ @@finally @{
+ @dots{}
+ @@throw expr;
+ @dots{}
+ @}
+@end smallexample
+
+The @code{@@throw} statement may appear anywhere in an Objective-C or
+Objective-C++ program; when used inside of a @code{@@catch} block, the
+@code{@@throw} may appear without an argument (as shown above), in which case
+the object caught by the @code{@@catch} will be rethrown.
+
+Note that only (pointers to) Objective-C objects may be thrown and
+caught using this scheme. When an object is thrown, it will be caught
+by the nearest @code{@@catch} clause capable of handling objects of that type,
+analogously to how @code{catch} blocks work in C++ and Java. A
+@code{@@catch(id @dots{})} clause (as shown above) may also be provided to catch
+any and all Objective-C exceptions not caught by previous @code{@@catch}
+clauses (if any).
+
+The @code{@@finally} clause, if present, will be executed upon exit from the
+immediately preceding @code{@@try @dots{} @@catch} section. This will happen
+regardless of whether any exceptions are thrown, caught or rethrown
+inside the @code{@@try @dots{} @@catch} section, analogously to the behavior
+of the @code{finally} clause in Java.
+
+There are several caveats to using the new exception mechanism:
+
+@itemize @bullet
+@item
+Although currently designed to be binary compatible with @code{NS_HANDLER}-style
+idioms provided by the @code{NSException} class, the new
+exceptions can only be used on Mac OS X 10.3 (Panther) and later
+systems, due to additional functionality needed in the (NeXT) Objective-C
+runtime.
+
+@item
+As mentioned above, the new exceptions do not support handling
+types other than Objective-C objects. Furthermore, when used from
+Objective-C++, the Objective-C exception model does not interoperate with C++
+exceptions at this time. This means you cannot @code{@@throw} an exception
+from Objective-C and @code{catch} it in C++, or vice versa
+(i.e., @code{throw @dots{} @@catch}).
+@end itemize
+
+The @option{-fobjc-exceptions} switch also enables the use of synchronization
+blocks for thread-safe execution:
+
+@smallexample
+ @@synchronized (ObjCClass *guard) @{
+ @dots{}
+ @}
+@end smallexample
+
+Upon entering the @code{@@synchronized} block, a thread of execution shall
+first check whether a lock has been placed on the corresponding @code{guard}
+object by another thread. If it has, the current thread shall wait until
+the other thread relinquishes its lock. Once @code{guard} becomes available,
+the current thread will place its own lock on it, execute the code contained in
+the @code{@@synchronized} block, and finally relinquish the lock (thereby
+making @code{guard} available to other threads).
+
+Unlike Java, Objective-C does not allow for entire methods to be marked
+@code{@@synchronized}. Note that throwing exceptions out of
+@code{@@synchronized} blocks is allowed, and will cause the guarding object
+to be unlocked properly.
+
+@item -freplace-objc-classes
+@opindex freplace-objc-classes
+Emit a special marker instructing @command{ld(1)} not to statically link in
+the resulting object file, and allow @command{dyld(1)} to load it in at
+run time instead. This is used in conjunction with the Fix-and-Continue
+debugging mode, where the object file in question may be recompiled and
+dynamically reloaded in the course of program execution, without the need
+to restart the program itself. Currently, Fix-and-Continue functionality
+is only available in conjunction with the NeXT runtime on Mac OS X 10.3
+and later.
+
+@item -fzero-link
+@opindex fzero-link
+When compiling for the NeXT runtime, the compiler ordinarily replaces calls
+to @code{objc_getClass("@dots{}")} (when the name of the class is known at
+compile time) with static class references that get initialized at load time,
+which improves run-time performance. Specifying the @option{-fzero-link} flag
+suppresses this behavior and causes calls to @code{objc_getClass("@dots{}")}
+to be retained. This is useful in Zero-Link debugging mode, since it allows
+for individual class implementations to be modified during program execution.
+
@item -gen-decls
@opindex gen-decls
Dump interface declarations for all classes seen in the source file to a
@@ -1813,7 +1927,7 @@ being used.
@opindex Wundeclared-selector
Warn if a @code{@@selector(@dots{})} expression referring to an
undeclared selector is found. A selector is considered undeclared if no
-method with that name has been declared before the
+method with that name has been declared before the
@code{@@selector(@dots{})} expression, either explicitly in an
@code{@@interface} or @code{@@protocol} declaration, or implicitly in
an @code{@@implementation} section. This option always performs its
@@ -1822,8 +1936,10 @@ while @code{-Wselector} only performs its checks in the final stage of
compilation. This also enforces the coding style convention
that methods and selectors must be declared before being used.
-@c not documented because only avail via -Wp
-@c @item -print-objc-runtime-info
+@item -print-objc-runtime-info
+@opindex print-objc-runtime-info
+Generate C header describing the largest structure that is passed by
+value, if any.
@end table
@@ -1985,14 +2101,14 @@ Since @option{-Wformat} also checks for null format arguments for
several functions, @option{-Wformat} also implies @option{-Wnonnull}.
@option{-Wformat} is included in @option{-Wall}. For more control over some
-aspects of format checking, the options @option{-Wno-format-y2k},
+aspects of format checking, the options @option{-Wformat-y2k},
@option{-Wno-format-extra-args}, @option{-Wno-format-zero-length},
@option{-Wformat-nonliteral}, @option{-Wformat-security}, and
@option{-Wformat=2} are available, but are not included in @option{-Wall}.
-@item -Wno-format-y2k
-@opindex Wno-format-y2k
-If @option{-Wformat} is specified, do not warn about @code{strftime}
+@item -Wformat-y2k
+@opindex Wformat-y2k
+If @option{-Wformat} is specified, also warn about @code{strftime}
formats which may yield only a two-digit year.
@item -Wno-format-extra-args
@@ -2036,16 +2152,34 @@ included in @option{-Wformat-nonliteral}.)
@opindex Wformat=2
Enable @option{-Wformat} plus format checks not included in
@option{-Wformat}. Currently equivalent to @samp{-Wformat
--Wformat-nonliteral -Wformat-security}.
+-Wformat-nonliteral -Wformat-security -Wformat-y2k}.
@item -Wnonnull
@opindex Wnonnull
-Enable warning about passing a null pointer for arguments marked as
+Warn about passing a null pointer for arguments marked as
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 -Winit-self @r{(C, C++, and Objective-C only)}
+@opindex Winit-self
+Warn about uninitialized variables which are initialized with themselves.
+Note this option can only be used with the @option{-Wuninitialized} option,
+which in turn only works with @option{-O1} and above.
+
+For example, GCC will warn about @code{i} being uninitialized in the
+following snippet only when @option{-Winit-self} has been specified:
+@smallexample
+@group
+int f()
+@{
+ int i = i;
+ return i;
+@}
+@end group
+@end smallexample
+
@item -Wimplicit-int
@opindex Wimplicit-int
Warn when a declaration does not specify a type.
@@ -2167,7 +2301,7 @@ future implementation may also work for C++ programs.
The C standard is worded confusingly, therefore there is some debate
over the precise meaning of the sequence point rules in subtle cases.
Links to discussions of the problem, including proposed formal
-definitions, may be found on our readings page, at
+definitions, may be found on the GCC readings page, at
@w{@uref{http://gcc.gnu.org/readings.html}}.
@item -Wreturn-type
@@ -2182,7 +2316,7 @@ exceptions are @samp{main} and functions defined in system headers.
@item -Wswitch
@opindex Wswitch
-Warn whenever a @code{switch} statement has an index of enumeral type
+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
@@ -2195,7 +2329,7 @@ case.
@item -Wswitch-enum
@opindex Wswitch-enum
-Warn whenever a @code{switch} statement has an index of enumeral type
+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.
@@ -2243,8 +2377,8 @@ To suppress this warning cast the expression to @samp{void}.
All the above @option{-Wunused} options combined.
In order to get a warning about an unused function parameter, you must
-either specify @samp{-W -Wunused} or separately specify
-@option{-Wunused-parameter}.
+either specify @samp{-Wextra -Wunused} (note that @samp{-Wall} implies
+@samp{-Wunused}), or separately specify @option{-Wunused-parameter}.
@item -Wuninitialized
@opindex Wuninitialized
@@ -2256,6 +2390,9 @@ because they require data flow information that is computed only
when optimizing. If you don't specify @option{-O}, you simply won't
get these warnings.
+If you want to warn about code which uses the uninitialized value of the
+variable in its own initializer, use the @option{-Winit-self} option.
+
These warnings occur only for variables that are candidates for
register allocation. Therefore, they do not occur for a variable that
is declared @code{volatile}, or whose address is taken, or whose size
@@ -2357,9 +2494,12 @@ in some cases, and there is no simple way to modify the code to suppress
the warning.
@table @gcctabopt
-@item -W
+@item -Wextra
@opindex W
-Print extra warning messages for these events:
+@opindex Wextra
+(This option used to be called @option{-W}. The older name is still
+supported, but the newer name is more descriptive.) Print extra warning
+messages for these events:
@itemize @bullet
@item
@@ -2414,17 +2554,6 @@ incorrect result when the signed value is converted to unsigned.
(But don't warn if @option{-Wno-sign-compare} is also specified.)
@item
-An aggregate has a partly bracketed initializer.
-For example, the following code would evoke such a warning,
-because braces are missing around the initializer for @code{x.h}:
-
-@smallexample
-struct s @{ int f, g; @};
-struct t @{ struct s h; int i; @};
-struct t x = @{ 1, 2, 3 @};
-@end smallexample
-
-@item
An aggregate has an initializer which does not initialize all members.
For example, the following code would cause such a warning, because
@code{x.h} would be implicitly initialized to zero:
@@ -2433,6 +2562,47 @@ For example, the following code would cause such a warning, because
struct s @{ int f, g, h; @};
struct s x = @{ 3, 4 @};
@end smallexample
+
+@item
+A function parameter is declared without a type specifier in K&R-style
+functions:
+
+@smallexample
+void foo(bar) @{ @}
+@end smallexample
+
+@item
+An empty body occurs in an @samp{if} or @samp{else} statement.
+
+@item
+A pointer is compared against integer zero with @samp{<}, @samp{<=},
+@samp{>}, or @samp{>=}.
+
+@item
+A variable might be changed by @samp{longjmp} or @samp{vfork}.
+
+@item
+Any of several floating-point events that often indicate errors, such as
+overflow, underflow, loss of precision, etc.
+
+@item @r{(C++ only)}
+An enumerator and a non-enumerator both appear in a conditional expression.
+
+@item @r{(C++ only)}
+A non-static reference or non-static @samp{const} member appears in a
+class without constructors.
+
+@item @r{(C++ only)}
+Ambiguous virtual bases.
+
+@item @r{(C++ only)}
+Subscripting an array which has been declared @samp{register}.
+
+@item @r{(C++ only)}
+Taking the address of a variable which has been declared @samp{register}.
+
+@item @r{(C++ only)}
+A base class is not initialized in a derived class' copy constructor.
@end itemize
@item -Wno-div-by-zero
@@ -2505,7 +2675,7 @@ constant suffixes. (Traditional C does support the @samp{L} suffix on integer
constants.) Note, these suffixes appear in macros defined in the system
headers of most modern systems, e.g.@: the @samp{_MIN}/@samp{_MAX} macros in @code{<limits.h>}.
Use of these macros in user code might normally lead to spurious
-warnings, however gcc's integrated preprocessor has enough context to
+warnings, however GCC's integrated preprocessor has enough context to
avoid warning in these cases.
@item
@@ -2554,10 +2724,17 @@ Use of ISO C style function definitions. This warning intentionally is
because these ISO C features will appear in your code when using
libiberty's traditional C compatibility macros, @code{PARAMS} and
@code{VPARAMS}. This warning is also bypassed for nested functions
-because that feature is already a gcc extension and thus not relevant to
+because that feature is already a GCC extension and thus not relevant to
traditional C compatibility.
@end itemize
+@item -Wdeclaration-after-statement @r{(C only)}
+@opindex Wdeclaration-after-statement
+Warn when a declaration is found after a statement in a block. This
+construct, known from C++, was introduced with ISO C99 and is by default
+allowed in GCC@. It is not supported by ISO C90 and was not supported by
+GCC versions before GCC 3.0. @xref{Mixed Declarations}.
+
@item -Wundef
@opindex Wundef
Warn if an undefined identifier is evaluated in an @samp{#if} directive.
@@ -2633,8 +2810,8 @@ casts like @code{(unsigned) -1}.
@cindex signed and unsigned values, comparison warning
Warn when a comparison between signed and unsigned values could produce
an incorrect result when the signed value is converted to unsigned.
-This warning is enabled by @option{-W}, and by @option{-Wall}
-in C++ only.
+This warning is also enabled by @option{-Wextra}; to get the other warnings
+of @option{-Wextra} without this warning, use @samp{-Wextra -Wno-sign-compare}.
@item -Waggregate-return
@opindex Waggregate-return
@@ -2649,6 +2826,11 @@ argument types. (An old-style function definition is permitted without
a warning if preceded by a declaration which specifies the argument
types.)
+@item -Wold-style-definition @r{(C only)}
+@opindex Wold-style-definition
+Warn if an old-style function definition is used. A warning is given
+even if there is a previous prototype.
+
@item -Wmissing-prototypes @r{(C only)}
@opindex Wmissing-prototypes
Warn if a global function is defined without a previous prototype
@@ -2762,7 +2944,7 @@ code is to provide behavior which is selectable at compile-time.
@opindex Winline
Warn if a function can not be inlined and it was declared as inline.
Even with this option, the compiler will not warn about failures to
-inline functions declared in system headers.
+inline functions declared in system headers.
The compiler uses a variety of heuristics to determine whether or not
to inline a function. For example, the compiler takes into account
@@ -2771,6 +2953,26 @@ that has already been done in the current function. Therefore,
seemingly insignificant changes in the source program can cause the
warnings produced by @option{-Winline} to appear or disappear.
+@item -Wno-invalid-offsetof @r{(C++ only)}
+@opindex Wno-invalid-offsetof
+Suppress warnings from applying the @samp{offsetof} macro to a non-POD
+type. According to the 1998 ISO C++ standard, applying @samp{offsetof}
+to a non-POD type is undefined. In existing C++ implementations,
+however, @samp{offsetof} typically gives meaningful results even when
+applied to certain kinds of non-POD types. (Such as a simple
+@samp{struct} that fails to be a POD type only by virtue of having a
+constructor.) This flag is for users who are aware that they are
+writing nonportable code and who have deliberately chosen to ignore the
+warning about it.
+
+The restrictions on @samp{offsetof} may be relaxed in a future version
+of the C++ standard.
+
+@item -Winvalid-pch
+@opindex Winvalid-pch
+Warn if a precompiled header (@pxref{Precompiled Headers}) is found in
+the search path but can't be used.
+
@item -Wlong-long
@opindex Wlong-long
@opindex Wno-long-long
@@ -2814,8 +3016,7 @@ makes debugging work better in GDB but will probably make other debuggers
crash or
refuse to read the program. If you want to control for certain whether
to generate the extra information, use @option{-gstabs+}, @option{-gstabs},
-@option{-gxcoff+}, @option{-gxcoff}, @option{-gdwarf-1+}, @option{-gdwarf-1},
-or @option{-gvms} (see below).
+@option{-gxcoff+}, @option{-gxcoff}, or @option{-gvms} (see below).
Unlike most other C compilers, GCC allows you to use @option{-g} with
@option{-O}. The shortcuts taken by optimized code may occasionally
@@ -2846,6 +3047,11 @@ systems. On MIPS, Alpha and System V Release 4 systems this option
produces stabs debugging output which is not understood by DBX or SDB@.
On System V Release 4 systems this option requires the GNU assembler.
+@item -feliminate-unused-debug-symbols
+@opindex feliminate-unused-debug-symbols
+Produce debugging information in stabs format (if that is supported),
+for only symbols that are actually used.
+
@item -gstabs+
@opindex gstabs+
Produce debugging information in stabs format (if that is supported),
@@ -2872,23 +3078,6 @@ 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
-@opindex gdwarf
-Produce debugging information in DWARF version 1 format (if that is
-supported). This is the format used by SDB on most System V Release 4
-systems.
-
-This option is deprecated.
-
-@item -gdwarf+
-@opindex gdwarf+
-Produce debugging information in DWARF version 1 format (if that is
-supported), using GNU extensions understood only by the GNU debugger
-(GDB)@. The use of these extensions is likely to make other debuggers
-crash or refuse to read the program.
-
-This option is deprecated.
-
@item -gdwarf-2
@opindex gdwarf-2
Produce debugging information in DWARF version 2 format (if that is
@@ -2918,9 +3107,9 @@ present in the program. Some debuggers support macro expansion when
you use @option{-g3}.
Note that in order to avoid confusion between DWARF1 debug level 2,
-and DWARF2, neither @option{-gdwarf} nor @option{-gdwarf-2} accept
-a concatenated debug level. Instead use an additional @option{-g@var{level}}
-option to change the debug level for DWARF1 or DWARF2.
+and DWARF2 @option{-gdwarf-2} does not accept a concatenated debug
+level. Instead use an additional @option{-g@var{level}} option to
+change the debug level for DWARF2.
@item -feliminate-dwarf2-dups
@opindex feliminate-dwarf2-dups
@@ -2961,27 +3150,51 @@ allocation when it finishes.
@item -fprofile-arcs
@opindex fprofile-arcs
-Instrument @dfn{arcs} during compilation to generate coverage data or
-for profile-directed block ordering. During execution the program
-records how many times each branch is executed and how many times it is
-taken. When the compiled program exits it saves this data to a file
-called @file{@var{auxname}.da} for each source file. @var{auxname} is
-generated from the name of the output file, if explicitly specified and
-it is not the final executable, otherwise it is the basename of the
-source file. In both cases any suffix is removed (e.g. @file{foo.da}
-for input file @file{dir/foo.c}, or @file{dir/foo.da} for output file
-specified as @option{-o dir/foo.o}).
-
-For profile-directed block ordering, compile the program with
-@option{-fprofile-arcs} plus optimization and code generation options,
-generate the arc profile information by running the program on a
-selected workload, and then compile the program again with the same
-optimization and code generation options plus
+Add code so that program flow @dfn{arcs} are instrumented. During
+execution the program records how many times each branch and call is
+executed and how many times it is taken or returns. When the compiled
+program exits it saves this data to a file called
+@file{@var{auxname}.gcda} for each source file. The data may be used for
+profile-directed optimizations (@option{-fbranch-probabilities}), or for
+test coverage analysis (@option{-ftest-coverage}). Each object file's
+@var{auxname} is generated from the name of the output file, if
+explicitly specified and it is not the final executable, otherwise it is
+the basename of the source file. In both cases any suffix is removed
+(e.g. @file{foo.gcda} for input file @file{dir/foo.c}, or
+@file{dir/foo.gcda} for output file specified as @option{-o dir/foo.o}).
+
+@itemize
+
+@item
+Compile the source files with @option{-fprofile-arcs} plus optimization
+and code generation options. For test coverage analysis, use the
+additional @option{-ftest-coverage} option. You do not need to profile
+every source file in a program.
+
+@item
+Link your object files with @option{-lgcov} or @option{-fprofile-arcs}
+(the latter implies the former).
+
+@item
+Run the program on a representative workload to generate the arc profile
+information. This may be repeated any number of times. You can run
+concurrent instances of your program, and provided that the file system
+supports locking, the data files will be correctly updated. Also
+@code{fork} calls are detected and correctly handled (double counting
+will not happen).
+
+@item
+For profile-directed optimizations, compile the source files again with
+the same optimization and code generation options plus
@option{-fbranch-probabilities} (@pxref{Optimize Options,,Options that
Control Optimization}).
-The other use of @option{-fprofile-arcs} is for use with @command{gcov},
-when it is used with the @option{-ftest-coverage} option.
+@item
+For test coverage analysis, use @command{gcov} to produce human readable
+information from the @file{.gcno} and @file{.gcda} files. Refer to the
+@command{gcov} documentation for further information.
+
+@end itemize
With @option{-fprofile-arcs}, for each function of your program GCC
creates a program flow graph, then finds a spanning tree for the graph.
@@ -2994,34 +3207,13 @@ block must be created to hold the instrumentation code.
@need 2000
@item -ftest-coverage
@opindex ftest-coverage
-Create data files for the @command{gcov} code-coverage utility
-(@pxref{Gcov,, @command{gcov}---a Test Coverage Program}). See
-@option{-fprofile-arcs} option above for a description of @var{auxname}.
-
-@table @gcctabopt
-@item @var{auxname}.bb
-A mapping from basic blocks to line numbers, which @command{gcov} uses to
-associate basic block execution counts with line numbers.
-
-@item @var{auxname}.bbg
-A list of all arcs in the program flow graph. This allows @command{gcov}
-to reconstruct the program flow graph, so that it can compute all basic
-block and arc execution counts from the information in the
-@file{@var{auxname}.da} file.
-@end table
-
-Use @option{-ftest-coverage} with @option{-fprofile-arcs}; the latter
-option adds instrumentation to the program, which then writes
-execution counts to another data file:
-
-@table @gcctabopt
-@item @var{auxname}.da
-Runtime arc execution counts, used in conjunction with the arc
-information in the file @file{@var{auxname}.bbg}.
-@end table
-
-Coverage data will map better to the source files if
-@option{-ftest-coverage} is used without optimization.
+Produce a notes file that the @command{gcov} code-coverage utility
+(@pxref{Gcov,, @command{gcov}---a Test Coverage Program}) can use to
+show program coverage. Each source file's note file is called
+@file{@var{auxname}.gcno}. Refer to the @option{-fprofile-arcs} option
+above for a description of @var{auxname} and instructions on how to
+generate test coverage data. Coverage data will match the source files
+more closely, if you do not optimize.
@item -d@var{letters}
@opindex d
@@ -3031,7 +3223,7 @@ for most of the dumps are made by appending a pass number and a word to
the @var{dumpname}. @var{dumpname} is generated from the name of the
output file, if explicitly specified and it is not an executable,
otherwise it is the basename of the source file. In both cases any
-suffix is removed (e.g. @file{foo.00.rtl} or @file{foo.01.sibling}).
+suffix is removed (e.g. @file{foo.01.rtl} or @file{foo.02.sibling}).
Here are the possible letters for use in @var{letters}, and their
meanings:
@@ -3041,113 +3233,119 @@ meanings:
Annotate the assembler output with miscellaneous debugging information.
@item b
@opindex db
-Dump after computing branch probabilities, to @file{@var{file}.14.bp}.
+Dump after computing branch probabilities, to @file{@var{file}.12.bp}.
@item B
@opindex dB
-Dump after block reordering, to @file{@var{file}.32.bbro}.
+Dump after block reordering, to @file{@var{file}.31.bbro}.
@item c
@opindex dc
-Dump after instruction combination, to the file @file{@var{file}.19.combine}.
+Dump after instruction combination, to the file @file{@var{file}.20.combine}.
@item C
@opindex dC
-Dump after the first if conversion, to the file @file{@var{file}.15.ce1}.
+Dump after the first if conversion, to the file @file{@var{file}.14.ce1}.
+Also dump after the second if conversion, to the file @file{@var{file}.21.ce2}.
@item d
@opindex dd
-Dump after delayed branch scheduling, to @file{@var{file}.34.dbr}.
+Dump after branch target load optimization, to to @file{@var{file}.32.btl}.
+Also dump after delayed branch scheduling, to @file{@var{file}.36.dbr}.
@item D
@opindex dD
Dump all macro definitions, at the end of preprocessing, in addition to
normal output.
-@item e
-@opindex de
-Dump after SSA optimizations, to @file{@var{file}.04.ssa} and
-@file{@var{file}.07.ussa}.
@item E
@opindex dE
-Dump after the second if conversion, to @file{@var{file}.29.ce3}.
+Dump after the third if conversion, to @file{@var{file}.30.ce3}.
@item f
@opindex df
-Dump after control and data flow analysis, to @file{@var{file}.14.cfg}.
-Also dump after life analysis, to @file{@var{file}.18.life}.
+Dump after control and data flow analysis, to @file{@var{file}.11.cfg}.
+Also dump after life analysis, to @file{@var{file}.19.life}.
@item F
@opindex dF
-Dump after purging @code{ADDRESSOF} codes, to @file{@var{file}.10.addressof}.
+Dump after purging @code{ADDRESSOF} codes, to @file{@var{file}.07.addressof}.
@item g
@opindex dg
-Dump after global register allocation, to @file{@var{file}.24.greg}.
+Dump after global register allocation, to @file{@var{file}.25.greg}.
@item G
@opindex dG
-Dump after GCSE, to @file{@var{file}.11.gcse}.
+Dump after GCSE, to @file{@var{file}.08.gcse}.
+Also dump after jump bypassing and control flow optimizations, to
+@file{@var{file}.10.bypass}.
@item h
@opindex dh
-Dump after finalization of EH handling code, to @file{@var{file}.02.eh}.
+Dump after finalization of EH handling code, to @file{@var{file}.03.eh}.
@item i
@opindex di
-Dump after sibling call optimizations, to @file{@var{file}.01.sibling}.
+Dump after sibling call optimizations, to @file{@var{file}.02.sibling}.
@item j
@opindex dj
-Dump after the first jump optimization, to @file{@var{file}.03.jump}.
+Dump after the first jump optimization, to @file{@var{file}.04.jump}.
@item k
@opindex dk
-Dump after conversion from registers to stack, to @file{@var{file}.31.stack}.
+Dump after conversion from registers to stack, to @file{@var{file}.34.stack}.
@item l
@opindex dl
-Dump after local register allocation, to @file{@var{file}.23.lreg}.
+Dump after local register allocation, to @file{@var{file}.24.lreg}.
@item L
@opindex dL
-Dump after loop optimization, to @file{@var{file}.12.loop}.
+Dump after loop optimization passes, to @file{@var{file}.09.loop} and
+@file{@var{file}.16.loop2}.
@item M
@opindex dM
Dump after performing the machine dependent reorganization pass, to
-@file{@var{file}.33.mach}.
+@file{@var{file}.35.mach}.
@item n
@opindex dn
-Dump after register renumbering, to @file{@var{file}.28.rnreg}.
+Dump after register renumbering, to @file{@var{file}.29.rnreg}.
@item N
@opindex dN
-Dump after the register move pass, to @file{@var{file}.21.regmove}.
+Dump after the register move pass, to @file{@var{file}.22.regmove}.
@item o
@opindex do
-Dump after post-reload optimizations, to @file{@var{file}.25.postreload}.
+Dump after post-reload optimizations, to @file{@var{file}.26.postreload}.
@item r
@opindex dr
-Dump after RTL generation, to @file{@var{file}.00.rtl}.
+Dump after RTL generation, to @file{@var{file}.01.rtl}.
@item R
@opindex dR
-Dump after the second scheduling pass, to @file{@var{file}.30.sched2}.
+Dump after the second scheduling pass, to @file{@var{file}.33.sched2}.
@item s
@opindex ds
Dump after CSE (including the jump optimization that sometimes follows
-CSE), to @file{@var{file}.09.cse}.
+CSE), to @file{@var{file}.06.cse}.
@item S
@opindex dS
-Dump after the first scheduling pass, to @file{@var{file}.22.sched}.
+Dump after the first scheduling pass, to @file{@var{file}.23.sched}.
@item t
@opindex dt
Dump after the second CSE pass (including the jump optimization that
-sometimes follows CSE), to @file{@var{file}.17.cse2}.
+sometimes follows CSE), to @file{@var{file}.18.cse2}.
@item T
@opindex dT
-Dump after running tracer, to @file{@var{file}.16.tracer}.
+Dump after running tracer, to @file{@var{file}.15.tracer}.
@item u
@opindex du
-Dump after null pointer elimination pass to @file{@var{file}.08.null}.
+Dump after null pointer elimination pass to @file{@var{file}.05.null}.
+@item U
+@opindex dU
+Dump callgraph and unit-at-a-time optimization @file{@var{file}.00.unit}.
+@item V
+@opindex dV
+Dump after the value profile transformations, to @file{@var{file}.13.vpt}.
@item w
@opindex dw
-Dump after the second flow pass, to @file{@var{file}.26.flow2}.
-@item W
-@opindex dW
-Dump after SSA conditional constant propagation, to
-@file{@var{file}.05.ssaccp}.
-@item X
-@opindex dX
-Dump after SSA dead code elimination, to @file{@var{file}.06.ssadce}.
+Dump after the second flow pass, to @file{@var{file}.27.flow2}.
@item z
@opindex dz
-Dump after the peephole pass, to @file{@var{file}.27.peephole2}.
+Dump after the peephole pass, to @file{@var{file}.28.peephole2}.
+@item Z
+@opindex dZ
+Dump after constructing the web, to @file{@var{file}.17.web}.
@item a
@opindex da
Produce all the dumps listed above.
+@item H
+@opindex dH
+Produce a core dump whenever an error occurs.
@item m
@opindex dm
Print statistics on memory usage, at the end of the run, to
@@ -3164,7 +3362,7 @@ Also turns on @option{-dp} annotation.
@item v
@opindex dv
For each of the other indicated dump files (except for
-@file{@var{file}.00.rtl}), dump a representation of the control flow graph
+@file{@var{file}.01.rtl}), dump a representation of the control flow graph
suitable for viewing with VCG to @file{@var{file}.@var{pass}.vcg}.
@item x
@opindex dx
@@ -3237,8 +3435,11 @@ Dump after function inlining, to @file{@var{file}.inlined}.
@item -frandom-seed=@var{string}
@opindex frandom-string
This option provides a seed that GCC uses when it would otherwise use
-random numbers. At present, this is used to generate certain symbol names
-that have to be different in every compiled file.
+random numbers. It is used to generate certain symbol names
+that have to be different in every compiled file. It is also used to
+place unique stamps in coverage data files and the object files that
+produce them. You can use the @option{-frandom-seed} option to produce
+reproducibly identical object files.
The @var{string} should be different for every file you compile.
@@ -3316,19 +3517,19 @@ Same as @option{-print-file-name=libgcc.a}.
This is useful when you use @option{-nostdlib} or @option{-nodefaultlibs}
but you do want to link with @file{libgcc.a}. You can do
-@example
+@smallexample
gcc -nostdlib @var{files}@dots{} `gcc -print-libgcc-file-name`
-@end example
+@end smallexample
@item -print-search-dirs
@opindex print-search-dirs
Print the name of the configured installation directory and a list of
-program and library directories gcc will search---and don't do anything else.
+program and library directories @command{gcc} will search---and don't do anything else.
-This is useful when gcc prints the error message
+This is useful when @command{gcc} prints the error message
@samp{installation problem, cannot exec cpp0: No such file or directory}.
To resolve this you either need to put @file{cpp0} and the other compiler
-components where gcc expects to find them, or you can set the environment
+components where @command{gcc} expects to find them, or you can set the environment
variable @env{GCC_EXEC_PREFIX} to the directory where you installed them.
Don't forget the trailing '/'.
@xref{Environment Variables}.
@@ -3347,6 +3548,18 @@ anything else.
@opindex dumpspecs
Print the compiler's built-in specs---and don't do anything else. (This
is used when GCC itself is being built.) @xref{Spec Files}.
+
+@item -feliminate-unused-debug-types
+@opindex feliminate-unused-debug-types
+Normally, when producing DWARF2 output, GCC will emit debugging
+information for all types declared in a compilation
+unit, regardless of whether or not they are actually used
+in that compilation unit. Sometimes this is useful, such as
+if, in the debugger, you want to cast a value to a type that is
+not actually used in your program (but is declared). More often,
+however, this results in a significant amount of wasted space.
+With this option, GCC will avoid producing debug symbol output
+for types that are nowhere used in the source file being compiled.
@end table
@node Optimize Options
@@ -3368,6 +3581,14 @@ Turning on optimization flags makes the compiler attempt to improve
the performance and/or code size at the expense of compilation time
and possibly the ability to debug the program.
+The compiler performs optimization based on the knowledge it has of
+the program. Using the @option{-funit-at-a-time} flag will allow the
+compiler to consider information gained from later functions in the
+file when compiling a function. Compiling multiple files at once to a
+single output file (and using @option{-funit-at-a-time}) will allow
+the compiler to use information gained from all of the files when
+compiling each of them.
+
Not all optimizations are controlled directly by a flag. Only
optimizations that have a flag are listed.
@@ -3383,12 +3604,11 @@ With @option{-O}, the compiler tries to reduce code size and execution
time, without performing any optimizations that take a great deal of
compilation time.
-@option{-O} turns on the following optimization flags:
+@option{-O} turns on the following optimization flags:
@gccoptlist{-fdefer-pop @gol
-fmerge-constants @gol
-fthread-jumps @gol
-floop-optimize @gol
--fcrossjumping @gol
-fif-conversion @gol
-fif-conversion2 @gol
-fdelayed-branch @gol
@@ -3413,18 +3633,20 @@ also turns on the following optimization flags:
-fstrength-reduce @gol
-fcse-follow-jumps -fcse-skip-blocks @gol
-frerun-cse-after-loop -frerun-loop-opt @gol
--fgcse -fgcse-lm -fgcse-sm @gol
+-fgcse -fgcse-lm -fgcse-sm -fgcse-las @gol
-fdelete-null-pointer-checks @gol
-fexpensive-optimizations @gol
-fregmove @gol
-fschedule-insns -fschedule-insns2 @gol
--fsched-interblock -fsched-spec @gol
+-fsched-interblock -fsched-spec @gol
-fcaller-saves @gol
-fpeephole2 @gol
-freorder-blocks -freorder-functions @gol
-fstrict-aliasing @gol
+-funit-at-a-time @gol
-falign-functions -falign-jumps @gol
--falign-loops -falign-labels}
+-falign-loops -falign-labels @gol
+-fcrossjumping}
Please note the warning under @option{-fgcse} about
invoking @option{-O2} on programs that use computed gotos.
@@ -3432,8 +3654,8 @@ invoking @option{-O2} on programs that use computed gotos.
@item -O3
@opindex O3
Optimize yet more. @option{-O3} turns on all optimizations specified by
-@option{-O2} and also turns on the @option{-finline-functions} and
-@option{-frename-registers} options.
+@option{-O2} and also turns on the @option{-finline-functions},
+@option{-fweb} and @option{-frename-registers} options.
@item -O0
@opindex O0
@@ -3542,7 +3764,7 @@ Enabled at level @option{-O3}.
@item -finline-limit=@var{n}
@opindex finline-limit
-By default, gcc limits the size of functions that can be inlined. This flag
+By default, GCC limits the size of functions that can be inlined. This flag
allows the control of this limit for functions that are explicitly marked as
inline (i.e., marked with the inline keyword or defined within the class
definition in c++). @var{n} is the size of functions that can be inlined in
@@ -3556,12 +3778,10 @@ use inlining heavily such as those based on recursive templates with C++.
Inlining is actually controlled by a number of parameters, which may be
specified individually by using @option{--param @var{name}=@var{value}}.
-The @option{-finline-limit=@var{n}} option sets some of these parameters
+The @option{-finline-limit=@var{n}} option sets some of these parameters
as follows:
@table @gcctabopt
- @item max-inline-insns
- is set to @var{n}.
@item max-inline-insns-single
is set to @var{n}/2.
@item max-inline-insns-auto
@@ -3572,8 +3792,7 @@ as follows:
is set to @var{n}.
@end table
-Using @option{-finline-limit=600} thus results in the default settings
-for these parameters. See below for a documentation of the individual
+See below for a documentation of the individual
parameters controlling inlining.
@emph{Note:} pseudo instruction represents, in this particular context, an
@@ -3617,6 +3836,12 @@ types. Languages like C or C++ require each non-automatic variable to
have distinct location, so using this option will result in non-conforming
behavior.
+@item -fnew-ra
+@opindex fnew-ra
+Use a graph coloring register allocator. Currently this option is meant
+only for testing. Users should not specify this option, since it is not
+yet ready for production use.
+
@item -fno-branch-count-reg
@opindex fno-branch-count-reg
Do not use ``decrement and branch'' instructions on a count register,
@@ -3725,10 +3950,19 @@ Enabled by default when gcse is enabled.
@item -fgcse-sm
@opindex fgcse-sm
-When @option{-fgcse-sm} is enabled, A store motion pass is run after global common
-subexpression elimination. This pass will attempt to move stores out of loops.
-When used in conjunction with @option{-fgcse-lm}, loops containing a load/store sequence
-can be changed to a load before the loop and a store after the loop.
+When @option{-fgcse-sm} is enabled, a store motion pass is run after
+global common subexpression elimination. This pass will attempt to move
+stores out of loops. When used in conjunction with @option{-fgcse-lm},
+loops containing a load/store sequence can be changed to a load before
+the loop and a store after the loop.
+
+Enabled by default when gcse is enabled.
+
+@item -fgcse-las
+@opindex fgcse-las
+When @option{-fgcse-las} is enabled, the global common subexpression
+elimination pass eliminates redundant loads that come after stores to the
+same memory location (both partial and full redundancies).
Enabled by default when gcse is enabled.
@@ -3848,6 +4082,42 @@ Allow speculative motion of more load instructions. This only makes
sense when scheduling before register allocation, i.e.@: with
@option{-fschedule-insns} or at @option{-O2} or higher.
+@item -fsched-stalled-insns=@var{n}
+@opindex fsched-stalled-insns
+Define how many insns (if any) can be moved prematurely from the queue
+of stalled insns into the ready list, during the second scheduling pass.
+
+@item -fsched-stalled-insns-dep=@var{n}
+@opindex fsched-stalled-insns-dep
+Define how many insn groups (cycles) will be examined for a dependency
+on a stalled insn that is candidate for premature removal from the queue
+of stalled insns. Has an effect only during the second scheduling pass,
+and only if @option{-fsched-stalled-insns} is used and its value is not zero.
+
+@item -fsched2-use-superblocks
+@opindex fsched2-use-superblocks
+When scheduling after register allocation, do use superblock scheduling
+algorithm. Superblock scheduling allows motion across basic block boundaries
+resulting on faster schedules. This option is experimental, as not all machine
+descriptions used by GCC model the CPU closely enough to avoid unreliable
+results from the algorithm.
+
+This only makes sense when scheduling after register allocation, i.e.@: with
+@option{-fschedule-insns2} or at @option{-O2} or higher.
+
+@item -fsched2-use-traces
+@opindex fsched2-use-traces
+Use @option{-fsched2-use-superblocks} algorithm when scheduling after register
+allocation and additionally perform code duplication in order to increase the
+size of superblocks using tracer pass. See @option{-ftracer} for details on
+trace formation.
+
+This mode should produce faster but significantly longer programs. Also
+without @code{-fbranch-probabilities} the traces constructed may not match the
+reality and hurt the performance. This only makes
+sense when scheduling after register allocation, i.e.@: with
+@option{-fschedule-insns2} or at @option{-O2} or higher.
+
@item -fcaller-saves
@opindex fcaller-saves
Enable values to be allocated in registers that will be clobbered by
@@ -3881,11 +4151,10 @@ These two options are intended to be removed someday, once
they have helped determine the efficacy of various
approaches to improving loop optimizations.
-Please let us (@w{@email{gcc@@gcc.gnu.org}} and @w{@email{fortran@@gnu.org}})
-know how use of these options affects
-the performance of your production code.
-We're very interested in code that runs @emph{slower}
-when these options are @emph{enabled}.
+Please contact @w{@email{gcc@@gcc.gnu.org}}, and describe how use of
+these options affects the performance of your production code.
+Examples of code that runs @emph{slower} when these options are
+@emph{enabled} are very valuable.
@item -fno-peephole
@itemx -fno-peephole2
@@ -3899,12 +4168,11 @@ other, a few use both.
@option{-fpeephole} is enabled by default.
@option{-fpeephole2} enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
-@item -fbranch-probabilities
@item -fno-guess-branch-probability
@opindex fno-guess-branch-probability
Do not guess branch probabilities using a randomized model.
-Sometimes gcc will opt to use a randomized model to guess branch
+Sometimes GCC will opt to use a randomized model to guess branch
probabilities, when none are available from either profiling feedback
(@option{-fprofile-arcs}) or @samp{__builtin_expect}. This means that
different runs of the compiler on the same program may produce different
@@ -3952,7 +4220,7 @@ example, an @code{unsigned int} can alias an @code{int}, but not a
type.
Pay special attention to code like this:
-@example
+@smallexample
union a_union @{
int i;
double d;
@@ -3963,13 +4231,13 @@ int f() @{
t.d = 3.0;
return t.i;
@}
-@end example
+@end smallexample
The practice of reading from a different union member than the one most
recently written to (called ``type-punning'') is common. Even with
@option{-fstrict-aliasing}, type-punning is allowed, provided the memory
is accessed through the union type. So, the code above will work as
expected. However, this code might not:
-@example
+@smallexample
int f() @{
a_union t;
int* ip;
@@ -3977,7 +4245,7 @@ int f() @{
ip = &t.i;
return *ip;
@}
-@end example
+@end smallexample
Every language that wishes to perform language-specific alias analysis
should define a function that computes, given an @code{tree}
@@ -4063,6 +4331,15 @@ will most benefit processors with lots of registers. It can, however,
make debugging impossible, since variables will no longer stay in
a ``home register''.
+@item -fweb
+@opindex fweb
+Constructs webs as commonly used for register allocation purposes and assign
+each web individual pseudo register. This allows the register allocation pass
+to operate on pseudos directly, but also strengthens several other optimization
+passes, such as CSE, loop optimizer and trivial dead code remover. It can,
+however, make debugging impossible, since variables will no longer stay in a
+``home register''.
+
Enabled at levels @option{-O3}.
@item -fno-cprop-registers
@@ -4073,6 +4350,24 @@ and occasionally eliminate the copy.
Disabled at levels @option{-O}, @option{-O2}, @option{-O3}, @option{-Os}.
+@item -fprofile-generate
+@opindex fprofile-generate
+
+Enable options usually used for instrumenting application to produce
+profile useful for later recompilation with profile feedback based
+optimization. You must use @code{-fprofile-generate} both when
+compiling and when linking your program.
+
+The following options are enabled: @code{-fprofile-arcs}, @code{-fprofile-values}, @code{-fvpt}.
+
+@item -fprofile-use
+@opindex fprofile-use
+Enable profile feedback directed optimizations, and optimizations
+generally profitable only with profile feedback available.
+
+The following options are enabled: @code{-fbranch-probabilities},
+@code{-fvpt}, @code{-funroll-loops}, @code{-fpeel-loops}, @code{-ftracer}.
+
@end table
The following options control compiler behavior regarding floating
@@ -4098,8 +4393,8 @@ them to store all pertinent intermediate computations into variables.
@item -ffast-math
@opindex ffast-math
Sets @option{-fno-math-errno}, @option{-funsafe-math-optimizations}, @*
-@option{-fno-trapping-math}, @option{-ffinite-math-only} and @*
-@option{-fno-signaling-nans}.
+@option{-fno-trapping-math}, @option{-ffinite-math-only},
+@option{-fno-rounding-math} and @option{-fno-signaling-nans}.
This option causes the preprocessor macro @code{__FAST_MATH__} to be defined.
@@ -4163,6 +4458,26 @@ math functions.
The default is @option{-ftrapping-math}.
+@item -frounding-math
+@opindex frounding-math
+Disable transformations and optimizations that assume default floating
+point rounding behavior. This is round-to-zero for all floating point
+to integer conversions, and round-to-nearest for all other arithmetic
+truncations. This option should be specified for programs that change
+the FP rounding mode dynamically, or that may be executed with a
+non-default rounding mode. This option disables constant folding of
+floating point expressions at compile-time (which may be affected by
+rounding mode) and arithmetic transformations that are unsafe in the
+presence of sign-dependent rounding modes.
+
+The default is @option{-fno-rounding-math}.
+
+This option is experimental and does not currently guarantee to
+disable all GCC optimizations that are affected by rounding mode.
+Future versions of GCC may provide finer control of this setting
+using C99's @code{FENV_ACCESS} pragma. This command line option
+will be used to specify the default state for @code{FENV_ACCESS}.
+
@item -fsignaling-nans
@opindex fsignaling-nans
Compile code assuming that IEEE signaling NaNs may generate user-visible
@@ -4199,18 +4514,37 @@ After running a program compiled with @option{-fprofile-arcs}
@option{-fbranch-probabilities}, to improve optimizations based on
the number of times each branch was taken. When the program
compiled with @option{-fprofile-arcs} exits it saves arc execution
-counts to a file called @file{@var{sourcename}.da} for each source
+counts to a file called @file{@var{sourcename}.gcda} for each source
file The information in this data file is very dependent on the
structure of the generated code, so you must use the same source code
and the same optimization options for both compilations.
-With @option{-fbranch-probabilities}, GCC puts a
+With @option{-fbranch-probabilities}, GCC puts a
@samp{REG_BR_PROB} note on each @samp{JUMP_INSN} and @samp{CALL_INSN}.
These can be used to improve optimization. Currently, they are only
used in one place: in @file{reorg.c}, instead of guessing which path a
branch is mostly to take, the @samp{REG_BR_PROB} values are used to
exactly determine which path is taken more often.
+@item -fprofile-values
+@opindex fprofile-values
+If combined with @option{-fprofile-arcs}, it adds code so that some
+data about values of expressions in the program is gathered.
+
+With @option{-fbranch-probabilities}, it reads back the data gathered
+from profiling values of expressions and adds @samp{REG_VALUE_PROFILE}
+notes to instructions for their later usage in optimizations.
+
+@item -fvpt
+@opindex fvpt
+If combined with @option{-fprofile-arcs}, it instructs the compiler to add
+a code to gather information about values of expressions.
+
+With @option{-fbranch-probabilities}, it reads back the data gathered
+and actually performs the optimizations based on them.
+Currently the optimizations include specialization of division operation
+using the knowledge about the value of the denominator.
+
@item -fnew-ra
@opindex fnew-ra
Use a graph coloring register allocator. Currently this option is meant
@@ -4223,19 +4557,63 @@ Perform tail duplication to enlarge superblock size. This transformation
simplifies the control flow of the function allowing other optimizations to do
better job.
+@item -funit-at-a-time
+@opindex funit-at-a-time
+Parse the whole compilation unit before starting to produce code.
+This allows some extra optimizations to take place but consumes more
+memory.
+
@item -funroll-loops
@opindex funroll-loops
-Unroll loops whose number of iterations can be determined at compile
-time or upon entry to the loop. @option{-funroll-loops} implies both
-@option{-fstrength-reduce} and @option{-frerun-cse-after-loop}. This
-option makes code larger, and may or may not make it run faster.
+Unroll loops whose number of iterations can be determined at compile time or
+upon entry to the loop. @option{-funroll-loops} implies
+@option{-frerun-cse-after-loop}. It also turns on complete loop peeling
+(i.e. complete removal of loops with small constant number of iterations).
+This option makes code larger, and may or may not make it run faster.
@item -funroll-all-loops
@opindex funroll-all-loops
Unroll all loops, even if their number of iterations is uncertain when
the loop is entered. This usually makes programs run more slowly.
@option{-funroll-all-loops} implies the same options as
-@option{-funroll-loops},
+@option{-funroll-loops}.
+
+@item -fpeel-loops
+@opindex fpeel-loops
+Peels the loops for that there is enough information that they do not
+roll much (from profile feedback). It also turns on complete loop peeling
+(i.e. complete removal of loops with small constant number of iterations).
+
+@item -funswitch-loops
+@opindex funswitch-loops
+Move branches with loop invariant conditions out of the loop, with duplicates
+of the loop on both branches (modified according to result of the condition).
+
+@item -fold-unroll-loops
+@opindex fold-unroll-loops
+Unroll loops whose number of iterations can be determined at compile
+time or upon entry to the loop, using the old loop unroller whose loop
+recognition is based on notes from frontend. @option{-fold-unroll-loops} implies
+both @option{-fstrength-reduce} and @option{-frerun-cse-after-loop}. This
+option makes code larger, and may or may not make it run faster.
+
+@item -fold-unroll-all-loops
+@opindex fold-unroll-all-loops
+Unroll all loops, even if their number of iterations is uncertain when
+the loop is entered. This is done using the old loop unroller whose loop
+recognition is based on notes from frontend. This usually makes programs run more slowly.
+@option{-fold-unroll-all-loops} implies the same options as
+@option{-fold-unroll-loops}.
+
+@item -funswitch-loops
+@opindex funswitch-loops
+Move branches with loop invariant conditions out of the loop, with duplicates
+of the loop on both branches (modified according to result of the condition).
+
+@item -funswitch-loops
+@opindex funswitch-loops
+Move branches with loop invariant conditions out of the loop, with duplicates
+of the loop on both branches (modified according to result of the condition).
@item -fprefetch-loop-arrays
@opindex fprefetch-loop-arrays
@@ -4266,23 +4644,18 @@ You will not be able to use @code{gprof} on all systems if you
specify this option and you may have problems with debugging if
you specify both this option and @option{-g}.
-@item -fssa
-@opindex fssa
-Perform optimizations in static single assignment form. Each function's
-flow graph is translated into SSA form, optimizations are performed, and
-the flow graph is translated back from SSA form. Users should not
-specify this option, since it is not yet ready for production use.
-
-@item -fssa-ccp
-@opindex fssa-ccp
-Perform Sparse Conditional Constant Propagation in SSA form. Requires
-@option{-fssa}. Like @option{-fssa}, this is an experimental feature.
-
-@item -fssa-dce
-@opindex fssa-dce
-Perform aggressive dead-code elimination in SSA form. Requires @option{-fssa}.
-Like @option{-fssa}, this is an experimental feature.
+@item -fbranch-target-load-optimize
+@opindex fbranch-target-load-optimize
+Perform branch target register load optimization before prologue / epilogue
+threading.
+The use of target registers can typically be exposed only during reload,
+thus hoisting loads out of loops and doing inter-block scheduling needs
+a separate optimization pass.
+@item -fbranch-target-load-optimize2
+@opindex fbranch-target-load-optimize2
+Perform branch target register load optimization after prologue / epilogue
+threading.
@item --param @var{name}=@var{value}
@opindex param
@@ -4292,6 +4665,10 @@ that contain more that a certain number of instructions. You can
control some of these constants on the command-line using the
@option{--param} option.
+The names of specific parameters, and the meaning of the values, are
+tied to the internals of the compiler, and are subject to change
+without notice in future releases.
+
In each case, the @var{value} is an integer. The allowable choices for
@var{name} are given in the following table:
@@ -4336,11 +4713,11 @@ needlessly consume memory and resources.
@item max-inline-insns-single
Several parameters control the tree inliner used in gcc.
-This number sets the maximum number of instructions (counted in gcc's
-internal representation) in a single function that the tree inliner
+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 300.
+The default value is 500.
@item max-inline-insns-auto
When you use @option{-finline-functions} (included in @option{-O3}),
@@ -4348,45 +4725,65 @@ 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 300.
-
-@item max-inline-insns
-The tree inliner does decrease the allowable size for single functions
-to be inlined after we already inlined the number of instructions
-given here by repeated inlining. This number should be a factor of
-two or more larger than the single function limit.
-Higher numbers result in better runtime performance, but incur higher
-compile-time resource (CPU time, memory) requirements and result in
-larger binaries. Very high values are not advisable, as too large
-binaries may adversely affect runtime performance.
-The default value is 600.
-
-@item max-inline-slope
-After exceeding the maximum number of inlined instructions by repeated
-inlining, a linear function is used to decrease the allowable size
-for single functions. The slope of that function is the negative
-reciprocal of the number specified here.
-The default value is 32.
-
-@item min-inline-insns
-The repeated inlining is throttled more and more by the linear function
-after exceeding the limit. To avoid too much throttling, a minimum for
-this function is specified here to allow repeated inlining for very small
-functions even when a lot of repeated inlining already has been done.
-The default value is 130.
+The default value is 100.
+
+@item large-function-insns
+The limit specifying really large functions. For functions greater than this
+limit inlining is constrained by @option{--param large-function-growth}.
+This parameter is useful primarily to avoid extreme compilation time caused by non-linear
+algorithms used by the backend.
+This parameter is ignored when @option{-funit-at-a-time} is not used.
+The default value is 3000.
+
+@item large-function-growth
+Specifies maximal growth of large function caused by inlining in percents.
+This parameter is ignored when @option{-funit-at-a-time} is not used.
+The default value is 200.
+
+@item inline-unit-growth
+Specifies maximal overall growth of the compilation unit caused by inlining.
+This parameter is ignored when @option{-funit-at-a-time} is not used.
+The default value is 150.
@item max-inline-insns-rtl
For languages that use the RTL inliner (this happens at a later stage
-than tree inlining), you can set the maximum allowable size (counted
+than tree inlining), you can set the maximum allowable size (counted
in RTL instructions) for the RTL inliner with this parameter.
The default value is 600.
-
@item max-unrolled-insns
The maximum number of instructions that a loop should have if that loop
is unrolled, and if the loop is unrolled, it determines how many times
the loop code is unrolled.
+@item max-average-unrolled-insns
+The maximum number of instructions biased by probabilities of their execution
+that a loop should have if that loop is unrolled, and if the loop is unrolled,
+it determines how many times the loop code is unrolled.
+
+@item max-unroll-times
+The maximum number of unrollings of a single loop.
+
+@item max-peeled-insns
+The maximum number of instructions that a loop should have if that loop
+is peeled, and if the loop is peeled, it determines how many times
+the loop code is peeled.
+
+@item max-peel-times
+The maximum number of peelings of a single loop.
+
+@item max-completely-peeled-insns
+The maximum number of insns of a completely peeled loop.
+
+@item max-completely-peel-times
+The maximum number of iterations of a loop to be suitable for complete peeling.
+
+@item max-unswitch-insns
+The maximum number of insns of an unswitched loop.
+
+@item max-unswitch-level
+The maximum number of branches unswitched in a single loop.
+
@item hot-bb-count-fraction
Select fraction of the maximal count of repetitions of basic block in program
given basic block needs to have to be considered hot.
@@ -4428,6 +4825,10 @@ compilation for profile feedback and one for compilation without. The value
for compilation with profile feedback needs to be more conservative (higher) in
order to make tracer effective.
+@item max-cse-path-length
+
+Maximum number of basic blocks on path that cse considers.
+
@item ggc-min-expand
GCC uses a garbage collector to manage its own memory allocation. This
@@ -4462,6 +4863,29 @@ parameter very large effectively disables garbage collection. Setting
this parameter and @option{ggc-min-expand} to zero causes a full
collection to occur at every opportunity.
+@item max-reload-search-insns
+The maximum number of instruction reload should look backward for equivalent
+register. Increasing values mean more aggressive optimization, making the
+compile time increase with probably slightly better performance. The default
+value is 100.
+
+@item max-cselib-memory-location
+The maximum number of memory locations cselib should take into acount.
+Increasing values mean more aggressive optimization, making the compile time
+increase with probably slightly better performance. The default value is 500.
+
+@item reorder-blocks-duplicate
+@itemx reorder-blocks-duplicate-feedback
+
+Used by basic block reordering pass to decide whether to use unconditional
+branch or duplicate the code on its destination. Code is duplicated when its
+estimated size is smaller than this value multiplied by the estimated size of
+unconditional jump in the hot spots of the program.
+
+The @option{reorder-block-duplicate-feedback} is used only when profile
+feedback is available and may be set to higher values than
+@option{reorder-block-duplicate} since information about the hot spots is more
+accurate.
@end table
@end table
@@ -4478,6 +4902,7 @@ Some of these options make sense only together with @option{-E} because
they cause the preprocessor output to be unsuitable for actual
compilation.
+@table @gcctabopt
@opindex Wp
You can use @option{-Wp,@var{option}} to bypass the compiler driver
and pass @var{option} directly through to the preprocessor. If
@@ -4489,6 +4914,16 @@ interface is undocumented and subject to change, so whenever possible
you should avoid using @option{-Wp} and let the driver handle the
options instead.
+@item -Xpreprocessor @var{option}
+@opindex preprocessor
+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.
+
+If you want to pass an option that takes an argument, you must use
+@option{-Xpreprocessor} twice, once for the option and once for the argument.
+@end table
+
@include cppopts.texi
@node Assembler Options
@@ -4502,6 +4937,16 @@ You can pass options to the assembler.
@opindex Wa
Pass @var{option} as an option to the assembler. If @var{option}
contains commas, it is split into multiple options at the commas.
+
+@item -Xassembler @var{option}
+@opindex Xassembler
+Pass @var{option} as an option to the assembler. You can use this to
+supply system-specific assembler options which GCC does not know how to
+recognize.
+
+If you want to pass an option that takes an argument, you must use
+@option{-Xassembler} twice, once for the option and once for the argument.
+
@end table
@node Link Options
@@ -4615,6 +5060,13 @@ library subroutines. (For example, @samp{__main}, used to ensure C++
constructors will be called; @pxref{Collect2,,@code{collect2}, gccint,
GNU Compiler Collection (GCC) Internals}.)
+@item -pie
+@opindex pie
+Produce a position independent executable on targets which support it.
+For predictable results, you must also specify the same set of options
+that were used to generate code (@option{-fpie}, @option{-fPIE},
+or model suboptions) when you specify this option.
+
@item -s
@opindex s
Remove all symbol table and relocation information from the executable.
@@ -4659,14 +5111,14 @@ this is the right thing to do.
If, instead, you use the GCC driver to create shared libraries, you may
find that they will not always be linked with the shared @file{libgcc}.
-If GCC finds, at its configuration time, that you have a GNU linker that
-does not support option @option{--eh-frame-hdr}, it will link the shared
-version of @file{libgcc} into shared libraries by default. Otherwise,
-it will take advantage of the linker and optimize away the linking with
-the shared version of @file{libgcc}, linking with the static version of
-libgcc by default. This allows exceptions to propagate through such
-shared libraries, without incurring relocation costs at library load
-time.
+If GCC finds, at its configuration time, that you have a non-GNU linker
+or a GNU linker that does not support option @option{--eh-frame-hdr},
+it will link the shared version of @file{libgcc} into shared libraries
+by default. Otherwise, it will take advantage of the linker and optimize
+away the linking with the shared version of @file{libgcc}, linking with
+the static version of libgcc by default. This allows exceptions to
+propagate through such shared libraries, without incurring relocation
+costs at library load time.
However, if a library or main executable is supposed to throw or catch
exceptions, you must link it using the G++ or GCJ driver, as appropriate
@@ -4777,7 +5229,7 @@ without @samp{@var{machine}/@var{version}/} (@pxref{Target Options}).
For each subprogram to be run, the compiler driver first tries the
@option{-B} prefix, if any. If that name is not found, or if @option{-B}
was not specified, the driver tries two standard prefixes, which are
-@file{/usr/lib/gcc/} and @file{/usr/local/lib/gcc-lib/}. If neither of
+@file{/usr/lib/gcc/} and @file{/usr/local/lib/gcc/}. If neither of
those results in a file name that is found, the unmodified program
name is searched for using the directories specified in your
@env{PATH} environment variable.
@@ -5022,6 +5474,15 @@ of a temporary file, just like @samp{%u}. This temporary file is not
meant for communication between processes, but rather as a junk
disposal mechanism.
+@item %|@var{suffix}
+@itemx %m@var{suffix}
+Like @samp{%g}, except if @option{-pipe} is in effect. In that case
+@samp{%|} substitutes a single dash and @samp{%m} substitutes nothing at
+all. These are the two most common ways to instruct a program that it
+should read from standard input or write to standard output. If you
+need something more elaborate you can use an @samp{%@{pipe:@code{X}@}}
+construct: see for example @file{f/lang-specs.h}.
+
@item %.@var{SUFFIX}
Substitutes @var{.SUFFIX} for the suffixes of a matched switch's args
when it is subsequently output with @samp{%*}. @var{SUFFIX} is
@@ -5061,7 +5522,10 @@ predefined macro, except for macros that start with @samp{__} or with
C@.
@item %I
-Substitute a @option{-iprefix} option made from @env{GCC_EXEC_PREFIX}.
+Substitute any of @option{-iprefix} (made from @env{GCC_EXEC_PREFIX}),
+@option{-isysroot} (made from @env{TARGET_SYSTEM_ROOT}), and
+@option{-isystem} (made from @env{COMPILER_PATH} and @option{-B} options)
+as necessary.
@item %s
Current argument is the name of a library or startup file of some sort.
@@ -5072,9 +5536,6 @@ the full name found.
Print @var{str} as an error message. @var{str} is terminated by a newline.
Use this when inconsistent options are detected.
-@item %|
-Output @samp{-} if the input for the current command is coming from a pipe.
-
@item %(@var{name})
Substitute the contents of spec string @var{name} at this point.
@@ -5094,18 +5555,6 @@ Output the accumulated assembler options specified by @option{-Wa}.
@item %Z
Output the accumulated preprocessor options specified by @option{-Wp}.
-@item %v1
-Substitute the major version number of GCC@.
-(For version 2.9.5, this is 2.)
-
-@item %v2
-Substitute the minor version number of GCC@.
-(For version 2.9.5, this is 9.)
-
-@item %v3
-Substitute the patch level number of GCC@.
-(For version 2.9.5, this is 5.)
-
@item %a
Process the @code{asm} spec. This is used to compute the
switches to be passed to the assembler.
@@ -5171,6 +5620,12 @@ Substitute the variable part of a matched option. See below.
Note that each comma in the substituted string is replaced by
a single space.
+@item %<@code{S}
+Remove all occurrences of @code{-S} from the command line. Note---this
+command is position dependent. @samp{%} commands in the spec string
+before this one will see @code{-S}, @samp{%} commands in the spec string
+after this one will not.
+
@item %:@var{function}(@var{args})
Call the named function @var{function}, passing it @var{args}.
@var{args} is first processed as a nested spec string, then split
@@ -5199,12 +5654,12 @@ returns the pathname. If it does not exist, it returns the second argument.
This way, @code{if-exists-else} can be used to select one file or another,
based on the existence of the first. Here is a small example of its usage:
-@smallexample
+@smallexample
*startfile:
crt0%O%s %:if-exists(crti%O%s) \
%:if-exists-else(crtbeginT%O%s crtbegin%O%s)
@end smallexample
-@end table
+@end table
@item %@{@code{S}@}
Substitutes the @code{-S} switch, if that switch was given to GCC@.
@@ -5226,51 +5681,40 @@ GCC considers @option{-o foo} as being
one switch whose names starts with @samp{o}. %@{o*@} would substitute this
text, including the space. Thus two arguments would be generated.
-@item %@{^@code{S}*@}
-Like %@{@code{S}*@}, but don't put a blank between a switch and its
-argument. Thus %@{^o*@} would only generate one argument, not two.
-
@item %@{@code{S}*&@code{T}*@}
Like %@{@code{S}*@}, but preserve order of @code{S} and @code{T} options
(the order of @code{S} and @code{T} in the spec is not significant).
There can be any number of ampersand-separated variables; for each the
wild card is optional. Useful for CPP as @samp{%@{D*&U*&A*@}}.
-@item %@{<@code{S}@}
-Remove all occurrences of @code{-S} from the command line. Note---this
-command is position dependent. @samp{%} commands in the spec string
-before this option will see @code{-S}, @samp{%} commands in the spec
-string after this option will not.
-
-@item %@{@code{S}*:@code{X}@}
-Substitutes @code{X} if one or more switches whose names start with
-@code{-S} are specified to GCC@. Note that the tail part of the
-@code{-S} option (i.e.@: the part matched by the @samp{*}) will be substituted
-for each occurrence of @samp{%*} within @code{X}.
-
@item %@{@code{S}:@code{X}@}
-Substitutes @code{X}, but only if the @samp{-S} switch was given to GCC@.
+Substitutes @code{X}, if the @samp{-S} switch was given to GCC@.
@item %@{!@code{S}:@code{X}@}
-Substitutes @code{X}, but only if the @samp{-S} switch was @emph{not} given to GCC@.
-
-@item %@{|@code{S}:@code{X}@}
-Like %@{@code{S}:@code{X}@}, but if no @code{S} switch, substitute @samp{-}.
+Substitutes @code{X}, if the @samp{-S} switch was @emph{not} given to GCC@.
-@item %@{|!@code{S}:@code{X}@}
-Like %@{!@code{S}:@code{X}@}, but if there is an @code{S} switch, substitute @samp{-}.
+@item %@{@code{S}*:@code{X}@}
+Substitutes @code{X} if one or more switches whose names start with
+@code{-S} are specified to GCC@. Normally @code{X} is substituted only
+once, no matter how many such switches appeared. However, if @code{%*}
+appears somewhere in @code{X}, then @code{X} will be substituted once
+for each matching switch, with the @code{%*} replaced by the part of
+that switch that matched the @code{*}.
@item %@{.@code{S}:@code{X}@}
-Substitutes @code{X}, but only if processing a file with suffix @code{S}.
+Substitutes @code{X}, if processing a file with suffix @code{S}.
@item %@{!.@code{S}:@code{X}@}
-Substitutes @code{X}, but only if @emph{not} processing a file with suffix @code{S}.
+Substitutes @code{X}, if @emph{not} processing a file with suffix @code{S}.
@item %@{@code{S}|@code{P}:@code{X}@}
-Substitutes @code{X} if either @code{-S} or @code{-P} was given to GCC@. This may be
-combined with @samp{!} and @samp{.} sequences as well, although they
-have a stronger binding than the @samp{|}. For example a spec string
-like this:
+Substitutes @code{X} if either @code{-S} or @code{-P} was given to GCC@.
+This may be combined with @samp{!}, @samp{.}, and @code{*} sequences as well,
+although they have a stronger binding than the @samp{|}. If @code{%*}
+appears in @code{X}, all of the alternatives must be starred, and only
+the first matching alternative is substituted.
+
+For example, a spec string like this:
@smallexample
%@{.c:-foo@} %@{!.c:-bar@} %@{.c|d:-baz@} %@{!.c|d:-boggle@}
@@ -5286,23 +5730,33 @@ jim.d -bar -boggle
-d jim.d -bar -baz -boggle
@end smallexample
+@item %@{S:X; T:Y; :D@}
+
+If @code{S} was given to GCC, substitutes @code{X}; else if @code{T} was
+given to GCC, substitutes @code{Y}; else substitutes @code{D}. There can
+be as many clauses as you need. This may be combined with @code{.},
+@code{!}, @code{|}, and @code{*} as needed.
+
+
@end table
-The conditional text @code{X} in a %@{@code{S}:@code{X}@} or
-%@{!@code{S}:@code{X}@} construct may contain other nested @samp{%} constructs
-or spaces, or even newlines. They are processed as usual, as described
-above.
+The conditional text @code{X} in a %@{@code{S}:@code{X}@} or similar
+construct may contain other nested @samp{%} constructs or spaces, or
+even newlines. They are processed as usual, as described above.
+Trailing white space in @code{X} is ignored. White space may also
+appear anywhere on the left side of the colon in these constructs,
+except between @code{.} or @code{*} and the corresponding word.
-The @option{-O}, @option{-f}, @option{-m}, and @option{-W}
-switches are handled specifically in these
-constructs. If another value of @option{-O} or the negated form of a @option{-f}, @option{-m}, or
-@option{-W} switch is found later in the command line, the earlier switch
-value is ignored, except with @{@code{S}*@} where @code{S} is just one
-letter, which passes all matching options.
+The @option{-O}, @option{-f}, @option{-m}, and @option{-W} switches are
+handled specifically in these constructs. If another value of
+@option{-O} or the negated form of a @option{-f}, @option{-m}, or
+@option{-W} switch is found later in the command line, the earlier
+switch value is ignored, except with @{@code{S}*@} where @code{S} is
+just one letter, which passes all matching options.
-The character @samp{|} at the beginning of the predicate text is used to indicate
-that a command should be piped to the following command, but only if @option{-pipe}
-is specified.
+The character @samp{|} at the beginning of the predicate text is used to
+indicate that a command should be piped to the following command, but
+only if @option{-pipe} is specified.
It is built into GCC which switches take arguments and which do not.
(You might think it would be useful to generalize this to allow each
@@ -5387,13 +5841,10 @@ that macro, which enables you to change the defaults.
* VAX Options::
* SPARC Options::
* ARM Options::
-* MN10200 Options::
* MN10300 Options::
* M32R/D Options::
-* M88K Options::
* RS/6000 and PowerPC Options::
* Darwin Options::
-* RT Options::
* MIPS Options::
* i386 and x86-64 Options::
* HPPA Options::
@@ -5508,10 +5959,6 @@ This results in code which can run relatively efficiently on either a
68020/68881 or a 68030 or a 68040. The generated code does use the
68881 instructions that are emulated on the 68060.
-@item -mfpa
-@opindex mfpa
-Generate output containing Sun FPA instructions for floating point.
-
@item -msoft-float
@opindex msoft-float
Generate output containing library calls for floating point.
@@ -5590,6 +6037,30 @@ not presently supported with @option{-mpcrel}, though this could be supported fo
Do not (do) assume that unaligned memory references will be handled by
the system.
+@item -msep-data
+Generate code that allows the data segment to be located in a different
+area of memory from the text segment. This allows for execute in place in
+an environment without virtual memory management. This option implies -fPIC.
+
+@item -mno-sep-data
+Generate code that assumes that the data segment follows the text segment.
+This is the default.
+
+@item -mid-shared-library
+Generate code that supports shared libraries via the library ID method.
+This allows for execute in place and shared libraries in an environment
+without virtual memory management. This option implies -fPIC.
+
+@item -mno-id-shared-library
+Generate code that doesn't assume ID based shared libraries are being used.
+This is the default.
+
+@item -mshared-library-id=n
+Specified the identification number of the ID based shared library being
+compiled. Specifying a value of 0 will generate more compact code, specifying
+other values will force the allocation of that number to the current
+library but is no more space or time efficient than omitting this option.
+
@end table
@node M68hc1x Options
@@ -5620,7 +6091,7 @@ when the compiler is configured for 68HC12-based systems.
@itemx -m68hcs12
@opindex m68S12
@opindex m68hcs12
-Generate output for a 68HCS12.
+Generate output for a 68HCS12.
@item -mauto-incdec
@opindex mauto-incdec
@@ -5681,7 +6152,7 @@ Output code for g-format floating point numbers instead of d-format.
@subsection SPARC Options
@cindex SPARC options
-These @samp{-m} switches are supported on the SPARC:
+These @samp{-m} options are supported on the SPARC:
@table @gcctabopt
@item -mno-app-regs
@@ -5732,7 +6203,7 @@ Generate output containing library calls for quad-word (long double)
floating point instructions. The functions called are those specified
in the SPARC ABI@. This is the default.
-As of this writing, there are no sparc implementations that have hardware
+As of this writing, there are no SPARC implementations that have hardware
support for the quad-word floating point instructions. They all invoke
a trap handler for one of these instructions, and then the trap handler
emulates the effect of the instruction. Because of the trap handler overhead,
@@ -5753,6 +6224,8 @@ The local registers and the input registers (0--5) are still treated as
With @option{-mno-flat} (the default), the compiler emits save/restore
instructions (except for leaf functions) and is the normal mode of operation.
+These options are deprecated and will be deleted in a future GCC release.
+
@item -mno-unaligned-doubles
@itemx -munaligned-doubles
@opindex mno-unaligned-doubles
@@ -5784,7 +6257,7 @@ the rules of the ABI@.
@option{-mimpure-text}, used in addition to @option{-shared}, tells
the compiler to not pass @option{-z text} to the linker when linking a
shared object. Using this option, you can link position-dependent
-code into a shared object.
+code into a shared object.
@option{-mimpure-text} suppresses the ``relocations remain against
allocatable but non-writable sections'' linker error message.
@@ -5800,35 +6273,18 @@ This option is only available on SunOS and Solaris.
@opindex mv8
@opindex msparclite
These two options select variations on the SPARC architecture.
-
-By default (unless specifically configured for the Fujitsu SPARClite),
-GCC generates code for the v7 variant of the SPARC architecture.
-
-@option{-mv8} will give you SPARC v8 code. The only difference from v7
-code is that the compiler emits the integer multiply and integer
-divide instructions which exist in SPARC v8 but not in SPARC v7.
-
-@option{-msparclite} will give you SPARClite code. This adds the integer
-multiply, integer divide step and scan (@code{ffs}) instructions which
-exist in SPARClite but not in SPARC v7.
-
These options are deprecated and will be deleted in a future GCC release.
They have been replaced with @option{-mcpu=xxx}.
@item -mcypress
@itemx -msupersparc
+@itemx -mf930
+@itemx -mf934
@opindex mcypress
@opindex msupersparc
-These two options select the processor for which the code is optimized.
-
-With @option{-mcypress} (the default), the compiler optimizes code for the
-Cypress CY7C602 chip, as used in the SPARCStation/SPARCServer 3xx series.
-This is also appropriate for the older SPARCStation 1, 2, IPX etc.
-
-With @option{-msupersparc} the compiler optimizes code for the SuperSPARC cpu, as
-used in the SPARCStation 10, 1000 and 2000 series. This flag also enables use
-of the full SPARC v8 instruction set.
-
+@opindex -mf930
+@opindex -mf934
+These four options select the processor for which the code is optimized.
These options are deprecated and will be deleted in a future GCC release.
They have been replaced with @option{-mcpu=xxx}.
@@ -5837,7 +6293,7 @@ They have been replaced with @option{-mcpu=xxx}.
Set the instruction set, register set, and instruction scheduling parameters
for machine type @var{cpu_type}. Supported values for @var{cpu_type} are
@samp{v7}, @samp{cypress}, @samp{v8}, @samp{supersparc}, @samp{sparclite},
-@samp{hypersparc}, @samp{sparclite86x}, @samp{f930}, @samp{f934},
+@samp{f930}, @samp{f934}, @samp{hypersparc}, @samp{sparclite86x},
@samp{sparclet}, @samp{tsc701}, @samp{v9}, @samp{ultrasparc}, and
@samp{ultrasparc3}.
@@ -5856,6 +6312,41 @@ implementations.
v9: ultrasparc, ultrasparc3
@end smallexample
+By default (unless configured otherwise), GCC generates code for the V7
+variant of the SPARC architecture. With @option{-mcpu=cypress}, the compiler
+additionally optimizes it for the Cypress CY7C602 chip, as used in the
+SPARCStation/SPARCServer 3xx series. This is also appropriate for the older
+SPARCStation 1, 2, IPX etc.
+
+With @option{-mcpu=v8}, GCC generates code for the V8 variant of the SPARC
+architecture. The only difference from V7 code is that the compiler emits
+the integer multiply and integer divide instructions which exist in SPARC-V8
+but not in SPARC-V7. With @option{-mcpu=supersparc}, the compiler additionally
+optimizes it for the SuperSPARC chip, as used in the SPARCStation 10, 1000 and
+2000 series.
+
+With @option{-mcpu=sparclite}, GCC generates code for the SPARClite variant of
+the SPARC architecture. This adds the integer multiply, integer divide step
+and scan (@code{ffs}) instructions which exist in SPARClite but not in SPARC-V7.
+With @option{-mcpu=f930}, the compiler additionally optimizes it for the
+Fujitsu MB86930 chip, which is the original SPARClite, with no FPU. With
+@option{-mcpu=f934}, the compiler additionally optimizes it for the Fujitsu
+MB86934 chip, which is the more recent SPARClite with FPU.
+
+With @option{-mcpu=sparclet}, GCC generates code for the SPARClet variant of
+the SPARC architecture. This adds the integer multiply, multiply/accumulate,
+integer divide step and scan (@code{ffs}) instructions which exist in SPARClet
+but not in SPARC-V7. With @option{-mcpu=tsc701}, the compiler additionally
+optimizes it for the TEMIC SPARClet chip.
+
+With @option{-mcpu=v9}, GCC generates code for the V9 variant of the SPARC
+architecture. This adds 64-bit integer and floating-point move instructions,
+3 additional floating-point condition code registers and conditional move
+instructions. With @option{-mcpu=ultrasparc}, the compiler additionally
+optimizes it for the Sun UltraSPARC I/II chips. With
+@option{-mcpu=ultrasparc3}, the compiler additionally optimizes it for the
+Sun UltraSPARC III chip.
+
@item -mtune=@var{cpu_type}
@opindex mtune
Set the instruction scheduling parameters for machine type
@@ -5869,36 +6360,25 @@ that select a particular cpu implementation. Those are @samp{cypress},
@samp{sparclite86x}, @samp{tsc701}, @samp{ultrasparc}, and
@samp{ultrasparc3}.
+@item -mv8plus
+@itemx -mno-v8plus
+@opindex mv8plus
+@opindex mno-v8plus
+With @option{-mv8plus}, GCC generates code for the SPARC-V8+ ABI. The
+difference from the V8 ABI is that the global and out registers are
+considered 64-bit wide. This is enabled by default on Solaris in 32-bit
+mode for all SPARC-V9 processors.
+
+@item -mvis
+@itemx -mno-vis
+@opindex mvis
+@opindex mno-vis
+With @option{-mvis}, GCC generates code that takes advantage of the UltraSPARC
+Visual Instruction Set extensions. The default is @option{-mno-vis}.
@end table
-These @samp{-m} switches are supported in addition to the above
-on the SPARCLET processor.
-
-@table @gcctabopt
-@item -mlittle-endian
-@opindex mlittle-endian
-Generate code for a processor running in little-endian mode.
-
-@item -mlive-g0
-@opindex mlive-g0
-Treat register @code{%g0} as a normal register.
-GCC will continue to clobber it as necessary but will not assume
-it always reads as 0.
-
-@item -mbroken-saverestore
-@opindex mbroken-saverestore
-Generate code that does not use non-trivial forms of the @code{save} and
-@code{restore} instructions. Early versions of the SPARCLET processor do
-not correctly handle @code{save} and @code{restore} instructions used with
-arguments. They correctly handle them used without arguments. A @code{save}
-instruction used without arguments increments the current window pointer
-but does not allocate a new stack frame. It is assumed that the window
-overflow trap handler will properly handle this case as will interrupt
-handlers.
-@end table
-
-These @samp{-m} switches are supported in addition to the above
-on SPARC V9 processors in 64-bit environments.
+These @samp{-m} options are supported in addition to the above
+on SPARC-V9 processors in 64-bit environments:
@table @gcctabopt
@item -mlittle-endian
@@ -5917,31 +6397,31 @@ to 64 bits.
@item -mcmodel=medlow
@opindex mcmodel=medlow
-Generate code for the Medium/Low code model: the program must be linked
-in the low 32 bits of the address space. Pointers are 64 bits.
-Programs can be statically or dynamically linked.
+Generate code for the Medium/Low code model: 64-bit addresses, programs
+must be linked in the low 32 bits of memory. Programs can be statically
+or dynamically linked.
@item -mcmodel=medmid
@opindex mcmodel=medmid
-Generate code for the Medium/Middle code model: the program must be linked
-in the low 44 bits of the address space, the text segment must be less than
-2G bytes, and data segment must be within 2G of the text segment.
-Pointers are 64 bits.
+Generate code for the Medium/Middle code model: 64-bit addresses, programs
+must be linked in the low 44 bits of memory, the text and data segments must
+be less than 2GB in size and the data segment must be located within 2GB of
+the text segment.
@item -mcmodel=medany
@opindex mcmodel=medany
-Generate code for the Medium/Anywhere code model: the program may be linked
-anywhere in the address space, the text segment must be less than
-2G bytes, and data segment must be within 2G of the text segment.
-Pointers are 64 bits.
+Generate code for the Medium/Anywhere code model: 64-bit addresses, programs
+may be linked anywhere in memory, the text and data segments must be less
+than 2GB in size and the data segment must be located within 2GB of the
+text segment.
@item -mcmodel=embmedany
@opindex mcmodel=embmedany
Generate code for the Medium/Anywhere code model for embedded systems:
-assume a 32-bit text and a 32-bit data segment, both starting anywhere
-(determined at link time). Register %g4 points to the base of the
-data segment. Pointers are still 64 bits.
-Programs are statically linked, PIC is not supported.
+64-bit addresses, the text and data segments must be less than 2GB in
+size, both starting anywhere in memory (determined at link time). The
+global register %g4 points to the base of the data segment. Programs
+are statically linked and PIC is not supported.
@item -mstack-bias
@itemx -mno-stack-bias
@@ -5949,10 +6429,28 @@ Programs are statically linked, PIC is not supported.
@opindex mno-stack-bias
With @option{-mstack-bias}, GCC assumes that the stack pointer, and
frame pointer if present, are offset by @minus{}2047 which must be added back
-when making stack frame references.
+when making stack frame references. This is the default in 64-bit mode.
Otherwise, assume no such offset is present.
@end table
+These switches are supported in addition to the above on Solaris:
+
+@table @gcctabopt
+@item -threads
+@opindex threads
+Add support for multithreading using the Solaris threads library. This
+option sets flags for both the preprocessor and linker. This option does
+not affect the thread safety of object code produced by the compiler or
+that of libraries supplied with it.
+
+@item -pthreads
+@opindex pthreads
+Add support for multithreading using the POSIX threads library. This
+option sets flags for both the preprocessor and linker. This option does
+not affect the thread safety of object code produced by the compiler or
+that of libraries supplied with it.
+@end table
+
@node ARM Options
@subsection ARM Options
@cindex ARM options
@@ -5977,15 +6475,19 @@ This is a synonym for @option{-mapcs-frame}.
@opindex mapcs-26
Generate code for a processor running with a 26-bit program counter,
and conforming to the function calling standards for the APCS 26-bit
-option. This option replaces the @option{-m2} and @option{-m3} options
-of previous releases of the compiler.
+option.
+
+This option is deprecated. Future releases of the GCC will only support
+generating code that runs in apcs-32 mode.
@item -mapcs-32
@opindex mapcs-32
Generate code for a processor running with a 32-bit program counter,
and conforming to the function calling standards for the APCS 32-bit
-option. This option replaces the @option{-m6} option of previous releases
-of the compiler.
+option.
+
+This flag is deprecated. Future releases of GCC will make this flag
+unconditional.
@ignore
@c not currently implemented
@@ -6086,7 +6588,7 @@ synthesize the access as a series of byte accesses. The compiler can
still use word accesses to load half-word data if it knows that the
address is aligned to a word boundary.
-This option is ignored when compiling for ARM architecture 4 or later,
+This option has no effect when compiling for ARM architecture 4 or later,
since these processors have instructions to directly access half-word
objects in memory.
@@ -6101,21 +6603,11 @@ Note that you cannot use this option to access unaligned word objects,
since the processor will only fetch one 32-bit aligned object from
memory.
-The default setting for most targets is @option{-mno-alignment-traps}, since
-this produces better code when there are no half-word memory
-instructions available.
+The default setting is @option{-malignment-traps}, since this produces
+code that will also run on processors implementing ARM architecture
+version 6 or later.
-@item -mshort-load-bytes
-@itemx -mno-short-load-words
-@opindex mshort-load-bytes
-@opindex mno-short-load-words
-These are deprecated aliases for @option{-malignment-traps}.
-
-@item -mno-short-load-bytes
-@itemx -mshort-load-words
-@opindex mno-short-load-bytes
-@opindex mshort-load-words
-This are deprecated aliases for @option{-mno-alignment-traps}.
+This option is deprecated and will be removed in the next release of GCC.
@item -mcpu=@var{name}
@opindex mcpu
@@ -6129,8 +6621,10 @@ assembly code. Permissible names are: @samp{arm2}, @samp{arm250},
@samp{arm7500}, @samp{arm7500fe}, @samp{arm7tdmi}, @samp{arm8},
@samp{strongarm}, @samp{strongarm110}, @samp{strongarm1100},
@samp{arm8}, @samp{arm810}, @samp{arm9}, @samp{arm9e}, @samp{arm920},
-@samp{arm920t}, @samp{arm940t}, @samp{arm9tdmi}, @samp{arm10tdmi},
-@samp{arm1020t}, @samp{xscale}.
+@samp{arm920t}, @samp{arm926ejs}, @samp{arm940t}, @samp{arm9tdmi},
+@samp{arm10tdmi}, @samp{arm1020t}, @samp{arm1026ejs},
+@samp{arm1136js}, @samp{arm1136jfs} ,@samp{xscale}, @samp{iwmmxt},
+@samp{ep9312}.
@itemx -mtune=@var{name}
@opindex mtune
@@ -6150,7 +6644,8 @@ name to determine what kind of instructions it can emit when generating
assembly code. This option can be used in conjunction with or instead
of the @option{-mcpu=} option. Permissible names are: @samp{armv2},
@samp{armv2a}, @samp{armv3}, @samp{armv3m}, @samp{armv4}, @samp{armv4t},
-@samp{armv5}, @samp{armv5t}, @samp{armv5te}.
+@samp{armv5}, @samp{armv5t}, @samp{armv5te}, @samp{armv6j},
+@samp{iwmmxt}, @samp{ep9312}.
@item -mfpe=@var{number}
@itemx -mfp=@var{number}
@@ -6222,6 +6717,18 @@ before execution begins.
Specify the register to be used for PIC addressing. The default is R10
unless stack-checking is enabled, when R9 is used.
+@item -mcirrus-fix-invalid-insns
+@opindex mcirrus-fix-invalid-insns
+@opindex mno-cirrus-fix-invalid-insns
+Insert NOPs into the instruction stream to in order to work around
+problems with invalid Maverick instruction combinations. This option
+is only valid if the @option{-mcpu=ep9312} option has been used to
+enable generation of instructions for the Cirrus Maverick floating
+point co-processor. This option is not enabled by default, since the
+problem is only present in older Maverick implementations. The default
+can be re-enabled by use of the @option{-mno-cirrus-fix-invalid-insns}
+switch.
+
@item -mpoke-function-name
@opindex mpoke-function-name
Write the name of each function into the text section, directly
@@ -6278,22 +6785,6 @@ of executing a function pointer if this option is enabled.
@end table
-@node MN10200 Options
-@subsection MN10200 Options
-@cindex MN10200 options
-
-These @option{-m} options are defined for Matsushita MN10200 architectures:
-@table @gcctabopt
-
-@item -mrelax
-@opindex mrelax
-Indicate to the linker that it should perform a relaxation optimization pass
-to shorten branches, calls and absolute memory addresses. This option only
-has an effect when used on the command line for the final link step.
-
-This option makes symbolic debugging impossible.
-@end table
-
@node MN10300 Options
@subsection MN10300 Options
@cindex MN10300 options
@@ -6338,9 +6829,13 @@ This option makes symbolic debugging impossible.
@subsection M32R/D Options
@cindex M32R/D options
-These @option{-m} options are defined for Mitsubishi M32R/D architectures:
+These @option{-m} options are defined for Renesas M32R/D architectures:
@table @gcctabopt
+@item -m32r2
+@opindex m32r2
+Generate code for the M32R/2@.
+
@item -m32rx
@opindex m32rx
Generate code for the M32R/X@.
@@ -6349,8 +6844,8 @@ Generate code for the M32R/X@.
@opindex m32r
Generate code for the M32R@. This is the default.
-@item -mcode-model=small
-@opindex mcode-model=small
+@item -mmodel=small
+@opindex mmodel=small
Assume all objects live in the lower 16MB of memory (so that their addresses
can be loaded with the @code{ld24} instruction), and assume all subroutines
are reachable with the @code{bl} instruction.
@@ -6359,14 +6854,14 @@ This is the default.
The addressability of a particular object can be set with the
@code{model} attribute.
-@item -mcode-model=medium
-@opindex mcode-model=medium
+@item -mmodel=medium
+@opindex mmodel=medium
Assume objects may be anywhere in the 32-bit address space (the compiler
will generate @code{seth/add3} instructions to load their addresses), and
assume all subroutines are reachable with the @code{bl} instruction.
-@item -mcode-model=large
-@opindex mcode-model=large
+@item -mmodel=large
+@opindex mmodel=large
Assume objects may be anywhere in the 32-bit address space (the compiler
will generate @code{seth/add3} instructions to load their addresses), and
assume subroutines may not be reachable with the @code{bl} instruction
@@ -6408,237 +6903,51 @@ Compiling with different values of @var{num} may or may not work; if it
doesn't the linker will give an error message---incorrect code will not be
generated.
-@end table
-
-@node M88K Options
-@subsection M88K Options
-@cindex M88k options
-
-These @samp{-m} options are defined for Motorola 88k architectures:
-
-@table @gcctabopt
-@item -m88000
-@opindex m88000
-Generate code that works well on both the m88100 and the
-m88110.
-
-@item -m88100
-@opindex m88100
-Generate code that works best for the m88100, but that also
-runs on the m88110.
-
-@item -m88110
-@opindex m88110
-Generate code that works best for the m88110, and may not run
-on the m88100.
-
-@item -mbig-pic
-@opindex mbig-pic
-Obsolete option to be removed from the next revision.
-Use @option{-fPIC}.
-
-@item -midentify-revision
-@opindex midentify-revision
-@cindex identifying source, compiler (88k)
-Include an @code{ident} directive in the assembler output recording the
-source file name, compiler name and version, timestamp, and compilation
-flags used.
-
-@item -mno-underscores
-@opindex mno-underscores
-@cindex underscores, avoiding (88k)
-In assembler output, emit symbol names without adding an underscore
-character at the beginning of each name. The default is to use an
-underscore as prefix on each name.
-
-@item -mocs-debug-info
-@itemx -mno-ocs-debug-info
-@opindex mocs-debug-info
-@opindex mno-ocs-debug-info
-@cindex OCS (88k)
-@cindex debugging, 88k OCS
-Include (or omit) additional debugging information (about registers used
-in each stack frame) as specified in the 88open Object Compatibility
-Standard, ``OCS''@. This extra information allows debugging of code that
-has had the frame pointer eliminated. The default for SVr4 and Delta 88
-SVr3.2 is to include this information; other 88k configurations omit this
-information by default.
-
-@item -mocs-frame-position
-@opindex mocs-frame-position
-@cindex register positions in frame (88k)
-When emitting COFF debugging information for automatic variables and
-parameters stored on the stack, use the offset from the canonical frame
-address, which is the stack pointer (register 31) on entry to the
-function. The SVr4 and Delta88 SVr3.2, and BCS configurations use
-@option{-mocs-frame-position}; other 88k configurations have the default
-@option{-mno-ocs-frame-position}.
-
-@item -mno-ocs-frame-position
-@opindex mno-ocs-frame-position
-@cindex register positions in frame (88k)
-When emitting COFF debugging information for automatic variables and
-parameters stored on the stack, use the offset from the frame pointer
-register (register 30). When this option is in effect, the frame
-pointer is not eliminated when debugging information is selected by the
--g switch.
-
-@item -moptimize-arg-area
-@opindex moptimize-arg-area
-@cindex arguments in frame (88k)
-Save space by reorganizing the stack frame. This option generates code
-that does not agree with the 88open specifications, but uses less
-memory.
-
-@itemx -mno-optimize-arg-area
-@opindex mno-optimize-arg-area
-Do not reorganize the stack frame to save space. This is the default.
-The generated conforms to the specification, but uses more memory.
-
-@item -mshort-data-@var{num}
-@opindex mshort-data
-@cindex smaller data references (88k)
-@cindex r0-relative references (88k)
-Generate smaller data references by making them relative to @code{r0},
-which allows loading a value using a single instruction (rather than the
-usual two). You control which data references are affected by
-specifying @var{num} with this option. For example, if you specify
-@option{-mshort-data-512}, then the data references affected are those
-involving displacements of less than 512 bytes.
-@option{-mshort-data-@var{num}} is not effective for @var{num} greater
-than 64k.
-
-@item -mserialize-volatile
-@opindex mserialize-volatile
-@itemx -mno-serialize-volatile
-@opindex mno-serialize-volatile
-@cindex sequential consistency on 88k
-Do, or don't, generate code to guarantee sequential consistency
-of volatile memory references. By default, consistency is
-guaranteed.
-
-The order of memory references made by the MC88110 processor does
-not always match the order of the instructions requesting those
-references. In particular, a load instruction may execute before
-a preceding store instruction. Such reordering violates
-sequential consistency of volatile memory references, when there
-are multiple processors. When consistency must be guaranteed,
-GCC generates special instructions, as needed, to force
-execution in the proper order.
-
-The MC88100 processor does not reorder memory references and so
-always provides sequential consistency. However, by default, GCC
-generates the special instructions to guarantee consistency
-even when you use @option{-m88100}, so that the code may be run on an
-MC88110 processor. If you intend to run your code only on the
-MC88100 processor, you may use @option{-mno-serialize-volatile}.
-
-The extra code generated to guarantee consistency may affect the
-performance of your application. If you know that you can safely
-forgo this guarantee, you may use @option{-mno-serialize-volatile}.
-
-@item -msvr4
-@itemx -msvr3
-@opindex msvr4
-@opindex msvr3
-@cindex assembler syntax, 88k
-@cindex SVr4
-Turn on (@option{-msvr4}) or off (@option{-msvr3}) compiler extensions
-related to System V release 4 (SVr4). This controls the following:
-
-@enumerate
-@item
-Which variant of the assembler syntax to emit.
-@item
-@option{-msvr4} makes the C preprocessor recognize @samp{#pragma weak}
-that is used on System V release 4.
-@item
-@option{-msvr4} makes GCC issue additional declaration directives used in
-SVr4.
-@end enumerate
-
-@option{-msvr4} is the default for the m88k-motorola-sysv4 configuration.
-@option{-msvr3} is the default for all other m88k configurations.
-
-@item -mversion-03.00
-@opindex mversion-03.00
-This option is obsolete, and is ignored.
-@c ??? which asm syntax better for GAS? option there too?
-
-@item -mno-check-zero-division
-@itemx -mcheck-zero-division
-@opindex mno-check-zero-division
-@opindex mcheck-zero-division
-@cindex zero division on 88k
-Do, or don't, generate code to guarantee that integer division by
-zero will be detected. By default, detection is guaranteed.
-
-Some models of the MC88100 processor fail to trap upon integer
-division by zero under certain conditions. By default, when
-compiling code that might be run on such a processor, GCC
-generates code that explicitly checks for zero-valued divisors
-and traps with exception number 503 when one is detected. Use of
-@option{-mno-check-zero-division} suppresses such checking for code
-generated to run on an MC88100 processor.
-
-GCC assumes that the MC88110 processor correctly detects all instances
-of integer division by zero. When @option{-m88110} is specified, no
-explicit checks for zero-valued divisors are generated, and both
-@option{-mcheck-zero-division} and @option{-mno-check-zero-division} are
-ignored.
+@item -mdebug
+@opindex mdebug
+Makes the M32R specific code in the compiler display some statistics
+that might help in debugging programs.
+
+@item -malign-loops
+@opindex malign-loops
+Align all loops to a 32-byte boundary.
+
+@item -mno-align-loops
+@opindex mno-align-loops
+Do not enforce a 32-byte alignment for loops. This is the default.
+
+@item -missue-rate=@var{number}
+@opindex missue-rate=@var{number}
+Issue @var{number} instructions per cycle. @var{number} can only be 1
+or 2.
+
+@item -mbranch-cost=@var{number}
+@opindex mbranch-cost=@var{number}
+@var{number} can only be 1 or 2. If it is 1 then branches will be
+preferred over conditional code, if it is 2, then the opposite will
+apply.
+
+@item -mflush-trap=@var{number}
+@opindex mflush-trap=@var{number}
+Specifies the trap number to use to flush the cache. The default is
+12. Valid numbers are between 0 and 15 inclusive.
+
+@item -mno-flush-trap
+@opindex mno-flush-trap
+Specifies that the cache cannot be flushed by using a trap.
+
+@item -mflush-func=@var{name}
+@opindex mflush-func=@var{name}
+Specifies the name of the operating system function to call to flush
+the cache. The default is @emph{_flush_cache}, but a function call
+will only be used if a trap is not available.
+
+@item -mno-flush-func
+@opindex mno-flush-func
+Indicates that there is no OS function for flushing the cache.
-@item -muse-div-instruction
-@opindex muse-div-instruction
-@cindex divide instruction, 88k
-Use the div instruction for signed integer division on the
-MC88100 processor. By default, the div instruction is not used.
-
-On the MC88100 processor the signed integer division instruction
-div) traps to the operating system on a negative operand. The
-operating system transparently completes the operation, but at a
-large cost in execution time. By default, when compiling code
-that might be run on an MC88100 processor, GCC emulates signed
-integer division using the unsigned integer division instruction
-divu), thereby avoiding the large penalty of a trap to the
-operating system. Such emulation has its own, smaller, execution
-cost in both time and space. To the extent that your code's
-important signed integer division operations are performed on two
-nonnegative operands, it may be desirable to use the div
-instruction directly.
-
-On the MC88110 processor the div instruction (also known as the
-divs instruction) processes negative operands without trapping to
-the operating system. When @option{-m88110} is specified,
-@option{-muse-div-instruction} is ignored, and the div instruction is used
-for signed integer division.
-
-Note that the result of dividing @code{INT_MIN} by @minus{}1 is undefined. In
-particular, the behavior of such a division with and without
-@option{-muse-div-instruction} may differ.
-
-@item -mtrap-large-shift
-@itemx -mhandle-large-shift
-@opindex mtrap-large-shift
-@opindex mhandle-large-shift
-@cindex bit shift overflow (88k)
-@cindex large bit shifts (88k)
-Include code to detect bit-shifts of more than 31 bits; respectively,
-trap such shifts or emit code to handle them properly. By default GCC
-makes no special provision for large bit shifts.
-
-@item -mwarn-passed-structs
-@opindex mwarn-passed-structs
-@cindex structure passing (88k)
-Warn when a function passes a struct as an argument or result.
-Structure-passing conventions have changed during the evolution of the C
-language, and are often the source of portability problems. By default,
-GCC issues no such warning.
@end table
-@c break page here to avoid unsightly interparagraph stretch.
-@c -zw, 2001-8-17
-@page
-
@node RS/6000 and PowerPC Options
@subsection IBM RS/6000 and PowerPC Options
@cindex RS/6000 and PowerPC Options
@@ -6736,12 +7045,15 @@ should normally not specify either @option{-mnew-mnemonics} or
@opindex mcpu
Set architecture type, register usage, choice of mnemonics, and
instruction scheduling parameters for machine type @var{cpu_type}.
-Supported values for @var{cpu_type} are @samp{rios}, @samp{rios1},
-@samp{rsc}, @samp{rios2}, @samp{rs64a}, @samp{601}, @samp{602},
-@samp{603}, @samp{603e}, @samp{604}, @samp{604e}, @samp{620},
-@samp{630}, @samp{740}, @samp{7400}, @samp{7450}, @samp{750},
-@samp{power}, @samp{power2}, @samp{powerpc}, @samp{403}, @samp{505},
-@samp{801}, @samp{821}, @samp{823}, and @samp{860} and @samp{common}.
+Supported values for @var{cpu_type} are @samp{401}, @samp{403},
+@samp{405}, @samp{405fp}, @samp{440}, @samp{440fp}, @samp{505},
+@samp{601}, @samp{602}, @samp{603}, @samp{603e}, @samp{604},
+@samp{604e}, @samp{620}, @samp{630}, @samp{740}, @samp{7400},
+@samp{7450}, @samp{750}, @samp{801}, @samp{821}, @samp{823},
+@samp{860}, @samp{970}, @samp{common}, @samp{ec603e}, @samp{G3},
+@samp{G4}, @samp{G5}, @samp{power}, @samp{power2}, @samp{power3},
+@samp{power4}, @samp{power5}, @samp{powerpc}, @samp{powerpc64},
+@samp{rios}, @samp{rios1}, @samp{rios2}, @samp{rsc}, and @samp{rs64a}.
@option{-mcpu=common} selects a completely generic processor. Code
generated under this option will run on any POWER or PowerPC processor.
@@ -6759,43 +7071,23 @@ The other options specify a specific processor. Code generated under
those options will run best on that processor, and may not run at all on
others.
-The @option{-mcpu} options automatically enable or disable other
-@option{-m} options as follows:
-
-@table @samp
-@item common
-@option{-mno-power}, @option{-mno-powerpc}
-
-@item power
-@itemx power2
-@itemx rios1
-@itemx rios2
-@itemx rsc
-@option{-mpower}, @option{-mno-powerpc}, @option{-mno-new-mnemonics}
-
-@item powerpc
-@itemx rs64a
-@itemx 602
-@itemx 603
-@itemx 603e
-@itemx 604
-@itemx 620
-@itemx 630
-@itemx 740
-@itemx 7400
-@itemx 7450
-@itemx 750
-@itemx 505
-@option{-mno-power}, @option{-mpowerpc}, @option{-mnew-mnemonics}
-
-@item 601
-@option{-mpower}, @option{-mpowerpc}, @option{-mnew-mnemonics}
-
-@item 403
-@itemx 821
-@itemx 860
-@option{-mno-power}, @option{-mpowerpc}, @option{-mnew-mnemonics}, @option{-msoft-float}
-@end table
+The @option{-mcpu} options automatically enable or disable the
+following options: @option{-maltivec}, @option{-mhard-float},
+@option{-mmfcrf}, @option{-mmultiple}, @option{-mnew-mnemonics},
+@option{-mpower}, @option{-mpower2}, @option{-mpowerpc64},
+@option{-mpowerpc-gpopt}, @option{-mpowerpc-gfxopt},
+@option{-mstring}. The particular options set for any particular CPU
+will vary between compiler versions, depending on what setting seems
+to produce optimal code for that CPU; it doesn't necessarily reflect
+the actual hardware's capabilities. If you wish to set an individual
+option to a particular value, you may specify it after the
+@option{-mcpu} option, like @samp{-mcpu=970 -mno-altivec}.
+
+On AIX, the @option{-maltivec} and @option{-mpowerpc64} options are
+not enabled or disabled by the @option{-mcpu} option at present, since
+AIX does not have full support for these options. You may still
+enable or disable them individually if you're sure it'll work in your
+environment.
@item -mtune=@var{cpu_type}
@opindex mtune
@@ -6831,6 +7123,19 @@ Disable Booke SPE ABI extensions for the current ABI.
@opindex misel
This switch enables or disables the generation of ISEL instructions.
+@item -mspe=@var{yes/no}
+@itemx -mspe
+@opindex mspe
+This switch enables or disables the generation of SPE simd
+instructions.
+
+@item -mfloat-gprs=@var{yes/no}
+@itemx -mfloat-gprs
+@opindex mfloat-gprs
+This switch enables or disables the generation of floating point
+operations on the general purpose registers for architectures that
+support it. This option is currently only available on the MPC8540.
+
@item -mfull-toc
@itemx -mno-fp-in-toc
@itemx -mno-sum-in-toc
@@ -6900,6 +7205,16 @@ appropriate directory location. The Parallel Environment does not
support threads, so the @option{-mpe} option and the @option{-pthread}
option are incompatible.
+@item -malign-natural
+@itemx -malign-power
+@opindex malign-natural
+@opindex malign-power
+On AIX, Darwin, and 64-bit PowerPC GNU/Linux, the option
+@option{-malign-natural} overrides the ABI-defined alignment of larger
+types, such as floating-point doubles, on their natural size-based boundary.
+The option @option{-malign-power} instructs GCC to follow the ABI-specified
+alignment rules. GCC defaults to the standard alignment defined in the ABI.
+
@item -msoft-float
@itemx -mhard-float
@opindex msoft-float
@@ -7017,6 +7332,46 @@ On System V.4 and embedded PowerPC systems compile code for the
processor in big endian mode. The @option{-mbig-endian} option is
the same as @option{-mbig}.
+@item -mdynamic-no-pic
+@opindex mdynamic-no-pic
+On Darwin and Mac OS X systems, compile code so that it is not
+relocatable, but that its external references are relocatable. The
+resulting code is suitable for applications, but not shared
+libraries.
+
+@item -mprioritize-restricted-insns=@var{priority}
+@opindex mprioritize-restricted-insns
+This option controls the priority that is assigned to
+dispatch-slot restricted instructions during the second scheduling
+pass. The argument @var{priority} takes the value @var{0/1/2} to assign
+@var{no/highest/second-highest} priority to dispatch slot restricted
+instructions.
+
+@item -msched-costly-dep=@var{dependence_type}
+@opindex msched-costly-dep
+This option controls which dependences are considered costly
+by the target during instruction scheduling. The argument
+@var{dependence_type} takes one of the following values:
+@var{no}: no dependence is costly,
+@var{all}: all dependences are costly,
+@var{true_store_to_load}: a true dependence from store to load is costly,
+@var{store_to_load}: any dependence from store to load is costly,
+@var{number}: any dependence which latency >= @var{number} is costly.
+
+@item -minsert-sched-nops=@var{scheme}
+@opindex minsert-sched-nops
+This option controls which nop insertion scheme will be used during
+the second scheduling pass. The argument @var{scheme} takes one of the
+following values:
+@var{no}: Don't insert nops.
+@var{pad}: Pad with nops any dispatch group which has vacant issue slots,
+according to the scheduler's grouping.
+@var{regroup_exact}: Insert nops to force costly dependent insns into
+separate groups. Insert exactly as many nops as needed to force an insn
+to a new group, according to the estimated processor grouping.
+@var{number}: Insert nops to force costly dependent insns into
+separate groups. Insert @var{number} nops to force an insn to a new group.
+
@item -mcall-sysv
@opindex mcall-sysv
On System V.4 and embedded PowerPC systems compile code using calling
@@ -7032,12 +7387,6 @@ Specify both @option{-mcall-sysv} and @option{-meabi} options.
@opindex mcall-sysv-noeabi
Specify both @option{-mcall-sysv} and @option{-mno-eabi} options.
-@item -mcall-aix
-@opindex mcall-aix
-On System V.4 and embedded PowerPC systems compile code using calling
-conventions that are similar to those used on AIX@. This is the
-default if you configured GCC using @samp{powerpc-*-eabiaix}.
-
@item -mcall-solaris
@opindex mcall-solaris
On System V.4 and embedded PowerPC systems compile code for the Solaris
@@ -7223,6 +7572,10 @@ generate slower code. As of this writing, the AIX linker can do this,
as can the GNU linker for PowerPC/64. It is planned to add this feature
to the GNU linker for 32-bit PowerPC systems as well.
+On Mach-O (Darwin) systems, this option directs the compiler emit to
+the glue for every direct call, and the Darwin linker decides whether
+to use or discard it.
+
In the future, we may cause GCC to ignore all longcall specifications
when the linker is known to generate glue.
@@ -7241,8 +7594,8 @@ These options are defined for all architectures running the Darwin operating
system. They are useful for compatibility with other Mac OS compilers.
@table @gcctabopt
-@item -all_load
-@opindex all_load
+@item -all_load
+@opindex all_load
Loads all members of static archive libraries.
See man ld(1) for more information.
@@ -7256,7 +7609,7 @@ to be fatal.
Causes the output file to be marked such that the dynamic linker will
bind all undefined references when the file is loaded or launched.
-@item -bundle
+@item -bundle
@opindex bundle
Produce a Mach-o bundle format file.
See man ld(1) for more information.
@@ -7267,64 +7620,65 @@ This specifies the @var{executable} that will be loading the build
output file being linked. See man ld(1) for more information.
@item -allowable_client @var{client_name}
-@item -arch_only
-
-@item -client_name
-@item -compatibility_version
-@item -current_version
-@item -dependency-file
-@item -dylib_file
-@item -dylinker_install_name
-@item -dynamic
-@item -dynamiclib
-@item -exported_symbols_list
-@item -filelist
-@item -flat_namespace
-@item -force_cpusubtype_ALL
-@item -force_flat_namespace
-@item -headerpad_max_install_names
-@item -image_base
-@item -init
-@item -install_name
-@item -keep_private_externs
-@item -multi_module
-@item -multiply_defined
-@item -multiply_defined_unused
-@item -noall_load
-@item -nomultidefs
-@item -noprebind
-@item -noseglinkedit
-@item -pagezero_size
-@item -prebind
-@item -prebind_all_twolevel_modules
-@item -private_bundle
-@item -read_only_relocs
-@item -sectalign
-@item -sectobjectsymbols
-@item -whyload
-@item -seg1addr
-@item -sectcreate
-@item -sectobjectsymbols
-@item -sectorder
-@item -seg_addr_table
-@item -seg_addr_table_filename
-@item -seglinkedit
-@item -segprot
-@item -segs_read_only_addr
-@item -segs_read_write_addr
-@item -single_module
-@item -static
-@item -sub_library
-@item -sub_umbrella
-@item -twolevel_namespace
-@item -umbrella
-@item -undefined
-@item -unexported_symbols_list
-@item -weak_reference_mismatches
-@item -whatsloaded
+@itemx -arch_only
+
+@itemx -client_name
+@itemx -compatibility_version
+@itemx -current_version
+@itemx -dependency-file
+@itemx -dylib_file
+@itemx -dylinker_install_name
+@itemx -dynamic
+@itemx -dynamiclib
+@itemx -exported_symbols_list
+@itemx -filelist
+@itemx -flat_namespace
+@itemx -force_cpusubtype_ALL
+@itemx -force_flat_namespace
+@itemx -headerpad_max_install_names
+@itemx -image_base
+@itemx -init
+@itemx -install_name
+@itemx -keep_private_externs
+@itemx -multi_module
+@itemx -multiply_defined
+@itemx -multiply_defined_unused
+@itemx -noall_load
+@itemx -nofixprebinding
+@itemx -nomultidefs
+@itemx -noprebind
+@itemx -noseglinkedit
+@itemx -pagezero_size
+@itemx -prebind
+@itemx -prebind_all_twolevel_modules
+@itemx -private_bundle
+@itemx -read_only_relocs
+@itemx -sectalign
+@itemx -sectobjectsymbols
+@itemx -whyload
+@itemx -seg1addr
+@itemx -sectcreate
+@itemx -sectobjectsymbols
+@itemx -sectorder
+@itemx -seg_addr_table
+@itemx -seg_addr_table_filename
+@itemx -seglinkedit
+@itemx -segprot
+@itemx -segs_read_only_addr
+@itemx -segs_read_write_addr
+@itemx -single_module
+@itemx -static
+@itemx -sub_library
+@itemx -sub_umbrella
+@itemx -twolevel_namespace
+@itemx -umbrella
+@itemx -undefined
+@itemx -unexported_symbols_list
+@itemx -weak_reference_mismatches
+@itemx -whatsloaded
@opindex allowable_client
-@opindex arch_only
+@opindex arch_only
@opindex client_name
@opindex compatibility_version
@opindex current_version
@@ -7334,34 +7688,35 @@ output file being linked. See man ld(1) for more information.
@opindex dynamic
@opindex dynamiclib
@opindex exported_symbols_list
-@opindex filelist
-@opindex flat_namespace
+@opindex filelist
+@opindex flat_namespace
@opindex force_cpusubtype_ALL
@opindex force_flat_namespace
@opindex headerpad_max_install_names
@opindex image_base
-@opindex init
+@opindex init
@opindex install_name
@opindex keep_private_externs
-@opindex multi_module
+@opindex multi_module
@opindex multiply_defined
-@opindex multiply_defined_unused
-@opindex noall_load
-@opindex nomultidefs
+@opindex multiply_defined_unused
+@opindex noall_load
+@opindex nofixprebinding
+@opindex nomultidefs
@opindex noprebind
-@opindex noseglinkedit
+@opindex noseglinkedit
@opindex pagezero_size
@opindex prebind
@opindex prebind_all_twolevel_modules
-@opindex private_bundle
+@opindex private_bundle
@opindex read_only_relocs
-@opindex sectalign
-@opindex sectobjectsymbols
-@opindex whyload
+@opindex sectalign
+@opindex sectobjectsymbols
+@opindex whyload
@opindex seg1addr
-@opindex sectcreate
-@opindex sectobjectsymbols
-@opindex sectorder
+@opindex sectcreate
+@opindex sectobjectsymbols
+@opindex sectorder
@opindex seg_addr_table
@opindex seg_addr_table_filename
@opindex seglinkedit
@@ -7379,85 +7734,44 @@ output file being linked. See man ld(1) for more information.
@opindex weak_reference_mismatches
@opindex whatsloaded
-This options are available for Darwin linker. Darwin linker man page
+These options are available for Darwin linker. Darwin linker man page
describes them in detail.
@end table
-@node RT Options
-@subsection IBM RT Options
-@cindex RT options
-@cindex IBM RT options
-
-These @samp{-m} options are defined for the IBM RT PC:
-
-@table @gcctabopt
-@item -min-line-mul
-@opindex min-line-mul
-Use an in-line code sequence for integer multiplies. This is the
-default.
-
-@item -mcall-lib-mul
-@opindex mcall-lib-mul
-Call @code{lmul$$} for integer multiples.
-
-@item -mfull-fp-blocks
-@opindex mfull-fp-blocks
-Generate full-size floating point data blocks, including the minimum
-amount of scratch space recommended by IBM@. This is the default.
-
-@item -mminimum-fp-blocks
-@opindex mminimum-fp-blocks
-Do not include extra scratch space in floating point data blocks. This
-results in smaller code, but slower execution, since scratch space must
-be allocated dynamically.
-
-@cindex @file{stdarg.h} and RT PC
-@item -mfp-arg-in-fpregs
-@opindex mfp-arg-in-fpregs
-Use a calling sequence incompatible with the IBM calling convention in
-which floating point arguments are passed in floating point registers.
-Note that @code{stdarg.h} will not work with floating point operands
-if this option is specified.
-
-@item -mfp-arg-in-gregs
-@opindex mfp-arg-in-gregs
-Use the normal calling convention for floating point arguments. This is
-the default.
-
-@item -mhc-struct-return
-@opindex mhc-struct-return
-Return structures of more than one word in memory, rather than in a
-register. This provides compatibility with the MetaWare HighC (hc)
-compiler. Use the option @option{-fpcc-struct-return} for compatibility
-with the Portable C Compiler (pcc).
-
-@item -mnohc-struct-return
-@opindex mnohc-struct-return
-Return some structures of more than one word in registers, when
-convenient. This is the default. For compatibility with the
-IBM-supplied compilers, use the option @option{-fpcc-struct-return} or the
-option @option{-mhc-struct-return}.
-@end table
-
@node MIPS Options
@subsection MIPS Options
@cindex MIPS options
-These @samp{-m} options are defined for the MIPS family of computers:
-
@table @gcctabopt
+@item -EB
+@opindex EB
+Generate big-endian code.
+
+@item -EL
+@opindex EL
+Generate little-endian code. This is the default for @samp{mips*el-*-*}
+configurations.
+
@item -march=@var{arch}
@opindex march
Generate code that will run on @var{arch}, which can be the name of a
-generic MIPS ISA, or the name of a particular processor. The ISA names
-are: @samp{mips1}, @samp{mips2}, @samp{mips3}, @samp{mips4}, @samp{mips32}
-and @samp{mips64}. The processor names are: @samp{r2000},
-@samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{vr4100}, @samp{vr4300},
-@samp{r4400}, @samp{r4600}, @samp{r4650}, @samp{vr5000}, @samp{r6000},
-@samp{r8000}, @samp{4kc}, @samp{4kp}, @samp{5kc}, @samp{20kc},
-@samp{orion}, and @samp{sb1}. The special value @samp{from-abi} selects the
+generic MIPS ISA, or the name of a particular processor.
+The ISA names are:
+@samp{mips1}, @samp{mips2}, @samp{mips3}, @samp{mips4},
+@samp{mips32}, @samp{mips32r2}, and @samp{mips64}.
+The processor names are:
+@samp{4kc}, @samp{4kp}, @samp{5kc}, @samp{20kc},
+@samp{m4k},
+@samp{r2000}, @samp{r3000}, @samp{r3900}, @samp{r4000}, @samp{r4400},
+@samp{r4600}, @samp{r4650}, @samp{r6000}, @samp{r8000}, @samp{rm7000},
+@samp{rm9000},
+@samp{orion},
+@samp{sb1},
+@samp{vr4100}, @samp{vr4111}, @samp{vr4120}, @samp{vr4300},
+@samp{vr5000}, @samp{vr5400} and @samp{vr5500}.
+The special value @samp{from-abi} selects the
most compatible architecture for the selected ABI (that is,
@samp{mips1} for 32-bit ABIs and @samp{mips3} for 64-bit ABIs)@.
@@ -7516,289 +7830,268 @@ Equivalent to @samp{-march=mips4}.
@opindex mips32
Equivalent to @samp{-march=mips32}.
+@item -mips32r2
+@opindex mips32r2
+Equivalent to @samp{-march=mips32r2}.
+
@item -mips64
@opindex mips64
Equivalent to @samp{-march=mips64}.
-@item -mfused-madd
-@itemx -mno-fused-madd
-@opindex mfused-madd
-@opindex mno-fused-madd
-Generate code that uses (does not use) the floating point multiply and
-accumulate instructions, when they are available. These instructions
-are generated by default if they are available, but this may be
-undesirable if the extra precision causes problems or on certain chips
-in the mode where denormals are rounded to zero where denormals
-generated by multiply and accumulate instructions cause exceptions
-anyway.
+@item -mips16
+@itemx -mno-mips16
+@opindex mips16
+@opindex mno-mips16
+Use (do not use) the MIPS16 ISA.
-@item -mfp32
-@opindex mfp32
-Assume that floating point registers are 32 bits wide.
+@item -mabi=32
+@itemx -mabi=o64
+@itemx -mabi=n32
+@itemx -mabi=64
+@itemx -mabi=eabi
+@opindex mabi=32
+@opindex mabi=o64
+@opindex mabi=n32
+@opindex mabi=64
+@opindex mabi=eabi
+Generate code for the given ABI@.
-@item -mfp64
-@opindex mfp64
-Assume that floating point registers are 64 bits wide.
+Note that the EABI has a 32-bit and a 64-bit variant. GCC normally
+generates 64-bit code when you select a 64-bit architecture, but you
+can use @option{-mgp32} to get 32-bit code instead.
+
+@item -mabicalls
+@itemx -mno-abicalls
+@opindex mabicalls
+@opindex mno-abicalls
+Generate (do not generate) SVR4-style position-independent code.
+@option{-mabicalls} is the default for SVR4-based systems.
+
+@item -mxgot
+@itemx -mno-xgot
+@opindex mxgot
+@opindex mno-xgot
+Lift (do not lift) the usual restrictions on the size of the global
+offset table.
+
+GCC normally uses a single instruction to load values from the GOT.
+While this is relatively efficient, it will only work if the GOT
+is smaller than about 64k. Anything larger will cause the linker
+to report an error such as:
+
+@cindex relocation truncated to fit (MIPS)
+@smallexample
+relocation truncated to fit: R_MIPS_GOT16 foobar
+@end smallexample
+
+If this happens, you should recompile your code with @option{-mxgot}.
+It should then work with very large GOTs, although it will also be
+less efficient, since it will take three instructions to fetch the
+value of a global symbol.
+
+Note that some linkers can create multiple GOTs. If you have such a
+linker, you should only need to use @option{-mxgot} when a single object
+file accesses more than 64k's worth of GOT entries. Very few do.
+
+These options have no effect unless GCC is generating position
+independent code.
+
+@item -membedded-pic
+@itemx -mno-embedded-pic
+@opindex membedded-pic
+@opindex mno-embedded-pic
+Generate (do not generate) position-independent code suitable for some
+embedded systems. All calls are made using PC relative addresses, and
+all data is addressed using the $gp register. No more than 65536
+bytes of global data may be used. This requires GNU as and GNU ld,
+which do most of the work.
@item -mgp32
@opindex mgp32
-Assume that general purpose registers are 32 bits wide.
+Assume that general-purpose registers are 32 bits wide.
@item -mgp64
@opindex mgp64
-Assume that general purpose registers are 64 bits wide.
+Assume that general-purpose registers are 64 bits wide.
+
+@item -mfp32
+@opindex mfp32
+Assume that floating-point registers are 32 bits wide.
+
+@item -mfp64
+@opindex mfp64
+Assume that floating-point registers are 64 bits wide.
+
+@item -mhard-float
+@opindex mhard-float
+Use floating-point coprocessor instructions.
+
+@item -msoft-float
+@opindex msoft-float
+Do not use floating-point coprocessor instructions. Implement
+floating-point calculations using library calls instead.
+
+@item -msingle-float
+@opindex msingle-float
+Assume that the floating-point coprocessor only supports single-precision
+operations.
+
+@itemx -mdouble-float
+@opindex mdouble-float
+Assume that the floating-point coprocessor supports double-precision
+operations. This is the default.
@item -mint64
@opindex mint64
-Force int and long types to be 64 bits wide. See @option{-mlong32} for an
-explanation of the default, and the width of pointers.
+Force @code{int} and @code{long} types to be 64 bits wide. See
+@option{-mlong32} for an explanation of the default and the way
+that the pointer size is determined.
@item -mlong64
@opindex mlong64
-Force long types to be 64 bits wide. See @option{-mlong32} for an
-explanation of the default, and the width of pointers.
+Force @code{long} types to be 64 bits wide. See @option{-mlong32} for
+an explanation of the default and the way that the pointer size is
+determined.
@item -mlong32
@opindex mlong32
-Force long, int, and pointer types to be 32 bits wide.
+Force @code{long}, @code{int}, and pointer types to be 32 bits wide.
-The default size of ints, longs and pointers depends on the ABI@. All
-the supported ABIs use 32-bit ints. The n64 ABI uses 64-bit longs, as
-does the 64-bit Cygnus EABI; the others use 32-bit longs. Pointers
-are the same size as longs, or the same size as integer registers,
-whichever is smaller.
+The default size of @code{int}s, @code{long}s and pointers depends on
+the ABI@. All the supported ABIs use 32-bit @code{int}s. The n64 ABI
+uses 64-bit @code{long}s, as does the 64-bit EABI; the others use
+32-bit @code{long}s. Pointers are the same size as @code{long}s,
+or the same size as integer registers, whichever is smaller.
-@item -mabi=32
-@itemx -mabi=o64
-@itemx -mabi=n32
-@itemx -mabi=64
-@itemx -mabi=eabi
-@itemx -mabi=meabi
-@opindex mabi=32
-@opindex mabi=o64
-@opindex mabi=n32
-@opindex mabi=64
-@opindex mabi=eabi
-@opindex mabi=meabi
-Generate code for the given ABI@.
+@item -G @var{num}
+@opindex G
+@cindex smaller data references (MIPS)
+@cindex gp-relative references (MIPS)
+Put global and static items less than or equal to @var{num} bytes into
+the small data or bss section instead of the normal data or bss section.
+This allows the data to be accessed using a single instruction.
-Note that there are two embedded ABIs: @option{-mabi=eabi}
-selects the one defined by Cygnus while @option{-meabi=meabi}
-selects the one defined by MIPS@. Both these ABIs have
-32-bit and 64-bit variants. Normally, GCC will generate
-64-bit code when you select a 64-bit architecture, but you
-can use @option{-mgp32} to get 32-bit code instead.
+All modules should be compiled with the same @option{-G @var{num}}
+value.
-@item -mmips-as
-@opindex mmips-as
-Generate code for the MIPS assembler, and invoke @file{mips-tfile} to
-add normal debug information. This is the default for all
-platforms except for the OSF/1 reference platform, using the OSF/rose
-object format. If the either of the @option{-gstabs} or @option{-gstabs+}
-switches are used, the @file{mips-tfile} program will encapsulate the
-stabs within MIPS ECOFF@.
+@item -membedded-data
+@itemx -mno-embedded-data
+@opindex membedded-data
+@opindex mno-embedded-data
+Allocate variables to the read-only data section first if possible, then
+next in the small data section if possible, otherwise in data. This gives
+slightly slower code than the default, but reduces the amount of RAM required
+when executing, and thus may be preferred for some embedded systems.
-@item -mgas
-@opindex mgas
-Generate code for the GNU assembler. This is the default on the OSF/1
-reference platform, using the OSF/rose object format. Also, this is
-the default if the configure option @option{--with-gnu-as} is used.
+@item -muninit-const-in-rodata
+@itemx -mno-uninit-const-in-rodata
+@opindex muninit-const-in-rodata
+@opindex mno-uninit-const-in-rodata
+Put uninitialized @code{const} variables in the read-only data section.
+This option is only meaningful in conjunction with @option{-membedded-data}.
@item -msplit-addresses
@itemx -mno-split-addresses
@opindex msplit-addresses
@opindex mno-split-addresses
-Generate code to load the high and low parts of address constants separately.
-This allows GCC to optimize away redundant loads of the high order
-bits of addresses. This optimization requires GNU as and GNU ld.
-This optimization is enabled by default for some embedded targets where
-GNU as and GNU ld are standard.
+Enable (disable) use of the @code{%hi()} and @code{%lo()} assembler
+relocation operators. This option has been superceded by
+@option{-mexplicit-relocs} but is retained for backwards compatibility.
+
+@item -mexplicit-relocs
+@itemx -mno-explicit-relocs
+@opindex mexplicit-relocs
+@opindex mno-explicit-relocs
+Use (do not use) assembler relocation operators when dealing with symbolic
+addresses. The alternative, selected by @option{-mno-explicit-relocs},
+is to use assembler macros instead.
+
+@option{-mexplicit-relocs} is usually the default if GCC was
+configured to use an assembler that supports relocation operators.
+However, there are two exceptions:
+
+@itemize @bullet
+@item
+GCC is not yet able to generate explicit relocations for the combination
+of @option{-mabi=64} and @option{-mno-abicalls}. This will be addressed
+in a future release.
+
+@item
+The combination of @option{-mabicalls} and @option{-fno-unit-at-a-time}
+implies @option{-mno-explicit-relocs} unless explicitly overridden.
+This is because, when generating abicalls, the choice of relocation
+depends on whether a symbol is local or global. In some rare cases,
+GCC will not be able to decide this until the whole compilation unit
+has been read.
+@end itemize
@item -mrnames
@itemx -mno-rnames
@opindex mrnames
@opindex mno-rnames
-The @option{-mrnames} switch says to output code using the MIPS software
-names for the registers, instead of the hardware names (ie, @var{a0}
-instead of @var{$4}). The only known assembler that supports this option
-is the Algorithmics assembler.
-
-@item -mgpopt
-@itemx -mno-gpopt
-@opindex mgpopt
-@opindex mno-gpopt
-The @option{-mgpopt} switch says to write all of the data declarations
-before the instructions in the text section, this allows the MIPS
-assembler to generate one word memory references instead of using two
-words for short global or static data items. This is on by default if
-optimization is selected.
-
-@item -mstats
-@itemx -mno-stats
-@opindex mstats
-@opindex mno-stats
-For each non-inline function processed, the @option{-mstats} switch
-causes the compiler to emit one line to the standard error file to
-print statistics about the program (number of registers saved, stack
-size, etc.).
+Generate (do not generate) code that refers to registers using their
+software names. The default is @option{-mno-rnames}, which tells GCC
+to use hardware names like @samp{$4} instead of software names like
+@samp{a0}. The only assembler known to support @option{-rnames} is
+the Algorithmics assembler.
+
+@item -mcheck-zero-division
+@itemx -mno-check-zero-division
+@opindex mcheck-zero-division
+@opindex mno-check-zero-division
+Trap (do not trap) on integer division by zero. The default is
+@option{-mcheck-zero-division}.
@item -mmemcpy
@itemx -mno-memcpy
@opindex mmemcpy
@opindex mno-memcpy
-The @option{-mmemcpy} switch makes all block moves call the appropriate
-string function (@samp{memcpy} or @samp{bcopy}) instead of possibly
-generating inline code.
-
-@item -mmips-tfile
-@itemx -mno-mips-tfile
-@opindex mmips-tfile
-@opindex mno-mips-tfile
-The @option{-mno-mips-tfile} switch causes the compiler not
-postprocess the object file with the @file{mips-tfile} program,
-after the MIPS assembler has generated it to add debug support. If
-@file{mips-tfile} is not run, then no local variables will be
-available to the debugger. In addition, @file{stage2} and
-@file{stage3} objects will have the temporary file names passed to the
-assembler embedded in the object file, which means the objects will
-not compare the same. The @option{-mno-mips-tfile} switch should only
-be used when there are bugs in the @file{mips-tfile} program that
-prevents compilation.
-
-@item -msoft-float
-@opindex msoft-float
-Generate output containing library calls for floating point.
-@strong{Warning:} the requisite libraries are not part of GCC@.
-Normally the facilities of the machine's usual C compiler are used, but
-this can't be done directly in cross-compilation. You must make your
-own arrangements to provide suitable library functions for
-cross-compilation.
-
-@item -mhard-float
-@opindex mhard-float
-Generate output containing floating point instructions. This is the
-default if you use the unmodified sources.
-
-@item -mabicalls
-@itemx -mno-abicalls
-@opindex mabicalls
-@opindex mno-abicalls
-Emit (or do not emit) the pseudo operations @samp{.abicalls},
-@samp{.cpload}, and @samp{.cprestore} that some System V.4 ports use for
-position independent code.
+Force (do not force) the use of @code{memcpy()} for non-trivial block
+moves. The default is @option{-mno-memcpy}, which allows GCC to inline
+most constant-sized copies.
@item -mlong-calls
@itemx -mno-long-calls
@opindex mlong-calls
@opindex mno-long-calls
-Do all calls with the @samp{JALR} instruction, which requires
-loading up a function's address into a register before the call.
-You need to use this switch, if you call outside of the current
-512 megabyte segment to functions that are not through pointers.
-
-@item -mhalf-pic
-@itemx -mno-half-pic
-@opindex mhalf-pic
-@opindex mno-half-pic
-Put pointers to extern references into the data section and load them
-up, rather than put the references in the text section.
+Disable (do not disable) use of the @code{jal} instruction. Calling
+functions using @code{jal} is more efficient but requires the caller
+and callee to be in the same 256 megabyte segment.
-@item -membedded-pic
-@itemx -mno-embedded-pic
-@opindex membedded-pic
-@opindex mno-embedded-pic
-Generate PIC code suitable for some embedded systems. All calls are
-made using PC relative address, and all data is addressed using the $gp
-register. No more than 65536 bytes of global data may be used. This
-requires GNU as and GNU ld which do most of the work. This currently
-only works on targets which use ECOFF; it does not work with ELF@.
-
-@item -membedded-data
-@itemx -mno-embedded-data
-@opindex membedded-data
-@opindex mno-embedded-data
-Allocate variables to the read-only data section first if possible, then
-next in the small data section if possible, otherwise in data. This gives
-slightly slower code than the default, but reduces the amount of RAM required
-when executing, and thus may be preferred for some embedded systems.
-
-@item -muninit-const-in-rodata
-@itemx -mno-uninit-const-in-rodata
-@opindex muninit-const-in-rodata
-@opindex mno-uninit-const-in-rodata
-When used together with @option{-membedded-data}, it will always store uninitialized
-const variables in the read-only data section.
-
-@item -msingle-float
-@itemx -mdouble-float
-@opindex msingle-float
-@opindex mdouble-float
-The @option{-msingle-float} switch tells gcc to assume that the floating
-point coprocessor only supports single precision operations, as on the
-@samp{r4650} chip. The @option{-mdouble-float} switch permits gcc to use
-double precision operations. This is the default.
+This option has no effect on abicalls code. The default is
+@option{-mno-long-calls}.
@item -mmad
@itemx -mno-mad
@opindex mmad
@opindex mno-mad
-Permit use of the @samp{mad}, @samp{madu} and @samp{mul} instructions,
-as on the @samp{r4650} chip.
-
-@item -m4650
-@opindex m4650
-Turns on @option{-msingle-float}, @option{-mmad}, and, at least for now,
-@option{-mcpu=r4650}.
-
-@item -mips16
-@itemx -mno-mips16
-@opindex mips16
-@opindex mno-mips16
-Enable 16-bit instructions.
+Enable (disable) use of the @code{mad}, @code{madu} and @code{mul}
+instructions, as provided by the R4650 ISA.
-@item -mentry
-@opindex mentry
-Use the entry and exit pseudo ops. This option can only be used with
-@option{-mips16}.
-
-@item -EL
-@opindex EL
-Compile code for the processor in little endian mode.
-The requisite libraries are assumed to exist.
-
-@item -EB
-@opindex EB
-Compile code for the processor in big endian mode.
-The requisite libraries are assumed to exist.
+@item -mfused-madd
+@itemx -mno-fused-madd
+@opindex mfused-madd
+@opindex mno-fused-madd
+Enable (disable) use of the floating point multiply-accumulate
+instructions, when they are available. The default is
+@option{-mfused-madd}.
-@item -G @var{num}
-@opindex G
-@cindex smaller data references (MIPS)
-@cindex gp-relative references (MIPS)
-Put global and static items less than or equal to @var{num} bytes into
-the small data or bss sections instead of the normal data or bss
-section. This allows the assembler to emit one word memory reference
-instructions based on the global pointer (@var{gp} or @var{$28}),
-instead of the normal two words used. By default, @var{num} is 8 when
-the MIPS assembler is used, and 0 when the GNU assembler is used. The
-@option{-G @var{num}} switch is also passed to the assembler and linker.
-All modules should be compiled with the same @option{-G @var{num}}
-value.
+When multiply-accumulate instructions are used, the intermediate
+product is calculated to infinite precision and is not subject to
+the FCSR Flush to Zero bit. This may be undesirable in some
+circumstances.
@item -nocpp
@opindex nocpp
Tell the MIPS assembler to not run its preprocessor over user
assembler files (with a @samp{.s} suffix) when assembling them.
-@item -mfix7000
-@opindex mfix7000
-Pass an option to gas which will cause nops to be inserted if
-the read of the destination register of an mfhi or mflo instruction
-occurs in the following two instructions.
-
-@item -no-crt0
-@opindex no-crt0
-Do not include the default crt0.
+@item -mfix-sb1
+@itemx -mno-fix-sb1
+@opindex mfix-sb1
+Work around certain SB-1 CPU core errata.
+(This flag currently works around the SB-1 revision 2
+``F1'' and ``F2'' floating point errata.)
@item -mflush-func=@var{func}
@itemx -mno-flush-func
@@ -7808,7 +8101,7 @@ call any such function. If called, the function must take the same
arguments as the common @code{_flush_func()}, that is, the address of the
memory range for which the cache is being flushed, the size of the
memory range, and the number 3 (to flush both caches). The default
-depends on the target gcc was configured for, but commonly is either
+depends on the target GCC was configured for, but commonly is either
@samp{_flush_func} or @samp{__cpu_flush}.
@item -mbranch-likely
@@ -7835,28 +8128,79 @@ These @samp{-m} options are defined for the i386 and x86-64 family of
computers:
@table @gcctabopt
-@item -mcpu=@var{cpu-type}
-@opindex mcpu
+@item -mtune=@var{cpu-type}
+@opindex mtune
Tune to @var{cpu-type} everything applicable about the generated code, except
for the ABI and the set of available instructions. The choices for
-@var{cpu-type} are @samp{i386}, @samp{i486}, @samp{i586}, @samp{i686},
-@samp{pentium}, @samp{pentium-mmx}, @samp{pentiumpro}, @samp{pentium2},
-@samp{pentium3}, @samp{pentium4}, @samp{k6}, @samp{k6-2}, @samp{k6-3},
-@samp{athlon}, @samp{athlon-tbird}, @samp{athlon-4}, @samp{athlon-xp},
-@samp{athlon-mp}, @samp{winchip-c6}, @samp{winchip2} and @samp{c3}.
+@var{cpu-type} are:
+@table @emph
+@item i386
+Original Intel's i386 CPU.
+@item i486
+Intel's i486 CPU. (No scheduling is implemented for this chip.)
+@item i586, pentium
+Intel Pentium CPU with no MMX support.
+@item pentium-mmx
+Intel PentiumMMX CPU based on Pentium core with MMX instruction set support.
+@item i686, pentiumpro
+Intel PentiumPro CPU.
+@item pentium2
+Intel Pentium2 CPU based on PentiumPro core with MMX instruction set support.
+@item pentium3, pentium3m
+Intel Pentium3 CPU based on PentiumPro core with MMX and SSE instruction set
+support.
+@item pentium-m
+Low power version of Intel Pentium3 CPU with MMX, SSE and SSE2 instruction set
+support. Used by Centrino notebooks.
+@item pentium4, pentium4m
+Intel Pentium4 CPU with MMX, SSE and SSE2 instruction set support.
+@item prescott
+Improved version of Intel Pentium4 CPU with MMX, SSE, SSE2 and SSE3 instruction
+set support.
+@item nocona
+Improved version of Intel Pentium4 CPU with 64-bit extensions, MMX, SSE,
+SSE2 and SSE3 instruction set support.
+@item k6
+AMD K6 CPU with MMX instruction set support.
+@item k6-2, k6-3
+Improved versions of AMD K6 CPU with MMX and 3dNOW! instruction set support.
+@item athlon, athlon-tbird
+AMD Athlon CPU with MMX, 3dNOW!, enhanced 3dNOW! and SSE prefetch instructions
+support.
+@item athlon-4, athlon-xp, athlon-mp
+Improved AMD Athlon CPU with MMX, 3dNOW!, enhanced 3dNOW! and full SSE
+instruction set support.
+@item k8, opteron, athlon64, athlon-fx
+AMD K8 core based CPUs with x86-64 instruction set support. (This supersets
+MMX, SSE, SSE2, 3dNOW!, enhanced 3dNOW! and 64-bit instruction set extensions.)
+@item winchip-c6
+IDT Winchip C6 CPU, dealt in same way as i486 with additional MMX instruction
+set support.
+@item winchip2
+IDT Winchip2 CPU, dealt in same way as i486 with additional MMX and 3dNOW!
+instruction set support.
+@item c3
+Via C3 CPU with MMX and 3dNOW! instruction set support. (No scheduling is
+implemented for this chip.)
+@item c3-2
+Via C3-2 CPU with MMX and SSE instruction set support. (No scheduling is
+implemented for this chip.)
+@end table
While picking a specific @var{cpu-type} will schedule things appropriately
for that particular chip, the compiler will not generate any code that
does not run on the i386 without the @option{-march=@var{cpu-type}} option
-being used. @samp{i586} is equivalent to @samp{pentium} and @samp{i686}
-is equivalent to @samp{pentiumpro}. @samp{k6} and @samp{athlon} are the
-AMD chips as opposed to the Intel ones.
+being used.
@item -march=@var{cpu-type}
@opindex march
Generate instructions for the machine type @var{cpu-type}. The choices
-for @var{cpu-type} are the same as for @option{-mcpu}. Moreover,
-specifying @option{-march=@var{cpu-type}} implies @option{-mcpu=@var{cpu-type}}.
+for @var{cpu-type} are the same as for @option{-mtune}. Moreover,
+specifying @option{-march=@var{cpu-type}} implies @option{-mtune=@var{cpu-type}}.
+
+@item -mcpu=@var{cpu-type}
+@opindex mcpu
+A deprecated synonym for @option{-mtune}.
@item -m386
@itemx -m486
@@ -7866,13 +8210,13 @@ specifying @option{-march=@var{cpu-type}} implies @option{-mcpu=@var{cpu-type}}.
@opindex m486
@opindex mpentium
@opindex mpentiumpro
-These options are synonyms for @option{-mcpu=i386}, @option{-mcpu=i486},
-@option{-mcpu=pentium}, and @option{-mcpu=pentiumpro} respectively.
+These options are synonyms for @option{-mtune=i386}, @option{-mtune=i486},
+@option{-mtune=pentium}, and @option{-mtune=pentiumpro} respectively.
These synonyms are deprecated.
@item -mfpmath=@var{unit}
@opindex march
-generate floating point arithmetics for selected unit @var{unit}. the choices
+Generate floating point arithmetics for selected unit @var{unit}. The choices
for @var{unit} are:
@table @samp
@@ -7898,24 +8242,17 @@ For i387 you need to use @option{-march=@var{cpu-type}}, @option{-msse} or
@option{-msse2} switches to enable SSE extensions and make this option
effective. For x86-64 compiler, these extensions are enabled by default.
-The resulting code should be considerably faster in majority of cases and avoid
+The resulting code should be considerably faster in the majority of cases and avoid
the numerical instability problems of 387 code, but may break some existing
code that expects temporaries to be 80bit.
-This is the default choice for x86-64 compiler.
-
-@item pni
-Use all SSE extensions enabled by @option{-msse2} as well as the new
-SSE extensions in Prescott New Intrunctions. @option{-mpni} also
-enables 2 builtin functions, @code{__builtin_ia32_monitor} and
-@code{__builtin_ia32_mwait}, for new intrunctions @code{monitor} and
-@code{mwait}.
+This is the default choice for the x86-64 compiler.
@item sse,387
Attempt to utilize both instruction sets at once. This effectively double the
amount of available registers and on chips with separate execution units for
387 and SSE the execution resources too. Use this option with care, as it is
-still experimental, because gcc register allocator does not model separate
+still experimental, because the GCC register allocator does not model separate
functional units well resulting in instable performance.
@end table
@@ -7985,31 +8322,31 @@ and will not be binary compatible with structures in code compiled
without that switch.
@item -m96bit-long-double
-@item -m128bit-long-double
+@itemx -m128bit-long-double
@opindex m96bit-long-double
@opindex m128bit-long-double
-These switches control the size of @code{long double} type. The i386
-application binary interface specifies the size to be 96 bits,
+These switches control the size of @code{long double} type. The i386
+application binary interface specifies the size to be 96 bits,
so @option{-m96bit-long-double} is the default in 32 bit mode.
Modern architectures (Pentium and newer) would prefer @code{long double}
-to be aligned to an 8 or 16 byte boundary. In arrays or structures
-conforming to the ABI, this would not be possible. So specifying a
+to be aligned to an 8 or 16 byte boundary. In arrays or structures
+conforming to the ABI, this would not be possible. So specifying a
@option{-m128bit-long-double} will align @code{long double}
to a 16 byte boundary by padding the @code{long double} with an additional
-32 bit zero.
+32 bit zero.
In the x86-64 compiler, @option{-m128bit-long-double} is the default choice as
its ABI specifies that @code{long double} is to be aligned on 16 byte boundary.
-
+
Notice that neither of these options enable any extra precision over the x87
-standard of 80 bits for a @code{long double}.
+standard of 80 bits for a @code{long double}.
@strong{Warning:} if you override the default value for your target ABI, the
-structures and arrays containing @code{long double} will change their size as
-well as function calling convention for function taking @code{long double}
-will be modified. Hence they will not be binary compatible with arrays or
-structures in code compiled without that switch.
+structures and arrays containing @code{long double} variables will change
+their size as well as function calling convention for function taking
+@code{long double} will be modified. Hence they will not be binary
+compatible with arrays or structures in code compiled without that switch.
@item -msvr3-shlib
@@ -8092,8 +8429,8 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@itemx -mno-sse
@item -msse2
@itemx -mno-sse2
-@item -mpni
-@itemx -mno-pni
+@item -msse3
+@itemx -mno-sse3
@item -m3dnow
@itemx -mno-3dnow
@opindex mmmx
@@ -8103,7 +8440,8 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@opindex m3dnow
@opindex mno-3dnow
These switches enable or disable the use of built-in functions that allow
-direct access to the MMX, SSE and 3Dnow extensions of the instruction set.
+direct access to the MMX, SSE, SSE2, SSE3 and 3Dnow extensions of the
+instruction set.
@xref{X86 Built-in Functions}, for details of the functions enabled
and disabled by these switches.
@@ -8140,7 +8478,7 @@ on thread-safe exception handling must compile and link all code with the
@opindex mno-align-stringops
Do not align destination of inlined string operations. This switch reduces
code size and improves performance in case the destination is already aligned,
-but gcc don't know about it.
+but GCC doesn't know about it.
@item -minline-all-stringops
@opindex minline-all-stringops
@@ -8156,6 +8494,17 @@ avoids the instructions to save, set up and restore frame pointers and
makes an extra register available in leaf functions. The option
@option{-fomit-frame-pointer} removes the frame pointer for all functions
which might make debugging harder.
+
+@item -mtls-direct-seg-refs
+@itemx -mno-tls-direct-seg-refs
+@opindex mtls-direct-seg-refs
+Controls whether TLS variables may be accessed with offsets from the
+TLS segment register (@code{%gs} for 32-bit, @code{%fs} for 64-bit),
+or whether the thread base pointer must be added. Whether or not this
+is legal depends on the operating system, and whether it maps the
+segment to cover the entire TLS area.
+
+For systems that use GNU libc, the default is on.
@end table
These @samp{-m} switches are supported in addition to the above
@@ -8334,7 +8683,7 @@ building a shared library. It is the default when GCC is configured,
explicitly or implicitly, with the GNU linker. This option does not
have any affect on which ld is called, it only changes what parameters
are passed to that ld. The ld that is called is determined by the
-@option{--with-ld} configure option, gcc's program search path, and
+@option{--with-ld} configure option, GCC's program search path, and
finally by the user's @env{PATH}. The linker used by GCC can be printed
using @samp{which `gcc -print-prog-name=ld`}.
@@ -8346,7 +8695,7 @@ links. It is the default when GCC is configured, explicitly or
implicitly, with the HP linker. This option does not have any affect on
which ld is called, it only changes what parameters are passed to that
ld. The ld that is called is determined by the @option{--with-ld}
-configure option, gcc's program search path, and finally by the user's
+configure option, GCC's program search path, and finally by the user's
@env{PATH}. The linker used by GCC can be printed using @samp{which
`gcc -print-prog-name=ld`}.
@@ -8746,6 +9095,19 @@ heap instead of in the program's data segment.
When generating code for shared libraries, @option{-fpic} implies
@option{-msmall-data} and @option{-fPIC} implies @option{-mlarge-data}.
+@item -msmall-text
+@itemx -mlarge-text
+@opindex msmall-text
+@opindex mlarge-text
+When @option{-msmall-text} is used, the compiler assumes that the
+code of the entire program (or shared library) fits in 4MB, and is
+thus reachable with a branch instruction. When @option{-msmall-data}
+is used, the compiler can assume that all local symbols share the
+same @code{$gp} value, and thus reduce the number of instructions
+required for a function call from 4 to 1.
+
+The default is @option{-mlarge-text}.
+
@item -mcpu=@var{cpu_type}
@opindex mcpu
Set the instruction set and instruction scheduling parameters for
@@ -8760,7 +9122,7 @@ Supported values for @var{cpu_type} are
@table @samp
@item ev4
-@item ev45
+@itemx ev45
@itemx 21064
Schedules as an EV4 and has no instruction set extensions.
@@ -8782,7 +9144,7 @@ Schedules as an EV5 and supports the BWX and MAX extensions.
Schedules as an EV6 and supports the BWX, FIX, and MAX extensions.
@item ev67
-@item 21264a
+@itemx 21264a
Schedules as an EV6 and supports the BWX, CIX, FIX, and MAX extensions.
@end table
@@ -8838,7 +9200,7 @@ These @samp{-m} options are defined for the H8/300 implementations:
@opindex mrelax
Shorten some address references at link time, when possible; uses the
linker option @option{-relax}. @xref{H8/300,, @code{ld} and the H8/300,
-ld.info, Using ld}, for a fuller description.
+ld, Using ld}, for a fuller description.
@item -mh
@opindex mh
@@ -8884,6 +9246,9 @@ Generate code for the SH1.
@opindex m2
Generate code for the SH2.
+@item -m2e
+Generate code for the SH2e.
+
@item -m3
@opindex m3
Generate code for the SH3.
@@ -9029,7 +9394,7 @@ parameters for machine type @var{cpu_type}. Supported values for
TMS320C40.
@item -mbig-memory
-@item -mbig
+@itemx -mbig
@itemx -msmall-memory
@itemx -msmall
@opindex mbig-memory
@@ -9238,15 +9603,21 @@ the compiler. This setting is the default.
@item -mno-app-regs
@opindex mno-app-regs
This option will cause r2 and r5 to be treated as fixed registers.
-
+
+@item -mv850e1
+@opindex mv850e1
+Specify that the target processor is the V850E1. The preprocessor
+constants @samp{__v850e1__} and @samp{__v850e__} will be defined if
+this option is used.
+
@item -mv850e
@opindex mv850e
Specify that the target processor is the V850E. The preprocessor
constant @samp{__v850e__} will be defined if this option is used.
-If neither @option{-mv850} nor @option{-mv850e} are defined
-then a default target processor will be chosen and the relevant
-@samp{__v850*__} preprocessor constant will be defined.
+If neither @option{-mv850} nor @option{-mv850e} nor @option{-mv850e1}
+are defined then a default target processor will be chosen and the
+relevant @samp{__v850*__} preprocessor constant will be defined.
The preprocessor constants @samp{__v850} and @samp{__v851__} are always
defined, regardless of which processor variant is the target.
@@ -9254,7 +9625,7 @@ defined, regardless of which processor variant is the target.
@item -mdisable-callt
@opindex mdisable-callt
This option will suppress generation of the CALLT instruction for the
-v850e flavors of the v850 architecture. The default is
+v850e and v850e1 flavors of the v850 architecture. The default is
@option{-mno-disable-callt} which allows the CALLT instruction to be used.
@end table
@@ -9582,7 +9953,7 @@ Generate code for a big endian target. This is the default for HP-UX@.
@item -mlittle-endian
@opindex mlittle-endian
Generate code for a little endian target. This is the default for AIX5
-and Linux.
+and GNU/Linux.
@item -mgnu-as
@itemx -mno-gnu-as
@@ -9674,6 +10045,14 @@ A fixed register is one that the register allocator can not use. This is
useful when compiling kernel code. A register range is specified as
two registers separated by a dash. Multiple register ranges can be
specified separated by a comma.
+
+@item -mearly-stop-bits
+@itemx -mno-early-stop-bits
+@opindex mearly-stop-bits
+@opindex mno-early-stop-bits
+Allow stop bits to be placed earlier than immediately preceding the
+instruction that triggered the stop bit. This can improve instruction
+scheduling, but does not always do so.
@end table
@node D30V Options
@@ -9743,8 +10122,9 @@ generates IEEE floating-point instructions. This is the default.
@opindex mno-backchain
Generate (or do not generate) code which maintains an explicit
backchain within the stack frame that points to the caller's frame.
-This is currently needed to allow debugging. The default is to
-generate the backchain.
+This may be needed to allow debugging using tools that do not understand
+DWARF-2 call frame information. The default is not to generate the
+backchain.
@item -msmall-exec
@itemx -mno-small-exec
@@ -9761,12 +10141,25 @@ which does not have this limitation.
@opindex m64
@opindex m31
When @option{-m31} is specified, generate code compliant to the
-Linux for S/390 ABI@. When @option{-m64} is specified, generate
-code compliant to the Linux for zSeries ABI@. This allows GCC in
+GNU/Linux for S/390 ABI@. When @option{-m64} is specified, generate
+code compliant to the GNU/Linux for zSeries ABI@. This allows GCC in
particular to generate 64-bit instructions. For the @samp{s390}
targets, the default is @option{-m31}, while the @samp{s390x}
targets default to @option{-m64}.
+@item -mzarch
+@itemx -mesa
+@opindex mzarch
+@opindex mesa
+When @option{-mzarch} is specified, generate code using the
+instructions available on z/Architecture.
+When @option{-mesa} is specified, generate code using the
+instructions available on ESA/390. Note that @option{-mesa} is
+not possible with @option{-m64}.
+When generating code compliant to the GNU/Linux for S/390 ABI,
+the default is @option{-mesa}. When generating code compliant
+to the GNU/Linux for zSeries ABI, the default is @option{-mzarch}.
+
@item -mmvcle
@itemx -mno-mvcle
@opindex mmvcle
@@ -9782,6 +10175,29 @@ use a @code{mvc} loop instead. This is the default.
Print (or do not print) additional debug information when compiling.
The default is to not print debug information.
+@item -march=@var{cpu-type}
+@opindex march
+Generate code that will run on @var{cpu-type}, which is the name of a system
+representing a certain processor type. Possible values for
+@var{cpu-type} are @samp{g5}, @samp{g6}, @samp{z900}, and @samp{z990}.
+When generating code using the instructions available on z/Architecture,
+the default is @option{-march=z900}. Otherwise, the default is
+@option{-march=g5}.
+
+@item -mtune=@var{cpu-type}
+@opindex mtune
+Tune to @var{cpu-type} everything applicable about the generated code,
+except for the ABI and the set of available instructions.
+The list of @var{cpu-type} values is the same as for @option{-march}.
+The default is the value used for @option{-march}.
+
+@item -mfused-madd
+@itemx -mno-fused-madd
+@opindex mfused-madd
+@opindex mno-fused-madd
+Generate code that uses (does not use) the floating point multiply and
+accumulate instructions. These instructions are generated by default if
+hardware floating point is used.
@end table
@node CRIS Options
@@ -9825,6 +10241,13 @@ program should be set to @var{n} bytes.
The options @option{-metrax4} and @option{-metrax100} are synonyms for
@option{-march=v3} and @option{-march=v8} respectively.
+@item -mmul-bug-workaround
+@itemx -mno-mul-bug-workaround
+@opindex mmul-bug-workaround
+@opindex mno-mul-bug-workaround
+Work around a bug in the @code{muls} and @code{mulu} instructions for CPU
+models where it applies. This option is active by default.
+
@item -mpdebug
@opindex mpdebug
Enable CRIS-specific verbose debug-related information in the assembly
@@ -10071,7 +10494,7 @@ Use 32-bit @code{int}.
Use 64-bit @code{float}. This is the default.
@item -mfloat32
-@item -mno-float64
+@itemx -mno-float64
@opindex mfloat32
@opindex mno-float64
Use 32-bit @code{float}.
@@ -10355,100 +10778,19 @@ Select the processor type for which to generate code. Possible values are
@subsection Xtensa Options
@cindex Xtensa Options
-The Xtensa architecture is designed to support many different
-configurations. The compiler's default options can be set to match a
-particular Xtensa configuration by copying a configuration file into the
-GCC sources when building GCC@. The options below may be used to
-override the default options.
+These options are supported for Xtensa targets:
@table @gcctabopt
-@item -mbig-endian
-@itemx -mlittle-endian
-@opindex mbig-endian
-@opindex mlittle-endian
-Specify big-endian or little-endian byte ordering for the target Xtensa
-processor.
-
-@item -mdensity
-@itemx -mno-density
-@opindex mdensity
-@opindex mno-density
-Enable or disable use of the optional Xtensa code density instructions.
-
-@item -mmac16
-@itemx -mno-mac16
-@opindex mmac16
-@opindex mno-mac16
-Enable or disable use of the Xtensa MAC16 option. When enabled, GCC
-will generate MAC16 instructions from standard C code, with the
-limitation that it will use neither the MR register file nor any
-instruction that operates on the MR registers. When this option is
-disabled, GCC will translate 16-bit multiply/accumulate operations to a
-combination of core instructions and library calls, depending on whether
-any other multiplier options are enabled.
-
-@item -mmul16
-@itemx -mno-mul16
-@opindex mmul16
-@opindex mno-mul16
-Enable or disable use of the 16-bit integer multiplier option. When
-enabled, the compiler will generate 16-bit multiply instructions for
-multiplications of 16 bits or smaller in standard C code. When this
-option is disabled, the compiler will either use 32-bit multiply or
-MAC16 instructions if they are available or generate library calls to
-perform the multiply operations using shifts and adds.
-
-@item -mmul32
-@itemx -mno-mul32
-@opindex mmul32
-@opindex mno-mul32
-Enable or disable use of the 32-bit integer multiplier option. When
-enabled, the compiler will generate 32-bit multiply instructions for
-multiplications of 32 bits or smaller in standard C code. When this
-option is disabled, the compiler will generate library calls to perform
-the multiply operations using either shifts and adds or 16-bit multiply
-instructions if they are available.
-
-@item -mnsa
-@itemx -mno-nsa
-@opindex mnsa
-@opindex mno-nsa
-Enable or disable use of the optional normalization shift amount
-(@code{NSA}) instructions to implement the built-in @code{ffs} function.
-
-@item -mminmax
-@itemx -mno-minmax
-@opindex mminmax
-@opindex mno-minmax
-Enable or disable use of the optional minimum and maximum value
-instructions.
-
-@item -msext
-@itemx -mno-sext
-@opindex msext
-@opindex mno-sext
-Enable or disable use of the optional sign extend (@code{SEXT})
-instruction.
-
-@item -mbooleans
-@itemx -mno-booleans
-@opindex mbooleans
-@opindex mno-booleans
-Enable or disable support for the boolean register file used by Xtensa
-coprocessors. This is not typically useful by itself but may be
-required for other options that make use of the boolean registers (e.g.,
-the floating-point option).
-
-@item -mhard-float
-@itemx -msoft-float
-@opindex mhard-float
-@opindex msoft-float
-Enable or disable use of the floating-point option. When enabled, GCC
-generates floating-point instructions for 32-bit @code{float}
-operations. When this option is disabled, GCC generates library calls
-to emulate 32-bit floating-point operations using integer instructions.
-Regardless of this option, 64-bit @code{double} operations are always
-emulated with calls to library functions.
+@item -mconst16
+@itemx -mno-const16
+@opindex mconst16
+@opindex mno-const16
+Enable or disable use of @code{CONST16} instructions for loading
+constant values. The @code{CONST16} instruction is currently not a
+standard option from Tensilica. When enabled, @code{CONST16}
+instructions are always used in place of the standard @code{L32R}
+instructions. The use of @code{CONST16} is enabled by default only if
+the @code{L32R} instruction is not available.
@item -mfused-madd
@itemx -mno-fused-madd
@@ -10467,15 +10809,6 @@ add/subtract instructions also ensures that the program output is not
sensitive to the compiler's ability to combine multiply and add/subtract
operations.
-@item -mserialize-volatile
-@itemx -mno-serialize-volatile
-@opindex mserialize-volatile
-@opindex mno-serialize-volatile
-When this option is enabled, GCC inserts @code{MEMW} instructions before
-@code{volatile} memory references to guarantee sequential consistency.
-The default is @option{-mserialize-volatile}. Use
-@option{-mno-serialize-volatile} to omit the @code{MEMW} instructions.
-
@item -mtext-section-literals
@itemx -mno-text-section-literals
@opindex mtext-section-literals
@@ -10552,6 +10885,14 @@ this option defaults to true and false respectively.
This option generates traps for signed overflow on addition, subtraction,
multiplication operations.
+@item -fwrapv
+@opindex fwrapv
+This option instructs the compiler to assume that signed arithmetic
+overflow of addition, subtraction and multiplication wraps around
+using twos-complement representation. This flag enables some optimizations
+and disables other. This option is enabled by default for the Java
+front-end, as required by the Java language specification.
+
@item -fexceptions
@opindex fexceptions
Enable exception handling. Generates extra code needed to propagate
@@ -10674,17 +11015,6 @@ program will work on other systems which always work this way.
@opindex fno-ident
Ignore the @samp{#ident} directive.
-@item -fno-gnu-linker
-@opindex fno-gnu-linker
-Do not output global initializations (such as C++ constructors and
-destructors) in the form used by the GNU linker (on systems where the GNU
-linker is the standard method of handling them). Use this option when
-you want to use a non-GNU linker, which also requires using the
-@command{collect2} program to make sure the system linker includes
-constructors and destructors. (@command{collect2} is included in the GCC
-distribution.) For systems which @emph{must} use @command{collect2}, the
-compiler driver @command{gcc} is configured to do this automatically.
-
@item -finhibit-size-directive
@opindex finhibit-size-directive
Don't output a @code{.size} assembler directive, or anything else that
@@ -10704,20 +11034,6 @@ debugging the compiler itself).
extra information to be omitted and is useful when comparing two assembler
files.
-@item -fvolatile
-@opindex fvolatile
-Consider all memory references through pointers to be volatile.
-
-@item -fvolatile-global
-@opindex fvolatile-global
-Consider all memory references to extern and global data items to
-be volatile. GCC does not consider static data items to be volatile
-because of this switch.
-
-@item -fvolatile-static
-@opindex fvolatile-static
-Consider all memory references to static data to be volatile.
-
@item -fpic
@opindex fpic
@cindex global offset table
@@ -10730,7 +11046,7 @@ loader is not part of GCC; it is part of the operating system). If
the GOT size for the linked executable exceeds a machine-specific
maximum size, you get an error message from the linker indicating that
@option{-fpic} does not work; in that case, recompile with @option{-fPIC}
-instead. (These maximums are 16k on the m88k, 8k on the SPARC, and 32k
+instead. (These maximums are 8k on the SPARC and 32k
on the m68k and RS/6000. The 386 has no such limit.)
Position-independent code requires special support, and therefore works
@@ -10742,12 +11058,21 @@ position-independent.
@opindex fPIC
If supported for the target machine, emit position-independent code,
suitable for dynamic linking and avoiding any limit on the size of the
-global offset table. This option makes a difference on the m68k, m88k,
+global offset table. This option makes a difference on the m68k
and the SPARC.
Position-independent code requires special support, and therefore works
only on certain machines.
+@item -fpie
+@itemx -fPIE
+@opindex fpie
+@opindex fPIE
+These options are similar to @option{-fpic} and @option{-fPIC}, but
+generated position independent code can be only linked into executables.
+Usually these options are used when @option{-pie} GCC option will be
+used during linking.
+
@item -ffixed-@var{reg}
@opindex ffixed
Treat the register named @var{reg} as a fixed register; generated code
@@ -10811,26 +11136,18 @@ function and its call site. (On some platforms,
function, so the call site information may not be available to the
profiling functions otherwise.)
-@example
+@smallexample
void __cyg_profile_func_enter (void *this_fn,
void *call_site);
void __cyg_profile_func_exit (void *this_fn,
void *call_site);
-@end example
+@end smallexample
The first argument is the address of the start of the current function,
which may be looked up exactly in the symbol table.
-This instrumentation is also done for functions expanded inline in other
-functions. The profiling calls will indicate where, conceptually, the
-inline function is entered and exited. This means that addressable
-versions of such functions must be available. If all your uses of a
-function are expanded inline, this may mean an additional expansion of
-code size. If you use @samp{extern inline} in your C code, an
-addressable version of such functions must be provided. (This is
-normally the case anyways, but if you get lucky and the optimizer always
-expands the functions inline, you might have gotten away without
-providing static copies.)
+This currently disables function inlining. This restriction is
+expected to be removed in future releases.
A function may be given the attribute @code{no_instrument_function}, in
which case this instrumentation will not be done. This can be used, for
@@ -10992,7 +11309,7 @@ If GCC cannot find the subprogram using the specified prefix, it
tries looking in the usual places for the subprogram.
The default value of @env{GCC_EXEC_PREFIX} is
-@file{@var{prefix}/lib/gcc-lib/} where @var{prefix} is the value
+@file{@var{prefix}/lib/gcc/} where @var{prefix} is the value
of @code{prefix} when you ran the @file{configure} script.
Other prefixes specified with @option{-B} take precedence over this prefix.
@@ -11002,7 +11319,7 @@ used for linking.
In addition, the prefix is used in an unusual way in finding the
directories to search for header files. For each of the standard
-directories whose name normally begins with @samp{/usr/local/lib/gcc-lib}
+directories whose name normally begins with @samp{/usr/local/lib/gcc}
(more precisely, with the value of @env{GCC_INCLUDE_DIR}), GCC tries
replacing that beginning with the specified prefix to produce an
alternate directory name. Thus, with @option{-Bfoo/}, GCC will search
@@ -11058,6 +11375,111 @@ preprocessor.
@c man end
+@node Precompiled Headers
+@section Using Precompiled Headers
+@cindex precompiled headers
+@cindex speed of compilation
+
+Often large projects have many header files that are included in every
+source file. The time the compiler takes to process these header files
+over and over again can account for nearly all of the time required to
+build the project. To make builds faster, GCC allows users to
+`precompile' a header file; then, if builds can use the precompiled
+header file they will be much faster.
+
+@strong{Caution:} There are a few known situations where GCC will
+crash when trying to use a precompiled header. If you have trouble
+with a precompiled header, you should remove the precompiled header
+and compile without it. In addition, please use GCC's on-line
+defect-tracking system to report any problems you encounter with
+precompiled headers. @xref{Bugs}.
+
+To create a precompiled header file, simply compile it as you would any
+other file, if necessary using the @option{-x} option to make the driver
+treat it as a C or C++ header file. You will probably want to use a
+tool like @command{make} to keep the precompiled header up-to-date when
+the headers it contains change.
+
+A precompiled header file will be searched for when @code{#include} is
+seen in the compilation. As it searches for the included file
+(@pxref{Search Path,,Search Path,cpp,The C Preprocessor}) the
+compiler looks for a precompiled header in each directory just before it
+looks for the include file in that directory. The name searched for is
+the name specified in the @code{#include} with @samp{.gch} appended. If
+the precompiled header file can't be used, it is ignored.
+
+For instance, if you have @code{#include "all.h"}, and you have
+@file{all.h.gch} in the same directory as @file{all.h}, then the
+precompiled header file will be used if possible, and the original
+header will be used otherwise.
+
+Alternatively, you might decide to put the precompiled header file in a
+directory and use @option{-I} to ensure that directory is searched
+before (or instead of) the directory containing the original header.
+Then, if you want to check that the precompiled header file is always
+used, you can put a file of the same name as the original header in this
+directory containing an @code{#error} command.
+
+This also works with @option{-include}. So yet another way to use
+precompiled headers, good for projects not designed with precompiled
+header files in mind, is to simply take most of the header files used by
+a project, include them from another header file, precompile that header
+file, and @option{-include} the precompiled header. If the header files
+have guards against multiple inclusion, they will be skipped because
+they've already been included (in the precompiled header).
+
+If you need to precompile the same header file for different
+languages, targets, or compiler options, you can instead make a
+@emph{directory} named like @file{all.h.gch}, and put each precompiled
+header in the directory. (It doesn't matter what you call the files
+in the directory, every precompiled header in the directory will be
+considered.) The first precompiled header encountered in the
+directory that is valid for this compilation will be used; they're
+searched in no particular order.
+
+There are many other possibilities, limited only by your imagination,
+good sense, and the constraints of your build system.
+
+A precompiled header file can be used only when these conditions apply:
+
+@itemize
+@item
+Only one precompiled header can be used in a particular compilation.
+@item
+A precompiled header can't be used once the first C token is seen. You
+can have preprocessor directives before a precompiled header; you can
+even include a precompiled header from inside another header, so long as
+there are no C tokens before the @code{#include}.
+@item
+The precompiled header file must be produced for the same language as
+the current compilation. You can't use a C precompiled header for a C++
+compilation.
+@item
+The precompiled header file must be produced by the same compiler
+version and configuration as the current compilation is using.
+The easiest way to guarantee this is to use the same compiler binary
+for creating and using precompiled headers.
+@item
+Any macros defined before the precompiled header (including with
+@option{-D}) must either be defined in the same way as when the
+precompiled header was generated, or must not affect the precompiled
+header, which usually means that the they don't appear in the
+precompiled header at all.
+@item
+Certain command-line options must be defined in the same way as when the
+precompiled header was generated. At present, it's not clear which
+options are safe to change and which are not; the safest choice is to
+use exactly the same options when generating and using the precompiled
+header.
+@end itemize
+
+For all of these but the last, the compiler will automatically ignore
+the precompiled header if the conditions aren't met. For the last item,
+some option changes will cause the precompiled header to be rejected,
+but not all incompatible option combinations have yet been found. If
+you find a new incompatible combination, please consider filing a bug
+report, see @ref{Bugs}.
+
@node Running Protoize
@section Running Protoize
@@ -11198,10 +11620,10 @@ appropriate options and the option @option{-aux-info}. Then run
the existing @samp{.X} file because it is newer than the source file.
For example:
-@example
+@smallexample
gcc -Dfoo=bar file1.c -aux-info file1.X
protoize *.c
-@end example
+@end smallexample
@noindent
You need to include the special files along with the rest in the
diff --git a/contrib/gcc/doc/libgcc.texi b/contrib/gcc/doc/libgcc.texi
new file mode 100644
index 000000000000..41e214e16127
--- /dev/null
+++ b/contrib/gcc/doc/libgcc.texi
@@ -0,0 +1,484 @@
+@c Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+@c This is part of the GCC manual.
+@c For copying conditions, see the file gcc.texi.
+@c Contributed by Aldy Hernandez <aldy@quesejoda.com>
+
+@node Libgcc
+@chapter The GCC low-level runtime library
+
+GCC provides a low-level runtime library, @file{libgcc.a} or
+@file{libgcc_s.so.1} on some platforms. GCC generates calls to
+routines in this library automatically, whenever it needs to perform
+some operation that is too complicated to emit inline code for.
+
+Most of the routines in @code{libgcc} handle arithmetic operations
+that the target processor cannot perform directly. This includes
+integer multiply and divide on some machines, and all floating-point
+operations on other machines. @code{libgcc} also includes routines
+for exception handling, and a handful of miscellaneous operations.
+
+Some of these routines can be defined in mostly machine-independent C.
+Others must be hand-written in assembly language for each processor
+that needs them.
+
+GCC will also generate calls to C library routines, such as
+@code{memcpy} and @code{memset}, in some cases. The set of routines
+that GCC may possibly use is documented in @ref{Other
+Builtins,,,gcc, Using the GNU Compiler Collection (GCC)}.
+
+These routines take arguments and return values of a specific machine
+mode, not a specific C type. @xref{Machine Modes}, for an explanation
+of this concept. For illustrative purposes, in this chapter the
+floating point type @code{float} is assumed to correspond to @code{SFmode};
+@code{double} to @code{DFmode}; and @code{@w{long double}} to both
+@code{TFmode} and @code{XFmode}. Similarly, the integer types @code{int}
+and @code{@w{unsigned int}} correspond to @code{SImode}; @code{long} and
+@code{@w{unsigned long}} to @code{DImode}; and @code{@w{long long}} and
+@code{@w{unsigned long long}} to @code{TImode}.
+
+@menu
+* Integer library routines::
+* Soft float library routines::
+* Exception handling routines::
+* Miscellaneous routines::
+@end menu
+
+@node Integer library routines
+@section Routines for integer arithmetic
+
+The integer arithmetic routines are used on platforms that don't provide
+hardware support for arithmetic operations on some modes.
+
+@subsection Arithmetic functions
+
+@deftypefn {Runtime Function} int __ashlsi3 (int @var{a}, int @var{b})
+@deftypefnx {Runtime Function} long __ashldi3 (long @var{a}, int @var{b})
+@deftypefnx {Runtime Function} {long long} __ashlti3 (long long @var{a}, int @var{b})
+These functions return the result of shifting @var{a} left by @var{b} bits.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __ashrsi3 (int @var{a}, int @var{b})
+@deftypefnx {Runtime Function} long __ashrdi3 (long @var{a}, int @var{b})
+@deftypefnx {Runtime Function} {long long} __ashrti3 (long long @var{a}, int @var{b})
+These functions return the result of arithmetically shifting @var{a} right
+by @var{b} bits.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __divsi3 (int @var{a}, int @var{b})
+@deftypefnx {Runtime Function} long __divdi3 (long @var{a}, long @var{b})
+@deftypefnx {Runtime Function} {long long} __divti3 (long long @var{a}, long long @var{b})
+These functions return the quotient of the signed division of @var{a} and
+@var{b}.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __lshrsi3 (int @var{a}, int @var{b})
+@deftypefnx {Runtime Function} long __lshrdi3 (long @var{a}, int @var{b})
+@deftypefnx {Runtime Function} {long long} __lshrti3 (long long @var{a}, int @var{b})
+These functions return the result of logically shifting @var{a} right by
+@var{b} bits.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __modsi3 (int @var{a}, int @var{b})
+@deftypefnx {Runtime Function} long __moddi3 (long @var{a}, long @var{b})
+@deftypefnx {Runtime Function} {long long} __modti3 (long long @var{a}, long long @var{b})
+These functions return the remainder of the signed division of @var{a}
+and @var{b}.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __mulsi3 (int @var{a}, int @var{b})
+@deftypefnx {Runtime Function} long __muldi3 (long @var{a}, long @var{b})
+@deftypefnx {Runtime Function} {long long} __multi3 (long long @var{a}, long long @var{b})
+These functions return the product of @var{a} and @var{b}.
+@end deftypefn
+
+@deftypefn {Runtime Function} long __negdi2 (long @var{a})
+@deftypefnx {Runtime Function} {long long} __negti2 (long long @var{a})
+These functions return the negation of @var{a}.
+@end deftypefn
+
+@deftypefn {Runtime Function} {unsigned int} __udivsi3 (unsigned int @var{a}, unsigned int @var{b})
+@deftypefnx {Runtime Function} {unsigned long} __udivdi3 (unsigned long @var{a}, unsigned long @var{b})
+@deftypefnx {Runtime Function} {unsigned long long} __udivti3 (unsigned long long @var{a}, unsigned long long @var{b})
+These functions return the quotient of the unsigned division of @var{a}
+and @var{b}.
+@end deftypefn
+
+@deftypefn {Runtime Function} {unsigned long} __udivmoddi3 (unsigned long @var{a}, unsigned long @var{b}, unsigned long *@var{c})
+@deftypefnx {Runtime Function} {unsigned long long} __udivti3 (unsigned long long @var{a}, unsigned long long @var{b}, unsigned long long *@var{c})
+These functions calculate both the quotient and remainder of the unsigned
+division of @var{a} and @var{b}. The return value is the quotient, and
+the remainder is placed in variable pointed to by @var{c}.
+@end deftypefn
+
+@deftypefn {Runtime Function} {unsigned int} __umodsi3 (unsigned int @var{a}, unsigned int @var{b})
+@deftypefnx {Runtime Function} {unsigned long} __umoddi3 (unsigned long @var{a}, unsigned long @var{b})
+@deftypefnx {Runtime Function} {unsigned long long} __umodti3 (unsigned long long @var{a}, unsigned long long @var{b})
+These functions return the remainder of the unsigned division of @var{a}
+and @var{b}.
+@end deftypefn
+
+@subsection Comparison functions
+
+The following functions implement integral comparisons. These functions
+implement a low-level compare, upon which the higher level comparison
+operators (such as less than and greater than or equal to) can be
+constructed. The returned values lie in the range zero to two, to allow
+the high-level operators to be implemented by testing the returned
+result using either signed or unsigned comparison.
+
+@deftypefn {Runtime Function} int __cmpdi2 (long @var{a}, long @var{b})
+@deftypefnx {Runtime Function} int __cmpti2 (long long @var{a}, long long @var{b})
+These functions perform a signed comparison of @var{a} and @var{b}. If
+@var{a} is less than @var{b}, they return 0; if @var{a} is greater than
+@var{b}, they return 2; and if @var{a} and @var{b} are equal they return 1.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __ucmpdi2 (unsigned long @var{a}, unsigned long @var{b})
+@deftypefnx {Runtime Function} int __ucmpti2 (unsigned long long @var{a}, unsigned long long @var{b})
+These functions perform an unsigned comparison of @var{a} and @var{b}.
+If @var{a} is less than @var{b}, they return 0; if @var{a} is greater than
+@var{b}, they return 2; and if @var{a} and @var{b} are equal they return 1.
+@end deftypefn
+
+@subsection Trapping arithmetic functions
+
+The following functions implement trapping arithmetic. These functions
+call the libc function @code{abort} upon signed arithmetic overflow.
+
+@deftypefn {Runtime Function} int __absvsi2 (int @var{a})
+@deftypefnx {Runtime Function} long __absvdi2 (long @var{a})
+These functions return the absolute value of @var{a}.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __addvsi3 (int @var{a}, int @var{b})
+@deftypefnx {Runtime Function} long __addvdi3 (long @var{a}, long @var{b})
+These functions return the sum of @var{a} and @var{b}; that is
+@code{@var{a} + @var{b}}.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __mulvsi3 (int @var{a}, int @var{b})
+@deftypefnx {Runtime Function} long __mulvdi3 (long @var{a}, long @var{b})
+The functions return the product of @var{a} and @var{b}; that is
+@code{@var{a} * @var{b}}.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __negvsi2 (int @var{a})
+@deftypefnx {Runtime Function} long __negvdi2 (long @var{a})
+These functions return the negation of @var{a}; that is @code{-@var{a}}.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __subvsi3 (int @var{a}, int @var{b})
+@deftypefnx {Runtime Function} long __subvdi3 (long @var{a}, long @var{b})
+These functions return the difference between @var{b} and @var{a};
+that is @code{@var{a} - @var{b}}.
+@end deftypefn
+
+@subsection Bit operations
+
+@deftypefn {Runtime Function} int __clzsi2 (int @var{a})
+@deftypefnx {Runtime Function} int __clzdi2 (long @var{a})
+@deftypefnx {Runtime Function} int __clzti2 (long long @var{a})
+These functions return the number of leading 0-bits in @var{a}, starting
+at the most significant bit position. If @var{a} is zero, the result is
+undefined.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __ctzsi2 (int @var{a})
+@deftypefnx {Runtime Function} int __ctzdi2 (long @var{a})
+@deftypefnx {Runtime Function} int __ctzti2 (long long @var{a})
+These functions return the number of trailing 0-bits in @var{a}, starting
+at the least significant bit position. If @var{a} is zero, the result is
+undefined.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __ffsdi2 (long @var{a})
+@deftypefnx {Runtime Function} int __ffsti2 (long long @var{a})
+These functions return the index of the least significant 1-bit in @var{a},
+or the value zero if @var{a} is zero. The least significant bit is index
+one.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __paritysi2 (int @var{a})
+@deftypefnx {Runtime Function} int __paritydi2 (long @var{a})
+@deftypefnx {Runtime Function} int __parityti2 (long long @var{a})
+These functions return the value zero if the number of bits set in
+@var{a} is even, and the value one otherwise.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __popcountsi2 (int @var{a})
+@deftypefnx {Runtime Function} int __popcountdi2 (long @var{a})
+@deftypefnx {Runtime Function} int __popcountti2 (long long @var{a})
+These functions return the number of bits set in @var{a}.
+@end deftypefn
+
+@node Soft float library routines
+@section Routines for floating point emulation
+@cindex soft float library
+@cindex arithmetic library
+@cindex math library
+@opindex msoft-float
+
+The software floating point library is used on machines which do not
+have hardware support for floating point. It is also used whenever
+@option{-msoft-float} is used to disable generation of floating point
+instructions. (Not all targets support this switch.)
+
+For compatibility with other compilers, the floating point emulation
+routines can be renamed with the @code{DECLARE_LIBRARY_RENAMES} macro
+(@pxref{Library Calls}). In this section, the default names are used.
+
+Presently the library does not support @code{XFmode}, which is used
+for @code{long double} on some architectures.
+
+@subsection Arithmetic functions
+
+@deftypefn {Runtime Function} float __addsf3 (float @var{a}, float @var{b})
+@deftypefnx {Runtime Function} double __adddf3 (double @var{a}, double @var{b})
+@deftypefnx {Runtime Function} {long double} __addtf3 (long double @var{a}, long double @var{b})
+@deftypefnx {Runtime Function} {long double} __addxf3 (long double @var{a}, long double @var{b})
+These functions return the sum of @var{a} and @var{b}.
+@end deftypefn
+
+@deftypefn {Runtime Function} float __subsf3 (float @var{a}, float @var{b})
+@deftypefnx {Runtime Function} double __subdf3 (double @var{a}, double @var{b})
+@deftypefnx {Runtime Function} {long double} __subtf3 (long double @var{a}, long double @var{b})
+@deftypefnx {Runtime Function} {long double} __subxf3 (long double @var{a}, long double @var{b})
+These functions return the difference between @var{b} and @var{a};
+that is, @w{@math{@var{a} - @var{b}}}.
+@end deftypefn
+
+@deftypefn {Runtime Function} float __mulsf3 (float @var{a}, float @var{b})
+@deftypefnx {Runtime Function} double __muldf3 (double @var{a}, double @var{b})
+@deftypefnx {Runtime Function} {long double} __multf3 (long double @var{a}, long double @var{b})
+@deftypefnx {Runtime Function} {long double} __mulxf3 (long double @var{a}, long double @var{b})
+These functions return the product of @var{a} and @var{b}.
+@end deftypefn
+
+@deftypefn {Runtime Function} float __divsf3 (float @var{a}, float @var{b})
+@deftypefnx {Runtime Function} double __divdf3 (double @var{a}, double @var{b})
+@deftypefnx {Runtime Function} {long double} __divtf3 (long double @var{a}, long double @var{b})
+@deftypefnx {Runtime Function} {long double} __divxf3 (long double @var{a}, long double @var{b})
+These functions return the quotient of @var{a} and @var{b}; that is,
+@w{@math{@var{a} / @var{b}}}.
+@end deftypefn
+
+@deftypefn {Runtime Function} float __negsf2 (float @var{a})
+@deftypefnx {Runtime Function} double __negdf2 (double @var{a})
+@deftypefnx {Runtime Function} {long double} __negtf2 (long double @var{a})
+@deftypefnx {Runtime Function} {long double} __negxf2 (long double @var{a})
+These functions return the negation of @var{a}. They simply flip the
+sign bit, so they can produce negative zero and negative NaN.
+@end deftypefn
+
+@subsection Conversion functions
+
+@deftypefn {Runtime Function} double __extendsfdf2 (float @var{a})
+@deftypefnx {Runtime Function} {long double} __extendsftf2 (float @var{a})
+@deftypefnx {Runtime Function} {long double} __extendsfxf2 (float @var{a})
+@deftypefnx {Runtime Function} {long double} __extenddftf2 (double @var{a})
+@deftypefnx {Runtime Function} {long double} __extenddfxf2 (double @var{a})
+These functions extend @var{a} to the wider mode of their return
+type.
+@end deftypefn
+
+@deftypefn {Runtime Function} double __truncxfdf2 (long double @var{a})
+@deftypefnx {Runtime Function} double __trunctfdf2 (long double @var{a})
+@deftypefnx {Runtime Function} float __truncxfsf2 (long double @var{a})
+@deftypefnx {Runtime Function} float __trunctfsf2 (long double @var{a})
+@deftypefnx {Runtime Function} float __truncdfsf2 (double @var{a})
+These functions truncate @var{a} to the narrower mode of their return
+type, rounding toward zero.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __fixsfsi (float @var{a})
+@deftypefnx {Runtime Function} int __fixdfsi (double @var{a})
+@deftypefnx {Runtime Function} int __fixtfsi (long double @var{a})
+@deftypefnx {Runtime Function} int __fixxfsi (long double @var{a})
+These functions convert @var{a} to a signed integer, rounding toward zero.
+@end deftypefn
+
+@deftypefn {Runtime Function} long __fixsfdi (float @var{a})
+@deftypefnx {Runtime Function} long __fixdfdi (double @var{a})
+@deftypefnx {Runtime Function} long __fixtfdi (long double @var{a})
+@deftypefnx {Runtime Function} long __fixxfdi (long double @var{a})
+These functions convert @var{a} to a signed long, rounding toward zero.
+@end deftypefn
+
+@deftypefn {Runtime Function} {long long} __fixsfti (float @var{a})
+@deftypefnx {Runtime Function} {long long} __fixdfti (double @var{a})
+@deftypefnx {Runtime Function} {long long} __fixtfti (long double @var{a})
+@deftypefnx {Runtime Function} {long long} __fixxfti (long double @var{a})
+These functions convert @var{a} to a signed long long, rounding toward zero.
+@end deftypefn
+
+@deftypefn {Runtime Function} {unsigned int} __fixunssfsi (float @var{a})
+@deftypefnx {Runtime Function} {unsigned int} __fixunsdfsi (double @var{a})
+@deftypefnx {Runtime Function} {unsigned int} __fixunstfsi (long double @var{a})
+@deftypefnx {Runtime Function} {unsigned int} __fixunsxfsi (long double @var{a})
+These functions convert @var{a} to an unsigned integer, rounding
+toward zero. Negative values all become zero.
+@end deftypefn
+
+@deftypefn {Runtime Function} {unsigned long} __fixunssfdi (float @var{a})
+@deftypefnx {Runtime Function} {unsigned long} __fixunsdfdi (double @var{a})
+@deftypefnx {Runtime Function} {unsigned long} __fixunstfdi (long double @var{a})
+@deftypefnx {Runtime Function} {unsigned long} __fixunsxfdi (long double @var{a})
+These functions convert @var{a} to an unsigned long, rounding
+toward zero. Negative values all become zero.
+@end deftypefn
+
+@deftypefn {Runtime Function} {unsigned long long} __fixunssfti (float @var{a})
+@deftypefnx {Runtime Function} {unsigned long long} __fixunsdfti (double @var{a})
+@deftypefnx {Runtime Function} {unsigned long long} __fixunstfti (long double @var{a})
+@deftypefnx {Runtime Function} {unsigned long long} __fixunsxfti (long double @var{a})
+These functions convert @var{a} to an unsigned long long, rounding
+toward zero. Negative values all become zero.
+@end deftypefn
+
+@deftypefn {Runtime Function} float __floatsisf (int @var{i})
+@deftypefnx {Runtime Function} double __floatsidf (int @var{i})
+@deftypefnx {Runtime Function} {long double} __floatsitf (int @var{i})
+@deftypefnx {Runtime Function} {long double} __floatsixf (int @var{i})
+These functions convert @var{i}, a signed integer, to floating point.
+@end deftypefn
+
+@deftypefn {Runtime Function} float __floatdisf (long @var{i})
+@deftypefnx {Runtime Function} double __floatdidf (long @var{i})
+@deftypefnx {Runtime Function} {long double} __floatditf (long @var{i})
+@deftypefnx {Runtime Function} {long double} __floatdixf (long @var{i})
+These functions convert @var{i}, a signed long, to floating point.
+@end deftypefn
+
+@deftypefn {Runtime Function} float __floattisf (long long @var{i})
+@deftypefnx {Runtime Function} double __floattidf (long long @var{i})
+@deftypefnx {Runtime Function} {long double} __floattitf (long long @var{i})
+@deftypefnx {Runtime Function} {long double} __floattixf (long long @var{i})
+These functions convert @var{i}, a signed long long, to floating point.
+@end deftypefn
+
+@subsection Comparison functions
+
+There are two sets of basic comparison functions.
+
+@deftypefn {Runtime Function} int __cmpsf2 (float @var{a}, float @var{b})
+@deftypefnx {Runtime Function} int __cmpdf2 (double @var{a}, double @var{b})
+@deftypefnx {Runtime Function} int __cmptf2 (long double @var{a}, long double @var{b})
+These functions calculate @math{a <=> b}. That is, if @var{a} is less
+than @var{b}, they return -1; if @var{a} is greater than @var{b}, they
+return 1; and if @var{a} and @var{b} are equal they return 0. If
+either argument is NaN they return 1, but you should not rely on this;
+if NaN is a possibility, use one of the higher-level comparison
+functions.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __unordsf2 (float @var{a}, float @var{b})
+@deftypefnx {Runtime Function} int __unorddf2 (double @var{a}, double @var{b})
+@deftypefnx {Runtime Function} int __unordtf2 (long double @var{a}, long double @var{b})
+These functions return a nonzero value if either argument is NaN, otherwise 0.
+@end deftypefn
+
+There is also a complete group of higher level functions which
+correspond directly to comparison operators. They implement the ISO C
+semantics for floating-point comparisons, taking NaN into account.
+Pay careful attention to the return values defined for each set.
+Under the hood, all of these routines are implemented as
+
+@smallexample
+ if (__unord@var{X}f2 (a, b))
+ return @var{E};
+ return __cmp@var{X}f2 (a, b);
+@end smallexample
+
+@noindent
+where @var{E} is a constant chosen to give the proper behavior for
+NaN. Thus, the meaning of the return value is different for each set.
+Do not rely on this implementation; only the semantics documented
+below are guaranteed.
+
+@deftypefn {Runtime Function} int __eqsf2 (float @var{a}, float @var{b})
+@deftypefnx {Runtime Function} int __eqdf2 (double @var{a}, double @var{b})
+@deftypefnx {Runtime Function} int __eqtf2 (long double @var{a}, long double @var{b})
+These functions return zero if neither argument is NaN, and @var{a} and
+@var{b} are equal.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __nesf2 (float @var{a}, float @var{b})
+@deftypefnx {Runtime Function} int __nedf2 (double @var{a}, double @var{b})
+@deftypefnx {Runtime Function} int __netf2 (long double @var{a}, long double @var{b})
+These functions return a nonzero value if either argument is NaN, or
+if @var{a} and @var{b} are unequal.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __gesf2 (float @var{a}, float @var{b})
+@deftypefnx {Runtime Function} int __gedf2 (double @var{a}, double @var{b})
+@deftypefnx {Runtime Function} int __getf2 (long double @var{a}, long double @var{b})
+These functions return a value greater than or equal to zero if
+neither argument is NaN, and @var{a} is greater than or equal to
+@var{b}.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __ltsf2 (float @var{a}, float @var{b})
+@deftypefnx {Runtime Function} int __ltdf2 (double @var{a}, double @var{b})
+@deftypefnx {Runtime Function} int __lttf2 (long double @var{a}, long double @var{b})
+These functions return a value less than zero if neither argument is
+NaN, and @var{a} is strictly less than @var{b}.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __lesf2 (float @var{a}, float @var{b})
+@deftypefnx {Runtime Function} int __ledf2 (double @var{a}, double @var{b})
+@deftypefnx {Runtime Function} int __letf2 (long double @var{a}, long double @var{b})
+These functions return a value less than or equal to zero if neither
+argument is NaN, and @var{a} is less than or equal to @var{b}.
+@end deftypefn
+
+@deftypefn {Runtime Function} int __gtsf2 (float @var{a}, float @var{b})
+@deftypefnx {Runtime Function} int __gtdf2 (double @var{a}, double @var{b})
+@deftypefnx {Runtime Function} int __gttf2 (long double @var{a}, long double @var{b})
+These functions return a value greater than zero if neither argument
+is NaN, and @var{a} is strictly greater than @var{b}.
+@end deftypefn
+
+@node Exception handling routines
+@section Language-independent routines for exception handling
+
+document me!
+
+@smallexample
+ _Unwind_DeleteException
+ _Unwind_Find_FDE
+ _Unwind_ForcedUnwind
+ _Unwind_GetGR
+ _Unwind_GetIP
+ _Unwind_GetLanguageSpecificData
+ _Unwind_GetRegionStart
+ _Unwind_GetTextRelBase
+ _Unwind_GetDataRelBase
+ _Unwind_RaiseException
+ _Unwind_Resume
+ _Unwind_SetGR
+ _Unwind_SetIP
+ _Unwind_FindEnclosingFunction
+ _Unwind_SjLj_Register
+ _Unwind_SjLj_Unregister
+ _Unwind_SjLj_RaiseException
+ _Unwind_SjLj_ForcedUnwind
+ _Unwind_SjLj_Resume
+ __deregister_frame
+ __deregister_frame_info
+ __deregister_frame_info_bases
+ __register_frame
+ __register_frame_info
+ __register_frame_info_bases
+ __register_frame_info_table
+ __register_frame_info_table_bases
+ __register_frame_table
+@end smallexample
+
+@node Miscellaneous routines
+@section Miscellaneous runtime library routines
+
+@subsection Cache control functions
+@deftypefn {Runtime Function} void __clear_cache (char *@var{beg}, char *@var{end})
+This function clears the instruction cache between @var{beg} and @var{end}.
+@end deftypefn
+
diff --git a/contrib/gcc/doc/makefile.texi b/contrib/gcc/doc/makefile.texi
index 1e64c5e61603..4e9121455d7a 100644
--- a/contrib/gcc/doc/makefile.texi
+++ b/contrib/gcc/doc/makefile.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+@c Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -13,9 +13,17 @@ This is the default target. Depending on what your build/host/target
configuration is, it coordinates all the things that need to be built.
@item doc
-Produce info-formatted documentation. Also, @samp{make dvi} is
-available for DVI-formatted documentation, and @samp{make
-generated-manpages} to generate man pages.
+Produce info-formatted documentation and man pages. Essentially it
+calls @samp{make man} and @samp{make info}.
+
+@item dvi
+Produce DVI-formatted documentation.
+
+@item man
+Generate man pages.
+
+@item info
+Generate info-formatted pages.
@item mostlyclean
Delete the files made while building the compiler.
@@ -26,14 +34,21 @@ That, and all the other files built by @samp{make all}.
@item distclean
That, and all the files created by @command{configure}.
-@item extraclean
-That, and any temporary or intermediate files, like emacs backup files.
-
@item maintainer-clean
Distclean plus any file that can be generated from other files. Note
that additional tools may be required beyond what is normally needed to
build gcc.
+@item srcextra
+Generates files in the source directory that do not exist in CVS but
+should go into a release tarball. One example is @file{gcc/c-parse.c}
+which is generated from the CVS source file @file{gcc/c-parse.in}.
+
+@item srcinfo
+@itemx srcman
+Copies the info-formatted and manpage documentation into the source
+directory usually for the purpose of generating a release tarball.
+
@item install
Installs gcc.
@@ -56,7 +71,7 @@ Note that running the testsuite may require additional tools be
installed, such as TCL or dejagnu.
@item bootstrap
-Builds gcc three times---once with the native compiler, once with the
+Builds GCC three times---once with the native compiler, once with the
native-built compiler it just built, and once with the compiler it built
the second time. In theory, the last two should produce the same
results, which @samp{make compare} can check. Each step of this process
@@ -68,21 +83,25 @@ Like @code{bootstrap}, except that the various stages are removed once
they're no longer needed. This saves disk space.
@item bubblestrap
-Once bootstrapped, this incrementally rebuilds each of the three stages,
-one at a time. It does this by ``bubbling'' the stages up from their
-subdirectories, rebuilding them, and copying them back to their
-subdirectories. This will allow you to, for example, quickly rebuild a
-bootstrapped compiler after changing the sources, without having to do a
-full bootstrap.
+This incrementally rebuilds each of the three stages, one at a time.
+It does this by ``bubbling'' the stages up from their subdirectories
+(if they had been built previously), rebuilding them, and copying them
+back to their subdirectories. This will allow you to, for example,
+continue a bootstrap after fixing a bug which causes the stage2 build
+to crash.
@item quickstrap
Rebuilds the most recently built stage. Since each stage requires
-special invocation, using this target means you don't have to keep track
-of which stage you're on or what invocation that stage needs.
+special invocation, using this target means you don't have to keep
+track of which stage you're on or what invocation that stage needs.
@item cleanstrap
Removed everything (@samp{make clean}) and rebuilds (@samp{make bootstrap}).
+@item restrap
+Like @code{cleanstrap}, except that the process starts from the first
+stage build, not from scratch.
+
@item stage@var{N} (@var{N} = 1@dots{}4)
For each stage, moves the appropriate files to the @file{stage@var{N}}
subdirectory.
@@ -99,4 +118,11 @@ Compares the results of stages 2 and 3. This ensures that the compiler
is running properly, since it should produce the same object files
regardless of how it itself was compiled.
+@item profiledbootstrap
+Builds a compiler with profiling feedback information. For more
+information, see
+@ref{Building,,Building with profile feedback,gccinstall,Installing GCC}.
+This is actually a target in the top-level directory, which then
+recurses into the @file{gcc} subdirectory multiple times.
+
@end table
diff --git a/contrib/gcc/doc/md.texi b/contrib/gcc/doc/md.texi
index 822ec14998f9..11e291589012 100644
--- a/contrib/gcc/doc/md.texi
+++ b/contrib/gcc/doc/md.texi
@@ -1,5 +1,5 @@
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001,
-@c 2002, 2003 Free Software Foundation, Inc.
+@c 2002, 2003, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -181,7 +181,7 @@ this pattern. @xref{Insn Attributes}.
Here is an actual example of an instruction pattern, for the 68000/68020.
-@example
+@smallexample
(define_insn "tstsi"
[(set (cc0)
(match_operand:SI 0 "general_operand" "rm"))]
@@ -192,12 +192,12 @@ Here is an actual example of an instruction pattern, for the 68000/68020.
return \"tstl %0\";
return \"cmpl #0,%0\";
@}")
-@end example
+@end smallexample
@noindent
This can also be written using braced strings:
-@example
+@smallexample
(define_insn "tstsi"
[(set (cc0)
(match_operand:SI 0 "general_operand" "rm"))]
@@ -207,7 +207,7 @@ This can also be written using braced strings:
return "tstl %0";
return "cmpl #0,%0";
@})
-@end example
+@end smallexample
This is an instruction that sets the condition codes based on the value of
a general operand. It has no condition, so any insn whose RTL description
@@ -1256,7 +1256,7 @@ instruction is defined:
@dots{})
@end smallexample
@end ifset
-GCC can only handle one commutative pair in an asm; if you use more,
+GCC can only handle one commutative pair in an asm; if you use more,
the compiler may fail.
@cindex @samp{#} in constraint
@@ -1314,15 +1314,15 @@ The constraints are defined through these macros:
@table @code
@item REG_CLASS_FROM_LETTER
-Register class constraints (usually lower case).
+Register class constraints (usually lowercase).
@item CONST_OK_FOR_LETTER_P
Immediate constant constraints, for non-floating point constants of
-word size or smaller precision (usually upper case).
+word size or smaller precision (usually uppercase).
@item CONST_DOUBLE_OK_FOR_LETTER_P
Immediate constant constraints, for all floating point constants and for
-constants of greater than word size precision (usually upper case).
+constants of greater than word size precision (usually uppercase).
@item EXTRA_CONSTRAINT
Special cases of registers or memory. This macro is not required, and
@@ -1439,7 +1439,7 @@ Constant integer 1
A floating point constant 0.0
@end table
-@item IBM RS6000---@file{rs6000.h}
+@item PowerPC and IBM RS6000---@file{rs6000.h}
@table @code
@item b
Address base register
@@ -1447,6 +1447,9 @@ Address base register
@item f
Floating point register
+@item v
+Vector register
+
@item h
@samp{MQ}, @samp{CTR}, or @samp{LINK} register
@@ -1825,11 +1828,11 @@ Non-pointer registers (not @samp{SP}, @samp{DP}, @samp{IP})
Non-SP registers (everything except @samp{SP})
@item R
-Indirect thru @samp{IP} - Avoid this except for @code{QImode}, since we
+Indirect through @samp{IP} - Avoid this except for @code{QImode}, since we
can't access extra bytes
@item S
-Indirect thru @samp{SP} or @samp{DP} with short displacement (0..127)
+Indirect through @samp{SP} or @samp{DP} with short displacement (0..127)
@item T
Data-section immediate value
@@ -1934,12 +1937,6 @@ Data register
@item f
68881 floating-point register, if available
-@item x
-Sun FPA (floating-point) register, if available
-
-@item y
-First 16 Sun FPA registers, if available
-
@item I
Integer in the range 1 to 8
@@ -1957,9 +1954,6 @@ Signed number whose magnitude is greater than 0x100
@item G
Floating point constant that is not a 68881 constant
-
-@item H
-Floating point constant that can be used by Sun FPA
@end table
@item Motorola 68HC11 & 68HC12 families---@file{m68hc11.h}
@@ -2205,13 +2199,52 @@ Unsigned 12-bit constant (0--4095)
Signed 16-bit constant (@minus{}32768--32767)
@item L
-Unsigned 16-bit constant (0--65535)
+Value appropriate as displacement.
+@table @code
+ @item (0..4095)
+ for short displacement
+ @item (-524288..524287)
+ for long displacement
+@end table
+
+@item M
+Constant integer with a value of 0x7fffffff.
+
+@item N
+Multiple letter constraint followed by 4 parameter letters.
+@table @code
+ @item 0..9:
+ number of the part counting from most to least significant
+ @item H,Q:
+ mode of the part
+ @item D,S,H:
+ mode of the containing operand
+ @item 0,F:
+ value of the other parts (F - all bits set)
+@end table
+The constraint matches if the specified part of a constant
+has a value different from it's other parts.
@item Q
-Memory reference without index register
+Memory reference without index register and with short displacement.
+
+@item R
+Memory reference with index register and short displacement.
@item S
-Symbolic constant suitable for use with the @code{larl} instruction
+Memory reference without index register but with long displacement.
+
+@item T
+Memory reference with index register and long displacement.
+
+@item U
+Pointer with short displacement.
+
+@item W
+Pointer with long displacement.
+
+@item Y
+Shift count operand.
@end table
@@ -2280,6 +2313,9 @@ The register indicated by Rx (not implemented yet).
@item U
A constant that is not between 2 and 15 inclusive.
+@item Z
+The constant 0.
+
@end table
@item Xtensa---@file{xtensa.h}
@@ -2324,7 +2360,7 @@ pattern to accomplish a certain task.
@table @asis
@cindex @code{mov@var{m}} instruction pattern
@item @samp{mov@var{m}}
-Here @var{m} stands for a two-letter machine mode name, in lower case.
+Here @var{m} stands for a two-letter machine mode name, in lowercase.
This instruction pattern moves data with that machine mode from operand
1 to operand 0. For example, @samp{movsi} moves full-word data.
@@ -2627,6 +2663,72 @@ corresponds to the C data type @code{double} and the @code{logf}
built-in function uses the mode which corresponds to the C data
type @code{float}.
+@cindex @code{pow@var{m}3} instruction pattern
+@item @samp{pow@var{m}3}
+Store the value of operand 1 raised to the exponent operand 2
+into operand 0.
+
+The @code{pow} built-in function of C always uses the mode which
+corresponds to the C data type @code{double} and the @code{powf}
+built-in function uses the mode which corresponds to the C data
+type @code{float}.
+
+@cindex @code{atan2@var{m}3} instruction pattern
+@item @samp{atan2@var{m}3}
+Store the arc tangent (inverse tangent) of operand 1 divided by
+operand 2 into operand 0, using the signs of both arguments to
+determine the quadrant of the result.
+
+The @code{atan2} built-in function of C always uses the mode which
+corresponds to the C data type @code{double} and the @code{atan2f}
+built-in function uses the mode which corresponds to the C data
+type @code{float}.
+
+@cindex @code{floor@var{m}2} instruction pattern
+@item @samp{floor@var{m}2}
+Store the largest integral value not greater than argument.
+
+The @code{floor} built-in function of C always uses the mode which
+corresponds to the C data type @code{double} and the @code{floorf}
+built-in function uses the mode which corresponds to the C data
+type @code{float}.
+
+@cindex @code{trunc@var{m}2} instruction pattern
+@item @samp{trunc@var{m}2}
+Store the argument rounded to integer towards zero.
+
+The @code{trunc} built-in function of C always uses the mode which
+corresponds to the C data type @code{double} and the @code{truncf}
+built-in function uses the mode which corresponds to the C data
+type @code{float}.
+
+@cindex @code{round@var{m}2} instruction pattern
+@item @samp{round@var{m}2}
+Store the argument rounded to integer away from zero.
+
+The @code{round} built-in function of C always uses the mode which
+corresponds to the C data type @code{double} and the @code{roundf}
+built-in function uses the mode which corresponds to the C data
+type @code{float}.
+
+@cindex @code{ceil@var{m}2} instruction pattern
+@item @samp{ceil@var{m}2}
+Store the argument rounded to integer away from zero.
+
+The @code{ceil} built-in function of C always uses the mode which
+corresponds to the C data type @code{double} and the @code{ceilf}
+built-in function uses the mode which corresponds to the C data
+type @code{float}.
+
+@cindex @code{nearbyint@var{m}2} instruction pattern
+@item @samp{nearbyint@var{m}2}
+Store the argument rounded according to the default rounding mode
+
+The @code{nearbyint} built-in function of C always uses the mode which
+corresponds to the C data type @code{double} and the @code{nearbyintf}
+built-in function uses the mode which corresponds to the C data
+type @code{float}.
+
@cindex @code{ffs@var{m}2} instruction pattern
@item @samp{ffs@var{m}2}
Store into operand 0 one plus the index of the least significant 1-bit
@@ -2638,6 +2740,36 @@ generating the instruction.
The @code{ffs} built-in function of C always uses the mode which
corresponds to the C data type @code{int}.
+@cindex @code{clz@var{m}2} instruction pattern
+@item @samp{clz@var{m}2}
+Store into operand 0 the number of leading 0-bits in @var{x}, starting
+at the most significant bit position. If @var{x} is 0, the result is
+undefined. @var{m} is the mode of operand 0; operand 1's mode is
+specified by the instruction pattern, and the compiler will convert the
+operand to that mode before generating the instruction.
+
+@cindex @code{ctz@var{m}2} instruction pattern
+@item @samp{ctz@var{m}2}
+Store into operand 0 the number of trailing 0-bits in @var{x}, starting
+at the least significant bit position. If @var{x} is 0, the result is
+undefined. @var{m} is the mode of operand 0; operand 1's mode is
+specified by the instruction pattern, and the compiler will convert the
+operand to that mode before generating the instruction.
+
+@cindex @code{popcount@var{m}2} instruction pattern
+@item @samp{popcount@var{m}2}
+Store into operand 0 the number of 1-bits in @var{x}. @var{m} is the
+mode of operand 0; operand 1's mode is specified by the instruction
+pattern, and the compiler will convert the operand to that mode before
+generating the instruction.
+
+@cindex @code{parity@var{m}2} instruction pattern
+@item @samp{parity@var{m}2}
+Store into operand 0 the parity of @var{x}, i.@:e. the number of 1-bits
+in @var{x} modulo 2. @var{m} is the mode of operand 0; operand 1's mode
+is specified by the instruction pattern, and the compiler will convert
+the operand to that mode before generating the instruction.
+
@cindex @code{one_cmpl@var{m}2} instruction pattern
@item @samp{one_cmpl@var{m}2}
Store the bitwise-complement of operand 1 into operand 0.
@@ -2709,10 +2841,23 @@ The use for multiple @code{clrstr@var{m}} is as for @code{movstr@var{m}}.
@cindex @code{cmpstr@var{m}} instruction pattern
@item @samp{cmpstr@var{m}}
-Block compare instruction, with five operands. Operand 0 is the output;
+String compare instruction, with five operands. Operand 0 is the output;
it has mode @var{m}. The remaining four operands are like the operands
of @samp{movstr@var{m}}. The two memory blocks specified are compared
-byte by byte in lexicographic order. The effect of the instruction is
+byte by byte in lexicographic order starting at the beginning of each
+string. The instruction is not allowed to prefetch more than one byte
+at a time since either string may end in the first byte and reading past
+that may access an invalid page or segment and cause a fault. The
+effect of the instruction is to store a value in operand 0 whose sign
+indicates the result of the comparison.
+
+@cindex @code{cmpmem@var{m}} instruction pattern
+@item @samp{cmpmem@var{m}}
+Block compare instruction, with five operands like the operands
+of @samp{cmpstr@var{m}}. The two memory blocks specified are compared
+byte by byte in lexicographic order starting at the beginning of each
+block. Unlike @samp{cmpstr@var{m}} the instruction can prefetch
+any bytes in the two memory blocks. The effect of the instruction is
to store a value in operand 0 whose sign indicates the result of the
comparison.
@@ -2829,6 +2974,13 @@ codes and vice versa.
If the machine does not have conditional move instructions, do not
define these patterns.
+@cindex @code{add@var{mode}cc} instruction pattern
+@item @samp{add@var{mode}cc}
+Similar to @samp{mov@var{mode}cc} but for conditional addition. Conditionally
+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.
@@ -3193,18 +3345,6 @@ Some machines require other operations such as stack probes or
maintaining the back chain. Define this pattern to emit those
operations in addition to updating the stack pointer.
-@cindex @code{probe} instruction pattern
-@item @samp{probe}
-Some machines require instructions to be executed after space is
-allocated from the stack, for example to generate a reference at
-the bottom of the stack.
-
-If you need to emit instructions before the stack has been adjusted,
-put them into the @samp{allocate_stack} pattern. Otherwise, define
-this pattern to emit the required instructions.
-
-No operands are provided.
-
@cindex @code{check_stack} instruction pattern
@item @samp{check_stack}
If stack checking cannot be done on your system by probing the stack with
@@ -3288,17 +3428,17 @@ and thence the call frame exception handling library routines, are
built. It is intended to handle non-trivial actions needed along
the abnormal return path.
-The pattern takes two arguments. The first is an offset to be applied
-to the stack pointer. It will have been copied to some appropriate
-location (typically @code{EH_RETURN_STACKADJ_RTX}) which will survive
-until after reload to when the normal epilogue is generated.
-The second argument is the address of the exception handler to which
-the function should return. This will normally need to copied by the
-pattern to some special register or memory location.
+The address of the exception handler to which the function should return
+is passed as operand to this pattern. It will normally need to copied by
+the pattern to some special register or memory location.
+If the pattern needs to determine the location of the target call
+frame in order to do so, it may use @code{EH_RETURN_STACKADJ_RTX},
+if defined; it will have already been assigned.
-This pattern only needs to be defined if call frame exception handling
-is to be used, and simple moves involving @code{EH_RETURN_STACKADJ_RTX}
-and @code{EH_RETURN_HANDLER_RTX} are not sufficient.
+If this pattern is not defined, the default action will be to simply
+copy the return address to @code{EH_RETURN_HANDLER_RTX}. Either
+that macro or this pattern needs to be defined if call frame exception
+handling is to be used.
@cindex @code{prologue} instruction pattern
@anchor{prologue instruction pattern}
@@ -3376,6 +3516,12 @@ the values of operands 1 and 2.
@end table
+@end ifset
+@c Each of the following nodes are wrapped in separate
+@c "@ifset INTERNALS" to work around memory limits for the default
+@c configuration in older tetex distributions. Known to not work:
+@c tetex-1.0.7, known to work: tetex-2.0.2.
+@ifset INTERNALS
@node Pattern Ordering
@section When the Order of Patterns Matters
@cindex Pattern Ordering
@@ -3399,6 +3545,8 @@ Instead of using this pattern ordering it would be possible to make the
pattern for convert-a-byte smart enough to deal properly with any
constant value.
+@end ifset
+@ifset INTERNALS
@node Dependent Patterns
@section Interdependence of Patterns
@cindex Dependent Patterns
@@ -3408,24 +3556,24 @@ 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
-@example
+@smallexample
(set (pc)
(if_then_else (@var{cond} (cc0) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))
-@end example
+@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
-@example
+@smallexample
(set (pc)
(if_then_else (@var{cond} (cc0) (const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))
-@end example
+@end smallexample
@noindent
They are necessary because jump optimization can turn direct-conditional
@@ -3435,7 +3583,7 @@ 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,
-@example
+@smallexample
(define_insn ""
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
@@ -3444,20 +3592,20 @@ example,
(label_ref (match_operand 1 "" ""))))]
"@var{condition}"
"@dots{}")
-@end example
+@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
patterns are
-@example
+@smallexample
(set (match_operand:SI 0 @dots{})
(extend:SI (match_operand:HI 1 @dots{})))
(set (match_operand:SI 0 @dots{})
(extend:SI (match_operand:QI 1 @dots{})))
-@end example
+@end smallexample
@noindent
Constant integers do not specify a machine mode, so an instruction to
@@ -3479,6 +3627,8 @@ instructions. Instead, they should be generated from the same pattern
that supports register-register add insns by examining the operands and
generating the appropriate machine instruction.
+@end ifset
+@ifset INTERNALS
@node Jump Patterns
@section Defining Jump Instruction Patterns
@cindex jump instruction patterns
@@ -3592,6 +3742,8 @@ discussed above, we have the pattern
The @code{SELECT_CC_MODE} macro on the SPARC returns @code{CC_NOOVmode}
for comparisons whose argument is a @code{plus}.
+@end ifset
+@ifset INTERNALS
@node Looping Patterns
@section Defining Looping Instruction Patterns
@cindex looping instruction patterns
@@ -3697,6 +3849,8 @@ be derived from it), however, in many cases the loop induction variable
may become redundant and removed by the flow pass.
+@end ifset
+@ifset INTERNALS
@node Insn Canonicalizations
@section Canonicalization of Instructions
@cindex canonicalization of instructions
@@ -3731,7 +3885,7 @@ first operand.
@item
In combinations of @code{neg}, @code{mult}, @code{plus}, and
@code{minus}, the @code{neg} operations (if any) will be moved inside
-the operations as far as possible. For instance,
+the operations as far as possible. For instance,
@code{(neg (mult A B))} is canonicalized as @code{(mult (neg A) B)}, but
@code{(plus (mult (neg A) B) C)} is canonicalized as
@code{(minus A (mult B C))}.
@@ -3770,26 +3924,26 @@ A machine that has an instruction that performs a bitwise logical-and of one
operand with the bitwise negation of the other should specify the pattern
for that instruction as
-@example
+@smallexample
(define_insn ""
[(set (match_operand:@var{m} 0 @dots{})
(and:@var{m} (not:@var{m} (match_operand:@var{m} 1 @dots{}))
(match_operand:@var{m} 2 @dots{})))]
"@dots{}"
"@dots{}")
-@end example
+@end smallexample
@noindent
Similarly, a pattern for a ``NAND'' instruction should be written
-@example
+@smallexample
(define_insn ""
[(set (match_operand:@var{m} 0 @dots{})
(ior:@var{m} (not:@var{m} (match_operand:@var{m} 1 @dots{}))
(not:@var{m} (match_operand:@var{m} 2 @dots{}))))]
"@dots{}"
"@dots{}")
-@end example
+@end smallexample
In both cases, it is not necessary to include patterns for the many
logically equivalent RTL expressions.
@@ -3804,9 +3958,9 @@ and @code{(not:@var{m} (xor:@var{m} @var{x} @var{y}))}.
The sum of three items, one of which is a constant, will only appear in
the form
-@example
+@smallexample
(plus:@var{m} (plus:@var{m} @var{x} @var{y}) @var{constant})
-@end example
+@end smallexample
@item
On machines that do not use @code{cc0},
@@ -3822,6 +3976,8 @@ will be written using @code{zero_extract} rather than the equivalent
@end itemize
+@end ifset
+@ifset INTERNALS
@node Expander Definitions
@section Defining RTL Sequences for Code Generation
@cindex expander definitions
@@ -4039,6 +4195,8 @@ at the end, emit an insn to copy the result of the operation into
itself. Such an insn will generate no code, but it can avoid problems
in the compiler.
+@end ifset
+@ifset INTERNALS
@node Insn Splitting
@section Defining How to Split Instructions
@cindex insn splitting
@@ -4272,6 +4430,8 @@ functionality as two separate @code{define_insn} and @code{define_split}
patterns. It exists for compactness, and as a maintenance tool to prevent
having to ensure the two patterns' templates match.
+@end ifset
+@ifset INTERNALS
@node Including Patterns
@section Including Patterns in Machine Descriptions.
@cindex insn includes
@@ -4346,6 +4506,8 @@ one @option{-I} option, the directories are scanned in left-to-right
order; the standard default directory come after.
+@end ifset
+@ifset INTERNALS
@node Peephole Definitions
@section Machine-Specific Peephole Optimizers
@cindex peephole optimizer definitions
@@ -4376,6 +4538,8 @@ targets that do scheduling.
* define_peephole2:: RTL to RTL Peephole Optimizers
@end menu
+@end ifset
+@ifset INTERNALS
@node define_peephole
@subsection RTL to Text Peephole Optimizers
@findex define_peephole
@@ -4567,6 +4731,8 @@ then the way to mention this insn in a peephole is as follows:
@dots{})
@end smallexample
+@end ifset
+@ifset INTERNALS
@node define_peephole2
@subsection RTL to RTL Peephole Optimizers
@findex define_peephole2
@@ -4652,6 +4818,8 @@ If we had not added the @code{(match_dup 4)} in the middle of the input
sequence, it might have been the case that the register we chose at the
beginning of the sequence is killed by the first or second @code{set}.
+@end ifset
+@ifset INTERNALS
@node Insn Attributes
@section Instruction Attributes
@cindex insn attributes
@@ -4675,6 +4843,8 @@ to track the condition codes.
* Processor pipeline description:: Specifying information for insn scheduling.
@end menu
+@end ifset
+@ifset INTERNALS
@node Defining Attributes
@subsection Defining Attributes and their Values
@cindex defining attributes and their values
@@ -4710,9 +4880,9 @@ specified for an attribute, the following are defined:
A @samp{#define} is written for the symbol @samp{HAVE_ATTR_@var{name}}.
@item
-An enumeral class is defined for @samp{attr_@var{name}} with
+An enumerated class is defined for @samp{attr_@var{name}} with
elements of the form @samp{@var{upper-name}_@var{upper-value}} where
-the attribute name and value are first converted to upper case.
+the attribute name and value are first converted to uppercase.
@item
A function @samp{get_attr_@var{name}} is defined that is passed an insn and
@@ -4739,6 +4909,8 @@ If the attribute takes numeric values, no @code{enum} type will be
defined and the function to obtain the attribute's value will return
@code{int}.
+@end ifset
+@ifset INTERNALS
@node Expressions
@subsection Attribute Expressions
@cindex attribute expressions
@@ -4948,6 +5120,8 @@ for numeric attributes, as @code{eq_attr} and @code{attr_flag}
produce more efficient code for non-numeric attributes.
@end table
+@end ifset
+@ifset INTERNALS
@node Tagging Insns
@subsection Assigning Attribute Values to Insns
@cindex tagging insns
@@ -5053,6 +5227,8 @@ string. Therefore, the value of the @code{length} attribute specified
in a @code{define_asm_attributes} should be the maximum possible length
of a single machine instruction.
+@end ifset
+@ifset INTERNALS
@node Attr Example
@subsection Example of Attribute Specifications
@cindex attribute specifications example
@@ -5108,6 +5284,8 @@ performed on quantities smaller than a machine word clobber the condition
code since they will set the condition code to a value corresponding to the
full-word result.
+@end ifset
+@ifset INTERNALS
@node Insn Lengths
@subsection Computing the Length of an Insn
@cindex insn lengths, computing
@@ -5149,12 +5327,6 @@ Lengths are measured in addressable storage units (bytes).
The following macros can be used to refine the length computation:
@table @code
-@findex FIRST_INSN_ADDRESS
-@item FIRST_INSN_ADDRESS
-When the @code{length} insn attribute is used, this macro specifies the
-value to be assigned to the address of the first insn in a function. If
-not specified, 0 is used.
-
@findex ADJUST_INSN_LENGTH
@item ADJUST_INSN_LENGTH (@var{insn}, @var{length})
If defined, modifies the length assigned to instruction @var{insn} as a
@@ -5198,6 +5370,8 @@ as follows:
(const_int 6)))])
@end smallexample
+@end ifset
+@ifset INTERNALS
@node Constant Attributes
@subsection Constant Attributes
@cindex constant attributes
@@ -5227,6 +5401,8 @@ the value of a constant attribute may use the @code{symbol_ref} form,
but may not use either the @code{match_operand} form or @code{eq_attr}
forms involving insn attributes.
+@end ifset
+@ifset INTERNALS
@node Delay Slots
@subsection Delay Slot Scheduling
@cindex delay slots, defining
@@ -5302,6 +5478,8 @@ branch is true, we might represent this as follows:
@end smallexample
@c the above is *still* too long. --mew 4feb93
+@end ifset
+@ifset INTERNALS
@node Processor pipeline description
@subsection Specifying processor pipeline description
@cindex processor pipeline description
@@ -5348,13 +5526,13 @@ processors.
The task of exploiting more processor parallelism is solved by an
instruction scheduler. For a better solution to this problem, the
instruction scheduler has to have an adequate description of the
-processor parallelism (or @dfn{pipeline description}). Currently GCC
+processor parallelism (or @dfn{pipeline description}). Currently GCC
provides two alternative ways to describe processor parallelism,
both described below. The first method is outlined in the next section;
it was once the only method provided by GCC, and thus is used in a number
of exiting ports. The second, and preferred method, specifies functional
unit reservations for groups of instructions with the aid of @dfn{regular
-expressions}. This is called the @dfn{automaton based description}.
+expressions}. This is called the @dfn{automaton based description}.
The GCC instruction scheduler uses a @dfn{pipeline hazard recognizer} to
figure out the possibility of the instruction issue by the processor
@@ -5367,18 +5545,18 @@ generated from the old description. Furthermore, its speed is not dependent
on processor complexity. The instruction issue is possible if there is
a transition from one automaton state to another one.
-You can use any model to describe processor pipeline characteristics
-or even a mix of them. You could use the old description for some
-processor submodels and the @acronym{DFA}-based one for the rest
+You can use either model to describe processor pipeline
+characteristics or even mix them. You could use the old description
+for some processor submodels and the @acronym{DFA}-based one for other
processor submodels.
-In general, the usage of the automaton based description is more
-preferable. Its model is more rich. It permits to describe more
-accurately pipeline characteristics of processors which results in
-improving code quality (although sometimes only on several percent
-fractions). It will be also used as an infrastructure to implement
-sophisticated and practical insn scheduling which will try many
-instruction sequences to choose the best one.
+In general, using the automaton based description is preferred. Its
+model is richer and makes it possible to more accurately describe
+pipeline characteristics of processors, which results in improved
+code quality (although sometimes only marginally). It will also be
+used as an infrastructure to implement sophisticated and practical
+instruction scheduling which will try many instruction sequences to
+choose the best one.
@menu
@@ -5387,6 +5565,8 @@ instruction sequences to choose the best one.
* Comparison of the two descriptions:: Drawbacks of the old pipeline description
@end menu
+@end ifset
+@ifset INTERNALS
@node Old pipeline description
@subsubsection Specifying Function Units
@cindex old pipeline description
@@ -5501,14 +5681,17 @@ single or double precision, but not both, the following could be specified:
@strong{Note:} The scheduler attempts to avoid function unit conflicts
and uses all the specifications in the @code{define_function_unit}
-expression. It has recently come to our attention that these
+expression. It has recently been discovered that these
specifications may not allow modeling of some of the newer
``superscalar'' processors that have insns using multiple pipelined
units. These insns will cause a potential conflict for the second unit
used during their execution and there is no way of representing that
-conflict. We welcome any examples of how function unit conflicts work
-in such processors and suggestions for their representation.
+conflict. Any examples of how function unit conflicts work
+in such processors and suggestions for their representation would be
+welcomed.
+@end ifset
+@ifset INTERNALS
@node Automaton pipeline description
@subsubsection Describing instruction pipeline characteristics
@cindex automaton based pipeline description
@@ -5523,7 +5706,7 @@ The following optional construction describes names of automata
generated and used for the pipeline hazards recognition. Sometimes
the generated finite state automaton used by the pipeline hazard
recognizer is large. If we use more than one automaton and bind functional
-units to the automata, the total size of the automata is usually
+units to the automata, the total size of the automata is usually
less than the size of the single automaton. If there is no one such
construction, only one finite state automaton is generated.
@@ -5554,16 +5737,23 @@ which the unit is bound. The automaton should be described in
construction @code{define_automaton}. You should give
@dfn{automaton-name}, if there is a defined automaton.
+The assignment of units to automata are constrained by the uses of the
+units in insn reservations. The most important constraint is: if a
+unit reservation is present on a particular cycle of an alternative
+for an insn reservation, then some unit from the same automaton must
+be present on the same cycle for the other alternatives of the insn
+reservation. The rest of the constraints are mentioned in the
+description of the subsequent constructions.
+
@findex define_query_cpu_unit
@cindex querying function unit reservations
The following construction describes CPU functional units analogously
-to @code{define_cpu_unit}. If we use automata without their
-minimization, the reservation of such units can be queried for an
-automaton state. The instruction scheduler never queries reservation
-of functional units for given automaton state. So as a rule, you
-don't need this construction. This construction could be used for
-future code generation goals (e.g. to generate @acronym{VLIW} insn
-templates).
+to @code{define_cpu_unit}. The reservation of such units can be
+queried for an automaton state. The instruction scheduler never
+queries reservation of functional units for given automaton state. So
+as a rule, you don't need this construction. This construction could
+be used for future code generation goals (e.g. to generate
+@acronym{VLIW} insn templates).
@smallexample
(define_query_cpu_unit @var{unit-names} [@var{automaton-name}])
@@ -5630,7 +5820,7 @@ expression according to the following syntax:
allof = allof "+" repeat
| repeat
-
+
repeat = element "*" number
| element
@@ -5712,23 +5902,31 @@ of insn @samp{store} (not a stored value).
@findex exclusion_set
@findex presence_set
+@findex final_presence_set
@findex absence_set
+@findex final_absence_set
@cindex VLIW
@cindex RISC
-Usually the following three constructions are used to describe
-@acronym{VLIW} processors (more correctly to describe a placement of
-small insns into @acronym{VLIW} insn slots). Although they can be
-used for @acronym{RISC} processors too.
+The following five constructions are usually used to describe
+@acronym{VLIW} processors, or more precisely, to describe a placement
+of small instructions into @acronym{VLIW} instruction slots. They
+can be used for @acronym{RISC} processors, too.
@smallexample
(exclusion_set @var{unit-names} @var{unit-names})
-(presence_set @var{unit-names} @var{unit-names})
-(absence_set @var{unit-names} @var{unit-names})
+(presence_set @var{unit-names} @var{patterns})
+(final_presence_set @var{unit-names} @var{patterns})
+(absence_set @var{unit-names} @var{patterns})
+(final_absence_set @var{unit-names} @var{patterns})
@end smallexample
@var{unit-names} is a string giving names of functional units
separated by commas.
+@var{patterns} is a string giving patterns of functional units
+separated by comma. Currently pattern is is one unit or units
+separated by white-spaces.
+
The first construction (@samp{exclusion_set}) means that each
functional unit in the first string can not be reserved simultaneously
with a unit whose name is in the second string and vice versa. For
@@ -5739,22 +5937,75 @@ point insns or only double floating point insns.
The second construction (@samp{presence_set}) means that each
functional unit in the first string can not be reserved unless at
-least one of units whose names are in the second string is reserved.
-This is an asymmetric relation. For example, it is useful for
-description that @acronym{VLIW} @samp{slot1} is reserved after
-@samp{slot0} reservation.
-
-The third construction (@samp{absence_set}) means that each functional
-unit in the first string can be reserved only if each unit whose name
-is in the second string is not reserved. This is an asymmetric
-relation (actually @samp{exclusion_set} is analogous to this one but
-it is symmetric). For example, it is useful for description that
-@acronym{VLIW} @samp{slot0} can not be reserved after @samp{slot1} or
-@samp{slot2} reservation.
+least one of pattern of units whose names are in the second string is
+reserved. This is an asymmetric relation. For example, it is useful
+for description that @acronym{VLIW} @samp{slot1} is reserved after
+@samp{slot0} reservation. We could describe it by the following
+construction
+
+@smallexample
+(presence_set "slot1" "slot0")
+@end smallexample
+
+Or @samp{slot1} is reserved only after @samp{slot0} and unit @samp{b0}
+reservation. In this case we could write
+
+@smallexample
+(presence_set "slot1" "slot0 b0")
+@end smallexample
+
+The third construction (@samp{final_presence_set}) is analogous to
+@samp{presence_set}. The difference between them is when checking is
+done. When an instruction is issued in given automaton state
+reflecting all current and planned unit reservations, the automaton
+state is changed. The first state is a source state, the second one
+is a result state. Checking for @samp{presence_set} is done on the
+source state reservation, checking for @samp{final_presence_set} is
+done on the result reservation. This construction is useful to
+describe a reservation which is actually two subsequent reservations.
+For example, if we use
+
+@smallexample
+(presence_set "slot1" "slot0")
+@end smallexample
+
+the following insn will be never issued (because @samp{slot1} requires
+@samp{slot0} which is absent in the source state).
+
+@smallexample
+(define_reservation "insn_and_nop" "slot0 + slot1")
+@end smallexample
+
+but it can be issued if we use analogous @samp{final_presence_set}.
+
+The forth construction (@samp{absence_set}) means that each functional
+unit in the first string can be reserved only if each pattern of units
+whose names are in the second string is not reserved. This is an
+asymmetric relation (actually @samp{exclusion_set} is analogous to
+this one but it is symmetric). For example, it is useful for
+description that @acronym{VLIW} @samp{slot0} can not be reserved after
+@samp{slot1} or @samp{slot2} reservation. We could describe it by the
+following construction
+
+@smallexample
+(absence_set "slot2" "slot0, slot1")
+@end smallexample
+
+Or @samp{slot2} can not be reserved if @samp{slot0} and unit @samp{b0}
+are reserved or @samp{slot1} and unit @samp{b1} are reserved. In
+this case we could write
+
+@smallexample
+(absence_set "slot2" "slot0 b0, slot1 b1")
+@end smallexample
All functional units mentioned in a set should belong to the same
automaton.
+The last construction (@samp{final_absence_set}) is analogous to
+@samp{absence_set} but checking is done on the result (state)
+reservation. See comments for @samp{final_presence_set}.
+
@findex automata_option
@cindex deterministic finite state automaton
@cindex nondeterministic finite state automaton
@@ -5797,6 +6048,14 @@ nondeterministic treatment means trying all alternatives, some of them
may be rejected by reservations in the subsequent insns. You can not
query functional unit reservations in nondeterministic automaton
states.
+
+@item
+@dfn{progress} means output of a progress bar showing how many states
+were generated so far for automaton being processed. This is useful
+during debugging a @acronym{DFA} description. If you see too many
+generated states, you could interrupt the generator of the pipeline
+hazard recognizer and try to figure out a reason for generation of the
+huge automaton.
@end itemize
As an example, consider a superscalar @acronym{RISC} machine which can
@@ -5855,6 +6114,8 @@ construction
@end smallexample
+@end ifset
+@ifset INTERNALS
@node Comparison of the two descriptions
@subsubsection Drawbacks of the old pipeline description
@cindex old pipeline description
@@ -5868,7 +6129,7 @@ construction
The old instruction level parallelism description and the pipeline
hazards recognizer based on it have the following drawbacks in
comparison with the @acronym{DFA}-based ones:
-
+
@itemize @bullet
@item
Each functional unit is believed to be reserved at the instruction
@@ -5908,6 +6169,8 @@ In an automaton based pipeline hazard recognizer, speed is not dependent
on processor complexity.
@end itemize
+@end ifset
+@ifset INTERNALS
@node Conditional Execution
@section Conditional Execution
@cindex conditional execution
@@ -5988,6 +6251,8 @@ generates a new pattern
"(%3) add %2,%1,%0")
@end smallexample
+@end ifset
+@ifset INTERNALS
@node Constant Definitions
@section Constant Definitions
@cindex constant definitions
diff --git a/contrib/gcc/doc/objc.texi b/contrib/gcc/doc/objc.texi
index a0c40f7296e6..481b51c09b85 100644
--- a/contrib/gcc/doc/objc.texi
+++ b/contrib/gcc/doc/objc.texi
@@ -1,5 +1,5 @@
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-@c 1999, 2000, 2001 Free Software Foundation, Inc.
+@c 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -41,7 +41,7 @@ Suppose for example you have a @code{FileStream} class that declares
@code{Stdin}, @code{Stdout} and @code{Stderr} as global variables, like
below:
-@example
+@smallexample
FileStream *Stdin = nil;
FileStream *Stdout = nil;
@@ -59,7 +59,7 @@ FileStream *Stderr = nil;
/* Other methods here */
@@end
-@end example
+@end smallexample
In this example, the initialization of @code{Stdin}, @code{Stdout} and
@code{Stderr} in @code{+initialize} occurs too late. The programmer can
@@ -73,7 +73,7 @@ just before entering @code{main}.
The correct solution of the above problem is to use the @code{+load}
method instead of @code{+initialize}:
-@example
+@smallexample
@@implementation FileStream
@@ -87,7 +87,7 @@ method instead of @code{+initialize}:
/* Other methods here */
@@end
-@end example
+@end smallexample
The @code{+load} is a method that is not overridden by categories. If a
class and a category of it both implement @code{+load}, both methods are
@@ -258,12 +258,12 @@ compiler on an i386 machine:
@item Objective-C type
@tab Compiler encoding
@item
-@example
+@smallexample
int a[10];
-@end example
+@end smallexample
@tab @code{[10i]}
@item
-@example
+@smallexample
struct @{
int i;
float f[3];
@@ -271,7 +271,7 @@ struct @{
int b:2;
char c;
@}
-@end example
+@end smallexample
@tab @code{@{?=i[3f]b128i3b131i2c@}}
@end multitable
@@ -343,7 +343,7 @@ Here is an example of how to use this feature. Suppose you want to
implement a class whose instances hold a weak pointer reference; the
following class does this:
-@example
+@smallexample
@@interface WeakPointer : Object
@{
@@ -375,7 +375,7 @@ following class does this:
@@end
-@end example
+@end smallexample
Weak pointers are supported through a new type character specifier
represented by the @samp{!} character. The
@@ -391,9 +391,9 @@ GNU Objective-C provides constant string objects that are generated
directly by the compiler. You declare a constant string object by
prefixing a C constant string with the character @samp{@@}:
-@example
+@smallexample
id myString = @@"this is a constant string object";
-@end example
+@end smallexample
The constant string objects are by default instances of the
@code{NXConstantString} class which is provided by the GNU Objective-C
@@ -406,7 +406,7 @@ a new command line options @option{-fconstant-string-class=@var{class-name}}.
The provided class should adhere to a strict structure, the same
as @code{NXConstantString}'s structure:
-@example
+@smallexample
@@interface MyConstantStringClass
@{
@@ -416,7 +416,7 @@ as @code{NXConstantString}'s structure:
@}
@@end
-@end example
+@end smallexample
@code{NXConstantString} inherits from @code{Object}; user class
libraries may choose to inherit the customized constant string class
@@ -455,9 +455,9 @@ forgotten, we are documenting it here.
The keyword @code{@@compatibility_alias} allows you to define a class name
as equivalent to another class name. For example:
-@example
+@smallexample
@@compatibility_alias WOApplication GSWApplication;
-@end example
+@end smallexample
tells the compiler that each time it encounters @code{WOApplication} as
a class name, it should replace it with @code{GSWApplication} (that is,
diff --git a/contrib/gcc/doc/passes.texi b/contrib/gcc/doc/passes.texi
index 9a1941b49492..6bbc61c2822d 100644
--- a/contrib/gcc/doc/passes.texi
+++ b/contrib/gcc/doc/passes.texi
@@ -1,5 +1,5 @@
-@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-@c 1999, 2000, 2001 Free Software Foundation, Inc.
+@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+@c 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -12,7 +12,10 @@
@cindex top level of compiler
The overall control structure of the compiler is in @file{toplev.c}. This
file is responsible for initialization, decoding arguments, opening and
-closing files, and sequencing the passes.
+closing files, and sequencing the passes. Routines for emitting
+diagnostic messages are defined in @file{diagnostic.c}. The files
+@file{pretty-print.h} and @file{pretty-print.c} provide basic support
+for language-independent pretty-printing.
@cindex parsing pass
The parsing pass is invoked only once, to parse the entire input. A
@@ -73,54 +76,27 @@ performed by cpplib, which is covered in separate documentation. In
particular, the internals are covered in @xref{Top, ,Cpplib internals,
cppinternals, Cpplib Internals}.
-@c Avoiding overfull is tricky here.
-The source files to parse C are
-@file{c-convert.c},
-@file{c-decl.c},
-@file{c-errors.c},
-@file{c-lang.c},
-@file{c-objc-common.c},
-@file{c-parse.in},
-@file{c-aux-info.c},
-and
-@file{c-typeck.c},
-along with a header file
-@file{c-tree.h}
-and some files shared with Objective-C and C++.
-
-The source files for parsing C++ are in @file{cp/}.
-They are @file{parse.y},
-@file{class.c},
-@file{cvt.c}, @file{decl.c}, @file{decl2.c},
-@file{except.c},
-@file{expr.c}, @file{init.c}, @file{lex.c},
-@file{method.c}, @file{ptree.c},
-@file{search.c}, @file{spew.c},
-@file{semantics.c}, @file{tree.c},
-@file{typeck2.c}, and
-@file{typeck.c}, along with header files @file{cp-tree.def},
-@file{cp-tree.h}, and @file{decl.h}.
-
-The special source files for parsing Objective-C are in @file{objc/}.
-They are @file{objc-act.c}, @file{objc-tree.def}, and @file{objc-act.h}.
-Certain C-specific files are used for this as well.
-
-The files
-@file{c-common.c},
+The source files to parse C are found in the toplevel directory, and
+by convention are named @file{c-*}. Some of these are also used by
+the other C-like languages: @file{c-common.c},
@file{c-common.def},
@file{c-format.c},
@file{c-opts.c},
@file{c-pragma.c},
@file{c-semantics.c},
-and
@file{c-lex.c},
-along with header files
+@file{c-incpath.c},
+@file{c-ppoutput.c},
+@file{c-cppbuiltin.c},
@file{c-common.h},
@file{c-dump.h},
+@file{c.opt},
+@file{c-incpath.h}
and
@file{c-pragma.h},
-are also used for all of the above languages.
+Files specific to each language are in subdirectories named after the
+language in question, like @file{ada}, @file{objc}, @file{cp} (for C++).
@cindex Tree optimization
@item
@@ -261,57 +237,6 @@ the second conditional test. The source code for this pass is in
@file{jump.c}. This optimization is only performed if
@option{-fthread-jumps} is enabled.
-@cindex SSA optimizations
-@cindex Single Static Assignment optimizations
-@opindex fssa
-@item
-Static Single Assignment (SSA) based optimization passes. The
-SSA conversion passes (to/from) are turned on by the @option{-fssa}
-option (it is also done automatically if you enable an SSA optimization pass).
-These passes utilize a form called Static Single Assignment. In SSA form,
-each variable (pseudo register) is only set once, giving you def-use
-and use-def chains for free, and enabling a lot more optimization
-passes to be run in linear time.
-Conversion to and from SSA form is handled by functions in
-@file{ssa.c}.
-
-@opindex de
-The option @option{-de} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.ssa} to
-the input file name.
-@itemize @bullet
-@cindex SSA Conditional Constant Propagation
-@cindex Conditional Constant Propagation, SSA based
-@cindex conditional constant propagation
-@opindex fssa-ccp
-@item
-SSA Conditional Constant Propagation. Turned on by the @option{-fssa-ccp}
-option. This pass performs conditional constant propagation to simplify
-instructions including conditional branches. This pass is more aggressive
-than the constant propagation done by the CSE and GCSE passes, but operates
-in linear time.
-
-@opindex dW
-The option @option{-dW} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.ssaccp} to
-the input file name.
-
-@cindex SSA DCE
-@cindex DCE, SSA based
-@cindex dead code elimination
-@opindex fssa-dce
-@item
-SSA Aggressive Dead Code Elimination. Turned on by the @option{-fssa-dce}
-option. This pass performs elimination of code considered unnecessary because
-it has no externally visible effects on the program. It operates in
-linear time.
-
-@opindex dX
-The option @option{-dX} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.ssadce} to
-the input file name.
-@end itemize
-
@cindex common subexpression elimination
@cindex constant propagation
@item
@@ -365,9 +290,41 @@ Its source files are @file{loop.c} and @file{unroll.c}, plus the header
some functions in @file{integrate.c} and the header @file{integrate.h}.
Loop dependency analysis routines are contained in @file{dependence.c}.
+Second loop optimization pass takes care of basic block level optimizations --
+unrolling, peeling and unswitching loops. The source files are
+@file{cfgloopanal.c} and @file{cfgloopmanip.c} containing generic loop
+analysis and manipulation code, @file{loop-init.c} with initialization and
+finalization code, @file{loop-unswitch.c} for loop unswitching and
+@file{loop-unroll.c} for loop unrolling and peeling.
+
@opindex dL
The option @option{-dL} causes a debugging dump of the RTL code after
-this pass. This dump file's name is made by appending @samp{.loop} to
+these passes. The dump file names are made by appending @samp{.loop} and
+@samp{.loop2} to the input file name.
+
+@cindex jump bypassing
+@item
+Jump bypassing. This pass is an aggressive form of GCSE that transforms
+the control flow graph of a function by propagating constants into
+conditional branch instructions.
+
+The source file for this pass is @file{gcse.c}.
+
+@opindex dG
+The option @option{-dG} causes a debugging dump of the RTL code after
+this pass. This dump file's name is made by appending @samp{.bypass}
+to the input file name.
+
+@cindex web construction
+@item
+Simple optimization pass that splits independent uses of each pseudo
+increasing effect of other optimizations. This can improve effect of the
+other transformation, such as CSE or register allocation.
+Its source files are @file{web.c}.
+
+@opindex dZ
+The option @option{-dZ} causes a debugging dump of the RTL code after
+this pass. This dump file's name is made by appending @samp{.web} to
the input file name.
@item
diff --git a/contrib/gcc/doc/portability.texi b/contrib/gcc/doc/portability.texi
index b05698dcfa69..e65e979fccab 100644
--- a/contrib/gcc/doc/portability.texi
+++ b/contrib/gcc/doc/portability.texi
@@ -1,5 +1,5 @@
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-@c 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+@c 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -18,9 +18,9 @@ GCC gets most of the information about the target machine from a machine
description which gives an algebraic formula for each of the machine's
instructions. This is a very clean way to describe the target. But when
the compiler needs information that is difficult to express in this
-fashion, I have not hesitated to define an ad-hoc parameter to the machine
-description. The purpose of portability is to reduce the total work needed
-on the compiler; it was not of interest for its own sake.
+fashion, ad-hoc parameters have been defined for machine descriptions.
+The purpose of portability is to reduce the total work needed on the
+compiler; it was not of interest for its own sake.
@cindex endianness
@cindex autoincrement addressing, availability
@@ -31,9 +31,10 @@ significant byte has the highest or lowest address of the bytes in a word)
and the availability of autoincrement addressing. In the RTL-generation
pass, it is often necessary to have multiple strategies for generating code
for a particular kind of syntax tree, strategies that are usable for different
-combinations of parameters. Often I have not tried to address all possible
-cases, but only the common ones or only the ones that I have encountered.
-As a result, a new target may require additional strategies. You will know
+combinations of parameters. Often, not all possible cases have been
+addressed, but only the common ones or only the ones that have been
+encountered. As a result, a new target may require additional
+strategies. You will know
if this happens because the compiler will call @code{abort}. Fortunately,
the new strategies can be added in a machine-independent fashion, and will
affect only the target machines that need them.
diff --git a/contrib/gcc/doc/rtl.texi b/contrib/gcc/doc/rtl.texi
index 605aad05f257..6fcce634f818 100644
--- a/contrib/gcc/doc/rtl.texi
+++ b/contrib/gcc/doc/rtl.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 1988, 1989, 1992, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+@c Copyright (C) 1988, 1989, 1992, 1994, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
@c Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -23,6 +23,7 @@ form uses nested parentheses to indicate the pointers in the internal form.
* RTL Objects:: Expressions vs vectors vs strings vs integers.
* RTL Classes:: Categories of RTL expression objects, and their structure.
* Accessors:: Macros to access expression operands or vector elts.
+* Special Accessors:: Macros to access specific annotations on RTL.
* Flags:: Other flags in an RTL expression.
* Machine Modes:: Describing the size and format of a datum.
* Constants:: Expressions with constant values.
@@ -98,7 +99,7 @@ null pointers are used instead.
@findex PUT_CODE
Expressions are classified by @dfn{expression codes} (also called RTX
codes). The expression code is a name defined in @file{rtl.def}, which is
-also (in upper case) a C enumeration constant. The possible expression
+also (in uppercase) a C enumeration constant. The possible expression
codes and their meanings are machine-independent. The code of an RTX can
be extracted with the macro @code{GET_CODE (@var{x})} and altered with
@code{PUT_CODE (@var{x}, @var{newcode})}.
@@ -117,8 +118,8 @@ Expressions are written as parentheses containing the name of the
expression type, its flags and machine mode if any, and then the operands
of the expression (separated by spaces).
-Expression code names in the @samp{md} file are written in lower case,
-but when they appear in C code they are written in upper case. In this
+Expression code names in the @samp{md} file are written in lowercase,
+but when they appear in C code they are written in uppercase. In this
manual, they are shown as follows: @code{const_int}.
@cindex (nil)
@@ -307,16 +308,16 @@ Operands of expressions are accessed using the macros @code{XEXP},
two arguments: an expression-pointer (RTX) and an operand number
(counting from zero). Thus,
-@example
+@smallexample
XEXP (@var{x}, 2)
-@end example
+@end smallexample
@noindent
accesses operand 2 of expression @var{x}, as an expression.
-@example
+@smallexample
XINT (@var{x}, 2)
-@end example
+@end smallexample
@noindent
accesses the same operand as an integer. @code{XSTR}, used in the same
@@ -368,6 +369,125 @@ All the macros defined in this section expand into lvalues and therefore
can be used to assign the operands, lengths and vector elements as well as
to access them.
+@node Special Accessors
+@section Access to Special Operands
+@cindex access to special operands
+
+Some RTL nodes have special annotations associated with them.
+
+@table @code
+@item MEM
+@table @code
+@findex MEM_ALIAS_SET
+@item MEM_ALIAS_SET (@var{x})
+If 0, @var{x} is not in any alias set, and may alias anything. Otherwise,
+@var{x} can only alias @code{MEM}s in a conflicting alias set. This value
+is set in a language-dependent manner in the front-end, and should not be
+altered in the back-end. In some front-ends, these numbers may correspond
+in some way to types, or other language-level entities, but they need not,
+and the back-end makes no such assumptions.
+These set numbers are tested with @code{alias_sets_conflict_p}.
+
+@findex MEM_EXPR
+@item MEM_EXPR (@var{x})
+If this register is known to hold the value of some user-level
+declaration, this is that tree node. It may also be a
+@code{COMPONENT_REF}, in which case this is some field reference,
+and @code{TREE_OPERAND (@var{x}, 0)} contains the declaration,
+or another @code{COMPONENT_REF}, or null if there is no compile-time
+object associated with the reference.
+
+@findex MEM_OFFSET
+@item MEM_OFFSET (@var{x})
+The offset from the start of @code{MEM_EXPR} as a @code{CONST_INT} rtx.
+
+@findex MEM_SIZE
+@item MEM_SIZE (@var{x})
+The size in bytes of the memory reference as a @code{CONST_INT} rtx.
+This is mostly relevant for @code{BLKmode} references as otherwise
+the size is implied by the mode.
+
+@findex MEM_ALIGN
+@item MEM_ALIGN (@var{x})
+The known alignment in bits of the memory reference.
+@end table
+
+@item REG
+@table @code
+@findex ORIGINAL_REGNO
+@item ORIGINAL_REGNO (@var{x})
+This field holds the number the register ``originally'' had; for a
+pseudo register turned into a hard reg this will hold the old pseudo
+register number.
+
+@findex REG_EXPR
+@item REG_EXPR (@var{x})
+If this register is known to hold the value of some user-level
+declaration, this is that tree node.
+
+@findex REG_OFFSET
+@item REG_OFFSET (@var{x})
+If this register is known to hold the value of some user-level
+declaration, this is the offset into that logical storage.
+@end table
+
+@item SYMBOL_REF
+@table @code
+@findex SYMBOL_REF_DECL
+@item SYMBOL_REF_DECL (@var{x})
+If the @code{symbol_ref} @var{x} was created for a @code{VAR_DECL} or
+a @code{FUNCTION_DECL}, that tree is recorded here. If this value is
+null, then @var{x} was created by back end code generation routines,
+and there is no associated front end symbol table entry.
+
+@code{SYMBOL_REF_DECL} may also point to a tree of class @code{'c'},
+that is, some sort of constant. In this case, the @code{symbol_ref}
+is an entry in the per-file constant pool; again, there is no associated
+front end symbol table entry.
+
+@findex SYMBOL_REF_FLAGS
+@item SYMBOL_REF_FLAGS (@var{x})
+In a @code{symbol_ref}, this is used to communicate various predicates
+about the symbol. Some of these are common enough to be computed by
+common code, some are specific to the target. The common bits are:
+
+@table @code
+@findex SYMBOL_REF_FUNCTION_P
+@findex SYMBOL_FLAG_FUNCTION
+@item SYMBOL_FLAG_FUNCTION
+Set if the symbol refers to a function.
+
+@findex SYMBOL_REF_LOCAL_P
+@findex SYMBOL_FLAG_LOCAL
+@item SYMBOL_FLAG_LOCAL
+Set if the symbol is local to this ``module''.
+See @code{TARGET_BINDS_LOCAL_P}.
+
+@findex SYMBOL_REF_EXTERNAL_P
+@findex SYMBOL_FLAG_EXTERNAL
+@item SYMBOL_FLAG_EXTERNAL
+Set if this symbol is not defined in this translation unit.
+Note that this is not the inverse of @code{SYMBOL_FLAG_LOCAL}.
+
+@findex SYMBOL_REF_SMALL_P
+@findex SYMBOL_FLAG_SMALL
+@item SYMBOL_FLAG_SMALL
+Set if the symbol is located in the small data section.
+See @code{TARGET_IN_SMALL_DATA_P}.
+
+@findex SYMBOL_FLAG_TLS_SHIFT
+@findex SYMBOL_REF_TLS_MODEL
+@item SYMBOL_REF_TLS_MODEL (@var{x})
+This is a multi-bit field accessor that returns the @code{tls_model}
+to be used for a thread-local storage symbol. It returns zero for
+non-thread-local symbols.
+@end table
+
+Bits beginning with @code{SYMBOL_FLAG_MACH_DEP} are available for
+the target's use.
+@end table
+@end table
+
@node Flags
@section Flags in an RTL Expression
@cindex flags in RTL expression
@@ -515,6 +635,13 @@ In @code{mem}, @code{asm_operands}, and @code{asm_input} expressions,
nonzero for volatile memory references.
Stored in the @code{volatil} field and printed as @samp{/v}.
+@findex MEM_NOTRAP_P
+@cindex @code{mem} and @samp{/c}
+@cindex @code{call}, in @code{mem}
+@item MEM_NOTRAP_P (@var{x})
+In @code{mem}, nonzero for memory references that will not trap.
+Stored in the @code{call} field and printed as @samp{/c}.
+
@findex REG_FUNCTION_VALUE_P
@cindex @code{reg} and @samp{/i}
@cindex @code{integrated}, in @code{reg}
@@ -732,7 +859,7 @@ These are the fields to which the above macros refer:
@findex call
@cindex @samp{/c} in RTL dump
@item call
-This flag is currently unused.
+In a @code{mem}, 1 means that the memory reference will not trap.
In an RTL dump, this flag is represented as @samp{/c}.
@@ -1723,9 +1850,9 @@ Represents the signed product of the values represented by @var{x} and
Some machines support a multiplication that generates a product wider
than the operands. Write the pattern for this as
-@example
+@smallexample
(mult:@var{m} (sign_extend:@var{m} @var{x}) (sign_extend:@var{m} @var{y}))
-@end example
+@end smallexample
where @var{m} is wider than the modes of @var{x} and @var{y}, which need
not be the same.
@@ -1747,9 +1874,9 @@ Some machines have division instructions in which the operands and
quotient widths are not all the same; you should represent
such instructions using @code{truncate} and @code{sign_extend} as in,
-@example
+@smallexample
(truncate:@var{m1} (div:@var{m2} @var{x} (sign_extend:@var{m2} @var{y})))
-@end example
+@end smallexample
@findex udiv
@cindex unsigned division
@@ -1862,6 +1989,35 @@ Represents one plus the index of the least significant 1-bit in
zero if @var{x} is zero.) The mode of @var{x} need not be @var{m};
depending on the target machine, various mode combinations may be
valid.
+
+@findex clz
+@item (clz:@var{m} @var{x})
+Represents the number of leading 0-bits in @var{x}, represented as an
+integer of mode @var{m}, starting at the most significant bit position.
+If @var{x} is zero, the value is determined by
+@code{CLZ_DEFINED_VALUE_AT_ZERO}. Note that this is one of
+the few expressions that is not invariant under widening. The mode of
+@var{x} will usually be an integer mode.
+
+@findex ctz
+@item (ctz:@var{m} @var{x})
+Represents the number of trailing 0-bits in @var{x}, represented as an
+integer of mode @var{m}, starting at the least significant bit position.
+If @var{x} is zero, the value is determined by
+@code{CTZ_DEFINED_VALUE_AT_ZERO}. Except for this case,
+@code{ctz(x)} is equivalent to @code{ffs(@var{x}) - 1}. The mode of
+@var{x} will usually be an integer mode.
+
+@findex popcount
+@item (popcount:@var{m} @var{x})
+Represents the number of 1-bits in @var{x}, represented as an integer of
+mode @var{m}. The mode of @var{x} will usually be an integer mode.
+
+@findex parity
+@item (parity:@var{m} @var{x})
+Represents the number of 1-bits modulo 2 in @var{x}, represented as an
+integer of mode @var{m}. The mode of @var{x} will usually be an integer
+mode.
@end table
@node Comparisons
@@ -2054,11 +2210,6 @@ Describes a vector concat operation. The result is a concatenation of the
vectors @var{vec1} and @var{vec2}; its length is the sum of the lengths of
the two inputs.
-@findex vec_const
-@item (vec_const:@var{m} @var{subparts})
-This describes a constant vector. @var{subparts} is a @code{parallel} that
-contains a constant for each of the subparts of the vector.
-
@findex vec_duplicate
@item (vec_duplicate:@var{m} @var{vec})
This operation converts a small vector into a larger one by duplicating the
@@ -2081,9 +2232,9 @@ operation requires two operands of the same machine mode.
Therefore, the byte-sized operand is enclosed in a conversion
operation, as in
-@example
+@smallexample
(plus:SI (sign_extend:SI (reg:QI 34)) (reg:SI 80))
-@end example
+@end smallexample
The conversion operation is not a mere placeholder, because there
may be more than one way of converting from a given starting mode
@@ -2227,7 +2378,7 @@ rest of the register receives an undefined value. Likewise, if
the mode of the register, the rest of the register can be changed in
an undefined way.
-If @var{lval} is a @code{strict_low_part} or @code{zero_extract}
+If @var{lval} is a @code{strict_low_part} or @code{zero_extract}
of a @code{subreg}, then the part of the register specified by the
machine mode of the @code{subreg} is given the value @var{x} and
the rest of the register is not changed.
@@ -2311,7 +2462,7 @@ trouble to describe the values that are stored, but it is essential to
inform the compiler that the registers will be altered, lest it
attempt to keep data in them across the string instruction.
-If @var{x} is @code{(mem:BLK (const_int 0))} or
+If @var{x} is @code{(mem:BLK (const_int 0))} or
@code{(mem:BLK (scratch))}, it means that all memory
locations must be presumed clobbered. If @var{x} is a @code{parallel},
it has the same meaning as a @code{parallel} in a @code{set} expression.
@@ -2416,10 +2567,10 @@ side effect expressions---expressions of code @code{set}, @code{call},
side-effects are computed, and second all the actual side-effects are
performed. For example,
-@example
+@smallexample
(parallel [(set (reg:SI 1) (mem:SI (reg:SI 1)))
(set (mem:SI (reg:SI 1)) (reg:SI 1))])
-@end example
+@end smallexample
@noindent
says unambiguously that the values of hard register 1 and the memory
@@ -2432,13 +2583,13 @@ expect the result of one @code{set} to be available for the next one.
For example, people sometimes attempt to represent a jump-if-zero
instruction this way:
-@example
+@smallexample
(parallel [(set (cc0) (reg:SI 34))
(set (pc) (if_then_else
(eq (cc0) (const_int 0))
(label_ref @dots{})
(pc)))])
-@end example
+@end smallexample
@noindent
But this is incorrect, because it says that the jump condition depends
@@ -2565,9 +2716,9 @@ by is the length in bytes of the machine mode of the containing memory
reference of which this expression serves as the address. Here is an
example of its use:
-@example
+@smallexample
(mem:DF (pre_dec:SI (reg:SI 39)))
-@end example
+@end smallexample
@noindent
This says to decrement pseudo register 39 by the length of a @code{DFmode}
@@ -2727,16 +2878,16 @@ chain delimited by these insns, the @code{NEXT_INSN} and
@code{PREV_INSN} pointers must always correspond: if @var{insn} is not
the first insn,
-@example
+@smallexample
NEXT_INSN (PREV_INSN (@var{insn})) == @var{insn}
-@end example
+@end smallexample
@noindent
is always true and if @var{insn} is not the last insn,
-@example
+@smallexample
PREV_INSN (NEXT_INSN (@var{insn})) == @var{insn}
-@end example
+@end smallexample
@noindent
is always true.
@@ -3198,13 +3349,6 @@ destination register.
Thus, compiler passes prior to register allocation need only check for
@code{REG_EQUAL} notes and passes subsequent to register allocation
need only check for @code{REG_EQUIV} notes.
-
-@findex REG_WAS_0
-@item REG_WAS_0
-The single output of this insn contained zero before this insn.
-@var{op} is the insn that set it to zero. You can rely on this note if
-it is present and @var{op} has not been deleted or turned into a @code{note};
-its absence implies nothing.
@end table
These notes describe linkages between insns. They occur in pairs: one
@@ -3315,9 +3459,9 @@ RTL expression code, @code{call}.
@cindex @code{call} usage
A @code{call} expression has two operands, as follows:
-@example
+@smallexample
(call (mem:@var{fm} @var{addr}) @var{nbytes})
-@end example
+@end smallexample
@noindent
Here @var{nbytes} is an operand that represents the number of bytes of
@@ -3335,10 +3479,10 @@ For a subroutine that returns a value whose mode is not @code{BLKmode},
the value is returned in a hard register. If this register's number is
@var{r}, then the body of the call insn looks like this:
-@example
+@smallexample
(set (reg:@var{m} @var{r})
(call (mem:@var{fm} @var{addr}) @var{nbytes}))
-@end example
+@end smallexample
@noindent
This RTL expression makes it clear (to the optimizer passes) that the
diff --git a/contrib/gcc/doc/sourcebuild.texi b/contrib/gcc/doc/sourcebuild.texi
index c2222c04d4c3..af57f3aafb1f 100644
--- a/contrib/gcc/doc/sourcebuild.texi
+++ b/contrib/gcc/doc/sourcebuild.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+@c Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -14,7 +14,7 @@ which it is presumed that you are familiar.
* Configure Terms:: Configuration terminology and history.
* Top Level:: The top level source directory.
* gcc Directory:: The @file{gcc} subdirectory.
-* Test Suites:: The GCC test suites.
+* Testsuites:: The GCC testsuites.
@end menu
@include configterms.texi
@@ -44,7 +44,7 @@ front end.
@item gcc
The main sources of GCC itself (except for runtime libraries),
including optimizers, support for different target architectures,
-language front ends, and test suites. @xref{gcc Directory, , The
+language front ends, and testsuites. @xref{gcc Directory, , The
@file{gcc} Subdirectory}, for details.
@item include
@@ -91,7 +91,7 @@ configure, The GNU configure and build system}, for details.
The @file{gcc} directory contains many files that are part of the C
sources of GCC, other files used as part of the configuration and
build process, and subdirectories including documentation and a
-test suite. The files that are sources of GCC are documented in a
+testsuite. The files that are sources of GCC are documented in a
separate chapter. @xref{Passes, , Passes and Files of the Compiler}.
@menu
@@ -159,8 +159,8 @@ by @samp{make gcc.pot}, and @file{EXCLUDES}, a list of files from
which messages should not be extracted.
@item testsuite
-The GCC test suites (except for those for runtime libraries).
-@xref{Test Suites}.
+The GCC testsuites (except for those for runtime libraries).
+@xref{Testsuites}.
@end table
@node Configuration
@@ -168,14 +168,15 @@ The GCC test suites (except for those for runtime libraries).
The @file{gcc} directory is configured with an Autoconf-generated
script @file{configure}. The @file{configure} script is generated
-from @file{configure.in} and @file{aclocal.m4}. From the files
-@file{configure.in} and @file{acconfig.h}, Autoheader generates the
+from @file{configure.ac} and @file{aclocal.m4}. From the files
+@file{configure.ac} and @file{acconfig.h}, Autoheader generates the
file @file{config.in}. The file @file{cstamp-h.in} is used as a
timestamp.
@menu
* Config Fragments:: Scripts used by @file{configure}.
-* System Config:: The @file{config.gcc} file.
+* System Config:: The @file{config.build}, @file{config.host}, and
+ @file{config.gcc} files.
* Configuration Files:: Files created by running @file{configure}.
@end menu
@@ -191,10 +192,14 @@ files, kept in the top level directory, are used. FIXME: when is the
the top level one) used?
@item The file @file{config.gcc} is used to handle configuration
-specific to the particular build, host or target machine. (In
-general, this should only be used for features that cannot reasonably
-be tested in Autoconf feature tests.) @xref{System Config, , The
-@file{config.gcc} File}, for details of the contents of this file.
+specific to the particular target machine. The file
+@file{config.build} is used to handle configuration specific to the
+particular build machine. The file @file{config.host} is used to handle
+configuration specific to the particular host machine. (In general,
+these should only be used for features that cannot reasonably be tested in
+Autoconf feature tests.)
+@xref{System Config, , The @file{config.build}; @file{config.host};
+and @file{config.gcc} Files}, for details of the contents of these files.
@item Each language subdirectory has a file
@file{@var{language}/config-lang.in} that is used for
@@ -206,9 +211,22 @@ creating the output of @file{configure}.
@end itemize
@node System Config
-@subsubsection The @file{config.gcc} File
+@subsubsection The @file{config.build}; @file{config.host}; and @file{config.gcc} Files
-FIXME: document the contents of this file, and what variables should
+The @file{config.build} file contains specific rules for particular systems
+which GCC is built on. This should be used as rarely as possible, as the
+behavior of the build system can always be detected by autoconf.
+
+The @file{config.host} file contains specific rules for particular systems
+which GCC will run on. This is rarely needed.
+
+The @file{config.gcc} file contains specific rules for particular systems
+which GCC will generate code for. This is usually needed.
+
+Each file has a list of the shell variables it sets, with descriptions, at the
+top of the file.
+
+FIXME: document the contents of these files, and what variables should
be set to control build, host and target configuration.
@include configfiles.texi
@@ -258,7 +276,7 @@ headers to work with GCC, some other headers may also be installed in
@file{config} to be installed on some systems.
GCC installs its own version of @code{<float.h>}, from @file{ginclude/float.h}.
-This is done to cope with command-line options that change the
+This is done to cope with command-line options that change the
representation of floating point numbers.
GCC also installs its own version of @code{<limits.h>}; this is generated
@@ -432,6 +450,13 @@ files for that front end. @xref{Front End Directory, , The Front End
A mention of the language in the list of supported languages in
@file{gcc/doc/install.texi}.
@item
+A mention of the name under which the language's runtime library is
+recognized by @option{--enable-shared=@var{package}} in the
+documentation of that option in @file{gcc/doc/install.texi}.
+@item
+A mention of any special prerequisites for building the front end in
+the documentation of prerequisites in @file{gcc/doc/install.texi}.
+@item
Details of contributors to that front end in
@file{gcc/doc/contrib.texi}. If the details are in that front end's
own manual then there should be a link to that manual's list in
@@ -450,9 +475,9 @@ Details of source file suffixes for that language and @option{-x
Entries in @code{default_compilers} in @file{gcc.c} for source file
suffixes for that language.
@item
-Preferably test suites, which may be under @file{gcc/testsuite} or
+Preferably testsuites, which may be under @file{gcc/testsuite} or
runtime library directories. FIXME: document somewhere how to write
-test suite harnesses.
+testsuite harnesses.
@item
Probably a runtime library for the language, outside the @file{gcc}
directory. FIXME: document this further.
@@ -530,7 +555,12 @@ setting of @code{language} in @file{config-lang.in}) for the following
values of @code{@var{hook}}, and any other Makefile rules required to
build those targets (which may if necessary use other Makefiles
specified in @code{outputs} in @file{config-lang.in}, although this is
-deprecated).
+deprecated). Some hooks are defined by using a double-colon rule for
+@code{@var{hook}}, rather than by using a target of form
+@code{@var{lang}.@var{hook}}. These hooks are called ``double-colon
+hooks'' below. It also adds any testsuite targets that can use the
+standard rule in @file{gcc/Makefile.in} to the variable
+@code{lang_checks}.
@table @code
@item all.build
@@ -538,8 +568,11 @@ deprecated).
@itemx start.encap
@itemx rest.encap
FIXME: exactly what goes in each of these targets?
+@item tags
+Build an @command{etags} @file{TAGS} file in the language subdirectory
+in the source tree.
@item info
-Build info documentation for the front end, in the source directory.
+Build info documentation for the front end, in the build directory.
This target is only called by @samp{make bootstrap} if a suitable
version of @command{makeinfo} is available, so does not need to check
for this, and should fail if an error occurs.
@@ -547,9 +580,10 @@ for this, and should fail if an error occurs.
Build DVI documentation for the front end, in the build directory.
This should be done using @code{$(TEXI2DVI)}, with appropriate
@option{-I} arguments pointing to directories of included files.
-@item generated-manpages
+This hook is a double-colon hook.
+@item man
Build generated man pages for the front end from Texinfo manuals
-(@pxref{Man Page Generation}), in the source directory. This target
+(@pxref{Man Page Generation}), in the build directory. This target
is only called if the necessary tools are available, but should ignore
errors so as not to stop the build if errors occur; man pages are
optional and the tools involved may be installed in a broken way.
@@ -558,17 +592,26 @@ FIXME: what is this target for?
@item install-common
Install everything that is part of the front end, apart from the
compiler executables listed in @code{compilers} in
-@file{config-lang.in} that are installed in @file{@var{libsubdir}} by
-the main @file{Makefile}.
+@file{config-lang.in}.
@item install-info
Install info documentation for the front end, if it is present in the
-source directory. (It may not be present if a suitable version of
-@command{makeinfo} was not installed.) This target should run the
-command @command{install-info} to update the info directory, but
-should ignore errors when running that command.
+source directory. This target should have dependencies on info files
+that should be installed. This hook is a double-colon hook.
@item install-man
Install man pages for the front end. This target should ignore
errors.
+@item srcextra
+Copies its dependencies into the source directory. This generally should
+be used for generated files such as @file{gcc/c-parse.c} which are not
+present in CVS, but should be included in any release tarballs. This
+target will be executed during a bootstrap if
+@samp{--enable-generated-files-in-srcdir} was specified as a
+@file{configure} option.
+@item srcinfo
+@itemx srcman
+Copies its dependencies into the source directory. These targets will be
+executed during a bootstrap if @samp{--enable-generated-files-in-srcdir}
+was specified as a @file{configure} option.
@item uninstall
Uninstall files installed by installing the compiler. This is
currently documented not to be supported, so the hook need not do
@@ -576,28 +619,28 @@ anything.
@item mostlyclean
@itemx clean
@itemx distclean
-@itemx extraclean
@itemx maintainer-clean
-Except for @code{extraclean}, the language parts of the standard GNU
+The language parts of the standard GNU
@samp{*clean} targets. @xref{Standard Targets, , Standard Targets for
Users, standards, GNU Coding Standards}, for details of the standard
-targets. @code{extraclean} does @code{distclean} and also deletes
-anything likely to be found in the source directory that shouldn't be
-in the distribution. For GCC, @code{maintainer-clean} should delete
+targets. For GCC, @code{maintainer-clean} should delete
all generated files in the source directory that are not checked into
CVS, but should not delete anything checked into CVS@.
@item stage1
@itemx stage2
@itemx stage3
@itemx stage4
+@itemx stageprofile
+@itemx stagefeedback
Move to the stage directory files not included in @code{stagestuff} in
@file{config-lang.in} or otherwise moved by the main @file{Makefile}.
@end table
-@item lang-options.h
-This file provides entries for @code{documented_lang_options} in
-@file{toplev.c} describing command-line options the front end accepts
-for @option{--help} output.
+@item lang.opt
+This file registers the set of switches that the front end accepts on
+the command line, and their --help text. The file format is
+documented in the file @file{c.opt}. These files are processed by the
+script @file{opts.sh}.
@item lang-specs.h
This file provides entries for @code{default_compilers} in
@file{gcc.c} which override the default of giving an error that a
@@ -637,15 +680,15 @@ that should not be configured if this front end is not built.
If defined to @samp{no}, this language front end is not built unless
enabled in a @option{--enable-languages} argument. Otherwise, front
ends are built by default, subject to any special logic in
-@file{configure.in} (as is present to disable the Ada front end if the
+@file{configure.ac} (as is present to disable the Ada front end if the
Ada compiler is not already installed).
@item boot_language
If defined to @samp{yes}, this front end is built in stage 1 of the
bootstrap. This is only relevant to front ends written in their own
languages.
@item compilers
-If defined, a space-separated list of compiler executables that should
-be installed in @file{@var{libsubdir}}. The names here will each end
+If defined, a space-separated list of compiler executables that will
+be run by the driver. The names here will each end
with @samp{\$(exeext)}.
@item stagestuff
If defined, a space-separated list of files that should be moved to
@@ -732,6 +775,9 @@ following are also necessary:
An entry for the target architecture in @file{readings.html} on the
GCC web site, with any relevant links.
@item
+Details of the properties of the back end and target architecture in
+@file{backends.html} on the GCC web site.
+@item
A news item about the contribution of support for that target
architecture, in @file{index.html} on the GCC web site.
@item
@@ -741,39 +787,48 @@ but it would be unusual to add support for a target that does not have
a maintainer when support is added.
@end itemize
-@node Test Suites
-@section Test Suites
+@node Testsuites
+@section Testsuites
-GCC contains several test suites to help maintain compiler quality.
-Most of the runtime libraries and language front ends in GCC have test
-suites. Currently only the C language test suites are documented
+GCC contains several testsuites to help maintain compiler quality.
+Most of the runtime libraries and language front ends in GCC have
+testsuites. Currently only the C language testsuites are documented
here; FIXME: document the others.
@menu
-* Test Idioms:: Idioms used in test suite code.
-* C Tests:: The C language test suites.
-* libgcj Tests:: The Java library test suites.
+* Test Idioms:: Idioms used in testsuite code.
+* Ada Tests:: The Ada language testsuites.
+* C Tests:: The C language testsuites.
+* libgcj Tests:: The Java library testsuites.
* gcov Testing:: Support for testing gcov.
* profopt Testing:: Support for testing profile-directed optimizations.
* compat Testing:: Support for testing binary compatibility.
@end menu
@node Test Idioms
-@subsection Idioms Used in Test Suite Code
-
-In the @file{gcc.c-torture} test suites, test cases are commonly named
-after the date on which they were added. This allows people to tell
-at a glance whether a test failure is because of a recently found bug
-that has not yet been fixed, or whether it may be a regression. In
-other test suites, more descriptive names are used. In general C test
-cases have a trailing @file{-@var{n}.c}, starting with @file{-1.c}, in
-case other test cases with similar names are added later.
+@subsection Idioms Used in Testsuite Code
+
+In general C testcases have a trailing @file{-@var{n}.c}, starting
+with @file{-1.c}, in case other testcases with similar names are added
+later. If the test is a test of some well-defined feature, it should
+have a name referring to that feature such as
+@file{@var{feature}-1.c}. If it does not test a well-defined feature
+but just happens to exercise a bug somewhere in the compiler, and a
+bug report has been filed for this bug in the GCC bug database,
+@file{pr@var{bug-number}-1.c} is the appropriate form of name.
+Otherwise (for miscellaneous bugs not filed in the GCC bug database),
+and previously more generally, test cases are named after the date on
+which they were added. This allows people to tell at a glance whether
+a test failure is because of a recently found bug that has not yet
+been fixed, or whether it may be a regression, but does not give any
+other information about the bug or where discussion of it may be
+found. Some other language testsuites follow similar conventions.
Test cases should use @code{abort ()} to indicate failure and
@code{exit (0)} for success; on some targets these may be redefined to
indicate failure and success in other ways.
-In the @file{gcc.dg} test suite, it is often necessary to test that an
+In the @file{gcc.dg} testsuite, it is often necessary to test that an
error is indeed a hard error and not just a warning---for example,
where it is a constraint violation in the C standard, which must
become an error with @option{-pedantic-errors}. The following idiom,
@@ -831,26 +886,64 @@ All testcases must be portable. Target-specific testcases must have
appropriate code to avoid causing failures on unsupported systems;
unfortunately, the mechanisms for this differ by directory.
-FIXME: discuss non-C test suites here.
+FIXME: discuss non-C testsuites here.
+
+@node Ada Tests
+@subsection Ada Language Testsuites
+
+The Ada testsuite includes executable tests from the ACATS 2.5
+testsuite, publicly available at
+@uref{http://www.adaic.org/compilers/acats/2.5}
+
+These tests are integrated in the GCC testsuite in the
+@file{gcc/testsuite/ada/acats} directory, and
+enabled automatically when running @code{make check}, assuming
+the Ada language has been enabled when configuring GCC.
+
+You can also run the Ada testsuite independently, using
+@code{make check-ada}, or run a subset of the tests by specifying which
+chapter to run, e.g:
+
+@smallexample
+$ make check-ada CHAPTERS="c3 c9"
+@end smallexample
+
+The tests are organized by directory, each directory corresponding to
+a chapter of the Ada Reference Manual. So for example, c9 corresponds
+to chapter 9, which deals with tasking features of the language.
+
+There is also an extra chapter called @file{gcc} containing a template for
+creating new executable tests.
+
+The tests are run using two 'sh' scripts: run_acats and run_all.sh
+To run the tests using a simulator or a cross target, see the small
+customization section at the top of run_all.sh
+
+These tests are run using the build tree: they can be run without doing
+a @code{make install}.
@node C Tests
-@subsection C Language Test Suites
+@subsection C Language Testsuites
-GCC contains the following C language test suites, in the
+GCC contains the following C language testsuites, in the
@file{gcc/testsuite} directory:
@table @file
@item gcc.dg
-This contains tests of particular features of the C compiler, using the
+This contains tests of particular features of the C compiler, using the
more modern @samp{dg} harness. Correctness tests for various compiler
features should go here if possible.
-Magic comments determine whether the file
-is preprocessed, compiled, linked or run. In these tests, error and warning
-message texts are compared against expected texts or regular expressions
+Magic comments determine whether the file
+is preprocessed, compiled, linked or run. In these tests, error and warning
+message texts are compared against expected texts or regular expressions
given in comments. These tests are run with the options @samp{-ansi -pedantic}
unless other options are given in the test. Except as noted below they
are not run with multiple optimization options.
+@item gcc.dg/compat
+This subdirectory contains tests for binary compatibility using
+@file{compat.exp}, which in turn uses the language-independent support
+(@pxref{compat Testing, , Support for testing binary compatibility}).
@item gcc.dg/cpp
This subdirectory contains tests of the preprocessor.
@item gcc.dg/debug
@@ -872,7 +965,7 @@ FIXME: describe this.
This contains particular code fragments which have historically broken easily.
These tests are run with multiple optimization options, so tests for features
which only break at some optimization levels belong here. This also contains
-tests to check that certain optimizations occur. It might be worthwhile to
+tests to check that certain optimizations occur. It might be worthwhile to
separate the correctness tests cleanly from the code quality tests, but
it hasn't been done yet.
@@ -881,7 +974,7 @@ FIXME: describe this.
This directory should probably not be used for new tests.
@item gcc.c-torture/compile
-This test suite contains test cases that should compile, but do not
+This testsuite contains test cases that should compile, but do not
need to link or run. These test cases are compiled with several
different combinations of optimization options. All warnings are
disabled for these test cases, so this directory is not suitable if
@@ -891,7 +984,7 @@ platforms, by the use of @file{.x} files, mostly these test cases
should not contain platform dependencies. FIXME: discuss how defines
such as @code{NO_LABEL_VALUES} and @code{STACK_SIZE} are used.
@item gcc.c-torture/execute
-This test suite contains test cases that should compile, link and run;
+This testsuite contains test cases that should compile, link and run;
otherwise the same comments as for @file{gcc.c-torture/compile} apply.
@item gcc.c-torture/execute/ieee
This contains tests which are specific to IEEE floating point.
@@ -928,14 +1021,14 @@ FIXME: merge in @file{testsuite/README.gcc} and discuss the format of
test cases and magic comments more.
@node libgcj Tests
-@subsection The Java library test suites.
+@subsection The Java library testsuites.
Runtime tests are executed via @samp{make check} in the
@file{@var{target}/libjava/testsuite} directory in the build
tree. Additional runtime tests can be checked into this testsuite.
Regression testing of the core packages in libgcj is also covered by the
-Mauve test suite. The @uref{http://sources.redhat.com/mauve/,,Mauve Project}
+Mauve testsuite. The @uref{http://sources.redhat.com/mauve/,,Mauve Project}
develops tests for the Java Class Libraries. These tests are run as part
of libgcj testing by placing the Mauve tree within the libjava testsuite
sources at @file{libjava/testsuite/libjava.mauve/mauve}, or by specifying
@@ -949,8 +1042,8 @@ Update this file when adding new failing tests to Mauve, or when fixing
bugs in libgcj that had caused Mauve test failures.
The @uref{http://oss.software.ibm.com/developerworks/opensource/jacks/,,
-Jacks} project provides a test suite for Java compilers that can be used
-to test changes that affect the GCJ front end. This test suite is run as
+Jacks} project provides a testsuite for Java compilers that can be used
+to test changes that affect the GCJ front end. This testsuite is run as
part of Java testing by placing the Jacks tree within the the libjava
testsuite sources at @file{libjava/testsuite/libjava.jacks/jacks}.
@@ -976,10 +1069,13 @@ and call return percentages. All of these checks are requested via
commands that appear in comments in the test's source file.
Commands to check line counts are processed by default.
Commands to check branch percentages and call return percentages are
-processed if there is a file with the same basename as the source
-file and a suffix @file{.x} that contains a line
-@code{set gcov_verify_branches 1} or @code{set gcov_verify_calls 1},
-respectively.
+processed if the @command{run-gcov} command has arguments @code{branches}
+or @code{calls}, respectively. For example, the following specifies
+checking both, as well as passing @code{-b} to @command{gcov}:
+
+@smallexample
+@{ dg-final @{ run-gcov branches calls @{ -b sourcefile @} @} @}
+@end smallexample
A line count command appears within a comment on the source line
that is expected to get the specified count and has the form
@@ -1042,7 +1138,7 @@ about a specific optimization:
@table @code
@item tool
-tool being tested, e.g., gcc
+tool being tested, e.g., @command{gcc}
@item profile_option
options used to generate profile data
@@ -1062,11 +1158,10 @@ torture tests
@subsection Support for testing binary compatibility
The file @file{compat.exp} provides language-independent support for
-binary compatibility testing. It supports testing interoperability
-of two compilers that follow the same ABI, or of multiple sets of
-compiler options that should not affect binary compatibility.
-It is intended to be used for test suites that complement ABI test
-suites.
+binary compatibility testing. It supports testing interoperability of
+two compilers that follow the same ABI, or of multiple sets of
+compiler options that should not affect binary compatibility. It is
+intended to be used for testsuites that complement ABI testsuites.
A test supported by this framework has three parts, each in a
separate source file: a main program and two pieces that interact
diff --git a/contrib/gcc/doc/standards.texi b/contrib/gcc/doc/standards.texi
index c939498d3983..af33612dd176 100644
--- a/contrib/gcc/doc/standards.texi
+++ b/contrib/gcc/doc/standards.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+@c Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -79,7 +79,7 @@ as @dfn{AMD1}; the amended standard is sometimes known as @dfn{C94} or
A new edition of the ISO C standard was published in 1999 as ISO/IEC
9899:1999, and is commonly known as @dfn{C99}. GCC has incomplete
support for this standard version; see
-@uref{http://gcc.gnu.org/gcc-3.3/c99status.html} for details. To select this
+@uref{http://gcc.gnu.org/gcc-3.4/c99status.html} for details. To select this
standard, use @option{-std=c99} or @option{-std=iso9899:1999}. (While in
development, drafts of this standard version were referred to as
@dfn{C9X}.)
@@ -145,10 +145,10 @@ GNU C library). @xref{Standard Libraries,,Standard Libraries}.
Most of the compiler support routines used by GCC are present in
@file{libgcc}, but there are a few exceptions. GCC requires the
freestanding environment provide @code{memcpy}, @code{memmove},
-@code{memset} and @code{memcmp}. Some older ports of GCC are
+@code{memset} and @code{memcmp}. Some older ports of GCC are
configured to use the BSD @code{bcopy}, @code{bzero} and @code{bcmp}
functions instead, but this is deprecated for new ports.
-Finally, if @code{__builtin_trap} is used, and the target does
+Finally, if @code{__builtin_trap} is used, and the target does
not implement the @code{trap} pattern, then GCC will emit a call
to @code{abort}.
diff --git a/contrib/gcc/doc/tm.texi b/contrib/gcc/doc/tm.texi
index 9a7117344ac0..03c1c4e6b9ad 100644
--- a/contrib/gcc/doc/tm.texi
+++ b/contrib/gcc/doc/tm.texi
@@ -1,5 +1,5 @@
-@c Copyright (C) 1988,1989,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003
-@c Free Software Foundation, Inc.
+@c Copyright (C) 1988,1989,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,
+@c 2002, 2003, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -50,6 +50,7 @@ through the macros defined in the @file{.h} file.
* Mode Switching:: Insertion of mode-switching instructions.
* Target Attributes:: Defining target-specific uses of @code{__attribute__}.
* MIPS Coprocessors:: MIPS coprocessor support and how to customize it.
+* PCH Target:: Validity checking for precompiled headers.
* Misc:: Everything else.
@end menu
@@ -93,9 +94,7 @@ from being defined in the @file{.h} file to being part of the
@c prevent bad page break with this line
You can control the compilation driver.
-@table @code
-@findex SWITCH_TAKES_ARG
-@item SWITCH_TAKES_ARG (@var{char})
+@defmac SWITCH_TAKES_ARG (@var{char})
A C expression which determines whether the option @option{-@var{char}}
takes arguments. The value should be the number of arguments that
option takes--zero, for many options.
@@ -106,9 +105,9 @@ properly. You need not define @code{SWITCH_TAKES_ARG} unless you
wish to add additional options which take arguments. Any redefinition
should call @code{DEFAULT_SWITCH_TAKES_ARG} and then check for
additional options.
+@end defmac
-@findex WORD_SWITCH_TAKES_ARG
-@item WORD_SWITCH_TAKES_ARG (@var{name})
+@defmac WORD_SWITCH_TAKES_ARG (@var{name})
A C expression which determines whether the option @option{-@var{name}}
takes arguments. The value should be the number of arguments that
option takes--zero, for many options. This macro rather than
@@ -120,9 +119,9 @@ properly. You need not define @code{WORD_SWITCH_TAKES_ARG} unless you
wish to add additional options which take arguments. Any redefinition
should call @code{DEFAULT_WORD_SWITCH_TAKES_ARG} and then check for
additional options.
+@end defmac
-@findex SWITCH_CURTAILS_COMPILATION
-@item SWITCH_CURTAILS_COMPILATION (@var{char})
+@defmac SWITCH_CURTAILS_COMPILATION (@var{char})
A C expression which determines whether the option @option{-@var{char}}
stops compilation before the generation of an executable. The value is
boolean, nonzero if the option does stop an executable from being
@@ -135,16 +134,16 @@ options properly. You need not define
options which affect the generation of an executable. Any redefinition
should call @code{DEFAULT_SWITCH_CURTAILS_COMPILATION} and then check
for additional options.
+@end defmac
-@findex SWITCHES_NEED_SPACES
-@item SWITCHES_NEED_SPACES
+@defmac SWITCHES_NEED_SPACES
A string-valued C expression which enumerates the options for which
the linker needs a space between the option and its argument.
If this macro is not defined, the default value is @code{""}.
+@end defmac
-@findex TARGET_OPTION_TRANSLATE_TABLE
-@item TARGET_OPTION_TRANSLATE_TABLE
+@defmac TARGET_OPTION_TRANSLATE_TABLE
If defined, a list of pairs of strings, the first of which is a
potential command line target to the @file{gcc} driver program, and the
second of which is a space-separated (tabs and other whitespace are not
@@ -162,40 +161,60 @@ multilibs. Example nonsensical definition, where @code{-malt-abi},
@{ "-fast", "-march=fast-foo -malt-abi -I/usr/fast-foo" @}, \
@{ "-compat", "-EB -malign=4 -mspoo" @}
@end smallexample
+@end defmac
-@findex DRIVER_SELF_SPECS
-@item DRIVER_SELF_SPECS
+@defmac DRIVER_SELF_SPECS
A list of specs for the driver itself. It should be a suitable
initializer for an array of strings, with no surrounding braces.
-The driver applies these specs to its own command line before choosing
-the multilib directory or running any subcommands. It applies them in
-the order given, so each spec can depend on the options added by
-earlier ones. It is also possible to remove options using
-@samp{%<@var{option}} in the usual way.
+The driver applies these specs to its own command line between loading
+default @file{specs} files (but not command-line specified ones) and
+choosing the multilib directory or running any subcommands. It
+applies them in the order given, so each spec can depend on the
+options added by earlier ones. It is also possible to remove options
+using @samp{%<@var{option}} in the usual way.
This macro can be useful when a port has several interdependent target
options. It provides a way of standardizing the command line so
that the other specs are easier to write.
Do not define this macro if it does not need to do anything.
+@end defmac
+
+@defmac OPTION_DEFAULT_SPECS
+A list of specs used to support configure-time default options (i.e.@:
+@option{--with} options) in the driver. It should be a suitable initializer
+for an array of structures, each containing two strings, without the
+outermost pair of surrounding braces.
+
+The first item in the pair is the name of the default. This must match
+the code in @file{config.gcc} for the target. The second item is a spec
+to apply if a default with this name was specified. The string
+@samp{%(VALUE)} in the spec will be replaced by the value of the default
+everywhere it occurs.
+
+The driver will apply these specs to its own command line between loading
+default @file{specs} files and processing @code{DRIVER_SELF_SPECS}, using
+the same mechanism as @code{DRIVER_SELF_SPECS}.
+
+Do not define this macro if it does not need to do anything.
+@end defmac
-@findex CPP_SPEC
-@item CPP_SPEC
+@defmac CPP_SPEC
A C string constant that tells the GCC driver program options to
pass to CPP@. It can also specify how to translate options you
give to GCC into options for GCC to pass to the CPP@.
Do not define this macro if it does not need to do anything.
+@end defmac
-@findex CPLUSPLUS_CPP_SPEC
-@item CPLUSPLUS_CPP_SPEC
+@defmac CPLUSPLUS_CPP_SPEC
This macro is just like @code{CPP_SPEC}, but is used for C++, rather
than C@. If you do not define this macro, then the value of
@code{CPP_SPEC} (if any) will be used instead.
+@end defmac
-@findex CC1_SPEC
-@item CC1_SPEC
+@defmac CC1_SPEC
A C string constant that tells the GCC driver program options to
pass to @code{cc1}, @code{cc1plus}, @code{f771}, and the other language
front ends.
@@ -203,9 +222,9 @@ It can also specify how to translate options you give to GCC into options
for GCC to pass to front ends.
Do not define this macro if it does not need to do anything.
+@end defmac
-@findex CC1PLUS_SPEC
-@item CC1PLUS_SPEC
+@defmac CC1PLUS_SPEC
A C string constant that tells the GCC driver program options to
pass to @code{cc1plus}. It can also specify how to translate options you
give to GCC into options for GCC to pass to the @code{cc1plus}.
@@ -214,44 +233,57 @@ Do not define this macro if it does not need to do anything.
Note that everything defined in CC1_SPEC is already passed to
@code{cc1plus} so there is no need to duplicate the contents of
CC1_SPEC in CC1PLUS_SPEC@.
+@end defmac
-@findex ASM_SPEC
-@item ASM_SPEC
+@defmac ASM_SPEC
A C string constant that tells the GCC driver program options to
pass to the assembler. It can also specify how to translate options
you give to GCC into options for GCC to pass to the assembler.
See the file @file{sun3.h} for an example of this.
Do not define this macro if it does not need to do anything.
+@end defmac
-@findex ASM_FINAL_SPEC
-@item ASM_FINAL_SPEC
+@defmac ASM_FINAL_SPEC
A C string constant that tells the GCC driver program how to
run any programs which cleanup after the normal assembler.
Normally, this is not needed. See the file @file{mips.h} for
an example of this.
Do not define this macro if it does not need to do anything.
+@end defmac
-@findex LINK_SPEC
-@item LINK_SPEC
+@defmac AS_NEEDS_DASH_FOR_PIPED_INPUT
+Define this macro, with no value, if the driver should give the assembler
+an argument consisting of a single dash, @option{-}, to instruct it to
+read from its standard input (which will be a pipe connected to the
+output of the compiler proper). This argument is given after any
+@option{-o} option specifying the name of the output file.
+
+If you do not define this macro, the assembler is assumed to read its
+standard input if given no non-option arguments. If your assembler
+cannot read standard input at all, use a @samp{%@{pipe:%e@}} construct;
+see @file{mips.h} for instance.
+@end defmac
+
+@defmac LINK_SPEC
A C string constant that tells the GCC driver program options to
pass to the linker. It can also specify how to translate options you
give to GCC into options for GCC to pass to the linker.
Do not define this macro if it does not need to do anything.
+@end defmac
-@findex LIB_SPEC
-@item LIB_SPEC
+@defmac LIB_SPEC
Another C string constant used much like @code{LINK_SPEC}. The difference
between the two is that @code{LIB_SPEC} is used at the end of the
command given to the linker.
If this macro is not defined, a default is provided that
loads the standard C library from the usual place. See @file{gcc.c}.
+@end defmac
-@findex LIBGCC_SPEC
-@item LIBGCC_SPEC
+@defmac LIBGCC_SPEC
Another C string constant that tells the GCC driver program
how and when to place a reference to @file{libgcc.a} into the
linker command line. This constant is placed both before and after
@@ -259,26 +291,26 @@ the value of @code{LIB_SPEC}.
If this macro is not defined, the GCC driver provides a default that
passes the string @option{-lgcc} to the linker.
+@end defmac
-@findex STARTFILE_SPEC
-@item STARTFILE_SPEC
+@defmac STARTFILE_SPEC
Another C string constant used much like @code{LINK_SPEC}. The
difference between the two is that @code{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 @file{gcc.c}.
+@end defmac
-@findex ENDFILE_SPEC
-@item ENDFILE_SPEC
+@defmac ENDFILE_SPEC
Another C string constant used much like @code{LINK_SPEC}. The
difference between the two is that @code{ENDFILE_SPEC} is used at
the very end of the command given to the linker.
Do not define this macro if it does not need to do anything.
+@end defmac
-@findex THREAD_MODEL_SPEC
-@item THREAD_MODEL_SPEC
+@defmac THREAD_MODEL_SPEC
GCC @code{-v} will print the thread model GCC was configured to use.
However, this doesn't work on platforms that are multilibbed on thread
models, such as AIX 4.3. On such platforms, define
@@ -286,9 +318,22 @@ models, such as AIX 4.3. On such platforms, define
blanks that names one of the recognized thread models. @code{%*}, the
default value of this macro, will expand to the value of
@code{thread_file} set in @file{config.gcc}.
+@end defmac
+
+@defmac SYSROOT_SUFFIX_SPEC
+Define this macro to add a suffix to the target sysroot when GCC is
+configured with a sysroot. This will cause GCC to search for usr/lib,
+et al, within sysroot+suffix.
+@end defmac
-@findex EXTRA_SPECS
-@item EXTRA_SPECS
+@defmac SYSROOT_HEADERS_SUFFIX_SPEC
+Define this macro to add a headers_suffix to the target sysroot when
+GCC is configured with a sysroot. This will cause GCC to pass the
+updated sysroot+headers_suffix to CPP, causing it to search for
+usr/include, et al, within sysroot+headers_suffix.
+@end defmac
+
+@defmac EXTRA_SPECS
Define this macro to provide additional specifications to put in the
@file{specs} file that can be used in various specifications like
@code{CC1_SPEC}.
@@ -311,20 +356,20 @@ used.
The @file{config/rs6000/rs6000.h} target file defines:
-@example
+@smallexample
#define EXTRA_SPECS \
@{ "cpp_sysv_default", CPP_SYSV_DEFAULT @},
#define CPP_SYS_DEFAULT ""
-@end example
+@end smallexample
The @file{config/rs6000/sysv.h} target file defines:
@smallexample
#undef CPP_SPEC
#define CPP_SPEC \
"%@{posix: -D_POSIX_SOURCE @} \
-%@{mcall-sysv: -D_CALL_SYSV @} %@{mcall-aix: -D_CALL_AIX @} \
-%@{!mcall-sysv: %@{!mcall-aix: %(cpp_sysv_default) @}@} \
+%@{mcall-sysv: -D_CALL_SYSV @} \
+%@{!mcall-sysv: %(cpp_sysv_default) @} \
%@{msoft-float: -D_SOFT_FLOAT@} %@{mcpu=403: -D_SOFT_FLOAT@}"
#undef CPP_SYSV_DEFAULT
@@ -338,30 +383,30 @@ while the @file{config/rs6000/eabiaix.h} target file defines
#undef CPP_SYSV_DEFAULT
#define CPP_SYSV_DEFAULT "-D_CALL_AIX"
@end smallexample
+@end defmac
-@findex LINK_LIBGCC_SPECIAL
-@item LINK_LIBGCC_SPECIAL
+@defmac LINK_LIBGCC_SPECIAL
Define this macro if the driver program should find the library
@file{libgcc.a} itself and should not pass @option{-L} options to the
linker. If you do not define this macro, the driver program will pass
the argument @option{-lgcc} to tell the linker to do the search and will
pass @option{-L} options to it.
+@end defmac
-@findex LINK_LIBGCC_SPECIAL_1
-@item LINK_LIBGCC_SPECIAL_1
+@defmac LINK_LIBGCC_SPECIAL_1
Define this macro if the driver program should find the library
@file{libgcc.a}. If you do not define this macro, the driver program will pass
the argument @option{-lgcc} to tell the linker to do the search.
This macro is similar to @code{LINK_LIBGCC_SPECIAL}, except that it does
not affect @option{-L} options.
+@end defmac
-@findex LINK_GCC_C_SEQUENCE_SPEC
-@item LINK_GCC_C_SEQUENCE_SPEC
+@defmac LINK_GCC_C_SEQUENCE_SPEC
The sequence in which libgcc and libc are specified to the linker.
By default this is @code{%G %L %G}.
+@end defmac
-@findex LINK_COMMAND_SPEC
-@item LINK_COMMAND_SPEC
+@defmac LINK_COMMAND_SPEC
A C string constant giving the complete command line need to execute the
linker. When you do this, you will need to update your port each time a
change is made to the link command line within @file{gcc.c}. Therefore,
@@ -369,15 +414,15 @@ define this macro only if you need to completely redefine the command
line for invoking the linker and there is no other way to accomplish
the effect you need. Overriding this macro may be avoidable by overriding
@code{LINK_GCC_C_SEQUENCE_SPEC} instead.
+@end defmac
-@findex LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
-@item LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
+@defmac LINK_ELIMINATE_DUPLICATE_LDIRECTORIES
A nonzero value causes @command{collect2} to remove duplicate @option{-L@var{directory}} search
directories from linking commands. Do not give it a nonzero value if
removing duplicate search directories changes the linker's semantics.
+@end defmac
-@findex MULTILIB_DEFAULTS
-@item MULTILIB_DEFAULTS
+@defmac MULTILIB_DEFAULTS
Define this macro as a C expression for the initializer of an array of
string to tell the driver program which options are defaults for this
target and thus do not need to be handled specially when using
@@ -387,55 +432,51 @@ Do not define this macro if @code{MULTILIB_OPTIONS} is not defined in
the target makefile fragment or if none of the options listed in
@code{MULTILIB_OPTIONS} are set by default.
@xref{Target Fragment}.
+@end defmac
-@findex RELATIVE_PREFIX_NOT_LINKDIR
-@item RELATIVE_PREFIX_NOT_LINKDIR
+@defmac RELATIVE_PREFIX_NOT_LINKDIR
Define this macro to tell @command{gcc} that it should only translate
a @option{-B} prefix into a @option{-L} linker option if the prefix
indicates an absolute file name.
+@end defmac
-@findex STANDARD_EXEC_PREFIX
-@item STANDARD_EXEC_PREFIX
-Define this macro as a C string constant if you wish to override the
-standard choice of @file{/usr/local/lib/gcc-lib/} as the default prefix to
-try when searching for the executable files of the compiler.
-
-@findex MD_EXEC_PREFIX
-@item MD_EXEC_PREFIX
+@defmac MD_EXEC_PREFIX
If defined, this macro is an additional prefix to try after
@code{STANDARD_EXEC_PREFIX}. @code{MD_EXEC_PREFIX} is not searched
when the @option{-b} option is used, or the compiler is built as a cross
compiler. If you define @code{MD_EXEC_PREFIX}, then be sure to add it
to the list of directories used to find the assembler in @file{configure.in}.
+@end defmac
-@findex STANDARD_STARTFILE_PREFIX
-@item STANDARD_STARTFILE_PREFIX
+@defmac STANDARD_STARTFILE_PREFIX
Define this macro as a C string constant if you wish to override the
-standard choice of @file{/usr/local/lib/} as the default prefix to
+standard choice of @code{libdir} as the default prefix to
try when searching for startup files such as @file{crt0.o}.
+@code{STANDARD_STARTFILE_PREFIX} is not searched when the compiler
+is built as a cross compiler.
+@end defmac
-@findex MD_STARTFILE_PREFIX
-@item MD_STARTFILE_PREFIX
+@defmac MD_STARTFILE_PREFIX
If defined, this macro supplies an additional prefix to try after the
standard prefixes. @code{MD_EXEC_PREFIX} is not searched when the
@option{-b} option is used, or when the compiler is built as a cross
compiler.
+@end defmac
-@findex MD_STARTFILE_PREFIX_1
-@item MD_STARTFILE_PREFIX_1
+@defmac MD_STARTFILE_PREFIX_1
If defined, this macro supplies yet another prefix to try after the
standard prefixes. It is not searched when the @option{-b} option is
used, or when the compiler is built as a cross compiler.
+@end defmac
-@findex INIT_ENVIRONMENT
-@item INIT_ENVIRONMENT
+@defmac INIT_ENVIRONMENT
Define this macro as a C string constant if you wish to set environment
variables for programs called by the driver, such as the assembler and
loader. The driver passes the value of this macro to @code{putenv} to
initialize the necessary environment variables.
+@end defmac
-@findex LOCAL_INCLUDE_DIR
-@item LOCAL_INCLUDE_DIR
+@defmac LOCAL_INCLUDE_DIR
Define this macro as a C string constant if you wish to override the
standard choice of @file{/usr/local/include} as the default prefix to
try when searching for local header files. @code{LOCAL_INCLUDE_DIR}
@@ -443,11 +484,11 @@ comes before @code{SYSTEM_INCLUDE_DIR} in the search order.
Cross compilers do not search either @file{/usr/local/include} or its
replacement.
+@end defmac
-@findex MODIFY_TARGET_NAME
-@item MODIFY_TARGET_NAME
-Define this macro if you with to define command-line switches that modify the
-default target name
+@defmac MODIFY_TARGET_NAME
+Define this macro if you wish to define command-line switches that
+modify the default target name.
For each switch, you can include a string to be appended to the first
part of the configuration name or a string to be deleted from the
@@ -468,10 +509,9 @@ code
@{ @{ "-32", DELETE, "64"@}, \
@{"-64", ADD, "64"@}@}
@end smallexample
+@end defmac
-
-@findex SYSTEM_INCLUDE_DIR
-@item SYSTEM_INCLUDE_DIR
+@defmac SYSTEM_INCLUDE_DIR
Define this macro as a C string constant if you wish to specify a
system-specific directory to search for header files before the standard
directory. @code{SYSTEM_INCLUDE_DIR} comes before
@@ -479,24 +519,24 @@ directory. @code{SYSTEM_INCLUDE_DIR} comes before
Cross compilers do not use this macro and do not search the directory
specified.
+@end defmac
-@findex STANDARD_INCLUDE_DIR
-@item STANDARD_INCLUDE_DIR
+@defmac STANDARD_INCLUDE_DIR
Define this macro as a C string constant if you wish to override the
standard choice of @file{/usr/include} as the default prefix to
try when searching for header files.
-Cross compilers do not use this macro and do not search either
+Cross compilers ignore this macro and do not search either
@file{/usr/include} or its replacement.
+@end defmac
-@findex STANDARD_INCLUDE_COMPONENT
-@item STANDARD_INCLUDE_COMPONENT
+@defmac STANDARD_INCLUDE_COMPONENT
The ``component'' corresponding to @code{STANDARD_INCLUDE_DIR}.
See @code{INCLUDE_DEFAULTS}, below, for the description of components.
If you do not define this macro, no component is used.
+@end defmac
-@findex INCLUDE_DEFAULTS
-@item INCLUDE_DEFAULTS
+@defmac INCLUDE_DEFAULTS
Define this macro if you wish to override the entire default search path
for include files. For a native compiler, the default search path
usually consists of @code{GCC_INCLUDE_DIR}, @code{LOCAL_INCLUDE_DIR},
@@ -515,13 +555,13 @@ wrapped in @code{extern @samp{C}} when compiling C++. Mark the end of
the array with a null element.
The component name denotes what GNU package the include file is part of,
-if any, in all upper-case letters. For example, it might be @samp{GCC}
+if any, in all uppercase letters. For example, it might be @samp{GCC}
or @samp{BINUTILS}. If the package is part of a vendor-supplied
operating system, code the component name as @samp{0}.
For example, here is the definition used for VAX/VMS:
-@example
+@smallexample
#define INCLUDE_DEFAULTS \
@{ \
@{ "GNU_GXX_INCLUDE:", "G++", 1, 1@}, \
@@ -530,8 +570,8 @@ For example, here is the definition used for VAX/VMS:
@{ ".", 0, 0, 0@}, \
@{ 0, 0, 0, 0@} \
@}
-@end example
-@end table
+@end smallexample
+@end defmac
Here is the order of prefixes tried for exec files:
@@ -599,13 +639,11 @@ The macro @code{STANDARD_STARTFILE_PREFIX}.
@c prevent bad page break with this line
Here are run-time target specifications.
-@table @code
-@findex TARGET_CPU_CPP_BUILTINS
-@item TARGET_CPU_CPP_BUILTINS()
+@defmac TARGET_CPU_CPP_BUILTINS ()
This function-like macro expands to a block of code that defines
built-in preprocessor macros and assertions for the target cpu, using
the functions @code{builtin_define}, @code{builtin_define_std} and
-@code{builtin_assert} defined in @file{c-common.c}. When the front end
+@code{builtin_assert}. When the front end
calls this macro it provides a trailing semicolon, and since it has
finished command line option processing your code can use those
results freely.
@@ -635,48 +673,28 @@ to check for that first. If you need to check for strict ANSI, the
variable @code{flag_iso} can be used. The function-like macro
@code{preprocessing_trad_p()} can be used to check for traditional
preprocessing.
+@end defmac
-With @code{TARGET_OS_CPP_BUILTINS} this macro obsoletes the
-@code{CPP_PREDEFINES} target macro.
-
-@findex TARGET_OS_CPP_BUILTINS
-@item TARGET_OS_CPP_BUILTINS()
+@defmac TARGET_OS_CPP_BUILTINS ()
Similarly to @code{TARGET_CPU_CPP_BUILTINS} but this macro is optional
and is used for the target operating system instead.
+@end defmac
-With @code{TARGET_CPU_CPP_BUILTINS} this macro obsoletes the
-@code{CPP_PREDEFINES} target macro.
-
-@findex CPP_PREDEFINES
-@item CPP_PREDEFINES
-Define this to be a string constant containing @option{-D} options to
-define the predefined macros that identify this machine and system.
-These macros will be predefined unless the @option{-ansi} option (or a
-@option{-std} option for strict ISO C conformance) is specified.
-
-In addition, a parallel set of macros are predefined, whose names are
-made by appending @samp{__} at the beginning and at the end. These
-@samp{__} macros are permitted by the ISO standard, so they are
-predefined regardless of whether @option{-ansi} or a @option{-std} option
-is specified.
-
-For example, on the Sun, one can use the following value:
-
-@smallexample
-"-Dmc68000 -Dsun -Dunix"
-@end smallexample
-
-The result is to define the macros @code{__mc68000__}, @code{__sun__}
-and @code{__unix__} unconditionally, and the macros @code{mc68000},
-@code{sun} and @code{unix} provided @option{-ansi} is not specified.
+@defmac TARGET_OBJFMT_CPP_BUILTINS ()
+Similarly to @code{TARGET_CPU_CPP_BUILTINS} but this macro is optional
+and is used for the target object format. @file{elfos.h} uses this
+macro to define @code{__ELF__}, so you probably do not need to define
+it yourself.
+@end defmac
-@findex extern int target_flags
-@item extern int target_flags;
+@deftypevar {extern int} target_flags
This declaration should be present.
+@end deftypevar
@cindex optional hardware or system features
@cindex features, optional, in system conventions
-@item TARGET_@dots{}
+
+@defmac TARGET_@var{featurename}
This series of macros is to allow compiler command arguments to
enable or disable the use of optional features of the target machine.
For example, one machine description serves both the 68000 and
@@ -687,14 +705,14 @@ by means of a macro @code{TARGET_68020} that tests a bit in
Define a macro @code{TARGET_@var{featurename}} for each such option.
Its definition should test a bit in @code{target_flags}. It is
-recommended that a helper macro @code{TARGET_MASK_@var{featurename}}
+recommended that a helper macro @code{MASK_@var{featurename}}
is defined for each bit-value to test, and used in
@code{TARGET_@var{featurename}} and @code{TARGET_SWITCHES}. For
example:
@smallexample
#define TARGET_MASK_68020 1
-#define TARGET_68020 (target_flags & TARGET_MASK_68020)
+#define TARGET_68020 (target_flags & MASK_68020)
@end smallexample
One place where these macros are used is in the condition-expressions
@@ -702,9 +720,9 @@ of instruction patterns. Note how @code{TARGET_68020} appears
frequently in the 68000 machine description file, @file{m68k.md}.
Another place they are used is in the definitions of the other
macros in the @file{@var{machine}.h} file.
+@end defmac
-@findex TARGET_SWITCHES
-@item TARGET_SWITCHES
+@defmac TARGET_SWITCHES
This macro defines names of command options to set and clear
bits in @code{target_flags}. Its definition is an initializer
with a subgrouping for each command option.
@@ -735,29 +753,39 @@ with opposite meanings, and picks the latter as the default:
@smallexample
#define TARGET_SWITCHES \
- @{ @{ "68020", TARGET_MASK_68020, "" @}, \
- @{ "68000", -TARGET_MASK_68020, \
+ @{ @{ "68020", MASK_68020, "" @}, \
+ @{ "68000", -MASK_68020, \
N_("Compile for the 68000") @}, \
- @{ "", TARGET_MASK_68020, "" @}@}
+ @{ "", MASK_68020, "" @}, \
+ @}
@end smallexample
+@end defmac
-@findex TARGET_OPTIONS
-@item TARGET_OPTIONS
+@defmac TARGET_OPTIONS
This macro is similar to @code{TARGET_SWITCHES} but defines names of command
options that have values. Its definition is an initializer with a
subgrouping for each command option.
-Each subgrouping contains a string constant, that defines the fixed part
-of the option name, the address of a variable, and a description string.
-Non-empty description strings should be marked with @code{N_(@dots{})} for
-@command{xgettext}. Please do not mark empty strings because the empty
-string is reserved by GNU gettext. @code{gettext("")} returns the header entry
-of the message catalog with meta information, not the empty string.
+Each subgrouping contains a string constant, that defines the option
+name, the address of a variable, a description string, and a value.
+Non-empty description strings should be marked with @code{N_(@dots{})}
+for @command{xgettext}. Please do not mark empty strings because the
+empty string is reserved by GNU gettext. @code{gettext("")} returns the
+header entry of the message catalog with meta information, not the empty
+string.
+
+If the value listed in the table is @code{NULL}, then the variable, type
+@code{char *}, is set to the variable part of the given option if the
+fixed part matches. In other words, if the first part of the option
+matches what's in the table, the variable will be set to point to the
+rest of the option. This allows the user to specify a value for that
+option. The actual option name is made by appending @samp{-m} to the
+specified name. Again, each option should also be documented in
+@file{invoke.texi}.
-The variable, type @code{char *}, is set to the variable part of the
-given option if the fixed part matches. The actual option name is made
-by appending @samp{-m} to the specified name. Again, each option should
-also be documented in @file{invoke.texi}.
+If the value listed in the table is non-@code{NULL}, then the option
+must match the option in the table exactly (with @samp{-m}), and the
+variable is set to point to the value listed in the table.
Here is an example which defines @option{-mshort-data-@var{number}}. If the
given option is @option{-mshort-data-512}, the variable @code{m88k_short_data}
@@ -767,11 +795,42 @@ will be set to the string @code{"512"}.
extern char *m88k_short_data;
#define TARGET_OPTIONS \
@{ @{ "short-data-", &m88k_short_data, \
- N_("Specify the size of the short data section") @} @}
+ N_("Specify the size of the short data section"), 0 @} @}
+@end smallexample
+
+Here is a variant of the above that allows the user to also specify
+just @option{-mshort-data} where a default of @code{"64"} is used.
+
+@smallexample
+extern char *m88k_short_data;
+#define TARGET_OPTIONS \
+ @{ @{ "short-data-", &m88k_short_data, \
+ N_("Specify the size of the short data section"), 0 @} \
+ @{ "short-data", &m88k_short_data, "", "64" @},
+ @}
+@end smallexample
+
+Here is an example which defines @option{-mno-alu}, @option{-malu1}, and
+@option{-malu2} as a three-state switch, along with suitable macros for
+checking the state of the option (documentation is elided for brevity).
+
+@smallexample
+[chip.c]
+char *chip_alu = ""; /* Specify default here. */
+
+[chip.h]
+extern char *chip_alu;
+#define TARGET_OPTIONS \
+ @{ @{ "no-alu", &chip_alu, "", "" @}, \
+ @{ "alu1", &chip_alu, "", "1" @}, \
+ @{ "alu2", &chip_alu, "", "2" @}, @}
+#define TARGET_ALU (chip_alu[0] != '\0')
+#define TARGET_ALU1 (chip_alu[0] == '1')
+#define TARGET_ALU2 (chip_alu[0] == '2')
@end smallexample
+@end defmac
-@findex TARGET_VERSION
-@item TARGET_VERSION
+@defmac TARGET_VERSION
This macro is a C statement to print on @code{stderr} a string
describing the particular machine description choice. Every machine
description should define @code{TARGET_VERSION}. For example:
@@ -785,9 +844,9 @@ description should define @code{TARGET_VERSION}. For example:
fprintf (stderr, " (68k, MIT syntax)");
#endif
@end smallexample
+@end defmac
-@findex OVERRIDE_OPTIONS
-@item OVERRIDE_OPTIONS
+@defmac OVERRIDE_OPTIONS
Sometimes certain combinations of command options do not make sense on
a particular target machine. You can define a macro
@code{OVERRIDE_OPTIONS} to take account of this. This macro, if
@@ -796,9 +855,9 @@ parsed.
Don't use this macro to turn on various extra optimizations for
@option{-O}. That is what @code{OPTIMIZATION_OPTIONS} is for.
+@end defmac
-@findex OPTIMIZATION_OPTIONS
-@item OPTIMIZATION_OPTIONS (@var{level}, @var{size})
+@defmac OPTIMIZATION_OPTIONS (@var{level}, @var{size})
Some machines may desire to change what optimizations are performed for
various optimization levels. This macro, if defined, is executed once
just after the optimization level is determined and before the remainder
@@ -818,13 +877,13 @@ machine-specific optimizations.
@strong{Do not examine @code{write_symbols} in
this macro!} The debugging options are not supposed to alter the
generated code.
+@end defmac
-@findex CAN_DEBUG_WITHOUT_FP
-@item CAN_DEBUG_WITHOUT_FP
+@defmac CAN_DEBUG_WITHOUT_FP
Define this macro if debugging can be performed even without a frame
pointer. If this macro is defined, GCC will turn on the
@option{-fomit-frame-pointer} option whenever @option{-O} is specified.
-@end table
+@end defmac
@node Per-Function Data
@section Defining data structures for per-function information.
@@ -863,30 +922,24 @@ the saving and restoring of the target specific information. Since the
single data area approach is no longer used, these pointers are no
longer supported.
-The macro and function pointers are described below.
-
-@table @code
-@findex INIT_EXPANDERS
-@item INIT_EXPANDERS
+@defmac INIT_EXPANDERS
Macro called to initialize any target specific information. This macro
is called once per function, before generation of any RTL has begun.
The intention of this macro is to allow the initialization of the
-function pointers below.
+function pointer @code{init_machine_status}.
+@end defmac
-@findex init_machine_status
-@item init_machine_status
-This is a @code{void (*)(struct function *)} function pointer. If this
-pointer is non-@code{NULL} it will be called once per function, before function
-compilation starts, in order to allow the target to perform any target
-specific initialization of the @code{struct function} structure. It is
-intended that this would be used to initialize the @code{machine} of
-that structure.
+@deftypevar {void (*)(struct function *)} init_machine_status
+If this function pointer is non-@code{NULL} it will be called once per
+function, before function compilation starts, in order to allow the
+target to perform any target specific initialization of the
+@code{struct function} structure. It is intended that this would be
+used to initialize the @code{machine} of that structure.
@code{struct machine_function} structures are expected to be freed by GC.
Generally, any memory that they reference must be allocated by using
@code{ggc_alloc}, including the structure itself.
-
-@end table
+@end deftypevar
@node Storage Layout
@section Storage Layout
@@ -897,9 +950,7 @@ alignments measured in bits do not need to be constant. They can be C
expressions that refer to static variables, such as the @code{target_flags}.
@xref{Run-time Target}.
-@table @code
-@findex BITS_BIG_ENDIAN
-@item BITS_BIG_ENDIAN
+@defmac BITS_BIG_ENDIAN
Define this macro to have the value 1 if the most significant bit in a
byte has the lowest number; otherwise define it to have the value zero.
This means that bit-field instructions count from the most significant
@@ -909,29 +960,29 @@ macro need not be a constant.
This macro does not affect the way structure fields are packed into
bytes or words; that is controlled by @code{BYTES_BIG_ENDIAN}.
+@end defmac
-@findex BYTES_BIG_ENDIAN
-@item BYTES_BIG_ENDIAN
+@defmac BYTES_BIG_ENDIAN
Define this macro to have the value 1 if the most significant byte in a
word has the lowest number. This macro need not be a constant.
+@end defmac
-@findex WORDS_BIG_ENDIAN
-@item WORDS_BIG_ENDIAN
+@defmac WORDS_BIG_ENDIAN
Define this macro to have the value 1 if, in a multiword object, the
most significant word has the lowest number. This applies to both
memory locations and registers; GCC fundamentally assumes that the
order of words in memory is the same as the order in registers. This
macro need not be a constant.
+@end defmac
-@findex LIBGCC2_WORDS_BIG_ENDIAN
-@item LIBGCC2_WORDS_BIG_ENDIAN
+@defmac LIBGCC2_WORDS_BIG_ENDIAN
Define this macro if @code{WORDS_BIG_ENDIAN} is not constant. This must be a
constant value with the same meaning as @code{WORDS_BIG_ENDIAN}, which will be
used only when compiling @file{libgcc2.c}. Typically the value will be set
based on preprocessor defines.
+@end defmac
-@findex FLOAT_WORDS_BIG_ENDIAN
-@item FLOAT_WORDS_BIG_ENDIAN
+@defmac FLOAT_WORDS_BIG_ENDIAN
Define this macro to have the value 1 if @code{DFmode}, @code{XFmode} or
@code{TFmode} floating point numbers are stored in memory with the word
containing the sign bit at the lowest address; otherwise define it to
@@ -939,42 +990,42 @@ have the value 0. This macro need not be a constant.
You need not define this macro if the ordering is the same as for
multi-word integers.
+@end defmac
-@findex BITS_PER_UNIT
-@item BITS_PER_UNIT
+@defmac BITS_PER_UNIT
Define this macro to be the number of bits in an addressable storage
unit (byte). If you do not define this macro the default is 8.
+@end defmac
-@findex BITS_PER_WORD
-@item BITS_PER_WORD
+@defmac BITS_PER_WORD
Number of bits in a word. If you do not define this macro, the default
is @code{BITS_PER_UNIT * UNITS_PER_WORD}.
+@end defmac
-@findex MAX_BITS_PER_WORD
-@item MAX_BITS_PER_WORD
+@defmac MAX_BITS_PER_WORD
Maximum number of bits in a word. If this is undefined, the default is
@code{BITS_PER_WORD}. Otherwise, it is the constant value that is the
largest value that @code{BITS_PER_WORD} can have at run-time.
+@end defmac
-@findex UNITS_PER_WORD
-@item UNITS_PER_WORD
+@defmac UNITS_PER_WORD
Number of storage units in a word; normally 4.
+@end defmac
-@findex MIN_UNITS_PER_WORD
-@item MIN_UNITS_PER_WORD
+@defmac MIN_UNITS_PER_WORD
Minimum number of units in a word. If this is undefined, the default is
@code{UNITS_PER_WORD}. Otherwise, it is the constant value that is the
smallest value that @code{UNITS_PER_WORD} can have at run-time.
+@end defmac
-@findex POINTER_SIZE
-@item POINTER_SIZE
+@defmac POINTER_SIZE
Width of a pointer, in bits. You must specify a value no wider than the
width of @code{Pmode}. If it is not equal to the width of @code{Pmode},
you must define @code{POINTERS_EXTEND_UNSIGNED}. If you do not specify
a value the default is @code{BITS_PER_WORD}.
+@end defmac
-@findex POINTERS_EXTEND_UNSIGNED
-@item POINTERS_EXTEND_UNSIGNED
+@defmac POINTERS_EXTEND_UNSIGNED
A C expression whose value is greater than zero if pointers that need to be
extended from being @code{POINTER_SIZE} bits wide to @code{Pmode} are to
be zero-extended and zero if they are to be sign-extended. If the value
@@ -983,9 +1034,9 @@ extends a pointer from @code{POINTER_SIZE} to @code{Pmode}.
You need not define this macro if the @code{POINTER_SIZE} is equal
to the width of @code{Pmode}.
+@end defmac
-@findex PROMOTE_MODE
-@item PROMOTE_MODE (@var{m}, @var{unsignedp}, @var{type})
+@defmac PROMOTE_MODE (@var{m}, @var{unsignedp}, @var{type})
A macro to update @var{m} and @var{unsignedp} when an object whose type
is @var{type} and which has the specified mode and signedness is to be
stored in a register. This macro is only called when @var{type} is a
@@ -1006,52 +1057,53 @@ sign-extend the result to 64 bits. On such machines, set
@var{unsignedp} according to which kind of extension is more efficient.
Do not define this macro if it would never modify @var{m}.
+@end defmac
-@findex PROMOTE_FUNCTION_ARGS
-@item PROMOTE_FUNCTION_ARGS
-Define this macro if the promotion described by @code{PROMOTE_MODE}
-should also be done for outgoing function arguments.
+@deftypefn {Target Hook} bool TARGET_PROMOTE_FUNCTION_ARGS (tree @var{fntype})
+This target hook should return @code{true} if the promotion described by
+@code{PROMOTE_MODE} should also be done for outgoing function arguments.
+@end deftypefn
-@findex PROMOTE_FUNCTION_RETURN
-@item PROMOTE_FUNCTION_RETURN
-Define this macro if the promotion described by @code{PROMOTE_MODE}
-should also be done for the return value of functions.
+@deftypefn {Target Hook} bool TARGET_PROMOTE_FUNCTION_RETURN (tree @var{fntype})
+This target hook should return @code{true} if the promotion described by
+@code{PROMOTE_MODE} should also be done for the return value of
+functions.
-If this macro is defined, @code{FUNCTION_VALUE} must perform the same
-promotions done by @code{PROMOTE_MODE}.
+If this target hook returns @code{true}, @code{FUNCTION_VALUE} must
+perform the same promotions done by @code{PROMOTE_MODE}.
+@end deftypefn
-@findex PROMOTE_FOR_CALL_ONLY
-@item PROMOTE_FOR_CALL_ONLY
+@defmac PROMOTE_FOR_CALL_ONLY
Define this macro if the promotion described by @code{PROMOTE_MODE}
should @emph{only} be performed for outgoing function arguments or
-function return values, as specified by @code{PROMOTE_FUNCTION_ARGS}
-and @code{PROMOTE_FUNCTION_RETURN}, respectively.
+function return values, as specified by @code{TARGET_PROMOTE_FUNCTION_ARGS}
+and @code{TARGET_PROMOTE_FUNCTION_RETURN}, respectively.
+@end defmac
-@findex PARM_BOUNDARY
-@item PARM_BOUNDARY
+@defmac PARM_BOUNDARY
Normal alignment required for function parameters on the stack, in
bits. All stack parameters receive at least this much alignment
regardless of data type. On most machines, this is the same as the
size of an integer.
+@end defmac
-@findex STACK_BOUNDARY
-@item STACK_BOUNDARY
+@defmac STACK_BOUNDARY
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). This value is used as a default
if @code{PREFERRED_STACK_BOUNDARY} is not defined. On most machines,
this should be the same as @code{PARM_BOUNDARY}.
+@end defmac
-@findex PREFERRED_STACK_BOUNDARY
-@item PREFERRED_STACK_BOUNDARY
+@defmac PREFERRED_STACK_BOUNDARY
Define this macro if you wish to preserve a certain alignment for the
stack pointer, greater than what the hardware enforces. The definition
is a C expression for the desired alignment (measured in bits). This
macro must evaluate to a value equal to or larger than
@code{STACK_BOUNDARY}.
+@end defmac
-@findex FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
-@item FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
+@defmac FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
A C expression that evaluates true if @code{PREFERRED_STACK_BOUNDARY} is
not guaranteed by the runtime and we should emit code to align the stack
at the beginning of @code{main}.
@@ -1061,47 +1113,47 @@ If @code{PUSH_ROUNDING} is not defined, the stack will always be aligned
to the specified boundary. If @code{PUSH_ROUNDING} is defined and specifies
a less strict alignment than @code{PREFERRED_STACK_BOUNDARY}, the stack may
be momentarily unaligned while pushing arguments.
+@end defmac
-@findex FUNCTION_BOUNDARY
-@item FUNCTION_BOUNDARY
+@defmac FUNCTION_BOUNDARY
Alignment required for a function entry point, in bits.
+@end defmac
-@findex BIGGEST_ALIGNMENT
-@item BIGGEST_ALIGNMENT
+@defmac BIGGEST_ALIGNMENT
Biggest alignment that any data type can require on this machine, in bits.
+@end defmac
-@findex MINIMUM_ATOMIC_ALIGNMENT
-@item MINIMUM_ATOMIC_ALIGNMENT
+@defmac MINIMUM_ATOMIC_ALIGNMENT
If defined, the smallest alignment, in bits, that can be given to an
object that can be referenced in one operation, without disturbing any
nearby object. Normally, this is @code{BITS_PER_UNIT}, but may be larger
on machines that don't have byte or half-word store operations.
+@end defmac
-@findex BIGGEST_FIELD_ALIGNMENT
-@item BIGGEST_FIELD_ALIGNMENT
+@defmac BIGGEST_FIELD_ALIGNMENT
Biggest alignment that any structure or union field can require on this
machine, in bits. If defined, this overrides @code{BIGGEST_ALIGNMENT} for
structure and union fields only, unless the field alignment has been set
by the @code{__attribute__ ((aligned (@var{n})))} construct.
+@end defmac
-@findex ADJUST_FIELD_ALIGN
-@item ADJUST_FIELD_ALIGN (@var{field}, @var{computed})
+@defmac ADJUST_FIELD_ALIGN (@var{field}, @var{computed})
An expression for the alignment of a structure field @var{field} if the
alignment computed in the usual way (including applying of
@code{BIGGEST_ALIGNMENT} and @code{BIGGEST_FIELD_ALIGNMENT} to the
alignment) is @var{computed}. It overrides alignment only if the
field alignment has not been set by the
@code{__attribute__ ((aligned (@var{n})))} construct.
+@end defmac
-@findex MAX_OFILE_ALIGNMENT
-@item MAX_OFILE_ALIGNMENT
+@defmac MAX_OFILE_ALIGNMENT
Biggest alignment supported by the object file format of this machine.
Use this macro to limit the alignment which can be specified using the
@code{__attribute__ ((aligned (@var{n})))} construct. If not defined,
the default value is @code{BIGGEST_ALIGNMENT}.
+@end defmac
-@findex DATA_ALIGNMENT
-@item DATA_ALIGNMENT (@var{type}, @var{basic-align})
+@defmac DATA_ALIGNMENT (@var{type}, @var{basic-align})
If defined, a C expression to compute the alignment for a variable in
the static store. @var{type} is the data type, and @var{basic-align} is
the alignment that the object would ordinarily have. The value of this
@@ -1114,9 +1166,9 @@ One use of this macro is to increase alignment of medium-size data to
make it all fit in fewer cache lines. Another is to cause character
arrays to be word-aligned so that @code{strcpy} calls that copy
constants to character arrays can be done inline.
+@end defmac
-@findex CONSTANT_ALIGNMENT
-@item CONSTANT_ALIGNMENT (@var{constant}, @var{basic-align})
+@defmac CONSTANT_ALIGNMENT (@var{constant}, @var{basic-align})
If defined, a C expression to compute the alignment given to a constant
that is being placed in memory. @var{constant} is the constant and
@var{basic-align} is the alignment that the object would ordinarily
@@ -1128,9 +1180,9 @@ If this macro is not defined, then @var{basic-align} is used.
The typical use of this macro is to increase alignment for string
constants to be word aligned so that @code{strcpy} calls that copy
constants can be done inline.
+@end defmac
-@findex LOCAL_ALIGNMENT
-@item LOCAL_ALIGNMENT (@var{type}, @var{basic-align})
+@defmac LOCAL_ALIGNMENT (@var{type}, @var{basic-align})
If defined, a C expression to compute the alignment for a variable in
the local store. @var{type} is the data type, and @var{basic-align} is
the alignment that the object would ordinarily have. The value of this
@@ -1140,45 +1192,46 @@ If this macro is not defined, then @var{basic-align} is used.
One use of this macro is to increase alignment of medium-size data to
make it all fit in fewer cache lines.
+@end defmac
-@findex EMPTY_FIELD_BOUNDARY
-@item EMPTY_FIELD_BOUNDARY
+@defmac EMPTY_FIELD_BOUNDARY
Alignment in bits to be given to a structure bit-field that follows an
empty field such as @code{int : 0;}.
-Note that @code{PCC_BITFIELD_TYPE_MATTERS} also affects the alignment
-that results from an empty field.
+If @code{PCC_BITFIELD_TYPE_MATTERS} is true, it overrides this macro.
+@end defmac
-@findex STRUCTURE_SIZE_BOUNDARY
-@item STRUCTURE_SIZE_BOUNDARY
+@defmac STRUCTURE_SIZE_BOUNDARY
Number of bits which any structure or union's size must be a multiple of.
Each structure or union's size is rounded up to a multiple of this.
If you do not define this macro, the default is the same as
@code{BITS_PER_UNIT}.
+@end defmac
-@findex STRICT_ALIGNMENT
-@item STRICT_ALIGNMENT
+@defmac STRICT_ALIGNMENT
Define this macro to be the value 1 if instructions will fail to work
if given data not on the nominal alignment. If instructions will merely
go slower in that case, define this macro as 0.
+@end defmac
-@findex PCC_BITFIELD_TYPE_MATTERS
-@item PCC_BITFIELD_TYPE_MATTERS
+@defmac PCC_BITFIELD_TYPE_MATTERS
Define this if you wish to imitate the way many other C compilers handle
alignment of bit-fields and the structures that contain them.
-The behavior is that the type written for a bit-field (@code{int},
-@code{short}, or other integer type) imposes an alignment for the
-entire structure, as if the structure really did contain an ordinary
-field of that type. In addition, the bit-field is placed within the
-structure so that it would fit within such a field, not crossing a
-boundary for it.
+The behavior is that the type written for a named bit-field (@code{int},
+@code{short}, or other integer type) imposes an alignment for the entire
+structure, as if the structure really did contain an ordinary field of
+that type. In addition, the bit-field is placed within the structure so
+that it would fit within such a field, not crossing a boundary for it.
+
+Thus, on most machines, a named bit-field whose type is written as
+@code{int} would not cross a four-byte boundary, and would force
+four-byte alignment for the whole structure. (The alignment used may
+not be four bytes; it is controlled by the other alignment parameters.)
-Thus, on most machines, a bit-field whose type is written as @code{int}
-would not cross a four-byte boundary, and would force four-byte
-alignment for the whole structure. (The alignment used may not be four
-bytes; it is controlled by the other alignment parameters.)
+An unnamed bit-field will not affect the alignment of the containing
+structure.
If the macro is defined, its definition should be a C expression;
a nonzero value for the expression enables this behavior.
@@ -1200,7 +1253,7 @@ If your aim is to make GCC use the same conventions for laying out
bit-fields as are used by another compiler, here is how to investigate
what the other compiler does. Compile and run this program:
-@example
+@smallexample
struct foo1
@{
char x;
@@ -1223,18 +1276,18 @@ main ()
sizeof (struct foo2));
exit (0);
@}
-@end example
+@end smallexample
If this prints 2 and 5, then the compiler's behavior is what you would
get from @code{PCC_BITFIELD_TYPE_MATTERS}.
+@end defmac
-@findex BITFIELD_NBYTES_LIMITED
-@item BITFIELD_NBYTES_LIMITED
+@defmac BITFIELD_NBYTES_LIMITED
Like @code{PCC_BITFIELD_TYPE_MATTERS} except that its effect is limited
to aligning a bit-field within the structure.
+@end defmac
-@findex MEMBER_TYPE_FORCES_BLK
-@item MEMBER_TYPE_FORCES_BLK (@var{field}, @var{mode})
+@defmac MEMBER_TYPE_FORCES_BLK (@var{field}, @var{mode})
Return 1 if a structure or array containing @var{field} should be accessed using
@code{BLKMODE}.
@@ -1246,24 +1299,9 @@ retain the field's mode.
Normally, this is not needed. See the file @file{c4x.h} for an example
of how to use this macro to prevent a structure having a floating point
field from being accessed in an integer mode.
+@end defmac
-@findex ROUND_TYPE_SIZE
-@item ROUND_TYPE_SIZE (@var{type}, @var{computed}, @var{specified})
-Define this macro as an expression for the overall size of a type
-(given by @var{type} as a tree node) when the size computed in the
-usual way is @var{computed} and the alignment is @var{specified}.
-
-The default is to round @var{computed} up to a multiple of @var{specified}.
-
-@findex ROUND_TYPE_SIZE_UNIT
-@item ROUND_TYPE_SIZE_UNIT (@var{type}, @var{computed}, @var{specified})
-Similar to @code{ROUND_TYPE_SIZE}, but sizes and alignments are
-specified in units (bytes). If you define @code{ROUND_TYPE_SIZE},
-you must also define this macro and they must be defined consistently
-with each other.
-
-@findex ROUND_TYPE_ALIGN
-@item ROUND_TYPE_ALIGN (@var{type}, @var{computed}, @var{specified})
+@defmac ROUND_TYPE_ALIGN (@var{type}, @var{computed}, @var{specified})
Define this macro as an expression for the alignment of a type (given
by @var{type} as a tree node) if the alignment computed in the usual
way is @var{computed} and the alignment explicitly specified was
@@ -1271,23 +1309,23 @@ way is @var{computed} and the alignment explicitly specified was
The default is to use @var{specified} if it is larger; otherwise, use
the smaller of @var{computed} and @code{BIGGEST_ALIGNMENT}
+@end defmac
-@findex MAX_FIXED_MODE_SIZE
-@item MAX_FIXED_MODE_SIZE
+@defmac MAX_FIXED_MODE_SIZE
An integer expression for the size in bits of the largest integer
machine mode that should actually be used. All integer machine modes of
this size or smaller can be used for structures and unions with the
appropriate sizes. If this macro is undefined, @code{GET_MODE_BITSIZE
(DImode)} is assumed.
+@end defmac
-@findex VECTOR_MODE_SUPPORTED_P
-@item VECTOR_MODE_SUPPORTED_P(@var{mode})
+@defmac VECTOR_MODE_SUPPORTED_P (@var{mode})
Define this macro to be nonzero if the port is prepared to handle insns
involving vector mode @var{mode}. At the very least, it must have move
patterns for this mode.
+@end defmac
-@findex STACK_SAVEAREA_MODE
-@item STACK_SAVEAREA_MODE (@var{save_level})
+@defmac STACK_SAVEAREA_MODE (@var{save_level})
If defined, an expression of type @code{enum machine_mode} that
specifies the mode of the save area operand of a
@code{save_stack_@var{level}} named pattern (@pxref{Standard Names}).
@@ -1299,9 +1337,9 @@ You need not define this macro if it always returns @code{Pmode}. You
would most commonly define this macro if the
@code{save_stack_@var{level}} patterns need to support both a 32- and a
64-bit mode.
+@end defmac
-@findex STACK_SIZE_MODE
-@item STACK_SIZE_MODE
+@defmac STACK_SIZE_MODE
If defined, an expression of type @code{enum machine_mode} that
specifies the mode of the size increment operand of an
@code{allocate_stack} named pattern (@pxref{Standard Names}).
@@ -1309,45 +1347,37 @@ specifies the mode of the size increment operand of an
You need not define this macro if it always returns @code{word_mode}.
You would most commonly define this macro if the @code{allocate_stack}
pattern needs to support both a 32- and a 64-bit mode.
+@end defmac
-@findex TARGET_FLOAT_FORMAT
-@item TARGET_FLOAT_FORMAT
+@defmac TARGET_FLOAT_FORMAT
A code distinguishing the floating point format of the target machine.
-There are five defined values:
+There are four defined values:
-@table @code
-@findex IEEE_FLOAT_FORMAT
+@ftable @code
@item IEEE_FLOAT_FORMAT
This code indicates IEEE floating point. It is the default; there is no
-need to define this macro when the format is IEEE@.
+need to define @code{TARGET_FLOAT_FORMAT} when the format is IEEE@.
-@findex VAX_FLOAT_FORMAT
@item VAX_FLOAT_FORMAT
This code indicates the ``F float'' (for @code{float}) and ``D float''
or ``G float'' formats (for @code{double}) used on the VAX and PDP-11@.
-@findex IBM_FLOAT_FORMAT
@item IBM_FLOAT_FORMAT
This code indicates the format used on the IBM System/370.
-@findex C4X_FLOAT_FORMAT
@item C4X_FLOAT_FORMAT
This code indicates the format used on the TMS320C3x/C4x.
+@end ftable
-@findex UNKNOWN_FLOAT_FORMAT
-@item UNKNOWN_FLOAT_FORMAT
-This code indicates any other format.
-@end table
-
-If any other
-formats are actually in use on supported machines, new codes should be
-defined for them.
+If your target uses a floating point format other than these, you must
+define a new @var{name}_FLOAT_FORMAT code for it, and add support for
+it to @file{real.c}.
The ordering of the component words of floating point values stored in
memory is controlled by @code{FLOAT_WORDS_BIG_ENDIAN}.
+@end defmac
-@findex MODE_HAS_NANS
-@item MODE_HAS_NANS (@var{mode})
+@defmac MODE_HAS_NANS (@var{mode})
When defined, this macro should be true if @var{mode} has a NaN
representation. The compiler assumes that NaNs are not equal to
anything (including themselves) and that addition, subtraction,
@@ -1356,16 +1386,16 @@ NaN@.
By default, this macro is true if @var{mode} is a floating-point
mode and the target floating-point format is IEEE@.
+@end defmac
-@findex MODE_HAS_INFINITIES
-@item MODE_HAS_INFINITIES (@var{mode})
+@defmac MODE_HAS_INFINITIES (@var{mode})
This macro should be true if @var{mode} can represent infinity. At
present, the compiler uses this macro to decide whether @samp{x - x}
is always defined. By default, the macro is true when @var{mode}
is a floating-point mode and the target format is IEEE@.
+@end defmac
-@findex MODE_HAS_SIGNED_ZEROS
-@item MODE_HAS_SIGNED_ZEROS (@var{mode})
+@defmac MODE_HAS_SIGNED_ZEROS (@var{mode})
True if @var{mode} distinguishes between positive and negative zero.
The rules are expected to follow the IEEE standard:
@@ -1385,9 +1415,9 @@ of the operands is negative.
The default definition is true if @var{mode} is a floating-point
mode and the target format is IEEE@.
+@end defmac
-@findex MODE_HAS_SIGN_DEPENDENT_ROUNDING
-@item MODE_HAS_SIGN_DEPENDENT_ROUNDING (@var{mode})
+@defmac MODE_HAS_SIGN_DEPENDENT_ROUNDING (@var{mode})
If defined, this macro should be true for @var{mode} if it has at
least one rounding mode in which @samp{x} and @samp{-x} can be
rounded to numbers of different magnitude. Two such modes are
@@ -1395,9 +1425,9 @@ towards @minus{}infinity and towards +infinity.
The default definition of this macro is true if @var{mode} is
a floating-point mode and the target format is IEEE@.
+@end defmac
-@findex ROUND_TOWARDS_ZERO
-@item ROUND_TOWARDS_ZERO
+@defmac ROUND_TOWARDS_ZERO
If defined, this macro should be true if the prevailing rounding
mode is towards zero. A true value has the following effects:
@@ -1421,9 +1451,9 @@ primary rounding mode is towards zero, library functions like
parser should behave like the target's @code{strtod} where possible.
Not defining this macro is equivalent to returning zero.
+@end defmac
-@findex LARGEST_EXPONENT_IS_NORMAL
-@item LARGEST_EXPONENT_IS_NORMAL (@var{size})
+@defmac LARGEST_EXPONENT_IS_NORMAL (@var{size})
This macro should return true if floats with @var{size}
bits do not have a NaN or infinity representation, but use the largest
exponent for normal numbers instead.
@@ -1434,7 +1464,15 @@ It also affects the way @file{libgcc.a} and @file{real.c} emulate
floating-point arithmetic.
The default definition of this macro returns false for all sizes.
-@end table
+@end defmac
+
+@deftypefn {Target Hook} bool TARGET_VECTOR_OPAQUE_P (tree @var{type})
+This target hook should return @code{true} a vector is opaque. That
+is, if no cast is needed when copying a vector value of type
+@var{type} into another vector lvalue of the same size. Vector opaque
+types cannot be initialized. The default is that there are no such
+types.
+@end deftypefn
@deftypefn {Target Hook} bool TARGET_MS_BITFIELD_LAYOUT_P (tree @var{record_type})
This target hook returns @code{true} if bit-fields in the given
@@ -1472,116 +1510,115 @@ basic data types used in programs being compiled. Unlike the macros in
the previous section, these apply to specific features of C and related
languages, rather than to fundamental aspects of storage layout.
-@table @code
-@findex INT_TYPE_SIZE
-@item INT_TYPE_SIZE
+@defmac INT_TYPE_SIZE
A C expression for the size in bits of the type @code{int} on the
target machine. If you don't define this, the default is one word.
+@end defmac
-@findex SHORT_TYPE_SIZE
-@item SHORT_TYPE_SIZE
+@defmac SHORT_TYPE_SIZE
A C expression for the size in bits of the type @code{short} on the
target machine. If you don't define this, the default is half a word.
(If this would be less than one storage unit, it is rounded up to one
unit.)
+@end defmac
-@findex LONG_TYPE_SIZE
-@item LONG_TYPE_SIZE
+@defmac LONG_TYPE_SIZE
A C expression for the size in bits of the type @code{long} on the
target machine. If you don't define this, the default is one word.
+@end defmac
-@findex ADA_LONG_TYPE_SIZE
-@item ADA_LONG_TYPE_SIZE
+@defmac ADA_LONG_TYPE_SIZE
On some machines, the size used for the Ada equivalent of the type
@code{long} by a native Ada compiler differs from that used by C. In
that situation, define this macro to be a C expression to be used for
the size of that type. If you don't define this, the default is the
value of @code{LONG_TYPE_SIZE}.
+@end defmac
-@findex MAX_LONG_TYPE_SIZE
-@item MAX_LONG_TYPE_SIZE
+@defmac MAX_LONG_TYPE_SIZE
Maximum number for the size in bits of the type @code{long} on the
target machine. If this is undefined, the default is
@code{LONG_TYPE_SIZE}. Otherwise, it is the constant value that is the
largest value that @code{LONG_TYPE_SIZE} can have at run-time. This is
used in @code{cpp}.
+@end defmac
-@findex LONG_LONG_TYPE_SIZE
-@item LONG_LONG_TYPE_SIZE
+@defmac LONG_LONG_TYPE_SIZE
A C expression for the size in bits of the type @code{long long} on the
target machine. If you don't define this, the default is two
words. If you want to support GNU Ada on your machine, the value of this
macro must be at least 64.
+@end defmac
-@findex CHAR_TYPE_SIZE
-@item CHAR_TYPE_SIZE
+@defmac CHAR_TYPE_SIZE
A C expression for the size in bits of the type @code{char} on the
target machine. If you don't define this, the default is
@code{BITS_PER_UNIT}.
+@end defmac
-@findex BOOL_TYPE_SIZE
-@item BOOL_TYPE_SIZE
+@defmac BOOL_TYPE_SIZE
A C expression for the size in bits of the C++ type @code{bool} and
C99 type @code{_Bool} on the target machine. If you don't define
this, and you probably shouldn't, the default is @code{CHAR_TYPE_SIZE}.
+@end defmac
-@findex FLOAT_TYPE_SIZE
-@item FLOAT_TYPE_SIZE
+@defmac FLOAT_TYPE_SIZE
A C expression for the size in bits of the type @code{float} on the
target machine. If you don't define this, the default is one word.
+@end defmac
-@findex DOUBLE_TYPE_SIZE
-@item DOUBLE_TYPE_SIZE
+@defmac DOUBLE_TYPE_SIZE
A C expression for the size in bits of the type @code{double} on the
target machine. If you don't define this, the default is two
words.
+@end defmac
-@findex LONG_DOUBLE_TYPE_SIZE
-@item LONG_DOUBLE_TYPE_SIZE
+@defmac LONG_DOUBLE_TYPE_SIZE
A C expression for the size in bits of the type @code{long double} on
the target machine. If you don't define this, the default is two
words.
+@end defmac
-@findex MAX_LONG_DOUBLE_TYPE_SIZE
+@defmac MAX_LONG_DOUBLE_TYPE_SIZE
Maximum number for the size in bits of the type @code{long double} on the
target machine. If this is undefined, the default is
@code{LONG_DOUBLE_TYPE_SIZE}. Otherwise, it is the constant value that is
the largest value that @code{LONG_DOUBLE_TYPE_SIZE} can have at run-time.
This is used in @code{cpp}.
+@end defmac
-@findex TARGET_FLT_EVAL_METHOD
-@item TARGET_FLT_EVAL_METHOD
+@defmac TARGET_FLT_EVAL_METHOD
A C expression for the value for @code{FLT_EVAL_METHOD} in @file{float.h},
assuming, if applicable, that the floating-point control word is in its
default state. If you do not define this macro the value of
@code{FLT_EVAL_METHOD} will be zero.
+@end defmac
-@findex WIDEST_HARDWARE_FP_SIZE
-@item WIDEST_HARDWARE_FP_SIZE
+@defmac WIDEST_HARDWARE_FP_SIZE
A C expression for the size in bits of the widest floating-point format
supported by the hardware. If you define this macro, you must specify a
value less than or equal to the value of @code{LONG_DOUBLE_TYPE_SIZE}.
If you do not define this macro, the value of @code{LONG_DOUBLE_TYPE_SIZE}
is the default.
+@end defmac
-@findex DEFAULT_SIGNED_CHAR
-@item DEFAULT_SIGNED_CHAR
+@defmac DEFAULT_SIGNED_CHAR
An expression whose value is 1 or 0, according to whether the type
@code{char} should be signed or unsigned by default. The user can
always override this default with the options @option{-fsigned-char}
and @option{-funsigned-char}.
+@end defmac
-@findex DEFAULT_SHORT_ENUMS
-@item DEFAULT_SHORT_ENUMS
+@defmac DEFAULT_SHORT_ENUMS
A C expression to determine whether to give an @code{enum} type
only as many bytes as it takes to represent the range of possible values
of that type. A nonzero value means to do that; a zero value means all
@code{enum} types should be allocated like @code{int}.
If you don't define the macro, the default is 0.
+@end defmac
-@findex SIZE_TYPE
-@item SIZE_TYPE
+@defmac SIZE_TYPE
A C expression for a string describing the name of the data type to use
for size values. The typedef name @code{size_t} is defined using the
contents of the string.
@@ -1596,49 +1633,49 @@ crash on startup.
If you don't define this macro, the default is @code{"long unsigned
int"}.
+@end defmac
-@findex PTRDIFF_TYPE
-@item PTRDIFF_TYPE
+@defmac PTRDIFF_TYPE
A C expression for a string describing the name of the data type to use
for the result of subtracting two pointers. The typedef name
@code{ptrdiff_t} is defined using the contents of the string. See
@code{SIZE_TYPE} above for more information.
If you don't define this macro, the default is @code{"long int"}.
+@end defmac
-@findex WCHAR_TYPE
-@item WCHAR_TYPE
+@defmac WCHAR_TYPE
A C expression for a string describing the name of the data type to use
for wide characters. The typedef name @code{wchar_t} is defined using
the contents of the string. See @code{SIZE_TYPE} above for more
information.
If you don't define this macro, the default is @code{"int"}.
+@end defmac
-@findex WCHAR_TYPE_SIZE
-@item WCHAR_TYPE_SIZE
+@defmac WCHAR_TYPE_SIZE
A C expression for the size in bits of the data type for wide
characters. This is used in @code{cpp}, which cannot make use of
@code{WCHAR_TYPE}.
+@end defmac
-@findex MAX_WCHAR_TYPE_SIZE
-@item MAX_WCHAR_TYPE_SIZE
+@defmac MAX_WCHAR_TYPE_SIZE
Maximum number for the size in bits of the data type for wide
characters. If this is undefined, the default is
@code{WCHAR_TYPE_SIZE}. Otherwise, it is the constant value that is the
largest value that @code{WCHAR_TYPE_SIZE} can have at run-time. This is
used in @code{cpp}.
+@end defmac
-@findex GCOV_TYPE_SIZE
-@item GCOV_TYPE_SIZE
+@defmac GCOV_TYPE_SIZE
A C expression for the size in bits of the type used for gcov counters on the
target machine. If you don't define this, the default is one
@code{LONG_TYPE_SIZE} in case it is greater or equal to 64-bit and
@code{LONG_LONG_TYPE_SIZE} otherwise. You may want to re-define the type to
ensure atomicity for counters in multithreaded programs.
+@end defmac
-@findex WINT_TYPE
-@item WINT_TYPE
+@defmac WINT_TYPE
A C expression for a string describing the name of the data type to
use for wide characters passed to @code{printf} and returned from
@code{getwc}. The typedef name @code{wint_t} is defined using the
@@ -1646,9 +1683,9 @@ contents of the string. See @code{SIZE_TYPE} above for more
information.
If you don't define this macro, the default is @code{"unsigned int"}.
+@end defmac
-@findex INTMAX_TYPE
-@item INTMAX_TYPE
+@defmac INTMAX_TYPE
A C expression for a string describing the name of the data type that
can represent any value of any standard or extended signed integer type.
The typedef name @code{intmax_t} is defined using the contents of the
@@ -1657,9 +1694,9 @@ string. See @code{SIZE_TYPE} above for more information.
If you don't define this macro, the default is the first of
@code{"int"}, @code{"long int"}, or @code{"long long int"} that has as
much precision as @code{long long int}.
+@end defmac
-@findex UINTMAX_TYPE
-@item UINTMAX_TYPE
+@defmac UINTMAX_TYPE
A C expression for a string describing the name of the data type that
can represent any value of any standard or extended unsigned integer
type. The typedef name @code{uintmax_t} is defined using the contents
@@ -1669,13 +1706,13 @@ If you don't define this macro, the default is the first of
@code{"unsigned int"}, @code{"long unsigned int"}, or @code{"long long
unsigned int"} that has as much precision as @code{long long unsigned
int}.
+@end defmac
-@findex TARGET_PTRMEMFUNC_VBIT_LOCATION
-@item TARGET_PTRMEMFUNC_VBIT_LOCATION
+@defmac TARGET_PTRMEMFUNC_VBIT_LOCATION
The C++ compiler represents a pointer-to-member-function with a struct
that looks like:
-@example
+@smallexample
struct @{
union @{
void (*fn)();
@@ -1683,7 +1720,7 @@ that looks like:
@};
ptrdiff_t delta;
@};
-@end example
+@end smallexample
@noindent
The C++ compiler must use one bit to indicate whether the function that
@@ -1708,9 +1745,9 @@ In general, you should not have to define this macro. On architectures
in which function addresses are always even, according to
@code{FUNCTION_BOUNDARY}, GCC will automatically define this macro to
@code{ptrmemfunc_vbit_in_pfn}.
+@end defmac
-@findex TARGET_VTABLE_USES_DESCRIPTORS
-@item TARGET_VTABLE_USES_DESCRIPTORS
+@defmac TARGET_VTABLE_USES_DESCRIPTORS
Normally, the C++ compiler uses function pointers in vtables. This
macro allows the target to change to use ``function descriptors''
instead. Function descriptors are found on targets for whom a
@@ -1720,21 +1757,21 @@ pointer to which the function's data is relative.
If vtables are used, the value of this macro should be the number
of words that the function descriptor occupies.
+@end defmac
-@findex TARGET_VTABLE_ENTRY_ALIGN
-@item TARGET_VTABLE_ENTRY_ALIGN
+@defmac TARGET_VTABLE_ENTRY_ALIGN
By default, the vtable entries are void pointers, the so the alignment
is the same as pointer alignment. The value of this macro specifies
the alignment of the vtable entry in bits. It should be defined only
when special alignment is necessary. */
+@end defmac
-@findex TARGET_VTABLE_DATA_ENTRY_DISTANCE
-@item TARGET_VTABLE_DATA_ENTRY_DISTANCE
+@defmac TARGET_VTABLE_DATA_ENTRY_DISTANCE
There are a few non-descriptor entries in the vtable at offsets below
zero. If these entries must be padded (say, to preserve the alignment
specified by @code{TARGET_VTABLE_ENTRY_ALIGN}), set this to the number
of words in each data entry.
-@end table
+@end defmac
@node Escape Sequences
@section Target Character Escape Sequences
@@ -1742,38 +1779,30 @@ of words in each data entry.
By default, GCC assumes that the C character escape sequences take on
their ASCII values for the target. If this is not correct, you must
-explicitly define all of the macros below.
+explicitly define all of the macros below. All of them must evaluate
+to constants; they are used in @code{case} statements.
-@table @code
@findex TARGET_BELL
-@item TARGET_BELL
-A C constant expression for the integer value for escape sequence
-@samp{\a}.
-
+@findex TARGET_CR
@findex TARGET_ESC
-@item TARGET_ESC
-A C constant expression for the integer value of the target escape
-character. As an extension, GCC evaluates the escape sequences
-@samp{\e} and @samp{\E} to this.
-
-@findex TARGET_TAB
-@findex TARGET_BS
+@findex TARGET_FF
@findex TARGET_NEWLINE
-@item TARGET_BS
-@itemx TARGET_TAB
-@itemx TARGET_NEWLINE
-C constant expressions for the integer values for escape sequences
-@samp{\b}, @samp{\t} and @samp{\n}.
-
+@findex TARGET_TAB
@findex TARGET_VT
-@findex TARGET_FF
-@findex TARGET_CR
-@item TARGET_VT
-@itemx TARGET_FF
-@itemx TARGET_CR
-C constant expressions for the integer values for escape sequences
-@samp{\v}, @samp{\f} and @samp{\r}.
-@end table
+@multitable {@code{TARGET_NEWLINE}} {Escape} {ASCII character}
+@item Macro @tab Escape @tab ASCII character
+@item @code{TARGET_BELL} @tab @kbd{\a} @tab @code{07}, @code{BEL}
+@item @code{TARGET_CR} @tab @kbd{\r} @tab @code{0D}, @code{CR}
+@item @code{TARGET_ESC} @tab @kbd{\e}, @kbd{\E} @tab @code{1B}, @code{ESC}
+@item @code{TARGET_FF} @tab @kbd{\f} @tab @code{0C}, @code{FF}
+@item @code{TARGET_NEWLINE} @tab @kbd{\n} @tab @code{0A}, @code{LF}
+@item @code{TARGET_TAB} @tab @kbd{\t} @tab @code{09}, @code{HT}
+@item @code{TARGET_VT} @tab @kbd{\v} @tab @code{0B}, @code{VT}
+@end multitable
+
+@noindent
+Note that the @kbd{\e} and @kbd{\E} escapes are GNU extensions, not
+part of the C standard.
@node Registers
@section Register Usage
@@ -1802,16 +1831,14 @@ For returning values in registers, see @ref{Scalar Return}.
@c prevent bad page break with this line
Registers have various characteristics.
-@table @code
-@findex FIRST_PSEUDO_REGISTER
-@item FIRST_PSEUDO_REGISTER
+@defmac FIRST_PSEUDO_REGISTER
Number of hardware registers known to the compiler. They receive
numbers 0 through @code{FIRST_PSEUDO_REGISTER-1}; thus, the first
pseudo register's number really is assigned the number
@code{FIRST_PSEUDO_REGISTER}.
+@end defmac
-@item FIXED_REGISTERS
-@findex FIXED_REGISTERS
+@defmac FIXED_REGISTERS
@cindex fixed register
An initializer that says which registers are used for fixed purposes
all throughout the compiled code and are therefore not available for
@@ -1830,9 +1857,9 @@ the following one, may be overridden at run time either automatically,
by the actions of the macro @code{CONDITIONAL_REGISTER_USAGE}, or by
the user with the command options @option{-ffixed-@var{reg}},
@option{-fcall-used-@var{reg}} and @option{-fcall-saved-@var{reg}}.
+@end defmac
-@findex CALL_USED_REGISTERS
-@item CALL_USED_REGISTERS
+@defmac CALL_USED_REGISTERS
@cindex call-used register
@cindex call-clobbered register
@cindex call-saved register
@@ -1845,9 +1872,9 @@ function calls.
If a register has 0 in @code{CALL_USED_REGISTERS}, the compiler
automatically saves it on function entry and restores it on function
exit, if the register is used within the function.
+@end defmac
-@findex CALL_REALLY_USED_REGISTERS
-@item CALL_REALLY_USED_REGISTERS
+@defmac CALL_REALLY_USED_REGISTERS
@cindex call-used register
@cindex call-clobbered register
@cindex call-saved register
@@ -1856,9 +1883,9 @@ that the entire set of @code{FIXED_REGISTERS} be included.
(@code{CALL_USED_REGISTERS} must be a superset of @code{FIXED_REGISTERS}).
This macro is optional. If not specified, it defaults to the value
of @code{CALL_USED_REGISTERS}.
+@end defmac
-@findex HARD_REGNO_CALL_PART_CLOBBERED
-@item HARD_REGNO_CALL_PART_CLOBBERED (@var{regno}, @var{mode})
+@defmac HARD_REGNO_CALL_PART_CLOBBERED (@var{regno}, @var{mode})
@cindex call-used register
@cindex call-clobbered register
@cindex call-saved register
@@ -1867,11 +1894,14 @@ value of mode @var{mode} in hard register number @var{regno} across a
call without some part of it being clobbered. For most machines this
macro need not be defined. It is only required for machines that do not
preserve the entire contents of a register across a call.
+@end defmac
-@findex CONDITIONAL_REGISTER_USAGE
@findex fixed_regs
@findex call_used_regs
-@item CONDITIONAL_REGISTER_USAGE
+@findex global_regs
+@findex reg_names
+@findex reg_class_contents
+@defmac CONDITIONAL_REGISTER_USAGE
Zero or more C statements that may conditionally modify five variables
@code{fixed_regs}, @code{call_used_regs}, @code{global_regs},
@code{reg_names}, and @code{reg_class_contents}, to take into account
@@ -1895,53 +1925,52 @@ If the usage of an entire class of registers depends on the target
flags, you may indicate this to GCC by using this macro to modify
@code{fixed_regs} and @code{call_used_regs} to 1 for each of the
registers in the classes which should not be used by GCC@. Also define
-the macro @code{REG_CLASS_FROM_LETTER} to return @code{NO_REGS} if it
+the macro @code{REG_CLASS_FROM_LETTER} / @code{REG_CLASS_FROM_CONSTRAINT}
+to return @code{NO_REGS} if it
is called with a letter for a class that shouldn't be used.
(However, if this class is not included in @code{GENERAL_REGS} and all
of the insn patterns whose constraints permit this class are
controlled by target switches, then GCC will automatically avoid using
these registers when the target switches are opposed to them.)
+@end defmac
-@findex NON_SAVING_SETJMP
-@item NON_SAVING_SETJMP
+@defmac NON_SAVING_SETJMP
If this macro is defined and has a nonzero value, it means that
@code{setjmp} and related functions fail to save the registers, or that
@code{longjmp} fails to restore them. To compensate, the compiler
avoids putting variables in registers in functions that use
@code{setjmp}.
+@end defmac
-@findex INCOMING_REGNO
-@item INCOMING_REGNO (@var{out})
+@defmac INCOMING_REGNO (@var{out})
Define this macro if the target machine has register windows. This C
expression returns the register number as seen by the called function
corresponding to the register number @var{out} as seen by the calling
function. Return @var{out} if register number @var{out} is not an
outbound register.
+@end defmac
-@findex OUTGOING_REGNO
-@item OUTGOING_REGNO (@var{in})
+@defmac OUTGOING_REGNO (@var{in})
Define this macro if the target machine has register windows. This C
expression returns the register number as seen by the calling function
corresponding to the register number @var{in} as seen by the called
function. Return @var{in} if register number @var{in} is not an inbound
register.
+@end defmac
-@findex LOCAL_REGNO
-@item LOCAL_REGNO (@var{regno})
+@defmac LOCAL_REGNO (@var{regno})
Define this macro if the target machine has register windows. This C
expression returns true if the register is call-saved but is in the
register window. Unlike most call-saved registers, such registers
need not be explicitly restored on function exit or during non-local
gotos.
+@end defmac
-@ignore
-@findex PC_REGNUM
-@item PC_REGNUM
+@defmac PC_REGNUM
If the program counter has a register number, define this as that
register number. Otherwise, do not define it.
-@end ignore
-@end table
+@end defmac
@node Allocation Order
@subsection Order of Allocation of Registers
@@ -1951,9 +1980,7 @@ register number. Otherwise, do not define it.
@c prevent bad page break with this line
Registers are allocated in order.
-@table @code
-@findex REG_ALLOC_ORDER
-@item REG_ALLOC_ORDER
+@defmac REG_ALLOC_ORDER
If defined, an initializer for a vector of integers, containing the
numbers of hard registers in the order in which GCC should prefer
to use them (from most preferred to least).
@@ -1966,9 +1993,9 @@ registers must always be saved and the save-multiple-registers
instruction supports only sequences of consecutive registers. On such
machines, define @code{REG_ALLOC_ORDER} to be an initializer that lists
the highest numbered allocable register first.
+@end defmac
-@findex ORDER_REGS_FOR_LOCAL_ALLOC
-@item ORDER_REGS_FOR_LOCAL_ALLOC
+@defmac ORDER_REGS_FOR_LOCAL_ALLOC
A C statement (sans semicolon) to choose the order in which to allocate
hard registers for pseudo-registers local to a basic block.
@@ -1980,7 +2007,7 @@ The macro body should not assume anything about the contents of
@code{reg_alloc_order} before execution of the macro.
On most machines, it is not necessary to define this macro.
-@end table
+@end defmac
@node Values in Registers
@subsection How Values Fit in Registers
@@ -1989,9 +2016,7 @@ This section discusses the macros that describe which kinds of values
(specifically, which machine modes) each register can hold, and how many
consecutive registers are needed for a given mode.
-@table @code
-@findex HARD_REGNO_NREGS
-@item HARD_REGNO_NREGS (@var{regno}, @var{mode})
+@defmac HARD_REGNO_NREGS (@var{regno}, @var{mode})
A C expression for the number of consecutive hard registers, starting
at register number @var{regno}, required to hold a value of mode
@var{mode}.
@@ -2004,9 +2029,18 @@ definition of this macro is
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
/ UNITS_PER_WORD)
@end smallexample
+@end defmac
+
+@defmac REGMODE_NATURAL_SIZE (@var{mode})
+Define this macro if the natural size of registers that hold values
+of mode @var{mode} is not the word size. It is a C expression that
+should give the natural size in bytes for the specified mode. It is
+used by the register allocator to try to optimize its results. This
+happens for example on SPARC 64-bit where the natural size of
+floating-point registers is still 32-bit.
+@end defmac
-@findex HARD_REGNO_MODE_OK
-@item HARD_REGNO_MODE_OK (@var{regno}, @var{mode})
+@defmac HARD_REGNO_MODE_OK (@var{regno}, @var{mode})
A C expression that is nonzero if it is permissible to store a value
of mode @var{mode} in hard register number @var{regno} (or in several
registers starting with that one). For a machine where all registers
@@ -2065,9 +2099,9 @@ so that it is better to store a value in a stack frame than in such a
register if floating point arithmetic is not being done. As long as the
floating registers are not in class @code{GENERAL_REGS}, they will not
be used unless some pattern's constraint asks for one.
+@end defmac
-@findex MODES_TIEABLE_P
-@item MODES_TIEABLE_P (@var{mode1}, @var{mode2})
+@defmac MODES_TIEABLE_P (@var{mode1}, @var{mode2})
A C expression that is nonzero if a value of mode
@var{mode1} is accessible in mode @var{mode2} without copying.
@@ -2081,13 +2115,13 @@ accessibility of the value in a narrower mode.
You should define this macro to return nonzero in as many cases as
possible since doing so will allow GCC to perform better register
allocation.
+@end defmac
-@findex AVOID_CCMODE_COPIES
-@item AVOID_CCMODE_COPIES
+@defmac AVOID_CCMODE_COPIES
Define this macro if the compiler should avoid copies to/from @code{CCmode}
registers. You should only define this macro if support for copying to/from
@code{CCmode} is incomplete.
-@end table
+@end defmac
@node Leaf Functions
@subsection Handling Leaf Functions
@@ -2112,9 +2146,7 @@ suitable for leaf function treatment. So it needs to renumber the
registers in order to output a leaf function. The following macros
accomplish this.
-@table @code
-@findex LEAF_REGISTERS
-@item LEAF_REGISTERS
+@defmac LEAF_REGISTERS
Name of a char vector, indexed by hard register number, which
contains 1 for a register that is allowable in a candidate for leaf
function treatment.
@@ -2127,9 +2159,9 @@ in this vector.
Define this macro only if the target machine offers a way to optimize
the treatment of leaf functions.
+@end defmac
-@findex LEAF_REG_REMAP
-@item LEAF_REG_REMAP (@var{regno})
+@defmac LEAF_REG_REMAP (@var{regno})
A C expression whose value is the register number to which @var{regno}
should be renumbered, when a function is treated as a leaf function.
@@ -2140,7 +2172,7 @@ will cause the compiler to abort.
Define this macro only if the target machine offers a way to optimize the
treatment of leaf functions, and registers need to be renumbered to do
this.
-@end table
+@end defmac
@findex current_function_is_leaf
@findex current_function_uses_only_leaf_regs
@@ -2161,28 +2193,31 @@ only useful if @code{LEAF_REGISTERS} is defined.
@subsection Registers That Form a Stack
There are special features to handle computers where some of the
-``registers'' form a stack, as in the 80387 coprocessor for the 80386.
-Stack registers are normally written by pushing onto the stack, and are
-numbered relative to the top of the stack.
+``registers'' form a stack. Stack registers are normally written by
+pushing onto the stack, and are numbered relative to the top of the
+stack.
Currently, GCC can only handle one group of stack-like registers, and
-they must be consecutively numbered.
-
-@table @code
-@findex STACK_REGS
-@item STACK_REGS
+they must be consecutively numbered. Furthermore, the existing
+support for stack-like registers is specific to the 80387 floating
+point coprocessor. If you have a new architecture that uses
+stack-like registers, you will need to do substantial work on
+@file{reg-stack.c} and write your machine description to cooperate
+with it, as well as defining these macros.
+
+@defmac STACK_REGS
Define this if the machine has any stack-like registers.
+@end defmac
-@findex FIRST_STACK_REG
-@item FIRST_STACK_REG
+@defmac FIRST_STACK_REG
The number of the first stack-like register. This one is the top
of the stack.
+@end defmac
-@findex LAST_STACK_REG
-@item LAST_STACK_REG
+@defmac LAST_STACK_REG
The number of the last stack-like register. This one is the bottom of
the stack.
-@end table
+@end defmac
@node Register Classes
@section Register Classes
@@ -2247,34 +2282,32 @@ instruction must have a subclass consisting of registers from which
single-byte values can be loaded or stored. This is so that
@code{PREFERRED_RELOAD_CLASS} can always have a possible value to return.
-@table @code
-@findex enum reg_class
-@item enum reg_class
-An enumeral type that must be defined with all the register class names
-as enumeral values. @code{NO_REGS} must be first. @code{ALL_REGS}
-must be the last register class, followed by one more enumeral value,
+@deftp {Data type} {enum reg_class}
+An enumerated type that must be defined with all the register class names
+as enumerated values. @code{NO_REGS} must be first. @code{ALL_REGS}
+must be the last register class, followed by one more enumerated value,
@code{LIM_REG_CLASSES}, which is not a register class but rather
tells how many classes there are.
Each register class has a number, which is the value of casting
the class name to type @code{int}. The number serves as an index
in many of the tables described below.
+@end deftp
-@findex N_REG_CLASSES
-@item N_REG_CLASSES
+@defmac N_REG_CLASSES
The number of distinct register classes, defined as follows:
-@example
+@smallexample
#define N_REG_CLASSES (int) LIM_REG_CLASSES
-@end example
+@end smallexample
+@end defmac
-@findex REG_CLASS_NAMES
-@item REG_CLASS_NAMES
+@defmac REG_CLASS_NAMES
An initializer containing the names of the register classes as C string
constants. These names are used in writing some of the debugging dumps.
+@end defmac
-@findex REG_CLASS_CONTENTS
-@item REG_CLASS_CONTENTS
+@defmac REG_CLASS_CONTENTS
An initializer containing the contents of the register classes, as integers
which are bit masks. The @var{n}th integer specifies the contents of class
@var{n}. The way the integer @var{mask} is interpreted is that
@@ -2287,61 +2320,82 @@ for the type @code{HARD_REG_SET} which is defined in @file{hard-reg-set.h}.
In this situation, the first integer in each sub-initializer corresponds to
registers 0 through 31, the second integer to registers 32 through 63, and
so on.
+@end defmac
-@findex REGNO_REG_CLASS
-@item REGNO_REG_CLASS (@var{regno})
+@defmac REGNO_REG_CLASS (@var{regno})
A C expression whose value is a register class containing hard register
@var{regno}. In general there is more than one such class; choose a class
which is @dfn{minimal}, meaning that no smaller class also contains the
register.
+@end defmac
-@findex BASE_REG_CLASS
-@item BASE_REG_CLASS
+@defmac BASE_REG_CLASS
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.
+@end defmac
-@findex MODE_BASE_REG_CLASS
-@item MODE_BASE_REG_CLASS (@var{mode})
+@defmac MODE_BASE_REG_CLASS (@var{mode})
This is a variation of the @code{BASE_REG_CLASS} macro which allows
the selection of a base register in a mode dependent manner. If
@var{mode} is VOIDmode then it should return the same value as
@code{BASE_REG_CLASS}.
+@end defmac
-@findex INDEX_REG_CLASS
-@item INDEX_REG_CLASS
+@defmac INDEX_REG_CLASS
A macro whose definition is the name of the class to which a valid
index register must belong. An index register is one used in an
address where its value is either multiplied by a scale factor or
added to another register (as well as added to a displacement).
+@end defmac
+
+@defmac CONSTRAINT_LEN (@var{char}, @var{str})
+For the constraint at the start of @var{str}, which starts with the letter
+@var{c}, return the length. This allows you to have register class /
+constant / extra constraints that are longer than a single letter;
+you don't need to define this macro if you can do with single-letter
+constraints only. The definition of this macro should use
+DEFAULT_CONSTRAINT_LEN for all the characters that you don't want
+to handle specially.
+There are some sanity checks in genoutput.c that check the constraint lengths
+for the md file, so you can also use this macro to help you while you are
+transitioning from a byzantine single-letter-constraint scheme: when you
+return a negative length for a constraint you want to re-use, genoutput
+will complain about every instance where it is used in the md file.
+@end defmac
-@findex REG_CLASS_FROM_LETTER
-@item REG_CLASS_FROM_LETTER (@var{char})
+@defmac REG_CLASS_FROM_LETTER (@var{char})
A C expression which defines the machine-dependent operand constraint
letters for register classes. If @var{char} is such a letter, the
value should be the register class corresponding to it. Otherwise,
the value should be @code{NO_REGS}. The register letter @samp{r},
corresponding to class @code{GENERAL_REGS}, will not be passed
to this macro; you do not need to handle it.
+@end defmac
+
+@defmac REG_CLASS_FROM_CONSTRAINT (@var{char}, @var{str})
+Like @code{REG_CLASS_FROM_LETTER}, but you also get the constraint string
+passed in @var{str}, so that you can use suffixes to distinguish between
+different variants.
+@end defmac
-@findex REGNO_OK_FOR_BASE_P
-@item REGNO_OK_FOR_BASE_P (@var{num})
+@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. It may be
either a suitable hard register or a pseudo register that has been
allocated such a hard register.
+@end defmac
-@findex REGNO_MODE_OK_FOR_BASE_P
-@item REGNO_MODE_OK_FOR_BASE_P (@var{num}, @var{mode})
+@defmac REGNO_MODE_OK_FOR_BASE_P (@var{num}, @var{mode})
A C expression that is just like @code{REGNO_OK_FOR_BASE_P}, except that
that expression may examine the mode of the memory reference in
@var{mode}. You should define this macro if the mode of the memory
reference affects whether a register may be used as a base register. If
you define this macro, the compiler will use it instead of
@code{REGNO_OK_FOR_BASE_P}.
+@end defmac
-@findex REGNO_OK_FOR_INDEX_P
-@item REGNO_OK_FOR_INDEX_P (@var{num})
+@defmac REGNO_OK_FOR_INDEX_P (@var{num})
A C expression which is nonzero if register number @var{num} is
suitable for use as an index register in operand addresses. It may be
either a suitable hard register or a pseudo register that has been
@@ -2355,18 +2409,18 @@ labeling is used must fit the machine's constraints of which registers
may serve in each capacity. The compiler will try both labelings,
looking for one that is valid, and will reload one or both registers
only if neither labeling works.
+@end defmac
-@findex PREFERRED_RELOAD_CLASS
-@item PREFERRED_RELOAD_CLASS (@var{x}, @var{class})
+@defmac PREFERRED_RELOAD_CLASS (@var{x}, @var{class})
A C expression that places additional restrictions on the register class
to use when it is necessary to copy value @var{x} into a register in class
@var{class}. The value is a register class; perhaps @var{class}, or perhaps
another, smaller class. On many machines, the following definition is
safe:
-@example
+@smallexample
#define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
-@end example
+@end smallexample
Sometimes returning a more restrictive class makes better code. For
example, on the 68000, when @var{x} is an integer constant that is in range
@@ -2374,19 +2428,26 @@ for a @samp{moveq} instruction, the value of this macro is always
@code{DATA_REGS} as long as @var{class} includes the data registers.
Requiring a data register guarantees that a @samp{moveq} will be used.
-If @var{x} is a @code{const_double}, by returning @code{NO_REGS}
-you can force @var{x} into a memory constant. This is useful on
-certain machines where immediate floating values cannot be loaded into
-certain kinds of registers.
+One case where @code{PREFERRED_RELOAD_CLASS} must not return
+@var{class} is if @var{x} is a legitimate constant which cannot be
+loaded into some register class. By returning @code{NO_REGS} you can
+force @var{x} into a memory location. For example, rs6000 can load
+immediate values into general-purpose registers, but does not have an
+instruction for loading an immediate value into a floating-point
+register, so @code{PREFERRED_RELOAD_CLASS} returns @code{NO_REGS} when
+@var{x} is a floating-point constant. If the constant can't be loaded
+into any kind of register, code generation will be better if
+@code{LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead
+of using @code{PREFERRED_RELOAD_CLASS}.
+@end defmac
-@findex PREFERRED_OUTPUT_RELOAD_CLASS
-@item PREFERRED_OUTPUT_RELOAD_CLASS (@var{x}, @var{class})
+@defmac PREFERRED_OUTPUT_RELOAD_CLASS (@var{x}, @var{class})
Like @code{PREFERRED_RELOAD_CLASS}, but for output reloads instead of
input reloads. If you don't define this macro, the default is to use
@var{class}, unchanged.
+@end defmac
-@findex LIMIT_RELOAD_CLASS
-@item LIMIT_RELOAD_CLASS (@var{mode}, @var{class})
+@defmac LIMIT_RELOAD_CLASS (@var{mode}, @var{class})
A C expression that places additional restrictions on the register class
to use when it is necessary to be able to hold a value of mode
@var{mode} in a reload register for which class @var{class} would
@@ -2400,13 +2461,11 @@ smaller class.
Don't define this macro unless the target machine has limitations which
require the macro to do something nontrivial.
+@end defmac
-@findex SECONDARY_RELOAD_CLASS
-@findex SECONDARY_INPUT_RELOAD_CLASS
-@findex SECONDARY_OUTPUT_RELOAD_CLASS
-@item SECONDARY_RELOAD_CLASS (@var{class}, @var{mode}, @var{x})
-@itemx SECONDARY_INPUT_RELOAD_CLASS (@var{class}, @var{mode}, @var{x})
-@itemx SECONDARY_OUTPUT_RELOAD_CLASS (@var{class}, @var{mode}, @var{x})
+@defmac SECONDARY_RELOAD_CLASS (@var{class}, @var{mode}, @var{x})
+@defmacx SECONDARY_INPUT_RELOAD_CLASS (@var{class}, @var{mode}, @var{x})
+@defmacx SECONDARY_OUTPUT_RELOAD_CLASS (@var{class}, @var{mode}, @var{x})
Many machines have some registers that cannot be copied directly to or
from memory or even from other types of registers. An example is the
@samp{MQ} register, which on most machines, can only be copied to or
@@ -2465,9 +2524,9 @@ would not be helpful. Instead, a stack location must be used to perform
the copy and the @code{mov@var{m}} pattern should use memory as an
intermediate storage. This case often occurs between floating-point and
general registers.
+@end defmac
-@findex SECONDARY_MEMORY_NEEDED
-@item SECONDARY_MEMORY_NEEDED (@var{class1}, @var{class2}, @var{m})
+@defmac SECONDARY_MEMORY_NEEDED (@var{class1}, @var{class2}, @var{m})
Certain machines have the property that some registers cannot be copied
to some other registers without using memory. Define this macro on
those machines to be a C expression that is nonzero if objects of mode
@@ -2476,9 +2535,9 @@ class @var{class2} by storing a register of @var{class1} into memory
and loading that memory location into a register of @var{class2}.
Do not define this macro if its value would always be zero.
+@end defmac
-@findex SECONDARY_MEMORY_NEEDED_RTX
-@item SECONDARY_MEMORY_NEEDED_RTX (@var{mode})
+@defmac SECONDARY_MEMORY_NEEDED_RTX (@var{mode})
Normally when @code{SECONDARY_MEMORY_NEEDED} is defined, the compiler
allocates a stack slot for a memory location needed for register copies.
If this macro is defined, the compiler instead uses the memory location
@@ -2486,9 +2545,9 @@ defined by this macro.
Do not define this macro if you do not define
@code{SECONDARY_MEMORY_NEEDED}.
+@end defmac
-@findex SECONDARY_MEMORY_NEEDED_MODE
-@item SECONDARY_MEMORY_NEEDED_MODE (@var{mode})
+@defmac SECONDARY_MEMORY_NEEDED_MODE (@var{mode})
When the compiler needs a secondary memory location to copy between two
registers of mode @var{mode}, it normally allocates sufficient memory to
hold a quantity of @code{BITS_PER_WORD} bits and performs the store and
@@ -2510,9 +2569,9 @@ details.
Do not define this macro if you do not define
@code{SECONDARY_MEMORY_NEEDED} or if widening @var{mode} to a mode that
is @code{BITS_PER_WORD} bits wide is correct for your machine.
+@end defmac
-@findex SMALL_REGISTER_CLASSES
-@item SMALL_REGISTER_CLASSES
+@defmac SMALL_REGISTER_CLASSES
On some machines, it is risky to let hard registers live across arbitrary
insns. Typically, these machines have instructions that require values
to be in specific registers (like an accumulator), and reload will fail
@@ -2529,9 +2588,9 @@ that can be performed in some cases. If you do not define this macro
with a nonzero value when it is required, the compiler will run out of
spill registers and print a fatal error message. For most machines, you
should not define this macro at all.
+@end defmac
-@findex CLASS_LIKELY_SPILLED_P
-@item CLASS_LIKELY_SPILLED_P (@var{class})
+@defmac CLASS_LIKELY_SPILLED_P (@var{class})
A C expression whose value is nonzero if pseudos that have been assigned
to registers of class @var{class} would likely be spilled because
registers of @var{class} are needed for spill registers.
@@ -2547,9 +2606,9 @@ register. If there would not be another register available for
reallocation, you should not change the definition of this macro since
the only effect of such a definition would be to slow down register
allocation.
+@end defmac
-@findex CLASS_MAX_NREGS
-@item CLASS_MAX_NREGS (@var{class}, @var{mode})
+@defmac CLASS_MAX_NREGS (@var{class}, @var{mode})
A C expression for the maximum number of consecutive registers
of class @var{class} needed to hold a value of mode @var{mode}.
@@ -2560,8 +2619,9 @@ should be the maximum value of @code{HARD_REGNO_NREGS (@var{regno},
This macro helps control the handling of multiple-word values
in the reload pass.
+@end defmac
-@item CANNOT_CHANGE_MODE_CLASS(@var{from}, @var{to}, @var{class})
+@defmac CANNOT_CHANGE_MODE_CLASS (@var{from}, @var{to}, @var{class})
If defined, a C expression that returns nonzero for a @var{class} for which
a change from mode @var{from} to mode @var{to} is invalid.
@@ -2572,19 +2632,17 @@ does not store the low-order 32 bits, as would be the case for a normal
register. Therefore, @file{alpha.h} defines @code{CANNOT_CHANGE_MODE_CLASS}
as below:
-@example
+@smallexample
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
? reg_classes_intersect_p (FLOAT_REGS, (CLASS)) : 0)
-@end example
-@end table
+@end smallexample
+@end defmac
Three other special macros describe which operands fit which constraint
letters.
-@table @code
-@findex CONST_OK_FOR_LETTER_P
-@item CONST_OK_FOR_LETTER_P (@var{value}, @var{c})
+@defmac CONST_OK_FOR_LETTER_P (@var{value}, @var{c})
A C expression that defines the machine-dependent operand constraint
letters (@samp{I}, @samp{J}, @samp{K}, @dots{} @samp{P}) that specify
particular ranges of integer values. If @var{c} is one of those
@@ -2592,9 +2650,15 @@ letters, the expression should check that @var{value}, an integer, is in
the appropriate range and return 1 if so, 0 otherwise. If @var{c} is
not one of those letters, the value should be 0 regardless of
@var{value}.
+@end defmac
+
+@defmac CONST_OK_FOR_CONSTRAINT_P (@var{value}, @var{c}, @var{str})
+Like @code{CONST_OK_FOR_LETTER_P}, but you also get the constraint
+string passed in @var{str}, so that you can use suffixes to distinguish
+between different variants.
+@end defmac
-@findex CONST_DOUBLE_OK_FOR_LETTER_P
-@item CONST_DOUBLE_OK_FOR_LETTER_P (@var{value}, @var{c})
+@defmac CONST_DOUBLE_OK_FOR_LETTER_P (@var{value}, @var{c})
A C expression that defines the machine-dependent operand constraint
letters that specify particular ranges of @code{const_double} values
(@samp{G} or @samp{H}).
@@ -2608,13 +2672,20 @@ letters, the value should be 0 regardless of @var{value}.
@code{DImode} fixed-point constants. A given letter can accept either
or both kinds of values. It can use @code{GET_MODE} to distinguish
between these kinds.
+@end defmac
+
+@defmac CONST_DOUBLE_OK_FOR_CONSTRAINT_P (@var{value}, @var{c}, @var{str})
+Like @code{CONST_DOUBLE_OK_FOR_LETTER_P}, but you also get the constraint
+string passed in @var{str}, so that you can use suffixes to distinguish
+between different variants.
+@end defmac
-@findex EXTRA_CONSTRAINT
-@item EXTRA_CONSTRAINT (@var{value}, @var{c})
+@defmac EXTRA_CONSTRAINT (@var{value}, @var{c})
A C expression that defines the optional machine-dependent constraint
letters that can be used to segregate specific types of operands, usually
memory references, for the target machine. Any letter that is not
-elsewhere defined and not matched by @code{REG_CLASS_FROM_LETTER}
+elsewhere defined and not matched by @code{REG_CLASS_FROM_LETTER} /
+@code{REG_CLASS_FROM_CONSTRAINT}
may be used. Normally this macro will not be defined.
If it is required for a particular target machine, it should return 1
@@ -2629,17 +2700,24 @@ letter @samp{Q} is defined as representing a memory address that does
a @samp{Q} constraint on the input and @samp{r} on the output. The next
alternative specifies @samp{m} on the input and a register class that
does not include r0 on the output.
+@end defmac
+
+@defmac EXTRA_CONSTRAINT_STR (@var{value}, @var{c}, @var{str})
+Like @code{EXTRA_CONSTRAINT}, but you also get the constraint string passed
+in @var{str}, so that you can use suffixes to distinguish between different
+variants.
+@end defmac
-@findex EXTRA_MEMORY_CONSTRAINT
-@item EXTRA_MEMORY_CONSTRAINT (@var{c})
+@defmac EXTRA_MEMORY_CONSTRAINT (@var{c}, @var{str})
A C expression that defines the optional machine-dependent constraint
letters, amongst those accepted by @code{EXTRA_CONSTRAINT}, that should
be treated like memory constraints by the reload pass.
-It should return 1 if the operand type represented by the constraint
-letter @var{c} comprises a subset of all memory references including
-all those whose address is simply a base register. This allows the reload
-pass to reload an operand, if it does not directly correspond to the operand
+It should return 1 if the operand type represented by the constraint
+at the start of @var{str}, the first letter of which is the letter @var{c},
+ comprises a subset of all memory references including
+all those whose address is simply a base register. This allows the reload
+pass to reload an operand, if it does not directly correspond to the operand
type of @var{c}, by copying its address into a base register.
For example, on the S/390, some instructions do not accept arbitrary
@@ -2651,23 +2729,25 @@ a @samp{Q} constraint can handle any memory operand, because the
reload pass knows it can be reloaded by copying the memory address
into a base register if required. This is analogous to the way
a @samp{o} constraint can handle any memory operand.
+@end defmac
-@findex EXTRA_ADDRESS_CONSTRAINT
-@item EXTRA_ADDRESS_CONSTRAINT (@var{c})
+@defmac EXTRA_ADDRESS_CONSTRAINT (@var{c}, @var{str})
A C expression that defines the optional machine-dependent constraint
-letters, amongst those accepted by @code{EXTRA_CONSTRAINT}, that should
+letters, amongst those accepted by @code{EXTRA_CONSTRAINT} /
+@code{EXTRA_CONSTRAINT_STR}, that should
be treated like address constraints by the reload pass.
-It should return 1 if the operand type represented by the constraint
-letter @var{c} comprises a subset of all memory addresses including
-all those that consist of just a base register. This allows the reload
-pass to reload an operand, if it does not directly correspond to the operand
-type of @var{c}, by copying it into a base register.
+It should return 1 if the operand type represented by the constraint
+at the start of @var{str}, which starts with the letter @var{c}, comprises
+a subset of all memory addresses including
+all those that consist of just a base register. This allows the reload
+pass to reload an operand, if it does not directly correspond to the operand
+type of @var{str}, by copying it into a base register.
Any constraint marked as @code{EXTRA_ADDRESS_CONSTRAINT} can only
-be used with the @code{address_operand} predicate. It is treated
+be used with the @code{address_operand} predicate. It is treated
analogously to the @samp{p} constraint.
-@end table
+@end defmac
@node Stack and Calling
@section Stack Layout and Calling Conventions
@@ -2700,19 +2780,16 @@ This describes the stack layout and calling conventions.
@c prevent bad page break with this line
Here is the basic stack layout.
-@table @code
-@findex STACK_GROWS_DOWNWARD
-@item STACK_GROWS_DOWNWARD
+@defmac STACK_GROWS_DOWNWARD
Define this macro if pushing a word onto the stack moves the stack
pointer to a smaller address.
When we say, ``define this macro if @dots{},'' it means that the
compiler checks this macro only with @code{#ifdef} so the precise
definition used does not matter.
+@end defmac
-@findex STACK_PUSH_CODE
-@item STACK_PUSH_CODE
-
+@defmac STACK_PUSH_CODE
This macro defines the operation used when something is pushed
on the stack. In RTL, a push operation will be
@code{(set (mem (STACK_PUSH_CODE (reg sp))) @dots{})}
@@ -2726,19 +2803,19 @@ space for the next item on the stack.
The default is @code{PRE_DEC} when @code{STACK_GROWS_DOWNWARD} is
defined, which is almost always right, and @code{PRE_INC} otherwise,
which is often wrong.
+@end defmac
-@findex FRAME_GROWS_DOWNWARD
-@item FRAME_GROWS_DOWNWARD
+@defmac FRAME_GROWS_DOWNWARD
Define this macro if the addresses of local variable slots are at negative
offsets from the frame pointer.
+@end defmac
-@findex ARGS_GROW_DOWNWARD
-@item ARGS_GROW_DOWNWARD
+@defmac ARGS_GROW_DOWNWARD
Define this macro if successive arguments to a function occupy decreasing
addresses on the stack.
+@end defmac
-@findex STARTING_FRAME_OFFSET
-@item STARTING_FRAME_OFFSET
+@defmac STARTING_FRAME_OFFSET
Offset from the frame pointer to the first local variable slot to be allocated.
If @code{FRAME_GROWS_DOWNWARD}, find the next slot's offset by
@@ -2747,36 +2824,46 @@ Otherwise, it is found by adding the length of the first slot to the
value @code{STARTING_FRAME_OFFSET}.
@c i'm not sure if the above is still correct.. had to change it to get
@c rid of an overfull. --mew 2feb93
+@end defmac
+
+@defmac STACK_ALIGNMENT_NEEDED
+Define to zero to disable final alignment of the stack during reload.
+The nonzero default for this macro is suitable for most ports.
+
+On ports where @code{STARTING_FRAME_OFFSET} is nonzero or where there
+is a register save block following the local block that doesn't require
+alignment to @code{STACK_BOUNDARY}, it may be beneficial to disable
+stack alignment and do it in the backend.
+@end defmac
-@findex STACK_POINTER_OFFSET
-@item STACK_POINTER_OFFSET
+@defmac STACK_POINTER_OFFSET
Offset from the stack pointer register to the first location at which
outgoing arguments are placed. If not specified, the default value of
zero is used. This is the proper value for most machines.
If @code{ARGS_GROW_DOWNWARD}, this is the offset to the location above
the first location at which outgoing arguments are placed.
+@end defmac
-@findex FIRST_PARM_OFFSET
-@item FIRST_PARM_OFFSET (@var{fundecl})
+@defmac FIRST_PARM_OFFSET (@var{fundecl})
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.
If @code{ARGS_GROW_DOWNWARD}, this is the offset to the location above
the first argument's address.
+@end defmac
-@findex STACK_DYNAMIC_OFFSET
-@item STACK_DYNAMIC_OFFSET (@var{fundecl})
+@defmac STACK_DYNAMIC_OFFSET (@var{fundecl})
Offset from the stack pointer register to an item dynamically allocated
on the stack, e.g., by @code{alloca}.
The default value for this macro is @code{STACK_POINTER_OFFSET} plus the
length of the outgoing arguments. The default is correct for most
machines. See @file{function.c} for details.
+@end defmac
-@findex DYNAMIC_CHAIN_ADDRESS
-@item DYNAMIC_CHAIN_ADDRESS (@var{frameaddr})
+@defmac DYNAMIC_CHAIN_ADDRESS (@var{frameaddr})
A C expression whose value is RTL representing the address in a stack
frame where the pointer to the caller's frame is stored. Assume that
@var{frameaddr} is an RTL expression for the address of the stack frame
@@ -2785,25 +2872,25 @@ itself.
If you don't define this macro, the default is to return the value
of @var{frameaddr}---that is, the stack frame address is also the
address of the stack word that points to the previous frame.
+@end defmac
-@findex SETUP_FRAME_ADDRESSES
-@item SETUP_FRAME_ADDRESSES
+@defmac SETUP_FRAME_ADDRESSES
If defined, a C expression that produces the machine-specific code to
setup the stack so that arbitrary frames can be accessed. For example,
on the SPARC, we must flush all of the register windows to the stack
before we can access arbitrary stack frames. You will seldom need to
define this macro.
+@end defmac
-@findex BUILTIN_SETJMP_FRAME_VALUE
-@item BUILTIN_SETJMP_FRAME_VALUE
+@defmac BUILTIN_SETJMP_FRAME_VALUE
If defined, a C expression that contains an rtx that is used to store
the address of the current frame into the built in @code{setjmp} buffer.
The default value, @code{virtual_stack_vars_rtx}, is correct for most
machines. One reason you may need to define this macro is if
@code{hard_frame_pointer_rtx} is the appropriate value on your machine.
+@end defmac
-@findex RETURN_ADDR_RTX
-@item RETURN_ADDR_RTX (@var{count}, @var{frameaddr})
+@defmac RETURN_ADDR_RTX (@var{count}, @var{frameaddr})
A C expression whose value is RTL representing the value of the return
address for the frame @var{count} steps up from the current frame, after
the prologue. @var{frameaddr} is the frame pointer of the @var{count}
@@ -2813,14 +2900,14 @@ frame, or the frame pointer of the @var{count} @minus{} 1 frame if
The value of the expression must always be the correct address when
@var{count} is zero, but may be @code{NULL_RTX} if there is not way to
determine the return address of other frames.
+@end defmac
-@findex RETURN_ADDR_IN_PREVIOUS_FRAME
-@item RETURN_ADDR_IN_PREVIOUS_FRAME
+@defmac RETURN_ADDR_IN_PREVIOUS_FRAME
Define this if the return address of a particular stack frame is accessed
from the frame pointer of the previous stack frame.
+@end defmac
-@findex INCOMING_RETURN_ADDR_RTX
-@item INCOMING_RETURN_ADDR_RTX
+@defmac INCOMING_RETURN_ADDR_RTX
A C expression whose value is RTL representing the location of the
incoming return address at the beginning of any function, before the
prologue. This RTL is either a @code{REG}, indicating that the return
@@ -2832,9 +2919,17 @@ debugging information like that provided by DWARF 2.
If this RTL is a @code{REG}, you should also define
@code{DWARF_FRAME_RETURN_COLUMN} to @code{DWARF_FRAME_REGNUM (REGNO)}.
+@end defmac
-@findex INCOMING_FRAME_SP_OFFSET
-@item INCOMING_FRAME_SP_OFFSET
+@defmac DWARF_ALT_FRAME_RETURN_COLUMN
+A C expression whose value is an integer giving a DWARF 2 column
+number that may be used as an alternate return column. This should
+be defined only if @code{DWARF_FRAME_RETURN_COLUMN} is set to a
+general register, but an alternate column needs to be used for
+signal frames.
+@end defmac
+
+@defmac INCOMING_FRAME_SP_OFFSET
A C expression whose value is an integer giving the offset, in bytes,
from the value of the stack pointer register to the top of the stack
frame at the beginning of any function, before the prologue. The top of
@@ -2843,9 +2938,9 @@ previous frame, just before the call instruction.
You only need to define this macro if you want to support call frame
debugging information like that provided by DWARF 2.
+@end defmac
-@findex ARG_POINTER_CFA_OFFSET
-@item ARG_POINTER_CFA_OFFSET (@var{fundecl})
+@defmac ARG_POINTER_CFA_OFFSET (@var{fundecl})
A C expression whose value is an integer giving the offset, in bytes,
from the argument pointer to the canonical frame address (cfa). The
final value should coincide with that calculated by
@@ -2861,21 +2956,13 @@ and rs6000, and so such targets need to define this macro.
You only need to define this macro if the default is incorrect, and you
want to support call frame debugging information like that provided by
DWARF 2.
-
-@findex SMALL_STACK
-@item SMALL_STACK
-Define this macro if the stack size for the target is very small. This
-has the effect of disabling gcc's built-in @samp{alloca}, though
-@samp{__builtin_alloca} is not affected.
-@end table
+@end defmac
@node Exception Handling
@subsection Exception Handling Support
@cindex exception handling
-@table @code
-@findex EH_RETURN_DATA_REGNO
-@item EH_RETURN_DATA_REGNO (@var{N})
+@defmac EH_RETURN_DATA_REGNO (@var{N})
A C expression whose value is the @var{N}th register number used for
data by exception handlers, or @code{INVALID_REGNUM} if fewer than
@var{N} registers are usable.
@@ -2888,9 +2975,9 @@ but may negatively impact code size. The target must support at least
You must define this macro if you want to support call frame exception
handling like that provided by DWARF 2.
+@end defmac
-@findex EH_RETURN_STACKADJ_RTX
-@item EH_RETURN_STACKADJ_RTX
+@defmac EH_RETURN_STACKADJ_RTX
A C expression whose value is RTL representing a location in which
to store a stack adjustment to be applied before function return.
This is used to unwind the stack to an exception handler's call frame.
@@ -2900,14 +2987,14 @@ Typically this is a call-clobbered hard register that is otherwise
untouched by the epilogue, but could also be a stack slot.
Do not define this macro if the stack pointer is saved and restored
-by the regular prolog and epilog code in the call frame itself; in
-this case, the exception handling library routines will update the
-stack location to be restored in place. Otherwise, you must define
-this macro if you want to support call frame exception handling like
+by the regular prolog and epilog code in the call frame itself; in
+this case, the exception handling library routines will update the
+stack location to be restored in place. Otherwise, you must define
+this macro if you want to support call frame exception handling like
that provided by DWARF 2.
+@end defmac
-@findex EH_RETURN_HANDLER_RTX
-@item EH_RETURN_HANDLER_RTX
+@defmac EH_RETURN_HANDLER_RTX
A C expression whose value is RTL representing a location in which
to store the address of an exception handler to which we should
return. It will not be assigned on code paths that return normally.
@@ -2916,8 +3003,8 @@ Typically this is the location in the call frame at which the normal
return address is stored. For targets that return by popping an
address off the stack, this might be a memory address just below
the @emph{target} call frame rather than inside the current call
-frame. If defined, @code{EH_RETURN_STACKADJ_RTX} will have already
-been assigned, so it may be used to calculate the location of the
+frame. If defined, @code{EH_RETURN_STACKADJ_RTX} will have already
+been assigned, so it may be used to calculate the location of the
target call frame.
Some targets have more complex requirements than storing to an
@@ -2926,9 +3013,16 @@ the @code{eh_return} instruction pattern should be used instead.
If you want to support call frame exception handling, you must
define either this macro or the @code{eh_return} instruction pattern.
+@end defmac
-@findex ASM_PREFERRED_EH_DATA_FORMAT
-@item ASM_PREFERRED_EH_DATA_FORMAT(@var{code}, @var{global})
+@defmac RETURN_ADDR_OFFSET
+If defined, an integer-valued C expression for which rtl will be generated
+to add it to the exception handler address before it is searched in the
+exception handling tables, and to subtract it again from the address before
+using it to return to the exception handler.
+@end defmac
+
+@defmac ASM_PREFERRED_EH_DATA_FORMAT (@var{code}, @var{global})
This macro chooses the encoding of pointers embedded in the exception
handling sections. If at all possible, this should be defined such
that the exception handling section will not require dynamic relocations,
@@ -2941,9 +3035,9 @@ as found in @file{dwarf2.h}.
If this macro is not defined, pointers will not be encoded but
represented directly.
+@end defmac
-@findex ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX
-@item ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(@var{file}, @var{encoding}, @var{size}, @var{addr}, @var{done})
+@defmac ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX (@var{file}, @var{encoding}, @var{size}, @var{addr}, @var{done})
This macro allows the target to emit whatever special magic is required
to represent the encoding chosen by @code{ASM_PREFERRED_EH_DATA_FORMAT}.
Generic code takes care of pc-relative and indirect encodings; this must
@@ -2953,9 +3047,9 @@ This is a C statement that branches to @var{done} if the format was
handled. @var{encoding} is the format chosen, @var{size} is the number
of bytes that the format occupies, @var{addr} is the @code{SYMBOL_REF}
to be emitted.
+@end defmac
-@findex MD_FALLBACK_FRAME_STATE_FOR
-@item MD_FALLBACK_FRAME_STATE_FOR(@var{context}, @var{fs}, @var{success})
+@defmac MD_FALLBACK_FRAME_STATE_FOR (@var{context}, @var{fs}, @var{success})
This macro allows the target to add cpu and operating system specific
code to the call-frame unwinder for use when there is no unwind data
available. The most common reason to implement this macro is to unwind
@@ -2969,7 +3063,23 @@ the stack pointer value. If the frame can be decoded, the register save
addresses should be updated in @var{fs} and the macro should branch to
@var{success}. If the frame cannot be decoded, the macro should do
nothing.
-@end table
+
+For proper signal handling in Java this macro is accompanied by
+@code{MAKE_THROW_FRAME}, defined in @file{libjava/include/*-signal.h} headers.
+@end defmac
+
+@defmac MD_HANDLE_UNWABI (@var{context}, @var{fs})
+This macro allows the target to add operating system specific code to the
+call-frame unwinder to handle the IA-64 @code{.unwabi} unwinding directive,
+usually used for signal or interrupt frames.
+
+This macro is called from @code{uw_update_context} in @file{unwind-ia64.c}.
+@var{context} is an @code{_Unwind_Context};
+@var{fs} is an @code{_Unwind_FrameState}. Examine @code{fs->unwabi}
+for the abi and context in the @code{.unwabi} directive. If the
+@code{.unwabi} directive can be handled, the register save addresses should
+be updated in @var{fs}.
+@end defmac
@node Stack Checking
@subsection Specifying How Stack Checking is Done
@@ -3000,59 +3110,57 @@ If neither of the above are true, GCC will generate code to periodically
Normally, you will use the default values of these macros, so GCC
will use the third approach.
-@table @code
-@findex STACK_CHECK_BUILTIN
-@item STACK_CHECK_BUILTIN
+@defmac STACK_CHECK_BUILTIN
A nonzero value if stack checking is done by the configuration files in a
machine-dependent manner. You should define this macro if stack checking
is require by the ABI of your machine or if you would like to have to stack
checking in some more efficient way than GCC's portable approach.
The default value of this macro is zero.
+@end defmac
-@findex STACK_CHECK_PROBE_INTERVAL
-@item STACK_CHECK_PROBE_INTERVAL
+@defmac STACK_CHECK_PROBE_INTERVAL
An integer representing the interval at which GCC must generate stack
probe instructions. You will normally define this macro to be no larger
than the size of the ``guard pages'' at the end of a stack area. The
default value of 4096 is suitable for most systems.
+@end defmac
-@findex STACK_CHECK_PROBE_LOAD
-@item STACK_CHECK_PROBE_LOAD
+@defmac STACK_CHECK_PROBE_LOAD
A integer which is nonzero if GCC should perform the stack probe
as a load instruction and zero if GCC should use a store instruction.
The default is zero, which is the most efficient choice on most systems.
+@end defmac
-@findex STACK_CHECK_PROTECT
-@item STACK_CHECK_PROTECT
+@defmac STACK_CHECK_PROTECT
The number of bytes of stack needed to recover from a stack overflow,
for languages where such a recovery is supported. The default value of
75 words should be adequate for most machines.
+@end defmac
-@findex STACK_CHECK_MAX_FRAME_SIZE
-@item STACK_CHECK_MAX_FRAME_SIZE
+@defmac STACK_CHECK_MAX_FRAME_SIZE
The maximum size of a stack frame, in bytes. GCC will generate probe
instructions in non-leaf functions to ensure at least this many bytes of
stack are available. If a stack frame is larger than this size, stack
checking will not be reliable and GCC will issue a warning. The
default is chosen so that GCC only generates one instruction on most
systems. You should normally not change the default value of this macro.
+@end defmac
-@findex STACK_CHECK_FIXED_FRAME_SIZE
-@item STACK_CHECK_FIXED_FRAME_SIZE
+@defmac STACK_CHECK_FIXED_FRAME_SIZE
GCC uses this value to generate the above warning message. It
represents the amount of fixed frame used by a function, not including
space for any callee-saved registers, temporaries and user variables.
You need only specify an upper bound for this amount and will normally
use the default of four words.
+@end defmac
-@findex STACK_CHECK_MAX_VAR_SIZE
-@item STACK_CHECK_MAX_VAR_SIZE
+@defmac STACK_CHECK_MAX_VAR_SIZE
The maximum size, in bytes, of an object that GCC will place in the
fixed area of the stack frame when the user specifies
@option{-fstack-check}.
GCC computed the default from the values of the above macros and you will
normally not need to override that default.
-@end table
+@end defmac
@need 2000
@node Frame Registers
@@ -3061,22 +3169,20 @@ normally not need to override that default.
@c prevent bad page break with this line
This discusses registers that address the stack frame.
-@table @code
-@findex STACK_POINTER_REGNUM
-@item STACK_POINTER_REGNUM
+@defmac STACK_POINTER_REGNUM
The register number of the stack pointer register, which must also be a
fixed register according to @code{FIXED_REGISTERS}. On most machines,
the hardware determines which register this is.
+@end defmac
-@findex FRAME_POINTER_REGNUM
-@item FRAME_POINTER_REGNUM
+@defmac FRAME_POINTER_REGNUM
The register number of the frame pointer register, which is used to
access automatic variables in the stack frame. On some machines, the
hardware determines which register this is. On other machines, you can
choose any register you wish for this purpose.
+@end defmac
-@findex HARD_FRAME_POINTER_REGNUM
-@item HARD_FRAME_POINTER_REGNUM
+@defmac HARD_FRAME_POINTER_REGNUM
On some machines the offset between the frame pointer and starting
offset of the automatic variables is not known until after register
allocation has been done (for example, because the saved registers are
@@ -3096,9 +3202,9 @@ or @code{STACK_POINTER_REGNUM}.
Do not define this macro if it would be the same as
@code{FRAME_POINTER_REGNUM}.
+@end defmac
-@findex ARG_POINTER_REGNUM
-@item ARG_POINTER_REGNUM
+@defmac ARG_POINTER_REGNUM
The register number of the arg pointer register, which is used to access
the function's argument list. On some machines, this is the same as the
frame pointer register. On some machines, the hardware determines which
@@ -3107,9 +3213,9 @@ wish for this purpose. If this is not the same register as the frame
pointer register, then you must mark it as a fixed register according to
@code{FIXED_REGISTERS}, or arrange to be able to eliminate it
(@pxref{Elimination}).
+@end defmac
-@findex RETURN_ADDRESS_POINTER_REGNUM
-@item RETURN_ADDRESS_POINTER_REGNUM
+@defmac RETURN_ADDRESS_POINTER_REGNUM
The register number of the return address pointer register, which is used to
access the current function's return address from the stack. On some
machines, the return address is not at a fixed offset from the frame
@@ -3119,11 +3225,10 @@ to point to the return address on the stack, and then be converted by
Do not define this macro unless there is no other way to get the return
address from the stack.
+@end defmac
-@findex STATIC_CHAIN_REGNUM
-@findex STATIC_CHAIN_INCOMING_REGNUM
-@item STATIC_CHAIN_REGNUM
-@itemx STATIC_CHAIN_INCOMING_REGNUM
+@defmac STATIC_CHAIN_REGNUM
+@defmacx STATIC_CHAIN_INCOMING_REGNUM
Register numbers used for passing a function's static chain pointer. If
register windows are used, the register number as seen by the called
function is @code{STATIC_CHAIN_INCOMING_REGNUM}, while the register
@@ -3135,11 +3240,10 @@ The static chain register need not be a fixed register.
If the static chain is passed in memory, these macros should not be
defined; instead, the next two macros should be defined.
+@end defmac
-@findex STATIC_CHAIN
-@findex STATIC_CHAIN_INCOMING
-@item STATIC_CHAIN
-@itemx STATIC_CHAIN_INCOMING
+@defmac STATIC_CHAIN
+@defmacx STATIC_CHAIN_INCOMING
If the static chain is passed in memory, these macros provide rtx giving
@code{mem} expressions that denote where they are stored.
@code{STATIC_CHAIN} and @code{STATIC_CHAIN_INCOMING} give the locations
@@ -3156,9 +3260,9 @@ macros and should be used to refer to those items.
If the static chain is passed in a register, the two previous macros should
be defined instead.
+@end defmac
-@findex DWARF_FRAME_REGISTERS
-@item DWARF_FRAME_REGISTERS
+@defmac DWARF_FRAME_REGISTERS
This macro specifies the maximum number of hard registers that can be
saved in a call frame. This is used to size data structures used in
DWARF2 exception handling.
@@ -3173,17 +3277,46 @@ registers that are not call-saved.
If this macro is not defined, it defaults to
@code{FIRST_PSEUDO_REGISTER}.
+@end defmac
-@findex PRE_GCC3_DWARF_FRAME_REGISTERS
-@item PRE_GCC3_DWARF_FRAME_REGISTERS
+@defmac PRE_GCC3_DWARF_FRAME_REGISTERS
This macro is similar to @code{DWARF_FRAME_REGISTERS}, but is provided
for backward compatibility in pre GCC 3.0 compiled code.
If this macro is not defined, it defaults to
@code{DWARF_FRAME_REGISTERS}.
+@end defmac
-@end table
+@defmac DWARF_REG_TO_UNWIND_COLUMN (@var{regno})
+
+Define this macro if the target's representation for dwarf registers
+is different than the internal representation for unwind column.
+Given a dwarf register, this macro should return the internal unwind
+column number to use instead.
+
+See the PowerPC's SPE target for an example.
+@end defmac
+
+@defmac DWARF_FRAME_REGNUM (@var{regno})
+
+Define this macro if the target's representation for dwarf registers
+used in .eh_frame or .debug_frame is different from that used in other
+debug info sections. Given a GCC hard register number, this macro
+should return the .eh_frame register number. The default is
+@code{DBX_REGISTER_NUMBER (@var{regno})}.
+
+@end defmac
+
+@defmac DWARF2_FRAME_REG_OUT (@var{regno}, @var{for_eh})
+
+Define this macro to map register numbers held in the call frame info
+that GCC has collected using @code{DWARF_FRAME_REGNUM} to those that
+should be output in .debug_frame (@code{@var{for_eh}} is zero) and
+.eh_frame (@code{@var{for_eh}} is nonzero). The default is to
+return @code{@var{regno}}.
+
+@end defmac
@node Elimination
@subsection Eliminating Frame Pointer and Arg Pointer
@@ -3191,9 +3324,7 @@ If this macro is not defined, it defaults to
@c prevent bad page break with this line
This is about eliminating the frame pointer and arg pointer.
-@table @code
-@findex FRAME_POINTER_REQUIRED
-@item FRAME_POINTER_REQUIRED
+@defmac FRAME_POINTER_REQUIRED
A C expression which is nonzero if a function must have and use a frame
pointer. This expression is evaluated in the reload pass. If its value is
nonzero the function will have a frame pointer.
@@ -3213,10 +3344,10 @@ them.
In a function that does not require a frame pointer, the frame pointer
register can be allocated for ordinary usage, unless you mark it as a
fixed register. See @code{FIXED_REGISTERS} for more information.
+@end defmac
-@findex INITIAL_FRAME_POINTER_OFFSET
@findex get_frame_size
-@item INITIAL_FRAME_POINTER_OFFSET (@var{depth-var})
+@defmac INITIAL_FRAME_POINTER_OFFSET (@var{depth-var})
A C statement to store in the variable @var{depth-var} the difference
between the frame pointer and the stack pointer values immediately after
the function prologue. The value would be computed from information
@@ -3227,9 +3358,9 @@ If @code{ELIMINABLE_REGS} is defined, this macro will be not be used and
need not be defined. Otherwise, it must be defined even if
@code{FRAME_POINTER_REQUIRED} is defined to always be true; in that
case, you may set @var{depth-var} to anything.
+@end defmac
-@findex ELIMINABLE_REGS
-@item ELIMINABLE_REGS
+@defmac ELIMINABLE_REGS
If defined, this macro specifies a table of register pairs used to
eliminate unneeded registers that point into the stack frame. If it is not
defined, the only elimination attempted by the compiler is to replace
@@ -3245,32 +3376,32 @@ replacing it with either the frame pointer or the argument pointer,
depending on whether or not the frame pointer has been eliminated.
In this case, you might specify:
-@example
+@smallexample
#define ELIMINABLE_REGS \
@{@{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM@}, \
@{ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM@}, \
@{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM@}@}
-@end example
+@end smallexample
Note that the elimination of the argument pointer with the stack pointer is
specified first since that is the preferred elimination.
+@end defmac
-@findex CAN_ELIMINATE
-@item CAN_ELIMINATE (@var{from-reg}, @var{to-reg})
+@defmac CAN_ELIMINATE (@var{from-reg}, @var{to-reg})
A C expression that returns nonzero if the compiler is allowed to try
to replace register number @var{from-reg} with register number
@var{to-reg}. This macro need only be defined if @code{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.
+@end defmac
-@findex INITIAL_ELIMINATION_OFFSET
-@item INITIAL_ELIMINATION_OFFSET (@var{from-reg}, @var{to-reg}, @var{offset-var})
+@defmac INITIAL_ELIMINATION_OFFSET (@var{from-reg}, @var{to-reg}, @var{offset-var})
This macro is similar to @code{INITIAL_FRAME_POINTER_OFFSET}. It
specifies the initial difference between the specified pair of
registers. This macro must be defined if @code{ELIMINABLE_REGS} is
defined.
-@end table
+@end defmac
@node Stack Arguments
@subsection Passing Function Arguments on the Stack
@@ -3281,48 +3412,52 @@ The macros in this section control how arguments are passed
on the stack. See the following section for other macros that
control passing certain arguments in registers.
-@table @code
-@findex PROMOTE_PROTOTYPES
-@item PROMOTE_PROTOTYPES
-A C expression whose value is nonzero if an argument declared in
-a prototype as an integral type smaller than @code{int} should
-actually be passed as an @code{int}. In addition to avoiding
-errors in certain cases of mismatch, it also makes for better
-code on certain machines. If the macro is not defined in target
-header files, it defaults to 0.
-
-@findex PUSH_ARGS
-@item PUSH_ARGS
+@deftypefn {Target Hook} bool TARGET_PROMOTE_PROTOTYPES (tree @var{fntype})
+This target hook returns @code{true} if an argument declared in a
+prototype as an integral type smaller than @code{int} should actually be
+passed as an @code{int}. In addition to avoiding errors in certain
+cases of mismatch, it also makes for better code on certain machines.
+The default is to not promote prototypes.
+@end deftypefn
+
+@defmac PUSH_ARGS
A C expression. If nonzero, push insns will be used to pass
outgoing arguments.
If the target machine does not have a push instruction, set it to zero.
That directs GCC to use an alternate strategy: to
allocate the entire argument block and then store the arguments into
it. When @code{PUSH_ARGS} is nonzero, @code{PUSH_ROUNDING} must be defined too.
+@end defmac
-@findex PUSH_ROUNDING
-@item PUSH_ROUNDING (@var{npushed})
+@defmac PUSH_ARGS_REVERSED
+A C expression. If nonzero, function arguments will be evaluated from
+last to first, rather than from first to last. If this macro is not
+defined, it defaults to @code{PUSH_ARGS} on targets where the stack
+and args grow in opposite directions, and 0 otherwise.
+@end defmac
+
+@defmac PUSH_ROUNDING (@var{npushed})
A C expression that is the number of bytes actually pushed onto the
stack when an instruction attempts to push @var{npushed} bytes.
On some machines, the definition
-@example
+@smallexample
#define PUSH_ROUNDING(BYTES) (BYTES)
-@end example
+@end smallexample
@noindent
will suffice. But on other machines, instructions that appear
to push one byte actually push two bytes in an attempt to maintain
alignment. Then the definition should be
-@example
+@smallexample
#define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1)
-@end example
+@end smallexample
+@end defmac
-@findex ACCUMULATE_OUTGOING_ARGS
@findex current_function_outgoing_args_size
-@item ACCUMULATE_OUTGOING_ARGS
+@defmac ACCUMULATE_OUTGOING_ARGS
A C expression. If nonzero, the maximum amount of space required for outgoing arguments
will be computed and placed into the variable
@code{current_function_outgoing_args_size}. No space will be pushed
@@ -3331,9 +3466,9 @@ increase the stack frame size by this amount.
Setting both @code{PUSH_ARGS} and @code{ACCUMULATE_OUTGOING_ARGS}
is not proper.
+@end defmac
-@findex REG_PARM_STACK_SPACE
-@item REG_PARM_STACK_SPACE (@var{fndecl})
+@defmac REG_PARM_STACK_SPACE (@var{fndecl})
Define this macro if functions should assume that stack space has been
allocated for arguments even when their values are passed in
registers.
@@ -3345,13 +3480,12 @@ which can be zero if GCC is calling a library function.
This space can be allocated by the caller, or be a part of the
machine-dependent stack frame: @code{OUTGOING_REG_PARM_STACK_SPACE} says
which.
+@end defmac
@c above is overfull. not sure what to do. --mew 5feb93 did
@c something, not sure if it looks good. --mew 10feb93
-@findex MAYBE_REG_PARM_STACK_SPACE
-@findex FINAL_REG_PARM_STACK_SPACE
-@item MAYBE_REG_PARM_STACK_SPACE
-@itemx FINAL_REG_PARM_STACK_SPACE (@var{const_size}, @var{var_size})
+@defmac MAYBE_REG_PARM_STACK_SPACE
+@defmacx FINAL_REG_PARM_STACK_SPACE (@var{const_size}, @var{var_size})
Define these macros in addition to the one above if functions might
allocate stack space for arguments even when their values are passed
in registers. These should be used when the stack space allocated
@@ -3375,18 +3509,18 @@ In each case this value can be easily computed.
When deciding whether a called function needs such stack space, and how
much space to reserve, GCC uses these two macros instead of
@code{REG_PARM_STACK_SPACE}.
+@end defmac
-@findex OUTGOING_REG_PARM_STACK_SPACE
-@item OUTGOING_REG_PARM_STACK_SPACE
+@defmac OUTGOING_REG_PARM_STACK_SPACE
Define this if it is the responsibility of the caller to allocate the area
reserved for arguments passed in registers.
If @code{ACCUMULATE_OUTGOING_ARGS} is defined, this macro controls
whether the space for these arguments counts in the value of
@code{current_function_outgoing_args_size}.
+@end defmac
-@findex STACK_PARMS_IN_REG_PARM_AREA
-@item STACK_PARMS_IN_REG_PARM_AREA
+@defmac STACK_PARMS_IN_REG_PARM_AREA
Define this macro if @code{REG_PARM_STACK_SPACE} is defined, but the
stack parameters don't skip the area specified by it.
@c i changed this, makes more sens and it should have taken care of the
@@ -3396,9 +3530,9 @@ Normally, when a parameter is not passed in registers, it is placed on the
stack beyond the @code{REG_PARM_STACK_SPACE} area. Defining this macro
suppresses this behavior and causes the parameter to be passed on the
stack in its natural location.
+@end defmac
-@findex RETURN_POPS_ARGS
-@item RETURN_POPS_ARGS (@var{fundecl}, @var{funtype}, @var{stack-size})
+@defmac RETURN_POPS_ARGS (@var{fundecl}, @var{funtype}, @var{stack-size})
A C expression that should indicate the number of bytes of its own
arguments that a function pops on returning, or 0 if the
function pops no arguments and the caller must therefore pop them all
@@ -3435,9 +3569,9 @@ arguments pop them but other functions (such as @code{printf}) pop
nothing (the caller pops all). When this convention is in use,
@var{funtype} is examined to determine whether a function takes a fixed
number of arguments.
+@end defmac
-@findex CALL_POPS_ARGS
-@item CALL_POPS_ARGS (@var{cum})
+@defmac CALL_POPS_ARGS (@var{cum})
A C expression that should indicate the number of bytes a call sequence
pops off the stack. It is added to the value of @code{RETURN_POPS_ARGS}
when compiling a function call.
@@ -3450,8 +3584,7 @@ that pops certain registers off the stack, depending on the arguments
that have been passed to the function. Since this is a property of the
call site, not of the called function, @code{RETURN_POPS_ARGS} is not
appropriate.
-
-@end table
+@end defmac
@node Register Arguments
@subsection Passing Arguments in Registers
@@ -3462,9 +3595,7 @@ This section describes the macros which let you control how various
types of arguments are passed in registers or how they are arranged in
the stack.
-@table @code
-@findex FUNCTION_ARG
-@item FUNCTION_ARG (@var{cum}, @var{mode}, @var{type}, @var{named})
+@defmac FUNCTION_ARG (@var{cum}, @var{mode}, @var{type}, @var{named})
A C expression that controls whether a function argument is passed
in a register, and which register.
@@ -3486,7 +3617,7 @@ pushed, zero suffices as a definition.
The value of the expression can also be a @code{parallel} RTX@. This is
used when an argument is passed in multiple locations. The mode of the
-of the @code{parallel} should be the mode of the entire argument. The
+@code{parallel} should be the mode of the entire argument. The
@code{parallel} holds any number of @code{expr_list} pairs; each one
describes where part of the argument is passed. In each
@code{expr_list} the first operand must be a @code{reg} RTX for the hard
@@ -3517,16 +3648,16 @@ is not defined and @code{FUNCTION_ARG} returns nonzero for such an
argument, the compiler will abort. If @code{REG_PARM_STACK_SPACE} is
defined, the argument will be computed in the stack and then loaded into
a register.
+@end defmac
-@findex MUST_PASS_IN_STACK
-@item MUST_PASS_IN_STACK (@var{mode}, @var{type})
+@defmac MUST_PASS_IN_STACK (@var{mode}, @var{type})
Define as a C expression that evaluates to nonzero if we do not know how
to pass TYPE solely in registers. The file @file{expr.h} defines a
definition that is usually appropriate, refer to @file{expr.h} for additional
documentation.
+@end defmac
-@findex FUNCTION_INCOMING_ARG
-@item FUNCTION_INCOMING_ARG (@var{cum}, @var{mode}, @var{type}, @var{named})
+@defmac FUNCTION_INCOMING_ARG (@var{cum}, @var{mode}, @var{type}, @var{named})
Define this macro if the target machine has ``register windows'', so
that the register in which a function sees an arguments is not
necessarily the same as the one in which the caller passed the
@@ -3539,9 +3670,9 @@ where the arguments will arrive.
If @code{FUNCTION_INCOMING_ARG} is not defined, @code{FUNCTION_ARG}
serves both purposes.
+@end defmac
-@findex FUNCTION_ARG_PARTIAL_NREGS
-@item FUNCTION_ARG_PARTIAL_NREGS (@var{cum}, @var{mode}, @var{type}, @var{named})
+@defmac FUNCTION_ARG_PARTIAL_NREGS (@var{cum}, @var{mode}, @var{type}, @var{named})
A C expression for the number of words, at the beginning of an
argument, that must be put in registers. The value must be zero for
arguments that are passed entirely in registers or that are entirely
@@ -3559,9 +3690,9 @@ registers.
@code{FUNCTION_ARG} for these arguments should return the first
register to be used by the caller for this argument; likewise
@code{FUNCTION_INCOMING_ARG}, for the called function.
+@end defmac
-@findex FUNCTION_ARG_PASS_BY_REFERENCE
-@item FUNCTION_ARG_PASS_BY_REFERENCE (@var{cum}, @var{mode}, @var{type}, @var{named})
+@defmac FUNCTION_ARG_PASS_BY_REFERENCE (@var{cum}, @var{mode}, @var{type}, @var{named})
A C expression that indicates when an argument must be passed by reference.
If nonzero for an argument, a copy of that argument is made in memory and a
pointer to the argument is passed instead of the argument itself.
@@ -3576,9 +3707,9 @@ definition of this macro might be
MUST_PASS_IN_STACK (MODE, TYPE)
@end smallexample
@c this is *still* too long. --mew 5feb93
+@end defmac
-@findex FUNCTION_ARG_CALLEE_COPIES
-@item FUNCTION_ARG_CALLEE_COPIES (@var{cum}, @var{mode}, @var{type}, @var{named})
+@defmac FUNCTION_ARG_CALLEE_COPIES (@var{cum}, @var{mode}, @var{type}, @var{named})
If defined, a C expression that indicates when it is the called function's
responsibility to make a copy of arguments passed by invisible reference.
Normally, the caller makes a copy and passes the address of the copy to the
@@ -3587,9 +3718,9 @@ nonzero, the caller does not make a copy. Instead, it passes a pointer to the
``live'' value. The called function must not modify this value. If it can be
determined that the value won't be modified, it need not make a copy;
otherwise a copy must be made.
+@end defmac
-@findex CUMULATIVE_ARGS
-@item CUMULATIVE_ARGS
+@defmac CUMULATIVE_ARGS
A C type for declaring a variable that is used as the first argument of
@code{FUNCTION_ARG} and other related values. For some target machines,
the type @code{int} suffices and can hold the number of bytes of
@@ -3601,19 +3732,21 @@ variables to keep track of that. For target machines on which all
arguments are passed on the stack, there is no need to store anything in
@code{CUMULATIVE_ARGS}; however, the data structure must exist and
should not be empty, so use @code{int}.
+@end defmac
-@findex INIT_CUMULATIVE_ARGS
-@item INIT_CUMULATIVE_ARGS (@var{cum}, @var{fntype}, @var{libname}, @var{indirect})
-A C statement (sans semicolon) for initializing the variable @var{cum}
-for the state at the beginning of the argument list. The variable has
-type @code{CUMULATIVE_ARGS}. The value of @var{fntype} is the tree node
-for the data type of the function which will receive the args, or 0
-if the args are to a compiler support library function. The value of
-@var{indirect} is nonzero when processing an indirect call, for example
-a call through a function pointer. The value of @var{indirect} is zero
-for a call to an explicitly named function, a library function call, or when
+@defmac INIT_CUMULATIVE_ARGS (@var{cum}, @var{fntype}, @var{libname}, @var{fndecl}, @var{n_named_args})
+A C statement (sans semicolon) for initializing the variable
+@var{cum} for the state at the beginning of the argument list. The
+variable has type @code{CUMULATIVE_ARGS}. The value of @var{fntype}
+is the tree node for the data type of the function which will receive
+the args, or 0 if the args are to a compiler support library function.
+For direct calls that are not libcalls, @var{fndecl} contain the
+declaration node of the function. @var{fndecl} is also set when
@code{INIT_CUMULATIVE_ARGS} is used to find arguments for the function
-being compiled.
+being compiled. @var{n_named_args} is set to the number of named
+arguments, including a structure return address if it is passed as a
+parameter, when making a call. When processing incoming arguments,
+@var{n_named_args} is set to -1.
When processing a call to a compiler support library function,
@var{libname} identifies which one. It is a @code{symbol_ref} rtx which
@@ -3621,17 +3754,17 @@ contains the name of the function, as a string. @var{libname} is 0 when
an ordinary C function call is being processed. Thus, each time this
macro is called, either @var{libname} or @var{fntype} is nonzero, but
never both of them at once.
+@end defmac
-@findex INIT_CUMULATIVE_LIBCALL_ARGS
-@item INIT_CUMULATIVE_LIBCALL_ARGS (@var{cum}, @var{mode}, @var{libname})
+@defmac INIT_CUMULATIVE_LIBCALL_ARGS (@var{cum}, @var{mode}, @var{libname})
Like @code{INIT_CUMULATIVE_ARGS} but only used for outgoing libcalls,
it gets a @code{MODE} argument instead of @var{fntype}, that would be
@code{NULL}. @var{indirect} would always be zero, too. If this macro
is not defined, @code{INIT_CUMULATIVE_ARGS (cum, NULL_RTX, libname,
0)} is used instead.
+@end defmac
-@findex INIT_CUMULATIVE_INCOMING_ARGS
-@item INIT_CUMULATIVE_INCOMING_ARGS (@var{cum}, @var{fntype}, @var{libname})
+@defmac INIT_CUMULATIVE_INCOMING_ARGS (@var{cum}, @var{fntype}, @var{libname})
Like @code{INIT_CUMULATIVE_ARGS} but overrides it for the purposes of
finding the arguments for the function being compiled. If this macro is
undefined, @code{INIT_CUMULATIVE_ARGS} is used instead.
@@ -3642,9 +3775,9 @@ argument @var{libname} exists for symmetry with
@code{INIT_CUMULATIVE_ARGS}.
@c could use "this macro" in place of @code{INIT_CUMULATIVE_ARGS}, maybe.
@c --mew 5feb93 i switched the order of the sentences. --mew 10feb93
+@end defmac
-@findex FUNCTION_ARG_ADVANCE
-@item FUNCTION_ARG_ADVANCE (@var{cum}, @var{mode}, @var{type}, @var{named})
+@defmac FUNCTION_ARG_ADVANCE (@var{cum}, @var{mode}, @var{type}, @var{named})
A C statement (sans semicolon) to update the summarizer variable
@var{cum} to advance past an argument in the argument list. The
values @var{mode}, @var{type} and @var{named} describe that argument.
@@ -3654,9 +3787,9 @@ the @emph{following} argument with @code{FUNCTION_ARG}, etc.
This macro need not do anything if the argument in question was passed
on the stack. The compiler knows how to track the amount of stack space
used for arguments without any special help.
+@end defmac
-@findex FUNCTION_ARG_PADDING
-@item FUNCTION_ARG_PADDING (@var{mode}, @var{type})
+@defmac FUNCTION_ARG_PADDING (@var{mode}, @var{type})
If defined, a C expression which determines whether, and in which direction,
to pad out an argument with extra space. The value should be of type
@code{enum direction}: either @code{upward} to pad above the argument,
@@ -3670,38 +3803,54 @@ This macro has a default definition which is right for most systems.
For little-endian machines, the default is to pad upward. For
big-endian machines, the default is to pad downward for an argument of
constant size shorter than an @code{int}, and upward otherwise.
+@end defmac
-@findex PAD_VARARGS_DOWN
-@item PAD_VARARGS_DOWN
+@defmac PAD_VARARGS_DOWN
If defined, a C expression which determines whether the default
implementation of va_arg will attempt to pad down before reading the
next argument, if that argument is smaller than its aligned space as
controlled by @code{PARM_BOUNDARY}. If this macro is not defined, all such
arguments are padded down if @code{BYTES_BIG_ENDIAN} is true.
+@end defmac
-@findex FUNCTION_ARG_BOUNDARY
-@item FUNCTION_ARG_BOUNDARY (@var{mode}, @var{type})
+@defmac BLOCK_REG_PADDING (@var{mode}, @var{type}, @var{first})
+Specify padding for the last element of a block move between registers and
+memory. @var{first} is nonzero if this is the only element. Defining this
+macro allows better control of register function parameters on big-endian
+machines, without using @code{PARALLEL} rtl. In particular,
+@code{MUST_PASS_IN_STACK} need not test padding and mode of types in
+registers, as there is no longer a "wrong" part of a register; For example,
+a three byte aggregate may be passed in the high part of a register if so
+required.
+@end defmac
+
+@defmac FUNCTION_ARG_BOUNDARY (@var{mode}, @var{type})
If defined, a C expression that gives the alignment boundary, in bits,
of an argument with the specified mode and type. If it is not defined,
@code{PARM_BOUNDARY} is used for all arguments.
+@end defmac
-@findex FUNCTION_ARG_REGNO_P
-@item FUNCTION_ARG_REGNO_P (@var{regno})
+@defmac FUNCTION_ARG_REGNO_P (@var{regno})
A C expression that is nonzero if @var{regno} is the number of a hard
register in which function arguments are sometimes passed. This does
@emph{not} include implicit arguments such as the static chain and
the structure-value address. On many machines, no registers can be
used for this purpose since all function arguments are pushed on the
stack.
+@end defmac
-@findex LOAD_ARGS_REVERSED
-@item LOAD_ARGS_REVERSED
-If defined, the order in which arguments are loaded into their
-respective argument registers is reversed so that the last
-argument is loaded first. This macro only affects arguments
-passed in registers.
-
-@end table
+@deftypefn {Target Hook} bool TARGET_SPLIT_COMPLEX_ARG (tree @var{type})
+This hook should return true if parameter of type @var{type} are passed
+as two scalar parameters. By default, GCC will attempt to pack complex
+arguments into the target's word size. Some ABIs require complex arguments
+to be split and treated as their individual components. For example, on
+AIX64, complex floats should be passed in a pair of floating point
+registers, even though a complex float would fit in one 64-bit floating
+point register.
+
+The default value of this hook is @code{NULL}, which is treated as always
+false.
+@end deftypefn
@node Scalar Return
@subsection How Scalar Function Values Are Returned
@@ -3712,9 +3861,7 @@ passed in registers.
This section discusses the macros that control returning scalars as
values---values that can fit in registers.
-@table @code
-@findex FUNCTION_VALUE
-@item FUNCTION_VALUE (@var{valtype}, @var{func})
+@defmac FUNCTION_VALUE (@var{valtype}, @var{func})
A C expression to create an RTX representing the place where a
function returns a value of data type @var{valtype}. @var{valtype} is
a tree node representing a data type. Write @code{TYPE_MODE
@@ -3728,7 +3875,7 @@ register where the return value is stored. The value can also be a
@code{parallel} RTX, if the return value is in multiple places. See
@code{FUNCTION_ARG} for an explanation of the @code{parallel} form.
-If @code{PROMOTE_FUNCTION_RETURN} is defined, you must apply the same
+If @code{TARGET_PROMOTE_FUNCTION_RETURN} returns true, you must apply the same
promotion rules specified in @code{PROMOTE_MODE} if @var{valtype} is a
scalar type.
@@ -3740,10 +3887,10 @@ known.
@code{FUNCTION_VALUE} is not used for return vales with aggregate data
types, because these are returned in another way. See
-@code{STRUCT_VALUE_REGNUM} and related macros, below.
+@code{TARGET_STRUCT_VALUE_RTX} and related macros, below.
+@end defmac
-@findex FUNCTION_OUTGOING_VALUE
-@item FUNCTION_OUTGOING_VALUE (@var{valtype}, @var{func})
+@defmac FUNCTION_OUTGOING_VALUE (@var{valtype}, @var{func})
Define this macro if the target machine has ``register windows''
so that the register in which a function returns its value is not
the same as the one in which the caller sees the value.
@@ -3758,10 +3905,10 @@ If @code{FUNCTION_OUTGOING_VALUE} is not defined,
@code{FUNCTION_OUTGOING_VALUE} is not used for return vales with
aggregate data types, because these are returned in another way. See
-@code{STRUCT_VALUE_REGNUM} and related macros, below.
+@code{TARGET_STRUCT_VALUE_RTX} and related macros, below.
+@end defmac
-@findex LIBCALL_VALUE
-@item LIBCALL_VALUE (@var{mode})
+@defmac LIBCALL_VALUE (@var{mode})
A C expression to create an RTX representing the place where a library
function returns a value of mode @var{mode}. If the precise function
being called is known, @var{func} is a tree node
@@ -3777,9 +3924,9 @@ compiled.
The definition of @code{LIBRARY_VALUE} need not be concerned aggregate
data types, because none of the library functions returns such types.
+@end defmac
-@findex FUNCTION_VALUE_REGNO_P
-@item FUNCTION_VALUE_REGNO_P (@var{regno})
+@defmac FUNCTION_VALUE_REGNO_P (@var{regno})
A C expression that is nonzero if @var{regno} is the number of a hard
register in which the values of called function may come back.
@@ -3788,20 +3935,32 @@ second of a pair (for a value of type @code{double}, say) need not be
recognized by this macro. So for most machines, this definition
suffices:
-@example
+@smallexample
#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
-@end example
+@end smallexample
If the machine has register windows, so that the caller and the called
function use different registers for the return value, this macro
should recognize only the caller's register numbers.
+@end defmac
-@findex APPLY_RESULT_SIZE
-@item APPLY_RESULT_SIZE
+@defmac APPLY_RESULT_SIZE
Define this macro if @samp{untyped_call} and @samp{untyped_return}
need more space than is implied by @code{FUNCTION_VALUE_REGNO_P} for
saving and restoring an arbitrary return value.
-@end table
+@end defmac
+
+@deftypefn {Target Hook} bool TARGET_RETURN_IN_MSB (tree @var{type})
+This hook should return true if values of type @var{type} are returned
+at the most significant end of a register (in other words, if they are
+padded at the least significant end). You can assume that @var{type}
+is returned in a register; the caller is required to check this.
+
+Note that the register provided by @code{FUNCTION_VALUE} must be able
+to hold the complete return value. For example, if a 1-, 2- or 3-byte
+structure is returned at the most significant end of a 4-byte register,
+@code{FUNCTION_VALUE} should provide an @code{SImode} rtx.
+@end deftypefn
@node Aggregate Return
@subsection How Large Values Are Returned
@@ -3819,69 +3978,55 @@ is called the @dfn{structure value address}.
This section describes how to control returning structure values in
memory.
-@table @code
-@findex RETURN_IN_MEMORY
-@item RETURN_IN_MEMORY (@var{type})
-A C expression which can inhibit the returning of certain function
-values in registers, based on the type of value. A nonzero value says
-to return the function value in memory, just as large structures are
-always returned. Here @var{type} will be a C expression of type
-@code{tree}, representing the data type of the value.
+@deftypefn {Target Hook} bool TARGET_RETURN_IN_MEMORY (tree @var{type}, tree @var{fntype})
+This target hook should return a nonzero value to say to return the
+function value in memory, just as large structures are always returned.
+Here @var{type} will be the data type of the value, and @var{fntype}
+will be the type of the function doing the returning, or @code{NULL} for
+libcalls.
Note that values of mode @code{BLKmode} must be explicitly handled
-by this macro. Also, the option @option{-fpcc-struct-return}
+by this function. Also, the option @option{-fpcc-struct-return}
takes effect regardless of this macro. On most systems, it is
-possible to leave the macro undefined; this causes a default
+possible to leave the hook undefined; this causes a default
definition to be used, whose value is the constant 1 for @code{BLKmode}
values, and 0 otherwise.
-Do not use this macro to indicate that structures and unions should always
+Do not use this hook to indicate that structures and unions should always
be returned in memory. You should instead use @code{DEFAULT_PCC_STRUCT_RETURN}
to indicate this.
+@end deftypefn
-@findex DEFAULT_PCC_STRUCT_RETURN
-@item DEFAULT_PCC_STRUCT_RETURN
+@defmac DEFAULT_PCC_STRUCT_RETURN
Define this macro to be 1 if all structure and union return values must be
in memory. Since this results in slower code, this should be defined
only if needed for compatibility with other compilers or with an ABI@.
If you define this macro to be 0, then the conventions used for structure
-and union return values are decided by the @code{RETURN_IN_MEMORY} macro.
+and union return values are decided by the @code{TARGET_RETURN_IN_MEMORY}
+target hook.
If not defined, this defaults to the value 1.
+@end defmac
-@findex STRUCT_VALUE_REGNUM
-@item STRUCT_VALUE_REGNUM
-If the structure value address is passed in a register, then
-@code{STRUCT_VALUE_REGNUM} should be the number of that register.
-
-@findex STRUCT_VALUE
-@item STRUCT_VALUE
-If the structure value address is not passed in a register, define
-@code{STRUCT_VALUE} as an expression returning an RTX for the place
-where the address is passed. If it returns 0, the address is passed as
-an ``invisible'' first argument.
+@deftypefn {Target Hook} rtx TARGET_STRUCT_VALUE_RTX (tree @var{fndecl}, int @var{incoming})
+This target hook should return the location of the structure value
+address (normally a @code{mem} or @code{reg}), or 0 if the address is
+passed as an ``invisible'' first argument. Note that @var{fndecl} may
+be @code{NULL}, for libcalls.
-@findex STRUCT_VALUE_INCOMING_REGNUM
-@item STRUCT_VALUE_INCOMING_REGNUM
On some architectures the place where the structure value address
is found by the called function is not the same place that the
caller put it. This can be due to register windows, or it could
be because the function prologue moves it to a different place.
+@var{incoming} is @code{true} when the location is needed in
+the context of the called function, and @code{false} in the context of
+the caller.
-If the incoming location of the structure value address is in a
-register, define this macro as the register number.
-
-@findex STRUCT_VALUE_INCOMING
-@item STRUCT_VALUE_INCOMING
-If the incoming location is not a register, then you should define
-@code{STRUCT_VALUE_INCOMING} as an expression for an RTX for where the
-called function should find the value. If it should find the value on
-the stack, define this to create a @code{mem} which refers to the frame
-pointer. A definition of 0 means that the address is passed as an
-``invisible'' first argument.
+If @var{incoming} is @code{true} and the address is to be found on the
+stack, return a @code{mem} which refers to the frame pointer.
+@end deftypefn
-@findex PCC_STATIC_STRUCT_RETURN
-@item PCC_STATIC_STRUCT_RETURN
+@defmac PCC_STATIC_STRUCT_RETURN
Define this macro if the usual system convention on the target machine
for returning structures and unions is for the called function to return
the address of a static variable containing the value.
@@ -3891,7 +4036,7 @@ pass an address to the subroutine.
This macro has effect in @option{-fpcc-struct-return} mode, but it does
nothing when you use @option{-freg-struct-return} mode.
-@end table
+@end defmac
@node Caller Saves
@subsection Caller-Saves Register Allocation
@@ -3900,17 +4045,7 @@ If you enable it, GCC can save registers around function calls. This
makes it possible to use call-clobbered registers to hold variables that
must live across calls.
-@table @code
-@findex DEFAULT_CALLER_SAVES
-@item DEFAULT_CALLER_SAVES
-Define this macro if function calls on the target machine do not preserve
-any registers; in other words, if @code{CALL_USED_REGISTERS} has 1
-for all registers. When defined, this macro enables @option{-fcaller-saves}
-by default for all optimization levels. It has no effect for optimization
-levels 2 and higher, where @option{-fcaller-saves} is the default.
-
-@findex CALLER_SAVE_PROFITABLE
-@item CALLER_SAVE_PROFITABLE (@var{refs}, @var{calls})
+@defmac CALLER_SAVE_PROFITABLE (@var{refs}, @var{calls})
A C expression to determine whether it is worthwhile to consider placing
a pseudo-register in a call-clobbered hard register and saving and
restoring it around each function call. The expression should be 1 when
@@ -3918,15 +4053,15 @@ this is worth doing, and 0 otherwise.
If you don't define this macro, a default is used which is good on most
machines: @code{4 * @var{calls} < @var{refs}}.
+@end defmac
-@findex HARD_REGNO_CALLER_SAVE_MODE
-@item HARD_REGNO_CALLER_SAVE_MODE (@var{regno}, @var{nregs})
+@defmac HARD_REGNO_CALLER_SAVE_MODE (@var{regno}, @var{nregs})
A C expression specifying which mode is required for saving @var{nregs}
of a pseudo-register in call-clobbered hard register @var{regno}. If
@var{regno} is unsuitable for caller save, @code{VOIDmode} should be
returned. For most machines this macro need not be defined since GCC
will select the smallest suitable mode.
-@end table
+@end defmac
@node Function Entry
@subsection Function Entry and Exit
@@ -4044,8 +4179,6 @@ arguments that a function should pop. @xref{Scalar Return}.
@c tell? --mew 5feb93
@end deftypefn
-@table @code
-
@itemize @bullet
@item
@findex current_function_pretend_args_size
@@ -4086,39 +4219,39 @@ Normally, it is necessary for the macros
The C variable @code{current_function_is_leaf} is nonzero for such a
function.
-@findex EXIT_IGNORE_STACK
-@item EXIT_IGNORE_STACK
+@defmac EXIT_IGNORE_STACK
Define this macro as a C expression that is nonzero if the return
instruction or the function epilogue ignores the value of the stack
pointer; in other words, if it is safe to delete an instruction to
-adjust the stack pointer before a return from the function.
+adjust the stack pointer before a return from the function. The
+default is 0.
Note that this macro's value is relevant only for functions for which
frame pointers are maintained. It is never safe to delete a final
stack adjustment in a function that has no frame pointer, and the
compiler knows this regardless of @code{EXIT_IGNORE_STACK}.
+@end defmac
-@findex EPILOGUE_USES
-@item EPILOGUE_USES (@var{regno})
+@defmac EPILOGUE_USES (@var{regno})
Define this macro as a C expression that is nonzero for registers that are
used by the epilogue or the @samp{return} pattern. The stack and frame
pointer registers are already be assumed to be used as needed.
+@end defmac
-@findex EH_USES
-@item EH_USES (@var{regno})
+@defmac EH_USES (@var{regno})
Define this macro as a C expression that is nonzero for registers that are
used by the exception handling mechanism, and so should be considered live
on entry to an exception edge.
+@end defmac
-@findex DELAY_SLOTS_FOR_EPILOGUE
-@item DELAY_SLOTS_FOR_EPILOGUE
+@defmac DELAY_SLOTS_FOR_EPILOGUE
Define this macro if the function epilogue contains delay slots to which
instructions from the rest of the function can be ``moved''. The
definition should be a C expression whose value is an integer
representing the number of delay slots there.
+@end defmac
-@findex ELIGIBLE_FOR_EPILOGUE_DELAY
-@item ELIGIBLE_FOR_EPILOGUE_DELAY (@var{insn}, @var{n})
+@defmac ELIGIBLE_FOR_EPILOGUE_DELAY (@var{insn}, @var{n})
A C expression that returns 1 if @var{insn} can be placed in delay
slot number @var{n} of the epilogue.
@@ -4143,10 +4276,8 @@ outputting the insns in this list, usually by calling
You need not define this macro if you did not define
@code{DELAY_SLOTS_FOR_EPILOGUE}.
+@end defmac
-@end table
-
-@findex TARGET_ASM_OUTPUT_MI_THUNK
@deftypefn {Target Hook} void TARGET_ASM_OUTPUT_MI_THUNK (FILE *@var{file}, tree @var{thunk_fndecl}, HOST_WIDE_INT @var{delta}, tree @var{function})
A function that outputs the assembler code for a thunk
function, used to implement C++ virtual function calls with multiple
@@ -4181,21 +4312,19 @@ front end will generate a less efficient heavyweight thunk that calls
not support varargs.
@end deftypefn
-@findex TARGET_ASM_OUTPUT_MI_VCALL_THUNK
@deftypefn {Target Hook} void TARGET_ASM_OUTPUT_MI_VCALL_THUNK (FILE *@var{file}, tree @var{thunk_fndecl}, HOST_WIDE_INT @var{delta}, int @var{vcall_offset}, tree @var{function})
A function like @code{TARGET_ASM_OUTPUT_MI_THUNK}, except that if
@var{vcall_offset} is nonzero, an additional adjustment should be made
after adding @code{delta}. In particular, if @var{p} is the
adjusted pointer, the following adjustment should be made:
-@example
+@smallexample
p += (*((ptrdiff_t **)p))[vcall_offset/sizeof(ptrdiff_t)]
-@end example
+@end smallexample
@noindent
If this function is defined, it will always be used in place of
@code{TARGET_ASM_OUTPUT_MI_THUNK}.
-
@end deftypefn
@node Profiling
@@ -4204,9 +4333,7 @@ If this function is defined, it will always be used in place of
These macros will help you generate code for profiling.
-@table @code
-@findex FUNCTION_PROFILER
-@item FUNCTION_PROFILER (@var{file}, @var{labelno})
+@defmac FUNCTION_PROFILER (@var{file}, @var{labelno})
A C statement or compound statement to output to @var{file} some
assembler code to call the profiling subroutine @code{mcount}.
@@ -4220,42 +4347,42 @@ Older implementations of @code{mcount} expect the address of a counter
variable to be loaded into some register. The name of this variable is
@samp{LP} followed by the number @var{labelno}, so you would generate
the name using @samp{LP%d} in a @code{fprintf}.
+@end defmac
-@findex PROFILE_HOOK
-@item PROFILE_HOOK
+@defmac PROFILE_HOOK
A C statement or compound statement to output to @var{file} some assembly
code to call the profiling subroutine @code{mcount} even the target does
not support profiling.
+@end defmac
-@findex NO_PROFILE_COUNTERS
-@item NO_PROFILE_COUNTERS
+@defmac NO_PROFILE_COUNTERS
Define this macro if the @code{mcount} subroutine on your system does
not need a counter variable allocated for each function. This is true
for almost all modern implementations. If you define this macro, you
must not use the @var{labelno} argument to @code{FUNCTION_PROFILER}.
+@end defmac
-@findex PROFILE_BEFORE_PROLOGUE
-@item PROFILE_BEFORE_PROLOGUE
+@defmac PROFILE_BEFORE_PROLOGUE
Define this macro if the code for function profiling should come before
the function prologue. Normally, the profiling code comes after.
-@end table
+@end defmac
@node Tail Calls
@subsection Permitting tail calls
@cindex tail calls
-@table @code
-@findex FUNCTION_OK_FOR_SIBCALL
-@item FUNCTION_OK_FOR_SIBCALL (@var{decl})
-A C expression that evaluates to true if it is ok to perform a sibling
-call to @var{decl} from the current function.
+@deftypefn {Target Hook} bool TARGET_FUNCTION_OK_FOR_SIBCALL (tree @var{decl}, tree @var{exp})
+True if it is ok to do sibling call optimization for the specified
+call expression @var{exp}. @var{decl} will be the called function,
+or @code{NULL} if this is an indirect call.
It is not uncommon for limitations of calling conventions to prevent
tail calls to functions outside the current unit of translation, or
-during PIC compilation. Use this macro to enforce these restrictions,
+during PIC compilation. The hook is used to enforce these restrictions,
as the @code{sibcall} md pattern can not fail, or fall over to a
-``normal'' call.
-@end table
+``normal'' call. The criteria for successful sibling call optimization
+may vary greatly between different architectures.
+@end deftypefn
@node Varargs
@section Implementing the Varargs Macros
@@ -4278,9 +4405,7 @@ However, @code{va_start} should not use this argument. The way to find
the end of the named arguments is with the built-in functions described
below.
-@table @code
-@findex __builtin_saveregs
-@item __builtin_saveregs ()
+@defmac __builtin_saveregs ()
Use this built-in function to save the argument registers in memory so
that the varargs mechanism can access them. Both ISO and traditional
versions of @code{va_start} must use @code{__builtin_saveregs}, unless
@@ -4298,9 +4423,9 @@ This is because the registers must be saved before the function starts
to use them for its own purposes.
@c i rewrote the first sentence above to fix an overfull hbox. --mew
@c 10feb93
+@end defmac
-@findex __builtin_args_info
-@item __builtin_args_info (@var{category})
+@defmac __builtin_args_info (@var{category})
Use this built-in function to find the first anonymous arguments in
registers.
@@ -4322,9 +4447,9 @@ of @code{va_start}, accessing each category just once and storing the
value in the @code{va_list} object. This is because @code{va_list} will
have to update the values, and there is no way to alter the
values accessed by @code{__builtin_args_info}.
+@end defmac
-@findex __builtin_next_arg
-@item __builtin_next_arg (@var{lastarg})
+@defmac __builtin_next_arg (@var{lastarg})
This is the equivalent of @code{__builtin_args_info}, for stack
arguments. It returns the address of the first anonymous stack
argument, as type @code{void *}. If @code{ARGS_GROW_DOWNWARD}, it
@@ -4333,9 +4458,9 @@ argument. Use it in @code{va_start} to initialize the pointer for
fetching arguments from the stack. Also use it in @code{va_start} to
verify that the second parameter @var{lastarg} is the last named argument
of the current function.
+@end defmac
-@findex __builtin_classify_type
-@item __builtin_classify_type (@var{object})
+@defmac __builtin_classify_type (@var{object})
Since each machine has its own conventions for which data types are
passed in which kind of register, your implementation of @code{va_arg}
has to embody these conventions. The easiest way to categorize the
@@ -4348,76 +4473,75 @@ kind of type that is---integer, floating, pointer, structure, and so on.
The file @file{typeclass.h} defines an enumeration that you can use to
interpret the values of @code{__builtin_classify_type}.
-@end table
+@end defmac
These machine description macros help implement varargs:
-@table @code
-@findex EXPAND_BUILTIN_SAVEREGS
-@item EXPAND_BUILTIN_SAVEREGS ()
-If defined, is a C expression that produces the machine-specific code
-for a call to @code{__builtin_saveregs}. This code will be moved to the
-very beginning of the function, before any parameter access are made.
-The return value of this function should be an RTX that contains the
-value to use as the return of @code{__builtin_saveregs}.
-
-@findex SETUP_INCOMING_VARARGS
-@item SETUP_INCOMING_VARARGS (@var{args_so_far}, @var{mode}, @var{type}, @var{pretend_args_size}, @var{second_time})
-This macro offers an alternative to using @code{__builtin_saveregs} and
-defining the macro @code{EXPAND_BUILTIN_SAVEREGS}. Use it to store the
-anonymous register arguments into the stack so that all the arguments
-appear to have been passed consecutively on the stack. Once this is
-done, you can use the standard implementation of varargs that works for
-machines that pass all their arguments on the stack.
-
-The argument @var{args_so_far} is the @code{CUMULATIVE_ARGS} data
+@deftypefn {Target Hook} rtx TARGET_EXPAND_BUILTIN_SAVEREGS (void)
+If defined, this hook produces the machine-specific code for a call to
+@code{__builtin_saveregs}. This code will be moved to the very
+beginning of the function, before any parameter access are made. The
+return value of this function should be an RTX that contains the value
+to use as the return of @code{__builtin_saveregs}.
+@end deftypefn
+
+@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARGS (CUMULATIVE_ARGS *@var{args_so_far}, enum machine_mode @var{mode}, tree @var{type}, int *@var{pretend_args_size}, int @var{second_time})
+This target hook offers an alternative to using
+@code{__builtin_saveregs} and defining the hook
+@code{TARGET_EXPAND_BUILTIN_SAVEREGS}. Use it to store the anonymous
+register arguments into the stack so that all the arguments appear to
+have been passed consecutively on the stack. Once this is done, you can
+use the standard implementation of varargs that works for machines that
+pass all their arguments on the stack.
+
+The argument @var{args_so_far} points to the @code{CUMULATIVE_ARGS} data
structure, containing the values that are obtained after processing the
named arguments. The arguments @var{mode} and @var{type} describe the
last named argument---its machine mode and its data type as a tree node.
-The macro implementation should do two things: first, push onto the
-stack all the argument registers @emph{not} used for the named
-arguments, and second, store the size of the data thus pushed into the
-@code{int}-valued variable whose name is supplied as the argument
-@var{pretend_args_size}. The value that you store here will serve as
-additional offset for setting up the stack frame.
+The target hook should do two things: first, push onto the stack all the
+argument registers @emph{not} used for the named arguments, and second,
+store the size of the data thus pushed into the @code{int}-valued
+variable pointed to by @var{pretend_args_size}. The value that you
+store here will serve as additional offset for setting up the stack
+frame.
Because you must generate code to push the anonymous arguments at
compile time without knowing their data types,
-@code{SETUP_INCOMING_VARARGS} is only useful on machines that have just
-a single category of argument register and use it uniformly for all data
-types.
+@code{TARGET_SETUP_INCOMING_VARARGS} is only useful on machines that
+have just a single category of argument register and use it uniformly
+for all data types.
If the argument @var{second_time} is nonzero, it means that the
arguments of the function are being analyzed for the second time. This
happens for an inline function, which is not actually compiled until the
-end of the source file. The macro @code{SETUP_INCOMING_VARARGS} should
+end of the source file. The hook @code{TARGET_SETUP_INCOMING_VARARGS} should
not generate any instructions in this case.
+@end deftypefn
-@findex STRICT_ARGUMENT_NAMING
-@item STRICT_ARGUMENT_NAMING
-Define this macro to be a nonzero value if the location where a function
+@deftypefn {Target Hook} bool TARGET_STRICT_ARGUMENT_NAMING (CUMULATIVE_ARGS *@var{ca})
+Define this hook to return @code{true} if the location where a function
argument is passed depends on whether or not it is a named argument.
-This macro controls how the @var{named} argument to @code{FUNCTION_ARG}
-is set for varargs and stdarg functions. If this macro returns a
-nonzero value, the @var{named} argument is always true for named
-arguments, and false for unnamed arguments. If it returns a value of
-zero, but @code{SETUP_INCOMING_VARARGS} is defined, then all arguments
-are treated as named. Otherwise, all named arguments except the last
-are treated as named.
+This hook controls how the @var{named} argument to @code{FUNCTION_ARG}
+is set for varargs and stdarg functions. If this hook returns
+@code{true}, the @var{named} argument is always true for named
+arguments, and false for unnamed arguments. If it returns @code{false},
+but @code{TARGET_PRETEND_OUTOGOING_VARARGS_NAMED} returns @code{true},
+then all arguments are treated as named. Otherwise, all named arguments
+except the last are treated as named.
-You need not define this macro if it always returns zero.
+You need not define this hook if it always returns zero.
+@end deftypefn
-@findex PRETEND_OUTGOING_VARARGS_NAMED
-@item PRETEND_OUTGOING_VARARGS_NAMED
+@deftypefn {Target Hook} bool TARGET_PRETEND_OUTGOING_VARARGS_NAMED
If you need to conditionally change ABIs so that one works with
-@code{SETUP_INCOMING_VARARGS}, but the other works like neither
-@code{SETUP_INCOMING_VARARGS} nor @code{STRICT_ARGUMENT_NAMING} was
-defined, then define this macro to return nonzero if
-@code{SETUP_INCOMING_VARARGS} is used, zero otherwise.
-Otherwise, you should not define this macro.
-@end table
+@code{TARGET_SETUP_INCOMING_VARARGS}, but the other works like neither
+@code{TARGET_SETUP_INCOMING_VARARGS} nor @code{TARGET_STRICT_ARGUMENT_NAMING} was
+defined, then define this hook to return @code{true} if
+@code{SETUP_INCOMING_VARARGS} is used, @code{false} otherwise.
+Otherwise, you should not define this hook.
+@end deftypefn
@node Trampolines
@section Trampolines for Nested Functions
@@ -4447,9 +4571,7 @@ proper offset from the start of the trampoline. On a RISC machine, it
may be necessary to take out pieces of the address and store them
separately.
-@table @code
-@findex TRAMPOLINE_TEMPLATE
-@item TRAMPOLINE_TEMPLATE (@var{file})
+@defmac TRAMPOLINE_TEMPLATE (@var{file})
A C statement to output, on the stream @var{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
@@ -4459,35 +4581,35 @@ If you do not define this macro, it means no template is needed
for the target. Do not define this macro on systems where the block move
code to copy the trampoline into place would be larger than the code
to generate it on the spot.
+@end defmac
-@findex TRAMPOLINE_SECTION
-@item TRAMPOLINE_SECTION
+@defmac TRAMPOLINE_SECTION
The name of a subroutine to switch to the section in which the
trampoline template is to be placed (@pxref{Sections}). The default is
a value of @samp{readonly_data_section}, which places the trampoline in
the section containing read-only data.
+@end defmac
-@findex TRAMPOLINE_SIZE
-@item TRAMPOLINE_SIZE
+@defmac TRAMPOLINE_SIZE
A C expression for the size in bytes of the trampoline, as an integer.
+@end defmac
-@findex TRAMPOLINE_ALIGNMENT
-@item TRAMPOLINE_ALIGNMENT
+@defmac TRAMPOLINE_ALIGNMENT
Alignment required for trampolines, in bits.
If you don't define this macro, the value of @code{BIGGEST_ALIGNMENT}
is used for aligning trampolines.
+@end defmac
-@findex INITIALIZE_TRAMPOLINE
-@item INITIALIZE_TRAMPOLINE (@var{addr}, @var{fnaddr}, @var{static_chain})
+@defmac INITIALIZE_TRAMPOLINE (@var{addr}, @var{fnaddr}, @var{static_chain})
A C statement to initialize the variable parts of a trampoline.
@var{addr} is an RTX for the address of the trampoline; @var{fnaddr} is
an RTX for the address of the nested function; @var{static_chain} is an
RTX for the static chain value that should be passed to the function
when it is called.
+@end defmac
-@findex TRAMPOLINE_ADJUST_ADDRESS
-@item TRAMPOLINE_ADJUST_ADDRESS (@var{addr})
+@defmac TRAMPOLINE_ADJUST_ADDRESS (@var{addr})
A C statement that should perform any machine-specific adjustment in
the address of the trampoline. Its argument contains the address that
was passed to @code{INITIALIZE_TRAMPOLINE}. In case the address to be
@@ -4496,12 +4618,6 @@ the template was stored, the different address should be assigned to
@var{addr}. If this macro is not defined, @var{addr} will be used for
function calls.
-@findex ALLOCATE_TRAMPOLINE
-@item ALLOCATE_TRAMPOLINE (@var{fp})
-A C expression to allocate run-time space for a trampoline. The
-expression value should be an RTX representing a memory reference to the
-space for the trampoline.
-
@cindex @code{TARGET_ASM_FUNCTION_EPILOGUE} and trampolines
@cindex @code{TARGET_ASM_FUNCTION_PROLOGUE} and trampolines
If this macro is not defined, by default the trampoline is allocated as
@@ -4513,12 +4629,11 @@ and @code{TARGET_ASM_FUNCTION_EPILOGUE}.
@var{fp} points to a data structure, a @code{struct function}, which
describes the compilation status of the immediate containing function of
-the function which the trampoline is for. Normally (when
-@code{ALLOCATE_TRAMPOLINE} is not defined), the stack slot for the
+the function which the trampoline is for. The stack slot for the
trampoline is in the stack frame of this containing function. Other
allocation strategies probably must do something analogous with this
information.
-@end table
+@end defmac
Implementing trampolines is difficult on many machines because they have
separate instruction and data caches. Writing into a stack location
@@ -4532,40 +4647,27 @@ subroutine. The former technique makes trampoline execution faster; the
latter makes initialization faster.
To clear the instruction cache when a trampoline is initialized, define
-the following macros which describe the shape of the cache.
-
-@table @code
-@findex INSN_CACHE_SIZE
-@item INSN_CACHE_SIZE
-The total size in bytes of the cache.
-
-@findex INSN_CACHE_LINE_WIDTH
-@item INSN_CACHE_LINE_WIDTH
-The length in bytes of each cache line. The cache is divided into cache
-lines which are disjoint slots, each holding a contiguous chunk of data
-fetched from memory. Each time data is brought into the cache, an
-entire line is read at once. The data loaded into a cache line is
-always aligned on a boundary equal to the line size.
-
-@findex INSN_CACHE_DEPTH
-@item INSN_CACHE_DEPTH
-The number of alternative cache lines that can hold any particular memory
-location.
-@end table
-
-Alternatively, if the machine has system calls or instructions to clear
-the instruction cache directly, you can define the following macro.
-
-@table @code
-@findex CLEAR_INSN_CACHE
-@item CLEAR_INSN_CACHE (@var{beg}, @var{end})
+the following macro.
+
+@defmac CLEAR_INSN_CACHE (@var{beg}, @var{end})
If defined, expands to a C expression clearing the @emph{instruction
-cache} in the specified interval. If it is not defined, and the macro
-@code{INSN_CACHE_SIZE} is defined, some generic code is generated to clear the
-cache. The definition of this macro would typically be a series of
-@code{asm} statements. Both @var{beg} and @var{end} are both pointer
-expressions.
-@end table
+cache} in the specified interval. The definition of this macro would
+typically be a series of @code{asm} statements. Both @var{beg} and
+@var{end} are both pointer expressions.
+@end defmac
+
+The operating system may also require the stack to be made executable
+before calling the trampoline. To implement this requirement, define
+the following macro.
+
+@defmac ENABLE_EXECUTE_STACK
+Define this macro if certain operations must be performed before executing
+code located on the stack. The macro should expand to a series of C
+file-scope constructs (e.g. functions) and provide a unique entry point
+named @code{__enable_execute_stack}. The target is responsible for
+emitting calls to the entry point in the code, for example from the
+@code{INITIALIZE_TRAMPOLINE} macro.
+@end defmac
To use a standard subroutine, define the following macro. In addition,
you must make sure that the instructions in a trampoline fill an entire
@@ -4573,9 +4675,7 @@ cache line with identical instructions, or else ensure that the
beginning of the trampoline code is always aligned at the same point in
its cache line. Look in @file{m68k.h} as a guide.
-@table @code
-@findex TRANSFER_FROM_TRAMPOLINE
-@item TRANSFER_FROM_TRAMPOLINE
+@defmac TRANSFER_FROM_TRAMPOLINE
Define this macro if trampolines need a special subroutine to do their
work. The macro should expand to a series of @code{asm} statements
which will be compiled with GCC@. They go in a library function named
@@ -4587,7 +4687,7 @@ special label of your own in the assembler code. Use one @code{asm}
statement to generate an assembler label, and another to make the label
global. Then trampolines can use that label to jump directly to your
special assembler code.
-@end table
+@end defmac
@node Library Calls
@section Implicit Calls to Library Routines
@@ -4597,102 +4697,59 @@ special assembler code.
@c prevent bad page break with this line
Here is an explanation of implicit calls to library routines.
-@table @code
-@findex MULSI3_LIBCALL
-@item MULSI3_LIBCALL
-A C string constant giving the name of the function to call for
-multiplication of one signed full-word by another. If you do not
-define this macro, the default name is used, which is @code{__mulsi3},
-a function defined in @file{libgcc.a}.
-
-@findex DIVSI3_LIBCALL
-@item DIVSI3_LIBCALL
-A C string constant giving the name of the function to call for
-division of one signed full-word by another. If you do not define
-this macro, the default name is used, which is @code{__divsi3}, a
-function defined in @file{libgcc.a}.
-
-@findex UDIVSI3_LIBCALL
-@item UDIVSI3_LIBCALL
-A C string constant giving the name of the function to call for
-division of one unsigned full-word by another. If you do not define
-this macro, the default name is used, which is @code{__udivsi3}, a
-function defined in @file{libgcc.a}.
-
-@findex MODSI3_LIBCALL
-@item MODSI3_LIBCALL
-A C string constant giving the name of the function to call for the
-remainder in division of one signed full-word by another. If you do
-not define this macro, the default name is used, which is
-@code{__modsi3}, a function defined in @file{libgcc.a}.
-
-@findex UMODSI3_LIBCALL
-@item UMODSI3_LIBCALL
-A C string constant giving the name of the function to call for the
-remainder in division of one unsigned full-word by another. If you do
-not define this macro, the default name is used, which is
-@code{__umodsi3}, a function defined in @file{libgcc.a}.
-
-@findex MULDI3_LIBCALL
-@item MULDI3_LIBCALL
-A C string constant giving the name of the function to call for
-multiplication of one signed double-word by another. If you do not
-define this macro, the default name is used, which is @code{__muldi3},
-a function defined in @file{libgcc.a}.
-
-@findex DIVDI3_LIBCALL
-@item DIVDI3_LIBCALL
-A C string constant giving the name of the function to call for
-division of one signed double-word by another. If you do not define
-this macro, the default name is used, which is @code{__divdi3}, a
-function defined in @file{libgcc.a}.
-
-@findex UDIVDI3_LIBCALL
-@item UDIVDI3_LIBCALL
-A C string constant giving the name of the function to call for
-division of one unsigned full-word by another. If you do not define
-this macro, the default name is used, which is @code{__udivdi3}, a
-function defined in @file{libgcc.a}.
-
-@findex MODDI3_LIBCALL
-@item MODDI3_LIBCALL
-A C string constant giving the name of the function to call for the
-remainder in division of one signed double-word by another. If you do
-not define this macro, the default name is used, which is
-@code{__moddi3}, a function defined in @file{libgcc.a}.
-
-@findex UMODDI3_LIBCALL
-@item UMODDI3_LIBCALL
-A C string constant giving the name of the function to call for the
-remainder in division of one unsigned full-word by another. If you do
-not define this macro, the default name is used, which is
-@code{__umoddi3}, a function defined in @file{libgcc.a}.
-
-@findex DECLARE_LIBRARY_RENAMES
-@item DECLARE_LIBRARY_RENAMES
+@defmac DECLARE_LIBRARY_RENAMES
This macro, if defined, should expand to a piece of C code that will get
expanded when compiling functions for libgcc.a. It can be used to
-provide alternate names for gcc's internal library functions if there
+provide alternate names for GCC's internal library functions if there
are ABI-mandated names that the compiler should provide.
+@end defmac
+
+@findex init_one_libfunc
+@findex set_optab_libfunc
+@deftypefn {Target Hook} void TARGET_INIT_LIBFUNCS (void)
+This hook should declare additional library routines or rename
+existing ones, using the functions @code{set_optab_libfunc} and
+@code{init_one_libfunc} defined in @file{optabs.c}.
+@code{init_optabs} calls this macro after initializing all the normal
+library routines.
-@findex INIT_TARGET_OPTABS
-@item INIT_TARGET_OPTABS
-Define this macro as a C statement that declares additional library
-routines renames existing ones. @code{init_optabs} calls this macro after
-initializing all the normal library routines.
+The default is to do nothing. Most ports don't need to define this hook.
+@end deftypefn
-@findex FLOAT_LIB_COMPARE_RETURNS_BOOL (@var{mode}, @var{comparison})
-@item FLOAT_LIB_COMPARE_RETURNS_BOOL
-Define this macro as a C statement that returns nonzero if a call to
-the floating point comparison library function will return a boolean
-value that indicates the result of the comparison. It should return
-zero if one of gcc's own libgcc functions is called.
+@defmac TARGET_FLOAT_LIB_COMPARE_RETURNS_BOOL (@var{mode}, @var{comparison})
+This macro should return @code{true} if the library routine that
+implements the floating point comparison operator @var{comparison} in
+mode @var{mode} will return a boolean, and @var{false} if it will
+return a tristate.
-Most ports don't need to define this macro.
+GCC's own floating point libraries return tristates from the
+comparison operators, so the default returns false always. Most ports
+don't need to define this macro.
+@end defmac
+
+@cindex US Software GOFAST, floating point emulation library
+@cindex floating point emulation library, US Software GOFAST
+@cindex GOFAST, floating point emulation library
+@findex gofast_maybe_init_libfuncs
+@defmac US_SOFTWARE_GOFAST
+Define this macro if your system C library uses the US Software GOFAST
+library to provide floating point emulation.
+
+In addition to defining this macro, your architecture must set
+@code{TARGET_INIT_LIBFUNCS} to @code{gofast_maybe_init_libfuncs}, or
+else call that function from its version of that hook. It is defined
+in @file{config/gofast.h}, which must be included by your
+architecture's @file{@var{cpu}.c} file. See @file{sparc/sparc.c} for
+an example.
+
+If this macro is defined, the
+@code{TARGET_FLOAT_LIB_COMPARE_RETURNS_BOOL} target hook must return
+false for @code{SFmode} and @code{DFmode} comparisons.
+@end defmac
-@findex TARGET_EDOM
@cindex @code{EDOM}, implicit usage
-@item TARGET_EDOM
+@findex matherr
+@defmac TARGET_EDOM
The value of @code{EDOM} on the target machine, as a C integer constant
expression. If you don't define this macro, GCC does not attempt to
deposit the value of @code{EDOM} into @code{errno} directly. Look in
@@ -4704,37 +4761,37 @@ domain errors by calling the library function and letting it report the
error. If mathematical functions on your system use @code{matherr} when
there is an error, then you should leave @code{TARGET_EDOM} undefined so
that @code{matherr} is used normally.
+@end defmac
-@findex GEN_ERRNO_RTX
@cindex @code{errno}, implicit usage
-@item GEN_ERRNO_RTX
+@defmac GEN_ERRNO_RTX
Define this macro as a C expression to create an rtl expression that
refers to the global ``variable'' @code{errno}. (On certain systems,
@code{errno} may not actually be a variable.) If you don't define this
macro, a reasonable default is used.
+@end defmac
-@findex TARGET_MEM_FUNCTIONS
@cindex @code{bcopy}, implicit usage
@cindex @code{memcpy}, implicit usage
@cindex @code{memmove}, implicit usage
@cindex @code{bzero}, implicit usage
@cindex @code{memset}, implicit usage
-@item TARGET_MEM_FUNCTIONS
+@defmac TARGET_MEM_FUNCTIONS
Define this macro if GCC should generate calls to the ISO C
(and System V) library functions @code{memcpy}, @code{memmove} and
@code{memset} rather than the BSD functions @code{bcopy} and @code{bzero}.
+@end defmac
+
+@cindex C99 math functions, implicit usage
+@defmac TARGET_C99_FUNCTIONS
+When this macro is nonzero, GCC will implicitly optimize @code{sin} calls into
+@code{sinf} and similarly for other functions defined by C99 standard. The
+default is nonzero that should be proper value for most modern systems, however
+number of existing systems lacks support for these functions in the runtime so
+they needs this macro to be redefined to 0.
+@end defmac
-@findex LIBGCC_NEEDS_DOUBLE
-@item LIBGCC_NEEDS_DOUBLE
-Define this macro if @code{float} arguments cannot be passed to library
-routines (so they must be converted to @code{double}). This macro
-affects both how library calls are generated and how the library
-routines in @file{libgcc.a} accept their arguments. It is useful on
-machines where floating and fixed point arguments are passed
-differently, such as the i860.
-
-@findex NEXT_OBJC_RUNTIME
-@item NEXT_OBJC_RUNTIME
+@defmac NEXT_OBJC_RUNTIME
Define this macro to generate code for Objective-C message sending using
the calling convention of the NeXT system. This calling convention
involves passing the object, the selector and the method arguments all
@@ -4742,7 +4799,7 @@ at once to the method-lookup library function.
The default calling convention passes just the object and the selector
to the lookup function, which returns a pointer to the method.
-@end table
+@end defmac
@node Addressing Modes
@section Addressing Modes
@@ -4751,55 +4808,50 @@ to the lookup function, which returns a pointer to the method.
@c prevent bad page break with this line
This is about addressing modes.
-@table @code
-@findex HAVE_PRE_INCREMENT
-@findex HAVE_PRE_DECREMENT
-@findex HAVE_POST_INCREMENT
-@findex HAVE_POST_DECREMENT
-@item HAVE_PRE_INCREMENT
-@itemx HAVE_PRE_DECREMENT
-@itemx HAVE_POST_INCREMENT
-@itemx HAVE_POST_DECREMENT
+@defmac HAVE_PRE_INCREMENT
+@defmacx HAVE_PRE_DECREMENT
+@defmacx HAVE_POST_INCREMENT
+@defmacx HAVE_POST_DECREMENT
A C expression that is nonzero if the machine supports pre-increment,
pre-decrement, post-increment, or post-decrement addressing respectively.
+@end defmac
-@findex HAVE_POST_MODIFY_DISP
-@findex HAVE_PRE_MODIFY_DISP
-@item HAVE_PRE_MODIFY_DISP
-@itemx HAVE_POST_MODIFY_DISP
+@defmac HAVE_PRE_MODIFY_DISP
+@defmacx HAVE_POST_MODIFY_DISP
A C expression that is nonzero if the machine supports pre- or
post-address side-effect generation involving constants other than
the size of the memory operand.
+@end defmac
-@findex HAVE_POST_MODIFY_REG
-@findex HAVE_PRE_MODIFY_REG
-@item HAVE_PRE_MODIFY_REG
-@itemx HAVE_POST_MODIFY_REG
+@defmac HAVE_PRE_MODIFY_REG
+@defmacx HAVE_POST_MODIFY_REG
A C expression that is nonzero if the machine supports pre- or
post-address side-effect generation involving a register displacement.
+@end defmac
-@findex CONSTANT_ADDRESS_P
-@item CONSTANT_ADDRESS_P (@var{x})
+@defmac CONSTANT_ADDRESS_P (@var{x})
A C expression that is 1 if the RTX @var{x} is a constant which
is a valid address. On most machines, this can be defined as
@code{CONSTANT_P (@var{x})}, but a few machines are more restrictive
in which constant addresses are supported.
+@end defmac
-@findex CONSTANT_P
-@code{CONSTANT_P} accepts integer-values expressions whose values are
-not explicitly known, such as @code{symbol_ref}, @code{label_ref}, and
-@code{high} expressions and @code{const} arithmetic expressions, in
-addition to @code{const_int} and @code{const_double} expressions.
+@defmac CONSTANT_P (@var{x})
+@code{CONSTANT_P}, which is defined by target-independent code,
+accepts integer-values expressions whose values are not explicitly
+known, such as @code{symbol_ref}, @code{label_ref}, and @code{high}
+expressions and @code{const} arithmetic expressions, in addition to
+@code{const_int} and @code{const_double} expressions.
+@end defmac
-@findex MAX_REGS_PER_ADDRESS
-@item MAX_REGS_PER_ADDRESS
+@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
accept.
+@end defmac
-@findex GO_IF_LEGITIMATE_ADDRESS
-@item GO_IF_LEGITIMATE_ADDRESS (@var{mode}, @var{x}, @var{label})
+@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}.
@@ -4851,21 +4903,9 @@ 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
-@findex saveable_obstack
-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 @code{saveable_obstack}. You will have to modify
-@code{ASM_OUTPUT_LABELREF} to remove and decode the added text and
-output the name accordingly, and define @code{TARGET_STRIP_NAME_ENCODING}
-to access the original name string.
-
-You can check the information stored here into the @code{symbol_ref} in
-the definitions of the macros @code{GO_IF_LEGITIMATE_ADDRESS} and
-@code{PRINT_OPERAND_ADDRESS}.
-
-@findex REG_OK_FOR_BASE_P
-@item REG_OK_FOR_BASE_P (@var{x})
+@defmac REG_OK_FOR_BASE_P (@var{x})
A C expression that is nonzero if @var{x} (assumed to be a @code{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
@@ -4873,18 +4913,18 @@ others. Whether the macro accepts or rejects pseudo registers must be
controlled by @code{REG_OK_STRICT} as described above. This usually
requires two variant definitions, of which @code{REG_OK_STRICT}
controls the one actually used.
+@end defmac
-@findex REG_MODE_OK_FOR_BASE_P
-@item REG_MODE_OK_FOR_BASE_P (@var{x}, @var{mode})
+@defmac REG_MODE_OK_FOR_BASE_P (@var{x}, @var{mode})
A C expression that is just like @code{REG_OK_FOR_BASE_P}, except that
that expression may examine the mode of the memory reference in
@var{mode}. You should define this macro if the mode of the memory
reference affects whether a register may be used as a base register. If
you define this macro, the compiler will use it instead of
@code{REG_OK_FOR_BASE_P}.
+@end defmac
-@findex REG_OK_FOR_INDEX_P
-@item REG_OK_FOR_INDEX_P (@var{x})
+@defmac REG_OK_FOR_INDEX_P (@var{x})
A C expression that is nonzero if @var{x} (assumed to be a @code{reg}
RTX) is valid for use as an index register.
@@ -4896,9 +4936,9 @@ labeling is used must fit the machine's constraints of which registers
may serve in each capacity. The compiler will try both labelings,
looking for one that is valid, and will reload one or both registers
only if neither labeling works.
+@end defmac
-@findex FIND_BASE_TERM
-@item FIND_BASE_TERM (@var{x})
+@defmac FIND_BASE_TERM (@var{x})
A C expression to determine the base term of address @var{x}.
This macro is used in only one place: `find_base_term' in alias.c.
@@ -4907,16 +4947,16 @@ that alias analysis can understand machine-dependent addresses.
The typical use of this macro is to handle addresses containing
a label_ref or symbol_ref within an UNSPEC@.
+@end defmac
-@findex LEGITIMIZE_ADDRESS
-@item LEGITIMIZE_ADDRESS (@var{x}, @var{oldx}, @var{mode}, @var{win})
+@defmac LEGITIMIZE_ADDRESS (@var{x}, @var{oldx}, @var{mode}, @var{win})
A C compound statement that attempts to replace @var{x} with a valid
memory address for an operand of mode @var{mode}. @var{win} will be a
C statement label elsewhere in the code; the macro definition may use
-@example
+@smallexample
GO_IF_LEGITIMATE_ADDRESS (@var{mode}, @var{x}, @var{win});
-@end example
+@end smallexample
@noindent
to avoid further processing if the address has become legitimate.
@@ -4934,9 +4974,9 @@ It is not necessary for this macro to come up with a legitimate
address. The compiler has standard ways of doing so in all cases. In
fact, it is safe for this macro to do nothing. But often a
machine-dependent strategy can generate better code.
+@end defmac
-@findex LEGITIMIZE_RELOAD_ADDRESS
-@item LEGITIMIZE_RELOAD_ADDRESS (@var{x}, @var{mode}, @var{opnum}, @var{type}, @var{ind_levels}, @var{win})
+@defmac LEGITIMIZE_RELOAD_ADDRESS (@var{x}, @var{mode}, @var{opnum}, @var{type}, @var{ind_levels}, @var{win})
A C compound statement that attempts to replace @var{x}, which is an address
that needs reloading, with a valid memory address for an operand of mode
@var{mode}. @var{win} will be a C statement label elsewhere in the code.
@@ -4983,9 +5023,9 @@ single level of rtl. Thus, if the part to be changed is not at the
top level, you'll need to replace first the top level.
It is not necessary for this macro to come up with a legitimate
address; but often a machine-dependent strategy can generate better code.
+@end defmac
-@findex GO_IF_MODE_DEPENDENT_ADDRESS
-@item GO_IF_MODE_DEPENDENT_ADDRESS (@var{addr}, @var{label})
+@defmac GO_IF_MODE_DEPENDENT_ADDRESS (@var{addr}, @var{label})
A C statement or compound statement with a conditional @code{goto
@var{label};} executed if memory address @var{x} (an RTX) can have
different meanings depending on the machine mode of the memory
@@ -4998,15 +5038,15 @@ of the operand being addressed. Some machines have other mode-dependent
addresses. Many RISC machines have no mode-dependent addresses.
You may assume that @var{addr} is a valid address for the machine.
+@end defmac
-@findex LEGITIMATE_CONSTANT_P
-@item LEGITIMATE_CONSTANT_P (@var{x})
+@defmac LEGITIMATE_CONSTANT_P (@var{x})
A C expression that is nonzero if @var{x} is a legitimate constant for
an immediate operand on the target machine. You can assume that
@var{x} satisfies @code{CONSTANT_P}, so you need not check this. In fact,
@samp{1} is a suitable definition for this macro on machines where
anything @code{CONSTANT_P} is valid.
-@end table
+@end defmac
@node Condition Code
@section Condition Code Status
@@ -5026,25 +5066,23 @@ Sometimes additional machine-specific flags must be defined in the machine
description header file. It can also add additional machine-specific
information by defining @code{CC_STATUS_MDEP}.
-@table @code
-@findex CC_STATUS_MDEP
-@item CC_STATUS_MDEP
+@defmac CC_STATUS_MDEP
C code for a data type which is used for declaring the @code{mdep}
component of @code{cc_status}. It defaults to @code{int}.
This macro is not used on machines that do not use @code{cc0}.
+@end defmac
-@findex CC_STATUS_MDEP_INIT
-@item CC_STATUS_MDEP_INIT
+@defmac CC_STATUS_MDEP_INIT
A C expression to initialize the @code{mdep} field to ``empty''.
The default definition does nothing, since most machines don't use
the field anyway. If you want to use the field, you should probably
define this macro to initialize it.
This macro is not used on machines that do not use @code{cc0}.
+@end defmac
-@findex NOTICE_UPDATE_CC
-@item NOTICE_UPDATE_CC (@var{exp}, @var{insn})
+@defmac NOTICE_UPDATE_CC (@var{exp}, @var{insn})
A C compound statement to set the components of @code{cc_status}
appropriately for an insn @var{insn} whose body is @var{exp}. It is
this macro's responsibility to recognize insns that set the condition
@@ -5079,34 +5117,9 @@ A possible definition of @code{NOTICE_UPDATE_CC} is to call a function
that looks at an attribute (@pxref{Insn Attributes}) named, for example,
@samp{cc}. This avoids having detailed information about patterns in
two places, the @file{md} file and in @code{NOTICE_UPDATE_CC}.
+@end defmac
-@findex EXTRA_CC_MODES
-@item EXTRA_CC_MODES
-Condition codes are represented in registers by machine modes of class
-@code{MODE_CC}. By default, there is just one mode, @code{CCmode}, with
-this class. If you need more such modes, create a file named
-@file{@var{machine}-modes.def} in your @file{config/@var{machine}}
-directory (@pxref{Back End, , Anatomy of a Target Back End}), containing
-a list of these modes. Each entry in the list should be a call to the
-macro @code{CC}. This macro takes one argument, which is the name of
-the mode: it should begin with @samp{CC}. Do not put quotation marks
-around the name, or include the trailing @samp{mode}; these are
-automatically added. There should not be anything else in the file
-except comments.
-
-A sample @file{@var{machine}-modes.def} file might look like this:
-
-@smallexample
-CC (CC_NOOV) /* @r{Comparison only valid if there was no overflow.} */
-CC (CCFP) /* @r{Floating point comparison that cannot trap.} */
-CC (CCFPE) /* @r{Floating point comparison that may trap.} */
-@end smallexample
-
-When you create this file, the macro @code{EXTRA_CC_MODES} is
-automatically defined by @command{configure}, with value @samp{1}.
-
-@findex SELECT_CC_MODE
-@item SELECT_CC_MODE (@var{op}, @var{x}, @var{y})
+@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
@@ -5122,10 +5135,11 @@ definition)
? CC_NOOVmode : CCmode))
@end smallexample
-You need not define this macro if @code{EXTRA_CC_MODES} is not defined.
+You should define this macro if and only if you define extra CC modes
+in @file{@var{machine}-modes.def}.
+@end defmac
-@findex CANONICALIZE_COMPARISON
-@item CANONICALIZE_COMPARISON (@var{code}, @var{op0}, @var{op1})
+@defmac CANONICALIZE_COMPARISON (@var{code}, @var{op0}, @var{op1})
On some machines not all possible comparisons are defined, but you can
convert an invalid comparison into a valid one. For example, the Alpha
does not have a @code{GT} comparison, but you can use an @code{LT}
@@ -5143,9 +5157,9 @@ valid but will see if the resulting insn matches a pattern in the
You need not define this macro if it would never change the comparison
code or operands.
+@end defmac
-@findex REVERSIBLE_CC_MODE
-@item REVERSIBLE_CC_MODE (@var{mode})
+@defmac REVERSIBLE_CC_MODE (@var{mode})
A C expression whose value is one if it is always safe to reverse a
comparison whose mode is @var{mode}. If @code{SELECT_CC_MODE}
can ever return @var{mode} for a floating-point inequality comparison,
@@ -5159,8 +5173,9 @@ inequality comparisons are always given @code{CCFPEmode}:
@smallexample
#define REVERSIBLE_CC_MODE(MODE) ((MODE) != CCFPEmode)
@end smallexample
+@end defmac
-@findex REVERSE_CONDITION (@var{code}, @var{mode})
+@defmac REVERSE_CONDITION (@var{code}, @var{mode})
A C expression whose value is reversed condition code of the @var{code} for
comparison done in CC_MODE @var{mode}. The macro is used only in case
@code{REVERSIBLE_CC_MODE (@var{mode})} is nonzero. Define this macro in case
@@ -5174,9 +5189,9 @@ like:
((MODE) != CCFPmode ? reverse_condition (CODE) \
: reverse_condition_maybe_unordered (CODE))
@end smallexample
+@end defmac
-@findex REVERSE_CONDEXEC_PREDICATES_P
-@item REVERSE_CONDEXEC_PREDICATES_P (@var{code1}, @var{code2})
+@defmac REVERSE_CONDEXEC_PREDICATES_P (@var{code1}, @var{code2})
A C expression that returns true if the conditional execution predicate
@var{code1} is the inverse of @var{code2} and vice versa. Define this to
return 0 if the target has conditional execution predicates that cannot be
@@ -5187,8 +5202,35 @@ follows:
#define REVERSE_CONDEXEC_PREDICATES_P (x, y) \
((x) == reverse_condition (y))
@end smallexample
+@end defmac
-@end table
+@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
+regular CSE passes are often not able to identify cases in which the
+hard register is set to a common value. Use this hook to enable a
+small pass which optimizes such cases. This hook should return true
+to enable this pass, and it should set the integers to which its
+arguments point to the hard register numbers used for condition codes.
+When there is only one such register, as is true on most systems, the
+integer pointed to by the second argument should be set to
+@code{INVALID_REGNUM}.
+
+The default version of this hook returns false.
+@end deftypefn
+
+@deftypefn {Target Hook} enum machine_mode TARGET_CC_MODES_COMPATIBLE (enum machine_mode, enum machine_mode)
+On targets which use multiple condition code modes in class
+@code{MODE_CC}, it is sometimes the case that a comparison can be
+validly done in more than one mode. On such a system, define this
+target hook to take two mode arguments and to return a mode in which
+both comparisons may be validly done. If there is no such mode,
+return @code{VOIDmode}.
+
+The default version of this hook checks whether the modes are the
+same. If they are, it returns that mode. If they are different, it
+returns @code{VOIDmode}.
+@end deftypefn
@node Costs
@section Describing Relative Costs of Operations
@@ -5199,94 +5241,7 @@ follows:
These macros let you describe the relative speed of various operations
on the target machine.
-@table @code
-@findex CONST_COSTS
-@item CONST_COSTS (@var{x}, @var{code}, @var{outer_code})
-A part of a C @code{switch} statement that describes the relative costs
-of constant RTL expressions. It must contain @code{case} labels for
-expression codes @code{const_int}, @code{const}, @code{symbol_ref},
-@code{label_ref} and @code{const_double}. Each case must ultimately
-reach a @code{return} statement to return the relative cost of the use
-of that kind of constant value in an expression. The cost may depend on
-the precise value of the constant, which is available for examination in
-@var{x}, and the rtx code of the expression in which it is contained,
-found in @var{outer_code}.
-
-@var{code} is the expression code---redundant, since it can be
-obtained with @code{GET_CODE (@var{x})}.
-
-@findex RTX_COSTS
-@findex COSTS_N_INSNS
-@item RTX_COSTS (@var{x}, @var{code}, @var{outer_code})
-Like @code{CONST_COSTS} but applies to nonconstant RTL expressions.
-This can be used, for example, to indicate how costly a multiply
-instruction is. In writing this macro, you can use the construct
-@code{COSTS_N_INSNS (@var{n})} to specify a cost equal to @var{n} fast
-instructions. @var{outer_code} is the code of the expression in which
-@var{x} is contained.
-
-This macro is optional; do not define it if the default cost assumptions
-are adequate for the target machine.
-
-@findex DEFAULT_RTX_COSTS
-@item DEFAULT_RTX_COSTS (@var{x}, @var{code}, @var{outer_code})
-This macro, if defined, is called for any case not handled by the
-@code{RTX_COSTS} or @code{CONST_COSTS} macros. This eliminates the need
-to put case labels into the macro, but the code, or any functions it
-calls, must assume that the RTL in @var{x} could be of any type that has
-not already been handled. The arguments are the same as for
-@code{RTX_COSTS}, and the macro should execute a return statement giving
-the cost of any RTL expressions that it can handle. The default cost
-calculation is used for any RTL for which this macro does not return a
-value.
-
-This macro is optional; do not define it if the default cost assumptions
-are adequate for the target machine.
-
-@findex ADDRESS_COST
-@item ADDRESS_COST (@var{address})
-An expression giving the cost of an addressing mode that contains
-@var{address}. If not defined, the cost is computed from
-the @var{address} expression and the @code{CONST_COSTS} values.
-
-For most CISC machines, the default cost is a good approximation of the
-true cost of the addressing mode. However, on RISC machines, all
-instructions normally have the same length and execution time. Hence
-all addresses will have equal costs.
-
-In cases where more than one form of an address is known, the form with
-the lowest cost will be used. If multiple forms have the same, lowest,
-cost, the one that is the most complex will be used.
-
-For example, suppose an address that is equal to the sum of a register
-and a constant is used twice in the same basic block. When this macro
-is not defined, the address will be computed in a register and memory
-references will be indirect through that register. On machines where
-the cost of the addressing mode containing the sum is no higher than
-that of a simple indirect reference, this will produce an additional
-instruction and possibly require an additional register. Proper
-specification of this macro eliminates this overhead for such machines.
-
-Similar use of this macro is made in strength reduction of loops.
-
-@var{address} need not be valid as an address. In such a case, the cost
-is not relevant and can be any value; invalid addresses need not be
-assigned a different cost.
-
-On machines where an address involving more than one register is as
-cheap as an address computation involving only one register, defining
-@code{ADDRESS_COST} to reflect this can cause two registers to be live
-over a region of code where only one would have been if
-@code{ADDRESS_COST} were not defined in that manner. This effect should
-be considered in the definition of this macro. Equivalent costs should
-probably only be given to addresses with different numbers of registers
-on machines with lots of registers.
-
-This macro will normally either not be defined or be defined as a
-constant.
-
-@findex REGISTER_MOVE_COST
-@item REGISTER_MOVE_COST (@var{mode}, @var{from}, @var{to})
+@defmac REGISTER_MOVE_COST (@var{mode}, @var{from}, @var{to})
A C expression for the cost of moving data of mode @var{mode} from a
register in class @var{from} to one in class @var{to}. The classes are
expressed using the enumeration values such as @code{GENERAL_REGS}. A
@@ -5303,9 +5258,9 @@ classes returns a value of 2, reload does not check to ensure that the
constraints of the insn are met. Setting a cost of other than 2 will
allow reload to verify that the constraints are met. You should do this
if the @samp{mov@var{m}} pattern's constraints do not allow such copying.
+@end defmac
-@findex MEMORY_MOVE_COST
-@item MEMORY_MOVE_COST (@var{mode}, @var{class}, @var{in})
+@defmac MEMORY_MOVE_COST (@var{mode}, @var{class}, @var{in})
A C expression for the cost of moving data of mode @var{mode} between a
register of class @var{class} and memory; @var{in} is zero if the value
is to be written to memory, nonzero if it is to be read in. This cost
@@ -5327,20 +5282,18 @@ secondary register in the conventional way but the default base value of
4 is not correct for your machine, define this macro to add some other
value to the result of that function. The arguments to that function
are the same as to this macro.
+@end defmac
-@findex BRANCH_COST
-@item BRANCH_COST
+@defmac BRANCH_COST
A C expression for the cost of a branch instruction. A value of 1 is
the default; other values are interpreted relative to that.
-@end table
+@end defmac
Here are additional macros which do not specify precise relative costs,
but only that certain actions are more expensive than GCC would
ordinarily expect.
-@table @code
-@findex SLOW_BYTE_ACCESS
-@item SLOW_BYTE_ACCESS
+@defmac SLOW_BYTE_ACCESS
Define this macro as a C expression which is nonzero if accessing less
than a word of memory (i.e.@: a @code{char} or a @code{short}) is no
faster than accessing a word of memory, i.e., if such access
@@ -5353,9 +5306,9 @@ load will be used if alignment permits. Unless bytes accesses are
faster than word accesses, using word accesses is preferable since it
may eliminate subsequent memory access if subsequent accesses occur to
other fields in the same word of the structure, but to different bytes.
+@end defmac
-@findex SLOW_UNALIGNED_ACCESS
-@item SLOW_UNALIGNED_ACCESS (@var{mode}, @var{alignment})
+@defmac SLOW_UNALIGNED_ACCESS (@var{mode}, @var{alignment})
Define this macro to be the value 1 if memory accesses described by the
@var{mode} and @var{alignment} parameters have a cost many times greater
than aligned accesses, for example if they are emulated in a trap
@@ -5370,15 +5323,9 @@ cycle or two to the time for a memory access.
If the value of this macro is always zero, it need not be defined. If
this macro is defined, it should produce a nonzero value when
@code{STRICT_ALIGNMENT} is nonzero.
+@end defmac
-@findex DONT_REDUCE_ADDR
-@item DONT_REDUCE_ADDR
-Define this macro to inhibit strength reduction of memory addresses.
-(On some machines, such strength reduction seems to do harm rather
-than good.)
-
-@findex MOVE_RATIO
-@item MOVE_RATIO
+@defmac MOVE_RATIO
The threshold of number of scalar memory-to-memory move insns, @emph{below}
which a sequence of insns should be generated instead of a
string move insn or a library call. Increasing the value will always
@@ -5389,94 +5336,165 @@ Note that on machines where the corresponding move insn is a
the number of such sequences.
If you don't define this, a reasonable default is used.
+@end defmac
-@findex MOVE_BY_PIECES_P
-@item MOVE_BY_PIECES_P (@var{size}, @var{alignment})
+@defmac MOVE_BY_PIECES_P (@var{size}, @var{alignment})
A C expression used to determine whether @code{move_by_pieces} will be used to
copy a chunk of memory, or whether some other block move mechanism
will be used. Defaults to 1 if @code{move_by_pieces_ninsns} returns less
than @code{MOVE_RATIO}.
+@end defmac
-@findex MOVE_MAX_PIECES
-@item MOVE_MAX_PIECES
+@defmac MOVE_MAX_PIECES
A C expression used by @code{move_by_pieces} to determine the largest unit
a load or store used to copy memory is. Defaults to @code{MOVE_MAX}.
+@end defmac
-@findex CLEAR_RATIO
-@item CLEAR_RATIO
+@defmac CLEAR_RATIO
The threshold of number of scalar move insns, @emph{below} which a sequence
of insns should be generated to clear memory instead of a string clear insn
or a library call. Increasing the value will always make code faster, but
eventually incurs high cost in increased code size.
If you don't define this, a reasonable default is used.
+@end defmac
-@findex CLEAR_BY_PIECES_P
-@item CLEAR_BY_PIECES_P (@var{size}, @var{alignment})
+@defmac CLEAR_BY_PIECES_P (@var{size}, @var{alignment})
A C expression used to determine whether @code{clear_by_pieces} will be used
to clear a chunk of memory, or whether some other block clear mechanism
will be used. Defaults to 1 if @code{move_by_pieces_ninsns} returns less
than @code{CLEAR_RATIO}.
+@end defmac
+
+@defmac STORE_BY_PIECES_P (@var{size}, @var{alignment})
+A C expression used to determine whether @code{store_by_pieces} will be
+used to set a chunk of memory to a constant value, or whether some other
+mechanism will be used. Used by @code{__builtin_memset} when storing
+values other than constant zero and by @code{__builtin_strcpy} when
+when called with a constant source string.
+Defaults to @code{MOVE_BY_PIECES_P}.
+@end defmac
-@findex USE_LOAD_POST_INCREMENT
-@item USE_LOAD_POST_INCREMENT (@var{mode})
+@defmac USE_LOAD_POST_INCREMENT (@var{mode})
A C expression used to determine whether a load postincrement is a good
thing to use for a given mode. Defaults to the value of
@code{HAVE_POST_INCREMENT}.
+@end defmac
-@findex USE_LOAD_POST_DECREMENT
-@item USE_LOAD_POST_DECREMENT (@var{mode})
+@defmac USE_LOAD_POST_DECREMENT (@var{mode})
A C expression used to determine whether a load postdecrement is a good
thing to use for a given mode. Defaults to the value of
@code{HAVE_POST_DECREMENT}.
+@end defmac
-@findex USE_LOAD_PRE_INCREMENT
-@item USE_LOAD_PRE_INCREMENT (@var{mode})
+@defmac USE_LOAD_PRE_INCREMENT (@var{mode})
A C expression used to determine whether a load preincrement is a good
thing to use for a given mode. Defaults to the value of
@code{HAVE_PRE_INCREMENT}.
+@end defmac
-@findex USE_LOAD_PRE_DECREMENT
-@item USE_LOAD_PRE_DECREMENT (@var{mode})
+@defmac USE_LOAD_PRE_DECREMENT (@var{mode})
A C expression used to determine whether a load predecrement is a good
thing to use for a given mode. Defaults to the value of
@code{HAVE_PRE_DECREMENT}.
+@end defmac
-@findex USE_STORE_POST_INCREMENT
-@item USE_STORE_POST_INCREMENT (@var{mode})
+@defmac USE_STORE_POST_INCREMENT (@var{mode})
A C expression used to determine whether a store postincrement is a good
thing to use for a given mode. Defaults to the value of
@code{HAVE_POST_INCREMENT}.
+@end defmac
-@findex USE_STORE_POST_DECREMENT
-@item USE_STORE_POST_DECREMENT (@var{mode})
+@defmac USE_STORE_POST_DECREMENT (@var{mode})
A C expression used to determine whether a store postdecrement is a good
thing to use for a given mode. Defaults to the value of
@code{HAVE_POST_DECREMENT}.
+@end defmac
-@findex USE_STORE_PRE_INCREMENT
-@item USE_STORE_PRE_INCREMENT (@var{mode})
+@defmac USE_STORE_PRE_INCREMENT (@var{mode})
This macro is used to determine whether a store preincrement is a good
thing to use for a given mode. Defaults to the value of
@code{HAVE_PRE_INCREMENT}.
+@end defmac
-@findex USE_STORE_PRE_DECREMENT
-@item USE_STORE_PRE_DECREMENT (@var{mode})
+@defmac USE_STORE_PRE_DECREMENT (@var{mode})
This macro is used to determine whether a store predecrement is a good
thing to use for a given mode. Defaults to the value of
@code{HAVE_PRE_DECREMENT}.
+@end defmac
-@findex NO_FUNCTION_CSE
-@item NO_FUNCTION_CSE
+@defmac NO_FUNCTION_CSE
Define this macro if it is as good or better to call a constant
function address than to call an address kept in a register.
+@end defmac
-@findex NO_RECURSIVE_FUNCTION_CSE
-@item NO_RECURSIVE_FUNCTION_CSE
+@defmac NO_RECURSIVE_FUNCTION_CSE
Define this macro if it is as good or better for a function to call
itself with an explicit address than to call an address kept in a
register.
-@end table
+@end defmac
+
+@defmac RANGE_TEST_NON_SHORT_CIRCUIT
+Define this macro if a non-short-circuit operation produced by
+@samp{fold_range_test ()} is optimal. This macro defaults to true if
+@code{BRANCH_COST} is greater than or equal to the value 2.
+@end defmac
+
+@deftypefn {Target Hook} bool TARGET_RTX_COSTS (rtx @var{x}, int @var{code}, int @var{outer_code}, int *@var{total})
+This target hook describes the relative costs of RTL expressions.
+
+The cost may depend on the precise form of the expression, which is
+available for examination in @var{x}, and the rtx code of the expression
+in which it is contained, found in @var{outer_code}. @var{code} is the
+expression code---redundant, since it can be obtained with
+@code{GET_CODE (@var{x})}.
+
+In implementing this hook, you can use the construct
+@code{COSTS_N_INSNS (@var{n})} to specify a cost equal to @var{n} fast
+instructions.
+
+On entry to the hook, @code{*@var{total}} contains a default estimate
+for the cost of the expression. The hook should modify this value as
+necessary.
+
+The hook returns true when all subexpressions of @var{x} have been
+processed, and false when @code{rtx_cost} should recurse.
+@end deftypefn
+
+@deftypefn {Target Hook} int TARGET_ADDRESS_COST (rtx @var{address})
+This hook computes the cost of an addressing mode that contains
+@var{address}. If not defined, the cost is computed from
+the @var{address} expression and the @code{TARGET_RTX_COST} hook.
+
+For most CISC machines, the default cost is a good approximation of the
+true cost of the addressing mode. However, on RISC machines, all
+instructions normally have the same length and execution time. Hence
+all addresses will have equal costs.
+
+In cases where more than one form of an address is known, the form with
+the lowest cost will be used. If multiple forms have the same, lowest,
+cost, the one that is the most complex will be used.
+
+For example, suppose an address that is equal to the sum of a register
+and a constant is used twice in the same basic block. When this macro
+is not defined, the address will be computed in a register and memory
+references will be indirect through that register. On machines where
+the cost of the addressing mode containing the sum is no higher than
+that of a simple indirect reference, this will produce an additional
+instruction and possibly require an additional register. Proper
+specification of this macro eliminates this overhead for such machines.
+
+This hook is never called with an invalid address.
+
+On machines where an address involving more than one register is as
+cheap as an address computation involving only one register, defining
+@code{TARGET_ADDRESS_COST} to reflect this can cause two registers to
+be live over a region of code where only one would have been if
+@code{TARGET_ADDRESS_COST} were not defined in that manner. This effect
+should be considered in the definition of this macro. Equivalent costs
+should probably only be given to addresses with different numbers of
+registers on machines with lots of registers.
+@end deftypefn
@node Scheduling
@section Adjusting the Instruction Scheduler
@@ -5504,13 +5522,15 @@ to return the value of the macro @code{MAX_DFA_ISSUE_RATE}.
@deftypefn {Target Hook} int TARGET_SCHED_VARIABLE_ISSUE (FILE *@var{file}, int @var{verbose}, rtx @var{insn}, int @var{more})
This hook is executed by the scheduler after it has scheduled an insn
from the ready list. It should return the number of insns which can
-still be issued in the current cycle. Normally this is
-@samp{@w{@var{more} - 1}}. You should define this hook if some insns
-take more machine resources than others, so that fewer insns can follow
-them in the same cycle. @var{file} is either a null pointer, or a stdio
-stream to write any debug output to. @var{verbose} is the verbose level
-provided by @option{-fsched-verbose-@var{n}}. @var{insn} is the
-instruction that was scheduled.
+still be issued in the current cycle. The default is
+@samp{@w{@var{more} - 1}} for insns other than @code{CLOBBER} and
+@code{USE}, which normally are not counted against the issue rate.
+You should define this hook if some insns take more machine resources
+than others, so that fewer insns can follow them in the same cycle.
+@var{file} is either a null pointer, or a stdio stream to write any
+debug output to. @var{verbose} is the verbose level provided by
+@option{-fsched-verbose-@var{n}}. @var{insn} is the instruction that
+was scheduled.
@end deftypefn
@deftypefn {Target Hook} int TARGET_SCHED_ADJUST_COST (rtx @var{insn}, rtx @var{link}, rtx @var{dep_insn}, int @var{cost})
@@ -5564,6 +5584,16 @@ scheduling one insn causes other insns to become ready in the same
cycle. These other insns can then be taken into account properly.
@end deftypefn
+@deftypefn {Target Hook} void TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK (rtx @var{head}, rtx @var{tail})
+This hook is called after evaluation forward dependencies of insns in
+chain given by two parameter values (@var{head} and @var{tail}
+correspondingly) but before insns scheduling of the insn chain. For
+example, it can be used for better insn classification if it requires
+analysis of dependencies. This hook can use backward and forward
+dependencies of the insn scheduler because they are already
+calculated.
+@end deftypefn
+
@deftypefn {Target Hook} void TARGET_SCHED_INIT (FILE *@var{file}, int @var{verbose}, int @var{max_ready})
This hook is executed by the scheduler at the beginning of each block of
instructions that are to be scheduled. @var{file} is either a null
@@ -5650,6 +5680,30 @@ schedules to choose the best one.
The default is no multipass scheduling.
@end deftypefn
+@deftypefn {Target Hook} int TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD (rtx)
+
+This hook controls what insns from the ready insn queue will be
+considered for the multipass insn scheduling. If the hook returns
+zero for insn passed as the parameter, the insn will be not chosen to
+be issued.
+
+The default is that any ready insns can be chosen to be issued.
+@end deftypefn
+
+@deftypefn {Target Hook} int TARGET_SCHED_DFA_NEW_CYCLE (FILE *, int, rtx, int, int, int *)
+
+This hook is called by the insn scheduler before issuing insn passed
+as the third parameter on given cycle. If the hook returns nonzero,
+the insn is not issued on given processors cycle. Instead of that,
+the processor cycle is advanced. If the value passed through the last
+parameter is zero, the insn ready queue is not sorted on the new cycle
+start as usually. The first parameter passes file for debugging
+output. The second one passes the scheduler verbose level of the
+debugging output. The forth and the fifth parameter values are
+correspondingly processor cycle on which the previous insn has been
+issued and the current processor cycle.
+@end deftypefn
+
@deftypefn {Target Hook} void TARGET_SCHED_INIT_DFA_BUBBLES (void)
The @acronym{DFA}-based scheduler could take the insertion of nop
operations for better insn scheduling into account. It can be done
@@ -5685,37 +5739,56 @@ zero. The hook should return @code{NULL} if there are no more nop
insns with indexes greater than given index.
@end deftypefn
+@deftypefn {Target Hook} bool IS_COSTLY_DEPENDENCE (rtx @var{insn1}, rtx @var{insn2}, rtx @var{dep_link}, int @var{dep_cost}, int @var{distance})
+This hook is used to define which dependences are considered costly by
+the target, so costly that it is not advisable to schedule the insns that
+are involved in the dependence too close to one another. The parameters
+to this hook are as follows: The second parameter @var{insn2} is dependent
+upon the first parameter @var{insn1}. The dependence between @var{insn1}
+and @var{insn2} is represented by the third parameter @var{dep_link}. The
+fourth parameter @var{cost} is the cost of the dependence, and the fifth
+parameter @var{distance} is the distance in cycles between the two insns.
+The hook returns @code{true} if considering the distance between the two
+insns the dependence between them is considered costly by the target,
+and @code{false} otherwise.
+
+Defining this hook can be useful in multiple-issue out-of-order machines,
+where (a) it's practically hopeless to predict the actual data/resource
+delays, however: (b) there's a better chance to predict the actual grouping
+that will be formed, and (c) correctly emulating the grouping can be very
+important. In such targets one may want to allow issuing dependent insns
+closer to one another - i.e, closer than the dependence distance; however,
+not in cases of "costly dependences", which this hooks allows to define.
+@end deftypefn
+
Macros in the following table are generated by the program
@file{genattr} and can be useful for writing the hooks.
-@table @code
-@findex TRADITIONAL_PIPELINE_INTERFACE
-@item TRADITIONAL_PIPELINE_INTERFACE
+@defmac TRADITIONAL_PIPELINE_INTERFACE
The macro definition is generated if there is a traditional pipeline
description in @file{.md} file. You should also remember that to
simplify the insn scheduler sources an empty traditional pipeline
description interface is generated even if there is no a traditional
pipeline description in the @file{.md} file. The macro can be used to
distinguish the two types of the traditional interface.
+@end defmac
-@findex DFA_PIPELINE_INTERFACE
-@item DFA_PIPELINE_INTERFACE
+@defmac DFA_PIPELINE_INTERFACE
The macro definition is generated if there is an automaton pipeline
description in @file{.md} file. You should also remember that to
simplify the insn scheduler sources an empty automaton pipeline
description interface is generated even if there is no an automaton
pipeline description in the @file{.md} file. The macro can be used to
distinguish the two types of the automaton interface.
+@end defmac
-@findex MAX_DFA_ISSUE_RATE
-@item MAX_DFA_ISSUE_RATE
+@defmac MAX_DFA_ISSUE_RATE
The macro definition is generated in the automaton based pipeline
description interface. Its value is calculated from the automaton
based pipeline description and is equal to maximal number of all insns
described in constructions @samp{define_insn_reservation} which can be
issued on the same processor cycle.
-
-@end table
+@end defmac
@node Sections
@section Dividing the Output into Sections (Texts, Data, @dots{})
@@ -5733,45 +5806,36 @@ The compiler must tell the assembler when to switch sections. These
macros control what commands to output to tell the assembler this. You
can also define additional sections.
-@table @code
-@findex TEXT_SECTION_ASM_OP
-@item TEXT_SECTION_ASM_OP
+@defmac TEXT_SECTION_ASM_OP
A C expression whose value is a string, including spacing, containing the
assembler operation that should precede instructions and read-only data.
Normally @code{"\t.text"} is right.
+@end defmac
-@findex TEXT_SECTION
-@item TEXT_SECTION
-A C statement that switches to the default section containing instructions.
-Normally this is not needed, as simply defining @code{TEXT_SECTION_ASM_OP}
-is enough. The MIPS port uses this to sort all functions after all data
-declarations.
-
-@findex HOT_TEXT_SECTION_NAME
-@item HOT_TEXT_SECTION_NAME
+@defmac HOT_TEXT_SECTION_NAME
If defined, a C string constant for the name of the section containing most
frequently executed functions of the program. If not defined, GCC will provide
a default definition if the target supports named sections.
+@end defmac
-@findex UNLIKELY_EXECUTED_TEXT_SECTION_NAME
-@item UNLIKELY_EXECUTED_TEXT_SECTION_NAME
+@defmac UNLIKELY_EXECUTED_TEXT_SECTION_NAME
If defined, a C string constant for the name of the section containing unlikely
executed functions in the program.
+@end defmac
-@findex DATA_SECTION_ASM_OP
-@item DATA_SECTION_ASM_OP
+@defmac DATA_SECTION_ASM_OP
A C expression whose value is a string, including spacing, containing the
assembler operation to identify the following data as writable initialized
data. Normally @code{"\t.data"} is right.
+@end defmac
-@findex READONLY_DATA_SECTION_ASM_OP
-@item READONLY_DATA_SECTION_ASM_OP
+@defmac READONLY_DATA_SECTION_ASM_OP
A C expression whose value is a string, including spacing, containing the
assembler operation to identify the following data as read-only initialized
data.
+@end defmac
-@findex READONLY_DATA_SECTION
-@item READONLY_DATA_SECTION
+@defmac READONLY_DATA_SECTION
A macro naming a function to call to switch to the proper section for
read-only data. The default is to use @code{READONLY_DATA_SECTION_ASM_OP}
if defined, else fall back to @code{text_section}.
@@ -5779,15 +5843,15 @@ if defined, else fall back to @code{text_section}.
The most common definition will be @code{data_section}, if the target
does not have a special read-only data section, and does not put data
in the text section.
+@end defmac
-@findex SHARED_SECTION_ASM_OP
-@item SHARED_SECTION_ASM_OP
+@defmac SHARED_SECTION_ASM_OP
If defined, a C expression whose value is a string, including spacing,
containing the assembler operation to identify the following data as
shared data. If not defined, @code{DATA_SECTION_ASM_OP} will be used.
+@end defmac
-@findex BSS_SECTION_ASM_OP
-@item BSS_SECTION_ASM_OP
+@defmac BSS_SECTION_ASM_OP
If defined, a C expression whose value is a string, including spacing,
containing the assembler operation to identify the following data as
uninitialized global data. If not defined, and neither
@@ -5795,30 +5859,23 @@ uninitialized global data. If not defined, and neither
uninitialized global data will be output in the data section if
@option{-fno-common} is passed, otherwise @code{ASM_OUTPUT_COMMON} will be
used.
+@end defmac
-@findex SHARED_BSS_SECTION_ASM_OP
-@item SHARED_BSS_SECTION_ASM_OP
-If defined, a C expression whose value is a string, including spacing,
-containing the assembler operation to identify the following data as
-uninitialized global shared data. If not defined, and
-@code{BSS_SECTION_ASM_OP} is, the latter will be used.
-
-@findex INIT_SECTION_ASM_OP
-@item INIT_SECTION_ASM_OP
+@defmac INIT_SECTION_ASM_OP
If defined, a C expression whose value is a string, including spacing,
containing the assembler operation to identify the following data as
initialization code. If not defined, GCC will assume such a section does
not exist.
+@end defmac
-@findex FINI_SECTION_ASM_OP
-@item FINI_SECTION_ASM_OP
+@defmac FINI_SECTION_ASM_OP
If defined, a C expression whose value is a string, including spacing,
containing the assembler operation to identify the following data as
finalization code. If not defined, GCC will assume such a section does
not exist.
+@end defmac
-@findex CRT_CALL_STATIC_FUNCTION
-@item CRT_CALL_STATIC_FUNCTION (@var{section_op}, @var{function})
+@defmac CRT_CALL_STATIC_FUNCTION (@var{section_op}, @var{function})
If defined, an ASM statement that switches to a different section
via @var{section_op}, calls @var{function}, and switches back to
the text section. This is used in @file{crtstuff.c} if
@@ -5828,40 +5885,40 @@ sections. By default, this macro uses a simple function call. Some
ports need hand-crafted assembly code to avoid dependencies on
registers initialized in the function prologue or to ensure that
constant pools don't end up too far way in the text section.
+@end defmac
-@findex FORCE_CODE_SECTION_ALIGN
-@item FORCE_CODE_SECTION_ALIGN
+@defmac FORCE_CODE_SECTION_ALIGN
If defined, an ASM statement that aligns a code section to some
arbitrary boundary. This is used to force all fragments of the
@code{.init} and @code{.fini} sections to have to same alignment
and thus prevent the linker from having to add any padding.
+@end defmac
-@findex EXTRA_SECTIONS
@findex in_text
@findex in_data
-@item EXTRA_SECTIONS
+@defmac EXTRA_SECTIONS
A list of names for sections other than the standard two, which are
@code{in_text} and @code{in_data}. You need not define this macro
on a system with no other sections (that GCC needs to use).
+@end defmac
-@findex EXTRA_SECTION_FUNCTIONS
@findex text_section
@findex data_section
-@item EXTRA_SECTION_FUNCTIONS
+@defmac EXTRA_SECTION_FUNCTIONS
One or more functions to be defined in @file{varasm.c}. These
functions should do jobs analogous to those of @code{text_section} and
@code{data_section}, for your additional sections. Do not define this
macro if you do not define @code{EXTRA_SECTIONS}.
+@end defmac
-@findex JUMP_TABLES_IN_TEXT_SECTION
-@item JUMP_TABLES_IN_TEXT_SECTION
+@defmac JUMP_TABLES_IN_TEXT_SECTION
Define this macro to be an expression with a nonzero value if jump
tables (for @code{tablejump} insns) should be output in the text
section, along with the assembler instructions. Otherwise, the
readonly data section is used.
This macro is irrelevant if there is no separate readonly data section.
-@end table
+@end defmac
@deftypefn {Target Hook} void TARGET_ASM_SELECT_SECTION (tree @var{exp}, int @var{reloc}, unsigned HOST_WIDE_INT @var{align})
Switches to the appropriate section for output of @var{exp}. You can
@@ -5902,30 +5959,42 @@ constants in @code{flag_pic} mode in @code{data_section} and everything
else in @code{readonly_data_section}.
@end deftypefn
-@deftypefn {Target Hook} void TARGET_ENCODE_SECTION_INFO (tree @var{decl}, int @var{new_decl_p})
+@deftypefn {Target Hook} void TARGET_ENCODE_SECTION_INFO (tree @var{decl}, rtx @var{rtl}, int @var{new_decl_p})
Define this hook if references to a symbol or a constant must be
treated differently depending on something about the variable or
function named by the symbol (such as what section it is in).
-The hook is executed under two circumstances. One is immediately after
-the rtl for @var{decl} that represents a variable or a function has been
-created and stored in @code{DECL_RTL(@var{decl})}. The value of the rtl
-will be a @code{mem} whose address is a @code{symbol_ref}. The other is
-immediately after the rtl for @var{decl} that represents a constant has
-been created and stored in @code{TREE_CST_RTL (@var{decl})}. The macro
-is called once for each distinct constant in a source file.
+The hook is executed immediately after rtl has been created for
+@var{decl}, which may be a variable or function declaration or
+an entry in the constant pool. In either case, @var{rtl} is the
+rtl in question. Do @emph{not} use @code{DECL_RTL (@var{decl})}
+in this hook; that field may not have been initialized yet.
+
+In the case of a constant, it is safe to assume that the rtl is
+a @code{mem} whose address is a @code{symbol_ref}. Most decls
+will also have this form, but that is not guaranteed. Global
+register variables, for instance, will have a @code{reg} for their
+rtl. (Normally the right thing to do with such unusual rtl is
+leave it alone.)
The @var{new_decl_p} argument will be true if this is the first time
-that @code{ENCODE_SECTION_INFO} has been invoked on this decl. It will
+that @code{TARGET_ENCODE_SECTION_INFO} has been invoked on this decl. It will
be false for subsequent invocations, which will happen for duplicate
declarations. Whether or not anything must be done for the duplicate
declaration depends on whether the hook examines @code{DECL_ATTRIBUTES}.
+@var{new_decl_p} is always true when the hook is called for a constant.
@cindex @code{SYMBOL_REF_FLAG}, in @code{TARGET_ENCODE_SECTION_INFO}
-The usual thing for this hook to do is to record a flag in the
-@code{symbol_ref} (such as @code{SYMBOL_REF_FLAG}) or to store a
-modified name string in the @code{symbol_ref} (if one bit is not
-enough information).
+The usual thing for this hook to do is to record flags in the
+@code{symbol_ref}, using @code{SYMBOL_REF_FLAG} or @code{SYMBOL_REF_FLAGS}.
+Historically, the name string was modified if it was necessary to
+encode more than one bit of information, but this practice is now
+discouraged; use @code{SYMBOL_REF_FLAGS}.
+
+The default definition of this hook, @code{default_encode_section_info}
+in @file{varasm.c}, sets a number of commonly-useful bits in
+@code{SYMBOL_REF_FLAGS}. Check whether the default does what you need
+before overriding it.
@end deftypefn
@deftypefn {Target Hook} const char *TARGET_STRIP_NAME_ENCODING (const char *name)
@@ -5976,9 +6045,7 @@ 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
-@table @code
-@findex PIC_OFFSET_TABLE_REGNUM
-@item PIC_OFFSET_TABLE_REGNUM
+@defmac PIC_OFFSET_TABLE_REGNUM
The register number of the register used to address a table of static
data addresses in memory. In some cases this register is defined by a
processor's ``application binary interface'' (ABI)@. When this macro
@@ -5987,15 +6054,15 @@ pointer and frame pointer registers. If this macro is not defined, it
is up to the machine-dependent files to allocate such a register (if
necessary). Note that this register must be fixed when in use (e.g.@:
when @code{flag_pic} is true).
+@end defmac
-@findex PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
-@item PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
+@defmac PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
Define this macro if the register defined by
@code{PIC_OFFSET_TABLE_REGNUM} is clobbered by calls. Do not define
this macro if @code{PIC_OFFSET_TABLE_REGNUM} is not defined.
+@end defmac
-@findex FINALIZE_PIC
-@item FINALIZE_PIC
+@defmac FINALIZE_PIC
By generating position-independent code, when two different programs (A
and B) share a common library (libC.a), the text of the library can be
shared whether or not the library is linked at the same address for both
@@ -6009,9 +6076,9 @@ before. (It is not done before, because in the case of compiling an
inline function, it would lead to multiple PIC prologues being
included in functions which used inline functions and were compiled to
assembly language.)
+@end defmac
-@findex LEGITIMATE_PIC_OPERAND_P
-@item LEGITIMATE_PIC_OPERAND_P (@var{x})
+@defmac LEGITIMATE_PIC_OPERAND_P (@var{x})
A C expression that is nonzero if @var{x} is a legitimate immediate
operand on the target machine when generating position independent code.
You can assume that @var{x} satisfies @code{CONSTANT_P}, so you need not
@@ -6019,7 +6086,7 @@ check this. You can also assume @var{flag_pic} is true, so you need not
check it either. You need not define this macro if all constants
(including @code{SYMBOL_REF}) can be immediate operands when generating
position independent code.
-@end table
+@end defmac
@node Assembler Format
@section Defining the Output Assembler Language
@@ -6050,93 +6117,107 @@ instructions do.
@cindex output of assembler code
@c prevent bad page break with this line
-This describes the overall framework of an assembler file.
-
-@table @code
-@findex ASM_FILE_START
-@item ASM_FILE_START (@var{stream})
-A C expression which outputs to the stdio stream @var{stream}
-some appropriate text to go at the start of an assembler file.
-
-Normally this macro is defined to output a line containing
-@samp{#NO_APP}, which is a comment that has no effect on most
-assemblers but tells the GNU assembler that it can save time by not
-checking for certain assembler constructs.
+This describes the overall framework of an assembly file.
+
+@deftypefn {Target Hook} void TARGET_ASM_FILE_START ()
+@findex default_file_start
+Output to @code{asm_out_file} any text which the assembler expects to
+find at the beginning of a file. The default behavior is controlled
+by two flags, documented below. Unless your target's assembler is
+quite unusual, if you override the default, you should call
+@code{default_file_start} at some point in your target hook. This
+lets other target files rely on these variables.
+@end deftypefn
-On systems that use SDB, it is necessary to output certain commands;
-see @file{attasm.h}.
+@deftypevr {Target Hook} bool TARGET_ASM_FILE_START_APP_OFF
+If this flag is true, the text of the macro @code{ASM_APP_OFF} will be
+printed as the very first line in the assembly file, unless
+@option{-fverbose-asm} is in effect. (If that macro has been defined
+to the empty string, this variable has no effect.) With the normal
+definition of @code{ASM_APP_OFF}, the effect is to notify the GNU
+assembler that it need not bother stripping comments or extra
+whitespace from its input. This allows it to work a bit faster.
+
+The default is false. You should not set it to true unless you have
+verified that your port does not generate any extra whitespace or
+comments that will cause GAS to issue errors in NO_APP mode.
+@end deftypevr
-@findex ASM_FILE_END
-@item ASM_FILE_END (@var{stream})
-A C expression which outputs to the stdio stream @var{stream}
-some appropriate text to go at the end of an assembler file.
+@deftypevr {Target Hook} bool TARGET_ASM_FILE_START_FILE_DIRECTIVE
+If this flag is true, @code{output_file_directive} will be called
+for the primary source file, immediately after printing
+@code{ASM_APP_OFF} (if that is enabled). Most ELF assemblers expect
+this to be done. The default is false.
+@end deftypevr
-If this macro is not defined, the default is to output nothing
-special at the end of the file. Most systems don't require any
-definition.
+@deftypefn {Target Hook} void TARGET_ASM_FILE_END ()
+Output to @code{asm_out_file} any text which the assembler expects
+to find at the end of a file. The default is to output nothing.
+@end deftypefn
-On systems that use SDB, it is necessary to output certain commands;
-see @file{attasm.h}.
+@deftypefun void file_end_indicate_exec_stack ()
+Some systems use a common convention, the @samp{.note.GNU-stack}
+special section, to indicate whether or not an object file relies on
+the stack being executable. If your system uses this convention, you
+should define @code{TARGET_ASM_FILE_END} to this function. If you
+need to do other things in that hook, have your hook function call
+this function.
+@end deftypefun
-@findex ASM_COMMENT_START
-@item ASM_COMMENT_START
+@defmac ASM_COMMENT_START
A C string constant describing how to begin a comment in the target
assembler language. The compiler assumes that the comment will end at
the end of the line.
+@end defmac
-@findex ASM_APP_ON
-@item ASM_APP_ON
+@defmac ASM_APP_ON
A C string constant for text to be output before each @code{asm}
statement or group of consecutive ones. Normally this is
@code{"#APP"}, which is a comment that has no effect on most
assemblers but tells the GNU assembler that it must check the lines
that follow for all valid assembler constructs.
+@end defmac
-@findex ASM_APP_OFF
-@item ASM_APP_OFF
+@defmac ASM_APP_OFF
A C string constant for text to be output after each @code{asm}
statement or group of consecutive ones. Normally this is
@code{"#NO_APP"}, which tells the GNU assembler to resume making the
time-saving assumptions that are valid for ordinary compiler output.
+@end defmac
-@findex ASM_OUTPUT_SOURCE_FILENAME
-@item ASM_OUTPUT_SOURCE_FILENAME (@var{stream}, @var{name})
+@defmac ASM_OUTPUT_SOURCE_FILENAME (@var{stream}, @var{name})
A C statement to output COFF information or DWARF debugging information
which indicates that filename @var{name} is the current source file to
the stdio stream @var{stream}.
This macro need not be defined if the standard form of output
for the file format in use is appropriate.
+@end defmac
-@findex OUTPUT_QUOTED_STRING
-@item OUTPUT_QUOTED_STRING (@var{stream}, @var{string})
+@defmac OUTPUT_QUOTED_STRING (@var{stream}, @var{string})
A C statement to output the string @var{string} to the stdio stream
@var{stream}. If you do not call the function @code{output_quoted_string}
in your config files, GCC will only call it to output filenames to
the assembler source. So you can use it to canonicalize the format
of the filename using this macro.
+@end defmac
-@findex ASM_OUTPUT_SOURCE_LINE
-@item ASM_OUTPUT_SOURCE_LINE (@var{stream}, @var{line})
+@defmac ASM_OUTPUT_SOURCE_LINE (@var{stream}, @var{line}, @var{counter})
A C statement to output DBX or SDB debugging information before code
for line number @var{line} of the current source file to the
-stdio stream @var{stream}.
+stdio stream @var{stream}. @var{counter} is the number of time the
+macro was invoked, including the current invocation; it is intended
+to generate unique labels in the assembly output.
This macro need not be defined if the standard form of debugging
information for the debugger in use is appropriate.
+@end defmac
-@findex ASM_OUTPUT_IDENT
-@item ASM_OUTPUT_IDENT (@var{stream}, @var{string})
+@defmac ASM_OUTPUT_IDENT (@var{stream}, @var{string})
A C statement to output something to the assembler file to handle a
@samp{#ident} directive containing the text @var{string}. If this
macro is not defined, nothing is output for a @samp{#ident} directive.
-
-@findex OBJC_PROLOGUE
-@item OBJC_PROLOGUE
-A C statement to output any assembler statements which are required to
-precede any Objective-C object definitions or message sending. The
-statement is executed only when compiling an Objective-C program.
-@end table
+@end defmac
@deftypefn {Target Hook} void TARGET_ASM_NAMED_SECTION (const char *@var{name}, unsigned int @var{flags}, unsigned int @var{align})
Output assembly directives to switch to section @var{name}. The section
@@ -6202,9 +6283,7 @@ The default implementation of this hook will use the
when the relevant string is @code{NULL}.
@end deftypefn
-@table @code
-@findex OUTPUT_ADDR_CONST_EXTRA
-@item OUTPUT_ADDR_CONST_EXTRA (@var{stream}, @var{x}, @var{fail})
+@defmac OUTPUT_ADDR_CONST_EXTRA (@var{stream}, @var{x}, @var{fail})
A C statement to recognize @var{rtx} patterns that
@code{output_addr_const} can't deal with, and output assembly code to
@var{stream} corresponding to the pattern @var{x}. This may be used to
@@ -6214,9 +6293,9 @@ If @code{OUTPUT_ADDR_CONST_EXTRA} fails to recognize a pattern, it must
@code{goto fail}, so that a standard error message is printed. If it
prints an error message itself, by calling, for example,
@code{output_operand_lossage}, it may just complete normally.
+@end defmac
-@findex ASM_OUTPUT_ASCII
-@item ASM_OUTPUT_ASCII (@var{stream}, @var{ptr}, @var{len})
+@defmac ASM_OUTPUT_ASCII (@var{stream}, @var{ptr}, @var{len})
A C statement to output to the stdio stream @var{stream} an assembler
instruction to assemble a string constant containing the @var{len}
bytes at @var{ptr}. @var{ptr} will be a C expression of type
@@ -6225,24 +6304,24 @@ bytes at @var{ptr}. @var{ptr} will be a C expression of type
If the assembler has a @code{.ascii} pseudo-op as found in the
Berkeley Unix assembler, do not define the macro
@code{ASM_OUTPUT_ASCII}.
+@end defmac
-@findex ASM_OUTPUT_FDESC
-@item ASM_OUTPUT_FDESC (@var{stream}, @var{decl}, @var{n})
+@defmac ASM_OUTPUT_FDESC (@var{stream}, @var{decl}, @var{n})
A C statement to output word @var{n} of a function descriptor for
@var{decl}. This must be defined if @code{TARGET_VTABLE_USES_DESCRIPTORS}
is defined, and is otherwise unused.
+@end defmac
-@findex CONSTANT_POOL_BEFORE_FUNCTION
-@item CONSTANT_POOL_BEFORE_FUNCTION
+@defmac CONSTANT_POOL_BEFORE_FUNCTION
You may define this macro as a C expression. You should define the
expression to have a nonzero value if GCC should output the constant
pool for a function before the code for the function, or a zero value if
GCC should output the constant pool after the function. If you do
not define this macro, the usual case, GCC will output the constant
pool before the function.
+@end defmac
-@findex ASM_OUTPUT_POOL_PROLOGUE
-@item ASM_OUTPUT_POOL_PROLOGUE (@var{file}, @var{funname}, @var{fundecl}, @var{size})
+@defmac ASM_OUTPUT_POOL_PROLOGUE (@var{file}, @var{funname}, @var{fundecl}, @var{size})
A C statement to output assembler commands to define the start of the
constant pool for a function. @var{funname} is a string giving
the name of the function. Should the return type of the function
@@ -6252,9 +6331,9 @@ immediately after this call.
If no constant-pool prefix is required, the usual case, this macro need
not be defined.
+@end defmac
-@findex ASM_OUTPUT_SPECIAL_POOL_ENTRY
-@item ASM_OUTPUT_SPECIAL_POOL_ENTRY (@var{file}, @var{x}, @var{mode}, @var{align}, @var{labelno}, @var{jumpto})
+@defmac ASM_OUTPUT_SPECIAL_POOL_ENTRY (@var{file}, @var{x}, @var{mode}, @var{align}, @var{labelno}, @var{jumpto})
A C statement (with or without semicolon) to output a constant in the
constant pool, if it needs special treatment. (This macro need not do
anything for RTL expressions that can be output normally.)
@@ -6271,25 +6350,18 @@ the address of this pool entry. The definition of this macro is
responsible for outputting the label definition at the proper place.
Here is how to do this:
-@example
-ASM_OUTPUT_INTERNAL_LABEL (@var{file}, "LC", @var{labelno});
-@end example
+@smallexample
+@code{(*targetm.asm_out.internal_label)} (@var{file}, "LC", @var{labelno});
+@end smallexample
When you output a pool entry specially, you should end with a
@code{goto} to the label @var{jumpto}. This will prevent the same pool
entry from being output a second time in the usual manner.
You need not define this macro if it would do nothing.
+@end defmac
-@findex CONSTANT_AFTER_FUNCTION_P
-@item CONSTANT_AFTER_FUNCTION_P (@var{exp})
-Define this macro as a C expression which is nonzero if the constant
-@var{exp}, of type @code{tree}, should be output after the code for a
-function. The compiler will normally output all constants before the
-function; you need not define this macro if this is OK@.
-
-@findex ASM_OUTPUT_POOL_EPILOGUE
-@item ASM_OUTPUT_POOL_EPILOGUE (@var{file} @var{funname} @var{fundecl} @var{size})
+@defmac ASM_OUTPUT_POOL_EPILOGUE (@var{file} @var{funname} @var{fundecl} @var{size})
A C statement to output assembler commands to at the end of the constant
pool for a function. @var{funname} is a string giving the name of the
function. Should the return type of the function be required, you can
@@ -6298,15 +6370,15 @@ constant pool that GCC wrote immediately before this call.
If no constant-pool epilogue is required, the usual case, you need not
define this macro.
+@end defmac
-@findex IS_ASM_LOGICAL_LINE_SEPARATOR
-@item IS_ASM_LOGICAL_LINE_SEPARATOR (@var{C})
+@defmac IS_ASM_LOGICAL_LINE_SEPARATOR (@var{C})
Define this macro as a C expression which is nonzero if @var{C} is
used as a logical line separator by the assembler.
If you do not define this macro, the default is that only
the character @samp{;} is treated as a logical line separator.
-@end table
+@end defmac
@deftypevr {Target Hook} {const char *} TARGET_ASM_OPEN_PAREN
@deftypevrx {Target Hook} {const char *} TARGET_ASM_CLOSE_PAREN
@@ -6318,13 +6390,9 @@ default to normal parentheses, which is correct for most assemblers.
These macros are provided by @file{real.h} for writing the definitions
of @code{ASM_OUTPUT_DOUBLE} and the like:
-@table @code
-@item REAL_VALUE_TO_TARGET_SINGLE (@var{x}, @var{l})
-@itemx REAL_VALUE_TO_TARGET_DOUBLE (@var{x}, @var{l})
-@itemx REAL_VALUE_TO_TARGET_LONG_DOUBLE (@var{x}, @var{l})
-@findex REAL_VALUE_TO_TARGET_SINGLE
-@findex REAL_VALUE_TO_TARGET_DOUBLE
-@findex REAL_VALUE_TO_TARGET_LONG_DOUBLE
+@defmac REAL_VALUE_TO_TARGET_SINGLE (@var{x}, @var{l})
+@defmacx REAL_VALUE_TO_TARGET_DOUBLE (@var{x}, @var{l})
+@defmacx REAL_VALUE_TO_TARGET_LONG_DOUBLE (@var{x}, @var{l})
These translate @var{x}, of type @code{REAL_VALUE_TYPE}, to the target's
floating point representation, and store its bit pattern in the variable
@var{l}. For @code{REAL_VALUE_TO_TARGET_SINGLE}, this variable should
@@ -6338,7 +6406,7 @@ host machine.
The array element values are designed so that you can print them out
using @code{fprintf} in the order they should appear in the target
machine's memory.
-@end table
+@end defmac
@node Uninitialized Data
@subsection Output of Uninitialized Variables
@@ -6346,9 +6414,7 @@ machine's memory.
Each of the macros in this section is used to do the whole job of
outputting a single uninitialized variable.
-@table @code
-@findex ASM_OUTPUT_COMMON
-@item ASM_OUTPUT_COMMON (@var{stream}, @var{name}, @var{size}, @var{rounded})
+@defmac ASM_OUTPUT_COMMON (@var{stream}, @var{name}, @var{size}, @var{rounded})
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}
@@ -6360,32 +6426,32 @@ assembler syntax for defining the name, and a newline.
This macro controls how the assembler definitions of uninitialized
common global variables are output.
+@end defmac
-@findex ASM_OUTPUT_ALIGNED_COMMON
-@item ASM_OUTPUT_ALIGNED_COMMON (@var{stream}, @var{name}, @var{size}, @var{alignment})
+@defmac ASM_OUTPUT_ALIGNED_COMMON (@var{stream}, @var{name}, @var{size}, @var{alignment})
Like @code{ASM_OUTPUT_COMMON} except takes the required alignment as a
separate, explicit argument. If you define this macro, it is used in
place of @code{ASM_OUTPUT_COMMON}, and gives you more flexibility in
handling the required alignment of the variable. The alignment is specified
as the number of bits.
+@end defmac
-@findex ASM_OUTPUT_ALIGNED_DECL_COMMON
-@item ASM_OUTPUT_ALIGNED_DECL_COMMON (@var{stream}, @var{decl}, @var{name}, @var{size}, @var{alignment})
+@defmac ASM_OUTPUT_ALIGNED_DECL_COMMON (@var{stream}, @var{decl}, @var{name}, @var{size}, @var{alignment})
Like @code{ASM_OUTPUT_ALIGNED_COMMON} except that @var{decl} of the
variable to be output, if there is one, or @code{NULL_TREE} if there
is no corresponding variable. If you define this macro, GCC will use it
in place of both @code{ASM_OUTPUT_COMMON} and
@code{ASM_OUTPUT_ALIGNED_COMMON}. Define this macro when you need to see
the variable's decl in order to chose what to output.
+@end defmac
-@findex ASM_OUTPUT_SHARED_COMMON
-@item ASM_OUTPUT_SHARED_COMMON (@var{stream}, @var{name}, @var{size}, @var{rounded})
+@defmac ASM_OUTPUT_SHARED_COMMON (@var{stream}, @var{name}, @var{size}, @var{rounded})
If defined, it is similar to @code{ASM_OUTPUT_COMMON}, except that it
is used when @var{name} is shared. If not defined, @code{ASM_OUTPUT_COMMON}
will be used.
+@end defmac
-@findex ASM_OUTPUT_BSS
-@item ASM_OUTPUT_BSS (@var{stream}, @var{decl}, @var{name}, @var{size}, @var{rounded})
+@defmac ASM_OUTPUT_BSS (@var{stream}, @var{decl}, @var{name}, @var{size}, @var{rounded})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} the assembler definition of uninitialized global @var{decl} named
@var{name} whose size is @var{size} bytes. The variable @var{rounded}
@@ -6404,9 +6470,9 @@ is not defined for all targets. If this macro and
@code{ASM_OUTPUT_ALIGNED_BSS} are not defined then @code{ASM_OUTPUT_COMMON}
or @code{ASM_OUTPUT_ALIGNED_COMMON} or
@code{ASM_OUTPUT_ALIGNED_DECL_COMMON} is used.
+@end defmac
-@findex ASM_OUTPUT_ALIGNED_BSS
-@item ASM_OUTPUT_ALIGNED_BSS (@var{stream}, @var{decl}, @var{name}, @var{size}, @var{alignment})
+@defmac ASM_OUTPUT_ALIGNED_BSS (@var{stream}, @var{decl}, @var{name}, @var{size}, @var{alignment})
Like @code{ASM_OUTPUT_BSS} except takes the required alignment as a
separate, explicit argument. If you define this macro, it is used in
place of @code{ASM_OUTPUT_BSS}, and gives you more flexibility in
@@ -6415,15 +6481,15 @@ as the number of bits.
Try to use function @code{asm_output_aligned_bss} defined in file
@file{varasm.c} when defining this macro.
+@end defmac
-@findex ASM_OUTPUT_SHARED_BSS
-@item ASM_OUTPUT_SHARED_BSS (@var{stream}, @var{decl}, @var{name}, @var{size}, @var{rounded})
+@defmac ASM_OUTPUT_SHARED_BSS (@var{stream}, @var{decl}, @var{name}, @var{size}, @var{rounded})
If defined, it is similar to @code{ASM_OUTPUT_BSS}, except that it
is used when @var{name} is shared. If not defined, @code{ASM_OUTPUT_BSS}
will be used.
+@end defmac
-@findex ASM_OUTPUT_LOCAL
-@item ASM_OUTPUT_LOCAL (@var{stream}, @var{name}, @var{size}, @var{rounded})
+@defmac ASM_OUTPUT_LOCAL (@var{stream}, @var{name}, @var{size}, @var{rounded})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} the assembler definition of a local-common-label named
@var{name} whose size is @var{size} bytes. The variable @var{rounded}
@@ -6435,30 +6501,30 @@ assembler syntax for defining the name, and a newline.
This macro controls how the assembler definitions of uninitialized
static variables are output.
+@end defmac
-@findex ASM_OUTPUT_ALIGNED_LOCAL
-@item ASM_OUTPUT_ALIGNED_LOCAL (@var{stream}, @var{name}, @var{size}, @var{alignment})
+@defmac ASM_OUTPUT_ALIGNED_LOCAL (@var{stream}, @var{name}, @var{size}, @var{alignment})
Like @code{ASM_OUTPUT_LOCAL} except takes the required alignment as a
separate, explicit argument. If you define this macro, it is used in
place of @code{ASM_OUTPUT_LOCAL}, and gives you more flexibility in
handling the required alignment of the variable. The alignment is specified
as the number of bits.
+@end defmac
-@findex ASM_OUTPUT_ALIGNED_DECL_LOCAL
-@item ASM_OUTPUT_ALIGNED_DECL_LOCAL (@var{stream}, @var{decl}, @var{name}, @var{size}, @var{alignment})
+@defmac ASM_OUTPUT_ALIGNED_DECL_LOCAL (@var{stream}, @var{decl}, @var{name}, @var{size}, @var{alignment})
Like @code{ASM_OUTPUT_ALIGNED_DECL} except that @var{decl} of the
variable to be output, if there is one, or @code{NULL_TREE} if there
is no corresponding variable. If you define this macro, GCC will use it
in place of both @code{ASM_OUTPUT_DECL} and
@code{ASM_OUTPUT_ALIGNED_DECL}. Define this macro when you need to see
the variable's decl in order to chose what to output.
+@end defmac
-@findex ASM_OUTPUT_SHARED_LOCAL
-@item ASM_OUTPUT_SHARED_LOCAL (@var{stream}, @var{name}, @var{size}, @var{rounded})
+@defmac ASM_OUTPUT_SHARED_LOCAL (@var{stream}, @var{name}, @var{size}, @var{rounded})
If defined, it is similar to @code{ASM_OUTPUT_LOCAL}, except that it
is used when @var{name} is shared. If not defined, @code{ASM_OUTPUT_LOCAL}
will be used.
-@end table
+@end defmac
@node Label Output
@subsection Output and Generation of Labels
@@ -6466,19 +6532,17 @@ will be used.
@c prevent bad page break with this line
This is about outputting labels.
-@table @code
-@findex ASM_OUTPUT_LABEL
@findex assemble_name
-@item ASM_OUTPUT_LABEL (@var{stream}, @var{name})
+@defmac ASM_OUTPUT_LABEL (@var{stream}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} the assembler definition of a label named @var{name}.
Use the expression @code{assemble_name (@var{stream}, @var{name})} to
output the name itself; before and after that, output the additional
assembler syntax for defining the name, and a newline. A default
definition of this macro is provided which is correct for most systems.
+@end defmac
-@findex SIZE_ASM_OP
-@item SIZE_ASM_OP
+@defmac SIZE_ASM_OP
A C string containing the appropriate assembler directive to specify the
size of a symbol, without any arguments. On systems that use ELF, the
default (in @file{config/elfos.h}) is @samp{"\t.size\t"}; on other
@@ -6489,21 +6553,21 @@ of @code{ASM_OUTPUT_SIZE_DIRECTIVE} and @code{ASM_OUTPUT_MEASURED_SIZE}
for your system. If you need your own custom definitions of those
macros, or if you do not need explicit symbol sizes at all, do not
define this macro.
+@end defmac
-@findex ASM_OUTPUT_SIZE_DIRECTIVE
-@item ASM_OUTPUT_SIZE_DIRECTIVE (@var{stream}, @var{name}, @var{size})
+@defmac ASM_OUTPUT_SIZE_DIRECTIVE (@var{stream}, @var{name}, @var{size})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} a directive telling the assembler that the size of the
symbol @var{name} is @var{size}. @var{size} is a @code{HOST_WIDE_INT}.
If you define @code{SIZE_ASM_OP}, a default definition of this macro is
provided.
+@end defmac
-@findex ASM_OUTPUT_MEASURED_SIZE
-@item ASM_OUTPUT_MEASURED_SIZE (@var{stream}, @var{name})
+@defmac ASM_OUTPUT_MEASURED_SIZE (@var{stream}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} a directive telling the assembler to calculate the size of
the symbol @var{name} by subtracting its address from the current
-address.
+address.
If you define @code{SIZE_ASM_OP}, a default definition of this macro is
provided. The default assumes that the assembler recognizes a special
@@ -6511,9 +6575,9 @@ provided. The default assumes that the assembler recognizes a special
the difference between this and another symbol. If your assembler does
not recognize @samp{.} or cannot do calculations with it, you will need
to redefine @code{ASM_OUTPUT_MEASURED_SIZE} to use some other technique.
+@end defmac
-@findex TYPE_ASM_OP
-@item TYPE_ASM_OP
+@defmac TYPE_ASM_OP
A C string containing the appropriate assembler directive to specify the
type of a symbol, without any arguments. On systems that use ELF, the
default (in @file{config/elfos.h}) is @samp{"\t.type\t"}; on other
@@ -6523,9 +6587,9 @@ Define this macro only if it is correct to use the default definition of
@code{ASM_OUTPUT_TYPE_DIRECTIVE} for your system. If you need your own
custom definition of this macro, or if you do not need explicit symbol
types at all, do not define this macro.
+@end defmac
-@findex TYPE_OPERAND_FMT
-@item TYPE_OPERAND_FMT
+@defmac TYPE_OPERAND_FMT
A C string which specifies (using @code{printf} syntax) the format of
the second operand to @code{TYPE_ASM_OP}. On systems that use ELF, the
default (in @file{config/elfos.h}) is @samp{"@@%s"}; on other systems,
@@ -6535,9 +6599,9 @@ Define this macro only if it is correct to use the default definition of
@code{ASM_OUTPUT_TYPE_DIRECTIVE} for your system. If you need your own
custom definition of this macro, or if you do not need explicit symbol
types at all, do not define this macro.
+@end defmac
-@findex ASM_OUTPUT_TYPE_DIRECTIVE
-@item ASM_OUTPUT_TYPE_DIRECTIVE (@var{stream}, @var{type})
+@defmac ASM_OUTPUT_TYPE_DIRECTIVE (@var{stream}, @var{type})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} a directive telling the assembler that the type of the
symbol @var{name} is @var{type}. @var{type} is a C string; currently,
@@ -6546,9 +6610,9 @@ you should not count on this.
If you define @code{TYPE_ASM_OP} and @code{TYPE_OPERAND_FMT}, a default
definition of this macro is provided.
+@end defmac
-@findex ASM_DECLARE_FUNCTION_NAME
-@item ASM_DECLARE_FUNCTION_NAME (@var{stream}, @var{name}, @var{decl})
+@defmac ASM_DECLARE_FUNCTION_NAME (@var{stream}, @var{name}, @var{decl})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} any text necessary for declaring the name @var{name} of a
function which is being defined. This macro is responsible for
@@ -6561,9 +6625,9 @@ usual manner as a label (by means of @code{ASM_OUTPUT_LABEL}).
You may wish to use @code{ASM_OUTPUT_TYPE_DIRECTIVE} in the definition
of this macro.
+@end defmac
-@findex ASM_DECLARE_FUNCTION_SIZE
-@item ASM_DECLARE_FUNCTION_SIZE (@var{stream}, @var{name}, @var{decl})
+@defmac ASM_DECLARE_FUNCTION_SIZE (@var{stream}, @var{name}, @var{decl})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} any text necessary for declaring the size of a function
which is being defined. The argument @var{name} is the name of the
@@ -6574,9 +6638,9 @@ If this macro is not defined, then the function size is not defined.
You may wish to use @code{ASM_OUTPUT_MEASURED_SIZE} in the definition
of this macro.
+@end defmac
-@findex ASM_DECLARE_OBJECT_NAME
-@item ASM_DECLARE_OBJECT_NAME (@var{stream}, @var{name}, @var{decl})
+@defmac ASM_DECLARE_OBJECT_NAME (@var{stream}, @var{name}, @var{decl})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} any text necessary for declaring the name @var{name} of an
initialized variable which is being defined. This macro must output the
@@ -6588,9 +6652,9 @@ usual manner as a label (by means of @code{ASM_OUTPUT_LABEL}).
You may wish to use @code{ASM_OUTPUT_TYPE_DIRECTIVE} and/or
@code{ASM_OUTPUT_SIZE_DIRECTIVE} in the definition of this macro.
+@end defmac
-@findex ASM_DECLARE_CONSTANT_NAME
-@item ASM_DECLARE_CONSTANT_NAME (@var{stream}, @var{name}, @var{exp}, @var{size})
+@defmac ASM_DECLARE_CONSTANT_NAME (@var{stream}, @var{name}, @var{exp}, @var{size})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} any text necessary for declaring the name @var{name} of a
constant which is being defined. This macro is responsible for
@@ -6604,18 +6668,18 @@ usual manner as a label (by means of @code{ASM_OUTPUT_LABEL}).
You may wish to use @code{ASM_OUTPUT_TYPE_DIRECTIVE} in the definition
of this macro.
+@end defmac
-@findex ASM_DECLARE_REGISTER_GLOBAL
-@item ASM_DECLARE_REGISTER_GLOBAL (@var{stream}, @var{decl}, @var{regno}, @var{name})
+@defmac ASM_DECLARE_REGISTER_GLOBAL (@var{stream}, @var{decl}, @var{regno}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} any text necessary for claiming a register @var{regno}
for a global variable @var{decl} with name @var{name}.
If you don't define this macro, that is equivalent to defining it to do
nothing.
+@end defmac
-@findex ASM_FINISH_DECLARE_OBJECT
-@item ASM_FINISH_DECLARE_OBJECT (@var{stream}, @var{decl}, @var{toplevel}, @var{atend})
+@defmac ASM_FINISH_DECLARE_OBJECT (@var{stream}, @var{decl}, @var{toplevel}, @var{atend})
A C statement (sans semicolon) to finish up declaring a variable name
once the compiler has processed its initializer fully and thus has had a
chance to determine the size of an array when controlled by an
@@ -6627,7 +6691,7 @@ nothing.
You may wish to use @code{ASM_OUTPUT_SIZE_DIRECTIVE} and/or
@code{ASM_OUTPUT_MEASURED_SIZE} in the definition of this macro.
-@end table
+@end defmac
@deftypefn {Target Hook} void TARGET_ASM_GLOBALIZE_LABEL (FILE *@var{stream}, const char *@var{name})
This target hook is a function to output to the stdio stream
@@ -6638,9 +6702,7 @@ The default implementation relies on a proper definition of
@code{GLOBAL_ASM_OP}.
@end deftypefn
-@table @code
-@findex ASM_WEAKEN_LABEL
-@item ASM_WEAKEN_LABEL (@var{stream}, @var{name})
+@defmac ASM_WEAKEN_LABEL (@var{stream}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} some commands that will make the label @var{name} weak;
that is, available for reference from other files but only used if
@@ -6652,9 +6714,9 @@ for making that name weak, and a newline.
If you don't define this macro or @code{ASM_WEAKEN_DECL}, GCC will not
support weak symbols and you should not define the @code{SUPPORTS_WEAK}
macro.
+@end defmac
-@findex ASM_WEAKEN_DECL
-@item ASM_WEAKEN_DECL (@var{stream}, @var{decl}, @var{name}, @var{value})
+@defmac ASM_WEAKEN_DECL (@var{stream}, @var{decl}, @var{name}, @var{value})
Combines (and replaces) the function of @code{ASM_WEAKEN_LABEL} and
@code{ASM_OUTPUT_WEAK_ALIAS}, allowing access to the associated function
or variable decl. If @var{value} is not @code{NULL}, this C statement
@@ -6662,9 +6724,9 @@ should output to the stdio stream @var{stream} assembler code which
defines (equates) the weak symbol @var{name} to have the value
@var{value}. If @var{value} is @code{NULL}, it should output commands
to make @var{name} weak.
+@end defmac
-@findex SUPPORTS_WEAK
-@item SUPPORTS_WEAK
+@defmac SUPPORTS_WEAK
A C expression which evaluates to true if the target supports weak symbols.
If you don't define this macro, @file{defaults.h} provides a default
@@ -6672,18 +6734,18 @@ definition. If either @code{ASM_WEAKEN_LABEL} or @code{ASM_WEAKEN_DECL}
is defined, the default definition is @samp{1}; otherwise, it is
@samp{0}. Define this macro if you want to control weak symbol support
with a compiler flag such as @option{-melf}.
+@end defmac
-@findex MAKE_DECL_ONE_ONLY (@var{decl})
-@item MAKE_DECL_ONE_ONLY
+@defmac MAKE_DECL_ONE_ONLY (@var{decl})
A C statement (sans semicolon) to mark @var{decl} to be emitted as a
public symbol such that extra copies in multiple translation units will
be discarded by the linker. Define this macro if your object file
format provides support for this concept, such as the @samp{COMDAT}
section flags in the Microsoft Windows PE/COFF format, and this support
requires changes to @var{decl}, such as putting it in a separate section.
+@end defmac
-@findex SUPPORTS_ONE_ONLY
-@item SUPPORTS_ONE_ONLY
+@defmac SUPPORTS_ONE_ONLY
A C expression which evaluates to true if the target supports one-only
semantics.
@@ -6693,6 +6755,7 @@ definition is @samp{1}; otherwise, it is @samp{0}. Define this macro if
you want to control one-only symbol support with a compiler flag, or if
setting the @code{DECL_ONE_ONLY} flag is enough to mark a declaration to
be emitted as one-only.
+@end defmac
@deftypefn {Target Hook} void TARGET_ASM_ASSEMBLE_VISIBILITY (tree @var{decl}, const char *@var{visibility})
This target hook is a function to output to @var{asm_out_file} some
@@ -6700,8 +6763,7 @@ commands that will make the symbol(s) associated with @var{decl} have
hidden, protected or internal visibility as specified by @var{visibility}.
@end deftypefn
-@findex ASM_OUTPUT_EXTERNAL
-@item ASM_OUTPUT_EXTERNAL (@var{stream}, @var{decl}, @var{name})
+@defmac ASM_OUTPUT_EXTERNAL (@var{stream}, @var{decl}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} any text necessary for declaring the name of an external
symbol named @var{name} which is referenced in this compilation but
@@ -6710,35 +6772,31 @@ declaration.
This macro need not be defined if it does not need to output anything.
The GNU assembler and most Unix assemblers don't require anything.
+@end defmac
-@findex ASM_OUTPUT_EXTERNAL_LIBCALL
-@item ASM_OUTPUT_EXTERNAL_LIBCALL (@var{stream}, @var{symref})
-A C statement (sans semicolon) to output on @var{stream} an assembler
+@deftypefn {Target Hook} void TARGET_ASM_EXTERNAL_LIBCALL (rtx @var{symref})
+This target hook is a function to output to @var{asm_out_file} an assembler
pseudo-op to declare a library function name external. The name of the
-library function is given by @var{symref}, which has type @code{rtx} and
-is a @code{symbol_ref}.
-
-This macro need not be defined if it does not need to output anything.
-The GNU assembler and most Unix assemblers don't require anything.
+library function is given by @var{symref}, which is a @code{symbol_ref}.
+@end deftypefn
-@findex ASM_OUTPUT_LABELREF
-@item ASM_OUTPUT_LABELREF (@var{stream}, @var{name})
+@defmac ASM_OUTPUT_LABELREF (@var{stream}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} a reference in assembler syntax to a label named
@var{name}. This should add @samp{_} to the front of the name, if that
is customary on your operating system, as it is in most Berkeley Unix
systems. This macro is used in @code{assemble_name}.
+@end defmac
-@findex ASM_OUTPUT_SYMBOL_REF
-@item ASM_OUTPUT_SYMBOL_REF (@var{stream}, @var{sym})
+@defmac ASM_OUTPUT_SYMBOL_REF (@var{stream}, @var{sym})
A C statement (sans semicolon) to output a reference to
@code{SYMBOL_REF} @var{sym}. If not defined, @code{assemble_name}
will be used to output the name of the symbol. This macro may be used
to modify the way a symbol is referenced depending on information
encoded by @code{TARGET_ENCODE_SECTION_INFO}.
+@end defmac
-@findex ASM_OUTPUT_LABEL_REF
-@item ASM_OUTPUT_LABEL_REF (@var{stream}, @var{buf})
+@defmac ASM_OUTPUT_LABEL_REF (@var{stream}, @var{buf})
A C statement (sans semicolon) to output a reference to @var{buf}, the
result of @code{ASM_GENERATE_INTERNAL_LABEL}. If not defined,
@code{assemble_name} will be used to output the name of the symbol.
@@ -6746,11 +6804,11 @@ This macro is not used by @code{output_asm_label}, or the @code{%l}
specifier that calls it; the intention is that this macro should be set
when it is necessary to output a label differently when its address is
being taken.
+@end defmac
-@findex ASM_OUTPUT_INTERNAL_LABEL
-@item ASM_OUTPUT_INTERNAL_LABEL (@var{stream}, @var{prefix}, @var{num})
-A C statement to output to the stdio stream @var{stream} a label whose
-name is made from the string @var{prefix} and the number @var{num}.
+@deftypefn {Target Hook} void TARGET_ASM_INTERNAL_LABEL (FILE *@var{stream}, const char *@var{prefix}, unsigned long @var{labelno})
+A function to output to the stdio stream @var{stream} a label whose
+name is made from the string @var{prefix} and the number @var{labelno}.
It is absolutely essential that these labels be distinct from the labels
used for user-level functions and variables. Otherwise, certain programs
@@ -6762,14 +6820,10 @@ should be excluded; on many systems, the letter @samp{L} at the
beginning of a label has this effect. You should find out what
convention your system uses, and follow it.
-The usual definition of this macro is as follows:
-
-@example
-fprintf (@var{stream}, "L%s%d:\n", @var{prefix}, @var{num})
-@end example
+The default version of this function utilizes ASM_GENERATE_INTERNAL_LABEL.
+@end deftypefn
-@findex ASM_OUTPUT_DEBUG_LABEL
-@item ASM_OUTPUT_DEBUG_LABEL (@var{stream}, @var{prefix}, @var{num})
+@defmac ASM_OUTPUT_DEBUG_LABEL (@var{stream}, @var{prefix}, @var{num})
A C statement to output to the stdio stream @var{stream} a debug info
label whose name is made from the string @var{prefix} and the number
@var{num}. This is useful for VLIW targets, where debug info labels
@@ -6778,16 +6832,16 @@ systems, branch target labels must be at the beginning of instruction
bundles, but debug info labels can occur in the middle of instruction
bundles.
-If this macro is not defined, then @code{ASM_OUTPUT_INTERNAL_LABEL} will be
+If this macro is not defined, then @code{(*targetm.asm_out.internal_label)} will be
used.
+@end defmac
-@findex ASM_GENERATE_INTERNAL_LABEL
-@item ASM_GENERATE_INTERNAL_LABEL (@var{string}, @var{prefix}, @var{num})
+@defmac ASM_GENERATE_INTERNAL_LABEL (@var{string}, @var{prefix}, @var{num})
A C statement to store into the string @var{string} a label whose name
is made from the string @var{prefix} and the number @var{num}.
This string, when output subsequently by @code{assemble_name}, should
-produce the output that @code{ASM_OUTPUT_INTERNAL_LABEL} would produce
+produce the output that @code{(*targetm.asm_out.internal_label)} would produce
with the same @var{prefix} and @var{num}.
If the string begins with @samp{*}, then @code{assemble_name} will
@@ -6797,9 +6851,9 @@ string doesn't start with @samp{*}, then @code{ASM_OUTPUT_LABELREF} gets
to output the string, and may change it. (Of course,
@code{ASM_OUTPUT_LABELREF} is also part of your machine description, so
you should know what it does on your machine.)
+@end defmac
-@findex ASM_FORMAT_PRIVATE_NAME
-@item ASM_FORMAT_PRIVATE_NAME (@var{outvar}, @var{name}, @var{number})
+@defmac ASM_FORMAT_PRIVATE_NAME (@var{outvar}, @var{name}, @var{number})
A C expression to assign to @var{outvar} (which is a variable of type
@code{char *}) a newly allocated string made from the string
@var{name} and the number @var{number}, with some suitable punctuation
@@ -6817,17 +6871,20 @@ conflict with the user's own symbols. Most assemblers allow periods
or percent signs in assembler symbols; putting at least one of these
between the name and the number will suffice.
-@findex ASM_OUTPUT_DEF
-@item ASM_OUTPUT_DEF (@var{stream}, @var{name}, @var{value})
+If this macro is not defined, a default definition will be provided
+which is correct for most systems.
+@end defmac
+
+@defmac ASM_OUTPUT_DEF (@var{stream}, @var{name}, @var{value})
A C statement to output to the stdio stream @var{stream} assembler code
which defines (equates) the symbol @var{name} to have the value @var{value}.
@findex SET_ASM_OP
If @code{SET_ASM_OP} is defined, a default definition is provided which is
correct for most systems.
+@end defmac
-@findex ASM_OUTPUT_DEF_FROM_DECLS
-@item ASM_OUTPUT_DEF_FROM_DECLS (@var{stream}, @var{decl_of_name}, @var{decl_of_value})
+@defmac ASM_OUTPUT_DEF_FROM_DECLS (@var{stream}, @var{decl_of_name}, @var{decl_of_value})
A C statement to output to the stdio stream @var{stream} assembler code
which defines (equates) the symbol whose tree node is @var{decl_of_name}
to have the value of the tree node @var{decl_of_value}. This macro will
@@ -6837,9 +6894,9 @@ the tree nodes are available.
@findex SET_ASM_OP
If @code{SET_ASM_OP} is defined, a default definition is provided which is
correct for most systems.
+@end defmac
-@findex ASM_OUTPUT_WEAK_ALIAS
-@item ASM_OUTPUT_WEAK_ALIAS (@var{stream}, @var{name}, @var{value})
+@defmac ASM_OUTPUT_WEAK_ALIAS (@var{stream}, @var{name}, @var{value})
A C statement to output to the stdio stream @var{stream} assembler code
which defines (equates) the weak symbol @var{name} to have the value
@var{value}. If @var{value} is @code{NULL}, it defines @var{name} as
@@ -6847,9 +6904,9 @@ an undefined weak symbol.
Define this macro if the target only supports weak aliases; define
@code{ASM_OUTPUT_DEF} instead if possible.
+@end defmac
-@findex OBJC_GEN_METHOD_LABEL
-@item OBJC_GEN_METHOD_LABEL (@var{buf}, @var{is_inst}, @var{class_name}, @var{cat_name}, @var{sel_name})
+@defmac OBJC_GEN_METHOD_LABEL (@var{buf}, @var{is_inst}, @var{class_name}, @var{cat_name}, @var{sel_name})
Define this macro to override the default assembler names used for
Objective-C methods.
@@ -6874,21 +6931,21 @@ in a category); and @var{sel_name} is the name of the selector.
On systems where the assembler can handle quoted names, you can use this
macro to provide more human-readable names.
+@end defmac
-@findex ASM_DECLARE_CLASS_REFERENCE
-@item ASM_DECLARE_CLASS_REFERENCE (@var{stream}, @var{name})
+@defmac ASM_DECLARE_CLASS_REFERENCE (@var{stream}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} commands to declare that the label @var{name} is an
Objective-C class reference. This is only needed for targets whose
linkers have special support for NeXT-style runtimes.
+@end defmac
-@findex ASM_DECLARE_UNRESOLVED_REFERENCE
-@item ASM_DECLARE_UNRESOLVED_REFERENCE (@var{stream}, @var{name})
+@defmac ASM_DECLARE_UNRESOLVED_REFERENCE (@var{stream}, @var{name})
A C statement (sans semicolon) to output to the stdio stream
@var{stream} commands to declare that the label @var{name} is an
unresolved Objective-C class reference. This is only needed for targets
whose linkers have special support for NeXT-style runtimes.
-@end table
+@end defmac
@node Initialization
@subsection How Initialization Functions Are Handled
@@ -6954,9 +7011,9 @@ support a @dfn{.init} section which is executed at program startup,
parts of @file{crtstuff.c} are compiled into that section. The
program is linked by the @command{gcc} driver like this:
-@example
+@smallexample
ld -o @var{output_file} crti.o crtbegin.o @dots{} -lgcc crtend.o crtn.o
-@end example
+@end smallexample
The prologue of a function (@code{__init}) appears in the @code{.init}
section of @file{crti.o}; the epilogue appears in @file{crtn.o}. Likewise
@@ -7019,34 +7076,33 @@ customize the handling of initialization and termination functions.
Here are the macros that control how the compiler handles initialization
and termination functions:
-@table @code
-@findex INIT_SECTION_ASM_OP
-@item INIT_SECTION_ASM_OP
+@defmac INIT_SECTION_ASM_OP
If defined, a C string constant, including spacing, for the assembler
operation to identify the following data as initialization code. If not
defined, GCC will assume such a section does not exist. When you are
using special sections for initialization and termination functions, this
macro also controls how @file{crtstuff.c} and @file{libgcc2.c} arrange to
run the initialization functions.
+@end defmac
-@item HAS_INIT_SECTION
-@findex HAS_INIT_SECTION
+@defmac HAS_INIT_SECTION
If defined, @code{main} will not call @code{__main} as described above.
This macro should be defined for systems that control start-up code
on a symbol-by-symbol basis, such as OSF/1, and should not
be defined explicitly for systems that support @code{INIT_SECTION_ASM_OP}.
+@end defmac
-@item LD_INIT_SWITCH
-@findex LD_INIT_SWITCH
+@defmac LD_INIT_SWITCH
If defined, a C string constant for a switch that tells the linker that
the following symbol is an initialization routine.
+@end defmac
-@item LD_FINI_SWITCH
-@findex LD_FINI_SWITCH
+@defmac LD_FINI_SWITCH
If defined, a C string constant for a switch that tells the linker that
the following symbol is a finalization routine.
+@end defmac
-@item COLLECT_SHARED_INIT_FUNC (@var{stream}, @var{func})
+@defmac COLLECT_SHARED_INIT_FUNC (@var{stream}, @var{func})
If defined, a C statement that will write a function that can be
automatically called when a shared library is loaded. The function
should call @var{func}, which takes no arguments. If not defined, and
@@ -7056,28 +7112,29 @@ function called @code{_GLOBAL__DI} will be generated.
This function and the following one are used by collect2 when linking a
shared library that needs constructors or destructors, or has DWARF2
exception tables embedded in the code.
+@end defmac
-@item COLLECT_SHARED_FINI_FUNC (@var{stream}, @var{func})
+@defmac COLLECT_SHARED_FINI_FUNC (@var{stream}, @var{func})
If defined, a C statement that will write a function that can be
automatically called when a shared library is unloaded. The function
should call @var{func}, which takes no arguments. If not defined, and
the object format requires an explicit finalization function, then a
function called @code{_GLOBAL__DD} will be generated.
+@end defmac
-@item INVOKE__main
-@findex INVOKE__main
+@defmac INVOKE__main
If defined, @code{main} will call @code{__main} despite the presence of
@code{INIT_SECTION_ASM_OP}. This macro should be defined for systems
where the init section is not actually run automatically, but is still
useful for collecting the lists of constructors and destructors.
+@end defmac
-@item SUPPORTS_INIT_PRIORITY
-@findex SUPPORTS_INIT_PRIORITY
+@defmac SUPPORTS_INIT_PRIORITY
If nonzero, the C++ @code{init_priority} attribute is supported and the
compiler should emit instructions to control the order of initialization
of objects. If zero, the compiler will issue an error message upon
encountering an @code{init_priority} attribute.
-@end table
+@end defmac
@deftypefn {Target Hook} bool TARGET_HAVE_CTORS_DTORS
This value is true if the target supports some ``native'' method of
@@ -7112,27 +7169,25 @@ If your system uses @command{collect2} as the means of processing
constructors, then that program normally uses @command{nm} to scan
an object file for constructor functions to be called.
-On certain kinds of systems, you can define these macros to make
+On certain kinds of systems, you can define this macro to make
@command{collect2} work faster (and, in some cases, make it work at all):
-@table @code
-@findex OBJECT_FORMAT_COFF
-@item OBJECT_FORMAT_COFF
+@defmac OBJECT_FORMAT_COFF
Define this macro if the system uses COFF (Common Object File Format)
object files, so that @command{collect2} can assume this format and scan
object files directly for dynamic constructor/destructor functions.
-@findex OBJECT_FORMAT_ROSE
-@item OBJECT_FORMAT_ROSE
-Define this macro if the system uses ROSE format object files, so that
-@command{collect2} can assume this format and scan object files directly
-for dynamic constructor/destructor functions.
-
-These macros are effective only in a native compiler; @command{collect2} as
+This macro is effective only in a native compiler; @command{collect2} as
part of a cross compiler always uses @command{nm} for the target machine.
+@end defmac
+
+@defmac COLLECT_PARSE_FLAG (@var{flag})
+Define this macro to be C code that examines @command{collect2} command
+line option @var{flag} and performs special actions if
+@command{collect2} needs to behave differently depending on @var{flag}.
+@end defmac
-@findex REAL_NM_FILE_NAME
-@item REAL_NM_FILE_NAME
+@defmac REAL_NM_FILE_NAME
Define this macro as a C string constant containing the file name to use
to execute @command{nm}. The default is to search the path normally for
@command{nm}.
@@ -7141,21 +7196,21 @@ If your system supports shared libraries and has a program to list the
dynamic dependencies of a given library or executable, you can define
these macros to enable support for running initialization and
termination functions in shared libraries:
+@end defmac
-@findex LDD_SUFFIX
-@item LDD_SUFFIX
+@defmac LDD_SUFFIX
Define this macro to a C string constant containing the name of the program
which lists dynamic dependencies, like @command{"ldd"} under SunOS 4.
+@end defmac
-@findex PARSE_LDD_OUTPUT
-@item PARSE_LDD_OUTPUT (@var{ptr})
+@defmac PARSE_LDD_OUTPUT (@var{ptr})
Define this macro to be C code that extracts filenames from the output
of the program denoted by @code{LDD_SUFFIX}. @var{ptr} is a variable
of type @code{char *} that points to the beginning of a line of output
from @code{LDD_SUFFIX}. If the line lists a dynamic dependency, the
code must advance @var{ptr} to the beginning of the filename on that
line. Otherwise, it must set @var{ptr} to @code{NULL}.
-@end table
+@end defmac
@node Instruction Output
@subsection Output of Assembler Instructions
@@ -7163,22 +7218,20 @@ line. Otherwise, it must set @var{ptr} to @code{NULL}.
@c prevent bad page break with this line
This describes assembler instruction output.
-@table @code
-@findex REGISTER_NAMES
-@item REGISTER_NAMES
+@defmac REGISTER_NAMES
A C initializer containing the assembler's names for the machine
registers, each one as a C string constant. This is what translates
register numbers in the compiler into assembler language.
+@end defmac
-@findex ADDITIONAL_REGISTER_NAMES
-@item ADDITIONAL_REGISTER_NAMES
+@defmac ADDITIONAL_REGISTER_NAMES
If defined, a C initializer for an array of structures containing a name
and a register number. This macro defines additional names for hard
registers, thus allowing the @code{asm} option in declarations to refer
to registers using alternate names.
+@end defmac
-@findex ASM_OUTPUT_OPCODE
-@item ASM_OUTPUT_OPCODE (@var{stream}, @var{ptr})
+@defmac ASM_OUTPUT_OPCODE (@var{stream}, @var{ptr})
Define this macro if you are using an unusual assembler that
requires different names for the machine instructions.
@@ -7203,9 +7256,9 @@ elements of @code{recog_data.operand}.
If the macro definition does nothing, the instruction is output
in the usual way.
+@end defmac
-@findex FINAL_PRESCAN_INSN
-@item FINAL_PRESCAN_INSN (@var{insn}, @var{opvec}, @var{noperands})
+@defmac FINAL_PRESCAN_INSN (@var{insn}, @var{opvec}, @var{noperands})
If defined, a C statement to be executed just prior to the output of
assembler code for @var{insn}, to modify the extracted operands so
they will be output differently.
@@ -7225,15 +7278,9 @@ syntax affecting individual insn patterns ought to be handled by
writing conditional output routines in those patterns.
If this macro is not defined, it is equivalent to a null statement.
+@end defmac
-@findex FINAL_PRESCAN_LABEL
-@item FINAL_PRESCAN_LABEL
-If defined, @code{FINAL_PRESCAN_INSN} will be called on each
-@code{CODE_LABEL}. In that case, @var{opvec} will be a null pointer and
-@var{noperands} will be zero.
-
-@findex PRINT_OPERAND
-@item PRINT_OPERAND (@var{stream}, @var{x}, @var{code})
+@defmac PRINT_OPERAND (@var{stream}, @var{x}, @var{code})
A C compound statement to output to stdio stream @var{stream} the
assembler syntax for an instruction operand @var{x}. @var{x} is an
RTL expression.
@@ -7256,17 +7303,17 @@ When the machine description has a specification @samp{%@var{punct}}
(a @samp{%} followed by a punctuation character), this macro is called
with a null pointer for @var{x} and the punctuation character for
@var{code}.
+@end defmac
-@findex PRINT_OPERAND_PUNCT_VALID_P
-@item PRINT_OPERAND_PUNCT_VALID_P (@var{code})
+@defmac PRINT_OPERAND_PUNCT_VALID_P (@var{code})
A C expression which evaluates to true if @var{code} is a valid
punctuation character for use in the @code{PRINT_OPERAND} macro. If
@code{PRINT_OPERAND_PUNCT_VALID_P} is not defined, it means that no
punctuation characters (except for the standard one, @samp{%}) are used
in this way.
+@end defmac
-@findex PRINT_OPERAND_ADDRESS
-@item PRINT_OPERAND_ADDRESS (@var{stream}, @var{x})
+@defmac PRINT_OPERAND_ADDRESS (@var{stream}, @var{x})
A C compound statement to output to stdio stream @var{stream} the
assembler syntax for an instruction operand that is a memory reference
whose address is @var{x}. @var{x} is an RTL expression.
@@ -7275,11 +7322,12 @@ whose address is @var{x}. @var{x} is an RTL expression.
On some machines, the syntax for a symbolic address depends on the
section that the address refers to. On these machines, define the hook
@code{TARGET_ENCODE_SECTION_INFO} to store the information into the
-@code{symbol_ref}, and then check for it here. @xref{Assembler Format}.
+@code{symbol_ref}, and then check for it here. @xref{Assembler
+Format}.
+@end defmac
-@findex DBR_OUTPUT_SEQEND
@findex dbr_sequence_length
-@item DBR_OUTPUT_SEQEND(@var{file})
+@defmac DBR_OUTPUT_SEQEND (@var{file})
A C statement, to be executed after all slot-filler instructions have
been output. If necessary, call @code{dbr_sequence_length} to
determine the number of slots filled in a sequence (zero if not
@@ -7289,6 +7337,7 @@ or whatever.
Don't define this macro if it has nothing to do, but it is helpful in
reading assembly output if the extent of the delay sequence is made
explicit (e.g.@: with white space).
+@end defmac
@findex final_sequence
Note that output routines for instructions with delay slots must be
@@ -7298,36 +7347,32 @@ found.) The variable @code{final_sequence} is null when not
processing a sequence, otherwise it contains the @code{sequence} rtx
being output.
-@findex REGISTER_PREFIX
-@findex LOCAL_LABEL_PREFIX
-@findex USER_LABEL_PREFIX
-@findex IMMEDIATE_PREFIX
@findex asm_fprintf
-@item REGISTER_PREFIX
-@itemx LOCAL_LABEL_PREFIX
-@itemx USER_LABEL_PREFIX
-@itemx IMMEDIATE_PREFIX
+@defmac REGISTER_PREFIX
+@defmacx LOCAL_LABEL_PREFIX
+@defmacx USER_LABEL_PREFIX
+@defmacx IMMEDIATE_PREFIX
If defined, C string expressions to be used for the @samp{%R}, @samp{%L},
@samp{%U}, and @samp{%I} options of @code{asm_fprintf} (see
@file{final.c}). These are useful when a single @file{md} file must
support multiple assembler formats. In that case, the various @file{tm.h}
files can define these macros differently.
+@end defmac
-@item ASM_FPRINTF_EXTENSIONS(@var{file}, @var{argptr}, @var{format})
-@findex ASM_FPRINTF_EXTENSIONS
+@defmac ASM_FPRINTF_EXTENSIONS (@var{file}, @var{argptr}, @var{format})
If defined this macro should expand to a series of @code{case}
statements which will be parsed inside the @code{switch} statement of
the @code{asm_fprintf} function. This allows targets to define extra
printf formats which may useful when generating their assembler
-statements. Note that upper case letters are reserved for future
+statements. Note that uppercase letters are reserved for future
generic extensions to asm_fprintf, and so are not available to target
specific code. The output file is given by the parameter @var{file}.
The varargs input pointer is @var{argptr} and the rest of the format
string, starting the character after the one that is being switched
upon, is pointed to by @var{format}.
+@end defmac
-@findex ASSEMBLER_DIALECT
-@item ASSEMBLER_DIALECT
+@defmac ASSEMBLER_DIALECT
If your target supports multiple dialects of assembler language (such as
different opcodes), define this macro as a C expression that gives the
numeric index of the assembler language dialect to use, with zero as the
@@ -7356,21 +7401,21 @@ the variations in assembler language syntax with that mechanism. Define
@code{ASSEMBLER_DIALECT} and use the @samp{@{option0|option1@}} syntax
if the syntax variant are larger and involve such things as different
opcodes or operand order.
+@end defmac
-@findex ASM_OUTPUT_REG_PUSH
-@item ASM_OUTPUT_REG_PUSH (@var{stream}, @var{regno})
+@defmac ASM_OUTPUT_REG_PUSH (@var{stream}, @var{regno})
A C expression to output to @var{stream} some assembler code
which will push hard register number @var{regno} onto the stack.
The code need not be optimal, since this macro is used only when
profiling.
+@end defmac
-@findex ASM_OUTPUT_REG_POP
-@item ASM_OUTPUT_REG_POP (@var{stream}, @var{regno})
+@defmac ASM_OUTPUT_REG_POP (@var{stream}, @var{regno})
A C expression to output to @var{stream} some assembler code
which will pop hard register number @var{regno} off of the stack.
The code need not be optimal, since this macro is used only when
profiling.
-@end table
+@end defmac
@node Dispatch Tables
@subsection Output of Dispatch Tables
@@ -7378,48 +7423,46 @@ profiling.
@c prevent bad page break with this line
This concerns dispatch tables.
-@table @code
@cindex dispatch table
-@findex ASM_OUTPUT_ADDR_DIFF_ELT
-@item ASM_OUTPUT_ADDR_DIFF_ELT (@var{stream}, @var{body}, @var{value}, @var{rel})
+@defmac ASM_OUTPUT_ADDR_DIFF_ELT (@var{stream}, @var{body}, @var{value}, @var{rel})
A C statement to output to the stdio stream @var{stream} an assembler
pseudo-instruction to generate a difference between two labels.
@var{value} and @var{rel} are the numbers of two internal labels. The
definitions of these labels are output using
-@code{ASM_OUTPUT_INTERNAL_LABEL}, and they must be printed in the same
+@code{(*targetm.asm_out.internal_label)}, and they must be printed in the same
way here. For example,
-@example
+@smallexample
fprintf (@var{stream}, "\t.word L%d-L%d\n",
@var{value}, @var{rel})
-@end example
+@end smallexample
You must provide this macro on machines where the addresses in a
dispatch table are relative to the table's own address. If defined, GCC
will also use this macro on all machines when producing PIC@.
@var{body} is the body of the @code{ADDR_DIFF_VEC}; it is provided so that the
mode and flags can be read.
+@end defmac
-@findex ASM_OUTPUT_ADDR_VEC_ELT
-@item ASM_OUTPUT_ADDR_VEC_ELT (@var{stream}, @var{value})
+@defmac ASM_OUTPUT_ADDR_VEC_ELT (@var{stream}, @var{value})
This macro should be provided on machines where the addresses
in a dispatch table are absolute.
The definition should be a C statement to output to the stdio stream
@var{stream} an assembler pseudo-instruction to generate a reference to
a label. @var{value} is the number of an internal label whose
-definition is output using @code{ASM_OUTPUT_INTERNAL_LABEL}.
+definition is output using @code{(*targetm.asm_out.internal_label)}.
For example,
-@example
+@smallexample
fprintf (@var{stream}, "\t.word L%d\n", @var{value})
-@end example
+@end smallexample
+@end defmac
-@findex ASM_OUTPUT_CASE_LABEL
-@item ASM_OUTPUT_CASE_LABEL (@var{stream}, @var{prefix}, @var{num}, @var{table})
+@defmac ASM_OUTPUT_CASE_LABEL (@var{stream}, @var{prefix}, @var{num}, @var{table})
Define this if the label before a jump-table needs to be output
specially. The first three arguments are the same as for
-@code{ASM_OUTPUT_INTERNAL_LABEL}; the fourth argument is the
+@code{(*targetm.asm_out.internal_label)}; the fourth argument is the
jump-table which follows (a @code{jump_insn} containing an
@code{addr_vec} or @code{addr_diff_vec}).
@@ -7427,10 +7470,10 @@ This feature is used on system V to output a @code{swbeg} statement
for the table.
If this macro is not defined, these labels are output with
-@code{ASM_OUTPUT_INTERNAL_LABEL}.
+@code{(*targetm.asm_out.internal_label)}.
+@end defmac
-@findex ASM_OUTPUT_CASE_END
-@item ASM_OUTPUT_CASE_END (@var{stream}, @var{num}, @var{table})
+@defmac ASM_OUTPUT_CASE_END (@var{stream}, @var{num}, @var{table})
Define this if something special must be output at the end of a
jump-table. The definition should be a C statement to be executed
after the assembler code for the table is written. It should write
@@ -7440,7 +7483,7 @@ of the preceding label.
If this macro is not defined, nothing special is output at the end of
the jump-table.
-@end table
+@end defmac
@node Exception Region Output
@subsection Assembler Commands for Exception Regions
@@ -7450,9 +7493,7 @@ the jump-table.
This describes commands marking the start and the end of an exception
region.
-@table @code
-@findex EH_FRAME_SECTION_NAME
-@item EH_FRAME_SECTION_NAME
+@defmac EH_FRAME_SECTION_NAME
If defined, a C string constant for the name of the section containing
exception handling frame unwind information. If not defined, GCC will
provide a default definition if the target supports named sections.
@@ -7460,9 +7501,9 @@ provide a default definition if the target supports named sections.
You should define this symbol if your target supports DWARF 2 frame
unwind information and the default definition does not work.
+@end defmac
-@findex EH_FRAME_IN_DATA_SECTION
-@item EH_FRAME_IN_DATA_SECTION
+@defmac EH_FRAME_IN_DATA_SECTION
If defined, DWARF 2 frame unwind information will be placed in the
data section even though the target supports named sections. This
might be necessary, for instance, if the system linker does garbage
@@ -7470,14 +7511,14 @@ collection and sections cannot be marked as not to be collected.
Do not define this macro unless @code{TARGET_ASM_NAMED_SECTION} is
also defined.
+@end defmac
-@findex MASK_RETURN_ADDR
-@item MASK_RETURN_ADDR
+@defmac MASK_RETURN_ADDR
An rtx used to mask the return address found via @code{RETURN_ADDR_RTX}, so
that it does not contain any extraneous set bits in it.
+@end defmac
-@findex DWARF2_UNWIND_INFO
-@item DWARF2_UNWIND_INFO
+@defmac DWARF2_UNWIND_INFO
Define this macro to 0 if your target supports DWARF 2 frame unwind
information, but it does not yet work with exception handling.
Otherwise, if your target supports this information (if it defines
@@ -7491,17 +7532,23 @@ default.
If this macro is defined to anything, the DWARF 2 unwinder will be used
instead of inline unwinders and @code{__unwind_function} in the non-@code{setjmp} case.
+@end defmac
+
+@defmac MUST_USE_SJLJ_EXCEPTIONS
+This macro need only be defined if @code{DWARF2_UNWIND_INFO} is
+runtime-variable. In that case, @file{except.h} cannot correctly
+determine the corresponding definition of
+@code{MUST_USE_SJLJ_EXCEPTIONS}, so the target must provide it directly.
+@end defmac
-@findex DWARF_CIE_DATA_ALIGNMENT
-@item DWARF_CIE_DATA_ALIGNMENT
+@defmac DWARF_CIE_DATA_ALIGNMENT
This macro need only be defined if the target might save registers in the
function prologue at an offset to the stack pointer that is not aligned to
@code{UNITS_PER_WORD}. The definition should be the negative minimum
alignment if @code{STACK_GROWS_DOWNWARD} is defined, and the positive
minimum alignment otherwise. @xref{SDB and DWARF}. Only applicable if
the target supports DWARF 2 frame unwind information.
-
-@end table
+@end defmac
@deftypefn {Target Hook} void TARGET_ASM_EXCEPTION_SECTION ()
If defined, a function that switches to the section in which the main
@@ -7528,15 +7575,22 @@ Default value is false if @code{EH_FRAME_SECTION_NAME} is defined, and
true otherwise.
@end deftypevar
+@deftypefn {Target Hook} rtx TARGET_DWARF_REGISTER_SPAN (rtx @var{reg})
+Given a register, this hook should return a parallel of registers to
+represent where to find the register pieces. Define this hook if the
+register and its mode are represented in Dwarf in non-contiguous
+locations, or if the register should be represented in more than one
+register in Dwarf. Otherwise, this hook should return @code{NULL_RTX}.
+If not defined, the default is to return @code{NULL_RTX}.
+@end deftypefn
+
@node Alignment Output
@subsection Assembler Commands for Alignment
@c prevent bad page break with this line
This describes commands for alignment.
-@table @code
-@findex JUMP_ALIGN
-@item JUMP_ALIGN (@var{label})
+@defmac JUMP_ALIGN (@var{label})
The alignment (log base 2) to put in front of @var{label}, which is
a common destination of jumps and has no fallthru incoming edge.
@@ -7548,24 +7602,24 @@ Unless it's necessary to inspect the @var{label} parameter, it is better
to set the variable @var{align_jumps} in the target's
@code{OVERRIDE_OPTIONS}. Otherwise, you should try to honor the user's
selection in @var{align_jumps} in a @code{JUMP_ALIGN} implementation.
+@end defmac
-@findex LABEL_ALIGN_AFTER_BARRIER
-@item LABEL_ALIGN_AFTER_BARRIER (@var{label})
+@defmac LABEL_ALIGN_AFTER_BARRIER (@var{label})
The alignment (log base 2) to put in front of @var{label}, which follows
a @code{BARRIER}.
This macro need not be defined if you don't want any special alignment
to be done at such a time. Most machine descriptions do not currently
define the macro.
+@end defmac
-@findex LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP
-@item LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP
+@defmac LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP
The maximum number of bytes to skip when applying
@code{LABEL_ALIGN_AFTER_BARRIER}. This works only if
@code{ASM_OUTPUT_MAX_SKIP_ALIGN} is defined.
+@end defmac
-@findex LOOP_ALIGN
-@item LOOP_ALIGN (@var{label})
+@defmac LOOP_ALIGN (@var{label})
The alignment (log base 2) to put in front of @var{label}, which follows
a @code{NOTE_INSN_LOOP_BEG} note.
@@ -7577,14 +7631,14 @@ Unless it's necessary to inspect the @var{label} parameter, it is better
to set the variable @code{align_loops} in the target's
@code{OVERRIDE_OPTIONS}. Otherwise, you should try to honor the user's
selection in @code{align_loops} in a @code{LOOP_ALIGN} implementation.
+@end defmac
-@findex LOOP_ALIGN_MAX_SKIP
-@item LOOP_ALIGN_MAX_SKIP
+@defmac LOOP_ALIGN_MAX_SKIP
The maximum number of bytes to skip when applying @code{LOOP_ALIGN}.
This works only if @code{ASM_OUTPUT_MAX_SKIP_ALIGN} is defined.
+@end defmac
-@findex LABEL_ALIGN
-@item LABEL_ALIGN (@var{label})
+@defmac LABEL_ALIGN (@var{label})
The alignment (log base 2) to put in front of @var{label}.
If @code{LABEL_ALIGN_AFTER_BARRIER} / @code{LOOP_ALIGN} specify a different alignment,
the maximum of the specified values is used.
@@ -7593,46 +7647,46 @@ Unless it's necessary to inspect the @var{label} parameter, it is better
to set the variable @code{align_labels} in the target's
@code{OVERRIDE_OPTIONS}. Otherwise, you should try to honor the user's
selection in @code{align_labels} in a @code{LABEL_ALIGN} implementation.
+@end defmac
-@findex LABEL_ALIGN_MAX_SKIP
-@item LABEL_ALIGN_MAX_SKIP
+@defmac LABEL_ALIGN_MAX_SKIP
The maximum number of bytes to skip when applying @code{LABEL_ALIGN}.
This works only if @code{ASM_OUTPUT_MAX_SKIP_ALIGN} is defined.
+@end defmac
-@findex ASM_OUTPUT_SKIP
-@item ASM_OUTPUT_SKIP (@var{stream}, @var{nbytes})
+@defmac ASM_OUTPUT_SKIP (@var{stream}, @var{nbytes})
A C statement to output to the stdio stream @var{stream} an assembler
instruction to advance the location counter by @var{nbytes} bytes.
Those bytes should be zero when loaded. @var{nbytes} will be a C
expression of type @code{int}.
+@end defmac
-@findex ASM_NO_SKIP_IN_TEXT
-@item ASM_NO_SKIP_IN_TEXT
+@defmac ASM_NO_SKIP_IN_TEXT
Define this macro if @code{ASM_OUTPUT_SKIP} should not be used in the
text section because it fails to put zeros in the bytes that are skipped.
This is true on many Unix systems, where the pseudo--op to skip bytes
produces no-op instructions rather than zeros when used in the text
section.
+@end defmac
-@findex ASM_OUTPUT_ALIGN
-@item ASM_OUTPUT_ALIGN (@var{stream}, @var{power})
+@defmac ASM_OUTPUT_ALIGN (@var{stream}, @var{power})
A C statement to output to the stdio stream @var{stream} an assembler
command to advance the location counter to a multiple of 2 to the
@var{power} bytes. @var{power} will be a C expression of type @code{int}.
+@end defmac
-@findex ASM_OUTPUT_ALIGN_WITH_NOP
-@item ASM_OUTPUT_ALIGN_WITH_NOP (@var{stream}, @var{power})
+@defmac ASM_OUTPUT_ALIGN_WITH_NOP (@var{stream}, @var{power})
Like @code{ASM_OUTPUT_ALIGN}, except that the ``nop'' instruction is used
for padding, if necessary.
+@end defmac
-@findex ASM_OUTPUT_MAX_SKIP_ALIGN
-@item ASM_OUTPUT_MAX_SKIP_ALIGN (@var{stream}, @var{power}, @var{max_skip})
+@defmac ASM_OUTPUT_MAX_SKIP_ALIGN (@var{stream}, @var{power}, @var{max_skip})
A C statement to output to the stdio stream @var{stream} an assembler
command to advance the location counter to a multiple of 2 to the
@var{power} bytes, but only if @var{max_skip} or fewer bytes are needed to
satisfy the alignment request. @var{power} and @var{max_skip} will be
a C expression of type @code{int}.
-@end table
+@end defmac
@need 3000
@node Debugging Info
@@ -7656,9 +7710,7 @@ This describes how to specify debugging information.
@c prevent bad page break with this line
These macros affect all debugging formats.
-@table @code
-@findex DBX_REGISTER_NUMBER
-@item DBX_REGISTER_NUMBER (@var{regno})
+@defmac DBX_REGISTER_NUMBER (@var{regno})
A C expression that returns the DBX register number for the compiler
register number @var{regno}. In the default macro provided, the value
of this expression will be @var{regno} itself. But sometimes there are
@@ -7675,9 +7727,9 @@ expect register pairs to be consecutive in their own numbering scheme.
If you find yourself defining @code{DBX_REGISTER_NUMBER} in way that
does not preserve register pairs, then what you must do instead is
redefine the actual register numbering scheme.
+@end defmac
-@findex DEBUGGER_AUTO_OFFSET
-@item DEBUGGER_AUTO_OFFSET (@var{x})
+@defmac DEBUGGER_AUTO_OFFSET (@var{x})
A C expression that returns the integer offset value for an automatic
variable having address @var{x} (an RTL expression). The default
computation assumes that @var{x} is based on the frame-pointer and
@@ -7685,15 +7737,15 @@ gives the offset from the frame-pointer. This is required for targets
that produce debugging output for DBX or COFF-style debugging output
for SDB and allow the frame-pointer to be eliminated when the
@option{-g} options is used.
+@end defmac
-@findex DEBUGGER_ARG_OFFSET
-@item DEBUGGER_ARG_OFFSET (@var{offset}, @var{x})
+@defmac DEBUGGER_ARG_OFFSET (@var{offset}, @var{x})
A C expression that returns the integer offset value for an argument
having address @var{x} (an RTL expression). The nominal offset is
@var{offset}.
+@end defmac
-@findex PREFERRED_DEBUGGING_TYPE
-@item PREFERRED_DEBUGGING_TYPE
+@defmac PREFERRED_DEBUGGING_TYPE
A C expression that returns the type of debugging output GCC should
produce when the user specifies just @option{-g}. Define
this if you have arranged for GCC to support more than one format of
@@ -7703,16 +7755,14 @@ debugging output. Currently, the allowable values are @code{DBX_DEBUG},
When the user specifies @option{-ggdb}, GCC normally also uses the
value of this macro to select the debugging output format, but with two
-exceptions. If @code{DWARF2_DEBUGGING_INFO} is defined and
-@code{LINKER_DOES_NOT_WORK_WITH_DWARF2} is not defined, GCC uses the
+exceptions. If @code{DWARF2_DEBUGGING_INFO} is defined, GCC uses the
value @code{DWARF2_DEBUG}. Otherwise, if @code{DBX_DEBUGGING_INFO} is
defined, GCC uses @code{DBX_DEBUG}.
The value of this macro only affects the default debugging output; the
user can always get a specific type of output by using @option{-gstabs},
-@option{-gcoff}, @option{-gdwarf-1}, @option{-gdwarf-2}, @option{-gxcoff},
-or @option{-gvms}.
-@end table
+@option{-gcoff}, @option{-gdwarf-2}, @option{-gxcoff}, or @option{-gvms}.
+@end defmac
@node DBX Options
@subsection Specific Options for DBX Output
@@ -7720,61 +7770,59 @@ or @option{-gvms}.
@c prevent bad page break with this line
These are specific options for DBX output.
-@table @code
-@findex DBX_DEBUGGING_INFO
-@item DBX_DEBUGGING_INFO
+@defmac DBX_DEBUGGING_INFO
Define this macro if GCC should produce debugging output for DBX
in response to the @option{-g} option.
+@end defmac
-@findex XCOFF_DEBUGGING_INFO
-@item XCOFF_DEBUGGING_INFO
+@defmac XCOFF_DEBUGGING_INFO
Define this macro if GCC should produce XCOFF format debugging output
in response to the @option{-g} option. This is a variant of DBX format.
+@end defmac
-@findex DEFAULT_GDB_EXTENSIONS
-@item DEFAULT_GDB_EXTENSIONS
+@defmac DEFAULT_GDB_EXTENSIONS
Define this macro to control whether GCC should by default generate
GDB's extended version of DBX debugging information (assuming DBX-format
debugging information is enabled at all). If you don't define the
macro, the default is 1: always generate the extended information
if there is any occasion to.
+@end defmac
-@findex DEBUG_SYMS_TEXT
-@item DEBUG_SYMS_TEXT
+@defmac DEBUG_SYMS_TEXT
Define this macro if all @code{.stabs} commands should be output while
in the text section.
+@end defmac
-@findex ASM_STABS_OP
-@item ASM_STABS_OP
+@defmac ASM_STABS_OP
A C string constant, including spacing, naming the assembler pseudo op to
use instead of @code{"\t.stabs\t"} to define an ordinary debugging symbol.
If you don't define this macro, @code{"\t.stabs\t"} is used. This macro
applies only to DBX debugging information format.
+@end defmac
-@findex ASM_STABD_OP
-@item ASM_STABD_OP
+@defmac ASM_STABD_OP
A C string constant, including spacing, naming the assembler pseudo op to
use instead of @code{"\t.stabd\t"} to define a debugging symbol whose
value is the current location. If you don't define this macro,
@code{"\t.stabd\t"} is used. This macro applies only to DBX debugging
information format.
+@end defmac
-@findex ASM_STABN_OP
-@item ASM_STABN_OP
+@defmac ASM_STABN_OP
A C string constant, including spacing, naming the assembler pseudo op to
use instead of @code{"\t.stabn\t"} to define a debugging symbol with no
name. If you don't define this macro, @code{"\t.stabn\t"} is used. This
macro applies only to DBX debugging information format.
+@end defmac
-@findex DBX_NO_XREFS
-@item DBX_NO_XREFS
+@defmac DBX_NO_XREFS
Define this macro if DBX on your system does not support the construct
@samp{xs@var{tagname}}. On some systems, this construct is used to
describe a forward reference to a structure named @var{tagname}.
On other systems, this construct is not supported at all.
+@end defmac
-@findex DBX_CONTIN_LENGTH
-@item DBX_CONTIN_LENGTH
+@defmac DBX_CONTIN_LENGTH
A symbol name in DBX-format debugging information is normally
continued (split into two separate @code{.stabs} directives) when it
exceeds a certain length (by default, 80 characters). On some
@@ -7782,78 +7830,71 @@ operating systems, DBX requires this splitting; on others, splitting
must not be done. You can inhibit splitting by defining this macro
with the value zero. You can override the default splitting-length by
defining this macro as an expression for the length you desire.
+@end defmac
-@findex DBX_CONTIN_CHAR
-@item DBX_CONTIN_CHAR
+@defmac DBX_CONTIN_CHAR
Normally continuation is indicated by adding a @samp{\} character to
the end of a @code{.stabs} string when a continuation follows. To use
a different character instead, define this macro as a character
constant for the character you want to use. Do not define this macro
if backslash is correct for your system.
+@end defmac
-@findex DBX_STATIC_STAB_DATA_SECTION
-@item DBX_STATIC_STAB_DATA_SECTION
+@defmac DBX_STATIC_STAB_DATA_SECTION
Define this macro if it is necessary to go to the data section before
outputting the @samp{.stabs} pseudo-op for a non-global static
variable.
+@end defmac
-@findex DBX_TYPE_DECL_STABS_CODE
-@item DBX_TYPE_DECL_STABS_CODE
+@defmac DBX_TYPE_DECL_STABS_CODE
The value to use in the ``code'' field of the @code{.stabs} directive
for a typedef. The default is @code{N_LSYM}.
+@end defmac
-@findex DBX_STATIC_CONST_VAR_CODE
-@item DBX_STATIC_CONST_VAR_CODE
+@defmac DBX_STATIC_CONST_VAR_CODE
The value to use in the ``code'' field of the @code{.stabs} directive
for a static variable located in the text section. DBX format does not
provide any ``right'' way to do this. The default is @code{N_FUN}.
+@end defmac
-@findex DBX_REGPARM_STABS_CODE
-@item DBX_REGPARM_STABS_CODE
+@defmac DBX_REGPARM_STABS_CODE
The value to use in the ``code'' field of the @code{.stabs} directive
for a parameter passed in registers. DBX format does not provide any
``right'' way to do this. The default is @code{N_RSYM}.
+@end defmac
-@findex DBX_REGPARM_STABS_LETTER
-@item DBX_REGPARM_STABS_LETTER
+@defmac DBX_REGPARM_STABS_LETTER
The letter to use in DBX symbol data to identify a symbol as a parameter
passed in registers. DBX format does not customarily provide any way to
do this. The default is @code{'P'}.
+@end defmac
-@findex DBX_MEMPARM_STABS_LETTER
-@item DBX_MEMPARM_STABS_LETTER
+@defmac DBX_MEMPARM_STABS_LETTER
The letter to use in DBX symbol data to identify a symbol as a stack
parameter. The default is @code{'p'}.
+@end defmac
-@findex DBX_FUNCTION_FIRST
-@item DBX_FUNCTION_FIRST
+@defmac DBX_FUNCTION_FIRST
Define this macro if the DBX information for a function and its
arguments should precede the assembler code for the function. Normally,
in DBX format, the debugging information entirely follows the assembler
code.
+@end defmac
-@findex DBX_LBRAC_FIRST
-@item DBX_LBRAC_FIRST
-Define this macro if the @code{N_LBRAC} symbol for a block should
-precede the debugging information for variables and functions defined in
-that block. Normally, in DBX format, the @code{N_LBRAC} symbol comes
-first.
-
-@findex DBX_BLOCKS_FUNCTION_RELATIVE
-@item DBX_BLOCKS_FUNCTION_RELATIVE
+@defmac DBX_BLOCKS_FUNCTION_RELATIVE
Define this macro if the value of a symbol describing the scope of a
block (@code{N_LBRAC} or @code{N_RBRAC}) should be relative to the start
of the enclosing function. Normally, GCC uses an absolute address.
+@end defmac
-@findex DBX_USE_BINCL
-@item DBX_USE_BINCL
+@defmac DBX_USE_BINCL
Define this macro if GCC should generate @code{N_BINCL} and
@code{N_EINCL} stabs for included header files, as on Sun systems. This
macro also directs GCC to output a type number as a pair of a file
number and a type number within the file. Normally, GCC does not
generate @code{N_BINCL} or @code{N_EINCL} stabs, and it outputs a single
number for a type number.
-@end table
+@end defmac
@node DBX Hooks
@subsection Open-Ended Hooks for DBX Format
@@ -7861,40 +7902,31 @@ number for a type number.
@c prevent bad page break with this line
These are hooks for DBX format.
-@table @code
-@findex DBX_OUTPUT_LBRAC
-@item DBX_OUTPUT_LBRAC (@var{stream}, @var{name})
+@defmac DBX_OUTPUT_LBRAC (@var{stream}, @var{name})
Define this macro to say how to output to @var{stream} the debugging
information for the start of a scope level for variable names. The
argument @var{name} is the name of an assembler symbol (for use with
@code{assemble_name}) whose value is the address where the scope begins.
+@end defmac
-@findex DBX_OUTPUT_RBRAC
-@item DBX_OUTPUT_RBRAC (@var{stream}, @var{name})
+@defmac DBX_OUTPUT_RBRAC (@var{stream}, @var{name})
Like @code{DBX_OUTPUT_LBRAC}, but for the end of a scope level.
+@end defmac
-@findex DBX_OUTPUT_NFUN
-@item DBX_OUTPUT_NFUN (@var{stream}, @var{lscope_label}, @var{decl})
+@defmac DBX_OUTPUT_NFUN (@var{stream}, @var{lscope_label}, @var{decl})
Define this macro if the target machine requires special handling to
output an @code{N_FUN} entry for the function @var{decl}.
+@end defmac
-@findex DBX_OUTPUT_ENUM
-@item DBX_OUTPUT_ENUM (@var{stream}, @var{type})
-Define this macro if the target machine requires special handling to
-output an enumeration type. The definition should be a C statement
-(sans semicolon) to output the appropriate information to @var{stream}
-for the type @var{type}.
-
-@findex DBX_OUTPUT_FUNCTION_END
-@item DBX_OUTPUT_FUNCTION_END (@var{stream}, @var{function})
+@defmac DBX_OUTPUT_FUNCTION_END (@var{stream}, @var{function})
Define this macro if the target machine requires special output at the
end of the debugging information for a function. The definition should
be a C statement (sans semicolon) to output the appropriate information
to @var{stream}. @var{function} is the @code{FUNCTION_DECL} node for
the function.
+@end defmac
-@findex DBX_OUTPUT_STANDARD_TYPES
-@item DBX_OUTPUT_STANDARD_TYPES (@var{syms})
+@defmac DBX_OUTPUT_STANDARD_TYPES (@var{syms})
Define this macro if you need to control the order of output of the
standard data types at the beginning of compilation. The argument
@var{syms} is a @code{tree} which is a chain of all the predefined
@@ -7951,15 +7983,14 @@ Here is another way of finding a particular type:
@}
@end group
@end smallexample
+@end defmac
-@findex NO_DBX_FUNCTION_END
-@item NO_DBX_FUNCTION_END
+@defmac NO_DBX_FUNCTION_END
Some stabs encapsulation formats (in particular ECOFF), cannot handle the
@code{.stabs "",N_FUN,,0,0,Lscope-function-1} gdb dbx extension construct.
On those machines, define this macro to turn this feature off without
disturbing the rest of the gdb extensions.
-
-@end table
+@end defmac
@node File Names and DBX
@subsection File Names in DBX Format
@@ -7967,17 +7998,7 @@ disturbing the rest of the gdb extensions.
@c prevent bad page break with this line
This describes file names in DBX format.
-@table @code
-@findex DBX_WORKING_DIRECTORY
-@item DBX_WORKING_DIRECTORY
-Define this if DBX wants to have the current directory recorded in each
-object file.
-
-Note that the working directory is always recorded if GDB extensions are
-enabled.
-
-@findex DBX_OUTPUT_MAIN_SOURCE_FILENAME
-@item DBX_OUTPUT_MAIN_SOURCE_FILENAME (@var{stream}, @var{name})
+@defmac DBX_OUTPUT_MAIN_SOURCE_FILENAME (@var{stream}, @var{name})
A C statement to output DBX debugging information to the stdio stream
@var{stream} which indicates that file @var{name} is the main source
file---the file specified as the input file for compilation.
@@ -7985,35 +8006,24 @@ This macro is called only once, at the beginning of compilation.
This macro need not be defined if the standard form of output
for DBX debugging information is appropriate.
+@end defmac
-@findex DBX_OUTPUT_MAIN_SOURCE_DIRECTORY
-@item DBX_OUTPUT_MAIN_SOURCE_DIRECTORY (@var{stream}, @var{name})
+@defmac DBX_OUTPUT_MAIN_SOURCE_DIRECTORY (@var{stream}, @var{name})
A C statement to output DBX debugging information to the stdio stream
@var{stream} which indicates that the current directory during
compilation is named @var{name}.
This macro need not be defined if the standard form of output
for DBX debugging information is appropriate.
+@end defmac
-@findex DBX_OUTPUT_MAIN_SOURCE_FILE_END
-@item DBX_OUTPUT_MAIN_SOURCE_FILE_END (@var{stream}, @var{name})
+@defmac DBX_OUTPUT_MAIN_SOURCE_FILE_END (@var{stream}, @var{name})
A C statement to output DBX debugging information at the end of
compilation of the main source file @var{name}.
If you don't define this macro, nothing special is output at the end
of compilation, which is correct for most machines.
-
-@findex DBX_OUTPUT_SOURCE_FILENAME
-@item DBX_OUTPUT_SOURCE_FILENAME (@var{stream}, @var{name})
-A C statement to output DBX debugging information to the stdio stream
-@var{stream} which indicates that file @var{name} is the current source
-file. This output is generated each time input shifts to a different
-source file as a result of @samp{#include}, the end of an included file,
-or a @samp{#line} command.
-
-This macro need not be defined if the standard form of output
-for DBX debugging information is appropriate.
-@end table
+@end defmac
@need 2000
@node SDB and DWARF
@@ -8022,19 +8032,12 @@ for DBX debugging information is appropriate.
@c prevent bad page break with this line
Here are macros for SDB and DWARF output.
-@table @code
-@findex SDB_DEBUGGING_INFO
-@item SDB_DEBUGGING_INFO
+@defmac SDB_DEBUGGING_INFO
Define this macro if GCC should produce COFF-style debugging output
for SDB in response to the @option{-g} option.
+@end defmac
-@findex DWARF_DEBUGGING_INFO
-@item DWARF_DEBUGGING_INFO
-Define this macro if GCC should produce dwarf format debugging output
-in response to the @option{-g} option.
-
-@findex DWARF2_DEBUGGING_INFO
-@item DWARF2_DEBUGGING_INFO
+@defmac DWARF2_DEBUGGING_INFO
Define this macro if GCC should produce dwarf version 2 format
debugging output in response to the @option{-g} option.
@@ -8043,84 +8046,77 @@ define @code{INCOMING_RETURN_ADDR_RTX} and either set
@code{RTX_FRAME_RELATED_P} on the prologue insns if you use RTL for the
prologue, or call @code{dwarf2out_def_cfa} and @code{dwarf2out_reg_save}
as appropriate from @code{TARGET_ASM_FUNCTION_PROLOGUE} if you don't.
+@end defmac
-@findex DWARF2_FRAME_INFO
-@item DWARF2_FRAME_INFO
+@defmac DWARF2_FRAME_INFO
Define this macro to a nonzero value if GCC should always output
Dwarf 2 frame information. If @code{DWARF2_UNWIND_INFO}
(@pxref{Exception Region Output} is nonzero, GCC will output this
information not matter how you define @code{DWARF2_FRAME_INFO}.
+@end defmac
-@findex LINKER_DOES_NOT_WORK_WITH_DWARF2
-@item LINKER_DOES_NOT_WORK_WITH_DWARF2
-Define this macro if the linker does not work with Dwarf version 2.
-Normally, if the user specifies only @option{-ggdb} GCC will use Dwarf
-version 2 if available; this macro disables this. See the description
-of the @code{PREFERRED_DEBUGGING_TYPE} macro for more details.
-
-@findex DWARF2_GENERATE_TEXT_SECTION_LABEL
-@item DWARF2_GENERATE_TEXT_SECTION_LABEL
+@defmac DWARF2_GENERATE_TEXT_SECTION_LABEL
By default, the Dwarf 2 debugging information generator will generate a
label to mark the beginning of the text section. If it is better simply
to use the name of the text section itself, rather than an explicit label,
to indicate the beginning of the text section, define this macro to zero.
+@end defmac
-@findex DWARF2_ASM_LINE_DEBUG_INFO
-@item DWARF2_ASM_LINE_DEBUG_INFO
+@defmac DWARF2_ASM_LINE_DEBUG_INFO
Define this macro to be a nonzero value if the assembler can generate Dwarf 2
line debug info sections. This will result in much more compact line number
tables, and hence is desirable if it works.
+@end defmac
-@findex ASM_OUTPUT_DWARF_DELTA
-@item ASM_OUTPUT_DWARF_DELTA (@var{stream}, @var{size}, @var{label1}, @var{label2})
+@defmac ASM_OUTPUT_DWARF_DELTA (@var{stream}, @var{size}, @var{label1}, @var{label2})
A C statement to issue assembly directives that create a difference
between the two given labels, using an integer of the given size.
+@end defmac
-@findex ASM_OUTPUT_DWARF_OFFSET
-@item ASM_OUTPUT_DWARF_OFFSET (@var{stream}, @var{size}, @var{label})
+@defmac ASM_OUTPUT_DWARF_OFFSET (@var{stream}, @var{size}, @var{label})
A C statement to issue assembly directives that create a
section-relative reference to the given label, using an integer of the
given size.
+@end defmac
-@findex ASM_OUTPUT_DWARF_PCREL
-@item ASM_OUTPUT_DWARF_PCREL (@var{stream}, @var{size}, @var{label})
+@defmac ASM_OUTPUT_DWARF_PCREL (@var{stream}, @var{size}, @var{label})
A C statement to issue assembly directives that create a self-relative
reference to the given label, using an integer of the given size.
+@end defmac
-@findex PUT_SDB_@dots{}
-@item PUT_SDB_@dots{}
+@defmac PUT_SDB_@dots{}
Define these macros to override the assembler syntax for the special
SDB assembler directives. See @file{sdbout.c} for a list of these
macros and their arguments. If the standard syntax is used, you need
not define them yourself.
+@end defmac
-@findex SDB_DELIM
-@item SDB_DELIM
+@defmac SDB_DELIM
Some assemblers do not support a semicolon as a delimiter, even between
SDB assembler directives. In that case, define this macro to be the
delimiter to use (usually @samp{\n}). It is not necessary to define
a new set of @code{PUT_SDB_@var{op}} macros if this is the only change
required.
+@end defmac
-@findex SDB_GENERATE_FAKE
-@item SDB_GENERATE_FAKE
+@defmac SDB_GENERATE_FAKE
Define this macro to override the usual method of constructing a dummy
name for anonymous structure and union types. See @file{sdbout.c} for
more information.
+@end defmac
-@findex SDB_ALLOW_UNKNOWN_REFERENCES
-@item SDB_ALLOW_UNKNOWN_REFERENCES
+@defmac SDB_ALLOW_UNKNOWN_REFERENCES
Define this macro to allow references to unknown structure,
union, or enumeration tags to be emitted. Standard COFF does not
allow handling of unknown references, MIPS ECOFF has support for
it.
+@end defmac
-@findex SDB_ALLOW_FORWARD_REFERENCES
-@item SDB_ALLOW_FORWARD_REFERENCES
+@defmac SDB_ALLOW_FORWARD_REFERENCES
Define this macro to allow references to structure, union, or
enumeration tags that have not yet been seen to be handled. Some
assemblers choke if forward tags are used, while some require it.
-@end table
+@end defmac
@need 2000
@node VMS Debug
@@ -8129,16 +8125,14 @@ assemblers choke if forward tags are used, while some require it.
@c prevent bad page break with this line
Here are macros for VMS debug format.
-@table @code
-@findex VMS_DEBUGGING_INFO
-@item VMS_DEBUGGING_INFO
+@defmac VMS_DEBUGGING_INFO
Define this macro if GCC should produce debugging output for VMS
in response to the @option{-g} option. The default behavior for VMS
is to generate minimal debug info for a traceback in the absence of
@option{-g} unless explicitly overridden with @option{-g0}. This
behavior is controlled by @code{OPTIMIZATION_OPTIONS} and
@code{OVERRIDE_OPTIONS}.
-@end table
+@end defmac
@node Floating Point
@section Cross Compilation and Floating Point
@@ -8247,7 +8241,6 @@ integral, it is truncated.
@end deftypefn
@deftypefn Macro void REAL_VALUE_FROM_INT (REAL_VALUE_TYPE @var{x}, HOST_WIDE_INT @var{low}, HOST_WIDE_INT @var{high}, enum machine_mode @var{mode})
-@findex REAL_VALUE_FROM_INT
Converts a double-precision integer found in @var{low} and @var{high},
into a floating point value which is then stored into @var{x}. The
value is truncated to fit in mode @var{mode}.
@@ -8258,9 +8251,7 @@ value is truncated to fit in mode @var{mode}.
@cindex mode switching
The following macros control mode switching optimizations:
-@table @code
-@findex OPTIMIZE_MODE_SWITCHING
-@item OPTIMIZE_MODE_SWITCHING (@var{entity})
+@defmac OPTIMIZE_MODE_SWITCHING (@var{entity})
Define this macro if the port needs extra instructions inserted for mode
switching in an optimizing compilation.
@@ -8270,7 +8261,7 @@ the FPSCR PR bit has to be cleared, while for a double precision
operation, this bit has to be set. Changing the PR bit requires a general
purpose register as a scratch register, hence these FPSCR sets have to
be inserted before reload, i.e.@: you can't put this into instruction emitting
-or @code{MACHINE_DEPENDENT_REORG}.
+or @code{TARGET_MACHINE_DEPENDENT_REORG}.
You can have multiple entities that are mode-switched, and select at run time
which entities actually need it. @code{OPTIMIZE_MODE_SWITCHING} should
@@ -8278,10 +8269,11 @@ return nonzero for any @var{entity} that needs mode-switching.
If you define this macro, you also have to define
@code{NUM_MODES_FOR_MODE_SWITCHING}, @code{MODE_NEEDED},
@code{MODE_PRIORITY_TO_MODE} and @code{EMIT_MODE_SET}.
-@code{NORMAL_MODE} is optional.
+@code{MODE_AFTER}, @code{MODE_ENTRY}, and @code{MODE_EXIT}
+are optional.
+@end defmac
-@findex NUM_MODES_FOR_MODE_SWITCHING
-@item NUM_MODES_FOR_MODE_SWITCHING
+@defmac NUM_MODES_FOR_MODE_SWITCHING
If you define @code{OPTIMIZE_MODE_SWITCHING}, you have to define this as
initializer for an array of integers. Each initializer element
N refers to an entity that needs mode switching, and specifies the number
@@ -8292,36 +8284,50 @@ entity in question.
In macros that take mode arguments / yield a mode result, modes are
represented as numbers 0 @dots{} N @minus{} 1. N is used to specify that no mode
switch is needed / supplied.
+@end defmac
-@findex MODE_NEEDED
-@item MODE_NEEDED (@var{entity}, @var{insn})
+@defmac MODE_NEEDED (@var{entity}, @var{insn})
@var{entity} is an integer specifying a mode-switched entity. If
@code{OPTIMIZE_MODE_SWITCHING} is defined, you must define this macro to
return an integer value not larger than the corresponding element in
@code{NUM_MODES_FOR_MODE_SWITCHING}, to denote the mode that @var{entity} must
be switched into prior to the execution of @var{insn}.
+@end defmac
+
+@defmac MODE_AFTER (@var{mode}, @var{insn})
+If this macro is defined, it is evaluated for every @var{insn} during
+mode switching. It determines the mode that an insn results in (if
+different from the incoming mode).
+@end defmac
+
+@defmac MODE_ENTRY (@var{entity})
+If this macro is defined, it is evaluated for every @var{entity} that needs
+mode switching. It should evaluate to an integer, which is a mode that
+@var{entity} is assumed to be switched to at function entry. If @code{MODE_ENTRY}
+is defined then @code{MODE_EXIT} must be defined.
+@end defmac
-@findex NORMAL_MODE
-@item NORMAL_MODE (@var{entity})
+@defmac MODE_EXIT (@var{entity})
If this macro is defined, it is evaluated for every @var{entity} that needs
-mode switching. It should evaluate to an integer, which is a mode that
-@var{entity} is assumed to be switched to at function entry and exit.
+mode switching. It should evaluate to an integer, which is a mode that
+@var{entity} is assumed to be switched to at function exit. If @code{MODE_EXIT}
+is defined then @code{MODE_ENTRY} must be defined.
+@end defmac
-@findex MODE_PRIORITY_TO_MODE
-@item MODE_PRIORITY_TO_MODE (@var{entity}, @var{n})
+@defmac MODE_PRIORITY_TO_MODE (@var{entity}, @var{n})
This macro specifies the order in which modes for @var{entity} are processed.
0 is the highest priority, @code{NUM_MODES_FOR_MODE_SWITCHING[@var{entity}] - 1} the
lowest. The value of the macro should be an integer designating a mode
for @var{entity}. For any fixed @var{entity}, @code{mode_priority_to_mode}
(@var{entity}, @var{n}) shall be a bijection in 0 @dots{}
@code{num_modes_for_mode_switching[@var{entity}] - 1}.
+@end defmac
-@findex EMIT_MODE_SET
-@item EMIT_MODE_SET (@var{entity}, @var{mode}, @var{hard_regs_live})
+@defmac EMIT_MODE_SET (@var{entity}, @var{mode}, @var{hard_regs_live})
Generate one or more insns to set @var{entity} to @var{mode}.
@var{hard_reg_live} is the set of hard registers live at the point where
the insn(s) are to be inserted.
-@end table
+@end defmac
@node Target Attributes
@section Defining target-specific uses of @code{__attribute__}
@@ -8374,7 +8380,7 @@ call @code{merge_attributes} to handle machine-independent merging.
@findex TARGET_DLLIMPORT_DECL_ATTRIBUTES
If the only target-specific handling you require is @samp{dllimport} for
-Windows targets, you should define the macro
+Microsoft Windows targets, you should define the macro
@code{TARGET_DLLIMPORT_DECL_ATTRIBUTES}. This links in a function
called @code{merge_dllimport_decl_attributes} which can then be defined
as the expansion of @code{TARGET_MERGE_DECL_ATTRIBUTES}. This is done
@@ -8407,7 +8413,7 @@ target specific attribute attached to it, it will not be inlined.
@cindex MIPS coprocessor-definition macros
The MIPS specification allows MIPS implementations to have as many as 4
-coprocessors, each with as many as 32 private registers. gcc supports
+coprocessors, each with as many as 32 private registers. GCC supports
accessing these registers and transferring values between the registers
and memory using asm-ized variables. For example:
@@ -8433,18 +8439,38 @@ floating-point support; they are not included in this mechanism.
There is one macro used in defining the MIPS coprocessor interface which
you may want to override in subtargets; it is described below.
-@table @code
-
-@item ALL_COP_ADDITIONAL_REGISTER_NAMES
-@findex ALL_COP_ADDITIONAL_REGISTER_NAMES
+@defmac ALL_COP_ADDITIONAL_REGISTER_NAMES
A comma-separated list (with leading comma) of pairs describing the
alternate names of coprocessor registers. The format of each entry should be
@smallexample
@{ @var{alternatename}, @var{register_number}@}
@end smallexample
Default: empty.
+@end defmac
+
+@node PCH Target
+@section Parameters for Precompiled Header Validity Checking
+@cindex parameters, precompiled headers
+
+@deftypefn {Target Hook} void * TARGET_GET_PCH_VALIDITY (size_t * @var{sz})
+Define this hook if your target needs to check a different collection
+of flags than the default, which is every flag defined by
+@code{TARGET_SWITCHES} and @code{TARGET_OPTIONS}. It should return
+some data which will be saved in the PCH file and presented to
+@code{TARGET_PCH_VALID_P} later; it should set @code{SZ} to the size
+of the data.
+@end deftypefn
-@end table
+@deftypefn {Target Hook} const char * TARGET_PCH_VALID_P (const void * @var{data}, size_t @var{sz})
+Define this hook if your target needs to check a different collection of
+flags than the default, which is every flag defined by @code{TARGET_SWITCHES}
+and @code{TARGET_OPTIONS}. It is given data which came from
+@code{TARGET_GET_PCH_VALIDITY} (in this version of this compiler, so there
+is no need for extensive validity checking). It returns @code{NULL} if
+it is safe to load a PCH file with this data, or a suitable error message
+if not. The error message will be presented to the user, so it should
+be localized.
+@end deftypefn
@node Misc
@section Miscellaneous Parameters
@@ -8453,9 +8479,7 @@ Default: empty.
@c prevent bad page break with this line
Here are several miscellaneous parameters.
-@table @code
-@item PREDICATE_CODES
-@findex PREDICATE_CODES
+@defmac PREDICATE_CODES
Define this if you have defined special-purpose predicates in the file
@file{@var{machine}.c}. This macro is called within an initializer of an
array of structures. The first field in the structure is the name of a
@@ -8480,9 +8504,9 @@ patterns.
For each predicate function named in @code{PREDICATE_CODES}, a
declaration will be generated in @file{insn-codes.h}.
+@end defmac
-@item SPECIAL_MODE_PREDICATES
-@findex SPECIAL_MODE_PREDICATES
+@defmac SPECIAL_MODE_PREDICATES
Define this if you have special predicates that know special things
about modes. Genrecog will warn about certain forms of
@code{match_operand} without a mode; if the operand predicate is
@@ -8497,14 +8521,14 @@ for a byte extraction from @code{%ah} etc.).
#define SPECIAL_MODE_PREDICATES \
"ext_register_operand",
@end smallexample
+@end defmac
-@findex CASE_VECTOR_MODE
-@item CASE_VECTOR_MODE
+@defmac CASE_VECTOR_MODE
An alias for a machine mode name. This is the machine mode that
elements of a jump-table should have.
+@end defmac
-@findex CASE_VECTOR_SHORTEN_MODE
-@item CASE_VECTOR_SHORTEN_MODE (@var{min_offset}, @var{max_offset}, @var{body})
+@defmac CASE_VECTOR_SHORTEN_MODE (@var{min_offset}, @var{max_offset}, @var{body})
Optional: return the preferred mode for an @code{addr_diff_vec}
when the minimum and maximum offset are known. If you define this,
it enables extra code in branch shortening to deal with @code{addr_diff_vec}.
@@ -8512,74 +8536,97 @@ To make this work, you also have to define @code{INSN_ALIGN} and
make the alignment for @code{addr_diff_vec} explicit.
The @var{body} argument is provided so that the offset_unsigned and scale
flags can be updated.
+@end defmac
-@findex CASE_VECTOR_PC_RELATIVE
-@item CASE_VECTOR_PC_RELATIVE
+@defmac CASE_VECTOR_PC_RELATIVE
Define this macro to be a C expression to indicate when jump-tables
-should contain relative addresses. If jump-tables never contain
-relative addresses, then you need not define this macro.
+should contain relative addresses. You need not define this macro if
+jump-tables never contain relative addresses, or jump-tables should
+contain relative addresses only when @option{-fPIC} or @option{-fPIC}
+is in effect.
+@end defmac
-@findex CASE_DROPS_THROUGH
-@item CASE_DROPS_THROUGH
+@defmac CASE_DROPS_THROUGH
Define this if control falls through a @code{case} insn when the index
value is out of range. This means the specified default-label is
actually ignored by the @code{case} insn proper.
+@end defmac
-@findex CASE_VALUES_THRESHOLD
-@item CASE_VALUES_THRESHOLD
+@defmac CASE_VALUES_THRESHOLD
Define this to be the smallest number of different values for which it
is best to use a jump-table instead of a tree of conditional branches.
The default is four for machines with a @code{casesi} instruction and
five otherwise. This is best for most machines.
+@end defmac
+
+@defmac CASE_USE_BIT_TESTS
+Define this macro to be a C expression to indicate whether C switch
+statements may be implemented by a sequence of bit tests. This is
+advantageous on processors that can efficiently implement left shift
+of 1 by the number of bits held in a register, but inappropriate on
+targets that would require a loop. By default, this macro returns
+@code{true} if the target defines an @code{ashlsi3} pattern, and
+@code{false} otherwise.
+@end defmac
-@findex WORD_REGISTER_OPERATIONS
-@item WORD_REGISTER_OPERATIONS
+@defmac WORD_REGISTER_OPERATIONS
Define this macro if operations between registers with integral mode
smaller than a word are always performed on the entire register.
Most RISC machines have this property and most CISC machines do not.
+@end defmac
-@findex LOAD_EXTEND_OP
-@item LOAD_EXTEND_OP (@var{mode})
+@defmac LOAD_EXTEND_OP (@var{mem_mode})
Define this macro to be a C expression indicating when insns that read
-memory in @var{mode}, an integral mode narrower than a word, set the
-bits outside of @var{mode} to be either the sign-extension or the
+memory in @var{mem_mode}, an integral mode narrower than a word, set the
+bits outside of @var{mem_mode} to be either the sign-extension or the
zero-extension of the data read. Return @code{SIGN_EXTEND} for values
-of @var{mode} for which the
+of @var{mem_mode} for which the
insn sign-extends, @code{ZERO_EXTEND} for which it zero-extends, and
@code{NIL} for other modes.
-This macro is not called with @var{mode} non-integral or with a width
+This macro is not called with @var{mem_mode} non-integral or with a width
greater than or equal to @code{BITS_PER_WORD}, so you may return any
value in this case. Do not define this macro if it would always return
@code{NIL}. On machines where this macro is defined, you will normally
define it as the constant @code{SIGN_EXTEND} or @code{ZERO_EXTEND}.
-@findex SHORT_IMMEDIATES_SIGN_EXTEND
-@item SHORT_IMMEDIATES_SIGN_EXTEND
+You may return a non-@code{NIL} value even if for some hard registers
+the sign extension is not performed, if for the @code{REGNO_REG_CLASS}
+of these hard registers @code{CANNOT_CHANGE_MODE_CLASS} returns nonzero
+when the @var{from} mode is @var{mem_mode} and the @var{to} mode is any
+integral mode larger than this but not larger than @code{word_mode}.
+
+You must return @code{NIL} if for some hard registers that allow this
+mode, @code{CANNOT_CHANGE_MODE_CLASS} says that they cannot change to
+@code{word_mode}, but that they can change to another integral mode that
+is larger then @var{mem_mode} but still smaller than @code{word_mode}.
+@end defmac
+
+@defmac SHORT_IMMEDIATES_SIGN_EXTEND
Define this macro if loading short immediate values into registers sign
extends.
+@end defmac
-@findex FIXUNS_TRUNC_LIKE_FIX_TRUNC
-@item FIXUNS_TRUNC_LIKE_FIX_TRUNC
+@defmac FIXUNS_TRUNC_LIKE_FIX_TRUNC
Define this macro if the same instructions that convert a floating
point number to a signed fixed point number also convert validly to an
unsigned one.
+@end defmac
-@findex MOVE_MAX
-@item MOVE_MAX
+@defmac MOVE_MAX
The maximum number of bytes that a single instruction can move quickly
between memory and registers or between two memory locations.
+@end defmac
-@findex MAX_MOVE_MAX
-@item MAX_MOVE_MAX
+@defmac MAX_MOVE_MAX
The maximum number of bytes that a single instruction can move quickly
between memory and registers or between two memory locations. If this
is undefined, the default is @code{MOVE_MAX}. Otherwise, it is the
constant value that is the largest value that @code{MOVE_MAX} can have
at run-time.
+@end defmac
-@findex SHIFT_COUNT_TRUNCATED
-@item SHIFT_COUNT_TRUNCATED
+@defmac SHIFT_COUNT_TRUNCATED
A C expression that is nonzero if on this machine the number of bits
actually used for the count of a shift operation is equal to the number
of bits needed to represent the size of the object being shifted. When
@@ -8602,9 +8649,9 @@ such machines. Instead, add patterns to the @file{md} file that include
the implied truncation of the shift instructions.
You need not define this macro if it would always have the value of zero.
+@end defmac
-@findex TRULY_NOOP_TRUNCATION
-@item TRULY_NOOP_TRUNCATION (@var{outprec}, @var{inprec})
+@defmac TRULY_NOOP_TRUNCATION (@var{outprec}, @var{inprec})
A C expression which is nonzero if on this machine it is safe to
``convert'' an integer of @var{inprec} bits to one of @var{outprec}
bits (where @var{outprec} is smaller than @var{inprec}) by merely
@@ -8618,9 +8665,9 @@ When @code{TRULY_NOOP_TRUNCATION} returns 1 for a pair of sizes for
modes for which @code{MODES_TIEABLE_P} is 0, suboptimal code can result.
If this is the case, making @code{TRULY_NOOP_TRUNCATION} return 0 in
such cases may improve things.
+@end defmac
-@findex STORE_FLAG_VALUE
-@item STORE_FLAG_VALUE
+@defmac STORE_FLAG_VALUE
A C expression describing the value returned by a comparison operator
with an integral mode and stored by a store-flag instruction
(@samp{s@var{cond}}) when the condition is true. This description must
@@ -8713,19 +8760,38 @@ and @code{decscc}, respectively, for the patterns which perform
@file{rs6000.md} for some examples. The GNU Superoptizer can be used to
find such instruction sequences on other machines.
-You need not define @code{STORE_FLAG_VALUE} if the machine has no store-flag
-instructions.
+If this macro is not defined, the default value, 1, is used. You need
+not define @code{STORE_FLAG_VALUE} if the machine has no store-flag
+instructions, or if the value generated by these instructions is 1.
+@end defmac
-@findex FLOAT_STORE_FLAG_VALUE
-@item FLOAT_STORE_FLAG_VALUE (@var{mode})
+@defmac FLOAT_STORE_FLAG_VALUE (@var{mode})
A C expression that gives a nonzero @code{REAL_VALUE_TYPE} value that is
returned when comparison operators with floating-point results are true.
Define this macro on machine that have comparison operations that return
floating-point values. If there are no such operations, do not define
this macro.
+@end defmac
-@findex Pmode
-@item Pmode
+@defmac CLZ_DEFINED_VALUE_AT_ZERO (@var{mode}, @var{value})
+@defmacx CTZ_DEFINED_VALUE_AT_ZERO (@var{mode}, @var{value})
+A C expression that evaluates to true if the architecture defines a value
+for @code{clz} or @code{ctz} with a zero operand. If so, @var{value}
+should be set to this value. If this macro is not defined, the value of
+@code{clz} or @code{ctz} is assumed to be undefined.
+
+This macro must be defined if the target's expansion for @code{ffs}
+relies on a particular value to get correct results. Otherwise it
+is not necessary, though it may be used to optimize some corner cases.
+
+Note that regardless of this macro the ``definedness'' of @code{clz}
+and @code{ctz} at zero do @emph{not} extend to the builtin functions
+visible to the user. Thus one may be free to adjust the value at will
+to match the target expansion of these operations without fear of
+breaking the API.
+@end defmac
+
+@defmac Pmode
An alias for the machine mode for pointers. On most machines, define
this to be the integer mode corresponding to the width of a hardware
pointer; @code{SImode} on 32-bit machine or @code{DImode} on 64-bit machines.
@@ -8736,15 +8802,15 @@ The width of @code{Pmode} must be at least as large as the value of
@code{POINTER_SIZE}. If it is not equal, you must define the macro
@code{POINTERS_EXTEND_UNSIGNED} to specify how pointers are extended
to @code{Pmode}.
+@end defmac
-@findex FUNCTION_MODE
-@item FUNCTION_MODE
+@defmac FUNCTION_MODE
An alias for the machine mode used for memory references to functions
being called, in @code{call} RTL expressions. On most machines this
should be @code{QImode}.
+@end defmac
-@findex INTEGRATE_THRESHOLD
-@item INTEGRATE_THRESHOLD (@var{decl})
+@defmac INTEGRATE_THRESHOLD (@var{decl})
A C expression for the maximum number of instructions above which the
function @var{decl} should not be inlined. @var{decl} is a
@code{FUNCTION_DECL} node.
@@ -8752,9 +8818,9 @@ function @var{decl} should not be inlined. @var{decl} is a
The default definition of this macro is 64 plus 8 times the number of
arguments that the function accepts. Some people think a larger
threshold should be used on RISC machines.
+@end defmac
-@findex STDC_0_IN_SYSTEM_HEADERS
-@item STDC_0_IN_SYSTEM_HEADERS
+@defmac STDC_0_IN_SYSTEM_HEADERS
In normal operation, the preprocessor expands @code{__STDC__} to the
constant 1, to signify that GCC conforms to ISO Standard C@. On some
hosts, like Solaris, the system compiler uses a different convention,
@@ -8764,27 +8830,21 @@ strict conformance to the C Standard.
Defining @code{STDC_0_IN_SYSTEM_HEADERS} makes GNU CPP follows the host
convention when processing system header files, but when processing user
files @code{__STDC__} will always expand to 1.
+@end defmac
-@findex NO_IMPLICIT_EXTERN_C
-@item NO_IMPLICIT_EXTERN_C
+@defmac NO_IMPLICIT_EXTERN_C
Define this macro if the system header files support C++ as well as C@.
This macro inhibits the usual method of using system header files in
C++, which is to pretend that the file's contents are enclosed in
@samp{extern "C" @{@dots{}@}}.
+@end defmac
-@findex HANDLE_PRAGMA
-@item HANDLE_PRAGMA (@var{getc}, @var{ungetc}, @var{name})
-This macro is no longer supported. You must use
-@code{REGISTER_TARGET_PRAGMAS} instead.
-
-@findex REGISTER_TARGET_PRAGMAS
@findex #pragma
@findex pragma
-@item REGISTER_TARGET_PRAGMAS (@var{pfile})
+@defmac REGISTER_TARGET_PRAGMAS ()
Define this macro if you want to implement any target-specific pragmas.
If defined, it is a C expression which makes a series of calls to
-@code{cpp_register_pragma} for each pragma, with @var{pfile} passed as
-the first argument to to these functions. The macro may also do any
+@code{c_register_pragma} for each pragma. The macro may also do any
setup required for the pragmas.
The primary reason to define this macro is to provide compatibility with
@@ -8797,10 +8857,11 @@ defining the target hook @samp{TARGET_INSERT_ATTRIBUTES} as well.
Preprocessor macros that appear on pragma lines are not expanded. All
@samp{#pragma} directives that do not match any registered pragma are
silently ignored, unless the user specifies @option{-Wunknown-pragmas}.
+@end defmac
-@deftypefun void cpp_register_pragma (cpp_reader *@var{pfile}, const char *@var{space}, const char *@var{name}, void (*@var{callback}) (cpp_reader *))
+@deftypefun void c_register_pragma (const char *@var{space}, const char *@var{name}, void (*@var{callback}) (struct cpp_reader *))
-Each call to @code{cpp_register_pragma} establishes one pragma. The
+Each call to @code{c_register_pragma} establishes one pragma. The
@var{callback} routine will be called when the preprocessor encounters a
pragma of the form
@@ -8814,7 +8875,7 @@ routine receives @var{pfile} as its first argument, which can be passed
on to cpplib's functions if necessary. You can lex tokens after the
@var{name} by calling @code{c_lex}. Tokens that are not read by the
callback will be silently ignored. The end of the line is indicated by
-a token of type @code{CPP_EOF}.
+a token of type @code{CPP_EOF}
For an example use of this routine, see @file{c4x.h} and the callback
routines defined in @file{c4x-c.c}.
@@ -8832,10 +8893,9 @@ rule to the makefile fragment pointed to by @code{tmake_file} that shows
how to build this object file.
@end deftypefun
-@findex HANDLE_SYSV_PRAGMA
@findex #pragma
@findex pragma
-@item HANDLE_SYSV_PRAGMA
+@defmac HANDLE_SYSV_PRAGMA
Define this macro (to a value of 1) if you want the System V style
pragmas @samp{#pragma pack(<n>)} and @samp{#pragma weak <name>
[=<value>]} to be supported by gcc.
@@ -8863,11 +8923,11 @@ may affect its placement.
The weak pragma only works if @code{SUPPORTS_WEAK} and
@code{ASM_WEAKEN_LABEL} are defined. If enabled it allows the creation
of specifically named weak labels, optionally with a value.
+@end defmac
-@findex HANDLE_PRAGMA_PACK_PUSH_POP
@findex #pragma
@findex pragma
-@item HANDLE_PRAGMA_PACK_PUSH_POP
+@defmac HANDLE_PRAGMA_PACK_PUSH_POP
Define this macro (to a value of 1) if you want to support the Win32
style pragmas @samp{#pragma pack(push,@var{n})} and @samp{#pragma
pack(pop)}. The @samp{pack(push,@var{n})} pragma specifies the maximum alignment
@@ -8877,30 +8937,30 @@ pack value of zero resets the behavior to the default. Successive
invocations of this pragma cause the previous values to be stacked, so
that invocations of @samp{#pragma pack(pop)} will return to the previous
value.
+@end defmac
-@findex DOLLARS_IN_IDENTIFIERS
-@item DOLLARS_IN_IDENTIFIERS
-Define this macro to control use of the character @samp{$} in identifier
-names. 0 means @samp{$} is not allowed by default; 1 means it is allowed.
-1 is the default; there is no need to define this macro in that case.
-This macro controls the compiler proper; it does not affect the preprocessor.
+@defmac DOLLARS_IN_IDENTIFIERS
+Define this macro to control use of the character @samp{$} in
+identifier names for the C family of languages. 0 means @samp{$} is
+not allowed by default; 1 means it is allowed. 1 is the default;
+there is no need to define this macro in that case.
+@end defmac
-@findex NO_DOLLAR_IN_LABEL
-@item NO_DOLLAR_IN_LABEL
+@defmac NO_DOLLAR_IN_LABEL
Define this macro if the assembler does not accept the character
@samp{$} in label names. By default constructors and destructors in
G++ have @samp{$} in the identifiers. If this macro is defined,
@samp{.} is used instead.
+@end defmac
-@findex NO_DOT_IN_LABEL
-@item NO_DOT_IN_LABEL
+@defmac NO_DOT_IN_LABEL
Define this macro if the assembler does not accept the character
@samp{.} in label names. By default constructors and destructors in G++
have names that use @samp{.}. If this macro is defined, these names
are rewritten to avoid @samp{.}.
+@end defmac
-@findex DEFAULT_MAIN_RETURN
-@item DEFAULT_MAIN_RETURN
+@defmac DEFAULT_MAIN_RETURN
Define this macro if the target system expects every program's @code{main}
function to return a standard ``success'' value by default (if no other
value is explicitly returned).
@@ -8908,33 +8968,9 @@ value is explicitly returned).
The definition should be a C statement (sans semicolon) to generate the
appropriate rtl instructions. It is used only when compiling the end of
@code{main}.
+@end defmac
-@item NEED_ATEXIT
-@findex NEED_ATEXIT
-Define this if the target system lacks the function @code{atexit}
-from the ISO C standard. If this macro is defined, a default definition
-will be provided to support C++. If @code{ON_EXIT} is not defined,
-a default @code{exit} function will also be provided.
-
-@item ON_EXIT
-@findex ON_EXIT
-Define this macro if the target has another way to implement atexit
-functionality without replacing @code{exit}. For instance, SunOS 4 has
-a similar @code{on_exit} library function.
-
-The definition should be a functional macro which can be used just like
-the @code{atexit} function.
-
-@item EXIT_BODY
-@findex EXIT_BODY
-Define this if your @code{exit} function needs to do something
-besides calling an external function @code{_cleanup} before
-terminating with @code{_exit}. The @code{EXIT_BODY} macro is
-only needed if @code{NEED_ATEXIT} is defined and @code{ON_EXIT} is not
-defined.
-
-@findex INSN_SETS_ARE_DELAYED
-@item INSN_SETS_ARE_DELAYED (@var{insn})
+@defmac INSN_SETS_ARE_DELAYED (@var{insn})
Define this macro as a C expression that is nonzero if it is safe for the
delay slot scheduler to place instructions in the delay slot of @var{insn},
even if they appear to use a resource set or clobbered in @var{insn}.
@@ -8944,9 +8980,9 @@ or @code{jump_insn} is really a function call and hence has this behavior,
you should define this macro.
You need not define this macro if it would always return zero.
+@end defmac
-@findex INSN_REFERENCES_ARE_DELAYED
-@item INSN_REFERENCES_ARE_DELAYED (@var{insn})
+@defmac INSN_REFERENCES_ARE_DELAYED (@var{insn})
Define this macro as a C expression that is nonzero if it is safe for the
delay slot scheduler to place instructions in the delay slot of @var{insn},
even if they appear to set or clobber a resource referenced in @var{insn}.
@@ -8958,69 +8994,53 @@ instructions which copy arguments into the argument registers into the delay
slot of @var{insn}.
You need not define this macro if it would always return zero.
+@end defmac
-@findex MACHINE_DEPENDENT_REORG
-@item MACHINE_DEPENDENT_REORG (@var{insn})
-In rare cases, correct code generation requires extra machine
-dependent processing between the second jump optimization pass and
-delayed branch scheduling. On those machines, define this macro as a C
-statement to act on the code starting at @var{insn}.
-
-@findex MULTIPLE_SYMBOL_SPACES
-@item MULTIPLE_SYMBOL_SPACES
+@defmac MULTIPLE_SYMBOL_SPACES
Define this macro if in some cases global symbols from one translation
unit may not be bound to undefined symbols in another translation unit
without user intervention. For instance, under Microsoft Windows
symbols must be explicitly imported from shared libraries (DLLs).
+@end defmac
-@findex MD_ASM_CLOBBERS
-@item MD_ASM_CLOBBERS (@var{clobbers})
+@defmac MD_ASM_CLOBBERS (@var{clobbers})
A C statement that adds to @var{clobbers} @code{STRING_CST} trees for
any hard regs the port wishes to automatically clobber for all asms.
+@end defmac
-@findex MAX_INTEGER_COMPUTATION_MODE
-@item MAX_INTEGER_COMPUTATION_MODE
-Define this to the largest integer machine mode which can be used for
-operations other than load, store and copy operations.
-
-You need only define this macro if the target holds values larger than
-@code{word_mode} in general purpose registers. Most targets should not define
-this macro.
-
-@findex MATH_LIBRARY
-@item MATH_LIBRARY
+@defmac MATH_LIBRARY
Define this macro as a C string constant for the linker argument to link
in the system math library, or @samp{""} if the target does not have a
separate math library.
You need only define this macro if the default of @samp{"-lm"} is wrong.
+@end defmac
-@findex LIBRARY_PATH_ENV
-@item LIBRARY_PATH_ENV
+@defmac LIBRARY_PATH_ENV
Define this macro as a C string constant for the environment variable that
specifies where the linker should look for libraries.
You need only define this macro if the default of @samp{"LIBRARY_PATH"}
is wrong.
+@end defmac
-@findex TARGET_HAS_F_SETLKW
-@item TARGET_HAS_F_SETLKW
+@defmac TARGET_HAS_F_SETLKW
Define this macro if the target supports file locking with fcntl / F_SETLKW@.
Note that this functionality is part of POSIX@.
Defining @code{TARGET_HAS_F_SETLKW} will enable the test coverage code
to use file locking when exiting a program, which avoids race conditions
if the program has forked.
+@end defmac
-@findex MAX_CONDITIONAL_EXECUTE
-@item MAX_CONDITIONAL_EXECUTE
+@defmac MAX_CONDITIONAL_EXECUTE
A C expression for the maximum number of instructions to execute via
conditional execution instructions instead of a branch. A value of
@code{BRANCH_COST}+1 is the default if the machine does not use cc0, and
1 if it does use cc0.
+@end defmac
-@findex IFCVT_MODIFY_TESTS
-@item IFCVT_MODIFY_TESTS(@var{ce_info}, @var{true_expr}, @var{false_expr})
+@defmac IFCVT_MODIFY_TESTS (@var{ce_info}, @var{true_expr}, @var{false_expr})
Used if the target needs to perform machine-dependent modifications on the
conditionals used for turning basic blocks into conditionally executed code.
@var{ce_info} points to a data structure, @code{struct ce_if_block}, which
@@ -9028,47 +9048,60 @@ contains information about the currently processed blocks. @var{true_expr}
and @var{false_expr} are the tests that are used for converting the
then-block and the else-block, respectively. Set either @var{true_expr} or
@var{false_expr} to a null pointer if the tests cannot be converted.
+@end defmac
-@findex IFCVT_MODIFY_MULTIPLE_TESTS
-@item IFCVT_MODIFY_MULTIPLE_TESTS(@var{ce_info}, @var{bb}, @var{true_expr}, @var{false_expr})
+@defmac IFCVT_MODIFY_MULTIPLE_TESTS (@var{ce_info}, @var{bb}, @var{true_expr}, @var{false_expr})
Like @code{IFCVT_MODIFY_TESTS}, but used when converting more complicated
if-statements into conditions combined by @code{and} and @code{or} operations.
@var{bb} contains the basic block that contains the test that is currently
being processed and about to be turned into a condition.
+@end defmac
-@findex IFCVT_MODIFY_INSN
-@item IFCVT_MODIFY_INSN(@var{ce_info}, @var{pattern}, @var{insn})
+@defmac IFCVT_MODIFY_INSN (@var{ce_info}, @var{pattern}, @var{insn})
A C expression to modify the @var{PATTERN} of an @var{INSN} that is to
be converted to conditional execution format. @var{ce_info} points to
a data structure, @code{struct ce_if_block}, which contains information
about the currently processed blocks.
+@end defmac
-@findex IFCVT_MODIFY_FINAL
-@item IFCVT_MODIFY_FINAL(@var{ce_info})
+@defmac IFCVT_MODIFY_FINAL (@var{ce_info})
A C expression to perform any final machine dependent modifications in
converting code to conditional execution. The involved basic blocks
can be found in the @code{struct ce_if_block} structure that is pointed
to by @var{ce_info}.
+@end defmac
-@findex IFCVT_MODIFY_CANCEL
-@item IFCVT_MODIFY_CANCEL(@var{ce_info})
+@defmac IFCVT_MODIFY_CANCEL (@var{ce_info})
A C expression to cancel any machine dependent modifications in
converting code to conditional execution. The involved basic blocks
can be found in the @code{struct ce_if_block} structure that is pointed
to by @var{ce_info}.
+@end defmac
-@findex IFCVT_INIT_EXTRA_FIELDS
-@item IFCVT_INIT_EXTRA_FIELDS(@var{ce_info})
+@defmac IFCVT_INIT_EXTRA_FIELDS (@var{ce_info})
A C expression to initialize any extra fields in a @code{struct ce_if_block}
structure, which are defined by the @code{IFCVT_EXTRA_FIELDS} macro.
+@end defmac
-@findex IFCVT_EXTRA_FIELDS
-@item IFCVT_EXTRA_FIELDS
+@defmac IFCVT_EXTRA_FIELDS
If defined, it should expand to a set of field declarations that will be
added to the @code{struct ce_if_block} structure. These should be initialized
by the @code{IFCVT_INIT_EXTRA_FIELDS} macro.
+@end defmac
-@end table
+@deftypefn {Target Hook} void TARGET_MACHINE_DEPENDENT_REORG ()
+If non-null, this hook performs a target-specific pass over the
+instruction stream. The compiler will run it at all optimization levels,
+just before the point at which it normally does delayed-branch scheduling.
+
+The exact purpose of the hook varies from target to target. Some use
+it to do transformations that are necessary for correctness, such as
+laying out in-function constant pools or avoiding hardware hazards.
+Others use it as an opportunity to do some machine-dependent optimizations.
+
+You need not implement the hook if it has nothing to do. The default
+definition is null.
+@end deftypefn
@deftypefn {Target Hook} void TARGET_INIT_BUILTINS ()
Define this hook if you have any machine-specific built-in functions
@@ -9099,9 +9132,7 @@ ignored. This function should return the result of the call to the
built-in function.
@end deftypefn
-@table @code
-@findex MD_CAN_REDIRECT_BRANCH
-@item MD_CAN_REDIRECT_BRANCH(@var{branch1}, @var{branch2})
+@defmac MD_CAN_REDIRECT_BRANCH (@var{branch1}, @var{branch2})
Take a branch insn in @var{branch1} and another in @var{branch2}.
Return true if redirecting @var{branch1} to the destination of
@@ -9110,9 +9141,9 @@ Return true if redirecting @var{branch1} to the destination of
On some targets, branches may have a limited range. Optimizing the
filling of delay slots can result in branches being redirected, and this
may in turn cause a branch offset to overflow.
+@end defmac
-@findex ALLOCATE_INITIAL_VALUE
-@item ALLOCATE_INITIAL_VALUE(@var{hard_reg})
+@defmac ALLOCATE_INITIAL_VALUE (@var{hard_reg})
When the initial value of a hard register has been copied in a pseudo
register, it is often not necessary to actually allocate another register
@@ -9130,34 +9161,34 @@ it might decide to use another register anyways.
You may use @code{current_function_leaf_function} in the definition of the
macro, functions that use @code{REG_N_SETS}, to determine if the hard
register in question will not be clobbered.
+@end defmac
-@findex TARGET_OBJECT_SUFFIX
-@item TARGET_OBJECT_SUFFIX
+@defmac TARGET_OBJECT_SUFFIX
Define this macro to be a C string representing the suffix for object
files on your target machine. If you do not define this macro, GCC will
use @samp{.o} as the suffix for object files.
+@end defmac
-@findex TARGET_EXECUTABLE_SUFFIX
-@item TARGET_EXECUTABLE_SUFFIX
+@defmac TARGET_EXECUTABLE_SUFFIX
Define this macro to be a C string representing the suffix to be
automatically added to executable files on your target machine. If you
do not define this macro, GCC will use the null string as the suffix for
executable files.
+@end defmac
-@findex COLLECT_EXPORT_LIST
-@item COLLECT_EXPORT_LIST
+@defmac COLLECT_EXPORT_LIST
If defined, @code{collect2} will scan the individual object files
specified on its command line and create an export list for the linker.
Define this macro for systems like AIX, where the linker discards
object files that are not referenced from @code{main} and uses export
lists.
+@end defmac
-@findex MODIFY_JNI_METHOD_CALL
-@item MODIFY_JNI_METHOD_CALL (@var{mdecl})
+@defmac MODIFY_JNI_METHOD_CALL (@var{mdecl})
Define this macro to a C expression representing a variant of the
method call @var{mdecl}, if Java Native Interface (JNI) methods
must be invoked differently from other methods on your target.
-For example, on 32-bit Windows, JNI methods must be invoked using
+For example, on 32-bit Microsoft Windows, JNI methods must be invoked using
the @code{stdcall} calling convention and this macro is then
defined as this expression:
@@ -9167,8 +9198,7 @@ build_type_attribute_variant (@var{mdecl},
(get_identifier ("stdcall"),
NULL))
@end smallexample
-
-@end table
+@end defmac
@deftypefn {Target Hook} bool TARGET_CANNOT_MODIFY_JUMPS_P (void)
This target hook returns @code{true} past the point in which new jump
@@ -9184,3 +9214,35 @@ cannot_modify_jumps_past_reload_p ()
@}
@end smallexample
@end deftypefn
+
+@deftypefn {Target Hook} int TARGET_BRANCH_TARGET_REGISTER_CLASS (void)
+This target hook returns a register class for which branch target register
+optimizations should be applied. All registers in this class should be
+usable interchangeably. After reload, registers in this class will be
+re-allocated and loads will be hoisted out of loops and be subjected
+to inter-block scheduling.
+@end deftypefn
+
+@deftypefn {Target Hook} bool TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED (bool @var{after_prologue_epilogue_gen})
+Branch target register optimization will by default exclude callee-saved
+registers
+that are not already live during the current function; if this target hook
+returns true, they will be included. The target code must than make sure
+that all target registers in the class returned by
+@samp{TARGET_BRANCH_TARGET_REGISTER_CLASS} that might need saving are
+saved. @var{after_prologue_epilogue_gen} indicates if prologues and
+epilogues have already been generated. Note, even if you only return
+true when @var{after_prologue_epilogue_gen} is false, you still are likely
+to have to make special provisions in @code{INITIAL_ELIMINATION_OFFSET}
+to reserve space for caller-saved target registers.
+@end deftypefn
+
+@defmac POWI_MAX_MULTS
+If defined, this macro is interpreted as a signed integer C expression
+that specifies the maximum number of floating point multiplications
+that should be emitted when expanding exponentiation by an integer
+constant inline. When this value is defined, exponentiation requiring
+more than this number of multiplications is implemented by calling the
+system library's @code{pow}, @code{powf} or @code{powl} routines.
+The default value places no upper bound on the multiplication count.
+@end defmac
diff --git a/contrib/gcc/doc/trouble.texi b/contrib/gcc/doc/trouble.texi
index a7e42000bb72..a1b86bc9fd2f 100644
--- a/contrib/gcc/doc/trouble.texi
+++ b/contrib/gcc/doc/trouble.texi
@@ -1,5 +1,5 @@
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-@c 1999, 2000, 2001 Free Software Foundation, Inc.
+@c 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -129,7 +129,7 @@ Older GDB versions sometimes fail to read the output of GCC version
DBX rejects some files produced by GCC, though it accepts similar
constructs in output from PCC@. Until someone can supply a coherent
description of what is valid DBX input and what is not, there is
-nothing I can do about these problems. You are on your own.
+nothing that can be done about these problems.
@item
The GNU assembler (GAS) does not support PIC@. To generate PIC code, you
@@ -374,11 +374,11 @@ because of problems in DEC's versions of the X11 header files
@option{-I/usr/include/mit} to use the MIT versions of the header files,
or fixing the header files by adding this:
-@example
+@smallexample
#ifdef __STDC__
#define NeedFunctionPrototypes 0
#endif
-@end example
+@end smallexample
@item
On various 386 Unix systems derived from System V, including SCO, ISC,
@@ -393,17 +393,17 @@ is available as a separate package, and also in the file
If you have installed GNU malloc as a separate library package, use this
option when you relink GCC:
-@example
+@smallexample
MALLOC=/usr/local/lib/libgmalloc.a
-@end example
+@end smallexample
Alternatively, if you have compiled @file{gmalloc.c} from Emacs 19, copy
the object file to @file{gmalloc.o} and use this option when you relink
GCC:
-@example
+@smallexample
MALLOC=gmalloc.o
-@end example
+@end smallexample
@end itemize
@node Incompatibilities
@@ -454,9 +454,9 @@ Negating this value yields 2147483648 again.
GCC does not substitute macro arguments when they appear inside of
string constants. For example, the following macro in GCC
-@example
+@smallexample
#define foo(a) "a"
-@end example
+@end smallexample
@noindent
will produce output @code{"a"} regardless of what the argument @var{a} is.
@@ -469,7 +469,7 @@ variables guaranteed to remain valid are those declared
@code{volatile}. This is a consequence of automatic register
allocation. Consider this function:
-@example
+@smallexample
jmp_buf j;
foo ()
@@ -484,7 +484,7 @@ foo ()
/* @r{@code{longjmp (j)} may occur in @code{fun3}.} */
return a + fun3 ();
@}
-@end example
+@end smallexample
Here @code{a} may or may not be restored to its first value when the
@code{longjmp} occurs. If @code{a} is allocated in a register, then
@@ -500,20 +500,19 @@ Programs that use preprocessing directives in the middle of macro
arguments do not work with GCC@. For example, a program like this
will not work:
-@example
+@smallexample
@group
foobar (
#define luser
hack)
@end group
-@end example
+@end smallexample
ISO C does not permit such a construct.
@item
K&R compilers allow comments to cross over an inclusion boundary
-(i.e.@: started in an include file and ended in the including file). I think
-this would be quite ugly and can't imagine it could be needed.
+(i.e.@: started in an include file and ended in the including file).
@cindex external declaration scope
@cindex scope of external declarations
@@ -530,10 +529,10 @@ rest of the file even if it happens within a block.
In traditional C, you can combine @code{long}, etc., with a typedef name,
as shown here:
-@example
+@smallexample
typedef int foo;
typedef long foo bar;
-@end example
+@end smallexample
In ISO C, this is not allowed: @code{long} and other type modifiers
require an explicit @code{int}.
@@ -546,10 +545,10 @@ PCC allows typedef names to be used as function parameters.
Traditional C allows the following erroneous pair of declarations to
appear together in a given scope:
-@example
+@smallexample
typedef int foo;
typedef foo foo;
-@end example
+@end smallexample
@item
GCC treats all characters of identifiers as significant. According to
@@ -574,11 +573,11 @@ comments enclosed in conditionals that are guaranteed to fail; if these
comments contain apostrophes, GCC will probably report an error. For
example, this code would produce an error:
-@example
+@smallexample
#if 0
You can't expect this to work.
#endif
-@end example
+@end smallexample
The best solution to such a problem is to put the text into an actual
C comment delimited by @samp{/*@dots{}*/}.
@@ -615,8 +614,8 @@ The method used by GCC is as follows: a structure or union which is
1, 2, 4 or 8 bytes long is returned like a scalar. A structure or union
with any other size is stored into an address supplied by the caller
(usually in a special, fixed register, but on some machines it is passed
-on the stack). The machine-description macros @code{STRUCT_VALUE} and
-@code{STRUCT_INCOMING_VALUE} tell GCC where to pass this address.
+on the stack). The target hook @code{TARGET_STRUCT_VALUE_RTX}
+tells GCC where to pass this address.
By contrast, PCC on most target machines returns structures and unions
of any size by copying the data into an area of static storage, and then
@@ -758,14 +757,14 @@ executable and your source code, when you use optimization.
Users often think it is a bug when GCC reports an error for code
like this:
-@example
+@smallexample
int foo (struct mumble *);
struct mumble @{ @dots{} @};
int foo (struct mumble *x)
@{ @dots{} @}
-@end example
+@end smallexample
This code really is erroneous, because the scope of @code{struct
mumble} in the prototype is limited to the argument list containing it.
@@ -851,6 +850,7 @@ give rise to questions of this sort.
@menu
* Static Definitions:: Static member declarations are not definitions
+* Name lookup:: Name lookup, templates, and accessing members of base classes
* Temporaries:: Temporaries may vanish before you expect
* Copy Assignment:: Copy Assignment operators copy virtual bases twice
@end menu
@@ -865,14 +865,14 @@ give rise to questions of this sort.
When a class has static data members, it is not enough to @emph{declare}
the static member; you must also @emph{define} it. For example:
-@example
+@smallexample
class Foo
@{
@dots{}
void method();
static int bar;
@};
-@end example
+@end smallexample
This declaration only establishes that the class @code{Foo} has an
@code{int} named @code{Foo::bar}, and a member function named
@@ -881,9 +881,9 @@ This declaration only establishes that the class @code{Foo} has an
standard, you must supply an initializer in one (and only one) source
file, such as:
-@example
+@smallexample
int Foo::bar = 0;
-@end example
+@end smallexample
Other C++ compilers may not correctly implement the standard behavior.
As a result, when you switch to @command{g++} from one of these compilers,
@@ -891,6 +891,130 @@ you may discover that a program that appeared to work correctly in fact
does not conform to the standard: @command{g++} reports as undefined
symbols any static data members that lack definitions.
+
+@node Name lookup
+@subsection Name lookup, templates, and accessing members of base classes
+
+@cindex base class members
+@cindex two-stage name lookup
+@cindex dependent name lookup
+
+The C++ standard prescribes that all names that are not dependent on
+template parameters are bound to their present definitions when parsing
+a template function or class.@footnote{The C++ standard just uses the
+term ``dependent'' for names that depend on the type or value of
+template parameters. This shorter term will also be used in the rest of
+this section.} Only names that are dependent are looked up at the point
+of instantiation. For example, consider
+
+@smallexample
+ void foo(double);
+
+ struct A @{
+ template <typename T>
+ void f () @{
+ foo (1); // 1
+ int i = N; // 2
+ T t;
+ t.bar(); // 3
+ foo (t); // 4
+ @}
+
+ static const int N;
+ @};
+@end smallexample
+
+Here, the names @code{foo} and @code{N} appear in a context that does
+not depend on the type of @code{T}. The compiler will thus require that
+they are defined in the context of use in the template, not only before
+the point of instantiation, and will here use @code{::foo(double)} and
+@code{A::N}, respectively. In particular, it will convert the integer
+value to a @code{double} when passing it to @code{::foo(double)}.
+
+Conversely, @code{bar} and the call to @code{foo} in the fourth marked
+line are used in contexts that do depend on the type of @code{T}, so
+they are only looked up at the point of instantiation, and you can
+provide declarations for them after declaring the template, but before
+instantiating it. In particular, if you instantiate @code{A::f<int>},
+the last line will call an overloaded @code{::foo(int)} if one was
+provided, even if after the declaration of @code{struct A}.
+
+This distinction between lookup of dependent and non-dependent names is
+called two-stage (or dependent) name lookup. G++ implements it
+since version 3.4.
+
+Two-stage name lookup sometimes leads to situations with behavior
+different from non-template codes. The most common is probably this:
+
+@smallexample
+ template <typename T> struct Base @{
+ int i;
+ @};
+
+ template <typename T> struct Derived : public Base<T> @{
+ int get_i() @{ return i; @}
+ @};
+@end smallexample
+
+In @code{get_i()}, @code{i} is not used in a dependent context, so the
+compiler will look for a name declared at the enclosing namespace scope
+(which is the global scope here). It will not look into the base class,
+since that is dependent and you may declare specializations of
+@code{Base} even after declaring @code{Derived}, so the compiler can't
+really know what @code{i} would refer to. If there is no global
+variable @code{i}, then you will get an error message.
+
+In order to make it clear that you want the member of the base class,
+you need to defer lookup until instantiation time, at which the base
+class is known. For this, you need to access @code{i} in a dependent
+context, by either using @code{this->i} (remember that @code{this} is of
+type @code{Derived<T>*}, so is obviously dependent), or using
+@code{Base<T>::i}. Alternatively, @code{Base<T>::i} might be brought
+into scope by a @code{using}-declaration.
+
+Another, similar example involves calling member functions of a base
+class:
+
+@smallexample
+ template <typename T> struct Base @{
+ int f();
+ @};
+
+ template <typename T> struct Derived : Base<T> @{
+ int g() @{ return f(); @};
+ @};
+@end smallexample
+
+Again, the call to @code{f()} is not dependent on template arguments
+(there are no arguments that depend on the type @code{T}, and it is also
+not otherwise specified that the call should be in a dependent context).
+Thus a global declaration of such a function must be available, since
+the one in the base class is not visible until instantiation time. The
+compiler will consequently produce the following error message:
+
+@smallexample
+ x.cc: In member function `int Derived<T>::g()':
+ x.cc:6: error: there are no arguments to `f' that depend on a template
+ parameter, so a declaration of `f' must be available
+ x.cc:6: error: (if you use `-fpermissive', G++ will accept your code, but
+ allowing the use of an undeclared name is deprecated)
+@end smallexample
+
+To make the code valid either use @code{this->f()}, or
+@code{Base<T>::f()}. Using the @code{-fpermissive} flag will also let
+the compiler accept the code, by marking all function calls for which no
+declaration is visible at the time of definition of the template for
+later lookup at instantiation time, as if it were a dependent call.
+We do not recommend using @code{-fpermissive} to work around invalid
+code, and it will also only catch cases where functions in base classes
+are called, not where variables in base classes are used (as in the
+example above).
+
+Note that some compilers (including G++ versions prior to 3.4) get these
+examples wrong and accept above code without an error. Those compilers
+do not implement two-stage name lookup correctly.
+
+
@node Temporaries
@subsection Temporaries May Vanish Before You Expect
@@ -910,7 +1034,7 @@ For example, a program may use a function @code{strfunc} that returns
@code{string} objects, and another function @code{charfunc} that
operates on pointers to @code{char}:
-@example
+@smallexample
string strfunc ();
void charfunc (const char *);
@@ -923,7 +1047,7 @@ f ()
@dots{}
charfunc (p);
@}
-@end example
+@end smallexample
@noindent
In this situation, it may seem reasonable to save a pointer to the C
@@ -942,10 +1066,10 @@ The safe way to write such code is to give the temporary a name, which
forces it to remain until the end of the scope of the name. For
example:
-@example
+@smallexample
string& tmp = strfunc ();
charfunc (tmp.c_str ());
-@end example
+@end smallexample
@node Copy Assignment
@subsection Implicit Copy-Assignment for Virtual Bases
@@ -955,7 +1079,7 @@ belongs to each full object. Also, the constructors and destructors are
invoked only once, and called from the most-derived class. However, such
objects behave unspecified when being assigned. For example:
-@example
+@smallexample
struct Base@{
char *name;
Base(char *n) : name(strdup(n))@{@}
@@ -983,7 +1107,7 @@ void func(Derived &d1, Derived &d2)
@{
d1 = d2;
@}
-@end example
+@end smallexample
The C++ standard specifies that @samp{Base::Base} is only called once
when constructing or copy-constructing a Derived object. It is
@@ -991,7 +1115,7 @@ unspecified whether @samp{Base::operator=} is called more than once when
the implicit copy-assignment for Derived objects is invoked (as it is
inside @samp{func} in the example).
-g++ implements the ``intuitive'' algorithm for copy-assignment: assign all
+G++ implements the ``intuitive'' algorithm for copy-assignment: assign all
direct bases, then assign all members. In that algorithm, the virtual
base subobject can be encountered more than once. In the example, copying
proceeds in the following order: @samp{val}, @samp{name} (via
@@ -1120,11 +1244,16 @@ more annoyance than good.
@item
Warning when a non-void function value is ignored.
-Coming as I do from a Lisp background, I balk at the idea that there is
-something dangerous about discarding a value. There are functions that
-return values which some callers may find useful; it makes no sense to
-clutter the program with a cast to @code{void} whenever the value isn't
-useful.
+C contains many standard functions that return a value that most
+programs choose to ignore. One obvious example is @code{printf}.
+Warning about this practice only leads the defensive programmer to
+clutter programs with dozens of casts to @code{void}. Such casts are
+required so frequently that they become visual noise. Writing those
+casts becomes so automatic that they no longer convey useful
+information about the intentions of the programmer. For functions
+where the return value should never be ignored, use the
+@code{warn_unused_result} function attribute (@pxref{Function
+Attributes}).
@item
@opindex fshort-enums
@@ -1279,12 +1408,12 @@ It is never safe to depend on the order of evaluation of side effects.
For example, a function call like this may very well behave differently
from one compiler to another:
-@example
+@smallexample
void func (int, int);
int i = 2;
func (i++, i++);
-@end example
+@end smallexample
There is no guarantee (in either the C or the C++ standard language
definitions) that the increments will be evaluated in any particular
@@ -1309,7 +1438,7 @@ an error message for a certain program.
ISO C requires a ``diagnostic'' message for certain kinds of invalid
programs, but a warning is defined by GCC to count as a diagnostic. If
GCC produces a warning but not an error, that is correct ISO C support.
-If test suites call this ``failure'', they should be run with the GCC
+If testsuites call this ``failure'', they should be run with the GCC
option @option{-pedantic-errors}, which will turn these warnings into
errors.
diff --git a/contrib/gcc/dojump.c b/contrib/gcc/dojump.c
new file mode 100644
index 000000000000..6b9569bb024d
--- /dev/null
+++ b/contrib/gcc/dojump.c
@@ -0,0 +1,999 @@
+/* Convert tree expression to rtl instructions, for GNU compiler.
+ Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "tree.h"
+#include "flags.h"
+#include "function.h"
+#include "insn-config.h"
+#include "insn-attr.h"
+/* Include expr.h after insn-config.h so we get HAVE_conditional_move. */
+#include "expr.h"
+#include "optabs.h"
+#include "langhooks.h"
+
+static void do_jump_by_parts_greater (tree, int, rtx, rtx);
+static void do_jump_by_parts_equality (tree, rtx, rtx);
+static void do_compare_and_jump (tree, enum rtx_code, enum rtx_code, rtx,
+ rtx);
+
+/* At the start of a function, record that we have no previously-pushed
+ arguments waiting to be popped. */
+
+void
+init_pending_stack_adjust (void)
+{
+ pending_stack_adjust = 0;
+}
+
+/* When exiting from function, if safe, clear out any pending stack adjust
+ so the adjustment won't get done.
+
+ Note, if the current function calls alloca, then it must have a
+ frame pointer regardless of the value of flag_omit_frame_pointer. */
+
+void
+clear_pending_stack_adjust (void)
+{
+ if (optimize > 0
+ && (! flag_omit_frame_pointer || current_function_calls_alloca)
+ && EXIT_IGNORE_STACK
+ && ! (DECL_INLINE (current_function_decl) && ! flag_no_inline)
+ && ! flag_inline_functions)
+ {
+ stack_pointer_delta -= pending_stack_adjust,
+ pending_stack_adjust = 0;
+ }
+}
+
+/* Pop any previously-pushed arguments that have not been popped yet. */
+
+void
+do_pending_stack_adjust (void)
+{
+ if (inhibit_defer_pop == 0)
+ {
+ if (pending_stack_adjust != 0)
+ adjust_stack (GEN_INT (pending_stack_adjust));
+ pending_stack_adjust = 0;
+ }
+}
+
+/* Expand conditional expressions. */
+
+/* Generate code to evaluate EXP and jump to LABEL if the value is zero.
+ LABEL is an rtx of code CODE_LABEL, in this function and all the
+ functions here. */
+
+void
+jumpifnot (tree exp, rtx label)
+{
+ do_jump (exp, label, NULL_RTX);
+}
+
+/* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */
+
+void
+jumpif (tree exp, rtx label)
+{
+ do_jump (exp, NULL_RTX, label);
+}
+
+/* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
+ the result is zero, or IF_TRUE_LABEL if the result is one.
+ Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
+ meaning fall through in that case.
+
+ do_jump always does any pending stack adjust except when it does not
+ actually perform a jump. An example where there is no jump
+ is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
+
+ This function is responsible for optimizing cases such as
+ &&, || and comparison operators in EXP. */
+
+void
+do_jump (tree exp, rtx if_false_label, rtx if_true_label)
+{
+ enum tree_code code = TREE_CODE (exp);
+ /* Some cases need to create a label to jump to
+ in order to properly fall through.
+ These cases set DROP_THROUGH_LABEL nonzero. */
+ rtx drop_through_label = 0;
+ rtx temp;
+ int i;
+ tree type;
+ enum machine_mode mode;
+
+ emit_queue ();
+
+ switch (code)
+ {
+ case ERROR_MARK:
+ break;
+
+ case INTEGER_CST:
+ temp = integer_zerop (exp) ? if_false_label : if_true_label;
+ if (temp)
+ emit_jump (temp);
+ break;
+
+#if 0
+ /* This is not true with #pragma weak */
+ case ADDR_EXPR:
+ /* The address of something can never be zero. */
+ if (if_true_label)
+ emit_jump (if_true_label);
+ break;
+#endif
+
+ case UNSAVE_EXPR:
+ do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
+ TREE_OPERAND (exp, 0)
+ = (*lang_hooks.unsave_expr_now) (TREE_OPERAND (exp, 0));
+ break;
+
+ case NOP_EXPR:
+ if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
+ || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
+ || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
+ || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
+ goto normal;
+ case CONVERT_EXPR:
+ /* If we are narrowing the operand, we have to do the compare in the
+ narrower mode. */
+ if ((TYPE_PRECISION (TREE_TYPE (exp))
+ < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
+ goto normal;
+ case NON_LVALUE_EXPR:
+ case REFERENCE_EXPR:
+ case ABS_EXPR:
+ case NEGATE_EXPR:
+ case LROTATE_EXPR:
+ case RROTATE_EXPR:
+ /* These cannot change zero->nonzero or vice versa. */
+ do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
+ break;
+
+ case WITH_RECORD_EXPR:
+ /* Put the object on the placeholder list, recurse through our first
+ operand, and pop the list. */
+ placeholder_list = tree_cons (TREE_OPERAND (exp, 1), NULL_TREE,
+ placeholder_list);
+ do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
+ placeholder_list = TREE_CHAIN (placeholder_list);
+ break;
+
+#if 0
+ /* This is never less insns than evaluating the PLUS_EXPR followed by
+ a test and can be longer if the test is eliminated. */
+ case PLUS_EXPR:
+ /* Reduce to minus. */
+ exp = build (MINUS_EXPR, TREE_TYPE (exp),
+ TREE_OPERAND (exp, 0),
+ fold (build1 (NEGATE_EXPR, TREE_TYPE (TREE_OPERAND (exp, 1)),
+ TREE_OPERAND (exp, 1))));
+ /* Process as MINUS. */
+#endif
+
+ case MINUS_EXPR:
+ /* Nonzero iff operands of minus differ. */
+ do_compare_and_jump (build (NE_EXPR, TREE_TYPE (exp),
+ TREE_OPERAND (exp, 0),
+ TREE_OPERAND (exp, 1)),
+ NE, NE, if_false_label, if_true_label);
+ break;
+
+ case BIT_AND_EXPR:
+ /* If we are AND'ing with a small constant, do this comparison in the
+ smallest type that fits. If the machine doesn't have comparisons
+ that small, it will be converted back to the wider comparison.
+ This helps if we are testing the sign bit of a narrower object.
+ combine can't do this for us because it can't know whether a
+ ZERO_EXTRACT or a compare in a smaller mode exists, but we do. */
+
+ if (! SLOW_BYTE_ACCESS
+ && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
+ && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
+ && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0
+ && (mode = mode_for_size (i + 1, MODE_INT, 0)) != BLKmode
+ && (type = (*lang_hooks.types.type_for_mode) (mode, 1)) != 0
+ && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
+ && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
+ != CODE_FOR_nothing))
+ {
+ do_jump (convert (type, exp), if_false_label, if_true_label);
+ break;
+ }
+ goto normal;
+
+ case TRUTH_NOT_EXPR:
+ do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
+ break;
+
+ case TRUTH_ANDIF_EXPR:
+ if (if_false_label == 0)
+ if_false_label = drop_through_label = gen_label_rtx ();
+ do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX);
+ start_cleanup_deferral ();
+ do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
+ end_cleanup_deferral ();
+ break;
+
+ case TRUTH_ORIF_EXPR:
+ if (if_true_label == 0)
+ if_true_label = drop_through_label = gen_label_rtx ();
+ do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label);
+ start_cleanup_deferral ();
+ do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
+ end_cleanup_deferral ();
+ break;
+
+ case COMPOUND_EXPR:
+ push_temp_slots ();
+ expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
+ preserve_temp_slots (NULL_RTX);
+ free_temp_slots ();
+ pop_temp_slots ();
+ emit_queue ();
+ do_pending_stack_adjust ();
+ do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
+ break;
+
+ case COMPONENT_REF:
+ case BIT_FIELD_REF:
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ {
+ HOST_WIDE_INT bitsize, bitpos;
+ int unsignedp;
+ enum machine_mode mode;
+ tree type;
+ tree offset;
+ int volatilep = 0;
+
+ /* Get description of this reference. We don't actually care
+ about the underlying object here. */
+ get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode,
+ &unsignedp, &volatilep);
+
+ type = (*lang_hooks.types.type_for_size) (bitsize, unsignedp);
+ if (! SLOW_BYTE_ACCESS
+ && type != 0 && bitsize >= 0
+ && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
+ && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
+ != CODE_FOR_nothing))
+ {
+ do_jump (convert (type, exp), if_false_label, if_true_label);
+ break;
+ }
+ goto normal;
+ }
+
+ case COND_EXPR:
+ /* Do (a ? 1 : 0) and (a ? 0 : 1) as special cases. */
+ if (integer_onep (TREE_OPERAND (exp, 1))
+ && integer_zerop (TREE_OPERAND (exp, 2)))
+ do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
+
+ else if (integer_zerop (TREE_OPERAND (exp, 1))
+ && integer_onep (TREE_OPERAND (exp, 2)))
+ do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
+
+ else
+ {
+ rtx label1 = gen_label_rtx ();
+ drop_through_label = gen_label_rtx ();
+
+ do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX);
+
+ start_cleanup_deferral ();
+ /* Now the THEN-expression. */
+ do_jump (TREE_OPERAND (exp, 1),
+ if_false_label ? if_false_label : drop_through_label,
+ if_true_label ? if_true_label : drop_through_label);
+ /* In case the do_jump just above never jumps. */
+ do_pending_stack_adjust ();
+ emit_label (label1);
+
+ /* Now the ELSE-expression. */
+ do_jump (TREE_OPERAND (exp, 2),
+ if_false_label ? if_false_label : drop_through_label,
+ if_true_label ? if_true_label : drop_through_label);
+ end_cleanup_deferral ();
+ }
+ break;
+
+ case EQ_EXPR:
+ {
+ tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
+
+ if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_FLOAT
+ || GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_INT)
+ {
+ tree exp0 = save_expr (TREE_OPERAND (exp, 0));
+ tree exp1 = save_expr (TREE_OPERAND (exp, 1));
+ do_jump
+ (fold
+ (build (TRUTH_ANDIF_EXPR, TREE_TYPE (exp),
+ fold (build (EQ_EXPR, TREE_TYPE (exp),
+ fold (build1 (REALPART_EXPR,
+ TREE_TYPE (inner_type),
+ exp0)),
+ fold (build1 (REALPART_EXPR,
+ TREE_TYPE (inner_type),
+ exp1)))),
+ fold (build (EQ_EXPR, TREE_TYPE (exp),
+ fold (build1 (IMAGPART_EXPR,
+ TREE_TYPE (inner_type),
+ exp0)),
+ fold (build1 (IMAGPART_EXPR,
+ TREE_TYPE (inner_type),
+ exp1)))))),
+ if_false_label, if_true_label);
+ }
+
+ else if (integer_zerop (TREE_OPERAND (exp, 1)))
+ do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
+
+ else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
+ && !can_compare_p (EQ, TYPE_MODE (inner_type), ccp_jump))
+ do_jump_by_parts_equality (exp, if_false_label, if_true_label);
+ else
+ do_compare_and_jump (exp, EQ, EQ, if_false_label, if_true_label);
+ break;
+ }
+
+ case NE_EXPR:
+ {
+ tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
+
+ if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_FLOAT
+ || GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_INT)
+ {
+ tree exp0 = save_expr (TREE_OPERAND (exp, 0));
+ tree exp1 = save_expr (TREE_OPERAND (exp, 1));
+ do_jump
+ (fold
+ (build (TRUTH_ORIF_EXPR, TREE_TYPE (exp),
+ fold (build (NE_EXPR, TREE_TYPE (exp),
+ fold (build1 (REALPART_EXPR,
+ TREE_TYPE (inner_type),
+ exp0)),
+ fold (build1 (REALPART_EXPR,
+ TREE_TYPE (inner_type),
+ exp1)))),
+ fold (build (NE_EXPR, TREE_TYPE (exp),
+ fold (build1 (IMAGPART_EXPR,
+ TREE_TYPE (inner_type),
+ exp0)),
+ fold (build1 (IMAGPART_EXPR,
+ TREE_TYPE (inner_type),
+ exp1)))))),
+ if_false_label, if_true_label);
+ }
+
+ else if (integer_zerop (TREE_OPERAND (exp, 1)))
+ do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
+
+ else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
+ && !can_compare_p (NE, TYPE_MODE (inner_type), ccp_jump))
+ do_jump_by_parts_equality (exp, if_true_label, if_false_label);
+ else
+ do_compare_and_jump (exp, NE, NE, if_false_label, if_true_label);
+ break;
+ }
+
+ case LT_EXPR:
+ mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && ! can_compare_p (LT, mode, ccp_jump))
+ do_jump_by_parts_greater (exp, 1, if_false_label, if_true_label);
+ else
+ do_compare_and_jump (exp, LT, LTU, if_false_label, if_true_label);
+ break;
+
+ case LE_EXPR:
+ mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && ! can_compare_p (LE, mode, ccp_jump))
+ do_jump_by_parts_greater (exp, 0, if_true_label, if_false_label);
+ else
+ do_compare_and_jump (exp, LE, LEU, if_false_label, if_true_label);
+ break;
+
+ case GT_EXPR:
+ mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && ! can_compare_p (GT, mode, ccp_jump))
+ do_jump_by_parts_greater (exp, 0, if_false_label, if_true_label);
+ else
+ do_compare_and_jump (exp, GT, GTU, if_false_label, if_true_label);
+ break;
+
+ case GE_EXPR:
+ mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && ! can_compare_p (GE, mode, ccp_jump))
+ do_jump_by_parts_greater (exp, 1, if_true_label, if_false_label);
+ else
+ do_compare_and_jump (exp, GE, GEU, if_false_label, if_true_label);
+ break;
+
+ case UNORDERED_EXPR:
+ case ORDERED_EXPR:
+ {
+ enum rtx_code cmp, rcmp;
+ int do_rev;
+
+ if (code == UNORDERED_EXPR)
+ cmp = UNORDERED, rcmp = ORDERED;
+ else
+ cmp = ORDERED, rcmp = UNORDERED;
+ mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+
+ do_rev = 0;
+ if (! can_compare_p (cmp, mode, ccp_jump)
+ && (can_compare_p (rcmp, mode, ccp_jump)
+ /* If the target doesn't provide either UNORDERED or ORDERED
+ comparisons, canonicalize on UNORDERED for the library. */
+ || rcmp == UNORDERED))
+ do_rev = 1;
+
+ if (! do_rev)
+ do_compare_and_jump (exp, cmp, cmp, if_false_label, if_true_label);
+ else
+ do_compare_and_jump (exp, rcmp, rcmp, if_true_label, if_false_label);
+ }
+ break;
+
+ {
+ enum rtx_code rcode1;
+ enum tree_code tcode2;
+
+ case UNLT_EXPR:
+ rcode1 = UNLT;
+ tcode2 = LT_EXPR;
+ goto unordered_bcc;
+ case UNLE_EXPR:
+ rcode1 = UNLE;
+ tcode2 = LE_EXPR;
+ goto unordered_bcc;
+ case UNGT_EXPR:
+ rcode1 = UNGT;
+ tcode2 = GT_EXPR;
+ goto unordered_bcc;
+ case UNGE_EXPR:
+ rcode1 = UNGE;
+ tcode2 = GE_EXPR;
+ goto unordered_bcc;
+ case UNEQ_EXPR:
+ rcode1 = UNEQ;
+ tcode2 = EQ_EXPR;
+ goto unordered_bcc;
+
+ unordered_bcc:
+ mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ if (can_compare_p (rcode1, mode, ccp_jump))
+ do_compare_and_jump (exp, rcode1, rcode1, if_false_label,
+ if_true_label);
+ else
+ {
+ tree op0 = save_expr (TREE_OPERAND (exp, 0));
+ tree op1 = save_expr (TREE_OPERAND (exp, 1));
+ tree cmp0, cmp1;
+
+ /* If the target doesn't support combined unordered
+ compares, decompose into UNORDERED + comparison. */
+ cmp0 = fold (build (UNORDERED_EXPR, TREE_TYPE (exp), op0, op1));
+ cmp1 = fold (build (tcode2, TREE_TYPE (exp), op0, op1));
+ exp = build (TRUTH_ORIF_EXPR, TREE_TYPE (exp), cmp0, cmp1);
+ do_jump (exp, if_false_label, if_true_label);
+ }
+ }
+ break;
+
+ /* Special case:
+ __builtin_expect (<test>, 0) and
+ __builtin_expect (<test>, 1)
+
+ We need to do this here, so that <test> is not converted to a SCC
+ operation on machines that use condition code registers and COMPARE
+ like the PowerPC, and then the jump is done based on whether the SCC
+ operation produced a 1 or 0. */
+ case CALL_EXPR:
+ /* Check for a built-in function. */
+ {
+ tree fndecl = get_callee_fndecl (exp);
+ tree arglist = TREE_OPERAND (exp, 1);
+
+ if (fndecl
+ && DECL_BUILT_IN (fndecl)
+ && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
+ && arglist != NULL_TREE
+ && TREE_CHAIN (arglist) != NULL_TREE)
+ {
+ rtx seq = expand_builtin_expect_jump (exp, if_false_label,
+ if_true_label);
+
+ if (seq != NULL_RTX)
+ {
+ emit_insn (seq);
+ return;
+ }
+ }
+ }
+ /* Fall through and generate the normal code. */
+
+ default:
+ normal:
+ temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
+#if 0
+ /* This is not needed any more and causes poor code since it causes
+ comparisons and tests from non-SI objects to have different code
+ sequences. */
+ /* Copy to register to avoid generating bad insns by cse
+ from (set (mem ...) (arithop)) (set (cc0) (mem ...)). */
+ if (!cse_not_expected && GET_CODE (temp) == MEM)
+ temp = copy_to_reg (temp);
+#endif
+ do_pending_stack_adjust ();
+ /* Do any postincrements in the expression that was tested. */
+ emit_queue ();
+
+ if (GET_CODE (temp) == CONST_INT
+ || (GET_CODE (temp) == CONST_DOUBLE && GET_MODE (temp) == VOIDmode)
+ || GET_CODE (temp) == LABEL_REF)
+ {
+ rtx target = temp == const0_rtx ? if_false_label : if_true_label;
+ if (target)
+ emit_jump (target);
+ }
+ else if (GET_MODE_CLASS (GET_MODE (temp)) == MODE_INT
+ && ! can_compare_p (NE, GET_MODE (temp), ccp_jump))
+ /* Note swapping the labels gives us not-equal. */
+ do_jump_by_parts_equality_rtx (temp, if_true_label, if_false_label);
+ else if (GET_MODE (temp) != VOIDmode)
+ {
+ /* The RTL optimizers prefer comparisons against pseudos. */
+ if (GET_CODE (temp) == SUBREG)
+ {
+ /* Compare promoted variables in their promoted mode. */
+ if (SUBREG_PROMOTED_VAR_P (temp)
+ && GET_CODE (XEXP (temp, 0)) == REG)
+ temp = XEXP (temp, 0);
+ else
+ temp = copy_to_reg (temp);
+ }
+ do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
+ NE, TREE_UNSIGNED (TREE_TYPE (exp)),
+ GET_MODE (temp), NULL_RTX,
+ if_false_label, if_true_label);
+ }
+ else
+ abort ();
+ }
+
+ if (drop_through_label)
+ {
+ /* If do_jump produces code that might be jumped around,
+ do any stack adjusts from that code, before the place
+ where control merges in. */
+ do_pending_stack_adjust ();
+ emit_label (drop_through_label);
+ }
+}
+
+/* Given a comparison expression EXP for values too wide to be compared
+ with one insn, test the comparison and jump to the appropriate label.
+ The code of EXP is ignored; we always test GT if SWAP is 0,
+ and LT if SWAP is 1. */
+
+static void
+do_jump_by_parts_greater (tree exp, int swap, rtx if_false_label,
+ rtx if_true_label)
+{
+ rtx op0 = expand_expr (TREE_OPERAND (exp, swap), NULL_RTX, VOIDmode, 0);
+ rtx op1 = expand_expr (TREE_OPERAND (exp, !swap), NULL_RTX, VOIDmode, 0);
+ enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ int unsignedp = TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0)));
+
+ do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label, if_true_label);
+}
+
+/* Compare OP0 with OP1, word at a time, in mode MODE.
+ UNSIGNEDP says to do unsigned comparison.
+ Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise. */
+
+void
+do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0,
+ rtx op1, rtx if_false_label, rtx if_true_label)
+{
+ int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
+ rtx drop_through_label = 0;
+ int i;
+
+ if (! if_true_label || ! if_false_label)
+ drop_through_label = gen_label_rtx ();
+ if (! if_true_label)
+ if_true_label = drop_through_label;
+ if (! if_false_label)
+ if_false_label = drop_through_label;
+
+ /* Compare a word at a time, high order first. */
+ for (i = 0; i < nwords; i++)
+ {
+ rtx op0_word, op1_word;
+
+ if (WORDS_BIG_ENDIAN)
+ {
+ op0_word = operand_subword_force (op0, i, mode);
+ op1_word = operand_subword_force (op1, i, mode);
+ }
+ else
+ {
+ op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
+ op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
+ }
+
+ /* All but high-order word must be compared as unsigned. */
+ do_compare_rtx_and_jump (op0_word, op1_word, GT,
+ (unsignedp || i > 0), word_mode, NULL_RTX,
+ NULL_RTX, if_true_label);
+
+ /* Consider lower words only if these are equal. */
+ do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
+ NULL_RTX, NULL_RTX, if_false_label);
+ }
+
+ if (if_false_label)
+ emit_jump (if_false_label);
+ if (drop_through_label)
+ emit_label (drop_through_label);
+}
+
+/* Given an EQ_EXPR expression EXP for values too wide to be compared
+ with one insn, test the comparison and jump to the appropriate label. */
+
+static void
+do_jump_by_parts_equality (tree exp, rtx if_false_label, rtx if_true_label)
+{
+ rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
+ rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
+ enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+ int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
+ int i;
+ rtx drop_through_label = 0;
+
+ if (! if_false_label)
+ drop_through_label = if_false_label = gen_label_rtx ();
+
+ for (i = 0; i < nwords; i++)
+ do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
+ operand_subword_force (op1, i, mode),
+ EQ, TREE_UNSIGNED (TREE_TYPE (exp)),
+ word_mode, NULL_RTX, if_false_label, NULL_RTX);
+
+ if (if_true_label)
+ emit_jump (if_true_label);
+ if (drop_through_label)
+ emit_label (drop_through_label);
+}
+
+/* Jump according to whether OP0 is 0.
+ We assume that OP0 has an integer mode that is too wide
+ for the available compare insns. */
+
+void
+do_jump_by_parts_equality_rtx (rtx op0, rtx if_false_label, rtx if_true_label)
+{
+ int nwords = GET_MODE_SIZE (GET_MODE (op0)) / UNITS_PER_WORD;
+ rtx part;
+ int i;
+ rtx drop_through_label = 0;
+
+ /* The fastest way of doing this comparison on almost any machine is to
+ "or" all the words and compare the result. If all have to be loaded
+ from memory and this is a very wide item, it's possible this may
+ be slower, but that's highly unlikely. */
+
+ part = gen_reg_rtx (word_mode);
+ emit_move_insn (part, operand_subword_force (op0, 0, GET_MODE (op0)));
+ for (i = 1; i < nwords && part != 0; i++)
+ part = expand_binop (word_mode, ior_optab, part,
+ operand_subword_force (op0, i, GET_MODE (op0)),
+ part, 1, OPTAB_WIDEN);
+
+ if (part != 0)
+ {
+ do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
+ NULL_RTX, if_false_label, if_true_label);
+
+ return;
+ }
+
+ /* If we couldn't do the "or" simply, do this with a series of compares. */
+ if (! if_false_label)
+ drop_through_label = if_false_label = gen_label_rtx ();
+
+ for (i = 0; i < nwords; i++)
+ do_compare_rtx_and_jump (operand_subword_force (op0, i, GET_MODE (op0)),
+ const0_rtx, EQ, 1, word_mode, NULL_RTX,
+ if_false_label, NULL_RTX);
+
+ if (if_true_label)
+ emit_jump (if_true_label);
+
+ if (drop_through_label)
+ emit_label (drop_through_label);
+}
+
+/* Generate code for a comparison of OP0 and OP1 with rtx code CODE.
+ (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)
+{
+ enum rtx_code ucode;
+ 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);
+ }
+
+ if (flag_force_mem)
+ {
+ op0 = force_not_mem (op0);
+ op1 = force_not_mem (op1);
+ }
+
+ do_pending_stack_adjust ();
+
+ ucode = unsignedp ? unsigned_condition (code) : code;
+ if ((tem = simplify_relational_operation (ucode, mode, op0, op1)) != 0)
+ return tem;
+
+#if 0
+ /* There's no need to do this now that combine.c can eliminate lots of
+ sign extensions. This can be less efficient in certain cases on other
+ machines. */
+
+ /* If this is a signed equality comparison, we can do it as an
+ unsigned comparison since zero-extension is cheaper than sign
+ extension and comparisons with zero are done as unsigned. This is
+ the case even on machines that can do fast sign extension, since
+ zero-extension is easier to combine with other operations than
+ sign-extension is. If we are comparing against a constant, we must
+ convert it to what it would look like unsigned. */
+ if ((code == EQ || code == NE) && ! unsignedp
+ && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
+ {
+ if (GET_CODE (op1) == CONST_INT
+ && (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0))) != INTVAL (op1))
+ op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0)));
+ unsignedp = 1;
+ }
+#endif
+
+ 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.
+
+ If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
+ compared. */
+
+void
+do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
+ enum machine_mode mode, rtx size, rtx if_false_label,
+ rtx if_true_label)
+{
+ enum rtx_code ucode;
+ rtx tem;
+ int dummy_true_label = 0;
+
+ /* Reverse the comparison if that is safe and we want to jump if it is
+ false. */
+ if (! if_true_label && ! FLOAT_MODE_P (mode))
+ {
+ if_true_label = if_false_label;
+ if_false_label = 0;
+ code = reverse_condition (code);
+ }
+
+ /* 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);
+ }
+
+ if (flag_force_mem)
+ {
+ op0 = force_not_mem (op0);
+ op1 = force_not_mem (op1);
+ }
+
+ do_pending_stack_adjust ();
+
+ ucode = unsignedp ? unsigned_condition (code) : code;
+ if ((tem = simplify_relational_operation (ucode, mode, op0, op1)) != 0)
+ {
+ if (tem == const_true_rtx)
+ {
+ if (if_true_label)
+ emit_jump (if_true_label);
+ }
+ else
+ {
+ if (if_false_label)
+ emit_jump (if_false_label);
+ }
+ return;
+ }
+
+#if 0
+ /* There's no need to do this now that combine.c can eliminate lots of
+ sign extensions. This can be less efficient in certain cases on other
+ machines. */
+
+ /* If this is a signed equality comparison, we can do it as an
+ unsigned comparison since zero-extension is cheaper than sign
+ extension and comparisons with zero are done as unsigned. This is
+ the case even on machines that can do fast sign extension, since
+ zero-extension is easier to combine with other operations than
+ sign-extension is. If we are comparing against a constant, we must
+ convert it to what it would look like unsigned. */
+ if ((code == EQ || code == NE) && ! unsignedp
+ && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
+ {
+ if (GET_CODE (op1) == CONST_INT
+ && (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0))) != INTVAL (op1))
+ op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0)));
+ unsignedp = 1;
+ }
+#endif
+
+ if (! if_true_label)
+ {
+ dummy_true_label = 1;
+ if_true_label = gen_label_rtx ();
+ }
+
+ emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
+ if_true_label);
+
+ if (if_false_label)
+ emit_jump (if_false_label);
+ if (dummy_true_label)
+ emit_label (if_true_label);
+}
+
+/* Generate code for a comparison expression EXP (including code to compute
+ the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
+ IF_TRUE_LABEL. One of the labels can be NULL_RTX, in which case the
+ generated code will drop through.
+ SIGNED_CODE should be the rtx operation for this comparison for
+ signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
+
+ We force a stack adjustment unless there are currently
+ things pushed on the stack that aren't yet used. */
+
+static void
+do_compare_and_jump (tree exp, enum rtx_code signed_code,
+ enum rtx_code unsigned_code, rtx if_false_label,
+ rtx if_true_label)
+{
+ rtx op0, op1;
+ tree type;
+ enum machine_mode mode;
+ int unsignedp;
+ enum rtx_code code;
+
+ /* Don't crash if the comparison was erroneous. */
+ op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
+ if (TREE_CODE (TREE_OPERAND (exp, 0)) == ERROR_MARK)
+ return;
+
+ op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
+ if (TREE_CODE (TREE_OPERAND (exp, 1)) == ERROR_MARK)
+ return;
+
+ type = TREE_TYPE (TREE_OPERAND (exp, 0));
+ mode = TYPE_MODE (type);
+ if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST
+ && (TREE_CODE (TREE_OPERAND (exp, 1)) != INTEGER_CST
+ || (GET_MODE_BITSIZE (mode)
+ > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp,
+ 1)))))))
+ {
+ /* op0 might have been replaced by promoted constant, in which
+ case the type of second argument should be used. */
+ type = TREE_TYPE (TREE_OPERAND (exp, 1));
+ mode = TYPE_MODE (type);
+ }
+ unsignedp = TREE_UNSIGNED (type);
+ code = unsignedp ? unsigned_code : signed_code;
+
+#ifdef HAVE_canonicalize_funcptr_for_compare
+ /* If function pointers need to be "canonicalized" before they can
+ be reliably compared, then canonicalize them. */
+ if (HAVE_canonicalize_funcptr_for_compare
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
+ && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))
+ == FUNCTION_TYPE))
+ {
+ rtx new_op0 = gen_reg_rtx (mode);
+
+ emit_insn (gen_canonicalize_funcptr_for_compare (new_op0, op0));
+ op0 = new_op0;
+ }
+
+ if (HAVE_canonicalize_funcptr_for_compare
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 1))) == POINTER_TYPE
+ && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 1))))
+ == FUNCTION_TYPE))
+ {
+ rtx new_op1 = gen_reg_rtx (mode);
+
+ emit_insn (gen_canonicalize_funcptr_for_compare (new_op1, op1));
+ op1 = new_op1;
+ }
+#endif
+
+ /* Do any postincrements in the expression that was tested. */
+ emit_queue ();
+
+ do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
+ ((mode == BLKmode)
+ ? expr_size (TREE_OPERAND (exp, 0)) : NULL_RTX),
+ if_false_label, if_true_label);
+}
diff --git a/contrib/gcc/doloop.c b/contrib/gcc/doloop.c
index 67b742cde714..a82fb16a35cb 100644
--- a/contrib/gcc/doloop.c
+++ b/contrib/gcc/doloop.c
@@ -1,5 +1,6 @@
/* Perform doloop optimizations
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
This file is part of GCC.
@@ -21,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "flags.h"
#include "expr.h"
@@ -29,6 +32,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "basic-block.h"
#include "toplev.h"
#include "tm_p.h"
+#include "cfgloop.h"
/* This module is used to modify loops with a determinable number of
@@ -56,23 +60,18 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifdef HAVE_doloop_end
-static rtx doloop_condition_get
- PARAMS ((rtx));
-static unsigned HOST_WIDE_INT doloop_iterations_max
- PARAMS ((const struct loop_info *, enum machine_mode, int));
-static int doloop_valid_p
- PARAMS ((const struct loop *, rtx));
-static int doloop_modify
- PARAMS ((const struct loop *, rtx, rtx, rtx, rtx, rtx));
-static int doloop_modify_runtime
- PARAMS ((const struct loop *, rtx, rtx, rtx, enum machine_mode, rtx));
+static unsigned HOST_WIDE_INT doloop_iterations_max (const struct loop_info *,
+ enum machine_mode, int);
+static int doloop_valid_p (const struct loop *, rtx);
+static int doloop_modify (const struct loop *, rtx, rtx, rtx, rtx, rtx);
+static int doloop_modify_runtime (const struct loop *, rtx, rtx, rtx,
+ enum machine_mode, rtx);
/* Return the loop termination condition for PATTERN or zero
if it is not a decrement and branch jump insn. */
-static rtx
-doloop_condition_get (pattern)
- rtx pattern;
+rtx
+doloop_condition_get (rtx pattern)
{
rtx cmp;
rtx inc;
@@ -143,10 +142,8 @@ doloop_condition_get (pattern)
MODE is the mode of the iteration count and NONNEG is nonzero if
the iteration count has been proved to be non-negative. */
static unsigned HOST_WIDE_INT
-doloop_iterations_max (loop_info, mode, nonneg)
- const struct loop_info *loop_info;
- enum machine_mode mode;
- int nonneg;
+doloop_iterations_max (const struct loop_info *loop_info,
+ enum machine_mode mode, int nonneg)
{
unsigned HOST_WIDE_INT n_iterations_max;
enum rtx_code code;
@@ -252,9 +249,7 @@ doloop_iterations_max (loop_info, mode, nonneg)
/* Return nonzero if the loop specified by LOOP is suitable for
the use of special low-overhead looping instructions. */
static int
-doloop_valid_p (loop, jump_insn)
- const struct loop *loop;
- rtx jump_insn;
+doloop_valid_p (const struct loop *loop, rtx jump_insn)
{
const struct loop_info *loop_info = LOOP_INFO (loop);
@@ -402,14 +397,8 @@ doloop_valid_p (loop, jump_insn)
low-overhead looping insn to emit at the end of the loop. This
returns nonzero if it was successful. */
static int
-doloop_modify (loop, iterations, iterations_max,
- doloop_seq, start_label, condition)
- const struct loop *loop;
- rtx iterations;
- rtx iterations_max;
- rtx doloop_seq;
- rtx start_label;
- rtx condition;
+doloop_modify (const struct loop *loop, rtx iterations, rtx iterations_max,
+ rtx doloop_seq, rtx start_label, rtx condition)
{
rtx counter_reg;
rtx count;
@@ -485,7 +474,7 @@ doloop_modify (loop, iterations, iterations_max,
count = GEN_INT (INTVAL (count) - 1);
else
count = expand_simple_binop (GET_MODE (counter_reg), MINUS,
- count, GEN_INT (1),
+ count, const1_rtx,
0, 0, OPTAB_LIB_WIDEN);
}
@@ -542,14 +531,9 @@ doloop_modify (loop, iterations, iterations_max,
number of loop iterations. DOLOOP_INSN is the low-overhead looping
insn to insert. Returns nonzero if loop successfully modified. */
static int
-doloop_modify_runtime (loop, iterations_max,
- doloop_seq, start_label, mode, condition)
- const struct loop *loop;
- rtx iterations_max;
- rtx doloop_seq;
- rtx start_label;
- enum machine_mode mode;
- rtx condition;
+doloop_modify_runtime (const struct loop *loop, rtx iterations_max,
+ rtx doloop_seq, rtx start_label,
+ enum machine_mode mode, rtx condition)
{
const struct loop_info *loop_info = LOOP_INFO (loop);
HOST_WIDE_INT abs_inc;
@@ -756,8 +740,7 @@ doloop_modify_runtime (loop, iterations_max,
is a candidate for this optimization. Returns nonzero if loop
successfully modified. */
int
-doloop_optimize (loop)
- const struct loop *loop;
+doloop_optimize (const struct loop *loop)
{
struct loop_info *loop_info = LOOP_INFO (loop);
rtx initial_value;
diff --git a/contrib/gcc/dominance.c b/contrib/gcc/dominance.c
index 1bba31fb57c9..d608391839df 100644
--- a/contrib/gcc/dominance.c
+++ b/contrib/gcc/dominance.c
@@ -1,5 +1,5 @@
/* Calculate (post)dominators in slightly super-linear time.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Matz (matz@ifh.de).
This file is part of GCC.
@@ -35,22 +35,16 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "errors.h"
#include "et-forest.h"
-struct dominance_info
-{
- et_forest_t forest;
- varray_type varray;
-};
-
-#define BB_NODE(info, bb) \
- ((et_forest_node_t)VARRAY_GENERIC_PTR ((info)->varray, (bb)->index + 2))
-#define SET_BB_NODE(info, bb, node) \
- (VARRAY_GENERIC_PTR ((info)->varray, (bb)->index + 2) = (node))
+/* Whether the dominators and the postdominators are available. */
+enum dom_state dom_computed[2];
/* We name our nodes with integers, beginning with 1. Zero is reserved for
'undefined' or 'end of list'. The name of each node is given by the dfs
@@ -113,19 +107,16 @@ struct dom_info
unsigned int nodes;
};
-static void init_dom_info PARAMS ((struct dom_info *));
-static void free_dom_info PARAMS ((struct dom_info *));
-static void calc_dfs_tree_nonrec PARAMS ((struct dom_info *,
- basic_block,
- enum cdi_direction));
-static void calc_dfs_tree PARAMS ((struct dom_info *,
- enum cdi_direction));
-static void compress PARAMS ((struct dom_info *, TBB));
-static TBB eval PARAMS ((struct dom_info *, TBB));
-static void link_roots PARAMS ((struct dom_info *, TBB, TBB));
-static void calc_idoms PARAMS ((struct dom_info *,
- enum cdi_direction));
-void debug_dominance_info PARAMS ((dominance_info));
+static void init_dom_info (struct dom_info *);
+static void free_dom_info (struct dom_info *);
+static void calc_dfs_tree_nonrec (struct dom_info *, basic_block,
+ enum cdi_direction);
+static void calc_dfs_tree (struct dom_info *, enum cdi_direction);
+static void compress (struct dom_info *, TBB);
+static TBB eval (struct dom_info *, TBB);
+static void link_roots (struct dom_info *, TBB, TBB);
+static void calc_idoms (struct dom_info *, enum cdi_direction);
+void debug_dominance_info (enum cdi_direction);
/* Helper macro for allocating and initializing an array,
for aesthetic reasons. */
@@ -134,10 +125,10 @@ void debug_dominance_info PARAMS ((dominance_info));
{ \
unsigned int i = 1; /* Catch content == i. */ \
if (! (content)) \
- (var) = (type *) xcalloc ((num), sizeof (type)); \
+ (var) = xcalloc ((num), sizeof (type)); \
else \
{ \
- (var) = (type *) xmalloc ((num) * sizeof (type)); \
+ (var) = xmalloc ((num) * sizeof (type)); \
for (i = 0; i < num; i++) \
(var)[i] = (content); \
} \
@@ -148,8 +139,7 @@ void debug_dominance_info PARAMS ((dominance_info));
This initializes the contents of DI, which already must be allocated. */
static void
-init_dom_info (di)
- struct dom_info *di;
+init_dom_info (struct dom_info *di)
{
/* We need memory for n_basic_blocks nodes and the ENTRY_BLOCK or
EXIT_BLOCK. */
@@ -178,8 +168,7 @@ init_dom_info (di)
/* Free all allocated memory in DI, but not DI itself. */
static void
-free_dom_info (di)
- struct dom_info *di;
+free_dom_info (struct dom_info *di)
{
free (di->dfs_parent);
free (di->path_min);
@@ -201,10 +190,7 @@ free_dom_info (di)
assigned their dfs number and are linked together to form a tree. */
static void
-calc_dfs_tree_nonrec (di, bb, reverse)
- struct dom_info *di;
- basic_block bb;
- enum cdi_direction reverse;
+calc_dfs_tree_nonrec (struct dom_info *di, basic_block bb, enum cdi_direction reverse)
{
/* We never call this with bb==EXIT_BLOCK_PTR (ENTRY_BLOCK_PTR if REVERSE). */
/* We call this _only_ if bb is not already visited. */
@@ -218,7 +204,7 @@ calc_dfs_tree_nonrec (di, bb, reverse)
/* Ending block. */
basic_block ex_block;
- stack = (edge *) xmalloc ((n_basic_blocks + 3) * sizeof (edge));
+ stack = xmalloc ((n_basic_blocks + 3) * sizeof (edge));
sp = 0;
/* Initialize our border blocks, and the first edge. */
@@ -319,9 +305,7 @@ calc_dfs_tree_nonrec (di, bb, reverse)
because there may be nodes from which the EXIT_BLOCK is unreachable. */
static void
-calc_dfs_tree (di, reverse)
- struct dom_info *di;
- enum cdi_direction reverse;
+calc_dfs_tree (struct dom_info *di, enum cdi_direction reverse)
{
/* The first block is the ENTRY_BLOCK (or EXIT_BLOCK if REVERSE). */
basic_block begin = reverse ? EXIT_BLOCK_PTR : ENTRY_BLOCK_PTR;
@@ -362,9 +346,7 @@ calc_dfs_tree (di, reverse)
from V to that root. */
static void
-compress (di, v)
- struct dom_info *di;
- TBB v;
+compress (struct dom_info *di, TBB v)
{
/* Btw. It's not worth to unrecurse compress() as the depth is usually not
greater than 5 even for huge graphs (I've not seen call depth > 4).
@@ -384,9 +366,7 @@ compress (di, v)
value on the path from V to the root. */
static inline TBB
-eval (di, v)
- struct dom_info *di;
- TBB v;
+eval (struct dom_info *di, TBB v)
{
/* The representant of the set V is in, also called root (as the set
representation is a tree). */
@@ -415,9 +395,7 @@ eval (di, v)
of W. */
static void
-link_roots (di, v, w)
- struct dom_info *di;
- TBB v, w;
+link_roots (struct dom_info *di, TBB v, TBB w)
{
TBB s = w;
@@ -459,9 +437,7 @@ link_roots (di, v, w)
On return the immediate dominator to node V is in di->dom[V]. */
static void
-calc_idoms (di, reverse)
- struct dom_info *di;
- enum cdi_direction reverse;
+calc_idoms (struct dom_info *di, enum cdi_direction reverse)
{
TBB v, w, k, par;
basic_block en_block;
@@ -542,191 +518,250 @@ calc_idoms (di, reverse)
di->dom[v] = di->dom[di->dom[v]];
}
-/* The main entry point into this module. IDOM is an integer array with room
- for last_basic_block integers, DOMS is a preallocated sbitmap array having
- room for last_basic_block^2 bits, and POST is true if the caller wants to
- know post-dominators.
+/* Assign dfs numbers starting from NUM to NODE and its sons. */
+
+static void
+assign_dfs_numbers (struct et_node *node, int *num)
+{
+ struct et_node *son;
+
+ node->dfs_num_in = (*num)++;
+
+ if (node->son)
+ {
+ assign_dfs_numbers (node->son, num);
+ for (son = node->son->right; son != node->son; son = son->right)
+ assign_dfs_numbers (son, num);
+ }
- On return IDOM[i] will be the BB->index of the immediate (post) dominator
- of basic block i, and DOMS[i] will have set bit j if basic block j is a
- (post)dominator for block i.
+ node->dfs_num_out = (*num)++;
+}
- Either IDOM or DOMS may be NULL (meaning the caller is not interested in
- immediate resp. all dominators). */
+/* Compute the data necessary for fast resolving of dominator queries in a
+ static dominator tree. */
-dominance_info
-calculate_dominance_info (reverse)
- enum cdi_direction reverse;
+static void
+compute_dom_fast_query (enum cdi_direction dir)
+{
+ int num = 0;
+ basic_block bb;
+
+ if (dom_computed[dir] < DOM_NO_FAST_QUERY)
+ abort ();
+
+ if (dom_computed[dir] == DOM_OK)
+ return;
+
+ FOR_ALL_BB (bb)
+ {
+ if (!bb->dom[dir]->father)
+ assign_dfs_numbers (bb->dom[dir], &num);
+ }
+
+ dom_computed[dir] = DOM_OK;
+}
+
+/* The main entry point into this module. DIR is set depending on whether
+ we want to compute dominators or postdominators. */
+
+void
+calculate_dominance_info (enum cdi_direction dir)
{
struct dom_info di;
- dominance_info info;
basic_block b;
- /* allocate structure for dominance information. */
- info = xmalloc (sizeof (struct dominance_info));
- info->forest = et_forest_create ();
- VARRAY_GENERIC_PTR_INIT (info->varray, last_basic_block + 3, "dominance info");
+ if (dom_computed[dir] == DOM_OK)
+ return;
- /* Add the two well-known basic blocks. */
- SET_BB_NODE (info, ENTRY_BLOCK_PTR, et_forest_add_node (info->forest,
- ENTRY_BLOCK_PTR));
- SET_BB_NODE (info, EXIT_BLOCK_PTR, et_forest_add_node (info->forest,
- EXIT_BLOCK_PTR));
- FOR_EACH_BB (b)
- SET_BB_NODE (info, b, et_forest_add_node (info->forest, b));
+ if (dom_computed[dir] != DOM_NO_FAST_QUERY)
+ {
+ if (dom_computed[dir] != DOM_NONE)
+ free_dominance_info (dir);
- init_dom_info (&di);
- calc_dfs_tree (&di, reverse);
- calc_idoms (&di, reverse);
+ FOR_ALL_BB (b)
+ {
+ b->dom[dir] = et_new_tree (b);
+ }
+ init_dom_info (&di);
+ calc_dfs_tree (&di, dir);
+ calc_idoms (&di, dir);
- FOR_EACH_BB (b)
- {
- TBB d = di.dom[di.dfs_order[b->index]];
+ FOR_EACH_BB (b)
+ {
+ TBB d = di.dom[di.dfs_order[b->index]];
+
+ if (di.dfs_to_bb[d])
+ et_set_father (b->dom[dir], di.dfs_to_bb[d]->dom[dir]);
+ }
- if (di.dfs_to_bb[d])
- et_forest_add_edge (info->forest, BB_NODE (info, di.dfs_to_bb[d]), BB_NODE (info, b));
+ free_dom_info (&di);
+ dom_computed[dir] = DOM_NO_FAST_QUERY;
}
- free_dom_info (&di);
- return info;
+ compute_dom_fast_query (dir);
}
-/* Free dominance information. */
+/* Free dominance information for direction DIR. */
void
-free_dominance_info (info)
- dominance_info info;
+free_dominance_info (enum cdi_direction dir)
{
basic_block bb;
- /* Allow users to create new basic block without setting up the dominance
- information for them. */
- FOR_EACH_BB (bb)
- if (bb->index < (int)(info->varray->num_elements - 2)
- && BB_NODE (info, bb))
- delete_from_dominance_info (info, bb);
- delete_from_dominance_info (info, ENTRY_BLOCK_PTR);
- delete_from_dominance_info (info, EXIT_BLOCK_PTR);
- et_forest_delete (info->forest);
- VARRAY_GROW (info->varray, 0);
- free (info);
+ if (!dom_computed[dir])
+ return;
+
+ FOR_ALL_BB (bb)
+ {
+ delete_from_dominance_info (dir, bb);
+ }
+
+ dom_computed[dir] = DOM_NONE;
}
/* Return the immediate dominator of basic block BB. */
basic_block
-get_immediate_dominator (dom, bb)
- dominance_info dom;
- basic_block bb;
+get_immediate_dominator (enum cdi_direction dir, basic_block bb)
{
- return et_forest_node_value (dom->forest,
- et_forest_parent (dom->forest,
- BB_NODE (dom, bb)));
+ struct et_node *node = bb->dom[dir];
+
+ if (!dom_computed[dir])
+ abort ();
+
+ if (!node->father)
+ return NULL;
+
+ return node->father->data;
}
/* Set the immediate dominator of the block possibly removing
existing edge. NULL can be used to remove any edge. */
inline void
-set_immediate_dominator (dom, bb, dominated_by)
- dominance_info dom;
- basic_block bb, dominated_by;
+set_immediate_dominator (enum cdi_direction dir, basic_block bb,
+ basic_block dominated_by)
{
- void *aux_bb_node;
- et_forest_node_t bb_node = BB_NODE (dom, bb);
+ struct et_node *node = bb->dom[dir];
+
+ if (!dom_computed[dir])
+ abort ();
- aux_bb_node = et_forest_parent (dom->forest, bb_node);
- if (aux_bb_node)
- et_forest_remove_edge (dom->forest, aux_bb_node, bb_node);
- if (dominated_by != NULL)
+ if (node->father)
{
- if (bb == dominated_by)
- abort ();
- if (!et_forest_add_edge (dom->forest, BB_NODE (dom, dominated_by), bb_node))
- abort ();
+ if (node->father->data == dominated_by)
+ return;
+ et_split (node);
}
+
+ if (dominated_by)
+ et_set_father (node, dominated_by->dom[dir]);
+
+ if (dom_computed[dir] == DOM_OK)
+ dom_computed[dir] = DOM_NO_FAST_QUERY;
}
-/* Store all basic blocks dominated by BB into BBS and return their number. */
+/* Store all basic blocks immediately dominated by BB into BBS and return
+ their number. */
int
-get_dominated_by (dom, bb, bbs)
- dominance_info dom;
- basic_block bb;
- basic_block **bbs;
+get_dominated_by (enum cdi_direction dir, basic_block bb, basic_block **bbs)
{
- int n, i;
+ int n;
+ struct et_node *node = bb->dom[dir], *son = node->son, *ason;
+
+ if (!dom_computed[dir])
+ abort ();
+
+ if (!son)
+ {
+ *bbs = NULL;
+ return 0;
+ }
+
+ for (ason = son->right, n = 1; ason != son; ason = ason->right)
+ n++;
+
+ *bbs = xmalloc (n * sizeof (basic_block));
+ (*bbs)[0] = son->data;
+ for (ason = son->right, n = 1; ason != son; ason = ason->right)
+ (*bbs)[n++] = ason->data;
- *bbs = xmalloc (n_basic_blocks * sizeof (basic_block));
- n = et_forest_enumerate_sons (dom->forest, BB_NODE (dom, bb), (et_forest_node_t *)*bbs);
- for (i = 0; i < n; i++)
- (*bbs)[i] = et_forest_node_value (dom->forest, (et_forest_node_t)(*bbs)[i]);
return n;
}
/* Redirect all edges pointing to BB to TO. */
void
-redirect_immediate_dominators (dom, bb, to)
- dominance_info dom;
- basic_block bb;
- basic_block to;
+redirect_immediate_dominators (enum cdi_direction dir, basic_block bb,
+ basic_block to)
{
- et_forest_node_t *bbs = xmalloc (n_basic_blocks * sizeof (basic_block));
- et_forest_node_t node = BB_NODE (dom, bb);
- et_forest_node_t node2 = BB_NODE (dom, to);
- int n = et_forest_enumerate_sons (dom->forest, node, bbs);
- int i;
+ struct et_node *bb_node = bb->dom[dir], *to_node = to->dom[dir], *son;
+
+ if (!dom_computed[dir])
+ abort ();
- for (i = 0; i < n; i++)
+ if (!bb_node->son)
+ return;
+
+ while (bb_node->son)
{
- et_forest_remove_edge (dom->forest, node, bbs[i]);
- et_forest_add_edge (dom->forest, node2, bbs[i]);
+ son = bb_node->son;
+
+ et_split (son);
+ et_set_father (son, to_node);
}
- free (bbs);
+
+ if (dom_computed[dir] == DOM_OK)
+ dom_computed[dir] = DOM_NO_FAST_QUERY;
}
/* Find first basic block in the tree dominating both BB1 and BB2. */
basic_block
-nearest_common_dominator (dom, bb1, bb2)
- dominance_info dom;
- basic_block bb1;
- basic_block bb2;
+nearest_common_dominator (enum cdi_direction dir, basic_block bb1, basic_block bb2)
{
+ if (!dom_computed[dir])
+ abort ();
+
if (!bb1)
return bb2;
if (!bb2)
return bb1;
- return et_forest_node_value (dom->forest,
- et_forest_common_ancestor (dom->forest,
- BB_NODE (dom, bb1),
- BB_NODE (dom,
- bb2)));
+
+ return et_nca (bb1->dom[dir], bb2->dom[dir])->data;
}
/* Return TRUE in case BB1 is dominated by BB2. */
bool
-dominated_by_p (dom, bb1, bb2)
- dominance_info dom;
- basic_block bb1;
- basic_block bb2;
+dominated_by_p (enum cdi_direction dir, basic_block bb1, basic_block bb2)
{
- return nearest_common_dominator (dom, bb1, bb2) == bb2;
+ struct et_node *n1 = bb1->dom[dir], *n2 = bb2->dom[dir];
+
+ if (!dom_computed[dir])
+ abort ();
+
+ if (dom_computed[dir] == DOM_OK)
+ return (n1->dfs_num_in >= n2->dfs_num_in
+ && n1->dfs_num_out <= n2->dfs_num_out);
+
+ return et_below (n1, n2);
}
/* Verify invariants of dominator structure. */
void
-verify_dominators (dom)
- dominance_info dom;
+verify_dominators (enum cdi_direction dir)
{
int err = 0;
basic_block bb;
+ if (!dom_computed[dir])
+ abort ();
+
FOR_EACH_BB (bb)
{
basic_block dom_bb;
- dom_bb = recount_dominator (dom, bb);
- if (dom_bb != get_immediate_dominator (dom, bb))
+ dom_bb = recount_dominator (dir, bb);
+ if (dom_bb != get_immediate_dominator (dir, bb))
{
error ("dominator of %d should be %d, not %d",
- bb->index, dom_bb->index, get_immediate_dominator(dom, bb)->index);
+ bb->index, dom_bb->index, get_immediate_dominator(dir, bb)->index);
err = 1;
}
}
@@ -736,17 +771,18 @@ verify_dominators (dom)
/* Recount dominator of BB. */
basic_block
-recount_dominator (dom, bb)
- dominance_info dom;
- basic_block bb;
+recount_dominator (enum cdi_direction dir, basic_block bb)
{
basic_block dom_bb = NULL;
edge e;
+ if (!dom_computed[dir])
+ abort ();
+
for (e = bb->pred; e; e = e->pred_next)
{
- if (!dominated_by_p (dom, e->src, bb))
- dom_bb = nearest_common_dominator (dom, dom_bb, e->src);
+ if (!dominated_by_p (dir, e->src, bb))
+ dom_bb = nearest_common_dominator (dir, dom_bb, e->src);
}
return dom_bb;
@@ -755,58 +791,85 @@ recount_dominator (dom, bb)
/* Iteratively recount dominators of BBS. The change is supposed to be local
and not to grow further. */
void
-iterate_fix_dominators (dom, bbs, n)
- dominance_info dom;
- basic_block *bbs;
- int n;
+iterate_fix_dominators (enum cdi_direction dir, basic_block *bbs, int n)
{
int i, changed = 1;
basic_block old_dom, new_dom;
+ if (!dom_computed[dir])
+ abort ();
+
while (changed)
{
changed = 0;
for (i = 0; i < n; i++)
{
- old_dom = get_immediate_dominator (dom, bbs[i]);
- new_dom = recount_dominator (dom, bbs[i]);
+ old_dom = get_immediate_dominator (dir, bbs[i]);
+ new_dom = recount_dominator (dir, bbs[i]);
if (old_dom != new_dom)
{
changed = 1;
- set_immediate_dominator (dom, bbs[i], new_dom);
+ set_immediate_dominator (dir, bbs[i], new_dom);
}
}
}
}
void
-add_to_dominance_info (dom, bb)
- dominance_info dom;
- basic_block bb;
+add_to_dominance_info (enum cdi_direction dir, basic_block bb)
{
- VARRAY_GROW (dom->varray, last_basic_block + 3);
-#ifdef ENABLE_CHECKING
- if (BB_NODE (dom, bb))
+ if (!dom_computed[dir])
abort ();
-#endif
- SET_BB_NODE (dom, bb, et_forest_add_node (dom->forest, bb));
+
+ if (bb->dom[dir])
+ abort ();
+
+ bb->dom[dir] = et_new_tree (bb);
+
+ if (dom_computed[dir] == DOM_OK)
+ dom_computed[dir] = DOM_NO_FAST_QUERY;
}
void
-delete_from_dominance_info (dom, bb)
- dominance_info dom;
- basic_block bb;
+delete_from_dominance_info (enum cdi_direction dir, basic_block bb)
+{
+ if (!dom_computed[dir])
+ abort ();
+
+ et_free_tree (bb->dom[dir]);
+ bb->dom[dir] = NULL;
+
+ if (dom_computed[dir] == DOM_OK)
+ dom_computed[dir] = DOM_NO_FAST_QUERY;
+}
+
+/* Returns the first son of BB in the dominator or postdominator tree
+ as determined by DIR. */
+
+basic_block
+first_dom_son (enum cdi_direction dir, basic_block bb)
{
- et_forest_remove_node (dom->forest, BB_NODE (dom, bb));
- SET_BB_NODE (dom, bb, NULL);
+ struct et_node *son = bb->dom[dir]->son;
+
+ return son ? son->data : NULL;
+}
+
+/* Returns the next dominance son after BB in the dominator or postdominator
+ tree as determined by DIR, or NULL if it was the last one. */
+
+basic_block
+next_dom_son (enum cdi_direction dir, basic_block bb)
+{
+ struct et_node *next = bb->dom[dir]->right;
+
+ return next->father->son == next ? NULL : next->data;
}
void
-debug_dominance_info (dom)
- dominance_info dom;
+debug_dominance_info (enum cdi_direction dir)
{
basic_block bb, bb2;
FOR_EACH_BB (bb)
- if ((bb2 = get_immediate_dominator (dom, bb)))
+ if ((bb2 = get_immediate_dominator (dir, bb)))
fprintf (stderr, "%i %i\n", bb->index, bb2->index);
}
diff --git a/contrib/gcc/dummy-conditions.c b/contrib/gcc/dummy-conditions.c
index 157f86bd639d..eb3fb4173144 100644
--- a/contrib/gcc/dummy-conditions.c
+++ b/contrib/gcc/dummy-conditions.c
@@ -1,25 +1,27 @@
/* Support for calculating constant conditions.
Copyright (C) 2002 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "gensupport.h"
/* MD generators that are run before insn-conditions.c exists should
diff --git a/contrib/gcc/dwarf2.h b/contrib/gcc/dwarf2.h
index a7f5f0f8d682..0e98a455fabb 100644
--- a/contrib/gcc/dwarf2.h
+++ b/contrib/gcc/dwarf2.h
@@ -4,7 +4,7 @@
Free Software Foundation, Inc.
Written by Gary Funck (gary@intrepid.com) The Ada Joint Program
- Office (AJPO), Florida State Unviversity and Silicon Graphics Inc.
+ Office (AJPO), Florida State University and Silicon Graphics Inc.
provided support for this effort -- June 21, 1995.
Derived from the DWARF 1 implementation written by Ron Guilmette
@@ -38,6 +38,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* This file is shared between GCC and GDB, and should not contain
prototypes. */
+#ifndef GCC_DWARF2_H
+#define GCC_DWARF2_H
+
/* Tag names and codes. */
enum dwarf_tag
{
@@ -628,3 +631,5 @@ enum dwarf_macinfo_record_type
#define DW_EH_PE_aligned 0x50
#define DW_EH_PE_indirect 0x80
+
+#endif /* dwarf2.h */
diff --git a/contrib/gcc/dwarf2asm.c b/contrib/gcc/dwarf2asm.c
index b5a87de86300..5b5056cc9eb6 100644
--- a/contrib/gcc/dwarf2asm.c
+++ b/contrib/gcc/dwarf2asm.c
@@ -1,5 +1,5 @@
/* Dwarf2 assembler output helper routines.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "flags.h"
#include "tree.h"
#include "rtl.h"
@@ -43,9 +45,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
to print a newline, since the caller may want to add a comment. */
void
-dw2_assemble_integer (size, x)
- int size;
- rtx x;
+dw2_assemble_integer (int size, rtx x)
{
const char *op = integer_asm_op (size, FALSE);
@@ -65,13 +65,12 @@ dw2_assemble_integer (size, x)
/* Output an immediate constant in a given size. */
void
-dw2_asm_output_data VPARAMS ((int size, unsigned HOST_WIDE_INT value,
- const char *comment, ...))
+dw2_asm_output_data (int size, unsigned HOST_WIDE_INT value,
+ const char *comment, ...)
{
- VA_OPEN (ap, comment);
- VA_FIXEDARG (ap, int, size);
- VA_FIXEDARG (ap, unsigned HOST_WIDE_INT, value);
- VA_FIXEDARG (ap, const char *, comment);
+ va_list ap;
+
+ va_start (ap, comment);
if (size * 8 < HOST_BITS_PER_WIDE_INT)
value &= ~(~(unsigned HOST_WIDE_INT) 0 << (size * 8));
@@ -85,7 +84,7 @@ dw2_asm_output_data VPARAMS ((int size, unsigned HOST_WIDE_INT value,
}
fputc ('\n', asm_out_file);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Output the difference between two symbols in a given size. */
@@ -95,14 +94,12 @@ dw2_asm_output_data VPARAMS ((int size, unsigned HOST_WIDE_INT value,
symbol must appear after both symbols are defined. */
void
-dw2_asm_output_delta VPARAMS ((int size, const char *lab1, const char *lab2,
- const char *comment, ...))
+dw2_asm_output_delta (int size, const char *lab1, const char *lab2,
+ const char *comment, ...)
{
- VA_OPEN (ap, comment);
- VA_FIXEDARG (ap, int, size);
- VA_FIXEDARG (ap, const char *, lab1);
- VA_FIXEDARG (ap, const char *, lab2);
- VA_FIXEDARG (ap, const char *, comment);
+ va_list ap;
+
+ va_start (ap, comment);
#ifdef ASM_OUTPUT_DWARF_DELTA
ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2);
@@ -119,7 +116,7 @@ dw2_asm_output_delta VPARAMS ((int size, const char *lab1, const char *lab2,
}
fputc ('\n', asm_out_file);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Output a section-relative reference to a label. In general this
@@ -129,13 +126,12 @@ dw2_asm_output_delta VPARAMS ((int size, const char *lab1, const char *lab2,
Some targets have special relocations for this that we must use. */
void
-dw2_asm_output_offset VPARAMS ((int size, const char *label,
- const char *comment, ...))
+dw2_asm_output_offset (int size, const char *label,
+ const char *comment, ...)
{
- VA_OPEN (ap, comment);
- VA_FIXEDARG (ap, int, size);
- VA_FIXEDARG (ap, const char *, label);
- VA_FIXEDARG (ap, const char *, comment);
+ va_list ap;
+
+ va_start (ap, comment);
#ifdef ASM_OUTPUT_DWARF_OFFSET
ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label);
@@ -150,21 +146,20 @@ dw2_asm_output_offset VPARAMS ((int size, const char *label,
}
fputc ('\n', asm_out_file);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Output a self-relative reference to a label, possibly in a
different section or object file. */
void
-dw2_asm_output_pcrel VPARAMS ((int size ATTRIBUTE_UNUSED,
- const char *label ATTRIBUTE_UNUSED,
- const char *comment, ...))
+dw2_asm_output_pcrel (int size ATTRIBUTE_UNUSED,
+ const char *label ATTRIBUTE_UNUSED,
+ const char *comment, ...)
{
- VA_OPEN (ap, comment);
- VA_FIXEDARG (ap, int, size);
- VA_FIXEDARG (ap, const char *, label);
- VA_FIXEDARG (ap, const char *, comment);
+ va_list ap;
+
+ va_start (ap, comment);
#ifdef ASM_OUTPUT_DWARF_PCREL
ASM_OUTPUT_DWARF_PCREL (asm_out_file, size, label);
@@ -182,19 +177,18 @@ dw2_asm_output_pcrel VPARAMS ((int size ATTRIBUTE_UNUSED,
}
fputc ('\n', asm_out_file);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Output an absolute reference to a label. */
void
-dw2_asm_output_addr VPARAMS ((int size, const char *label,
- const char *comment, ...))
+dw2_asm_output_addr (int size, const char *label,
+ const char *comment, ...)
{
- VA_OPEN (ap, comment);
- VA_FIXEDARG (ap, int, size);
- VA_FIXEDARG (ap, const char *, label);
- VA_FIXEDARG (ap, const char *, comment);
+ va_list ap;
+
+ va_start (ap, comment);
dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
@@ -205,19 +199,18 @@ dw2_asm_output_addr VPARAMS ((int size, const char *label,
}
fputc ('\n', asm_out_file);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Similar, but use an RTX expression instead of a text label. */
void
-dw2_asm_output_addr_rtx VPARAMS ((int size, rtx addr,
- const char *comment, ...))
+dw2_asm_output_addr_rtx (int size, rtx addr,
+ const char *comment, ...)
{
- VA_OPEN (ap, comment);
- VA_FIXEDARG (ap, int, size);
- VA_FIXEDARG (ap, rtx, addr);
- VA_FIXEDARG (ap, const char *, comment);
+ va_list ap;
+
+ va_start (ap, comment);
dw2_assemble_integer (size, addr);
@@ -228,19 +221,24 @@ dw2_asm_output_addr_rtx VPARAMS ((int size, rtx addr,
}
fputc ('\n', asm_out_file);
- VA_CLOSE (ap);
+ va_end (ap);
}
+/* Output the first ORIG_LEN characters of STR as a string.
+ If ORIG_LEN is equal to -1, ignore this parameter and output
+ the entire STR instead.
+ If COMMENT is not NULL and comments in the debug information
+ have been requested by the user, append the given COMMENT
+ to the generated output. */
+
void
-dw2_asm_output_nstring VPARAMS ((const char *str, size_t orig_len,
- const char *comment, ...))
+dw2_asm_output_nstring (const char *str, size_t orig_len,
+ const char *comment, ...)
{
size_t i, len;
+ va_list ap;
- VA_OPEN (ap, comment);
- VA_FIXEDARG (ap, const char *, str);
- VA_FIXEDARG (ap, size_t, orig_len);
- VA_FIXEDARG (ap, const char *, comment);
+ va_start (ap, comment);
len = orig_len;
@@ -275,21 +273,19 @@ dw2_asm_output_nstring VPARAMS ((const char *str, size_t orig_len,
assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1);
}
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Return the size of an unsigned LEB128 quantity. */
int
-size_of_uleb128 (value)
- unsigned HOST_WIDE_INT value;
+size_of_uleb128 (unsigned HOST_WIDE_INT value)
{
- int size = 0, byte;
+ int size = 0;
do
{
- byte = (value & 0x7f);
value >>= 7;
size += 1;
}
@@ -301,8 +297,7 @@ size_of_uleb128 (value)
/* Return the size of a signed LEB128 quantity. */
int
-size_of_sleb128 (value)
- HOST_WIDE_INT value;
+size_of_sleb128 (HOST_WIDE_INT value)
{
int size = 0, byte;
@@ -323,8 +318,7 @@ size_of_sleb128 (value)
include leb128. */
int
-size_of_encoded_value (encoding)
- int encoding;
+size_of_encoded_value (int encoding)
{
if (encoding == DW_EH_PE_omit)
return 0;
@@ -346,8 +340,7 @@ size_of_encoded_value (encoding)
/* Yield a name for a given pointer encoding. */
const char *
-eh_data_format_name (format)
- int format;
+eh_data_format_name (int format)
{
#if HAVE_DESIGNATED_INITIALIZERS
#define S(p, v) [p] = v,
@@ -505,16 +498,15 @@ eh_data_format_name (format)
/* Output an unsigned LEB128 quantity. */
void
-dw2_asm_output_data_uleb128 VPARAMS ((unsigned HOST_WIDE_INT value,
- const char *comment, ...))
+dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT value,
+ const char *comment, ...)
{
- VA_OPEN (ap, comment);
- VA_FIXEDARG (ap, unsigned HOST_WIDE_INT, value);
- VA_FIXEDARG (ap, const char *, comment);
+ va_list ap;
+
+ va_start (ap, comment);
#ifdef HAVE_AS_LEB128
- fputs ("\t.uleb128 ", asm_out_file);
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
+ fprintf (asm_out_file, "\t.uleb128 " HOST_WIDE_INT_PRINT_HEX , value);
if (flag_debug_asm && comment)
{
@@ -549,8 +541,8 @@ dw2_asm_output_data_uleb128 VPARAMS ((unsigned HOST_WIDE_INT value,
if (flag_debug_asm)
{
- fprintf (asm_out_file, "\t%s uleb128 ", ASM_COMMENT_START);
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_HEX, value);
+ fprintf (asm_out_file, "\t%s uleb128 " HOST_WIDE_INT_PRINT_HEX,
+ ASM_COMMENT_START, value);
if (comment)
{
fputs ("; ", asm_out_file);
@@ -561,22 +553,21 @@ dw2_asm_output_data_uleb128 VPARAMS ((unsigned HOST_WIDE_INT value,
#endif
fputc ('\n', asm_out_file);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Output a signed LEB128 quantity. */
void
-dw2_asm_output_data_sleb128 VPARAMS ((HOST_WIDE_INT value,
- const char *comment, ...))
+dw2_asm_output_data_sleb128 (HOST_WIDE_INT value,
+ const char *comment, ...)
{
- VA_OPEN (ap, comment);
- VA_FIXEDARG (ap, HOST_WIDE_INT, value);
- VA_FIXEDARG (ap, const char *, comment);
+ va_list ap;
+
+ va_start (ap, comment);
#ifdef HAVE_AS_LEB128
- fputs ("\t.sleb128 ", asm_out_file);
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, value);
+ fprintf (asm_out_file, "\t.sleb128 " HOST_WIDE_INT_PRINT_DEC, value);
if (flag_debug_asm && comment)
{
@@ -614,8 +605,8 @@ dw2_asm_output_data_sleb128 VPARAMS ((HOST_WIDE_INT value,
if (flag_debug_asm)
{
- fprintf (asm_out_file, "\t%s sleb128 ", ASM_COMMENT_START);
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, value);
+ fprintf (asm_out_file, "\t%s sleb128 " HOST_WIDE_INT_PRINT_DEC,
+ ASM_COMMENT_START, value);
if (comment)
{
fputs ("; ", asm_out_file);
@@ -626,18 +617,17 @@ dw2_asm_output_data_sleb128 VPARAMS ((HOST_WIDE_INT value,
#endif
fputc ('\n', asm_out_file);
- VA_CLOSE (ap);
+ va_end (ap);
}
void
-dw2_asm_output_delta_uleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
- const char *lab2 ATTRIBUTE_UNUSED,
- const char *comment, ...))
+dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED,
+ const char *lab2 ATTRIBUTE_UNUSED,
+ const char *comment, ...)
{
- VA_OPEN (ap, comment);
- VA_FIXEDARG (ap, const char *, lab1);
- VA_FIXEDARG (ap, const char *, lab2);
- VA_FIXEDARG (ap, const char *, comment);
+ va_list ap;
+
+ va_start (ap, comment);
#ifdef HAVE_AS_LEB128
fputs ("\t.uleb128 ", asm_out_file);
@@ -655,18 +645,17 @@ dw2_asm_output_delta_uleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
}
fputc ('\n', asm_out_file);
- VA_CLOSE (ap);
+ va_end (ap);
}
void
-dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
- const char *lab2 ATTRIBUTE_UNUSED,
- const char *comment, ...))
+dw2_asm_output_delta_sleb128 (const char *lab1 ATTRIBUTE_UNUSED,
+ const char *lab2 ATTRIBUTE_UNUSED,
+ const char *comment, ...)
{
- VA_OPEN (ap, comment);
- VA_FIXEDARG (ap, const char *, lab1);
- VA_FIXEDARG (ap, const char *, lab2);
- VA_FIXEDARG (ap, const char *, comment);
+ va_list ap;
+
+ va_start (ap, comment);
#ifdef HAVE_AS_LEB128
fputs ("\t.sleb128 ", asm_out_file);
@@ -684,15 +673,15 @@ dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
}
fputc ('\n', asm_out_file);
- VA_CLOSE (ap);
+ va_end (ap);
}
-static int mark_indirect_pool_entry PARAMS ((splay_tree_node, void *));
-static void mark_indirect_pool PARAMS ((PTR arg));
-static rtx dw2_force_const_mem PARAMS ((rtx));
-static int dw2_output_indirect_constant_1 PARAMS ((splay_tree_node, void *));
+static rtx dw2_force_const_mem (rtx);
+static int dw2_output_indirect_constant_1 (splay_tree_node, void *);
-static splay_tree indirect_pool;
+static GTY((param1_is (char *), param2_is (tree))) splay_tree indirect_pool;
+
+static GTY(()) int dw2_const_labelno;
#if defined(HAVE_GAS_HIDDEN) && defined(SUPPORTS_ONE_ONLY)
# define USE_LINKONCE_INDIRECT 1
@@ -700,44 +689,20 @@ static splay_tree indirect_pool;
# define USE_LINKONCE_INDIRECT 0
#endif
-/* Mark all indirect constants for GC. */
-
-static int
-mark_indirect_pool_entry (node, data)
- splay_tree_node node;
- void* data ATTRIBUTE_UNUSED;
-{
- ggc_mark_tree ((tree) node->value);
- return 0;
-}
-
-/* Mark all indirect constants for GC. */
-
-static void
-mark_indirect_pool (arg)
- PTR arg ATTRIBUTE_UNUSED;
-{
- splay_tree_foreach (indirect_pool, mark_indirect_pool_entry, NULL);
-}
-
/* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
memory. Differs from force_const_mem in that a single pool is used for
the entire unit of translation, and the memory is not guaranteed to be
"near" the function in any interesting sense. */
static rtx
-dw2_force_const_mem (x)
- rtx x;
+dw2_force_const_mem (rtx x)
{
splay_tree_node node;
const char *str;
tree decl;
if (! indirect_pool)
- {
- indirect_pool = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
- ggc_add_root (&indirect_pool, 1, sizeof indirect_pool, mark_indirect_pool);
- }
+ indirect_pool = splay_tree_new_ggc (splay_tree_compare_pointers);
if (GET_CODE (x) != SYMBOL_REF)
abort ();
@@ -764,11 +729,10 @@ dw2_force_const_mem (x)
}
else
{
- extern int const_labelno;
char label[32];
- ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
- ++const_labelno;
+ ASM_GENERATE_INTERNAL_LABEL (label, "LDFCM", dw2_const_labelno);
+ ++dw2_const_labelno;
id = get_identifier (label);
decl = build_decl (VAR_DECL, id, ptr_type_node);
DECL_ARTIFICIAL (decl) = 1;
@@ -791,9 +755,8 @@ dw2_force_const_mem (x)
splay_tree_foreach. Emit one queued constant to memory. */
static int
-dw2_output_indirect_constant_1 (node, data)
- splay_tree_node node;
- void* data ATTRIBUTE_UNUSED;
+dw2_output_indirect_constant_1 (splay_tree_node node,
+ void *data ATTRIBUTE_UNUSED)
{
const char *sym;
rtx sym_ref;
@@ -801,7 +764,7 @@ dw2_output_indirect_constant_1 (node, data)
sym = (const char *) node->key;
sym_ref = gen_rtx_SYMBOL_REF (Pmode, sym);
if (USE_LINKONCE_INDIRECT)
- fprintf (asm_out_file, "\t.hidden DW.ref.%s\n", sym);
+ fprintf (asm_out_file, "\t.hidden %sDW.ref.%s\n", user_label_prefix, sym);
assemble_variable ((tree) node->value, 1, 1, 1);
assemble_integer (sym_ref, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
@@ -811,7 +774,7 @@ dw2_output_indirect_constant_1 (node, data)
/* Emit the constants queued through dw2_force_const_mem. */
void
-dw2_output_indirect_constants ()
+dw2_output_indirect_constants (void)
{
if (indirect_pool)
splay_tree_foreach (indirect_pool, dw2_output_indirect_constant_1, NULL);
@@ -820,16 +783,13 @@ dw2_output_indirect_constants ()
/* Like dw2_asm_output_addr_rtx, but encode the pointer as directed. */
void
-dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding,
- rtx addr,
- const char *comment, ...))
+dw2_asm_output_encoded_addr_rtx (int encoding, rtx addr,
+ const char *comment, ...)
{
int size;
+ va_list ap;
- VA_OPEN (ap, comment);
- VA_FIXEDARG (ap, int, encoding);
- VA_FIXEDARG (ap, rtx, addr);
- VA_FIXEDARG (ap, const char *, comment);
+ va_start (ap, comment);
size = size_of_encoded_value (encoding);
@@ -903,5 +863,7 @@ dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding,
}
fputc ('\n', asm_out_file);
- VA_CLOSE (ap);
+ va_end (ap);
}
+
+#include "gt-dwarf2asm.h"
diff --git a/contrib/gcc/dwarf2asm.h b/contrib/gcc/dwarf2asm.h
index 8d6fd18bd89f..1cc599e73993 100644
--- a/contrib/gcc/dwarf2asm.h
+++ b/contrib/gcc/dwarf2asm.h
@@ -1,5 +1,5 @@
/* Dwarf2 assembler output helper routines.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -19,60 +19,55 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-extern void dw2_assemble_integer PARAMS ((int, rtx));
+extern void dw2_assemble_integer (int, rtx);
-extern void dw2_asm_output_data PARAMS ((int, unsigned HOST_WIDE_INT,
- const char *, ...))
+extern void dw2_asm_output_data (int, unsigned HOST_WIDE_INT,
+ const char *, ...)
ATTRIBUTE_NULL_PRINTF_3;
-extern void dw2_asm_output_delta PARAMS ((int, const char *,
- const char *,
- const char *, ...))
+extern void dw2_asm_output_delta (int, const char *, const char *,
+ const char *, ...)
ATTRIBUTE_NULL_PRINTF_4;
-extern void dw2_asm_output_offset PARAMS ((int, const char *,
- const char *, ...))
+extern void dw2_asm_output_offset (int, const char *, const char *, ...)
ATTRIBUTE_NULL_PRINTF_3;
-extern void dw2_asm_output_pcrel PARAMS ((int, const char *,
- const char *, ...))
+extern void dw2_asm_output_pcrel (int, const char *, const char *, ...)
ATTRIBUTE_NULL_PRINTF_3;
-extern void dw2_asm_output_addr PARAMS ((int, const char *,
- const char *, ...))
+extern void dw2_asm_output_addr (int, const char *, const char *, ...)
ATTRIBUTE_NULL_PRINTF_3;
-extern void dw2_asm_output_addr_rtx PARAMS ((int, rtx,
- const char *, ...))
+extern void dw2_asm_output_addr_rtx (int, rtx, const char *, ...)
ATTRIBUTE_NULL_PRINTF_3;
-extern void dw2_asm_output_encoded_addr_rtx PARAMS ((int, rtx,
- const char *, ...))
+extern void dw2_asm_output_encoded_addr_rtx (int, rtx,
+ const char *, ...)
ATTRIBUTE_NULL_PRINTF_3;
-extern void dw2_asm_output_nstring PARAMS ((const char *, size_t,
- const char *, ...))
+extern void dw2_asm_output_nstring (const char *, size_t,
+ const char *, ...)
ATTRIBUTE_NULL_PRINTF_3;
-extern void dw2_asm_output_data_uleb128 PARAMS ((unsigned HOST_WIDE_INT,
- const char *, ...))
+extern void dw2_asm_output_data_uleb128 (unsigned HOST_WIDE_INT,
+ const char *, ...)
ATTRIBUTE_NULL_PRINTF_2;
-extern void dw2_asm_output_data_sleb128 PARAMS ((HOST_WIDE_INT,
- const char *, ...))
+extern void dw2_asm_output_data_sleb128 (HOST_WIDE_INT,
+ const char *, ...)
ATTRIBUTE_NULL_PRINTF_2;
-extern void dw2_asm_output_delta_uleb128 PARAMS ((const char *, const char *,
- const char *, ...))
+extern void dw2_asm_output_delta_uleb128 (const char *, const char *,
+ const char *, ...)
ATTRIBUTE_NULL_PRINTF_3;
-extern void dw2_asm_output_delta_sleb128 PARAMS ((const char *, const char *,
- const char *, ...))
+extern void dw2_asm_output_delta_sleb128 (const char *, const char *,
+ const char *, ...)
ATTRIBUTE_NULL_PRINTF_3;
-extern int size_of_uleb128 PARAMS ((unsigned HOST_WIDE_INT));
-extern int size_of_sleb128 PARAMS ((HOST_WIDE_INT));
-extern int size_of_encoded_value PARAMS ((int));
-extern const char *eh_data_format_name PARAMS ((int));
+extern int size_of_uleb128 (unsigned HOST_WIDE_INT);
+extern int size_of_sleb128 (HOST_WIDE_INT);
+extern int size_of_encoded_value (int);
+extern const char *eh_data_format_name (int);
-extern void dw2_output_indirect_constants PARAMS ((void));
+extern void dw2_output_indirect_constants (void);
diff --git a/contrib/gcc/dwarf2out.c b/contrib/gcc/dwarf2out.c
index bd86bc42d8be..a2d866931c72 100644
--- a/contrib/gcc/dwarf2out.c
+++ b/contrib/gcc/dwarf2out.c
@@ -1,6 +1,6 @@
-/* Output Dwarf2 format symbol table information from the GNU C compiler.
- Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
- Free Software Foundation, Inc.
+/* Output Dwarf2 format symbol table information from GCC.
+ Copyright (C) 1992, 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004 Free Software Foundation, Inc.
Contributed by Gary Funck (gary@intrepid.com).
Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com).
Extensively modified by Jason Merrill (jason@cygnus.com).
@@ -36,6 +36,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "real.h"
@@ -61,11 +63,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "debug.h"
#include "target.h"
#include "langhooks.h"
-#include "hashtable.h"
#include "hashtab.h"
+#include "cgraph.h"
#ifdef DWARF2_DEBUGGING_INFO
-static void dwarf2out_source_line PARAMS ((unsigned int, const char *));
+static void dwarf2out_source_line (unsigned int, const char *);
#endif
/* DWARF2 Abbreviation Glossary:
@@ -90,7 +92,7 @@ static void dwarf2out_source_line PARAMS ((unsigned int, const char *));
translation unit. */
int
-dwarf2out_do_frame ()
+dwarf2out_do_frame (void)
{
return (write_symbols == DWARF2_DEBUG
|| write_symbols == VMS_AND_DWARF2_DEBUG
@@ -109,12 +111,12 @@ dwarf2out_do_frame ()
#define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
#endif
-/* Default version of targetm.eh_frame_section. Note this must appear
- outside the DWARF2_DEBUGGING_INFO || DWARF2_UNWIND_INFO macro
- guards. */
+/* Various versions of targetm.eh_frame_section. Note these must appear
+ outside the DWARF2_DEBUGGING_INFO || DWARF2_UNWIND_INFO macro guards. */
+/* Version of targetm.eh_frame_section for systems with named sections. */
void
-default_eh_frame_section ()
+named_section_eh_frame_section (void)
{
#ifdef EH_FRAME_SECTION_NAME
#ifdef HAVE_LD_RO_RW_SECTION_MIXING
@@ -135,13 +137,29 @@ default_eh_frame_section ()
#else
named_section_flags (EH_FRAME_SECTION_NAME, SECTION_WRITE);
#endif
-#else
+#endif
+}
+
+/* Version of targetm.eh_frame_section for systems using collect2. */
+void
+collect2_eh_frame_section (void)
+{
tree label = get_file_function_name ('F');
data_section ();
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
(*targetm.asm_out.globalize_label) (asm_out_file, IDENTIFIER_POINTER (label));
ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
+}
+
+/* Default version of targetm.eh_frame_section. */
+void
+default_eh_frame_section (void)
+{
+#ifdef EH_FRAME_SECTION_NAME
+ named_section_eh_frame_section ();
+#else
+ collect2_eh_frame_section ();
#endif
}
@@ -161,8 +179,6 @@ static GTY(()) varray_type incomplete_types;
define type declaration DIE's. */
static GTY(()) varray_type decl_scope_table;
-#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
-
/* How to start an assembler comment. */
#ifndef ASM_COMMENT_START
#define ASM_COMMENT_START ";#"
@@ -177,21 +193,31 @@ typedef union dw_cfi_oprnd_struct *dw_cfi_oprnd_ref;
and address fields are provided as possible operands;
their use is selected by the opcode field. */
-typedef union dw_cfi_oprnd_struct
+enum dw_cfi_oprnd_type {
+ dw_cfi_oprnd_unused,
+ dw_cfi_oprnd_reg_num,
+ dw_cfi_oprnd_offset,
+ dw_cfi_oprnd_addr,
+ dw_cfi_oprnd_loc
+};
+
+typedef union dw_cfi_oprnd_struct GTY(())
{
- unsigned long dw_cfi_reg_num;
- long int dw_cfi_offset;
- const char *dw_cfi_addr;
- struct dw_loc_descr_struct *dw_cfi_loc;
+ unsigned long GTY ((tag ("dw_cfi_oprnd_reg_num"))) dw_cfi_reg_num;
+ HOST_WIDE_INT GTY ((tag ("dw_cfi_oprnd_offset"))) dw_cfi_offset;
+ const char * GTY ((tag ("dw_cfi_oprnd_addr"))) dw_cfi_addr;
+ struct dw_loc_descr_struct * GTY ((tag ("dw_cfi_oprnd_loc"))) dw_cfi_loc;
}
dw_cfi_oprnd;
-typedef struct dw_cfi_struct
+typedef struct dw_cfi_struct GTY(())
{
dw_cfi_ref dw_cfi_next;
enum dwarf_call_frame_info dw_cfi_opc;
- dw_cfi_oprnd dw_cfi_oprnd1;
- dw_cfi_oprnd dw_cfi_oprnd2;
+ dw_cfi_oprnd GTY ((desc ("dw_cfi_oprnd1_desc (%1.dw_cfi_opc)")))
+ dw_cfi_oprnd1;
+ dw_cfi_oprnd GTY ((desc ("dw_cfi_oprnd2_desc (%1.dw_cfi_opc)")))
+ dw_cfi_oprnd2;
}
dw_cfi_node;
@@ -200,11 +226,11 @@ dw_cfi_node;
It can now be either REG + CFA_OFFSET or *(REG + BASE_OFFSET) + CFA_OFFSET.
Instead of passing around REG and OFFSET, we pass a copy
of this structure. */
-typedef struct cfa_loc
+typedef struct cfa_loc GTY(())
{
unsigned long reg;
- long offset;
- long base_offset;
+ HOST_WIDE_INT offset;
+ HOST_WIDE_INT base_offset;
int indirect; /* 1 if CFA is accessed via a dereference. */
} dw_cfa_location;
@@ -214,7 +240,7 @@ typedef struct cfa_loc
CIE obviates the need to keep track of multiple CIE's
in the DWARF generation routines below. */
-typedef struct dw_fde_struct
+typedef struct dw_fde_struct GTY(())
{
const char *dw_fde_begin;
const char *dw_fde_current_label;
@@ -248,6 +274,18 @@ dw_fde_node;
#define DWARF_OFFSET_SIZE 4
#endif
+/* According to the (draft) DWARF 3 specification, the initial length
+ should either be 4 or 12 bytes. When it's 12 bytes, the first 4
+ bytes are 0xffffffff, followed by the length stored in the next 8
+ bytes.
+
+ However, the SGI/MIPS ABI uses an initial length which is equal to
+ DWARF_OFFSET_SIZE. It is defined (elsewhere) accordingly. */
+
+#ifndef DWARF_INITIAL_LENGTH_SIZE
+#define DWARF_INITIAL_LENGTH_SIZE (DWARF_OFFSET_SIZE == 4 ? 4 : 12)
+#endif
+
#define DWARF_VERSION 2
/* Round SIZE up to the nearest BOUNDARY. */
@@ -265,67 +303,71 @@ dw_fde_node;
/* A pointer to the base of a table that contains frame description
information for each routine. */
-static dw_fde_ref fde_table;
+static GTY((length ("fde_table_allocated"))) dw_fde_ref fde_table;
/* Number of elements currently allocated for fde_table. */
-static unsigned fde_table_allocated;
+static GTY(()) unsigned fde_table_allocated;
/* Number of elements in fde_table currently in use. */
-static unsigned fde_table_in_use;
+static GTY(()) unsigned fde_table_in_use;
/* Size (in elements) of increments by which we may expand the
fde_table. */
#define FDE_TABLE_INCREMENT 256
/* A list of call frame insns for the CIE. */
-static dw_cfi_ref cie_cfi_head;
+static GTY(()) dw_cfi_ref cie_cfi_head;
+#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
/* Some DWARF extensions (e.g., MIPS/SGI) implement a subprogram
attribute that accelerates the lookup of the FDE associated
with the subprogram. This variable holds the table index of the FDE
associated with the current function (body) definition. */
static unsigned current_funcdef_fde;
+#endif
-struct ht *debug_str_hash;
-
-struct indirect_string_node
+struct indirect_string_node GTY(())
{
- struct ht_identifier id;
+ const char *str;
unsigned int refcount;
unsigned int form;
char *label;
};
+static GTY ((param_is (struct indirect_string_node))) htab_t debug_str_hash;
+
+static GTY(()) int dw2_string_counter;
+static GTY(()) unsigned long dwarf2out_cfi_label_num;
+
+#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
+
/* Forward declarations for functions defined in this file. */
-static char *stripattributes PARAMS ((const char *));
-static const char *dwarf_cfi_name PARAMS ((unsigned));
-static dw_cfi_ref new_cfi PARAMS ((void));
-static void add_cfi PARAMS ((dw_cfi_ref *, dw_cfi_ref));
-static void add_fde_cfi PARAMS ((const char *, dw_cfi_ref));
-static void lookup_cfa_1 PARAMS ((dw_cfi_ref,
- dw_cfa_location *));
-static void lookup_cfa PARAMS ((dw_cfa_location *));
-static void reg_save PARAMS ((const char *, unsigned,
- unsigned, long));
-static void initial_return_save PARAMS ((rtx));
-static long stack_adjust_offset PARAMS ((rtx));
-static void output_cfi PARAMS ((dw_cfi_ref, dw_fde_ref, int));
-static void output_call_frame_info PARAMS ((int));
-static void dwarf2out_stack_adjust PARAMS ((rtx));
-static void queue_reg_save PARAMS ((const char *, rtx, long));
-static void flush_queued_reg_saves PARAMS ((void));
-static bool clobbers_queued_reg_save PARAMS ((rtx));
-static void dwarf2out_frame_debug_expr PARAMS ((rtx, const char *));
+static char *stripattributes (const char *);
+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 (dw_cfa_location *);
+static void reg_save (const char *, unsigned, unsigned, HOST_WIDE_INT);
+static void initial_return_save (rtx);
+static HOST_WIDE_INT stack_adjust_offset (rtx);
+static void output_cfi (dw_cfi_ref, dw_fde_ref, int);
+static void output_call_frame_info (int);
+static void dwarf2out_stack_adjust (rtx);
+static void queue_reg_save (const char *, rtx, HOST_WIDE_INT);
+static void flush_queued_reg_saves (void);
+static bool clobbers_queued_reg_save (rtx);
+static void dwarf2out_frame_debug_expr (rtx, const char *);
/* Support for complex CFA locations. */
-static void output_cfa_loc PARAMS ((dw_cfi_ref));
-static void get_cfa_from_loc_descr PARAMS ((dw_cfa_location *,
- struct dw_loc_descr_struct *));
+static void output_cfa_loc (dw_cfi_ref);
+static void get_cfa_from_loc_descr (dw_cfa_location *,
+ struct dw_loc_descr_struct *);
static struct dw_loc_descr_struct *build_cfa_loc
- PARAMS ((dw_cfa_location *));
-static void def_cfa_1 PARAMS ((const char *,
- dw_cfa_location *));
+ (dw_cfa_location *);
+static void def_cfa_1 (const char *, dw_cfa_location *);
/* How to start an assembler comment. */
#ifndef ASM_COMMENT_START
@@ -365,9 +407,9 @@ static void def_cfa_1 PARAMS ((const char *,
registers. */
#ifndef DWARF_FRAME_RETURN_COLUMN
#ifdef PC_REGNUM
-#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (PC_REGNUM)
+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (PC_REGNUM)
#else
-#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGISTERS
+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGISTERS
#endif
#endif
@@ -386,7 +428,7 @@ static void def_cfa_1 PARAMS ((const char *,
/* Hook used by __throw. */
rtx
-expand_builtin_dwarf_sp_column ()
+expand_builtin_dwarf_sp_column (void)
{
return GEN_INT (DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM));
}
@@ -395,8 +437,7 @@ expand_builtin_dwarf_sp_column ()
attributes stripped off, and an asterisk prepended (for assemble_name). */
static inline char *
-stripattributes (s)
- const char *s;
+stripattributes (const char *s)
{
char *stripped = xmalloc (strlen (s) + 2);
char *p = stripped;
@@ -413,20 +454,30 @@ stripattributes (s)
/* Generate code to initialize the register size table. */
void
-expand_builtin_init_dwarf_reg_sizes (address)
- tree address;
+expand_builtin_init_dwarf_reg_sizes (tree address)
{
int i;
enum machine_mode mode = TYPE_MODE (char_type_node);
rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0);
rtx mem = gen_rtx_MEM (BLKmode, addr);
+ bool wrote_return_column = false;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (DWARF_FRAME_REGNUM (i) < DWARF_FRAME_REGISTERS)
{
HOST_WIDE_INT offset = DWARF_FRAME_REGNUM (i) * GET_MODE_SIZE (mode);
- HOST_WIDE_INT size = GET_MODE_SIZE (reg_raw_mode[i]);
+ enum machine_mode save_mode = reg_raw_mode[i];
+ HOST_WIDE_INT size;
+ if (HARD_REGNO_CALL_PART_CLOBBERED (i, save_mode))
+ save_mode = choose_hard_reg_mode (i, 1, true);
+ if (DWARF_FRAME_REGNUM (i) == DWARF_FRAME_RETURN_COLUMN)
+ {
+ if (save_mode == VOIDmode)
+ continue;
+ wrote_return_column = true;
+ }
+ size = GET_MODE_SIZE (save_mode);
if (offset < 0)
continue;
@@ -434,20 +485,27 @@ expand_builtin_init_dwarf_reg_sizes (address)
}
#ifdef DWARF_ALT_FRAME_RETURN_COLUMN
- {
- enum machine_mode save_mode = Pmode;
- HOST_WIDE_INT offset = DWARF_ALT_FRAME_RETURN_COLUMN * GET_MODE_SIZE (mode);
- HOST_WIDE_INT size = GET_MODE_SIZE (save_mode);
- emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
- }
+ if (! wrote_return_column)
+ abort ();
+ i = DWARF_ALT_FRAME_RETURN_COLUMN;
+ wrote_return_column = false;
+#else
+ i = DWARF_FRAME_RETURN_COLUMN;
#endif
+
+ if (! wrote_return_column)
+ {
+ enum machine_mode save_mode = Pmode;
+ HOST_WIDE_INT offset = i * GET_MODE_SIZE (mode);
+ HOST_WIDE_INT size = GET_MODE_SIZE (save_mode);
+ emit_move_insn (adjust_address (mem, mode, offset), GEN_INT (size));
+ }
}
/* Convert a DWARF call frame info. operation to its string name */
static const char *
-dwarf_cfi_name (cfi_opc)
- unsigned cfi_opc;
+dwarf_cfi_name (unsigned int cfi_opc)
{
switch (cfi_opc)
{
@@ -520,9 +578,9 @@ dwarf_cfi_name (cfi_opc)
/* Return a pointer to a newly allocated Call Frame Instruction. */
static inline dw_cfi_ref
-new_cfi ()
+new_cfi (void)
{
- dw_cfi_ref cfi = (dw_cfi_ref) xmalloc (sizeof (dw_cfi_node));
+ dw_cfi_ref cfi = ggc_alloc (sizeof (dw_cfi_node));
cfi->dw_cfi_next = NULL;
cfi->dw_cfi_oprnd1.dw_cfi_reg_num = 0;
@@ -534,9 +592,7 @@ new_cfi ()
/* Add a Call Frame Instruction to list of instructions. */
static inline void
-add_cfi (list_head, cfi)
- dw_cfi_ref *list_head;
- dw_cfi_ref cfi;
+add_cfi (dw_cfi_ref *list_head, dw_cfi_ref cfi)
{
dw_cfi_ref *p;
@@ -550,12 +606,11 @@ add_cfi (list_head, cfi)
/* Generate a new label for the CFI info to refer to. */
char *
-dwarf2out_cfi_label ()
+dwarf2out_cfi_label (void)
{
static char label[20];
- static unsigned long label_num = 0;
- ASM_GENERATE_INTERNAL_LABEL (label, "LCFI", label_num++);
+ ASM_GENERATE_INTERNAL_LABEL (label, "LCFI", dwarf2out_cfi_label_num++);
ASM_OUTPUT_LABEL (asm_out_file, label);
return label;
}
@@ -564,9 +619,7 @@ dwarf2out_cfi_label ()
or to the CIE if LABEL is NULL. */
static void
-add_fde_cfi (label, cfi)
- const char *label;
- dw_cfi_ref cfi;
+add_fde_cfi (const char *label, dw_cfi_ref cfi)
{
if (label)
{
@@ -599,9 +652,7 @@ add_fde_cfi (label, cfi)
/* Subroutine of lookup_cfa. */
static inline void
-lookup_cfa_1 (cfi, loc)
- dw_cfi_ref cfi;
- dw_cfa_location *loc;
+lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc)
{
switch (cfi->dw_cfi_opc)
{
@@ -626,8 +677,7 @@ lookup_cfa_1 (cfi, loc)
/* Find the previous value for the CFA. */
static void
-lookup_cfa (loc)
- dw_cfa_location *loc;
+lookup_cfa (dw_cfa_location *loc)
{
dw_cfi_ref cfi;
@@ -655,20 +705,17 @@ static dw_cfa_location cfa;
static dw_cfa_location cfa_store;
/* The running total of the size of arguments pushed onto the stack. */
-static long args_size;
+static HOST_WIDE_INT args_size;
/* The last args_size we actually output. */
-static long old_args_size;
+static HOST_WIDE_INT old_args_size;
/* Entry point to update the canonical frame address (CFA).
LABEL is passed to add_fde_cfi. The value of CFA is now to be
calculated from REG+OFFSET. */
void
-dwarf2out_def_cfa (label, reg, offset)
- const char *label;
- unsigned reg;
- long offset;
+dwarf2out_def_cfa (const char *label, unsigned int reg, HOST_WIDE_INT offset)
{
dw_cfa_location loc;
loc.indirect = 0;
@@ -682,9 +729,7 @@ dwarf2out_def_cfa (label, reg, offset)
the dw_cfa_location structure. */
static void
-def_cfa_1 (label, loc_p)
- const char *label;
- dw_cfa_location *loc_p;
+def_cfa_1 (const char *label, dw_cfa_location *loc_p)
{
dw_cfi_ref cfi;
dw_cfa_location old_cfa, loc;
@@ -757,11 +802,7 @@ def_cfa_1 (label, loc_p)
otherwise it is saved in SREG. */
static void
-reg_save (label, reg, sreg, offset)
- const char *label;
- unsigned reg;
- unsigned sreg;
- long offset;
+reg_save (const char *label, unsigned int reg, unsigned int sreg, HOST_WIDE_INT offset)
{
dw_cfi_ref cfi = new_cfi ();
@@ -784,7 +825,7 @@ reg_save (label, reg, sreg, offset)
DWARF_CIE_DATA_ALIGNMENT, there is either a bug in the
definition of DWARF_CIE_DATA_ALIGNMENT, or a bug in the machine
description. */
- long check_offset = offset / DWARF_CIE_DATA_ALIGNMENT;
+ HOST_WIDE_INT check_offset = offset / DWARF_CIE_DATA_ALIGNMENT;
if (check_offset * DWARF_CIE_DATA_ALIGNMENT != offset)
abort ();
@@ -816,8 +857,7 @@ reg_save (label, reg, sreg, offset)
assuming 0(cfa)) and what registers are in the window. */
void
-dwarf2out_window_save (label)
- const char *label;
+dwarf2out_window_save (const char *label)
{
dw_cfi_ref cfi = new_cfi ();
@@ -829,9 +869,7 @@ dwarf2out_window_save (label)
pushed onto the stack. */
void
-dwarf2out_args_size (label, size)
- const char *label;
- long size;
+dwarf2out_args_size (const char *label, HOST_WIDE_INT size)
{
dw_cfi_ref cfi;
@@ -850,10 +888,7 @@ dwarf2out_args_size (label, size)
number. LABEL and OFFSET are passed to reg_save. */
void
-dwarf2out_reg_save (label, reg, offset)
- const char *label;
- unsigned reg;
- long offset;
+dwarf2out_reg_save (const char *label, unsigned int reg, HOST_WIDE_INT offset)
{
reg_save (label, DWARF_FRAME_REGNUM (reg), -1, offset);
}
@@ -862,9 +897,7 @@ dwarf2out_reg_save (label, reg, offset)
LABEL and OFFSET are passed to reg_save. */
void
-dwarf2out_return_save (label, offset)
- const char *label;
- long offset;
+dwarf2out_return_save (const char *label, HOST_WIDE_INT offset)
{
reg_save (label, DWARF_FRAME_RETURN_COLUMN, -1, offset);
}
@@ -873,9 +906,7 @@ dwarf2out_return_save (label, offset)
LABEL and SREG are passed to reg_save. */
void
-dwarf2out_return_reg (label, sreg)
- const char *label;
- unsigned sreg;
+dwarf2out_return_reg (const char *label, unsigned int sreg)
{
reg_save (label, DWARF_FRAME_RETURN_COLUMN, sreg, 0);
}
@@ -884,8 +915,7 @@ dwarf2out_return_reg (label, sreg)
INCOMING_RETURN_ADDR_RTX. */
static void
-initial_return_save (rtl)
- rtx rtl;
+initial_return_save (rtx rtl)
{
unsigned int reg = (unsigned int) -1;
HOST_WIDE_INT offset = 0;
@@ -945,9 +975,8 @@ initial_return_save (rtl)
/* Given a SET, calculate the amount of stack adjustment it
contains. */
-static long
-stack_adjust_offset (pattern)
- rtx pattern;
+static HOST_WIDE_INT
+stack_adjust_offset (rtx pattern)
{
rtx src = SET_SRC (pattern);
rtx dest = SET_DEST (pattern);
@@ -1022,13 +1051,19 @@ stack_adjust_offset (pattern)
much extra space it needs to pop off the stack. */
static void
-dwarf2out_stack_adjust (insn)
- rtx insn;
+dwarf2out_stack_adjust (rtx insn)
{
HOST_WIDE_INT offset;
const char *label;
int i;
+ /* Don't handle epilogues at all. Certainly it would be wrong to do so
+ 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))
+ return;
+
if (!flag_asynchronous_unwind_tables && GET_CODE (insn) == CALL_INSN)
{
/* Extract the size of the args from the CALL rtx itself. */
@@ -1093,27 +1128,28 @@ dwarf2out_stack_adjust (insn)
dwarf2out_args_size (label, args_size);
}
+#endif
+
/* We delay emitting a register save until either (a) we reach the end
of the prologue or (b) the register is clobbered. This clusters
register saves so that there are fewer pc advances. */
-struct queued_reg_save
+struct queued_reg_save GTY(())
{
struct queued_reg_save *next;
rtx reg;
- long cfa_offset;
+ HOST_WIDE_INT cfa_offset;
};
-static struct queued_reg_save *queued_reg_saves;
+static GTY(()) struct queued_reg_save *queued_reg_saves;
+
+#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
static const char *last_reg_save_label;
static void
-queue_reg_save (label, reg, offset)
- const char *label;
- rtx reg;
- long offset;
+queue_reg_save (const char *label, rtx reg, HOST_WIDE_INT offset)
{
- struct queued_reg_save *q = (struct queued_reg_save *) xmalloc (sizeof (*q));
+ struct queued_reg_save *q = ggc_alloc (sizeof (*q));
q->next = queued_reg_saves;
q->reg = reg;
@@ -1124,7 +1160,7 @@ queue_reg_save (label, reg, offset)
}
static void
-flush_queued_reg_saves ()
+flush_queued_reg_saves (void)
{
struct queued_reg_save *q, *next;
@@ -1132,7 +1168,6 @@ flush_queued_reg_saves ()
{
dwarf2out_reg_save (last_reg_save_label, REGNO (q->reg), q->cfa_offset);
next = q->next;
- free (q);
}
queued_reg_saves = NULL;
@@ -1140,8 +1175,7 @@ flush_queued_reg_saves ()
}
static bool
-clobbers_queued_reg_save (insn)
- rtx insn;
+clobbers_queued_reg_save (rtx insn)
{
struct queued_reg_save *q;
@@ -1204,7 +1238,7 @@ static dw_cfa_location cfa_temp;
to track stores to the stack via fp or a temp reg.
Rules 1- 4: Setting a register's value to cfa.reg or an expression
- with cfa.reg as the first operand changes the cfa.reg and its
+ with cfa.reg as the first operand changes the cfa.reg and its
cfa.offset. Rule 1 and 4 also set cfa_temp.reg and
cfa_temp.offset.
@@ -1227,7 +1261,7 @@ static dw_cfa_location cfa_temp;
Rule 1:
(set <reg1> <reg2>:cfa.reg)
effects: cfa.reg = <reg1>
- cfa.offset unchanged
+ cfa.offset unchanged
cfa_temp.reg = <reg1>
cfa_temp.offset = cfa.offset
@@ -1235,19 +1269,19 @@ static dw_cfa_location cfa_temp;
(set sp ({minus,plus,losum} {sp,fp}:cfa.reg
{<const_int>,<reg>:cfa_temp.reg}))
effects: cfa.reg = sp if fp used
- cfa.offset += {+/- <const_int>, cfa_temp.offset} if cfa.reg==sp
+ cfa.offset += {+/- <const_int>, cfa_temp.offset} if cfa.reg==sp
cfa_store.offset += {+/- <const_int>, cfa_temp.offset}
if cfa_store.reg==sp
Rule 3:
(set fp ({minus,plus,losum} <reg>:cfa.reg <const_int>))
effects: cfa.reg = fp
- cfa_offset += +/- <const_int>
+ cfa_offset += +/- <const_int>
Rule 4:
(set <reg1> ({plus,losum} <reg2>:cfa.reg <const_int>))
constraints: <reg1> != fp
- <reg1> != sp
+ <reg1> != sp
effects: cfa.reg = <reg1>
cfa_temp.reg = <reg1>
cfa_temp.offset = cfa.offset
@@ -1255,14 +1289,14 @@ static dw_cfa_location cfa_temp;
Rule 5:
(set <reg1> (plus <reg2>:cfa_temp.reg sp:cfa.reg))
constraints: <reg1> != fp
- <reg1> != sp
+ <reg1> != sp
effects: cfa_store.reg = <reg1>
- cfa_store.offset = cfa.offset - cfa_temp.offset
+ cfa_store.offset = cfa.offset - cfa_temp.offset
Rule 6:
(set <reg> <const_int>)
effects: cfa_temp.reg = <reg>
- cfa_temp.offset = <const_int>
+ cfa_temp.offset = <const_int>
Rule 7:
(set <reg1>:cfa_temp.reg (ior <reg2>:cfa_temp.reg <const_int>))
@@ -1276,7 +1310,7 @@ static dw_cfa_location cfa_temp;
Rule 9:
(set <reg> (lo_sum <exp> <const_int>))
effects: cfa_temp.reg = <reg>
- cfa_temp.offset = <const_int>
+ cfa_temp.offset = <const_int>
Rule 10:
(set (mem (pre_modify sp:cfa_store (???? <reg1> <const_int>))) <reg2>)
@@ -1311,9 +1345,7 @@ static dw_cfa_location cfa_temp;
cfa_temp.offset -= mode_size(mem) */
static void
-dwarf2out_frame_debug_expr (expr, label)
- rtx expr;
- const char *label;
+dwarf2out_frame_debug_expr (rtx expr, const char *label)
{
rtx src, dest;
HOST_WIDE_INT offset;
@@ -1348,7 +1380,7 @@ dwarf2out_frame_debug_expr (expr, label)
case REG:
/* Rule 1 */
/* Update the CFA rule wrt SP or FP. Make sure src is
- relative to the current CFA register. */
+ relative to the current CFA register. */
switch (GET_CODE (src))
{
/* Setting FP from SP. */
@@ -1611,7 +1643,7 @@ dwarf2out_frame_debug_expr (expr, label)
else
{
/* Otherwise, we'll need to look in the stack to
- calculate the CFA. */
+ calculate the CFA. */
rtx x = XEXP (dest, 0);
if (GET_CODE (x) != REG)
@@ -1641,8 +1673,7 @@ dwarf2out_frame_debug_expr (expr, label)
register to the stack. If INSN is NULL_RTX, initialize our state. */
void
-dwarf2out_frame_debug (insn)
- rtx insn;
+dwarf2out_frame_debug (rtx insn)
{
const char *label;
rtx src;
@@ -1685,32 +1716,111 @@ dwarf2out_frame_debug (insn)
dwarf2out_frame_debug_expr (insn, label);
}
+#endif
+
+/* Describe for the GTY machinery what parts of dw_cfi_oprnd1 are used. */
+static enum dw_cfi_oprnd_type dw_cfi_oprnd1_desc
+ (enum dwarf_call_frame_info cfi);
+
+static enum dw_cfi_oprnd_type
+dw_cfi_oprnd1_desc (enum dwarf_call_frame_info cfi)
+{
+ switch (cfi)
+ {
+ case DW_CFA_nop:
+ case DW_CFA_GNU_window_save:
+ return dw_cfi_oprnd_unused;
+
+ case DW_CFA_set_loc:
+ case DW_CFA_advance_loc1:
+ case DW_CFA_advance_loc2:
+ case DW_CFA_advance_loc4:
+ case DW_CFA_MIPS_advance_loc8:
+ return dw_cfi_oprnd_addr;
+
+ case DW_CFA_offset:
+ case DW_CFA_offset_extended:
+ case DW_CFA_def_cfa:
+ case DW_CFA_offset_extended_sf:
+ case DW_CFA_def_cfa_sf:
+ case DW_CFA_restore_extended:
+ case DW_CFA_undefined:
+ case DW_CFA_same_value:
+ case DW_CFA_def_cfa_register:
+ case DW_CFA_register:
+ return dw_cfi_oprnd_reg_num;
+
+ case DW_CFA_def_cfa_offset:
+ case DW_CFA_GNU_args_size:
+ case DW_CFA_def_cfa_offset_sf:
+ return dw_cfi_oprnd_offset;
+
+ case DW_CFA_def_cfa_expression:
+ case DW_CFA_expression:
+ return dw_cfi_oprnd_loc;
+
+ default:
+ abort ();
+ }
+}
+
+/* Describe for the GTY machinery what parts of dw_cfi_oprnd2 are used. */
+static enum dw_cfi_oprnd_type dw_cfi_oprnd2_desc
+ (enum dwarf_call_frame_info cfi);
+
+static enum dw_cfi_oprnd_type
+dw_cfi_oprnd2_desc (enum dwarf_call_frame_info cfi)
+{
+ switch (cfi)
+ {
+ case DW_CFA_def_cfa:
+ case DW_CFA_def_cfa_sf:
+ case DW_CFA_offset:
+ case DW_CFA_offset_extended_sf:
+ case DW_CFA_offset_extended:
+ return dw_cfi_oprnd_offset;
+
+ case DW_CFA_register:
+ return dw_cfi_oprnd_reg_num;
+
+ default:
+ return dw_cfi_oprnd_unused;
+ }
+}
+
+#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
+
+/* Map register numbers held in the call frame info that gcc has
+ collected using DWARF_FRAME_REGNUM to those that should be output in
+ .debug_frame and .eh_frame. */
+#ifndef DWARF2_FRAME_REG_OUT
+#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) (REGNO)
+#endif
+
/* Output a Call Frame Information opcode and its operand(s). */
static void
-output_cfi (cfi, fde, for_eh)
- dw_cfi_ref cfi;
- dw_fde_ref fde;
- int for_eh;
+output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
{
+ unsigned long r;
if (cfi->dw_cfi_opc == DW_CFA_advance_loc)
dw2_asm_output_data (1, (cfi->dw_cfi_opc
| (cfi->dw_cfi_oprnd1.dw_cfi_offset & 0x3f)),
- "DW_CFA_advance_loc 0x%lx",
+ "DW_CFA_advance_loc " HOST_WIDE_INT_PRINT_HEX,
cfi->dw_cfi_oprnd1.dw_cfi_offset);
else if (cfi->dw_cfi_opc == DW_CFA_offset)
{
- dw2_asm_output_data (1, (cfi->dw_cfi_opc
- | (cfi->dw_cfi_oprnd1.dw_cfi_reg_num & 0x3f)),
- "DW_CFA_offset, column 0x%lx",
- cfi->dw_cfi_oprnd1.dw_cfi_reg_num);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)),
+ "DW_CFA_offset, column 0x%lx", r);
dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
}
else if (cfi->dw_cfi_opc == DW_CFA_restore)
- dw2_asm_output_data (1, (cfi->dw_cfi_opc
- | (cfi->dw_cfi_oprnd1.dw_cfi_reg_num & 0x3f)),
- "DW_CFA_restore, column 0x%lx",
- cfi->dw_cfi_oprnd1.dw_cfi_reg_num);
+ {
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)),
+ "DW_CFA_restore, column 0x%lx", r);
+ }
else
{
dw2_asm_output_data (1, cfi->dw_cfi_opc,
@@ -1755,15 +1865,15 @@ output_cfi (cfi, fde, for_eh)
case DW_CFA_offset_extended:
case DW_CFA_def_cfa:
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
- NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
break;
case DW_CFA_offset_extended_sf:
case DW_CFA_def_cfa_sf:
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
- NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
dw2_asm_output_data_sleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
break;
@@ -1771,15 +1881,15 @@ output_cfi (cfi, fde, for_eh)
case DW_CFA_undefined:
case DW_CFA_same_value:
case DW_CFA_def_cfa_register:
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
- NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
break;
case DW_CFA_register:
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num,
- NULL);
- dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_reg_num,
- NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
+ r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd2.dw_cfi_reg_num, for_eh);
+ dw2_asm_output_data_uleb128 (r, NULL);
break;
case DW_CFA_def_cfa_offset:
@@ -1809,13 +1919,12 @@ output_cfi (cfi, fde, for_eh)
}
}
-/* Output the call frame information used to used to record information
+/* Output the call frame information used to record information
that relates to calculating the frame pointer, and records the
location of saved registers. */
static void
-output_call_frame_info (for_eh)
- int for_eh;
+output_call_frame_info (int for_eh)
{
unsigned int i;
dw_fde_ref fde;
@@ -1843,7 +1952,8 @@ output_call_frame_info (for_eh)
for (i = 0; i < fde_table_in_use; i++)
if (fde_table[i].uses_eh_lsda)
any_eh_needed = any_lsda_needed = true;
- else if (! fde_table[i].nothrow)
+ else if (! fde_table[i].nothrow
+ && ! fde_table[i].all_throwers_are_sibcalls)
any_eh_needed = true;
if (! any_eh_needed)
@@ -1885,7 +1995,7 @@ output_call_frame_info (for_eh)
/* Augmentation:
z Indicates that a uleb128 is present to size the
- augmentation section.
+ augmentation section.
L Indicates the encoding (and thus presence) of
an LSDA pointer in the FDE augmentation.
R Indicates a non-default pointer encoding for
@@ -1987,7 +2097,7 @@ output_call_frame_info (for_eh)
&& !fde->uses_eh_lsda)
continue;
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, FDE_LABEL, for_eh + i * 2);
+ (*targetm.asm_out.internal_label) (asm_out_file, FDE_LABEL, for_eh + i * 2);
ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + i * 2);
ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + i * 2);
dw2_asm_output_delta (for_eh ? 4 : DWARF_OFFSET_SIZE, l2, l1,
@@ -2040,13 +2150,13 @@ output_call_frame_info (for_eh)
dw2_asm_output_data_uleb128 (size, "Augmentation size");
if (fde->uses_eh_lsda)
- {
- ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA",
+ {
+ ASM_GENERATE_INTERNAL_LABEL (l1, "LLSDA",
fde->funcdef_number);
- dw2_asm_output_encoded_addr_rtx (
+ dw2_asm_output_encoded_addr_rtx (
lsda_encoding, gen_rtx_SYMBOL_REF (Pmode, l1),
- "Language Specific Data Area");
- }
+ "Language Specific Data Area");
+ }
else
{
if (lsda_encoding == DW_EH_PE_aligned)
@@ -2068,7 +2178,7 @@ output_call_frame_info (for_eh)
/* Pad the FDE out to an address sized boundary. */
ASM_OUTPUT_ALIGN (asm_out_file,
- floor_log2 ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE)));
+ floor_log2 ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE)));
ASM_OUTPUT_LABEL (asm_out_file, l2);
}
@@ -2089,9 +2199,8 @@ output_call_frame_info (for_eh)
the prologue. */
void
-dwarf2out_begin_prologue (line, file)
- unsigned int line ATTRIBUTE_UNUSED;
- const char *file ATTRIBUTE_UNUSED;
+dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
+ const char *file ATTRIBUTE_UNUSED)
{
char label[MAX_ARTIFICIAL_LABEL_BYTES];
dw_fde_ref fde;
@@ -2127,9 +2236,10 @@ dwarf2out_begin_prologue (line, file)
if (fde_table_in_use == fde_table_allocated)
{
fde_table_allocated += FDE_TABLE_INCREMENT;
- fde_table
- = (dw_fde_ref) xrealloc (fde_table,
- fde_table_allocated * sizeof (dw_fde_node));
+ fde_table = ggc_realloc (fde_table,
+ fde_table_allocated * sizeof (dw_fde_node));
+ memset (fde_table + fde_table_in_use, 0,
+ FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
}
/* Record the FDE associated with this function. */
@@ -2161,9 +2271,8 @@ dwarf2out_begin_prologue (line, file)
been generated. */
void
-dwarf2out_end_epilogue (line, file)
- unsigned int line ATTRIBUTE_UNUSED;
- const char *file ATTRIBUTE_UNUSED;
+dwarf2out_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
+ const char *file ATTRIBUTE_UNUSED)
{
dw_fde_ref fde;
char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -2178,10 +2287,10 @@ dwarf2out_end_epilogue (line, file)
}
void
-dwarf2out_frame_init ()
+dwarf2out_frame_init (void)
{
/* Allocate the initial hunk of the fde_table. */
- fde_table = (dw_fde_ref) xcalloc (FDE_TABLE_INCREMENT, sizeof (dw_fde_node));
+ fde_table = ggc_alloc_cleared (FDE_TABLE_INCREMENT * sizeof (dw_fde_node));
fde_table_allocated = FDE_TABLE_INCREMENT;
fde_table_in_use = 0;
@@ -2196,7 +2305,7 @@ dwarf2out_frame_init ()
}
void
-dwarf2out_frame_finish ()
+dwarf2out_frame_finish (void)
{
/* Output call frame information. */
if (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
@@ -2205,6 +2314,7 @@ dwarf2out_frame_finish ()
if (! USING_SJLJ_EXCEPTIONS && (flag_unwind_tables || flag_exceptions))
output_call_frame_info (1);
}
+#endif
/* And now, the subset of the debugging information support code necessary
for emitting location expressions. */
@@ -2223,7 +2333,7 @@ typedef struct dw_loc_list_struct *dw_loc_list_ref;
can take on several forms. The forms that are used in this
implementation are listed below. */
-typedef enum
+enum dw_val_class
{
dw_val_class_addr,
dw_val_class_offset,
@@ -2233,69 +2343,69 @@ typedef enum
dw_val_class_const,
dw_val_class_unsigned_const,
dw_val_class_long_long,
- dw_val_class_float,
+ dw_val_class_vec,
dw_val_class_flag,
dw_val_class_die_ref,
dw_val_class_fde_ref,
dw_val_class_lbl_id,
dw_val_class_lbl_offset,
dw_val_class_str
-}
-dw_val_class;
+};
/* Describe a double word constant value. */
/* ??? Every instance of long_long in the code really means CONST_DOUBLE. */
-typedef struct dw_long_long_struct
+typedef struct dw_long_long_struct GTY(())
{
unsigned long hi;
unsigned long low;
}
dw_long_long_const;
-/* Describe a floating point constant value. */
+/* Describe a floating point constant value, or a vector constant value. */
-typedef struct dw_fp_struct
+typedef struct dw_vec_struct GTY(())
{
- long *array;
+ unsigned char * GTY((length ("%h.length"))) array;
unsigned length;
+ unsigned elt_size;
}
-dw_float_const;
+dw_vec_const;
/* The dw_val_node describes an attribute's value, as it is
represented internally. */
-typedef struct dw_val_struct
+typedef struct dw_val_struct GTY(())
{
- dw_val_class val_class;
- union
+ enum dw_val_class val_class;
+ union dw_val_struct_union
{
- rtx val_addr;
- long unsigned val_offset;
- dw_loc_list_ref val_loc_list;
- dw_loc_descr_ref val_loc;
- long int val_int;
- long unsigned val_unsigned;
- dw_long_long_const val_long_long;
- dw_float_const val_float;
- struct
+ rtx GTY ((tag ("dw_val_class_addr"))) val_addr;
+ unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_offset"))) val_offset;
+ dw_loc_list_ref GTY ((tag ("dw_val_class_loc_list"))) val_loc_list;
+ dw_loc_descr_ref GTY ((tag ("dw_val_class_loc"))) val_loc;
+ HOST_WIDE_INT GTY ((default (""))) val_int;
+ unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_unsigned_const"))) val_unsigned;
+ dw_long_long_const GTY ((tag ("dw_val_class_long_long"))) val_long_long;
+ dw_vec_const GTY ((tag ("dw_val_class_vec"))) val_vec;
+ struct dw_val_die_union
{
dw_die_ref die;
int external;
- } val_die_ref;
- unsigned val_fde_index;
- struct indirect_string_node *val_str;
- char *val_lbl_id;
- unsigned char val_flag;
+ } GTY ((tag ("dw_val_class_die_ref"))) val_die_ref;
+ unsigned GTY ((tag ("dw_val_class_fde_ref"))) val_fde_index;
+ struct indirect_string_node * GTY ((tag ("dw_val_class_str"))) val_str;
+ char * GTY ((tag ("dw_val_class_lbl_id"))) val_lbl_id;
+ unsigned char GTY ((tag ("dw_val_class_flag"))) val_flag;
}
- v;
+ GTY ((desc ("%1.val_class"))) v;
}
dw_val_node;
/* Locations in memory are described using a sequence of stack machine
operations. */
-typedef struct dw_loc_descr_struct
+typedef struct dw_loc_descr_struct GTY(())
{
dw_loc_descr_ref dw_loc_next;
enum dwarf_location_atom dw_loc_opc;
@@ -2308,7 +2418,7 @@ dw_loc_descr_node;
/* Location lists are ranges + location descriptions for that range,
so you can track variables that are in different places over
their entire life. */
-typedef struct dw_loc_list_struct
+typedef struct dw_loc_list_struct GTY(())
{
dw_loc_list_ref dw_loc_next;
const char *begin; /* Label for begin address of range */
@@ -2319,22 +2429,21 @@ typedef struct dw_loc_list_struct
dw_loc_descr_ref expr;
} dw_loc_list_node;
-static const char *dwarf_stack_op_name PARAMS ((unsigned));
-static dw_loc_descr_ref new_loc_descr PARAMS ((enum dwarf_location_atom,
- unsigned long,
- unsigned long));
-static void add_loc_descr PARAMS ((dw_loc_descr_ref *,
- dw_loc_descr_ref));
-static unsigned long size_of_loc_descr PARAMS ((dw_loc_descr_ref));
-static unsigned long size_of_locs PARAMS ((dw_loc_descr_ref));
-static void output_loc_operands PARAMS ((dw_loc_descr_ref));
-static void output_loc_sequence PARAMS ((dw_loc_descr_ref));
+#if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO)
+
+static const char *dwarf_stack_op_name (unsigned);
+static dw_loc_descr_ref new_loc_descr (enum dwarf_location_atom,
+ unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT);
+static void add_loc_descr (dw_loc_descr_ref *, dw_loc_descr_ref);
+static unsigned long size_of_loc_descr (dw_loc_descr_ref);
+static unsigned long size_of_locs (dw_loc_descr_ref);
+static void output_loc_operands (dw_loc_descr_ref);
+static void output_loc_sequence (dw_loc_descr_ref);
/* Convert a DWARF stack opcode into its string name. */
static const char *
-dwarf_stack_op_name (op)
- unsigned op;
+dwarf_stack_op_name (unsigned int op)
{
switch (op)
{
@@ -2649,15 +2758,10 @@ dwarf_stack_op_name (op)
together to form more complicated location (address) descriptions. */
static inline dw_loc_descr_ref
-new_loc_descr (op, oprnd1, oprnd2)
- enum dwarf_location_atom op;
- unsigned long oprnd1;
- unsigned long oprnd2;
+new_loc_descr (enum dwarf_location_atom op, unsigned HOST_WIDE_INT oprnd1,
+ unsigned HOST_WIDE_INT oprnd2)
{
- /* Use xcalloc here so we clear out all of the long_long constant in
- the union. */
- dw_loc_descr_ref descr
- = (dw_loc_descr_ref) xcalloc (1, sizeof (dw_loc_descr_node));
+ dw_loc_descr_ref descr = ggc_alloc_cleared (sizeof (dw_loc_descr_node));
descr->dw_loc_opc = op;
descr->dw_loc_oprnd1.val_class = dw_val_class_unsigned_const;
@@ -2672,9 +2776,7 @@ new_loc_descr (op, oprnd1, oprnd2)
/* Add a location description term to a location description expression. */
static inline void
-add_loc_descr (list_head, descr)
- dw_loc_descr_ref *list_head;
- dw_loc_descr_ref descr;
+add_loc_descr (dw_loc_descr_ref *list_head, dw_loc_descr_ref descr)
{
dw_loc_descr_ref *d;
@@ -2688,8 +2790,7 @@ add_loc_descr (list_head, descr)
/* Return the size of a location descriptor. */
static unsigned long
-size_of_loc_descr (loc)
- dw_loc_descr_ref loc;
+size_of_loc_descr (dw_loc_descr_ref loc)
{
unsigned long size = 1;
@@ -2801,8 +2902,7 @@ size_of_loc_descr (loc)
/* Return the size of a series of location descriptors. */
static unsigned long
-size_of_locs (loc)
- dw_loc_descr_ref loc;
+size_of_locs (dw_loc_descr_ref loc)
{
unsigned long size;
@@ -2818,8 +2918,7 @@ size_of_locs (loc)
/* Output location description stack opcode's operands (if any). */
static void
-output_loc_operands (loc)
- dw_loc_descr_ref loc;
+output_loc_operands (dw_loc_descr_ref loc)
{
dw_val_ref val1 = &loc->dw_loc_oprnd1;
dw_val_ref val2 = &loc->dw_loc_oprnd2;
@@ -2868,9 +2967,9 @@ output_loc_operands (loc)
case DW_OP_skip:
case DW_OP_bra:
/* We currently don't make any attempt to make sure these are
- aligned properly like we do for the main unwind info, so
- don't support emitting things larger than a byte if we're
- only doing unwinding. */
+ aligned properly like we do for the main unwind info, so
+ don't support emitting things larger than a byte if we're
+ only doing unwinding. */
abort ();
#endif
case DW_OP_const1u:
@@ -2960,8 +3059,7 @@ output_loc_operands (loc)
/* Output a sequence of location operations. */
static void
-output_loc_sequence (loc)
- dw_loc_descr_ref loc;
+output_loc_sequence (dw_loc_descr_ref loc)
{
for (; loc != NULL; loc = loc->dw_loc_next)
{
@@ -2978,8 +3076,7 @@ output_loc_sequence (loc)
description based on a cfi entry with a complex address. */
static void
-output_cfa_loc (cfi)
- dw_cfi_ref cfi;
+output_cfa_loc (dw_cfi_ref cfi)
{
dw_loc_descr_ref loc;
unsigned long size;
@@ -2997,8 +3094,7 @@ output_cfa_loc (cfi)
a dw_cfa_location. */
static struct dw_loc_descr_struct *
-build_cfa_loc (cfa)
- dw_cfa_location *cfa;
+build_cfa_loc (dw_cfa_location *cfa)
{
struct dw_loc_descr_struct *head, *tmp;
@@ -3033,9 +3129,7 @@ build_cfa_loc (cfa)
descriptor sequence. */
static void
-get_cfa_from_loc_descr (cfa, loc)
- dw_cfa_location *cfa;
- struct dw_loc_descr_struct *loc;
+get_cfa_from_loc_descr (dw_cfa_location *cfa, struct dw_loc_descr_struct *loc)
{
struct dw_loc_descr_struct *ptr;
cfa->offset = 0;
@@ -3143,22 +3237,19 @@ get_cfa_from_loc_descr (cfa, loc)
#ifdef DWARF2_DEBUGGING_INFO
/* .debug_str support. */
-static hashnode indirect_string_alloc PARAMS ((hash_table *));
-static int output_indirect_string PARAMS ((struct cpp_reader *,
- hashnode, const PTR));
-
-
-static void dwarf2out_init PARAMS ((const char *));
-static void dwarf2out_finish PARAMS ((const char *));
-static void dwarf2out_define PARAMS ((unsigned int, const char *));
-static void dwarf2out_undef PARAMS ((unsigned int, const char *));
-static void dwarf2out_start_source_file PARAMS ((unsigned, const char *));
-static void dwarf2out_end_source_file PARAMS ((unsigned));
-static void dwarf2out_begin_block PARAMS ((unsigned, unsigned));
-static void dwarf2out_end_block PARAMS ((unsigned, unsigned));
-static bool dwarf2out_ignore_block PARAMS ((tree));
-static void dwarf2out_global_decl PARAMS ((tree));
-static void dwarf2out_abstract_function PARAMS ((tree));
+static int output_indirect_string (void **, void *);
+
+static void dwarf2out_init (const char *);
+static void dwarf2out_finish (const char *);
+static void dwarf2out_define (unsigned int, const char *);
+static void dwarf2out_undef (unsigned int, const char *);
+static void dwarf2out_start_source_file (unsigned, const char *);
+static void dwarf2out_end_source_file (unsigned);
+static void dwarf2out_begin_block (unsigned, unsigned);
+static void dwarf2out_end_block (unsigned, unsigned);
+static bool dwarf2out_ignore_block (tree);
+static void dwarf2out_global_decl (tree);
+static void dwarf2out_abstract_function (tree);
/* The debug hooks structure. */
@@ -3186,8 +3277,10 @@ const struct gcc_debug_hooks dwarf2_debug_hooks =
emitting the abstract description of inline functions until
something tries to reference them. */
dwarf2out_abstract_function, /* outlining_inline_function */
- debug_nothing_rtx /* label */
+ debug_nothing_rtx, /* label */
+ debug_nothing_int /* handle_pch */
};
+#endif
/* NOTE: In the comments in this file, many references are made to
"Debugging Information Entries". This term is abbreviated as `DIE'
@@ -3216,7 +3309,7 @@ typedef struct dw_ranges_struct *dw_ranges_ref;
entry. The label gives the PC value associated with
the line number entry. */
-typedef struct dw_line_info_struct
+typedef struct dw_line_info_struct GTY(())
{
unsigned long dw_file_num;
unsigned long dw_line_num;
@@ -3225,7 +3318,7 @@ dw_line_info_entry;
/* Line information for functions in separate sections; each one gets its
own sequence. */
-typedef struct dw_separate_line_info_struct
+typedef struct dw_separate_line_info_struct GTY(())
{
unsigned long dw_file_num;
unsigned long dw_line_num;
@@ -3237,7 +3330,7 @@ dw_separate_line_info_entry;
a link to the next attribute in the chain, and an attribute value.
Attributes are typically linked below the DIE they modify. */
-typedef struct dw_attr_struct
+typedef struct dw_attr_struct GTY(())
{
enum dwarf_attribute dw_attr;
dw_attr_ref dw_attr_next;
@@ -3247,7 +3340,7 @@ dw_attr_node;
/* The Debugging Information Entry (DIE) structure */
-typedef struct die_struct
+typedef struct die_struct GTY(())
{
enum dwarf_tag die_tag;
char *die_symbol;
@@ -3255,6 +3348,7 @@ typedef struct die_struct
dw_die_ref die_parent;
dw_die_ref die_child;
dw_die_ref die_sib;
+ dw_die_ref die_definition; /* ref from a specification to its definition */
dw_offset die_offset;
unsigned long die_abbrev;
int die_mark;
@@ -3263,20 +3357,20 @@ die_node;
/* The pubname structure */
-typedef struct pubname_struct
+typedef struct pubname_struct GTY(())
{
dw_die_ref die;
char *name;
}
pubname_entry;
-struct dw_ranges_struct
+struct dw_ranges_struct GTY(())
{
int block_num;
};
/* The limbo die list structure. */
-typedef struct limbo_die_struct
+typedef struct limbo_die_struct GTY(())
{
dw_die_ref die;
tree created_for;
@@ -3314,21 +3408,24 @@ limbo_die_node;
language, and compiler version. */
/* Fixed size portion of the DWARF compilation unit header. */
-#define DWARF_COMPILE_UNIT_HEADER_SIZE (2 * DWARF_OFFSET_SIZE + 3)
+#define DWARF_COMPILE_UNIT_HEADER_SIZE \
+ (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 3)
/* Fixed size portion of public names info. */
#define DWARF_PUBNAMES_HEADER_SIZE (2 * DWARF_OFFSET_SIZE + 2)
/* Fixed size portion of the address range info. */
#define DWARF_ARANGES_HEADER_SIZE \
- (DWARF_ROUND (2 * DWARF_OFFSET_SIZE + 4, DWARF2_ADDR_SIZE * 2) \
- - DWARF_OFFSET_SIZE)
+ (DWARF_ROUND (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 4, \
+ DWARF2_ADDR_SIZE * 2) \
+ - DWARF_INITIAL_LENGTH_SIZE)
/* Size of padding portion in the address range info. It must be
aligned to twice the pointer size. */
#define DWARF_ARANGES_PAD_SIZE \
- (DWARF_ROUND (2 * DWARF_OFFSET_SIZE + 4, DWARF2_ADDR_SIZE * 2) \
- - (2 * DWARF_OFFSET_SIZE + 4))
+ (DWARF_ROUND (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 4, \
+ DWARF2_ADDR_SIZE * 2) \
+ - (DWARF_INITIAL_LENGTH_SIZE + DWARF_OFFSET_SIZE + 4))
/* Use assembler line directives if available. */
#ifndef DWARF2_ASM_LINE_DEBUG_INFO
@@ -3355,50 +3452,33 @@ limbo_die_node;
is not made available by the GCC front-end. */
#define DWARF_LINE_DEFAULT_IS_STMT_START 1
+#ifdef DWARF2_DEBUGGING_INFO
/* This location is used by calc_die_sizes() to keep track
the offset of each DIE within the .debug_info section. */
static unsigned long next_die_offset;
+#endif
/* Record the root of the DIE's built for the current compilation unit. */
-static dw_die_ref comp_unit_die;
-
-/* We need special handling in dwarf2out_start_source_file if it is
- first one. */
-static int is_main_source;
+static GTY(()) dw_die_ref comp_unit_die;
/* A list of DIEs with a NULL parent waiting to be relocated. */
-static limbo_die_node *limbo_die_list = 0;
-
-/* Structure used by lookup_filename to manage sets of filenames. */
-struct file_table
-{
- char **table;
- unsigned allocated;
- unsigned in_use;
- unsigned last_lookup_index;
-};
-
-/* Size (in elements) of increments by which we may expand the filename
- table. */
-#define FILE_TABLE_INCREMENT 64
+static GTY(()) limbo_die_node *limbo_die_list;
/* Filenames referenced by this compilation unit. */
-static struct file_table file_table;
-
-/* Local pointer to the name of the main input file. Initialized in
- dwarf2out_init. */
-static const char *primary_filename;
+static GTY(()) varray_type file_table;
+static GTY(()) varray_type file_table_emitted;
+static GTY(()) size_t file_table_last_lookup_index;
/* A pointer to the base of a table of references to DIE's that describe
declarations. The table is indexed by DECL_UID() which is a unique
number identifying each decl. */
-static dw_die_ref *decl_die_table;
+static GTY((length ("decl_die_table_allocated"))) dw_die_ref *decl_die_table;
/* Number of elements currently allocated for the decl_die_table. */
-static unsigned decl_die_table_allocated;
+static GTY(()) unsigned decl_die_table_allocated;
/* Number of elements in decl_die_table currently in use. */
-static unsigned decl_die_table_in_use;
+static GTY(()) unsigned decl_die_table_in_use;
/* Size (in elements) of increments by which we may expand the
decl_die_table. */
@@ -3407,13 +3487,14 @@ static unsigned decl_die_table_in_use;
/* A pointer to the base of a list of references to DIE's that
are uniquely identified by their tag, presence/absence of
children DIE's, and list of attribute/value pairs. */
-static dw_die_ref *abbrev_die_table;
+static GTY((length ("abbrev_die_table_allocated")))
+ dw_die_ref *abbrev_die_table;
/* Number of elements currently allocated for abbrev_die_table. */
-static unsigned abbrev_die_table_allocated;
+static GTY(()) unsigned abbrev_die_table_allocated;
/* Number of elements in type_die_table currently in use. */
-static unsigned abbrev_die_table_in_use;
+static GTY(()) unsigned abbrev_die_table_in_use;
/* Size (in elements) of increments by which we may expand the
abbrev_die_table. */
@@ -3421,23 +3502,25 @@ static unsigned abbrev_die_table_in_use;
/* A pointer to the base of a table that contains line information
for each source code line in .text in the compilation unit. */
-static dw_line_info_ref line_info_table;
+static GTY((length ("line_info_table_allocated")))
+ dw_line_info_ref line_info_table;
/* Number of elements currently allocated for line_info_table. */
-static unsigned line_info_table_allocated;
+static GTY(()) unsigned line_info_table_allocated;
-/* Number of elements in separate_line_info_table currently in use. */
-static unsigned separate_line_info_table_in_use;
+/* Number of elements in line_info_table currently in use. */
+static GTY(()) unsigned line_info_table_in_use;
/* A pointer to the base of a table that contains line information
for each source code line outside of .text in the compilation unit. */
-static dw_separate_line_info_ref separate_line_info_table;
+static GTY ((length ("separate_line_info_table_allocated")))
+ dw_separate_line_info_ref separate_line_info_table;
/* Number of elements currently allocated for separate_line_info_table. */
-static unsigned separate_line_info_table_allocated;
+static GTY(()) unsigned separate_line_info_table_allocated;
-/* Number of elements in line_info_table currently in use. */
-static unsigned line_info_table_in_use;
+/* Number of elements in separate_line_info_table currently in use. */
+static GTY(()) unsigned separate_line_info_table_in_use;
/* Size (in elements) of increments by which we may expand the
line_info_table. */
@@ -3445,312 +3528,302 @@ static unsigned line_info_table_in_use;
/* A pointer to the base of a table that contains a list of publicly
accessible names. */
-static pubname_ref pubname_table;
+static GTY ((length ("pubname_table_allocated"))) pubname_ref pubname_table;
/* Number of elements currently allocated for pubname_table. */
-static unsigned pubname_table_allocated;
+static GTY(()) unsigned pubname_table_allocated;
/* Number of elements in pubname_table currently in use. */
-static unsigned pubname_table_in_use;
+static GTY(()) unsigned pubname_table_in_use;
/* Size (in elements) of increments by which we may expand the
pubname_table. */
#define PUBNAME_TABLE_INCREMENT 64
/* Array of dies for which we should generate .debug_arange info. */
-static dw_die_ref *arange_table;
+static GTY((length ("arange_table_allocated"))) dw_die_ref *arange_table;
/* Number of elements currently allocated for arange_table. */
-static unsigned arange_table_allocated;
+static GTY(()) unsigned arange_table_allocated;
/* Number of elements in arange_table currently in use. */
-static unsigned arange_table_in_use;
+static GTY(()) unsigned arange_table_in_use;
/* Size (in elements) of increments by which we may expand the
arange_table. */
#define ARANGE_TABLE_INCREMENT 64
/* Array of dies for which we should generate .debug_ranges info. */
-static dw_ranges_ref ranges_table;
+static GTY ((length ("ranges_table_allocated"))) dw_ranges_ref ranges_table;
/* Number of elements currently allocated for ranges_table. */
-static unsigned ranges_table_allocated;
+static GTY(()) unsigned ranges_table_allocated;
/* Number of elements in ranges_table currently in use. */
-static unsigned ranges_table_in_use;
+static GTY(()) unsigned ranges_table_in_use;
/* Size (in elements) of increments by which we may expand the
ranges_table. */
#define RANGES_TABLE_INCREMENT 64
/* Whether we have location lists that need outputting */
-static unsigned have_location_lists;
+static GTY(()) unsigned have_location_lists;
+#ifdef DWARF2_DEBUGGING_INFO
/* Record whether the function being analyzed contains inlined functions. */
static int current_function_has_inlines;
+#endif
#if 0 && defined (MIPS_DEBUGGING_INFO)
static int comp_unit_has_inlines;
#endif
+/* Number of file tables emitted in maybe_emit_file(). */
+static GTY(()) int emitcount = 0;
+
+/* Number of internal labels generated by gen_internal_sym(). */
+static GTY(()) int label_num;
+
+#ifdef DWARF2_DEBUGGING_INFO
+
/* Forward declarations for functions defined in this file. */
-static int is_pseudo_reg PARAMS ((rtx));
-static tree type_main_variant PARAMS ((tree));
-static int is_tagged_type PARAMS ((tree));
-static const char *dwarf_tag_name PARAMS ((unsigned));
-static const char *dwarf_attr_name PARAMS ((unsigned));
-static const char *dwarf_form_name PARAMS ((unsigned));
+static int is_pseudo_reg (rtx);
+static tree type_main_variant (tree);
+static int is_tagged_type (tree);
+static const char *dwarf_tag_name (unsigned);
+static const char *dwarf_attr_name (unsigned);
+static const char *dwarf_form_name (unsigned);
#if 0
-static const char *dwarf_type_encoding_name PARAMS ((unsigned));
+static const char *dwarf_type_encoding_name (unsigned);
#endif
-static tree decl_ultimate_origin PARAMS ((tree));
-static tree block_ultimate_origin PARAMS ((tree));
-static tree decl_class_context PARAMS ((tree));
-static void add_dwarf_attr PARAMS ((dw_die_ref, dw_attr_ref));
-static inline dw_val_class AT_class PARAMS ((dw_attr_ref));
-static void add_AT_flag PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned));
-static inline unsigned AT_flag PARAMS ((dw_attr_ref));
-static void add_AT_int PARAMS ((dw_die_ref,
- enum dwarf_attribute, long));
-static inline long int AT_int PARAMS ((dw_attr_ref));
-static void add_AT_unsigned PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned long));
-static inline unsigned long AT_unsigned PARAMS ((dw_attr_ref));
-static void add_AT_long_long PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned long,
- unsigned long));
-static void add_AT_float PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned, long *));
-static void add_AT_string PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- const char *));
-static inline const char *AT_string PARAMS ((dw_attr_ref));
-static int AT_string_form PARAMS ((dw_attr_ref));
-static void add_AT_die_ref PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- dw_die_ref));
-static inline dw_die_ref AT_ref PARAMS ((dw_attr_ref));
-static inline int AT_ref_external PARAMS ((dw_attr_ref));
-static inline void set_AT_ref_external PARAMS ((dw_attr_ref, int));
-static void add_AT_fde_ref PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned));
-static void add_AT_loc PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- dw_loc_descr_ref));
-static inline dw_loc_descr_ref AT_loc PARAMS ((dw_attr_ref));
-static void add_AT_loc_list PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- dw_loc_list_ref));
-static inline dw_loc_list_ref AT_loc_list PARAMS ((dw_attr_ref));
-static void add_AT_addr PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- rtx));
-static inline rtx AT_addr PARAMS ((dw_attr_ref));
-static void add_AT_lbl_id PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- const char *));
-static void add_AT_lbl_offset PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- const char *));
-static void add_AT_offset PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned long));
-static void add_AT_range_list PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- unsigned long));
-static inline const char *AT_lbl PARAMS ((dw_attr_ref));
-static dw_attr_ref get_AT PARAMS ((dw_die_ref,
- enum dwarf_attribute));
-static const char *get_AT_low_pc PARAMS ((dw_die_ref));
-static const char *get_AT_hi_pc PARAMS ((dw_die_ref));
-static const char *get_AT_string PARAMS ((dw_die_ref,
- enum dwarf_attribute));
-static int get_AT_flag PARAMS ((dw_die_ref,
- enum dwarf_attribute));
-static unsigned get_AT_unsigned PARAMS ((dw_die_ref,
- enum dwarf_attribute));
-static inline dw_die_ref get_AT_ref PARAMS ((dw_die_ref,
- enum dwarf_attribute));
-static int is_c_family PARAMS ((void));
-static int is_cxx PARAMS ((void));
-static int is_java PARAMS ((void));
-static int is_fortran PARAMS ((void));
-static void remove_AT PARAMS ((dw_die_ref,
- enum dwarf_attribute));
-static inline void free_die PARAMS ((dw_die_ref));
-static void remove_children PARAMS ((dw_die_ref));
-static void add_child_die PARAMS ((dw_die_ref, dw_die_ref));
-static dw_die_ref new_die PARAMS ((enum dwarf_tag, dw_die_ref,
- tree));
-static dw_die_ref lookup_type_die PARAMS ((tree));
-static void equate_type_number_to_die PARAMS ((tree, dw_die_ref));
-static dw_die_ref lookup_decl_die PARAMS ((tree));
-static void equate_decl_number_to_die PARAMS ((tree, dw_die_ref));
-static void print_spaces PARAMS ((FILE *));
-static void print_die PARAMS ((dw_die_ref, FILE *));
-static void print_dwarf_line_table PARAMS ((FILE *));
-static void reverse_die_lists PARAMS ((dw_die_ref));
-static void reverse_all_dies PARAMS ((dw_die_ref));
-static dw_die_ref push_new_compile_unit PARAMS ((dw_die_ref, dw_die_ref));
-static dw_die_ref pop_compile_unit PARAMS ((dw_die_ref));
-static void loc_checksum PARAMS ((dw_loc_descr_ref,
- struct md5_ctx *));
-static void attr_checksum PARAMS ((dw_attr_ref,
- struct md5_ctx *,
- int *));
-static void die_checksum PARAMS ((dw_die_ref,
- struct md5_ctx *,
- int *));
-static int same_loc_p PARAMS ((dw_loc_descr_ref,
- dw_loc_descr_ref, int *));
-static int same_dw_val_p PARAMS ((dw_val_node *, dw_val_node *,
- int *));
-static int same_attr_p PARAMS ((dw_attr_ref, dw_attr_ref, int *));
-static int same_die_p PARAMS ((dw_die_ref, dw_die_ref, int *));
-static int same_die_p_wrap PARAMS ((dw_die_ref, dw_die_ref));
-static void compute_section_prefix PARAMS ((dw_die_ref));
-static int is_type_die PARAMS ((dw_die_ref));
-static int is_comdat_die PARAMS ((dw_die_ref));
-static int is_symbol_die PARAMS ((dw_die_ref));
-static void assign_symbol_names PARAMS ((dw_die_ref));
-static void break_out_includes PARAMS ((dw_die_ref));
-static hashval_t htab_cu_hash PARAMS ((const void *));
-static int htab_cu_eq PARAMS ((const void *, const void *));
-static void htab_cu_del PARAMS ((void *));
-static int check_duplicate_cu PARAMS ((dw_die_ref, htab_t, unsigned *));
-static void record_comdat_symbol_number PARAMS ((dw_die_ref, htab_t, unsigned));
-static void add_sibling_attributes PARAMS ((dw_die_ref));
-static void build_abbrev_table PARAMS ((dw_die_ref));
-static void output_location_lists PARAMS ((dw_die_ref));
-static int constant_size PARAMS ((long unsigned));
-static unsigned long size_of_die PARAMS ((dw_die_ref));
-static void calc_die_sizes PARAMS ((dw_die_ref));
-static void mark_dies PARAMS ((dw_die_ref));
-static void unmark_dies PARAMS ((dw_die_ref));
-static void unmark_all_dies PARAMS ((dw_die_ref));
-static unsigned long size_of_pubnames PARAMS ((void));
-static unsigned long size_of_aranges PARAMS ((void));
-static enum dwarf_form value_format PARAMS ((dw_attr_ref));
-static void output_value_format PARAMS ((dw_attr_ref));
-static void output_abbrev_section PARAMS ((void));
-static void output_die_symbol PARAMS ((dw_die_ref));
-static void output_die PARAMS ((dw_die_ref));
-static void output_compilation_unit_header PARAMS ((void));
-static void output_comp_unit PARAMS ((dw_die_ref, int));
-static const char *dwarf2_name PARAMS ((tree, int));
-static void add_pubname PARAMS ((tree, dw_die_ref));
-static void output_pubnames PARAMS ((void));
-static void add_arange PARAMS ((tree, dw_die_ref));
-static void output_aranges PARAMS ((void));
-static unsigned int add_ranges PARAMS ((tree));
-static void output_ranges PARAMS ((void));
-static void output_line_info PARAMS ((void));
-static void output_file_names PARAMS ((void));
-static dw_die_ref base_type_die PARAMS ((tree));
-static tree root_type PARAMS ((tree));
-static int is_base_type PARAMS ((tree));
-static dw_die_ref modified_type_die PARAMS ((tree, int, int, dw_die_ref));
-static int type_is_enum PARAMS ((tree));
-static unsigned int reg_number PARAMS ((rtx));
-static dw_loc_descr_ref reg_loc_descriptor PARAMS ((rtx));
-static dw_loc_descr_ref int_loc_descriptor PARAMS ((HOST_WIDE_INT));
-static dw_loc_descr_ref based_loc_descr PARAMS ((unsigned, long));
-static int is_based_loc PARAMS ((rtx));
-static dw_loc_descr_ref mem_loc_descriptor PARAMS ((rtx, enum machine_mode mode));
-static dw_loc_descr_ref concat_loc_descriptor PARAMS ((rtx, rtx));
-static dw_loc_descr_ref loc_descriptor PARAMS ((rtx));
-static dw_loc_descr_ref loc_descriptor_from_tree PARAMS ((tree, int));
-static HOST_WIDE_INT ceiling PARAMS ((HOST_WIDE_INT, unsigned int));
-static tree field_type PARAMS ((tree));
-static unsigned int simple_type_align_in_bits PARAMS ((tree));
-static unsigned int simple_decl_align_in_bits PARAMS ((tree));
-static unsigned HOST_WIDE_INT simple_type_size_in_bits PARAMS ((tree));
-static HOST_WIDE_INT field_byte_offset PARAMS ((tree));
-static void add_AT_location_description PARAMS ((dw_die_ref,
- enum dwarf_attribute,
- dw_loc_descr_ref));
-static void add_data_member_location_attribute PARAMS ((dw_die_ref, tree));
-static void add_const_value_attribute PARAMS ((dw_die_ref, rtx));
-static rtx rtl_for_decl_location PARAMS ((tree));
-static void add_location_or_const_value_attribute PARAMS ((dw_die_ref, tree));
-static void tree_add_const_value_attribute PARAMS ((dw_die_ref, tree));
-static void add_name_attribute PARAMS ((dw_die_ref, const char *));
-static void add_bound_info PARAMS ((dw_die_ref,
- enum dwarf_attribute, tree));
-static void add_subscript_info PARAMS ((dw_die_ref, tree));
-static void add_byte_size_attribute PARAMS ((dw_die_ref, tree));
-static void add_bit_offset_attribute PARAMS ((dw_die_ref, tree));
-static void add_bit_size_attribute PARAMS ((dw_die_ref, tree));
-static void add_prototyped_attribute PARAMS ((dw_die_ref, tree));
-static void add_abstract_origin_attribute PARAMS ((dw_die_ref, tree));
-static void add_pure_or_virtual_attribute PARAMS ((dw_die_ref, tree));
-static void add_src_coords_attributes PARAMS ((dw_die_ref, tree));
-static void add_name_and_src_coords_attributes PARAMS ((dw_die_ref, tree));
-static void push_decl_scope PARAMS ((tree));
-static void pop_decl_scope PARAMS ((void));
-static dw_die_ref scope_die_for PARAMS ((tree, dw_die_ref));
-static inline int local_scope_p PARAMS ((dw_die_ref));
-static inline int class_scope_p PARAMS ((dw_die_ref));
-static void add_type_attribute PARAMS ((dw_die_ref, tree, int, int,
- dw_die_ref));
-static const char *type_tag PARAMS ((tree));
-static tree member_declared_type PARAMS ((tree));
+static tree decl_ultimate_origin (tree);
+static tree block_ultimate_origin (tree);
+static tree decl_class_context (tree);
+static void add_dwarf_attr (dw_die_ref, dw_attr_ref);
+static inline enum dw_val_class AT_class (dw_attr_ref);
+static void add_AT_flag (dw_die_ref, enum dwarf_attribute, unsigned);
+static inline unsigned AT_flag (dw_attr_ref);
+static void add_AT_int (dw_die_ref, enum dwarf_attribute, HOST_WIDE_INT);
+static inline HOST_WIDE_INT AT_int (dw_attr_ref);
+static void add_AT_unsigned (dw_die_ref, enum dwarf_attribute, unsigned HOST_WIDE_INT);
+static inline unsigned HOST_WIDE_INT AT_unsigned (dw_attr_ref);
+static void add_AT_long_long (dw_die_ref, enum dwarf_attribute, unsigned long,
+ unsigned long);
+static inline void add_AT_vec (dw_die_ref, enum dwarf_attribute, unsigned int,
+ unsigned int, unsigned char *);
+static hashval_t debug_str_do_hash (const void *);
+static int debug_str_eq (const void *, const void *);
+static void add_AT_string (dw_die_ref, enum dwarf_attribute, const char *);
+static inline const char *AT_string (dw_attr_ref);
+static int AT_string_form (dw_attr_ref);
+static void add_AT_die_ref (dw_die_ref, enum dwarf_attribute, dw_die_ref);
+static void add_AT_specification (dw_die_ref, dw_die_ref);
+static inline dw_die_ref AT_ref (dw_attr_ref);
+static inline int AT_ref_external (dw_attr_ref);
+static inline void set_AT_ref_external (dw_attr_ref, int);
+static void add_AT_fde_ref (dw_die_ref, enum dwarf_attribute, unsigned);
+static void add_AT_loc (dw_die_ref, enum dwarf_attribute, dw_loc_descr_ref);
+static inline dw_loc_descr_ref AT_loc (dw_attr_ref);
+static void add_AT_loc_list (dw_die_ref, enum dwarf_attribute,
+ dw_loc_list_ref);
+static inline dw_loc_list_ref AT_loc_list (dw_attr_ref);
+static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx);
+static inline rtx AT_addr (dw_attr_ref);
+static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *);
+static void add_AT_lbl_offset (dw_die_ref, enum dwarf_attribute, const char *);
+static void add_AT_offset (dw_die_ref, enum dwarf_attribute,
+ unsigned HOST_WIDE_INT);
+static void add_AT_range_list (dw_die_ref, enum dwarf_attribute,
+ unsigned long);
+static inline const char *AT_lbl (dw_attr_ref);
+static dw_attr_ref get_AT (dw_die_ref, enum dwarf_attribute);
+static const char *get_AT_low_pc (dw_die_ref);
+static const char *get_AT_hi_pc (dw_die_ref);
+static const char *get_AT_string (dw_die_ref, enum dwarf_attribute);
+static int get_AT_flag (dw_die_ref, enum dwarf_attribute);
+static unsigned get_AT_unsigned (dw_die_ref, enum dwarf_attribute);
+static inline dw_die_ref get_AT_ref (dw_die_ref, enum dwarf_attribute);
+static bool is_c_family (void);
+static bool is_cxx (void);
+static bool is_java (void);
+static bool is_fortran (void);
+static bool is_ada (void);
+static void remove_AT (dw_die_ref, enum dwarf_attribute);
+static inline void free_die (dw_die_ref);
+static void remove_children (dw_die_ref);
+static void add_child_die (dw_die_ref, dw_die_ref);
+static dw_die_ref new_die (enum dwarf_tag, dw_die_ref, tree);
+static dw_die_ref lookup_type_die (tree);
+static void equate_type_number_to_die (tree, dw_die_ref);
+static dw_die_ref lookup_decl_die (tree);
+static void equate_decl_number_to_die (tree, dw_die_ref);
+static void print_spaces (FILE *);
+static void print_die (dw_die_ref, FILE *);
+static void print_dwarf_line_table (FILE *);
+static void reverse_die_lists (dw_die_ref);
+static void reverse_all_dies (dw_die_ref);
+static dw_die_ref push_new_compile_unit (dw_die_ref, dw_die_ref);
+static dw_die_ref pop_compile_unit (dw_die_ref);
+static void loc_checksum (dw_loc_descr_ref, struct md5_ctx *);
+static void attr_checksum (dw_attr_ref, struct md5_ctx *, int *);
+static void die_checksum (dw_die_ref, struct md5_ctx *, int *);
+static int same_loc_p (dw_loc_descr_ref, dw_loc_descr_ref, int *);
+static int same_dw_val_p (dw_val_node *, dw_val_node *, int *);
+static int same_attr_p (dw_attr_ref, dw_attr_ref, int *);
+static int same_die_p (dw_die_ref, dw_die_ref, int *);
+static int same_die_p_wrap (dw_die_ref, dw_die_ref);
+static void compute_section_prefix (dw_die_ref);
+static int is_type_die (dw_die_ref);
+static int is_comdat_die (dw_die_ref);
+static int is_symbol_die (dw_die_ref);
+static void assign_symbol_names (dw_die_ref);
+static void break_out_includes (dw_die_ref);
+static hashval_t htab_cu_hash (const void *);
+static int htab_cu_eq (const void *, const void *);
+static void htab_cu_del (void *);
+static int check_duplicate_cu (dw_die_ref, htab_t, unsigned *);
+static void record_comdat_symbol_number (dw_die_ref, htab_t, unsigned);
+static void add_sibling_attributes (dw_die_ref);
+static void build_abbrev_table (dw_die_ref);
+static void output_location_lists (dw_die_ref);
+static int constant_size (long unsigned);
+static unsigned long size_of_die (dw_die_ref);
+static void calc_die_sizes (dw_die_ref);
+static void mark_dies (dw_die_ref);
+static void unmark_dies (dw_die_ref);
+static void unmark_all_dies (dw_die_ref);
+static unsigned long size_of_pubnames (void);
+static unsigned long size_of_aranges (void);
+static enum dwarf_form value_format (dw_attr_ref);
+static void output_value_format (dw_attr_ref);
+static void output_abbrev_section (void);
+static void output_die_symbol (dw_die_ref);
+static void output_die (dw_die_ref);
+static void output_compilation_unit_header (void);
+static void output_comp_unit (dw_die_ref, int);
+static const char *dwarf2_name (tree, int);
+static void add_pubname (tree, dw_die_ref);
+static void output_pubnames (void);
+static void add_arange (tree, dw_die_ref);
+static void output_aranges (void);
+static unsigned int add_ranges (tree);
+static void output_ranges (void);
+static void output_line_info (void);
+static void output_file_names (void);
+static dw_die_ref base_type_die (tree);
+static tree root_type (tree);
+static int is_base_type (tree);
+static bool is_subrange_type (tree);
+static dw_die_ref subrange_type_die (tree, dw_die_ref);
+static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
+static int type_is_enum (tree);
+static unsigned int dbx_reg_number (rtx);
+static dw_loc_descr_ref reg_loc_descriptor (rtx);
+static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int);
+static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx);
+static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT);
+static dw_loc_descr_ref based_loc_descr (unsigned, HOST_WIDE_INT);
+static int is_based_loc (rtx);
+static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode);
+static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx);
+static dw_loc_descr_ref loc_descriptor (rtx);
+static dw_loc_descr_ref loc_descriptor_from_tree (tree, int);
+static HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int);
+static tree field_type (tree);
+static unsigned int simple_type_align_in_bits (tree);
+static unsigned int simple_decl_align_in_bits (tree);
+static unsigned HOST_WIDE_INT simple_type_size_in_bits (tree);
+static HOST_WIDE_INT field_byte_offset (tree);
+static void add_AT_location_description (dw_die_ref, enum dwarf_attribute,
+ dw_loc_descr_ref);
+static void add_data_member_location_attribute (dw_die_ref, tree);
+static void add_const_value_attribute (dw_die_ref, rtx);
+static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *);
+static HOST_WIDE_INT extract_int (const unsigned char *, unsigned);
+static void insert_float (rtx, unsigned char *);
+static rtx rtl_for_decl_location (tree);
+static void add_location_or_const_value_attribute (dw_die_ref, tree);
+static void tree_add_const_value_attribute (dw_die_ref, tree);
+static void add_name_attribute (dw_die_ref, const char *);
+static void add_comp_dir_attribute (dw_die_ref);
+static void add_bound_info (dw_die_ref, enum dwarf_attribute, tree);
+static void add_subscript_info (dw_die_ref, tree);
+static void add_byte_size_attribute (dw_die_ref, tree);
+static void add_bit_offset_attribute (dw_die_ref, tree);
+static void add_bit_size_attribute (dw_die_ref, tree);
+static void add_prototyped_attribute (dw_die_ref, tree);
+static void add_abstract_origin_attribute (dw_die_ref, tree);
+static void add_pure_or_virtual_attribute (dw_die_ref, tree);
+static void add_src_coords_attributes (dw_die_ref, tree);
+static void add_name_and_src_coords_attributes (dw_die_ref, tree);
+static void push_decl_scope (tree);
+static void pop_decl_scope (void);
+static dw_die_ref scope_die_for (tree, dw_die_ref);
+static inline int local_scope_p (dw_die_ref);
+static inline int class_or_namespace_scope_p (dw_die_ref);
+static void add_type_attribute (dw_die_ref, tree, int, int, dw_die_ref);
+static const char *type_tag (tree);
+static tree member_declared_type (tree);
#if 0
-static const char *decl_start_label PARAMS ((tree));
+static const char *decl_start_label (tree);
#endif
-static void gen_array_type_die PARAMS ((tree, dw_die_ref));
-static void gen_set_type_die PARAMS ((tree, dw_die_ref));
+static void gen_array_type_die (tree, dw_die_ref);
+static void gen_set_type_die (tree, dw_die_ref);
#if 0
-static void gen_entry_point_die PARAMS ((tree, dw_die_ref));
+static void gen_entry_point_die (tree, dw_die_ref);
#endif
-static void gen_inlined_enumeration_type_die PARAMS ((tree, dw_die_ref));
-static void gen_inlined_structure_type_die PARAMS ((tree, dw_die_ref));
-static void gen_inlined_union_type_die PARAMS ((tree, dw_die_ref));
-static void gen_enumeration_type_die PARAMS ((tree, dw_die_ref));
-static dw_die_ref gen_formal_parameter_die PARAMS ((tree, dw_die_ref));
-static void gen_unspecified_parameters_die PARAMS ((tree, dw_die_ref));
-static void gen_formal_types_die PARAMS ((tree, dw_die_ref));
-static void gen_subprogram_die PARAMS ((tree, dw_die_ref));
-static void gen_variable_die PARAMS ((tree, dw_die_ref));
-static void gen_label_die PARAMS ((tree, dw_die_ref));
-static void gen_lexical_block_die PARAMS ((tree, dw_die_ref, int));
-static void gen_inlined_subroutine_die PARAMS ((tree, dw_die_ref, int));
-static void gen_field_die PARAMS ((tree, dw_die_ref));
-static void gen_ptr_to_mbr_type_die PARAMS ((tree, dw_die_ref));
-static dw_die_ref gen_compile_unit_die PARAMS ((const char *));
-static void gen_string_type_die PARAMS ((tree, dw_die_ref));
-static void gen_inheritance_die PARAMS ((tree, dw_die_ref));
-static void gen_member_die PARAMS ((tree, dw_die_ref));
-static void gen_struct_or_union_type_die PARAMS ((tree, dw_die_ref));
-static void gen_subroutine_type_die PARAMS ((tree, dw_die_ref));
-static void gen_typedef_die PARAMS ((tree, dw_die_ref));
-static void gen_type_die PARAMS ((tree, dw_die_ref));
-static void gen_tagged_type_instantiation_die PARAMS ((tree, dw_die_ref));
-static void gen_block_die PARAMS ((tree, dw_die_ref, int));
-static void decls_for_scope PARAMS ((tree, dw_die_ref, int));
-static int is_redundant_typedef PARAMS ((tree));
-static void gen_decl_die PARAMS ((tree, dw_die_ref));
-static unsigned lookup_filename PARAMS ((const char *));
-static void init_file_table PARAMS ((void));
-static void retry_incomplete_types PARAMS ((void));
-static void gen_type_die_for_member PARAMS ((tree, tree, dw_die_ref));
-static void splice_child_die PARAMS ((dw_die_ref, dw_die_ref));
-static int file_info_cmp PARAMS ((const void *, const void *));
-static dw_loc_list_ref new_loc_list PARAMS ((dw_loc_descr_ref,
- const char *, const char *,
- const char *, unsigned));
-static void add_loc_descr_to_loc_list PARAMS ((dw_loc_list_ref *,
- dw_loc_descr_ref,
- const char *, const char *, const char *));
-static void output_loc_list PARAMS ((dw_loc_list_ref));
-static char *gen_internal_sym PARAMS ((const char *));
-static void mark_limbo_die_list PARAMS ((void *));
+static void gen_inlined_enumeration_type_die (tree, dw_die_ref);
+static void gen_inlined_structure_type_die (tree, dw_die_ref);
+static void gen_inlined_union_type_die (tree, dw_die_ref);
+static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
+static dw_die_ref gen_formal_parameter_die (tree, dw_die_ref);
+static void gen_unspecified_parameters_die (tree, dw_die_ref);
+static void gen_formal_types_die (tree, dw_die_ref);
+static void gen_subprogram_die (tree, dw_die_ref);
+static void gen_variable_die (tree, dw_die_ref);
+static void gen_label_die (tree, dw_die_ref);
+static void gen_lexical_block_die (tree, dw_die_ref, int);
+static void gen_inlined_subroutine_die (tree, dw_die_ref, int);
+static void gen_field_die (tree, dw_die_ref);
+static void gen_ptr_to_mbr_type_die (tree, dw_die_ref);
+static dw_die_ref gen_compile_unit_die (const char *);
+static void gen_string_type_die (tree, dw_die_ref);
+static void gen_inheritance_die (tree, tree, dw_die_ref);
+static void gen_member_die (tree, dw_die_ref);
+static void gen_struct_or_union_type_die (tree, dw_die_ref);
+static void gen_subroutine_type_die (tree, dw_die_ref);
+static void gen_typedef_die (tree, dw_die_ref);
+static void gen_type_die (tree, dw_die_ref);
+static void gen_tagged_type_instantiation_die (tree, dw_die_ref);
+static void gen_block_die (tree, dw_die_ref, int);
+static void decls_for_scope (tree, dw_die_ref, int);
+static int is_redundant_typedef (tree);
+static void gen_namespace_die (tree);
+static void gen_decl_die (tree, dw_die_ref);
+static dw_die_ref force_namespace_die (tree);
+static dw_die_ref setup_namespace_context (tree, dw_die_ref);
+static void declare_in_namespace (tree, dw_die_ref);
+static unsigned lookup_filename (const char *);
+static void init_file_table (void);
+static void retry_incomplete_types (void);
+static void gen_type_die_for_member (tree, tree, dw_die_ref);
+static void splice_child_die (dw_die_ref, dw_die_ref);
+static int file_info_cmp (const void *, const void *);
+static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *,
+ const char *, const char *, unsigned);
+static void add_loc_descr_to_loc_list (dw_loc_list_ref *, dw_loc_descr_ref,
+ const char *, const char *,
+ const char *);
+static void output_loc_list (dw_loc_list_ref);
+static char *gen_internal_sym (const char *);
+
+static void prune_unmark_dies (dw_die_ref);
+static void prune_unused_types_mark (dw_die_ref, int);
+static void prune_unused_types_walk (dw_die_ref);
+static void prune_unused_types_walk_attribs (dw_die_ref);
+static void prune_unused_types_prune (dw_die_ref);
+static void prune_unused_types (void);
+static int maybe_emit_file (int);
/* Section names used to hold DWARF debugging information. */
#ifndef DEBUG_INFO_SECTION
@@ -3787,12 +3860,10 @@ static void mark_limbo_die_list PARAMS ((void *));
#endif
/* Section flags for .debug_str section. */
-#ifdef HAVE_GAS_SHF_MERGE
#define DEBUG_STR_SECTION_FLAGS \
- (SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1)
-#else
-#define DEBUG_STR_SECTION_FLAGS SECTION_DEBUG
-#endif
+ (HAVE_GAS_SHF_MERGE && flag_merge_constants \
+ ? SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1 \
+ : SECTION_DEBUG)
/* Labels we insert at beginning sections we can reference instead of
the section names themselves. */
@@ -3821,7 +3892,7 @@ static void mark_limbo_die_list PARAMS ((void *));
/* Definitions of defaults for formats and names of various special
(artificial) labels which may be generated within this file (when the -g
- options is used and DWARF_DEBUGGING_INFO is in effect.
+ options is used and DWARF2_DEBUGGING_INFO is in effect.
If necessary, these may be overridden from within the tm.h file, but
typically, overriding these defaults is unnecessary. */
@@ -3853,11 +3924,10 @@ static char ranges_section_label[2 * MAX_ARTIFICIAL_LABEL_BYTES];
/* We allow a language front-end to designate a function that is to be
called to "demangle" any name before it it put into a DIE. */
-static const char *(*demangle_name_func) PARAMS ((const char *));
+static const char *(*demangle_name_func) (const char *);
void
-dwarf2out_set_demangle_name_func (func)
- const char *(*func) PARAMS ((const char *));
+dwarf2out_set_demangle_name_func (const char *(*func) (const char *))
{
demangle_name_func = func;
}
@@ -3865,8 +3935,7 @@ dwarf2out_set_demangle_name_func (func)
/* Test if rtl node points to a pseudo register. */
static inline int
-is_pseudo_reg (rtl)
- rtx rtl;
+is_pseudo_reg (rtx rtl)
{
return ((GET_CODE (rtl) == REG && REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
|| (GET_CODE (rtl) == SUBREG
@@ -3877,8 +3946,7 @@ is_pseudo_reg (rtl)
removed. */
static inline tree
-type_main_variant (type)
- tree type;
+type_main_variant (tree type)
{
type = TYPE_MAIN_VARIANT (type);
@@ -3897,8 +3965,7 @@ type_main_variant (type)
/* Return nonzero if the given type node represents a tagged type. */
static inline int
-is_tagged_type (type)
- tree type;
+is_tagged_type (tree type)
{
enum tree_code code = TREE_CODE (type);
@@ -3909,8 +3976,7 @@ is_tagged_type (type)
/* Convert a DIE tag into its string name. */
static const char *
-dwarf_tag_name (tag)
- unsigned tag;
+dwarf_tag_name (unsigned int tag)
{
switch (tag)
{
@@ -3992,6 +4058,8 @@ dwarf_tag_name (tag)
return "DW_TAG_namelist";
case DW_TAG_namelist_item:
return "DW_TAG_namelist_item";
+ case DW_TAG_namespace:
+ return "DW_TAG_namespace";
case DW_TAG_packed_type:
return "DW_TAG_packed_type";
case DW_TAG_subprogram:
@@ -4030,8 +4098,7 @@ dwarf_tag_name (tag)
/* Convert a DWARF attribute code into its string name. */
static const char *
-dwarf_attr_name (attr)
- unsigned attr;
+dwarf_attr_name (unsigned int attr)
{
switch (attr)
{
@@ -4234,8 +4301,7 @@ dwarf_attr_name (attr)
/* Convert a DWARF value form code into its string name. */
static const char *
-dwarf_form_name (form)
- unsigned form;
+dwarf_form_name (unsigned int form)
{
switch (form)
{
@@ -4290,8 +4356,7 @@ dwarf_form_name (form)
#if 0
static const char *
-dwarf_type_encoding_name (enc)
- unsigned enc;
+dwarf_type_encoding_name (unsigned enc)
{
switch (enc)
{
@@ -4324,8 +4389,7 @@ dwarf_type_encoding_name (enc)
given block. */
static tree
-decl_ultimate_origin (decl)
- tree decl;
+decl_ultimate_origin (tree decl)
{
/* output_inline_function sets DECL_ABSTRACT_ORIGIN for all the
nodes in the function to point to themselves; ignore that if
@@ -4350,8 +4414,7 @@ decl_ultimate_origin (decl)
given block. */
static tree
-block_ultimate_origin (block)
- tree block;
+block_ultimate_origin (tree block)
{
tree immediate_origin = BLOCK_ABSTRACT_ORIGIN (block);
@@ -4385,8 +4448,7 @@ block_ultimate_origin (block)
parameter. */
static tree
-decl_class_context (decl)
- tree decl;
+decl_class_context (tree decl)
{
tree context = NULL_TREE;
@@ -4406,9 +4468,7 @@ decl_class_context (decl)
addition order, and correct that in reverse_all_dies. */
static inline void
-add_dwarf_attr (die, attr)
- dw_die_ref die;
- dw_attr_ref attr;
+add_dwarf_attr (dw_die_ref die, dw_attr_ref attr)
{
if (die != NULL && attr != NULL)
{
@@ -4417,9 +4477,8 @@ add_dwarf_attr (die, attr)
}
}
-static inline dw_val_class
-AT_class (a)
- dw_attr_ref a;
+static inline enum dw_val_class
+AT_class (dw_attr_ref a)
{
return a->dw_attr_val.val_class;
}
@@ -4427,12 +4486,9 @@ AT_class (a)
/* Add a flag value attribute to a DIE. */
static inline void
-add_AT_flag (die, attr_kind, flag)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned flag;
+add_AT_flag (dw_die_ref die, enum dwarf_attribute attr_kind, unsigned int flag)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4442,8 +4498,7 @@ add_AT_flag (die, attr_kind, flag)
}
static inline unsigned
-AT_flag (a)
- dw_attr_ref a;
+AT_flag (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_flag)
return a->dw_attr_val.v.val_flag;
@@ -4454,12 +4509,9 @@ AT_flag (a)
/* Add a signed integer attribute value to a DIE. */
static inline void
-add_AT_int (die, attr_kind, int_val)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- long int int_val;
+add_AT_int (dw_die_ref die, enum dwarf_attribute attr_kind, HOST_WIDE_INT int_val)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4468,9 +4520,8 @@ add_AT_int (die, attr_kind, int_val)
add_dwarf_attr (die, attr);
}
-static inline long int
-AT_int (a)
- dw_attr_ref a;
+static inline HOST_WIDE_INT
+AT_int (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_const)
return a->dw_attr_val.v.val_int;
@@ -4481,12 +4532,10 @@ AT_int (a)
/* Add an unsigned integer attribute value to a DIE. */
static inline void
-add_AT_unsigned (die, attr_kind, unsigned_val)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned long unsigned_val;
+add_AT_unsigned (dw_die_ref die, enum dwarf_attribute attr_kind,
+ unsigned HOST_WIDE_INT unsigned_val)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4495,9 +4544,8 @@ add_AT_unsigned (die, attr_kind, unsigned_val)
add_dwarf_attr (die, attr);
}
-static inline unsigned long
-AT_unsigned (a)
- dw_attr_ref a;
+static inline unsigned HOST_WIDE_INT
+AT_unsigned (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_unsigned_const)
return a->dw_attr_val.v.val_unsigned;
@@ -4508,13 +4556,10 @@ AT_unsigned (a)
/* Add an unsigned double integer attribute value to a DIE. */
static inline void
-add_AT_long_long (die, attr_kind, val_hi, val_low)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned long val_hi;
- unsigned long val_low;
+add_AT_long_long (dw_die_ref die, enum dwarf_attribute attr_kind,
+ long unsigned int val_hi, long unsigned int val_low)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4527,42 +4572,54 @@ add_AT_long_long (die, attr_kind, val_hi, val_low)
/* Add a floating point attribute value to a DIE and return it. */
static inline void
-add_AT_float (die, attr_kind, length, array)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned length;
- long *array;
+add_AT_vec (dw_die_ref die, enum dwarf_attribute attr_kind,
+ unsigned int length, unsigned int elt_size, unsigned char *array)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
- attr->dw_attr_val.val_class = dw_val_class_float;
- attr->dw_attr_val.v.val_float.length = length;
- attr->dw_attr_val.v.val_float.array = array;
+ attr->dw_attr_val.val_class = dw_val_class_vec;
+ attr->dw_attr_val.v.val_vec.length = length;
+ attr->dw_attr_val.v.val_vec.elt_size = elt_size;
+ attr->dw_attr_val.v.val_vec.array = array;
add_dwarf_attr (die, attr);
}
+/* Hash and equality functions for debug_str_hash. */
+
+static hashval_t
+debug_str_do_hash (const void *x)
+{
+ return htab_hash_string (((const struct indirect_string_node *)x)->str);
+}
+
+static int
+debug_str_eq (const void *x1, const void *x2)
+{
+ return strcmp ((((const struct indirect_string_node *)x1)->str),
+ (const char *)x2) == 0;
+}
+
/* Add a string attribute value to a DIE. */
static inline void
-add_AT_string (die, attr_kind, str)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- const char *str;
+add_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind, const char *str)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
struct indirect_string_node *node;
+ void **slot;
if (! debug_str_hash)
- {
- debug_str_hash = ht_create (10);
- debug_str_hash->alloc_node = indirect_string_alloc;
- }
-
- node = (struct indirect_string_node *)
- ht_lookup (debug_str_hash, (const unsigned char *) str,
- strlen (str), HT_ALLOC);
+ debug_str_hash = htab_create_ggc (10, debug_str_do_hash,
+ debug_str_eq, NULL);
+
+ slot = htab_find_slot_with_hash (debug_str_hash, str,
+ htab_hash_string (str), INSERT);
+ if (*slot == NULL)
+ *slot = ggc_alloc_cleared (sizeof (struct indirect_string_node));
+ node = (struct indirect_string_node *) *slot;
+ node->str = ggc_strdup (str);
node->refcount++;
attr->dw_attr_next = NULL;
@@ -4573,11 +4630,10 @@ add_AT_string (die, attr_kind, str)
}
static inline const char *
-AT_string (a)
- dw_attr_ref a;
+AT_string (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_str)
- return (const char *) HT_STR (&a->dw_attr_val.v.val_str->id);
+ return a->dw_attr_val.v.val_str->str;
abort ();
}
@@ -4586,21 +4642,19 @@ AT_string (a)
or out-of-line in .debug_str section. */
static int
-AT_string_form (a)
- dw_attr_ref a;
+AT_string_form (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_str)
{
struct indirect_string_node *node;
unsigned int len;
- extern int const_labelno;
char label[32];
node = a->dw_attr_val.v.val_str;
if (node->form)
return node->form;
- len = HT_LEN (&node->id) + 1;
+ len = strlen (node->str) + 1;
/* If the string is shorter or equal to the size of the reference, it is
always better to put it inline. */
@@ -4614,8 +4668,8 @@ AT_string_form (a)
&& (len - DWARF_OFFSET_SIZE) * node->refcount <= len)
return node->form = DW_FORM_string;
- ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
- ++const_labelno;
+ ASM_GENERATE_INTERNAL_LABEL (label, "LASF", dw2_string_counter);
+ ++dw2_string_counter;
node->label = xstrdup (label);
return node->form = DW_FORM_strp;
@@ -4627,12 +4681,9 @@ AT_string_form (a)
/* Add a DIE reference attribute value to a DIE. */
static inline void
-add_AT_die_ref (die, attr_kind, targ_die)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- dw_die_ref targ_die;
+add_AT_die_ref (dw_die_ref die, enum dwarf_attribute attr_kind, dw_die_ref targ_die)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4642,9 +4693,20 @@ add_AT_die_ref (die, attr_kind, targ_die)
add_dwarf_attr (die, attr);
}
+/* Add an AT_specification attribute to a DIE, and also make the back
+ pointer from the specification to the definition. */
+
+static inline void
+add_AT_specification (dw_die_ref die, dw_die_ref targ_die)
+{
+ add_AT_die_ref (die, DW_AT_specification, targ_die);
+ if (targ_die->die_definition)
+ abort ();
+ targ_die->die_definition = die;
+}
+
static inline dw_die_ref
-AT_ref (a)
- dw_attr_ref a;
+AT_ref (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_die_ref)
return a->dw_attr_val.v.val_die_ref.die;
@@ -4653,8 +4715,7 @@ AT_ref (a)
}
static inline int
-AT_ref_external (a)
- dw_attr_ref a;
+AT_ref_external (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_die_ref)
return a->dw_attr_val.v.val_die_ref.external;
@@ -4663,9 +4724,7 @@ AT_ref_external (a)
}
static inline void
-set_AT_ref_external (a, i)
- dw_attr_ref a;
- int i;
+set_AT_ref_external (dw_attr_ref a, int i)
{
if (a && AT_class (a) == dw_val_class_die_ref)
a->dw_attr_val.v.val_die_ref.external = i;
@@ -4676,12 +4735,9 @@ set_AT_ref_external (a, i)
/* Add an FDE reference attribute value to a DIE. */
static inline void
-add_AT_fde_ref (die, attr_kind, targ_fde)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned targ_fde;
+add_AT_fde_ref (dw_die_ref die, enum dwarf_attribute attr_kind, unsigned int targ_fde)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4693,12 +4749,9 @@ add_AT_fde_ref (die, attr_kind, targ_fde)
/* Add a location description attribute value to a DIE. */
static inline void
-add_AT_loc (die, attr_kind, loc)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- dw_loc_descr_ref loc;
+add_AT_loc (dw_die_ref die, enum dwarf_attribute attr_kind, dw_loc_descr_ref loc)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4708,8 +4761,7 @@ add_AT_loc (die, attr_kind, loc)
}
static inline dw_loc_descr_ref
-AT_loc (a)
- dw_attr_ref a;
+AT_loc (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_loc)
return a->dw_attr_val.v.val_loc;
@@ -4718,12 +4770,9 @@ AT_loc (a)
}
static inline void
-add_AT_loc_list (die, attr_kind, loc_list)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- dw_loc_list_ref loc_list;
+add_AT_loc_list (dw_die_ref die, enum dwarf_attribute attr_kind, dw_loc_list_ref loc_list)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4734,8 +4783,7 @@ add_AT_loc_list (die, attr_kind, loc_list)
}
static inline dw_loc_list_ref
-AT_loc_list (a)
- dw_attr_ref a;
+AT_loc_list (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_loc_list)
return a->dw_attr_val.v.val_loc_list;
@@ -4746,12 +4794,9 @@ AT_loc_list (a)
/* Add an address constant attribute value to a DIE. */
static inline void
-add_AT_addr (die, attr_kind, addr)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- rtx addr;
+add_AT_addr (dw_die_ref die, enum dwarf_attribute attr_kind, rtx addr)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4761,8 +4806,7 @@ add_AT_addr (die, attr_kind, addr)
}
static inline rtx
-AT_addr (a)
- dw_attr_ref a;
+AT_addr (dw_attr_ref a)
{
if (a && AT_class (a) == dw_val_class_addr)
return a->dw_attr_val.v.val_addr;
@@ -4773,12 +4817,9 @@ AT_addr (a)
/* Add a label identifier attribute value to a DIE. */
static inline void
-add_AT_lbl_id (die, attr_kind, lbl_id)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- const char *lbl_id;
+add_AT_lbl_id (dw_die_ref die, enum dwarf_attribute attr_kind, const char *lbl_id)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4790,12 +4831,9 @@ add_AT_lbl_id (die, attr_kind, lbl_id)
/* Add a section offset attribute value to a DIE. */
static inline void
-add_AT_lbl_offset (die, attr_kind, label)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- const char *label;
+add_AT_lbl_offset (dw_die_ref die, enum dwarf_attribute attr_kind, const char *label)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4807,12 +4845,10 @@ add_AT_lbl_offset (die, attr_kind, label)
/* Add an offset attribute value to a DIE. */
static inline void
-add_AT_offset (die, attr_kind, offset)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned long offset;
+add_AT_offset (dw_die_ref die, enum dwarf_attribute attr_kind,
+ unsigned HOST_WIDE_INT offset)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4824,12 +4860,10 @@ add_AT_offset (die, attr_kind, offset)
/* Add an range_list attribute value to a DIE. */
static void
-add_AT_range_list (die, attr_kind, offset)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- unsigned long offset;
+add_AT_range_list (dw_die_ref die, enum dwarf_attribute attr_kind,
+ long unsigned int offset)
{
- dw_attr_ref attr = (dw_attr_ref) xmalloc (sizeof (dw_attr_node));
+ dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
attr->dw_attr_next = NULL;
attr->dw_attr = attr_kind;
@@ -4839,8 +4873,7 @@ add_AT_range_list (die, attr_kind, offset)
}
static inline const char *
-AT_lbl (a)
- dw_attr_ref a;
+AT_lbl (dw_attr_ref a)
{
if (a && (AT_class (a) == dw_val_class_lbl_id
|| AT_class (a) == dw_val_class_lbl_offset))
@@ -4851,10 +4884,8 @@ AT_lbl (a)
/* Get the attribute of type attr_kind. */
-static inline dw_attr_ref
-get_AT (die, attr_kind)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
+static dw_attr_ref
+get_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
{
dw_attr_ref a;
dw_die_ref spec = NULL;
@@ -4880,8 +4911,7 @@ get_AT (die, attr_kind)
cannot be represented as an assembler label identifier. */
static inline const char *
-get_AT_low_pc (die)
- dw_die_ref die;
+get_AT_low_pc (dw_die_ref die)
{
dw_attr_ref a = get_AT (die, DW_AT_low_pc);
@@ -4893,8 +4923,7 @@ get_AT_low_pc (die)
cannot be represented as an assembler label identifier. */
static inline const char *
-get_AT_hi_pc (die)
- dw_die_ref die;
+get_AT_hi_pc (dw_die_ref die)
{
dw_attr_ref a = get_AT (die, DW_AT_high_pc);
@@ -4905,9 +4934,7 @@ get_AT_hi_pc (die)
NULL if it is not present. */
static inline const char *
-get_AT_string (die, attr_kind)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
+get_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind)
{
dw_attr_ref a = get_AT (die, attr_kind);
@@ -4918,9 +4945,7 @@ get_AT_string (die, attr_kind)
if it is not present. */
static inline int
-get_AT_flag (die, attr_kind)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
+get_AT_flag (dw_die_ref die, enum dwarf_attribute attr_kind)
{
dw_attr_ref a = get_AT (die, attr_kind);
@@ -4931,9 +4956,7 @@ get_AT_flag (die, attr_kind)
if it is not present. */
static inline unsigned
-get_AT_unsigned (die, attr_kind)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
+get_AT_unsigned (dw_die_ref die, enum dwarf_attribute attr_kind)
{
dw_attr_ref a = get_AT (die, attr_kind);
@@ -4941,83 +4964,78 @@ get_AT_unsigned (die, attr_kind)
}
static inline dw_die_ref
-get_AT_ref (die, attr_kind)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
+get_AT_ref (dw_die_ref die, enum dwarf_attribute attr_kind)
{
dw_attr_ref a = get_AT (die, attr_kind);
return a ? AT_ref (a) : NULL;
}
-static inline int
-is_c_family ()
+/* Return TRUE if the language is C or C++. */
+
+static inline bool
+is_c_family (void)
{
- unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+ unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
return (lang == DW_LANG_C || lang == DW_LANG_C89
|| lang == DW_LANG_C_plus_plus);
}
-static inline int
-is_cxx ()
+/* Return TRUE if the language is C++. */
+
+static inline bool
+is_cxx (void)
{
return (get_AT_unsigned (comp_unit_die, DW_AT_language)
== DW_LANG_C_plus_plus);
}
-static inline int
-is_fortran ()
+/* Return TRUE if the language is Fortran. */
+
+static inline bool
+is_fortran (void)
{
- unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+ unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
- return (lang == DW_LANG_Fortran77 || lang == DW_LANG_Fortran90);
+ return lang == DW_LANG_Fortran77 || lang == DW_LANG_Fortran90;
}
-static inline int
-is_java ()
+/* Return TRUE if the language is Java. */
+
+static inline bool
+is_java (void)
{
- unsigned lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
+ unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
- return (lang == DW_LANG_Java);
+ return lang == DW_LANG_Java;
}
-/* Free up the memory used by A. */
+/* Return TRUE if the language is Ada. */
-static inline void free_AT PARAMS ((dw_attr_ref));
-static inline void
-free_AT (a)
- dw_attr_ref a;
+static inline bool
+is_ada (void)
{
- switch (AT_class (a))
- {
- case dw_val_class_str:
- if (a->dw_attr_val.v.val_str->refcount)
- a->dw_attr_val.v.val_str->refcount--;
- break;
+ unsigned int lang = get_AT_unsigned (comp_unit_die, DW_AT_language);
- case dw_val_class_lbl_id:
- case dw_val_class_lbl_offset:
- free (a->dw_attr_val.v.val_lbl_id);
- break;
-
- case dw_val_class_float:
- free (a->dw_attr_val.v.val_float.array);
- break;
+ return lang == DW_LANG_Ada95 || lang == DW_LANG_Ada83;
+}
- default:
- break;
- }
+/* Free up the memory used by A. */
- free (a);
+static inline void free_AT (dw_attr_ref);
+static inline void
+free_AT (dw_attr_ref a)
+{
+ if (AT_class (a) == dw_val_class_str)
+ if (a->dw_attr_val.v.val_str->refcount)
+ a->dw_attr_val.v.val_str->refcount--;
}
/* Remove the specified attribute if present. */
static void
-remove_AT (die, attr_kind)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
+remove_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
{
dw_attr_ref *p;
dw_attr_ref removed = NULL;
@@ -5040,18 +5058,15 @@ remove_AT (die, attr_kind)
/* Free up the memory used by DIE. */
static inline void
-free_die (die)
- dw_die_ref die;
+free_die (dw_die_ref die)
{
remove_children (die);
- free (die);
}
/* Discard the children of this DIE. */
static void
-remove_children (die)
- dw_die_ref die;
+remove_children (dw_die_ref die)
{
dw_die_ref child_die = die->die_child;
@@ -5080,9 +5095,7 @@ remove_children (die)
addition order, and correct that in reverse_all_dies. */
static inline void
-add_child_die (die, child_die)
- dw_die_ref die;
- dw_die_ref child_die;
+add_child_die (dw_die_ref die, dw_die_ref child_die)
{
if (die != NULL && child_die != NULL)
{
@@ -5099,8 +5112,7 @@ add_child_die (die, child_die)
is the specification, to the front of PARENT's list of children. */
static void
-splice_child_die (parent, child)
- dw_die_ref parent, child;
+splice_child_die (dw_die_ref parent, dw_die_ref child)
{
dw_die_ref *p;
@@ -5125,6 +5137,7 @@ splice_child_die (parent, child)
break;
}
+ child->die_parent = parent;
child->die_sib = parent->die_child;
parent->die_child = child;
}
@@ -5132,12 +5145,9 @@ splice_child_die (parent, child)
/* Return a pointer to a newly created DIE node. */
static inline dw_die_ref
-new_die (tag_value, parent_die, t)
- enum dwarf_tag tag_value;
- dw_die_ref parent_die;
- tree t;
+new_die (enum dwarf_tag tag_value, dw_die_ref parent_die, tree t)
{
- dw_die_ref die = (dw_die_ref) xcalloc (1, sizeof (die_node));
+ dw_die_ref die = ggc_alloc_cleared (sizeof (die_node));
die->die_tag = tag_value;
@@ -5147,7 +5157,7 @@ new_die (tag_value, parent_die, t)
{
limbo_die_node *limbo_node;
- limbo_node = (limbo_die_node *) xmalloc (sizeof (limbo_die_node));
+ limbo_node = ggc_alloc_cleared (sizeof (limbo_die_node));
limbo_node->die = die;
limbo_node->created_for = t;
limbo_node->next = limbo_die_list;
@@ -5160,8 +5170,7 @@ new_die (tag_value, parent_die, t)
/* Return the DIE associated with the given type specifier. */
static inline dw_die_ref
-lookup_type_die (type)
- tree type;
+lookup_type_die (tree type)
{
return TYPE_SYMTAB_DIE (type);
}
@@ -5169,9 +5178,7 @@ lookup_type_die (type)
/* Equate a DIE to a given type specifier. */
static inline void
-equate_type_number_to_die (type, type_die)
- tree type;
- dw_die_ref type_die;
+equate_type_number_to_die (tree type, dw_die_ref type_die)
{
TYPE_SYMTAB_DIE (type) = type_die;
}
@@ -5179,8 +5186,7 @@ equate_type_number_to_die (type, type_die)
/* Return the DIE associated with a given declaration. */
static inline dw_die_ref
-lookup_decl_die (decl)
- tree decl;
+lookup_decl_die (tree decl)
{
unsigned decl_id = DECL_UID (decl);
@@ -5190,9 +5196,7 @@ lookup_decl_die (decl)
/* Equate a DIE to a particular declaration. */
static void
-equate_decl_number_to_die (decl, decl_die)
- tree decl;
- dw_die_ref decl_die;
+equate_decl_number_to_die (tree decl, dw_die_ref decl_die)
{
unsigned int decl_id = DECL_UID (decl);
unsigned int num_allocated;
@@ -5204,11 +5208,10 @@ equate_decl_number_to_die (decl, decl_die)
/ DECL_DIE_TABLE_INCREMENT)
* DECL_DIE_TABLE_INCREMENT;
- decl_die_table
- = (dw_die_ref *) xrealloc (decl_die_table,
- sizeof (dw_die_ref) * num_allocated);
+ decl_die_table = ggc_realloc (decl_die_table,
+ sizeof (dw_die_ref) * num_allocated);
- memset ((char *) &decl_die_table[decl_die_table_allocated], 0,
+ memset (&decl_die_table[decl_die_table_allocated], 0,
(num_allocated - decl_die_table_allocated) * sizeof (dw_die_ref));
decl_die_table_allocated = num_allocated;
}
@@ -5227,8 +5230,7 @@ static int print_indent;
/* Indent the line the number of spaces given by print_indent. */
static inline void
-print_spaces (outfile)
- FILE *outfile;
+print_spaces (FILE *outfile)
{
fprintf (outfile, "%*s", print_indent, "");
}
@@ -5237,9 +5239,7 @@ print_spaces (outfile)
This routine is a debugging aid only. */
static void
-print_die (die, outfile)
- dw_die_ref die;
- FILE *outfile;
+print_die (dw_die_ref die, FILE *outfile)
{
dw_attr_ref a;
dw_die_ref c;
@@ -5275,18 +5275,18 @@ print_die (die, outfile)
fprintf (outfile, "range list");
break;
case dw_val_class_const:
- fprintf (outfile, "%ld", AT_int (a));
+ fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, AT_int (a));
break;
case dw_val_class_unsigned_const:
- fprintf (outfile, "%lu", AT_unsigned (a));
+ fprintf (outfile, HOST_WIDE_INT_PRINT_UNSIGNED, AT_unsigned (a));
break;
case dw_val_class_long_long:
fprintf (outfile, "constant (%lu,%lu)",
a->dw_attr_val.v.val_long_long.hi,
a->dw_attr_val.v.val_long_long.low);
break;
- case dw_val_class_float:
- fprintf (outfile, "floating-point constant");
+ case dw_val_class_vec:
+ fprintf (outfile, "floating-point or vector constant");
break;
case dw_val_class_flag:
fprintf (outfile, "%u", AT_flag (a));
@@ -5335,8 +5335,7 @@ print_die (die, outfile)
This routine is a debugging aid only. */
static void
-print_dwarf_line_table (outfile)
- FILE *outfile;
+print_dwarf_line_table (FILE *outfile)
{
unsigned i;
dw_line_info_ref line_info;
@@ -5346,7 +5345,8 @@ print_dwarf_line_table (outfile)
{
line_info = &line_info_table[i];
fprintf (outfile, "%5d: ", i);
- fprintf (outfile, "%-20s", file_table.table[line_info->dw_file_num]);
+ fprintf (outfile, "%-20s",
+ VARRAY_CHAR_PTR (file_table, line_info->dw_file_num));
fprintf (outfile, "%6ld", line_info->dw_line_num);
fprintf (outfile, "\n");
}
@@ -5357,8 +5357,7 @@ print_dwarf_line_table (outfile)
/* Print the information collected for a given DIE. */
void
-debug_dwarf_die (die)
- dw_die_ref die;
+debug_dwarf_die (dw_die_ref die)
{
print_die (die, stderr);
}
@@ -5367,7 +5366,7 @@ debug_dwarf_die (die)
This routine is a debugging aid only. */
void
-debug_dwarf ()
+debug_dwarf (void)
{
print_indent = 0;
print_die (comp_unit_die, stderr);
@@ -5380,8 +5379,7 @@ debug_dwarf ()
they are in order of addition. */
static void
-reverse_die_lists (die)
- dw_die_ref die;
+reverse_die_lists (dw_die_ref die)
{
dw_die_ref c, cp, cn;
dw_attr_ref a, ap, an;
@@ -5412,8 +5410,7 @@ reverse_die_lists (die)
recursively reverse all the dies. This is that routine. */
static void
-reverse_all_dies (die)
- dw_die_ref die;
+reverse_all_dies (dw_die_ref die)
{
dw_die_ref c;
@@ -5428,8 +5425,7 @@ reverse_all_dies (die)
DIE that marks the start of the DIEs for this include file. */
static dw_die_ref
-push_new_compile_unit (old_unit, bincl_die)
- dw_die_ref old_unit, bincl_die;
+push_new_compile_unit (dw_die_ref old_unit, dw_die_ref bincl_die)
{
const char *filename = get_AT_string (bincl_die, DW_AT_name);
dw_die_ref new_unit = gen_compile_unit_die (filename);
@@ -5441,8 +5437,7 @@ push_new_compile_unit (old_unit, bincl_die)
/* Close an include-file CU and reopen the enclosing one. */
static dw_die_ref
-pop_compile_unit (old_unit)
- dw_die_ref old_unit;
+pop_compile_unit (dw_die_ref old_unit)
{
dw_die_ref new_unit = old_unit->die_sib;
@@ -5456,9 +5451,7 @@ pop_compile_unit (old_unit)
/* Calculate the checksum of a location expression. */
static inline void
-loc_checksum (loc, ctx)
- dw_loc_descr_ref loc;
- struct md5_ctx *ctx;
+loc_checksum (dw_loc_descr_ref loc, struct md5_ctx *ctx)
{
CHECKSUM (loc->dw_loc_opc);
CHECKSUM (loc->dw_loc_oprnd1);
@@ -5468,10 +5461,7 @@ loc_checksum (loc, ctx)
/* Calculate the checksum of an attribute. */
static void
-attr_checksum (at, ctx, mark)
- dw_attr_ref at;
- struct md5_ctx *ctx;
- int *mark;
+attr_checksum (dw_attr_ref at, struct md5_ctx *ctx, int *mark)
{
dw_loc_descr_ref loc;
rtx r;
@@ -5496,8 +5486,8 @@ attr_checksum (at, ctx, mark)
case dw_val_class_long_long:
CHECKSUM (at->dw_attr_val.v.val_long_long);
break;
- case dw_val_class_float:
- CHECKSUM (at->dw_attr_val.v.val_float);
+ case dw_val_class_vec:
+ CHECKSUM (at->dw_attr_val.v.val_vec);
break;
case dw_val_class_flag:
CHECKSUM (at->dw_attr_val.v.val_flag);
@@ -5545,10 +5535,7 @@ attr_checksum (at, ctx, mark)
/* Calculate the checksum of a DIE. */
static void
-die_checksum (die, ctx, mark)
- dw_die_ref die;
- struct md5_ctx *ctx;
- int *mark;
+die_checksum (dw_die_ref die, struct md5_ctx *ctx, int *mark)
{
dw_die_ref c;
dw_attr_ref a;
@@ -5575,10 +5562,7 @@ die_checksum (die, ctx, mark)
/* Do the location expressions look same? */
static inline int
-same_loc_p (loc1, loc2, mark)
- dw_loc_descr_ref loc1;
- dw_loc_descr_ref loc2;
- int *mark;
+same_loc_p (dw_loc_descr_ref loc1, dw_loc_descr_ref loc2, int *mark)
{
return loc1->dw_loc_opc == loc2->dw_loc_opc
&& same_dw_val_p (&loc1->dw_loc_oprnd1, &loc2->dw_loc_oprnd1, mark)
@@ -5587,14 +5571,10 @@ same_loc_p (loc1, loc2, mark)
/* Do the values look the same? */
static int
-same_dw_val_p (v1, v2, mark)
- dw_val_node *v1;
- dw_val_node *v2;
- int *mark;
+same_dw_val_p (dw_val_node *v1, dw_val_node *v2, int *mark)
{
dw_loc_descr_ref loc1, loc2;
rtx r1, r2;
- unsigned i;
if (v1->val_class != v2->val_class)
return 0;
@@ -5607,19 +5587,19 @@ same_dw_val_p (v1, v2, mark)
return v1->v.val_unsigned == v2->v.val_unsigned;
case dw_val_class_long_long:
return v1->v.val_long_long.hi == v2->v.val_long_long.hi
- && v1->v.val_long_long.low == v2->v.val_long_long.low;
- case dw_val_class_float:
- if (v1->v.val_float.length != v2->v.val_float.length)
+ && v1->v.val_long_long.low == v2->v.val_long_long.low;
+ case dw_val_class_vec:
+ if (v1->v.val_vec.length != v2->v.val_vec.length
+ || v1->v.val_vec.elt_size != v2->v.val_vec.elt_size)
+ return 0;
+ if (memcmp (v1->v.val_vec.array, v2->v.val_vec.array,
+ v1->v.val_vec.length * v1->v.val_vec.elt_size))
return 0;
- for (i = 0; i < v1->v.val_float.length; i++)
- if (v1->v.val_float.array[i] != v2->v.val_float.array[i])
- return 0;
return 1;
case dw_val_class_flag:
return v1->v.val_flag == v2->v.val_flag;
case dw_val_class_str:
- return !strcmp((const char *) HT_STR (&v1->v.val_str->id),
- (const char *) HT_STR (&v2->v.val_str->id));
+ return !strcmp(v1->v.val_str->str, v2->v.val_str->str);
case dw_val_class_addr:
r1 = v1->v.val_addr;
@@ -5662,10 +5642,7 @@ same_dw_val_p (v1, v2, mark)
/* Do the attributes look the same? */
static int
-same_attr_p (at1, at2, mark)
- dw_attr_ref at1;
- dw_attr_ref at2;
- int *mark;
+same_attr_p (dw_attr_ref at1, dw_attr_ref at2, int *mark)
{
if (at1->dw_attr != at2->dw_attr)
return 0;
@@ -5683,10 +5660,7 @@ same_attr_p (at1, at2, mark)
/* Do the dies look the same? */
static int
-same_die_p (die1, die2, mark)
- dw_die_ref die1;
- dw_die_ref die2;
- int *mark;
+same_die_p (dw_die_ref die1, dw_die_ref die2, int *mark)
{
dw_die_ref c1, c2;
dw_attr_ref a1, a2;
@@ -5721,9 +5695,7 @@ same_die_p (die1, die2, mark)
/* Do the dies look the same? Wrapper around same_die_p. */
static int
-same_die_p_wrap (die1, die2)
- dw_die_ref die1;
- dw_die_ref die2;
+same_die_p_wrap (dw_die_ref die1, dw_die_ref die2)
{
int mark = 0;
int ret = same_die_p (die1, die2, &mark);
@@ -5745,12 +5717,11 @@ static unsigned int comdat_symbol_number;
children, and set comdat_symbol_id accordingly. */
static void
-compute_section_prefix (unit_die)
- dw_die_ref unit_die;
+compute_section_prefix (dw_die_ref unit_die)
{
const char *die_name = get_AT_string (unit_die, DW_AT_name);
const char *base = die_name ? lbasename (die_name) : "anonymous";
- char *name = (char *) alloca (strlen (base) + 64);
+ char *name = alloca (strlen (base) + 64);
char *p;
int i, mark;
unsigned char checksum[16];
@@ -5782,8 +5753,7 @@ compute_section_prefix (unit_die)
/* Returns nonzero if DIE represents a type, in the sense of TYPE_P. */
static int
-is_type_die (die)
- dw_die_ref die;
+is_type_die (dw_die_ref die)
{
switch (die->die_tag)
{
@@ -5817,8 +5787,7 @@ is_type_die (die)
compilations (functions). */
static int
-is_comdat_die (c)
- dw_die_ref c;
+is_comdat_die (dw_die_ref c)
{
/* I think we want to leave base types and __vtbl_ptr_type in the main CU, as
we do for stabs. The advantage is a greater likelihood of sharing between
@@ -5845,8 +5814,7 @@ is_comdat_die (c)
compilation unit. */
static int
-is_symbol_die (c)
- dw_die_ref c;
+is_symbol_die (dw_die_ref c)
{
return (is_type_die (c)
|| (get_AT (c, DW_AT_declaration)
@@ -5854,11 +5822,9 @@ is_symbol_die (c)
}
static char *
-gen_internal_sym (prefix)
- const char *prefix;
+gen_internal_sym (const char *prefix)
{
char buf[256];
- static int label_num;
ASM_GENERATE_INTERNAL_LABEL (buf, prefix, label_num++);
return xstrdup (buf);
@@ -5867,8 +5833,7 @@ gen_internal_sym (prefix)
/* Assign symbols to all worthy DIEs under DIE. */
static void
-assign_symbol_names (die)
- dw_die_ref die;
+assign_symbol_names (dw_die_ref die)
{
dw_die_ref c;
@@ -5899,8 +5864,7 @@ struct cu_hash_table_entry
/* Routines to manipulate hash table of CUs. */
static hashval_t
-htab_cu_hash (of)
- const void *of;
+htab_cu_hash (const void *of)
{
const struct cu_hash_table_entry *entry = of;
@@ -5908,9 +5872,7 @@ htab_cu_hash (of)
}
static int
-htab_cu_eq (of1, of2)
- const void *of1;
- const void *of2;
+htab_cu_eq (const void *of1, const void *of2)
{
const struct cu_hash_table_entry *entry1 = of1;
const struct die_struct *entry2 = of2;
@@ -5919,8 +5881,7 @@ htab_cu_eq (of1, of2)
}
static void
-htab_cu_del (what)
- void *what;
+htab_cu_del (void *what)
{
struct cu_hash_table_entry *next, *entry = what;
@@ -5935,10 +5896,7 @@ htab_cu_del (what)
/* Check whether we have already seen this CU and set up SYM_NUM
accordingly. */
static int
-check_duplicate_cu (cu, htable, sym_num)
- dw_die_ref cu;
- htab_t htable;
- unsigned *sym_num;
+check_duplicate_cu (dw_die_ref cu, htab_t htable, unsigned int *sym_num)
{
struct cu_hash_table_entry dummy;
struct cu_hash_table_entry **slot, *entry, *last = &dummy;
@@ -5973,10 +5931,7 @@ check_duplicate_cu (cu, htable, sym_num)
/* Record SYM_NUM to record of CU in HTABLE. */
static void
-record_comdat_symbol_number (cu, htable, sym_num)
- dw_die_ref cu;
- htab_t htable;
- unsigned sym_num;
+record_comdat_symbol_number (dw_die_ref cu, htab_t htable, unsigned int sym_num)
{
struct cu_hash_table_entry **slot, *entry;
@@ -5993,8 +5948,7 @@ record_comdat_symbol_number (cu, htable, sym_num)
bracketed by BINCL/EINCL. */
static void
-break_out_includes (die)
- dw_die_ref die;
+break_out_includes (dw_die_ref die)
{
dw_die_ref *ptr;
dw_die_ref unit = NULL;
@@ -6054,7 +6008,7 @@ break_out_includes (die)
if (is_dupl)
*pnode = node->next;
else
- {
+ {
pnode = &node->next;
record_comdat_symbol_number (node->die, cu_hash_table,
comdat_symbol_number);
@@ -6068,8 +6022,7 @@ break_out_includes (die)
avoid generating sibling attributes for DIE's without children. */
static void
-add_sibling_attributes (die)
- dw_die_ref die;
+add_sibling_attributes (dw_die_ref die)
{
dw_die_ref c;
@@ -6085,8 +6038,7 @@ add_sibling_attributes (die)
/* Output all location lists for the DIE and its children. */
static void
-output_location_lists (die)
- dw_die_ref die;
+output_location_lists (dw_die_ref die)
{
dw_die_ref c;
dw_attr_ref d_attr;
@@ -6106,8 +6058,7 @@ output_location_lists (die)
die are visited recursively. */
static void
-build_abbrev_table (die)
- dw_die_ref die;
+build_abbrev_table (dw_die_ref die)
{
unsigned long abbrev_id;
unsigned int n_alloc;
@@ -6158,11 +6109,10 @@ build_abbrev_table (die)
if (abbrev_die_table_in_use >= abbrev_die_table_allocated)
{
n_alloc = abbrev_die_table_allocated + ABBREV_DIE_TABLE_INCREMENT;
- abbrev_die_table
- = (dw_die_ref *) xrealloc (abbrev_die_table,
- sizeof (dw_die_ref) * n_alloc);
+ abbrev_die_table = ggc_realloc (abbrev_die_table,
+ sizeof (dw_die_ref) * n_alloc);
- memset ((char *) &abbrev_die_table[abbrev_die_table_allocated], 0,
+ memset (&abbrev_die_table[abbrev_die_table_allocated], 0,
(n_alloc - abbrev_die_table_allocated) * sizeof (dw_die_ref));
abbrev_die_table_allocated = n_alloc;
}
@@ -6179,8 +6129,7 @@ build_abbrev_table (die)
/* Return the power-of-two number of bytes necessary to represent VALUE. */
static int
-constant_size (value)
- long unsigned value;
+constant_size (long unsigned int value)
{
int log;
@@ -6199,8 +6148,7 @@ constant_size (value)
.debug_info section. */
static unsigned long
-size_of_die (die)
- dw_die_ref die;
+size_of_die (dw_die_ref die)
{
unsigned long size = 0;
dw_attr_ref a;
@@ -6240,14 +6188,18 @@ size_of_die (die)
case dw_val_class_long_long:
size += 1 + 2*HOST_BITS_PER_LONG/HOST_BITS_PER_CHAR; /* block */
break;
- case dw_val_class_float:
- size += 1 + a->dw_attr_val.v.val_float.length * 4; /* block */
+ case dw_val_class_vec:
+ size += 1 + (a->dw_attr_val.v.val_vec.length
+ * a->dw_attr_val.v.val_vec.elt_size); /* block */
break;
case dw_val_class_flag:
size += 1;
break;
case dw_val_class_die_ref:
- size += DWARF_OFFSET_SIZE;
+ if (AT_ref_external (a))
+ size += DWARF2_ADDR_SIZE;
+ else
+ size += DWARF_OFFSET_SIZE;
break;
case dw_val_class_fde_ref:
size += DWARF_OFFSET_SIZE;
@@ -6262,7 +6214,7 @@ size_of_die (die)
if (AT_string_form (a) == DW_FORM_strp)
size += DWARF_OFFSET_SIZE;
else
- size += HT_LEN (&a->dw_attr_val.v.val_str->id) + 1;
+ size += strlen (a->dw_attr_val.v.val_str->str) + 1;
break;
default:
abort ();
@@ -6278,8 +6230,7 @@ size_of_die (die)
die_offset field in each DIE. */
static void
-calc_die_sizes (die)
- dw_die_ref die;
+calc_die_sizes (dw_die_ref die)
{
dw_die_ref c;
@@ -6300,14 +6251,13 @@ calc_die_sizes (die)
and use that as the flag, but ran into ordering problems. */
static void
-mark_dies (die)
- dw_die_ref die;
+mark_dies (dw_die_ref die)
{
dw_die_ref c;
if (die->die_mark)
abort ();
-
+
die->die_mark = 1;
for (c = die->die_child; c; c = c->die_sib)
mark_dies (c);
@@ -6316,14 +6266,13 @@ mark_dies (die)
/* Clear the marks for a die and its children. */
static void
-unmark_dies (die)
- dw_die_ref die;
+unmark_dies (dw_die_ref die)
{
dw_die_ref c;
if (!die->die_mark)
abort ();
-
+
die->die_mark = 0;
for (c = die->die_child; c; c = c->die_sib)
unmark_dies (c);
@@ -6332,8 +6281,7 @@ unmark_dies (die)
/* Clear the marks for a die, its children and referred dies. */
static void
-unmark_all_dies (die)
- dw_die_ref die;
+unmark_all_dies (dw_die_ref die)
{
dw_die_ref c;
dw_attr_ref a;
@@ -6354,7 +6302,7 @@ unmark_all_dies (die)
compilation unit. */
static unsigned long
-size_of_pubnames ()
+size_of_pubnames (void)
{
unsigned long size;
unsigned i;
@@ -6373,7 +6321,7 @@ size_of_pubnames ()
/* Return the size of the information in the .debug_aranges section. */
static unsigned long
-size_of_aranges ()
+size_of_aranges (void)
{
unsigned long size;
@@ -6391,8 +6339,7 @@ size_of_aranges ()
/* Select the encoding of an attribute value. */
static enum dwarf_form
-value_format (a)
- dw_attr_ref a;
+value_format (dw_attr_ref a)
{
switch (a->dw_attr_val.val_class)
{
@@ -6437,7 +6384,7 @@ value_format (a)
}
case dw_val_class_long_long:
return DW_FORM_block1;
- case dw_val_class_float:
+ case dw_val_class_vec:
return DW_FORM_block1;
case dw_val_class_flag:
return DW_FORM_flag;
@@ -6463,8 +6410,7 @@ value_format (a)
/* Output the encoding of an attribute value. */
static void
-output_value_format (a)
- dw_attr_ref a;
+output_value_format (dw_attr_ref a)
{
enum dwarf_form form = value_format (a);
@@ -6475,7 +6421,7 @@ output_value_format (a)
table. */
static void
-output_abbrev_section ()
+output_abbrev_section (void)
{
unsigned long abbrev_id;
@@ -6513,8 +6459,7 @@ output_abbrev_section ()
/* Output a symbol we can use to refer to this DIE from another CU. */
static inline void
-output_die_symbol (die)
- dw_die_ref die;
+output_die_symbol (dw_die_ref die)
{
char *sym = die->die_symbol;
@@ -6535,15 +6480,10 @@ output_die_symbol (die)
this location list node, which is done for the head of the list only. */
static inline dw_loc_list_ref
-new_loc_list (expr, begin, end, section, gensym)
- dw_loc_descr_ref expr;
- const char *begin;
- const char *end;
- const char *section;
- unsigned gensym;
+new_loc_list (dw_loc_descr_ref expr, const char *begin, const char *end,
+ const char *section, unsigned int gensym)
{
- dw_loc_list_ref retlist
- = (dw_loc_list_ref) xcalloc (1, sizeof (dw_loc_list_node));
+ dw_loc_list_ref retlist = ggc_alloc_cleared (sizeof (dw_loc_list_node));
retlist->begin = begin;
retlist->end = end;
@@ -6555,15 +6495,12 @@ new_loc_list (expr, begin, end, section, gensym)
return retlist;
}
-/* Add a location description expression to a location list */
+/* Add a location description expression to a location list. */
static inline void
-add_loc_descr_to_loc_list (list_head, descr, begin, end, section)
- dw_loc_list_ref *list_head;
- dw_loc_descr_ref descr;
- const char *begin;
- const char *end;
- const char *section;
+add_loc_descr_to_loc_list (dw_loc_list_ref *list_head, dw_loc_descr_ref descr,
+ const char *begin, const char *end,
+ const char *section)
{
dw_loc_list_ref *d;
@@ -6571,15 +6508,14 @@ add_loc_descr_to_loc_list (list_head, descr, begin, end, section)
for (d = list_head; (*d) != NULL; d = &(*d)->dw_loc_next)
;
- /* Add a new location list node to the list */
+ /* Add a new location list node to the list. */
*d = new_loc_list (descr, begin, end, section, 0);
}
-/* Output the location list given to us */
+/* Output the location list given to us. */
static void
-output_loc_list (list_head)
- dw_loc_list_ref list_head;
+output_loc_list (dw_loc_list_ref list_head)
{
dw_loc_list_ref curr = list_head;
@@ -6629,8 +6565,7 @@ output_loc_list (list_head)
the definitions of each child DIE. */
static void
-output_die (die)
- dw_die_ref die;
+output_die (dw_die_ref die)
{
dw_attr_ref a;
dw_die_ref c;
@@ -6663,7 +6598,8 @@ output_die (die)
{
char *p = strchr (ranges_section_label, '\0');
- sprintf (p, "+0x%lx", a->dw_attr_val.v.val_offset);
+ sprintf (p, "+" HOST_WIDE_INT_PRINT_HEX,
+ a->dw_attr_val.v.val_offset);
dw2_asm_output_offset (DWARF_OFFSET_SIZE, ranges_section_label,
"%s", name);
*p = '\0';
@@ -6717,16 +6653,24 @@ output_die (die)
}
break;
- case dw_val_class_float:
+ case dw_val_class_vec:
{
+ unsigned int elt_size = a->dw_attr_val.v.val_vec.elt_size;
+ unsigned int len = a->dw_attr_val.v.val_vec.length;
unsigned int i;
+ unsigned char *p;
- dw2_asm_output_data (1, a->dw_attr_val.v.val_float.length * 4,
- "%s", name);
-
- for (i = 0; i < a->dw_attr_val.v.val_float.length; i++)
- dw2_asm_output_data (4, a->dw_attr_val.v.val_float.array[i],
- "fp constant word %u", i);
+ dw2_asm_output_data (1, len * elt_size, "%s", name);
+ if (elt_size > sizeof (HOST_WIDE_INT))
+ {
+ elt_size /= 2;
+ len *= 2;
+ }
+ for (i = 0, p = a->dw_attr_val.v.val_vec.array;
+ i < len;
+ i++, p += elt_size)
+ dw2_asm_output_data (elt_size, extract_int (p, elt_size),
+ "fp or vector constant word %u", i);
break;
}
@@ -6806,9 +6750,13 @@ output_die (die)
.debug_info section, and precedes the DIE descriptions. */
static void
-output_compilation_unit_header ()
+output_compilation_unit_header (void)
{
- dw2_asm_output_data (DWARF_OFFSET_SIZE, next_die_offset - DWARF_OFFSET_SIZE,
+ if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+ dw2_asm_output_data (4, 0xffffffff,
+ "Initial length escape value indicating 64-bit DWARF extension");
+ 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_offset (DWARF_OFFSET_SIZE, abbrev_section_label,
@@ -6819,9 +6767,7 @@ output_compilation_unit_header ()
/* Output the compilation unit DIE and its children. */
static void
-output_comp_unit (die, output_if_empty)
- dw_die_ref die;
- int output_if_empty;
+output_comp_unit (dw_die_ref die, int output_if_empty)
{
const char *secname;
char *oldsym, *tmp;
@@ -6846,7 +6792,7 @@ output_comp_unit (die, output_if_empty)
oldsym = die->die_symbol;
if (oldsym)
{
- tmp = (char *) alloca (strlen (oldsym) + 24);
+ tmp = alloca (strlen (oldsym) + 24);
sprintf (tmp, ".gnu.linkonce.wi.%s", oldsym);
secname = tmp;
@@ -6874,9 +6820,7 @@ output_comp_unit (die, output_if_empty)
"A::f(int)". Let's drop the argument list, and maybe the scope. */
static const char *
-dwarf2_name (decl, scope)
- tree decl;
- int scope;
+dwarf2_name (tree decl, int scope)
{
return (*lang_hooks.decl_printable_name) (decl, scope ? 1 : 0);
}
@@ -6884,9 +6828,7 @@ dwarf2_name (decl, scope)
/* Add a new entry to .debug_pubnames if appropriate. */
static void
-add_pubname (decl, die)
- tree decl;
- dw_die_ref die;
+add_pubname (tree decl, dw_die_ref die)
{
pubname_ref p;
@@ -6897,9 +6839,10 @@ add_pubname (decl, die)
{
pubname_table_allocated += PUBNAME_TABLE_INCREMENT;
pubname_table
- = (pubname_ref) xrealloc (pubname_table,
- (pubname_table_allocated
- * sizeof (pubname_entry)));
+ = ggc_realloc (pubname_table,
+ (pubname_table_allocated * sizeof (pubname_entry)));
+ memset (pubname_table + pubname_table_in_use, 0,
+ PUBNAME_TABLE_INCREMENT * sizeof (pubname_entry));
}
p = &pubname_table[pubname_table_in_use++];
@@ -6912,11 +6855,14 @@ add_pubname (decl, die)
visible procedures. */
static void
-output_pubnames ()
+output_pubnames (void)
{
unsigned i;
unsigned long pubnames_length = size_of_pubnames ();
+ if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+ dw2_asm_output_data (4, 0xffffffff,
+ "Initial length escape value indicating 64-bit DWARF extension");
dw2_asm_output_data (DWARF_OFFSET_SIZE, pubnames_length,
"Length of Public Names Info");
dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version");
@@ -6945,9 +6891,7 @@ output_pubnames ()
/* Add a new entry to .debug_aranges if appropriate. */
static void
-add_arange (decl, die)
- tree decl;
- dw_die_ref die;
+add_arange (tree decl, dw_die_ref die)
{
if (! DECL_SECTION_NAME (decl))
return;
@@ -6955,8 +6899,11 @@ add_arange (decl, die)
if (arange_table_in_use == arange_table_allocated)
{
arange_table_allocated += ARANGE_TABLE_INCREMENT;
- arange_table = (dw_die_ref *)
- xrealloc (arange_table, arange_table_allocated * sizeof (dw_die_ref));
+ arange_table = ggc_realloc (arange_table,
+ (arange_table_allocated
+ * sizeof (dw_die_ref)));
+ memset (arange_table + arange_table_in_use, 0,
+ ARANGE_TABLE_INCREMENT * sizeof (dw_die_ref));
}
arange_table[arange_table_in_use++] = die;
@@ -6967,11 +6914,14 @@ add_arange (decl, die)
text section generated for this compilation unit. */
static void
-output_aranges ()
+output_aranges (void)
{
unsigned i;
unsigned long aranges_length = size_of_aranges ();
+ if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+ dw2_asm_output_data (4, 0xffffffff,
+ "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");
@@ -6984,7 +6934,7 @@ output_aranges ()
if (DWARF_ARANGES_PAD_SIZE)
{
/* Pad using a 2 byte words so that padding is correct for any
- pointer size. */
+ pointer size. */
dw2_asm_output_data (2, 0, "Pad to %d byte boundary",
2 * DWARF2_ADDR_SIZE);
for (i = 2; i < (unsigned) DWARF_ARANGES_PAD_SIZE; i += 2)
@@ -7042,17 +6992,18 @@ output_aranges ()
was placed. */
static unsigned int
-add_ranges (block)
- tree block;
+add_ranges (tree block)
{
unsigned int in_use = ranges_table_in_use;
if (in_use == ranges_table_allocated)
{
ranges_table_allocated += RANGES_TABLE_INCREMENT;
- ranges_table = (dw_ranges_ref)
- xrealloc (ranges_table, (ranges_table_allocated
- * sizeof (struct dw_ranges_struct)));
+ ranges_table
+ = ggc_realloc (ranges_table, (ranges_table_allocated
+ * sizeof (struct dw_ranges_struct)));
+ memset (ranges_table + ranges_table_in_use, 0,
+ RANGES_TABLE_INCREMENT * sizeof (struct dw_ranges_struct));
}
ranges_table[in_use].block_num = (block ? BLOCK_NUMBER (block) : 0);
@@ -7062,7 +7013,7 @@ add_ranges (block)
}
static void
-output_ranges ()
+output_ranges (void)
{
unsigned i;
static const char *const start_fmt = "Offset 0x%x";
@@ -7140,9 +7091,7 @@ struct dir_info
the directories in the path. */
static int
-file_info_cmp (p1, p2)
- const void *p1;
- const void *p2;
+file_info_cmp (const void *p1, const void *p2)
{
const struct file_info *s1 = p1;
const struct file_info *s2 = p2;
@@ -7181,31 +7130,37 @@ file_info_cmp (p1, p2)
slowdowns with many input files. */
static void
-output_file_names ()
+output_file_names (void)
{
struct file_info *files;
struct dir_info *dirs;
int *saved;
int *savehere;
int *backmap;
- int ndirs;
+ size_t ndirs;
int idx_offset;
- int i;
+ size_t i;
int idx;
+ /* Handle the case where file_table is empty. */
+ if (VARRAY_ACTIVE_SIZE (file_table) <= 1)
+ {
+ dw2_asm_output_data (1, 0, "End directory table");
+ dw2_asm_output_data (1, 0, "End file name table");
+ return;
+ }
+
/* Allocate the various arrays we need. */
- files = (struct file_info *) alloca (file_table.in_use
- * sizeof (struct file_info));
- dirs = (struct dir_info *) alloca (file_table.in_use
- * sizeof (struct dir_info));
+ files = alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (struct file_info));
+ dirs = alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (struct dir_info));
/* Sort the file names. */
- for (i = 1; i < (int) file_table.in_use; i++)
+ for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
{
char *f;
/* Skip all leading "./". */
- f = file_table.table[i];
+ f = VARRAY_CHAR_PTR (file_table, i);
while (f[0] == '.' && f[1] == '/')
f += 2;
@@ -7219,7 +7174,8 @@ output_file_names ()
files[i].fname = f == NULL ? files[i].path : f + 1;
}
- qsort (files + 1, file_table.in_use - 1, sizeof (files[0]), file_info_cmp);
+ qsort (files + 1, VARRAY_ACTIVE_SIZE (file_table) - 1,
+ sizeof (files[0]), file_info_cmp);
/* Find all the different directories used. */
dirs[0].path = files[1].path;
@@ -7231,7 +7187,7 @@ output_file_names ()
files[1].dir_idx = 0;
ndirs = 1;
- for (i = 2; i < (int) file_table.in_use; i++)
+ for (i = 2; i < VARRAY_ACTIVE_SIZE (file_table); i++)
if (files[i].fname - files[i].path == dirs[ndirs - 1].length
&& memcmp (dirs[ndirs - 1].path, files[i].path,
dirs[ndirs - 1].length) == 0)
@@ -7242,7 +7198,7 @@ output_file_names ()
}
else
{
- int j;
+ size_t j;
/* This is a new directory. */
dirs[ndirs].path = files[i].path;
@@ -7271,13 +7227,13 @@ output_file_names ()
where we would have to check out every combination of every single
possible prefix. Instead we use a heuristic which provides nearly optimal
results in most cases and never is much off. */
- saved = (int *) alloca (ndirs * sizeof (int));
- savehere = (int *) alloca (ndirs * sizeof (int));
+ saved = alloca (ndirs * sizeof (int));
+ savehere = alloca (ndirs * sizeof (int));
memset (saved, '\0', ndirs * sizeof (saved[0]));
for (i = 0; i < ndirs; i++)
{
- int j;
+ size_t j;
int total;
/* We can always save some space for the current directory. But this
@@ -7295,10 +7251,10 @@ output_file_names ()
int k;
k = dirs[j].prefix;
- while (k != -1 && k != i)
+ while (k != -1 && k != (int) i)
k = dirs[k].prefix;
- if (k == i)
+ if (k == (int) i)
{
/* Yes it is. We can possibly safe some memory but
writing the filenames in dirs[j] relative to
@@ -7329,8 +7285,8 @@ output_file_names ()
/* We have to emit them in the order they appear in the file_table array
since the index is used in the debug info generation. To do this
efficiently we generate a back-mapping of the indices first. */
- backmap = (int *) alloca (file_table.in_use * sizeof (int));
- for (i = 1; i < (int) file_table.in_use; i++)
+ backmap = alloca (VARRAY_ACTIVE_SIZE (file_table) * sizeof (int));
+ for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
{
backmap[files[i].file_idx] = i;
@@ -7361,13 +7317,13 @@ output_file_names ()
dirs[0].used = 0;
/* Now write all the file names. */
- for (i = 1; i < (int) file_table.in_use; i++)
+ for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
{
int file_idx = backmap[i];
int dir_idx = dirs[files[file_idx].dir_idx].dir_idx;
dw2_asm_output_nstring (files[file_idx].path + dirs[dir_idx].length, -1,
- "File Entry: 0x%x", i);
+ "File Entry: 0x%lx", (unsigned long) i);
/* Include directory index. */
dw2_asm_output_data_uleb128 (dirs[dir_idx].used, NULL);
@@ -7387,7 +7343,7 @@ output_file_names ()
information goes into the .debug_line section. */
static void
-output_line_info ()
+output_line_info (void)
{
char l1[20], l2[20], p1[20], p2[20];
char line_label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -7406,6 +7362,9 @@ output_line_info ()
ASM_GENERATE_INTERNAL_LABEL (p1, LN_PROLOG_AS_LABEL, 0);
ASM_GENERATE_INTERNAL_LABEL (p2, LN_PROLOG_END_LABEL, 0);
+ if (DWARF_INITIAL_LENGTH_SIZE - DWARF_OFFSET_SIZE == 4)
+ dw2_asm_output_data (4, 0xffffffff,
+ "Initial length escape value indicating 64-bit DWARF extension");
dw2_asm_output_delta (DWARF_OFFSET_SIZE, l2, l1,
"Length of Source Line Info");
ASM_OUTPUT_LABEL (asm_out_file, l1);
@@ -7477,8 +7436,8 @@ output_line_info ()
prologue. */
/* Don't emit anything for redundant notes. Just updating the
- address doesn't accomplish anything, because we already assume
- that anything after the last address is this line. */
+ address doesn't accomplish anything, because we already assume
+ that anything after the last address is this line. */
if (line_info->dw_line_num == current_line
&& line_info->dw_file_num == current_file)
continue;
@@ -7504,7 +7463,7 @@ output_line_info ()
else
{
/* This can handle any delta. This takes
- 4+DWARF2_ADDR_SIZE bytes. */
+ 4+DWARF2_ADDR_SIZE bytes. */
dw2_asm_output_data (1, 0, "DW_LNE_set_address");
dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL);
dw2_asm_output_data (1, DW_LNE_set_address, NULL);
@@ -7520,7 +7479,8 @@ output_line_info ()
current_file = line_info->dw_file_num;
dw2_asm_output_data (1, DW_LNS_set_file, "DW_LNS_set_file");
dw2_asm_output_data_uleb128 (current_file, "(\"%s\")",
- file_table.table[current_file]);
+ VARRAY_CHAR_PTR (file_table,
+ current_file));
}
/* Emit debug info for the current line number, choosing the encoding
@@ -7595,7 +7555,7 @@ output_line_info ()
{
function = line_info->function;
- /* Set the address register to the first line in the function */
+ /* Set the address register to the first line in the function. */
dw2_asm_output_data (1, 0, "DW_LNE_set_address");
dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL);
dw2_asm_output_data (1, DW_LNE_set_address, NULL);
@@ -7628,7 +7588,8 @@ output_line_info ()
current_file = line_info->dw_file_num;
dw2_asm_output_data (1, DW_LNS_set_file, "DW_LNS_set_file");
dw2_asm_output_data_uleb128 (current_file, "(\"%s\")",
- file_table.table[current_file]);
+ VARRAY_CHAR_PTR (file_table,
+ current_file));
}
/* Emit debug info for the current line number, choosing the encoding
@@ -7699,8 +7660,7 @@ output_line_info ()
Dwarf base (fundamental) types. */
static dw_die_ref
-base_type_die (type)
- tree type;
+base_type_die (tree type)
{
dw_die_ref base_type_result;
const char *type_name;
@@ -7724,9 +7684,9 @@ base_type_die (type)
{
case INTEGER_TYPE:
/* Carefully distinguish the C character types, without messing
- up if the language is not C. Note that we check only for the names
- that contain spaces; other names might occur by coincidence in other
- languages. */
+ up if the language is not C. Note that we check only for the names
+ that contain spaces; other names might occur by coincidence in other
+ languages. */
if (! (TYPE_PRECISION (type) == CHAR_TYPE_SIZE
&& (type == char_type_node
|| ! strcmp (type_name, "signed char")
@@ -7793,8 +7753,7 @@ base_type_die (type)
root type of the given type without the qualifiers. */
static tree
-root_type (type)
- tree type;
+root_type (tree type)
{
if (TREE_CODE (type) == ERROR_MARK)
return error_mark_node;
@@ -7817,8 +7776,7 @@ root_type (type)
given input type is a Dwarf "fundamental" type. Otherwise return null. */
static inline int
-is_base_type (type)
- tree type;
+is_base_type (tree type)
{
switch (TREE_CODE (type))
{
@@ -7854,15 +7812,96 @@ is_base_type (type)
return 0;
}
+/* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE
+ node, return the size in bits for the type if it is a constant, or else
+ return the alignment for the type if the type's size is not constant, or
+ else return BITS_PER_WORD if the type actually turns out to be an
+ ERROR_MARK node. */
+
+static inline unsigned HOST_WIDE_INT
+simple_type_size_in_bits (tree type)
+{
+ if (TREE_CODE (type) == ERROR_MARK)
+ return BITS_PER_WORD;
+ else if (TYPE_SIZE (type) == NULL_TREE)
+ return 0;
+ else if (host_integerp (TYPE_SIZE (type), 1))
+ return tree_low_cst (TYPE_SIZE (type), 1);
+ else
+ 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 (tree type)
+{
+ tree subtype = TREE_TYPE (type);
+
+ if (TREE_CODE (type) == INTEGER_TYPE
+ && subtype != NULL_TREE)
+ {
+ if (TREE_CODE (subtype) == INTEGER_TYPE)
+ return true;
+ if (TREE_CODE (subtype) == ENUMERAL_TYPE)
+ return true;
+ }
+ return false;
+}
+
+/* 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)
+{
+ dw_die_ref subtype_die;
+ dw_die_ref subrange_die;
+ tree name = TYPE_NAME (type);
+ const HOST_WIDE_INT size_in_bytes = int_size_in_bytes (type);
+
+ if (context_die == NULL)
+ context_die = comp_unit_die;
+
+ if (TREE_CODE (TREE_TYPE (type)) == ENUMERAL_TYPE)
+ subtype_die = gen_enumeration_type_die (TREE_TYPE (type), context_die);
+ else
+ subtype_die = base_type_die (TREE_TYPE (type));
+
+ subrange_die = new_die (DW_TAG_subrange_type, context_die, type);
+
+ if (name != NULL)
+ {
+ if (TREE_CODE (name) == TYPE_DECL)
+ name = DECL_NAME (name);
+ add_name_attribute (subrange_die, IDENTIFIER_POINTER (name));
+ }
+
+ if (int_size_in_bytes (TREE_TYPE (type)) != size_in_bytes)
+ {
+ /* The size of the subrange type and its base type do not match,
+ so we need to generate a size attribute for the subrange type. */
+ 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));
+ add_AT_die_ref (subrange_die, DW_AT_type, subtype_die);
+
+ return subrange_die;
+}
+
/* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging
entry that chains various modifiers in front of the given type. */
static dw_die_ref
-modified_type_die (type, is_const_type, is_volatile_type, context_die)
- tree type;
- int is_const_type;
- int is_volatile_type;
- dw_die_ref context_die;
+modified_type_die (tree type, int is_const_type, int is_volatile_type,
+ dw_die_ref context_die)
{
enum tree_code code = TREE_CODE (type);
dw_die_ref mod_type_die = NULL;
@@ -7931,7 +7970,8 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die)
else if (code == POINTER_TYPE)
{
mod_type_die = new_die (DW_TAG_pointer_type, comp_unit_die, type);
- add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
+ add_AT_unsigned (mod_type_die, DW_AT_byte_size,
+ simple_type_size_in_bits (type) / BITS_PER_UNIT);
#if 0
add_AT_unsigned (mod_type_die, DW_AT_address_class, 0);
#endif
@@ -7940,12 +7980,15 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die)
else if (code == REFERENCE_TYPE)
{
mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die, type);
- add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
+ add_AT_unsigned (mod_type_die, DW_AT_byte_size,
+ simple_type_size_in_bits (type) / BITS_PER_UNIT);
#if 0
add_AT_unsigned (mod_type_die, DW_AT_address_class, 0);
#endif
item_type = TREE_TYPE (type);
}
+ else if (is_subrange_type (type))
+ mod_type_die = subrange_type_die (type, context_die);
else if (is_base_type (type))
mod_type_die = base_type_die (type);
else
@@ -7994,17 +8037,15 @@ modified_type_die (type, is_const_type, is_volatile_type, context_die)
an enumerated type. */
static inline int
-type_is_enum (type)
- tree type;
+type_is_enum (tree type)
{
return TREE_CODE (type) == ENUMERAL_TYPE;
}
-/* Return the register number described by a given RTL node. */
+/* Return the DBX register number described by a given RTL node. */
static unsigned int
-reg_number (rtl)
- rtx rtl;
+dbx_reg_number (rtx rtl)
{
unsigned regno = REGNO (rtl);
@@ -8015,32 +8056,94 @@ reg_number (rtl)
}
/* Return a location descriptor that designates a machine register or
- zero if there is no such. */
+ zero if there is none. */
static dw_loc_descr_ref
-reg_loc_descriptor (rtl)
- rtx rtl;
+reg_loc_descriptor (rtx rtl)
{
- dw_loc_descr_ref loc_result = NULL;
unsigned reg;
+ rtx regs;
if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
return 0;
- reg = reg_number (rtl);
- if (reg <= 31)
- loc_result = new_loc_descr (DW_OP_reg0 + reg, 0, 0);
+ reg = dbx_reg_number (rtl);
+ regs = (*targetm.dwarf_register_span) (rtl);
+
+ if (HARD_REGNO_NREGS (REGNO (rtl), GET_MODE (rtl)) > 1
+ || regs)
+ return multiple_reg_loc_descriptor (rtl, regs);
+ else
+ return one_reg_loc_descriptor (reg);
+}
+
+/* Return a location descriptor that designates a machine register for
+ a given hard register number. */
+
+static dw_loc_descr_ref
+one_reg_loc_descriptor (unsigned int regno)
+{
+ if (regno <= 31)
+ return new_loc_descr (DW_OP_reg0 + regno, 0, 0);
else
- loc_result = new_loc_descr (DW_OP_regx, reg, 0);
+ return new_loc_descr (DW_OP_regx, regno, 0);
+}
+
+/* Given an RTL of a register, return a location descriptor that
+ designates a value that spans more than one register. */
+
+static dw_loc_descr_ref
+multiple_reg_loc_descriptor (rtx rtl, rtx regs)
+{
+ int nregs, size, i;
+ unsigned reg;
+ dw_loc_descr_ref loc_result = NULL;
+
+ reg = dbx_reg_number (rtl);
+ nregs = HARD_REGNO_NREGS (REGNO (rtl), GET_MODE (rtl));
+
+ /* Simple, contiguous registers. */
+ if (regs == NULL_RTX)
+ {
+ size = GET_MODE_SIZE (GET_MODE (rtl)) / nregs;
+
+ loc_result = NULL;
+ while (nregs--)
+ {
+ dw_loc_descr_ref t;
+
+ t = one_reg_loc_descriptor (reg);
+ add_loc_descr (&loc_result, t);
+ add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+ ++reg;
+ }
+ return loc_result;
+ }
+
+ /* Now onto stupid register sets in non contiguous locations. */
+ if (GET_CODE (regs) != PARALLEL)
+ abort ();
+
+ size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
+ loc_result = NULL;
+
+ for (i = 0; i < XVECLEN (regs, 0); ++i)
+ {
+ dw_loc_descr_ref t;
+
+ t = one_reg_loc_descriptor (REGNO (XVECEXP (regs, 0, i)));
+ add_loc_descr (&loc_result, t);
+ size = GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0)));
+ add_loc_descr (&loc_result, new_loc_descr (DW_OP_piece, size, 0));
+ }
return loc_result;
}
/* Return a location descriptor that designates a constant. */
static dw_loc_descr_ref
-int_loc_descriptor (i)
- HOST_WIDE_INT i;
+int_loc_descriptor (HOST_WIDE_INT i)
{
enum dwarf_location_atom op;
@@ -8079,9 +8182,7 @@ int_loc_descriptor (i)
/* Return a location descriptor that designates a base+offset location. */
static dw_loc_descr_ref
-based_loc_descr (reg, offset)
- unsigned reg;
- long int offset;
+based_loc_descr (unsigned int reg, HOST_WIDE_INT offset)
{
dw_loc_descr_ref loc_result;
/* For the "frame base", we use the frame pointer or stack pointer
@@ -8104,8 +8205,7 @@ based_loc_descr (reg, offset)
/* Return true if this RTL expression describes a base+offset calculation. */
static inline int
-is_based_loc (rtl)
- rtx rtl;
+is_based_loc (rtx rtl)
{
return (GET_CODE (rtl) == PLUS
&& ((GET_CODE (XEXP (rtl, 0)) == REG
@@ -8129,9 +8229,7 @@ is_based_loc (rtl)
Return 0 if we can't represent the location. */
static dw_loc_descr_ref
-mem_loc_descriptor (rtl, mode)
- rtx rtl;
- enum machine_mode mode;
+mem_loc_descriptor (rtx rtl, enum machine_mode mode)
{
dw_loc_descr_ref mem_loc_result = NULL;
@@ -8140,9 +8238,7 @@ mem_loc_descriptor (rtl, mode)
actually within the array. That's *not* necessarily the same as the
zeroth element of the array. */
-#ifdef ASM_SIMPLIFY_DWARF_ADDR
- rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
-#endif
+ rtl = (*targetm.delegitimize_address) (rtl);
switch (GET_CODE (rtl))
{
@@ -8156,30 +8252,30 @@ mem_loc_descriptor (rtl, mode)
case SUBREG:
/* The case of a subreg may arise when we have a local (register)
- variable or a formal (register) parameter which doesn't quite fill
- up an entire register. For now, just assume that it is
- legitimate to make the Dwarf info refer to the whole register which
- contains the given subreg. */
+ variable or a formal (register) parameter which doesn't quite fill
+ up an entire register. For now, just assume that it is
+ legitimate to make the Dwarf info refer to the whole register which
+ contains the given subreg. */
rtl = SUBREG_REG (rtl);
/* ... fall through ... */
case REG:
/* Whenever a register number forms a part of the description of the
- method for calculating the (dynamic) address of a memory resident
- object, DWARF rules require the register number be referred to as
- a "base register". This distinction is not based in any way upon
- what category of register the hardware believes the given register
- belongs to. This is strictly DWARF terminology we're dealing with
- here. Note that in cases where the location of a memory-resident
- data object could be expressed as: OP_ADD (OP_BASEREG (basereg),
- OP_CONST (0)) the actual DWARF location descriptor that we generate
- may just be OP_BASEREG (basereg). This may look deceptively like
- the object in question was allocated to a register (rather than in
- memory) so DWARF consumers need to be aware of the subtle
- distinction between OP_REG and OP_BASEREG. */
+ method for calculating the (dynamic) address of a memory resident
+ object, DWARF rules require the register number be referred to as
+ a "base register". This distinction is not based in any way upon
+ what category of register the hardware believes the given register
+ belongs to. This is strictly DWARF terminology we're dealing with
+ here. Note that in cases where the location of a memory-resident
+ data object could be expressed as: OP_ADD (OP_BASEREG (basereg),
+ OP_CONST (0)) the actual DWARF location descriptor that we generate
+ may just be OP_BASEREG (basereg). This may look deceptively like
+ the object in question was allocated to a register (rather than in
+ memory) so DWARF consumers need to be aware of the subtle
+ distinction between OP_REG and OP_BASEREG. */
if (REGNO (rtl) < FIRST_PSEUDO_REGISTER)
- mem_loc_result = based_loc_descr (reg_number (rtl), 0);
+ mem_loc_result = based_loc_descr (dbx_reg_number (rtl), 0);
break;
case MEM:
@@ -8195,8 +8291,8 @@ mem_loc_descriptor (rtl, mode)
case LABEL_REF:
/* Some ports can transform a symbol ref into a label ref, because
- the symbol ref is too far away and has to be dumped into a constant
- pool. */
+ the symbol ref is too far away and has to be dumped into a constant
+ pool. */
case CONST:
case SYMBOL_REF:
/* Alternatively, the symbol in the constant pool might be referenced
@@ -8231,7 +8327,7 @@ mem_loc_descriptor (rtl, mode)
case PRE_MODIFY:
/* Extract the PLUS expression nested inside and fall into
- PLUS code below. */
+ PLUS code below. */
rtl = XEXP (rtl, 1);
goto plus;
@@ -8249,7 +8345,7 @@ mem_loc_descriptor (rtl, mode)
case PLUS:
plus:
if (is_based_loc (rtl))
- mem_loc_result = based_loc_descr (reg_number (XEXP (rtl, 0)),
+ mem_loc_result = based_loc_descr (dbx_reg_number (XEXP (rtl, 0)),
INTVAL (XEXP (rtl, 1)));
else
{
@@ -8311,8 +8407,7 @@ mem_loc_descriptor (rtl, mode)
This is typically a complex variable. */
static dw_loc_descr_ref
-concat_loc_descriptor (x0, x1)
- rtx x0, x1;
+concat_loc_descriptor (rtx x0, rtx x1)
{
dw_loc_descr_ref cc_loc_result = NULL;
dw_loc_descr_ref x0_ref = loc_descriptor (x0);
@@ -8343,8 +8438,7 @@ concat_loc_descriptor (x0, x1)
If we don't know how to describe it, return 0. */
static dw_loc_descr_ref
-loc_descriptor (rtl)
- rtx rtl;
+loc_descriptor (rtx rtl)
{
dw_loc_descr_ref loc_result = NULL;
@@ -8352,10 +8446,10 @@ loc_descriptor (rtl)
{
case SUBREG:
/* The case of a subreg may arise when we have a local (register)
- variable or a formal (register) parameter which doesn't quite fill
- up an entire register. For now, just assume that it is
- legitimate to make the Dwarf info refer to the whole register which
- contains the given subreg. */
+ variable or a formal (register) parameter which doesn't quite fill
+ up an entire register. For now, just assume that it is
+ legitimate to make the Dwarf info refer to the whole register which
+ contains the given subreg. */
rtl = SUBREG_REG (rtl);
/* ... fall through ... */
@@ -8385,9 +8479,7 @@ loc_descriptor (rtl)
descriptor, return 0. */
static dw_loc_descr_ref
-loc_descriptor_from_tree (loc, addressp)
- tree loc;
- int addressp;
+loc_descriptor_from_tree (tree loc, int addressp)
{
dw_loc_descr_ref ret, ret1;
int indirect_p = 0;
@@ -8414,6 +8506,13 @@ loc_descriptor_from_tree (loc, addressp)
case CALL_EXPR:
return 0;
+ case PREINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ /* There are no opcodes for these operations. */
+ return 0;
+
case ADDR_EXPR:
/* We can support this only if we can look through conversions and
find an INDIRECT_EXPR. */
@@ -8464,7 +8563,7 @@ loc_descriptor_from_tree (loc, addressp)
indirect_p = 1;
break;
}
- /* FALLTHRU */
+ /* Fall through. */
case PARM_DECL:
{
@@ -8507,6 +8606,7 @@ loc_descriptor_from_tree (loc, addressp)
case NON_LVALUE_EXPR:
case VIEW_CONVERT_EXPR:
case SAVE_EXPR:
+ case MODIFY_EXPR:
return loc_descriptor_from_tree (TREE_OPERAND (loc, 0), addressp);
case COMPONENT_REF:
@@ -8558,6 +8658,24 @@ loc_descriptor_from_tree (loc, addressp)
return 0;
break;
+ case CONSTRUCTOR:
+ {
+ /* Get an RTL for this, if something has been emitted. */
+ rtx rtl = lookup_constant_def (loc);
+ enum machine_mode mode;
+
+ if (GET_CODE (rtl) != MEM)
+ return 0;
+ mode = GET_MODE (rtl);
+ rtl = XEXP (rtl, 0);
+
+ rtl = (*targetm.delegitimize_address) (rtl);
+
+ indirect_p = 1;
+ ret = mem_loc_descriptor (rtl, mode);
+ break;
+ }
+
case TRUTH_AND_EXPR:
case TRUTH_ANDIF_EXPR:
case BIT_AND_EXPR:
@@ -8575,6 +8693,9 @@ loc_descriptor_from_tree (loc, addressp)
op = DW_OP_or;
goto do_binop;
+ case FLOOR_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case ROUND_DIV_EXPR:
case TRUNC_DIV_EXPR:
op = DW_OP_div;
goto do_binop;
@@ -8583,6 +8704,9 @@ loc_descriptor_from_tree (loc, addressp)
op = DW_OP_minus;
goto do_binop;
+ case FLOOR_MOD_EXPR:
+ case CEIL_MOD_EXPR:
+ case ROUND_MOD_EXPR:
case TRUNC_MOD_EXPR:
op = DW_OP_mod;
goto do_binop;
@@ -8724,7 +8848,18 @@ loc_descriptor_from_tree (loc, addressp)
}
break;
+ case EXPR_WITH_FILE_LOCATION:
+ return loc_descriptor_from_tree (EXPR_WFL_NODE (loc), addressp);
+
default:
+ /* Leave front-end specific codes as simply unknown. This comes
+ up, for instance, with the C STMT_EXPR. */
+ if ((unsigned int) TREE_CODE (loc)
+ >= (unsigned int) LAST_AND_UNUSED_TREE_CODE)
+ return 0;
+
+ /* Otherwise this is a generic code; we should just lists all of
+ these explicitly. Aborting means we forgot one. */
abort ();
}
@@ -8754,9 +8889,7 @@ loc_descriptor_from_tree (loc, addressp)
which is not less than the value itself. */
static inline HOST_WIDE_INT
-ceiling (value, boundary)
- HOST_WIDE_INT value;
- unsigned int boundary;
+ceiling (HOST_WIDE_INT value, unsigned int boundary)
{
return (((value + boundary - 1) / boundary) * boundary);
}
@@ -8767,8 +8900,7 @@ ceiling (value, boundary)
ERROR_MARK node. */
static inline tree
-field_type (decl)
- tree decl;
+field_type (tree decl)
{
tree type;
@@ -8787,40 +8919,17 @@ field_type (decl)
be an ERROR_MARK node. */
static inline unsigned
-simple_type_align_in_bits (type)
- tree type;
+simple_type_align_in_bits (tree type)
{
return (TREE_CODE (type) != ERROR_MARK) ? TYPE_ALIGN (type) : BITS_PER_WORD;
}
static inline unsigned
-simple_decl_align_in_bits (decl)
- tree decl;
+simple_decl_align_in_bits (tree decl)
{
return (TREE_CODE (decl) != ERROR_MARK) ? DECL_ALIGN (decl) : BITS_PER_WORD;
}
-/* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE
- node, return the size in bits for the type if it is a constant, or else
- return the alignment for the type if the type's size is not constant, or
- else return BITS_PER_WORD if the type actually turns out to be an
- ERROR_MARK node. */
-
-static inline unsigned HOST_WIDE_INT
-simple_type_size_in_bits (type)
- tree type;
-{
-
- if (TREE_CODE (type) == ERROR_MARK)
- return BITS_PER_WORD;
- else if (TYPE_SIZE (type) == NULL_TREE)
- return 0;
- else if (host_integerp (TYPE_SIZE (type), 1))
- return tree_low_cst (TYPE_SIZE (type), 1);
- else
- return TYPE_ALIGN (type);
-}
-
/* Given a pointer to a FIELD_DECL, compute and return the byte offset of the
lowest addressed byte of the "containing object" for the given FIELD_DECL,
or return 0 if we are unable to determine what that offset is, either
@@ -8829,8 +8938,7 @@ simple_type_size_in_bits (type)
just yet). */
static HOST_WIDE_INT
-field_byte_offset (decl)
- tree decl;
+field_byte_offset (tree decl)
{
unsigned int type_align_in_bits;
unsigned int decl_align_in_bits;
@@ -8949,10 +9057,8 @@ field_byte_offset (decl)
generated by the routine `data_member_location_attribute' below. */
static inline void
-add_AT_location_description (die, attr_kind, descr)
- dw_die_ref die;
- enum dwarf_attribute attr_kind;
- dw_loc_descr_ref descr;
+add_AT_location_description (dw_die_ref die, enum dwarf_attribute attr_kind,
+ dw_loc_descr_ref descr)
{
if (descr != 0)
add_AT_loc (die, attr_kind, descr);
@@ -8978,11 +9084,9 @@ add_AT_location_description (die, attr_kind, descr)
function below.) */
static void
-add_data_member_location_attribute (die, decl)
- dw_die_ref die;
- tree decl;
+add_data_member_location_attribute (dw_die_ref die, tree decl)
{
- long offset;
+ HOST_WIDE_INT offset;
dw_loc_descr_ref loc_descr = 0;
if (TREE_CODE (decl) == TREE_VEC)
@@ -9056,80 +9160,93 @@ add_data_member_location_attribute (die, decl)
add_AT_loc (die, DW_AT_data_member_location, loc_descr);
}
-/* Attach an DW_AT_const_value attribute for a variable or a parameter which
+/* Writes integer values to dw_vec_const array. */
+
+static void
+insert_int (HOST_WIDE_INT val, unsigned int size, unsigned char *dest)
+{
+ while (size != 0)
+ {
+ *dest++ = val & 0xff;
+ val >>= 8;
+ --size;
+ }
+}
+
+/* Reads integers from dw_vec_const array. Inverse of insert_int. */
+
+static HOST_WIDE_INT
+extract_int (const unsigned char *src, unsigned int size)
+{
+ HOST_WIDE_INT val = 0;
+
+ src += size;
+ while (size != 0)
+ {
+ val <<= 8;
+ val |= *--src & 0xff;
+ --size;
+ }
+ return val;
+}
+
+/* Writes floating point values to dw_vec_const array. */
+
+static void
+insert_float (rtx rtl, unsigned char *array)
+{
+ REAL_VALUE_TYPE rv;
+ long val[4];
+ int i;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, rtl);
+ real_to_target (val, &rv, GET_MODE (rtl));
+
+ /* real_to_target puts 32-bit pieces in each long. Pack them. */
+ for (i = 0; i < GET_MODE_SIZE (GET_MODE (rtl)) / 4; i++)
+ {
+ insert_int (val[i], 4, array);
+ array += 4;
+ }
+}
+
+/* Attach a DW_AT_const_value attribute for a variable or a parameter which
does not have a "location" either in memory or in a register. These
things can arise in GNU C when a constant is passed as an actual parameter
to an inlined function. They can also arise in C++ where declared
constants do not necessarily get memory "homes". */
static void
-add_const_value_attribute (die, rtl)
- dw_die_ref die;
- rtx rtl;
+add_const_value_attribute (dw_die_ref die, rtx rtl)
{
switch (GET_CODE (rtl))
{
case CONST_INT:
- /* Note that a CONST_INT rtx could represent either an integer
- or a floating-point constant. A CONST_INT is used whenever
- the constant will fit into a single word. In all such
- cases, the original mode of the constant value is wiped
- out, and the CONST_INT rtx is assigned VOIDmode. */
{
HOST_WIDE_INT val = INTVAL (rtl);
- /* ??? We really should be using HOST_WIDE_INT throughout. */
- if (val < 0 && (long) val == val)
- add_AT_int (die, DW_AT_const_value, (long) val);
- else if ((unsigned long) val == (unsigned HOST_WIDE_INT) val)
- add_AT_unsigned (die, DW_AT_const_value, (unsigned long) val);
- else
- {
-#if HOST_BITS_PER_LONG * 2 == HOST_BITS_PER_WIDE_INT
- add_AT_long_long (die, DW_AT_const_value,
- val >> HOST_BITS_PER_LONG, val);
-#else
- abort ();
-#endif
- }
+ if (val < 0)
+ add_AT_int (die, DW_AT_const_value, val);
+ else
+ add_AT_unsigned (die, DW_AT_const_value, (unsigned HOST_WIDE_INT) val);
}
break;
case CONST_DOUBLE:
/* Note that a CONST_DOUBLE rtx could represent either an integer or a
- floating-point constant. A CONST_DOUBLE is used whenever the
- constant requires more than one word in order to be adequately
- represented. We output CONST_DOUBLEs as blocks. */
+ floating-point constant. A CONST_DOUBLE is used whenever the
+ constant requires more than one word in order to be adequately
+ represented. We output CONST_DOUBLEs as blocks. */
{
enum machine_mode mode = GET_MODE (rtl);
if (GET_MODE_CLASS (mode) == MODE_FLOAT)
{
- unsigned length = GET_MODE_SIZE (mode) / 4;
- long *array = (long *) xmalloc (sizeof (long) * length);
- REAL_VALUE_TYPE rv;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rv, rtl);
- switch (mode)
- {
- case SFmode:
- REAL_VALUE_TO_TARGET_SINGLE (rv, array[0]);
- break;
-
- case DFmode:
- REAL_VALUE_TO_TARGET_DOUBLE (rv, array);
- break;
-
- case XFmode:
- case TFmode:
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, array);
- break;
+ unsigned int length = GET_MODE_SIZE (mode);
+ unsigned char *array = ggc_alloc (length);
- default:
- abort ();
- }
-
- add_AT_float (die, DW_AT_const_value, length, array);
+ insert_float (rtl, array);
+ add_AT_vec (die, DW_AT_const_value, length / 4, 4, array);
}
else
{
@@ -9143,6 +9260,68 @@ add_const_value_attribute (die, rtl)
}
break;
+ case CONST_VECTOR:
+ {
+ enum machine_mode mode = GET_MODE (rtl);
+ unsigned int elt_size = GET_MODE_UNIT_SIZE (mode);
+ unsigned int length = CONST_VECTOR_NUNITS (rtl);
+ unsigned char *array = ggc_alloc (length * elt_size);
+ unsigned int i;
+ unsigned char *p;
+
+ if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
+ {
+ for (i = 0, p = array; i < length; i++, p += elt_size)
+ {
+ rtx elt = CONST_VECTOR_ELT (rtl, i);
+ HOST_WIDE_INT lo, hi;
+ if (GET_CODE (elt) == CONST_INT)
+ {
+ lo = INTVAL (elt);
+ hi = -(lo < 0);
+ }
+ else if (GET_CODE (elt) == CONST_DOUBLE)
+ {
+ lo = CONST_DOUBLE_LOW (elt);
+ hi = CONST_DOUBLE_HIGH (elt);
+ }
+ else
+ abort ();
+
+ if (elt_size <= sizeof (HOST_WIDE_INT))
+ insert_int (lo, elt_size, p);
+ else if (elt_size == 2 * sizeof (HOST_WIDE_INT))
+ {
+ unsigned char *p0 = p;
+ unsigned char *p1 = p + sizeof (HOST_WIDE_INT);
+
+ if (WORDS_BIG_ENDIAN)
+ {
+ p0 = p1;
+ p1 = p;
+ }
+ insert_int (lo, sizeof (HOST_WIDE_INT), p0);
+ insert_int (hi, sizeof (HOST_WIDE_INT), p1);
+ }
+ else
+ abort ();
+ }
+ }
+ else if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
+ {
+ for (i = 0, p = array; i < length; i++, p += elt_size)
+ {
+ rtx elt = CONST_VECTOR_ELT (rtl, i);
+ insert_float (elt, p);
+ }
+ }
+ else
+ abort ();
+
+ add_AT_vec (die, DW_AT_const_value, length, elt_size, array);
+ }
+ break;
+
case CONST_STRING:
add_AT_string (die, DW_AT_const_value, XSTR (rtl, 0));
break;
@@ -9156,16 +9335,16 @@ add_const_value_attribute (die, rtl)
case PLUS:
/* In cases where an inlined instance of an inline function is passed
- the address of an `auto' variable (which is local to the caller) we
- can get a situation where the DECL_RTL of the artificial local
- variable (for the inlining) which acts as a stand-in for the
- corresponding formal parameter (of the inline function) will look
- like (plus:SI (reg:SI FRAME_PTR) (const_int ...)). This is not
- exactly a compile-time constant expression, but it isn't the address
- of the (artificial) local variable either. Rather, it represents the
- *value* which the artificial local variable always has during its
- lifetime. We currently have no way to represent such quasi-constant
- values in Dwarf, so for now we just punt and generate nothing. */
+ the address of an `auto' variable (which is local to the caller) we
+ can get a situation where the DECL_RTL of the artificial local
+ variable (for the inlining) which acts as a stand-in for the
+ corresponding formal parameter (of the inline function) will look
+ like (plus:SI (reg:SI FRAME_PTR) (const_int ...)). This is not
+ exactly a compile-time constant expression, but it isn't the address
+ of the (artificial) local variable either. Rather, it represents the
+ *value* which the artificial local variable always has during its
+ lifetime. We currently have no way to represent such quasi-constant
+ values in Dwarf, so for now we just punt and generate nothing. */
break;
default:
@@ -9176,8 +9355,7 @@ add_const_value_attribute (die, rtl)
}
static rtx
-rtl_for_decl_location (decl)
- tree decl;
+rtl_for_decl_location (tree decl)
{
rtx rtl;
@@ -9270,9 +9448,7 @@ rtl_for_decl_location (decl)
&& TREE_CODE (decl) == VAR_DECL
&& TREE_STATIC (decl))))
{
-#ifdef ASM_SIMPLIFY_DWARF_ADDR
- rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
-#endif
+ rtl = (*targetm.delegitimize_address) (rtl);
return rtl;
}
rtl = NULL_RTX;
@@ -9378,10 +9554,8 @@ rtl_for_decl_location (decl)
}
}
-#ifdef ASM_SIMPLIFY_DWARF_ADDR
if (rtl)
- rtl = ASM_SIMPLIFY_DWARF_ADDR (rtl);
-#endif
+ rtl = (*targetm.delegitimize_address) (rtl);
/* If we don't look past the constant pool, we risk emitting a
reference to a constant pool entry that isn't referenced from
@@ -9392,7 +9566,7 @@ rtl_for_decl_location (decl)
return rtl;
}
-/* Generate *either* an DW_AT_location attribute or else an DW_AT_const_value
+/* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value
data attribute for a variable or a parameter. We generate the
DW_AT_const_value attribute only in those cases where the given variable
or parameter does not have a true "location" either in memory or in a
@@ -9404,9 +9578,7 @@ rtl_for_decl_location (decl)
function call evaluates to a compile-time constant address. */
static void
-add_location_or_const_value_attribute (die, decl)
- dw_die_ref die;
- tree decl;
+add_location_or_const_value_attribute (dw_die_ref die, tree decl)
{
rtx rtl;
dw_loc_descr_ref descr;
@@ -9429,6 +9601,7 @@ add_location_or_const_value_attribute (die, decl)
case CONST_INT:
case CONST_DOUBLE:
+ case CONST_VECTOR:
case CONST_STRING:
case SYMBOL_REF:
case LABEL_REF:
@@ -9456,7 +9629,34 @@ add_location_or_const_value_attribute (die, decl)
}
add_AT_location_description (die, DW_AT_location, descr);
break;
-
+
+ case PARALLEL:
+ {
+ rtvec par_elems = XVEC (rtl, 0);
+ int num_elem = GET_NUM_ELEM (par_elems);
+ enum machine_mode mode;
+ int i;
+
+ /* Create the first one, so we have something to add to. */
+ descr = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0));
+ mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
+ add_loc_descr (&descr,
+ new_loc_descr (DW_OP_piece, GET_MODE_SIZE (mode), 0));
+ for (i = 1; i < num_elem; i++)
+ {
+ dw_loc_descr_ref temp;
+
+ temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0));
+ add_loc_descr (&descr, temp);
+ mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
+ add_loc_descr (&descr,
+ new_loc_descr (DW_OP_piece,
+ GET_MODE_SIZE (mode), 0));
+ }
+ }
+ add_AT_location_description (die, DW_AT_location, descr);
+ break;
+
default:
abort ();
}
@@ -9467,9 +9667,7 @@ add_location_or_const_value_attribute (die, decl)
we should tell the debugger about the constant value. */
static void
-tree_add_const_value_attribute (var_die, decl)
- dw_die_ref var_die;
- tree decl;
+tree_add_const_value_attribute (dw_die_ref var_die, tree decl)
{
tree init = DECL_INITIAL (decl);
tree type = TREE_TYPE (decl);
@@ -9496,13 +9694,11 @@ tree_add_const_value_attribute (var_die, decl)
}
}
-/* Generate an DW_AT_name attribute given some string value to be included as
+/* Generate a DW_AT_name attribute given some string value to be included as
the value of the attribute. */
-static inline void
-add_name_attribute (die, name_string)
- dw_die_ref die;
- const char *name_string;
+static void
+add_name_attribute (dw_die_ref die, const char *name_string)
{
if (name_string != NULL && *name_string != 0)
{
@@ -9513,14 +9709,21 @@ add_name_attribute (die, name_string)
}
}
+/* Generate a DW_AT_comp_dir attribute for DIE. */
+
+static void
+add_comp_dir_attribute (dw_die_ref die)
+{
+ const char *wd = get_src_pwd ();
+ if (wd != NULL)
+ add_AT_string (die, DW_AT_comp_dir, wd);
+}
+
/* Given a tree node describing an array bound (either lower or upper) output
a representation for that bound. */
static void
-add_bound_info (subrange_die, bound_attr, bound)
- dw_die_ref subrange_die;
- enum dwarf_attribute bound_attr;
- tree bound;
+add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree bound)
{
switch (TREE_CODE (bound))
{
@@ -9548,23 +9751,23 @@ add_bound_info (subrange_die, bound_attr, bound)
case SAVE_EXPR:
/* If optimization is turned on, the SAVE_EXPRs that describe how to
- access the upper bound values may be bogus. If they refer to a
- register, they may only describe how to get at these values at the
- points in the generated code right after they have just been
- computed. Worse yet, in the typical case, the upper bound values
- will not even *be* computed in the optimized code (though the
- number of elements will), so these SAVE_EXPRs are entirely
- bogus. In order to compensate for this fact, we check here to see
- if optimization is enabled, and if so, we don't add an attribute
- for the (unknown and unknowable) upper bound. This should not
- cause too much trouble for existing (stupid?) debuggers because
- they have to deal with empty upper bounds location descriptions
- anyway in order to be able to deal with incomplete array types.
- Of course an intelligent debugger (GDB?) should be able to
- comprehend that a missing upper bound specification in an array
- type used for a storage class `auto' local array variable
- indicates that the upper bound is both unknown (at compile- time)
- and unknowable (at run-time) due to optimization.
+ access the upper bound values may be bogus. If they refer to a
+ register, they may only describe how to get at these values at the
+ points in the generated code right after they have just been
+ computed. Worse yet, in the typical case, the upper bound values
+ will not even *be* computed in the optimized code (though the
+ number of elements will), so these SAVE_EXPRs are entirely
+ bogus. In order to compensate for this fact, we check here to see
+ if optimization is enabled, and if so, we don't add an attribute
+ for the (unknown and unknowable) upper bound. This should not
+ cause too much trouble for existing (stupid?) debuggers because
+ they have to deal with empty upper bounds location descriptions
+ anyway in order to be able to deal with incomplete array types.
+ Of course an intelligent debugger (GDB?) should be able to
+ comprehend that a missing upper bound specification in an array
+ type used for a storage class `auto' local array variable
+ indicates that the upper bound is both unknown (at compile- time)
+ and unknowable (at run-time) due to optimization.
We assume that a MEM rtx is safe because gcc wouldn't put the
value there unless it was going to be used repeatedly in the
@@ -9652,9 +9855,7 @@ add_bound_info (subrange_die, bound_attr, bound)
includes information about the element type of type given array type. */
static void
-add_subscript_info (type_die, type)
- dw_die_ref type_die;
- tree type;
+add_subscript_info (dw_die_ref type_die, tree type)
{
#ifndef MIPS_DEBUGGING_INFO
unsigned dimension_number;
@@ -9685,7 +9886,7 @@ add_subscript_info (type_die, type)
/* Arrays come in three flavors: Unspecified bounds, fixed bounds,
and (in GNU C only) variable bounds. Handle all three forms
- here. */
+ here. */
subrange_die = new_die (DW_TAG_subrange_type, type_die, NULL);
if (domain)
{
@@ -9693,7 +9894,7 @@ add_subscript_info (type_die, type)
lower = TYPE_MIN_VALUE (domain);
upper = TYPE_MAX_VALUE (domain);
- /* define the index type. */
+ /* Define the index type. */
if (TREE_TYPE (domain))
{
/* ??? This is probably an Ada unnamed subrange type. Ignore the
@@ -9712,7 +9913,7 @@ add_subscript_info (type_die, type)
/* ??? If upper is NULL, the array has unspecified length,
but it does have a lower bound. This happens with Fortran
dimension arr(N:*)
- Since the debugger is definitely going to need to know N
+ Since the debugger is definitely going to need to know N
to produce useful results, go ahead and output the lower
bound solo, and hope the debugger can cope. */
@@ -9728,9 +9929,7 @@ add_subscript_info (type_die, type)
}
static void
-add_byte_size_attribute (die, tree_node)
- dw_die_ref die;
- tree tree_node;
+add_byte_size_attribute (dw_die_ref die, tree tree_node)
{
unsigned size;
@@ -9747,9 +9946,9 @@ add_byte_size_attribute (die, tree_node)
break;
case FIELD_DECL:
/* For a data member of a struct or union, the DW_AT_byte_size is
- generally given as the number of bytes normally allocated for an
- object of the *declared* type of the member itself. This is true
- even for bit-fields. */
+ generally given as the number of bytes normally allocated for an
+ object of the *declared* type of the member itself. This is true
+ even for bit-fields. */
size = simple_type_size_in_bits (field_type (tree_node)) / BITS_PER_UNIT;
break;
default:
@@ -9780,9 +9979,7 @@ add_byte_size_attribute (die, tree_node)
(See `byte_size_attribute' above). */
static inline void
-add_bit_offset_attribute (die, decl)
- dw_die_ref die;
- tree decl;
+add_bit_offset_attribute (dw_die_ref die, tree decl)
{
HOST_WIDE_INT object_offset_in_bytes = field_byte_offset (decl);
tree type = DECL_BIT_FIELD_TYPE (decl);
@@ -9831,9 +10028,7 @@ add_bit_offset_attribute (die, decl)
which specifies the length in bits of the given field. */
static inline void
-add_bit_size_attribute (die, decl)
- dw_die_ref die;
- tree decl;
+add_bit_size_attribute (dw_die_ref die, tree decl)
{
/* Must be a field and a bit field. */
if (TREE_CODE (decl) != FIELD_DECL
@@ -9848,9 +10043,7 @@ add_bit_size_attribute (die, decl)
attribute, if arg types are given for the parameters of a function. */
static inline void
-add_prototyped_attribute (die, func_type)
- dw_die_ref die;
- tree func_type;
+add_prototyped_attribute (dw_die_ref die, tree func_type)
{
if (get_AT_unsigned (comp_unit_die, DW_AT_language) == DW_LANG_C89
&& TYPE_ARG_TYPES (func_type) != NULL)
@@ -9862,9 +10055,7 @@ add_prototyped_attribute (die, func_type)
equate table. */
static inline void
-add_abstract_origin_attribute (die, origin)
- dw_die_ref die;
- tree origin;
+add_abstract_origin_attribute (dw_die_ref die, tree origin)
{
dw_die_ref origin_die = NULL;
@@ -9874,7 +10065,7 @@ add_abstract_origin_attribute (die, origin)
function, if we're in an exception handler or some such; make
sure that the abstract function has been written out.
- Doing this for nested functions is wrong, however; functions are
+ Doing this for nested functions is wrong, however; functions are
distinct units, and our context might not even be inline. */
tree fn = origin;
@@ -9900,9 +10091,7 @@ add_abstract_origin_attribute (die, origin)
/* We do not currently support the pure_virtual attribute. */
static inline void
-add_pure_or_virtual_attribute (die, func_decl)
- dw_die_ref die;
- tree func_decl;
+add_pure_or_virtual_attribute (dw_die_ref die, tree func_decl)
{
if (DECL_VINDEX (func_decl))
{
@@ -9924,9 +10113,7 @@ add_pure_or_virtual_attribute (die, func_decl)
/* Add source coordinate attributes for the given decl. */
static void
-add_src_coords_attributes (die, decl)
- dw_die_ref die;
- tree decl;
+add_src_coords_attributes (dw_die_ref die, tree decl)
{
unsigned file_index = lookup_filename (DECL_SOURCE_FILE (decl));
@@ -9934,13 +10121,11 @@ add_src_coords_attributes (die, decl)
add_AT_unsigned (die, DW_AT_decl_line, DECL_SOURCE_LINE (decl));
}
-/* Add an DW_AT_name attribute and source coordinate attribute for the
+/* Add a DW_AT_name attribute and source coordinate attribute for the
given decl, but only if it actually has a name. */
static void
-add_name_and_src_coords_attributes (die, decl)
- dw_die_ref die;
- tree decl;
+add_name_and_src_coords_attributes (dw_die_ref die, tree decl)
{
tree decl_name;
@@ -9974,8 +10159,7 @@ add_name_and_src_coords_attributes (die, decl)
/* Push a new declaration scope. */
static void
-push_decl_scope (scope)
- tree scope;
+push_decl_scope (tree scope)
{
VARRAY_PUSH_TREE (decl_scope_table, scope);
}
@@ -9983,7 +10167,7 @@ push_decl_scope (scope)
/* Pop a declaration scope. */
static inline void
-pop_decl_scope ()
+pop_decl_scope (void)
{
if (VARRAY_ACTIVE_SIZE (decl_scope_table) <= 0)
abort ();
@@ -9998,9 +10182,7 @@ pop_decl_scope ()
the current active scope. */
static dw_die_ref
-scope_die_for (t, context_die)
- tree t;
- dw_die_ref context_die;
+scope_die_for (tree t, dw_die_ref context_die)
{
dw_die_ref scope_die = NULL;
tree containing_scope;
@@ -10012,9 +10194,14 @@ scope_die_for (t, context_die)
containing_scope = TYPE_CONTEXT (t);
- /* Ignore namespaces for the moment. */
+ /* Use the containing namespace if it was passed in (for a declaration). */
if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
- containing_scope = NULL_TREE;
+ {
+ if (context_die == lookup_decl_die (containing_scope))
+ /* OK */;
+ else
+ containing_scope = NULL_TREE;
+ }
/* Ignore function type "scopes" from the C frontend. They mean that
a tagged type is local to a parmlist of a function declarator, but
@@ -10054,8 +10241,7 @@ scope_die_for (t, context_die)
/* Returns nonzero if CONTEXT_DIE is internal to a function. */
static inline int
-local_scope_p (context_die)
- dw_die_ref context_die;
+local_scope_p (dw_die_ref context_die)
{
for (; context_die; context_die = context_die->die_parent)
if (context_die->die_tag == DW_TAG_inlined_subroutine
@@ -10065,28 +10251,25 @@ local_scope_p (context_die)
return 0;
}
-/* Returns nonzero if CONTEXT_DIE is a class. */
+/* Returns nonzero if CONTEXT_DIE is a class or namespace, for deciding
+ whether or not to treat a DIE in this context as a declaration. */
static inline int
-class_scope_p (context_die)
- dw_die_ref context_die;
+class_or_namespace_scope_p (dw_die_ref context_die)
{
return (context_die
&& (context_die->die_tag == DW_TAG_structure_type
- || context_die->die_tag == DW_TAG_union_type));
+ || context_die->die_tag == DW_TAG_union_type
+ || context_die->die_tag == DW_TAG_namespace));
}
/* Many forms of DIEs require a "type description" attribute. This
routine locates the proper "type descriptor" die for the type given
- by 'type', and adds an DW_AT_type attribute below the given die. */
+ by 'type', and adds a DW_AT_type attribute below the given die. */
static void
-add_type_attribute (object_die, type, decl_const, decl_volatile, context_die)
- dw_die_ref object_die;
- tree type;
- int decl_const;
- int decl_volatile;
- dw_die_ref context_die;
+add_type_attribute (dw_die_ref object_die, tree type, int decl_const,
+ int decl_volatile, dw_die_ref context_die)
{
enum tree_code code = TREE_CODE (type);
dw_die_ref type_die = NULL;
@@ -10120,8 +10303,7 @@ add_type_attribute (object_die, type, decl_const, decl_volatile, context_die)
was declared without a tag. */
static const char *
-type_tag (type)
- tree type;
+type_tag (tree type)
{
const char *name = 0;
@@ -10134,8 +10316,8 @@ type_tag (type)
t = TYPE_NAME (type);
/* The g++ front end makes the TYPE_NAME of *each* tagged type point to
- a TYPE_DECL node, regardless of whether or not a `typedef' was
- involved. */
+ a TYPE_DECL node, regardless of whether or not a `typedef' was
+ involved. */
else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
&& ! DECL_IGNORED_P (TYPE_NAME (type)))
t = DECL_NAME (TYPE_NAME (type));
@@ -10152,8 +10334,7 @@ type_tag (type)
for bit field types. */
static inline tree
-member_declared_type (member)
- tree member;
+member_declared_type (tree member)
{
return (DECL_BIT_FIELD_TYPE (member)
? DECL_BIT_FIELD_TYPE (member) : TREE_TYPE (member));
@@ -10164,8 +10345,7 @@ member_declared_type (member)
#if 0
static const char *
-decl_start_label (decl)
- tree decl;
+decl_start_label (tree decl)
{
rtx x;
const char *fnname;
@@ -10188,9 +10368,7 @@ decl_start_label (decl)
the declaration trees passed in from dwarf2out_decl(). */
static void
-gen_array_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_array_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref scope_die = scope_die_for (type, context_die);
dw_die_ref array_die;
@@ -10230,7 +10408,7 @@ gen_array_type_die (type, context_die)
/* The SGI compilers handle arrays of unknown bound by setting
AT_declaration and not emitting any subrange DIEs. */
if (! TYPE_DOMAIN (type))
- add_AT_unsigned (array_die, DW_AT_declaration, 1);
+ add_AT_flag (array_die, DW_AT_declaration, 1);
else
#endif
add_subscript_info (array_die, type);
@@ -10253,9 +10431,7 @@ gen_array_type_die (type, context_die)
}
static void
-gen_set_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_set_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die
= new_die (DW_TAG_set_type, scope_die_for (type, context_die), type);
@@ -10266,9 +10442,7 @@ gen_set_type_die (type, context_die)
#if 0
static void
-gen_entry_point_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_entry_point_die (tree decl, dw_die_ref context_die)
{
tree origin = decl_ultimate_origin (decl);
dw_die_ref decl_die = new_die (DW_TAG_entry_point, context_die, decl);
@@ -10293,7 +10467,7 @@ gen_entry_point_die (decl, context_die)
emit full debugging info for them. */
static void
-retry_incomplete_types ()
+retry_incomplete_types (void)
{
int i;
@@ -10304,9 +10478,7 @@ retry_incomplete_types ()
/* Generate a DIE to represent an inlined instance of an enumeration type. */
static void
-gen_inlined_enumeration_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_inlined_enumeration_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die = new_die (DW_TAG_enumeration_type, context_die, type);
@@ -10318,9 +10490,7 @@ gen_inlined_enumeration_type_die (type, context_die)
/* Generate a DIE to represent an inlined instance of a structure type. */
static void
-gen_inlined_structure_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_inlined_structure_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die = new_die (DW_TAG_structure_type, context_die, type);
@@ -10332,9 +10502,7 @@ gen_inlined_structure_type_die (type, context_die)
/* Generate a DIE to represent an inlined instance of a union type. */
static void
-gen_inlined_union_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_inlined_union_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die = new_die (DW_TAG_union_type, context_die, type);
@@ -10348,10 +10516,8 @@ gen_inlined_union_type_die (type, context_die)
enumerated type name/value is listed as a child of the enumerated type
DIE. */
-static void
-gen_enumeration_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+static dw_die_ref
+gen_enumeration_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die = lookup_type_die (type);
@@ -10363,7 +10529,7 @@ gen_enumeration_type_die (type, context_die)
add_name_attribute (type_die, type_tag (type));
}
else if (! TYPE_SIZE (type))
- return;
+ return type_die;
else
remove_AT (type_die, DW_AT_declaration);
@@ -10388,24 +10554,26 @@ gen_enumeration_type_die (type, context_die)
link != NULL; link = TREE_CHAIN (link))
{
dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die, link);
+ tree value = TREE_VALUE (link);
add_name_attribute (enum_die,
IDENTIFIER_POINTER (TREE_PURPOSE (link)));
- if (host_integerp (TREE_VALUE (link),
- TREE_UNSIGNED (TREE_TYPE (TREE_VALUE (link)))))
- {
- if (tree_int_cst_sgn (TREE_VALUE (link)) < 0)
- add_AT_int (enum_die, DW_AT_const_value,
- tree_low_cst (TREE_VALUE (link), 0));
- else
- add_AT_unsigned (enum_die, DW_AT_const_value,
- tree_low_cst (TREE_VALUE (link), 1));
- }
+ if (host_integerp (value, TREE_UNSIGNED (TREE_TYPE (value))))
+ /* DWARF2 does not provide a way of indicating whether or
+ not enumeration constants are signed or unsigned. GDB
+ always assumes the values are signed, so we output all
+ values as if they were signed. That means that
+ enumeration constants with very large unsigned values
+ will appear to have negative values in the debugger. */
+ add_AT_int (enum_die, DW_AT_const_value,
+ tree_low_cst (value, tree_int_cst_sgn (value) > 0));
}
}
else
add_AT_flag (type_die, DW_AT_declaration, 1);
+
+ return type_die;
}
/* Generate a DIE to represent either a real live formal parameter decl or to
@@ -10422,9 +10590,7 @@ gen_enumeration_type_die (type, context_die)
argument type of some subprogram type. */
static dw_die_ref
-gen_formal_parameter_die (node, context_die)
- tree node;
- dw_die_ref context_die;
+gen_formal_parameter_die (tree node, dw_die_ref context_die)
{
dw_die_ref parm_die
= new_die (DW_TAG_formal_parameter, context_die, node);
@@ -10469,9 +10635,7 @@ gen_formal_parameter_die (node, context_die)
at the end of an (ANSI prototyped) formal parameters list. */
static void
-gen_unspecified_parameters_die (decl_or_type, context_die)
- tree decl_or_type;
- dw_die_ref context_die;
+gen_unspecified_parameters_die (tree decl_or_type, dw_die_ref context_die)
{
new_die (DW_TAG_unspecified_parameters, context_die, decl_or_type);
}
@@ -10482,9 +10646,7 @@ gen_unspecified_parameters_die (decl_or_type, context_die)
those which appear as part of a function *definition*). */
static void
-gen_formal_types_die (function_or_method_type, context_die)
- tree function_or_method_type;
- dw_die_ref context_die;
+gen_formal_types_die (tree function_or_method_type, dw_die_ref context_die)
{
tree link;
tree formal_type = NULL;
@@ -10543,9 +10705,7 @@ gen_formal_types_die (function_or_method_type, context_die)
trick; we need to attach the member declaration by hand. */
static void
-gen_type_die_for_member (type, member, context_die)
- tree type, member;
- dw_die_ref context_die;
+gen_type_die_for_member (tree type, tree member, dw_die_ref context_die)
{
gen_type_die (type, context_die);
@@ -10571,8 +10731,7 @@ gen_type_die_for_member (type, member, context_die)
may later generate inlined and/or out-of-line instances of. */
static void
-dwarf2out_abstract_function (decl)
- tree decl;
+dwarf2out_abstract_function (tree decl)
{
dw_die_ref old_die;
tree save_fn;
@@ -10583,7 +10742,7 @@ dwarf2out_abstract_function (decl)
decl = DECL_ORIGIN (decl);
old_die = lookup_decl_die (decl);
- if (old_die && get_AT_unsigned (old_die, DW_AT_inline))
+ if (old_die && get_AT (old_die, DW_AT_inline))
/* We've already generated the abstract instance. */
return;
@@ -10613,9 +10772,7 @@ dwarf2out_abstract_function (decl)
block-local). */
static void
-gen_subprogram_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_subprogram_die (tree decl, dw_die_ref context_die)
{
char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
tree origin = decl_ultimate_origin (decl);
@@ -10625,7 +10782,7 @@ gen_subprogram_die (decl, context_die)
tree outer_scope;
dw_die_ref old_die = lookup_decl_die (decl);
int declaration = (current_function_decl != decl
- || class_scope_p (context_die));
+ || class_or_namespace_scope_p (context_die));
/* It is possible to have both DECL_ABSTRACT and DECLARATION be true if we
started to generate the abstract instance of an inline, decided to output
@@ -10634,7 +10791,7 @@ gen_subprogram_die (decl, context_die)
we'll get back to the abstract instance when done with the class. */
/* The class-scope declaration DIE must be the primary DIE. */
- if (origin && declaration && class_scope_p (context_die))
+ if (origin && declaration && class_or_namespace_scope_p (context_die))
{
origin = NULL;
if (old_die)
@@ -10662,7 +10819,7 @@ gen_subprogram_die (decl, context_die)
/* We can have a normal definition following an inline one in the
case of redefinition of GNU C extern inlines.
It seems reasonable to use AT_specification in this case. */
- && !get_AT_unsigned (old_die, DW_AT_inline))
+ && !get_AT (old_die, DW_AT_inline))
{
/* ??? This can happen if there is a bug in the program, for
instance, if it has duplicate function definitions. Ideally,
@@ -10696,7 +10853,7 @@ gen_subprogram_die (decl, context_die)
else
{
subr_die = new_die (DW_TAG_subprogram, context_die, decl);
- add_AT_die_ref (subr_die, DW_AT_specification, old_die);
+ add_AT_specification (subr_die, old_die);
if (get_AT_unsigned (old_die, DW_AT_decl_file) != file_index)
add_AT_unsigned (subr_die, DW_AT_decl_file, file_index);
if (get_AT_unsigned (old_die, DW_AT_decl_line)
@@ -10732,7 +10889,7 @@ gen_subprogram_die (decl, context_die)
if (declaration)
{
- if (!old_die || !get_AT_unsigned (old_die, DW_AT_inline))
+ if (!old_die || !get_AT (old_die, DW_AT_inline))
{
add_AT_flag (subr_die, DW_AT_declaration, 1);
@@ -10746,26 +10903,26 @@ gen_subprogram_die (decl, context_die)
}
else if (DECL_ABSTRACT (decl))
{
- if (DECL_INLINE (decl) && !flag_no_inline)
+ if (DECL_DECLARED_INLINE_P (decl))
{
- /* ??? Checking DECL_DEFER_OUTPUT is correct for static
- inline functions, but not for extern inline functions.
- We can't get this completely correct because information
- about whether the function was declared inline is not
- saved anywhere. */
- if (DECL_DEFER_OUTPUT (decl))
+ if (cgraph_function_possibly_inlined_p (decl))
add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_inlined);
else
- add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_inlined);
+ add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_not_inlined);
}
else
- add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_declared_not_inlined);
+ {
+ if (cgraph_function_possibly_inlined_p (decl))
+ add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_inlined);
+ else
+ add_AT_unsigned (subr_die, DW_AT_inline, DW_INL_not_inlined);
+ }
equate_decl_number_to_die (decl, subr_die);
}
else if (!DECL_EXTERNAL (decl))
{
- if (!old_die || !get_AT_unsigned (old_die, DW_AT_inline))
+ if (!old_die || !get_AT (old_die, DW_AT_inline))
equate_decl_number_to_die (decl, subr_die);
ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_BEGIN_LABEL,
@@ -10784,8 +10941,8 @@ gen_subprogram_die (decl, context_die)
#endif
/* Define the "frame base" location for this routine. We use the
- frame pointer or stack pointer registers, since the RTL for local
- variables is relative to one of them. */
+ frame pointer or stack pointer registers, since the RTL for local
+ variables is relative to one of them. */
fp_reg
= frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx;
add_AT_loc (subr_die, DW_AT_frame_base, reg_loc_descriptor (fp_reg));
@@ -10818,12 +10975,12 @@ gen_subprogram_die (decl, context_die)
gen_formal_types_die (decl, subr_die);
else
{
- /* Generate DIEs to represent all known formal parameters */
+ /* Generate DIEs to represent all known formal parameters. */
tree arg_decls = DECL_ARGUMENTS (decl);
tree parm;
/* When generating DIEs, generate the unspecified_parameters DIE
- instead if we come across the arg "__builtin_va_alist" */
+ instead if we come across the arg "__builtin_va_alist" */
for (parm = arg_decls; parm; parm = TREE_CHAIN (parm))
if (TREE_CODE (parm) == PARM_DECL)
{
@@ -10836,15 +10993,15 @@ gen_subprogram_die (decl, context_die)
}
/* Decide whether we need an unspecified_parameters DIE at the end.
- There are 2 more cases to do this for: 1) the ansi ... declaration -
- this is detectable when the end of the arg list is not a
- void_type_node 2) an unprototyped function declaration (not a
- definition). This just means that we have no info about the
- parameters at all. */
+ There are 2 more cases to do this for: 1) the ansi ... declaration -
+ this is detectable when the end of the arg list is not a
+ void_type_node 2) an unprototyped function declaration (not a
+ definition). This just means that we have no info about the
+ parameters at all. */
fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
if (fn_arg_types != NULL)
{
- /* this is the prototyped case, check for ... */
+ /* This is the prototyped case, check for.... */
if (TREE_VALUE (tree_last (fn_arg_types)) != void_type_node)
gen_unspecified_parameters_die (decl, subr_die);
}
@@ -10892,16 +11049,14 @@ gen_subprogram_die (decl, context_die)
/* Generate a DIE to represent a declared data object. */
static void
-gen_variable_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_variable_die (tree decl, dw_die_ref context_die)
{
tree origin = decl_ultimate_origin (decl);
dw_die_ref var_die = new_die (DW_TAG_variable, context_die, decl);
dw_die_ref old_die = lookup_decl_die (decl);
int declaration = (DECL_EXTERNAL (decl)
- || class_scope_p (context_die));
+ || class_or_namespace_scope_p (context_die));
if (origin != NULL)
add_abstract_origin_attribute (var_die, origin);
@@ -10918,7 +11073,7 @@ gen_variable_die (decl, context_die)
&& get_AT_flag (old_die, DW_AT_declaration) == 1)
{
/* This is a definition of a C++ class level static. */
- add_AT_die_ref (var_die, DW_AT_specification, old_die);
+ add_AT_specification (var_die, old_die);
if (DECL_NAME (decl))
{
unsigned file_index = lookup_filename (DECL_SOURCE_FILE (decl));
@@ -10954,7 +11109,7 @@ gen_variable_die (decl, context_die)
if (declaration)
add_AT_flag (var_die, DW_AT_declaration, 1);
- if (class_scope_p (context_die) || DECL_ABSTRACT (decl))
+ if (class_or_namespace_scope_p (context_die) || DECL_ABSTRACT (decl))
equate_decl_number_to_die (decl, var_die);
if (! declaration && ! DECL_ABSTRACT (decl))
@@ -10969,9 +11124,7 @@ gen_variable_die (decl, context_die)
/* Generate a DIE to represent a label identifier. */
static void
-gen_label_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_label_die (tree decl, dw_die_ref context_die)
{
tree origin = decl_ultimate_origin (decl);
dw_die_ref lbl_die = new_die (DW_TAG_label, context_die, decl);
@@ -10987,14 +11140,15 @@ gen_label_die (decl, context_die)
equate_decl_number_to_die (decl, lbl_die);
else
{
- insn = DECL_RTL (decl);
+ insn = DECL_RTL_IF_SET (decl);
/* Deleted labels are programmer specified labels which have been
- eliminated because of various optimisations. We still emit them
+ eliminated because of various optimizations. We still emit them
here so that it is possible to put breakpoints on them. */
- if (GET_CODE (insn) == CODE_LABEL
- || ((GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
+ if (insn
+ && (GET_CODE (insn) == CODE_LABEL
+ || ((GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL))))
{
/* When optimization is enabled (via -O) some parts of the compiler
(e.g. jump.c and cse.c) may try to delete CODE_LABEL insns which
@@ -11013,10 +11167,7 @@ gen_label_die (decl, context_die)
/* Generate a DIE for a lexical block. */
static void
-gen_lexical_block_die (stmt, context_die, depth)
- tree stmt;
- dw_die_ref context_die;
- int depth;
+gen_lexical_block_die (tree stmt, dw_die_ref context_die, int depth)
{
dw_die_ref stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -11055,10 +11206,7 @@ gen_lexical_block_die (stmt, context_die, depth)
/* Generate a DIE for an inlined subprogram. */
static void
-gen_inlined_subroutine_die (stmt, context_die, depth)
- tree stmt;
- dw_die_ref context_die;
- int depth;
+gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die, int depth)
{
tree decl = block_ultimate_origin (stmt);
@@ -11103,15 +11251,13 @@ gen_inlined_subroutine_die (stmt, context_die, depth)
/* Generate a DIE for a field in a record, or structure. */
static void
-gen_field_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_field_die (tree decl, dw_die_ref context_die)
{
dw_die_ref decl_die;
if (TREE_TYPE (decl) == error_mark_node)
return;
-
+
decl_die = new_die (DW_TAG_member, context_die, decl);
add_name_and_src_coords_attributes (decl_die, decl);
add_type_attribute (decl_die, member_declared_type (decl),
@@ -11144,9 +11290,7 @@ gen_field_die (decl, context_die)
represent certain things in other languages (e.g. Pascal) someday. */
static void
-gen_pointer_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_pointer_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref ptr_die
= new_die (DW_TAG_pointer_type, scope_die_for (type, context_die), type);
@@ -11162,9 +11306,7 @@ gen_pointer_type_die (type, context_die)
represent certain things in other languages (e.g. Pascal) someday. */
static void
-gen_reference_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_reference_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref ref_die
= new_die (DW_TAG_reference_type, scope_die_for (type, context_die), type);
@@ -11178,9 +11320,7 @@ gen_reference_type_die (type, context_die)
/* Generate a DIE for a pointer to a member type. */
static void
-gen_ptr_to_mbr_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_ptr_to_mbr_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref ptr_die
= new_die (DW_TAG_ptr_to_member_type,
@@ -11195,20 +11335,22 @@ gen_ptr_to_mbr_type_die (type, context_die)
/* Generate the DIE for the compilation unit. */
static dw_die_ref
-gen_compile_unit_die (filename)
- const char *filename;
+gen_compile_unit_die (const char *filename)
{
dw_die_ref die;
char producer[250];
- const char *wd = getpwd ();
const char *language_string = lang_hooks.name;
int language;
die = new_die (DW_TAG_compile_unit, NULL, NULL);
- add_name_attribute (die, filename);
- if (wd != NULL && filename[0] != DIR_SEPARATOR)
- add_AT_string (die, DW_AT_comp_dir, wd);
+ if (filename)
+ {
+ add_name_attribute (die, filename);
+ /* Don't add cwd for <built-in>. */
+ if (filename[0] != DIR_SEPARATOR && filename[0] != '<')
+ add_comp_dir_attribute (die);
+ }
sprintf (producer, "%s %s", language_string, version_string);
@@ -11228,7 +11370,7 @@ gen_compile_unit_die (filename)
if (strcmp (language_string, "GNU C++") == 0)
language = DW_LANG_C_plus_plus;
else if (strcmp (language_string, "GNU Ada") == 0)
- language = DW_LANG_Ada83;
+ language = DW_LANG_Ada95;
else if (strcmp (language_string, "GNU F77") == 0)
language = DW_LANG_Fortran77;
else if (strcmp (language_string, "GNU Pascal") == 0)
@@ -11245,9 +11387,7 @@ gen_compile_unit_die (filename)
/* Generate a DIE for a string type. */
static void
-gen_string_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_string_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die
= new_die (DW_TAG_string_type, scope_die_for (type, context_die), type);
@@ -11265,9 +11405,7 @@ gen_string_type_die (type, context_die)
/* Generate the DIE for a base class. */
static void
-gen_inheritance_die (binfo, context_die)
- tree binfo;
- dw_die_ref context_die;
+gen_inheritance_die (tree binfo, tree access, dw_die_ref context_die)
{
dw_die_ref die = new_die (DW_TAG_inheritance, context_die, binfo);
@@ -11277,20 +11415,19 @@ gen_inheritance_die (binfo, context_die)
if (TREE_VIA_VIRTUAL (binfo))
add_AT_unsigned (die, DW_AT_virtuality, DW_VIRTUALITY_virtual);
- if (TREE_VIA_PUBLIC (binfo))
+ if (access == access_public_node)
add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_public);
- else if (TREE_VIA_PROTECTED (binfo))
+ else if (access == access_protected_node)
add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_protected);
}
/* Generate a DIE for a class member. */
static void
-gen_member_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_member_die (tree type, dw_die_ref context_die)
{
tree member;
+ tree binfo = TYPE_BINFO (type);
dw_die_ref child;
/* If this is not an incomplete type, output descriptions of each of its
@@ -11306,14 +11443,17 @@ gen_member_die (type, context_die)
the TREE node representing the appropriate (containing) type. */
/* First output info about the base classes. */
- if (TYPE_BINFO (type) && TYPE_BINFO_BASETYPES (type))
+ if (binfo && BINFO_BASETYPES (binfo))
{
- tree bases = TYPE_BINFO_BASETYPES (type);
+ tree bases = BINFO_BASETYPES (binfo);
+ tree accesses = BINFO_BASEACCESSES (binfo);
int n_bases = TREE_VEC_LENGTH (bases);
int i;
for (i = 0; i < n_bases; i++)
- gen_inheritance_die (TREE_VEC_ELT (bases, i), context_die);
+ gen_inheritance_die (TREE_VEC_ELT (bases, i),
+ (accesses ? TREE_VEC_ELT (accesses, i)
+ : access_public_node), context_die);
}
/* Now output info about the data members and type members. */
@@ -11351,9 +11491,7 @@ gen_member_die (type, context_die)
member DIEs needed by later specification DIEs. */
static void
-gen_struct_or_union_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_struct_or_union_type_die (tree type, dw_die_ref context_die)
{
dw_die_ref type_die = lookup_type_die (type);
dw_die_ref scope_die = 0;
@@ -11361,12 +11499,14 @@ gen_struct_or_union_type_die (type, context_die)
int complete = (TYPE_SIZE (type)
&& (! TYPE_STUB_DECL (type)
|| ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))));
+ int ns_decl = (context_die && context_die->die_tag == DW_TAG_namespace);
if (type_die && ! complete)
return;
if (TYPE_CONTEXT (type) != NULL_TREE
- && AGGREGATE_TYPE_P (TYPE_CONTEXT (type)))
+ && (AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
+ || TREE_CODE (TYPE_CONTEXT (type)) == NAMESPACE_DECL))
nested = 1;
scope_die = scope_die_for (type, context_die);
@@ -11381,7 +11521,7 @@ gen_struct_or_union_type_die (type, context_die)
scope_die, type);
equate_type_number_to_die (type, type_die);
if (old_die)
- add_AT_die_ref (type_die, DW_AT_specification, old_die);
+ add_AT_specification (type_die, old_die);
else
add_name_attribute (type_die, type_tag (type));
}
@@ -11390,10 +11530,10 @@ gen_struct_or_union_type_die (type, context_die)
/* If this type has been completed, then give it a byte_size attribute and
then give a list of members. */
- if (complete)
+ if (complete && !ns_decl)
{
/* Prevent infinite recursion in cases where the type of some member of
- this type is expressed in terms of this type itself. */
+ this type is expressed in terms of this type itself. */
TREE_ASM_WRITTEN (type) = 1;
add_byte_size_attribute (type_die, type);
if (TYPE_STUB_DECL (type) != NULL_TREE)
@@ -11432,9 +11572,7 @@ gen_struct_or_union_type_die (type, context_die)
/* Generate a DIE for a subroutine _type_. */
static void
-gen_subroutine_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_subroutine_type_die (tree type, dw_die_ref context_die)
{
tree return_type = TREE_TYPE (type);
dw_die_ref subr_die
@@ -11447,12 +11585,10 @@ gen_subroutine_type_die (type, context_die)
gen_formal_types_die (type, subr_die);
}
-/* Generate a DIE for a type definition */
+/* Generate a DIE for a type definition. */
static void
-gen_typedef_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_typedef_die (tree decl, dw_die_ref context_die)
{
dw_die_ref type_die;
tree origin;
@@ -11493,9 +11629,7 @@ gen_typedef_die (decl, context_die)
/* Generate a type description DIE. */
static void
-gen_type_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_type_die (tree type, dw_die_ref context_die)
{
int need_pop;
@@ -11543,7 +11677,7 @@ gen_type_die (type, context_die)
TREE_ASM_WRITTEN (type) = 1;
/* For these types, all that is required is that we output a DIE (or a
- set of DIEs) to represent the "basis" type. */
+ set of DIEs) to represent the "basis" type. */
gen_type_die (TREE_TYPE (type), context_die);
break;
@@ -11556,7 +11690,7 @@ gen_type_die (type, context_die)
gen_type_die (TREE_TYPE (type), context_die);
/* Now output a DIE to represent this pointer-to-data-member type
- itself. */
+ itself. */
gen_ptr_to_mbr_type_die (type, context_die);
break;
@@ -11601,11 +11735,11 @@ gen_type_die (type, context_die)
case UNION_TYPE:
case QUAL_UNION_TYPE:
/* If this is a nested type whose containing class hasn't been written
- out yet, writing it out will cover this one, too. This does not apply
- to instantiations of member class templates; they need to be added to
- the containing class as they are generated. FIXME: This hurts the
- idea of combining type decls from multiple TUs, since we can't predict
- what set of template instantiations we'll get. */
+ out yet, writing it out will cover this one, too. This does not apply
+ to instantiations of member class templates; they need to be added to
+ the containing class as they are generated. FIXME: This hurts the
+ idea of combining type decls from multiple TUs, since we can't predict
+ what set of template instantiations we'll get. */
if (TYPE_CONTEXT (type)
&& AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
&& ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type)))
@@ -11621,7 +11755,10 @@ gen_type_die (type, context_die)
need_pop = 1;
}
else
- need_pop = 0;
+ {
+ declare_in_namespace (type, context_die);
+ need_pop = 0;
+ }
if (TREE_CODE (type) == ENUMERAL_TYPE)
gen_enumeration_type_die (type, context_die);
@@ -11659,9 +11796,7 @@ gen_type_die (type, context_die)
/* Generate a DIE for a tagged type instantiation. */
static void
-gen_tagged_type_instantiation_die (type, context_die)
- tree type;
- dw_die_ref context_die;
+gen_tagged_type_instantiation_die (tree type, dw_die_ref context_die)
{
if (type == NULL_TREE || type == error_mark_node)
return;
@@ -11703,10 +11838,7 @@ gen_tagged_type_instantiation_die (type, context_die)
things which are local to the given block. */
static void
-gen_block_die (stmt, context_die, depth)
- tree stmt;
- dw_die_ref context_die;
- int depth;
+gen_block_die (tree stmt, dw_die_ref context_die, int depth)
{
int must_output_die = 0;
tree origin;
@@ -11748,12 +11880,12 @@ gen_block_die (stmt, context_die, depth)
else
{
/* In the case where the current block represents an inlining of the
- "body block" of an inline function, we must *NOT* output any DIE for
- this block because we have already output a DIE to represent the whole
- inlined function scope and the "body block" of any function doesn't
- really represent a different scope according to ANSI C rules. So we
- check here to make sure that this block does not represent a "body
- block inlining" before trying to set the MUST_OUTPUT_DIE flag. */
+ "body block" of an inline function, we must *NOT* output any DIE for
+ this block because we have already output a DIE to represent the whole
+ inlined function scope and the "body block" of any function doesn't
+ really represent a different scope according to ANSI C rules. So we
+ check here to make sure that this block does not represent a "body
+ block inlining" before trying to set the MUST_OUTPUT_DIE flag. */
if (! is_body_block (origin ? origin : stmt))
{
/* Determine if this block directly contains any "significant"
@@ -11798,10 +11930,7 @@ gen_block_die (stmt, context_die, depth)
all of its sub-blocks. */
static void
-decls_for_scope (stmt, context_die, depth)
- tree stmt;
- dw_die_ref context_die;
- int depth;
+decls_for_scope (tree stmt, dw_die_ref context_die, int depth)
{
tree decl;
tree subblocks;
@@ -11846,8 +11975,7 @@ decls_for_scope (stmt, context_die, depth)
/* Is this a typedef we can avoid emitting? */
static inline int
-is_redundant_typedef (decl)
- tree decl;
+is_redundant_typedef (tree decl)
{
if (TYPE_DECL_IS_STUB (decl))
return 1;
@@ -11863,12 +11991,102 @@ is_redundant_typedef (decl)
return 0;
}
+/* Returns the DIE for namespace NS or aborts.
+
+ Note that namespaces don't really have a lexical context, so there's no
+ need to pass in a context_die. They always go inside their containing
+ namespace, or comp_unit_die if none. */
+
+static dw_die_ref
+force_namespace_die (tree ns)
+{
+ dw_die_ref ns_die;
+
+ dwarf2out_decl (ns);
+ ns_die = lookup_decl_die (ns);
+ if (!ns_die)
+ abort();
+
+ return ns_die;
+}
+
+/* Force out any required namespaces to be able to output DECL,
+ and return the new context_die for it, if it's changed. */
+
+static dw_die_ref
+setup_namespace_context (tree thing, dw_die_ref context_die)
+{
+ tree context = DECL_P (thing) ? DECL_CONTEXT (thing) : TYPE_CONTEXT (thing);
+ if (context && TREE_CODE (context) == NAMESPACE_DECL)
+ /* Force out the namespace. */
+ context_die = force_namespace_die (context);
+
+ return context_die;
+}
+
+/* Emit a declaration DIE for THING (which is either a DECL or a tagged
+ type) within its namespace, if appropriate.
+
+ For compatibility with older debuggers, namespace DIEs only contain
+ declarations; all definitions are emitted at CU scope. */
+
+static void
+declare_in_namespace (tree thing, dw_die_ref context_die)
+{
+ dw_die_ref ns_context;
+
+ if (debug_info_level <= DINFO_LEVEL_TERSE)
+ return;
+
+ ns_context = setup_namespace_context (thing, context_die);
+
+ if (ns_context != context_die)
+ {
+ if (DECL_P (thing))
+ gen_decl_die (thing, ns_context);
+ else
+ gen_type_die (thing, ns_context);
+ }
+}
+
+/* Generate a DIE for a namespace or namespace alias. */
+
+static void
+gen_namespace_die (tree decl)
+{
+ dw_die_ref context_die = setup_namespace_context (decl, comp_unit_die);
+
+ /* Namespace aliases have a DECL_ABSTRACT_ORIGIN of the namespace
+ they are an alias of. */
+ if (DECL_ABSTRACT_ORIGIN (decl) == NULL)
+ {
+ /* Output a real namespace. */
+ dw_die_ref namespace_die
+ = new_die (DW_TAG_namespace, context_die, decl);
+ add_name_and_src_coords_attributes (namespace_die, decl);
+ equate_decl_number_to_die (decl, namespace_die);
+ }
+ else
+ {
+ /* Output a namespace alias. */
+
+ /* Force out the namespace we are an alias of, if necessary. */
+ dw_die_ref origin_die
+ = force_namespace_die (DECL_ABSTRACT_ORIGIN (decl));
+
+ /* Now create the namespace alias DIE. */
+ dw_die_ref namespace_die
+ = new_die (DW_TAG_imported_declaration, context_die, decl);
+ add_name_and_src_coords_attributes (namespace_die, decl);
+ add_AT_die_ref (namespace_die, DW_AT_import, origin_die);
+ equate_decl_number_to_die (decl, namespace_die);
+ }
+}
+
/* Generate Dwarf debug information for a decl described by DECL. */
static void
-gen_decl_die (decl, context_die)
- tree decl;
- dw_die_ref context_die;
+gen_decl_die (tree decl, dw_die_ref context_die)
{
tree origin;
@@ -11882,7 +12100,7 @@ gen_decl_die (decl, context_die)
case CONST_DECL:
/* The individual enumerators of an enum type get output when we output
- the Dwarf representation of the relevant enum type itself. */
+ the Dwarf representation of the relevant enum type itself. */
break;
case FUNCTION_DECL:
@@ -11898,8 +12116,9 @@ gen_decl_die (decl, context_die)
/* If we're emitting an out-of-line copy of an inline function,
emit info for the abstract instance and set up to refer to it. */
- else if (DECL_INLINE (decl) && ! DECL_ABSTRACT (decl)
- && ! class_scope_p (context_die)
+ else if (cgraph_function_possibly_inlined_p (decl)
+ && ! DECL_ABSTRACT (decl)
+ && ! class_or_namespace_scope_p (context_die)
/* dwarf2out_abstract_function won't emit a die if this is just
a declaration. We must avoid setting DECL_ABSTRACT_ORIGIN in
that case, because that works only if we have a die. */
@@ -11924,6 +12143,9 @@ gen_decl_die (decl, context_die)
origin = decl_class_context (decl);
if (origin != NULL_TREE)
gen_type_die_for_member (origin, decl, context_die);
+
+ /* And its containing namespace. */
+ declare_in_namespace (decl, context_die);
}
/* Now output a DIE to represent the function itself. */
@@ -11932,16 +12154,16 @@ gen_decl_die (decl, context_die)
case TYPE_DECL:
/* If we are in terse mode, don't generate any DIEs to represent any
- actual typedefs. */
+ actual typedefs. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
break;
/* In the special case of a TYPE_DECL node representing the declaration
- of some type tag, if the given TYPE_DECL is marked as having been
- instantiated from some other (original) TYPE_DECL node (e.g. one which
- was generated within the original definition of an inline function) we
- have to generate a special (abbreviated) DW_TAG_structure_type,
- DW_TAG_union_type, or DW_TAG_enumeration_type DIE here. */
+ of some type tag, if the given TYPE_DECL is marked as having been
+ instantiated from some other (original) TYPE_DECL node (e.g. one which
+ was generated within the original definition of an inline function) we
+ have to generate a special (abbreviated) DW_TAG_structure_type,
+ DW_TAG_union_type, or DW_TAG_enumeration_type DIE here. */
if (TYPE_DECL_IS_STUB (decl) && decl_ultimate_origin (decl) != NULL_TREE)
{
gen_tagged_type_instantiation_die (TREE_TYPE (decl), context_die);
@@ -11962,12 +12184,12 @@ gen_decl_die (decl, context_die)
case VAR_DECL:
/* If we are in terse mode, don't generate any DIEs to represent any
- variable declarations or definitions. */
+ variable declarations or definitions. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
break;
/* Output any DIEs that are needed to specify the type of this data
- object. */
+ object. */
gen_type_die (TREE_TYPE (decl), context_die);
/* And its containing type. */
@@ -11975,10 +12197,13 @@ gen_decl_die (decl, context_die)
if (origin != NULL_TREE)
gen_type_die_for_member (origin, decl, context_die);
+ /* And its containing namespace. */
+ declare_in_namespace (decl, context_die);
+
/* Now output the DIE to represent the data object itself. This gets
- complicated because of the possibility that the VAR_DECL really
- represents an inlined instance of a formal parameter for an inline
- function. */
+ complicated because of the possibility that the VAR_DECL really
+ represents an inlined instance of a formal parameter for an inline
+ function. */
origin = decl_ultimate_origin (decl);
if (origin != NULL_TREE && TREE_CODE (origin) == PARM_DECL)
gen_formal_parameter_die (decl, context_die);
@@ -12003,29 +12228,21 @@ gen_decl_die (decl, context_die)
break;
case NAMESPACE_DECL:
- /* Ignore for now. */
+ gen_namespace_die (decl);
break;
default:
+ if ((int)TREE_CODE (decl) > NUM_TREE_CODES)
+ /* Probably some frontend-internal decl. Assume we don't care. */
+ break;
abort ();
}
}
-
-static void
-mark_limbo_die_list (ptr)
- void *ptr ATTRIBUTE_UNUSED;
-{
- limbo_die_node *node;
- for (node = limbo_die_list; node; node = node->next)
- ggc_mark_tree (node->created_for);
-}
/* Add Ada "use" clause information for SGI Workshop debugger. */
void
-dwarf2out_add_library_unit_info (filename, context_list)
- const char *filename;
- const char *context_list;
+dwarf2out_add_library_unit_info (const char *filename, const char *context_list)
{
unsigned int file_index;
@@ -12048,8 +12265,7 @@ dwarf2out_add_library_unit_info (filename, context_list)
compilation proper has finished. */
static void
-dwarf2out_global_decl (decl)
- tree decl;
+dwarf2out_global_decl (tree decl)
{
/* Output DWARF2 information for file-scope tentative data object
declarations, file-scope (extern) function declarations (which had no
@@ -12062,8 +12278,7 @@ dwarf2out_global_decl (decl)
/* Write the debugging output for DECL. */
void
-dwarf2out_decl (decl)
- tree decl;
+dwarf2out_decl (tree decl)
{
dw_die_ref context_die = comp_unit_die;
@@ -12073,33 +12288,27 @@ dwarf2out_decl (decl)
return;
case FUNCTION_DECL:
- /* Ignore this FUNCTION_DECL if it refers to a builtin declaration of a
- builtin function. Explicit programmer-supplied declarations of
- these same functions should NOT be ignored however. */
- if (DECL_EXTERNAL (decl) && DECL_BUILT_IN (decl))
- return;
-
/* What we would really like to do here is to filter out all mere
- file-scope declarations of file-scope functions which are never
- referenced later within this translation unit (and keep all of ones
- that *are* referenced later on) but we aren't clairvoyant, so we have
- no idea which functions will be referenced in the future (i.e. later
- on within the current translation unit). So here we just ignore all
- file-scope function declarations which are not also definitions. If
- and when the debugger needs to know something about these functions,
- it will have to hunt around and find the DWARF information associated
- with the definition of the function.
+ file-scope declarations of file-scope functions which are never
+ referenced later within this translation unit (and keep all of ones
+ that *are* referenced later on) but we aren't clairvoyant, so we have
+ no idea which functions will be referenced in the future (i.e. later
+ on within the current translation unit). So here we just ignore all
+ file-scope function declarations which are not also definitions. If
+ and when the debugger needs to know something about these functions,
+ it will have to hunt around and find the DWARF information associated
+ with the definition of the function.
We can't just check DECL_EXTERNAL to find out which FUNCTION_DECL
- nodes represent definitions and which ones represent mere
- declarations. We have to check DECL_INITIAL instead. That's because
- the C front-end supports some weird semantics for "extern inline"
- function definitions. These can get inlined within the current
- translation unit (an thus, we need to generate Dwarf info for their
- abstract instances so that the Dwarf info for the concrete inlined
- instances can have something to refer to) but the compiler never
- generates any out-of-lines instances of such things (despite the fact
- that they *are* definitions).
+ nodes represent definitions and which ones represent mere
+ declarations. We have to check DECL_INITIAL instead. That's because
+ the C front-end supports some weird semantics for "extern inline"
+ function definitions. These can get inlined within the current
+ translation unit (an thus, we need to generate Dwarf info for their
+ abstract instances so that the Dwarf info for the concrete inlined
+ instances can have something to refer to) but the compiler never
+ generates any out-of-lines instances of such things (despite the fact
+ that they *are* definitions).
The important point is that the C front-end marks these "extern
inline" functions as DECL_EXTERNAL, but we need to generate DWARF for
@@ -12120,33 +12329,40 @@ dwarf2out_decl (decl)
case VAR_DECL:
/* Ignore this VAR_DECL if it refers to a file-scope extern data object
- declaration and if the declaration was never even referenced from
- within this entire compilation unit. We suppress these DIEs in
- order to save space in the .debug section (by eliminating entries
- which are probably useless). Note that we must not suppress
- block-local extern declarations (whether used or not) because that
- would screw-up the debugger's name lookup mechanism and cause it to
- miss things which really ought to be in scope at a given point. */
+ declaration and if the declaration was never even referenced from
+ within this entire compilation unit. We suppress these DIEs in
+ order to save space in the .debug section (by eliminating entries
+ which are probably useless). Note that we must not suppress
+ block-local extern declarations (whether used or not) because that
+ would screw-up the debugger's name lookup mechanism and cause it to
+ miss things which really ought to be in scope at a given point. */
if (DECL_EXTERNAL (decl) && !TREE_USED (decl))
return;
/* If we are in terse mode, don't generate any DIEs to represent any
- variable declarations or definitions. */
+ variable declarations or definitions. */
if (debug_info_level <= DINFO_LEVEL_TERSE)
return;
break;
+ case NAMESPACE_DECL:
+ if (debug_info_level <= DINFO_LEVEL_TERSE)
+ return;
+ if (lookup_decl_die (decl) != NULL)
+ return;
+ break;
+
case TYPE_DECL:
/* Don't emit stubs for types unless they are needed by other DIEs. */
if (TYPE_DECL_SUPPRESS_DEBUG (decl))
return;
/* Don't bother trying to generate any DIEs to represent any of the
- normal built-in types for the language we are compiling. */
+ normal built-in types for the language we are compiling. */
if (DECL_SOURCE_LINE (decl) == 0)
{
/* OK, we need to generate one for `bool' so GDB knows what type
- comparisons have. */
+ comparisons have. */
if ((get_AT_unsigned (comp_unit_die, DW_AT_language)
== DW_LANG_C_plus_plus)
&& TREE_CODE (TREE_TYPE (decl)) == BOOLEAN_TYPE
@@ -12178,9 +12394,8 @@ dwarf2out_decl (decl)
a lexical block. */
static void
-dwarf2out_begin_block (line, blocknum)
- unsigned int line ATTRIBUTE_UNUSED;
- unsigned int blocknum;
+dwarf2out_begin_block (unsigned int line ATTRIBUTE_UNUSED,
+ unsigned int blocknum)
{
function_section (current_function_decl);
ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
@@ -12190,9 +12405,7 @@ dwarf2out_begin_block (line, blocknum)
lexical block. */
static void
-dwarf2out_end_block (line, blocknum)
- unsigned int line ATTRIBUTE_UNUSED;
- unsigned int blocknum;
+dwarf2out_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum)
{
function_section (current_function_decl);
ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum);
@@ -12206,8 +12419,7 @@ dwarf2out_end_block (line, blocknum)
we may end up calling them anyway. */
static bool
-dwarf2out_ignore_block (block)
- tree block;
+dwarf2out_ignore_block (tree block)
{
tree decl;
@@ -12231,65 +12443,70 @@ dwarf2out_ignore_block (block)
all searches. */
static unsigned
-lookup_filename (file_name)
- const char *file_name;
+lookup_filename (const char *file_name)
{
- unsigned i;
-
- /* ??? Why isn't DECL_SOURCE_FILE left null instead. */
- if (strcmp (file_name, "<internal>") == 0
- || strcmp (file_name, "<built-in>") == 0)
- return 0;
+ size_t i, n;
+ char *save_file_name;
/* Check to see if the file name that was searched on the previous
call matches this file name. If so, return the index. */
- if (file_table.last_lookup_index != 0)
- if (0 == strcmp (file_name,
- file_table.table[file_table.last_lookup_index]))
- return file_table.last_lookup_index;
+ if (file_table_last_lookup_index != 0)
+ {
+ const char *last
+ = VARRAY_CHAR_PTR (file_table, file_table_last_lookup_index);
+ if (strcmp (file_name, last) == 0)
+ return file_table_last_lookup_index;
+ }
/* Didn't match the previous lookup, search the table */
- for (i = 1; i < file_table.in_use; i++)
- if (strcmp (file_name, file_table.table[i]) == 0)
+ n = VARRAY_ACTIVE_SIZE (file_table);
+ for (i = 1; i < n; i++)
+ if (strcmp (file_name, VARRAY_CHAR_PTR (file_table, i)) == 0)
{
- file_table.last_lookup_index = i;
+ file_table_last_lookup_index = i;
return i;
}
- /* Prepare to add a new table entry by making sure there is enough space in
- the table to do so. If not, expand the current table. */
- if (i == file_table.allocated)
- {
- file_table.allocated = i + FILE_TABLE_INCREMENT;
- file_table.table = (char **)
- xrealloc (file_table.table, file_table.allocated * sizeof (char *));
- }
-
/* Add the new entry to the end of the filename table. */
- file_table.table[i] = xstrdup (file_name);
- file_table.in_use = i + 1;
- file_table.last_lookup_index = i;
+ file_table_last_lookup_index = n;
+ save_file_name = (char *) ggc_strdup (file_name);
+ VARRAY_PUSH_CHAR_PTR (file_table, save_file_name);
+ VARRAY_PUSH_UINT (file_table_emitted, 0);
- if (DWARF2_ASM_LINE_DEBUG_INFO)
+ return i;
+}
+
+static int
+maybe_emit_file (int fileno)
+{
+ if (DWARF2_ASM_LINE_DEBUG_INFO && fileno > 0)
{
- fprintf (asm_out_file, "\t.file %u ", i);
- output_quoted_string (asm_out_file, file_name);
- fputc ('\n', asm_out_file);
+ if (!VARRAY_UINT (file_table_emitted, fileno))
+ {
+ VARRAY_UINT (file_table_emitted, fileno) = ++emitcount;
+ fprintf (asm_out_file, "\t.file %u ",
+ VARRAY_UINT (file_table_emitted, fileno));
+ output_quoted_string (asm_out_file,
+ VARRAY_CHAR_PTR (file_table, fileno));
+ fputc ('\n', asm_out_file);
+ }
+ return VARRAY_UINT (file_table_emitted, fileno);
}
-
- return i;
+ else
+ return fileno;
}
static void
-init_file_table ()
+init_file_table (void)
{
/* Allocate the initial hunk of the file_table. */
- file_table.table = (char **) xcalloc (FILE_TABLE_INCREMENT, sizeof (char *));
- file_table.allocated = FILE_TABLE_INCREMENT;
+ VARRAY_CHAR_PTR_INIT (file_table, 64, "file_table");
+ VARRAY_UINT_INIT (file_table_emitted, 64, "file_table_emitted");
/* Skip the first entry - file numbers begin at 1. */
- file_table.in_use = 1;
- file_table.last_lookup_index = 0;
+ VARRAY_PUSH_CHAR_PTR (file_table, NULL);
+ VARRAY_PUSH_UINT (file_table_emitted, 0);
+ file_table_last_lookup_index = 0;
}
/* Output a label to mark the beginning of a source code line entry
@@ -12297,11 +12514,10 @@ init_file_table ()
'line_info_table' for later output of the .debug_line section. */
static void
-dwarf2out_source_line (line, filename)
- unsigned int line;
- const char *filename;
+dwarf2out_source_line (unsigned int line, const char *filename)
{
- if (debug_info_level >= DINFO_LEVEL_NORMAL)
+ if (debug_info_level >= DINFO_LEVEL_NORMAL
+ && line != 0)
{
function_section (current_function_decl);
@@ -12314,6 +12530,8 @@ dwarf2out_source_line (line, filename)
{
unsigned file_num = lookup_filename (filename);
+ file_num = maybe_emit_file (file_num);
+
/* Emit the .loc directive understood by GNU as. */
fprintf (asm_out_file, "\t.loc %d %d 0\n", file_num, line);
@@ -12327,7 +12545,7 @@ dwarf2out_source_line (line, filename)
else if (DECL_SECTION_NAME (current_function_decl))
{
dw_separate_line_info_ref line_info;
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, SEPARATE_LINE_CODE_LABEL,
+ (*targetm.asm_out.internal_label) (asm_out_file, SEPARATE_LINE_CODE_LABEL,
separate_line_info_table_in_use);
/* expand the line info table if necessary */
@@ -12336,10 +12554,14 @@ dwarf2out_source_line (line, filename)
{
separate_line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
separate_line_info_table
- = (dw_separate_line_info_ref)
- xrealloc (separate_line_info_table,
- separate_line_info_table_allocated
- * sizeof (dw_separate_line_info_entry));
+ = ggc_realloc (separate_line_info_table,
+ separate_line_info_table_allocated
+ * sizeof (dw_separate_line_info_entry));
+ memset (separate_line_info_table
+ + separate_line_info_table_in_use,
+ 0,
+ (LINE_INFO_TABLE_INCREMENT
+ * sizeof (dw_separate_line_info_entry)));
}
/* Add the new entry at the end of the line_info_table. */
@@ -12353,7 +12575,7 @@ dwarf2out_source_line (line, filename)
{
dw_line_info_ref line_info;
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, LINE_CODE_LABEL,
+ (*targetm.asm_out.internal_label) (asm_out_file, LINE_CODE_LABEL,
line_info_table_in_use);
/* Expand the line info table if necessary. */
@@ -12361,10 +12583,11 @@ dwarf2out_source_line (line, filename)
{
line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
line_info_table
- = (dw_line_info_ref)
- xrealloc (line_info_table,
- (line_info_table_allocated
- * sizeof (dw_line_info_entry)));
+ = ggc_realloc (line_info_table,
+ (line_info_table_allocated
+ * sizeof (dw_line_info_entry)));
+ memset (line_info_table + line_info_table_in_use, 0,
+ LINE_INFO_TABLE_INCREMENT * sizeof (dw_line_info_entry));
}
/* Add the new entry at the end of the line_info_table. */
@@ -12378,11 +12601,9 @@ dwarf2out_source_line (line, filename)
/* Record the beginning of a new source file. */
static void
-dwarf2out_start_source_file (lineno, filename)
- unsigned int lineno;
- const char *filename;
+dwarf2out_start_source_file (unsigned int lineno, const char *filename)
{
- if (flag_eliminate_dwarf2_dups && !is_main_source)
+ if (flag_eliminate_dwarf2_dups)
{
/* Record the beginning of the file for break_out_includes. */
dw_die_ref bincl_die;
@@ -12391,14 +12612,13 @@ dwarf2out_start_source_file (lineno, filename)
add_AT_string (bincl_die, DW_AT_name, filename);
}
- is_main_source = 0;
-
if (debug_info_level >= DINFO_LEVEL_VERBOSE)
{
named_section_flags (DEBUG_MACINFO_SECTION, SECTION_DEBUG);
dw2_asm_output_data (1, DW_MACINFO_start_file, "Start new file");
dw2_asm_output_data_uleb128 (lineno, "Included from line number %d",
lineno);
+ maybe_emit_file (lookup_filename (filename));
dw2_asm_output_data_uleb128 (lookup_filename (filename),
"Filename we just started");
}
@@ -12407,8 +12627,7 @@ dwarf2out_start_source_file (lineno, filename)
/* Record the end of a source file. */
static void
-dwarf2out_end_source_file (lineno)
- unsigned int lineno ATTRIBUTE_UNUSED;
+dwarf2out_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED)
{
if (flag_eliminate_dwarf2_dups)
/* Record the end of the file for break_out_includes. */
@@ -12426,9 +12645,8 @@ dwarf2out_end_source_file (lineno)
initial whitespace, #, whitespace, directive-name, whitespace part. */
static void
-dwarf2out_define (lineno, buffer)
- unsigned lineno ATTRIBUTE_UNUSED;
- const char *buffer ATTRIBUTE_UNUSED;
+dwarf2out_define (unsigned int lineno ATTRIBUTE_UNUSED,
+ const char *buffer ATTRIBUTE_UNUSED)
{
if (debug_info_level >= DINFO_LEVEL_VERBOSE)
{
@@ -12444,9 +12662,8 @@ dwarf2out_define (lineno, buffer)
initial whitespace, #, whitespace, directive-name, whitespace part. */
static void
-dwarf2out_undef (lineno, buffer)
- unsigned lineno ATTRIBUTE_UNUSED;
- const char *buffer ATTRIBUTE_UNUSED;
+dwarf2out_undef (unsigned int lineno ATTRIBUTE_UNUSED,
+ const char *buffer ATTRIBUTE_UNUSED)
{
if (debug_info_level >= DINFO_LEVEL_VERBOSE)
{
@@ -12460,22 +12677,13 @@ dwarf2out_undef (lineno, buffer)
/* Set up for Dwarf output at the start of compilation. */
static void
-dwarf2out_init (main_input_filename)
- const char *main_input_filename;
+dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
{
init_file_table ();
- /* Remember the name of the primary input file. */
- primary_filename = main_input_filename;
-
- /* Add it to the file table first, under the assumption that we'll
- be emitting line number data for it first, which avoids having
- to add an initial DW_LNS_set_file. */
- lookup_filename (main_input_filename);
-
/* Allocate the initial hunk of the decl_die_table. */
- decl_die_table
- = (dw_die_ref *) xcalloc (DECL_DIE_TABLE_INCREMENT, sizeof (dw_die_ref));
+ decl_die_table = ggc_alloc_cleared (DECL_DIE_TABLE_INCREMENT
+ * sizeof (dw_die_ref));
decl_die_table_allocated = DECL_DIE_TABLE_INCREMENT;
decl_die_table_in_use = 0;
@@ -12483,17 +12691,15 @@ dwarf2out_init (main_input_filename)
VARRAY_TREE_INIT (decl_scope_table, 256, "decl_scope_table");
/* Allocate the initial hunk of the abbrev_die_table. */
- abbrev_die_table
- = (dw_die_ref *) xcalloc (ABBREV_DIE_TABLE_INCREMENT,
- sizeof (dw_die_ref));
+ abbrev_die_table = ggc_alloc_cleared (ABBREV_DIE_TABLE_INCREMENT
+ * sizeof (dw_die_ref));
abbrev_die_table_allocated = ABBREV_DIE_TABLE_INCREMENT;
/* Zero-th entry is allocated, but unused */
abbrev_die_table_in_use = 1;
/* Allocate the initial hunk of the line_info_table. */
- line_info_table
- = (dw_line_info_ref) xcalloc (LINE_INFO_TABLE_INCREMENT,
- sizeof (dw_line_info_entry));
+ line_info_table = ggc_alloc_cleared (LINE_INFO_TABLE_INCREMENT
+ * sizeof (dw_line_info_entry));
line_info_table_allocated = LINE_INFO_TABLE_INCREMENT;
/* Zero-th entry is allocated, but unused */
@@ -12503,16 +12709,14 @@ dwarf2out_init (main_input_filename)
value given in the DW_AT_name attribute of the DW_TAG_compile_unit DIE
will (typically) be a relative pathname and that this pathname should be
taken as being relative to the directory from which the compiler was
- invoked when the given (base) source file was compiled. */
- comp_unit_die = gen_compile_unit_die (main_input_filename);
- is_main_source = 1;
+ invoked when the given (base) source file was compiled. We will fill
+ in this value in dwarf2out_finish. */
+ comp_unit_die = gen_compile_unit_die (NULL);
VARRAY_TREE_INIT (incomplete_types, 64, "incomplete_types");
VARRAY_RTX_INIT (used_rtx_varray, 32, "used_rtx_varray");
- ggc_add_root (&limbo_die_list, 1, 1, mark_limbo_die_list);
-
ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label,
DEBUG_ABBREV_SECTION_LABEL, 0);
@@ -12549,54 +12753,255 @@ dwarf2out_init (main_input_filename)
}
}
-/* Allocate a string in .debug_str hash table. */
-
-static hashnode
-indirect_string_alloc (tab)
- hash_table *tab ATTRIBUTE_UNUSED;
-{
- struct indirect_string_node *node;
-
- node = xmalloc (sizeof (struct indirect_string_node));
- node->refcount = 0;
- node->form = 0;
- node->label = NULL;
-
- return (hashnode) node;
-}
-
/* A helper function for dwarf2out_finish called through
ht_forall. Emit one queued .debug_str string. */
static int
-output_indirect_string (pfile, h, v)
- struct cpp_reader *pfile ATTRIBUTE_UNUSED;
- hashnode h;
- const PTR v ATTRIBUTE_UNUSED;
+output_indirect_string (void **h, void *v ATTRIBUTE_UNUSED)
{
- struct indirect_string_node *node = (struct indirect_string_node *) h;
+ struct indirect_string_node *node = (struct indirect_string_node *) *h;
if (node->form == DW_FORM_strp)
{
named_section_flags (DEBUG_STR_SECTION, DEBUG_STR_SECTION_FLAGS);
ASM_OUTPUT_LABEL (asm_out_file, node->label);
- assemble_string ((const char *) HT_STR (&node->id),
- HT_LEN (&node->id) + 1);
+ assemble_string (node->str, strlen (node->str) + 1);
}
return 1;
}
+
+
+/* Clear the marks for a die and its children.
+ Be cool if the mark isn't set. */
+
+static void
+prune_unmark_dies (dw_die_ref die)
+{
+ dw_die_ref c;
+ die->die_mark = 0;
+ for (c = die->die_child; c; c = c->die_sib)
+ prune_unmark_dies (c);
+}
+
+
+/* Given DIE that we're marking as used, find any other dies
+ it references as attributes and mark them as used. */
+
+static void
+prune_unused_types_walk_attribs (dw_die_ref die)
+{
+ dw_attr_ref a;
+
+ for (a = die->die_attr; a != NULL; a = a->dw_attr_next)
+ {
+ if (a->dw_attr_val.val_class == dw_val_class_die_ref)
+ {
+ /* A reference to another DIE.
+ Make sure that it will get emitted. */
+ prune_unused_types_mark (a->dw_attr_val.v.val_die_ref.die, 1);
+ }
+ else if (a->dw_attr == DW_AT_decl_file)
+ {
+ /* A reference to a file. Make sure the file name is emitted. */
+ a->dw_attr_val.v.val_unsigned =
+ maybe_emit_file (a->dw_attr_val.v.val_unsigned);
+ }
+ }
+}
+
+
+/* Mark DIE as being used. If DOKIDS is true, then walk down
+ to DIE's children. */
+
+static void
+prune_unused_types_mark (dw_die_ref die, int dokids)
+{
+ dw_die_ref c;
+
+ if (die->die_mark == 0)
+ {
+ /* We haven't done this node yet. Mark it as used. */
+ die->die_mark = 1;
+
+ /* We also have to mark its parents as used.
+ (But we don't want to mark our parents' kids due to this.) */
+ if (die->die_parent)
+ prune_unused_types_mark (die->die_parent, 0);
+
+ /* Mark any referenced nodes. */
+ prune_unused_types_walk_attribs (die);
+
+ /* If this node is a specification,
+ also mark the definition, if it exists. */
+ if (get_AT_flag (die, DW_AT_declaration) && die->die_definition)
+ prune_unused_types_mark (die->die_definition, 1);
+ }
+
+ if (dokids && die->die_mark != 2)
+ {
+ /* We need to walk the children, but haven't done so yet.
+ Remember that we've walked the kids. */
+ die->die_mark = 2;
+
+ /* Walk them. */
+ for (c = die->die_child; c; c = c->die_sib)
+ {
+ /* If this is an array type, we need to make sure our
+ kids get marked, even if they're types. */
+ if (die->die_tag == DW_TAG_array_type)
+ prune_unused_types_mark (c, 1);
+ else
+ prune_unused_types_walk (c);
+ }
+ }
+}
+
+
+/* Walk the tree DIE and mark types that we actually use. */
+
+static void
+prune_unused_types_walk (dw_die_ref die)
+{
+ dw_die_ref c;
+
+ /* Don't do anything if this node is already marked. */
+ if (die->die_mark)
+ return;
+
+ switch (die->die_tag) {
+ case DW_TAG_const_type:
+ case DW_TAG_packed_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_volatile_type:
+ case DW_TAG_typedef:
+ case DW_TAG_array_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_class_type:
+ case DW_TAG_friend:
+ case DW_TAG_variant_part:
+ case DW_TAG_enumeration_type:
+ case DW_TAG_subroutine_type:
+ case DW_TAG_string_type:
+ case DW_TAG_set_type:
+ case DW_TAG_subrange_type:
+ case DW_TAG_ptr_to_member_type:
+ case DW_TAG_file_type:
+ /* It's a type node --- don't mark it. */
+ return;
+
+ default:
+ /* Mark everything else. */
+ break;
+ }
+
+ die->die_mark = 1;
+
+ /* Now, mark any dies referenced from here. */
+ prune_unused_types_walk_attribs (die);
+
+ /* Mark children. */
+ for (c = die->die_child; c; c = c->die_sib)
+ prune_unused_types_walk (c);
+}
+
+
+/* Remove from the tree DIE any dies that aren't marked. */
+
+static void
+prune_unused_types_prune (dw_die_ref die)
+{
+ dw_die_ref c, p, n;
+ if (!die->die_mark)
+ abort();
+
+ p = NULL;
+ for (c = die->die_child; c; c = n)
+ {
+ n = c->die_sib;
+ if (c->die_mark)
+ {
+ prune_unused_types_prune (c);
+ p = c;
+ }
+ else
+ {
+ if (p)
+ p->die_sib = n;
+ else
+ die->die_child = n;
+ free_die (c);
+ }
+ }
+}
+
+
+/* Remove dies representing declarations that we never use. */
+
+static void
+prune_unused_types (void)
+{
+ unsigned int i;
+ limbo_die_node *node;
+
+ /* Clear all the marks. */
+ prune_unmark_dies (comp_unit_die);
+ for (node = limbo_die_list; node; node = node->next)
+ prune_unmark_dies (node->die);
+
+ /* Set the mark on nodes that are actually used. */
+ prune_unused_types_walk (comp_unit_die);
+ for (node = limbo_die_list; node; node = node->next)
+ prune_unused_types_walk (node->die);
+
+ /* Also set the mark on nodes referenced from the
+ pubname_table or arange_table. */
+ for (i = 0; i < pubname_table_in_use; i++)
+ prune_unused_types_mark (pubname_table[i].die, 1);
+ for (i = 0; i < arange_table_in_use; i++)
+ prune_unused_types_mark (arange_table[i], 1);
+
+ /* Get rid of nodes that aren't marked. */
+ prune_unused_types_prune (comp_unit_die);
+ for (node = limbo_die_list; node; node = node->next)
+ prune_unused_types_prune (node->die);
+
+ /* Leave the marks clear. */
+ prune_unmark_dies (comp_unit_die);
+ for (node = limbo_die_list; node; node = node->next)
+ prune_unmark_dies (node->die);
+}
+
/* Output stuff that dwarf requires at the end of every file,
and generate the DWARF-2 debugging info. */
static void
-dwarf2out_finish (input_filename)
- const char *input_filename ATTRIBUTE_UNUSED;
+dwarf2out_finish (const char *filename)
{
limbo_die_node *node, *next_node;
dw_die_ref die = 0;
+ /* Add the name for the main input file now. We delayed this from
+ dwarf2out_init to avoid complications with PCH. */
+ add_name_attribute (comp_unit_die, filename);
+ if (filename[0] != DIR_SEPARATOR)
+ add_comp_dir_attribute (comp_unit_die);
+ else if (get_AT (comp_unit_die, DW_AT_comp_dir) == NULL)
+ {
+ size_t i;
+ for (i = 1; i < VARRAY_ACTIVE_SIZE (file_table); i++)
+ if (VARRAY_CHAR_PTR (file_table, i)[0] != DIR_SEPARATOR
+ /* Don't add cwd for <built-in>. */
+ && VARRAY_CHAR_PTR (file_table, i)[0] != '<')
+ {
+ add_comp_dir_attribute (comp_unit_die);
+ break;
+ }
+ }
+
/* Traverse the limbo die list, and add parent/child links. The only
dies without parents that should be here are concrete instances of
inline functions, and the comp_unit_die. We can ignore the comp_unit_die.
@@ -12648,8 +13053,6 @@ dwarf2out_finish (input_filename)
else
abort ();
}
-
- free (node);
}
limbo_die_list = NULL;
@@ -12662,6 +13065,9 @@ dwarf2out_finish (input_filename)
we'll see the end of an include file before the beginning. */
reverse_all_dies (comp_unit_die);
+ if (flag_eliminate_unused_debug_types)
+ prune_unused_types ();
+
/* Generate separate CUs for each of the include files we've seen.
They will go into limbo_die_list. */
if (flag_eliminate_dwarf2_dups)
@@ -12675,7 +13081,7 @@ dwarf2out_finish (input_filename)
/* Output a terminator label for the .text section. */
text_section ();
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, TEXT_END_LABEL, 0);
+ (*targetm.asm_out.internal_label) (asm_out_file, TEXT_END_LABEL, 0);
/* Output the source line correspondence table. We must do this
even if there is no line information. Otherwise, on an empty
@@ -12765,7 +13171,7 @@ dwarf2out_finish (input_filename)
/* If we emitted any DW_FORM_strp form attribute, output the string
table too. */
if (debug_str_hash)
- ht_forall (debug_str_hash, output_indirect_string, NULL);
+ htab_traverse (debug_str_hash, output_indirect_string, NULL);
}
#else
diff --git a/contrib/gcc/dwarf2out.h b/contrib/gcc/dwarf2out.h
index 63cedeadddc8..e6bf532ff086 100644
--- a/contrib/gcc/dwarf2out.h
+++ b/contrib/gcc/dwarf2out.h
@@ -1,5 +1,6 @@
/* dwarf2out.h - Various declarations for functions found in dwarf2out.c
- Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -18,11 +19,11 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-extern void dwarf2out_decl PARAMS ((tree));
-extern void dwarf2out_frame_debug PARAMS ((rtx));
+extern void dwarf2out_decl (tree);
+extern void dwarf2out_frame_debug (rtx);
-extern void debug_dwarf PARAMS ((void));
+extern void debug_dwarf (void);
struct die_struct;
-extern void debug_dwarf_die PARAMS ((struct die_struct *));
-extern void dwarf2out_set_demangle_name_func PARAMS ((const char *(*) (const char *)));
-extern void dwarf2out_add_library_unit_info PARAMS ((const char *, const char *));
+extern void debug_dwarf_die (struct die_struct *);
+extern void dwarf2out_set_demangle_name_func (const char *(*) (const char *));
+extern void dwarf2out_add_library_unit_info (const char *, const char *);
diff --git a/contrib/gcc/emit-rtl.c b/contrib/gcc/emit-rtl.c
index 172a82d3b4b1..f6e44f9c27d5 100644
--- a/contrib/gcc/emit-rtl.c
+++ b/contrib/gcc/emit-rtl.c
@@ -1,6 +1,6 @@
-/* Emit RTL for the GNU C-Compiler expander.
+/* Emit RTL for the GCC expander.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -37,6 +37,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "tree.h"
@@ -67,7 +69,7 @@ enum machine_mode ptr_mode; /* Mode whose width is POINTER_SIZE. */
/* This is *not* reset after each function. It gives each CODE_LABEL
in the entire compilation a unique label number. */
-static int label_num = 1;
+static GTY(()) int label_num = 1;
/* Highest label number in current function.
Zero means use the value of label_num instead.
@@ -75,7 +77,7 @@ static int label_num = 1;
static int last_label_num;
-/* Value label_num had when set_new_first_and_last_label_number was called.
+/* Value label_num had when set_new_last_label_num was called.
If label_num has not changed since then, last_label_num is valid. */
static int base_label_num;
@@ -108,7 +110,14 @@ rtx const_true_rtx;
REAL_VALUE_TYPE dconst0;
REAL_VALUE_TYPE dconst1;
REAL_VALUE_TYPE dconst2;
+REAL_VALUE_TYPE dconst3;
+REAL_VALUE_TYPE dconst10;
REAL_VALUE_TYPE dconstm1;
+REAL_VALUE_TYPE dconstm2;
+REAL_VALUE_TYPE dconsthalf;
+REAL_VALUE_TYPE dconstthird;
+REAL_VALUE_TYPE dconstpi;
+REAL_VALUE_TYPE dconste;
/* All references to the following fixed hard registers go through
these unique rtl objects. On machines where the frame-pointer and
@@ -128,8 +137,6 @@ REAL_VALUE_TYPE dconstm1;
In an inline procedure, the stack and frame pointer rtxs may not be
used for anything else. */
-rtx struct_value_rtx; /* (REG:Pmode STRUCT_VALUE_REGNUM) */
-rtx struct_value_incoming_rtx; /* (REG:Pmode STRUCT_VALUE_INCOMING_REGNUM) */
rtx static_chain_rtx; /* (REG:Pmode STATIC_CHAIN_REGNUM) */
rtx static_chain_incoming_rtx; /* (REG:Pmode STATIC_CHAIN_INCOMING_REGNUM) */
rtx pic_offset_table_rtx; /* (REG:Pmode PIC_OFFSET_TABLE_REGNUM) */
@@ -155,6 +162,10 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
static GTY ((if_marked ("ggc_marked_p"), param_is (struct mem_attrs)))
htab_t mem_attrs_htab;
+/* A hash table storing register attribute structures. */
+static GTY ((if_marked ("ggc_marked_p"), param_is (struct reg_attrs)))
+ htab_t reg_attrs_htab;
+
/* A hash table storing all CONST_DOUBLEs. */
static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
htab_t const_double_htab;
@@ -162,34 +173,32 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
#define first_insn (cfun->emit->x_first_insn)
#define last_insn (cfun->emit->x_last_insn)
#define cur_insn_uid (cfun->emit->x_cur_insn_uid)
-#define last_linenum (cfun->emit->x_last_linenum)
-#define last_filename (cfun->emit->x_last_filename)
+#define last_location (cfun->emit->x_last_location)
#define first_label_num (cfun->emit->x_first_label_num)
-static rtx make_jump_insn_raw PARAMS ((rtx));
-static rtx make_call_insn_raw PARAMS ((rtx));
-static rtx find_line_note PARAMS ((rtx));
-static rtx change_address_1 PARAMS ((rtx, enum machine_mode, rtx,
- int));
-static void unshare_all_rtl_1 PARAMS ((rtx));
-static void unshare_all_decls PARAMS ((tree));
-static void reset_used_decls PARAMS ((tree));
-static void mark_label_nuses PARAMS ((rtx));
-static hashval_t const_int_htab_hash PARAMS ((const void *));
-static int const_int_htab_eq PARAMS ((const void *,
- const void *));
-static hashval_t const_double_htab_hash PARAMS ((const void *));
-static int const_double_htab_eq PARAMS ((const void *,
- const void *));
-static rtx lookup_const_double PARAMS ((rtx));
-static hashval_t mem_attrs_htab_hash PARAMS ((const void *));
-static int mem_attrs_htab_eq PARAMS ((const void *,
- const void *));
-static mem_attrs *get_mem_attrs PARAMS ((HOST_WIDE_INT, tree, rtx,
- rtx, unsigned int,
- enum machine_mode));
-static tree component_ref_for_mem_expr PARAMS ((tree));
-static rtx gen_const_vector_0 PARAMS ((enum machine_mode));
+static rtx make_jump_insn_raw (rtx);
+static rtx make_call_insn_raw (rtx);
+static rtx find_line_note (rtx);
+static rtx change_address_1 (rtx, enum machine_mode, rtx, int);
+static void unshare_all_decls (tree);
+static void reset_used_decls (tree);
+static void mark_label_nuses (rtx);
+static hashval_t const_int_htab_hash (const void *);
+static int const_int_htab_eq (const void *, const void *);
+static hashval_t const_double_htab_hash (const void *);
+static int const_double_htab_eq (const void *, const void *);
+static rtx lookup_const_double (rtx);
+static hashval_t mem_attrs_htab_hash (const void *);
+static int mem_attrs_htab_eq (const void *, const void *);
+static mem_attrs *get_mem_attrs (HOST_WIDE_INT, tree, rtx, rtx, unsigned int,
+ enum machine_mode);
+static hashval_t reg_attrs_htab_hash (const void *);
+static int reg_attrs_htab_eq (const void *, const void *);
+static reg_attrs *get_reg_attrs (tree, int);
+static tree component_ref_for_mem_expr (tree);
+static rtx gen_const_vector_0 (enum machine_mode);
+static rtx gen_complex_constant_part (enum machine_mode, rtx, int);
+static void copy_rtx_if_shared_1 (rtx *orig);
/* Probability of the conditional branch currently proceeded by try_split.
Set to -1 otherwise. */
@@ -198,10 +207,9 @@ int split_branch_probability = -1;
/* Returns a hash code for X (which is a really a CONST_INT). */
static hashval_t
-const_int_htab_hash (x)
- const void *x;
+const_int_htab_hash (const void *x)
{
- return (hashval_t) INTVAL ((struct rtx_def *) x);
+ return (hashval_t) INTVAL ((rtx) x);
}
/* Returns nonzero if the value represented by X (which is really a
@@ -209,17 +217,14 @@ const_int_htab_hash (x)
HOST_WIDE_INT *). */
static int
-const_int_htab_eq (x, y)
- const void *x;
- const void *y;
+const_int_htab_eq (const void *x, const void *y)
{
return (INTVAL ((rtx) x) == *((const HOST_WIDE_INT *) y));
}
/* Returns a hash code for X (which is really a CONST_DOUBLE). */
static hashval_t
-const_double_htab_hash (x)
- const void *x;
+const_double_htab_hash (const void *x)
{
rtx value = (rtx) x;
hashval_t h;
@@ -227,16 +232,18 @@ const_double_htab_hash (x)
if (GET_MODE (value) == VOIDmode)
h = CONST_DOUBLE_LOW (value) ^ CONST_DOUBLE_HIGH (value);
else
- h = real_hash (CONST_DOUBLE_REAL_VALUE (value));
+ {
+ h = real_hash (CONST_DOUBLE_REAL_VALUE (value));
+ /* MODE is used in the comparison, so it should be in the hash. */
+ h ^= GET_MODE (value);
+ }
return h;
}
/* Returns nonzero if the value represented by X (really a ...)
is the same as that represented by Y (really a ...) */
static int
-const_double_htab_eq (x, y)
- const void *x;
- const void *y;
+const_double_htab_eq (const void *x, const void *y)
{
rtx a = (rtx)x, b = (rtx)y;
@@ -253,8 +260,7 @@ const_double_htab_eq (x, y)
/* Returns a hash code for X (which is a really a mem_attrs *). */
static hashval_t
-mem_attrs_htab_hash (x)
- const void *x;
+mem_attrs_htab_hash (const void *x)
{
mem_attrs *p = (mem_attrs *) x;
@@ -269,9 +275,7 @@ mem_attrs_htab_hash (x)
mem_attrs *). */
static int
-mem_attrs_htab_eq (x, y)
- const void *x;
- const void *y;
+mem_attrs_htab_eq (const void *x, const void *y)
{
mem_attrs *p = (mem_attrs *) x;
mem_attrs *q = (mem_attrs *) y;
@@ -285,24 +289,20 @@ mem_attrs_htab_eq (x, y)
MEM of mode MODE. */
static mem_attrs *
-get_mem_attrs (alias, expr, offset, size, align, mode)
- HOST_WIDE_INT alias;
- tree expr;
- rtx offset;
- rtx size;
- unsigned int align;
- enum machine_mode mode;
+get_mem_attrs (HOST_WIDE_INT alias, tree expr, rtx offset, rtx size,
+ unsigned int align, enum machine_mode mode)
{
mem_attrs attrs;
void **slot;
- /* If everything is the default, we can just return zero. */
+ /* If everything is the default, we can just return zero.
+ This must match what the corresponding MEM_* macros return when the
+ field is not present. */
if (alias == 0 && expr == 0 && offset == 0
&& (size == 0
|| (mode != BLKmode && GET_MODE_SIZE (mode) == INTVAL (size)))
- && (align == BITS_PER_UNIT
- || (STRICT_ALIGNMENT
- && mode != BLKmode && align == GET_MODE_ALIGNMENT (mode))))
+ && (STRICT_ALIGNMENT && mode != BLKmode
+ ? align == GET_MODE_ALIGNMENT (mode) : align == BITS_PER_UNIT))
return 0;
attrs.alias = alias;
@@ -321,14 +321,61 @@ get_mem_attrs (alias, expr, offset, size, align, mode)
return *slot;
}
+/* Returns a hash code for X (which is a really a reg_attrs *). */
+
+static hashval_t
+reg_attrs_htab_hash (const void *x)
+{
+ reg_attrs *p = (reg_attrs *) x;
+
+ return ((p->offset * 1000) ^ (long) p->decl);
+}
+
+/* Returns nonzero if the value represented by X (which is really a
+ reg_attrs *) is the same as that given by Y (which is also really a
+ reg_attrs *). */
+
+static int
+reg_attrs_htab_eq (const void *x, const void *y)
+{
+ reg_attrs *p = (reg_attrs *) x;
+ reg_attrs *q = (reg_attrs *) y;
+
+ return (p->decl == q->decl && p->offset == q->offset);
+}
+/* Allocate a new reg_attrs structure and insert it into the hash table if
+ one identical to it is not already in the table. We are doing this for
+ MEM of mode MODE. */
+
+static reg_attrs *
+get_reg_attrs (tree decl, int offset)
+{
+ reg_attrs attrs;
+ void **slot;
+
+ /* If everything is the default, we can just return zero. */
+ if (decl == 0 && offset == 0)
+ return 0;
+
+ attrs.decl = decl;
+ attrs.offset = offset;
+
+ slot = htab_find_slot (reg_attrs_htab, &attrs, INSERT);
+ if (*slot == 0)
+ {
+ *slot = ggc_alloc (sizeof (reg_attrs));
+ memcpy (*slot, &attrs, sizeof (reg_attrs));
+ }
+
+ return *slot;
+}
+
/* Generate a new REG rtx. Make sure ORIGINAL_REGNO is set properly, and
don't attempt to share with the various global pieces of rtl (such as
frame_pointer_rtx). */
rtx
-gen_raw_REG (mode, regno)
- enum machine_mode mode;
- int regno;
+gen_raw_REG (enum machine_mode mode, int regno)
{
rtx x = gen_rtx_raw_REG (mode, regno);
ORIGINAL_REGNO (x) = regno;
@@ -340,9 +387,7 @@ gen_raw_REG (mode, regno)
special_rtx in gengenrtl.c as well. */
rtx
-gen_rtx_CONST_INT (mode, arg)
- enum machine_mode mode ATTRIBUTE_UNUSED;
- HOST_WIDE_INT arg;
+gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg)
{
void **slot;
@@ -364,9 +409,7 @@ gen_rtx_CONST_INT (mode, arg)
}
rtx
-gen_int_mode (c, mode)
- HOST_WIDE_INT c;
- enum machine_mode mode;
+gen_int_mode (HOST_WIDE_INT c, enum machine_mode mode)
{
return GEN_INT (trunc_int_for_mode (c, mode));
}
@@ -379,8 +422,7 @@ gen_int_mode (c, mode)
hash table. If so, return its counterpart; otherwise add it
to the hash table and return it. */
static rtx
-lookup_const_double (real)
- rtx real;
+lookup_const_double (rtx real)
{
void **slot = htab_find_slot (const_double_htab, real, INSERT);
if (*slot == 0)
@@ -392,9 +434,7 @@ lookup_const_double (real)
/* Return a CONST_DOUBLE rtx for a floating-point value specified by
VALUE in mode MODE. */
rtx
-const_double_from_real_value (value, mode)
- REAL_VALUE_TYPE value;
- enum machine_mode mode;
+const_double_from_real_value (REAL_VALUE_TYPE value, enum machine_mode mode)
{
rtx real = rtx_alloc (CONST_DOUBLE);
PUT_MODE (real, mode);
@@ -410,9 +450,7 @@ const_double_from_real_value (value, mode)
REAL_VALUE_TYPE and use CONST_DOUBLE_FROM_REAL_VALUE. */
rtx
-immed_double_const (i0, i1, mode)
- HOST_WIDE_INT i0, i1;
- enum machine_mode mode;
+immed_double_const (HOST_WIDE_INT i0, HOST_WIDE_INT i1, enum machine_mode mode)
{
rtx value;
unsigned int i;
@@ -495,9 +533,7 @@ immed_double_const (i0, i1, mode)
}
rtx
-gen_rtx_REG (mode, regno)
- enum machine_mode mode;
- unsigned int regno;
+gen_rtx_REG (enum machine_mode mode, unsigned int regno)
{
/* In case the MD file explicitly references the frame pointer, have
all such references point to the same frame pointer. This is
@@ -531,7 +567,7 @@ gen_rtx_REG (mode, regno)
if (regno == RETURN_ADDRESS_POINTER_REGNUM)
return return_address_pointer_rtx;
#endif
- if (regno == PIC_OFFSET_TABLE_REGNUM
+ if (regno == (unsigned) PIC_OFFSET_TABLE_REGNUM
&& fixed_regs[PIC_OFFSET_TABLE_REGNUM])
return pic_offset_table_rtx;
if (regno == STACK_POINTER_REGNUM)
@@ -562,9 +598,7 @@ gen_rtx_REG (mode, regno)
}
rtx
-gen_rtx_MEM (mode, addr)
- enum machine_mode mode;
- rtx addr;
+gen_rtx_MEM (enum machine_mode mode, rtx addr)
{
rtx rt = gen_rtx_raw_MEM (mode, addr);
@@ -576,10 +610,7 @@ gen_rtx_MEM (mode, addr)
}
rtx
-gen_rtx_SUBREG (mode, reg, offset)
- enum machine_mode mode;
- rtx reg;
- int offset;
+gen_rtx_SUBREG (enum machine_mode mode, rtx reg, int offset)
{
/* This is the most common failure type.
Catch it early so we can see who does it. */
@@ -601,9 +632,7 @@ gen_rtx_SUBREG (mode, reg, offset)
is smaller than mode of REG, otherwise paradoxical SUBREG. */
rtx
-gen_lowpart_SUBREG (mode, reg)
- enum machine_mode mode;
- rtx reg;
+gen_lowpart_SUBREG (enum machine_mode mode, rtx reg)
{
enum machine_mode inmode;
@@ -642,15 +671,14 @@ gen_lowpart_SUBREG (mode, reg)
/*VARARGS2*/
rtx
-gen_rtx VPARAMS ((enum rtx_code code, enum machine_mode mode, ...))
+gen_rtx (enum rtx_code code, enum machine_mode mode, ...)
{
int i; /* Array indices... */
const char *fmt; /* Current rtx's format... */
rtx rt_val; /* RTX to return to caller... */
+ va_list p;
- VA_OPEN (p, mode);
- VA_FIXEDARG (p, enum rtx_code, code);
- VA_FIXEDARG (p, enum machine_mode, mode);
+ va_start (p, mode);
switch (code)
{
@@ -684,7 +712,8 @@ gen_rtx VPARAMS ((enum rtx_code code, enum machine_mode mode, ...))
{
switch (*fmt++)
{
- case '0': /* Unused field. */
+ case '0': /* Field with unknown use. Zero it. */
+ X0EXP (rt_val, i) = NULL_RTX;
break;
case 'i': /* An integer? */
@@ -723,7 +752,7 @@ gen_rtx VPARAMS ((enum rtx_code code, enum machine_mode mode, ...))
break;
}
- VA_CLOSE (p);
+ va_end (p);
return rt_val;
}
@@ -735,33 +764,31 @@ gen_rtx VPARAMS ((enum rtx_code code, enum machine_mode mode, ...))
/*VARARGS1*/
rtvec
-gen_rtvec VPARAMS ((int n, ...))
+gen_rtvec (int n, ...)
{
int i, save_n;
rtx *vector;
+ va_list p;
- VA_OPEN (p, n);
- VA_FIXEDARG (p, int, n);
+ va_start (p, n);
if (n == 0)
return NULL_RTVEC; /* Don't allocate an empty rtvec... */
- vector = (rtx *) alloca (n * sizeof (rtx));
+ vector = alloca (n * sizeof (rtx));
for (i = 0; i < n; i++)
vector[i] = va_arg (p, rtx);
/* The definition of VA_* in K&R C causes `n' to go out of scope. */
save_n = n;
- VA_CLOSE (p);
+ va_end (p);
return gen_rtvec_v (save_n, vector);
}
rtvec
-gen_rtvec_v (n, argp)
- int n;
- rtx *argp;
+gen_rtvec_v (int n, rtx *argp)
{
int i;
rtvec rt_val;
@@ -781,8 +808,7 @@ gen_rtvec_v (n, argp)
This pseudo is assigned the next sequential register number. */
rtx
-gen_reg_rtx (mode)
- enum machine_mode mode;
+gen_reg_rtx (enum machine_mode mode)
{
struct function *f = cfun;
rtx val;
@@ -809,7 +835,7 @@ gen_reg_rtx (mode)
return gen_rtx_CONCAT (mode, realpart, imagpart);
}
- /* Make sure regno_pointer_align, regno_decl, and regno_reg_rtx are large
+ /* Make sure regno_pointer_align, and regno_reg_rtx are large
enough to have an element for this pseudo reg number. */
if (reg_rtx_no == f->emit->regno_pointer_align_length)
@@ -817,22 +843,16 @@ gen_reg_rtx (mode)
int old_size = f->emit->regno_pointer_align_length;
char *new;
rtx *new1;
- tree *new2;
new = ggc_realloc (f->emit->regno_pointer_align, old_size * 2);
memset (new + old_size, 0, old_size);
f->emit->regno_pointer_align = (unsigned char *) new;
- new1 = (rtx *) ggc_realloc (f->emit->x_regno_reg_rtx,
- old_size * 2 * sizeof (rtx));
+ new1 = ggc_realloc (f->emit->x_regno_reg_rtx,
+ old_size * 2 * sizeof (rtx));
memset (new1 + old_size, 0, old_size * sizeof (rtx));
regno_reg_rtx = new1;
- new2 = (tree *) ggc_realloc (f->emit->regno_decl,
- old_size * 2 * sizeof (tree));
- memset (new2 + old_size, 0, old_size * sizeof (tree));
- f->emit->regno_decl = new2;
-
f->emit->regno_pointer_align_length = old_size * 2;
}
@@ -841,11 +861,90 @@ gen_reg_rtx (mode)
return val;
}
+/* Generate a register with same attributes as REG,
+ but offsetted by OFFSET. */
+
+rtx
+gen_rtx_REG_offset (rtx reg, enum machine_mode mode, unsigned int regno, int offset)
+{
+ rtx new = gen_rtx_REG (mode, regno);
+ REG_ATTRS (new) = get_reg_attrs (REG_EXPR (reg),
+ REG_OFFSET (reg) + offset);
+ return new;
+}
+
+/* Set the decl for MEM to DECL. */
+
+void
+set_reg_attrs_from_mem (rtx reg, rtx mem)
+{
+ if (MEM_OFFSET (mem) && GET_CODE (MEM_OFFSET (mem)) == CONST_INT)
+ REG_ATTRS (reg)
+ = get_reg_attrs (MEM_EXPR (mem), INTVAL (MEM_OFFSET (mem)));
+}
+
+/* Set the register attributes for registers contained in PARM_RTX.
+ Use needed values from memory attributes of MEM. */
+
+void
+set_reg_attrs_for_parm (rtx parm_rtx, rtx mem)
+{
+ if (GET_CODE (parm_rtx) == REG)
+ set_reg_attrs_from_mem (parm_rtx, mem);
+ else if (GET_CODE (parm_rtx) == PARALLEL)
+ {
+ /* Check for a NULL entry in the first slot, used to indicate that the
+ parameter goes both on the stack and in registers. */
+ int i = XEXP (XVECEXP (parm_rtx, 0, 0), 0) ? 0 : 1;
+ for (; i < XVECLEN (parm_rtx, 0); i++)
+ {
+ rtx x = XVECEXP (parm_rtx, 0, i);
+ if (GET_CODE (XEXP (x, 0)) == REG)
+ REG_ATTRS (XEXP (x, 0))
+ = get_reg_attrs (MEM_EXPR (mem),
+ INTVAL (XEXP (x, 1)));
+ }
+ }
+}
+
+/* Assign the RTX X to declaration T. */
+void
+set_decl_rtl (tree t, rtx x)
+{
+ DECL_CHECK (t)->decl.rtl = x;
+
+ if (!x)
+ return;
+ /* For register, we maintain the reverse information too. */
+ if (GET_CODE (x) == REG)
+ REG_ATTRS (x) = get_reg_attrs (t, 0);
+ else if (GET_CODE (x) == SUBREG)
+ REG_ATTRS (SUBREG_REG (x))
+ = get_reg_attrs (t, -SUBREG_BYTE (x));
+ if (GET_CODE (x) == CONCAT)
+ {
+ if (REG_P (XEXP (x, 0)))
+ REG_ATTRS (XEXP (x, 0)) = get_reg_attrs (t, 0);
+ if (REG_P (XEXP (x, 1)))
+ REG_ATTRS (XEXP (x, 1))
+ = get_reg_attrs (t, GET_MODE_UNIT_SIZE (GET_MODE (XEXP (x, 0))));
+ }
+ if (GET_CODE (x) == PARALLEL)
+ {
+ int i;
+ for (i = 0; i < XVECLEN (x, 0); i++)
+ {
+ rtx y = XVECEXP (x, 0, i);
+ if (REG_P (XEXP (y, 0)))
+ REG_ATTRS (XEXP (y, 0)) = get_reg_attrs (t, INTVAL (XEXP (y, 1)));
+ }
+ }
+}
+
/* Identify REG (which may be a CONCAT) as a user register. */
void
-mark_user_reg (reg)
- rtx reg;
+mark_user_reg (rtx reg)
{
if (GET_CODE (reg) == CONCAT)
{
@@ -862,9 +961,7 @@ mark_user_reg (reg)
as ALIGN, if nonzero. */
void
-mark_reg_pointer (reg, align)
- rtx reg;
- int align;
+mark_reg_pointer (rtx reg, int align)
{
if (! REG_POINTER (reg))
{
@@ -874,14 +971,14 @@ mark_reg_pointer (reg, align)
REGNO_POINTER_ALIGN (REGNO (reg)) = align;
}
else if (align && align < REGNO_POINTER_ALIGN (REGNO (reg)))
- /* We can no-longer be sure just how aligned this pointer is */
+ /* We can no-longer be sure just how aligned this pointer is. */
REGNO_POINTER_ALIGN (REGNO (reg)) = align;
}
/* Return 1 plus largest pseudo reg number used in the current function. */
int
-max_reg_num ()
+max_reg_num (void)
{
return reg_rtx_no;
}
@@ -889,7 +986,7 @@ max_reg_num ()
/* Return 1 + the largest label number used so far in the current function. */
int
-max_label_num ()
+max_label_num (void)
{
if (last_label_num && label_num == base_label_num)
return last_label_num;
@@ -899,7 +996,7 @@ max_label_num ()
/* Return first label number used in this function (if any were used). */
int
-get_first_label_num ()
+get_first_label_num (void)
{
return first_label_num;
}
@@ -907,9 +1004,7 @@ get_first_label_num ()
/* Return the final regno of X, which is a SUBREG of a hard
register. */
int
-subreg_hard_regno (x, check_mode)
- rtx x;
- int check_mode;
+subreg_hard_regno (rtx x, int check_mode)
{
enum machine_mode mode = GET_MODE (x);
unsigned int byte_offset, base_regno, final_regno;
@@ -927,7 +1022,7 @@ subreg_hard_regno (x, check_mode)
abort ();
#ifdef ENABLE_CHECKING
if (!subreg_offset_representable_p (REGNO (reg), GET_MODE (reg),
- SUBREG_BYTE (x), mode))
+ SUBREG_BYTE (x), mode))
abort ();
#endif
/* Catch non-congruent offsets too. */
@@ -952,29 +1047,39 @@ subreg_hard_regno (x, check_mode)
If this is not a case we can handle, return 0. */
rtx
-gen_lowpart_common (mode, x)
- enum machine_mode mode;
- rtx x;
+gen_lowpart_common (enum machine_mode mode, rtx x)
{
int msize = GET_MODE_SIZE (mode);
- int xsize = GET_MODE_SIZE (GET_MODE (x));
+ int xsize;
int offset = 0;
+ enum machine_mode innermode;
+
+ /* Unfortunately, this routine doesn't take a parameter for the mode of X,
+ so we have to make one up. Yuk. */
+ innermode = GET_MODE (x);
+ if (GET_CODE (x) == CONST_INT && msize <= HOST_BITS_PER_WIDE_INT)
+ innermode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
+ else if (innermode == VOIDmode)
+ innermode = mode_for_size (HOST_BITS_PER_WIDE_INT * 2, MODE_INT, 0);
+
+ xsize = GET_MODE_SIZE (innermode);
+
+ if (innermode == VOIDmode || innermode == BLKmode)
+ abort ();
- if (GET_MODE (x) == mode)
+ if (innermode == mode)
return x;
/* MODE must occupy no more words than the mode of X. */
- if (GET_MODE (x) != VOIDmode
- && ((msize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD
- > ((xsize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
+ if ((msize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD
+ > ((xsize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
return 0;
/* Don't allow generating paradoxical FLOAT_MODE subregs. */
- if (GET_MODE_CLASS (mode) == MODE_FLOAT
- && GET_MODE (x) != VOIDmode && msize > xsize)
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT && msize > xsize)
return 0;
- offset = subreg_lowpart_offset (mode, GET_MODE (x));
+ offset = subreg_lowpart_offset (mode, innermode);
if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
&& (GET_MODE_CLASS (mode) == MODE_INT
@@ -990,163 +1095,58 @@ gen_lowpart_common (mode, x)
if (GET_MODE (XEXP (x, 0)) == mode)
return XEXP (x, 0);
- else if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (XEXP (x, 0))))
+ else if (msize < GET_MODE_SIZE (GET_MODE (XEXP (x, 0))))
return gen_lowpart_common (mode, XEXP (x, 0));
- else if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x)))
+ else if (msize < xsize)
return gen_rtx_fmt_e (GET_CODE (x), mode, XEXP (x, 0));
}
else if (GET_CODE (x) == SUBREG || GET_CODE (x) == REG
- || GET_CODE (x) == CONCAT || GET_CODE (x) == CONST_VECTOR)
- return simplify_gen_subreg (mode, x, GET_MODE (x), offset);
- else if ((GET_MODE_CLASS (mode) == MODE_VECTOR_INT
- || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
- && GET_MODE (x) == VOIDmode)
- return simplify_gen_subreg (mode, x, int_mode_for_mode (mode), offset);
- /* If X is a CONST_INT or a CONST_DOUBLE, extract the appropriate bits
- from the low-order part of the constant. */
- else if ((GET_MODE_CLASS (mode) == MODE_INT
- || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
- && GET_MODE (x) == VOIDmode
- && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
- {
- /* If MODE is twice the host word size, X is already the desired
- representation. Otherwise, if MODE is wider than a word, we can't
- do this. If MODE is exactly a word, return just one CONST_INT. */
-
- if (GET_MODE_BITSIZE (mode) >= 2 * HOST_BITS_PER_WIDE_INT)
- return x;
- else if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
- return 0;
- else if (GET_MODE_BITSIZE (mode) == HOST_BITS_PER_WIDE_INT)
- return (GET_CODE (x) == CONST_INT ? x
- : GEN_INT (CONST_DOUBLE_LOW (x)));
- else
- {
- /* MODE must be narrower than HOST_BITS_PER_WIDE_INT. */
- HOST_WIDE_INT val = (GET_CODE (x) == CONST_INT ? INTVAL (x)
- : CONST_DOUBLE_LOW (x));
+ || GET_CODE (x) == CONCAT || GET_CODE (x) == CONST_VECTOR
+ || GET_CODE (x) == CONST_DOUBLE || GET_CODE (x) == CONST_INT)
+ return simplify_gen_subreg (mode, x, innermode, offset);
- /* Sign extend to HOST_WIDE_INT. */
- val = trunc_int_for_mode (val, mode);
-
- return (GET_CODE (x) == CONST_INT && INTVAL (x) == val ? x
- : GEN_INT (val));
- }
- }
-
- /* The floating-point emulator can handle all conversions between
- FP and integer operands. This simplifies reload because it
- doesn't have to deal with constructs like (subreg:DI
- (const_double:SF ...)) or (subreg:DF (const_int ...)). */
- /* Single-precision floats are always 32-bits and double-precision
- floats are always 64-bits. */
+ /* Otherwise, we can't do this. */
+ return 0;
+}
+
+/* Return the constant real or imaginary part (which has mode MODE)
+ of a complex value X. The IMAGPART_P argument determines whether
+ the real or complex component should be returned. This function
+ returns NULL_RTX if the component isn't a constant. */
- else if (GET_MODE_CLASS (mode) == MODE_FLOAT
- && GET_MODE_BITSIZE (mode) == 32
- && GET_CODE (x) == CONST_INT)
- {
- REAL_VALUE_TYPE r;
- long i = INTVAL (x);
+static rtx
+gen_complex_constant_part (enum machine_mode mode, rtx x, int imagpart_p)
+{
+ tree decl, part;
- real_from_target (&r, &i, mode);
- return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
- }
- else if (GET_MODE_CLASS (mode) == MODE_FLOAT
- && GET_MODE_BITSIZE (mode) == 64
- && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
- && GET_MODE (x) == VOIDmode)
+ if (GET_CODE (x) == MEM
+ && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
{
- REAL_VALUE_TYPE r;
- HOST_WIDE_INT low, high;
- long i[2];
-
- if (GET_CODE (x) == CONST_INT)
- {
- low = INTVAL (x);
- high = low >> (HOST_BITS_PER_WIDE_INT - 1);
- }
- else
+ decl = SYMBOL_REF_DECL (XEXP (x, 0));
+ if (decl != NULL_TREE && TREE_CODE (decl) == COMPLEX_CST)
{
- low = CONST_DOUBLE_LOW (x);
- high = CONST_DOUBLE_HIGH (x);
+ part = imagpart_p ? TREE_IMAGPART (decl) : TREE_REALPART (decl);
+ if (TREE_CODE (part) == REAL_CST
+ || TREE_CODE (part) == INTEGER_CST)
+ return expand_expr (part, NULL_RTX, mode, 0);
}
-
- if (HOST_BITS_PER_WIDE_INT > 32)
- high = low >> 31 >> 1;
-
- /* REAL_VALUE_TARGET_DOUBLE takes the addressing order of the
- target machine. */
- if (WORDS_BIG_ENDIAN)
- i[0] = high, i[1] = low;
- else
- i[0] = low, i[1] = high;
-
- real_from_target (&r, i, mode);
- return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
}
- else if ((GET_MODE_CLASS (mode) == MODE_INT
- || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
- && GET_CODE (x) == CONST_DOUBLE
- && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
- {
- REAL_VALUE_TYPE r;
- long i[4]; /* Only the low 32 bits of each 'long' are used. */
- int endian = WORDS_BIG_ENDIAN ? 1 : 0;
-
- /* Convert 'r' into an array of four 32-bit words in target word
- order. */
- REAL_VALUE_FROM_CONST_DOUBLE (r, x);
- switch (GET_MODE_BITSIZE (GET_MODE (x)))
- {
- case 32:
- REAL_VALUE_TO_TARGET_SINGLE (r, i[3 * endian]);
- i[1] = 0;
- i[2] = 0;
- i[3 - 3 * endian] = 0;
- break;
- case 64:
- REAL_VALUE_TO_TARGET_DOUBLE (r, i + 2 * endian);
- i[2 - 2 * endian] = 0;
- i[3 - 2 * endian] = 0;
- break;
- case 96:
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, i + endian);
- i[3 - 3 * endian] = 0;
- break;
- case 128:
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, i);
- break;
- default:
- abort ();
- }
- /* Now, pack the 32-bit elements of the array into a CONST_DOUBLE
- and return it. */
-#if HOST_BITS_PER_WIDE_INT == 32
- return immed_double_const (i[3 * endian], i[1 + endian], mode);
-#else
- if (HOST_BITS_PER_WIDE_INT != 64)
- abort ();
-
- return immed_double_const ((((unsigned long) i[3 * endian])
- | ((HOST_WIDE_INT) i[1 + endian] << 32)),
- (((unsigned long) i[2 - endian])
- | ((HOST_WIDE_INT) i[3 - 3 * endian] << 32)),
- mode);
-#endif
- }
-
- /* Otherwise, we can't do this. */
- return 0;
+ return NULL_RTX;
}
-
+
/* Return the real part (which has mode MODE) of a complex value X.
This always comes at the low address in memory. */
rtx
-gen_realpart (mode, x)
- enum machine_mode mode;
- rtx x;
+gen_realpart (enum machine_mode mode, rtx x)
{
+ rtx part;
+
+ /* Handle complex constants. */
+ part = gen_complex_constant_part (mode, x, 0);
+ if (part != NULL_RTX)
+ return part;
+
if (WORDS_BIG_ENDIAN
&& GET_MODE_BITSIZE (mode) < BITS_PER_WORD
&& REG_P (x)
@@ -1163,10 +1163,15 @@ gen_realpart (mode, x)
This always comes at the high address in memory. */
rtx
-gen_imagpart (mode, x)
- enum machine_mode mode;
- rtx x;
+gen_imagpart (enum machine_mode mode, rtx x)
{
+ rtx part;
+
+ /* Handle complex constants. */
+ part = gen_complex_constant_part (mode, x, 1);
+ if (part != NULL_RTX)
+ return part;
+
if (WORDS_BIG_ENDIAN)
return gen_lowpart (mode, x);
else if (! WORDS_BIG_ENDIAN
@@ -1185,14 +1190,13 @@ gen_imagpart (mode, x)
regardless of WORDS_BIG_ENDIAN. */
int
-subreg_realpart_p (x)
- rtx x;
+subreg_realpart_p (rtx x)
{
if (GET_CODE (x) != SUBREG)
abort ();
return ((unsigned int) SUBREG_BYTE (x)
- < GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (x))));
+ < (unsigned int) GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (x))));
}
/* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a value,
@@ -1203,9 +1207,7 @@ subreg_realpart_p (x)
If X is a MEM whose address is a QUEUED, the value may be so also. */
rtx
-gen_lowpart (mode, x)
- enum machine_mode mode;
- rtx x;
+gen_lowpart (enum machine_mode mode, rtx x)
{
rtx result = gen_lowpart_common (mode, x);
@@ -1223,6 +1225,15 @@ gen_lowpart (mode, x)
{
/* The only additional case we can do is MEM. */
int offset = 0;
+
+ /* The following exposes the use of "x" to CSE. */
+ if (GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD
+ && SCALAR_INT_MODE_P (GET_MODE (x))
+ && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
+ GET_MODE_BITSIZE (GET_MODE (x)))
+ && ! no_new_pseudos)
+ return gen_lowpart (mode, force_reg (GET_MODE (x), x));
+
if (WORDS_BIG_ENDIAN)
offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
@@ -1245,9 +1256,7 @@ gen_lowpart (mode, x)
This is used to access the imaginary part of a complex number. */
rtx
-gen_highpart (mode, x)
- enum machine_mode mode;
- rtx x;
+gen_highpart (enum machine_mode mode, rtx x)
{
unsigned int msize = GET_MODE_SIZE (mode);
rtx result;
@@ -1255,7 +1264,7 @@ gen_highpart (mode, x)
/* This case loses if X is a subreg. To catch bugs early,
complain if an invalid MODE is used even in other cases. */
if (msize > UNITS_PER_WORD
- && msize != GET_MODE_UNIT_SIZE (GET_MODE (x)))
+ && msize != (unsigned int) GET_MODE_UNIT_SIZE (GET_MODE (x)))
abort ();
result = simplify_gen_subreg (mode, x, GET_MODE (x),
@@ -1272,12 +1281,10 @@ gen_highpart (mode, x)
return result;
}
-/* Like gen_highpart_mode, but accept mode of EXP operand in case EXP can
+/* Like gen_highpart, but accept mode of EXP operand in case EXP can
be VOIDmode constant. */
rtx
-gen_highpart_mode (outermode, innermode, exp)
- enum machine_mode outermode, innermode;
- rtx exp;
+gen_highpart_mode (enum machine_mode outermode, enum machine_mode innermode, rtx exp)
{
if (GET_MODE (exp) != VOIDmode)
{
@@ -1293,8 +1300,7 @@ gen_highpart_mode (outermode, innermode, exp)
of the value in mode INNERMODE stored in memory in target format. */
unsigned int
-subreg_lowpart_offset (outermode, innermode)
- enum machine_mode outermode, innermode;
+subreg_lowpart_offset (enum machine_mode outermode, enum machine_mode innermode)
{
unsigned int offset = 0;
int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
@@ -1313,8 +1319,7 @@ subreg_lowpart_offset (outermode, innermode)
/* Return offset in bytes to get OUTERMODE high part
of the value in mode INNERMODE stored in memory in target format. */
unsigned int
-subreg_highpart_offset (outermode, innermode)
- enum machine_mode outermode, innermode;
+subreg_highpart_offset (enum machine_mode outermode, enum machine_mode innermode)
{
unsigned int offset = 0;
int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
@@ -1338,8 +1343,7 @@ subreg_highpart_offset (outermode, innermode)
If X is not a SUBREG, always return 1 (it is its own low part!). */
int
-subreg_lowpart_p (x)
- rtx x;
+subreg_lowpart_p (rtx x)
{
if (GET_CODE (x) != SUBREG)
return 1;
@@ -1350,165 +1354,6 @@ subreg_lowpart_p (x)
== SUBREG_BYTE (x));
}
-
-/* Helper routine for all the constant cases of operand_subword.
- Some places invoke this directly. */
-
-rtx
-constant_subword (op, offset, mode)
- rtx op;
- int offset;
- enum machine_mode mode;
-{
- int size_ratio = HOST_BITS_PER_WIDE_INT / BITS_PER_WORD;
- HOST_WIDE_INT val;
-
- /* If OP is already an integer word, return it. */
- if (GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_SIZE (mode) == UNITS_PER_WORD)
- return op;
-
- /* The output is some bits, the width of the target machine's word.
- A wider-word host can surely hold them in a CONST_INT. A narrower-word
- host can't. */
- if (HOST_BITS_PER_WIDE_INT >= BITS_PER_WORD
- && GET_MODE_CLASS (mode) == MODE_FLOAT
- && GET_MODE_BITSIZE (mode) == 64
- && GET_CODE (op) == CONST_DOUBLE)
- {
- long k[2];
- REAL_VALUE_TYPE rv;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
- REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
-
- /* We handle 32-bit and >= 64-bit words here. Note that the order in
- which the words are written depends on the word endianness.
- ??? This is a potential portability problem and should
- be fixed at some point.
-
- We must exercise caution with the sign bit. By definition there
- are 32 significant bits in K; there may be more in a HOST_WIDE_INT.
- Consider a host with a 32-bit long and a 64-bit HOST_WIDE_INT.
- So we explicitly mask and sign-extend as necessary. */
- if (BITS_PER_WORD == 32)
- {
- val = k[offset];
- val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000;
- return GEN_INT (val);
- }
-#if HOST_BITS_PER_WIDE_INT >= 64
- else if (BITS_PER_WORD >= 64 && offset == 0)
- {
- val = k[! WORDS_BIG_ENDIAN];
- val = (((val & 0xffffffff) ^ 0x80000000) - 0x80000000) << 32;
- val |= (HOST_WIDE_INT) k[WORDS_BIG_ENDIAN] & 0xffffffff;
- return GEN_INT (val);
- }
-#endif
- else if (BITS_PER_WORD == 16)
- {
- val = k[offset >> 1];
- if ((offset & 1) == ! WORDS_BIG_ENDIAN)
- val >>= 16;
- val = ((val & 0xffff) ^ 0x8000) - 0x8000;
- return GEN_INT (val);
- }
- else
- abort ();
- }
- else if (HOST_BITS_PER_WIDE_INT >= BITS_PER_WORD
- && GET_MODE_CLASS (mode) == MODE_FLOAT
- && GET_MODE_BITSIZE (mode) > 64
- && GET_CODE (op) == CONST_DOUBLE)
- {
- long k[4];
- REAL_VALUE_TYPE rv;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
-
- if (BITS_PER_WORD == 32)
- {
- val = k[offset];
- val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000;
- return GEN_INT (val);
- }
-#if HOST_BITS_PER_WIDE_INT >= 64
- else if (BITS_PER_WORD >= 64 && offset <= 1)
- {
- val = k[offset * 2 + ! WORDS_BIG_ENDIAN];
- val = (((val & 0xffffffff) ^ 0x80000000) - 0x80000000) << 32;
- val |= (HOST_WIDE_INT) k[offset * 2 + WORDS_BIG_ENDIAN] & 0xffffffff;
- return GEN_INT (val);
- }
-#endif
- else
- abort ();
- }
-
- /* Single word float is a little harder, since single- and double-word
- values often do not have the same high-order bits. We have already
- verified that we want the only defined word of the single-word value. */
- if (GET_MODE_CLASS (mode) == MODE_FLOAT
- && GET_MODE_BITSIZE (mode) == 32
- && GET_CODE (op) == CONST_DOUBLE)
- {
- long l;
- REAL_VALUE_TYPE rv;
-
- REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
- REAL_VALUE_TO_TARGET_SINGLE (rv, l);
-
- /* Sign extend from known 32-bit value to HOST_WIDE_INT. */
- val = l;
- val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000;
-
- if (BITS_PER_WORD == 16)
- {
- if ((offset & 1) == ! WORDS_BIG_ENDIAN)
- val >>= 16;
- val = ((val & 0xffff) ^ 0x8000) - 0x8000;
- }
-
- return GEN_INT (val);
- }
-
- /* The only remaining cases that we can handle are integers.
- Convert to proper endianness now since these cases need it.
- At this point, offset == 0 means the low-order word.
-
- We do not want to handle the case when BITS_PER_WORD <= HOST_BITS_PER_INT
- in general. However, if OP is (const_int 0), we can just return
- it for any word. */
-
- if (op == const0_rtx)
- return op;
-
- if (GET_MODE_CLASS (mode) != MODE_INT
- || (GET_CODE (op) != CONST_INT && GET_CODE (op) != CONST_DOUBLE)
- || BITS_PER_WORD > HOST_BITS_PER_WIDE_INT)
- return 0;
-
- if (WORDS_BIG_ENDIAN)
- offset = GET_MODE_SIZE (mode) / UNITS_PER_WORD - 1 - offset;
-
- /* Find out which word on the host machine this value is in and get
- it from the constant. */
- val = (offset / size_ratio == 0
- ? (GET_CODE (op) == CONST_INT ? INTVAL (op) : CONST_DOUBLE_LOW (op))
- : (GET_CODE (op) == CONST_INT
- ? (INTVAL (op) < 0 ? ~0 : 0) : CONST_DOUBLE_HIGH (op)));
-
- /* Get the value we want into the low bits of val. */
- if (BITS_PER_WORD < HOST_BITS_PER_WIDE_INT)
- val = ((val >> ((offset % size_ratio) * BITS_PER_WORD)));
-
- val = trunc_int_for_mode (val, word_mode);
-
- return GEN_INT (val);
-}
-
/* Return subword OFFSET of operand OP.
The word number, OFFSET, is interpreted as the word number starting
at the low-order address. OFFSET 0 is the low-order word if not
@@ -1535,11 +1380,7 @@ constant_subword (op, offset, mode)
*/
rtx
-operand_subword (op, offset, validate_address, mode)
- rtx op;
- unsigned int offset;
- int validate_address;
- enum machine_mode mode;
+operand_subword (rtx op, unsigned int offset, int validate_address, enum machine_mode mode)
{
if (mode == VOIDmode)
mode = GET_MODE (op);
@@ -1585,10 +1426,7 @@ operand_subword (op, offset, validate_address, mode)
MODE is the mode of OP, in case it is CONST_INT. */
rtx
-operand_subword_force (op, offset, mode)
- rtx op;
- unsigned int offset;
- enum machine_mode mode;
+operand_subword_force (rtx op, unsigned int offset, enum machine_mode mode)
{
rtx result = operand_subword (op, offset, 1, mode);
@@ -1616,8 +1454,7 @@ operand_subword_force (op, offset, mode)
A test instruction is changed into a compare of 0 against the operand. */
void
-reverse_comparison (insn)
- rtx insn;
+reverse_comparison (rtx insn)
{
rtx body = PATTERN (insn);
rtx comp;
@@ -1650,8 +1487,7 @@ reverse_comparison (insn)
a NULL expression. */
static tree
-component_ref_for_mem_expr (ref)
- tree ref;
+component_ref_for_mem_expr (tree ref)
{
tree inner = TREE_OPERAND (ref, 0);
@@ -1684,17 +1520,48 @@ component_ref_for_mem_expr (ref)
TREE_OPERAND (ref, 1));
}
+/* Returns 1 if both MEM_EXPR can be considered equal
+ and 0 otherwise. */
+
+int
+mem_expr_equal_p (tree expr1, tree expr2)
+{
+ if (expr1 == expr2)
+ return 1;
+
+ if (! expr1 || ! expr2)
+ return 0;
+
+ if (TREE_CODE (expr1) != TREE_CODE (expr2))
+ return 0;
+
+ if (TREE_CODE (expr1) == COMPONENT_REF)
+ return
+ mem_expr_equal_p (TREE_OPERAND (expr1, 0),
+ TREE_OPERAND (expr2, 0))
+ && mem_expr_equal_p (TREE_OPERAND (expr1, 1), /* field decl */
+ TREE_OPERAND (expr2, 1));
+
+ if (TREE_CODE (expr1) == INDIRECT_REF)
+ return mem_expr_equal_p (TREE_OPERAND (expr1, 0),
+ TREE_OPERAND (expr2, 0));
+
+ /* Decls with different pointers can't be equal. */
+ if (DECL_P (expr1))
+ return 0;
+
+ abort(); /* ARRAY_REFs, ARRAY_RANGE_REFs and BIT_FIELD_REFs should already
+ have been resolved here. */
+}
+
/* Given REF, a MEM, and T, either the type of X or the expression
corresponding to REF, set the memory attributes. OBJECTP is nonzero
if we are making a new object of this type. BITPOS is nonzero if
there is an offset outstanding on T that will be applied later. */
void
-set_mem_attributes_minus_bitpos (ref, t, objectp, bitpos)
- rtx ref;
- tree t;
- int objectp;
- HOST_WIDE_INT bitpos;
+set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
+ HOST_WIDE_INT bitpos)
{
HOST_WIDE_INT alias = MEM_ALIAS_SET (ref);
tree expr = MEM_EXPR (ref);
@@ -1711,6 +1578,8 @@ set_mem_attributes_minus_bitpos (ref, t, objectp, bitpos)
return;
type = TYPE_P (t) ? t : TREE_TYPE (t);
+ if (type == error_mark_node)
+ return;
/* If we have already set DECL_RTL = ref, get_alias_set will get the
wrong answer, as it assumes that DECL_RTL already has the right alias
@@ -1827,11 +1696,9 @@ set_mem_attributes_minus_bitpos (ref, t, objectp, bitpos)
/* If the index has a self-referential type, pass it to a
WITH_RECORD_EXPR; if the component size is, pass our
component to one. */
- if (! TREE_CONSTANT (index)
- && contains_placeholder_p (index))
+ if (CONTAINS_PLACEHOLDER_P (index))
index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, t2);
- if (! TREE_CONSTANT (unit_size)
- && contains_placeholder_p (unit_size))
+ if (CONTAINS_PLACEHOLDER_P (unit_size))
unit_size = build (WITH_RECORD_EXPR, sizetype,
unit_size, array);
@@ -1854,7 +1721,7 @@ set_mem_attributes_minus_bitpos (ref, t, objectp, bitpos)
HOST_WIDE_INT ioff = tree_low_cst (off_tree, 1);
HOST_WIDE_INT aoff = (ioff & -ioff) * BITS_PER_UNIT;
align = DECL_ALIGN (t2);
- if (aoff && aoff < align)
+ if (aoff && (unsigned HOST_WIDE_INT) aoff < align)
align = aoff;
offset = GEN_INT (ioff);
apply_bitpos = bitpos;
@@ -1891,7 +1758,7 @@ set_mem_attributes_minus_bitpos (ref, t, objectp, bitpos)
}
}
- /* If we modified OFFSET based on T, then subtract the outstanding
+ /* If we modified OFFSET based on T, then subtract the outstanding
bit position offset. Similarly, increase the size of the accessed
object to contain the negative offset. */
if (apply_bitpos)
@@ -1918,20 +1785,26 @@ set_mem_attributes_minus_bitpos (ref, t, objectp, bitpos)
}
void
-set_mem_attributes (ref, t, objectp)
- rtx ref;
- tree t;
- int objectp;
+set_mem_attributes (rtx ref, tree t, int objectp)
{
set_mem_attributes_minus_bitpos (ref, t, objectp, 0);
}
+/* Set the decl for MEM to DECL. */
+
+void
+set_mem_attrs_from_reg (rtx mem, rtx reg)
+{
+ MEM_ATTRS (mem)
+ = get_mem_attrs (MEM_ALIAS_SET (mem), REG_EXPR (reg),
+ GEN_INT (REG_OFFSET (reg)),
+ MEM_SIZE (mem), MEM_ALIGN (mem), GET_MODE (mem));
+}
+
/* Set the alias set of MEM to SET. */
void
-set_mem_alias_set (mem, set)
- rtx mem;
- HOST_WIDE_INT set;
+set_mem_alias_set (rtx mem, HOST_WIDE_INT set)
{
#ifdef ENABLE_CHECKING
/* If the new and old alias sets don't conflict, something is wrong. */
@@ -1947,9 +1820,7 @@ set_mem_alias_set (mem, set)
/* Set the alignment of MEM to ALIGN bits. */
void
-set_mem_align (mem, align)
- rtx mem;
- unsigned int align;
+set_mem_align (rtx mem, unsigned int align)
{
MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
MEM_OFFSET (mem), MEM_SIZE (mem), align,
@@ -1959,9 +1830,7 @@ set_mem_align (mem, align)
/* Set the expr for MEM to EXPR. */
void
-set_mem_expr (mem, expr)
- rtx mem;
- tree expr;
+set_mem_expr (rtx mem, tree expr)
{
MEM_ATTRS (mem)
= get_mem_attrs (MEM_ALIAS_SET (mem), expr, MEM_OFFSET (mem),
@@ -1971,8 +1840,7 @@ set_mem_expr (mem, expr)
/* Set the offset of MEM to OFFSET. */
void
-set_mem_offset (mem, offset)
- rtx mem, offset;
+set_mem_offset (rtx mem, rtx offset)
{
MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
offset, MEM_SIZE (mem), MEM_ALIGN (mem),
@@ -1982,8 +1850,7 @@ set_mem_offset (mem, offset)
/* Set the size of MEM to SIZE. */
void
-set_mem_size (mem, size)
- rtx mem, size;
+set_mem_size (rtx mem, rtx size)
{
MEM_ATTRS (mem) = get_mem_attrs (MEM_ALIAS_SET (mem), MEM_EXPR (mem),
MEM_OFFSET (mem), size, MEM_ALIGN (mem),
@@ -1997,11 +1864,7 @@ set_mem_size (mem, size)
attributes are not changed. */
static rtx
-change_address_1 (memref, mode, addr, validate)
- rtx memref;
- enum machine_mode mode;
- rtx addr;
- int validate;
+change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
{
rtx new;
@@ -2011,6 +1874,9 @@ change_address_1 (memref, mode, addr, validate)
mode = GET_MODE (memref);
if (addr == 0)
addr = XEXP (memref, 0);
+ if (mode == GET_MODE (memref) && addr == XEXP (memref, 0)
+ && (!validate || memory_address_p (mode, addr)))
+ return memref;
if (validate)
{
@@ -2035,20 +1901,31 @@ change_address_1 (memref, mode, addr, validate)
way we are changing MEMREF, so we only preserve the alias set. */
rtx
-change_address (memref, mode, addr)
- rtx memref;
- enum machine_mode mode;
- rtx addr;
+change_address (rtx memref, enum machine_mode mode, rtx addr)
{
- rtx new = change_address_1 (memref, mode, addr, 1);
+ rtx new = change_address_1 (memref, mode, addr, 1), size;
enum machine_mode mmode = GET_MODE (new);
+ unsigned int align;
+
+ size = mmode == BLKmode ? 0 : GEN_INT (GET_MODE_SIZE (mmode));
+ align = mmode == BLKmode ? BITS_PER_UNIT : GET_MODE_ALIGNMENT (mmode);
+
+ /* If there are no changes, just return the original memory reference. */
+ if (new == memref)
+ {
+ if (MEM_ATTRS (memref) == 0
+ || (MEM_EXPR (memref) == NULL
+ && MEM_OFFSET (memref) == NULL
+ && MEM_SIZE (memref) == size
+ && MEM_ALIGN (memref) == align))
+ return new;
+
+ new = gen_rtx_MEM (mmode, XEXP (memref, 0));
+ MEM_COPY_ATTRIBUTES (new, memref);
+ }
MEM_ATTRS (new)
- = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0,
- mmode == BLKmode ? 0 : GEN_INT (GET_MODE_SIZE (mmode)),
- (mmode == BLKmode ? BITS_PER_UNIT
- : GET_MODE_ALIGNMENT (mmode)),
- mmode);
+ = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align, mmode);
return new;
}
@@ -2060,11 +1937,8 @@ change_address (memref, mode, addr)
and caller is responsible for adjusting MEMREF base register. */
rtx
-adjust_address_1 (memref, mode, offset, validate, adjust)
- rtx memref;
- enum machine_mode mode;
- HOST_WIDE_INT offset;
- int validate, adjust;
+adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset,
+ int validate, int adjust)
{
rtx addr = XEXP (memref, 0);
rtx new;
@@ -2072,6 +1946,11 @@ adjust_address_1 (memref, mode, offset, validate, adjust)
rtx size = 0;
unsigned int memalign = MEM_ALIGN (memref);
+ /* If there are no changes, just return the original memory reference. */
+ if (mode == GET_MODE (memref) && !offset
+ && (!validate || memory_address_p (mode, addr)))
+ return memref;
+
/* ??? Prefer to create garbage instead of creating shared rtl.
This may happen even if offset is nonzero -- consider
(plus (plus reg reg) const_int) -- so do this always. */
@@ -2126,12 +2005,8 @@ adjust_address_1 (memref, mode, offset, validate, adjust)
nonzero, the memory address is forced to be valid. */
rtx
-adjust_automodify_address_1 (memref, mode, addr, offset, validate)
- rtx memref;
- enum machine_mode mode;
- rtx addr;
- HOST_WIDE_INT offset;
- int validate;
+adjust_automodify_address_1 (rtx memref, enum machine_mode mode, rtx addr,
+ HOST_WIDE_INT offset, int validate)
{
memref = change_address_1 (memref, VOIDmode, addr, validate);
return adjust_address_1 (memref, mode, offset, validate, 0);
@@ -2142,17 +2017,14 @@ adjust_automodify_address_1 (memref, mode, addr, offset, validate)
known to be in OFFSET (possibly 1). */
rtx
-offset_address (memref, offset, pow2)
- rtx memref;
- rtx offset;
- HOST_WIDE_INT pow2;
+offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
{
rtx new, addr = XEXP (memref, 0);
new = simplify_gen_binary (PLUS, Pmode, addr, offset);
/* At this point we don't know _why_ the address is invalid. It
- could have secondary memory refereces, multiplies or anything.
+ could have secondary memory references, multiplies or anything.
However, if we did go and rearrange things, we can wind up not
being able to recognize the magic around pic_offset_table_rtx.
@@ -2169,12 +2041,15 @@ offset_address (memref, offset, pow2)
update_temp_slot_address (XEXP (memref, 0), new);
new = change_address_1 (memref, VOIDmode, new, 1);
+ /* If there are no changes, just return the original memory reference. */
+ if (new == memref)
+ return new;
+
/* Update the alignment to reflect the offset. Reset the offset, which
we don't know. */
MEM_ATTRS (new)
= get_mem_attrs (MEM_ALIAS_SET (memref), MEM_EXPR (memref), 0, 0,
- MIN (MEM_ALIGN (memref),
- (unsigned HOST_WIDE_INT) pow2 * BITS_PER_UNIT),
+ MIN (MEM_ALIGN (memref), pow2 * BITS_PER_UNIT),
GET_MODE (new));
return new;
}
@@ -2185,9 +2060,7 @@ offset_address (memref, offset, pow2)
by putting something into a register. */
rtx
-replace_equiv_address (memref, addr)
- rtx memref;
- rtx addr;
+replace_equiv_address (rtx memref, rtx addr)
{
/* change_address_1 copies the memory attribute structure without change
and that's exactly what we want here. */
@@ -2198,9 +2071,7 @@ replace_equiv_address (memref, addr)
/* Likewise, but the reference is not required to be valid. */
rtx
-replace_equiv_address_nv (memref, addr)
- rtx memref;
- rtx addr;
+replace_equiv_address_nv (rtx memref, rtx addr)
{
return change_address_1 (memref, VOIDmode, addr, 0);
}
@@ -2211,16 +2082,17 @@ replace_equiv_address_nv (memref, addr)
operations plus masking logic. */
rtx
-widen_memory_access (memref, mode, offset)
- rtx memref;
- enum machine_mode mode;
- HOST_WIDE_INT offset;
+widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
{
rtx new = adjust_address_1 (memref, mode, offset, 1, 1);
tree expr = MEM_EXPR (new);
rtx memoffset = MEM_OFFSET (new);
unsigned int size = GET_MODE_SIZE (mode);
+ /* If there are no changes, just return the original memory reference. */
+ if (new == memref)
+ return new;
+
/* If we don't know what offset we were at within the expression, then
we can't know if we've overstepped the bounds. */
if (! memoffset)
@@ -2288,10 +2160,10 @@ widen_memory_access (memref, mode, offset)
/* Return a newly created CODE_LABEL rtx with a unique label number. */
rtx
-gen_label_rtx ()
+gen_label_rtx (void)
{
return gen_rtx_CODE_LABEL (VOIDmode, 0, NULL_RTX, NULL_RTX,
- NULL, label_num++, NULL);
+ NULL, label_num++, NULL);
}
/* For procedure integration. */
@@ -2301,8 +2173,7 @@ gen_label_rtx ()
Used for an inline-procedure after copying the insn chain. */
void
-set_new_first_and_last_insn (first, last)
- rtx first, last;
+set_new_first_and_last_insn (rtx first, rtx last)
{
rtx insn;
@@ -2316,24 +2187,11 @@ set_new_first_and_last_insn (first, last)
cur_insn_uid++;
}
-/* Set the range of label numbers found in the current function.
- This is used when belatedly compiling an inline function. */
-
-void
-set_new_first_and_last_label_num (first, last)
- int first, last;
-{
- base_label_num = label_num;
- first_label_num = first;
- last_label_num = last;
-}
-
/* Set the last label number found in the current function.
This is used when belatedly compiling an inline function. */
void
-set_new_last_label_num (last)
- int last;
+set_new_last_label_num (int last)
{
base_label_num = label_num;
last_label_num = last;
@@ -2343,8 +2201,7 @@ set_new_last_label_num (last)
This is used after a nested function. */
void
-restore_emit_status (p)
- struct function *p ATTRIBUTE_UNUSED;
+restore_emit_status (struct function *p ATTRIBUTE_UNUSED)
{
last_label_num = 0;
}
@@ -2353,9 +2210,7 @@ restore_emit_status (p)
structure. This routine should only be called once. */
void
-unshare_all_rtl (fndecl, insn)
- tree fndecl;
- rtx insn;
+unshare_all_rtl (tree fndecl, rtx insn)
{
tree decl;
@@ -2367,7 +2222,7 @@ unshare_all_rtl (fndecl, insn)
unshare_all_decls (DECL_INITIAL (fndecl));
/* Unshare just about everything else. */
- unshare_all_rtl_1 (insn);
+ unshare_all_rtl_in_chain (insn);
/* Make sure the addresses of stack slots found outside the insn chain
(such as, in DECL_RTL of a variable) are not shared
@@ -2384,8 +2239,7 @@ unshare_all_rtl (fndecl, insn)
should be done sparingly. */
void
-unshare_all_rtl_again (insn)
- rtx insn;
+unshare_all_rtl_again (rtx insn)
{
rtx p;
tree decl;
@@ -2410,12 +2264,138 @@ unshare_all_rtl_again (insn)
unshare_all_rtl (cfun->decl, insn);
}
+/* Check that ORIG is not marked when it should not be and mark ORIG as in use,
+ Recursively does the same for subexpressions. */
+
+static void
+verify_rtx_sharing (rtx orig, rtx insn)
+{
+ rtx x = orig;
+ int i;
+ enum rtx_code code;
+ const char *format_ptr;
+
+ if (x == 0)
+ return;
+
+ code = GET_CODE (x);
+
+ /* These types may be freely shared. */
+
+ switch (code)
+ {
+ case REG:
+ case QUEUED:
+ case CONST_INT:
+ case CONST_DOUBLE:
+ case CONST_VECTOR:
+ case SYMBOL_REF:
+ case LABEL_REF:
+ case CODE_LABEL:
+ case PC:
+ case CC0:
+ case SCRATCH:
+ /* SCRATCH must be shared because they represent distinct values. */
+ return;
+
+ case CONST:
+ /* CONST can be shared if it contains a SYMBOL_REF. If it contains
+ a LABEL_REF, it isn't sharable. */
+ if (GET_CODE (XEXP (x, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
+ return;
+ break;
+
+ case MEM:
+ /* A MEM is allowed to be shared if its address is constant. */
+ if (CONSTANT_ADDRESS_P (XEXP (x, 0))
+ || reload_completed || reload_in_progress)
+ return;
+
+ break;
+
+ default:
+ break;
+ }
+
+ /* This rtx may not be shared. If it has already been seen,
+ replace it with a copy of itself. */
+
+ if (RTX_FLAG (x, used))
+ {
+ error ("Invalid rtl sharing found in the insn");
+ debug_rtx (insn);
+ error ("Shared rtx");
+ debug_rtx (x);
+ abort ();
+ }
+ RTX_FLAG (x, used) = 1;
+
+ /* Now scan the subexpressions recursively. */
+
+ format_ptr = GET_RTX_FORMAT (code);
+
+ for (i = 0; i < GET_RTX_LENGTH (code); i++)
+ {
+ switch (*format_ptr++)
+ {
+ case 'e':
+ verify_rtx_sharing (XEXP (x, i), insn);
+ break;
+
+ case 'E':
+ if (XVEC (x, i) != NULL)
+ {
+ int j;
+ int len = XVECLEN (x, i);
+
+ for (j = 0; j < len; j++)
+ {
+ /* We allow sharing of ASM_OPERANDS inside single instruction. */
+ if (j && GET_CODE (XVECEXP (x, i, j)) == SET
+ && GET_CODE (SET_SRC (XVECEXP (x, i, j))) == ASM_OPERANDS)
+ verify_rtx_sharing (SET_DEST (XVECEXP (x, i, j)), insn);
+ else
+ verify_rtx_sharing (XVECEXP (x, i, j), insn);
+ }
+ }
+ break;
+ }
+ }
+ return;
+}
+
+/* Go through all the RTL insn bodies and check that there is no unexpected
+ sharing in between the subexpressions. */
+
+void
+verify_rtl_sharing (void)
+{
+ rtx p;
+
+ for (p = get_insns (); p; p = NEXT_INSN (p))
+ if (INSN_P (p))
+ {
+ reset_used_flags (PATTERN (p));
+ reset_used_flags (REG_NOTES (p));
+ reset_used_flags (LOG_LINKS (p));
+ }
+
+ for (p = get_insns (); p; p = NEXT_INSN (p))
+ if (INSN_P (p))
+ {
+ verify_rtx_sharing (PATTERN (p), p);
+ verify_rtx_sharing (REG_NOTES (p), p);
+ verify_rtx_sharing (LOG_LINKS (p), p);
+ }
+}
+
/* Go through all the RTL insn bodies and copy any invalid shared structure.
Assumes the mark bits are cleared at entry. */
-static void
-unshare_all_rtl_1 (insn)
- rtx insn;
+void
+unshare_all_rtl_in_chain (rtx insn)
{
for (; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn))
@@ -2429,8 +2409,7 @@ unshare_all_rtl_1 (insn)
/* Go through all virtual stack slots of a function and copy any
shared structure. */
static void
-unshare_all_decls (blk)
- tree blk;
+unshare_all_decls (tree blk)
{
tree t;
@@ -2447,8 +2426,7 @@ unshare_all_decls (blk)
/* Go through all virtual stack slots of a function and mark them as
not shared. */
static void
-reset_used_decls (blk)
- tree blk;
+reset_used_decls (tree blk)
{
tree t;
@@ -2467,9 +2445,7 @@ reset_used_decls (blk)
either a MEM of an EXPR_LIST of MEMs. */
rtx
-copy_most_rtx (orig, may_share)
- rtx orig;
- rtx may_share;
+copy_most_rtx (rtx orig, rtx may_share)
{
rtx copy;
int i, j;
@@ -2554,8 +2530,7 @@ copy_most_rtx (orig, may_share)
break;
case '0':
- /* Copy this through the wide int field; that's safest. */
- X0WINT (copy, i) = X0WINT (orig, i);
+ X0ANY (copy, i) = X0ANY (orig, i);
break;
default:
@@ -2566,20 +2541,36 @@ copy_most_rtx (orig, may_share)
}
/* Mark ORIG as in use, and return a copy of it if it was already in use.
- Recursively does the same for subexpressions. */
+ Recursively does the same for subexpressions. Uses
+ copy_rtx_if_shared_1 to reduce stack space. */
rtx
-copy_rtx_if_shared (orig)
- rtx orig;
+copy_rtx_if_shared (rtx orig)
{
- rtx x = orig;
+ copy_rtx_if_shared_1 (&orig);
+ return orig;
+}
+
+/* Mark *ORIG1 as in use, and set it to a copy of it if it was already in
+ use. Recursively does the same for subexpressions. */
+
+static void
+copy_rtx_if_shared_1 (rtx *orig1)
+{
+ rtx x;
int i;
enum rtx_code code;
+ rtx *last_ptr;
const char *format_ptr;
int copied = 0;
+ int length;
+
+ /* Repeat is used to turn tail-recursion into iteration. */
+repeat:
+ x = *orig1;
if (x == 0)
- return 0;
+ return;
code = GET_CODE (x);
@@ -2593,12 +2584,13 @@ copy_rtx_if_shared (orig)
case CONST_DOUBLE:
case CONST_VECTOR:
case SYMBOL_REF:
+ case LABEL_REF:
case CODE_LABEL:
case PC:
case CC0:
case SCRATCH:
/* SCRATCH must be shared because they represent distinct values. */
- return x;
+ return;
case CONST:
/* CONST can be shared if it contains a SYMBOL_REF. If it contains
@@ -2606,7 +2598,7 @@ copy_rtx_if_shared (orig)
if (GET_CODE (XEXP (x, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
- return x;
+ return;
break;
case INSN:
@@ -2615,21 +2607,7 @@ copy_rtx_if_shared (orig)
case NOTE:
case BARRIER:
/* The chain of insns is not being copied. */
- return x;
-
- case MEM:
- /* A MEM is allowed to be shared if its address is constant.
-
- We used to allow sharing of MEMs which referenced
- virtual_stack_vars_rtx or virtual_incoming_args_rtx, but
- that can lose. instantiate_virtual_regs will not unshare
- the MEMs, and combine may change the structure of the address
- because it looks safe and profitable in one context, but
- in some other context it creates unrecognizable RTL. */
- if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
- return x;
-
- break;
+ return;
default:
break;
@@ -2643,9 +2621,7 @@ copy_rtx_if_shared (orig)
rtx copy;
copy = rtx_alloc (code);
- memcpy (copy, x,
- (sizeof (*copy) - sizeof (copy->fld)
- + sizeof (copy->fld[0]) * GET_RTX_LENGTH (code)));
+ memcpy (copy, x, RTX_SIZE (code));
x = copy;
copied = 1;
}
@@ -2657,13 +2633,17 @@ copy_rtx_if_shared (orig)
must be copied if X was copied. */
format_ptr = GET_RTX_FORMAT (code);
-
- for (i = 0; i < GET_RTX_LENGTH (code); i++)
+ length = GET_RTX_LENGTH (code);
+ last_ptr = NULL;
+
+ for (i = 0; i < length; i++)
{
switch (*format_ptr++)
{
case 'e':
- XEXP (x, i) = copy_rtx_if_shared (XEXP (x, i));
+ if (last_ptr)
+ copy_rtx_if_shared_1 (last_ptr);
+ last_ptr = &XEXP (x, i);
break;
case 'E':
@@ -2671,29 +2651,45 @@ copy_rtx_if_shared (orig)
{
int j;
int len = XVECLEN (x, i);
-
+
+ /* Copy the vector iff I copied the rtx and the length
+ is nonzero. */
if (copied && len > 0)
XVEC (x, i) = gen_rtvec_v (len, XVEC (x, i)->elem);
+
+ /* Call recursively on all inside the vector. */
for (j = 0; j < len; j++)
- XVECEXP (x, i, j) = copy_rtx_if_shared (XVECEXP (x, i, j));
+ {
+ if (last_ptr)
+ copy_rtx_if_shared_1 (last_ptr);
+ last_ptr = &XVECEXP (x, i, j);
+ }
}
break;
}
}
- return x;
+ *orig1 = x;
+ if (last_ptr)
+ {
+ orig1 = last_ptr;
+ goto repeat;
+ }
+ return;
}
/* Clear all the USED bits in X to allow copy_rtx_if_shared to be used
to look for shared sub-parts. */
void
-reset_used_flags (x)
- rtx x;
+reset_used_flags (rtx x)
{
int i, j;
enum rtx_code code;
const char *format_ptr;
+ int length;
+ /* Repeat is used to turn tail-recursion into iteration. */
+repeat:
if (x == 0)
return;
@@ -2731,11 +2727,18 @@ reset_used_flags (x)
RTX_FLAG (x, used) = 0;
format_ptr = GET_RTX_FORMAT (code);
- for (i = 0; i < GET_RTX_LENGTH (code); i++)
+ length = GET_RTX_LENGTH (code);
+
+ for (i = 0; i < length; i++)
{
switch (*format_ptr++)
{
case 'e':
+ if (i == length-1)
+ {
+ x = XEXP (x, i);
+ goto repeat;
+ }
reset_used_flags (XEXP (x, i));
break;
@@ -2746,14 +2749,76 @@ reset_used_flags (x)
}
}
}
+
+/* Set all the USED bits in X to allow copy_rtx_if_shared to be used
+ to look for shared sub-parts. */
+
+void
+set_used_flags (rtx x)
+{
+ int i, j;
+ enum rtx_code code;
+ const char *format_ptr;
+
+ if (x == 0)
+ return;
+
+ code = GET_CODE (x);
+
+ /* These types may be freely shared so we needn't do any resetting
+ for them. */
+
+ switch (code)
+ {
+ case REG:
+ case QUEUED:
+ case CONST_INT:
+ case CONST_DOUBLE:
+ case CONST_VECTOR:
+ case SYMBOL_REF:
+ case CODE_LABEL:
+ case PC:
+ case CC0:
+ return;
+
+ case INSN:
+ case JUMP_INSN:
+ case CALL_INSN:
+ case NOTE:
+ case LABEL_REF:
+ case BARRIER:
+ /* The chain of insns is not being copied. */
+ return;
+
+ default:
+ break;
+ }
+
+ RTX_FLAG (x, used) = 1;
+
+ format_ptr = GET_RTX_FORMAT (code);
+ for (i = 0; i < GET_RTX_LENGTH (code); i++)
+ {
+ switch (*format_ptr++)
+ {
+ case 'e':
+ set_used_flags (XEXP (x, i));
+ break;
+
+ case 'E':
+ for (j = 0; j < XVECLEN (x, i); j++)
+ set_used_flags (XVECEXP (x, i, j));
+ break;
+ }
+ }
+}
/* Copy X if necessary so that it won't be altered by changes in OTHER.
Return X or the rtx for the pseudo reg the value of X was copied into.
OTHER must be valid as a SET_DEST. */
rtx
-make_safe_from (x, other)
- rtx x, other;
+make_safe_from (rtx x, rtx other)
{
while (1)
switch (GET_CODE (other))
@@ -2790,7 +2855,7 @@ make_safe_from (x, other)
/* Return the first insn of the current sequence or current function. */
rtx
-get_insns ()
+get_insns (void)
{
return first_insn;
}
@@ -2798,8 +2863,7 @@ get_insns ()
/* Specify a new insn as the first in the chain. */
void
-set_first_insn (insn)
- rtx insn;
+set_first_insn (rtx insn)
{
if (PREV_INSN (insn) != 0)
abort ();
@@ -2809,7 +2873,7 @@ set_first_insn (insn)
/* Return the last insn emitted in current sequence or current function. */
rtx
-get_last_insn ()
+get_last_insn (void)
{
return last_insn;
}
@@ -2817,8 +2881,7 @@ get_last_insn ()
/* Specify a new insn as the last in the chain. */
void
-set_last_insn (insn)
- rtx insn;
+set_last_insn (rtx insn)
{
if (NEXT_INSN (insn) != 0)
abort ();
@@ -2828,7 +2891,7 @@ set_last_insn (insn)
/* Return the last insn emitted, even if it is in a sequence now pushed. */
rtx
-get_last_insn_anywhere ()
+get_last_insn_anywhere (void)
{
struct sequence_stack *stack;
if (last_insn)
@@ -2843,7 +2906,7 @@ get_last_insn_anywhere ()
function. This routine looks inside SEQUENCEs. */
rtx
-get_first_nonnote_insn ()
+get_first_nonnote_insn (void)
{
rtx insn = first_insn;
@@ -2861,7 +2924,7 @@ get_first_nonnote_insn ()
function. This routine looks inside SEQUENCEs. */
rtx
-get_last_nonnote_insn ()
+get_last_nonnote_insn (void)
{
rtx insn = last_insn;
@@ -2878,7 +2941,7 @@ get_last_nonnote_insn ()
/* Return a number larger than any instruction's uid in this function. */
int
-get_max_uid ()
+get_max_uid (void)
{
return cur_insn_uid;
}
@@ -2886,8 +2949,7 @@ get_max_uid ()
/* Renumber instructions so that no instruction UIDs are wasted. */
void
-renumber_insns (stream)
- FILE *stream;
+renumber_insns (FILE *stream)
{
rtx insn;
@@ -2915,8 +2977,7 @@ renumber_insns (stream)
of the sequence. */
rtx
-next_insn (insn)
- rtx insn;
+next_insn (rtx insn)
{
if (insn)
{
@@ -2933,8 +2994,7 @@ next_insn (insn)
of the sequence. */
rtx
-previous_insn (insn)
- rtx insn;
+previous_insn (rtx insn)
{
if (insn)
{
@@ -2951,8 +3011,7 @@ previous_insn (insn)
look inside SEQUENCEs. */
rtx
-next_nonnote_insn (insn)
- rtx insn;
+next_nonnote_insn (rtx insn)
{
while (insn)
{
@@ -2968,8 +3027,7 @@ next_nonnote_insn (insn)
not look inside SEQUENCEs. */
rtx
-prev_nonnote_insn (insn)
- rtx insn;
+prev_nonnote_insn (rtx insn)
{
while (insn)
{
@@ -2986,8 +3044,7 @@ prev_nonnote_insn (insn)
SEQUENCEs. */
rtx
-next_real_insn (insn)
- rtx insn;
+next_real_insn (rtx insn)
{
while (insn)
{
@@ -3005,8 +3062,7 @@ next_real_insn (insn)
SEQUENCEs. */
rtx
-prev_real_insn (insn)
- rtx insn;
+prev_real_insn (rtx insn)
{
while (insn)
{
@@ -3019,13 +3075,28 @@ prev_real_insn (insn)
return insn;
}
+/* Return the last CALL_INSN in the current list, or 0 if there is none.
+ This routine does not look inside SEQUENCEs. */
+
+rtx
+last_call_insn (void)
+{
+ rtx insn;
+
+ for (insn = get_last_insn ();
+ insn && GET_CODE (insn) != CALL_INSN;
+ insn = PREV_INSN (insn))
+ ;
+
+ return insn;
+}
+
/* Find the next insn after INSN that really does something. This routine
does not look inside SEQUENCEs. Until reload has completed, this is the
same as next_real_insn. */
int
-active_insn_p (insn)
- rtx insn;
+active_insn_p (rtx insn)
{
return (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN
|| (GET_CODE (insn) == INSN
@@ -3035,8 +3106,7 @@ active_insn_p (insn)
}
rtx
-next_active_insn (insn)
- rtx insn;
+next_active_insn (rtx insn)
{
while (insn)
{
@@ -3053,8 +3123,7 @@ next_active_insn (insn)
same as prev_real_insn. */
rtx
-prev_active_insn (insn)
- rtx insn;
+prev_active_insn (rtx insn)
{
while (insn)
{
@@ -3069,8 +3138,7 @@ prev_active_insn (insn)
/* Return the next CODE_LABEL after the insn INSN, or 0 if there is none. */
rtx
-next_label (insn)
- rtx insn;
+next_label (rtx insn)
{
while (insn)
{
@@ -3085,8 +3153,7 @@ next_label (insn)
/* Return the last CODE_LABEL before the insn INSN, or 0 if there is none. */
rtx
-prev_label (insn)
- rtx insn;
+prev_label (rtx insn)
{
while (insn)
{
@@ -3103,8 +3170,7 @@ prev_label (insn)
and REG_CC_USER notes so we can find it. */
void
-link_cc0_insns (insn)
- rtx insn;
+link_cc0_insns (rtx insn)
{
rtx user = next_nonnote_insn (insn);
@@ -3126,8 +3192,7 @@ link_cc0_insns (insn)
Return 0 if we can't find the insn. */
rtx
-next_cc0_user (insn)
- rtx insn;
+next_cc0_user (rtx insn)
{
rtx note = find_reg_note (insn, REG_CC_USER, NULL_RTX);
@@ -3148,8 +3213,7 @@ next_cc0_user (insn)
note, it is the previous insn. */
rtx
-prev_cc0_setter (insn)
- rtx insn;
+prev_cc0_setter (rtx insn)
{
rtx note = find_reg_note (insn, REG_CC_SETTER, NULL_RTX);
@@ -3167,15 +3231,14 @@ prev_cc0_setter (insn)
/* Increment the label uses for all labels present in rtx. */
static void
-mark_label_nuses (x)
- rtx x;
+mark_label_nuses (rtx x)
{
enum rtx_code code;
int i, j;
const char *fmt;
code = GET_CODE (x);
- if (code == LABEL_REF)
+ if (code == LABEL_REF && LABEL_P (XEXP (x, 0)))
LABEL_NUSES (XEXP (x, 0))++;
fmt = GET_RTX_FORMAT (code);
@@ -3200,9 +3263,7 @@ mark_label_nuses (x)
returns TRIAL. If the insn to be returned can be split, it will be. */
rtx
-try_split (pat, trial, last)
- rtx pat, trial;
- int last;
+try_split (rtx pat, rtx trial, int last)
{
rtx before = PREV_INSN (trial);
rtx after = NEXT_INSN (trial);
@@ -3278,8 +3339,10 @@ try_split (pat, trial, last)
for (insn = insn_last; insn ; insn = PREV_INSN (insn))
if (GET_CODE (insn) == CALL_INSN)
{
- CALL_INSN_FUNCTION_USAGE (insn)
- = CALL_INSN_FUNCTION_USAGE (trial);
+ rtx *p = &CALL_INSN_FUNCTION_USAGE (insn);
+ while (*p)
+ p = &XEXP (*p, 1);
+ *p = CALL_INSN_FUNCTION_USAGE (trial);
SIBLING_CALL_P (insn) = SIBLING_CALL_P (trial);
}
}
@@ -3351,7 +3414,7 @@ try_split (pat, trial, last)
}
}
- tem = emit_insn_after_scope (seq, trial, INSN_SCOPE (trial));
+ tem = emit_insn_after_setloc (seq, trial, INSN_LOCATOR (trial));
delete_insn (trial);
if (has_barrier)
@@ -3377,8 +3440,7 @@ try_split (pat, trial, last)
Store PATTERN in the pattern slots. */
rtx
-make_insn_raw (pattern)
- rtx pattern;
+make_insn_raw (rtx pattern)
{
rtx insn;
@@ -3389,7 +3451,7 @@ make_insn_raw (pattern)
INSN_CODE (insn) = -1;
LOG_LINKS (insn) = NULL;
REG_NOTES (insn) = NULL;
- INSN_SCOPE (insn) = NULL;
+ INSN_LOCATOR (insn) = 0;
BLOCK_FOR_INSN (insn) = NULL;
#ifdef ENABLE_RTL_CHECKING
@@ -3410,8 +3472,7 @@ make_insn_raw (pattern)
/* Like `make_insn_raw' but make a JUMP_INSN instead of an insn. */
static rtx
-make_jump_insn_raw (pattern)
- rtx pattern;
+make_jump_insn_raw (rtx pattern)
{
rtx insn;
@@ -3423,7 +3484,7 @@ make_jump_insn_raw (pattern)
LOG_LINKS (insn) = NULL;
REG_NOTES (insn) = NULL;
JUMP_LABEL (insn) = NULL;
- INSN_SCOPE (insn) = NULL;
+ INSN_LOCATOR (insn) = 0;
BLOCK_FOR_INSN (insn) = NULL;
return insn;
@@ -3432,8 +3493,7 @@ make_jump_insn_raw (pattern)
/* Like `make_insn_raw' but make a CALL_INSN instead of an insn. */
static rtx
-make_call_insn_raw (pattern)
- rtx pattern;
+make_call_insn_raw (rtx pattern)
{
rtx insn;
@@ -3445,7 +3505,7 @@ make_call_insn_raw (pattern)
LOG_LINKS (insn) = NULL;
REG_NOTES (insn) = NULL;
CALL_INSN_FUNCTION_USAGE (insn) = NULL;
- INSN_SCOPE (insn) = NULL;
+ INSN_LOCATOR (insn) = 0;
BLOCK_FOR_INSN (insn) = NULL;
return insn;
@@ -3455,8 +3515,7 @@ make_call_insn_raw (pattern)
INSN may be an INSN, JUMP_INSN, CALL_INSN, CODE_LABEL, BARRIER or NOTE. */
void
-add_insn (insn)
- rtx insn;
+add_insn (rtx insn)
{
PREV_INSN (insn) = last_insn;
NEXT_INSN (insn) = 0;
@@ -3476,8 +3535,7 @@ add_insn (insn)
SEQUENCE. */
void
-add_insn_after (insn, after)
- rtx insn, after;
+add_insn_after (rtx insn, rtx after)
{
rtx next = NEXT_INSN (after);
basic_block bb;
@@ -3520,12 +3578,12 @@ add_insn_after (insn, after)
bb->flags |= BB_DIRTY;
/* Should not happen as first in the BB is always
either NOTE or LABEL. */
- if (bb->end == after
+ if (BB_END (bb) == after
/* Avoid clobbering of structure when creating new BB. */
&& GET_CODE (insn) != BARRIER
&& (GET_CODE (insn) != NOTE
|| NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK))
- bb->end = insn;
+ BB_END (bb) = insn;
}
NEXT_INSN (after) = insn;
@@ -3542,8 +3600,7 @@ add_insn_after (insn, after)
SEQUENCE. */
void
-add_insn_before (insn, before)
- rtx insn, before;
+add_insn_before (rtx insn, rtx before)
{
rtx prev = PREV_INSN (before);
basic_block bb;
@@ -3589,7 +3646,7 @@ add_insn_before (insn, before)
bb->flags |= BB_DIRTY;
/* Should not happen as first in the BB is always
either NOTE or LABEl. */
- if (bb->head == insn
+ if (BB_HEAD (bb) == insn
/* Avoid clobbering of structure when creating new BB. */
&& GET_CODE (insn) != BARRIER
&& (GET_CODE (insn) != NOTE
@@ -3605,8 +3662,7 @@ add_insn_before (insn, before)
/* Remove an insn from its doubly-linked list. This function knows how
to handle sequences. */
void
-remove_insn (insn)
- rtx insn;
+remove_insn (rtx insn)
{
rtx next = NEXT_INSN (insn);
rtx prev = PREV_INSN (insn);
@@ -3665,25 +3721,48 @@ remove_insn (insn)
{
if (INSN_P (insn))
bb->flags |= BB_DIRTY;
- if (bb->head == insn)
+ if (BB_HEAD (bb) == insn)
{
/* Never ever delete the basic block note without deleting whole
basic block. */
if (GET_CODE (insn) == NOTE)
abort ();
- bb->head = next;
+ BB_HEAD (bb) = next;
}
- if (bb->end == insn)
- bb->end = prev;
+ if (BB_END (bb) == insn)
+ BB_END (bb) = prev;
}
}
+/* Append CALL_FUSAGE to the CALL_INSN_FUNCTION_USAGE for CALL_INSN. */
+
+void
+add_function_usage_to (rtx call_insn, rtx call_fusage)
+{
+ if (! call_insn || GET_CODE (call_insn) != CALL_INSN)
+ abort ();
+
+ /* Put the register usage information on the CALL. If there is already
+ some usage information, put ours at the end. */
+ if (CALL_INSN_FUNCTION_USAGE (call_insn))
+ {
+ rtx link;
+
+ for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
+ link = XEXP (link, 1))
+ ;
+
+ XEXP (link, 1) = call_fusage;
+ }
+ else
+ CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
+}
+
/* Delete all insns made since FROM.
FROM becomes the new last instruction. */
void
-delete_insns_since (from)
- rtx from;
+delete_insns_since (rtx from)
{
if (from == 0)
first_insn = 0;
@@ -3703,8 +3782,7 @@ delete_insns_since (from)
called after delay-slot filling has been done. */
void
-reorder_insns_nobb (from, to, after)
- rtx from, to, after;
+reorder_insns_nobb (rtx from, rtx to, rtx after)
{
/* Splice this bunch out of where it is now. */
if (PREV_INSN (from))
@@ -3729,8 +3807,7 @@ reorder_insns_nobb (from, to, after)
/* Same as function above, but take care to update BB boundaries. */
void
-reorder_insns (from, to, after)
- rtx from, to, after;
+reorder_insns (rtx from, rtx to, rtx after)
{
rtx prev = PREV_INSN (from);
basic_block bb, bb2;
@@ -3746,13 +3823,13 @@ reorder_insns (from, to, after)
if (GET_CODE (from) != BARRIER
&& (bb2 = BLOCK_FOR_INSN (from)))
{
- if (bb2->end == to)
- bb2->end = prev;
+ if (BB_END (bb2) == to)
+ BB_END (bb2) = prev;
bb2->flags |= BB_DIRTY;
}
- if (bb->end == after)
- bb->end = to;
+ if (BB_END (bb) == after)
+ BB_END (bb) = to;
for (x = from; x != NEXT_INSN (to); x = NEXT_INSN (x))
set_block_for_insn (x, bb);
@@ -3762,8 +3839,7 @@ reorder_insns (from, to, after)
/* Return the line note insn preceding INSN. */
static rtx
-find_line_note (insn)
- rtx insn;
+find_line_note (rtx insn)
{
if (no_line_numbers)
return 0;
@@ -3781,8 +3857,7 @@ find_line_note (insn)
and FROM, and another one after TO. */
void
-reorder_insns_with_line_notes (from, to, after)
- rtx from, to, after;
+reorder_insns_with_line_notes (rtx from, rtx to, rtx after)
{
rtx from_line = find_line_note (from);
rtx after_line = find_line_note (after);
@@ -3793,19 +3868,15 @@ reorder_insns_with_line_notes (from, to, after)
return;
if (from_line)
- emit_line_note_after (NOTE_SOURCE_FILE (from_line),
- NOTE_LINE_NUMBER (from_line),
- after);
+ emit_note_copy_after (from_line, after);
if (after_line)
- emit_line_note_after (NOTE_SOURCE_FILE (after_line),
- NOTE_LINE_NUMBER (after_line),
- to);
+ emit_note_copy_after (after_line, to);
}
/* Remove unnecessary notes from the instruction stream. */
void
-remove_unnecessary_notes ()
+remove_unnecessary_notes (void)
{
rtx block_stack = NULL_RTX;
rtx eh_stack = NULL_RTX;
@@ -3943,8 +4014,7 @@ remove_unnecessary_notes ()
/* Make X be output before the instruction BEFORE. */
rtx
-emit_insn_before (x, before)
- rtx x, before;
+emit_insn_before_noloc (rtx x, rtx before)
{
rtx last = before;
rtx insn;
@@ -3994,8 +4064,7 @@ emit_insn_before (x, before)
and output it before the instruction BEFORE. */
rtx
-emit_jump_insn_before (x, before)
- rtx x, before;
+emit_jump_insn_before_noloc (rtx x, rtx before)
{
rtx insn, last = NULL_RTX;
@@ -4041,8 +4110,7 @@ emit_jump_insn_before (x, before)
and output it before the instruction BEFORE. */
rtx
-emit_call_insn_before (x, before)
- rtx x, before;
+emit_call_insn_before_noloc (rtx x, rtx before)
{
rtx last = NULL_RTX, insn;
@@ -4088,8 +4156,7 @@ emit_call_insn_before (x, before)
and output it before the insn BEFORE. */
rtx
-emit_barrier_before (before)
- rtx before;
+emit_barrier_before (rtx before)
{
rtx insn = rtx_alloc (BARRIER);
@@ -4102,8 +4169,7 @@ emit_barrier_before (before)
/* Emit the label LABEL before the insn BEFORE. */
rtx
-emit_label_before (label, before)
- rtx label, before;
+emit_label_before (rtx label, rtx before)
{
/* This can be called twice for the same label as a result of the
confusion that follows a syntax error! So make it harmless. */
@@ -4119,9 +4185,7 @@ emit_label_before (label, before)
/* Emit a note of subtype SUBTYPE before the insn BEFORE. */
rtx
-emit_note_before (subtype, before)
- int subtype;
- rtx before;
+emit_note_before (int subtype, rtx before)
{
rtx note = rtx_alloc (NOTE);
INSN_UID (note) = cur_insn_uid++;
@@ -4136,11 +4200,10 @@ emit_note_before (subtype, before)
/* Helper for emit_insn_after, handles lists of instructions
efficiently. */
-static rtx emit_insn_after_1 PARAMS ((rtx, rtx));
+static rtx emit_insn_after_1 (rtx, rtx);
static rtx
-emit_insn_after_1 (first, after)
- rtx first, after;
+emit_insn_after_1 (rtx first, rtx after)
{
rtx last;
rtx after_after;
@@ -4155,8 +4218,8 @@ emit_insn_after_1 (first, after)
set_block_for_insn (last, bb);
if (GET_CODE (last) != BARRIER)
set_block_for_insn (last, bb);
- if (bb->end == after)
- bb->end = last;
+ if (BB_END (bb) == after)
+ BB_END (bb) = last;
}
else
for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
@@ -4178,8 +4241,7 @@ emit_insn_after_1 (first, after)
/* Make X be output after the insn AFTER. */
rtx
-emit_insn_after (x, after)
- rtx x, after;
+emit_insn_after_noloc (rtx x, rtx after)
{
rtx last = after;
@@ -4221,30 +4283,24 @@ emit_insn_after (x, after)
as to act as if this insn were at FROM. */
void
-emit_insn_after_with_line_notes (x, after, from)
- rtx x, after, from;
+emit_insn_after_with_line_notes (rtx x, rtx after, rtx from)
{
rtx from_line = find_line_note (from);
rtx after_line = find_line_note (after);
rtx insn = emit_insn_after (x, after);
if (from_line)
- emit_line_note_after (NOTE_SOURCE_FILE (from_line),
- NOTE_LINE_NUMBER (from_line),
- after);
+ emit_note_copy_after (from_line, after);
if (after_line)
- emit_line_note_after (NOTE_SOURCE_FILE (after_line),
- NOTE_LINE_NUMBER (after_line),
- insn);
+ emit_note_copy_after (after_line, insn);
}
/* Make an insn of code JUMP_INSN with body X
and output it after the insn AFTER. */
rtx
-emit_jump_insn_after (x, after)
- rtx x, after;
+emit_jump_insn_after_noloc (rtx x, rtx after)
{
rtx last;
@@ -4283,8 +4339,7 @@ emit_jump_insn_after (x, after)
and output it after the instruction AFTER. */
rtx
-emit_call_insn_after (x, after)
- rtx x, after;
+emit_call_insn_after_noloc (rtx x, rtx after)
{
rtx last;
@@ -4323,8 +4378,7 @@ emit_call_insn_after (x, after)
and output it after the insn AFTER. */
rtx
-emit_barrier_after (after)
- rtx after;
+emit_barrier_after (rtx after)
{
rtx insn = rtx_alloc (BARRIER);
@@ -4337,8 +4391,7 @@ emit_barrier_after (after)
/* Emit the label LABEL after the insn AFTER. */
rtx
-emit_label_after (label, after)
- rtx label, after;
+emit_label_after (rtx label, rtx after)
{
/* This can be called twice for the same label
as a result of the confusion that follows a syntax error!
@@ -4355,9 +4408,7 @@ emit_label_after (label, after)
/* Emit a note of subtype SUBTYPE after the insn AFTER. */
rtx
-emit_note_after (subtype, after)
- int subtype;
- rtx after;
+emit_note_after (int subtype, rtx after)
{
rtx note = rtx_alloc (NOTE);
INSN_UID (note) = cur_insn_uid++;
@@ -4368,17 +4419,14 @@ emit_note_after (subtype, after)
return note;
}
-/* Emit a line note for FILE and LINE after the insn AFTER. */
+/* Emit a copy of note ORIG after the insn AFTER. */
rtx
-emit_line_note_after (file, line, after)
- const char *file;
- int line;
- rtx after;
+emit_note_copy_after (rtx orig, rtx after)
{
rtx note;
- if (no_line_numbers && line > 0)
+ if (NOTE_LINE_NUMBER (orig) >= 0 && no_line_numbers)
{
cur_insn_uid++;
return 0;
@@ -4386,26 +4434,27 @@ emit_line_note_after (file, line, after)
note = rtx_alloc (NOTE);
INSN_UID (note) = cur_insn_uid++;
- NOTE_SOURCE_FILE (note) = file;
- NOTE_LINE_NUMBER (note) = line;
+ NOTE_LINE_NUMBER (note) = NOTE_LINE_NUMBER (orig);
+ NOTE_DATA (note) = NOTE_DATA (orig);
BLOCK_FOR_INSN (note) = NULL;
add_insn_after (note, after);
return note;
}
-/* Like emit_insn_after, but set INSN_SCOPE according to SCOPE. */
+/* Like emit_insn_after_noloc, but set INSN_LOCATOR according to SCOPE. */
rtx
-emit_insn_after_scope (pattern, after, scope)
- rtx pattern, after;
- tree scope;
+emit_insn_after_setloc (rtx pattern, rtx after, int loc)
{
- rtx last = emit_insn_after (pattern, after);
+ rtx last = emit_insn_after_noloc (pattern, after);
+
+ if (pattern == NULL_RTX || !loc)
+ return last;
after = NEXT_INSN (after);
while (1)
{
- if (active_insn_p (after))
- INSN_SCOPE (after) = scope;
+ if (active_insn_p (after) && !INSN_LOCATOR (after))
+ INSN_LOCATOR (after) = loc;
if (after == last)
break;
after = NEXT_INSN (after);
@@ -4413,19 +4462,30 @@ emit_insn_after_scope (pattern, after, scope)
return last;
}
-/* Like emit_jump_insn_after, but set INSN_SCOPE according to SCOPE. */
+/* Like emit_insn_after_noloc, but set INSN_LOCATOR according to AFTER. */
rtx
-emit_jump_insn_after_scope (pattern, after, scope)
- rtx pattern, after;
- tree scope;
+emit_insn_after (rtx pattern, rtx after)
{
- rtx last = emit_jump_insn_after (pattern, after);
+ if (INSN_P (after))
+ return emit_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
+ else
+ return emit_insn_after_noloc (pattern, after);
+}
+
+/* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to SCOPE. */
+rtx
+emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
+{
+ rtx last = emit_jump_insn_after_noloc (pattern, after);
+
+ if (pattern == NULL_RTX || !loc)
+ return last;
after = NEXT_INSN (after);
while (1)
{
- if (active_insn_p (after))
- INSN_SCOPE (after) = scope;
+ if (active_insn_p (after) && !INSN_LOCATOR (after))
+ INSN_LOCATOR (after) = loc;
if (after == last)
break;
after = NEXT_INSN (after);
@@ -4433,19 +4493,30 @@ emit_jump_insn_after_scope (pattern, after, scope)
return last;
}
-/* Like emit_call_insn_after, but set INSN_SCOPE according to SCOPE. */
+/* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to AFTER. */
rtx
-emit_call_insn_after_scope (pattern, after, scope)
- rtx pattern, after;
- tree scope;
+emit_jump_insn_after (rtx pattern, rtx after)
{
- rtx last = emit_call_insn_after (pattern, after);
+ if (INSN_P (after))
+ return emit_jump_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
+ else
+ return emit_jump_insn_after_noloc (pattern, after);
+}
+
+/* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according to SCOPE. */
+rtx
+emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
+{
+ rtx last = emit_call_insn_after_noloc (pattern, after);
+
+ if (pattern == NULL_RTX || !loc)
+ return last;
after = NEXT_INSN (after);
while (1)
{
- if (active_insn_p (after))
- INSN_SCOPE (after) = scope;
+ if (active_insn_p (after) && !INSN_LOCATOR (after))
+ INSN_LOCATOR (after) = loc;
if (after == last)
break;
after = NEXT_INSN (after);
@@ -4453,26 +4524,112 @@ emit_call_insn_after_scope (pattern, after, scope)
return last;
}
-/* Like emit_insn_before, but set INSN_SCOPE according to SCOPE. */
+/* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according to AFTER. */
+rtx
+emit_call_insn_after (rtx pattern, rtx after)
+{
+ if (INSN_P (after))
+ return emit_call_insn_after_setloc (pattern, after, INSN_LOCATOR (after));
+ else
+ return emit_call_insn_after_noloc (pattern, after);
+}
+
+/* Like emit_insn_before_noloc, but set INSN_LOCATOR according to SCOPE. */
rtx
-emit_insn_before_scope (pattern, before, scope)
- rtx pattern, before;
- tree scope;
+emit_insn_before_setloc (rtx pattern, rtx before, int loc)
{
rtx first = PREV_INSN (before);
- rtx last = emit_insn_before (pattern, before);
+ rtx last = emit_insn_before_noloc (pattern, before);
+
+ if (pattern == NULL_RTX || !loc)
+ return last;
first = NEXT_INSN (first);
while (1)
{
- if (active_insn_p (first))
- INSN_SCOPE (first) = scope;
+ if (active_insn_p (first) && !INSN_LOCATOR (first))
+ INSN_LOCATOR (first) = loc;
if (first == last)
break;
first = NEXT_INSN (first);
}
return last;
}
+
+/* Like emit_insn_before_noloc, but set INSN_LOCATOR according to BEFORE. */
+rtx
+emit_insn_before (rtx pattern, rtx before)
+{
+ if (INSN_P (before))
+ return emit_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
+ else
+ return emit_insn_before_noloc (pattern, before);
+}
+
+/* like emit_insn_before_noloc, but set insn_locator according to scope. */
+rtx
+emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
+{
+ rtx first = PREV_INSN (before);
+ rtx last = emit_jump_insn_before_noloc (pattern, before);
+
+ if (pattern == NULL_RTX)
+ return last;
+
+ first = NEXT_INSN (first);
+ while (1)
+ {
+ if (active_insn_p (first) && !INSN_LOCATOR (first))
+ INSN_LOCATOR (first) = loc;
+ if (first == last)
+ break;
+ first = NEXT_INSN (first);
+ }
+ return last;
+}
+
+/* Like emit_jump_insn_before_noloc, but set INSN_LOCATOR according to BEFORE. */
+rtx
+emit_jump_insn_before (rtx pattern, rtx before)
+{
+ if (INSN_P (before))
+ return emit_jump_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
+ else
+ return emit_jump_insn_before_noloc (pattern, before);
+}
+
+/* like emit_insn_before_noloc, but set insn_locator according to scope. */
+rtx
+emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
+{
+ rtx first = PREV_INSN (before);
+ rtx last = emit_call_insn_before_noloc (pattern, before);
+
+ if (pattern == NULL_RTX)
+ return last;
+
+ first = NEXT_INSN (first);
+ while (1)
+ {
+ if (active_insn_p (first) && !INSN_LOCATOR (first))
+ INSN_LOCATOR (first) = loc;
+ if (first == last)
+ break;
+ first = NEXT_INSN (first);
+ }
+ return last;
+}
+
+/* like emit_call_insn_before_noloc,
+ but set insn_locator according to before. */
+rtx
+emit_call_insn_before (rtx pattern, rtx before)
+{
+ if (INSN_P (before))
+ return emit_call_insn_before_setloc (pattern, before, INSN_LOCATOR (before));
+ else
+ return emit_call_insn_before_noloc (pattern, before);
+}
/* Take X and emit it at the end of the doubly-linked
INSN list.
@@ -4480,8 +4637,7 @@ emit_insn_before_scope (pattern, before, scope)
Returns the last insn emitted. */
rtx
-emit_insn (x)
- rtx x;
+emit_insn (rtx x)
{
rtx last = last_insn;
rtx insn;
@@ -4526,8 +4682,7 @@ emit_insn (x)
and add it to the end of the doubly-linked list. */
rtx
-emit_jump_insn (x)
- rtx x;
+emit_jump_insn (rtx x)
{
rtx last = NULL_RTX, insn;
@@ -4568,8 +4723,7 @@ emit_jump_insn (x)
and add it to the end of the doubly-linked list. */
rtx
-emit_call_insn (x)
- rtx x;
+emit_call_insn (rtx x)
{
rtx insn;
@@ -4602,8 +4756,7 @@ emit_call_insn (x)
/* Add the label LABEL to the end of the doubly-linked list. */
rtx
-emit_label (label)
- rtx label;
+emit_label (rtx label)
{
/* This can be called twice for the same label
as a result of the confusion that follows a syntax error!
@@ -4620,7 +4773,7 @@ emit_label (label)
and add it to the end of the doubly-linked list. */
rtx
-emit_barrier ()
+emit_barrier (void)
{
rtx barrier = rtx_alloc (BARRIER);
INSN_UID (barrier) = cur_insn_uid++;
@@ -4628,90 +4781,90 @@ emit_barrier ()
return barrier;
}
-/* Make an insn of code NOTE
- with data-fields specified by FILE and LINE
- and add it to the end of the doubly-linked list,
- but only if line-numbers are desired for debugging info. */
+/* Make line numbering NOTE insn for LOCATION add it to the end
+ of the doubly-linked list, but only if line-numbers are desired for
+ debugging info and it doesn't match the previous one. */
rtx
-emit_line_note (file, line)
- const char *file;
- int line;
+emit_line_note (location_t location)
{
- set_file_and_line_for_stmt (file, line);
-
-#if 0
+ rtx note;
+
+ set_file_and_line_for_stmt (location);
+
+ if (location.file && last_location.file
+ && !strcmp (location.file, last_location.file)
+ && location.line == last_location.line)
+ return NULL_RTX;
+ last_location = location;
+
if (no_line_numbers)
- return 0;
-#endif
+ {
+ cur_insn_uid++;
+ return NULL_RTX;
+ }
- return emit_note (file, line);
+ note = emit_note (location.line);
+ NOTE_SOURCE_FILE (note) = location.file;
+
+ return note;
}
-/* Make an insn of code NOTE
- with data-fields specified by FILE and LINE
- and add it to the end of the doubly-linked list.
- If it is a line-number NOTE, omit it if it matches the previous one. */
+/* Emit a copy of note ORIG. */
rtx
-emit_note (file, line)
- const char *file;
- int line;
+emit_note_copy (rtx orig)
{
rtx note;
-
- if (line > 0)
- {
- if (file && last_filename && !strcmp (file, last_filename)
- && line == last_linenum)
- return 0;
- last_filename = file;
- last_linenum = line;
- }
-
- if (no_line_numbers && line > 0)
+
+ if (NOTE_LINE_NUMBER (orig) >= 0 && no_line_numbers)
{
cur_insn_uid++;
- return 0;
+ return NULL_RTX;
}
-
+
note = rtx_alloc (NOTE);
+
INSN_UID (note) = cur_insn_uid++;
- NOTE_SOURCE_FILE (note) = file;
- NOTE_LINE_NUMBER (note) = line;
+ NOTE_DATA (note) = NOTE_DATA (orig);
+ NOTE_LINE_NUMBER (note) = NOTE_LINE_NUMBER (orig);
BLOCK_FOR_INSN (note) = NULL;
add_insn (note);
+
return note;
}
-/* Emit a NOTE, and don't omit it even if LINE is the previous note. */
+/* Make an insn of code NOTE or type NOTE_NO
+ and add it to the end of the doubly-linked list. */
rtx
-emit_line_note_force (file, line)
- const char *file;
- int line;
+emit_note (int note_no)
{
- last_linenum = -1;
- return emit_line_note (file, line);
+ rtx note;
+
+ note = rtx_alloc (NOTE);
+ INSN_UID (note) = cur_insn_uid++;
+ NOTE_LINE_NUMBER (note) = note_no;
+ memset (&NOTE_DATA (note), 0, sizeof (NOTE_DATA (note)));
+ BLOCK_FOR_INSN (note) = NULL;
+ add_insn (note);
+ return note;
}
/* Cause next statement to emit a line note even if the line number
- has not changed. This is used at the beginning of a function. */
+ has not changed. */
void
-force_next_line_note ()
+force_next_line_note (void)
{
- last_linenum = -1;
+ last_location.line = -1;
}
/* Place a note of KIND on insn INSN with DATUM as the datum. If a
note of this type already exists, remove it first. */
rtx
-set_unique_reg_note (insn, kind, datum)
- rtx insn;
- enum reg_note kind;
- rtx datum;
+set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
{
rtx note = find_reg_note (insn, kind, NULL_RTX);
@@ -4754,8 +4907,7 @@ set_unique_reg_note (insn, kind, datum)
The value is CODE_LABEL, INSN, CALL_INSN or JUMP_INSN. */
enum rtx_code
-classify_insn (x)
- rtx x;
+classify_insn (rtx x)
{
if (GET_CODE (x) == CODE_LABEL)
return CODE_LABEL;
@@ -4792,8 +4944,7 @@ classify_insn (x)
If X is a label, it is simply added into the insn chain. */
rtx
-emit (x)
- rtx x;
+emit (rtx x)
{
enum rtx_code code = classify_insn (x);
@@ -4826,7 +4977,7 @@ static GTY ((deletable (""))) struct sequence_stack *free_sequence_stack;
emitted in the middle of this sequence. */
void
-start_sequence ()
+start_sequence (void)
{
struct sequence_stack *tem;
@@ -4836,7 +4987,7 @@ start_sequence ()
free_sequence_stack = tem->next;
}
else
- tem = (struct sequence_stack *) ggc_alloc (sizeof (struct sequence_stack));
+ tem = ggc_alloc (sizeof (struct sequence_stack));
tem->next = seq_stack;
tem->first = first_insn;
@@ -4854,8 +5005,7 @@ start_sequence ()
information about how to use this function. */
void
-start_sequence_for_rtl_expr (t)
- tree t;
+start_sequence_for_rtl_expr (tree t)
{
start_sequence ();
@@ -4867,8 +5017,7 @@ start_sequence_for_rtl_expr (t)
start_sequence for more information about how to use this function. */
void
-push_to_sequence (first)
- rtx first;
+push_to_sequence (rtx first)
{
rtx last;
@@ -4883,8 +5032,7 @@ push_to_sequence (first)
/* Set up the insn chain from a chain stort in FIRST to LAST. */
void
-push_to_full_sequence (first, last)
- rtx first, last;
+push_to_full_sequence (rtx first, rtx last)
{
start_sequence ();
first_insn = first;
@@ -4898,7 +5046,7 @@ push_to_full_sequence (first, last)
as the current sequence, saving the previously current one. */
void
-push_topmost_sequence ()
+push_topmost_sequence (void)
{
struct sequence_stack *stack, *top = NULL;
@@ -4916,7 +5064,7 @@ push_topmost_sequence ()
insn chain, and restore the previous saved state. */
void
-pop_topmost_sequence ()
+pop_topmost_sequence (void)
{
struct sequence_stack *stack, *top = NULL;
@@ -4944,7 +5092,7 @@ pop_topmost_sequence ()
information about deferred popping of arguments. */
void
-end_sequence ()
+end_sequence (void)
{
struct sequence_stack *tem = seq_stack;
@@ -4962,8 +5110,7 @@ end_sequence ()
and LAST. */
void
-end_full_sequence (first, last)
- rtx *first, *last;
+end_full_sequence (rtx *first, rtx *last)
{
*first = first_insn;
*last = last_insn;
@@ -4973,7 +5120,7 @@ end_full_sequence (first, last)
/* Return 1 if currently emitting into a sequence. */
int
-in_sequence_p ()
+in_sequence_p (void)
{
return seq_stack != 0;
}
@@ -4981,8 +5128,7 @@ in_sequence_p ()
/* Put the various virtual registers into REGNO_REG_RTX. */
void
-init_virtual_regs (es)
- struct emit_status *es;
+init_virtual_regs (struct emit_status *es)
{
rtx *ptr = es->x_regno_reg_rtx;
ptr[VIRTUAL_INCOMING_ARGS_REGNUM] = virtual_incoming_args_rtx;
@@ -5021,8 +5167,7 @@ static rtvec copy_asm_constraints_vector;
SCRATCHes. */
rtx
-copy_insn_1 (orig)
- rtx orig;
+copy_insn_1 (rtx orig)
{
rtx copy;
int i, j;
@@ -5075,7 +5220,7 @@ copy_insn_1 (orig)
all fields need copying, and then clear the fields that should
not be copied. That is the sensible default behavior, and forces
us to explicitly document why we are *not* copying a flag. */
- memcpy (copy, orig, sizeof (struct rtx_def) - sizeof (rtunion));
+ memcpy (copy, orig, RTX_HDR_SIZE);
/* We do not copy the USED flag, which is used as a mark bit during
walks over the RTL. */
@@ -5093,7 +5238,7 @@ copy_insn_1 (orig)
for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
{
- copy->fld[i] = orig->fld[i];
+ copy->u.fld[i] = orig->u.fld[i];
switch (*format_ptr++)
{
case 'e':
@@ -5155,8 +5300,7 @@ copy_insn_1 (orig)
INSN doesn't really have to be a full INSN; it could be just the
pattern. */
rtx
-copy_insn (insn)
- rtx insn;
+copy_insn (rtx insn)
{
copy_insn_n_scratches = 0;
orig_asm_operands_vector = 0;
@@ -5170,18 +5314,18 @@ copy_insn (insn)
before generating rtl for each function. */
void
-init_emit ()
+init_emit (void)
{
struct function *f = cfun;
- f->emit = (struct emit_status *) ggc_alloc (sizeof (struct emit_status));
+ f->emit = ggc_alloc (sizeof (struct emit_status));
first_insn = NULL;
last_insn = NULL;
seq_rtl_expr = NULL;
cur_insn_uid = 1;
reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
- last_linenum = 0;
- last_filename = 0;
+ last_location.line = 0;
+ last_location.file = 0;
first_label_num = label_num;
last_label_num = 0;
seq_stack = NULL;
@@ -5191,16 +5335,11 @@ init_emit ()
f->emit->regno_pointer_align_length = LAST_VIRTUAL_REGISTER + 101;
f->emit->regno_pointer_align
- = (unsigned char *) ggc_alloc_cleared (f->emit->regno_pointer_align_length
- * sizeof (unsigned char));
+ = ggc_alloc_cleared (f->emit->regno_pointer_align_length
+ * sizeof (unsigned char));
regno_reg_rtx
- = (rtx *) ggc_alloc_cleared (f->emit->regno_pointer_align_length
- * sizeof (rtx));
-
- f->emit->regno_decl
- = (tree *) ggc_alloc_cleared (f->emit->regno_pointer_align_length
- * sizeof (tree));
+ = ggc_alloc (f->emit->regno_pointer_align_length * sizeof (rtx));
/* Put copies of all the hard registers into regno_reg_rtx. */
memcpy (regno_reg_rtx,
@@ -5244,8 +5383,7 @@ init_emit ()
/* Generate the constant 0. */
static rtx
-gen_const_vector_0 (mode)
- enum machine_mode mode;
+gen_const_vector_0 (enum machine_mode mode)
{
rtx tem;
rtvec v;
@@ -5271,9 +5409,7 @@ gen_const_vector_0 (mode)
/* Generate a vector like gen_rtx_raw_CONST_VEC, but use the zero vector when
all elements are zero. */
rtx
-gen_rtx_CONST_VECTOR (mode, v)
- enum machine_mode mode;
- rtvec v;
+gen_rtx_CONST_VECTOR (enum machine_mode mode, rtvec v)
{
rtx inner_zero = CONST0_RTX (GET_MODE_INNER (mode));
int i;
@@ -5288,23 +5424,27 @@ gen_rtx_CONST_VECTOR (mode, v)
LINE_NUMBERS is nonzero if line numbers are to be generated. */
void
-init_emit_once (line_numbers)
- int line_numbers;
+init_emit_once (int line_numbers)
{
int i;
enum machine_mode mode;
enum machine_mode double_mode;
+ /* We need reg_raw_mode, so initialize the modes now. */
+ init_reg_modes_once ();
+
/* Initialize the CONST_INT, CONST_DOUBLE, and memory attribute hash
tables. */
- const_int_htab = htab_create (37, const_int_htab_hash,
- const_int_htab_eq, NULL);
+ const_int_htab = htab_create_ggc (37, const_int_htab_hash,
+ const_int_htab_eq, NULL);
- const_double_htab = htab_create (37, const_double_htab_hash,
- const_double_htab_eq, NULL);
+ const_double_htab = htab_create_ggc (37, const_double_htab_hash,
+ const_double_htab_eq, NULL);
- mem_attrs_htab = htab_create (37, mem_attrs_htab_hash,
- mem_attrs_htab_eq, NULL);
+ mem_attrs_htab = htab_create_ggc (37, mem_attrs_htab_hash,
+ mem_attrs_htab_eq, NULL);
+ reg_attrs_htab = htab_create_ggc (37, reg_attrs_htab_hash,
+ reg_attrs_htab_eq, NULL);
no_line_numbers = ! line_numbers;
@@ -5389,9 +5529,24 @@ init_emit_once (line_numbers)
REAL_VALUE_FROM_INT (dconst0, 0, 0, double_mode);
REAL_VALUE_FROM_INT (dconst1, 1, 0, double_mode);
REAL_VALUE_FROM_INT (dconst2, 2, 0, double_mode);
+ REAL_VALUE_FROM_INT (dconst3, 3, 0, double_mode);
+ REAL_VALUE_FROM_INT (dconst10, 10, 0, double_mode);
REAL_VALUE_FROM_INT (dconstm1, -1, -1, double_mode);
+ REAL_VALUE_FROM_INT (dconstm2, -2, -1, double_mode);
+
+ dconsthalf = dconst1;
+ dconsthalf.exp--;
+
+ real_arithmetic (&dconstthird, RDIV_EXPR, &dconst1, &dconst3);
+
+ /* Initialize mathematical constants for constant folding builtins.
+ These constants need to be given to at least 160 bits precision. */
+ real_from_string (&dconstpi,
+ "3.1415926535897932384626433832795028841971693993751058209749445923078");
+ real_from_string (&dconste,
+ "2.7182818284590452353602874713526624977572470936999595749669676277241");
- for (i = 0; i <= 2; i++)
+ for (i = 0; i < (int) ARRAY_SIZE (const_tiny_rtx); i++)
{
REAL_VALUE_TYPE *r =
(i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);
@@ -5436,23 +5591,6 @@ init_emit_once (line_numbers)
= gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM);
#endif
-#ifdef STRUCT_VALUE
- struct_value_rtx = STRUCT_VALUE;
-#else
- struct_value_rtx = gen_rtx_REG (Pmode, STRUCT_VALUE_REGNUM);
-#endif
-
-#ifdef STRUCT_VALUE_INCOMING
- struct_value_incoming_rtx = STRUCT_VALUE_INCOMING;
-#else
-#ifdef STRUCT_VALUE_INCOMING_REGNUM
- struct_value_incoming_rtx
- = gen_rtx_REG (Pmode, STRUCT_VALUE_INCOMING_REGNUM);
-#else
- struct_value_incoming_rtx = struct_value_rtx;
-#endif
-#endif
-
#ifdef STATIC_CHAIN_REGNUM
static_chain_rtx = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
@@ -5475,7 +5613,7 @@ init_emit_once (line_numbers)
#endif
#endif
- if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
+ if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
}
@@ -5484,7 +5622,7 @@ init_emit_once (line_numbers)
warnings about unreachable code. */
int
-force_line_numbers ()
+force_line_numbers (void)
{
int old = no_line_numbers;
@@ -5495,8 +5633,7 @@ force_line_numbers ()
}
void
-restore_line_number_status (old_value)
- int old_value;
+restore_line_number_status (int old_value)
{
no_line_numbers = old_value;
}
@@ -5505,8 +5642,7 @@ restore_line_number_status (old_value)
Care updating of libcall regions if present. */
rtx
-emit_copy_of_insn_after (insn, after)
- rtx insn, after;
+emit_copy_of_insn_after (rtx insn, rtx after)
{
rtx new;
rtx note1, note2, link;
@@ -5537,7 +5673,7 @@ emit_copy_of_insn_after (insn, after)
/* Update LABEL_NUSES. */
mark_jump_label (PATTERN (new), new, 0);
- INSN_SCOPE (new) = INSN_SCOPE (insn);
+ INSN_LOCATOR (new) = INSN_LOCATOR (insn);
/* Copy all REG_NOTES except REG_LABEL since mark_jump_label will
make them. */
@@ -5565,6 +5701,7 @@ emit_copy_of_insn_after (insn, after)
XEXP (note1, 0) = p;
XEXP (note2, 0) = new;
}
+ INSN_CODE (new) = INSN_CODE (insn);
return new;
}
diff --git a/contrib/gcc/errors.c b/contrib/gcc/errors.c
index f3a3e9b76e70..09504d39d863 100644
--- a/contrib/gcc/errors.c
+++ b/contrib/gcc/errors.c
@@ -1,5 +1,6 @@
/* Basic error reporting routines.
- Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -37,14 +38,14 @@ int have_error = 0;
/* Print a warning message - output produced, but there may be problems. */
void
-warning VPARAMS ((const char *format, ...))
+warning (const char *format, ...)
{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
+ va_list ap;
+ va_start (ap, format);
fprintf (stderr, "%s: warning: ", progname);
vfprintf (stderr, format, ap);
- VA_CLOSE (ap);
+ va_end (ap);
fputc('\n', stderr);
}
@@ -52,14 +53,14 @@ warning VPARAMS ((const char *format, ...))
/* Print an error message - we keep going but the output is unusable. */
void
-error VPARAMS ((const char *format, ...))
+error (const char *format, ...)
{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
+ va_list ap;
+ va_start (ap, format);
fprintf (stderr, "%s: ", progname);
vfprintf (stderr, format, ap);
- VA_CLOSE (ap);
+ va_end (ap);
fputc('\n', stderr);
have_error = 1;
@@ -69,14 +70,14 @@ error VPARAMS ((const char *format, ...))
/* Fatal error - terminate execution immediately. Does not return. */
void
-fatal VPARAMS ((const char *format, ...))
+fatal (const char *format, ...)
{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
+ va_list ap;
+ va_start (ap, format);
fprintf (stderr, "%s: ", progname);
vfprintf (stderr, format, ap);
- VA_CLOSE (ap);
+ va_end (ap);
fputc('\n', stderr);
exit (FATAL_EXIT_CODE);
}
@@ -84,14 +85,14 @@ fatal VPARAMS ((const char *format, ...))
/* Similar, but say we got an internal error. */
void
-internal_error VPARAMS ((const char *format, ...))
+internal_error (const char *format, ...)
{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
+ va_list ap;
+ va_start (ap, format);
fprintf (stderr, "%s: Internal error: ", progname);
vfprintf (stderr, format, ap);
- VA_CLOSE (ap);
+ va_end (ap);
fputc ('\n', stderr);
exit (FATAL_EXIT_CODE);
}
@@ -103,8 +104,7 @@ internal_error VPARAMS ((const char *format, ...))
version if for the gen* programs and so needn't handle subdirectories. */
const char *
-trim_filename (name)
- const char *name;
+trim_filename (const char *name)
{
static const char this_file[] = __FILE__;
const char *p = name, *q = this_file;
@@ -114,11 +114,7 @@ trim_filename (name)
p++, q++;
/* Now go backwards until the previous directory separator. */
- while (p > name && p[-1] != DIR_SEPARATOR
-#ifdef DIR_SEPARATOR_2
- && p[-1] != DIR_SEPARATOR_2
-#endif
- )
+ while (p > name && !IS_DIR_SEPARATOR (p[-1]))
p--;
return p;
@@ -128,10 +124,7 @@ trim_filename (name)
This file is used only by build programs, so we're not as polite as
the version in diagnostic.c. */
void
-fancy_abort (file, line, func)
- const char *file;
- int line;
- const char *func;
+fancy_abort (const char *file, int line, const char *func)
{
internal_error ("abort in %s, at %s:%d", func, file, line);
}
diff --git a/contrib/gcc/errors.h b/contrib/gcc/errors.h
index b48f855554f3..9e0bf1e8e01e 100644
--- a/contrib/gcc/errors.h
+++ b/contrib/gcc/errors.h
@@ -1,5 +1,6 @@
/* Basic error reporting routines.
- Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -29,12 +30,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_ERRORS_H
#define GCC_ERRORS_H
-extern void warning PARAMS ((const char *, ...));
-extern void error PARAMS ((const char *, ...));
-extern void fatal PARAMS ((const char *, ...)) ATTRIBUTE_NORETURN;
-extern void internal_error PARAMS ((const char *, ...)) ATTRIBUTE_NORETURN;
-extern const char *trim_filename PARAMS ((const char *));
-extern void fancy_abort PARAMS ((const char *, int, const char *))
+extern void warning (const char *, ...);
+extern void error (const char *, ...);
+extern void fatal (const char *, ...) ATTRIBUTE_NORETURN;
+extern void internal_error (const char *, ...) ATTRIBUTE_NORETURN;
+extern const char *trim_filename (const char *);
+extern void fancy_abort (const char *, int, const char *)
ATTRIBUTE_NORETURN;
extern int have_error;
diff --git a/contrib/gcc/et-forest.c b/contrib/gcc/et-forest.c
index 84594d44365e..62cdd2107d3d 100644
--- a/contrib/gcc/et-forest.c
+++ b/contrib/gcc/et-forest.c
@@ -1,6 +1,6 @@
-/* ET-trees datastructure implementation.
+/* ET-trees data structure implementation.
Contributed by Pavel Nejedly
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the libiberty library.
Libiberty is free software; you can redistribute it and/or
@@ -16,7 +16,7 @@ Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.
+Boston, MA 02111-1307, USA.
The ET-forest structure is described in:
D. D. Sleator and R. E. Tarjan. A data structure for dynamic trees.
@@ -25,656 +25,719 @@ Boston, MA 02111-1307, USA.
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "et-forest.h"
+#include "alloc-pool.h"
-struct et_forest_occurrence;
-typedef struct et_forest_occurrence* et_forest_occurrence_t;
+/* We do not enable this with ENABLE_CHECKING, since it is awfully slow. */
+#undef DEBUG_ET
-/* The ET-forest type. */
-struct et_forest
-{
- /* Linked list of nodes is used to destroy the structure. */
- int nnodes;
-};
+#ifdef DEBUG_ET
+#include "basic-block.h"
+#endif
-/* Single occurrence of node in ET-forest.
- A single node may have multiple occurrences.
- */
-struct et_forest_occurrence
+/* The occurence of a node in the et tree. */
+struct et_occ
{
- /* Parent in the splay-tree. */
- et_forest_occurrence_t parent;
+ struct et_node *of; /* The node. */
+
+ struct et_occ *parent; /* Parent in the splay-tree. */
+ struct et_occ *prev; /* Left son in the splay-tree. */
+ struct et_occ *next; /* Right son in the splay-tree. */
+
+ int depth; /* The depth of the node is the sum of depth
+ fields on the path to the root. */
+ int min; /* The minimum value of the depth in the subtree
+ is obtained by adding sum of depth fields
+ on the path to the root. */
+ struct et_occ *min_occ; /* The occurence in the subtree with the minimal
+ depth. */
+};
- /* Children in the splay-tree. */
- et_forest_occurrence_t left, right;
+static alloc_pool et_nodes;
+static alloc_pool et_occurences;
- /* Counts of vertices in the two splay-subtrees. */
- int count_left, count_right;
+/* Changes depth of OCC to D. */
- /* Next occurrence of this node in the sequence. */
- et_forest_occurrence_t next;
+static inline void
+set_depth (struct et_occ *occ, int d)
+{
+ if (!occ)
+ return;
- /* The node, which this occurrence is of. */
- et_forest_node_t node;
-};
+ occ->min += d - occ->depth;
+ occ->depth = d;
+}
+/* Adds D to the depth of OCC. */
-/* ET-forest node. */
-struct et_forest_node
+static inline void
+set_depth_add (struct et_occ *occ, int d)
{
- et_forest_t forest;
- void *value;
-
- /* First and last occurrence of this node in the sequence. */
- et_forest_occurrence_t first, last;
-};
+ if (!occ)
+ return;
+ occ->min += d;
+ occ->depth += d;
+}
-static et_forest_occurrence_t splay PARAMS ((et_forest_occurrence_t));
-static void remove_all_occurrences PARAMS ((et_forest_node_t));
-static inline et_forest_occurrence_t find_leftmost_node
- PARAMS ((et_forest_occurrence_t));
-static inline et_forest_occurrence_t find_rightmost_node
- PARAMS ((et_forest_occurrence_t));
-static int calculate_value PARAMS ((et_forest_occurrence_t));
+/* Sets prev field of OCC to P. */
-/* Return leftmost node present in the tree roted by OCC. */
-static inline et_forest_occurrence_t
-find_leftmost_node (occ)
- et_forest_occurrence_t occ;
+static inline void
+set_prev (struct et_occ *occ, struct et_occ *t)
{
- while (occ->left)
- occ = occ->left;
+#ifdef DEBUG_ET
+ if (occ == t)
+ abort ();
+#endif
- return occ;
+ occ->prev = t;
+ if (t)
+ t->parent = occ;
}
-/* Return rightmost node present in the tree roted by OCC. */
-static inline et_forest_occurrence_t
-find_rightmost_node (occ)
- et_forest_occurrence_t occ;
+/* Sets next field of OCC to P. */
+
+static inline void
+set_next (struct et_occ *occ, struct et_occ *t)
{
- while (occ->right)
- occ = occ->right;
- return occ;
+#ifdef DEBUG_ET
+ if (occ == t)
+ abort ();
+#endif
+
+ occ->next = t;
+ if (t)
+ t->parent = occ;
}
+/* Recompute minimum for occurence OCC. */
-/* Operation splay for splay tree structure representing ocuurences. */
-static et_forest_occurrence_t
-splay (node)
- et_forest_occurrence_t node;
+static inline void
+et_recomp_min (struct et_occ *occ)
{
- et_forest_occurrence_t parent;
- et_forest_occurrence_t grandparent;
+ struct et_occ *mson = occ->prev;
- while (1)
+ if (!mson
+ || (occ->next
+ && mson->min > occ->next->min))
+ mson = occ->next;
+
+ if (mson && mson->min < 0)
+ {
+ occ->min = mson->min + occ->depth;
+ occ->min_occ = mson->min_occ;
+ }
+ else
{
- parent = node->parent;
+ occ->min = occ->depth;
+ occ->min_occ = occ;
+ }
+}
- if (! parent)
- return node; /* node == root. */
+#ifdef DEBUG_ET
+/* Checks whether neighbourhood of OCC seems sane. */
- grandparent = parent->parent;
+static void
+et_check_occ_sanity (struct et_occ *occ)
+{
+ if (!occ)
+ return;
- if (! grandparent)
- break;
+ if (occ->parent == occ)
+ abort ();
- /* Now there are four possible combinations: */
+ if (occ->prev == occ)
+ abort ();
- if (node == parent->left)
- {
- if (parent == grandparent->left)
- {
- et_forest_occurrence_t node1, node2;
- int count1, count2;
-
- node1 = node->right;
- count1 = node->count_right;
- node2 = parent->right;
- count2 = parent->count_right;
-
- grandparent->left = node2;
- grandparent->count_left = count2;
- if (node2)
- node2->parent = grandparent;
- parent->left = node1;
- parent->count_left = count1;
- if (node1)
- node1->parent = parent;
- parent->right = grandparent;
- parent->count_right = count2 + grandparent->count_right + 1;
- node->right = parent;
- node->count_right = count1 + parent->count_right + 1;
-
- node->parent = grandparent->parent;
- parent->parent = node;
- grandparent->parent = parent;
-
- if (node->parent)
- {
- if (node->parent->left == grandparent)
- node->parent->left = node;
- else
- node->parent->right = node;
- }
- }
- else
- {
- /* parent == grandparent->right && node == parent->left*/
- et_forest_occurrence_t node1, node2;
- int count1, count2;
-
- node1 = node->left;
- count1 = node->count_left;
- node2 = node->right;
- count2 = node->count_right;
-
- grandparent->right = node1;
- grandparent->count_right = count1;
- if (node1)
- node1->parent = grandparent;
- parent->left = node2;
- parent->count_left = count2;
- if (node2)
- node2->parent = parent;
- node->left = grandparent;
- node->count_left = grandparent->count_left + count1 + 1;
- node->right = parent;
- node->count_right = parent->count_right + count2 + 1;
-
- node->parent = grandparent->parent;
- parent->parent = node;
- grandparent->parent = node;
-
- if (node->parent)
- {
- if (node->parent->left == grandparent)
- node->parent->left = node;
- else
- node->parent->right = node;
- }
- }
- }
- else
- {
- /* node == parent->right. */
- if (parent == grandparent->left)
- {
- et_forest_occurrence_t node1, node2;
- int count1, count2;
-
- node1 = node->left;
- count1 = node->count_left;
- node2 = node->right;
- count2 = node->count_right;
-
- parent->right = node1;
- parent->count_right = count1;
- if (node1)
- node1->parent = parent;
- grandparent->left = node2;
- grandparent->count_left = count2;
- if (node2)
- node2->parent = grandparent;
- node->left = parent;
- node->count_left = parent->count_left + count1 + 1;
- node->right = grandparent;
- node->count_right = grandparent->count_right + count2 + 1;
-
- node->parent = grandparent->parent;
- parent->parent = node;
- grandparent->parent = node;
-
- if (node->parent)
- {
- if (node->parent->left == grandparent)
- node->parent->left = node;
- else
- node->parent->right = node;
- }
- }
- else
- {
- /* parent == grandparent->right && node == parent->right*/
- et_forest_occurrence_t node1, node2;
- int count1, count2;
-
- node1 = node->left;
- count1 = node->count_left;
- node2 = parent->left;
- count2 = parent->count_left;
-
- grandparent->right = node2;
- grandparent->count_right = count2;
- if (node2)
- node2->parent = grandparent;
- parent->right = node1;
- parent->count_right = count1;
- if (node1)
- node1->parent = parent;
- parent->left = grandparent;
- parent->count_left = count2 + grandparent->count_left + 1;
- node->left = parent;
- node->count_left = count1 + parent->count_left + 1;
-
- node->parent = grandparent->parent;
- parent->parent = node;
- grandparent->parent = parent;
-
- if (node->parent)
- {
- if (node->parent->left == grandparent)
- node->parent->left = node;
- else
- node->parent->right = node;
- }
- }
- }
-
- }
+ if (occ->next == occ)
+ abort ();
- /* parent == root. */
- /* There are two possible combinations: */
+ if (occ->next && occ->next == occ->prev)
+ abort ();
- if (node == parent->left)
+ if (occ->next)
{
- et_forest_occurrence_t node1;
- int count1;
-
- node1 = node->right;
- count1 = node->count_right;
-
- parent->left = node1;
- parent->count_left = count1;
- if (node1)
- node1->parent = parent;
- node->right = parent;
- node->count_right = parent->count_right + 1 + count1;
- node->parent = parent->parent; /* the same as = 0; */
- parent->parent = node;
-
- if (node->parent)
- {
- if (node->parent->left == parent)
- node->parent->left = node;
- else
- node->parent->right = node;
- }
- }
- else
+ if (occ->next == occ->parent)
+ abort ();
+
+ if (occ->next->parent != occ)
+ abort ();
+ }
+
+ if (occ->prev)
{
- /* node == parent->right. */
- et_forest_occurrence_t node1;
- int count1;
-
- node1 = node->left;
- count1 = node->count_left;
-
- parent->right = node1;
- parent->count_right = count1;
- if (node1)
- node1->parent = parent;
- node->left = parent;
- node->count_left = parent->count_left + 1 + count1;
- node->parent = parent->parent; /* the same as = 0; */
- parent->parent = node;
-
- if (node->parent)
- {
- if (node->parent->left == parent)
- node->parent->left = node;
- else
- node->parent->right = node;
- }
+ if (occ->prev == occ->parent)
+ abort ();
+
+ if (occ->prev->parent != occ)
+ abort ();
}
- return node;
+ if (occ->parent
+ && occ->parent->prev != occ
+ && occ->parent->next != occ)
+ abort ();
}
-/* Remove all occurences of the given node before destroying the node. */
+/* Checks whether tree rooted at OCC is sane. */
+
static void
-remove_all_occurrences (forest_node)
- et_forest_node_t forest_node;
+et_check_sanity (struct et_occ *occ)
{
- et_forest_occurrence_t first = forest_node->first;
- et_forest_occurrence_t last = forest_node->last;
- et_forest_occurrence_t node;
+ et_check_occ_sanity (occ);
+ if (occ->prev)
+ et_check_sanity (occ->prev);
+ if (occ->next)
+ et_check_sanity (occ->next);
+}
- splay (first);
+/* Checks whether tree containing OCC is sane. */
- if (first->left)
- first->left->parent = 0;
- if (first->right)
- first->right->parent = 0;
+static void
+et_check_tree_sanity (struct et_occ *occ)
+{
+ while (occ->parent)
+ occ = occ->parent;
- if (last != first)
- {
- splay (last);
+ et_check_sanity (occ);
+}
- if (last->left)
- last->left->parent = 0;
- if (last->right)
- last->right->parent = 0;
- }
+/* For recording the paths. */
- if (last->right && first->left) /* actually, first->left would suffice. */
- {
- /* Need to join them. */
- et_forest_occurrence_t prev_node, next_node;
-
- prev_node = splay (find_rightmost_node (first->left));
- next_node = splay (find_leftmost_node (last->right));
- /* prev_node and next_node are consecutive occurencies
- of the same node. */
- if (prev_node->next != next_node)
- abort ();
+static int len;
+static void *datas[100000];
+static int depths[100000];
+
+/* Records the path represented by OCC, with depth incremented by DEPTH. */
- prev_node->right = next_node->right;
- prev_node->count_right = next_node->count_right;
- prev_node->next = next_node->next;
- if (prev_node->right)
- prev_node->right->parent = prev_node;
+static int
+record_path_before_1 (struct et_occ *occ, int depth)
+{
+ int mn, m;
- if (prev_node->node->last == next_node)
- prev_node->node->last = prev_node;
+ depth += occ->depth;
+ mn = depth;
- free (next_node);
+ if (occ->prev)
+ {
+ m = record_path_before_1 (occ->prev, depth);
+ if (m < mn)
+ mn = m;
}
- if (first != last)
+ fprintf (stderr, "%d (%d); ", ((basic_block) occ->of->data)->index, depth);
+ depths[len] = depth;
+ datas[len] = occ->of;
+ len++;
+
+ if (occ->next)
{
- node = first->next;
+ m = record_path_before_1 (occ->next, depth);
+ if (m < mn)
+ mn = m;
+ }
- while (node != last)
- {
- et_forest_occurrence_t next_node;
+ if (mn != occ->min + depth - occ->depth)
+ abort ();
- splay (node);
+ return mn;
+}
- if (node->left)
- node->left->parent = 0;
- if (node->right)
- node->right->parent = 0;
+/* Records the path represented by a tree containing OCC. */
- next_node = node->next;
- free (node);
- node = next_node;
- }
- }
+static void
+record_path_before (struct et_occ *occ)
+{
+ while (occ->parent)
+ occ = occ->parent;
- free (first);
- if (first != last)
- free (last);
+ len = 0;
+ record_path_before_1 (occ, 0);
+ fprintf (stderr, "\n");
}
-/* Calculate ET value of the given node. */
-static inline int
-calculate_value (node)
- et_forest_occurrence_t node;
+/* Checks whether the path represented by OCC, with depth incremented by DEPTH,
+ was not changed since the last recording. */
+
+static int
+check_path_after_1 (struct et_occ *occ, int depth)
{
- int value = node->count_left;
+ int mn, m;
+
+ depth += occ->depth;
+ mn = depth;
- while (node->parent)
+ if (occ->next)
{
- if (node == node->parent->right)
- value += node->parent->count_left + 1;
+ m = check_path_after_1 (occ->next, depth);
+ if (m < mn)
+ mn = m;
+ }
+
+ len--;
+ if (depths[len] != depth
+ || datas[len] != occ->of)
+ abort ();
- node = node->parent;
+ if (occ->prev)
+ {
+ m = check_path_after_1 (occ->prev, depth);
+ if (m < mn)
+ mn = m;
}
- return value;
+ if (mn != occ->min + depth - occ->depth)
+ abort ();
+
+ return mn;
}
+/* Checks whether the path represented by a tree containing OCC was
+ not changed since the last recording. */
+static void
+check_path_after (struct et_occ *occ)
+{
+ while (occ->parent)
+ occ = occ->parent;
+
+ check_path_after_1 (occ, 0);
+ if (len != 0)
+ abort ();
+}
+
+#endif
+/* Splay the occurence OCC to the root of the tree. */
-/* Create ET-forest structure. */
-et_forest_t
-et_forest_create ()
+static void
+et_splay (struct et_occ *occ)
{
+ struct et_occ *f, *gf, *ggf;
+ int occ_depth, f_depth, gf_depth;
+
+#ifdef DEBUG_ET
+ record_path_before (occ);
+ et_check_tree_sanity (occ);
+#endif
+
+ while (occ->parent)
+ {
+ occ_depth = occ->depth;
- et_forest_t forest = xmalloc (sizeof (struct et_forest));
+ f = occ->parent;
+ f_depth = f->depth;
- forest->nnodes = 0;
- return forest;
-}
+ gf = f->parent;
+ if (!gf)
+ {
+ set_depth_add (occ, f_depth);
+ occ->min_occ = f->min_occ;
+ occ->min = f->min;
+ if (f->prev == occ)
+ {
+ /* zig */
+ set_prev (f, occ->next);
+ set_next (occ, f);
+ set_depth_add (f->prev, occ_depth);
+ }
+ else
+ {
+ /* zag */
+ set_next (f, occ->prev);
+ set_prev (occ, f);
+ set_depth_add (f->next, occ_depth);
+ }
+ set_depth (f, -occ_depth);
+ occ->parent = NULL;
+
+ et_recomp_min (f);
+#ifdef DEBUG_ET
+ et_check_tree_sanity (occ);
+ check_path_after (occ);
+#endif
+ return;
+ }
-/* Deallocate the structure. */
-void
-et_forest_delete (forest)
- et_forest_t forest;
-{
- if (forest->nnodes)
- abort ();
+ gf_depth = gf->depth;
- free (forest);
-}
+ set_depth_add (occ, f_depth + gf_depth);
+ occ->min_occ = gf->min_occ;
+ occ->min = gf->min;
-/* Create new node with VALUE and return the edge.
- Return NULL when memory allocation failed. */
-et_forest_node_t
-et_forest_add_node (forest, value)
- et_forest_t forest;
- void *value;
-{
- /* Create node with one occurrence. */
- et_forest_node_t node;
- et_forest_occurrence_t occ;
-
- node = xmalloc (sizeof (struct et_forest_node));
- occ = xmalloc (sizeof (struct et_forest_occurrence));
-
- node->first = node->last = occ;
- node->value = value;
- forest->nnodes++;
-
- occ->node = node;
- occ->left = occ->right = occ->parent = 0;
- occ->next = 0;
- occ->count_left = occ->count_right = 0;
- return node;
+ ggf = gf->parent;
+
+ if (gf->prev == f)
+ {
+ if (f->prev == occ)
+ {
+ /* zig zig */
+ set_prev (gf, f->next);
+ set_prev (f, occ->next);
+ set_next (occ, f);
+ set_next (f, gf);
+
+ set_depth (f, -occ_depth);
+ set_depth_add (f->prev, occ_depth);
+ set_depth (gf, -f_depth);
+ set_depth_add (gf->prev, f_depth);
+ }
+ else
+ {
+ /* zag zig */
+ set_prev (gf, occ->next);
+ set_next (f, occ->prev);
+ set_prev (occ, f);
+ set_next (occ, gf);
+
+ set_depth (f, -occ_depth);
+ set_depth_add (f->next, occ_depth);
+ set_depth (gf, -occ_depth - f_depth);
+ set_depth_add (gf->prev, occ_depth + f_depth);
+ }
+ }
+ else
+ {
+ if (f->prev == occ)
+ {
+ /* zig zag */
+ set_next (gf, occ->prev);
+ set_prev (f, occ->next);
+ set_prev (occ, gf);
+ set_next (occ, f);
+
+ set_depth (f, -occ_depth);
+ set_depth_add (f->prev, occ_depth);
+ set_depth (gf, -occ_depth - f_depth);
+ set_depth_add (gf->next, occ_depth + f_depth);
+ }
+ else
+ {
+ /* zag zag */
+ set_next (gf, f->prev);
+ set_next (f, occ->prev);
+ set_prev (occ, f);
+ set_prev (f, gf);
+
+ set_depth (f, -occ_depth);
+ set_depth_add (f->next, occ_depth);
+ set_depth (gf, -f_depth);
+ set_depth_add (gf->next, f_depth);
+ }
+ }
+
+ occ->parent = ggf;
+ if (ggf)
+ {
+ if (ggf->prev == gf)
+ ggf->prev = occ;
+ else
+ ggf->next = occ;
+ }
+
+ et_recomp_min (gf);
+ et_recomp_min (f);
+#ifdef DEBUG_ET
+ et_check_tree_sanity (occ);
+#endif
+ }
+
+#ifdef DEBUG_ET
+ et_check_sanity (occ);
+ check_path_after (occ);
+#endif
}
-/* Add new edge to the tree, return 1 if succesfull.
- 0 indicates that creation of the edge will close the cycle in graph. */
-int
-et_forest_add_edge (forest, parent_node, child_node)
- et_forest_t forest ATTRIBUTE_UNUSED;
- et_forest_node_t parent_node;
- et_forest_node_t child_node;
+/* Create a new et tree occurence of NODE. */
+
+static struct et_occ *
+et_new_occ (struct et_node *node)
{
- et_forest_occurrence_t new_occ, parent_occ, child_occ;
+ struct et_occ *nw;
+
+ if (!et_occurences)
+ et_occurences = create_alloc_pool ("et_occ pool", sizeof (struct et_occ), 300);
+ nw = pool_alloc (et_occurences);
- if (! parent_node || ! child_node)
- abort ();
+ nw->of = node;
+ nw->parent = NULL;
+ nw->prev = NULL;
+ nw->next = NULL;
- parent_occ = parent_node->first;
- child_occ = child_node->first;
+ nw->depth = 0;
+ nw->min_occ = nw;
+ nw->min = 0;
- splay (parent_occ);
- splay (child_occ);
+ return nw;
+}
- if (parent_occ->parent)
- return 0; /* Both child and parent are in the same tree. */
+/* Create a new et tree containing DATA. */
- if (child_occ->left)
- abort (); /* child must be root of its containing tree. */
+struct et_node *
+et_new_tree (void *data)
+{
+ struct et_node *nw;
- new_occ = xmalloc (sizeof (struct et_forest_occurrence));
-
- new_occ->node = parent_node;
- new_occ->left = child_occ;
- new_occ->count_left = child_occ->count_right + 1; /* count_left is 0. */
- new_occ->right = parent_occ->right;
- new_occ->count_right = parent_occ->count_right;
- new_occ->parent = parent_occ;
- new_occ->next = parent_occ->next;
- child_occ->parent = new_occ;
- parent_occ->right = new_occ;
- parent_occ->count_right = new_occ->count_left + new_occ->count_right + 1;
- parent_occ->next = new_occ;
- if (new_occ->right)
- new_occ->right->parent = new_occ;
-
- if (parent_node->last == parent_occ)
- parent_node->last = new_occ;
- return 1;
+ if (!et_nodes)
+ et_nodes = create_alloc_pool ("et_node pool", sizeof (struct et_node), 300);
+ nw = pool_alloc (et_nodes);
+
+ nw->data = data;
+ nw->father = NULL;
+ nw->left = NULL;
+ nw->right = NULL;
+ nw->son = NULL;
+
+ nw->rightmost_occ = et_new_occ (nw);
+ nw->parent_occ = NULL;
+
+ return nw;
}
-/* Remove NODE from the tree and all connected edges. */
+/* Releases et tree T. */
+
void
-et_forest_remove_node (forest, node)
- et_forest_t forest;
- et_forest_node_t node;
+et_free_tree (struct et_node *t)
{
- remove_all_occurrences (node);
- forest->nnodes--;
+ while (t->son)
+ et_split (t->son);
+
+ if (t->father)
+ et_split (t);
- free (node);
+ pool_free (et_occurences, t->rightmost_occ);
+ pool_free (et_nodes, t);
}
-/* Remove edge from the tree, return 1 if sucesfull,
- 0 indicates nonexisting edge. */
-int
-et_forest_remove_edge (forest, parent_node, child_node)
- et_forest_t forest ATTRIBUTE_UNUSED;
- et_forest_node_t parent_node;
- et_forest_node_t child_node;
-{
- et_forest_occurrence_t parent_pre_occ, parent_post_occ;
+/* Sets father of et tree T to FATHER. */
- splay (child_node->first);
+void
+et_set_father (struct et_node *t, struct et_node *father)
+{
+ struct et_node *left, *right;
+ struct et_occ *rmost, *left_part, *new_f_occ, *p;
- if (! child_node->first->left)
- return 0;
+ /* Update the path represented in the splay tree. */
+ new_f_occ = et_new_occ (father);
- parent_pre_occ = find_rightmost_node (child_node->first->left);
- if (parent_pre_occ->node != parent_node)
- abort ();
+ rmost = father->rightmost_occ;
+ et_splay (rmost);
- splay (parent_pre_occ);
- parent_pre_occ->right->parent = 0;
-
- parent_post_occ = parent_pre_occ->next;
- splay (parent_post_occ);
+ left_part = rmost->prev;
- parent_post_occ->left->parent = 0;
+ p = t->rightmost_occ;
+ et_splay (p);
- parent_pre_occ->right = parent_post_occ->right;
- parent_pre_occ->count_right = parent_post_occ->count_right;
- if (parent_post_occ->right)
- parent_post_occ->right->parent = parent_pre_occ;
+ set_prev (new_f_occ, left_part);
+ set_next (new_f_occ, p);
- parent_pre_occ->next = parent_post_occ->next;
+ p->depth++;
+ p->min++;
+ et_recomp_min (new_f_occ);
- if (parent_post_occ == parent_node->last)
- parent_node->last = parent_pre_occ;
+ set_prev (rmost, new_f_occ);
- free (parent_post_occ);
- return 1;
-}
+ if (new_f_occ->min + rmost->depth < rmost->min)
+ {
+ rmost->min = new_f_occ->min + rmost->depth;
+ rmost->min_occ = new_f_occ->min_occ;
+ }
-/* Return the parent of the NODE if any, NULL otherwise. */
-et_forest_node_t
-et_forest_parent (forest, node)
- et_forest_t forest ATTRIBUTE_UNUSED;
- et_forest_node_t node;
-{
- splay (node->first);
+ t->parent_occ = new_f_occ;
- if (node->first->left)
- return find_rightmost_node (node->first->left)->node;
+ /* Update the tree. */
+ t->father = father;
+ right = father->son;
+ if (right)
+ left = right->left;
else
- return 0;
+ left = right = t;
+
+ left->right = t;
+ right->left = t;
+ t->left = left;
+ t->right = right;
+
+ father->son = t;
+
+#ifdef DEBUG_ET
+ et_check_tree_sanity (rmost);
+ record_path_before (rmost);
+#endif
}
+/* Splits the edge from T to its father. */
-/* Return nearest common ancestor of NODE1 and NODE2.
- Return NULL of they are in different trees. */
-et_forest_node_t
-et_forest_common_ancestor (forest, node1, node2)
- et_forest_t forest ATTRIBUTE_UNUSED;
- et_forest_node_t node1;
- et_forest_node_t node2;
+void
+et_split (struct et_node *t)
{
- int value1, value2, max_value;
- et_forest_node_t ancestor;
+ struct et_node *father = t->father;
+ struct et_occ *r, *l, *rmost, *p_occ;
- if (node1 == node2)
- return node1;
-
- if (! node1 || ! node2)
- abort ();
+ /* Update the path represented by the splay tree. */
+ rmost = t->rightmost_occ;
+ et_splay (rmost);
+
+ for (r = rmost->next; r->prev; r = r->prev)
+ continue;
+ et_splay (r);
+
+ r->prev->parent = NULL;
+ p_occ = t->parent_occ;
+ et_splay (p_occ);
+ t->parent_occ = NULL;
+
+ l = p_occ->prev;
+ p_occ->next->parent = NULL;
+
+ set_prev (r, l);
- splay (node1->first);
- splay (node2->first);
+ et_recomp_min (r);
- if (! node1->first->parent) /* The two vertices are in different trees. */
- return 0;
+ et_splay (rmost);
+ rmost->depth = 0;
+ rmost->min = 0;
- value2 = calculate_value (node2->first);
- value1 = calculate_value (node1->first);
+ pool_free (et_occurences, p_occ);
- if (value1 < value2)
+ /* Update the tree. */
+ if (father->son == t)
+ father->son = t->right;
+ if (father->son == t)
+ father->son = NULL;
+ else
+ {
+ t->left->right = t->right;
+ t->right->left = t->left;
+ }
+ t->left = t->right = NULL;
+ t->father = NULL;
+
+#ifdef DEBUG_ET
+ et_check_tree_sanity (rmost);
+ record_path_before (rmost);
+
+ et_check_tree_sanity (r);
+ record_path_before (r);
+#endif
+}
+
+/* Finds the nearest common ancestor of the nodes N1 and N2. */
+
+struct et_node *
+et_nca (struct et_node *n1, struct et_node *n2)
+{
+ struct et_occ *o1 = n1->rightmost_occ, *o2 = n2->rightmost_occ, *om;
+ struct et_occ *l, *r, *ret;
+ int mn;
+
+ if (n1 == n2)
+ return n1;
+
+ et_splay (o1);
+ l = o1->prev;
+ r = o1->next;
+ if (l)
+ l->parent = NULL;
+ if (r)
+ r->parent = NULL;
+ et_splay (o2);
+
+ if (l == o2 || (l && l->parent != NULL))
{
- ancestor = node1;
- max_value = value2;
+ ret = o2->next;
+
+ set_prev (o1, o2);
+ if (r)
+ r->parent = o1;
}
else
{
- ancestor = node2;
- max_value = value1;
+ ret = o2->prev;
+
+ set_next (o1, o2);
+ if (l)
+ l->parent = o1;
}
-
- while (calculate_value (ancestor->last) < max_value)
+
+ if (0 < o2->depth)
+ {
+ om = o1;
+ mn = o1->depth;
+ }
+ else
{
- /* Find parent node. */
- splay (ancestor->first);
- ancestor = find_rightmost_node (ancestor->first->left) ->node;
+ om = o2;
+ mn = o2->depth + o1->depth;
}
- return ancestor;
-}
+#ifdef DEBUG_ET
+ et_check_tree_sanity (o2);
+#endif
-/* Return the value pointer of node set during it's creation. */
-void *
-et_forest_node_value (forest, node)
- et_forest_t forest ATTRIBUTE_UNUSED;
- et_forest_node_t node;
-{
- /* Alloc threading NULL as a special node of the forest. */
- if (!node)
- return NULL;
- return node->value;
+ if (ret && ret->min + o1->depth + o2->depth < mn)
+ return ret->min_occ->of;
+ else
+ return om->of;
}
-/* Find all sons of NODE and store them into ARRAY allocated by the caller.
- Return number of nodes found. */
-int
-et_forest_enumerate_sons (forest, node, array)
- et_forest_t forest ATTRIBUTE_UNUSED;
- et_forest_node_t node;
- et_forest_node_t *array;
+/* Checks whether the node UP is an ancestor of the node DOWN. */
+
+bool
+et_below (struct et_node *down, struct et_node *up)
{
- int n = 0;
- et_forest_occurrence_t occ = node->first, stop = node->last, occ1;
+ struct et_occ *u = up->rightmost_occ, *d = down->rightmost_occ;
+ struct et_occ *l, *r;
+
+ if (up == down)
+ return true;
+
+ et_splay (u);
+ l = u->prev;
+ r = u->next;
+
+ if (!l)
+ return false;
+
+ l->parent = NULL;
- /* Parent is the rightmost node of the left successor.
- Look for all occurences having no right succesor
- and lookup the sons. */
- while (occ != stop)
+ if (r)
+ r->parent = NULL;
+
+ et_splay (d);
+
+ if (l == d || l->parent != NULL)
{
- splay (occ);
- if (occ->right)
- {
- occ1 = find_leftmost_node (occ->right);
- if (occ1->node->first == occ1)
- array[n++] = occ1->node;
- }
- occ = occ->next;
+ if (r)
+ r->parent = u;
+ set_prev (u, d);
+#ifdef DEBUG_ET
+ et_check_tree_sanity (u);
+#endif
+ }
+ else
+ {
+ l->parent = u;
+
+ /* In case O1 and O2 are in two different trees, we must just restore the
+ original state. */
+ if (r && r->parent != NULL)
+ set_next (u, d);
+ else
+ set_next (u, r);
+
+#ifdef DEBUG_ET
+ et_check_tree_sanity (u);
+#endif
+ return false;
}
- return n;
+
+ if (0 >= d->depth)
+ return false;
+
+ return !d->next || d->next->min + d->depth >= 0;
}
diff --git a/contrib/gcc/et-forest.h b/contrib/gcc/et-forest.h
index 8f4290c1193e..833146d61470 100644
--- a/contrib/gcc/et-forest.h
+++ b/contrib/gcc/et-forest.h
@@ -1,5 +1,5 @@
-/* Et-forest data structure implementation.
- Copyright (C) 2002 Free Software Foundation, Inc.
+/* Et-forest data structure implementation.
+ Copyright (C) 2002, 2003 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
@@ -15,33 +15,33 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* This package implements ET forest data structure. Each tree in
+/* This package implements ET forest data structure. Each tree in
the structure maintains a tree structure and offers logarithmic time
for tree operations (insertion and removal of nodes and edges) and
- poly-logarithmic time for nearest common ancesto.
-
- ET tree strores its structue as a sequence of symbols obtained
+ poly-logarithmic time for nearest common ancestor.
+
+ ET tree stores its structure as a sequence of symbols obtained
by dfs(root)
- dfs (node)
+ dfs (node)
{
s = node;
for each child c of node do
s = concat (s, c, node);
return s;
}
-
+
For example for tree
-
+
1
/ | \
2 3 4
/ |
4 5
-
+
the sequence is 1 2 4 2 5 3 1 3 1 4 1.
-
- The sequence is stored in a sligtly modified splay tree.
+
+ The sequence is stored in a slightly modified splay tree.
In order to support various types of node values, a hashtable
is used to convert node values to the internal representation. */
@@ -55,26 +55,28 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
extern "C" {
#endif /* __cplusplus */
-typedef struct et_forest *et_forest_t;
-typedef struct et_forest_node *et_forest_node_t;
-
-extern et_forest_t et_forest_create PARAMS ((void));
-
-extern void et_forest_delete PARAMS ((et_forest_t));
-
-extern et_forest_node_t et_forest_add_node PARAMS ((et_forest_t, void *));
-extern int et_forest_add_edge PARAMS ((et_forest_t, et_forest_node_t,
- et_forest_node_t));
-extern void et_forest_remove_node PARAMS ((et_forest_t, et_forest_node_t));
-extern int et_forest_remove_edge PARAMS ((et_forest_t, et_forest_node_t,
- et_forest_node_t));
-extern et_forest_node_t et_forest_parent PARAMS ((et_forest_t, et_forest_node_t));
-extern et_forest_node_t et_forest_common_ancestor PARAMS ((et_forest_t,
- et_forest_node_t,
- et_forest_node_t));
-extern void * et_forest_node_value PARAMS ((et_forest_t, et_forest_node_t));
-extern int et_forest_enumerate_sons PARAMS ((et_forest_t, et_forest_node_t,
- et_forest_node_t *));
+/* The node representing the node in an et tree. */
+struct et_node
+{
+ void *data; /* The data represented by the node. */
+
+ int dfs_num_in, dfs_num_out; /* Number of the node in the dfs ordering. */
+
+ struct et_node *father; /* Father of the node. */
+ struct et_node *son; /* The first of the sons of the node. */
+ struct et_node *left;
+ struct et_node *right; /* The brothers of the node. */
+
+ struct et_occ *rightmost_occ; /* The rightmost occurence. */
+ struct et_occ *parent_occ; /* The occurence of the parent node. */
+};
+
+struct et_node *et_new_tree (void *data);
+void et_free_tree (struct et_node *);
+void et_set_father (struct et_node *, struct et_node *);
+void et_split (struct et_node *);
+struct et_node *et_nca (struct et_node *, struct et_node *);
+bool et_below (struct et_node *, struct et_node *);
#ifdef __cplusplus
}
diff --git a/contrib/gcc/except.c b/contrib/gcc/except.c
index b6f851bcbfb1..50fd11a2a9be 100644
--- a/contrib/gcc/except.c
+++ b/contrib/gcc/except.c
@@ -1,6 +1,6 @@
/* Implements exception handling.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Mike Stump <mrs@cygnus.com>.
This file is part of GCC.
@@ -49,6 +49,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "flags.h"
@@ -71,6 +73,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm_p.h"
#include "target.h"
#include "langhooks.h"
+#include "cgraph.h"
/* Provide defaults for stuff that may not be defined when using
sjlj exceptions. */
@@ -84,13 +87,13 @@ int flag_non_call_exceptions;
/* Protect cleanup actions with must-not-throw regions, with a call
to the given failure handler. */
-tree (*lang_protect_cleanup_actions) PARAMS ((void));
+tree (*lang_protect_cleanup_actions) (void);
/* Return true if type A catches type B. */
-int (*lang_eh_type_covers) PARAMS ((tree a, tree b));
+int (*lang_eh_type_covers) (tree a, tree b);
/* Map a type to a runtime object to match type. */
-tree (*lang_eh_runtime_type) PARAMS ((tree));
+tree (*lang_eh_runtime_type) (tree);
/* A hash table of label to region number. */
@@ -100,7 +103,7 @@ struct ehl_map_entry GTY(())
struct eh_region *region;
};
-static int call_site_base;
+static GTY(()) int call_site_base;
static GTY ((param_is (union tree_node)))
htab_t type_to_runtime_map;
@@ -186,6 +189,7 @@ struct eh_region GTY(())
struct eh_region_u_fixup {
tree cleanup_exp;
struct eh_region *real_region;
+ bool resolved;
} GTY ((tag ("ERT_FIXUP"))) fixup;
} GTY ((desc ("%0.type"))) u;
@@ -239,7 +243,7 @@ struct eh_status GTY(())
htab_t GTY ((param_is (struct ehl_map_entry))) exception_handler_label_map;
- struct call_site_record * GTY ((length ("%h.call_site_data_used")))
+ struct call_site_record * GTY ((length ("%h.call_site_data_used")))
call_site_data;
int call_site_data_used;
int call_site_data_size;
@@ -253,61 +257,50 @@ struct eh_status GTY(())
};
-static int t2r_eq PARAMS ((const PTR,
- const PTR));
-static hashval_t t2r_hash PARAMS ((const PTR));
-static void add_type_for_runtime PARAMS ((tree));
-static tree lookup_type_for_runtime PARAMS ((tree));
-
-static struct eh_region *expand_eh_region_end PARAMS ((void));
-
-static rtx get_exception_filter PARAMS ((struct function *));
-
-static void collect_eh_region_array PARAMS ((void));
-static void resolve_fixup_regions PARAMS ((void));
-static void remove_fixup_regions PARAMS ((void));
-static void remove_unreachable_regions PARAMS ((rtx));
-static void convert_from_eh_region_ranges_1 PARAMS ((rtx *, int *, int));
-
-static struct eh_region *duplicate_eh_region_1 PARAMS ((struct eh_region *,
- struct inline_remap *));
-static void duplicate_eh_region_2 PARAMS ((struct eh_region *,
- struct eh_region **));
-static int ttypes_filter_eq PARAMS ((const PTR,
- const PTR));
-static hashval_t ttypes_filter_hash PARAMS ((const PTR));
-static int ehspec_filter_eq PARAMS ((const PTR,
- const PTR));
-static hashval_t ehspec_filter_hash PARAMS ((const PTR));
-static int add_ttypes_entry PARAMS ((htab_t, tree));
-static int add_ehspec_entry PARAMS ((htab_t, htab_t,
- tree));
-static void assign_filter_values PARAMS ((void));
-static void build_post_landing_pads PARAMS ((void));
-static void connect_post_landing_pads PARAMS ((void));
-static void dw2_build_landing_pads PARAMS ((void));
+static int t2r_eq (const void *, const void *);
+static hashval_t t2r_hash (const void *);
+static void add_type_for_runtime (tree);
+static tree lookup_type_for_runtime (tree);
+
+static struct eh_region *expand_eh_region_end (void);
+
+static rtx get_exception_filter (struct function *);
+
+static void collect_eh_region_array (void);
+static void resolve_fixup_regions (void);
+static void remove_fixup_regions (void);
+static void remove_unreachable_regions (rtx);
+static void convert_from_eh_region_ranges_1 (rtx *, int *, int);
+
+static struct eh_region *duplicate_eh_region_1 (struct eh_region *,
+ struct inline_remap *);
+static void duplicate_eh_region_2 (struct eh_region *, struct eh_region **);
+static int ttypes_filter_eq (const void *, const void *);
+static hashval_t ttypes_filter_hash (const void *);
+static int ehspec_filter_eq (const void *, const void *);
+static hashval_t ehspec_filter_hash (const void *);
+static int add_ttypes_entry (htab_t, tree);
+static int add_ehspec_entry (htab_t, htab_t, tree);
+static void assign_filter_values (void);
+static void build_post_landing_pads (void);
+static void connect_post_landing_pads (void);
+static void dw2_build_landing_pads (void);
struct sjlj_lp_info;
-static bool sjlj_find_directly_reachable_regions
- PARAMS ((struct sjlj_lp_info *));
-static void sjlj_assign_call_site_values
- PARAMS ((rtx, struct sjlj_lp_info *));
-static void sjlj_mark_call_sites
- PARAMS ((struct sjlj_lp_info *));
-static void sjlj_emit_function_enter PARAMS ((rtx));
-static void sjlj_emit_function_exit PARAMS ((void));
-static void sjlj_emit_dispatch_table
- PARAMS ((rtx, struct sjlj_lp_info *));
-static void sjlj_build_landing_pads PARAMS ((void));
-
-static hashval_t ehl_hash PARAMS ((const PTR));
-static int ehl_eq PARAMS ((const PTR,
- const PTR));
-static void add_ehl_entry PARAMS ((rtx,
- struct eh_region *));
-static void remove_exception_handler_label PARAMS ((rtx));
-static void remove_eh_handler PARAMS ((struct eh_region *));
-static int for_each_eh_label_1 PARAMS ((PTR *, PTR));
+static bool sjlj_find_directly_reachable_regions (struct sjlj_lp_info *);
+static void sjlj_assign_call_site_values (rtx, struct sjlj_lp_info *);
+static void sjlj_mark_call_sites (struct sjlj_lp_info *);
+static void sjlj_emit_function_enter (rtx);
+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 hashval_t ehl_hash (const void *);
+static int ehl_eq (const void *, const void *);
+static void add_ehl_entry (rtx, struct eh_region *);
+static void remove_exception_handler_label (rtx);
+static void remove_eh_handler (struct eh_region *);
+static int for_each_eh_label_1 (void **, void *);
struct reachable_info;
@@ -324,30 +317,26 @@ enum reachable_code
RNL_BLOCKED
};
-static int check_handled PARAMS ((tree, tree));
-static void add_reachable_handler
- PARAMS ((struct reachable_info *, struct eh_region *,
- struct eh_region *));
-static enum reachable_code reachable_next_level
- PARAMS ((struct eh_region *, tree, struct reachable_info *));
-
-static int action_record_eq PARAMS ((const PTR,
- const PTR));
-static hashval_t action_record_hash PARAMS ((const PTR));
-static int add_action_record PARAMS ((htab_t, int, int));
-static int collect_one_action_chain PARAMS ((htab_t,
- struct eh_region *));
-static int add_call_site PARAMS ((rtx, int));
-
-static void push_uleb128 PARAMS ((varray_type *,
- unsigned int));
-static void push_sleb128 PARAMS ((varray_type *, int));
+static int check_handled (tree, tree);
+static void add_reachable_handler (struct reachable_info *,
+ struct eh_region *, struct eh_region *);
+static enum reachable_code reachable_next_level (struct eh_region *, tree,
+ struct reachable_info *);
+
+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 add_call_site (rtx, int);
+
+static void push_uleb128 (varray_type *, unsigned int);
+static void push_sleb128 (varray_type *, int);
#ifndef HAVE_AS_LEB128
-static int dw2_size_of_call_site_table PARAMS ((void));
-static int sjlj_size_of_call_site_table PARAMS ((void));
+static int dw2_size_of_call_site_table (void);
+static int sjlj_size_of_call_site_table (void);
#endif
-static void dw2_output_call_site_table PARAMS ((void));
-static void sjlj_output_call_site_table PARAMS ((void));
+static void dw2_output_call_site_table (void);
+static void sjlj_output_call_site_table (void);
/* Routine to see if exception handling is turned on.
@@ -358,8 +347,7 @@ static void sjlj_output_call_site_table PARAMS ((void));
compiler tries to use any exception-specific functions. */
int
-doing_eh (do_warn)
- int do_warn;
+doing_eh (int do_warn)
{
if (! flag_exceptions)
{
@@ -376,7 +364,7 @@ doing_eh (do_warn)
void
-init_eh ()
+init_eh (void)
{
if (! flag_exceptions)
return;
@@ -424,10 +412,8 @@ init_eh ()
tmp = build_int_2 (FIRST_PSEUDO_REGISTER + 2 - 1, 0);
#endif
#else
- /* This is 2 for builtin_setjmp, plus whatever the target requires
- via STACK_SAVEAREA_MODE (SAVE_NONLOCAL). */
- tmp = build_int_2 ((GET_MODE_SIZE (STACK_SAVEAREA_MODE (SAVE_NONLOCAL))
- / GET_MODE_SIZE (Pmode)) + 2 - 1, 0);
+ /* builtin_setjmp takes a pointer to 5 words. */
+ tmp = build_int_2 (5 * BITS_PER_WORD / POINTER_SIZE - 1, 0);
#endif
tmp = build_index_type (tmp);
tmp = build_array_type (ptr_type_node, tmp);
@@ -470,10 +456,9 @@ init_eh ()
}
void
-init_eh_for_function ()
+init_eh_for_function (void)
{
- cfun->eh = (struct eh_status *)
- ggc_alloc_cleared (sizeof (struct eh_status));
+ cfun->eh = ggc_alloc_cleared (sizeof (struct eh_status));
}
/* Start an exception handling region. All instructions emitted
@@ -481,7 +466,7 @@ init_eh_for_function ()
expand_eh_region_end is invoked. */
void
-expand_eh_region_start ()
+expand_eh_region_start (void)
{
struct eh_region *new_region;
struct eh_region *cur_region;
@@ -491,7 +476,7 @@ expand_eh_region_start ()
return;
/* Insert a new blank region as a leaf in the tree. */
- new_region = (struct eh_region *) ggc_alloc_cleared (sizeof (*new_region));
+ new_region = ggc_alloc_cleared (sizeof (*new_region));
cur_region = cfun->eh->cur_region;
new_region->outer = cur_region;
if (cur_region)
@@ -508,20 +493,20 @@ expand_eh_region_start ()
/* Create a note marking the start of this region. */
new_region->region_number = ++cfun->eh->last_region_number;
- note = emit_note (NULL, NOTE_INSN_EH_REGION_BEG);
+ note = emit_note (NOTE_INSN_EH_REGION_BEG);
NOTE_EH_HANDLER (note) = new_region->region_number;
}
/* Common code to end a region. Returns the region just ended. */
static struct eh_region *
-expand_eh_region_end ()
+expand_eh_region_end (void)
{
struct eh_region *cur_region = cfun->eh->cur_region;
rtx note;
/* Create a note marking the end of this region. */
- note = emit_note (NULL, NOTE_INSN_EH_REGION_END);
+ note = emit_note (NOTE_INSN_EH_REGION_END);
NOTE_EH_HANDLER (note) = cur_region->region_number;
/* Pop. */
@@ -534,8 +519,7 @@ expand_eh_region_end ()
expression to expand for the cleanup. */
void
-expand_eh_region_end_cleanup (handler)
- tree handler;
+expand_eh_region_end_cleanup (tree handler)
{
struct eh_region *region;
tree protect_cleanup_actions;
@@ -601,7 +585,7 @@ expand_eh_region_end_cleanup (handler)
for subsequent calls to expand_start_catch. */
void
-expand_start_all_catch ()
+expand_start_all_catch (void)
{
struct eh_region *region;
@@ -624,8 +608,7 @@ expand_start_all_catch ()
is useful e.g. for Ada. */
void
-expand_start_catch (type_or_list)
- tree type_or_list;
+expand_start_catch (tree type_or_list)
{
struct eh_region *t, *c, *l;
tree type_list;
@@ -672,14 +655,14 @@ expand_start_catch (type_or_list)
/* End a catch clause. Control will resume after the try/catch block. */
void
-expand_end_catch ()
+expand_end_catch (void)
{
- struct eh_region *try_region, *catch_region;
+ struct eh_region *try_region;
if (! doing_eh (0))
return;
- catch_region = expand_eh_region_end ();
+ expand_eh_region_end ();
try_region = cfun->eh->try_region;
emit_jump (try_region->u.try.continue_label);
@@ -688,7 +671,7 @@ expand_end_catch ()
/* End a sequence of catch handlers for a try block. */
void
-expand_end_all_catch ()
+expand_end_all_catch (void)
{
struct eh_region *try_region;
@@ -710,8 +693,7 @@ expand_end_all_catch ()
rethrowing satisfies the "filter" of the catch type. */
void
-expand_eh_region_end_allowed (allowed, failure)
- tree allowed, failure;
+expand_eh_region_end_allowed (tree allowed, tree failure)
{
struct eh_region *region;
rtx around_label;
@@ -753,8 +735,7 @@ expand_eh_region_end_allowed (allowed, failure)
the C++ LSDA. */
void
-expand_eh_region_end_must_not_throw (failure)
- tree failure;
+expand_eh_region_end_must_not_throw (tree failure)
{
struct eh_region *region;
rtx around_label;
@@ -784,8 +765,7 @@ expand_eh_region_end_must_not_throw (failure)
is being thrown. */
void
-expand_eh_region_end_throw (type)
- tree type;
+expand_eh_region_end_throw (tree type)
{
struct eh_region *region;
@@ -808,8 +788,7 @@ expand_eh_region_end_throw (type)
the proper notion of "enclosing" in convert_from_eh_region_ranges. */
void
-expand_eh_region_end_fixup (handler)
- tree handler;
+expand_eh_region_end_fixup (tree handler)
{
struct eh_region *fixup;
@@ -825,7 +804,7 @@ expand_eh_region_end_fixup (handler)
call to a function which itself may contain a throw. */
void
-note_eh_region_may_contain_throw ()
+note_eh_region_may_contain_throw (void)
{
struct eh_region *region;
@@ -841,8 +820,7 @@ note_eh_region_may_contain_throw ()
within a handler. */
rtx
-get_exception_pointer (fun)
- struct function *fun;
+get_exception_pointer (struct function *fun)
{
rtx exc_ptr = fun->eh->exc_ptr;
if (fun == cfun && ! exc_ptr)
@@ -857,8 +835,7 @@ get_exception_pointer (fun)
within a handler. */
static rtx
-get_exception_filter (fun)
- struct function *fun;
+get_exception_filter (struct function *fun)
{
rtx filter = fun->eh->filter;
if (fun == cfun && ! filter)
@@ -876,7 +853,7 @@ get_exception_filter (fun)
without having to realloc memory. */
static void
-collect_eh_region_array ()
+collect_eh_region_array (void)
{
struct eh_region **array, *i;
@@ -912,29 +889,49 @@ collect_eh_region_array ()
}
static void
-resolve_fixup_regions ()
+resolve_one_fixup_region (struct eh_region *fixup)
{
- int i, j, n = cfun->eh->last_region_number;
+ struct eh_region *cleanup, *real;
+ int j, n;
+
+ n = cfun->eh->last_region_number;
+ cleanup = 0;
+
+ for (j = 1; j <= n; ++j)
+ {
+ cleanup = cfun->eh->region_array[j];
+ if (cleanup && cleanup->type == ERT_CLEANUP
+ && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp)
+ break;
+ }
+ if (j > n)
+ abort ();
+
+ real = cleanup->outer;
+ if (real && real->type == ERT_FIXUP)
+ {
+ if (!real->u.fixup.resolved)
+ resolve_one_fixup_region (real);
+ real = real->u.fixup.real_region;
+ }
+
+ fixup->u.fixup.real_region = real;
+ fixup->u.fixup.resolved = true;
+}
+
+static void
+resolve_fixup_regions (void)
+{
+ int i, n = cfun->eh->last_region_number;
for (i = 1; i <= n; ++i)
{
struct eh_region *fixup = cfun->eh->region_array[i];
- struct eh_region *cleanup = 0;
- if (! fixup || fixup->type != ERT_FIXUP)
+ if (!fixup || fixup->type != ERT_FIXUP || fixup->u.fixup.resolved)
continue;
- for (j = 1; j <= n; ++j)
- {
- cleanup = cfun->eh->region_array[j];
- if (cleanup->type == ERT_CLEANUP
- && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp)
- break;
- }
- if (j > n)
- abort ();
-
- fixup->u.fixup.real_region = cleanup->outer;
+ resolve_one_fixup_region (fixup);
}
}
@@ -942,7 +939,7 @@ resolve_fixup_regions ()
we can shuffle pointers and remove them from the tree. */
static void
-remove_fixup_regions ()
+remove_fixup_regions (void)
{
int i;
rtx insn, note;
@@ -1012,8 +1009,7 @@ remove_fixup_regions ()
/* Remove all regions whose labels are not reachable from insns. */
static void
-remove_unreachable_regions (insns)
- rtx insns;
+remove_unreachable_regions (rtx insns)
{
int i, *uid_region_num;
bool *reachable;
@@ -1050,7 +1046,18 @@ remove_unreachable_regions (insns)
}
for (insn = insns; insn; insn = NEXT_INSN (insn))
- reachable[uid_region_num[INSN_UID (insn)]] = true;
+ {
+ reachable[uid_region_num[INSN_UID (insn)]] = true;
+
+ if (GET_CODE (insn) == CALL_INSN
+ && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
+ for (i = 0; i < 3; i++)
+ {
+ rtx sub = XEXP (PATTERN (insn), i);
+ for (; sub ; sub = NEXT_INSN (sub))
+ reachable[uid_region_num[INSN_UID (sub)]] = true;
+ }
+ }
for (i = cfun->eh->last_region_number; i > 0; --i)
{
@@ -1076,10 +1083,7 @@ remove_unreachable_regions (insns)
can_throw instruction in the region. */
static void
-convert_from_eh_region_ranges_1 (pinsns, orig_sp, cur)
- rtx *pinsns;
- int *orig_sp;
- int cur;
+convert_from_eh_region_ranges_1 (rtx *pinsns, int *orig_sp, int cur)
{
int *sp = orig_sp;
rtx insn, next;
@@ -1160,7 +1164,7 @@ convert_from_eh_region_ranges_1 (pinsns, orig_sp, cur)
}
void
-convert_from_eh_region_ranges ()
+convert_from_eh_region_ranges (void)
{
int *stack;
rtx insns;
@@ -1178,15 +1182,13 @@ convert_from_eh_region_ranges ()
}
static void
-add_ehl_entry (label, region)
- rtx label;
- struct eh_region *region;
+add_ehl_entry (rtx label, struct eh_region *region)
{
struct ehl_map_entry **slot, *entry;
LABEL_PRESERVE_P (label) = 1;
- entry = (struct ehl_map_entry *) ggc_alloc (sizeof (*entry));
+ entry = ggc_alloc (sizeof (*entry));
entry->label = label;
entry->region = region;
@@ -1204,7 +1206,7 @@ add_ehl_entry (label, region)
}
void
-find_exception_handler_labels ()
+find_exception_handler_labels (void)
{
int i;
@@ -1245,7 +1247,7 @@ find_exception_handler_labels ()
}
bool
-current_function_has_exception_handlers ()
+current_function_has_exception_handlers (void)
{
int i;
@@ -1263,12 +1265,9 @@ current_function_has_exception_handlers ()
}
static struct eh_region *
-duplicate_eh_region_1 (o, map)
- struct eh_region *o;
- struct inline_remap *map;
+duplicate_eh_region_1 (struct eh_region *o, struct inline_remap *map)
{
- struct eh_region *n
- = (struct eh_region *) ggc_alloc_cleared (sizeof (struct eh_region));
+ struct eh_region *n = ggc_alloc_cleared (sizeof (struct eh_region));
n->region_number = o->region_number + cfun->eh->last_region_number;
n->type = o->type;
@@ -1314,9 +1313,7 @@ duplicate_eh_region_1 (o, map)
}
static void
-duplicate_eh_region_2 (o, n_array)
- struct eh_region *o;
- struct eh_region **n_array;
+duplicate_eh_region_2 (struct eh_region *o, struct eh_region **n_array)
{
struct eh_region *n = n_array[o->region_number];
@@ -1347,9 +1344,7 @@ duplicate_eh_region_2 (o, n_array)
}
int
-duplicate_eh_regions (ifun, map)
- struct function *ifun;
- struct inline_remap *map;
+duplicate_eh_regions (struct function *ifun, struct inline_remap *map)
{
int ifun_last_region_number = ifun->eh->last_region_number;
struct eh_region **n_array, *root, *cur;
@@ -1415,9 +1410,7 @@ duplicate_eh_regions (ifun, map)
static int
-t2r_eq (pentry, pdata)
- const PTR pentry;
- const PTR pdata;
+t2r_eq (const void *pentry, const void *pdata)
{
tree entry = (tree) pentry;
tree data = (tree) pdata;
@@ -1426,16 +1419,14 @@ t2r_eq (pentry, pdata)
}
static hashval_t
-t2r_hash (pentry)
- const PTR pentry;
+t2r_hash (const void *pentry)
{
tree entry = (tree) pentry;
return TYPE_HASH (TREE_PURPOSE (entry));
}
static void
-add_type_for_runtime (type)
- tree type;
+add_type_for_runtime (tree type)
{
tree *slot;
@@ -1449,8 +1440,7 @@ add_type_for_runtime (type)
}
static tree
-lookup_type_for_runtime (type)
- tree type;
+lookup_type_for_runtime (tree type)
{
tree *slot;
@@ -1474,9 +1464,7 @@ struct ttypes_filter GTY(())
(a tree) for a @TTypes type node we are thinking about adding. */
static int
-ttypes_filter_eq (pentry, pdata)
- const PTR pentry;
- const PTR pdata;
+ttypes_filter_eq (const void *pentry, const void *pdata)
{
const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
tree data = (tree) pdata;
@@ -1485,8 +1473,7 @@ ttypes_filter_eq (pentry, pdata)
}
static hashval_t
-ttypes_filter_hash (pentry)
- const PTR pentry;
+ttypes_filter_hash (const void *pentry)
{
const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
return TYPE_HASH (entry->t);
@@ -1498,9 +1485,7 @@ ttypes_filter_hash (pentry)
should put these in some canonical order. */
static int
-ehspec_filter_eq (pentry, pdata)
- const PTR pentry;
- const PTR pdata;
+ehspec_filter_eq (const void *pentry, const void *pdata)
{
const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
const struct ttypes_filter *data = (const struct ttypes_filter *) pdata;
@@ -1511,8 +1496,7 @@ ehspec_filter_eq (pentry, pdata)
/* Hash function for exception specification lists. */
static hashval_t
-ehspec_filter_hash (pentry)
- const PTR pentry;
+ehspec_filter_hash (const void *pentry)
{
const struct ttypes_filter *entry = (const struct ttypes_filter *) pentry;
hashval_t h = 0;
@@ -1527,9 +1511,7 @@ ehspec_filter_hash (pentry)
up the search. Return the filter value to be used. */
static int
-add_ttypes_entry (ttypes_hash, type)
- htab_t ttypes_hash;
- tree type;
+add_ttypes_entry (htab_t ttypes_hash, tree type)
{
struct ttypes_filter **slot, *n;
@@ -1540,7 +1522,7 @@ add_ttypes_entry (ttypes_hash, type)
{
/* Filter value is a 1 based table index. */
- n = (struct ttypes_filter *) xmalloc (sizeof (*n));
+ n = xmalloc (sizeof (*n));
n->t = type;
n->filter = VARRAY_ACTIVE_SIZE (cfun->eh->ttype_data) + 1;
*slot = n;
@@ -1555,10 +1537,7 @@ add_ttypes_entry (ttypes_hash, type)
to speed up the search. Return the filter value to be used. */
static int
-add_ehspec_entry (ehspec_hash, ttypes_hash, list)
- htab_t ehspec_hash;
- htab_t ttypes_hash;
- tree list;
+add_ehspec_entry (htab_t ehspec_hash, htab_t ttypes_hash, tree list)
{
struct ttypes_filter **slot, *n;
struct ttypes_filter dummy;
@@ -1571,7 +1550,7 @@ add_ehspec_entry (ehspec_hash, ttypes_hash, list)
{
/* Filter value is a -1 based byte index into a uleb128 buffer. */
- n = (struct ttypes_filter *) xmalloc (sizeof (*n));
+ n = xmalloc (sizeof (*n));
n->t = list;
n->filter = -(VARRAY_ACTIVE_SIZE (cfun->eh->ehspec_data) + 1);
*slot = n;
@@ -1593,7 +1572,7 @@ add_ehspec_entry (ehspec_hash, ttypes_hash, list)
the same filter value, which saves table space. */
static void
-assign_filter_values ()
+assign_filter_values (void)
{
int i;
htab_t ttypes, ehspec;
@@ -1661,8 +1640,11 @@ assign_filter_values ()
htab_delete (ehspec);
}
+/* Generate the code to actually handle exceptions, which will follow the
+ landing pads. */
+
static void
-build_post_landing_pads ()
+build_post_landing_pads (void)
{
int i;
@@ -1778,7 +1760,7 @@ build_post_landing_pads ()
_Unwind_Resume otherwise. */
static void
-connect_post_landing_pads ()
+connect_post_landing_pads (void)
{
int i;
@@ -1819,7 +1801,7 @@ connect_post_landing_pads ()
static void
-dw2_build_landing_pads ()
+dw2_build_landing_pads (void)
{
int i;
unsigned int j;
@@ -1902,8 +1884,7 @@ struct sjlj_lp_info
};
static bool
-sjlj_find_directly_reachable_regions (lp_info)
- struct sjlj_lp_info *lp_info;
+sjlj_find_directly_reachable_regions (struct sjlj_lp_info *lp_info)
{
rtx insn;
bool found_one = false;
@@ -1951,9 +1932,7 @@ sjlj_find_directly_reachable_regions (lp_info)
}
static void
-sjlj_assign_call_site_values (dispatch_label, lp_info)
- rtx dispatch_label;
- struct sjlj_lp_info *lp_info;
+sjlj_assign_call_site_values (rtx dispatch_label, struct sjlj_lp_info *lp_info)
{
htab_t ar_hash;
int i, index;
@@ -2015,8 +1994,7 @@ sjlj_assign_call_site_values (dispatch_label, lp_info)
}
static void
-sjlj_mark_call_sites (lp_info)
- struct sjlj_lp_info *lp_info;
+sjlj_mark_call_sites (struct sjlj_lp_info *lp_info)
{
int last_call_site = -2;
rtx insn, mem;
@@ -2080,8 +2058,7 @@ sjlj_mark_call_sites (lp_info)
/* Construct the SjLj_Function_Context. */
static void
-sjlj_emit_function_enter (dispatch_label)
- rtx dispatch_label;
+sjlj_emit_function_enter (rtx dispatch_label)
{
rtx fn_begin, fc, mem, seq;
@@ -2100,8 +2077,12 @@ sjlj_emit_function_enter (dispatch_label)
if (cfun->uses_eh_lsda)
{
char buf[20];
+ rtx sym;
+
ASM_GENERATE_INTERNAL_LABEL (buf, "LLSDA", current_function_funcdef_no);
- emit_move_insn (mem, gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
+ sym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
+ SYMBOL_REF_FLAGS (sym) = SYMBOL_FLAG_LOCAL;
+ emit_move_insn (mem, sym);
}
else
emit_move_insn (mem, const0_rtx);
@@ -2114,7 +2095,7 @@ sjlj_emit_function_enter (dispatch_label)
plus_constant (XEXP (fc, 0),
sjlj_fc_jbuf_ofs), Pmode);
- note = emit_note (NULL, NOTE_INSN_EXPECTED_VALUE);
+ note = emit_note (NOTE_INSN_EXPECTED_VALUE);
NOTE_EXPECTED_VALUE (note) = gen_rtx_EQ (VOIDmode, x, const0_rtx);
emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
@@ -2146,14 +2127,13 @@ sjlj_emit_function_enter (dispatch_label)
the call to unwind_sjlj_unregister_libfunc if needed. */
void
-sjlj_emit_function_exit_after (after)
- rtx after;
+sjlj_emit_function_exit_after (rtx after)
{
cfun->eh->sjlj_exit_after = after;
}
static void
-sjlj_emit_function_exit ()
+sjlj_emit_function_exit (void)
{
rtx seq;
@@ -2173,9 +2153,7 @@ sjlj_emit_function_exit ()
}
static void
-sjlj_emit_dispatch_table (dispatch_label, lp_info)
- rtx dispatch_label;
- struct sjlj_lp_info *lp_info;
+sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info)
{
int i, first_reachable;
rtx mem, dispatch, seq, fc;
@@ -2197,12 +2175,12 @@ sjlj_emit_dispatch_table (dispatch_label, lp_info)
dispatch = copy_to_reg (mem);
mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs);
- if (word_mode != Pmode)
+ if (word_mode != ptr_mode)
{
#ifdef POINTERS_EXTEND_UNSIGNED
- mem = convert_memory_address (Pmode, mem);
+ mem = convert_memory_address (ptr_mode, mem);
#else
- mem = convert_to_mode (Pmode, mem, 0);
+ mem = convert_to_mode (ptr_mode, mem, 0);
#endif
}
emit_move_insn (cfun->eh->exc_ptr, mem);
@@ -2238,12 +2216,12 @@ sjlj_emit_dispatch_table (dispatch_label, lp_info)
}
static void
-sjlj_build_landing_pads ()
+sjlj_build_landing_pads (void)
{
struct sjlj_lp_info *lp_info;
- lp_info = (struct sjlj_lp_info *) xcalloc (cfun->eh->last_region_number + 1,
- sizeof (struct sjlj_lp_info));
+ lp_info = xcalloc (cfun->eh->last_region_number + 1,
+ sizeof (struct sjlj_lp_info));
if (sjlj_find_directly_reachable_regions (lp_info))
{
@@ -2266,7 +2244,7 @@ sjlj_build_landing_pads ()
}
void
-finish_eh_generation ()
+finish_eh_generation (void)
{
/* Nothing to do if no regions created. */
if (cfun->eh->region_tree == NULL)
@@ -2308,8 +2286,7 @@ finish_eh_generation ()
}
static hashval_t
-ehl_hash (pentry)
- const PTR pentry;
+ehl_hash (const void *pentry)
{
struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry;
@@ -2319,9 +2296,7 @@ ehl_hash (pentry)
}
static int
-ehl_eq (pentry, pdata)
- const PTR pentry;
- const PTR pdata;
+ehl_eq (const void *pentry, const void *pdata)
{
struct ehl_map_entry *entry = (struct ehl_map_entry *) pentry;
struct ehl_map_entry *data = (struct ehl_map_entry *) pdata;
@@ -2334,8 +2309,7 @@ ehl_eq (pentry, pdata)
/* Remove LABEL from exception_handler_label_map. */
static void
-remove_exception_handler_label (label)
- rtx label;
+remove_exception_handler_label (rtx label)
{
struct ehl_map_entry **slot, tmp;
@@ -2356,8 +2330,7 @@ remove_exception_handler_label (label)
/* Splice REGION from the region tree etc. */
static void
-remove_eh_handler (region)
- struct eh_region *region;
+remove_eh_handler (struct eh_region *region)
{
struct eh_region **pp, **pp_start, *p, *outer, *inner;
rtx lab;
@@ -2446,8 +2419,7 @@ remove_eh_handler (region)
delete the region. */
void
-maybe_remove_eh_handler (label)
- rtx label;
+maybe_remove_eh_handler (rtx label)
{
struct ehl_map_entry **slot, tmp;
struct eh_region *region;
@@ -2485,20 +2457,17 @@ maybe_remove_eh_handler (label)
loop hackery; should not be used by new code. */
void
-for_each_eh_label (callback)
- void (*callback) PARAMS ((rtx));
+for_each_eh_label (void (*callback) (rtx))
{
htab_traverse (cfun->eh->exception_handler_label_map, for_each_eh_label_1,
- (void *)callback);
+ (void *) &callback);
}
static int
-for_each_eh_label_1 (pentry, data)
- PTR *pentry;
- PTR data;
+for_each_eh_label_1 (void **pentry, void *data)
{
struct ehl_map_entry *entry = *(struct ehl_map_entry **)pentry;
- void (*callback) PARAMS ((rtx)) = (void (*) PARAMS ((rtx))) data;
+ void (*callback) (rtx) = *(void (**) (rtx)) data;
(*callback) (entry->label);
return 1;
@@ -2518,8 +2487,7 @@ struct reachable_info GTY(())
base class of TYPE, is in HANDLED. */
static int
-check_handled (handled, type)
- tree handled, type;
+check_handled (tree handled, tree type)
{
tree t;
@@ -2549,10 +2517,7 @@ check_handled (handled, type)
LP_REGION contains the landing pad; REGION is the handler. */
static void
-add_reachable_handler (info, lp_region, region)
- struct reachable_info *info;
- struct eh_region *lp_region;
- struct eh_region *region;
+add_reachable_handler (struct reachable_info *info, struct eh_region *lp_region, struct eh_region *region)
{
if (! info)
return;
@@ -2572,10 +2537,8 @@ add_reachable_handler (info, lp_region, region)
and caught/allowed type information between invocations. */
static enum reachable_code
-reachable_next_level (region, type_thrown, info)
- struct eh_region *region;
- tree type_thrown;
- struct reachable_info *info;
+reachable_next_level (struct eh_region *region, tree type_thrown,
+ struct reachable_info *info)
{
switch (region->type)
{
@@ -2706,7 +2669,7 @@ reachable_next_level (region, type_thrown, info)
return RNL_MAYBE_CAUGHT;
case ERT_CATCH:
- /* Catch regions are handled by their controling try region. */
+ /* Catch regions are handled by their controlling try region. */
return RNL_NOT_CAUGHT;
case ERT_MUST_NOT_THROW:
@@ -2736,8 +2699,7 @@ reachable_next_level (region, type_thrown, info)
reached by a given insn. */
rtx
-reachable_handlers (insn)
- rtx insn;
+reachable_handlers (rtx insn)
{
struct reachable_info info;
struct eh_region *region;
@@ -2788,7 +2750,7 @@ reachable_handlers (insn)
else
region = region->outer;
}
-
+
return info.handlers;
}
@@ -2796,8 +2758,7 @@ reachable_handlers (insn)
within the function. */
bool
-can_throw_internal (insn)
- rtx insn;
+can_throw_internal (rtx insn)
{
struct eh_region *region;
tree type_thrown;
@@ -2857,8 +2818,7 @@ can_throw_internal (insn)
visible outside the function. */
bool
-can_throw_external (insn)
- rtx insn;
+can_throw_external (rtx insn)
{
struct eh_region *region;
tree type_thrown;
@@ -2921,10 +2881,10 @@ can_throw_external (insn)
/* Set current_function_nothrow and cfun->all_throwers_are_sibcalls. */
void
-set_nothrow_function_flags ()
+set_nothrow_function_flags (void)
{
rtx insn;
-
+
current_function_nothrow = 1;
/* Assume cfun->all_throwers_are_sibcalls until we encounter
@@ -2937,7 +2897,7 @@ set_nothrow_function_flags ()
if (! flag_exceptions)
return;
-
+
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (can_throw_external (insn))
{
@@ -2971,7 +2931,7 @@ set_nothrow_function_flags ()
On the SPARC, this means flushing the register windows. */
void
-expand_builtin_unwind_init ()
+expand_builtin_unwind_init (void)
{
/* Set this so all the registers get saved in our frame; we need to be
able to copy the saved values for any registers from frames we unwind. */
@@ -2983,8 +2943,7 @@ expand_builtin_unwind_init ()
}
rtx
-expand_builtin_eh_return_data_regno (arglist)
- tree arglist;
+expand_builtin_eh_return_data_regno (tree arglist)
{
tree which = TREE_VALUE (arglist);
unsigned HOST_WIDE_INT iwhich;
@@ -3013,8 +2972,7 @@ expand_builtin_eh_return_data_regno (arglist)
return the actual address encoded in that value. */
rtx
-expand_builtin_extract_return_addr (addr_tree)
- tree addr_tree;
+expand_builtin_extract_return_addr (tree addr_tree)
{
rtx addr = expand_expr (addr_tree, NULL_RTX, Pmode, 0);
@@ -3046,15 +3004,11 @@ expand_builtin_extract_return_addr (addr_tree)
stack slot so the epilogue will return to that address. */
rtx
-expand_builtin_frob_return_addr (addr_tree)
- tree addr_tree;
+expand_builtin_frob_return_addr (tree addr_tree)
{
rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, 0);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (addr) != Pmode)
- addr = convert_memory_address (Pmode, addr);
-#endif
+ addr = convert_memory_address (Pmode, addr);
#ifdef RETURN_ADDR_OFFSET
addr = force_reg (Pmode, addr);
@@ -3068,18 +3022,14 @@ expand_builtin_frob_return_addr (addr_tree)
exception handler. */
void
-expand_builtin_eh_return (stackadj_tree, handler_tree)
- tree stackadj_tree ATTRIBUTE_UNUSED;
- tree handler_tree;
+expand_builtin_eh_return (tree stackadj_tree ATTRIBUTE_UNUSED,
+ tree handler_tree)
{
rtx tmp;
#ifdef EH_RETURN_STACKADJ_RTX
tmp = expand_expr (stackadj_tree, cfun->eh->ehr_stackadj, VOIDmode, 0);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (tmp) != Pmode)
- tmp = convert_memory_address (Pmode, tmp);
-#endif
+ tmp = convert_memory_address (Pmode, tmp);
if (!cfun->eh->ehr_stackadj)
cfun->eh->ehr_stackadj = copy_to_reg (tmp);
else if (tmp != cfun->eh->ehr_stackadj)
@@ -3087,10 +3037,7 @@ expand_builtin_eh_return (stackadj_tree, handler_tree)
#endif
tmp = expand_expr (handler_tree, cfun->eh->ehr_handler, VOIDmode, 0);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (tmp) != Pmode)
- tmp = convert_memory_address (Pmode, tmp);
-#endif
+ tmp = convert_memory_address (Pmode, tmp);
if (!cfun->eh->ehr_handler)
cfun->eh->ehr_handler = copy_to_reg (tmp);
else if (tmp != cfun->eh->ehr_handler)
@@ -3102,7 +3049,7 @@ expand_builtin_eh_return (stackadj_tree, handler_tree)
}
void
-expand_eh_return ()
+expand_eh_return (void)
{
rtx around_label;
@@ -3140,6 +3087,26 @@ expand_eh_return ()
emit_label (around_label);
}
+
+/* Convert a ptr_mode address ADDR_TREE to a Pmode address controlled by
+ POINTERS_EXTEND_UNSIGNED and return it. */
+
+rtx
+expand_builtin_extend_pointer (tree addr_tree)
+{
+ rtx addr = expand_expr (addr_tree, NULL_RTX, ptr_mode, 0);
+ int extend;
+
+#ifdef POINTERS_EXTEND_UNSIGNED
+ extend = POINTERS_EXTEND_UNSIGNED;
+#else
+ /* The previous EH code did an unsigned extend by default, so we do this also
+ for consistency. */
+ extend = 1;
+#endif
+
+ return convert_modes (word_mode, ptr_mode, addr, extend);
+}
/* In the following functions, we represent entries in the action table
as 1-based indices. Special cases are:
@@ -3160,9 +3127,7 @@ struct action_record
};
static int
-action_record_eq (pentry, pdata)
- const PTR pentry;
- const PTR pdata;
+action_record_eq (const void *pentry, const void *pdata)
{
const struct action_record *entry = (const struct action_record *) pentry;
const struct action_record *data = (const struct action_record *) pdata;
@@ -3170,17 +3135,14 @@ action_record_eq (pentry, pdata)
}
static hashval_t
-action_record_hash (pentry)
- const PTR pentry;
+action_record_hash (const void *pentry)
{
const struct action_record *entry = (const struct action_record *) pentry;
return entry->next * 1009 + entry->filter;
}
static int
-add_action_record (ar_hash, filter, next)
- htab_t ar_hash;
- int filter, next;
+add_action_record (htab_t ar_hash, int filter, int next)
{
struct action_record **slot, *new, tmp;
@@ -3190,7 +3152,7 @@ add_action_record (ar_hash, filter, next)
if ((new = *slot) == NULL)
{
- new = (struct action_record *) xmalloc (sizeof (*new));
+ new = xmalloc (sizeof (*new));
new->offset = VARRAY_ACTIVE_SIZE (cfun->eh->action_record_data) + 1;
new->filter = filter;
new->next = next;
@@ -3211,9 +3173,7 @@ add_action_record (ar_hash, filter, next)
}
static int
-collect_one_action_chain (ar_hash, region)
- htab_t ar_hash;
- struct eh_region *region;
+collect_one_action_chain (htab_t ar_hash, struct eh_region *region)
{
struct eh_region *c;
int next;
@@ -3292,8 +3252,18 @@ collect_one_action_chain (ar_hash, region)
/* An exception specification adds its filter to the
beginning of the chain. */
next = collect_one_action_chain (ar_hash, region->outer);
- return add_action_record (ar_hash, region->u.allowed.filter,
- next < 0 ? 0 : next);
+
+ /* If there is no next action, terminate the chain. */
+ if (next == -1)
+ next = 0;
+ /* If all outer actions are cleanups or must_not_throw,
+ we'll have no action record for it, since we had wanted
+ to encode these states in the call-site record directly.
+ Add a cleanup action to the chain to catch these. */
+ else if (next <= 0)
+ next = add_action_record (ar_hash, 0, 0);
+
+ return add_action_record (ar_hash, region->u.allowed.filter, next);
case ERT_MUST_NOT_THROW:
/* A must-not-throw region with no inner handlers or cleanups
@@ -3314,9 +3284,7 @@ collect_one_action_chain (ar_hash, region)
}
static int
-add_call_site (landing_pad, action)
- rtx landing_pad;
- int action;
+add_call_site (rtx landing_pad, int action)
{
struct call_site_record *data = cfun->eh->call_site_data;
int used = cfun->eh->call_site_data_used;
@@ -3325,8 +3293,7 @@ add_call_site (landing_pad, action)
if (used >= size)
{
size = (size ? size * 2 : 64);
- data = (struct call_site_record *)
- ggc_realloc (data, sizeof (*data) * size);
+ data = ggc_realloc (data, sizeof (*data) * size);
cfun->eh->call_site_data = data;
cfun->eh->call_site_data_size = size;
}
@@ -3344,7 +3311,7 @@ add_call_site (landing_pad, action)
instead to call site entries. */
void
-convert_to_eh_region_ranges ()
+convert_to_eh_region_ranges (void)
{
rtx insn, iter, note;
htab_t ar_hash;
@@ -3468,9 +3435,7 @@ convert_to_eh_region_ranges ()
static void
-push_uleb128 (data_area, value)
- varray_type *data_area;
- unsigned int value;
+push_uleb128 (varray_type *data_area, unsigned int value)
{
do
{
@@ -3484,9 +3449,7 @@ push_uleb128 (data_area, value)
}
static void
-push_sleb128 (data_area, value)
- varray_type *data_area;
- int value;
+push_sleb128 (varray_type *data_area, int value)
{
unsigned char byte;
int more;
@@ -3507,7 +3470,7 @@ push_sleb128 (data_area, value)
#ifndef HAVE_AS_LEB128
static int
-dw2_size_of_call_site_table ()
+dw2_size_of_call_site_table (void)
{
int n = cfun->eh->call_site_data_used;
int size = n * (4 + 4 + 4);
@@ -3523,7 +3486,7 @@ dw2_size_of_call_site_table ()
}
static int
-sjlj_size_of_call_site_table ()
+sjlj_size_of_call_site_table (void)
{
int n = cfun->eh->call_site_data_used;
int size = 0;
@@ -3541,7 +3504,7 @@ sjlj_size_of_call_site_table ()
#endif
static void
-dw2_output_call_site_table ()
+dw2_output_call_site_table (void)
{
const char *const function_start_lab
= IDENTIFIER_POINTER (current_function_func_begin_label);
@@ -3593,7 +3556,7 @@ dw2_output_call_site_table ()
}
static void
-sjlj_output_call_site_table ()
+sjlj_output_call_site_table (void)
{
int n = cfun->eh->call_site_data_used;
int i;
@@ -3614,7 +3577,7 @@ sjlj_output_call_site_table ()
table. */
void
-default_exception_section ()
+default_exception_section (void)
{
if (targetm.have_named_sections)
{
@@ -3638,7 +3601,7 @@ default_exception_section ()
}
void
-output_function_exception_table ()
+output_function_exception_table (void)
{
int tt_format, cs_format, lp_format, i, n;
#ifdef HAVE_AS_LEB128
@@ -3683,7 +3646,7 @@ output_function_exception_table ()
assemble_align (tt_format_size * BITS_PER_UNIT);
}
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LLSDA",
+ (*targetm.asm_out.internal_label) (asm_out_file, "LLSDA",
current_function_funcdef_no);
/* The LSDA header. */
@@ -3797,11 +3760,28 @@ output_function_exception_table ()
rtx value;
if (type == NULL_TREE)
- type = integer_zero_node;
+ value = const0_rtx;
else
- type = lookup_type_for_runtime (type);
+ {
+ struct cgraph_varpool_node *node;
+
+ type = lookup_type_for_runtime (type);
+ value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
+
+ /* Let cgraph know that the rtti decl is used. Not all of the
+ paths below go through assemble_integer, which would take
+ care of this for us. */
+ if (TREE_CODE (type) == ADDR_EXPR)
+ {
+ type = TREE_OPERAND (type, 0);
+ node = cgraph_varpool_node (type);
+ if (node)
+ cgraph_varpool_mark_needed_node (node);
+ }
+ else if (TREE_CODE (type) != INTEGER_CST)
+ abort ();
+ }
- value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
if (tt_format == DW_EH_PE_absptr || tt_format == DW_EH_PE_aligned)
assemble_integer (value, tt_format_size,
tt_format_size * BITS_PER_UNIT, 1);
diff --git a/contrib/gcc/except.h b/contrib/gcc/except.h
index 320552c5b7c5..5093a65059a8 100644
--- a/contrib/gcc/except.h
+++ b/contrib/gcc/except.h
@@ -1,5 +1,5 @@
/* Exception Handling interface routines.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Mike Stump <mrs@cygnus.com>.
@@ -21,11 +21,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#ifndef GCC_VARRAY_H
-struct varray_head_tag;
-#define varray_type struct varray_head_tag *
-#endif
-
struct function;
struct inline_remap;
@@ -38,95 +33,95 @@ struct eh_status;
struct eh_region;
/* Test: is exception handling turned on? */
-extern int doing_eh PARAMS ((int));
+extern int doing_eh (int);
/* Start an exception handling region. All instructions emitted after
this point are considered to be part of the region until an
expand_eh_region_end variant is invoked. */
-extern void expand_eh_region_start PARAMS ((void));
+extern void expand_eh_region_start (void);
/* End an exception handling region for a cleanup. HANDLER is an
expression to expand for the cleanup. */
-extern void expand_eh_region_end_cleanup PARAMS ((tree));
+extern void expand_eh_region_end_cleanup (tree);
/* End an exception handling region for a try block, and prepares
for subsequent calls to expand_start_catch. */
-extern void expand_start_all_catch PARAMS ((void));
+extern void expand_start_all_catch (void);
/* Begin a catch clause. TYPE is an object to be matched by the
runtime, or a list of such objects, or null if this is a catch-all
clause. */
-extern void expand_start_catch PARAMS ((tree));
+extern void expand_start_catch (tree);
/* End a catch clause. Control will resume after the try/catch block. */
-extern void expand_end_catch PARAMS ((void));
+extern void expand_end_catch (void);
/* End a sequence of catch handlers for a try block. */
-extern void expand_end_all_catch PARAMS ((void));
+extern void expand_end_all_catch (void);
/* End an exception region for an exception type filter. ALLOWED is a
TREE_LIST of TREE_VALUE objects to be matched by the runtime.
FAILURE is a function to invoke if a mismatch occurs. */
-extern void expand_eh_region_end_allowed PARAMS ((tree, tree));
+extern void expand_eh_region_end_allowed (tree, tree);
/* End an exception region for a must-not-throw filter. FAILURE is a
function to invoke if an uncaught exception propagates this far. */
-extern void expand_eh_region_end_must_not_throw PARAMS ((tree));
+extern void expand_eh_region_end_must_not_throw (tree);
/* End an exception region for a throw. No handling goes on here,
but it's the easiest way for the front-end to indicate what type
is being thrown. */
-extern void expand_eh_region_end_throw PARAMS ((tree));
+extern void expand_eh_region_end_throw (tree);
/* End a fixup region. Within this region the cleanups for the immediately
enclosing region are _not_ run. This is used for goto cleanup to avoid
destroying an object twice. */
-extern void expand_eh_region_end_fixup PARAMS ((tree));
+extern void expand_eh_region_end_fixup (tree);
/* 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 PARAMS ((void));
+extern void note_eh_region_may_contain_throw (void);
/* 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 PARAMS ((void (*) (rtx)));
+extern void for_each_eh_label (void (*) (rtx));
/* Determine if the given INSN can throw an exception. */
-extern bool can_throw_internal PARAMS ((rtx));
-extern bool can_throw_external PARAMS ((rtx));
+extern bool can_throw_internal (rtx);
+extern bool can_throw_external (rtx);
/* Set current_function_nothrow and cfun->all_throwers_are_sibcalls. */
-extern void set_nothrow_function_flags PARAMS ((void));
+extern void set_nothrow_function_flags (void);
/* After initial rtl generation, call back to finish generating
exception support code. */
-extern void finish_eh_generation PARAMS ((void));
+extern void finish_eh_generation (void);
-extern void init_eh PARAMS ((void));
-extern void init_eh_for_function PARAMS ((void));
+extern void init_eh (void);
+extern void init_eh_for_function (void);
-extern rtx reachable_handlers PARAMS ((rtx));
-extern void maybe_remove_eh_handler PARAMS ((rtx));
+extern rtx reachable_handlers (rtx);
+extern void maybe_remove_eh_handler (rtx);
-extern void convert_from_eh_region_ranges PARAMS ((void));
-extern void convert_to_eh_region_ranges PARAMS ((void));
-extern void find_exception_handler_labels PARAMS ((void));
-extern bool current_function_has_exception_handlers PARAMS ((void));
-extern void output_function_exception_table PARAMS ((void));
+extern void convert_from_eh_region_ranges (void);
+extern void convert_to_eh_region_ranges (void);
+extern void find_exception_handler_labels (void);
+extern bool current_function_has_exception_handlers (void);
+extern void output_function_exception_table (void);
-extern void expand_builtin_unwind_init PARAMS ((void));
-extern rtx expand_builtin_eh_return_data_regno PARAMS ((tree));
-extern rtx expand_builtin_extract_return_addr PARAMS ((tree));
-extern void expand_builtin_init_dwarf_reg_sizes PARAMS ((tree));
-extern rtx expand_builtin_frob_return_addr PARAMS ((tree));
-extern rtx expand_builtin_dwarf_sp_column PARAMS ((void));
-extern void expand_builtin_eh_return PARAMS ((tree, tree));
-extern void expand_eh_return PARAMS ((void));
-extern rtx get_exception_pointer PARAMS ((struct function *));
-extern int duplicate_eh_regions PARAMS ((struct function *,
- struct inline_remap *));
+extern void expand_builtin_unwind_init (void);
+extern rtx expand_builtin_eh_return_data_regno (tree);
+extern rtx expand_builtin_extract_return_addr (tree);
+extern void expand_builtin_init_dwarf_reg_sizes (tree);
+extern rtx expand_builtin_frob_return_addr (tree);
+extern rtx expand_builtin_dwarf_sp_column (void);
+extern void expand_builtin_eh_return (tree, tree);
+extern void expand_eh_return (void);
+extern rtx expand_builtin_extend_pointer (tree);
+extern rtx get_exception_pointer (struct function *);
+extern int duplicate_eh_regions (struct function *, struct inline_remap *);
-extern void sjlj_emit_function_exit_after PARAMS ((rtx));
+extern void sjlj_emit_function_exit_after (rtx);
/* If non-NULL, this is a function that returns an expression to be
@@ -135,31 +130,29 @@ extern void sjlj_emit_function_exit_after PARAMS ((rtx));
during stack unwinding is required to result in a call to
`std::terminate', so the C++ version of this function returns a
CALL_EXPR for `std::terminate'. */
-extern tree (*lang_protect_cleanup_actions) PARAMS ((void));
+extern tree (*lang_protect_cleanup_actions) (void);
/* Return true if type A catches type B. */
-extern int (*lang_eh_type_covers) PARAMS ((tree a, tree b));
+extern int (*lang_eh_type_covers) (tree a, tree b);
/* Map a type to a runtime object to match type. */
-extern tree (*lang_eh_runtime_type) PARAMS ((tree));
-
-#ifndef GCC_VARRAY_H
-#undef varray_type
-#endif
+extern tree (*lang_eh_runtime_type) (tree);
/* Just because the user configured --with-sjlj-exceptions=no doesn't
mean that we can use call frame exceptions. Detect that the target
has appropriate support. */
-#if ! (defined (EH_RETURN_DATA_REGNO) \
+#ifndef MUST_USE_SJLJ_EXCEPTIONS
+# if !(defined (EH_RETURN_DATA_REGNO) \
&& (defined (IA64_UNWIND_INFO) \
|| (DWARF2_UNWIND_INFO \
&& (defined (EH_RETURN_HANDLER_RTX) \
|| defined (HAVE_eh_return)))))
-#define MUST_USE_SJLJ_EXCEPTIONS 1
-#else
-#define MUST_USE_SJLJ_EXCEPTIONS 0
+# define MUST_USE_SJLJ_EXCEPTIONS 1
+# else
+# define MUST_USE_SJLJ_EXCEPTIONS 0
+# endif
#endif
#ifdef CONFIG_SJLJ_EXCEPTIONS
diff --git a/contrib/gcc/explow.c b/contrib/gcc/explow.c
index 0d9139a466b2..c1de4c85d22c 100644
--- a/contrib/gcc/explow.c
+++ b/contrib/gcc/explow.c
@@ -1,6 +1,6 @@
/* Subroutines for manipulating rtx's in semantically interesting ways.
Copyright (C) 1987, 1991, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "tree.h"
@@ -36,16 +38,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "recog.h"
#include "langhooks.h"
-static rtx break_out_memory_refs PARAMS ((rtx));
-static void emit_stack_probe PARAMS ((rtx));
+static rtx break_out_memory_refs (rtx);
+static void emit_stack_probe (rtx);
/* Truncate and perhaps sign-extend C as appropriate for MODE. */
HOST_WIDE_INT
-trunc_int_for_mode (c, mode)
- HOST_WIDE_INT c;
- enum machine_mode mode;
+trunc_int_for_mode (HOST_WIDE_INT c, enum machine_mode mode)
{
int width = GET_MODE_BITSIZE (mode);
@@ -76,9 +76,7 @@ trunc_int_for_mode (c, mode)
This function should be used via the `plus_constant' macro. */
rtx
-plus_constant_wide (x, c)
- rtx x;
- HOST_WIDE_INT c;
+plus_constant_wide (rtx x, HOST_WIDE_INT c)
{
RTX_CODE code;
rtx y;
@@ -204,9 +202,7 @@ plus_constant_wide (x, c)
it is not isomorphic to X. */
rtx
-eliminate_constant_term (x, constptr)
- rtx x;
- rtx *constptr;
+eliminate_constant_term (rtx x, rtx *constptr)
{
rtx x0, x1;
rtx tem;
@@ -239,61 +235,14 @@ eliminate_constant_term (x, constptr)
return x;
}
-/* Returns the insn that next references REG after INSN, or 0
- if REG is clobbered before next referenced or we cannot find
- an insn that references REG in a straight-line piece of code. */
-
-rtx
-find_next_ref (reg, insn)
- rtx reg;
- rtx insn;
-{
- rtx next;
-
- for (insn = NEXT_INSN (insn); insn; insn = next)
- {
- next = NEXT_INSN (insn);
- if (GET_CODE (insn) == NOTE)
- continue;
- if (GET_CODE (insn) == CODE_LABEL
- || GET_CODE (insn) == BARRIER)
- return 0;
- if (GET_CODE (insn) == INSN
- || GET_CODE (insn) == JUMP_INSN
- || GET_CODE (insn) == CALL_INSN)
- {
- if (reg_set_p (reg, insn))
- return 0;
- if (reg_mentioned_p (reg, PATTERN (insn)))
- return insn;
- if (GET_CODE (insn) == JUMP_INSN)
- {
- if (any_uncondjump_p (insn))
- next = JUMP_LABEL (insn);
- else
- return 0;
- }
- if (GET_CODE (insn) == CALL_INSN
- && REGNO (reg) < FIRST_PSEUDO_REGISTER
- && call_used_regs[REGNO (reg)])
- return 0;
- }
- else
- abort ();
- }
- return 0;
-}
-
/* Return an rtx for the size in bytes of the value of EXP. */
rtx
-expr_size (exp)
- tree exp;
+expr_size (tree exp)
{
tree size = (*lang_hooks.expr_size) (exp);
- if (TREE_CODE (size) != INTEGER_CST
- && contains_placeholder_p (size))
+ if (CONTAINS_PLACEHOLDER_P (size))
size = build (WITH_RECORD_EXPR, sizetype, size, exp);
return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), 0);
@@ -303,8 +252,7 @@ expr_size (exp)
if the size can vary or is larger than an integer. */
HOST_WIDE_INT
-int_expr_size (exp)
- tree exp;
+int_expr_size (tree exp)
{
tree t = (*lang_hooks.expr_size) (exp);
@@ -336,8 +284,7 @@ int_expr_size (exp)
Values returned by expand_expr with 1 for sum_ok fit this constraint. */
static rtx
-break_out_memory_refs (x)
- rtx x;
+break_out_memory_refs (rtx x)
{
if (GET_CODE (x) == MEM
|| (CONSTANT_P (x) && CONSTANT_ADDRESS_P (x)
@@ -356,8 +303,6 @@ break_out_memory_refs (x)
return x;
}
-#ifdef POINTERS_EXTEND_UNSIGNED
-
/* Given X, a memory address in ptr_mode, convert it to an address
in Pmode, or vice versa (TO_MODE says which way). We take advantage of
the fact that pointers are not allowed to overflow by commuting arithmetic
@@ -365,14 +310,22 @@ break_out_memory_refs (x)
used. */
rtx
-convert_memory_address (to_mode, x)
- enum machine_mode to_mode;
- rtx x;
+convert_memory_address (enum machine_mode to_mode ATTRIBUTE_UNUSED,
+ rtx x)
{
- enum machine_mode from_mode = to_mode == ptr_mode ? Pmode : ptr_mode;
+#ifndef POINTERS_EXTEND_UNSIGNED
+ return x;
+#else /* defined(POINTERS_EXTEND_UNSIGNED) */
+ enum machine_mode from_mode;
rtx temp;
enum rtx_code code;
+ /* If X already has the right mode, just return it. */
+ if (GET_MODE (x) == to_mode)
+ return x;
+
+ from_mode = to_mode == ptr_mode ? Pmode : ptr_mode;
+
/* Here we handle some special cases. If none of them apply, fall through
to the default case. */
switch (GET_CODE (x))
@@ -436,8 +389,8 @@ convert_memory_address (to_mode, x)
return convert_modes (to_mode, from_mode,
x, POINTERS_EXTEND_UNSIGNED);
+#endif /* defined(POINTERS_EXTEND_UNSIGNED) */
}
-#endif
/* Given a memory address or facsimile X, construct a new address,
currently equivalent, that is stable: future stores won't change it.
@@ -453,8 +406,7 @@ convert_memory_address (to_mode, x)
but then you wouldn't get indexed addressing in the reference. */
rtx
-copy_all_regs (x)
- rtx x;
+copy_all_regs (rtx x)
{
if (GET_CODE (x) == REG)
{
@@ -483,21 +435,16 @@ copy_all_regs (x)
works by copying X or subexpressions of it into registers. */
rtx
-memory_address (mode, x)
- enum machine_mode mode;
- rtx x;
+memory_address (enum machine_mode mode, rtx x)
{
rtx oldx = x;
if (GET_CODE (x) == ADDRESSOF)
return x;
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (x) != Pmode)
- x = convert_memory_address (Pmode, x);
-#endif
+ x = convert_memory_address (Pmode, x);
- /* By passing constant addresses thru registers
+ /* By passing constant addresses through registers
we get a chance to cse them. */
if (! cse_not_expected && CONSTANT_P (x) && CONSTANT_ADDRESS_P (x))
x = force_reg (Pmode, x);
@@ -613,9 +560,7 @@ memory_address (mode, x)
/* Like `memory_address' but pretend `flag_force_addr' is 0. */
rtx
-memory_address_noforce (mode, x)
- enum machine_mode mode;
- rtx x;
+memory_address_noforce (enum machine_mode mode, rtx x)
{
int ambient_force_addr = flag_force_addr;
rtx val;
@@ -630,8 +575,7 @@ memory_address_noforce (mode, x)
Pass through anything else unchanged. */
rtx
-validize_mem (ref)
- rtx ref;
+validize_mem (rtx ref)
{
if (GET_CODE (ref) != MEM)
return ref;
@@ -648,28 +592,17 @@ validize_mem (ref)
appropriate. */
void
-maybe_set_unchanging (ref, t)
- rtx ref;
- tree t;
+maybe_set_unchanging (rtx ref, tree t)
{
/* We can set RTX_UNCHANGING_P from TREE_READONLY for decls whose
initialization is only executed once, or whose initializer always
has the same value. Currently we simplify this to PARM_DECLs in the
- first case, and decls with TREE_CONSTANT initializers in the second.
-
- We cannot do this for non-static aggregates, because of the double
- writes that can be generated by store_constructor, depending on the
- contents of the initializer. Yes, this does eliminate a good fraction
- of the number of uses of RTX_UNCHANGING_P for a language like Ada.
- It also eliminates a good quantity of bugs. Let this be incentive to
- eliminate RTX_UNCHANGING_P entirely in favour of a more reliable
- solution, perhaps based on alias sets. */
+ first case, and decls with TREE_CONSTANT initializers in the second. */
if ((TREE_READONLY (t) && DECL_P (t)
- && (TREE_STATIC (t) || ! AGGREGATE_TYPE_P (TREE_TYPE (t)))
- && (TREE_CODE (t) == PARM_DECL
- || DECL_INITIAL (t) == NULL_TREE
- || TREE_CONSTANT (DECL_INITIAL (t))))
+ && (DECL_EXTERNAL (t)
+ || TREE_CODE (t) == PARM_DECL
+ || (DECL_INITIAL (t) && TREE_CONSTANT (DECL_INITIAL (t)))))
|| TREE_CODE_CLASS (TREE_CODE (t)) == 'c')
RTX_UNCHANGING_P (ref) = 1;
}
@@ -680,10 +613,8 @@ maybe_set_unchanging (ref, t)
Perhaps even if it is a MEM, if there is no need to change it. */
rtx
-stabilize (x)
- rtx x;
+stabilize (rtx x)
{
-
if (GET_CODE (x) != MEM
|| ! rtx_unstable_p (XEXP (x, 0)))
return x;
@@ -695,8 +626,7 @@ stabilize (x)
/* Copy the value or contents of X to a new temp reg and return that reg. */
rtx
-copy_to_reg (x)
- rtx x;
+copy_to_reg (rtx x)
{
rtx temp = gen_reg_rtx (GET_MODE (x));
@@ -715,8 +645,7 @@ copy_to_reg (x)
in case X is a constant. */
rtx
-copy_addr_to_reg (x)
- rtx x;
+copy_addr_to_reg (rtx x)
{
return copy_to_mode_reg (Pmode, x);
}
@@ -725,9 +654,7 @@ copy_addr_to_reg (x)
in case X is a constant. */
rtx
-copy_to_mode_reg (mode, x)
- enum machine_mode mode;
- rtx x;
+copy_to_mode_reg (enum machine_mode mode, rtx x)
{
rtx temp = gen_reg_rtx (mode);
@@ -752,9 +679,7 @@ copy_to_mode_reg (mode, x)
since we mark it as a "constant" register. */
rtx
-force_reg (mode, x)
- enum machine_mode mode;
- rtx x;
+force_reg (enum machine_mode mode, rtx x)
{
rtx temp, insn, set;
@@ -784,7 +709,8 @@ force_reg (mode, x)
if INSN set something else (such as a SUBREG of TEMP). */
if (CONSTANT_P (x)
&& (set = single_set (insn)) != 0
- && SET_DEST (set) == temp)
+ && SET_DEST (set) == temp
+ && ! rtx_equal_p (x, SET_SRC (set)))
set_unique_reg_note (insn, REG_EQUAL, x);
return temp;
@@ -794,8 +720,7 @@ force_reg (mode, x)
that reg. Otherwise, return X. */
rtx
-force_not_mem (x)
- rtx x;
+force_not_mem (rtx x)
{
rtx temp;
@@ -812,9 +737,7 @@ force_not_mem (x)
MODE is the mode to use for X in case it is a constant. */
rtx
-copy_to_suggested_reg (x, target, mode)
- rtx x, target;
- enum machine_mode mode;
+copy_to_suggested_reg (rtx x, rtx target, enum machine_mode mode)
{
rtx temp;
@@ -834,11 +757,8 @@ copy_to_suggested_reg (x, target, mode)
FOR_CALL is nonzero if this call is promoting args for a call. */
enum machine_mode
-promote_mode (type, mode, punsignedp, for_call)
- tree type;
- enum machine_mode mode;
- int *punsignedp;
- int for_call ATTRIBUTE_UNUSED;
+promote_mode (tree type, enum machine_mode mode, int *punsignedp,
+ int for_call ATTRIBUTE_UNUSED)
{
enum tree_code code = TREE_CODE (type);
int unsignedp = *punsignedp;
@@ -877,8 +797,7 @@ promote_mode (type, mode, punsignedp, for_call)
This pops when ADJUST is positive. ADJUST need not be constant. */
void
-adjust_stack (adjust)
- rtx adjust;
+adjust_stack (rtx adjust)
{
rtx temp;
adjust = protect_from_queue (adjust, 0);
@@ -908,8 +827,7 @@ adjust_stack (adjust)
This pushes when ADJUST is positive. ADJUST need not be constant. */
void
-anti_adjust_stack (adjust)
- rtx adjust;
+anti_adjust_stack (rtx adjust)
{
rtx temp;
adjust = protect_from_queue (adjust, 0);
@@ -939,15 +857,17 @@ anti_adjust_stack (adjust)
by this machine. SIZE is the desired size, which need not be constant. */
rtx
-round_push (size)
- rtx size;
+round_push (rtx size)
{
int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
+
if (align == 1)
return size;
+
if (GET_CODE (size) == CONST_INT)
{
- int new = (INTVAL (size) + align - 1) / align * align;
+ HOST_WIDE_INT new = (INTVAL (size) + align - 1) / align * align;
+
if (INTVAL (size) != new)
size = GEN_INT (new);
}
@@ -962,6 +882,7 @@ round_push (size)
NULL_RTX, 1);
size = expand_mult (Pmode, size, GEN_INT (align), NULL_RTX, 1);
}
+
return size;
}
@@ -974,14 +895,11 @@ round_push (size)
are emitted at the current position. */
void
-emit_stack_save (save_level, psave, after)
- enum save_level save_level;
- rtx *psave;
- rtx after;
+emit_stack_save (enum save_level save_level, rtx *psave, rtx after)
{
rtx sa = *psave;
/* The default is that we use a move insn and save in a Pmode object. */
- rtx (*fcn) PARAMS ((rtx, rtx)) = gen_move_insn;
+ rtx (*fcn) (rtx, rtx) = gen_move_insn;
enum machine_mode mode = STACK_SAVEAREA_MODE (save_level);
/* See if this machine has anything special to do for this kind of save. */
@@ -1057,13 +975,10 @@ emit_stack_save (save_level, psave, after)
current position. */
void
-emit_stack_restore (save_level, sa, after)
- enum save_level save_level;
- rtx after;
- rtx sa;
+emit_stack_restore (enum save_level save_level, rtx sa, rtx after)
{
/* The default is that we use a move insn. */
- rtx (*fcn) PARAMS ((rtx, rtx)) = gen_move_insn;
+ rtx (*fcn) (rtx, rtx) = gen_move_insn;
/* See if this machine has anything special to do for this kind of save. */
switch (save_level)
@@ -1097,7 +1012,7 @@ emit_stack_restore (save_level, sa, after)
references to variable arrays below the code
that deletes (pops) the arrays. */
emit_insn (gen_rtx_CLOBBER (VOIDmode,
- gen_rtx_MEM (BLKmode,
+ gen_rtx_MEM (BLKmode,
gen_rtx_SCRATCH (VOIDmode))));
emit_insn (gen_rtx_CLOBBER (VOIDmode,
gen_rtx_MEM (BLKmode, stack_pointer_rtx)));
@@ -1124,8 +1039,7 @@ emit_stack_restore (save_level, sa, after)
frame, thus causing a crash if a longjmp unwinds to it. */
void
-optimize_save_area_alloca (insns)
- rtx insns;
+optimize_save_area_alloca (rtx insns)
{
rtx insn;
@@ -1209,10 +1123,7 @@ optimize_save_area_alloca (insns)
KNOWN_ALIGN is the alignment (in bits) that we know SIZE has. */
rtx
-allocate_dynamic_stack_space (size, target, known_align)
- rtx size;
- rtx target;
- int known_align;
+allocate_dynamic_stack_space (rtx size, rtx target, int known_align)
{
#ifdef SETJMP_VIA_SAVE_AREA
rtx setjmpless_size = NULL_RTX;
@@ -1373,7 +1284,7 @@ allocate_dynamic_stack_space (size, target, known_align)
pred = insn_data[(int) CODE_FOR_allocate_stack].operand[1].predicate;
if (pred && ! ((*pred) (size, mode)))
- size = copy_to_mode_reg (mode, size);
+ size = copy_to_mode_reg (mode, convert_to_mode (mode, size, 1));
emit_insn (gen_allocate_stack (target, size));
}
@@ -1443,13 +1354,6 @@ allocate_dynamic_stack_space (size, target, known_align)
NULL_RTX, 1);
}
- /* Some systems require a particular insn to refer to the stack
- to make the pages exist. */
-#ifdef HAVE_probe
- if (HAVE_probe)
- emit_insn (gen_probe ());
-#endif
-
/* Record the new stack level for nonlocal gotos. */
if (nonlocal_goto_handler_slots != 0)
emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
@@ -1464,8 +1368,7 @@ allocate_dynamic_stack_space (size, target, known_align)
static GTY(()) rtx stack_check_libfunc;
void
-set_stack_check_libfunc (libfunc)
- rtx libfunc;
+set_stack_check_libfunc (rtx libfunc)
{
stack_check_libfunc = libfunc;
}
@@ -1473,8 +1376,7 @@ set_stack_check_libfunc (libfunc)
/* Emit one stack probe at ADDRESS, an address within the stack. */
static void
-emit_stack_probe (address)
- rtx address;
+emit_stack_probe (rtx address)
{
rtx memref = gen_rtx_MEM (word_mode, address);
@@ -1499,9 +1401,7 @@ emit_stack_probe (address)
#endif
void
-probe_stack_range (first, size)
- HOST_WIDE_INT first;
- rtx size;
+probe_stack_range (HOST_WIDE_INT first, rtx size)
{
/* First ensure SIZE is Pmode. */
if (GET_MODE (size) != VOIDmode && GET_MODE (size) != Pmode)
@@ -1516,11 +1416,7 @@ probe_stack_range (first, size)
stack_pointer_rtx,
plus_constant (size, first)));
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (addr) != ptr_mode)
- addr = convert_memory_address (ptr_mode, addr);
-#endif
-
+ addr = convert_memory_address (ptr_mode, addr);
emit_library_call (stack_check_libfunc, LCT_NORMAL, VOIDmode, 1, addr,
ptr_mode);
}
@@ -1591,13 +1487,13 @@ probe_stack_range (first, size)
|| REGNO (test_addr) < FIRST_PSEUDO_REGISTER)
test_addr = force_reg (Pmode, test_addr);
- emit_note (NULL, NOTE_INSN_LOOP_BEG);
+ emit_note (NOTE_INSN_LOOP_BEG);
emit_jump (test_lab);
emit_label (loop_lab);
emit_stack_probe (test_addr);
- emit_note (NULL, NOTE_INSN_LOOP_CONT);
+ emit_note (NOTE_INSN_LOOP_CONT);
#ifdef STACK_GROWS_DOWNWARD
#define CMP_OPCODE GTU
@@ -1616,7 +1512,7 @@ probe_stack_range (first, size)
emit_cmp_and_jump_insns (test_addr, last_addr, CMP_OPCODE,
NULL_RTX, Pmode, 1, loop_lab);
emit_jump (end_lab);
- emit_note (NULL, NOTE_INSN_LOOP_END);
+ emit_note (NOTE_INSN_LOOP_END);
emit_label (end_lab);
emit_stack_probe (last_addr);
@@ -1633,10 +1529,8 @@ probe_stack_range (first, size)
and 0 otherwise. */
rtx
-hard_function_value (valtype, func, outgoing)
- tree valtype;
- tree func ATTRIBUTE_UNUSED;
- int outgoing ATTRIBUTE_UNUSED;
+hard_function_value (tree valtype, tree func ATTRIBUTE_UNUSED,
+ int outgoing ATTRIBUTE_UNUSED)
{
rtx val;
@@ -1679,8 +1573,7 @@ hard_function_value (valtype, func, outgoing)
in which a scalar value of mode MODE was returned by a library call. */
rtx
-hard_libcall_value (mode)
- enum machine_mode mode;
+hard_libcall_value (enum machine_mode mode)
{
return LIBCALL_VALUE (mode);
}
@@ -1691,8 +1584,7 @@ hard_libcall_value (mode)
what `enum tree_code' means. */
int
-rtx_to_tree_code (code)
- enum rtx_code code;
+rtx_to_tree_code (enum rtx_code code)
{
enum tree_code tcode;
diff --git a/contrib/gcc/expmed.c b/contrib/gcc/expmed.c
index 2274bdaacb0e..e8b508b14adb 100644
--- a/contrib/gcc/expmed.c
+++ b/contrib/gcc/expmed.c
@@ -1,7 +1,7 @@
/* Medium-level subroutines: convert bit-field store and extract
and shifts, multiplies and divides to rtl instructions.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -23,6 +23,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "tree.h"
@@ -35,24 +37,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "recog.h"
#include "langhooks.h"
-static void store_fixed_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, rtx));
-static void store_split_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, rtx));
-static rtx extract_fixed_bit_field PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT,
- rtx, int));
-static rtx mask_rtx PARAMS ((enum machine_mode, int,
- int, int));
-static rtx lshift_value PARAMS ((enum machine_mode, rtx,
- int, int));
-static rtx extract_split_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, int));
-static void do_cmp_and_jump PARAMS ((rtx, rtx, enum rtx_code,
- enum machine_mode, rtx));
+static void store_fixed_bit_field (rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, rtx);
+static void store_split_bit_field (rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, rtx);
+static rtx extract_fixed_bit_field (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, rtx, int);
+static rtx mask_rtx (enum machine_mode, int, int, int);
+static rtx lshift_value (enum machine_mode, rtx, int, int);
+static rtx extract_split_bit_field (rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, int);
+static void do_cmp_and_jump (rtx, rtx, enum rtx_code, enum machine_mode, rtx);
/* Nonzero means divides or modulus operations are relatively cheap for
powers of two, so don't use branches; emit the operation instead.
@@ -102,7 +100,7 @@ static int mul_widen_cost[NUM_MACHINE_MODES];
static int mul_highpart_cost[NUM_MACHINE_MODES];
void
-init_expmed ()
+init_expmed (void)
{
rtx reg, shift_insn, shiftadd_insn, shiftsub_insn;
int dummy;
@@ -205,9 +203,7 @@ init_expmed ()
useful if X is a CONST_INT. */
rtx
-negate_rtx (mode, x)
- enum machine_mode mode;
- rtx x;
+negate_rtx (enum machine_mode mode, rtx x)
{
rtx result = simplify_unary_operation (NEG, mode, x, mode);
@@ -222,9 +218,7 @@ negate_rtx (mode, x)
is false; else the mode of the specified operand. If OPNO is -1,
all the caller cares about is whether the insn is available. */
enum machine_mode
-mode_for_extraction (pattern, opno)
- enum extraction_pattern pattern;
- int opno;
+mode_for_extraction (enum extraction_pattern pattern, int opno)
{
const struct insn_data *data;
@@ -285,13 +279,9 @@ mode_for_extraction (pattern, opno)
else, we use the mode of operand 3. */
rtx
-store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, total_size)
- rtx str_rtx;
- unsigned HOST_WIDE_INT bitsize;
- unsigned HOST_WIDE_INT bitnum;
- enum machine_mode fieldmode;
- rtx value;
- HOST_WIDE_INT total_size;
+store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
+ unsigned HOST_WIDE_INT bitnum, enum machine_mode fieldmode,
+ rtx value, HOST_WIDE_INT total_size)
{
unsigned int unit
= (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD;
@@ -323,6 +313,53 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, total_size)
value = protect_from_queue (value, 0);
+ /* Use vec_extract patterns for extracting parts of vectors whenever
+ available. */
+ if (VECTOR_MODE_P (GET_MODE (op0))
+ && GET_CODE (op0) != MEM
+ && (vec_set_optab->handlers[(int)GET_MODE (op0)].insn_code
+ != CODE_FOR_nothing)
+ && fieldmode == GET_MODE_INNER (GET_MODE (op0))
+ && bitsize == GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0)))
+ && !(bitnum % GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0)))))
+ {
+ enum machine_mode outermode = GET_MODE (op0);
+ enum machine_mode innermode = GET_MODE_INNER (outermode);
+ int icode = (int) vec_set_optab->handlers[(int) outermode].insn_code;
+ int pos = bitnum / GET_MODE_BITSIZE (innermode);
+ rtx rtxpos = GEN_INT (pos);
+ rtx src = value;
+ rtx dest = op0;
+ rtx pat, seq;
+ enum machine_mode mode0 = insn_data[icode].operand[0].mode;
+ enum machine_mode mode1 = insn_data[icode].operand[1].mode;
+ enum machine_mode mode2 = insn_data[icode].operand[2].mode;
+
+ start_sequence ();
+
+ if (! (*insn_data[icode].operand[1].predicate) (src, mode1))
+ src = copy_to_mode_reg (mode1, src);
+
+ if (! (*insn_data[icode].operand[2].predicate) (rtxpos, mode2))
+ rtxpos = copy_to_mode_reg (mode1, rtxpos);
+
+ /* We could handle this, but we should always be called with a pseudo
+ for our targets and all insns should take them as outputs. */
+ if (! (*insn_data[icode].operand[0].predicate) (dest, mode0)
+ || ! (*insn_data[icode].operand[1].predicate) (src, mode1)
+ || ! (*insn_data[icode].operand[2].predicate) (rtxpos, mode2))
+ abort ();
+ pat = GEN_FCN (icode) (dest, src, rtxpos);
+ seq = get_insns ();
+ end_sequence ();
+ if (pat)
+ {
+ emit_insn (seq);
+ emit_insn (pat);
+ return dest;
+ }
+ }
+
if (flag_force_mem)
{
int old_generating_concat_p = generating_concat_p;
@@ -471,7 +508,9 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, total_size)
VOIDmode, because that is what store_field uses to indicate that this
is a bit field, but passing VOIDmode to operand_subword_force will
result in an abort. */
- fieldmode = smallest_mode_for_size (nwords * BITS_PER_WORD, MODE_INT);
+ fieldmode = GET_MODE (value);
+ if (fieldmode == VOIDmode)
+ fieldmode = smallest_mode_for_size (nwords * BITS_PER_WORD, MODE_INT);
for (i = 0; i < nwords; i++)
{
@@ -487,10 +526,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, total_size)
store_bit_field (op0, MIN (BITS_PER_WORD,
bitsize - i * BITS_PER_WORD),
bitnum + bit_offset, word_mode,
- operand_subword_force (value, wordnum,
- (GET_MODE (value) == VOIDmode
- ? fieldmode
- : GET_MODE (value))),
+ operand_subword_force (value, wordnum, fieldmode),
total_size);
}
return value;
@@ -700,10 +736,9 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, total_size)
Note that protect_from_queue has already been done on OP0 and VALUE. */
static void
-store_fixed_bit_field (op0, offset, bitsize, bitpos, value)
- rtx op0;
- unsigned HOST_WIDE_INT offset, bitsize, bitpos;
- rtx value;
+store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT offset,
+ unsigned HOST_WIDE_INT bitsize,
+ unsigned HOST_WIDE_INT bitpos, rtx value)
{
enum machine_mode mode;
unsigned int total_bits = BITS_PER_WORD;
@@ -866,10 +901,8 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value)
This does not yet handle fields wider than BITS_PER_WORD. */
static void
-store_split_bit_field (op0, bitsize, bitpos, value)
- rtx op0;
- unsigned HOST_WIDE_INT bitsize, bitpos;
- rtx value;
+store_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
+ unsigned HOST_WIDE_INT bitpos, rtx value)
{
unsigned int unit;
unsigned int bitsdone = 0;
@@ -1002,15 +1035,10 @@ store_split_bit_field (op0, bitsize, bitpos, value)
if they are equally easy. */
rtx
-extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
- target, mode, tmode, total_size)
- rtx str_rtx;
- unsigned HOST_WIDE_INT bitsize;
- unsigned HOST_WIDE_INT bitnum;
- int unsignedp;
- rtx target;
- enum machine_mode mode, tmode;
- HOST_WIDE_INT total_size;
+extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
+ unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target,
+ enum machine_mode mode, enum machine_mode tmode,
+ HOST_WIDE_INT total_size)
{
unsigned int unit
= (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD;
@@ -1054,6 +1082,61 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
return op0;
}
+ /* Use vec_extract patterns for extracting parts of vectors whenever
+ available. */
+ if (VECTOR_MODE_P (GET_MODE (op0))
+ && GET_CODE (op0) != MEM
+ && (vec_extract_optab->handlers[(int)GET_MODE (op0)].insn_code
+ != CODE_FOR_nothing)
+ && ((bitsize + bitnum) / GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0)))
+ == bitsize / GET_MODE_BITSIZE (GET_MODE_INNER (GET_MODE (op0)))))
+ {
+ enum machine_mode outermode = GET_MODE (op0);
+ enum machine_mode innermode = GET_MODE_INNER (outermode);
+ int icode = (int) vec_extract_optab->handlers[(int) outermode].insn_code;
+ int pos = bitnum / GET_MODE_BITSIZE (innermode);
+ rtx rtxpos = GEN_INT (pos);
+ rtx src = op0;
+ rtx dest = NULL, pat, seq;
+ enum machine_mode mode0 = insn_data[icode].operand[0].mode;
+ enum machine_mode mode1 = insn_data[icode].operand[1].mode;
+ enum machine_mode mode2 = insn_data[icode].operand[2].mode;
+
+ if (innermode == tmode || innermode == mode)
+ dest = target;
+
+ if (!dest)
+ dest = gen_reg_rtx (innermode);
+
+ start_sequence ();
+
+ if (! (*insn_data[icode].operand[0].predicate) (dest, mode0))
+ dest = copy_to_mode_reg (mode0, dest);
+
+ if (! (*insn_data[icode].operand[1].predicate) (src, mode1))
+ src = copy_to_mode_reg (mode1, src);
+
+ if (! (*insn_data[icode].operand[2].predicate) (rtxpos, mode2))
+ rtxpos = copy_to_mode_reg (mode1, rtxpos);
+
+ /* We could handle this, but we should always be called with a pseudo
+ for our targets and all insns should take them as outputs. */
+ if (! (*insn_data[icode].operand[0].predicate) (dest, mode0)
+ || ! (*insn_data[icode].operand[1].predicate) (src, mode1)
+ || ! (*insn_data[icode].operand[2].predicate) (rtxpos, mode2))
+ abort ();
+
+ pat = GEN_FCN (icode) (dest, src, rtxpos);
+ seq = get_insns ();
+ end_sequence ();
+ if (pat)
+ {
+ emit_insn (seq);
+ emit_insn (pat);
+ return dest;
+ }
+ }
+
/* Make sure we are playing with integral modes. Pun with subregs
if we aren't. */
{
@@ -1098,29 +1181,34 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
If that's wrong, the solution is to test for it and set TARGET to 0
if needed. */
- mode1 = (VECTOR_MODE_P (tmode)
- ? mode
- : mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0));
-
- if (((GET_CODE (op0) != MEM
- && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
- GET_MODE_BITSIZE (GET_MODE (op0)))
- && GET_MODE_SIZE (mode1) != 0
- && byte_offset % GET_MODE_SIZE (mode1) == 0)
- || (GET_CODE (op0) == MEM
- && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (op0))
- || (offset * BITS_PER_UNIT % bitsize == 0
- && MEM_ALIGN (op0) % bitsize == 0))))
- && ((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode)
- && bitpos % BITS_PER_WORD == 0)
- || (mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0) != BLKmode
- /* ??? The big endian test here is wrong. This is correct
- if the value is in a register, and if mode_for_size is not
- the same mode as op0. This causes us to get unnecessarily
- inefficient code from the Thumb port when -mbig-endian. */
- && (BYTES_BIG_ENDIAN
- ? bitpos + bitsize == BITS_PER_WORD
- : bitpos == 0))))
+ /* Only scalar integer modes can be converted via subregs. There is an
+ additional problem for FP modes here in that they can have a precision
+ which is different from the size. mode_for_size uses precision, but
+ we want a mode based on the size, so we must avoid calling it for FP
+ modes. */
+ mode1 = (SCALAR_INT_MODE_P (tmode)
+ ? mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0)
+ : mode);
+
+ if (((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode)
+ && bitpos % BITS_PER_WORD == 0)
+ || (mode1 != BLKmode
+ /* ??? The big endian test here is wrong. This is correct
+ if the value is in a register, and if mode_for_size is not
+ the same mode as op0. This causes us to get unnecessarily
+ inefficient code from the Thumb port when -mbig-endian. */
+ && (BYTES_BIG_ENDIAN
+ ? bitpos + bitsize == BITS_PER_WORD
+ : bitpos == 0)))
+ && ((GET_CODE (op0) != MEM
+ && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
+ GET_MODE_BITSIZE (GET_MODE (op0)))
+ && GET_MODE_SIZE (mode1) != 0
+ && byte_offset % GET_MODE_SIZE (mode1) == 0)
+ || (GET_CODE (op0) == MEM
+ && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (op0))
+ || (offset * BITS_PER_UNIT % bitsize == 0
+ && MEM_ALIGN (op0) % bitsize == 0)))))
{
if (mode1 != GET_MODE (op0))
{
@@ -1558,12 +1646,11 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
If TARGET is not used, create a pseudo-reg of mode TMODE for the value. */
static rtx
-extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
- target, unsignedp)
- enum machine_mode tmode;
- rtx op0, target;
- unsigned HOST_WIDE_INT offset, bitsize, bitpos;
- int unsignedp;
+extract_fixed_bit_field (enum machine_mode tmode, rtx op0,
+ unsigned HOST_WIDE_INT offset,
+ unsigned HOST_WIDE_INT bitsize,
+ unsigned HOST_WIDE_INT bitpos, rtx target,
+ int unsignedp)
{
unsigned int total_bits = BITS_PER_WORD;
enum machine_mode mode;
@@ -1690,13 +1777,13 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
BITSIZE+BITPOS is too small for MODE. */
static rtx
-mask_rtx (mode, bitpos, bitsize, complement)
- enum machine_mode mode;
- int bitpos, bitsize, complement;
+mask_rtx (enum machine_mode mode, int bitpos, int bitsize, int complement)
{
HOST_WIDE_INT masklow, maskhigh;
- if (bitpos < HOST_BITS_PER_WIDE_INT)
+ if (bitsize == 0)
+ masklow = 0;
+ else if (bitpos < HOST_BITS_PER_WIDE_INT)
masklow = (HOST_WIDE_INT) -1 << bitpos;
else
masklow = 0;
@@ -1710,7 +1797,9 @@ mask_rtx (mode, bitpos, bitsize, complement)
else
maskhigh = (HOST_WIDE_INT) -1 << (bitpos - HOST_BITS_PER_WIDE_INT);
- if (bitpos + bitsize > HOST_BITS_PER_WIDE_INT)
+ if (bitsize == 0)
+ maskhigh = 0;
+ else if (bitpos + bitsize > HOST_BITS_PER_WIDE_INT)
maskhigh &= ((unsigned HOST_WIDE_INT) -1
>> (2 * HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
else
@@ -1729,10 +1818,7 @@ mask_rtx (mode, bitpos, bitsize, complement)
VALUE truncated to BITSIZE bits and then shifted left BITPOS bits. */
static rtx
-lshift_value (mode, value, bitpos, bitsize)
- enum machine_mode mode;
- rtx value;
- int bitpos, bitsize;
+lshift_value (enum machine_mode mode, rtx value, int bitpos, int bitsize)
{
unsigned HOST_WIDE_INT v = INTVAL (value);
HOST_WIDE_INT low, high;
@@ -1762,10 +1848,8 @@ lshift_value (mode, value, bitpos, bitsize)
UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend. */
static rtx
-extract_split_bit_field (op0, bitsize, bitpos, unsignedp)
- rtx op0;
- unsigned HOST_WIDE_INT bitsize, bitpos;
- int unsignedp;
+extract_split_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
+ unsigned HOST_WIDE_INT bitpos, int unsignedp)
{
unsigned int unit;
unsigned int bitsdone = 0;
@@ -1864,8 +1948,7 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp)
/* Add INC into TARGET. */
void
-expand_inc (target, inc)
- rtx target, inc;
+expand_inc (rtx target, rtx inc)
{
rtx value = expand_binop (GET_MODE (target), add_optab,
target, inc,
@@ -1877,8 +1960,7 @@ expand_inc (target, inc)
/* Subtract DEC from TARGET. */
void
-expand_dec (target, dec)
- rtx target, dec;
+expand_dec (rtx target, rtx dec)
{
rtx value = expand_binop (GET_MODE (target), sub_optab,
target, dec,
@@ -1895,13 +1977,8 @@ expand_dec (target, dec)
Return the rtx for where the value is. */
rtx
-expand_shift (code, mode, shifted, amount, target, unsignedp)
- enum tree_code code;
- enum machine_mode mode;
- rtx shifted;
- tree amount;
- rtx target;
- int unsignedp;
+expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
+ tree amount, rtx target, int unsignedp)
{
rtx op1, temp = 0;
int left = (code == LSHIFT_EXPR || code == LROTATE_EXPR);
@@ -2073,25 +2150,19 @@ struct algorithm
char log[MAX_BITS_PER_WORD];
};
-static void synth_mult PARAMS ((struct algorithm *,
- unsigned HOST_WIDE_INT,
- int));
-static unsigned HOST_WIDE_INT choose_multiplier PARAMS ((unsigned HOST_WIDE_INT,
- int, int,
- unsigned HOST_WIDE_INT *,
- int *, int *));
-static unsigned HOST_WIDE_INT invert_mod2n PARAMS ((unsigned HOST_WIDE_INT,
- int));
+static void synth_mult (struct algorithm *, unsigned HOST_WIDE_INT, int);
+static unsigned HOST_WIDE_INT choose_multiplier (unsigned HOST_WIDE_INT, int,
+ int, unsigned HOST_WIDE_INT *,
+ int *, int *);
+static unsigned HOST_WIDE_INT invert_mod2n (unsigned HOST_WIDE_INT, int);
/* Compute and return the best algorithm for multiplying by T.
The algorithm must cost less than cost_limit
If retval.cost >= COST_LIMIT, no algorithm was found and all
other field of the returned struct are undefined. */
static void
-synth_mult (alg_out, t, cost_limit)
- struct algorithm *alg_out;
- unsigned HOST_WIDE_INT t;
- int cost_limit;
+synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
+ int cost_limit)
{
int m;
struct algorithm *alg_in, *best_alg;
@@ -2131,8 +2202,8 @@ synth_mult (alg_out, t, cost_limit)
/* We'll be needing a couple extra algorithm structures now. */
- alg_in = (struct algorithm *)alloca (sizeof (struct algorithm));
- best_alg = (struct algorithm *)alloca (sizeof (struct algorithm));
+ alg_in = alloca (sizeof (struct algorithm));
+ best_alg = alloca (sizeof (struct algorithm));
/* If we have a group of zero bits at the low-order part of T, try
multiplying by the remaining bits and then doing a shift. */
@@ -2335,10 +2406,8 @@ synth_mult (alg_out, t, cost_limit)
you should swap the two operands if OP0 would be constant. */
rtx
-expand_mult (mode, op0, op1, target, unsignedp)
- enum machine_mode mode;
- rtx op0, op1, target;
- int unsignedp;
+expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
+ int unsignedp)
{
rtx const_op1 = op1;
@@ -2529,9 +2598,9 @@ expand_mult (mode, op0, op1, target, unsignedp)
insn = get_last_insn ();
set_unique_reg_note (insn,
- REG_EQUAL,
+ REG_EQUAL,
gen_rtx_MULT (nmode, tem,
- GEN_INT (val_so_far)));
+ GEN_INT (val_so_far)));
}
if (variant == negate_variant)
@@ -2552,6 +2621,28 @@ expand_mult (mode, op0, op1, target, unsignedp)
}
}
+ if (GET_CODE (op0) == CONST_DOUBLE)
+ {
+ rtx temp = op0;
+ op0 = op1;
+ op1 = temp;
+ }
+
+ /* Expand x*2.0 as x+x. */
+ if (GET_CODE (op1) == CONST_DOUBLE
+ && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ REAL_VALUE_TYPE d;
+ REAL_VALUE_FROM_CONST_DOUBLE (d, op1);
+
+ if (REAL_VALUES_EQUAL (d, dconst2))
+ {
+ op0 = force_reg (GET_MODE (op0), op0);
+ return expand_binop (mode, add_optab, op0, op0,
+ target, unsignedp, OPTAB_LIB_WIDEN);
+ }
+ }
+
/* This used to use umul_optab if unsigned, but for non-widening multiply
there is no difference between signed and unsigned. */
op0 = expand_binop (mode,
@@ -2567,8 +2658,7 @@ expand_mult (mode, op0, op1, target, unsignedp)
/* Return the smallest n such that 2**n >= X. */
int
-ceil_log2 (x)
- unsigned HOST_WIDE_INT x;
+ceil_log2 (unsigned HOST_WIDE_INT x)
{
return floor_log2 (x - 1) + 1;
}
@@ -2591,13 +2681,9 @@ ceil_log2 (x)
static
unsigned HOST_WIDE_INT
-choose_multiplier (d, n, precision, multiplier_ptr, post_shift_ptr, lgup_ptr)
- unsigned HOST_WIDE_INT d;
- int n;
- int precision;
- unsigned HOST_WIDE_INT *multiplier_ptr;
- int *post_shift_ptr;
- int *lgup_ptr;
+choose_multiplier (unsigned HOST_WIDE_INT d, int n, int precision,
+ unsigned HOST_WIDE_INT *multiplier_ptr,
+ int *post_shift_ptr, int *lgup_ptr)
{
HOST_WIDE_INT mhigh_hi, mlow_hi;
unsigned HOST_WIDE_INT mhigh_lo, mlow_lo;
@@ -2648,14 +2734,14 @@ choose_multiplier (d, n, precision, multiplier_ptr, post_shift_ptr, lgup_ptr)
abort ();
if (mhigh_hi > 1 || mlow_hi > 1)
abort ();
- /* assert that mlow < mhigh. */
+ /* Assert that mlow < mhigh. */
if (! (mlow_hi < mhigh_hi || (mlow_hi == mhigh_hi && mlow_lo < mhigh_lo)))
abort ();
/* If precision == N, then mlow, mhigh exceed 2^N
(but they do not exceed 2^(N+1)). */
- /* Reduce to lowest terms */
+ /* Reduce to lowest terms. */
for (post_shift = lgup; post_shift > 0; post_shift--)
{
unsigned HOST_WIDE_INT ml_lo = (mlow_hi << (HOST_BITS_PER_WIDE_INT - 1)) | (mlow_lo >> 1);
@@ -2688,9 +2774,7 @@ choose_multiplier (d, n, precision, multiplier_ptr, post_shift_ptr, lgup_ptr)
congruent to 1 (mod 2**N). */
static unsigned HOST_WIDE_INT
-invert_mod2n (x, n)
- unsigned HOST_WIDE_INT x;
- int n;
+invert_mod2n (unsigned HOST_WIDE_INT x, int n)
{
/* Solve x*y == 1 (mod 2^n), where x is odd. Return y. */
@@ -2725,10 +2809,8 @@ invert_mod2n (x, n)
MODE is the mode of operation. */
rtx
-expand_mult_highpart_adjust (mode, adj_operand, op0, op1, target, unsignedp)
- enum machine_mode mode;
- rtx adj_operand, op0, op1, target;
- int unsignedp;
+expand_mult_highpart_adjust (enum machine_mode mode, rtx adj_operand, rtx op0,
+ rtx op1, rtx target, int unsignedp)
{
rtx tem;
enum rtx_code adj_code = unsignedp ? PLUS : MINUS;
@@ -2762,12 +2844,9 @@ expand_mult_highpart_adjust (mode, adj_operand, op0, op1, target, unsignedp)
MAX_COST is the total allowed cost for the expanded RTL. */
rtx
-expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost)
- enum machine_mode mode;
- rtx op0, target;
- unsigned HOST_WIDE_INT cnst1;
- int unsignedp;
- int max_cost;
+expand_mult_highpart (enum machine_mode mode, rtx op0,
+ unsigned HOST_WIDE_INT cnst1, rtx target,
+ int unsignedp, int max_cost)
{
enum machine_mode wider_mode = GET_MODE_WIDER_MODE (mode);
optab mul_highpart_optab;
@@ -2939,12 +3018,8 @@ expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost)
#define EXACT_POWER_OF_2_OR_ZERO_P(x) (((x) & ((x) - 1)) == 0)
rtx
-expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
- int rem_flag;
- enum tree_code code;
- enum machine_mode mode;
- rtx op0, op1, target;
- int unsignedp;
+expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
+ rtx op0, rtx op1, rtx target, int unsignedp)
{
enum machine_mode compute_mode;
rtx tquotient;
@@ -2953,14 +3028,20 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
int size;
rtx insn, set;
optab optab1, optab2;
- int op1_is_constant, op1_is_pow2;
+ int op1_is_constant, op1_is_pow2 = 0;
int max_cost, extra_cost;
static HOST_WIDE_INT last_div_const = 0;
+ static HOST_WIDE_INT ext_op1;
op1_is_constant = GET_CODE (op1) == CONST_INT;
- op1_is_pow2 = (op1_is_constant
- && ((EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
- || (! unsignedp && EXACT_POWER_OF_2_OR_ZERO_P (-INTVAL (op1))))));
+ if (op1_is_constant)
+ {
+ ext_op1 = INTVAL (op1);
+ if (unsignedp)
+ ext_op1 &= GET_MODE_MASK (mode);
+ op1_is_pow2 = ((EXACT_POWER_OF_2_OR_ZERO_P (ext_op1)
+ || (! unsignedp && EXACT_POWER_OF_2_OR_ZERO_P (-ext_op1))));
+ }
/*
This is the structure of expand_divmod:
@@ -3140,7 +3221,8 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
unsigned HOST_WIDE_INT mh, ml;
int pre_shift, post_shift;
int dummy;
- unsigned HOST_WIDE_INT d = INTVAL (op1);
+ unsigned HOST_WIDE_INT d = (INTVAL (op1)
+ & GET_MODE_MASK (compute_mode));
if (EXACT_POWER_OF_2_OR_ZERO_P (d))
{
@@ -3253,7 +3335,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
&& (set = single_set (insn)) != 0
&& SET_DEST (set) == quotient)
set_unique_reg_note (insn,
- REG_EQUAL,
+ REG_EQUAL,
gen_rtx_UDIV (compute_mode, op0, op1));
}
else /* TRUNC_DIV, signed */
@@ -3341,7 +3423,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
&& abs_d < ((unsigned HOST_WIDE_INT) 1
<< (HOST_BITS_PER_WIDE_INT - 1)))
set_unique_reg_note (insn,
- REG_EQUAL,
+ REG_EQUAL,
gen_rtx_DIV (compute_mode,
op0,
GEN_INT
@@ -3432,7 +3514,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
&& (set = single_set (insn)) != 0
&& SET_DEST (set) == quotient)
set_unique_reg_note (insn,
- REG_EQUAL,
+ REG_EQUAL,
gen_rtx_DIV (compute_mode, op0, op1));
}
break;
@@ -3848,11 +3930,11 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
build_int_2 (pre_shift, 0), NULL_RTX, unsignedp);
quotient = expand_mult (compute_mode, t1,
gen_int_mode (ml, compute_mode),
- NULL_RTX, 0);
+ NULL_RTX, 1);
insn = get_last_insn ();
set_unique_reg_note (insn,
- REG_EQUAL,
+ REG_EQUAL,
gen_rtx_fmt_ee (unsignedp ? UDIV : DIV,
compute_mode,
op0, op1));
@@ -3937,7 +4019,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
{
/* Try to produce the remainder without producing the quotient.
If we seem to have a divmod pattern that does not require widening,
- don't try widening here. We should really have an WIDEN argument
+ don't try widening here. We should really have a WIDEN argument
to expand_twoval_binop, since what we'd really like to do here is
1) try a mod insn in compute_mode
2) try a divmod insn in compute_mode
@@ -4031,9 +4113,7 @@ expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
generated by loop.c. */
tree
-make_tree (type, x)
- tree type;
- rtx x;
+make_tree (tree type, rtx x)
{
tree t;
@@ -4141,12 +4221,10 @@ make_tree (type, x)
t = make_node (RTL_EXPR);
TREE_TYPE (t) = type;
-#ifdef POINTERS_EXTEND_UNSIGNED
/* If TYPE is a POINTER_TYPE, X might be Pmode with TYPE_MODE being
ptr_mode. So convert. */
- if (POINTER_TYPE_P (type) && GET_MODE (x) != TYPE_MODE (type))
+ if (POINTER_TYPE_P (type))
x = convert_memory_address (TYPE_MODE (type), x);
-#endif
RTL_EXPR_RTL (t) = x;
/* There are no insns to be output
@@ -4164,10 +4242,7 @@ make_tree (type, x)
UNSIGNEDP is nonzero to do unsigned multiplication. */
bool
-const_mult_add_overflow_p (x, mult, add, mode, unsignedp)
- rtx x, mult, add;
- enum machine_mode mode;
- int unsignedp;
+const_mult_add_overflow_p (rtx x, rtx mult, rtx add, enum machine_mode mode, int unsignedp)
{
tree type, mult_type, add_type, result;
@@ -4203,10 +4278,8 @@ const_mult_add_overflow_p (x, mult, add, mode, unsignedp)
This may emit insns. */
rtx
-expand_mult_add (x, target, mult, add, mode, unsignedp)
- rtx x, target, mult, add;
- enum machine_mode mode;
- int unsignedp;
+expand_mult_add (rtx x, rtx target, rtx mult, rtx add, enum machine_mode mode,
+ int unsignedp)
{
tree type = (*lang_hooks.types.type_for_mode) (mode, unsignedp);
tree add_type = (GET_MODE (add) == VOIDmode
@@ -4227,9 +4300,7 @@ expand_mult_add (x, target, mult, add, mode, unsignedp)
If TARGET is 0, a pseudo-register or constant is returned. */
rtx
-expand_and (mode, op0, op1, target)
- enum machine_mode mode;
- rtx op0, op1, target;
+expand_and (enum machine_mode mode, rtx op0, rtx op1, rtx target)
{
rtx tem = 0;
@@ -4261,13 +4332,8 @@ expand_and (mode, op0, op1, target)
"raw" out of the scc insn. */
rtx
-emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
- rtx target;
- enum rtx_code code;
- rtx op0, op1;
- enum machine_mode mode;
- int unsignedp;
- int normalizep;
+emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
+ enum machine_mode mode, int unsignedp, int normalizep)
{
rtx subtarget;
enum insn_code icode;
@@ -4374,7 +4440,7 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
&& (normalizep || STORE_FLAG_VALUE == 1
|| (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
&& ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
- == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))))
+ == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))))
{
subtarget = target;
@@ -4701,13 +4767,8 @@ emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
/* Like emit_store_flag, but always succeeds. */
rtx
-emit_store_flag_force (target, code, op0, op1, mode, unsignedp, normalizep)
- rtx target;
- enum rtx_code code;
- rtx op0, op1;
- enum machine_mode mode;
- int unsignedp;
- int normalizep;
+emit_store_flag_force (rtx target, enum rtx_code code, rtx op0, rtx op1,
+ enum machine_mode mode, int unsignedp, int normalizep)
{
rtx tem, label;
@@ -4746,10 +4807,8 @@ emit_store_flag_force (target, code, op0, op1, mode, unsignedp, normalizep)
be handled if needed). */
static void
-do_cmp_and_jump (arg1, arg2, op, mode, label)
- rtx arg1, arg2, label;
- enum rtx_code op;
- enum machine_mode mode;
+do_cmp_and_jump (rtx arg1, rtx arg2, enum rtx_code op, enum machine_mode mode,
+ rtx label)
{
/* If this mode is an integer too wide to compare properly,
compare word by word. Rely on cse to optimize constant cases. */
diff --git a/contrib/gcc/expr.c b/contrib/gcc/expr.c
index 9f7c2847c58d..aa80ae63f46b 100644
--- a/contrib/gcc/expr.c
+++ b/contrib/gcc/expr.c
@@ -1,6 +1,6 @@
/* Convert tree expression to rtl instructions, for GNU compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "machmode.h"
#include "real.h"
#include "rtl.h"
@@ -45,6 +47,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "langhooks.h"
#include "intl.h"
#include "tm_p.h"
+#include "target.h"
/* Decide whether a function's arguments should be processed
from first to last or from last to first.
@@ -93,7 +96,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
int cse_not_expected;
/* Chain of pending expressions for PLACEHOLDER_EXPR to replace. */
-static tree placeholder_list = 0;
+tree placeholder_list = 0;
/* This structure is used by move_by_pieces to describe the move to
be performed. */
@@ -123,61 +126,53 @@ struct store_by_pieces
int explicit_inc_to;
unsigned HOST_WIDE_INT len;
HOST_WIDE_INT offset;
- rtx (*constfun) PARAMS ((PTR, HOST_WIDE_INT, enum machine_mode));
- PTR constfundata;
+ rtx (*constfun) (void *, HOST_WIDE_INT, enum machine_mode);
+ void *constfundata;
int reverse;
};
-static rtx enqueue_insn PARAMS ((rtx, rtx));
-static unsigned HOST_WIDE_INT move_by_pieces_ninsns
- PARAMS ((unsigned HOST_WIDE_INT,
- unsigned int));
-static void move_by_pieces_1 PARAMS ((rtx (*) (rtx, ...), enum machine_mode,
- struct move_by_pieces *));
-static bool block_move_libcall_safe_for_call_parm PARAMS ((void));
-static bool emit_block_move_via_movstr PARAMS ((rtx, rtx, rtx, unsigned));
-static rtx emit_block_move_via_libcall PARAMS ((rtx, rtx, rtx));
-static tree emit_block_move_libcall_fn PARAMS ((int));
-static void emit_block_move_via_loop PARAMS ((rtx, rtx, rtx, unsigned));
-static rtx clear_by_pieces_1 PARAMS ((PTR, HOST_WIDE_INT,
- enum machine_mode));
-static void clear_by_pieces PARAMS ((rtx, unsigned HOST_WIDE_INT,
- unsigned int));
-static void store_by_pieces_1 PARAMS ((struct store_by_pieces *,
- unsigned int));
-static void store_by_pieces_2 PARAMS ((rtx (*) (rtx, ...),
- enum machine_mode,
- struct store_by_pieces *));
-static bool clear_storage_via_clrstr PARAMS ((rtx, rtx, unsigned));
-static rtx clear_storage_via_libcall PARAMS ((rtx, rtx));
-static tree clear_storage_libcall_fn PARAMS ((int));
-static rtx compress_float_constant PARAMS ((rtx, rtx));
-static rtx get_subtarget PARAMS ((rtx));
-static int is_zeros_p PARAMS ((tree));
-static int mostly_zeros_p PARAMS ((tree));
-static void store_constructor_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
- HOST_WIDE_INT, enum machine_mode,
- tree, tree, int, int));
-static void store_constructor PARAMS ((tree, rtx, int, HOST_WIDE_INT));
-static rtx store_field PARAMS ((rtx, HOST_WIDE_INT,
- HOST_WIDE_INT, enum machine_mode,
- tree, enum machine_mode, int, tree,
- int));
-static rtx var_rtx PARAMS ((tree));
-static HOST_WIDE_INT highest_pow2_factor PARAMS ((tree));
-static HOST_WIDE_INT highest_pow2_factor_for_type PARAMS ((tree, tree));
-static int is_aligning_offset PARAMS ((tree, tree));
-static rtx expand_increment PARAMS ((tree, int, int));
-static void do_jump_by_parts_greater PARAMS ((tree, int, rtx, rtx));
-static void do_jump_by_parts_equality PARAMS ((tree, rtx, rtx));
-static void do_compare_and_jump PARAMS ((tree, enum rtx_code, enum rtx_code,
- rtx, rtx));
-static rtx do_store_flag PARAMS ((tree, rtx, enum machine_mode, int));
+static rtx enqueue_insn (rtx, rtx);
+static unsigned HOST_WIDE_INT move_by_pieces_ninsns (unsigned HOST_WIDE_INT,
+ unsigned int);
+static void move_by_pieces_1 (rtx (*) (rtx, ...), enum machine_mode,
+ struct move_by_pieces *);
+static bool block_move_libcall_safe_for_call_parm (void);
+static bool emit_block_move_via_movstr (rtx, rtx, rtx, unsigned);
+static rtx emit_block_move_via_libcall (rtx, rtx, rtx);
+static tree emit_block_move_libcall_fn (int);
+static void emit_block_move_via_loop (rtx, rtx, rtx, unsigned);
+static rtx clear_by_pieces_1 (void *, HOST_WIDE_INT, enum machine_mode);
+static void clear_by_pieces (rtx, unsigned HOST_WIDE_INT, unsigned int);
+static void store_by_pieces_1 (struct store_by_pieces *, unsigned int);
+static void store_by_pieces_2 (rtx (*) (rtx, ...), enum machine_mode,
+ struct store_by_pieces *);
+static bool clear_storage_via_clrstr (rtx, rtx, unsigned);
+static rtx clear_storage_via_libcall (rtx, rtx);
+static tree clear_storage_libcall_fn (int);
+static rtx compress_float_constant (rtx, rtx);
+static rtx get_subtarget (rtx);
+static int is_zeros_p (tree);
+static void store_constructor_field (rtx, unsigned HOST_WIDE_INT,
+ HOST_WIDE_INT, enum machine_mode,
+ tree, tree, int, int);
+static void store_constructor (tree, rtx, int, HOST_WIDE_INT);
+static rtx store_field (rtx, HOST_WIDE_INT, HOST_WIDE_INT, enum machine_mode,
+ tree, enum machine_mode, int, tree, int);
+static rtx var_rtx (tree);
+
+static unsigned HOST_WIDE_INT highest_pow2_factor (tree);
+static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (tree, tree);
+
+static int is_aligning_offset (tree, tree);
+static rtx expand_increment (tree, int, int);
+static void expand_operands (tree, tree, rtx, rtx*, rtx*,
+ enum expand_modifier);
+static rtx do_store_flag (tree, rtx, enum machine_mode, int);
#ifdef PUSH_ROUNDING
-static void emit_single_push_insn PARAMS ((enum machine_mode, rtx, tree));
+static void emit_single_push_insn (enum machine_mode, rtx, tree);
#endif
-static void do_tablejump PARAMS ((rtx, enum machine_mode, rtx, rtx, rtx));
-static rtx const_vector_from_tree PARAMS ((tree));
+static void do_tablejump (rtx, enum machine_mode, rtx, rtx, rtx);
+static rtx const_vector_from_tree (tree);
/* Record for each mode whether we can move a register directly to or
from an object of that mode in memory. If we can't, we won't try
@@ -190,18 +185,6 @@ static char direct_store[NUM_MACHINE_MODES];
static bool float_extend_from_mem[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
-/* If a memory-to-memory move would take MOVE_RATIO or more simple
- move-instruction sequences, we will do a movstr or libcall instead. */
-
-#ifndef MOVE_RATIO
-#if defined (HAVE_movstrqi) || defined (HAVE_movstrhi) || defined (HAVE_movstrsi) || defined (HAVE_movstrdi) || defined (HAVE_movstrti)
-#define MOVE_RATIO 2
-#else
-/* If we are optimizing for space (-Os), cut down the default move ratio. */
-#define MOVE_RATIO (optimize_size ? 3 : 15)
-#endif
-#endif
-
/* This macro is used to determine whether move_by_pieces should be called
to perform a structure copy. */
#ifndef MOVE_BY_PIECES_P
@@ -209,18 +192,6 @@ static bool float_extend_from_mem[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
(move_by_pieces_ninsns (SIZE, ALIGN) < (unsigned int) MOVE_RATIO)
#endif
-/* If a clear memory operation would take CLEAR_RATIO or more simple
- move-instruction sequences, we will do a clrstr or libcall instead. */
-
-#ifndef CLEAR_RATIO
-#if defined (HAVE_clrstrqi) || defined (HAVE_clrstrhi) || defined (HAVE_clrstrsi) || defined (HAVE_clrstrdi) || defined (HAVE_clrstrti)
-#define CLEAR_RATIO 2
-#else
-/* If we are optimizing for space, cut down the default clear ratio. */
-#define CLEAR_RATIO (optimize_size ? 3 : 15)
-#endif
-#endif
-
/* This macro is used to determine whether clear_by_pieces should be
called to clear storage. */
#ifndef CLEAR_BY_PIECES_P
@@ -228,12 +199,27 @@ static bool float_extend_from_mem[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
(move_by_pieces_ninsns (SIZE, ALIGN) < (unsigned int) CLEAR_RATIO)
#endif
+/* This macro is used to determine whether store_by_pieces should be
+ called to "memset" storage with byte values other than zero, or
+ to "memcpy" storage when the source is a constant string. */
+#ifndef STORE_BY_PIECES_P
+#define STORE_BY_PIECES_P(SIZE, ALIGN) MOVE_BY_PIECES_P (SIZE, ALIGN)
+#endif
+
/* This array records the insn_code of insns to perform block moves. */
enum insn_code movstr_optab[NUM_MACHINE_MODES];
/* This array records the insn_code of insns to perform block clears. */
enum insn_code clrstr_optab[NUM_MACHINE_MODES];
+/* These arrays record the insn_code of two different kinds of insns
+ to perform block compares. */
+enum insn_code cmpstr_optab[NUM_MACHINE_MODES];
+enum insn_code cmpmem_optab[NUM_MACHINE_MODES];
+
+/* Stack of EXPR_WITH_FILE_LOCATION nested expressions. */
+struct file_stack *expr_wfl_stack;
+
/* SLOW_UNALIGNED_ACCESS is nonzero if unaligned accesses are very slow. */
#ifndef SLOW_UNALIGNED_ACCESS
@@ -244,7 +230,7 @@ enum insn_code clrstr_optab[NUM_MACHINE_MODES];
directly in memory and to initialize the block move optab. */
void
-init_expr_once ()
+init_expr_once (void)
{
rtx insn, pat;
enum machine_mode mode;
@@ -337,23 +323,15 @@ init_expr_once ()
/* This is run at the start of compiling a function. */
void
-init_expr ()
+init_expr (void)
{
- cfun->expr = (struct expr_status *) ggc_alloc (sizeof (struct expr_status));
-
- pending_chain = 0;
- pending_stack_adjust = 0;
- stack_pointer_delta = 0;
- inhibit_defer_pop = 0;
- saveregs_value = 0;
- apply_args_value = 0;
- forced_labels = 0;
+ cfun->expr = ggc_alloc_cleared (sizeof (struct expr_status));
}
/* Small sanity check that the queue is empty at the end of a function. */
void
-finish_expr_for_function ()
+finish_expr_for_function (void)
{
if (pending_chain)
abort ();
@@ -370,8 +348,7 @@ finish_expr_for_function ()
where you want to guarantee the pre-incrementation value of VAR. */
static rtx
-enqueue_insn (var, body)
- rtx var, body;
+enqueue_insn (rtx var, rtx body)
{
pending_chain = gen_rtx_QUEUED (GET_MODE (var), var, NULL_RTX, NULL_RTX,
body, pending_chain);
@@ -394,9 +371,7 @@ enqueue_insn (var, body)
If the queue is flushed in between, incorrect code will result. */
rtx
-protect_from_queue (x, modify)
- rtx x;
- int modify;
+protect_from_queue (rtx x, int modify)
{
RTX_CODE code = GET_CODE (x);
@@ -480,8 +455,7 @@ protect_from_queue (x, modify)
since memory addresses generally contain only those. */
int
-queued_subexp_p (x)
- rtx x;
+queued_subexp_p (rtx x)
{
enum rtx_code code = GET_CODE (x);
switch (code)
@@ -500,13 +474,30 @@ queued_subexp_p (x)
}
}
-/* Perform all the pending incrementations. */
+/* Retrieve a mark on the queue. */
+
+static rtx
+mark_queue (void)
+{
+ return pending_chain;
+}
-void
-emit_queue ()
+/* Perform all the pending incrementations that have been enqueued
+ after MARK was retrieved. If MARK is null, perform all the
+ pending incrementations. */
+
+static void
+emit_insns_enqueued_after_mark (rtx mark)
{
rtx p;
- while ((p = pending_chain))
+
+ /* The marked incrementation may have been emitted in the meantime
+ through a call to emit_queue. In this case, the mark is not valid
+ anymore so do nothing. */
+ if (mark && ! QUEUED_BODY (mark))
+ return;
+
+ while ((p = pending_chain) != mark)
{
rtx body = QUEUED_BODY (p);
@@ -533,9 +524,18 @@ emit_queue ()
break;
}
+ QUEUED_BODY (p) = 0;
pending_chain = QUEUED_NEXT (p);
}
}
+
+/* Perform all the pending incrementations. */
+
+void
+emit_queue (void)
+{
+ emit_insns_enqueued_after_mark (NULL_RTX);
+}
/* Copy data from FROM to TO, where the machine modes are not the same.
Both modes may be integer, or both may be floating.
@@ -543,9 +543,7 @@ emit_queue ()
This causes zero-extension instead of sign-extension. */
void
-convert_move (to, from, unsignedp)
- rtx to, from;
- int unsignedp;
+convert_move (rtx to, rtx from, int unsignedp)
{
enum machine_mode to_mode = GET_MODE (to);
enum machine_mode from_mode = GET_MODE (from);
@@ -598,248 +596,39 @@ convert_move (to, from, unsignedp)
return;
}
- if (to_real != from_real)
- abort ();
+ if (GET_CODE (to) == CONCAT && GET_CODE (from) == CONCAT)
+ {
+ convert_move (XEXP (to, 0), XEXP (from, 0), unsignedp);
+ convert_move (XEXP (to, 1), XEXP (from, 1), unsignedp);
+ return;
+ }
if (to_real)
{
rtx value, insns;
+ convert_optab tab;
- if (GET_MODE_BITSIZE (from_mode) < GET_MODE_BITSIZE (to_mode))
- {
- /* Try converting directly if the insn is supported. */
- if ((code = can_extend_p (to_mode, from_mode, 0))
- != CODE_FOR_nothing)
- {
- emit_unop_insn (code, to, from, UNKNOWN);
- return;
- }
- }
-
-#ifdef HAVE_trunchfqf2
- if (HAVE_trunchfqf2 && from_mode == HFmode && to_mode == QFmode)
- {
- emit_unop_insn (CODE_FOR_trunchfqf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_trunctqfqf2
- if (HAVE_trunctqfqf2 && from_mode == TQFmode && to_mode == QFmode)
- {
- emit_unop_insn (CODE_FOR_trunctqfqf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_truncsfqf2
- if (HAVE_truncsfqf2 && from_mode == SFmode && to_mode == QFmode)
- {
- emit_unop_insn (CODE_FOR_truncsfqf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_truncdfqf2
- if (HAVE_truncdfqf2 && from_mode == DFmode && to_mode == QFmode)
- {
- emit_unop_insn (CODE_FOR_truncdfqf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_truncxfqf2
- if (HAVE_truncxfqf2 && from_mode == XFmode && to_mode == QFmode)
- {
- emit_unop_insn (CODE_FOR_truncxfqf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_trunctfqf2
- if (HAVE_trunctfqf2 && from_mode == TFmode && to_mode == QFmode)
- {
- emit_unop_insn (CODE_FOR_trunctfqf2, to, from, UNKNOWN);
- return;
- }
-#endif
-
-#ifdef HAVE_trunctqfhf2
- if (HAVE_trunctqfhf2 && from_mode == TQFmode && to_mode == HFmode)
- {
- emit_unop_insn (CODE_FOR_trunctqfhf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_truncsfhf2
- if (HAVE_truncsfhf2 && from_mode == SFmode && to_mode == HFmode)
- {
- emit_unop_insn (CODE_FOR_truncsfhf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_truncdfhf2
- if (HAVE_truncdfhf2 && from_mode == DFmode && to_mode == HFmode)
- {
- emit_unop_insn (CODE_FOR_truncdfhf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_truncxfhf2
- if (HAVE_truncxfhf2 && from_mode == XFmode && to_mode == HFmode)
- {
- emit_unop_insn (CODE_FOR_truncxfhf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_trunctfhf2
- if (HAVE_trunctfhf2 && from_mode == TFmode && to_mode == HFmode)
- {
- emit_unop_insn (CODE_FOR_trunctfhf2, to, from, UNKNOWN);
- return;
- }
-#endif
+ if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode))
+ tab = sext_optab;
+ else if (GET_MODE_PRECISION (from_mode) > GET_MODE_PRECISION (to_mode))
+ tab = trunc_optab;
+ else
+ abort ();
-#ifdef HAVE_truncsftqf2
- if (HAVE_truncsftqf2 && from_mode == SFmode && to_mode == TQFmode)
- {
- emit_unop_insn (CODE_FOR_truncsftqf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_truncdftqf2
- if (HAVE_truncdftqf2 && from_mode == DFmode && to_mode == TQFmode)
- {
- emit_unop_insn (CODE_FOR_truncdftqf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_truncxftqf2
- if (HAVE_truncxftqf2 && from_mode == XFmode && to_mode == TQFmode)
- {
- emit_unop_insn (CODE_FOR_truncxftqf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_trunctftqf2
- if (HAVE_trunctftqf2 && from_mode == TFmode && to_mode == TQFmode)
- {
- emit_unop_insn (CODE_FOR_trunctftqf2, to, from, UNKNOWN);
- return;
- }
-#endif
+ /* Try converting directly if the insn is supported. */
-#ifdef HAVE_truncdfsf2
- if (HAVE_truncdfsf2 && from_mode == DFmode && to_mode == SFmode)
- {
- emit_unop_insn (CODE_FOR_truncdfsf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_truncxfsf2
- if (HAVE_truncxfsf2 && from_mode == XFmode && to_mode == SFmode)
- {
- emit_unop_insn (CODE_FOR_truncxfsf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_trunctfsf2
- if (HAVE_trunctfsf2 && from_mode == TFmode && to_mode == SFmode)
- {
- emit_unop_insn (CODE_FOR_trunctfsf2, to, from, UNKNOWN);
- return;
- }
-#endif
-#ifdef HAVE_truncxfdf2
- if (HAVE_truncxfdf2 && from_mode == XFmode && to_mode == DFmode)
+ code = tab->handlers[to_mode][from_mode].insn_code;
+ if (code != CODE_FOR_nothing)
{
- emit_unop_insn (CODE_FOR_truncxfdf2, to, from, UNKNOWN);
+ emit_unop_insn (code, to, from,
+ tab == sext_optab ? FLOAT_EXTEND : FLOAT_TRUNCATE);
return;
}
-#endif
-#ifdef HAVE_trunctfdf2
- if (HAVE_trunctfdf2 && from_mode == TFmode && to_mode == DFmode)
- {
- emit_unop_insn (CODE_FOR_trunctfdf2, to, from, UNKNOWN);
- return;
- }
-#endif
- libcall = (rtx) 0;
- switch (from_mode)
- {
- case SFmode:
- switch (to_mode)
- {
- case DFmode:
- libcall = extendsfdf2_libfunc;
- break;
-
- case XFmode:
- libcall = extendsfxf2_libfunc;
- break;
-
- case TFmode:
- libcall = extendsftf2_libfunc;
- break;
-
- default:
- break;
- }
- break;
+ /* Otherwise use a libcall. */
+ libcall = tab->handlers[to_mode][from_mode].libfunc;
- case DFmode:
- switch (to_mode)
- {
- case SFmode:
- libcall = truncdfsf2_libfunc;
- break;
-
- case XFmode:
- libcall = extenddfxf2_libfunc;
- break;
-
- case TFmode:
- libcall = extenddftf2_libfunc;
- break;
-
- default:
- break;
- }
- break;
-
- case XFmode:
- switch (to_mode)
- {
- case SFmode:
- libcall = truncxfsf2_libfunc;
- break;
-
- case DFmode:
- libcall = truncxfdf2_libfunc;
- break;
-
- default:
- break;
- }
- break;
-
- case TFmode:
- switch (to_mode)
- {
- case SFmode:
- libcall = trunctfsf2_libfunc;
- break;
-
- case DFmode:
- libcall = trunctfdf2_libfunc;
- break;
-
- default:
- break;
- }
- break;
-
- default:
- break;
- }
-
- if (libcall == (rtx) 0)
+ if (!libcall)
/* This conversion is not implemented yet. */
abort ();
@@ -848,11 +637,49 @@ convert_move (to, from, unsignedp)
1, from, from_mode);
insns = get_insns ();
end_sequence ();
- emit_libcall_block (insns, to, value, gen_rtx_FLOAT_TRUNCATE (to_mode,
- from));
+ emit_libcall_block (insns, to, value,
+ tab == trunc_optab ? gen_rtx_FLOAT_TRUNCATE (to_mode,
+ from)
+ : gen_rtx_FLOAT_EXTEND (to_mode, from));
return;
}
+ /* Handle pointer conversion. */ /* SPEE 900220. */
+ /* Targets are expected to provide conversion insns between PxImode and
+ xImode for all MODE_PARTIAL_INT modes they use, but no others. */
+ if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)
+ {
+ enum machine_mode full_mode
+ = smallest_mode_for_size (GET_MODE_BITSIZE (to_mode), MODE_INT);
+
+ if (trunc_optab->handlers[to_mode][full_mode].insn_code
+ == CODE_FOR_nothing)
+ abort ();
+
+ if (full_mode != from_mode)
+ from = convert_to_mode (full_mode, from, unsignedp);
+ emit_unop_insn (trunc_optab->handlers[to_mode][full_mode].insn_code,
+ to, from, UNKNOWN);
+ return;
+ }
+ if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
+ {
+ enum machine_mode full_mode
+ = smallest_mode_for_size (GET_MODE_BITSIZE (from_mode), MODE_INT);
+
+ if (sext_optab->handlers[full_mode][from_mode].insn_code
+ == CODE_FOR_nothing)
+ abort ();
+
+ emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
+ to, from, UNKNOWN);
+ if (to_mode == full_mode)
+ return;
+
+ /* else proceed to integer conversions below */
+ from_mode = full_mode;
+ }
+
/* Now both modes are integers. */
/* Handle expanding beyond a word. */
@@ -886,7 +713,11 @@ convert_move (to, from, unsignedp)
!= CODE_FOR_nothing))
{
if (GET_CODE (to) == REG)
- emit_insn (gen_rtx_CLOBBER (VOIDmode, to));
+ {
+ if (reg_overlap_mentioned_p (to, from))
+ from = force_reg (from_mode, from);
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, to));
+ }
convert_move (gen_lowpart (word_mode, to), from, unsignedp);
emit_unop_insn (code, to,
gen_lowpart (word_mode, to), equiv_code);
@@ -975,119 +806,6 @@ convert_move (to, from, unsignedp)
return;
}
- /* Handle pointer conversion. */ /* SPEE 900220. */
- if (to_mode == PQImode)
- {
- if (from_mode != QImode)
- from = convert_to_mode (QImode, from, unsignedp);
-
-#ifdef HAVE_truncqipqi2
- if (HAVE_truncqipqi2)
- {
- emit_unop_insn (CODE_FOR_truncqipqi2, to, from, UNKNOWN);
- return;
- }
-#endif /* HAVE_truncqipqi2 */
- abort ();
- }
-
- if (from_mode == PQImode)
- {
- if (to_mode != QImode)
- {
- from = convert_to_mode (QImode, from, unsignedp);
- from_mode = QImode;
- }
- else
- {
-#ifdef HAVE_extendpqiqi2
- if (HAVE_extendpqiqi2)
- {
- emit_unop_insn (CODE_FOR_extendpqiqi2, to, from, UNKNOWN);
- return;
- }
-#endif /* HAVE_extendpqiqi2 */
- abort ();
- }
- }
-
- if (to_mode == PSImode)
- {
- if (from_mode != SImode)
- from = convert_to_mode (SImode, from, unsignedp);
-
-#ifdef HAVE_truncsipsi2
- if (HAVE_truncsipsi2)
- {
- emit_unop_insn (CODE_FOR_truncsipsi2, to, from, UNKNOWN);
- return;
- }
-#endif /* HAVE_truncsipsi2 */
- abort ();
- }
-
- if (from_mode == PSImode)
- {
- if (to_mode != SImode)
- {
- from = convert_to_mode (SImode, from, unsignedp);
- from_mode = SImode;
- }
- else
- {
-#ifdef HAVE_extendpsisi2
- if (! unsignedp && HAVE_extendpsisi2)
- {
- emit_unop_insn (CODE_FOR_extendpsisi2, to, from, UNKNOWN);
- return;
- }
-#endif /* HAVE_extendpsisi2 */
-#ifdef HAVE_zero_extendpsisi2
- if (unsignedp && HAVE_zero_extendpsisi2)
- {
- emit_unop_insn (CODE_FOR_zero_extendpsisi2, to, from, UNKNOWN);
- return;
- }
-#endif /* HAVE_zero_extendpsisi2 */
- abort ();
- }
- }
-
- if (to_mode == PDImode)
- {
- if (from_mode != DImode)
- from = convert_to_mode (DImode, from, unsignedp);
-
-#ifdef HAVE_truncdipdi2
- if (HAVE_truncdipdi2)
- {
- emit_unop_insn (CODE_FOR_truncdipdi2, to, from, UNKNOWN);
- return;
- }
-#endif /* HAVE_truncdipdi2 */
- abort ();
- }
-
- if (from_mode == PDImode)
- {
- if (to_mode != DImode)
- {
- from = convert_to_mode (DImode, from, unsignedp);
- from_mode = DImode;
- }
- else
- {
-#ifdef HAVE_extendpdidi2
- if (HAVE_extendpdidi2)
- {
- emit_unop_insn (CODE_FOR_extendpdidi2, to, from, UNKNOWN);
- return;
- }
-#endif /* HAVE_extendpdidi2 */
- abort ();
- }
- }
-
/* Now follow all the conversions between integers
no more than a word long. */
@@ -1161,140 +879,20 @@ convert_move (to, from, unsignedp)
}
/* Support special truncate insns for certain modes. */
-
- if (from_mode == DImode && to_mode == SImode)
- {
-#ifdef HAVE_truncdisi2
- if (HAVE_truncdisi2)
- {
- emit_unop_insn (CODE_FOR_truncdisi2, to, from, UNKNOWN);
- return;
- }
-#endif
- convert_move (to, force_reg (from_mode, from), unsignedp);
- return;
- }
-
- if (from_mode == DImode && to_mode == HImode)
- {
-#ifdef HAVE_truncdihi2
- if (HAVE_truncdihi2)
- {
- emit_unop_insn (CODE_FOR_truncdihi2, to, from, UNKNOWN);
- return;
- }
-#endif
- convert_move (to, force_reg (from_mode, from), unsignedp);
- return;
- }
-
- if (from_mode == DImode && to_mode == QImode)
+ if (trunc_optab->handlers[to_mode][from_mode].insn_code != CODE_FOR_nothing)
{
-#ifdef HAVE_truncdiqi2
- if (HAVE_truncdiqi2)
- {
- emit_unop_insn (CODE_FOR_truncdiqi2, to, from, UNKNOWN);
- return;
- }
-#endif
- convert_move (to, force_reg (from_mode, from), unsignedp);
- return;
- }
-
- if (from_mode == SImode && to_mode == HImode)
- {
-#ifdef HAVE_truncsihi2
- if (HAVE_truncsihi2)
- {
- emit_unop_insn (CODE_FOR_truncsihi2, to, from, UNKNOWN);
- return;
- }
-#endif
- convert_move (to, force_reg (from_mode, from), unsignedp);
- return;
- }
-
- if (from_mode == SImode && to_mode == QImode)
- {
-#ifdef HAVE_truncsiqi2
- if (HAVE_truncsiqi2)
- {
- emit_unop_insn (CODE_FOR_truncsiqi2, to, from, UNKNOWN);
- return;
- }
-#endif
- convert_move (to, force_reg (from_mode, from), unsignedp);
- return;
- }
-
- if (from_mode == HImode && to_mode == QImode)
- {
-#ifdef HAVE_trunchiqi2
- if (HAVE_trunchiqi2)
- {
- emit_unop_insn (CODE_FOR_trunchiqi2, to, from, UNKNOWN);
- return;
- }
-#endif
- convert_move (to, force_reg (from_mode, from), unsignedp);
- return;
- }
-
- if (from_mode == TImode && to_mode == DImode)
- {
-#ifdef HAVE_trunctidi2
- if (HAVE_trunctidi2)
- {
- emit_unop_insn (CODE_FOR_trunctidi2, to, from, UNKNOWN);
- return;
- }
-#endif
- convert_move (to, force_reg (from_mode, from), unsignedp);
- return;
- }
-
- if (from_mode == TImode && to_mode == SImode)
- {
-#ifdef HAVE_trunctisi2
- if (HAVE_trunctisi2)
- {
- emit_unop_insn (CODE_FOR_trunctisi2, to, from, UNKNOWN);
- return;
- }
-#endif
- convert_move (to, force_reg (from_mode, from), unsignedp);
- return;
- }
-
- if (from_mode == TImode && to_mode == HImode)
- {
-#ifdef HAVE_trunctihi2
- if (HAVE_trunctihi2)
- {
- emit_unop_insn (CODE_FOR_trunctihi2, to, from, UNKNOWN);
- return;
- }
-#endif
- convert_move (to, force_reg (from_mode, from), unsignedp);
- return;
- }
-
- if (from_mode == TImode && to_mode == QImode)
- {
-#ifdef HAVE_trunctiqi2
- if (HAVE_trunctiqi2)
- {
- emit_unop_insn (CODE_FOR_trunctiqi2, to, from, UNKNOWN);
- return;
- }
-#endif
- convert_move (to, force_reg (from_mode, from), unsignedp);
+ emit_unop_insn (trunc_optab->handlers[to_mode][from_mode].insn_code,
+ to, from, UNKNOWN);
return;
}
/* Handle truncation of volatile memrefs, and so on;
the things that couldn't be truncated directly,
- and for which there was no special instruction. */
+ and for which there was no special instruction.
+
+ ??? Code above formerly short-circuited this, for most integer
+ mode pairs, with a force_reg in from_mode followed by a recursive
+ call to this routine. Appears always to have been wrong. */
if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode))
{
rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));
@@ -1317,10 +915,7 @@ convert_move (to, from, unsignedp)
except when putting X into an insn (in which case convert_move does it). */
rtx
-convert_to_mode (mode, x, unsignedp)
- enum machine_mode mode;
- rtx x;
- int unsignedp;
+convert_to_mode (enum machine_mode mode, rtx x, int unsignedp)
{
return convert_modes (mode, VOIDmode, x, unsignedp);
}
@@ -1339,10 +934,7 @@ convert_to_mode (mode, x, unsignedp)
except when putting X into an insn (in which case convert_move does it). */
rtx
-convert_modes (mode, oldmode, x, unsignedp)
- enum machine_mode mode, oldmode;
- rtx x;
- int unsignedp;
+convert_modes (enum machine_mode mode, enum machine_mode oldmode, rtx x, int unsignedp)
{
rtx temp;
@@ -1439,17 +1031,6 @@ convert_modes (mode, oldmode, x, unsignedp)
return temp;
}
-/* This macro is used to determine what the largest unit size that
- move_by_pieces can use is. */
-
-/* MOVE_MAX_PIECES is the number of bytes at a time which we can
- move efficiently, as opposed to MOVE_MAX which is the maximum
- number of bytes we can move with a single instruction. */
-
-#ifndef MOVE_MAX_PIECES
-#define MOVE_MAX_PIECES MOVE_MAX
-#endif
-
/* STORE_MAX_PIECES is the number of bytes at a time that we can
store efficiently. Due to internal GCC limitations, this is
MOVE_MAX_PIECES limited by the number of bytes GCC can represent
@@ -1457,6 +1038,17 @@ convert_modes (mode, oldmode, x, unsignedp)
#define STORE_MAX_PIECES MIN (MOVE_MAX_PIECES, 2 * sizeof (HOST_WIDE_INT))
+/* Determine whether the LEN bytes can be moved by using several move
+ instructions. Return nonzero if a call to move_by_pieces should
+ succeed. */
+
+int
+can_move_by_pieces (unsigned HOST_WIDE_INT len,
+ unsigned int align ATTRIBUTE_UNUSED)
+{
+ return MOVE_BY_PIECES_P (len, align);
+}
+
/* Generate several move instructions to copy LEN bytes from block FROM to
block TO. (These are MEM rtx's with BLKmode). The caller must pass FROM
and TO through protect_from_queue before calling.
@@ -1464,13 +1056,15 @@ convert_modes (mode, oldmode, x, unsignedp)
If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
used to push FROM to the stack.
- ALIGN is maximum alignment we can assume. */
+ ALIGN is maximum stack alignment we can assume.
-void
-move_by_pieces (to, from, len, align)
- rtx to, from;
- unsigned HOST_WIDE_INT len;
- unsigned int align;
+ If ENDP is 0 return to, if ENDP is 1 return memory at the end ala
+ mempcpy, and if ENDP is 2 return memory the end minus one byte ala
+ stpcpy. */
+
+rtx
+move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
+ unsigned int align, int endp)
{
struct move_by_pieces data;
rtx to_addr, from_addr = XEXP (from, 0);
@@ -1478,6 +1072,8 @@ move_by_pieces (to, from, len, align)
enum machine_mode mode = VOIDmode, tmode;
enum insn_code icode;
+ align = MIN (to ? MEM_ALIGN (to) : align, MEM_ALIGN (from));
+
data.offset = 0;
data.from_addr = from_addr;
if (to)
@@ -1582,15 +1178,43 @@ move_by_pieces (to, from, len, align)
/* The code above should have handled everything. */
if (data.len > 0)
abort ();
+
+ if (endp)
+ {
+ rtx to1;
+
+ if (data.reverse)
+ abort ();
+ if (data.autinc_to)
+ {
+ if (endp == 2)
+ {
+ if (HAVE_POST_INCREMENT && data.explicit_inc_to > 0)
+ emit_insn (gen_add2_insn (data.to_addr, constm1_rtx));
+ else
+ data.to_addr = copy_addr_to_reg (plus_constant (data.to_addr,
+ -1));
+ }
+ to1 = adjust_automodify_address (data.to, QImode, data.to_addr,
+ data.offset);
+ }
+ else
+ {
+ if (endp == 2)
+ --data.offset;
+ to1 = adjust_address (data.to, QImode, data.offset);
+ }
+ return to1;
+ }
+ else
+ return data.to;
}
/* Return number of insns required to move L bytes by pieces.
ALIGN (in bits) is maximum alignment we can assume. */
static unsigned HOST_WIDE_INT
-move_by_pieces_ninsns (l, align)
- unsigned HOST_WIDE_INT l;
- unsigned int align;
+move_by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align)
{
unsigned HOST_WIDE_INT n_insns = 0;
unsigned HOST_WIDE_INT max_size = MOVE_MAX + 1;
@@ -1629,10 +1253,8 @@ move_by_pieces_ninsns (l, align)
to make a move insn for that mode. DATA has all the other info. */
static void
-move_by_pieces_1 (genfun, mode, data)
- rtx (*genfun) PARAMS ((rtx, ...));
- enum machine_mode mode;
- struct move_by_pieces *data;
+move_by_pieces_1 (rtx (*genfun) (rtx, ...), enum machine_mode mode,
+ struct move_by_pieces *data)
{
unsigned int size = GET_MODE_SIZE (mode);
rtx to1 = NULL_RTX, from1;
@@ -1700,9 +1322,7 @@ move_by_pieces_1 (genfun, mode, data)
0 otherwise. */
rtx
-emit_block_move (x, y, size, method)
- rtx x, y, size;
- enum block_op_methods method;
+emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method)
{
bool may_use_call;
rtx retval = 0;
@@ -1752,6 +1372,9 @@ emit_block_move (x, y, size, method)
can be incorrect is coming from __builtin_memcpy. */
if (GET_CODE (size) == CONST_INT)
{
+ if (INTVAL (size) == 0)
+ return 0;
+
x = shallow_copy_rtx (x);
y = shallow_copy_rtx (y);
set_mem_size (x, size);
@@ -1759,7 +1382,7 @@ emit_block_move (x, y, size, method)
}
if (GET_CODE (size) == CONST_INT && MOVE_BY_PIECES_P (INTVAL (size), align))
- move_by_pieces (x, y, INTVAL (size), align);
+ move_by_pieces (x, y, INTVAL (size), align, 0);
else if (emit_block_move_via_movstr (x, y, size, align))
;
else if (may_use_call)
@@ -1773,83 +1396,71 @@ emit_block_move (x, y, size, method)
return retval;
}
-/* A subroutine of emit_block_move. Returns true if calling the
+/* A subroutine of emit_block_move. Returns true if calling the
block move libcall will not clobber any parameters which may have
already been placed on the stack. */
static bool
-block_move_libcall_safe_for_call_parm ()
+block_move_libcall_safe_for_call_parm (void)
{
+ /* If arguments are pushed on the stack, then they're safe. */
if (PUSH_ARGS)
return true;
- else
- {
- /* Check to see whether memcpy takes all register arguments. */
- static enum {
- takes_regs_uninit, takes_regs_no, takes_regs_yes
- } takes_regs = takes_regs_uninit;
-
- switch (takes_regs)
- {
- case takes_regs_uninit:
- {
- CUMULATIVE_ARGS args_so_far;
- tree fn, arg;
-
- fn = emit_block_move_libcall_fn (false);
- INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fn), NULL_RTX, 0);
- arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
- for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
- {
- enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
- rtx tmp = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
- if (!tmp || !REG_P (tmp))
- goto fail_takes_regs;
-#ifdef FUNCTION_ARG_PARTIAL_NREGS
- if (FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode,
- NULL_TREE, 1))
- goto fail_takes_regs;
+ /* If registers go on the stack anyway, any argument is sure to clobber
+ an outgoing argument. */
+#if defined (REG_PARM_STACK_SPACE) && defined (OUTGOING_REG_PARM_STACK_SPACE)
+ {
+ tree fn = emit_block_move_libcall_fn (false);
+ (void) fn;
+ if (REG_PARM_STACK_SPACE (fn) != 0)
+ return false;
+ }
#endif
- FUNCTION_ARG_ADVANCE (args_so_far, mode, NULL_TREE, 1);
- }
- }
- takes_regs = takes_regs_yes;
- /* FALLTHRU */
- case takes_regs_yes:
- return true;
+ /* If any argument goes in memory, then it might clobber an outgoing
+ argument. */
+ {
+ CUMULATIVE_ARGS args_so_far;
+ tree fn, arg;
- fail_takes_regs:
- takes_regs = takes_regs_no;
- /* FALLTHRU */
- case takes_regs_no:
- return false;
+ fn = emit_block_move_libcall_fn (false);
+ INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fn), NULL_RTX, 0, 3);
- default:
- abort ();
- }
- }
+ arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
+ {
+ enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
+ rtx tmp = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
+ if (!tmp || !REG_P (tmp))
+ return false;
+#ifdef FUNCTION_ARG_PARTIAL_NREGS
+ if (FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode,
+ NULL_TREE, 1))
+ return false;
+#endif
+ FUNCTION_ARG_ADVANCE (args_so_far, mode, NULL_TREE, 1);
+ }
+ }
+ return true;
}
-/* A subroutine of emit_block_move. Expand a movstr pattern;
+/* A subroutine of emit_block_move. Expand a movstr pattern;
return true if successful. */
static bool
-emit_block_move_via_movstr (x, y, size, align)
- rtx x, y, size;
- unsigned int align;
+emit_block_move_via_movstr (rtx x, rtx y, rtx size, unsigned int align)
{
- /* Try the most limited insn first, because there's no point
- including more than one in the machine description unless
- the more limited one has some advantage. */
-
rtx opalign = GEN_INT (align / BITS_PER_UNIT);
enum machine_mode mode;
/* Since this is a move insn, we don't care about volatility. */
volatile_ok = 1;
+ /* Try the most limited insn first, because there's no point
+ including more than one in the machine description unless
+ the more limited one has some advantage. */
+
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
{
@@ -1906,41 +1517,48 @@ emit_block_move_via_movstr (x, y, size, align)
Return the return value from memcpy, 0 otherwise. */
static rtx
-emit_block_move_via_libcall (dst, src, size)
- rtx dst, src, size;
+emit_block_move_via_libcall (rtx dst, rtx src, rtx size)
{
+ rtx dst_addr, src_addr;
tree call_expr, arg_list, fn, src_tree, dst_tree, size_tree;
enum machine_mode size_mode;
rtx retval;
/* DST, SRC, or SIZE may have been passed through protect_from_queue.
- It is unsafe to save the value generated by protect_from_queue
- and reuse it later. Consider what happens if emit_queue is
- called before the return value from protect_from_queue is used.
+ It is unsafe to save the value generated by protect_from_queue and reuse
+ it later. Consider what happens if emit_queue is called before the
+ return value from protect_from_queue is used.
- Expansion of the CALL_EXPR below will call emit_queue before
- we are finished emitting RTL for argument setup. So if we are
- not careful we could get the wrong value for an argument.
+ Expansion of the CALL_EXPR below will call emit_queue before we are
+ finished emitting RTL for argument setup. So if we are not careful we
+ could get the wrong value for an argument.
- To avoid this problem we go ahead and emit code to copy X, Y &
- SIZE into new pseudos. We can then place those new pseudos
- into an RTL_EXPR and use them later, even after a call to
+ To avoid this problem we go ahead and emit code to copy the addresses of
+ DST and SRC and SIZE into new pseudos. We can then place those new
+ pseudos into an RTL_EXPR and use them later, even after a call to
emit_queue.
- Note this is not strictly needed for library calls since they
- do not call emit_queue before loading their arguments. However,
- we may need to have library calls call emit_queue in the future
- since failing to do so could cause problems for targets which
- define SMALL_REGISTER_CLASSES and pass arguments in registers. */
+ Note this is not strictly needed for library calls since they do not call
+ emit_queue before loading their arguments. However, we may need to have
+ library calls call emit_queue in the future since failing to do so could
+ cause problems for targets which define SMALL_REGISTER_CLASSES and pass
+ arguments in registers. */
- dst = copy_to_mode_reg (Pmode, XEXP (dst, 0));
- src = copy_to_mode_reg (Pmode, XEXP (src, 0));
+ dst_addr = copy_to_mode_reg (Pmode, XEXP (dst, 0));
+ src_addr = copy_to_mode_reg (Pmode, XEXP (src, 0));
+
+ dst_addr = convert_memory_address (ptr_mode, dst_addr);
+ src_addr = convert_memory_address (ptr_mode, src_addr);
+
+ dst_tree = make_tree (ptr_type_node, dst_addr);
+ src_tree = make_tree (ptr_type_node, src_addr);
if (TARGET_MEM_FUNCTIONS)
size_mode = TYPE_MODE (sizetype);
else
size_mode = TYPE_MODE (unsigned_type_node);
+
size = convert_to_mode (size_mode, size, 1);
size = copy_to_mode_reg (size_mode, size);
@@ -1952,8 +1570,6 @@ emit_block_move_via_libcall (dst, src, size)
For convenience, we generate the call to bcopy this way as well. */
- dst_tree = make_tree (ptr_type_node, dst);
- src_tree = make_tree (ptr_type_node, src);
if (TARGET_MEM_FUNCTIONS)
size_tree = make_tree (sizetype, size);
else
@@ -1976,17 +1592,20 @@ emit_block_move_via_libcall (dst, src, size)
call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
call_expr, arg_list, NULL_TREE);
- TREE_SIDE_EFFECTS (call_expr) = 1;
retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
- /* If we are initializing a readonly value, show the above call
- clobbered it. Otherwise, a load from it may erroneously be
- hoisted from a loop. */
+ /* If we are initializing a readonly value, show the above call clobbered
+ it. Otherwise, a load from it may erroneously be hoisted from a loop, or
+ the delay slot scheduler might overlook conflicts and take nasty
+ decisions. */
if (RTX_UNCHANGING_P (dst))
- emit_insn (gen_rtx_CLOBBER (VOIDmode, dst));
+ add_function_usage_to
+ (last_call_insn (), gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_CLOBBER (VOIDmode, dst),
+ NULL_RTX));
- return (TARGET_MEM_FUNCTIONS ? retval : NULL_RTX);
+ return TARGET_MEM_FUNCTIONS ? retval : NULL_RTX;
}
/* A subroutine of emit_block_move_via_libcall. Create the tree node
@@ -1995,15 +1614,13 @@ emit_block_move_via_libcall (dst, src, size)
static GTY(()) tree block_move_fn;
-static tree
-emit_block_move_libcall_fn (for_call)
- int for_call;
+void
+init_block_move_fn (const char *asmspec)
{
- static bool emitted_extern;
- tree fn = block_move_fn, args;
-
- if (!fn)
+ if (!block_move_fn)
{
+ tree args, fn;
+
if (TARGET_MEM_FUNCTIONS)
{
fn = get_identifier ("memcpy");
@@ -2028,14 +1645,29 @@ emit_block_move_libcall_fn (for_call)
block_move_fn = fn;
}
+ if (asmspec)
+ {
+ SET_DECL_RTL (block_move_fn, NULL_RTX);
+ SET_DECL_ASSEMBLER_NAME (block_move_fn, get_identifier (asmspec));
+ }
+}
+
+static tree
+emit_block_move_libcall_fn (int for_call)
+{
+ static bool emitted_extern;
+
+ if (!block_move_fn)
+ init_block_move_fn (NULL);
+
if (for_call && !emitted_extern)
{
emitted_extern = true;
- make_decl_rtl (fn, NULL);
- assemble_external (fn);
+ make_decl_rtl (block_move_fn, NULL);
+ assemble_external (block_move_fn);
}
- return fn;
+ return block_move_fn;
}
/* A subroutine of emit_block_move. Copy the data via an explicit
@@ -2043,9 +1675,8 @@ emit_block_move_libcall_fn (for_call)
/* ??? It'd be nice to copy in hunks larger than QImode. */
static void
-emit_block_move_via_loop (x, y, size, align)
- rtx x, y, size;
- unsigned int align ATTRIBUTE_UNUSED;
+emit_block_move_via_loop (rtx x, rtx y, rtx size,
+ unsigned int align ATTRIBUTE_UNUSED)
{
rtx cmp_label, top_label, iter, x_addr, y_addr, tmp;
enum machine_mode iter_mode;
@@ -2064,7 +1695,7 @@ emit_block_move_via_loop (x, y, size, align)
y_addr = force_operand (XEXP (y, 0), NULL_RTX);
do_pending_stack_adjust ();
- emit_note (NULL, NOTE_INSN_LOOP_BEG);
+ emit_note (NOTE_INSN_LOOP_BEG);
emit_jump (cmp_label);
emit_label (top_label);
@@ -2082,24 +1713,20 @@ emit_block_move_via_loop (x, y, size, align)
if (tmp != iter)
emit_move_insn (iter, tmp);
- emit_note (NULL, NOTE_INSN_LOOP_CONT);
+ emit_note (NOTE_INSN_LOOP_CONT);
emit_label (cmp_label);
emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode,
true, top_label);
- emit_note (NULL, NOTE_INSN_LOOP_END);
+ emit_note (NOTE_INSN_LOOP_END);
}
/* Copy all or part of a value X into registers starting at REGNO.
The number of registers to be filled is NREGS. */
void
-move_block_to_reg (regno, x, nregs, mode)
- int regno;
- rtx x;
- int nregs;
- enum machine_mode mode;
+move_block_to_reg (int regno, rtx x, int nregs, enum machine_mode mode)
{
int i;
#ifdef HAVE_load_multiple
@@ -2136,61 +1763,23 @@ move_block_to_reg (regno, x, nregs, mode)
}
/* Copy all or part of a BLKmode value X out of registers starting at REGNO.
- The number of registers to be filled is NREGS. SIZE indicates the number
- of bytes in the object X. */
+ The number of registers to be filled is NREGS. */
void
-move_block_from_reg (regno, x, nregs, size)
- int regno;
- rtx x;
- int nregs;
- int size;
+move_block_from_reg (int regno, rtx x, int nregs)
{
int i;
-#ifdef HAVE_store_multiple
- rtx pat;
- rtx last;
-#endif
- enum machine_mode mode;
if (nregs == 0)
return;
- /* If SIZE is that of a mode no bigger than a word, just use that
- mode's store operation. */
- if (size <= UNITS_PER_WORD
- && (mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0)) != BLKmode)
- {
- emit_move_insn (adjust_address (x, mode, 0), gen_rtx_REG (mode, regno));
- return;
- }
-
- /* Blocks smaller than a word on a BYTES_BIG_ENDIAN machine must be aligned
- to the left before storing to memory. Note that the previous test
- doesn't handle all cases (e.g. SIZE == 3). */
- if (size < UNITS_PER_WORD && BYTES_BIG_ENDIAN)
- {
- rtx tem = operand_subword (x, 0, 1, BLKmode);
- rtx shift;
-
- if (tem == 0)
- abort ();
-
- shift = expand_shift (LSHIFT_EXPR, word_mode,
- gen_rtx_REG (word_mode, regno),
- build_int_2 ((UNITS_PER_WORD - size)
- * BITS_PER_UNIT, 0), NULL_RTX, 0);
- emit_move_insn (tem, shift);
- return;
- }
-
/* See if the machine can do this with a store multiple insn. */
#ifdef HAVE_store_multiple
if (HAVE_store_multiple)
{
- last = get_last_insn ();
- pat = gen_store_multiple (x, gen_rtx_REG (word_mode, regno),
- GEN_INT (nregs));
+ rtx last = get_last_insn ();
+ rtx pat = gen_store_multiple (x, gen_rtx_REG (word_mode, regno),
+ GEN_INT (nregs));
if (pat)
{
emit_insn (pat);
@@ -2219,8 +1808,7 @@ move_block_from_reg (regno, x, nregs, size)
The new set has the same modes as the original set. */
rtx
-gen_group_rtx (orig)
- rtx orig;
+gen_group_rtx (rtx orig)
{
int i, length;
rtx *tmps;
@@ -2229,7 +1817,7 @@ gen_group_rtx (orig)
abort ();
length = XVECLEN (orig, 0);
- tmps = (rtx *) alloca (sizeof (rtx) * length);
+ tmps = alloca (sizeof (rtx) * length);
/* Skip a NULL entry in first slot. */
i = XEXP (XVECEXP (orig, 0, 0), 0) ? 0 : 1;
@@ -2248,20 +1836,13 @@ gen_group_rtx (orig)
return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps));
}
-/* Emit code to move a block SRC to a block DST, where DST is non-consecutive
- registers represented by a PARALLEL. SSIZE represents the total size of
- block SRC in bytes, or -1 if not known. */
-/* ??? If SSIZE % UNITS_PER_WORD != 0, we make the blatant assumption that
- the balance will be in what would be the low-order memory addresses, i.e.
- left justified for big endian, right justified for little endian. This
- happens to be true for the targets currently using this support. If this
- ever changes, a new target macro along the lines of FUNCTION_ARG_PADDING
- would be needed. */
+/* Emit code to move a block ORIG_SRC of type TYPE to a block DST,
+ where DST is non-consecutive registers represented by a PARALLEL.
+ SSIZE represents the total size of block ORIG_SRC in bytes, or -1
+ if not known. */
void
-emit_group_load (dst, orig_src, ssize)
- rtx dst, orig_src;
- int ssize;
+emit_group_load (rtx dst, rtx orig_src, tree type ATTRIBUTE_UNUSED, int ssize)
{
rtx *tmps, src;
int start, i;
@@ -2276,7 +1857,7 @@ emit_group_load (dst, orig_src, ssize)
else
start = 1;
- tmps = (rtx *) alloca (sizeof (rtx) * XVECLEN (dst, 0));
+ tmps = alloca (sizeof (rtx) * XVECLEN (dst, 0));
/* Process the pieces. */
for (i = start; i < XVECLEN (dst, 0); i++)
@@ -2289,7 +1870,17 @@ emit_group_load (dst, orig_src, ssize)
/* Handle trailing fragments that run over the size of the struct. */
if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
{
- shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
+ /* Arrange to shift the fragment to where it belongs.
+ extract_bit_field loads to the lsb of the reg. */
+ if (
+#ifdef BLOCK_REG_PADDING
+ BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
+ == (BYTES_BIG_ENDIAN ? upward : downward)
+#else
+ BYTES_BIG_ENDIAN
+#endif
+ )
+ shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
bytelen = ssize - bytepos;
if (bytelen <= 0)
abort ();
@@ -2314,7 +1905,8 @@ emit_group_load (dst, orig_src, ssize)
/* Optimize the access just a bit. */
if (GET_CODE (src) == MEM
- && MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode)
+ && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (src))
+ || MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode))
&& bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
&& bytelen == GET_MODE_SIZE (mode))
{
@@ -2349,6 +1941,22 @@ emit_group_load (dst, orig_src, ssize)
else
abort ();
}
+ /* FIXME: A SIMD parallel will eventually lead to a subreg of a
+ SIMD register, which is currently broken. While we get GCC
+ to emit proper RTL for these cases, let's dump to memory. */
+ else if (VECTOR_MODE_P (GET_MODE (dst))
+ && GET_CODE (src) == REG)
+ {
+ int slen = GET_MODE_SIZE (GET_MODE (src));
+ rtx mem;
+
+ mem = assign_stack_temp (GET_MODE (src), slen, 0);
+ emit_move_insn (mem, src);
+ tmps[i] = adjust_address (mem, mode, (int) bytepos);
+ }
+ else if (CONSTANT_P (src) && GET_MODE (dst) != BLKmode
+ && XVECLEN (dst, 0) > 1)
+ tmps[i] = simplify_gen_subreg (mode, src, GET_MODE(dst), bytepos);
else if (CONSTANT_P (src)
|| (GET_CODE (src) == REG && GET_MODE (src) == mode))
tmps[i] = src;
@@ -2357,7 +1965,7 @@ emit_group_load (dst, orig_src, ssize)
bytepos * BITS_PER_UNIT, 1, NULL_RTX,
mode, mode, ssize);
- if (BYTES_BIG_ENDIAN && shift)
+ if (shift)
expand_binop (mode, ashl_optab, tmps[i], GEN_INT (shift),
tmps[i], 0, OPTAB_WIDEN);
}
@@ -2373,8 +1981,7 @@ emit_group_load (dst, orig_src, ssize)
non-consecutive groups of registers, each represented by a PARALLEL. */
void
-emit_group_move (dst, src)
- rtx dst, src;
+emit_group_move (rtx dst, rtx src)
{
int i;
@@ -2389,14 +1996,13 @@ emit_group_move (dst, src)
XEXP (XVECEXP (src, 0, i), 0));
}
-/* Emit code to move a block SRC to a block DST, where SRC is non-consecutive
- registers represented by a PARALLEL. SSIZE represents the total size of
- block DST, or -1 if not known. */
+/* Emit code to move a block SRC to a block ORIG_DST of type TYPE,
+ where SRC is non-consecutive registers represented by a PARALLEL.
+ SSIZE represents the total size of block ORIG_DST, or -1 if not
+ known. */
void
-emit_group_store (orig_dst, src, ssize)
- rtx orig_dst, src;
- int ssize;
+emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED, int ssize)
{
rtx *tmps, dst;
int start, i;
@@ -2411,7 +2017,7 @@ emit_group_store (orig_dst, src, ssize)
else
start = 1;
- tmps = (rtx *) alloca (sizeof (rtx) * XVECLEN (src, 0));
+ tmps = alloca (sizeof (rtx) * XVECLEN (src, 0));
/* Copy the (probable) hard regs into pseudos. */
for (i = start; i < XVECLEN (src, 0); i++)
@@ -2440,8 +2046,8 @@ emit_group_store (orig_dst, src, ssize)
the temporary. */
temp = assign_stack_temp (GET_MODE (dst), ssize, 0);
- emit_group_store (temp, src, ssize);
- emit_group_load (dst, temp, ssize);
+ emit_group_store (temp, src, type, ssize);
+ emit_group_load (dst, temp, type, ssize);
return;
}
else if (GET_CODE (dst) != MEM && GET_CODE (dst) != CONCAT)
@@ -2462,7 +2068,16 @@ emit_group_store (orig_dst, src, ssize)
/* Handle trailing fragments that run over the size of the struct. */
if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
{
- if (BYTES_BIG_ENDIAN)
+ /* store_bit_field always takes its value from the lsb.
+ Move the fragment to the lsb if it's not already there. */
+ if (
+#ifdef BLOCK_REG_PADDING
+ BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
+ == (BYTES_BIG_ENDIAN ? upward : downward)
+#else
+ BYTES_BIG_ENDIAN
+#endif
+ )
{
int shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
expand_binop (mode, ashr_optab, tmps[i], GEN_INT (shift),
@@ -2495,7 +2110,8 @@ emit_group_store (orig_dst, src, ssize)
/* Optimize the access just a bit. */
if (GET_CODE (dest) == MEM
- && MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode)
+ && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (dest))
+ || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
&& bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
&& bytelen == GET_MODE_SIZE (mode))
emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
@@ -2515,21 +2131,18 @@ emit_group_store (orig_dst, src, ssize)
set of registers starting with SRCREG into TGTBLK. If TGTBLK
is null, a stack temporary is created. TGTBLK is returned.
- The primary purpose of this routine is to handle functions
- that return BLKmode structures in registers. Some machines
- (the PA for example) want to return all small structures
- in registers regardless of the structure's alignment. */
+ The purpose of this routine is to handle functions that return
+ BLKmode structures in registers. Some machines (the PA for example)
+ want to return all small structures in registers regardless of the
+ structure's alignment. */
rtx
-copy_blkmode_from_reg (tgtblk, srcreg, type)
- rtx tgtblk;
- rtx srcreg;
- tree type;
+copy_blkmode_from_reg (rtx tgtblk, rtx srcreg, tree type)
{
unsigned HOST_WIDE_INT bytes = int_size_in_bytes (type);
rtx src = NULL, dst = NULL;
unsigned HOST_WIDE_INT bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
- unsigned HOST_WIDE_INT bitpos, xbitpos, big_endian_correction = 0;
+ unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0;
if (tgtblk == 0)
{
@@ -2547,13 +2160,20 @@ copy_blkmode_from_reg (tgtblk, srcreg, type)
&& GET_MODE_SIZE (GET_MODE (srcreg)) < UNITS_PER_WORD)
srcreg = convert_to_mode (word_mode, srcreg, TREE_UNSIGNED (type));
- /* Structures whose size is not a multiple of a word are aligned
- to the least significant byte (to the right). On a BYTES_BIG_ENDIAN
- machine, this means we must skip the empty high order bytes when
- calculating the bit offset. */
- if (BYTES_BIG_ENDIAN
- && bytes % UNITS_PER_WORD)
- big_endian_correction
+ /* If the structure doesn't take up a whole number of words, see whether
+ SRCREG is padded on the left or on the right. If it's on the left,
+ set PADDING_CORRECTION to the number of bits to skip.
+
+ In most ABIs, the structure will be returned at the least end of
+ the register, which translates to right padding on little-endian
+ targets and left padding on big-endian targets. The opposite
+ holds if the structure is returned at the most significant
+ end of the register. */
+ if (bytes % UNITS_PER_WORD != 0
+ && (targetm.calls.return_in_msb (type)
+ ? !BYTES_BIG_ENDIAN
+ : BYTES_BIG_ENDIAN))
+ padding_correction
= (BITS_PER_WORD - ((bytes % UNITS_PER_WORD) * BITS_PER_UNIT));
/* Copy the structure BITSIZE bites at a time.
@@ -2561,15 +2181,15 @@ copy_blkmode_from_reg (tgtblk, srcreg, type)
We could probably emit more efficient code for machines which do not use
strict alignment, but it doesn't seem worth the effort at the current
time. */
- for (bitpos = 0, xbitpos = big_endian_correction;
+ for (bitpos = 0, xbitpos = padding_correction;
bitpos < bytes * BITS_PER_UNIT;
bitpos += bitsize, xbitpos += bitsize)
{
/* We need a new source operand each time xbitpos is on a
- word boundary and when xbitpos == big_endian_correction
+ word boundary and when xbitpos == padding_correction
(the first time through). */
if (xbitpos % BITS_PER_WORD == 0
- || xbitpos == big_endian_correction)
+ || xbitpos == padding_correction)
src = operand_subword_force (srcreg, xbitpos / BITS_PER_WORD,
GET_MODE (srcreg));
@@ -2595,8 +2215,7 @@ copy_blkmode_from_reg (tgtblk, srcreg, type)
to by CALL_FUSAGE. REG must denote a hard register. */
void
-use_reg (call_fusage, reg)
- rtx *call_fusage, reg;
+use_reg (rtx *call_fusage, rtx reg)
{
if (GET_CODE (reg) != REG
|| REGNO (reg) >= FIRST_PSEUDO_REGISTER)
@@ -2611,10 +2230,7 @@ use_reg (call_fusage, reg)
starting at REGNO. All of these registers must be hard registers. */
void
-use_regs (call_fusage, regno, nregs)
- rtx *call_fusage;
- int regno;
- int nregs;
+use_regs (rtx *call_fusage, int regno, int nregs)
{
int i;
@@ -2630,9 +2246,7 @@ use_regs (call_fusage, regno, nregs)
non-contiguous locations. The Irix 6 ABI has examples of this. */
void
-use_group_regs (call_fusage, regs)
- rtx *call_fusage;
- rtx regs;
+use_group_regs (rtx *call_fusage, rtx regs)
{
int i;
@@ -2656,11 +2270,9 @@ use_group_regs (call_fusage, regs)
call to store_by_pieces should succeed. */
int
-can_store_by_pieces (len, constfun, constfundata, align)
- unsigned HOST_WIDE_INT len;
- rtx (*constfun) PARAMS ((PTR, HOST_WIDE_INT, enum machine_mode));
- PTR constfundata;
- unsigned int align;
+can_store_by_pieces (unsigned HOST_WIDE_INT len,
+ rtx (*constfun) (void *, HOST_WIDE_INT, enum machine_mode),
+ void *constfundata, unsigned int align)
{
unsigned HOST_WIDE_INT max_size, l;
HOST_WIDE_INT offset = 0;
@@ -2672,7 +2284,7 @@ can_store_by_pieces (len, constfun, constfundata, align)
if (len == 0)
return 1;
- if (! MOVE_BY_PIECES_P (len, align))
+ if (! STORE_BY_PIECES_P (len, align))
return 0;
if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
@@ -2735,22 +2347,26 @@ can_store_by_pieces (len, constfun, constfundata, align)
/* Generate several move instructions to store LEN bytes generated by
CONSTFUN to block TO. (A MEM rtx with BLKmode). CONSTFUNDATA is a
pointer which will be passed as argument in every CONSTFUN call.
- ALIGN is maximum alignment we can assume. */
+ ALIGN is maximum alignment we can assume.
+ If ENDP is 0 return to, if ENDP is 1 return memory at the end ala
+ mempcpy, and if ENDP is 2 return memory the end minus one byte ala
+ stpcpy. */
-void
-store_by_pieces (to, len, constfun, constfundata, align)
- rtx to;
- unsigned HOST_WIDE_INT len;
- rtx (*constfun) PARAMS ((PTR, HOST_WIDE_INT, enum machine_mode));
- PTR constfundata;
- unsigned int align;
+rtx
+store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
+ rtx (*constfun) (void *, HOST_WIDE_INT, enum machine_mode),
+ void *constfundata, unsigned int align, int endp)
{
struct store_by_pieces data;
if (len == 0)
- return;
+ {
+ if (endp == 2)
+ abort ();
+ return to;
+ }
- if (! MOVE_BY_PIECES_P (len, align))
+ if (! STORE_BY_PIECES_P (len, align))
abort ();
to = protect_from_queue (to, 1);
data.constfun = constfun;
@@ -2758,6 +2374,35 @@ store_by_pieces (to, len, constfun, constfundata, align)
data.len = len;
data.to = to;
store_by_pieces_1 (&data, align);
+ if (endp)
+ {
+ rtx to1;
+
+ if (data.reverse)
+ abort ();
+ if (data.autinc_to)
+ {
+ if (endp == 2)
+ {
+ if (HAVE_POST_INCREMENT && data.explicit_inc_to > 0)
+ emit_insn (gen_add2_insn (data.to_addr, constm1_rtx));
+ else
+ data.to_addr = copy_addr_to_reg (plus_constant (data.to_addr,
+ -1));
+ }
+ to1 = adjust_automodify_address (data.to, QImode, data.to_addr,
+ data.offset);
+ }
+ else
+ {
+ if (endp == 2)
+ --data.offset;
+ to1 = adjust_address (data.to, QImode, data.offset);
+ }
+ return to1;
+ }
+ else
+ return data.to;
}
/* Generate several move instructions to clear LEN bytes of block TO. (A MEM
@@ -2765,10 +2410,7 @@ store_by_pieces (to, len, constfun, constfundata, align)
before calling. ALIGN is maximum alignment we can assume. */
static void
-clear_by_pieces (to, len, align)
- rtx to;
- unsigned HOST_WIDE_INT len;
- unsigned int align;
+clear_by_pieces (rtx to, unsigned HOST_WIDE_INT len, unsigned int align)
{
struct store_by_pieces data;
@@ -2786,10 +2428,9 @@ clear_by_pieces (to, len, align)
Return const0_rtx unconditionally. */
static rtx
-clear_by_pieces_1 (data, offset, mode)
- PTR data ATTRIBUTE_UNUSED;
- HOST_WIDE_INT offset ATTRIBUTE_UNUSED;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+clear_by_pieces_1 (void *data ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
return const0_rtx;
}
@@ -2800,9 +2441,8 @@ clear_by_pieces_1 (data, offset, mode)
before calling. ALIGN is maximum alignment we can assume. */
static void
-store_by_pieces_1 (data, align)
- struct store_by_pieces *data;
- unsigned int align;
+store_by_pieces_1 (struct store_by_pieces *data ATTRIBUTE_UNUSED,
+ unsigned int align ATTRIBUTE_UNUSED)
{
rtx to_addr = XEXP (data->to, 0);
unsigned HOST_WIDE_INT max_size = STORE_MAX_PIECES + 1;
@@ -2886,10 +2526,8 @@ store_by_pieces_1 (data, align)
to make a move insn for that mode. DATA has all the other info. */
static void
-store_by_pieces_2 (genfun, mode, data)
- rtx (*genfun) PARAMS ((rtx, ...));
- enum machine_mode mode;
- struct store_by_pieces *data;
+store_by_pieces_2 (rtx (*genfun) (rtx, ...), enum machine_mode mode,
+ struct store_by_pieces *data)
{
unsigned int size = GET_MODE_SIZE (mode);
rtx to1, cst;
@@ -2926,9 +2564,7 @@ store_by_pieces_2 (genfun, mode, data)
its length in bytes. */
rtx
-clear_storage (object, size)
- rtx object;
- rtx size;
+clear_storage (rtx object, rtx size)
{
rtx retval = 0;
unsigned int align = (GET_CODE (object) == MEM ? MEM_ALIGN (object)
@@ -2945,7 +2581,7 @@ clear_storage (object, size)
object = protect_from_queue (object, 1);
size = protect_from_queue (size, 0);
- if (GET_CODE (size) == CONST_INT && INTVAL (size) == 0)
+ if (size == const0_rtx)
;
else if (GET_CODE (size) == CONST_INT
&& CLEAR_BY_PIECES_P (INTVAL (size), align))
@@ -2963,9 +2599,7 @@ clear_storage (object, size)
return true if successful. */
static bool
-clear_storage_via_clrstr (object, size, align)
- rtx object, size;
- unsigned int align;
+clear_storage_via_clrstr (rtx object, rtx size, unsigned int align)
{
/* Try the most limited insn first, because there's no point
including more than one in the machine description unless
@@ -3021,8 +2655,7 @@ clear_storage_via_clrstr (object, size, align)
Return the return value of memset, 0 otherwise. */
static rtx
-clear_storage_via_libcall (object, size)
- rtx object, size;
+clear_storage_via_libcall (rtx object, rtx size)
{
tree call_expr, arg_list, fn, object_tree, size_tree;
enum machine_mode size_mode;
@@ -3082,7 +2715,6 @@ clear_storage_via_libcall (object, size)
call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
call_expr, arg_list, NULL_TREE);
- TREE_SIDE_EFFECTS (call_expr) = 1;
retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
@@ -3101,15 +2733,13 @@ clear_storage_via_libcall (object, size)
static GTY(()) tree block_clear_fn;
-static tree
-clear_storage_libcall_fn (for_call)
- int for_call;
+void
+init_block_clear_fn (const char *asmspec)
{
- static bool emitted_extern;
- tree fn = block_clear_fn, args;
-
- if (!fn)
+ if (!block_clear_fn)
{
+ tree fn, args;
+
if (TARGET_MEM_FUNCTIONS)
{
fn = get_identifier ("memset");
@@ -3133,14 +2763,29 @@ clear_storage_libcall_fn (for_call)
block_clear_fn = fn;
}
+ if (asmspec)
+ {
+ SET_DECL_RTL (block_clear_fn, NULL_RTX);
+ SET_DECL_ASSEMBLER_NAME (block_clear_fn, get_identifier (asmspec));
+ }
+}
+
+static tree
+clear_storage_libcall_fn (int for_call)
+{
+ static bool emitted_extern;
+
+ if (!block_clear_fn)
+ init_block_clear_fn (NULL);
+
if (for_call && !emitted_extern)
{
emitted_extern = true;
- make_decl_rtl (fn, NULL);
- assemble_external (fn);
+ make_decl_rtl (block_clear_fn, NULL);
+ assemble_external (block_clear_fn);
}
- return fn;
+ return block_clear_fn;
}
/* Generate code to copy Y into X.
@@ -3151,12 +2796,11 @@ clear_storage_libcall_fn (for_call)
Return the last instruction emitted. */
rtx
-emit_move_insn (x, y)
- rtx x, y;
+emit_move_insn (rtx x, rtx y)
{
enum machine_mode mode = GET_MODE (x);
rtx y_cst = NULL_RTX;
- rtx last_insn;
+ rtx last_insn, set;
x = protect_from_queue (x, 1);
y = protect_from_queue (y, 0);
@@ -3174,9 +2818,10 @@ emit_move_insn (x, y)
&& (last_insn = compress_float_constant (x, y)))
return last_insn;
+ y_cst = y;
+
if (!LEGITIMATE_CONSTANT_P (y))
{
- y_cst = y;
y = force_const_mem (mode, y);
/* If the target's cannot_force_const_mem prevented the spill,
@@ -3207,7 +2852,10 @@ emit_move_insn (x, y)
last_insn = emit_move_insn_1 (x, y);
- if (y_cst && GET_CODE (x) == REG)
+ if (y_cst && GET_CODE (x) == REG
+ && (set = single_set (last_insn)) != NULL_RTX
+ && SET_DEST (set) == x
+ && ! rtx_equal_p (y_cst, SET_SRC (set)))
set_unique_reg_note (last_insn, REG_EQUAL, y_cst);
return last_insn;
@@ -3218,8 +2866,7 @@ emit_move_insn (x, y)
are basically valid. */
rtx
-emit_move_insn_1 (x, y)
- rtx x, y;
+emit_move_insn_1 (rtx x, rtx y)
{
enum machine_mode mode = GET_MODE (x);
enum machine_mode submode;
@@ -3242,8 +2889,8 @@ emit_move_insn_1 (x, y)
int stack = push_operand (x, GET_MODE (x));
#ifdef PUSH_ROUNDING
- /* In case we output to the stack, but the size is smaller machine can
- push exactly, we need to use move instructions. */
+ /* In case we output to the stack, but the size is smaller than the
+ machine can push exactly, we need to use move instructions. */
if (stack
&& (PUSH_ROUNDING (GET_MODE_SIZE (submode))
!= GET_MODE_SIZE (submode)))
@@ -3300,19 +2947,15 @@ emit_move_insn_1 (x, y)
/* Note that the real part always precedes the imag part in memory
regardless of machine's endianness. */
#ifdef STACK_GROWS_DOWNWARD
- emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
- (gen_rtx_MEM (submode, XEXP (x, 0)),
- gen_imagpart (submode, y)));
- emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
- (gen_rtx_MEM (submode, XEXP (x, 0)),
- gen_realpart (submode, y)));
+ emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
+ gen_imagpart (submode, y));
+ emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
+ gen_realpart (submode, y));
#else
- emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
- (gen_rtx_MEM (submode, XEXP (x, 0)),
- gen_realpart (submode, y)));
- emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
- (gen_rtx_MEM (submode, XEXP (x, 0)),
- gen_imagpart (submode, y)));
+ emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
+ gen_realpart (submode, y));
+ emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
+ gen_imagpart (submode, y));
#endif
}
else
@@ -3387,15 +3030,79 @@ emit_move_insn_1 (x, y)
|| GET_CODE (imagpart_x) == SUBREG))
emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
- emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
- (realpart_x, realpart_y));
- emit_insn (GEN_FCN (mov_optab->handlers[(int) submode].insn_code)
- (imagpart_x, imagpart_y));
+ emit_move_insn (realpart_x, realpart_y);
+ emit_move_insn (imagpart_x, imagpart_y);
}
return get_last_insn ();
}
+ /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
+ find a mode to do it in. If we have a movcc, use it. Otherwise,
+ find the MODE_INT mode of the same width. */
+ else if (GET_MODE_CLASS (mode) == MODE_CC
+ && mov_optab->handlers[(int) mode].insn_code == CODE_FOR_nothing)
+ {
+ enum insn_code insn_code;
+ enum machine_mode tmode = VOIDmode;
+ rtx x1 = x, y1 = y;
+
+ if (mode != CCmode
+ && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
+ tmode = CCmode;
+ else
+ for (tmode = QImode; tmode != VOIDmode;
+ tmode = GET_MODE_WIDER_MODE (tmode))
+ if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
+ break;
+
+ if (tmode == VOIDmode)
+ abort ();
+
+ /* Get X and Y in TMODE. We can't use gen_lowpart here because it
+ may call change_address which is not appropriate if we were
+ called when a reload was in progress. We don't have to worry
+ about changing the address since the size in bytes is supposed to
+ be the same. Copy the MEM to change the mode and move any
+ substitutions from the old MEM to the new one. */
+
+ if (reload_in_progress)
+ {
+ x = gen_lowpart_common (tmode, x1);
+ if (x == 0 && GET_CODE (x1) == MEM)
+ {
+ x = adjust_address_nv (x1, tmode, 0);
+ copy_replacements (x1, x);
+ }
+
+ y = gen_lowpart_common (tmode, y1);
+ if (y == 0 && GET_CODE (y1) == MEM)
+ {
+ y = adjust_address_nv (y1, tmode, 0);
+ copy_replacements (y1, y);
+ }
+ }
+ else
+ {
+ x = gen_lowpart (tmode, x);
+ y = gen_lowpart (tmode, y);
+ }
+
+ insn_code = mov_optab->handlers[(int) tmode].insn_code;
+ return emit_insn (GEN_FCN (insn_code) (x, y));
+ }
+
+ /* Try using a move pattern for the corresponding integer mode. This is
+ only safe when simplify_subreg can convert MODE constants into integer
+ constants. At present, it can only do this reliably if the value
+ fits within a HOST_WIDE_INT. */
+ else if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
+ && (submode = int_mode_for_mode (mode)) != BLKmode
+ && mov_optab->handlers[submode].insn_code != CODE_FOR_nothing)
+ return emit_insn (GEN_FCN (mov_optab->handlers[submode].insn_code)
+ (simplify_gen_subreg (submode, x, mode, 0),
+ simplify_gen_subreg (submode, y, mode, 0)));
+
/* This will handle any multi-word or full-word mode that lacks a move_insn
pattern. However, you will get better code if you define such patterns,
even if they must turn into multiple assembler instructions. */
@@ -3512,8 +3219,7 @@ emit_move_insn_1 (x, y)
move as an extension. */
static rtx
-compress_float_constant (x, y)
- rtx x, y;
+compress_float_constant (rtx x, rtx y)
{
enum machine_mode dstmode = GET_MODE (x);
enum machine_mode orig_srcmode = GET_MODE (y);
@@ -3556,8 +3262,7 @@ compress_float_constant (x, y)
last_insn = get_last_insn ();
if (GET_CODE (x) == REG)
- REG_NOTES (last_insn)
- = gen_rtx_EXPR_LIST (REG_EQUAL, y, REG_NOTES (last_insn));
+ set_unique_reg_note (last_insn, REG_EQUAL, y);
return last_insn;
}
@@ -3577,9 +3282,7 @@ compress_float_constant (x, y)
otherwise, the padding comes at high addresses. */
rtx
-push_block (size, extra, below)
- rtx size;
- int extra, below;
+push_block (rtx size, int extra, int below)
{
rtx temp;
@@ -3628,10 +3331,7 @@ push_block (size, extra, below)
/* Emit single push insn. */
static void
-emit_single_push_insn (mode, x, type)
- rtx x;
- enum machine_mode mode;
- tree type;
+emit_single_push_insn (enum machine_mode mode, rtx x, tree type)
{
rtx dest_addr;
unsigned rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
@@ -3653,12 +3353,48 @@ emit_single_push_insn (mode, x, type)
}
if (GET_MODE_SIZE (mode) == rounded_size)
dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
+ /* If we are to pad downward, adjust the stack pointer first and
+ then store X into the stack location using an offset. This is
+ because emit_move_insn does not know how to pad; it does not have
+ access to type. */
+ else if (FUNCTION_ARG_PADDING (mode, type) == downward)
+ {
+ unsigned padding_size = rounded_size - GET_MODE_SIZE (mode);
+ HOST_WIDE_INT offset;
+
+ emit_move_insn (stack_pointer_rtx,
+ expand_binop (Pmode,
+#ifdef STACK_GROWS_DOWNWARD
+ sub_optab,
+#else
+ add_optab,
+#endif
+ stack_pointer_rtx,
+ GEN_INT (rounded_size),
+ NULL_RTX, 0, OPTAB_LIB_WIDEN));
+
+ offset = (HOST_WIDE_INT) padding_size;
+#ifdef STACK_GROWS_DOWNWARD
+ if (STACK_PUSH_CODE == POST_DEC)
+ /* We have already decremented the stack pointer, so get the
+ previous value. */
+ offset += (HOST_WIDE_INT) rounded_size;
+#else
+ if (STACK_PUSH_CODE == POST_INC)
+ /* We have already incremented the stack pointer, so get the
+ previous value. */
+ offset -= (HOST_WIDE_INT) rounded_size;
+#endif
+ dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
+ }
else
{
#ifdef STACK_GROWS_DOWNWARD
+ /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC. */
dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
GEN_INT (-(HOST_WIDE_INT) rounded_size));
#else
+ /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC. */
dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
GEN_INT (rounded_size));
#endif
@@ -3715,21 +3451,10 @@ emit_single_push_insn (mode, x, type)
of bytes required. */
void
-emit_push_insn (x, mode, type, size, align, partial, reg, extra,
- args_addr, args_so_far, reg_parm_stack_space,
- alignment_pad)
- rtx x;
- enum machine_mode mode;
- tree type;
- rtx size;
- unsigned int align;
- int partial;
- rtx reg;
- int extra;
- rtx args_addr;
- rtx args_so_far;
- int reg_parm_stack_space;
- rtx alignment_pad;
+emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size,
+ unsigned int align, int partial, rtx reg, int extra,
+ rtx args_addr, rtx args_so_far, int reg_parm_stack_space,
+ rtx alignment_pad)
{
rtx xinner;
enum direction stack_direction
@@ -3758,9 +3483,19 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
rtx temp;
int used = partial * UNITS_PER_WORD;
- int offset = used % (PARM_BOUNDARY / BITS_PER_UNIT);
+ int offset;
int skip;
+ if (reg && GET_CODE (reg) == PARALLEL)
+ {
+ /* Use the size of the elt to compute offset. */
+ rtx elt = XEXP (XVECEXP (reg, 0, 0), 0);
+ used = partial * GET_MODE_SIZE (GET_MODE (elt));
+ offset = used % (PARM_BOUNDARY / BITS_PER_UNIT);
+ }
+ else
+ offset = used % (PARM_BOUNDARY / BITS_PER_UNIT);
+
if (size == 0)
abort ();
@@ -3786,6 +3521,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
&& PUSH_ARGS
&& GET_CODE (size) == CONST_INT
&& skip == 0
+ && MEM_ALIGN (xinner) >= align
&& (MOVE_BY_PIECES_P ((unsigned) INTVAL (size) - used, align))
/* Here we avoid the case of a structure whose weak alignment
forces many pushes of a small amount of data,
@@ -3803,7 +3539,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
&& where_pad != none && where_pad != stack_direction)
anti_adjust_stack (GEN_INT (extra));
- move_by_pieces (NULL, xinner, INTVAL (size) - used, align);
+ move_by_pieces (NULL, xinner, INTVAL (size) - used, align, 0);
}
else
#endif /* PUSH_ROUNDING */
@@ -3937,7 +3673,6 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
else
{
rtx addr;
- rtx target = NULL_RTX;
rtx dest;
/* Push padding now if padding above and stack grows down,
@@ -3961,7 +3696,6 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
else
addr = memory_address (mode, gen_rtx_PLUS (Pmode, args_addr,
args_so_far));
- target = addr;
dest = gen_rtx_MEM (mode, addr);
if (type != 0)
{
@@ -3985,7 +3719,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
/* Handle calls that pass values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
if (GET_CODE (reg) == PARALLEL)
- emit_group_load (reg, x, -1); /* ??? size? */
+ emit_group_load (reg, x, type, -1);
else
move_block_to_reg (REGNO (reg), x, partial, mode);
}
@@ -4001,8 +3735,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
operations. */
static rtx
-get_subtarget (x)
- rtx x;
+get_subtarget (rtx x)
{
return ((x == 0
/* Only registers can be subtargets. */
@@ -4021,18 +3754,10 @@ get_subtarget (x)
If WANT_VALUE is nonzero, return an rtx for the value of TO.
(This may contain a QUEUED rtx;
if the value is constant, this rtx is a constant.)
- Otherwise, the returned value is NULL_RTX.
-
- SUGGEST_REG is no longer actually used.
- It used to mean, copy the value through a register
- and return that register, if that is possible.
- We now use WANT_VALUE to decide whether to do this. */
+ Otherwise, the returned value is NULL_RTX. */
rtx
-expand_assignment (to, from, want_value, suggest_reg)
- tree to, from;
- int want_value;
- int suggest_reg ATTRIBUTE_UNUSED;
+expand_assignment (tree to, tree from, int want_value)
{
rtx to_rtx = 0;
rtx result;
@@ -4105,8 +3830,8 @@ expand_assignment (to, from, want_value, suggest_reg)
}
to_rtx = offset_address (to_rtx, offset_rtx,
- highest_pow2_factor_for_type (TREE_TYPE (to),
- offset));
+ highest_pow2_factor_for_target (to,
+ offset));
}
if (GET_CODE (to_rtx) == MEM)
@@ -4128,7 +3853,11 @@ expand_assignment (to, from, want_value, suggest_reg)
}
if (TREE_CODE (to) == COMPONENT_REF
- && TREE_READONLY (TREE_OPERAND (to, 1)))
+ && TREE_READONLY (TREE_OPERAND (to, 1))
+ /* We can't assert that a MEM won't be set more than once
+ if the component is not addressable because another
+ non-addressable component may be referenced by the same MEM. */
+ && ! (GET_CODE (to_rtx) == MEM && ! can_address_p (to)))
{
if (to_rtx == orig_to_rtx)
to_rtx = copy_rtx (to_rtx);
@@ -4173,7 +3902,7 @@ expand_assignment (to, from, want_value, suggest_reg)
since it might be a promoted variable where the zero- or sign- extension
needs to be done. Handling this in the normal way is safe because no
computation is done before the call. */
- if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from)
+ if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from, from)
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
&& ! ((TREE_CODE (to) == VAR_DECL || TREE_CODE (to) == PARM_DECL)
&& GET_CODE (DECL_RTL (to)) == REG))
@@ -4188,16 +3917,14 @@ expand_assignment (to, from, want_value, suggest_reg)
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
if (GET_CODE (to_rtx) == PARALLEL)
- emit_group_load (to_rtx, value, int_size_in_bytes (TREE_TYPE (from)));
+ emit_group_load (to_rtx, value, TREE_TYPE (from),
+ int_size_in_bytes (TREE_TYPE (from)));
else if (GET_MODE (to_rtx) == BLKmode)
emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
else
{
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (POINTER_TYPE_P (TREE_TYPE (to))
- && GET_MODE (to_rtx) != GET_MODE (value))
+ if (POINTER_TYPE_P (TREE_TYPE (to)))
value = convert_memory_address (GET_MODE (to_rtx), value);
-#endif
emit_move_insn (to_rtx, value);
}
preserve_temp_slots (to_rtx);
@@ -4222,7 +3949,8 @@ expand_assignment (to, from, want_value, suggest_reg)
temp = expand_expr (from, 0, GET_MODE (to_rtx), 0);
if (GET_CODE (to_rtx) == PARALLEL)
- emit_group_load (to_rtx, temp, int_size_in_bytes (TREE_TYPE (from)));
+ emit_group_load (to_rtx, temp, TREE_TYPE (from),
+ int_size_in_bytes (TREE_TYPE (from)));
else
emit_move_insn (to_rtx, temp);
@@ -4304,12 +4032,11 @@ expand_assignment (to, from, want_value, suggest_reg)
stack, and block moves may need to be treated specially. */
rtx
-store_expr (exp, target, want_value)
- tree exp;
- rtx target;
- int want_value;
+store_expr (tree exp, rtx target, int want_value)
{
rtx temp;
+ rtx alt_rtl = NULL_RTX;
+ rtx mark = mark_queue ();
int dont_return_target = 0;
int dont_store_target = 0;
@@ -4317,7 +4044,7 @@ store_expr (exp, target, want_value)
{
/* C++ can generate ?: expressions with a throw expression in one
branch and an rvalue in the other. Here, we resolve attempts to
- store the throw expression's nonexistant result. */
+ store the throw expression's nonexistent result. */
if (want_value)
abort ();
expand_expr (exp, const0_rtx, VOIDmode, 0);
@@ -4446,12 +4173,12 @@ store_expr (exp, target, want_value)
temp = expand_expr (exp, inner_target, VOIDmode,
want_value & 2 ? EXPAND_STACK_PARM : EXPAND_NORMAL);
- /* If TEMP is a volatile MEM and we want a result value, make
- the access now so it gets done only once. Likewise if
- it contains TARGET. */
- if (GET_CODE (temp) == MEM && (want_value & 1) != 0
- && (MEM_VOLATILE_P (temp)
- || reg_mentioned_p (SUBREG_REG (target), XEXP (temp, 0))))
+ /* If TEMP is a MEM and we want a result value, make the access
+ now so it gets done only once. Strictly speaking, this is
+ only necessary if the MEM is volatile, or if the address
+ overlaps TARGET. But not performing the load twice also
+ reduces the amount of rtl we generate and then have to CSE. */
+ if (GET_CODE (temp) == MEM && (want_value & 1) != 0)
temp = copy_to_reg (temp);
/* If TEMP is a VOIDmode constant, use convert_modes to make
@@ -4491,8 +4218,10 @@ store_expr (exp, target, want_value)
}
else
{
- temp = expand_expr (exp, target, GET_MODE (target),
- want_value & 2 ? EXPAND_STACK_PARM : EXPAND_NORMAL);
+ temp = expand_expr_real (exp, target, GET_MODE (target),
+ (want_value & 2
+ ? EXPAND_STACK_PARM : EXPAND_NORMAL),
+ &alt_rtl);
/* Return TARGET if it's a specified hardware register.
If TARGET is a volatile mem ref, either return TARGET
or return a reg copied *from* TARGET; ANSI requires this.
@@ -4519,7 +4248,11 @@ store_expr (exp, target, want_value)
temp, TREE_UNSIGNED (TREE_TYPE (exp)));
/* If value was not generated in the target, store it there.
- Convert the value to TARGET's type first if necessary.
+ Convert the value to TARGET's type first if necessary and emit the
+ pending incrementations that have been queued when expanding EXP.
+ Note that we cannot emit the whole queue blindly because this will
+ effectively disable the POST_INC optimization later.
+
If TEMP and TARGET compare equal according to rtx_equal_p, but
one or both of them are volatile memory refs, we have to distinguish
two cases:
@@ -4537,18 +4270,19 @@ store_expr (exp, target, want_value)
|| side_effects_p (target))))
&& TREE_CODE (exp) != ERROR_MARK
&& ! dont_store_target
- /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
- but TARGET is not valid memory reference, TEMP will differ
- from TARGET although it is really the same location. */
- && (TREE_CODE_CLASS (TREE_CODE (exp)) != 'd'
- || target != DECL_RTL_IF_SET (exp))
+ /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
+ but TARGET is not valid memory reference, TEMP will differ
+ from TARGET although it is really the same location. */
+ && !(alt_rtl && rtx_equal_p (alt_rtl, target))
/* If there's nothing to copy, don't bother. Don't call expr_size
unless necessary, because some front-ends (C++) expr_size-hook
aborts on objects that are not supposed to be bit-copied or
bit-initialized. */
&& expr_size (exp) != const0_rtx)
{
+ emit_insns_enqueued_after_mark (mark);
target = protect_from_queue (target, 1);
+ temp = protect_from_queue (temp, 0);
if (GET_MODE (temp) != GET_MODE (target)
&& GET_MODE (temp) != VOIDmode)
{
@@ -4635,7 +4369,8 @@ store_expr (exp, target, want_value)
/* Handle calls that return values in multiple non-contiguous locations.
The Irix 6 ABI has examples of this. */
else if (GET_CODE (target) == PARALLEL)
- emit_group_load (target, temp, int_size_in_bytes (TREE_TYPE (exp)));
+ emit_group_load (target, temp, TREE_TYPE (exp),
+ int_size_in_bytes (TREE_TYPE (exp)));
else if (GET_MODE (temp) == BLKmode)
emit_block_move (target, temp, expr_size (exp),
(want_value & 2
@@ -4664,11 +4399,10 @@ store_expr (exp, target, want_value)
return target;
}
-/* Return 1 if EXP just contains zeros. */
+/* Return 1 if EXP just contains zeros. FIXME merge with initializer_zerop. */
static int
-is_zeros_p (exp)
- tree exp;
+is_zeros_p (tree exp)
{
tree elt;
@@ -4714,9 +4448,8 @@ is_zeros_p (exp)
/* Return 1 if EXP contains mostly (3/4) zeros. */
-static int
-mostly_zeros_p (exp)
- tree exp;
+int
+mostly_zeros_p (tree exp)
{
if (TREE_CODE (exp) == CONSTRUCTOR)
{
@@ -4757,15 +4490,9 @@ mostly_zeros_p (exp)
clear a substructure if the outer structure has already been cleared. */
static void
-store_constructor_field (target, bitsize, bitpos, mode, exp, type, cleared,
- alias_set)
- rtx target;
- unsigned HOST_WIDE_INT bitsize;
- HOST_WIDE_INT bitpos;
- enum machine_mode mode;
- tree exp, type;
- int cleared;
- int alias_set;
+store_constructor_field (rtx target, unsigned HOST_WIDE_INT bitsize,
+ HOST_WIDE_INT bitpos, enum machine_mode mode,
+ tree exp, tree type, int cleared, int alias_set)
{
if (TREE_CODE (exp) == CONSTRUCTOR
&& bitpos % BITS_PER_UNIT == 0
@@ -4807,11 +4534,7 @@ store_constructor_field (target, bitsize, bitpos, mode, exp, type, cleared,
which has been packed to exclude padding bits. */
static void
-store_constructor (exp, target, cleared, size)
- tree exp;
- rtx target;
- int cleared;
- HOST_WIDE_INT size;
+store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
{
tree type = TREE_TYPE (exp);
#ifdef WORD_REGISTER_OPERATIONS
@@ -4852,14 +4575,36 @@ store_constructor (exp, target, cleared, size)
clear the whole structure first. Don't do this if TARGET is a
register whose mode size isn't equal to SIZE since clear_storage
can't handle this case. */
- else if (((list_length (CONSTRUCTOR_ELTS (exp)) != fields_length (type))
- || mostly_zeros_p (exp))
+ else if (size > 0
+ && ((list_length (CONSTRUCTOR_ELTS (exp)) != fields_length (type))
+ || mostly_zeros_p (exp))
&& (GET_CODE (target) != REG
|| ((HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (target))
== size)))
{
- clear_storage (target, GEN_INT (size));
+ rtx xtarget = target;
+
+ if (RTX_UNCHANGING_P (target))
+ {
+ xtarget = copy_rtx (target);
+ RTX_UNCHANGING_P (xtarget) = 0;
+ }
+
+ clear_storage (xtarget, GEN_INT (size));
cleared = 1;
+ if (RTX_UNCHANGING_P (target) || readonly_fields_p (type))
+ {
+ /* ??? Emit a blockage to prevent the scheduler from swapping
+ the memory write issued above without the /u flag and
+ memory writes that will be issued later with it.
+ Note that the clearing above cannot be simply disabled
+ in the unsafe cases because the C front-end relies on
+ it to implement the semantics of constructors for
+ automatic objects. However, not all machine descriptions
+ define a blockage insn, so emit an ASM_INPUT to
+ act as one.  */
+ emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
+ }
}
if (! cleared)
@@ -4875,7 +4620,6 @@ store_constructor (exp, target, cleared, size)
enum machine_mode mode;
HOST_WIDE_INT bitsize;
HOST_WIDE_INT bitpos = 0;
- int unsignedp;
tree offset;
rtx to_rtx = target;
@@ -4893,7 +4637,6 @@ store_constructor (exp, target, cleared, size)
else
bitsize = -1;
- unsignedp = TREE_UNSIGNED (field);
mode = DECL_MODE (field);
if (DECL_BIT_FIELD (field))
mode = VOIDmode;
@@ -4912,7 +4655,7 @@ store_constructor (exp, target, cleared, size)
{
rtx offset_rtx;
- if (contains_placeholder_p (offset))
+ if (CONTAINS_PLACEHOLDER_P (offset))
offset = build (WITH_RECORD_EXPR, sizetype,
offset, make_tree (TREE_TYPE (exp), target));
@@ -4994,6 +4737,10 @@ store_constructor (exp, target, cleared, size)
int const_bounds_p;
HOST_WIDE_INT minelt = 0;
HOST_WIDE_INT maxelt = 0;
+ int icode = 0;
+ rtx *vector = NULL;
+ int elt_size = 0;
+ unsigned n_elts = 0;
/* Vectors are like arrays, but the domain is stored via an array
type indirectly. */
@@ -5004,6 +4751,22 @@ store_constructor (exp, target, cleared, size)
it always will. */
domain = TYPE_DEBUG_REPRESENTATION_TYPE (type);
domain = TYPE_DOMAIN (TREE_TYPE (TYPE_FIELDS (domain)));
+ if (REG_P (target) && VECTOR_MODE_P (GET_MODE (target)))
+ {
+ enum machine_mode mode = GET_MODE (target);
+
+ icode = (int) vec_init_optab->handlers[mode].insn_code;
+ if (icode != CODE_FOR_nothing)
+ {
+ unsigned int i;
+
+ elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
+ n_elts = (GET_MODE_SIZE (mode) / elt_size);
+ vector = alloca (n_elts);
+ for (i = 0; i < n_elts; i++)
+ vector [i] = CONST0_RTX (GET_MODE_INNER (mode));
+ }
+ }
}
const_bounds_p = (TYPE_MIN_VALUE (domain)
@@ -5068,14 +4831,33 @@ store_constructor (exp, target, cleared, size)
need_to_clear = 1;
}
- if (need_to_clear && size > 0)
+ if (need_to_clear && size > 0 && !vector)
{
if (! cleared)
{
if (REG_P (target))
- emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
+ emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
else
- clear_storage (target, GEN_INT (size));
+ {
+ rtx xtarget = target;
+
+ if (RTX_UNCHANGING_P (target))
+ {
+ xtarget = copy_rtx (target);
+ RTX_UNCHANGING_P (xtarget) = 0;
+ }
+
+ clear_storage (xtarget, GEN_INT (size));
+
+ if (RTX_UNCHANGING_P (target))
+ {
+ /* ??? Emit a blockage to prevent the scheduler from
+ swapping the memory write issued above without the
+ /u flag and memory writes that will be issued later
+ with it. */
+ emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
+ }
+ }
}
cleared = 1;
}
@@ -5114,11 +4896,14 @@ store_constructor (exp, target, cleared, size)
{
tree lo_index = TREE_OPERAND (index, 0);
tree hi_index = TREE_OPERAND (index, 1);
- rtx index_r, pos_rtx, hi_r, loop_top, loop_end;
+ rtx index_r, pos_rtx, loop_end;
struct nesting *loop;
HOST_WIDE_INT lo, hi, count;
tree position;
+ if (vector)
+ abort ();
+
/* If the range is constant and "small", unroll the loop. */
if (const_bounds_p
&& host_integerp (lo_index, 0)
@@ -5153,8 +4938,7 @@ store_constructor (exp, target, cleared, size)
}
else
{
- hi_r = expand_expr (hi_index, NULL_RTX, VOIDmode, 0);
- loop_top = gen_label_rtx ();
+ expand_expr (hi_index, NULL_RTX, VOIDmode, 0);
loop_end = gen_label_rtx ();
unsignedp = TREE_UNSIGNED (domain);
@@ -5211,6 +4995,9 @@ store_constructor (exp, target, cleared, size)
{
tree position;
+ if (vector)
+ abort ();
+
if (index == 0)
index = ssize_int (1);
@@ -5228,6 +5015,16 @@ store_constructor (exp, target, cleared, size)
xtarget = adjust_address (xtarget, mode, 0);
store_expr (value, xtarget, 0);
}
+ else if (vector)
+ {
+ int pos;
+
+ if (index != 0)
+ pos = tree_low_cst (index, 0) - minelt;
+ else
+ pos = i;
+ vector[pos] = expand_expr (value, NULL_RTX, VOIDmode, 0);
+ }
else
{
if (index != 0)
@@ -5243,12 +5040,16 @@ store_constructor (exp, target, cleared, size)
target = copy_rtx (target);
MEM_KEEP_ALIAS_SET_P (target) = 1;
}
-
store_constructor_field (target, bitsize, bitpos, mode, value,
type, cleared, get_alias_set (elttype));
-
}
}
+ if (vector)
+ {
+ emit_insn (GEN_FCN (icode) (target,
+ gen_rtx_PARALLEL (GET_MODE (target),
+ gen_rtvec_v (n_elts, vector))));
+ }
}
/* Set constructor assignments. */
@@ -5293,7 +5094,7 @@ store_constructor (exp, target, cleared, size)
{
unsigned int set_word_size = TYPE_ALIGN (TREE_TYPE (exp));
enum machine_mode mode = mode_for_size (set_word_size, MODE_INT, 1);
- char *bit_buffer = (char *) alloca (nbits);
+ char *bit_buffer = alloca (nbits);
HOST_WIDE_INT word = 0;
unsigned int bit_pos = 0;
unsigned int ibit = 0;
@@ -5315,7 +5116,7 @@ store_constructor (exp, target, cleared, size)
{
if (word != 0 || ! cleared)
{
- rtx datum = GEN_INT (word);
+ rtx datum = gen_int_mode (word, mode);
rtx to_rtx;
/* The assumption here is that it is safe to use
@@ -5415,8 +5216,8 @@ store_constructor (exp, target, cleared, size)
TYPE_MODE (sizetype));
}
else
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__setbits"),
- LCT_NORMAL, VOIDmode, 4, XEXP (targetx, 0),
+ emit_library_call (setbits_libfunc, LCT_NORMAL,
+ VOIDmode, 4, XEXP (targetx, 0),
Pmode, bitlength_rtx, TYPE_MODE (sizetype),
startbit_rtx, TYPE_MODE (sizetype),
endbit_rtx, TYPE_MODE (sizetype));
@@ -5449,17 +5250,9 @@ store_constructor (exp, target, cleared, size)
reference to the containing structure. */
static rtx
-store_field (target, bitsize, bitpos, mode, exp, value_mode, unsignedp, type,
- alias_set)
- rtx target;
- HOST_WIDE_INT bitsize;
- HOST_WIDE_INT bitpos;
- enum machine_mode mode;
- tree exp;
- enum machine_mode value_mode;
- int unsignedp;
- tree type;
- int alias_set;
+store_field (rtx target, HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
+ enum machine_mode mode, tree exp, enum machine_mode value_mode,
+ int unsignedp, tree type, int alias_set)
{
HOST_WIDE_INT width_mask = 0;
@@ -5470,7 +5263,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, unsignedp, type,
side-effects. */
if (bitsize == 0)
return expand_expr (exp, const0_rtx, VOIDmode, 0);
- else if (bitsize >=0 && bitsize < HOST_BITS_PER_WIDE_INT)
+ else if (bitsize >= 0 && bitsize < HOST_BITS_PER_WIDE_INT)
width_mask = ((HOST_WIDE_INT) 1 << bitsize) - 1;
/* If we are storing into an unaligned field of an aligned union that is
@@ -5482,15 +5275,13 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, unsignedp, type,
that object. Finally, load from the object into TARGET. This is not
very efficient in general, but should only be slightly more expensive
than the otherwise-required unaligned accesses. Perhaps this can be
- cleaned up later. */
+ cleaned up later. It's tempting to make OBJECT readonly, but it's set
+ twice, once with emit_move_insn and once via store_field. */
if (mode == BLKmode
&& (GET_CODE (target) == REG || GET_CODE (target) == SUBREG))
{
- rtx object
- = assign_temp
- (build_qualified_type (type, TYPE_QUALS (type) | TYPE_QUAL_CONST),
- 0, 1, 1);
+ rtx object = assign_temp (type, 0, 1, 1);
rtx blk_object = adjust_address (object, BLKmode, 0);
if (bitsize != (HOST_WIDE_INT) GET_MODE_BITSIZE (GET_MODE (target)))
@@ -5526,9 +5317,11 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, unsignedp, type,
|| GET_CODE (target) == SUBREG
/* If the field isn't aligned enough to store as an ordinary memref,
store it as a bit field. */
- || (mode != BLKmode && SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (target))
- && (MEM_ALIGN (target) < GET_MODE_ALIGNMENT (mode)
- || bitpos % GET_MODE_ALIGNMENT (mode)))
+ || (mode != BLKmode
+ && ((((MEM_ALIGN (target) < GET_MODE_ALIGNMENT (mode))
+ || bitpos % GET_MODE_ALIGNMENT (mode))
+ && SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (target)))
+ || (bitpos % BITS_PER_UNIT != 0)))
/* If the RHS and field are a constant size and the size of the
RHS isn't the same size as the bitfield, we must use bitfield
operations. */
@@ -5548,7 +5341,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, unsignedp, type,
temp = expand_shift (RSHIFT_EXPR, GET_MODE (temp), temp,
size_int (GET_MODE_BITSIZE (GET_MODE (temp))
- bitsize),
- temp, 1);
+ NULL_RTX, 1);
/* Unless MODE is VOIDmode or BLKmode, convert TEMP to
MODE. */
@@ -5663,15 +5456,10 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, unsignedp, type,
this case, but the address of the object can be found. */
tree
-get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
- punsignedp, pvolatilep)
- tree exp;
- HOST_WIDE_INT *pbitsize;
- HOST_WIDE_INT *pbitpos;
- tree *poffset;
- enum machine_mode *pmode;
- int *punsignedp;
- int *pvolatilep;
+get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
+ HOST_WIDE_INT *pbitpos, tree *poffset,
+ enum machine_mode *pmode, int *punsignedp,
+ int *pvolatilep)
{
tree size_tree = 0;
enum machine_mode mode = VOIDmode;
@@ -5730,8 +5518,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
made during type construction. */
if (this_offset == 0)
break;
- else if (! TREE_CONSTANT (this_offset)
- && contains_placeholder_p (this_offset))
+ else if (CONTAINS_PLACEHOLDER_P (this_offset))
this_offset = build (WITH_RECORD_EXPR, sizetype, this_offset, exp);
offset = size_binop (PLUS_EXPR, offset, this_offset);
@@ -5761,11 +5548,9 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
/* If the index has a self-referential type, pass it to a
WITH_RECORD_EXPR; if the component size is, pass our
component to one. */
- if (! TREE_CONSTANT (index)
- && contains_placeholder_p (index))
+ if (CONTAINS_PLACEHOLDER_P (index))
index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, exp);
- if (! TREE_CONSTANT (unit_size)
- && contains_placeholder_p (unit_size))
+ if (CONTAINS_PLACEHOLDER_P (unit_size))
unit_size = build (WITH_RECORD_EXPR, sizetype, unit_size, array);
offset = size_binop (PLUS_EXPR, offset,
@@ -5788,8 +5573,20 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
continue;
}
+
+ /* We can go inside most conversions: all NON_VALUE_EXPRs, all normal
+ conversions that don't change the mode, and all view conversions
+ except those that need to "step up" the alignment. */
else if (TREE_CODE (exp) != NON_LVALUE_EXPR
- && TREE_CODE (exp) != VIEW_CONVERT_EXPR
+ && ! (TREE_CODE (exp) == VIEW_CONVERT_EXPR
+ && ! ((TYPE_ALIGN (TREE_TYPE (exp))
+ > TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0))))
+ && STRICT_ALIGNMENT
+ && (TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0)))
+ < BIGGEST_ALIGNMENT)
+ && (TYPE_ALIGN_OK (TREE_TYPE (exp))
+ || TYPE_ALIGN_OK (TREE_TYPE
+ (TREE_OPERAND (exp, 0))))))
&& ! ((TREE_CODE (exp) == NOP_EXPR
|| TREE_CODE (exp) == CONVERT_EXPR)
&& (TYPE_MODE (TREE_TYPE (exp))
@@ -5821,8 +5618,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
/* Return 1 if T is an expression that get_inner_reference handles. */
int
-handled_component_p (t)
- tree t;
+handled_component_p (tree t)
{
switch (TREE_CODE (t))
{
@@ -5834,6 +5630,9 @@ handled_component_p (t)
case VIEW_CONVERT_EXPR:
return 1;
+ /* ??? Sure they are handled, but get_inner_reference may return
+ a different PBITSIZE, depending upon whether the expression is
+ wrapped up in a NOP_EXPR or not, e.g. for bitfields. */
case NOP_EXPR:
case CONVERT_EXPR:
return (TYPE_MODE (TREE_TYPE (t))
@@ -5852,8 +5651,7 @@ handled_component_p (t)
The returned value may be a REG, SUBREG, MEM or constant. */
rtx
-force_operand (value, target)
- rtx value, target;
+force_operand (rtx value, rtx target)
{
rtx op1, op2;
/* Use subtarget as the target for operand 0 of a binary operation. */
@@ -5984,10 +5782,7 @@ force_operand (value, target)
searches for optimization opportunities. */
int
-safe_from_p (x, exp, top_p)
- rtx x;
- tree exp;
- int top_p;
+safe_from_p (rtx x, tree exp, int top_p)
{
rtx exp_rtl = 0;
int i, nops;
@@ -6026,7 +5821,7 @@ safe_from_p (x, exp, top_p)
/* A SAVE_EXPR might appear many times in the expression passed to the
top-level safe_from_p call, and if it has a complex subexpression,
examining it multiple times could result in a combinatorial explosion.
- E.g. on an Alpha running at least 200MHz, a Fortran test case compiled
+ E.g. on an Alpha running at least 200MHz, a Fortran testcase compiled
with optimization took about 28 minutes to compile -- even though it was
only a few lines long. So we mark each SAVE_EXPR we see with TREE_PRIVATE
and turn that off when we are done. We keep a list of the SAVE_EXPRs
@@ -6080,7 +5875,7 @@ safe_from_p (x, exp, top_p)
case '<':
if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0))
return 0;
- /* FALLTHRU */
+ /* Fall through. */
case '1':
return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
@@ -6174,10 +5969,6 @@ safe_from_p (x, exp, top_p)
part of the expression. */
return safe_from_p (x, TREE_OPERAND (exp, 1), 0);
- case METHOD_CALL_EXPR:
- /* This takes an rtx argument, but shouldn't appear here. */
- abort ();
-
default:
break;
}
@@ -6228,8 +6019,7 @@ safe_from_p (x, exp, top_p)
variable or parameter; else return 0. */
static rtx
-var_rtx (exp)
- tree exp;
+var_rtx (tree exp)
{
STRIP_NOPS (exp);
switch (TREE_CODE (exp))
@@ -6241,70 +6031,14 @@ var_rtx (exp)
return 0;
}
}
-
-#ifdef MAX_INTEGER_COMPUTATION_MODE
-
-void
-check_max_integer_computation_mode (exp)
- tree exp;
-{
- enum tree_code code;
- enum machine_mode mode;
-
- /* Strip any NOPs that don't change the mode. */
- STRIP_NOPS (exp);
- code = TREE_CODE (exp);
-
- /* We must allow conversions of constants to MAX_INTEGER_COMPUTATION_MODE. */
- if (code == NOP_EXPR
- && TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST)
- return;
-
- /* First check the type of the overall operation. We need only look at
- unary, binary and relational operations. */
- if (TREE_CODE_CLASS (code) == '1'
- || TREE_CODE_CLASS (code) == '2'
- || TREE_CODE_CLASS (code) == '<')
- {
- mode = TYPE_MODE (TREE_TYPE (exp));
- if (GET_MODE_CLASS (mode) == MODE_INT
- && mode > MAX_INTEGER_COMPUTATION_MODE)
- internal_error ("unsupported wide integer operation");
- }
-
- /* Check operand of a unary op. */
- if (TREE_CODE_CLASS (code) == '1')
- {
- mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
- if (GET_MODE_CLASS (mode) == MODE_INT
- && mode > MAX_INTEGER_COMPUTATION_MODE)
- internal_error ("unsupported wide integer operation");
- }
-
- /* Check operands of a binary/comparison op. */
- if (TREE_CODE_CLASS (code) == '2' || TREE_CODE_CLASS (code) == '<')
- {
- mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
- if (GET_MODE_CLASS (mode) == MODE_INT
- && mode > MAX_INTEGER_COMPUTATION_MODE)
- internal_error ("unsupported wide integer operation");
-
- mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 1)));
- if (GET_MODE_CLASS (mode) == MODE_INT
- && mode > MAX_INTEGER_COMPUTATION_MODE)
- internal_error ("unsupported wide integer operation");
- }
-}
-#endif
/* Return the highest power of two that EXP is known to be a multiple of.
This is used in updating alignment of MEMs in array references. */
-static HOST_WIDE_INT
-highest_pow2_factor (exp)
- tree exp;
+static unsigned HOST_WIDE_INT
+highest_pow2_factor (tree exp)
{
- HOST_WIDE_INT c0, c1;
+ unsigned HOST_WIDE_INT c0, c1;
switch (TREE_CODE (exp))
{
@@ -6312,7 +6046,7 @@ highest_pow2_factor (exp)
/* We can find the lowest bit that's a one. If the low
HOST_BITS_PER_WIDE_INT bits are zero, return BIGGEST_ALIGNMENT.
We need to handle this case since we can find it in a COND_EXPR,
- a MIN_EXPR, or a MAX_EXPR. If the constant overlows, we have an
+ a MIN_EXPR, or a MAX_EXPR. If the constant overflows, we have an
erroneous program, so return BIGGEST_ALIGNMENT to avoid any
later ICE. */
if (TREE_CONSTANT_OVERFLOW (exp))
@@ -6367,19 +6101,22 @@ highest_pow2_factor (exp)
return 1;
}
-/* Similar, except that it is known that the expression must be a multiple
- of the alignment of TYPE. */
+/* Similar, except that the alignment requirements of TARGET are
+ taken into account. Assume it is at least as aligned as its
+ type, unless it is a COMPONENT_REF in which case the layout of
+ the structure gives the alignment. */
-static HOST_WIDE_INT
-highest_pow2_factor_for_type (type, exp)
- tree type;
- tree exp;
+static unsigned HOST_WIDE_INT
+highest_pow2_factor_for_target (tree target, tree exp)
{
- HOST_WIDE_INT type_align, factor;
+ unsigned HOST_WIDE_INT target_align, factor;
factor = highest_pow2_factor (exp);
- type_align = TYPE_ALIGN (type) / BITS_PER_UNIT;
- return MAX (factor, type_align);
+ if (TREE_CODE (target) == COMPONENT_REF)
+ target_align = DECL_ALIGN (TREE_OPERAND (target, 1)) / BITS_PER_UNIT;
+ else
+ target_align = TYPE_ALIGN (TREE_TYPE (target)) / BITS_PER_UNIT;
+ return MAX (factor, target_align);
}
/* Return an object on the placeholder list that matches EXP, a
@@ -6391,9 +6128,7 @@ highest_pow2_factor_for_type (type, exp)
the placeholder list at which the object is found is placed. */
tree
-find_placeholder (exp, plist)
- tree exp;
- tree *plist;
+find_placeholder (tree exp, tree *plist)
{
tree type = TREE_TYPE (exp);
tree placeholder_expr;
@@ -6447,6 +6182,34 @@ find_placeholder (exp, plist)
return 0;
}
+
+/* Subroutine of expand_expr. Expand the two operands of a binary
+ expression EXP0 and EXP1 placing the results in OP0 and OP1.
+ The value may be stored in TARGET if TARGET is nonzero. The
+ MODIFIER argument is as documented by expand_expr. */
+
+static void
+expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1,
+ enum expand_modifier modifier)
+{
+ if (! safe_from_p (target, exp1, 1))
+ target = 0;
+ if (operand_equal_p (exp0, exp1, 0))
+ {
+ *op0 = expand_expr (exp0, target, VOIDmode, modifier);
+ *op1 = copy_rtx (*op0);
+ }
+ else
+ {
+ /* If we need to preserve evaluation order, copy exp0 into its own
+ temporary variable so that it can't be clobbered by exp1. */
+ if (flag_evaluation_order && TREE_SIDE_EFFECTS (exp1))
+ exp0 = save_expr (exp0);
+ *op0 = expand_expr (exp0, target, VOIDmode, modifier);
+ *op1 = expand_expr (exp1, NULL_RTX, VOIDmode, modifier);
+ }
+}
+
/* expand_expr: generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null.
@@ -6488,14 +6251,17 @@ find_placeholder (exp, plist)
marked TARGET so that it's safe from being trashed by libcalls. We
don't want to use TARGET for anything but the final result;
Intermediate values must go elsewhere. Additionally, calls to
- emit_block_move will be flagged with BLOCK_OP_CALL_PARM. */
+ emit_block_move will be flagged with BLOCK_OP_CALL_PARM.
+
+ If EXP is a VAR_DECL whose DECL_RTL was a MEM with an invalid
+ address, and ALT_RTL is non-NULL, then *ALT_RTL is set to the
+ DECL_RTL of the VAR_DECL. *ALT_RTL is also set if EXP is a
+ COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
+ recursively. */
rtx
-expand_expr (exp, target, tmode, modifier)
- tree exp;
- rtx target;
- enum machine_mode tmode;
- enum expand_modifier modifier;
+expand_expr_real (tree exp, rtx target, enum machine_mode tmode,
+ enum expand_modifier modifier, rtx *alt_rtl)
{
rtx op0, op1, temp;
tree type = TREE_TYPE (exp);
@@ -6579,58 +6345,17 @@ expand_expr (exp, target, tmode, modifier)
target = 0;
}
-#ifdef MAX_INTEGER_COMPUTATION_MODE
- /* Only check stuff here if the mode we want is different from the mode
- of the expression; if it's the same, check_max_integer_computiation_mode
- will handle it. Do we really need to check this stuff at all? */
-
- if (target
- && GET_MODE (target) != mode
- && TREE_CODE (exp) != INTEGER_CST
- && TREE_CODE (exp) != PARM_DECL
- && TREE_CODE (exp) != ARRAY_REF
- && TREE_CODE (exp) != ARRAY_RANGE_REF
- && TREE_CODE (exp) != COMPONENT_REF
- && TREE_CODE (exp) != BIT_FIELD_REF
- && TREE_CODE (exp) != INDIRECT_REF
- && TREE_CODE (exp) != CALL_EXPR
- && TREE_CODE (exp) != VAR_DECL
- && TREE_CODE (exp) != RTL_EXPR)
- {
- enum machine_mode mode = GET_MODE (target);
-
- if (GET_MODE_CLASS (mode) == MODE_INT
- && mode > MAX_INTEGER_COMPUTATION_MODE)
- internal_error ("unsupported wide integer operation");
- }
-
- if (tmode != mode
- && TREE_CODE (exp) != INTEGER_CST
- && TREE_CODE (exp) != PARM_DECL
- && TREE_CODE (exp) != ARRAY_REF
- && TREE_CODE (exp) != ARRAY_RANGE_REF
- && TREE_CODE (exp) != COMPONENT_REF
- && TREE_CODE (exp) != BIT_FIELD_REF
- && TREE_CODE (exp) != INDIRECT_REF
- && TREE_CODE (exp) != VAR_DECL
- && TREE_CODE (exp) != CALL_EXPR
- && TREE_CODE (exp) != RTL_EXPR
- && GET_MODE_CLASS (tmode) == MODE_INT
- && tmode > MAX_INTEGER_COMPUTATION_MODE)
- internal_error ("unsupported wide integer operation");
-
- check_max_integer_computation_mode (exp);
-#endif
-
/* If will do cse, generate all results into pseudo registers
since 1) that allows cse to find more things
and 2) otherwise cse could produce an insn the machine
- cannot support. And exception is a CONSTRUCTOR into a multi-word
- MEM: that's much more likely to be most efficient into the MEM. */
+ cannot support. An exception is a CONSTRUCTOR into a multi-word
+ MEM: that's much more likely to be most efficient into the MEM.
+ Another is a CALL_EXPR which must return in memory. */
if (! cse_not_expected && mode != BLKmode && target
&& (GET_CODE (target) != REG || REGNO (target) < FIRST_PSEUDO_REGISTER)
- && ! (code == CONSTRUCTOR && GET_MODE_SIZE (mode) > UNITS_PER_WORD))
+ && ! (code == CONSTRUCTOR && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
+ && ! (code == CALL_EXPR && aggregate_value_p (exp, exp)))
target = 0;
switch (code)
@@ -6638,25 +6363,17 @@ expand_expr (exp, target, tmode, modifier)
case LABEL_DECL:
{
tree function = decl_function_context (exp);
- /* Handle using a label in a containing function. */
- if (function != current_function_decl
- && function != inline_function_decl && function != 0)
- {
- struct function *p = find_function_data (function);
- p->expr->x_forced_labels
- = gen_rtx_EXPR_LIST (VOIDmode, label_rtx (exp),
- p->expr->x_forced_labels);
- }
+ /* Labels in containing functions, or labels used from initializers,
+ must be forced. */
+ if (modifier == EXPAND_INITIALIZER
+ || (function != current_function_decl
+ && function != inline_function_decl
+ && function != 0))
+ temp = force_label_rtx (exp);
else
- {
- if (modifier == EXPAND_INITIALIZER)
- forced_labels = gen_rtx_EXPR_LIST (VOIDmode,
- label_rtx (exp),
- forced_labels);
- }
+ temp = label_rtx (exp);
- temp = gen_rtx_MEM (FUNCTION_MODE,
- gen_rtx_LABEL_REF (Pmode, label_rtx (exp)));
+ temp = gen_rtx_MEM (FUNCTION_MODE, gen_rtx_LABEL_REF (Pmode, temp));
if (function != current_function_decl
&& function != inline_function_decl && function != 0)
LABEL_REF_NONLOCAL_P (XEXP (temp, 0)) = 1;
@@ -6666,7 +6383,7 @@ expand_expr (exp, target, tmode, modifier)
case PARM_DECL:
if (!DECL_RTL_SET_P (exp))
{
- error_with_decl (exp, "prior parameter's size depends on `%s'");
+ error ("%Jprior parameter's size depends on '%D'", exp, exp);
return CONST0_RTX (mode);
}
@@ -6753,8 +6470,12 @@ expand_expr (exp, target, tmode, modifier)
XEXP (DECL_RTL (exp), 0))
|| (flag_force_addr
&& GET_CODE (XEXP (DECL_RTL (exp), 0)) != REG)))
- temp = replace_equiv_address (DECL_RTL (exp),
- copy_rtx (XEXP (DECL_RTL (exp), 0)));
+ {
+ if (alt_rtl)
+ *alt_rtl = DECL_RTL (exp);
+ temp = replace_equiv_address (DECL_RTL (exp),
+ copy_rtx (XEXP (DECL_RTL (exp), 0)));
+ }
/* If we got something, return it. But first, set the alignment
if the address is a register. */
@@ -6824,37 +6545,64 @@ expand_expr (exp, target, tmode, modifier)
TYPE_MODE (TREE_TYPE (exp)));
case COMPLEX_CST:
+ /* Handle evaluating a complex constant in a CONCAT target. */
+ if (original_target && GET_CODE (original_target) == CONCAT)
+ {
+ enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
+ rtx rtarg, itarg;
+
+ rtarg = XEXP (original_target, 0);
+ itarg = XEXP (original_target, 1);
+
+ /* Move the real and imaginary parts separately. */
+ op0 = expand_expr (TREE_REALPART (exp), rtarg, mode, 0);
+ op1 = expand_expr (TREE_IMAGPART (exp), itarg, mode, 0);
+
+ if (op0 != rtarg)
+ emit_move_insn (rtarg, op0);
+ if (op1 != itarg)
+ emit_move_insn (itarg, op1);
+
+ return original_target;
+ }
+
+ /* ... fall through ... */
+
case STRING_CST:
- if (! TREE_CST_RTL (exp))
- output_constant_def (exp, 1);
+ temp = output_constant_def (exp, 1);
- /* TREE_CST_RTL probably contains a constant address.
+ /* temp contains a constant address.
On RISC machines where a constant address isn't valid,
make some insns to get that address into a register. */
- if (GET_CODE (TREE_CST_RTL (exp)) == MEM
- && modifier != EXPAND_CONST_ADDRESS
+ if (modifier != EXPAND_CONST_ADDRESS
&& modifier != EXPAND_INITIALIZER
&& modifier != EXPAND_SUM
- && (! memory_address_p (mode, XEXP (TREE_CST_RTL (exp), 0))
- || (flag_force_addr
- && GET_CODE (XEXP (TREE_CST_RTL (exp), 0)) != REG)))
- return replace_equiv_address (TREE_CST_RTL (exp),
- copy_rtx (XEXP (TREE_CST_RTL (exp), 0)));
- return TREE_CST_RTL (exp);
+ && (! memory_address_p (mode, XEXP (temp, 0))
+ || flag_force_addr))
+ return replace_equiv_address (temp,
+ copy_rtx (XEXP (temp, 0)));
+ return temp;
case EXPR_WITH_FILE_LOCATION:
{
rtx to_return;
- const char *saved_input_filename = input_filename;
- int saved_lineno = lineno;
+ struct file_stack fs;
+
+ fs.location = input_location;
+ fs.next = expr_wfl_stack;
input_filename = EXPR_WFL_FILENAME (exp);
- lineno = EXPR_WFL_LINENO (exp);
+ input_line = EXPR_WFL_LINENO (exp);
+ expr_wfl_stack = &fs;
if (EXPR_WFL_EMIT_LINE_NOTE (exp))
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
/* Possibly avoid switching back and forth here. */
- to_return = expand_expr (EXPR_WFL_NODE (exp), target, tmode, modifier);
- input_filename = saved_input_filename;
- lineno = saved_lineno;
+ to_return = expand_expr (EXPR_WFL_NODE (exp),
+ (ignore ? const0_rtx : target),
+ tmode, modifier);
+ if (expr_wfl_stack != &fs)
+ abort ();
+ input_location = fs.location;
+ expr_wfl_stack = fs.next;
return to_return;
}
@@ -7018,7 +6766,6 @@ expand_expr (exp, target, tmode, modifier)
case BIND_EXPR:
{
tree vars = TREE_OPERAND (exp, 0);
- int vars_need_expansion = 0;
/* Need to open a binding contour here because
if there are any cleanups they must be contained here. */
@@ -7033,10 +6780,7 @@ expand_expr (exp, target, tmode, modifier)
while (vars)
{
if (!DECL_RTL_SET_P (vars))
- {
- vars_need_expansion = 1;
- expand_decl (vars);
- }
+ expand_decl (vars);
expand_decl_init (vars);
vars = TREE_CHAIN (vars);
}
@@ -7058,6 +6802,8 @@ expand_expr (exp, target, tmode, modifier)
}
preserve_rtl_expr_result (RTL_EXPR_RTL (exp));
free_temps_for_rtl_expr (exp);
+ if (alt_rtl)
+ *alt_rtl = RTL_EXPR_ALT_RTL (exp);
return RTL_EXPR_RTL (exp);
case CONSTRUCTOR:
@@ -7097,7 +6843,9 @@ expand_expr (exp, target, tmode, modifier)
&& ((TREE_CODE (type) == VECTOR_TYPE
&& !is_zeros_p (exp))
|| ! mostly_zeros_p (exp)))))
- || (modifier == EXPAND_INITIALIZER && TREE_CONSTANT (exp)))
+ || ((modifier == EXPAND_INITIALIZER
+ || modifier == EXPAND_CONST_ADDRESS)
+ && TREE_CONSTANT (exp)))
{
rtx constructor = output_constant_def (exp, 1);
@@ -7228,7 +6976,8 @@ expand_expr (exp, target, tmode, modifier)
&& modifier != EXPAND_MEMORY
&& TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
&& TREE_CODE (array) == VAR_DECL && DECL_INITIAL (array)
- && TREE_CODE (DECL_INITIAL (array)) != ERROR_MARK)
+ && TREE_CODE (DECL_INITIAL (array)) != ERROR_MARK
+ && targetm.binds_local_p (array))
{
if (TREE_CODE (index) == INTEGER_CST)
{
@@ -7263,18 +7012,12 @@ expand_expr (exp, target, tmode, modifier)
}
}
}
- /* Fall through. */
+ goto normal_inner_ref;
case COMPONENT_REF:
- case BIT_FIELD_REF:
- case ARRAY_RANGE_REF:
/* If the operand is a CONSTRUCTOR, we can just extract the
- appropriate field if it is present. Don't do this if we have
- already written the data since we want to refer to that copy
- and varasm.c assumes that's what we'll do. */
- if (code == COMPONENT_REF
- && TREE_CODE (TREE_OPERAND (exp, 0)) == CONSTRUCTOR
- && TREE_CST_RTL (TREE_OPERAND (exp, 0)) == 0)
+ appropriate field if it is present. */
+ if (TREE_CODE (TREE_OPERAND (exp, 0)) == CONSTRUCTOR)
{
tree elt;
@@ -7326,7 +7069,11 @@ expand_expr (exp, target, tmode, modifier)
return op0;
}
}
+ goto normal_inner_ref;
+ case BIT_FIELD_REF:
+ case ARRAY_RANGE_REF:
+ normal_inner_ref:
{
enum machine_mode mode1;
HOST_WIDE_INT bitsize, bitpos;
@@ -7371,39 +7118,41 @@ expand_expr (exp, target, tmode, modifier)
op0 = validize_mem (force_const_mem (mode, op0));
}
+ /* Otherwise, if this object not in memory and we either have an
+ offset or a BLKmode result, put it there. This case can't occur in
+ C, but can in Ada if we have unchecked conversion of an expression
+ from a scalar type to an array or record type or for an
+ ARRAY_RANGE_REF whose type is BLKmode. */
+ else if (GET_CODE (op0) != MEM
+ && (offset != 0
+ || (code == ARRAY_RANGE_REF && mode == BLKmode)))
+ {
+ /* If the operand is a SAVE_EXPR, we can deal with this by
+ forcing the SAVE_EXPR into memory. */
+ if (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR)
+ {
+ put_var_into_stack (TREE_OPERAND (exp, 0),
+ /*rescan=*/true);
+ op0 = SAVE_EXPR_RTL (TREE_OPERAND (exp, 0));
+ }
+ else
+ {
+ tree nt
+ = build_qualified_type (TREE_TYPE (tem),
+ (TYPE_QUALS (TREE_TYPE (tem))
+ | TYPE_QUAL_CONST));
+ rtx memloc = assign_temp (nt, 1, 1, 1);
+
+ emit_move_insn (memloc, op0);
+ op0 = memloc;
+ }
+ }
+
if (offset != 0)
{
rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
EXPAND_SUM);
- /* If this object is in a register, put it into memory.
- This case can't occur in C, but can in Ada if we have
- unchecked conversion of an expression from a scalar type to
- an array or record type. */
- if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
- || GET_CODE (op0) == CONCAT || GET_CODE (op0) == ADDRESSOF)
- {
- /* If the operand is a SAVE_EXPR, we can deal with this by
- forcing the SAVE_EXPR into memory. */
- if (TREE_CODE (TREE_OPERAND (exp, 0)) == SAVE_EXPR)
- {
- put_var_into_stack (TREE_OPERAND (exp, 0),
- /*rescan=*/true);
- op0 = SAVE_EXPR_RTL (TREE_OPERAND (exp, 0));
- }
- else
- {
- tree nt
- = build_qualified_type (TREE_TYPE (tem),
- (TYPE_QUALS (TREE_TYPE (tem))
- | TYPE_QUAL_CONST));
- rtx memloc = assign_temp (nt, 1, 1, 1);
-
- emit_move_insn (memloc, op0);
- op0 = memloc;
- }
- }
-
if (GET_CODE (op0) != MEM)
abort ();
@@ -7415,10 +7164,9 @@ expand_expr (exp, target, tmode, modifier)
offset_rtx = convert_to_mode (ptr_mode, offset_rtx, 0);
#endif
- /* A constant address in OP0 can have VOIDmode, we must not try
- to call force_reg for that case. Avoid that case. */
- if (GET_CODE (op0) == MEM
- && GET_MODE (op0) == BLKmode
+ if (GET_MODE (op0) == BLKmode
+ /* A constant address in OP0 can have VOIDmode, we must
+ not try to call force_reg in that case. */
&& GET_MODE (XEXP (op0, 0)) != VOIDmode
&& bitsize != 0
&& (bitpos % bitsize) == 0
@@ -7474,10 +7222,16 @@ expand_expr (exp, target, tmode, modifier)
/* If the field isn't aligned enough to fetch as a memref,
fetch it as a bit field. */
|| (mode1 != BLKmode
- && SLOW_UNALIGNED_ACCESS (mode1, MEM_ALIGN (op0))
- && ((TYPE_ALIGN (TREE_TYPE (tem))
- < GET_MODE_ALIGNMENT (mode))
- || (bitpos % GET_MODE_ALIGNMENT (mode) != 0)))
+ && (((TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
+ || (bitpos % GET_MODE_ALIGNMENT (mode) != 0)
+ || (GET_CODE (op0) == MEM
+ && (MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
+ || (bitpos % GET_MODE_ALIGNMENT (mode1) != 0))))
+ && ((modifier == EXPAND_CONST_ADDRESS
+ || modifier == EXPAND_INITIALIZER)
+ ? STRICT_ALIGNMENT
+ : SLOW_UNALIGNED_ACCESS (mode1, MEM_ALIGN (op0))))
+ || (bitpos % BITS_PER_UNIT != 0)))
/* If the type and the field are a constant size and the
size of the type isn't the same size as the bitfield,
we must use bitfield operations. */
@@ -7497,6 +7251,12 @@ expand_expr (exp, target, tmode, modifier)
if (ext_mode == BLKmode)
{
+ if (target == 0)
+ target = assign_temp (type, 0, 1, 1);
+
+ if (bitsize == 0)
+ return target;
+
/* In this case, BITPOS must start at a byte boundary and
TARGET, if specified, must be a MEM. */
if (GET_CODE (op0) != MEM
@@ -7504,11 +7264,9 @@ expand_expr (exp, target, tmode, modifier)
|| bitpos % BITS_PER_UNIT != 0)
abort ();
- op0 = adjust_address (op0, VOIDmode, bitpos / BITS_PER_UNIT);
- if (target == 0)
- target = assign_temp (type, 0, 1, 1);
-
- emit_block_move (target, op0,
+ emit_block_move (target,
+ adjust_address (op0, VOIDmode,
+ bitpos / BITS_PER_UNIT),
GEN_INT ((bitsize + BITS_PER_UNIT - 1)
/ BITS_PER_UNIT),
(modifier == EXPAND_STACK_PARM
@@ -7770,7 +7528,8 @@ expand_expr (exp, target, tmode, modifier)
if (DECL_BUILT_IN_CLASS (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
== BUILT_IN_FRONTEND)
return (*lang_hooks.expand_expr) (exp, original_target,
- tmode, modifier);
+ tmode, modifier,
+ alt_rtl);
else
return expand_builtin (exp, target, subtarget, tmode, ignore);
}
@@ -7801,7 +7560,12 @@ expand_expr (exp, target, tmode, modifier)
}
if (target == 0)
- target = assign_temp (type, 0, 1, 1);
+ {
+ if (TYPE_MODE (type) != BLKmode)
+ target = gen_reg_rtx (TYPE_MODE (type));
+ else
+ target = assign_temp (type, 0, 1, 1);
+ }
if (GET_CODE (target) == MEM)
/* Store data into beginning of memory target. */
@@ -7875,12 +7639,14 @@ expand_expr (exp, target, tmode, modifier)
op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, modifier);
/* If the input and output modes are both the same, we are done.
- Otherwise, if neither mode is BLKmode and both are within a word, we
- can use gen_lowpart. If neither is true, make sure the operand is
- in memory and convert the MEM to the new mode. */
+ Otherwise, if neither mode is BLKmode and both are integral and within
+ a word, we can use gen_lowpart. If neither is true, make sure the
+ operand is in memory and convert the MEM to the new mode. */
if (TYPE_MODE (type) == GET_MODE (op0))
;
else if (TYPE_MODE (type) != BLKmode && GET_MODE (op0) != BLKmode
+ && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
+ && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
&& GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD
&& GET_MODE_SIZE (GET_MODE (op0)) <= UNITS_PER_WORD)
op0 = gen_lowpart (TYPE_MODE (type), op0);
@@ -8022,11 +7788,11 @@ expand_expr (exp, target, tmode, modifier)
{
op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
VOIDmode, modifier);
- /* Don't go to both_summands if modifier
- says it's not right to return a PLUS. */
- if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
- goto binop2;
- goto both_summands;
+ /* Return a PLUS if modifier says it's OK. */
+ if (modifier == EXPAND_SUM
+ || modifier == EXPAND_INITIALIZER)
+ return simplify_gen_binary (PLUS, mode, op0, op1);
+ goto binop2;
}
/* Use immed_double_const to ensure that the constant is
truncated according to the mode of OP1, then sign extended
@@ -8043,9 +7809,6 @@ expand_expr (exp, target, tmode, modifier)
}
}
- if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
- subtarget = 0;
-
/* No sense saving up arithmetic to be done
if it's all in the wrong mode to form part of an address.
And force_operand won't know whether to sign-extend or
@@ -8053,8 +7816,8 @@ expand_expr (exp, target, tmode, modifier)
if ((modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
|| mode != ptr_mode)
{
- op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
- op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
+ expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+ subtarget, &op0, &op1, 0);
if (op0 == const0_rtx)
return op1;
if (op1 == const0_rtx)
@@ -8062,57 +7825,9 @@ expand_expr (exp, target, tmode, modifier)
goto binop2;
}
- op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
- op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);
-
- /* We come here from MINUS_EXPR when the second operand is a
- constant. */
- both_summands:
- /* Make sure any term that's a sum with a constant comes last. */
- if (GET_CODE (op0) == PLUS
- && CONSTANT_P (XEXP (op0, 1)))
- {
- temp = op0;
- op0 = op1;
- op1 = temp;
- }
- /* If adding to a sum including a constant,
- associate it to put the constant outside. */
- if (GET_CODE (op1) == PLUS
- && CONSTANT_P (XEXP (op1, 1)))
- {
- rtx constant_term = const0_rtx;
-
- temp = simplify_binary_operation (PLUS, mode, XEXP (op1, 0), op0);
- if (temp != 0)
- op0 = temp;
- /* Ensure that MULT comes first if there is one. */
- else if (GET_CODE (op0) == MULT)
- op0 = gen_rtx_PLUS (mode, op0, XEXP (op1, 0));
- else
- op0 = gen_rtx_PLUS (mode, XEXP (op1, 0), op0);
-
- /* Let's also eliminate constants from op0 if possible. */
- op0 = eliminate_constant_term (op0, &constant_term);
-
- /* CONSTANT_TERM and XEXP (op1, 1) are known to be constant, so
- their sum should be a constant. Form it into OP1, since the
- result we want will then be OP0 + OP1. */
-
- temp = simplify_binary_operation (PLUS, mode, constant_term,
- XEXP (op1, 1));
- if (temp != 0)
- op1 = temp;
- else
- op1 = gen_rtx_PLUS (mode, constant_term, XEXP (op1, 1));
- }
-
- /* Put a constant term last and put a multiplication first. */
- if (CONSTANT_P (op0) || GET_CODE (op1) == MULT)
- temp = op1, op1 = op0, op0 = temp;
-
- temp = simplify_binary_operation (PLUS, mode, op0, op1);
- return temp ? temp : gen_rtx_PLUS (mode, op0, op1);
+ expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+ subtarget, &op0, &op1, modifier);
+ return simplify_gen_binary (PLUS, mode, op0, op1);
case MINUS_EXPR:
/* For initializers, we are allowed to return a MINUS of two
@@ -8124,10 +7839,8 @@ expand_expr (exp, target, tmode, modifier)
&& really_constant_p (TREE_OPERAND (exp, 0))
&& really_constant_p (TREE_OPERAND (exp, 1)))
{
- rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode,
- modifier);
- rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode,
- modifier);
+ expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+ NULL_RTX, &op0, &op1, modifier);
/* If the last operand is a CONST_INT, use plus_constant of
the negated constant. Else make the MINUS. */
@@ -8149,17 +7862,14 @@ expand_expr (exp, target, tmode, modifier)
|| mode != ptr_mode)
goto binop;
- if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
- subtarget = 0;
-
- op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, modifier);
- op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, modifier);
+ expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+ subtarget, &op0, &op1, modifier);
/* Convert A - const to A + (-const). */
if (GET_CODE (op1) == CONST_INT)
{
op1 = negate_rtx (mode, op1);
- goto both_summands;
+ return simplify_gen_binary (PLUS, mode, op0, op1);
}
goto binop2;
@@ -8186,16 +7896,6 @@ expand_expr (exp, target, tmode, modifier)
op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode,
EXPAND_SUM);
- /* If we knew for certain that this is arithmetic for an array
- reference, and we knew the bounds of the array, then we could
- apply the distributive law across (PLUS X C) for constant C.
- Without such knowledge, we risk overflowing the computation
- when both X and C are large, but X+C isn't. */
- /* ??? Could perhaps special-case EXP being unsigned and C being
- positive. In that case we are certain that X+C is no smaller
- than X and so the transformed expression will overflow iff the
- original would have. */
-
if (GET_CODE (op0) != REG)
op0 = force_operand (op0, NULL_RTX);
if (GET_CODE (op0) != REG)
@@ -8206,9 +7906,6 @@ expand_expr (exp, target, tmode, modifier)
TYPE_MODE (TREE_TYPE (exp1))));
}
- if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
- subtarget = 0;
-
if (modifier == EXPAND_STACK_PARM)
target = 0;
@@ -8248,14 +7945,14 @@ expand_expr (exp, target, tmode, modifier)
{
if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
- op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
- NULL_RTX, VOIDmode, 0);
if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST)
- op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX,
- VOIDmode, 0);
+ expand_operands (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
+ TREE_OPERAND (exp, 1),
+ NULL_RTX, &op0, &op1, 0);
else
- op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0),
- NULL_RTX, VOIDmode, 0);
+ expand_operands (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
+ TREE_OPERAND (TREE_OPERAND (exp, 1), 0),
+ NULL_RTX, &op0, &op1, 0);
goto binop2;
}
else if (other_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
@@ -8284,8 +7981,8 @@ expand_expr (exp, target, tmode, modifier)
}
}
}
- op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
- op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
+ expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+ subtarget, &op0, &op1, 0);
return expand_mult (mode, op0, op1, target, unsignedp);
case TRUNC_DIV_EXPR:
@@ -8293,15 +7990,13 @@ expand_expr (exp, target, tmode, modifier)
case CEIL_DIV_EXPR:
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
- if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
- subtarget = 0;
if (modifier == EXPAND_STACK_PARM)
target = 0;
/* Possible optimization: compute the dividend with EXPAND_SUM
then if the divisor is constant can optimize the case
where some terms of the dividend have coeffs divisible by it. */
- op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
- op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
+ expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+ subtarget, &op0, &op1, 0);
return expand_divmod (0, code, mode, op0, op1, target, unsignedp);
case RDIV_EXPR:
@@ -8323,12 +8018,10 @@ expand_expr (exp, target, tmode, modifier)
case FLOOR_MOD_EXPR:
case CEIL_MOD_EXPR:
case ROUND_MOD_EXPR:
- if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
- subtarget = 0;
if (modifier == EXPAND_STACK_PARM)
target = 0;
- op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
- op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
+ expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+ subtarget, &op0, &op1, 0);
return expand_divmod (1, code, mode, op0, op1, target, unsignedp);
case FIX_ROUND_EXPR:
@@ -8373,10 +8066,10 @@ expand_expr (exp, target, tmode, modifier)
if (modifier == EXPAND_STACK_PARM)
target = 0;
- /* Handle complex values specially. */
+ /* ABS_EXPR is not valid for complex arguments. */
if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
|| GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
- return expand_complex_abs (mode, op0, target, unsignedp);
+ abort ();
/* Unsigned abs is simply the operand. Testing here means we don't
risk generating incorrect code below. */
@@ -8391,19 +8084,18 @@ expand_expr (exp, target, tmode, modifier)
target = original_target;
if (target == 0
|| modifier == EXPAND_STACK_PARM
- || ! safe_from_p (target, TREE_OPERAND (exp, 1), 1)
|| (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
|| GET_MODE (target) != mode
|| (GET_CODE (target) == REG
&& REGNO (target) < FIRST_PSEUDO_REGISTER))
target = gen_reg_rtx (mode);
- op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
- op0 = expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, 0);
+ expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+ target, &op0, &op1, 0);
/* First try to do it with a special MIN or MAX instruction.
If that does not win, use a conditional jump to select the proper
value. */
- this_optab = (TREE_UNSIGNED (type)
+ this_optab = (unsignedp
? (code == MIN_EXPR ? umin_optab : umax_optab)
: (code == MIN_EXPR ? smin_optab : smax_optab));
@@ -8418,6 +8110,14 @@ expand_expr (exp, target, tmode, modifier)
if (GET_CODE (target) == MEM)
target = gen_reg_rtx (mode);
+ /* If op1 was placed in target, swap op0 and op1. */
+ if (target != op0 && target == op1)
+ {
+ rtx tem = op0;
+ op0 = op1;
+ op1 = tem;
+ }
+
if (target != op0)
emit_move_insn (target, op0);
@@ -8429,18 +8129,16 @@ expand_expr (exp, target, tmode, modifier)
&& ! can_compare_p (GE, mode, ccp_jump))
{
if (code == MAX_EXPR)
- do_jump_by_parts_greater_rtx (mode, TREE_UNSIGNED (type),
- target, op1, NULL_RTX, op0);
+ do_jump_by_parts_greater_rtx (mode, unsignedp, target, op1,
+ NULL_RTX, op0);
else
- do_jump_by_parts_greater_rtx (mode, TREE_UNSIGNED (type),
- op1, target, NULL_RTX, op0);
+ do_jump_by_parts_greater_rtx (mode, unsignedp, op1, target,
+ NULL_RTX, op0);
}
else
{
- int unsignedp = TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 1)));
do_compare_rtx_and_jump (target, op1, code == MAX_EXPR ? GE : LE,
- unsignedp, mode, NULL_RTX, NULL_RTX,
- op0);
+ unsignedp, mode, NULL_RTX, NULL_RTX, op0);
}
emit_move_insn (target, op1);
emit_label (op0);
@@ -8455,15 +8153,6 @@ expand_expr (exp, target, tmode, modifier)
abort ();
return temp;
- case FFS_EXPR:
- op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
- if (modifier == EXPAND_STACK_PARM)
- target = 0;
- temp = expand_unop (mode, ffs_optab, op0, target, 1);
- if (temp == 0)
- abort ();
- return temp;
-
/* ??? Can optimize bitwise operations with one arg constant.
Can optimize (a bitwise1 n) bitwise2 (a bitwise3 b)
and (a bitwise1 b) bitwise2 b (etc)
@@ -8606,9 +8295,9 @@ expand_expr (exp, target, tmode, modifier)
case COMPOUND_EXPR:
expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
emit_queue ();
- return expand_expr (TREE_OPERAND (exp, 1),
- (ignore ? const0_rtx : target),
- VOIDmode, modifier);
+ return expand_expr_real (TREE_OPERAND (exp, 1),
+ (ignore ? const0_rtx : target),
+ VOIDmode, modifier, alt_rtl);
case COND_EXPR:
/* If we would have a "singleton" (see below) were it not for a
@@ -8840,8 +8529,12 @@ expand_expr (exp, target, tmode, modifier)
jumpif (TREE_OPERAND (exp, 0), op0);
start_cleanup_deferral ();
- store_expr (TREE_OPERAND (exp, 2), temp,
- modifier == EXPAND_STACK_PARM ? 2 : 0);
+ if (TREE_TYPE (TREE_OPERAND (exp, 2)) != void_type_node)
+ store_expr (TREE_OPERAND (exp, 2), temp,
+ modifier == EXPAND_STACK_PARM ? 2 : 0);
+ else
+ expand_expr (TREE_OPERAND (exp, 2),
+ ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
op1 = op0;
}
else if (temp
@@ -8861,8 +8554,12 @@ expand_expr (exp, target, tmode, modifier)
jumpifnot (TREE_OPERAND (exp, 0), op0);
start_cleanup_deferral ();
- store_expr (TREE_OPERAND (exp, 1), temp,
- modifier == EXPAND_STACK_PARM ? 2 : 0);
+ if (TREE_TYPE (TREE_OPERAND (exp, 1)) != void_type_node)
+ store_expr (TREE_OPERAND (exp, 1), temp,
+ modifier == EXPAND_STACK_PARM ? 2 : 0);
+ else
+ expand_expr (TREE_OPERAND (exp, 1),
+ ignore ? const0_rtx : NULL_RTX, VOIDmode, 0);
op1 = op0;
}
else
@@ -8944,8 +8641,6 @@ expand_expr (exp, target, tmode, modifier)
else
{
target = assign_temp (type, 2, 0, 1);
- /* All temp slots at this level must not conflict. */
- preserve_temp_slots (target);
SET_DECL_RTL (slot, target);
if (TREE_ADDRESSABLE (slot))
put_var_into_stack (slot, /*rescan=*/false);
@@ -9007,7 +8702,7 @@ expand_expr (exp, target, tmode, modifier)
tree lhs = TREE_OPERAND (exp, 0);
tree rhs = TREE_OPERAND (exp, 1);
- temp = expand_assignment (lhs, rhs, ! ignore, original_target != 0);
+ temp = expand_assignment (lhs, rhs, ! ignore);
return temp;
}
@@ -9052,13 +8747,13 @@ expand_expr (exp, target, tmode, modifier)
(TREE_CODE (rhs) == BIT_IOR_EXPR
? integer_one_node
: integer_zero_node)),
- 0, 0);
+ 0);
do_pending_stack_adjust ();
emit_label (label);
return const0_rtx;
}
- temp = expand_assignment (lhs, rhs, ! ignore, original_target != 0);
+ temp = expand_assignment (lhs, rhs, ! ignore);
return temp;
}
@@ -9131,7 +8826,7 @@ expand_expr (exp, target, tmode, modifier)
op0);
else if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
|| GET_CODE (op0) == CONCAT || GET_CODE (op0) == ADDRESSOF
- || GET_CODE (op0) == PARALLEL)
+ || GET_CODE (op0) == PARALLEL || GET_CODE (op0) == LO_SUM)
{
/* If the operand is a SAVE_EXPR, we can deal with this by
forcing the SAVE_EXPR into memory. */
@@ -9151,7 +8846,7 @@ expand_expr (exp, target, tmode, modifier)
/* Handle calls that pass values in multiple
non-contiguous locations. The Irix 6 ABI has examples
of this. */
- emit_group_store (memloc, op0,
+ emit_group_store (memloc, op0, inner_type,
int_size_in_bytes (inner_type));
else
emit_move_insn (memloc, op0);
@@ -9167,11 +8862,8 @@ expand_expr (exp, target, tmode, modifier)
if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
{
op0 = XEXP (op0, 0);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (op0) == Pmode && GET_MODE (op0) != mode
- && mode == ptr_mode)
+ if (GET_MODE (op0) == Pmode && mode == ptr_mode)
op0 = convert_memory_address (ptr_mode, op0);
-#endif
return op0;
}
@@ -9232,11 +8924,8 @@ expand_expr (exp, target, tmode, modifier)
&& ! REG_USERVAR_P (op0))
mark_reg_pointer (op0, TYPE_ALIGN (TREE_TYPE (type)));
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (op0) == Pmode && GET_MODE (op0) != mode
- && mode == ptr_mode)
+ if (GET_MODE (op0) == Pmode && mode == ptr_mode)
op0 = convert_memory_address (ptr_mode, op0);
-#endif
return op0;
@@ -9419,16 +9108,15 @@ expand_expr (exp, target, tmode, modifier)
abort ();
default:
- return (*lang_hooks.expand_expr) (exp, original_target, tmode, modifier);
+ return (*lang_hooks.expand_expr) (exp, original_target, tmode, modifier,
+ alt_rtl);
}
/* Here to do an ordinary binary operator, generating an instruction
from the optab already placed in `this_optab'. */
binop:
- if (! safe_from_p (subtarget, TREE_OPERAND (exp, 1), 1))
- subtarget = 0;
- op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0);
- op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
+ expand_operands (TREE_OPERAND (exp, 0), TREE_OPERAND (exp, 1),
+ subtarget, &op0, &op1, 0);
binop2:
if (modifier == EXPAND_STACK_PARM)
target = 0;
@@ -9444,9 +9132,7 @@ expand_expr (exp, target, tmode, modifier)
aligned more than BIGGEST_ALIGNMENT. */
static int
-is_aligning_offset (offset, exp)
- tree offset;
- tree exp;
+is_aligning_offset (tree offset, tree exp)
{
/* Strip off any conversions and WITH_RECORD_EXPR nodes. */
while (TREE_CODE (offset) == NON_LVALUE_EXPR
@@ -9459,7 +9145,8 @@ is_aligning_offset (offset, exp)
power of 2 and which is larger than BIGGEST_ALIGNMENT. */
if (TREE_CODE (offset) != BIT_AND_EXPR
|| !host_integerp (TREE_OPERAND (offset, 1), 1)
- || compare_tree_int (TREE_OPERAND (offset, 1), BIGGEST_ALIGNMENT) <= 0
+ || compare_tree_int (TREE_OPERAND (offset, 1),
+ BIGGEST_ALIGNMENT / BITS_PER_UNIT) <= 0
|| !exact_log2 (tree_low_cst (TREE_OPERAND (offset, 1), 1) + 1) < 0)
return 0;
@@ -9495,9 +9182,7 @@ is_aligning_offset (offset, exp)
offset will be `sizetype'. */
tree
-string_constant (arg, ptr_offset)
- tree arg;
- tree *ptr_offset;
+string_constant (tree arg, tree *ptr_offset)
{
STRIP_NOPS (arg);
@@ -9537,9 +9222,7 @@ string_constant (arg, ptr_offset)
POST is 1 for postinc/decrements and 0 for preinc/decrements. */
static rtx
-expand_increment (exp, post, ignore)
- tree exp;
- int post, ignore;
+expand_increment (tree exp, int post, int ignore)
{
rtx op0, op1;
rtx temp, value;
@@ -9667,7 +9350,7 @@ expand_increment (exp, post, ignore)
incremented = TREE_OPERAND (incremented, 0);
}
- temp = expand_assignment (incremented, newexp, ! post && ! ignore , 0);
+ temp = expand_assignment (incremented, newexp, ! post && ! ignore);
return post ? op0 : temp;
}
@@ -9675,7 +9358,7 @@ expand_increment (exp, post, ignore)
{
/* We have a true reference to the value in OP0.
If there is an insn to add or subtract in this mode, queue it.
- Queueing the increment insn avoids the register shuffling
+ Queuing the increment insn avoids the register shuffling
that often results if we must increment now and first save
the old value for subsequent use. */
@@ -9737,986 +9420,6 @@ expand_increment (exp, post, ignore)
return temp;
}
-/* At the start of a function, record that we have no previously-pushed
- arguments waiting to be popped. */
-
-void
-init_pending_stack_adjust ()
-{
- pending_stack_adjust = 0;
-}
-
-/* When exiting from function, if safe, clear out any pending stack adjust
- so the adjustment won't get done.
-
- Note, if the current function calls alloca, then it must have a
- frame pointer regardless of the value of flag_omit_frame_pointer. */
-
-void
-clear_pending_stack_adjust ()
-{
-#ifdef EXIT_IGNORE_STACK
- if (optimize > 0
- && (! flag_omit_frame_pointer || current_function_calls_alloca)
- && EXIT_IGNORE_STACK
- && ! (DECL_INLINE (current_function_decl) && ! flag_no_inline)
- && ! flag_inline_functions)
- {
- stack_pointer_delta -= pending_stack_adjust,
- pending_stack_adjust = 0;
- }
-#endif
-}
-
-/* Pop any previously-pushed arguments that have not been popped yet. */
-
-void
-do_pending_stack_adjust ()
-{
- if (inhibit_defer_pop == 0)
- {
- if (pending_stack_adjust != 0)
- adjust_stack (GEN_INT (pending_stack_adjust));
- pending_stack_adjust = 0;
- }
-}
-
-/* Expand conditional expressions. */
-
-/* Generate code to evaluate EXP and jump to LABEL if the value is zero.
- LABEL is an rtx of code CODE_LABEL, in this function and all the
- functions here. */
-
-void
-jumpifnot (exp, label)
- tree exp;
- rtx label;
-{
- do_jump (exp, label, NULL_RTX);
-}
-
-/* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */
-
-void
-jumpif (exp, label)
- tree exp;
- rtx label;
-{
- do_jump (exp, NULL_RTX, label);
-}
-
-/* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
- the result is zero, or IF_TRUE_LABEL if the result is one.
- Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero,
- meaning fall through in that case.
-
- do_jump always does any pending stack adjust except when it does not
- actually perform a jump. An example where there is no jump
- is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null.
-
- This function is responsible for optimizing cases such as
- &&, || and comparison operators in EXP. */
-
-void
-do_jump (exp, if_false_label, if_true_label)
- tree exp;
- rtx if_false_label, if_true_label;
-{
- enum tree_code code = TREE_CODE (exp);
- /* Some cases need to create a label to jump to
- in order to properly fall through.
- These cases set DROP_THROUGH_LABEL nonzero. */
- rtx drop_through_label = 0;
- rtx temp;
- int i;
- tree type;
- enum machine_mode mode;
-
-#ifdef MAX_INTEGER_COMPUTATION_MODE
- check_max_integer_computation_mode (exp);
-#endif
-
- emit_queue ();
-
- switch (code)
- {
- case ERROR_MARK:
- break;
-
- case INTEGER_CST:
- temp = integer_zerop (exp) ? if_false_label : if_true_label;
- if (temp)
- emit_jump (temp);
- break;
-
-#if 0
- /* This is not true with #pragma weak */
- case ADDR_EXPR:
- /* The address of something can never be zero. */
- if (if_true_label)
- emit_jump (if_true_label);
- break;
-#endif
-
- case UNSAVE_EXPR:
- do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
- TREE_OPERAND (exp, 0)
- = (*lang_hooks.unsave_expr_now) (TREE_OPERAND (exp, 0));
- break;
-
- case NOP_EXPR:
- if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF
- || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF
- || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF
- || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF)
- goto normal;
- case CONVERT_EXPR:
- /* If we are narrowing the operand, we have to do the compare in the
- narrower mode. */
- if ((TYPE_PRECISION (TREE_TYPE (exp))
- < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0)))))
- goto normal;
- case NON_LVALUE_EXPR:
- case REFERENCE_EXPR:
- case ABS_EXPR:
- case NEGATE_EXPR:
- case LROTATE_EXPR:
- case RROTATE_EXPR:
- /* These cannot change zero->nonzero or vice versa. */
- do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
- break;
-
- case WITH_RECORD_EXPR:
- /* Put the object on the placeholder list, recurse through our first
- operand, and pop the list. */
- placeholder_list = tree_cons (TREE_OPERAND (exp, 1), NULL_TREE,
- placeholder_list);
- do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
- placeholder_list = TREE_CHAIN (placeholder_list);
- break;
-
-#if 0
- /* This is never less insns than evaluating the PLUS_EXPR followed by
- a test and can be longer if the test is eliminated. */
- case PLUS_EXPR:
- /* Reduce to minus. */
- exp = build (MINUS_EXPR, TREE_TYPE (exp),
- TREE_OPERAND (exp, 0),
- fold (build1 (NEGATE_EXPR, TREE_TYPE (TREE_OPERAND (exp, 1)),
- TREE_OPERAND (exp, 1))));
- /* Process as MINUS. */
-#endif
-
- case MINUS_EXPR:
- /* Nonzero iff operands of minus differ. */
- do_compare_and_jump (build (NE_EXPR, TREE_TYPE (exp),
- TREE_OPERAND (exp, 0),
- TREE_OPERAND (exp, 1)),
- NE, NE, if_false_label, if_true_label);
- break;
-
- case BIT_AND_EXPR:
- /* If we are AND'ing with a small constant, do this comparison in the
- smallest type that fits. If the machine doesn't have comparisons
- that small, it will be converted back to the wider comparison.
- This helps if we are testing the sign bit of a narrower object.
- combine can't do this for us because it can't know whether a
- ZERO_EXTRACT or a compare in a smaller mode exists, but we do. */
-
- if (! SLOW_BYTE_ACCESS
- && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST
- && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT
- && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0
- && (mode = mode_for_size (i + 1, MODE_INT, 0)) != BLKmode
- && (type = (*lang_hooks.types.type_for_mode) (mode, 1)) != 0
- && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
- && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
- != CODE_FOR_nothing))
- {
- do_jump (convert (type, exp), if_false_label, if_true_label);
- break;
- }
- goto normal;
-
- case TRUTH_NOT_EXPR:
- do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
- break;
-
- case TRUTH_ANDIF_EXPR:
- if (if_false_label == 0)
- if_false_label = drop_through_label = gen_label_rtx ();
- do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX);
- start_cleanup_deferral ();
- do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
- end_cleanup_deferral ();
- break;
-
- case TRUTH_ORIF_EXPR:
- if (if_true_label == 0)
- if_true_label = drop_through_label = gen_label_rtx ();
- do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label);
- start_cleanup_deferral ();
- do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
- end_cleanup_deferral ();
- break;
-
- case COMPOUND_EXPR:
- push_temp_slots ();
- expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
- preserve_temp_slots (NULL_RTX);
- free_temp_slots ();
- pop_temp_slots ();
- emit_queue ();
- do_pending_stack_adjust ();
- do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
- break;
-
- case COMPONENT_REF:
- case BIT_FIELD_REF:
- case ARRAY_REF:
- case ARRAY_RANGE_REF:
- {
- HOST_WIDE_INT bitsize, bitpos;
- int unsignedp;
- enum machine_mode mode;
- tree type;
- tree offset;
- int volatilep = 0;
-
- /* Get description of this reference. We don't actually care
- about the underlying object here. */
- get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode,
- &unsignedp, &volatilep);
-
- type = (*lang_hooks.types.type_for_size) (bitsize, unsignedp);
- if (! SLOW_BYTE_ACCESS
- && type != 0 && bitsize >= 0
- && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp))
- && (cmp_optab->handlers[(int) TYPE_MODE (type)].insn_code
- != CODE_FOR_nothing))
- {
- do_jump (convert (type, exp), if_false_label, if_true_label);
- break;
- }
- goto normal;
- }
-
- case COND_EXPR:
- /* Do (a ? 1 : 0) and (a ? 0 : 1) as special cases. */
- if (integer_onep (TREE_OPERAND (exp, 1))
- && integer_zerop (TREE_OPERAND (exp, 2)))
- do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
-
- else if (integer_zerop (TREE_OPERAND (exp, 1))
- && integer_onep (TREE_OPERAND (exp, 2)))
- do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
-
- else
- {
- rtx label1 = gen_label_rtx ();
- drop_through_label = gen_label_rtx ();
-
- do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX);
-
- start_cleanup_deferral ();
- /* Now the THEN-expression. */
- do_jump (TREE_OPERAND (exp, 1),
- if_false_label ? if_false_label : drop_through_label,
- if_true_label ? if_true_label : drop_through_label);
- /* In case the do_jump just above never jumps. */
- do_pending_stack_adjust ();
- emit_label (label1);
-
- /* Now the ELSE-expression. */
- do_jump (TREE_OPERAND (exp, 2),
- if_false_label ? if_false_label : drop_through_label,
- if_true_label ? if_true_label : drop_through_label);
- end_cleanup_deferral ();
- }
- break;
-
- case EQ_EXPR:
- {
- tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
-
- if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_FLOAT
- || GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_INT)
- {
- tree exp0 = save_expr (TREE_OPERAND (exp, 0));
- tree exp1 = save_expr (TREE_OPERAND (exp, 1));
- do_jump
- (fold
- (build (TRUTH_ANDIF_EXPR, TREE_TYPE (exp),
- fold (build (EQ_EXPR, TREE_TYPE (exp),
- fold (build1 (REALPART_EXPR,
- TREE_TYPE (inner_type),
- exp0)),
- fold (build1 (REALPART_EXPR,
- TREE_TYPE (inner_type),
- exp1)))),
- fold (build (EQ_EXPR, TREE_TYPE (exp),
- fold (build1 (IMAGPART_EXPR,
- TREE_TYPE (inner_type),
- exp0)),
- fold (build1 (IMAGPART_EXPR,
- TREE_TYPE (inner_type),
- exp1)))))),
- if_false_label, if_true_label);
- }
-
- else if (integer_zerop (TREE_OPERAND (exp, 1)))
- do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label);
-
- else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
- && !can_compare_p (EQ, TYPE_MODE (inner_type), ccp_jump))
- do_jump_by_parts_equality (exp, if_false_label, if_true_label);
- else
- do_compare_and_jump (exp, EQ, EQ, if_false_label, if_true_label);
- break;
- }
-
- case NE_EXPR:
- {
- tree inner_type = TREE_TYPE (TREE_OPERAND (exp, 0));
-
- if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_FLOAT
- || GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_COMPLEX_INT)
- {
- tree exp0 = save_expr (TREE_OPERAND (exp, 0));
- tree exp1 = save_expr (TREE_OPERAND (exp, 1));
- do_jump
- (fold
- (build (TRUTH_ORIF_EXPR, TREE_TYPE (exp),
- fold (build (NE_EXPR, TREE_TYPE (exp),
- fold (build1 (REALPART_EXPR,
- TREE_TYPE (inner_type),
- exp0)),
- fold (build1 (REALPART_EXPR,
- TREE_TYPE (inner_type),
- exp1)))),
- fold (build (NE_EXPR, TREE_TYPE (exp),
- fold (build1 (IMAGPART_EXPR,
- TREE_TYPE (inner_type),
- exp0)),
- fold (build1 (IMAGPART_EXPR,
- TREE_TYPE (inner_type),
- exp1)))))),
- if_false_label, if_true_label);
- }
-
- else if (integer_zerop (TREE_OPERAND (exp, 1)))
- do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label);
-
- else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT
- && !can_compare_p (NE, TYPE_MODE (inner_type), ccp_jump))
- do_jump_by_parts_equality (exp, if_true_label, if_false_label);
- else
- do_compare_and_jump (exp, NE, NE, if_false_label, if_true_label);
- break;
- }
-
- case LT_EXPR:
- mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
- if (GET_MODE_CLASS (mode) == MODE_INT
- && ! can_compare_p (LT, mode, ccp_jump))
- do_jump_by_parts_greater (exp, 1, if_false_label, if_true_label);
- else
- do_compare_and_jump (exp, LT, LTU, if_false_label, if_true_label);
- break;
-
- case LE_EXPR:
- mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
- if (GET_MODE_CLASS (mode) == MODE_INT
- && ! can_compare_p (LE, mode, ccp_jump))
- do_jump_by_parts_greater (exp, 0, if_true_label, if_false_label);
- else
- do_compare_and_jump (exp, LE, LEU, if_false_label, if_true_label);
- break;
-
- case GT_EXPR:
- mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
- if (GET_MODE_CLASS (mode) == MODE_INT
- && ! can_compare_p (GT, mode, ccp_jump))
- do_jump_by_parts_greater (exp, 0, if_false_label, if_true_label);
- else
- do_compare_and_jump (exp, GT, GTU, if_false_label, if_true_label);
- break;
-
- case GE_EXPR:
- mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
- if (GET_MODE_CLASS (mode) == MODE_INT
- && ! can_compare_p (GE, mode, ccp_jump))
- do_jump_by_parts_greater (exp, 1, if_true_label, if_false_label);
- else
- do_compare_and_jump (exp, GE, GEU, if_false_label, if_true_label);
- break;
-
- case UNORDERED_EXPR:
- case ORDERED_EXPR:
- {
- enum rtx_code cmp, rcmp;
- int do_rev;
-
- if (code == UNORDERED_EXPR)
- cmp = UNORDERED, rcmp = ORDERED;
- else
- cmp = ORDERED, rcmp = UNORDERED;
- mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
-
- do_rev = 0;
- if (! can_compare_p (cmp, mode, ccp_jump)
- && (can_compare_p (rcmp, mode, ccp_jump)
- /* If the target doesn't provide either UNORDERED or ORDERED
- comparisons, canonicalize on UNORDERED for the library. */
- || rcmp == UNORDERED))
- do_rev = 1;
-
- if (! do_rev)
- do_compare_and_jump (exp, cmp, cmp, if_false_label, if_true_label);
- else
- do_compare_and_jump (exp, rcmp, rcmp, if_true_label, if_false_label);
- }
- break;
-
- {
- enum rtx_code rcode1;
- enum tree_code tcode2;
-
- case UNLT_EXPR:
- rcode1 = UNLT;
- tcode2 = LT_EXPR;
- goto unordered_bcc;
- case UNLE_EXPR:
- rcode1 = UNLE;
- tcode2 = LE_EXPR;
- goto unordered_bcc;
- case UNGT_EXPR:
- rcode1 = UNGT;
- tcode2 = GT_EXPR;
- goto unordered_bcc;
- case UNGE_EXPR:
- rcode1 = UNGE;
- tcode2 = GE_EXPR;
- goto unordered_bcc;
- case UNEQ_EXPR:
- rcode1 = UNEQ;
- tcode2 = EQ_EXPR;
- goto unordered_bcc;
-
- unordered_bcc:
- mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
- if (can_compare_p (rcode1, mode, ccp_jump))
- do_compare_and_jump (exp, rcode1, rcode1, if_false_label,
- if_true_label);
- else
- {
- tree op0 = save_expr (TREE_OPERAND (exp, 0));
- tree op1 = save_expr (TREE_OPERAND (exp, 1));
- tree cmp0, cmp1;
-
- /* If the target doesn't support combined unordered
- compares, decompose into UNORDERED + comparison. */
- cmp0 = fold (build (UNORDERED_EXPR, TREE_TYPE (exp), op0, op1));
- cmp1 = fold (build (tcode2, TREE_TYPE (exp), op0, op1));
- exp = build (TRUTH_ORIF_EXPR, TREE_TYPE (exp), cmp0, cmp1);
- do_jump (exp, if_false_label, if_true_label);
- }
- }
- break;
-
- /* Special case:
- __builtin_expect (<test>, 0) and
- __builtin_expect (<test>, 1)
-
- We need to do this here, so that <test> is not converted to a SCC
- operation on machines that use condition code registers and COMPARE
- like the PowerPC, and then the jump is done based on whether the SCC
- operation produced a 1 or 0. */
- case CALL_EXPR:
- /* Check for a built-in function. */
- if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
- {
- tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
- tree arglist = TREE_OPERAND (exp, 1);
-
- if (TREE_CODE (fndecl) == FUNCTION_DECL
- && DECL_BUILT_IN (fndecl)
- && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT
- && arglist != NULL_TREE
- && TREE_CHAIN (arglist) != NULL_TREE)
- {
- rtx seq = expand_builtin_expect_jump (exp, if_false_label,
- if_true_label);
-
- if (seq != NULL_RTX)
- {
- emit_insn (seq);
- return;
- }
- }
- }
- /* fall through and generate the normal code. */
-
- default:
- normal:
- temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
-#if 0
- /* This is not needed any more and causes poor code since it causes
- comparisons and tests from non-SI objects to have different code
- sequences. */
- /* Copy to register to avoid generating bad insns by cse
- from (set (mem ...) (arithop)) (set (cc0) (mem ...)). */
- if (!cse_not_expected && GET_CODE (temp) == MEM)
- temp = copy_to_reg (temp);
-#endif
- do_pending_stack_adjust ();
- /* Do any postincrements in the expression that was tested. */
- emit_queue ();
-
- if (GET_CODE (temp) == CONST_INT
- || (GET_CODE (temp) == CONST_DOUBLE && GET_MODE (temp) == VOIDmode)
- || GET_CODE (temp) == LABEL_REF)
- {
- rtx target = temp == const0_rtx ? if_false_label : if_true_label;
- if (target)
- emit_jump (target);
- }
- else if (GET_MODE_CLASS (GET_MODE (temp)) == MODE_INT
- && ! can_compare_p (NE, GET_MODE (temp), ccp_jump))
- /* Note swapping the labels gives us not-equal. */
- do_jump_by_parts_equality_rtx (temp, if_true_label, if_false_label);
- else if (GET_MODE (temp) != VOIDmode)
- do_compare_rtx_and_jump (temp, CONST0_RTX (GET_MODE (temp)),
- NE, TREE_UNSIGNED (TREE_TYPE (exp)),
- GET_MODE (temp), NULL_RTX,
- if_false_label, if_true_label);
- else
- abort ();
- }
-
- if (drop_through_label)
- {
- /* If do_jump produces code that might be jumped around,
- do any stack adjusts from that code, before the place
- where control merges in. */
- do_pending_stack_adjust ();
- emit_label (drop_through_label);
- }
-}
-
-/* Given a comparison expression EXP for values too wide to be compared
- with one insn, test the comparison and jump to the appropriate label.
- The code of EXP is ignored; we always test GT if SWAP is 0,
- and LT if SWAP is 1. */
-
-static void
-do_jump_by_parts_greater (exp, swap, if_false_label, if_true_label)
- tree exp;
- int swap;
- rtx if_false_label, if_true_label;
-{
- rtx op0 = expand_expr (TREE_OPERAND (exp, swap), NULL_RTX, VOIDmode, 0);
- rtx op1 = expand_expr (TREE_OPERAND (exp, !swap), NULL_RTX, VOIDmode, 0);
- enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
- int unsignedp = TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0)));
-
- do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label, if_true_label);
-}
-
-/* Compare OP0 with OP1, word at a time, in mode MODE.
- UNSIGNEDP says to do unsigned comparison.
- Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise. */
-
-void
-do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label, if_true_label)
- enum machine_mode mode;
- int unsignedp;
- rtx op0, op1;
- rtx if_false_label, if_true_label;
-{
- int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
- rtx drop_through_label = 0;
- int i;
-
- if (! if_true_label || ! if_false_label)
- drop_through_label = gen_label_rtx ();
- if (! if_true_label)
- if_true_label = drop_through_label;
- if (! if_false_label)
- if_false_label = drop_through_label;
-
- /* Compare a word at a time, high order first. */
- for (i = 0; i < nwords; i++)
- {
- rtx op0_word, op1_word;
-
- if (WORDS_BIG_ENDIAN)
- {
- op0_word = operand_subword_force (op0, i, mode);
- op1_word = operand_subword_force (op1, i, mode);
- }
- else
- {
- op0_word = operand_subword_force (op0, nwords - 1 - i, mode);
- op1_word = operand_subword_force (op1, nwords - 1 - i, mode);
- }
-
- /* All but high-order word must be compared as unsigned. */
- do_compare_rtx_and_jump (op0_word, op1_word, GT,
- (unsignedp || i > 0), word_mode, NULL_RTX,
- NULL_RTX, if_true_label);
-
- /* Consider lower words only if these are equal. */
- do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode,
- NULL_RTX, NULL_RTX, if_false_label);
- }
-
- if (if_false_label)
- emit_jump (if_false_label);
- if (drop_through_label)
- emit_label (drop_through_label);
-}
-
-/* Given an EQ_EXPR expression EXP for values too wide to be compared
- with one insn, test the comparison and jump to the appropriate label. */
-
-static void
-do_jump_by_parts_equality (exp, if_false_label, if_true_label)
- tree exp;
- rtx if_false_label, if_true_label;
-{
- rtx op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
- rtx op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
- enum machine_mode mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)));
- int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD);
- int i;
- rtx drop_through_label = 0;
-
- if (! if_false_label)
- drop_through_label = if_false_label = gen_label_rtx ();
-
- for (i = 0; i < nwords; i++)
- do_compare_rtx_and_jump (operand_subword_force (op0, i, mode),
- operand_subword_force (op1, i, mode),
- EQ, TREE_UNSIGNED (TREE_TYPE (exp)),
- word_mode, NULL_RTX, if_false_label, NULL_RTX);
-
- if (if_true_label)
- emit_jump (if_true_label);
- if (drop_through_label)
- emit_label (drop_through_label);
-}
-
-/* Jump according to whether OP0 is 0.
- We assume that OP0 has an integer mode that is too wide
- for the available compare insns. */
-
-void
-do_jump_by_parts_equality_rtx (op0, if_false_label, if_true_label)
- rtx op0;
- rtx if_false_label, if_true_label;
-{
- int nwords = GET_MODE_SIZE (GET_MODE (op0)) / UNITS_PER_WORD;
- rtx part;
- int i;
- rtx drop_through_label = 0;
-
- /* The fastest way of doing this comparison on almost any machine is to
- "or" all the words and compare the result. If all have to be loaded
- from memory and this is a very wide item, it's possible this may
- be slower, but that's highly unlikely. */
-
- part = gen_reg_rtx (word_mode);
- emit_move_insn (part, operand_subword_force (op0, 0, GET_MODE (op0)));
- for (i = 1; i < nwords && part != 0; i++)
- part = expand_binop (word_mode, ior_optab, part,
- operand_subword_force (op0, i, GET_MODE (op0)),
- part, 1, OPTAB_WIDEN);
-
- if (part != 0)
- {
- do_compare_rtx_and_jump (part, const0_rtx, EQ, 1, word_mode,
- NULL_RTX, if_false_label, if_true_label);
-
- return;
- }
-
- /* If we couldn't do the "or" simply, do this with a series of compares. */
- if (! if_false_label)
- drop_through_label = if_false_label = gen_label_rtx ();
-
- for (i = 0; i < nwords; i++)
- do_compare_rtx_and_jump (operand_subword_force (op0, i, GET_MODE (op0)),
- const0_rtx, EQ, 1, word_mode, NULL_RTX,
- if_false_label, NULL_RTX);
-
- if (if_true_label)
- emit_jump (if_true_label);
-
- if (drop_through_label)
- emit_label (drop_through_label);
-}
-
-/* Generate code for a comparison of OP0 and OP1 with rtx code CODE.
- (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 (op0, op1, code, unsignedp, mode, size)
- rtx op0, op1;
- enum rtx_code code;
- int unsignedp;
- enum machine_mode mode;
- rtx size;
-{
- enum rtx_code ucode;
- 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);
- }
-
- if (flag_force_mem)
- {
- op0 = force_not_mem (op0);
- op1 = force_not_mem (op1);
- }
-
- do_pending_stack_adjust ();
-
- ucode = unsignedp ? unsigned_condition (code) : code;
- if ((tem = simplify_relational_operation (ucode, mode, op0, op1)) != 0)
- return tem;
-
-#if 0
- /* There's no need to do this now that combine.c can eliminate lots of
- sign extensions. This can be less efficient in certain cases on other
- machines. */
-
- /* If this is a signed equality comparison, we can do it as an
- unsigned comparison since zero-extension is cheaper than sign
- extension and comparisons with zero are done as unsigned. This is
- the case even on machines that can do fast sign extension, since
- zero-extension is easier to combine with other operations than
- sign-extension is. If we are comparing against a constant, we must
- convert it to what it would look like unsigned. */
- if ((code == EQ || code == NE) && ! unsignedp
- && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
- {
- if (GET_CODE (op1) == CONST_INT
- && (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0))) != INTVAL (op1))
- op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0)));
- unsignedp = 1;
- }
-#endif
-
- 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.
-
- If MODE is BLKmode, SIZE is an RTX giving the size of the objects being
- compared. */
-
-void
-do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, size,
- if_false_label, if_true_label)
- rtx op0, op1;
- enum rtx_code code;
- int unsignedp;
- enum machine_mode mode;
- rtx size;
- rtx if_false_label, if_true_label;
-{
- enum rtx_code ucode;
- rtx tem;
- int dummy_true_label = 0;
-
- /* Reverse the comparison if that is safe and we want to jump if it is
- false. */
- if (! if_true_label && ! FLOAT_MODE_P (mode))
- {
- if_true_label = if_false_label;
- if_false_label = 0;
- code = reverse_condition (code);
- }
-
- /* 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);
- }
-
- if (flag_force_mem)
- {
- op0 = force_not_mem (op0);
- op1 = force_not_mem (op1);
- }
-
- do_pending_stack_adjust ();
-
- ucode = unsignedp ? unsigned_condition (code) : code;
- if ((tem = simplify_relational_operation (ucode, mode, op0, op1)) != 0)
- {
- if (tem == const_true_rtx)
- {
- if (if_true_label)
- emit_jump (if_true_label);
- }
- else
- {
- if (if_false_label)
- emit_jump (if_false_label);
- }
- return;
- }
-
-#if 0
- /* There's no need to do this now that combine.c can eliminate lots of
- sign extensions. This can be less efficient in certain cases on other
- machines. */
-
- /* If this is a signed equality comparison, we can do it as an
- unsigned comparison since zero-extension is cheaper than sign
- extension and comparisons with zero are done as unsigned. This is
- the case even on machines that can do fast sign extension, since
- zero-extension is easier to combine with other operations than
- sign-extension is. If we are comparing against a constant, we must
- convert it to what it would look like unsigned. */
- if ((code == EQ || code == NE) && ! unsignedp
- && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
- {
- if (GET_CODE (op1) == CONST_INT
- && (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0))) != INTVAL (op1))
- op1 = GEN_INT (INTVAL (op1) & GET_MODE_MASK (GET_MODE (op0)));
- unsignedp = 1;
- }
-#endif
-
- if (! if_true_label)
- {
- dummy_true_label = 1;
- if_true_label = gen_label_rtx ();
- }
-
- emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp,
- if_true_label);
-
- if (if_false_label)
- emit_jump (if_false_label);
- if (dummy_true_label)
- emit_label (if_true_label);
-}
-
-/* Generate code for a comparison expression EXP (including code to compute
- the values to be compared) and a conditional jump to IF_FALSE_LABEL and/or
- IF_TRUE_LABEL. One of the labels can be NULL_RTX, in which case the
- generated code will drop through.
- SIGNED_CODE should be the rtx operation for this comparison for
- signed data; UNSIGNED_CODE, likewise for use if data is unsigned.
-
- We force a stack adjustment unless there are currently
- things pushed on the stack that aren't yet used. */
-
-static void
-do_compare_and_jump (exp, signed_code, unsigned_code, if_false_label,
- if_true_label)
- tree exp;
- enum rtx_code signed_code, unsigned_code;
- rtx if_false_label, if_true_label;
-{
- rtx op0, op1;
- tree type;
- enum machine_mode mode;
- int unsignedp;
- enum rtx_code code;
-
- /* Don't crash if the comparison was erroneous. */
- op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
- if (TREE_CODE (TREE_OPERAND (exp, 0)) == ERROR_MARK)
- return;
-
- op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, VOIDmode, 0);
- if (TREE_CODE (TREE_OPERAND (exp, 1)) == ERROR_MARK)
- return;
-
- type = TREE_TYPE (TREE_OPERAND (exp, 0));
- mode = TYPE_MODE (type);
- if (TREE_CODE (TREE_OPERAND (exp, 0)) == INTEGER_CST
- && (TREE_CODE (TREE_OPERAND (exp, 1)) != INTEGER_CST
- || (GET_MODE_BITSIZE (mode)
- > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp,
- 1)))))))
- {
- /* op0 might have been replaced by promoted constant, in which
- case the type of second argument should be used. */
- type = TREE_TYPE (TREE_OPERAND (exp, 1));
- mode = TYPE_MODE (type);
- }
- unsignedp = TREE_UNSIGNED (type);
- code = unsignedp ? unsigned_code : signed_code;
-
-#ifdef HAVE_canonicalize_funcptr_for_compare
- /* If function pointers need to be "canonicalized" before they can
- be reliably compared, then canonicalize them. */
- if (HAVE_canonicalize_funcptr_for_compare
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE
- && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))))
- == FUNCTION_TYPE))
- {
- rtx new_op0 = gen_reg_rtx (mode);
-
- emit_insn (gen_canonicalize_funcptr_for_compare (new_op0, op0));
- op0 = new_op0;
- }
-
- if (HAVE_canonicalize_funcptr_for_compare
- && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 1))) == POINTER_TYPE
- && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 1))))
- == FUNCTION_TYPE))
- {
- rtx new_op1 = gen_reg_rtx (mode);
-
- emit_insn (gen_canonicalize_funcptr_for_compare (new_op1, op1));
- op1 = new_op1;
- }
-#endif
-
- /* Do any postincrements in the expression that was tested. */
- emit_queue ();
-
- do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
- ((mode == BLKmode)
- ? expr_size (TREE_OPERAND (exp, 0)) : NULL_RTX),
- if_false_label, if_true_label);
-}
-
/* Generate code to calculate EXP using a store-flag instruction
and return an rtx for the result. EXP is either a comparison
or a TRUTH_NOT_EXPR whose operand is a comparison.
@@ -10738,11 +9441,7 @@ do_compare_and_jump (exp, signed_code, unsigned_code, if_false_label,
set/jump/set sequence. */
static rtx
-do_store_flag (exp, target, mode, only_cheap)
- tree exp;
- rtx target;
- enum machine_mode mode;
- int only_cheap;
+do_store_flag (tree exp, rtx target, enum machine_mode mode, int only_cheap)
{
enum rtx_code code;
tree arg0, arg1, type;
@@ -10872,64 +9571,19 @@ do_store_flag (exp, target, mode, only_cheap)
do this by shifting the bit being tested to the low-order bit and
masking the result with the constant 1. If the condition was EQ,
we xor it with 1. This does not require an scc insn and is faster
- than an scc insn even if we have it. */
+ than an scc insn even if we have it.
+
+ The code to make this transformation was moved into fold_single_bit_test,
+ so we just call into the folder and expand its result. */
if ((code == NE || code == EQ)
&& TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1)
&& integer_pow2p (TREE_OPERAND (arg0, 1)))
{
- tree inner = TREE_OPERAND (arg0, 0);
- int bitnum = tree_log2 (TREE_OPERAND (arg0, 1));
- int ops_unsignedp;
-
- /* If INNER is a right shift of a constant and it plus BITNUM does
- not overflow, adjust BITNUM and INNER. */
-
- if (TREE_CODE (inner) == RSHIFT_EXPR
- && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST
- && TREE_INT_CST_HIGH (TREE_OPERAND (inner, 1)) == 0
- && bitnum < TYPE_PRECISION (type)
- && 0 > compare_tree_int (TREE_OPERAND (inner, 1),
- bitnum - TYPE_PRECISION (type)))
- {
- bitnum += TREE_INT_CST_LOW (TREE_OPERAND (inner, 1));
- inner = TREE_OPERAND (inner, 0);
- }
-
- /* If we are going to be able to omit the AND below, we must do our
- operations as unsigned. If we must use the AND, we have a choice.
- Normally unsigned is faster, but for some machines signed is. */
- ops_unsignedp = (bitnum == TYPE_PRECISION (type) - 1 ? 1
-#ifdef LOAD_EXTEND_OP
- : (LOAD_EXTEND_OP (operand_mode) == SIGN_EXTEND ? 0 : 1)
-#else
- : 1
-#endif
- );
-
- if (! get_subtarget (subtarget)
- || GET_MODE (subtarget) != operand_mode
- || ! safe_from_p (subtarget, inner, 1))
- subtarget = 0;
-
- op0 = expand_expr (inner, subtarget, VOIDmode, 0);
-
- if (bitnum != 0)
- op0 = expand_shift (RSHIFT_EXPR, operand_mode, op0,
- size_int (bitnum), subtarget, ops_unsignedp);
-
- if (GET_MODE (op0) != mode)
- op0 = convert_to_mode (mode, op0, ops_unsignedp);
-
- if ((code == EQ && ! invert) || (code == NE && invert))
- op0 = expand_binop (mode, xor_optab, op0, const1_rtx, subtarget,
- ops_unsignedp, OPTAB_LIB_WIDEN);
-
- /* Put the AND last so it can combine with more things. */
- if (bitnum != TYPE_PRECISION (type) - 1)
- op0 = expand_and (mode, op0, const1_rtx, subtarget);
-
- return op0;
+ tree type = (*lang_hooks.types.type_for_mode) (mode, unsignedp);
+ return expand_expr (fold_single_bit_test (code == NE ? NE_EXPR : EQ_EXPR,
+ arg0, arg1, type),
+ target, VOIDmode, EXPAND_NORMAL);
}
/* Now see if we are likely to be able to do this. Return if not. */
@@ -10958,12 +9612,10 @@ do_store_flag (exp, target, mode, only_cheap)
}
if (! get_subtarget (target)
- || GET_MODE (subtarget) != operand_mode
- || ! safe_from_p (subtarget, arg1, 1))
+ || GET_MODE (subtarget) != operand_mode)
subtarget = 0;
- op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
- op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
+ expand_operands (arg0, arg1, subtarget, &op0, &op1, 0);
if (target == 0)
target = gen_reg_rtx (mode);
@@ -11033,7 +9685,7 @@ do_store_flag (exp, target, mode, only_cheap)
#endif /* CASE_VALUES_THRESHOLD */
unsigned int
-case_values_threshold ()
+case_values_threshold (void)
{
return CASE_VALUES_THRESHOLD;
}
@@ -11041,11 +9693,8 @@ case_values_threshold ()
/* Attempt to generate a casesi instruction. Returns 1 if successful,
0 otherwise (i.e. if there is no casesi instruction). */
int
-try_casesi (index_type, index_expr, minval, range,
- table_label, default_label)
- tree index_type, index_expr, minval, range;
- rtx table_label ATTRIBUTE_UNUSED;
- rtx default_label;
+try_casesi (tree index_type, tree index_expr, tree minval, tree range,
+ rtx table_label ATTRIBUTE_UNUSED, rtx default_label)
{
enum machine_mode index_mode = SImode;
int index_bits = GET_MODE_BITSIZE (index_mode);
@@ -11132,9 +9781,8 @@ try_casesi (index_type, index_expr, minval, range,
index value is out of range. */
static void
-do_tablejump (index, mode, range, table_label, default_label)
- rtx index, range, table_label, default_label;
- enum machine_mode mode;
+do_tablejump (rtx index, enum machine_mode mode, rtx range, rtx table_label,
+ rtx default_label)
{
rtx temp, vector;
@@ -11157,7 +9805,7 @@ do_tablejump (index, mode, range, table_label, default_label)
if (mode != Pmode)
index = convert_to_mode (Pmode, index, 1);
- /* Don't let a MEM slip thru, because then INDEX that comes
+ /* Don't let a MEM slip through, because then INDEX that comes
out of PIC_CASE_VECTOR_ADDRESS won't be a valid address,
and break_out_memory_refs will go to work on it and mess it up. */
#ifdef PIC_CASE_VECTOR_ADDRESS
@@ -11198,10 +9846,8 @@ do_tablejump (index, mode, range, table_label, default_label)
}
int
-try_tablejump (index_type, index_expr, minval, range,
- table_label, default_label)
- tree index_type, index_expr, minval, range;
- rtx table_label, default_label;
+try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
+ rtx table_label, rtx default_label)
{
rtx index;
@@ -11231,8 +9877,7 @@ try_tablejump (index_type, index_expr, minval, range,
vector mode, but we can emulate with narrower modes. */
int
-vector_mode_valid_p (mode)
- enum machine_mode mode;
+vector_mode_valid_p (enum machine_mode mode)
{
enum mode_class class = GET_MODE_CLASS (mode);
enum machine_mode innermode;
@@ -11258,8 +9903,7 @@ vector_mode_valid_p (mode)
/* Return a CONST_VECTOR rtx for a VECTOR_CST tree. */
static rtx
-const_vector_from_tree (exp)
- tree exp;
+const_vector_from_tree (tree exp)
{
rtvec v;
int units, i;
@@ -11290,6 +9934,10 @@ const_vector_from_tree (exp)
inner);
}
+ /* Initialize remaining elements to 0. */
+ for (; i < units; ++i)
+ RTVEC_ELT (v, i) = CONST0_RTX (inner);
+
return gen_rtx_raw_CONST_VECTOR (mode, v);
}
diff --git a/contrib/gcc/expr.h b/contrib/gcc/expr.h
index c38cd9946c90..dd7ac9c6058b 100644
--- a/contrib/gcc/expr.h
+++ b/contrib/gcc/expr.h
@@ -1,6 +1,6 @@
/* Definitions for code generation pass of GNU compiler.
Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -66,7 +66,32 @@ enum expand_modifier {EXPAND_NORMAL = 0, EXPAND_STACK_PARM = 2, EXPAND_SUM,
more information. */
#define OK_DEFER_POP (inhibit_defer_pop -= 1)
-#ifdef TREE_CODE /* Don't lose if tree.h not included. */
+/* If a memory-to-memory move would take MOVE_RATIO or more simple
+ move-instruction sequences, we will do a movstr or libcall instead. */
+
+#ifndef MOVE_RATIO
+#if defined (HAVE_movstrqi) || defined (HAVE_movstrhi) || defined (HAVE_movstrsi) || defined (HAVE_movstrdi) || defined (HAVE_movstrti)
+#define MOVE_RATIO 2
+#else
+/* If we are optimizing for space (-Os), cut down the default move ratio. */
+#define MOVE_RATIO (optimize_size ? 3 : 15)
+#endif
+#endif
+
+/* If a clear memory operation would take CLEAR_RATIO or more simple
+ move-instruction sequences, we will do a clrstr or libcall instead. */
+
+#ifndef CLEAR_RATIO
+#if defined (HAVE_clrstrqi) || defined (HAVE_clrstrhi) || defined (HAVE_clrstrsi) || defined (HAVE_clrstrdi) || defined (HAVE_clrstrti)
+#define CLEAR_RATIO 2
+#else
+/* If we are optimizing for space, cut down the default clear ratio. */
+#define CLEAR_RATIO (optimize_size ? 3 : 15)
+#endif
+#endif
+
+enum direction {none, upward, downward};
+
/* Structure to record the size of a sequence of arguments
as the sum of a tree-expression and a constant. This structure is
also used to store offsets from the stack, which might be negative,
@@ -77,7 +102,26 @@ struct args_size
HOST_WIDE_INT constant;
tree var;
};
-#endif
+
+/* Package up various arg related fields of struct args for
+ locate_and_pad_parm. */
+struct locate_and_pad_arg_data
+{
+ /* Size of this argument on the stack, rounded up for any padding it
+ gets. If REG_PARM_STACK_SPACE is defined, then register parms are
+ counted here, otherwise they aren't. */
+ struct args_size size;
+ /* Offset of this argument from beginning of stack-args. */
+ struct args_size offset;
+ /* Offset to the start of the stack slot. Different from OFFSET
+ if this arg pads downward. */
+ struct args_size slot_offset;
+ /* The amount that the stack pointer needs to be adjusted to
+ force alignment for the next argument. */
+ struct args_size alignment_pad;
+ /* Which way we should pad this arg. */
+ enum direction where_pad;
+};
/* Add the value of the tree INC to the `struct args_size' TO. */
@@ -122,10 +166,7 @@ do { \
usually pad upward, but pad short args downward on
big-endian machines. */
-enum direction {none, upward, downward}; /* Value has this type. */
-
-#ifndef FUNCTION_ARG_PADDING
-#define FUNCTION_ARG_PADDING(MODE, TYPE) \
+#define DEFAULT_FUNCTION_ARG_PADDING(MODE, TYPE) \
(! BYTES_BIG_ENDIAN \
? upward \
: (((MODE) == BLKmode \
@@ -133,6 +174,10 @@ enum direction {none, upward, downward}; /* Value has this type. */
&& int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT)) \
: GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY) \
? downward : upward))
+
+#ifndef FUNCTION_ARG_PADDING
+#define FUNCTION_ARG_PADDING(MODE, TYPE) \
+ DEFAULT_FUNCTION_ARG_PADDING ((MODE), (TYPE))
#endif
/* Supply a default definition for FUNCTION_ARG_BOUNDARY. Normally, we let
@@ -143,56 +188,13 @@ enum direction {none, upward, downward}; /* Value has this type. */
#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) PARM_BOUNDARY
#endif
-/* Provide a default value for STRICT_ARGUMENT_NAMING. */
-#ifndef STRICT_ARGUMENT_NAMING
-#define STRICT_ARGUMENT_NAMING 0
-#endif
-
-/* Provide a default value for PRETEND_OUTGOING_VARARGS_NAMED. */
-#ifdef SETUP_INCOMING_VARARGS
-#ifndef PRETEND_OUTGOING_VARARGS_NAMED
-#define PRETEND_OUTGOING_VARARGS_NAMED 1
-#endif
-#else
-/* It is an error to define PRETEND_OUTGOING_VARARGS_NAMED without
- defining SETUP_INCOMING_VARARGS. */
-#define PRETEND_OUTGOING_VARARGS_NAMED 0
-#endif
-
-/* Nonzero if we do not know how to pass TYPE solely in registers.
- We cannot do so in the following cases:
-
- - if the type has variable size
- - if the type is marked as addressable (it is required to be constructed
- into the stack)
- - if the padding and mode of the type is such that a copy into a register
- would put it into the wrong part of the register.
-
- Which padding can't be supported depends on the byte endianness.
-
- A value in a register is implicitly padded at the most significant end.
- On a big-endian machine, that is the lower end in memory.
- So a value padded in memory at the upper end can't go in a register.
- For a little-endian machine, the reverse is true. */
+tree split_complex_types (tree);
+tree split_complex_values (tree);
+/* Nonzero if we do not know how to pass TYPE solely in registers. */
+extern bool default_must_pass_in_stack (enum machine_mode, tree);
#ifndef MUST_PASS_IN_STACK
-#define MUST_PASS_IN_STACK(MODE,TYPE) \
- ((TYPE) != 0 \
- && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
- || TREE_ADDRESSABLE (TYPE) \
- || ((MODE) == BLKmode \
- && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
- && 0 == (int_size_in_bytes (TYPE) \
- % (PARM_BOUNDARY / BITS_PER_UNIT))) \
- && (FUNCTION_ARG_PADDING (MODE, TYPE) \
- == (BYTES_BIG_ENDIAN ? upward : downward)))))
-#endif
-
-/* Nonzero if type TYPE should be returned in memory.
- Most machines can use the following default definition. */
-
-#ifndef RETURN_IN_MEMORY
-#define RETURN_IN_MEMORY(TYPE) (TYPE_MODE (TYPE) == BLKmode)
+#define MUST_PASS_IN_STACK(MODE,TYPE) default_must_pass_in_stack(MODE, TYPE)
#endif
/* Supply a default definition of STACK_SAVEAREA_MODE for emit_stack_save.
@@ -271,133 +273,131 @@ enum optab_methods
/* Generate code for a simple binary or unary operation. "Simple" in
this case means "can be unambiguously described by a (mode, code)
pair and mapped to a single optab." */
-extern rtx expand_simple_binop PARAMS ((enum machine_mode, enum rtx_code, rtx,
- rtx, rtx, int, enum optab_methods));
-extern rtx expand_simple_unop PARAMS ((enum machine_mode, enum rtx_code,
- rtx, rtx, int));
+extern rtx expand_simple_binop (enum machine_mode, enum rtx_code, rtx,
+ rtx, rtx, int, enum optab_methods);
+extern rtx expand_simple_unop (enum machine_mode, enum rtx_code, rtx, rtx,
+ int);
/* Report whether the machine description contains an insn which can
perform the operation described by CODE and MODE. */
-extern int have_insn_for PARAMS ((enum rtx_code, enum machine_mode));
+extern int have_insn_for (enum rtx_code, enum machine_mode);
/* Emit code to make a call to a constant function or a library call. */
-extern void emit_libcall_block PARAMS ((rtx, rtx, rtx, rtx));
+extern void emit_libcall_block (rtx, rtx, rtx, rtx);
/* Create but don't emit one rtl instruction to perform certain operations.
Modes must match; operands must meet the operation's predicates.
Likewise for subtraction and for just copying.
These do not call protect_from_queue; caller must do so. */
-extern rtx gen_add2_insn PARAMS ((rtx, rtx));
-extern rtx gen_add3_insn PARAMS ((rtx, rtx, rtx));
-extern rtx gen_sub2_insn PARAMS ((rtx, rtx));
-extern rtx gen_sub3_insn PARAMS ((rtx, rtx, rtx));
-extern rtx gen_move_insn PARAMS ((rtx, rtx));
-extern int have_add2_insn PARAMS ((rtx, rtx));
-extern int have_sub2_insn PARAMS ((rtx, rtx));
+extern rtx gen_add2_insn (rtx, rtx);
+extern rtx gen_add3_insn (rtx, rtx, rtx);
+extern rtx gen_sub2_insn (rtx, rtx);
+extern rtx gen_sub3_insn (rtx, rtx, rtx);
+extern rtx gen_move_insn (rtx, rtx);
+extern int have_add2_insn (rtx, rtx);
+extern int have_sub2_insn (rtx, rtx);
/* Emit a pair of rtl insns to compare two rtx's and to jump
to a label if the comparison is true. */
-extern void emit_cmp_and_jump_insns PARAMS ((rtx, rtx, enum rtx_code, rtx,
- enum machine_mode, int, rtx));
+extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx,
+ enum machine_mode, int, rtx);
/* Generate code to indirectly jump to a location given in the rtx LOC. */
-extern void emit_indirect_jump PARAMS ((rtx));
+extern void emit_indirect_jump (rtx);
#ifdef HAVE_conditional_move
/* Emit a conditional move operation. */
-rtx emit_conditional_move PARAMS ((rtx, enum rtx_code, rtx, rtx,
- enum machine_mode, rtx, rtx,
- enum machine_mode, int));
+rtx emit_conditional_move (rtx, enum rtx_code, rtx, rtx, enum machine_mode,
+ rtx, rtx, enum machine_mode, int);
/* Return nonzero if the conditional move is supported. */
-int can_conditionally_move_p PARAMS ((enum machine_mode mode));
+int can_conditionally_move_p (enum machine_mode mode);
#endif
+rtx emit_conditional_add (rtx, enum rtx_code, rtx, rtx, enum machine_mode,
+ rtx, rtx, enum machine_mode, int);
/* Functions from expmed.c: */
/* Arguments MODE, RTX: return an rtx for the negation of that value.
May emit insns. */
-extern rtx negate_rtx PARAMS ((enum machine_mode, rtx));
+extern rtx negate_rtx (enum machine_mode, rtx);
/* Expand a logical AND operation. */
-extern rtx expand_and PARAMS ((enum machine_mode, rtx, rtx, rtx));
+extern rtx expand_and (enum machine_mode, rtx, rtx, rtx);
/* Emit a store-flag operation. */
-extern rtx emit_store_flag PARAMS ((rtx, enum rtx_code, rtx, rtx,
- enum machine_mode, int, int));
+extern rtx emit_store_flag (rtx, enum rtx_code, rtx, rtx, enum machine_mode,
+ int, int);
/* Like emit_store_flag, but always succeeds. */
-extern rtx emit_store_flag_force PARAMS ((rtx, enum rtx_code, rtx, rtx,
- enum machine_mode, int, int));
+extern rtx emit_store_flag_force (rtx, enum rtx_code, rtx, rtx,
+ enum machine_mode, int, int);
/* Functions from loop.c: */
/* Given an insn and condition, return a canonical description of
the test being made. */
-extern rtx canonicalize_condition PARAMS ((rtx, rtx, int, rtx *, rtx));
+extern rtx canonicalize_condition (rtx, rtx, int, rtx *, rtx, int);
/* Given a JUMP_INSN, return a canonical description of the test
being made. */
-extern rtx get_condition PARAMS ((rtx, rtx *));
+extern rtx get_condition (rtx, rtx *, int);
/* Generate a conditional trap instruction. */
-extern rtx gen_cond_trap PARAMS ((enum rtx_code, rtx, rtx, rtx));
+extern rtx gen_cond_trap (enum rtx_code, rtx, rtx, rtx);
/* Functions from builtins.c: */
-extern rtx expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
-extern void std_expand_builtin_va_start PARAMS ((tree, rtx));
-extern rtx std_expand_builtin_va_arg PARAMS ((tree, tree));
-extern rtx expand_builtin_va_arg PARAMS ((tree, tree));
-extern void default_init_builtins PARAMS ((void));
-extern rtx default_expand_builtin PARAMS ((tree, rtx, rtx,
- enum machine_mode, int));
-extern void expand_builtin_setjmp_setup PARAMS ((rtx, rtx));
-extern void expand_builtin_setjmp_receiver PARAMS ((rtx));
-extern void expand_builtin_longjmp PARAMS ((rtx, rtx));
-extern rtx expand_builtin_saveregs PARAMS ((void));
-extern void expand_builtin_trap PARAMS ((void));
-extern HOST_WIDE_INT get_varargs_alias_set PARAMS ((void));
-extern HOST_WIDE_INT get_frame_alias_set PARAMS ((void));
-extern void record_base_value PARAMS ((unsigned int, rtx, int));
-extern void record_alias_subset PARAMS ((HOST_WIDE_INT,
- HOST_WIDE_INT));
-extern HOST_WIDE_INT new_alias_set PARAMS ((void));
-extern int can_address_p PARAMS ((tree));
+extern rtx expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+extern tree std_build_builtin_va_list (void);
+extern void std_expand_builtin_va_start (tree, rtx);
+extern rtx std_expand_builtin_va_arg (tree, tree);
+extern rtx expand_builtin_va_arg (tree, tree);
+extern rtx default_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
+extern void expand_builtin_setjmp_setup (rtx, rtx);
+extern void expand_builtin_setjmp_receiver (rtx);
+extern void expand_builtin_longjmp (rtx, rtx);
+extern rtx expand_builtin_saveregs (void);
+extern void expand_builtin_trap (void);
+extern HOST_WIDE_INT get_varargs_alias_set (void);
+extern HOST_WIDE_INT get_frame_alias_set (void);
+extern void record_base_value (unsigned int, rtx, int);
+extern void record_alias_subset (HOST_WIDE_INT, HOST_WIDE_INT);
+extern HOST_WIDE_INT new_alias_set (void);
+extern int can_address_p (tree);
/* Functions from expr.c: */
/* This is run once per compilation to set up which modes can be used
directly in memory and to initialize the block move optab. */
-extern void init_expr_once PARAMS ((void));
+extern void init_expr_once (void);
/* This is run at the start of compiling a function. */
-extern void init_expr PARAMS ((void));
+extern void init_expr (void);
/* This is run at the end of compiling a function. */
-extern void finish_expr_for_function PARAMS ((void));
+extern void finish_expr_for_function (void);
/* Use protect_from_queue to convert a QUEUED expression
into something that you can put immediately into an instruction. */
-extern rtx protect_from_queue PARAMS ((rtx, int));
+extern rtx protect_from_queue (rtx, int);
/* Perform all the pending incrementations. */
-extern void emit_queue PARAMS ((void));
+extern void emit_queue (void);
/* Tell if something has a queued subexpression. */
-extern int queued_subexp_p PARAMS ((rtx));
+extern int queued_subexp_p (rtx);
/* Emit some rtl insns to move data between rtx's, converting machine modes.
Both modes must be floating or both fixed. */
-extern void convert_move PARAMS ((rtx, rtx, int));
+extern void convert_move (rtx, rtx, int);
/* Convert an rtx to specified machine mode and return the result. */
-extern rtx convert_to_mode PARAMS ((enum machine_mode, rtx, int));
+extern rtx convert_to_mode (enum machine_mode, rtx, int);
/* Convert an rtx to MODE from OLDMODE and return the result. */
-extern rtx convert_modes PARAMS ((enum machine_mode, enum machine_mode,
- rtx, int));
+extern rtx convert_modes (enum machine_mode, enum machine_mode, rtx, int);
/* Emit code to move a block Y to a block X. */
@@ -408,99 +408,102 @@ enum block_op_methods
BLOCK_OP_CALL_PARM
};
-extern rtx emit_block_move PARAMS ((rtx, rtx, rtx, enum block_op_methods));
+extern void init_block_move_fn (const char *);
+extern void init_block_clear_fn (const char *);
+
+extern rtx emit_block_move (rtx, rtx, rtx, enum block_op_methods);
/* Copy all or part of a value X into registers starting at REGNO.
The number of registers to be filled is NREGS. */
-extern void move_block_to_reg PARAMS ((int, rtx, int, enum machine_mode));
+extern void move_block_to_reg (int, rtx, int, enum machine_mode);
/* Copy all or part of a BLKmode value X out of registers starting at REGNO.
The number of registers to be filled is NREGS. */
-extern void move_block_from_reg PARAMS ((int, rtx, int, int));
+extern void move_block_from_reg (int, rtx, int);
/* Generate a non-consecutive group of registers represented by a PARALLEL. */
-extern rtx gen_group_rtx PARAMS ((rtx));
+extern rtx gen_group_rtx (rtx);
/* Load a BLKmode value into non-consecutive registers represented by a
PARALLEL. */
-extern void emit_group_load PARAMS ((rtx, rtx, int));
+extern void emit_group_load (rtx, rtx, tree, int);
/* Move a non-consecutive group of registers represented by a PARALLEL into
a non-consecutive group of registers represented by a PARALLEL. */
-extern void emit_group_move PARAMS ((rtx, rtx));
+extern void emit_group_move (rtx, rtx);
/* Store a BLKmode value from non-consecutive registers represented by a
PARALLEL. */
-extern void emit_group_store PARAMS ((rtx, rtx, int));
+extern void emit_group_store (rtx, rtx, tree, int);
-#ifdef TREE_CODE
/* Copy BLKmode object from a set of registers. */
-extern rtx copy_blkmode_from_reg PARAMS ((rtx,rtx,tree));
-#endif
+extern rtx copy_blkmode_from_reg (rtx, rtx, tree);
/* Mark REG as holding a parameter for the next CALL_INSN. */
-extern void use_reg PARAMS ((rtx *, rtx));
+extern void use_reg (rtx *, rtx);
/* Mark NREGS consecutive regs, starting at REGNO, as holding parameters
for the next CALL_INSN. */
-extern void use_regs PARAMS ((rtx *, int, int));
+extern void use_regs (rtx *, int, int);
/* Mark a PARALLEL as holding a parameter for the next CALL_INSN. */
-extern void use_group_regs PARAMS ((rtx *, rtx));
+extern void use_group_regs (rtx *, rtx);
/* Write zeros through the storage of OBJECT.
If OBJECT has BLKmode, SIZE is its length in bytes. */
-extern rtx clear_storage PARAMS ((rtx, rtx));
+extern rtx clear_storage (rtx, rtx);
+
+/* Determine whether the LEN bytes can be moved by using several move
+ instructions. Return nonzero if a call to move_by_pieces should
+ succeed. */
+extern int can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int);
/* Return nonzero if it is desirable to store LEN bytes generated by
CONSTFUN with several move instructions by store_by_pieces
function. CONSTFUNDATA is a pointer which will be passed as argument
in every CONSTFUN call.
ALIGN is maximum alignment we can assume. */
-extern int can_store_by_pieces PARAMS ((unsigned HOST_WIDE_INT,
- rtx (*) (PTR, HOST_WIDE_INT,
- enum machine_mode),
- PTR, unsigned int));
+extern int can_store_by_pieces (unsigned HOST_WIDE_INT,
+ rtx (*) (void *, HOST_WIDE_INT,
+ enum machine_mode),
+ void *, unsigned int);
/* Generate several move instructions to store LEN bytes generated by
CONSTFUN to block TO. (A MEM rtx with BLKmode). CONSTFUNDATA is a
pointer which will be passed as argument in every CONSTFUN call.
- ALIGN is maximum alignment we can assume. */
-extern void store_by_pieces PARAMS ((rtx, unsigned HOST_WIDE_INT,
- rtx (*) (PTR, HOST_WIDE_INT,
- enum machine_mode),
- PTR, unsigned int));
+ ALIGN is maximum alignment we can assume.
+ Returns TO + LEN. */
+extern rtx store_by_pieces (rtx, unsigned HOST_WIDE_INT,
+ rtx (*) (void *, HOST_WIDE_INT, enum machine_mode),
+ void *, unsigned int, int);
/* Emit insns to set X from Y. */
-extern rtx emit_move_insn PARAMS ((rtx, rtx));
+extern rtx emit_move_insn (rtx, rtx);
/* Emit insns to set X from Y, with no frills. */
-extern rtx emit_move_insn_1 PARAMS ((rtx, rtx));
+extern rtx emit_move_insn_1 (rtx, rtx);
/* Push a block of length SIZE (perhaps variable)
and return an rtx to address the beginning of the block. */
-extern rtx push_block PARAMS ((rtx, int, int));
+extern rtx push_block (rtx, int, int);
-#ifdef TREE_CODE
/* Generate code to push something onto the stack, given its mode and type. */
-extern void emit_push_insn PARAMS ((rtx, enum machine_mode, tree, rtx,
- unsigned int, int, rtx, int, rtx, rtx,
- int, rtx));
+extern void emit_push_insn (rtx, enum machine_mode, tree, rtx, unsigned int,
+ int, rtx, int, rtx, rtx, int, rtx);
/* Expand an assignment that stores the value of FROM into TO. */
-extern rtx expand_assignment PARAMS ((tree, tree, int, int));
+extern rtx expand_assignment (tree, tree, int);
/* Generate code for computing expression EXP,
and storing the value into TARGET.
If SUGGEST_REG is nonzero, copy the value through a register
and return that register, if that is possible. */
-extern rtx store_expr PARAMS ((tree, rtx, int));
-#endif
+extern rtx store_expr (tree, rtx, int);
/* Given an rtx that may include add and multiply operations,
generate them as insns and return a pseudo-reg containing the value.
Useful after calling expand_expr with 1 as sum_ok. */
-extern rtx force_operand PARAMS ((rtx, rtx));
+extern rtx force_operand (rtx, rtx);
/* Return an object on the placeholder list that matches EXP, a
PLACEHOLDER_EXPR. An object "matches" if it is of the type of the
@@ -509,134 +512,136 @@ extern rtx force_operand PARAMS ((rtx, rtx));
a location which initially points to a starting location in the
placeholder list (zero means start of the list) and where a pointer into
the placeholder list at which the object is found is placed. */
-extern tree find_placeholder PARAMS ((tree, tree *));
+extern tree find_placeholder (tree, tree *);
/* Generate code for computing expression EXP.
An rtx for the computed value is returned. The value is never null.
In the case of a void EXP, const0_rtx is returned. */
-extern rtx expand_expr PARAMS ((tree, rtx, enum machine_mode,
- enum expand_modifier));
+#define expand_expr(EXP, TARGET, MODE, MODIFIER) \
+ expand_expr_real((EXP), (TARGET), (MODE), (MODIFIER), NULL)
+extern rtx expand_expr_real (tree, rtx, enum machine_mode,
+ enum expand_modifier, rtx *);
/* At the start of a function, record that we have no previously-pushed
arguments waiting to be popped. */
-extern void init_pending_stack_adjust PARAMS ((void));
+extern void init_pending_stack_adjust (void);
/* When exiting from function, if safe, clear out any pending stack adjust
so the adjustment won't get done. */
-extern void clear_pending_stack_adjust PARAMS ((void));
+extern void clear_pending_stack_adjust (void);
/* Pop any previously-pushed arguments that have not been popped yet. */
-extern void do_pending_stack_adjust PARAMS ((void));
+extern void do_pending_stack_adjust (void);
-#ifdef TREE_CODE
/* Return the tree node and offset if a given argument corresponds to
a string constant. */
-extern tree string_constant PARAMS ((tree, tree *));
+extern tree string_constant (tree, tree *);
/* Generate code to evaluate EXP and jump to LABEL if the value is zero. */
-extern void jumpifnot PARAMS ((tree, rtx));
+extern void jumpifnot (tree, rtx);
/* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */
-extern void jumpif PARAMS ((tree, rtx));
+extern void jumpif (tree, rtx);
/* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if
the result is zero, or IF_TRUE_LABEL if the result is one. */
-extern void do_jump PARAMS ((tree, rtx, rtx));
-#endif
+extern void do_jump (tree, rtx, rtx);
/* Generate rtl to compare two rtx's, will call emit_cmp_insn. */
-extern rtx compare_from_rtx PARAMS ((rtx, rtx, enum rtx_code, int,
- enum machine_mode, rtx));
-extern void do_compare_rtx_and_jump PARAMS ((rtx, rtx, enum rtx_code, int,
- enum machine_mode, rtx,
- rtx, rtx));
+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);
/* Two different ways of generating switch statements. */
-extern int try_casesi PARAMS ((tree, tree, tree, tree, rtx, rtx));
-extern int try_tablejump PARAMS ((tree, tree, tree, tree, rtx, rtx));
+extern int try_casesi (tree, tree, tree, tree, rtx, rtx);
+extern int try_tablejump (tree, tree, tree, tree, rtx, rtx);
/* Smallest number of adjacent cases before we use a jump table.
XXX Should be a target hook. */
-extern unsigned int case_values_threshold PARAMS ((void));
+extern unsigned int case_values_threshold (void);
-#ifdef TREE_CODE
/* rtl.h and tree.h were included. */
/* Return an rtx for the size in bytes of the value of an expr. */
-extern rtx expr_size PARAMS ((tree));
+extern rtx expr_size (tree);
/* Return a wide integer for the size in bytes of the value of EXP, or -1
if the size can vary or is larger than an integer. */
-extern HOST_WIDE_INT int_expr_size PARAMS ((tree));
+extern HOST_WIDE_INT int_expr_size (tree);
-extern rtx lookup_static_chain PARAMS ((tree));
+extern rtx lookup_static_chain (tree);
/* Convert a stack slot address ADDR valid in function FNDECL
into an address valid in this function (using a static chain). */
-extern rtx fix_lexical_addr PARAMS ((rtx, tree));
+extern rtx fix_lexical_addr (rtx, tree);
/* Return the address of the trampoline for entering nested fn FUNCTION. */
-extern rtx trampoline_address PARAMS ((tree));
+extern rtx trampoline_address (tree);
/* Return an rtx that refers to the value returned by a function
in its original home. This becomes invalid if any more code is emitted. */
-extern rtx hard_function_value PARAMS ((tree, tree, int));
+extern rtx hard_function_value (tree, tree, int);
-extern rtx prepare_call_address PARAMS ((rtx, tree, rtx *, int, int));
+extern rtx prepare_call_address (rtx, tree, rtx *, int, int);
-extern rtx expand_call PARAMS ((tree, rtx, int));
+extern rtx expand_call (tree, rtx, int);
-extern rtx expand_shift PARAMS ((enum tree_code, enum machine_mode, rtx, tree,
- rtx, int));
-extern rtx expand_divmod PARAMS ((int, enum tree_code, enum machine_mode, rtx,
- rtx, rtx, int));
-extern void locate_and_pad_parm PARAMS ((enum machine_mode, tree, int, tree,
- struct args_size *,
- struct args_size *,
- struct args_size *,
- struct args_size *));
-extern rtx expand_inline_function PARAMS ((tree, tree, rtx, int, tree, rtx));
+#ifdef TREE_CODE
+extern rtx expand_shift (enum tree_code, enum machine_mode, rtx, tree, rtx,
+ int);
+extern rtx expand_divmod (int, enum tree_code, enum machine_mode, rtx, rtx,
+ rtx, int);
+#endif
+
+extern void locate_and_pad_parm (enum machine_mode, tree, int, int, tree,
+ struct args_size *,
+ struct locate_and_pad_arg_data *);
+extern rtx expand_inline_function (tree, tree, rtx, int, tree, rtx);
/* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary. */
-extern rtx label_rtx PARAMS ((tree));
-#endif
+extern rtx label_rtx (tree);
+
+/* As label_rtx, but additionally the label is placed on the forced label
+ list of its containing function (i.e. it is treated as reachable even
+ if how is not obvious). */
+extern rtx force_label_rtx (tree);
/* Indicate how an input argument register was promoted. */
-extern rtx promoted_input_arg PARAMS ((unsigned int, enum machine_mode *,
- int *));
+extern rtx promoted_input_arg (unsigned int, enum machine_mode *, int *);
/* Return an rtx like arg but sans any constant terms.
Returns the original rtx if it has no constant terms.
The constant terms are added and stored via a second arg. */
-extern rtx eliminate_constant_term PARAMS ((rtx, rtx *));
+extern rtx eliminate_constant_term (rtx, rtx *);
/* Convert arg to a valid memory address for specified machine mode,
by emitting insns to perform arithmetic if nec. */
-extern rtx memory_address PARAMS ((enum machine_mode, rtx));
+extern rtx memory_address (enum machine_mode, rtx);
/* Like `memory_address' but pretent `flag_force_addr' is 0. */
-extern rtx memory_address_noforce PARAMS ((enum machine_mode, rtx));
+extern rtx memory_address_noforce (enum machine_mode, rtx);
/* Set the alias set of MEM to SET. */
-extern void set_mem_alias_set PARAMS ((rtx, HOST_WIDE_INT));
+extern void set_mem_alias_set (rtx, HOST_WIDE_INT);
/* Set the alignment of MEM to ALIGN bits. */
-extern void set_mem_align PARAMS ((rtx, unsigned int));
+extern void set_mem_align (rtx, unsigned int);
/* Set the expr for MEM to EXPR. */
-extern void set_mem_expr PARAMS ((rtx, tree));
+extern void set_mem_expr (rtx, tree);
/* Set the offset for MEM to OFFSET. */
-extern void set_mem_offset PARAMS ((rtx, rtx));
+extern void set_mem_offset (rtx, rtx);
/* Set the size for MEM to SIZE. */
-extern void set_mem_size PARAMS ((rtx, rtx));
+extern void set_mem_size (rtx, rtx);
/* Return a memory reference like MEMREF, but with its mode changed
to MODE and its address changed to ADDR.
(VOIDmode means don't change the mode.
NULL for ADDR means don't change the address.) */
-extern rtx change_address PARAMS ((rtx, enum machine_mode, rtx));
+extern rtx change_address (rtx, enum machine_mode, rtx);
/* Return a memory reference like MEMREF, but with its mode changed
to MODE and its address offset by OFFSET bytes. */
@@ -657,120 +662,113 @@ extern rtx change_address PARAMS ((rtx, enum machine_mode, rtx));
#define adjust_automodify_address_nv(MEMREF, MODE, ADDR, OFFSET) \
adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 0)
-extern rtx adjust_address_1 PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT,
- int, int));
-extern rtx adjust_automodify_address_1 PARAMS ((rtx, enum machine_mode,
- rtx, HOST_WIDE_INT, int));
+extern rtx adjust_address_1 (rtx, enum machine_mode, HOST_WIDE_INT, int, int);
+extern rtx adjust_automodify_address_1 (rtx, enum machine_mode, rtx,
+ HOST_WIDE_INT, int);
/* Return a memory reference like MEMREF, but whose address is changed by
adding OFFSET, an RTX, to it. POW2 is the highest power of two factor
known to be in OFFSET (possibly 1). */
-extern rtx offset_address PARAMS ((rtx, rtx, HOST_WIDE_INT));
+extern rtx offset_address (rtx, rtx, unsigned HOST_WIDE_INT);
/* Return a memory reference like MEMREF, but with its address changed to
ADDR. The caller is asserting that the actual piece of memory pointed
to is the same, just the form of the address is being changed, such as
by putting something into a register. */
-extern rtx replace_equiv_address PARAMS ((rtx, rtx));
+extern rtx replace_equiv_address (rtx, rtx);
/* Likewise, but the reference is not required to be valid. */
-extern rtx replace_equiv_address_nv PARAMS ((rtx, rtx));
+extern rtx replace_equiv_address_nv (rtx, rtx);
/* Return a memory reference like MEMREF, but with its mode widened to
MODE and adjusted by OFFSET. */
-extern rtx widen_memory_access PARAMS ((rtx, enum machine_mode, HOST_WIDE_INT));
+extern rtx widen_memory_access (rtx, enum machine_mode, HOST_WIDE_INT);
/* Return a memory reference like MEMREF, but which is known to have a
valid address. */
-extern rtx validize_mem PARAMS ((rtx));
+extern rtx validize_mem (rtx);
-#ifdef TREE_CODE
/* Given REF, either a MEM or a REG, and T, either the type of X or
the expression corresponding to REF, set RTX_UNCHANGING_P if
appropriate. */
-extern void maybe_set_unchanging PARAMS ((rtx, tree));
+extern void maybe_set_unchanging (rtx, tree);
/* Given REF, a MEM, and T, either the type of X or the expression
corresponding to REF, set the memory attributes. OBJECTP is nonzero
if we are making a new object of this type. */
-extern void set_mem_attributes PARAMS ((rtx, tree, int));
+extern void set_mem_attributes (rtx, tree, int);
/* Similar, except that BITPOS has not yet been applied to REF, so if
we alter MEM_OFFSET according to T then we should subtract BITPOS
expecting that it'll be added back in later. */
-extern void set_mem_attributes_minus_bitpos PARAMS ((rtx, tree, int,
- HOST_WIDE_INT));
-#endif
+extern void set_mem_attributes_minus_bitpos (rtx, tree, int, HOST_WIDE_INT);
/* Assemble the static constant template for function entry trampolines. */
-extern rtx assemble_trampoline_template PARAMS ((void));
+extern rtx assemble_trampoline_template (void);
/* Given rtx, return new rtx whose address won't be affected by
any side effects. It has been copied to a new temporary reg. */
-extern rtx stabilize PARAMS ((rtx));
+extern rtx stabilize (rtx);
/* Given an rtx, copy all regs it refers to into new temps
and return a modified copy that refers to the new temps. */
-extern rtx copy_all_regs PARAMS ((rtx));
+extern rtx copy_all_regs (rtx);
/* Copy given rtx to a new temp reg and return that. */
-extern rtx copy_to_reg PARAMS ((rtx));
+extern rtx copy_to_reg (rtx);
/* Like copy_to_reg but always make the reg Pmode. */
-extern rtx copy_addr_to_reg PARAMS ((rtx));
+extern rtx copy_addr_to_reg (rtx);
/* Like copy_to_reg but always make the reg the specified mode MODE. */
-extern rtx copy_to_mode_reg PARAMS ((enum machine_mode, rtx));
+extern rtx copy_to_mode_reg (enum machine_mode, rtx);
/* Copy given rtx to given temp reg and return that. */
-extern rtx copy_to_suggested_reg PARAMS ((rtx, rtx, enum machine_mode));
+extern rtx copy_to_suggested_reg (rtx, rtx, enum machine_mode);
/* Copy a value to a register if it isn't already a register.
Args are mode (in case value is a constant) and the value. */
-extern rtx force_reg PARAMS ((enum machine_mode, rtx));
+extern rtx force_reg (enum machine_mode, rtx);
/* Return given rtx, copied into a new temp reg if it was in memory. */
-extern rtx force_not_mem PARAMS ((rtx));
+extern rtx force_not_mem (rtx);
-#ifdef TREE_CODE
/* Return mode and signedness to use when object is promoted. */
-extern enum machine_mode promote_mode PARAMS ((tree, enum machine_mode,
- int *, int));
-#endif
+extern enum machine_mode promote_mode (tree, enum machine_mode, int *, int);
/* Remove some bytes from the stack. An rtx says how many. */
-extern void adjust_stack PARAMS ((rtx));
+extern void adjust_stack (rtx);
/* Add some bytes to the stack. An rtx says how many. */
-extern void anti_adjust_stack PARAMS ((rtx));
+extern void anti_adjust_stack (rtx);
/* This enum is used for the following two functions. */
enum save_level {SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL};
/* Save the stack pointer at the specified level. */
-extern void emit_stack_save PARAMS ((enum save_level, rtx *, rtx));
+extern void emit_stack_save (enum save_level, rtx *, rtx);
/* Restore the stack pointer from a save area of the specified level. */
-extern void emit_stack_restore PARAMS ((enum save_level, rtx, rtx));
+extern void emit_stack_restore (enum save_level, rtx, rtx);
/* Allocate some space on the stack dynamically and return its address. An rtx
says how many bytes. */
-extern rtx allocate_dynamic_stack_space PARAMS ((rtx, rtx, int));
+extern rtx allocate_dynamic_stack_space (rtx, rtx, int);
/* Probe a range of stack addresses from FIRST to FIRST+SIZE, inclusive.
FIRST is a constant and size is a Pmode RTX. These are offsets from the
current stack pointer. STACK_GROWS_DOWNWARD says whether to add or
subtract from the stack. If SIZE is constant, this is done
with a fixed number of probes. Otherwise, we must make a loop. */
-extern void probe_stack_range PARAMS ((HOST_WIDE_INT, rtx));
+extern void probe_stack_range (HOST_WIDE_INT, rtx);
/* Return an rtx that refers to the value returned by a library call
in its original home. This becomes invalid if any more code is emitted. */
-extern rtx hard_libcall_value PARAMS ((enum machine_mode));
+extern rtx hard_libcall_value (enum machine_mode);
/* Given an rtx, return an rtx for a value rounded up to a multiple
of STACK_BOUNDARY / BITS_PER_UNIT. */
-extern rtx round_push PARAMS ((rtx));
+extern rtx round_push (rtx);
/* Return the mode desired by operand N of a particular bitfield
insert/extract insn, or MAX_MACHINE_MODE if no such insn is
@@ -778,47 +776,37 @@ extern rtx round_push PARAMS ((rtx));
enum extraction_pattern { EP_insv, EP_extv, EP_extzv };
extern enum machine_mode
-mode_for_extraction PARAMS ((enum extraction_pattern, int));
-
-extern rtx store_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT,
- enum machine_mode, rtx, HOST_WIDE_INT));
-extern rtx extract_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, int, rtx,
- enum machine_mode, enum machine_mode,
- HOST_WIDE_INT));
-extern rtx expand_mult PARAMS ((enum machine_mode, rtx, rtx, rtx, int));
-extern bool const_mult_add_overflow_p PARAMS ((rtx, rtx, rtx, enum machine_mode, int));
-extern rtx expand_mult_add PARAMS ((rtx, rtx, rtx, rtx,enum machine_mode, int));
-extern rtx expand_mult_highpart_adjust PARAMS ((enum machine_mode, rtx, rtx, rtx, rtx, int));
-
-extern rtx assemble_static_space PARAMS ((int));
-
-/* Hook called by expand_expr for language-specific tree codes.
- It is up to the language front end to install a hook
- if it has any such codes that expand_expr needs to know about. */
-extern rtx (*lang_expand_expr) PARAMS ((union tree_node *, rtx,
- enum machine_mode,
- enum expand_modifier modifier));
-
-extern int safe_from_p PARAMS ((rtx, tree, int));
+mode_for_extraction (enum extraction_pattern, int);
+
+extern rtx store_bit_field (rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, enum machine_mode, rtx,
+ HOST_WIDE_INT);
+extern rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, int, rtx,
+ enum machine_mode, enum machine_mode,
+ HOST_WIDE_INT);
+extern rtx expand_mult (enum machine_mode, rtx, rtx, rtx, int);
+extern bool const_mult_add_overflow_p (rtx, rtx, rtx, enum machine_mode, int);
+extern rtx expand_mult_add (rtx, rtx, rtx, rtx,enum machine_mode, int);
+extern rtx expand_mult_highpart_adjust (enum machine_mode, rtx, rtx, rtx, rtx, int);
+
+extern rtx assemble_static_space (unsigned HOST_WIDE_INT);
+extern int safe_from_p (rtx, tree, int);
/* Call this once to initialize the contents of the optabs
appropriately for the current target machine. */
-extern void init_optabs PARAMS ((void));
-extern void init_all_optabs PARAMS ((void));
+extern void init_optabs (void);
+extern void init_all_optabs (void);
/* Call this to initialize an optab function entry. */
-extern rtx init_one_libfunc PARAMS ((const char *));
+extern rtx init_one_libfunc (const char *);
-extern void do_jump_by_parts_equality_rtx PARAMS ((rtx, rtx, rtx));
-extern void do_jump_by_parts_greater_rtx PARAMS ((enum machine_mode,
- int, rtx, rtx, rtx,
- rtx));
+extern void do_jump_by_parts_equality_rtx (rtx, rtx, rtx);
+extern void do_jump_by_parts_greater_rtx (enum machine_mode, int, rtx, rtx,
+ rtx, rtx);
-#ifdef TREE_CODE /* Don't lose if tree.h not included. */
-extern void mark_seen_cases PARAMS ((tree, unsigned char *,
- HOST_WIDE_INT, int));
-#endif
+extern void mark_seen_cases (tree, unsigned char *, HOST_WIDE_INT, int);
+
+extern int vector_mode_valid_p (enum machine_mode);
-extern int vector_mode_valid_p PARAMS ((enum machine_mode));
+extern tree placeholder_list;
diff --git a/contrib/gcc/f/ChangeLog b/contrib/gcc/f/ChangeLog
index d88c6537208a..d671c1ed952c 100644
--- a/contrib/gcc/f/ChangeLog
+++ b/contrib/gcc/f/ChangeLog
@@ -1,14 +1,295 @@
-2003-10-16 Release Manager
+2004-07-12 Bud Davis <bdavis9659@comcast.net>
- * GCC 3.3.2 Released.
+ * bld.c (ffebld_constant_new_character1, ffebld_constant_new_complex{1,2},
+ ffebld_constant_new_hollerith, ffebld_constant_new_integer1,
+ ffebld_constant_new_integer{1,2,3,4}_val, ffebld_constant_new_logical1,
+ ffebld_constant_new_logical{1,2,3,4}_val, ffebld_constant_new_real{1,2},
+ ffebld_constant_new_typeless_ov):
+ Fill and use `rlink' and `llink' pointers in _ffebld_ struct.
+ * bld.h (struct _ffebld_): remove 'next' pointer, add
+ `rlink, llink' pointers; remove `negate' entry.
+ * malloc.c (malloc_kill_area_): Adapt for new `mallocArea' pointer.
+ (malloc_display_): Adapt.
+ (malloc_new_inpool_): Set it.
+ (malloc_resize_inpool_): Ditto.
-2003-08-04 Release Manager
+2004-07-01 Release Manager
- * GCC 3.3.1 Released.
+ * GCC 3.4.1 released.
-2003-08-04 Release Manager
+2004-06-17 Toon Moene <toon@moene.indiv.nluug.nl>
- * GCC 3.3.1 Released.
+ * news.texi: Note that GCC 3.4.x is the last version
+ of GCC to contain g77.
+
+2004-05-18 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * bugs.texi, news.texi: Don't reference mainline versions.
+
+2004-05-16 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * g77.texi (Floating-point Errors): Fix typo.
+
+2004-05-07 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * g77.texi (Floating-point Errors): Avoid referencing
+ http://www.linuxsupportline.com/~billm/ which as has been hijacked;
+ add a reference to the official IEEE 754 site.
+
+2004-04-18 Release Manager
+
+ * GCC 3.4.0 released.
+
+2004-03-21 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * g77.texi: Update link to "G++ and GCC".
+
+2004-03-14 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * g77.texi (Aligned Data): Remove obsolete paragraph including a
+ broken link.
+ (Floating-point Errors): Remove links to http://www.validgh.com/
+ which was "hijacked".
+ (Language): Fix link to Fortran books.
+ (Projects): Remove obsolete paragraph including a broken link to
+ ftp://alpha.gnu.org/gnu/g77/projects/.
+ (Trouble): Remove obsolete paragraph including a broken link to
+ ftp://alpha.gnu.org/g77.plan.
+
+ * invoke.texi (Overall Options): Remove broken reference to
+ rat7.uue (which was of dubious copyright status anyways).
+
+ * root.texi (www-burley): Fix URL.
+
+2004-03-06 Roger Sayle <roger@eyesopen.com>
+
+ * parse.c (ffe_parse_file): Handle the case that main_input_filename
+ is NULL.
+
+2004-02-24 Michael Matz <matz@suse.de>
+
+ * Make-lang.in (sta.o-warn): Delete.
+ * sta.c (ffesta_save_): Don't break aliasing rules.
+
+2004-02-20 Kazu Hirata <kazu@cs.umass.edu>
+
+ * Make-lang.in (g77spec.o): Depend on intl.h.
+ * g77spec.c: Include intl.h.
+ (lang_specific_driver): Allow translation of the copyright
+ symbol but not the rest of the copyright message. Allow
+ translation of the message about warranty.
+
+2004-02-15 Roger Sayle <roger@eyesopen.com>
+
+ PR fortran/14129
+ * lex.c (ffelex_cfelex_): Avoid calling xrealloc on a local stack
+ allocated array.
+
+2004-01-30 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in (doc/g77.dvi): Use $(abs_docdir).
+
+2004-01-20 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in: Replace $(docdir) with doc.
+ (TEXI_G77_FILES): Define.
+ (f77.rebuilt): Delete.
+ (f77.srcextra): Add dependencies on f/BUGS and f/NEWS.
+ (f77.srcman, f77.srcinfo, f77.man, f77.info): New rules.
+ (doc/g77.info, doc/g77.dvi): Depend on TEXI_G77_FILES. Always build in
+ doc directory. Use $(MAKEINFOFLAGS).
+ (info, dvi, generated_manpages): Update to look in doc directory.
+ (f/BUGS, f/NEWS): Generate in build directory.
+ (f77.mostlyclean): Delete BUGS and NEWS from build directory.
+ (f77.maintainer-clean): Adjust to delete from source directory.
+ (f77.install-man): Revamp rule.
+
+2004-01-19 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in (G77_INSTALL_NAME): Define via a immediate $(shell)
+ instead of deferred backquote.
+
+2004-01-15 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in (f77.srcextra): Dummy entry.
+
+2004-01-13 Ian Lance Taylor <ian@wasabisystems.com>
+
+ PR fortran/6491
+ * expr.c (ffeexpr_reduce_): When handling AND, OR, and XOR, and
+ when using -fugly-logint, if both operands are logical, convert
+ the result back to logical.
+ (ffeexpr_reduced_ugly2log_): Add bothlogical parameter. Change
+ all callers. Convert logical operands to integer.
+
+2004-01-12 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * README: Remove.
+
+2004-01-07 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * com.h (ffecom_gfrt_basictype): Correct return type.
+
+2003-12-29 Roger Sayle <roger@eyesopen.com>
+
+ PR fortran/12632
+ * com.c (ffecom_subscript_check_): Take as an extra argument the
+ (possibly NULL) decl of the array. Don't create unnecessary tree
+ nodes if the array index is known to be safe at compile-time.
+ If the array index is unsafe, force the array decl into memory to
+ avoid RTL expansion problems.
+ (ffecom_array_ref_): Update calls to ffecom_subscript_check_.
+ (ffecom_char_args_x_): Likewise.
+
+2003-12-06 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in (G77_CROSS_NAME): Delete.
+ (g77.install_common, g77.install-man, g77.uninstall): Adjust for above.
+
+2003-11-30 Andreas Jaeger <aj@suse.de>
+
+ * Make-lang.in (f77.rebuilt): Fix dependency on g77.info.
+
+2003-11-24 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ PR fortran/12633
+ * expr.c (ffeexpr_reduced_ugly2log_): Revert
+ change allowing logical .and. logical to be
+ integer in expressions when -fugly-logint.
+
+2003-11-21 Kelley Cook <kcook@gcc.gnu.org>
+
+ * .cvsignore: Delete.
+
+2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Make-lang.in (f77.extraclean): Delete.
+
+2003-11-20 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * Make-lang.in (check-f77, lang_checks): Add.
+
+2003-11-16 Jason Merrill <jason@redhat.com>
+
+ * Make-lang.in (f77.tags): Create TAGS.sub files in each directory
+ and TAGS files that include them for each front end.
+
+2003-11-12 Andreas Jaeger <aj@suse.de>
+
+ * intdoc.in (Signal Intrinsic (subroutine)): Fix texinfo warning
+ using @code.
+ * intdoc.texi: Regenerated.
+
+2003-11-03 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in (dvi): Move targets to $(docobjdir).
+ (g77.dvi): Simplify rule.
+ (g77.info): Sinplify rule.
+ (g77.1): Delete.
+ (g77.pod): New intermediate rule.
+
+2003-10-31 Jakub Jelinek <jakub@redhat.com>
+
+ * com.c (ffecom_sym_transform_): Set tree type of offset
+ to ssizetype.
+
+2003-10-21 Kelley Cook <kcook@gcc.gnu.org>
+
+ * Make-lang.in (f/g77.1): Honor $(docobjdir).
+ ($(docobjdir)/g77.info): Replace $(srcdir)/doc with $(docdir).
+ (f/g77.dvi): Likewise.
+
+2003-10-21 Jan Hubicka <jh@suse.cz>
+
+ * lex.c (ffelex_cfelex_): Initialize d.
+
+Mon Oct 20 23:15:46 2003 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in ($(docobjdir)/g77.info): Add dependency on
+ stmp-docobjdir.
+
+Mon Oct 20 13:49:43 2003 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (.PHONY): Remove f77.info, f77.install-info.
+ (info): Update dependencies.
+ ($(srcdir)/f/g77.info): Replace with ...
+ ($(docobjdir)/g77.info): ... this.
+ (f77.install-info): Remove.
+ (install-info): New target.
+
+2003-10-06 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (f77.info): Replace with ...
+ (info): ... this.
+ (f77.dvi): Replace with ...
+ (dvi): ... this.
+ (f77.generated-manpages): Replace with ...
+ (generated-manpages): ... this.
+
+2003-09-29 Zack Weinberg <zack@codesourcery.com>
+
+ * target.c (FFETARGET_ATOF_): Delete.
+ (ffetarget_real1, ffetarget_real2): Use real_from_string directly.
+ * target.h (FFETARGET_REAL_VALUE_FROM_INT_,
+ FFETARGET_REAL_VALUE_FROM_LONGLONG_): Use mode_for_size,
+ don't refer to SFmode or DFmode directly.
+
+2003-09-28 Richard Henderson <rth@redhat.com>
+
+ * com.c (duplicate_decls): Copy DECL_SOURCE_LOCATION, not
+ file and line separately.
+
+2003-09-21 Richard Henderson <rth@redhat.com>
+
+ * com.c, ste.c: Revert.
+
+2003-09-21 Richard Henderson <rth@redhat.com>
+
+ * com.c, ste.c: Update for DECL_SOURCE_LOCATION rename and
+ change to const.
+
+2003-09-21 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * news.texi: Update with fixed PR's.
+
+2003-09-21 George Helffrich <bugzilla@w170.uklinux.net>
+
+ * g77.texi: Remove ancient part about debugging COMMON
+ and EQUIVALENCE not correctly.
+
+2003-09-18 Roger Sayle <roger@eyesopen.com>
+
+ * com.c (ffecom_overlap_): Remove FFS_EXPR case.
+ (ffecom_tree_canonize_ref_): Likewise.
+ (ffe_truthvalue_conversion): Likewise.
+
+2003-09-01 Josef Zlomek <zlomekj@suse.cz>
+
+ * com.c (ffecom_overlap_): Kill BIT_ANDTC_EXPR.
+ (ffecom_tree_canonize_ref_): Kill BIT_ANDTC_EXPR.
+
+Thu Jul 31 01:47:27 2003 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (ffecom_init_0): Use `dconsthalf'.
+
+Sat Jul 19 12:03:03 2003 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c data.c expr.c fini.c g77spec.c global.c lab.c lex.c name.c
+ sta.c stc.c std.c storag.c stt.c stw.c symbol.c target.c type.c:
+ Remove unnecessary casts.
+
+Thu Jul 17 06:34:41 2003 Neil Booth <neil@daikokuya.co.uk>
+
+ * lang-options.h: Remove.
+ * lang.opt: Document most options.
+
+2003-07-14 Geoffrey Keating <geoffk@apple.com>
+
+ * lang-specs.h (f77-cpp-input): Use -o to specify the CPP output file.
+
+2003-07-10 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * ffe.texi: Correctly use @var{srcdir}.
2003-07-09 Toon Moene <toon@moene.indiv.nluug.nl>
@@ -16,9 +297,56 @@
* com.c (ffecom_sym_transform_): finish_decl should have
the same last argument as start_decl.
-Tue Jul 8 15:18:14 2003 Andreas Schwab <schwab@suse.de>
+2003-07-08 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * Make-lang.in (f/g77.dvi): Use PWD_COMMAND.
+
+2003-07-08 Zack Weinberg <zack@codesourcery.com>
+
+ * lex.c: Remove error block #ifdef MAP_CHARACTER.
- * Make-lang.in (f/g77.dvi): Replace PWD with PWD_COMMAND.
+Mon Jul 7 18:13:22 2003 Nathan Sidwell <nathan@codesourcery.com>
+
+ * com.c (bison_rule_pushlevel_, bison_rule_compstmt_): Adjust
+ emit_line_note calls.
+ * ste.c (ffeste_emit_line_note_): Likewise.
+
+2003-07-06 Andreas Jaeger <aj@suse.de>
+
+ * bad.c: Convert () to (void) in function definitions.
+ * bld.c: Likewise.
+ * data.c: Likewise.
+ * equiv.c: Likewise.
+ * expr.c: Likewise.
+ * global.c: Likewise.
+ * implic.c: Likewise.
+ * info.c: Likewise.
+ * intdoc.c: Likewise.
+ * intrin.c: Likewise.
+ * lab.c: Likewise.
+ * lex.c: Likewise.
+ * malloc.c: Likewise.
+ * src.c: Likewise.
+ * st.c: Likewise.
+ * sta.c: Likewise.
+ * stb.c: Likewise.
+ * stc.c: Likewise.
+ * std.c: Likewise.
+ * ste.c: Likewise.
+ * storag.c: Likewise.
+ * stt.c: Likewise.
+ * stw.c: Likewise.
+ * symbol.c: Likewise.
+ * top.c: Likewise.
+ * where.c: Likewise.
+
+ * com.c: Convert prototypes to ISO C90.
+ * com.h: Likewise.
+ * g77spec.c: Likewise.
+
+Sun Jul 6 20:01:29 2003 Neil Booth <neil@daikokuya.co.uk>
+
+ * top.c (ffe_handle_option): Don't handle filenames.
2003-07-05 Toon Moene <toon@moene.indiv.nluug.nl>
@@ -27,39 +355,344 @@ Tue Jul 8 15:18:14 2003 Andreas Schwab <schwab@suse.de>
FFEINFO_whereGLOBAL symbols in the global binding
level if not -fno-globals.
+Wed Jul 2 21:16:02 2003 Neil Booth <neil@daikokuya.co.uk>
+
+ * top.c (ffe_init_options): Update prototype.
+ * top.h (ffe_init_options): Update prototype.
+
+2003-06-27 Zack Weinberg <zack@codesourcery.com>
+
+ * com.c (input_file_stack_tick): Delete redundant declaration.
+
+Thu Jun 26 07:06:29 2003 Neil Booth <neil@daikokuya.co.uk>
+
+ * top.c (ffe_handle_option): Don't check for missing arguments.
+
+Wed Jun 25 06:52:12 2003 Neil Booth <neil@daikokuya.co.uk>
+
+ * top.c (ffe_handle_option): Add missing break;.
+
+2003-06-24 Scott Snyder <snyder@fnal.gov>
+
+ PR fortran/11299
+ * com.c (ffe_init): Call push_srcloc() to ensure that
+ input_file_stack is initialized.
+
+Sat Jun 21 21:29:38 2003 Neil Booth <neil@daikokuya.co.uk>
+
+ * lang.opt: Add -fpreprocessed.
+ * top.c (ffe_handle_option): Handle it.
+
+Fri Jun 20 10:00:31 2003 Nathan Sidwell <nathan@codesourcery.com>
+
+ * com.c (finish_function): Adjust expand_function_end call.
+
+2003-06-17 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Make-lang.in: Replace BUILD_CC references with CC_FOR_BUILD.
+
+Sun Jun 15 15:56:51 2003 Neil Booth <neil@daikokuya.co.uk>
+
+ * lang.opt: Declare F77.
+
+Sat Jun 14 18:13:00 2003 Nathan Sidwell <nathan@codesourcery.com>
+
+ * com.c (stor_parm_decls): Adjust init_function_start call.
+
+Sat Jun 14 13:25:00 2003 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Update to use options.c and options.h.
+ * top.c: Include options.h not f-options.h.
+ (ffe_init_options): From com.c. Request F77 options.
+ (ffe_handle_options): Abort on unrecognized switch.
+ * com.c (ffe_init_options): Move to top.c.
+ * top.h (fee_init_options): New.
+
2003-06-13 Richard Henderson <rth@redhat.com>
- PR debug/9864
- * com.c (ffecom_sym_transform_): Install FFEINFO_whereGLOBAL
- symbols in the global binding level.
+ PR debug/9864
+ * com.c (ffecom_sym_transform_): Install FFEINFO_whereGLOBAL
+ symbols in the global binding level.
+
+Sun Jun 8 15:42:09 2003 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in (F77_OBJS, f77.mostlyclean, f/com.o): Update.
+ (f/f-options.c, f/f-options.h): New.
+ * com.c: Include opts.h and f-options.h.
+ (ffecom_decode_include_option_): Remove.
+ (LANG_HOOKS_HANDLE_OPTION): New.
+ (LANG_HOOKS_DECODE_OPTION): Drop.
+ (struct file_name_list, ffecom_decode_include_option,
+ ffecom_open_include_): Constify.
+ * com.h (ffecom_decode_include_option): Update.
+ * lang.opt: New.
+ * top.c: Include f-options.h, opts.h.
+ (ffe_is_digit_string_): Constify.
+ (ffe_decode_option): Transform to ffe_handle_option.
+ * top.h (ffe_decode_option): Replace with ffe_handle_option.
+
+2003-06-08 Andreas Jaeger <aj@suse.de>
+
+ * std.c: Remove #if 0'ed functions.
+
+ * sta.c: Remove usage of HARD_F90, FFESTR_F90 and FFESTR_VXT.
+ * stb.c: Likewise.
+ * stb.h: Likewise.
+ * stc.c: Likewise.
+ * stc.h: Likewise.
+ * std.c: Likewise.
+ * std.h: Likewise.
+ * ste.c: Likewise.
+ * ste.h: Likewise.
+
+ * str.h (FFESTR_F90): Remove macro.
+ (FFESTR_VXT): Remove macro.
+
+ * bld.c: Remove usage of FFETARGET_okCHARACTER2,
+ FFETARGET_okCHARACTER3, FFETARGET_okCHARACTER4,
+ FFETARGET_okCHARACTER5, FFETARGET_okCHARACTER6,
+ FFETARGET_okCHARACTER7, FFETARGET_okCHARACTER8,
+ FFETARGET_okCOMPLEX4, FFETARGET_okCOMPLEX5, FFETARGET_okCOMPLEX6,
+ FFETARGET_okCOMPLEX7, FFETARGET_okCOMPLEX8, FFETARGET_okINTEGER5,
+ FFETARGET_okINTEGER6, FFETARGET_okINTEGER7, FFETARGET_okINTEGER8,
+ FFETARGET_okLOGICAL5, FFETARGET_okLOGICAL6, FFETARGET_okLOGICAL7,
+ FFETARGET_okLOGICAL8, FFETARGET_okREAL4, FFETARGET_okREAL5,
+ FFETARGET_okREAL6, FFETARGET_okREAL7 and FFETARGET_okREAL8.
+ * bld.h: Likewise.
+ * expr.c: Likewise.
+ * target.h: Likewise.
+ * com.c: Likewise.
+
+Sun Jun 8 12:28:14 2003 Neil Booth <neil@daikokuya.co.uk>
+
+ * Make-lang.in: Update.
+ * top.c: Include opts.h. Define cl_options_count and cl_options.
+
+2003-06-07 Andreas Jaeger <aj@suse.de>
+
+ * symbol.c (ffesymbol_new_): Remove tests for macro
+ FFECOM_symbolHOOK.
+ * symbol.h: Likewise.
+
+ * storag.c (ffestorag_new): Remove tests for macro
+ FFECOM_storageHOOK.
+ * storag.h: Likewise.
+
+ * lab.c (ffelab_new): Remove tests for macro FFECOM_labelHOOK.
+ * lab.h: Likewise.
+
+ * global.c: Remove tests for macro FFECOM_globalHOOK.
+ * global.h (struct _ffeglobal_): Likewise.
+
+ * bld.h: Remove tests for macros FFECOM_constantHOOK,
+ FFECOM_nonterHOOK, FFECOM_globalHOOK, FFECOM_labelHOOK,
+ FFECOM_storageHOOK, FFECOM_symbolHOOK.
+ Remove code dependend on FFECOM_itemHOOK.
+ * bld.c: Likewise.
+
+ * com.h (FFECOM_constantHOOK): Remove define.
+ (FFECOM_nonterHOOK): Remove.
+ (FFECOM_globalHOOK): Remove.
+ (FFECOM_labelHOOK): Remove.
+ (FFECOM_storageHOOK): Remove.
+ (FFECOM_symbolHOOK): Remove.
+
+ * com.c (ffecom_get_external_identifier_): Remove usage of
+ FFETARGET_isENFORCED_MAIN_NAME.
+
+ * bld.c: Remove code dependend on FFEBLD_BLANK_, FFECOM_itemHOOK.
+ (ffebld_new_accter): Likewise.
+ (ffebld_new_arrter): Likewise.
+ (ffebld_new_conter_with_orig): Likewise.
+ (ffebld_new_item): Likewise.
+ (ffebld_new_labter): Likewise.
+ (ffebld_new_labtok): Likewise.
+ (ffebld_new_none): Likewise.
+ (ffebld_new_one): Likewise.
+ (ffebld_new_symter): Likewise.
+ (ffebld_new_two): Likewise.
+
+Sat Jun 7 12:10:41 2003 Neil Booth <neil@daikokuya.co.uk>
+
+ * com.c (ffe_init_options): Update.
+
+Thu Jun 5 18:33:40 CEST 2003 Jan Hubicka <jh@suse.cz>
+
+ * Make-lang.in: Add support for stageprofile and stagefeedback
+
+2003-06-04 Andreas Jaeger <aj@suse.de>
+
+ * g77spec.c (lang_specific_driver): Remove ALT_LIBM usage.
+
+2003-06-01 Bud Davis <bdavis9659@comcast.net>
+
+ * ste.c (ffeste_R838): Handle ERROR_MARK.
+ (ffeste_R839): Ditto.
+
+2003-06-01 Andreas Jaeger <aj@suse.de>
+
+ * lex.c (ffelex_file_fixed): Remove usage of
+ REDUCE_CARD_SIZE_AFTER_BIGGY.
+
+ * expr.c (ffeexpr_exprstack_push_operand_): Remove code depenend
+ on WEIRD_NONFORTRAN_RULES.
+
+ * com.c (ffecom_arg_ptr_to_expr): Remove
+ PASS_HOLLERITH_BY_DESCRIPTOR dependend code.
+ (ffecom_const_expr): Remove usage of NEWCOMMON.
+ (ffecom_expand_let_stmt): Remove MOVE_EXPR.
+
+2003-05-31 Bud Davis <bdavis9659@comcast.net>
+
+ PR fortran/10843
+ * sta.c (ffesta_second_): Parse GO TO correctly,
+ even in free source format.
+
+2003-05-31 Andreas Jaeger <aj@suse.de>
+
+ * lex.c (ffelex_hash_): Remove HANDLE_PRAGMA and
+ HANDLE_GENERIC_PRAGMA dependend code, remove #if 0 code.
+ (pragma_getc): Removed.
+ (pragma_ungetc): Removed.
+
+2003-05-30 Roger Sayle <roger@eyesopen.com>
+
+ * com.c (ffecom_init_0): Define built-in functions for tan and atan.
+ * com-rt.def: Use then to implement g77's tan and atan intrinsics.
+
+2003-05-22 Bud Davis <bdavis9659@comcast.net>
+
+ * com.c (ffecom_sym_transform_): Error out on unallocatable
+ storage after type is set.
2003-05-18 Toon Moene <toon@moene.indiv.nluug.nl>
- PR fortran/10726
* intdoc.in: Fix documentation of IDATE.
* intdoc.texi: Regenerate.
- * news.texi: Update due to the above.
+ * news.texi: Update due to also fixing it in 3.3.1.
2003-05-16 Wolfgang Bangerth <bangerth@dealii.org>
- * g77.texi: Remove most of the preface of the bugs section.
+ * g77.texi: Remove most of the of the preface of the
+ bugs section.
2003-05-15 Wolfgang Bangerth <bangerth@dealii.org>
* g77.texi: Remove most of the bug reporting instructions and
merge them into bugs.html.
-2003-05-13 Release Manager
+2003-05-13 Zack Weinberg <zack@codesourcery.com>
+
+ * com.c: Replace all calls to fatal_io_error with calls to
+ fatal_error; add ": %m" to the end of all the affected error
+ messages.
- * GCC 3.3 Released.
+2003-05-12 Zack Weinberg <zack@codesourcery.com>
-2003-05-13 Release Manager
+ * bad.c: Don't call diagnostic_count_diagnostic.
- * GCC 3.3 Released.
+2003-05-12 Roger Sayle <roger@eyesopen.com>
-2003-05-13 Release Manager
+ * com.c (ffecom_init_0): Define built-in functions for atan2,
+ exp, floor, fmod, log and pow.
+ (duplicate_decls): Preserve assembler name when redeclaring a
+ built-in.
+ * com-rt.def: Implement using the built-in forms of the above
+ functions rather than calling the standard C library directly.
+ Correct some of the run-time prototype "codes".
- * GCC 3.3 Released.
+2003-05-11 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ PR fortran/10726
+ * intdoc.in: Fix documentation of IDATE.
+ * intdoc.texi: Regenerate.
+ * g77.texi: Document completion of INTEGER*n support.
+ * news.texi: Update due to the above.
+
+2003-05-08 Roger Sayle <roger@eyesopen.com>
+
+ PR fortran/8485
+ * target.h (FFETARGET_REAL_VALUE_FROM_INT_): Cast to
+ HOST_WIDE_INT instead of long.
+ (FFETARGET_REAL_VALUE_FROM_LONGLONG_): New macro.
+ (FFETARGET_LONGLONG_FROM_INTS_): New macro.
+ (ffetarget_convert_complex1_integer4): Implement.
+ (ffetarget_convert_complex2_integer4): Implement.
+ (ffetarget_convert_integer4_complex1): Implement.
+ (ffetarget_convert_integer4_complex2): Implement.
+ (ffetarget_convert_integer4_real1): Implement.
+ (ffetarget_convert_integer4_real2): Implement.
+ (ffetarget_convert_real1_integer4): Implement.
+ (ffetarget_convert_real2_integer4): Implement.
+ * com.c (ffecom_constantunion): Handle INTEGER*8.
+ (ffecom_constantunion_with_type): Likewise.
+
+2003-05-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * com.c (ffecom_do_entry_): Use location_t and input_location
+ directly.
+ (ffecom_gen_sfuncdef_): Likewise.
+ (ffecom_start_progunit_): Likewise.
+ (ffecom_sym_transform_): Likewise.
+ (ffecom_sym_transform_assign_): Likewise.
+ * lex.c (ffelex_hash_): Likewise.
+ (ffelex_include_): Likewise.
+ * std.c (ffestd_exec_begin): Likewise.
+ (ffestd_exec_end): Likewise.
+ * ste.c (struct gbe_block): Likewise.
+ (ffeste_start_block_): Likewise.
+ (ffeste_start_stmt_): Likewise.
+
+2003-05-03 Nathan Sidwell <nathan@codesourcery.com>
+
+ * ansify.c (die_unless): Revert lineno change here.
+
+2003-05-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * lex.c (ffelex_file_pop_): Adjust file_stack member use.
+ (ffelex_file_push_): Likewise.
+ (ffelex_hash_): Likewise.
+
+2003-05-01 Nathan Sidwell <nathan@codesourcery.com>
+
+ * ansify.c (die_unless): Rename lineno to input_line.
+ * com.c (ffecom_subscript_check_, ffecom_do_entry_,
+ ffecom_gen_sfuncdef_, ffecom_start_progunit_,
+ ffecom_sym_transform_, ffecom_sym_transform_assign_,
+ bison_rule_pushlevel_, bison_rule_compstmt_, finish_function,
+ store_parm_decls): Likewise.
+ * intrin.c (ffeintrin_fulfill_generic): Likewise.
+ * lex.c (ffelex_hash_, ffelex_include_, ffelex_next_line_,
+ ffelex_file_fixed, ffelex_file_free): Likewise.
+ * std.c (ffestd_exec_end): Likewise.
+ * ste.c (ffeste_emit_line_note_, ffeste_start_block_,
+ ffeste_start_stmt_): Likewise.
+ * ste.h (ffeste_filelinenum, ffeste_set_line): Likewise.
+
+ * lex.c (ffelex_file_pop_): Rename parameter from input_filename.
+ (ffelex_file_push_): Likewise.
+
+ * ste.c (struct gbe_block): Rename field from input_filename.
+ (ffeste_start_block_, ffeste_start_stmt_): Likewise.
+
+2003-04-17 Roger Sayle <roger@eyesopen.com>
+
+ PR c/10375
+ * com.c (duplicate_decls): Preserve "const" and "noreturn"
+ function attributes.
+
+2003-04-13 Roger Sayle <roger@eyesopen.com>
+
+ * com.c (duplicate_decls): Preserve pure and malloc attributes.
+
+2003-04-12 Zack Weinberg <zack@codesourcery.com>
+
+ * com.c (ffecom_build_complex_constant_, ffecom_expr_)
+ (ffecom_init_zero_, ffecom_transform_namelist_, ffecom_vardesc_)
+ (ffecom_vardesc_array_, ffecom_vardesc_dims_, ffecom_2)
+ * ste.c (ffeste_io_ialist_, ffeste_io_cilist_, ffeste_io_cllist_)
+ (ffeste_io_icilist_, ffeste_io_inlist_, ffeste_io_olist_):
+ Use build_constructor.
2003-04-11 Bud Davis <bdavis9659@comcast.net>
@@ -68,6 +701,10 @@ Tue Jul 8 15:18:14 2003 Andreas Schwab <schwab@suse.de>
increment values for INTEGER typeness.
* gcc/f/news.texi: Document these fixes.
+2003-03-27 Steven Bosscher <steven@gcc.gnu.org>
+
+ * ffe.texi: Don't mention dead file proj.c.
+
2003-03-26 Roger Sayle <roger@eyesopen.com>
PR fortran/9793
@@ -99,12 +736,42 @@ Sun Mar 23 23:43:45 2003 Mark Mitchell <mark@codesourcery.com>
* ste.c (ffeste_R810): Use ffecom_constantunion_with_type
to discern SELECT CASE variables.
+2003-03-15 Roger Sayle <roger@eyesopen.com>
+
+ * stb.c (ffestb_R100110_): Allow the number before the X format
+ to be optional when not -fpedantic.
+ * std.c (ffestd_R1001dump_1010_3_): Delete unused static function.
+ (ffestd_R1001dump_): For the FFESTP_formattypeX case, call
+ ffestd_R1001dump_1010_2_ instead of ffestd_R1001dump_1010_3_.
+
+2003-03-15 Roger Sayle <roger@eyesopen.com>
+
+ * f/ste.c (ffeste_R810): Fix whitespace.
+
2003-03-15 Andreas Jaeger <aj@suse.de>
* g77spec.c (DEFAULT_SWITCH_TAKES_ARG): Remove.
(DEFAULT_WORD_SWITCH_TAKES_ARG): Remove.
-2003-02-21 Toon Moene <toon@moene.indiv.nluug.nl>
+2003-03-12 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * g77.texi, invoke.texi, g77spec.c, lang-specs.h: GCC, not
+ GNU CC. Especially here.
+
+2003-03-10 Roger Sayle <roger@eyesopen.com>
+
+ * com.c (duplicate_decls): Synchronize with C's duplicate_decls.
+
+Sat Mar 8 21:11:40 2003 Neil Booth <neil@daikokuya.co.uk>
+
+ * com.c (ffe_init): Update prototype; move code to ffe_post_options.
+ (ffe_post_options): New.
+
+2003-03-04 Tom Tromey <tromey@redhat.com>
+
+ * Make-lang.in (f77.tags): New target.
+
+2003-02-20 Toon Moene <toon@moene.indiv.nluug.nl>
* news.texi: Document fixing PR fortran/9038.
@@ -112,28 +779,61 @@ Sun Mar 23 23:43:45 2003 Mark Mitchell <mark@codesourcery.com>
* g77.texi, invoke.texi: Update to GFDL 1.2.
-2003-01-30 Toon Moene <toon@moene.indiv.nluug.nl>
+2003-01-31 Toon Moene <toon@moene.indiv.nluug.nl>
* news.texi: Document fixing PR fortran/7681
- and PR optimization/9258.
+ and optimization/9258.
2003-01-26 Toon Moene <toon@moene.indiv.nluug.nl>
- * lang-specs.h: Revert change to solve 9038.
+ * lang-specs.h: Revoke change to (incorrectly) prohibit
+ passing -f options to cc1 when preprocessing.
* news.texi: Document this.
-2003-01-26 Christian Cornelssen <ccorn@cs.tu-berlin.de>
+Tue Jan 21 08:42:12 2003 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ Make-lang.in (f/sta.o-warn): Add -Wno-error.
- * Make-lang.in (f77.install-common, f77.install-info)
- (f77.install-man, f77.uninstall): Prepend $(DESTDIR) to
+Thu Jan 16 10:53:16 2003 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (f/target.o): Depend on toplev.h.
+ * target.c: Include toplev.h.
+
+Sat Jan 11 21:31:10 2003 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (ffecom_convert_narrow_, ffecom_convert_widen_,
+ pushdecl_top_level, storedecls, convert, delete_block,
+ insert_block, ffe_init, ffe_mark_addressable, poplevel,
+ ffe_print_identifier, pushdecl, pushlevel, set_block,
+ ffe_signed_or_unsigned_type, ffe_signed_type,
+ ffe_truthvalue_conversion, ffe_type_for_mode, ffe_type_for_size,
+ ffe_unsigned_type, append_include_chain, open_include_file,
+ read_filename_string, read_name_map): Convert to ISO C style function
+ definitions.
+ * parse.c (ffe_parse_file): Likewise.
+ * top.c (ffe_is_digit_string_): Likewise.
+
+2003-01-09 Christian Cornelssen <ccorn@cs.tu-berlin.de>
+
+ * Make-lang.in (f77.install-common, f77.install-info,
+ f77.install-man, f77.uninstall): Prepend $(DESTDIR) to
destination paths in all (un)installation commands.
-2003-01-05 Steven Bosscher <s.bosscher@student.tudelft.nl>
+2003-01-05 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * news.texi: Revise history again:
+ PR Fortran/9038 will be fixed in 3.4.
+
+2003-01-05 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * news.texi: Update news to reflect reality:
+ PR Fortran/9038 won't be fixed until 3.4.
+
+2003-01-04 Toon Moene <toon@moene.indiv.nluug.nl>
PR Fortran/9038
- * lang-specs.h: Prevent -f<option> from being passed
- to cc1.
- * news.texi: Document this fix.
+ * lang-specs.h: Remove -f options before preprocessing.
+ * news.texi: Document fixing of PR Fortran/9038.
2003-01-03 Bud Davis <bdavis11@directvinternet.com>
@@ -171,15 +871,3260 @@ Sun Mar 23 23:43:45 2003 Mark Mitchell <mark@codesourcery.com>
* intdoc.texi: Likewise.
* news.texi: Follow spelling conventions.
-Mon Dec 16 13:55:24 2002 Mark Mitchell <mark@codesourcery.com>
+Mon Dec 16 13:53:18 2002 Mark Mitchell <mark@codesourcery.com>
+
+ * root.texi: Change version number to 3.4.
+
+2002-12-15 Zack Weinberg <zack@codesourcery.com>
+
+ * target.h: Don't define HOST_WIDE_INT.
- * root.texi (DEVELOPMENT): @clear it.
+2002-12-02 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Make-lang.in, ansify.c, intdoc.c, proj.h: Replace hconfig.h with
+ bconfig.h.
+ * fini.c, proj.h: Replace USE_HCONFIG with USE_BCONFIG
+
+2002-11-30 Zack Weinberg <zack@codesourcery.com>
+
+ * proj.h, ansify.c, g77spec.c, intdoc.c:
+ Include coretypes.h and tm.h.
+ * Make-lang.in: Update dependencies.
2002-11-20 Toon Moene <toon@moene.indiv.nluug.nl>
* invoke.texi: Explain the purpose of -fmove-all-movables,
-freduce-all-givs and -frerun-loop-opts better.
+2002-11-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Make-lang.in: Correct BUILD/HOST confusion.
+
+2002-11-19 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ PR fortran/8587
+ * news.texi: Show PR fortran/8587 fixed.
+
+2002-11-19 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * g77spec.c (lang_specific_spec_functions): New.
+
+2002-11-02 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * g77.texi: Correct documentation on generating C++ prototypes
+ of Fortran routines with f2c.
+ * news.texi: Document fixes in GCC-3.3, 3.2 and 3.1.
+
+2002-10-30 Roger Sayle <roger@eyesopen.com>
+
+ * com.c (ffecom_subscript_check_): Cast the failure branch
+ of the bounds check COND_EXPR to void, to indicate noreturn.
+ (ffe_truthvalue_conversion): Only apply truth value conversion
+ to the non-void branches of a COND_EXPR.
+
+2002-10-26 Andris Pavenis <pavenis@latnet.lv>
+
+ * lang-specs.h: Fix ratfor specs.
+
+2002-10-15 Richard Henderson <rth@redhat.com>
+
+ * target.h (ffetarget_print_real1, ffetarget_print_real2): Use
+ real_to_decimal directly, and with the new arguments.
+
+2002-09-23 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in (g77spec.o): Don't depend on f/version.h.
+ (f/parse.o): Depend on version.h not f/version.h.
+ (g77version.o, f/version.o): Delete all references.
+
+ * com.c (ffecom_init_0): Fix transposed array indices in bsearch test.
+ * g77spec.c: Don't include f/version.h or refer to ffe_version_string.
+ * parse.c: Use version_string, not ffe_version_string.
+ * version.c, version.h: Delete files.
+
+2002-09-23 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * ChangeLog.0: Likewise.
+ * com.c: Likewise.
+ * ffe.texi: Likewise.
+ * g77.texi: Likewise.
+ * intdoc.in: Likewise.
+ * invoke.texi: Likewise.
+ * news.texi: Likewise.
+ * intdoc.texi: Regenerate.
+
+2002-09-16 Geoffrey Keating <geoffk@apple.com>
+
+ * com.c (union lang_tree_node): Add chain_next option.
+
+2002-09-16 Richard Henderson <rth@redhat.com>
+
+ * target.c (ffetarget_real1): Don't pass FFETARGET_ATOF_
+ directly to ffetarget_make_real1.
+ (ffetarget_real2): Similarly.
+ * target.h (ffetarget_cvt_r1_to_rv_, ffetarget_cvt_rv_to_r2_,
+ ffetarget_cvt_r2_to_rv_): Use new real.h interface and simplify.
+
+2002-09-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * intdoc.texi: Regenerate.
+
+2002-09-15 Kazu Hirata <kazu@cs.umass.edu>
+
+ * ChangeLog: Follow spelling conventions.
+ * intdoc.in: Likewise.
+
+2002-09-09 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ Fix PR web/7596:
+ * ffe.texi (Front End): Fix broken links.
+ * bugs.texi (Known Bugs): Refer to gcc.gnu.org instead of
+ www.gnu.org for onlinedocs.
+ * news.texi (News): Ditto.
+
+2002-09-07 Jan Hubicka <jh@suse.cz>
+
+ * com.c (ffe_type_for_mode): Handle long double.
+
+2002-09-04 Richard Henderson <rth@redhat.com>
+
+ * target.h (ffetarget_print_real1, ffetarget_print_real2): Update
+ call to REAL_VALUE_TO_DECIMAL.
+
+2002-08-31 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * com.c: Don't set flag_finite_math_only by default.
+ * invoke.texi: Reverse the documentation of option
+ -ffinite-math-only to reflect the new default.
+
+2002-08-30 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * target.c (ffetarget_memcpy_): Don't test nonexistent
+ HOST_BYTES_BIG_ENDIAN, HOST_BITS_BIG_ENDIAN. Check
+ HOST_WORDS_BIG_ENDIAN against both WORDS_BIG_ENDIAN and
+ BYTES_BIG_ENDIAN.
+
+2002-08-30 Alan Modra <amodra@bigpond.net.au>
+
+ * target.h (FFETARGET_32bit_longs): Don't define for powerpc64 or
+ mmix.
+
+2002-08-28 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * bugs.texi, news.texi: Update URLs for online news and bugs
+ lists.
+
+2002-08-22 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * where.h (struct _ffewhere_file_): Mark GTY.
+ (ffewhere_file_kill): Remove prototype.
+ * where.c: Include ggc.h.
+ (struct _ffewhere_ll_, struct _ffewhere_root_ll_): Mark GTY.
+ (ffewhere_root_ll_): Ditto. Change type from struct
+ _ffewhere_root_ll_ to struct _ffewhere_root_ll_*. All uses
+ changed.
+ (ffewhere_file_kill): Remove.
+ (ffewhere_file_new): Use GC to allocate ffewhereFile objects.
+ (ffewhere_file_set): Use GC to allocate ffewhereLL_ objects.
+ (ffewhere_init_1): Use GC to allocate ffewhere_root_ll_ sentinel.
+ Include gt-f-where.h.
+ * lex.c (ffelex_current_wf_, ffelex_include_wherefile_): Mark GTY.
+ Include gt-f-lex.h.
+ * std.c (ffestd_S3P4): Don't call ffewhere_file_kill.
+ * config-lang.in (gtfiles): Add f/where.h f/where.c and f/lex.c.
+ * Make-lang.in (gt-f-lex.h gt-f-where.h): Add to dependents of
+ s-gtype.
+ (f/lex.o): Depend on gt-f-lex.h.
+ (f/where.o): Depend on gt-f-where.h.
+
+Tue Aug 20 16:49:40 2002 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * where.c (ffewhere_track): Remove impossible if-then clause.
+
+Thu Aug 8 10:06:14 2002 Nathan Sidwell <nathan@codesourcery.com>
+
+ * f/Make-lang.in (f.mostlyclean): Remove coverage files.
+
+2002-08-06 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * g77.texi (Top): Rename Index to Keyword Index.
+
+2002-08-05 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * invoke.texi: Improve description of
+ -fno-finite-math-only flag.
+
+Sun Aug 4 16:45:49 2002 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * root.texi (version-gcc): Increase to 3.3.
+
+2002-07-30 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * com.c (ffe_init_options): Set
+ flag_finite_math_only.
+ * invoke.texi: Document -fno-finite-math-only.
+
+Mon Jul 29 22:05:35 2002 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (read_name_map): Use concat in lieu of xmalloc/strcpy.
+
+2002-07-25 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * news.texi: Document better handling of (no-)alias
+ information of dummy arguments and induction variables
+ on loop unrolling.
+
+2002-07-01 Roger Sayle <roger@eyesopen.com>
+
+ * f/com.c (builtin_function): Accept additional parameter.
+ (ffe_com_init_0): Pass an additional NULL_TREE argument to
+ builtin_function.
+
+2002-06-28 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * news.texi: Mention 2 Gbyte limit on 32-bit targets
+ for arrays explicitly in news on g77-3.1.
+
+Thu Jun 20 21:56:34 2002 Neil Booth <neil@daikokuya.co.uk>
+
+ * lang-specs.h: Use cc1 for traditional preprocessing.
+
+2002-06-20 Andreas Jaeger <aj@suse.de>
+
+ * com.c (ffecom_prepare_expr_,ffecom_expr_power_integer_):
+ Remove #ifdefed HAHA sections.
+
+2002-06-20 Nathanael Nerode <neroden@twcny.rr.com>
+
+ * com.c: Remove #ifdef HOHO sections.
+
+2002-06-17 Jason Thorpe <thorpej@wasabisystems.com>
+
+ * bit.c: Don't include glimits.h.
+ * target.c: Likewise.
+ * where.h: Likewise.
+
+2002-06-12 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * bad.c (ffebad_start_): Adjust calls to diagnostic_count_error.
+
+2002-06-04 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * bad.c (ffebad_start_): Adjust call to count_error.
+ * Make-lang.in (f/bad.o): Depend on diagnostic.h
+ * bad.c: #include diagnostic.h
+
+2002-06-03 Geoffrey Keating <geoffk@redhat.com>
+
+ * Make-lang.in (f/com.o): Depend on debug.h.
+ * com.c: Include debug.h.
+ (LANG_HOOKS_MARK_TREE): Delete.
+ (struct lang_identifier): Use gengtype.
+ (union lang_tree_node): New.
+ (struct lang_decl): New dummy definition.
+ (struct lang_type): New dummy definition.
+ (ffe_mark_tree): Delete.
+
+ * com.c (struct language_function): New dummy structure.
+
+ * Make-lang.in: Add rules to generate gt-f-ste.h gtype-f.h; allow
+ for filename changes.
+ (com.o): Allow for filename changes; add gtype-f.h as dependency.
+ (ste.o): Add gt-f-ste.h as dependency.
+ * config-lang.in (gtfiles): Add com.h, ste.c.
+ * com.c: Replace uses of ggc_add_* with GTY markers. Include
+ gtype-f.h.
+ (mark_binding_level): Delete.
+ * com.h: Replace uses of ggc_add_* with GTY markers.
+ * ste.c: Replace uses of ggc_add_* with GTY markers. Include
+ gt-f-ste.h.
+
+ * Make-lang.in (f/gt-com.h): Build using gengtype.
+ (com.o): Depend on f/gt-com.h.
+ * com.c: Rename struct binding_level to f_binding_level.
+ (struct f_binding_level): Use gengtype.
+ (struct tree_ggc_tracker): Use gengtype.
+ (mark_tracker_head): Use gt_ggc_m_tree_ggc_tracker.
+ (make_binding_level): Use GGC.
+ (mark_binding_level): Use gt_ggc_m_f_binding_level.
+ (ffecom_init_decl_processing): Change free_binding_level
+ to a deletable root.
+ * config-lang.in (gtfiles): Define.
+ * where.c: Strings need no longer be allocated in GCable memory;
+ remove my change of 30 Dec 1999.
+
+2002-05-31 Matthew Woodcraft <mattheww@chiark.greenend.org.uk>
+
+ * lang-specs.h: Use cpp_debug_options.
+
+2002-05-28 Zack Weinberg <zack@codesourcery.com>
+
+ * bld.c, com.c, expr.c, target.c: Include real.h.
+ * Make-lang.in: Update dependency lists.
+
+2002-05-16 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * Make-lang.in: Allow for PWDCMD to override hardcoded pwd.
+
+2002-05-09 Hassan Aurag <aurag@cae.com>
+
+ * expr.c (ffeexpr_reduced_ugly2log_): Allow logicals-as-integers
+ under -fugly-logint as arguments of .and., .or., .xor.
+
+2002-05-07 Jan Hubicka <jh@suse.cz>
+
+ * target.h (FFETARGET_32bit_longs): Undefine for x86-64.
+
+2002-04-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * invoke.texi: Use @gol at ends of lines inside @gccoptlist.
+ * g77.texi: Update last update date.
+
+Thu Apr 25 07:44:44 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.h (ffe_parse_file): Update.
+ * lex.c (ffe_parse_file): Update.
+
+2002-04-20 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * root.texi: Remove variable version-g77.
+ * g77.texi: Remove the single use of that variable.
+
+Thu Apr 18 19:10:44 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (incomplete_type_error): Remove.
+
+Tue Apr 16 14:55:47 2002 Mark Mitchell <mark@codesourcery.com>
+
+ * com.c (ffecom_expr_power_integer): Add has_scope argument to
+ call to expand_start_stmt_expr.
+
+Mon Apr 15 10:59:14 2002 Mark Mitchell <mark@codesourcery.com>
+
+ * g77.texi: Remove Chill reference.
+
+2002-04-13 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * news.texi: Deprecate frontend version number;
+ update list of fixed bugs.
+
+2002-04-08 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * Make-lang.in (f/target.o): Depend on diagnostic.h.
+ * target.c: Include diagnostic.h.
+ (ffetarget_memcpy_): Call sorry if host and target endians are
+ not matching.
+
+Thu Apr 4 23:29:48 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (LANG_HOOKS_TRUTHVALUE_CONVERSION): Redefine.
+ (truthvalue_conversion): Rename. Update. Make static.
+ (ffecom_truth_value): Update.
+
+Mon Apr 1 21:39:36 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (LANG_HOOKS_MARK_ADDRESSABLE): Redefine.
+ (mark_addressable): Rename.
+ (ffecom_arrayref_, ffecom_1): Update.
+
+Mon Apr 1 09:59:53 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (LANG_HOOKS_SIGNED_TYPE, LANG_HOOKS_UNSIGNED_TYPE,
+ LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE): New.
+ (unsigned_type, signed_type, signed_or_unsigned_type): Rename.
+
+Sun Mar 31 23:50:22 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (lang_print_error_function): Rename.
+ (LANG_HOOKS_PRINT_ERROR_FUNCTION): Redefine.
+ (ffe_init): Don't set hook.
+
+Fri Mar 29 21:59:15 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (LANG_HOOKS_TYPE_FOR_MODE, LANG_HOOKS_TYPE_FOR_SIZE):
+ Redefine.
+ (type_for_mode, type_for_size): Rename.
+ (signed_or_unsigned_type, signed_type, truthvalue_conversion,
+ unsigned_type): Use new hooks.
+
+Tue Mar 26 10:30:05 2002 Andrew Cagney <ac131313@redhat.com>
+
+ * invoke.texi (Warning Options): Mention -Wswitch-enum.
+ Fix PR c/5044.
+
+Tue Mar 26 07:30:51 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (LANG_HOOKS_MARK_TREE): Redefine.
+ (lang_mark_tree): Rename ffe_mark_tree, make static.
+
+Mon Mar 25 19:27:11 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (maybe_build_cleanup): Remove.
+
+2002-03-23 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * com.c (ffecom_check_size_overflow_): Add a test
+ so that arrays too large for 32-bit byte-offset
+ addressing get caught.
+ * news.texi: Document the fixing of this problem.
+
+Sat Mar 23 11:18:17 2002 Andrew Cagney <ac131313@redhat.com>
+
+ * invoke.texi (Warning Options): Mention -Wswitch-default.
+
+Thu Mar 21 18:55:41 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * cp-tree.h (pushdecl, pushlevel, poplevel, set_block,
+ insert_block, getdecls, global_bindings_p): New.
+
+Wed Mar 20 08:03:42 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (lang_printable_name): Rename.
+ (LANG_HOOKS_DECL_PRINTABLE_NAME): Redefine.
+ (ffe_init): Don't use old hook.
+
+Sun Mar 17 18:50:15 2002 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.h (ffe_parse_file): Prototype.
+
+Sun Mar 17 20:57:30 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (LANG_HOOKS_PARSE_FILE): Redefine.
+ * com.h (ffe_parse_file): New.
+ * parse.c (NAME_OF_STDIN): Remove.
+ (yyparse): Rename ffe_parse_file.
+
+Tue Mar 12 20:23:18 2002 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (tree_code_type, tree_code_length, tree_code_name):
+ Define.
+
+Sun Mar 10 12:37:42 2002 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * target.c (ffetarget_print_hex): Const-ify.
+
+2002-03-06 Phil Edwards <pme@gcc.gnu.org>
+
+ * version.c: Fix misplaced leading blanks on first line.
+
+2002-03-03 Zack Weinberg <zack@codesourcery.com>
+
+ * com.c, target.h: Remove all #ifndef REAL_ARITHMETIC
+ blocks, make all #ifdef REAL_ARITHMETIC blocks unconditional.
+ Delete some further #ifdef blocks predicated on REAL_ARITHMETIC.
+
+Thu Feb 28 07:53:46 2002 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (copy_lang_decl): Delete.
+
+2002-02-27 Zack Weinberg <zack@codesourcery.com>
+
+ * com.c, lex.c, top.c: Delete traditional-mode-related code
+ copied from the C front end but not used, or used only to
+ permit the compiler to link.
+
+2002-02-13 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * news.texi: List Problem Reports fixed in 3.1.
+
+2002-02-13 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * data.c (ffedata_eval_offset_): Only convert index,
+ low and high bound in data statements to default integer
+ if they are constants. Use a copy of the data structure.
+
+2002-02-09 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * data.c (ffedata_eval_offset_): Convert non-default integer
+ constants to default integer kind if necessary.
+
+2002-02-09 Toon Moene <toon@moene.indiv.nlug.nl>
+
+ * invoke.texi: Add a short debugging session
+ as an example to the documentation of -g.
+
+2002-02-06 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ PR fortran/4730 fortran/5473
+ * com.c (ffecom_expr_): Deal with %VAL constructs.
+ * intrin.c (ffeintrin_check_): Handle 'N' constraints for intrinsics,
+ to indicate "no larger than default kind" integers and logicals.
+ * intrin.def: Use 'N' constraints in table of intrinsics.
+ * intdoc.c: Document this constraint.
+ * intdoc.texi: Regenerated.
+
+2002-02-04 Philipp Thomas <pthomas@suse.de>
+
+ * implic.c lex.c stb.c ste.c stu.c: Update copyright dates.
+
+2002-02-04 Philipp Thomas <pthomas@suse.de>
+
+ * bad.def com.c expr.c implic.c lex.c stb.c ste.c stu.c:
+ Insert comments to mark messages as not being printf style
+ where appropriate.
+
+2002-02-03 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * expr.c (ffeexpr_sym_impdoitem_): Allow other than
+ default INTEGER implied-do loop counts.
+
+2002-02-01 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * bad.def: Remove non-historical reference to version 0.6.
+ * bugs.texi: Ditto.
+ * com.c: Ditto.
+ * ffe.texi: Ditto.
+ * proj.h: Ditto.
+ * g77.texi: Ditto.
+
+2002-01-31 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77spec.c (lang_specific_driver): Follow GNU Coding Standards
+ for --version.
+
+2002-01-30 Richard Henderson <rth@redhat.com>
+
+ * ste.c (ffeste_begin_iterdo_): Use expand_exit_loop_top_cond.
+ (ffeste_R819B): Likewise.
+
+2002-01-30 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * intrin.c (upcasecmp_): New function.
+ (ffeintrin_cmp_name_): Use it to correctly compare name
+ and table entry for bsearch.
+
+2002-01-26 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * intrin.c (ffeintrin_cmp_name_): Correct comparison
+ for intrinsics in intrinsic table (intrin.def).
+
+2002-01-22 Zack Weinberg <zack@codesourcery.com>
+
+ * bad.c: Include intl.h.
+ (FFEBAD_MSGS1, FFEBAD_MSGS2): Replace by FFEBAD_MSG, SHORT,
+ LONG. Adjust definitions to work with exgettext.
+ (ffebad_start_): Translate all error messages.
+ (ffebad_finish): Mark constant strings for translation.
+ * bad.h: Use FFEBAD_MSG. Adjust prototype of ffebad_start_
+ and definitions of ffebad_start_msg, ffebad_start_msg_lex to
+ work with exgettext.
+ * bad.def: Use FFEBAD_MSG, SHORT, LONG throughout.
+
+ * com.c: Include intl.h.
+ (lang_print_error_function): Always use ffeinfo_kind_message
+ to get the kind label for a non-nested construct. Translate
+ it. Translate constant strings.
+ * info.c (FFEINFO_KIND): Adjust definition to work with exgettext.
+ * info-k.def: Block xgettext from slurping copyright notice
+ into gcc.pot. Adjust strings for their sole use, in com.c.
+
+ * Make-lang.in (f/bad.o, f/com.o): Depend on intl.h.
+
+2002-01-14 David Billinghurst <David.Billinghurst@riotinto.com>
+
+ PR fortran/3807
+ * f/intrin.c (ffeintrin_check_): Allow for case of intrinsic
+ control string have COL-spec an integer > 0.
+
+2002-01-08 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77spec.c (lookup_option): Handle -fversion.
+ (lang_specific_driver): Update copyright date in --version output.
+
+Mon Jan 7 00:03:42 2002 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * invoke.texi: Markup g77 as @command. Remove reference to
+ http://gcc.gnu.org/thanks.html.
+
+Wed Jan 2 18:13:11 2002 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (clear_binding_level): Const-ify.
+ (ffecom_arglist_expr_): Likewise.
+ * info.c (ffeinfo_types_): Don't needlessly zero init.
+ * lex.c (ffelex_hash_kludge): Const-ify.
+
+Sun Dec 23 10:45:09 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (ffecom_gfrt_volatile_, ffecom_gfrt_complex_,
+ ffecom_gfrt_const_, ffecom_gfrt_type_): Const-ify.
+
+Sat Dec 22 16:01:51 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bld.c (ffebld_arity_op_): Declare array size explicitly.
+ * bld.h (ffebld_arity_op_): Likewise.
+
+2001-12-20 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * config-lang.in (diff_excludes): Remove.
+
+2001-12-17 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77.texi, invoke.texi: Update links to GCC manual.
+
+Sun Dec 16 16:08:57 2001 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * news.texi: Fix spelling errors.
+
+Sun Dec 16 10:36:51 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (f/version.o): Depend on f/version.h.
+ * version.c: Include ansidecl.h and f/version.h.
+
+Sun Dec 16 08:52:48 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * lex.c (ffelex_backslash_, ffelex_cfebackslash_): Use hex_value.
+ * target.c (ffetarget_integerhex, ffetarget_typeless_hex): Use
+ hex_p/hex_value.
+
+2001-12-14 Roger Sayle <roger@eyesopen.com>
+
+ * com-rt.def: Use __builtin_sqrt instead of __builtin_fsqrt.
+ * com.c (ffecom_init_0): Same, and fixed enumeration usage.
+
+2001-12-10 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77.texi: Don't condition menus on @ifinfo.
+
+Wed Dec 5 06:49:21 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * com.c (ffecom_1): Properly handle TREE_READONLY for INDIRECT_REF.
+
+Mon Dec 3 18:56:04 2001 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c: Remove leading capital from diagnostic messages, as
+ per GNU coding standards.
+ * g77spec.c: Similarly.
+ * lex.c: Similarly.
+
+2001-12-01 Zack Weinberg <zack@codesourcery.com>
+
+ * f/fini.c: Use xmalloc.
+
+Fri Nov 30 20:54:02 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in: Delete references to proj.[co], proj-h.[co].
+ * proj.c: Delete file.
+
+2001-11-29 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in (f/fini, f/intdoc): Depend on $(HOST_LIBDEPS)
+ and link with $(HOST_LIBS), not safe-ctype.o.
+
+2001-11-29 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (f77.generated-manpages): New target.
+ ($(srcdir)/f/g77.1): Don't check $(GENERATED_MANPAGES). Allow
+ manpage generation to fail.
+ (f77.info): Don't depend on $(srcdir)/f/g77.1.
+ (f77.install-man): Depend on $(GENERATED_MANPAGES) rather than
+ directly on $(srcdir)/g77.1.
+
+2001-11-24 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ PR fortran/3957
+ * lang-specs.h: Correct !pipe conditional in tradcpp0 invocation.
+
+2001-11-21 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * g77.texi: egcs was not a `@command'.
+ * invoke.texi: Ditto.
+ * news.texi: Substitute `@command' for `@code'
+ and `@option' for `@samp' where appropriate.
+
+2001-11-19 Loren J. Rittle <ljrittle@acm.org>
+
+ * Make-lang.in: Complete ``Build g77.1 in $(srcdir)''.
+
+2001-11-19 Geoffrey Keating <geoffk@redhat.com>
+
+ * g77spec.c (lang_specific_driver) [ENABLE_SHARED_LIBGCC]: Add
+ libgcc_s.so if libf2c is used.
+ * Make-lang.in (g77spec.o): Use DRIVER_DEFINES.
+
+2001-11-19 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * .cvsignore: Ignore g77.1
+ * g77.texi: Substitute `@command' for `@code'
+ where appropriate.
+ * invoke.texi: Ditto.
+
+2001-11-18 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * Make-lang.in: Remove all references to LANGUAGES
+ and the stamp files that depend on its value.
+
+Sun Nov 18 11:13:04 2001 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (finish_parse): Remove.
+ (ffe_finish): Move body of finish_parse.
+
+Thu Nov 15 10:06:38 2001 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (ffecom_init_decl_processing): Renamed from
+ init_decl_processing.
+ (init_parse): Move contents to ffe_init.
+ (ffe_init): Update prototype.
+
+2001-11-14 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * g77.texi: Update to use `@command', `@option.
+ * invoke.texi: Ditto
+
+2001-11-14 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in: Change all uses of $(manext) to $(man1ext).
+
+2001-11-14 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * g77.1: Remove from CVS.
+ * Make-lang.in: Build g77.1 in $(srcdir).
+ Add --section=1 to POD2MAN command line.
+ * invoke.texi: Correct copyright years.
+ Add more sections to man page. Add GFDL.
+
+Fri Nov 9 23:16:45 2001 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (ffe_print_identifier): Rename.
+ (LANG_HOOKS_PRINT_IDENTIFIER): Override.
+ (lang_print_xnode, print_lang_decl, print_lang_statistics,
+ print_lang_type, set_yydebug): Remove.
+
+2001-11-09 Zack Weinberg <zack@codesourcery.com>
+
+ * g77spec.c (lang_specific_driver): Adjust behavior of -v and
+ --version for consistency with other front ends. Remove large
+ #if 0 block. Do not add libraries to argv if there are no
+ input files.
+ (add_version_magic): Delete all references and dependent code.
+ * lang-options.h: Delete -fnull-version.
+ * lang-specs.h: Delete f77-version spec.
+
+ * lex.c: Delete logic conditional on ffe_is_null_version() and
+ now-unused label.
+ * top.c: Delete ffe_is_null_version_ variable.
+ (ffe_decode_option): Delete -fnull-version case.
+ * top.h: Delete declaration of ffe_is_null_version_ and
+ ffe_is_null_version(), ffe_set_is_null_version() macros.
+
+Fri Nov 9 07:14:47 2001 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * com.c (language_string, lang_identify): Remove.
+ (struct lang_hooks): Constify.
+ (LANG_HOOKS_NAME): Override.
+ (init_parse): Update.
+
+2001-11-08 Andreas Franck <afranck@gmx.de>
+
+ * Make-lang.in (G77_INSTALL_NAME, G77_CROSS_NAME): Handle
+ program_transform_name the way suggested by autoconf.
+
+2001-11-08 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * Make-lang.in: Add rules for building g77.1.
+ * invoke.texi: Add man page stuff. Move indexing
+ from g77.texi to here.
+ * g77.texi: Remove indexing specific to invoke.texi.
+ * news.texi: Document that g77.1 is now a generated
+ file.
+
+Tue Nov 6 21:17:47 2001 Neil Booth <neil@cat.daikokuya.demon.co.uk>
+
+ * com.c: Include langhooks-def.h.
+ * Make-lang.in: Update.
+
+2001-11-04 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * g77.texi: Split off invoke.texi (preliminary to using it
+ to generate a man page).
+ * Make-lang.in: Reflect in build rules.
+
+Fri Nov 2 10:51:34 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (ffecom_initialize_char_syntax_, U_CHAR, is_idchar,
+ is_idstart, is_hor_space, is_space, SKIP_WHITE_SPACE,
+ SKIP_ALL_WHITE_SPACE): Delete.
+ (read_filename_string, read_name_map): Don't use is_space or
+ is_hor_space.
+
+2001-10-29 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * news.texi: Document new ability to compile programs with
+ arrays larger than 512 Mbyte on 32-bit targets.
+
+2001-10-24 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * com.c (ffecom_check_size_overflow_): Only check for TREE_OVERFLOW.
+
+Tue Oct 23 14:01:27 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * com.c (LANG_HOOKS_GET_ALIAS_SET): New macro.
+ (lang_get_alias_set): Delete.
+
+2001-10-23 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77.texi (Sending Patches): Remove.
+
+2001-10-22 Zack Weinberg <zack@codesourcery.com>
+
+ * Make-lang.in (f/intdoc): Depend on safe-ctype.o.
+
+Sun Oct 21 17:28:17 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bad.c (ffebad_finish): Use safe-ctype macros and/or fold extra
+ calls into fewer ones.
+ * implic.c (ffeimplic_lookup_): Likewise.
+ * intdoc.c (dumpimp): Likewise.
+ * intrin.c (ffeintrin_init_0): Likewise.
+ * lex.c (ffelex_backslash_, ffelex_cfebackslash_, ffelex_hash_):
+ Likewise.
+ * lex.h (ffelex_is_firstnamechar): Likewise.
+ * target.c (ffetarget_integerhex): Likewise.
+
+2001-10-21 Craig Prescott <prescott@phys.ufl.edu>
+
+ * target.h (FFETARGET_32bit_longs): Don't define
+ for 64-bit hppa.
+
+2001-10-17 Richard Henderson <rth@redhat.com>
+
+ * std.c (ffestd_labeldef_format): Fix variable/stmt ordering.
+ (ffestd_R737A): Likewise.
+
+2001-10-17 Richard Henderson <rth@redhat.com>
+
+ * com.h: Remove FFECOM_targetCURRENT, FFECOM_ONEPASS, BUILT_FOR_270,
+ BUILT_FOR_280, FFECOM_GCC_INCLUDE, all derivitive defines, and all
+ related conditional compilation directives.
+ * bad.c, bld.c, bld.h, com.c, equiv.c, equiv.h, global.h, intdoc.c,
+ intrin.c, intrin.h, lex.c, parse.c, sta.c, std.c, ste.c, ste.h, stt.c,
+ stt.h, stw.h, symbol.c, symbol.h, target.h, top.c: Likewise.
+
+2001-10-17 Richard Henderson <rth@redhat.com>
+
+ * Make-lang.in (f/com.o): Depend on langhooks.h.
+ * com.c: Include it.
+ (LANG_HOOKS_INIT, LANG_HOOKS_FINISH): New.
+ (LANG_HOOKS_INIT_OPTIONS, LANG_HOOKS_DECODE_OPTION): New.
+ (lang_hooks): Use LANG_HOOKS_INITIALIZER.
+
+Sun Oct 7 12:27:54 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bad.c (_ffebad_message_, ffebad_messages_): Const-ify.
+ * bld.c (ffebld_arity_op_): Likewise.
+ * bld.h (ffebld_arity_op_): Likewise.
+ * com.c (ffecom_init_0): Likewise.
+ * intdoc.c (_ffeintrin_name_, _ffeintrin_gen_, _ffeintrin_spec_,
+ _ffeintrin_imp_, names, gens, imps, specs, cc_pair,
+ cc_descriptions, cc_summaries): Likewise.
+ * intrin.c (_ffeintrin_name_, _ffeintrin_gen_, _ffeintrin_spec_,
+ _ffeintrin_imp_, ffeintrin_names_, ffeintrin_gens_,
+ ffeintrin_imps_, ffeintrin_specs_): Likewise.
+
+2001-10-05 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * news.texi: Document libf2c being built as a shared library.
+ Use of array elements in bounds of adjustable arrays ditto.
+
+2001-10-03 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * Make-lang.in: Remove reference to FORTRAN_INIT.
+ * g77spec.c: Add reference to FORTRAN_INIT.
+
+2001-09-29 Juergen Pfeifer <juergen.pfeifer@gmx.net>
+
+ Make libf2c a shared library.
+
+ * Make-lang.in: Pass define of frtbegin.o to compilation of g77spec.c.
+ * g77spec.c (lang_specific_driver): Treat linking in of frtbegin.o.
+
+2001-09-28 Robert Anderson <rwa@alumni.princeton.edu>
+
+ * expr.c (ffeexpr_sym_rhs_dimlist_): Allow array elements
+ as bounds of adjustable arrays.
+
+Thu Sep 20 15:05:20 JST 2001 George Helffrich <george@geo.titech.ac.jp>
+
+ * com.c (ffecom_subscript_check_): Loosen subscript checking rules
+ for character strings, to permit substring expressions like
+ string(1:0).
+ * news.texi: Document this as a new feature.
+
+Thu Sep 13 10:33:27 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bad.c (ffebad_finish): Const-ification and/or static-ization.
+ * intrin.c (ffeintrin_cmp_name_): Likewise.
+ * stc.c (ffestc_R904): Likewise.
+
+Wed Sep 12 12:09:04 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bld.c (ffebld_op_string_): Const-ification.
+ * com.c (ffecom_gfrt_name_, ffecom_gfrt_argstring_): Likewise.
+ * fini.c (xspaces): Likewise.
+ * global.c (ffeglobal_type_string_): Likewise.
+ * info.c (ffeinfo_basictype_string_, ffeinfo_kind_message_,
+ ffeinfo_kind_string_, ffeinfo_kindtype_string_,
+ ffeinfo_where_string_): Likewise.
+ * lex.c (ffelex_type_string_): Likewise.
+ * malloc.c (malloc_types_): Likewise.
+ * stc.c (ffestc_subr_binsrch_, ffestc_R904, ffestc_R904,
+ ffestc_R907): Likewise.
+ * symbol.c (ffesymbol_state_name_, ffesymbol_attr_name_):
+ Likewise.
+ * version.c (ffe_version_string): Likewise.
+ * version.h (ffe_version_string): Likewise.
+
+2001-09-11 Richard Henderson <rth@redhat.com>
+
+ * parse.c (finput): Mark extern.
+
+2001-09-11 Jakub Jelinek <jakub@redhat.com>
+
+ * com.c (ffe_init_options): Default to -fmerge-all-constants
+ if optimizing.
+
+2000-08-14 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * target.h (FFETARGET_32bit_longs): Don't define
+ for 64-bit S/390.
+
+2001-07-20 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * com.c (ffecom_expr_intrinsic_):
+ case FFEINTRIN_impIBITS: Remove TREE_SHIFT_FULLWIDTH define.
+ case FFEINTRIN_impISHFT: Ditto. Change LT_EXPR to NE_EXPR.
+ case FFEINTRIN_impISHFTC: Ditto.
+ case FFEINTRIN_impMVBITS: Ditto.
+
+2001-07-19 Jakub Jelinek <jakub@redhat.com>
+
+ * top.c (ffe_decode_option): Disallow lang-independent processing
+ for -ffixed-form.
+
+2001-07-19 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * f/com.c (ffecom_expr_intrinsic_): Deal (correctly) with
+ {L|R}SHIFT_EXPR not working when shift > size of type.
+
+2001-07-17 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * com.c (lang_print_error_function): Argument context
+ is unused.
+
+2001-07-14 Tim Josling <tej@melbpc.org.au>
+
+ * com.c (ffecom_overlap_): Remove references to EXPON_EXPR.
+ (ffecom_tree_canonize_ref_): Likewise.
+
+2001-07-10 James Smaby <jsmaby@virgo.umeche.maine.edu>
+
+ * intdoc.in: Fix the definition of COMPLEX ABS.
+ Remove `the' where inappropriate.
+ * intdoc.texi: Rebuilt.
+
+2001-07-04 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77.texi: Use gpl.texi and funding.texi. Remove Look and Feel
+ section. Add Funding Free Software to invariant sections.
+ * Make-lang.in ($(srcdir)/f/g77.info, f/g77.dvi): Update
+ dependencies and use doc/include in search path.
+
+2001-06-28 Gabriel Dos Reis <gdr@codesourcery.com>
+
+ * Make-lang.in (f/com.o): Depend on diagnostic.h
+ * com.c: #include diagnostic.h
+ (lang_print_error_function): Take a 'diagnostic_context *'.
+
+Wed Jun 13 11:22:39 2001 Mark Mitchell <mark@codesourcery.com>
+
+ * BUGS: Remove.
+ * NEWS: Likewise.
+
+2001-06-10 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * g77install.texi: Remove.
+ * Make-lang.in: Remove all mention of g77install.texi.
+ * g77.texi: Add documentation on how to get output always
+ flushed and how to increase the maximum unit number.
+ Remove all mention of g77install.texi.
+ * bugs.texi: Add documentation on how to change the threshold
+ for putting local arrays on the stack.
+
+2001-06-03 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * root.texi: Fix typo in patches e-mail address.
+
+2001-06-03 Toon Moene <toon@moene.indiv.nluug.nl>
+ Jan van Male <jan.vanmale@fenk.wau.nl>
+
+ * root.texi: Define `help' and `patches' mailing list
+ addresses.
+ * news.texi: Remove `prerelease' from 0.5.26
+ * g77.texi: Use two spaces between command options, eliminate
+ some 'overfull hboxes'. Use help and patches mailing list
+ addresses where appropriate.
+
+2001-06-02 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77.texi: Move contents to just after title page.
+
+2001-06-02 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * com.c (ffecom_init_0): Make CHARACTER*1 unsigned.
+
+2001-05-23 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * Make-lang.in ($(srcdir)/f/g77.info): Added dependencies on
+ fdl.texi.
+ (f/g77.dvi): Use TEXI2DVI instead of custom tex calls. Create the
+ dvi file in the f directory.
+
+2001-05-25 Sam TH <sam@uchicago.edu>
+
+ * bad.h: Fix header include guards.
+ * bit.h bld.h com.h data.h equiv.h expr.h global.h
+ implic.h info.h intrin.h lab.h lex.h malloc.h name.h
+ proj.h src.h st.h sta.h stb.h stc.h std.h ste.h
+ storag.h stp.h str.h sts.h stt.h stu.h stv.h stw.h
+ symbol.h target.h top.h type.h version.h
+ where.h: Likewise.
+
+2001-05-22 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * g77.texi: Update last-changed date.
+ * news.texi: Update copyright years, last-changed date.
+ * bugs.texi: Update copyright years, last-changed date.
+
+2001-05-22 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * g77.texi: Update maintenance information for
+ GNU Fortran. Remove all mention of -fdebug-kludge.
+ * news.texi: Make more news in 0.5.26 `user visible
+ changes'. Acknowledge work by important contributors.
+ * bugs.texi: Remove all mention of -fdebug-kludge.
+
+2001-05-20 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (f/g77.dvi): Include $(srcdir) in TEXINPUTS.
+
+2001-05-19 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * Make-lang.in: Have $(MAKEINFO) look into the parent
+ directory for includes.
+ * g77.texi: Use the GFDL.
+
+Sun May 13 12:25:06 2001 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in: Replace all uses of `touch' with $(STAMP).
+
+Wed May 2 10:20:08 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c: NULL_PTR -> NULL.
+
+Sun Apr 22 20:18:01 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (ffecom_subscript_check_): Use concat in lieu of
+ xmalloc/sprintf.
+
+2001-04-21 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * news.texi: Update release information for 0.5.27.
+
+Thu Apr 19 12:49:24 2001 Mark Mitchell <mark@codesourcery.com>
+
+ * top.c (ffe_decode_option): Do not permit language-independent
+ processing for -ffixed-line-length.
+
+Thu Apr 12 17:57:55 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bad.c (inhibit_warnings): Delete redundant declaration.
+
+ * com.c (skip_redundant_dir_prefix): Likewise.
+
+ * com.h (mark_addressable): Likewise.
+
+2001-04-02 Jakub Jelinek <jakub@redhat.com>
+
+ * lex.c (ffelex_hash_): Avoid eating one whole line after
+ #line.
+
+Mon Apr 2 22:38:09 2001 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * com.c (duplicate_decls): Fix thinko in lazy DECL_RTL patch
+ of 2001-03-04.
+
+Tue Mar 27 17:40:08 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in: Depend on $(SYSTEM_H), not system.h.
+
+Mon Mar 26 18:13:30 2001 Mark Mitchell <mark@codesourcery.com>
+
+ * com.c (duplicate_decls): Don't copy DECL_FRAME_SIZE.
+
+Mon Mar 19 15:05:39 2001 Mark Mitchell <mark@codesourcery.com>
+
+ * com.c (builtin_function): Use SET_DECL_ASSEMBLER_NAME.
+
+Wed Mar 14 09:29:27 2001 Mark Mitchell <mark@codesourcery.com>
+
+ * com.c (ffecom_member_phase_2): Use COPY_DECL_RTL,
+ DECL_RTL_SET_P, etc.
+ (duplicate_decls): Likewise.
+ (start_decl): Likewise.
+
+Fri Mar 9 22:52:55 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fini.c (main): Use really_call_malloc, not malloc.
+
+Thu Mar 8 13:27:47 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c: Don't rely on the POSIX macro to define autoconf stuff.
+
+2001-03-07 Brad Lucier <lucier@math.purdue.edu>
+
+ * g77.texi: Document new options -funsafe-math-optimizations
+ and -fno-trapping-math. Revise documentation for -ffast-math.
+
+2001-03-01 Zack Weinberg <zackw@stanford.edu>
+
+ * proj.h: Delete 'bool' type. Don't include stddef.h here.
+ * com.c: Rename variables named 'true' and/or 'false'.
+ * intdoc.c: Delete 'bool' type.
+
+2001-03-01 Zack Weinberg <zackw@stanford.edu>
+
+ * lang-specs.h: Add zero initializer for cpp_spec field to all
+ array elements.
+
+2001-02-24 Zack Weinberg <zackw@stanford.edu>
+
+ * com.c: Don't define STDC_HEADERS, autoconf handles it.
+
+Fri Feb 23 15:28:39 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * com.c (set_block): Set NAMES and BLOCKS from BLOCK.
+
+2001-02-19 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * version.c, root.texi: Update GCC version number to 3.1. Update
+ G77 version number to 0.5.27.
+ * BUGS, NEWS: Regenerate.
+
+Sun Feb 4 15:52:44 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * com.c (ffecom_init_0): Call fatal_error instead of fatal.
+ * com.c (init_parse): Call fatal_io_error instead of
+ pfatal_with_name.
+ (ffecom_decode_include_option_): Make errors non-fatal.
+ * lex.c (ffelex_cfelex_, ffelex_get_directive_line_): Likewise.
+ (ffelex_hash_): Likewise.
+
+Sat Jan 27 20:52:18 2001 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in: Remove all dependencies on defaults.h.
+ * com.c: Don't include defaults.h.
+
+2001-01-23 Michael Sokolov <msokolov@ivan.Harhan.ORG>
+
+ * com.c: Don't explicitly include any time headers, the right ones are
+ already included by proj.h.
+
+2001-01-15 Mark Mitchell <mark@codesourcery.com>
+
+ * com.c (ffecom_lookup_label): Set DECL_CONTEXT for FORMAT
+ label to current_function_decl.
+
+Fri Jan 12 17:21:33 2001 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77spec.c (lang_specific_driver): Update copyright year to 2001.
+
+Wed Jan 10 14:39:45 2001 Mark Mitchell <mark@codesourcery.com>
+
+ * com.c (ffecom_init_zero_): Remove last argument in call to
+ make_decl_rtl; use make_function_rtl instead of make_decl_rtl.
+ (ffecom_lookup_label_): Likewise.
+ (builtin_function): Likewise.
+ (start_function): Likewise.
+
+Thu Dec 21 21:19:42 2000 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77install.texi, g77.texi: Update last-updated dates for
+ installation information and the manual as a whole.
+ * bugs.texi, news.texi: Update copyright years in the comments at
+ the top of the file.
+
+2000-12-21 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77install.texi: Adjust wording of an EGCS reference.
+
+Thu Dec 21 20:00:48 2000 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * BUGS, NEWS: Regenerate.
+
+2000-12-18 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * com.c [VMS]: Remove definition of BSTRING.
+
+2000-12-18 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77.texi: Update GPL copy not to refer to years 19@var{yy}.
+
+2000-12-18 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * bugs.texi: Correct copyright years.
+ * g77.texi: Likewise.
+ * news.texi: Likewise.
+
+2000-12-18 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77install.texi: Remove obsolete parts only used for INSTALL,
+ and DOC-G77 conditionals. Update last-update-install date.
+
+Sat Dec 9 10:20:11 2000 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * .cvsignore: New file; add info files.
+
+2000-12-08 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in (f77.info): Depend on info files in source
+ directory.
+ (f/g77.info): Build info files in source directory; don't build
+ them unless BUILD_INFO is "info".
+ (f77.install-info): Install info files from source directory.
+
+2000-12-07 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * Make-lang.in: Link f/fini with safe-ctype.o.
+ * bad.c: Don't test ISUPPER(c) || ISLOWER(c) before calling TOUPPER(c).
+ * com.c: Use TOUPPER, not ffesrc_toupper.
+ * fini.c: Don't test ISALPHA(c) before calling TOUPPER(c)/TOLOWER(c).
+ * intrin.c: Don't test IN_CTYPE_DOMAIN(c).
+ * src.c: Delete ffesrc_toupper_ and ffesrc_tolower_ and their
+ initializing code; use TOUPPER and TOLOWER instead of
+ ffesrc_toupper and ffesrc_tolower.
+ * src.h: Don't declare ffesrc_toupper_ or ffesrc_tolower_.
+ Don't define ffesrc_toupper or ffesrc_tolower.
+
+2000-11-28 Richard Henderson <rth@redhat.com>
+
+ * com.c (ffecom_member_phase2_): Set TREE_USED on the debugging decl.
+
+2000-11-26 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * RELEASE-PREP: Remove obsolete EGCS reference.
+ * g77.texi: Adjust reference to EGCS as something current.
+ * lang-options.h (FTNOPT): Remove macro and obsolete comment.
+ Include doc strings directly in option listing instead of through
+ this macro.
+ * root.texi: Remove support for multiple different (FSF and EGCS)
+ distributions of g77.
+ * g77install.texi: Remove conditioned out instructions applying
+ only to obsolete distributions of g77 not as part of GCC. Change
+ "superceded" to the correct spelling "superseded".
+
+Sun Nov 26 19:25:56 2000 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * g77spec.c (lang_specific_driver): Update copyright year to 2000.
+
+Thu Nov 23 02:18:57 2000 J"orn Rennecke <amylaar@redhat.com>
+
+ * Make-lang.in (g77spec.o): Depend on $(CONFIG_H).
+
+2000-11-21 David Billinghurst <David.Billinghurst@riotinto.com)
+
+ * Make-lang.in: Add $(build_exeext) to f/fini target
+
+2000-11-21 Andreas Jaeger <aj@suse.de>
+
+ * g77.texi (Floating-point Exception Handling): Use feenableexcept
+ in example.
+ (Floating-point precision): Change to match above change.
+
+Sun Nov 19 17:29:22 2000 Matthias Klose <doko@marvin.itso-berlin.de>
+
+ * g77.texi (Floating-point precision): Adjust example
+ to work with glibc (>= 2.1).
+
+Sat Nov 18 13:54:49 2000 Matthias Klose <doko@cs.tu-berlin.de>
+
+ * g77.texi (Floating-point Exception Handling): Adjust
+ example to work with glibc (>= 2.1).
+
+2000-11-18 Alexandre Oliva <aoliva@redhat.com>
+
+ * Make-lang.in (INTDOC_DEPS): New macro.
+ (f/intdoc.texi): Depend on $(INTDOC_DEPS). Build f/intdoc.
+ (f/intdoc): Likewise. Add $(build_exeext).
+
+2000-11-17 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * lex.c (ffelex_hash_): Change ggc_alloc_string (var, -1) to
+ ggc_strdup (var).
+
+Thu Nov 16 23:14:07 2000 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * malloc.c (malloc_init): Call xmalloc, not malloc.
+
+2000-11-10 Rodney Brown <RodneyBrown@mynd.com>
+
+ * Make-lang.in: Remove OUTPUT_OPTION from g77version.o target.
+
+2000-11-10 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * root.texi: Remove non-historical EGCS reference.
+ Set current g77 version to 0.5.26.
+
+2000-11-10 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * com.c (ffecom_stabilize_aggregate_) case RTL_EXPR: Abort.
+
+2000-11-10 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * Make-lang.in (f/fini.o, f/proj-h.o): Remove pointless sed
+ munging of source file name.
+ ($(srcdir)/f/intdoc.texi): Break up into several rules each of
+ which builds just one thing. Don't mess with $(LANGUAGES).
+ (f/ansify.o, f/intdoc.o): Remove unnecessary rules.
+
+2000-11-05 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * root.texi, news.texi, g77install.texi, g77.texi, bugs.texi:
+ Remove non-historical references to egcs/EGCS.
+
+2000-11-05 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Make-lang.in: Remove f77.distdir and f/INSTALL.
+ * INSTALL, install0.texi: Remove.
+
+2000-11-02 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * com.c (open_include_file, ffecom_open_include_): Use strchr ()
+ and strrchr () instead of index () and rindex ().
+
+2000-10-27 Zack Weinberg <zack@wolery.stanford.edu>
+
+ * Make-lang.in: Move all build rules here from Makefile.in,
+ adapt to new context. Wrap all rules that change the current
+ directory in parentheses. Expunge all references to $(P).
+ When one command depends on another and they're run all at
+ once, use && to separate them, not ;. Add OUTPUT_OPTION to
+ all object-file generation rules. Delete obsolete variables.
+
+ * Makefile.in: Delete.
+ * config-lang.in: Delete outputs= line.
+
+Sat Oct 21 18:07:48 2000 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * Makefile.in, g77spec.c: Remove EGCS references in comments.
+
+Thu Oct 12 22:28:51 2000 Mark Mitchell <mark@codesourcery.com>
+
+ * com.c (ffecom_do_entry_): Don't mess with obstacks.
+ (ffecom_finish_global_): Likewise.
+ (ffecom_finish_symbol_transform_): Likewise.
+ (ffecom_gen_sfuncdef_): Likewise.
+ (ffecom_init_zero_): Likewise.
+ (ffecom_start_progunit_): Likewise.
+ (ffecom_sym_transform_): Likewise.
+ (ffecom_sym_transform_assign_): Likewise.
+ (ffecom_transform_equiv_): Likewise.
+ (ffecom_transform_namelist_): Likewise.
+ (ffecom_vardesc_): Likewise.
+ (ffecom_vardesc_array_): Likewise.
+ (ffecom_vardesc_dims_): Likewise.
+ (ffecom_end_transition): Likewise.
+ (ffecom_make_tempvar): Likewise.
+ (bison_rule_pushlevel_): Likewise.
+ (bison_rule_compstmt_): Likewise.
+ (finish_decl): Likewise.
+ (finish_function): Likewise.
+ (push_parm_decl): Likewise.
+ (start_decl): Likewise.
+ (start_function): Likewise.
+ (ggc_p): Don't define.
+ * std.c (ffestd_stmt_pass_): Likewise.
+ * ste.c (ffeste_end_block_): Likewise.
+ (ffeste_end_stmt_): Likewise.
+ (ffeste_begin_iterdo_): Likewise.
+ (ffeste_io_ialist_): Likewise.
+ (ffeste_io_cilist_): Likewise.
+ (ffeste_io_inlist_): Likewise.
+ (ffeste_io_olist_): Likewise.
+ (ffeste_R810): Likewise.
+ (ffeste_R838): Likewise.
+ (ffeste_R839): Likewise.
+ (ffeste_R842): Likewise.
+ (ffeste_R843): Likewise.
+ (ffeste_R1001): Likewise.
+
+2000-10-05 Richard Henderson <rth@cygnus.com>
+
+ * com.c (finish_function): Don't init can_reach_end.
+
+Sun Oct 1 11:43:44 2000 Mark Mitchell <mark@codesourcery.com>
+
+ * com.c (lang_mark_false_label_stack): Remove.
+
+2000-09-10 Zack Weinberg <zack@wolery.cumb.org>
+
+ * com.c: Include defaults.h.
+ * com.h: Don't define the *_TYPE_SIZE macros.
+ * Makefile.in: Update dependencies.
+
+2000-08-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * ansify.c: Use #line, not # <number>.
+
+2000-08-24 Greg McGary <greg@mcgary.org>
+
+ * intdoc.c (ARRAY_SIZE): Remove macro.
+ * proj.h (ARRAY_SIZE): Remove macro.
+ * com.c (init_decl_processing): Use ARRAY_SIZE.
+
+2000-08-22 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * com-rt.def: Adapt macro DEFGFRT to accept CONST boolean.
+ * com.c (macro DEFGFRT): Use CONST boolean.
+ (ffecom_call_binop_): Choose between call by value
+ and call by reference.
+ (ffecom_expr_): Use direct calls to (g)libc functions for
+ POW_DD, LOG10, (float) MOD.
+ (ffecom_make_gfrt_): Add const indication to table of
+ intrinsics.
+ * com.h (macro DEFGFRT): Use CONST boolean.
+ * intrin.def: Adjust DEFIMP definition of LOG10, (float) MOD.
+
+2000-08-21 Nix <nix@esperi.demon.co.uk>
+
+ * lang-specs.h: Do not process -o or run the assembler if
+ -fsyntax-only. Use %j instead of /dev/null.
+
+2000-08-21 Jakub Jelinek <jakub@redhat.com>
+
+ * lang-specs.h: Pass -I* options to f771.
+
+2000-08-19 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * top.c (ffe_decode_option): Disable -fdebug-kludge
+ and warn about it.
+ * lang-options.h: Document the fact.
+ * g77.texi: Ditto.
+
+2000-08-13 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * bugs.texi: Describe new ability to emit debug info
+ for EQUIVALENCE members.
+ * news.texi: Ditto.
+
+2000-08-11 G. Helffrich <george@gly.bris.ac.uk>
+ Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * com.c (ffecom_transform_equiv_): Make EQUIVALENCEs addressable
+ so that debug info can be attached to their storage.
+ Unconditionally list the storage set aside for them.
+
+2000-08-07 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * g77spec.c (lang_specific_driver): Clearer g77 version message.
+
+2000-08-04 Zack Weinberg <zack@wolery.cumb.org>
+
+ * Make-lang.in (f771): Depend on $(BACKEND), not stamp-objlist.
+ * Makefile.in: Add BACKEND; delete OBJS, OBJDEPS.
+ (f771): Link with $(BACKEND).
+
+2000-08-02 Zack Weinberg <zack@wolery.cumb.org>
+
+ * g77spec.c: Adjust type of second argument to
+ lang_specific_driver, and update code as necessary.
+
+ * expr.c (ffeexpr_finished_): Cast signed side of ?:
+ expression to bool.
+
+2000-07-31 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Rename cpp to cpp0 and/or tradcpp to tradcpp0.
+
+Thu Jul 27 11:50:08 2000 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fini.c (main): Avoid automatic aggregate initialization.
+
+ * proj.h: Indent #error directive.
+
+2000-07-26 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * lang-specs.h: Remove one /dev/null from tradcpp invocation.
+
+Sun Jul 23 15:47:30 2000 Billinghurst, David <David.Billinghurst@riotinto.com>
+
+ * Make-lang.in: Put $(build_exeext) suffix on programs which run
+ on the build machine.
+
+2000-07-22 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * com.c (ffecom_expr_intrinsic_): case FFEINTRIN_impFGETC_subr,
+ FFEINTRIN_impFPUTC_subr: Check for arg3 being NULL.
+
+2000-07-13 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Use the new named specs. Remove unnecessary braces.
+
+2000-07-02 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * version.c: Bump version number.
+
+2000-06-21 Zack Weinberg <zack@wolery.cumb.org>
+
+ * Make-lang.in (F77_SRCS): Remove all .j files.
+ * Makefile.in (ASSERT_H, CONFIG_H, CONVERT_H, FLAGS_H, GGC_H,
+ GLIMITS_H, HCONFIG_H, INPUT_H, OUTPUT_H, RTL_H, SYSTEM_H,
+ TOPLEV_H, TREE_H): Remove references to .j files.
+ (TCONFIG_H, TM_H): Remove entirely.
+ (deps-kinda): Delete rule.
+ Correct commentary.
+
+ * assert.j, config.j, convert.j. flags.j, ggc.j, glimits.j,
+ hconfig.j, input.j, output.j, rtl.j, system.j, toplev.j,
+ tree.j, tconfig.j, tree.j: Delete.
+
+ * ansify.c, bad.c, bit.c, com.c, com.h, intdoc.c, lex.c,
+ parse.c, proj.c, proj.h, ste.c, target.c, target.h, top.c,
+ where.c, where.h: Include parent-directory headers directly.
+ * lex.c: Don't include tree.h twice.
+
+2000-05-17 H.J. Lu (hjl@gnu.org)
+
+ * Make-lang.in: Use a unique stamp for each target to support
+ parallel make.
+
+Thu Jun 15 14:03:14 2000 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ste.c (gbe_block): Constify.
+
+2000-06-13 Jakub Jelinek <jakub@redhat.com>
+
+ * com.c (ffecom_transform_common_): Set DECL_USER_ALIGN.
+ (ffecom_transform_equiv_, ffecom_decl_field): Likewise.
+ (ffecom_init_0): Set DECL_USER_ALIGN resp. TYPE_USER_ALIGN.
+ (duplicate_decls): Set DECL_USER_ALIGN.
+
+Sun Jun 11 00:03:00 2000 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (lang_get_alias_set): Mark parameter with ATTRIBUTE_UNUSED.
+
+2000-06-04 Philipp Thomas <pthomas@suse.de>
+
+ * Makefile.in(INTLLIBS): New macro.
+ (LIBS): Add INTLLIBS.
+ (DEPLIBS): Likewise.
+
+2000-06-02 Richard Henderson <rth@cygnus.com>
+
+ * com.c (lang_get_alias_set): New.
+
+2000-05-28 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * bugs.texi: Note that debugging information for
+ common block items is emitted now.
+ * news.texi: Ditto.
+
+2000-05-18 Chris Demetriou <cgd@sibyte.com>
+
+ * com.h (FFECOM_f2cINTEGER, FFECOM_f2cLONGINT): Note that
+ these types correspond to built-in types now defined in
+ the C front end (for libf2c).
+
+Wed May 17 17:27:44 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (ffe_decode_option): Update -Wall unused flags by calling
+ set_Wunused.
+
+2000-05-09 Zack Weinberg <zack@wolery.cumb.org>
+
+ * com.c (ffecom_subscript_check_): Constify array_name
+ parameter. Clean up string bashing.
+ (ffecom_arrayref_, ffecom_char_args_x_): Constify array_name
+ parameter.
+ (ffecom_do_entry_, ffecom_gen_sfuncdef_, ffecom_start_progunit_,
+ ffecom_sym_transform_, ffecom_sym_transform_assign_): Constify
+ local char *.
+ (init_parse): Constify parameter and return value.
+ * lex.c: Include dwarfout.h instead of prototyping dwarfout_*
+ functions here.
+ (ffelex_file_pop_, ffelex_file_push_): Constify filename parameter.
+ (ffelex_hash_, ffelex_include_): Constify local char *.
+ * std.c (ffestd_exec_end): Constify local char *.
+ * where.c (ffewhere_file_new): Constify filename parameter.
+ * where.h: Update prototypes.
+
+2000-05-06 Zack Weinberg <zack@wolery.cumb.org>
+
+ * com.c (ffecom_overlap_): Set source_offset to
+ bitsize_zero_node.
+ (ffecom_tree_canonize_ptr_): Use size_binop. Convert to
+ bitsizetype before multiplying by TYPE_SIZE.
+ (ffecom_tree_canonize_ref_) [case ARRAY_REF]: Break up offset
+ calculation. Convert to bitsizetype before multiplying by
+ TYPE_SIZE.
+
+2000-04-18 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lex.c: Remove references to cccp.c.
+ * g77install.texi: Remove references to cexp.c/cexp.y.
+
+2000-04-15 David Edelsohn <edelsohn@gnu.org>
+
+ * target.h (FFETARGET_32bit_longs): Define for 64-bit PowerPC
+ as well.
+
+Wed Apr 12 15:15:26 2000 Mark Mitchell <mark@codesourcery.com>
+
+ * com.h (FFECOM_f2cINTEGER): Avoid using LONG_TYPE_SIZE as a
+ preprocessor constant.
+ (FFECOM_f2cLOGICAL): Likewise.
+ (FFECOM_f2cLONGINT): Likewise.
+
+Wed Apr 5 17:46:39 2000 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (GGC_H): Add varray.h.
+
+2000-04-03 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Pass -fno-show-column to the preprocessor.
+
+2000-03-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * com.c (ffecom_decl_field): Use DECL_ALIGN for a FIELD_DECL.
+ (ffecom_init_0): Likewise.
+
+Sat Mar 25 09:12:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
+ (ffecom_tree_canonize_ref_): Likewise.
+
+Mon Mar 20 15:49:40 2000 Jim Wilson <wilson@cygnus.com>
+
+ * f/target.h (FFETARGET_32bit_longs): New. Define for alpha, sparc64,
+ and ia64.
+ (ffetargetInteger1, ffetargetLogical1, ffetargetReal1, ffetargetReal2,
+ ffetarget_integerdefault_is_magical): Use FFETARGET_32bit_longs.
+
+Fri Mar 10 00:43:55 2000 Jason Merrill <jason@casey.cygnus.com>
+
+ * com.c (ffecom_stabilize_aggregate_): Don't refer to TREE_RAISES.
+
+Mon Mar 6 18:05:19 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * com.c (ffecom_f2c_set_lio_code_): Use compare_tree_int.
+ (ffecom_sym_transform_, ffecom_transform_common_): Likewise.
+ (ffecom_transform_equiv_): Likewise.
+
+Mon Mar 6 13:01:19 2000 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ansify.c (die_unless): Don't use ANSI string concatenation.
+ (die): Mark with ATTRIBUTE_NORETURN.
+
+Wed Mar 1 00:31:44 2000 Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+ * com.c (current_function_decl): Move to toplev.c.
+
+Sun Feb 27 16:40:33 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * com.c (ffecom_arrayref_): Convert args to size_binop to proper type.
+ (ffecom_tree_canonize_ptr_): Don't use size_binop for non-sizes.
+ (ffecom_tree_canonize_ref_): Likewise.
+ (type_for_mode): Handle TImode.
+ * ste.c (ffeste_io_dofio_, ffeste_io_douio_): Use TYPE_SIZE_UNIT.
+ (ffeste_io_ciclist_): Likewise.
+
+2000-02-23 Zack Weinberg <zack@wolery.cumb.org>
+
+ * com.c (ffecom_type_permanent_copy_): Delete unused function.
+ (finish_decl): Don't change TREE_PERMANENT (DECL_INITIAL (decl)).
+
+Sat Feb 19 18:43:13 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * com.c (ffecom_sym_transform): Use DECL_SIZE_UNIT.
+ (ffecom_transform_common_, ffecom_transform_equiv_): Likewise.
+ (duplicate_decls): Likewise.
+ (ffecom_tree_canonize_ptr_): Delete extra arg to bitsize_int.
+ (finish_decl): Delete -Wlarger-than processing.
+
+Fri Feb 18 13:19:34 2000 Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+ * g77spec.c (lang_specific_driver): Use GCCBUGURL.
+
+2000-02-17 Andy Vaught <andy@maxwell.la.asu.edu>
+
+ * com.c (ffecom_member_phase2_): Re-enable COMMON debug code.
+ (ffecom_finish_symbol_transform_): Likewise.
+ (ffecom_transform_common_): Call ffestorag_set_hook.
+
+Wed Feb 16 11:09:38 2000 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (g77spec.o): Depend on $(GCC_H), not gcc.h.
+
+2000-02-15 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * lang-specs.h: Add new __GNUC_PATCHLEVEL__ define to default spec.
+
+Tue Feb 15 11:14:17 2000 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * g77spec.c: Don't declare `version_string'.
+
+Sat Feb 5 23:27:25 2000 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (mark_tracker_head, mark_binding_level): Protoize.
+
+ * where.c (mark_ffewhere_head): Likewise.
+
+Wed Jan 12 09:32:59 2000 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Pass -lang-fortran to preprocessor.
+
+Thu Dec 30 13:14:31 1999 Richard Henderson <rth@cygnus.com>
+
+ * stw.h (struct _ffestw_): Change type of uses_ to int.
+
+Thu Dec 30 11:42:05 1999 Geoff Keating <geoffk@cygnus.com>
+
+ * com.c (ffecom_init_0): Make double_ftype_double,
+ float_ftype_float, ldouble_ftype_ldouble,
+ ffecom_tree_ptr_to_fun_type_void local.
+ (tracker_head): New static variable.
+ (mark_tracker_head): New, marker procedure for tracker_head.
+ (ffecom_save_tree_forever): New procedure.
+ (ffecom_init_zero_): Remove obstack use.
+ (ffecom_make_gfrt_): Remove obstack use.
+ (ffecom_sym_transform_): Remove obstack use, save appropriate trees.
+ (ffecom_transform_common_): Remove obstack use, save appropriate
+ trees.
+ (ffecom_type_namelist_): Remove obstack use, save appropriate
+ trees.
+ (ffecom_type_vardesc_): Remove obstack use, save appropriate trees.
+ (ffecom_lookup_label): Remove obstack use, save appropriate trees.
+ (duplicate_decls): Remove obstack use.
+ (finish_function): push & pop ggc context around
+ rest_of_compilation when building nested function.
+ (mark_binding_level): New function.
+ (init_decl_processing): Mark all the GC roots.
+ (ggc_p): Set to 1.
+ (lang_mark_tree): New function.
+ (lang_mark_false_label_stack): New trivial function.
+ * com.h (ffecom_save_tree_forever): Declare as external.
+ * lex.c (ffelex_hash_): Use GC to allocate the filename string
+ even when ffelex_kludge_flag_.
+ * ste.c (ffeste_io_ialist_): Register a static root.
+ (ffeste_io_inlist_): Likewise.
+ (ffeste_io_icilist_): Likewise.
+ (ffeste_io_cllist_): Likewise.
+ (ffeste_io_cilist_): Likewise.
+ (ffeste_io_olist_): Likewise.
+ * Makefile.in (OBJS): Don't use ggc-callbacks.o.
+ (OBJDEPS): Likewise.
+ (GGC_H): New variable.
+ Update dependencies.
+ * where.c (ffewhere_head): New global.
+ (mark_ffewhere_head): New marker procedure for ffewhere_head.
+ (ffewhere_file_kill): Use GC to do memory management.
+ (ffewhere_file_new): Use GC to do memory management.
+ * ggc.j: New file.
+
+Wed Dec 29 19:29:26 1999 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * g77.texi (C Interfacing Tools): Fix an incorrect link.
+
+1999-12-13 Jakub Jelinek <jakub@redhat.com>
+
+ * target.h: Handle sparc64 the same way as alpha.
+
+Sun Nov 28 21:39:05 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (ffecom_file_, ffecom_file, file_buf,
+ ffecom_open_include_): Constify a char*.
+ (ffecom_possible_partial_overlap_): Mark parameter `expr2' with
+ ATTRIBUTE_UNUSED.
+ (ffecom_init_0): Use a fully prototyped cast in call to bsearch.
+ (lang_print_error_function): ANSI-fy.
+
+ * com.h (ffecom_file): Constify a char*.
+
+ * fini.c (main): Call return, not exit.
+
+ * g77spec.c (lang_specific_driver): Use non-const *in_argv in
+ assignment.
+
+ * intrin.c (ffeintrin_cmp_name_): Don't needlessly cast away
+ const-ness.
+
+Sun Nov 28 21:15:29 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (ffecom_get_invented_identifier): Rewrite to take an ellipses.
+
+ (ffecom_char_enhance_arg_, ffecom_do_entry_,
+ ffecom_f2c_make_type_, ffecom_gen_sfuncdef_,
+ ffecom_start_progunit_, ffecom_start_progunit_,
+ ffecom_start_progunit_, ffecom_sym_transform_assign_,
+ ffecom_transform_equiv_, ffecom_transform_namelist_,
+ ffecom_vardesc_, ffecom_vardesc_array_, ffecom_vardesc_dims_,
+ ffecom_end_transition, ffecom_lookup_label, ffecom_temp_label):
+ Adjust accordingly.
+
+ * com.h (ffecom_get_invented_identifier): Likewise.
+
+ * sts.c (ffests_printf): New function taking ellipses.
+ (ffests_printf_1D, ffests_printf_1U, ffests_printf_1s,
+ ffests_printf_2Us): Delete.
+
+ * sts.h: Likewise.
+
+ * std.c (ffestd_R1001dump_, ffestd_R1001dump_1005_1_,
+ ffestd_R1001dump_1005_2_, ffestd_R1001dump_1005_3_,
+ ffestd_R1001dump_1005_4_, ffestd_R1001dump_1005_5_,
+ ffestd_R1001dump_1010_2_, ffestd_R1001dump_1010_3_,
+ ffestd_R1001dump_1010_4_, ffestd_R1001dump_1010_5_,
+ ffestd_R1001rtexpr_): Call `ffests_printf', not `ffests_printf_*'.
+
+ * ste.c (ffeste_io_ialist_, ffeste_io_cilist_, ffeste_io_cllist_,
+ ffeste_io_icilist_, ffeste_io_inlist_, ffeste_io_olist_): Likewise.
+
+Wed Nov 10 12:43:21 1999 Philippe De Muyter <phdm@macqel.be>
+ Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * proj.h: Test `GCC_VERSION', not `HAVE_GCC_VERSION'.
+
+Tue Oct 26 01:32:19 1999 Mark Mitchell <mark@codesourcery.com>
+
+ * com.c (poplevel): Don't call remember_end_note.
+
+Fri Oct 15 15:18:12 1999 Greg McGary <gkm@gnu.org>
+
+ * top.h (ffe_is_subscript_check_): Remove extern decl.
+ (ffe_is_subscript_check, ffe_set_is_subscript_check): Remove macros.
+ * top.c (ffe_is_subscript_check_): Remove global variable.
+ (ffe_decode_option): Remove "(no-)bounds-check" flag handling.
+ Set flag_bounds_check for "(no-)fortran-bounds-check".
+ * com.c
+ (ffecom_arrayref_): s/ffe_is_subscript_check ()/flag_bounds_check/
+ (ffecom_char_args_x_): Ditto.
+
+Sun Oct 10 08:40:18 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * proj.h: Use HAVE_GCC_VERSION instead of explicitly testing
+ __GNUC__ and __GNUC_MINOR__. Don't define BUILT_WITH_270. Define
+ macro UNUSED in terms of ATTRIBUTE_UNUSED.
+
+Fri Sep 24 10:48:10 1999 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * com.c (duplicate_decls): Use DECL_BUILT_IN_CLASS rather than
+ DECL_BUILT_IN.
+ (builtin_function): No longer static. New arg CLASS. Arg
+ FUNCTION_CODE now of type int. All callers changed.
+ Set the builtin's DECL_BUILT_IN_CLASS.
+
+Tue Sep 21 09:08:30 1999 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * g77spec.c (lang_specific_driver): Initialize return value.
+
+Thu Sep 16 18:07:11 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bad.c (ffebad_finish): Use uppercase ctype macro from system.h.
+
+ * fini.c (main): Likewise.
+
+ * intrin.c (ffeintrin_init_0): Likewise.
+
+ * lex.c (ffelex_hash_): Likewise.
+
+ * src.c (ffesrc_init_1): Likewise.
+
+Tue Sep 14 12:14:28 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * g77spec.c (lang_specific_driver): Remove unnecessary argument in
+ call to function `fatal'.
+
+Sun Sep 12 23:29:47 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (g77spec.o): Depend on system.h and gcc.h.
+
+ * g77spec.c: Include gcc.h.
+ (g77_xargv): Constify.
+ (g77_fn): Add parameter prototypes.
+ (lookup_option, append_arg): Add static prototypes.
+ (g77_newargv): Constify.
+ (lookup_option, append_arg, lang_specific_driver): Constify a char*.
+ (lang_specific_driver): All calls to the function pointer
+ parameter now explicitly call `fatal'.
+
+Fri Sep 10 10:32:32 1999 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * com.h: Delete declarations for all tree nodes now moved to
+ global_trees.
+ * com.c: Delete their definitions.
+ (ffecom_init_0): Call build_common_tree_nodes and
+ build_common_tree_nodes_2 instead of building their nodes here.
+ Override their decisions for complex nodes.
+
+Sat Sep 4 13:46:27 1999 Mark Mitchell <mark@codesourcery.com>
+
+ * Make-lang.in (f771): Depend on ggc-callbacks.o.
+ * Makefile.in (OBJS): Add ggc-callbacks.o.
+ (OBJDEPS): Likewise.
+
+Mon Aug 30 22:05:53 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (language_string): Constify.
+
+Mon Aug 30 20:29:30 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (LIBS, LIBDEPS): Link with & depend on libiberty.a.
+ Remove hacks for stuff which now comes from libiberty.
+
+Sun Aug 29 09:47:45 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (lang_printable_name): Constify a char*.
+
+Wed Aug 25 01:21:06 1999 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * lang-specs.h: Pass cc1 spec to f771.
+
+Mon Aug 9 19:44:08 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * com.c (lang_print_error_function): Constify a char*.
+ (init_parse): Remove redundant prototype for `print_error_function'.
+ (lang_identify): Constify a char*.
+
+Thu Aug 5 02:40:42 1999 Jeffrey A Law (law@cygnus.com)
+
+ * g77spec.c: Update URLS and mail addresses.
+ * root.texi: Update URLS and mail addresses.
+
+1999-07-25 Richard Henderson <rth@cygnus.com>
+
+ * com.c (ptr_type_node, va_list_type_node): New.
+ (ffecom_init_0): Init and use ptr_type_node.
+
+1999-07-17 Alexandre Oliva <oliva@dcc.unicamp.br>
+
+ * root.texi: Update e-mail addresses to gcc.gnu.org.
+ * g77spec.c (lang_specific_driver): Updated URL with bug reporting
+ instructions to gcc.gnu.org. Removed e-mail address.
+
+Sat Jul 17 11:28:43 1999 Craig Burley <craig@jcb-sc.com>
+
+ * root.texi, g77install.texi: Switchover to GCC terminology.
+ Also, FSF-G77 had been mistakenly set at some point.
+
+Thu Jul 8 15:38:50 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Describe DATE intrinsic fix.
+
+Mon Jun 28 21:44:19 1999 Craig Burley <craig@jcb-sc.com>
+
+ * version.c: Denote experimental version.
+
+Mon Jun 28 10:43:11 1999 Craig Burley <craig@jcb-sc.com>
+
+ * com.c (ffecom_prepare_expr_): A COMPLEX intrinsic needs
+ a temp even if -fno-f2c.
+
+ * version.c: Bump version.
+
+Mon Jun 28 21:31:35 1999 Craig Burley <craig@jcb-sc.com>
+
+ * bugs.texi, news.texi: Doc upgrade to netlib libf2c as of today.
+ Explain that this fixes the NAMELIST-read bug.
+
+Fri Jun 25 11:06:32 1999 Craig Burley <craig@jcb-sc.com>
+
+ * bugs.texi: Describe K(5)=10*3 NAMELIST-read bug.
+
+Mon Jun 21 12:40:17 1999 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
+
+ * g77.texi: Update links.
+
+Mon Jun 21 05:33:51 1999 Jeffrey A Law (law@cygnus.com)
+
+ * news.texi: Add missing @end ifclear.
+
+Fri Jun 18 11:43:46 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Doc TtyNam fix.
+
+Fri Jun 18 11:26:50 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: New heading for development version.
+ Doc upgrade to netlib libf2c as of today.
+
+Wed Jun 16 11:43:02 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Mention BACKSPACE fix to libg2c.
+
+Mon Jun 7 08:42:40 1999 Craig Burley <craig@jcb-sc.com>
+
+ * Make-lang.in: Any target using libsubdir must depend
+ on installdirs.
+
+Sat Jun 5 23:50:36 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Describe a few more missing features people
+ have emailed me about.
+
+Sat Jun 5 17:03:23 1999 Craig Burley <craig@jcb-sc.com>
+
+ From Dave Love to egcs-patches on 20 May 1999 17:38:38 +0100:
+ * g77.texi: Clean up fossil text vis-a-vis Intel CPUs.
+
+Fri Jun 4 13:56:56 1999 Craig Burley <craig@jcb-sc.com>
+
+ * Make-lang.in: Use libsubdir, not prefix, to store
+ temporary lang-f77 `flag' file.
+
+Fri Jun 4 10:26:04 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi (News): Mention GCC 2.95 in favor of EGCS 1.2.
+ Mention that libg2c is multilibbed.
+
+Fri Jun 4 10:09:50 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi (Missing Features): Add `Better Warnings'
+ item.
+
+Fri May 28 16:51:41 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Fix thinko.
+
+Wed May 26 14:43:27 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Document Tue May 18 03:52:04 1999 patch.
+ Fix a grammo.
+
+Wed May 26 14:25:07 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi, news.texi, root.texi, version.c: Start renaming
+ EGCS 1.2 to GCC 2.95, and start using 0.5.25 to designate
+ the version of g77 within GCC 2.95.
+
+Wed May 26 11:45:21 1999 Craig Burley <craig@jcb-sc.com>
+
+ Rename -fsubscript-check to -fbounds-check and
+ -ff2c-subscript-check to -ffortran-bounds-check:
+ * g77.texi: Rename options in docs, clarify usage.
+ * lang-options.h: Rename options, clarify doclets.
+ * news.texi: Rename options, don't bother with fortran-specific
+ option.
+ * top.c (ffe_decode_option): Rename recognized strings.
+
+Tue May 25 18:21:09 1999 Craig Burley <craig@jcb-sc.com>
+
+ * com.c (FFECOM_FASTER_ARRAY_REFS): Delete this vestige,
+ now that -fflatten-arrays exists.
+
+Tue May 25 17:48:34 1999 Craig Burley <craig@jcb-sc.com>
+
+ Fix 19990525-0.f:
+ * com.c (ffecom_arg_ptr_to_expr): Strip off parens around
+ CHARACTER expression.
+ (ffecom_prepare_expr_): Ditto.
+
+Tue May 18 03:52:04 1999 Craig Burley <craig@jcb-sc.com>
+
+ Support use of back end's improved open-coding of complex divide:
+ * com.c (ffecom_tree_divide_): Use RDIV_EXPR for complex divide,
+ instead of run-time call to [cz]_div, if `-Os' option specified.
+ (lang_init_options): Tell back end we want support for wide range
+ of inputs to complex divide.
+
+ * Bump version.
+
+Tue May 18 00:21:34 1999 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * lang-specs.h: Define __GNUC__ and __GNUC_MINOR__ only if -no-gcc
+ was not given.
+
+Thu May 13 12:23:20 1999 Craig Burley <craig@jcb-sc.com>
+
+ Fix INTEGER*8 subscripts in array references:
+ * com.c (ffecom_subscript_check_): Convert low, high, and
+ element as necessary to make comparison work.
+ (ffecom_arrayref_): Do more of the work.
+ Properly handle subscript expr that's wider than int,
+ if pointers are wider than int.
+ (ffecom_expr_): Leave more work to ffecom_arrayref_.
+ (ffecom_init_0): Record sizes of pointers and ints for
+ convenience.
+ Use set_sizetype etc. as done by gcc front end.
+ (ffecom_ptr_to_expr): Leave more work to ffecom_arrayref_.
+ * expr.c (ffeexpr_finished_): Don't convert INTEGER subscript
+ expressions in run-time contexts.
+ (ffeexpr_token_elements_, ffeexpr_token_substring_1_): Cope with
+ non-default INTEGER subscript expressions.
+ * news.texi: Announce.
+
+ Finish accepting -fflatten-arrays option:
+ * com.c (ffecom_arrayref_): Flatten references if requested.
+ * g77.texi: Describe.
+ * lang-options.h: Allow.
+ * news.texi: Announce.
+ * top.c, top.h: Recognize.
+
+ * version.c: Bump version.
+
+Wed May 12 07:30:05 1999 Craig Burley <craig@jcb-sc.com>
+
+ * com.c (lang_init_options): Disable back end's maintenance
+ of errno.
+ * news.texi: Document dropping of errno.
+
+1999-05-10 18:21 -0400 Zack Weinberg <zack@rabi.phys.columbia.edu>
+
+ * lang-specs.h: Pass -$ to the preprocessor.
+
+Mon May 10 18:14:28 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Fix various @xref's per proper style.
+ Go ahead and use nested braces in @xref's, with care.
+ * g77install.texi: Fix @xref per proper style.
+
+Mon May 10 17:38:39 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Doc upgrade to netlib libf2c as of today.
+
+Sun May 9 18:52:13 1999 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * f/g77spec.c (lang_specific_driver): Correct bug-report address
+ and point to the FAQ.
+
+Thu May 6 12:40:21 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi (Arbitrary Concatenation): Put this under
+ "Missing Features" instead of "Projects".
+ (Internals Documentation): Point to new "Front End" chapter.
+
+Thu May 6 08:23:52 1999 Craig Burley <craig@jcb-sc.com>
+
+ * bugs.texi, news.texi: Automatic arrays reportedly working
+ on HP-UX systems.
+
+Thu May 6 08:19:31 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi (Advantages Over f2c): Expand on this topic.
+
+Mon May 3 19:41:48 1999 Craig Burley <craig@jcb-sc.com>
+
+ * com.c (ffecom_expr_intrinsic_): Fix test of CTIME_subr.
+
+Mon May 3 18:11:48 1999 Craig Burley <craig@jcb-sc.com>
+
+ Reverse order of two arguments to CTIME_subr, DTIME_subr,
+ ETIME_subr, and TTYNAM_subr:
+ * com.c (ffecom_expr_intrinsic_): Reverse the arguments.
+ While at it, set TREE_SIDE_EFFECTS for CTIME_subr and
+ TTYNAM_subr.
+ * intdoc.in: Document the new calling sequences.
+ * intrin.def: Reverse the arguments.
+ * news.texi: Document the fact that they changed.
+ * version.c: Bump version.
+
+Mon May 3 11:28:14 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Doc upgrade to netlib libf2c as of today.
+
+Sun May 2 17:04:28 1999 Craig Burley <craig@jcb-sc.com>
+
+ * version.c: Bump version.
+
+Sun May 2 16:53:01 1999 Craig Burley <craig@jcb-sc.com>
+
+ Fix compile/19990502-1.f:
+ * ste.c (ffeste_R819B): Don't overwrite tree for temp
+ variable when expanding the assignment into it.
+
+Sun Apr 25 20:55:10 1999 Craig Burley <craig@jcb-sc.com>
+
+ Fix 19990325-0.f and 19990325-1.f:
+ * com.c (ffecom_possible_partial_overlap_): New function.
+ (ffecom_expand_let_stmt): Use it to determine whether to assign
+ to a COMPLEX operand through a temp.
+ * news.texi: Document fix.
+
+ * version.c: Bump version.
+
+Sat Apr 24 12:19:53 1999 Craig Burley <craig@jcb-sc.com>
+
+ * expr.c (ffeexpr_finished_): Convert DATA implied-do
+ start/end/incr expressions to default INTEGER.
+ Fix some broken conditionals.
+ Clean up some code in the region.
+ * news.c: Document the fix.
+
+ * version.c: Bump version.
+
+Fri Apr 23 02:08:32 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi (Compiler Prototypes): Replace "missing" subscript-
+ checking option with something else.
+
+Fri Apr 23 01:48:28 1999 Craig Burley <craig@jcb-sc.com>
+
+ Support new -fsubscript-check and -ff2c-subscript-check options:
+ * com-rt.def (FFECOM_gfrtRANGE): Describe s_rnge, in libf2c/libF77.
+ * com.c (ffecom_subscript_check_, ffecom_arrayref_): New functions.
+ (ffecom_char_args_x_): Use new ffecom_arrayref_ function for
+ FFEBLD_opARRAYREF case.
+ Compute character name, array type, and use new
+ ffecom_subscript_check_ function for FFEBLD_opSUBSTRING case.
+ (ffecom_expr_): Use new ffecom_arrayref_ function.
+ (ffecom_ptr_to_expr): Use new ffecom_arrayref_ function.
+ * g77.texi, news.texi: Document new options.
+ * top.c, top.h: Support new options.
+
+ * news.texi: Fix up some items to not be in "User-Visible Changes".
+
+ * ste.c (ffeste_R819B): Fix type for loop variable, to avoid
+ warnings.
+
+ * version.c: Bump version.
+
+Tue Apr 20 01:38:57 1999 Craig Burley <craig@jcb-sc.com>
+
+ * bugs.texi, news.texi: Clarify -malign-double situation.
+
+Tue Apr 20 01:15:25 1999 Craig Burley <craig@jcb-sc.com>
+
+ * stb.c (ffestb_R5282_): Convert DATA repeat count
+ to default INTEGER, to avoid problems downstream.
+
+ * version.c: Bump version.
+
+Mon Apr 19 21:36:48 1999 Craig Burley <craig@jcb-sc.com>
+
+ * ste.c (ffeste_R819B): Start the loop before expanding
+ the termination expression.
+
+ * version.c: Bump version.
+
+Sun Apr 18 21:53:58 1999 Craig Burley <craig@jcb-sc.com>
+
+ * com.c (ffecom_sym_transform_): COMMON and EQUIVALENCE
+ variables have constant addresses (EQUIVALENCE only if
+ containing aggregate is static).
+
+Sat Apr 17 16:55:59 1999 Craig Burley <craig@jcb-sc.com>
+
+ * bugs.texi, ffe.texi, g77.texi, g77install.texi, news.texi:
+ Clean up @code{} vs. @samp{}.
+ Clean up dashes (`--') vs. @minus{} vs. `---'.
+
+ * ffe.texi: Add copyright header.
+
+ * g77.texi, lang-options.h, news.texi, top.c (ffe_decode_option):
+ Remove support for -fugly option.
+ Clarify that -fugly-logint is needed instead of -fugly
+ to work around using .EQ./.NE. on LOGICAL operands.
+ Explain more about why -fugly-logint is bad juju.
+
+ * g77.texi (Missing Features): Describe READONLY as a missing
+ feature. Describe AUTOMATIC better.
+
+ * news.texi: Mention libf2c upgrade.
+
+Sat Apr 17 14:05:53 1999 Craig Burley <craig@jcb-sc.com>
+
+ Make a place for front-end internals documentation:
+ * Make-lang.in (f/g77.info, f/g77.dvi): Depend on f/ffe.texi.
+ * ffe.texi: New file, containing docs on front-end internals.
+ * g77.texi: New chapter for, and inclusion of, ffe.texi.
+
+ * g77.texi: Fix an index entry.
+
+Sat Apr 17 13:53:43 1999 Craig Burley <craig@jcb-sc.com>
+
+ Rewrite to use block/scope structure of GBE and to ensure
+ variables (especially those going on stack/reg) are declared
+ before executable code generated:
+ * bld.c (ffebld_new_item, ffebld_new_one, ffebld_new_two):
+ Support new hooks.
+ * bld.h (ffebld_item_hook, ffebld_item_set_hook,
+ ffebld_nonter_hook, ffebld_nonter_set_hook): Ditto.
+ * bld.h (ffebld_basictype, ffebld_kind, ffebld_kindtype,
+ ffebld_rank, ffebld_where): New convenience macros (used
+ by rest of this patch).
+ * com.c, com.h (ffecom_push_calltemps, ffecom_pop_calltemps,
+ ffecom_push_tempvar, ffecom_pop_tempvar): Remove temp-var-
+ handling mechanism.
+ * com.c (ffecom_call_, ffecom_call_binop_, ffecom_tree_divide_,
+ ffecom_call_gfrt): Support passing hooks for temp-var info.
+ (ffecom_expr_power_integer_): Takes opPOWER expression, instead
+ of its left and right operands, so it can get at the hook.
+ (ffecom_prepare_let_char_, ffecom_prepare_arg_ptr_to_expr,
+ ffecom_prepare_end, ffecom_prepare_expr_, ffecom_prepare_expr_rw,
+ ffecom_prepare_expr_w, ffecom_prepare_return_expr,
+ ffecom_prepare_ptr_to_expr): New functions supporting expression
+ pre-scanning.
+ (bison_rule_compstmt_): Return the tree, as in the CFE.
+ (delete_block): New function, from CFE.
+ (kept_level_p): New function, from CFE, modified.
+ (ffecom_start_compstmt, ffecom_end_compstmt): New functions,
+ replacing ffecom_start_compstmt_ and ffecom_end_compstmt_ macros,
+ and they do real work.
+ (struct binding_level): Add prep_state member. Initialize to 0.
+ (ffecom_get_invented_identifier): Now takes either or both a
+ string and an integer, using -1 to denote no integer.
+ (ffecom_do_entry_): Disallow temp-var generation via expressions
+ in body of function, since the exprs aren't prescanned.
+ (ffecom_expr_rw): Now takes destination tree.
+ (ffecom_expr_w): New function, now used in some places
+ ffecom_expr_rw had been used.
+ (ffecom_expr_intrinsic_): Move huge f2c-related comment to bottom
+ of source file, to avoid annoying problems editing com.c using
+ Emacs C-mode.
+ (ffecom_expr_power_integer_): Make a temp var for division, if
+ necessary.
+ Handle expanded statement expression as does CFE.
+ (ffecom_start_progunit_): Disallow temp-var generation in body
+ of function, since expressions are not prescanned at this level.
+ (ffecom_sym_transform_): Transform ASSIGN variables as well,
+ so these are all transformed up front, before code-generation
+ begins.
+ (ffecom_arg_ptr_to_const_expr, ffecom_const_expr,
+ ffecom_ptr_to_const_expr): New functions to transform expressions
+ only if the results will surely be constants.
+ (ffecom_arg_ptr_to_expr): Precompute size, for convenience
+ obtaining temp vars.
+ (ffecom_expand_let_stmt): Guess at usability of destination
+ pre-expansion, to provide better prescan preparation (fewer
+ spurious temp vars).
+ (ffecom_init_0): Disallow temp-var generation in global scope.
+ (ffecom_type_expr): New function, returns just the type tree
+ for the expression.
+ (start_function): Disallow temp-var generation in parm scope.
+ (incomplete_type_error): Fix introductory comment.
+ (poplevel): Update (somewhat) from CFE.
+ (pushlevel): Update (somewhat) from CFE.
+ * stc.c (ffestc_R838): Mark ASSIGNed variable as so.
+ * std.c (ffestd_stmt_pass_, ffestd_R803, ffestd_R804, ffestd_R805,
+ ffestd_R806): Remember and pass through the ffestw block info
+ for these (IFTHEN, ELSEIF, ELSE, and ENDIF) statements.
+ * ste.c (ffeste_end_iterdo_): Now takes ffestw block argument.
+ (ffeste_io_inlist_): Add prototype.
+ (ffeste_f2c_*): Macros rewritten, new ones added.
+ (ffeste_start_block_, ffeste_end_block_, ffeste_start_stmt_,
+ ffeste_end_stmt_): New macros/functions, depending on whether
+ checking is enabled, to keep track of symmetry of other ste.c code.
+ (ffeste_begin_iterdo_, ffeste_end_iterdo_, ffeste_io_impdo_,
+ ffeste_io_dofio_, ffeste_io_dolio_, ffeste_io_douio_,
+ ffeste_io_ialist_, ffeste_io_cilist_, ffeste_io_cllist_,
+ ffeste_icilist_, ffeste_io_inlist_, ffeste_io_olist_,
+ ffeste_subr_beru_, ffeste_do, ffeste_end_R807, ffeste_R737A,
+ ffeste_R803, ffeste_R804, ffeste_R805, ffeste_R806, ffeste_R807,
+ ffeste_R809, ffeste_R810, ffeste_R811, ffeste_R819A, ffeste_R819B,
+ ffeste_R837, ffeste_R838, ffeste_R839, ffeste_R840, ffeste_R904,
+ ffeste_R907, ffeste_R909_start, ffeste_R909_item, ffeste_R909_finish,
+ ffeste_R910_start, ffeste_R910_item, ffeste_R910_finish,
+ ffeste_R911_start, ffeste_R911_item, ffeste_R911_finish,
+ ffeste_R923A, ffeste_R1212, ffeste_R1227): Prescan/prepare
+ all pertinent expressions, update to new com.c interface, etc.
+ (ffeste_io_impdo_): Relocate.
+ (ffeste_R834, ffeste_R835, ffeste_R836, ffeste_R1226): Don't
+ bother calling clear_momentary, nothing was generated.
+ (ffeste_R842, ffeste_R843): Update to new com.c interface.
+ (ffeste_R1226): Don't try to stuff error_mark_node's DECL_INITIAL.
+ (ffeste_terminate_2): When checking enabled, make sure all blocks
+ and statements have been ended.
+ * ste.h (ffeste_R803, ffeste_R804, ffeste_R805, ffeste_R806):
+ These now take ffestw block argument.
+ (ffeste_terminate_2): When checking enabled, it's a function, not
+ a macro.
+ * stw.h (struct _ffestw_): New variable for IFTHEN.
+ (ffestw_ifthen_fake_else, ffestw_set_ifthen_fake_else): New
+ accessor macros.
+ * symbol.c, symbol.h: Support new ASSIGN'ed-to info.
+
+ * com.c: Clean up commentary per GNU coding standards.
+
+ * bld.h (ffebld_size, ffebld_size_known): Canonize.
+
+ * version.c: Bump version.
+
+Sun Apr 11 21:33:33 1999 Mumit Khan <khan@xraylith.wisc.edu>
+
+ * g77spec.c (lang_specific_driver): Check whether MATH_LIBRARY is
+ null to decide whether to use it.
+
+Wed Apr 7 09:47:09 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ansify.c (die): Specify void argument.
+
+ * intdoc.c (family_name, dumpgen, dumpspec, dumpimp,
+ argument_info_ptr, argument_info_string, argument_name_ptr,
+ argument_name_string, elaborate_if_complex,
+ elaborate_if_maybe_complex, elaborate_if_real, print_type_string):
+ Const-ify a char*.
+ (main): Mark parameter `argv' with ATTRIBUTE_UNUSED.
+ (_ffeintrin_name_, _ffeintrin_gen_, _ffeintrin_spec_,
+ _ffeintrin_imp_, cc_pair, descriptions, summaries): Const-ify a char*.
+
+Mon Apr 5 11:57:54 1999 Donn Terry (donn@interix.com)
+
+ * Make-lang.in (HOST_CFLAGS): compute dynamically.
+
+Mon Apr 5 02:11:23 1999 Craig Burley <craig@jcb-sc.com>
+
+ Fix bugs exposed by configuring with --enable-checking:
+ * com.c (ffecom_do_entry_, ffecom_expr_, ffecom_arg_ptr_to_expr,
+ ffecom_list_expr, ffecom_list_ptr_to_expr, finish_function,
+ pop_f_function_context, store_parm_decls, poplevel): Handle
+ error_mark_node properly.
+ * ste.c (ffeste_begin_iterdo_, ffeste_end_iterdo_): Ditto.
+ * version.c: Bump version.
+
+Sat Apr 3 23:57:56 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Fix up docs for -fset-g77-defaults, and
+ describe how internal consistency checking now happens.
+ (Should have been done for EGCS version 1.1.)
+
+Sat Apr 3 23:29:33 1999 Craig Burley <craig@jcb-sc.com>
+
+ * bugs.texi, g77.texi, lang-options.h, news.texi, top.c:
+ Make -fno-emulate-complex the default, as COMPLEX support
+ in the back end is now believed to be working.
+
+ * version.c: Bump version.
+
+Fri Apr 2 13:33:16 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: -malign-double now works.
+ Give URL for alignment-testing package.
+ * news.texi: -malign-double now works.
+
+Fri Apr 2 12:49:12 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi (Funding GNU Fortran): Dude's got a web page.
+ * root.texi: Ditto.
+
+Tue Mar 30 12:04:11 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * sta.c (ffesta_ffebad_1sp, ffesta_ffebad_1st, ffesta_ffebad_2st):
+ Const-ify a char*.
+
+ * sta.h (ffesta_ffebad_1sp, ffesta_ffebad_1st, ffesta_ffebad_2st):
+ Likewise.
+
+ * stb.c (ffestb_local_u_): Likewise.
+ (ffestb_do, ffestb_dowhile, ffestb_else, ffestb_elsexyz,
+ ffestb_else3_, ffestb_endxyz, ffestb_goto, ffestb_let,
+ ffestb_type, ffestb_type1_, ffestb_varlist, ffestb_R423B,
+ ffestb_R522, ffestb_R528, ffestb_R542, ffestb_R834, ffestb_R835,
+ ffestb_R838, ffestb_R841, ffestb_R1102, ffestb_blockdata,
+ ffestb_R1212, ffestb_R1228, ffestb_V009, ffestb_module,
+ ffestb_R809, ffestb_R810, ffestb_R10014_, ffestb_R10015_,
+ ffestb_R10018_, ffestb_R1107, ffestb_R1202, ffestb_R12026_,
+ ffestb_S3P4, ffestb_V012, ffestb_V014, ffestb_V025, ffestb_V0255_,
+ ffestb_V020, ffestb_dimlist, ffestb_dummy, ffestb_R524,
+ ffestb_R547, ffestb_decl_chartype, ffestb_decl_dbltype,
+ ffestb_decl_gentype, ffestb_decl_recursive, ffestb_decl_entsp_2_,
+ ffestb_decl_func_, ffestb_V003, ffestb_V016, ffestb_V027,
+ ffestb_decl_R539): Likewise.
+
+ * stb.h (_ffestb_args_): Likewise.
+
+ * stc.c (ffestc_subr_binsrch_, ffestc_subr_is_present_,
+ ffestc_subr_speccmp_, ffestc_R904, ffestc_R907): Likewise.
+
+ * std.c (ffestd_R1001dump_1005_1_, ffestd_R1001dump_1005_2_,
+ ffestd_R1001dump_1005_3_, ffestd_R1001dump_1005_4_,
+ ffestd_R1001dump_1005_5_, ffestd_R1001dump_1010_1_,
+ ffestd_R1001dump_1010_2_, ffestd_R1001dump_1010_3_,
+ ffestd_R1001dump_1010_4_, ffestd_R1001dump_1010_5_): Likewise.
+
+ * ste.c (ffeste_begin_iterdo_, ffeste_subr_file_): Likewise.
+
+ * sts.c (ffests_printf_1D, ffests_printf_1U, ffests_printf_1s,
+ ffests_printf_2Us, ffests_puts, ffests_puttext): Likewise.
+
+ * sts.h (ffests_printf_1D, ffests_printf_1U, ffests_printf_1s,
+ ffests_printf_2Us, ffests_puts, ffests_puttext): Likewise.
+
+ * stt.c (ffestt_exprlist_drive, ffestt_implist_drive,
+ ffestt_tokenlist_drive): Add prototype arguments.
+
+ * stt.h (ffestt_exprlist_drive, ffestt_implist_drive,
+ ffestt_tokenlist_drive): Likewise.
+
+ * stu.c (ffestu_dummies_transition_): Likewise.
+ (ffestu_sym_end_transition): Const-ify a char*.
+
+ * stw.c (ffestw_display_state, ffestw_new, ffestw_pop): Add
+ prototype arguments.
+
+ * stw.h (ffestw_display_state, ffestw_new, ffestw_pop): Likewise.
+
+ * version.c (ffe_version_string): Const-ify a char*.
+
+ * version.h (ffe_version_string): Likewise.
+
+Sat Mar 27 13:00:43 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bad.c (_ffebad_message_, ffebad_string_, ffebad_message_,
+ ffebad_bufputs_, ffebad_bufputs_, ffebad_start_, ffebad_string,
+ ffebad_finish): Const-ify a char*.
+
+ * bld.c (ffebld_op_string_, ffebld_op_string): Likewise.
+
+ * bld.h (ffebld_op_string): Likewise.
+
+ * com.c (ffecom_arglist_expr_, ffecom_build_f2c_string_,
+ ffecom_debug_kludge_, ffecom_f2c_make_type_,
+ ffecom_get_appended_identifier_, ffecom_get_identifier_,
+ ffecom_gfrt_args_): Likewise.
+ (ffecom_convert_narrow_, ffecom_convert_widen_): Add prototype.
+ (builtin_function, ffecom_gfrt_name_, ffecom_gfrt_argstring_,
+ ffecom_arglist_expr_, ffecom_build_f2c_string_,
+ ffecom_debug_kludge_, ffecom_f2c_make_type_,
+ ffecom_get_appended_identifier_, ffecom_get_external_identifier_,
+ ffecom_get_identifier_, ffecom_decl_field,
+ ffecom_get_invented_identifier, lang_print_error_function,
+ skip_redundant_dir_prefix, read_name_map, print_containing_files):
+ Const-ify a char*.
+ (savestring): Remove, use `xstrdup' instead.
+
+ * com.h (ffecom_decl_field, ffecom_get_invented_identifier):
+ Const-ify a char*.
+
+ * data.c (ffebld, ffedata_gather_): Make explicitly static.
+
+ * expr.c (ffeexpr_isdigits_, ffeexpr_percent_,
+ ffeexpr_reduced_concatenate_, ffeexpr_nil_real_,
+ ffeexpr_nil_number_, ffeexpr_nil_number_period_,
+ ffeexpr_nil_number_real_, ffeexpr_token_real_,
+ ffeexpr_token_number_, ffeexpr_token_number_period_,
+ ffeexpr_token_number_real_): Const-ify a char*.
+
+ * fini.c (xspaces): Likewise.
+
+ * global.c (ffeglobal_type_string_): Likewise.
+ (ffeglobal_drive): Protoize.
+ (ffeglobal_proc_def_arg): Const-ify a char*.
+
+ * global.h (ffeglobal_drive): Protoize.
+ (ffeglobal_proc_def_arg): Const-ify a char*.
+
+ * implic.c (ffeimplic_none, ffeimplic_peek_symbol_type):
+ Likewise.
+
+ * implic.h (ffeimplic_peek_symbol_type): Likewise.
+
+ * info.c (ffeinfo_basictype_string_, ffeinfo_kind_message_,
+ ffeinfo_kind_string_, ffeinfo_kindtype_string_,
+ ffeinfo_where_string_, ffeinfo_basictype_string,
+ ffeinfo_kind_message, ffeinfo_kind_string,
+ ffeinfo_kindtype_string, ffeinfo_where_string): Likewise.
+
+ * info.h (ffeinfo_basictype_string, ffeinfo_kind_message,
+ ffeinfo_kind_string, ffeinfo_kindtype_string,
+ ffeinfo_where_string): Likewise.
+
+ * intrin.c (_ffeintrin_name_, _ffeintrin_gen_, _ffeintrin_spec_,
+ _ffeintrin_imp_, ffeintrin_check_, ffeintrin_cmp_name_,
+ ffeintrin_fulfill_specific, ffeintrin_init_0,
+ ffeintrin_is_actualarg, ffeintrin_is_intrinsic,
+ ffeintrin_name_generic, ffeintrin_name_implementation,
+ ffeintrin_name_specific): Likewise.
+
+ * intrin.h (ffeintrin_is_intrinsic, ffeintrin_name_generic,
+ ffeintrin_name_implementation, ffeintrin_name_specific): Likewise.
+
+ * lex.c (ffelex_type_string_, ffelex_token_new_character,
+ ffelex_token_new_name, ffelex_token_new_names,
+ ffelex_token_new_number): Likewise.
+
+ * lex.h (ffelex_token_new_character, ffelex_token_new_name,
+ ffelex_token_new_names, ffelex_token_new_number): Likewise.
+
+ * malloc.c (malloc_types_, malloc_pool_new, malloc_new_inpool_,
+ malloc_new_zinpool_): Likewise.
+
+ * malloc.h (malloc_new_inpool_, malloc_new_zinpool_,
+ malloc_pool_new): Likewise.
+
+ * name.c (ffename_space_drive_global, ffename_space_drive_symbol):
+ Protoize.
+
+ * name.h (ffename_space_drive_global, ffename_space_drive_symbol):
+ Likewise.
+
+ * symbol.c (ffesymbol_state_name_, ffesymbol_attr_name_,
+ ffesymbol_attrs_string): Const-ify a char*.
+ (ffesymbol_drive, ffesymbol_drive_sfnames): Protoize.
+ (ffesymbol_state_string): Const-ify a char*.
+
+ * symbol.h (ffesymbol_attrs_string): Likewise.
+ (ffesymbol_drive, ffesymbol_drive_sfnames): Protoize.
+ (ffesymbol_state_string): Const-ify a char*.
+
+ * target.c (ffetarget_layout): Likewise.
+
+ * target.h (ffetarget_layout): Likewise.
+
+1999-03-25 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * Make-lang.in: Remove all references to g77.o/g77.c.
+ Link g77 from gcc.o.
+
+1999-03-21 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Makefile.in (g77$(exeext)): Depend on intl.o. Link in intl.o.
+
+Wed Mar 17 11:39:44 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Editorial fix.
+
+Mon Mar 15 17:12:07 1999 Craig Burley <craig@jcb-sc.com>
+
+ * bugs.texi, g77.texi, news.texi: Editorial fixes.
+
+Sat Mar 13 17:51:55 1999 Craig Burley <craig@jcb-sc.com>
+
+ Fix 19990313-0.f, 19990313-1.f, 19990313-2.f, 19990313-3.f:
+ * bad.def (FFEBAD_NOCANDO): New error code for internal use only.
+ * expr.c (ffeexpr_collapse_convert): If FFEBAD_NOCANDO returned
+ by convertor, just return original expr.
+ * target.h: Return FFEBAD_NOCANDO for (usually) 64-bit
+ conversions that aren't yet working properly.
+ * news.texi: Explain.
+
+ * version.c: Bump version.
+
+Sat Mar 13 14:26:55 1999 Craig Burley <craig@jcb-sc.com>
+
+ * RELEASE-PREP: New file, lists things to do for a release.
+
+ * Make-lang.in, bugs.texi, bugs0.texi, g77.texi, g77install.texi,
+ install0.texi, news.texi, news0.texi: Accommodate new doc
+ architecture.
+ Consolidate news items. Don't describe old news items in
+ various generated docs.
+ Don't describe FSF-g77 installation stuff in various EGCS-g77
+ generated docs.
+ Move description of AUTOMATIC to more suitable location.
+ * root.texi: New file for new doc architecture.
+
+Thu Mar 11 17:32:55 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Add AUTOMATIC to list of unsupported extensions.
+
+Sat Mar 6 02:28:35 1999 Craig Burley <craig@jcb-sc.com>
+
+ Warn about non-Y2K-compliant intrinsics:
+ * bad.def (FFEBAD_INTRINSIC_Y2KBAD): New diagnostic.
+ * intrin.def (FFEINTRIN_impDATE, FFEINTRIN_impIDATE_vxt):
+ Use new DEFIMPY macro to flag these as non-Y2K-compliant.
+ * intdoc.c (DEFIMPY): Support new Y2K macro.
+ * intrin.h (DEFIMPY): Ditto.
+ * intrin.c (DEFIMPY): Ditto.
+ (ffeintrin_fulfill_generic, ffeintrin_fulfill_specific):
+ Warn about invocation of non-Y2K-compliant intrinsic.
+ * com-rt.def (FFECOM_gfrtDATE, FFECOM_gfrtVXTIDATE):
+ Rename external procedure names, to keep previously-
+ compiled (sans-new-warnings) code from linking to
+ new library.
+ * g77.texi: Document all this stuff.
+ * news.texi: Spread the joy.
+ * version.c: Bump version.
+
+Fri Mar 5 13:22:44 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Relocate IDATE (VXT) fix: we put it in 1.1.2
+ so describe it there, instead of under 1.2.
+
+Wed Mar 3 00:57:56 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: IDATE (VXT) fixed to return year as 0..99.
+
+Wed Mar 3 00:43:49 1999 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Add remaining changes pending from Dave Love.
+
+Wed Mar 3 00:38:42 1999 Craig Burley <craig@jcb-sc.com>
+
+ * bugs.texi, news.texi: Conditionalize cross-references
+ on non-html processing, providing temporary HTML "links".
+
+ * g77.texi: Fix up a reference.
+
+Wed Mar 3 00:12:31 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi, bugs.texi: Delete fixed bugs, make one
+ of them into the appropriate news item.
+
+Wed Mar 3 00:05:52 1999 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Copy over 1.1.2 news.
+
+1999-03-02 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi (Bug Reporting): Clarify whether to use -E.
+ Clarify other instructions.
+
+1999-02-27 Craig Burley <craig@jcb-sc.com>
+
+ * lang-specs.h: Fix specs to pass `-ax' as well as `-a' option.
+
+1999-02-26 Craig Burley <craig@jcb-sc.com>
+
+ * intdoc.in (STAT_func, STAT_subr,
+ FSTAT_func, FSTAT_subr, LSTAT_func, LSTAT_subr):
+ Properly order array elements. Specify N/A return values.
+
+1999-02-26 Craig Burley <craig@jcb-sc.com>
+
+ * intdoc.in (DATE_AND_TIME): Explain that VALUES(7) holds
+ seconds, and VALUES(8), therefore, milliseconds.
+
+1999-02-26 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Clarify IOSTAT= fix.
+
+1999-02-25 Richard Henderson <rth@cygnus.com>
+
+ * lang-specs.h: Define __FAST_MATH__ when appropriate.
+
+1999-02-25 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Clarify/index lack of run-time allocation for
+ concatenation.
+
+1999-02-25 Andreas Jaeger <aj@arthur.rhein-neckar.de>
+
+ * f/intdoc.in: Add missing `,' after cross references.
+
+1999-02-20 Craig Burley <craig@jcb-sc.com>
+
+ * Make-lang.in (f77.install-common, f77.install-info,
+ f77.install-man, f77.uninstall): Use `$(prefix)/lang-f77'
+ instead of `lang-f77' for flag file, to be sure of a
+ writable directory, and remove the flag file after each
+ operation to keep things clean.
+
+1999-02-20 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Properly attribute Priest document; clarify
+ that it is in the .ps version of the Goldberg document.
+
+1999-02-19 Craig Burley <craig@jcb-sc.com>
+
+ * bugs0.texi, bugs.texi, install0.texi, g77install.texi,
+ news0.texi, news.texi: Update copyright dates.
+ Clarify which files are source, which are derived,
+ and remind maintainers where copyright dates are sourced.
+ * BUGS, INSTALL, NEWS: Regenerated.
+
+1999-02-19 Craig Burley <craig@jcb-sc.com>
+
+ * global.c (ffeglobal_ref_progunit_): Warn about a function
+ definition that disagrees with the type of a previous reference.
+ Improve commentary. Fix a couple of minor bugs. Clean up
+ some code.
+ * news.texi: Spread the joy.
+
+1999-02-18 Craig Burley <craig@jcb-sc.com>
+
+ * expr.c (ffeexpr_finished_): Disallow non-default INTEGER
+ as argument for FILEINT and FILEASSOC as lhs.
+ * news.texi: Document fix.
+ * version.c: Bump.
+
+1999-02-18 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi: Clarify -fno-globals vs. -Wno-globals.
+
+1999-02-18 Craig Burley <craig@jcb-sc.com>
+
+ * intdoc.in (LOG10): Fix typo.
+
+1999-02-17 Ulrich Drepper <drepper@cygnus.com>
+
+ * intdoc.in: Fix typo.
+
+1999-02-17 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi, intdoc.in: Document Y2K and some other known
+ limitations.
+ * intrin.def (DTIME, FDATE): Fix capitalization of
+ case-sensitive forms of these intrinsics' names.
+
+1999-02-17 Dave Love <fx@gnu.org>
+
+ * intdoc.in: Say `common' logarithm for log10.
+
+1999-02-16 Ulrich Drepper <drepper@cygnus.com>
+
+ * g77.texi: Add missing @ in email addresses.
+
+1999-02-15 Craig Burley <craig@jcb-sc.com>
+
+ * *.*: Delete my (old) email address in most places, change it
+ in a few.
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * version.c: Bump.
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * version.c: Bump for 1998-10-02 change (forgot to do this
+ before).
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * lang-specs.h, g77.1, g77.texi, news.texi: Recognize `.FOR'
+ and `.FPP' as well as `.for' and `.fpp'.
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * intdoc.in (LOG10): Fix description.
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * news.texi: Mention fix for SIGNAL invocation circa egcs-1.1.
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * g77.texi, g77install.texi, bugs.texi, g77install.texi: Clean
+ up and improve indexing, and some other areas of docs.
+
+1999-02-14 Craig Burley <craig@jcb-sc.com>
+
+ * intdoc.in (MCLOCK8, TIME8): Warn about lower range on
+ 32-bit systems.
+
+Sat Feb 6 18:02:17 1999 Jeffrey A Law (law@cygnus.com)
+
+ * g77.texi: Update email addresses.
+
+Wed Feb 3 22:50:17 1999 Marc Espie <Marc.Espie@liafa.jussieu.fr>
+
+ * Make-lang.in (g77$(exeext)): Get choose-temp.o, pexecute.o and
+ mkstemp.o from libiberty.
+
+1999-02-01 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * top.c: Don't define ffe_is_ident_. Don't process
+ -f(no-)ident here.
+ * top.h: Remove declaration of ffe_is_ident_ and macros
+ ffe_is_ident() and ffe_set_is_ident().
+ * lex.c: Use flag_no_ident instead of ffe_is_ident().
+
+Sun Jan 31 20:34:29 1999 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * lang-specs.h: Map -Qn to -fno-ident.
+
+Tue Jan 5 22:12:41 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Make-lang.in (g77.o): Depend on prefix.h.
+
+Fri Nov 27 13:10:32 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fini.c: Rename variable `spaces' to `xspaces' to avoid
+ conflicting with function `spaces' from libiberty.
+
+ * g77spec.c: Don't prototype libiberty functions.
+ * malloc.c: Likewise.
+
+1998-11-20 Dave Love <d.love@dl.ac.uk>
+
+ * g77.texi: Assorted minor changes.
+
+1998-11-19 Dave Love <d.love@dl.ac.uk>
+
+ * bugs.texi: Formatting changes from Craig.
+
+ * intdoc.in: Terminate some @xrefs with `,'.
+
+1998-11-19 Manfred Hollstein <manfred@s-direktnet.de>
+
+ * Make-lang.in (mandir): Replace all uses of $(mandir) by $(man1dir).
+
+Mon Nov 9 23:15:39 1998 Jeffrey A Law (law@cygnus.com)
+
+ * g77.texi, news.texi: Updates from Craig.
+
+Sun Nov 8 17:47:56 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * Makefile.in (INCLUDES): Add "-I$(srcdir)/../../include".
+
+Sat Nov 7 15:58:54 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * g77spec.c: Don't include gansidecl.h.
+ * output.j: Likewise.
+
+1998-11-04 Dave Love <d.love@dl.ac.uk>
+
+ * g77.texi: Small formatting/indexing fixes.
+
+Mon Oct 12 20:41:59 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * bad.c (ffebad_finish): Change type of variable `c' to unsigned
+ char, change type of variable `s' to unsigned char *.
+
+ * com.c (ffecom_symbol_null_): Add missing initializers.
+
+ * fini.c (MAXNAMELEN): Undef it before defining.
+
+ * implic.c (ffeimplic_lookup_): Change type of parameter `c' to
+ unsigned char.
+
+ * intrin.c (ffeintrin_init_0): Cast the argument of ctype macros
+ to (unsigned char).
+
+ * lex.c (ffelex_splice_tokens): Change type of variable `p' to
+ unsigned char *.
+ (ffelex_token_name_from_names): Cast the argument of
+ `ffelex_is_firstnamechar' to (unsigned char).
+ (ffelex_token_names_from_names): Likewise.
+ (ffelex_token_new_name): Likewise.
+ (ffelex_token_new_names): Likewise.
+
+ * malloc.c (malloc_root_): Add missing initializer.
+
+ * stb.c (ffestb_do): Change type of variable `p' to unsigned char *.
+ (ffestb_else) Likewise.
+ (ffestb_else3_) Likewise.
+ (ffestb_endxyz) Likewise.
+ (ffestb_goto) Likewise.
+ (ffestb_let) Likewise.
+ (ffestb_varlist) Likewise.
+ (ffestb_R522) Likewise.
+ (ffestb_R528) Likewise.
+ (ffestb_R834) Likewise.
+ (ffestb_R835) Likewise.
+ (ffestb_R838) Likewise.
+ (ffestb_R1102) Likewise.
+ (ffestb_blockdata) Likewise.
+ (ffestb_R1212) Likewise.
+ (ffestb_R810) Likewise.
+ (ffestb_R10014_): Cast the argument of `ffelex_is_firstnamechar'
+ to (unsigned char).
+ (ffestb_V014): Change type of variable `p' to unsigned char *.
+ (ffestb_dummy) Likewise.
+ (ffestb_R524) Likewise.
+ (ffestb_R547) Likewise.
+ (ffestb_decl_chartype) Likewise.
+ (ffestb_decl_dbltype) Likewise.
+ (ffestb_decl_gentype) Likewise.
+ (ffestb_decl_entsp_2_) Likewise.
+ (ffestb_V027) Likewise.
+ (ffestb_decl_R539) Likewise.
+
+ * top.c (ffe_decode_option): Mark parameter `argc' with
+ ATTRIBUTE_UNUSED.
+
+ * where.c (ffewhere_unknown_line_): Add missing initializers.
+
+1998-10-02 Dave Love <d.love@dl.ac.uk>
+
+ * com.c (ffecom_expr_intrinsic_): Fix return type for RAND.
+
+Thu Oct 1 10:43:45 1998 Nick Clifton <nickc@cygnus.com>
+
+ * lex.c: Replace occurances of HANDLE_SYSV_PRAGMA with
+ HANDLE_GENERIC_PRAGMAS.
+
+Mon Sep 28 04:22:00 1998 Jeffrey A Law (law@cygnus.com)
+
+ * news.texi: Update from Craig.
+
+1998-09-23 Dave Love <d.love@dl.ac.uk>
+
+ * g77.texi: Additions about `/*', trailing comments and cpp.
+
+1998-09-18 Dave Love <d.love@dl.ac.uk>
+
+ * g77.texi: Various additions and some small fixes.
+
+Thu Sep 10 14:55:44 1998 Kamil Iskra <iskra@student.uci.agh.edu.pl>
+
+ * Make-lang.in (f77.install-common): Add missing "else true;".
+
+1998-09-07 Dave Love <d.love@dl.ac.uk>
+
+ * ChangeLog.egcs: Deleted. Entries merged here.
+
+1998-09-05 Dave Love <d.love@dl.ac.uk>
+
+ * Makefile.in (LDFLAGS): Set from BOOT_LDFLAGS.
+ (F771_LDFLAGS): Variable dispensed with.
+
+Fri Sep 4 19:53:34 1998 Craig Burley <burley@gnu.org>
+
+ * intdoc.in: Minor editorial tweaks.
+
+Fri Sep 4 18:35:52 1998 Craig Burley <burley@gnu.org>
+
+ * lang-options.h: Convert to wrap option and doc string
+ in a new macro invocation, FTNOPT, so the nearly identical
+ list can be used in FSF-g77.
+
+Fri Sep 4 18:35:52 1998 Craig Burley <burley@gnu.org>
+
+ * Makefile.in (fini.o): Don't define USE_HCONFIG here.
+ * fini.c: Define USE_HCONFIG here instead, so deps-kinda
+ picks up correct dependency.
+
+ * Makefile.in (proj-h.o): Fix dependencies list.
+
+Wed Sep 02 09:25:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * lex.c (ffe_lex_hash): Change how HANDLE_PRAGMA and
+ HANDLE_SYSV_PRAGMA would be called if they pragma parsing was
+ enabled in this code.
+ Generate warning messages if unknown pragmas are encountered.
+ (pragma_getc): New function: retrieves characters from the
+ input stream. Defined when HANDLE_PRAGMA is defined.
+ (pragma_ungetc): New function: replaces characters back into the
+ input stream. Defined when HANDLE_PRAGMA is defined.
+
+Tue Sep 1 10:00:21 1998 Craig Burley <burley@gnu.org>
+
+ * bugs.texi, g77.1, g77.texi, intdoc.in, news.texi: Doc updates
+ from Craig.
+
+1998-08-23 Dave Love <d.love@dl.ac.uk>
+
+ * g77.texi: Increment `version-g77' and fix a few typos.
+
+Tue Aug 18 21:41:31 1998 Jeffrey A Law (law@cygnus.com)
+
+ * Make-lang.in: Add several "else true" clauses to deal with lame
+ systems.
+
+Tue Aug 11 08:12:14 1998 H.J. Lu (hjl@gnu.org)
+
+ * Make-lang.in (g77.o): Touch lang-f77 before checking it.
+
+1998-08-09 Dave Love <d.love@dl.ac.uk>
+
+ * Make-lang.in (f/g77.dvi): Replace non-working use of texi2dvi
+ with explicit use of tex.
+ (f77.mostlyclean): Remove TeX index files.
+
+ * g77install.texi (Prerequisites): Kluge round TeX lossage with
+ hyphen in @value in @code.
+
+Tue Aug 4 16:59:39 1998 Craig Burley <burley@gnu.org>
+
+ * com.c (ffecom_convert_narrow_, ffecom_convert_widen_):
+ Allow conversion from pointer to same-sized integer,
+ to fix invoking SIGNAL as a function.
+
+1998-07-26 Dave Love <d.love@dl.ac.uk>
+
+ * BUGS, INSTALL, NEWS: Rebuilt.
+
+Sat Jul 25 17:23:55 1998 Craig Burley <burley@gnu.org>
+
+ Fix 980615-0.f:
+ * stc.c (ffestc_R1229_start): Set info to ANY as well.
+
+Tue Jul 21 04:33:37 1998 Craig Burley <burley@gnu.org>
+
+ * g77spec.c (lang_specific_driver): Return unmolested
+ command line when --help seen.
+ Comment out code that printed g77-specific --help info.
+
+Sat Jul 18 19:16:48 1998 Craig Burley <burley@gnu.org>
+
+ * lang-options.h: Fix up doc strings.
+ Remove the unimplemented -fdcp-intrinsics-* options.
+
+ * str-1t.fin: Change mixed-case spelling of `GoTo' from
+ `Goto'.
+
+Thu Jul 16 13:26:36 1998 Craig Burley <burley@gnu.org>
+
+ * com.c (ffecom_finish_symbol_transform_): Revert change
+ of 1998-05-23, as it was too aggressive, in that it
+ prevented transformation of (used) functions before
+ primary code generation.
+
+1998-07-15 Dave Love <d.love@dl.ac.uk>
+
+ * intdoc.texi: Regenerated.
+
+Mon Jul 13 18:45:06 1998 Craig Burley <burley@gnu.org>
+
+ * Make-lang.in (f77.rebuilt): Fix to depend on
+ build-dir-based, not source-based, g77.info.
+
+ * g77.texi: Merge docs with 0.5.24.
+ * g77install.texi: Ditto.
+
+Mon Jul 13 18:02:29 1998 Craig Burley <burley@gnu.org>
+
+ Cleanups vis-a-vis g77-0.5.24:
+ * g77spec.c (lang_specific_driver): Tabify source.
+ * top.c (ffe_decode_option): Use fixed macro to set
+ internal-checking flag.
+ * top.h (ffe_set_is_do_internal_checks): Fix macro.
+
+Mon Jul 13 17:33:44 1998 Craig Burley <burley@gnu.org>
+
+ Cleanups vis-a-vis system.h cutover and g77-0.5.24:
+ * Makefile.in (fini.o): Define USE_HCONFIG macro
+ so source code doesn't have to.
+ * fini.c: Don't define USE_HCONFIG here, since
+ source code usually shouldn't care about this.
+ * ansify.c: Include stddef.h only if we have it.
+ * intdoc.c: Ditto.
+ * proj.h: Ditto.
+
+Mon Jul 13 17:30:29 1998 Nick Clifton <nickc@cygnus.com>
+
+ * lang-options.h: Format changed to work with --help support added
+ to gcc/toplev.c
+
+Mon Jul 13 11:54:03 1998 Craig Burley <burley@gnu.org>
+
+ * com.c (ffecom_push_tempvar): Replace kludge that
+ munged back-end globals directly with proper calls
+ to push_topmost_sequence and pop_topmost_sequence.
+
+1998-07-12 Dave Love <d.love@dl.ac.uk>
+
+ * version.c: Bump version.
+
+Sat Jul 11 19:24:32 1998 Craig Burley <burley@gnu.org>
+
+ Fix 980616-0.f:
+ * equiv.c (ffeequiv_offset_): Don't crash on various
+ possible ANY operands.
+
+Sat Jul 11 18:24:37 1998 Craig Burley <burley@gnu.org>
+
+ * com.c (ffecom_expr_) [FFEBLD_opCONTER]: Die if padding
+ for constant is nonzero.
+
+ * com.c (__eprintf): Delete this function, it is obsolete.
+
+1998-07-09 Dave Love <d.love@dl.ac.uk>
+
+ * intdoc.in (HOSTNM_func, HOSTNM_subr): Update last change.
+
+Thu Jul 9 00:45:59 1998 Craig Burley <burley@gnu.org>
+
+ Fix debugging of CHARACTER*(*), etc., which requires
+ emitting debug info on types like `ftnlen':
+ * com.c (ffecom_start_progunit_): Don't bother
+ resetting "invented" flag for identifier.
+ (ffecom_transform_equiv_): Don't bother zeroing
+ "ignored" flag for decl.
+ (pushdecl): No longer set "ignored", "used", or
+ "suppressed debug" flags for decls having "invented"
+ identifiers.
+
+1998-07-06 Mike Stump <mrs@wrs.com>
+
+ * Make-lang.in (f77.stage?): Use mv -f instead of just mv so that
+ we can move g77.c.
+
+1998-07-06 Dave Love <d.love@dl.ac.uk>
+
+ * intdoc.in (HOSTNM_func, HOSTNM_subr): Note possible need for
+ -lsocket.
+
+1998-07-05 Dave Love <d.love@dl.ac.uk>
+
+ * intdoc.in: Add entry for DATE_AND_TIME.
+
+ * intrin.def: Add implementation for DATE_AND_TIME. Make second
+ and third args of SYSTEM_CLOCK optional.
+
+ * com.c (ffecom_expr_intrinsic_): New case for DATE_AND_TIME.
+
+ * com-rt.def (FFECOM_gfrtSYSTEM_CLOCK): Call G77_system_clock_0,
+ not system_clock_.
+ (FFECOM_gfrtDATE_AND_TIME): New DEFGFRT.
+
+Wed Jul 1 11:19:13 1998 Craig Burley <burley@gnu.org>
+
+ Fix 980701-1.f (which was producing "unaligned trap"
+ on an Alpha running GNU/Linux, as predicted):
+ * equiv.c (ffeequiv_layout_local_): Don't bother
+ coping with pre-padding of entire area while building
+ it; do that instead after the building is done, and
+ do it by modifying only the modulo field. This covers
+ the case of alignment stringency being increased without
+ lowering the starting offset, unlike the previous changes,
+ and even more elegantly than those.
+
+ * target.c (ffetarget_align): Make sure alignments
+ are nonzero, just in case.
+
+See ChangeLog.0 for earlier changes.
+
+Local Variables:
+add-log-time-format: current-time-string
+End:
+2003-01-01 Andreas Jaeger <aj@suse.de>
+
+ * f/Make-lang.in ($(srcdir)/f/BUGS): Add include path for
+ gcc-common.texi.
+ ($(srcdir)/f/NEWS): Likewise.
+
+2002-12-28 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * g77.texi: Use @copying.
+
+2002-12-23 Joseph S. Myers <jsm@polyomino.org.uk>
+
+ * root.texi: Include gcc-common.texi.
+ * bugs.texi, news.texi: Don't include root.texi as part of full
+ manual.
+ * g77.texi: Update for use of gcc-common.texi.
+ * Make-lang.in ($(srcdir)/f/g77.info, f/g77.dvi): Depend on
+ $(srcdir)/doc/include/gcc-common.texi.
+
+2002-12-19 Kazu Hirata <kazu@cs.umass.edu>
+
+ * intdoc.in: Fix typos.
+
+2002-12-18 Kazu Hirata <kazu@cs.umass.edu>
+
+ * g77.texi: Fix typos.
+ * intdoc.texi: Likewise.
+ * news.texi: Follow spelling conventions.
+
+Mon Dec 16 13:53:18 2002 Mark Mitchell <mark@codesourcery.com>
+
+ * root.texi: Change version number to 3.4.
+
+2002-12-15 Zack Weinberg <zack@codesourcery.com>
+
+ * target.h: Don't define HOST_WIDE_INT.
+
+2002-12-02 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Make-lang.in, ansify.c, intdoc.c, proj.h: Replace hconfig.h with
+ bconfig.h.
+ * fini.c, proj.h: Replace USE_HCONFIG with USE_BCONFIG
+
+2002-11-30 Zack Weinberg <zack@codesourcery.com>
+
+ * proj.h, ansify.c, g77spec.c, intdoc.c:
+ Include coretypes.h and tm.h.
+ * Make-lang.in: Update dependencies.
+
+2002-11-20 Toon Moene <toon@moene.indiv.nluug.nl>
+
+ * invoke.texi: Explain the purpose of -fmove-all-movables,
+ -freduce-all-givs and -frerun-loop-opts better.
+
+2002-11-19 Nathanael Nerode <neroden@gcc.gnu.org>
+
+ * Make-lang.in: Correct BUILD/HOST confusion.
+
2002-11-19 Toon Moene <toon@moene.indiv.nluug.nl>
PR fortran/8587
diff --git a/contrib/gcc/f/Make-lang.in b/contrib/gcc/f/Make-lang.in
index 1286f07e6d4b..47585b0e2421 100644
--- a/contrib/gcc/f/Make-lang.in
+++ b/contrib/gcc/f/Make-lang.in
@@ -1,4 +1,4 @@
-# Top level makefile fragment for GNU Fortran. -*-makefile-*-
+# Top level -*- makefile -*- fragment for GNU Fortran.
# Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
#This file is part of GNU Fortran.
@@ -22,10 +22,9 @@
# Each language makefile fragment must provide the following targets:
#
# foo.all.build, foo.all.cross, foo.start.encap, foo.rest.encap,
-# foo.info, foo.dvi,
-# foo.install-normal, foo.install-common, foo.install-info, foo.install-man,
+# foo.install-normal, foo.install-common, foo.install-man,
# foo.uninstall,
-# foo.mostlyclean, foo.clean, foo.distclean, foo.extraclean,
+# foo.mostlyclean, foo.clean, foo.distclean,
# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4
#
# where `foo' is the name of the language.
@@ -39,10 +38,7 @@
# $(srcdir) must be set to the gcc/ source directory (not gcc/f/).
#
# Actual name to use when installing a native compiler.
-G77_INSTALL_NAME = `echo g77|sed '$(program_transform_name)'`
-
-# Actual name to use when installing a cross-compiler.
-G77_CROSS_NAME = `echo g77|sed '$(program_transform_cross_name)'`
+G77_INSTALL_NAME := $(shell echo g77|sed '$(program_transform_name)')
# Some versions of `touch' (such as the version on Solaris 2.8)
# do not correctly set the timestamp due to buggy versions of `utime'
@@ -58,15 +54,16 @@ F77 f77: f771$(exeext)
# Tell GNU make to ignore these if they exist.
.PHONY: F77 f77 f77.all.build f77.all.cross \
- f77.start.encap f77.rest.encap f77.info f77.dvi \
+ f77.start.encap f77.rest.encap f77.dvi \
f77.install-normal \
- f77.install-common f77.install-info f77.install-man \
+ f77.install-common f77.install-man \
f77.uninstall f77.mostlyclean f77.clean f77.distclean \
- f77.extraclean f77.maintainer-clean f77.rebuilt \
- f77.stage1 f77.stage2 f77.stage3 f77.stage4
+ f77.maintainer-clean \
+ f77.stage1 f77.stage2 f77.stage3 f77.stage4 \
+ f77.stageprofile f77.stagefeedback
-g77spec.o: $(srcdir)/f/g77spec.c $(SYSTEM_H) $(GCC_H) \
- $(CONFIG_H)
+g77spec.o: $(srcdir)/f/g77spec.c $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) \
+ $(CONFIG_H) intl.h
(SHLIB_LINK='$(SHLIB_LINK)' \
SHLIB_MULTILIB='$(SHLIB_MULTILIB)'; \
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(DRIVER_DEFINES) \
@@ -92,7 +89,7 @@ F77_OBJS = f/bad.o f/bit.o f/bld.o f/com.o f/data.o f/equiv.o f/expr.o \
f/stv.o f/stw.o f/symbol.o f/target.o f/top.o f/type.o f/where.o
# Use loose warnings for this front end.
-f-warn =
+f-warn = $(WERROR)
f771$(exeext): $(F77_OBJS) $(BACKEND) $(LIBDEPS)
rm -f f771$(exeext)
@@ -125,12 +122,12 @@ f/str-op.h f/str-op.j: f/fini$(build_exeext) f/str-op.fin
f/str-ot.h f/str-ot.j: f/fini$(build_exeext) f/str-ot.fin
./f/fini$(build_exeext) $(srcdir)/f/str-ot.fin f/str-ot.j f/str-ot.h
-f/fini$(build_exeext): f/fini.o $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o f/fini$(build_exeext) \
- f/fini.o $(HOST_LIBS)
+f/fini$(build_exeext): f/fini.o $(BUILD_LIBDEPS)
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o f/fini$(build_exeext) \
+ f/fini.o $(BUILD_LIBS)
f/fini.o:
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \
-c $(srcdir)/f/fini.c $(OUTPUT_OPTION)
gt-f-lex.h gt-f-where.h gt-f-com.h gt-f-ste.h gtype-f.h : s-gtype; @true
@@ -143,39 +140,43 @@ f77.all.cross: g77-cross$(exeext)
f77.start.encap: g77$(exeext)
f77.rest.encap:
-f77.info: $(srcdir)/f/g77.info
-f77.dvi: f/g77.dvi
-f77.generated-manpages: $(srcdir)/f/g77.1
+f77.srcinfo: doc/g77.info
+ -cp -p $^ $(srcdir)/doc
+f77.srcman: doc/g77.1
+ -cp -p $^ $(srcdir)/doc
+f77.srcextra: f/BUGS f/NEWS
+ -cp -p $^ $(srcdir)/f
+
+f77.tags: force
+ cd $(srcdir)/f; etags -o TAGS.sub *.c *.h; \
+ etags --include TAGS.sub --include ../TAGS.sub
+
+f77.info: doc/g77.info
+dvi:: doc/g77.dvi
+f77.man: doc/g77.1
+
+check-f77 : check-g77
+lang_checks += check-g77
# g77 documentation.
-$(srcdir)/f/g77.info: $(srcdir)/f/g77.texi $(srcdir)/f/bugs.texi \
- $(srcdir)/f/ffe.texi $(srcdir)/f/invoke.texi \
- $(srcdir)/f/news.texi $(srcdir)/f/intdoc.texi \
- $(srcdir)/f/root.texi $(srcdir)/doc/include/fdl.texi \
- $(srcdir)/doc/include/gpl.texi \
- $(srcdir)/doc/include/funding.texi \
- $(srcdir)/doc/include/gcc-common.texi
- if [ x$(BUILD_INFO) = xinfo ]; then \
- rm -f $(srcdir)/f/g77.info-*; \
- cd $(srcdir)/f && $(MAKEINFO) -I../doc/include -o g77.info g77.texi; \
+TEXI_G77_FILES = f/g77.texi f/bugs.texi f/ffe.texi f/invoke.texi \
+ f/news.texi f/root.texi $(docdir)/include/fdl.texi \
+ $(docdir)/include/gpl.texi $(docdir)/include/funding.texi \
+ $(docdir)/include/gcc-common.texi $(srcdir)/f/intdoc.texi
+
+doc/g77.info: $(TEXI_G77_FILES)
+ if test "x$(BUILD_INFO)" = xinfo; then \
+ rm -f $(@)*; \
+ $(MAKEINFO) $(MAKEINFOFLAGS) -I$(docdir)/include -I$(srcdir)/f \
+ -o$@ $<; \
else true; fi
-f/g77.dvi: $(srcdir)/f/g77.texi $(srcdir)/f/bugs.texi \
- $(srcdir)/f/ffe.texi $(srcdir)/f/invoke.texi \
- $(srcdir)/f/news.texi $(srcdir)/f/intdoc.texi \
- $(srcdir)/f/root.texi $(srcdir)/doc/include/fdl.texi \
- $(srcdir)/doc/include/gpl.texi \
- $(srcdir)/doc/include/funding.texi \
- $(srcdir)/doc/include/gcc-common.texi
- s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
- cd f && $(TEXI2DVI) -I $$s/doc/include $$s/f/g77.texi
-
-$(srcdir)/f/g77.1: $(srcdir)/f/invoke.texi
- -$(TEXI2POD) < $(srcdir)/f/invoke.texi > f/g77.pod; \
- ($(POD2MAN) --section=1 f/g77.pod > f/g77.1.T$$$$ && \
- mv -f f/g77.1.T$$$$ $(srcdir)/f/g77.1) || \
- (rm -f f/g77.1.T$$$$ && exit 1); \
- rm -f f/g77.pod; \
+doc/g77.dvi: $(TEXI_G77_FILES)
+ $(TEXI2DVI) -I $(srcdir)/f -I $(abs_docdir)/include -I $(objdir)/f -o $@ $<
+
+.INTERMEDIATE: g77.pod
+g77.pod: f/invoke.texi
+ -$(TEXI2POD) < $< > $@
# This dance is all about producing accurate documentation for g77's
# intrinsics with minimum fuss. f/ansify appends "\n\" to C strings
@@ -199,41 +200,43 @@ $(srcdir)/f/g77.1: $(srcdir)/f/invoke.texi
# If the documentation files depended on executables in the build
# tree, there'd be no way to ship a source tree with the documentation
-# already generated such that `make' wouldn't attempt to rebuilt it.
+# already generated such that `make' wouldn't attempt to rebuild it.
# So, we punt and arrange for the documentation files to depend on the
# dependencies of the executables, not on the executables themselves.
# But then, we have to build the executables explicitly in their build
# rules.
-INTDOC_DEPS = $(srcdir)/f/intdoc.c $(srcdir)/f/intrin.h $(srcdir)/f/intrin.def
+INTDOC_DEPS = f/intdoc.c f/intrin.h f/intrin.def
-$(srcdir)/f/intdoc.texi: $(INTDOC_DEPS) $(srcdir)/f/intdoc.in
+$(srcdir)/f/intdoc.texi: $(INTDOC_DEPS) f/intdoc.in
$(MAKE) f/intdoc$(build_exeext)
f/intdoc$(build_exeext) > $(srcdir)/f/intdoc.texi
-f/intdoc$(build_exeext): $(INTDOC_DEPS) f/intdoc.h0 hconfig.h $(SYSTEM_H) \
- $(HOST_LIBDEPS)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) $(INCLUDES) \
- $(srcdir)/f/intdoc.c $(HOST_LIBS) -o f/intdoc$(build_exeext)
+f/intdoc$(build_exeext): $(INTDOC_DEPS) f/intdoc.h0 bconfig.h \
+ $(SYSTEM_H) coretypes.h $(TM_H) $(BUILD_LIBDEPS)
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) $(INCLUDES) $< \
+ $(BUILD_LIBS) -o $@
f/intdoc.h0: f/intdoc.in f/ansify$(build_exeext)
- f/ansify$(build_exeext) $(srcdir)/f/intdoc.in \
- < $(srcdir)/f/intdoc.in > f/intdoc.h0
-
-f/ansify$(build_exeext): f/ansify.c hconfig.h $(SYSTEM_H)
- $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) $(INCLUDES) \
- $(srcdir)/f/ansify.c -o f/ansify$(build_exeext)
+ f/ansify$(build_exeext) $< < $< > $@
-$(srcdir)/f/BUGS: f/bugs0.texi f/bugs.texi f/root.texi
- cd $(srcdir)/f; $(MAKEINFO) -D BUGSONLY --no-header --no-split \
- --no-validate -I../doc/include -o BUGS bugs0.texi
+f/ansify$(build_exeext): f/ansify.c bconfig.h $(SYSTEM_H) coretypes.h $(TM_H)
+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) $(INCLUDES) $< \
+ -o $@
-$(srcdir)/f/NEWS: f/news0.texi f/news.texi f/root.texi
- cd $(srcdir)/f; $(MAKEINFO) -D NEWSONLY --no-header --no-split \
- --no-validate -I../doc/include -o NEWS news0.texi
+f/BUGS: f/bugs0.texi f/bugs.texi f/root.texi
+ if [ x$(BUILD_INFO) = xinfo ]; then \
+ rm -f $(@)*; \
+ $(MAKEINFO) $(MAKEINFOFLAGS) -D BUGSONLY --no-header --no-split \
+ --no-validate -I$(docdir)/include -I$(srcdir)/f -o $@ bugs0.texi; \
+ else true; fi
-f77.rebuilt: f/g77.info $(srcdir)/f/BUGS \
- $(srcdir)/f/NEWS
+f/NEWS: f/news0.texi f/news.texi f/root.texi
+ if [ x$(BUILD_INFO) = xinfo ]; then \
+ rm -f $(@)*; \
+ $(MAKEINFO) $(MAKEINFOFLAGS) -D NEWSONLY --no-header --no-split \
+ --no-validate -I$(docdir)/include -I$(srcdir)/f -o $@ news0.texi; \
+ else true; fi
#
# Install hooks:
@@ -245,15 +248,9 @@ f77.install-normal:
# and also as either g77 (if native) or $(tooldir)/bin/g77.
f77.install-common: installdirs
-if [ -f f771$(exeext) ] ; then \
- if [ -f g77-cross$(exeext) ] ; then \
- rm -f $(DESTDIR)$(bindir)/$(G77_CROSS_NAME)$(exeext); \
- $(INSTALL_PROGRAM) g77-cross$(exeext) $(DESTDIR)$(bindir)/$(G77_CROSS_NAME)$(exeext); \
- chmod a+x $(DESTDIR)$(bindir)/$(G77_CROSS_NAME)$(exeext); \
- else \
- rm -f $(DESTDIR)$(bindir)/$(G77_INSTALL_NAME)$(exeext); \
- $(INSTALL_PROGRAM) g77$(exeext) $(DESTDIR)$(bindir)/$(G77_INSTALL_NAME)$(exeext); \
- chmod a+x $(DESTDIR)$(bindir)/$(G77_INSTALL_NAME)$(exeext); \
- fi ; \
+ rm -f $(DESTDIR)$(bindir)/$(G77_INSTALL_NAME)$(exeext); \
+ $(INSTALL_PROGRAM) g77$(exeext) $(DESTDIR)$(bindir)/$(G77_INSTALL_NAME)$(exeext); \
+ chmod a+x $(DESTDIR)$(bindir)/$(G77_INSTALL_NAME)$(exeext); \
else true; fi
@if [ -f f77-install-ok -o -f $(srcdir)/f77-install-ok ]; then \
echo ''; \
@@ -265,36 +262,14 @@ f77.install-common: installdirs
echo ''; \
else true; fi
-# $(INSTALL_DATA) might be a relative pathname, so we can't cd into srcdir
-# to do the install. The sed rule was copied from stmp-int-hdrs.
-f77.install-info: f77.info installdirs
- if [ -f $(srcdir)/f/g77.info ] ; then \
- rm -f $(DESTDIR)$(infodir)/g77.info*; \
- for f in $(srcdir)/f/g77.info*; do \
- realfile=`echo $$f | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
- $(INSTALL_DATA) $$f $(DESTDIR)$(infodir)/$$realfile; \
- done; \
- chmod a-x $(DESTDIR)$(infodir)/g77.info*; \
- else true; fi
- @if [ -f $(srcdir)/f/g77.info ] ; then \
- if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
- echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/g77.info"; \
- install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/g77.info || : ; \
- else : ; fi; \
- else : ; fi
+install-info:: $(DESTDIR)$(infodir)/g77.info
-f77.install-man: $(GENERATED_MANPAGES) installdirs
- -if [ -f f771$(exeext) ] ; then \
- if [ -f g77-cross$(exeext) ] ; then \
- rm -f $(DESTDIR)$(man1dir)/$(G77_CROSS_NAME)$(man1ext); \
- $(INSTALL_DATA) $(srcdir)/f/g77.1 $(DESTDIR)$(man1dir)/$(G77_CROSS_NAME)$(man1ext); \
- chmod a-x $(DESTDIR)$(man1dir)/$(G77_CROSS_NAME)$(man1ext); \
- else \
- rm -f $(DESTDIR)$(man1dir)/$(G77_INSTALL_NAME)$(man1ext); \
- $(INSTALL_DATA) $(srcdir)/f/g77.1 $(DESTDIR)$(man1dir)/$(G77_INSTALL_NAME)$(man1ext); \
- chmod a-x $(DESTDIR)$(man1dir)/$(G77_INSTALL_NAME)$(man1ext); \
- fi; \
- else true; fi
+f77.install-man: installdirs $(DESTDIR)$(man1dir)/$(G77_INSTALL_NAME)$(man1ext)
+
+$(DESTDIR)$(man1dir)/$(G77_INSTALL_NAME)$(man1ext): doc/g77.1
+ -rm -f $@
+ -$(INSTALL_DATA) $< $@
+ -chmod a-x $@
f77.uninstall: installdirs
if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \
@@ -302,9 +277,7 @@ f77.uninstall: installdirs
install-info --delete --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/g77.info || : ; \
else : ; fi
rm -rf $(DESTDIR)$(bindir)/$(G77_INSTALL_NAME)$(exeext); \
- rm -rf $(DESTDIR)$(bindir)/$(G77_CROSS_NAME)$(exeext); \
rm -rf $(DESTDIR)$(man1dir)/$(G77_INSTALL_NAME)$(man1ext); \
- rm -rf $(DESTDIR)$(man1dir)/$(G77_CROSS_NAME)$(man1ext); \
rm -rf $(DESTDIR)$(infodir)/g77.info*
#
# Clean hooks:
@@ -315,16 +288,16 @@ f77.mostlyclean:
-rm -f f/*$(objext)
-rm -f f/*$(coverageexts)
-rm -f f/fini$(build_exeext) f/stamp-str f/str-*.h f/str-*.j
- -rm -f f/intdoc$(build_exeext) f/ansify$(build_exeext) f/intdoc.h0
+ -rm -f f/BUGS f/NEWS
-rm -f g77.aux g77.cps g77.ky g77.toc g77.vr g77.fn g77.kys \
g77.pg g77.tp g77.vrs g77.cp g77.fns g77.log g77.pgs g77.tps
f77.clean:
-rm -f g77spec.o
f77.distclean:
-rm -f f/Makefile
-f77.extraclean:
f77.maintainer-clean:
- -rm -f f/g77.info* f/g77.*aux f/TAGS f/BUGS f/NEWS f/intdoc.texi
+ -rm -f $(srcdir)/f/BUGS $(srcdir)/f/TAGS $(srcdir)/f/TAGS.SUB
+ -rm -f $(srcdir)/f/NEWS $(srcdir)/f/intdoc.texi
#
# Stage hooks:
# The main makefile has already created stage?/f.
@@ -344,6 +317,11 @@ f77.stage3: stage3-start
f77.stage4: stage4-start
-mv -f $(G77STAGESTUFF) stage4/f
+f77.stageprofile: stageprofile-start
+ -mv -f $(G77STAGESTUFF) stageprofile/f
+
+f77.stagefeedback: stageprofile-start
+ -mv -f $(G77STAGESTUFF) stagefeedback/f
#
# .o: .h dependencies.
@@ -352,178 +330,187 @@ f/bad.o: f/bad.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/bad.h f/bad.def f/where.h \
f/bld-op.def f/bit.h f/info.h f/info-b.def f/info-k.def f/info-w.def \
f/target.h f/lex.h f/type.h f/intrin.h f/intrin.def f/lab.h f/symbol.h \
f/symbol.def f/equiv.h f/storag.h f/global.h f/name.h toplev.h intl.h \
- diagnostic.h
+ diagnostic.h coretypes.h $(TM_H)
f/bit.o: f/bit.c f/proj.h $(CONFIG_H) $(SYSTEM_H) glimits.h f/bit.h \
- f/malloc.h
+ f/malloc.h coretypes.h $(TM_H)
f/bld.o: f/bld.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/bld.h f/bld-op.def f/bit.h \
f/malloc.h f/com.h f/com-rt.def $(TREE_H) f/info.h f/info-b.def f/info-k.def \
f/info-w.def f/target.h f/bad.h f/bad.def f/where.h glimits.h f/top.h f/lex.h \
f/type.h f/lab.h f/storag.h f/symbol.h f/symbol.def f/equiv.h f/global.h \
- f/name.h f/intrin.h f/intrin.def real.h
+ f/name.h f/intrin.h f/intrin.def real.h coretypes.h $(TM_H)
f/com.o: f/com.c f/proj.h $(CONFIG_H) $(SYSTEM_H) flags.h $(RTL_H) $(TREE_H) \
output.h convert.h f/com.h f/com-rt.def f/bld.h f/bld-op.def f/bit.h \
f/malloc.h f/info.h f/info-b.def f/info-k.def f/info-w.def f/target.h f/bad.h \
f/bad.def f/where.h glimits.h f/top.h f/lex.h f/type.h f/intrin.h \
f/intrin.def f/lab.h f/symbol.h f/symbol.def f/equiv.h f/storag.h f/global.h \
f/name.h f/expr.h f/implic.h f/src.h f/st.h $(GGC_H) toplev.h diagnostic.h \
- $(LANGHOOKS_DEF) langhooks.h intl.h real.h debug.h gt-f-com.h gtype-f.h
+ $(LANGHOOKS_DEF) langhooks.h intl.h real.h debug.h gt-f-com.h gtype-f.h \
+ coretypes.h $(TM_H)
f/data.o: f/data.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/data.h f/bld.h f/bld-op.def \
f/bit.h f/malloc.h f/com.h f/com-rt.def $(TREE_H) f/info.h f/info-b.def \
f/info-k.def f/info-w.def f/target.h f/bad.h f/bad.def f/where.h glimits.h \
f/top.h f/lex.h f/type.h f/lab.h f/storag.h f/symbol.h f/symbol.def f/equiv.h \
- f/global.h f/name.h f/intrin.h f/intrin.def f/expr.h f/st.h
+ f/global.h f/name.h f/intrin.h f/intrin.def f/expr.h f/st.h coretypes.h $(TM_H)
f/equiv.o: f/equiv.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/equiv.h f/bld.h \
f/bld-op.def f/bit.h f/malloc.h f/com.h f/com-rt.def $(TREE_H) f/info.h \
f/info-b.def f/info-k.def f/info-w.def f/target.h f/bad.h f/bad.def f/where.h \
glimits.h f/top.h f/lex.h f/type.h f/lab.h f/storag.h f/symbol.h f/symbol.def \
- f/global.h f/name.h f/intrin.h f/intrin.def f/data.h
+ f/global.h f/name.h f/intrin.h f/intrin.def f/data.h coretypes.h $(TM_H)
f/expr.o: f/expr.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/expr.h f/bld.h f/bld-op.def \
f/bit.h f/malloc.h f/com.h f/com-rt.def $(TREE_H) f/info.h f/info-b.def \
f/info-k.def f/info-w.def f/target.h f/bad.h f/bad.def f/where.h glimits.h \
f/top.h f/lex.h f/type.h f/lab.h f/storag.h f/symbol.h f/symbol.def f/equiv.h \
f/global.h f/name.h f/intrin.h f/intrin.def f/implic.h f/src.h f/st.h \
- f/stamp-str real.h
-f/fini.o: f/fini.c f/proj.h hconfig.h $(SYSTEM_H) f/malloc.h
+ f/stamp-str real.h coretypes.h $(TM_H)
+f/fini.o: f/fini.c f/proj.h bconfig.h $(SYSTEM_H) f/malloc.h coretypes.h $(TM_H)
f/global.o: f/global.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/global.h f/info.h \
f/info-b.def f/info-k.def f/info-w.def f/target.h $(TREE_H) f/bad.h f/bad.def \
f/where.h glimits.h f/top.h f/malloc.h f/lex.h f/type.h f/name.h f/symbol.h \
f/symbol.def f/bld.h f/bld-op.def f/bit.h f/com.h f/com-rt.def f/lab.h \
- f/storag.h f/intrin.h f/intrin.def f/equiv.h
+ f/storag.h f/intrin.h f/intrin.def f/equiv.h coretypes.h $(TM_H)
f/implic.o: f/implic.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/implic.h f/info.h \
f/info-b.def f/info-k.def f/info-w.def f/target.h $(TREE_H) f/bad.h f/bad.def \
f/where.h glimits.h f/top.h f/malloc.h f/lex.h f/type.h f/symbol.h \
f/symbol.def f/bld.h f/bld-op.def f/bit.h f/com.h f/com-rt.def f/lab.h \
- f/storag.h f/intrin.h f/intrin.def f/equiv.h f/global.h f/name.h f/src.h
+ f/storag.h f/intrin.h f/intrin.def f/equiv.h f/global.h f/name.h f/src.h \
+ coretypes.h $(TM_H)
f/info.o: f/info.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/info.h f/info-b.def \
f/info-k.def f/info-w.def f/target.h $(TREE_H) f/bad.h f/bad.def f/where.h \
- glimits.h f/top.h f/malloc.h f/lex.h f/type.h
+ glimits.h f/top.h f/malloc.h f/lex.h f/type.h coretypes.h $(TM_H)
f/intrin.o: f/intrin.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/intrin.h \
f/intrin.def f/bld.h f/bld-op.def f/bit.h f/malloc.h f/com.h f/com-rt.def \
$(TREE_H) f/info.h f/info-b.def f/info-k.def f/info-w.def f/target.h f/bad.h \
f/bad.def f/where.h glimits.h f/top.h f/lex.h f/type.h f/lab.h f/storag.h \
- f/symbol.h f/symbol.def f/equiv.h f/global.h f/name.h f/expr.h f/src.h
+ f/symbol.h f/symbol.def f/equiv.h f/global.h f/name.h f/expr.h f/src.h \
+ coretypes.h $(TM_H)
f/lab.o: f/lab.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/lab.h f/com.h f/com-rt.def \
$(TREE_H) f/bld.h f/bld-op.def f/bit.h f/malloc.h f/info.h f/info-b.def \
f/info-k.def f/info-w.def f/target.h f/bad.h f/bad.def f/where.h glimits.h \
f/top.h f/lex.h f/type.h f/intrin.h f/intrin.def f/symbol.h f/symbol.def \
- f/equiv.h f/storag.h f/global.h f/name.h
+ f/equiv.h f/storag.h f/global.h f/name.h coretypes.h $(TM_H)
f/lex.o: f/lex.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/top.h f/malloc.h f/where.h \
glimits.h f/bad.h f/bad.def f/com.h f/com-rt.def $(TREE_H) f/bld.h \
f/bld-op.def f/bit.h f/info.h f/info-b.def f/info-k.def f/info-w.def \
f/target.h f/lex.h f/type.h f/intrin.h f/intrin.def f/lab.h f/symbol.h \
f/symbol.def f/equiv.h f/storag.h f/global.h f/name.h f/src.h flags.h \
- debug.h input.h toplev.h output.h $(GGC_H) gt-f-lex.h
-f/malloc.o: f/malloc.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/malloc.h
+ debug.h input.h toplev.h output.h $(GGC_H) gt-f-lex.h coretypes.h $(TM_H)
+f/malloc.o: f/malloc.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/malloc.h \
+ coretypes.h $(TM_H)
f/name.o: f/name.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/bad.h f/bad.def f/where.h \
glimits.h f/top.h f/malloc.h f/name.h f/global.h f/info.h f/info-b.def \
f/info-k.def f/info-w.def f/target.h $(TREE_H) f/lex.h f/type.h f/symbol.h \
f/symbol.def f/bld.h f/bld-op.def f/bit.h f/com.h f/com-rt.def f/lab.h \
- f/storag.h f/intrin.h f/intrin.def f/equiv.h f/src.h
+ f/storag.h f/intrin.h f/intrin.def f/equiv.h f/src.h coretypes.h $(TM_H)
f/parse.o: f/parse.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/top.h f/malloc.h \
f/where.h glimits.h f/com.h f/com-rt.def $(TREE_H) f/bld.h f/bld-op.def \
f/bit.h f/info.h f/info-b.def f/info-k.def f/info-w.def f/target.h f/bad.h \
f/bad.def f/lex.h f/type.h f/intrin.h f/intrin.def f/lab.h f/symbol.h \
- f/symbol.def f/equiv.h f/storag.h f/global.h f/name.h version.h flags.h
+ f/symbol.def f/equiv.h f/storag.h f/global.h f/name.h version.h flags.h \
+ coretypes.h $(TM_H)
f/src.o: f/src.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/src.h f/bad.h f/bad.def \
- f/where.h glimits.h f/top.h f/malloc.h
+ f/where.h glimits.h f/top.h f/malloc.h coretypes.h $(TM_H)
f/st.o: f/st.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/st.h f/bad.h f/bad.def \
f/where.h glimits.h f/top.h f/malloc.h f/lex.h f/symbol.h f/symbol.def \
f/bld.h f/bld-op.def f/bit.h f/com.h f/com-rt.def $(TREE_H) f/info.h \
f/info-b.def f/info-k.def f/info-w.def f/target.h f/type.h f/lab.h \
f/storag.h f/intrin.h f/intrin.def f/equiv.h f/global.h f/name.h f/sta.h \
f/stamp-str f/stb.h f/expr.h f/stp.h f/stt.h f/stc.h f/std.h \
- f/stv.h f/stw.h f/ste.h f/sts.h f/stu.h
+ f/stv.h f/stw.h f/ste.h f/sts.h f/stu.h coretypes.h $(TM_H)
f/sta.o: f/sta.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/sta.h f/bad.h f/bad.def \
f/where.h glimits.h f/top.h f/malloc.h f/lex.h f/stamp-str f/symbol.h \
f/symbol.def f/bld.h f/bld-op.def f/bit.h f/com.h f/com-rt.def $(TREE_H) \
f/info.h f/info-b.def f/info-k.def f/info-w.def f/target.h f/type.h f/lab.h \
f/storag.h f/intrin.h f/intrin.def f/equiv.h f/global.h f/name.h f/implic.h \
- f/stb.h f/expr.h f/stp.h f/stt.h f/stc.h f/std.h f/stv.h f/stw.h
+ f/stb.h f/expr.h f/stp.h f/stt.h f/stc.h f/std.h f/stv.h f/stw.h coretypes.h \
+ $(TM_H)
f/stb.o: f/stb.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/stb.h f/bad.h f/bad.def \
f/where.h glimits.h f/top.h f/malloc.h f/expr.h f/bld.h f/bld-op.def f/bit.h \
f/com.h f/com-rt.def $(TREE_H) f/info.h f/info-b.def f/info-k.def \
f/info-w.def f/target.h f/lex.h f/type.h f/lab.h f/storag.h f/symbol.h \
f/symbol.def f/equiv.h f/global.h f/name.h f/intrin.h f/intrin.def f/stp.h \
- f/stt.h f/stamp-str f/src.h f/sta.h f/stc.h
+ f/stt.h f/stamp-str f/src.h f/sta.h f/stc.h coretypes.h $(TM_H)
f/stc.o: f/stc.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/stc.h f/bad.h f/bad.def \
f/where.h glimits.h f/top.h f/malloc.h f/bld.h f/bld-op.def f/bit.h f/com.h \
f/com-rt.def $(TREE_H) f/info.h f/info-b.def f/info-k.def f/info-w.def \
f/target.h f/lex.h f/type.h f/lab.h f/storag.h f/symbol.h f/symbol.def \
f/equiv.h f/global.h f/name.h f/intrin.h f/intrin.def f/expr.h f/stp.h \
- f/stt.h f/stamp-str f/data.h f/implic.h f/src.h f/sta.h f/std.h f/stv.h f/stw.h
+ f/stt.h f/stamp-str f/data.h f/implic.h f/src.h f/sta.h f/std.h f/stv.h \
+ f/stw.h coretypes.h $(TM_H)
f/std.o: f/std.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/std.h f/bld.h f/bld-op.def \
f/bit.h f/malloc.h f/com.h f/com-rt.def $(TREE_H) f/info.h f/info-b.def \
f/info-k.def f/info-w.def f/target.h f/bad.h f/bad.def f/where.h glimits.h \
f/top.h f/lex.h f/type.h f/lab.h f/storag.h f/symbol.h f/symbol.def f/equiv.h \
f/global.h f/name.h f/intrin.h f/intrin.def f/stp.h f/stt.h f/stamp-str \
- f/stv.h f/stw.h f/sta.h f/ste.h f/sts.h
+ f/stv.h f/stw.h f/sta.h f/ste.h f/sts.h coretypes.h $(TM_H)
f/ste.o: f/ste.c f/proj.h $(CONFIG_H) $(SYSTEM_H) $(RTL_H) toplev.h f/ste.h \
f/bld.h f/bld-op.def f/bit.h f/malloc.h f/com.h f/com-rt.def $(TREE_H) \
f/info.h f/info-b.def f/info-k.def f/info-w.def f/target.h f/bad.h f/bad.def \
f/where.h glimits.h f/top.h f/lex.h f/type.h f/lab.h f/storag.h f/symbol.h \
f/symbol.def f/equiv.h f/global.h f/name.h f/intrin.h f/intrin.def f/stp.h \
f/stt.h f/stamp-str f/sts.h f/stv.h f/stw.h f/expr.h f/sta.h $(GGC_H) \
- gt-f-ste.h
+ gt-f-ste.h coretypes.h $(TM_H)
f/storag.o: f/storag.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/storag.h f/bld.h \
f/bld-op.def f/bit.h f/malloc.h f/com.h f/com-rt.def $(TREE_H) \
f/info.h f/info-b.def f/info-k.def f/info-w.def f/target.h f/bad.h \
f/bad.def f/where.h glimits.h f/top.h f/lex.h f/type.h f/lab.h \
f/symbol.h f/symbol.def f/equiv.h f/global.h f/name.h f/intrin.h \
- f/intrin.def f/data.h
+ f/intrin.def f/data.h coretypes.h $(TM_H)
f/stp.o: f/stp.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/stp.h f/bld.h f/bld-op.def \
f/bit.h f/malloc.h f/com.h f/com-rt.def $(TREE_H) f/info.h \
f/info-b.def f/info-k.def f/info-w.def f/target.h f/bad.h f/bad.def \
f/where.h glimits.h f/top.h f/lex.h f/type.h f/lab.h f/storag.h \
f/symbol.h f/symbol.def f/equiv.h f/global.h f/name.h f/intrin.h \
- f/intrin.def f/stt.h
+ f/intrin.def f/stt.h coretypes.h $(TM_H)
f/str.o: f/str.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/src.h f/bad.h f/bad.def \
- f/where.h glimits.h f/top.h f/malloc.h f/stamp-str f/lex.h
+ f/where.h glimits.h f/top.h f/malloc.h f/stamp-str f/lex.h coretypes.h $(TM_H)
f/sts.o: f/sts.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/sts.h f/malloc.h f/com.h \
f/com-rt.def $(TREE_H) f/bld.h f/bld-op.def f/bit.h f/info.h \
f/info-b.def f/info-k.def f/info-w.def f/target.h f/bad.h f/bad.def \
f/where.h glimits.h f/top.h f/lex.h f/type.h f/intrin.h f/intrin.def \
f/lab.h f/symbol.h f/symbol.def f/equiv.h f/storag.h f/global.h \
- f/name.h
+ f/name.h coretypes.h $(TM_H)
f/stt.o: f/stt.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/stt.h f/top.h f/malloc.h \
f/where.h glimits.h f/bld.h f/bld-op.def f/bit.h f/com.h f/com-rt.def \
$(TREE_H) f/info.h f/info-b.def f/info-k.def f/info-w.def f/target.h \
f/bad.h f/bad.def f/lex.h f/type.h f/lab.h f/storag.h f/symbol.h \
f/symbol.def f/equiv.h f/global.h f/name.h f/intrin.h f/intrin.def \
- f/stp.h f/expr.h f/sta.h f/stamp-str
+ f/stp.h f/expr.h f/sta.h f/stamp-str coretypes.h $(TM_H)
f/stu.o: f/stu.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/bld.h f/bld-op.def f/bit.h \
f/malloc.h f/com.h f/com-rt.def $(TREE_H) f/info.h f/info-b.def \
f/info-k.def f/info-w.def f/target.h f/bad.h f/bad.def f/where.h \
glimits.h f/top.h f/lex.h f/type.h f/lab.h f/storag.h f/symbol.h \
f/symbol.def f/equiv.h f/global.h f/name.h f/intrin.h f/intrin.def \
- f/implic.h f/stu.h f/sta.h f/stamp-str
+ f/implic.h f/stu.h f/sta.h f/stamp-str coretypes.h $(TM_H)
f/stv.o: f/stv.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/stv.h f/lab.h f/com.h \
f/com-rt.def $(TREE_H) f/bld.h f/bld-op.def f/bit.h f/malloc.h \
f/info.h f/info-b.def f/info-k.def f/info-w.def f/target.h f/bad.h \
f/bad.def f/where.h glimits.h f/top.h f/lex.h f/type.h f/intrin.h \
f/intrin.def f/symbol.h f/symbol.def f/equiv.h f/storag.h f/global.h \
- f/name.h
+ f/name.h coretypes.h $(TM_H)
f/stw.o: f/stw.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/stw.h f/bld.h f/bld-op.def \
f/bit.h f/malloc.h f/com.h f/com-rt.def $(TREE_H) f/info.h \
f/info-b.def f/info-k.def f/info-w.def f/target.h f/bad.h f/bad.def \
f/where.h glimits.h f/top.h f/lex.h f/type.h f/lab.h f/storag.h \
f/symbol.h f/symbol.def f/equiv.h f/global.h f/name.h f/intrin.h \
- f/intrin.def f/stv.h f/sta.h f/stamp-str
+ f/intrin.def f/stv.h f/sta.h f/stamp-str coretypes.h $(TM_H)
f/symbol.o: f/symbol.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/symbol.h \
f/symbol.def f/bld.h f/bld-op.def f/bit.h f/malloc.h f/com.h \
f/com-rt.def $(TREE_H) f/info.h f/info-b.def f/info-k.def \
f/info-w.def f/target.h f/bad.h f/bad.def f/where.h glimits.h f/top.h \
f/lex.h f/type.h f/lab.h f/storag.h f/intrin.h f/intrin.def f/equiv.h \
- f/global.h f/name.h f/src.h f/st.h
+ f/global.h f/name.h f/src.h f/st.h coretypes.h $(TM_H)
f/target.o: f/target.c f/proj.h $(CONFIG_H) $(SYSTEM_H) glimits.h f/target.h \
$(TREE_H) f/bad.h f/bad.def f/where.h f/top.h f/malloc.h f/info.h real.h \
- f/info-b.def f/info-k.def f/info-w.def f/type.h f/lex.h diagnostic.h
+ f/info-b.def f/info-k.def f/info-w.def f/type.h f/lex.h diagnostic.h \
+ coretypes.h $(TM_H) toplev.h
f/top.o: f/top.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/top.h f/malloc.h f/where.h \
glimits.h f/bad.h f/bad.def f/bit.h f/bld.h f/bld-op.def f/com.h \
f/com-rt.def $(TREE_H) f/info.h f/info-b.def f/info-k.def \
f/info-w.def f/target.h f/lex.h f/type.h f/lab.h f/storag.h \
f/symbol.h f/symbol.def f/equiv.h f/global.h f/name.h f/intrin.h \
f/intrin.def f/data.h f/expr.h f/implic.h f/src.h f/st.h flags.h \
- toplev.h
-f/type.o: f/type.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/type.h f/malloc.h
-f/where.o: f/where.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/where.h glimits.h f/top.h \
- f/malloc.h f/lex.h $(GGC_H) gt-f-where.h
+ toplev.h coretypes.h $(TM_H) opts.h options.h
+f/type.o: f/type.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/type.h f/malloc.h \
+ coretypes.h $(TM_H)
+f/where.o: f/where.c f/proj.h $(CONFIG_H) $(SYSTEM_H) f/where.h glimits.h \
+ f/top.h f/malloc.h f/lex.h $(GGC_H) gt-f-where.h coretypes.h $(TM_H)
diff --git a/contrib/gcc/f/ansify.c b/contrib/gcc/f/ansify.c
index ec9910779e78..b03206d79e35 100644
--- a/contrib/gcc/f/ansify.c
+++ b/contrib/gcc/f/ansify.c
@@ -1,5 +1,5 @@
/* ansify.c
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -19,8 +19,10 @@ along with GNU Fortran; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#define die_unless(c) \
do if (!(c)) \
diff --git a/contrib/gcc/f/bad.c b/contrib/gcc/f/bad.c
index 21fa4871d748..bed9734ecc78 100644
--- a/contrib/gcc/f/bad.c
+++ b/contrib/gcc/f/bad.c
@@ -1,5 +1,5 @@
/* bad.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2002, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -132,7 +132,7 @@ ffebad_bufputs_ (char buf[], int bufi, const char *s)
ffebad_init_0(); */
void
-ffebad_init_0 ()
+ffebad_init_0 (void)
{
assert (FFEBAD == ARRAY_SIZE (ffebad_messages_));
}
@@ -203,11 +203,12 @@ ffebad_start_ (bool lex_override, ffebad errnum, ffebadSeverity sev,
if ((ffebad_severity_ != FFEBAD_severityPEDANTIC)
|| !flag_pedantic_errors)
{
- if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
+ if (!diagnostic_report_warnings_p ())
{ /* User wants no warnings. */
ffebad_is_temp_inhibited_ = TRUE;
return FALSE;
}
+ diagnostic_kind_count (global_dc, DK_WARNING)++;
break;
}
/* Fall through (PEDANTIC && flag_pedantic_errors). */
@@ -215,7 +216,7 @@ ffebad_start_ (bool lex_override, ffebad errnum, ffebadSeverity sev,
case FFEBAD_severityWEIRD:
case FFEBAD_severitySEVERE:
case FFEBAD_severityDISASTER:
- diagnostic_count_diagnostic (global_dc, DK_ERROR);
+ diagnostic_kind_count (global_dc, DK_ERROR)++;
break;
default:
@@ -347,7 +348,7 @@ ffebad_string (const char *string)
to actually get it to print (to stderr). */
void
-ffebad_finish ()
+ffebad_finish (void)
{
#define MAX_SPACES 132
static const char *const spaces
diff --git a/contrib/gcc/f/bld.c b/contrib/gcc/f/bld.c
index 3460c241b246..ec7c5cd683e3 100644
--- a/contrib/gcc/f/bld.c
+++ b/contrib/gcc/f/bld.c
@@ -1,5 +1,5 @@
/* bld.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2003, 2004 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -70,40 +70,9 @@ struct _ffebld_pool_stack_ ffebld_pool_stack_;
/* Static objects accessed by functions in this module. */
-#if FFEBLD_BLANK_
-static struct _ffebld_ ffebld_blank_
-=
-{
- 0,
- {FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindNONE,
- FFEINFO_whereNONE, FFETARGET_charactersizeNONE},
- {NULL, NULL}
-};
-#endif
#if FFETARGET_okCHARACTER1
static ffebldConstant ffebld_constant_character1_;
#endif
-#if FFETARGET_okCHARACTER2
-static ffebldConstant ffebld_constant_character2_;
-#endif
-#if FFETARGET_okCHARACTER3
-static ffebldConstant ffebld_constant_character3_;
-#endif
-#if FFETARGET_okCHARACTER4
-static ffebldConstant ffebld_constant_character4_;
-#endif
-#if FFETARGET_okCHARACTER5
-static ffebldConstant ffebld_constant_character5_;
-#endif
-#if FFETARGET_okCHARACTER6
-static ffebldConstant ffebld_constant_character6_;
-#endif
-#if FFETARGET_okCHARACTER7
-static ffebldConstant ffebld_constant_character7_;
-#endif
-#if FFETARGET_okCHARACTER8
-static ffebldConstant ffebld_constant_character8_;
-#endif
#if FFETARGET_okCOMPLEX1
static ffebldConstant ffebld_constant_complex1_;
#endif
@@ -113,21 +82,6 @@ static ffebldConstant ffebld_constant_complex2_;
#if FFETARGET_okCOMPLEX3
static ffebldConstant ffebld_constant_complex3_;
#endif
-#if FFETARGET_okCOMPLEX4
-static ffebldConstant ffebld_constant_complex4_;
-#endif
-#if FFETARGET_okCOMPLEX5
-static ffebldConstant ffebld_constant_complex5_;
-#endif
-#if FFETARGET_okCOMPLEX6
-static ffebldConstant ffebld_constant_complex6_;
-#endif
-#if FFETARGET_okCOMPLEX7
-static ffebldConstant ffebld_constant_complex7_;
-#endif
-#if FFETARGET_okCOMPLEX8
-static ffebldConstant ffebld_constant_complex8_;
-#endif
#if FFETARGET_okINTEGER1
static ffebldConstant ffebld_constant_integer1_;
#endif
@@ -140,18 +94,6 @@ static ffebldConstant ffebld_constant_integer3_;
#if FFETARGET_okINTEGER4
static ffebldConstant ffebld_constant_integer4_;
#endif
-#if FFETARGET_okINTEGER5
-static ffebldConstant ffebld_constant_integer5_;
-#endif
-#if FFETARGET_okINTEGER6
-static ffebldConstant ffebld_constant_integer6_;
-#endif
-#if FFETARGET_okINTEGER7
-static ffebldConstant ffebld_constant_integer7_;
-#endif
-#if FFETARGET_okINTEGER8
-static ffebldConstant ffebld_constant_integer8_;
-#endif
#if FFETARGET_okLOGICAL1
static ffebldConstant ffebld_constant_logical1_;
#endif
@@ -164,18 +106,6 @@ static ffebldConstant ffebld_constant_logical3_;
#if FFETARGET_okLOGICAL4
static ffebldConstant ffebld_constant_logical4_;
#endif
-#if FFETARGET_okLOGICAL5
-static ffebldConstant ffebld_constant_logical5_;
-#endif
-#if FFETARGET_okLOGICAL6
-static ffebldConstant ffebld_constant_logical6_;
-#endif
-#if FFETARGET_okLOGICAL7
-static ffebldConstant ffebld_constant_logical7_;
-#endif
-#if FFETARGET_okLOGICAL8
-static ffebldConstant ffebld_constant_logical8_;
-#endif
#if FFETARGET_okREAL1
static ffebldConstant ffebld_constant_real1_;
#endif
@@ -185,21 +115,6 @@ static ffebldConstant ffebld_constant_real2_;
#if FFETARGET_okREAL3
static ffebldConstant ffebld_constant_real3_;
#endif
-#if FFETARGET_okREAL4
-static ffebldConstant ffebld_constant_real4_;
-#endif
-#if FFETARGET_okREAL5
-static ffebldConstant ffebld_constant_real5_;
-#endif
-#if FFETARGET_okREAL6
-static ffebldConstant ffebld_constant_real6_;
-#endif
-#if FFETARGET_okREAL7
-static ffebldConstant ffebld_constant_real7_;
-#endif
-#if FFETARGET_okREAL8
-static ffebldConstant ffebld_constant_real8_;
-#endif
static ffebldConstant ffebld_constant_hollerith_;
static ffebldConstant ffebld_constant_typeless_[FFEBLD_constTYPELESS_LAST
- FFEBLD_constTYPELESS_FIRST + 1];
@@ -265,30 +180,6 @@ ffebld_constant_cmp (ffebldConstant c1, ffebldConstant c2)
ffebld_constant_integer4 (c2));
#endif
-#if FFETARGET_okINTEGER5
- case FFEBLD_constINTEGER5:
- return ffetarget_cmp_integer5 (ffebld_constant_integer5 (c1),
- ffebld_constant_integer5 (c2));
-#endif
-
-#if FFETARGET_okINTEGER6
- case FFEBLD_constINTEGER6:
- return ffetarget_cmp_integer6 (ffebld_constant_integer6 (c1),
- ffebld_constant_integer6 (c2));
-#endif
-
-#if FFETARGET_okINTEGER7
- case FFEBLD_constINTEGER7:
- return ffetarget_cmp_integer7 (ffebld_constant_integer7 (c1),
- ffebld_constant_integer7 (c2));
-#endif
-
-#if FFETARGET_okINTEGER8
- case FFEBLD_constINTEGER8:
- return ffetarget_cmp_integer8 (ffebld_constant_integer8 (c1),
- ffebld_constant_integer8 (c2));
-#endif
-
#if FFETARGET_okLOGICAL1
case FFEBLD_constLOGICAL1:
return ffetarget_cmp_logical1 (ffebld_constant_logical1 (c1),
@@ -313,30 +204,6 @@ ffebld_constant_cmp (ffebldConstant c1, ffebldConstant c2)
ffebld_constant_logical4 (c2));
#endif
-#if FFETARGET_okLOGICAL5
- case FFEBLD_constLOGICAL5:
- return ffetarget_cmp_logical5 (ffebld_constant_logical5 (c1),
- ffebld_constant_logical5 (c2));
-#endif
-
-#if FFETARGET_okLOGICAL6
- case FFEBLD_constLOGICAL6:
- return ffetarget_cmp_logical6 (ffebld_constant_logical6 (c1),
- ffebld_constant_logical6 (c2));
-#endif
-
-#if FFETARGET_okLOGICAL7
- case FFEBLD_constLOGICAL7:
- return ffetarget_cmp_logical7 (ffebld_constant_logical7 (c1),
- ffebld_constant_logical7 (c2));
-#endif
-
-#if FFETARGET_okLOGICAL8
- case FFEBLD_constLOGICAL8:
- return ffetarget_cmp_logical8 (ffebld_constant_logical8 (c1),
- ffebld_constant_logical8 (c2));
-#endif
-
#if FFETARGET_okREAL1
case FFEBLD_constREAL1:
return ffetarget_cmp_real1 (ffebld_constant_real1 (c1),
@@ -355,84 +222,12 @@ ffebld_constant_cmp (ffebldConstant c1, ffebldConstant c2)
ffebld_constant_real3 (c2));
#endif
-#if FFETARGET_okREAL4
- case FFEBLD_constREAL4:
- return ffetarget_cmp_real4 (ffebld_constant_real4 (c1),
- ffebld_constant_real4 (c2));
-#endif
-
-#if FFETARGET_okREAL5
- case FFEBLD_constREAL5:
- return ffetarget_cmp_real5 (ffebld_constant_real5 (c1),
- ffebld_constant_real5 (c2));
-#endif
-
-#if FFETARGET_okREAL6
- case FFEBLD_constREAL6:
- return ffetarget_cmp_real6 (ffebld_constant_real6 (c1),
- ffebld_constant_real6 (c2));
-#endif
-
-#if FFETARGET_okREAL7
- case FFEBLD_constREAL7:
- return ffetarget_cmp_real7 (ffebld_constant_real7 (c1),
- ffebld_constant_real7 (c2));
-#endif
-
-#if FFETARGET_okREAL8
- case FFEBLD_constREAL8:
- return ffetarget_cmp_real8 (ffebld_constant_real8 (c1),
- ffebld_constant_real8 (c2));
-#endif
-
#if FFETARGET_okCHARACTER1
case FFEBLD_constCHARACTER1:
return ffetarget_cmp_character1 (ffebld_constant_character1 (c1),
ffebld_constant_character1 (c2));
#endif
-#if FFETARGET_okCHARACTER2
- case FFEBLD_constCHARACTER2:
- return ffetarget_cmp_character2 (ffebld_constant_character2 (c1),
- ffebld_constant_character2 (c2));
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEBLD_constCHARACTER3:
- return ffetarget_cmp_character3 (ffebld_constant_character3 (c1),
- ffebld_constant_character3 (c2));
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEBLD_constCHARACTER4:
- return ffetarget_cmp_character4 (ffebld_constant_character4 (c1),
- ffebld_constant_character4 (c2));
-#endif
-
-#if FFETARGET_okCHARACTER5
- case FFEBLD_constCHARACTER5:
- return ffetarget_cmp_character5 (ffebld_constant_character5 (c1),
- ffebld_constant_character5 (c2));
-#endif
-
-#if FFETARGET_okCHARACTER6
- case FFEBLD_constCHARACTER6:
- return ffetarget_cmp_character6 (ffebld_constant_character6 (c1),
- ffebld_constant_character6 (c2));
-#endif
-
-#if FFETARGET_okCHARACTER7
- case FFEBLD_constCHARACTER7:
- return ffetarget_cmp_character7 (ffebld_constant_character7 (c1),
- ffebld_constant_character7 (c2));
-#endif
-
-#if FFETARGET_okCHARACTER8
- case FFEBLD_constCHARACTER8:
- return ffetarget_cmp_character8 (ffebld_constant_character8 (c1),
- ffebld_constant_character8 (c2));
-#endif
-
default:
assert ("bad constant type" == NULL);
return 0;
@@ -488,26 +283,6 @@ ffebld_constant_is_zero (ffebldConstant c)
return ffebld_constant_integer4 (c) == 0;
#endif
-#if FFETARGET_okINTEGER5
- case FFEBLD_constINTEGER5:
- return ffebld_constant_integer5 (c) == 0;
-#endif
-
-#if FFETARGET_okINTEGER6
- case FFEBLD_constINTEGER6:
- return ffebld_constant_integer6 (c) == 0;
-#endif
-
-#if FFETARGET_okINTEGER7
- case FFEBLD_constINTEGER7:
- return ffebld_constant_integer7 (c) == 0;
-#endif
-
-#if FFETARGET_okINTEGER8
- case FFEBLD_constINTEGER8:
- return ffebld_constant_integer8 (c) == 0;
-#endif
-
#if FFETARGET_okLOGICAL1
case FFEBLD_constLOGICAL1:
return ffebld_constant_logical1 (c) == 0;
@@ -528,26 +303,6 @@ ffebld_constant_is_zero (ffebldConstant c)
return ffebld_constant_logical4 (c) == 0;
#endif
-#if FFETARGET_okLOGICAL5
- case FFEBLD_constLOGICAL5:
- return ffebld_constant_logical5 (c) == 0;
-#endif
-
-#if FFETARGET_okLOGICAL6
- case FFEBLD_constLOGICAL6:
- return ffebld_constant_logical6 (c) == 0;
-#endif
-
-#if FFETARGET_okLOGICAL7
- case FFEBLD_constLOGICAL7:
- return ffebld_constant_logical7 (c) == 0;
-#endif
-
-#if FFETARGET_okLOGICAL8
- case FFEBLD_constLOGICAL8:
- return ffebld_constant_logical8 (c) == 0;
-#endif
-
#if FFETARGET_okREAL1
case FFEBLD_constREAL1:
return ffetarget_iszero_real1 (ffebld_constant_real1 (c));
@@ -563,31 +318,6 @@ ffebld_constant_is_zero (ffebldConstant c)
return ffetarget_iszero_real3 (ffebld_constant_real3 (c));
#endif
-#if FFETARGET_okREAL4
- case FFEBLD_constREAL4:
- return ffetarget_iszero_real4 (ffebld_constant_real4 (c));
-#endif
-
-#if FFETARGET_okREAL5
- case FFEBLD_constREAL5:
- return ffetarget_iszero_real5 (ffebld_constant_real5 (c));
-#endif
-
-#if FFETARGET_okREAL6
- case FFEBLD_constREAL6:
- return ffetarget_iszero_real6 (ffebld_constant_real6 (c));
-#endif
-
-#if FFETARGET_okREAL7
- case FFEBLD_constREAL7:
- return ffetarget_iszero_real7 (ffebld_constant_real7 (c));
-#endif
-
-#if FFETARGET_okREAL8
- case FFEBLD_constREAL8:
- return ffetarget_iszero_real8 (ffebld_constant_real8 (c));
-#endif
-
#if FFETARGET_okCOMPLEX1
case FFEBLD_constCOMPLEX1:
return ffetarget_iszero_real1 (ffebld_constant_complex1 (c).real)
@@ -606,45 +336,11 @@ ffebld_constant_is_zero (ffebldConstant c)
&& ffetarget_iszero_real3 (ffebld_constant_complex3 (c).imaginary);
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEBLD_constCOMPLEX4:
- return ffetarget_iszero_real4 (ffebld_constant_complex4 (c).real)
- && ffetarget_iszero_real4 (ffebld_constant_complex4 (c).imaginary);
-#endif
-
-#if FFETARGET_okCOMPLEX5
- case FFEBLD_constCOMPLEX5:
- return ffetarget_iszero_real5 (ffebld_constant_complex5 (c).real)
- && ffetarget_iszero_real5 (ffebld_constant_complex5 (c).imaginary);
-#endif
-
-#if FFETARGET_okCOMPLEX6
- case FFEBLD_constCOMPLEX6:
- return ffetarget_iszero_real6 (ffebld_constant_complex6 (c).real)
- && ffetarget_iszero_real6 (ffebld_constant_complex6 (c).imaginary);
-#endif
-
-#if FFETARGET_okCOMPLEX7
- case FFEBLD_constCOMPLEX7:
- return ffetarget_iszero_real7 (ffebld_constant_complex7 (c).real)
- && ffetarget_iszero_real7 (ffebld_constant_complex7 (c).imaginary);
-#endif
-
-#if FFETARGET_okCOMPLEX8
- case FFEBLD_constCOMPLEX8:
- return ffetarget_iszero_real8 (ffebld_constant_complex8 (c).real)
- && ffetarget_iszero_real8 (ffebld_constant_complex8 (c).imaginary);
-#endif
-
#if FFETARGET_okCHARACTER1
case FFEBLD_constCHARACTER1:
return ffetarget_iszero_character1 (ffebld_constant_character1 (c));
#endif
-#if FFETARGET_okCHARACTER2 || FFETARGET_okCHARACTER3 /* ... */
-#error "no support for these!!"
-#endif
-
case FFEBLD_constHOLLERITH:
return ffetarget_iszero_hollerith (ffebld_constant_hollerith (c));
@@ -686,40 +382,52 @@ ffebld_constant_new_character1 (ffelexToken t)
ffebldConstant
ffebld_constant_new_character1_val (ffetargetCharacter1 val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- ffetarget_verify_character1 (ffebld_constant_pool(), val);
-
- for (c = (ffebldConstant) &ffebld_constant_character1_;
- c->next != NULL;
- c = c->next)
- {
- malloc_verify_kp (ffebld_constant_pool(),
- c->next,
- sizeof (*(c->next)));
- ffetarget_verify_character1 (ffebld_constant_pool(),
- ffebld_constant_character1 (c->next));
- cmp = ffetarget_cmp_character1 (val,
- ffebld_constant_character1 (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_character1_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constCHARACTER1",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constCHARACTER1;
+ nc->u.character1 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_character1_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_character1 (val, ffebld_constant_character1 (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constCHARACTER1",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constCHARACTER1;
nc->u.character1 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -749,35 +457,56 @@ ffebld_constant_new_complex1 (ffebldConstant real,
ffebldConstant
ffebld_constant_new_complex1_val (ffetargetComplex1 val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- for (c = (ffebldConstant) &ffebld_constant_complex1_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_real1 (val.real, ffebld_constant_complex1 (c->next).real);
- if (cmp == 0)
- cmp = ffetarget_cmp_real1 (val.imaginary,
- ffebld_constant_complex1 (c->next).imaginary);
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_complex1_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constCOMPLEX1",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constCOMPLEX1;
+ nc->u.complex1 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_complex1_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_real1 (val.real,
+ ffebld_constant_complex1 (P).real);
+ if (cmp == 0)
+ cmp = ffetarget_cmp_real1 (val.imaginary,
+ ffebld_constant_complex1 (P).imaginary);
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constCOMPLEX1",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constCOMPLEX1;
nc->u.complex1 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -807,35 +536,56 @@ ffebld_constant_new_complex2 (ffebldConstant real,
ffebldConstant
ffebld_constant_new_complex2_val (ffetargetComplex2 val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- for (c = (ffebldConstant) &ffebld_constant_complex2_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_real2 (val.real, ffebld_constant_complex2 (c->next).real);
- if (cmp == 0)
- cmp = ffetarget_cmp_real2 (val.imaginary,
- ffebld_constant_complex2 (c->next).imaginary);
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_complex2_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constCOMPLEX2",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constCOMPLEX2;
+ nc->u.complex2 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_complex2_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_real2 (val.real,
+ ffebld_constant_complex2 (P).real);
+ if (cmp == 0)
+ cmp = ffetarget_cmp_real2 (val.imaginary,
+ ffebld_constant_complex2 (P).imaginary);
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constCOMPLEX2",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constCOMPLEX2;
nc->u.complex2 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -860,32 +610,52 @@ ffebld_constant_new_hollerith (ffelexToken t)
ffebldConstant
ffebld_constant_new_hollerith_val (ffetargetHollerith val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- for (c = (ffebldConstant) &ffebld_constant_hollerith_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_hollerith (val, ffebld_constant_hollerith (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_hollerith_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constHOLLERITH",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constHOLLERITH;
+ nc->u.hollerith = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_hollerith_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_hollerith (val, ffebld_constant_hollerith (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constHOLLERITH",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constHOLLERITH;
nc->u.hollerith = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -917,32 +687,53 @@ ffebld_constant_new_integer1 (ffelexToken t)
ffebldConstant
ffebld_constant_new_integer1_val (ffetargetInteger1 val)
{
- ffebldConstant c;
- ffebldConstant nc;
- int cmp;
- for (c = (ffebldConstant) &ffebld_constant_integer1_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_integer1 (val, ffebld_constant_integer1 (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant nc;
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_integer1_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constINTEGER1",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constINTEGER1;
+ nc->u.integer1 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_integer1_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_integer1 (val, ffebld_constant_integer1 (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constINTEGER1",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constINTEGER1;
nc->u.integer1 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -955,32 +746,52 @@ ffebld_constant_new_integer1_val (ffetargetInteger1 val)
ffebldConstant
ffebld_constant_new_integer2_val (ffetargetInteger2 val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- for (c = (ffebldConstant) &ffebld_constant_integer2_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_integer2 (val, ffebld_constant_integer2 (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_integer2_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constINTEGER2",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constINTEGER2;
+ nc->u.integer2 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_integer2_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_integer2 (val, ffebld_constant_integer2 (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constINTEGER2",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constINTEGER2;
nc->u.integer2 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -993,32 +804,52 @@ ffebld_constant_new_integer2_val (ffetargetInteger2 val)
ffebldConstant
ffebld_constant_new_integer3_val (ffetargetInteger3 val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- for (c = (ffebldConstant) &ffebld_constant_integer3_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_integer3 (val, ffebld_constant_integer3 (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_integer3_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constINTEGER3",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constINTEGER3;
+ nc->u.integer3 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_integer3_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_integer3 (val, ffebld_constant_integer3 (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constINTEGER3",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constINTEGER3;
nc->u.integer3 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -1031,32 +862,52 @@ ffebld_constant_new_integer3_val (ffetargetInteger3 val)
ffebldConstant
ffebld_constant_new_integer4_val (ffetargetInteger4 val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- for (c = (ffebldConstant) &ffebld_constant_integer4_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_integer4 (val, ffebld_constant_integer4 (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_integer4_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constINTEGER4",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constINTEGER4;
+ nc->u.integer4 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_integer4_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_integer4 (val, ffebld_constant_integer4 (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constINTEGER4",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constINTEGER4;
nc->u.integer4 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -1144,32 +995,52 @@ ffebld_constant_new_logical1 (bool truth)
ffebldConstant
ffebld_constant_new_logical1_val (ffetargetLogical1 val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- for (c = (ffebldConstant) &ffebld_constant_logical1_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_logical1 (val, ffebld_constant_logical1 (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_logical1_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constLOGICAL1",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constLOGICAL1;
+ nc->u.logical1 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_logical1_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_logical1 (val, ffebld_constant_logical1 (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constLOGICAL1",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constLOGICAL1;
nc->u.logical1 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -1182,32 +1053,52 @@ ffebld_constant_new_logical1_val (ffetargetLogical1 val)
ffebldConstant
ffebld_constant_new_logical2_val (ffetargetLogical2 val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- for (c = (ffebldConstant) &ffebld_constant_logical2_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_logical2 (val, ffebld_constant_logical2 (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_logical2_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constLOGICAL2",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constLOGICAL2;
+ nc->u.logical2 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_logical2_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_logical2 (val, ffebld_constant_logical2 (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constLOGICAL2",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constLOGICAL2;
nc->u.logical2 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -1220,32 +1111,52 @@ ffebld_constant_new_logical2_val (ffetargetLogical2 val)
ffebldConstant
ffebld_constant_new_logical3_val (ffetargetLogical3 val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- for (c = (ffebldConstant) &ffebld_constant_logical3_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_logical3 (val, ffebld_constant_logical3 (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_logical3_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constLOGICAL3",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constLOGICAL3;
+ nc->u.logical3 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_logical3_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_logical3 (val, ffebld_constant_logical3 (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constLOGICAL3",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constLOGICAL3;
nc->u.logical3 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -1258,32 +1169,52 @@ ffebld_constant_new_logical3_val (ffetargetLogical3 val)
ffebldConstant
ffebld_constant_new_logical4_val (ffetargetLogical4 val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- for (c = (ffebldConstant) &ffebld_constant_logical4_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_logical4 (val, ffebld_constant_logical4 (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_logical4_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constLOGICAL4",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constLOGICAL4;
+ nc->u.logical4 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_logical4_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_logical4 (val, ffebld_constant_logical4 (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constLOGICAL4",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constLOGICAL4;
nc->u.logical4 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -1314,32 +1245,52 @@ ffebld_constant_new_real1 (ffelexToken integer, ffelexToken decimal,
ffebldConstant
ffebld_constant_new_real1_val (ffetargetReal1 val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- for (c = (ffebldConstant) &ffebld_constant_real1_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_real1 (val, ffebld_constant_real1 (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_real1_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constREAL1",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constREAL1;
+ nc->u.real1 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_real1_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_real1 (val, ffebld_constant_real1 (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constREAL1",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constREAL1;
nc->u.real1 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -1370,32 +1321,52 @@ ffebld_constant_new_real2 (ffelexToken integer, ffelexToken decimal,
ffebldConstant
ffebld_constant_new_real2_val (ffetargetReal2 val)
{
- ffebldConstant c;
ffebldConstant nc;
- int cmp;
-
- for (c = (ffebldConstant) &ffebld_constant_real2_;
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_real2 (val, ffebld_constant_real2 (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_real2_;
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constREAL2",
+ sizeof (*nc));
+ nc->consttype = FFEBLD_constREAL1;
+ nc->u.real2 = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_real2_ = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_real2 (val, ffebld_constant_real2 (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constREAL2",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = FFEBLD_constREAL2;
nc->u.real2 = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -1535,33 +1506,54 @@ ffebld_constant_new_typeless_ov (ffelexToken t)
ffebldConstant
ffebld_constant_new_typeless_val (ffebldConst type, ffetargetTypeless val)
{
- ffebldConstant c;
- ffebldConstant nc;
- int cmp;
- for (c = (ffebldConstant) &ffebld_constant_typeless_[type
- - FFEBLD_constTYPELESS_FIRST];
- c->next != NULL;
- c = c->next)
- {
- cmp = ffetarget_cmp_typeless (val, ffebld_constant_typeless (c->next));
- if (cmp == 0)
- return c->next;
- if (cmp > 0)
- break;
- }
+ ffebldConstant nc;
+ ffebldConstant P;
+ ffebldConstant Q;
+ int cmp = 0;
+ P = ffebld_constant_typeless_[type
+ - FFEBLD_constTYPELESS_FIRST];
+ Q = P;
+ if (!P)
+ {
+ /* make this node the root */
+ nc = malloc_new_kp (ffebld_constant_pool(),
+ "FFEBLD_constTYPELESS",
+ sizeof (*nc));
+ nc->consttype = type;
+ nc->u.typeless = val;
+ nc->hook = FFECOM_constantNULL;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ ffebld_constant_typeless_[type- FFEBLD_constTYPELESS_FIRST] = nc;
+ return nc;
+ }
+ else
+ while (P)
+ {
+ Q = P;
+ cmp = ffetarget_cmp_typeless (val, ffebld_constant_typeless (P));
+ if (cmp > 0)
+ P = P->llink;
+ else if (cmp < 0)
+ P = P->rlink;
+ else
+ return P;
+ }
nc = malloc_new_kp (ffebld_constant_pool(),
"FFEBLD_constTYPELESS",
sizeof (*nc));
- nc->next = c->next;
nc->consttype = type;
nc->u.typeless = val;
-#ifdef FFECOM_constantHOOK
nc->hook = FFECOM_constantNULL;
-#endif
- c->next = nc;
+ nc->llink = NULL;
+ nc->rlink = NULL;
+ if (cmp < 0)
+ Q->llink = nc;
+ else
+ Q->rlink = nc;
return nc;
}
@@ -1604,30 +1596,6 @@ ffebld_constantarray_get (ffebldConstantArray array, ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okINTEGER5
- case FFEINFO_kindtypeINTEGER5:
- u.integer5 = *(array.integer5 + offset);
- break;
-#endif
-
-#if FFETARGET_okINTEGER6
- case FFEINFO_kindtypeINTEGER6:
- u.integer6 = *(array.integer6 + offset);
- break;
-#endif
-
-#if FFETARGET_okINTEGER7
- case FFEINFO_kindtypeINTEGER7:
- u.integer7 = *(array.integer7 + offset);
- break;
-#endif
-
-#if FFETARGET_okINTEGER8
- case FFEINFO_kindtypeINTEGER8:
- u.integer8 = *(array.integer8 + offset);
- break;
-#endif
-
default:
assert ("bad INTEGER kindtype" == NULL);
break;
@@ -1661,30 +1629,6 @@ ffebld_constantarray_get (ffebldConstantArray array, ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okLOGICAL5
- case FFEINFO_kindtypeLOGICAL5:
- u.logical5 = *(array.logical5 + offset);
- break;
-#endif
-
-#if FFETARGET_okLOGICAL6
- case FFEINFO_kindtypeLOGICAL6:
- u.logical6 = *(array.logical6 + offset);
- break;
-#endif
-
-#if FFETARGET_okLOGICAL7
- case FFEINFO_kindtypeLOGICAL7:
- u.logical7 = *(array.logical7 + offset);
- break;
-#endif
-
-#if FFETARGET_okLOGICAL8
- case FFEINFO_kindtypeLOGICAL8:
- u.logical8 = *(array.logical8 + offset);
- break;
-#endif
-
default:
assert ("bad LOGICAL kindtype" == NULL);
break;
@@ -1712,36 +1656,6 @@ ffebld_constantarray_get (ffebldConstantArray array, ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- u.real4 = *(array.real4 + offset);
- break;
-#endif
-
-#if FFETARGET_okREAL5
- case FFEINFO_kindtypeREAL5:
- u.real5 = *(array.real5 + offset);
- break;
-#endif
-
-#if FFETARGET_okREAL6
- case FFEINFO_kindtypeREAL6:
- u.real6 = *(array.real6 + offset);
- break;
-#endif
-
-#if FFETARGET_okREAL7
- case FFEINFO_kindtypeREAL7:
- u.real7 = *(array.real7 + offset);
- break;
-#endif
-
-#if FFETARGET_okREAL8
- case FFEINFO_kindtypeREAL8:
- u.real8 = *(array.real8 + offset);
- break;
-#endif
-
default:
assert ("bad REAL kindtype" == NULL);
break;
@@ -1769,36 +1683,6 @@ ffebld_constantarray_get (ffebldConstantArray array, ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- u.complex4 = *(array.complex4 + offset);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX5
- case FFEINFO_kindtypeREAL5:
- u.complex5 = *(array.complex5 + offset);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX6
- case FFEINFO_kindtypeREAL6:
- u.complex6 = *(array.complex6 + offset);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX7
- case FFEINFO_kindtypeREAL7:
- u.complex7 = *(array.complex7 + offset);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX8
- case FFEINFO_kindtypeREAL8:
- u.complex8 = *(array.complex8 + offset);
- break;
-#endif
-
default:
assert ("bad COMPLEX kindtype" == NULL);
break;
@@ -1815,55 +1699,6 @@ ffebld_constantarray_get (ffebldConstantArray array, ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- u.character2.length = 1;
- u.character2.text = array.character2 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- u.character3.length = 1;
- u.character3.text = array.character3 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- u.character4.length = 1;
- u.character4.text = array.character4 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER5
- case FFEINFO_kindtypeCHARACTER5:
- u.character5.length = 1;
- u.character5.text = array.character5 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER6
- case FFEINFO_kindtypeCHARACTER6:
- u.character6.length = 1;
- u.character6.text = array.character6 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER7
- case FFEINFO_kindtypeCHARACTER7:
- u.character7.length = 1;
- u.character7.text = array.character7 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER8
- case FFEINFO_kindtypeCHARACTER8:
- u.character8.length = 1;
- u.character8.text = array.character8 + offset;
- break;
-#endif
-
default:
assert ("bad CHARACTER kindtype" == NULL);
break;
@@ -1929,42 +1764,6 @@ ffebld_constantarray_new (ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okINTEGER5
- case FFEINFO_kindtypeINTEGER5:
- ptr.integer5 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetInteger5),
- 0);
- break;
-#endif
-
-#if FFETARGET_okINTEGER6
- case FFEINFO_kindtypeINTEGER6:
- ptr.integer6 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetInteger6),
- 0);
- break;
-#endif
-
-#if FFETARGET_okINTEGER7
- case FFEINFO_kindtypeINTEGER7:
- ptr.integer7 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetInteger7),
- 0);
- break;
-#endif
-
-#if FFETARGET_okINTEGER8
- case FFEINFO_kindtypeINTEGER8:
- ptr.integer8 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetInteger8),
- 0);
- break;
-#endif
-
default:
assert ("bad INTEGER kindtype" == NULL);
break;
@@ -2010,42 +1809,6 @@ ffebld_constantarray_new (ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okLOGICAL5
- case FFEINFO_kindtypeLOGICAL5:
- ptr.logical5 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetLogical5),
- 0);
- break;
-#endif
-
-#if FFETARGET_okLOGICAL6
- case FFEINFO_kindtypeLOGICAL6:
- ptr.logical6 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetLogical6),
- 0);
- break;
-#endif
-
-#if FFETARGET_okLOGICAL7
- case FFEINFO_kindtypeLOGICAL7:
- ptr.logical7 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetLogical7),
- 0);
- break;
-#endif
-
-#if FFETARGET_okLOGICAL8
- case FFEINFO_kindtypeLOGICAL8:
- ptr.logical8 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetLogical8),
- 0);
- break;
-#endif
-
default:
assert ("bad LOGICAL kindtype" == NULL);
break;
@@ -2082,51 +1845,6 @@ ffebld_constantarray_new (ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- ptr.real4 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetReal4),
- 0);
- break;
-#endif
-
-#if FFETARGET_okREAL5
- case FFEINFO_kindtypeREAL5:
- ptr.real5 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetReal5),
- 0);
- break;
-#endif
-
-#if FFETARGET_okREAL6
- case FFEINFO_kindtypeREAL6:
- ptr.real6 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetReal6),
- 0);
- break;
-#endif
-
-#if FFETARGET_okREAL7
- case FFEINFO_kindtypeREAL7:
- ptr.real7 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetReal7),
- 0);
- break;
-#endif
-
-#if FFETARGET_okREAL8
- case FFEINFO_kindtypeREAL8:
- ptr.real8 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetReal8),
- 0);
- break;
-#endif
-
default:
assert ("bad REAL kindtype" == NULL);
break;
@@ -2163,51 +1881,6 @@ ffebld_constantarray_new (ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- ptr.complex4 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetComplex4),
- 0);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX5
- case FFEINFO_kindtypeREAL5:
- ptr.complex5 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetComplex5),
- 0);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX6
- case FFEINFO_kindtypeREAL6:
- ptr.complex6 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetComplex6),
- 0);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX7
- case FFEINFO_kindtypeREAL7:
- ptr.complex7 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetComplex7),
- 0);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX8
- case FFEINFO_kindtypeREAL8:
- ptr.complex8 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size *= sizeof (ffetargetComplex8),
- 0);
- break;
-#endif
-
default:
assert ("bad COMPLEX kindtype" == NULL);
break;
@@ -2227,76 +1900,6 @@ ffebld_constantarray_new (ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- ptr.character2 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size
- *= sizeof (ffetargetCharacterUnit2),
- 0);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- ptr.character3 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size
- *= sizeof (ffetargetCharacterUnit3),
- 0);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- ptr.character4 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size
- *= sizeof (ffetargetCharacterUnit4),
- 0);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER5
- case FFEINFO_kindtypeCHARACTER5:
- ptr.character5 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size
- *= sizeof (ffetargetCharacterUnit5),
- 0);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER6
- case FFEINFO_kindtypeCHARACTER6:
- ptr.character6 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size
- *= sizeof (ffetargetCharacterUnit6),
- 0);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER7
- case FFEINFO_kindtypeCHARACTER7:
- ptr.character7 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size
- *= sizeof (ffetargetCharacterUnit7),
- 0);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER8
- case FFEINFO_kindtypeCHARACTER8:
- ptr.character8 = malloc_new_zkp (ffebld_constant_pool(),
- "ffebldConstantArray",
- size
- *= sizeof (ffetargetCharacterUnit8),
- 0);
- break;
-#endif
-
default:
assert ("bad CHARACTER kindtype" == NULL);
break;
@@ -2353,30 +1956,6 @@ ffebld_constantarray_preparray (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okINTEGER5
- case FFEINFO_kindtypeINTEGER5:
- *aptr = array.integer5 + offset;
- break;
-#endif
-
-#if FFETARGET_okINTEGER6
- case FFEINFO_kindtypeINTEGER6:
- *aptr = array.integer6 + offset;
- break;
-#endif
-
-#if FFETARGET_okINTEGER7
- case FFEINFO_kindtypeINTEGER7:
- *aptr = array.integer7 + offset;
- break;
-#endif
-
-#if FFETARGET_okINTEGER8
- case FFEINFO_kindtypeINTEGER8:
- *aptr = array.integer8 + offset;
- break;
-#endif
-
default:
assert ("bad INTEGER akindtype" == NULL);
break;
@@ -2410,30 +1989,6 @@ ffebld_constantarray_preparray (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okLOGICAL5
- case FFEINFO_kindtypeLOGICAL5:
- *aptr = array.logical5 + offset;
- break;
-#endif
-
-#if FFETARGET_okLOGICAL6
- case FFEINFO_kindtypeLOGICAL6:
- *aptr = array.logical6 + offset;
- break;
-#endif
-
-#if FFETARGET_okLOGICAL7
- case FFEINFO_kindtypeLOGICAL7:
- *aptr = array.logical7 + offset;
- break;
-#endif
-
-#if FFETARGET_okLOGICAL8
- case FFEINFO_kindtypeLOGICAL8:
- *aptr = array.logical8 + offset;
- break;
-#endif
-
default:
assert ("bad LOGICAL akindtype" == NULL);
break;
@@ -2461,36 +2016,6 @@ ffebld_constantarray_preparray (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- *aptr = array.real4 + offset;
- break;
-#endif
-
-#if FFETARGET_okREAL5
- case FFEINFO_kindtypeREAL5:
- *aptr = array.real5 + offset;
- break;
-#endif
-
-#if FFETARGET_okREAL6
- case FFEINFO_kindtypeREAL6:
- *aptr = array.real6 + offset;
- break;
-#endif
-
-#if FFETARGET_okREAL7
- case FFEINFO_kindtypeREAL7:
- *aptr = array.real7 + offset;
- break;
-#endif
-
-#if FFETARGET_okREAL8
- case FFEINFO_kindtypeREAL8:
- *aptr = array.real8 + offset;
- break;
-#endif
-
default:
assert ("bad REAL akindtype" == NULL);
break;
@@ -2518,36 +2043,6 @@ ffebld_constantarray_preparray (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- *aptr = array.complex4 + offset;
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX5
- case FFEINFO_kindtypeREAL5:
- *aptr = array.complex5 + offset;
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX6
- case FFEINFO_kindtypeREAL6:
- *aptr = array.complex6 + offset;
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX7
- case FFEINFO_kindtypeREAL7:
- *aptr = array.complex7 + offset;
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX8
- case FFEINFO_kindtypeREAL8:
- *aptr = array.complex8 + offset;
- break;
-#endif
-
default:
assert ("bad COMPLEX akindtype" == NULL);
break;
@@ -2563,48 +2058,6 @@ ffebld_constantarray_preparray (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- *aptr = array.character2 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- *aptr = array.character3 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- *aptr = array.character4 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER5
- case FFEINFO_kindtypeCHARACTER5:
- *aptr = array.character5 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER6
- case FFEINFO_kindtypeCHARACTER6:
- *aptr = array.character6 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER7
- case FFEINFO_kindtypeCHARACTER7:
- *aptr = array.character7 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER8
- case FFEINFO_kindtypeCHARACTER8:
- *aptr = array.character8 + offset;
- break;
-#endif
-
default:
assert ("bad CHARACTER akindtype" == NULL);
break;
@@ -2649,34 +2102,6 @@ ffebld_constantarray_preparray (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okINTEGER5
- case FFEINFO_kindtypeINTEGER5:
- *cptr = source_array.integer5;
- *size = sizeof (*source_array.integer5);
- break;
-#endif
-
-#if FFETARGET_okINTEGER6
- case FFEINFO_kindtypeINTEGER6:
- *cptr = source_array.integer6;
- *size = sizeof (*source_array.integer6);
- break;
-#endif
-
-#if FFETARGET_okINTEGER7
- case FFEINFO_kindtypeINTEGER7:
- *cptr = source_array.integer7;
- *size = sizeof (*source_array.integer7);
- break;
-#endif
-
-#if FFETARGET_okINTEGER8
- case FFEINFO_kindtypeINTEGER8:
- *cptr = source_array.integer8;
- *size = sizeof (*source_array.integer8);
- break;
-#endif
-
default:
assert ("bad INTEGER ckindtype" == NULL);
break;
@@ -2714,34 +2139,6 @@ ffebld_constantarray_preparray (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okLOGICAL5
- case FFEINFO_kindtypeLOGICAL5:
- *cptr = source_array.logical5;
- *size = sizeof (*source_array.logical5);
- break;
-#endif
-
-#if FFETARGET_okLOGICAL6
- case FFEINFO_kindtypeLOGICAL6:
- *cptr = source_array.logical6;
- *size = sizeof (*source_array.logical6);
- break;
-#endif
-
-#if FFETARGET_okLOGICAL7
- case FFEINFO_kindtypeLOGICAL7:
- *cptr = source_array.logical7;
- *size = sizeof (*source_array.logical7);
- break;
-#endif
-
-#if FFETARGET_okLOGICAL8
- case FFEINFO_kindtypeLOGICAL8:
- *cptr = source_array.logical8;
- *size = sizeof (*source_array.logical8);
- break;
-#endif
-
default:
assert ("bad LOGICAL ckindtype" == NULL);
break;
@@ -2772,41 +2169,6 @@ ffebld_constantarray_preparray (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- *cptr = source_array.real4;
- *size = sizeof (*source_array.real4);
- break;
-#endif
-
-#if FFETARGET_okREAL5
- case FFEINFO_kindtypeREAL5:
- *cptr = source_array.real5;
- *size = sizeof (*source_array.real5);
- break;
-#endif
-
-#if FFETARGET_okREAL6
- case FFEINFO_kindtypeREAL6:
- *cptr = source_array.real6;
- *size = sizeof (*source_array.real6);
- break;
-#endif
-
-#if FFETARGET_okREAL7
- case FFEINFO_kindtypeREAL7:
- *cptr = source_array.real7;
- *size = sizeof (*source_array.real7);
- break;
-#endif
-
-#if FFETARGET_okREAL8
- case FFEINFO_kindtypeREAL8:
- *cptr = source_array.real8;
- *size = sizeof (*source_array.real8);
- break;
-#endif
-
default:
assert ("bad REAL ckindtype" == NULL);
break;
@@ -2837,41 +2199,6 @@ ffebld_constantarray_preparray (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- *cptr = source_array.complex4;
- *size = sizeof (*source_array.complex4);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX5
- case FFEINFO_kindtypeREAL5:
- *cptr = source_array.complex5;
- *size = sizeof (*source_array.complex5);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX6
- case FFEINFO_kindtypeREAL6:
- *cptr = source_array.complex6;
- *size = sizeof (*source_array.complex6);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX7
- case FFEINFO_kindtypeREAL7:
- *cptr = source_array.complex7;
- *size = sizeof (*source_array.complex7);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX8
- case FFEINFO_kindtypeREAL8:
- *cptr = source_array.complex8;
- *size = sizeof (*source_array.complex8);
- break;
-#endif
-
default:
assert ("bad COMPLEX ckindtype" == NULL);
break;
@@ -2888,55 +2215,6 @@ ffebld_constantarray_preparray (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- *cptr = source_array.character2;
- *size = sizeof (*source_array.character2);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- *cptr = source_array.character3;
- *size = sizeof (*source_array.character3);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- *cptr = source_array.character4;
- *size = sizeof (*source_array.character4);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER5
- case FFEINFO_kindtypeCHARACTER5:
- *cptr = source_array.character5;
- *size = sizeof (*source_array.character5);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER6
- case FFEINFO_kindtypeCHARACTER6:
- *cptr = source_array.character6;
- *size = sizeof (*source_array.character6);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER7
- case FFEINFO_kindtypeCHARACTER7:
- *cptr = source_array.character7;
- *size = sizeof (*source_array.character7);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER8
- case FFEINFO_kindtypeCHARACTER8:
- *cptr = source_array.character8;
- *size = sizeof (*source_array.character8);
- break;
-#endif
-
default:
assert ("bad CHARACTER ckindtype" == NULL);
break;
@@ -2999,30 +2277,6 @@ ffebld_constantarray_prepare (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okINTEGER5
- case FFEINFO_kindtypeINTEGER5:
- *aptr = array.integer5 + offset;
- break;
-#endif
-
-#if FFETARGET_okINTEGER6
- case FFEINFO_kindtypeINTEGER6:
- *aptr = array.integer6 + offset;
- break;
-#endif
-
-#if FFETARGET_okINTEGER7
- case FFEINFO_kindtypeINTEGER7:
- *aptr = array.integer7 + offset;
- break;
-#endif
-
-#if FFETARGET_okINTEGER8
- case FFEINFO_kindtypeINTEGER8:
- *aptr = array.integer8 + offset;
- break;
-#endif
-
default:
assert ("bad INTEGER akindtype" == NULL);
break;
@@ -3056,30 +2310,6 @@ ffebld_constantarray_prepare (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okLOGICAL5
- case FFEINFO_kindtypeLOGICAL5:
- *aptr = array.logical5 + offset;
- break;
-#endif
-
-#if FFETARGET_okLOGICAL6
- case FFEINFO_kindtypeLOGICAL6:
- *aptr = array.logical6 + offset;
- break;
-#endif
-
-#if FFETARGET_okLOGICAL7
- case FFEINFO_kindtypeLOGICAL7:
- *aptr = array.logical7 + offset;
- break;
-#endif
-
-#if FFETARGET_okLOGICAL8
- case FFEINFO_kindtypeLOGICAL8:
- *aptr = array.logical8 + offset;
- break;
-#endif
-
default:
assert ("bad LOGICAL akindtype" == NULL);
break;
@@ -3107,36 +2337,6 @@ ffebld_constantarray_prepare (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- *aptr = array.real4 + offset;
- break;
-#endif
-
-#if FFETARGET_okREAL5
- case FFEINFO_kindtypeREAL5:
- *aptr = array.real5 + offset;
- break;
-#endif
-
-#if FFETARGET_okREAL6
- case FFEINFO_kindtypeREAL6:
- *aptr = array.real6 + offset;
- break;
-#endif
-
-#if FFETARGET_okREAL7
- case FFEINFO_kindtypeREAL7:
- *aptr = array.real7 + offset;
- break;
-#endif
-
-#if FFETARGET_okREAL8
- case FFEINFO_kindtypeREAL8:
- *aptr = array.real8 + offset;
- break;
-#endif
-
default:
assert ("bad REAL akindtype" == NULL);
break;
@@ -3164,36 +2364,6 @@ ffebld_constantarray_prepare (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- *aptr = array.complex4 + offset;
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX5
- case FFEINFO_kindtypeREAL5:
- *aptr = array.complex5 + offset;
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX6
- case FFEINFO_kindtypeREAL6:
- *aptr = array.complex6 + offset;
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX7
- case FFEINFO_kindtypeREAL7:
- *aptr = array.complex7 + offset;
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX8
- case FFEINFO_kindtypeREAL8:
- *aptr = array.complex8 + offset;
- break;
-#endif
-
default:
assert ("bad COMPLEX akindtype" == NULL);
break;
@@ -3209,48 +2379,6 @@ ffebld_constantarray_prepare (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- *aptr = array.character2 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- *aptr = array.character3 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- *aptr = array.character4 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER5
- case FFEINFO_kindtypeCHARACTER5:
- *aptr = array.character5 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER6
- case FFEINFO_kindtypeCHARACTER6:
- *aptr = array.character6 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER7
- case FFEINFO_kindtypeCHARACTER7:
- *aptr = array.character7 + offset;
- break;
-#endif
-
-#if FFETARGET_okCHARACTER8
- case FFEINFO_kindtypeCHARACTER8:
- *aptr = array.character8 + offset;
- break;
-#endif
-
default:
assert ("bad CHARACTER akindtype" == NULL);
break;
@@ -3295,34 +2423,6 @@ ffebld_constantarray_prepare (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okINTEGER5
- case FFEINFO_kindtypeINTEGER5:
- *cptr = &constant->integer5;
- *size = sizeof (constant->integer5);
- break;
-#endif
-
-#if FFETARGET_okINTEGER6
- case FFEINFO_kindtypeINTEGER6:
- *cptr = &constant->integer6;
- *size = sizeof (constant->integer6);
- break;
-#endif
-
-#if FFETARGET_okINTEGER7
- case FFEINFO_kindtypeINTEGER7:
- *cptr = &constant->integer7;
- *size = sizeof (constant->integer7);
- break;
-#endif
-
-#if FFETARGET_okINTEGER8
- case FFEINFO_kindtypeINTEGER8:
- *cptr = &constant->integer8;
- *size = sizeof (constant->integer8);
- break;
-#endif
-
default:
assert ("bad INTEGER ckindtype" == NULL);
break;
@@ -3360,34 +2460,6 @@ ffebld_constantarray_prepare (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okLOGICAL5
- case FFEINFO_kindtypeLOGICAL5:
- *cptr = &constant->logical5;
- *size = sizeof (constant->logical5);
- break;
-#endif
-
-#if FFETARGET_okLOGICAL6
- case FFEINFO_kindtypeLOGICAL6:
- *cptr = &constant->logical6;
- *size = sizeof (constant->logical6);
- break;
-#endif
-
-#if FFETARGET_okLOGICAL7
- case FFEINFO_kindtypeLOGICAL7:
- *cptr = &constant->logical7;
- *size = sizeof (constant->logical7);
- break;
-#endif
-
-#if FFETARGET_okLOGICAL8
- case FFEINFO_kindtypeLOGICAL8:
- *cptr = &constant->logical8;
- *size = sizeof (constant->logical8);
- break;
-#endif
-
default:
assert ("bad LOGICAL ckindtype" == NULL);
break;
@@ -3418,41 +2490,6 @@ ffebld_constantarray_prepare (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- *cptr = &constant->real4;
- *size = sizeof (constant->real4);
- break;
-#endif
-
-#if FFETARGET_okREAL5
- case FFEINFO_kindtypeREAL5:
- *cptr = &constant->real5;
- *size = sizeof (constant->real5);
- break;
-#endif
-
-#if FFETARGET_okREAL6
- case FFEINFO_kindtypeREAL6:
- *cptr = &constant->real6;
- *size = sizeof (constant->real6);
- break;
-#endif
-
-#if FFETARGET_okREAL7
- case FFEINFO_kindtypeREAL7:
- *cptr = &constant->real7;
- *size = sizeof (constant->real7);
- break;
-#endif
-
-#if FFETARGET_okREAL8
- case FFEINFO_kindtypeREAL8:
- *cptr = &constant->real8;
- *size = sizeof (constant->real8);
- break;
-#endif
-
default:
assert ("bad REAL ckindtype" == NULL);
break;
@@ -3483,41 +2520,6 @@ ffebld_constantarray_prepare (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- *cptr = &constant->complex4;
- *size = sizeof (constant->complex4);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX5
- case FFEINFO_kindtypeREAL5:
- *cptr = &constant->complex5;
- *size = sizeof (constant->complex5);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX6
- case FFEINFO_kindtypeREAL6:
- *cptr = &constant->complex6;
- *size = sizeof (constant->complex6);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX7
- case FFEINFO_kindtypeREAL7:
- *cptr = &constant->complex7;
- *size = sizeof (constant->complex7);
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX8
- case FFEINFO_kindtypeREAL8:
- *cptr = &constant->complex8;
- *size = sizeof (constant->complex8);
- break;
-#endif
-
default:
assert ("bad COMPLEX ckindtype" == NULL);
break;
@@ -3534,55 +2536,6 @@ ffebld_constantarray_prepare (void **aptr, void **cptr, size_t *size,
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- *cptr = ffetarget_text_character2 (constant->character2);
- *size = ffetarget_length_character2 (constant->character2);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- *cptr = ffetarget_text_character3 (constant->character3);
- *size = ffetarget_length_character3 (constant->character3);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- *cptr = ffetarget_text_character4 (constant->character4);
- *size = ffetarget_length_character4 (constant->character4);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER5
- case FFEINFO_kindtypeCHARACTER5:
- *cptr = ffetarget_text_character5 (constant->character5);
- *size = ffetarget_length_character5 (constant->character5);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER6
- case FFEINFO_kindtypeCHARACTER6:
- *cptr = ffetarget_text_character6 (constant->character6);
- *size = ffetarget_length_character6 (constant->character6);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER7
- case FFEINFO_kindtypeCHARACTER7:
- *cptr = ffetarget_text_character7 (constant->character7);
- *size = ffetarget_length_character7 (constant->character7);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER8
- case FFEINFO_kindtypeCHARACTER8:
- *cptr = ffetarget_text_character8 (constant->character8);
- *size = ffetarget_length_character8 (constant->character8);
- break;
-#endif
-
default:
assert ("bad CHARACTER ckindtype" == NULL);
break;
@@ -3632,30 +2585,6 @@ ffebld_constantarray_put (ffebldConstantArray array, ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okINTEGER5
- case FFEINFO_kindtypeINTEGER5:
- *(array.integer5 + offset) = constant.integer5;
- break;
-#endif
-
-#if FFETARGET_okINTEGER6
- case FFEINFO_kindtypeINTEGER6:
- *(array.integer6 + offset) = constant.integer6;
- break;
-#endif
-
-#if FFETARGET_okINTEGER7
- case FFEINFO_kindtypeINTEGER7:
- *(array.integer7 + offset) = constant.integer7;
- break;
-#endif
-
-#if FFETARGET_okINTEGER8
- case FFEINFO_kindtypeINTEGER8:
- *(array.integer8 + offset) = constant.integer8;
- break;
-#endif
-
default:
assert ("bad INTEGER kindtype" == NULL);
break;
@@ -3689,30 +2618,6 @@ ffebld_constantarray_put (ffebldConstantArray array, ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okLOGICAL5
- case FFEINFO_kindtypeLOGICAL5:
- *(array.logical5 + offset) = constant.logical5;
- break;
-#endif
-
-#if FFETARGET_okLOGICAL6
- case FFEINFO_kindtypeLOGICAL6:
- *(array.logical6 + offset) = constant.logical6;
- break;
-#endif
-
-#if FFETARGET_okLOGICAL7
- case FFEINFO_kindtypeLOGICAL7:
- *(array.logical7 + offset) = constant.logical7;
- break;
-#endif
-
-#if FFETARGET_okLOGICAL8
- case FFEINFO_kindtypeLOGICAL8:
- *(array.logical8 + offset) = constant.logical8;
- break;
-#endif
-
default:
assert ("bad LOGICAL kindtype" == NULL);
break;
@@ -3740,36 +2645,6 @@ ffebld_constantarray_put (ffebldConstantArray array, ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- *(array.real4 + offset) = constant.real4;
- break;
-#endif
-
-#if FFETARGET_okREAL5
- case FFEINFO_kindtypeREAL5:
- *(array.real5 + offset) = constant.real5;
- break;
-#endif
-
-#if FFETARGET_okREAL6
- case FFEINFO_kindtypeREAL6:
- *(array.real6 + offset) = constant.real6;
- break;
-#endif
-
-#if FFETARGET_okREAL7
- case FFEINFO_kindtypeREAL7:
- *(array.real7 + offset) = constant.real7;
- break;
-#endif
-
-#if FFETARGET_okREAL8
- case FFEINFO_kindtypeREAL8:
- *(array.real8 + offset) = constant.real8;
- break;
-#endif
-
default:
assert ("bad REAL kindtype" == NULL);
break;
@@ -3797,36 +2672,6 @@ ffebld_constantarray_put (ffebldConstantArray array, ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- *(array.complex4 + offset) = constant.complex4;
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX5
- case FFEINFO_kindtypeREAL5:
- *(array.complex5 + offset) = constant.complex5;
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX6
- case FFEINFO_kindtypeREAL6:
- *(array.complex6 + offset) = constant.complex6;
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX7
- case FFEINFO_kindtypeREAL7:
- *(array.complex7 + offset) = constant.complex7;
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX8
- case FFEINFO_kindtypeREAL8:
- *(array.complex8 + offset) = constant.complex8;
- break;
-#endif
-
default:
assert ("bad COMPLEX kindtype" == NULL);
break;
@@ -3844,62 +2689,6 @@ ffebld_constantarray_put (ffebldConstantArray array, ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- memcpy (array.character2 + offset,
- ffetarget_text_character2 (constant.character2),
- ffetarget_length_character2 (constant.character2));
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- memcpy (array.character3 + offset,
- ffetarget_text_character3 (constant.character3),
- ffetarget_length_character3 (constant.character3));
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- memcpy (array.character4 + offset,
- ffetarget_text_character4 (constant.character4),
- ffetarget_length_character4 (constant.character4));
- break;
-#endif
-
-#if FFETARGET_okCHARACTER5
- case FFEINFO_kindtypeCHARACTER5:
- memcpy (array.character5 + offset,
- ffetarget_text_character5 (constant.character5),
- ffetarget_length_character5 (constant.character5));
- break;
-#endif
-
-#if FFETARGET_okCHARACTER6
- case FFEINFO_kindtypeCHARACTER6:
- memcpy (array.character6 + offset,
- ffetarget_text_character6 (constant.character6),
- ffetarget_length_character6 (constant.character6));
- break;
-#endif
-
-#if FFETARGET_okCHARACTER7
- case FFEINFO_kindtypeCHARACTER7:
- memcpy (array.character7 + offset,
- ffetarget_text_character7 (constant.character7),
- ffetarget_length_character7 (constant.character7));
- break;
-#endif
-
-#if FFETARGET_okCHARACTER8
- case FFEINFO_kindtypeCHARACTER8:
- memcpy (array.character8 + offset,
- ffetarget_text_character8 (constant.character8),
- ffetarget_length_character8 (constant.character8));
- break;
-#endif
-
default:
assert ("bad CHARACTER kindtype" == NULL);
break;
@@ -3917,7 +2706,7 @@ ffebld_constantarray_put (ffebldConstantArray array, ffeinfoBasictype bt,
ffebld_init_0(); */
void
-ffebld_init_0 ()
+ffebld_init_0 (void)
{
assert (FFEBLD_op == ARRAY_SIZE (ffebld_op_string_));
assert (FFEBLD_op == ARRAY_SIZE (ffebld_arity_op_));
@@ -3928,7 +2717,7 @@ ffebld_init_0 ()
ffebld_init_1(); */
void
-ffebld_init_1 ()
+ffebld_init_1 (void)
{
#if FFEBLD_whereconstCURRENT_ == FFEBLD_whereconstFILE_
int i;
@@ -3936,27 +2725,6 @@ ffebld_init_1 ()
#if FFETARGET_okCHARACTER1
ffebld_constant_character1_ = NULL;
#endif
-#if FFETARGET_okCHARACTER2
- ffebld_constant_character2_ = NULL;
-#endif
-#if FFETARGET_okCHARACTER3
- ffebld_constant_character3_ = NULL;
-#endif
-#if FFETARGET_okCHARACTER4
- ffebld_constant_character4_ = NULL;
-#endif
-#if FFETARGET_okCHARACTER5
- ffebld_constant_character5_ = NULL;
-#endif
-#if FFETARGET_okCHARACTER6
- ffebld_constant_character6_ = NULL;
-#endif
-#if FFETARGET_okCHARACTER7
- ffebld_constant_character7_ = NULL;
-#endif
-#if FFETARGET_okCHARACTER8
- ffebld_constant_character8_ = NULL;
-#endif
#if FFETARGET_okCOMPLEX1
ffebld_constant_complex1_ = NULL;
#endif
@@ -3966,21 +2734,6 @@ ffebld_init_1 ()
#if FFETARGET_okCOMPLEX3
ffebld_constant_complex3_ = NULL;
#endif
-#if FFETARGET_okCOMPLEX4
- ffebld_constant_complex4_ = NULL;
-#endif
-#if FFETARGET_okCOMPLEX5
- ffebld_constant_complex5_ = NULL;
-#endif
-#if FFETARGET_okCOMPLEX6
- ffebld_constant_complex6_ = NULL;
-#endif
-#if FFETARGET_okCOMPLEX7
- ffebld_constant_complex7_ = NULL;
-#endif
-#if FFETARGET_okCOMPLEX8
- ffebld_constant_complex8_ = NULL;
-#endif
#if FFETARGET_okINTEGER1
ffebld_constant_integer1_ = NULL;
#endif
@@ -3993,18 +2746,6 @@ ffebld_init_1 ()
#if FFETARGET_okINTEGER4
ffebld_constant_integer4_ = NULL;
#endif
-#if FFETARGET_okINTEGER5
- ffebld_constant_integer5_ = NULL;
-#endif
-#if FFETARGET_okINTEGER6
- ffebld_constant_integer6_ = NULL;
-#endif
-#if FFETARGET_okINTEGER7
- ffebld_constant_integer7_ = NULL;
-#endif
-#if FFETARGET_okINTEGER8
- ffebld_constant_integer8_ = NULL;
-#endif
#if FFETARGET_okLOGICAL1
ffebld_constant_logical1_ = NULL;
#endif
@@ -4017,18 +2758,6 @@ ffebld_init_1 ()
#if FFETARGET_okLOGICAL4
ffebld_constant_logical4_ = NULL;
#endif
-#if FFETARGET_okLOGICAL5
- ffebld_constant_logical5_ = NULL;
-#endif
-#if FFETARGET_okLOGICAL6
- ffebld_constant_logical6_ = NULL;
-#endif
-#if FFETARGET_okLOGICAL7
- ffebld_constant_logical7_ = NULL;
-#endif
-#if FFETARGET_okLOGICAL8
- ffebld_constant_logical8_ = NULL;
-#endif
#if FFETARGET_okREAL1
ffebld_constant_real1_ = NULL;
#endif
@@ -4038,21 +2767,6 @@ ffebld_init_1 ()
#if FFETARGET_okREAL3
ffebld_constant_real3_ = NULL;
#endif
-#if FFETARGET_okREAL4
- ffebld_constant_real4_ = NULL;
-#endif
-#if FFETARGET_okREAL5
- ffebld_constant_real5_ = NULL;
-#endif
-#if FFETARGET_okREAL6
- ffebld_constant_real6_ = NULL;
-#endif
-#if FFETARGET_okREAL7
- ffebld_constant_real7_ = NULL;
-#endif
-#if FFETARGET_okREAL8
- ffebld_constant_real8_ = NULL;
-#endif
ffebld_constant_hollerith_ = NULL;
for (i = FFEBLD_constTYPELESS_FIRST; i <= FFEBLD_constTYPELESS_LAST; ++i)
ffebld_constant_typeless_[i - FFEBLD_constTYPELESS_FIRST] = NULL;
@@ -4064,7 +2778,7 @@ ffebld_init_1 ()
ffebld_init_2(); */
void
-ffebld_init_2 ()
+ffebld_init_2 (void)
{
#if FFEBLD_whereconstCURRENT_ == FFEBLD_whereconstPROGUNIT_
int i;
@@ -4076,27 +2790,6 @@ ffebld_init_2 ()
#if FFETARGET_okCHARACTER1
ffebld_constant_character1_ = NULL;
#endif
-#if FFETARGET_okCHARACTER2
- ffebld_constant_character2_ = NULL;
-#endif
-#if FFETARGET_okCHARACTER3
- ffebld_constant_character3_ = NULL;
-#endif
-#if FFETARGET_okCHARACTER4
- ffebld_constant_character4_ = NULL;
-#endif
-#if FFETARGET_okCHARACTER5
- ffebld_constant_character5_ = NULL;
-#endif
-#if FFETARGET_okCHARACTER6
- ffebld_constant_character6_ = NULL;
-#endif
-#if FFETARGET_okCHARACTER7
- ffebld_constant_character7_ = NULL;
-#endif
-#if FFETARGET_okCHARACTER8
- ffebld_constant_character8_ = NULL;
-#endif
#if FFETARGET_okCOMPLEX1
ffebld_constant_complex1_ = NULL;
#endif
@@ -4106,21 +2799,6 @@ ffebld_init_2 ()
#if FFETARGET_okCOMPLEX3
ffebld_constant_complex3_ = NULL;
#endif
-#if FFETARGET_okCOMPLEX4
- ffebld_constant_complex4_ = NULL;
-#endif
-#if FFETARGET_okCOMPLEX5
- ffebld_constant_complex5_ = NULL;
-#endif
-#if FFETARGET_okCOMPLEX6
- ffebld_constant_complex6_ = NULL;
-#endif
-#if FFETARGET_okCOMPLEX7
- ffebld_constant_complex7_ = NULL;
-#endif
-#if FFETARGET_okCOMPLEX8
- ffebld_constant_complex8_ = NULL;
-#endif
#if FFETARGET_okINTEGER1
ffebld_constant_integer1_ = NULL;
#endif
@@ -4133,18 +2811,6 @@ ffebld_init_2 ()
#if FFETARGET_okINTEGER4
ffebld_constant_integer4_ = NULL;
#endif
-#if FFETARGET_okINTEGER5
- ffebld_constant_integer5_ = NULL;
-#endif
-#if FFETARGET_okINTEGER6
- ffebld_constant_integer6_ = NULL;
-#endif
-#if FFETARGET_okINTEGER7
- ffebld_constant_integer7_ = NULL;
-#endif
-#if FFETARGET_okINTEGER8
- ffebld_constant_integer8_ = NULL;
-#endif
#if FFETARGET_okLOGICAL1
ffebld_constant_logical1_ = NULL;
#endif
@@ -4157,18 +2823,6 @@ ffebld_init_2 ()
#if FFETARGET_okLOGICAL4
ffebld_constant_logical4_ = NULL;
#endif
-#if FFETARGET_okLOGICAL5
- ffebld_constant_logical5_ = NULL;
-#endif
-#if FFETARGET_okLOGICAL6
- ffebld_constant_logical6_ = NULL;
-#endif
-#if FFETARGET_okLOGICAL7
- ffebld_constant_logical7_ = NULL;
-#endif
-#if FFETARGET_okLOGICAL8
- ffebld_constant_logical8_ = NULL;
-#endif
#if FFETARGET_okREAL1
ffebld_constant_real1_ = NULL;
#endif
@@ -4178,21 +2832,6 @@ ffebld_init_2 ()
#if FFETARGET_okREAL3
ffebld_constant_real3_ = NULL;
#endif
-#if FFETARGET_okREAL4
- ffebld_constant_real4_ = NULL;
-#endif
-#if FFETARGET_okREAL5
- ffebld_constant_real5_ = NULL;
-#endif
-#if FFETARGET_okREAL6
- ffebld_constant_real6_ = NULL;
-#endif
-#if FFETARGET_okREAL7
- ffebld_constant_real7_ = NULL;
-#endif
-#if FFETARGET_okREAL8
- ffebld_constant_real8_ = NULL;
-#endif
ffebld_constant_hollerith_ = NULL;
for (i = FFEBLD_constTYPELESS_FIRST; i <= FFEBLD_constTYPELESS_LAST; ++i)
ffebld_constant_typeless_[i - FFEBLD_constTYPELESS_FIRST] = NULL;
@@ -4231,9 +2870,6 @@ ffebld_new_accter (ffebldConstantArray a, ffebit b)
ffebld x;
x = ffebld_new ();
-#if FFEBLD_BLANK_
- *x = ffebld_blank_;
-#endif
x->op = FFEBLD_opACCTER;
x->u.accter.array = a;
x->u.accter.bits = b;
@@ -4254,9 +2890,6 @@ ffebld_new_arrter (ffebldConstantArray a, ffetargetOffset size)
ffebld x;
x = ffebld_new ();
-#if FFEBLD_BLANK_
- *x = ffebld_blank_;
-#endif
x->op = FFEBLD_opARRTER;
x->u.arrter.array = a;
x->u.arrter.size = size;
@@ -4276,9 +2909,6 @@ ffebld_new_conter_with_orig (ffebldConstant c, ffebld o)
ffebld x;
x = ffebld_new ();
-#if FFEBLD_BLANK_
- *x = ffebld_blank_;
-#endif
x->op = FFEBLD_opCONTER;
x->u.conter.expr = c;
x->u.conter.orig = o;
@@ -4297,15 +2927,9 @@ ffebld_new_item (ffebld head, ffebld trail)
ffebld x;
x = ffebld_new ();
-#if FFEBLD_BLANK_
- *x = ffebld_blank_;
-#endif
x->op = FFEBLD_opITEM;
x->u.item.head = head;
x->u.item.trail = trail;
-#ifdef FFECOM_itemHOOK
- x->u.item.hook = FFECOM_itemNULL;
-#endif
return x;
}
@@ -4321,9 +2945,6 @@ ffebld_new_labter (ffelab l)
ffebld x;
x = ffebld_new ();
-#if FFEBLD_BLANK_
- *x = ffebld_blank_;
-#endif
x->op = FFEBLD_opLABTER;
x->u.labter = l;
return x;
@@ -4346,9 +2967,6 @@ ffebld_new_labtok (ffelexToken t)
ffebld x;
x = ffebld_new ();
-#if FFEBLD_BLANK_
- *x = ffebld_blank_;
-#endif
x->op = FFEBLD_opLABTOK;
x->u.labtok = t;
return x;
@@ -4365,9 +2983,6 @@ ffebld_new_none (ffebldOp o)
ffebld x;
x = ffebld_new ();
-#if FFEBLD_BLANK_
- *x = ffebld_blank_;
-#endif
x->op = o;
return x;
}
@@ -4383,14 +2998,9 @@ ffebld_new_one (ffebldOp o, ffebld left)
ffebld x;
x = ffebld_new ();
-#if FFEBLD_BLANK_
- *x = ffebld_blank_;
-#endif
x->op = o;
x->u.nonter.left = left;
-#ifdef FFECOM_nonterHOOK
x->u.nonter.hook = FFECOM_nonterNULL;
-#endif
return x;
}
@@ -4410,9 +3020,6 @@ ffebld_new_symter (ffesymbol s, ffeintrinGen gen, ffeintrinSpec spec,
ffebld x;
x = ffebld_new ();
-#if FFEBLD_BLANK_
- *x = ffebld_blank_;
-#endif
x->op = FFEBLD_opSYMTER;
x->u.symter.symbol = s;
x->u.symter.generic = gen;
@@ -4433,15 +3040,10 @@ ffebld_new_two (ffebldOp o, ffebld left, ffebld right)
ffebld x;
x = ffebld_new ();
-#if FFEBLD_BLANK_
- *x = ffebld_blank_;
-#endif
x->op = o;
x->u.nonter.left = left;
x->u.nonter.right = right;
-#ifdef FFECOM_nonterHOOK
x->u.nonter.hook = FFECOM_nonterNULL;
-#endif
return x;
}
@@ -4450,7 +3052,7 @@ ffebld_new_two (ffebldOp o, ffebld left, ffebld right)
ffebld_pool_pop(); */
void
-ffebld_pool_pop ()
+ffebld_pool_pop (void)
{
ffebldPoolstack_ ps;
diff --git a/contrib/gcc/f/bld.h b/contrib/gcc/f/bld.h
index e7285e62b010..900b5dea0199 100644
--- a/contrib/gcc/f/bld.h
+++ b/contrib/gcc/f/bld.h
@@ -1,5 +1,5 @@
/* bld.h -- Public #include File (module.h template V1.0)
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -154,18 +154,6 @@ union _ffebld_constant_union_
#if FFETARGET_okINTEGER4
ffetargetInteger4 integer4;
#endif
-#if FFETARGET_okINTEGER5
- ffetargetInteger5 integer5;
-#endif
-#if FFETARGET_okINTEGER6
- ffetargetInteger6 integer6;
-#endif
-#if FFETARGET_okINTEGER7
- ffetargetInteger7 integer7;
-#endif
-#if FFETARGET_okINTEGER8
- ffetargetInteger8 integer8;
-#endif
#if FFETARGET_okLOGICAL1
ffetargetLogical1 logical1;
#endif
@@ -178,18 +166,6 @@ union _ffebld_constant_union_
#if FFETARGET_okLOGICAL4
ffetargetLogical4 logical4;
#endif
-#if FFETARGET_okLOGICAL5
- ffetargetLogical5 logical5;
-#endif
-#if FFETARGET_okLOGICAL6
- ffetargetLogical6 logical6;
-#endif
-#if FFETARGET_okLOGICAL7
- ffetargetLogical7 logical7;
-#endif
-#if FFETARGET_okLOGICAL8
- ffetargetLogical8 logical8;
-#endif
#if FFETARGET_okREAL1
ffetargetReal1 real1;
#endif
@@ -199,21 +175,6 @@ union _ffebld_constant_union_
#if FFETARGET_okREAL3
ffetargetReal3 real3;
#endif
-#if FFETARGET_okREAL4
- ffetargetReal4 real4;
-#endif
-#if FFETARGET_okREAL5
- ffetargetReal5 real5;
-#endif
-#if FFETARGET_okREAL6
- ffetargetReal6 real6;
-#endif
-#if FFETARGET_okREAL7
- ffetargetReal7 real7;
-#endif
-#if FFETARGET_okREAL8
- ffetargetReal8 real8;
-#endif
#if FFETARGET_okCOMPLEX1
ffetargetComplex1 complex1;
#endif
@@ -223,45 +184,9 @@ union _ffebld_constant_union_
#if FFETARGET_okCOMPLEX3
ffetargetComplex3 complex3;
#endif
-#if FFETARGET_okCOMPLEX4
- ffetargetComplex4 complex4;
-#endif
-#if FFETARGET_okCOMPLEX5
- ffetargetComplex5 complex5;
-#endif
-#if FFETARGET_okCOMPLEX6
- ffetargetComplex6 complex6;
-#endif
-#if FFETARGET_okCOMPLEX7
- ffetargetComplex7 complex7;
-#endif
-#if FFETARGET_okCOMPLEX8
- ffetargetComplex8 complex8;
-#endif
#if FFETARGET_okCHARACTER1
ffetargetCharacter1 character1;
#endif
-#if FFETARGET_okCHARACTER2
- ffetargetCharacter2 character2;
-#endif
-#if FFETARGET_okCHARACTER3
- ffetargetCharacter3 character3;
-#endif
-#if FFETARGET_okCHARACTER4
- ffetargetCharacter4 character4;
-#endif
-#if FFETARGET_okCHARACTER5
- ffetargetCharacter5 character5;
-#endif
-#if FFETARGET_okCHARACTER6
- ffetargetCharacter6 character6;
-#endif
-#if FFETARGET_okCHARACTER7
- ffetargetCharacter7 character7;
-#endif
-#if FFETARGET_okCHARACTER8
- ffetargetCharacter8 character8;
-#endif
};
union _ffebld_constant_array_
@@ -278,18 +203,6 @@ union _ffebld_constant_array_
#if FFETARGET_okINTEGER4
ffetargetInteger4 *integer4;
#endif
-#if FFETARGET_okINTEGER5
- ffetargetInteger5 *integer5;
-#endif
-#if FFETARGET_okINTEGER6
- ffetargetInteger6 *integer6;
-#endif
-#if FFETARGET_okINTEGER7
- ffetargetInteger7 *integer7;
-#endif
-#if FFETARGET_okINTEGER8
- ffetargetInteger8 *integer8;
-#endif
#if FFETARGET_okLOGICAL1
ffetargetLogical1 *logical1;
#endif
@@ -302,18 +215,6 @@ union _ffebld_constant_array_
#if FFETARGET_okLOGICAL4
ffetargetLogical4 *logical4;
#endif
-#if FFETARGET_okLOGICAL5
- ffetargetLogical5 *logical5;
-#endif
-#if FFETARGET_okLOGICAL6
- ffetargetLogical6 *logical6;
-#endif
-#if FFETARGET_okLOGICAL7
- ffetargetLogical7 *logical7;
-#endif
-#if FFETARGET_okLOGICAL8
- ffetargetLogical8 *logical8;
-#endif
#if FFETARGET_okREAL1
ffetargetReal1 *real1;
#endif
@@ -323,21 +224,6 @@ union _ffebld_constant_array_
#if FFETARGET_okREAL3
ffetargetReal3 *real3;
#endif
-#if FFETARGET_okREAL4
- ffetargetReal4 *real4;
-#endif
-#if FFETARGET_okREAL5
- ffetargetReal5 *real5;
-#endif
-#if FFETARGET_okREAL6
- ffetargetReal6 *real6;
-#endif
-#if FFETARGET_okREAL7
- ffetargetReal7 *real7;
-#endif
-#if FFETARGET_okREAL8
- ffetargetReal8 *real8;
-#endif
#if FFETARGET_okCOMPLEX1
ffetargetComplex1 *complex1;
#endif
@@ -347,45 +233,9 @@ union _ffebld_constant_array_
#if FFETARGET_okCOMPLEX3
ffetargetComplex3 *complex3;
#endif
-#if FFETARGET_okCOMPLEX4
- ffetargetComplex4 *complex4;
-#endif
-#if FFETARGET_okCOMPLEX5
- ffetargetComplex5 *complex5;
-#endif
-#if FFETARGET_okCOMPLEX6
- ffetargetComplex6 *complex6;
-#endif
-#if FFETARGET_okCOMPLEX7
- ffetargetComplex7 *complex7;
-#endif
-#if FFETARGET_okCOMPLEX8
- ffetargetComplex8 *complex8;
-#endif
#if FFETARGET_okCHARACTER1
ffetargetCharacterUnit1 *character1;
#endif
-#if FFETARGET_okCHARACTER2
- ffetargetCharacterUnit2 *character2;
-#endif
-#if FFETARGET_okCHARACTER3
- ffetargetCharacterUnit3 *character3;
-#endif
-#if FFETARGET_okCHARACTER4
- ffetargetCharacterUnit4 *character4;
-#endif
-#if FFETARGET_okCHARACTER5
- ffetargetCharacterUnit5 *character5;
-#endif
-#if FFETARGET_okCHARACTER6
- ffetargetCharacterUnit6 *character6;
-#endif
-#if FFETARGET_okCHARACTER7
- ffetargetCharacterUnit7 *character7;
-#endif
-#if FFETARGET_okCHARACTER8
- ffetargetCharacterUnit8 *character8;
-#endif
};
struct _ffebld_
@@ -400,18 +250,13 @@ struct _ffebld_
{
ffebld left;
ffebld right;
-#ifdef FFECOM_nonterHOOK
ffecomNonter hook; /* Whatever the compiler/backend wants! */
-#endif
}
nonter;
struct
{
ffebld head;
ffebld trail;
-#ifdef FFECOM_itemHOOK
- ffecomItem hook; /* Whatever the compiler/backend wants! */
-#endif
}
item;
struct
@@ -454,14 +299,12 @@ struct _ffebld_
struct _ffebld_constant_
{
- ffebldConstant next;
+ ffebldConstant rlink;
+ ffebldConstant llink;
ffebldConstant first_complex; /* First complex const with me as
real. */
- ffebldConstant negated; /* We point to each other through here. */
ffebldConst consttype;
-#ifdef FFECOM_constantHOOK
ffecomConstant hook; /* Whatever the compiler/backend wants! */
-#endif
bool numeric; /* A numeric kind of constant. */
ffebldConstantUnion u;
};
@@ -486,34 +329,6 @@ bool ffebld_constant_is_zero (ffebldConstant c);
ffebldConstant ffebld_constant_new_character1 (ffelexToken t);
ffebldConstant ffebld_constant_new_character1_val (ffetargetCharacter1 val);
#endif
-#if FFETARGET_okCHARACTER2
-ffebldConstant ffebld_constant_new_character2 (ffelexToken t);
-ffebldConstant ffebld_constant_new_character2_val (ffetargetCharacter2 val);
-#endif
-#if FFETARGET_okCHARACTER3
-ffebldConstant ffebld_constant_new_character3 (ffelexToken t);
-ffebldConstant ffebld_constant_new_character3_val (ffetargetCharacter3 val);
-#endif
-#if FFETARGET_okCHARACTER4
-ffebldConstant ffebld_constant_new_character4 (ffelexToken t);
-ffebldConstant ffebld_constant_new_character4_val (ffetargetCharacter4 val);
-#endif
-#if FFETARGET_okCHARACTER5
-ffebldConstant ffebld_constant_new_character5 (ffelexToken t);
-ffebldConstant ffebld_constant_new_character5_val (ffetargetCharacter5 val);
-#endif
-#if FFETARGET_okCHARACTER6
-ffebldConstant ffebld_constant_new_character6 (ffelexToken t);
-ffebldConstant ffebld_constant_new_character6_val (ffetargetCharacter6 val);
-#endif
-#if FFETARGET_okCHARACTER7
-ffebldConstant ffebld_constant_new_character7 (ffelexToken t);
-ffebldConstant ffebld_constant_new_character7_val (ffetargetCharacter7 val);
-#endif
-#if FFETARGET_okCHARACTER8
-ffebldConstant ffebld_constant_new_character8 (ffelexToken t);
-ffebldConstant ffebld_constant_new_character8_val (ffetargetCharacter8 val);
-#endif
#if FFETARGET_okCOMPLEX1
ffebldConstant ffebld_constant_new_complex1 (ffebldConstant real,
ffebldConstant imaginary);
@@ -529,31 +344,6 @@ ffebldConstant ffebld_constant_new_complex3 (ffebldConstant real,
ffebldConstant imaginary);
ffebldConstant ffebld_constant_new_complex3_val (ffetargetComplex3 val);
#endif
-#if FFETARGET_okCOMPLEX4
-ffebldConstant ffebld_constant_new_complex4 (ffebldConstant real,
- ffebldConstant imaginary);
-ffebldConstant ffebld_constant_new_complex4_val (ffetargetComplex4 val);
-#endif
-#if FFETARGET_okCOMPLEX5
-ffebldConstant ffebld_constant_new_complex5 (ffebldConstant real,
- ffebldConstant imaginary);
-ffebldConstant ffebld_constant_new_complex5_val (ffetargetComplex5 val);
-#endif
-#if FFETARGET_okCOMPLEX6
-ffebldConstant ffebld_constant_new_complex6 (ffebldConstant real,
- ffebldConstant imaginary);
-ffebldConstant ffebld_constant_new_complex6_val (ffetargetComplex6 val);
-#endif
-#if FFETARGET_okCOMPLEX7
-ffebldConstant ffebld_constant_new_complex7 (ffebldConstant real,
- ffebldConstant imaginary);
-ffebldConstant ffebld_constant_new_complex7_val (ffetargetComplex7 val);
-#endif
-#if FFETARGET_okCOMPLEX8
-ffebldConstant ffebld_constant_new_complex8 (ffebldConstant real,
- ffebldConstant imaginary);
-ffebldConstant ffebld_constant_new_complex8_val (ffetargetComplex8 val);
-#endif
ffebldConstant ffebld_constant_new_hollerith (ffelexToken t);
ffebldConstant ffebld_constant_new_hollerith_val (ffetargetHollerith val);
#if FFETARGET_okINTEGER1
@@ -572,22 +362,6 @@ ffebldConstant ffebld_constant_new_integer3_val (ffetargetInteger3 val);
ffebldConstant ffebld_constant_new_integer4 (ffelexToken t);
ffebldConstant ffebld_constant_new_integer4_val (ffetargetInteger4 val);
#endif
-#if FFETARGET_okINTEGER5
-ffebldConstant ffebld_constant_new_integer5 (ffelexToken t);
-ffebldConstant ffebld_constant_new_integer5_val (ffetargetInteger5 val);
-#endif
-#if FFETARGET_okINTEGER6
-ffebldConstant ffebld_constant_new_integer6 (ffelexToken t);
-ffebldConstant ffebld_constant_new_integer6_val (ffetargetInteger6 val);
-#endif
-#if FFETARGET_okINTEGER7
-ffebldConstant ffebld_constant_new_integer7 (ffelexToken t);
-ffebldConstant ffebld_constant_new_integer7_val (ffetargetInteger7 val);
-#endif
-#if FFETARGET_okINTEGER8
-ffebldConstant ffebld_constant_new_integer8 (ffelexToken t);
-ffebldConstant ffebld_constant_new_integer8_val (ffetargetInteger8 val);
-#endif
ffebldConstant ffebld_constant_new_integerbinary (ffelexToken t);
ffebldConstant ffebld_constant_new_integerhex (ffelexToken t);
ffebldConstant ffebld_constant_new_integeroctal (ffelexToken t);
@@ -607,22 +381,6 @@ ffebldConstant ffebld_constant_new_logical3_val (ffetargetLogical3 val);
ffebldConstant ffebld_constant_new_logical4 (bool truth);
ffebldConstant ffebld_constant_new_logical4_val (ffetargetLogical4 val);
#endif
-#if FFETARGET_okLOGICAL5
-ffebldConstant ffebld_constant_new_logical5 (bool truth);
-ffebldConstant ffebld_constant_new_logical5_val (ffetargetLogical5 val);
-#endif
-#if FFETARGET_okLOGICAL6
-ffebldConstant ffebld_constant_new_logical6 (bool truth);
-ffebldConstant ffebld_constant_new_logical6_val (ffetargetLogical6 val);
-#endif
-#if FFETARGET_okLOGICAL7
-ffebldConstant ffebld_constant_new_logical7 (bool truth);
-ffebldConstant ffebld_constant_new_logical7_val (ffetargetLogical7 val);
-#endif
-#if FFETARGET_okLOGICAL8
-ffebldConstant ffebld_constant_new_logical8 (bool truth);
-ffebldConstant ffebld_constant_new_logical8_val (ffetargetLogical8 val);
-#endif
#if FFETARGET_okREAL1
ffebldConstant ffebld_constant_new_real1 (ffelexToken integer,
ffelexToken decimal, ffelexToken fraction, ffelexToken exponent,
@@ -641,36 +399,6 @@ ffebldConstant ffebld_constant_new_real3 (ffelexToken integer,
ffelexToken exponent_sign, ffelexToken exponent_digits);
ffebldConstant ffebld_constant_new_real3_val (ffetargetReal3 val);
#endif
-#if FFETARGET_okREAL4
-ffebldConstant ffebld_constant_new_real4 (ffelexToken integer,
- ffelexToken decimal, ffelexToken fraction, ffelexToken exponent,
- ffelexToken exponent_sign, ffelexToken exponent_digits);
-ffebldConstant ffebld_constant_new_real4_val (ffetargetReal4 val);
-#endif
-#if FFETARGET_okREAL5
-ffebldConstant ffebld_constant_new_real5 (ffelexToken integer,
- ffelexToken decimal, ffelexToken fraction, ffelexToken exponent,
- ffelexToken exponent_sign, ffelexToken exponent_digits);
-ffebldConstant ffebld_constant_new_real5_val (ffetargetReal5 val);
-#endif
-#if FFETARGET_okREAL6
-ffebldConstant ffebld_constant_new_real6 (ffelexToken integer,
- ffelexToken decimal, ffelexToken fraction, ffelexToken exponent,
- ffelexToken exponent_sign, ffelexToken exponent_digits);
-ffebldConstant ffebld_constant_new_real6_val (ffetargetReal6 val);
-#endif
-#if FFETARGET_okREAL7
-ffebldConstant ffebld_constant_new_real7 (ffelexToken integer,
- ffelexToken decimal, ffelexToken fraction, ffelexToken exponent,
- ffelexToken exponent_sign, ffelexToken exponent_digits);
-ffebldConstant ffebld_constant_new_real7_val (ffetargetReal7 val);
-#endif
-#if FFETARGET_okREAL8
-ffebldConstant ffebld_constant_new_real8 (ffelexToken integer,
- ffelexToken decimal, ffelexToken fraction, ffelexToken exponent,
- ffelexToken exponent_sign, ffelexToken exponent_digits);
-ffebldConstant ffebld_constant_new_real8_val (ffetargetReal8 val);
-#endif
ffebldConstant ffebld_constant_new_typeless_bm (ffelexToken t);
ffebldConstant ffebld_constant_new_typeless_bv (ffelexToken t);
ffebldConstant ffebld_constant_new_typeless_hxm (ffelexToken t);
diff --git a/contrib/gcc/f/bugs.texi b/contrib/gcc/f/bugs.texi
index 176072c0d214..fdc4f159deba 100644
--- a/contrib/gcc/f/bugs.texi
+++ b/contrib/gcc/f/bugs.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+@c Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
@c This is part of the G77 manual.
@c For copying conditions, see the file g77.texi.
@@ -7,9 +7,9 @@
@c Keep this the same as the dates above, since it's used
@c in the standalone derivations of this file (e.g. BUGS).
-@set copyrights-bugs 1995,1996,1997,1998,1999,2000,2001,2002
+@set copyrights-bugs 1995,1996,1997,1998,1999,2000,2001,2002,2004
-@set last-update-bugs 2002-02-01
+@set last-update-bugs 2004-05-18
@ifset DOC-BUGS
@include root.texi
@@ -74,13 +74,6 @@ is expected to contain documentation that is
most consistent with the @code{g77} product in that version.
@end ifset
-An online, ``live'' version of this document
-(derived directly from the mainline, development version
-of @code{g77} within @code{gcc})
-is available via
-@uref{http://gcc.gnu.org/onlinedocs/g77/Trouble.html}.
-Follow the ``Known Bugs'' link.
-
The following information was last updated on @value{last-update-bugs}:
@itemize @bullet
diff --git a/contrib/gcc/f/com-rt.def b/contrib/gcc/f/com-rt.def
index 43344d938c42..185aef52d058 100644
--- a/contrib/gcc/f/com-rt.def
+++ b/contrib/gcc/f/com-rt.def
@@ -128,7 +128,7 @@ DEFGFRT (FFECOM_gfrtAMOD, "r_mod", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE, F
DEFGFRT (FFECOM_gfrtANINT, "r_nint", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE, FALSE)
DEFGFRT (FFECOM_gfrtASIN, "r_asin", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE, FALSE)
DEFGFRT (FFECOM_gfrtATAN, "r_atan", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE, FALSE)
-DEFGFRT (FFECOM_gfrtATAN2, "r_atn2", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE, FALSE)
+DEFGFRT (FFECOM_gfrtATAN2, "r_atn2", FFECOM_rttypeREAL_F2C_, "&f&f", FALSE, FALSE, FALSE)
DEFGFRT (FFECOM_gfrtCABS, "c_abs", FFECOM_rttypeREAL_F2C_, "&c", FALSE, FALSE, FALSE)
DEFGFRT (FFECOM_gfrtCCOS, "c_cos", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE, FALSE)
DEFGFRT (FFECOM_gfrtCEXP, "c_exp", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE, FALSE)
@@ -259,22 +259,22 @@ DEFGFRT (FFECOM_gfrtDIMAG, "d_imag", FFECOM_rttypeDOUBLE_, "&e", FALSE, FALSE, F
DEFGFRT (FFECOM_gfrtL_ACOS, "acos", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
DEFGFRT (FFECOM_gfrtL_ASIN, "asin", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
-DEFGFRT (FFECOM_gfrtL_ATAN, "atan", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
-DEFGFRT (FFECOM_gfrtL_ATAN2, "atan2", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
+DEFGFRT (FFECOM_gfrtL_ATAN, "__builtin_atan", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
+DEFGFRT (FFECOM_gfrtL_ATAN2, "__builtin_atan2", FFECOM_rttypeDOUBLE_, "dd", FALSE, FALSE, TRUE)
DEFGFRT (FFECOM_gfrtL_COS, "__builtin_cos", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
DEFGFRT (FFECOM_gfrtL_COSH, "cosh", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
DEFGFRT (FFECOM_gfrtL_ERF, "erf", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
DEFGFRT (FFECOM_gfrtL_ERFC, "erfc", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
-DEFGFRT (FFECOM_gfrtL_EXP, "exp", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
-DEFGFRT (FFECOM_gfrtL_FLOOR, "floor", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
-DEFGFRT (FFECOM_gfrtL_FMOD, "fmod", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
-DEFGFRT (FFECOM_gfrtL_LOG, "log", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
+DEFGFRT (FFECOM_gfrtL_EXP, "__builtin_exp", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
+DEFGFRT (FFECOM_gfrtL_FLOOR, "__builtin_floor", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
+DEFGFRT (FFECOM_gfrtL_FMOD, "__builtin_fmod", FFECOM_rttypeDOUBLE_, "dd", FALSE, FALSE, TRUE)
+DEFGFRT (FFECOM_gfrtL_LOG, "__builtin_log", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
DEFGFRT (FFECOM_gfrtL_LOG10, "log10", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
-DEFGFRT (FFECOM_gfrtL_POW, "pow", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
+DEFGFRT (FFECOM_gfrtL_POW, "__builtin_pow", FFECOM_rttypeDOUBLE_, "dd", FALSE, FALSE, TRUE)
DEFGFRT (FFECOM_gfrtL_SIN, "__builtin_sin", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
DEFGFRT (FFECOM_gfrtL_SINH, "sinh", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
DEFGFRT (FFECOM_gfrtL_SQRT, "__builtin_sqrt", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
-DEFGFRT (FFECOM_gfrtL_TAN, "tan", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
+DEFGFRT (FFECOM_gfrtL_TAN, "__builtin_tan", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
DEFGFRT (FFECOM_gfrtL_TANH, "tanh", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE, TRUE)
DEFGFRT (FFECOM_gfrtPOW_CI, "pow_ci", FFECOM_rttypeCOMPLEX_F2C_, "&c&i", FALSE, TRUE, FALSE)
diff --git a/contrib/gcc/f/com.c b/contrib/gcc/f/com.c
index fca0f94ac9d6..a64ef86b1724 100644
--- a/contrib/gcc/f/com.c
+++ b/contrib/gcc/f/com.c
@@ -1,5 +1,5 @@
/* com.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by James Craig Burley.
@@ -168,7 +168,7 @@ tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype];
appropriate _tree_type array element. */
static GTY(()) tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
-static GTY(()) tree
+static GTY(()) tree
ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype];
static GTY(()) tree ffecom_tree_subr_type;
static GTY(()) tree ffecom_tree_ptr_to_subr_type;
@@ -264,14 +264,14 @@ struct _ffecom_concat_list_
/* Static functions (internal). */
-static tree ffe_type_for_mode PARAMS ((enum machine_mode, int));
-static tree ffe_type_for_size PARAMS ((unsigned int, int));
-static tree ffe_unsigned_type PARAMS ((tree));
-static tree ffe_signed_type PARAMS ((tree));
-static tree ffe_signed_or_unsigned_type PARAMS ((int, tree));
-static bool ffe_mark_addressable PARAMS ((tree));
-static tree ffe_truthvalue_conversion PARAMS ((tree));
-static void ffecom_init_decl_processing PARAMS ((void));
+static tree ffe_type_for_mode (enum machine_mode, int);
+static tree ffe_type_for_size (unsigned int, int);
+static tree ffe_unsigned_type (tree);
+static tree ffe_signed_type (tree);
+static tree ffe_signed_or_unsigned_type (int, tree);
+static bool ffe_mark_addressable (tree);
+static tree ffe_truthvalue_conversion (tree);
+static void ffecom_init_decl_processing (void);
static tree ffecom_arglist_expr_ (const char *argstring, ffebld args);
static tree ffecom_widest_expr_type_ (ffebld list);
static bool ffecom_overlap_ (tree dest_decl, tree dest_offset,
@@ -389,7 +389,6 @@ static tree start_decl (tree decl, bool is_top_level);
static void start_function (tree name, tree type, int nested, int public);
static void ffecom_file_ (const char *name);
static void ffecom_close_include_ (FILE *f);
-static int ffecom_decode_include_option_ (char *spec);
static FILE *ffecom_open_include_ (char *name, ffewhereLine l,
ffewhereColumn c);
@@ -604,18 +603,18 @@ struct lang_identifier GTY(())
(((struct lang_identifier *)(NODE))->invented)
/* The resulting tree type. */
-union lang_tree_node
+union lang_tree_node
GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
{
- union tree_node GTY ((tag ("0"),
- desc ("tree_node_structure (&%h)")))
+ union tree_node GTY ((tag ("0"),
+ desc ("tree_node_structure (&%h)")))
generic;
struct lang_identifier GTY ((tag ("1"))) identifier;
};
/* Fortran doesn't use either of these. */
-struct lang_decl GTY(())
+struct lang_decl GTY(())
{
};
struct lang_type GTY(())
@@ -639,15 +638,16 @@ static GTY(()) tree shadowed_labels;
/* Return the subscript expression, modified to do range-checking.
- `array' is the array to be checked against.
+ `array' is the array type to be checked against.
`element' is the subscript expression to check.
`dim' is the dimension number (starting at 0).
`total_dims' is the total number of dimensions (0 for CHARACTER substring).
+ `item' is the array decl or NULL_TREE.
*/
static tree
ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
- const char *array_name)
+ const char *array_name, tree item)
{
tree low = TYPE_MIN_VALUE (TYPE_DOMAIN (array));
tree high = TYPE_MAX_VALUE (TYPE_DOMAIN (array));
@@ -714,6 +714,10 @@ ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
}
}
+ /* If the array index is safe at compile-time, return element. */
+ if (integer_nonzerop (cond))
+ return element;
+
{
int len;
char *proc;
@@ -791,7 +795,7 @@ ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
arg3);
arg4 = convert (ffecom_f2c_ftnint_type_node,
- build_int_2 (lineno, 0));
+ build_int_2 (input_line, 0));
arg1 = build_tree_list (NULL_TREE, arg1);
arg2 = build_tree_list (NULL_TREE, arg2);
@@ -808,13 +812,10 @@ ffecom_subscript_check_ (tree array, tree element, int dim, int total_dims,
TREE_SIDE_EFFECTS (die) = 1;
die = convert (void_type_node, die);
- element = ffecom_3 (COND_EXPR,
- TREE_TYPE (element),
- cond,
- element,
- die);
+ if (integer_zerop (cond) && item)
+ ffe_mark_addressable (item);
- return element;
+ return ffecom_3 (COND_EXPR, TREE_TYPE (element), cond, element, die);
}
/* Return the computed element of an array reference.
@@ -900,7 +901,7 @@ ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
if (flag_bounds_check)
element = ffecom_subscript_check_ (array, element, i, total_dims,
- array_name);
+ array_name, item);
if (element == error_mark_node)
return element;
@@ -946,7 +947,7 @@ ffecom_arrayref_ (tree item, ffebld expr, int want_ptr)
element = ffecom_expr_ (dims[i], NULL, NULL, NULL, FALSE, TRUE);
if (flag_bounds_check)
element = ffecom_subscript_check_ (array, element, i, total_dims,
- array_name);
+ array_name, item);
if (element == error_mark_node)
return element;
@@ -1109,8 +1110,7 @@ ffecom_convert_to_complex_ (tree type, tree expr)
/* Like gcc's convert(), but crashes if widening might happen. */
static tree
-ffecom_convert_narrow_ (type, expr)
- tree type, expr;
+ffecom_convert_narrow_ (tree type, tree expr)
{
register tree e = expr;
register enum tree_code code = TREE_CODE (type);
@@ -1180,8 +1180,7 @@ ffecom_convert_narrow_ (type, expr)
/* Like gcc's convert(), but crashes if narrowing might happen. */
static tree
-ffecom_convert_widen_ (type, expr)
- tree type, expr;
+ffecom_convert_widen_ (tree type, tree expr)
{
register tree e = expr;
register enum tree_code code = TREE_CODE (type);
@@ -1289,7 +1288,7 @@ ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart)
{
bothparts = build_tree_list (TYPE_FIELDS (type), realpart);
TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart);
- bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts);
+ bothparts = build_constructor (type, bothparts);
}
else
{
@@ -1533,8 +1532,7 @@ ffecom_possible_partial_overlap_ (ffebld expr1, ffebld expr2 ATTRIBUTE_UNUSED)
static bool
ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
- tree source_tree, ffebld source UNUSED,
- bool scalar_arg)
+ tree source_tree, ffebld source UNUSED, bool scalar_arg)
{
tree source_decl;
tree source_offset;
@@ -1577,7 +1575,6 @@ ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
case MIN_EXPR:
case MAX_EXPR:
case ABS_EXPR:
- case FFS_EXPR:
case LSHIFT_EXPR:
case RSHIFT_EXPR:
case LROTATE_EXPR:
@@ -1585,7 +1582,6 @@ ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
case BIT_AND_EXPR:
- case BIT_ANDTC_EXPR:
case BIT_NOT_EXPR:
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
@@ -1715,9 +1711,8 @@ ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size,
in a COMMON area the callee might know about (and thus modify). */
static bool
-ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED,
- tree args, tree callee_commons,
- bool scalar_args)
+ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED, tree args,
+ tree callee_commons, bool scalar_args)
{
tree arg;
tree dest_decl;
@@ -1791,10 +1786,9 @@ ffecom_build_f2c_string_ (int i, const char *s)
to the arglist a pointer to a temporary to receive the return value. */
static tree
-ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
- tree type, tree args, tree dest_tree,
- ffebld dest, bool *dest_used, tree callee_commons,
- bool scalar_args, tree hook)
+ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex, tree type,
+ tree args, tree dest_tree, ffebld dest, bool *dest_used,
+ tree callee_commons, bool scalar_args, tree hook)
{
tree item;
tree tempvar;
@@ -1852,9 +1846,9 @@ ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
static tree
ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex,
- tree type, ffebld left, ffebld right,
- tree dest_tree, ffebld dest, bool *dest_used,
- tree callee_commons, bool scalar_args, bool ref, tree hook)
+ tree type, ffebld left, ffebld right, tree dest_tree,
+ ffebld dest, bool *dest_used, tree callee_commons,
+ bool scalar_args, bool ref, tree hook)
{
tree left_tree;
tree right_tree;
@@ -2045,7 +2039,7 @@ ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
end_tree = ffecom_expr (end);
if (flag_bounds_check)
end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
- char_name);
+ char_name, NULL_TREE);
end_tree = convert (ffecom_f2c_ftnlen_type_node,
end_tree);
@@ -2063,7 +2057,7 @@ ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
start_tree = ffecom_expr (start);
if (flag_bounds_check)
start_tree = ffecom_subscript_check_ (array, start_tree, 0, 0,
- char_name);
+ char_name, NULL_TREE);
start_tree = convert (ffecom_f2c_ftnlen_type_node,
start_tree);
@@ -2096,7 +2090,7 @@ ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null)
end_tree = ffecom_expr (end);
if (flag_bounds_check)
end_tree = ffecom_subscript_check_ (array, end_tree, 1, 0,
- char_name);
+ char_name, NULL_TREE);
end_tree = convert (ffecom_f2c_ftnlen_type_node,
end_tree);
@@ -2584,12 +2578,12 @@ ffecom_do_entry_ (ffesymbol fn, int entrynum)
CHARACTER. */
bool cmplxfunc; /* Use f2c way of returning COMPLEX. */
bool multi; /* Master fn has multiple return types. */
- bool altreturning = FALSE; /* This entry point has alternate returns. */
- int old_lineno = lineno;
- const char *old_input_filename = input_filename;
+ bool altreturning = FALSE; /* This entry point has alternate
+ returns. */
+ location_t old_loc = input_location;
input_filename = ffesymbol_where_filename (fn);
- lineno = ffesymbol_where_filelinenum (fn);
+ input_line = ffesymbol_where_filelinenum (fn);
ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */
@@ -2919,8 +2913,7 @@ ffecom_do_entry_ (ffesymbol fn, int entrynum)
finish_function (0);
- lineno = old_lineno;
- input_filename = old_input_filename;
+ input_location = old_loc;
ffecom_doing_entry_ = FALSE;
}
@@ -2933,8 +2926,8 @@ ffecom_do_entry_ (ffesymbol fn, int entrynum)
made, destination used instead, and dest_used flag set TRUE. */
static tree
-ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
- bool *dest_used, bool assignp, bool widenp)
+ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest, bool *dest_used,
+ bool assignp, bool widenp)
{
tree item;
tree list;
@@ -3029,7 +3022,7 @@ ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
build_range_type (ffecom_integer_type_node,
ffecom_integer_zero_node,
item));
- list = build (CONSTRUCTOR, item, NULL_TREE, list);
+ list = build_constructor (item, list);
TREE_CONSTANT (list) = 1;
TREE_STATIC (list) = 1;
return list;
@@ -3077,7 +3070,7 @@ ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
build_range_type (ffecom_integer_type_node,
ffecom_integer_zero_node,
item));
- list = build (CONSTRUCTOR, item, NULL_TREE, list);
+ list = build_constructor (item, list);
TREE_CONSTANT (list) = 1;
TREE_STATIC (list) = 1;
return list;
@@ -3799,8 +3792,8 @@ ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest,
subroutines. */
static tree
-ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree,
- ffebld dest, bool *dest_used)
+ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, ffebld dest,
+ bool *dest_used)
{
tree expr_tree;
tree saved_expr1; /* For those who need it. */
@@ -5905,8 +5898,7 @@ ffecom_f2c_make_type_ (tree *type, int tcode, const char *name)
given size. */
static void
-ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size,
- int code)
+ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size, int code)
{
int j;
tree t;
@@ -6050,11 +6042,7 @@ ffecom_get_external_identifier_ (ffesymbol s)
if (!ffe_is_underscoring ()
|| (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0)
-#if FFETARGET_isENFORCED_MAIN_NAME
- || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0)
-#else
|| (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0)
-#endif
|| (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0))
return get_identifier (name);
@@ -6112,8 +6100,7 @@ ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
tree result;
bool charfunc = (bt == FFEINFO_basictypeCHARACTER);
static bool recurse = FALSE;
- int old_lineno = lineno;
- const char *old_input_filename = input_filename;
+ location_t old_loc = input_location;
ffecom_nested_entry_ = s;
@@ -6126,7 +6113,7 @@ ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
see how it works at this point. */
input_filename = ffesymbol_where_filename (s);
- lineno = ffesymbol_where_filelinenum (s);
+ input_line = ffesymbol_where_filelinenum (s);
/* Pretransform the expression so any newly discovered things belong to the
outer program unit, not to the statement function. */
@@ -6223,8 +6210,7 @@ ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
recurse = FALSE;
- lineno = old_lineno;
- input_filename = old_input_filename;
+ input_location = old_loc;
ffecom_nested_entry_ = NULL;
@@ -6304,7 +6290,7 @@ ffecom_init_zero_ (tree decl)
init = convert (type, integer_zero_node);
else if (!incremental)
{
- init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
+ init = build_constructor (type, NULL_TREE);
TREE_CONSTANT (init) = 1;
TREE_STATIC (init) = 1;
}
@@ -6318,8 +6304,7 @@ ffecom_init_zero_ (tree decl)
}
static tree
-ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg,
- tree *maybe_tree)
+ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg, tree *maybe_tree)
{
tree expr_tree;
tree length_tree;
@@ -7062,7 +7047,7 @@ ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc)
equivalent of a Fortran program unit. */
static void
-ffecom_start_progunit_ ()
+ffecom_start_progunit_ (void)
{
ffesymbol fn = ffecom_primary_entry_;
ffebld arglist;
@@ -7082,14 +7067,13 @@ ffecom_start_progunit_ ()
&& (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION)
&& (ffecom_master_bt_ == FFEINFO_basictypeNONE);
bool main_program = FALSE;
- int old_lineno = lineno;
- const char *old_input_filename = input_filename;
+ location_t old_loc = input_location;
assert (fn != NULL);
assert (ffesymbol_hook (fn).decl_tree == NULL_TREE);
input_filename = ffesymbol_where_filename (fn);
- lineno = ffesymbol_where_filelinenum (fn);
+ input_line = ffesymbol_where_filelinenum (fn);
switch (ffecom_primary_entry_kind_)
{
@@ -7271,8 +7255,7 @@ ffecom_start_progunit_ ()
/* Disallow temp vars at this level. */
current_binding_level->prep_state = 2;
- lineno = old_lineno;
- input_filename = old_input_filename;
+ input_location = old_loc;
/* This handles any symbols still untransformed, in case -g specified.
This used to be done in ffecom_finish_progunit, but it turns out to
@@ -7300,8 +7283,7 @@ ffecom_sym_transform_ (ffesymbol s)
ffeinfoBasictype bt;
ffeinfoKindtype kt;
ffeglobal g;
- int old_lineno = lineno;
- const char *old_input_filename = input_filename;
+ location_t old_loc = input_location;
/* Must ensure special ASSIGN variables are declared at top of outermost
block, else they'll end up in the innermost block when their first
@@ -7320,14 +7302,14 @@ ffecom_sym_transform_ (ffesymbol s)
if (ffesymbol_sfdummyparent (s) == NULL)
{
input_filename = ffesymbol_where_filename (s);
- lineno = ffesymbol_where_filelinenum (s);
+ input_line = ffesymbol_where_filelinenum (s);
}
else
{
ffesymbol sf = ffesymbol_sfdummyparent (s);
input_filename = ffesymbol_where_filename (sf);
- lineno = ffesymbol_where_filelinenum (sf);
+ input_line = ffesymbol_where_filelinenum (sf);
}
bt = ffeinfo_basictype (ffebld_info (s));
@@ -7416,16 +7398,16 @@ ffecom_sym_transform_ (ffesymbol s)
ffestorag st = ffesymbol_storage (s);
tree type;
- if ((st != NULL)
- && (ffestorag_size (st) == 0))
+ type = ffecom_type_localvar_ (s, bt, kt);
+
+ if (type == error_mark_node)
{
t = error_mark_node;
break;
}
- type = ffecom_type_localvar_ (s, bt, kt);
-
- if (type == error_mark_node)
+ if ((st != NULL)
+ && (ffestorag_size (st) == 0))
{
t = error_mark_node;
break;
@@ -7939,6 +7921,7 @@ ffecom_sym_transform_ (ffesymbol s)
{
ffetargetOffset offset;
ffestorag cst;
+ tree toffset;
cst = ffestorag_parent (st);
assert (cst == ffesymbol_storage (cs));
@@ -7955,9 +7938,10 @@ ffecom_sym_transform_ (ffesymbol s)
ffecom_1 (ADDR_EXPR,
build_pointer_type (TREE_TYPE (ct)),
ct));
+ toffset = build_int_2 (offset, 0);
+ TREE_TYPE (toffset) = ssizetype;
t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t),
- t,
- build_int_2 (offset, 0));
+ t, toffset);
t = convert (build_pointer_type (type),
t);
TREE_CONSTANT (t) = 1;
@@ -8296,8 +8280,7 @@ ffecom_sym_transform_ (ffesymbol s)
ffesymbol_hook (s).length_tree = tlen;
ffesymbol_hook (s).addr = addr;
- lineno = old_lineno;
- input_filename = old_input_filename;
+ input_location = old_loc;
return s;
}
@@ -8314,20 +8297,19 @@ static ffesymbol
ffecom_sym_transform_assign_ (ffesymbol s)
{
tree t; /* Transformed thingy. */
- int old_lineno = lineno;
- const char *old_input_filename = input_filename;
+ location_t old_loc = input_location;
if (ffesymbol_sfdummyparent (s) == NULL)
{
input_filename = ffesymbol_where_filename (s);
- lineno = ffesymbol_where_filelinenum (s);
+ input_line = ffesymbol_where_filelinenum (s);
}
else
{
ffesymbol sf = ffesymbol_sfdummyparent (s);
input_filename = ffesymbol_where_filename (sf);
- lineno = ffesymbol_where_filelinenum (sf);
+ input_line = ffesymbol_where_filelinenum (sf);
}
assert (!ffecom_transform_only_dummies_);
@@ -8377,8 +8359,7 @@ ffecom_sym_transform_assign_ (ffesymbol s)
ffesymbol_hook (s).assign_tree = t;
- lineno = old_lineno;
- input_filename = old_input_filename;
+ input_location = old_loc;
return s;
}
@@ -8763,7 +8744,7 @@ ffecom_transform_namelist_ (ffesymbol s)
TREE_CHAIN (TREE_CHAIN (nmlinits))
= build_tree_list ((field = TREE_CHAIN (field)), nvarsinit);
- nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits);
+ nmlinits = build_constructor (nmltype, nmlinits);
TREE_CONSTANT (nmlinits) = 1;
TREE_STATIC (nmlinits) = 1;
@@ -8780,8 +8761,7 @@ ffecom_transform_namelist_ (ffesymbol s)
taking into account different units of measurements for offsets. */
static void
-ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
- tree t)
+ffecom_tree_canonize_ptr_ (tree *decl, tree *offset, tree t)
{
switch (TREE_CODE (t))
{
@@ -8866,8 +8846,7 @@ ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
reveal the overlap. */
static void
-ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
- tree *size, tree t)
+ffecom_tree_canonize_ref_ (tree *decl, tree *offset, tree *size, tree t)
{
/* The default path is to report a nonexistant decl. */
*decl = NULL_TREE;
@@ -8906,7 +8885,6 @@ ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
case MIN_EXPR:
case MAX_EXPR:
case ABS_EXPR:
- case FFS_EXPR:
case LSHIFT_EXPR:
case RSHIFT_EXPR:
case LROTATE_EXPR:
@@ -8914,7 +8892,6 @@ ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
case BIT_AND_EXPR:
- case BIT_ANDTC_EXPR:
case BIT_NOT_EXPR:
case TRUTH_ANDIF_EXPR:
case TRUTH_ORIF_EXPR:
@@ -9020,9 +8997,8 @@ ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
/* Do divide operation appropriate to type of operands. */
static tree
-ffecom_tree_divide_ (tree tree_type, tree left, tree right,
- tree dest_tree, ffebld dest, bool *dest_used,
- tree hook)
+ffecom_tree_divide_ (tree tree_type, tree left, tree right, tree dest_tree,
+ ffebld dest, bool *dest_used, tree hook)
{
if ((left == error_mark_node)
|| (right == error_mark_node))
@@ -9109,8 +9085,7 @@ ffecom_tree_divide_ (tree tree_type, tree left, tree right,
/* Build type info for non-dummy variable. */
static tree
-ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
- ffeinfoKindtype kt)
+ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt)
{
tree type;
ffebld dl;
@@ -9168,7 +9143,7 @@ ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt,
static GTY(()) tree ffecom_type_namelist_var;
static tree
-ffecom_type_namelist_ ()
+ffecom_type_namelist_ (void)
{
if (ffecom_type_namelist_var == NULL_TREE)
{
@@ -9199,7 +9174,7 @@ ffecom_type_namelist_ ()
static GTY(()) tree ffecom_type_vardesc_var;
static tree
-ffecom_type_vardesc_ ()
+ffecom_type_vardesc_ (void)
{
if (ffecom_type_vardesc_var == NULL_TREE)
{
@@ -9298,7 +9273,7 @@ ffecom_vardesc_ (ffebld expr)
TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits)))
= build_tree_list ((field = TREE_CHAIN (field)), typeinit);
- varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits);
+ varinits = build_constructor (vardesctype, varinits);
TREE_CONSTANT (varinits) = 1;
TREE_STATIC (varinits) = 1;
@@ -9343,7 +9318,7 @@ ffecom_vardesc_array_ (ffesymbol s)
build_range_type (integer_type_node,
integer_one_node,
build_int_2 (i, 0)));
- list = build (CONSTRUCTOR, item, NULL_TREE, list);
+ list = build_constructor (item, list);
TREE_CONSTANT (list) = 1;
TREE_STATIC (list) = 1;
@@ -9449,7 +9424,7 @@ ffecom_vardesc_dims_ (ffesymbol s)
build_int_2
((int) ffesymbol_rank (s)
+ 2, 0)));
- list = build (CONSTRUCTOR, item, NULL_TREE, numdim);
+ list = build_constructor (item, numdim);
TREE_CONSTANT (list) = 1;
TREE_STATIC (list) = 1;
@@ -9563,8 +9538,7 @@ ffecom_1_fn (tree node)
checking for certain housekeeping things. */
tree
-ffecom_2 (enum tree_code code, tree type, tree node1,
- tree node2)
+ffecom_2 (enum tree_code code, tree type, tree node1, tree node2)
{
tree item;
@@ -9584,7 +9558,7 @@ ffecom_2 (enum tree_code code, tree type, tree node1,
case COMPLEX_EXPR:
item = build_tree_list (TYPE_FIELDS (type), node1);
TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2);
- item = build (CONSTRUCTOR, type, NULL_TREE, item);
+ item = build_constructor (type, item);
break;
case PLUS_EXPR:
@@ -9919,8 +9893,7 @@ ffecom_2pass_do_entrypoint (ffesymbol entry)
TREE_SIDE_EFFECTS. */
tree
-ffecom_2s (enum tree_code code, tree type, tree node1,
- tree node2)
+ffecom_2s (enum tree_code code, tree type, tree node1, tree node2)
{
tree item;
@@ -9938,8 +9911,7 @@ ffecom_2s (enum tree_code code, tree type, tree node1,
checking for certain housekeeping things. */
tree
-ffecom_3 (enum tree_code code, tree type, tree node1,
- tree node2, tree node3)
+ffecom_3 (enum tree_code code, tree type, tree node1, tree node2, tree node3)
{
tree item;
@@ -9961,8 +9933,7 @@ ffecom_3 (enum tree_code code, tree type, tree node1,
TREE_SIDE_EFFECTS. */
tree
-ffecom_3s (enum tree_code code, tree type, tree node1,
- tree node2, tree node3)
+ffecom_3s (enum tree_code code, tree type, tree node1, tree node2, tree node3)
{
tree item;
@@ -10122,9 +10093,6 @@ ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
case FFEBLD_opPERCENT_DESCR:
switch (ffeinfo_basictype (ffebld_info (expr)))
{
-#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
- case FFEINFO_basictypeHOLLERITH:
-#endif
case FFEINFO_basictypeCHARACTER:
break; /* Passed by descriptor anyway. */
@@ -10140,21 +10108,6 @@ ffecom_arg_ptr_to_expr (ffebld expr, tree *length)
break;
}
-#ifdef PASS_HOLLERITH_BY_DESCRIPTOR
- if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH)
- && (length != NULL))
- { /* Pass Hollerith by descriptor. */
- ffetargetHollerith h;
-
- assert (ffebld_op (expr) == FFEBLD_opCONTER);
- h = ffebld_cu_val_hollerith (ffebld_constant_union
- (ffebld_conter (expr)));
- *length
- = build_int_2 (h.length, 0);
- TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node;
- }
-#endif
-
if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER)
return ffecom_ptr_to_expr (expr);
@@ -10336,31 +10289,43 @@ ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
{
case FFEINFO_basictypeINTEGER:
{
- int val;
+ HOST_WIDE_INT hi, lo;
switch (kt)
{
#if FFETARGET_okINTEGER1
case FFEINFO_kindtypeINTEGER1:
- val = ffebld_cu_val_integer1 (*cu);
+ lo = ffebld_cu_val_integer1 (*cu);
+ hi = (lo < 0) ? -1 : 0;
break;
#endif
#if FFETARGET_okINTEGER2
case FFEINFO_kindtypeINTEGER2:
- val = ffebld_cu_val_integer2 (*cu);
+ lo = ffebld_cu_val_integer2 (*cu);
+ hi = (lo < 0) ? -1 : 0;
break;
#endif
#if FFETARGET_okINTEGER3
case FFEINFO_kindtypeINTEGER3:
- val = ffebld_cu_val_integer3 (*cu);
+ lo = ffebld_cu_val_integer3 (*cu);
+ hi = (lo < 0) ? -1 : 0;
break;
#endif
#if FFETARGET_okINTEGER4
case FFEINFO_kindtypeINTEGER4:
- val = ffebld_cu_val_integer4 (*cu);
+#if HOST_BITS_PER_LONGLONG > HOST_BITS_PER_WIDE_INT
+ {
+ long long int big = ffebld_cu_val_integer4 (*cu);
+ hi = (HOST_WIDE_INT) (big >> HOST_BITS_PER_WIDE_INT);
+ lo = (HOST_WIDE_INT) big;
+ }
+#else
+ lo = ffebld_cu_val_integer4 (*cu);
+ hi = (lo < 0) ? -1 : 0;
+#endif
break;
#endif
@@ -10370,7 +10335,7 @@ ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
case FFEINFO_kindtypeANY:
return error_mark_node;
}
- item = build_int_2 (val, (val < 0) ? -1 : 0);
+ item = build_int_2 (lo, hi);
TREE_TYPE (item) = tree_type;
}
break;
@@ -10440,12 +10405,6 @@ ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu));
- break;
-#endif
-
default:
assert ("bad REAL constant kind type" == NULL);
/* Fall through. */
@@ -10485,13 +10444,6 @@ ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real);
- imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary);
- break;
-#endif
-
default:
assert ("bad REAL constant kind type" == NULL);
/* Fall through. */
@@ -10596,8 +10548,8 @@ ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt,
/* Transform constant-union to tree, with the type known. */
tree
-ffecom_constantunion_with_type (ffebldConstantUnion *cu,
- tree tree_type, ffebldConst ct)
+ffecom_constantunion_with_type (ffebldConstantUnion *cu, tree tree_type,
+ ffebldConst ct)
{
tree item;
@@ -10607,7 +10559,7 @@ ffecom_constantunion_with_type (ffebldConstantUnion *cu,
{
#if FFETARGET_okINTEGER1
case FFEBLD_constINTEGER1:
- val = ffebld_cu_val_integer1 (*cu);
+ val = ffebld_cu_val_integer1 (*cu);
item = build_int_2 (val, (val < 0) ? -1 : 0);
break;
#endif
@@ -10625,8 +10577,17 @@ ffecom_constantunion_with_type (ffebldConstantUnion *cu,
#endif
#if FFETARGET_okINTEGER4
case FFEBLD_constINTEGER4:
+#if HOST_BITS_PER_LONGLONG > HOST_BITS_PER_WIDE_INT
+ {
+ long long int big = ffebld_cu_val_integer4 (*cu);
+ item = build_int_2 ((HOST_WIDE_INT) big,
+ (HOST_WIDE_INT)
+ (big >> HOST_BITS_PER_WIDE_INT));
+ }
+#else
val = ffebld_cu_val_integer4 (*cu);
item = build_int_2 (val, (val < 0) ? -1 : 0);
+#endif
break;
#endif
#if FFETARGET_okLOGICAL1
@@ -10685,10 +10646,6 @@ ffecom_const_expr (ffebld expr)
if (ffebld_arity (expr) == 0
&& (ffebld_op (expr) != FFEBLD_opSYMTER
-#if NEWCOMMON
- /* ~~Enable once common/equivalence is handled properly? */
- || ffebld_where (expr) == FFEINFO_whereCOMMON
-#endif
|| ffebld_where (expr) == FFEINFO_whereGLOBAL
|| ffebld_where (expr) == FFEINFO_whereINTRINSIC))
{
@@ -10705,8 +10662,7 @@ ffecom_const_expr (ffebld expr)
/* Handy way to make a field in a struct/union. */
tree
-ffecom_decl_field (tree context, tree prevfield,
- const char *name, tree type)
+ffecom_decl_field (tree context, tree prevfield, const char *name, tree type)
{
tree field;
@@ -10726,12 +10682,6 @@ ffecom_close_include (FILE *f)
ffecom_close_include_ (f);
}
-int
-ffecom_decode_include_option (char *spec)
-{
- return ffecom_decode_include_option_ (spec);
-}
-
/* End a compound statement (block). */
tree
@@ -10747,7 +10697,7 @@ ffecom_end_compstmt (void)
Calls ffecom_sym_end_transition for each global and local symbol. */
void
-ffecom_end_transition ()
+ffecom_end_transition (void)
{
ffebld item;
@@ -10823,7 +10773,7 @@ ffecom_end_transition ()
Make sure error updating not inhibited. */
void
-ffecom_exec_transition ()
+ffecom_exec_transition (void)
{
bool inhibited;
@@ -10920,16 +10870,6 @@ ffecom_expand_let_stmt (ffebld dest, ffebld source)
expr_tree = source_tree;
else if (assign_temp)
{
-#ifdef MOVE_EXPR
- /* The back end understands a conceptual move (evaluate source;
- store into dest), so use that, in case it can determine
- that it is going to use, say, two registers as temporaries
- anyway. So don't use the temp (and someday avoid generating
- it, once this code starts triggering regularly). */
- expr_tree = ffecom_2s (MOVE_EXPR, void_type_node,
- dest_tree,
- source_tree);
-#else
expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
assign_temp,
source_tree);
@@ -10937,7 +10877,6 @@ ffecom_expand_let_stmt (ffebld dest, ffebld source)
expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
dest_tree,
assign_temp);
-#endif
}
else
expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node,
@@ -11024,7 +10963,7 @@ ffecom_expr_w (tree type, ffebld expr)
/* Do global stuff. */
void
-ffecom_finish_compile ()
+ffecom_finish_compile (void)
{
assert (ffecom_outer_function_decl_ == NULL_TREE);
assert (current_function_decl == NULL_TREE);
@@ -11044,7 +10983,7 @@ ffecom_finish_decl (tree decl, tree init, bool is_top_level)
/* Finish a program unit. */
void
-ffecom_finish_progunit ()
+ffecom_finish_progunit (void)
{
ffecom_end_compstmt ();
@@ -11168,7 +11107,7 @@ ffecom_gfrt_kindtype (ffecomGfrt gfrt)
}
void
-ffecom_init_0 ()
+ffecom_init_0 (void)
{
tree endlink;
int i;
@@ -11177,9 +11116,9 @@ ffecom_init_0 ()
tree field;
ffetype type;
ffetype base_type;
- tree double_ftype_double;
- tree float_ftype_float;
- tree ldouble_ftype_ldouble;
+ tree double_ftype_double, double_ftype_double_double;
+ tree float_ftype_float, float_ftype_float_float;
+ tree ldouble_ftype_ldouble, ldouble_ftype_ldouble_ldouble;
tree ffecom_tree_ptr_to_fun_type_void;
/* This block of code comes from the now-obsolete cktyps.c. It checks
@@ -11312,18 +11251,21 @@ ffecom_init_0 ()
endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE);
- float_ftype_float
- = build_function_type (float_type_node,
- tree_cons (NULL_TREE, float_type_node, endlink));
+ t = tree_cons (NULL_TREE, float_type_node, endlink);
+ float_ftype_float = build_function_type (float_type_node, t);
+ t = tree_cons (NULL_TREE, float_type_node, t);
+ float_ftype_float_float = build_function_type (float_type_node, t);
- double_ftype_double
- = build_function_type (double_type_node,
- tree_cons (NULL_TREE, double_type_node, endlink));
+ t = tree_cons (NULL_TREE, double_type_node, endlink);
+ double_ftype_double = build_function_type (double_type_node, t);
+ t = tree_cons (NULL_TREE, double_type_node, t);
+ double_ftype_double_double = build_function_type (double_type_node, t);
- ldouble_ftype_ldouble
- = build_function_type (long_double_type_node,
- tree_cons (NULL_TREE, long_double_type_node,
- endlink));
+ t = tree_cons (NULL_TREE, long_double_type_node, endlink);
+ ldouble_ftype_ldouble = build_function_type (long_double_type_node, t);
+ t = tree_cons (NULL_TREE, long_double_type_node, t);
+ ldouble_ftype_ldouble_ldouble = build_function_type (long_double_type_node,
+ t);
for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i)
for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j)
@@ -11740,18 +11682,20 @@ ffecom_init_0 ()
ffecom_tree_blockdata_type
= build_function_type (void_type_node, NULL_TREE);
- builtin_function ("__builtin_sqrtf", float_ftype_float,
- BUILT_IN_SQRTF, BUILT_IN_NORMAL, "sqrtf", NULL_TREE);
- builtin_function ("__builtin_sqrt", double_ftype_double,
- BUILT_IN_SQRT, BUILT_IN_NORMAL, "sqrt", NULL_TREE);
- builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
- BUILT_IN_SQRTL, BUILT_IN_NORMAL, "sqrtl", NULL_TREE);
- builtin_function ("__builtin_sinf", float_ftype_float,
- BUILT_IN_SINF, BUILT_IN_NORMAL, "sinf", NULL_TREE);
- builtin_function ("__builtin_sin", double_ftype_double,
- BUILT_IN_SIN, BUILT_IN_NORMAL, "sin", NULL_TREE);
- builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
- BUILT_IN_SINL, BUILT_IN_NORMAL, "sinl", NULL_TREE);
+ builtin_function ("__builtin_atanf", float_ftype_float,
+ BUILT_IN_ATANF, BUILT_IN_NORMAL, "atanf", NULL_TREE);
+ builtin_function ("__builtin_atan", double_ftype_double,
+ BUILT_IN_ATAN, BUILT_IN_NORMAL, "atan", NULL_TREE);
+ builtin_function ("__builtin_atanl", ldouble_ftype_ldouble,
+ BUILT_IN_ATANL, BUILT_IN_NORMAL, "atanl", NULL_TREE);
+
+ builtin_function ("__builtin_atan2f", float_ftype_float_float,
+ BUILT_IN_ATAN2F, BUILT_IN_NORMAL, "atan2f", NULL_TREE);
+ builtin_function ("__builtin_atan2", double_ftype_double_double,
+ BUILT_IN_ATAN2, BUILT_IN_NORMAL, "atan2", NULL_TREE);
+ builtin_function ("__builtin_atan2l", ldouble_ftype_ldouble_ldouble,
+ BUILT_IN_ATAN2L, BUILT_IN_NORMAL, "atan2l", NULL_TREE);
+
builtin_function ("__builtin_cosf", float_ftype_float,
BUILT_IN_COSF, BUILT_IN_NORMAL, "cosf", NULL_TREE);
builtin_function ("__builtin_cos", double_ftype_double,
@@ -11759,6 +11703,62 @@ ffecom_init_0 ()
builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
BUILT_IN_COSL, BUILT_IN_NORMAL, "cosl", NULL_TREE);
+ builtin_function ("__builtin_expf", float_ftype_float,
+ BUILT_IN_EXPF, BUILT_IN_NORMAL, "expf", NULL_TREE);
+ builtin_function ("__builtin_exp", double_ftype_double,
+ BUILT_IN_EXP, BUILT_IN_NORMAL, "exp", NULL_TREE);
+ builtin_function ("__builtin_expl", ldouble_ftype_ldouble,
+ BUILT_IN_EXPL, BUILT_IN_NORMAL, "expl", NULL_TREE);
+
+ builtin_function ("__builtin_floorf", float_ftype_float,
+ BUILT_IN_FLOORF, BUILT_IN_NORMAL, "floorf", NULL_TREE);
+ builtin_function ("__builtin_floor", double_ftype_double,
+ BUILT_IN_FLOOR, BUILT_IN_NORMAL, "floor", NULL_TREE);
+ builtin_function ("__builtin_floorl", ldouble_ftype_ldouble,
+ BUILT_IN_FLOORL, BUILT_IN_NORMAL, "floorl", NULL_TREE);
+
+ builtin_function ("__builtin_fmodf", float_ftype_float_float,
+ BUILT_IN_FMODF, BUILT_IN_NORMAL, "fmodf", NULL_TREE);
+ builtin_function ("__builtin_fmod", double_ftype_double_double,
+ BUILT_IN_FMOD, BUILT_IN_NORMAL, "fmod", NULL_TREE);
+ builtin_function ("__builtin_fmodl", ldouble_ftype_ldouble_ldouble,
+ BUILT_IN_FMODL, BUILT_IN_NORMAL, "fmodl", NULL_TREE);
+
+ builtin_function ("__builtin_logf", float_ftype_float,
+ BUILT_IN_LOGF, BUILT_IN_NORMAL, "logf", NULL_TREE);
+ builtin_function ("__builtin_log", double_ftype_double,
+ BUILT_IN_LOG, BUILT_IN_NORMAL, "log", NULL_TREE);
+ builtin_function ("__builtin_logl", ldouble_ftype_ldouble,
+ BUILT_IN_LOGL, BUILT_IN_NORMAL, "logl", NULL_TREE);
+
+ builtin_function ("__builtin_powf", float_ftype_float_float,
+ BUILT_IN_POWF, BUILT_IN_NORMAL, "powf", NULL_TREE);
+ builtin_function ("__builtin_pow", double_ftype_double_double,
+ BUILT_IN_POW, BUILT_IN_NORMAL, "pow", NULL_TREE);
+ builtin_function ("__builtin_powl", ldouble_ftype_ldouble_ldouble,
+ BUILT_IN_POWL, BUILT_IN_NORMAL, "powl", NULL_TREE);
+
+ builtin_function ("__builtin_sinf", float_ftype_float,
+ BUILT_IN_SINF, BUILT_IN_NORMAL, "sinf", NULL_TREE);
+ builtin_function ("__builtin_sin", double_ftype_double,
+ BUILT_IN_SIN, BUILT_IN_NORMAL, "sin", NULL_TREE);
+ builtin_function ("__builtin_sinl", ldouble_ftype_ldouble,
+ BUILT_IN_SINL, BUILT_IN_NORMAL, "sinl", NULL_TREE);
+
+ builtin_function ("__builtin_sqrtf", float_ftype_float,
+ BUILT_IN_SQRTF, BUILT_IN_NORMAL, "sqrtf", NULL_TREE);
+ builtin_function ("__builtin_sqrt", double_ftype_double,
+ BUILT_IN_SQRT, BUILT_IN_NORMAL, "sqrt", NULL_TREE);
+ builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble,
+ BUILT_IN_SQRTL, BUILT_IN_NORMAL, "sqrtl", NULL_TREE);
+
+ builtin_function ("__builtin_tanf", float_ftype_float,
+ BUILT_IN_TANF, BUILT_IN_NORMAL, "tanf", NULL_TREE);
+ builtin_function ("__builtin_tan", double_ftype_double,
+ BUILT_IN_TAN, BUILT_IN_NORMAL, "tan", NULL_TREE);
+ builtin_function ("__builtin_tanl", ldouble_ftype_ldouble,
+ BUILT_IN_TANL, BUILT_IN_NORMAL, "tanl", NULL_TREE);
+
pedantic_lvalues = FALSE;
ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node,
@@ -11818,13 +11818,8 @@ ffecom_init_0 ()
ffecom_float_zero_ = build_real (float_type_node, dconst0);
ffecom_double_zero_ = build_real (double_type_node, dconst0);
- {
- REAL_VALUE_TYPE point_5;
-
- REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2);
- ffecom_float_half_ = build_real (float_type_node, point_5);
- ffecom_double_half_ = build_real (double_type_node, point_5);
- }
+ ffecom_float_half_ = build_real (float_type_node, dconsthalf);
+ ffecom_double_half_ = build_real (double_type_node, dconsthalf);
/* Do "extern int xargc;". */
@@ -11875,7 +11870,7 @@ ffecom_init_0 ()
ffecom_init_2(); */
void
-ffecom_init_2 ()
+ffecom_init_2 (void)
{
assert (ffecom_outer_function_decl_ == NULL_TREE);
assert (current_function_decl == NULL_TREE);
@@ -12035,8 +12030,7 @@ ffecom_lookup_label (ffelab label)
the MODIFY_EXPR. */
tree
-ffecom_modify (tree newtype, tree lhs,
- tree rhs)
+ffecom_modify (tree newtype, tree lhs, tree rhs)
{
if (lhs == error_mark_node || rhs == error_mark_node)
return error_mark_node;
@@ -12978,7 +12972,7 @@ ffecom_sym_retract (ffesymbol s UNUSED)
/* Create temporary gcc label. */
tree
-ffecom_temp_label ()
+ffecom_temp_label (void)
{
tree glabel;
static int mynumber = 0;
@@ -13092,7 +13086,7 @@ ffecom_type_expr (ffebld expr)
first ENTRY statement, and so on). */
tree
-ffecom_which_entrypoint_decl ()
+ffecom_which_entrypoint_decl (void)
{
assert (ffecom_which_entrypoint_decl_ != NULL_TREE);
@@ -13115,16 +13109,16 @@ ffecom_which_entrypoint_decl ()
"bison_rule_foo_" so they are easy to find. */
static void
-bison_rule_pushlevel_ ()
+bison_rule_pushlevel_ (void)
{
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
pushlevel (0);
clear_last_expr ();
expand_start_bindings (0);
}
static tree
-bison_rule_compstmt_ ()
+bison_rule_compstmt_ (void)
{
tree t;
int keep = kept_level_p ();
@@ -13133,7 +13127,7 @@ bison_rule_compstmt_ ()
if (! keep)
current_binding_level->names = NULL_TREE;
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
expand_end_bindings (getdecls (), keep, 0);
t = poplevel (keep, 1, 0);
@@ -13151,8 +13145,7 @@ bison_rule_compstmt_ ()
tree
builtin_function (const char *name, tree type, int function_code,
- enum built_in_class class,
- const char *library_name,
+ enum built_in_class class, const char *library_name,
tree attrs ATTRIBUTE_UNUSED)
{
tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
@@ -13294,9 +13287,6 @@ duplicate_decls (tree newdecl, tree olddecl)
COPY_DECL_RTL (olddecl, newdecl);
/* Merge the type qualifiers. */
- if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
- && !TREE_THIS_VOLATILE (newdecl))
- TREE_THIS_VOLATILE (olddecl) = 0;
if (TREE_READONLY (newdecl))
TREE_READONLY (olddecl) = 1;
if (TREE_THIS_VOLATILE (newdecl))
@@ -13311,8 +13301,7 @@ duplicate_decls (tree newdecl, tree olddecl)
if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0)
|| (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0))
{
- DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl);
- DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl);
+ DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
if (DECL_CONTEXT (olddecl) == 0
&& TREE_CODE (newdecl) != FUNCTION_DECL)
@@ -13336,10 +13325,17 @@ duplicate_decls (tree newdecl, tree olddecl)
if (DECL_SECTION_NAME (newdecl) == NULL_TREE)
DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl);
+ /* Copy the assembler name. */
+ COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);
+
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl);
DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
+ TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
+ TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
+ DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
+ DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
}
}
/* If cannot merge, then use the new type and qualifiers,
@@ -13586,7 +13582,7 @@ finish_function (int nested)
/* Obey `register' declarations if `setjmp' is called in this fn. */
/* Generate rtl for function exit. */
- expand_function_end (input_filename, lineno, 0);
+ expand_function_end ();
/* If this is a nested function, protect the local variables in the stack
above us from being collected while we're compiling this function. */
@@ -13724,7 +13720,7 @@ lookup_name_current_level (tree name)
/* Create a new `struct f_binding_level'. */
static struct f_binding_level *
-make_binding_level ()
+make_binding_level (void)
{
/* NOSTRICT */
return ggc_alloc (sizeof (struct f_binding_level));
@@ -13747,7 +13743,7 @@ struct f_function *f_function_chain;
/* Restore the variables used during compilation of a C function. */
static void
-pop_f_function_context ()
+pop_f_function_context (void)
{
struct f_function *p = f_function_chain;
tree link;
@@ -13783,10 +13779,9 @@ pop_f_function_context ()
used during compilation of a C function. */
static void
-push_f_function_context ()
+push_f_function_context (void)
{
- struct f_function *p
- = (struct f_function *) xmalloc (sizeof (struct f_function));
+ struct f_function *p = xmalloc (sizeof (struct f_function));
push_function_context ();
@@ -13823,8 +13818,7 @@ push_parm_decl (tree parm)
/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */
static tree
-pushdecl_top_level (x)
- tree x;
+pushdecl_top_level (tree x)
{
register tree t;
register struct f_binding_level *b = current_binding_level;
@@ -13843,8 +13837,7 @@ pushdecl_top_level (x)
after they are modified in the light of any missing parameters. */
static tree
-storedecls (decls)
- tree decls;
+storedecls (tree decls)
{
return current_binding_level->names = decls;
}
@@ -13868,11 +13861,9 @@ store_parm_decls (int is_main_program UNUSED)
DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ()));
/* Initialize the RTL code for the function. */
-
- init_function_start (fndecl, input_filename, lineno);
+ init_function_start (fndecl);
/* Set up parameters and prepare for return, for the function. */
-
expand_function_start (fndecl, 0);
}
@@ -14008,8 +13999,7 @@ start_function (tree name, tree type, int nested, int public)
/* Here are the public functions the GNU back end needs. */
tree
-convert (type, expr)
- tree type, expr;
+convert (tree type, tree expr)
{
register tree e = expr;
register enum tree_code code = TREE_CODE (type);
@@ -14054,7 +14044,7 @@ convert (type, expr)
store the result back using `storedecls' or you will lose. */
tree
-getdecls ()
+getdecls (void)
{
return current_binding_level->names;
}
@@ -14062,13 +14052,13 @@ getdecls ()
/* Nonzero if we are currently in the global binding level. */
int
-global_bindings_p ()
+global_bindings_p (void)
{
return current_binding_level == global_binding_level;
}
static void
-ffecom_init_decl_processing ()
+ffecom_init_decl_processing (void)
{
malloc_init ();
@@ -14080,8 +14070,7 @@ ffecom_init_decl_processing ()
so that the block can be reinserted where appropriate. */
static void
-delete_block (block)
- tree block;
+delete_block (tree block)
{
tree t;
if (current_binding_level->blocks == block)
@@ -14100,8 +14089,7 @@ delete_block (block)
}
void
-insert_block (block)
- tree block;
+insert_block (tree block)
{
TREE_USED (block) = 1;
current_binding_level->blocks
@@ -14109,10 +14097,10 @@ insert_block (block)
}
/* Each front end provides its own. */
-static const char *ffe_init PARAMS ((const char *));
-static void ffe_finish PARAMS ((void));
-static void ffe_init_options PARAMS ((void));
-static void ffe_print_identifier PARAMS ((FILE *, tree, int));
+static bool ffe_init (void);
+static void ffe_finish (void);
+static bool ffe_post_options (const char **);
+static void ffe_print_identifier (FILE *, tree, int);
struct language_function GTY(())
{
@@ -14127,8 +14115,10 @@ struct language_function GTY(())
#define LANG_HOOKS_FINISH ffe_finish
#undef LANG_HOOKS_INIT_OPTIONS
#define LANG_HOOKS_INIT_OPTIONS ffe_init_options
-#undef LANG_HOOKS_DECODE_OPTION
-#define LANG_HOOKS_DECODE_OPTION ffe_decode_option
+#undef LANG_HOOKS_HANDLE_OPTION
+#define LANG_HOOKS_HANDLE_OPTION ffe_handle_option
+#undef LANG_HOOKS_POST_OPTIONS
+#define LANG_HOOKS_POST_OPTIONS ffe_post_options
#undef LANG_HOOKS_PARSE_FILE
#define LANG_HOOKS_PARSE_FILE ffe_parse_file
#undef LANG_HOOKS_MARK_ADDRESSABLE
@@ -14194,10 +14184,11 @@ const char *const tree_code_name[] = {
};
#undef DEFTREECODE
-static const char *
-ffe_init (filename)
- const char *filename;
+static bool
+ffe_post_options (const char **pfilename)
{
+ const char *filename = *pfilename;
+
/* Open input file. */
if (filename == 0 || !strcmp (filename, "-"))
{
@@ -14206,11 +14197,19 @@ ffe_init (filename)
}
else
finput = fopen (filename, "r");
+
if (finput == 0)
- fatal_io_error ("can't open %s", filename);
+ fatal_error ("can't open %s: %m", filename);
+
+ return false;
+}
+
+static bool
+ffe_init (void)
+{
#ifdef IO_BUFFER_SIZE
- setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
+ setvbuf (finput, xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
#endif
ffecom_init_decl_processing ();
@@ -14223,16 +14222,15 @@ ffe_init (filename)
to try doing this. */
ffelex_hash_kludge (finput);
- /* FIXME: The ffelex_hash_kludge code needs to be cleaned up to
- return the new file name. */
- if (main_input_filename)
- filename = main_input_filename;
+ push_srcloc (input_filename, 0);
- return filename;
+ /* FIXME: The ffelex_hash_kludge code needs to be cleaned up to
+ set the new file name. Maybe in ffe_post_options. */
+ return true;
}
static void
-ffe_finish ()
+ffe_finish (void)
{
ffe_terminate_0 ();
@@ -14242,21 +14240,8 @@ ffe_finish ()
fclose (finput);
}
-static void
-ffe_init_options ()
-{
- /* Set default options for Fortran. */
- flag_move_all_movables = 1;
- flag_reduce_all_givs = 1;
- flag_argument_noalias = 2;
- flag_merge_constants = 2;
- flag_errno_math = 0;
- flag_complex_divide_method = 1;
-}
-
static bool
-ffe_mark_addressable (exp)
- tree exp;
+ffe_mark_addressable (tree exp)
{
register tree x = exp;
while (1)
@@ -14326,10 +14311,7 @@ ffe_mark_addressable (exp)
them into the BLOCK. */
tree
-poplevel (keep, reverse, functionbody)
- int keep;
- int reverse;
- int functionbody;
+poplevel (int keep, int reverse, int functionbody)
{
register tree link;
/* The chain of decls was accumulated in reverse order.
@@ -14465,10 +14447,7 @@ poplevel (keep, reverse, functionbody)
}
static void
-ffe_print_identifier (file, node, indent)
- FILE *file;
- tree node;
- int indent;
+ffe_print_identifier (FILE *file, tree node, int indent)
{
print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4);
print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4);
@@ -14483,8 +14462,7 @@ ffe_print_identifier (file, node, indent)
to agree with what X says. */
tree
-pushdecl (x)
- tree x;
+pushdecl (tree x)
{
register tree t;
register tree name = DECL_NAME (x);
@@ -14594,7 +14572,7 @@ pushdecl (x)
/* Nonzero if the current level needs to have a BLOCK made. */
static int
-kept_level_p ()
+kept_level_p (void)
{
tree decl;
@@ -14617,8 +14595,7 @@ kept_level_p ()
not for that of tags. */
void
-pushlevel (tag_transparent)
- int tag_transparent;
+pushlevel (int tag_transparent)
{
register struct f_binding_level *newlevel = NULL_BINDING_LEVEL;
@@ -14653,8 +14630,7 @@ pushlevel (tag_transparent)
(the one we are currently in). */
void
-set_block (block)
- register tree block;
+set_block (tree block)
{
current_binding_level->this_block = block;
current_binding_level->names = chainon (current_binding_level->names,
@@ -14664,9 +14640,7 @@ set_block (block)
}
static tree
-ffe_signed_or_unsigned_type (unsignedp, type)
- int unsignedp;
- tree type;
+ffe_signed_or_unsigned_type (int unsignedp, tree type)
{
tree type2;
@@ -14692,8 +14666,7 @@ ffe_signed_or_unsigned_type (unsignedp, type)
}
static tree
-ffe_signed_type (type)
- tree type;
+ffe_signed_type (tree type)
{
tree type1 = TYPE_MAIN_VARIANT (type);
ffeinfoKindtype kt;
@@ -14747,8 +14720,7 @@ ffe_signed_type (type)
The resulting type should always be `integer_type_node'. */
static tree
-ffe_truthvalue_conversion (expr)
- tree expr;
+ffe_truthvalue_conversion (tree expr)
{
if (TREE_CODE (expr) == ERROR_MARK)
return expr;
@@ -14830,7 +14802,6 @@ ffe_truthvalue_conversion (expr)
case NEGATE_EXPR:
case ABS_EXPR:
case FLOAT_EXPR:
- case FFS_EXPR:
/* These don't change whether an object is nonzero or zero. */
return ffe_truthvalue_conversion (TREE_OPERAND (expr, 0));
@@ -14926,9 +14897,7 @@ ffe_truthvalue_conversion (expr)
}
static tree
-ffe_type_for_mode (mode, unsignedp)
- enum machine_mode mode;
- int unsignedp;
+ffe_type_for_mode (enum machine_mode mode, int unsignedp)
{
int i;
int j;
@@ -14986,9 +14955,7 @@ ffe_type_for_mode (mode, unsignedp)
}
static tree
-ffe_type_for_size (bits, unsignedp)
- unsigned bits;
- int unsignedp;
+ffe_type_for_size (unsigned bits, int unsignedp)
{
ffeinfoKindtype kt;
tree type_node;
@@ -15022,8 +14989,7 @@ ffe_type_for_size (bits, unsignedp)
}
static tree
-ffe_unsigned_type (type)
- tree type;
+ffe_unsigned_type (tree type)
{
tree type1 = TYPE_MAIN_VARIANT (type);
ffeinfoKindtype kt;
@@ -15106,7 +15072,7 @@ static int max_include_len = 0;
struct file_name_list
{
struct file_name_list *next;
- char *fname;
+ const char *fname;
/* Mapping of file names for this directory. */
struct file_name_map *name_map;
/* Nonzero if name_map is valid. */
@@ -15134,7 +15100,6 @@ static struct file_buf {
} instack[INPUT_STACK_MAX];
static int last_error_tick = 0; /* Incremented each time we print it. */
-static int input_file_stack_tick = 0; /* Incremented when status changes. */
/* Current nesting level of input sources.
`instack[indepth]' is the level currently being read. */
@@ -15163,8 +15128,8 @@ static struct file_name_map *read_name_map (const char *dirname);
FIRST is the beginning of the chain to append, and LAST is the end. */
static void
-append_include_chain (first, last)
- struct file_name_list *first, *last;
+append_include_chain (struct file_name_list *first,
+ struct file_name_list *last)
{
struct file_name_list *dir;
@@ -15194,9 +15159,7 @@ append_include_chain (first, last)
read_name_map. */
static FILE *
-open_include_file (filename, searchptr)
- char *filename;
- struct file_name_list *searchptr;
+open_include_file (char *filename, struct file_name_list *searchptr)
{
register struct file_name_map *map;
register char *from;
@@ -15255,7 +15218,7 @@ open_include_file (filename, searchptr)
}
else
{
- dir = (char *) xmalloc (p - filename + 1);
+ dir = xmalloc (p - filename + 1);
memcpy (dir, filename, p - filename);
dir[p - filename] = '\0';
from = p + 1;
@@ -15333,9 +15296,7 @@ print_containing_files (ffebadSeverity sev)
file. */
static char *
-read_filename_string (ch, f)
- int ch;
- FILE *f;
+read_filename_string (int ch, FILE *f)
{
char *alloc, *set;
int len;
@@ -15364,8 +15325,7 @@ read_filename_string (ch, f)
/* Read the file name map file for DIRNAME. */
static struct file_name_map *
-read_name_map (dirname)
- const char *dirname;
+read_name_map (const char *dirname)
{
/* This structure holds a linked list of file name maps, one per
directory. */
@@ -15389,8 +15349,7 @@ read_name_map (dirname)
if (! strcmp (map_list_ptr->map_list_name, dirname))
return map_list_ptr->map_list_map;
- map_list_ptr = ((struct file_name_map_list *)
- xmalloc (sizeof (struct file_name_map_list)));
+ map_list_ptr = xmalloc (sizeof (struct file_name_map_list));
map_list_ptr->map_list_name = xstrdup (dirname);
map_list_ptr->map_list_map = NULL;
@@ -15420,8 +15379,7 @@ read_name_map (dirname)
;
to = read_filename_string (ch, f);
- ptr = ((struct file_name_map *)
- xmalloc (sizeof (struct file_name_map)));
+ ptr = xmalloc (sizeof (struct file_name_map));
ptr->map_from = from;
/* Make the real filename absolute. */
@@ -15461,7 +15419,7 @@ ffecom_file_ (const char *name)
early #line directives (when -g is in effect). */
fp = &instack[++indepth];
- memset ((char *) fp, 0, sizeof (FILE_BUF));
+ memset (fp, 0, sizeof (FILE_BUF));
if (name == NULL)
name = "";
fp->nominal_fname = fp->fname = name;
@@ -15479,26 +15437,20 @@ ffecom_close_include_ (FILE *f)
ffewhere_column_kill (instack[indepth].column);
}
-static int
-ffecom_decode_include_option_ (char *spec)
+void
+ffecom_decode_include_option (const char *dir)
{
- struct file_name_list *dirtmp;
-
- if (! ignore_srcdir && !strcmp (spec, "-"))
+ if (! ignore_srcdir && !strcmp (dir, "-"))
ignore_srcdir = 1;
else
{
- dirtmp = (struct file_name_list *)
- xmalloc (sizeof (struct file_name_list));
+ struct file_name_list *dirtmp
+ = xmalloc (sizeof (struct file_name_list));
dirtmp->next = 0; /* New one goes on the end */
- dirtmp->fname = spec;
+ dirtmp->fname = dir;
dirtmp->got_name_map = 0;
- if (spec[0] == 0)
- error ("directory name must immediately follow -I");
- else
- append_include_chain (dirtmp, dirtmp);
+ append_include_chain (dirtmp, dirtmp);
}
- return 1;
}
/* Open INCLUDEd file. */
@@ -15553,9 +15505,10 @@ ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
if (ep != NULL)
{
n = ep - nam;
- dsp[0].fname = (char *) xmalloc (n + 1);
- strncpy (dsp[0].fname, nam, n);
- dsp[0].fname[n] = '\0';
+ fname = xmalloc (n + 1);
+ strncpy (fname, nam, n);
+ fname[n] = '\0';
+ dsp[0].fname = fname;
if (n + INCLUDE_LEN_FUDGE > max_include_len)
max_include_len = n + INCLUDE_LEN_FUDGE;
}
@@ -15663,7 +15616,7 @@ ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
}
if (dsp[0].fname != NULL)
- free (dsp[0].fname);
+ free ((char *) dsp[0].fname);
if (f == NULL)
return NULL;
@@ -15684,7 +15637,7 @@ ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c)
instack[indepth].column = ffewhere_column_use (c);
fp = &instack[indepth + 1];
- memset ((char *) fp, 0, sizeof (FILE_BUF));
+ memset (fp, 0, sizeof (FILE_BUF));
fp->nominal_fname = fp->fname = fname;
fp->dir = searchptr;
diff --git a/contrib/gcc/f/com.h b/contrib/gcc/f/com.h
index b58e5ba1205f..d23db6687a2f 100644
--- a/contrib/gcc/f/com.h
+++ b/contrib/gcc/f/com.h
@@ -1,5 +1,6 @@
/* com.h -- Public #include File (module.h template V1.0)
- Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 2000, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -128,17 +129,11 @@ typedef enum
#endif
typedef tree ffecomConstant;
-#define FFECOM_constantHOOK
typedef tree ffecomNonter;
-#define FFECOM_nonterHOOK
typedef tree ffecomLabel;
-#define FFECOM_globalHOOK
typedef tree ffecomGlobal;
-#define FFECOM_labelHOOK
typedef tree ffecomStorage;
-#define FFECOM_storageHOOK
typedef struct _ffecom_symbol_ ffecomSymbol;
-#define FFECOM_symbolHOOK
struct _ffecom_symbol_
{
@@ -157,13 +152,13 @@ struct _ffecom_symbol_
#include "storag.h"
#include "symbol.h"
-extern int global_bindings_p PARAMS ((void));
-extern tree getdecls PARAMS ((void));
-extern void pushlevel PARAMS ((int));
-extern tree poplevel PARAMS ((int,int, int));
-extern void insert_block PARAMS ((tree));
-extern void set_block PARAMS ((tree));
-extern tree pushdecl PARAMS ((tree));
+extern int global_bindings_p (void);
+extern tree getdecls (void);
+extern void pushlevel (int);
+extern tree poplevel (int,int, int);
+extern void insert_block (tree);
+extern void set_block (tree);
+extern tree pushdecl (tree);
/* Global objects accessed by users of this module. */
@@ -218,7 +213,7 @@ tree ffecom_const_expr (ffebld expr);
tree ffecom_decl_field (tree context, tree prevfield, const char *name,
tree type);
void ffecom_close_include (FILE *f);
-int ffecom_decode_include_option (char *spec);
+void ffecom_decode_include_option (const char *dir);
tree ffecom_end_compstmt (void);
void ffecom_end_transition (void);
void ffecom_exec_transition (void);
@@ -233,7 +228,7 @@ void ffecom_finish_decl (tree decl, tree init, bool is_top_level);
void ffecom_finish_progunit (void);
tree ffecom_get_invented_identifier (const char *pattern, ...)
ATTRIBUTE_PRINTF_1;
-ffeinfoKindtype ffecom_gfrt_basictype (ffecomGfrt ix);
+ffeinfoBasictype ffecom_gfrt_basictype (ffecomGfrt ix);
ffeinfoKindtype ffecom_gfrt_kindtype (ffecomGfrt ix);
void ffecom_init_0 (void);
void ffecom_init_2 (void);
diff --git a/contrib/gcc/f/data.c b/contrib/gcc/f/data.c
index 91b835dbc605..2040f0ab6dc2 100644
--- a/contrib/gcc/f/data.c
+++ b/contrib/gcc/f/data.c
@@ -314,7 +314,7 @@ ffedata_value (ffetargetIntegerDefault rpt, ffebld value, ffelexToken token)
CHARTYPE is CHARACTER*3, for example. */
static bool
-ffedata_advance_ ()
+ffedata_advance_ (void)
{
ffebld next;
@@ -723,8 +723,8 @@ ffedata_convert_ (ffebld source, ffelexToken source_token,
if (max > ffedata_convert_cache_max_)
{
- cache = (ffedataConvertCache_) malloc_new_ks (malloc_pool_image (),
- "FFEDATA cache", max * sizeof (*cache));
+ cache = malloc_new_ks (malloc_pool_image (),
+ "FFEDATA cache", max * sizeof (*cache));
if (ffedata_convert_cache_max_ != 0)
{
memcpy (cache, ffedata_convert_cache_,
@@ -1457,7 +1457,7 @@ ffedata_gather_ (ffestorag mst, ffestorag st)
ffedata_pop_(); */
static void
-ffedata_pop_ ()
+ffedata_pop_ (void)
{
ffedataImpdo_ victim = ffedata_stack_;
@@ -1473,7 +1473,7 @@ ffedata_pop_ ()
ffedata_push_(); */
static void
-ffedata_push_ ()
+ffedata_push_ (void)
{
ffedataImpdo_ baby;
diff --git a/contrib/gcc/f/equiv.c b/contrib/gcc/f/equiv.c
index f58de9c4379d..bd7ac6d4d24f 100644
--- a/contrib/gcc/f/equiv.c
+++ b/contrib/gcc/f/equiv.c
@@ -1,5 +1,6 @@
/* equiv.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 2003
+ Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -918,7 +919,7 @@ ffeequiv_add (ffeequiv eq, ffebld list, ffelexToken t)
ffeequiv_exec_transition(); */
void
-ffeequiv_exec_transition ()
+ffeequiv_exec_transition (void)
{
while (ffeequiv_list_.first != (ffeequiv) &ffeequiv_list_.first)
ffeequiv_layout_local_ (ffeequiv_list_.first);
@@ -931,7 +932,7 @@ ffeequiv_exec_transition ()
Initializes the list of equivalences. */
void
-ffeequiv_init_2 ()
+ffeequiv_init_2 (void)
{
ffeequiv_list_.first = (ffeequiv) &ffeequiv_list_.first;
ffeequiv_list_.last = (ffeequiv) &ffeequiv_list_.first;
@@ -1312,7 +1313,7 @@ ffeequiv_merge (ffeequiv eq1, ffeequiv eq2, ffelexToken t)
objects. */
ffeequiv
-ffeequiv_new ()
+ffeequiv_new (void)
{
ffeequiv eq;
diff --git a/contrib/gcc/f/expr.c b/contrib/gcc/f/expr.c
index 4824be7cdb35..ef7661dc3ec3 100644
--- a/contrib/gcc/f/expr.c
+++ b/contrib/gcc/f/expr.c
@@ -1,5 +1,5 @@
/* expr.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 1996, 1997, 1998, 2001, 2002
+ Copyright (C) 1995, 1996, 1997, 1998, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by James Craig Burley.
@@ -309,7 +309,8 @@ static ffebld ffeexpr_reduced_ugly1log_ (ffebld reduced, ffeexprExpr_ op,
static ffebld ffeexpr_reduced_ugly2_ (ffebld reduced, ffeexprExpr_ l,
ffeexprExpr_ op, ffeexprExpr_ r);
static ffebld ffeexpr_reduced_ugly2log_ (ffebld reduced, ffeexprExpr_ l,
- ffeexprExpr_ op, ffeexprExpr_ r);
+ ffeexprExpr_ op, ffeexprExpr_ r,
+ bool *);
static ffelexHandler ffeexpr_find_close_paren_ (ffelexToken t,
ffelexHandler after);
static ffelexHandler ffeexpr_nil_finished_ (ffelexToken t);
@@ -516,14 +517,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_integer1_real4
- (ffebld_cu_ptr_integer1 (u),
- ffebld_constant_real4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("INTEGER1/REAL bad source kind type" == NULL);
break;
@@ -557,14 +550,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_integer1_complex4
- (ffebld_cu_ptr_integer1 (u),
- ffebld_constant_complex4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("INTEGER1/COMPLEX bad source kind type" == NULL);
break;
@@ -709,14 +694,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_integer2_real4
- (ffebld_cu_ptr_integer2 (u),
- ffebld_constant_real4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("INTEGER2/REAL bad source kind type" == NULL);
break;
@@ -750,14 +727,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_integer2_complex4
- (ffebld_cu_ptr_integer2 (u),
- ffebld_constant_complex4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("INTEGER2/COMPLEX bad source kind type" == NULL);
break;
@@ -902,14 +871,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_integer3_real4
- (ffebld_cu_ptr_integer3 (u),
- ffebld_constant_real4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("INTEGER3/REAL bad source kind type" == NULL);
break;
@@ -943,14 +904,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_integer3_complex4
- (ffebld_cu_ptr_integer3 (u),
- ffebld_constant_complex4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("INTEGER3/COMPLEX bad source kind type" == NULL);
break;
@@ -1095,14 +1048,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_integer4_real4
- (ffebld_cu_ptr_integer4 (u),
- ffebld_constant_real4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("INTEGER4/REAL bad source kind type" == NULL);
break;
@@ -1136,14 +1081,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_integer4_complex4
- (ffebld_cu_ptr_integer4 (u),
- ffebld_constant_complex4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("INTEGER3/COMPLEX bad source kind type" == NULL);
break;
@@ -1752,14 +1689,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_real1_real4
- (ffebld_cu_ptr_real1 (u),
- ffebld_constant_real4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("REAL1/REAL bad source kind type" == NULL);
break;
@@ -1793,14 +1722,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_real1_complex4
- (ffebld_cu_ptr_real1 (u),
- ffebld_constant_complex4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("REAL1/COMPLEX bad source kind type" == NULL);
break;
@@ -1904,14 +1825,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_real2_real4
- (ffebld_cu_ptr_real2 (u),
- ffebld_constant_real4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("REAL2/REAL bad source kind type" == NULL);
break;
@@ -1945,14 +1858,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_real2_complex4
- (ffebld_cu_ptr_real2 (u),
- ffebld_constant_complex4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("REAL2/COMPLEX bad source kind type" == NULL);
break;
@@ -2056,14 +1961,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_real3_real4
- (ffebld_cu_ptr_real3 (u),
- ffebld_constant_real4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("REAL3/REAL bad source kind type" == NULL);
break;
@@ -2097,14 +1994,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_real3_complex4
- (ffebld_cu_ptr_real3 (u),
- ffebld_constant_complex4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("REAL3/COMPLEX bad source kind type" == NULL);
break;
@@ -2144,158 +2033,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- switch (ffeinfo_basictype (ffebld_info (l)))
- {
- case FFEINFO_basictypeINTEGER:
- switch (ffeinfo_kindtype (ffebld_info (l)))
- {
-#if FFETARGET_okINTEGER1
- case FFEINFO_kindtypeINTEGER1:
- error = ffetarget_convert_real4_integer1
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_integer1 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okINTEGER2
- case FFEINFO_kindtypeINTEGER2:
- error = ffetarget_convert_real4_integer2
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_integer2 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okINTEGER3
- case FFEINFO_kindtypeINTEGER3:
- error = ffetarget_convert_real4_integer3
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_integer3 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okINTEGER4
- case FFEINFO_kindtypeINTEGER4:
- error = ffetarget_convert_real4_integer4
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_integer4 (ffebld_conter (l)));
- break;
-#endif
-
- default:
- assert ("REAL4/INTEGER bad source kind type" == NULL);
- break;
- }
- break;
-
- case FFEINFO_basictypeREAL:
- switch (ffeinfo_kindtype (ffebld_info (l)))
- {
-#if FFETARGET_okREAL1
- case FFEINFO_kindtypeREAL1:
- error = ffetarget_convert_real4_real1
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_real1 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okREAL2
- case FFEINFO_kindtypeREAL2:
- error = ffetarget_convert_real4_real2
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_real2 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okREAL3
- case FFEINFO_kindtypeREAL3:
- error = ffetarget_convert_real4_real3
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_real3 (ffebld_conter (l)));
- break;
-#endif
-
- default:
- assert ("REAL4/REAL bad source kind type" == NULL);
- break;
- }
- break;
-
- case FFEINFO_basictypeCOMPLEX:
- switch (ffeinfo_kindtype (ffebld_info (l)))
- {
-#if FFETARGET_okCOMPLEX1
- case FFEINFO_kindtypeREAL1:
- error = ffetarget_convert_real4_complex1
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_complex1 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX2
- case FFEINFO_kindtypeREAL2:
- error = ffetarget_convert_real4_complex2
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_complex2 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX3
- case FFEINFO_kindtypeREAL3:
- error = ffetarget_convert_real4_complex3
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_complex3 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_real4_complex4
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_complex4 (ffebld_conter (l)));
- break;
-#endif
-
- default:
- assert ("REAL4/COMPLEX bad source kind type" == NULL);
- break;
- }
- break;
-
- case FFEINFO_basictypeCHARACTER:
- error = ffetarget_convert_real4_character1
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_character1 (ffebld_conter (l)));
- break;
-
- case FFEINFO_basictypeHOLLERITH:
- error = ffetarget_convert_real4_hollerith
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_hollerith (ffebld_conter (l)));
- break;
-
- case FFEINFO_basictypeTYPELESS:
- error = ffetarget_convert_real4_typeless
- (ffebld_cu_ptr_real4 (u),
- ffebld_constant_typeless (ffebld_conter (l)));
- break;
-
- default:
- assert ("REAL4 bad type" == NULL);
- break;
- }
-
- /* If conversion operation is not implemented, return original expr. */
- if (error == FFEBAD_NOCANDO)
- return expr;
-
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_real4_val
- (ffebld_cu_val_real4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad real kind type" == NULL);
break;
@@ -2378,14 +2115,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_complex1_real4
- (ffebld_cu_ptr_complex1 (u),
- ffebld_constant_real4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("COMPLEX1/REAL bad source kind type" == NULL);
break;
@@ -2411,14 +2140,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_complex1_complex4
- (ffebld_cu_ptr_complex1 (u),
- ffebld_constant_complex4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("COMPLEX1/COMPLEX bad source kind type" == NULL);
break;
@@ -2530,14 +2251,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_complex2_real4
- (ffebld_cu_ptr_complex2 (u),
- ffebld_constant_real4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("COMPLEX2/REAL bad source kind type" == NULL);
break;
@@ -2563,14 +2276,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_complex2_complex4
- (ffebld_cu_ptr_complex2 (u),
- ffebld_constant_complex4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("COMPLEX2/COMPLEX bad source kind type" == NULL);
break;
@@ -2682,14 +2387,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_complex3_real4
- (ffebld_cu_ptr_complex3 (u),
- ffebld_constant_real4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("COMPLEX3/REAL bad source kind type" == NULL);
break;
@@ -2715,14 +2412,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_complex3_complex4
- (ffebld_cu_ptr_complex3 (u),
- ffebld_constant_complex4 (ffebld_conter (l)));
- break;
-#endif
-
default:
assert ("COMPLEX3/COMPLEX bad source kind type" == NULL);
break;
@@ -2762,158 +2451,6 @@ ffeexpr_collapse_convert (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- switch (ffeinfo_basictype (ffebld_info (l)))
- {
- case FFEINFO_basictypeINTEGER:
- switch (ffeinfo_kindtype (ffebld_info (l)))
- {
-#if FFETARGET_okINTEGER1
- case FFEINFO_kindtypeINTEGER1:
- error = ffetarget_convert_complex4_integer1
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_integer1 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okINTEGER2
- case FFEINFO_kindtypeINTEGER2:
- error = ffetarget_convert_complex4_integer2
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_integer2 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okINTEGER3
- case FFEINFO_kindtypeINTEGER3:
- error = ffetarget_convert_complex4_integer3
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_integer3 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okINTEGER4
- case FFEINFO_kindtypeINTEGER4:
- error = ffetarget_convert_complex4_integer4
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_integer4 (ffebld_conter (l)));
- break;
-#endif
-
- default:
- assert ("COMPLEX4/INTEGER bad source kind type" == NULL);
- break;
- }
- break;
-
- case FFEINFO_basictypeREAL:
- switch (ffeinfo_kindtype (ffebld_info (l)))
- {
-#if FFETARGET_okREAL1
- case FFEINFO_kindtypeREAL1:
- error = ffetarget_convert_complex4_real1
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_real1 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okREAL2
- case FFEINFO_kindtypeREAL2:
- error = ffetarget_convert_complex4_real2
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_real2 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okREAL3
- case FFEINFO_kindtypeREAL3:
- error = ffetarget_convert_complex4_real3
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_real3 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_convert_complex4_real4
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_real4 (ffebld_conter (l)));
- break;
-#endif
-
- default:
- assert ("COMPLEX4/REAL bad source kind type" == NULL);
- break;
- }
- break;
-
- case FFEINFO_basictypeCOMPLEX:
- switch (ffeinfo_kindtype (ffebld_info (l)))
- {
-#if FFETARGET_okCOMPLEX1
- case FFEINFO_kindtypeREAL1:
- error = ffetarget_convert_complex4_complex1
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_complex1 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX2
- case FFEINFO_kindtypeREAL2:
- error = ffetarget_convert_complex4_complex2
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_complex2 (ffebld_conter (l)));
- break;
-#endif
-
-#if FFETARGET_okCOMPLEX3
- case FFEINFO_kindtypeREAL3:
- error = ffetarget_convert_complex4_complex3
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_complex3 (ffebld_conter (l)));
- break;
-#endif
-
- default:
- assert ("COMPLEX4/COMPLEX bad source kind type" == NULL);
- break;
- }
- break;
-
- case FFEINFO_basictypeCHARACTER:
- error = ffetarget_convert_complex4_character1
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_character1 (ffebld_conter (l)));
- break;
-
- case FFEINFO_basictypeHOLLERITH:
- error = ffetarget_convert_complex4_hollerith
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_hollerith (ffebld_conter (l)));
- break;
-
- case FFEINFO_basictypeTYPELESS:
- error = ffetarget_convert_complex4_typeless
- (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_typeless (ffebld_conter (l)));
- break;
-
- default:
- assert ("COMPLEX4 bad type" == NULL);
- break;
- }
-
- /* If conversion operation is not implemented, return original expr. */
- if (error == FFEBAD_NOCANDO)
- return expr;
-
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_complex4_val
- (ffebld_cu_val_complex4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad complex kind type" == NULL);
break;
@@ -3302,15 +2839,6 @@ ffeexpr_collapse_uminus (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_uminus_real4 (ffebld_cu_ptr_real4 (u),
- ffebld_constant_real4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_real4_val
- (ffebld_cu_val_real4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad real kind type" == NULL);
break;
@@ -3347,15 +2875,6 @@ ffeexpr_collapse_uminus (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_uminus_complex4 (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_complex4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex4_val
- (ffebld_cu_val_complex4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad complex kind type" == NULL);
break;
@@ -3646,16 +3165,6 @@ ffeexpr_collapse_add (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_add_real4 (ffebld_cu_ptr_real4 (u),
- ffebld_constant_real4 (ffebld_conter (l)),
- ffebld_constant_real4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_real4_val
- (ffebld_cu_val_real4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad real kind type" == NULL);
break;
@@ -3695,16 +3204,6 @@ ffeexpr_collapse_add (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_add_complex4 (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_complex4 (ffebld_conter (l)),
- ffebld_constant_complex4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex4_val
- (ffebld_cu_val_complex4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad complex kind type" == NULL);
break;
@@ -3851,16 +3350,6 @@ ffeexpr_collapse_subtract (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_subtract_real4 (ffebld_cu_ptr_real4 (u),
- ffebld_constant_real4 (ffebld_conter (l)),
- ffebld_constant_real4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_real4_val
- (ffebld_cu_val_real4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad real kind type" == NULL);
break;
@@ -3900,16 +3389,6 @@ ffeexpr_collapse_subtract (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_subtract_complex4 (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_complex4 (ffebld_conter (l)),
- ffebld_constant_complex4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex4_val
- (ffebld_cu_val_complex4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad complex kind type" == NULL);
break;
@@ -4056,16 +3535,6 @@ ffeexpr_collapse_multiply (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_multiply_real4 (ffebld_cu_ptr_real4 (u),
- ffebld_constant_real4 (ffebld_conter (l)),
- ffebld_constant_real4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_real4_val
- (ffebld_cu_val_real4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad real kind type" == NULL);
break;
@@ -4105,16 +3574,6 @@ ffeexpr_collapse_multiply (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_multiply_complex4 (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_complex4 (ffebld_conter (l)),
- ffebld_constant_complex4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex4_val
- (ffebld_cu_val_complex4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad complex kind type" == NULL);
break;
@@ -4261,16 +3720,6 @@ ffeexpr_collapse_divide (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_divide_real4 (ffebld_cu_ptr_real4 (u),
- ffebld_constant_real4 (ffebld_conter (l)),
- ffebld_constant_real4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_real4_val
- (ffebld_cu_val_real4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad real kind type" == NULL);
break;
@@ -4310,16 +3759,6 @@ ffeexpr_collapse_divide (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_divide_complex4 (ffebld_cu_ptr_complex4 (u),
- ffebld_constant_complex4 (ffebld_conter (l)),
- ffebld_constant_complex4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex4_val
- (ffebld_cu_val_complex4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad complex kind type" == NULL);
break;
@@ -4563,39 +4002,6 @@ ffeexpr_collapse_concatenate (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- error = ffetarget_concatenate_character2 (ffebld_cu_ptr_character2 (u),
- ffebld_constant_character2 (ffebld_conter (l)),
- ffebld_constant_character2 (ffebld_conter (r)),
- ffebld_constant_pool (), &len);
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_character2_val
- (ffebld_cu_val_character2 (u)), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- error = ffetarget_concatenate_character3 (ffebld_cu_ptr_character3 (u),
- ffebld_constant_character3 (ffebld_conter (l)),
- ffebld_constant_character3 (ffebld_conter (r)),
- ffebld_constant_pool (), &len);
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_character3_val
- (ffebld_cu_val_character3 (u)), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- error = ffetarget_concatenate_character4 (ffebld_cu_ptr_character4 (u),
- ffebld_constant_character4 (ffebld_conter (l)),
- ffebld_constant_character4 (ffebld_conter (r)),
- ffebld_constant_pool (), &len);
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_character4_val
- (ffebld_cu_val_character4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad character kind type" == NULL);
break;
@@ -4740,16 +4146,6 @@ ffeexpr_collapse_eq (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_eq_real4 (&val,
- ffebld_constant_real4 (ffebld_conter (l)),
- ffebld_constant_real4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad real kind type" == NULL);
break;
@@ -4789,16 +4185,6 @@ ffeexpr_collapse_eq (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_eq_complex4 (&val,
- ffebld_constant_complex4 (ffebld_conter (l)),
- ffebld_constant_complex4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad complex kind type" == NULL);
break;
@@ -4818,36 +4204,6 @@ ffeexpr_collapse_eq (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- error = ffetarget_eq_character2 (&val,
- ffebld_constant_character2 (ffebld_conter (l)),
- ffebld_constant_character2 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- error = ffetarget_eq_character3 (&val,
- ffebld_constant_character3 (ffebld_conter (l)),
- ffebld_constant_character3 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- error = ffetarget_eq_character4 (&val,
- ffebld_constant_character4 (ffebld_conter (l)),
- ffebld_constant_character4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad character kind type" == NULL);
break;
@@ -4992,16 +4348,6 @@ ffeexpr_collapse_ne (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_ne_real4 (&val,
- ffebld_constant_real4 (ffebld_conter (l)),
- ffebld_constant_real4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad real kind type" == NULL);
break;
@@ -5041,16 +4387,6 @@ ffeexpr_collapse_ne (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_ne_complex4 (&val,
- ffebld_constant_complex4 (ffebld_conter (l)),
- ffebld_constant_complex4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad complex kind type" == NULL);
break;
@@ -5070,36 +4406,6 @@ ffeexpr_collapse_ne (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- error = ffetarget_ne_character2 (&val,
- ffebld_constant_character2 (ffebld_conter (l)),
- ffebld_constant_character2 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- error = ffetarget_ne_character3 (&val,
- ffebld_constant_character3 (ffebld_conter (l)),
- ffebld_constant_character3 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- error = ffetarget_ne_character4 (&val,
- ffebld_constant_character4 (ffebld_conter (l)),
- ffebld_constant_character4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad character kind type" == NULL);
break;
@@ -5244,16 +4550,6 @@ ffeexpr_collapse_ge (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_ge_real4 (&val,
- ffebld_constant_real4 (ffebld_conter (l)),
- ffebld_constant_real4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad real kind type" == NULL);
break;
@@ -5273,36 +4569,6 @@ ffeexpr_collapse_ge (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- error = ffetarget_ge_character2 (&val,
- ffebld_constant_character2 (ffebld_conter (l)),
- ffebld_constant_character2 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- error = ffetarget_ge_character3 (&val,
- ffebld_constant_character3 (ffebld_conter (l)),
- ffebld_constant_character3 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- error = ffetarget_ge_character4 (&val,
- ffebld_constant_character4 (ffebld_conter (l)),
- ffebld_constant_character4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad character kind type" == NULL);
break;
@@ -5447,16 +4713,6 @@ ffeexpr_collapse_gt (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_gt_real4 (&val,
- ffebld_constant_real4 (ffebld_conter (l)),
- ffebld_constant_real4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad real kind type" == NULL);
break;
@@ -5476,36 +4732,6 @@ ffeexpr_collapse_gt (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- error = ffetarget_gt_character2 (&val,
- ffebld_constant_character2 (ffebld_conter (l)),
- ffebld_constant_character2 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- error = ffetarget_gt_character3 (&val,
- ffebld_constant_character3 (ffebld_conter (l)),
- ffebld_constant_character3 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- error = ffetarget_gt_character4 (&val,
- ffebld_constant_character4 (ffebld_conter (l)),
- ffebld_constant_character4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad character kind type" == NULL);
break;
@@ -5650,16 +4876,6 @@ ffeexpr_collapse_le (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_le_real4 (&val,
- ffebld_constant_real4 (ffebld_conter (l)),
- ffebld_constant_real4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad real kind type" == NULL);
break;
@@ -5679,36 +4895,6 @@ ffeexpr_collapse_le (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- error = ffetarget_le_character2 (&val,
- ffebld_constant_character2 (ffebld_conter (l)),
- ffebld_constant_character2 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- error = ffetarget_le_character3 (&val,
- ffebld_constant_character3 (ffebld_conter (l)),
- ffebld_constant_character3 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- error = ffetarget_le_character4 (&val,
- ffebld_constant_character4 (ffebld_conter (l)),
- ffebld_constant_character4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad character kind type" == NULL);
break;
@@ -5853,16 +5039,6 @@ ffeexpr_collapse_lt (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okREAL4
- case FFEINFO_kindtypeREAL4:
- error = ffetarget_lt_real4 (&val,
- ffebld_constant_real4 (ffebld_conter (l)),
- ffebld_constant_real4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad real kind type" == NULL);
break;
@@ -5882,36 +5058,6 @@ ffeexpr_collapse_lt (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- error = ffetarget_lt_character2 (&val,
- ffebld_constant_character2 (ffebld_conter (l)),
- ffebld_constant_character2 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- error = ffetarget_lt_character3 (&val,
- ffebld_constant_character3 (ffebld_conter (l)),
- ffebld_constant_character3 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- error = ffetarget_lt_character4 (&val,
- ffebld_constant_character4 (ffebld_conter (l)),
- ffebld_constant_character4 (ffebld_conter (r)));
- expr = ffebld_new_conter_with_orig
- (ffebld_constant_new_logicaldefault (val), expr);
- break;
-#endif
-
default:
assert ("bad character kind type" == NULL);
break;
@@ -6906,36 +6052,6 @@ ffeexpr_collapse_substr (ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCHARACTER2
- case FFEINFO_kindtypeCHARACTER2:
- error = ffetarget_substr_character2 (ffebld_cu_ptr_character2 (u),
- ffebld_constant_character2 (ffebld_conter (l)), first, last,
- ffebld_constant_pool (), &len);
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_character2_val
- (ffebld_cu_val_character2 (u)), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER3
- case FFEINFO_kindtypeCHARACTER3:
- error = ffetarget_substr_character3 (ffebld_cu_ptr_character3 (u),
- ffebld_constant_character3 (ffebld_conter (l)), first, last,
- ffebld_constant_pool (), &len);
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_character3_val
- (ffebld_cu_val_character3 (u)), expr);
- break;
-#endif
-
-#if FFETARGET_okCHARACTER4
- case FFEINFO_kindtypeCHARACTER4:
- error = ffetarget_substr_character4 (ffebld_cu_ptr_character4 (u),
- ffebld_constant_character4 (ffebld_conter (l)), first, last,
- ffebld_constant_pool (), &len);
- expr = ffebld_new_conter_with_orig (ffebld_constant_new_character4_val
- (ffebld_cu_val_character4 (u)), expr);
- break;
-#endif
-
default:
assert ("bad character kind type" == NULL);
break;
@@ -7204,7 +6320,7 @@ ffeexpr_convert_to_sym (ffebld source, ffelexToken source_token,
/* Initializes the module. */
void
-ffeexpr_init_2 ()
+ffeexpr_init_2 (void)
{
ffeexpr_stack_ = NULL;
ffeexpr_level_ = 0;
@@ -7666,17 +6782,6 @@ ffeexpr_cb_comma_c_ (ffelexToken ft, ffebld expr, ffelexToken t)
break;
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
- e->u.operand = ffebld_new_conter (ffebld_constant_new_complex4
- (ffebld_conter (ffeexpr_stack_->expr), ffebld_conter (expr)));
- ffebld_set_info (e->u.operand,
- ffeinfo_new (FFEINFO_basictypeCOMPLEX, nkt, 0,
- FFEINFO_kindENTITY, FFEINFO_whereCONSTANT,
- FFETARGET_charactersizeNONE));
- break;
-#endif
-
default:
if (ffebad_start ((nkt == FFEINFO_kindtypeREALDOUBLE)
? FFEBAD_BAD_DBLCMPLX : FFEBAD_BAD_COMPLEX))
@@ -8663,9 +7768,6 @@ ffeexpr_type_combine (ffeinfoBasictype *xnbt, ffeinfoKindtype *xnkt,
#if FFETARGET_okCOMPLEX3
case FFEINFO_kindtypeREAL3:
#endif
-#if FFETARGET_okCOMPLEX4
- case FFEINFO_kindtypeREAL4:
-#endif
break; /* Fine and dandy. */
default:
@@ -9383,12 +8485,11 @@ ffeexpr_expr_kill_ (ffeexprExpr_ e)
Allocates and initializes a new expression object, returns it. */
static ffeexprExpr_
-ffeexpr_expr_new_ ()
+ffeexpr_expr_new_ (void)
{
ffeexprExpr_ e;
- e = (ffeexprExpr_) malloc_new_ks (ffe_pool_program_unit (), "FFEEXPR expr",
- sizeof (*e));
+ e = malloc_new_ks (ffe_pool_program_unit (), "FFEEXPR expr", sizeof (*e));
e->previous = NULL;
e->type = FFEEXPR_exprtypeUNKNOWN_;
e->token = NULL;
@@ -9577,15 +8678,6 @@ static void
ffeexpr_exprstack_push_operand_ (ffeexprExpr_ e)
{
ffeexpr_exprstack_push_ (e);
-#ifdef WEIRD_NONFORTRAN_RULES
- if ((ffeexpr_stack_->exprstack != NULL)
- && (ffeexpr_stack_->exprstack->expr->type == FFEEXPR_exprtypeBINARY_)
- && (ffeexpr_stack_->exprstack->expr->u.operator.prec
- == FFEEXPR_operatorprecedenceHIGHEST_)
- && (ffeexpr_stack_->exprstack->expr->u.operator.as
- == FFEEXPR_operatorassociativityL2R_))
- ffeexpr_reduce_ ();
-#endif
}
/* ffeexpr_exprstack_push_unary_ -- Push a unary operator onto the stack
@@ -9700,7 +8792,7 @@ again:
requisite type-assignment. */
static void
-ffeexpr_reduce_ ()
+ffeexpr_reduce_ (void)
{
ffeexprExpr_ operand; /* This is B in -B or A+B. */
ffeexprExpr_ left_operand; /* When operator is binary, this is A in A+B. */
@@ -9711,6 +8803,7 @@ ffeexpr_reduce_ ()
ffebld expr;
ffebld left_expr;
bool submag = FALSE;
+ bool bothlogical;
operand = ffeexpr_stack_->exprstack;
assert (operand != NULL);
@@ -9902,37 +8995,58 @@ ffeexpr_reduce_ ()
reduced = ffebld_new_and (left_expr, expr);
if (ffe_is_ugly_logint ())
reduced = ffeexpr_reduced_ugly2log_ (reduced, left_operand, operator,
- operand);
+ operand, &bothlogical);
reduced = ffeexpr_reduced_bool2_ (reduced, left_operand, operator,
operand);
reduced = ffeexpr_collapse_and (reduced, operator->token);
+ if (ffe_is_ugly_logint() && bothlogical)
+ reduced = ffeexpr_convert (reduced, left_operand->token,
+ operator->token,
+ FFEINFO_basictypeLOGICAL,
+ FFEINFO_kindtypeLOGICALDEFAULT, 0,
+ FFETARGET_charactersizeNONE,
+ FFEEXPR_contextLET);
break;
case FFEEXPR_operatorOR_:
reduced = ffebld_new_or (left_expr, expr);
if (ffe_is_ugly_logint ())
reduced = ffeexpr_reduced_ugly2log_ (reduced, left_operand, operator,
- operand);
+ operand, &bothlogical);
reduced = ffeexpr_reduced_bool2_ (reduced, left_operand, operator,
operand);
reduced = ffeexpr_collapse_or (reduced, operator->token);
+ if (ffe_is_ugly_logint() && bothlogical)
+ reduced = ffeexpr_convert (reduced, left_operand->token,
+ operator->token,
+ FFEINFO_basictypeLOGICAL,
+ FFEINFO_kindtypeLOGICALDEFAULT, 0,
+ FFETARGET_charactersizeNONE,
+ FFEEXPR_contextLET);
break;
case FFEEXPR_operatorXOR_:
reduced = ffebld_new_xor (left_expr, expr);
if (ffe_is_ugly_logint ())
reduced = ffeexpr_reduced_ugly2log_ (reduced, left_operand, operator,
- operand);
+ operand, &bothlogical);
reduced = ffeexpr_reduced_bool2_ (reduced, left_operand, operator,
operand);
reduced = ffeexpr_collapse_xor (reduced, operator->token);
+ if (ffe_is_ugly_logint() && bothlogical)
+ reduced = ffeexpr_convert (reduced, left_operand->token,
+ operator->token,
+ FFEINFO_basictypeLOGICAL,
+ FFEINFO_kindtypeLOGICALDEFAULT, 0,
+ FFETARGET_charactersizeNONE,
+ FFEEXPR_contextLET);
break;
case FFEEXPR_operatorEQV_:
reduced = ffebld_new_eqv (left_expr, expr);
if (ffe_is_ugly_logint ())
reduced = ffeexpr_reduced_ugly2log_ (reduced, left_operand, operator,
- operand);
+ operand, NULL);
reduced = ffeexpr_reduced_bool2_ (reduced, left_operand, operator,
operand);
reduced = ffeexpr_collapse_eqv (reduced, operator->token);
@@ -9942,7 +9056,7 @@ ffeexpr_reduce_ ()
reduced = ffebld_new_neqv (left_expr, expr);
if (ffe_is_ugly_logint ())
reduced = ffeexpr_reduced_ugly2log_ (reduced, left_operand, operator,
- operand);
+ operand, NULL);
reduced = ffeexpr_reduced_bool2_ (reduced, left_operand, operator,
operand);
reduced = ffeexpr_collapse_neqv (reduced, operator->token);
@@ -11423,7 +10537,7 @@ ffeexpr_reduced_ugly2_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op,
static ffebld
ffeexpr_reduced_ugly2log_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op,
- ffeexprExpr_ r)
+ ffeexprExpr_ r, bool *bothlogical)
{
ffeinfo linfo, rinfo;
ffeinfoBasictype lbt, rbt;
@@ -11503,23 +10617,31 @@ ffeexpr_reduced_ugly2log_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op,
}
if (lbt == FFEINFO_basictypeLOGICAL)
- {
- ffebld_set_left (reduced, ffeexpr_convert (ffebld_left (reduced),
- l->token, op->token, FFEINFO_basictypeINTEGER,
- FFEINFO_kindtypeINTEGERDEFAULT, 0,
- FFETARGET_charactersizeNONE,
- FFEEXPR_contextLET));
- }
+ {
+ ffebld_set_left (reduced,
+ ffeexpr_convert (ffebld_left (reduced),
+ l->token, op->token,
+ FFEINFO_basictypeINTEGER,
+ FFEINFO_kindtypeINTEGERDEFAULT, 0,
+ FFETARGET_charactersizeNONE,
+ FFEEXPR_contextLET));
+ }
if (rbt == FFEINFO_basictypeLOGICAL)
- {
- ffebld_set_right (reduced, ffeexpr_convert (ffebld_right (reduced),
- r->token, op->token, FFEINFO_basictypeINTEGER,
- FFEINFO_kindtypeINTEGERDEFAULT, 0,
- FFETARGET_charactersizeNONE,
- FFEEXPR_contextLET));
- }
-
+ {
+ ffebld_set_right (reduced,
+ ffeexpr_convert (ffebld_right (reduced),
+ r->token, op->token,
+ FFEINFO_basictypeINTEGER,
+ FFEINFO_kindtypeINTEGERDEFAULT, 0,
+ FFETARGET_charactersizeNONE,
+ FFEEXPR_contextLET));
+ }
+
+ if (bothlogical != NULL)
+ *bothlogical = (lbt == FFEINFO_basictypeLOGICAL
+ && rbt == FFEINFO_basictypeLOGICAL);
+
return reduced;
}
@@ -19442,7 +18564,7 @@ ffeexpr_token_anything_ (ffelexToken ft UNUSED, ffebld expr UNUSED,
/* Terminate module. */
void
-ffeexpr_terminate_2 ()
+ffeexpr_terminate_2 (void)
{
assert (ffeexpr_stack_ == NULL);
assert (ffeexpr_level_ == 0);
diff --git a/contrib/gcc/f/ffe.texi b/contrib/gcc/f/ffe.texi
index 9aa6a973e3b9..fd5d3bf349ae 100644
--- a/contrib/gcc/f/ffe.texi
+++ b/contrib/gcc/f/ffe.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 1999 Free Software Foundation, Inc.
+@c Copyright (C) 1999, 2003 Free Software Foundation, Inc.
@c This is part of the G77 manual.
@c For copying conditions, see the file g77.texi.
@@ -37,22 +37,22 @@ need to take first.
The current directory layout includes the following:
@table @file
-@item @value{srcdir}/gcc/
+@item @var{srcdir}/gcc/
Non-g77 files in gcc
-@item @value{srcdir}/gcc/f/
+@item @var{srcdir}/gcc/f/
GNU Fortran front end sources
-@item @value{srcdir}/libf2c/
+@item @var{srcdir}/libf2c/
@code{libg2c} configuration and @code{g2c.h} file generation
-@item @value{srcdir}/libf2c/libF77/
+@item @var{srcdir}/libf2c/libF77/
General support and math portion of @code{libg2c}
-@item @value{srcdir}/libf2c/libI77/
+@item @var{srcdir}/libf2c/libI77/
I/O portion of @code{libg2c}
-@item @value{srcdir}/libf2c/libU77/
+@item @var{srcdir}/libf2c/libU77/
Additional interfaces to Unix @code{libc} for @code{libg2c}
@end table
@@ -199,8 +199,7 @@ in @file{xyz.h} and implemented there (if it's a macro) or in @file{xyz.c}.
The ``porting'' files of note currently are:
@table @file
-@item proj.c
-@itemx proj.h
+@item proj.h
This defines the ``language'' used by all the other source files,
the language being Standard C plus some useful things
like @code{ARRAY_SIZE} and such.
diff --git a/contrib/gcc/f/fini.c b/contrib/gcc/f/fini.c
index 28d9028df137..167837b461f3 100644
--- a/contrib/gcc/f/fini.c
+++ b/contrib/gcc/f/fini.c
@@ -19,7 +19,7 @@ along with GNU Fortran; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#define USE_HCONFIG
+#define USE_BCONFIG
#include "proj.h"
#include "malloc.h"
@@ -367,7 +367,7 @@ main (int argc, char **argv)
/* Make new name object to store name and its keyword. */
- newname = (name) xmalloc (sizeof (*newname));
+ newname = xmalloc (sizeof (*newname));
newname->namelen = strlen (buf);
newname->kwlen = strlen (kwname);
total_length = newname->kwlen + fixlengths;
diff --git a/contrib/gcc/f/g77.texi b/contrib/gcc/f/g77.texi
index a7cd96bc0fbb..3d5f83d3da6a 100644
--- a/contrib/gcc/f/g77.texi
+++ b/contrib/gcc/f/g77.texi
@@ -2,8 +2,8 @@
@c %**start of header
@setfilename g77.info
-@set last-update 2003-05-13
-@set copyrights-g77 1995,1996,1997,1998,1999,2000,2001,2002,2003
+@set last-update 2004-03-21
+@set copyrights-g77 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004
@include root.texi
@@ -250,7 +250,7 @@ many people have helped create and improve GNU Fortran.
@itemize @bullet
@item
The packaging and compiler portions of GNU Fortran are based largely
-on the GNU CC compiler.
+on the GCC compiler.
@xref{Contributors,,Contributors to GCC,gcc,Using the GNU Compiler
Collection (GCC)},
for more information.
@@ -316,6 +316,8 @@ for @code{INTEGER*1}, @code{INTEGER*2}, and
This inspired Craig to add further support,
even though the resulting support
would still be incomplete.
+This support is believed to be completed at version 3.4
+of @command{gcc} by Roger Sayle (@email{roger@@eyesopen.com}).
@item
David Ronis (@email{ronis@@onsager.chem.mcgill.ca}) inspired
@@ -797,10 +799,10 @@ files and accepts Fortran-specific command-line options, plus some
command-line options that are designed to cater to Fortran users
but apply to other languages as well.
-@xref{G++ and GCC,,Compile C; C++; Objective-C; Ada; Fortran;
-or Java,gcc,Using the GNU Compiler Collection (GCC)},
+@xref{G++ and GCC,,Programming Languages Supported by GCC,gcc,Using
+the GNU Compiler Collection (GCC)},
for information on the way different languages are handled
-by the GNU CC compiler (@command{gcc}).
+by the GCC compiler (@command{gcc}).
@cindex @command{g77}, command
@cindex commands, @command{g77}
@@ -849,7 +851,7 @@ by GNU Fortran.
@cindex textbooks
(If you need a text on Fortran,
a few freely available electronic references have pointers from
-@uref{http://www.fortran.com/fortran/Books/}. There is a `cooperative
+@uref{http://www.fortran.com/F/books.html}. There is a `cooperative
net project', @cite{User Notes on Fortran Programming} at
@uref{ftp://vms.huji.ac.il/fortran/} and mirrors elsewhere; some of this
material might not apply specifically to @command{g77}.)
@@ -6898,13 +6900,6 @@ without having to traverse C-like structures and unions, while @command{f2c}
is unlikely to ever offer this ability (due to limitations in the
C language).
-However, due to apparent bugs in the back end, @command{g77} currently doesn't
-take advantage of this facility at all---it doesn't emit any debugging
-information for @code{COMMON} and @code{EQUIVALENCE} areas,
-other than information
-on the array of @code{char} it creates (and, in the case
-of local @code{EQUIVALENCE}, names) for each such area.
-
Yet another example is arrays.
@command{g77} represents them to the debugger
using the same ``dimensionality'' as in the source code, while @command{f2c}
@@ -8000,13 +7995,6 @@ Progress is being made on making this work
@command{gcc}, and some of the relevant operating systems
(such as GNU/Linux).
-@cindex alignment testing
-@cindex testing alignment
-A package that tests the degree to which a Fortran compiler
-(such as @command{g77})
-aligns 64-bit floating-point variables and arrays
-is available at @uref{ftp://alpha.gnu.org/gnu/g77/align/}.
-
@node Prefer Automatic Uninitialized Variables
@subsection Prefer Automatic Uninitialized Variables
@@ -8088,10 +8076,6 @@ Some of these problems are due to bugs in other software, some are
missing features that are too much work to add, and some are places
where people's opinions differ as to what is best.
-To find out about major bugs discovered in the current release and
-possible workarounds for them, see
-@uref{ftp://alpha.gnu.org/g77.plan}.
-
(Note that some of this portion of the manual is lifted
directly from the @command{gcc} manual, with minor modifications
to tailor it to users of @command{g77}.
@@ -8627,24 +8611,17 @@ Goldberg, `What Every Computer Scientist Should Know About
Floating-Point Arithmetic', Computing Surveys, 23, March 1991, pp.@:
5-48.
An online version is available at
-@uref{http://docs.sun.com/},
-and there is a supplemented version, in PostScript form, at
-@uref{http://www.validgh.com/goldberg/paper.ps}.
+@uref{http://docs.sun.com/}.
-Information related to the IEEE 754
-floating-point standard by a leading light can be found at
+Information related to the IEEE 754 floating-point standard can be found
+at @uref{http://grouper.ieee.org/groups/754/} and
@uref{http://http.cs.berkeley.edu/%7Ewkahan/ieee754status/};
see also slides from the short course referenced from
@uref{http://http.cs.berkeley.edu/%7Efateman/}.
-@uref{http://www.linuxsupportline.com/%7Ebillm/} has a brief
-guide to IEEE 754, a somewhat x86-GNU/Linux-specific FAQ,
-and library code for GNU/Linux x86 systems.
The supplement to the PostScript-formatted Goldberg document,
referenced above, is available in HTML format.
-See `Differences Among IEEE 754 Implementations' by Doug Priest,
-available online at
-@uref{http://www.validgh.com/goldberg/addendum.html}.
+See `Differences Among IEEE 754 Implementations' by Doug Priest.
This document explores some of the issues surrounding computing
of extended (80-bit) results on processors such as the x86,
especially when those results are arbitrarily truncated
@@ -10635,7 +10612,7 @@ ways to find it:
@item
Look in the service directory for someone who might help you for a fee.
The service directory is found in the file named @file{SERVICE} in the
-GNU CC distribution.
+GCC distribution.
@item
Send a message to @email{@value{email-help}}.
@@ -10777,8 +10754,6 @@ are passed via this mechanism.
If you want to contribute to @command{g77} by doing research,
design, specification, documentation, coding, or testing,
the following information should give you some ideas.
-More relevant information might be available from
-@uref{ftp://alpha.gnu.org/gnu/g77/projects/}.
@menu
* Efficiency:: Make @command{g77} itself compile code faster.
diff --git a/contrib/gcc/f/g77spec.c b/contrib/gcc/f/g77spec.c
index 9206ef7f1a87..3dca7bc44838 100644
--- a/contrib/gcc/f/g77spec.c
+++ b/contrib/gcc/f/g77spec.c
@@ -1,21 +1,21 @@
/* Specific flags and argument handling of the Fortran front-end.
- Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003
+ Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -47,7 +47,10 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "gcc.h"
+#include "intl.h"
#ifndef MATH_LIBRARY
#define MATH_LIBRARY "-lm"
@@ -91,9 +94,8 @@ typedef enum
/* The original argument list and related info is copied here. */
static int g77_xargc;
static const char *const *g77_xargv;
-static void lookup_option PARAMS ((Option *, int *, const char **,
- const char *));
-static void append_arg PARAMS ((const char *));
+static void lookup_option (Option *, int *, const char **, const char *);
+static void append_arg (const char *);
/* The new argument list will be built here. */
static int g77_newargc;
@@ -116,11 +118,7 @@ static const char **g77_newargv;
to short ones, where available, has already been run. */
static void
-lookup_option (xopt, xskip, xarg, text)
- Option *xopt;
- int *xskip;
- const char **xarg;
- const char *text;
+lookup_option (Option *xopt, int *xskip, const char **xarg, const char *text)
{
Option opt = OPTION_;
int skip;
@@ -200,8 +198,7 @@ lookup_option (xopt, xskip, xarg, text)
the new arg count. Otherwise allocate a new list, etc. */
static void
-append_arg (arg)
- const char *arg;
+append_arg (const char *arg)
{
static int newargsize;
@@ -223,7 +220,7 @@ append_arg (arg)
int i;
newargsize = (g77_xargc << 2) + 20; /* This should handle all. */
- g77_newargv = (const char **) xmalloc (newargsize * sizeof (char *));
+ g77_newargv = xmalloc (newargsize * sizeof (char *));
/* Copy what has been done so far. */
for (i = 0; i < g77_newargc; ++i)
@@ -237,10 +234,8 @@ append_arg (arg)
}
void
-lang_specific_driver (in_argc, in_argv, in_added_libraries)
- int *in_argc;
- const char *const **in_argv;
- int *in_added_libraries ATTRIBUTE_UNUSED;
+lang_specific_driver (int *in_argc, const char *const **in_argv,
+ int *in_added_libraries ATTRIBUTE_UNUSED)
{
int argc = *in_argc;
const char *const *argv = *in_argv;
@@ -351,16 +346,17 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
break;
case OPTION_version:
- printf ("\
-GNU Fortran (GCC) %s\n\
-Copyright (C) 2002 Free Software Foundation, Inc.\n\
-\n\
+ printf ("GNU Fortran (GCC) %s\n", version_string);
+ printf ("Copyright %s 2004 Free Software Foundation, Inc.\n",
+ _("(C)"));
+ printf ("\n");
+ printf (_("\
GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\
You may redistribute copies of GNU Fortran\n\
under the terms of the GNU General Public License.\n\
For more information about these matters, see the file named COPYING\n\
or type the command `info -f g77 Copying'.\n\
-", version_string);
+"));
exit (0);
break;
@@ -449,11 +445,7 @@ or type the command `info -f g77 Copying'.\n\
saw_library = 0; /* -xfoo currently active. */
else
{ /* -lfoo or filename. */
- if (strcmp (argv[i], MATH_LIBRARY) == 0
-#ifdef ALT_LIBM
- || strcmp (argv[i], ALT_LIBM) == 0
-#endif
- )
+ if (strcmp (argv[i], MATH_LIBRARY) == 0)
{
if (saw_library == 1)
saw_library = 2; /* -l<library> -lm. */
@@ -534,7 +526,7 @@ or type the command `info -f g77 Copying'.\n\
}
/* Called before linking. Returns 0 on success and -1 on failure. */
-int lang_specific_pre_link () /* Not used for F77. */
+int lang_specific_pre_link (void) /* Not used for F77. */
{
return 0;
}
diff --git a/contrib/gcc/f/global.c b/contrib/gcc/f/global.c
index 1fe92701a12e..8793f62c4a73 100644
--- a/contrib/gcc/f/global.c
+++ b/contrib/gcc/f/global.c
@@ -1,5 +1,5 @@
/* global.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1997, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -62,14 +62,14 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
static ffenameSpace ffeglobal_filewide_ = NULL;
static const char *const ffeglobal_type_string_[] =
{
- [FFEGLOBAL_typeNONE] "??",
- [FFEGLOBAL_typeMAIN] "main program",
- [FFEGLOBAL_typeEXT] "external",
- [FFEGLOBAL_typeSUBR] "subroutine",
- [FFEGLOBAL_typeFUNC] "function",
- [FFEGLOBAL_typeBDATA] "block data",
- [FFEGLOBAL_typeCOMMON] "common block",
- [FFEGLOBAL_typeANY] "?any?"
+ [FFEGLOBAL_typeNONE] = "??",
+ [FFEGLOBAL_typeMAIN] = "main program",
+ [FFEGLOBAL_typeEXT] = "external",
+ [FFEGLOBAL_typeSUBR] = "subroutine",
+ [FFEGLOBAL_typeFUNC] = "function",
+ [FFEGLOBAL_typeBDATA] = "block data",
+ [FFEGLOBAL_typeCOMMON] = "common block",
+ [FFEGLOBAL_typeANY] = "?any?"
};
#endif
@@ -107,12 +107,9 @@ ffeglobal_new_ (ffename n)
assert (n != NULL);
- g = (ffeglobal) malloc_new_ks (malloc_pool_image (), "FFEGLOBAL",
- sizeof (*g));
+ g = malloc_new_ks (malloc_pool_image (), "FFEGLOBAL", sizeof (*g));
g->n = n;
-#ifdef FFECOM_globalHOOK
g->hook = FFECOM_globalNULL;
-#endif
g->tick = 0;
ffename_set_global (n, g);
@@ -126,7 +123,7 @@ ffeglobal_new_ (ffename n)
ffeglobal_init_1(); */
void
-ffeglobal_init_1 ()
+ffeglobal_init_1 (void)
{
#if FFEGLOBAL_ENABLED
if (ffeglobal_filewide_ != NULL)
@@ -782,10 +779,9 @@ ffeglobal_proc_def_nargs (ffesymbol s, int n_args)
return;
}
- g->u.proc.arg_info
- = (ffeglobalArgInfo_) malloc_new_ks (malloc_pool_image (),
- "ffeglobalArgInfo_",
- n_args * sizeof (g->u.proc.arg_info[0]));
+ g->u.proc.arg_info = malloc_new_ks (malloc_pool_image (),
+ "ffeglobalArgInfo_",
+ n_args * sizeof (g->u.proc.arg_info[0]));
while (n_args-- > 0)
g->u.proc.arg_info[n_args].t = NULL;
}
@@ -1125,10 +1121,9 @@ ffeglobal_proc_ref_nargs (ffesymbol s, int n_args, ffelexToken t)
return TRUE;
}
- g->u.proc.arg_info
- = (ffeglobalArgInfo_) malloc_new_ks (malloc_pool_image (),
- "ffeglobalArgInfo_",
- n_args * sizeof (g->u.proc.arg_info[0]));
+ g->u.proc.arg_info = malloc_new_ks (malloc_pool_image (),
+ "ffeglobalArgInfo_",
+ n_args * sizeof (g->u.proc.arg_info[0]));
while (n_args-- > 0)
g->u.proc.arg_info[n_args].t = NULL;
@@ -1430,9 +1425,7 @@ ffeglobal_ref_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type)
/* We've learned more, so point to where we learned it. */
g->t = ffelex_token_use (t);
g->type = type;
-#ifdef FFECOM_globalHOOK
g->hook = FFECOM_globalNULL; /* Discard previous _DECL. */
-#endif
g->u.proc.n_args = -1;
}
@@ -1588,6 +1581,6 @@ ffeglobal_size_common (ffesymbol s, ffetargetOffset size)
#endif
void
-ffeglobal_terminate_1 ()
+ffeglobal_terminate_1 (void)
{
}
diff --git a/contrib/gcc/f/global.h b/contrib/gcc/f/global.h
index 15d984f7f4ed..dc499df9eb7d 100644
--- a/contrib/gcc/f/global.h
+++ b/contrib/gcc/f/global.h
@@ -1,5 +1,5 @@
/* global.h -- Public #include File (module.h template V1.0)
- Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1997, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -89,9 +89,7 @@ struct _ffeglobal_
{
ffelexToken t;
ffename n;
-#ifdef FFECOM_globalHOOK
ffecomGlobal hook;
-#endif
ffeCounter tick; /* Recent transition in this progunit. */
ffeglobalType type;
bool intrinsic; /* Known as intrinsic? */
diff --git a/contrib/gcc/f/implic.c b/contrib/gcc/f/implic.c
index 6fe4606e357e..c7a28cbc42ac 100644
--- a/contrib/gcc/f/implic.c
+++ b/contrib/gcc/f/implic.c
@@ -1,5 +1,5 @@
/* implic.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2002, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -220,7 +220,7 @@ ffeimplic_establish_symbol (ffesymbol s)
Allows for holes in the sequence of letters (i.e. EBCDIC). */
void
-ffeimplic_init_2 ()
+ffeimplic_init_2 (void)
{
ffeimplic_ imp;
char c;
@@ -312,7 +312,7 @@ ffeimplic_init_2 ()
Assigns null type information to all initial letters. */
void
-ffeimplic_none ()
+ffeimplic_none (void)
{
ffeimplic_ imp;
@@ -378,6 +378,6 @@ ffeimplic_peek_symbol_type (ffesymbol s, const char *name)
Kills info object for each entry in table. */
void
-ffeimplic_terminate_2 ()
+ffeimplic_terminate_2 (void)
{
}
diff --git a/contrib/gcc/f/info.c b/contrib/gcc/f/info.c
index 1bedaa0772dd..3c0030f27f8f 100644
--- a/contrib/gcc/f/info.c
+++ b/contrib/gcc/f/info.c
@@ -1,5 +1,5 @@
/* info.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2002, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -141,7 +141,7 @@ ffeinfo_basictype_string (ffeinfoBasictype basictype)
ffeinfo_init_0(); */
void
-ffeinfo_init_0 ()
+ffeinfo_init_0 (void)
{
ffeinfoBasictype i;
ffeinfoBasictype j;
diff --git a/contrib/gcc/f/intdoc.c b/contrib/gcc/f/intdoc.c
index fb88e88cecd6..b24c79a48114 100644
--- a/contrib/gcc/f/intdoc.c
+++ b/contrib/gcc/f/intdoc.c
@@ -1,5 +1,6 @@
/* intdoc.c
- Copyright (C) 1997, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1997, 2000, 2001, 2003
+ Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -22,8 +23,10 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* From f/proj.h, which uses #error -- not all C compilers
support that, and we want *this* program to be compilable
by pretty much any C compiler. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "assert.h"
/* Pull in the intrinsics info, but only the doc parts. */
@@ -235,13 +238,13 @@ dumpif (ffeintrinFamily fam)
}
static void
-dumpendif ()
+dumpendif (void)
{
in_ifset = 2;
}
static void
-dumpclearif ()
+dumpclearif (void)
{
if ((in_ifset == 2)
|| (latest_family != FFEINTRIN_familyNONE))
@@ -251,7 +254,7 @@ dumpclearif ()
}
static void
-dumpem ()
+dumpem (void)
{
int i;
diff --git a/contrib/gcc/f/intdoc.in b/contrib/gcc/f/intdoc.in
index 55d426ad9305..6f2423f6cac6 100644
--- a/contrib/gcc/f/intdoc.in
+++ b/contrib/gcc/f/intdoc.in
@@ -2401,7 +2401,7 @@ See @code{signal(2)}.
Note that @var{@2@} will be called using C conventions,
so the value of its argument in Fortran terms
-Fortran terms is obtained by applying @code{%LOC()} (or @var{LOC()}) to it.
+Fortran terms is obtained by applying @code{%LOC()} (or @code{LOC()}) to it.
The value returned by @code{signal(2)} is written to @var{@3@}, if
that argument is supplied.
@@ -2451,7 +2451,7 @@ See @code{signal(2)}.
Note that @var{@2@} will be called using C conventions,
so the value of its argument in Fortran terms
-is obtained by applying @code{%LOC()} (or @var{LOC()}) to it.
+is obtained by applying @code{%LOC()} (or @code{LOC()}) to it.
The value returned by @code{signal(2)} is returned.
diff --git a/contrib/gcc/f/intdoc.texi b/contrib/gcc/f/intdoc.texi
index 7de42578d1a4..e657510a0608 100644
--- a/contrib/gcc/f/intdoc.texi
+++ b/contrib/gcc/f/intdoc.texi
@@ -9500,7 +9500,7 @@ See @code{signal(2)}.
Note that @var{Handler} will be called using C conventions,
so the value of its argument in Fortran terms
-Fortran terms is obtained by applying @code{%LOC()} (or @var{LOC()}) to it.
+Fortran terms is obtained by applying @code{%LOC()} (or @code{LOC()}) to it.
The value returned by @code{signal(2)} is written to @var{Status}, if
that argument is supplied.
@@ -9579,7 +9579,7 @@ See @code{signal(2)}.
Note that @var{Handler} will be called using C conventions,
so the value of its argument in Fortran terms
-is obtained by applying @code{%LOC()} (or @var{LOC()}) to it.
+is obtained by applying @code{%LOC()} (or @code{LOC()}) to it.
The value returned by @code{signal(2)} is returned.
diff --git a/contrib/gcc/f/intrin.c b/contrib/gcc/f/intrin.c
index 1c6c00c73210..a379684ae4c2 100644
--- a/contrib/gcc/f/intrin.c
+++ b/contrib/gcc/f/intrin.c
@@ -1,5 +1,6 @@
/* intrin.c -- Recognize references to intrinsics
- Copyright (C) 1995, 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1998, 2002,
+ 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -1389,7 +1390,7 @@ ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t)
if (!highly_specific && (nimp != FFEINTRIN_impNONE))
{
fprintf (stderr, "lineno=%ld, gen=%s, imp=%s, timp=%s\n",
- (long) lineno,
+ (long) input_line,
ffeintrin_gens_[gen].name,
ffeintrin_imps_[imp].name,
ffeintrin_imps_[nimp].name);
@@ -1588,7 +1589,7 @@ ffeintrin_gfrt_indirect (ffeintrinImp imp)
}
void
-ffeintrin_init_0 ()
+ffeintrin_init_0 (void)
{
int i;
const char *p1;
diff --git a/contrib/gcc/f/invoke.texi b/contrib/gcc/f/invoke.texi
index 50c7ca42e736..fd1b80412a64 100644
--- a/contrib/gcc/f/invoke.texi
+++ b/contrib/gcc/f/invoke.texi
@@ -1,11 +1,11 @@
-@c Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+@c Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004
@c Free Software Foundation, Inc.
@c This is part of the G77 manual.
@c For copying conditions, see the file g77.texi.
@ignore
@c man begin COPYRIGHT
-Copyright @copyright{} 1996, 1997, 1998, 1999, 2000, 2001, 2002
+Copyright @copyright{} 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
@@ -255,7 +255,7 @@ program is written is generally indicated by the suffix.
Suffixes specific to GNU Fortran are listed below.
@xref{Overall Options,,Options Controlling the Kind of
Output,gcc,Using the GNU Compiler Collection (GCC)}, for
-information on suffixes recognized by GNU CC.
+information on suffixes recognized by GCC.
@table @gcctabopt
@cindex .f filename suffix
@@ -286,7 +286,7 @@ You can force @samp{.f} files to be preprocessed by @command{cpp} by using
@item @var{file}.fpp
@item @var{file}.FPP
Fortran source code that must be preprocessed (by the C preprocessor
-@command{cpp}, which is part of GNU CC).
+@command{cpp}, which is part of GCC).
Note that preprocessing is not extended to the contents of
files included by the @code{INCLUDE} directive---the @code{#include}
@@ -300,9 +300,7 @@ preprocessor directive must be used instead.
Ratfor source code, which must be preprocessed by the @command{ratfor}
command, which is available separately (as it is not yet part of the GNU
Fortran distribution).
-One version in Fortran, adapted for use with @command{g77} is at
-@uref{ftp://members.aol.com/n8tm/rat7.uue} (of uncertain copyright
-status). Another, public domain version in C is at
+A public domain version in C is at
@uref{http://sepwww.stanford.edu/sep/prof/ratfor.shar.2}.
@end table
diff --git a/contrib/gcc/f/lab.c b/contrib/gcc/f/lab.c
index a870a7fe9c02..1d278748b21d 100644
--- a/contrib/gcc/f/lab.c
+++ b/contrib/gcc/f/lab.c
@@ -1,5 +1,5 @@
/* lab.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -94,7 +94,7 @@ ffelab_find (ffelabValue v)
Kill all the labels on the list. */
void
-ffelab_finish ()
+ffelab_finish (void)
{
ffelab l;
ffelab pl;
@@ -115,7 +115,7 @@ ffelab_finish ()
unit is going to be processed. */
void
-ffelab_init_3 ()
+ffelab_init_3 (void)
{
ffelab_list_ = NULL;
ffelab_num_news_ = 0;
@@ -141,11 +141,9 @@ ffelab_new (ffelabValue v)
ffelab l;
++ffelab_num_news_;
- l = (ffelab) malloc_new_ks (ffe_pool_any_unit (), "FFELAB label", sizeof (*l));
+ l = malloc_new_ks (ffe_pool_any_unit (), "FFELAB label", sizeof (*l));
l->next = ffelab_list_;
-#ifdef FFECOM_labelHOOK
l->hook = FFECOM_labelNULL;
-#endif
l->value = v;
l->firstref_line = ffewhere_line_unknown ();
l->firstref_col = ffewhere_column_unknown ();
diff --git a/contrib/gcc/f/lab.h b/contrib/gcc/f/lab.h
index fba3808ec8e2..f3f89868a546 100644
--- a/contrib/gcc/f/lab.h
+++ b/contrib/gcc/f/lab.h
@@ -1,5 +1,5 @@
/* lab.h -- Public #include File (module.h template V1.0)
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -70,9 +70,7 @@ typedef unsigned long ffelabValue;
struct _ffelab_
{
ffelab next;
-#ifdef FFECOM_labelHOOK
ffecomLabel hook;
-#endif
ffelabValue value; /* 1 through 99999, or 100000+ for temp
labels. */
unsigned long blocknum; /* Managed entirely by user of module. */
diff --git a/contrib/gcc/f/lang-specs.h b/contrib/gcc/f/lang-specs.h
index 62b78c6f361c..9ed51ef5a60c 100644
--- a/contrib/gcc/f/lang-specs.h
+++ b/contrib/gcc/f/lang-specs.h
@@ -31,14 +31,14 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
{"@f77-cpp-input",
"cc1 -E -traditional-cpp -D_LANGUAGE_FORTRAN %(cpp_options) \
%{E|M|MM:%(cpp_debug_options)}\
- %{!M:%{!MM:%{!E:%{!pipe:%g.f} |\n\
- f771 %{!pipe:%g.f} %(cc1_options) %{I*} %{!fsyntax-only:%(invoke_as)}}}}", 0},
+ %{!M:%{!MM:%{!E: -o %|.f |\n\
+ f771 %|.f %(cc1_options) %{I*} %{!fsyntax-only:%(invoke_as)}}}}", 0},
{".r", "@ratfor", 0},
{"@ratfor",
- "%{C:%{!E:%eGNU C does not support -C without using -E}}\
- %{CC:%{!E:%eGNU C does not support -CC without using -E}}\
+ "%{C:%{!E:%eGCC does not support -C without using -E}}\
+ %{CC:%{!E:%eGCC does not support -CC without using -E}}\
ratfor %{C} %{CC} %{v} %{E:%W{o*}} %{!E: %{!pipe:-o %g.f} %i |\n\
- f771 %{!pipe:%g.f} %(cc1_options) %{I*} %{!fsyntax-only:%(invoke_as)}}", 0},
+ f771 %m.f %(cc1_options) %{I*} %{!fsyntax-only:%(invoke_as)}}", 0},
{".f", "@f77", 0},
{".for", "@f77", 0},
{".FOR", "@f77", 0},
diff --git a/contrib/gcc/f/lang.opt b/contrib/gcc/f/lang.opt
new file mode 100644
index 000000000000..d6a53b7dcd13
--- /dev/null
+++ b/contrib/gcc/f/lang.opt
@@ -0,0 +1,402 @@
+; Options for the Fortran 77 front end.
+; Copyright (C) 2003 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 2, 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 COPYING. If not, write to the Free
+; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+; 02111-1307, USA.
+
+; See c.opt for a description of this file's format.
+
+; Please try to keep this file in ASCII collating order.
+
+Language
+F77
+
+I
+F77 Joined
+Add a directory for INCLUDE searching
+
+Wall
+F77
+; Documented in C
+
+Wcomment
+F77
+
+Wcomments
+F77
+
+Wglobals
+F77
+Enable warnings about inter-procedural problems
+
+Wimplicit
+F77
+
+Wimport
+F77
+
+Wsurprising
+F77
+Warn about constructs with surprising meanings
+
+Wtrigraphs
+F77
+
+fautomatic
+F77
+Do not treat local variables and COMMON blocks as if they were named in SAVE statements
+
+fbackslash
+F77
+Backslashes in character and hollerith constants are special (not C-style)
+
+fbadu77-intrinsics-delete
+F77 RejectNegative
+Delete libU77 intrinsics with bad interfaces
+
+fbadu77-intrinsics-disable
+F77 RejectNegative
+Disable libU77 intrinsics with bad interfaces
+
+fbadu77-intrinsics-enable
+F77 RejectNegative
+Enable libU77 intrinsics with bad interfaces
+
+fbadu77-intrinsics-hide
+F77 RejectNegative
+Hide libU77 intrinsics with bad interfaces
+
+fcase-initcap
+F77 RejectNegative
+Program written in strict mixed-case
+
+fcase-lower
+F77 RejectNegative
+Compile as if program written in lowercase
+
+fcase-preserve
+F77 RejectNegative
+Preserve case used in program
+
+fcase-strict-lower
+F77 RejectNegative
+Program written in lowercase
+
+fcase-strict-upper
+F77 RejectNegative
+Program written in uppercase
+
+fcase-upper
+F77 RejectNegative
+Compile as if program written in uppercase
+
+fdebug-kludge
+F77
+Emit special debugging information for COMMON and EQUIVALENCE (disabled)
+
+fdollar-ok
+F77
+Allow '$' in symbol names
+
+femulate-complex
+F77
+Have front end emulate COMPLEX arithmetic to avoid bugs
+
+ff2c
+F77
+f2c-compatible code can be generated
+
+ff2c-intrinsics-delete
+F77 RejectNegative
+Delete non-FORTRAN-77 intrinsics f2c supports
+
+ff2c-intrinsics-disable
+F77 RejectNegative
+Disable non-FORTRAN-77 intrinsics f2c supports
+
+ff2c-intrinsics-enable
+F77 RejectNegative
+Enable non-FORTRAN-77 intrinsics f2c supports
+
+ff2c-intrinsics-hide
+F77 RejectNegative
+Hide non-FORTRAN-77 intrinsics f2c supports
+
+ff2c-library
+F77
+Unsupported; generate libf2c-calling code
+
+ff66
+F77
+Program is written in typical FORTRAN 66 dialect
+
+ff77
+F77
+Program is written in typical Unix-f77 dialect
+
+ff90
+F77
+Program is written in Fortran-90-ish dialect
+
+ff90-intrinsics-delete
+F77 RejectNegative
+Delete non-FORTRAN-77 intrinsics F90 supports
+
+ff90-intrinsics-disable
+F77 RejectNegative
+Disable non-FORTRAN-77 intrinsics F90 supports
+
+ff90-intrinsics-enable
+F77 RejectNegative
+Enable non-FORTRAN-77 intrinsics F90 supports
+
+ff90-intrinsics-hide
+F77 RejectNegative
+Hide non-FORTRAN-77 intrinsics F90 supports
+
+ff90-not-vxt
+F77 RejectNegative
+
+ffixed-form
+F77
+
+ffixed-line-length-
+F77 Joined
+ffixed-line-length-<number> Set the maximum line length to <number>
+
+fflatten-arrays
+F77
+Unsupported; affects code generation of arrays
+
+ffortran-bounds-check
+F77
+Generate code to check subscript and substring bounds
+
+ffree-form
+F77
+Program is written in Fortran-90-ish free form
+
+fglobals
+F77
+Enable fatal diagnostics about inter-procedural problems
+
+fgnu-intrinsics-delete
+F77 RejectNegative
+Delete non-FORTRAN-77 intrinsics g77 supports
+
+fgnu-intrinsics-disable
+F77 RejectNegative
+Disable non-FORTRAN 77 intrinsics F90 supports
+
+fgnu-intrinsics-enable
+F77 RejectNegative
+Enable non-FORTRAN 77 intrinsics F90 supports
+
+fgnu-intrinsics-hide
+F77 RejectNegative
+Hide non-FORTRAN 77 intrinsics F90 supports
+
+finit-local-zero
+F77
+Initialize local vars and arrays to zero
+
+fintrin-case-any
+F77 RejectNegative
+Intrinsics letters in arbitrary cases
+
+fintrin-case-initcap
+F77 RejectNegative
+Intrinsics spelled as e.g. SqRt
+
+fintrin-case-lower
+F77 RejectNegative
+Intrinsics in lowercase
+
+fintrin-case-upper
+F77 RejectNegative
+Intrinsics in uppercase
+
+fmatch-case-any
+F77 RejectNegative
+Language keyword letters in arbitrary cases
+
+fmatch-case-initcap
+F77 RejectNegative
+Language keywords spelled as e.g. IOStat
+
+fmatch-case-lower
+F77 RejectNegative
+Language keywords in lowercase
+
+fmatch-case-upper
+F77 RejectNegative
+Language keywords in uppercase
+
+fmil-intrinsics-delete
+F77 RejectNegative
+Delete MIL-STD 1753 intrinsics
+
+fmil-intrinsics-disable
+F77 RejectNegative
+Disable MIL-STD 1753 intrinsics
+
+fmil-intrinsics-enable
+F77 RejectNegative
+Enable MIL-STD 1753 intrinsics
+
+fmil-intrinsics-hide
+F77 RejectNegative
+Hide MIL-STD 1753 intrinsics
+
+fonetrip
+F77
+Take at least one trip through each iterative DO loop
+
+fpedantic
+F77
+Warn about use of (only a few for now) Fortran extensions
+
+fpreprocessed
+F77
+
+fsecond-underscore
+F77
+Allow appending a second underscore to externals
+
+fsilent
+F77
+Do not print names of program units as they are compiled
+
+fsource-case-lower
+F77 RejectNegative
+Internally convert most source to lowercase
+
+fsource-case-preserve
+F77 RejectNegative
+Internally preserve source case
+
+fsource-case-upper
+F77 RejectNegative
+Internally convert most source to uppercase
+
+fsymbol-case-any
+F77 RejectNegative
+
+fsymbol-case-initcap
+F77 RejectNegative
+Symbol names spelled in mixed case
+
+fsymbol-case-lower
+F77 RejectNegative
+Symbol names in lowercase
+
+fsymbol-case-upper
+F77 RejectNegative
+Symbol names in uppercase
+
+ftypeless-boz
+F77
+Make prefix-radix non-decimal constants be typeless
+
+fugly
+F77
+Allow all ugly features
+
+fugly-args
+F77
+Hollerith and typeless can be passed as arguments
+
+fugly-assign
+F77
+Allow ordinary copying of ASSIGN'ed vars
+
+fugly-assumed
+F77
+Dummy array dimensioned to (1) is assumed-size
+
+fugly-comma
+F77
+Trailing comma in procedure call denotes null argument
+
+fugly-complex
+F77
+Allow REAL(Z) and AIMAG(Z) given DOUBLE COMPLEX Z
+
+fugly-init
+F77
+Initialization via DATA and PARAMETER is not type-compatible
+
+fugly-logint
+F77
+Allow INTEGER and LOGICAL interchangeability
+
+funderscoring
+F77
+Append underscores to externals
+
+funix-intrinsics-delete
+F77 RejectNegative
+Delete libU77 intrinsics
+
+funix-intrinsics-disable
+F77 RejectNegative
+Disable libU77 intrinsics
+
+funix-intrinsics-enable
+F77 RejectNegative
+Enable libU77 intrinsics
+
+funix-intrinsics-hide
+F77 RejectNegative
+Hide libU77 intrinsics
+
+fversion
+F77 RejectNegative
+Print g77-specific version information and run internal tests
+
+fvxt
+F77
+Program is written in VXT (Digital-like) FORTRAN
+
+fvxt-intrinsics-delete
+F77 RejectNegative
+Delete non-FORTRAN-77 intrinsics VXT FORTRAN supports
+
+fvxt-intrinsics-disable
+F77 RejectNegative
+Disable non-FORTRAN-77 intrinsics VXT FORTRAN supports
+
+fvxt-intrinsics-enable
+F77 RejectNegative
+Enable non-FORTRAN-77 intrinsics VXT FORTRAN supports
+
+fvxt-intrinsics-hide
+F77 RejectNegative
+Hide non-FORTRAN-77 intrinsics VXT FORTRAN supports
+
+fvxt-not-f90
+F77 RejectNegative
+
+fxyzzy
+F77
+Print internal debugging-related information
+
+fzeros
+F77
+Treat initial values of 0 like non-zero values
+
+; This comment is to ensure we retain the blank line above.
diff --git a/contrib/gcc/f/lex.c b/contrib/gcc/f/lex.c
index 6d065ddd052f..8475d2ff2c37 100644
--- a/contrib/gcc/f/lex.c
+++ b/contrib/gcc/f/lex.c
@@ -1,5 +1,5 @@
/* Implementation of Fortran lexer
- Copyright (C) 1995, 1996, 1997, 1998, 2001, 2002
+ Copyright (C) 1995, 1996, 1997, 1998, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by James Craig Burley.
@@ -219,11 +219,6 @@ ffelex_append_to_token_ (char c)
ffelex_token_->size <<= 1;
assert (ffelex_token_->length < ffelex_token_->size);
}
-#ifdef MAP_CHARACTER
-Sorry, MAP_CHARACTER is not going to work as expected in GNU Fortran,
-please contact fortran@gnu.org if you wish to fund work to
-port g77 to non-ASCII machines.
-#endif
ffelex_token_->text[ffelex_token_->length++] = c;
}
@@ -699,7 +694,13 @@ ffelex_cfelex_ (ffelexToken *xtoken, FILE *finput, int c)
register unsigned bytes_used = (p - q);
buffer_length *= 2;
- q = (char *)xrealloc (q, buffer_length);
+ if (q == &buff[0])
+ {
+ q = xmalloc (buffer_length);
+ memcpy (q, buff, bytes_used);
+ }
+ else
+ q = xrealloc (q, buffer_length);
p = &q[bytes_used];
r = &q[buffer_length];
}
@@ -726,7 +727,7 @@ ffelex_cfelex_ (ffelexToken *xtoken, FILE *finput, int c)
{
bool done = FALSE;
int use_d = 0;
- int d;
+ int d = 0;
switch (c)
{
@@ -759,7 +760,13 @@ ffelex_cfelex_ (ffelexToken *xtoken, FILE *finput, int c)
register unsigned bytes_used = (p - q);
buffer_length = bytes_used * 2;
- q = (char *)xrealloc (q, buffer_length);
+ if (q == &buff[0])
+ {
+ q = xmalloc (buffer_length);
+ memcpy (q, buff, bytes_used);
+ }
+ else
+ q = xrealloc (q, buffer_length);
p = &q[bytes_used];
r = &q[buffer_length];
}
@@ -788,7 +795,7 @@ ffelex_cfelex_ (ffelexToken *xtoken, FILE *finput, int c)
}
static void
-ffelex_file_pop_ (const char *input_filename)
+ffelex_file_pop_ (const char *filename)
{
if (input_file_stack->next)
{
@@ -796,7 +803,7 @@ ffelex_file_pop_ (const char *input_filename)
input_file_stack = p->next;
free (p);
input_file_stack_tick++;
- (*debug_hooks->end_source_file) (input_file_stack->line);
+ (*debug_hooks->end_source_file) (input_file_stack->location.line);
}
else
error ("#-lines for entering and leaving files don't match");
@@ -804,27 +811,26 @@ ffelex_file_pop_ (const char *input_filename)
/* Now that we've pushed or popped the input stack,
update the name in the top element. */
if (input_file_stack)
- input_file_stack->name = input_filename;
+ input_file_stack->location.file = filename;
}
static void
-ffelex_file_push_ (int old_lineno, const char *input_filename)
+ffelex_file_push_ (int old_lineno, const char *filename)
{
- struct file_stack *p
- = (struct file_stack *) xmalloc (sizeof (struct file_stack));
+ struct file_stack *p = xmalloc (sizeof (struct file_stack));
- input_file_stack->line = old_lineno;
+ input_file_stack->location.line = old_lineno;
p->next = input_file_stack;
- p->name = input_filename;
+ p->location.file = filename;
input_file_stack = p;
input_file_stack_tick++;
- (*debug_hooks->start_source_file) (0, input_filename);
+ (*debug_hooks->start_source_file) (0, filename);
/* Now that we've pushed or popped the input stack,
update the name in the top element. */
if (input_file_stack)
- input_file_stack->name = input_filename;
+ input_file_stack->location.file = filename;
}
/* Prepare to finish a statement-in-progress by sending the current
@@ -834,7 +840,7 @@ ffelex_file_push_ (int old_lineno, const char *input_filename)
typical fixed-form cases. */
static void
-ffelex_prepare_eos_ ()
+ffelex_prepare_eos_ (void)
{
if (ffelex_token_->type != FFELEX_typeNONE)
{
@@ -883,7 +889,7 @@ ffelex_prepare_eos_ ()
}
static void
-ffelex_finish_statement_ ()
+ffelex_finish_statement_ (void)
{
if ((ffelex_number_of_tokens_ == 0)
&& (ffelex_token_->type == FFELEX_typeNONE))
@@ -928,7 +934,7 @@ ffelex_get_directive_line_ (char **text, FILE *finput)
if (buffer_length == 0)
{
- directive_buffer = (char *)xmalloc (128);
+ directive_buffer = xmalloc (128);
buffer_length = 128;
}
@@ -944,8 +950,7 @@ ffelex_get_directive_line_ (char **text, FILE *finput)
register unsigned bytes_used = (p - directive_buffer);
buffer_length *= 2;
- directive_buffer
- = (char *)xrealloc (directive_buffer, buffer_length);
+ directive_buffer = xrealloc (directive_buffer, buffer_length);
p = &directive_buffer[bytes_used];
buffer_limit = &directive_buffer[buffer_length];
}
@@ -997,22 +1002,6 @@ ffelex_get_directive_line_ (char **text, FILE *finput)
Returns the next character unhandled, which is always newline or EOF. */
-#if defined HANDLE_PRAGMA
-/* Local versions of these macros, that can be passed as function pointers. */
-static int
-pragma_getc ()
-{
- return getc (finput);
-}
-
-static void
-pragma_ungetc (arg)
- int arg;
-{
- ungetc (arg, finput);
-}
-#endif /* HANDLE_PRAGMA */
-
static int
ffelex_hash_ (FILE *finput)
{
@@ -1041,46 +1030,9 @@ ffelex_hash_ (FILE *finput)
&& ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'
|| c == EOF))
{
-#if 0 /* g77 doesn't handle pragmas, so ignores them FOR NOW. */
- static char buffer [128];
- char * buff = buffer;
-
- /* Read the pragma name into a buffer.
- ISSPACE() may evaluate its argument more than once! */
- while (((c = getc (finput)), ISSPACE(c)))
- continue;
-
- do
- {
- * buff ++ = c;
- c = getc (finput);
- }
- while (c != EOF && ! ISSPACE (c) && c != '\n'
- && buff < buffer + 128);
-
- pragma_ungetc (c);
-
- * -- buff = 0;
-#ifdef HANDLE_PRAGMA
- if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, buffer))
- goto skipline;
-#endif /* HANDLE_PRAGMA */
-#ifdef HANDLE_GENERIC_PRAGMAS
- if (handle_generic_pragma (buffer))
- goto skipline;
-#endif /* !HANDLE_GENERIC_PRAGMAS */
-
- /* Issue a warning message if we have been asked to do so.
- Ignoring unknown pragmas in system header file unless
- an explcit -Wunknown-pragmas has been given. */
- if (warn_unknown_pragmas > 1
- || (warn_unknown_pragmas && ! in_system_header))
- warning ("ignoring pragma: %s", token_buffer);
-#endif /* 0 */
goto skipline;
}
}
-
else if (c == 'd')
{
if (getc (finput) == 'e'
@@ -1096,7 +1048,7 @@ ffelex_hash_ (FILE *finput)
c = ffelex_get_directive_line_ (&text, finput);
if (debug_info_level == DINFO_LEVEL_VERBOSE)
- (*debug_hooks->define) (lineno, text);
+ (*debug_hooks->define) (input_line, text);
goto skipline;
}
@@ -1115,7 +1067,7 @@ ffelex_hash_ (FILE *finput)
c = ffelex_get_directive_line_ (&text, finput);
if (debug_info_level == DINFO_LEVEL_VERBOSE)
- (*debug_hooks->undef) (lineno, text);
+ (*debug_hooks->undef) (input_line, text);
goto skipline;
}
@@ -1193,8 +1145,7 @@ ffelex_hash_ (FILE *finput)
if ((token != NULL)
&& (ffelex_token_type (token) == FFELEX_typeNUMBER))
{
- int old_lineno = lineno;
- const char *old_input_filename = input_filename;
+ location_t old_loc = input_location;
ffewhereFile wf;
/* subtract one, because it is the following line that
@@ -1207,7 +1158,7 @@ ffelex_hash_ (FILE *finput)
if (c == '\n' || c == EOF)
{
/* No more: store the line number and check following line. */
- lineno = l;
+ input_line = l;
if (!ffelex_kludge_flag_)
{
ffewhere_file_set (NULL, TRUE, (ffewhereLineNumber) l);
@@ -1230,7 +1181,7 @@ ffelex_hash_ (FILE *finput)
goto skipline;
}
- lineno = l;
+ input_line = l;
if (ffelex_kludge_flag_)
input_filename = ggc_strdup (ffelex_token_text (token));
@@ -1260,7 +1211,7 @@ ffelex_hash_ (FILE *finput)
{
/* Update the name in the top element of input_file_stack. */
if (input_file_stack)
- input_file_stack->name = input_filename;
+ input_file_stack->location.file = input_filename;
if (token != NULL)
ffelex_token_kill (token);
@@ -1280,15 +1231,15 @@ ffelex_hash_ (FILE *finput)
if (ffelex_kludge_flag_)
{
- lineno = 1;
- input_filename = old_input_filename;
+ input_line = 1;
+ input_filename = old_loc.file;
error ("use `#line ...' instead of `# ...' in first line");
}
if (num == 1)
{
/* Pushing to a new file. */
- ffelex_file_push_ (old_lineno, input_filename);
+ ffelex_file_push_ (old_loc.line, input_filename);
}
else if (num == 2)
{
@@ -1324,8 +1275,8 @@ ffelex_hash_ (FILE *finput)
|| (c != '\n' && c != EOF))
&& ffelex_kludge_flag_)
{
- lineno = 1;
- input_filename = old_input_filename;
+ input_line = 1;
+ input_filename = old_loc.file;
error ("use `#line ...' instead of `# ...' in first line");
}
if (c == '\n' || c == EOF)
@@ -1452,7 +1403,7 @@ ffelex_image_char_ (int c, ffewhereColumnNumber column)
}
static void
-ffelex_include_ ()
+ffelex_include_ (void)
{
ffewhereFile include_wherefile = ffelex_include_wherefile_;
FILE *include_file = ffelex_include_file_;
@@ -1470,8 +1421,7 @@ ffelex_include_ ()
ffewhereLineNumber linecount_current = ffelex_linecount_current_;
ffewhereLineNumber linecount_offset
= ffewhere_line_filelinenum (current_wl);
- int old_lineno = lineno;
- const char *old_input_filename = input_filename;
+ location_t old_loc = input_location;
if (card_length != 0)
{
@@ -1489,7 +1439,7 @@ ffelex_include_ ()
ffewhere_file_set (include_wherefile, TRUE, 0);
- ffelex_file_push_ (old_lineno, ffewhere_file_name (include_wherefile));
+ ffelex_file_push_ (old_loc.line, ffewhere_file_name (include_wherefile));
if (ffelex_include_free_form_)
ffelex_file_free (include_wherefile, include_file);
@@ -1504,16 +1454,12 @@ ffelex_include_ ()
if (card_length != 0)
{
-#ifdef REDUCE_CARD_SIZE_AFTER_BIGGY /* Define if occasional large lines. */
-#error "need to handle possible reduction of card size here!!"
-#endif
assert (ffelex_card_size_ >= card_length); /* It shrunk?? */
memcpy (ffelex_card_image_, card_image, card_length);
}
ffelex_card_image_[card_length] = '\0';
- input_filename = old_input_filename;
- lineno = old_lineno;
+ input_location = old_loc;
ffelex_linecount_current_ = linecount_current;
ffelex_current_wf_ = current_wf;
ffelex_final_nontab_column_ = final_nontab_column;
@@ -1567,15 +1513,15 @@ ffelex_is_free_nonc_ctx_contin_ (ffewhereColumnNumber col)
}
static void
-ffelex_next_line_ ()
+ffelex_next_line_ (void)
{
ffelex_linecount_current_ = ffelex_linecount_next_;
++ffelex_linecount_next_;
- ++lineno;
+ ++input_line;
}
static void
-ffelex_send_token_ ()
+ffelex_send_token_ (void)
{
++ffelex_number_of_tokens_;
@@ -1649,14 +1595,13 @@ ffelex_swallow_tokens_ (ffelexToken t)
}
static ffelexToken
-ffelex_token_new_ ()
+ffelex_token_new_ (void)
{
ffelexToken t;
++ffelex_total_tokens_;
- t = (ffelexToken) malloc_new_ks (malloc_pool_image (),
- "FFELEX token", sizeof (*t));
+ t = malloc_new_ks (malloc_pool_image (), "FFELEX token", sizeof (*t));
t->id_ = ffelex_token_nextid_++;
return t;
}
@@ -1747,7 +1692,7 @@ ffelex_display_token (ffelexToken t)
return FALSE. */
bool
-ffelex_expecting_character ()
+ffelex_expecting_character (void)
{
return (ffelex_raw_mode_ != 0);
}
@@ -1787,7 +1732,7 @@ ffelex_file_fixed (ffewhereFile wf, FILE *f)
assert (ffelex_handler_ != NULL);
- lineno = 0;
+ input_line = 0;
input_filename = ffewhere_file_name (wf);
ffelex_current_wf_ = wf;
disallow_continuation_line = TRUE;
@@ -1811,18 +1756,6 @@ ffelex_file_fixed (ffewhereFile wf, FILE *f)
beginning_of_line_again: /* :::::::::::::::::::: */
-#ifdef REDUCE_CARD_SIZE_AFTER_BIGGY /* Define if occasional large lines. */
- if (ffelex_card_size_ != FFELEX_columnINITIAL_SIZE_)
- {
- ffelex_card_image_
- = malloc_resize_ks (malloc_pool_image (),
- ffelex_card_image_,
- FFELEX_columnINITIAL_SIZE_ + 9,
- ffelex_card_size_ + 9);
- ffelex_card_size_ = FFELEX_columnINITIAL_SIZE_;
- }
-#endif
-
first_line: /* :::::::::::::::::::: */
c = latest_char_in_file;
@@ -2977,7 +2910,7 @@ ffelex_file_free (ffewhereFile wf, FILE *f)
assert (ffelex_handler_ != NULL);
- lineno = 0;
+ input_line = 0;
input_filename = ffewhere_file_name (wf);
ffelex_current_wf_ = wf;
continuation_line = FALSE;
@@ -3896,7 +3829,7 @@ ffelex_hash_kludge (FILE *finput)
}
void
-ffelex_init_1 ()
+ffelex_init_1 (void)
{
unsigned int i;
@@ -3977,7 +3910,7 @@ ffelex_init_1 ()
Must be called while lexer is active, obviously. */
bool
-ffelex_is_names_expected ()
+ffelex_is_names_expected (void)
{
return ffelex_names_;
}
@@ -3986,7 +3919,7 @@ ffelex_is_names_expected ()
ffelex_linecount_current_. */
char *
-ffelex_line ()
+ffelex_line (void)
{
return ffelex_card_image_;
}
@@ -3998,7 +3931,7 @@ ffelex_line ()
Must be called while lexer is active, obviously. */
ffewhereColumnNumber
-ffelex_line_length ()
+ffelex_line_length (void)
{
return ffelex_card_length_;
}
@@ -4007,7 +3940,7 @@ ffelex_line_length ()
is current. */
ffewhereLineNumber
-ffelex_line_number ()
+ffelex_line_number (void)
{
return ffelex_linecount_current_;
}
@@ -4442,7 +4375,7 @@ ffelex_token_new_character (const char *s, ffewhereLine l, ffewhereColumn c)
/* Make a new EOF token right after end of file. */
ffelexToken
-ffelex_token_new_eof ()
+ffelex_token_new_eof (void)
{
ffelexToken t;
diff --git a/contrib/gcc/f/malloc.c b/contrib/gcc/f/malloc.c
index 77e2e4a12e2d..8c85511342cb 100644
--- a/contrib/gcc/f/malloc.c
+++ b/contrib/gcc/f/malloc.c
@@ -1,5 +1,5 @@
/* malloc.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -101,13 +101,14 @@ malloc_kill_area_ (mallocPool pool UNUSED, mallocArea_ a)
#if MALLOC_DEBUG
assert (strcmp (a->name, ((char *) (a->where)) + a->size) == 0);
#endif
- malloc_kill_ (a->where, a->size);
+ malloc_kill_ (a->where - sizeof(mallocArea_*), a->size);
a->next->previous = a->previous;
a->previous->next = a->next;
#if MALLOC_DEBUG
pool->freed += a->size;
pool->frees++;
#endif
+
malloc_kill_ (a,
offsetof (struct _malloc_area_, name)
+ strlen (a->name) + 1);
@@ -136,7 +137,7 @@ malloc_verify_area_ (mallocPool pool UNUSED, mallocArea_ a UNUSED)
Call malloc_init before you do anything else. */
void
-malloc_init ()
+malloc_init (void)
{
if (malloc_reserve_ != NULL)
return;
@@ -303,21 +304,9 @@ malloc_display_ (mallocArea_ a UNUSED)
mallocArea_
malloc_find_inpool_ (mallocPool pool, void *ptr)
{
- mallocArea_ a;
- mallocArea_ b = (mallocArea_) &pool->first;
- int n = 0;
-
- for (a = pool->first; a != (mallocArea_) &pool->first; a = a->next)
- {
- assert (("Infinite loop detected" != NULL) && (a != b));
- if (a->where == ptr)
- return a;
- ++n;
- if (n & 1)
- b = b->next;
- }
- assert ("Couldn't find object in pool!" == NULL);
- return NULL;
+ mallocArea_ *t;
+ t = (mallocArea_ *) (ptr - sizeof(mallocArea_));
+ return *t;
}
/* malloc_kill_inpool_ -- Kill object
@@ -388,6 +377,7 @@ malloc_new_inpool_ (mallocPool pool, mallocType_ type, const char *name, mallocS
void *ptr;
mallocArea_ a;
unsigned short i;
+ mallocArea_ *temp;
if (pool == NULL)
pool = malloc_pool_image ();
@@ -397,11 +387,14 @@ malloc_new_inpool_ (mallocPool pool, mallocType_ type, const char *name, mallocS
|| malloc_pool_find_ (pool, malloc_pool_image ()));
#endif
- ptr = malloc_new_ (s + (i = (MALLOC_DEBUG ? strlen (name) + 1 : 0)));
+ ptr = malloc_new_ (sizeof(mallocArea_*) + s + (i = (MALLOC_DEBUG ? strlen (name) + 1 : 0)));
#if MALLOC_DEBUG
strcpy (((char *) (ptr)) + s, name);
#endif
a = malloc_new_ (offsetof (struct _malloc_area_, name) + i);
+ temp = (mallocArea_ *) ptr;
+ *temp = a;
+ ptr = ptr + sizeof(mallocArea_*);
switch (type)
{ /* A little optimization to speed up killing
of non-permanent stuff. */
@@ -477,6 +470,7 @@ malloc_resize_inpool_ (mallocPool pool, mallocType_ type UNUSED,
void *ptr, mallocSize ns, mallocSize os UNUSED)
{
mallocArea_ a;
+ mallocArea_ *temp;
if (pool == NULL)
pool = malloc_pool_image ();
@@ -493,7 +487,10 @@ malloc_resize_inpool_ (mallocPool pool, mallocType_ type UNUSED,
assert (a->size == os);
assert (strcmp (a->name, ((char *) (ptr)) + os) == 0);
#endif
- ptr = malloc_resize_ (ptr, ns + (MALLOC_DEBUG ? strlen (a->name) + 1: 0));
+ ptr = malloc_resize_ (ptr - sizeof(mallocArea_*), sizeof(mallocArea_*) + ns + (MALLOC_DEBUG ? strlen (a->name) + 1: 0));
+ temp = (mallocArea_ *) ptr;
+ *temp = a;
+ ptr = ptr + sizeof(mallocArea_*);
a->where = ptr;
#if MALLOC_DEBUG
a->size = ns;
diff --git a/contrib/gcc/f/name.c b/contrib/gcc/f/name.c
index 360279b3151a..26f713ef32b9 100644
--- a/contrib/gcc/f/name.c
+++ b/contrib/gcc/f/name.c
@@ -105,7 +105,7 @@ ffename_find (ffenameSpace ns, ffelexToken t)
if (found)
return n;
- newn = (ffename) malloc_new_ks (ns->pool, "FFENAME name", sizeof (*n));
+ newn = malloc_new_ks (ns->pool, "FFENAME name", sizeof (*n));
newn->next = n;
newn->previous = n->previous;
n->previous = newn;
@@ -232,8 +232,7 @@ ffename_space_new (mallocPool pool)
{
ffenameSpace ns;
- ns = (ffenameSpace) malloc_new_ks (pool, "FFENAME space",
- sizeof (*ns));
+ ns = malloc_new_ks (pool, "FFENAME space", sizeof (*ns));
ns->first = (ffename) &ns->first;
ns->last = (ffename) &ns->first;
ns->pool = pool;
diff --git a/contrib/gcc/f/news.texi b/contrib/gcc/f/news.texi
index fe6fa80ada24..9b34df021c2b 100644
--- a/contrib/gcc/f/news.texi
+++ b/contrib/gcc/f/news.texi
@@ -1,4 +1,5 @@
-@c Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+@c Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
+@c 2003, 2004
@c Free Software Foundation, Inc.
@c This is part of the G77 manual.
@c For copying conditions, see the file g77.texi.
@@ -8,9 +9,9 @@
@c Keep this the same as the dates above, since it's used
@c in the standalone derivations of this file (e.g. NEWS).
-@set copyrights-news 1995,1996,1997,1998,1999,2000,2001,2002,2003
+@set copyrights-news 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004
-@set last-update-news 2003-05-18
+@set last-update-news 2004-06-17
@ifset DOC-NEWS
@include root.texi
@@ -60,6 +61,9 @@ such changes to @command{g77}.
@end ifset
@ifclear USERVISONLY
+
+@emph{@code{GCC} 3.4.x is the last edition of @code{GCC} to contain @command{g77} - from @code{GCC} 3.5 onwards, use @command{gfortran}}
+
Changes made to recent versions of GNU Fortran are listed
below, with the most recent version first.
@@ -142,16 +146,26 @@ That's due to attempts to keep this development version
of news about previous @command{g77} versions up-to-date.
@end ifset
-@ifclear USERVISONLY
-An online, ``live'' version of this document
-(derived directly from the mainline, development version
-of @command{g77} within @command{gcc})
-is available at
-@uref{http://gcc.gnu.org/onlinedocs/g77/News.html}.
-@end ifclear
-
The following information was last updated on @value{last-update-news}:
+@heading In @code{GCC} 3.4 versus @code{GCC} 3.3:
+@itemize @bullet
+@item
+Problem Reports fixed (in chronological order of submission):
+@table @code
+@item 8485
+g77 doesn't accept INTEGER*8 constant in PARAMETER multiplication.
+@item 11918
+(libf2c) isatty does not call f_init.
+@item 12317
+Incorrect documentation for Fortran debugging features.
+@end table
+@item
+Roger Sayle (@email{roger@@eyesopen.com}) fixed the remaining
+problems with regard to the support of INTEGER*8, INTEGER*2 and INTEGER*1
+as a fallout of fixing PR 8485.
+@end itemize
+
@heading In @code{GCC} 3.3 versus @code{GCC} 3.2:
@itemize @bullet
@item
diff --git a/contrib/gcc/f/parse.c b/contrib/gcc/f/parse.c
index 106ff3f60cc0..d822773f35be 100644
--- a/contrib/gcc/f/parse.c
+++ b/contrib/gcc/f/parse.c
@@ -29,9 +29,9 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
extern FILE *finput;
void
-ffe_parse_file (set_yydebug)
- int set_yydebug ATTRIBUTE_UNUSED;
+ffe_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
{
+ const char *fname;
ffewhereFile wf;
if (ffe_is_version ())
@@ -40,8 +40,9 @@ ffe_parse_file (set_yydebug)
if (!ffe_is_pedantic ())
ffe_set_is_pedantic (pedantic);
- wf = ffewhere_file_new (main_input_filename, strlen (main_input_filename));
- ffecom_file (main_input_filename);
+ fname = main_input_filename ? main_input_filename : "<stdin>";
+ wf = ffewhere_file_new (fname, strlen (fname));
+ ffecom_file (fname);
ffe_file (wf, finput);
ffecom_finish_compile ();
diff --git a/contrib/gcc/f/proj.h b/contrib/gcc/f/proj.h
index 8cf54c96a0d7..0896bdf32c07 100644
--- a/contrib/gcc/f/proj.h
+++ b/contrib/gcc/f/proj.h
@@ -24,12 +24,14 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_F_PROJ_H
#define GCC_F_PROJ_H
-#ifdef USE_HCONFIG
-#include "hconfig.h"
+#ifdef USE_BCONFIG
+#include "bconfig.h"
#else
#include "config.h"
#endif
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#if (GCC_VERSION < 2000)
#error "You have to use gcc 2.x to build g77."
diff --git a/contrib/gcc/f/root.texi b/contrib/gcc/f/root.texi
index d8619cc376d7..1956abca3c3e 100644
--- a/contrib/gcc/f/root.texi
+++ b/contrib/gcc/f/root.texi
@@ -11,4 +11,4 @@
@set which-gcc GCC
@set email-burley craig@@jcb-sc.com
-@set www-burley http://world.std.com/%7Eburley
+@set www-burley http://world.std.com/%7Eburley/
diff --git a/contrib/gcc/f/src.c b/contrib/gcc/f/src.c
index 28c55cccf4fc..54fc7773fef9 100644
--- a/contrib/gcc/f/src.c
+++ b/contrib/gcc/f/src.c
@@ -1,5 +1,5 @@
/* src.c -- Implementation File
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -93,7 +93,7 @@ bool ffesrc_ok_match_noninit_lower_;
/* Initialize table of alphabetic matches. */
void
-ffesrc_init_1 ()
+ffesrc_init_1 (void)
{
int i;
diff --git a/contrib/gcc/f/st.c b/contrib/gcc/f/st.c
index 8f27f89fbfd3..cdfdfb596a89 100644
--- a/contrib/gcc/f/st.c
+++ b/contrib/gcc/f/st.c
@@ -1,5 +1,5 @@
/* st.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -141,7 +141,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
yet been set. */
void
-ffest_confirmed ()
+ffest_confirmed (void)
{
ffesta_confirmed ();
}
@@ -160,7 +160,7 @@ ffest_confirmed ()
processing a statement (make and destroy pools, et cetera). */
void
-ffest_eof ()
+ffest_eof (void)
{
ffesta_eof ();
}
@@ -242,7 +242,7 @@ ffest_first (ffelexToken t)
this list. Initializes the executable and nonexecutable lists. */
void
-ffest_init_0 ()
+ffest_init_0 (void)
{
ffesta_init_0 ();
ffestb_init_0 ();
@@ -271,7 +271,7 @@ ffest_init_0 ()
this list. Initializes the executable and nonexecutable lists. */
void
-ffest_init_1 ()
+ffest_init_1 (void)
{
ffesta_init_1 ();
ffestb_init_1 ();
@@ -300,7 +300,7 @@ ffest_init_1 ()
this list. Initializes the executable and nonexecutable lists. */
void
-ffest_init_2 ()
+ffest_init_2 (void)
{
ffesta_init_2 ();
ffestb_init_2 ();
@@ -321,7 +321,7 @@ ffest_init_2 ()
ffest_init_3(); */
void
-ffest_init_3 ()
+ffest_init_3 (void)
{
ffesta_init_3 ();
ffestb_init_3 ();
@@ -344,7 +344,7 @@ ffest_init_3 ()
ffest_init_4(); */
void
-ffest_init_4 ()
+ffest_init_4 (void)
{
ffesta_init_4 ();
ffestb_init_4 ();
@@ -366,7 +366,7 @@ ffest_init_4 ()
Else returns FALSE. */
bool
-ffest_is_entry_valid ()
+ffest_is_entry_valid (void)
{
return ffesta_is_entry_valid;
}
@@ -396,7 +396,7 @@ ffest_is_entry_valid ()
the ffestb call would be completely dropped without this mechanism. */
bool
-ffest_is_inhibited ()
+ffest_is_inhibited (void)
{
return ffesta_is_inhibited ();
}
@@ -412,7 +412,7 @@ ffest_is_inhibited ()
is being run. */
bool
-ffest_seen_first_exec ()
+ffest_seen_first_exec (void)
{
return ffesta_seen_first_exec;
}
@@ -421,7 +421,7 @@ ffest_seen_first_exec ()
user with a diagnostic if we're not inhibited. */
void
-ffest_shutdown ()
+ffest_shutdown (void)
{
ffesta_shutdown ();
}
@@ -453,7 +453,7 @@ ffest_sym_exec_transition (ffesymbol s)
ffest_terminate_0(); */
void
-ffest_terminate_0 ()
+ffest_terminate_0 (void)
{
ffesta_terminate_0 ();
ffestb_terminate_0 ();
@@ -474,7 +474,7 @@ ffest_terminate_0 ()
ffest_terminate_1(); */
void
-ffest_terminate_1 ()
+ffest_terminate_1 (void)
{
ffesta_terminate_1 ();
ffestb_terminate_1 ();
@@ -495,7 +495,7 @@ ffest_terminate_1 ()
ffest_terminate_2(); */
void
-ffest_terminate_2 ()
+ffest_terminate_2 (void)
{
ffesta_terminate_2 ();
ffestb_terminate_2 ();
@@ -516,7 +516,7 @@ ffest_terminate_2 ()
ffest_terminate_3(); */
void
-ffest_terminate_3 ()
+ffest_terminate_3 (void)
{
ffesta_terminate_3 ();
ffestb_terminate_3 ();
@@ -537,7 +537,7 @@ ffest_terminate_3 ()
ffest_terminate_4(); */
void
-ffest_terminate_4 ()
+ffest_terminate_4 (void)
{
ffesta_terminate_4 ();
ffestb_terminate_4 ();
diff --git a/contrib/gcc/f/sta.c b/contrib/gcc/f/sta.c
index 0b4c11aa9efd..ee75fa88f608 100644
--- a/contrib/gcc/f/sta.c
+++ b/contrib/gcc/f/sta.c
@@ -1,5 +1,5 @@
/* sta.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -183,7 +183,7 @@ ffesta_add_possible_ (ffelexHandler fn, bool exec, bool named)
invocation of ffestc_exec_transition. */
static bool
-ffesta_inhibited_exec_transition_ ()
+ffesta_inhibited_exec_transition_ (void)
{
bool result;
@@ -208,7 +208,7 @@ ffesta_inhibited_exec_transition_ ()
Clears the lists of executable and nonexecutable statements. */
static void
-ffesta_reset_possibles_ ()
+ffesta_reset_possibles_ (void)
{
ffesta_num_possibles_ = 0;
@@ -247,9 +247,8 @@ ffesta_save_ (ffelexToken t)
if (saved_tokens == NULL)
{
saved_tokens
- = (ffelexToken *) malloc_new_ksr (malloc_pool_image (),
- "FFEST Saved Tokens",
- (max_saved_tokens = 8) * sizeof (ffelexToken));
+ = malloc_new_ksr (malloc_pool_image (), "FFEST Saved Tokens",
+ (max_saved_tokens = 8) * sizeof (ffelexToken));
/* Start off with 8. */
}
else if (num_saved_tokens >= max_saved_tokens)
@@ -258,10 +257,9 @@ ffesta_save_ (ffelexToken t)
max_saved_tokens <<= 1; /* Multiply by two. */
assert (max_saved_tokens > toknum);
saved_tokens
- = (ffelexToken *) malloc_resize_ksr (malloc_pool_image (),
- saved_tokens,
- max_saved_tokens * sizeof (ffelexToken),
- toknum * sizeof (ffelexToken));
+ = malloc_resize_ksr (malloc_pool_image (), saved_tokens,
+ max_saved_tokens * sizeof (ffelexToken),
+ toknum * sizeof (ffelexToken));
}
*(saved_tokens + num_saved_tokens++) = ffelex_token_use (t);
@@ -337,7 +335,7 @@ ffesta_save_ (ffelexToken t)
{ /* No handler in this list, try exec list if
not tried yet. */
if (ffesta_current_possible_
- == (ffestaPossible_) &ffesta_possible_nonexecs_)
+ == (ffestaPossible_) &ffesta_possible_nonexecs_.first)
{
ffesta_current_possible_ = ffesta_possible_execs_.first;
ffesta_current_handler_ = ffesta_current_possible_->handler;
@@ -381,7 +379,7 @@ ffesta_save_ (ffelexToken t)
{
if (possible->handler == NULL)
{
- if (possible == (ffestaPossible_) &ffesta_possible_nonexecs_)
+ if (possible == (ffestaPossible_) &ffesta_possible_nonexecs_.first)
{
possible = first_exec = ffesta_possible_execs_.first;
continue;
@@ -592,29 +590,6 @@ ffesta_second_ (ffelexToken t)
switch (ffesta_first_kw)
{
-#if FFESTR_VXT
- case FFESTR_firstACCEPT:
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V019);
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstALLOCATABLE:
- ffestb_args.dimlist.len = FFESTR_firstlALLOCATABLE;
- ffestb_args.dimlist.badname = "ALLOCATABLE";
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dimlist);
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstALLOCATE:
- ffestb_args.heap.len = FFESTR_firstlALLOCATE;
- ffestb_args.heap.badname = "ALLOCATE";
- ffestb_args.heap.ctx = FFEEXPR_contextALLOCATE;
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_heap);
- break;
-#endif
-
case FFESTR_firstASSIGN:
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R838);
break;
@@ -666,12 +641,6 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype);
break;
-#if FFESTR_F90
- case FFESTR_firstCONTAINS:
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1228);
- break;
-#endif
-
case FFESTR_firstCONTINUE:
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R841);
break;
@@ -687,32 +656,6 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R528);
break;
-#if FFESTR_F90
- case FFESTR_firstDEALLOCATE:
- ffestb_args.heap.len = FFESTR_firstlDEALLOCATE;
- ffestb_args.heap.badname = "DEALLOCATE";
- ffestb_args.heap.ctx = FFEEXPR_contextDEALLOCATE;
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_heap);
- break;
-#endif
-
-#if FFESTR_VXT
- case FFESTR_firstDECODE:
- ffestb_args.vxtcode.len = FFESTR_firstlDECODE;
- ffestb_args.vxtcode.badname = "DECODE";
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_vxtcode);
- break;
-#endif
-
-#if FFESTR_VXT
- case FFESTR_firstDEFINEFILE:
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V025);
- break;
-
- case FFESTR_firstDELETE:
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V021);
- break;
-#endif
case FFESTR_firstDIMENSION:
ffestb_args.R524.len = FFESTR_firstlDIMENSION;
ffestb_args.R524.badname = "DIMENSION";
@@ -752,21 +695,6 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_elsexyz);
break;
-#if FFESTR_F90
- case FFESTR_firstELSEWHERE:
- ffestb_args.elsexyz.second = FFESTR_secondWHERE;
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_elsexyz);
- break;
-#endif
-
-#if FFESTR_VXT
- case FFESTR_firstENCODE:
- ffestb_args.vxtcode.len = FFESTR_firstlENCODE;
- ffestb_args.vxtcode.badname = "ENCODE";
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_vxtcode);
- break;
-#endif
-
case FFESTR_firstEND:
if ((ffelex_token_type (ffesta_token_0_) == FFELEX_typeNAMES)
|| (ffelex_token_type (t) != FFELEX_typeNAME))
@@ -781,15 +709,9 @@ ffesta_second_ (ffelexToken t)
case FFESTR_secondFILE:
case FFESTR_secondFUNCTION:
case FFESTR_secondIF:
-#if FFESTR_F90
- case FFESTR_secondMODULE:
-#endif
case FFESTR_secondPROGRAM:
case FFESTR_secondSELECT:
case FFESTR_secondSUBROUTINE:
-#if FFESTR_F90
- case FFESTR_secondWHERE:
-#endif
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_end);
break;
@@ -836,30 +758,6 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
break;
-#if FFESTR_F90
- case FFESTR_firstENDINTERFACE:
- ffestb_args.endxyz.len = FFESTR_firstlENDINTERFACE;
- ffestb_args.endxyz.second = FFESTR_secondINTERFACE;
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_endxyz);
- break;
-#endif
-
-#if FFESTR_VXT
- case FFESTR_firstENDMAP:
- ffestb_args.endxyz.len = FFESTR_firstlENDMAP;
- ffestb_args.endxyz.second = FFESTR_secondMAP;
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_endxyz);
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstENDMODULE:
- ffestb_args.endxyz.len = FFESTR_firstlENDMODULE;
- ffestb_args.endxyz.second = FFESTR_secondMODULE;
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
- break;
-#endif
-
case FFESTR_firstENDPROGRAM:
ffestb_args.endxyz.len = FFESTR_firstlENDPROGRAM;
ffestb_args.endxyz.second = FFESTR_secondPROGRAM;
@@ -872,44 +770,12 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
break;
-#if FFESTR_VXT
- case FFESTR_firstENDSTRUCTURE:
- ffestb_args.endxyz.len = FFESTR_firstlENDSTRUCTURE;
- ffestb_args.endxyz.second = FFESTR_secondSTRUCTURE;
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_endxyz);
- break;
-#endif
-
case FFESTR_firstENDSUBROUTINE:
ffestb_args.endxyz.len = FFESTR_firstlENDSUBROUTINE;
ffestb_args.endxyz.second = FFESTR_secondSUBROUTINE;
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
break;
-#if FFESTR_F90
- case FFESTR_firstENDTYPE:
- ffestb_args.endxyz.len = FFESTR_firstlENDTYPE;
- ffestb_args.endxyz.second = FFESTR_secondTYPE;
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_endxyz);
- break;
-#endif
-
-#if FFESTR_VXT
- case FFESTR_firstENDUNION:
- ffestb_args.endxyz.len = FFESTR_firstlENDUNION;
- ffestb_args.endxyz.second = FFESTR_secondUNION;
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_endxyz);
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstENDWHERE:
- ffestb_args.endxyz.len = FFESTR_firstlENDWHERE;
- ffestb_args.endxyz.second = FFESTR_secondWHERE;
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz);
- break;
-#endif
-
case FFESTR_firstENTRY:
ffestb_args.dummy.len = FFESTR_firstlENTRY;
ffestb_args.dummy.badname = "ENTRY";
@@ -931,12 +797,6 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist);
break;
-#if FFESTR_VXT
- case FFESTR_firstFIND:
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V026);
- break;
-#endif
-
/* WARNING: don't put anything that might cause an item to precede
FORMAT in the list of possible statements (it's added below) without
making sure FORMAT still is first. It has to run with
@@ -954,6 +814,22 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dummy);
break;
+ case FFESTR_firstGO:
+ if ((ffelex_token_type (ffesta_token_0_) == FFELEX_typeNAMES)
+ || (ffelex_token_type (t) != FFELEX_typeNAME))
+ ffesta_add_possible_exec_ ((ffelexHandler) ffestb_goto);
+ else
+ switch (ffesta_second_kw)
+ {
+ case FFESTR_secondTO:
+ ffesta_add_possible_exec_ ((ffelexHandler) ffestb_goto);
+ break;
+ default:
+ ffesta_add_possible_exec_ ((ffelexHandler) ffestb_goto);
+ break;
+ }
+ break;
+
case FFESTR_firstGOTO:
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_goto);
break;
@@ -992,20 +868,6 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype);
break;
-#if FFESTR_F90
- case FFESTR_firstINTENT:
- ffestb_args.varlist.len = FFESTR_firstlINTENT;
- ffestb_args.varlist.badname = "INTENT";
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist);
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstINTERFACE:
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1202);
- break;
-#endif
-
case FFESTR_firstINTRINSIC:
ffestb_args.varlist.len = FFESTR_firstlINTRINSIC;
ffestb_args.varlist.badname = "INTRINSIC";
@@ -1018,40 +880,14 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype);
break;
-#if FFESTR_VXT
- case FFESTR_firstMAP:
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V012);
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstMODULE:
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_module);
- break;
-#endif
-
case FFESTR_firstNAMELIST:
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R542);
break;
-#if FFESTR_F90
- case FFESTR_firstNULLIFY:
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R624);
- break;
-#endif
-
case FFESTR_firstOPEN:
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R904);
break;
-#if FFESTR_F90
- case FFESTR_firstOPTIONAL:
- ffestb_args.varlist.len = FFESTR_firstlOPTIONAL;
- ffestb_args.varlist.badname = "OPTIONAL";
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist);
- break;
-#endif
-
case FFESTR_firstPARAMETER:
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R537);
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V027);
@@ -1062,38 +898,14 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_halt);
break;
-#if FFESTR_F90
- case FFESTR_firstPOINTER:
- ffestb_args.dimlist.len = FFESTR_firstlPOINTER;
- ffestb_args.dimlist.badname = "POINTER";
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dimlist);
- break;
-#endif
-
case FFESTR_firstPRINT:
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R911);
break;
-#if HARD_F90
- case FFESTR_firstPRIVATE:
- ffestb_args.varlist.len = FFESTR_firstlPRIVATE;
- ffestb_args.varlist.badname = "ACCESS";
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist);
- break;
-#endif
-
case FFESTR_firstPROGRAM:
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1102);
break;
-#if HARD_F90
- case FFESTR_firstPUBLIC:
- ffestb_args.varlist.len = FFESTR_firstlPUBLIC;
- ffestb_args.varlist.badname = "ACCESS";
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist);
- break;
-#endif
-
case FFESTR_firstREAD:
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R909);
break;
@@ -1104,18 +916,6 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype);
break;
-#if FFESTR_VXT
- case FFESTR_firstRECORD:
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V016);
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstRECURSIVE:
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_recursive);
- break;
-#endif
-
case FFESTR_firstRETURN:
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1227);
break;
@@ -1126,12 +926,6 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_beru);
break;
-#if FFESTR_VXT
- case FFESTR_firstREWRITE:
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V018);
- break;
-#endif
-
case FFESTR_firstSAVE:
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R522);
break;
@@ -1144,23 +938,11 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R809);
break;
-#if HARD_F90
- case FFESTR_firstSEQUENCE:
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R423B);
- break;
-#endif
-
case FFESTR_firstSTOP:
ffestb_args.halt.len = FFESTR_firstlSTOP;
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_halt);
break;
-#if FFESTR_VXT
- case FFESTR_firstSTRUCTURE:
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V003);
- break;
-#endif
-
case FFESTR_firstSUBROUTINE:
ffestb_args.dummy.len = FFESTR_firstlSUBROUTINE;
ffestb_args.dummy.badname = "SUBROUTINE";
@@ -1168,50 +950,10 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dummy);
break;
-#if FFESTR_F90
- case FFESTR_firstTARGET:
- ffestb_args.dimlist.len = FFESTR_firstlTARGET;
- ffestb_args.dimlist.badname = "TARGET";
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dimlist);
- break;
-#endif
-
case FFESTR_firstTYPE:
ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V020);
break;
-#if FFESTR_F90
- case FFESTR_firstTYPE:
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_type);
- break;
-#endif
-
-#if HARD_F90
- case FFESTR_firstTYPE:
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_typetype);
- break;
-#endif
-
-#if FFESTR_VXT
- case FFESTR_firstUNLOCK:
- ffestb_args.beru.len = FFESTR_firstlUNLOCK;
- ffestb_args.beru.badname = "UNLOCK";
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_beru);
- break;
-#endif
-
-#if FFESTR_VXT
- case FFESTR_firstUNION:
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V009);
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstUSE:
- ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1107);
- break;
-#endif
-
case FFESTR_firstVIRTUAL:
ffestb_args.R524.len = FFESTR_firstlVIRTUAL;
ffestb_args.R524.badname = "VIRTUAL";
@@ -1222,12 +964,6 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V014);
break;
-#if HARD_F90
- case FFESTR_firstWHERE:
- ffesta_add_possible_exec_ ((ffelexHandler) ffestb_where);
- break;
-#endif
-
case FFESTR_firstWORD:
ffestb_args.decl.len = FFESTR_firstlWORD;
ffestb_args.decl.type = FFESTP_typeWORD;
@@ -1274,13 +1010,7 @@ ffesta_second_ (ffelexToken t)
ffesta_add_possible_unnamed_exec_ ((ffelexHandler) ffestb_let);
break;
-#if FFESTR_F90
- case FFELEX_typePERCENT:
-#endif
case FFELEX_typeEQUALS:
-#if FFESTR_F90
- case FFELEX_typePOINTS:
-#endif
ffesta_add_possible_unnamed_exec_ ((ffelexHandler) ffestb_let);
break;
@@ -1391,7 +1121,7 @@ ffesta_send_two_ (ffelexToken t)
yet been set. */
void
-ffesta_confirmed ()
+ffesta_confirmed (void)
{
if (ffesta_inhibit_confirmation_)
return;
@@ -1415,7 +1145,7 @@ ffesta_confirmed ()
processing a statement (make and destroy pools, et cetera). */
void
-ffesta_eof ()
+ffesta_eof (void)
{
ffesta_tokens[0] = ffelex_token_new_eof ();
@@ -1582,15 +1312,13 @@ ffesta_first (ffelexToken t)
this list. Initializes the executable and nonexecutable lists. */
void
-ffesta_init_0 ()
+ffesta_init_0 (void)
{
ffestaPossible_ ptr;
int i;
- ptr = (ffestaPossible_) malloc_new_kp (malloc_pool_image (),
- "FFEST possibles",
- FFESTA_maxPOSSIBLES_
- * sizeof (*ptr));
+ ptr = malloc_new_kp (malloc_pool_image (), "FFEST possibles",
+ FFESTA_maxPOSSIBLES_ * sizeof (*ptr));
for (i = 0; i < FFESTA_maxPOSSIBLES_; ++i)
ffesta_possibles_[i] = ptr++;
@@ -1607,7 +1335,7 @@ ffesta_init_0 ()
ffesta_init_3(); */
void
-ffesta_init_3 ()
+ffesta_init_3 (void)
{
ffesta_output_pool = NULL; /* May be doing this just before reaching */
ffesta_scratch_pool = NULL; /* ffesta_zero or ffesta_two. */
@@ -1644,7 +1372,7 @@ ffesta_init_3 ()
the ffestb call would be completely dropped without this mechanism. */
bool
-ffesta_is_inhibited ()
+ffesta_is_inhibited (void)
{
assert (ffesta_confirmed_current_ || ffesta_inhibit_confirmation_);
return ffesta_is_inhibited_;
@@ -1793,7 +1521,7 @@ ffesta_ffebad_2t (ffebad errnum, ffelexToken t1, ffelexToken t2)
}
ffestaPooldisp
-ffesta_outpooldisp ()
+ffesta_outpooldisp (void)
{
return ffesta_outpooldisp_;
}
@@ -1808,7 +1536,7 @@ ffesta_set_outpooldisp (ffestaPooldisp d)
user with a diagnostic if we're not inhibited. */
void
-ffesta_shutdown ()
+ffesta_shutdown (void)
{
if (ffesta_is_inhibited_)
ffesta_current_shutdown_ = TRUE;
diff --git a/contrib/gcc/f/stb.c b/contrib/gcc/f/stb.c
index bf456a1afc13..673f96c23c54 100644
--- a/contrib/gcc/f/stb.c
+++ b/contrib/gcc/f/stb.c
@@ -1,5 +1,6 @@
/* stb.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 1996, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2002, 2003
+ Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -216,13 +217,6 @@ union ffestb_local_u_
ffestrOther kw;
}
varlist;
-#if FFESTR_F90
- struct
- {
- ffestrOther kw;
- }
- type;
-#endif
struct
{
ffelexHandler next;
@@ -241,13 +235,6 @@ union ffestb_local_u_
bool complained; /* If run-time expr seen in nonexec context. */
}
format;
-#if FFESTR_F90
- struct
- {
- bool started;
- }
- moduleprocedure;
-#endif
struct
{
ffebld expr;
@@ -258,47 +245,11 @@ union ffestb_local_u_
ffesttCaseList cases;
}
case_stmt;
-#if FFESTR_F90
- struct
- {
- ffesttExprList exprs;
- ffebld expr;
- }
- heap;
-#endif
-#if FFESTR_F90
- struct
- {
- ffesttExprList exprs;
- }
- R624;
-#endif
-#if FFESTR_F90
- struct
- {
- ffestpDefinedOperator operator;
- bool assignment; /* TRUE for INTERFACE ASSIGNMENT, FALSE for
- ...OPERATOR. */
- bool slash; /* TRUE if OPEN_ARRAY, FALSE if OPEN_PAREN. */
- }
- interface;
-#endif
struct
{
bool is_cblock;
}
V014;
-#if FFESTR_VXT
- struct
- {
- bool started;
- ffebld u;
- ffebld m;
- ffebld n;
- ffebld asv;
- }
- V025;
-#endif
struct
{
ffestpBeruIx ix;
@@ -380,13 +331,6 @@ union ffestb_local_u_
ffeexprContext context;
}
write;
-#if FFESTR_F90
- struct
- {
- bool started;
- }
- structure;
-#endif
struct
{
bool started;
@@ -481,10 +425,6 @@ static ffelexHandler ffestb_decl_typeparams_2_ (ffelexToken ft, ffebld expr,
ffelexToken t);
static ffelexHandler ffestb_decl_typeparams_3_ (ffelexToken ft, ffebld expr,
ffelexToken t);
-#if FFESTR_F90
-static ffelexHandler ffestb_decl_typetype1_ (ffelexToken t);
-static ffelexHandler ffestb_decl_typetype2_ (ffelexToken t);
-#endif
static ffelexHandler ffestb_subr_label_list_ (ffelexToken t);
static ffelexHandler ffestb_subr_label_list_1_ (ffelexToken t);
static ffelexHandler ffestb_do1_ (ffelexToken t);
@@ -529,26 +469,8 @@ static ffelexHandler ffestb_let1_ (ffelexToken ft, ffebld expr,
ffelexToken t);
static ffelexHandler ffestb_let2_ (ffelexToken ft, ffebld expr,
ffelexToken t);
-#if FFESTR_F90
-static ffelexHandler ffestb_type1_ (ffelexToken t);
-static ffelexHandler ffestb_type2_ (ffelexToken t);
-static ffelexHandler ffestb_type3_ (ffelexToken t);
-static ffelexHandler ffestb_type4_ (ffelexToken t);
-#endif
-#if FFESTR_F90
-static ffelexHandler ffestb_varlist1_ (ffelexToken t);
-static ffelexHandler ffestb_varlist2_ (ffelexToken t);
-static ffelexHandler ffestb_varlist3_ (ffelexToken t);
-static ffelexHandler ffestb_varlist4_ (ffelexToken t);
-#endif
static ffelexHandler ffestb_varlist5_ (ffelexToken t);
static ffelexHandler ffestb_varlist6_ (ffelexToken t);
-#if FFESTR_F90
-static ffelexHandler ffestb_where1_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_where2_ (ffelexToken t);
-static ffelexHandler ffestb_where3_ (ffelexToken t);
-#endif
static ffelexHandler ffestb_R5221_ (ffelexToken t);
static ffelexHandler ffestb_R5222_ (ffelexToken t);
static ffelexHandler ffestb_R5223_ (ffelexToken t);
@@ -599,20 +521,6 @@ static ffelexHandler ffestb_R12271_ (ffelexToken ft, ffebld expr,
ffelexToken t);
static ffelexHandler ffestb_construct1_ (ffelexToken t);
static ffelexHandler ffestb_construct2_ (ffelexToken t);
-#if FFESTR_F90
-static ffelexHandler ffestb_heap1_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_heap2_ (ffelexToken t);
-static ffelexHandler ffestb_heap3_ (ffelexToken t);
-static ffelexHandler ffestb_heap4_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_heap5_ (ffelexToken t);
-#endif
-#if FFESTR_F90
-static ffelexHandler ffestb_module1_ (ffelexToken t);
-static ffelexHandler ffestb_module2_ (ffelexToken t);
-static ffelexHandler ffestb_module3_ (ffelexToken t);
-#endif
static ffelexHandler ffestb_R8091_ (ffelexToken t);
static ffelexHandler ffestb_R8092_ (ffelexToken ft, ffebld expr,
ffelexToken t);
@@ -645,48 +553,12 @@ static ffelexHandler ffestb_R100117_ (ffelexToken ft, ffebld expr,
ffelexToken t);
static ffelexHandler ffestb_R100118_ (ffelexToken ft, ffebld expr,
ffelexToken t);
-#if FFESTR_F90
-static ffelexHandler ffestb_R11071_ (ffelexToken t);
-static ffelexHandler ffestb_R11072_ (ffelexToken t);
-static ffelexHandler ffestb_R11073_ (ffelexToken t);
-static ffelexHandler ffestb_R11074_ (ffelexToken t);
-static ffelexHandler ffestb_R11075_ (ffelexToken t);
-static ffelexHandler ffestb_R11076_ (ffelexToken t);
-static ffelexHandler ffestb_R11077_ (ffelexToken t);
-static ffelexHandler ffestb_R11078_ (ffelexToken t);
-static ffelexHandler ffestb_R11079_ (ffelexToken t);
-static ffelexHandler ffestb_R110710_ (ffelexToken t);
-static ffelexHandler ffestb_R110711_ (ffelexToken t);
-static ffelexHandler ffestb_R110712_ (ffelexToken t);
-#endif
-#if FFESTR_F90
-static ffelexHandler ffestb_R12021_ (ffelexToken t);
-static ffelexHandler ffestb_R12022_ (ffelexToken t);
-static ffelexHandler ffestb_R12023_ (ffelexToken t);
-static ffelexHandler ffestb_R12024_ (ffelexToken t);
-static ffelexHandler ffestb_R12025_ (ffelexToken t);
-static ffelexHandler ffestb_R12026_ (ffelexToken t);
-#endif
static ffelexHandler ffestb_S3P41_ (ffelexToken ft, ffebld expr,
ffelexToken t);
static ffelexHandler ffestb_V0141_ (ffelexToken t);
static ffelexHandler ffestb_V0142_ (ffelexToken t);
static ffelexHandler ffestb_V0143_ (ffelexToken t);
static ffelexHandler ffestb_V0144_ (ffelexToken t);
-#if FFESTR_VXT
-static ffelexHandler ffestb_V0251_ (ffelexToken t);
-static ffelexHandler ffestb_V0252_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V0253_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V0254_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V0255_ (ffelexToken t);
-static ffelexHandler ffestb_V0256_ (ffelexToken t);
-static ffelexHandler ffestb_V0257_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V0258_ (ffelexToken t);
-#endif
#if FFESTB_KILL_EASY_
static void ffestb_subr_kill_easy_ (ffestpInquireIx max);
#else
@@ -717,23 +589,6 @@ static ffelexHandler ffestb_beru7_ (ffelexToken ft, ffebld expr,
static ffelexHandler ffestb_beru8_ (ffelexToken t);
static ffelexHandler ffestb_beru9_ (ffelexToken t);
static ffelexHandler ffestb_beru10_ (ffelexToken t);
-#if FFESTR_VXT
-static ffelexHandler ffestb_vxtcode1_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_vxtcode2_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_vxtcode3_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_vxtcode4_ (ffelexToken t);
-static ffelexHandler ffestb_vxtcode5_ (ffelexToken t);
-static ffelexHandler ffestb_vxtcode6_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_vxtcode7_ (ffelexToken t);
-static ffelexHandler ffestb_vxtcode8_ (ffelexToken t);
-static ffelexHandler ffestb_vxtcode9_ (ffelexToken t);
-static ffelexHandler ffestb_vxtcode10_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-#endif
static ffelexHandler ffestb_R9041_ (ffelexToken t);
static ffelexHandler ffestb_R9042_ (ffelexToken t);
static ffelexHandler ffestb_R9043_ (ffelexToken ft, ffebld expr,
@@ -814,63 +669,10 @@ static ffelexHandler ffestb_R9239_ (ffelexToken t);
static ffelexHandler ffestb_R92310_ (ffelexToken t);
static ffelexHandler ffestb_R92311_ (ffelexToken ft, ffebld expr,
ffelexToken t);
-#if FFESTR_VXT
-static ffelexHandler ffestb_V0181_ (ffelexToken t);
-static ffelexHandler ffestb_V0182_ (ffelexToken t);
-static ffelexHandler ffestb_V0183_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V0184_ (ffelexToken t);
-static ffelexHandler ffestb_V0185_ (ffelexToken t);
-static ffelexHandler ffestb_V0186_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V0187_ (ffelexToken t);
-static ffelexHandler ffestb_V0188_ (ffelexToken t);
-static ffelexHandler ffestb_V0189_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V01810_ (ffelexToken t);
-static ffelexHandler ffestb_V01811_ (ffelexToken t);
-static ffelexHandler ffestb_V01812_ (ffelexToken t);
-static ffelexHandler ffestb_V01813_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V0191_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V0192_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-#endif
static ffelexHandler ffestb_V0201_ (ffelexToken ft, ffebld expr,
ffelexToken t);
static ffelexHandler ffestb_V0202_ (ffelexToken ft, ffebld expr,
ffelexToken t);
-#if FFESTR_VXT
-static ffelexHandler ffestb_V0211_ (ffelexToken t);
-static ffelexHandler ffestb_V0212_ (ffelexToken t);
-static ffelexHandler ffestb_V0213_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V0214_ (ffelexToken t);
-static ffelexHandler ffestb_V0215_ (ffelexToken t);
-static ffelexHandler ffestb_V0216_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V0217_ (ffelexToken t);
-static ffelexHandler ffestb_V0218_ (ffelexToken t);
-static ffelexHandler ffestb_V0219_ (ffelexToken t);
-static ffelexHandler ffestb_V0261_ (ffelexToken t);
-static ffelexHandler ffestb_V0262_ (ffelexToken t);
-static ffelexHandler ffestb_V0263_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V0264_ (ffelexToken t);
-static ffelexHandler ffestb_V0265_ (ffelexToken t);
-static ffelexHandler ffestb_V0266_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_V0267_ (ffelexToken t);
-static ffelexHandler ffestb_V0268_ (ffelexToken t);
-static ffelexHandler ffestb_V0269_ (ffelexToken t);
-#endif
-#if FFESTR_F90
-static ffelexHandler ffestb_dimlist1_ (ffelexToken t);
-static ffelexHandler ffestb_dimlist2_ (ffelexToken t);
-static ffelexHandler ffestb_dimlist3_ (ffelexToken t);
-static ffelexHandler ffestb_dimlist4_ (ffelexToken t);
-#endif
static ffelexHandler ffestb_dummy1_ (ffelexToken t);
static ffelexHandler ffestb_dummy2_ (ffelexToken t);
static ffelexHandler ffestb_R5241_ (ffelexToken t);
@@ -884,30 +686,13 @@ static ffelexHandler ffestb_R5474_ (ffelexToken t);
static ffelexHandler ffestb_R5475_ (ffelexToken t);
static ffelexHandler ffestb_R5476_ (ffelexToken t);
static ffelexHandler ffestb_R5477_ (ffelexToken t);
-#if FFESTR_F90
-static ffelexHandler ffestb_R6241_ (ffelexToken ft, ffebld expr,
- ffelexToken t);
-static ffelexHandler ffestb_R6242_ (ffelexToken t);
-#endif
static ffelexHandler ffestb_R12291_ (ffelexToken t);
static ffelexHandler ffestb_R12292_ (ffelexToken ft, ffebld expr,
ffelexToken t);
static ffelexHandler ffestb_decl_chartype1_ (ffelexToken t);
-#if FFESTR_F90
-static ffelexHandler ffestb_decl_recursive1_ (ffelexToken t);
-static ffelexHandler ffestb_decl_recursive2_ (ffelexToken t);
-static ffelexHandler ffestb_decl_recursive3_ (ffelexToken t);
-static ffelexHandler ffestb_decl_recursive4_ (ffelexToken t);
-#endif
static ffelexHandler ffestb_decl_attrs_ (ffelexToken t);
static ffelexHandler ffestb_decl_attrs_1_ (ffelexToken t);
static ffelexHandler ffestb_decl_attrs_2_ (ffelexToken t);
-#if FFESTR_F90
-static ffelexHandler ffestb_decl_attrs_3_ (ffelexToken t);
-static ffelexHandler ffestb_decl_attrs_4_ (ffelexToken t);
-static ffelexHandler ffestb_decl_attrs_5_ (ffelexToken t);
-static ffelexHandler ffestb_decl_attrs_6_ (ffelexToken t);
-#endif
static ffelexHandler ffestb_decl_attrs_7_ (ffelexToken t);
static ffelexHandler ffestb_decl_attrsp_ (ffelexToken t);
static ffelexHandler ffestb_decl_ents_ (ffelexToken t);
@@ -936,9 +721,6 @@ static ffelexHandler ffestb_decl_entsp_5_ (ffelexToken t);
static ffelexHandler ffestb_decl_entsp_6_ (ffelexToken t);
static ffelexHandler ffestb_decl_entsp_7_ (ffelexToken t);
static ffelexHandler ffestb_decl_entsp_8_ (ffelexToken t);
-#if FFESTR_F90
-static ffelexHandler ffestb_decl_func_ (ffelexToken t);
-#endif
static ffelexHandler ffestb_decl_funcname_ (ffelexToken t);
static ffelexHandler ffestb_decl_funcname_1_ (ffelexToken t);
static ffelexHandler ffestb_decl_funcname_2_ (ffelexToken t);
@@ -950,29 +732,12 @@ static ffelexHandler ffestb_decl_funcname_6_ (ffelexToken t);
static ffelexHandler ffestb_decl_funcname_7_ (ffelexToken t);
static ffelexHandler ffestb_decl_funcname_8_ (ffelexToken t);
static ffelexHandler ffestb_decl_funcname_9_ (ffelexToken t);
-#if FFESTR_VXT
-static ffelexHandler ffestb_V0031_ (ffelexToken t);
-static ffelexHandler ffestb_V0032_ (ffelexToken t);
-static ffelexHandler ffestb_V0033_ (ffelexToken t);
-static ffelexHandler ffestb_V0034_ (ffelexToken t);
-static ffelexHandler ffestb_V0035_ (ffelexToken t);
-static ffelexHandler ffestb_V0036_ (ffelexToken t);
-static ffelexHandler ffestb_V0161_ (ffelexToken t);
-static ffelexHandler ffestb_V0162_ (ffelexToken t);
-static ffelexHandler ffestb_V0163_ (ffelexToken t);
-static ffelexHandler ffestb_V0164_ (ffelexToken t);
-static ffelexHandler ffestb_V0165_ (ffelexToken t);
-static ffelexHandler ffestb_V0166_ (ffelexToken t);
-#endif
static ffelexHandler ffestb_V0271_ (ffelexToken t);
static ffelexHandler ffestb_V0272_ (ffelexToken ft, ffebld expr,
ffelexToken t);
static ffelexHandler ffestb_V0273_ (ffelexToken t);
static ffelexHandler ffestb_decl_R5391_ (ffelexToken t);
static ffelexHandler ffestb_decl_R5392_ (ffelexToken t);
-#if FFESTR_F90
-static ffelexHandler ffestb_decl_R5393_ (ffelexToken t);
-#endif
static ffelexHandler ffestb_decl_R5394_ (ffelexToken t);
static ffelexHandler ffestb_decl_R5395_ (ffelexToken t);
static ffelexHandler ffestb_decl_R539letters_ (ffelexToken t);
@@ -1050,7 +815,7 @@ ffestb_subr_ambig_nope_ (ffelexToken t)
in _ents_ (perform housekeeping tasks). */
static void
-ffestb_subr_ambig_to_ents_ ()
+ffestb_subr_ambig_to_ents_ (void)
{
ffelexToken nt;
@@ -1737,67 +1502,6 @@ ffestb_decl_typeparams_3_ (ffelexToken ft, ffebld expr, ffelexToken t)
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_decl_typetype1_ -- "TYPE" OPEN_PAREN
-
- return ffestb_decl_typetype1_; // to lexer
-
- Handle NAME. */
-
-#if FFESTR_F90
-static ffelexHandler
-ffestb_decl_typetype1_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffestb_local_.decl.kindt = ffelex_token_use (t);
- return (ffelexHandler) ffestb_decl_typetype2_;
-
- default:
- break;
- }
-
- if (ffestb_local_.decl.recursive != NULL)
- ffelex_token_kill (ffestb_local_.decl.recursive);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM,
- ffestb_local_.decl.badname,
- t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_decl_typetype2_ -- "TYPE" OPEN_PAREN NAME
-
- return ffestb_decl_typetype2_; // to lexer
-
- Handle CLOSE_PAREN. */
-
-static ffelexHandler
-ffestb_decl_typetype2_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCLOSE_PAREN:
- ffestb_local_.decl.type = FFESTP_typeTYPE;
- ffestb_local_.decl.kind = NULL;
- ffestb_local_.decl.len = NULL;
- ffestb_local_.decl.lent = NULL;
- ffelex_set_names (TRUE);
- return (ffelexHandler) ffestb_local_.decl.handler;
-
- default:
- break;
- }
-
- if (ffestb_local_.decl.recursive != NULL)
- ffelex_token_kill (ffestb_local_.decl.recursive);
- ffelex_token_kill (ffestb_local_.decl.kindt);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM,
- ffestb_local_.decl.badname,
- t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_subr_label_list_ -- Collect a tokenlist of labels and close-paren
return ffestb_subr_label_list_; // to lexer after seeing OPEN_PAREN
@@ -2664,11 +2368,6 @@ ffestb_elsexyz (ffelexToken t)
p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlELSE);
ffesta_tokens[1]
= ffelex_token_name_from_names (ffesta_tokens[0], i, 0);
-#if FFESTR_F90
- if ((ffestb_args.elsexyz.second == FFESTR_secondWHERE)
- && (ffelex_token_length (ffesta_tokens[1]) != FFESTR_secondlWHERE))
- ffestb_args.elsexyz.second = FFESTR_secondNone;
-#endif
return (ffelexHandler) ffestb_else1_ (t);
default:
@@ -2727,16 +2426,6 @@ ffestb_else1_ (ffelexToken t)
switch (ffestb_args.elsexyz.second)
{
-#if FFESTR_F90
- case FFESTR_secondWHERE:
- if (!ffesta_is_inhibited ())
- if ((ffesta_first_kw == FFESTR_firstELSEWHERE)
- && (ffelex_token_type (ffesta_tokens[0]) == FFELEX_typeNAME))
- ffestc_R744 ();
- else
- ffestc_elsewhere (ffesta_tokens[1]); /* R744 or R805. */
- break;
-#endif
default:
if (!ffesta_is_inhibited ())
@@ -2936,20 +2625,6 @@ ffestb_end (ffelexToken t)
case FFESTR_secondBLOCK:
return (ffelexHandler) ffestb_end1_;
-#if FFESTR_F90
- case FFESTR_secondINTERFACE:
-#endif
-#if FFESTR_VXT
- case FFESTR_secondMAP:
- case FFESTR_secondSTRUCTURE:
- case FFESTR_secondUNION:
-#endif
-#if FFESTR_F90
- case FFESTR_secondWHERE:
- ffesta_tokens[1] = NULL;
- return (ffelexHandler) ffestb_end3_;
-#endif
-
case FFESTR_secondNone:
goto bad_1; /* :::::::::::::::::::: */
@@ -3030,19 +2705,6 @@ ffestb_endxyz (ffelexToken t)
ffesta_confirmed ();
switch (ffestb_args.endxyz.second)
{
-#if FFESTR_F90
- case FFESTR_secondINTERFACE:
-#endif
-#if FFESTR_VXT
- case FFESTR_secondMAP:
- case FFESTR_secondSTRUCTURE:
- case FFESTR_secondUNION:
-#endif
-#if FFESTR_F90
- case FFESTR_secondWHERE:
- goto bad_1; /* :::::::::::::::::::: */
-#endif
-
case FFESTR_secondBLOCK:
if (ffesta_second_kw != FFESTR_secondDATA)
goto bad_1; /* :::::::::::::::::::: */
@@ -3086,24 +2748,6 @@ ffestb_endxyz (ffelexToken t)
{
p = ffelex_token_text (ffesta_tokens[0])
+ (i = ffestb_args.endxyz.len);
- switch (ffestb_args.endxyz.second)
- {
-#if FFESTR_F90
- case FFESTR_secondINTERFACE:
-#endif
-#if FFESTR_VXT
- case FFESTR_secondMAP:
- case FFESTR_secondSTRUCTURE:
- case FFESTR_secondUNION:
-#endif
-#if FFESTR_F90
- case FFESTR_secondWHERE:
- goto bad_i; /* :::::::::::::::::::: */
-#endif
-
- default:
- break;
- }
if (!ffesrc_is_name_init (*p))
goto bad_i; /* :::::::::::::::::::: */
ffesta_tokens[1]
@@ -3211,20 +2855,6 @@ ffestb_end3_ (ffelexToken t)
switch (ffestb_args.endxyz.second)
{
-#if FFESTR_F90
- case FFESTR_secondTYPE:
- if (!ffesta_is_inhibited ())
- ffestc_R425 (ffesta_tokens[1]);
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_secondWHERE:
- if (!ffesta_is_inhibited ())
- ffestc_R745 ();
- break;
-#endif
-
case FFESTR_secondIF:
if (!ffesta_is_inhibited ())
ffestc_R806 (ffesta_tokens[1]);
@@ -3245,25 +2875,12 @@ ffestb_end3_ (ffelexToken t)
ffestc_R1103 (ffesta_tokens[1]);
break;
-#if FFESTR_F90
- case FFESTR_secondMODULE:
- if (!ffesta_is_inhibited ())
- ffestc_R1106 (ffesta_tokens[1]);
- break;
-#endif
case FFESTR_secondBLOCK:
case FFESTR_secondBLOCKDATA:
if (!ffesta_is_inhibited ())
ffestc_R1112 (ffesta_tokens[1]);
break;
-#if FFESTR_F90
- case FFESTR_secondINTERFACE:
- if (!ffesta_is_inhibited ())
- ffestc_R1203 ();
- break;
-#endif
-
case FFESTR_secondFUNCTION:
if (!ffesta_is_inhibited ())
ffestc_R1221 (ffesta_tokens[1]);
@@ -3274,27 +2891,6 @@ ffestb_end3_ (ffelexToken t)
ffestc_R1225 (ffesta_tokens[1]);
break;
-#if FFESTR_VXT
- case FFESTR_secondSTRUCTURE:
- if (!ffesta_is_inhibited ())
- ffestc_V004 ();
- break;
-#endif
-
-#if FFESTR_VXT
- case FFESTR_secondUNION:
- if (!ffesta_is_inhibited ())
- ffestc_V010 ();
- break;
-#endif
-
-#if FFESTR_VXT
- case FFESTR_secondMAP:
- if (!ffesta_is_inhibited ())
- ffestc_V013 ();
- break;
-#endif
-
default:
ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "END", ffesta_tokens[0]);
if (ffesta_tokens[1] != NULL)
@@ -3990,155 +3586,6 @@ ffestb_if3_ (ffelexToken t)
return (ffelexHandler) next;
}
-/* ffestb_where -- Parse a WHERE statement
-
- return ffestb_where; // to lexer
-
- Make sure the statement has a valid form for a WHERE statement.
- If it does, implement the statement. */
-
-#if FFESTR_F90
-ffelexHandler
-ffestb_where (ffelexToken t)
-{
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstWHERE)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstWHERE)
- goto bad_0; /* :::::::::::::::::::: */
- if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlWHERE)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- break;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
-
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, FFEEXPR_contextWHERE,
- (ffeexprCallback) ffestb_where1_);
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WHERE", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WHERE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-}
-
-#endif
-/* ffestb_where1_ -- "WHERE" OPEN_PAREN expr
-
- (ffestb_where1_) // to expression handler
-
- Make sure the next token is CLOSE_PAREN. */
-
-#if FFESTR_F90
-static ffelexHandler
-ffestb_where1_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- ffestb_local_.if_stmt.expr = expr;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCLOSE_PAREN:
- if (expr == NULL)
- break;
- ffesta_tokens[1] = ffelex_token_use (ft);
- ffelex_set_names (TRUE);
- return (ffelexHandler) ffestb_where2_;
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WHERE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
-/* ffestb_where2_ -- "WHERE" OPEN_PAREN expr CLOSE_PAREN
-
- return ffestb_where2_; // to lexer
-
- Make sure the next token is NAME. */
-
-#if FFESTR_F90
-static ffelexHandler
-ffestb_where2_ (ffelexToken t)
-{
- ffelex_set_names (FALSE);
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- case FFELEX_typeNAMES:
- ffesta_confirmed ();
- ffesta_tokens[2] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_where3_;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_R742 (ffestb_local_.if_stmt.expr, ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WHERE", t);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
-/* ffestb_where3_ -- "WHERE" OPEN_PAREN expr CLOSE_PAREN NAME
-
- return ffestb_where3_; // to lexer
-
- Implement R742. */
-
-#if FFESTR_F90
-static ffelexHandler
-ffestb_where3_ (ffelexToken t)
-{
- ffelexHandler next;
- ffelexToken my_2 = ffesta_tokens[2];
-
- if (!ffesta_is_inhibited ())
- ffestc_R740 (ffestb_local_.if_stmt.expr, ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[1]);
- next = (ffelexHandler) ffesta_two (my_2, t);
- ffelex_token_kill (my_2);
- return (ffelexHandler) next;
-}
-
-#endif
/* ffestb_let -- Parse an assignment statement
return ffestb_let; // to lexer
@@ -4220,9 +3667,6 @@ ffestb_let1_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t)
switch (ffelex_token_type (t))
{
-#if FFESTR_F90
- case FFELEX_typePOINTS:
-#endif
case FFELEX_typeEQUALS:
if (expr == NULL)
break;
@@ -4257,14 +3701,7 @@ ffestb_let2_ (ffelexToken ft, ffebld expr, ffelexToken t)
break;
ffesta_confirmed ();
if (!ffesta_is_inhibited ())
-#if FFESTR_F90
- if (ffelex_token_type (ffesta_tokens[1]) == FFELEX_typeEQUALS)
-#endif
- ffestc_let (ffestb_local_.let.dest, expr, ft);
-#if FFESTR_F90
- else
- ffestc_R738 (ffestb_local_.let.dest, expr, ft);
-#endif
+ ffestc_let (ffestb_local_.let.dest, expr, ft);
ffelex_token_kill (ffesta_tokens[1]);
return (ffelexHandler) ffesta_zero (t);
@@ -4280,251 +3717,6 @@ ffestb_let2_ (ffelexToken ft, ffebld expr, ffelexToken t)
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_type -- Parse the TYPE statement
-
- return ffestb_type; // to lexer
-
- Make sure the statement has a valid form for the TYPE statement. If
- it does, implement the statement. */
-
-#if FFESTR_F90
-ffelexHandler
-ffestb_type (ffelexToken t)
-{
- ffeTokenLength i;
- const char *p;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstTYPE)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeCOMMA:
- ffesta_confirmed ();
- return (ffelexHandler) ffestb_type1_;
-
- case FFELEX_typeNAME: /* No confirm here, because ambig w/V020 VXT
- TYPE. */
- ffesta_tokens[1] = NULL;
- ffesta_tokens[2] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_type4_;
- }
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstTYPE)
- goto bad_0; /* :::::::::::::::::::: */
- p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlTYPE);
- switch (ffelex_token_type (t))
- {
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeCOMMA:
- if (*p != '\0')
- goto bad_i; /* :::::::::::::::::::: */
- ffesta_confirmed ();
- ffelex_set_names (TRUE);
- return (ffelexHandler) ffestb_type1_;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- break;
- }
- if (!ffesrc_is_name_init (*p))
- goto bad_i; /* :::::::::::::::::::: */
- ffesta_tokens[1] = NULL;
- ffesta_tokens[2]
- = ffelex_token_name_from_names (ffesta_tokens[0], i, 0);
- return (ffelexHandler) ffestb_type4_ (t);
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_i: /* :::::::::::::::::::: */
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "TYPE", ffesta_tokens[0], i, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_type1_ -- "TYPE" COMMA
-
- return ffestb_type1_; // to lexer
-
- Make sure the next token is a NAME. */
-
-static ffelexHandler
-ffestb_type1_ (ffelexToken t)
-{
- ffeTokenLength i;
- const char *p;
-
- ffelex_set_names (FALSE);
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- ffestb_local_.type.kw = ffestr_other (t);
- switch (ffestb_local_.varlist.kw)
- {
- case FFESTR_otherPUBLIC:
- case FFESTR_otherPRIVATE:
- return (ffelexHandler) ffestb_type2_;
-
- default:
- ffelex_token_kill (ffesta_tokens[1]);
- break;
- }
- break;
-
- case FFELEX_typeNAMES:
- ffesta_tokens[1] = ffelex_token_use (t);
- ffestb_local_.type.kw = ffestr_other (t);
- switch (ffestb_local_.varlist.kw)
- {
- case FFESTR_otherPUBLIC:
- p = ffelex_token_text (t) + (i = FFESTR_otherlPUBLIC);
- if (*p == '\0')
- return (ffelexHandler) ffestb_type2_;
- if (!ffesrc_is_name_init (*p))
- goto bad_i1; /* :::::::::::::::::::: */
- ffesta_tokens[2] = ffelex_token_name_from_names (t, i, 0);
- return (ffelexHandler) ffestb_type4_;
-
- case FFESTR_otherPRIVATE:
- p = ffelex_token_text (t) + (i = FFESTR_otherlPRIVATE);
- if (*p == '\0')
- return (ffelexHandler) ffestb_type2_;
- if (!ffesrc_is_name_init (*p))
- goto bad_i1; /* :::::::::::::::::::: */
- ffesta_tokens[2] = ffelex_token_name_from_names (t, i, 0);
- return (ffelexHandler) ffestb_type4_;
-
- default:
- ffelex_token_kill (ffesta_tokens[1]);
- break;
- }
- break;
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_i1: /* :::::::::::::::::::: */
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "TYPE", t, i, NULL);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_type2_ -- "TYPE" COMMA NAME
-
- return ffestb_type2_; // to lexer
-
- Handle COLONCOLON or NAME. */
-
-static ffelexHandler
-ffestb_type2_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOLONCOLON:
- return (ffelexHandler) ffestb_type3_;
-
- case FFELEX_typeNAME:
- return (ffelexHandler) ffestb_type3_ (t);
-
- default:
- break;
- }
-
- if (ffesta_tokens[1] != NULL)
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_type3_ -- "TYPE" [COMMA NAME [COLONCOLON]]
-
- return ffestb_type3_; // to lexer
-
- Make sure the next token is a NAME. */
-
-static ffelexHandler
-ffestb_type3_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[2] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_type4_;
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE", t);
- break;
- }
-
- if (ffesta_tokens[1] != NULL)
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_type4_ -- "TYPE" [COMMA NAME [COLONCOLON]] NAME
-
- return ffestb_type4_; // to lexer
-
- Make sure the next token is an EOS or SEMICOLON. */
-
-static ffelexHandler
-ffestb_type4_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_R424 (ffesta_tokens[1], ffestb_local_.type.kw,
- ffesta_tokens[2]);
- if (ffesta_tokens[1] != NULL)
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE", t);
- break;
- }
-
- if (ffesta_tokens[1] != NULL)
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_varlist -- Parse EXTERNAL/INTENT/INTRINSIC/OPTIONAL/PUBLIC/PRIVATE
statement
@@ -4549,23 +3741,7 @@ ffestb_varlist (ffelexToken t)
case FFELEX_typeEOS:
case FFELEX_typeSEMICOLON:
ffesta_confirmed ();
- switch (ffesta_first_kw)
- {
-#if FFESTR_F90
- case FFESTR_firstPUBLIC:
- if (!ffesta_is_inhibited ())
- ffestc_R521A ();
- return (ffelexHandler) ffesta_zero (t);
-
- case FFESTR_firstPRIVATE:
- if (!ffesta_is_inhibited ())
- ffestc_private (); /* Either R523A or R521B. */
- return (ffelexHandler) ffesta_zero (t);
-#endif
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
+ goto bad_1; /* :::::::::::::::::::: */
case FFELEX_typeCOMMA:
ffesta_confirmed (); /* Error, but clearly intended. */
@@ -4573,45 +3749,14 @@ ffestb_varlist (ffelexToken t)
case FFELEX_typeCOLONCOLON:
ffesta_confirmed ();
- switch (ffesta_first_kw)
- {
-#if FFESTR_F90
- case FFESTR_firstOPTIONAL:
- if (!ffesta_is_inhibited ())
- ffestc_R520_start ();
- break;
-
- case FFESTR_firstPUBLIC:
- if (!ffesta_is_inhibited ())
- ffestc_R521Astart ();
- break;
-
- case FFESTR_firstPRIVATE:
- if (!ffesta_is_inhibited ())
- ffestc_R521Bstart ();
- break;
-#endif
-
- default:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
- }
- return (ffelexHandler) ffestb_varlist5_;
+ ffesta_confirmed (); /* Error, but clearly intended. */
+ goto bad_1; /* :::::::::::::::::::: */
default:
goto bad_1; /* :::::::::::::::::::: */
case FFELEX_typeOPEN_PAREN:
- switch (ffesta_first_kw)
- {
-#if FFESTR_F90
- case FFESTR_firstINTENT:
- return (ffelexHandler) ffestb_varlist1_;
-#endif
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
+ goto bad_1; /* :::::::::::::::::::: */
case FFELEX_typeNAME:
ffesta_confirmed ();
@@ -4622,35 +3767,11 @@ ffestb_varlist (ffelexToken t)
ffestc_R1207_start ();
break;
-#if FFESTR_F90
- case FFESTR_firstINTENT:
- goto bad_1; /* :::::::::::::::::::: */
-#endif
-
case FFESTR_firstINTRINSIC:
if (!ffesta_is_inhibited ())
ffestc_R1208_start ();
break;
-#if FFESTR_F90
- case FFESTR_firstOPTIONAL:
- if (!ffesta_is_inhibited ())
- ffestc_R520_start ();
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstPUBLIC:
- if (!ffesta_is_inhibited ())
- ffestc_R521Astart ();
- break;
-
- case FFESTR_firstPRIVATE:
- if (!ffesta_is_inhibited ())
- ffestc_R521Bstart ();
- break;
-#endif
-
default:
break;
}
@@ -4664,93 +3785,23 @@ ffestb_varlist (ffelexToken t)
case FFELEX_typeEOS:
case FFELEX_typeSEMICOLON:
ffesta_confirmed ();
- switch (ffesta_first_kw)
- {
-#if FFESTR_F90
- case FFESTR_firstINTENT:
- goto bad_1; /* :::::::::::::::::::: */
-#endif
-
- default:
- break;
- }
if (*p != '\0')
break;
- switch (ffesta_first_kw)
- {
-#if FFESTR_F90
- case FFESTR_firstPUBLIC:
- if (!ffesta_is_inhibited ())
- ffestc_R521A ();
- return (ffelexHandler) ffesta_zero (t);
-
- case FFESTR_firstPRIVATE:
- if (!ffesta_is_inhibited ())
- ffestc_private (); /* Either R423A or R521B. */
- return (ffelexHandler) ffesta_zero (t);
-#endif
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
+ goto bad_1; /* :::::::::::::::::::: */
case FFELEX_typeCOMMA:
ffesta_confirmed (); /* Error, but clearly intended. */
- switch (ffesta_first_kw)
- {
-#if FFESTR_F90
- case FFESTR_firstINTENT:
- goto bad_1; /* :::::::::::::::::::: */
-#endif
- default:
- break;
- }
if (*p != '\0')
break;
goto bad_1; /* :::::::::::::::::::: */
case FFELEX_typeCOLONCOLON:
ffesta_confirmed ();
- switch (ffesta_first_kw)
- {
-#if FFESTR_F90
- case FFESTR_firstOPTIONAL:
- if (!ffesta_is_inhibited ())
- ffestc_R520_start ();
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstPUBLIC:
- if (!ffesta_is_inhibited ())
- ffestc_R521Astart ();
- break;
-
- case FFESTR_firstPRIVATE:
- if (!ffesta_is_inhibited ())
- ffestc_R521Bstart ();
- break;
-#endif
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
- return (ffelexHandler) ffestb_varlist5_;
+ goto bad_1; /* :::::::::::::::::::: */
case FFELEX_typeOPEN_PAREN:
- switch (ffesta_first_kw)
- {
-#if FFESTR_F90
- case FFESTR_firstINTENT:
- if (*p != '\0')
- goto bad_1; /* :::::::::::::::::::: */
- return (ffelexHandler) ffestb_varlist1_;
-#endif
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
+ goto bad_1; /* :::::::::::::::::::: */
case FFELEX_typeNAME:
ffesta_confirmed ();
@@ -4761,35 +3812,11 @@ ffestb_varlist (ffelexToken t)
ffestc_R1207_start ();
break;
-#if FFESTR_F90
- case FFESTR_firstINTENT:
- goto bad_1; /* :::::::::::::::::::: */
-#endif
-
case FFESTR_firstINTRINSIC:
if (!ffesta_is_inhibited ())
ffestc_R1208_start ();
break;
-#if FFESTR_F90
- case FFESTR_firstOPTIONAL:
- if (!ffesta_is_inhibited ())
- ffestc_R520_start ();
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstPUBLIC:
- if (!ffesta_is_inhibited ())
- ffestc_R521Astart ();
- break;
-
- case FFESTR_firstPRIVATE:
- if (!ffesta_is_inhibited ())
- ffestc_R521Bstart ();
- break;
-#endif
-
default:
break;
}
@@ -4819,22 +3846,6 @@ ffestb_varlist (ffelexToken t)
ffestc_R1208_start ();
break;
-#if FFESTR_F90
- case FFESTR_firstOPTIONAL:
- ffestc_R520_start ();
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstPUBLIC:
- ffestc_R521Astart ();
- break;
-
- case FFESTR_firstPRIVATE:
- ffestc_R521Bstart ();
- break;
-#endif
-
default:
assert (FALSE);
}
@@ -4861,139 +3872,6 @@ bad_i: /* :::::::::::::::::::: */
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_varlist1_ -- "INTENT" OPEN_PAREN
-
- return ffestb_varlist1_; // to lexer
-
- Handle NAME. */
-
-#if FFESTR_F90
-static ffelexHandler
-ffestb_varlist1_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- ffestb_local_.varlist.kw = ffestr_other (t);
- switch (ffestb_local_.varlist.kw)
- {
- case FFESTR_otherIN:
- return (ffelexHandler) ffestb_varlist2_;
-
- case FFESTR_otherINOUT:
- return (ffelexHandler) ffestb_varlist3_;
-
- case FFESTR_otherOUT:
- return (ffelexHandler) ffestb_varlist3_;
-
- default:
- ffelex_token_kill (ffesta_tokens[1]);
- break;
- }
- break;
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_varlist2_ -- "INTENT" OPEN_PAREN "IN"
-
- return ffestb_varlist2_; // to lexer
-
- Handle NAME. */
-
-static ffelexHandler
-ffestb_varlist2_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- switch (ffestr_other (t))
- {
- case FFESTR_otherOUT:
- ffestb_local_.varlist.kw = FFESTR_otherINOUT;
- return (ffelexHandler) ffestb_varlist3_;
-
- default:
- break;
- }
- break;
-
- case FFELEX_typeCLOSE_PAREN:
- return (ffelexHandler) ffestb_varlist4_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_varlist3_ -- "INTENT" OPEN_PAREN NAME ["OUT"]
-
- return ffestb_varlist3_; // to lexer
-
- Handle CLOSE_PAREN. */
-
-static ffelexHandler
-ffestb_varlist3_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCLOSE_PAREN:
- return (ffelexHandler) ffestb_varlist4_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_varlist4_ -- "INTENT" OPEN_PAREN NAME ["OUT"] CLOSE_PAREN
-
- return ffestb_varlist4_; // to lexer
-
- Handle COLONCOLON or NAME. */
-
-static ffelexHandler
-ffestb_varlist4_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_R519_start (ffesta_tokens[1], ffestb_local_.varlist.kw);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffestb_varlist5_;
-
- case FFELEX_typeNAME:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_R519_start (ffesta_tokens[1], ffestb_local_.varlist.kw);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffestb_varlist5_ (t);
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_varlist5_ -- Handles the list of variable names
return ffestb_varlist5_; // to lexer
@@ -5022,32 +3900,10 @@ ffestb_varlist5_ (ffelexToken t)
ffestc_R1207_finish ();
break;
-#if FFESTR_F90
- case FFESTR_firstINTENT:
- ffestc_R519_finish ();
- break;
-#endif
-
case FFESTR_firstINTRINSIC:
ffestc_R1208_finish ();
break;
-#if FFESTR_F90
- case FFESTR_firstOPTIONAL:
- ffestc_R520_finish ();
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstPUBLIC:
- ffestc_R521Afinish ();
- break;
-
- case FFESTR_firstPRIVATE:
- ffestc_R521Bfinish ();
- break;
-#endif
-
default:
assert (FALSE);
}
@@ -5075,32 +3931,10 @@ ffestb_varlist6_ (ffelexToken t)
ffestc_R1207_item (ffesta_tokens[1]);
break;
-#if FFESTR_F90
- case FFESTR_firstINTENT:
- ffestc_R519_item (ffesta_tokens[1]);
- break;
-#endif
-
case FFESTR_firstINTRINSIC:
ffestc_R1208_item (ffesta_tokens[1]);
break;
-#if FFESTR_F90
- case FFESTR_firstOPTIONAL:
- ffestc_R520_item (ffesta_tokens[1]);
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstPUBLIC:
- ffestc_R521Aitem (ffesta_tokens[1]);
- break;
-
- case FFESTR_firstPRIVATE:
- ffestc_R521Bitem (ffesta_tokens[1]);
- break;
-#endif
-
default:
assert (FALSE);
}
@@ -5119,37 +3953,11 @@ ffestb_varlist6_ (ffelexToken t)
ffestc_R1207_finish ();
break;
-#if FFESTR_F90
- case FFESTR_firstINTENT:
- ffestc_R519_item (ffesta_tokens[1]);
- ffestc_R519_finish ();
- break;
-#endif
-
case FFESTR_firstINTRINSIC:
ffestc_R1208_item (ffesta_tokens[1]);
ffestc_R1208_finish ();
break;
-#if FFESTR_F90
- case FFESTR_firstOPTIONAL:
- ffestc_R520_item (ffesta_tokens[1]);
- ffestc_R520_finish ();
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstPUBLIC:
- ffestc_R521Aitem (ffesta_tokens[1]);
- ffestc_R521Afinish ();
- break;
-
- case FFESTR_firstPRIVATE:
- ffestc_R521Bitem (ffesta_tokens[1]);
- ffestc_R521Bfinish ();
- break;
-#endif
-
default:
assert (FALSE);
}
@@ -5170,32 +3978,10 @@ ffestb_varlist6_ (ffelexToken t)
ffestc_R1207_finish ();
break;
-#if FFESTR_F90
- case FFESTR_firstINTENT:
- ffestc_R519_finish ();
- break;
-#endif
-
case FFESTR_firstINTRINSIC:
ffestc_R1208_finish ();
break;
-#if FFESTR_F90
- case FFESTR_firstOPTIONAL:
- ffestc_R520_finish ();
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstPUBLIC:
- ffestc_R521Afinish ();
- break;
-
- case FFESTR_firstPRIVATE:
- ffestc_R521Bfinish ();
- break;
-#endif
-
default:
assert (FALSE);
}
@@ -5204,75 +3990,6 @@ ffestb_varlist6_ (ffelexToken t)
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_R423B -- Parse the SEQUENCE statement
-
- return ffestb_R423B; // to lexer
-
- Make sure the statement has a valid form for the SEQUENCE statement. If
- it does, implement the statement. */
-
-#if FFESTR_F90
-ffelexHandler
-ffestb_R423B (ffelexToken t)
-{
- const char *p;
- ffeTokenLength i;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstSEQUENCE)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstSEQUENCE)
- goto bad_0; /* :::::::::::::::::::: */
- if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlSEQUENCE)
- {
- p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlSEQUENCE);
- goto bad_i; /* :::::::::::::::::::: */
- }
- break;
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_R423B ();
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SEQUENCE", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid first token. */
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SEQUENCE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_i: /* :::::::::::::::::::: */
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "SEQUENCE", ffesta_tokens[0], i, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_R522 -- Parse the SAVE statement
return ffestb_R522; // to lexer
@@ -7669,144 +6386,6 @@ ffestb_R12271_ (ffelexToken ft, ffebld expr, ffelexToken t)
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_R1228 -- Parse the CONTAINS statement
-
- return ffestb_R1228; // to lexer
-
- Make sure the statement has a valid form for the CONTAINS statement. If
- it does, implement the statement. */
-
-#if FFESTR_F90
-ffelexHandler
-ffestb_R1228 (ffelexToken t)
-{
- const char *p;
- ffeTokenLength i;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstCONTAINS)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstCONTAINS)
- goto bad_0; /* :::::::::::::::::::: */
- if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlCONTAINS)
- {
- p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlCONTAINS);
- goto bad_i; /* :::::::::::::::::::: */
- }
- break;
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_R1228 ();
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CONTAINS", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid first token. */
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CONTAINS", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_i: /* :::::::::::::::::::: */
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "CONTAINS", ffesta_tokens[0], i, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
-/* ffestb_V009 -- Parse the UNION statement
-
- return ffestb_V009; // to lexer
-
- Make sure the statement has a valid form for the UNION statement. If
- it does, implement the statement. */
-
-#if FFESTR_VXT
-ffelexHandler
-ffestb_V009 (ffelexToken t)
-{
- const char *p;
- ffeTokenLength i;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstUNION)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstUNION)
- goto bad_0; /* :::::::::::::::::::: */
- if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlUNION)
- {
- p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlUNION);
- goto bad_i; /* :::::::::::::::::::: */
- }
- break;
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_V009 ();
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "UNION", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid first token. */
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "UNION", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_i: /* :::::::::::::::::::: */
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "UNION", ffesta_tokens[0], i, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_construct -- Parse a construct name
return ffestb_construct; // to lexer
@@ -7924,505 +6503,6 @@ ffestb_construct2_ (ffelexToken t)
return (ffelexHandler) (*ffestb_local_.construct.next) (t);
}
-/* ffestb_heap -- Parse an ALLOCATE/DEALLOCATE statement
-
- return ffestb_heap; // to lexer
-
- Make sure the statement has a valid form for an ALLOCATE/DEALLOCATE
- statement. If it does, implement the statement. */
-
-#if FFESTR_F90
-ffelexHandler
-ffestb_heap (ffelexToken t)
-{
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- break;
-
- case FFELEX_typeNAMES:
- if (ffelex_token_length (ffesta_tokens[0]) != ffestb_args.heap.len)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- break;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
-
- ffestb_local_.heap.exprs = ffestt_exprlist_create ();
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- ffestb_args.heap.ctx,
- (ffeexprCallback) ffestb_heap1_);
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-}
-
-/* ffestb_heap1_ -- "ALLOCATE/DEALLOCATE" OPEN_PAREN expr
-
- (ffestb_heap1_) // to expression handler
-
- Make sure the next token is COMMA. */
-
-static ffelexHandler
-ffestb_heap1_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- if (expr == NULL)
- break;
- ffestt_exprlist_append (ffestb_local_.heap.exprs, expr,
- ffelex_token_use (t));
- return (ffelexHandler) ffestb_heap2_;
-
- case FFELEX_typeCLOSE_PAREN:
- if (expr == NULL)
- break;
- ffestt_exprlist_append (ffestb_local_.heap.exprs, expr,
- ffelex_token_use (t));
- ffesta_tokens[1] = NULL;
- ffestb_local_.heap.expr = NULL;
- return (ffelexHandler) ffestb_heap5_;
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, t);
- ffestt_exprlist_kill (ffestb_local_.heap.exprs);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_heap2_ -- "ALLOCATE/DEALLOCATE" OPEN_PAREN expr COMMA
-
- return ffestb_heap2_; // to lexer
-
- Make sure the next token is NAME. */
-
-static ffelexHandler
-ffestb_heap2_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_heap3_;
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, t);
- ffestt_exprlist_kill (ffestb_local_.heap.exprs);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_heap3_ -- "ALLOCATE/DEALLOCATE" OPEN_PAREN expr COMMA NAME
-
- return ffestb_heap3_; // to lexer
-
- If token is EQUALS, make sure NAME was "STAT" and handle STAT variable;
- else pass NAME and token to expression handler. */
-
-static ffelexHandler
-ffestb_heap3_ (ffelexToken t)
-{
- ffelexHandler next;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEQUALS:
- ffesta_confirmed ();
- if (ffestr_other (ffesta_tokens[1]) != FFESTR_otherSTAT)
- break;
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- FFEEXPR_contextHEAPSTAT,
- (ffeexprCallback) ffestb_heap4_);
-
- default:
- next = (ffelexHandler)
- (*((ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- ffestb_args.heap.ctx,
- (ffeexprCallback) ffestb_heap1_)))
- (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) (*next) (t);
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, t);
- ffestt_exprlist_kill (ffestb_local_.heap.exprs);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_heap4_ -- "ALLOCATE/DEALLOCATE" OPEN_PAREN ... COMMA "STAT" EQUALS
- expr
-
- (ffestb_heap4_) // to expression handler
-
- Make sure the next token is CLOSE_PAREN. */
-
-static ffelexHandler
-ffestb_heap4_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCLOSE_PAREN:
- if (expr == NULL)
- break;
- ffesta_tokens[1] = ffelex_token_use (ft);
- ffestb_local_.heap.expr = expr;
- return (ffelexHandler) ffestb_heap5_;
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, t);
- ffestt_exprlist_kill (ffestb_local_.heap.exprs);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_heap5_ -- "ALLOCATE/DEALLOCATE" OPEN_PAREN ... CLOSE_PAREN
-
- return ffestb_heap5_; // to lexer
-
- Make sure the next token is EOS/SEMICOLON. */
-
-static ffelexHandler
-ffestb_heap5_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- if (ffesta_first_kw == FFESTR_firstALLOCATE)
- ffestc_R620 (ffestb_local_.heap.exprs, ffestb_local_.heap.expr,
- ffesta_tokens[1]);
- else
- ffestc_R625 (ffestb_local_.heap.exprs, ffestb_local_.heap.expr,
- ffesta_tokens[1]);
- ffestt_exprlist_kill (ffestb_local_.heap.exprs);
- if (ffesta_tokens[1] != NULL)
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, t);
- ffestt_exprlist_kill (ffestb_local_.heap.exprs);
- if (ffesta_tokens[1] != NULL)
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
-/* ffestb_module -- Parse the MODULEPROCEDURE statement
-
- return ffestb_module; // to lexer
-
- Make sure the statement has a valid form for the MODULEPROCEDURE statement.
- If it does, implement the statement.
-
- 31-May-90 JCB 1.1
- Confirm NAME==MODULE followed by standard four invalid tokens, so we
- get decent message if somebody forgets that MODULE requires a name. */
-
-#if FFESTR_F90
-ffelexHandler
-ffestb_module (ffelexToken t)
-{
- ffeTokenLength i;
- const char *p;
- ffelexToken nt;
- ffelexToken mt; /* Name in MODULE PROCEDUREname, i.e.
- includes "PROCEDURE". */
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstMODULE)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- break;
-
- case FFELEX_typeCOLONCOLON:
- case FFELEX_typeCOMMA:
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- goto bad_1m; /* :::::::::::::::::::: */
-
- default:
- goto bad_1m; /* :::::::::::::::::::: */
- }
-
- ffesta_confirmed ();
- if (ffesta_second_kw != FFESTR_secondPROCEDURE)
- {
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_module3_;
- }
- ffestb_local_.moduleprocedure.started = FALSE;
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_module1_;
-
- case FFELEX_typeNAMES:
- p = ffelex_token_text (ffesta_tokens[0])
- + (i = FFESTR_firstlMODULEPROCEDURE);
- if ((ffesta_first_kw == FFESTR_firstMODULE)
- || ((ffesta_first_kw == FFESTR_firstMODULEPROCEDURE)
- && !ffesrc_is_name_init (*p)))
- { /* Definitely not "MODULE PROCEDURE name". */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1m; /* :::::::::::::::::::: */
-
- default:
- goto bad_1m; /* :::::::::::::::::::: */
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- break;
- }
- p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlMODULE);
- if (!ffesrc_is_name_init (*p))
- goto bad_im; /* :::::::::::::::::::: */
- nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0);
- if (!ffesta_is_inhibited ())
- ffestc_R1105 (nt);
- ffelex_token_kill (nt);
- return (ffelexHandler) ffesta_zero (t);
- }
-
- /* Here we know that we're indeed looking at a MODULEPROCEDURE
- statement rather than MODULE and that the character following
- MODULEPROCEDURE in the NAMES token is a valid first character for a
- NAME. This means that unless the second token is COMMA, we have an
- ambiguous statement that can be read either as MODULE PROCEDURE name
- or MODULE PROCEDUREname, the former being an R1205, the latter an
- R1105. */
-
- if (ffesta_first_kw != FFESTR_firstMODULEPROCEDURE)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeCOMMA: /* Aha, clearly not MODULE PROCEDUREname. */
- ffesta_confirmed ();
- ffestb_local_.moduleprocedure.started = FALSE;
- ffesta_tokens[1]
- = ffelex_token_name_from_names (ffesta_tokens[0], i, 0);
- return (ffelexHandler) ffestb_module2_ (t);
-
- case FFELEX_typeEOS: /* MODULE PROCEDURE name or MODULE
- PROCEDUREname. */
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- break;
- }
- nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0);
- mt = ffelex_token_name_from_names (ffesta_tokens[0], FFESTR_firstlMODULE,
- 0);
- if (!ffesta_is_inhibited ())
- ffestc_module (mt, nt); /* Implement ambiguous statement. */
- ffelex_token_kill (nt);
- ffelex_token_kill (mt);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MODULE PROCEDURE", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MODULE PROCEDURE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_1m: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MODULE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_im: /* :::::::::::::::::::: */
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "MODULE", ffesta_tokens[0], i, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_module1_ -- "MODULEPROCEDURE" or "MODULE" "PROCEDURE"
-
- return ffestb_module1_; // to lexer
-
- Make sure the statement has a valid form for the MODULEPROCEDURE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_module1_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- if (!ffestb_local_.moduleprocedure.started
- && (ffelex_token_type (ffesta_tokens[0]) == FFELEX_typeNAME))
- {
- ffesta_confirmed ();
- ffelex_token_kill (ffesta_tokens[1]);
- }
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_module2_;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (ffestb_local_.moduleprocedure.started)
- break; /* Error if we've already seen NAME COMMA. */
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_R1105 (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- break;
-
- default:
- break;
- }
-
- if (ffestb_local_.moduleprocedure.started && !ffesta_is_inhibited ())
- ffestc_R1205_finish ();
- else if (!ffestb_local_.moduleprocedure.started)
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MODULE PROCEDURE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_module2_ -- "MODULE/PROCEDURE" NAME
-
- return ffestb_module2_; // to lexer
-
- Make sure the statement has a valid form for the MODULEPROCEDURE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_module2_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffestb_local_.moduleprocedure.started)
- {
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_R1205_start ();
- }
- if (!ffesta_is_inhibited ())
- {
- ffestc_R1205_item (ffesta_tokens[1]);
- ffestc_R1205_finish ();
- }
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeCOMMA:
- if (!ffestb_local_.moduleprocedure.started)
- {
- ffestb_local_.moduleprocedure.started = TRUE;
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_R1205_start ();
- }
- if (!ffesta_is_inhibited ())
- ffestc_R1205_item (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffestb_module1_;
-
- default:
- break;
- }
-
- if (ffestb_local_.moduleprocedure.started && !ffesta_is_inhibited ())
- ffestc_R1205_finish ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MODULE PROCEDURE", t);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_module3_ -- "MODULE" NAME
-
- return ffestb_module3_; // to lexer
-
- Make sure the statement has a valid form for the MODULE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_module3_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffesta_is_inhibited ())
- ffestc_R1105 (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MODULE", t);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_R809 -- Parse the SELECTCASE statement
return ffestb_R809; // to lexer
@@ -10514,7 +8594,7 @@ ffestb_R100110_ (ffelexToken t)
case FFESTP_formattypeX:
err = FFEBAD_FORMAT_BAD_X_SPEC;
- pre = required;
+ pre = ffe_is_pedantic() ? required : optional;
post = disallowed;
dot = disallowed;
exp = disallowed;
@@ -10978,987 +9058,6 @@ ffestb_R100118_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t)
}
}
-/* ffestb_R1107 -- Parse the USE statement
-
- return ffestb_R1107; // to lexer
-
- Make sure the statement has a valid form for the USE statement.
- If it does, implement the statement. */
-
-#if FFESTR_F90
-ffelexHandler
-ffestb_R1107 (ffelexToken t)
-{
- ffeTokenLength i;
- const char *p;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstUSE)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- break;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
- ffesta_confirmed ();
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_R11071_;
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstUSE)
- goto bad_0; /* :::::::::::::::::::: */
- p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlUSE);
- if (!ffesrc_is_name_init (*p))
- goto bad_i; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeCOMMA:
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- break;
- }
- ffesta_confirmed ();
- ffesta_tokens[1]
- = ffelex_token_name_from_names (ffesta_tokens[0], i, 0);
- return (ffelexHandler) ffestb_R11071_ (t);
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_i: /* :::::::::::::::::::: */
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "USE", ffesta_tokens[0], i, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R11071_ -- "USE" NAME
-
- return ffestb_R11071_; // to lexer
-
- Make sure the statement has a valid form for the USE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R11071_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffesta_is_inhibited ())
- {
- ffestc_R1107_start (ffesta_tokens[1], FALSE);
- ffestc_R1107_finish ();
- }
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeCOMMA:
- return (ffelexHandler) ffestb_R11072_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R11072_ -- "USE" NAME COMMA
-
- return ffestb_R11072_; // to lexer
-
- Make sure the statement has a valid form for the USE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R11072_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[2] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_R11073_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R11073_ -- "USE" NAME COMMA NAME
-
- return ffestb_R11073_; // to lexer
-
- Make sure the statement has a valid form for the USE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R11073_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOLON:
- if (ffestr_other (ffesta_tokens[2]) != FFESTR_otherONLY)
- break;
- if (!ffesta_is_inhibited ())
- ffestc_R1107_start (ffesta_tokens[1], TRUE);
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- return (ffelexHandler) ffestb_R11074_;
-
- case FFELEX_typePOINTS:
- if (!ffesta_is_inhibited ())
- ffestc_R1107_start (ffesta_tokens[1], FALSE);
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_tokens[1] = ffesta_tokens[2];
- return (ffelexHandler) ffestb_R110711_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R11074_ -- "USE" NAME COMMA "ONLY" COLON
-
- return ffestb_R11074_; // to lexer
-
- Make sure the statement has a valid form for the USE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R11074_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_R11075_;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffesta_is_inhibited ())
- ffestc_R1107_finish ();
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- ffestc_R1107_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R11075_ -- "USE" NAME COMMA "ONLY" COLON NAME
-
- return ffestb_R11075_; // to lexer
-
- Make sure the statement has a valid form for the USE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R11075_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffesta_is_inhibited ())
- {
- ffestc_R1107_item (NULL, ffesta_tokens[1]);
- ffestc_R1107_finish ();
- }
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeCOMMA:
- if (!ffesta_is_inhibited ())
- ffestc_R1107_item (NULL, ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffestb_R11078_;
-
- case FFELEX_typePOINTS:
- return (ffelexHandler) ffestb_R11076_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- ffestc_R1107_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R11076_ -- "USE" NAME COMMA "ONLY" COLON NAME POINTS
-
- return ffestb_R11076_; // to lexer
-
- Make sure the statement has a valid form for the USE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R11076_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- if (!ffesta_is_inhibited ())
- ffestc_R1107_item (ffesta_tokens[1], t);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffestb_R11077_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- ffestc_R1107_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R11077_ -- "USE" NAME COMMA "ONLY" COLON NAME POINTS NAME
-
- return ffestb_R11077_; // to lexer
-
- Make sure the statement has a valid form for the USE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R11077_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffesta_is_inhibited ())
- ffestc_R1107_finish ();
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeCOMMA:
- return (ffelexHandler) ffestb_R11078_;
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- ffestc_R1107_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R11078_ -- "USE" NAME COMMA "ONLY" COLON NAME POINTS NAME COMMA
-
- return ffestb_R11078_; // to lexer
-
- Make sure the statement has a valid form for the USE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R11078_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_R11075_;
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- ffestc_R1107_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R11079_ -- "USE" NAME COMMA
-
- return ffestb_R11079_; // to lexer
-
- Make sure the statement has a valid form for the USE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R11079_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_R110710_;
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- ffestc_R1107_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R110710_ -- "USE" NAME COMMA NAME
-
- return ffestb_R110710_; // to lexer
-
- Make sure the statement has a valid form for the USE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R110710_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typePOINTS:
- return (ffelexHandler) ffestb_R110711_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- ffestc_R1107_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R110711_ -- "USE" NAME COMMA NAME POINTS
-
- return ffestb_R110711_; // to lexer
-
- Make sure the statement has a valid form for the USE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R110711_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- if (!ffesta_is_inhibited ())
- ffestc_R1107_item (ffesta_tokens[1], t);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffestb_R110712_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- ffestc_R1107_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R110712_ -- "USE" NAME COMMA NAME POINTS NAME
-
- return ffestb_R110712_; // to lexer
-
- Make sure the statement has a valid form for the USE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R110712_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffesta_is_inhibited ())
- ffestc_R1107_finish ();
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeCOMMA:
- return (ffelexHandler) ffestb_R11079_;
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t);
- ffestc_R1107_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
-/* ffestb_R1202 -- Parse the INTERFACE statement
-
- return ffestb_R1202; // to lexer
-
- Make sure the statement has a valid form for the INTERFACE statement.
- If it does, implement the statement.
-
- 15-May-90 JCB 1.1
- Allow INTERFACE by itself; missed this
- valid form when originally doing syntactic analysis code. */
-
-#if FFESTR_F90
-ffelexHandler
-ffestb_R1202 (ffelexToken t)
-{
- ffeTokenLength i;
- const char *p;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstINTERFACE)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- break;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorNone, NULL);
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
-
- ffesta_confirmed ();
- switch (ffesta_second_kw)
- {
- case FFESTR_secondOPERATOR:
- ffestb_local_.interface.operator = FFESTP_definedoperatorOPERATOR;
- break;
-
- case FFESTR_secondASSIGNMENT:
- ffestb_local_.interface.operator = FFESTP_definedoperatorASSIGNMENT;
- break;
-
- default:
- ffestb_local_.interface.operator = FFESTP_definedoperatorNone;
- break;
- }
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_R12021_;
-
- case FFELEX_typeNAMES:
- p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlINTERFACE);
- switch (ffesta_first_kw)
- {
- case FFESTR_firstINTERFACEOPERATOR:
- if (*(ffelex_token_text (ffesta_tokens[0])
- + FFESTR_firstlINTERFACEOPERATOR) == '\0')
- ffestb_local_.interface.operator
- = FFESTP_definedoperatorOPERATOR;
- break;
-
- case FFESTR_firstINTERFACEASSGNMNT:
- if (*(ffelex_token_text (ffesta_tokens[0])
- + FFESTR_firstlINTERFACEASSGNMNT) == '\0')
- ffestb_local_.interface.operator
- = FFESTP_definedoperatorASSIGNMENT;
- break;
-
- case FFESTR_firstINTERFACE:
- ffestb_local_.interface.operator = FFESTP_definedoperatorNone;
- break;
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeOPEN_PAREN:
- case FFELEX_typeOPEN_ARRAY: /* Sigh. */
- break;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (*p == '\0')
- {
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorNone, NULL);
- return (ffelexHandler) ffesta_zero (t);
- }
- break;
- }
- if (!ffesrc_is_name_init (*p))
- goto bad_i; /* :::::::::::::::::::: */
- ffesta_tokens[1] = ffelex_token_name_from_names (ffesta_tokens[0], i, 0);
- return (ffelexHandler) ffestb_R12021_ (t);
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_i: /* :::::::::::::::::::: */
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "INTERFACE", ffesta_tokens[0], i, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R12021_ -- "INTERFACE" NAME
-
- return ffestb_R12021_; // to lexer
-
- Make sure the statement has a valid form for the INTERFACE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_R12021_ (ffelexToken t)
-{
- ffestb_local_.interface.slash = TRUE; /* Slash follows open paren. */
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorNone, ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeOPEN_PAREN:
- ffestb_local_.interface.slash = FALSE; /* Slash doesn't follow. */
- /* Fall through. */
- case FFELEX_typeOPEN_ARRAY:
- switch (ffestb_local_.interface.operator)
- {
- case FFESTP_definedoperatorNone:
- break;
-
- case FFESTP_definedoperatorOPERATOR:
- ffestb_local_.interface.assignment = FALSE;
- return (ffelexHandler) ffestb_R12022_;
-
- case FFESTP_definedoperatorASSIGNMENT:
- ffestb_local_.interface.assignment = TRUE;
- return (ffelexHandler) ffestb_R12022_;
-
- default:
- assert (FALSE);
- }
- break;
-
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- break;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R12022_ -- "INTERFACE" "OPERATOR/ASSIGNMENT" OPEN_PAREN
-
- return ffestb_R12022_; // to lexer
-
- Make sure the statement has a valid form for the INTERFACE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_R12022_ (ffelexToken t)
-{
- ffesta_tokens[2] = ffelex_token_use (t);
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typePERIOD:
- if (ffestb_local_.interface.slash)
- break;
- return (ffelexHandler) ffestb_R12023_;
-
- case FFELEX_typePOWER:
- if (ffestb_local_.interface.slash)
- break;
- ffestb_local_.interface.operator = FFESTP_definedoperatorPOWER;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typeASTERISK:
- if (ffestb_local_.interface.slash)
- break;
- ffestb_local_.interface.operator = FFESTP_definedoperatorMULT;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typePLUS:
- if (ffestb_local_.interface.slash)
- break;
- ffestb_local_.interface.operator = FFESTP_definedoperatorADD;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typeCONCAT:
- if (ffestb_local_.interface.slash)
- break;
- ffestb_local_.interface.operator = FFESTP_definedoperatorCONCAT;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typeSLASH:
- if (ffestb_local_.interface.slash)
- {
- ffestb_local_.interface.operator = FFESTP_definedoperatorCONCAT;
- return (ffelexHandler) ffestb_R12025_;
- }
- ffestb_local_.interface.operator = FFESTP_definedoperatorDIVIDE;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typeMINUS:
- if (ffestb_local_.interface.slash)
- break;
- ffestb_local_.interface.operator = FFESTP_definedoperatorSUBTRACT;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typeREL_EQ:
- if (ffestb_local_.interface.slash)
- break;
- ffestb_local_.interface.operator = FFESTP_definedoperatorEQ;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typeREL_NE:
- if (ffestb_local_.interface.slash)
- break;
- ffestb_local_.interface.operator = FFESTP_definedoperatorNE;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typeOPEN_ANGLE:
- if (ffestb_local_.interface.slash)
- break;
- ffestb_local_.interface.operator = FFESTP_definedoperatorLT;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typeREL_LE:
- if (ffestb_local_.interface.slash)
- break;
- ffestb_local_.interface.operator = FFESTP_definedoperatorLE;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typeCLOSE_ANGLE:
- if (ffestb_local_.interface.slash)
- break;
- ffestb_local_.interface.operator = FFESTP_definedoperatorGT;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typeREL_GE:
- if (ffestb_local_.interface.slash)
- break;
- ffestb_local_.interface.operator = FFESTP_definedoperatorGE;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typeEQUALS:
- if (ffestb_local_.interface.slash)
- {
- ffestb_local_.interface.operator = FFESTP_definedoperatorNE;
- return (ffelexHandler) ffestb_R12025_;
- }
- ffestb_local_.interface.operator = FFESTP_definedoperatorASSIGNMENT;
- return (ffelexHandler) ffestb_R12025_;
-
- case FFELEX_typeCLOSE_ARRAY:
- if (!ffestb_local_.interface.slash)
- {
- ffestb_local_.interface.operator = FFESTP_definedoperatorDIVIDE;
- return (ffelexHandler) ffestb_R12026_;
- }
- ffestb_local_.interface.operator = FFESTP_definedoperatorCONCAT;
- return (ffelexHandler) ffestb_R12026_;
-
- case FFELEX_typeCLOSE_PAREN:
- if (!ffestb_local_.interface.slash)
- break;
- ffestb_local_.interface.operator = FFESTP_definedoperatorDIVIDE;
- return (ffelexHandler) ffestb_R12026_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R12023_ -- "INTERFACE" NAME OPEN_PAREN PERIOD
-
- return ffestb_R12023_; // to lexer
-
- Make sure the statement has a valid form for the INTERFACE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_R12023_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffelex_token_kill (ffesta_tokens[2]);
- ffesta_tokens[2] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_R12024_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R12024_ -- "INTERFACE" NAME OPEN_PAREN PERIOD NAME
-
- return ffestb_R12024_; // to lexer
-
- Make sure the statement has a valid form for the INTERFACE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_R12024_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typePERIOD:
- return (ffelexHandler) ffestb_R12025_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R12025_ -- "INTERFACE" NAME OPEN_PAREN operator
-
- return ffestb_R12025_; // to lexer
-
- Make sure the statement has a valid form for the INTERFACE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_R12025_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCLOSE_PAREN:
- return (ffelexHandler) ffestb_R12026_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R12026_ -- "INTERFACE" NAME OPEN_PAREN operator CLOSE_PAREN
-
- return ffestb_R12026_; // to lexer
-
- Make sure the statement has a valid form for the INTERFACE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_R12026_ (ffelexToken t)
-{
- const char *p;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (ffestb_local_.interface.assignment
- && (ffestb_local_.interface.operator
- != FFESTP_definedoperatorASSIGNMENT))
- {
- ffebad_start (FFEBAD_INTERFACE_ASSIGNMENT);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[1]),
- ffelex_token_where_column (ffesta_tokens[1]));
- ffebad_here (1, ffelex_token_where_line (ffesta_tokens[2]),
- ffelex_token_where_column (ffesta_tokens[2]));
- ffebad_finish ();
- }
- switch (ffelex_token_type (ffesta_tokens[2]))
- {
- case FFELEX_typeNAME:
- switch (ffestr_other (ffesta_tokens[2]))
- {
- case FFESTR_otherNOT:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorNOT, NULL);
- break;
-
- case FFESTR_otherAND:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorAND, NULL);
- break;
-
- case FFESTR_otherOR:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorOR, NULL);
- break;
-
- case FFESTR_otherEQV:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorEQV, NULL);
- break;
-
- case FFESTR_otherNEQV:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorNEQV, NULL);
- break;
-
- case FFESTR_otherEQ:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorEQ, NULL);
- break;
-
- case FFESTR_otherNE:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorNE, NULL);
- break;
-
- case FFESTR_otherLT:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorLT, NULL);
- break;
-
- case FFESTR_otherLE:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorLE, NULL);
- break;
-
- case FFESTR_otherGT:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorGT, NULL);
- break;
-
- case FFESTR_otherGE:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorGE, NULL);
- break;
-
- default:
- for (p = ffelex_token_text (ffesta_tokens[2]); *p != '\0'; ++p)
- {
- if (! ISALPHA (*p))
- {
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffesta_ffebad_1t (FFEBAD_INTERFACE_NONLETTER,
- ffesta_tokens[2]);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero);
- }
- }
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (FFESTP_definedoperatorOPERATOR,
- ffesta_tokens[2]);
- }
- break;
-
- case FFELEX_typeEQUALS:
- if (!ffestb_local_.interface.assignment
- && (ffestb_local_.interface.operator
- == FFESTP_definedoperatorASSIGNMENT))
- {
- ffebad_start (FFEBAD_INTERFACE_OPERATOR);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[1]),
- ffelex_token_where_column (ffesta_tokens[1]));
- ffebad_here (1, ffelex_token_where_line (ffesta_tokens[2]),
- ffelex_token_where_column (ffesta_tokens[2]));
- ffebad_finish ();
- }
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (ffestb_local_.interface.operator, NULL);
- break;
-
- default:
- if (!ffesta_is_inhibited ())
- ffestc_R1202 (ffestb_local_.interface.operator, NULL);
- }
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_S3P4 -- Parse the INCLUDE line
return ffestb_S3P4; // to lexer
@@ -12092,75 +9191,6 @@ ffestb_S3P41_ (ffelexToken ft, ffebld expr, ffelexToken t)
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_V012 -- Parse the MAP statement
-
- return ffestb_V012; // to lexer
-
- Make sure the statement has a valid form for the MAP statement. If
- it does, implement the statement. */
-
-#if FFESTR_VXT
-ffelexHandler
-ffestb_V012 (ffelexToken t)
-{
- const char *p;
- ffeTokenLength i;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstMAP)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstMAP)
- goto bad_0; /* :::::::::::::::::::: */
- if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlMAP)
- {
- p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlMAP);
- goto bad_i; /* :::::::::::::::::::: */
- }
- break;
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_V012 ();
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MAP", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid first token. */
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MAP", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_i: /* :::::::::::::::::::: */
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "MAP", ffesta_tokens[0], i, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_V014 -- Parse the VOLATILE statement
return ffestb_V014; // to lexer
@@ -12394,344 +9424,6 @@ ffestb_V0144_ (ffelexToken t)
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_V025 -- Parse the DEFINEFILE statement
-
- return ffestb_V025; // to lexer
-
- Make sure the statement has a valid form for the DEFINEFILE statement.
- If it does, implement the statement. */
-
-#if FFESTR_VXT
-ffelexHandler
-ffestb_V025 (ffelexToken t)
-{
- ffeTokenLength i;
- const char *p;
- ffelexToken nt;
- ffelexHandler next;
-
- ffestb_local_.V025.started = FALSE;
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- switch (ffesta_first_kw)
- {
- case FFESTR_firstDEFINE:
- if ((ffelex_token_type (t) != FFELEX_typeNAME)
- || (ffesta_second_kw != FFESTR_secondFILE))
- goto bad_1; /* :::::::::::::::::::: */
- ffesta_confirmed ();
- return (ffelexHandler) ffestb_V0251_;
-
- case FFESTR_firstDEFINEFILE:
- return (ffelexHandler) ffestb_V0251_ (t);
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstDEFINEFILE)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeOPEN_PAREN:
- break;
- }
- p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlDEFINEFILE);
- if (ISDIGIT (*p))
- nt = ffelex_token_number_from_names (ffesta_tokens[0], i);
- else if (ffesrc_is_name_init (*p))
- nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0);
- else
- goto bad_i; /* :::::::::::::::::::: */
- next = (ffelexHandler) ffestb_V0251_ (nt);
- ffelex_token_kill (nt);
- return (ffelexHandler) (*next) (t);
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_i: /* :::::::::::::::::::: */
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", ffesta_tokens[0], i, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0251_ -- "DEFINEFILE" or "DEFINE" "FILE"
-
- return ffestb_V0251_; // to lexer
-
- Make sure the statement has a valid form for the DEFINEFILE statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_V0251_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- case FFELEX_typeNUMBER:
- if (ffelex_token_type (ffesta_tokens[0]) == FFELEX_typeNAME)
- ffesta_confirmed ();
- return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILEUNIT_DF, (ffeexprCallback) ffestb_V0252_)))
- (t);
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- break;
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0252_ -- "DEFINEFILE" expr
-
- (ffestb_V0252_) // to expression handler
-
- Make sure the statement has a valid form for the DEFINEFILE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_V0252_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- ffestb_local_.V025.u = expr;
- ffesta_tokens[1] = ffelex_token_use (ft);
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0253_);
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0253_ -- "DEFINEFILE" expr OPEN_PAREN expr
-
- (ffestb_V0253_) // to expression handler
-
- Make sure the statement has a valid form for the DEFINEFILE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_V0253_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- ffestb_local_.V025.m = expr;
- ffesta_tokens[2] = ffelex_token_use (ft);
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0254_);
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0254_ -- "DEFINEFILE" expr OPEN_PAREN expr COMMA expr
-
- (ffestb_V0254_) // to expression handler
-
- Make sure the statement has a valid form for the DEFINEFILE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_V0254_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- ffestb_local_.V025.n = expr;
- ffesta_tokens[3] = ffelex_token_use (ft);
- return (ffelexHandler) ffestb_V0255_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0255_ -- "DEFINEFILE" expr OPEN_PAREN expr COMMA expr COMMA
-
- return ffestb_V0255_; // to lexer
-
- Make sure the statement has a valid form for the DEFINEFILE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_V0255_ (ffelexToken t)
-{
- const char *p;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- p = ffelex_token_text (t);
- if (!ffesrc_char_match_init (*p, 'U', 'u') || (*++p != '\0'))
- break;
- return (ffelexHandler) ffestb_V0256_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffelex_token_kill (ffesta_tokens[3]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0256_ -- "DEFINEFILE" expr OPEN_PAREN expr COMMA expr COMMA "U"
-
- return ffestb_V0256_; // to lexer
-
- Make sure the statement has a valid form for the DEFINEFILE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_V0256_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- FFEEXPR_contextFILEASSOC,
- (ffeexprCallback) ffestb_V0257_);
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffelex_token_kill (ffesta_tokens[3]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0257_ -- "DEFINEFILE" expr OPEN_PAREN expr COMMA expr COMMA "U"
- COMMA expr
-
- (ffestb_V0257_) // to expression handler
-
- Make sure the statement has a valid form for the DEFINEFILE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_V0257_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCLOSE_PAREN:
- ffestb_local_.V025.asv = expr;
- ffesta_tokens[4] = ffelex_token_use (ft);
- return (ffelexHandler) ffestb_V0258_;
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffelex_token_kill (ffesta_tokens[3]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0258_ -- "DEFINEFILE" expr OPEN_PAREN expr COMMA expr COMMA "U"
- COMMA expr CLOSE_PAREN
-
- return ffestb_V0258_; // to lexer
-
- Make sure the statement has a valid form for the DEFINEFILE statement. If
- it does, implement the statement. */
-
-static ffelexHandler
-ffestb_V0258_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffestb_local_.V025.started)
- {
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_V025_start ();
- ffestb_local_.V025.started = TRUE;
- }
- if (!ffesta_is_inhibited ())
- ffestc_V025_item (ffestb_local_.V025.u, ffesta_tokens[1],
- ffestb_local_.V025.m, ffesta_tokens[2],
- ffestb_local_.V025.n, ffesta_tokens[3],
- ffestb_local_.V025.asv, ffesta_tokens[4]);
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffelex_token_kill (ffesta_tokens[3]);
- ffelex_token_kill (ffesta_tokens[4]);
- if (ffelex_token_type (t) == FFELEX_typeCOMMA)
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILEUNIT_DF, (ffeexprCallback) ffestb_V0252_);
- if (!ffesta_is_inhibited ())
- ffestc_V025_finish ();
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[2]);
- ffelex_token_kill (ffesta_tokens[3]);
- ffelex_token_kill (ffesta_tokens[4]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_subr_kill_easy_ -- Kill I/O statement data structure
ffestb_subr_kill_easy_();
@@ -12768,7 +9460,7 @@ ffestb_subr_kill_easy_ (ffestpInquireIx max)
#if !FFESTB_KILL_EASY_
static void
-ffestb_subr_kill_accept_ ()
+ffestb_subr_kill_accept_ (void)
{
ffestpAcceptIx ix;
@@ -12794,7 +9486,7 @@ ffestb_subr_kill_accept_ ()
#if !FFESTB_KILL_EASY_
static void
-ffestb_subr_kill_beru_ ()
+ffestb_subr_kill_beru_ (void)
{
ffestpBeruIx ix;
@@ -12819,7 +9511,7 @@ ffestb_subr_kill_beru_ ()
#if !FFESTB_KILL_EASY_
static void
-ffestb_subr_kill_close_ ()
+ffestb_subr_kill_close_ (void)
{
ffestpCloseIx ix;
@@ -12844,7 +9536,7 @@ ffestb_subr_kill_close_ ()
#if !FFESTB_KILL_EASY_
static void
-ffestb_subr_kill_delete_ ()
+ffestb_subr_kill_delete_ (void)
{
ffestpDeleteIx ix;
@@ -12869,7 +9561,7 @@ ffestb_subr_kill_delete_ ()
#if !FFESTB_KILL_EASY_
static void
-ffestb_subr_kill_inquire_ ()
+ffestb_subr_kill_inquire_ (void)
{
ffestpInquireIx ix;
@@ -12894,7 +9586,7 @@ ffestb_subr_kill_inquire_ ()
#if !FFESTB_KILL_EASY_
static void
-ffestb_subr_kill_open_ ()
+ffestb_subr_kill_open_ (void)
{
ffestpOpenIx ix;
@@ -12919,7 +9611,7 @@ ffestb_subr_kill_open_ ()
#if !FFESTB_KILL_EASY_
static void
-ffestb_subr_kill_print_ ()
+ffestb_subr_kill_print_ (void)
{
ffestpPrintIx ix;
@@ -12944,7 +9636,7 @@ ffestb_subr_kill_print_ ()
#if !FFESTB_KILL_EASY_
static void
-ffestb_subr_kill_read_ ()
+ffestb_subr_kill_read_ (void)
{
ffestpReadIx ix;
@@ -12969,7 +9661,7 @@ ffestb_subr_kill_read_ ()
#if !FFESTB_KILL_EASY_
static void
-ffestb_subr_kill_rewrite_ ()
+ffestb_subr_kill_rewrite_ (void)
{
ffestpRewriteIx ix;
@@ -12994,7 +9686,7 @@ ffestb_subr_kill_rewrite_ ()
#if !FFESTB_KILL_EASY_
static void
-ffestb_subr_kill_type_ ()
+ffestb_subr_kill_type_ (void)
{
ffestpTypeIx ix;
@@ -13019,7 +9711,7 @@ ffestb_subr_kill_type_ ()
#if !FFESTB_KILL_EASY_
static void
-ffestb_subr_kill_write_ ()
+ffestb_subr_kill_write_ (void)
{
ffestpWriteIx ix;
@@ -13187,12 +9879,6 @@ ffestb_beru1_ (ffelexToken ft, ffebld expr, ffelexToken t)
ffestc_R921 ();
break;
-#if FFESTR_VXT
- case FFESTR_firstUNLOCK:
- ffestc_V022 ();
- break;
-#endif
-
default:
assert (FALSE);
}
@@ -13549,12 +10235,6 @@ ffestb_beru10_ (ffelexToken t)
ffestc_R921 ();
break;
-#if FFESTR_VXT
- case FFESTR_firstUNLOCK:
- ffestc_V022 ();
- break;
-#endif
-
default:
assert (FALSE);
}
@@ -13571,504 +10251,6 @@ ffestb_beru10_ (ffelexToken t)
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_vxtcode -- Parse the VXT DECODE/ENCODE statement
-
- return ffestb_vxtcode; // to lexer
-
- Make sure the statement has a valid form for the VXT DECODE/ENCODE
- statement. If it does, implement the statement. */
-
-#if FFESTR_VXT
-ffelexHandler
-ffestb_vxtcode (ffelexToken t)
-{
- ffestpVxtcodeIx ix;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeNAME:
- case FFELEX_typeNUMBER:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeOPEN_PAREN:
- for (ix = 0; ix < FFESTP_vxtcodeix; ++ix)
- ffestp_file.vxtcode.vxtcode_spec[ix].kw_or_val_present = FALSE;
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_vxtcode1_);
- }
-
- case FFELEX_typeNAMES:
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeOPEN_PAREN:
- if (ffelex_token_length (ffesta_tokens[0])
- != ffestb_args.vxtcode.len)
- goto bad_0; /* :::::::::::::::::::: */
-
- for (ix = 0; ix < FFESTP_vxtcodeix; ++ix)
- ffestp_file.vxtcode.vxtcode_spec[ix].kw_or_val_present = FALSE;
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_vxtcode1_);
- }
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-}
-
-/* ffestb_vxtcode1_ -- "VXTCODE" OPEN_PAREN expr
-
- (ffestb_vxtcode1_) // to expression handler
-
- Handle COMMA here. */
-
-static ffelexHandler
-ffestb_vxtcode1_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- if (expr == NULL)
- break;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixC].kw_or_val_present
- = TRUE;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixC].kw_present = FALSE;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixC].value_present = TRUE;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixC].value_is_label
- = FALSE;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixC].value
- = ffelex_token_use (ft);
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixC].u.expr = expr;
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILEFORMAT, (ffeexprCallback) ffestb_vxtcode2_);
-
- default:
- break;
- }
-
- ffestb_subr_kill_vxtcode_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_vxtcode2_ -- "VXTCODE" OPEN_PAREN expr COMMA expr
-
- (ffestb_vxtcode2_) // to expression handler
-
- Handle COMMA here. */
-
-static ffelexHandler
-ffestb_vxtcode2_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixF].kw_or_val_present
- = TRUE;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixF].kw_present = FALSE;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixF].value_present = TRUE;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixF].value_is_label
- = (expr == NULL);
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixF].value
- = ffelex_token_use (ft);
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixF].u.expr = expr;
- if (ffesta_first_kw == FFESTR_firstENCODE)
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- FFEEXPR_contextFILEVXTCODE,
- (ffeexprCallback) ffestb_vxtcode3_);
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILEVXTCODE,
- (ffeexprCallback) ffestb_vxtcode3_);
-
- default:
- break;
- }
-
- ffestb_subr_kill_vxtcode_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_vxtcode3_ -- "VXTCODE" OPEN_PAREN expr COMMA expr COMMA expr
-
- (ffestb_vxtcode3_) // to expression handler
-
- Handle COMMA or CLOSE_PAREN here. */
-
-static ffelexHandler
-ffestb_vxtcode3_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCLOSE_PAREN:
- if (expr == NULL)
- break;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixB].kw_or_val_present
- = TRUE;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixB].kw_present = FALSE;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixB].value_present = TRUE;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixB].value_is_label
- = FALSE;
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixB].value
- = ffelex_token_use (ft);
- ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixB].u.expr = expr;
- if (ffelex_token_type (t) == FFELEX_typeCOMMA)
- return (ffelexHandler) ffestb_vxtcode4_;
- return (ffelexHandler) ffestb_vxtcode9_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_vxtcode_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_vxtcode4_ -- "VXTCODE" OPEN_PAREN ...
-
- return ffestb_vxtcode4_; // to lexer
-
- Handle NAME=expr construct here. */
-
-static ffelexHandler
-ffestb_vxtcode4_ (ffelexToken t)
-{
- ffestrGenio kw;
-
- ffestb_local_.vxtcode.label = FALSE;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- kw = ffestr_genio (t);
- switch (kw)
- {
- case FFESTR_genioERR:
- ffestb_local_.vxtcode.ix = FFESTP_vxtcodeixERR;
- ffestb_local_.vxtcode.label = TRUE;
- break;
-
- case FFESTR_genioIOSTAT:
- ffestb_local_.vxtcode.ix = FFESTP_vxtcodeixIOSTAT;
- ffestb_local_.vxtcode.left = TRUE;
- ffestb_local_.vxtcode.context = FFEEXPR_contextFILEINT;
- break;
-
- default:
- goto bad; /* :::::::::::::::::::: */
- }
- if (ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix]
- .kw_or_val_present)
- break; /* Can't specify a keyword twice! */
- ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix]
- .kw_or_val_present = TRUE;
- ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix]
- .kw_present = TRUE;
- ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix]
- .value_present = FALSE;
- ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].value_is_label
- = ffestb_local_.vxtcode.label;
- ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].kw
- = ffelex_token_use (t);
- return (ffelexHandler) ffestb_vxtcode5_;
-
- default:
- break;
- }
-
-bad: /* :::::::::::::::::::: */
- ffestb_subr_kill_vxtcode_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_vxtcode5_ -- "VXTCODE" OPEN_PAREN [external-file-unit COMMA [format
- COMMA]] NAME
-
- return ffestb_vxtcode5_; // to lexer
-
- Make sure EQUALS here, send next token to expression handler. */
-
-static ffelexHandler
-ffestb_vxtcode5_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEQUALS:
- ffesta_confirmed ();
- if (ffestb_local_.vxtcode.label)
- return (ffelexHandler) ffestb_vxtcode7_;
- if (ffestb_local_.vxtcode.left)
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- ffestb_local_.vxtcode.context,
- (ffeexprCallback) ffestb_vxtcode6_);
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- ffestb_local_.vxtcode.context,
- (ffeexprCallback) ffestb_vxtcode6_);
-
- default:
- break;
- }
-
- ffestb_subr_kill_vxtcode_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_vxtcode6_ -- "VXTCODE" OPEN_PAREN ... NAME EQUALS expr
-
- (ffestb_vxtcode6_) // to expression handler
-
- Handle COMMA or CLOSE_PAREN here. */
-
-static ffelexHandler
-ffestb_vxtcode6_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCLOSE_PAREN:
- if (expr == NULL)
- break;
- ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].value_present
- = TRUE;
- ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].value
- = ffelex_token_use (ft);
- ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].u.expr = expr;
- if (ffelex_token_type (t) == FFELEX_typeCOMMA)
- return (ffelexHandler) ffestb_vxtcode4_;
- return (ffelexHandler) ffestb_vxtcode9_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_vxtcode_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_vxtcode7_ -- "VXTCODE" OPEN_PAREN ... NAME EQUALS
-
- return ffestb_vxtcode7_; // to lexer
-
- Handle NUMBER for label here. */
-
-static ffelexHandler
-ffestb_vxtcode7_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNUMBER:
- ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].value_present
- = TRUE;
- ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].value
- = ffelex_token_use (t);
- return (ffelexHandler) ffestb_vxtcode8_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_vxtcode_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_vxtcode8_ -- "VXTCODE" OPEN_PAREN ... NAME EQUALS NUMBER
-
- return ffestb_vxtcode8_; // to lexer
-
- Handle COMMA or CLOSE_PAREN here. */
-
-static ffelexHandler
-ffestb_vxtcode8_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- return (ffelexHandler) ffestb_vxtcode4_;
-
- case FFELEX_typeCLOSE_PAREN:
- return (ffelexHandler) ffestb_vxtcode9_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_vxtcode_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_vxtcode9_ -- "VXTCODE" OPEN_PAREN ... CLOSE_PAREN
-
- return ffestb_vxtcode9_; // to lexer
-
- Handle EOS or SEMICOLON here.
-
- 07-Jun-90 JCB 1.1
- Context for ENCODE/DECODE expressions is now IOLISTDF instead of IOLIST
- since they apply to internal files. */
-
-static ffelexHandler
-ffestb_vxtcode9_ (ffelexToken t)
-{
- ffelexHandler next;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- {
- if (ffesta_first_kw == FFESTR_firstENCODE)
- {
- ffestc_V023_start ();
- ffestc_V023_finish ();
- }
- else
- {
- ffestc_V024_start ();
- ffestc_V024_finish ();
- }
- }
- ffestb_subr_kill_vxtcode_ ();
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeNAME:
- case FFELEX_typeOPEN_PAREN:
- case FFELEX_typeCOMMA:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- if (ffesta_first_kw == FFESTR_firstENCODE)
- ffestc_V023_start ();
- else
- ffestc_V024_start ();
- ffestb_subr_kill_vxtcode_ ();
- if (ffesta_first_kw == FFESTR_firstDECODE)
- next = (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- FFEEXPR_contextIOLISTDF,
- (ffeexprCallback) ffestb_vxtcode10_);
- else
- next = (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextIOLISTDF,
- (ffeexprCallback) ffestb_vxtcode10_);
-
- /* EXTENSION: Allow an optional preceding COMMA here if not pedantic.
- (f2c provides this extension, as do other compilers, supposedly.) */
-
- if (!ffe_is_pedantic () && (ffelex_token_type (t) == FFELEX_typeCOMMA))
- return next;
-
- return (ffelexHandler) (*next) (t);
-
- default:
- break;
- }
-
- ffestb_subr_kill_vxtcode_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_vxtcode10_ -- "VXTCODE(...)" expr
-
- (ffestb_vxtcode10_) // to expression handler
-
- Handle COMMA or EOS/SEMICOLON here.
-
- 07-Jun-90 JCB 1.1
- Context for ENCODE/DECODE expressions is now IOLISTDF instead of IOLIST
- since they apply to internal files. */
-
-static ffelexHandler
-ffestb_vxtcode10_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- if (expr == NULL)
- break;
- if (!ffesta_is_inhibited ())
- if (ffesta_first_kw == FFESTR_firstENCODE)
- ffestc_V023_item (expr, ft);
- else
- ffestc_V024_item (expr, ft);
- if (ffesta_first_kw == FFESTR_firstDECODE)
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- FFEEXPR_contextIOLISTDF,
- (ffeexprCallback) ffestb_vxtcode10_);
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextIOLISTDF,
- (ffeexprCallback) ffestb_vxtcode10_);
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (expr == NULL)
- break;
- if (!ffesta_is_inhibited ())
- {
- if (ffesta_first_kw == FFESTR_firstENCODE)
- {
- ffestc_V023_item (expr, ft);
- ffestc_V023_finish ();
- }
- else
- {
- ffestc_V024_item (expr, ft);
- ffestc_V024_finish ();
- }
- }
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- if (!ffesta_is_inhibited ())
- if (ffesta_first_kw == FFESTR_firstENCODE)
- ffestc_V023_finish ();
- else
- ffestc_V024_finish ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_R904 -- Parse an OPEN statement
return ffestb_R904; // to lexer
@@ -17183,728 +13365,6 @@ ffestb_R92311_ (ffelexToken ft, ffebld expr, ffelexToken t)
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_V018 -- Parse the REWRITE statement
-
- return ffestb_V018; // to lexer
-
- Make sure the statement has a valid form for the REWRITE
- statement. If it does, implement the statement. */
-
-#if FFESTR_VXT
-ffelexHandler
-ffestb_V018 (ffelexToken t)
-{
- ffestpRewriteIx ix;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstREWRITE)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeNAME:
- case FFELEX_typeNUMBER:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeOPEN_PAREN:
- for (ix = 0; ix < FFESTP_rewriteix; ++ix)
- ffestp_file.rewrite.rewrite_spec[ix].kw_or_val_present = FALSE;
- return (ffelexHandler) ffestb_V0181_;
- }
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstREWRITE)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeOPEN_PAREN:
- if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlREWRITE)
- goto bad_0; /* :::::::::::::::::::: */
-
- for (ix = 0; ix < FFESTP_rewriteix; ++ix)
- ffestp_file.rewrite.rewrite_spec[ix].kw_or_val_present = FALSE;
- return (ffelexHandler) ffestb_V0181_;
- }
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-}
-
-/* ffestb_V0181_ -- "REWRITE" OPEN_PAREN
-
- return ffestb_V0181_; // to lexer
-
- Handle expr construct (not NAME=expr construct) here. */
-
-static ffelexHandler
-ffestb_V0181_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0182_;
-
- default:
- return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0183_)))
- (t);
- }
-}
-
-/* ffestb_V0182_ -- "REWRITE" OPEN_PAREN NAME
-
- return ffestb_V0182_; // to lexer
-
- If EQUALS here, go to states that handle it. Else, send NAME and this
- token thru expression handler. */
-
-static ffelexHandler
-ffestb_V0182_ (ffelexToken t)
-{
- ffelexHandler next;
- ffelexToken nt;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEQUALS:
- nt = ffesta_tokens[1];
- next = (ffelexHandler) ffestb_V0187_ (nt);
- ffelex_token_kill (nt);
- return (ffelexHandler) (*next) (t);
-
- default:
- nt = ffesta_tokens[1];
- next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0183_)))
- (nt);
- ffelex_token_kill (nt);
- return (ffelexHandler) (*next) (t);
- }
-}
-
-/* ffestb_V0183_ -- "REWRITE" OPEN_PAREN expr [CLOSE_PAREN]
-
- (ffestb_V0183_) // to expression handler
-
- Handle COMMA or EOS/SEMICOLON here. */
-
-static ffelexHandler
-ffestb_V0183_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCLOSE_PAREN:
- if (expr == NULL)
- break;
- ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT].kw_or_val_present
- = TRUE;
- ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT].kw_present = FALSE;
- ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT].value_present = TRUE;
- ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT].value_is_label
- = FALSE;
- ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT].value
- = ffelex_token_use (ft);
- ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT].u.expr = expr;
- if (ffelex_token_type (t) == FFELEX_typeCOMMA)
- return (ffelexHandler) ffestb_V0184_;
- return (ffelexHandler) ffestb_V01812_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_rewrite_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0184_ -- "REWRITE" OPEN_PAREN expr COMMA
-
- return ffestb_V0184_; // to lexer
-
- Handle expr construct (not NAME=expr construct) here. */
-
-static ffelexHandler
-ffestb_V0184_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0185_;
-
- default:
- return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILEFORMAT, (ffeexprCallback) ffestb_V0186_)))
- (t);
- }
-}
-
-/* ffestb_V0185_ -- "REWRITE" OPEN_PAREN expr COMMA NAME
-
- return ffestb_V0185_; // to lexer
-
- If EQUALS here, go to states that handle it. Else, send NAME and this
- token thru expression handler. */
-
-static ffelexHandler
-ffestb_V0185_ (ffelexToken t)
-{
- ffelexHandler next;
- ffelexToken nt;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEQUALS:
- nt = ffesta_tokens[1];
- next = (ffelexHandler) ffestb_V0187_ (nt);
- ffelex_token_kill (nt);
- return (ffelexHandler) (*next) (t);
-
- default:
- nt = ffesta_tokens[1];
- next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILEFORMAT, (ffeexprCallback) ffestb_V0186_)))
- (nt);
- ffelex_token_kill (nt);
- return (ffelexHandler) (*next) (t);
- }
-}
-
-/* ffestb_V0186_ -- "REWRITE" OPEN_PAREN expr COMMA expr
-
- (ffestb_V0186_) // to expression handler
-
- Handle COMMA or CLOSE_PAREN here. */
-
-static ffelexHandler
-ffestb_V0186_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCLOSE_PAREN:
- ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw_or_val_present
- = TRUE;
- ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw_present = FALSE;
- ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].value_present = TRUE;
- ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].value_is_label
- = (expr == NULL);
- ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].value
- = ffelex_token_use (ft);
- ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].u.expr = expr;
- if (ffelex_token_type (t) == FFELEX_typeCOMMA)
- return (ffelexHandler) ffestb_V0187_;
- return (ffelexHandler) ffestb_V01812_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_rewrite_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0187_ -- "REWRITE" OPEN_PAREN [external-file-unit COMMA [format
- COMMA]]
-
- return ffestb_V0187_; // to lexer
-
- Handle expr construct (not NAME=expr construct) here. */
-
-static ffelexHandler
-ffestb_V0187_ (ffelexToken t)
-{
- ffestrGenio kw;
-
- ffestb_local_.rewrite.label = FALSE;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- kw = ffestr_genio (t);
- switch (kw)
- {
- case FFESTR_genioERR:
- ffestb_local_.rewrite.ix = FFESTP_rewriteixERR;
- ffestb_local_.rewrite.label = TRUE;
- break;
-
- case FFESTR_genioFMT:
- ffestb_local_.rewrite.ix = FFESTP_rewriteixFMT;
- ffestb_local_.rewrite.left = FALSE;
- ffestb_local_.rewrite.context = FFEEXPR_contextFILEFORMAT;
- break;
-
- case FFESTR_genioIOSTAT:
- ffestb_local_.rewrite.ix = FFESTP_rewriteixIOSTAT;
- ffestb_local_.rewrite.left = TRUE;
- ffestb_local_.rewrite.context = FFEEXPR_contextFILEINT;
- break;
-
- case FFESTR_genioUNIT:
- ffestb_local_.rewrite.ix = FFESTP_rewriteixUNIT;
- ffestb_local_.rewrite.left = FALSE;
- ffestb_local_.rewrite.context = FFEEXPR_contextFILENUM;
- break;
-
- default:
- goto bad; /* :::::::::::::::::::: */
- }
- if (ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix]
- .kw_or_val_present)
- break; /* Can't specify a keyword twice! */
- ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix]
- .kw_or_val_present = TRUE;
- ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix]
- .kw_present = TRUE;
- ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix]
- .value_present = FALSE;
- ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].value_is_label
- = ffestb_local_.rewrite.label;
- ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].kw
- = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0188_;
-
- default:
- break;
- }
-
-bad: /* :::::::::::::::::::: */
- ffestb_subr_kill_rewrite_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0188_ -- "REWRITE" OPEN_PAREN [external-file-unit COMMA [format
- COMMA]] NAME
-
- return ffestb_V0188_; // to lexer
-
- Make sure EQUALS here, send next token to expression handler. */
-
-static ffelexHandler
-ffestb_V0188_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEQUALS:
- ffesta_confirmed ();
- if (ffestb_local_.rewrite.label)
- return (ffelexHandler) ffestb_V01810_;
- if (ffestb_local_.rewrite.left)
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- ffestb_local_.rewrite.context,
- (ffeexprCallback) ffestb_V0189_);
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- ffestb_local_.rewrite.context,
- (ffeexprCallback) ffestb_V0189_);
-
- default:
- break;
- }
-
- ffestb_subr_kill_rewrite_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0189_ -- "REWRITE" OPEN_PAREN ... NAME EQUALS expr
-
- (ffestb_V0189_) // to expression handler
-
- Handle COMMA or CLOSE_PAREN here. */
-
-static ffelexHandler
-ffestb_V0189_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCLOSE_PAREN:
- if (expr == NULL)
- if (ffestb_local_.rewrite.context == FFEEXPR_contextFILEFORMAT)
- ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix]
- .value_is_label = TRUE;
- else
- break;
- ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].value_present
- = TRUE;
- ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].value
- = ffelex_token_use (ft);
- ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].u.expr = expr;
- if (ffelex_token_type (t) == FFELEX_typeCOMMA)
- return (ffelexHandler) ffestb_V0187_;
- return (ffelexHandler) ffestb_V01812_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_rewrite_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V01810_ -- "REWRITE" OPEN_PAREN ... NAME EQUALS
-
- return ffestb_V01810_; // to lexer
-
- Handle NUMBER for label here. */
-
-static ffelexHandler
-ffestb_V01810_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNUMBER:
- ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].value_present
- = TRUE;
- ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].value
- = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V01811_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_rewrite_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V01811_ -- "REWRITE" OPEN_PAREN ... NAME EQUALS NUMBER
-
- return ffestb_V01811_; // to lexer
-
- Handle COMMA or CLOSE_PAREN here. */
-
-static ffelexHandler
-ffestb_V01811_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- return (ffelexHandler) ffestb_V0187_;
-
- case FFELEX_typeCLOSE_PAREN:
- return (ffelexHandler) ffestb_V01812_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_rewrite_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V01812_ -- "REWRITE" OPEN_PAREN ... CLOSE_PAREN
-
- return ffestb_V01812_; // to lexer
-
- Handle EOS or SEMICOLON here. */
-
-static ffelexHandler
-ffestb_V01812_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- {
- ffestc_V018_start ();
- ffestc_V018_finish ();
- }
- ffestb_subr_kill_rewrite_ ();
- return (ffelexHandler) ffesta_zero (t);
-
- case FFELEX_typeNAME:
- case FFELEX_typeOPEN_PAREN:
- case FFELEX_typeCOMMA:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_V018_start ();
- ffestb_subr_kill_rewrite_ ();
-
- /* EXTENSION: Allow an optional preceding COMMA here if not pedantic.
- (f2c provides this extension, as do other compilers, supposedly.) */
-
- if (!ffe_is_pedantic () && (ffelex_token_type (t) == FFELEX_typeCOMMA))
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextIOLIST, (ffeexprCallback) ffestb_V01813_);
-
- return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextIOLIST, (ffeexprCallback) ffestb_V01813_)))
- (t);
-
- default:
- break;
- }
-
- ffestb_subr_kill_rewrite_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V01813_ -- "REWRITE(...)" expr
-
- (ffestb_V01813_) // to expression handler
-
- Handle COMMA or EOS/SEMICOLON here. */
-
-static ffelexHandler
-ffestb_V01813_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- if (expr == NULL)
- break;
- if (!ffesta_is_inhibited ())
- ffestc_V018_item (expr, ft);
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextIOLIST, (ffeexprCallback) ffestb_V01813_);
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (expr == NULL)
- break;
- if (!ffesta_is_inhibited ())
- {
- ffestc_V018_item (expr, ft);
- ffestc_V018_finish ();
- }
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_V018_finish ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V019 -- Parse the ACCEPT statement
-
- return ffestb_V019; // to lexer
-
- Make sure the statement has a valid form for the ACCEPT
- statement. If it does, implement the statement. */
-
-ffelexHandler
-ffestb_V019 (ffelexToken t)
-{
- ffelexHandler next;
- ffestpAcceptIx ix;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstACCEPT)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeEQUALS:
- case FFELEX_typePOINTS:
- case FFELEX_typeCOLON:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeNAME:
- case FFELEX_typeNUMBER:
- ffesta_confirmed ();
- break;
-
- default:
- break;
- }
-
- for (ix = 0; ix < FFESTP_acceptix; ++ix)
- ffestp_file.accept.accept_spec[ix].kw_or_val_present = FALSE;
- return (ffelexHandler) (*((ffelexHandler)
- ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_V0191_)))
- (t);
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstACCEPT)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- ffesta_confirmed ();
- if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlACCEPT)
- break;
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeEQUALS:
- case FFELEX_typePOINTS:
- case FFELEX_typeCOLON:
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- break;
- }
- for (ix = 0; ix < FFESTP_acceptix; ++ix)
- ffestp_file.accept.accept_spec[ix].kw_or_val_present = FALSE;
- next = (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_V0191_);
- next = (ffelexHandler) ffelex_splice_tokens (next, ffesta_tokens[0],
- FFESTR_firstlACCEPT);
- if (next == NULL)
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero);
- return (ffelexHandler) (*next) (t);
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ACCEPT", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ACCEPT", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-}
-
-/* ffestb_V0191_ -- "ACCEPT" expr
-
- (ffestb_V0191_) // to expression handler
-
- Make sure the next token is a COMMA or EOS/SEMICOLON. */
-
-static ffelexHandler
-ffestb_V0191_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- ffesta_confirmed ();
- ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT].kw_or_val_present
- = TRUE;
- ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT].kw_present = FALSE;
- ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT].value_present = TRUE;
- ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT].value_is_label
- = (expr == NULL);
- ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT].value
- = ffelex_token_use (ft);
- ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT].u.expr = expr;
- if (!ffesta_is_inhibited ())
- ffestc_V019_start ();
- ffestb_subr_kill_accept_ ();
- if (ffelex_token_type (t) == FFELEX_typeCOMMA)
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- FFEEXPR_contextIOLIST,
- (ffeexprCallback) ffestb_V0192_);
- if (!ffesta_is_inhibited ())
- ffestc_V019_finish ();
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- ffestb_subr_kill_accept_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ACCEPT", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0192_ -- "ACCEPT" expr COMMA expr
-
- (ffestb_V0192_) // to expression handler
-
- Handle COMMA or EOS/SEMICOLON here. */
-
-static ffelexHandler
-ffestb_V0192_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- if (expr == NULL)
- break;
- if (!ffesta_is_inhibited ())
- ffestc_V019_item (expr, ft);
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- FFEEXPR_contextIOLIST,
- (ffeexprCallback) ffestb_V0192_);
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (expr == NULL)
- break;
- if (!ffesta_is_inhibited ())
- {
- ffestc_V019_item (expr, ft);
- ffestc_V019_finish ();
- }
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_V019_finish ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ACCEPT", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_V020 -- Parse the TYPE statement
return ffestb_V020; // to lexer
@@ -18107,1294 +13567,6 @@ ffestb_V0202_ (ffelexToken ft, ffebld expr, ffelexToken t)
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_V021 -- Parse a DELETE statement
-
- return ffestb_V021; // to lexer
-
- Make sure the statement has a valid form for a DELETE statement.
- If it does, implement the statement. */
-
-#if FFESTR_VXT
-ffelexHandler
-ffestb_V021 (ffelexToken t)
-{
- ffestpDeleteIx ix;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstDELETE)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstDELETE)
- goto bad_0; /* :::::::::::::::::::: */
- if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlDELETE)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- break;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
-
- for (ix = 0; ix < FFESTP_deleteix; ++ix)
- ffestp_file.delete.delete_spec[ix].kw_or_val_present = FALSE;
-
- return (ffelexHandler) ffestb_V0211_;
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-}
-
-/* ffestb_V0211_ -- "DELETE" OPEN_PAREN
-
- return ffestb_V0211_; // to lexer
-
- Handle expr construct (not NAME=expr construct) here. */
-
-static ffelexHandler
-ffestb_V0211_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0212_;
-
- default:
- return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0213_)))
- (t);
- }
-}
-
-/* ffestb_V0212_ -- "DELETE" OPEN_PAREN NAME
-
- return ffestb_V0212_; // to lexer
-
- If EQUALS here, go to states that handle it. Else, send NAME and this
- token thru expression handler. */
-
-static ffelexHandler
-ffestb_V0212_ (ffelexToken t)
-{
- ffelexHandler next;
- ffelexToken nt;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEQUALS:
- nt = ffesta_tokens[1];
- next = (ffelexHandler) ffestb_V0214_ (nt);
- ffelex_token_kill (nt);
- return (ffelexHandler) (*next) (t);
-
- default:
- next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0213_)))
- (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) (*next) (t);
- }
-}
-
-/* ffestb_V0213_ -- "DELETE" OPEN_PAREN expr
-
- (ffestb_V0213_) // to expression handler
-
- Handle COMMA or DELETE_PAREN here. */
-
-static ffelexHandler
-ffestb_V0213_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCLOSE_PAREN:
- if (expr == NULL)
- break;
- ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT].kw_or_val_present
- = TRUE;
- ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT].kw_present = FALSE;
- ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT].value_present = TRUE;
- ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT].value_is_label
- = FALSE;
- ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT].value
- = ffelex_token_use (ft);
- ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT].u.expr = expr;
- if (ffelex_token_type (t) == FFELEX_typeCOMMA)
- return (ffelexHandler) ffestb_V0214_;
- return (ffelexHandler) ffestb_V0219_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_delete_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0214_ -- "DELETE" OPEN_PAREN [external-file-unit COMMA]
-
- return ffestb_V0214_; // to lexer
-
- Handle expr construct (not NAME=expr construct) here. */
-
-static ffelexHandler
-ffestb_V0214_ (ffelexToken t)
-{
- ffestrGenio kw;
-
- ffestb_local_.delete.label = FALSE;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- kw = ffestr_genio (t);
- switch (kw)
- {
- case FFESTR_genioERR:
- ffestb_local_.delete.ix = FFESTP_deleteixERR;
- ffestb_local_.delete.label = TRUE;
- break;
-
- case FFESTR_genioIOSTAT:
- ffestb_local_.delete.ix = FFESTP_deleteixIOSTAT;
- ffestb_local_.delete.left = TRUE;
- ffestb_local_.delete.context = FFEEXPR_contextFILEINT;
- break;
-
- case FFESTR_genioREC:
- ffestb_local_.delete.ix = FFESTP_deleteixREC;
- ffestb_local_.delete.left = FALSE;
- ffestb_local_.delete.context = FFEEXPR_contextFILENUM;
- break;
-
- case FFESTR_genioUNIT:
- ffestb_local_.delete.ix = FFESTP_deleteixUNIT;
- ffestb_local_.delete.left = FALSE;
- ffestb_local_.delete.context = FFEEXPR_contextFILENUM;
- break;
-
- default:
- goto bad; /* :::::::::::::::::::: */
- }
- if (ffestp_file.delete.delete_spec[ffestb_local_.delete.ix]
- .kw_or_val_present)
- break; /* Can't specify a keyword twice! */
- ffestp_file.delete.delete_spec[ffestb_local_.delete.ix]
- .kw_or_val_present = TRUE;
- ffestp_file.delete.delete_spec[ffestb_local_.delete.ix]
- .kw_present = TRUE;
- ffestp_file.delete.delete_spec[ffestb_local_.delete.ix]
- .value_present = FALSE;
- ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].value_is_label
- = ffestb_local_.delete.label;
- ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].kw
- = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0215_;
-
- default:
- break;
- }
-
-bad: /* :::::::::::::::::::: */
- ffestb_subr_kill_delete_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0215_ -- "DELETE" OPEN_PAREN [external-file-unit COMMA] NAME
-
- return ffestb_V0215_; // to lexer
-
- Make sure EQUALS here, send next token to expression handler. */
-
-static ffelexHandler
-ffestb_V0215_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEQUALS:
- ffesta_confirmed ();
- if (ffestb_local_.delete.label)
- return (ffelexHandler) ffestb_V0217_;
- if (ffestb_local_.delete.left)
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- ffestb_local_.delete.context,
- (ffeexprCallback) ffestb_V0216_);
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- ffestb_local_.delete.context, (ffeexprCallback) ffestb_V0216_);
-
- default:
- break;
- }
-
- ffestb_subr_kill_delete_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0216_ -- "DELETE" OPEN_PAREN ... NAME EQUALS expr
-
- (ffestb_V0216_) // to expression handler
-
- Handle COMMA or CLOSE_PAREN here. */
-
-static ffelexHandler
-ffestb_V0216_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCLOSE_PAREN:
- if (expr == NULL)
- break;
- ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].value_present
- = TRUE;
- ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].value
- = ffelex_token_use (ft);
- ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].u.expr = expr;
- if (ffelex_token_type (t) == FFELEX_typeCOMMA)
- return (ffelexHandler) ffestb_V0214_;
- return (ffelexHandler) ffestb_V0219_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_delete_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0217_ -- "DELETE" OPEN_PAREN ... NAME EQUALS
-
- return ffestb_V0217_; // to lexer
-
- Handle NUMBER for label here. */
-
-static ffelexHandler
-ffestb_V0217_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNUMBER:
- ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].value_present
- = TRUE;
- ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].value
- = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0218_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_delete_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0218_ -- "DELETE" OPEN_PAREN ... NAME EQUALS NUMBER
-
- return ffestb_V0218_; // to lexer
-
- Handle COMMA or CLOSE_PAREN here. */
-
-static ffelexHandler
-ffestb_V0218_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- return (ffelexHandler) ffestb_V0214_;
-
- case FFELEX_typeCLOSE_PAREN:
- return (ffelexHandler) ffestb_V0219_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_delete_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0219_ -- "DELETE" OPEN_PAREN ... CLOSE_PAREN
-
- return ffestb_V0219_; // to lexer
-
- Handle EOS or SEMICOLON here. */
-
-static ffelexHandler
-ffestb_V0219_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_V021 ();
- ffestb_subr_kill_delete_ ();
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- ffestb_subr_kill_delete_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V026 -- Parse a FIND statement
-
- return ffestb_V026; // to lexer
-
- Make sure the statement has a valid form for a FIND statement.
- If it does, implement the statement. */
-
-ffelexHandler
-ffestb_V026 (ffelexToken t)
-{
- ffestpFindIx ix;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstFIND)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstFIND)
- goto bad_0; /* :::::::::::::::::::: */
- if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlFIND)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- break;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
-
- for (ix = 0; ix < FFESTP_findix; ++ix)
- ffestp_file.find.find_spec[ix].kw_or_val_present = FALSE;
-
- return (ffelexHandler) ffestb_V0261_;
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-}
-
-/* ffestb_V0261_ -- "FIND" OPEN_PAREN
-
- return ffestb_V0261_; // to lexer
-
- Handle expr construct (not NAME=expr construct) here. */
-
-static ffelexHandler
-ffestb_V0261_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0262_;
-
- default:
- return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0263_)))
- (t);
- }
-}
-
-/* ffestb_V0262_ -- "FIND" OPEN_PAREN NAME
-
- return ffestb_V0262_; // to lexer
-
- If EQUALS here, go to states that handle it. Else, send NAME and this
- token thru expression handler. */
-
-static ffelexHandler
-ffestb_V0262_ (ffelexToken t)
-{
- ffelexHandler next;
- ffelexToken nt;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEQUALS:
- nt = ffesta_tokens[1];
- next = (ffelexHandler) ffestb_V0264_ (nt);
- ffelex_token_kill (nt);
- return (ffelexHandler) (*next) (t);
-
- default:
- next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0263_)))
- (ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) (*next) (t);
- }
-}
-
-/* ffestb_V0263_ -- "FIND" OPEN_PAREN expr
-
- (ffestb_V0263_) // to expression handler
-
- Handle COMMA or FIND_PAREN here. */
-
-static ffelexHandler
-ffestb_V0263_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCLOSE_PAREN:
- if (expr == NULL)
- break;
- ffestp_file.find.find_spec[FFESTP_findixUNIT].kw_or_val_present
- = TRUE;
- ffestp_file.find.find_spec[FFESTP_findixUNIT].kw_present = FALSE;
- ffestp_file.find.find_spec[FFESTP_findixUNIT].value_present = TRUE;
- ffestp_file.find.find_spec[FFESTP_findixUNIT].value_is_label
- = FALSE;
- ffestp_file.find.find_spec[FFESTP_findixUNIT].value
- = ffelex_token_use (ft);
- ffestp_file.find.find_spec[FFESTP_findixUNIT].u.expr = expr;
- if (ffelex_token_type (t) == FFELEX_typeCOMMA)
- return (ffelexHandler) ffestb_V0264_;
- return (ffelexHandler) ffestb_V0269_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_find_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0264_ -- "FIND" OPEN_PAREN [external-file-unit COMMA]
-
- return ffestb_V0264_; // to lexer
-
- Handle expr construct (not NAME=expr construct) here. */
-
-static ffelexHandler
-ffestb_V0264_ (ffelexToken t)
-{
- ffestrGenio kw;
-
- ffestb_local_.find.label = FALSE;
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- kw = ffestr_genio (t);
- switch (kw)
- {
- case FFESTR_genioERR:
- ffestb_local_.find.ix = FFESTP_findixERR;
- ffestb_local_.find.label = TRUE;
- break;
-
- case FFESTR_genioIOSTAT:
- ffestb_local_.find.ix = FFESTP_findixIOSTAT;
- ffestb_local_.find.left = TRUE;
- ffestb_local_.find.context = FFEEXPR_contextFILEINT;
- break;
-
- case FFESTR_genioREC:
- ffestb_local_.find.ix = FFESTP_findixREC;
- ffestb_local_.find.left = FALSE;
- ffestb_local_.find.context = FFEEXPR_contextFILENUM;
- break;
-
- case FFESTR_genioUNIT:
- ffestb_local_.find.ix = FFESTP_findixUNIT;
- ffestb_local_.find.left = FALSE;
- ffestb_local_.find.context = FFEEXPR_contextFILENUM;
- break;
-
- default:
- goto bad; /* :::::::::::::::::::: */
- }
- if (ffestp_file.find.find_spec[ffestb_local_.find.ix]
- .kw_or_val_present)
- break; /* Can't specify a keyword twice! */
- ffestp_file.find.find_spec[ffestb_local_.find.ix]
- .kw_or_val_present = TRUE;
- ffestp_file.find.find_spec[ffestb_local_.find.ix]
- .kw_present = TRUE;
- ffestp_file.find.find_spec[ffestb_local_.find.ix]
- .value_present = FALSE;
- ffestp_file.find.find_spec[ffestb_local_.find.ix].value_is_label
- = ffestb_local_.find.label;
- ffestp_file.find.find_spec[ffestb_local_.find.ix].kw
- = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0265_;
-
- default:
- break;
- }
-
-bad: /* :::::::::::::::::::: */
- ffestb_subr_kill_find_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0265_ -- "FIND" OPEN_PAREN [external-file-unit COMMA] NAME
-
- return ffestb_V0265_; // to lexer
-
- Make sure EQUALS here, send next token to expression handler. */
-
-static ffelexHandler
-ffestb_V0265_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEQUALS:
- ffesta_confirmed ();
- if (ffestb_local_.find.label)
- return (ffelexHandler) ffestb_V0267_;
- if (ffestb_local_.find.left)
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- ffestb_local_.find.context,
- (ffeexprCallback) ffestb_V0266_);
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- ffestb_local_.find.context,
- (ffeexprCallback) ffestb_V0266_);
-
- default:
- break;
- }
-
- ffestb_subr_kill_find_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0266_ -- "FIND" OPEN_PAREN ... NAME EQUALS expr
-
- (ffestb_V0266_) // to expression handler
-
- Handle COMMA or CLOSE_PAREN here. */
-
-static ffelexHandler
-ffestb_V0266_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCLOSE_PAREN:
- if (expr == NULL)
- break;
- ffestp_file.find.find_spec[ffestb_local_.find.ix].value_present
- = TRUE;
- ffestp_file.find.find_spec[ffestb_local_.find.ix].value
- = ffelex_token_use (ft);
- ffestp_file.find.find_spec[ffestb_local_.find.ix].u.expr = expr;
- if (ffelex_token_type (t) == FFELEX_typeCOMMA)
- return (ffelexHandler) ffestb_V0264_;
- return (ffelexHandler) ffestb_V0269_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_find_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0267_ -- "FIND" OPEN_PAREN ... NAME EQUALS
-
- return ffestb_V0267_; // to lexer
-
- Handle NUMBER for label here. */
-
-static ffelexHandler
-ffestb_V0267_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNUMBER:
- ffestp_file.find.find_spec[ffestb_local_.find.ix].value_present
- = TRUE;
- ffestp_file.find.find_spec[ffestb_local_.find.ix].value
- = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0268_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_find_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0268_ -- "FIND" OPEN_PAREN ... NAME EQUALS NUMBER
-
- return ffestb_V0268_; // to lexer
-
- Handle COMMA or CLOSE_PAREN here. */
-
-static ffelexHandler
-ffestb_V0268_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- return (ffelexHandler) ffestb_V0264_;
-
- case FFELEX_typeCLOSE_PAREN:
- return (ffelexHandler) ffestb_V0269_;
-
- default:
- break;
- }
-
- ffestb_subr_kill_find_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0269_ -- "FIND" OPEN_PAREN ... CLOSE_PAREN
-
- return ffestb_V0269_; // to lexer
-
- Handle EOS or SEMICOLON here. */
-
-static ffelexHandler
-ffestb_V0269_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_V026 ();
- ffestb_subr_kill_find_ ();
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- ffestb_subr_kill_find_ ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
-/* ffestb_dimlist -- Parse the ALLOCATABLE/POINTER/TARGET statement
-
- return ffestb_dimlist; // to lexer
-
- Make sure the statement has a valid form for the ALLOCATABLE/POINTER/
- TARGET statement. If it does, implement the statement. */
-
-#if FFESTR_F90
-ffelexHandler
-ffestb_dimlist (ffelexToken t)
-{
- ffeTokenLength i;
- const char *p;
- ffelexToken nt;
- ffelexHandler next;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- {
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_start ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_start ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_start ();
- break;
-
- default:
- assert (FALSE);
- }
- }
- ffestb_local_.dimlist.started = TRUE;
- return (ffelexHandler) ffestb_dimlist1_;
-
- case FFELEX_typeNAME:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- {
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_start ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_start ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_start ();
- break;
-
- default:
- assert (FALSE);
- }
- }
- ffestb_local_.dimlist.started = TRUE;
- return (ffelexHandler) ffestb_dimlist1_ (t);
- }
-
- case FFELEX_typeNAMES:
- p = ffelex_token_text (ffesta_tokens[0]) + (i = ffestb_args.dimlist.len);
- switch (ffelex_token_type (t))
- {
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- ffesta_confirmed ();
- if (!ffesrc_is_name_init (*p))
- goto bad_i; /* :::::::::::::::::::: */
- nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0);
- if (!ffesta_is_inhibited ())
- {
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_start ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_start ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_start ();
- break;
-
- default:
- assert (FALSE);
- }
- }
- ffestb_local_.dimlist.started = TRUE;
- next = (ffelexHandler) ffestb_dimlist1_ (nt);
- ffelex_token_kill (nt);
- return (ffelexHandler) (*next) (t);
-
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed ();
- if (*p != '\0')
- goto bad_i; /* :::::::::::::::::::: */
- if (!ffesta_is_inhibited ())
- {
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_start ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_start ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_start ();
- break;
-
- default:
- assert (FALSE);
- }
- }
- ffestb_local_.dimlist.started = TRUE;
- return (ffelexHandler) ffestb_dimlist1_;
-
- case FFELEX_typeOPEN_PAREN:
- if (!ffesrc_is_name_init (*p))
- goto bad_i; /* :::::::::::::::::::: */
- nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0);
- ffestb_local_.dimlist.started = FALSE;
- next = (ffelexHandler) ffestb_dimlist1_ (nt);
- ffelex_token_kill (nt);
- return (ffelexHandler) (*next) (t);
- }
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_i: /* :::::::::::::::::::: */
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, ffesta_tokens[0], i, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_dimlist1_ -- "ALLOCATABLE/POINTER/TARGET" [COLONCOLON]
-
- return ffestb_dimlist1_; // to lexer
-
- Handle NAME. */
-
-static ffelexHandler
-ffestb_dimlist1_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_dimlist2_;
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, t);
- break;
- }
-
- if (!ffesta_is_inhibited ())
- {
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_finish ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_finish ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_finish ();
- break;
-
- default:
- assert (FALSE);
- }
- }
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_dimlist2_ -- "ALLOCATABLE/POINTER/TARGET" ... NAME
-
- return ffestb_dimlist2_; // to lexer
-
- Handle OPEN_PAREN. */
-
-static ffelexHandler
-ffestb_dimlist2_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- ffestb_subrargs_.dim_list.dims = ffestt_dimlist_create ();
- ffestb_subrargs_.dim_list.handler = (ffelexHandler) ffestb_dimlist3_;
- ffestb_subrargs_.dim_list.pool = ffesta_output_pool;
- ffestb_subrargs_.dim_list.ctx = FFEEXPR_contextDIMLIST;
-#ifdef FFECOM_dimensionsMAX
- ffestb_subrargs_.dim_list.ndims = 0;
-#endif
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextDIMLIST, (ffeexprCallback) ffestb_subr_dimlist_);
-
- case FFELEX_typeCOMMA:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- {
- if (!ffestb_local_.dimlist.started)
- {
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_start ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_start ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_start ();
- break;
-
- default:
- assert (FALSE);
- }
- ffestb_local_.dimlist.started = TRUE;
- }
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_item (ffesta_tokens[1], NULL);
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_item (ffesta_tokens[1], NULL);
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_item (ffesta_tokens[1], NULL);
- break;
-
- default:
- assert (FALSE);
- }
- }
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffestb_dimlist4_;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- {
- if (!ffestb_local_.dimlist.started)
- {
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_start ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_start ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_start ();
- break;
-
- default:
- assert (FALSE);
- }
- }
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_item (ffesta_tokens[1], NULL);
- ffestc_R525_finish ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_item (ffesta_tokens[1], NULL);
- ffestc_R526_finish ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_item (ffesta_tokens[1], NULL);
- ffestc_R527_finish ();
- break;
-
- default:
- assert (FALSE);
- }
- }
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, t);
- break;
- }
-
- if (!ffesta_is_inhibited ())
- {
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_finish ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_finish ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_finish ();
- break;
-
- default:
- assert (FALSE);
- }
- }
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_dimlist3_ -- "ALLOCATABLE/POINTER/TARGET" ... NAME OPEN_PAREN
- dimlist CLOSE_PAREN
-
- return ffestb_dimlist3_; // to lexer
-
- Handle COMMA or EOS/SEMICOLON. */
-
-static ffelexHandler
-ffestb_dimlist3_ (ffelexToken t)
-{
- if (!ffestb_subrargs_.dim_list.ok)
- goto bad; /* :::::::::::::::::::: */
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- {
- if (!ffestb_local_.dimlist.started)
- {
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_start ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_start ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_start ();
- break;
-
- default:
- assert (FALSE);
- }
- ffestb_local_.dimlist.started = TRUE;
- }
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_item (ffesta_tokens[1],
- ffestb_subrargs_.dim_list.dims);
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_item (ffesta_tokens[1],
- ffestb_subrargs_.dim_list.dims);
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_item (ffesta_tokens[1],
- ffestb_subrargs_.dim_list.dims);
- break;
-
- default:
- assert (FALSE);
- }
- }
- ffelex_token_kill (ffesta_tokens[1]);
- ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims);
- return (ffelexHandler) ffestb_dimlist4_;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- {
- if (!ffestb_local_.dimlist.started)
- {
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_start ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_start ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_start ();
- break;
-
- default:
- assert (FALSE);
- }
- }
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_item (ffesta_tokens[1],
- ffestb_subrargs_.dim_list.dims);
- ffestc_R525_finish ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_item (ffesta_tokens[1],
- ffestb_subrargs_.dim_list.dims);
- ffestc_R526_finish ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_item (ffesta_tokens[1],
- ffestb_subrargs_.dim_list.dims);
- ffestc_R527_finish ();
- break;
-
- default:
- assert (FALSE);
- }
- }
- ffelex_token_kill (ffesta_tokens[1]);
- ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
-bad: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, t);
- if (ffestb_local_.dimlist.started && !ffesta_is_inhibited ())
- {
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_finish ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_finish ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_finish ();
- break;
-
- default:
- assert (FALSE);
- }
- }
- ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_dimlist4_ -- "ALLOCATABLE/POINTER/TARGET" ... COMMA
-
- return ffestb_dimlist4_; // to lexer
-
- Make sure we don't have EOS or SEMICOLON. */
-
-static ffelexHandler
-ffestb_dimlist4_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffesta_is_inhibited ())
- {
- switch (ffesta_first_kw)
- {
- case FFESTR_firstALLOCATABLE:
- ffestc_R525_finish ();
- break;
-
- case FFESTR_firstPOINTER:
- ffestc_R526_finish ();
- break;
-
- case FFESTR_firstTARGET:
- ffestc_R527_finish ();
- break;
-
- default:
- assert (FALSE);
- }
- }
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, t);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- return (ffelexHandler) ffestb_dimlist1_ (t);
- }
-}
-
-#endif
/* ffestb_dummy -- Parse an ENTRY/FUNCTION/SUBROUTINE statement
return ffestb_dummy; // to lexer
@@ -20220,146 +14392,6 @@ ffestb_R5477_ (ffelexToken t)
}
}
-/* ffestb_R624 -- Parse a NULLIFY statement
-
- return ffestb_R624; // to lexer
-
- Make sure the statement has a valid form for a NULLIFY
- statement. If it does, implement the statement.
-
- 31-May-90 JCB 2.0
- Rewrite to produce a list of expressions rather than just names; this
- eases semantic checking, putting it in expression handling where that
- kind of thing gets done anyway, and makes it easier to support more
- flexible extensions to Fortran 90 like NULLIFY(FOO%BAR). */
-
-#if FFESTR_F90
-ffelexHandler
-ffestb_R624 (ffelexToken t)
-{
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstNULLIFY)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstNULLIFY)
- goto bad_0; /* :::::::::::::::::::: */
- if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlNULLIFY)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- break;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- case FFELEX_typeNAME:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
-
- ffestb_local_.R624.exprs = ffestt_exprlist_create ();
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- FFEEXPR_contextNULLIFY,
- (ffeexprCallback) ffestb_R6241_);
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NULLIFY", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NULLIFY", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-}
-
-/* ffestb_R6241_ -- "NULLIFY" OPEN_PAREN expr
-
- return ffestb_R6241_; // to lexer
-
- Make sure the statement has a valid form for a NULLIFY statement. If it
- does, implement the statement.
-
- 31-May-90 JCB 2.0
- Rewrite to produce a list of expressions rather than just names; this
- eases semantic checking, putting it in expression handling where that
- kind of thing gets done anyway, and makes it easier to support more
- flexible extensions to Fortran 90 like NULLIFY(FOO%BAR). */
-
-static ffelexHandler
-ffestb_R6241_ (ffelexToken ft, ffebld expr, ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCLOSE_PAREN:
- if (expr == NULL)
- break;
- ffestt_exprlist_append (ffestb_local_.R624.exprs, expr,
- ffelex_token_use (t));
- return (ffelexHandler) ffestb_R6242_;
-
- case FFELEX_typeCOMMA:
- if (expr == NULL)
- break;
- ffestt_exprlist_append (ffestb_local_.R624.exprs, expr,
- ffelex_token_use (t));
- return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool,
- FFEEXPR_contextNULLIFY,
- (ffeexprCallback) ffestb_R6241_);
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NULLIFY", t);
- ffestt_exprlist_kill (ffestb_local_.R624.exprs);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_R6242_ -- "NULLIFY" OPEN_PAREN expr-list CLOSE_PAREN
-
- return ffestb_R6242_; // to lexer
-
- Make sure the statement has a valid form for a NULLIFY statement. If it
- does, implement the statement. */
-
-static ffelexHandler
-ffestb_R6242_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_R624 (ffestb_local_.R624.exprs);
- ffestt_exprlist_kill (ffestb_local_.R624.exprs);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NULLIFY", t);
- ffestt_exprlist_kill (ffestb_local_.R624.exprs);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_R1229 -- Parse a STMTFUNCTION statement
return ffestb_R1229; // to lexer
@@ -21004,496 +15036,6 @@ bad_i: /* :::::::::::::::::::: */
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_decl_recursive -- Parse the RECURSIVE FUNCTION statement
-
- return ffestb_decl_recursive; // to lexer
-
- Make sure the statement has a valid form for the RECURSIVE FUNCTION
- statement. If it does, implement the statement. */
-
-#if FFESTR_F90
-ffelexHandler
-ffestb_decl_recursive (ffelexToken t)
-{
- ffeTokenLength i;
- const char *p;
- ffelexToken nt;
- ffelexToken ot;
- ffelexHandler next;
- bool needfunc;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstRECURSIVE)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeNAME:
- break;
- }
- ffesta_confirmed ();
- ffestb_local_.decl.recursive = ffelex_token_use (ffesta_tokens[0]);
- switch (ffesta_second_kw)
- {
- case FFESTR_secondINTEGER:
- ffestb_local_.decl.type = FFESTP_typeINTEGER;
- return (ffelexHandler) ffestb_decl_recursive1_;
-
- case FFESTR_secondBYTE:
- ffestb_local_.decl.type = FFESTP_typeBYTE;
- return (ffelexHandler) ffestb_decl_recursive1_;
-
- case FFESTR_secondWORD:
- ffestb_local_.decl.type = FFESTP_typeWORD;
- return (ffelexHandler) ffestb_decl_recursive1_;
-
- case FFESTR_secondREAL:
- ffestb_local_.decl.type = FFESTP_typeREAL;
- return (ffelexHandler) ffestb_decl_recursive1_;
-
- case FFESTR_secondCOMPLEX:
- ffestb_local_.decl.type = FFESTP_typeCOMPLEX;
- return (ffelexHandler) ffestb_decl_recursive1_;
-
- case FFESTR_secondLOGICAL:
- ffestb_local_.decl.type = FFESTP_typeLOGICAL;
- return (ffelexHandler) ffestb_decl_recursive1_;
-
- case FFESTR_secondCHARACTER:
- ffestb_local_.decl.type = FFESTP_typeCHARACTER;
- return (ffelexHandler) ffestb_decl_recursive1_;
-
- case FFESTR_secondDOUBLE:
- return (ffelexHandler) ffestb_decl_recursive2_;
-
- case FFESTR_secondDOUBLEPRECISION:
- ffestb_local_.decl.type = FFESTP_typeDBLPRCSN;
- ffestb_local_.decl.kind = NULL;
- ffestb_local_.decl.kindt = NULL;
- ffestb_local_.decl.len = NULL;
- ffestb_local_.decl.lent = NULL;
- return (ffelexHandler) ffestb_decl_func_;
-
- case FFESTR_secondDOUBLECOMPLEX:
- ffestb_local_.decl.type = FFESTP_typeDBLCMPLX;
- ffestb_local_.decl.kind = NULL;
- ffestb_local_.decl.kindt = NULL;
- ffestb_local_.decl.len = NULL;
- ffestb_local_.decl.lent = NULL;
- return (ffelexHandler) ffestb_decl_func_;
-
- case FFESTR_secondTYPE:
- ffestb_local_.decl.type = FFESTP_typeTYPE;
- return (ffelexHandler) ffestb_decl_recursive3_;
-
- case FFESTR_secondFUNCTION:
- ffestb_local_.dummy.first_kw = FFESTR_firstFUNCTION;
- ffestb_local_.dummy.badname = "FUNCTION";
- ffestb_local_.dummy.is_subr = FALSE;
- return (ffelexHandler) ffestb_decl_recursive4_;
-
- case FFESTR_secondSUBROUTINE:
- ffestb_local_.dummy.first_kw = FFESTR_firstSUBROUTINE;
- ffestb_local_.dummy.badname = "SUBROUTINE";
- ffestb_local_.dummy.is_subr = TRUE;
- return (ffelexHandler) ffestb_decl_recursive4_;
-
- default:
- ffelex_token_kill (ffestb_local_.decl.recursive);
- goto bad_1; /* :::::::::::::::::::: */
- }
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstRECURSIVE)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- case FFELEX_typeASTERISK:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeEOS:
- ffesta_confirmed ();
- break;
-
- default:
- break;
- }
- p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlRECURSIVE);
- if (!ffesrc_is_name_init (*p))
- goto bad_0; /* :::::::::::::::::::: */
- ffestb_local_.decl.recursive
- = ffelex_token_name_from_names (ffesta_tokens[0], 0,
- FFESTR_firstlRECURSIVE);
- nt = ffelex_token_names_from_names (ffesta_tokens[0],
- FFESTR_firstlRECURSIVE, 0);
- switch (ffestr_first (nt))
- {
- case FFESTR_firstINTGR:
- p = ffelex_token_text (nt) + (i = FFESTR_firstlINTGR);
- ffestb_local_.decl.type = FFESTP_typeINTEGER;
- needfunc = FALSE;
- goto typefunc; /* :::::::::::::::::::: */
-
- case FFESTR_firstBYTE:
- p = ffelex_token_text (nt) + (i = FFESTR_firstlBYTE);
- ffestb_local_.decl.type = FFESTP_typeBYTE;
- needfunc = FALSE;
- goto typefunc; /* :::::::::::::::::::: */
-
- case FFESTR_firstWORD:
- p = ffelex_token_text (nt) + (i = FFESTR_firstlWORD);
- ffestb_local_.decl.type = FFESTP_typeWORD;
- needfunc = FALSE;
- goto typefunc; /* :::::::::::::::::::: */
-
- case FFESTR_firstREAL:
- p = ffelex_token_text (nt) + (i = FFESTR_firstlREAL);
- ffestb_local_.decl.type = FFESTP_typeREAL;
- needfunc = FALSE;
- goto typefunc; /* :::::::::::::::::::: */
-
- case FFESTR_firstCMPLX:
- p = ffelex_token_text (nt) + (i = FFESTR_firstlCMPLX);
- ffestb_local_.decl.type = FFESTP_typeCOMPLEX;
- needfunc = FALSE;
- goto typefunc; /* :::::::::::::::::::: */
-
- case FFESTR_firstLGCL:
- p = ffelex_token_text (nt) + (i = FFESTR_firstlLGCL);
- ffestb_local_.decl.type = FFESTP_typeLOGICAL;
- needfunc = FALSE;
- goto typefunc; /* :::::::::::::::::::: */
-
- case FFESTR_firstCHRCTR:
- p = ffelex_token_text (nt) + (i = FFESTR_firstlCHRCTR);
- ffestb_local_.decl.type = FFESTP_typeCHARACTER;
- needfunc = FALSE;
- goto typefunc; /* :::::::::::::::::::: */
-
- case FFESTR_firstDBLPRCSN:
- p = ffelex_token_text (nt) + (i = FFESTR_firstlDBLPRCSN);
- ffestb_local_.decl.type = FFESTP_typeDBLPRCSN;
- needfunc = TRUE;
- goto typefunc; /* :::::::::::::::::::: */
-
- case FFESTR_firstDBLCMPLX:
- p = ffelex_token_text (nt) + (i = FFESTR_firstlDBLCMPLX);
- ffestb_local_.decl.type = FFESTP_typeDBLCMPLX;
- needfunc = TRUE;
- goto typefunc; /* :::::::::::::::::::: */
-
- case FFESTR_firstTYPE:
- p = ffelex_token_text (nt) + (i = FFESTR_firstlTYPE);
- ffestb_local_.decl.type = FFESTP_typeTYPE;
- next = (ffelexHandler) ffestb_decl_recursive3_;
- break;
-
- case FFESTR_firstFUNCTION:
- p = ffelex_token_text (nt) + (i = FFESTR_firstlFUNCTION);
- ffestb_local_.dummy.first_kw = FFESTR_firstFUNCTION;
- ffestb_local_.dummy.badname = "FUNCTION";
- ffestb_local_.dummy.is_subr = FALSE;
- next = (ffelexHandler) ffestb_decl_recursive4_;
- break;
-
- case FFESTR_firstSUBROUTINE:
- p = ffelex_token_text (nt) + (i = FFESTR_firstlSUBROUTINE);
- ffestb_local_.dummy.first_kw = FFESTR_firstSUBROUTINE;
- ffestb_local_.dummy.badname = "SUBROUTINE";
- ffestb_local_.dummy.is_subr = TRUE;
- next = (ffelexHandler) ffestb_decl_recursive4_;
- break;
-
- default:
- ffelex_token_kill (ffestb_local_.decl.recursive);
- ffelex_token_kill (nt);
- goto bad_1; /* :::::::::::::::::::: */
- }
- if (*p == '\0')
- {
- ffelex_token_kill (nt);
- return (ffelexHandler) (*next) (t);
- }
- if (!ffesrc_is_name_init (*p))
- goto bad_i; /* :::::::::::::::::::: */
- ot = ffelex_token_name_from_names (nt, i, 0);
- ffelex_token_kill (nt);
- next = (ffelexHandler) (*next) (ot);
- ffelex_token_kill (ot);
- return (ffelexHandler) (*next) (t);
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
-typefunc: /* :::::::::::::::::::: */
- if (*p == '\0')
- {
- ffelex_token_kill (nt);
- if (needfunc) /* DOUBLE PRECISION or DOUBLE COMPLEX? */
- {
- ffelex_token_kill (ffestb_local_.decl.recursive);
- goto bad_1; /* :::::::::::::::::::: */
- }
- return (ffelexHandler) ffestb_decl_recursive1_ (t);
- }
- if (!ffesrc_is_name_init (*p))
- goto bad_i; /* :::::::::::::::::::: */
- ot = ffelex_token_names_from_names (nt, i, 0);
- ffelex_token_kill (nt);
- if (ffestr_first (ot) != FFESTR_firstFUNCTION)
- goto bad_o; /* :::::::::::::::::::: */
- p = ffelex_token_text (ot) + (i = FFESTR_firstlFUNCTION);
- if (!ffesrc_is_name_init (*p))
- goto bad_i; /* :::::::::::::::::::: */
- ffesta_tokens[1] = ffelex_token_name_from_names (ot, i, 0);
- ffelex_token_kill (ot);
- ffestb_local_.decl.kind = NULL;
- ffestb_local_.decl.kindt = NULL;
- ffestb_local_.decl.len = NULL;
- ffestb_local_.decl.lent = NULL;
- return (ffelexHandler) ffestb_decl_funcname_1_ (t);
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_i: /* :::::::::::::::::::: */
- ffelex_token_kill (ffestb_local_.decl.recursive);
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "type-declaration", nt, i, t);
- ffelex_token_kill (nt);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_o: /* :::::::::::::::::::: */
- ffelex_token_kill (ffestb_local_.decl.recursive);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", ot);
- ffelex_token_kill (ot);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_decl_recursive1_ -- "RECURSIVE" generic-type
-
- return ffestb_decl_recursive1_; // to lexer
-
- Handle ASTERISK, OPEN_PAREN, or NAME. */
-
-static ffelexHandler
-ffestb_decl_recursive1_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeASTERISK:
- ffesta_confirmed ();
- ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_func_;
- ffestb_local_.decl.badname = "TYPEFUNC";
- if (ffestb_local_.decl.type == FFESTP_typeCHARACTER)
- return (ffelexHandler) ffestb_decl_starlen_;
- return (ffelexHandler) ffestb_decl_starkind_;
-
- case FFELEX_typeOPEN_PAREN:
- ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_func_;
- ffestb_local_.decl.badname = "TYPEFUNC";
- if (ffestb_local_.decl.type == FFESTP_typeCHARACTER)
- {
- ffestb_local_.decl.kind = NULL;
- ffestb_local_.decl.kindt = NULL;
- ffestb_local_.decl.len = NULL;
- ffestb_local_.decl.lent = NULL;
- return (ffelexHandler) ffestb_decl_typeparams_;
- }
- return (ffelexHandler) ffestb_decl_kindparam_;
-
- case FFELEX_typeNAME:
- ffestb_local_.decl.kind = NULL;
- ffestb_local_.decl.kindt = NULL;
- ffestb_local_.decl.len = NULL;
- ffestb_local_.decl.lent = NULL;
- return (ffelexHandler) ffestb_decl_func_ (t);
-
- default:
- break;
- }
-
- if (ffestb_local_.decl.recursive != NULL)
- ffelex_token_kill (ffestb_local_.decl.recursive);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_decl_recursive2_ -- "RECURSIVE" "DOUBLE"
-
- return ffestb_decl_recursive2_; // to lexer
-
- Handle NAME. */
-
-static ffelexHandler
-ffestb_decl_recursive2_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- switch (ffestr_second (t))
- {
- case FFESTR_secondPRECISION:
- ffestb_local_.decl.type = FFESTP_typeDBLPRCSN;
- break;
-
- case FFESTR_secondCOMPLEX:
- ffestb_local_.decl.type = FFESTP_typeDBLCMPLX;
- break;
-
- default:
- goto bad; /* :::::::::::::::::::: */
- }
- ffestb_local_.decl.kind = NULL;
- ffestb_local_.decl.kindt = NULL;
- ffestb_local_.decl.len = NULL;
- ffestb_local_.decl.lent = NULL;
- return (ffelexHandler) ffestb_decl_func_;
-
- default:
- break;
- }
-
-bad: /* :::::::::::::::::::: */
- if (ffestb_local_.decl.recursive != NULL)
- ffelex_token_kill (ffestb_local_.decl.recursive);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_decl_recursive3_ -- "RECURSIVE" "TYPE"
-
- return ffestb_decl_recursive3_; // to lexer
-
- Handle OPEN_PAREN. */
-
-static ffelexHandler
-ffestb_decl_recursive3_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_func_;
- ffestb_local_.decl.badname = "TYPEFUNC";
- return (ffelexHandler) ffestb_decl_typetype1_;
-
- default:
- break;
- }
-
- if (ffestb_local_.decl.recursive != NULL)
- ffelex_token_kill (ffestb_local_.decl.recursive);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_decl_recursive4_ -- "RECURSIVE" "FUNCTION/SUBROUTINE"
-
- return ffestb_decl_recursive4_; // to lexer
-
- Handle OPEN_PAREN. */
-
-static ffelexHandler
-ffestb_decl_recursive4_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_dummy1_;
-
- default:
- break;
- }
-
- if (ffestb_local_.decl.recursive != NULL)
- ffelex_token_kill (ffestb_local_.decl.recursive);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
-/* ffestb_decl_typetype -- Parse the R426/R501/R1219 TYPE statement
-
- return ffestb_decl_typetype; // to lexer
-
- Make sure the statement has a valid form for the TYPE statement. If it
- does, implement the statement. */
-
-#if FFESTR_F90
-ffelexHandler
-ffestb_decl_typetype (ffelexToken t)
-{
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstTYPE)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstTYPE)
- goto bad_0; /* :::::::::::::::::::: */
- if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlTYPE)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- break;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOLONCOLON:/* Not COMMA: R424 "TYPE,PUBLIC::A". */
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
- }
-
- ffestb_local_.decl.recursive = NULL;
- ffestb_local_.decl.parameter = FALSE; /* No PARAMETER attribute seen. */
- ffestb_local_.decl.coloncolon = FALSE; /* No COLONCOLON seen. */
-
- ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_attrsp_;
- ffestb_local_.decl.badname = "type-declaration";
- return (ffelexHandler) ffestb_decl_typetype1_;
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-}
-
-#endif
/* ffestb_decl_attrs_ -- "type" [type parameters] COMMA
return ffestb_decl_attrs_; // to lexer
@@ -21508,14 +15050,6 @@ ffestb_decl_attrs_ (ffelexToken t)
case FFELEX_typeNAME:
switch (ffestr_first (t))
{
-#if FFESTR_F90
- case FFESTR_firstALLOCATABLE:
- if (!ffesta_is_inhibited ())
- ffestc_decl_attrib (FFESTP_attribALLOCATABLE, t,
- FFESTR_otherNone, NULL);
- return (ffelexHandler) ffestb_decl_attrs_7_;
-#endif
-
case FFESTR_firstDIMENSION:
ffesta_tokens[1] = ffelex_token_use (t);
return (ffelexHandler) ffestb_decl_attrs_1_;
@@ -21526,26 +15060,12 @@ ffestb_decl_attrs_ (ffelexToken t)
FFESTR_otherNone, NULL);
return (ffelexHandler) ffestb_decl_attrs_7_;
-#if FFESTR_F90
- case FFESTR_firstINTENT:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_decl_attrs_3_;
-#endif
-
case FFESTR_firstINTRINSIC:
if (!ffesta_is_inhibited ())
ffestc_decl_attrib (FFESTP_attribINTRINSIC, t,
FFESTR_otherNone, NULL);
return (ffelexHandler) ffestb_decl_attrs_7_;
-#if FFESTR_F90
- case FFESTR_firstOPTIONAL:
- if (!ffesta_is_inhibited ())
- ffestc_decl_attrib (FFESTP_attribOPTIONAL, t,
- FFESTR_otherNone, NULL);
- return (ffelexHandler) ffestb_decl_attrs_7_;
-#endif
-
case FFESTR_firstPARAMETER:
ffestb_local_.decl.parameter = TRUE;
if (!ffesta_is_inhibited ())
@@ -21553,42 +15073,12 @@ ffestb_decl_attrs_ (ffelexToken t)
FFESTR_otherNone, NULL);
return (ffelexHandler) ffestb_decl_attrs_7_;
-#if FFESTR_F90
- case FFESTR_firstPOINTER:
- if (!ffesta_is_inhibited ())
- ffestc_decl_attrib (FFESTP_attribPOINTER, t,
- FFESTR_otherNone, NULL);
- return (ffelexHandler) ffestb_decl_attrs_7_;
-#endif
-
-#if FFESTR_F90
- case FFESTR_firstPRIVATE:
- if (!ffesta_is_inhibited ())
- ffestc_decl_attrib (FFESTP_attribPRIVATE, t,
- FFESTR_otherNone, NULL);
- return (ffelexHandler) ffestb_decl_attrs_7_;
-
- case FFESTR_firstPUBLIC:
- if (!ffesta_is_inhibited ())
- ffestc_decl_attrib (FFESTP_attribPUBLIC, t,
- FFESTR_otherNone, NULL);
- return (ffelexHandler) ffestb_decl_attrs_7_;
-#endif
-
case FFESTR_firstSAVE:
if (!ffesta_is_inhibited ())
ffestc_decl_attrib (FFESTP_attribSAVE, t,
FFESTR_otherNone, NULL);
return (ffelexHandler) ffestb_decl_attrs_7_;
-#if FFESTR_F90
- case FFESTR_firstTARGET:
- if (!ffesta_is_inhibited ())
- ffestc_decl_attrib (FFESTP_attribTARGET, t,
- FFESTR_otherNone, NULL);
- return (ffelexHandler) ffestb_decl_attrs_7_;
-#endif
-
default:
ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_ATTR, t);
return (ffelexHandler) ffestb_decl_attrs_7_;
@@ -21683,155 +15173,6 @@ bad: /* :::::::::::::::::::: */
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_decl_attrs_3_ -- "type" [type parameters] ",INTENT"
-
- return ffestb_decl_attrs_3_; // to lexer
-
- Handle OPEN_PAREN. */
-
-#if FFESTR_F90
-static ffelexHandler
-ffestb_decl_attrs_3_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- return (ffelexHandler) ffestb_decl_attrs_4_;
-
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_ATTR, ffesta_tokens[1]);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffestb_decl_attrs_7_ (t);
-
- default:
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_decl_finish ();
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_ATTR, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_decl_attrs_4_ -- "type" [type parameters] ",INTENT" OPEN_PAREN
-
- return ffestb_decl_attrs_4_; // to lexer
-
- Handle NAME. */
-
-static ffelexHandler
-ffestb_decl_attrs_4_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffestb_local_.decl.kw = ffestr_other (t);
- switch (ffestb_local_.decl.kw)
- {
- case FFESTR_otherIN:
- return (ffelexHandler) ffestb_decl_attrs_5_;
-
- case FFESTR_otherINOUT:
- return (ffelexHandler) ffestb_decl_attrs_6_;
-
- case FFESTR_otherOUT:
- return (ffelexHandler) ffestb_decl_attrs_6_;
-
- default:
- ffestb_local_.decl.kw = FFESTR_otherNone;
- ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_ATTR, t);
- return (ffelexHandler) ffestb_decl_attrs_5_;
- }
- break;
-
- default:
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_decl_finish ();
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_decl_attrs_5_ -- "type" [type parameters] ",INTENT" OPEN_PAREN "IN"
-
- return ffestb_decl_attrs_5_; // to lexer
-
- Handle NAME or CLOSE_PAREN. */
-
-static ffelexHandler
-ffestb_decl_attrs_5_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- switch (ffestr_other (t))
- {
- case FFESTR_otherOUT:
- if (ffestb_local_.decl.kw != FFESTR_otherNone)
- ffestb_local_.decl.kw = FFESTR_otherINOUT;
- return (ffelexHandler) ffestb_decl_attrs_6_;
-
- default:
- if (ffestb_local_.decl.kw != FFESTR_otherNone)
- {
- ffestb_local_.decl.kw = FFESTR_otherNone;
- ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_ATTR, t);
- }
- return (ffelexHandler) ffestb_decl_attrs_5_;
- }
- break;
-
- case FFELEX_typeCLOSE_PAREN:
- return (ffelexHandler) ffestb_decl_attrs_6_ (t);
-
- default:
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_decl_finish ();
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_decl_attrs_6_ -- "type" [type parameters] ",INTENT" OPEN_PAREN "IN"
- ["OUT"]
-
- return ffestb_decl_attrs_6_; // to lexer
-
- Handle CLOSE_PAREN. */
-
-static ffelexHandler
-ffestb_decl_attrs_6_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCLOSE_PAREN:
- if ((ffestb_local_.decl.kw != FFESTR_otherNone)
- && !ffesta_is_inhibited ())
- ffestc_decl_attrib (FFESTP_attribINTENT, ffesta_tokens[1],
- ffestb_local_.decl.kw, NULL);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffestb_decl_attrs_7_;
-
- default:
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_decl_finish ();
- ffelex_token_kill (ffesta_tokens[1]);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_decl_attrs_7_ -- "type" [type parameters] attribute
return ffestb_decl_attrs_7_; // to lexer
@@ -22616,17 +15957,6 @@ ffestb_decl_entsp_1_ (ffelexToken t)
case FFELEX_typeNAME:
switch (ffestr_first (ffesta_tokens[1]))
{
-#if FFESTR_F90
- case FFESTR_firstRECURSIVE:
- if (ffestr_first (t) != FFESTR_firstFUNCTION)
- {
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t);
- break;
- }
- ffestb_local_.decl.recursive = ffesta_tokens[1];
- return (ffelexHandler) ffestb_decl_funcname_;
-#endif
-
case FFESTR_firstFUNCTION:
ffelex_token_kill (ffesta_tokens[1]);
return (ffelexHandler) ffestb_decl_funcname_ (t);
@@ -22702,23 +16032,6 @@ ffestb_decl_entsp_2_ (ffelexToken t)
}
switch (ffestr_first (ffesta_tokens[1]))
{
-#if FFESTR_F90
- case FFESTR_firstRECURSIVEFNCTN:
- if (!asterisk_ok)
- break; /* For our own convenience, treat as non-FN
- stmt. */
- p = ffelex_token_text (ffesta_tokens[1])
- + (i = FFESTR_firstlRECURSIVEFNCTN);
- if (!ffesrc_is_name_init (*p))
- break;
- ffestb_local_.decl.recursive
- = ffelex_token_name_from_names (ffesta_tokens[1], 0,
- FFESTR_firstlRECURSIVEFNCTN);
- ffesta_tokens[2] = ffelex_token_name_from_names (ffesta_tokens[1],
- FFESTR_firstlRECURSIVEFNCTN, 0);
- return (ffelexHandler) ffestb_decl_entsp_3_;
-#endif
-
case FFESTR_firstFUNCTION:
if (!asterisk_ok)
break; /* For our own convenience, treat as non-FN
@@ -22741,20 +16054,6 @@ ffestb_decl_entsp_2_ (ffelexToken t)
ffestb_local_.decl.aster_after = FALSE;
switch (ffestr_first (ffesta_tokens[1]))
{
-#if FFESTR_F90
- case FFESTR_firstRECURSIVEFNCTN:
- p = ffelex_token_text (ffesta_tokens[1])
- + (i = FFESTR_firstlRECURSIVEFNCTN);
- if (!ffesrc_is_name_init (*p))
- break;
- ffestb_local_.decl.recursive
- = ffelex_token_name_from_names (ffesta_tokens[1], 0,
- FFESTR_firstlRECURSIVEFNCTN);
- ffesta_tokens[2] = ffelex_token_name_from_names (ffesta_tokens[1],
- FFESTR_firstlRECURSIVEFNCTN, 0);
- return (ffelexHandler) ffestb_decl_entsp_5_ (t);
-#endif
-
case FFESTR_firstFUNCTION:
p = ffelex_token_text (ffesta_tokens[1])
+ (i = FFESTR_firstlFUNCTION);
@@ -23091,65 +16390,6 @@ ffestb_decl_entsp_8_ (ffelexToken t)
return (ffelexHandler) (*next) (t);
}
-/* ffestb_decl_func_ -- ["type" [type parameters]] RECURSIVE
-
- return ffestb_decl_func_; // to lexer
-
- Handle "FUNCTION". */
-
-#if FFESTR_F90
-static ffelexHandler
-ffestb_decl_func_ (ffelexToken t)
-{
- const char *p;
- ffeTokenLength i;
-
- ffelex_set_names (FALSE);
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- if (ffestr_first (t) != FFESTR_firstFUNCTION)
- break;
- return (ffelexHandler) ffestb_decl_funcname_;
-
- case FFELEX_typeNAMES:
- ffesta_confirmed ();
- if (ffestr_first (t) != FFESTR_firstFUNCTION)
- break;
- p = ffelex_token_text (t) + (i = FFESTR_firstlFUNCTION);
- if (*p == '\0')
- break;
- if (!ffesrc_is_name_init (*p))
- goto bad_i; /* :::::::::::::::::::: */
- ffesta_tokens[1] = ffelex_token_name_from_names (t, i, 0);
- return (ffelexHandler) ffestb_decl_funcname_1_;
-
- default:
- break;
- }
-
- if (ffestb_local_.decl.recursive != NULL)
- ffelex_token_kill (ffestb_local_.decl.recursive);
- if (ffestb_local_.decl.kindt != NULL)
- ffelex_token_kill (ffestb_local_.decl.kindt);
- if (ffestb_local_.decl.lent != NULL)
- ffelex_token_kill (ffestb_local_.decl.lent);
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_i: /* :::::::::::::::::::: */
- if (ffestb_local_.decl.recursive != NULL)
- ffelex_token_kill (ffestb_local_.decl.recursive);
- if (ffestb_local_.decl.kindt != NULL)
- ffelex_token_kill (ffestb_local_.decl.kindt);
- if (ffestb_local_.decl.lent != NULL)
- ffelex_token_kill (ffestb_local_.decl.lent);
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t, i, NULL);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_decl_funcname_ -- "type" [type parameters] [RECURSIVE] FUNCTION
return ffestb_decl_funcname_; // to lexer
@@ -23566,593 +16806,6 @@ ffestb_decl_funcname_9_ (ffelexToken t)
ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t);
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-
-/* ffestb_V003 -- Parse the STRUCTURE statement
-
- return ffestb_V003; // to lexer
-
- Make sure the statement has a valid form for the STRUCTURE statement.
- If it does, implement the statement. */
-
-#if FFESTR_VXT
-ffelexHandler
-ffestb_V003 (ffelexToken t)
-{
- ffeTokenLength i;
- const char *p;
- ffelexToken nt;
- ffelexHandler next;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstSTRUCTURE)
- goto bad_0; /* :::::::::::::::::::: */
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeNAME:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_V003_start (NULL);
- ffestb_local_.structure.started = TRUE;
- return (ffelexHandler) ffestb_V0034_ (t);
-
- case FFELEX_typeSLASH:
- ffesta_confirmed ();
- return (ffelexHandler) ffestb_V0031_;
- }
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstSTRUCTURE)
- goto bad_0; /* :::::::::::::::::::: */
- p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlSTRUCTURE);
- switch (ffelex_token_type (t))
- {
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOMMA:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed ();
- break;
-
- case FFELEX_typeSLASH:
- ffesta_confirmed ();
- if (*p != '\0')
- goto bad_1; /* :::::::::::::::::::: */
- return (ffelexHandler) ffestb_V0031_;
-
- case FFELEX_typeOPEN_PAREN:
- break;
- }
-
- /* Here, we have at least one char after "STRUCTURE" and t is COMMA,
- EOS/SEMICOLON, or OPEN_PAREN. */
-
- if (!ffesrc_is_name_init (*p))
- goto bad_i; /* :::::::::::::::::::: */
- nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0);
- if (ffelex_token_type (t) == FFELEX_typeOPEN_PAREN)
- ffestb_local_.structure.started = FALSE;
- else
- {
- if (!ffesta_is_inhibited ())
- ffestc_V003_start (NULL);
- ffestb_local_.structure.started = TRUE;
- }
- next = (ffelexHandler) ffestb_V0034_ (nt);
- ffelex_token_kill (nt);
- return (ffelexHandler) (*next) (t);
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_i: /* :::::::::::::::::::: */
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", ffesta_tokens[0], i, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0031_ -- "STRUCTURE" SLASH
-
- return ffestb_V0031_; // to lexer
-
- Handle NAME. */
-
-static ffelexHandler
-ffestb_V0031_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0032_;
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t);
- break;
- }
-
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0032_ -- "STRUCTURE" SLASH NAME
-
- return ffestb_V0032_; // to lexer
-
- Handle SLASH. */
-
-static ffelexHandler
-ffestb_V0032_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeSLASH:
- if (!ffesta_is_inhibited ())
- ffestc_V003_start (ffesta_tokens[1]);
- ffestb_local_.structure.started = TRUE;
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffestb_V0033_;
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t);
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0033_ -- "STRUCTURE" SLASH NAME SLASH
-
- return ffestb_V0033_; // to lexer
-
- Handle NAME or EOS/SEMICOLON. */
-
-static ffelexHandler
-ffestb_V0033_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- return (ffelexHandler) ffestb_V0034_ (t);
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffesta_is_inhibited ())
- ffestc_V003_finish ();
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t);
- break;
- }
-
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0034_ -- "STRUCTURE" [SLASH NAME SLASH]
-
- return ffestb_V0034_; // to lexer
-
- Handle NAME. */
-
-static ffelexHandler
-ffestb_V0034_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0035_;
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t);
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_V003_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0035_ -- "STRUCTURE" ... NAME
-
- return ffestb_V0035_; // to lexer
-
- Handle OPEN_PAREN. */
-
-static ffelexHandler
-ffestb_V0035_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- ffestb_subrargs_.dim_list.dims = ffestt_dimlist_create ();
- ffestb_subrargs_.dim_list.handler = (ffelexHandler) ffestb_V0036_;
- ffestb_subrargs_.dim_list.pool = ffesta_output_pool;
- ffestb_subrargs_.dim_list.ctx = FFEEXPR_contextDIMLISTCOMMON;
-#ifdef FFECOM_dimensionsMAX
- ffestb_subrargs_.dim_list.ndims = 0;
-#endif
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextDIMLISTCOMMON, (ffeexprCallback) ffestb_subr_dimlist_);
-
- case FFELEX_typeCOMMA:
- if (!ffesta_is_inhibited ())
- ffestc_V003_item (ffesta_tokens[1], NULL);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffestb_V0034_;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffesta_is_inhibited ())
- {
- ffestc_V003_item (ffesta_tokens[1], NULL);
- ffestc_V003_finish ();
- }
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t);
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_V003_finish ();
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0036_ -- "STRUCTURE" ... NAME OPEN_PAREN dimlist CLOSE_PAREN
-
- return ffestb_V0036_; // to lexer
-
- Handle COMMA or EOS/SEMICOLON. */
-
-static ffelexHandler
-ffestb_V0036_ (ffelexToken t)
-{
- if (!ffestb_subrargs_.dim_list.ok)
- goto bad; /* :::::::::::::::::::: */
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- {
- if (!ffestb_local_.structure.started)
- {
- ffestc_V003_start (NULL);
- ffestb_local_.structure.started = TRUE;
- }
- ffestc_V003_item (ffesta_tokens[1],
- ffestb_subrargs_.dim_list.dims);
- }
- ffelex_token_kill (ffesta_tokens[1]);
- ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims);
- return (ffelexHandler) ffestb_V0034_;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- {
- if (!ffestb_local_.structure.started)
- ffestc_V003_start (NULL);
- ffestc_V003_item (ffesta_tokens[1],
- ffestb_subrargs_.dim_list.dims);
- ffestc_V003_finish ();
- }
- ffelex_token_kill (ffesta_tokens[1]);
- ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
-bad: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t);
- if (ffestb_local_.structure.started && !ffesta_is_inhibited ())
- ffestc_V003_finish ();
- ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V016 -- Parse the RECORD statement
-
- return ffestb_V016; // to lexer
-
- Make sure the statement has a valid form for the RECORD statement. If it
- does, implement the statement. */
-
-ffelexHandler
-ffestb_V016 (ffelexToken t)
-{
- const char *p;
- ffeTokenLength i;
-
- switch (ffelex_token_type (ffesta_tokens[0]))
- {
- case FFELEX_typeNAME:
- if (ffesta_first_kw != FFESTR_firstRECORD)
- goto bad_0; /* :::::::::::::::::::: */
- break;
-
- case FFELEX_typeNAMES:
- if (ffesta_first_kw != FFESTR_firstRECORD)
- goto bad_0; /* :::::::::::::::::::: */
- p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlRECORD);
- if (*p != '\0')
- goto bad_i; /* :::::::::::::::::::: */
- break;
-
- default:
- goto bad_0; /* :::::::::::::::::::: */
- }
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- case FFELEX_typeCOLONCOLON:
- ffesta_confirmed (); /* Error, but clearly intended. */
- goto bad_1; /* :::::::::::::::::::: */
-
- default:
- goto bad_1; /* :::::::::::::::::::: */
-
- case FFELEX_typeSLASH:
- break;
- }
-
- ffesta_confirmed ();
- if (!ffesta_is_inhibited ())
- ffestc_V016_start ();
- return (ffelexHandler) ffestb_V0161_;
-
-bad_0: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", ffesta_tokens[0]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-
-bad_1: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t);
- return (ffelexHandler) ffelex_swallow_tokens (t,
- (ffelexHandler) ffesta_zero); /* Invalid second token. */
-
-bad_i: /* :::::::::::::::::::: */
- ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "RECORD", ffesta_tokens[0], i, t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0161_ -- "RECORD" SLASH
-
- return ffestb_V0161_; // to lexer
-
- Handle NAME. */
-
-static ffelexHandler
-ffestb_V0161_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- if (!ffesta_is_inhibited ())
- ffestc_V016_item_structure (t);
- return (ffelexHandler) ffestb_V0162_;
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t);
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_V016_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0162_ -- "RECORD" SLASH NAME
-
- return ffestb_V0162_; // to lexer
-
- Handle SLASH. */
-
-static ffelexHandler
-ffestb_V0162_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeSLASH:
- return (ffelexHandler) ffestb_V0163_;
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t);
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_V016_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0163_ -- "RECORD" SLASH NAME SLASH
-
- return ffestb_V0163_; // to lexer
-
- Handle NAME. */
-
-static ffelexHandler
-ffestb_V0163_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0164_;
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t);
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_V016_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0164_ -- "RECORD" ... NAME
-
- return ffestb_V0164_; // to lexer
-
- Handle OPEN_PAREN. */
-
-static ffelexHandler
-ffestb_V0164_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- ffestb_subrargs_.dim_list.dims = ffestt_dimlist_create ();
- ffestb_subrargs_.dim_list.handler = (ffelexHandler) ffestb_V0165_;
- ffestb_subrargs_.dim_list.pool = ffesta_output_pool;
- ffestb_subrargs_.dim_list.ctx = FFEEXPR_contextDIMLISTCOMMON;
-#ifdef FFECOM_dimensionsMAX
- ffestb_subrargs_.dim_list.ndims = 0;
-#endif
- return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool,
- FFEEXPR_contextDIMLISTCOMMON, (ffeexprCallback) ffestb_subr_dimlist_);
-
- case FFELEX_typeCOMMA:
- if (!ffesta_is_inhibited ())
- ffestc_V016_item_object (ffesta_tokens[1], NULL);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffestb_V0166_;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffesta_is_inhibited ())
- {
- ffestc_V016_item_object (ffesta_tokens[1], NULL);
- ffestc_V016_finish ();
- }
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t);
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_V016_finish ();
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0165_ -- "RECORD" ... NAME OPEN_PAREN dimlist CLOSE_PAREN
-
- return ffestb_V0165_; // to lexer
-
- Handle COMMA or EOS/SEMICOLON. */
-
-static ffelexHandler
-ffestb_V0165_ (ffelexToken t)
-{
- if (!ffestb_subrargs_.dim_list.ok)
- goto bad; /* :::::::::::::::::::: */
-
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeCOMMA:
- if (!ffesta_is_inhibited ())
- ffestc_V016_item_object (ffesta_tokens[1],
- ffestb_subrargs_.dim_list.dims);
- ffelex_token_kill (ffesta_tokens[1]);
- ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims);
- return (ffelexHandler) ffestb_V0166_;
-
- case FFELEX_typeEOS:
- case FFELEX_typeSEMICOLON:
- if (!ffesta_is_inhibited ())
- {
- ffestc_V016_item_object (ffesta_tokens[1],
- ffestb_subrargs_.dim_list.dims);
- ffestc_V016_finish ();
- }
- ffelex_token_kill (ffesta_tokens[1]);
- ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims);
- return (ffelexHandler) ffesta_zero (t);
-
- default:
- break;
- }
-
-bad: /* :::::::::::::::::::: */
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t);
- if (ffestb_local_.structure.started && !ffesta_is_inhibited ())
- ffestc_V016_finish ();
- ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims);
- ffelex_token_kill (ffesta_tokens[1]);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-/* ffestb_V0166_ -- "RECORD" SLASH NAME SLASH NAME [OPEN_PAREN dimlist
- CLOSE_PAREN] COMMA
-
- return ffestb_V0166_; // to lexer
-
- Handle NAME or SLASH. */
-
-static ffelexHandler
-ffestb_V0166_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeNAME:
- ffesta_tokens[1] = ffelex_token_use (t);
- return (ffelexHandler) ffestb_V0164_;
-
- case FFELEX_typeSLASH:
- return (ffelexHandler) ffestb_V0161_;
-
- default:
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t);
- break;
- }
-
- if (!ffesta_is_inhibited ())
- ffestc_V016_finish ();
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_V027 -- Parse the VXT PARAMETER statement
return ffestb_V027; // to lexer
@@ -24423,12 +17076,6 @@ ffestb_decl_R539 (ffelexToken t)
case FFESTR_secondNONE:
return (ffelexHandler) ffestb_decl_R5394_;
-#if FFESTR_F90
- case FFESTR_secondTYPE:
- ffestb_local_.decl.type = FFESTP_typeTYPE;
- return (ffelexHandler) ffestb_decl_R5393_;
-#endif
-
default:
goto bad_1; /* :::::::::::::::::::: */
}
@@ -24509,12 +17156,6 @@ ffestb_decl_R539 (ffelexToken t)
case FFESTR_secondNONE:
return (ffelexHandler) ffestb_decl_R5394_ (t);
-#if FFESTR_F90
- case FFESTR_secondTYPE:
- ffestb_local_.decl.type = FFESTP_typeTYPE;
- return (ffelexHandler) ffestb_decl_R5393_ (t);
-#endif
-
default:
goto bad_1; /* :::::::::::::::::::: */
}
@@ -24619,34 +17260,6 @@ bad: /* :::::::::::::::::::: */
return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
}
-/* ffestb_decl_R5393_ -- "IMPLICIT" "TYPE"
-
- return ffestb_decl_R5393_; // to lexer
-
- Handle OPEN_PAREN. */
-
-#if FFESTR_F90
-static ffelexHandler
-ffestb_decl_R5393_ (ffelexToken t)
-{
- switch (ffelex_token_type (t))
- {
- case FFELEX_typeOPEN_PAREN:
- ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_R539letters_;
- ffestb_local_.decl.badname = "IMPLICIT";
- return (ffelexHandler) ffestb_decl_typetype1_;
-
- default:
- break;
- }
-
- if (ffestb_local_.decl.imp_started && !ffesta_is_inhibited ())
- ffestc_R539finish ();
- ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t);
- return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero);
-}
-
-#endif
/* ffestb_decl_R5394_ -- "IMPLICIT" "NONE"
return ffestb_decl_R5394_; // to lexer
@@ -24734,12 +17347,6 @@ ffestb_decl_R5395_ (ffelexToken t)
ffestb_local_.decl.lent = NULL;
return (ffelexHandler) ffestb_decl_R539letters_;
-#if FFESTR_F90
- case FFESTR_secondTYPE:
- ffestb_local_.decl.type = FFESTP_typeTYPE;
- return (ffelexHandler) ffestb_decl_R5393_;
-#endif
-
default:
break;
}
diff --git a/contrib/gcc/f/stb.h b/contrib/gcc/f/stb.h
index a9b3acc586c7..88cb7c5452bb 100644
--- a/contrib/gcc/f/stb.h
+++ b/contrib/gcc/f/stb.h
@@ -1,5 +1,5 @@
/* stb.h -- Private #include File (module.h template V1.0)
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -79,15 +79,6 @@ struct _ffestb_args_
ffeTokenLength len; /* Length of "STOP/PAUSE". */
}
halt;
-#if FFESTR_F90
- struct
- {
- const char *badname;
- ffeTokenLength len; /* Length of "ALLOCATE/DEALLOCATE". */
- ffeexprContext ctx; /* Either ALLOCATE or DEALLOCATE. */
- }
- heap;
-#endif
struct
{
const char *badname;
@@ -96,22 +87,6 @@ struct _ffestb_args_
PRIVATE". */
}
varlist;
-#if FFESTR_VXT
- struct
- {
- const char *badname;
- ffeTokenLength len; /* Length of "ENCODE/DECODE". */
- }
- vxtcode;
-#endif
-#if FFESTR_F90
- struct
- {
- const char *badname;
- ffeTokenLength len; /* Length of "ALLOCATABLE/POINTER/TARGET". */
- }
- dimlist;
-#endif
struct
{
const char *badname;
@@ -150,33 +125,9 @@ ffelexHandler ffestb_endxyz (ffelexToken t);
ffelexHandler ffestb_decl_gentype (ffelexToken t);
ffelexHandler ffestb_goto (ffelexToken t);
ffelexHandler ffestb_halt (ffelexToken t);
-#if FFESTR_F90
-ffelexHandler ffestb_heap (ffelexToken t);
-#endif
ffelexHandler ffestb_if (ffelexToken t);
ffelexHandler ffestb_let (ffelexToken t);
-#if FFESTR_F90
-ffelexHandler ffestb_module (ffelexToken t);
-#endif
-#if FFESTR_F90
-ffelexHandler ffestb_decl_recursive (ffelexToken t);
-#endif
-#if FFESTR_F90
-ffelexHandler ffestb_type (ffelexToken t);
-#endif
-#if FFESTR_F90
-ffelexHandler ffestb_decl_typetype (ffelexToken t);
-#endif
ffelexHandler ffestb_varlist (ffelexToken t);
-#if FFESTR_VXT
-ffelexHandler ffestb_vxtcode (ffelexToken t);
-#endif
-#if FFESTR_F90
-ffelexHandler ffestb_where (ffelexToken t);
-#endif
-#if HARD_F90
-ffelexHandler ffestb_R423B (ffelexToken t);
-#endif
ffelexHandler ffestb_R522 (ffelexToken t);
ffelexHandler ffestb_R524 (ffelexToken t);
ffelexHandler ffestb_R528 (ffelexToken t);
@@ -185,9 +136,6 @@ ffelexHandler ffestb_decl_R539 (ffelexToken t);
ffelexHandler ffestb_R542 (ffelexToken t);
ffelexHandler ffestb_R544 (ffelexToken t);
ffelexHandler ffestb_R547 (ffelexToken t);
-#if FFESTR_F90
-ffelexHandler ffestb_R624 (ffelexToken t);
-#endif
ffelexHandler ffestb_R809 (ffelexToken t);
ffelexHandler ffestb_R810 (ffelexToken t);
ffelexHandler ffestb_R834 (ffelexToken t);
@@ -203,36 +151,12 @@ ffelexHandler ffestb_R911 (ffelexToken t);
ffelexHandler ffestb_R923 (ffelexToken t);
ffelexHandler ffestb_R1001 (ffelexToken t);
ffelexHandler ffestb_R1102 (ffelexToken t);
-#if FFESTR_F90
-ffelexHandler ffestb_R1107 (ffelexToken t);
-#endif
-#if FFESTR_F90
-ffelexHandler ffestb_R1202 (ffelexToken t);
-#endif
ffelexHandler ffestb_R1212 (ffelexToken t);
ffelexHandler ffestb_R1227 (ffelexToken t);
-#if FFESTR_F90
-ffelexHandler ffestb_R1228 (ffelexToken t);
-#endif
ffelexHandler ffestb_R1229 (ffelexToken t);
ffelexHandler ffestb_S3P4 (ffelexToken t);
-#if FFESTR_VXT
-ffelexHandler ffestb_V003 (ffelexToken t);
-ffelexHandler ffestb_V009 (ffelexToken t);
-ffelexHandler ffestb_V012 (ffelexToken t);
-#endif
ffelexHandler ffestb_V014 (ffelexToken t);
-#if FFESTR_VXT
-ffelexHandler ffestb_V016 (ffelexToken t);
-ffelexHandler ffestb_V018 (ffelexToken t);
-ffelexHandler ffestb_V019 (ffelexToken t);
-#endif
ffelexHandler ffestb_V020 (ffelexToken t);
-#if FFESTR_VXT
-ffelexHandler ffestb_V021 (ffelexToken t);
-ffelexHandler ffestb_V025 (ffelexToken t);
-ffelexHandler ffestb_V026 (ffelexToken t);
-#endif
ffelexHandler ffestb_V027 (ffelexToken t);
/* Define macros. */
diff --git a/contrib/gcc/f/stc.c b/contrib/gcc/f/stc.c
index b9602c20a469..5f058135bbf6 100644
--- a/contrib/gcc/f/stc.c
+++ b/contrib/gcc/f/stc.c
@@ -170,15 +170,6 @@ union ffestc_local_u_
ffesymbol symbol; /* SFN symbol. */
}
sfunc;
-#if FFESTR_VXT
- struct
- {
- char list_state; /* 0=>no field names allowed, 1=>error
- reported already, 2=>field names req'd,
- 3=>have a field name. */
- }
- V003;
-#endif
}; /* Merge with the one in ffestc later. */
/* Static objects accessed by functions in this module. */
@@ -226,9 +217,6 @@ static bool ffestc_labelref_is_format_ (ffelexToken label_token,
ffelab *label);
static bool ffestc_labelref_is_loopend_ (ffelexToken label_token,
ffelab *label);
-#if FFESTR_F90
-static ffestcOrder_ ffestc_order_access_ (void);
-#endif
static ffestcOrder_ ffestc_order_actiondo_ (void);
static ffestcOrder_ ffestc_order_actionif_ (void);
static ffestcOrder_ ffestc_order_actionwhere_ (void);
@@ -236,17 +224,8 @@ static void ffestc_order_any_ (void);
static void ffestc_order_bad_ (void);
static ffestcOrder_ ffestc_order_blockdata_ (void);
static ffestcOrder_ ffestc_order_blockspec_ (void);
-#if FFESTR_F90
-static ffestcOrder_ ffestc_order_component_ (void);
-#endif
-#if FFESTR_F90
-static ffestcOrder_ ffestc_order_contains_ (void);
-#endif
static ffestcOrder_ ffestc_order_data_ (void);
static ffestcOrder_ ffestc_order_data77_ (void);
-#if FFESTR_F90
-static ffestcOrder_ ffestc_order_derivedtype_ (void);
-#endif
static ffestcOrder_ ffestc_order_do_ (void);
static ffestcOrder_ ffestc_order_entry_ (void);
static ffestcOrder_ ffestc_order_exec_ (void);
@@ -256,89 +235,26 @@ static ffestcOrder_ ffestc_order_iface_ (void);
static ffestcOrder_ ffestc_order_ifthen_ (void);
static ffestcOrder_ ffestc_order_implicit_ (void);
static ffestcOrder_ ffestc_order_implicitnone_ (void);
-#if FFESTR_F90
-static ffestcOrder_ ffestc_order_interface_ (void);
-#endif
-#if FFESTR_F90
-static ffestcOrder_ ffestc_order_map_ (void);
-#endif
-#if FFESTR_F90
-static ffestcOrder_ ffestc_order_module_ (void);
-#endif
static ffestcOrder_ ffestc_order_parameter_ (void);
static ffestcOrder_ ffestc_order_program_ (void);
static ffestcOrder_ ffestc_order_progspec_ (void);
-#if FFESTR_F90
-static ffestcOrder_ ffestc_order_record_ (void);
-#endif
static ffestcOrder_ ffestc_order_selectcase_ (void);
static ffestcOrder_ ffestc_order_sfunc_ (void);
-#if FFESTR_F90
-static ffestcOrder_ ffestc_order_spec_ (void);
-#endif
-#if FFESTR_VXT
-static ffestcOrder_ ffestc_order_structure_ (void);
-#endif
static ffestcOrder_ ffestc_order_subroutine_ (void);
-#if FFESTR_F90
-static ffestcOrder_ ffestc_order_type_ (void);
-#endif
static ffestcOrder_ ffestc_order_typedecl_ (void);
-#if FFESTR_VXT
-static ffestcOrder_ ffestc_order_union_ (void);
-#endif
static ffestcOrder_ ffestc_order_unit_ (void);
-#if FFESTR_F90
-static ffestcOrder_ ffestc_order_use_ (void);
-#endif
-#if FFESTR_VXT
-static ffestcOrder_ ffestc_order_vxtstructure_ (void);
-#endif
-#if FFESTR_F90
-static ffestcOrder_ ffestc_order_where_ (void);
-#endif
static void ffestc_promote_dummy_ (ffelexToken t);
static void ffestc_promote_execdummy_ (ffelexToken t);
static void ffestc_promote_sfdummy_ (ffelexToken t);
static void ffestc_shriek_begin_program_ (void);
-#if FFESTR_F90
-static void ffestc_shriek_begin_uses_ (void);
-#endif
static void ffestc_shriek_blockdata_ (bool ok);
static void ffestc_shriek_do_ (bool ok);
static void ffestc_shriek_end_program_ (bool ok);
-#if FFESTR_F90
-static void ffestc_shriek_end_uses_ (bool ok);
-#endif
static void ffestc_shriek_function_ (bool ok);
static void ffestc_shriek_if_ (bool ok);
static void ffestc_shriek_ifthen_ (bool ok);
-#if FFESTR_F90
-static void ffestc_shriek_interface_ (bool ok);
-#endif
-#if FFESTR_F90
-static void ffestc_shriek_map_ (bool ok);
-#endif
-#if FFESTR_F90
-static void ffestc_shriek_module_ (bool ok);
-#endif
static void ffestc_shriek_select_ (bool ok);
-#if FFESTR_VXT
-static void ffestc_shriek_structure_ (bool ok);
-#endif
static void ffestc_shriek_subroutine_ (bool ok);
-#if FFESTR_F90
-static void ffestc_shriek_type_ (bool ok);
-#endif
-#if FFESTR_VXT
-static void ffestc_shriek_union_ (bool ok);
-#endif
-#if FFESTR_F90
-static void ffestc_shriek_where_ (bool ok);
-#endif
-#if FFESTR_F90
-static void ffestc_shriek_wherethen_ (bool ok);
-#endif
static int ffestc_subr_binsrch_ (const char *const *list, int size,
ffestpFile *spec, const char *whine);
static ffestvFormat ffestc_subr_format_ (ffestpFile *spec);
@@ -377,13 +293,7 @@ static void ffestc_try_shriek_do_ (void);
|| ffestc_statelet_ == FFESTC_stateletITEM_); \
ffestc_statelet_ = FFESTC_stateletSIMPLE_
#define ffestc_order_action_() ffestc_order_exec_()
-#if FFESTR_F90
-#define ffestc_order_interfacespec_() ffestc_order_derivedtype_()
-#endif
#define ffestc_shriek_if_lost_ ffestc_shriek_if_
-#if FFESTR_F90
-#define ffestc_shriek_where_lost_ ffestc_shriek_where_
-#endif
/* ffestc_establish_declinfo_ -- Determine specific type/params info for entity
@@ -689,7 +599,7 @@ ffestc_establish_impletter_ (ffelexToken first, ffelexToken last)
ffestc_init_3(); */
void
-ffestc_init_3 ()
+ffestc_init_3 (void)
{
ffestv_save_state_ = FFESTV_savestateNONE;
ffestc_entry_num_ = 0;
@@ -704,7 +614,7 @@ ffestc_init_3 ()
defs, and statement function defs. */
void
-ffestc_init_4 ()
+ffestc_init_4 (void)
{
ffestc_saved_entry_num_ = ffestc_entry_num_;
ffestc_entry_num_ = 0;
@@ -773,7 +683,7 @@ ffestc_kindtype_star_ (ffeinfoBasictype bt, ffetargetCharacterSize val)
/* Define label as usable for anything without complaint. */
static void
-ffestc_labeldef_any_ ()
+ffestc_labeldef_any_ (void)
{
if ((ffesta_label_token == NULL)
|| !ffestc_labeldef_begin_ ())
@@ -790,7 +700,7 @@ ffestc_labeldef_any_ ()
ffestc_labeldef_begin_(); */
static bool
-ffestc_labeldef_begin_ ()
+ffestc_labeldef_begin_ (void)
{
ffelabValue label_value;
ffelab label;
@@ -847,7 +757,7 @@ ffestc_labeldef_begin_ ()
ffestc_labeldef_branch_begin_(); */
static void
-ffestc_labeldef_branch_begin_ ()
+ffestc_labeldef_branch_begin_ (void)
{
if ((ffesta_label_token == NULL)
|| (ffestc_shriek_after1_ != NULL)
@@ -931,7 +841,7 @@ ffestc_labeldef_branch_begin_ ()
which case they must issue a diagnostic). */
static void
-ffestc_labeldef_branch_end_ ()
+ffestc_labeldef_branch_end_ (void)
{
if (ffesta_label_token == NULL)
return;
@@ -955,7 +865,7 @@ ffestc_labeldef_branch_end_ ()
ffestc_labeldef_endif_(); */
static void
-ffestc_labeldef_endif_ ()
+ffestc_labeldef_endif_ (void)
{
if ((ffesta_label_token == NULL)
|| (ffestc_shriek_after1_ != NULL)
@@ -1044,7 +954,7 @@ ffestc_labeldef_endif_ ()
ffestc_labeldef_format_(); */
static void
-ffestc_labeldef_format_ ()
+ffestc_labeldef_format_ (void)
{
if ((ffesta_label_token == NULL)
|| (ffestc_shriek_after1_ != NULL))
@@ -1127,7 +1037,7 @@ ffestc_labeldef_format_ ()
ffestc_labeldef_invalid_(); */
static void
-ffestc_labeldef_invalid_ ()
+ffestc_labeldef_invalid_ (void)
{
if ((ffesta_label_token == NULL)
|| (ffestc_shriek_after1_ != NULL)
@@ -1152,7 +1062,7 @@ ffestc_labeldef_invalid_ ()
be in the "then" part of a logical IF, such as a block-IF statement. */
static void
-ffestc_labeldef_notloop_ ()
+ffestc_labeldef_notloop_ (void)
{
if (ffesta_label_token == NULL)
return;
@@ -1246,7 +1156,7 @@ ffestc_labeldef_notloop_ ()
loop-ending label. */
static void
-ffestc_labeldef_notloop_begin_ ()
+ffestc_labeldef_notloop_begin_ (void)
{
if ((ffesta_label_token == NULL)
|| (ffestc_shriek_after1_ != NULL)
@@ -1334,7 +1244,7 @@ ffestc_labeldef_notloop_begin_ ()
ffestc_labeldef_useless_(); */
static void
-ffestc_labeldef_useless_ ()
+ffestc_labeldef_useless_ (void)
{
if ((ffesta_label_token == NULL)
|| (ffestc_shriek_after1_ != NULL)
@@ -1834,65 +1744,13 @@ ffestc_labelref_is_loopend_ (ffelexToken label_token, ffelab *x_label)
return TRUE;
}
-/* ffestc_order_access_ -- Check ordering on <access> statement
-
- if (ffestc_order_access_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_F90
-static ffestcOrder_
-ffestc_order_access_ ()
-{
- recurse:
-
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateNIL:
- ffestc_shriek_begin_program_ ();
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateMODULE0:
- case FFESTV_stateMODULE1:
- case FFESTV_stateMODULE2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateMODULE3:
- return FFESTC_orderOK_;
-
- case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-#endif
/* ffestc_order_actiondo_ -- Check ordering on <actiondo> statement
if (ffestc_order_actiondo_() != FFESTC_orderOK_)
return; */
static ffestcOrder_
-ffestc_order_actiondo_ ()
+ffestc_order_actiondo_ (void)
{
recurse:
@@ -1918,16 +1776,10 @@ ffestc_order_actiondo_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
default:
@@ -1943,7 +1795,7 @@ ffestc_order_actiondo_ ()
return; */
static ffestcOrder_
-ffestc_order_actionif_ ()
+ffestc_order_actionif_ (void)
{
bool update;
@@ -1995,16 +1847,10 @@ recurse:
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
default:
@@ -2033,7 +1879,7 @@ recurse:
return; */
static ffestcOrder_
-ffestc_order_actionwhere_ ()
+ffestc_order_actionwhere_ (void)
{
bool update;
@@ -2082,9 +1928,6 @@ recurse:
return FFESTC_orderOK_;
case FFESTV_stateWHERE:
-#if FFESTR_F90
- ffestc_shriek_after1_ = ffestc_shriek_where_;
-#endif
return FFESTC_orderOK_;
case FFESTV_stateIF:
@@ -2092,9 +1935,6 @@ recurse:
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
default:
@@ -2121,7 +1961,7 @@ recurse:
doesn't produce any diagnostics. */
static void
-ffestc_order_any_ ()
+ffestc_order_any_ (void)
{
bool update;
@@ -2170,9 +2010,6 @@ recurse:
return;
case FFESTV_stateWHERE:
-#if FFESTR_F90
- ffestc_shriek_after1_ = ffestc_shriek_where_;
-#endif
return;
case FFESTV_stateIF:
@@ -2180,9 +2017,6 @@ recurse:
return;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
default:
@@ -2213,7 +2047,7 @@ recurse:
now. */
static void
-ffestc_order_bad_ ()
+ffestc_order_bad_ (void)
{
if (ffewhere_line_is_unknown (ffestw_line (ffestw_stack_top ())))
{
@@ -2239,7 +2073,7 @@ ffestc_order_bad_ ()
return; */
static ffestcOrder_
-ffestc_order_blockdata_ ()
+ffestc_order_blockdata_ (void)
{
recurse:
@@ -2254,16 +2088,10 @@ ffestc_order_blockdata_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -2283,7 +2111,7 @@ ffestc_order_blockdata_ ()
return; */
static ffestcOrder_
-ffestc_order_blockspec_ ()
+ffestc_order_blockspec_ (void)
{
recurse:
@@ -2336,118 +2164,10 @@ ffestc_order_blockspec_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-/* ffestc_order_component_ -- Check ordering on <component-decl> statement
-
- if (ffestc_order_component_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_F90
-static ffestcOrder_
-ffestc_order_component_ ()
-{
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateTYPE:
- case FFESTV_stateSTRUCTURE:
- case FFESTV_stateMAP:
- return FFESTC_orderOK_;
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
- ffestc_shriek_where_ (FALSE);
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-#endif
-/* ffestc_order_contains_ -- Check ordering on CONTAINS statement
-
- if (ffestc_order_contains_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_F90
-static ffestcOrder_
-ffestc_order_contains_ ()
-{
- recurse:
-
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateNIL:
- ffestc_shriek_begin_program_ ();
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_statePROGRAM0:
- case FFESTV_statePROGRAM1:
- case FFESTV_statePROGRAM2:
- case FFESTV_statePROGRAM3:
- case FFESTV_statePROGRAM4:
- ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM5);
- break;
-
- case FFESTV_stateSUBROUTINE0:
- case FFESTV_stateSUBROUTINE1:
- case FFESTV_stateSUBROUTINE2:
- case FFESTV_stateSUBROUTINE3:
- case FFESTV_stateSUBROUTINE4:
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE5);
- break;
-
- case FFESTV_stateFUNCTION0:
- case FFESTV_stateFUNCTION1:
- case FFESTV_stateFUNCTION2:
- case FFESTV_stateFUNCTION3:
- case FFESTV_stateFUNCTION4:
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION5);
- break;
-
- case FFESTV_stateMODULE0:
- case FFESTV_stateMODULE1:
- case FFESTV_stateMODULE2:
- case FFESTV_stateMODULE3:
- case FFESTV_stateMODULE4:
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE5);
- break;
-
- case FFESTV_stateUSE:
- ffestc_shriek_end_uses_ (TRUE);
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
- ffestc_shriek_where_ (FALSE);
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -2459,28 +2179,14 @@ ffestc_order_contains_ ()
ffestc_order_bad_ ();
return FFESTC_orderBAD_;
}
-
- switch (ffestw_state (ffestw_previous (ffestw_stack_top ())))
- {
- case FFESTV_stateNIL:
- ffestw_update (NULL);
- return FFESTC_orderOK_;
-
- default:
- ffestc_order_bad_ ();
- ffestw_update (NULL);
- return FFESTC_orderBAD_;
- }
}
-
-#endif
/* ffestc_order_data_ -- Check ordering on DATA statement
if (ffestc_order_data_() != FFESTC_orderOK_)
return; */
static ffestcOrder_
-ffestc_order_data_ ()
+ffestc_order_data_ (void)
{
recurse:
@@ -2534,16 +2240,10 @@ ffestc_order_data_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -2563,7 +2263,7 @@ ffestc_order_data_ ()
return; */
static ffestcOrder_
-ffestc_order_data77_ ()
+ffestc_order_data77_ (void)
{
recurse:
@@ -2619,16 +2319,10 @@ ffestc_order_data77_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -2641,86 +2335,13 @@ ffestc_order_data77_ ()
return FFESTC_orderBAD_;
}
}
-
-/* ffestc_order_derivedtype_ -- Check ordering on derived TYPE statement
-
- if (ffestc_order_derivedtype_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_F90
-static ffestcOrder_
-ffestc_order_derivedtype_ ()
-{
- recurse:
-
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateNIL:
- ffestc_shriek_begin_program_ ();
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_statePROGRAM0:
- case FFESTV_statePROGRAM1:
- case FFESTV_statePROGRAM2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateSUBROUTINE0:
- case FFESTV_stateSUBROUTINE1:
- case FFESTV_stateSUBROUTINE2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateFUNCTION0:
- case FFESTV_stateFUNCTION1:
- case FFESTV_stateFUNCTION2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateMODULE0:
- case FFESTV_stateMODULE1:
- case FFESTV_stateMODULE2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3);
- return FFESTC_orderOK_;
-
- case FFESTV_statePROGRAM3:
- case FFESTV_stateSUBROUTINE3:
- case FFESTV_stateFUNCTION3:
- case FFESTV_stateMODULE3:
- return FFESTC_orderOK_;
-
- case FFESTV_stateUSE:
- ffestc_shriek_end_uses_ (TRUE);
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
- ffestc_shriek_where_ (FALSE);
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-#endif
/* ffestc_order_do_ -- Check ordering on <do> statement
if (ffestc_order_do_() != FFESTC_orderOK_)
return; */
static ffestcOrder_
-ffestc_order_do_ ()
+ffestc_order_do_ (void)
{
switch (ffestw_state (ffestw_stack_top ()))
{
@@ -2729,9 +2350,6 @@ ffestc_order_do_ ()
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -2751,7 +2369,7 @@ ffestc_order_do_ ()
return; */
static ffestcOrder_
-ffestc_order_entry_ ()
+ffestc_order_entry_ (void)
{
recurse:
@@ -2780,16 +2398,10 @@ ffestc_order_entry_ ()
break;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -2822,7 +2434,7 @@ ffestc_order_entry_ ()
return; */
static ffestcOrder_
-ffestc_order_exec_ ()
+ffestc_order_exec_ (void)
{
bool update;
@@ -2870,16 +2482,10 @@ recurse:
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -2913,7 +2519,7 @@ recurse:
return; */
static ffestcOrder_
-ffestc_order_format_ ()
+ffestc_order_format_ (void)
{
recurse:
@@ -2958,16 +2564,10 @@ ffestc_order_format_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -2987,7 +2587,7 @@ ffestc_order_format_ ()
return; */
static ffestcOrder_
-ffestc_order_function_ ()
+ffestc_order_function_ (void)
{
recurse:
@@ -3002,16 +2602,10 @@ ffestc_order_function_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -3031,7 +2625,7 @@ ffestc_order_function_ ()
return; */
static ffestcOrder_
-ffestc_order_iface_ ()
+ffestc_order_iface_ (void)
{
switch (ffestw_state (ffestw_stack_top ()))
{
@@ -3045,9 +2639,6 @@ ffestc_order_iface_ ()
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -3067,7 +2658,7 @@ ffestc_order_iface_ ()
return; */
static ffestcOrder_
-ffestc_order_ifthen_ ()
+ffestc_order_ifthen_ (void)
{
switch (ffestw_state (ffestw_stack_top ()))
{
@@ -3076,9 +2667,6 @@ ffestc_order_ifthen_ ()
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -3098,7 +2686,7 @@ ffestc_order_ifthen_ ()
return; */
static ffestcOrder_
-ffestc_order_implicit_ ()
+ffestc_order_implicit_ (void)
{
recurse:
@@ -3146,16 +2734,10 @@ ffestc_order_implicit_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -3175,7 +2757,7 @@ ffestc_order_implicit_ ()
return; */
static ffestcOrder_
-ffestc_order_implicitnone_ ()
+ffestc_order_implicitnone_ (void)
{
recurse:
@@ -3216,47 +2798,10 @@ ffestc_order_implicitnone_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-/* ffestc_order_interface_ -- Check ordering on <interface> statement
-
- if (ffestc_order_interface_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_F90
-static ffestcOrder_
-ffestc_order_interface_ ()
-{
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateINTERFACE0:
- case FFESTV_stateINTERFACE1:
- return FFESTC_orderOK_;
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
- ffestc_shriek_where_ (FALSE);
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -3270,87 +2815,13 @@ ffestc_order_interface_ ()
}
}
-#endif
-/* ffestc_order_map_ -- Check ordering on <map> statement
-
- if (ffestc_order_map_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_VXT
-static ffestcOrder_
-ffestc_order_map_ ()
-{
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateMAP:
- return FFESTC_orderOK_;
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
- ffestc_shriek_where_ (FALSE);
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-#endif
-/* ffestc_order_module_ -- Check ordering on <module> statement
-
- if (ffestc_order_module_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_F90
-static ffestcOrder_
-ffestc_order_module_ ()
-{
- recurse:
-
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateMODULE0:
- case FFESTV_stateMODULE1:
- case FFESTV_stateMODULE2:
- case FFESTV_stateMODULE3:
- case FFESTV_stateMODULE4:
- case FFESTV_stateMODULE5:
- return FFESTC_orderOK_;
-
- case FFESTV_stateUSE:
- ffestc_shriek_end_uses_ (TRUE);
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
- ffestc_shriek_where_ (FALSE);
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-#endif
/* ffestc_order_parameter_ -- Check ordering on <parameter> statement
if (ffestc_order_parameter_() != FFESTC_orderOK_)
return; */
static ffestcOrder_
-ffestc_order_parameter_ ()
+ffestc_order_parameter_ (void)
{
recurse:
@@ -3407,16 +2878,10 @@ ffestc_order_parameter_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -3436,7 +2901,7 @@ ffestc_order_parameter_ ()
return; */
static ffestcOrder_
-ffestc_order_program_ ()
+ffestc_order_program_ (void)
{
recurse:
@@ -3455,16 +2920,10 @@ ffestc_order_program_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -3484,7 +2943,7 @@ ffestc_order_program_ ()
return; */
static ffestcOrder_
-ffestc_order_progspec_ ()
+ffestc_order_progspec_ (void)
{
recurse:
@@ -3544,16 +3003,10 @@ ffestc_order_progspec_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -3566,100 +3019,13 @@ ffestc_order_progspec_ ()
return FFESTC_orderBAD_;
}
}
-
-/* ffestc_order_record_ -- Check ordering on RECORD statement
-
- if (ffestc_order_record_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_VXT
-static ffestcOrder_
-ffestc_order_record_ ()
-{
- recurse:
-
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateNIL:
- ffestc_shriek_begin_program_ ();
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_statePROGRAM0:
- case FFESTV_statePROGRAM1:
- case FFESTV_statePROGRAM2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateSUBROUTINE0:
- case FFESTV_stateSUBROUTINE1:
- case FFESTV_stateSUBROUTINE2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateFUNCTION0:
- case FFESTV_stateFUNCTION1:
- case FFESTV_stateFUNCTION2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateMODULE0:
- case FFESTV_stateMODULE1:
- case FFESTV_stateMODULE2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateBLOCKDATA0:
- case FFESTV_stateBLOCKDATA1:
- case FFESTV_stateBLOCKDATA2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA3);
- return FFESTC_orderOK_;
-
- case FFESTV_statePROGRAM3:
- case FFESTV_stateSUBROUTINE3:
- case FFESTV_stateFUNCTION3:
- case FFESTV_stateMODULE3:
- case FFESTV_stateBLOCKDATA3:
- case FFESTV_stateSTRUCTURE:
- case FFESTV_stateMAP:
- return FFESTC_orderOK_;
-
- case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-#endif
/* ffestc_order_selectcase_ -- Check ordering on <selectcase> statement
if (ffestc_order_selectcase_() != FFESTC_orderOK_)
return; */
static ffestcOrder_
-ffestc_order_selectcase_ ()
+ffestc_order_selectcase_ (void)
{
switch (ffestw_state (ffestw_stack_top ()))
{
@@ -3669,9 +3035,6 @@ ffestc_order_selectcase_ ()
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -3691,7 +3054,7 @@ ffestc_order_selectcase_ ()
return; */
static ffestcOrder_
-ffestc_order_sfunc_ ()
+ffestc_order_sfunc_ (void)
{
recurse:
@@ -3728,16 +3091,10 @@ ffestc_order_sfunc_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -3750,115 +3107,13 @@ ffestc_order_sfunc_ ()
return FFESTC_orderBAD_;
}
}
-
-/* ffestc_order_spec_ -- Check ordering on <spec> statement
-
- if (ffestc_order_spec_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_F90
-static ffestcOrder_
-ffestc_order_spec_ ()
-{
- recurse:
-
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateNIL:
- ffestc_shriek_begin_program_ ();
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateSUBROUTINE0:
- case FFESTV_stateSUBROUTINE1:
- case FFESTV_stateSUBROUTINE2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateFUNCTION0:
- case FFESTV_stateFUNCTION1:
- case FFESTV_stateFUNCTION2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateMODULE0:
- case FFESTV_stateMODULE1:
- case FFESTV_stateMODULE2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateSUBROUTINE3:
- case FFESTV_stateFUNCTION3:
- case FFESTV_stateMODULE3:
- return FFESTC_orderOK_;
-
- case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-#endif
-/* ffestc_order_structure_ -- Check ordering on <structure> statement
-
- if (ffestc_order_structure_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_VXT
-static ffestcOrder_
-ffestc_order_structure_ ()
-{
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateSTRUCTURE:
- return FFESTC_orderOK_;
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-#endif
/* ffestc_order_subroutine_ -- Check ordering on <subroutine> statement
if (ffestc_order_subroutine_() != FFESTC_orderOK_)
return; */
static ffestcOrder_
-ffestc_order_subroutine_ ()
+ffestc_order_subroutine_ (void)
{
recurse:
@@ -3873,46 +3128,10 @@ ffestc_order_subroutine_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-/* ffestc_order_type_ -- Check ordering on <type> statement
-
- if (ffestc_order_type_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_F90
-static ffestcOrder_
-ffestc_order_type_ ()
-{
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateTYPE:
- return FFESTC_orderOK_;
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
- ffestc_shriek_where_ (FALSE);
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -3926,14 +3145,13 @@ ffestc_order_type_ ()
}
}
-#endif
/* ffestc_order_typedecl_ -- Check ordering on <typedecl> statement
if (ffestc_order_typedecl_() != FFESTC_orderOK_)
return; */
static ffestcOrder_
-ffestc_order_typedecl_ ()
+ffestc_order_typedecl_ (void)
{
recurse:
@@ -3986,16 +3204,10 @@ ffestc_order_typedecl_ ()
return FFESTC_orderOK_;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -4008,118 +3220,21 @@ ffestc_order_typedecl_ ()
return FFESTC_orderBAD_;
}
}
-
-/* ffestc_order_union_ -- Check ordering on <union> statement
-
- if (ffestc_order_union_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_VXT
-static ffestcOrder_
-ffestc_order_union_ ()
-{
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateUNION:
- return FFESTC_orderOK_;
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-#endif
/* ffestc_order_unit_ -- Check ordering on <unit> statement
if (ffestc_order_unit_() != FFESTC_orderOK_)
return; */
static ffestcOrder_
-ffestc_order_unit_ ()
-{
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateNIL:
- return FFESTC_orderOK_;
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-/* ffestc_order_use_ -- Check ordering on USE statement
-
- if (ffestc_order_use_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_F90
-static ffestcOrder_
-ffestc_order_use_ ()
+ffestc_order_unit_ (void)
{
- recurse:
-
switch (ffestw_state (ffestw_stack_top ()))
{
case FFESTV_stateNIL:
- ffestc_shriek_begin_program_ ();
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_statePROGRAM0:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM1);
- ffestc_shriek_begin_uses_ ();
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateSUBROUTINE0:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE1);
- ffestc_shriek_begin_uses_ ();
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateFUNCTION0:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION1);
- ffestc_shriek_begin_uses_ ();
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateMODULE0:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE1);
- ffestc_shriek_begin_uses_ ();
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateUSE:
return FFESTC_orderOK_;
case FFESTV_stateWHERE:
ffestc_order_bad_ ();
- ffestc_shriek_where_ (FALSE);
return FFESTC_orderBAD_;
case FFESTV_stateIF:
@@ -4132,125 +3247,6 @@ ffestc_order_use_ ()
return FFESTC_orderBAD_;
}
}
-
-#endif
-/* ffestc_order_vxtstructure_ -- Check ordering on STRUCTURE statement
-
- if (ffestc_order_vxtstructure_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_VXT
-static ffestcOrder_
-ffestc_order_vxtstructure_ ()
-{
- recurse:
-
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateNIL:
- ffestc_shriek_begin_program_ ();
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_statePROGRAM0:
- case FFESTV_statePROGRAM1:
- case FFESTV_statePROGRAM2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateSUBROUTINE0:
- case FFESTV_stateSUBROUTINE1:
- case FFESTV_stateSUBROUTINE2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateFUNCTION0:
- case FFESTV_stateFUNCTION1:
- case FFESTV_stateFUNCTION2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateMODULE0:
- case FFESTV_stateMODULE1:
- case FFESTV_stateMODULE2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3);
- return FFESTC_orderOK_;
-
- case FFESTV_stateBLOCKDATA0:
- case FFESTV_stateBLOCKDATA1:
- case FFESTV_stateBLOCKDATA2:
- ffestw_update (NULL);
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA3);
- return FFESTC_orderOK_;
-
- case FFESTV_statePROGRAM3:
- case FFESTV_stateSUBROUTINE3:
- case FFESTV_stateFUNCTION3:
- case FFESTV_stateMODULE3:
- case FFESTV_stateBLOCKDATA3:
- case FFESTV_stateSTRUCTURE:
- case FFESTV_stateMAP:
- return FFESTC_orderOK_;
-
- case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
- goto recurse; /* :::::::::::::::::::: */
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
-#if FFESTR_F90
- ffestc_shriek_where_ (FALSE);
-#endif
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-#endif
-/* ffestc_order_where_ -- Check ordering on <where> statement
-
- if (ffestc_order_where_() != FFESTC_orderOK_)
- return; */
-
-#if FFESTR_F90
-static ffestcOrder_
-ffestc_order_where_ ()
-{
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateWHERETHEN:
- return FFESTC_orderOK_;
-
- case FFESTV_stateWHERE:
- ffestc_order_bad_ ();
- ffestc_shriek_where_ (FALSE);
- return FFESTC_orderBAD_;
-
- case FFESTV_stateIF:
- ffestc_order_bad_ ();
- ffestc_shriek_if_ (FALSE);
- return FFESTC_orderBAD_;
-
- default:
- ffestc_order_bad_ ();
- return FFESTC_orderBAD_;
- }
-}
-
-#endif
/* Invoked for each token in dummy arg list of FUNCTION, SUBROUTINE, and
ENTRY (prior to the first executable statement). */
@@ -4567,7 +3563,7 @@ ffestc_promote_sfdummy_ (ffelexToken t)
of a main program unit. */
static void
-ffestc_shriek_begin_program_ ()
+ffestc_shriek_begin_program_ (void)
{
ffestw b;
ffesymbol s;
@@ -4605,32 +3601,6 @@ ffestc_shriek_begin_program_ ()
ffestd_R1102 (s, NULL);
}
-/* ffestc_shriek_begin_uses_ -- Start a bunch of USE statements
-
- ffestc_shriek_begin_uses_();
-
- Invoked before handling the first USE statement in a block of one or
- more USE statements. _end_uses_(bool ok) is invoked before handling
- the first statement after the block (there are no BEGIN USE and END USE
- statements, but the semantics of USE statements effectively requires
- handling them as a single block rather than one statement at a time). */
-
-#if FFESTR_F90
-static void
-ffestc_shriek_begin_uses_ ()
-{
- ffestw b;
-
- b = ffestw_update (ffestw_push (NULL));
- ffestw_set_top_do (b, NULL);
- ffestw_set_state (b, FFESTV_stateUSE);
- ffestw_set_blocknum (b, 0);
- ffestw_set_shriek (b, ffestc_shriek_end_uses_);
-
- ffestd_begin_uses ();
-}
-
-#endif
/* ffestc_shriek_blockdata_ -- End a BLOCK DATA
ffestc_shriek_blockdata_(TRUE); */
@@ -4724,23 +3694,6 @@ ffestc_shriek_end_program_ (bool ok)
ffe_init_2 ();
}
-/* ffestc_shriek_end_uses_ -- End a bunch of USE statements
-
- ffestc_shriek_end_uses_(TRUE);
-
- ok==TRUE means simply not popping due to ffestc_eof()
- being called, because there is no formal END USES statement in Fortran. */
-
-#if FFESTR_F90
-static void
-ffestc_shriek_end_uses_ (bool ok)
-{
- ffestd_end_uses (ok);
-
- ffestw_kill (ffestw_pop ());
-}
-
-#endif
/* ffestc_shriek_function_ -- End a FUNCTION
ffestc_shriek_function_(TRUE); */
@@ -4818,64 +3771,6 @@ ffestc_shriek_ifthen_ (bool ok)
ffestc_try_shriek_do_ ();
}
-/* ffestc_shriek_interface_ -- End an INTERFACE
-
- ffestc_shriek_interface_(TRUE); */
-
-#if FFESTR_F90
-static void
-ffestc_shriek_interface_ (bool ok)
-{
- ffestd_R1203 (ok);
-
- ffestw_kill (ffestw_pop ());
-
- ffestc_try_shriek_do_ ();
-}
-
-#endif
-/* ffestc_shriek_map_ -- End a MAP
-
- ffestc_shriek_map_(TRUE); */
-
-#if FFESTR_VXT
-static void
-ffestc_shriek_map_ (bool ok)
-{
- ffestd_V013 (ok);
-
- ffestw_kill (ffestw_pop ());
-
- ffestc_try_shriek_do_ ();
-}
-
-#endif
-/* ffestc_shriek_module_ -- End a MODULE
-
- ffestc_shriek_module_(TRUE); */
-
-#if FFESTR_F90
-static void
-ffestc_shriek_module_ (bool ok)
-{
- if (!ffesta_seen_first_exec)
- {
- ffesta_seen_first_exec = TRUE;
- ffestd_exec_begin ();
- }
-
- ffestd_R1106 (ok);
-
- ffestd_exec_end ();
-
- ffelex_token_kill (ffestw_name (ffestw_stack_top ()));
- ffestw_kill (ffestw_pop ());
-
- ffe_terminate_2 ();
- ffe_init_2 ();
-}
-
-#endif
/* ffestc_shriek_select_ -- End a SELECT
ffestc_shriek_select_(TRUE); */
@@ -4901,22 +3796,6 @@ ffestc_shriek_select_ (bool ok)
ffestc_try_shriek_do_ ();
}
-/* ffestc_shriek_structure_ -- End a STRUCTURE
-
- ffestc_shriek_structure_(TRUE); */
-
-#if FFESTR_VXT
-static void
-ffestc_shriek_structure_ (bool ok)
-{
- ffestd_V004 (ok);
-
- ffestw_kill (ffestw_pop ());
-
- ffestc_try_shriek_do_ ();
-}
-
-#endif
/* ffestc_shriek_subroutine_ -- End a SUBROUTINE
ffestc_shriek_subroutine_(TRUE); */
@@ -4957,81 +3836,6 @@ ffestc_shriek_subroutine_ (bool ok)
}
}
-/* ffestc_shriek_type_ -- End a TYPE
-
- ffestc_shriek_type_(TRUE); */
-
-#if FFESTR_F90
-static void
-ffestc_shriek_type_ (bool ok)
-{
- ffestd_R425 (ok);
-
- ffe_terminate_4 ();
-
- ffelex_token_kill (ffestw_name (ffestw_stack_top ()));
- ffestw_kill (ffestw_pop ());
-
- ffestc_try_shriek_do_ ();
-}
-
-#endif
-/* ffestc_shriek_union_ -- End a UNION
-
- ffestc_shriek_union_(TRUE); */
-
-#if FFESTR_VXT
-static void
-ffestc_shriek_union_ (bool ok)
-{
- ffestd_V010 (ok);
-
- ffestw_kill (ffestw_pop ());
-
- ffestc_try_shriek_do_ ();
-}
-
-#endif
-/* ffestc_shriek_where_ -- Implicit END WHERE statement
-
- ffestc_shriek_where_(TRUE);
-
- Implement the end of the current WHERE "block". ok==TRUE iff statement
- following WHERE (substatement) is valid; else, statement is invalid
- or stack forcibly popped due to ffestc_eof(). */
-
-#if FFESTR_F90
-static void
-ffestc_shriek_where_ (bool ok)
-{
- ffestd_R745 (ok);
-
- ffestw_kill (ffestw_pop ());
- ffestc_shriek_after1_ = NULL;
- if (ffestw_state (ffestw_stack_top ()) == FFESTV_stateIF)
- ffestc_shriek_if_ (TRUE); /* "IF (x) WHERE (y) stmt" is only valid
- case. */
-
- ffestc_try_shriek_do_ ();
-}
-
-#endif
-/* ffestc_shriek_wherethen_ -- End a WHERE(-THEN)
-
- ffestc_shriek_wherethen_(TRUE); */
-
-#if FFESTR_F90
-static void
-ffestc_shriek_wherethen_ (bool ok)
-{
- ffestd_end_R740 (ok);
-
- ffestw_kill (ffestw_pop ());
-
- ffestc_try_shriek_do_ ();
-}
-
-#endif
/* ffestc_subr_binsrch_ -- Binary search of char const in list of strings
i = ffestc_subr_binsrch_(search_list,search_list_size,&spec,"etc");
@@ -5303,7 +4107,7 @@ ffestc_subr_unit_ (ffestpFile *spec)
like "DO 10", "IF (...) THEN", "10 ELSE", "END IF", "END". */
static void
-ffestc_try_shriek_do_ ()
+ffestc_try_shriek_do_ (void)
{
ffelab lab;
ffelabType ty;
@@ -5372,12 +4176,6 @@ ffestc_decl_start (ffestpType type, ffelexToken typet, ffebld kind,
switch (ffestc_local_.decl.is_R426)
{
-#if FFESTR_F90
- case 1:
- ffestc_R426_start (type, typet, kind, kindt, len, lent);
- break;
-#endif
-
case 2:
ffestc_R501_start (type, typet, kind, kindt, len, lent);
break;
@@ -5401,27 +4199,11 @@ ffestc_decl_attrib (ffestpAttrib attrib UNUSED,
ffestrOther intent_kw UNUSED,
ffesttDimList dims UNUSED)
{
-#if FFESTR_F90
- switch (ffestc_local_.decl.is_R426)
- {
- case 1:
- ffestc_R426_attrib (attrib, attribt, intent_kw, dims);
- break;
-
- case 2:
- ffestc_R501_attrib (attrib, attribt, intent_kw, dims);
- break;
-
- default:
- break;
- }
-#else
ffebad_start (FFEBAD_F90);
ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
ffelex_token_where_column (ffesta_tokens[0]));
ffebad_finish ();
return;
-#endif
}
/* ffestc_decl_item -- R426 or R501
@@ -5437,13 +4219,6 @@ ffestc_decl_item (ffelexToken name, ffebld kind, ffelexToken kindt,
{
switch (ffestc_local_.decl.is_R426)
{
-#if FFESTR_F90
- case 1:
- ffestc_R426_item (name, kind, kindt, dims, len, lent, init, initt,
- clist);
- break;
-#endif
-
case 2:
ffestc_R501_item (name, kind, kindt, dims, len, lent, init, initt,
clist);
@@ -5461,16 +4236,10 @@ ffestc_decl_item (ffelexToken name, ffebld kind, ffelexToken kindt,
Gonna specify values for the object now. */
void
-ffestc_decl_itemstartvals ()
+ffestc_decl_itemstartvals (void)
{
switch (ffestc_local_.decl.is_R426)
{
-#if FFESTR_F90
- case 1:
- ffestc_R426_itemstartvals ();
- break;
-#endif
-
case 2:
ffestc_R501_itemstartvals ();
break;
@@ -5492,12 +4261,6 @@ ffestc_decl_itemvalue (ffebld repeat, ffelexToken repeat_token,
{
switch (ffestc_local_.decl.is_R426)
{
-#if FFESTR_F90
- case 1:
- ffestc_R426_itemvalue (repeat, repeat_token, value, value_token);
- break;
-#endif
-
case 2:
ffestc_R501_itemvalue (repeat, repeat_token, value, value_token);
break;
@@ -5519,12 +4282,6 @@ ffestc_decl_itemendvals (ffelexToken t)
{
switch (ffestc_local_.decl.is_R426)
{
-#if FFESTR_F90
- case 1:
- ffestc_R426_itemendvals (t);
- break;
-#endif
-
case 2:
ffestc_R501_itemendvals (t);
break;
@@ -5541,16 +4298,10 @@ ffestc_decl_itemendvals (ffelexToken t)
Just wrap up any local activities. */
void
-ffestc_decl_finish ()
+ffestc_decl_finish (void)
{
switch (ffestc_local_.decl.is_R426)
{
-#if FFESTR_F90
- case 1:
- ffestc_R426_finish ();
- break;
-#endif
-
case 2:
ffestc_R501_finish ();
break;
@@ -5576,9 +4327,6 @@ ffestc_elsewhere (ffelexToken where)
break;
default:
-#if FFESTR_F90
- ffestc_R744 ();
-#endif
break;
}
}
@@ -5591,7 +4339,7 @@ ffestc_elsewhere (ffelexToken where)
it. */
void
-ffestc_end ()
+ffestc_end (void)
{
ffestw b;
@@ -5635,9 +4383,6 @@ recurse:
case FFESTV_stateMODULE3:
case FFESTV_stateMODULE4:
case FFESTV_stateMODULE5:
-#if FFESTR_F90
- ffestc_R1106 (NULL);
-#endif
break;
case FFESTV_stateSUBROUTINE0:
@@ -5677,7 +4422,7 @@ recurse:
block's shriek function to clean up to state NIL. */
void
-ffestc_eof ()
+ffestc_eof (void)
{
if (ffestw_state (ffestw_stack_top ()) != FFESTV_stateNIL)
{
@@ -5712,7 +4457,7 @@ ffestc_eof ()
seeing the unrecognized statement? we do the former at the moment). */
bool
-ffestc_exec_transition ()
+ffestc_exec_transition (void)
{
bool update;
@@ -5757,9 +4502,6 @@ recurse:
break;
case FFESTV_stateUSE:
-#if FFESTR_F90
- ffestc_shriek_end_uses_ (TRUE);
-#endif
goto recurse; /* :::::::::::::::::::: */
default:
@@ -5819,7 +4561,7 @@ ffestc_ffebad_here_doiter (ffebadIndex i, ffesymbol s)
is the R1219 function-stmt case). */
bool
-ffestc_is_decl_not_R1219 ()
+ffestc_is_decl_not_R1219 (void)
{
switch (ffestw_state (ffestw_stack_top ()))
{
@@ -5849,7 +4591,7 @@ ffestc_is_decl_not_R1219 ()
if the ENTRY is in a function context. */
bool
-ffestc_is_entry_in_subr ()
+ffestc_is_entry_in_subr (void)
{
ffestvState s;
@@ -5888,7 +4630,7 @@ recurse:
explicit typing of name. */
bool
-ffestc_is_let_not_V027 ()
+ffestc_is_let_not_V027 (void)
{
switch (ffestw_state (ffestw_stack_top ()))
{
@@ -5909,58 +4651,6 @@ ffestc_is_let_not_V027 ()
}
}
-/* ffestc_module -- MODULE or MODULE PROCEDURE statement
-
- ffestc_module(module_name_token,procedure_name_token);
-
- Decide which is intended, and implement it by calling _R1105_ or
- _R1205_. */
-
-#if FFESTR_F90
-void
-ffestc_module (ffelexToken module, ffelexToken procedure)
-{
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateINTERFACE0:
- case FFESTV_stateINTERFACE1:
- ffestc_R1205_start ();
- ffestc_R1205_item (procedure);
- ffestc_R1205_finish ();
- break;
-
- default:
- ffestc_R1105 (module);
- break;
- }
-}
-
-#endif
-/* ffestc_private -- Generic PRIVATE statement
-
- ffestc_end();
-
- This is either a PRIVATE within R422 derived-type statement or an
- R521 PRIVATE statement. Figure it out based on context and implement
- it, or produce an error. */
-
-#if FFESTR_F90
-void
-ffestc_private ()
-{
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateTYPE:
- ffestc_R423A ();
- break;
-
- default:
- ffestc_R521B ();
- break;
- }
-}
-
-#endif
/* ffestc_terminate_4 -- Terminate ffestc after scoping unit
ffestc_terminate_4();
@@ -5969,280 +4659,11 @@ ffestc_private ()
defs, and statement function defs. */
void
-ffestc_terminate_4 ()
+ffestc_terminate_4 (void)
{
ffestc_entry_num_ = ffestc_saved_entry_num_;
}
-/* ffestc_R423A -- PRIVATE statement (in R422 derived-type statement)
-
- ffestc_R423A(); */
-
-#if FFESTR_F90
-void
-ffestc_R423A ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_type_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- if (ffestw_substate (ffestw_stack_top ()) != 0)
- {
- ffebad_start (FFEBAD_DERIVTYP_ACCESS_FIRST);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ()));
- ffebad_finish ();
- return;
- }
-
- if (ffestw_state (ffestw_previous (ffestw_stack_top ())) != FFESTV_stateMODULE3)
- {
- ffebad_start (FFEBAD_DERIVTYP_ACCESS);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_finish ();
- return;
- }
-
- ffestw_set_substate (ffestw_stack_top (), 1); /* Seen
- private-sequence-stmt. */
-
- ffestd_R423A ();
-}
-
-/* ffestc_R423B -- SEQUENCE statement (in R422 derived-type-stmt)
-
- ffestc_R423B(); */
-
-void
-ffestc_R423B ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_type_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- if (ffestw_substate (ffestw_stack_top ()) != 0)
- {
- ffebad_start (FFEBAD_DERIVTYP_ACCESS_FIRST);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ()));
- ffebad_finish ();
- return;
- }
-
- ffestw_set_substate (ffestw_stack_top (), 1); /* Seen
- private-sequence-stmt. */
-
- ffestd_R423B ();
-}
-
-/* ffestc_R424 -- derived-TYPE-def statement
-
- ffestc_R424(access_token,access_kw,name_token);
-
- Handle a derived-type definition. */
-
-void
-ffestc_R424 (ffelexToken access, ffestrOther access_kw, ffelexToken name)
-{
- ffestw b;
-
- assert (name != NULL);
-
- ffestc_check_simple_ ();
- if (ffestc_order_derivedtype_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- if ((access != NULL)
- && (ffestw_state (ffestw_stack_top ()) != FFESTV_stateMODULE3))
- {
- ffebad_start (FFEBAD_DERIVTYP_ACCESS);
- ffebad_here (0, ffelex_token_where_line (access),
- ffelex_token_where_column (access));
- ffebad_finish ();
- access = NULL;
- }
-
- b = ffestw_update (ffestw_push (NULL));
- ffestw_set_top_do (b, NULL);
- ffestw_set_state (b, FFESTV_stateTYPE);
- ffestw_set_blocknum (b, 0);
- ffestw_set_shriek (b, ffestc_shriek_type_);
- ffestw_set_name (b, ffelex_token_use (name));
- ffestw_set_substate (b, 0); /* Awaiting private-sequence-stmt and one
- component-def-stmt. */
-
- ffestd_R424 (access, access_kw, name);
-
- ffe_init_4 ();
-}
-
-/* ffestc_R425 -- END TYPE statement
-
- ffestc_R425(name_token);
-
- Make sure ffestc_kind_ identifies a TYPE definition. If not
- NULL, make sure name_token gives the correct name. Implement the end
- of the type definition. */
-
-void
-ffestc_R425 (ffelexToken name)
-{
- ffestc_check_simple_ ();
- if (ffestc_order_type_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- if (ffestw_substate (ffestw_stack_top ()) != 2)
- {
- ffebad_start (FFEBAD_DERIVTYP_NO_COMPONENTS);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ()));
- ffebad_finish ();
- }
-
- if ((name != NULL)
- && (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0))
- {
- ffebad_start (FFEBAD_TYPE_WRONG_NAME);
- ffebad_here (0, ffelex_token_where_line (name),
- ffelex_token_where_column (name));
- ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())),
- ffelex_token_where_column (ffestw_name (ffestw_stack_top ())));
- ffebad_finish ();
- }
-
- ffestc_shriek_type_ (TRUE);
-}
-
-/* ffestc_R426_start -- component-declaration-stmt
-
- ffestc_R426_start(...);
-
- Verify that R426 component-declaration-stmt is
- valid here and implement. */
-
-void
-ffestc_R426_start (ffestpType type, ffelexToken typet, ffebld kind,
- ffelexToken kindt, ffebld len, ffelexToken lent)
-{
- ffestc_check_start_ ();
- if (ffestc_order_component_ () != FFESTC_orderOK_)
- {
- ffestc_local_.decl.is_R426 = 0;
- return;
- }
- ffestc_labeldef_useless_ ();
-
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateSTRUCTURE:
- case FFESTV_stateMAP:
- ffestw_set_substate (ffestw_stack_top (), 1); /* Seen at least one
- member. */
- break;
-
- case FFESTV_stateTYPE:
- ffestw_set_substate (ffestw_stack_top (), 2);
- break;
-
- default:
- assert ("Component parent state invalid" == NULL);
- break;
- }
-}
-
-/* ffestc_R426_attrib -- type attribute
-
- ffestc_R426_attrib(...);
-
- Verify that R426 component-declaration-stmt attribute
- is valid here and implement. */
-
-void
-ffestc_R426_attrib (ffestpAttrib attrib, ffelexToken attribt,
- ffestrOther intent_kw, ffesttDimList dims)
-{
- ffestc_check_attrib_ ();
-}
-
-/* ffestc_R426_item -- declared object
-
- ffestc_R426_item(...);
-
- Establish type for a particular object. */
-
-void
-ffestc_R426_item (ffelexToken name, ffebld kind, ffelexToken kindt,
- ffesttDimList dims, ffebld len, ffelexToken lent, ffebld init,
- ffelexToken initt, bool clist)
-{
- ffestc_check_item_ ();
- assert (name != NULL);
- assert (ffelex_token_type (name) == FFELEX_typeNAME); /* Not NAMES. */
- assert (kind == NULL); /* No way an expression should get here. */
-
- if ((dims != NULL) || (init != NULL) || clist)
- ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE);
-}
-
-/* ffestc_R426_itemstartvals -- Start list of values
-
- ffestc_R426_itemstartvals();
-
- Gonna specify values for the object now. */
-
-void
-ffestc_R426_itemstartvals ()
-{
- ffestc_check_item_startvals_ ();
-}
-
-/* ffestc_R426_itemvalue -- Source value
-
- ffestc_R426_itemvalue(repeat,repeat_token,value,value_token);
-
- Make sure repeat and value are valid for the object being initialized. */
-
-void
-ffestc_R426_itemvalue (ffebld repeat, ffelexToken repeat_token,
- ffebld value, ffelexToken value_token)
-{
- ffestc_check_item_value_ ();
-}
-
-/* ffestc_R426_itemendvals -- End list of values
-
- ffelexToken t; // the SLASH token that ends the list.
- ffestc_R426_itemendvals(t);
-
- No more values, might specify more objects now. */
-
-void
-ffestc_R426_itemendvals (ffelexToken t)
-{
- ffestc_check_item_endvals_ ();
-}
-
-/* ffestc_R426_finish -- Done
-
- ffestc_R426_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_R426_finish ()
-{
- ffestc_check_finish_ ();
-}
-
-#endif
/* ffestc_R501_start -- type-declaration-stmt
ffestc_R501_start(...);
@@ -6281,11 +4702,6 @@ ffestc_R501_attrib (ffestpAttrib attrib, ffelexToken attribt,
switch (attrib)
{
-#if FFESTR_F90
- case FFESTP_attribALLOCATABLE:
- break;
-#endif
-
case FFESTP_attribDIMENSION:
ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE);
break;
@@ -6293,35 +4709,12 @@ ffestc_R501_attrib (ffestpAttrib attrib, ffelexToken attribt,
case FFESTP_attribEXTERNAL:
break;
-#if FFESTR_F90
- case FFESTP_attribINTENT:
- break;
-#endif
-
case FFESTP_attribINTRINSIC:
break;
-#if FFESTR_F90
- case FFESTP_attribOPTIONAL:
- break;
-#endif
-
case FFESTP_attribPARAMETER:
break;
-#if FFESTR_F90
- case FFESTP_attribPOINTER:
- break;
-#endif
-
-#if FFESTR_F90
- case FFESTP_attribPRIVATE:
- break;
-
- case FFESTP_attribPUBLIC:
- break;
-#endif
-
case FFESTP_attribSAVE:
switch (ffestv_save_state_)
{
@@ -6355,11 +4748,6 @@ ffestc_R501_attrib (ffestpAttrib attrib, ffelexToken attribt,
}
break;
-#if FFESTR_F90
- case FFESTP_attribTARGET:
- break;
-#endif
-
default:
assert ("unexpected attribute" == NULL);
break;
@@ -6635,7 +5023,7 @@ ffestc_R501_item (ffelexToken name, ffebld kind, ffelexToken kindt,
Gonna specify values for the object now. */
void
-ffestc_R501_itemstartvals ()
+ffestc_R501_itemstartvals (void)
{
ffestc_check_item_startvals_ ();
@@ -6703,323 +5091,11 @@ ffestc_R501_itemendvals (ffelexToken t)
Just wrap up any local activities. */
void
-ffestc_R501_finish ()
+ffestc_R501_finish (void)
{
ffestc_check_finish_ ();
}
-/* ffestc_R519_start -- INTENT statement list begin
-
- ffestc_R519_start();
-
- Verify that INTENT is valid here, and begin accepting items in the list. */
-
-#if FFESTR_F90
-void
-ffestc_R519_start (ffelexToken intent, ffestrOther intent_kw)
-{
- ffestc_check_start_ ();
- if (ffestc_order_spec_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_useless_ ();
-
- ffestd_R519_start (intent_kw);
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_R519_item -- INTENT statement for name
-
- ffestc_R519_item(name_token);
-
- Make sure name_token identifies a valid object to be INTENTed. */
-
-void
-ffestc_R519_item (ffelexToken name)
-{
- ffestc_check_item_ ();
- assert (name != NULL);
- if (!ffestc_ok_)
- return;
-
- ffestd_R519_item (name);
-}
-
-/* ffestc_R519_finish -- INTENT statement list complete
-
- ffestc_R519_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_R519_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_R519_finish ();
-}
-
-/* ffestc_R520_start -- OPTIONAL statement list begin
-
- ffestc_R520_start();
-
- Verify that OPTIONAL is valid here, and begin accepting items in the list. */
-
-void
-ffestc_R520_start ()
-{
- ffestc_check_start_ ();
- if (ffestc_order_spec_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_useless_ ();
-
- ffestd_R520_start ();
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_R520_item -- OPTIONAL statement for name
-
- ffestc_R520_item(name_token);
-
- Make sure name_token identifies a valid object to be OPTIONALed. */
-
-void
-ffestc_R520_item (ffelexToken name)
-{
- ffestc_check_item_ ();
- assert (name != NULL);
- if (!ffestc_ok_)
- return;
-
- ffestd_R520_item (name);
-}
-
-/* ffestc_R520_finish -- OPTIONAL statement list complete
-
- ffestc_R520_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_R520_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_R520_finish ();
-}
-
-/* ffestc_R521A -- PUBLIC statement
-
- ffestc_R521A();
-
- Verify that PUBLIC is valid here. */
-
-void
-ffestc_R521A ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_access_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- switch (ffestv_access_state_)
- {
- case FFESTV_accessstateNONE:
- ffestv_access_state_ = FFESTV_accessstatePUBLIC;
- ffestv_access_line_
- = ffewhere_line_use (ffelex_token_where_line (ffesta_tokens[0]));
- ffestv_access_col_
- = ffewhere_column_use (ffelex_token_where_column (ffesta_tokens[0]));
- break;
-
- case FFESTV_accessstateANY:
- break;
-
- case FFESTV_accessstatePUBLIC:
- case FFESTV_accessstatePRIVATE:
- ffebad_start (FFEBAD_CONFLICTING_ACCESSES);
- ffebad_here (0, ffestv_access_line_, ffestv_access_col_);
- ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_finish ();
- ffestv_access_state_ = FFESTV_accessstateANY;
- break;
-
- default:
- assert ("unexpected access state" == NULL);
- break;
- }
-
- ffestd_R521A ();
-}
-
-/* ffestc_R521Astart -- PUBLIC statement list begin
-
- ffestc_R521Astart();
-
- Verify that PUBLIC is valid here, and begin accepting items in the list. */
-
-void
-ffestc_R521Astart ()
-{
- ffestc_check_start_ ();
- if (ffestc_order_access_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_useless_ ();
-
- ffestd_R521Astart ();
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_R521Aitem -- PUBLIC statement for name
-
- ffestc_R521Aitem(name_token);
-
- Make sure name_token identifies a valid object to be PUBLICed. */
-
-void
-ffestc_R521Aitem (ffelexToken name)
-{
- ffestc_check_item_ ();
- assert (name != NULL);
- if (!ffestc_ok_)
- return;
-
- ffestd_R521Aitem (name);
-}
-
-/* ffestc_R521Afinish -- PUBLIC statement list complete
-
- ffestc_R521Afinish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_R521Afinish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_R521Afinish ();
-}
-
-/* ffestc_R521B -- PRIVATE statement
-
- ffestc_R521B();
-
- Verify that PRIVATE is valid here (outside a derived-type statement). */
-
-void
-ffestc_R521B ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_access_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- switch (ffestv_access_state_)
- {
- case FFESTV_accessstateNONE:
- ffestv_access_state_ = FFESTV_accessstatePRIVATE;
- ffestv_access_line_
- = ffewhere_line_use (ffelex_token_where_line (ffesta_tokens[0]));
- ffestv_access_col_
- = ffewhere_column_use (ffelex_token_where_column (ffesta_tokens[0]));
- break;
-
- case FFESTV_accessstateANY:
- break;
-
- case FFESTV_accessstatePUBLIC:
- case FFESTV_accessstatePRIVATE:
- ffebad_start (FFEBAD_CONFLICTING_ACCESSES);
- ffebad_here (0, ffestv_access_line_, ffestv_access_col_);
- ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_finish ();
- ffestv_access_state_ = FFESTV_accessstateANY;
- break;
-
- default:
- assert ("unexpected access state" == NULL);
- break;
- }
-
- ffestd_R521B ();
-}
-
-/* ffestc_R521Bstart -- PRIVATE statement list begin
-
- ffestc_R521Bstart();
-
- Verify that PRIVATE is valid here, and begin accepting items in the list. */
-
-void
-ffestc_R521Bstart ()
-{
- ffestc_check_start_ ();
- if (ffestc_order_access_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_useless_ ();
-
- ffestd_R521Bstart ();
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_R521Bitem -- PRIVATE statement for name
-
- ffestc_R521Bitem(name_token);
-
- Make sure name_token identifies a valid object to be PRIVATEed. */
-
-void
-ffestc_R521Bitem (ffelexToken name)
-{
- ffestc_check_item_ ();
- assert (name != NULL);
- if (!ffestc_ok_)
- return;
-
- ffestd_R521Bitem (name);
-}
-
-/* ffestc_R521Bfinish -- PRIVATE statement list complete
-
- ffestc_R521Bfinish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_R521Bfinish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_R521Bfinish ();
-}
-
-#endif
/* ffestc_R522 -- SAVE statement with no list
ffestc_R522();
@@ -7027,7 +5103,7 @@ ffestc_R521Bfinish ()
Verify that SAVE is valid here, and flag everything as SAVEd. */
void
-ffestc_R522 ()
+ffestc_R522 (void)
{
ffestc_check_simple_ ();
if (ffestc_order_blockspec_ () != FFESTC_orderOK_)
@@ -7077,7 +5153,7 @@ ffestc_R522 ()
Verify that SAVE is valid here, and begin accepting items in the list. */
void
-ffestc_R522start ()
+ffestc_R522start (void)
{
ffestc_check_start_ ();
if (ffestc_order_blockspec_ () != FFESTC_orderOK_)
@@ -7239,7 +5315,7 @@ ffestc_R522item_cblock (ffelexToken name)
Just wrap up any local activities. */
void
-ffestc_R522finish ()
+ffestc_R522finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -7411,7 +5487,7 @@ ffestc_R524_item (ffelexToken name, ffesttDimList dims)
Just wrap up any local activities. */
void
-ffestc_R524_finish ()
+ffestc_R524_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -7420,182 +5496,6 @@ ffestc_R524_finish ()
ffestd_R524_finish ();
}
-/* ffestc_R525_start -- ALLOCATABLE statement list begin
-
- ffestc_R525_start();
-
- Verify that ALLOCATABLE is valid here, and begin accepting items in the
- list. */
-
-#if FFESTR_F90
-void
-ffestc_R525_start ()
-{
- ffestc_check_start_ ();
- if (ffestc_order_progspec_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_useless_ ();
-
- ffestd_R525_start ();
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_R525_item -- ALLOCATABLE statement for object-name
-
- ffestc_R525_item(name_token,dim_list);
-
- Make sure name_token identifies a valid object to be ALLOCATABLEd. */
-
-void
-ffestc_R525_item (ffelexToken name, ffesttDimList dims)
-{
- ffestc_check_item_ ();
- assert (name != NULL);
- if (!ffestc_ok_)
- return;
-
- ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE);
-
- ffestd_R525_item (name, dims);
-}
-
-/* ffestc_R525_finish -- ALLOCATABLE statement list complete
-
- ffestc_R525_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_R525_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_R525_finish ();
-}
-
-/* ffestc_R526_start -- POINTER statement list begin
-
- ffestc_R526_start();
-
- Verify that POINTER is valid here, and begin accepting items in the
- list. */
-
-void
-ffestc_R526_start ()
-{
- ffestc_check_start_ ();
- if (ffestc_order_progspec_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_useless_ ();
-
- ffestd_R526_start ();
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_R526_item -- POINTER statement for object-name
-
- ffestc_R526_item(name_token,dim_list);
-
- Make sure name_token identifies a valid object to be POINTERd. */
-
-void
-ffestc_R526_item (ffelexToken name, ffesttDimList dims)
-{
- ffestc_check_item_ ();
- assert (name != NULL);
- if (!ffestc_ok_)
- return;
-
- ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE);
-
- ffestd_R526_item (name, dims);
-}
-
-/* ffestc_R526_finish -- POINTER statement list complete
-
- ffestc_R526_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_R526_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_R526_finish ();
-}
-
-/* ffestc_R527_start -- TARGET statement list begin
-
- ffestc_R527_start();
-
- Verify that TARGET is valid here, and begin accepting items in the
- list. */
-
-void
-ffestc_R527_start ()
-{
- ffestc_check_start_ ();
- if (ffestc_order_progspec_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_useless_ ();
-
- ffestd_R527_start ();
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_R527_item -- TARGET statement for object-name
-
- ffestc_R527_item(name_token,dim_list);
-
- Make sure name_token identifies a valid object to be TARGETd. */
-
-void
-ffestc_R527_item (ffelexToken name, ffesttDimList dims)
-{
- ffestc_check_item_ ();
- assert (name != NULL);
- if (!ffestc_ok_)
- return;
-
- ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE);
-
- ffestd_R527_item (name, dims);
-}
-
-/* ffestc_R527_finish -- TARGET statement list complete
-
- ffestc_R527_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_R527_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_R527_finish ();
-}
-
-#endif
/* ffestc_R528_start -- DATA statement list begin
ffestc_R528_start();
@@ -7603,7 +5503,7 @@ ffestc_R527_finish ()
Verify that DATA is valid here, and begin accepting items in the list. */
void
-ffestc_R528_start ()
+ffestc_R528_start (void)
{
ffestcOrder_ order;
@@ -7661,7 +5561,7 @@ ffestc_R528_item_object (ffebld expr, ffelexToken expr_token UNUSED)
No more objects, gonna specify values for the list of objects now. */
void
-ffestc_R528_item_startvals ()
+ffestc_R528_item_startvals (void)
{
ffestc_check_item_startvals_ ();
if (!ffestc_ok_)
@@ -7744,7 +5644,7 @@ ffestc_R528_item_endvals (ffelexToken t)
Just wrap up any local activities. */
void
-ffestc_R528_finish ()
+ffestc_R528_finish (void)
{
ffestc_check_finish_ ();
@@ -7762,7 +5662,7 @@ ffestc_R528_finish ()
list. */
void
-ffestc_R537_start ()
+ffestc_R537_start (void)
{
ffestc_check_start_ ();
if (ffestc_order_parameter_ () != FFESTC_orderOK_)
@@ -7845,7 +5745,7 @@ ffestc_R537_item (ffebld dest, ffelexToken dest_token, ffebld source,
Just wrap up any local activities. */
void
-ffestc_R537_finish ()
+ffestc_R537_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -7861,7 +5761,7 @@ ffestc_R537_finish ()
Verify that the IMPLICIT NONE statement is ok here and implement. */
void
-ffestc_R539 ()
+ffestc_R539 (void)
{
ffestc_check_simple_ ();
if (ffestc_order_implicitnone_ () != FFESTC_orderOK_)
@@ -7880,7 +5780,7 @@ ffestc_R539 ()
Verify that the IMPLICIT statement is ok here and implement. */
void
-ffestc_R539start ()
+ffestc_R539start (void)
{
ffestc_check_start_ ();
if (ffestc_order_implicit_ () != FFESTC_orderOK_)
@@ -7935,7 +5835,7 @@ ffestc_R539item (ffestpType type, ffebld kind, ffelexToken kindt,
Finish up any local activities. */
void
-ffestc_R539finish ()
+ffestc_R539finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -7952,7 +5852,7 @@ ffestc_R539finish ()
list. */
void
-ffestc_R542_start ()
+ffestc_R542_start (void)
{
ffestc_check_start_ ();
if (ffestc_order_progspec_ () != FFESTC_orderOK_)
@@ -8117,7 +6017,7 @@ ffestc_R542_item_nitem (ffelexToken name)
Just wrap up any local activities. */
void
-ffestc_R542_finish ()
+ffestc_R542_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -8136,7 +6036,7 @@ ffestc_R542_finish ()
list. */
void
-ffestc_R544_start ()
+ffestc_R544_start (void)
{
ffestc_check_start_ ();
if (ffestc_order_blockspec_ () != FFESTC_orderOK_)
@@ -8263,7 +6163,7 @@ ffestc_R544_equiv_ (ffebld expr, ffelexToken t)
Just wrap up any local activities. */
void
-ffestc_R544_finish ()
+ffestc_R544_finish (void)
{
ffestc_check_finish_ ();
}
@@ -8275,7 +6175,7 @@ ffestc_R544_finish ()
Verify that COMMON is valid here, and begin accepting items in the list. */
void
-ffestc_R547_start ()
+ffestc_R547_start (void)
{
ffestc_check_start_ ();
if (ffestc_order_blockspec_ () != FFESTC_orderOK_)
@@ -8544,7 +6444,7 @@ ffestc_R547_item_cblock (ffelexToken name)
Just wrap up any local activities. */
void
-ffestc_R547_finish ()
+ffestc_R547_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -8556,86 +6456,6 @@ ffestc_R547_finish ()
ffestd_R547_finish ();
}
-/* ffestc_R620 -- ALLOCATE statement
-
- ffestc_R620(exprlist,stat,stat_token);
-
- Make sure the expression list is valid, then implement it. */
-
-#if FFESTR_F90
-void
-ffestc_R620 (ffesttExprList exprlist, ffebld stat, ffelexToken stat_token)
-{
- ffestc_check_simple_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_branch_begin_ ();
-
- ffestd_R620 (exprlist, stat);
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-/* ffestc_R624 -- NULLIFY statement
-
- ffestc_R624(pointer_name_list);
-
- Make sure pointer_name_list identifies valid pointers for a NULLIFY. */
-
-void
-ffestc_R624 (ffesttExprList pointers)
-{
- ffestc_check_simple_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_branch_begin_ ();
-
- ffestd_R624 (pointers);
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-/* ffestc_R625 -- DEALLOCATE statement
-
- ffestc_R625(exprlist,stat,stat_token);
-
- Make sure the equivalence is valid, then implement it. */
-
-void
-ffestc_R625 (ffesttExprList exprlist, ffebld stat, ffelexToken stat_token)
-{
- ffestc_check_simple_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_branch_begin_ ();
-
- ffestd_R625 (exprlist, stat);
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-#endif
-/* ffestc_let -- R1213 or R737
-
- ffestc_let(...);
-
- Verify that R1213 defined-assignment or R737 assignment-stmt are
- valid here, figure out which one, and implement. */
-
-#if FFESTR_F90
-void
-ffestc_let (ffebld dest, ffebld source, ffelexToken source_token)
-{
- ffestc_R737 (dest, source, source_token);
-}
-
-#endif
/* ffestc_R737 -- Assignment statement
ffestc_R737(dest_expr,source_expr,source_token);
@@ -8647,26 +6467,6 @@ ffestc_R737 (ffebld dest, ffebld source, ffelexToken source_token)
{
ffestc_check_simple_ ();
- switch (ffestw_state (ffestw_stack_top ()))
- {
-#if FFESTR_F90
- case FFESTV_stateWHERE:
- case FFESTV_stateWHERETHEN:
- if (ffestc_order_actionwhere_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- ffestd_R737B (dest, source);
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- return;
-#endif
-
- default:
- break;
- }
-
if (ffestc_order_actionwhere_ () != FFESTC_orderOK_)
return;
ffestc_labeldef_branch_begin_ ();
@@ -8681,130 +6481,6 @@ ffestc_R737 (ffebld dest, ffebld source, ffelexToken source_token)
ffestc_labeldef_branch_end_ ();
}
-/* ffestc_R738 -- Pointer assignment statement
-
- ffestc_R738(dest_expr,source_expr,source_token);
-
- Make sure the assignment is valid. */
-
-#if FFESTR_F90
-void
-ffestc_R738 (ffebld dest, ffebld source, ffelexToken source_token)
-{
- ffestc_check_simple_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_branch_begin_ ();
-
- ffestd_R738 (dest, source);
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-/* ffestc_R740 -- WHERE statement
-
- ffestc_R740(expr,expr_token);
-
- Make sure statement is valid here; implement. */
-
-void
-ffestc_R740 (ffebld expr, ffelexToken expr_token)
-{
- ffestw b;
-
- ffestc_check_simple_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_branch_begin_ ();
-
- b = ffestw_update (ffestw_push (NULL));
- ffestw_set_top_do (b, ffestw_top_do (ffestw_previous (b)));
- ffestw_set_state (b, FFESTV_stateWHERE);
- ffestw_set_blocknum (b, ffestc_blocknum_++);
- ffestw_set_shriek (b, ffestc_shriek_where_lost_);
-
- ffestd_R740 (expr);
-
- /* Leave label finishing to next statement. */
-
-}
-
-/* ffestc_R742 -- WHERE-construct statement
-
- ffestc_R742(expr,expr_token);
-
- Make sure statement is valid here; implement. */
-
-void
-ffestc_R742 (ffebld expr, ffelexToken expr_token)
-{
- ffestw b;
-
- ffestc_check_simple_ ();
- if (ffestc_order_exec_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_notloop_probably_this_wont_work_ ();
-
- b = ffestw_update (ffestw_push (NULL));
- ffestw_set_top_do (b, ffestw_top_do (ffestw_previous (b)));
- ffestw_set_state (b, FFESTV_stateWHERETHEN);
- ffestw_set_blocknum (b, ffestc_blocknum_++);
- ffestw_set_shriek (b, ffestc_shriek_wherethen_);
- ffestw_set_substate (b, 0); /* Haven't seen ELSEWHERE yet. */
-
- ffestd_R742 (expr);
-}
-
-/* ffestc_R744 -- ELSE WHERE statement
-
- ffestc_R744();
-
- Make sure ffestc_kind_ identifies a WHERE block.
- Implement the ELSE of the current WHERE block. */
-
-void
-ffestc_R744 ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_where_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- if (ffestw_substate (ffestw_stack_top ()) != 0)
- {
- ffebad_start (FFEBAD_SECOND_ELSE_WHERE);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ()));
- ffebad_finish ();
- }
-
- ffestw_set_substate (ffestw_stack_top (), 1); /* Saw ELSEWHERE. */
-
- ffestd_R744 ();
-}
-
-/* ffestc_R745 -- END WHERE statement
-
- ffestc_R745();
-
- Make sure ffestc_kind_ identifies a WHERE block.
- Implement the end of the current WHERE block. */
-
-void
-ffestc_R745 ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_where_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- ffestc_shriek_wherethen_ (TRUE);
-}
-
-#endif
/* ffestc_R803 -- Block IF (IF-THEN) statement
ffestc_R803(construct_name,expr,expr_token);
@@ -9072,7 +6748,7 @@ ffestc_R809 (ffelexToken construct_name, ffebld expr, ffelexToken expr_token)
/* Init block to manage CASE list. */
pool = malloc_pool_new ("Select", ffe_pool_any_unit (), 1024);
- s = (ffestwSelect) malloc_new_kp (pool, "Select", sizeof (*s));
+ s = malloc_new_kp (pool, "Select", sizeof (*s));
s->first_rel = (ffestwCase) &s->first_rel;
s->last_rel = (ffestwCase) &s->first_rel;
s->first_stmt = (ffestwCase) &s->first_rel;
@@ -9199,7 +6875,7 @@ ffestc_R810 (ffesttCaseList cases, ffelexToken name)
&& ((ffeinfo_basictype (ffebld_info (caseobj->expr1))
!= s->type)
|| ((ffeinfo_kindtype (ffebld_info (caseobj->expr1))
- != s->kindtype)
+ != s->kindtype)
&& (ffeinfo_kindtype (ffebld_info (caseobj->expr1)) != FFEINFO_kindtypeINTEGER1 ))
|| ((caseobj->range)
&& (caseobj->expr2 != NULL)
@@ -10112,34 +7788,16 @@ ffestc_R840 (ffebld expr, ffelexToken expr_token UNUSED,
ffestc_R841(); */
void
-ffestc_R841 ()
+ffestc_R841 (void)
{
ffestc_check_simple_ ();
if (ffestc_order_actionwhere_ () != FFESTC_orderOK_)
return;
- switch (ffestw_state (ffestw_stack_top ()))
- {
-#if FFESTR_F90
- case FFESTV_stateWHERE:
- case FFESTV_stateWHERETHEN:
- ffestc_labeldef_useless_ ();
-
- ffestd_R841 (TRUE);
-
- /* It's okay that we call ffestc_labeldef_branch_end_ () below,
- since that will be a no-op after calling _useless_ () above. */
- break;
-#endif
-
- default:
- ffestc_labeldef_branch_begin_ ();
-
- ffestd_R841 (FALSE);
+ ffestc_labeldef_branch_begin_ ();
- break;
- }
+ ffestd_R841 (FALSE);
if (ffestc_shriek_after1_ != NULL)
(*ffestc_shriek_after1_) (TRUE);
@@ -10202,7 +7860,7 @@ ffestc_R843 (ffebld expr, ffelexToken expr_token UNUSED)
Make sure an OPEN is valid in the current context, and implement it. */
void
-ffestc_R904 ()
+ffestc_R904 (void)
{
int i;
int expect_file;
@@ -10447,7 +8105,7 @@ ffestc_R904 ()
Make sure a CLOSE is valid in the current context, and implement it. */
void
-ffestc_R907 ()
+ffestc_R907 (void)
{
static const char *const status_strs[] =
{
@@ -10839,7 +8497,7 @@ ffestc_R909_item (ffebld expr, ffelexToken expr_token)
Just wrap up any local activities. */
void
-ffestc_R909_finish ()
+ffestc_R909_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -10860,7 +8518,7 @@ ffestc_R909_finish ()
list. */
void
-ffestc_R910_start ()
+ffestc_R910_start (void)
{
ffestvUnit unit;
ffestvFormat format;
@@ -11079,7 +8737,7 @@ ffestc_R910_item (ffebld expr, ffelexToken expr_token)
Just wrap up any local activities. */
void
-ffestc_R910_finish ()
+ffestc_R910_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -11100,7 +8758,7 @@ ffestc_R910_finish ()
list. */
void
-ffestc_R911_start ()
+ffestc_R911_start (void)
{
ffestvFormat format;
@@ -11164,7 +8822,7 @@ ffestc_R911_item (ffebld expr, ffelexToken expr_token)
Just wrap up any local activities. */
void
-ffestc_R911_finish ()
+ffestc_R911_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -11184,7 +8842,7 @@ ffestc_R911_finish ()
Make sure a BACKSPACE is valid in the current context, and implement it. */
void
-ffestc_R919 ()
+ffestc_R919 (void)
{
ffestc_check_simple_ ();
if (ffestc_order_actionif_ () != FFESTC_orderOK_)
@@ -11209,7 +8867,7 @@ ffestc_R919 ()
Make sure a ENDFILE is valid in the current context, and implement it. */
void
-ffestc_R920 ()
+ffestc_R920 (void)
{
ffestc_check_simple_ ();
if (ffestc_order_actionif_ () != FFESTC_orderOK_)
@@ -11234,7 +8892,7 @@ ffestc_R920 ()
Make sure a REWIND is valid in the current context, and implement it. */
void
-ffestc_R921 ()
+ffestc_R921 (void)
{
ffestc_check_simple_ ();
if (ffestc_order_actionif_ () != FFESTC_orderOK_)
@@ -11259,7 +8917,7 @@ ffestc_R921 ()
Make sure an INQUIRE is valid in the current context, and implement it. */
void
-ffestc_R923A ()
+ffestc_R923A (void)
{
bool by_file;
bool by_unit;
@@ -11336,7 +8994,7 @@ ffestc_R923A ()
list. */
void
-ffestc_R923B_start ()
+ffestc_R923B_start (void)
{
ffestc_check_start_ ();
if (ffestc_order_actionif_ () != FFESTC_orderOK_)
@@ -11374,7 +9032,7 @@ ffestc_R923B_item (ffebld expr, ffelexToken expr_token UNUSED)
Just wrap up any local activities. */
void
-ffestc_R923B_finish ()
+ffestc_R923B_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -11496,124 +9154,6 @@ ffestc_R1103 (ffelexToken name)
ffestc_shriek_end_program_ (TRUE);
}
-/* ffestc_R1105 -- MODULE statement
-
- ffestc_R1105(name_token);
-
- Make sure ffestc_kind_ identifies an empty block. Make sure name_token
- gives a valid name. Implement the beginning of a module. */
-
-#if FFESTR_F90
-void
-ffestc_R1105 (ffelexToken name)
-{
- ffestw b;
-
- assert (name != NULL);
-
- ffestc_check_simple_ ();
- if (ffestc_order_unit_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- ffestc_blocknum_ = 0;
- b = ffestw_update (ffestw_push (NULL));
- ffestw_set_top_do (b, NULL);
- ffestw_set_state (b, FFESTV_stateMODULE0);
- ffestw_set_blocknum (b, ffestc_blocknum_++);
- ffestw_set_shriek (b, ffestc_shriek_module_);
- ffestw_set_name (b, ffelex_token_use (name));
-
- ffestd_R1105 (name);
-}
-
-/* ffestc_R1106 -- END MODULE statement
-
- ffestc_R1106(name_token);
-
- Make sure ffestc_kind_ identifies the current kind of program unit. If not
- NULL, make sure name_token gives the correct name. Implement the end
- of the current program unit. */
-
-void
-ffestc_R1106 (ffelexToken name)
-{
- ffestc_check_simple_ ();
- if (ffestc_order_module_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- if ((name != NULL)
- && (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0))
- {
- ffebad_start (FFEBAD_UNIT_WRONG_NAME);
- ffebad_here (0, ffelex_token_where_line (name),
- ffelex_token_where_column (name));
- ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())),
- ffelex_token_where_column (ffestw_name (ffestw_stack_top ())));
- ffebad_finish ();
- }
-
- ffestc_shriek_module_ (TRUE);
-}
-
-/* ffestc_R1107_start -- USE statement list begin
-
- ffestc_R1107_start();
-
- Verify that USE is valid here, and begin accepting items in the list. */
-
-void
-ffestc_R1107_start (ffelexToken name, bool only)
-{
- ffestc_check_start_ ();
- if (ffestc_order_use_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_useless_ ();
-
- ffestd_R1107_start (name, only);
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_R1107_item -- USE statement for name
-
- ffestc_R1107_item(local_token,use_token);
-
- Make sure name_token identifies a valid object to be USEed. local_token
- may be NULL if _start_ was called with only==TRUE. */
-
-void
-ffestc_R1107_item (ffelexToken local, ffelexToken use)
-{
- ffestc_check_item_ ();
- assert (use != NULL);
- if (!ffestc_ok_)
- return;
-
- ffestd_R1107_item (local, use);
-}
-
-/* ffestc_R1107_finish -- USE statement list complete
-
- ffestc_R1107_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_R1107_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_R1107_finish ();
-}
-
-#endif
/* ffestc_R1111 -- BLOCK DATA statement
ffestc_R1111(name_token);
@@ -11707,139 +9247,6 @@ ffestc_R1112 (ffelexToken name)
ffestc_shriek_blockdata_ (TRUE);
}
-/* ffestc_R1202 -- INTERFACE statement
-
- ffestc_R1202(operator,defined_name);
-
- Make sure ffestc_kind_ identifies an INTERFACE block.
- Implement the end of the current interface.
-
- 15-May-90 JCB 1.1
- Allow no operator or name to mean INTERFACE by itself; missed this
- valid form when originally doing syntactic analysis code. */
-
-#if FFESTR_F90
-void
-ffestc_R1202 (ffestpDefinedOperator operator, ffelexToken name)
-{
- ffestw b;
-
- ffestc_check_simple_ ();
- if (ffestc_order_interfacespec_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- b = ffestw_update (ffestw_push (NULL));
- ffestw_set_top_do (b, NULL);
- ffestw_set_state (b, FFESTV_stateINTERFACE0);
- ffestw_set_blocknum (b, 0);
- ffestw_set_shriek (b, ffestc_shriek_interface_);
-
- if ((operator == FFESTP_definedoperatorNone) && (name == NULL))
- ffestw_set_substate (b, 0); /* No generic-spec, so disallow MODULE
- PROCEDURE. */
- else
- ffestw_set_substate (b, 1); /* MODULE PROCEDURE ok. */
-
- ffestd_R1202 (operator, name);
-
- ffe_init_4 ();
-}
-
-/* ffestc_R1203 -- END INTERFACE statement
-
- ffestc_R1203();
-
- Make sure ffestc_kind_ identifies an INTERFACE block.
- Implement the end of the current interface. */
-
-void
-ffestc_R1203 ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_interface_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- ffestc_shriek_interface_ (TRUE);
-
- ffe_terminate_4 ();
-}
-
-/* ffestc_R1205_start -- MODULE PROCEDURE statement list begin
-
- ffestc_R1205_start();
-
- Verify that MODULE PROCEDURE is valid here, and begin accepting items in
- the list. */
-
-void
-ffestc_R1205_start ()
-{
- ffestc_check_start_ ();
- if (ffestc_order_interface_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_useless_ ();
-
- if (ffestw_substate (ffestw_stack_top ()) == 0)
- {
- ffebad_start (FFEBAD_INVALID_MODULE_PROCEDURE);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ()));
- ffebad_finish ();
- ffestc_ok_ = FALSE;
- return;
- }
-
- if (ffestw_state (ffestw_stack_top ()) == FFESTV_stateINTERFACE0)
- {
- ffestw_update (NULL); /* Update state line/col info. */
- ffestw_set_state (ffestw_stack_top (), FFESTV_stateINTERFACE1);
- }
-
- ffestd_R1205_start ();
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_R1205_item -- MODULE PROCEDURE statement for name
-
- ffestc_R1205_item(name_token);
-
- Make sure name_token identifies a valid object to be MODULE PROCEDUREed. */
-
-void
-ffestc_R1205_item (ffelexToken name)
-{
- ffestc_check_item_ ();
- assert (name != NULL);
- if (!ffestc_ok_)
- return;
-
- ffestd_R1205_item (name);
-}
-
-/* ffestc_R1205_finish -- MODULE PROCEDURE statement list complete
-
- ffestc_R1205_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_R1205_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_R1205_finish ();
-}
-
-#endif
/* ffestc_R1207_start -- EXTERNAL statement list begin
ffestc_R1207_start();
@@ -11847,7 +9254,7 @@ ffestc_R1205_finish ()
Verify that EXTERNAL is valid here, and begin accepting items in the list. */
void
-ffestc_R1207_start ()
+ffestc_R1207_start (void)
{
ffestc_check_start_ ();
if (ffestc_order_progspec_ () != FFESTC_orderOK_)
@@ -11921,7 +9328,7 @@ ffestc_R1207_item (ffelexToken name)
Just wrap up any local activities. */
void
-ffestc_R1207_finish ()
+ffestc_R1207_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -11937,7 +9344,7 @@ ffestc_R1207_finish ()
Verify that INTRINSIC is valid here, and begin accepting items in the list. */
void
-ffestc_R1208_start ()
+ffestc_R1208_start (void)
{
ffestc_check_start_ ();
if (ffestc_order_progspec_ () != FFESTC_orderOK_)
@@ -12040,7 +9447,7 @@ ffestc_R1208_item (ffelexToken name)
Just wrap up any local activities. */
void
-ffestc_R1208_finish ()
+ffestc_R1208_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -12104,29 +9511,6 @@ ffestc_R1212 (ffebld expr, ffelexToken expr_token UNUSED)
ffestc_labeldef_branch_end_ ();
}
-/* ffestc_R1213 -- Defined assignment statement
-
- ffestc_R1213(dest_expr,source_expr,source_token);
-
- Make sure the assignment is valid. */
-
-#if FFESTR_F90
-void
-ffestc_R1213 (ffebld dest, ffebld source, ffelexToken source_token)
-{
- ffestc_check_simple_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_branch_begin_ ();
-
- ffestd_R1213 (dest, source);
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-#endif
/* ffestc_R1219 -- FUNCTION statement
ffestc_R1219(funcname,arglist,ending_token,kind,kindt,len,lent,
@@ -12702,26 +10086,6 @@ ffestc_R1227 (ffebld expr, ffelexToken expr_token)
ffestc_labeldef_branch_end_ ();
}
-/* ffestc_R1228 -- CONTAINS statement
-
- ffestc_R1228(); */
-
-#if FFESTR_F90
-void
-ffestc_R1228 ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_contains_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- ffestd_R1228 ();
-
- ffe_terminate_3 ();
- ffe_init_3 ();
-}
-
-#endif
/* ffestc_R1229_start -- STMTFUNCTION statement begin
ffestc_R1229_start(func_name,func_arg_list,close_paren);
@@ -12860,255 +10224,6 @@ ffestc_S3P4 (ffebld filename, ffelexToken filename_token UNUSED)
ffestd_S3P4 (filename);
}
-/* ffestc_V003_start -- STRUCTURE statement list begin
-
- ffestc_V003_start(structure_name);
-
- Verify that STRUCTURE is valid here, and begin accepting items in the list. */
-
-#if FFESTR_VXT
-void
-ffestc_V003_start (ffelexToken structure_name)
-{
- ffestw b;
-
- ffestc_check_start_ ();
- if (ffestc_order_vxtstructure_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_useless_ ();
-
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateSTRUCTURE:
- case FFESTV_stateMAP:
- ffestc_local_.V003.list_state = 2; /* Require at least one field
- name. */
- ffestw_set_substate (ffestw_stack_top (), 1); /* Seen at least one
- member. */
- break;
-
- default:
- ffestc_local_.V003.list_state = 0; /* No field names required. */
- if (structure_name == NULL)
- {
- ffebad_start (FFEBAD_STRUCT_MISSING_NAME);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_finish ();
- }
- break;
- }
-
- b = ffestw_update (ffestw_push (NULL));
- ffestw_set_top_do (b, NULL);
- ffestw_set_state (b, FFESTV_stateSTRUCTURE);
- ffestw_set_blocknum (b, 0);
- ffestw_set_shriek (b, ffestc_shriek_structure_);
- ffestw_set_substate (b, 0); /* No field-declarations seen yet. */
-
- ffestd_V003_start (structure_name);
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_V003_item -- STRUCTURE statement for object-name
-
- ffestc_V003_item(name_token,dim_list);
-
- Make sure name_token identifies a valid object to be STRUCTUREd. */
-
-void
-ffestc_V003_item (ffelexToken name, ffesttDimList dims)
-{
- ffestc_check_item_ ();
- assert (name != NULL);
- if (!ffestc_ok_)
- return;
-
- if (ffestc_local_.V003.list_state < 2)
- {
- if (ffestc_local_.V003.list_state == 0)
- {
- ffestc_local_.V003.list_state = 1;
- ffebad_start (FFEBAD_STRUCT_IGNORING_FIELD);
- ffebad_here (0, ffelex_token_where_line (name),
- ffelex_token_where_column (name));
- ffebad_finish ();
- }
- return;
- }
- ffestc_local_.V003.list_state = 3; /* Have at least one field name. */
-
- if (dims != NULL)
- ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE);
-
- ffestd_V003_item (name, dims);
-}
-
-/* ffestc_V003_finish -- STRUCTURE statement list complete
-
- ffestc_V003_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_V003_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- if (ffestc_local_.V003.list_state == 2)
- {
- ffebad_start (FFEBAD_STRUCT_MISSING_FIELD);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_here (1, ffestw_line (ffestw_previous (ffestw_stack_top ())),
- ffestw_col (ffestw_previous (ffestw_stack_top ())));
- ffebad_finish ();
- }
-
- ffestd_V003_finish ();
-}
-
-/* ffestc_V004 -- END STRUCTURE statement
-
- ffestc_V004();
-
- Make sure ffestc_kind_ identifies a STRUCTURE block.
- Implement the end of the current STRUCTURE block. */
-
-void
-ffestc_V004 ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_structure_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- if (ffestw_substate (ffestw_stack_top ()) != 1)
- {
- ffebad_start (FFEBAD_STRUCT_NO_COMPONENTS);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ()));
- ffebad_finish ();
- }
-
- ffestc_shriek_structure_ (TRUE);
-}
-
-/* ffestc_V009 -- UNION statement
-
- ffestc_V009(); */
-
-void
-ffestc_V009 ()
-{
- ffestw b;
-
- ffestc_check_simple_ ();
- if (ffestc_order_structure_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- ffestw_set_substate (ffestw_stack_top (), 1); /* Seen at least one member. */
-
- b = ffestw_update (ffestw_push (NULL));
- ffestw_set_top_do (b, NULL);
- ffestw_set_state (b, FFESTV_stateUNION);
- ffestw_set_blocknum (b, 0);
- ffestw_set_shriek (b, ffestc_shriek_union_);
- ffestw_set_substate (b, 0); /* No map decls seen yet. */
-
- ffestd_V009 ();
-}
-
-/* ffestc_V010 -- END UNION statement
-
- ffestc_V010();
-
- Make sure ffestc_kind_ identifies a UNION block.
- Implement the end of the current UNION block. */
-
-void
-ffestc_V010 ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_union_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- if (ffestw_substate (ffestw_stack_top ()) != 2)
- {
- ffebad_start (FFEBAD_UNION_NO_TWO_MAPS);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ()));
- ffebad_finish ();
- }
-
- ffestc_shriek_union_ (TRUE);
-}
-
-/* ffestc_V012 -- MAP statement
-
- ffestc_V012(); */
-
-void
-ffestc_V012 ()
-{
- ffestw b;
-
- ffestc_check_simple_ ();
- if (ffestc_order_union_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- if (ffestw_substate (ffestw_stack_top ()) != 2)
- ffestw_substate (ffestw_stack_top ())++; /* 0=>1, 1=>2. */
-
- b = ffestw_update (ffestw_push (NULL));
- ffestw_set_top_do (b, NULL);
- ffestw_set_state (b, FFESTV_stateMAP);
- ffestw_set_blocknum (b, 0);
- ffestw_set_shriek (b, ffestc_shriek_map_);
- ffestw_set_substate (b, 0); /* No field-declarations seen yet. */
-
- ffestd_V012 ();
-}
-
-/* ffestc_V013 -- END MAP statement
-
- ffestc_V013();
-
- Make sure ffestc_kind_ identifies a MAP block.
- Implement the end of the current MAP block. */
-
-void
-ffestc_V013 ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_map_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_useless_ ();
-
- if (ffestw_substate (ffestw_stack_top ()) != 1)
- {
- ffebad_start (FFEBAD_MAP_NO_COMPONENTS);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ()));
- ffebad_finish ();
- }
-
- ffestc_shriek_map_ (TRUE);
-}
-
-#endif
/* ffestc_V014_start -- VOLATILE statement list begin
ffestc_V014_start();
@@ -13117,7 +10232,7 @@ ffestc_V013 ()
list. */
void
-ffestc_V014_start ()
+ffestc_V014_start (void)
{
ffestc_check_start_ ();
if (ffestc_order_progspec_ () != FFESTC_orderOK_)
@@ -13173,7 +10288,7 @@ ffestc_V014_item_cblock (ffelexToken name)
Just wrap up any local activities. */
void
-ffestc_V014_finish ()
+ffestc_V014_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -13182,284 +10297,6 @@ ffestc_V014_finish ()
ffestd_V014_finish ();
}
-/* ffestc_V016_start -- RECORD statement list begin
-
- ffestc_V016_start();
-
- Verify that RECORD is valid here, and begin accepting items in the list. */
-
-#if FFESTR_VXT
-void
-ffestc_V016_start ()
-{
- ffestc_check_start_ ();
- if (ffestc_order_record_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_useless_ ();
-
- switch (ffestw_state (ffestw_stack_top ()))
- {
- case FFESTV_stateSTRUCTURE:
- case FFESTV_stateMAP:
- ffestw_set_substate (ffestw_stack_top (), 1); /* Seen at least one
- member. */
- break;
-
- default:
- break;
- }
-
- ffestd_V016_start ();
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_V016_item_structure -- RECORD statement for common-block-name
-
- ffestc_V016_item_structure(name_token);
-
- Make sure name_token identifies a valid structure to be RECORDed. */
-
-void
-ffestc_V016_item_structure (ffelexToken name)
-{
- ffestc_check_item_ ();
- assert (name != NULL);
- if (!ffestc_ok_)
- return;
-
- ffestd_V016_item_structure (name);
-}
-
-/* ffestc_V016_item_object -- RECORD statement for object-name
-
- ffestc_V016_item_object(name_token,dim_list);
-
- Make sure name_token identifies a valid object to be RECORDd. */
-
-void
-ffestc_V016_item_object (ffelexToken name, ffesttDimList dims)
-{
- ffestc_check_item_ ();
- assert (name != NULL);
- if (!ffestc_ok_)
- return;
-
- if (dims != NULL)
- ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE);
-
- ffestd_V016_item_object (name, dims);
-}
-
-/* ffestc_V016_finish -- RECORD statement list complete
-
- ffestc_V016_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_V016_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_V016_finish ();
-}
-
-/* ffestc_V018_start -- REWRITE(...) statement list begin
-
- ffestc_V018_start();
-
- Verify that REWRITE is valid here, and begin accepting items in the
- list. */
-
-void
-ffestc_V018_start ()
-{
- ffestvFormat format;
-
- ffestc_check_start_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_branch_begin_ ();
-
- if (!ffestc_subr_is_branch_
- (&ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixERR])
- || !ffestc_subr_is_format_
- (&ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT])
- || !ffestc_subr_is_present_ ("UNIT",
- &ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT]))
- {
- ffestc_ok_ = FALSE;
- return;
- }
-
- format = ffestc_subr_format_
- (&ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT]);
- switch (format)
- {
- case FFESTV_formatNAMELIST:
- case FFESTV_formatASTERISK:
- ffebad_start (FFEBAD_CONFLICTING_SPECS);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- assert (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw_or_val_present);
- if (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw_present)
- {
- ffebad_here (0, ffelex_token_where_line
- (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw),
- ffelex_token_where_column
- (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw));
- }
- else
- {
- ffebad_here (1, ffelex_token_where_line
- (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].value),
- ffelex_token_where_column
- (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].value));
- }
- ffebad_finish ();
- ffestc_ok_ = FALSE;
- return;
-
- default:
- break;
- }
-
- ffestd_V018_start (format);
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_V018_item -- REWRITE statement i/o item
-
- ffestc_V018_item(expr,expr_token);
-
- Implement output-list expression. */
-
-void
-ffestc_V018_item (ffebld expr, ffelexToken expr_token)
-{
- ffestc_check_item_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_V018_item (expr);
-}
-
-/* ffestc_V018_finish -- REWRITE statement list complete
-
- ffestc_V018_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_V018_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_V018_finish ();
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-/* ffestc_V019_start -- ACCEPT statement list begin
-
- ffestc_V019_start();
-
- Verify that ACCEPT is valid here, and begin accepting items in the
- list. */
-
-void
-ffestc_V019_start ()
-{
- ffestvFormat format;
-
- ffestc_check_start_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_branch_begin_ ();
-
- if (!ffestc_subr_is_format_
- (&ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT]))
- {
- ffestc_ok_ = FALSE;
- return;
- }
-
- format = ffestc_subr_format_
- (&ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT]);
- ffestc_namelist_ = (format == FFESTV_formatNAMELIST);
-
- ffestd_V019_start (format);
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_V019_item -- ACCEPT statement i/o item
-
- ffestc_V019_item(expr,expr_token);
-
- Implement output-list expression. */
-
-void
-ffestc_V019_item (ffebld expr, ffelexToken expr_token)
-{
- ffestc_check_item_ ();
- if (!ffestc_ok_)
- return;
-
- if (ffestc_namelist_ != 0)
- {
- if (ffestc_namelist_ == 1)
- {
- ffestc_namelist_ = 2;
- ffebad_start (FFEBAD_NAMELIST_ITEMS);
- ffebad_here (0, ffelex_token_where_line (expr_token),
- ffelex_token_where_column (expr_token));
- ffebad_finish ();
- }
- return;
- }
-
- ffestd_V019_item (expr);
-}
-
-/* ffestc_V019_finish -- ACCEPT statement list complete
-
- ffestc_V019_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_V019_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_V019_finish ();
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-#endif
/* ffestc_V020_start -- TYPE statement list begin
ffestc_V020_start();
@@ -13468,7 +10305,7 @@ ffestc_V019_finish ()
list. */
void
-ffestc_V020_start ()
+ffestc_V020_start (void)
{
ffestvFormat format;
@@ -13532,7 +10369,7 @@ ffestc_V020_item (ffebld expr, ffelexToken expr_token)
Just wrap up any local activities. */
void
-ffestc_V020_finish ()
+ffestc_V020_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -13545,277 +10382,6 @@ ffestc_V020_finish ()
ffestc_labeldef_branch_end_ ();
}
-/* ffestc_V021 -- DELETE statement
-
- ffestc_V021();
-
- Make sure a DELETE is valid in the current context, and implement it. */
-
-#if FFESTR_VXT
-void
-ffestc_V021 ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_branch_begin_ ();
-
- if (ffestc_subr_is_branch_
- (&ffestp_file.delete.delete_spec[FFESTP_deleteixERR])
- && ffestc_subr_is_present_ ("UNIT",
- &ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT]))
- ffestd_V021 ();
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-/* ffestc_V022 -- UNLOCK statement
-
- ffestc_V022();
-
- Make sure a UNLOCK is valid in the current context, and implement it. */
-
-void
-ffestc_V022 ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_branch_begin_ ();
-
- if (ffestc_subr_is_branch_
- (&ffestp_file.beru.beru_spec[FFESTP_beruixERR])
- && ffestc_subr_is_present_ ("UNIT",
- &ffestp_file.beru.beru_spec[FFESTP_beruixUNIT]))
- ffestd_V022 ();
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-/* ffestc_V023_start -- ENCODE(...) statement list begin
-
- ffestc_V023_start();
-
- Verify that ENCODE is valid here, and begin accepting items in the
- list. */
-
-void
-ffestc_V023_start ()
-{
- ffestc_check_start_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_branch_begin_ ();
-
- if (!ffestc_subr_is_branch_
- (&ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixERR]))
- {
- ffestc_ok_ = FALSE;
- return;
- }
-
- ffestd_V023_start ();
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_V023_item -- ENCODE statement i/o item
-
- ffestc_V023_item(expr,expr_token);
-
- Implement output-list expression. */
-
-void
-ffestc_V023_item (ffebld expr, ffelexToken expr_token)
-{
- ffestc_check_item_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_V023_item (expr);
-}
-
-/* ffestc_V023_finish -- ENCODE statement list complete
-
- ffestc_V023_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_V023_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_V023_finish ();
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-/* ffestc_V024_start -- DECODE(...) statement list begin
-
- ffestc_V024_start();
-
- Verify that DECODE is valid here, and begin accepting items in the
- list. */
-
-void
-ffestc_V024_start ()
-{
- ffestc_check_start_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_branch_begin_ ();
-
- if (!ffestc_subr_is_branch_
- (&ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixERR]))
- {
- ffestc_ok_ = FALSE;
- return;
- }
-
- ffestd_V024_start ();
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_V024_item -- DECODE statement i/o item
-
- ffestc_V024_item(expr,expr_token);
-
- Implement output-list expression. */
-
-void
-ffestc_V024_item (ffebld expr, ffelexToken expr_token)
-{
- ffestc_check_item_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_V024_item (expr);
-}
-
-/* ffestc_V024_finish -- DECODE statement list complete
-
- ffestc_V024_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_V024_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_V024_finish ();
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-/* ffestc_V025_start -- DEFINEFILE statement list begin
-
- ffestc_V025_start();
-
- Verify that DEFINEFILE is valid here, and begin accepting items in the
- list. */
-
-void
-ffestc_V025_start ()
-{
- ffestc_check_start_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- {
- ffestc_ok_ = FALSE;
- return;
- }
- ffestc_labeldef_branch_begin_ ();
-
- ffestd_V025_start ();
-
- ffestc_ok_ = TRUE;
-}
-
-/* ffestc_V025_item -- DEFINE FILE statement item
-
- ffestc_V025_item(u,ut,m,mt,n,nt,asv,asvt);
-
- Implement item. */
-
-void
-ffestc_V025_item (ffebld u, ffelexToken ut, ffebld m, ffelexToken mt,
- ffebld n, ffelexToken nt, ffebld asv, ffelexToken asvt)
-{
- ffestc_check_item_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_V025_item (u, m, n, asv);
-}
-
-/* ffestc_V025_finish -- DEFINE FILE statement list complete
-
- ffestc_V025_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestc_V025_finish ()
-{
- ffestc_check_finish_ ();
- if (!ffestc_ok_)
- return;
-
- ffestd_V025_finish ();
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-/* ffestc_V026 -- FIND statement
-
- ffestc_V026();
-
- Make sure a FIND is valid in the current context, and implement it. */
-
-void
-ffestc_V026 ()
-{
- ffestc_check_simple_ ();
- if (ffestc_order_actionif_ () != FFESTC_orderOK_)
- return;
- ffestc_labeldef_branch_begin_ ();
-
- if (ffestc_subr_is_branch_
- (&ffestp_file.find.find_spec[FFESTP_findixERR])
- && ffestc_subr_is_present_ ("UNIT",
- &ffestp_file.find.find_spec[FFESTP_findixUNIT])
- && ffestc_subr_is_present_ ("REC",
- &ffestp_file.find.find_spec[FFESTP_findixREC]))
- ffestd_V026 ();
-
- if (ffestc_shriek_after1_ != NULL)
- (*ffestc_shriek_after1_) (TRUE);
- ffestc_labeldef_branch_end_ ();
-}
-
-#endif
/* ffestc_V027_start -- VXT PARAMETER statement list begin
ffestc_V027_start();
@@ -13823,7 +10389,7 @@ ffestc_V026 ()
Verify that PARAMETER is valid here, and begin accepting items in the list. */
void
-ffestc_V027_start ()
+ffestc_V027_start (void)
{
ffestc_check_start_ ();
if (ffestc_order_parameter_ () != FFESTC_orderOK_)
@@ -13863,7 +10429,7 @@ ffestc_V027_item (ffelexToken dest_token, ffebld source,
Just wrap up any local activities. */
void
-ffestc_V027_finish ()
+ffestc_V027_finish (void)
{
ffestc_check_finish_ ();
if (!ffestc_ok_)
@@ -13876,7 +10442,7 @@ ffestc_V027_finish ()
like the statement for a logical IF are reset. */
void
-ffestc_any ()
+ffestc_any (void)
{
ffestc_check_simple_ ();
diff --git a/contrib/gcc/f/stc.h b/contrib/gcc/f/stc.h
index 8b2f7c3aafe5..37feba69b853 100644
--- a/contrib/gcc/f/stc.h
+++ b/contrib/gcc/f/stc.h
@@ -1,5 +1,5 @@
/* stc.h -- Private #include File (module.h template V1.0)
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -77,36 +77,8 @@ void ffestc_init_4 (void);
bool ffestc_is_decl_not_R1219 (void);
bool ffestc_is_entry_in_subr (void);
bool ffestc_is_let_not_V027 (void);
-#if FFESTR_F90
-void ffestc_let (ffebld dest, ffebld source, ffelexToken source_token);
-#else
#define ffestc_let ffestc_R737
-#endif
-#if FFESTR_F90
-void ffestc_module (ffelexToken module_name, ffelexToken procedure_name);
-#endif
-#if FFESTR_F90
-void ffestc_private (void);
-#endif
void ffestc_terminate_4 (void);
-#if FFESTR_F90
-void ffestc_R423A (void);
-void ffestc_R423B (void);
-void ffestc_R424 (ffelexToken access, ffestrOther access_kw, ffelexToken name);
-void ffestc_R425 (ffelexToken name);
-void ffestc_R426_start (ffestpType type, ffelexToken typet, ffebld kind,
- ffelexToken kindt, ffebld len, ffelexToken lent);
-void ffestc_R426_attrib (ffestpAttrib attrib, ffelexToken attribt,
- ffestrOther intent_kw, ffesttDimList dims);
-void ffestc_R426_item (ffelexToken name, ffebld kind, ffelexToken kindt,
- ffesttDimList dims, ffebld len, ffelexToken lent, ffebld init,
- ffelexToken initt, bool clist);
-void ffestc_R426_itemstartvals (void);
-void ffestc_R426_itemvalue (ffebld repeat, ffelexToken repeat_token,
- ffebld value, ffelexToken value_token);
-void ffestc_R426_itemendvals (ffelexToken t);
-void ffestc_R426_finish (void);
-#endif
void ffestc_R501_start (ffestpType type, ffelexToken typet, ffebld kind,
ffelexToken kindt, ffebld len, ffelexToken lent);
void ffestc_R501_attrib (ffestpAttrib attrib, ffelexToken attribt,
@@ -119,22 +91,6 @@ void ffestc_R501_itemvalue (ffebld repeat, ffelexToken repeat_token,
ffebld value, ffelexToken value_token);
void ffestc_R501_itemendvals (ffelexToken t);
void ffestc_R501_finish (void);
-#if FFESTR_F90
-void ffestc_R519_start (ffelexToken intent, ffestrOther intent_kw);
-void ffestc_R519_item (ffelexToken name);
-void ffestc_R519_finish (void);
-void ffestc_R520_start (void);
-void ffestc_R520_item (ffelexToken name);
-void ffestc_R520_finish (void);
-void ffestc_R521A (void);
-void ffestc_R521Astart (void);
-void ffestc_R521Aitem (ffelexToken name);
-void ffestc_R521Afinish (void);
-void ffestc_R521B (void);
-void ffestc_R521Bstart (void);
-void ffestc_R521Bitem (ffelexToken name);
-void ffestc_R521Bfinish (void);
-#endif
void ffestc_R522 (void);
void ffestc_R522start (void);
void ffestc_R522item_object (ffelexToken name);
@@ -143,17 +99,6 @@ void ffestc_R522finish (void);
void ffestc_R524_start (bool virtual);
void ffestc_R524_item (ffelexToken name, ffesttDimList dims);
void ffestc_R524_finish (void);
-#if FFESTR_F90
-void ffestc_R525_start (void);
-void ffestc_R525_item (ffelexToken name, ffesttDimList dims);
-void ffestc_R525_finish (void);
-void ffestc_R526_start (void);
-void ffestc_R526_item (ffelexToken name, ffesttDimList dims);
-void ffestc_R526_finish (void);
-void ffestc_R527_start (void);
-void ffestc_R527_item (ffelexToken name, ffesttDimList dims);
-void ffestc_R527_finish (void);
-#endif
void ffestc_R528_start (void);
void ffestc_R528_item_object (ffebld expr, ffelexToken expr_token);
void ffestc_R528_item_startvals (void);
@@ -181,21 +126,7 @@ void ffestc_R547_start (void);
void ffestc_R547_item_object (ffelexToken name, ffesttDimList dims);
void ffestc_R547_item_cblock (ffelexToken name);
void ffestc_R547_finish (void);
-#if FFESTR_F90
-void ffestc_R620 (ffesttExprList objects, ffebld stat,
- ffelexToken stat_token);
-void ffestc_R624 (ffesttExprList pointers);
-void ffestc_R625 (ffesttExprList objects, ffebld stat,
- ffelexToken stat_token);
-#endif
void ffestc_R737 (ffebld dest, ffebld source, ffelexToken source_token);
-#if FFESTR_F90
-void ffestc_R738 (ffebld dest, ffebld source, ffelexToken source_token);
-void ffestc_R740 (ffebld expr, ffelexToken expr_token);
-void ffestc_R742 (ffebld expr, ffelexToken expr_token);
-void ffestc_R744 (void);
-void ffestc_R745 (void);
-#endif
void ffestc_R803 (ffelexToken construct_name, ffebld expr,
ffelexToken expr_token);
void ffestc_R804 (ffebld expr, ffelexToken expr_token, ffelexToken name);
@@ -251,22 +182,8 @@ void ffestc_R923B_finish (void);
void ffestc_R1001 (ffesttFormatList f);
void ffestc_R1102 (ffelexToken name);
void ffestc_R1103 (ffelexToken name);
-#if FFESTR_F90
-void ffestc_R1105 (ffelexToken name);
-void ffestc_R1106 (ffelexToken name);
-void ffestc_R1107_start (ffelexToken name, bool only);
-void ffestc_R1107_item (ffelexToken local, ffelexToken use);
-void ffestc_R1107_finish (void);
-#endif
void ffestc_R1111 (ffelexToken name);
void ffestc_R1112 (ffelexToken name);
-#if FFESTR_F90
-void ffestc_R1202 (ffestpDefinedOperator operator, ffelexToken name);
-void ffestc_R1203 (void);
-void ffestc_R1205_start (void);
-void ffestc_R1205_item (ffelexToken name);
-void ffestc_R1205_finish (void);
-#endif
void ffestc_R1207_start (void);
void ffestc_R1207_item (ffelexToken name);
void ffestc_R1207_finish (void);
@@ -274,9 +191,6 @@ void ffestc_R1208_start (void);
void ffestc_R1208_item (ffelexToken name);
void ffestc_R1208_finish (void);
void ffestc_R1212 (ffebld expr, ffelexToken expr_token);
-#if FFESTR_F90
-void ffestc_R1213 (ffebld dest, ffebld source, ffelexToken source_token);
-#endif
void ffestc_R1219 (ffelexToken funcname, ffesttTokenList args,
ffelexToken final, ffestpType type, ffebld kind, ffelexToken kindt,
ffebld len, ffelexToken lent, ffelexToken recursive, ffelexToken result);
@@ -287,57 +201,17 @@ void ffestc_R1225 (ffelexToken name);
void ffestc_R1226 (ffelexToken entryname, ffesttTokenList args,
ffelexToken final);
void ffestc_R1227 (ffebld expr, ffelexToken expr_token);
-#if FFESTR_F90
-void ffestc_R1228 (void);
-#endif
void ffestc_R1229_start (ffelexToken name, ffesttTokenList args,
ffelexToken final);
void ffestc_R1229_finish (ffebld expr, ffelexToken expr_token);
void ffestc_S3P4 (ffebld filename, ffelexToken filename_token);
-#if FFESTR_VXT
-void ffestc_V003_start (ffelexToken structure_name);
-void ffestc_V003_item (ffelexToken name, ffesttDimList dims);
-void ffestc_V003_finish (void);
-void ffestc_V004 (void);
-void ffestc_V009 (void);
-void ffestc_V010 (void);
-void ffestc_V012 (void);
-void ffestc_V013 (void);
-#endif
void ffestc_V014_start (void);
void ffestc_V014_item_object (ffelexToken name);
void ffestc_V014_item_cblock (ffelexToken name);
void ffestc_V014_finish (void);
-#if FFESTR_VXT
-void ffestc_V016_start (void);
-void ffestc_V016_item_structure (ffelexToken name);
-void ffestc_V016_item_object (ffelexToken name, ffesttDimList dims);
-void ffestc_V016_finish (void);
-void ffestc_V018_start (void);
-void ffestc_V018_item (ffebld expr, ffelexToken expr_token);
-void ffestc_V018_finish (void);
-void ffestc_V019_start (void);
-void ffestc_V019_item (ffebld expr, ffelexToken expr_token);
-void ffestc_V019_finish (void);
-#endif
void ffestc_V020_start (void);
void ffestc_V020_item (ffebld expr, ffelexToken expr_token);
void ffestc_V020_finish (void);
-#if FFESTR_VXT
-void ffestc_V021 (void);
-void ffestc_V022 (void);
-void ffestc_V023_start (void);
-void ffestc_V023_item (ffebld expr, ffelexToken expr_token);
-void ffestc_V023_finish (void);
-void ffestc_V024_start (void);
-void ffestc_V024_item (ffebld expr, ffelexToken expr_token);
-void ffestc_V024_finish (void);
-void ffestc_V025_start (void);
-void ffestc_V025_item (ffebld u, ffelexToken ut, ffebld m, ffelexToken mt,
- ffebld n, ffelexToken nt, ffebld asv, ffelexToken asvt);
-void ffestc_V025_finish (void);
-void ffestc_V026 (void);
-#endif
void ffestc_V027_start (void);
void ffestc_V027_item (ffelexToken dest_token, ffebld source,
ffelexToken source_token);
diff --git a/contrib/gcc/f/std.c b/contrib/gcc/f/std.c
index bd2add21f652..09f04198f0a8 100644
--- a/contrib/gcc/f/std.c
+++ b/contrib/gcc/f/std.c
@@ -1,5 +1,5 @@
/* std.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 1996, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2000, 2002, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -115,21 +115,7 @@ typedef enum
FFESTD_stmtidR1225_, /* END_SUBROUTINE */
FFESTD_stmtidR1226_, /* ENTRY */
FFESTD_stmtidR1227_, /* RETURN */
-#if FFESTR_VXT
- FFESTD_stmtidV018_, /* REWRITE */
- FFESTD_stmtidV019_, /* ACCEPT */
-#endif
FFESTD_stmtidV020_, /* TYPE */
-#if FFESTR_VXT
- FFESTD_stmtidV021_, /* DELETE */
- FFESTD_stmtidV022_, /* UNLOCK */
- FFESTD_stmtidV023_, /* ENCODE */
- FFESTD_stmtidV024_, /* DECODE */
- FFESTD_stmtidV025start_, /* DEFINEFILE (start) */
- FFESTD_stmtidV025item_, /* (DEFINEFILE item) */
- FFESTD_stmtidV025finish_, /* (DEFINEFILE finish) */
- FFESTD_stmtidV026_, /* FIND */
-#endif
FFESTD_stmtid_,
} ffestdStmtId_;
@@ -407,24 +393,6 @@ struct _ffestd_stmt_
ffebld expr;
}
R1227;
-#if FFESTR_VXT
- struct
- {
- mallocPool pool;
- ffestpRewriteStmt *params;
- ffestvFormat format;
- ffestdExprItem_ list;
- }
- V018;
- struct
- {
- mallocPool pool;
- ffestpAcceptStmt *params;
- ffestvFormat format;
- ffestdExprItem_ list;
- }
- V019;
-#endif
struct
{
mallocPool pool;
@@ -433,52 +401,6 @@ struct _ffestd_stmt_
ffestdExprItem_ list;
}
V020;
-#if FFESTR_VXT
- struct
- {
- mallocPool pool;
- ffestpDeleteStmt *params;
- }
- V021;
- struct
- {
- mallocPool pool;
- ffestpBeruStmt *params;
- }
- V022;
- struct
- {
- mallocPool pool;
- ffestpVxtcodeStmt *params;
- ffestdExprItem_ list;
- }
- V023;
- struct
- {
- mallocPool pool;
- ffestpVxtcodeStmt *params;
- ffestdExprItem_ list;
- }
- V024;
- struct
- {
- ffebld u;
- ffebld m;
- ffebld n;
- ffebld asv;
- }
- V025item;
- struct
- {
- mallocPool pool;
- } V025finish;
- struct
- {
- mallocPool pool;
- ffestpFindStmt *params;
- }
- V026;
-#endif
}
u;
};
@@ -513,9 +435,6 @@ static void ffestd_stmt_pass_ (void);
static ffestpInquireStmt *ffestd_subr_copy_easy_ (ffestpInquireIx max);
#endif
static void ffestd_subr_vxt_ (void);
-#if FFESTR_F90
-static void ffestd_subr_f90_ (void);
-#endif
static void ffestd_subr_labels_ (bool unexpected);
static void ffestd_R1001dump_ (ffests s, ffesttFormatList list);
static void ffestd_R1001dump_1005_1_ (ffests s, ffesttFormatList f,
@@ -532,8 +451,6 @@ static void ffestd_R1001dump_1010_1_ (ffests s, ffesttFormatList f,
const char *string);
static void ffestd_R1001dump_1010_2_ (ffests s, ffesttFormatList f,
const char *string);
-static void ffestd_R1001dump_1010_3_ (ffests s, ffesttFormatList f,
- const char *string);
static void ffestd_R1001dump_1010_4_ (ffests s, ffesttFormatList f,
const char *string);
static void ffestd_R1001dump_1010_5_ (ffests s, ffesttFormatList f,
@@ -638,7 +555,7 @@ ffestd_stmt_new_ (ffestdStmtId_ id)
ffestd_stmt_pass_(); */
static void
-ffestd_stmt_pass_ ()
+ffestd_stmt_pass_ (void)
{
ffestdStmt_ stmt;
ffestdExprItem_ expr; /* For traversing lists. */
@@ -1028,36 +945,6 @@ ffestd_stmt_pass_ ()
malloc_pool_kill (stmt->u.R1227.pool);
break;
-#if FFESTR_VXT
- case FFESTD_stmtidV018_:
- ffestd_subr_line_restore_ (stmt);
- if (okay)
- ffeste_V018_start (stmt->u.V018.params, stmt->u.V018.format);
- for (expr = stmt->u.V018.list; expr != NULL; expr = expr->next)
- {
- if (okay)
- ffeste_V018_item (expr->expr);
- }
- if (okay)
- ffeste_V018_finish ();
- malloc_pool_kill (stmt->u.V018.pool);
- break;
-
- case FFESTD_stmtidV019_:
- ffestd_subr_line_restore_ (stmt);
- if (okay)
- ffeste_V019_start (stmt->u.V019.params, stmt->u.V019.format);
- for (expr = stmt->u.V019.list; expr != NULL; expr = expr->next)
- {
- if (okay)
- ffeste_V019_item (expr->expr);
- }
- if (okay)
- ffeste_V019_finish ();
- malloc_pool_kill (stmt->u.V019.pool);
- break;
-#endif
-
case FFESTD_stmtidV020_:
ffestd_subr_line_restore_ (stmt);
if (okay)
@@ -1072,68 +959,6 @@ ffestd_stmt_pass_ ()
malloc_pool_kill (stmt->u.V020.pool);
break;
-#if FFESTR_VXT
- case FFESTD_stmtidV021_:
- ffestd_subr_line_restore_ (stmt);
- if (okay)
- ffeste_V021 (stmt->u.V021.params);
- malloc_pool_kill (stmt->u.V021.pool);
- break;
-
- case FFESTD_stmtidV023_:
- ffestd_subr_line_restore_ (stmt);
- if (okay)
- ffeste_V023_start (stmt->u.V023.params);
- for (expr = stmt->u.V023.list; expr != NULL; expr = expr->next)
- {
- if (okay)
- ffeste_V023_item (expr->expr);
- }
- if (okay)
- ffeste_V023_finish ();
- malloc_pool_kill (stmt->u.V023.pool);
- break;
-
- case FFESTD_stmtidV024_:
- ffestd_subr_line_restore_ (stmt);
- if (okay)
- ffeste_V024_start (stmt->u.V024.params);
- for (expr = stmt->u.V024.list; expr != NULL; expr = expr->next)
- {
- if (okay)
- ffeste_V024_item (expr->expr);
- }
- if (okay)
- ffeste_V024_finish ();
- malloc_pool_kill (stmt->u.V024.pool);
- break;
-
- case FFESTD_stmtidV025start_:
- ffestd_subr_line_restore_ (stmt);
- if (okay)
- ffeste_V025_start ();
- break;
-
- case FFESTD_stmtidV025item_:
- if (okay)
- ffeste_V025_item (stmt->u.V025item.u, stmt->u.V025item.m,
- stmt->u.V025item.n, stmt->u.V025item.asv);
- break;
-
- case FFESTD_stmtidV025finish_:
- if (okay)
- ffeste_V025_finish ();
- malloc_pool_kill (stmt->u.V025finish.pool);
- break;
-
- case FFESTD_stmtidV026_:
- ffestd_subr_line_restore_ (stmt);
- if (okay)
- ffeste_V026 (stmt->u.V026.params);
- malloc_pool_kill (stmt->u.V026.pool);
- break;
-#endif
-
default:
assert ("bad stmt->id" == NULL);
break;
@@ -1159,8 +984,8 @@ ffestd_subr_copy_easy_ (ffestpInquireIx max)
ffestpInquireStmt *stmt;
ffestpInquireIx ix;
- stmt = (ffestpInquireStmt *) malloc_new_kp (ffesta_output_pool,
- "FFESTD easy", sizeof (ffestpFile) * max);
+ stmt = malloc_new_kp (ffesta_output_pool, "FFESTD easy",
+ sizeof (ffestpFile) * max);
for (ix = 0; ix < max; ++ix)
{
@@ -1272,27 +1097,12 @@ ffestd_subr_labels_ (bool unexpected)
assert (undef == 0);
}
-/* ffestd_subr_f90_ -- Report error about lack of full F90 support
-
- ffestd_subr_f90_(); */
-
-#if FFESTR_F90
-static void
-ffestd_subr_f90_ ()
-{
- ffebad_start (FFEBAD_F90);
- ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
- ffelex_token_where_column (ffesta_tokens[0]));
- ffebad_finish ();
-}
-
-#endif
/* ffestd_subr_vxt_ -- Report error about lack of full VXT support
ffestd_subr_vxt_(); */
static void
-ffestd_subr_vxt_ ()
+ffestd_subr_vxt_ (void)
{
ffebad_start (FFEBAD_VXT_UNSUPPORTED);
ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]),
@@ -1311,7 +1121,7 @@ ffestd_subr_vxt_ ()
handling them as a single block rather than one statement at a time). */
void
-ffestd_begin_uses ()
+ffestd_begin_uses (void)
{
}
@@ -1339,30 +1149,6 @@ ffestd_do (bool ok UNUSED)
assert (ffestd_block_level_ >= 0);
}
-/* ffestd_end_uses -- End a bunch of USE statements
-
- ffestd_end_uses(TRUE);
-
- ok==TRUE means simply not popping due to ffestd_eof_()
- being called, because there is no formal END USES statement in Fortran. */
-
-#if FFESTR_F90
-void
-ffestd_end_uses (bool ok)
-{
-}
-
-/* ffestd_end_R740 -- End a WHERE(-THEN)
-
- ffestd_end_R740(TRUE); */
-
-void
-ffestd_end_R740 (bool ok)
-{
- return; /* F90. */
-}
-
-#endif
/* ffestd_end_R807 -- End of statement following logical IF
ffestd_end_R807(TRUE);
@@ -1391,7 +1177,7 @@ ffestd_end_R807 (bool ok UNUSED)
ffestd_exec_begin(); */
void
-ffestd_exec_begin ()
+ffestd_exec_begin (void)
{
ffecom_exec_transition ();
@@ -1423,10 +1209,9 @@ ffestd_exec_begin ()
ffestd_exec_end(); */
void
-ffestd_exec_end ()
+ffestd_exec_end (void)
{
- int old_lineno = lineno;
- const char *old_input_filename = input_filename;
+ location_t old_loc = input_location;
ffecom_end_transition ();
@@ -1458,8 +1243,7 @@ ffestd_exec_end ()
ffestd_stmt_list_.last = NULL;
ffestd_2pass_entrypoints_ = 0;
- lineno = old_lineno;
- input_filename = old_input_filename;
+ input_location = old_loc;
}
/* ffestd_init_3 -- Initialize for any program unit
@@ -1467,7 +1251,7 @@ ffestd_exec_end ()
ffestd_init_3(); */
void
-ffestd_init_3 ()
+ffestd_init_3 (void)
{
ffestd_stmt_list_.first = (ffestdStmt_) &ffestd_stmt_list_.first;
ffestd_stmt_list_.last = (ffestdStmt_) &ffestd_stmt_list_.first;
@@ -1521,353 +1305,6 @@ ffestd_labeldef_useless (ffelab label UNUSED)
{
}
-/* ffestd_R423A -- PRIVATE statement (in R422 derived-type statement)
-
- ffestd_R423A(); */
-
-#if FFESTR_F90
-void
-ffestd_R423A ()
-{
- ffestd_check_simple_ ();
-}
-
-/* ffestd_R423B -- SEQUENCE statement (in R422 derived-type-stmt)
-
- ffestd_R423B(); */
-
-void
-ffestd_R423B ()
-{
- ffestd_check_simple_ ();
-}
-
-/* ffestd_R424 -- derived-TYPE-def statement
-
- ffestd_R424(access_token,access_kw,name_token);
-
- Handle a derived-type definition. */
-
-void
-ffestd_R424 (ffelexToken access, ffestrOther access_kw, ffelexToken name)
-{
- ffestd_check_simple_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- char *a;
-
- if (access == NULL)
- fprintf (dmpout, "* TYPE %s\n", ffelex_token_text (name));
- else
- {
- switch (access_kw)
- {
- case FFESTR_otherPUBLIC:
- a = "PUBLIC";
- break;
-
- case FFESTR_otherPRIVATE:
- a = "PRIVATE";
- break;
-
- default:
- assert (FALSE);
- }
- fprintf (dmpout, "* TYPE,%s: %s\n", a, ffelex_token_text (name));
- }
-#endif
-}
-
-/* ffestd_R425 -- End a TYPE
-
- ffestd_R425(TRUE); */
-
-void
-ffestd_R425 (bool ok)
-{
-}
-
-/* ffestd_R519_start -- INTENT statement list begin
-
- ffestd_R519_start();
-
- Verify that INTENT is valid here, and begin accepting items in the list. */
-
-void
-ffestd_R519_start (ffestrOther intent_kw)
-{
- ffestd_check_start_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- char *a;
-
- switch (intent_kw)
- {
- case FFESTR_otherIN:
- a = "IN";
- break;
-
- case FFESTR_otherOUT:
- a = "OUT";
- break;
-
- case FFESTR_otherINOUT:
- a = "INOUT";
- break;
-
- default:
- assert (FALSE);
- }
- fprintf (dmpout, "* INTENT (%s) ", a);
-#endif
-}
-
-/* ffestd_R519_item -- INTENT statement for name
-
- ffestd_R519_item(name_token);
-
- Make sure name_token identifies a valid object to be INTENTed. */
-
-void
-ffestd_R519_item (ffelexToken name)
-{
- ffestd_check_item_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fprintf (dmpout, "%s,", ffelex_token_text (name));
-#endif
-}
-
-/* ffestd_R519_finish -- INTENT statement list complete
-
- ffestd_R519_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_R519_finish ()
-{
- ffestd_check_finish_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputc ('\n', dmpout);
-#endif
-}
-
-/* ffestd_R520_start -- OPTIONAL statement list begin
-
- ffestd_R520_start();
-
- Verify that OPTIONAL is valid here, and begin accepting items in the list. */
-
-void
-ffestd_R520_start ()
-{
- ffestd_check_start_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- fputs ("* OPTIONAL ", dmpout);
-#endif
-}
-
-/* ffestd_R520_item -- OPTIONAL statement for name
-
- ffestd_R520_item(name_token);
-
- Make sure name_token identifies a valid object to be OPTIONALed. */
-
-void
-ffestd_R520_item (ffelexToken name)
-{
- ffestd_check_item_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fprintf (dmpout, "%s,", ffelex_token_text (name));
-#endif
-}
-
-/* ffestd_R520_finish -- OPTIONAL statement list complete
-
- ffestd_R520_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_R520_finish ()
-{
- ffestd_check_finish_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputc ('\n', dmpout);
-#endif
-}
-
-/* ffestd_R521A -- PUBLIC statement
-
- ffestd_R521A();
-
- Verify that PUBLIC is valid here. */
-
-void
-ffestd_R521A ()
-{
- ffestd_check_simple_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- fputs ("* PUBLIC\n", dmpout);
-#endif
-}
-
-/* ffestd_R521Astart -- PUBLIC statement list begin
-
- ffestd_R521Astart();
-
- Verify that PUBLIC is valid here, and begin accepting items in the list. */
-
-void
-ffestd_R521Astart ()
-{
- ffestd_check_start_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- fputs ("* PUBLIC ", dmpout);
-#endif
-}
-
-/* ffestd_R521Aitem -- PUBLIC statement for name
-
- ffestd_R521Aitem(name_token);
-
- Make sure name_token identifies a valid object to be PUBLICed. */
-
-void
-ffestd_R521Aitem (ffelexToken name)
-{
- ffestd_check_item_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fprintf (dmpout, "%s,", ffelex_token_text (name));
-#endif
-}
-
-/* ffestd_R521Afinish -- PUBLIC statement list complete
-
- ffestd_R521Afinish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_R521Afinish ()
-{
- ffestd_check_finish_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputc ('\n', dmpout);
-#endif
-}
-
-/* ffestd_R521B -- PRIVATE statement
-
- ffestd_R521B();
-
- Verify that PRIVATE is valid here (outside a derived-type statement). */
-
-void
-ffestd_R521B ()
-{
- ffestd_check_simple_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- fputs ("* PRIVATE_outside_of_R422_derived_type_def\n", dmpout);
-#endif
-}
-
-/* ffestd_R521Bstart -- PRIVATE statement list begin
-
- ffestd_R521Bstart();
-
- Verify that PRIVATE is valid here, and begin accepting items in the list. */
-
-void
-ffestd_R521Bstart ()
-{
- ffestd_check_start_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- fputs ("* PRIVATE ", dmpout);
-#endif
-}
-
-/* ffestd_R521Bitem -- PRIVATE statement for name
-
- ffestd_R521Bitem(name_token);
-
- Make sure name_token identifies a valid object to be PRIVATEed. */
-
-void
-ffestd_R521Bitem (ffelexToken name)
-{
- ffestd_check_item_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fprintf (dmpout, "%s,", ffelex_token_text (name));
-#endif
-}
-
-/* ffestd_R521Bfinish -- PRIVATE statement list complete
-
- ffestd_R521Bfinish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_R521Bfinish ()
-{
- ffestd_check_finish_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputc ('\n', dmpout);
-#endif
-}
-
-#endif
/* ffestd_R522 -- SAVE statement with no list
ffestd_R522();
@@ -1875,7 +1312,7 @@ ffestd_R521Bfinish ()
Verify that SAVE is valid here, and flag everything as SAVEd. */
void
-ffestd_R522 ()
+ffestd_R522 (void)
{
ffestd_check_simple_ ();
}
@@ -1887,7 +1324,7 @@ ffestd_R522 ()
Verify that SAVE is valid here, and begin accepting items in the list. */
void
-ffestd_R522start ()
+ffestd_R522start (void)
{
ffestd_check_start_ ();
}
@@ -1923,7 +1360,7 @@ ffestd_R522item_cblock (ffelexToken name UNUSED)
Just wrap up any local activities. */
void
-ffestd_R522finish ()
+ffestd_R522finish (void)
{
ffestd_check_finish_ ();
}
@@ -1959,202 +1396,11 @@ ffestd_R524_item (ffelexToken name UNUSED, ffesttDimList dims UNUSED)
Just wrap up any local activities. */
void
-ffestd_R524_finish ()
-{
- ffestd_check_finish_ ();
-}
-
-/* ffestd_R525_start -- ALLOCATABLE statement list begin
-
- ffestd_R525_start();
-
- Verify that ALLOCATABLE is valid here, and begin accepting items in the
- list. */
-
-#if FFESTR_F90
-void
-ffestd_R525_start ()
-{
- ffestd_check_start_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- fputs ("* ALLOCATABLE ", dmpout);
-#endif
-}
-
-/* ffestd_R525_item -- ALLOCATABLE statement for object-name
-
- ffestd_R525_item(name_token,dim_list);
-
- Make sure name_token identifies a valid object to be ALLOCATABLEd. */
-
-void
-ffestd_R525_item (ffelexToken name, ffesttDimList dims)
-{
- ffestd_check_item_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputs (ffelex_token_text (name), dmpout);
- if (dims != NULL)
- {
- fputc ('(', dmpout);
- ffestt_dimlist_dump (dims);
- fputc (')', dmpout);
- }
- fputc (',', dmpout);
-#endif
-}
-
-/* ffestd_R525_finish -- ALLOCATABLE statement list complete
-
- ffestd_R525_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_R525_finish ()
-{
- ffestd_check_finish_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputc ('\n', dmpout);
-#endif
-}
-
-/* ffestd_R526_start -- POINTER statement list begin
-
- ffestd_R526_start();
-
- Verify that POINTER is valid here, and begin accepting items in the
- list. */
-
-void
-ffestd_R526_start ()
-{
- ffestd_check_start_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- fputs ("* POINTER ", dmpout);
-#endif
-}
-
-/* ffestd_R526_item -- POINTER statement for object-name
-
- ffestd_R526_item(name_token,dim_list);
-
- Make sure name_token identifies a valid object to be POINTERd. */
-
-void
-ffestd_R526_item (ffelexToken name, ffesttDimList dims)
-{
- ffestd_check_item_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputs (ffelex_token_text (name), dmpout);
- if (dims != NULL)
- {
- fputc ('(', dmpout);
- ffestt_dimlist_dump (dims);
- fputc (')', dmpout);
- }
- fputc (',', dmpout);
-#endif
-}
-
-/* ffestd_R526_finish -- POINTER statement list complete
-
- ffestd_R526_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_R526_finish ()
+ffestd_R524_finish (void)
{
ffestd_check_finish_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputc ('\n', dmpout);
-#endif
}
-/* ffestd_R527_start -- TARGET statement list begin
-
- ffestd_R527_start();
-
- Verify that TARGET is valid here, and begin accepting items in the
- list. */
-
-void
-ffestd_R527_start ()
-{
- ffestd_check_start_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- fputs ("* TARGET ", dmpout);
-#endif
-}
-
-/* ffestd_R527_item -- TARGET statement for object-name
-
- ffestd_R527_item(name_token,dim_list);
-
- Make sure name_token identifies a valid object to be TARGETd. */
-
-void
-ffestd_R527_item (ffelexToken name, ffesttDimList dims)
-{
- ffestd_check_item_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputs (ffelex_token_text (name), dmpout);
- if (dims != NULL)
- {
- fputc ('(', dmpout);
- ffestt_dimlist_dump (dims);
- fputc (')', dmpout);
- }
- fputc (',', dmpout);
-#endif
-}
-
-/* ffestd_R527_finish -- TARGET statement list complete
-
- ffestd_R527_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_R527_finish ()
-{
- ffestd_check_finish_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputc ('\n', dmpout);
-#endif
-}
-
-#endif
/* ffestd_R537_start -- PARAMETER statement list begin
ffestd_R537_start();
@@ -2162,7 +1408,7 @@ ffestd_R527_finish ()
Verify that PARAMETER is valid here, and begin accepting items in the list. */
void
-ffestd_R537_start ()
+ffestd_R537_start (void)
{
ffestd_check_start_ ();
}
@@ -2187,7 +1433,7 @@ ffestd_R537_item (ffebld dest UNUSED, ffebld source UNUSED)
Just wrap up any local activities. */
void
-ffestd_R537_finish ()
+ffestd_R537_finish (void)
{
ffestd_check_finish_ ();
}
@@ -2199,7 +1445,7 @@ ffestd_R537_finish ()
Verify that the IMPLICIT NONE statement is ok here and implement. */
void
-ffestd_R539 ()
+ffestd_R539 (void)
{
ffestd_check_simple_ ();
}
@@ -2211,7 +1457,7 @@ ffestd_R539 ()
Verify that the IMPLICIT statement is ok here and implement. */
void
-ffestd_R539start ()
+ffestd_R539start (void)
{
ffestd_check_start_ ();
}
@@ -2237,7 +1483,7 @@ ffestd_R539item (ffestpType type UNUSED, ffebld kind UNUSED,
Finish up any local activities. */
void
-ffestd_R539finish ()
+ffestd_R539finish (void)
{
ffestd_check_finish_ ();
}
@@ -2249,7 +1495,7 @@ ffestd_R539finish ()
Verify that NAMELIST is valid here, and begin accepting items in the list. */
void
-ffestd_R542_start ()
+ffestd_R542_start (void)
{
ffestd_check_start_ ();
}
@@ -2285,54 +1531,11 @@ ffestd_R542_item_nitem (ffelexToken name UNUSED)
Just wrap up any local activities. */
void
-ffestd_R542_finish ()
-{
- ffestd_check_finish_ ();
-}
-
-/* ffestd_R544_start -- EQUIVALENCE statement list begin
-
- ffestd_R544_start();
-
- Verify that EQUIVALENCE is valid here, and begin accepting items in the
- list. */
-
-#if 0
-void
-ffestd_R544_start ()
-{
- ffestd_check_start_ ();
-}
-
-#endif
-/* ffestd_R544_item -- EQUIVALENCE statement assignment
-
- ffestd_R544_item(exprlist);
-
- Make sure the equivalence is valid, then implement it. */
-
-#if 0
-void
-ffestd_R544_item (ffesttExprList exprlist)
-{
- ffestd_check_item_ ();
-}
-
-#endif
-/* ffestd_R544_finish -- EQUIVALENCE statement list complete
-
- ffestd_R544_finish();
-
- Just wrap up any local activities. */
-
-#if 0
-void
-ffestd_R544_finish ()
+ffestd_R542_finish (void)
{
ffestd_check_finish_ ();
}
-#endif
/* ffestd_R547_start -- COMMON statement list begin
ffestd_R547_start();
@@ -2340,7 +1543,7 @@ ffestd_R544_finish ()
Verify that COMMON is valid here, and begin accepting items in the list. */
void
-ffestd_R547_start ()
+ffestd_R547_start (void)
{
ffestd_check_start_ ();
}
@@ -2377,63 +1580,11 @@ ffestd_R547_item_cblock (ffelexToken name UNUSED)
Just wrap up any local activities. */
void
-ffestd_R547_finish ()
+ffestd_R547_finish (void)
{
ffestd_check_finish_ ();
}
-/* ffestd_R620 -- ALLOCATE statement
-
- ffestd_R620(exprlist,stat,stat_token);
-
- Make sure the expression list is valid, then implement it. */
-
-#if FFESTR_F90
-void
-ffestd_R620 (ffesttExprList exprlist, ffebld stat)
-{
- ffestd_check_simple_ ();
-
- ffestd_subr_f90_ ();
-}
-
-/* ffestd_R624 -- NULLIFY statement
-
- ffestd_R624(pointer_name_list);
-
- Make sure pointer_name_list identifies valid pointers for a NULLIFY. */
-
-void
-ffestd_R624 (ffesttExprList pointers)
-{
- ffestd_check_simple_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- fputs ("+ NULLIFY (", dmpout);
- assert (pointers != NULL);
- ffestt_exprlist_dump (pointers);
- fputs (")\n", dmpout);
-#endif
-}
-
-/* ffestd_R625 -- DEALLOCATE statement
-
- ffestd_R625(exprlist,stat,stat_token);
-
- Make sure the equivalence is valid, then implement it. */
-
-void
-ffestd_R625 (ffesttExprList exprlist, ffebld stat)
-{
- ffestd_check_simple_ ();
-
- ffestd_subr_f90_ ();
-}
-
-#endif
/* ffestd_R737A -- Assignment statement outside of WHERE
ffestd_R737A(dest_expr,source_expr); */
@@ -2454,94 +1605,6 @@ ffestd_R737A (ffebld dest, ffebld source)
ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE);
}
-/* ffestd_R737B -- Assignment statement inside of WHERE
-
- ffestd_R737B(dest_expr,source_expr); */
-
-#if FFESTR_F90
-void
-ffestd_R737B (ffebld dest, ffebld source)
-{
- ffestd_check_simple_ ();
-}
-
-/* ffestd_R738 -- Pointer assignment statement
-
- ffestd_R738(dest_expr,source_expr,source_token);
-
- Make sure the assignment is valid. */
-
-void
-ffestd_R738 (ffebld dest, ffebld source)
-{
- ffestd_check_simple_ ();
-
- ffestd_subr_f90_ ();
-}
-
-/* ffestd_R740 -- WHERE statement
-
- ffestd_R740(expr,expr_token);
-
- Make sure statement is valid here; implement. */
-
-void
-ffestd_R740 (ffebld expr)
-{
- ffestd_check_simple_ ();
-
- ffestd_subr_f90_ ();
-}
-
-/* ffestd_R742 -- WHERE-construct statement
-
- ffestd_R742(expr,expr_token);
-
- Make sure statement is valid here; implement. */
-
-void
-ffestd_R742 (ffebld expr)
-{
- ffestd_check_simple_ ();
-
- ffestd_subr_f90_ ();
-}
-
-/* ffestd_R744 -- ELSE WHERE statement
-
- ffestd_R744();
-
- Make sure ffestd_kind_ identifies a WHERE block.
- Implement the ELSE of the current WHERE block. */
-
-void
-ffestd_R744 ()
-{
- ffestd_check_simple_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputs ("+ ELSE_WHERE\n", dmpout);
-#endif
-}
-
-/* ffestd_R745 -- Implicit END WHERE statement. */
-
-void
-ffestd_R745 (bool ok)
-{
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputs ("+ END_WHERE\n", dmpout); /* Also see ffestd_R745. */
-
- --ffestd_block_level_;
- assert (ffestd_block_level_ >= 0);
-#endif
-}
-
-#endif
/* Block IF (IF-THEN) statement. */
@@ -3033,7 +2096,7 @@ ffestd_R843 (ffebld expr)
Make sure an OPEN is valid in the current context, and implement it. */
void
-ffestd_R904 ()
+ffestd_R904 (void)
{
ffestdStmt_ stmt;
@@ -3088,7 +2151,7 @@ ffestd_R904 ()
Make sure a CLOSE is valid in the current context, and implement it. */
void
-ffestd_R907 ()
+ffestd_R907 (void)
{
ffestdStmt_ stmt;
@@ -3166,8 +2229,7 @@ ffestd_R909_item (ffebld expr, ffelexToken expr_token)
ffestd_check_item_ ();
- item = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool,
- "ffestdExprItem_", sizeof (*item));
+ item = malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", sizeof (*item));
item->next = NULL;
item->expr = expr;
@@ -3183,7 +2245,7 @@ ffestd_R909_item (ffebld expr, ffelexToken expr_token)
Just wrap up any local activities. */
void
-ffestd_R909_finish ()
+ffestd_R909_finish (void)
{
ffestd_check_finish_ ();
}
@@ -3243,8 +2305,7 @@ ffestd_R910_item (ffebld expr, ffelexToken expr_token)
ffestd_check_item_ ();
- item = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool,
- "ffestdExprItem_", sizeof (*item));
+ item = malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", sizeof (*item));
item->next = NULL;
item->expr = expr;
@@ -3260,7 +2321,7 @@ ffestd_R910_item (ffebld expr, ffelexToken expr_token)
Just wrap up any local activities. */
void
-ffestd_R910_finish ()
+ffestd_R910_finish (void)
{
ffestd_check_finish_ ();
}
@@ -3303,8 +2364,7 @@ ffestd_R911_item (ffebld expr, ffelexToken expr_token)
ffestd_check_item_ ();
- item = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool,
- "ffestdExprItem_", sizeof (*item));
+ item = malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", sizeof (*item));
item->next = NULL;
item->expr = expr;
@@ -3320,7 +2380,7 @@ ffestd_R911_item (ffebld expr, ffelexToken expr_token)
Just wrap up any local activities. */
void
-ffestd_R911_finish ()
+ffestd_R911_finish (void)
{
ffestd_check_finish_ ();
}
@@ -3332,7 +2392,7 @@ ffestd_R911_finish ()
Make sure a BACKSPACE is valid in the current context, and implement it. */
void
-ffestd_R919 ()
+ffestd_R919 (void)
{
ffestdStmt_ stmt;
@@ -3353,7 +2413,7 @@ ffestd_R919 ()
Make sure a ENDFILE is valid in the current context, and implement it. */
void
-ffestd_R920 ()
+ffestd_R920 (void)
{
ffestdStmt_ stmt;
@@ -3374,7 +2434,7 @@ ffestd_R920 ()
Make sure a REWIND is valid in the current context, and implement it. */
void
-ffestd_R921 ()
+ffestd_R921 (void)
{
ffestdStmt_ stmt;
@@ -3443,7 +2503,7 @@ ffestd_R923A (bool by_file)
list. */
void
-ffestd_R923B_start ()
+ffestd_R923B_start (void)
{
ffestdStmt_ stmt;
@@ -3472,8 +2532,7 @@ ffestd_R923B_item (ffebld expr)
ffestd_check_item_ ();
- item = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool,
- "ffestdExprItem_", sizeof (*item));
+ item = malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", sizeof (*item));
item->next = NULL;
item->expr = expr;
@@ -3488,7 +2547,7 @@ ffestd_R923B_item (ffebld expr)
Just wrap up any local activities. */
void
-ffestd_R923B_finish ()
+ffestd_R923B_finish (void)
{
ffestd_check_finish_ ();
}
@@ -3608,7 +2667,7 @@ ffestd_R1001dump_ (ffests s, ffesttFormatList list)
break;
case FFESTP_formattypeX:
- ffestd_R1001dump_1010_3_ (s, next, "X");
+ ffestd_R1001dump_1010_2_ (s, next, "X");
break;
case FFESTP_formattypeS:
@@ -3914,26 +2973,6 @@ ffestd_R1001dump_1010_2_ (ffests s, ffesttFormatList f, const char *string)
ffests_puts (s, string);
}
-/* ffestd_R1001dump_1010_3_ -- Dump a particular format
-
- ffesttFormatList f;
- ffestd_R1001dump_1010_3_(f,"I");
-
- The format is dumped with form nX. */
-
-static void
-ffestd_R1001dump_1010_3_ (ffests s, ffesttFormatList f, const char *string)
-{
- assert (f->u.R1010.val.present);
-
- if (f->u.R1010.val.rtexpr)
- ffestd_R1001rtexpr_ (s, f, f->u.R1010.val.u.expr);
- else
- ffests_printf (s, "%lu", f->u.R1010.val.u.unsigned_val);
-
- ffests_puts (s, string);
-}
-
/* ffestd_R1001dump_1010_4_ -- Dump a particular format
ffesttFormatList f;
@@ -4078,114 +3117,6 @@ ffestd_R1103 (bool ok UNUSED)
ffestd_stmt_append_ (stmt);
}
-/* ffestd_R1105 -- MODULE statement
-
- ffestd_R1105(name_token);
-
- Make sure ffestd_kind_ identifies an empty block. Make sure name_token
- gives a valid name. Implement the beginning of a module. */
-
-#if FFESTR_F90
-void
-ffestd_R1105 (ffelexToken name)
-{
- assert (ffestd_block_level_ == 0);
-
- ffestd_check_simple_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- fprintf (dmpout, "* MODULE %s\n", ffelex_token_text (name));
-#endif
-}
-
-/* ffestd_R1106 -- End a MODULE
-
- ffestd_R1106(TRUE); */
-
-void
-ffestd_R1106 (bool ok)
-{
- assert (ffestd_block_level_ == 0);
-
- /* Generate any wrap-up code here (unlikely in MODULE!). */
-
- if (ffestw_state (ffestw_stack_top ()) != FFESTV_stateMODULE5)
- ffestd_subr_labels_ (TRUE); /* Handle any undefined labels (unlikely). */
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fprintf (dmpout, "< END_MODULE %s\n",
- ffelex_token_text (ffestw_name (ffestw_stack_top ())));
-#endif
-}
-
-/* ffestd_R1107_start -- USE statement list begin
-
- ffestd_R1107_start();
-
- Verify that USE is valid here, and begin accepting items in the list. */
-
-void
-ffestd_R1107_start (ffelexToken name, bool only)
-{
- ffestd_check_start_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- fprintf (dmpout, "* USE %s,", ffelex_token_text (name)); /* NB
- _shriek_begin_uses_. */
- if (only)
- fputs ("only: ", dmpout);
-#endif
-}
-
-/* ffestd_R1107_item -- USE statement for name
-
- ffestd_R1107_item(local_token,use_token);
-
- Make sure name_token identifies a valid object to be USEed. local_token
- may be NULL if _start_ was called with only==TRUE. */
-
-void
-ffestd_R1107_item (ffelexToken local, ffelexToken use)
-{
- ffestd_check_item_ ();
- assert (use != NULL);
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- if (local != NULL)
- fprintf (dmpout, "%s=>", ffelex_token_text (local));
- fprintf (dmpout, "%s,", ffelex_token_text (use));
-#endif
-}
-
-/* ffestd_R1107_finish -- USE statement list complete
-
- ffestd_R1107_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_R1107_finish ()
-{
- ffestd_check_finish_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputc ('\n', dmpout);
-#endif
-}
-
-#endif
/* ffestd_R1111 -- BLOCK DATA statement
ffestd_R1111(name_token);
@@ -4226,190 +3157,6 @@ ffestd_R1112 (bool ok UNUSED)
ffestd_stmt_append_ (stmt);
}
-/* ffestd_R1202 -- INTERFACE statement
-
- ffestd_R1202(operator,defined_name);
-
- Make sure ffestd_kind_ identifies an INTERFACE block.
- Implement the end of the current interface.
-
- 06-Jun-90 JCB 1.1
- Allow no operator or name to mean INTERFACE by itself; missed this
- valid form when originally doing syntactic analysis code. */
-
-#if FFESTR_F90
-void
-ffestd_R1202 (ffestpDefinedOperator operator, ffelexToken name)
-{
- ffestd_check_simple_ ();
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- switch (operator)
- {
- case FFESTP_definedoperatorNone:
- if (name == NULL)
- fputs ("* INTERFACE_unnamed\n", dmpout);
- else
- fprintf (dmpout, "* INTERFACE %s\n", ffelex_token_text (name));
- break;
-
- case FFESTP_definedoperatorOPERATOR:
- fprintf (dmpout, "* INTERFACE_OPERATOR (.%s.)\n", ffelex_token_text (name));
- break;
-
- case FFESTP_definedoperatorASSIGNMENT:
- fputs ("* INTERFACE_ASSIGNMENT (=)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorPOWER:
- fputs ("* INTERFACE_OPERATOR (**)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorMULT:
- fputs ("* INTERFACE_OPERATOR (*)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorADD:
- fputs ("* INTERFACE_OPERATOR (+)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorCONCAT:
- fputs ("* INTERFACE_OPERATOR (//)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorDIVIDE:
- fputs ("* INTERFACE_OPERATOR (/)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorSUBTRACT:
- fputs ("* INTERFACE_OPERATOR (-)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorNOT:
- fputs ("* INTERFACE_OPERATOR (.not.)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorAND:
- fputs ("* INTERFACE_OPERATOR (.and.)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorOR:
- fputs ("* INTERFACE_OPERATOR (.or.)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorEQV:
- fputs ("* INTERFACE_OPERATOR (.eqv.)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorNEQV:
- fputs ("* INTERFACE_OPERATOR (.neqv.)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorEQ:
- fputs ("* INTERFACE_OPERATOR (==)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorNE:
- fputs ("* INTERFACE_OPERATOR (/=)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorLT:
- fputs ("* INTERFACE_OPERATOR (<)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorLE:
- fputs ("* INTERFACE_OPERATOR (<=)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorGT:
- fputs ("* INTERFACE_OPERATOR (>)\n", dmpout);
- break;
-
- case FFESTP_definedoperatorGE:
- fputs ("* INTERFACE_OPERATOR (>=)\n", dmpout);
- break;
-
- default:
- assert (FALSE);
- break;
- }
-#endif
-}
-
-/* ffestd_R1203 -- End an INTERFACE
-
- ffestd_R1203(TRUE); */
-
-void
-ffestd_R1203 (bool ok)
-{
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputs ("* END_INTERFACE\n", dmpout);
-#endif
-}
-
-/* ffestd_R1205_start -- MODULE PROCEDURE statement list begin
-
- ffestd_R1205_start();
-
- Verify that MODULE PROCEDURE is valid here, and begin accepting items in
- the list. */
-
-void
-ffestd_R1205_start ()
-{
- ffestd_check_start_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputs ("* MODULE_PROCEDURE ", dmpout);
-#endif
-}
-
-/* ffestd_R1205_item -- MODULE PROCEDURE statement for name
-
- ffestd_R1205_item(name_token);
-
- Make sure name_token identifies a valid object to be MODULE PROCEDUREed. */
-
-void
-ffestd_R1205_item (ffelexToken name)
-{
- ffestd_check_item_ ();
- assert (name != NULL);
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fprintf (dmpout, "%s,", ffelex_token_text (name));
-#endif
-}
-
-/* ffestd_R1205_finish -- MODULE PROCEDURE statement list complete
-
- ffestd_R1205_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_R1205_finish ()
-{
- ffestd_check_finish_ ();
-
- return; /* F90. */
-
-#ifdef FFESTD_F90
- fputc ('\n', dmpout);
-#endif
-}
-
-#endif
/* ffestd_R1207_start -- EXTERNAL statement list begin
ffestd_R1207_start();
@@ -4417,7 +3164,7 @@ ffestd_R1205_finish ()
Verify that EXTERNAL is valid here, and begin accepting items in the list. */
void
-ffestd_R1207_start ()
+ffestd_R1207_start (void)
{
ffestd_check_start_ ();
}
@@ -4442,7 +3189,7 @@ ffestd_R1207_item (ffelexToken name)
Just wrap up any local activities. */
void
-ffestd_R1207_finish ()
+ffestd_R1207_finish (void)
{
ffestd_check_finish_ ();
}
@@ -4454,7 +3201,7 @@ ffestd_R1207_finish ()
Verify that INTRINSIC is valid here, and begin accepting items in the list. */
void
-ffestd_R1208_start ()
+ffestd_R1208_start (void)
{
ffestd_check_start_ ();
}
@@ -4479,7 +3226,7 @@ ffestd_R1208_item (ffelexToken name)
Just wrap up any local activities. */
void
-ffestd_R1208_finish ()
+ffestd_R1208_finish (void)
{
ffestd_check_finish_ ();
}
@@ -4505,22 +3252,6 @@ ffestd_R1212 (ffebld expr)
ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE);
}
-/* ffestd_R1213 -- Defined assignment statement
-
- ffestd_R1213(dest_expr,source_expr,source_token);
-
- Make sure the assignment is valid. */
-
-#if FFESTR_F90
-void
-ffestd_R1213 (ffebld dest, ffebld source)
-{
- ffestd_check_simple_ ();
-
- ffestd_subr_f90_ ();
-}
-
-#endif
/* ffestd_R1219 -- FUNCTION statement
ffestd_R1219(funcname,arglist,ending_token,kind,kindt,len,lent,
@@ -4667,33 +3398,6 @@ ffestd_R1227 (ffebld expr)
ffestd_is_reachable_ = FALSE;
}
-/* ffestd_R1228 -- CONTAINS statement
-
- ffestd_R1228(); */
-
-#if FFESTR_F90
-void
-ffestd_R1228 ()
-{
- assert (ffestd_block_level_ == 0);
-
- ffestd_check_simple_ ();
-
- /* Generate RETURN/STOP code here */
-
- ffestd_subr_labels_ (ffestw_state (ffestw_stack_top ())
- == FFESTV_stateMODULE5); /* Handle any undefined
- labels. */
-
- ffestd_subr_f90_ ();
- return;
-
-#ifdef FFESTD_F90
- fputs ("- CONTAINS\n", dmpout);
-#endif
-}
-
-#endif
/* ffestd_R1229_start -- STMTFUNCTION statement begin
ffestd_R1229_start(func_name,func_arg_list,close_paren);
@@ -4780,92 +3484,6 @@ ffestd_S3P4 (ffebld filename)
}
}
-/* ffestd_V003_start -- STRUCTURE statement list begin
-
- ffestd_V003_start(structure_name);
-
- Verify that STRUCTURE is valid here, and begin accepting items in the list. */
-
-#if FFESTR_VXT
-void
-ffestd_V003_start (ffelexToken structure_name)
-{
- ffestd_check_start_ ();
- ffestd_subr_vxt_ ();
-}
-
-/* ffestd_V003_item -- STRUCTURE statement for object-name
-
- ffestd_V003_item(name_token,dim_list);
-
- Make sure name_token identifies a valid object to be STRUCTUREd. */
-
-void
-ffestd_V003_item (ffelexToken name, ffesttDimList dims)
-{
- ffestd_check_item_ ();
-}
-
-/* ffestd_V003_finish -- STRUCTURE statement list complete
-
- ffestd_V003_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_V003_finish ()
-{
- ffestd_check_finish_ ();
-}
-
-/* ffestd_V004 -- End a STRUCTURE
-
- ffestd_V004(TRUE); */
-
-void
-ffestd_V004 (bool ok)
-{
-}
-
-/* ffestd_V009 -- UNION statement
-
- ffestd_V009(); */
-
-void
-ffestd_V009 ()
-{
- ffestd_check_simple_ ();
-}
-
-/* ffestd_V010 -- End a UNION
-
- ffestd_V010(TRUE); */
-
-void
-ffestd_V010 (bool ok)
-{
-}
-
-/* ffestd_V012 -- MAP statement
-
- ffestd_V012(); */
-
-void
-ffestd_V012 ()
-{
- ffestd_check_simple_ ();
-}
-
-/* ffestd_V013 -- End a MAP
-
- ffestd_V013(TRUE); */
-
-void
-ffestd_V013 (bool ok)
-{
-}
-
-#endif
/* ffestd_V014_start -- VOLATILE statement list begin
ffestd_V014_start();
@@ -4873,7 +3491,7 @@ ffestd_V013 (bool ok)
Verify that VOLATILE is valid here, and begin accepting items in the list. */
void
-ffestd_V014_start ()
+ffestd_V014_start (void)
{
ffestd_check_start_ ();
}
@@ -4909,137 +3527,11 @@ ffestd_V014_item_cblock (ffelexToken name UNUSED)
Just wrap up any local activities. */
void
-ffestd_V014_finish ()
-{
- ffestd_check_finish_ ();
-}
-
-/* ffestd_V016_start -- RECORD statement list begin
-
- ffestd_V016_start();
-
- Verify that RECORD is valid here, and begin accepting items in the list. */
-
-#if FFESTR_VXT
-void
-ffestd_V016_start ()
-{
- ffestd_check_start_ ();
-}
-
-/* ffestd_V016_item_structure -- RECORD statement for common-block-name
-
- ffestd_V016_item_structure(name_token);
-
- Make sure name_token identifies a valid structure to be RECORDed. */
-
-void
-ffestd_V016_item_structure (ffelexToken name)
-{
- ffestd_check_item_ ();
-}
-
-/* ffestd_V016_item_object -- RECORD statement for object-name
-
- ffestd_V016_item_object(name_token,dim_list);
-
- Make sure name_token identifies a valid object to be RECORDd. */
-
-void
-ffestd_V016_item_object (ffelexToken name, ffesttDimList dims)
-{
- ffestd_check_item_ ();
-}
-
-/* ffestd_V016_finish -- RECORD statement list complete
-
- ffestd_V016_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_V016_finish ()
-{
- ffestd_check_finish_ ();
-}
-
-/* ffestd_V018_start -- REWRITE(...) statement list begin
-
- ffestd_V018_start();
-
- Verify that REWRITE is valid here, and begin accepting items in the
- list. */
-
-void
-ffestd_V018_start (ffestvFormat format)
-{
- ffestd_check_start_ ();
- ffestd_subr_vxt_ ();
-}
-
-/* ffestd_V018_item -- REWRITE statement i/o item
-
- ffestd_V018_item(expr,expr_token);
-
- Implement output-list expression. */
-
-void
-ffestd_V018_item (ffebld expr)
-{
- ffestd_check_item_ ();
-}
-
-/* ffestd_V018_finish -- REWRITE statement list complete
-
- ffestd_V018_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_V018_finish ()
-{
- ffestd_check_finish_ ();
-}
-
-/* ffestd_V019_start -- ACCEPT statement list begin
-
- ffestd_V019_start();
-
- Verify that ACCEPT is valid here, and begin accepting items in the
- list. */
-
-void
-ffestd_V019_start (ffestvFormat format)
-{
- ffestd_check_start_ ();
- ffestd_subr_vxt_ ();
-}
-
-/* ffestd_V019_item -- ACCEPT statement i/o item
-
- ffestd_V019_item(expr,expr_token);
-
- Implement output-list expression. */
-
-void
-ffestd_V019_item (ffebld expr)
-{
- ffestd_check_item_ ();
-}
-
-/* ffestd_V019_finish -- ACCEPT statement list complete
-
- ffestd_V019_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_V019_finish ()
+ffestd_V014_finish (void)
{
ffestd_check_finish_ ();
}
-#endif
/* ffestd_V020_start -- TYPE statement list begin
ffestd_V020_start();
@@ -5073,167 +3565,11 @@ ffestd_V020_item (ffebld expr UNUSED)
Just wrap up any local activities. */
void
-ffestd_V020_finish ()
+ffestd_V020_finish (void)
{
ffestd_check_finish_ ();
}
-/* ffestd_V021 -- DELETE statement
-
- ffestd_V021();
-
- Make sure a DELETE is valid in the current context, and implement it. */
-
-#if FFESTR_VXT
-void
-ffestd_V021 ()
-{
- ffestd_check_simple_ ();
- ffestd_subr_vxt_ ();
-}
-
-/* ffestd_V022 -- UNLOCK statement
-
- ffestd_V022();
-
- Make sure a UNLOCK is valid in the current context, and implement it. */
-
-void
-ffestd_V022 ()
-{
- ffestd_check_simple_ ();
- ffestd_subr_vxt_ ();
-}
-
-/* ffestd_V023_start -- ENCODE(...) statement list begin
-
- ffestd_V023_start();
-
- Verify that ENCODE is valid here, and begin accepting items in the
- list. */
-
-void
-ffestd_V023_start ()
-{
- ffestd_check_start_ ();
- ffestd_subr_vxt_ ();
-}
-
-/* ffestd_V023_item -- ENCODE statement i/o item
-
- ffestd_V023_item(expr,expr_token);
-
- Implement output-list expression. */
-
-void
-ffestd_V023_item (ffebld expr)
-{
- ffestd_check_item_ ();
-}
-
-/* ffestd_V023_finish -- ENCODE statement list complete
-
- ffestd_V023_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_V023_finish ()
-{
- ffestd_check_finish_ ();
-}
-
-/* ffestd_V024_start -- DECODE(...) statement list begin
-
- ffestd_V024_start();
-
- Verify that DECODE is valid here, and begin accepting items in the
- list. */
-
-void
-ffestd_V024_start ()
-{
- ffestd_check_start_ ();
- ffestd_subr_vxt_ ();
-}
-
-/* ffestd_V024_item -- DECODE statement i/o item
-
- ffestd_V024_item(expr,expr_token);
-
- Implement output-list expression. */
-
-void
-ffestd_V024_item (ffebld expr)
-{
- ffestd_check_item_ ();
-}
-
-/* ffestd_V024_finish -- DECODE statement list complete
-
- ffestd_V024_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_V024_finish ()
-{
- ffestd_check_finish_ ();
-}
-
-/* ffestd_V025_start -- DEFINEFILE statement list begin
-
- ffestd_V025_start();
-
- Verify that DEFINEFILE is valid here, and begin accepting items in the
- list. */
-
-void
-ffestd_V025_start ()
-{
- ffestd_check_start_ ();
- ffestd_subr_vxt_ ();
-}
-
-/* ffestd_V025_item -- DEFINE FILE statement item
-
- ffestd_V025_item(u,ut,m,mt,n,nt,asv,asvt);
-
- Implement item. Treat each item kind of like a separate statement,
- since there's really no need to treat them as an aggregate. */
-
-void
-ffestd_V025_item (ffebld u, ffebld m, ffebld n, ffebld asv)
-{
- ffestd_check_item_ ();
-}
-
-/* ffestd_V025_finish -- DEFINE FILE statement list complete
-
- ffestd_V025_finish();
-
- Just wrap up any local activities. */
-
-void
-ffestd_V025_finish ()
-{
- ffestd_check_finish_ ();
-}
-
-/* ffestd_V026 -- FIND statement
-
- ffestd_V026();
-
- Make sure a FIND is valid in the current context, and implement it. */
-
-void
-ffestd_V026 ()
-{
- ffestd_check_simple_ ();
- ffestd_subr_vxt_ ();
-}
-
-#endif
/* ffestd_V027_start -- VXT PARAMETER statement list begin
ffestd_V027_start();
@@ -5241,7 +3577,7 @@ ffestd_V026 ()
Verify that PARAMETER is valid here, and begin accepting items in the list. */
void
-ffestd_V027_start ()
+ffestd_V027_start (void)
{
ffestd_check_start_ ();
ffestd_subr_vxt_ ();
@@ -5267,7 +3603,7 @@ ffestd_V027_item (ffelexToken dest_token UNUSED, ffebld source UNUSED)
Just wrap up any local activities. */
void
-ffestd_V027_finish ()
+ffestd_V027_finish (void)
{
ffestd_check_finish_ ();
}
@@ -5275,7 +3611,7 @@ ffestd_V027_finish ()
/* Any executable statement. */
void
-ffestd_any ()
+ffestd_any (void)
{
ffestdStmt_ stmt;
diff --git a/contrib/gcc/f/std.h b/contrib/gcc/f/std.h
index ea8292cc8dcc..29a82a8c9986 100644
--- a/contrib/gcc/f/std.h
+++ b/contrib/gcc/f/std.h
@@ -1,5 +1,5 @@
/* std.h -- Private #include File (module.h template V1.0)
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -58,10 +58,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
void ffestd_begin_uses (void);
void ffestd_do (bool ok);
-#if FFESTR_F90
-void ffestd_end_uses (bool ok);
-void ffestd_end_R740 (bool ok);
-#endif
void ffestd_end_R807 (bool ok);
void ffestd_exec_begin (void);
void ffestd_exec_end (void);
@@ -70,26 +66,6 @@ void ffestd_labeldef_any (ffelab label);
void ffestd_labeldef_branch (ffelab label);
void ffestd_labeldef_format (ffelab label);
void ffestd_labeldef_useless (ffelab label);
-#if FFESTR_F90
-void ffestd_R423A (void);
-void ffestd_R423B (void);
-void ffestd_R424 (ffelexToken access, ffestrOther access_kw, ffelexToken name);
-void ffestd_R425 (bool ok);
-void ffestd_R519_start (ffestrOther intent_kw);
-void ffestd_R519_item (ffelexToken name);
-void ffestd_R519_finish (void);
-void ffestd_R520_start (void);
-void ffestd_R520_item (ffelexToken name);
-void ffestd_R520_finish (void);
-void ffestd_R521A (void);
-void ffestd_R521Astart (void);
-void ffestd_R521Aitem (ffelexToken name);
-void ffestd_R521Afinish (void);
-void ffestd_R521B (void);
-void ffestd_R521Bstart (void);
-void ffestd_R521Bitem (ffelexToken name);
-void ffestd_R521Bfinish (void);
-#endif
void ffestd_R522 (void);
void ffestd_R522start (void);
void ffestd_R522item_object (ffelexToken name);
@@ -98,17 +74,6 @@ void ffestd_R522finish (void);
void ffestd_R524_start (bool virtual);
void ffestd_R524_item (ffelexToken name, ffesttDimList dims);
void ffestd_R524_finish (void);
-#if FFESTR_F90
-void ffestd_R525_start (void);
-void ffestd_R525_item (ffelexToken name, ffesttDimList dims);
-void ffestd_R525_finish (void);
-void ffestd_R526_start (void);
-void ffestd_R526_item (ffelexToken name, ffesttDimList dims);
-void ffestd_R526_finish (void);
-void ffestd_R527_start (void);
-void ffestd_R527_item (ffelexToken name, ffesttDimList dims);
-void ffestd_R527_finish (void);
-#endif
void ffestd_R537_start (void);
void ffestd_R537_item (ffebld dest, ffebld source);
void ffestd_R537_finish (void);
@@ -128,20 +93,7 @@ void ffestd_R547_start (void);
void ffestd_R547_item_object (ffelexToken name, ffesttDimList dims);
void ffestd_R547_item_cblock (ffelexToken name);
void ffestd_R547_finish (void);
-#if FFESTR_F90
-void ffestd_R620 (ffesttExprList exprlist, ffebld stat);
-void ffestd_R624 (ffesttExprList pointers);
-void ffestd_R625 (ffesttExprList exprlist, ffebld stat);
-#endif
void ffestd_R737A (ffebld dest, ffebld source);
-#if FFESTR_F90
-void ffestd_R737B (ffebld dest, ffebld source);
-void ffestd_R738 (ffebld dest, ffebld source);
-void ffestd_R740 (ffebld expr);
-void ffestd_R742 (ffebld expr);
-void ffestd_R744 (void);
-void ffestd_R745 (bool ok);
-#endif
void ffestd_R803 (ffelexToken construct_name, ffebld expr);
void ffestd_R804 (ffebld expr, ffelexToken name);
void ffestd_R805 (ffelexToken name);
@@ -188,22 +140,8 @@ void ffestd_R923B_finish (void);
void ffestd_R1001 (ffesttFormatList f);
void ffestd_R1102 (ffesymbol s, ffelexToken name);
void ffestd_R1103 (bool ok);
-#if FFESTR_F90
-void ffestd_R1105 (ffelexToken name);
-void ffestd_R1106 (bool ok);
-void ffestd_R1107_start (ffelexToken name, bool only);
-void ffestd_R1107_item (ffelexToken local, ffelexToken use);
-void ffestd_R1107_finish (void);
-#endif
void ffestd_R1111 (ffesymbol s, ffelexToken name);
void ffestd_R1112 (bool ok);
-#if FFESTR_F90
-void ffestd_R1202 (ffestpDefinedOperator operator, ffelexToken name);
-void ffestd_R1203 (bool ok);
-void ffestd_R1205_start (void);
-void ffestd_R1205_item (ffelexToken name);
-void ffestd_R1205_finish (void);
-#endif
void ffestd_R1207_start (void);
void ffestd_R1207_item (ffelexToken name);
void ffestd_R1207_finish (void);
@@ -211,9 +149,6 @@ void ffestd_R1208_start (void);
void ffestd_R1208_item (ffelexToken name);
void ffestd_R1208_finish (void);
void ffestd_R1212 (ffebld expr);
-#if FFESTR_F90
-void ffestd_R1213 (ffebld dest, ffebld source);
-#endif
void ffestd_R1219 (ffesymbol s, ffelexToken funcname,
ffesttTokenList args, ffestpType type, ffebld kind,
ffelexToken kindt, ffebld len, ffelexToken lent,
@@ -225,55 +160,16 @@ void ffestd_R1223 (ffesymbol s, ffelexToken subrname, ffesttTokenList args,
void ffestd_R1225 (bool ok);
void ffestd_R1226 (ffesymbol entry);
void ffestd_R1227 (ffebld expr);
-#if FFESTR_F90
-void ffestd_R1228 (void);
-#endif
void ffestd_R1229_start (ffelexToken name, ffesttTokenList args);
void ffestd_R1229_finish (ffesymbol s);
void ffestd_S3P4 (ffebld filename);
-#if FFESTR_VXT
-void ffestd_V003_start (ffelexToken structure_name);
-void ffestd_V003_item (ffelexToken name, ffesttDimList dims);
-void ffestd_V003_finish (void);
-void ffestd_V004 (bool ok);
-void ffestd_V009 (void);
-void ffestd_V010 (bool ok);
-void ffestd_V012 (void);
-void ffestd_V013 (bool ok);
-#endif
void ffestd_V014_start (void);
void ffestd_V014_item_object (ffelexToken name);
void ffestd_V014_item_cblock (ffelexToken name);
void ffestd_V014_finish (void);
-#if FFESTR_VXT
-void ffestd_V016_start (void);
-void ffestd_V016_item_structure (ffelexToken name);
-void ffestd_V016_item_object (ffelexToken name, ffesttDimList dims);
-void ffestd_V016_finish (void);
-void ffestd_V018_start (ffestvFormat format);
-void ffestd_V018_item (ffebld expr);
-void ffestd_V018_finish (void);
-void ffestd_V019_start (ffestvFormat format);
-void ffestd_V019_item (ffebld expr);
-void ffestd_V019_finish (void);
-#endif
void ffestd_V020_start (ffestvFormat format);
void ffestd_V020_item (ffebld expr);
void ffestd_V020_finish (void);
-#if FFESTR_VXT
-void ffestd_V021 (void);
-void ffestd_V022 (void);
-void ffestd_V023_start (void);
-void ffestd_V023_item (ffebld expr);
-void ffestd_V023_finish (void);
-void ffestd_V024_start (void);
-void ffestd_V024_item (ffebld expr);
-void ffestd_V024_finish (void);
-void ffestd_V025_start (void);
-void ffestd_V025_item (ffebld u, ffebld m, ffebld n, ffebld asv);
-void ffestd_V025_finish (void);
-void ffestd_V026 (void);
-#endif
void ffestd_V027_start (void);
void ffestd_V027_item (ffelexToken dest_token, ffebld source);
void ffestd_V027_finish (void);
diff --git a/contrib/gcc/f/ste.c b/contrib/gcc/f/ste.c
index 2ddf18118bfe..82435bc8dc8e 100644
--- a/contrib/gcc/f/ste.c
+++ b/contrib/gcc/f/ste.c
@@ -141,7 +141,7 @@ static void ffeste_subr_beru_ (ffestpBeruStmt *info, ffecomGfrt rt);
/* Internal macros. */
#define ffeste_emit_line_note_() \
- emit_line_note (input_filename, lineno)
+ emit_line_note (input_location)
#define ffeste_check_simple_() \
assert(ffeste_statelet_ == FFESTE_stateletSIMPLE_)
#define ffeste_check_start_() \
@@ -335,7 +335,7 @@ static void ffeste_subr_beru_ (ffestpBeruStmt *info, ffecomGfrt rt);
tree exq = (Exp); \
tree lenexq = (Lenexp); \
int need_exq = (! exq); \
- int need_lenexq = (! lenexq); \
+ int need_lenexq = (! lenexq); \
if (need_exq || need_lenexq) \
{ \
exq = ffecom_arg_ptr_to_expr ((Spec)->u.expr, &lenexq); \
@@ -387,8 +387,7 @@ typedef struct gbe_block
{
struct gbe_block *outer;
ffestw block;
- int lineno;
- const char *input_filename;
+ location_t location;
bool is_stmt;
} *gbe_block;
@@ -401,8 +400,7 @@ ffeste_start_block_ (ffestw block)
b->outer = ffeste_top_block_;
b->block = block;
- b->lineno = lineno;
- b->input_filename = input_filename;
+ b->location = input_location;
b->is_stmt = FALSE;
ffeste_top_block_ = b;
@@ -443,8 +441,7 @@ ffeste_start_stmt_(void)
b->outer = ffeste_top_block_;
b->block = NULL;
- b->lineno = lineno;
- b->input_filename = input_filename;
+ b->location = input_location;
b->is_stmt = TRUE;
ffeste_top_block_ = b;
@@ -1231,7 +1228,7 @@ ffeste_io_ialist_ (bool have_err,
initn = inits;
ffeste_f2c_init_next_ (unitinit);
- inits = build (CONSTRUCTOR, f2c_alist_struct, NULL_TREE, inits);
+ inits = build_constructor (f2c_alist_struct, inits);
TREE_CONSTANT (inits) = constantp ? 1 : 0;
TREE_STATIC (inits) = 1;
@@ -1434,7 +1431,7 @@ ffeste_io_cilist_ (bool have_err,
ffeste_f2c_init_next_ (formatinit);
ffeste_f2c_init_next_ (recinit);
- inits = build (CONSTRUCTOR, f2c_cilist_struct, NULL_TREE, inits);
+ inits = build_constructor (f2c_cilist_struct, inits);
TREE_CONSTANT (inits) = constantp ? 1 : 0;
TREE_STATIC (inits) = 1;
@@ -1561,7 +1558,7 @@ ffeste_io_cllist_ (bool have_err,
ffeste_f2c_init_next_ (unitinit);
ffeste_f2c_init_next_ (statinit);
- inits = build (CONSTRUCTOR, f2c_close_struct, NULL_TREE, inits);
+ inits = build_constructor (f2c_close_struct, inits);
TREE_CONSTANT (inits) = constantp ? 1 : 0;
TREE_STATIC (inits) = 1;
@@ -1766,7 +1763,7 @@ ffeste_io_icilist_ (bool have_err,
ffeste_f2c_init_next_ (unitleninit);
ffeste_f2c_init_next_ (unitnuminit);
- inits = build (CONSTRUCTOR, f2c_icilist_struct, NULL_TREE, inits);
+ inits = build_constructor (f2c_icilist_struct, inits);
TREE_CONSTANT (inits) = constantp ? 1 : 0;
TREE_STATIC (inits) = 1;
@@ -2013,7 +2010,7 @@ ffeste_io_inlist_ (bool have_err,
ffeste_f2c_init_next_ (blankinit);
ffeste_f2c_init_next_ (blankleninit);
- inits = build (CONSTRUCTOR, f2c_inquire_struct, NULL_TREE, inits);
+ inits = build_constructor (f2c_inquire_struct, inits);
TREE_CONSTANT (inits) = constantp ? 1 : 0;
TREE_STATIC (inits) = 1;
@@ -2189,7 +2186,7 @@ ffeste_io_olist_ (bool have_err,
ffeste_f2c_init_next_ (reclinit);
ffeste_f2c_init_next_ (blankinit);
- inits = build (CONSTRUCTOR, f2c_open_struct, NULL_TREE, inits);
+ inits = build_constructor (f2c_open_struct, inits);
TREE_CONSTANT (inits) = constantp ? 1 : 0;
TREE_STATIC (inits) = 1;
@@ -2371,7 +2368,7 @@ ffeste_do (ffestw block)
Applies to *only* logical IF, not to IF-THEN. */
void
-ffeste_end_R807 ()
+ffeste_end_R807 (void)
{
ffeste_emit_line_note_ ();
@@ -2712,19 +2709,18 @@ ffeste_R810 (ffestw block, unsigned long casenum)
{
texprlow = (c->low == NULL) ? NULL_TREE
: ffecom_constantunion_with_type (&ffebld_constant_union (c->low),
- ffecom_tree_type[s->type][s->kindtype], c->low->consttype);
+ ffecom_tree_type[s->type][s->kindtype],c->low->consttype);
if (c->low != c->high)
{
texprhigh = (c->high == NULL) ? NULL_TREE
: ffecom_constantunion_with_type (&ffebld_constant_union (c->high),
- ffecom_tree_type[s->type][s->kindtype], c->high->consttype);
+ ffecom_tree_type[s->type][s->kindtype],c->high->consttype);
pushok = pushcase_range (texprlow, texprhigh, convert,
tlabel, &duplicate);
}
else
pushok = pushcase (texprlow, convert, tlabel, &duplicate);
- assert((pushok !=2) || (pushok !=0));
- if (pushok==2)
+ if (pushok == 2)
{
ffebad_start_msg ("SELECT (at %0) has duplicate cases -- check integer overflow of CASE(s)",
FFEBAD_severityFATAL);
@@ -2828,7 +2824,7 @@ ffeste_R819B (ffestw block, ffelab label UNUSED, ffebld expr)
ending an iterative DO statement, even one that ends at a label. */
void
-ffeste_R825 ()
+ffeste_R825 (void)
{
ffeste_check_simple_ ();
@@ -2954,16 +2950,19 @@ ffeste_R838 (ffelab label, ffebld target)
TREE_CONSTANT (label_tree) = 1;
target_tree = ffecom_expr_assign_w (target);
- if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (target_tree)))
- < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (label_tree))))
- error ("ASSIGN to variable that is too small");
+ if (TREE_CODE (target_tree) != ERROR_MARK)
+ {
+ if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (target_tree)))
+ < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (label_tree))))
+ error ("ASSIGN to variable that is too small");
- label_tree = convert (TREE_TYPE (target_tree), label_tree);
+ label_tree = convert (TREE_TYPE (target_tree), label_tree);
- expr_tree = ffecom_modify (void_type_node,
+ expr_tree = ffecom_modify (void_type_node,
target_tree,
label_tree);
- expand_expr_stmt (expr_tree);
+ expand_expr_stmt (expr_tree);
+ }
}
}
@@ -2982,11 +2981,15 @@ ffeste_R839 (ffebld target)
seen here should never require use of temporaries. */
t = ffecom_expr_assign (target);
- if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
- < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
- error ("ASSIGNed GOTO target variable is too small");
- expand_computed_goto (convert (TREE_TYPE (null_pointer_node), t));
+ if (TREE_CODE (t) != ERROR_MARK)
+ {
+ if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t)))
+ < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node))))
+ error ("ASSIGNed GOTO target variable is too small");
+
+ expand_computed_goto (convert (TREE_TYPE (null_pointer_node), t));
+ }
}
/* Arithmetic IF statement. */
@@ -3094,7 +3097,7 @@ ffeste_R840 (ffebld expr, ffelab neg, ffelab zero, ffelab pos)
/* CONTINUE statement. */
void
-ffeste_R841 ()
+ffeste_R841 (void)
{
ffeste_check_simple_ ();
@@ -3635,7 +3638,7 @@ ffeste_R909_item (ffebld expr, ffelexToken expr_token)
/* READ statement -- end. */
void
-ffeste_R909_finish ()
+ffeste_R909_finish (void)
{
ffeste_check_finish_ ();
@@ -3866,7 +3869,7 @@ ffeste_R910_item (ffebld expr, ffelexToken expr_token)
/* WRITE statement -- end. */
void
-ffeste_R910_finish ()
+ffeste_R910_finish (void)
{
ffeste_check_finish_ ();
@@ -3993,7 +3996,7 @@ ffeste_R911_item (ffebld expr, ffelexToken expr_token)
/* PRINT statement -- end. */
void
-ffeste_R911_finish ()
+ffeste_R911_finish (void)
{
ffeste_check_finish_ ();
@@ -4164,7 +4167,7 @@ ffeste_R923B_item (ffebld expr UNUSED)
/* INQUIRE(IOLENGTH=expr) statement -- end. */
void
-ffeste_R923B_finish ()
+ffeste_R923B_finish (void)
{
ffeste_check_finish_ ();
}
@@ -4224,14 +4227,14 @@ ffeste_R1001 (ffests s)
/* END PROGRAM. */
void
-ffeste_R1103 ()
+ffeste_R1103 (void)
{
}
/* END BLOCK DATA. */
void
-ffeste_R1112 ()
+ffeste_R1112 (void)
{
}
@@ -4360,14 +4363,14 @@ ffeste_R1212 (ffebld expr)
/* END FUNCTION. */
void
-ffeste_R1221 ()
+ffeste_R1221 (void)
{
}
/* END SUBROUTINE. */
void
-ffeste_R1225 ()
+ffeste_R1225 (void)
{
}
@@ -4433,54 +4436,6 @@ ffeste_R1227 (ffestw block UNUSED, ffebld expr)
/* REWRITE statement -- start. */
-#if FFESTR_VXT
-void
-ffeste_V018_start (ffestpRewriteStmt *info, ffestvFormat format)
-{
- ffeste_check_start_ ();
-}
-
-/* REWRITE statement -- I/O item. */
-
-void
-ffeste_V018_item (ffebld expr)
-{
- ffeste_check_item_ ();
-}
-
-/* REWRITE statement -- end. */
-
-void
-ffeste_V018_finish ()
-{
- ffeste_check_finish_ ();
-}
-
-/* ACCEPT statement -- start. */
-
-void
-ffeste_V019_start (ffestpAcceptStmt *info, ffestvFormat format)
-{
- ffeste_check_start_ ();
-}
-
-/* ACCEPT statement -- I/O item. */
-
-void
-ffeste_V019_item (ffebld expr)
-{
- ffeste_check_item_ ();
-}
-
-/* ACCEPT statement -- end. */
-
-void
-ffeste_V019_finish ()
-{
- ffeste_check_finish_ ();
-}
-
-#endif
/* TYPE statement -- start. */
void
@@ -4501,109 +4456,13 @@ ffeste_V020_item (ffebld expr UNUSED)
/* TYPE statement -- end. */
void
-ffeste_V020_finish ()
+ffeste_V020_finish (void)
{
ffeste_check_finish_ ();
}
/* DELETE statement. */
-#if FFESTR_VXT
-void
-ffeste_V021 (ffestpDeleteStmt *info)
-{
- ffeste_check_simple_ ();
-}
-
-/* UNLOCK statement. */
-
-void
-ffeste_V022 (ffestpBeruStmt *info)
-{
- ffeste_check_simple_ ();
-}
-
-/* ENCODE statement -- start. */
-
-void
-ffeste_V023_start (ffestpVxtcodeStmt *info)
-{
- ffeste_check_start_ ();
-}
-
-/* ENCODE statement -- I/O item. */
-
-void
-ffeste_V023_item (ffebld expr)
-{
- ffeste_check_item_ ();
-}
-
-/* ENCODE statement -- end. */
-
-void
-ffeste_V023_finish ()
-{
- ffeste_check_finish_ ();
-}
-
-/* DECODE statement -- start. */
-
-void
-ffeste_V024_start (ffestpVxtcodeStmt *info)
-{
- ffeste_check_start_ ();
-}
-
-/* DECODE statement -- I/O item. */
-
-void
-ffeste_V024_item (ffebld expr)
-{
- ffeste_check_item_ ();
-}
-
-/* DECODE statement -- end. */
-
-void
-ffeste_V024_finish ()
-{
- ffeste_check_finish_ ();
-}
-
-/* DEFINEFILE statement -- start. */
-
-void
-ffeste_V025_start ()
-{
- ffeste_check_start_ ();
-}
-
-/* DEFINE FILE statement -- item. */
-
-void
-ffeste_V025_item (ffebld u, ffebld m, ffebld n, ffebld asv)
-{
- ffeste_check_item_ ();
-}
-
-/* DEFINE FILE statement -- end. */
-
-void
-ffeste_V025_finish ()
-{
- ffeste_check_finish_ ();
-}
-
-/* FIND statement. */
-
-void
-ffeste_V026 (ffestpFindStmt *info)
-{
- ffeste_check_simple_ ();
-}
-
-#endif
#ifdef ENABLE_CHECKING
void
diff --git a/contrib/gcc/f/ste.h b/contrib/gcc/f/ste.h
index fb32c792f980..ac04a4c00da1 100644
--- a/contrib/gcc/f/ste.h
+++ b/contrib/gcc/f/ste.h
@@ -1,5 +1,5 @@
/* ste.h -- Private #include File (module.h template V1.0)
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -114,31 +114,9 @@ void ffeste_R1221 (void);
void ffeste_R1225 (void);
void ffeste_R1226 (ffesymbol entry);
void ffeste_R1227 (ffestw block, ffebld expr);
-#if FFESTR_VXT
-void ffeste_V018_start (ffestpRewriteStmt *info, ffestvFormat format);
-void ffeste_V018_item (ffebld expr);
-void ffeste_V018_finish (void);
-void ffeste_V019_start (ffestpAcceptStmt *info, ffestvFormat format);
-void ffeste_V019_item (ffebld expr);
-void ffeste_V019_finish (void);
-#endif
void ffeste_V020_start (ffestpTypeStmt *info, ffestvFormat format);
void ffeste_V020_item (ffebld expr);
void ffeste_V020_finish (void);
-#if FFESTR_VXT
-void ffeste_V021 (ffestpDeleteStmt *info);
-void ffeste_V022 (ffestpBeruStmt *info);
-void ffeste_V023_start (ffestpVxtcodeStmt *info);
-void ffeste_V023_item (ffebld expr);
-void ffeste_V023_finish (void);
-void ffeste_V024_start (ffestpVxtcodeStmt *info);
-void ffeste_V024_item (ffebld expr);
-void ffeste_V024_finish (void);
-void ffeste_V025_start (void);
-void ffeste_V025_item (ffebld u, ffebld m, ffebld n, ffebld asv);
-void ffeste_V025_finish (void);
-void ffeste_V026 (ffestpFindStmt *info);
-#endif
/* Define macros. */
@@ -148,9 +126,9 @@ void ffeste_V026 (ffestpFindStmt *info);
#define ffeste_init_3()
#define ffeste_init_4()
#define ffeste_filename() input_filename
-#define ffeste_filelinenum() lineno
+#define ffeste_filelinenum() input_line
#define ffeste_set_line(name,num) \
- (input_filename = (name), lineno = (num))
+ (input_filename = (name), input_line = (num))
#define ffeste_terminate_0()
#define ffeste_terminate_1()
#ifdef ENABLE_CHECKING
diff --git a/contrib/gcc/f/storag.c b/contrib/gcc/f/storag.c
index f8af500ddb98..8e9cb247a081 100644
--- a/contrib/gcc/f/storag.c
+++ b/contrib/gcc/f/storag.c
@@ -1,5 +1,5 @@
/* storag.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -162,7 +162,7 @@ ffestorag_dump (ffestorag s)
ffestorag_init_2(); */
void
-ffestorag_init_2 ()
+ffestorag_init_2 (void)
{
ffestorag_list_.first = ffestorag_list_.last
= (ffestorag) &ffestorag_list_.first;
@@ -416,13 +416,10 @@ ffestorag_new (ffestoragList sl)
{
ffestorag s;
- s = (ffestorag) malloc_new_kp (ffe_pool_program_unit (), "ffestorag",
- sizeof (*s));
+ s = malloc_new_kp (ffe_pool_program_unit (), "ffestorag", sizeof (*s));
s->next = (ffestorag) &sl->first;
s->previous = sl->last;
-#ifdef FFECOM_storageHOOK
s->hook = FFECOM_storageNULL;
-#endif
s->previous->next = s;
sl->last = s;
s->equivs_.first = s->equivs_.last = (ffestorag) &s->equivs_.first;
@@ -433,7 +430,7 @@ ffestorag_new (ffestoragList sl)
/* Report info on LOCAL non-sym-assoc'ed entities if needed. */
void
-ffestorag_report ()
+ffestorag_report (void)
{
ffestorag s;
diff --git a/contrib/gcc/f/storag.h b/contrib/gcc/f/storag.h
index e4aa4046db70..b58dc9a9602e 100644
--- a/contrib/gcc/f/storag.h
+++ b/contrib/gcc/f/storag.h
@@ -1,5 +1,5 @@
/* storag.h -- Public #include File (module.h template V1.0)
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -83,9 +83,7 @@ struct _ffestorag_
LOCAL. */
ffetargetAlign alignment; /* Initial alignment for entity. */
ffetargetAlign modulo; /* Modulo within alignment. */
-#ifdef FFECOM_storageHOOK
ffecomStorage hook; /* Whatever the backend needs here. */
-#endif
ffestoragType type;
ffeinfoBasictype basic_type;/* NONE= >1 non-CHARACTER; ANY=
CHAR+non-CHAR. */
diff --git a/contrib/gcc/f/str.h b/contrib/gcc/f/str.h
index 543eeeb7c90e..b3ac04e5cb6d 100644
--- a/contrib/gcc/f/str.h
+++ b/contrib/gcc/f/str.h
@@ -1,5 +1,5 @@
/* str.h -- Private #include File (module.h template V1.0)
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -30,11 +30,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_F_STR_H
#define GCC_F_STR_H
-/* Simple definitions and enumerations. */
-
-#define FFESTR_F90 0 /* Unsupported F90 stuff. */
-#define FFESTR_VXT 0 /* Unsupported VXT stuff. */
-
/* Typedefs. */
diff --git a/contrib/gcc/f/stt.c b/contrib/gcc/f/stt.c
index c48a505b48b2..e616d492289a 100644
--- a/contrib/gcc/f/stt.c
+++ b/contrib/gcc/f/stt.c
@@ -1,5 +1,5 @@
/* stt.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1997, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -79,8 +79,7 @@ ffestt_caselist_append (ffesttCaseList list, bool range, ffebld case1,
{
ffesttCaseList new;
- new = (ffesttCaseList) malloc_new_kp (ffesta_scratch_pool,
- "FFEST case list", sizeof (*new));
+ new = malloc_new_kp (ffesta_scratch_pool, "FFEST case list", sizeof (*new));
new->next = list->previous->next;
new->previous = list->previous;
new->next->previous = new;
@@ -99,13 +98,12 @@ ffestt_caselist_append (ffesttCaseList list, bool range, ffebld case1,
The list is allocated out of the scratch pool. */
ffesttCaseList
-ffestt_caselist_create ()
+ffestt_caselist_create (void)
{
ffesttCaseList new;
- new = (ffesttCaseList) malloc_new_kp (ffesta_scratch_pool,
- "FFEST case list root",
- sizeof (*new));
+ new = malloc_new_kp (ffesta_scratch_pool, "FFEST case list root",
+ sizeof (*new));
new->next = new->previous = new;
new->t = NULL;
new->expr1 = NULL;
@@ -151,8 +149,7 @@ ffestt_dimlist_append (ffesttDimList list, ffebld lower, ffebld upper,
{
ffesttDimList new;
- new = (ffesttDimList) malloc_new_kp (ffesta_scratch_pool,
- "FFEST dim list", sizeof (*new));
+ new = malloc_new_kp (ffesta_scratch_pool, "FFEST dim list", sizeof (*new));
new->next = list->previous->next;
new->previous = list->previous;
new->next->previous = new;
@@ -396,12 +393,12 @@ ffestt_dimlist_as_expr (ffesttDimList list, ffeinfoRank *rank,
The list is allocated out of the scratch pool. */
ffesttDimList
-ffestt_dimlist_create ()
+ffestt_dimlist_create (void)
{
ffesttDimList new;
- new = (ffesttDimList) malloc_new_kp (ffesta_scratch_pool,
- "FFEST dim list root", sizeof (*new));
+ new = malloc_new_kp (ffesta_scratch_pool, "FFEST dim list root",
+ sizeof (*new));
new->next = new->previous = new;
new->t = NULL;
new->lower = NULL;
@@ -503,8 +500,7 @@ ffestt_exprlist_append (ffesttExprList list, ffebld expr, ffelexToken t)
{
ffesttExprList new;
- new = (ffesttExprList) malloc_new_kp (ffesta_scratch_pool,
- "FFEST expr list", sizeof (*new));
+ new = malloc_new_kp (ffesta_scratch_pool, "FFEST expr list", sizeof (*new));
new->next = list->previous->next;
new->previous = list->previous;
new->next->previous = new;
@@ -521,12 +517,12 @@ ffestt_exprlist_append (ffesttExprList list, ffebld expr, ffelexToken t)
The list is allocated out of the scratch pool. */
ffesttExprList
-ffestt_exprlist_create ()
+ffestt_exprlist_create (void)
{
ffesttExprList new;
- new = (ffesttExprList) malloc_new_kp (ffesta_scratch_pool,
- "FFEST expr list root", sizeof (*new));
+ new = malloc_new_kp (ffesta_scratch_pool, "FFEST expr list root",
+ sizeof (*new));
new->next = new->previous = new;
new->expr = NULL;
new->t = NULL;
@@ -592,8 +588,8 @@ ffestt_formatlist_append (ffesttFormatList list)
{
ffesttFormatList new;
- new = (ffesttFormatList) malloc_new_kp (ffesta_scratch_pool,
- "FFEST format list", sizeof (*new));
+ new = malloc_new_kp (ffesta_scratch_pool, "FFEST format list",
+ sizeof (*new));
new->next = list->previous->next;
new->previous = list->previous;
new->next->previous = new;
@@ -613,8 +609,8 @@ ffestt_formatlist_create (ffesttFormatList parent, ffelexToken t)
{
ffesttFormatList new;
- new = (ffesttFormatList) malloc_new_kp (ffesta_scratch_pool,
- "FFEST format list root", sizeof (*new));
+ new = malloc_new_kp (ffesta_scratch_pool, "FFEST format list root",
+ sizeof (*new));
new->next = new->previous = new;
new->type = FFESTP_formattypeNone;
new->t = t;
@@ -720,8 +716,7 @@ ffestt_implist_append (ffesttImpList list, ffelexToken first, ffelexToken last)
{
ffesttImpList new;
- new = (ffesttImpList) malloc_new_kp (ffesta_scratch_pool,
- "FFEST token list", sizeof (*new));
+ new = malloc_new_kp (ffesta_scratch_pool, "FFEST token list", sizeof (*new));
new->next = list->previous->next;
new->previous = list->previous;
new->next->previous = new;
@@ -738,13 +733,12 @@ ffestt_implist_append (ffesttImpList list, ffelexToken first, ffelexToken last)
The list is allocated out of the scratch pool. */
ffesttImpList
-ffestt_implist_create ()
+ffestt_implist_create (void)
{
ffesttImpList new;
- new = (ffesttImpList) malloc_new_kp (ffesta_scratch_pool,
- "FFEST token list root",
- sizeof (*new));
+ new = malloc_new_kp (ffesta_scratch_pool, "FFEST token list root",
+ sizeof (*new));
new->next = new->previous = new;
new->first = NULL;
new->last = NULL;
@@ -807,8 +801,7 @@ ffestt_tokenlist_append (ffesttTokenList tl, ffelexToken t)
{
ffesttTokenItem ti;
- ti = (ffesttTokenItem) malloc_new_kp (ffesta_scratch_pool,
- "FFEST token item", sizeof (*ti));
+ ti = malloc_new_kp (ffesta_scratch_pool, "FFEST token item", sizeof (*ti));
ti->next = (ffesttTokenItem) &tl->first;
ti->previous = tl->last;
ti->next->previous = ti;
@@ -825,12 +818,11 @@ ffestt_tokenlist_append (ffesttTokenList tl, ffelexToken t)
The list is allocated out of the scratch pool. */
ffesttTokenList
-ffestt_tokenlist_create ()
+ffestt_tokenlist_create (void)
{
ffesttTokenList tl;
- tl = (ffesttTokenList) malloc_new_kp (ffesta_scratch_pool,
- "FFEST token list", sizeof (*tl));
+ tl = malloc_new_kp (ffesta_scratch_pool, "FFEST token list", sizeof (*tl));
tl->first = tl->last = (ffesttTokenItem) &tl->first;
tl->count = 0;
return tl;
diff --git a/contrib/gcc/f/stw.c b/contrib/gcc/f/stw.c
index 058b1eb952af..57658de3204e 100644
--- a/contrib/gcc/f/stw.c
+++ b/contrib/gcc/f/stw.c
@@ -1,5 +1,5 @@
/* stw.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -278,12 +278,12 @@ ffestw_display_state (void)
ffestw_init_0(); */
void
-ffestw_init_0 ()
+ffestw_init_0 (void)
{
ffestw b;
- ffestw_stack_top_ = b = (ffestw) malloc_new_kp (malloc_pool_image (),
- "FFESTW stack base", sizeof (*b));
+ ffestw_stack_top_ = b = malloc_new_kp (malloc_pool_image (),
+ "FFESTW stack base", sizeof (*b));
b->uses_ = 0; /* catch if anyone uses, kills, &c this
block. */
b->next_ = NULL;
@@ -324,7 +324,7 @@ ffestw_new (void)
{
ffestw b;
- b = (ffestw) malloc_new_kp (malloc_pool_image (), "FFESTW", sizeof (*b));
+ b = malloc_new_kp (malloc_pool_image (), "FFESTW", sizeof (*b));
b->uses_ = 1;
return b;
diff --git a/contrib/gcc/f/symbol.c b/contrib/gcc/f/symbol.c
index 816ad1964bbc..c22697ff3771 100644
--- a/contrib/gcc/f/symbol.c
+++ b/contrib/gcc/f/symbol.c
@@ -1,5 +1,6 @@
/* Implementation of Fortran symbol manager
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 2003
+ Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -177,7 +178,7 @@ ffesymbol_check_token_ (ffelexToken t, char *c)
/* Kill manifest (g77-picked) names. */
static void
-ffesymbol_kill_manifest_ ()
+ffesymbol_kill_manifest_ (void)
{
if (ffesymbol_token_blank_common_ != NULL)
ffelex_token_kill (ffesymbol_token_blank_common_);
@@ -205,8 +206,7 @@ ffesymbol_new_ (ffename n)
assert (n != NULL);
- s = (ffesymbol) malloc_new_ks (FFESYMBOL_SPACE_POOL_, "FFESYMBOL",
- sizeof (*s));
+ s = malloc_new_ks (FFESYMBOL_SPACE_POOL_, "FFESYMBOL", sizeof (*s));
s->name = n;
s->other_space_name = NULL;
#if FFEGLOBAL_ENABLED
@@ -230,9 +230,7 @@ ffesymbol_new_ (ffename n)
s->common = NULL;
s->equiv = NULL;
s->storage = NULL;
-#ifdef FFECOM_symbolHOOK
s->hook = FFECOM_symbolNULL;
-#endif
s->sfa_dummy_parent = NULL;
s->func_result = NULL;
s->value = 0;
@@ -259,8 +257,8 @@ ffesymbol_new_ (ffename n)
return s;
}
- r = (ffesymbolRetract_) malloc_new_kp (ffesymbol_retract_pool_,
- "FFESYMBOL retract", sizeof (*r));
+ r = malloc_new_kp (ffesymbol_retract_pool_, "FFESYMBOL retract",
+ sizeof (*r));
r->next = NULL;
r->command = FFESYMBOL_retractcommandDELETE_;
r->live = s;
@@ -823,7 +821,7 @@ ffesymbol_error (ffesymbol s, ffelexToken t)
}
void
-ffesymbol_init_0 ()
+ffesymbol_init_0 (void)
{
ffesymbolAttrs attrs = FFESYMBOL_attrsetNONE;
@@ -835,7 +833,7 @@ ffesymbol_init_0 ()
}
void
-ffesymbol_init_1 ()
+ffesymbol_init_1 (void)
{
#if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalFILE_
ffesymbol_global_ = ffename_space_new (ffe_pool_file ());
@@ -843,12 +841,12 @@ ffesymbol_init_1 ()
}
void
-ffesymbol_init_2 ()
+ffesymbol_init_2 (void)
{
}
void
-ffesymbol_init_3 ()
+ffesymbol_init_3 (void)
{
#if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_
ffesymbol_global_ = ffename_space_new (ffe_pool_program_unit ());
@@ -857,7 +855,7 @@ ffesymbol_init_3 ()
}
void
-ffesymbol_init_4 ()
+ffesymbol_init_4 (void)
{
ffesymbol_sfunc_ = ffename_space_new (ffe_pool_program_unit ());
}
@@ -1061,7 +1059,7 @@ ffesymbol_retract (bool retract)
/* Return retractable flag. */
bool
-ffesymbol_retractable ()
+ffesymbol_retractable (void)
{
return ffesymbol_retractable_;
}
@@ -1105,13 +1103,13 @@ ffesymbol_signal_change (ffesymbol s)
if (!ffesymbol_retractable_ || s->have_old)
return;
- r = (ffesymbolRetract_) malloc_new_kp (ffesymbol_retract_pool_,
- "FFESYMBOL retract", sizeof (*r));
+ r = malloc_new_kp (ffesymbol_retract_pool_, "FFESYMBOL retract",
+ sizeof (*r));
r->next = NULL;
r->command = FFESYMBOL_retractcommandRETRACT_;
r->live = s;
- r->symbol = sym = (ffesymbol) malloc_new_ks (FFESYMBOL_SPACE_POOL_,
- "FFESYMBOL", sizeof (*sym));
+ r->symbol = sym = malloc_new_ks (FFESYMBOL_SPACE_POOL_,
+ "FFESYMBOL", sizeof (*sym));
*sym = *s; /* Make an exact copy of the symbol in case
we need it back. */
sym->info = ffeinfo_use (s->info);
@@ -1135,12 +1133,12 @@ ffesymbol_state_string (ffesymbolState state)
}
void
-ffesymbol_terminate_0 ()
+ffesymbol_terminate_0 (void)
{
}
void
-ffesymbol_terminate_1 ()
+ffesymbol_terminate_1 (void)
{
#if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalFILE_
ffename_space_drive_symbol (ffesymbol_global_, ffesymbol_unhook_);
@@ -1152,7 +1150,7 @@ ffesymbol_terminate_1 ()
}
void
-ffesymbol_terminate_2 ()
+ffesymbol_terminate_2 (void)
{
#if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_
ffesymbol_kill_manifest_ ();
@@ -1160,7 +1158,7 @@ ffesymbol_terminate_2 ()
}
void
-ffesymbol_terminate_3 ()
+ffesymbol_terminate_3 (void)
{
#if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_
ffename_space_drive_symbol (ffesymbol_global_, ffesymbol_unhook_);
@@ -1175,7 +1173,7 @@ ffesymbol_terminate_3 ()
}
void
-ffesymbol_terminate_4 ()
+ffesymbol_terminate_4 (void)
{
ffename_space_drive_symbol (ffesymbol_sfunc_, ffesymbol_unhook_);
ffename_space_kill (ffesymbol_sfunc_);
diff --git a/contrib/gcc/f/symbol.h b/contrib/gcc/f/symbol.h
index c9e582a4f264..7ddafbd446dd 100644
--- a/contrib/gcc/f/symbol.h
+++ b/contrib/gcc/f/symbol.h
@@ -1,5 +1,5 @@
/* Interface definitions for Fortran symbol manager
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -121,9 +121,7 @@ struct _ffesymbol_
ffeequiv equiv; /* Who have I been equivalenced with? */
ffestorag storage; /* Where am I in relation to my outside
world? */
-#ifdef FFECOM_symbolHOOK
ffecomSymbol hook; /* Whatever the compiler/backend wants! */
-#endif
ffesymbol sfa_dummy_parent; /* "X" outside sfunc "CIRC(X) = 3.14 * X". */
ffesymbol func_result; /* FUN sym's corresponding RES sym, & vice
versa. */
diff --git a/contrib/gcc/f/target.c b/contrib/gcc/f/target.c
index 82ae955ebec9..16261120e240 100644
--- a/contrib/gcc/f/target.c
+++ b/contrib/gcc/f/target.c
@@ -76,6 +76,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "lex.h"
#include "malloc.h"
#include "real.h"
+#include "toplev.h"
/* Externals defined here. */
@@ -104,11 +105,6 @@ static void ffetarget_print_char_ (FILE *f, unsigned char c);
/* Internal macros. */
-#ifdef REAL_VALUE_ATOF
-#define FFETARGET_ATOF_(p,m) REAL_VALUE_ATOF ((p),(m))
-#else
-#define FFETARGET_ATOF_(p,m) atof ((p))
-#endif
/* ffetarget_print_char_ -- Print a single character (in apostrophe context)
@@ -2243,8 +2239,7 @@ ffetarget_real1 (ffetargetReal1 *value, ffelexToken integer,
#undef dotoktxt
if (sz > ARRAY_SIZE (ffetarget_string_))
- p = ptr = (char *) malloc_new_ks (malloc_pool_image (), "ffetarget_real1",
- sz);
+ p = ptr = malloc_new_ks (malloc_pool_image (), "ffetarget_real1", sz);
#define dotoktxt(x) if (x != NULL) \
{ \
@@ -2279,7 +2274,7 @@ ffetarget_real1 (ffetargetReal1 *value, ffelexToken integer,
{
REAL_VALUE_TYPE rv;
- rv = FFETARGET_ATOF_ (ptr, SFmode);
+ real_from_string (&rv, ptr);
ffetarget_make_real1 (value, rv);
}
@@ -2326,7 +2321,7 @@ ffetarget_real2 (ffetargetReal2 *value, ffelexToken integer,
#undef dotoktxt
if (sz > ARRAY_SIZE (ffetarget_string_))
- p = ptr = (char *) malloc_new_ks (malloc_pool_image (), "ffetarget_real1", sz);
+ p = ptr = malloc_new_ks (malloc_pool_image (), "ffetarget_real1", sz);
#define dotoktxt(x) if (x != NULL) \
{ \
@@ -2367,7 +2362,7 @@ ffetarget_real2 (ffetargetReal2 *value, ffelexToken integer,
{
REAL_VALUE_TYPE rv;
- rv = FFETARGET_ATOF_ (ptr, DFmode);
+ real_from_string (&rv, ptr);
ffetarget_make_real2 (value, rv);
}
diff --git a/contrib/gcc/f/target.h b/contrib/gcc/f/target.h
index 2125ad54eee8..8ec73addc85c 100644
--- a/contrib/gcc/f/target.h
+++ b/contrib/gcc/f/target.h
@@ -1,5 +1,6 @@
/* target.h -- Public #include File (module.h template V1.0)
- Copyright (C) 1995, 1996, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2002, 2003
+ Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -30,13 +31,9 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_F_TARGET_H
#define GCC_F_TARGET_H
-#ifdef FFE_STANDALONE
-#define HOST_WIDE_INT long
-#else
#ifndef TREE_CODE
#include "tree.h"
#endif
-#endif
/* Simple definitions and enumerations. */
@@ -269,26 +266,6 @@ typedef short int ffetargetInteger3;
typedef long long int ffetargetInteger4;
#define ffetargetInteger4_f "ll"
#endif
-#if FFETARGET_okINTEGER5
-typedef ? ffetargetInteger5;
-#define ffetargetInteger5_f
-?
-#endif
-#if FFETARGET_okINTEGER6
-typedef ? ffetargetInteger6;
-#define ffetargetInteger6_f
-?
-#endif
-#if FFETARGET_okINTEGER7
-typedef ? ffetargetInteger7;
-#define ffetargetInteger7_f
-?
-#endif
-#if FFETARGET_okINTEGER8
-typedef ? ffetargetInteger8;
-#define ffetargetInteger8_f
-?
-#endif
#if FFETARGET_okLOGICAL1
#ifdef FFETARGET_32bit_longs
typedef long int ffetargetLogical1;
@@ -310,26 +287,6 @@ typedef short int ffetargetLogical3;
typedef long long int ffetargetLogical4;
#define ffetargetLogical4_f "ll"
#endif
-#if FFETARGET_okLOGICAL5
-typedef ? ffetargetLogical5;
-#define ffetargetLogical5_f
-?
-#endif
-#if FFETARGET_okLOGICAL6
-typedef ? ffetargetLogical6;
-#define ffetargetLogical6_f
-?
-#endif
-#if FFETARGET_okLOGICAL7
-typedef ? ffetargetLogical7;
-#define ffetargetLogical7_f
-?
-#endif
-#if FFETARGET_okLOGICAL8
-typedef ? ffetargetLogical8;
-#define ffetargetLogical8_f
-?
-#endif
#if FFETARGET_okREAL1
typedef int ffetargetReal1;
#define ffetargetReal1_f ""
@@ -360,26 +317,6 @@ typedef struct { int v[2]; } ffetargetReal2;
typedef long ffetargetReal3[?];
?
#endif
-#if FFETARGET_okREAL4
-typedef long ffetargetReal4[?];
-?
-#endif
-#if FFETARGET_okREAL5
-typedef long ffetargetReal5[?];
-?
-#endif
-#if FFETARGET_okREAL6
-typedef long ffetargetReal6[?];
-?
-#endif
-#if FFETARGET_okREAL7
-typedef long ffetargetReal7[?];
-?
-#endif
-#if FFETARGET_okREAL8
-typedef long ffetargetReal8[?];
-?
-#endif
#if FFETARGET_okCOMPLEX1
struct _ffetarget_complex_1_
{
@@ -404,46 +341,6 @@ struct _ffetarget_complex_3_
};
typedef struct _ffetarget_complex_3_ ffetargetComplex3;
#endif
-#if FFETARGET_okCOMPLEX4
-struct _ffetarget_complex_4_
- {
- ffetargetReal4 real;
- ffetargetReal4 imaginary;
- };
-typedef struct _ffetarget_complex_4_ ffetargetComplex4;
-#endif
-#if FFETARGET_okCOMPLEX5
-struct _ffetarget_complex_5_
- {
- ffetargetReal5 real;
- ffetargetReal5 imaginary;
- };
-typedef struct _ffetarget_complex_5_ ffetargetComplex5;
-#endif
-#if FFETARGET_okCOMPLEX6
-struct _ffetarget_complex_6_
- {
- ffetargetReal6 real;
- ffetargetReal6 imaginary;
- };
-typedef struct _ffetarget_complex_6_ ffetargetComplex6;
-#endif
-#if FFETARGET_okCOMPLEX7
-struct _ffetarget_complex_7_
- {
- ffetargetReal7 real;
- ffetargetReal7 imaginary;
- };
-typedef struct _ffetarget_complex_7_ ffetargetComplex7;
-#endif
-#if FFETARGET_okCOMPLEX8
-struct _ffetarget_complex_8_
- {
- ffetargetReal8 real;
- ffetargetReal8 imaginary;
- };
-typedef struct _ffetarget_complex_8_ ffetargetComplex8;
-#endif
#if FFETARGET_okCHARACTER1
struct _ffetarget_char_1_
{
@@ -453,34 +350,6 @@ struct _ffetarget_char_1_
typedef struct _ffetarget_char_1_ ffetargetCharacter1;
typedef unsigned char ffetargetCharacterUnit1;
#endif
-#if FFETARGET_okCHARACTER2
-typedef ? ffetargetCharacter2;
-typedef ? ffetargetCharacterUnit2;
-#endif
-#if FFETARGET_okCHARACTER3
-typedef ? ffetargetCharacter3;
-typedef ? ffetargetCharacterUnit3;
-#endif
-#if FFETARGET_okCHARACTER4
-typedef ? ffetargetCharacter4;
-typedef ? ffetargetCharacterUnit4;
-#endif
-#if FFETARGET_okCHARACTER5
-typedef ? ffetargetCharacter5;
-typedef ? ffetargetCharacterUnit5;
-#endif
-#if FFETARGET_okCHARACTER6
-typedef ? ffetargetCharacter6;
-typedef ? ffetargetCharacterUnit6;
-#endif
-#if FFETARGET_okCHARACTER7
-typedef ? ffetargetCharacter7;
-typedef ? ffetargetCharacterUnit7;
-#endif
-#if FFETARGET_okCHARACTER8
-typedef ? ffetargetCharacter8;
-typedef ? ffetargetCharacterUnit8;
-#endif
typedef unsigned long long int ffetargetTypeless;
@@ -608,26 +477,6 @@ ffebad ffetarget_divide_complex2 (ffetargetComplex2 *res, ffetargetComplex2 l,
ffebad ffetarget_divide_complex3 (ffetargetComplex3 *res, ffetargetComplex3 l,
ffetargetComplex3 r);
#endif
-#if FFETARGET_okCOMPLEX4
-ffebad ffetarget_divide_complex4 (ffetargetComplex4 *res, ffetargetComplex4 l,
- ffetargetComplex4 r);
-#endif
-#if FFETARGET_okCOMPLEX5
-ffebad ffetarget_divide_complex5 (ffetargetComplex5 *res, ffetargetComplex5 l,
- ffetargetComplex5 r);
-#endif
-#if FFETARGET_okCOMPLEX6
-ffebad ffetarget_divide_complex6 (ffetargetComplex6 *res, ffetargetComplex6 l,
- ffetargetComplex6 r);
-#endif
-#if FFETARGET_okCOMPLEX7
-ffebad ffetarget_divide_complex7 (ffetargetComplex7 *res, ffetargetComplex7 l,
- ffetargetComplex7 r);
-#endif
-#if FFETARGET_okCOMPLEX8
-ffebad ffetarget_divide_complex8 (ffetargetComplex8 *res, ffetargetComplex8 l,
- ffetargetComplex8 r);
-#endif
#if FFETARGET_okINTEGER1
bool ffetarget_integer1 (ffetargetInteger1 *val, ffelexToken integer);
#endif
@@ -640,18 +489,6 @@ bool ffetarget_integer3 (ffetargetInteger3 *val, ffelexToken integer);
#if FFETARGET_okINTEGER4
bool ffetarget_integer4 (ffetargetInteger4 *val, ffelexToken integer);
#endif
-#if FFETARGET_okINTEGER5
-bool ffetarget_integer5 (ffetargetInteger5 *val, ffelexToken integer);
-#endif
-#if FFETARGET_okINTEGER6
-bool ffetarget_integer6 (ffetargetInteger6 *val, ffelexToken integer);
-#endif
-#if FFETARGET_okINTEGER7
-bool ffetarget_integer7 (ffetargetInteger7 *val, ffelexToken integer);
-#endif
-#if FFETARGET_okINTEGER8
-bool ffetarget_integer8 (ffetargetInteger8 *val, ffelexToken integer);
-#endif
bool ffetarget_integerbinary (ffetargetIntegerDefault *val,
ffelexToken integer);
bool ffetarget_integerhex (ffetargetIntegerDefault *val,
@@ -690,31 +527,6 @@ ffebad ffetarget_multiply_complex3 (ffetargetComplex3 *res,
ffetargetComplex3 l,
ffetargetComplex3 r);
#endif
-#if FFETARGET_okCOMPLEX4
-ffebad ffetarget_multiply_complex4 (ffetargetComplex4 *res,
- ffetargetComplex4 l,
- ffetargetComplex4 r);
-#endif
-#if FFETARGET_okCOMPLEX5
-ffebad ffetarget_multiply_complex5 (ffetargetComplex5 *res,
- ffetargetComplex5 l,
- ffetargetComplex5 r);
-#endif
-#if FFETARGET_okCOMPLEX6
-ffebad ffetarget_multiply_complex6 (ffetargetComplex6 *res,
- ffetargetComplex6 l,
- ffetargetComplex6 r);
-#endif
-#if FFETARGET_okCOMPLEX7
-ffebad ffetarget_multiply_complex7 (ffetargetComplex7 *res,
- ffetargetComplex7 l,
- ffetargetComplex7 r);
-#endif
-#if FFETARGET_okCOMPLEX8
-ffebad ffetarget_multiply_complex8 (ffetargetComplex8 *res,
- ffetargetComplex8 l,
- ffetargetComplex8 r);
-#endif
ffebad ffetarget_power_complexdefault_integerdefault (ffetargetComplexDefault *res,
ffetargetComplexDefault l,
ffetargetIntegerDefault r);
@@ -755,36 +567,6 @@ bool ffetarget_real3 (ffetargetReal3 *value, ffelexToken integer,
ffelexToken exponent, ffelexToken exponent_sign,
ffelexToken exponent_digits);
#endif
-#if FFETARGET_okREAL4
-bool ffetarget_real4 (ffetargetReal4 *value, ffelexToken integer,
- ffelexToken decimal, ffelexToken fraction,
- ffelexToken exponent, ffelexToken exponent_sign,
- ffelexToken exponent_digits);
-#endif
-#if FFETARGET_okREAL5
-bool ffetarget_real5 (ffetargetReal5 *value, ffelexToken integer,
- ffelexToken decimal, ffelexToken fraction,
- ffelexToken exponent, ffelexToken exponent_sign,
- ffelexToken exponent_digits);
-#endif
-#if FFETARGET_okREAL6
-bool ffetarget_real6 (ffetargetReal6 *value, ffelexToken integer,
- ffelexToken decimal, ffelexToken fraction,
- ffelexToken exponent, ffelexToken exponent_sign,
- ffelexToken exponent_digits);
-#endif
-#if FFETARGET_okREAL7
-bool ffetarget_real7 (ffetargetReal7 *value, ffelexToken integer,
- ffelexToken decimal, ffelexToken fraction,
- ffelexToken exponent, ffelexToken exponent_sign,
- ffelexToken exponent_digits);
-#endif
-#if FFETARGET_okREAL8
-bool ffetarget_real8 (ffetargetReal8 *value, ffelexToken integer,
- ffelexToken decimal, ffelexToken fraction,
- ffelexToken exponent, ffelexToken exponent_sign,
- ffelexToken exponent_digits);
-#endif
bool ffetarget_typeless_binary (ffetargetTypeless *value, ffelexToken token);
bool ffetarget_typeless_octal (ffetargetTypeless *value, ffelexToken token);
bool ffetarget_typeless_hex (ffetargetTypeless *value, ffelexToken token);
@@ -794,9 +576,24 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len);
/* Define macros. */
-#define FFETARGET_REAL_VALUE_FROM_INT_(resr, lf, kt) \
- REAL_VALUE_FROM_INT (resr, (long) lf, (long) ((lf < 0) ? -1 : 0), \
- ((kt == 1) ? SFmode : DFmode))
+#define FFETARGET_REAL_VALUE_FROM_INT_(resr, lf, kt) \
+ REAL_VALUE_FROM_INT (resr, (HOST_WIDE_INT) lf, \
+ (HOST_WIDE_INT) ((lf < 0) ? -1 : 0), \
+ mode_for_size (kt == 1 ? 32 : 64, MODE_FLOAT, 0))
+
+#if HOST_BITS_PER_LONGLONG > HOST_BITS_PER_WIDE_INT
+#define FFETARGET_REAL_VALUE_FROM_LONGLONG_(resr, lf, kt) \
+ REAL_VALUE_FROM_INT (resr, (HOST_WIDE_INT) lf, \
+ (HOST_WIDE_INT) (lf >> HOST_BITS_PER_WIDE_INT), \
+ mode_for_size (kt == 1 ? 32 : 64, MODE_FLOAT, 0))
+#define FFETARGET_LONGLONG_FROM_INTS_(hi, lo) \
+ (((long long int) hi << HOST_BITS_PER_WIDE_INT) \
+ | (long long int) ((unsigned HOST_WIDE_INT) lo))
+#else
+#define FFETARGET_REAL_VALUE_FROM_LONGLONG_(resr, lf, kt) \
+ FFETARGET_REAL_VALUE_FROM_INT_ (resr, lf, kt)
+#define FFETARGET_LONGLONG_FROM_INTS_(hi, lo) lo
+#endif
#define ffetarget_add_complex1(res,l,r) \
({ REAL_VALUE_TYPE lr, li, rr, ri, resr, resi; \
@@ -899,7 +696,14 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len);
#define ffetarget_convert_complex1_integer1 ffetarget_convert_complex1_integer
#define ffetarget_convert_complex1_integer2 ffetarget_convert_complex1_integer
#define ffetarget_convert_complex1_integer3 ffetarget_convert_complex1_integer
-#define ffetarget_convert_complex1_integer4(res,l) FFEBAD_NOCANDO
+#define ffetarget_convert_complex1_integer4(res,l) \
+ ({ REAL_VALUE_TYPE resi, resr; \
+ ffetargetInteger4 lf = (l); \
+ FFETARGET_REAL_VALUE_FROM_LONGLONG_ (resr, lf, 1); \
+ resi = dconst0; \
+ ffetarget_cvt_rv_to_r1_ (resr, (res)->real); \
+ ffetarget_cvt_rv_to_r1_ (resi, (res)->imaginary); \
+ FFEBAD; })
#define ffetarget_convert_complex1_real1(res,l) \
((res)->real = (l), \
ffetarget_cvt_rv_to_r1_ (dconst0, (res)->imaginary), \
@@ -934,7 +738,14 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len);
#define ffetarget_convert_complex2_integer1 ffetarget_convert_complex2_integer
#define ffetarget_convert_complex2_integer2 ffetarget_convert_complex2_integer
#define ffetarget_convert_complex2_integer3 ffetarget_convert_complex2_integer
-#define ffetarget_convert_complex2_integer4(res,l) FFEBAD_NOCANDO
+#define ffetarget_convert_complex2_integer4(res,l) \
+ ({ REAL_VALUE_TYPE resi, resr; \
+ ffetargetInteger4 lf = (l); \
+ FFETARGET_REAL_VALUE_FROM_LONGLONG_ (resr, lf, 2); \
+ resi = dconst0; \
+ ffetarget_cvt_rv_to_r2_ (resr, &((res)->real.v[0])); \
+ ffetarget_cvt_rv_to_r2_ (resi, &((res)->imaginary.v[0])); \
+ FFEBAD; })
#define ffetarget_convert_complex2_real1(res,l) \
({ REAL_VALUE_TYPE lr; \
lr = ffetarget_cvt_r1_to_rv_ (l); \
@@ -997,8 +808,20 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len);
ffetarget_convert_integer1_typeless(res,l)
#define ffetarget_convert_integer4_character1(res,l) \
ffetarget_convert_integer1_character1(res,l)
-#define ffetarget_convert_integer4_complex1(res,l) FFEBAD_NOCANDO
-#define ffetarget_convert_integer4_complex2(res,l) FFEBAD_NOCANDO
+#define ffetarget_convert_integer4_complex1(res,l) \
+ ({ REAL_VALUE_TYPE lr; \
+ lr = ffetarget_cvt_r1_to_rv_ ((l).real); \
+ REAL_VALUE_TO_INT (&ffetarget_long_val_, &ffetarget_long_junk_, lr); \
+ *(res) = FFETARGET_LONGLONG_FROM_INTS_ (ffetarget_long_junk_, \
+ ffetarget_long_val_); \
+ FFEBAD; })
+#define ffetarget_convert_integer4_complex2(res,l) \
+ ({ REAL_VALUE_TYPE lr; \
+ lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \
+ REAL_VALUE_TO_INT (&ffetarget_long_val_, &ffetarget_long_junk_, lr); \
+ *(res) = FFETARGET_LONGLONG_FROM_INTS_ (ffetarget_long_junk_, \
+ ffetarget_long_val_); \
+ FFEBAD; })
#define ffetarget_convert_integer4_hollerith(res,l) \
ffetarget_convert_integer1_hollerith(res,l)
#define ffetarget_convert_integer4_integer1(res,l) (*(res) = (l), FFEBAD)
@@ -1012,8 +835,20 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len);
ffetarget_convert_integer1_logical1(res,l)
#define ffetarget_convert_integer4_logical4(res,l) \
ffetarget_convert_integer1_logical1(res,l)
-#define ffetarget_convert_integer4_real1(res,l) FFEBAD_NOCANDO
-#define ffetarget_convert_integer4_real2(res,l) FFEBAD_NOCANDO
+#define ffetarget_convert_integer4_real1(res,l) \
+ ({ REAL_VALUE_TYPE lr; \
+ lr = ffetarget_cvt_r1_to_rv_ (l); \
+ REAL_VALUE_TO_INT (&ffetarget_long_val_, &ffetarget_long_junk_, lr); \
+ *(res) = FFETARGET_LONGLONG_FROM_INTS_ (ffetarget_long_junk_, \
+ ffetarget_long_val_); \
+ FFEBAD; })
+#define ffetarget_convert_integer4_real2(res,l) \
+ ({ REAL_VALUE_TYPE lr; \
+ lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \
+ REAL_VALUE_TO_INT (&ffetarget_long_val_, &ffetarget_long_junk_, lr); \
+ *(res) = FFETARGET_LONGLONG_FROM_INTS_ (ffetarget_long_junk_, \
+ ffetarget_long_val_); \
+ FFEBAD; })
#define ffetarget_convert_integer4_typeless(res,l) \
ffetarget_convert_integer1_typeless(res,l)
#define ffetarget_convert_logical1_character1(res,l) \
@@ -1113,7 +948,12 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len);
ffetarget_convert_real1_integer1(res,l)
#define ffetarget_convert_real1_integer3(res,l) \
ffetarget_convert_real1_integer1(res,l)
-#define ffetarget_convert_real1_integer4(res,l) FFEBAD_NOCANDO
+#define ffetarget_convert_real1_integer4(res,l) \
+ ({ REAL_VALUE_TYPE resr; \
+ ffetargetInteger4 lf = (l); \
+ FFETARGET_REAL_VALUE_FROM_LONGLONG_ (resr, lf, 1); \
+ ffetarget_cvt_rv_to_r1_ (resr, *(res)); \
+ FFEBAD; })
#define ffetarget_convert_real1_typeless(res,l) \
ffetarget_convert_any_typeless_ ((char *) (res), sizeof(*(res)), l)
#define ffetarget_convert_real1_complex1(res,l) (*(res) = (l).real, FFEBAD)
@@ -1138,7 +978,12 @@ void *ffetarget_memcpy_ (void *dst, void *src, size_t len);
ffetarget_convert_real2_integer1(res,l)
#define ffetarget_convert_real2_integer3(res,l) \
ffetarget_convert_real2_integer1(res,l)
-#define ffetarget_convert_real2_integer4(res,l) FFEBAD_NOCANDO
+#define ffetarget_convert_real2_integer4(res,l) \
+ ({ REAL_VALUE_TYPE resr; \
+ ffetargetInteger4 lf = (l); \
+ FFETARGET_REAL_VALUE_FROM_LONGLONG_ (resr, lf, 2); \
+ ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \
+ FFEBAD; })
#define ffetarget_convert_real2_typeless(res,l) \
ffetarget_convert_any_typeless_ ((char *) (res), sizeof(*(res)), l)
#define ffetarget_convert_real2_complex1(res,l) \
diff --git a/contrib/gcc/f/top.c b/contrib/gcc/f/top.c
index 6a789e3ed01f..ce39dd09bf4c 100644
--- a/contrib/gcc/f/top.c
+++ b/contrib/gcc/f/top.c
@@ -1,5 +1,6 @@
/* top.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 1996, 1997, 1999, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 1997, 1999, 2001, 2003
+ Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -47,6 +48,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "lex.h"
#include "malloc.h"
#include "name.h"
+#include "options.h"
+#include "opts.h"
#include "src.h"
#include "st.h"
#include "storag.h"
@@ -138,14 +141,14 @@ bool ffe_in_4 = FALSE;
/* Static functions (internal). */
-static bool ffe_is_digit_string_ (char *s);
+static bool ffe_is_digit_string_ (const char *s);
/* Internal macros. */
static bool
-ffe_is_digit_string_ (char *s)
+ffe_is_digit_string_ (const char *s)
{
- char *p;
+ const char *p;
for (p = s; ISDIGIT (*p); ++p)
;
@@ -153,375 +156,449 @@ ffe_is_digit_string_ (char *s)
return (p != s) && (*p == '\0');
}
+/* Get ready for options handling. */
+unsigned int
+ffe_init_options (unsigned int argc ATTRIBUTE_UNUSED,
+ const char **argv ATTRIBUTE_UNUSED)
+{
+ /* Set default options for Fortran. */
+ flag_move_all_movables = 1;
+ flag_reduce_all_givs = 1;
+ flag_argument_noalias = 2;
+ flag_merge_constants = 2;
+ flag_errno_math = 0;
+ flag_complex_divide_method = 1;
+
+ return CL_F77;
+}
+
/* Handle command-line options. Returns 0 if unrecognized, 1 if
recognized and handled. */
-
int
-ffe_decode_option (argc, argv)
- int argc ATTRIBUTE_UNUSED;
- char **argv;
+ffe_handle_option (size_t scode, const char *arg, int value)
{
- char *opt = argv[0];
- if (opt[0] != '-')
- return 0;
- if (opt[1] == 'f')
+ enum opt_code code = (enum opt_code) scode;
+
+ switch (code)
{
- if (strcmp (&opt[2], "version") == 0)
- {
- ffe_set_is_version (TRUE);
- ffe_set_is_do_internal_checks (TRUE);
- }
- else if (strcmp (&opt[2], "f66") == 0)
- {
- ffe_set_is_onetrip (TRUE);
- ffe_set_is_ugly_assumed (TRUE);
- }
- else if (strcmp (&opt[2], "no-f66") == 0)
- {
- ffe_set_is_onetrip (FALSE);
- ffe_set_is_ugly_assumed (FALSE);
- }
- else if (strcmp (&opt[2], "f77") == 0)
- {
- ffe_set_is_backslash (TRUE);
- ffe_set_is_typeless_boz (FALSE);
- }
- else if (strcmp (&opt[2], "no-f77") == 0)
- {
- ffe_set_is_backslash (FALSE);
- }
- else if (strcmp (&opt[2], "f90") == 0)
- ffe_set_is_90 (TRUE);
- else if (strcmp (&opt[2], "no-f90") == 0)
- ffe_set_is_90 (FALSE);
- else if (strcmp (&opt[2], "automatic") == 0)
- ffe_set_is_automatic (TRUE);
- else if (strcmp (&opt[2], "no-automatic") == 0)
- ffe_set_is_automatic (FALSE);
- else if (strcmp (&opt[2], "dollar-ok") == 0)
- ffe_set_is_dollar_ok (TRUE);
- else if (strcmp (&opt[2], "no-dollar-ok") == 0)
- ffe_set_is_dollar_ok (FALSE);
- else if (strcmp (&opt[2], "f2c") == 0)
- ffe_set_is_f2c (TRUE);
- else if (strcmp (&opt[2], "no-f2c") == 0)
- ffe_set_is_f2c (FALSE);
- else if (strcmp (&opt[2], "f2c-library") == 0)
- ffe_set_is_f2c_library (TRUE);
- else if (strcmp (&opt[2], "no-f2c-library") == 0)
- ffe_set_is_f2c_library (FALSE);
- else if (strcmp (&opt[2], "flatten-arrays") == 0)
- ffe_set_is_flatten_arrays (TRUE);
- else if (strcmp (&opt[2], "no-flatten-arrays") == 0)
- ffe_set_is_flatten_arrays (FALSE);
- else if (strcmp (&opt[2], "free-form") == 0)
- ffe_set_is_free_form (TRUE);
- else if (strcmp (&opt[2], "no-free-form") == 0)
- ffe_set_is_free_form (FALSE);
- else if (strcmp (&opt[2], "fixed-form") == 0)
- {
- ffe_set_is_free_form (FALSE);
- return -1;
- }
- else if (strcmp (&opt[2], "no-fixed-form") == 0)
- ffe_set_is_free_form (TRUE);
- else if (strcmp (&opt[2], "pedantic") == 0)
- ffe_set_is_pedantic (TRUE);
- else if (strcmp (&opt[2], "no-pedantic") == 0)
- ffe_set_is_pedantic (FALSE);
- else if (strcmp (&opt[2], "vxt") == 0)
- ffe_set_is_vxt (TRUE);
- else if (strcmp (&opt[2], "not-vxt") == 0)
- ffe_set_is_vxt (FALSE);
- else if (strcmp (&opt[2], "vxt-not-f90") == 0)
- warning ("%s no longer supported -- try -fvxt", opt);
- else if (strcmp (&opt[2], "f90-not-vxt") == 0)
- warning ("%s no longer supported -- try -fno-vxt -ff90", opt);
- else if (strcmp (&opt[2], "no-ugly") == 0)
- {
- ffe_set_is_ugly_args (FALSE);
- ffe_set_is_ugly_assign (FALSE);
- ffe_set_is_ugly_assumed (FALSE);
- ffe_set_is_ugly_comma (FALSE);
- ffe_set_is_ugly_complex (FALSE);
- ffe_set_is_ugly_init (FALSE);
- ffe_set_is_ugly_logint (FALSE);
- }
- else if (strcmp (&opt[2], "ugly-args") == 0)
- ffe_set_is_ugly_args (TRUE);
- else if (strcmp (&opt[2], "no-ugly-args") == 0)
- ffe_set_is_ugly_args (FALSE);
- else if (strcmp (&opt[2], "ugly-assign") == 0)
- ffe_set_is_ugly_assign (TRUE);
- else if (strcmp (&opt[2], "no-ugly-assign") == 0)
- ffe_set_is_ugly_assign (FALSE);
- else if (strcmp (&opt[2], "ugly-assumed") == 0)
- ffe_set_is_ugly_assumed (TRUE);
- else if (strcmp (&opt[2], "no-ugly-assumed") == 0)
- ffe_set_is_ugly_assumed (FALSE);
- else if (strcmp (&opt[2], "ugly-comma") == 0)
- ffe_set_is_ugly_comma (TRUE);
- else if (strcmp (&opt[2], "no-ugly-comma") == 0)
- ffe_set_is_ugly_comma (FALSE);
- else if (strcmp (&opt[2], "ugly-complex") == 0)
- ffe_set_is_ugly_complex (TRUE);
- else if (strcmp (&opt[2], "no-ugly-complex") == 0)
- ffe_set_is_ugly_complex (FALSE);
- else if (strcmp (&opt[2], "ugly-init") == 0)
- ffe_set_is_ugly_init (TRUE);
- else if (strcmp (&opt[2], "no-ugly-init") == 0)
- ffe_set_is_ugly_init (FALSE);
- else if (strcmp (&opt[2], "ugly-logint") == 0)
- ffe_set_is_ugly_logint (TRUE);
- else if (strcmp (&opt[2], "no-ugly-logint") == 0)
- ffe_set_is_ugly_logint (FALSE);
- else if (strcmp (&opt[2], "xyzzy") == 0)
- ffe_set_is_ffedebug (TRUE);
- else if (strcmp (&opt[2], "no-xyzzy") == 0)
- ffe_set_is_ffedebug (FALSE);
- else if (strcmp (&opt[2], "init-local-zero") == 0)
- ffe_set_is_init_local_zero (TRUE);
- else if (strcmp (&opt[2], "no-init-local-zero") == 0)
- ffe_set_is_init_local_zero (FALSE);
- else if (strcmp (&opt[2], "emulate-complex") == 0)
- ffe_set_is_emulate_complex (TRUE);
- else if (strcmp (&opt[2], "no-emulate-complex") == 0)
- ffe_set_is_emulate_complex (FALSE);
- else if (strcmp (&opt[2], "backslash") == 0)
- ffe_set_is_backslash (TRUE);
- else if (strcmp (&opt[2], "no-backslash") == 0)
- ffe_set_is_backslash (FALSE);
- else if (strcmp (&opt[2], "underscoring") == 0)
- ffe_set_is_underscoring (TRUE);
- else if (strcmp (&opt[2], "no-underscoring") == 0)
- ffe_set_is_underscoring (FALSE);
- else if (strcmp (&opt[2], "second-underscore") == 0)
- ffe_set_is_second_underscore (TRUE);
- else if (strcmp (&opt[2], "no-second-underscore") == 0)
- ffe_set_is_second_underscore (FALSE);
- else if (strcmp (&opt[2], "zeros") == 0)
- ffe_set_is_zeros (TRUE);
- else if (strcmp (&opt[2], "no-zeros") == 0)
- ffe_set_is_zeros (FALSE);
- else if (strcmp (&opt[2], "debug-kludge") == 0)
- warning ("%s disabled, use normal debugging flags", opt);
- else if (strcmp (&opt[2], "no-debug-kludge") == 0)
- warning ("%s disabled, use normal debugging flags", opt);
- else if (strcmp (&opt[2], "onetrip") == 0)
- ffe_set_is_onetrip (TRUE);
- else if (strcmp (&opt[2], "no-onetrip") == 0)
- ffe_set_is_onetrip (FALSE);
- else if (strcmp (&opt[2], "silent") == 0)
- ffe_set_is_silent (TRUE);
- else if (strcmp (&opt[2], "no-silent") == 0)
- ffe_set_is_silent (FALSE);
- else if (strcmp (&opt[2], "globals") == 0)
- ffe_set_is_globals (TRUE);
- else if (strcmp (&opt[2], "no-globals") == 0)
- ffe_set_is_globals (FALSE);
- else if (strcmp (&opt[2], "fortran-bounds-check") == 0)
- flag_bounds_check = TRUE;
- else if (strcmp (&opt[2], "no-fortran-bounds-check") == 0)
- flag_bounds_check = FALSE;
- else if (strcmp (&opt[2], "typeless-boz") == 0)
- ffe_set_is_typeless_boz (TRUE);
- else if (strcmp (&opt[2], "no-typeless-boz") == 0)
+ default:
+ abort();
+
+ case OPT_fversion:
+ ffe_set_is_version (TRUE);
+ ffe_set_is_do_internal_checks (TRUE);
+ break;
+
+ case OPT_ff66:
+ ffe_set_is_onetrip (value);
+ ffe_set_is_ugly_assumed (value);
+ break;
+
+ case OPT_ff77:
+ ffe_set_is_backslash (value);
+ if (value)
ffe_set_is_typeless_boz (FALSE);
- else if (strcmp (&opt[2], "intrin-case-initcap") == 0)
- ffe_set_case_intrin (FFE_caseINITCAP);
- else if (strcmp (&opt[2], "intrin-case-upper") == 0)
- ffe_set_case_intrin (FFE_caseUPPER);
- else if (strcmp (&opt[2], "intrin-case-lower") == 0)
- ffe_set_case_intrin (FFE_caseLOWER);
- else if (strcmp (&opt[2], "intrin-case-any") == 0)
- ffe_set_case_intrin (FFE_caseNONE);
- else if (strcmp (&opt[2], "match-case-initcap") == 0)
- ffe_set_case_match (FFE_caseINITCAP);
- else if (strcmp (&opt[2], "match-case-upper") == 0)
- ffe_set_case_match (FFE_caseUPPER);
- else if (strcmp (&opt[2], "match-case-lower") == 0)
- ffe_set_case_match (FFE_caseLOWER);
- else if (strcmp (&opt[2], "match-case-any") == 0)
- ffe_set_case_match (FFE_caseNONE);
- else if (strcmp (&opt[2], "source-case-upper") == 0)
- ffe_set_case_source (FFE_caseUPPER);
- else if (strcmp (&opt[2], "source-case-lower") == 0)
- ffe_set_case_source (FFE_caseLOWER);
- else if (strcmp (&opt[2], "source-case-preserve") == 0)
- ffe_set_case_source (FFE_caseNONE);
- else if (strcmp (&opt[2], "symbol-case-initcap") == 0)
- ffe_set_case_symbol (FFE_caseINITCAP);
- else if (strcmp (&opt[2], "symbol-case-upper") == 0)
- ffe_set_case_symbol (FFE_caseUPPER);
- else if (strcmp (&opt[2], "symbol-case-lower") == 0)
- ffe_set_case_symbol (FFE_caseLOWER);
- else if (strcmp (&opt[2], "symbol-case-any") == 0)
- ffe_set_case_symbol (FFE_caseNONE);
- else if (strcmp (&opt[2], "case-strict-upper") == 0)
- {
- ffe_set_case_intrin (FFE_caseUPPER);
- ffe_set_case_match (FFE_caseUPPER);
- ffe_set_case_source (FFE_caseNONE);
- ffe_set_case_symbol (FFE_caseUPPER);
- }
- else if (strcmp (&opt[2], "case-strict-lower") == 0)
- {
- ffe_set_case_intrin (FFE_caseLOWER);
- ffe_set_case_match (FFE_caseLOWER);
- ffe_set_case_source (FFE_caseNONE);
- ffe_set_case_symbol (FFE_caseLOWER);
- }
- else if (strcmp (&opt[2], "case-initcap") == 0)
- {
- ffe_set_case_intrin (FFE_caseINITCAP);
- ffe_set_case_match (FFE_caseINITCAP);
- ffe_set_case_source (FFE_caseNONE);
- ffe_set_case_symbol (FFE_caseINITCAP);
- }
- else if (strcmp (&opt[2], "case-upper") == 0)
- {
- ffe_set_case_intrin (FFE_caseNONE);
- ffe_set_case_match (FFE_caseNONE);
- ffe_set_case_source (FFE_caseUPPER);
- ffe_set_case_symbol (FFE_caseNONE);
- }
- else if (strcmp (&opt[2], "case-lower") == 0)
- {
- ffe_set_case_intrin (FFE_caseNONE);
- ffe_set_case_match (FFE_caseNONE);
- ffe_set_case_source (FFE_caseLOWER);
- ffe_set_case_symbol (FFE_caseNONE);
- }
- else if (strcmp (&opt[2], "case-preserve") == 0)
- {
- ffe_set_case_intrin (FFE_caseNONE);
- ffe_set_case_match (FFE_caseNONE);
- ffe_set_case_source (FFE_caseNONE);
- ffe_set_case_symbol (FFE_caseNONE);
- }
- else if (strcmp (&opt[2], "badu77-intrinsics-delete") == 0)
- ffe_set_intrinsic_state_badu77 (FFE_intrinsicstateDELETED);
- else if (strcmp (&opt[2], "badu77-intrinsics-hide") == 0)
- ffe_set_intrinsic_state_badu77 (FFE_intrinsicstateHIDDEN);
- else if (strcmp (&opt[2], "badu77-intrinsics-disable") == 0)
- ffe_set_intrinsic_state_badu77 (FFE_intrinsicstateDISABLED);
- else if (strcmp (&opt[2], "badu77-intrinsics-enable") == 0)
- ffe_set_intrinsic_state_badu77 (FFE_intrinsicstateENABLED);
- else if (strcmp (&opt[2], "gnu-intrinsics-delete") == 0)
- ffe_set_intrinsic_state_gnu (FFE_intrinsicstateDELETED);
- else if (strcmp (&opt[2], "gnu-intrinsics-hide") == 0)
- ffe_set_intrinsic_state_gnu (FFE_intrinsicstateHIDDEN);
- else if (strcmp (&opt[2], "gnu-intrinsics-disable") == 0)
- ffe_set_intrinsic_state_gnu (FFE_intrinsicstateDISABLED);
- else if (strcmp (&opt[2], "gnu-intrinsics-enable") == 0)
- ffe_set_intrinsic_state_gnu (FFE_intrinsicstateENABLED);
- else if (strcmp (&opt[2], "f2c-intrinsics-delete") == 0)
- ffe_set_intrinsic_state_f2c (FFE_intrinsicstateDELETED);
- else if (strcmp (&opt[2], "f2c-intrinsics-hide") == 0)
- ffe_set_intrinsic_state_f2c (FFE_intrinsicstateHIDDEN);
- else if (strcmp (&opt[2], "f2c-intrinsics-disable") == 0)
- ffe_set_intrinsic_state_f2c (FFE_intrinsicstateDISABLED);
- else if (strcmp (&opt[2], "f2c-intrinsics-enable") == 0)
- ffe_set_intrinsic_state_f2c (FFE_intrinsicstateENABLED);
- else if (strcmp (&opt[2], "f90-intrinsics-delete") == 0)
- ffe_set_intrinsic_state_f90 (FFE_intrinsicstateDELETED);
- else if (strcmp (&opt[2], "f90-intrinsics-hide") == 0)
- ffe_set_intrinsic_state_f90 (FFE_intrinsicstateHIDDEN);
- else if (strcmp (&opt[2], "f90-intrinsics-disable") == 0)
- ffe_set_intrinsic_state_f90 (FFE_intrinsicstateDISABLED);
- else if (strcmp (&opt[2], "f90-intrinsics-enable") == 0)
- ffe_set_intrinsic_state_f90 (FFE_intrinsicstateENABLED);
- else if (strcmp (&opt[2], "mil-intrinsics-delete") == 0)
- ffe_set_intrinsic_state_mil (FFE_intrinsicstateDELETED);
- else if (strcmp (&opt[2], "mil-intrinsics-hide") == 0)
- ffe_set_intrinsic_state_mil (FFE_intrinsicstateHIDDEN);
- else if (strcmp (&opt[2], "mil-intrinsics-disable") == 0)
- ffe_set_intrinsic_state_mil (FFE_intrinsicstateDISABLED);
- else if (strcmp (&opt[2], "mil-intrinsics-enable") == 0)
- ffe_set_intrinsic_state_mil (FFE_intrinsicstateENABLED);
- else if (strcmp (&opt[2], "unix-intrinsics-delete") == 0)
- ffe_set_intrinsic_state_unix (FFE_intrinsicstateDELETED);
- else if (strcmp (&opt[2], "unix-intrinsics-hide") == 0)
- ffe_set_intrinsic_state_unix (FFE_intrinsicstateHIDDEN);
- else if (strcmp (&opt[2], "unix-intrinsics-disable") == 0)
- ffe_set_intrinsic_state_unix (FFE_intrinsicstateDISABLED);
- else if (strcmp (&opt[2], "unix-intrinsics-enable") == 0)
- ffe_set_intrinsic_state_unix (FFE_intrinsicstateENABLED);
- else if (strcmp (&opt[2], "vxt-intrinsics-delete") == 0)
- ffe_set_intrinsic_state_vxt (FFE_intrinsicstateDELETED);
- else if (strcmp (&opt[2], "vxt-intrinsics-hide") == 0)
- ffe_set_intrinsic_state_vxt (FFE_intrinsicstateHIDDEN);
- else if (strcmp (&opt[2], "vxt-intrinsics-disable") == 0)
- ffe_set_intrinsic_state_vxt (FFE_intrinsicstateDISABLED);
- else if (strcmp (&opt[2], "vxt-intrinsics-enable") == 0)
- ffe_set_intrinsic_state_vxt (FFE_intrinsicstateENABLED);
- else if (strncmp (&opt[2], "fixed-line-length-",
- strlen ("fixed-line-length-")) == 0)
- {
- char *len = &opt[2] + strlen ("fixed-line-length-");
-
- if (strcmp (len, "none") == 0)
- {
- ffe_set_fixed_line_length (0);
- return -1;
- }
- else if (ffe_is_digit_string_ (len))
- {
- ffe_set_fixed_line_length (atol (len));
- return -1;
- }
- else
- return 0;
- }
+ break;
+
+ case OPT_ff90:
+ ffe_set_is_90 (value);
+ break;
+
+ case OPT_fautomatic:
+ ffe_set_is_automatic (value);
+ break;
+
+ case OPT_fdollar_ok:
+ ffe_set_is_dollar_ok (value);
+ break;
+
+ case OPT_ff2c:
+ ffe_set_is_f2c (value);
+ break;
+
+ case OPT_ff2c_library:
+ ffe_set_is_f2c_library (value);
+ break;
+
+ case OPT_fflatten_arrays:
+ ffe_set_is_f2c_library (value);
+ break;
+
+ case OPT_ffree_form:
+ ffe_set_is_free_form (value);
+ break;
+
+ case OPT_ffixed_form:
+ ffe_set_is_free_form (!value);
+ break;
+
+ case OPT_fpedantic:
+ ffe_set_is_pedantic (value);
+ break;
+
+ case OPT_fvxt:
+ ffe_set_is_vxt (value);
+ break;
+
+ case OPT_fvxt_not_f90:
+ warning ("-fvxt-not-f90 no longer supported -- try -fvxt");
+ break;
+
+ case OPT_ff90_not_vxt:
+ warning ("-ff90-not-vxt no longer supported -- try -fno-vxt -ff90");
+ break;
+
+ case OPT_fugly:
+ ffe_set_is_ugly_args (value);
+ ffe_set_is_ugly_assign (value);
+ ffe_set_is_ugly_assumed (value);
+ ffe_set_is_ugly_comma (value);
+ ffe_set_is_ugly_complex (value);
+ ffe_set_is_ugly_init (value);
+ ffe_set_is_ugly_logint (value);
+ break;
+
+ case OPT_fugly_args:
+ ffe_set_is_ugly_args (value);
+ break;
+
+ case OPT_fugly_assign:
+ ffe_set_is_ugly_assign (value);
+ break;
+
+ case OPT_fugly_assumed:
+ ffe_set_is_ugly_assumed (value);
+ break;
+
+ case OPT_fugly_comma:
+ ffe_set_is_ugly_comma (value);
+ break;
+
+ case OPT_fugly_complex:
+ ffe_set_is_ugly_complex (value);
+ break;
+
+ case OPT_fugly_init:
+ ffe_set_is_ugly_init (value);
+ break;
+
+ case OPT_fugly_logint:
+ ffe_set_is_ugly_logint (value);
+ break;
+
+ case OPT_fxyzzy:
+ ffe_set_is_ffedebug (value);
+ break;
+
+ case OPT_finit_local_zero:
+ ffe_set_is_init_local_zero (value);
+ break;
+
+ case OPT_femulate_complex:
+ ffe_set_is_emulate_complex (value);
+ break;
+
+ case OPT_fbackslash:
+ ffe_set_is_backslash (value);
+ break;
+
+ case OPT_funderscoring:
+ ffe_set_is_underscoring (value);
+ break;
+
+ case OPT_fsecond_underscore:
+ ffe_set_is_second_underscore (value);
+ break;
+
+ case OPT_fzeros:
+ ffe_set_is_zeros (value);
+ break;
+
+ case OPT_fdebug_kludge:
+ warning ("-fdebug-kludge is disabled, use normal debugging flags");
+ break;
+
+ case OPT_fonetrip:
+ ffe_set_is_onetrip (value);
+ break;
+
+ case OPT_fsilent:
+ ffe_set_is_silent (value);
+ break;
+
+ case OPT_fglobals:
+ ffe_set_is_globals (value);
+ break;
+
+ case OPT_ffortran_bounds_check:
+ flag_bounds_check = value;
+ break;
+
+ case OPT_ftypeless_boz:
+ ffe_set_is_typeless_boz (value);
+ break;
+
+ case OPT_fintrin_case_initcap:
+ ffe_set_case_intrin (FFE_caseINITCAP);
+ break;
+
+ case OPT_fintrin_case_lower:
+ ffe_set_case_intrin (FFE_caseLOWER);
+ break;
+
+ case OPT_fintrin_case_upper:
+ ffe_set_case_intrin (FFE_caseUPPER);
+ break;
+
+ case OPT_fintrin_case_any:
+ ffe_set_case_intrin (FFE_caseNONE);
+ break;
+
+ case OPT_fmatch_case_initcap:
+ ffe_set_case_match (FFE_caseINITCAP);
+ break;
+
+ case OPT_fmatch_case_lower:
+ ffe_set_case_match (FFE_caseLOWER);
+ break;
+
+ case OPT_fmatch_case_upper:
+ ffe_set_case_match (FFE_caseUPPER);
+ break;
+
+ case OPT_fmatch_case_any:
+ ffe_set_case_match (FFE_caseNONE);
+ break;
+
+ case OPT_fsource_case_lower:
+ ffe_set_case_source (FFE_caseLOWER);
+ break;
+
+ case OPT_fsource_case_preserve:
+ ffe_set_case_match (FFE_caseNONE);
+ break;
+
+ case OPT_fsource_case_upper:
+ ffe_set_case_source (FFE_caseUPPER);
+ break;
+
+ case OPT_fsymbol_case_initcap:
+ ffe_set_case_symbol (FFE_caseINITCAP);
+ break;
+
+ case OPT_fsymbol_case_lower:
+ ffe_set_case_symbol (FFE_caseLOWER);
+ break;
+
+ case OPT_fsymbol_case_upper:
+ ffe_set_case_symbol (FFE_caseUPPER);
+ break;
+
+ case OPT_fsymbol_case_any:
+ ffe_set_case_symbol (FFE_caseNONE);
+ break;
+
+ case OPT_fcase_strict_upper:
+ ffe_set_case_intrin (FFE_caseUPPER);
+ ffe_set_case_match (FFE_caseUPPER);
+ ffe_set_case_source (FFE_caseNONE);
+ ffe_set_case_symbol (FFE_caseUPPER);
+ break;
+
+ case OPT_fcase_strict_lower:
+ ffe_set_case_intrin (FFE_caseLOWER);
+ ffe_set_case_match (FFE_caseLOWER);
+ ffe_set_case_source (FFE_caseNONE);
+ ffe_set_case_symbol (FFE_caseLOWER);
+ break;
+
+ case OPT_fcase_initcap:
+ ffe_set_case_intrin (FFE_caseINITCAP);
+ ffe_set_case_match (FFE_caseINITCAP);
+ ffe_set_case_source (FFE_caseNONE);
+ ffe_set_case_symbol (FFE_caseINITCAP);
+ break;
+
+ case OPT_fcase_upper:
+ ffe_set_case_intrin (FFE_caseNONE);
+ ffe_set_case_match (FFE_caseNONE);
+ ffe_set_case_source (FFE_caseUPPER);
+ ffe_set_case_symbol (FFE_caseNONE);
+ break;
+
+ case OPT_fcase_lower:
+ ffe_set_case_intrin (FFE_caseNONE);
+ ffe_set_case_match (FFE_caseNONE);
+ ffe_set_case_source (FFE_caseLOWER);
+ ffe_set_case_symbol (FFE_caseNONE);
+ break;
+
+ case OPT_fcase_preserve:
+ ffe_set_case_intrin (FFE_caseNONE);
+ ffe_set_case_match (FFE_caseNONE);
+ ffe_set_case_source (FFE_caseNONE);
+ ffe_set_case_symbol (FFE_caseNONE);
+ break;
+
+ case OPT_fbadu77_intrinsics_delete:
+ ffe_set_intrinsic_state_badu77 (FFE_intrinsicstateDELETED);
+ break;
+
+ case OPT_fbadu77_intrinsics_hide:
+ ffe_set_intrinsic_state_badu77 (FFE_intrinsicstateHIDDEN);
+ break;
+
+ case OPT_fbadu77_intrinsics_disable:
+ ffe_set_intrinsic_state_badu77 (FFE_intrinsicstateDISABLED);
+ break;
+
+ case OPT_fbadu77_intrinsics_enable:
+ ffe_set_intrinsic_state_badu77 (FFE_intrinsicstateENABLED);
+ break;
+
+ case OPT_fgnu_intrinsics_delete:
+ ffe_set_intrinsic_state_gnu (FFE_intrinsicstateDELETED);
+ break;
+
+ case OPT_fgnu_intrinsics_hide:
+ ffe_set_intrinsic_state_gnu (FFE_intrinsicstateHIDDEN);
+ break;
+
+ case OPT_fgnu_intrinsics_disable:
+ ffe_set_intrinsic_state_gnu (FFE_intrinsicstateDISABLED);
+ break;
+
+ case OPT_fgnu_intrinsics_enable:
+ ffe_set_intrinsic_state_gnu (FFE_intrinsicstateENABLED);
+ break;
+
+ case OPT_ff2c_intrinsics_delete:
+ ffe_set_intrinsic_state_f2c (FFE_intrinsicstateDELETED);
+ break;
+
+ case OPT_ff2c_intrinsics_hide:
+ ffe_set_intrinsic_state_f2c (FFE_intrinsicstateHIDDEN);
+ break;
+
+ case OPT_ff2c_intrinsics_disable:
+ ffe_set_intrinsic_state_f2c (FFE_intrinsicstateDISABLED);
+ break;
+
+ case OPT_ff2c_intrinsics_enable:
+ ffe_set_intrinsic_state_f2c (FFE_intrinsicstateENABLED);
+ break;
+
+ case OPT_ff90_intrinsics_delete:
+ ffe_set_intrinsic_state_f90 (FFE_intrinsicstateDELETED);
+ break;
+
+ case OPT_ff90_intrinsics_hide:
+ ffe_set_intrinsic_state_f90 (FFE_intrinsicstateHIDDEN);
+ break;
+
+ case OPT_ff90_intrinsics_disable:
+ ffe_set_intrinsic_state_f90 (FFE_intrinsicstateDISABLED);
+ break;
+
+ case OPT_ff90_intrinsics_enable:
+ ffe_set_intrinsic_state_f90 (FFE_intrinsicstateENABLED);
+ break;
+
+ case OPT_fmil_intrinsics_delete:
+ ffe_set_intrinsic_state_mil (FFE_intrinsicstateDELETED);
+ break;
+
+ case OPT_fmil_intrinsics_hide:
+ ffe_set_intrinsic_state_mil (FFE_intrinsicstateHIDDEN);
+ break;
+
+ case OPT_fmil_intrinsics_disable:
+ ffe_set_intrinsic_state_mil (FFE_intrinsicstateDISABLED);
+ break;
+
+ case OPT_fmil_intrinsics_enable:
+ ffe_set_intrinsic_state_mil (FFE_intrinsicstateENABLED);
+ break;
+
+ case OPT_funix_intrinsics_delete:
+ ffe_set_intrinsic_state_unix (FFE_intrinsicstateDELETED);
+ break;
+
+ case OPT_funix_intrinsics_hide:
+ ffe_set_intrinsic_state_unix (FFE_intrinsicstateHIDDEN);
+ break;
+
+ case OPT_funix_intrinsics_disable:
+ ffe_set_intrinsic_state_unix (FFE_intrinsicstateDISABLED);
+ break;
+
+ case OPT_funix_intrinsics_enable:
+ ffe_set_intrinsic_state_unix (FFE_intrinsicstateENABLED);
+ break;
+
+ case OPT_fvxt_intrinsics_delete:
+ ffe_set_intrinsic_state_vxt (FFE_intrinsicstateDELETED);
+ break;
+
+ case OPT_fvxt_intrinsics_hide:
+ ffe_set_intrinsic_state_vxt (FFE_intrinsicstateHIDDEN);
+ break;
+
+ case OPT_fvxt_intrinsics_disable:
+ ffe_set_intrinsic_state_vxt (FFE_intrinsicstateDISABLED);
+ break;
+
+ case OPT_fvxt_intrinsics_enable:
+ ffe_set_intrinsic_state_vxt (FFE_intrinsicstateENABLED);
+ break;
+
+ case OPT_ffixed_line_length_:
+ if (strcmp (arg, "none") == 0)
+ ffe_set_fixed_line_length (0);
+ else if (ffe_is_digit_string_ (arg))
+ ffe_set_fixed_line_length (atol (arg));
else
return 0;
- }
- else if (opt[1] == 'W')
- {
- if (!strcmp (&opt[2], "comment"))
- ; /* cpp handles this one. */
- else if (!strcmp (&opt[2], "no-comment"))
- ; /* cpp handles this one. */
- else if (!strcmp (&opt[2], "comments"))
- ; /* cpp handles this one. */
- else if (!strcmp (&opt[2], "no-comments"))
- ; /* cpp handles this one. */
- else if (!strcmp (&opt[2], "trigraphs"))
- ; /* cpp handles this one. */
- else if (!strcmp (&opt[2], "no-trigraphs"))
- ; /* cpp handles this one. */
- else if (!strcmp (&opt[2], "import"))
- ; /* cpp handles this one. */
- else if (!strcmp (&opt[2], "no-import"))
- ; /* cpp handles this one. */
- else if (!strcmp (&opt[2], "globals"))
- ffe_set_is_warn_globals (TRUE);
- else if (!strcmp (&opt[2], "no-globals"))
- ffe_set_is_warn_globals (FALSE);
- else if (!strcmp (&opt[2], "implicit"))
- ffe_set_is_warn_implicit (TRUE);
- else if (!strcmp (&opt[2], "no-implicit"))
- ffe_set_is_warn_implicit (FALSE);
- else if (!strcmp (&opt[2], "surprising"))
- ffe_set_is_warn_surprising (TRUE);
- else if (!strcmp (&opt[2], "no-surprising"))
- ffe_set_is_warn_surprising (FALSE);
- else if (!strcmp (&opt[2], "all"))
+ break;
+
+ case OPT_Wcomment:
+ case OPT_Wcomments:
+ case OPT_Wimport:
+ case OPT_Wtrigraphs:
+ case OPT_fpreprocessed:
+ /* These are for cpp. */
+ break;
+
+ case OPT_Wglobals:
+ ffe_set_is_warn_globals (value);
+ break;
+
+ case OPT_Wimplicit:
+ ffe_set_is_warn_implicit (value);
+ break;
+
+ case OPT_Wsurprising:
+ ffe_set_is_warn_surprising (value);
+ break;
+
+ case OPT_Wall:
+ set_Wunused (value);
+ /* We save the value of warn_uninitialized, since if they put
+ -Wuninitialized on the command line, we need to generate a
+ warning about not using it without also specifying -O. */
+ if (value)
{
- /* We save the value of warn_uninitialized, since if they put
- -Wuninitialized on the command line, we need to generate a
- warning about not using it without also specifying -O. */
if (warn_uninitialized != 1)
warn_uninitialized = 2;
- set_Wunused (1);
}
else
- return 0;
+ warn_uninitialized = 0;
+ break;
+
+ case OPT_I:
+ ffecom_decode_include_option (arg);
+ break;
}
- else if (opt[1] == 'I')
- return ffecom_decode_include_option (&opt[2]);
- else
- return 0;
return 1;
}
@@ -553,7 +630,7 @@ ffe_file (ffewhereFile wf, FILE *f)
Performs per-image invocation. */
void
-ffe_init_0 ()
+ffe_init_0 (void)
{
++ffe_count_0;
ffe_in_0 = TRUE;
@@ -588,7 +665,7 @@ ffe_init_0 ()
Performs per-source-file invocation (not including INCLUDEd files). */
void
-ffe_init_1 ()
+ffe_init_1 (void)
{
++ffe_count_1;
ffe_in_1 = TRUE;
@@ -628,7 +705,7 @@ ffe_init_1 ()
Performs per-program-unit invocation. */
void
-ffe_init_2 ()
+ffe_init_2 (void)
{
++ffe_count_2;
ffe_in_2 = TRUE;
@@ -672,7 +749,7 @@ ffe_init_2 ()
of inits, from 0-3, breaks here; level 4 must be invoked independently). */
void
-ffe_init_3 ()
+ffe_init_3 (void)
{
++ffe_count_3;
ffe_in_3 = TRUE;
@@ -708,7 +785,7 @@ ffe_init_3 ()
ffe_init_4(); */
void
-ffe_init_4 ()
+ffe_init_4 (void)
{
++ffe_count_4;
ffe_in_4 = TRUE;
@@ -741,7 +818,7 @@ ffe_init_4 ()
ffe_terminate_0(); */
void
-ffe_terminate_0 ()
+ffe_terminate_0 (void)
{
ffe_count_1 = 0;
ffe_in_0 = FALSE;
@@ -774,7 +851,7 @@ ffe_terminate_0 ()
ffe_terminate_1(); */
void
-ffe_terminate_1 ()
+ffe_terminate_1 (void)
{
ffe_count_2 = 0;
ffe_in_1 = FALSE;
@@ -813,7 +890,7 @@ ffe_terminate_1 ()
ffe_terminate_2(); */
void
-ffe_terminate_2 ()
+ffe_terminate_2 (void)
{
ffe_count_3 = 0;
ffe_in_2 = FALSE;
@@ -852,7 +929,7 @@ ffe_terminate_2 ()
ffe_terminate_3(); */
void
-ffe_terminate_3 ()
+ffe_terminate_3 (void)
{
ffe_count_4 = 0;
ffe_in_3 = FALSE;
@@ -889,7 +966,7 @@ ffe_terminate_3 ()
ffe_terminate_4(); */
void
-ffe_terminate_4 ()
+ffe_terminate_4 (void)
{
ffe_in_4 = FALSE;
diff --git a/contrib/gcc/f/top.h b/contrib/gcc/f/top.h
index 3159b511fee8..5538ab8db134 100644
--- a/contrib/gcc/f/top.h
+++ b/contrib/gcc/f/top.h
@@ -141,7 +141,8 @@ extern bool ffe_in_4;
/* Declare functions with prototypes. */
-int ffe_decode_option (int argc, char **argv);
+unsigned int ffe_init_options (unsigned int, const char **);
+int ffe_handle_option (size_t code, const char *arg, int on);
void ffe_file (ffewhereFile wf, FILE *f);
void ffe_init_0 (void);
void ffe_init_1 (void);
diff --git a/contrib/gcc/f/type.c b/contrib/gcc/f/type.c
index 7625cbbaa0ea..d25ab50f4c2a 100644
--- a/contrib/gcc/f/type.c
+++ b/contrib/gcc/f/type.c
@@ -53,8 +53,7 @@ ffetype_new (void)
{
ffetype type;
- type = (ffetype) malloc_new_kp (malloc_pool_image (), "ffetype",
- sizeof (*type));
+ type = malloc_new_kp (malloc_pool_image (), "ffetype", sizeof (*type));
type->kinds_ = NULL;
type->stars_ = NULL;
type->alignment_ = 0;
@@ -74,9 +73,8 @@ ffetype_set_kind (ffetype base_type, int kind, ffetype type)
int i;
base_type->kinds_
- = (ffetype_indexes_) malloc_new_kp (malloc_pool_image (),
- "ffetype_indexes_[kinds]",
- sizeof (*(base_type->kinds_)));
+ = malloc_new_kp (malloc_pool_image (), "ffetype_indexes_[kinds]",
+ sizeof (*(base_type->kinds_)));
for (i = 0; ((size_t) i) < ARRAY_SIZE (base_type->kinds_->type_); ++i)
base_type->kinds_->type_[i] = NULL;
}
@@ -94,9 +92,8 @@ ffetype_set_star (ffetype base_type, int star, ffetype type)
int i;
base_type->stars_
- = (ffetype_indexes_) malloc_new_kp (malloc_pool_image (),
- "ffetype_indexes_[stars]",
- sizeof (*(base_type->stars_)));
+ = malloc_new_kp (malloc_pool_image (), "ffetype_indexes_[stars]",
+ sizeof (*(base_type->stars_)));
for (i = 0; ((size_t) i) < ARRAY_SIZE (base_type->stars_->type_); ++i)
base_type->stars_->type_[i] = NULL;
}
diff --git a/contrib/gcc/f/where.c b/contrib/gcc/f/where.c
index b16f965721e2..b409a4681f52 100644
--- a/contrib/gcc/f/where.c
+++ b/contrib/gcc/f/where.c
@@ -1,5 +1,5 @@
/* where.c -- Implementation File (module.c template V1.0)
- Copyright (C) 1995, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2002, 2003 Free Software Foundation, Inc.
Contributed by James Craig Burley.
This file is part of GNU Fortran.
@@ -161,7 +161,7 @@ ffewhere_file_set (ffewhereFile wf, bool have_num, ffewhereLineNumber ln)
/* Do initializations. */
void
-ffewhere_init_1 ()
+ffewhere_init_1 (void)
{
ffewhere_root_line_.first = ffewhere_root_line_.last
= (ffewhereLine) &ffewhere_root_line_.first;
diff --git a/contrib/gcc/fibheap.c b/contrib/gcc/fibheap.c
index 36062d451a23..bcecf80251f2 100644
--- a/contrib/gcc/fibheap.c
+++ b/contrib/gcc/fibheap.c
@@ -218,7 +218,7 @@ fibheap_replace_key_data (heap, node, key, data)
void *data;
{
void *odata;
- int okey;
+ fibheapkey_t okey;
fibnode_t y;
/* If we wanted to, we could actually do a real increase by redeleting and
diff --git a/contrib/gcc/fibheap.h b/contrib/gcc/fibheap.h
index fc37f9ef635e..4eebaf13ba6f 100644
--- a/contrib/gcc/fibheap.h
+++ b/contrib/gcc/fibheap.h
@@ -59,8 +59,13 @@ typedef struct fibnode
struct fibnode *right;
fibheapkey_t key;
void *data;
+#ifdef __GNUC__
+ __extension__ unsigned long int degree : 31;
+ __extension__ unsigned long int mark : 1;
+#else
unsigned int degree : 31;
unsigned int mark : 1;
+#endif
} *fibnode_t;
extern fibheap_t fibheap_new PARAMS ((void));
diff --git a/contrib/gcc/filenames.h b/contrib/gcc/filenames.h
new file mode 100644
index 000000000000..ca9e2732a326
--- /dev/null
+++ b/contrib/gcc/filenames.h
@@ -0,0 +1,51 @@
+/* Macros for taking apart, interpreting and processing file names.
+
+ These are here because some non-Posix (a.k.a. DOSish) systems have
+ drive letter brain-damage at the beginning of an absolute file name,
+ use forward- and back-slash in path names interchangeably, and
+ some of them have case-insensitive file names.
+
+ Copyright 2000, 2001 Free Software Foundation, Inc.
+
+This file is part of BFD, the Binary File Descriptor library.
+
+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 2 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, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef FILENAMES_H
+#define FILENAMES_H
+
+#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__)
+
+#ifndef HAVE_DOS_BASED_FILE_SYSTEM
+#define HAVE_DOS_BASED_FILE_SYSTEM 1
+#endif
+
+#define IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\')
+/* Note that IS_ABSOLUTE_PATH accepts d:foo as well, although it is
+ only semi-absolute. This is because the users of IS_ABSOLUTE_PATH
+ want to know whether to prepend the current working directory to
+ a file name, which should not be done with a name like d:foo. */
+#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]) || (((f)[0]) && ((f)[1] == ':')))
+#define FILENAME_CMP(s1, s2) strcasecmp(s1, s2)
+
+#else /* not DOSish */
+
+#define IS_DIR_SEPARATOR(c) ((c) == '/')
+#define IS_ABSOLUTE_PATH(f) (IS_DIR_SEPARATOR((f)[0]))
+#define FILENAME_CMP(s1, s2) strcmp(s1, s2)
+
+#endif /* not DOSish */
+
+#endif /* FILENAMES_H */
diff --git a/contrib/gcc/final.c b/contrib/gcc/final.c
index 94a0f4c53a4b..dd5b64ec53f5 100644
--- a/contrib/gcc/final.c
+++ b/contrib/gcc/final.c
@@ -1,6 +1,6 @@
/* Convert RTL to assembler code and output it, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -46,6 +46,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
@@ -68,7 +70,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "target.h"
#include "debug.h"
#include "expr.h"
-#include "profile.h"
#include "cfglayout.h"
#ifdef XCOFF_DEBUGGING_INFO
@@ -80,6 +81,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "dwarf2out.h"
#endif
+#ifdef DBX_DEBUGGING_INFO
+#include "dbxout.h"
+#endif
+
/* If we aren't using cc0, CC_STATUS_INIT shouldn't exist. So define a
null default for it to save conditionalization later. */
#ifndef CC_STATUS_INIT
@@ -106,6 +111,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define HAVE_READONLY_DATA_SECTION 0
#endif
+/* Bitflags used by final_scan_insn. */
+#define SEEN_BB 1
+#define SEEN_NOTE 2
+#define SEEN_EMITTED 4
+
/* Last insn processed by final_scan_insn. */
static rtx debug_insn;
rtx current_output_insn;
@@ -136,10 +146,6 @@ static unsigned int insn_noperands;
static rtx last_ignored_compare = 0;
-/* Flag indicating this insn is the start of a new basic block. */
-
-static int new_block = 1;
-
/* Assign a unique number to each insn that is output.
This can be used to generate unique local labels. */
@@ -169,9 +175,15 @@ CC_STATUS cc_prev_status;
char regs_ever_live[FIRST_PSEUDO_REGISTER];
+/* Like regs_ever_live, but 1 if a reg is set or clobbered from an asm.
+ Unlike regs_ever_live, elements of this array corresponding to
+ eliminable regs like the frame pointer are set if an asm sets them. */
+
+char regs_asm_clobbered[FIRST_PSEUDO_REGISTER];
+
/* Nonzero means current function must be given a frame pointer.
- Set in stmt.c if anything is allocated on the stack there.
- Set in reload1.c if anything is allocated on the stack there. */
+ Initialized in function.c to 0. Set only in reload1.c as per
+ the needs of the function. */
int frame_pointer_needed;
@@ -194,56 +206,40 @@ rtx final_sequence;
static int dialect_number;
#endif
-/* Indexed by line number, nonzero if there is a note for that line. */
-
-static char *line_note_exists;
-
#ifdef HAVE_conditional_execution
/* Nonnull if the insn currently being emitted was a COND_EXEC pattern. */
rtx current_insn_predicate;
#endif
-struct function_list
-{
- struct function_list *next; /* next function */
- const char *name; /* function name */
- long cfg_checksum; /* function checksum */
- long count_edges; /* number of intrumented edges in this function */
-};
-
-static struct function_list *functions_head = 0;
-static struct function_list **functions_tail = &functions_head;
-
#ifdef HAVE_ATTR_length
-static int asm_insn_count PARAMS ((rtx));
-#endif
-static void profile_function PARAMS ((FILE *));
-static void profile_after_prologue PARAMS ((FILE *));
-static void notice_source_line PARAMS ((rtx));
-static rtx walk_alter_subreg PARAMS ((rtx *));
-static void output_asm_name PARAMS ((void));
-static void output_alternate_entry_point PARAMS ((FILE *, rtx));
-static tree get_mem_expr_from_op PARAMS ((rtx, int *));
-static void output_asm_operand_names PARAMS ((rtx *, int *, int));
-static void output_operand PARAMS ((rtx, int));
+static int asm_insn_count (rtx);
+#endif
+static void profile_function (FILE *);
+static void profile_after_prologue (FILE *);
+static bool notice_source_line (rtx);
+static rtx walk_alter_subreg (rtx *);
+static void output_asm_name (void);
+static void output_alternate_entry_point (FILE *, rtx);
+static tree get_mem_expr_from_op (rtx, int *);
+static void output_asm_operand_names (rtx *, int *, int);
+static void output_operand (rtx, int);
#ifdef LEAF_REGISTERS
-static void leaf_renumber_regs PARAMS ((rtx));
+static void leaf_renumber_regs (rtx);
#endif
#ifdef HAVE_cc0
-static int alter_cond PARAMS ((rtx));
+static int alter_cond (rtx);
#endif
#ifndef ADDR_VEC_ALIGN
-static int final_addr_vec_align PARAMS ((rtx));
+static int final_addr_vec_align (rtx);
#endif
#ifdef HAVE_ATTR_length
-static int align_fuzz PARAMS ((rtx, rtx, int, unsigned));
+static int align_fuzz (rtx, rtx, int, unsigned);
#endif
/* Initialize data in final at the beginning of a compilation. */
void
-init_final (filename)
- const char *filename ATTRIBUTE_UNUSED;
+init_final (const char *filename ATTRIBUTE_UNUSED)
{
app_on = 0;
final_sequence = 0;
@@ -253,287 +249,19 @@ init_final (filename)
#endif
}
-/* Called at end of source file,
- to output the arc-profiling table for this entire compilation. */
-
-void
-end_final (filename)
- const char *filename;
-{
- if (profile_arc_flag && profile_info.count_instrumented_edges)
- {
- char name[20];
- tree string_type, string_cst;
- tree structure_decl, structure_value, structure_pointer_type;
- tree field_decl, decl_chain, value_chain;
- tree sizeof_field_value, domain_type;
-
- /* Build types. */
- string_type = build_pointer_type (char_type_node);
-
- /* Libgcc2 bb structure. */
- structure_decl = make_node (RECORD_TYPE);
- structure_pointer_type = build_pointer_type (structure_decl);
-
- /* Output the main header, of 7 words:
- 0: 1 if this file is initialized, else 0.
- 1: address of file name (LPBX1).
- 2: address of table of counts (LPBX2).
- 3: number of counts in the table.
- 4: always 0, libgcc2 uses this as a pointer to next ``struct bb''
-
- The following are GNU extensions:
-
- 5: Number of bytes in this header.
- 6: address of table of function checksums (LPBX7). */
-
- /* The zero word. */
- decl_chain =
- build_decl (FIELD_DECL, get_identifier ("zero_word"),
- long_integer_type_node);
- value_chain = build_tree_list (decl_chain,
- convert (long_integer_type_node,
- integer_zero_node));
-
- /* Address of filename. */
- {
- char *cwd, *da_filename;
- int da_filename_len;
-
- field_decl =
- build_decl (FIELD_DECL, get_identifier ("filename"), string_type);
- TREE_CHAIN (field_decl) = decl_chain;
- decl_chain = field_decl;
-
- cwd = getpwd ();
- da_filename_len = strlen (filename) + strlen (cwd) + 4 + 1;
- da_filename = (char *) alloca (da_filename_len);
- strcpy (da_filename, cwd);
- strcat (da_filename, "/");
- strcat (da_filename, filename);
- strcat (da_filename, ".da");
- da_filename_len = strlen (da_filename);
- string_cst = build_string (da_filename_len + 1, da_filename);
- domain_type = build_index_type (build_int_2 (da_filename_len, 0));
- TREE_TYPE (string_cst)
- = build_array_type (char_type_node, domain_type);
- value_chain = tree_cons (field_decl,
- build1 (ADDR_EXPR, string_type, string_cst),
- value_chain);
- }
-
- /* Table of counts. */
- {
- tree gcov_type_type = make_unsigned_type (GCOV_TYPE_SIZE);
- tree gcov_type_pointer_type = build_pointer_type (gcov_type_type);
- tree domain_tree
- = build_index_type (build_int_2 (profile_info.
- count_instrumented_edges - 1, 0));
- tree gcov_type_array_type
- = build_array_type (gcov_type_type, domain_tree);
- tree gcov_type_array_pointer_type
- = build_pointer_type (gcov_type_array_type);
- tree counts_table;
-
- field_decl =
- build_decl (FIELD_DECL, get_identifier ("counts"),
- gcov_type_pointer_type);
- TREE_CHAIN (field_decl) = decl_chain;
- decl_chain = field_decl;
-
- /* No values. */
- counts_table
- = build (VAR_DECL, gcov_type_array_type, NULL_TREE, NULL_TREE);
- TREE_STATIC (counts_table) = 1;
- ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 2);
- DECL_NAME (counts_table) = get_identifier (name);
- assemble_variable (counts_table, 0, 0, 0);
-
- value_chain = tree_cons (field_decl,
- build1 (ADDR_EXPR,
- gcov_type_array_pointer_type,
- counts_table), value_chain);
- }
-
- /* Count of the # of instrumented arcs. */
- field_decl
- = build_decl (FIELD_DECL, get_identifier ("ncounts"),
- long_integer_type_node);
- TREE_CHAIN (field_decl) = decl_chain;
- decl_chain = field_decl;
-
- value_chain = tree_cons (field_decl,
- convert (long_integer_type_node,
- build_int_2 (profile_info.
- count_instrumented_edges,
- 0)), value_chain);
- /* Pointer to the next bb. */
- field_decl
- = build_decl (FIELD_DECL, get_identifier ("next"),
- structure_pointer_type);
- TREE_CHAIN (field_decl) = decl_chain;
- decl_chain = field_decl;
-
- value_chain = tree_cons (field_decl, null_pointer_node, value_chain);
-
- /* sizeof(struct bb). We'll set this after entire structure
- is laid out. */
- field_decl
- = build_decl (FIELD_DECL, get_identifier ("sizeof_bb"),
- long_integer_type_node);
- TREE_CHAIN (field_decl) = decl_chain;
- decl_chain = field_decl;
-
- sizeof_field_value = tree_cons (field_decl, NULL, value_chain);
- value_chain = sizeof_field_value;
-
- /* struct bb_function []. */
- {
- struct function_list *item;
- int num_nodes;
- tree checksum_field, arc_count_field, name_field;
- tree domain;
- tree array_value_chain = NULL_TREE;
- tree bb_fn_struct_type;
- tree bb_fn_struct_array_type;
- tree bb_fn_struct_array_pointer_type;
- tree bb_fn_struct_pointer_type;
- tree field_value, field_value_chain;
-
- bb_fn_struct_type = make_node (RECORD_TYPE);
-
- checksum_field = build_decl (FIELD_DECL, get_identifier ("checksum"),
- long_integer_type_node);
-
- arc_count_field
- = build_decl (FIELD_DECL, get_identifier ("arc_count"),
- integer_type_node);
- TREE_CHAIN (checksum_field) = arc_count_field;
-
- name_field
- = build_decl (FIELD_DECL, get_identifier ("name"), string_type);
- TREE_CHAIN (arc_count_field) = name_field;
-
- TYPE_FIELDS (bb_fn_struct_type) = checksum_field;
-
- num_nodes = 0;
-
- for (item = functions_head; item != 0; item = item->next)
- num_nodes++;
-
- /* Note that the array contains a terminator, hence no - 1. */
- domain = build_index_type (build_int_2 (num_nodes, 0));
-
- bb_fn_struct_pointer_type = build_pointer_type (bb_fn_struct_type);
- bb_fn_struct_array_type
- = build_array_type (bb_fn_struct_type, domain);
- bb_fn_struct_array_pointer_type
- = build_pointer_type (bb_fn_struct_array_type);
-
- layout_type (bb_fn_struct_type);
- layout_type (bb_fn_struct_pointer_type);
- layout_type (bb_fn_struct_array_type);
- layout_type (bb_fn_struct_array_pointer_type);
-
- for (item = functions_head; item != 0; item = item->next)
- {
- size_t name_len;
-
- /* create constructor for structure. */
- field_value_chain
- = build_tree_list (checksum_field,
- convert (long_integer_type_node,
- build_int_2 (item->cfg_checksum, 0)));
- field_value_chain
- = tree_cons (arc_count_field,
- convert (integer_type_node,
- build_int_2 (item->count_edges, 0)),
- field_value_chain);
-
- name_len = strlen (item->name);
- string_cst = build_string (name_len + 1, item->name);
- domain_type = build_index_type (build_int_2 (name_len, 0));
- TREE_TYPE (string_cst)
- = build_array_type (char_type_node, domain_type);
- field_value_chain = tree_cons (name_field,
- build1 (ADDR_EXPR, string_type,
- string_cst),
- field_value_chain);
-
- /* Add to chain. */
- array_value_chain
- = tree_cons (NULL_TREE, build (CONSTRUCTOR,
- bb_fn_struct_type, NULL_TREE,
- nreverse (field_value_chain)),
- array_value_chain);
- }
-
- /* Add terminator. */
- field_value = build_tree_list (arc_count_field,
- convert (integer_type_node,
- build_int_2 (-1, 0)));
-
- array_value_chain = tree_cons (NULL_TREE,
- build (CONSTRUCTOR, bb_fn_struct_type,
- NULL_TREE, field_value),
- array_value_chain);
-
-
- /* Create constructor for array. */
- field_decl
- = build_decl (FIELD_DECL, get_identifier ("function_infos"),
- bb_fn_struct_pointer_type);
- value_chain = tree_cons (field_decl,
- build1 (ADDR_EXPR,
- bb_fn_struct_array_pointer_type,
- build (CONSTRUCTOR,
- bb_fn_struct_array_type,
- NULL_TREE,
- nreverse
- (array_value_chain))),
- value_chain);
- TREE_CHAIN (field_decl) = decl_chain;
- decl_chain = field_decl;
- }
-
- /* Finish structure. */
- TYPE_FIELDS (structure_decl) = nreverse (decl_chain);
- layout_type (structure_decl);
-
- structure_value
- = build (VAR_DECL, structure_decl, NULL_TREE, NULL_TREE);
- DECL_INITIAL (structure_value)
- = build (CONSTRUCTOR, structure_decl, NULL_TREE,
- nreverse (value_chain));
- TREE_STATIC (structure_value) = 1;
- ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
- DECL_NAME (structure_value) = get_identifier (name);
-
- /* Size of this structure. */
- TREE_VALUE (sizeof_field_value)
- = convert (long_integer_type_node,
- build_int_2 (int_size_in_bytes (structure_decl), 0));
-
- /* Build structure. */
- assemble_variable (structure_value, 0, 0, 0);
- }
-}
-
/* Default target function prologue and epilogue assembler output.
If not overridden for epilogue code, then the function body itself
contains return instructions wherever needed. */
void
-default_function_pro_epilogue (file, size)
- FILE *file ATTRIBUTE_UNUSED;
- HOST_WIDE_INT size ATTRIBUTE_UNUSED;
+default_function_pro_epilogue (FILE *file ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
{
}
/* Default target hook that outputs nothing to a stream. */
void
-no_asm_to_stream (file)
- FILE *file ATTRIBUTE_UNUSED;
+no_asm_to_stream (FILE *file ATTRIBUTE_UNUSED)
{
}
@@ -541,7 +269,7 @@ no_asm_to_stream (file)
Used before the output from an `asm' statement. */
void
-app_enable ()
+app_enable (void)
{
if (! app_on)
{
@@ -554,7 +282,7 @@ app_enable ()
Called from varasm.c before most kinds of output. */
void
-app_disable ()
+app_disable (void)
{
if (app_on)
{
@@ -569,7 +297,7 @@ app_disable ()
#ifdef DELAY_SLOTS
int
-dbr_sequence_length ()
+dbr_sequence_length (void)
{
if (final_sequence != 0)
return XVECLEN (final_sequence, 0) - 1;
@@ -622,7 +350,7 @@ static struct label_alignment *label_align;
/* Indicate that branch shortening hasn't yet been done. */
void
-init_insn_lengths ()
+init_insn_lengths (void)
{
if (uid_shuid)
{
@@ -649,8 +377,7 @@ init_insn_lengths ()
get its actual length. Otherwise, get its maximum length. */
int
-get_attr_length (insn)
- rtx insn ATTRIBUTE_UNUSED;
+get_attr_length (rtx insn ATTRIBUTE_UNUSED)
{
#ifdef HAVE_ATTR_length
rtx body;
@@ -784,8 +511,7 @@ get_attr_length (insn)
#ifndef ADDR_VEC_ALIGN
static int
-final_addr_vec_align (addr_vec)
- rtx addr_vec;
+final_addr_vec_align (rtx addr_vec)
{
int align = GET_MODE_SIZE (GET_MODE (PATTERN (addr_vec)));
@@ -815,8 +541,7 @@ static int min_labelno, max_labelno;
/* For the benefit of port specific code do this also as a function. */
int
-label_to_alignment (label)
- rtx label;
+label_to_alignment (rtx label)
{
return LABEL_TO_ALIGNMENT (label);
}
@@ -851,10 +576,7 @@ label_to_alignment (label)
The return value is undefined for any other value of GROWTH. */
static int
-align_fuzz (start, end, known_align_log, growth)
- rtx start, end;
- int known_align_log;
- unsigned growth;
+align_fuzz (rtx start, rtx end, int known_align_log, unsigned int growth)
{
int uid = INSN_UID (start);
rtx align_label;
@@ -893,8 +615,7 @@ align_fuzz (start, end, known_align_log, growth)
to exclude the branch size. */
int
-insn_current_reference_address (branch)
- rtx branch;
+insn_current_reference_address (rtx branch)
{
rtx dest, seq;
int seq_uid;
@@ -931,7 +652,7 @@ insn_current_reference_address (branch)
#endif /* HAVE_ATTR_length */
void
-compute_alignments ()
+compute_alignments (void)
{
int log, max_skip, max_log;
basic_block bb;
@@ -944,8 +665,8 @@ compute_alignments ()
max_labelno = max_label_num ();
min_labelno = get_first_label_num ();
- label_align = (struct label_alignment *)
- xcalloc (max_labelno - min_labelno + 1, sizeof (struct label_alignment));
+ label_align = xcalloc (max_labelno - min_labelno + 1,
+ sizeof (struct label_alignment));
/* If not optimizing or optimizing for size, don't assign any alignments. */
if (! optimize || optimize_size)
@@ -953,11 +674,12 @@ compute_alignments ()
FOR_EACH_BB (bb)
{
- rtx label = bb->head;
+ rtx label = BB_HEAD (bb);
int fallthru_frequency = 0, branch_frequency = 0, has_fallthru = 0;
edge e;
- if (GET_CODE (label) != CODE_LABEL)
+ if (GET_CODE (label) != CODE_LABEL
+ || probably_never_executed_bb_p (bb))
continue;
max_log = LABEL_ALIGN (label);
max_skip = LABEL_ALIGN_MAX_SKIP;
@@ -996,6 +718,7 @@ compute_alignments ()
/* In case block is frequent and reached mostly by non-fallthru edge,
align it. It is most likely a first block of loop. */
if (has_fallthru
+ && maybe_hot_bb_p (bb)
&& branch_frequency + fallthru_frequency > BB_FREQ_MAX / 10
&& branch_frequency > fallthru_frequency * 2)
{
@@ -1014,12 +737,6 @@ compute_alignments ()
/* Make a pass over all insns and compute their actual lengths by shortening
any branches of variable length if possible. */
-/* Give a default value for the lowest address in a function. */
-
-#ifndef FIRST_INSN_ADDRESS
-#define FIRST_INSN_ADDRESS 0
-#endif
-
/* shorten_branches might be called multiple times: for example, the SH
port splits out-of-range conditional branches in MACHINE_DEPENDENT_REORG.
In order to do this, it needs proper length information, which it obtains
@@ -1029,8 +746,7 @@ compute_alignments ()
slots. */
void
-shorten_branches (first)
- rtx first ATTRIBUTE_UNUSED;
+shorten_branches (rtx first ATTRIBUTE_UNUSED)
{
rtx insn;
int max_uid;
@@ -1051,7 +767,7 @@ shorten_branches (first)
/* Compute maximum UID and allocate label_align / uid_shuid. */
max_uid = get_max_uid ();
- uid_shuid = (int *) xmalloc (max_uid * sizeof *uid_shuid);
+ uid_shuid = xmalloc (max_uid * sizeof *uid_shuid);
if (max_labelno != max_label_num ())
{
@@ -1064,8 +780,8 @@ shorten_branches (first)
n_labels = max_labelno - min_labelno + 1;
n_old_labels = old - min_labelno + 1;
- label_align = (struct label_alignment *) xrealloc
- (label_align, n_labels * sizeof (struct label_alignment));
+ label_align = xrealloc (label_align,
+ n_labels * sizeof (struct label_alignment));
/* Range of labels grows monotonically in the function. Abort here
means that the initialization of array got lost. */
@@ -1160,20 +876,20 @@ shorten_branches (first)
#ifdef HAVE_ATTR_length
/* Allocate the rest of the arrays. */
- insn_lengths = (int *) xmalloc (max_uid * sizeof (*insn_lengths));
+ insn_lengths = xmalloc (max_uid * sizeof (*insn_lengths));
insn_lengths_max_uid = max_uid;
/* Syntax errors can lead to labels being outside of the main insn stream.
Initialize insn_addresses, so that we get reproducible results. */
INSN_ADDRESSES_ALLOC (max_uid);
- varying_length = (char *) xcalloc (max_uid, sizeof (char));
+ varying_length = xcalloc (max_uid, sizeof (char));
/* Initialize uid_align. We scan instructions
from end to start, and keep in align_tab[n] the last seen insn
that does an alignment of at least n+1, i.e. the successor
in the alignment chain for an insn that does / has a known
alignment of n. */
- uid_align = (rtx *) xcalloc (max_uid, sizeof *uid_align);
+ uid_align = xcalloc (max_uid, sizeof *uid_align);
for (i = MAX_CODE_ALIGN; --i >= 0;)
align_tab[i] = NULL_RTX;
@@ -1250,7 +966,7 @@ shorten_branches (first)
#endif /* CASE_VECTOR_SHORTEN_MODE */
/* Compute initial lengths, addresses, and varying flags for each insn. */
- for (insn_current_address = FIRST_INSN_ADDRESS, insn = first;
+ for (insn_current_address = 0, insn = first;
insn != 0;
insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn))
{
@@ -1351,7 +1067,7 @@ shorten_branches (first)
{
something_changed = 0;
insn_current_align = MAX_CODE_ALIGN - 1;
- for (insn_current_address = FIRST_INSN_ADDRESS, insn = first;
+ for (insn_current_address = 0, insn = first;
insn != 0;
insn = NEXT_INSN (insn))
{
@@ -1585,8 +1301,7 @@ shorten_branches (first)
This is used to compute its length. */
static int
-asm_insn_count (body)
- rtx body;
+asm_insn_count (rtx body)
{
const char *template;
int count = 1;
@@ -1615,30 +1330,16 @@ asm_insn_count (body)
test and compare insns. */
void
-final_start_function (first, file, optimize)
- rtx first;
- FILE *file;
- int optimize ATTRIBUTE_UNUSED;
+final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
+ int optimize ATTRIBUTE_UNUSED)
{
block_depth = 0;
this_is_asm_operands = 0;
-#ifdef NON_SAVING_SETJMP
- /* A function that calls setjmp should save and restore all the
- call-saved registers on a system where longjmp clobbers them. */
- if (NON_SAVING_SETJMP && current_function_calls_setjmp)
- {
- int i;
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (!call_used_regs[i])
- regs_ever_live[i] = 1;
- }
-#endif
+ last_filename = locator_file (prologue_locator);
+ last_linenum = locator_line (prologue_locator);
- if (NOTE_LINE_NUMBER (first) != NOTE_INSN_DELETED)
- notice_source_line (first);
high_block_linenum = high_function_linenum = last_linenum;
(*debug_hooks->begin_prologue) (last_linenum, last_filename);
@@ -1670,7 +1371,7 @@ final_start_function (first, file, optimize)
if (write_symbols)
{
remove_unnecessary_notes ();
- scope_to_insns_finalize ();
+ reemit_insn_block_notes ();
number_blocks (current_function_decl);
/* We never actually put out begin/end notes for the top-level
block in the function. But, conceptually, that block is
@@ -1690,8 +1391,7 @@ final_start_function (first, file, optimize)
}
static void
-profile_after_prologue (file)
- FILE *file ATTRIBUTE_UNUSED;
+profile_after_prologue (FILE *file ATTRIBUTE_UNUSED)
{
#ifndef PROFILE_BEFORE_PROLOGUE
if (current_function_profile)
@@ -1700,40 +1400,33 @@ profile_after_prologue (file)
}
static void
-profile_function (file)
- FILE *file ATTRIBUTE_UNUSED;
+profile_function (FILE *file ATTRIBUTE_UNUSED)
{
#ifndef NO_PROFILE_COUNTERS
- int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
+# define NO_PROFILE_COUNTERS 0
#endif
#if defined(ASM_OUTPUT_REG_PUSH)
-#if defined(STRUCT_VALUE_INCOMING_REGNUM) || defined(STRUCT_VALUE_REGNUM)
int sval = current_function_returns_struct;
-#endif
+ rtx svrtx = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl), 1);
#if defined(STATIC_CHAIN_INCOMING_REGNUM) || defined(STATIC_CHAIN_REGNUM)
int cxt = current_function_needs_context;
#endif
#endif /* ASM_OUTPUT_REG_PUSH */
-#ifndef NO_PROFILE_COUNTERS
- data_section ();
- ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
- ASM_OUTPUT_INTERNAL_LABEL (file, "LP", current_function_funcdef_no);
- assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
-#endif
+ if (! NO_PROFILE_COUNTERS)
+ {
+ int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
+ data_section ();
+ ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
+ (*targetm.asm_out.internal_label) (file, "LP", current_function_funcdef_no);
+ assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
+ }
function_section (current_function_decl);
-#if defined(STRUCT_VALUE_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
- if (sval)
- ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_INCOMING_REGNUM);
-#else
-#if defined(STRUCT_VALUE_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
- if (sval)
- {
- ASM_OUTPUT_REG_PUSH (file, STRUCT_VALUE_REGNUM);
- }
-#endif
+#if defined(ASM_OUTPUT_REG_PUSH)
+ if (sval && svrtx != NULL_RTX && GET_CODE (svrtx) == REG)
+ ASM_OUTPUT_REG_PUSH (file, REGNO (svrtx));
#endif
#if defined(STATIC_CHAIN_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
@@ -1762,16 +1455,9 @@ profile_function (file)
#endif
#endif
-#if defined(STRUCT_VALUE_INCOMING_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
- if (sval)
- ASM_OUTPUT_REG_POP (file, STRUCT_VALUE_INCOMING_REGNUM);
-#else
-#if defined(STRUCT_VALUE_REGNUM) && defined(ASM_OUTPUT_REG_PUSH)
- if (sval)
- {
- ASM_OUTPUT_REG_POP (file, STRUCT_VALUE_REGNUM);
- }
-#endif
+#if defined(ASM_OUTPUT_REG_PUSH)
+ if (sval && svrtx != NULL_RTX && GET_CODE (svrtx) == REG)
+ ASM_OUTPUT_REG_POP (file, REGNO (svrtx));
#endif
}
@@ -1780,7 +1466,7 @@ profile_function (file)
even though not all of them are needed. */
void
-final_end_function ()
+final_end_function (void)
{
app_disable ();
@@ -1812,24 +1498,18 @@ final_end_function ()
Prescanning is done only on certain machines. */
void
-final (first, file, optimize, prescan)
- rtx first;
- FILE *file;
- int optimize;
- int prescan;
+final (rtx first, FILE *file, int optimize, int prescan)
{
rtx insn;
- int max_line = 0;
int max_uid = 0;
+ int seen = 0;
last_ignored_compare = 0;
- new_block = 1;
- /* Make a map indicating which line numbers appear in this function.
- When producing SDB debugging info, delete troublesome line number
+#ifdef SDB_DEBUGGING_INFO
+ /* When producing SDB debugging info, delete troublesome line number
notes from inlined functions in other files as well as duplicate
line number notes. */
-#ifdef SDB_DEBUGGING_INFO
if (write_symbols == SDB_DEBUG)
{
rtx last = 0;
@@ -1838,34 +1518,22 @@ final (first, file, optimize, prescan)
{
if ((RTX_INTEGRATED_P (insn)
&& strcmp (NOTE_SOURCE_FILE (insn), main_input_filename) != 0)
- || (last != 0
- && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)
- && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last)))
+ || (last != 0
+ && NOTE_LINE_NUMBER (insn) == NOTE_LINE_NUMBER (last)
+ && NOTE_SOURCE_FILE (insn) == NOTE_SOURCE_FILE (last)))
{
delete_insn (insn); /* Use delete_note. */
continue;
}
last = insn;
- if (NOTE_LINE_NUMBER (insn) > max_line)
- max_line = NOTE_LINE_NUMBER (insn);
}
}
- else
#endif
- {
- for (insn = first; insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > max_line)
- max_line = NOTE_LINE_NUMBER (insn);
- }
-
- line_note_exists = (char *) xcalloc (max_line + 1, sizeof (char));
for (insn = first; insn; insn = NEXT_INSN (insn))
{
- if (INSN_UID (insn) > max_uid) /* find largest UID */
+ if (INSN_UID (insn) > max_uid) /* Find largest UID. */
max_uid = INSN_UID (insn);
- if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
- line_note_exists[NOTE_LINE_NUMBER (insn)] = 1;
#ifdef HAVE_cc0
/* If CC tracking across branches is enabled, record the insn which
jumps to each branch only reached from one place. */
@@ -1901,46 +1569,23 @@ final (first, file, optimize, prescan)
insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
#endif /* HAVE_ATTR_length */
- insn = final_scan_insn (insn, file, optimize, prescan, 0);
- }
-
- /* Store function names for edge-profiling. */
- /* ??? Probably should re-use the existing struct function. */
-
- if (cfun->arc_profile)
- {
- struct function_list *new_item = xmalloc (sizeof (struct function_list));
-
- *functions_tail = new_item;
- functions_tail = &new_item->next;
-
- new_item->next = 0;
- new_item->name = xstrdup (IDENTIFIER_POINTER
- (DECL_ASSEMBLER_NAME (current_function_decl)));
- new_item->cfg_checksum = profile_info.current_function_cfg_checksum;
- new_item->count_edges = profile_info.count_edges_instrumented_now;
+ insn = final_scan_insn (insn, file, optimize, prescan, 0, &seen);
}
-
- free (line_note_exists);
- line_note_exists = NULL;
}
const char *
-get_insn_template (code, insn)
- int code;
- rtx insn;
+get_insn_template (int code, rtx insn)
{
- const void *output = insn_data[code].output;
switch (insn_data[code].output_format)
{
case INSN_OUTPUT_FORMAT_SINGLE:
- return (const char *) output;
+ return insn_data[code].output.single;
case INSN_OUTPUT_FORMAT_MULTI:
- return ((const char *const *) output)[which_alternative];
+ return insn_data[code].output.multi[which_alternative];
case INSN_OUTPUT_FORMAT_FUNCTION:
if (insn == NULL)
abort ();
- return (*(insn_output_fn) output) (recog_data.operand, insn);
+ return (*insn_data[code].output.function) (recog_data.operand, insn);
default:
abort ();
@@ -1953,9 +1598,7 @@ get_insn_template (code, insn)
The case fall-through in this function is intentional. */
static void
-output_alternate_entry_point (file, insn)
- FILE *file;
- rtx insn;
+output_alternate_entry_point (FILE *file, rtx insn)
{
const char *name = LABEL_NAME (insn);
@@ -1986,15 +1629,18 @@ output_alternate_entry_point (file, insn)
Value returned is the next insn to be scanned.
NOPEEPHOLES is the flag to disallow peephole processing (currently
- used for within delayed branch sequence output). */
+ used for within delayed branch sequence output).
+
+ SEEN is used to track the end of the prologue, for emitting
+ debug information. We force the emission of a line note after
+ both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG, or
+ at the beginning of the second basic block, whichever comes
+ first. */
rtx
-final_scan_insn (insn, file, optimize, prescan, nopeepholes)
- rtx insn;
- FILE *file;
- int optimize ATTRIBUTE_UNUSED;
- int prescan;
- int nopeepholes ATTRIBUTE_UNUSED;
+final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
+ int prescan, int nopeepholes ATTRIBUTE_UNUSED,
+ int *seen)
{
#ifdef HAVE_cc0
rtx set;
@@ -2033,6 +1679,15 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
if (flag_debug_asm)
fprintf (asm_out_file, "\t%s basic block %d\n",
ASM_COMMENT_START, NOTE_BASIC_BLOCK (insn)->index);
+
+ if ((*seen & (SEEN_EMITTED | SEEN_BB)) == SEEN_BB)
+ {
+ *seen |= SEEN_EMITTED;
+ last_filename = NULL;
+ }
+ else
+ *seen |= SEEN_BB;
+
break;
case NOTE_INSN_EH_REGION_BEG:
@@ -2048,6 +1703,15 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
case NOTE_INSN_PROLOGUE_END:
(*targetm.asm_out.function_end_prologue) (file);
profile_after_prologue (file);
+
+ if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
+ {
+ *seen |= SEEN_EMITTED;
+ last_filename = NULL;
+ }
+ else
+ *seen |= SEEN_NOTE;
+
break;
case NOTE_INSN_EPILOGUE_BEG:
@@ -2057,6 +1721,15 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
case NOTE_INSN_FUNCTION_BEG:
app_disable ();
(*debug_hooks->end_prologue) (last_linenum, last_filename);
+
+ if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
+ {
+ *seen |= SEEN_EMITTED;
+ last_filename = NULL;
+ }
+ else
+ *seen |= SEEN_NOTE;
+
break;
case NOTE_INSN_BLOCK_BEG:
@@ -2115,51 +1788,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
default:
if (NOTE_LINE_NUMBER (insn) <= 0)
abort ();
-
- /* This note is a line-number. */
- {
- rtx note;
- int note_after = 0;
-
- /* If there is anything real after this note, output it.
- If another line note follows, omit this one. */
- for (note = NEXT_INSN (insn); note; note = NEXT_INSN (note))
- {
- if (GET_CODE (note) != NOTE && GET_CODE (note) != CODE_LABEL)
- break;
-
- /* These types of notes can be significant
- so make sure the preceding line number stays. */
- else if (GET_CODE (note) == NOTE
- && (NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_BEG
- || NOTE_LINE_NUMBER (note) == NOTE_INSN_BLOCK_END
- || NOTE_LINE_NUMBER (note) == NOTE_INSN_FUNCTION_BEG))
- break;
- else if (GET_CODE (note) == NOTE && NOTE_LINE_NUMBER (note) > 0)
- {
- /* Another line note follows; we can delete this note
- if no intervening line numbers have notes elsewhere. */
- int num;
- for (num = NOTE_LINE_NUMBER (insn) + 1;
- num < NOTE_LINE_NUMBER (note);
- num++)
- if (line_note_exists[num])
- break;
-
- if (num >= NOTE_LINE_NUMBER (note))
- note_after = 1;
- break;
- }
- }
-
- /* Output this line note if it is the first or the last line
- note in a row. */
- if (!note_after)
- {
- notice_source_line (insn);
- (*debug_hooks->source_line) (last_linenum, last_filename);
- }
- }
break;
}
break;
@@ -2223,11 +1851,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
#endif
if (prescan > 0)
break;
- new_block = 1;
-
-#ifdef FINAL_PRESCAN_LABEL
- FINAL_PRESCAN_INSN (insn, NULL, 0);
-#endif
if (LABEL_NAME (insn))
(*debug_hooks->label) (insn);
@@ -2274,7 +1897,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn),
NEXT_INSN (insn));
#else
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
+ (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (insn));
#endif
#endif
break;
@@ -2283,7 +1906,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
if (LABEL_ALT_ENTRY_P (insn))
output_alternate_entry_point (file, insn);
else
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
+ (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (insn));
break;
default:
@@ -2296,7 +1919,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
/* An INSN, JUMP_INSN or CALL_INSN.
First check for special kinds that recog doesn't recognize. */
- if (GET_CODE (body) == USE /* These are just declarations */
+ if (GET_CODE (body) == USE /* These are just declarations. */
|| GET_CODE (body) == CLOBBER)
break;
@@ -2386,6 +2009,12 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
break;
}
+ /* Output this line note if it is the first or the last line
+ note in a row. */
+ if (notice_source_line (insn))
+ {
+ (*debug_hooks->source_line) (last_linenum, last_filename);
+ }
if (GET_CODE (body) == ASM_INPUT)
{
@@ -2412,7 +2041,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
if (asm_noperands (body) >= 0)
{
unsigned int noperands = asm_noperands (body);
- rtx *ops = (rtx *) alloca (noperands * sizeof (rtx));
+ rtx *ops = alloca (noperands * sizeof (rtx));
const char *string;
/* There's no telling what that did to the condition codes. */
@@ -2426,6 +2055,10 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
insn_noperands = noperands;
this_is_asm_operands = insn;
+#ifdef FINAL_PRESCAN_INSN
+ FINAL_PRESCAN_INSN (insn, ops, insn_noperands);
+#endif
+
/* Output the insn using them. */
if (string[0])
{
@@ -2457,12 +2090,20 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
break;
final_sequence = body;
+ /* Record the delay slots' frame information before the branch.
+ This is needed for delayed calls: see execute_cfa_program(). */
+#if defined (DWARF2_UNWIND_INFO)
+ if (dwarf2out_do_frame ())
+ for (i = 1; i < XVECLEN (body, 0); i++)
+ dwarf2out_frame_debug (XVECEXP (body, 0, i));
+#endif
+
/* The first insn in this SEQUENCE might be a JUMP_INSN that will
force the restoration of a comparison that was previously
thought unnecessary. If that happens, cancel this sequence
and cause that insn to be restored. */
- next = final_scan_insn (XVECEXP (body, 0, 0), file, 0, prescan, 1);
+ next = final_scan_insn (XVECEXP (body, 0, 0), file, 0, prescan, 1, seen);
if (next != XVECEXP (body, 0, 1))
{
final_sequence = 0;
@@ -2476,7 +2117,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
/* We loop in case any instruction in a delay slot gets
split. */
do
- insn = final_scan_insn (insn, file, 0, prescan, 1);
+ insn = final_scan_insn (insn, file, 0, prescan, 1, seen);
while (insn != next);
}
#ifdef DBR_OUTPUT_SEQEND
@@ -2513,10 +2154,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
if (optimize)
{
-#if 0
- rtx set = single_set (insn);
-#endif
-
if (set
&& GET_CODE (SET_DEST (set)) == CC0
&& insn != last_ignored_compare)
@@ -2684,7 +2321,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
for (note = NEXT_INSN (insn); note != next;
note = NEXT_INSN (note))
- final_scan_insn (note, file, optimize, prescan, nopeepholes);
+ final_scan_insn (note, file, optimize, prescan, nopeepholes, seen);
/* In case this is prescan, put the notes
in proper position for later rescan. */
@@ -2765,7 +2402,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
if (prev_nonnote_insn (insn) != last_ignored_compare)
abort ();
- new_block = 0;
/* We have already processed the notes between the setter and
the user. Make sure we don't process them again, this is
@@ -2799,7 +2435,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
abort ();
#endif
- new_block = 0;
return new;
}
@@ -2813,22 +2448,23 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
output_asm_insn (template, recog_data.operand);
+ /* If necessary, report the effect that the instruction has on
+ the unwind info. We've already done this for delay slots
+ and call instructions. */
#if defined (DWARF2_UNWIND_INFO)
-#if defined (HAVE_prologue)
- if (GET_CODE (insn) == INSN && dwarf2out_do_frame ())
- dwarf2out_frame_debug (insn);
-#else
- if (!ACCUMULATE_OUTGOING_ARGS
- && GET_CODE (insn) == INSN
+ if (GET_CODE (insn) == INSN
+#if !defined (HAVE_prologue)
+ && !ACCUMULATE_OUTGOING_ARGS
+#endif
+ && final_sequence == 0
&& dwarf2out_do_frame ())
dwarf2out_frame_debug (insn);
#endif
-#endif
#if 0
- /* It's not at all clear why we did this and doing so interferes
- with tests we'd like to do to use REG_WAS_0 notes, so let's try
- with this out. */
+ /* It's not at all clear why we did this and doing so used to
+ interfere with tests that used REG_WAS_0 notes, which are
+ now gone, so let's try with this out. */
/* Mark this insn as having been output. */
INSN_DELETED_P (insn) = 1;
@@ -2836,9 +2472,6 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
/* Emit information for vtable gc. */
note = find_reg_note (insn, REG_VTABLE_REF, NULL_RTX);
- if (note)
- assemble_vtable_entry (XEXP (XEXP (note, 0), 0),
- INTVAL (XEXP (XEXP (note, 0), 1)));
current_output_insn = debug_insn = 0;
}
@@ -2849,30 +2482,34 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
/* Output debugging info to the assembler file FILE
based on the NOTE-insn INSN, assumed to be a line number. */
-static void
-notice_source_line (insn)
- rtx insn;
+static bool
+notice_source_line (rtx insn)
{
- const char *filename = NOTE_SOURCE_FILE (insn);
+ const char *filename = insn_file (insn);
+ int linenum = insn_line (insn);
- last_filename = filename;
- last_linenum = NOTE_LINE_NUMBER (insn);
- high_block_linenum = MAX (last_linenum, high_block_linenum);
- high_function_linenum = MAX (last_linenum, high_function_linenum);
+ if (filename && (filename != last_filename || last_linenum != linenum))
+ {
+ last_filename = filename;
+ last_linenum = linenum;
+ high_block_linenum = MAX (last_linenum, high_block_linenum);
+ high_function_linenum = MAX (last_linenum, high_function_linenum);
+ return true;
+ }
+ return false;
}
/* For each operand in INSN, simplify (subreg (reg)) so that it refers
directly to the desired hard register. */
void
-cleanup_subreg_operands (insn)
- rtx insn;
+cleanup_subreg_operands (rtx insn)
{
int i;
extract_insn_cached (insn);
for (i = 0; i < recog_data.n_operands; i++)
{
- /* The following test cannot use recog_data.operand when tesing
+ /* The following test cannot use recog_data.operand when testing
for a SUBREG: the underlying object might have been changed
already if we are inside a match_operator expression that
matches the else clause. Instead we test the underlying
@@ -2900,8 +2537,7 @@ cleanup_subreg_operands (insn)
based on the thing it is a subreg of. */
rtx
-alter_subreg (xp)
- rtx *xp;
+alter_subreg (rtx *xp)
{
rtx x = *xp;
rtx y = SUBREG_REG (x);
@@ -2921,12 +2557,7 @@ alter_subreg (xp)
else if (GET_CODE (y) == REG)
{
unsigned int regno = subreg_hard_regno (x, 1);
- PUT_CODE (x, REG);
- REGNO (x) = regno;
- ORIGINAL_REGNO (x) = ORIGINAL_REGNO (y);
- /* This field has a different meaning for REGs and SUBREGs. Make
- sure to clear it! */
- RTX_FLAG (x, used) = 0;
+ *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, SUBREG_BYTE (x));
}
else
abort ();
@@ -2938,8 +2569,7 @@ alter_subreg (xp)
/* Do alter_subreg on all the SUBREGs contained in X. */
static rtx
-walk_alter_subreg (xp)
- rtx *xp;
+walk_alter_subreg (rtx *xp)
{
rtx x = *xp;
switch (GET_CODE (x))
@@ -2976,8 +2606,7 @@ walk_alter_subreg (xp)
2 means that COND has been altered. */
static int
-alter_cond (cond)
- rtx cond;
+alter_cond (rtx cond)
{
int value = 0;
@@ -3130,13 +2759,14 @@ alter_cond (cond)
In an `asm', it's the user's fault; otherwise, the compiler's fault. */
void
-output_operand_lossage VPARAMS ((const char *msgid, ...))
+output_operand_lossage (const char *msgid, ...)
{
char *fmt_string;
char *new_message;
const char *pfx_str;
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_list ap;
+
+ va_start (ap, msgid);
pfx_str = this_is_asm_operands ? _("invalid `asm': ") : "output_operand: ";
asprintf (&fmt_string, "%s%s", pfx_str, _(msgid));
@@ -3149,7 +2779,7 @@ output_operand_lossage VPARAMS ((const char *msgid, ...))
free (fmt_string);
free (new_message);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Output of assembler code from a template, and its subroutines. */
@@ -3158,7 +2788,7 @@ output_operand_lossage VPARAMS ((const char *msgid, ...))
alternative used. */
static void
-output_asm_name ()
+output_asm_name (void)
{
if (debug_insn)
{
@@ -3183,20 +2813,15 @@ output_asm_name ()
corresponds to the address of the object and 0 if to the object. */
static tree
-get_mem_expr_from_op (op, paddressp)
- rtx op;
- int *paddressp;
+get_mem_expr_from_op (rtx op, int *paddressp)
{
tree expr;
int inner_addressp;
*paddressp = 0;
- if (op == NULL)
- return 0;
-
- if (GET_CODE (op) == REG && ORIGINAL_REGNO (op) >= FIRST_PSEUDO_REGISTER)
- return REGNO_DECL (ORIGINAL_REGNO (op));
+ if (GET_CODE (op) == REG)
+ return REG_EXPR (op);
else if (GET_CODE (op) != MEM)
return 0;
@@ -3229,10 +2854,7 @@ get_mem_expr_from_op (op, paddressp)
is the number of operands to write. */
static void
-output_asm_operand_names (operands, oporder, nops)
- rtx *operands;
- int *oporder;
- int nops;
+output_asm_operand_names (rtx *operands, int *oporder, int nops)
{
int wrote = 0;
int i;
@@ -3240,16 +2862,22 @@ output_asm_operand_names (operands, oporder, nops)
for (i = 0; i < nops; i++)
{
int addressp;
- tree expr = get_mem_expr_from_op (operands[oporder[i]], &addressp);
+ rtx op = operands[oporder[i]];
+ tree expr = get_mem_expr_from_op (op, &addressp);
+ fprintf (asm_out_file, "%c%s",
+ wrote ? ',' : '\t', wrote ? "" : ASM_COMMENT_START);
+ wrote = 1;
if (expr)
{
- fprintf (asm_out_file, "%c%s %s",
- wrote ? ',' : '\t', wrote ? "" : ASM_COMMENT_START,
+ fprintf (asm_out_file, "%s",
addressp ? "*" : "");
print_mem_expr (asm_out_file, expr);
wrote = 1;
}
+ else if (REG_P (op) && ORIGINAL_REGNO (op)
+ && ORIGINAL_REGNO (op) != REGNO (op))
+ fprintf (asm_out_file, " tmp%i", ORIGINAL_REGNO (op));
}
}
@@ -3270,9 +2898,7 @@ output_asm_operand_names (operands, oporder, nops)
of the operand, with no other punctuation. */
void
-output_asm_insn (template, operands)
- const char *template;
- rtx *operands;
+output_asm_insn (const char *template, rtx *operands)
{
const char *p;
int c;
@@ -3478,8 +3104,7 @@ output_asm_insn (template, operands)
/* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol. */
void
-output_asm_label (x)
- rtx x;
+output_asm_label (rtx x)
{
char buf[256];
@@ -3506,9 +3131,7 @@ output_asm_label (x)
by PRINT_OPERAND. */
static void
-output_operand (x, code)
- rtx x;
- int code ATTRIBUTE_UNUSED;
+output_operand (rtx x, int code ATTRIBUTE_UNUSED)
{
if (x && GET_CODE (x) == SUBREG)
x = alter_subreg (&x);
@@ -3527,8 +3150,7 @@ output_operand (x, code)
The macro PRINT_OPERAND_ADDRESS exists just to control this function. */
void
-output_address (x)
- rtx x;
+output_address (rtx x)
{
walk_alter_subreg (&x);
PRINT_OPERAND_ADDRESS (asm_out_file, x);
@@ -3539,9 +3161,7 @@ output_address (x)
that may appear in these expressions. */
void
-output_addr_const (file, x)
- FILE *file;
- rtx x;
+output_addr_const (FILE *file, rtx x)
{
char buf[256];
@@ -3663,19 +3283,18 @@ output_addr_const (file, x)
%U prints the value of USER_LABEL_PREFIX.
%I prints the value of IMMEDIATE_PREFIX.
%O runs ASM_OUTPUT_OPCODE to transform what follows in the string.
- Also supported are %d, %x, %s, %e, %f, %g and %%.
+ Also supported are %d, %i, %u, %x, %X, %o, %c, %s and %%.
We handle alternate assembler dialects here, just like output_asm_insn. */
void
-asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
+asm_fprintf (FILE *file, const char *p, ...)
{
char buf[10];
char *q, c;
+ va_list argptr;
- VA_OPEN (argptr, p);
- VA_FIXEDARG (argptr, FILE *, file);
- VA_FIXEDARG (argptr, const char *, p);
+ va_start (argptr, p);
buf[0] = '%';
@@ -3713,6 +3332,11 @@ asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
case '%':
c = *p++;
q = &buf[1];
+ while (strchr ("-+ #0", c))
+ {
+ *q++ = c;
+ c = *p++;
+ }
while (ISDIGIT (c) || c == '.')
{
*q++ = c;
@@ -3721,32 +3345,24 @@ asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
switch (c)
{
case '%':
- fprintf (file, "%%");
+ putc ('%', file);
break;
case 'd': case 'i': case 'u':
- case 'x': case 'p': case 'X':
- case 'o':
+ case 'x': case 'X': case 'o':
+ case 'c':
*q++ = c;
*q = 0;
fprintf (file, buf, va_arg (argptr, int));
break;
case 'w':
- /* This is a prefix to the 'd', 'i', 'u', 'x', 'p', and 'X' cases,
- but we do not check for those cases. It means that the value
- is a HOST_WIDE_INT, which may be either `int' or `long'. */
-
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
-#else
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
- *q++ = 'l';
-#else
- *q++ = 'l';
- *q++ = 'l';
-#endif
-#endif
-
+ /* This is a prefix to the 'd', 'i', 'u', 'x', 'X', and
+ 'o' cases, but we do not check for those cases. It
+ means that the value is a HOST_WIDE_INT, which may be
+ either `long' or `long long'. */
+ memcpy (q, HOST_WIDE_INT_PRINT, strlen (HOST_WIDE_INT_PRINT));
+ q += strlen (HOST_WIDE_INT_PRINT);
*q++ = *p++;
*q = 0;
fprintf (file, buf, va_arg (argptr, HOST_WIDE_INT));
@@ -3754,17 +3370,22 @@ asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
case 'l':
*q++ = c;
- *q++ = *p++;
- *q = 0;
- fprintf (file, buf, va_arg (argptr, long));
- break;
+#ifdef HAVE_LONG_LONG
+ if (*p == 'l')
+ {
+ *q++ = *p++;
+ *q++ = *p++;
+ *q = 0;
+ fprintf (file, buf, va_arg (argptr, long long));
+ }
+ else
+#endif
+ {
+ *q++ = *p++;
+ *q = 0;
+ fprintf (file, buf, va_arg (argptr, long));
+ }
- case 'e':
- case 'f':
- case 'g':
- *q++ = c;
- *q = 0;
- fprintf (file, buf, va_arg (argptr, double));
break;
case 's':
@@ -3802,7 +3423,7 @@ asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
break;
#ifdef ASM_FPRINTF_EXTENSIONS
- /* Upper case letters are reserved for general use by asm_fprintf
+ /* Uppercase letters are reserved for general use by asm_fprintf
and so are not available to target specific code. In order to
prevent the ASM_FPRINTF_EXTENSIONS macro from using them then,
they are defined here. As they get turned into real extensions
@@ -3821,9 +3442,9 @@ asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
break;
default:
- fputc (c, file);
+ putc (c, file);
}
- VA_CLOSE (argptr);
+ va_end (argptr);
}
/* Split up a CONST_DOUBLE or integer constant rtx
@@ -3832,9 +3453,7 @@ asm_fprintf VPARAMS ((FILE *file, const char *p, ...))
and in *SECOND the other. */
void
-split_double (value, first, second)
- rtx value;
- rtx *first, *second;
+split_double (rtx value, rtx *first, rtx *second)
{
if (GET_CODE (value) == CONST_INT)
{
@@ -3973,7 +3592,7 @@ split_double (value, first, second)
/* Return nonzero if this function has no function calls. */
int
-leaf_function_p ()
+leaf_function_p (void)
{
rtx insn;
rtx link;
@@ -4016,8 +3635,7 @@ leaf_function_p ()
output templates to customary add branch prediction hints.
*/
int
-final_forward_branch_p (insn)
- rtx insn;
+final_forward_branch_p (rtx insn)
{
int insn_id, label_id;
if (!uid_shuid)
@@ -4045,10 +3663,10 @@ final_forward_branch_p (insn)
safely renumbered. */
int
-only_leaf_regs_used ()
+only_leaf_regs_used (void)
{
int i;
- char *permitted_reg_in_leaf_functions = LEAF_REGISTERS;
+ const char *const permitted_reg_in_leaf_functions = LEAF_REGISTERS;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if ((regs_ever_live[i] || global_regs[i])
@@ -4068,8 +3686,7 @@ only_leaf_regs_used ()
available in leaf functions. */
static void
-leaf_renumber_regs (first)
- rtx first;
+leaf_renumber_regs (rtx first)
{
rtx insn;
@@ -4090,8 +3707,7 @@ leaf_renumber_regs (first)
available in leaf functions. */
void
-leaf_renumber_regs_insn (in_rtx)
- rtx in_rtx;
+leaf_renumber_regs_insn (rtx in_rtx)
{
int i, j;
const char *format_ptr;
@@ -4168,3 +3784,85 @@ leaf_renumber_regs_insn (in_rtx)
}
}
#endif
+
+
+/* When -gused is used, emit debug info for only used symbols. But in
+ addition to the standard intercepted debug_hooks there are some direct
+ calls into this file, i.e., dbxout_symbol, dbxout_parms, and dbxout_reg_params.
+ Those routines may also be called from a higher level intercepted routine. So
+ to prevent recording data for an inner call to one of these for an intercept,
+ we maintain an intercept nesting counter (debug_nesting). We only save the
+ intercepted arguments if the nesting is 1. */
+int debug_nesting = 0;
+
+static tree *symbol_queue;
+int symbol_queue_index = 0;
+static int symbol_queue_size = 0;
+
+/* Generate the symbols for any queued up type symbols we encountered
+ while generating the type info for some originally used symbol.
+ This might generate additional entries in the queue. Only when
+ the nesting depth goes to 0 is this routine called. */
+
+void
+debug_flush_symbol_queue (void)
+{
+ int i;
+
+ /* Make sure that additionally queued items are not flushed
+ prematurely. */
+
+ ++debug_nesting;
+
+ for (i = 0; i < symbol_queue_index; ++i)
+ {
+ /* If we pushed queued symbols then such symbols are must be
+ output no matter what anyone else says. Specifically,
+ we need to make sure dbxout_symbol() thinks the symbol was
+ used and also we need to override TYPE_DECL_SUPPRESS_DEBUG
+ which may be set for outside reasons. */
+ int saved_tree_used = TREE_USED (symbol_queue[i]);
+ int saved_suppress_debug = TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]);
+ TREE_USED (symbol_queue[i]) = 1;
+ TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]) = 0;
+
+#ifdef DBX_DEBUGGING_INFO
+ dbxout_symbol (symbol_queue[i], 0);
+#endif
+
+ TREE_USED (symbol_queue[i]) = saved_tree_used;
+ TYPE_DECL_SUPPRESS_DEBUG (symbol_queue[i]) = saved_suppress_debug;
+ }
+
+ symbol_queue_index = 0;
+ --debug_nesting;
+}
+
+/* Queue a type symbol needed as part of the definition of a decl
+ symbol. These symbols are generated when debug_flush_symbol_queue()
+ is called. */
+
+void
+debug_queue_symbol (tree decl)
+{
+ if (symbol_queue_index >= symbol_queue_size)
+ {
+ symbol_queue_size += 10;
+ symbol_queue = xrealloc (symbol_queue,
+ symbol_queue_size * sizeof (tree));
+ }
+
+ symbol_queue[symbol_queue_index++] = decl;
+}
+
+/* Free symbol queue. */
+void
+debug_free_queue (void)
+{
+ if (symbol_queue)
+ {
+ free (symbol_queue);
+ symbol_queue = NULL;
+ symbol_queue_size = 0;
+ }
+}
diff --git a/contrib/gcc/fix-header.c b/contrib/gcc/fix-header.c
index bce334dee038..88390e3e5371 100644
--- a/contrib/gcc/fix-header.c
+++ b/contrib/gcc/fix-header.c
@@ -1,6 +1,6 @@
/* fix-header.c - Make C header file suitable for C++.
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 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
@@ -67,18 +67,22 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
* INFILE.H is a full pathname for the input file (e.g. /usr/include/stdio.h)
* OUTFILE.H is the full pathname for where to write the output file,
if anything needs to be done. (e.g. ./include/stdio.h)
- * OPTIONS are such as you would pass to cpp.
+ * OPTIONS can be -D or -I switches as you would pass to cpp.
Written by Per Bothner <bothner@cygnus.com>, July 1993. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "obstack.h"
#include "scan.h"
#include "cpplib.h"
+#include "c-incpath.h"
-static void v_fatal PARAMS ((const char *, va_list)) ATTRIBUTE_PRINTF (1,0) ATTRIBUTE_NORETURN;
-static void fatal PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+static void v_fatal (const char *, va_list)
+ ATTRIBUTE_PRINTF (1,0) ATTRIBUTE_NORETURN;
+static void fatal (const char *, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
sstring buf;
@@ -86,10 +90,6 @@ int verbose = 0;
int partial_count = 0;
int warnings = 0;
-/* We no longer need to add extern "C", because cpp implicitly
- forces the standard include files to be treated as C. */
-/*#define ADD_MISSING_EXTERN_C 1 */
-
#if ADD_MISSING_EXTERN_C
int missing_extern_C_count = 0;
#endif
@@ -188,23 +188,21 @@ struct symbol_list {
struct symbol_list symbol_table[SYMBOL_TABLE_SIZE];
int cur_symbol_table_size;
-static void add_symbols PARAMS ((symbol_flags, namelist));
-static struct fn_decl *lookup_std_proto PARAMS ((const char *, int));
-static void write_lbrac PARAMS ((void));
-static void recognized_macro PARAMS ((const char *));
-static void check_macro_names PARAMS ((cpp_reader *, namelist));
-static void read_scan_file PARAMS ((char *, int, char **));
-static void write_rbrac PARAMS ((void));
-static int inf_skip_spaces PARAMS ((int));
-static int inf_read_upto PARAMS ((sstring *, int));
-static int inf_scan_ident PARAMS ((sstring *, int));
-static int check_protection PARAMS ((int *, int *));
-static void cb_file_change PARAMS ((cpp_reader *, const struct line_map *));
+static void add_symbols (symbol_flags, namelist);
+static struct fn_decl *lookup_std_proto (const char *, int);
+static void write_lbrac (void);
+static void recognized_macro (const char *);
+static void check_macro_names (cpp_reader *, namelist);
+static void read_scan_file (char *, int, char **);
+static void write_rbrac (void);
+static int inf_skip_spaces (int);
+static int inf_read_upto (sstring *, int);
+static int inf_scan_ident (sstring *, int);
+static int check_protection (int *, int *);
+static void cb_file_change (cpp_reader *, const struct line_map *);
static void
-add_symbols (flags, names)
- symbol_flags flags;
- namelist names;
+add_symbols (symbol_flags flags, namelist names)
{
symbol_table[cur_symbol_table_size].flags = flags;
symbol_table[cur_symbol_table_size].names = names;
@@ -377,9 +375,7 @@ struct obstack scan_file_obstack;
/* NOTE: If you edit this, also edit gen-protos.c !! */
static struct fn_decl *
-lookup_std_proto (name, name_length)
- const char *name;
- int name_length;
+lookup_std_proto (const char *name, int name_length)
{
int i = hashstr (name, name_length) % HASH_SIZE;
int i0 = i;
@@ -410,14 +406,8 @@ int required_unseen_count = 0;
int required_other = 0;
static void
-write_lbrac ()
+write_lbrac (void)
{
-
-#if ADD_MISSING_EXTERN_C
- if (missing_extern_C_count + required_unseen_count > 0)
- fprintf (outf, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
-#endif
-
if (partial_count)
{
fprintf (outf, "#ifndef _PARAMS\n");
@@ -445,8 +435,7 @@ struct partial_proto required_dummy_proto, seen_dummy_proto;
#define SEEN(FN) ((FN)->partial == &seen_dummy_proto)
static void
-recognized_macro (fname)
- const char *fname;
+recognized_macro (const char *fname)
{
/* The original include file defines fname as a macro. */
struct fn_decl *fn = lookup_std_proto (fname, strlen (fname));
@@ -495,8 +484,7 @@ recognized_macro (fname)
}
void
-recognized_extern (name)
- const cpp_token *name;
+recognized_extern (const cpp_token *name)
{
switch (special_file_handling)
{
@@ -516,19 +504,12 @@ recognized_extern (name)
'extern "C"' braces); or 'f' for other function declarations. */
void
-recognized_function (fname, line, kind, have_arg_list)
- const cpp_token *fname;
- unsigned int line;
- int kind; /* One of 'f' 'F' or 'I' */
- int have_arg_list;
+recognized_function (const cpp_token *fname, unsigned int line, int kind,
+ int have_arg_list)
{
struct partial_proto *partial;
int i;
struct fn_decl *fn;
-#if ADD_MISSING_EXTERN_C
- if (kind == 'f')
- missing_extern_C_count++;
-#endif
fn = lookup_std_proto ((const char *) NODE_NAME (fname->val.node),
NODE_LEN (fname->val.node));
@@ -563,8 +544,7 @@ recognized_function (fname, line, kind, have_arg_list)
/* We only have a partial function declaration,
so remember that we have to add a complete prototype. */
partial_count++;
- partial = (struct partial_proto *)
- obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto));
+ partial = obstack_alloc (&scan_file_obstack, sizeof (struct partial_proto));
partial->line_seen = line;
partial->fn = fn;
fn->partial = partial;
@@ -581,9 +561,7 @@ recognized_function (fname, line, kind, have_arg_list)
call recognized_macro on it. */
static void
-check_macro_names (pfile, names)
- cpp_reader *pfile;
- namelist names;
+check_macro_names (cpp_reader *pfile, namelist names)
{
size_t len;
while (*names)
@@ -596,30 +574,26 @@ check_macro_names (pfile, names)
}
static void
-cb_file_change (pfile, map)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
- const struct line_map *map;
+cb_file_change (cpp_reader *pfile ATTRIBUTE_UNUSED,
+ const struct line_map *map)
{
/* Just keep track of current file name. */
- cur_file = map->to_file;
+ cur_file = map == NULL ? NULL : map->to_file;
}
static void
-read_scan_file (in_fname, argc, argv)
- char *in_fname;
- int argc;
- char **argv;
+read_scan_file (char *in_fname, int argc, char **argv)
{
cpp_reader *scan_in;
cpp_callbacks *cb;
cpp_options *options;
struct fn_decl *fn;
- int i;
+ int i, strings_processed;
struct symbol_list *cur_symbols;
obstack_init (&scan_file_obstack);
- scan_in = cpp_create_reader (CLK_GNUC89);
+ scan_in = cpp_create_reader (CLK_GNUC89, NULL);
cb = cpp_get_callbacks (scan_in);
cb->file_change = cb_file_change;
@@ -628,17 +602,55 @@ read_scan_file (in_fname, argc, argv)
options = cpp_get_options (scan_in);
options->inhibit_warnings = 1;
options->inhibit_errors = 1;
+ cpp_post_options (scan_in);
- i = cpp_handle_options (scan_in, argc, argv);
- if (i < argc)
- cpp_error (scan_in, DL_ERROR, "invalid option `%s'", argv[i]);
- if (cpp_errors (scan_in))
+ if (!cpp_read_main_file (scan_in, in_fname))
exit (FATAL_EXIT_CODE);
- if (! cpp_read_main_file (scan_in, in_fname, NULL))
+ cpp_change_file (scan_in, LC_RENAME, "<built-in>");
+ cpp_init_builtins (scan_in, true);
+ cpp_change_file (scan_in, LC_RENAME, in_fname);
+
+ /* Process switches after builtins so -D can override them. */
+ for (i = 0; i < argc; i += strings_processed)
+ {
+ strings_processed = 0;
+ if (argv[i][0] == '-')
+ {
+ if (argv[i][1] == 'I')
+ {
+ if (argv[i][2] != '\0')
+ {
+ strings_processed = 1;
+ add_path (xstrdup (argv[i] + 2), BRACKET, false);
+ }
+ else if (i + 1 != argc)
+ {
+ strings_processed = 2;
+ add_path (xstrdup (argv[i + 1]), BRACKET, false);
+ }
+ }
+ else if (argv[i][1] == 'D')
+ {
+ if (argv[i][2] != '\0')
+ strings_processed = 1, cpp_define (scan_in, argv[i] + 2);
+ else if (i + 1 != argc)
+ strings_processed = 2, cpp_define (scan_in, argv[i + 1]);
+ }
+ }
+
+ if (strings_processed == 0)
+ break;
+ }
+
+ if (i < argc)
+ cpp_error (scan_in, CPP_DL_ERROR, "invalid option `%s'", argv[i]);
+ if (cpp_errors (scan_in))
exit (FATAL_EXIT_CODE);
- cpp_finish_options (scan_in);
+ register_include_chains (scan_in, NULL /* sysroot */, NULL /* iprefix */,
+ true /* stdinc */, false /* cxx_stdinc */,
+ false /* verbose */);
/* We are scanning a system header, so mark it as such. */
cpp_make_system_header (scan_in, 1, 0);
@@ -652,12 +664,12 @@ read_scan_file (in_fname, argc, argv)
if (special_file_handling == stdio_h
&& (fn = lookup_std_proto ("_filbuf", 7)) != NULL)
{
- static const unsigned char getchar_call[] = "getchar();";
+ unsigned char getchar_call[] = "getchar();\n";
int seen_filbuf = 0;
/* Scan the macro expansion of "getchar();". */
cpp_push_buffer (scan_in, getchar_call, sizeof(getchar_call) - 1,
- /* from_stage3 */ true, 1);
+ /* from_stage3 */ true);
for (;;)
{
const cpp_token *t = cpp_get_token (scan_in);
@@ -695,11 +707,7 @@ read_scan_file (in_fname, argc, argv)
}
}
- if (required_unseen_count + partial_count + required_other
-#if ADD_MISSING_EXTERN_C
- + missing_extern_C_count
-#endif
- == 0)
+ if (required_unseen_count + partial_count + required_other == 0)
{
if (verbose)
fprintf (stderr, "%s: OK, nothing needs to be done.\n", inc_filename);
@@ -715,17 +723,11 @@ read_scan_file (in_fname, argc, argv)
if (partial_count)
fprintf (stderr, "%s: %d non-prototype function declarations.\n",
inc_filename, partial_count);
-#if ADD_MISSING_EXTERN_C
- if (missing_extern_C_count)
- fprintf (stderr,
- "%s: %d declarations not protected by extern \"C\".\n",
- inc_filename, missing_extern_C_count);
-#endif
}
}
static void
-write_rbrac ()
+write_rbrac (void)
{
struct fn_decl *fn;
const char *cptr;
@@ -852,11 +854,6 @@ write_rbrac ()
break;
}
-
-#if ADD_MISSING_EXTERN_C
- if (missing_extern_C_count + required_unseen_count > 0)
- fprintf (outf, "#ifdef __cplusplus\n}\n#endif\n");
-#endif
}
/* Returns 1 iff the file is properly protected from multiple inclusion:
@@ -870,8 +867,7 @@ write_rbrac ()
#define INF_UNGET(c) ((c)!=EOF && inf_ptr--)
static int
-inf_skip_spaces (c)
- int c;
+inf_skip_spaces (int c)
{
for (;;)
{
@@ -909,9 +905,7 @@ inf_skip_spaces (c)
/* Read into STR from inf_buffer upto DELIM. */
static int
-inf_read_upto (str, delim)
- sstring *str;
- int delim;
+inf_read_upto (sstring *str, int delim)
{
int ch;
for (;;)
@@ -927,9 +921,7 @@ inf_read_upto (str, delim)
}
static int
-inf_scan_ident (s, c)
- sstring *s;
- int c;
+inf_scan_ident (sstring *s, int c)
{
s->ptr = s->base;
if (ISIDST (c))
@@ -953,8 +945,7 @@ inf_scan_ident (s, c)
Otherwise return 0. */
static int
-check_protection (ifndef_line, endif_line)
- int *ifndef_line, *endif_line;
+check_protection (int *ifndef_line, int *endif_line)
{
int c;
int if_nesting = 1; /* Level of nesting of #if's */
@@ -1055,12 +1046,10 @@ check_protection (ifndef_line, endif_line)
return 1;
}
-extern int main PARAMS ((int, char **));
+extern int main (int, char **);
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
int inf_fd;
struct stat sbuf;
@@ -1180,7 +1169,7 @@ main (argc, argv)
exit (FATAL_EXIT_CODE);
}
inf_size = sbuf.st_size;
- inf_buffer = (char *) xmalloc (inf_size + 2);
+ inf_buffer = xmalloc (inf_size + 2);
inf_ptr = inf_buffer;
to_read = inf_size;
@@ -1303,9 +1292,7 @@ main (argc, argv)
static void
-v_fatal (str, ap)
- const char * str;
- va_list ap;
+v_fatal (const char *str, va_list ap)
{
fprintf (stderr, "%s: %s: ", progname, inc_filename);
vfprintf (stderr, str, ap);
@@ -1315,11 +1302,11 @@ v_fatal (str, ap)
}
static void
-fatal VPARAMS ((const char *str, ...))
+fatal (const char *str, ...)
{
- VA_OPEN (ap, str);
- VA_FIXEDARG (ap, const char *, str);
-
+ va_list ap;
+
+ va_start (ap, str);
v_fatal (str, ap);
- VA_CLOSE (ap);
+ va_end (ap);
}
diff --git a/contrib/gcc/fixproto b/contrib/gcc/fixproto
index 5f84880a117c..8bffaa9110f0 100755
--- a/contrib/gcc/fixproto
+++ b/contrib/gcc/fixproto
@@ -4,7 +4,8 @@
# fixproto TARGET-DIR SOURCE-DIR-ALL SOURCE-DIR-STD
#
# COPYRIGHT
-# Copyright (C) 1993, 1994, 1997, 1998, 2002 Free Software Foundation, Inc.
+# Copyright (C) 1993, 1994, 1997, 1998, 2002, 2003
+# Free Software Foundation, Inc.
# This file is part of GCC.
#
# GCC is free software; you can redistribute it and/or modify
@@ -133,13 +134,6 @@ if [ `echo $* | wc -w` != 0 ] ; then
done
fi
-required_stdlib_h="abort abs atexit atof atoi atol bsearch calloc exit free getenv labs malloc putenv qsort rand realloc srand strtod strtol strtoul system"
-# "div ldiv", - ignored because these depend on div_t, ldiv_t
-# ignore these: "mblen mbstowcs mbstowc wcstombs wctomb"
-# Left out getgroups, because SunOS4 has incompatible BSD and SVR4 versions.
-# Should perhaps also add NULL
-required_unistd_h="_exit access alarm chdir chown close ctermid cuserid dup dup2 execl execle execlp execv execve execvp fork fpathconf getcwd getegid geteuid getgid getlogin getopt getpgrp getpid getppid getuid isatty link lseek pathconf pause pipe read rmdir setgid setpgid setsid setuid sleep sysconf tcgetpgrp tcsetpgrp ttyname unlink write"
-
done_dirs=""
subdirs_made=""
echo "" >fixproto.list
@@ -283,35 +277,57 @@ done
# This might be more cleanly moved into the main loop, by adding
# a <dummy> source directory at the end. FIXME!
-for rel_source_file in unistd.h stdlib.h
-do
- if grep "$rel_source_file" fixproto.list >/dev/null
- then true
+
+# All the headers we create define size_t and NULL.
+for rel_source_file in unistd.h stdlib.h string.h time.h ; do
+ if grep "$rel_source_file" fixproto.list >/dev/null ; then
+ : # It exists, we don't need to make it
else
echo Adding missing $rel_source_file
rel_source_ident=`echo $rel_source_file | tr ./ __`
- required_list=`eval echo '${required_'${rel_source_ident}'-}'`
cat >tmp.h <<EOF
+/* Fake ${rel_source_file}, created by GCC.
+ The functions declared in this file do not necessarily exist in
+ your C library. */
#ifndef __${rel_source_ident}
#define __${rel_source_ident}
-EOF
- if test $rel_source_file = stdlib.h
- then
- # Make sure it contains a definition of size_t.
- cat >>tmp.h <<EOF
+#define __need_NULL
#define __need_size_t
#include <stddef.h>
EOF
- fi
+ # Insert special stuff for particular files here.
+ case ${rel_source_file} in
+ time.h)
+ # If time.h doesn't exist, find out if sys/time.h does.
+ if test -f $src_dir_std/sys/time.h \
+ || grep "sys/time.h" fixproto.list >/dev/null ; then
+ # It does; include it and hope it has the needed declarations.
+ # Some versions require sys/types.h.
+ cat >>tmp.h <<EOF
+
+#include <sys/types.h>
+#include <sys/time.h>
+EOF
+ else
+ # It doesn't. Make up plausible definitions for time_t, clock_t.
+ # Forward-declare struct tm. Hope nobody tries to use it. (Odds
+ # are they won't.)
+ cat >>tmp.h <<EOF
+
+typedef long time_t;
+typedef long clock_t;
+struct tm;
+EOF
+ fi ;;
+ esac
cat >>tmp.h <<EOF
#endif /* __${rel_source_ident} */
EOF
${FIX_HEADER} $rel_source_file tmp.h $abs_target_dir/$rel_source_file ${DEFINES} $include_path
if test $? != 0 ; then exit 1 ; fi
- if test -f $abs_target_dir/$rel_source_file
- then
+ if test -f $abs_target_dir/$rel_source_file ; then
rm tmp.h
else
mv tmp.h $abs_target_dir/$rel_source_file
diff --git a/contrib/gcc/flags.h b/contrib/gcc/flags.h
index 0a8979d2dc9e..e947f2a66bb2 100644
--- a/contrib/gcc/flags.h
+++ b/contrib/gcc/flags.h
@@ -1,5 +1,6 @@
/* Compilation switch flag definitions for GCC.
- Copyright (C) 1987, 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002
+ Copyright (C) 1987, 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+ 2003
Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,9 +23,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_FLAGS_H
#define GCC_FLAGS_H
-/* Name of the input .c file being compiled. */
-extern const char *main_input_filename;
-
enum debug_info_type
{
NO_DEBUG, /* Write no debug info. */
@@ -41,6 +39,9 @@ enum debug_info_type
/* Specify which kind of debugging info to generate. */
extern enum debug_info_type write_symbols;
+/* Names of debug_info_type, for error messages. */
+extern const char *const debug_type_names[];
+
enum debug_info_level
{
DINFO_LEVEL_NONE, /* Write no debugging info. */
@@ -54,7 +55,10 @@ extern enum debug_info_level debug_info_level;
/* Nonzero means use GNU-only extensions in the generated symbolic
debugging information. */
-extern int use_gnu_debug_info_extensions;
+extern bool use_gnu_debug_info_extensions;
+
+/* Nonzero means emit debugging information only for symbols which are used. */
+extern int flag_debug_only_used_symbols;
/* Nonzero means do optimizations. -opt. */
@@ -69,10 +73,6 @@ extern int optimize_size;
extern int quiet_flag;
-/* Print times taken by the various passes. -ftime-report. */
-
-extern int time_report;
-
/* Print memory still in use at end of compilation (which may have little
to do with peak memory consumption). -fmem-report. */
@@ -80,65 +80,62 @@ extern int mem_report;
/* Don't print warning messages. -w. */
-extern int inhibit_warnings;
+extern bool inhibit_warnings;
/* Don't suppress warnings from system headers. -Wsystem-headers. */
-extern int warn_system_headers;
+extern bool warn_system_headers;
+
+/* Do print extra warnings (such as for uninitialized variables).
+ -W/-Wextra. */
-/* Do print extra warnings (such as for uninitialized variables). -W. */
+extern bool extra_warnings;
-extern int extra_warnings;
+/* If -Werror. */
+
+extern bool warnings_are_errors;
/* Nonzero to warn about unused variables, functions et.al. Use
set_Wunused() to update the -Wunused-* flags that correspond to the
-Wunused option. */
-extern void set_Wunused PARAMS ((int setting));
+extern void set_Wunused (int setting);
-extern int warn_unused_function;
-extern int warn_unused_label;
-extern int warn_unused_parameter;
-extern int warn_unused_variable;
-extern int warn_unused_value;
+extern bool warn_unused_function;
+extern bool warn_unused_label;
+extern bool warn_unused_parameter;
+extern bool warn_unused_variable;
+extern bool warn_unused_value;
/* Nonzero to warn about code which is never reached. */
-extern int warn_notreached;
+extern bool warn_notreached;
/* Nonzero means warn if inline function is too large. */
-extern int warn_inline;
+extern bool warn_inline;
/* Nonzero to warn about variables used before they are initialized. */
extern int warn_uninitialized;
-/* Zero if unknown pragmas are ignored
- One if the compiler should warn about an unknown pragma not in
- a system include file.
- Greater than one if the compiler should warn for all unknown
- pragmas. */
-
-extern int warn_unknown_pragmas;
-
/* Nonzero means warn about all declarations which shadow others. */
-extern int warn_shadow;
+extern bool warn_shadow;
/* Warn if a switch on an enum, that does not have a default case,
fails to have a case for every enum value. */
-extern int warn_switch;
+extern bool warn_switch;
/* Warn if a switch does not have a default case. */
-extern int warn_switch_default;
+extern bool warn_switch_default;
/* Warn if a switch on an enum fails to have a case for every enum
value (regardless of the presence or otherwise of a default case). */
-extern int warn_switch_enum;
+extern bool warn_switch_enum;
/* Nonzero means warn about function definitions that default the return type
or that use a null return and have a return-type other than void. */
@@ -147,47 +144,47 @@ extern int warn_return_type;
/* Warn about functions which might be candidates for attribute noreturn. */
-extern int warn_missing_noreturn;
+extern bool warn_missing_noreturn;
/* Nonzero means warn about pointer casts that increase the required
alignment of the target type (and might therefore lead to a crash
due to a misaligned access). */
-extern int warn_cast_align;
+extern bool warn_cast_align;
/* Nonzero means warn about any objects definitions whose size is larger
than N bytes. Also want about function definitions whose returned
values are larger than N bytes. The value N is in `larger_than_size'. */
-extern int warn_larger_than;
+extern bool warn_larger_than;
extern HOST_WIDE_INT larger_than_size;
/* Warn if a function returns an aggregate,
since there are often incompatible calling conventions for doing this. */
-extern int warn_aggregate_return;
+extern bool warn_aggregate_return;
/* Warn if packed attribute on struct is unnecessary and inefficient. */
-extern int warn_packed;
+extern bool warn_packed;
/* Warn when gcc pads a structure to an alignment boundary. */
-extern int warn_padded;
+extern bool warn_padded;
/* Warn when an optimization pass is disabled. */
-extern int warn_disabled_optimization;
+extern bool warn_disabled_optimization;
/* Nonzero means warn about uses of __attribute__((deprecated))
declarations. */
-extern int warn_deprecated_decl;
+extern bool warn_deprecated_decl;
/* Nonzero means warn about constructs which might not be strict
aliasing safe. */
-extern int warn_strict_aliasing;
+extern bool warn_strict_aliasing;
/* Nonzero if generating code to do profiling. */
@@ -197,6 +194,10 @@ extern int profile_flag;
extern int profile_arc_flag;
+/* Nonzero if value profile should be measured. */
+
+extern int flag_profile_values;
+
/* Nonzero if generating info for gcov to calculate line test coverage. */
extern int flag_test_coverage;
@@ -281,12 +282,12 @@ extern int flag_strength_reduce;
UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are
unrolled. */
-extern int flag_unroll_loops;
+extern int flag_old_unroll_loops;
/* Nonzero enables loop unrolling in unroll.c. All loops are unrolled.
This is generally not a win. */
-extern int flag_unroll_all_loops;
+extern int flag_old_unroll_all_loops;
/* Nonzero forces all invariant computations in loops to be moved
outside the loop. */
@@ -336,18 +337,6 @@ extern int flag_omit_frame_pointer;
extern int flag_no_peephole;
-/* Nonzero means all references through pointers are volatile. */
-
-extern int flag_volatile;
-
-/* Nonzero means treat all global and extern variables as volatile. */
-
-extern int flag_volatile_global;
-
-/* Nonzero means treat all static variables as volatile. */
-
-extern int flag_volatile_static;
-
/* Nonzero allows GCC to optimize sibling and tail recursive calls. */
extern int flag_optimize_sibling_calls;
@@ -374,6 +363,11 @@ extern int flag_finite_math_only;
extern int flag_trapping_math;
+/* Nonzero means disable transformations that assume default floating
+ point rounding behavior. */
+
+extern int flag_rounding_math;
+
/* 0 means straightforward implementation of complex divide acceptable.
1 means wide ranges of inputs must work for complex divide.
2 means C99-like requirements for complex divide (not yet implemented). */
@@ -427,6 +421,8 @@ extern int flag_shared_data;
extern int flag_schedule_insns;
extern int flag_schedule_insns_after_reload;
+extern int flag_sched2_use_superblocks;
+extern int flag_sched2_use_traces;
/* The following flags have effect only for scheduling before register
allocation:
@@ -443,6 +439,20 @@ extern int flag_schedule_speculative;
extern int flag_schedule_speculative_load;
extern int flag_schedule_speculative_load_dangerous;
+/* The following flags have an effect during scheduling after register
+ allocation:
+
+ sched_stalled_insns means that insns can be moved prematurely from the queue
+ of stalled insns into the ready list.
+
+ sched_stalled_insns_dep controls how many recently scheduled cycles will
+ be examined for a dependency on a stalled insn that is candidate for
+ premature removal from the queue of stalled insns into the ready list (has
+ an effect only if the flag 'sched_stalled_insns' is set). */
+
+extern int flag_sched_stalled_insns;
+extern int flag_sched_stalled_insns_dep;
+
/* flag_branch_on_count_reg means try to replace add-1,compare,branch tupple
by a cheaper branch, on a count register. */
extern int flag_branch_on_count_reg;
@@ -472,16 +482,26 @@ extern int flag_pedantic_errors;
extern int flag_pic;
+/* Nonzero if we are compiling position independent code for executable.
+ 1 vs 2 for a target-dependent "small" or "large" mode. */
+
+extern int flag_pie;
+
+/* Nonzero if we are compiling code for a shared library, zero for
+ executable. */
+
+extern int flag_shlib;
+
/* Nonzero means generate extra code for exception handling and enable
exception handling. */
extern int flag_exceptions;
-/* Nonzero means generate frame unwind info table when supported */
+/* Nonzero means generate frame unwind info table when supported. */
extern int flag_unwind_tables;
-/* Nonzero means generate frame unwind info table exact at each insn boundary */
+/* Nonzero means generate frame unwind info table exact at each insn boundary. */
extern int flag_asynchronous_unwind_tables;
@@ -525,9 +545,9 @@ extern int flag_debug_asm;
extern int flag_dump_rtl_in_asm;
-/* -fgnu-linker specifies use of the GNU linker for initializations.
- -fno-gnu-linker says that collect will be used. */
-extern int flag_gnu_linker;
+/* Greater than zero if user symbols are prepended by a leading underscore
+ in generated assembly code. */
+extern int flag_leading_underscore;
/* Tag all structures with __attribute__(packed) */
extern int flag_pack_struct;
@@ -560,7 +580,7 @@ extern int flag_instrument_function_entry_exit;
/* Perform a peephole pass before sched2. */
extern int flag_peephole2;
-/* Try to guess branch probablities. */
+/* Try to guess branch probabilities. */
extern int flag_guess_branch_prob;
/* -fcheck-bounds causes gcc to generate array bounds checks.
@@ -591,9 +611,15 @@ extern int frame_pointer_needed;
for PLUS / SUB / MULT. */
extern int flag_trapv;
+/* Nonzero if the signed arithmetic overflow should wrap around. */
+extern int flag_wrapv;
+
+/* Nonzero if subexpressions must be evaluated from left-to-right. */
+extern int flag_evaluation_order;
+
/* Value of the -G xx switch, and whether it was passed or not. */
-extern int g_switch_value;
-extern int g_switch_set;
+extern unsigned HOST_WIDE_INT g_switch_value;
+extern bool g_switch_set;
/* Values of the -falign-* flags: how much to align labels in code.
0 means `use default', 1 means `don't align'.
@@ -633,6 +659,10 @@ extern enum graph_dump_types graph_dump_format;
extern int flag_no_ident;
+/* Nonzero means perform global CSE. */
+
+extern int flag_gcse;
+
/* Nonzero if we want to perform enhanced load motion during gcse. */
extern int flag_gcse_lm;
@@ -641,11 +671,33 @@ extern int flag_gcse_lm;
extern int flag_gcse_sm;
+/* Nonzero if we want to perform redundant load-after-store elimination
+ in gcse. */
+
+extern int flag_gcse_las;
+
+/* Nonzero if value histograms should be used to optimize code. */
+extern int flag_value_profile_transformations;
+
+/* Perform branch target register optimization before prologue / epilogue
+ threading. */
+
+extern int flag_branch_target_load_optimize;
+
+/* Perform branch target register optimization after prologue / epilogue
+ threading and jump2. */
+
+extern int flag_branch_target_load_optimize2;
+
/* Nonzero means we should do dwarf2 duplicate elimination. */
extern int flag_eliminate_dwarf2_dups;
+/* Nonzero means we should do unused type elimination. */
+
+extern int flag_eliminate_unused_debug_types;
+
/* Nonzero means to collect statistics which might be expensive
and to print them when we are done. */
extern int flag_detailed_statistics;
@@ -659,11 +711,40 @@ extern int flag_zero_initialized_in_bss;
/* Nonzero means disable transformations observable by signaling NaNs. */
extern int flag_signaling_nans;
+extern int flag_unit_at_a_time;
+
+extern int flag_web;
+
+/* Nonzero means that we defer emitting functions until they are actually
+ used. */
+extern int flag_remove_unreachable_functions;
+
/* A string that's used when a random name is required. NULL means
to make it really random. */
extern const char *flag_random_seed;
+/* The version of the C++ ABI in use. The following values are
+ allowed:
+
+ 0: The version of the ABI believed most conformant with the
+ C++ ABI specification. This ABI may change as bugs are
+ discovered and fixed. Therefore, 0 will not necessarily
+ indicate the same ABI in different versions of G++.
+
+ 1: The version of the ABI first used in G++ 3.2.
+
+ Additional positive integers will be assigned as new versions of
+ the ABI become the default version of the ABI. */
+
+extern int flag_abi_version;
+
+/* Returns TRUE if generated code should match ABI version N or
+ greater is in use. */
+
+#define abi_version_at_least(N) \
+ (flag_abi_version == 0 || flag_abi_version >= (N))
+
/* True if the given mode has a NaN representation and the treatment of
NaN operands is important. Certain optimizations, such as folding
x * 0 into x, are not correct for NaN operands, and are normally
@@ -681,13 +762,13 @@ extern const char *flag_random_seed;
(MODE_HAS_INFINITIES (MODE) && !flag_finite_math_only)
/* Like HONOR_NANS, but true if the given mode distinguishes between
- postive and negative zero, and the sign of zero is important. */
+ positive and negative zero, and the sign of zero is important. */
#define HONOR_SIGNED_ZEROS(MODE) \
(MODE_HAS_SIGNED_ZEROS (MODE) && !flag_unsafe_math_optimizations)
/* Like HONOR_NANS, but true if given mode supports sign-dependent rounding,
and the rounding mode is important. */
#define HONOR_SIGN_DEPENDENT_ROUNDING(MODE) \
- (MODE_HAS_SIGN_DEPENDENT_ROUNDING (MODE) && !flag_unsafe_math_optimizations)
+ (MODE_HAS_SIGN_DEPENDENT_ROUNDING (MODE) && flag_rounding_math)
#endif /* ! GCC_FLAGS_H */
diff --git a/contrib/gcc/flow.c b/contrib/gcc/flow.c
index 7882b25ae9a8..90bc5f871dfc 100644
--- a/contrib/gcc/flow.c
+++ b/contrib/gcc/flow.c
@@ -1,6 +1,6 @@
/* Data flow analysis for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -120,6 +120,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
@@ -134,20 +136,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "recog.h"
#include "expr.h"
-#include "ssa.h"
#include "timevar.h"
#include "obstack.h"
#include "splay-tree.h"
-/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
- the stack pointer does not matter. The value is tested only in
- functions that have frame pointers.
- No definition is equivalent to always zero. */
-#ifndef EXIT_IGNORE_STACK
-#define EXIT_IGNORE_STACK 0
-#endif
-
#ifndef HAVE_epilogue
#define HAVE_epilogue 0
#endif
@@ -158,9 +151,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define HAVE_sibcall_epilogue 0
#endif
-#ifndef LOCAL_REGNO
-#define LOCAL_REGNO(REGNO) 0
-#endif
#ifndef EPILOGUE_USES
#define EPILOGUE_USES(REGNO) 0
#endif
@@ -204,7 +194,7 @@ rtx regs_may_share;
/* Callback that determines if it's ok for a function to have no
noreturn attribute. */
-int (*lang_missing_noreturn_ok_p) PARAMS ((tree));
+int (*lang_missing_noreturn_ok_p) (tree);
/* Set of registers that may be eliminable. These are handled specially
in updating regs_ever_live. */
@@ -272,7 +262,7 @@ struct propagate_block_info
/* Nonzero if the value of CC0 is live. */
int cc0_live;
- /* Flags controling the set of information propagate_block collects. */
+ /* Flags controlling the set of information propagate_block collects. */
int flags;
};
@@ -284,65 +274,52 @@ static int ndead;
#define MAX_MEM_SET_LIST_LEN 100
/* Forward declarations */
-static int verify_wide_reg_1 PARAMS ((rtx *, void *));
-static void verify_wide_reg PARAMS ((int, basic_block));
-static void verify_local_live_at_start PARAMS ((regset, basic_block));
-static void notice_stack_pointer_modification_1 PARAMS ((rtx, rtx, void *));
-static void notice_stack_pointer_modification PARAMS ((rtx));
-static void mark_reg PARAMS ((rtx, void *));
-static void mark_regs_live_at_end PARAMS ((regset));
-static int set_phi_alternative_reg PARAMS ((rtx, int, int, void *));
-static void calculate_global_regs_live PARAMS ((sbitmap, sbitmap, int));
-static void propagate_block_delete_insn PARAMS ((rtx));
-static rtx propagate_block_delete_libcall PARAMS ((rtx, rtx));
-static int insn_dead_p PARAMS ((struct propagate_block_info *,
- rtx, int, rtx));
-static int libcall_dead_p PARAMS ((struct propagate_block_info *,
- rtx, rtx));
-static void mark_set_regs PARAMS ((struct propagate_block_info *,
- rtx, rtx));
-static void mark_set_1 PARAMS ((struct propagate_block_info *,
- enum rtx_code, rtx, rtx,
- rtx, int));
-static int find_regno_partial PARAMS ((rtx *, void *));
+static int verify_wide_reg_1 (rtx *, void *);
+static void verify_wide_reg (int, basic_block);
+static void verify_local_live_at_start (regset, basic_block);
+static void notice_stack_pointer_modification_1 (rtx, rtx, void *);
+static void notice_stack_pointer_modification (rtx);
+static void mark_reg (rtx, void *);
+static void mark_regs_live_at_end (regset);
+static void calculate_global_regs_live (sbitmap, sbitmap, int);
+static void propagate_block_delete_insn (rtx);
+static rtx propagate_block_delete_libcall (rtx, rtx);
+static int insn_dead_p (struct propagate_block_info *, rtx, int, rtx);
+static int libcall_dead_p (struct propagate_block_info *, rtx, rtx);
+static void mark_set_regs (struct propagate_block_info *, rtx, rtx);
+static void mark_set_1 (struct propagate_block_info *, enum rtx_code, rtx,
+ rtx, rtx, int);
+static int find_regno_partial (rtx *, void *);
#ifdef HAVE_conditional_execution
-static int mark_regno_cond_dead PARAMS ((struct propagate_block_info *,
- int, rtx));
-static void free_reg_cond_life_info PARAMS ((splay_tree_value));
-static int flush_reg_cond_reg_1 PARAMS ((splay_tree_node, void *));
-static void flush_reg_cond_reg PARAMS ((struct propagate_block_info *,
- int));
-static rtx elim_reg_cond PARAMS ((rtx, unsigned int));
-static rtx ior_reg_cond PARAMS ((rtx, rtx, int));
-static rtx not_reg_cond PARAMS ((rtx));
-static rtx and_reg_cond PARAMS ((rtx, rtx, int));
+static int mark_regno_cond_dead (struct propagate_block_info *, int, rtx);
+static void free_reg_cond_life_info (splay_tree_value);
+static int flush_reg_cond_reg_1 (splay_tree_node, void *);
+static void flush_reg_cond_reg (struct propagate_block_info *, int);
+static rtx elim_reg_cond (rtx, unsigned int);
+static rtx ior_reg_cond (rtx, rtx, int);
+static rtx not_reg_cond (rtx);
+static rtx and_reg_cond (rtx, rtx, int);
#endif
#ifdef AUTO_INC_DEC
-static void attempt_auto_inc PARAMS ((struct propagate_block_info *,
- rtx, rtx, rtx, rtx, rtx));
-static void find_auto_inc PARAMS ((struct propagate_block_info *,
- rtx, rtx));
-static int try_pre_increment_1 PARAMS ((struct propagate_block_info *,
- rtx));
-static int try_pre_increment PARAMS ((rtx, rtx, HOST_WIDE_INT));
+static void attempt_auto_inc (struct propagate_block_info *, rtx, rtx, rtx,
+ rtx, rtx);
+static void find_auto_inc (struct propagate_block_info *, rtx, rtx);
+static int try_pre_increment_1 (struct propagate_block_info *, rtx);
+static int try_pre_increment (rtx, rtx, HOST_WIDE_INT);
#endif
-static void mark_used_reg PARAMS ((struct propagate_block_info *,
- rtx, rtx, rtx));
-static void mark_used_regs PARAMS ((struct propagate_block_info *,
- rtx, rtx, rtx));
-void dump_flow_info PARAMS ((FILE *));
-void debug_flow_info PARAMS ((void));
-static void add_to_mem_set_list PARAMS ((struct propagate_block_info *,
- rtx));
-static int invalidate_mems_from_autoinc PARAMS ((rtx *, void *));
-static void invalidate_mems_from_set PARAMS ((struct propagate_block_info *,
- rtx));
-static void clear_log_links PARAMS ((sbitmap));
+static void mark_used_reg (struct propagate_block_info *, rtx, rtx, rtx);
+static void mark_used_regs (struct propagate_block_info *, rtx, rtx, rtx);
+void debug_flow_info (void);
+static void add_to_mem_set_list (struct propagate_block_info *, rtx);
+static int invalidate_mems_from_autoinc (rtx *, void *);
+static void invalidate_mems_from_set (struct propagate_block_info *, rtx);
+static void clear_log_links (sbitmap);
+static int count_or_remove_death_notes_bb (basic_block, int);
void
-check_function_return_warnings ()
+check_function_return_warnings (void)
{
if (warn_missing_noreturn
&& !TREE_THIS_VOLATILE (cfun->decl)
@@ -386,13 +363,12 @@ check_function_return_warnings ()
note associated with the BLOCK. */
rtx
-first_insn_after_basic_block_note (block)
- basic_block block;
+first_insn_after_basic_block_note (basic_block block)
{
rtx insn;
/* Get the first instruction in the block. */
- insn = block->head;
+ insn = BB_HEAD (block);
if (insn == NULL_RTX)
return NULL_RTX;
@@ -409,10 +385,7 @@ first_insn_after_basic_block_note (block)
to be used in accumulating flow info. */
void
-life_analysis (f, file, flags)
- rtx f;
- FILE *file;
- int flags;
+life_analysis (rtx f, FILE *file, int flags)
{
#ifdef ELIMINABLE_REGS
int i;
@@ -433,7 +406,8 @@ life_analysis (f, file, flags)
#ifdef CANNOT_CHANGE_MODE_CLASS
- bitmap_initialize (&subregs_of_mode, 1);
+ if (flags & PROP_REG_INFO)
+ bitmap_initialize (&subregs_of_mode, 1);
#endif
if (! optimize)
@@ -479,7 +453,10 @@ life_analysis (f, file, flags)
is not immediately handy. */
if (flags & PROP_REG_INFO)
- memset (regs_ever_live, 0, sizeof (regs_ever_live));
+ {
+ memset (regs_ever_live, 0, sizeof (regs_ever_live));
+ memset (regs_asm_clobbered, 0, sizeof (regs_asm_clobbered));
+ }
update_life_info (NULL, UPDATE_LIFE_GLOBAL, flags);
/* Clean up. */
@@ -500,9 +477,7 @@ life_analysis (f, file, flags)
word_mode. */
static int
-verify_wide_reg_1 (px, pregno)
- rtx *px;
- void *pregno;
+verify_wide_reg_1 (rtx *px, void *pregno)
{
rtx x = *px;
unsigned int regno = *(int *) pregno;
@@ -520,11 +495,9 @@ verify_wide_reg_1 (px, pregno)
of BB looking for register REGNO. */
static void
-verify_wide_reg (regno, bb)
- int regno;
- basic_block bb;
+verify_wide_reg (int regno, basic_block bb)
{
- rtx head = bb->head, end = bb->end;
+ rtx head = BB_HEAD (bb), end = BB_END (bb);
while (1)
{
@@ -553,9 +526,7 @@ verify_wide_reg (regno, bb)
changes in live_at_start during a local update. */
static void
-verify_local_live_at_start (new_live_at_start, bb)
- regset new_live_at_start;
- basic_block bb;
+verify_local_live_at_start (regset new_live_at_start, basic_block bb)
{
if (reload_completed)
{
@@ -605,7 +576,7 @@ verify_local_live_at_start (new_live_at_start, bb)
/* Updates life information starting with the basic blocks set in BLOCKS.
If BLOCKS is null, consider it to be the universal set.
- If EXTENT is UPDATE_LIFE_LOCAL, such as after splitting or peepholeing,
+ If EXTENT is UPDATE_LIFE_LOCAL, such as after splitting or peepholing,
we are only expecting local modifications to basic blocks. If we find
extra registers live at the beginning of a block, then we either killed
useful data, or we have a broken split that wants data not provided.
@@ -616,14 +587,14 @@ verify_local_live_at_start (new_live_at_start, bb)
generates subregs of a multi-word pseudo, current life analysis will
lose the kill. So we _can_ have a pseudo go live. How irritating.
+ It is also not true when a peephole decides that it doesn't need one
+ or more of the inputs.
+
Including PROP_REG_INFO does not properly refresh regs_ever_live
unless the caller resets it to zero. */
int
-update_life_info (blocks, extent, prop_flags)
- sbitmap blocks;
- enum update_life_extent extent;
- int prop_flags;
+update_life_info (sbitmap blocks, enum update_life_extent extent, int prop_flags)
{
regset tmp;
regset_head tmp_head;
@@ -686,6 +657,16 @@ update_life_info (blocks, extent, prop_flags)
partial improvement (see MAX_MEM_SET_LIST_LEN usage).
Further improvement may be possible. */
cleanup_cfg (CLEANUP_EXPENSIVE);
+
+ /* Zap the life information from the last round. If we don't
+ do this, we can wind up with registers that no longer appear
+ in the code being marked live at entry, which twiggs bogus
+ warnings from regno_uninitialized. */
+ FOR_EACH_BB (bb)
+ {
+ CLEAR_REG_SET (bb->global_live_at_start);
+ CLEAR_REG_SET (bb->global_live_at_end);
+ }
}
/* If asked, remove notes from the blocks we'll update. */
@@ -763,9 +744,7 @@ update_life_info (blocks, extent, prop_flags)
/* Update life information in all blocks where BB_DIRTY is set. */
int
-update_life_info_in_dirty_blocks (extent, prop_flags)
- enum update_life_extent extent;
- int prop_flags;
+update_life_info_in_dirty_blocks (enum update_life_extent extent, int prop_flags)
{
sbitmap update_life_blocks = sbitmap_alloc (last_basic_block);
int n = 0;
@@ -805,8 +784,7 @@ update_life_info_in_dirty_blocks (extent, prop_flags)
KEEP_HEAD_END_P is nonzero if basic_block_info is not to be freed. */
void
-free_basic_block_vars (keep_head_end_p)
- int keep_head_end_p;
+free_basic_block_vars (int keep_head_end_p)
{
if (! keep_head_end_p)
{
@@ -828,8 +806,7 @@ free_basic_block_vars (keep_head_end_p)
/* Delete any insns that copy a register to itself. */
int
-delete_noop_moves (f)
- rtx f ATTRIBUTE_UNUSED;
+delete_noop_moves (rtx f ATTRIBUTE_UNUSED)
{
rtx insn, next;
basic_block bb;
@@ -837,7 +814,7 @@ delete_noop_moves (f)
FOR_EACH_BB (bb)
{
- for (insn = bb->head; insn != NEXT_INSN (bb->end); insn = next)
+ for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); insn = next)
{
next = NEXT_INSN (insn);
if (INSN_P (insn) && noop_move_p (insn))
@@ -874,7 +851,7 @@ delete_noop_moves (f)
insns computing the destination, so we delay deleting and garbagecollect
them once life information is computed. */
void
-delete_dead_jumptables ()
+delete_dead_jumptables (void)
{
rtx insn, next;
for (insn = get_insns (); insn; insn = next)
@@ -899,10 +876,8 @@ delete_dead_jumptables ()
Only useful before prologues have been emitted. */
static void
-notice_stack_pointer_modification_1 (x, pat, data)
- rtx x;
- rtx pat ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+notice_stack_pointer_modification_1 (rtx x, rtx pat ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
{
if (x == stack_pointer_rtx
/* The stack pointer is only modified indirectly as the result
@@ -915,8 +890,7 @@ notice_stack_pointer_modification_1 (x, pat, data)
}
static void
-notice_stack_pointer_modification (f)
- rtx f;
+notice_stack_pointer_modification (rtx f)
{
rtx insn;
@@ -943,9 +917,7 @@ notice_stack_pointer_modification (f)
of their component registers set as well. */
static void
-mark_reg (reg, xset)
- rtx reg;
- void *xset;
+mark_reg (rtx reg, void *xset)
{
regset set = (regset) xset;
int regno = REGNO (reg);
@@ -966,14 +938,13 @@ mark_reg (reg, xset)
at the end of the last basic block. */
static void
-mark_regs_live_at_end (set)
- regset set;
+mark_regs_live_at_end (regset set)
{
unsigned int i;
/* If exiting needs the right stack value, consider the stack pointer
live at the end of the function. */
- if ((HAVE_epilogue && reload_completed)
+ if ((HAVE_epilogue && epilogue_completed)
|| ! EXIT_IGNORE_STACK
|| (! FRAME_POINTER_REQUIRED
&& ! current_function_calls_alloca
@@ -1001,7 +972,7 @@ mark_regs_live_at_end (set)
/* Many architectures have a GP register even without flag_pic.
Assume the pic register is not in use, or will be handled by
other means, if it is not fixed. */
- if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
+ if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
&& fixed_regs[PIC_OFFSET_TABLE_REGNUM])
SET_REGNO_REG_SET (set, PIC_OFFSET_TABLE_REGNUM);
#endif
@@ -1013,7 +984,7 @@ mark_regs_live_at_end (set)
if (global_regs[i] || EPILOGUE_USES (i))
SET_REGNO_REG_SET (set, i);
- if (HAVE_epilogue && reload_completed)
+ if (HAVE_epilogue && epilogue_completed)
{
/* Mark all call-saved registers that we actually used. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
@@ -1034,7 +1005,7 @@ mark_regs_live_at_end (set)
}
#endif
#ifdef EH_RETURN_STACKADJ_RTX
- if ((! HAVE_epilogue || ! reload_completed)
+ if ((! HAVE_epilogue || ! epilogue_completed)
&& current_function_calls_eh_return)
{
rtx tmp = EH_RETURN_STACKADJ_RTX;
@@ -1043,7 +1014,7 @@ mark_regs_live_at_end (set)
}
#endif
#ifdef EH_RETURN_HANDLER_RTX
- if ((! HAVE_epilogue || ! reload_completed)
+ if ((! HAVE_epilogue || ! epilogue_completed)
&& current_function_calls_eh_return)
{
rtx tmp = EH_RETURN_HANDLER_RTX;
@@ -1056,22 +1027,6 @@ mark_regs_live_at_end (set)
diddle_return_value (mark_reg, set);
}
-/* Callback function for for_each_successor_phi. DATA is a regset.
- Sets the SRC_REGNO, the regno of the phi alternative for phi node
- INSN, in the regset. */
-
-static int
-set_phi_alternative_reg (insn, dest_regno, src_regno, data)
- rtx insn ATTRIBUTE_UNUSED;
- int dest_regno ATTRIBUTE_UNUSED;
- int src_regno;
- void *data;
-{
- regset live = (regset) data;
- SET_REGNO_REG_SET (live, src_regno);
- return 0;
-}
-
/* Propagate global life info around the graph of basic blocks. Begin
considering blocks with their corresponding bit set in BLOCKS_IN.
If BLOCKS_IN is null, consider it the universal set.
@@ -1079,9 +1034,7 @@ set_phi_alternative_reg (insn, dest_regno, src_regno, data)
BLOCKS_OUT is set for every block that was changed. */
static void
-calculate_global_regs_live (blocks_in, blocks_out, flags)
- sbitmap blocks_in, blocks_out;
- int flags;
+calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags)
{
basic_block *queue, *qhead, *qtail, *qend, bb;
regset tmp, new_live_at_end, invalidated_by_call;
@@ -1109,7 +1062,7 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
/* Create a worklist. Allocate an extra slot for ENTRY_BLOCK, and one
because the `head == tail' style test for an empty queue doesn't
work with a full queue. */
- queue = (basic_block *) xmalloc ((n_basic_blocks + 2) * sizeof (*queue));
+ queue = xmalloc ((n_basic_blocks + 2) * sizeof (*queue));
qtail = queue;
qhead = qend = queue + n_basic_blocks + 2;
@@ -1230,19 +1183,11 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
/* Any constant, or pseudo with constant equivalences, may
require reloading from memory using the pic register. */
- if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
+ if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
&& fixed_regs[PIC_OFFSET_TABLE_REGNUM])
SET_REGNO_REG_SET (new_live_at_end, PIC_OFFSET_TABLE_REGNUM);
}
- /* Regs used in phi nodes are not included in
- global_live_at_start, since they are live only along a
- particular edge. Set those regs that are live because of a
- phi node alternative corresponding to this particular block. */
- if (in_ssa_form)
- for_each_successor_phi (bb, &set_phi_alternative_reg,
- new_live_at_end);
-
if (bb == ENTRY_BLOCK_PTR)
{
COPY_REG_SET (bb->global_live_at_end, new_live_at_end);
@@ -1393,9 +1338,7 @@ typedef struct {
part of an expression which only uses part of the register. Return
it in the structure passed in. */
static int
-find_regno_partial (ptr, data)
- rtx *ptr;
- void *data;
+find_regno_partial (rtx *ptr, void *data)
{
find_regno_partial_param *param = (find_regno_partial_param *)data;
unsigned reg = param->regno_to_find;
@@ -1440,7 +1383,7 @@ find_regno_partial (ptr, data)
bits we don't want. */
int
-initialize_uninitialized_subregs ()
+initialize_uninitialized_subregs (void)
{
rtx insn;
edge e;
@@ -1495,7 +1438,7 @@ initialize_uninitialized_subregs ()
of life analysis. Not static since used also for stupid life analysis. */
void
-allocate_bb_life_data ()
+allocate_bb_life_data (void)
{
basic_block bb;
@@ -1509,7 +1452,7 @@ allocate_bb_life_data ()
}
void
-allocate_reg_life_data ()
+allocate_reg_life_data (void)
{
int i;
@@ -1528,6 +1471,7 @@ allocate_reg_life_data ()
REG_N_DEATHS (i) = 0;
REG_N_CALLS_CROSSED (i) = 0;
REG_LIVE_LENGTH (i) = 0;
+ REG_FREQ (i) = 0;
REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
}
}
@@ -1535,8 +1479,7 @@ allocate_reg_life_data ()
/* Delete dead instructions for propagate_block. */
static void
-propagate_block_delete_insn (insn)
- rtx insn;
+propagate_block_delete_insn (rtx insn)
{
rtx inote = find_reg_note (insn, REG_LABEL, NULL_RTX);
@@ -1585,8 +1528,7 @@ propagate_block_delete_insn (insn)
before the libcall. */
static rtx
-propagate_block_delete_libcall ( insn, note)
- rtx insn, note;
+propagate_block_delete_libcall (rtx insn, rtx note)
{
rtx first = XEXP (note, 0);
rtx before = PREV_INSN (first);
@@ -1599,9 +1541,7 @@ propagate_block_delete_libcall ( insn, note)
/* Update the life-status of regs for one insn. Return the previous insn. */
rtx
-propagate_one_insn (pbi, insn)
- struct propagate_block_info *pbi;
- rtx insn;
+propagate_one_insn (struct propagate_block_info *pbi, rtx insn)
{
rtx prev = PREV_INSN (insn);
int flags = pbi->flags;
@@ -1659,23 +1599,23 @@ propagate_one_insn (pbi, insn)
as a whole is not dead, then we want to remove INSN, but
not the whole libcall sequence.
- However, we need to also remove the dangling REG_LIBCALL
+ However, we need to also remove the dangling REG_LIBCALL
note so that we do not have mis-matched LIBCALL/RETVAL
notes. In theory we could find a new location for the
- REG_RETVAL note, but it hardly seems worth the effort.
+ REG_RETVAL note, but it hardly seems worth the effort.
NOTE at this point will be the RETVAL note if it exists. */
if (note)
{
rtx libcall_note;
-
+
libcall_note
= find_reg_note (XEXP (note, 0), REG_LIBCALL, NULL_RTX);
remove_note (XEXP (note, 0), libcall_note);
}
/* Similarly if INSN contains a LIBCALL note, remove the
- dnagling REG_RETVAL note. */
+ dangling REG_RETVAL note. */
note = find_reg_note (insn, REG_LIBCALL, NULL_RTX);
if (note)
{
@@ -1799,8 +1739,9 @@ propagate_one_insn (pbi, insn)
current_function_return_rtx,
(rtx *) 0)))
{
+ enum rtx_code code = global_regs[i] ? SET : CLOBBER;
/* We do not want REG_UNUSED notes for these registers. */
- mark_set_1 (pbi, CLOBBER, regno_reg_rtx[i], cond, insn,
+ mark_set_1 (pbi, code, regno_reg_rtx[i], cond, insn,
pbi->flags & ~(PROP_DEATH_NOTES | PROP_REG_INFO));
}
}
@@ -1833,13 +1774,14 @@ propagate_one_insn (pbi, insn)
if (GET_CODE (PATTERN (insn)) == COND_EXEC)
cond = COND_EXEC_TEST (PATTERN (insn));
- /* Calls use their arguments. */
+ /* Calls use their arguments, and may clobber memory which
+ address involves some register. */
for (note = CALL_INSN_FUNCTION_USAGE (insn);
note;
note = XEXP (note, 1))
- if (GET_CODE (XEXP (note, 0)) == USE)
- mark_used_regs (pbi, XEXP (XEXP (note, 0), 0),
- cond, insn);
+ /* We find USE or CLOBBER entities in a FUNCTION_USAGE list: both
+ of which mark_used_regs knows how to handle. */
+ mark_used_regs (pbi, XEXP (XEXP (note, 0), 0), cond, insn);
/* The stack ptr is used (honorarily) by a CALL insn. */
SET_REGNO_REG_SET (pbi->reg_live, STACK_POINTER_REGNUM);
@@ -1866,10 +1808,8 @@ propagate_one_insn (pbi, insn)
the user can use the regsets provided here. */
struct propagate_block_info *
-init_propagate_block_info (bb, live, local_set, cond_local_set, flags)
- basic_block bb;
- regset live, local_set, cond_local_set;
- int flags;
+init_propagate_block_info (basic_block bb, regset live, regset local_set,
+ regset cond_local_set, int flags)
{
struct propagate_block_info *pbi = xmalloc (sizeof (*pbi));
@@ -1883,7 +1823,7 @@ init_propagate_block_info (bb, live, local_set, cond_local_set, flags)
pbi->flags = flags;
if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
- pbi->reg_next_use = (rtx *) xcalloc (max_reg_num (), sizeof (rtx));
+ pbi->reg_next_use = xcalloc (max_reg_num (), sizeof (rtx));
else
pbi->reg_next_use = NULL;
@@ -1894,16 +1834,15 @@ init_propagate_block_info (bb, live, local_set, cond_local_set, flags)
free_reg_cond_life_info);
pbi->reg_cond_reg = BITMAP_XMALLOC ();
- /* If this block ends in a conditional branch, for each register live
- from one side of the branch and not the other, record the register
- as conditionally dead. */
- if (GET_CODE (bb->end) == JUMP_INSN
- && any_condjump_p (bb->end))
+ /* If this block ends in a conditional branch, for each register
+ live from one side of the branch and not the other, record the
+ register as conditionally dead. */
+ if (GET_CODE (BB_END (bb)) == JUMP_INSN
+ && any_condjump_p (BB_END (bb)))
{
regset_head diff_head;
regset diff = INITIALIZE_REG_SET (diff_head);
basic_block bb_true, bb_false;
- rtx cond_true, cond_false, set_src;
int i;
/* Identify the successor blocks. */
@@ -1924,60 +1863,66 @@ init_propagate_block_info (bb, live, local_set, cond_local_set, flags)
else
{
/* This can happen with a conditional jump to the next insn. */
- if (JUMP_LABEL (bb->end) != bb_true->head)
+ if (JUMP_LABEL (BB_END (bb)) != BB_HEAD (bb_true))
abort ();
/* Simplest way to do nothing. */
bb_false = bb_true;
}
- /* Extract the condition from the branch. */
- set_src = SET_SRC (pc_set (bb->end));
- cond_true = XEXP (set_src, 0);
- cond_false = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond_true)),
- GET_MODE (cond_true), XEXP (cond_true, 0),
- XEXP (cond_true, 1));
- if (GET_CODE (XEXP (set_src, 1)) == PC)
- {
- rtx t = cond_false;
- cond_false = cond_true;
- cond_true = t;
- }
-
/* Compute which register lead different lives in the successors. */
if (bitmap_operation (diff, bb_true->global_live_at_start,
bb_false->global_live_at_start, BITMAP_XOR))
{
+ /* Extract the condition from the branch. */
+ rtx set_src = SET_SRC (pc_set (BB_END (bb)));
+ rtx cond_true = XEXP (set_src, 0);
rtx reg = XEXP (cond_true, 0);
if (GET_CODE (reg) == SUBREG)
reg = SUBREG_REG (reg);
- if (GET_CODE (reg) != REG)
- abort ();
+ /* We can only track conditional lifetimes if the condition is
+ in the form of a comparison of a register against zero.
+ If the condition is more complex than that, then it is safe
+ not to record any information. */
+ if (GET_CODE (reg) == REG
+ && XEXP (cond_true, 1) == const0_rtx)
+ {
+ rtx cond_false
+ = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond_true)),
+ GET_MODE (cond_true), XEXP (cond_true, 0),
+ XEXP (cond_true, 1));
+ if (GET_CODE (XEXP (set_src, 1)) == PC)
+ {
+ rtx t = cond_false;
+ cond_false = cond_true;
+ cond_true = t;
+ }
- SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (reg));
+ SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (reg));
- /* For each such register, mark it conditionally dead. */
- EXECUTE_IF_SET_IN_REG_SET
- (diff, 0, i,
- {
- struct reg_cond_life_info *rcli;
- rtx cond;
+ /* For each such register, mark it conditionally dead. */
+ EXECUTE_IF_SET_IN_REG_SET
+ (diff, 0, i,
+ {
+ struct reg_cond_life_info *rcli;
+ rtx cond;
- rcli = (struct reg_cond_life_info *) xmalloc (sizeof (*rcli));
+ rcli = xmalloc (sizeof (*rcli));
- if (REGNO_REG_SET_P (bb_true->global_live_at_start, i))
- cond = cond_false;
- else
- cond = cond_true;
- rcli->condition = cond;
- rcli->stores = const0_rtx;
- rcli->orig_condition = cond;
+ if (REGNO_REG_SET_P (bb_true->global_live_at_start, i))
+ cond = cond_false;
+ else
+ cond = cond_true;
+ rcli->condition = cond;
+ rcli->stores = const0_rtx;
+ rcli->orig_condition = cond;
- splay_tree_insert (pbi->reg_cond_dead, i,
- (splay_tree_value) rcli);
- });
+ splay_tree_insert (pbi->reg_cond_dead, i,
+ (splay_tree_value) rcli);
+ });
+ }
}
FREE_REG_SET (diff);
@@ -1999,7 +1944,7 @@ init_propagate_block_info (bb, live, local_set, cond_local_set, flags)
&& ! current_function_calls_eh_return)))
{
rtx insn, set;
- for (insn = bb->end; insn != bb->head; insn = PREV_INSN (insn))
+ for (insn = BB_END (bb); insn != BB_HEAD (bb); insn = PREV_INSN (insn))
if (GET_CODE (insn) == INSN
&& (set = single_set (insn))
&& GET_CODE (SET_DEST (set)) == MEM)
@@ -2007,13 +1952,6 @@ init_propagate_block_info (bb, live, local_set, cond_local_set, flags)
rtx mem = SET_DEST (set);
rtx canon_mem = canon_rtx (mem);
- /* This optimization is performed by faking a store to the
- memory at the end of the block. This doesn't work for
- unchanging memories because multiple stores to unchanging
- memory is illegal and alias analysis doesn't consider it. */
- if (RTX_UNCHANGING_P (canon_mem))
- continue;
-
if (XEXP (canon_mem, 0) == frame_pointer_rtx
|| (GET_CODE (XEXP (canon_mem, 0)) == PLUS
&& XEXP (XEXP (canon_mem, 0), 0) == frame_pointer_rtx
@@ -2028,8 +1966,7 @@ init_propagate_block_info (bb, live, local_set, cond_local_set, flags)
/* Release a propagate_block_info struct. */
void
-free_propagate_block_info (pbi)
- struct propagate_block_info *pbi;
+free_propagate_block_info (struct propagate_block_info *pbi)
{
free_EXPR_LIST_list (&pbi->mem_set_list);
@@ -2065,12 +2002,8 @@ free_propagate_block_info (pbi)
Return nonzero if an INSN is deleted (i.e. by dead code removal). */
int
-propagate_block (bb, live, local_set, cond_local_set, flags)
- basic_block bb;
- regset live;
- regset local_set;
- regset cond_local_set;
- int flags;
+propagate_block (basic_block bb, regset live, regset local_set,
+ regset cond_local_set, int flags)
{
struct propagate_block_info *pbi;
rtx insn, prev;
@@ -2091,7 +2024,7 @@ propagate_block (bb, live, local_set, cond_local_set, flags)
/* Scan the block an insn at a time from end to beginning. */
changed = 0;
- for (insn = bb->end;; insn = prev)
+ for (insn = BB_END (bb); ; insn = prev)
{
/* If this is a call to `setjmp' et al, warn if any
non-volatile datum is live. */
@@ -2101,9 +2034,12 @@ propagate_block (bb, live, local_set, cond_local_set, flags)
IOR_REG_SET (regs_live_at_setjmp, pbi->reg_live);
prev = propagate_one_insn (pbi, insn);
- changed |= NEXT_INSN (prev) != insn;
+ if (!prev)
+ changed |= insn != get_insns ();
+ else
+ changed |= NEXT_INSN (prev) != insn;
- if (insn == bb->head)
+ if (insn == BB_HEAD (bb))
break;
}
@@ -2122,11 +2058,8 @@ propagate_block (bb, live, local_set, cond_local_set, flags)
pertaining to the insn. */
static int
-insn_dead_p (pbi, x, call_ok, notes)
- struct propagate_block_info *pbi;
- rtx x;
- int call_ok;
- rtx notes ATTRIBUTE_UNUSED;
+insn_dead_p (struct propagate_block_info *pbi, rtx x, int call_ok,
+ rtx notes ATTRIBUTE_UNUSED)
{
enum rtx_code code = GET_CODE (x);
@@ -2190,7 +2123,7 @@ insn_dead_p (pbi, x, call_ok, notes)
rtx_equal_p does not check the alias set or flags, we also
must have the potential for them to conflict (anti_dependence). */
for (temp = pbi->mem_set_list; temp != 0; temp = XEXP (temp, 1))
- if (anti_dependence (r, XEXP (temp, 0)))
+ if (unchanging_anti_dependence (r, XEXP (temp, 0)))
{
rtx mem = XEXP (temp, 0);
@@ -2292,14 +2225,22 @@ insn_dead_p (pbi, x, call_ok, notes)
}
/* A CLOBBER of a pseudo-register that is dead serves no purpose. That
- is not necessarily true for hard registers. */
- else if (code == CLOBBER && GET_CODE (XEXP (x, 0)) == REG
- && REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER
- && ! REGNO_REG_SET_P (pbi->reg_live, REGNO (XEXP (x, 0))))
- return 1;
-
- /* We do not check other CLOBBER or USE here. An insn consisting of just
- a CLOBBER or just a USE should not be deleted. */
+ is not necessarily true for hard registers until after reload. */
+ else if (code == CLOBBER)
+ {
+ if (GET_CODE (XEXP (x, 0)) == REG
+ && (REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER
+ || reload_completed)
+ && ! REGNO_REG_SET_P (pbi->reg_live, REGNO (XEXP (x, 0))))
+ return 1;
+ }
+
+ /* ??? A base USE is a historical relic. It ought not be needed anymore.
+ Instances where it is still used are either (1) temporary and the USE
+ escaped the pass, (2) cruft and the USE need not be emitted anymore,
+ or (3) hiding bugs elsewhere that are not properly representing data
+ flow. */
+
return 0;
}
@@ -2319,10 +2260,7 @@ insn_dead_p (pbi, x, call_ok, notes)
NOTE is the REG_RETVAL note of the insn. */
static int
-libcall_dead_p (pbi, note, insn)
- struct propagate_block_info *pbi;
- rtx note;
- rtx insn;
+libcall_dead_p (struct propagate_block_info *pbi, rtx note, rtx insn)
{
rtx x = single_set (insn);
@@ -2376,8 +2314,7 @@ libcall_dead_p (pbi, note, insn)
fixed hard registers. */
int
-regno_uninitialized (regno)
- unsigned int regno;
+regno_uninitialized (unsigned int regno)
{
if (n_basic_blocks == 0
|| (regno < FIRST_PSEUDO_REGISTER
@@ -2386,7 +2323,7 @@ regno_uninitialized (regno)
|| FUNCTION_ARG_REGNO_P (regno))))
return 0;
- return REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno);
+ return REGNO_REG_SET_P (ENTRY_BLOCK_PTR->global_live_at_end, regno);
}
/* 1 if register REGNO was alive at a place where `setjmp' was called
@@ -2394,23 +2331,20 @@ regno_uninitialized (regno)
Such regs may be clobbered by `longjmp'. */
int
-regno_clobbered_at_setjmp (regno)
- int regno;
+regno_clobbered_at_setjmp (int regno)
{
if (n_basic_blocks == 0)
return 0;
return ((REG_N_SETS (regno) > 1
- || REGNO_REG_SET_P (ENTRY_BLOCK_PTR->next_bb->global_live_at_start, regno))
+ || REGNO_REG_SET_P (ENTRY_BLOCK_PTR->global_live_at_end, regno))
&& REGNO_REG_SET_P (regs_live_at_setjmp, regno));
}
/* Add MEM to PBI->MEM_SET_LIST. MEM should be canonical. Respect the
maximal list size; look for overlaps in mode and select the largest. */
static void
-add_to_mem_set_list (pbi, mem)
- struct propagate_block_info *pbi;
- rtx mem;
+add_to_mem_set_list (struct propagate_block_info *pbi, rtx mem)
{
rtx i;
@@ -2457,9 +2391,7 @@ add_to_mem_set_list (pbi, mem)
to an address change. */
static int
-invalidate_mems_from_autoinc (px, data)
- rtx *px;
- void *data;
+invalidate_mems_from_autoinc (rtx *px, void *data)
{
rtx x = *px;
struct propagate_block_info *pbi = data;
@@ -2476,9 +2408,7 @@ invalidate_mems_from_autoinc (px, data)
/* EXP is a REG. Remove any dependent entries from pbi->mem_set_list. */
static void
-invalidate_mems_from_set (pbi, exp)
- struct propagate_block_info *pbi;
- rtx exp;
+invalidate_mems_from_set (struct propagate_block_info *pbi, rtx exp)
{
rtx temp = pbi->mem_set_list;
rtx prev = NULL_RTX;
@@ -2511,13 +2441,12 @@ invalidate_mems_from_set (pbi, exp)
FLAGS is the set of operations to perform. */
static void
-mark_set_regs (pbi, x, insn)
- struct propagate_block_info *pbi;
- rtx x, insn;
+mark_set_regs (struct propagate_block_info *pbi, rtx x, rtx insn)
{
rtx cond = NULL_RTX;
rtx link;
enum rtx_code code;
+ int flags = pbi->flags;
if (insn)
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
@@ -2526,14 +2455,17 @@ mark_set_regs (pbi, x, insn)
mark_set_1 (pbi, SET, XEXP (link, 0),
(GET_CODE (x) == COND_EXEC
? COND_EXEC_TEST (x) : NULL_RTX),
- insn, pbi->flags);
+ insn, flags);
}
retry:
switch (code = GET_CODE (x))
{
case SET:
+ if (GET_CODE (XEXP (x, 1)) == ASM_OPERANDS)
+ flags |= PROP_ASM_SCAN;
+ /* Fall through */
case CLOBBER:
- mark_set_1 (pbi, code, SET_DEST (x), cond, insn, pbi->flags);
+ mark_set_1 (pbi, code, SET_DEST (x), cond, insn, flags);
return;
case COND_EXEC:
@@ -2545,7 +2477,9 @@ mark_set_regs (pbi, x, insn)
{
int i;
- for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
+ /* We must scan forwards. If we have an asm, we need to set
+ the PROP_ASM_SCAN flag before scanning the clobbers. */
+ for (i = 0; i < XVECLEN (x, 0); i++)
{
rtx sub = XVECEXP (x, 0, i);
switch (code = GET_CODE (sub))
@@ -2556,13 +2490,24 @@ mark_set_regs (pbi, x, insn)
cond = COND_EXEC_TEST (sub);
sub = COND_EXEC_CODE (sub);
- if (GET_CODE (sub) != SET && GET_CODE (sub) != CLOBBER)
- break;
- /* Fall through. */
+ if (GET_CODE (sub) == SET)
+ goto mark_set;
+ if (GET_CODE (sub) == CLOBBER)
+ goto mark_clob;
+ break;
case SET:
+ mark_set:
+ if (GET_CODE (XEXP (sub, 1)) == ASM_OPERANDS)
+ flags |= PROP_ASM_SCAN;
+ /* Fall through */
case CLOBBER:
- mark_set_1 (pbi, code, SET_DEST (sub), cond, insn, pbi->flags);
+ mark_clob:
+ mark_set_1 (pbi, code, SET_DEST (sub), cond, insn, flags);
+ break;
+
+ case ASM_OPERANDS:
+ flags |= PROP_ASM_SCAN;
break;
default:
@@ -2584,11 +2529,7 @@ mark_set_regs (pbi, x, insn)
will be the condition. */
static void
-mark_set_1 (pbi, code, reg, cond, insn, flags)
- struct propagate_block_info *pbi;
- enum rtx_code code;
- rtx reg, cond, insn;
- int flags;
+mark_set_1 (struct propagate_block_info *pbi, enum rtx_code code, rtx reg, rtx cond, rtx insn, int flags)
{
int regno_first = -1, regno_last = -1;
unsigned long not_dead = 0;
@@ -2790,6 +2731,9 @@ mark_set_1 (pbi, code, reg, cond, insn, flags)
{
for (i = regno_first; i <= regno_last; i++)
regs_ever_live[i] = 1;
+ if (flags & PROP_ASM_SCAN)
+ for (i = regno_first; i <= regno_last; i++)
+ regs_asm_clobbered[i] = 1;
}
else
{
@@ -2813,10 +2757,18 @@ mark_set_1 (pbi, code, reg, cond, insn, flags)
in ASM_OPERANDs. If these registers get replaced,
we might wind up changing the semantics of the insn,
even if reload can make what appear to be valid
- assignments later. */
+ assignments later.
+
+ We don't build a LOG_LINK for global registers to
+ or from a function call. We don't want to let
+ combine think that it knows what is going on with
+ global registers. */
if (y && (BLOCK_NUM (y) == blocknum)
&& (regno_first >= FIRST_PSEUDO_REGISTER
- || asm_noperands (PATTERN (y)) < 0))
+ || (asm_noperands (PATTERN (y)) < 0
+ && ! ((GET_CODE (insn) == CALL_INSN
+ || GET_CODE (y) == CALL_INSN)
+ && global_regs[regno_first]))))
LOG_LINKS (y) = alloc_INSN_LIST (insn, LOG_LINKS (y));
}
}
@@ -2875,6 +2827,14 @@ mark_set_1 (pbi, code, reg, cond, insn, flags)
{
if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
pbi->reg_next_use[regno_first] = 0;
+
+ if ((flags & PROP_REG_INFO) != 0
+ && (flags & PROP_ASM_SCAN) != 0
+ && regno_first < FIRST_PSEUDO_REGISTER)
+ {
+ for (i = regno_first; i <= regno_last; i++)
+ regs_asm_clobbered[i] = 1;
+ }
}
/* If this is the last pass and this is a SCRATCH, show it will be dying
@@ -2892,10 +2852,7 @@ mark_set_1 (pbi, code, reg, cond, insn, flags)
Return true if the register is now unconditionally dead. */
static int
-mark_regno_cond_dead (pbi, regno, cond)
- struct propagate_block_info *pbi;
- int regno;
- rtx cond;
+mark_regno_cond_dead (struct propagate_block_info *pbi, int regno, rtx cond)
{
/* If this is a store to a predicate register, the value of the
predicate is changing, we don't know that the predicate as seen
@@ -2925,7 +2882,7 @@ mark_regno_cond_dead (pbi, regno, cond)
/* The register was unconditionally live previously.
Record the current condition as the condition under
which it is dead. */
- rcli = (struct reg_cond_life_info *) xmalloc (sizeof (*rcli));
+ rcli = xmalloc (sizeof (*rcli));
rcli->condition = cond;
rcli->stores = cond;
rcli->orig_condition = const0_rtx;
@@ -2978,8 +2935,7 @@ mark_regno_cond_dead (pbi, regno, cond)
/* Called from splay_tree_delete for pbi->reg_cond_life. */
static void
-free_reg_cond_life_info (value)
- splay_tree_value value;
+free_reg_cond_life_info (splay_tree_value value)
{
struct reg_cond_life_info *rcli = (struct reg_cond_life_info *) value;
free (rcli);
@@ -2988,9 +2944,7 @@ free_reg_cond_life_info (value)
/* Helper function for flush_reg_cond_reg. */
static int
-flush_reg_cond_reg_1 (node, data)
- splay_tree_node node;
- void *data;
+flush_reg_cond_reg_1 (splay_tree_node node, void *data)
{
struct reg_cond_life_info *rcli;
int *xdata = (int *) data;
@@ -3022,9 +2976,7 @@ flush_reg_cond_reg_1 (node, data)
/* Flush all (sub) expressions referring to REGNO from REG_COND_LIVE. */
static void
-flush_reg_cond_reg (pbi, regno)
- struct propagate_block_info *pbi;
- int regno;
+flush_reg_cond_reg (struct propagate_block_info *pbi, int regno)
{
int pair[2];
@@ -3047,9 +2999,7 @@ flush_reg_cond_reg (pbi, regno)
ADD. */
static rtx
-ior_reg_cond (old, x, add)
- rtx old, x;
- int add;
+ior_reg_cond (rtx old, rtx x, int add)
{
rtx op0, op1;
@@ -3137,8 +3087,7 @@ ior_reg_cond (old, x, add)
}
static rtx
-not_reg_cond (x)
- rtx x;
+not_reg_cond (rtx x)
{
enum rtx_code x_code;
@@ -3162,9 +3111,7 @@ not_reg_cond (x)
}
static rtx
-and_reg_cond (old, x, add)
- rtx old, x;
- int add;
+and_reg_cond (rtx old, rtx x, int add)
{
rtx op0, op1;
@@ -3257,9 +3204,7 @@ and_reg_cond (old, x, add)
is used when the value of REGNO changes. */
static rtx
-elim_reg_cond (x, regno)
- rtx x;
- unsigned int regno;
+elim_reg_cond (rtx x, unsigned int regno)
{
rtx op0, op1;
@@ -3323,9 +3268,8 @@ elim_reg_cond (x, regno)
else. */
static void
-attempt_auto_inc (pbi, inc, insn, mem, incr, incr_reg)
- struct propagate_block_info *pbi;
- rtx inc, insn, mem, incr, incr_reg;
+attempt_auto_inc (struct propagate_block_info *pbi, rtx inc, rtx insn,
+ rtx mem, rtx incr, rtx incr_reg)
{
int regno = REGNO (incr_reg);
rtx set = single_set (incr);
@@ -3384,8 +3328,8 @@ attempt_auto_inc (pbi, inc, insn, mem, incr, incr_reg)
new insn(s) and do the updates. */
emit_insn_before (insns, insn);
- if (pbi->bb->head == insn)
- pbi->bb->head = insns;
+ if (BB_HEAD (pbi->bb) == insn)
+ BB_HEAD (pbi->bb) = insns;
/* INCR will become a NOTE and INSN won't contain a
use of INCR_REG. If a use of INCR_REG was just placed in
@@ -3467,10 +3411,7 @@ attempt_auto_inc (pbi, inc, insn, mem, incr, incr_reg)
reference. */
static void
-find_auto_inc (pbi, x, insn)
- struct propagate_block_info *pbi;
- rtx x;
- rtx insn;
+find_auto_inc (struct propagate_block_info *pbi, rtx x, rtx insn)
{
rtx addr = XEXP (x, 0);
HOST_WIDE_INT offset = 0;
@@ -3535,6 +3476,12 @@ find_auto_inc (pbi, x, insn)
addr,
inc_val)),
insn, x, incr, addr);
+ else if (HAVE_PRE_MODIFY_DISP && offset == INTVAL (inc_val))
+ attempt_auto_inc (pbi, gen_rtx_PRE_MODIFY (Pmode, addr,
+ gen_rtx_PLUS (Pmode,
+ addr,
+ inc_val)),
+ insn, x, incr, addr);
}
else if (GET_CODE (inc_val) == REG
&& ! reg_set_between_p (inc_val, PREV_INSN (insn),
@@ -3553,11 +3500,8 @@ find_auto_inc (pbi, x, insn)
#endif /* AUTO_INC_DEC */
static void
-mark_used_reg (pbi, reg, cond, insn)
- struct propagate_block_info *pbi;
- rtx reg;
- rtx cond ATTRIBUTE_UNUSED;
- rtx insn;
+mark_used_reg (struct propagate_block_info *pbi, rtx reg,
+ rtx cond ATTRIBUTE_UNUSED, rtx insn)
{
unsigned int regno_first, regno_last, i;
int some_was_live, some_was_dead, some_not_set;
@@ -3715,7 +3659,7 @@ mark_used_reg (pbi, reg, cond, insn)
{
/* The register was not previously live at all. Record
the condition under which it is still dead. */
- rcli = (struct reg_cond_life_info *) xmalloc (sizeof (*rcli));
+ rcli = xmalloc (sizeof (*rcli));
rcli->condition = not_reg_cond (cond);
rcli->stores = const0_rtx;
rcli->orig_condition = const0_rtx;
@@ -3745,9 +3689,7 @@ mark_used_reg (pbi, reg, cond, insn)
is not called. */
static void
-mark_used_regs (pbi, x, cond, insn)
- struct propagate_block_info *pbi;
- rtx x, cond, insn;
+mark_used_regs (struct propagate_block_info *pbi, rtx x, rtx cond, rtx insn)
{
RTX_CODE code;
int regno;
@@ -3803,7 +3745,7 @@ mark_used_regs (pbi, x, cond, insn)
while (temp)
{
next = XEXP (temp, 1);
- if (anti_dependence (XEXP (temp, 0), x))
+ if (unchanging_anti_dependence (XEXP (temp, 0), x))
{
/* Splice temp out of the list. */
if (prev)
@@ -3834,7 +3776,8 @@ mark_used_regs (pbi, x, cond, insn)
case SUBREG:
#ifdef CANNOT_CHANGE_MODE_CLASS
- if (GET_CODE (SUBREG_REG (x)) == REG
+ if ((flags & PROP_REG_INFO)
+ && GET_CODE (SUBREG_REG (x)) == REG
&& REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
bitmap_set_bit (&subregs_of_mode, REGNO (SUBREG_REG (x))
* MAX_MACHINE_MODE
@@ -3883,7 +3826,8 @@ mark_used_regs (pbi, x, cond, insn)
|| GET_CODE (testreg) == SUBREG)
{
#ifdef CANNOT_CHANGE_MODE_CLASS
- if (GET_CODE (testreg) == SUBREG
+ if ((flags & PROP_REG_INFO)
+ && GET_CODE (testreg) == SUBREG
&& GET_CODE (SUBREG_REG (testreg)) == REG
&& REGNO (SUBREG_REG (testreg)) >= FIRST_PSEUDO_REGISTER)
bitmap_set_bit (&subregs_of_mode, REGNO (SUBREG_REG (testreg))
@@ -3981,14 +3925,6 @@ mark_used_regs (pbi, x, cond, insn)
x = COND_EXEC_CODE (x);
goto retry;
- case PHI:
- /* We _do_not_ want to scan operands of phi nodes. Operands of
- a phi function are evaluated only when control reaches this
- block along a particular edge. Therefore, regs that appear
- as arguments to phi should not be added to the global live at
- start. */
- return;
-
default:
break;
}
@@ -4024,9 +3960,7 @@ mark_used_regs (pbi, x, cond, insn)
#ifdef AUTO_INC_DEC
static int
-try_pre_increment_1 (pbi, insn)
- struct propagate_block_info *pbi;
- rtx insn;
+try_pre_increment_1 (struct propagate_block_info *pbi, rtx insn)
{
/* Find the next use of this reg. If in same basic block,
make it do pre-increment or pre-decrement if appropriate. */
@@ -4072,9 +4006,7 @@ try_pre_increment_1 (pbi, insn)
This checks all about the validity of the result of modifying INSN. */
static int
-try_pre_increment (insn, reg, amount)
- rtx insn, reg;
- HOST_WIDE_INT amount;
+try_pre_increment (rtx insn, rtx reg, HOST_WIDE_INT amount)
{
rtx use;
@@ -4152,10 +4084,7 @@ try_pre_increment (insn, reg, amount)
return (rtx) 1. */
rtx
-find_use_as_address (x, reg, plusconst)
- rtx x;
- rtx reg;
- HOST_WIDE_INT plusconst;
+find_use_as_address (rtx x, rtx reg, HOST_WIDE_INT plusconst)
{
enum rtx_code code = GET_CODE (x);
const char * const fmt = GET_RTX_FORMAT (code);
@@ -4214,9 +4143,7 @@ find_use_as_address (x, reg, plusconst)
This is part of making a debugging dump. */
void
-dump_regset (r, outf)
- regset r;
- FILE *outf;
+dump_regset (regset r, FILE *outf)
{
int i;
if (r == NULL)
@@ -4234,13 +4161,12 @@ dump_regset (r, outf)
});
}
-/* Print a human-reaable representation of R on the standard error
+/* Print a human-readable representation of R on the standard error
stream. This function is designed to be used from within the
debugger. */
void
-debug_regset (r)
- regset r;
+debug_regset (regset r)
{
dump_regset (r, stderr);
putc ('\n', stderr);
@@ -4266,9 +4192,7 @@ debug_regset (r)
possibly other information which is used by the register allocators. */
void
-recompute_reg_usage (f, loop_step)
- rtx f ATTRIBUTE_UNUSED;
- int loop_step ATTRIBUTE_UNUSED;
+recompute_reg_usage (rtx f ATTRIBUTE_UNUSED, int loop_step ATTRIBUTE_UNUSED)
{
allocate_reg_life_data ();
update_life_info (NULL, UPDATE_LIFE_LOCAL, PROP_REG_INFO);
@@ -4279,76 +4203,103 @@ recompute_reg_usage (f, loop_step)
of the number of registers that died. */
int
-count_or_remove_death_notes (blocks, kill)
- sbitmap blocks;
- int kill;
+count_or_remove_death_notes (sbitmap blocks, int kill)
{
int count = 0;
+ int i;
basic_block bb;
- FOR_EACH_BB_REVERSE (bb)
+
+ /* This used to be a loop over all the blocks with a membership test
+ inside the loop. That can be amazingly expensive on a large CFG
+ when only a small number of bits are set in BLOCKs (for example,
+ the calls from the scheduler typically have very few bits set).
+
+ For extra credit, someone should convert BLOCKS to a bitmap rather
+ than an sbitmap. */
+ if (blocks)
+ {
+ EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
+ {
+ count += count_or_remove_death_notes_bb (BASIC_BLOCK (i), kill);
+ });
+ }
+ else
{
- rtx insn;
+ FOR_EACH_BB (bb)
+ {
+ count += count_or_remove_death_notes_bb (bb, kill);
+ }
+ }
- if (blocks && ! TEST_BIT (blocks, bb->index))
- continue;
+ return count;
+}
+
+/* Optionally removes all the REG_DEAD and REG_UNUSED notes from basic
+ block BB. Returns a count of the number of registers that died. */
- for (insn = bb->head;; insn = NEXT_INSN (insn))
+static int
+count_or_remove_death_notes_bb (basic_block bb, int kill)
+{
+ int count = 0;
+ rtx insn;
+
+ for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
{
- if (INSN_P (insn))
- {
- rtx *pprev = &REG_NOTES (insn);
- rtx link = *pprev;
+ rtx *pprev = &REG_NOTES (insn);
+ rtx link = *pprev;
- while (link)
+ while (link)
+ {
+ switch (REG_NOTE_KIND (link))
{
- switch (REG_NOTE_KIND (link))
+ case REG_DEAD:
+ if (GET_CODE (XEXP (link, 0)) == REG)
{
- case REG_DEAD:
- if (GET_CODE (XEXP (link, 0)) == REG)
- {
- rtx reg = XEXP (link, 0);
- int n;
-
- if (REGNO (reg) >= FIRST_PSEUDO_REGISTER)
- n = 1;
- else
- n = HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg));
- count += n;
- }
- /* Fall through. */
-
- case REG_UNUSED:
- if (kill)
- {
- rtx next = XEXP (link, 1);
- free_EXPR_LIST_node (link);
- *pprev = link = next;
- break;
- }
- /* Fall through. */
-
- default:
- pprev = &XEXP (link, 1);
- link = *pprev;
+ rtx reg = XEXP (link, 0);
+ int n;
+
+ if (REGNO (reg) >= FIRST_PSEUDO_REGISTER)
+ n = 1;
+ else
+ n = HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg));
+ count += n;
+ }
+
+ /* Fall through. */
+
+ case REG_UNUSED:
+ if (kill)
+ {
+ rtx next = XEXP (link, 1);
+ free_EXPR_LIST_node (link);
+ *pprev = link = next;
break;
}
+ /* Fall through. */
+
+ default:
+ pprev = &XEXP (link, 1);
+ link = *pprev;
+ break;
}
}
-
- if (insn == bb->end)
- break;
}
+
+ if (insn == BB_END (bb))
+ break;
}
return count;
}
+
/* Clear LOG_LINKS fields of insns in a selected blocks or whole chain
if blocks is NULL. */
static void
-clear_log_links (blocks)
- sbitmap blocks;
+clear_log_links (sbitmap blocks)
{
rtx insn;
int i;
@@ -4364,7 +4315,7 @@ clear_log_links (blocks)
{
basic_block bb = BASIC_BLOCK (i);
- for (insn = bb->head; insn != NEXT_INSN (bb->end);
+ for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
if (INSN_P (insn))
free_INSN_LIST_list (&LOG_LINKS (insn));
@@ -4377,9 +4328,7 @@ clear_log_links (blocks)
with moving single words, but probably isn't worth the trouble. */
void
-reg_set_to_hard_reg_set (to, from)
- HARD_REG_SET *to;
- bitmap from;
+reg_set_to_hard_reg_set (HARD_REG_SET *to, bitmap from)
{
int i;
diff --git a/contrib/gcc/fold-const.c b/contrib/gcc/fold-const.c
index 94682d477ee4..2c0f813b544d 100644
--- a/contrib/gcc/fold-const.c
+++ b/contrib/gcc/fold-const.c
@@ -1,6 +1,6 @@
/* Fold a constant sub-tree into a single node for C-compiler
- Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2002,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -44,6 +44,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "flags.h"
#include "tree.h"
#include "real.h"
@@ -54,62 +56,62 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "hashtab.h"
#include "langhooks.h"
-
-static void encode PARAMS ((HOST_WIDE_INT *,
- unsigned HOST_WIDE_INT,
- HOST_WIDE_INT));
-static void decode PARAMS ((HOST_WIDE_INT *,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *));
-static tree negate_expr PARAMS ((tree));
-static tree split_tree PARAMS ((tree, enum tree_code, tree *, tree *,
- tree *, int));
-static tree associate_trees PARAMS ((tree, tree, enum tree_code, tree));
-static tree int_const_binop PARAMS ((enum tree_code, tree, tree, int));
-static tree const_binop PARAMS ((enum tree_code, tree, tree, int));
-static hashval_t size_htab_hash PARAMS ((const void *));
-static int size_htab_eq PARAMS ((const void *, const void *));
-static tree fold_convert PARAMS ((tree, tree));
-static enum tree_code invert_tree_comparison PARAMS ((enum tree_code));
-static enum tree_code swap_tree_comparison PARAMS ((enum tree_code));
-static int comparison_to_compcode PARAMS ((enum tree_code));
-static enum tree_code compcode_to_comparison PARAMS ((int));
-static int truth_value_p PARAMS ((enum tree_code));
-static int operand_equal_for_comparison_p PARAMS ((tree, tree, tree));
-static int twoval_comparison_p PARAMS ((tree, tree *, tree *, int *));
-static tree eval_subst PARAMS ((tree, tree, tree, tree, tree));
-static tree omit_one_operand PARAMS ((tree, tree, tree));
-static tree pedantic_omit_one_operand PARAMS ((tree, tree, tree));
-static tree distribute_bit_expr PARAMS ((enum tree_code, tree, tree, tree));
-static tree make_bit_field_ref PARAMS ((tree, tree, int, int, int));
-static tree optimize_bit_field_compare PARAMS ((enum tree_code, tree,
- tree, tree));
-static tree decode_field_reference PARAMS ((tree, HOST_WIDE_INT *,
- HOST_WIDE_INT *,
- enum machine_mode *, int *,
- int *, tree *, tree *));
-static int all_ones_mask_p PARAMS ((tree, int));
-static tree sign_bit_p PARAMS ((tree, tree));
-static int simple_operand_p PARAMS ((tree));
-static tree range_binop PARAMS ((enum tree_code, tree, tree, int,
- tree, int));
-static tree make_range PARAMS ((tree, int *, tree *, tree *));
-static tree build_range_check PARAMS ((tree, tree, int, tree, tree));
-static int merge_ranges PARAMS ((int *, tree *, tree *, int, tree, tree,
- int, tree, tree));
-static tree fold_range_test PARAMS ((tree));
-static tree unextend PARAMS ((tree, int, int, tree));
-static tree fold_truthop PARAMS ((enum tree_code, tree, tree, tree));
-static tree optimize_minmax_comparison PARAMS ((tree));
-static tree extract_muldiv PARAMS ((tree, tree, enum tree_code, tree));
-static tree extract_muldiv_1 PARAMS ((tree, tree, enum tree_code, tree));
-static tree strip_compound_expr PARAMS ((tree, tree));
-static int multiple_of_p PARAMS ((tree, tree, tree));
-static tree constant_boolean_node PARAMS ((int, tree));
-static int count_cond PARAMS ((tree, int));
-static tree fold_binary_op_with_conditional_arg
- PARAMS ((enum tree_code, tree, tree, tree, int));
-static bool fold_real_zero_addition_p PARAMS ((tree, tree, int));
+#include "md5.h"
+
+static void encode (HOST_WIDE_INT *, unsigned HOST_WIDE_INT, HOST_WIDE_INT);
+static void decode (HOST_WIDE_INT *, unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
+static bool negate_mathfn_p (enum built_in_function);
+static bool negate_expr_p (tree);
+static tree negate_expr (tree);
+static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int);
+static tree associate_trees (tree, tree, enum tree_code, tree);
+static tree int_const_binop (enum tree_code, tree, tree, int);
+static tree const_binop (enum tree_code, tree, tree, int);
+static hashval_t size_htab_hash (const void *);
+static int size_htab_eq (const void *, const void *);
+static tree fold_convert_const (enum tree_code, tree, tree);
+static tree fold_convert (tree, tree);
+static enum tree_code invert_tree_comparison (enum tree_code);
+static enum tree_code swap_tree_comparison (enum tree_code);
+static int comparison_to_compcode (enum tree_code);
+static enum tree_code compcode_to_comparison (int);
+static int truth_value_p (enum tree_code);
+static int operand_equal_for_comparison_p (tree, tree, tree);
+static int twoval_comparison_p (tree, tree *, tree *, int *);
+static tree eval_subst (tree, tree, tree, tree, tree);
+static tree pedantic_omit_one_operand (tree, tree, tree);
+static tree distribute_bit_expr (enum tree_code, tree, tree, tree);
+static tree make_bit_field_ref (tree, tree, int, int, int);
+static tree optimize_bit_field_compare (enum tree_code, tree, tree, tree);
+static tree decode_field_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
+ enum machine_mode *, int *, int *,
+ tree *, tree *);
+static int all_ones_mask_p (tree, int);
+static tree sign_bit_p (tree, tree);
+static int simple_operand_p (tree);
+static tree range_binop (enum tree_code, tree, tree, int, tree, int);
+static tree make_range (tree, int *, tree *, tree *);
+static tree build_range_check (tree, tree, int, tree, tree);
+static int merge_ranges (int *, tree *, tree *, int, tree, tree, int, tree,
+ tree);
+static tree fold_range_test (tree);
+static tree unextend (tree, int, int, tree);
+static tree fold_truthop (enum tree_code, tree, tree, tree);
+static tree optimize_minmax_comparison (tree);
+static tree extract_muldiv (tree, tree, enum tree_code, tree);
+static tree extract_muldiv_1 (tree, tree, enum tree_code, tree);
+static tree strip_compound_expr (tree, tree);
+static int multiple_of_p (tree, tree, tree);
+static tree constant_boolean_node (int, tree);
+static int count_cond (tree, int);
+static tree fold_binary_op_with_conditional_arg (enum tree_code, tree, tree,
+ tree, int);
+static bool fold_real_zero_addition_p (tree, tree, int);
+static tree fold_mathfn_compare (enum built_in_function, enum tree_code,
+ tree, tree, tree);
+static tree fold_inf_compare (enum tree_code, tree, tree, tree);
+static bool reorder_operands_p (tree, tree);
+static bool tree_swap_operands_p (tree, tree, bool);
/* The following constants represent a bit based encoding of GCC's
comparison operators. This encoding simplifies transformations
@@ -149,10 +151,7 @@ static bool fold_real_zero_addition_p PARAMS ((tree, tree, int));
WORDS points to the array of HOST_WIDE_INTs. */
static void
-encode (words, low, hi)
- HOST_WIDE_INT *words;
- unsigned HOST_WIDE_INT low;
- HOST_WIDE_INT hi;
+encode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
{
words[0] = LOWPART (low);
words[1] = HIGHPART (low);
@@ -165,10 +164,8 @@ encode (words, low, hi)
The integer is stored into *LOW and *HI as two `HOST_WIDE_INT' pieces. */
static void
-decode (words, low, hi)
- HOST_WIDE_INT *words;
- unsigned HOST_WIDE_INT *low;
- HOST_WIDE_INT *hi;
+decode (HOST_WIDE_INT *words, unsigned HOST_WIDE_INT *low,
+ HOST_WIDE_INT *hi)
{
*low = words[0] + words[1] * BASE;
*hi = words[2] + words[3] * BASE;
@@ -182,9 +179,7 @@ decode (words, low, hi)
propagate it. */
int
-force_fit_type (t, overflow)
- tree t;
- int overflow;
+force_fit_type (tree t, int overflow)
{
unsigned HOST_WIDE_INT low;
HOST_WIDE_INT high;
@@ -203,7 +198,8 @@ force_fit_type (t, overflow)
low = TREE_INT_CST_LOW (t);
high = TREE_INT_CST_HIGH (t);
- if (POINTER_TYPE_P (TREE_TYPE (t)))
+ if (POINTER_TYPE_P (TREE_TYPE (t))
+ || TREE_CODE (TREE_TYPE (t)) == OFFSET_TYPE)
prec = POINTER_SIZE;
else
prec = TYPE_PRECISION (TREE_TYPE (t));
@@ -263,11 +259,9 @@ force_fit_type (t, overflow)
The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV. */
int
-add_double (l1, h1, l2, h2, lv, hv)
- unsigned HOST_WIDE_INT l1, l2;
- HOST_WIDE_INT h1, h2;
- unsigned HOST_WIDE_INT *lv;
- HOST_WIDE_INT *hv;
+add_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
+ unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
+ unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
{
unsigned HOST_WIDE_INT l;
HOST_WIDE_INT h;
@@ -286,11 +280,8 @@ add_double (l1, h1, l2, h2, lv, hv)
The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV. */
int
-neg_double (l1, h1, lv, hv)
- unsigned HOST_WIDE_INT l1;
- HOST_WIDE_INT h1;
- unsigned HOST_WIDE_INT *lv;
- HOST_WIDE_INT *hv;
+neg_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
+ unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
{
if (l1 == 0)
{
@@ -313,11 +304,9 @@ neg_double (l1, h1, lv, hv)
The value is stored as two `HOST_WIDE_INT' pieces in *LV and *HV. */
int
-mul_double (l1, h1, l2, h2, lv, hv)
- unsigned HOST_WIDE_INT l1, l2;
- HOST_WIDE_INT h1, h2;
- unsigned HOST_WIDE_INT *lv;
- HOST_WIDE_INT *hv;
+mul_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
+ unsigned HOST_WIDE_INT l2, HOST_WIDE_INT h2,
+ unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
{
HOST_WIDE_INT arg1[4];
HOST_WIDE_INT arg2[4];
@@ -330,7 +319,7 @@ mul_double (l1, h1, l2, h2, lv, hv)
encode (arg1, l1, h1);
encode (arg2, l2, h2);
- memset ((char *) prod, 0, sizeof prod);
+ memset (prod, 0, sizeof prod);
for (i = 0; i < 4; i++)
{
@@ -373,13 +362,9 @@ mul_double (l1, h1, l2, h2, lv, hv)
Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. */
void
-lshift_double (l1, h1, count, prec, lv, hv, arith)
- unsigned HOST_WIDE_INT l1;
- HOST_WIDE_INT h1, count;
- unsigned int prec;
- unsigned HOST_WIDE_INT *lv;
- HOST_WIDE_INT *hv;
- int arith;
+lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
+ HOST_WIDE_INT count, unsigned int prec,
+ unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv, int arith)
{
unsigned HOST_WIDE_INT signmask;
@@ -441,13 +426,10 @@ lshift_double (l1, h1, count, prec, lv, hv, arith)
Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. */
void
-rshift_double (l1, h1, count, prec, lv, hv, arith)
- unsigned HOST_WIDE_INT l1;
- HOST_WIDE_INT h1, count;
- unsigned int prec;
- unsigned HOST_WIDE_INT *lv;
- HOST_WIDE_INT *hv;
- int arith;
+rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
+ HOST_WIDE_INT count, unsigned int prec,
+ unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv,
+ int arith)
{
unsigned HOST_WIDE_INT signmask;
@@ -507,12 +489,9 @@ rshift_double (l1, h1, count, prec, lv, hv, arith)
Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. */
void
-lrotate_double (l1, h1, count, prec, lv, hv)
- unsigned HOST_WIDE_INT l1;
- HOST_WIDE_INT h1, count;
- unsigned int prec;
- unsigned HOST_WIDE_INT *lv;
- HOST_WIDE_INT *hv;
+lrotate_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
+ HOST_WIDE_INT count, unsigned int prec,
+ unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
{
unsigned HOST_WIDE_INT s1l, s2l;
HOST_WIDE_INT s1h, s2h;
@@ -532,12 +511,9 @@ lrotate_double (l1, h1, count, prec, lv, hv)
Store the value as two `HOST_WIDE_INT' pieces in *LV and *HV. */
void
-rrotate_double (l1, h1, count, prec, lv, hv)
- unsigned HOST_WIDE_INT l1;
- HOST_WIDE_INT h1, count;
- unsigned int prec;
- unsigned HOST_WIDE_INT *lv;
- HOST_WIDE_INT *hv;
+rrotate_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
+ HOST_WIDE_INT count, unsigned int prec,
+ unsigned HOST_WIDE_INT *lv, HOST_WIDE_INT *hv)
{
unsigned HOST_WIDE_INT s1l, s2l;
HOST_WIDE_INT s1h, s2h;
@@ -562,17 +538,14 @@ rrotate_double (l1, h1, count, prec, lv, hv)
UNS nonzero says do unsigned division. */
int
-div_and_round_double (code, uns,
- lnum_orig, hnum_orig, lden_orig, hden_orig,
- lquo, hquo, lrem, hrem)
- enum tree_code code;
- int uns;
- unsigned HOST_WIDE_INT lnum_orig; /* num == numerator == dividend */
- HOST_WIDE_INT hnum_orig;
- unsigned HOST_WIDE_INT lden_orig; /* den == denominator == divisor */
- HOST_WIDE_INT hden_orig;
- unsigned HOST_WIDE_INT *lquo, *lrem;
- HOST_WIDE_INT *hquo, *hrem;
+div_and_round_double (enum tree_code code, int uns,
+ unsigned HOST_WIDE_INT lnum_orig, /* num == numerator == dividend */
+ HOST_WIDE_INT hnum_orig,
+ unsigned HOST_WIDE_INT lden_orig, /* den == denominator == divisor */
+ HOST_WIDE_INT hden_orig,
+ unsigned HOST_WIDE_INT *lquo,
+ HOST_WIDE_INT *hquo, unsigned HOST_WIDE_INT *lrem,
+ HOST_WIDE_INT *hrem)
{
int quo_neg = 0;
HOST_WIDE_INT num[4 + 1]; /* extra element for scaling. */
@@ -589,7 +562,7 @@ div_and_round_double (code, uns,
if (hden == 0 && lden == 0)
overflow = 1, lden = 1;
- /* calculate quotient sign and convert operands to unsigned. */
+ /* Calculate quotient sign and convert operands to unsigned. */
if (!uns)
{
if (hnum < 0)
@@ -624,10 +597,10 @@ div_and_round_double (code, uns,
goto finish_up;
}
- memset ((char *) quo, 0, sizeof quo);
+ memset (quo, 0, sizeof quo);
- memset ((char *) num, 0, sizeof num); /* to zero 9th element */
- memset ((char *) den, 0, sizeof den);
+ memset (num, 0, sizeof num); /* to zero 9th element */
+ memset (den, 0, sizeof den);
encode (num, lnum, hnum);
encode (den, lden, hden);
@@ -745,7 +718,7 @@ div_and_round_double (code, uns,
decode (quo, lquo, hquo);
finish_up:
- /* if result is negative, make it so. */
+ /* If result is negative, make it so. */
if (quo_neg)
neg_double (*lquo, *hquo, lquo, hquo);
@@ -792,7 +765,7 @@ div_and_round_double (code, uns,
unsigned HOST_WIDE_INT labs_den = lden, ltwice;
HOST_WIDE_INT habs_den = hden, htwice;
- /* Get absolute values */
+ /* Get absolute values. */
if (*hrem < 0)
neg_double (*lrem, *hrem, &labs_rem, &habs_rem);
if (hden < 0)
@@ -826,19 +799,132 @@ div_and_round_double (code, uns,
abort ();
}
- /* compute true remainder: rem = num - (quo * den) */
+ /* Compute true remainder: rem = num - (quo * den) */
mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
neg_double (*lrem, *hrem, lrem, hrem);
add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
return overflow;
}
+/* Return true if built-in mathematical function specified by CODE
+ preserves the sign of it argument, i.e. -f(x) == f(-x). */
+
+static bool
+negate_mathfn_p (enum built_in_function code)
+{
+ switch (code)
+ {
+ case BUILT_IN_ASIN:
+ case BUILT_IN_ASINF:
+ case BUILT_IN_ASINL:
+ case BUILT_IN_ATAN:
+ case BUILT_IN_ATANF:
+ case BUILT_IN_ATANL:
+ case BUILT_IN_SIN:
+ case BUILT_IN_SINF:
+ case BUILT_IN_SINL:
+ case BUILT_IN_TAN:
+ case BUILT_IN_TANF:
+ case BUILT_IN_TANL:
+ return true;
+
+ default:
+ break;
+ }
+ return false;
+}
+
+
+/* Determine whether an expression T can be cheaply negated using
+ the function negate_expr. */
+
+static bool
+negate_expr_p (tree t)
+{
+ unsigned HOST_WIDE_INT val;
+ unsigned int prec;
+ tree type;
+
+ if (t == 0)
+ return false;
+
+ type = TREE_TYPE (t);
+
+ STRIP_SIGN_NOPS (t);
+ switch (TREE_CODE (t))
+ {
+ case INTEGER_CST:
+ if (TREE_UNSIGNED (type) || ! flag_trapv)
+ return true;
+
+ /* Check that -CST will not overflow type. */
+ prec = TYPE_PRECISION (type);
+ if (prec > HOST_BITS_PER_WIDE_INT)
+ {
+ if (TREE_INT_CST_LOW (t) != 0)
+ return true;
+ prec -= HOST_BITS_PER_WIDE_INT;
+ val = TREE_INT_CST_HIGH (t);
+ }
+ else
+ val = TREE_INT_CST_LOW (t);
+ if (prec < HOST_BITS_PER_WIDE_INT)
+ val &= ((unsigned HOST_WIDE_INT) 1 << prec) - 1;
+ return val != ((unsigned HOST_WIDE_INT) 1 << (prec - 1));
+
+ case REAL_CST:
+ case NEGATE_EXPR:
+ return true;
+
+ case COMPLEX_CST:
+ return negate_expr_p (TREE_REALPART (t))
+ && negate_expr_p (TREE_IMAGPART (t));
+
+ case MINUS_EXPR:
+ /* We can't turn -(A-B) into B-A when we honor signed zeros. */
+ return (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
+ && reorder_operands_p (TREE_OPERAND (t, 0),
+ TREE_OPERAND (t, 1));
+
+ case MULT_EXPR:
+ if (TREE_UNSIGNED (TREE_TYPE (t)))
+ break;
+
+ /* Fall through. */
+
+ case RDIV_EXPR:
+ if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (t))))
+ return negate_expr_p (TREE_OPERAND (t, 1))
+ || negate_expr_p (TREE_OPERAND (t, 0));
+ break;
+
+ case NOP_EXPR:
+ /* Negate -((double)float) as (double)(-float). */
+ if (TREE_CODE (type) == REAL_TYPE)
+ {
+ tree tem = strip_float_extensions (t);
+ if (tem != t)
+ return negate_expr_p (tem);
+ }
+ break;
+
+ case CALL_EXPR:
+ /* Negate -f(x) as f(-x). */
+ if (negate_mathfn_p (builtin_mathfn_code (t)))
+ return negate_expr_p (TREE_VALUE (TREE_OPERAND (t, 1)));
+ break;
+
+ default:
+ break;
+ }
+ return false;
+}
+
/* Given T, an expression, return the negation of T. Allow for T to be
null, in which case return null. */
static tree
-negate_expr (t)
- tree t;
+negate_expr (tree t)
{
tree type;
tree tem;
@@ -852,30 +938,113 @@ negate_expr (t)
switch (TREE_CODE (t))
{
case INTEGER_CST:
- case REAL_CST:
- if (! TREE_UNSIGNED (type)
- && 0 != (tem = fold (build1 (NEGATE_EXPR, type, t)))
- && ! TREE_OVERFLOW (tem))
+ {
+ unsigned HOST_WIDE_INT low;
+ HOST_WIDE_INT high;
+ int overflow = neg_double (TREE_INT_CST_LOW (t),
+ TREE_INT_CST_HIGH (t),
+ &low, &high);
+ tem = build_int_2 (low, high);
+ TREE_TYPE (tem) = type;
+ TREE_OVERFLOW (tem)
+ = (TREE_OVERFLOW (t)
+ | force_fit_type (tem, overflow && !TREE_UNSIGNED (type)));
+ TREE_CONSTANT_OVERFLOW (tem)
+ = TREE_OVERFLOW (tem) | TREE_CONSTANT_OVERFLOW (t);
+ }
+ if (! TREE_OVERFLOW (tem)
+ || TREE_UNSIGNED (type)
+ || ! flag_trapv)
return tem;
break;
+ case REAL_CST:
+ tem = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (t)));
+ /* Two's complement FP formats, such as c4x, may overflow. */
+ if (! TREE_OVERFLOW (tem) || ! flag_trapping_math)
+ return fold_convert (type, tem);
+ break;
+
+ case COMPLEX_CST:
+ {
+ tree rpart = negate_expr (TREE_REALPART (t));
+ tree ipart = negate_expr (TREE_IMAGPART (t));
+
+ if ((TREE_CODE (rpart) == REAL_CST
+ && TREE_CODE (ipart) == REAL_CST)
+ || (TREE_CODE (rpart) == INTEGER_CST
+ && TREE_CODE (ipart) == INTEGER_CST))
+ return build_complex (type, rpart, ipart);
+ }
+ break;
+
case NEGATE_EXPR:
- return convert (type, TREE_OPERAND (t, 0));
+ return fold_convert (type, TREE_OPERAND (t, 0));
case MINUS_EXPR:
/* - (A - B) -> B - A */
- if (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
- return convert (type,
- fold (build (MINUS_EXPR, TREE_TYPE (t),
- TREE_OPERAND (t, 1),
- TREE_OPERAND (t, 0))));
+ if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
+ && reorder_operands_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)))
+ return fold_convert (type,
+ fold (build (MINUS_EXPR, TREE_TYPE (t),
+ TREE_OPERAND (t, 1),
+ TREE_OPERAND (t, 0))));
+ break;
+
+ case MULT_EXPR:
+ if (TREE_UNSIGNED (TREE_TYPE (t)))
+ break;
+
+ /* Fall through. */
+
+ case RDIV_EXPR:
+ if (! HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (TREE_TYPE (t))))
+ {
+ tem = TREE_OPERAND (t, 1);
+ if (negate_expr_p (tem))
+ return fold_convert (type,
+ fold (build (TREE_CODE (t), TREE_TYPE (t),
+ TREE_OPERAND (t, 0),
+ negate_expr (tem))));
+ tem = TREE_OPERAND (t, 0);
+ if (negate_expr_p (tem))
+ return fold_convert (type,
+ fold (build (TREE_CODE (t), TREE_TYPE (t),
+ negate_expr (tem),
+ TREE_OPERAND (t, 1))));
+ }
+ break;
+
+ case NOP_EXPR:
+ /* Convert -((double)float) into (double)(-float). */
+ if (TREE_CODE (type) == REAL_TYPE)
+ {
+ tem = strip_float_extensions (t);
+ if (tem != t && negate_expr_p (tem))
+ return fold_convert (type, negate_expr (tem));
+ }
+ break;
+
+ case CALL_EXPR:
+ /* Negate -f(x) as f(-x). */
+ if (negate_mathfn_p (builtin_mathfn_code (t))
+ && negate_expr_p (TREE_VALUE (TREE_OPERAND (t, 1))))
+ {
+ tree fndecl, arg, arglist;
+
+ fndecl = get_callee_fndecl (t);
+ arg = negate_expr (TREE_VALUE (TREE_OPERAND (t, 1)));
+ arglist = build_tree_list (NULL_TREE, arg);
+ return build_function_call_expr (fndecl, arglist);
+ }
break;
default:
break;
}
- return convert (type, fold (build1 (NEGATE_EXPR, TREE_TYPE (t), t)));
+ tem = fold (build1 (NEGATE_EXPR, TREE_TYPE (t), t));
+ return fold_convert (type, tem);
}
/* Split a tree IN into a constant, literal and variable parts that could be
@@ -899,11 +1068,8 @@ negate_expr (t)
same type as IN, but they will have the same signedness and mode. */
static tree
-split_tree (in, code, conp, litp, minus_litp, negate_p)
- tree in;
- enum tree_code code;
- tree *conp, *litp, *minus_litp;
- int negate_p;
+split_tree (tree in, enum tree_code code, tree *conp, tree *litp,
+ tree *minus_litp, int negate_p)
{
tree var = 0;
@@ -981,10 +1147,7 @@ split_tree (in, code, conp, litp, minus_litp, negate_p)
we build an operation, do it in TYPE and with CODE. */
static tree
-associate_trees (t1, t2, code, type)
- tree t1, t2;
- enum tree_code code;
- tree type;
+associate_trees (tree t1, tree t2, enum tree_code code, tree type)
{
if (t1 == 0)
return t2;
@@ -1000,16 +1163,18 @@ associate_trees (t1, t2, code, type)
if (code == PLUS_EXPR)
{
if (TREE_CODE (t1) == NEGATE_EXPR)
- return build (MINUS_EXPR, type, convert (type, t2),
- convert (type, TREE_OPERAND (t1, 0)));
+ return build (MINUS_EXPR, type, fold_convert (type, t2),
+ fold_convert (type, TREE_OPERAND (t1, 0)));
else if (TREE_CODE (t2) == NEGATE_EXPR)
- return build (MINUS_EXPR, type, convert (type, t1),
- convert (type, TREE_OPERAND (t2, 0)));
+ return build (MINUS_EXPR, type, fold_convert (type, t1),
+ fold_convert (type, TREE_OPERAND (t2, 0)));
}
- return build (code, type, convert (type, t1), convert (type, t2));
+ return build (code, type, fold_convert (type, t1),
+ fold_convert (type, t2));
}
- return fold (build (code, type, convert (type, t1), convert (type, t2)));
+ return fold (build (code, type, fold_convert (type, t1),
+ fold_convert (type, t2)));
}
/* Combine two integer constants ARG1 and ARG2 under operation CODE
@@ -1018,10 +1183,7 @@ associate_trees (t1, t2, code, type)
If NOTRUNC is nonzero, do not truncate the result to fit the data type. */
static tree
-int_const_binop (code, arg1, arg2, notrunc)
- enum tree_code code;
- tree arg1, arg2;
- int notrunc;
+int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
{
unsigned HOST_WIDE_INT int1l, int2l;
HOST_WIDE_INT int1h, int2h;
@@ -1056,10 +1218,6 @@ int_const_binop (code, arg1, arg2, notrunc)
low = int1l & int2l, hi = int1h & int2h;
break;
- case BIT_ANDTC_EXPR:
- low = int1l & ~int2l, hi = int1h & ~int2h;
- break;
-
case RSHIFT_EXPR:
int2l = -int2l;
case LSHIFT_EXPR:
@@ -1213,10 +1371,7 @@ int_const_binop (code, arg1, arg2, notrunc)
If NOTRUNC is nonzero, do not truncate the result to fit the data type. */
static tree
-const_binop (code, arg1, arg2, notrunc)
- enum tree_code code;
- tree arg1, arg2;
- int notrunc;
+const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
{
STRIP_NOPS (arg1);
STRIP_NOPS (arg2);
@@ -1226,14 +1381,31 @@ const_binop (code, arg1, arg2, notrunc)
if (TREE_CODE (arg1) == REAL_CST)
{
+ enum machine_mode mode;
REAL_VALUE_TYPE d1;
REAL_VALUE_TYPE d2;
REAL_VALUE_TYPE value;
- tree t;
+ tree t, type;
d1 = TREE_REAL_CST (arg1);
d2 = TREE_REAL_CST (arg2);
+ type = TREE_TYPE (arg1);
+ mode = TYPE_MODE (type);
+
+ /* Don't perform operation if we honor signaling NaNs and
+ either operand is a NaN. */
+ if (HONOR_SNANS (mode)
+ && (REAL_VALUE_ISNAN (d1) || REAL_VALUE_ISNAN (d2)))
+ return NULL_TREE;
+
+ /* Don't perform operation if it would raise a division
+ by zero exception. */
+ if (code == RDIV_EXPR
+ && REAL_VALUES_EQUAL (d2, dconst0)
+ && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
+ return NULL_TREE;
+
/* If either operand is a NaN, just return it. Otherwise, set up
for floating-point trap; we return an overflow. */
if (REAL_VALUE_ISNAN (d1))
@@ -1243,9 +1415,7 @@ const_binop (code, arg1, arg2, notrunc)
REAL_ARITHMETIC (value, code, d1, d2);
- t = build_real (TREE_TYPE (arg1),
- real_value_truncate (TYPE_MODE (TREE_TYPE (arg1)),
- value));
+ t = build_real (type, real_value_truncate (mode, value));
TREE_OVERFLOW (t)
= (force_fit_type (t, 0)
@@ -1341,8 +1511,7 @@ const_binop (code, arg1, arg2, notrunc)
/* Return the hash code code X, an INTEGER_CST. */
static hashval_t
-size_htab_hash (x)
- const void *x;
+size_htab_hash (const void *x)
{
tree t = (tree) x;
@@ -1355,9 +1524,7 @@ size_htab_hash (x)
is the same as that given by *Y, which is the same. */
static int
-size_htab_eq (x, y)
- const void *x;
- const void *y;
+size_htab_eq (const void *x, const void *y)
{
tree xt = (tree) x;
tree yt = (tree) y;
@@ -1372,9 +1539,7 @@ size_htab_eq (x, y)
bits are given by NUMBER and of the sizetype represented by KIND. */
tree
-size_int_wide (number, kind)
- HOST_WIDE_INT number;
- enum size_type_kind kind;
+size_int_wide (HOST_WIDE_INT number, enum size_type_kind kind)
{
return size_int_type_wide (number, sizetype_tab[(int) kind]);
}
@@ -1386,15 +1551,13 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
htab_t size_htab;
tree
-size_int_type_wide (number, type)
- HOST_WIDE_INT number;
- tree type;
+size_int_type_wide (HOST_WIDE_INT number, tree type)
{
- PTR *slot;
+ void **slot;
if (size_htab == 0)
{
- size_htab = htab_create (1024, size_htab_hash, size_htab_eq, NULL);
+ size_htab = htab_create_ggc (1024, size_htab_hash, size_htab_eq, NULL);
new_const = make_node (INTEGER_CST);
}
@@ -1412,7 +1575,7 @@ size_int_type_wide (number, type)
{
tree t = new_const;
- *slot = (PTR) new_const;
+ *slot = new_const;
new_const = make_node (INTEGER_CST);
return t;
}
@@ -1426,9 +1589,7 @@ size_int_type_wide (number, type)
If the operands are constant, so is the result. */
tree
-size_binop (code, arg0, arg1)
- enum tree_code code;
- tree arg0, arg1;
+size_binop (enum tree_code code, tree arg0, tree arg1)
{
tree type = TREE_TYPE (arg0);
@@ -1463,8 +1624,7 @@ size_binop (code, arg0, arg1)
in signed type corresponding to the type of the operands. */
tree
-size_diffop (arg0, arg1)
- tree arg0, arg1;
+size_diffop (tree arg0, tree arg1)
{
tree type = TREE_TYPE (arg0);
tree ctype;
@@ -1484,33 +1644,36 @@ size_diffop (arg0, arg1)
type and subtract. The hardware will do the right thing with any
overflow in the subtraction. */
if (TREE_CODE (arg0) != INTEGER_CST || TREE_CODE (arg1) != INTEGER_CST)
- return size_binop (MINUS_EXPR, convert (ctype, arg0),
- convert (ctype, arg1));
+ return size_binop (MINUS_EXPR, fold_convert (ctype, arg0),
+ fold_convert (ctype, arg1));
/* If ARG0 is larger than ARG1, subtract and return the result in CTYPE.
Otherwise, subtract the other way, convert to CTYPE (we know that can't
overflow) and negate (which can't either). Special-case a result
of zero while we're here. */
if (tree_int_cst_equal (arg0, arg1))
- return convert (ctype, integer_zero_node);
+ return fold_convert (ctype, integer_zero_node);
else if (tree_int_cst_lt (arg1, arg0))
- return convert (ctype, size_binop (MINUS_EXPR, arg0, arg1));
+ return fold_convert (ctype, size_binop (MINUS_EXPR, arg0, arg1));
else
- return size_binop (MINUS_EXPR, convert (ctype, integer_zero_node),
- convert (ctype, size_binop (MINUS_EXPR, arg1, arg0)));
+ return size_binop (MINUS_EXPR, fold_convert (ctype, integer_zero_node),
+ fold_convert (ctype, size_binop (MINUS_EXPR,
+ arg1, arg0)));
}
-/* Given T, a tree representing type conversion of ARG1, a constant,
- return a constant tree representing the result of conversion. */
+/* Attempt to fold type conversion operation CODE of expression ARG1 to
+ type TYPE. If no simplification can be done return NULL_TREE. */
static tree
-fold_convert (t, arg1)
- tree t;
- tree arg1;
+fold_convert_const (enum tree_code code ATTRIBUTE_UNUSED, tree type,
+ tree arg1)
{
- tree type = TREE_TYPE (t);
int overflow = 0;
+ tree t;
+
+ if (TREE_TYPE (arg1) == type)
+ return arg1;
if (POINTER_TYPE_P (type) || INTEGRAL_TYPE_P (type))
{
@@ -1519,7 +1682,7 @@ fold_convert (t, arg1)
/* If we would build a constant wider than GCC supports,
leave the conversion unfolded. */
if (TYPE_PRECISION (type) > 2 * HOST_BITS_PER_WIDE_INT)
- return t;
+ return NULL_TREE;
/* If we are trying to make a sizetype for a small integer, use
size_int to pick up cached types to reduce duplicate nodes. */
@@ -1547,51 +1710,74 @@ fold_convert (t, arg1)
|| TREE_OVERFLOW (arg1));
TREE_CONSTANT_OVERFLOW (t)
= TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
+ return t;
}
else if (TREE_CODE (arg1) == REAL_CST)
{
- /* Don't initialize these, use assignments.
- Initialized local aggregates don't work on old compilers. */
- REAL_VALUE_TYPE x;
- REAL_VALUE_TYPE l;
- REAL_VALUE_TYPE u;
- tree type1 = TREE_TYPE (arg1);
- int no_upper_bound;
-
- x = TREE_REAL_CST (arg1);
- l = real_value_from_int_cst (type1, TYPE_MIN_VALUE (type));
-
- no_upper_bound = (TYPE_MAX_VALUE (type) == NULL);
- if (!no_upper_bound)
- u = real_value_from_int_cst (type1, TYPE_MAX_VALUE (type));
+ /* The following code implements the floating point to integer
+ conversion rules required by the Java Language Specification,
+ that IEEE NaNs are mapped to zero and values that overflow
+ the target precision saturate, i.e. values greater than
+ INT_MAX are mapped to INT_MAX, and values less than INT_MIN
+ are mapped to INT_MIN. These semantics are allowed by the
+ C and C++ standards that simply state that the behavior of
+ FP-to-integer conversion is unspecified upon overflow. */
+
+ HOST_WIDE_INT high, low;
+
+ REAL_VALUE_TYPE x = TREE_REAL_CST (arg1);
+ /* If x is NaN, return zero and show we have an overflow. */
+ if (REAL_VALUE_ISNAN (x))
+ {
+ overflow = 1;
+ high = 0;
+ low = 0;
+ }
/* See if X will be in range after truncation towards 0.
To compensate for truncation, move the bounds away from 0,
but reject if X exactly equals the adjusted bounds. */
- REAL_ARITHMETIC (l, MINUS_EXPR, l, dconst1);
- if (!no_upper_bound)
- REAL_ARITHMETIC (u, PLUS_EXPR, u, dconst1);
- /* If X is a NaN, use zero instead and show we have an overflow.
- Otherwise, range check. */
- if (REAL_VALUE_ISNAN (x))
- overflow = 1, x = dconst0;
- else if (! (REAL_VALUES_LESS (l, x)
- && !no_upper_bound
- && REAL_VALUES_LESS (x, u)))
- overflow = 1;
- {
- HOST_WIDE_INT low, high;
+ if (! overflow)
+ {
+ tree lt = TYPE_MIN_VALUE (type);
+ REAL_VALUE_TYPE l = real_value_from_int_cst (NULL_TREE, lt);
+ REAL_ARITHMETIC (l, MINUS_EXPR, l, dconst1);
+ if (! REAL_VALUES_LESS (l, x))
+ {
+ overflow = 1;
+ high = TREE_INT_CST_HIGH (lt);
+ low = TREE_INT_CST_LOW (lt);
+ }
+ }
+
+ if (! overflow)
+ {
+ tree ut = TYPE_MAX_VALUE (type);
+ if (ut)
+ {
+ REAL_VALUE_TYPE u = real_value_from_int_cst (NULL_TREE, ut);
+ REAL_ARITHMETIC (u, PLUS_EXPR, u, dconst1);
+ if (! REAL_VALUES_LESS (x, u))
+ {
+ overflow = 1;
+ high = TREE_INT_CST_HIGH (ut);
+ low = TREE_INT_CST_LOW (ut);
+ }
+ }
+ }
+
+ if (! overflow)
REAL_VALUE_TO_INT (&low, &high, x);
- t = build_int_2 (low, high);
- }
+
+ t = build_int_2 (low, high);
TREE_TYPE (t) = type;
TREE_OVERFLOW (t)
= TREE_OVERFLOW (arg1) | force_fit_type (t, overflow);
TREE_CONSTANT_OVERFLOW (t)
= TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg1);
+ return t;
}
- TREE_TYPE (t) = type;
}
else if (TREE_CODE (type) == REAL_TYPE)
{
@@ -1619,15 +1805,122 @@ fold_convert (t, arg1)
return t;
}
}
- TREE_CONSTANT (t) = 1;
- return t;
+ return NULL_TREE;
+}
+
+/* Convert expression ARG to type TYPE. Used by the middle-end for
+ simple conversions in preference to calling the front-end's convert. */
+
+static tree
+fold_convert (tree type, tree arg)
+{
+ tree orig = TREE_TYPE (arg);
+ tree tem;
+
+ if (type == orig)
+ return arg;
+
+ if (TREE_CODE (arg) == ERROR_MARK
+ || TREE_CODE (type) == ERROR_MARK
+ || TREE_CODE (orig) == ERROR_MARK)
+ return error_mark_node;
+
+ if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (orig))
+ return fold (build1 (NOP_EXPR, type, arg));
+
+ if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
+ {
+ if (TREE_CODE (arg) == INTEGER_CST)
+ {
+ tem = fold_convert_const (NOP_EXPR, type, arg);
+ if (tem != NULL_TREE)
+ return tem;
+ }
+ if (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig))
+ return fold (build1 (NOP_EXPR, type, arg));
+ if (TREE_CODE (orig) == COMPLEX_TYPE)
+ {
+ tem = fold (build1 (REALPART_EXPR, TREE_TYPE (orig), arg));
+ return fold_convert (type, tem);
+ }
+ if (TREE_CODE (orig) == VECTOR_TYPE
+ && GET_MODE_SIZE (TYPE_MODE (type))
+ == GET_MODE_SIZE (TYPE_MODE (orig)))
+ return fold (build1 (NOP_EXPR, type, arg));
+ }
+ else if (TREE_CODE (type) == REAL_TYPE)
+ {
+ if (TREE_CODE (arg) == INTEGER_CST)
+ {
+ tem = fold_convert_const (FLOAT_EXPR, type, arg);
+ if (tem != NULL_TREE)
+ return tem;
+ }
+ else if (TREE_CODE (arg) == REAL_CST)
+ {
+ tem = fold_convert_const (NOP_EXPR, type, arg);
+ if (tem != NULL_TREE)
+ return tem;
+ }
+
+ if (INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig))
+ return fold (build1 (FLOAT_EXPR, type, arg));
+ if (TREE_CODE (orig) == REAL_TYPE)
+ return fold (build1 (flag_float_store ? CONVERT_EXPR : NOP_EXPR,
+ type, arg));
+ if (TREE_CODE (orig) == COMPLEX_TYPE)
+ {
+ tem = fold (build1 (REALPART_EXPR, TREE_TYPE (orig), arg));
+ return fold_convert (type, tem);
+ }
+ }
+ else if (TREE_CODE (type) == COMPLEX_TYPE)
+ {
+ if (INTEGRAL_TYPE_P (orig)
+ || POINTER_TYPE_P (orig)
+ || TREE_CODE (orig) == REAL_TYPE)
+ return build (COMPLEX_EXPR, type,
+ fold_convert (TREE_TYPE (type), arg),
+ fold_convert (TREE_TYPE (type), integer_zero_node));
+ if (TREE_CODE (orig) == COMPLEX_TYPE)
+ {
+ tree rpart, ipart;
+
+ if (TREE_CODE (arg) == COMPLEX_EXPR)
+ {
+ rpart = fold_convert (TREE_TYPE (type), TREE_OPERAND (arg, 0));
+ ipart = fold_convert (TREE_TYPE (type), TREE_OPERAND (arg, 1));
+ return fold (build (COMPLEX_EXPR, type, rpart, ipart));
+ }
+
+ arg = save_expr (arg);
+ rpart = fold (build1 (REALPART_EXPR, TREE_TYPE (orig), arg));
+ ipart = fold (build1 (IMAGPART_EXPR, TREE_TYPE (orig), arg));
+ rpart = fold_convert (TREE_TYPE (type), rpart);
+ ipart = fold_convert (TREE_TYPE (type), ipart);
+ return fold (build (COMPLEX_EXPR, type, rpart, ipart));
+ }
+ }
+ else if (TREE_CODE (type) == VECTOR_TYPE)
+ {
+ if ((INTEGRAL_TYPE_P (orig) || POINTER_TYPE_P (orig))
+ && GET_MODE_SIZE (TYPE_MODE (type))
+ == GET_MODE_SIZE (TYPE_MODE (orig)))
+ return fold (build1 (NOP_EXPR, type, arg));
+ if (TREE_CODE (orig) == VECTOR_TYPE
+ && GET_MODE_SIZE (TYPE_MODE (type))
+ == GET_MODE_SIZE (TYPE_MODE (orig)))
+ return fold (build1 (NOP_EXPR, type, arg));
+ }
+ else if (VOID_TYPE_P (type))
+ return fold (build1 (CONVERT_EXPR, type, arg));
+ abort ();
}
/* Return an expr equal to X but certainly not valid as an lvalue. */
tree
-non_lvalue (x)
- tree x;
+non_lvalue (tree x)
{
tree result;
@@ -1653,8 +1946,7 @@ int pedantic_lvalues;
pedantic lvalue. Otherwise, return X. */
tree
-pedantic_non_lvalue (x)
- tree x;
+pedantic_non_lvalue (tree x)
{
if (pedantic_lvalues)
return non_lvalue (x);
@@ -1667,8 +1959,7 @@ pedantic_non_lvalue (x)
comparisons, except for NE_EXPR and EQ_EXPR. */
static enum tree_code
-invert_tree_comparison (code)
- enum tree_code code;
+invert_tree_comparison (enum tree_code code)
{
switch (code)
{
@@ -1693,8 +1984,7 @@ invert_tree_comparison (code)
swapped. This is safe for floating-point. */
static enum tree_code
-swap_tree_comparison (code)
- enum tree_code code;
+swap_tree_comparison (enum tree_code code)
{
switch (code)
{
@@ -1720,8 +2010,7 @@ swap_tree_comparison (code)
compcode_to_comparison. */
static int
-comparison_to_compcode (code)
- enum tree_code code;
+comparison_to_compcode (enum tree_code code)
{
switch (code)
{
@@ -1747,8 +2036,7 @@ comparison_to_compcode (code)
inverse of comparison_to_compcode. */
static enum tree_code
-compcode_to_comparison (code)
- int code;
+compcode_to_comparison (int code)
{
switch (code)
{
@@ -1772,8 +2060,7 @@ compcode_to_comparison (code)
/* Return nonzero if CODE is a tree code that represents a truth value. */
static int
-truth_value_p (code)
- enum tree_code code;
+truth_value_p (enum tree_code code)
{
return (TREE_CODE_CLASS (code) == '<'
|| code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
@@ -1781,19 +2068,33 @@ truth_value_p (code)
|| code == TRUTH_XOR_EXPR || code == TRUTH_NOT_EXPR);
}
-/* Return nonzero if two operands are necessarily equal.
+/* Return nonzero if two operands (typically of the same tree node)
+ are necessarily equal. If either argument has side-effects this
+ function returns zero.
+
If ONLY_CONST is nonzero, only return nonzero for constants.
This function tests whether the operands are indistinguishable;
it does not test whether they are equal using C's == operation.
The distinction is important for IEEE floating point, because
(1) -0.0 and 0.0 are distinguishable, but -0.0==0.0, and
- (2) two NaNs may be indistinguishable, but NaN!=NaN. */
+ (2) two NaNs may be indistinguishable, but NaN!=NaN.
+
+ If ONLY_CONST is zero, a VAR_DECL is considered equal to itself
+ even though it may hold multiple values during a function.
+ This is because a GCC tree node guarantees that nothing else is
+ executed between the evaluation of its "operands" (which may often
+ be evaluated in arbitrary order). Hence if the operands themselves
+ don't side-effect, the VAR_DECLs, PARM_DECLs etc... must hold the
+ same value in each operand/subexpression. Hence a zero value for
+ ONLY_CONST assumes isochronic (or instantaneous) tree equivalence.
+ If comparing arbitrary expression trees, such as from different
+ statements, ONLY_CONST must usually be nonzero. */
int
-operand_equal_p (arg0, arg1, only_const)
- tree arg0, arg1;
- int only_const;
+operand_equal_p (tree arg0, tree arg1, int only_const)
{
+ tree fndecl;
+
/* If both types don't have the same signedness, then we can't consider
them equal. We must check this before the STRIP_NOPS calls
because they may change the signedness of the arguments. */
@@ -1914,8 +2215,8 @@ operand_equal_p (arg0, arg1, only_const)
TREE_OPERAND (arg1, 0), 0));
case 'r':
- /* If either of the pointer (or reference) expressions we are dereferencing
- contain a side effect, these cannot be equal. */
+ /* If either of the pointer (or reference) expressions we are
+ dereferencing contain a side effect, these cannot be equal. */
if (TREE_SIDE_EFFECTS (arg0)
|| TREE_SIDE_EFFECTS (arg1))
return 0;
@@ -1946,9 +2247,57 @@ operand_equal_p (arg0, arg1, only_const)
}
case 'e':
- if (TREE_CODE (arg0) == RTL_EXPR)
- return rtx_equal_p (RTL_EXPR_RTL (arg0), RTL_EXPR_RTL (arg1));
- return 0;
+ switch (TREE_CODE (arg0))
+ {
+ case ADDR_EXPR:
+ case TRUTH_NOT_EXPR:
+ return operand_equal_p (TREE_OPERAND (arg0, 0),
+ TREE_OPERAND (arg1, 0), 0);
+
+ case RTL_EXPR:
+ return rtx_equal_p (RTL_EXPR_RTL (arg0), RTL_EXPR_RTL (arg1));
+
+ case CALL_EXPR:
+ /* If the CALL_EXPRs call different functions, then they
+ clearly can not be equal. */
+ if (! operand_equal_p (TREE_OPERAND (arg0, 0),
+ TREE_OPERAND (arg1, 0), 0))
+ return 0;
+
+ /* Only consider const functions equivalent. */
+ fndecl = get_callee_fndecl (arg0);
+ if (fndecl == NULL_TREE
+ || ! (flags_from_decl_or_type (fndecl) & ECF_CONST))
+ return 0;
+
+ /* Now see if all the arguments are the same. operand_equal_p
+ does not handle TREE_LIST, so we walk the operands here
+ feeding them to operand_equal_p. */
+ arg0 = TREE_OPERAND (arg0, 1);
+ arg1 = TREE_OPERAND (arg1, 1);
+ while (arg0 && arg1)
+ {
+ if (! operand_equal_p (TREE_VALUE (arg0), TREE_VALUE (arg1), 0))
+ return 0;
+
+ arg0 = TREE_CHAIN (arg0);
+ arg1 = TREE_CHAIN (arg1);
+ }
+
+ /* If we get here and both argument lists are exhausted
+ then the CALL_EXPRs are equal. */
+ return ! (arg0 || arg1);
+
+ default:
+ return 0;
+ }
+
+ case 'd':
+ /* Consider __builtin_sqrt equal to sqrt. */
+ return TREE_CODE (arg0) == FUNCTION_DECL
+ && DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1)
+ && DECL_BUILT_IN_CLASS (arg0) == DECL_BUILT_IN_CLASS (arg1)
+ && DECL_FUNCTION_CODE (arg0) == DECL_FUNCTION_CODE (arg1);
default:
return 0;
@@ -1961,9 +2310,7 @@ operand_equal_p (arg0, arg1, only_const)
When in doubt, return 0. */
static int
-operand_equal_for_comparison_p (arg0, arg1, other)
- tree arg0, arg1;
- tree other;
+operand_equal_for_comparison_p (tree arg0, tree arg1, tree other)
{
int unsignedp1, unsignedpo;
tree primarg0, primarg1, primother;
@@ -2003,10 +2350,10 @@ operand_equal_for_comparison_p (arg0, arg1, other)
/* Make sure shorter operand is extended the right way
to match the longer operand. */
- primarg1 = convert ((*lang_hooks.types.signed_or_unsigned_type)
- (unsignedp1, TREE_TYPE (primarg1)), primarg1);
+ primarg1 = fold_convert ((*lang_hooks.types.signed_or_unsigned_type)
+ (unsignedp1, TREE_TYPE (primarg1)), primarg1);
- if (operand_equal_p (arg0, convert (type, primarg1), 0))
+ if (operand_equal_p (arg0, fold_convert (type, primarg1), 0))
return 1;
}
@@ -2024,10 +2371,7 @@ operand_equal_for_comparison_p (arg0, arg1, other)
If this is true, return 1. Otherwise, return zero. */
static int
-twoval_comparison_p (arg, cval1, cval2, save_p)
- tree arg;
- tree *cval1, *cval2;
- int *save_p;
+twoval_comparison_p (tree arg, tree *cval1, tree *cval2, int *save_p)
{
enum tree_code code = TREE_CODE (arg);
char class = TREE_CODE_CLASS (code);
@@ -2119,9 +2463,7 @@ twoval_comparison_p (arg, cval1, cval2, save_p)
NEW1 and OLD1. */
static tree
-eval_subst (arg, old0, new0, old1, new1)
- tree arg;
- tree old0, new0, old1, new1;
+eval_subst (tree arg, tree old0, tree new0, tree old1, tree new1)
{
tree type = TREE_TYPE (arg);
enum tree_code code = TREE_CODE (arg);
@@ -2168,7 +2510,7 @@ eval_subst (arg, old0, new0, old1, new1)
default:
break;
}
- /* fall through - ??? */
+ /* Fall through - ??? */
case '<':
{
@@ -2204,11 +2546,10 @@ eval_subst (arg, old0, new0, old1, new1)
If OMITTED has side effects, we must evaluate it. Otherwise, just do
the conversion of RESULT to TYPE. */
-static tree
-omit_one_operand (type, result, omitted)
- tree type, result, omitted;
+tree
+omit_one_operand (tree type, tree result, tree omitted)
{
- tree t = convert (type, result);
+ tree t = fold_convert (type, result);
if (TREE_SIDE_EFFECTS (omitted))
return build (COMPOUND_EXPR, type, omitted, t);
@@ -2219,10 +2560,9 @@ omit_one_operand (type, result, omitted)
/* Similar, but call pedantic_non_lvalue instead of non_lvalue. */
static tree
-pedantic_omit_one_operand (type, result, omitted)
- tree type, result, omitted;
+pedantic_omit_one_operand (tree type, tree result, tree omitted)
{
- tree t = convert (type, result);
+ tree t = fold_convert (type, result);
if (TREE_SIDE_EFFECTS (omitted))
return build (COMPOUND_EXPR, type, omitted, t);
@@ -2235,8 +2575,7 @@ pedantic_omit_one_operand (type, result, omitted)
returns a truth value (0 or 1). */
tree
-invert_truthvalue (arg)
- tree arg;
+invert_truthvalue (tree arg)
{
tree type = TREE_TYPE (arg);
enum tree_code code = TREE_CODE (arg);
@@ -2263,7 +2602,7 @@ invert_truthvalue (arg)
switch (code)
{
case INTEGER_CST:
- return convert (type, build_int_2 (integer_zerop (arg), 0));
+ return fold_convert (type, build_int_2 (integer_zerop (arg), 0));
case TRUTH_AND_EXPR:
return build (TRUTH_OR_EXPR, type,
@@ -2328,7 +2667,8 @@ invert_truthvalue (arg)
case BIT_AND_EXPR:
if (!integer_onep (TREE_OPERAND (arg, 1)))
break;
- return build (EQ_EXPR, type, arg, convert (type, integer_zero_node));
+ return build (EQ_EXPR, type, arg,
+ fold_convert (type, integer_zero_node));
case SAVE_EXPR:
return build1 (TRUTH_NOT_EXPR, type, arg);
@@ -2349,16 +2689,13 @@ invert_truthvalue (arg)
operands are another bit-wise operation with a common input. If so,
distribute the bit operations to save an operation and possibly two if
constants are involved. For example, convert
- (A | B) & (A | C) into A | (B & C)
+ (A | B) & (A | C) into A | (B & C)
Further simplification will occur if B and C are constants.
If this optimization cannot be done, 0 will be returned. */
static tree
-distribute_bit_expr (code, type, arg0, arg1)
- enum tree_code code;
- tree type;
- tree arg0, arg1;
+distribute_bit_expr (enum tree_code code, tree type, tree arg0, tree arg1)
{
tree common;
tree left, right;
@@ -2404,11 +2741,8 @@ distribute_bit_expr (code, type, arg0, arg1)
starting at BITPOS. The field is unsigned if UNSIGNEDP is nonzero. */
static tree
-make_bit_field_ref (inner, type, bitsize, bitpos, unsignedp)
- tree inner;
- tree type;
- int bitsize, bitpos;
- int unsignedp;
+make_bit_field_ref (tree inner, tree type, int bitsize, int bitpos,
+ int unsignedp)
{
tree result = build (BIT_FIELD_REF, type, inner,
size_int (bitsize), bitsize_int (bitpos));
@@ -2439,10 +2773,8 @@ make_bit_field_ref (inner, type, bitsize, bitpos, unsignedp)
tree. Otherwise we return zero. */
static tree
-optimize_bit_field_compare (code, compare_type, lhs, rhs)
- enum tree_code code;
- tree compare_type;
- tree lhs, rhs;
+optimize_bit_field_compare (enum tree_code code, tree compare_type,
+ tree lhs, tree rhs)
{
HOST_WIDE_INT lbitpos, lbitsize, rbitpos, rbitsize, nbitpos, nbitsize;
tree type = TREE_TYPE (lhs);
@@ -2510,7 +2842,7 @@ optimize_bit_field_compare (code, compare_type, lhs, rhs)
mask = build_int_2 (~0, ~0);
TREE_TYPE (mask) = unsigned_type;
force_fit_type (mask, 0);
- mask = convert (unsigned_type, mask);
+ mask = fold_convert (unsigned_type, mask);
mask = const_binop (LSHIFT_EXPR, mask, size_int (nbitsize - lbitsize), 0);
mask = const_binop (RSHIFT_EXPR, mask,
size_int (nbitsize - lbitsize - lbitpos), 0);
@@ -2540,27 +2872,27 @@ optimize_bit_field_compare (code, compare_type, lhs, rhs)
if (lunsignedp)
{
if (! integer_zerop (const_binop (RSHIFT_EXPR,
- convert (unsigned_type, rhs),
+ fold_convert (unsigned_type, rhs),
size_int (lbitsize), 0)))
{
warning ("comparison is always %d due to width of bit-field",
code == NE_EXPR);
- return convert (compare_type,
- (code == NE_EXPR
- ? integer_one_node : integer_zero_node));
+ return fold_convert (compare_type,
+ (code == NE_EXPR
+ ? integer_one_node : integer_zero_node));
}
}
else
{
- tree tem = const_binop (RSHIFT_EXPR, convert (signed_type, rhs),
+ tree tem = const_binop (RSHIFT_EXPR, fold_convert (signed_type, rhs),
size_int (lbitsize - 1), 0);
if (! integer_zerop (tem) && ! integer_all_onesp (tem))
{
warning ("comparison is always %d due to width of bit-field",
code == NE_EXPR);
- return convert (compare_type,
- (code == NE_EXPR
- ? integer_one_node : integer_zero_node));
+ return fold_convert (compare_type,
+ (code == NE_EXPR
+ ? integer_one_node : integer_zero_node));
}
}
@@ -2568,7 +2900,7 @@ optimize_bit_field_compare (code, compare_type, lhs, rhs)
if (lbitsize == 1 && ! integer_zerop (rhs))
{
code = code == EQ_EXPR ? NE_EXPR : EQ_EXPR;
- rhs = convert (type, integer_zero_node);
+ rhs = fold_convert (type, integer_zero_node);
}
/* Make a new bitfield reference, shift the constant over the
@@ -2583,7 +2915,7 @@ optimize_bit_field_compare (code, compare_type, lhs, rhs)
rhs = fold (const_binop (BIT_AND_EXPR,
const_binop (LSHIFT_EXPR,
- convert (unsigned_type, rhs),
+ fold_convert (unsigned_type, rhs),
size_int (lbitpos), 0),
mask, 0));
@@ -2616,15 +2948,12 @@ optimize_bit_field_compare (code, compare_type, lhs, rhs)
do anything with. */
static tree
-decode_field_reference (exp, pbitsize, pbitpos, pmode, punsignedp,
- pvolatilep, pmask, pand_mask)
- tree exp;
- HOST_WIDE_INT *pbitsize, *pbitpos;
- enum machine_mode *pmode;
- int *punsignedp, *pvolatilep;
- tree *pmask;
- tree *pand_mask;
+decode_field_reference (tree exp, HOST_WIDE_INT *pbitsize,
+ HOST_WIDE_INT *pbitpos, enum machine_mode *pmode,
+ int *punsignedp, int *pvolatilep,
+ tree *pmask, tree *pand_mask)
{
+ tree outer_type = 0;
tree and_mask = 0;
tree mask, inner, offset;
tree unsigned_type;
@@ -2636,6 +2965,13 @@ decode_field_reference (exp, pbitsize, pbitpos, pmode, punsignedp,
if (! INTEGRAL_TYPE_P (TREE_TYPE (exp)))
return 0;
+ /* We are interested in the bare arrangement of bits, so strip everything
+ that doesn't affect the machine mode. However, record the type of the
+ outermost expression if it may matter below. */
+ if (TREE_CODE (exp) == NOP_EXPR
+ || TREE_CODE (exp) == CONVERT_EXPR
+ || TREE_CODE (exp) == NON_LVALUE_EXPR)
+ outer_type = TREE_TYPE (exp);
STRIP_NOPS (exp);
if (TREE_CODE (exp) == BIT_AND_EXPR)
@@ -2654,6 +2990,12 @@ decode_field_reference (exp, pbitsize, pbitpos, pmode, punsignedp,
|| TREE_CODE (inner) == PLACEHOLDER_EXPR)
return 0;
+ /* If the number of bits in the reference is the same as the bitsize of
+ the outer type, then the outer type gives the signedness. Otherwise
+ (in case of a small bitfield) the signedness is unchanged. */
+ if (outer_type && *pbitsize == tree_low_cst (TYPE_SIZE (outer_type), 1))
+ *punsignedp = TREE_UNSIGNED (outer_type);
+
/* Compute the mask to access the bitfield. */
unsigned_type = (*lang_hooks.types.type_for_size) (*pbitsize, 1);
precision = TYPE_PRECISION (unsigned_type);
@@ -2667,7 +3009,7 @@ decode_field_reference (exp, pbitsize, pbitpos, pmode, punsignedp,
/* Merge it with the mask we found in the BIT_AND_EXPR, if any. */
if (and_mask != 0)
mask = fold (build (BIT_AND_EXPR, unsigned_type,
- convert (unsigned_type, and_mask), mask));
+ fold_convert (unsigned_type, and_mask), mask));
*pmask = mask;
*pand_mask = and_mask;
@@ -2678,9 +3020,7 @@ decode_field_reference (exp, pbitsize, pbitpos, pmode, punsignedp,
bit positions. */
static int
-all_ones_mask_p (mask, size)
- tree mask;
- int size;
+all_ones_mask_p (tree mask, int size)
{
tree type = TREE_TYPE (mask);
unsigned int precision = TYPE_PRECISION (type);
@@ -2705,12 +3045,10 @@ all_ones_mask_p (mask, size)
or NULL_TREE otherwise. */
static tree
-sign_bit_p (exp, val)
- tree exp;
- tree val;
+sign_bit_p (tree exp, tree val)
{
- unsigned HOST_WIDE_INT lo;
- HOST_WIDE_INT hi;
+ unsigned HOST_WIDE_INT mask_lo, lo;
+ HOST_WIDE_INT mask_hi, hi;
int width;
tree t;
@@ -2729,14 +3067,25 @@ sign_bit_p (exp, val)
{
hi = (unsigned HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT - 1);
lo = 0;
+
+ mask_hi = ((unsigned HOST_WIDE_INT) -1
+ >> (2 * HOST_BITS_PER_WIDE_INT - width));
+ mask_lo = -1;
}
else
{
hi = 0;
lo = (unsigned HOST_WIDE_INT) 1 << (width - 1);
+
+ mask_hi = 0;
+ mask_lo = ((unsigned HOST_WIDE_INT) -1
+ >> (HOST_BITS_PER_WIDE_INT - width));
}
- if (TREE_INT_CST_HIGH (val) == hi && TREE_INT_CST_LOW (val) == lo)
+ /* We mask off those bits beyond TREE_TYPE (exp) so that we can
+ treat VAL as if it were unsigned. */
+ if ((TREE_INT_CST_HIGH (val) & mask_hi) == hi
+ && (TREE_INT_CST_LOW (val) & mask_lo) == lo)
return exp;
/* Handle extension from a narrower type. */
@@ -2751,8 +3100,7 @@ sign_bit_p (exp, val)
to be evaluated unconditionally. */
static int
-simple_operand_p (exp)
- tree exp;
+simple_operand_p (tree exp)
{
/* Strip any conversions that don't change the machine mode. */
while ((TREE_CODE (exp) == NOP_EXPR
@@ -2780,9 +3128,9 @@ simple_operand_p (exp)
try to change a logical combination of comparisons into a range test.
For example, both
- X == 2 || X == 3 || X == 4 || X == 5
+ X == 2 || X == 3 || X == 4 || X == 5
and
- X >= 2 && X <= 5
+ X >= 2 && X <= 5
are converted to
(unsigned) (X - 2) <= 3
@@ -2812,11 +3160,8 @@ simple_operand_p (exp)
type if both are specified. */
static tree
-range_binop (code, type, arg0, upper0_p, arg1, upper1_p)
- enum tree_code code;
- tree type;
- tree arg0, arg1;
- int upper0_p, upper1_p;
+range_binop (enum tree_code code, tree type, tree arg0, int upper0_p,
+ tree arg1, int upper1_p)
{
tree tem;
int result;
@@ -2830,7 +3175,7 @@ range_binop (code, type, arg0, upper0_p, arg1, upper1_p)
if (arg0 != 0 && arg1 != 0)
{
tem = fold (build (code, type != 0 ? type : TREE_TYPE (arg0),
- arg0, convert (TREE_TYPE (arg0), arg1)));
+ arg0, fold_convert (TREE_TYPE (arg0), arg1)));
STRIP_NOPS (tem);
return TREE_CODE (tem) == INTEGER_CST ? tem : 0;
}
@@ -2870,7 +3215,7 @@ range_binop (code, type, arg0, upper0_p, arg1, upper1_p)
abort ();
}
- return convert (type, result ? integer_one_node : integer_zero_node);
+ return fold_convert (type, result ? integer_one_node : integer_zero_node);
}
/* Given EXP, a logical expression, set the range it is testing into
@@ -2880,10 +3225,7 @@ range_binop (code, type, arg0, upper0_p, arg1, upper1_p)
likely not be returning a useful value and range. */
static tree
-make_range (exp, pin_p, plow, phigh)
- tree exp;
- int *pin_p;
- tree *plow, *phigh;
+make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
{
enum tree_code code;
tree arg0 = NULL_TREE, arg1 = NULL_TREE, type = NULL_TREE;
@@ -2897,7 +3239,8 @@ make_range (exp, pin_p, plow, phigh)
the outer loop when we've changed something; otherwise we "break"
the switch, which will "break" the while. */
- in_p = 0, low = high = convert (TREE_TYPE (exp), integer_zero_node);
+ in_p = 0;
+ low = high = fold_convert (TREE_TYPE (exp), integer_zero_node);
while (1)
{
@@ -2905,7 +3248,8 @@ make_range (exp, pin_p, plow, phigh)
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
{
- arg0 = TREE_OPERAND (exp, 0);
+ if (first_rtl_op (code) > 0)
+ arg0 = TREE_OPERAND (exp, 0);
if (TREE_CODE_CLASS (code) == '<'
|| TREE_CODE_CLASS (code) == '1'
|| TREE_CODE_CLASS (code) == '2')
@@ -2973,21 +3317,21 @@ make_range (exp, pin_p, plow, phigh)
if (TREE_UNSIGNED (type) && (low == 0 || high == 0))
{
if (! merge_ranges (&n_in_p, &n_low, &n_high, in_p, low, high,
- 1, convert (type, integer_zero_node),
+ 1, fold_convert (type, integer_zero_node),
NULL_TREE))
break;
in_p = n_in_p, low = n_low, high = n_high;
- /* If the high bound is missing, but we
- have a low bound, reverse the range so
- it goes from zero to the low bound minus 1. */
- if (high == 0 && low)
+ /* If the high bound is missing, but we have a nonzero low
+ bound, reverse the range so it goes from zero to the low bound
+ minus 1. */
+ if (high == 0 && low && ! integer_zerop (low))
{
in_p = ! in_p;
high = range_binop (MINUS_EXPR, NULL_TREE, low, 0,
integer_one_node, 0);
- low = convert (type, integer_zero_node);
+ low = fold_convert (type, integer_zero_node);
}
}
continue;
@@ -2995,9 +3339,11 @@ make_range (exp, pin_p, plow, phigh)
case NEGATE_EXPR:
/* (-x) IN [a,b] -> x in [-b, -a] */
n_low = range_binop (MINUS_EXPR, type,
- convert (type, integer_zero_node), 0, high, 1);
+ fold_convert (type, integer_zero_node),
+ 0, high, 1);
n_high = range_binop (MINUS_EXPR, type,
- convert (type, integer_zero_node), 0, low, 0);
+ fold_convert (type, integer_zero_node),
+ 0, low, 0);
low = n_low, high = n_high;
exp = arg0;
continue;
@@ -3005,7 +3351,7 @@ make_range (exp, pin_p, plow, phigh)
case BIT_NOT_EXPR:
/* ~ X -> -X - 1 */
exp = build (MINUS_EXPR, type, negate_expr (arg0),
- convert (type, integer_one_node));
+ fold_convert (type, integer_one_node));
continue;
case PLUS_EXPR: case MINUS_EXPR:
@@ -3061,10 +3407,10 @@ make_range (exp, pin_p, plow, phigh)
n_low = low, n_high = high;
if (n_low != 0)
- n_low = convert (type, n_low);
+ n_low = fold_convert (type, n_low);
if (n_high != 0)
- n_high = convert (type, n_high);
+ n_high = fold_convert (type, n_high);
/* If we're converting from an unsigned to a signed type,
we will be doing the comparison as unsigned. The tests above
@@ -3087,8 +3433,10 @@ make_range (exp, pin_p, plow, phigh)
if (TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (exp)))
high_positive = fold (build (RSHIFT_EXPR, type,
- convert (type, high_positive),
- convert (type, integer_one_node)));
+ fold_convert (type,
+ high_positive),
+ fold_convert (type,
+ integer_one_node)));
/* If the low bound is specified, "and" the range with the
range for which the original unsigned value will be
@@ -3096,8 +3444,8 @@ make_range (exp, pin_p, plow, phigh)
if (low != 0)
{
if (! merge_ranges (&n_in_p, &n_low, &n_high,
- 1, n_low, n_high,
- 1, convert (type, integer_zero_node),
+ 1, n_low, n_high, 1,
+ fold_convert (type, integer_zero_node),
high_positive))
break;
@@ -3108,8 +3456,8 @@ make_range (exp, pin_p, plow, phigh)
/* Otherwise, "or" the range with the range of the input
that will be interpreted as negative. */
if (! merge_ranges (&n_in_p, &n_low, &n_high,
- 0, n_low, n_high,
- 1, convert (type, integer_zero_node),
+ 0, n_low, n_high, 1,
+ fold_convert (type, integer_zero_node),
high_positive))
break;
@@ -3148,11 +3496,7 @@ make_range (exp, pin_p, plow, phigh)
on IN_P) the range. */
static tree
-build_range_check (type, exp, in_p, low, high)
- tree type;
- tree exp;
- int in_p;
- tree low, high;
+build_range_check (tree type, tree exp, int in_p, tree low, tree high)
{
tree etype = TREE_TYPE (exp);
tree value;
@@ -3162,7 +3506,7 @@ build_range_check (type, exp, in_p, low, high)
return invert_truthvalue (value);
if (low == 0 && high == 0)
- return convert (type, integer_one_node);
+ return fold_convert (type, integer_one_node);
if (low == 0)
return fold (build (LE_EXPR, type, exp, high));
@@ -3178,8 +3522,8 @@ build_range_check (type, exp, in_p, low, high)
if (! TREE_UNSIGNED (etype))
{
etype = (*lang_hooks.types.unsigned_type) (etype);
- high = convert (etype, high);
- exp = convert (etype, exp);
+ high = fold_convert (etype, high);
+ exp = fold_convert (etype, exp);
}
return build_range_check (type, exp, 1, 0, high);
}
@@ -3191,7 +3535,13 @@ build_range_check (type, exp, in_p, low, high)
HOST_WIDE_INT hi;
int prec;
- prec = TYPE_PRECISION (etype);
+ /* For enums the comparison will be done in the underlying type,
+ so using enum's precision is wrong here.
+ Consider e.g. enum { A, B, C, D, E }, low == B and high == D. */
+ if (TREE_CODE (etype) == ENUMERAL_TYPE)
+ prec = GET_MODE_BITSIZE (TYPE_MODE (etype));
+ else
+ prec = TYPE_PRECISION (etype);
if (prec <= HOST_BITS_PER_WIDE_INT)
{
hi = 0;
@@ -3208,10 +3558,10 @@ build_range_check (type, exp, in_p, low, high)
if (TREE_UNSIGNED (etype))
{
etype = (*lang_hooks.types.signed_type) (etype);
- exp = convert (etype, exp);
+ exp = fold_convert (etype, exp);
}
return fold (build (GT_EXPR, type, exp,
- convert (etype, integer_zero_node)));
+ fold_convert (etype, integer_zero_node)));
}
}
@@ -3219,7 +3569,8 @@ build_range_check (type, exp, in_p, low, high)
&& ! TREE_OVERFLOW (value))
return build_range_check (type,
fold (build (MINUS_EXPR, etype, exp, low)),
- 1, convert (etype, integer_zero_node), value);
+ 1, fold_convert (etype, integer_zero_node),
+ value);
return 0;
}
@@ -3228,11 +3579,8 @@ build_range_check (type, exp, in_p, low, high)
can, 0 if we can't. Set the output range into the specified parameters. */
static int
-merge_ranges (pin_p, plow, phigh, in0_p, low0, high0, in1_p, low1, high1)
- int *pin_p;
- tree *plow, *phigh;
- int in0_p, in1_p;
- tree low0, high0, low1, high1;
+merge_ranges (int *pin_p, tree *plow, tree *phigh, int in0_p, tree low0,
+ tree high0, int in1_p, tree low1, tree high1)
{
int no_overlap;
int subset;
@@ -3360,12 +3708,15 @@ merge_ranges (pin_p, plow, phigh, in0_p, low0, high0, in1_p, low1, high1)
return 1;
}
+#ifndef RANGE_TEST_NON_SHORT_CIRCUIT
+#define RANGE_TEST_NON_SHORT_CIRCUIT (BRANCH_COST >= 2)
+#endif
+
/* EXP is some logical combination of boolean tests. See if we can
merge it into some range test. Return the new tree if so. */
static tree
-fold_range_test (exp)
- tree exp;
+fold_range_test (tree exp)
{
int or_op = (TREE_CODE (exp) == TRUTH_ORIF_EXPR
|| TREE_CODE (exp) == TRUTH_OR_EXPR);
@@ -3396,7 +3747,7 @@ fold_range_test (exp)
/* On machines where the branch cost is expensive, if this is a
short-circuited branch and the underlying object on both sides
is the same, make a non-short-circuit operation. */
- else if (BRANCH_COST >= 2
+ else if (RANGE_TEST_NON_SHORT_CIRCUIT
&& lhs != 0 && rhs != 0
&& (TREE_CODE (exp) == TRUTH_ANDIF_EXPR
|| TREE_CODE (exp) == TRUTH_ORIF_EXPR)
@@ -3412,7 +3763,7 @@ fold_range_test (exp)
TREE_OPERAND (exp, 1));
else if ((*lang_hooks.decls.global_bindings_p) () == 0
- && ! contains_placeholder_p (lhs))
+ && ! CONTAINS_PLACEHOLDER_P (lhs))
{
tree common = save_expr (lhs);
@@ -3437,11 +3788,7 @@ fold_range_test (exp)
it is an INTEGER_CST that should be AND'ed with the extra bits. */
static tree
-unextend (c, p, unsignedp, mask)
- tree c;
- int p;
- int unsignedp;
- tree mask;
+unextend (tree c, int p, int unsignedp, tree mask)
{
tree type = TREE_TYPE (c);
int modesize = GET_MODE_BITSIZE (TYPE_MODE (type));
@@ -3463,17 +3810,18 @@ unextend (c, p, unsignedp, mask)
zero or one, and the conversion to a signed type can never overflow.
We could get an overflow if this conversion is done anywhere else. */
if (TREE_UNSIGNED (type))
- temp = convert ((*lang_hooks.types.signed_type) (type), temp);
+ temp = fold_convert ((*lang_hooks.types.signed_type) (type), temp);
temp = const_binop (LSHIFT_EXPR, temp, size_int (modesize - 1), 0);
temp = const_binop (RSHIFT_EXPR, temp, size_int (modesize - p - 1), 0);
if (mask != 0)
- temp = const_binop (BIT_AND_EXPR, temp, convert (TREE_TYPE (c), mask), 0);
+ temp = const_binop (BIT_AND_EXPR, temp,
+ fold_convert (TREE_TYPE (c), mask), 0);
/* If necessary, convert the type back to match the type of C. */
if (TREE_UNSIGNED (type))
- temp = convert (type, temp);
+ temp = fold_convert (type, temp);
- return convert (type, const_binop (BIT_XOR_EXPR, c, temp, 0));
+ return fold_convert (type, const_binop (BIT_XOR_EXPR, c, temp, 0));
}
/* Find ways of folding logical expressions of LHS and RHS:
@@ -3501,14 +3849,12 @@ unextend (c, p, unsignedp, mask)
We return the simplified tree or 0 if no optimization is possible. */
static tree
-fold_truthop (code, truth_type, lhs, rhs)
- enum tree_code code;
- tree truth_type, lhs, rhs;
+fold_truthop (enum tree_code code, tree truth_type, tree lhs, tree rhs)
{
/* If this is the "or" of two comparisons, we can do something if
the comparisons are NE_EXPR. If this is the "and", we can do something
if the comparisons are EQ_EXPR. I.e.,
- (a->b == 2 && a->c == 4) can become (a->new == NEW).
+ (a->b == 2 && a->c == 4) can become (a->new == NEW).
WANTED_CODE is this operation code. For single bit fields, we can
convert EQ_EXPR to NE_EXPR so we need not reject the "wrong"
@@ -3593,9 +3939,9 @@ fold_truthop (code, truth_type, lhs, rhs)
compcode = -1;
if (compcode == COMPCODE_TRUE)
- return convert (truth_type, integer_one_node);
+ return fold_convert (truth_type, integer_one_node);
else if (compcode == COMPCODE_FALSE)
- return convert (truth_type, integer_zero_node);
+ return fold_convert (truth_type, integer_zero_node);
else if (compcode != -1)
return build (compcode_to_comparison (compcode),
truth_type, ll_arg, lr_arg);
@@ -3735,14 +4081,14 @@ fold_truthop (code, truth_type, lhs, rhs)
xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
}
- ll_mask = const_binop (LSHIFT_EXPR, convert (lntype, ll_mask),
+ ll_mask = const_binop (LSHIFT_EXPR, fold_convert (lntype, ll_mask),
size_int (xll_bitpos), 0);
- rl_mask = const_binop (LSHIFT_EXPR, convert (lntype, rl_mask),
+ rl_mask = const_binop (LSHIFT_EXPR, fold_convert (lntype, rl_mask),
size_int (xrl_bitpos), 0);
if (l_const)
{
- l_const = convert (lntype, l_const);
+ l_const = fold_convert (lntype, l_const);
l_const = unextend (l_const, ll_bitsize, ll_unsignedp, ll_and_mask);
l_const = const_binop (LSHIFT_EXPR, l_const, size_int (xll_bitpos), 0);
if (! integer_zerop (const_binop (BIT_AND_EXPR, l_const,
@@ -3752,14 +4098,14 @@ fold_truthop (code, truth_type, lhs, rhs)
{
warning ("comparison is always %d", wanted_code == NE_EXPR);
- return convert (truth_type,
- wanted_code == NE_EXPR
- ? integer_one_node : integer_zero_node);
+ return fold_convert (truth_type,
+ wanted_code == NE_EXPR
+ ? integer_one_node : integer_zero_node);
}
}
if (r_const)
{
- r_const = convert (lntype, r_const);
+ r_const = fold_convert (lntype, r_const);
r_const = unextend (r_const, rl_bitsize, rl_unsignedp, rl_and_mask);
r_const = const_binop (LSHIFT_EXPR, r_const, size_int (xrl_bitpos), 0);
if (! integer_zerop (const_binop (BIT_AND_EXPR, r_const,
@@ -3769,9 +4115,9 @@ fold_truthop (code, truth_type, lhs, rhs)
{
warning ("comparison is always %d", wanted_code == NE_EXPR);
- return convert (truth_type,
- wanted_code == NE_EXPR
- ? integer_one_node : integer_zero_node);
+ return fold_convert (truth_type,
+ wanted_code == NE_EXPR
+ ? integer_one_node : integer_zero_node);
}
}
@@ -3806,9 +4152,9 @@ fold_truthop (code, truth_type, lhs, rhs)
xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
}
- lr_mask = const_binop (LSHIFT_EXPR, convert (rntype, lr_mask),
+ lr_mask = const_binop (LSHIFT_EXPR, fold_convert (rntype, lr_mask),
size_int (xlr_bitpos), 0);
- rr_mask = const_binop (LSHIFT_EXPR, convert (rntype, rr_mask),
+ rr_mask = const_binop (LSHIFT_EXPR, fold_convert (rntype, rr_mask),
size_int (xrr_bitpos), 0);
/* Make a mask that corresponds to both fields being compared.
@@ -3863,14 +4209,14 @@ fold_truthop (code, truth_type, lhs, rhs)
{
if (lnbitsize > rnbitsize)
{
- lhs = convert (rntype, lhs);
- ll_mask = convert (rntype, ll_mask);
+ lhs = fold_convert (rntype, lhs);
+ ll_mask = fold_convert (rntype, ll_mask);
type = rntype;
}
else if (lnbitsize < rnbitsize)
{
- rhs = convert (lntype, rhs);
- lr_mask = convert (lntype, lr_mask);
+ rhs = fold_convert (lntype, rhs);
+ lr_mask = fold_convert (lntype, lr_mask);
type = lntype;
}
}
@@ -3899,12 +4245,12 @@ fold_truthop (code, truth_type, lhs, rhs)
if (wanted_code == NE_EXPR)
{
warning ("`or' of unmatched not-equal tests is always 1");
- return convert (truth_type, integer_one_node);
+ return fold_convert (truth_type, integer_one_node);
}
else
{
warning ("`and' of mutually exclusive equal-tests is always 0");
- return convert (truth_type, integer_zero_node);
+ return fold_convert (truth_type, integer_zero_node);
}
}
@@ -3927,8 +4273,7 @@ fold_truthop (code, truth_type, lhs, rhs)
constant. */
static tree
-optimize_minmax_comparison (t)
- tree t;
+optimize_minmax_comparison (tree t)
{
tree type = TREE_TYPE (t);
tree arg0 = TREE_OPERAND (t, 0);
@@ -4039,11 +4384,7 @@ optimize_minmax_comparison (t)
original computation, but need not be in the original type. */
static tree
-extract_muldiv (t, c, code, wide_type)
- tree t;
- tree c;
- enum tree_code code;
- tree wide_type;
+extract_muldiv (tree t, tree c, enum tree_code code, tree wide_type)
{
/* To avoid exponential search depth, refuse to allow recursion past
three levels. Beyond that (1) it's highly unlikely that we'll find
@@ -4064,11 +4405,7 @@ extract_muldiv (t, c, code, wide_type)
}
static tree
-extract_muldiv_1 (t, c, code, wide_type)
- tree t;
- tree c;
- enum tree_code code;
- tree wide_type;
+extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type)
{
tree type = TREE_TYPE (t);
enum tree_code tcode = TREE_CODE (t);
@@ -4098,7 +4435,8 @@ extract_muldiv_1 (t, c, code, wide_type)
or (for divide and modulus) if it is a multiple of our constant. */
if (code == MULT_EXPR
|| integer_zerop (const_binop (TRUNC_MOD_EXPR, t, c, 0)))
- return const_binop (code, convert (ctype, t), convert (ctype, c), 0);
+ return const_binop (code, fold_convert (ctype, t),
+ fold_convert (ctype, c), 0);
break;
case CONVERT_EXPR: case NON_LVALUE_EXPR: case NOP_EXPR:
@@ -4128,14 +4466,18 @@ extract_muldiv_1 (t, c, code, wide_type)
/* Pass the constant down and see if we can make a simplification. If
we can, replace this expression with the inner simplification for
possible later conversion to our or some other type. */
- if (0 != (t1 = extract_muldiv (op0, convert (TREE_TYPE (op0), c), code,
- code == MULT_EXPR ? ctype : NULL_TREE)))
+ if ((t2 = fold_convert (TREE_TYPE (op0), c)) != 0
+ && TREE_CODE (t2) == INTEGER_CST
+ && ! TREE_CONSTANT_OVERFLOW (t2)
+ && (0 != (t1 = extract_muldiv (op0, t2, code,
+ code == MULT_EXPR
+ ? ctype : NULL_TREE))))
return t1;
break;
case NEGATE_EXPR: case ABS_EXPR:
if ((t1 = extract_muldiv (op0, c, code, wide_type)) != 0)
- return fold (build1 (tcode, ctype, convert (ctype, t1)));
+ return fold (build1 (tcode, ctype, fold_convert (ctype, t1)));
break;
case MIN_EXPR: case MAX_EXPR:
@@ -4151,8 +4493,8 @@ extract_muldiv_1 (t, c, code, wide_type)
if (tree_int_cst_sgn (c) < 0)
tcode = (tcode == MIN_EXPR ? MAX_EXPR : MIN_EXPR);
- return fold (build (tcode, ctype, convert (ctype, t1),
- convert (ctype, t2)));
+ return fold (build (tcode, ctype, fold_convert (ctype, t1),
+ fold_convert (ctype, t2)));
}
break;
@@ -4171,13 +4513,14 @@ extract_muldiv_1 (t, c, code, wide_type)
so check for it explicitly here. */
&& TYPE_PRECISION (TREE_TYPE (size_one_node)) > TREE_INT_CST_LOW (op1)
&& TREE_INT_CST_HIGH (op1) == 0
- && 0 != (t1 = convert (ctype,
- const_binop (LSHIFT_EXPR, size_one_node,
- op1, 0)))
+ && 0 != (t1 = fold_convert (ctype,
+ const_binop (LSHIFT_EXPR,
+ size_one_node,
+ op1, 0)))
&& ! TREE_OVERFLOW (t1))
return extract_muldiv (build (tcode == LSHIFT_EXPR
? MULT_EXPR : FLOOR_DIV_EXPR,
- ctype, convert (ctype, op0), t1),
+ ctype, fold_convert (ctype, op0), t1),
c, code, wide_type);
break;
@@ -4194,8 +4537,8 @@ extract_muldiv_1 (t, c, code, wide_type)
are divisible by c. */
|| (multiple_of_p (ctype, op0, c)
&& multiple_of_p (ctype, op1, c))))
- return fold (build (tcode, ctype, convert (ctype, t1),
- convert (ctype, t2)));
+ return fold (build (tcode, ctype, fold_convert (ctype, t1),
+ fold_convert (ctype, t2)));
/* If this was a subtraction, negate OP1 and set it to be an addition.
This simplifies the logic below. */
@@ -4224,8 +4567,11 @@ extract_muldiv_1 (t, c, code, wide_type)
if (code == MULT_EXPR
|| integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
{
- op1 = const_binop (code, convert (ctype, op1), convert (ctype, c), 0);
- if (op1 == 0 || TREE_OVERFLOW (op1))
+ op1 = const_binop (code, fold_convert (ctype, op1),
+ fold_convert (ctype, c), 0);
+ /* We allow the constant to overflow with wrapping semantics. */
+ if (op1 == 0
+ || (TREE_OVERFLOW (op1) && ! flag_wrapv))
break;
}
else
@@ -4242,15 +4588,16 @@ extract_muldiv_1 (t, c, code, wide_type)
/* If we were able to eliminate our operation from the first side,
apply our operation to the second side and reform the PLUS. */
if (t1 != 0 && (TREE_CODE (t1) != code || code == MULT_EXPR))
- return fold (build (tcode, ctype, convert (ctype, t1), op1));
+ return fold (build (tcode, ctype, fold_convert (ctype, t1), op1));
/* The last case is if we are a multiply. In that case, we can
apply the distributive law to commute the multiply and addition
if the multiplication of the constants doesn't overflow. */
if (code == MULT_EXPR)
- return fold (build (tcode, ctype, fold (build (code, ctype,
- convert (ctype, op0),
- convert (ctype, c))),
+ return fold (build (tcode, ctype,
+ fold (build (code, ctype,
+ fold_convert (ctype, op0),
+ fold_convert (ctype, c))),
op1));
break;
@@ -4273,22 +4620,22 @@ extract_muldiv_1 (t, c, code, wide_type)
do something only if the second operand is a constant. */
if (same_p
&& (t1 = extract_muldiv (op0, c, code, wide_type)) != 0)
- return fold (build (tcode, ctype, convert (ctype, t1),
- convert (ctype, op1)));
+ return fold (build (tcode, ctype, fold_convert (ctype, t1),
+ fold_convert (ctype, op1)));
else if (tcode == MULT_EXPR && code == MULT_EXPR
&& (t1 = extract_muldiv (op1, c, code, wide_type)) != 0)
- return fold (build (tcode, ctype, convert (ctype, op0),
- convert (ctype, t1)));
+ return fold (build (tcode, ctype, fold_convert (ctype, op0),
+ fold_convert (ctype, t1)));
else if (TREE_CODE (op1) != INTEGER_CST)
return 0;
/* If these are the same operation types, we can associate them
assuming no overflow. */
if (tcode == code
- && 0 != (t1 = const_binop (MULT_EXPR, convert (ctype, op1),
- convert (ctype, c), 0))
+ && 0 != (t1 = const_binop (MULT_EXPR, fold_convert (ctype, op1),
+ fold_convert (ctype, c), 0))
&& ! TREE_OVERFLOW (t1))
- return fold (build (tcode, ctype, convert (ctype, op0), t1));
+ return fold (build (tcode, ctype, fold_convert (ctype, op0), t1));
/* If these operations "cancel" each other, we have the main
optimizations of this pass, which occur when either constant is a
@@ -4300,21 +4647,22 @@ extract_muldiv_1 (t, c, code, wide_type)
overflowed. */
if ((! TREE_UNSIGNED (ctype)
|| (TREE_CODE (ctype) == INTEGER_TYPE && TYPE_IS_SIZETYPE (ctype)))
+ && ! flag_wrapv
&& ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR)
|| (tcode == MULT_EXPR
&& code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR
&& code != FLOOR_MOD_EXPR && code != ROUND_MOD_EXPR)))
{
if (integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
- return fold (build (tcode, ctype, convert (ctype, op0),
- convert (ctype,
- const_binop (TRUNC_DIV_EXPR,
- op1, c, 0))));
+ return fold (build (tcode, ctype, fold_convert (ctype, op0),
+ fold_convert (ctype,
+ const_binop (TRUNC_DIV_EXPR,
+ op1, c, 0))));
else if (integer_zerop (const_binop (TRUNC_MOD_EXPR, c, op1, 0)))
- return fold (build (code, ctype, convert (ctype, op0),
- convert (ctype,
- const_binop (TRUNC_DIV_EXPR,
- c, op1, 0))));
+ return fold (build (code, ctype, fold_convert (ctype, op0),
+ fold_convert (ctype,
+ const_binop (TRUNC_DIV_EXPR,
+ c, op1, 0))));
}
break;
@@ -4330,9 +4678,7 @@ extract_muldiv_1 (t, c, code, wide_type)
that we may sometimes modify the tree. */
static tree
-strip_compound_expr (t, s)
- tree t;
- tree s;
+strip_compound_expr (tree t, tree s)
{
enum tree_code code = TREE_CODE (t);
@@ -4365,9 +4711,7 @@ strip_compound_expr (t, s)
1), and is of the indicated TYPE. */
static tree
-constant_boolean_node (value, type)
- int value;
- tree type;
+constant_boolean_node (int value, tree type)
{
if (type == integer_type_node)
return value ? integer_one_node : integer_zero_node;
@@ -4388,9 +4732,7 @@ constant_boolean_node (value, type)
we don't care (to avoid spending too much time on complex expressions.). */
static int
-count_cond (expr, lim)
- tree expr;
- int lim;
+count_cond (tree expr, int lim)
{
int ctrue, cfalse;
@@ -4413,12 +4755,8 @@ count_cond (expr, lim)
original expression. */
static tree
-fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p)
- enum tree_code code;
- tree type;
- tree cond;
- tree arg;
- int cond_first_p;
+fold_binary_op_with_conditional_arg (enum tree_code code, tree type,
+ tree cond, tree arg, int cond_first_p)
{
tree test, true_value, false_value;
tree lhs = NULL_TREE;
@@ -4491,25 +4829,23 @@ fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p)
{
tree testtype = TREE_TYPE (cond);
test = cond;
- true_value = convert (testtype, integer_one_node);
- false_value = convert (testtype, integer_zero_node);
+ true_value = fold_convert (testtype, integer_one_node);
+ false_value = fold_convert (testtype, integer_zero_node);
}
- /* If ARG is complex we want to make sure we only evaluate
- it once. Though this is only required if it is volatile, it
- might be more efficient even if it is not. However, if we
- succeed in folding one part to a constant, we do not need
- to make this SAVE_EXPR. Since we do this optimization
- primarily to see if we do end up with constant and this
- SAVE_EXPR interferes with later optimizations, suppressing
- it when we can is important.
-
- If we are not in a function, we can't make a SAVE_EXPR, so don't
- try to do so. Don't try to see if the result is a constant
- if an arm is a COND_EXPR since we get exponential behavior
- in that case. */
-
- if (TREE_CODE (arg) == SAVE_EXPR)
+ /* If ARG is complex we want to make sure we only evaluate it once. Though
+ this is only required if it is volatile, it might be more efficient even
+ if it is not. However, if we succeed in folding one part to a constant,
+ we do not need to make this SAVE_EXPR. Since we do this optimization
+ primarily to see if we do end up with constant and this SAVE_EXPR
+ interferes with later optimizations, suppressing it when we can is
+ important.
+
+ If we are not in a function, we can't make a SAVE_EXPR, so don't try to
+ do so. Don't try to see if the result is a constant if an arm is a
+ COND_EXPR since we get exponential behavior in that case. */
+
+ if (saved_expr_p (arg))
save = 1;
else if (lhs == 0 && rhs == 0
&& !TREE_CONSTANT (arg)
@@ -4528,7 +4864,7 @@ fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p)
{
arg = save_expr (arg);
lhs = rhs = 0;
- save = 1;
+ save = saved_expr_p (arg);
}
}
@@ -4539,12 +4875,18 @@ fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p)
test = fold (build (COND_EXPR, type, test, lhs, rhs));
+ /* If ARG involves a SAVE_EXPR, we need to ensure it is evaluated
+ ahead of the COND_EXPR we made. Otherwise we would have it only
+ evaluated in one branch, with the other branch using the result
+ but missing the evaluation code. Beware that the save_expr call
+ above might not return a SAVE_EXPR, so testing the TREE_CODE
+ of ARG is not enough to decide here.  */
if (save)
return build (COMPOUND_EXPR, type,
- convert (void_type_node, arg),
+ fold_convert (void_type_node, arg),
strip_compound_expr (test, arg));
else
- return convert (type, test);
+ return fold_convert (type, test);
}
@@ -4561,13 +4903,15 @@ fold_binary_op_with_conditional_arg (code, type, cond, arg, cond_first_p)
modes, X + 0 is not the same as X because -0 + 0 is 0. */
static bool
-fold_real_zero_addition_p (type, addend, negate)
- tree type, addend;
- int negate;
+fold_real_zero_addition_p (tree type, tree addend, int negate)
{
if (!real_zerop (addend))
return false;
+ /* Don't allow the fold with -fsignaling-nans. */
+ if (HONOR_SNANS (TYPE_MODE (type)))
+ return false;
+
/* Allow the fold if zeros aren't signed, or their sign isn't important. */
if (!HONOR_SIGNED_ZEROS (TYPE_MODE (type)))
return true;
@@ -4584,6 +4928,386 @@ fold_real_zero_addition_p (type, addend, negate)
return negate && !HONOR_SIGN_DEPENDENT_ROUNDING (TYPE_MODE (type));
}
+/* Subroutine of fold() that checks comparisons of built-in math
+ functions against real constants.
+
+ FCODE is the DECL_FUNCTION_CODE of the built-in, CODE is the comparison
+ operator: EQ_EXPR, NE_EXPR, GT_EXPR, LT_EXPR, GE_EXPR or LE_EXPR. TYPE
+ is the type of the result and ARG0 and ARG1 are the operands of the
+ comparison. ARG1 must be a TREE_REAL_CST.
+
+ The function returns the constant folded tree if a simplification
+ can be made, and NULL_TREE otherwise. */
+
+static tree
+fold_mathfn_compare (enum built_in_function fcode, enum tree_code code,
+ tree type, tree arg0, tree arg1)
+{
+ REAL_VALUE_TYPE c;
+
+ if (fcode == BUILT_IN_SQRT
+ || fcode == BUILT_IN_SQRTF
+ || fcode == BUILT_IN_SQRTL)
+ {
+ tree arg = TREE_VALUE (TREE_OPERAND (arg0, 1));
+ enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg0));
+
+ c = TREE_REAL_CST (arg1);
+ if (REAL_VALUE_NEGATIVE (c))
+ {
+ /* sqrt(x) < y is always false, if y is negative. */
+ if (code == EQ_EXPR || code == LT_EXPR || code == LE_EXPR)
+ return omit_one_operand (type,
+ fold_convert (type, integer_zero_node),
+ arg);
+
+ /* sqrt(x) > y is always true, if y is negative and we
+ don't care about NaNs, i.e. negative values of x. */
+ if (code == NE_EXPR || !HONOR_NANS (mode))
+ return omit_one_operand (type,
+ fold_convert (type, integer_one_node),
+ arg);
+
+ /* sqrt(x) > y is the same as x >= 0, if y is negative. */
+ return fold (build (GE_EXPR, type, arg,
+ build_real (TREE_TYPE (arg), dconst0)));
+ }
+ else if (code == GT_EXPR || code == GE_EXPR)
+ {
+ REAL_VALUE_TYPE c2;
+
+ REAL_ARITHMETIC (c2, MULT_EXPR, c, c);
+ real_convert (&c2, mode, &c2);
+
+ if (REAL_VALUE_ISINF (c2))
+ {
+ /* sqrt(x) > y is x == +Inf, when y is very large. */
+ if (HONOR_INFINITIES (mode))
+ return fold (build (EQ_EXPR, type, arg,
+ build_real (TREE_TYPE (arg), c2)));
+
+ /* sqrt(x) > y is always false, when y is very large
+ and we don't care about infinities. */
+ return omit_one_operand (type,
+ fold_convert (type, integer_zero_node),
+ arg);
+ }
+
+ /* sqrt(x) > c is the same as x > c*c. */
+ return fold (build (code, type, arg,
+ build_real (TREE_TYPE (arg), c2)));
+ }
+ else if (code == LT_EXPR || code == LE_EXPR)
+ {
+ REAL_VALUE_TYPE c2;
+
+ REAL_ARITHMETIC (c2, MULT_EXPR, c, c);
+ real_convert (&c2, mode, &c2);
+
+ if (REAL_VALUE_ISINF (c2))
+ {
+ /* sqrt(x) < y is always true, when y is a very large
+ value and we don't care about NaNs or Infinities. */
+ if (! HONOR_NANS (mode) && ! HONOR_INFINITIES (mode))
+ return omit_one_operand (type,
+ fold_convert (type, integer_one_node),
+ arg);
+
+ /* sqrt(x) < y is x != +Inf when y is very large and we
+ don't care about NaNs. */
+ if (! HONOR_NANS (mode))
+ return fold (build (NE_EXPR, type, arg,
+ build_real (TREE_TYPE (arg), c2)));
+
+ /* sqrt(x) < y is x >= 0 when y is very large and we
+ don't care about Infinities. */
+ if (! HONOR_INFINITIES (mode))
+ return fold (build (GE_EXPR, type, arg,
+ build_real (TREE_TYPE (arg), dconst0)));
+
+ /* sqrt(x) < y is x >= 0 && x != +Inf, when y is large. */
+ if ((*lang_hooks.decls.global_bindings_p) () != 0
+ || CONTAINS_PLACEHOLDER_P (arg))
+ return NULL_TREE;
+
+ arg = save_expr (arg);
+ return fold (build (TRUTH_ANDIF_EXPR, type,
+ fold (build (GE_EXPR, type, arg,
+ build_real (TREE_TYPE (arg),
+ dconst0))),
+ fold (build (NE_EXPR, type, arg,
+ build_real (TREE_TYPE (arg),
+ c2)))));
+ }
+
+ /* sqrt(x) < c is the same as x < c*c, if we ignore NaNs. */
+ if (! HONOR_NANS (mode))
+ return fold (build (code, type, arg,
+ build_real (TREE_TYPE (arg), c2)));
+
+ /* sqrt(x) < c is the same as x >= 0 && x < c*c. */
+ if ((*lang_hooks.decls.global_bindings_p) () == 0
+ && ! CONTAINS_PLACEHOLDER_P (arg))
+ {
+ arg = save_expr (arg);
+ return fold (build (TRUTH_ANDIF_EXPR, type,
+ fold (build (GE_EXPR, type, arg,
+ build_real (TREE_TYPE (arg),
+ dconst0))),
+ fold (build (code, type, arg,
+ build_real (TREE_TYPE (arg),
+ c2)))));
+ }
+ }
+ }
+
+ return NULL_TREE;
+}
+
+/* Subroutine of fold() that optimizes comparisons against Infinities,
+ either +Inf or -Inf.
+
+ CODE is the comparison operator: EQ_EXPR, NE_EXPR, GT_EXPR, LT_EXPR,
+ GE_EXPR or LE_EXPR. TYPE is the type of the result and ARG0 and ARG1
+ are the operands of the comparison. ARG1 must be a TREE_REAL_CST.
+
+ The function returns the constant folded tree if a simplification
+ can be made, and NULL_TREE otherwise. */
+
+static tree
+fold_inf_compare (enum tree_code code, tree type, tree arg0, tree arg1)
+{
+ enum machine_mode mode;
+ REAL_VALUE_TYPE max;
+ tree temp;
+ bool neg;
+
+ mode = TYPE_MODE (TREE_TYPE (arg0));
+
+ /* For negative infinity swap the sense of the comparison. */
+ neg = REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1));
+ if (neg)
+ code = swap_tree_comparison (code);
+
+ switch (code)
+ {
+ case GT_EXPR:
+ /* x > +Inf is always false, if with ignore sNANs. */
+ if (HONOR_SNANS (mode))
+ return NULL_TREE;
+ return omit_one_operand (type,
+ fold_convert (type, integer_zero_node),
+ arg0);
+
+ case LE_EXPR:
+ /* x <= +Inf is always true, if we don't case about NaNs. */
+ if (! HONOR_NANS (mode))
+ return omit_one_operand (type,
+ fold_convert (type, integer_one_node),
+ arg0);
+
+ /* x <= +Inf is the same as x == x, i.e. isfinite(x). */
+ if ((*lang_hooks.decls.global_bindings_p) () == 0
+ && ! CONTAINS_PLACEHOLDER_P (arg0))
+ {
+ arg0 = save_expr (arg0);
+ return fold (build (EQ_EXPR, type, arg0, arg0));
+ }
+ break;
+
+ case EQ_EXPR:
+ case GE_EXPR:
+ /* x == +Inf and x >= +Inf are always equal to x > DBL_MAX. */
+ real_maxval (&max, neg, mode);
+ return fold (build (neg ? LT_EXPR : GT_EXPR, type,
+ arg0, build_real (TREE_TYPE (arg0), max)));
+
+ case LT_EXPR:
+ /* x < +Inf is always equal to x <= DBL_MAX. */
+ real_maxval (&max, neg, mode);
+ return fold (build (neg ? GE_EXPR : LE_EXPR, type,
+ arg0, build_real (TREE_TYPE (arg0), max)));
+
+ case NE_EXPR:
+ /* x != +Inf is always equal to !(x > DBL_MAX). */
+ real_maxval (&max, neg, mode);
+ if (! HONOR_NANS (mode))
+ return fold (build (neg ? GE_EXPR : LE_EXPR, type,
+ arg0, build_real (TREE_TYPE (arg0), max)));
+ temp = fold (build (neg ? LT_EXPR : GT_EXPR, type,
+ arg0, build_real (TREE_TYPE (arg0), max)));
+ return fold (build1 (TRUTH_NOT_EXPR, type, temp));
+
+ default:
+ break;
+ }
+
+ return NULL_TREE;
+}
+
+/* If CODE with arguments ARG0 and ARG1 represents a single bit
+ equality/inequality test, then return a simplified form of
+ the test using shifts and logical operations. Otherwise return
+ NULL. TYPE is the desired result type. */
+
+tree
+fold_single_bit_test (enum tree_code code, tree arg0, tree arg1,
+ tree result_type)
+{
+ /* If this is a TRUTH_NOT_EXPR, it may have a single bit test inside
+ operand 0. */
+ if (code == TRUTH_NOT_EXPR)
+ {
+ code = TREE_CODE (arg0);
+ if (code != NE_EXPR && code != EQ_EXPR)
+ return NULL_TREE;
+
+ /* Extract the arguments of the EQ/NE. */
+ arg1 = TREE_OPERAND (arg0, 1);
+ arg0 = TREE_OPERAND (arg0, 0);
+
+ /* This requires us to invert the code. */
+ code = (code == EQ_EXPR ? NE_EXPR : EQ_EXPR);
+ }
+
+ /* If this is testing a single bit, we can optimize the test. */
+ if ((code == NE_EXPR || code == EQ_EXPR)
+ && TREE_CODE (arg0) == BIT_AND_EXPR && integer_zerop (arg1)
+ && integer_pow2p (TREE_OPERAND (arg0, 1)))
+ {
+ tree inner = TREE_OPERAND (arg0, 0);
+ tree type = TREE_TYPE (arg0);
+ int bitnum = tree_log2 (TREE_OPERAND (arg0, 1));
+ enum machine_mode operand_mode = TYPE_MODE (type);
+ int ops_unsigned;
+ tree signed_type, unsigned_type, intermediate_type;
+ tree arg00;
+
+ /* If we have (A & C) != 0 where C is the sign bit of A, convert
+ this into A < 0. Similarly for (A & C) == 0 into A >= 0. */
+ arg00 = sign_bit_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg0, 1));
+ if (arg00 != NULL_TREE
+ /* This is only a win if casting to a signed type is cheap,
+ i.e. when arg00's type is not a partial mode. */
+ && TYPE_PRECISION (TREE_TYPE (arg00))
+ == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg00))))
+ {
+ tree stype = (*lang_hooks.types.signed_type) (TREE_TYPE (arg00));
+ return fold (build (code == EQ_EXPR ? GE_EXPR : LT_EXPR, result_type,
+ fold_convert (stype, arg00),
+ fold_convert (stype, integer_zero_node)));
+ }
+
+ /* Otherwise we have (A & C) != 0 where C is a single bit,
+ convert that into ((A >> C2) & 1). Where C2 = log2(C).
+ Similarly for (A & C) == 0. */
+
+ /* If INNER is a right shift of a constant and it plus BITNUM does
+ not overflow, adjust BITNUM and INNER. */
+ if (TREE_CODE (inner) == RSHIFT_EXPR
+ && TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST
+ && TREE_INT_CST_HIGH (TREE_OPERAND (inner, 1)) == 0
+ && bitnum < TYPE_PRECISION (type)
+ && 0 > compare_tree_int (TREE_OPERAND (inner, 1),
+ bitnum - TYPE_PRECISION (type)))
+ {
+ bitnum += TREE_INT_CST_LOW (TREE_OPERAND (inner, 1));
+ inner = TREE_OPERAND (inner, 0);
+ }
+
+ /* If we are going to be able to omit the AND below, we must do our
+ operations as unsigned. If we must use the AND, we have a choice.
+ Normally unsigned is faster, but for some machines signed is. */
+#ifdef LOAD_EXTEND_OP
+ ops_unsigned = (LOAD_EXTEND_OP (operand_mode) == SIGN_EXTEND ? 0 : 1);
+#else
+ ops_unsigned = 1;
+#endif
+
+ signed_type = (*lang_hooks.types.type_for_mode) (operand_mode, 0);
+ unsigned_type = (*lang_hooks.types.type_for_mode) (operand_mode, 1);
+ intermediate_type = ops_unsigned ? unsigned_type : signed_type;
+ inner = fold_convert (intermediate_type, inner);
+
+ if (bitnum != 0)
+ inner = build (RSHIFT_EXPR, intermediate_type,
+ inner, size_int (bitnum));
+
+ if (code == EQ_EXPR)
+ inner = build (BIT_XOR_EXPR, intermediate_type,
+ inner, integer_one_node);
+
+ /* Put the AND last so it can combine with more things. */
+ inner = build (BIT_AND_EXPR, intermediate_type,
+ inner, integer_one_node);
+
+ /* Make sure to return the proper type. */
+ inner = fold_convert (result_type, inner);
+
+ return inner;
+ }
+ return NULL_TREE;
+}
+
+/* Check whether we are allowed to reorder operands arg0 and arg1,
+ such that the evaluation of arg1 occurs before arg0. */
+
+static bool
+reorder_operands_p (tree arg0, tree arg1)
+{
+ if (! flag_evaluation_order)
+ return true;
+ if (TREE_CONSTANT (arg0) || TREE_CONSTANT (arg1))
+ return true;
+ return ! TREE_SIDE_EFFECTS (arg0)
+ && ! TREE_SIDE_EFFECTS (arg1);
+}
+
+/* Test whether it is preferable two swap two operands, ARG0 and
+ ARG1, for example because ARG0 is an integer constant and ARG1
+ isn't. If REORDER is true, only recommend swapping if we can
+ evaluate the operands in reverse order. */
+
+static bool
+tree_swap_operands_p (tree arg0, tree arg1, bool reorder)
+{
+ STRIP_SIGN_NOPS (arg0);
+ STRIP_SIGN_NOPS (arg1);
+
+ if (TREE_CODE (arg1) == INTEGER_CST)
+ return 0;
+ if (TREE_CODE (arg0) == INTEGER_CST)
+ return 1;
+
+ if (TREE_CODE (arg1) == REAL_CST)
+ return 0;
+ if (TREE_CODE (arg0) == REAL_CST)
+ return 1;
+
+ if (TREE_CODE (arg1) == COMPLEX_CST)
+ return 0;
+ if (TREE_CODE (arg0) == COMPLEX_CST)
+ return 1;
+
+ if (TREE_CONSTANT (arg1))
+ return 0;
+ if (TREE_CONSTANT (arg0))
+ return 1;
+
+ if (optimize_size)
+ return 0;
+
+ if (reorder && flag_evaluation_order
+ && (TREE_SIDE_EFFECTS (arg0) || TREE_SIDE_EFFECTS (arg1)))
+ return 0;
+
+ if (DECL_P (arg1))
+ return 0;
+ if (DECL_P (arg0))
+ return 1;
+
+ return 0;
+}
/* Perform constant folding and related simplification of EXPR.
The related simplifications include x*1 => x, x*0 => 0, etc.,
@@ -4593,11 +5317,15 @@ fold_real_zero_addition_p (type, addend, negate)
We cannot simplify through a CONVERT_EXPR, FIX_EXPR or FLOAT_EXPR,
but we can constant-fold them if they have constant operands. */
+#ifdef ENABLE_FOLD_CHECKING
+# define fold(x) fold_1 (x)
+static tree fold_1 (tree);
+static
+#endif
tree
-fold (expr)
- tree expr;
+fold (tree expr)
{
- tree t = expr;
+ tree t = expr, orig_t;
tree t1 = NULL_TREE;
tree tem;
tree type = TREE_TYPE (expr);
@@ -4618,9 +5346,7 @@ fold (expr)
if (kind == 'c')
return t;
-#ifdef MAX_INTEGER_COMPUTATION_MODE
- check_max_integer_computation_mode (expr);
-#endif
+ orig_t = t;
if (code == NOP_EXPR || code == FLOAT_EXPR || code == CONVERT_EXPR)
{
@@ -4639,14 +5365,13 @@ fold (expr)
subop = arg0;
if (subop != 0 && TREE_CODE (subop) != INTEGER_CST
- && TREE_CODE (subop) != REAL_CST
- )
+ && TREE_CODE (subop) != REAL_CST)
/* Note that TREE_CONSTANT isn't enough:
static var addresses are constant but we can't
do arithmetic on them. */
wins = 0;
}
- else if (IS_EXPR_CODE_CLASS (kind) || kind == 'r')
+ else if (IS_EXPR_CODE_CLASS (kind))
{
int len = first_rtl_op (code);
int i;
@@ -4692,13 +5417,9 @@ fold (expr)
if ((code == PLUS_EXPR || code == MULT_EXPR || code == MIN_EXPR
|| code == MAX_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR
|| code == BIT_AND_EXPR)
- && (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST))
- {
- tem = arg0; arg0 = arg1; arg1 = tem;
-
- tem = TREE_OPERAND (t, 0); TREE_OPERAND (t, 0) = TREE_OPERAND (t, 1);
- TREE_OPERAND (t, 1) = tem;
- }
+ && tree_swap_operands_p (arg0, arg1, true))
+ return fold (build (code, type, TREE_OPERAND (t, 1),
+ TREE_OPERAND (t, 0)));
/* Now WINS is set as described above,
ARG0 is the first operand of EXPR,
@@ -4792,6 +5513,14 @@ fold (expr)
fold (build1 (code, type, integer_one_node)),
fold (build1 (code, type, integer_zero_node))));
}
+ else if (TREE_CODE_CLASS (code) == '<'
+ && TREE_CODE (arg0) == COMPOUND_EXPR)
+ return build (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
+ fold (build (code, type, TREE_OPERAND (arg0, 1), arg1)));
+ else if (TREE_CODE_CLASS (code) == '<'
+ && TREE_CODE (arg1) == COMPOUND_EXPR)
+ return build (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
+ fold (build (code, type, arg0, TREE_OPERAND (arg1, 1))));
else if (TREE_CODE_CLASS (code) == '2'
|| TREE_CODE_CLASS (code) == '<')
{
@@ -4808,7 +5537,7 @@ fold (expr)
|| count_cond (arg0, 25) + count_cond (arg1, 25) <= 25)
&& (! TREE_SIDE_EFFECTS (arg0)
|| ((*lang_hooks.decls.global_bindings_p) () == 0
- && ! contains_placeholder_p (arg0))))
+ && ! CONTAINS_PLACEHOLDER_P (arg0))))
return
fold_binary_op_with_conditional_arg (code, type, arg1, arg0,
/*cond_first_p=*/0);
@@ -4822,19 +5551,11 @@ fold (expr)
|| count_cond (arg0, 25) + count_cond (arg1, 25) <= 25)
&& (! TREE_SIDE_EFFECTS (arg1)
|| ((*lang_hooks.decls.global_bindings_p) () == 0
- && ! contains_placeholder_p (arg1))))
+ && ! CONTAINS_PLACEHOLDER_P (arg1))))
return
fold_binary_op_with_conditional_arg (code, type, arg0, arg1,
/*cond_first_p=*/1);
}
- else if (TREE_CODE_CLASS (code) == '<'
- && TREE_CODE (arg0) == COMPOUND_EXPR)
- return build (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
- fold (build (code, type, TREE_OPERAND (arg0, 1), arg1)));
- else if (TREE_CODE_CLASS (code) == '<'
- && TREE_CODE (arg1) == COMPOUND_EXPR)
- return build (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
- fold (build (code, type, arg0, TREE_OPERAND (arg1, 1))));
switch (code)
{
@@ -4888,7 +5609,8 @@ fold (expr)
if (TYPE_MAIN_VARIANT (inside_type) == TYPE_MAIN_VARIANT (final_type)
&& ((inter_int && final_int) || (inter_float && final_float))
&& inter_prec >= final_prec)
- return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0));
+ return fold (build1 (code, final_type,
+ TREE_OPERAND (TREE_OPERAND (t, 0), 0)));
/* Likewise, if the intermediate and final types are either both
float or both integer, we don't need the middle conversion if
@@ -4903,14 +5625,16 @@ fold (expr)
&& ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (final_type))
&& TYPE_MODE (final_type) == TYPE_MODE (inter_type))
&& ! final_ptr)
- return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0));
+ return fold (build1 (code, final_type,
+ TREE_OPERAND (TREE_OPERAND (t, 0), 0)));
/* If we have a sign-extension of a zero-extended value, we can
replace that by a single zero-extension. */
if (inside_int && inter_int && final_int
&& inside_prec < inter_prec && inter_prec < final_prec
&& inside_unsignedp && !inter_unsignedp)
- return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0));
+ return fold (build1 (code, final_type,
+ TREE_OPERAND (TREE_OPERAND (t, 0), 0)));
/* Two conversions in a row are not needed unless:
- some conversion is floating-point (overstrict for now), or
@@ -4934,7 +5658,8 @@ fold (expr)
&& ! (final_prec != GET_MODE_BITSIZE (TYPE_MODE (final_type))
&& TYPE_MODE (final_type) == TYPE_MODE (inter_type))
&& ! final_ptr)
- return convert (final_type, TREE_OPERAND (TREE_OPERAND (t, 0), 0));
+ return fold (build1 (code, final_type,
+ TREE_OPERAND (TREE_OPERAND (t, 0), 0)));
}
if (TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR
@@ -4946,9 +5671,12 @@ fold (expr)
/* Don't leave an assignment inside a conversion
unless assigning a bitfield. */
tree prev = TREE_OPERAND (t, 0);
+ if (t == orig_t)
+ t = copy_node (t);
TREE_OPERAND (t, 0) = TREE_OPERAND (prev, 1);
/* First do the assignment, then return converted constant. */
t = build (COMPOUND_EXPR, TREE_TYPE (t), prev, fold (t));
+ TREE_NO_UNUSED_WARNING (t) = 1;
TREE_USED (t) = 1;
return t;
}
@@ -4985,23 +5713,19 @@ fold (expr)
== ZERO_EXTEND))
{
tree uns = (*lang_hooks.types.unsigned_type) (TREE_TYPE (and0));
- and0 = convert (uns, and0);
- and1 = convert (uns, and1);
+ and0 = fold_convert (uns, and0);
+ and1 = fold_convert (uns, and1);
}
#endif
}
if (change)
return fold (build (BIT_AND_EXPR, TREE_TYPE (t),
- convert (TREE_TYPE (t), and0),
- convert (TREE_TYPE (t), and1)));
+ fold_convert (TREE_TYPE (t), and0),
+ fold_convert (TREE_TYPE (t), and1)));
}
- if (!wins)
- {
- TREE_CONSTANT (t) = TREE_CONSTANT (arg0);
- return t;
- }
- return fold_convert (t, arg0);
+ tem = fold_convert_const (code, TREE_TYPE (t), arg0);
+ return tem ? tem : t;
case VIEW_CONVERT_EXPR:
if (TREE_CODE (TREE_OPERAND (t, 0)) == VIEW_CONVERT_EXPR)
@@ -5010,7 +5734,8 @@ fold (expr)
return t;
case COMPONENT_REF:
- if (TREE_CODE (arg0) == CONSTRUCTOR)
+ if (TREE_CODE (arg0) == CONSTRUCTOR
+ && ! type_contains_placeholder_p (TREE_TYPE (arg0)))
{
tree m = purpose_member (arg1, CONSTRUCTOR_ELTS (arg0));
if (m)
@@ -5019,39 +5744,17 @@ fold (expr)
return t;
case RANGE_EXPR:
- TREE_CONSTANT (t) = wins;
- return t;
-
- case NEGATE_EXPR:
- if (wins)
+ if (TREE_CONSTANT (t) != wins)
{
- if (TREE_CODE (arg0) == INTEGER_CST)
- {
- unsigned HOST_WIDE_INT low;
- HOST_WIDE_INT high;
- int overflow = neg_double (TREE_INT_CST_LOW (arg0),
- TREE_INT_CST_HIGH (arg0),
- &low, &high);
- t = build_int_2 (low, high);
- TREE_TYPE (t) = type;
- TREE_OVERFLOW (t)
- = (TREE_OVERFLOW (arg0)
- | force_fit_type (t, overflow && !TREE_UNSIGNED (type)));
- TREE_CONSTANT_OVERFLOW (t)
- = TREE_OVERFLOW (t) | TREE_CONSTANT_OVERFLOW (arg0);
- }
- else if (TREE_CODE (arg0) == REAL_CST)
- t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
+ if (t == orig_t)
+ t = copy_node (t);
+ TREE_CONSTANT (t) = wins;
}
- else if (TREE_CODE (arg0) == NEGATE_EXPR)
- return TREE_OPERAND (arg0, 0);
-
- /* Convert - (a - b) to (b - a) for non-floating-point. */
- else if (TREE_CODE (arg0) == MINUS_EXPR
- && (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
- return build (MINUS_EXPR, type, TREE_OPERAND (arg0, 1),
- TREE_OPERAND (arg0, 0));
+ return t;
+ case NEGATE_EXPR:
+ if (negate_expr_p (arg0))
+ return fold_convert (type, negate_expr (arg0));
return t;
case ABS_EXPR:
@@ -5091,13 +5794,25 @@ fold (expr)
REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
}
}
- else if (TREE_CODE (arg0) == ABS_EXPR || TREE_CODE (arg0) == NEGATE_EXPR)
- return build1 (ABS_EXPR, type, TREE_OPERAND (arg0, 0));
+ else if (TREE_CODE (arg0) == NEGATE_EXPR)
+ return fold (build1 (ABS_EXPR, type, TREE_OPERAND (arg0, 0)));
+ /* Convert fabs((double)float) into (double)fabsf(float). */
+ else if (TREE_CODE (arg0) == NOP_EXPR
+ && TREE_CODE (type) == REAL_TYPE)
+ {
+ tree targ0 = strip_float_extensions (arg0);
+ if (targ0 != arg0)
+ return fold_convert (type, fold (build1 (ABS_EXPR,
+ TREE_TYPE (targ0),
+ targ0)));
+ }
+ else if (tree_expr_nonnegative_p (arg0))
+ return arg0;
return t;
case CONJ_EXPR:
if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
- return convert (type, arg0);
+ return fold_convert (type, arg0);
else if (TREE_CODE (arg0) == COMPLEX_EXPR)
return build (COMPLEX_EXPR, type,
TREE_OPERAND (arg0, 0),
@@ -5139,7 +5854,7 @@ fold (expr)
else if (! FLOAT_TYPE_P (type))
{
if (integer_zerop (arg1))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
/* If we are adding two BIT_AND_EXPR's, both of which are and'ing
with a constant, and the two constants have no bits in common,
@@ -5179,13 +5894,17 @@ fold (expr)
if (TREE_CODE (parg0) == MULT_EXPR
&& TREE_CODE (parg1) != MULT_EXPR)
return fold (build (PLUS_EXPR, type,
- fold (build (PLUS_EXPR, type, parg0, marg)),
- parg1));
+ fold (build (PLUS_EXPR, type,
+ fold_convert (type, parg0),
+ fold_convert (type, marg))),
+ fold_convert (type, parg1)));
if (TREE_CODE (parg0) != MULT_EXPR
&& TREE_CODE (parg1) == MULT_EXPR)
return fold (build (PLUS_EXPR, type,
- fold (build (PLUS_EXPR, type, parg1, marg)),
- parg0));
+ fold (build (PLUS_EXPR, type,
+ fold_convert (type, parg1),
+ fold_convert (type, marg))),
+ fold_convert (type, parg0)));
}
if (TREE_CODE (arg0) == MULT_EXPR && TREE_CODE (arg1) == MULT_EXPR)
@@ -5249,14 +5968,73 @@ fold (expr)
same));
}
}
+ else
+ {
+ /* See if ARG1 is zero and X + ARG1 reduces to X. */
+ if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 0))
+ return non_lvalue (fold_convert (type, arg0));
+
+ /* Likewise if the operands are reversed. */
+ if (fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
+ return non_lvalue (fold_convert (type, arg1));
+
+ /* Convert x+x into x*2.0. */
+ if (operand_equal_p (arg0, arg1, 0)
+ && SCALAR_FLOAT_TYPE_P (type))
+ return fold (build (MULT_EXPR, type, arg0,
+ build_real (type, dconst2)));
+
+ /* Convert x*c+x into x*(c+1). */
+ if (flag_unsafe_math_optimizations
+ && TREE_CODE (arg0) == MULT_EXPR
+ && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg0, 1))
+ && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0))
+ {
+ REAL_VALUE_TYPE c;
+
+ c = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
+ real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
+ return fold (build (MULT_EXPR, type, arg1,
+ build_real (type, c)));
+ }
+
+ /* Convert x+x*c into x*(c+1). */
+ if (flag_unsafe_math_optimizations
+ && TREE_CODE (arg1) == MULT_EXPR
+ && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg1, 1))
+ && operand_equal_p (TREE_OPERAND (arg1, 0), arg0, 0))
+ {
+ REAL_VALUE_TYPE c;
- /* See if ARG1 is zero and X + ARG1 reduces to X. */
- else if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 0))
- return non_lvalue (convert (type, arg0));
+ c = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
+ real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
+ return fold (build (MULT_EXPR, type, arg0,
+ build_real (type, c)));
+ }
- /* Likewise if the operands are reversed. */
- else if (fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
- return non_lvalue (convert (type, arg1));
+ /* Convert x*c1+x*c2 into x*(c1+c2). */
+ if (flag_unsafe_math_optimizations
+ && TREE_CODE (arg0) == MULT_EXPR
+ && TREE_CODE (arg1) == MULT_EXPR
+ && TREE_CODE (TREE_OPERAND (arg0, 1)) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg0, 1))
+ && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (TREE_OPERAND (arg1, 1))
+ && operand_equal_p (TREE_OPERAND (arg0, 0),
+ TREE_OPERAND (arg1, 0), 0))
+ {
+ REAL_VALUE_TYPE c1, c2;
+
+ c1 = TREE_REAL_CST (TREE_OPERAND (arg0, 1));
+ c2 = TREE_REAL_CST (TREE_OPERAND (arg1, 1));
+ real_arithmetic (&c1, PLUS_EXPR, &c1, &c2);
+ return fold (build (MULT_EXPR, type,
+ TREE_OPERAND (arg0, 0),
+ build_real (type, c1)));
+ }
+ }
bit_rotate:
/* (A << C1) + (A >> C2) if A is unsigned and C1+C2 is the size of A
@@ -5332,13 +6110,11 @@ fold (expr)
associate:
/* In most languages, can't associate operations on floats through
parentheses. Rather than remember where the parentheses were, we
- don't associate floats at all. It shouldn't matter much. However,
- associating multiplications is only very slightly inaccurate, so do
- that if -funsafe-math-optimizations is specified. */
+ don't associate floats at all, unless the user has specified
+ -funsafe-math-optimizations. */
if (! wins
- && (! FLOAT_TYPE_P (type)
- || (flag_unsafe_math_optimizations && code == MULT_EXPR)))
+ && (! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations))
{
tree var0, con0, lit0, minus_lit0;
tree var1, con1, lit1, minus_lit1;
@@ -5371,11 +6147,13 @@ fold (expr)
/* Preserve the MINUS_EXPR if the negative part of the literal is
greater than the positive part. Otherwise, the multiplicative
folding code (i.e extract_muldiv) may be fooled in case
- unsigned constants are substracted, like in the following
+ unsigned constants are subtracted, like in the following
example: ((X*2 + 4) - 8U)/2. */
if (minus_lit0 && lit0)
{
- if (tree_int_cst_lt (lit0, minus_lit0))
+ if (TREE_CODE (lit0) == INTEGER_CST
+ && TREE_CODE (minus_lit0) == INTEGER_CST
+ && tree_int_cst_lt (lit0, minus_lit0))
{
minus_lit0 = associate_trees (minus_lit0, lit0,
MINUS_EXPR, type);
@@ -5391,19 +6169,22 @@ fold (expr)
if (minus_lit0)
{
if (con0 == 0)
- return convert (type, associate_trees (var0, minus_lit0,
- MINUS_EXPR, type));
+ return fold_convert (type,
+ associate_trees (var0, minus_lit0,
+ MINUS_EXPR, type));
else
{
con0 = associate_trees (con0, minus_lit0,
MINUS_EXPR, type);
- return convert (type, associate_trees (var0, con0,
- PLUS_EXPR, type));
+ return fold_convert (type,
+ associate_trees (var0, con0,
+ PLUS_EXPR, type));
}
}
con0 = associate_trees (con0, lit0, code, type);
- return convert (type, associate_trees (var0, con0, code, type));
+ return fold_convert (type, associate_trees (var0, con0,
+ code, type));
}
}
@@ -5415,7 +6196,7 @@ fold (expr)
/* The return value should always have
the same type as the original expression. */
if (TREE_TYPE (t1) != TREE_TYPE (t))
- t1 = convert (TREE_TYPE (t), t1);
+ t1 = fold_convert (TREE_TYPE (t), t1);
return t1;
}
@@ -5425,20 +6206,21 @@ fold (expr)
/* A - (-B) -> A + B */
if (TREE_CODE (arg1) == NEGATE_EXPR)
return fold (build (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
- /* (-A) - CST -> (-CST) - A for floating point (what about ints ?) */
- if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == REAL_CST)
- return
- fold (build (MINUS_EXPR, type,
- build_real (TREE_TYPE (arg1),
- REAL_VALUE_NEGATE (TREE_REAL_CST (arg1))),
- TREE_OPERAND (arg0, 0)));
+ /* (-A) - B -> (-B) - A where B is easily negated and we can swap. */
+ if (TREE_CODE (arg0) == NEGATE_EXPR
+ && (FLOAT_TYPE_P (type)
+ || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv))
+ && negate_expr_p (arg1)
+ && reorder_operands_p (arg0, arg1))
+ return fold (build (MINUS_EXPR, type, negate_expr (arg1),
+ TREE_OPERAND (arg0, 0)));
if (! FLOAT_TYPE_P (type))
{
if (! wins && integer_zerop (arg0))
- return negate_expr (convert (type, arg1));
+ return negate_expr (fold_convert (type, arg1));
if (integer_zerop (arg1))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
/* (A * C) - (B * C) -> (A-B) * C. Since we are most concerned
about the case where C is a constant, just try one of the
@@ -5452,17 +6234,52 @@ fold (expr)
TREE_OPERAND (arg0, 0),
TREE_OPERAND (arg1, 0))),
TREE_OPERAND (arg0, 1)));
+
+ /* Fold A - (A & B) into ~B & A. */
+ if (!TREE_SIDE_EFFECTS (arg0)
+ && TREE_CODE (arg1) == BIT_AND_EXPR)
+ {
+ if (operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0))
+ return fold (build (BIT_AND_EXPR, type,
+ fold (build1 (BIT_NOT_EXPR, type,
+ TREE_OPERAND (arg1, 0))),
+ arg0));
+ if (operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
+ return fold (build (BIT_AND_EXPR, type,
+ fold (build1 (BIT_NOT_EXPR, type,
+ TREE_OPERAND (arg1, 1))),
+ arg0));
+ }
+
+ /* Fold (A & ~B) - (A & B) into (A ^ B) - B, where B is
+ any power of 2 minus 1. */
+ if (TREE_CODE (arg0) == BIT_AND_EXPR
+ && TREE_CODE (arg1) == BIT_AND_EXPR
+ && operand_equal_p (TREE_OPERAND (arg0, 0),
+ TREE_OPERAND (arg1, 0), 0))
+ {
+ tree mask0 = TREE_OPERAND (arg0, 1);
+ tree mask1 = TREE_OPERAND (arg1, 1);
+ tree tem = fold (build1 (BIT_NOT_EXPR, type, mask0));
+
+ if (operand_equal_p (tem, mask1, 0))
+ {
+ tem = fold (build (BIT_XOR_EXPR, type,
+ TREE_OPERAND (arg0, 0), mask1));
+ return fold (build (MINUS_EXPR, type, tem, mask1));
+ }
+ }
}
/* See if ARG1 is zero and X - ARG1 reduces to X. */
else if (fold_real_zero_addition_p (TREE_TYPE (arg0), arg1, 1))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
/* (ARG0 - ARG1) is the same as (-ARG1 + ARG0). So check whether
ARG0 is zero and X + ARG0 reduces to X, since that would mean
(-ARG1 + ARG0) reduces to -ARG1. */
else if (!wins && fold_real_zero_addition_p (TREE_TYPE (arg1), arg0, 0))
- return negate_expr (convert (type, arg1));
+ return negate_expr (fold_convert (type, arg1));
/* Fold &x - &x. This can happen from &x.foo - &x.
This is unsafe for certain floats even in non-IEEE formats.
@@ -5472,14 +6289,19 @@ fold (expr)
if ((! FLOAT_TYPE_P (type) || flag_unsafe_math_optimizations)
&& operand_equal_p (arg0, arg1, 0))
- return convert (type, integer_zero_node);
+ return fold_convert (type, integer_zero_node);
goto associate;
case MULT_EXPR:
/* (-A) * (-B) -> A * B */
- if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == NEGATE_EXPR)
- return fold (build (MULT_EXPR, type, TREE_OPERAND (arg0, 0),
+ if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
+ return fold (build (MULT_EXPR, type,
+ TREE_OPERAND (arg0, 0),
+ negate_expr (arg1)));
+ if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
+ return fold (build (MULT_EXPR, type,
+ negate_expr (arg0),
TREE_OPERAND (arg1, 0)));
if (! FLOAT_TYPE_P (type))
@@ -5487,7 +6309,7 @@ fold (expr)
if (integer_zerop (arg1))
return omit_one_operand (type, arg1, arg0);
if (integer_onep (arg1))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
/* (a * (1 << b)) is (a << b) */
if (TREE_CODE (arg1) == LSHIFT_EXPR
@@ -5500,9 +6322,10 @@ fold (expr)
TREE_OPERAND (arg0, 1)));
if (TREE_CODE (arg1) == INTEGER_CST
- && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
+ && 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0),
+ fold_convert (type, arg1),
code, NULL_TREE)))
- return convert (type, tem);
+ return fold_convert (type, tem);
}
else
@@ -5518,20 +6341,218 @@ fold (expr)
/* In IEEE floating point, x*1 is not equivalent to x for snans. */
if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
&& real_onep (arg1))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
/* Transform x * -1.0 into -x. */
if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
&& real_minus_onep (arg1))
return fold (build1 (NEGATE_EXPR, type, arg0));
- /* x*2 is x+x */
- if (! wins && real_twop (arg1)
- && (*lang_hooks.decls.global_bindings_p) () == 0
- && ! contains_placeholder_p (arg0))
+ /* Convert (C1/X)*C2 into (C1*C2)/X. */
+ if (flag_unsafe_math_optimizations
+ && TREE_CODE (arg0) == RDIV_EXPR
+ && TREE_CODE (arg1) == REAL_CST
+ && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST)
+ {
+ tree tem = const_binop (MULT_EXPR, TREE_OPERAND (arg0, 0),
+ arg1, 0);
+ if (tem)
+ return fold (build (RDIV_EXPR, type, tem,
+ TREE_OPERAND (arg0, 1)));
+ }
+
+ if (flag_unsafe_math_optimizations)
{
- tree arg = save_expr (arg0);
- return build (PLUS_EXPR, type, arg, arg);
+ enum built_in_function fcode0 = builtin_mathfn_code (arg0);
+ enum built_in_function fcode1 = builtin_mathfn_code (arg1);
+
+ /* Optimizations of sqrt(...)*sqrt(...). */
+ if ((fcode0 == BUILT_IN_SQRT && fcode1 == BUILT_IN_SQRT)
+ || (fcode0 == BUILT_IN_SQRTF && fcode1 == BUILT_IN_SQRTF)
+ || (fcode0 == BUILT_IN_SQRTL && fcode1 == BUILT_IN_SQRTL))
+ {
+ tree sqrtfn, arg, arglist;
+ tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
+ tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
+
+ /* Optimize sqrt(x)*sqrt(x) as x. */
+ if (operand_equal_p (arg00, arg10, 0)
+ && ! HONOR_SNANS (TYPE_MODE (type)))
+ return arg00;
+
+ /* Optimize sqrt(x)*sqrt(y) as sqrt(x*y). */
+ sqrtfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
+ arg = fold (build (MULT_EXPR, type, arg00, arg10));
+ arglist = build_tree_list (NULL_TREE, arg);
+ return build_function_call_expr (sqrtfn, arglist);
+ }
+
+ /* Optimize expN(x)*expN(y) as expN(x+y). */
+ if (fcode0 == fcode1
+ && (fcode0 == BUILT_IN_EXP
+ || fcode0 == BUILT_IN_EXPF
+ || fcode0 == BUILT_IN_EXPL
+ || fcode0 == BUILT_IN_EXP2
+ || fcode0 == BUILT_IN_EXP2F
+ || fcode0 == BUILT_IN_EXP2L
+ || fcode0 == BUILT_IN_EXP10
+ || fcode0 == BUILT_IN_EXP10F
+ || fcode0 == BUILT_IN_EXP10L
+ || fcode0 == BUILT_IN_POW10
+ || fcode0 == BUILT_IN_POW10F
+ || fcode0 == BUILT_IN_POW10L))
+ {
+ tree expfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
+ tree arg = build (PLUS_EXPR, type,
+ TREE_VALUE (TREE_OPERAND (arg0, 1)),
+ TREE_VALUE (TREE_OPERAND (arg1, 1)));
+ tree arglist = build_tree_list (NULL_TREE, fold (arg));
+ return build_function_call_expr (expfn, arglist);
+ }
+
+ /* Optimizations of pow(...)*pow(...). */
+ if ((fcode0 == BUILT_IN_POW && fcode1 == BUILT_IN_POW)
+ || (fcode0 == BUILT_IN_POWF && fcode1 == BUILT_IN_POWF)
+ || (fcode0 == BUILT_IN_POWL && fcode1 == BUILT_IN_POWL))
+ {
+ tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
+ tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0,
+ 1)));
+ tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
+ tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1,
+ 1)));
+
+ /* Optimize pow(x,y)*pow(z,y) as pow(x*z,y). */
+ if (operand_equal_p (arg01, arg11, 0))
+ {
+ tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
+ tree arg = build (MULT_EXPR, type, arg00, arg10);
+ tree arglist = tree_cons (NULL_TREE, fold (arg),
+ build_tree_list (NULL_TREE,
+ arg01));
+ return build_function_call_expr (powfn, arglist);
+ }
+
+ /* Optimize pow(x,y)*pow(x,z) as pow(x,y+z). */
+ if (operand_equal_p (arg00, arg10, 0))
+ {
+ tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
+ tree arg = fold (build (PLUS_EXPR, type, arg01, arg11));
+ tree arglist = tree_cons (NULL_TREE, arg00,
+ build_tree_list (NULL_TREE,
+ arg));
+ return build_function_call_expr (powfn, arglist);
+ }
+ }
+
+ /* Optimize tan(x)*cos(x) as sin(x). */
+ if (((fcode0 == BUILT_IN_TAN && fcode1 == BUILT_IN_COS)
+ || (fcode0 == BUILT_IN_TANF && fcode1 == BUILT_IN_COSF)
+ || (fcode0 == BUILT_IN_TANL && fcode1 == BUILT_IN_COSL)
+ || (fcode0 == BUILT_IN_COS && fcode1 == BUILT_IN_TAN)
+ || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_TANF)
+ || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_TANL))
+ && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
+ TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
+ {
+ tree sinfn;
+
+ switch (fcode0)
+ {
+ case BUILT_IN_TAN:
+ case BUILT_IN_COS:
+ sinfn = implicit_built_in_decls[BUILT_IN_SIN];
+ break;
+ case BUILT_IN_TANF:
+ case BUILT_IN_COSF:
+ sinfn = implicit_built_in_decls[BUILT_IN_SINF];
+ break;
+ case BUILT_IN_TANL:
+ case BUILT_IN_COSL:
+ sinfn = implicit_built_in_decls[BUILT_IN_SINL];
+ break;
+ default:
+ sinfn = NULL_TREE;
+ }
+
+ if (sinfn != NULL_TREE)
+ return build_function_call_expr (sinfn,
+ TREE_OPERAND (arg0, 1));
+ }
+
+ /* Optimize x*pow(x,c) as pow(x,c+1). */
+ if (fcode1 == BUILT_IN_POW
+ || fcode1 == BUILT_IN_POWF
+ || fcode1 == BUILT_IN_POWL)
+ {
+ tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
+ tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1,
+ 1)));
+ if (TREE_CODE (arg11) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (arg11)
+ && operand_equal_p (arg0, arg10, 0))
+ {
+ tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
+ REAL_VALUE_TYPE c;
+ tree arg, arglist;
+
+ c = TREE_REAL_CST (arg11);
+ real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
+ arg = build_real (type, c);
+ arglist = build_tree_list (NULL_TREE, arg);
+ arglist = tree_cons (NULL_TREE, arg0, arglist);
+ return build_function_call_expr (powfn, arglist);
+ }
+ }
+
+ /* Optimize pow(x,c)*x as pow(x,c+1). */
+ if (fcode0 == BUILT_IN_POW
+ || fcode0 == BUILT_IN_POWF
+ || fcode0 == BUILT_IN_POWL)
+ {
+ tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
+ tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0,
+ 1)));
+ if (TREE_CODE (arg01) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (arg01)
+ && operand_equal_p (arg1, arg00, 0))
+ {
+ tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
+ REAL_VALUE_TYPE c;
+ tree arg, arglist;
+
+ c = TREE_REAL_CST (arg01);
+ real_arithmetic (&c, PLUS_EXPR, &c, &dconst1);
+ arg = build_real (type, c);
+ arglist = build_tree_list (NULL_TREE, arg);
+ arglist = tree_cons (NULL_TREE, arg1, arglist);
+ return build_function_call_expr (powfn, arglist);
+ }
+ }
+
+ /* Optimize x*x as pow(x,2.0), which is expanded as x*x. */
+ if (! optimize_size
+ && operand_equal_p (arg0, arg1, 0))
+ {
+ tree powfn;
+
+ if (type == double_type_node)
+ powfn = implicit_built_in_decls[BUILT_IN_POW];
+ else if (type == float_type_node)
+ powfn = implicit_built_in_decls[BUILT_IN_POWF];
+ else if (type == long_double_type_node)
+ powfn = implicit_built_in_decls[BUILT_IN_POWL];
+ else
+ powfn = NULL_TREE;
+
+ if (powfn)
+ {
+ tree arg = build_real (type, dconst2);
+ tree arglist = build_tree_list (NULL_TREE, arg);
+ arglist = tree_cons (NULL_TREE, arg0, arglist);
+ return build_function_call_expr (powfn, arglist);
+ }
+ }
}
}
goto associate;
@@ -5541,7 +6562,7 @@ fold (expr)
if (integer_all_onesp (arg1))
return omit_one_operand (type, arg1, arg0);
if (integer_zerop (arg1))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
t1 = distribute_bit_expr (code, type, arg0, arg1);
if (t1 != NULL_TREE)
return t1;
@@ -5567,7 +6588,7 @@ fold (expr)
case BIT_XOR_EXPR:
if (integer_zerop (arg1))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
if (integer_all_onesp (arg1))
return fold (build1 (BIT_NOT_EXPR, type, arg0));
@@ -5592,15 +6613,14 @@ fold (expr)
goto bit_rotate;
case BIT_AND_EXPR:
- bit_and:
if (integer_all_onesp (arg1))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
if (integer_zerop (arg1))
return omit_one_operand (type, arg1, arg0);
t1 = distribute_bit_expr (code, type, arg0, arg1);
if (t1 != NULL_TREE)
return t1;
- /* Simplify ((int)c & 0x377) into (int)c, if c is unsigned char. */
+ /* Simplify ((int)c & 0377) into (int)c, if c is unsigned char. */
if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR
&& TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
{
@@ -5610,7 +6630,7 @@ fold (expr)
if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_WIDE_INT
&& (~TREE_INT_CST_LOW (arg1)
& (((HOST_WIDE_INT) 1 << prec) - 1)) == 0)
- return build1 (NOP_EXPR, type, TREE_OPERAND (arg0, 0));
+ return fold_convert (type, TREE_OPERAND (arg0, 0));
}
/* Convert (and (not arg0) (not arg1)) to (not (or (arg0) (arg1))).
@@ -5630,19 +6650,6 @@ fold (expr)
goto associate;
- case BIT_ANDTC_EXPR:
- if (integer_all_onesp (arg0))
- return non_lvalue (convert (type, arg1));
- if (integer_zerop (arg0))
- return omit_one_operand (type, arg0, arg1);
- if (TREE_CODE (arg1) == INTEGER_CST)
- {
- arg1 = fold (build1 (BIT_NOT_EXPR, type, arg1));
- code = BIT_AND_EXPR;
- goto bit_and;
- }
- goto binary;
-
case RDIV_EXPR:
/* Don't touch a floating-point divide by zero unless the mode
of the constant can represent infinity. */
@@ -5652,14 +6659,24 @@ fold (expr)
return t;
/* (-A) / (-B) -> A / B */
- if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == NEGATE_EXPR)
- return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
+ if (TREE_CODE (arg0) == NEGATE_EXPR && negate_expr_p (arg1))
+ return fold (build (RDIV_EXPR, type,
+ TREE_OPERAND (arg0, 0),
+ negate_expr (arg1)));
+ if (TREE_CODE (arg1) == NEGATE_EXPR && negate_expr_p (arg0))
+ return fold (build (RDIV_EXPR, type,
+ negate_expr (arg0),
TREE_OPERAND (arg1, 0)));
/* In IEEE floating point, x/1 is not equivalent to x for snans. */
if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
&& real_onep (arg1))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
+
+ /* In IEEE floating point, x/-1 is not equivalent to -x for snans. */
+ if (!HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0)))
+ && real_minus_onep (arg1))
+ return non_lvalue (fold_convert (type, negate_expr (arg0)));
/* If ARG1 is a constant, we can convert this to a multiply by the
reciprocal. This does not have the same rounding properties,
@@ -5673,7 +6690,7 @@ fold (expr)
arg1, 0)))
return fold (build (MULT_EXPR, type, arg0, tem));
/* Find the reciprocal if optimizing and the result is exact. */
- else if (optimize)
+ if (optimize)
{
REAL_VALUE_TYPE r;
r = TREE_REAL_CST (arg1);
@@ -5687,19 +6704,151 @@ fold (expr)
/* Convert A/B/C to A/(B*C). */
if (flag_unsafe_math_optimizations
&& TREE_CODE (arg0) == RDIV_EXPR)
- {
- return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
- build (MULT_EXPR, type, TREE_OPERAND (arg0, 1),
- arg1)));
- }
+ return fold (build (RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
+ fold (build (MULT_EXPR, type,
+ TREE_OPERAND (arg0, 1), arg1))));
+
/* Convert A/(B/C) to (A/B)*C. */
if (flag_unsafe_math_optimizations
&& TREE_CODE (arg1) == RDIV_EXPR)
+ return fold (build (MULT_EXPR, type,
+ fold (build (RDIV_EXPR, type, arg0,
+ TREE_OPERAND (arg1, 0))),
+ TREE_OPERAND (arg1, 1)));
+
+ /* Convert C1/(X*C2) into (C1/C2)/X. */
+ if (flag_unsafe_math_optimizations
+ && TREE_CODE (arg1) == MULT_EXPR
+ && TREE_CODE (arg0) == REAL_CST
+ && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
+ {
+ tree tem = const_binop (RDIV_EXPR, arg0,
+ TREE_OPERAND (arg1, 1), 0);
+ if (tem)
+ return fold (build (RDIV_EXPR, type, tem,
+ TREE_OPERAND (arg1, 0)));
+ }
+
+ if (flag_unsafe_math_optimizations)
{
- return fold (build (MULT_EXPR, type,
- build (RDIV_EXPR, type, arg0,
- TREE_OPERAND (arg1, 0)),
- TREE_OPERAND (arg1, 1)));
+ enum built_in_function fcode = builtin_mathfn_code (arg1);
+ /* Optimize x/expN(y) into x*expN(-y). */
+ if (fcode == BUILT_IN_EXP
+ || fcode == BUILT_IN_EXPF
+ || fcode == BUILT_IN_EXPL
+ || fcode == BUILT_IN_EXP2
+ || fcode == BUILT_IN_EXP2F
+ || fcode == BUILT_IN_EXP2L
+ || fcode == BUILT_IN_EXP10
+ || fcode == BUILT_IN_EXP10F
+ || fcode == BUILT_IN_EXP10L
+ || fcode == BUILT_IN_POW10
+ || fcode == BUILT_IN_POW10F
+ || fcode == BUILT_IN_POW10L)
+ {
+ tree expfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
+ tree arg = build1 (NEGATE_EXPR, type,
+ TREE_VALUE (TREE_OPERAND (arg1, 1)));
+ tree arglist = build_tree_list (NULL_TREE, fold (arg));
+ arg1 = build_function_call_expr (expfn, arglist);
+ return fold (build (MULT_EXPR, type, arg0, arg1));
+ }
+
+ /* Optimize x/pow(y,z) into x*pow(y,-z). */
+ if (fcode == BUILT_IN_POW
+ || fcode == BUILT_IN_POWF
+ || fcode == BUILT_IN_POWL)
+ {
+ tree powfn = TREE_OPERAND (TREE_OPERAND (arg1, 0), 0);
+ tree arg10 = TREE_VALUE (TREE_OPERAND (arg1, 1));
+ tree arg11 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg1, 1)));
+ tree neg11 = fold (build1 (NEGATE_EXPR, type, arg11));
+ tree arglist = tree_cons(NULL_TREE, arg10,
+ build_tree_list (NULL_TREE, neg11));
+ arg1 = build_function_call_expr (powfn, arglist);
+ return fold (build (MULT_EXPR, type, arg0, arg1));
+ }
+ }
+
+ if (flag_unsafe_math_optimizations)
+ {
+ enum built_in_function fcode0 = builtin_mathfn_code (arg0);
+ enum built_in_function fcode1 = builtin_mathfn_code (arg1);
+
+ /* Optimize sin(x)/cos(x) as tan(x). */
+ if (((fcode0 == BUILT_IN_SIN && fcode1 == BUILT_IN_COS)
+ || (fcode0 == BUILT_IN_SINF && fcode1 == BUILT_IN_COSF)
+ || (fcode0 == BUILT_IN_SINL && fcode1 == BUILT_IN_COSL))
+ && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
+ TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
+ {
+ tree tanfn;
+
+ if (fcode0 == BUILT_IN_SIN)
+ tanfn = implicit_built_in_decls[BUILT_IN_TAN];
+ else if (fcode0 == BUILT_IN_SINF)
+ tanfn = implicit_built_in_decls[BUILT_IN_TANF];
+ else if (fcode0 == BUILT_IN_SINL)
+ tanfn = implicit_built_in_decls[BUILT_IN_TANL];
+ else
+ tanfn = NULL_TREE;
+
+ if (tanfn != NULL_TREE)
+ return build_function_call_expr (tanfn,
+ TREE_OPERAND (arg0, 1));
+ }
+
+ /* Optimize cos(x)/sin(x) as 1.0/tan(x). */
+ if (((fcode0 == BUILT_IN_COS && fcode1 == BUILT_IN_SIN)
+ || (fcode0 == BUILT_IN_COSF && fcode1 == BUILT_IN_SINF)
+ || (fcode0 == BUILT_IN_COSL && fcode1 == BUILT_IN_SINL))
+ && operand_equal_p (TREE_VALUE (TREE_OPERAND (arg0, 1)),
+ TREE_VALUE (TREE_OPERAND (arg1, 1)), 0))
+ {
+ tree tanfn;
+
+ if (fcode0 == BUILT_IN_COS)
+ tanfn = implicit_built_in_decls[BUILT_IN_TAN];
+ else if (fcode0 == BUILT_IN_COSF)
+ tanfn = implicit_built_in_decls[BUILT_IN_TANF];
+ else if (fcode0 == BUILT_IN_COSL)
+ tanfn = implicit_built_in_decls[BUILT_IN_TANL];
+ else
+ tanfn = NULL_TREE;
+
+ if (tanfn != NULL_TREE)
+ {
+ tree tmp = TREE_OPERAND (arg0, 1);
+ tmp = build_function_call_expr (tanfn, tmp);
+ return fold (build (RDIV_EXPR, type,
+ build_real (type, dconst1),
+ tmp));
+ }
+ }
+
+ /* Optimize pow(x,c)/x as pow(x,c-1). */
+ if (fcode0 == BUILT_IN_POW
+ || fcode0 == BUILT_IN_POWF
+ || fcode0 == BUILT_IN_POWL)
+ {
+ tree arg00 = TREE_VALUE (TREE_OPERAND (arg0, 1));
+ tree arg01 = TREE_VALUE (TREE_CHAIN (TREE_OPERAND (arg0, 1)));
+ if (TREE_CODE (arg01) == REAL_CST
+ && ! TREE_CONSTANT_OVERFLOW (arg01)
+ && operand_equal_p (arg1, arg00, 0))
+ {
+ tree powfn = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
+ REAL_VALUE_TYPE c;
+ tree arg, arglist;
+
+ c = TREE_REAL_CST (arg01);
+ real_arithmetic (&c, MINUS_EXPR, &c, &dconst1);
+ arg = build_real (type, c);
+ arglist = build_tree_list (NULL_TREE, arg);
+ arglist = tree_cons (NULL_TREE, arg1, arglist);
+ return build_function_call_expr (powfn, arglist);
+ }
+ }
}
goto binary;
@@ -5709,7 +6858,7 @@ fold (expr)
case CEIL_DIV_EXPR:
case EXACT_DIV_EXPR:
if (integer_onep (arg1))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
if (integer_zerop (arg1))
return t;
@@ -5726,7 +6875,7 @@ fold (expr)
if (TREE_CODE (arg1) == INTEGER_CST
&& 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
code, NULL_TREE)))
- return convert (type, tem);
+ return fold_convert (type, tem);
goto binary;
@@ -5742,16 +6891,29 @@ fold (expr)
if (TREE_CODE (arg1) == INTEGER_CST
&& 0 != (tem = extract_muldiv (TREE_OPERAND (t, 0), arg1,
code, NULL_TREE)))
- return convert (type, tem);
+ return fold_convert (type, tem);
goto binary;
- case LSHIFT_EXPR:
- case RSHIFT_EXPR:
case LROTATE_EXPR:
case RROTATE_EXPR:
+ if (integer_all_onesp (arg0))
+ return omit_one_operand (type, arg0, arg1);
+ goto shift;
+
+ case RSHIFT_EXPR:
+ /* Optimize -1 >> x for arithmetic right shifts. */
+ if (integer_all_onesp (arg0) && ! TREE_UNSIGNED (type))
+ return omit_one_operand (type, arg0, arg1);
+ /* ... fall through ... */
+
+ case LSHIFT_EXPR:
+ shift:
if (integer_zerop (arg1))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
+ if (integer_zerop (arg0))
+ return omit_one_operand (type, arg0, arg1);
+
/* Since negative shift count is not well-defined,
don't try to compute it in the compiler. */
if (TREE_CODE (arg1) == INTEGER_CST && tree_int_cst_sgn (arg1) < 0)
@@ -5760,16 +6922,10 @@ fold (expr)
RROTATE_EXPR by a new constant. */
if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
{
- TREE_SET_CODE (t, RROTATE_EXPR);
- code = RROTATE_EXPR;
- TREE_OPERAND (t, 1) = arg1
- = const_binop
- (MINUS_EXPR,
- convert (TREE_TYPE (arg1),
- build_int_2 (GET_MODE_BITSIZE (TYPE_MODE (type)), 0)),
- arg1, 0);
- if (tree_int_cst_sgn (arg1) < 0)
- return t;
+ tree tem = build_int_2 (GET_MODE_BITSIZE (TYPE_MODE (type)), 0);
+ tem = fold_convert (TREE_TYPE (arg1), tem);
+ tem = const_binop (MINUS_EXPR, tem, arg1, 0);
+ return fold (build (RROTATE_EXPR, type, arg0, tem));
}
/* If we have a rotate of a bit operation with the rotate count and
@@ -5777,7 +6933,6 @@ fold (expr)
permute the two operations. */
if (code == RROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST
&& (TREE_CODE (arg0) == BIT_AND_EXPR
- || TREE_CODE (arg0) == BIT_ANDTC_EXPR
|| TREE_CODE (arg0) == BIT_IOR_EXPR
|| TREE_CODE (arg0) == BIT_XOR_EXPR)
&& TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
@@ -5826,8 +6981,13 @@ fold (expr)
tem = invert_truthvalue (arg0);
/* Avoid infinite recursion. */
if (TREE_CODE (tem) == TRUTH_NOT_EXPR)
- return t;
- return convert (type, tem);
+ {
+ tem = fold_single_bit_test (code, arg0, arg1, type);
+ if (tem)
+ return tem;
+ return t;
+ }
+ return fold_convert (type, tem);
case TRUTH_ANDIF_EXPR:
/* Note that the operands of this must be ints
@@ -5835,15 +6995,15 @@ fold (expr)
("true" is a fixed value perhaps depending on the language.) */
/* If first arg is constant zero, return it. */
if (integer_zerop (arg0))
- return convert (type, arg0);
+ return fold_convert (type, arg0);
case TRUTH_AND_EXPR:
/* If either arg is constant true, drop it. */
if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
- return non_lvalue (convert (type, arg1));
+ return non_lvalue (fold_convert (type, arg1));
if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1)
/* Preserve sequence points. */
&& (code != TRUTH_ANDIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
/* If second arg is constant zero, result is zero, but first arg
must be evaluated. */
if (integer_zerop (arg1))
@@ -5923,15 +7083,15 @@ fold (expr)
("true" is a fixed value perhaps depending on the language.) */
/* If first arg is constant true, return it. */
if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
- return convert (type, arg0);
+ return fold_convert (type, arg0);
case TRUTH_OR_EXPR:
/* If either arg is constant zero, drop it. */
if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
- return non_lvalue (convert (type, arg1));
+ return non_lvalue (fold_convert (type, arg1));
if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1)
/* Preserve sequence points. */
&& (code != TRUTH_ORIF_EXPR || ! TREE_SIDE_EFFECTS (arg0)))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
/* If second arg is constant true, result is true, but we must
evaluate first arg. */
if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
@@ -5945,14 +7105,14 @@ fold (expr)
case TRUTH_XOR_EXPR:
/* If either arg is constant zero, drop it. */
if (integer_zerop (arg0))
- return non_lvalue (convert (type, arg1));
+ return non_lvalue (fold_convert (type, arg1));
if (integer_zerop (arg1))
- return non_lvalue (convert (type, arg0));
+ return non_lvalue (fold_convert (type, arg0));
/* If either arg is constant true, this is a logical inversion. */
if (integer_onep (arg0))
- return non_lvalue (convert (type, invert_truthvalue (arg1)));
+ return non_lvalue (fold_convert (type, invert_truthvalue (arg1)));
if (integer_onep (arg1))
- return non_lvalue (convert (type, invert_truthvalue (arg0)));
+ return non_lvalue (fold_convert (type, invert_truthvalue (arg0)));
return t;
case EQ_EXPR:
@@ -5962,40 +7122,64 @@ fold (expr)
case LE_EXPR:
case GE_EXPR:
/* If one arg is a real or integer constant, put it last. */
- if ((TREE_CODE (arg0) == INTEGER_CST
- && TREE_CODE (arg1) != INTEGER_CST)
- || (TREE_CODE (arg0) == REAL_CST
- && TREE_CODE (arg0) != REAL_CST))
- {
- TREE_OPERAND (t, 0) = arg1;
- TREE_OPERAND (t, 1) = arg0;
- arg0 = TREE_OPERAND (t, 0);
- arg1 = TREE_OPERAND (t, 1);
- code = swap_tree_comparison (code);
- TREE_SET_CODE (t, code);
- }
+ if (tree_swap_operands_p (arg0, arg1, true))
+ return fold (build (swap_tree_comparison (code), type, arg1, arg0));
if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
{
+ tree targ0 = strip_float_extensions (arg0);
+ tree targ1 = strip_float_extensions (arg1);
+ tree newtype = TREE_TYPE (targ0);
+
+ if (TYPE_PRECISION (TREE_TYPE (targ1)) > TYPE_PRECISION (newtype))
+ newtype = TREE_TYPE (targ1);
+
+ /* Fold (double)float1 CMP (double)float2 into float1 CMP float2. */
+ if (TYPE_PRECISION (newtype) < TYPE_PRECISION (TREE_TYPE (arg0)))
+ return fold (build (code, type, fold_convert (newtype, targ0),
+ fold_convert (newtype, targ1)));
+
/* (-a) CMP (-b) -> b CMP a */
if (TREE_CODE (arg0) == NEGATE_EXPR
&& TREE_CODE (arg1) == NEGATE_EXPR)
return fold (build (code, type, TREE_OPERAND (arg1, 0),
TREE_OPERAND (arg0, 0)));
- /* (-a) CMP CST -> a swap(CMP) (-CST) */
- if (TREE_CODE (arg0) == NEGATE_EXPR && TREE_CODE (arg1) == REAL_CST)
- return
- fold (build
- (swap_tree_comparison (code), type,
- TREE_OPERAND (arg0, 0),
- build_real (TREE_TYPE (arg1),
- REAL_VALUE_NEGATE (TREE_REAL_CST (arg1)))));
- /* IEEE doesn't distinguish +0 and -0 in comparisons. */
- /* a CMP (-0) -> a CMP 0 */
- if (TREE_CODE (arg1) == REAL_CST
- && REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (arg1)))
- return fold (build (code, type, arg0,
- build_real (TREE_TYPE (arg1), dconst0)));
+
+ if (TREE_CODE (arg1) == REAL_CST)
+ {
+ REAL_VALUE_TYPE cst;
+ cst = TREE_REAL_CST (arg1);
+
+ /* (-a) CMP CST -> a swap(CMP) (-CST) */
+ if (TREE_CODE (arg0) == NEGATE_EXPR)
+ return
+ fold (build (swap_tree_comparison (code), type,
+ TREE_OPERAND (arg0, 0),
+ build_real (TREE_TYPE (arg1),
+ REAL_VALUE_NEGATE (cst))));
+
+ /* IEEE doesn't distinguish +0 and -0 in comparisons. */
+ /* a CMP (-0) -> a CMP 0 */
+ if (REAL_VALUE_MINUS_ZERO (cst))
+ return fold (build (code, type, arg0,
+ build_real (TREE_TYPE (arg1), dconst0)));
+
+ /* x != NaN is always true, other ops are always false. */
+ if (REAL_VALUE_ISNAN (cst)
+ && ! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1))))
+ {
+ t = (code == NE_EXPR) ? integer_one_node : integer_zero_node;
+ return omit_one_operand (type, fold_convert (type, t), arg0);
+ }
+
+ /* Fold comparisons against infinity. */
+ if (REAL_VALUE_ISINF (cst))
+ {
+ tem = fold_inf_compare (code, type, arg0, arg1);
+ if (tem != NULL_TREE)
+ return tem;
+ }
+ }
/* If this is a comparison of a real constant with a PLUS_EXPR
or a MINUS_EXPR of a real constant, we can convert it into a
@@ -6011,152 +7195,97 @@ fold (expr)
arg1, TREE_OPERAND (arg0, 1), 0))
&& ! TREE_CONSTANT_OVERFLOW (tem))
return fold (build (code, type, TREE_OPERAND (arg0, 0), tem));
+
+ /* Likewise, we can simplify a comparison of a real constant with
+ a MINUS_EXPR whose first operand is also a real constant, i.e.
+ (c1 - x) < c2 becomes x > c1-c2. */
+ if (flag_unsafe_math_optimizations
+ && TREE_CODE (arg1) == REAL_CST
+ && TREE_CODE (arg0) == MINUS_EXPR
+ && TREE_CODE (TREE_OPERAND (arg0, 0)) == REAL_CST
+ && 0 != (tem = const_binop (MINUS_EXPR, TREE_OPERAND (arg0, 0),
+ arg1, 0))
+ && ! TREE_CONSTANT_OVERFLOW (tem))
+ return fold (build (swap_tree_comparison (code), type,
+ TREE_OPERAND (arg0, 1), tem));
+
+ /* Fold comparisons against built-in math functions. */
+ if (TREE_CODE (arg1) == REAL_CST
+ && flag_unsafe_math_optimizations
+ && ! flag_errno_math)
+ {
+ enum built_in_function fcode = builtin_mathfn_code (arg0);
+
+ if (fcode != END_BUILTINS)
+ {
+ tem = fold_mathfn_compare (fcode, code, type, arg0, arg1);
+ if (tem != NULL_TREE)
+ return tem;
+ }
+ }
}
- /* Convert foo++ == CONST into ++foo == CONST + INCR.
- First, see if one arg is constant; find the constant arg
- and the other one. */
- {
- tree constop = 0, varop = NULL_TREE;
- int constopnum = -1;
+ /* Convert foo++ == CONST into ++foo == CONST + INCR. */
+ if (TREE_CONSTANT (arg1)
+ && (TREE_CODE (arg0) == POSTINCREMENT_EXPR
+ || TREE_CODE (arg0) == POSTDECREMENT_EXPR)
+ /* This optimization is invalid for ordered comparisons
+ if CONST+INCR overflows or if foo+incr might overflow.
+ This optimization is invalid for floating point due to rounding.
+ For pointer types we assume overflow doesn't happen. */
+ && (POINTER_TYPE_P (TREE_TYPE (arg0))
+ || (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
+ && (code == EQ_EXPR || code == NE_EXPR))))
+ {
+ tree varop, newconst;
- if (TREE_CONSTANT (arg1))
- constopnum = 1, constop = arg1, varop = arg0;
- if (TREE_CONSTANT (arg0))
- constopnum = 0, constop = arg0, varop = arg1;
+ if (TREE_CODE (arg0) == POSTINCREMENT_EXPR)
+ {
+ newconst = fold (build (PLUS_EXPR, TREE_TYPE (arg0),
+ arg1, TREE_OPERAND (arg0, 1)));
+ varop = build (PREINCREMENT_EXPR, TREE_TYPE (arg0),
+ TREE_OPERAND (arg0, 0),
+ TREE_OPERAND (arg0, 1));
+ }
+ else
+ {
+ newconst = fold (build (MINUS_EXPR, TREE_TYPE (arg0),
+ arg1, TREE_OPERAND (arg0, 1)));
+ varop = build (PREDECREMENT_EXPR, TREE_TYPE (arg0),
+ TREE_OPERAND (arg0, 0),
+ TREE_OPERAND (arg0, 1));
+ }
- if (constop && TREE_CODE (varop) == POSTINCREMENT_EXPR)
- {
- /* This optimization is invalid for ordered comparisons
- if CONST+INCR overflows or if foo+incr might overflow.
- This optimization is invalid for floating point due to rounding.
- For pointer types we assume overflow doesn't happen. */
- if (POINTER_TYPE_P (TREE_TYPE (varop))
- || (! FLOAT_TYPE_P (TREE_TYPE (varop))
- && (code == EQ_EXPR || code == NE_EXPR)))
- {
- tree newconst
- = fold (build (PLUS_EXPR, TREE_TYPE (varop),
- constop, TREE_OPERAND (varop, 1)));
-
- /* Do not overwrite the current varop to be a preincrement,
- create a new node so that we won't confuse our caller who
- might create trees and throw them away, reusing the
- arguments that they passed to build. This shows up in
- the THEN or ELSE parts of ?: being postincrements. */
- varop = build (PREINCREMENT_EXPR, TREE_TYPE (varop),
- TREE_OPERAND (varop, 0),
- TREE_OPERAND (varop, 1));
-
- /* If VAROP is a reference to a bitfield, we must mask
- the constant by the width of the field. */
- if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
- && DECL_BIT_FIELD(TREE_OPERAND
- (TREE_OPERAND (varop, 0), 1)))
- {
- int size
- = TREE_INT_CST_LOW (DECL_SIZE
- (TREE_OPERAND
- (TREE_OPERAND (varop, 0), 1)));
- tree mask, unsigned_type;
- unsigned int precision;
- tree folded_compare;
-
- /* First check whether the comparison would come out
- always the same. If we don't do that we would
- change the meaning with the masking. */
- if (constopnum == 0)
- folded_compare = fold (build (code, type, constop,
- TREE_OPERAND (varop, 0)));
- else
- folded_compare = fold (build (code, type,
- TREE_OPERAND (varop, 0),
- constop));
- if (integer_zerop (folded_compare)
- || integer_onep (folded_compare))
- return omit_one_operand (type, folded_compare, varop);
-
- unsigned_type = (*lang_hooks.types.type_for_size)(size, 1);
- precision = TYPE_PRECISION (unsigned_type);
- mask = build_int_2 (~0, ~0);
- TREE_TYPE (mask) = unsigned_type;
- force_fit_type (mask, 0);
- mask = const_binop (RSHIFT_EXPR, mask,
- size_int (precision - size), 0);
- newconst = fold (build (BIT_AND_EXPR,
- TREE_TYPE (varop), newconst,
- convert (TREE_TYPE (varop),
- mask)));
- }
- t = build (code, type,
- (constopnum == 0) ? newconst : varop,
- (constopnum == 1) ? newconst : varop);
- return t;
- }
- }
- else if (constop && TREE_CODE (varop) == POSTDECREMENT_EXPR)
- {
- if (POINTER_TYPE_P (TREE_TYPE (varop))
- || (! FLOAT_TYPE_P (TREE_TYPE (varop))
- && (code == EQ_EXPR || code == NE_EXPR)))
- {
- tree newconst
- = fold (build (MINUS_EXPR, TREE_TYPE (varop),
- constop, TREE_OPERAND (varop, 1)));
-
- /* Do not overwrite the current varop to be a predecrement,
- create a new node so that we won't confuse our caller who
- might create trees and throw them away, reusing the
- arguments that they passed to build. This shows up in
- the THEN or ELSE parts of ?: being postdecrements. */
- varop = build (PREDECREMENT_EXPR, TREE_TYPE (varop),
- TREE_OPERAND (varop, 0),
- TREE_OPERAND (varop, 1));
-
- if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
- && DECL_BIT_FIELD(TREE_OPERAND
- (TREE_OPERAND (varop, 0), 1)))
- {
- int size
- = TREE_INT_CST_LOW (DECL_SIZE
- (TREE_OPERAND
- (TREE_OPERAND (varop, 0), 1)));
- tree mask, unsigned_type;
- unsigned int precision;
- tree folded_compare;
-
- if (constopnum == 0)
- folded_compare = fold (build (code, type, constop,
- TREE_OPERAND (varop, 0)));
- else
- folded_compare = fold (build (code, type,
- TREE_OPERAND (varop, 0),
- constop));
- if (integer_zerop (folded_compare)
- || integer_onep (folded_compare))
- return omit_one_operand (type, folded_compare, varop);
-
- unsigned_type = (*lang_hooks.types.type_for_size)(size, 1);
- precision = TYPE_PRECISION (unsigned_type);
- mask = build_int_2 (~0, ~0);
- TREE_TYPE (mask) = TREE_TYPE (varop);
- force_fit_type (mask, 0);
- mask = const_binop (RSHIFT_EXPR, mask,
- size_int (precision - size), 0);
- newconst = fold (build (BIT_AND_EXPR,
- TREE_TYPE (varop), newconst,
- convert (TREE_TYPE (varop),
- mask)));
- }
+ /* If VAROP is a reference to a bitfield, we must mask
+ the constant by the width of the field. */
+ if (TREE_CODE (TREE_OPERAND (varop, 0)) == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (TREE_OPERAND (varop, 0), 1)))
+ {
+ tree fielddecl = TREE_OPERAND (TREE_OPERAND (varop, 0), 1);
+ int size = TREE_INT_CST_LOW (DECL_SIZE (fielddecl));
+ tree folded_compare, shift;
+
+ /* First check whether the comparison would come out
+ always the same. If we don't do that we would
+ change the meaning with the masking. */
+ folded_compare = fold (build (code, type,
+ TREE_OPERAND (varop, 0),
+ arg1));
+ if (integer_zerop (folded_compare)
+ || integer_onep (folded_compare))
+ return omit_one_operand (type, folded_compare, varop);
+
+ shift = build_int_2 (TYPE_PRECISION (TREE_TYPE (varop)) - size,
+ 0);
+ newconst = fold (build (LSHIFT_EXPR, TREE_TYPE (varop),
+ newconst, shift));
+ newconst = fold (build (RSHIFT_EXPR, TREE_TYPE (varop),
+ newconst, shift));
+ }
- t = build (code, type,
- (constopnum == 0) ? newconst : varop,
- (constopnum == 1) ? newconst : varop);
- return t;
- }
- }
- }
+ return fold (build (code, type, varop, newconst));
+ }
/* Change X >= C to X > (C - 1) and X < C to X <= (C - 1) if C > 0.
This transformation affects the cases which are handled in later
@@ -6168,16 +7297,12 @@ fold (expr)
switch (code)
{
case GE_EXPR:
- code = GT_EXPR;
arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
- t = build (code, type, TREE_OPERAND (t, 0), arg1);
- break;
+ return fold (build (GT_EXPR, type, arg0, arg1));
case LT_EXPR:
- code = LE_EXPR;
arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
- t = build (code, type, TREE_OPERAND (t, 0), arg1);
- break;
+ return fold (build (LE_EXPR, type, arg0, arg1));
default:
break;
@@ -6217,23 +7342,22 @@ fold (expr)
{
case GT_EXPR:
return omit_one_operand (type,
- convert (type, integer_zero_node),
+ fold_convert (type,
+ integer_zero_node),
arg0);
case GE_EXPR:
- code = EQ_EXPR;
- TREE_SET_CODE (t, EQ_EXPR);
- break;
+ return fold (build (EQ_EXPR, type, arg0, arg1));
+
case LE_EXPR:
return omit_one_operand (type,
- convert (type, integer_one_node),
+ fold_convert (type,
+ integer_one_node),
arg0);
case LT_EXPR:
- code = NE_EXPR;
- TREE_SET_CODE (t, NE_EXPR);
- break;
+ return fold (build (NE_EXPR, type, arg0, arg1));
/* The GE_EXPR and LT_EXPR cases above are not normally
- reached because of previous transformations. */
+ reached because of previous transformations. */
default:
break;
@@ -6243,15 +7367,11 @@ fold (expr)
switch (code)
{
case GT_EXPR:
- code = EQ_EXPR;
arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
- t = build (code, type, TREE_OPERAND (t, 0), arg1);
- break;
+ return fold (build (EQ_EXPR, type, arg0, arg1));
case LE_EXPR:
- code = NE_EXPR;
arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
- t = build (code, type, TREE_OPERAND (t, 0), arg1);
- break;
+ return fold (build (NE_EXPR, type, arg0, arg1));
default:
break;
}
@@ -6261,21 +7381,19 @@ fold (expr)
{
case LT_EXPR:
return omit_one_operand (type,
- convert (type, integer_zero_node),
+ fold_convert (type,
+ integer_zero_node),
arg0);
case LE_EXPR:
- code = EQ_EXPR;
- TREE_SET_CODE (t, EQ_EXPR);
- break;
+ return fold (build (EQ_EXPR, type, arg0, arg1));
case GE_EXPR:
return omit_one_operand (type,
- convert (type, integer_one_node),
+ fold_convert (type,
+ integer_one_node),
arg0);
case GT_EXPR:
- code = NE_EXPR;
- TREE_SET_CODE (t, NE_EXPR);
- break;
+ return fold (build (NE_EXPR, type, arg0, arg1));
default:
break;
@@ -6285,15 +7403,11 @@ fold (expr)
switch (code)
{
case GE_EXPR:
- code = NE_EXPR;
arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
- t = build (code, type, TREE_OPERAND (t, 0), arg1);
- break;
+ return fold (build (NE_EXPR, type, arg0, arg1));
case LT_EXPR:
- code = EQ_EXPR;
arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
- t = build (code, type, TREE_OPERAND (t, 0), arg1);
- break;
+ return fold (build (EQ_EXPR, type, arg0, arg1));
default:
break;
}
@@ -6313,8 +7427,8 @@ fold (expr)
st1 = (*lang_hooks.types.signed_type) (TREE_TYPE (arg1));
return fold
(build (code == LE_EXPR ? GE_EXPR: LT_EXPR,
- type, convert (st0, arg0),
- convert (st1, integer_zero_node)));
+ type, fold_convert (st0, arg0),
+ fold_convert (st1, integer_zero_node)));
}
}
}
@@ -6356,11 +7470,15 @@ fold (expr)
else if (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
&& TREE_CODE (arg0) == NOP_EXPR
&& (tem = get_unwidened (arg0, NULL_TREE)) != arg0
+ && (code == EQ_EXPR || code == NE_EXPR
+ || TREE_UNSIGNED (TREE_TYPE (arg0))
+ == TREE_UNSIGNED (TREE_TYPE (tem)))
&& (t1 = get_unwidened (arg1, TREE_TYPE (tem))) != 0
&& (TREE_TYPE (t1) == TREE_TYPE (tem)
|| (TREE_CODE (t1) == INTEGER_CST
&& int_fits_type_p (t1, TREE_TYPE (tem)))))
- return fold (build (code, type, tem, convert (TREE_TYPE (tem), t1)));
+ return fold (build (code, type, tem,
+ fold_convert (TREE_TYPE (tem), t1)));
/* If this is comparing a constant with a MIN_EXPR or a MAX_EXPR of a
constant, we can simplify it. */
@@ -6403,8 +7521,8 @@ fold (expr)
TREE_TYPE (TREE_OPERAND (arg0, 0)),
TREE_OPERAND (arg0, 1),
TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)),
- convert (TREE_TYPE (arg0),
- integer_one_node)),
+ fold_convert (TREE_TYPE (arg0),
+ integer_one_node)),
arg1));
else if (TREE_CODE (TREE_OPERAND (arg0, 1)) == LSHIFT_EXPR
&& integer_onep (TREE_OPERAND (TREE_OPERAND (arg0, 1), 0)))
@@ -6415,8 +7533,8 @@ fold (expr)
TREE_TYPE (TREE_OPERAND (arg0, 1)),
TREE_OPERAND (arg0, 0),
TREE_OPERAND (TREE_OPERAND (arg0, 1), 1)),
- convert (TREE_TYPE (arg0),
- integer_one_node)),
+ fold_convert (TREE_TYPE (arg0),
+ integer_one_node)),
arg1));
}
@@ -6434,10 +7552,12 @@ fold (expr)
{
tree newtype = (*lang_hooks.types.unsigned_type) (TREE_TYPE (arg0));
tree newmod = build (TREE_CODE (arg0), newtype,
- convert (newtype, TREE_OPERAND (arg0, 0)),
- convert (newtype, TREE_OPERAND (arg0, 1)));
+ fold_convert (newtype,
+ TREE_OPERAND (arg0, 0)),
+ fold_convert (newtype,
+ TREE_OPERAND (arg0, 1)));
- return build (code, type, newmod, convert (newtype, arg1));
+ return build (code, type, newmod, fold_convert (newtype, arg1));
}
/* If this is an NE comparison of zero with an AND of one, remove the
@@ -6445,7 +7565,7 @@ fold (expr)
if (code == NE_EXPR && integer_zerop (arg1)
&& TREE_CODE (arg0) == BIT_AND_EXPR
&& integer_onep (TREE_OPERAND (arg0, 1)))
- return convert (type, arg0);
+ return fold_convert (type, arg0);
/* If we have (A & C) == C where C is a power of 2, convert this into
(A & C) != 0. Similarly for NE_EXPR. */
@@ -6456,21 +7576,43 @@ fold (expr)
return fold (build (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
arg0, integer_zero_node));
- /* If we have (A & C) != 0 where C is the sign bit of A, convert
- this into A < 0. Similarly for (A & C) == 0 into A >= 0. */
+ /* If we have (A & C) != 0 or (A & C) == 0 and C is a power of
+ 2, then fold the expression into shifts and logical operations. */
+ tem = fold_single_bit_test (code, arg0, arg1, type);
+ if (tem)
+ return tem;
+
+ /* If we have (A & C) == D where D & ~C != 0, convert this into 0.
+ Similarly for NE_EXPR. */
if ((code == EQ_EXPR || code == NE_EXPR)
&& TREE_CODE (arg0) == BIT_AND_EXPR
- && integer_zerop (arg1))
+ && TREE_CODE (arg1) == INTEGER_CST
+ && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
{
- tree arg00 = sign_bit_p (TREE_OPERAND (arg0, 0),
- TREE_OPERAND (arg0, 1));
- if (arg00 != NULL_TREE)
- {
- tree stype = (*lang_hooks.types.signed_type) (TREE_TYPE (arg00));
- return fold (build (code == EQ_EXPR ? GE_EXPR : LT_EXPR, type,
- convert (stype, arg00),
- convert (stype, integer_zero_node)));
- }
+ tree dandnotc
+ = fold (build (BIT_AND_EXPR, TREE_TYPE (arg0),
+ arg1, build1 (BIT_NOT_EXPR,
+ TREE_TYPE (TREE_OPERAND (arg0, 1)),
+ TREE_OPERAND (arg0, 1))));
+ tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
+ if (integer_nonzerop (dandnotc))
+ return omit_one_operand (type, rslt, arg0);
+ }
+
+ /* If we have (A | C) == D where C & ~D != 0, convert this into 0.
+ Similarly for NE_EXPR. */
+ if ((code == EQ_EXPR || code == NE_EXPR)
+ && TREE_CODE (arg0) == BIT_IOR_EXPR
+ && TREE_CODE (arg1) == INTEGER_CST
+ && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST)
+ {
+ tree candnotd
+ = fold (build (BIT_AND_EXPR, TREE_TYPE (arg0),
+ TREE_OPERAND (arg0, 1),
+ build1 (BIT_NOT_EXPR, TREE_TYPE (arg1), arg1)));
+ tree rslt = code == EQ_EXPR ? integer_zero_node : integer_one_node;
+ if (integer_nonzerop (candnotd))
+ return omit_one_operand (type, rslt, arg0);
}
/* If X is unsigned, convert X < (1 << Y) into X >> Y == 0
@@ -6482,7 +7624,7 @@ fold (expr)
return build (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
build (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
TREE_OPERAND (arg1, 1)),
- convert (TREE_TYPE (arg0), integer_zero_node));
+ fold_convert (TREE_TYPE (arg0), integer_zero_node));
else if ((code == LT_EXPR || code == GE_EXPR)
&& TREE_UNSIGNED (TREE_TYPE (arg0))
@@ -6492,10 +7634,11 @@ fold (expr)
&& integer_onep (TREE_OPERAND (TREE_OPERAND (arg1, 0), 0)))
return
build (code == LT_EXPR ? EQ_EXPR : NE_EXPR, type,
- convert (TREE_TYPE (arg0),
- build (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
- TREE_OPERAND (TREE_OPERAND (arg1, 0), 1))),
- convert (TREE_TYPE (arg0), integer_zero_node));
+ fold_convert (TREE_TYPE (arg0),
+ build (RSHIFT_EXPR, TREE_TYPE (arg0), arg0,
+ TREE_OPERAND (TREE_OPERAND (arg1, 0),
+ 1))),
+ fold_convert (TREE_TYPE (arg0), integer_zero_node));
/* Simplify comparison of something with itself. (For IEEE
floating-point, we can only do some of these simplifications.) */
@@ -6504,17 +7647,23 @@ fold (expr)
switch (code)
{
case EQ_EXPR:
+ if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
+ || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
+ return constant_boolean_node (1, type);
+ break;
+
case GE_EXPR:
case LE_EXPR:
- if (! FLOAT_TYPE_P (TREE_TYPE (arg0)))
+ if (! FLOAT_TYPE_P (TREE_TYPE (arg0))
+ || ! HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
return constant_boolean_node (1, type);
- code = EQ_EXPR;
- TREE_SET_CODE (t, code);
- break;
+ return fold (build (EQ_EXPR, type, arg0, arg1));
case NE_EXPR:
- /* For NE, we can only do this simplification if integer. */
- if (FLOAT_TYPE_P (TREE_TYPE (arg0)))
+ /* For NE, we can only do this simplification if integer
+ or we don't honor IEEE floating point NaNs. */
+ if (FLOAT_TYPE_P (TREE_TYPE (arg0))
+ && HONOR_NANS (TYPE_MODE (TREE_TYPE (arg0))))
break;
/* ... fall through ... */
case GT_EXPR:
@@ -6636,7 +7785,8 @@ fold (expr)
&& (optimize || TREE_CODE (arg1) == INTEGER_CST))
{
t1 = optimize_bit_field_compare (code, type, arg0, arg1);
- return t1 ? t1 : t;
+ if (t1)
+ return t1;
}
/* If this is a comparison of complex values and either or both sides
@@ -6669,19 +7819,18 @@ fold (expr)
/* Optimize comparisons of strlen vs zero to a compare of the
first character of the string vs zero. To wit,
- strlen(ptr) == 0 => *ptr == 0
+ strlen(ptr) == 0 => *ptr == 0
strlen(ptr) != 0 => *ptr != 0
Other cases should reduce to one of these two (or a constant)
due to the return value of strlen being unsigned. */
if ((code == EQ_EXPR || code == NE_EXPR)
&& integer_zerop (arg1)
- && TREE_CODE (arg0) == CALL_EXPR
- && TREE_CODE (TREE_OPERAND (arg0, 0)) == ADDR_EXPR)
+ && TREE_CODE (arg0) == CALL_EXPR)
{
- tree fndecl = TREE_OPERAND (TREE_OPERAND (arg0, 0), 0);
+ tree fndecl = get_callee_fndecl (arg0);
tree arglist;
- if (TREE_CODE (fndecl) == FUNCTION_DECL
+ if (fndecl
&& DECL_BUILT_IN (fndecl)
&& DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_MD
&& DECL_FUNCTION_CODE (fndecl) == BUILT_IN_STRLEN
@@ -6785,38 +7934,18 @@ fold (expr)
/* Pedantic ANSI C says that a conditional expression is never an lvalue,
so all simple results must be passed through pedantic_non_lvalue. */
if (TREE_CODE (arg0) == INTEGER_CST)
- return pedantic_non_lvalue
- (TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1)));
- else if (operand_equal_p (arg1, TREE_OPERAND (expr, 2), 0))
- return pedantic_omit_one_operand (type, arg1, arg0);
-
- /* If the second operand is zero, invert the comparison and swap
- the second and third operands. Likewise if the second operand
- is constant and the third is not or if the third operand is
- equivalent to the first operand of the comparison. */
-
- if (integer_zerop (arg1)
- || (TREE_CONSTANT (arg1) && ! TREE_CONSTANT (TREE_OPERAND (t, 2)))
- || (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<'
- && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0),
- TREE_OPERAND (t, 2),
- TREE_OPERAND (arg0, 1))))
{
- /* See if this can be inverted. If it can't, possibly because
- it was a floating-point inequality comparison, don't do
- anything. */
- tem = invert_truthvalue (arg0);
-
- if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
- {
- t = build (code, type, tem,
- TREE_OPERAND (t, 2), TREE_OPERAND (t, 1));
- arg0 = tem;
- /* arg1 should be the first argument of the new T. */
- arg1 = TREE_OPERAND (t, 1);
- STRIP_NOPS (arg1);
- }
+ tem = TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1));
+ /* Only optimize constant conditions when the selected branch
+ has the same type as the COND_EXPR. This avoids optimizing
+ away "c ? x : throw", where the throw has a void type. */
+ if (! VOID_TYPE_P (TREE_TYPE (tem))
+ || VOID_TYPE_P (TREE_TYPE (t)))
+ return pedantic_non_lvalue (tem);
+ return t;
}
+ if (operand_equal_p (arg1, TREE_OPERAND (expr, 2), 0))
+ return pedantic_omit_one_operand (type, arg1, arg0);
/* If we have A op B ? A : C, we may be able to convert this to a
simpler expression, depending on the operation and the values
@@ -6860,32 +7989,26 @@ fold (expr)
switch (comp_code)
{
case EQ_EXPR:
- return
- pedantic_non_lvalue
- (convert (type,
- negate_expr
- (convert (TREE_TYPE (TREE_OPERAND (t, 1)),
- arg1))));
+ tem = fold_convert (TREE_TYPE (TREE_OPERAND (t, 1)), arg1);
+ tem = fold_convert (type, negate_expr (tem));
+ return pedantic_non_lvalue (tem);
case NE_EXPR:
- return pedantic_non_lvalue (convert (type, arg1));
+ return pedantic_non_lvalue (fold_convert (type, arg1));
case GE_EXPR:
case GT_EXPR:
if (TREE_UNSIGNED (TREE_TYPE (arg1)))
- arg1 = convert ((*lang_hooks.types.signed_type)
- (TREE_TYPE (arg1)), arg1);
- return pedantic_non_lvalue
- (convert (type, fold (build1 (ABS_EXPR,
- TREE_TYPE (arg1), arg1))));
+ arg1 = fold_convert ((*lang_hooks.types.signed_type)
+ (TREE_TYPE (arg1)), arg1);
+ arg1 = fold (build1 (ABS_EXPR, TREE_TYPE (arg1), arg1));
+ return pedantic_non_lvalue (fold_convert (type, arg1));
case LE_EXPR:
case LT_EXPR:
if (TREE_UNSIGNED (TREE_TYPE (arg1)))
- arg1 = convert ((lang_hooks.types.signed_type)
- (TREE_TYPE (arg1)), arg1);
- return pedantic_non_lvalue
- (negate_expr (convert (type,
- fold (build1 (ABS_EXPR,
- TREE_TYPE (arg1),
- arg1)))));
+ arg1 = fold_convert ((lang_hooks.types.signed_type)
+ (TREE_TYPE (arg1)), arg1);
+ arg1 = fold (build1 (ABS_EXPR, TREE_TYPE (arg1), arg1));
+ arg1 = negate_expr (fold_convert (type, arg1));
+ return pedantic_non_lvalue (arg1);
default:
abort ();
}
@@ -6898,9 +8021,9 @@ fold (expr)
if (integer_zerop (TREE_OPERAND (arg0, 1)) && integer_zerop (arg2))
{
if (comp_code == NE_EXPR)
- return pedantic_non_lvalue (convert (type, arg1));
+ return pedantic_non_lvalue (fold_convert (type, arg1));
else if (comp_code == EQ_EXPR)
- return pedantic_non_lvalue (convert (type, integer_zero_node));
+ return pedantic_non_lvalue (fold_convert (type, integer_zero_node));
}
/* Try some transformations of A op B ? A : B.
@@ -6938,14 +8061,18 @@ fold (expr)
/* Avoid adding NOP_EXPRs in case this is an lvalue. */
if (TYPE_MAIN_VARIANT (comp_type) == TYPE_MAIN_VARIANT (type))
- comp_type = type;
+ {
+ comp_type = type;
+ comp_op0 = arg1;
+ comp_op1 = arg2;
+ }
switch (comp_code)
{
case EQ_EXPR:
- return pedantic_non_lvalue (convert (type, arg2));
+ return pedantic_non_lvalue (fold_convert (type, arg2));
case NE_EXPR:
- return pedantic_non_lvalue (convert (type, arg1));
+ return pedantic_non_lvalue (fold_convert (type, arg1));
case LE_EXPR:
case LT_EXPR:
/* In C++ a ?: expression can be an lvalue, so put the
@@ -6953,22 +8080,22 @@ fold (expr)
so that we can convert this back to the
corresponding COND_EXPR. */
if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
- return pedantic_non_lvalue
- (convert (type, fold (build (MIN_EXPR, comp_type,
- (comp_code == LE_EXPR
- ? comp_op0 : comp_op1),
- (comp_code == LE_EXPR
- ? comp_op1 : comp_op0)))));
+ return pedantic_non_lvalue (fold_convert
+ (type, fold (build (MIN_EXPR, comp_type,
+ (comp_code == LE_EXPR
+ ? comp_op0 : comp_op1),
+ (comp_code == LE_EXPR
+ ? comp_op1 : comp_op0)))));
break;
case GE_EXPR:
case GT_EXPR:
if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (arg1))))
- return pedantic_non_lvalue
- (convert (type, fold (build (MAX_EXPR, comp_type,
- (comp_code == GE_EXPR
- ? comp_op0 : comp_op1),
- (comp_code == GE_EXPR
- ? comp_op1 : comp_op0)))));
+ return pedantic_non_lvalue (fold_convert
+ (type, fold (build (MAX_EXPR, comp_type,
+ (comp_code == GE_EXPR
+ ? comp_op0 : comp_op1),
+ (comp_code == GE_EXPR
+ ? comp_op1 : comp_op0)))));
break;
default:
abort ();
@@ -6988,10 +8115,9 @@ fold (expr)
{
case EQ_EXPR:
/* We can replace A with C1 in this case. */
- arg1 = convert (type, TREE_OPERAND (arg0, 1));
- t = build (code, type, TREE_OPERAND (t, 0), arg1,
- TREE_OPERAND (t, 2));
- break;
+ arg1 = fold_convert (type, TREE_OPERAND (arg0, 1));
+ return fold (build (code, type, TREE_OPERAND (t, 0), arg1,
+ TREE_OPERAND (t, 2)));
case LT_EXPR:
/* If C1 is C2 + 1, this is min(A, C2). */
@@ -7041,11 +8167,8 @@ fold (expr)
/* If the second operand is simpler than the third, swap them
since that produces better jump optimization results. */
- if ((TREE_CONSTANT (arg1) || DECL_P (arg1)
- || TREE_CODE (arg1) == SAVE_EXPR)
- && ! (TREE_CONSTANT (TREE_OPERAND (t, 2))
- || DECL_P (TREE_OPERAND (t, 2))
- || TREE_CODE (TREE_OPERAND (t, 2)) == SAVE_EXPR))
+ if (tree_swap_operands_p (TREE_OPERAND (t, 1),
+ TREE_OPERAND (t, 2), false))
{
/* See if this can be inverted. If it can't, possibly because
it was a floating-point inequality comparison, don't do
@@ -7053,14 +8176,8 @@ fold (expr)
tem = invert_truthvalue (arg0);
if (TREE_CODE (tem) != TRUTH_NOT_EXPR)
- {
- t = build (code, type, tem,
- TREE_OPERAND (t, 2), TREE_OPERAND (t, 1));
- arg0 = tem;
- /* arg1 should be the first argument of the new T. */
- arg1 = TREE_OPERAND (t, 1);
- STRIP_NOPS (arg1);
- }
+ return fold (build (code, type, tem,
+ TREE_OPERAND (t, 2), TREE_OPERAND (t, 1)));
}
/* Convert A ? 1 : 0 to simply A. */
@@ -7078,8 +8195,8 @@ fold (expr)
if (integer_zerop (TREE_OPERAND (t, 1))
&& integer_onep (TREE_OPERAND (t, 2))
&& truth_value_p (TREE_CODE (arg0)))
- return pedantic_non_lvalue (convert (type,
- invert_truthvalue (arg0)));
+ return pedantic_non_lvalue (fold_convert (type,
+ invert_truthvalue (arg0)));
/* Look for expressions of the form A & 2 ? 2 : 0. The result of this
operation is simply A & 2. */
@@ -7091,7 +8208,8 @@ fold (expr)
&& TREE_CODE (TREE_OPERAND (arg0, 0)) == BIT_AND_EXPR
&& operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg0, 0), 1),
arg1, 1))
- return pedantic_non_lvalue (convert (type, TREE_OPERAND (arg0, 0)));
+ return pedantic_non_lvalue (fold_convert (type,
+ TREE_OPERAND (arg0, 0)));
/* Convert A ? B : 0 into A && B if A and B are truth values. */
if (integer_zerop (TREE_OPERAND (t, 2))
@@ -7122,7 +8240,7 @@ fold (expr)
/* Don't let (0, 0) be null pointer constant. */
if (integer_zerop (arg1))
return build1 (NOP_EXPR, type, arg1);
- return convert (type, arg1);
+ return fold_convert (type, arg1);
case COMPLEX_EXPR:
if (wins)
@@ -7147,7 +8265,7 @@ fold (expr)
case IMAGPART_EXPR:
if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
- return convert (type, integer_zero_node);
+ return fold_convert (type, integer_zero_node);
else if (TREE_CODE (arg0) == COMPLEX_EXPR)
return omit_one_operand (type, TREE_OPERAND (arg0, 1),
TREE_OPERAND (arg0, 0));
@@ -7220,6 +8338,224 @@ fold (expr)
} /* switch (code) */
}
+#ifdef ENABLE_FOLD_CHECKING
+#undef fold
+
+static void fold_checksum_tree (tree, struct md5_ctx *, htab_t);
+static void fold_check_failed (tree, tree);
+void print_fold_checksum (tree);
+
+/* When --enable-checking=fold, compute a digest of expr before
+ and after actual fold call to see if fold did not accidentally
+ change original expr. */
+
+tree
+fold (tree expr)
+{
+ tree ret;
+ struct md5_ctx ctx;
+ unsigned char checksum_before[16], checksum_after[16];
+ htab_t ht;
+
+ ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
+ md5_init_ctx (&ctx);
+ fold_checksum_tree (expr, &ctx, ht);
+ md5_finish_ctx (&ctx, checksum_before);
+ htab_empty (ht);
+
+ ret = fold_1 (expr);
+
+ md5_init_ctx (&ctx);
+ fold_checksum_tree (expr, &ctx, ht);
+ md5_finish_ctx (&ctx, checksum_after);
+ htab_delete (ht);
+
+ if (memcmp (checksum_before, checksum_after, 16))
+ fold_check_failed (expr, ret);
+
+ return ret;
+}
+
+void
+print_fold_checksum (tree expr)
+{
+ struct md5_ctx ctx;
+ unsigned char checksum[16], cnt;
+ htab_t ht;
+
+ ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
+ md5_init_ctx (&ctx);
+ fold_checksum_tree (expr, &ctx, ht);
+ md5_finish_ctx (&ctx, checksum);
+ htab_delete (ht);
+ for (cnt = 0; cnt < 16; ++cnt)
+ fprintf (stderr, "%02x", checksum[cnt]);
+ putc ('\n', stderr);
+}
+
+static void
+fold_check_failed (tree expr ATTRIBUTE_UNUSED, tree ret ATTRIBUTE_UNUSED)
+{
+ internal_error ("fold check: original tree changed by fold");
+}
+
+static void
+fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht)
+{
+ void **slot;
+ enum tree_code code;
+ char buf[sizeof (struct tree_decl)];
+ int i, len;
+
+ if (sizeof (struct tree_exp) + 5 * sizeof (tree)
+ > sizeof (struct tree_decl)
+ || sizeof (struct tree_type) > sizeof (struct tree_decl))
+ abort ();
+ if (expr == NULL)
+ return;
+ slot = htab_find_slot (ht, expr, INSERT);
+ if (*slot != NULL)
+ return;
+ *slot = expr;
+ code = TREE_CODE (expr);
+ if (code == SAVE_EXPR && SAVE_EXPR_NOPLACEHOLDER (expr))
+ {
+ /* Allow SAVE_EXPR_NOPLACEHOLDER flag to be modified. */
+ memcpy (buf, expr, tree_size (expr));
+ expr = (tree) buf;
+ SAVE_EXPR_NOPLACEHOLDER (expr) = 0;
+ }
+ else if (TREE_CODE_CLASS (code) == 'd' && DECL_ASSEMBLER_NAME_SET_P (expr))
+ {
+ /* Allow DECL_ASSEMBLER_NAME to be modified. */
+ memcpy (buf, expr, tree_size (expr));
+ expr = (tree) buf;
+ SET_DECL_ASSEMBLER_NAME (expr, NULL);
+ }
+ else if (TREE_CODE_CLASS (code) == 't'
+ && (TYPE_POINTER_TO (expr) || TYPE_REFERENCE_TO (expr)))
+ {
+ /* Allow TYPE_POINTER_TO and TYPE_REFERENCE_TO to be modified. */
+ memcpy (buf, expr, tree_size (expr));
+ expr = (tree) buf;
+ TYPE_POINTER_TO (expr) = NULL;
+ TYPE_REFERENCE_TO (expr) = NULL;
+ }
+ md5_process_bytes (expr, tree_size (expr), ctx);
+ fold_checksum_tree (TREE_TYPE (expr), ctx, ht);
+ if (TREE_CODE_CLASS (code) != 't' && TREE_CODE_CLASS (code) != 'd')
+ fold_checksum_tree (TREE_CHAIN (expr), ctx, ht);
+ len = TREE_CODE_LENGTH (code);
+ switch (TREE_CODE_CLASS (code))
+ {
+ case 'c':
+ switch (code)
+ {
+ case STRING_CST:
+ md5_process_bytes (TREE_STRING_POINTER (expr),
+ TREE_STRING_LENGTH (expr), ctx);
+ break;
+ case COMPLEX_CST:
+ fold_checksum_tree (TREE_REALPART (expr), ctx, ht);
+ fold_checksum_tree (TREE_IMAGPART (expr), ctx, ht);
+ break;
+ case VECTOR_CST:
+ fold_checksum_tree (TREE_VECTOR_CST_ELTS (expr), ctx, ht);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 'x':
+ switch (code)
+ {
+ case TREE_LIST:
+ fold_checksum_tree (TREE_PURPOSE (expr), ctx, ht);
+ fold_checksum_tree (TREE_VALUE (expr), ctx, ht);
+ break;
+ case TREE_VEC:
+ for (i = 0; i < TREE_VEC_LENGTH (expr); ++i)
+ fold_checksum_tree (TREE_VEC_ELT (expr, i), ctx, ht);
+ break;
+ default:
+ break;
+ }
+ break;
+ case 'e':
+ switch (code)
+ {
+ case SAVE_EXPR: len = 2; break;
+ case GOTO_SUBROUTINE_EXPR: len = 0; break;
+ case RTL_EXPR: len = 0; break;
+ case WITH_CLEANUP_EXPR: len = 2; break;
+ default: break;
+ }
+ /* Fall through. */
+ case 'r':
+ case '<':
+ case '1':
+ case '2':
+ case 's':
+ for (i = 0; i < len; ++i)
+ fold_checksum_tree (TREE_OPERAND (expr, i), ctx, ht);
+ break;
+ case 'd':
+ fold_checksum_tree (DECL_SIZE (expr), ctx, ht);
+ fold_checksum_tree (DECL_SIZE_UNIT (expr), ctx, ht);
+ fold_checksum_tree (DECL_NAME (expr), ctx, ht);
+ fold_checksum_tree (DECL_CONTEXT (expr), ctx, ht);
+ fold_checksum_tree (DECL_ARGUMENTS (expr), ctx, ht);
+ fold_checksum_tree (DECL_RESULT_FLD (expr), ctx, ht);
+ fold_checksum_tree (DECL_INITIAL (expr), ctx, ht);
+ fold_checksum_tree (DECL_ABSTRACT_ORIGIN (expr), ctx, ht);
+ fold_checksum_tree (DECL_SECTION_NAME (expr), ctx, ht);
+ fold_checksum_tree (DECL_ATTRIBUTES (expr), ctx, ht);
+ fold_checksum_tree (DECL_VINDEX (expr), ctx, ht);
+ break;
+ case 't':
+ fold_checksum_tree (TYPE_VALUES (expr), ctx, ht);
+ fold_checksum_tree (TYPE_SIZE (expr), ctx, ht);
+ fold_checksum_tree (TYPE_SIZE_UNIT (expr), ctx, ht);
+ fold_checksum_tree (TYPE_ATTRIBUTES (expr), ctx, ht);
+ fold_checksum_tree (TYPE_NAME (expr), ctx, ht);
+ fold_checksum_tree (TYPE_MIN_VALUE (expr), ctx, ht);
+ fold_checksum_tree (TYPE_MAX_VALUE (expr), ctx, ht);
+ fold_checksum_tree (TYPE_MAIN_VARIANT (expr), ctx, ht);
+ fold_checksum_tree (TYPE_BINFO (expr), ctx, ht);
+ fold_checksum_tree (TYPE_CONTEXT (expr), ctx, ht);
+ break;
+ default:
+ break;
+ }
+}
+
+#endif
+
+/* Perform constant folding and related simplification of initializer
+ expression EXPR. This behaves identically to "fold" but ignores
+ potential run-time traps and exceptions that fold must preserve. */
+
+tree
+fold_initializer (tree expr)
+{
+ int saved_signaling_nans = flag_signaling_nans;
+ int saved_trapping_math = flag_trapping_math;
+ int saved_trapv = flag_trapv;
+ tree result;
+
+ flag_signaling_nans = 0;
+ flag_trapping_math = 0;
+ flag_trapv = 0;
+
+ result = fold (expr);
+
+ flag_signaling_nans = saved_signaling_nans;
+ flag_trapping_math = saved_trapping_math;
+ flag_trapv = saved_trapv;
+
+ return result;
+}
+
/* Determine if first argument is a multiple of second argument. Return 0 if
it is not, or we cannot easily determined it to be.
@@ -7261,10 +8597,7 @@ fold (expr)
transformed version). */
static int
-multiple_of_p (type, top, bottom)
- tree type;
- tree top;
- tree bottom;
+multiple_of_p (tree type, tree top, tree bottom)
{
if (operand_equal_p (top, bottom, 0))
return 1;
@@ -7294,9 +8627,10 @@ multiple_of_p (type, top, bottom)
if (TYPE_PRECISION (TREE_TYPE (size_one_node))
> TREE_INT_CST_LOW (op1)
&& TREE_INT_CST_HIGH (op1) == 0
- && 0 != (t1 = convert (type,
- const_binop (LSHIFT_EXPR, size_one_node,
- op1, 0)))
+ && 0 != (t1 = fold_convert (type,
+ const_binop (LSHIFT_EXPR,
+ size_one_node,
+ op1, 0)))
&& ! TREE_OVERFLOW (t1))
return multiple_of_p (type, t1, bottom);
}
@@ -7331,27 +8665,111 @@ multiple_of_p (type, top, bottom)
/* Return true if `t' is known to be non-negative. */
int
-tree_expr_nonnegative_p (t)
- tree t;
+tree_expr_nonnegative_p (tree t)
{
switch (TREE_CODE (t))
{
case ABS_EXPR:
- case FFS_EXPR:
return 1;
+
case INTEGER_CST:
return tree_int_cst_sgn (t) >= 0;
+
+ case REAL_CST:
+ return ! REAL_VALUE_NEGATIVE (TREE_REAL_CST (t));
+
+ case PLUS_EXPR:
+ if (FLOAT_TYPE_P (TREE_TYPE (t)))
+ return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
+ && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+
+ /* zero_extend(x) + zero_extend(y) is non-negative if x and y are
+ both unsigned and at least 2 bits shorter than the result. */
+ if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
+ && TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
+ && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR)
+ {
+ tree inner1 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
+ tree inner2 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0));
+ if (TREE_CODE (inner1) == INTEGER_TYPE && TREE_UNSIGNED (inner1)
+ && TREE_CODE (inner2) == INTEGER_TYPE && TREE_UNSIGNED (inner2))
+ {
+ unsigned int prec = MAX (TYPE_PRECISION (inner1),
+ TYPE_PRECISION (inner2)) + 1;
+ return prec < TYPE_PRECISION (TREE_TYPE (t));
+ }
+ }
+ break;
+
+ case MULT_EXPR:
+ if (FLOAT_TYPE_P (TREE_TYPE (t)))
+ {
+ /* x * x for floating point x is always non-negative. */
+ if (operand_equal_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1), 0))
+ return 1;
+ return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
+ && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+ }
+
+ /* zero_extend(x) * zero_extend(y) is non-negative if x and y are
+ both unsigned and their total bits is shorter than the result. */
+ if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
+ && TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
+ && TREE_CODE (TREE_OPERAND (t, 1)) == NOP_EXPR)
+ {
+ tree inner1 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
+ tree inner2 = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 1), 0));
+ if (TREE_CODE (inner1) == INTEGER_TYPE && TREE_UNSIGNED (inner1)
+ && TREE_CODE (inner2) == INTEGER_TYPE && TREE_UNSIGNED (inner2))
+ return TYPE_PRECISION (inner1) + TYPE_PRECISION (inner2)
+ < TYPE_PRECISION (TREE_TYPE (t));
+ }
+ return 0;
+
case TRUNC_DIV_EXPR:
case CEIL_DIV_EXPR:
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
- && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+ && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+
case TRUNC_MOD_EXPR:
case CEIL_MOD_EXPR:
case FLOOR_MOD_EXPR:
case ROUND_MOD_EXPR:
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
+
+ case RDIV_EXPR:
+ return tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
+ && tree_expr_nonnegative_p (TREE_OPERAND (t, 1));
+
+ case NOP_EXPR:
+ {
+ tree inner_type = TREE_TYPE (TREE_OPERAND (t, 0));
+ tree outer_type = TREE_TYPE (t);
+
+ if (TREE_CODE (outer_type) == REAL_TYPE)
+ {
+ if (TREE_CODE (inner_type) == REAL_TYPE)
+ return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
+ if (TREE_CODE (inner_type) == INTEGER_TYPE)
+ {
+ if (TREE_UNSIGNED (inner_type))
+ return 1;
+ return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
+ }
+ }
+ else if (TREE_CODE (outer_type) == INTEGER_TYPE)
+ {
+ if (TREE_CODE (inner_type) == REAL_TYPE)
+ return tree_expr_nonnegative_p (TREE_OPERAND (t,0));
+ if (TREE_CODE (inner_type) == INTEGER_TYPE)
+ return TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type)
+ && TREE_UNSIGNED (inner_type);
+ }
+ }
+ break;
+
case COND_EXPR:
return tree_expr_nonnegative_p (TREE_OPERAND (t, 1))
&& tree_expr_nonnegative_p (TREE_OPERAND (t, 2));
@@ -7371,25 +8789,99 @@ tree_expr_nonnegative_p (t)
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
case NON_LVALUE_EXPR:
return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
+ case FLOAT_EXPR:
+ return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
case RTL_EXPR:
return rtl_expr_nonnegative_p (RTL_EXPR_RTL (t));
+ case CALL_EXPR:
+ {
+ tree fndecl = get_callee_fndecl (t);
+ tree arglist = TREE_OPERAND (t, 1);
+ if (fndecl
+ && DECL_BUILT_IN (fndecl)
+ && DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_MD)
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_CABS:
+ case BUILT_IN_CABSL:
+ case BUILT_IN_CABSF:
+ case BUILT_IN_EXP:
+ case BUILT_IN_EXPF:
+ case BUILT_IN_EXPL:
+ case BUILT_IN_EXP2:
+ case BUILT_IN_EXP2F:
+ case BUILT_IN_EXP2L:
+ case BUILT_IN_EXP10:
+ case BUILT_IN_EXP10F:
+ case BUILT_IN_EXP10L:
+ case BUILT_IN_FABS:
+ case BUILT_IN_FABSF:
+ case BUILT_IN_FABSL:
+ case BUILT_IN_FFS:
+ case BUILT_IN_FFSL:
+ case BUILT_IN_FFSLL:
+ case BUILT_IN_PARITY:
+ case BUILT_IN_PARITYL:
+ case BUILT_IN_PARITYLL:
+ case BUILT_IN_POPCOUNT:
+ case BUILT_IN_POPCOUNTL:
+ case BUILT_IN_POPCOUNTLL:
+ case BUILT_IN_POW10:
+ case BUILT_IN_POW10F:
+ case BUILT_IN_POW10L:
+ case BUILT_IN_SQRT:
+ case BUILT_IN_SQRTF:
+ case BUILT_IN_SQRTL:
+ return 1;
+
+ case BUILT_IN_ATAN:
+ case BUILT_IN_ATANF:
+ case BUILT_IN_ATANL:
+ case BUILT_IN_CEIL:
+ case BUILT_IN_CEILF:
+ case BUILT_IN_CEILL:
+ case BUILT_IN_FLOOR:
+ case BUILT_IN_FLOORF:
+ case BUILT_IN_FLOORL:
+ case BUILT_IN_NEARBYINT:
+ case BUILT_IN_NEARBYINTF:
+ case BUILT_IN_NEARBYINTL:
+ case BUILT_IN_ROUND:
+ case BUILT_IN_ROUNDF:
+ case BUILT_IN_ROUNDL:
+ case BUILT_IN_TRUNC:
+ case BUILT_IN_TRUNCF:
+ case BUILT_IN_TRUNCL:
+ return tree_expr_nonnegative_p (TREE_VALUE (arglist));
+
+ case BUILT_IN_POW:
+ case BUILT_IN_POWF:
+ case BUILT_IN_POWL:
+ return tree_expr_nonnegative_p (TREE_VALUE (arglist));
+
+ default:
+ break;
+ }
+ }
+
+ /* ... fall through ... */
+
default:
if (truth_value_p (TREE_CODE (t)))
/* Truth values evaluate to 0 or 1, which is nonnegative. */
return 1;
- else
- /* We don't know sign of `t', so be conservative and return false. */
- return 0;
}
+
+ /* We don't know sign of `t', so be conservative and return false. */
+ return 0;
}
/* Return true if `r' is known to be non-negative.
Only handles constants at the moment. */
int
-rtl_expr_nonnegative_p (r)
- rtx r;
+rtl_expr_nonnegative_p (rtx r)
{
switch (GET_CODE (r))
{
diff --git a/contrib/gcc/fp-test.c b/contrib/gcc/fp-test.c
index c85bf21befaa..cfd7f9c4bfc4 100644
--- a/contrib/gcc/fp-test.c
+++ b/contrib/gcc/fp-test.c
@@ -1,5 +1,5 @@
/* fp-test.c - Check that all floating-point operations are available.
- Copyright (C) 1995, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1995, 2000, 2003 Free Software Foundation, Inc.
Contributed by Ronald F. Guilmette <rfg@monkeys.com>.
This file is part of GCC.
@@ -83,7 +83,7 @@ volatile double d1 = 1.0, d2 = 1.0, d3 = 1.0;
volatile long double D1 = 1.0, D2 = 1.0, D3 = 1.0;
int
-main ()
+main (void)
{
/* TYPE: float */
diff --git a/contrib/gcc/function.c b/contrib/gcc/function.c
index e055375d8604..dcd972c7cd8f 100644
--- a/contrib/gcc/function.c
+++ b/contrib/gcc/function.c
@@ -1,6 +1,6 @@
-/* Expands front end tree to back end RTL for GNU C-Compiler
+/* Expands front end tree to back end RTL for GCC.
Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -40,12 +40,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "flags.h"
#include "except.h"
#include "function.h"
#include "expr.h"
+#include "optabs.h"
#include "libfuncs.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -59,6 +62,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm_p.h"
#include "integrate.h"
#include "langhooks.h"
+#include "target.h"
#ifndef TRAMPOLINE_ALIGNMENT
#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
@@ -68,6 +72,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
#endif
+#ifndef STACK_ALIGNMENT_NEEDED
+#define STACK_ALIGNMENT_NEEDED 1
+#endif
+
+#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
+
/* Some systems use __main in a way incompatible with its use in gcc, in these
cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
give the same symbol without quotes for an alternative entry point. You
@@ -122,12 +132,15 @@ int current_function_uses_only_leaf_regs;
post-instantiation libcalls. */
int virtuals_instantiated;
+/* Nonzero if at least one trampoline has been created. */
+int trampolines_created;
+
/* Assign unique numbers to labels generated for profiling, debugging, etc. */
-static int funcdef_no;
+static GTY(()) int funcdef_no;
/* These variables hold pointers to functions to create and destroy
target specific, per-function data structures. */
-struct machine_function * (*init_machine_status) PARAMS ((void));
+struct machine_function * (*init_machine_status) (void);
/* The FUNCTION_DECL for an inline function currently being expanded. */
tree inline_function_decl;
@@ -219,87 +232,79 @@ struct insns_for_mem_entry
/* Forward declarations. */
-static rtx assign_stack_local_1 PARAMS ((enum machine_mode, HOST_WIDE_INT,
- int, struct function *));
-static struct temp_slot *find_temp_slot_from_address PARAMS ((rtx));
-static void put_reg_into_stack PARAMS ((struct function *, rtx, tree,
- enum machine_mode, enum machine_mode,
- int, unsigned int, int,
- htab_t));
-static void schedule_fixup_var_refs PARAMS ((struct function *, rtx, tree,
- enum machine_mode,
- htab_t));
-static void fixup_var_refs PARAMS ((rtx, enum machine_mode, int, rtx,
- htab_t));
+static rtx assign_stack_local_1 (enum machine_mode, HOST_WIDE_INT, int,
+ struct function *);
+static struct temp_slot *find_temp_slot_from_address (rtx);
+static void put_reg_into_stack (struct function *, rtx, tree, enum machine_mode,
+ enum machine_mode, int, unsigned int, int, htab_t);
+static void schedule_fixup_var_refs (struct function *, rtx, tree, enum machine_mode,
+ htab_t);
+static void fixup_var_refs (rtx, enum machine_mode, int, rtx, htab_t);
static struct fixup_replacement
- *find_fixup_replacement PARAMS ((struct fixup_replacement **, rtx));
-static void fixup_var_refs_insns PARAMS ((rtx, rtx, enum machine_mode,
- int, int, rtx));
-static void fixup_var_refs_insns_with_hash
- PARAMS ((htab_t, rtx,
- enum machine_mode, int, rtx));
-static void fixup_var_refs_insn PARAMS ((rtx, rtx, enum machine_mode,
- int, int, rtx));
-static void fixup_var_refs_1 PARAMS ((rtx, enum machine_mode, rtx *, rtx,
- struct fixup_replacement **, rtx));
-static rtx fixup_memory_subreg PARAMS ((rtx, rtx, enum machine_mode, int));
-static rtx walk_fixup_memory_subreg PARAMS ((rtx, rtx, enum machine_mode,
- int));
-static rtx fixup_stack_1 PARAMS ((rtx, rtx));
-static void optimize_bit_field PARAMS ((rtx, rtx, rtx *));
-static void instantiate_decls PARAMS ((tree, int));
-static void instantiate_decls_1 PARAMS ((tree, int));
-static void instantiate_decl PARAMS ((rtx, HOST_WIDE_INT, int));
-static rtx instantiate_new_reg PARAMS ((rtx, HOST_WIDE_INT *));
-static int instantiate_virtual_regs_1 PARAMS ((rtx *, rtx, int));
-static void delete_handlers PARAMS ((void));
-static void pad_to_arg_alignment PARAMS ((struct args_size *, int,
- struct args_size *));
-static void pad_below PARAMS ((struct args_size *, enum machine_mode,
- tree));
-static rtx round_trampoline_addr PARAMS ((rtx));
-static rtx adjust_trampoline_addr PARAMS ((rtx));
-static tree *identify_blocks_1 PARAMS ((rtx, tree *, tree *, tree *));
-static void reorder_blocks_0 PARAMS ((tree));
-static void reorder_blocks_1 PARAMS ((rtx, tree, varray_type *));
-static void reorder_fix_fragments PARAMS ((tree));
-static tree blocks_nreverse PARAMS ((tree));
-static int all_blocks PARAMS ((tree, tree *));
-static tree *get_block_vector PARAMS ((tree, int *));
-extern tree debug_find_var_in_block_tree PARAMS ((tree, tree));
+ *find_fixup_replacement (struct fixup_replacement **, rtx);
+static void fixup_var_refs_insns (rtx, rtx, enum machine_mode, int, int, rtx);
+static void fixup_var_refs_insns_with_hash (htab_t, rtx, enum machine_mode, int, rtx);
+static void fixup_var_refs_insn (rtx, rtx, enum machine_mode, int, int, rtx);
+static void fixup_var_refs_1 (rtx, enum machine_mode, rtx *, rtx,
+ struct fixup_replacement **, rtx);
+static rtx fixup_memory_subreg (rtx, rtx, enum machine_mode, int);
+static rtx walk_fixup_memory_subreg (rtx, rtx, enum machine_mode, int);
+static rtx fixup_stack_1 (rtx, rtx);
+static void optimize_bit_field (rtx, rtx, rtx *);
+static void instantiate_decls (tree, int);
+static void instantiate_decls_1 (tree, int);
+static void instantiate_decl (rtx, HOST_WIDE_INT, int);
+static rtx instantiate_new_reg (rtx, HOST_WIDE_INT *);
+static int instantiate_virtual_regs_1 (rtx *, rtx, int);
+static void delete_handlers (void);
+static void pad_to_arg_alignment (struct args_size *, int, struct args_size *);
+static void pad_below (struct args_size *, enum machine_mode, tree);
+static rtx round_trampoline_addr (rtx);
+static rtx adjust_trampoline_addr (rtx);
+static tree *identify_blocks_1 (rtx, tree *, tree *, tree *);
+static void reorder_blocks_0 (tree);
+static void reorder_blocks_1 (rtx, tree, varray_type *);
+static void reorder_fix_fragments (tree);
+static tree blocks_nreverse (tree);
+static int all_blocks (tree, tree *);
+static tree *get_block_vector (tree, int *);
+extern tree debug_find_var_in_block_tree (tree, tree);
/* We always define `record_insns' even if its not used so that we
can always export `prologue_epilogue_contains'. */
-static void record_insns PARAMS ((rtx, varray_type *)) ATTRIBUTE_UNUSED;
-static int contains PARAMS ((rtx, varray_type));
+static void record_insns (rtx, varray_type *) ATTRIBUTE_UNUSED;
+static int contains (rtx, varray_type);
#ifdef HAVE_return
-static void emit_return_into_block PARAMS ((basic_block, rtx));
+static void emit_return_into_block (basic_block, rtx);
#endif
-static void put_addressof_into_stack PARAMS ((rtx, htab_t));
-static bool purge_addressof_1 PARAMS ((rtx *, rtx, int, int,
- htab_t));
-static void purge_single_hard_subreg_set PARAMS ((rtx));
+static void put_addressof_into_stack (rtx, htab_t);
+static bool purge_addressof_1 (rtx *, rtx, int, int, int, htab_t);
+static void purge_single_hard_subreg_set (rtx);
#if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
-static rtx keep_stack_depressed PARAMS ((rtx));
+static rtx keep_stack_depressed (rtx);
#endif
-static int is_addressof PARAMS ((rtx *, void *));
-static hashval_t insns_for_mem_hash PARAMS ((const void *));
-static int insns_for_mem_comp PARAMS ((const void *, const void *));
-static int insns_for_mem_walk PARAMS ((rtx *, void *));
-static void compute_insns_for_mem PARAMS ((rtx, rtx, htab_t));
-static void prepare_function_start PARAMS ((void));
-static void do_clobber_return_reg PARAMS ((rtx, void *));
-static void do_use_return_reg PARAMS ((rtx, void *));
-static void instantiate_virtual_regs_lossage PARAMS ((rtx));
+static int is_addressof (rtx *, void *);
+static hashval_t insns_for_mem_hash (const void *);
+static int insns_for_mem_comp (const void *, const void *);
+static int insns_for_mem_walk (rtx *, void *);
+static void compute_insns_for_mem (rtx, rtx, htab_t);
+static void prepare_function_start (tree);
+static void do_clobber_return_reg (rtx, void *);
+static void do_use_return_reg (rtx, void *);
+static void instantiate_virtual_regs_lossage (rtx);
+static tree split_complex_args (tree);
+static void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED;
/* Pointer to chain of `struct function' for containing functions. */
-static GTY(()) struct function *outer_function_chain;
+struct function *outer_function_chain;
+
+/* List of insns that were postponed by purge_addressof_1. */
+static rtx postponed_insns;
/* Given a function decl for a containing function,
return the `struct function' for it. */
struct function *
-find_function_data (decl)
- tree decl;
+find_function_data (tree decl)
{
struct function *p;
@@ -317,8 +322,7 @@ find_function_data (decl)
variables. */
void
-push_function_context_to (context)
- tree context;
+push_function_context_to (tree context)
{
struct function *p;
@@ -347,7 +351,7 @@ push_function_context_to (context)
}
void
-push_function_context ()
+push_function_context (void)
{
push_function_context_to (current_function_decl);
}
@@ -356,8 +360,7 @@ push_function_context ()
This function is called from language-specific code. */
void
-pop_function_context_from (context)
- tree context ATTRIBUTE_UNUSED;
+pop_function_context_from (tree context ATTRIBUTE_UNUSED)
{
struct function *p = outer_function_chain;
struct var_refs_queue *queue;
@@ -405,7 +408,7 @@ pop_function_context_from (context)
}
void
-pop_function_context ()
+pop_function_context (void)
{
pop_function_context_from (current_function_decl);
}
@@ -415,8 +418,7 @@ pop_function_context ()
garbage collection reclaim the memory. */
void
-free_after_parsing (f)
- struct function *f;
+free_after_parsing (struct function *f)
{
/* f->expr->forced_labels is used by code generation. */
/* f->emit->regno_reg_rtx is used by code generation. */
@@ -432,8 +434,7 @@ free_after_parsing (f)
reclaim the memory. */
void
-free_after_compilation (f)
- struct function *f;
+free_after_compilation (struct function *f)
{
f->eh = NULL;
f->expr = NULL;
@@ -451,6 +452,7 @@ free_after_compilation (f)
f->x_nonlocal_goto_stack_level = NULL;
f->x_cleanup_label = NULL;
f->x_return_label = NULL;
+ f->x_naked_return_label = NULL;
f->computed_goto_common_label = NULL;
f->computed_goto_common_reg = NULL;
f->x_save_expr_regs = NULL;
@@ -480,8 +482,7 @@ free_after_compilation (f)
the caller may have to do that. */
HOST_WIDE_INT
-get_func_frame_size (f)
- struct function *f;
+get_func_frame_size (struct function *f)
{
#ifdef FRAME_GROWS_DOWNWARD
return -f->x_frame_offset;
@@ -494,7 +495,7 @@ get_func_frame_size (f)
This size counts from zero. It is not rounded to PREFERRED_STACK_BOUNDARY;
the caller may have to do that. */
HOST_WIDE_INT
-get_frame_size ()
+get_frame_size (void)
{
return get_func_frame_size (cfun);
}
@@ -512,11 +513,8 @@ get_frame_size ()
FUNCTION specifies the function to allocate in. */
static rtx
-assign_stack_local_1 (mode, size, align, function)
- enum machine_mode mode;
- HOST_WIDE_INT size;
- int align;
- struct function *function;
+assign_stack_local_1 (enum machine_mode mode, HOST_WIDE_INT size, int align,
+ struct function *function)
{
rtx x, addr;
int bigend_correction = 0;
@@ -565,16 +563,27 @@ assign_stack_local_1 (mode, size, align, function)
frame_off = STARTING_FRAME_OFFSET % frame_alignment;
frame_phase = frame_off ? frame_alignment - frame_off : 0;
- /* Round frame offset to that alignment.
- We must be careful here, since FRAME_OFFSET might be negative and
- division with a negative dividend isn't as well defined as we might
- like. So we instead assume that ALIGNMENT is a power of two and
- use logical operations which are unambiguous. */
+ /* Round the frame offset to the specified alignment. The default is
+ to always honor requests to align the stack but a port may choose to
+ do its own stack alignment by defining STACK_ALIGNMENT_NEEDED. */
+ if (STACK_ALIGNMENT_NEEDED
+ || mode != BLKmode
+ || size != 0)
+ {
+ /* We must be careful here, since FRAME_OFFSET might be negative and
+ division with a negative dividend isn't as well defined as we might
+ like. So we instead assume that ALIGNMENT is a power of two and
+ use logical operations which are unambiguous. */
#ifdef FRAME_GROWS_DOWNWARD
- function->x_frame_offset = FLOOR_ROUND (function->x_frame_offset - frame_phase, alignment) + frame_phase;
+ function->x_frame_offset
+ = (FLOOR_ROUND (function->x_frame_offset - frame_phase, alignment)
+ + frame_phase);
#else
- function->x_frame_offset = CEIL_ROUND (function->x_frame_offset - frame_phase, alignment) + frame_phase;
+ function->x_frame_offset
+ = (CEIL_ROUND (function->x_frame_offset - frame_phase, alignment)
+ + frame_phase);
#endif
+ }
/* On a big-endian machine, if we are allocating more space than we will use,
use the least significant bytes of those that are allocated. */
@@ -585,11 +594,14 @@ assign_stack_local_1 (mode, size, align, function)
address relative to the frame pointer. */
if (function == cfun && virtuals_instantiated)
addr = plus_constant (frame_pointer_rtx,
+ trunc_int_for_mode
(frame_offset + bigend_correction
- + STARTING_FRAME_OFFSET));
+ + STARTING_FRAME_OFFSET, Pmode));
else
addr = plus_constant (virtual_stack_vars_rtx,
- function->x_frame_offset + bigend_correction);
+ trunc_int_for_mode
+ (function->x_frame_offset + bigend_correction,
+ Pmode));
#ifndef FRAME_GROWS_DOWNWARD
function->x_frame_offset += size;
@@ -607,10 +619,7 @@ assign_stack_local_1 (mode, size, align, function)
current function. */
rtx
-assign_stack_local (mode, size, align)
- enum machine_mode mode;
- HOST_WIDE_INT size;
- int align;
+assign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
{
return assign_stack_local_1 (mode, size, align, cfun);
}
@@ -633,11 +642,8 @@ assign_stack_local (mode, size, align)
TYPE is the type that will be used for the stack slot. */
rtx
-assign_stack_temp_for_type (mode, size, keep, type)
- enum machine_mode mode;
- HOST_WIDE_INT size;
- int keep;
- tree type;
+assign_stack_temp_for_type (enum machine_mode mode, HOST_WIDE_INT size, int keep,
+ tree type)
{
unsigned int align;
struct temp_slot *p, *best_p = 0;
@@ -690,7 +696,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
if (best_p->size - rounded_size >= alignment)
{
- p = (struct temp_slot *) ggc_alloc (sizeof (struct temp_slot));
+ p = ggc_alloc (sizeof (struct temp_slot));
p->in_use = p->addr_taken = 0;
p->size = best_p->size - rounded_size;
p->base_offset = best_p->base_offset + rounded_size;
@@ -721,7 +727,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
{
HOST_WIDE_INT frame_offset_old = frame_offset;
- p = (struct temp_slot *) ggc_alloc (sizeof (struct temp_slot));
+ p = ggc_alloc (sizeof (struct temp_slot));
/* We are passing an explicit alignment request to assign_stack_local.
One side effect of that is assign_stack_local will not round SIZE
@@ -734,7 +740,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
abort ();
p->slot = assign_stack_local (mode,
(mode == BLKmode
- ? CEIL_ROUND (size, align / BITS_PER_UNIT)
+ ? CEIL_ROUND (size, (int) align / BITS_PER_UNIT)
: size),
align);
@@ -774,7 +780,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
if (keep == 2)
{
p->level = target_temp_slot_level;
- p->keep = 0;
+ p->keep = 1;
}
else if (keep == 3)
{
@@ -801,7 +807,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
/* If a type is specified, set the relevant flags. */
if (type != 0)
{
- RTX_UNCHANGING_P (slot) = (lang_hooks.honor_readonly
+ RTX_UNCHANGING_P (slot) = (lang_hooks.honor_readonly
&& TYPE_READONLY (type));
MEM_VOLATILE_P (slot) = TYPE_VOLATILE (type);
MEM_SET_IN_STRUCT_P (slot, AGGREGATE_TYPE_P (type));
@@ -814,10 +820,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
reuse. First three arguments are same as in preceding function. */
rtx
-assign_stack_temp (mode, size, keep)
- enum machine_mode mode;
- HOST_WIDE_INT size;
- int keep;
+assign_stack_temp (enum machine_mode mode, HOST_WIDE_INT size, int keep)
{
return assign_stack_temp_for_type (mode, size, keep, NULL_TREE);
}
@@ -833,11 +836,8 @@ assign_stack_temp (mode, size, keep)
to wider modes. */
rtx
-assign_temp (type_or_decl, keep, memory_required, dont_promote)
- tree type_or_decl;
- int keep;
- int memory_required;
- int dont_promote ATTRIBUTE_UNUSED;
+assign_temp (tree type_or_decl, int keep, int memory_required,
+ int dont_promote ATTRIBUTE_UNUSED)
{
tree type, decl;
enum machine_mode mode;
@@ -881,7 +881,7 @@ assign_temp (type_or_decl, keep, memory_required, dont_promote)
if (decl && size == -1
&& TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST)
{
- error_with_decl (decl, "size of variable `%s' is too large");
+ error ("%Jsize of variable '%D' is too large", decl, decl);
size = 1;
}
@@ -904,7 +904,7 @@ assign_temp (type_or_decl, keep, memory_required, dont_promote)
problems in this case. */
void
-combine_temp_slots ()
+combine_temp_slots (void)
{
struct temp_slot *p, *q;
struct temp_slot *prev_p, *prev_q;
@@ -970,8 +970,7 @@ combine_temp_slots ()
/* Find the temp slot corresponding to the object at address X. */
static struct temp_slot *
-find_temp_slot_from_address (x)
- rtx x;
+find_temp_slot_from_address (rtx x)
{
struct temp_slot *p;
rtx next;
@@ -1012,8 +1011,7 @@ find_temp_slot_from_address (x)
that previously was known by OLD. */
void
-update_temp_slot_address (old, new)
- rtx old, new;
+update_temp_slot_address (rtx old, rtx new)
{
struct temp_slot *p;
@@ -1069,8 +1067,7 @@ update_temp_slot_address (old, new)
address was taken. */
void
-mark_temp_addr_taken (x)
- rtx x;
+mark_temp_addr_taken (rtx x)
{
struct temp_slot *p;
@@ -1097,8 +1094,7 @@ mark_temp_addr_taken (x)
returns a value in memory. */
void
-preserve_temp_slots (x)
- rtx x;
+preserve_temp_slots (rtx x)
{
struct temp_slot *p = 0;
@@ -1166,8 +1162,7 @@ preserve_temp_slots (x)
RTL_EXPR. */
void
-preserve_rtl_expr_result (x)
- rtx x;
+preserve_rtl_expr_result (rtx x)
{
struct temp_slot *p;
@@ -1196,7 +1191,7 @@ preserve_rtl_expr_result (x)
worthwhile. */
void
-free_temp_slots ()
+free_temp_slots (void)
{
struct temp_slot *p;
@@ -1211,8 +1206,7 @@ free_temp_slots ()
/* Free all temporary slots used in T, an RTL_EXPR node. */
void
-free_temps_for_rtl_expr (t)
- tree t;
+free_temps_for_rtl_expr (tree t)
{
struct temp_slot *p;
@@ -1236,7 +1230,7 @@ free_temps_for_rtl_expr (t)
for reuse until the current level is exited. */
void
-mark_all_temps_used ()
+mark_all_temps_used (void)
{
struct temp_slot *p;
@@ -1250,56 +1244,16 @@ mark_all_temps_used ()
/* Push deeper into the nesting level for stack temporaries. */
void
-push_temp_slots ()
+push_temp_slots (void)
{
temp_slot_level++;
}
-/* Likewise, but save the new level as the place to allocate variables
- for blocks. */
-
-#if 0
-void
-push_temp_slots_for_block ()
-{
- push_temp_slots ();
-
- var_temp_slot_level = temp_slot_level;
-}
-
-/* Likewise, but save the new level as the place to allocate temporaries
- for TARGET_EXPRs. */
-
-void
-push_temp_slots_for_target ()
-{
- push_temp_slots ();
-
- target_temp_slot_level = temp_slot_level;
-}
-
-/* Set and get the value of target_temp_slot_level. The only
- permitted use of these functions is to save and restore this value. */
-
-int
-get_target_temp_slot_level ()
-{
- return target_temp_slot_level;
-}
-
-void
-set_target_temp_slot_level (level)
- int level;
-{
- target_temp_slot_level = level;
-}
-#endif
-
/* Pop a temporary nesting level. All slots in use in the current level
are freed. */
void
-pop_temp_slots ()
+pop_temp_slots (void)
{
struct temp_slot *p;
@@ -1315,7 +1269,7 @@ pop_temp_slots ()
/* Initialize temporary slots. */
void
-init_temp_slots ()
+init_temp_slots (void)
{
/* We have not allocated any temporaries yet. */
temp_slots = 0;
@@ -1331,9 +1285,7 @@ init_temp_slots ()
addressable. */
void
-put_var_into_stack (decl, rescan)
- tree decl;
- int rescan;
+put_var_into_stack (tree decl, int rescan)
{
rtx reg;
enum machine_mode promoted_mode, decl_mode;
@@ -1477,16 +1429,10 @@ put_var_into_stack (decl, rescan)
USED_P is nonzero if this reg might have already been used in an insn. */
static void
-put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
- original_regno, used_p, ht)
- struct function *function;
- rtx reg;
- tree type;
- enum machine_mode promoted_mode, decl_mode;
- int volatile_p;
- unsigned int original_regno;
- int used_p;
- htab_t ht;
+put_reg_into_stack (struct function *function, rtx reg, tree type,
+ enum machine_mode promoted_mode,
+ enum machine_mode decl_mode, int volatile_p,
+ unsigned int original_regno, int used_p, htab_t ht)
{
struct function *func = function ? function : cfun;
rtx new = 0;
@@ -1496,7 +1442,11 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
regno = REGNO (reg);
if (regno < func->x_max_parm_reg)
- new = func->x_parm_reg_stack_loc[regno];
+ {
+ if (!func->x_parm_reg_stack_loc)
+ abort ();
+ new = func->x_parm_reg_stack_loc[regno];
+ }
if (new == 0)
new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func);
@@ -1529,12 +1479,8 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
See function above for meaning of arguments. */
static void
-schedule_fixup_var_refs (function, reg, type, promoted_mode, ht)
- struct function *function;
- rtx reg;
- tree type;
- enum machine_mode promoted_mode;
- htab_t ht;
+schedule_fixup_var_refs (struct function *function, rtx reg, tree type,
+ enum machine_mode promoted_mode, htab_t ht)
{
int unsigned_p = type ? TREE_UNSIGNED (type) : 0;
@@ -1542,8 +1488,7 @@ schedule_fixup_var_refs (function, reg, type, promoted_mode, ht)
{
struct var_refs_queue *temp;
- temp
- = (struct var_refs_queue *) ggc_alloc (sizeof (struct var_refs_queue));
+ temp = ggc_alloc (sizeof (struct var_refs_queue));
temp->modified = reg;
temp->promoted_mode = promoted_mode;
temp->unsignedp = unsigned_p;
@@ -1556,12 +1501,8 @@ schedule_fixup_var_refs (function, reg, type, promoted_mode, ht)
}
static void
-fixup_var_refs (var, promoted_mode, unsignedp, may_share, ht)
- rtx var;
- enum machine_mode promoted_mode;
- int unsignedp;
- htab_t ht;
- rtx may_share;
+fixup_var_refs (rtx var, enum machine_mode promoted_mode, int unsignedp,
+ rtx may_share, htab_t ht)
{
tree pending;
rtx first_insn = get_insns ();
@@ -1612,9 +1553,7 @@ fixup_var_refs (var, promoted_mode, unsignedp, may_share, ht)
value is equal to X. Allocate a new structure if no such entry exists. */
static struct fixup_replacement *
-find_fixup_replacement (replacements, x)
- struct fixup_replacement **replacements;
- rtx x;
+find_fixup_replacement (struct fixup_replacement **replacements, rtx x)
{
struct fixup_replacement *p;
@@ -1624,7 +1563,7 @@ find_fixup_replacement (replacements, x)
if (p == 0)
{
- p = (struct fixup_replacement *) xmalloc (sizeof (struct fixup_replacement));
+ p = xmalloc (sizeof (struct fixup_replacement));
p->old = x;
p->new = 0;
p->next = *replacements;
@@ -1640,13 +1579,8 @@ find_fixup_replacement (replacements, x)
to be unshared or a list of them. */
static void
-fixup_var_refs_insns (insn, var, promoted_mode, unsignedp, toplevel, may_share)
- rtx insn;
- rtx var;
- enum machine_mode promoted_mode;
- int unsignedp;
- int toplevel;
- rtx may_share;
+fixup_var_refs_insns (rtx insn, rtx var, enum machine_mode promoted_mode,
+ int unsignedp, int toplevel, rtx may_share)
{
while (insn)
{
@@ -1695,19 +1629,15 @@ fixup_var_refs_insns (insn, var, promoted_mode, unsignedp, toplevel, may_share)
(inside the CALL_PLACEHOLDER). */
static void
-fixup_var_refs_insns_with_hash (ht, var, promoted_mode, unsignedp, may_share)
- htab_t ht;
- rtx var;
- enum machine_mode promoted_mode;
- int unsignedp;
- rtx may_share;
+fixup_var_refs_insns_with_hash (htab_t ht, rtx var, enum machine_mode promoted_mode,
+ int unsignedp, rtx may_share)
{
struct insns_for_mem_entry tmp;
struct insns_for_mem_entry *ime;
rtx insn_list;
tmp.key = var;
- ime = (struct insns_for_mem_entry *) htab_find (ht, &tmp);
+ ime = htab_find (ht, &tmp);
for (insn_list = ime->insns; insn_list != 0; insn_list = XEXP (insn_list, 1))
if (INSN_P (XEXP (insn_list, 0)))
fixup_var_refs_insn (XEXP (insn_list, 0), var, promoted_mode,
@@ -1722,13 +1652,8 @@ fixup_var_refs_insns_with_hash (ht, var, promoted_mode, unsignedp, may_share)
function. */
static void
-fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, toplevel, no_share)
- rtx insn;
- rtx var;
- enum machine_mode promoted_mode;
- int unsignedp;
- int toplevel;
- rtx no_share;
+fixup_var_refs_insn (rtx insn, rtx var, enum machine_mode promoted_mode,
+ int unsignedp, int toplevel, rtx no_share)
{
rtx call_dest = 0;
rtx set, prev, prev_set;
@@ -1912,13 +1837,8 @@ fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, toplevel, no_share)
or the SUBREG, as appropriate, to the pseudo. */
static void
-fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
- rtx var;
- enum machine_mode promoted_mode;
- rtx *loc;
- rtx insn;
- struct fixup_replacement **replacements;
- rtx no_share;
+fixup_var_refs_1 (rtx var, enum machine_mode promoted_mode, rtx *loc, rtx insn,
+ struct fixup_replacement **replacements, rtx no_share)
{
int i;
rtx x = *loc;
@@ -2177,7 +2097,23 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
replacement = find_fixup_replacement (replacements, x);
if (replacement->new)
{
+ enum machine_mode mode = GET_MODE (x);
*loc = replacement->new;
+
+ /* Careful! We may have just replaced a SUBREG by a MEM, which
+ means that the insn may have become invalid again. We can't
+ in this case make a new replacement since we already have one
+ and we must deal with MATCH_DUPs. */
+ if (GET_CODE (replacement->new) == MEM)
+ {
+ INSN_CODE (insn) = -1;
+ if (recog_memoized (insn) >= 0)
+ return;
+
+ fixup_var_refs_1 (replacement->new, mode, &PATTERN (insn),
+ insn, replacements, no_share);
+ }
+
return;
}
@@ -2537,11 +2473,7 @@ fixup_var_refs_1 (var, promoted_mode, loc, insn, replacements, no_share)
This is used for subregs found inside REG_NOTES. */
static rtx
-fixup_memory_subreg (x, insn, promoted_mode, uncritical)
- rtx x;
- rtx insn;
- enum machine_mode promoted_mode;
- int uncritical;
+fixup_memory_subreg (rtx x, rtx insn, enum machine_mode promoted_mode, int uncritical)
{
int offset;
rtx mem = SUBREG_REG (x);
@@ -2583,11 +2515,8 @@ fixup_memory_subreg (x, insn, promoted_mode, uncritical)
fixup_memory_subreg. */
static rtx
-walk_fixup_memory_subreg (x, insn, promoted_mode, uncritical)
- rtx x;
- rtx insn;
- enum machine_mode promoted_mode;
- int uncritical;
+walk_fixup_memory_subreg (rtx x, rtx insn, enum machine_mode promoted_mode,
+ int uncritical)
{
enum rtx_code code;
const char *fmt;
@@ -2628,9 +2557,7 @@ walk_fixup_memory_subreg (x, insn, promoted_mode, uncritical)
Replace each such MEM rtx with a copy, to avoid clobberage. */
static rtx
-fixup_stack_1 (x, insn)
- rtx x;
- rtx insn;
+fixup_stack_1 (rtx x, rtx insn)
{
int i;
RTX_CODE code = GET_CODE (x);
@@ -2695,10 +2622,7 @@ fixup_stack_1 (x, insn)
is always 0.) */
static void
-optimize_bit_field (body, insn, equiv_mem)
- rtx body;
- rtx insn;
- rtx *equiv_mem;
+optimize_bit_field (rtx body, rtx insn, rtx *equiv_mem)
{
rtx bitfield;
int destflag;
@@ -2906,10 +2830,7 @@ static int cfa_offset;
been transformed. */
rtx
-gen_mem_addressof (reg, decl, rescan)
- rtx reg;
- tree decl;
- int rescan;
+gen_mem_addressof (rtx reg, tree decl, int rescan)
{
rtx r = gen_rtx_ADDRESSOF (Pmode, gen_reg_rtx (GET_MODE (reg)),
REGNO (reg), decl);
@@ -2947,12 +2868,22 @@ gen_mem_addressof (reg, decl, rescan)
if (DECL_P (decl) && decl_rtl == reg)
SET_DECL_RTL (decl, reg);
- if (rescan
+ if (rescan
&& (TREE_USED (decl) || (DECL_P (decl) && DECL_INITIAL (decl) != 0)))
fixup_var_refs (reg, GET_MODE (reg), TREE_UNSIGNED (type), reg, 0);
}
else if (rescan)
- fixup_var_refs (reg, GET_MODE (reg), 0, reg, 0);
+ {
+ /* This can only happen during reload. Clear the same flag bits as
+ reload. */
+ MEM_VOLATILE_P (reg) = 0;
+ RTX_UNCHANGING_P (reg) = 0;
+ MEM_IN_STRUCT_P (reg) = 0;
+ MEM_SCALAR_P (reg) = 0;
+ MEM_ATTRS (reg) = 0;
+
+ fixup_var_refs (reg, GET_MODE (reg), 0, reg, 0);
+ }
return reg;
}
@@ -2960,8 +2891,7 @@ gen_mem_addressof (reg, decl, rescan)
/* If DECL has an RTL that is an ADDRESSOF rtx, put it into the stack. */
void
-flush_addressof (decl)
- tree decl;
+flush_addressof (tree decl)
{
if ((TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == VAR_DECL)
&& DECL_RTL (decl) != 0
@@ -2974,9 +2904,7 @@ flush_addressof (decl)
/* Force the register pointed to by R, an ADDRESSOF rtx, into the stack. */
static void
-put_addressof_into_stack (r, ht)
- rtx r;
- htab_t ht;
+put_addressof_into_stack (rtx r, htab_t ht)
{
tree decl, type;
int volatile_p, used_p;
@@ -3021,20 +2949,19 @@ static rtx purge_addressof_replacements;
/* Helper function for purge_addressof. See if the rtx expression at *LOC
in INSN needs to be changed. If FORCE, always put any ADDRESSOFs into
the stack. If the function returns FALSE then the replacement could not
- be made. */
+ be made. If MAY_POSTPONE is true and we would not put the addressof
+ to stack, postpone processing of the insn. */
static bool
-purge_addressof_1 (loc, insn, force, store, ht)
- rtx *loc;
- rtx insn;
- int force, store;
- htab_t ht;
+purge_addressof_1 (rtx *loc, rtx insn, int force, int store, int may_postpone,
+ htab_t ht)
{
rtx x;
RTX_CODE code;
int i, j;
const char *fmt;
bool result = true;
+ bool libcall = false;
/* Re-start here to avoid recursion in common cases. */
restart:
@@ -3043,6 +2970,10 @@ purge_addressof_1 (loc, insn, force, store, ht)
if (x == 0)
return true;
+ /* Is this a libcall? */
+ if (!insn)
+ libcall = REG_NOTE_KIND (*loc) == REG_RETVAL;
+
code = GET_CODE (x);
/* If we don't return in any of the cases below, we will recurse inside
@@ -3050,8 +2981,10 @@ purge_addressof_1 (loc, insn, force, store, ht)
memory. */
if (code == SET)
{
- result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
- result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
+ result = purge_addressof_1 (&SET_DEST (x), insn, force, 1,
+ may_postpone, ht);
+ result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0,
+ may_postpone, ht);
return result;
}
else if (code == ADDRESSOF)
@@ -3069,7 +3002,15 @@ purge_addressof_1 (loc, insn, force, store, ht)
return true;
start_sequence ();
- sub = force_operand (sub, NULL_RTX);
+
+ /* If SUB is a hard or virtual register, try it as a pseudo-register.
+ Otherwise, perhaps SUB is an expression, so generate code to compute
+ it. */
+ if (GET_CODE (sub) == REG && REGNO (sub) <= LAST_VIRTUAL_REGISTER)
+ sub = copy_to_reg (sub);
+ else
+ sub = force_operand (sub, NULL_RTX);
+
if (! validate_change (insn, loc, sub, 0)
&& ! validate_replace_rtx (x, sub, insn))
abort ();
@@ -3093,6 +3034,15 @@ purge_addressof_1 (loc, insn, force, store, ht)
{
int size_x, size_sub;
+ if (may_postpone)
+ {
+ /* Postpone for now, so that we do not emit bitfield arithmetics
+ unless there is some benefit from it. */
+ if (!postponed_insns || XEXP (postponed_insns, 0) != insn)
+ postponed_insns = alloc_INSN_LIST (insn, postponed_insns);
+ return true;
+ }
+
if (!insn)
{
/* When processing REG_NOTES look at the list of
@@ -3149,6 +3099,35 @@ purge_addressof_1 (loc, insn, force, store, ht)
return true;
}
+ /* When we are processing the REG_NOTES of the last instruction
+ of a libcall, there will be typically no replacements
+ for that insn; the replacements happened before, piecemeal
+ fashion. OTOH we are not interested in the details of
+ this for the REG_EQUAL note, we want to know the big picture,
+ which can be succinctly described with a simple SUBREG.
+ Note that removing the REG_EQUAL note is not an option
+ on the last insn of a libcall, so we must do a replacement. */
+
+ /* In compile/990107-1.c:7 compiled at -O1 -m1 for sh-elf,
+ we got
+ (mem:DI (addressof:SI (reg/v:DF 160) 159 0x401c8510)
+ [0 S8 A32]), which can be expressed with a simple
+ same-size subreg */
+ if ((GET_MODE_SIZE (GET_MODE (x))
+ <= GET_MODE_SIZE (GET_MODE (sub)))
+ /* Again, invalid pointer casts (as in
+ compile/990203-1.c) can require paradoxical
+ subregs. */
+ || (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
+ && (GET_MODE_SIZE (GET_MODE (x))
+ > GET_MODE_SIZE (GET_MODE (sub)))
+ && libcall))
+ {
+ *loc = gen_rtx_SUBREG (GET_MODE (x), sub, 0);
+ return true;
+ }
+ /* ??? Are there other cases we should handle? */
+
/* Sometimes we may not be able to find the replacement. For
example when the original insn was a MEM in a wider mode,
and the note is part of a sign extension of a narrowed
@@ -3282,10 +3261,12 @@ purge_addressof_1 (loc, insn, force, store, ht)
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
{
if (*fmt == 'e')
- result &= purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
+ result &= purge_addressof_1 (&XEXP (x, i), insn, force, 0,
+ may_postpone, ht);
else if (*fmt == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
- result &= purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
+ result &= purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0,
+ may_postpone, ht);
}
return result;
@@ -3294,8 +3275,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
/* Return a hash value for K, a REG. */
static hashval_t
-insns_for_mem_hash (k)
- const void * k;
+insns_for_mem_hash (const void *k)
{
/* Use the address of the key for the hash value. */
struct insns_for_mem_entry *m = (struct insns_for_mem_entry *) k;
@@ -3305,9 +3285,7 @@ insns_for_mem_hash (k)
/* Return nonzero if K1 and K2 (two REGs) are the same. */
static int
-insns_for_mem_comp (k1, k2)
- const void * k1;
- const void * k2;
+insns_for_mem_comp (const void *k1, const void *k2)
{
struct insns_for_mem_entry *m1 = (struct insns_for_mem_entry *) k1;
struct insns_for_mem_entry *m2 = (struct insns_for_mem_entry *) k2;
@@ -3334,9 +3312,7 @@ struct insns_for_mem_walk_info
insns_for_mem_walk_info structure). */
static int
-insns_for_mem_walk (r, data)
- rtx *r;
- void *data;
+insns_for_mem_walk (rtx *r, void *data)
{
struct insns_for_mem_walk_info *ifmwi
= (struct insns_for_mem_walk_info *) data;
@@ -3346,7 +3322,7 @@ insns_for_mem_walk (r, data)
if (ifmwi->pass == 0 && *r && GET_CODE (*r) == ADDRESSOF
&& GET_CODE (XEXP (*r, 0)) == REG)
{
- PTR *e;
+ void **e;
tmp.key = XEXP (*r, 0);
e = htab_find_slot (ifmwi->ht, &tmp, INSERT);
if (*e == NULL)
@@ -3359,7 +3335,7 @@ insns_for_mem_walk (r, data)
{
struct insns_for_mem_entry *ifme;
tmp.key = *r;
- ifme = (struct insns_for_mem_entry *) htab_find (ifmwi->ht, &tmp);
+ ifme = htab_find (ifmwi->ht, &tmp);
/* If we have not already recorded this INSN, do so now. Since
we process the INSNs in order, we know that if we have
@@ -3376,10 +3352,7 @@ insns_for_mem_walk (r, data)
which REGs in HT. */
static void
-compute_insns_for_mem (insns, last_insn, ht)
- rtx insns;
- rtx last_insn;
- htab_t ht;
+compute_insns_for_mem (rtx insns, rtx last_insn, htab_t ht)
{
rtx insn;
struct insns_for_mem_walk_info ifmwi;
@@ -3398,9 +3371,7 @@ compute_insns_for_mem (insns, last_insn, ht)
Returns true iff the rtl is an ADDRESSOF. */
static int
-is_addressof (rtl, data)
- rtx *rtl;
- void *data ATTRIBUTE_UNUSED;
+is_addressof (rtx *rtl, void *data ATTRIBUTE_UNUSED)
{
return GET_CODE (*rtl) == ADDRESSOF;
}
@@ -3410,10 +3381,9 @@ is_addressof (rtl, data)
stack. */
void
-purge_addressof (insns)
- rtx insns;
+purge_addressof (rtx insns)
{
- rtx insn;
+ rtx insn, tmp;
htab_t ht;
/* When we actually purge ADDRESSOFs, we turn REGs into MEMs. That
@@ -3426,17 +3396,18 @@ purge_addressof (insns)
ht = htab_create_ggc (1000, insns_for_mem_hash, insns_for_mem_comp, NULL);
compute_insns_for_mem (insns, NULL_RTX, ht);
+ postponed_insns = NULL;
+
for (insn = insns; insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
- || GET_CODE (insn) == CALL_INSN)
+ if (INSN_P (insn))
{
if (! purge_addressof_1 (&PATTERN (insn), insn,
- asm_noperands (PATTERN (insn)) > 0, 0, ht))
+ asm_noperands (PATTERN (insn)) > 0, 0, 1, ht))
/* If we could not replace the ADDRESSOFs in the insn,
something is wrong. */
abort ();
- if (! purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, ht))
+ if (! purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, 0, ht))
{
/* If we could not replace the ADDRESSOFs in the insn's notes,
we can just remove the offending notes instead. */
@@ -3456,6 +3427,19 @@ purge_addressof (insns)
}
}
+ /* Process the postponed insns. */
+ while (postponed_insns)
+ {
+ insn = XEXP (postponed_insns, 0);
+ tmp = postponed_insns;
+ postponed_insns = XEXP (postponed_insns, 1);
+ free_INSN_LIST_node (tmp);
+
+ if (! purge_addressof_1 (&PATTERN (insn), insn,
+ asm_noperands (PATTERN (insn)) > 0, 0, 0, ht))
+ abort ();
+ }
+
/* Clean up. */
purge_bitfield_addressof_replacements = 0;
purge_addressof_replacements = 0;
@@ -3479,8 +3463,7 @@ purge_addressof (insns)
register. A subroutine of purge_hard_subreg_sets. */
static void
-purge_single_hard_subreg_set (pattern)
- rtx pattern;
+purge_single_hard_subreg_set (rtx pattern)
{
rtx reg = SET_DEST (pattern);
enum machine_mode mode = GET_MODE (SET_DEST (pattern));
@@ -3512,8 +3495,7 @@ purge_single_hard_subreg_set (pattern)
of hard registers. */
void
-purge_hard_subreg_sets (insn)
- rtx insn;
+purge_hard_subreg_sets (rtx insn)
{
for (; insn; insn = NEXT_INSN (insn))
{
@@ -3549,9 +3531,7 @@ purge_hard_subreg_sets (insn)
references to hard register references. */
void
-instantiate_virtual_regs (fndecl, insns)
- tree fndecl;
- rtx insns;
+instantiate_virtual_regs (tree fndecl, rtx insns)
{
rtx insn;
unsigned int i;
@@ -3616,9 +3596,7 @@ instantiate_virtual_regs (fndecl, insns)
Otherwise, always do it. */
static void
-instantiate_decls (fndecl, valid_only)
- tree fndecl;
- int valid_only;
+instantiate_decls (tree fndecl, int valid_only)
{
tree decl;
@@ -3646,9 +3624,7 @@ instantiate_decls (fndecl, valid_only)
BLOCK node and all its subblocks. */
static void
-instantiate_decls_1 (let, valid_only)
- tree let;
- int valid_only;
+instantiate_decls_1 (tree let, int valid_only)
{
tree t;
@@ -3670,10 +3646,7 @@ instantiate_decls_1 (let, valid_only)
changed if the new address is valid. */
static void
-instantiate_decl (x, size, valid_only)
- rtx x;
- HOST_WIDE_INT size;
- int valid_only;
+instantiate_decl (rtx x, HOST_WIDE_INT size, int valid_only)
{
enum machine_mode mode;
rtx addr;
@@ -3735,9 +3708,7 @@ instantiate_decl (x, size, valid_only)
offset indirectly through the pointer. Otherwise, return 0. */
static rtx
-instantiate_new_reg (x, poffset)
- rtx x;
- HOST_WIDE_INT *poffset;
+instantiate_new_reg (rtx x, HOST_WIDE_INT *poffset)
{
rtx new;
HOST_WIDE_INT offset;
@@ -3764,8 +3735,7 @@ instantiate_new_reg (x, poffset)
Usually this means that non-matching instruction has been emit, however for
asm statements it may be the problem in the constraints. */
static void
-instantiate_virtual_regs_lossage (insn)
- rtx insn;
+instantiate_virtual_regs_lossage (rtx insn)
{
if (asm_noperands (PATTERN (insn)) >= 0)
{
@@ -3790,10 +3760,7 @@ instantiate_virtual_regs_lossage (insn)
pseudos. */
static int
-instantiate_virtual_regs_1 (loc, object, extra_insns)
- rtx *loc;
- rtx object;
- int extra_insns;
+instantiate_virtual_regs_1 (rtx *loc, rtx object, int extra_insns)
{
rtx x;
RTX_CODE code;
@@ -4097,6 +4064,8 @@ instantiate_virtual_regs_1 (loc, object, extra_insns)
case ABS:
case SQRT:
case FFS:
+ case CLZ: case CTZ:
+ case POPCOUNT: case PARITY:
/* These case either have just one operand or we know that we need not
check the rest of the operands. */
loc = &XEXP (x, 0);
@@ -4184,7 +4153,7 @@ instantiate_virtual_regs_1 (loc, object, extra_insns)
and disestablish them. */
static void
-delete_handlers ()
+delete_handlers (void)
{
rtx insn;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
@@ -4232,57 +4201,53 @@ delete_handlers ()
}
}
-int
-max_parm_reg_num ()
-{
- return max_parm_reg;
-}
-
/* Return the first insn following those generated by `assign_parms'. */
rtx
-get_first_nonparm_insn ()
+get_first_nonparm_insn (void)
{
if (last_parm_insn)
return NEXT_INSN (last_parm_insn);
return get_insns ();
}
-/* Return the first NOTE_INSN_BLOCK_BEG note in the function.
- Crash if there is none. */
-
-rtx
-get_first_block_beg ()
-{
- rtx searcher;
- rtx insn = get_first_nonparm_insn ();
-
- for (searcher = insn; searcher; searcher = NEXT_INSN (searcher))
- if (GET_CODE (searcher) == NOTE
- && NOTE_LINE_NUMBER (searcher) == NOTE_INSN_BLOCK_BEG)
- return searcher;
-
- abort (); /* Invalid call to this function. (See comments above.) */
- return NULL_RTX;
-}
-
/* Return 1 if EXP is an aggregate type (or a value with aggregate type).
This means a type for which function calls must pass an address to the
function or get an address back from the function.
EXP may be a type node or an expression (whose type is tested). */
int
-aggregate_value_p (exp)
- tree exp;
+aggregate_value_p (tree exp, tree fntype)
{
int i, regno, nregs;
rtx reg;
tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp);
+ if (fntype)
+ switch (TREE_CODE (fntype))
+ {
+ case CALL_EXPR:
+ fntype = get_callee_fndecl (fntype);
+ fntype = fntype ? TREE_TYPE (fntype) : 0;
+ break;
+ case FUNCTION_DECL:
+ fntype = TREE_TYPE (fntype);
+ break;
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ break;
+ case IDENTIFIER_NODE:
+ fntype = 0;
+ break;
+ default:
+ /* We don't expect other rtl types here. */
+ abort();
+ }
+
if (TREE_CODE (type) == VOID_TYPE)
return 0;
- if (RETURN_IN_MEMORY (type))
+ if (targetm.calls.return_in_memory (type, fntype))
return 1;
/* Types that are TREE_ADDRESSABLE must be constructed in memory,
and thus can't be returned in registers. */
@@ -4312,31 +4277,23 @@ aggregate_value_p (exp)
those registers as the RTL for them. */
void
-assign_parms (fndecl)
- tree fndecl;
+assign_parms (tree fndecl)
{
tree parm;
- rtx entry_parm = 0;
- rtx stack_parm = 0;
CUMULATIVE_ARGS args_so_far;
- enum machine_mode promoted_mode, passed_mode;
- enum machine_mode nominal_mode, promoted_nominal_mode;
- int unsignedp;
/* Total space needed so far for args on the stack,
given as a constant and a tree-expression. */
struct args_size stack_args_size;
tree fntype = TREE_TYPE (fndecl);
- tree fnargs = DECL_ARGUMENTS (fndecl);
+ tree fnargs = DECL_ARGUMENTS (fndecl), orig_fnargs;
/* This is used for the arg pointer when referring to stack args. */
rtx internal_arg_pointer;
/* This is a dummy PARM_DECL that we used for the function result if
the function returns a structure. */
tree function_result_decl = 0;
-#ifdef SETUP_INCOMING_VARARGS
int varargs_setup = 0;
-#endif
+ int reg_parm_stack_space ATTRIBUTE_UNUSED = 0;
rtx conversion_insns = 0;
- struct args_size alignment_pad;
/* Nonzero if function takes extra anonymous args.
This means the last named arg must be on the stack
@@ -4367,9 +4324,9 @@ assign_parms (fndecl)
stack_args_size.var = 0;
/* If struct value address is treated as the first argument, make it so. */
- if (aggregate_value_p (DECL_RESULT (fndecl))
+ if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
&& ! current_function_returns_pcc_struct
- && struct_value_incoming_rtx == 0)
+ && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0)
{
tree type = build_pointer_type (TREE_TYPE (fntype));
@@ -4380,13 +4337,27 @@ assign_parms (fndecl)
fnargs = function_result_decl;
}
+ orig_fnargs = fnargs;
+
max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
- parm_reg_stack_loc = (rtx *) ggc_alloc_cleared (max_parm_reg * sizeof (rtx));
+ parm_reg_stack_loc = ggc_alloc_cleared (max_parm_reg * sizeof (rtx));
+
+ /* If the target wants to split complex arguments into scalars, do so. */
+ if (targetm.calls.split_complex_arg)
+ fnargs = split_complex_args (fnargs);
+
+#ifdef REG_PARM_STACK_SPACE
+#ifdef MAYBE_REG_PARM_STACK_SPACE
+ reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
+#else
+ reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
+#endif
+#endif
#ifdef INIT_CUMULATIVE_INCOMING_ARGS
INIT_CUMULATIVE_INCOMING_ARGS (args_so_far, fntype, NULL_RTX);
#else
- INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0);
+ INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, fndecl, -1);
#endif
/* We haven't yet found an argument that we must push and pretend the
@@ -4395,14 +4366,20 @@ assign_parms (fndecl)
for (parm = fnargs; parm; parm = TREE_CHAIN (parm))
{
- struct args_size stack_offset;
- struct args_size arg_size;
+ rtx entry_parm;
+ rtx stack_parm;
+ enum machine_mode promoted_mode, passed_mode;
+ enum machine_mode nominal_mode, promoted_nominal_mode;
+ int unsignedp;
+ struct locate_and_pad_arg_data locate;
int passed_pointer = 0;
int did_conversion = 0;
tree passed_type = DECL_ARG_TYPE (parm);
tree nominal_type = TREE_TYPE (parm);
- int pretend_named;
int last_named = 0, named_arg;
+ int in_regs;
+ int partial = 0;
+ int pretend_bytes = 0;
/* Set LAST_NAMED if this is last named arg before last
anonymous args. */
@@ -4420,7 +4397,7 @@ assign_parms (fndecl)
/* Set NAMED_ARG if this arg should be treated as a named arg. For
most machines, if this is a varargs/stdarg function, then we treat
the last named arg as if it were anonymous too. */
- named_arg = STRICT_ARGUMENT_NAMING ? 1 : ! last_named;
+ named_arg = targetm.calls.strict_argument_naming (&args_so_far) ? 1 : ! last_named;
if (TREE_TYPE (parm) == error_mark_node
/* This can happen after weird syntax errors
@@ -4461,12 +4438,11 @@ assign_parms (fndecl)
object itself or if the machine requires these objects be passed
that way. */
- if ((TREE_CODE (TYPE_SIZE (passed_type)) != INTEGER_CST
- && contains_placeholder_p (TYPE_SIZE (passed_type)))
+ if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (passed_type))
|| TREE_ADDRESSABLE (passed_type)
#ifdef FUNCTION_ARG_PASS_BY_REFERENCE
|| FUNCTION_ARG_PASS_BY_REFERENCE (args_so_far, passed_mode,
- passed_type, named_arg)
+ passed_type, named_arg)
#endif
)
{
@@ -4486,11 +4462,12 @@ assign_parms (fndecl)
promoted_mode = passed_mode;
-#ifdef PROMOTE_FUNCTION_ARGS
- /* Compute the mode in which the arg is actually extended to. */
- unsignedp = TREE_UNSIGNED (passed_type);
- promoted_mode = promote_mode (passed_type, promoted_mode, &unsignedp, 1);
-#endif
+ if (targetm.calls.promote_function_args (TREE_TYPE (fndecl)))
+ {
+ /* Compute the mode in which the arg is actually extended to. */
+ unsignedp = TREE_UNSIGNED (passed_type);
+ promoted_mode = promote_mode (passed_type, promoted_mode, &unsignedp, 1);
+ }
/* Let machine desc say which reg (if any) the parm arrives in.
0 means it arrives on the stack. */
@@ -4505,7 +4482,6 @@ assign_parms (fndecl)
if (entry_parm == 0)
promoted_mode = passed_mode;
-#ifdef SETUP_INCOMING_VARARGS
/* If this is the last named parameter, do any required setup for
varargs or stdargs. We need to know about the case of this being an
addressable type, in which case we skip the registers it
@@ -4518,11 +4494,18 @@ assign_parms (fndecl)
Also, indicate when RTL generation is to be suppressed. */
if (last_named && !varargs_setup)
{
- SETUP_INCOMING_VARARGS (args_so_far, promoted_mode, passed_type,
- current_function_pretend_args_size, 0);
+ int varargs_pretend_bytes = 0;
+ targetm.calls.setup_incoming_varargs (&args_so_far, promoted_mode,
+ passed_type,
+ &varargs_pretend_bytes, 0);
varargs_setup = 1;
+
+ /* If the back-end has requested extra stack space, record how
+ much is needed. Do not change pretend_args_size otherwise
+ since it may be nonzero from an earlier partial argument. */
+ if (varargs_pretend_bytes > 0)
+ current_function_pretend_args_size = varargs_pretend_bytes;
}
-#endif
/* Determine parm's home in the stack,
in case it arrives in the stack or we should pretend it did.
@@ -4536,27 +4519,89 @@ assign_parms (fndecl)
it came in a register so that REG_PARM_STACK_SPACE isn't skipped.
In this case, we call FUNCTION_ARG with NAMED set to 1 instead of
0 as it was the previous time. */
-
- pretend_named = named_arg || PRETEND_OUTGOING_VARARGS_NAMED;
- locate_and_pad_parm (promoted_mode, passed_type,
+ in_regs = entry_parm != 0;
#ifdef STACK_PARMS_IN_REG_PARM_AREA
- 1,
-#else
+ in_regs = 1;
+#endif
+ if (!in_regs && !named_arg)
+ {
+ int pretend_named =
+ targetm.calls.pretend_outgoing_varargs_named (&args_so_far);
+ if (pretend_named)
+ {
#ifdef FUNCTION_INCOMING_ARG
- FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
- passed_type,
- pretend_named) != 0,
+ in_regs = FUNCTION_INCOMING_ARG (args_so_far, promoted_mode,
+ passed_type,
+ pretend_named) != 0;
#else
- FUNCTION_ARG (args_so_far, promoted_mode,
- passed_type,
- pretend_named) != 0,
+ in_regs = FUNCTION_ARG (args_so_far, promoted_mode,
+ passed_type,
+ pretend_named) != 0;
#endif
+ }
+ }
+
+ /* If this parameter was passed both in registers and in the stack,
+ use the copy on the stack. */
+ if (MUST_PASS_IN_STACK (promoted_mode, passed_type))
+ entry_parm = 0;
+
+#ifdef FUNCTION_ARG_PARTIAL_NREGS
+ if (entry_parm)
+ {
+ partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
+ passed_type, named_arg);
+ if (partial
+#ifndef MAYBE_REG_PARM_STACK_SPACE
+ /* The caller might already have allocated stack space
+ for the register parameters. */
+ && reg_parm_stack_space == 0
+#endif
+ )
+ {
+ /* Part of this argument is passed in registers and part
+ is passed on the stack. Ask the prologue code to extend
+ the stack part so that we can recreate the full value.
+
+ PRETEND_BYTES is the size of the registers we need to store.
+ CURRENT_FUNCTION_PRETEND_ARGS_SIZE is the amount of extra
+ stack space that the prologue should allocate.
+
+ Internally, gcc assumes that the argument pointer is
+ aligned to STACK_BOUNDARY bits. This is used both for
+ alignment optimizations (see init_emit) and to locate
+ arguments that are aligned to more than PARM_BOUNDARY
+ bits. We must preserve this invariant by rounding
+ CURRENT_FUNCTION_PRETEND_ARGS_SIZE up to a stack
+ boundary. */
+ pretend_bytes = partial * UNITS_PER_WORD;
+ current_function_pretend_args_size
+ = CEIL_ROUND (pretend_bytes, STACK_BYTES);
+
+ /* If PRETEND_BYTES != CURRENT_FUNCTION_PRETEND_ARGS_SIZE,
+ insert the padding before the start of the first pretend
+ argument. */
+ stack_args_size.constant
+ = (current_function_pretend_args_size - pretend_bytes);
+ }
+ }
#endif
- fndecl, &stack_args_size, &stack_offset, &arg_size,
- &alignment_pad);
+
+ memset (&locate, 0, sizeof (locate));
+ locate_and_pad_parm (promoted_mode, passed_type, in_regs,
+ entry_parm ? partial : 0, fndecl,
+ &stack_args_size, &locate);
{
- rtx offset_rtx = ARGS_SIZE_RTX (stack_offset);
+ rtx offset_rtx;
+ unsigned int align, boundary;
+
+ /* If we're passing this arg using a reg, make its stack home
+ the aligned stack slot. */
+ if (entry_parm)
+ offset_rtx = ARGS_SIZE_RTX (locate.slot_offset);
+ else
+ offset_rtx = ARGS_SIZE_RTX (locate.offset);
if (offset_rtx == const0_rtx)
stack_parm = gen_rtx_MEM (promoted_mode, internal_arg_pointer);
@@ -4567,14 +4612,28 @@ assign_parms (fndecl)
offset_rtx));
set_mem_attributes (stack_parm, parm, 1);
- }
- /* If this parameter was passed both in registers and in the stack,
- use the copy on the stack. */
- if (MUST_PASS_IN_STACK (promoted_mode, passed_type))
- entry_parm = 0;
+ boundary = FUNCTION_ARG_BOUNDARY (promoted_mode, passed_type);
+ align = 0;
+
+ /* If we're padding upward, we know that the alignment of the slot
+ is FUNCTION_ARG_BOUNDARY. If we're using slot_offset, we're
+ intentionally forcing upward padding. Otherwise we have to come
+ up with a guess at the alignment based on OFFSET_RTX. */
+ if (locate.where_pad == upward || entry_parm)
+ align = boundary;
+ else if (GET_CODE (offset_rtx) == CONST_INT)
+ {
+ align = INTVAL (offset_rtx) * BITS_PER_UNIT | boundary;
+ align = align & -align;
+ }
+ if (align > 0)
+ set_mem_align (stack_parm, align);
+
+ if (entry_parm)
+ set_reg_attrs_for_parm (entry_parm, stack_parm);
+ }
-#ifdef FUNCTION_ARG_PARTIAL_NREGS
/* If this parm was passed part in regs and part in memory,
pretend it arrived entirely in memory
by pushing the register-part onto the stack.
@@ -4583,39 +4642,21 @@ assign_parms (fndecl)
we could put it together in a pseudoreg directly,
but for now that's not worth bothering with. */
- if (entry_parm)
+ if (partial)
{
- int nregs = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, promoted_mode,
- passed_type, named_arg);
-
- if (nregs > 0)
- {
-#if defined (REG_PARM_STACK_SPACE) && !defined (MAYBE_REG_PARM_STACK_SPACE)
- /* When REG_PARM_STACK_SPACE is nonzero, stack space for
- split parameters was allocated by our caller, so we
- won't be pushing it in the prolog. */
- if (REG_PARM_STACK_SPACE (fndecl) == 0)
-#endif
- current_function_pretend_args_size
- = (((nregs * UNITS_PER_WORD) + (PARM_BOUNDARY / BITS_PER_UNIT) - 1)
- / (PARM_BOUNDARY / BITS_PER_UNIT)
- * (PARM_BOUNDARY / BITS_PER_UNIT));
-
- /* Handle calls that pass values in multiple non-contiguous
- locations. The Irix 6 ABI has examples of this. */
- if (GET_CODE (entry_parm) == PARALLEL)
- emit_group_store (validize_mem (stack_parm), entry_parm,
- int_size_in_bytes (TREE_TYPE (parm)));
+ /* Handle calls that pass values in multiple non-contiguous
+ locations. The Irix 6 ABI has examples of this. */
+ if (GET_CODE (entry_parm) == PARALLEL)
+ emit_group_store (validize_mem (stack_parm), entry_parm,
+ TREE_TYPE (parm),
+ int_size_in_bytes (TREE_TYPE (parm)));
- else
- move_block_from_reg (REGNO (entry_parm),
- validize_mem (stack_parm), nregs,
- int_size_in_bytes (TREE_TYPE (parm)));
+ else
+ move_block_from_reg (REGNO (entry_parm), validize_mem (stack_parm),
+ partial);
- entry_parm = stack_parm;
- }
+ entry_parm = stack_parm;
}
-#endif
/* If we didn't decide this parm came in a register,
by default it came on the stack. */
@@ -4646,9 +4687,9 @@ assign_parms (fndecl)
#endif
)
{
- stack_args_size.constant += arg_size.constant;
- if (arg_size.var)
- ADD_PARM_SIZE (stack_args_size, arg_size.var);
+ stack_args_size.constant += pretend_bytes + locate.size.constant;
+ if (locate.size.var)
+ ADD_PARM_SIZE (stack_args_size, locate.size.var);
}
else
/* No stack slot was pushed for this parm. */
@@ -4662,17 +4703,13 @@ assign_parms (fndecl)
/* If we can't trust the parm stack slot to be aligned enough
for its ultimate type, don't use that slot after entry.
We'll make another stack slot, if we need one. */
- {
- unsigned int thisparm_boundary
- = FUNCTION_ARG_BOUNDARY (promoted_mode, passed_type);
-
- if (GET_MODE_ALIGNMENT (nominal_mode) > thisparm_boundary)
- stack_parm = 0;
- }
+ if (STRICT_ALIGNMENT && stack_parm
+ && GET_MODE_ALIGNMENT (nominal_mode) > MEM_ALIGN (stack_parm))
+ stack_parm = 0;
/* If parm was passed in memory, and we need to convert it on entry,
don't store it back in that same slot. */
- if (entry_parm != 0
+ if (entry_parm == stack_parm
&& nominal_mode != BLKmode && nominal_mode != passed_mode)
stack_parm = 0;
@@ -4711,7 +4748,46 @@ assign_parms (fndecl)
Set DECL_RTL to that place. */
- if (nominal_mode == BLKmode || GET_CODE (entry_parm) == PARALLEL)
+ if (GET_CODE (entry_parm) == PARALLEL && nominal_mode != BLKmode
+ && XVECLEN (entry_parm, 0) > 1)
+ {
+ /* Reconstitute objects the size of a register or larger using
+ register operations instead of the stack. */
+ rtx parmreg = gen_reg_rtx (nominal_mode);
+
+ if (REG_P (parmreg))
+ {
+ unsigned int regno = REGNO (parmreg);
+
+ emit_group_store (parmreg, entry_parm, TREE_TYPE (parm),
+ int_size_in_bytes (TREE_TYPE (parm)));
+ SET_DECL_RTL (parm, parmreg);
+
+ if (regno >= max_parm_reg)
+ {
+ rtx *new;
+ int old_max_parm_reg = max_parm_reg;
+
+ /* It's slow to expand this one register at a time,
+ but it's also rare and we need max_parm_reg to be
+ precisely correct. */
+ max_parm_reg = regno + 1;
+ new = ggc_realloc (parm_reg_stack_loc,
+ max_parm_reg * sizeof (rtx));
+ memset (new + old_max_parm_reg, 0,
+ (max_parm_reg - old_max_parm_reg) * sizeof (rtx));
+ parm_reg_stack_loc = new;
+ parm_reg_stack_loc[regno] = stack_parm;
+ }
+ }
+ }
+
+ if (nominal_mode == BLKmode
+#ifdef BLOCK_REG_PADDING
+ || (locate.where_pad == (BYTES_BIG_ENDIAN ? upward : downward)
+ && GET_MODE_SIZE (promoted_mode) < UNITS_PER_WORD)
+#endif
+ || GET_CODE (entry_parm) == PARALLEL)
{
/* If a BLKmode arrives in registers, copy it to a stack slot.
Handle calls that pass values in multiple non-contiguous
@@ -4719,9 +4795,9 @@ assign_parms (fndecl)
if (GET_CODE (entry_parm) == REG
|| GET_CODE (entry_parm) == PARALLEL)
{
- int size_stored
- = CEIL_ROUND (int_size_in_bytes (TREE_TYPE (parm)),
- UNITS_PER_WORD);
+ int size = int_size_in_bytes (TREE_TYPE (parm));
+ int size_stored = CEIL_ROUND (size, UNITS_PER_WORD);
+ rtx mem;
/* Note that we will be storing an integral number of words.
So we have to be careful to ensure that we allocate an
@@ -4729,31 +4805,83 @@ assign_parms (fndecl)
assign_stack_local if space was not allocated in the argument
list. If it was, this will not work if PARM_BOUNDARY is not
a multiple of BITS_PER_WORD. It isn't clear how to fix this
- if it becomes a problem. */
+ if it becomes a problem. Exception is when BLKmode arrives
+ with arguments not conforming to word_mode. */
if (stack_parm == 0)
{
- stack_parm
- = assign_stack_local (GET_MODE (entry_parm),
- size_stored, 0);
+ stack_parm = assign_stack_local (BLKmode, size_stored, 0);
+ PUT_MODE (stack_parm, GET_MODE (entry_parm));
set_mem_attributes (stack_parm, parm, 1);
}
-
+ else if (GET_CODE (entry_parm) == PARALLEL)
+ ;
else if (PARM_BOUNDARY % BITS_PER_WORD != 0)
abort ();
+ mem = validize_mem (stack_parm);
+
/* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (entry_parm) == PARALLEL)
- emit_group_store (validize_mem (stack_parm), entry_parm,
- int_size_in_bytes (TREE_TYPE (parm)));
+ emit_group_store (mem, entry_parm, TREE_TYPE (parm), size);
+
+ else if (size == 0)
+ ;
+
+ /* If SIZE is that of a mode no bigger than a word, just use
+ that mode's store operation. */
+ else if (size <= UNITS_PER_WORD)
+ {
+ enum machine_mode mode
+ = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
+
+ if (mode != BLKmode
+#ifdef BLOCK_REG_PADDING
+ && (size == UNITS_PER_WORD
+ || (BLOCK_REG_PADDING (mode, TREE_TYPE (parm), 1)
+ != (BYTES_BIG_ENDIAN ? upward : downward)))
+#endif
+ )
+ {
+ rtx reg = gen_rtx_REG (mode, REGNO (entry_parm));
+ emit_move_insn (change_address (mem, mode, 0), reg);
+ }
+
+ /* Blocks smaller than a word on a BYTES_BIG_ENDIAN
+ machine must be aligned to the left before storing
+ to memory. Note that the previous test doesn't
+ handle all cases (e.g. SIZE == 3). */
+ else if (size != UNITS_PER_WORD
+#ifdef BLOCK_REG_PADDING
+ && (BLOCK_REG_PADDING (mode, TREE_TYPE (parm), 1)
+ == downward)
+#else
+ && BYTES_BIG_ENDIAN
+#endif
+ )
+ {
+ rtx tem, x;
+ int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
+ rtx reg = gen_rtx_REG (word_mode, REGNO (entry_parm));
+
+ x = expand_binop (word_mode, ashl_optab, reg,
+ GEN_INT (by), 0, 1, OPTAB_WIDEN);
+ tem = change_address (mem, word_mode, 0);
+ emit_move_insn (tem, x);
+ }
+ else
+ move_block_from_reg (REGNO (entry_parm), mem,
+ size_stored / UNITS_PER_WORD);
+ }
else
- move_block_from_reg (REGNO (entry_parm),
- validize_mem (stack_parm),
- size_stored / UNITS_PER_WORD,
- int_size_in_bytes (TREE_TYPE (parm)));
+ move_block_from_reg (REGNO (entry_parm), mem,
+ size_stored / UNITS_PER_WORD);
}
- SET_DECL_RTL (parm, stack_parm);
+ /* If parm is already bound to register pair, don't change
+ this binding. */
+ if (! DECL_RTL_SET_P (parm))
+ SET_DECL_RTL (parm, stack_parm);
}
else if (! ((! optimize
&& ! DECL_REGISTER (parm))
@@ -4843,7 +4971,7 @@ assign_parms (fndecl)
/* TREE_USED gets set erroneously during expand_assignment. */
save_tree_used = TREE_USED (parm);
expand_assignment (parm,
- make_tree (nominal_type, tempreg), 0, 0);
+ make_tree (nominal_type, tempreg), 0);
TREE_USED (parm) = save_tree_used;
conversion_insns = get_insns ();
did_conversion = 1;
@@ -4902,13 +5030,13 @@ assign_parms (fndecl)
else if (passed_pointer
&& FUNCTION_ARG_CALLEE_COPIES (args_so_far,
- TYPE_MODE (DECL_ARG_TYPE (parm)),
- DECL_ARG_TYPE (parm),
+ TYPE_MODE (TREE_TYPE (passed_type)),
+ TREE_TYPE (passed_type),
named_arg)
- && ! TREE_ADDRESSABLE (DECL_ARG_TYPE (parm)))
+ && ! TREE_ADDRESSABLE (TREE_TYPE (passed_type)))
{
rtx copy;
- tree type = DECL_ARG_TYPE (parm);
+ tree type = TREE_TYPE (passed_type);
/* This sequence may involve a library call perhaps clobbering
registers that haven't been copied to pseudos yet. */
@@ -4955,10 +5083,10 @@ assign_parms (fndecl)
but it's also rare and we need max_parm_reg to be
precisely correct. */
max_parm_reg = regno + 1;
- new = (rtx *) ggc_realloc (parm_reg_stack_loc,
- max_parm_reg * sizeof (rtx));
- memset ((char *) (new + old_max_parm_reg), 0,
- (max_parm_reg - old_max_parm_reg) * sizeof (rtx));
+ new = ggc_realloc (parm_reg_stack_loc,
+ max_parm_reg * sizeof (rtx));
+ memset (new + old_max_parm_reg, 0,
+ (max_parm_reg - old_max_parm_reg) * sizeof (rtx));
parm_reg_stack_loc = new;
}
@@ -4995,7 +5123,7 @@ assign_parms (fndecl)
&& ! did_conversion
&& stack_parm != 0
&& GET_CODE (stack_parm) == MEM
- && stack_offset.var == 0
+ && locate.offset.var == 0
&& reg_mentioned_p (virtual_incoming_args_rtx,
XEXP (stack_parm, 0)))
{
@@ -5081,7 +5209,8 @@ assign_parms (fndecl)
{
stack_parm
= assign_stack_local (GET_MODE (entry_parm),
- GET_MODE_SIZE (GET_MODE (entry_parm)), 0);
+ GET_MODE_SIZE (GET_MODE (entry_parm)),
+ 0);
set_mem_attributes (stack_parm, parm, 1);
}
@@ -5100,39 +5229,68 @@ assign_parms (fndecl)
SET_DECL_RTL (parm, stack_parm);
}
+ }
- /* If this "parameter" was the place where we are receiving the
- function's incoming structure pointer, set up the result. */
- if (parm == function_result_decl)
+ if (targetm.calls.split_complex_arg && fnargs != orig_fnargs)
+ {
+ for (parm = orig_fnargs; parm; parm = TREE_CHAIN (parm))
{
- tree result = DECL_RESULT (fndecl);
- rtx addr = DECL_RTL (parm);
- rtx x;
-
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (addr) != Pmode)
- addr = convert_memory_address (Pmode, addr);
-#endif
+ if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (TREE_TYPE (parm)))
+ {
+ rtx tmp, real, imag;
+ enum machine_mode inner = GET_MODE_INNER (DECL_MODE (parm));
- x = gen_rtx_MEM (DECL_MODE (result), addr);
- set_mem_attributes (x, result, 1);
- SET_DECL_RTL (result, x);
- }
+ real = DECL_RTL (fnargs);
+ imag = DECL_RTL (TREE_CHAIN (fnargs));
+ if (inner != GET_MODE (real))
+ {
+ real = gen_lowpart_SUBREG (inner, real);
+ imag = gen_lowpart_SUBREG (inner, imag);
+ }
+ tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
+ SET_DECL_RTL (parm, tmp);
- if (GET_CODE (DECL_RTL (parm)) == REG)
- REGNO_DECL (REGNO (DECL_RTL (parm))) = parm;
- else if (GET_CODE (DECL_RTL (parm)) == CONCAT)
- {
- REGNO_DECL (REGNO (XEXP (DECL_RTL (parm), 0))) = parm;
- REGNO_DECL (REGNO (XEXP (DECL_RTL (parm), 1))) = parm;
+ real = DECL_INCOMING_RTL (fnargs);
+ imag = DECL_INCOMING_RTL (TREE_CHAIN (fnargs));
+ if (inner != GET_MODE (real))
+ {
+ real = gen_lowpart_SUBREG (inner, real);
+ imag = gen_lowpart_SUBREG (inner, imag);
+ }
+ tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
+ DECL_INCOMING_RTL (parm) = tmp;
+ fnargs = TREE_CHAIN (fnargs);
+ }
+ else
+ {
+ SET_DECL_RTL (parm, DECL_RTL (fnargs));
+ DECL_INCOMING_RTL (parm) = DECL_INCOMING_RTL (fnargs);
+ }
+ fnargs = TREE_CHAIN (fnargs);
}
-
}
/* Output all parameter conversion instructions (possibly including calls)
now that all parameters have been copied out of hard registers. */
emit_insn (conversion_insns);
+ /* If we are receiving a struct value address as the first argument, set up
+ the RTL for the function result. As this might require code to convert
+ the transmitted address to Pmode, we do this here to ensure that possible
+ preliminary conversions of the address have been emitted already. */
+ if (function_result_decl)
+ {
+ tree result = DECL_RESULT (fndecl);
+ rtx addr = DECL_RTL (function_result_decl);
+ rtx x;
+
+ addr = convert_memory_address (Pmode, addr);
+ x = gen_rtx_MEM (DECL_MODE (result), addr);
+ set_mem_attributes (x, result, 1);
+ SET_DECL_RTL (result, x);
+ }
+
last_parm_insn = get_last_insn ();
current_function_args_size = stack_args_size.constant;
@@ -5147,8 +5305,6 @@ assign_parms (fndecl)
#endif
#endif
-#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
-
current_function_args_size
= ((current_function_args_size + STACK_BYTES - 1)
/ STACK_BYTES) * STACK_BYTES;
@@ -5212,6 +5368,60 @@ assign_parms (fndecl)
}
}
}
+
+/* If ARGS contains entries with complex types, split the entry into two
+ entries of the component type. Return a new list of substitutions are
+ needed, else the old list. */
+
+static tree
+split_complex_args (tree args)
+{
+ tree p;
+
+ /* Before allocating memory, check for the common case of no complex. */
+ for (p = args; p; p = TREE_CHAIN (p))
+ {
+ tree type = TREE_TYPE (p);
+ if (TREE_CODE (type) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (type))
+ goto found;
+ }
+ return args;
+
+ found:
+ args = copy_list (args);
+
+ for (p = args; p; p = TREE_CHAIN (p))
+ {
+ tree type = TREE_TYPE (p);
+ if (TREE_CODE (type) == COMPLEX_TYPE
+ && targetm.calls.split_complex_arg (type))
+ {
+ tree decl;
+ tree subtype = TREE_TYPE (type);
+
+ /* Rewrite the PARM_DECL's type with its component. */
+ TREE_TYPE (p) = subtype;
+ DECL_ARG_TYPE (p) = TREE_TYPE (DECL_ARG_TYPE (p));
+ DECL_MODE (p) = VOIDmode;
+ DECL_SIZE (p) = NULL;
+ DECL_SIZE_UNIT (p) = NULL;
+ layout_decl (p, 0);
+
+ /* Build a second synthetic decl. */
+ decl = build_decl (PARM_DECL, NULL_TREE, subtype);
+ DECL_ARG_TYPE (decl) = DECL_ARG_TYPE (p);
+ layout_decl (decl, 0);
+
+ /* Splice it in; skip the new decl. */
+ TREE_CHAIN (decl) = TREE_CHAIN (p);
+ TREE_CHAIN (p) = decl;
+ p = decl;
+ }
+ }
+
+ return args;
+}
/* Indicate whether REGNO is an incoming argument to the current function
that was promoted to a wider mode. If so, return the RTX for the
@@ -5219,13 +5429,8 @@ assign_parms (fndecl)
that REGNO is promoted from and whether the promotion was signed or
unsigned. */
-#ifdef PROMOTE_FUNCTION_ARGS
-
rtx
-promoted_input_arg (regno, pmode, punsignedp)
- unsigned int regno;
- enum machine_mode *pmode;
- int *punsignedp;
+promoted_input_arg (unsigned int regno, enum machine_mode *pmode, int *punsignedp)
{
tree arg;
@@ -5251,7 +5456,6 @@ promoted_input_arg (regno, pmode, punsignedp)
return 0;
}
-#endif
/* Compute the size and offset from the start of the stacked arguments for a
parm passed in mode PASSED_MODE and with type TYPE.
@@ -5259,8 +5463,11 @@ promoted_input_arg (regno, pmode, punsignedp)
INITIAL_OFFSET_PTR points to the current offset into the stacked
arguments.
- The starting offset and size for this parm are returned in *OFFSET_PTR
- and *ARG_SIZE_PTR, respectively.
+ The starting offset and size for this parm are returned in
+ LOCATE->OFFSET and LOCATE->SIZE, respectively. When IN_REGS is
+ nonzero, the offset is that of stack slot, which is returned in
+ LOCATE->SLOT_OFFSET. LOCATE->ALIGNMENT_PAD is the amount of
+ padding required from the initial offset ptr to the stack slot.
IN_REGS is nonzero if the argument will be passed in registers. It will
never be set if REG_PARM_STACK_SPACE is not defined.
@@ -5277,45 +5484,34 @@ promoted_input_arg (regno, pmode, punsignedp)
initial offset is not affected by this rounding, while the size always
is and the starting offset may be. */
-/* offset_ptr will be negative for ARGS_GROW_DOWNWARD case;
- initial_offset_ptr is positive because locate_and_pad_parm's
+/* LOCATE->OFFSET will be negative for ARGS_GROW_DOWNWARD case;
+ INITIAL_OFFSET_PTR is positive because locate_and_pad_parm's
callers pass in the total size of args so far as
- initial_offset_ptr. arg_size_ptr is always positive. */
+ INITIAL_OFFSET_PTR. LOCATE->SIZE is always positive. */
void
-locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
- initial_offset_ptr, offset_ptr, arg_size_ptr,
- alignment_pad)
- enum machine_mode passed_mode;
- tree type;
- int in_regs ATTRIBUTE_UNUSED;
- tree fndecl ATTRIBUTE_UNUSED;
- struct args_size *initial_offset_ptr;
- struct args_size *offset_ptr;
- struct args_size *arg_size_ptr;
- struct args_size *alignment_pad;
-
+locate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs,
+ int partial, tree fndecl ATTRIBUTE_UNUSED,
+ struct args_size *initial_offset_ptr,
+ struct locate_and_pad_arg_data *locate)
{
- tree sizetree
- = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
- enum direction where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
- int boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
-#ifdef ARGS_GROW_DOWNWARD
- tree s2 = sizetree;
-#endif
+ tree sizetree;
+ enum direction where_pad;
+ int boundary;
+ int reg_parm_stack_space = 0;
+ int part_size_in_regs;
#ifdef REG_PARM_STACK_SPACE
+#ifdef MAYBE_REG_PARM_STACK_SPACE
+ reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
+#else
+ reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
+#endif
+
/* If we have found a stack parm before we reach the end of the
area reserved for registers, skip that area. */
if (! in_regs)
{
- int reg_parm_stack_space = 0;
-
-#ifdef MAYBE_REG_PARM_STACK_SPACE
- reg_parm_stack_space = MAYBE_REG_PARM_STACK_SPACE;
-#else
- reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl);
-#endif
if (reg_parm_stack_space > 0)
{
if (initial_offset_ptr->var)
@@ -5331,54 +5527,57 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
}
#endif /* REG_PARM_STACK_SPACE */
- arg_size_ptr->var = 0;
- arg_size_ptr->constant = 0;
- alignment_pad->var = 0;
- alignment_pad->constant = 0;
+ part_size_in_regs = 0;
+ if (reg_parm_stack_space == 0)
+ part_size_in_regs = ((partial * UNITS_PER_WORD)
+ / (PARM_BOUNDARY / BITS_PER_UNIT)
+ * (PARM_BOUNDARY / BITS_PER_UNIT));
+
+ sizetree
+ = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode));
+ where_pad = FUNCTION_ARG_PADDING (passed_mode, type);
+ boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type);
+ locate->where_pad = where_pad;
#ifdef ARGS_GROW_DOWNWARD
+ locate->slot_offset.constant = -initial_offset_ptr->constant;
if (initial_offset_ptr->var)
- {
- offset_ptr->constant = 0;
- offset_ptr->var = size_binop (MINUS_EXPR, ssize_int (0),
- initial_offset_ptr->var);
- }
- else
- {
- offset_ptr->constant = -initial_offset_ptr->constant;
- offset_ptr->var = 0;
- }
+ locate->slot_offset.var = size_binop (MINUS_EXPR, ssize_int (0),
+ initial_offset_ptr->var);
- if (where_pad != none
- && (!host_integerp (sizetree, 1)
- || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
- s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
- SUB_PARM_SIZE (*offset_ptr, s2);
+ {
+ tree s2 = sizetree;
+ if (where_pad != none
+ && (!host_integerp (sizetree, 1)
+ || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
+ s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT);
+ SUB_PARM_SIZE (locate->slot_offset, s2);
+ }
+
+ locate->slot_offset.constant += part_size_in_regs;
if (!in_regs
#ifdef REG_PARM_STACK_SPACE
|| REG_PARM_STACK_SPACE (fndecl) > 0
#endif
)
- pad_to_arg_alignment (offset_ptr, boundary, alignment_pad);
+ pad_to_arg_alignment (&locate->slot_offset, boundary,
+ &locate->alignment_pad);
+ locate->size.constant = (-initial_offset_ptr->constant
+ - locate->slot_offset.constant);
if (initial_offset_ptr->var)
- arg_size_ptr->var = size_binop (MINUS_EXPR,
- size_binop (MINUS_EXPR,
- ssize_int (0),
- initial_offset_ptr->var),
- offset_ptr->var);
-
- else
- arg_size_ptr->constant = (-initial_offset_ptr->constant
- - offset_ptr->constant);
-
- /* Pad_below needs the pre-rounded size to know how much to pad below.
- We only pad parameters which are not in registers as they have their
- padding done elsewhere. */
- if (where_pad == downward
- && !in_regs)
- pad_below (offset_ptr, passed_mode, sizetree);
+ locate->size.var = size_binop (MINUS_EXPR,
+ size_binop (MINUS_EXPR,
+ ssize_int (0),
+ initial_offset_ptr->var),
+ locate->slot_offset.var);
+
+ /* Pad_below needs the pre-rounded size to know how much to pad
+ below. */
+ locate->offset = locate->slot_offset;
+ if (where_pad == downward)
+ pad_below (&locate->offset, passed_mode, sizetree);
#else /* !ARGS_GROW_DOWNWARD */
if (!in_regs
@@ -5386,8 +5585,9 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
|| REG_PARM_STACK_SPACE (fndecl) > 0
#endif
)
- pad_to_arg_alignment (initial_offset_ptr, boundary, alignment_pad);
- *offset_ptr = *initial_offset_ptr;
+ pad_to_arg_alignment (initial_offset_ptr, boundary,
+ &locate->alignment_pad);
+ locate->slot_offset = *initial_offset_ptr;
#ifdef PUSH_ROUNDING
if (passed_mode != BLKmode)
@@ -5396,18 +5596,18 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
/* Pad_below needs the pre-rounded size to know how much to pad below
so this must be done before rounding up. */
- if (where_pad == downward
- /* However, BLKmode args passed in regs have their padding done elsewhere.
- The stack slot must be able to hold the entire register. */
- && !(in_regs && passed_mode == BLKmode))
- pad_below (offset_ptr, passed_mode, sizetree);
+ locate->offset = locate->slot_offset;
+ if (where_pad == downward)
+ pad_below (&locate->offset, passed_mode, sizetree);
if (where_pad != none
&& (!host_integerp (sizetree, 1)
|| (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY))
sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT);
- ADD_PARM_SIZE (*arg_size_ptr, sizetree);
+ ADD_PARM_SIZE (locate->size, sizetree);
+
+ locate->size.constant -= part_size_in_regs;
#endif /* ARGS_GROW_DOWNWARD */
}
@@ -5415,15 +5615,22 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl,
BOUNDARY is measured in bits, but must be a multiple of a storage unit. */
static void
-pad_to_arg_alignment (offset_ptr, boundary, alignment_pad)
- struct args_size *offset_ptr;
- int boundary;
- struct args_size *alignment_pad;
+pad_to_arg_alignment (struct args_size *offset_ptr, int boundary,
+ struct args_size *alignment_pad)
{
tree save_var = NULL_TREE;
HOST_WIDE_INT save_constant = 0;
-
int boundary_in_bytes = boundary / BITS_PER_UNIT;
+ HOST_WIDE_INT sp_offset = STACK_POINTER_OFFSET;
+
+#ifdef SPARC_STACK_BOUNDARY_HACK
+ /* The sparc port has a bug. It sometimes claims a STACK_BOUNDARY
+ higher than the real alignment of %sp. However, when it does this,
+ the alignment of %sp+STACK_POINTER_OFFSET will be STACK_BOUNDARY.
+ This is a temporary hack while the sparc port is fixed. */
+ if (SPARC_STACK_BOUNDARY_HACK)
+ sp_offset = 0;
+#endif
if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
{
@@ -5438,26 +5645,30 @@ pad_to_arg_alignment (offset_ptr, boundary, alignment_pad)
{
if (offset_ptr->var)
{
- offset_ptr->var =
+ tree sp_offset_tree = ssize_int (sp_offset);
+ tree offset = size_binop (PLUS_EXPR,
+ ARGS_SIZE_TREE (*offset_ptr),
+ sp_offset_tree);
#ifdef ARGS_GROW_DOWNWARD
- round_down
+ tree rounded = round_down (offset, boundary / BITS_PER_UNIT);
#else
- round_up
+ tree rounded = round_up (offset, boundary / BITS_PER_UNIT);
#endif
- (ARGS_SIZE_TREE (*offset_ptr),
- boundary / BITS_PER_UNIT);
- offset_ptr->constant = 0; /*?*/
+
+ offset_ptr->var = size_binop (MINUS_EXPR, rounded, sp_offset_tree);
+ /* ARGS_SIZE_TREE includes constant term. */
+ offset_ptr->constant = 0;
if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var,
save_var);
}
else
{
- offset_ptr->constant =
+ offset_ptr->constant = -sp_offset +
#ifdef ARGS_GROW_DOWNWARD
- FLOOR_ROUND (offset_ptr->constant, boundary_in_bytes);
+ FLOOR_ROUND (offset_ptr->constant + sp_offset, boundary_in_bytes);
#else
- CEIL_ROUND (offset_ptr->constant, boundary_in_bytes);
+ CEIL_ROUND (offset_ptr->constant + sp_offset, boundary_in_bytes);
#endif
if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY)
alignment_pad->constant = offset_ptr->constant - save_constant;
@@ -5466,10 +5677,7 @@ pad_to_arg_alignment (offset_ptr, boundary, alignment_pad)
}
static void
-pad_below (offset_ptr, passed_mode, sizetree)
- struct args_size *offset_ptr;
- enum machine_mode passed_mode;
- tree sizetree;
+pad_below (struct args_size *offset_ptr, enum machine_mode passed_mode, tree sizetree)
{
if (passed_mode != BLKmode)
{
@@ -5499,8 +5707,7 @@ pad_below (offset_ptr, passed_mode, sizetree)
clobbers the pseudo-regs to hard regs. */
void
-uninitialized_vars_warning (block)
- tree block;
+uninitialized_vars_warning (tree block)
{
tree decl, sub;
for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
@@ -5512,26 +5719,26 @@ uninitialized_vars_warning (block)
flow.c that the entire aggregate was initialized.
Unions are troublesome because members may be shorter. */
&& ! AGGREGATE_TYPE_P (TREE_TYPE (decl))
- && DECL_RTL (decl) != 0
+ && DECL_RTL_SET_P (decl)
&& GET_CODE (DECL_RTL (decl)) == REG
/* Global optimizations can make it difficult to determine if a
particular variable has been initialized. However, a VAR_DECL
with a nonzero DECL_INITIAL had an initializer, so do not
claim it is potentially uninitialized.
- We do not care about the actual value in DECL_INITIAL, so we do
- not worry that it may be a dangling pointer. */
- && DECL_INITIAL (decl) == NULL_TREE
+ When the DECL_INITIAL is NULL call the language hook to tell us
+ if we want to warn. */
+ && (DECL_INITIAL (decl) == NULL_TREE || lang_hooks.decl_uninit (decl))
&& regno_uninitialized (REGNO (DECL_RTL (decl))))
- warning_with_decl (decl,
- "`%s' might be used uninitialized in this function");
+ warning ("%J'%D' might be used uninitialized in this function",
+ decl, decl);
if (extra_warnings
&& TREE_CODE (decl) == VAR_DECL
- && DECL_RTL (decl) != 0
+ && DECL_RTL_SET_P (decl)
&& GET_CODE (DECL_RTL (decl)) == REG
&& regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
- warning_with_decl (decl,
- "variable `%s' might be clobbered by `longjmp' or `vfork'");
+ warning ("%Jvariable '%D' might be clobbered by `longjmp' or `vfork'",
+ decl, decl);
}
for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub))
uninitialized_vars_warning (sub);
@@ -5541,7 +5748,7 @@ uninitialized_vars_warning (block)
but for arguments instead of local variables. */
void
-setjmp_args_warning ()
+setjmp_args_warning (void)
{
tree decl;
for (decl = DECL_ARGUMENTS (current_function_decl);
@@ -5549,16 +5756,15 @@ setjmp_args_warning ()
if (DECL_RTL (decl) != 0
&& GET_CODE (DECL_RTL (decl)) == REG
&& regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl))))
- warning_with_decl (decl,
- "argument `%s' might be clobbered by `longjmp' or `vfork'");
+ warning ("%Jargument '%D' might be clobbered by `longjmp' or `vfork'",
+ decl, decl);
}
/* If this function call setjmp, put all vars into the stack
unless they were declared `register'. */
void
-setjmp_protect (block)
- tree block;
+setjmp_protect (tree block)
{
tree decl, sub;
for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl))
@@ -5590,7 +5796,7 @@ setjmp_protect (block)
/* Like the previous function, but for args instead of local variables. */
void
-setjmp_protect_args ()
+setjmp_protect_args (void)
{
tree decl;
for (decl = DECL_ARGUMENTS (current_function_decl);
@@ -5616,8 +5822,7 @@ setjmp_protect_args ()
or 0 if it does not need one. */
rtx
-lookup_static_chain (decl)
- tree decl;
+lookup_static_chain (tree decl)
{
tree context = decl_function_context (decl);
tree link;
@@ -5645,9 +5850,7 @@ lookup_static_chain (decl)
into an address valid in this function (using a static chain). */
rtx
-fix_lexical_addr (addr, var)
- rtx addr;
- tree var;
+fix_lexical_addr (rtx addr, tree var)
{
rtx basereg;
HOST_WIDE_INT displacement;
@@ -5728,8 +5931,7 @@ fix_lexical_addr (addr, var)
and emit rtl to initialize its contents (at entry to this function). */
rtx
-trampoline_address (function)
- tree function;
+trampoline_address (tree function)
{
tree link;
tree rtlexp;
@@ -5761,19 +5963,13 @@ trampoline_address (function)
&& fn_context != inline_function_decl)
fp = find_function_data (fn_context);
- /* Allocate run-time space for this trampoline
- (usually in the defining function's stack frame). */
-#ifdef ALLOCATE_TRAMPOLINE
- tramp = ALLOCATE_TRAMPOLINE (fp);
-#else
+ /* Allocate run-time space for this trampoline. */
/* If rounding needed, allocate extra space
to ensure we have TRAMPOLINE_SIZE bytes left after rounding up. */
#define TRAMPOLINE_REAL_SIZE \
(TRAMPOLINE_SIZE + (TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT) - 1)
tramp = assign_stack_local_1 (BLKmode, TRAMPOLINE_REAL_SIZE, 0,
fp ? fp : cfun);
-#endif
-
/* Record the trampoline for reuse and note it for later initialization
by expand_function_end. */
if (fp != 0)
@@ -5801,8 +5997,7 @@ trampoline_address (function)
round it to multiple of TRAMPOLINE_ALIGNMENT. */
static rtx
-round_trampoline_addr (tramp)
- rtx tramp;
+round_trampoline_addr (rtx tramp)
{
/* Round address up to desired boundary. */
rtx temp = gen_reg_rtx (Pmode);
@@ -5822,8 +6017,7 @@ round_trampoline_addr (tramp)
function call . */
static rtx
-adjust_trampoline_addr (tramp)
- rtx tramp;
+adjust_trampoline_addr (rtx tramp)
{
tramp = round_trampoline_addr (tramp);
#ifdef TRAMPOLINE_ADJUST_ADDRESS
@@ -5840,7 +6034,7 @@ adjust_trampoline_addr (tramp)
and INSNS, the insn chain of the function. */
void
-identify_blocks ()
+identify_blocks (void)
{
int n_blocks;
tree *block_vector, *last_block_vector;
@@ -5853,7 +6047,7 @@ identify_blocks ()
/* Fill the BLOCK_VECTOR with all of the BLOCKs in this function, in
depth-first order. */
block_vector = get_block_vector (block, &n_blocks);
- block_stack = (tree *) xmalloc (n_blocks * sizeof (tree));
+ block_stack = xmalloc (n_blocks * sizeof (tree));
last_block_vector = identify_blocks_1 (get_insns (),
block_vector + 1,
@@ -5876,11 +6070,8 @@ identify_blocks ()
BLOCK_VECTOR is incremented for each block seen. */
static tree *
-identify_blocks_1 (insns, block_vector, end_block_vector, orig_block_stack)
- rtx insns;
- tree *block_vector;
- tree *end_block_vector;
- tree *orig_block_stack;
+identify_blocks_1 (rtx insns, tree *block_vector, tree *end_block_vector,
+ tree *orig_block_stack)
{
rtx insn;
tree *block_stack = orig_block_stack;
@@ -5943,7 +6134,7 @@ identify_blocks_1 (insns, block_vector, end_block_vector, orig_block_stack)
on what optimization has been performed. */
void
-reorder_blocks ()
+reorder_blocks (void)
{
tree block = DECL_INITIAL (current_function_decl);
varray_type block_stack;
@@ -5971,8 +6162,7 @@ reorder_blocks ()
/* Helper function for reorder_blocks. Reset TREE_ASM_WRITTEN. */
static void
-reorder_blocks_0 (block)
- tree block;
+reorder_blocks_0 (tree block)
{
while (block)
{
@@ -5983,10 +6173,7 @@ reorder_blocks_0 (block)
}
static void
-reorder_blocks_1 (insns, current_block, p_block_stack)
- rtx insns;
- tree current_block;
- varray_type *p_block_stack;
+reorder_blocks_1 (rtx insns, tree current_block, varray_type *p_block_stack)
{
rtx insn;
@@ -6019,10 +6206,16 @@ reorder_blocks_1 (insns, current_block, p_block_stack)
BLOCK_SUBBLOCKS (block) = 0;
TREE_ASM_WRITTEN (block) = 1;
- BLOCK_SUPERCONTEXT (block) = current_block;
- BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
- BLOCK_SUBBLOCKS (current_block) = block;
- current_block = block;
+ /* When there's only one block for the entire function,
+ current_block == block and we mustn't do this, it
+ will cause infinite recursion. */
+ if (block != current_block)
+ {
+ BLOCK_SUPERCONTEXT (block) = current_block;
+ BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block);
+ BLOCK_SUBBLOCKS (current_block) = block;
+ current_block = block;
+ }
VARRAY_PUSH_TREE (*p_block_stack, block);
}
else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END)
@@ -6052,8 +6245,7 @@ reorder_blocks_1 (insns, current_block, p_block_stack)
the new origin block. */
static void
-reorder_fix_fragments (block)
- tree block;
+reorder_fix_fragments (tree block)
{
while (block)
{
@@ -6107,8 +6299,7 @@ reorder_fix_fragments (block)
and return the new head of the chain (old last element). */
static tree
-blocks_nreverse (t)
- tree t;
+blocks_nreverse (tree t)
{
tree prev = 0, decl, next;
for (decl = t; decl; decl = next)
@@ -6126,9 +6317,7 @@ blocks_nreverse (t)
blocks. */
static int
-all_blocks (block, vector)
- tree block;
- tree *vector;
+all_blocks (tree block, tree *vector)
{
int n_blocks = 0;
@@ -6157,26 +6346,23 @@ all_blocks (block, vector)
to call `free' on the pointer returned. */
static tree *
-get_block_vector (block, n_blocks_p)
- tree block;
- int *n_blocks_p;
+get_block_vector (tree block, int *n_blocks_p)
{
tree *block_vector;
*n_blocks_p = all_blocks (block, NULL);
- block_vector = (tree *) xmalloc (*n_blocks_p * sizeof (tree));
+ block_vector = xmalloc (*n_blocks_p * sizeof (tree));
all_blocks (block, block_vector);
return block_vector;
}
-static int next_block_index = 2;
+static GTY(()) int next_block_index = 2;
/* Set BLOCK_NUMBER for all the blocks in FN. */
void
-number_blocks (fn)
- tree fn;
+number_blocks (tree fn)
{
int i;
int n_blocks;
@@ -6205,9 +6391,7 @@ number_blocks (fn)
/* If VAR is present in a subblock of BLOCK, return the subblock. */
tree
-debug_find_var_in_block_tree (var, block)
- tree var;
- tree block;
+debug_find_var_in_block_tree (tree var, tree block)
{
tree t;
@@ -6225,101 +6409,75 @@ debug_find_var_in_block_tree (var, block)
return NULL_TREE;
}
-/* Allocate a function structure and reset its contents to the defaults. */
+/* Allocate a function structure for FNDECL and set its contents
+ to the defaults. */
-static void
-prepare_function_start ()
+void
+allocate_struct_function (tree fndecl)
{
- cfun = (struct function *) ggc_alloc_cleared (sizeof (struct function));
-
- init_stmt_for_function ();
- init_eh_for_function ();
-
- cse_not_expected = ! optimize;
-
- /* Caller save not needed yet. */
- caller_save_needed = 0;
-
- /* No stack slots have been made yet. */
- stack_slot_list = 0;
-
- current_function_has_nonlocal_label = 0;
- current_function_has_nonlocal_goto = 0;
-
- /* There is no stack slot for handling nonlocal gotos. */
- nonlocal_goto_handler_slots = 0;
- nonlocal_goto_stack_level = 0;
+ tree result;
- /* No labels have been declared for nonlocal use. */
- nonlocal_labels = 0;
- nonlocal_goto_handler_labels = 0;
+ cfun = ggc_alloc_cleared (sizeof (struct function));
- /* No function calls so far in this function. */
- function_call_count = 0;
-
- /* No parm regs have been allocated.
- (This is important for output_inline_function.) */
max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
- /* Initialize the RTL mechanism. */
- init_emit ();
-
- /* Initialize the queue of pending postincrement and postdecrements,
- and some other info in expr.c. */
- init_expr ();
+ cfun->stack_alignment_needed = STACK_BOUNDARY;
+ cfun->preferred_stack_boundary = STACK_BOUNDARY;
- /* We haven't done register allocation yet. */
- reg_renumber = 0;
+ current_function_funcdef_no = funcdef_no++;
- init_varasm_status (cfun);
+ cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;
- /* Clear out data used for inlining. */
- cfun->inlinable = 0;
- cfun->original_decl_initial = 0;
- cfun->original_arg_vector = 0;
+ init_stmt_for_function ();
+ init_eh_for_function ();
- cfun->stack_alignment_needed = STACK_BOUNDARY;
- cfun->preferred_stack_boundary = STACK_BOUNDARY;
+ (*lang_hooks.function.init) (cfun);
+ if (init_machine_status)
+ cfun->machine = (*init_machine_status) ();
- /* Set if a call to setjmp is seen. */
- current_function_calls_setjmp = 0;
+ if (fndecl == NULL)
+ return;
- /* Set if a call to longjmp is seen. */
- current_function_calls_longjmp = 0;
+ DECL_SAVED_INSNS (fndecl) = cfun;
+ cfun->decl = fndecl;
- current_function_calls_alloca = 0;
- current_function_contains_functions = 0;
- current_function_is_leaf = 0;
- current_function_nothrow = 0;
- current_function_sp_is_unchanging = 0;
- current_function_uses_only_leaf_regs = 0;
- current_function_has_computed_jump = 0;
- current_function_is_thunk = 0;
+ result = DECL_RESULT (fndecl);
+ if (aggregate_value_p (result, fndecl))
+ {
+#ifdef PCC_STATIC_STRUCT_RETURN
+ current_function_returns_pcc_struct = 1;
+#endif
+ current_function_returns_struct = 1;
+ }
- current_function_returns_pcc_struct = 0;
- current_function_returns_struct = 0;
- current_function_epilogue_delay_list = 0;
- current_function_uses_const_pool = 0;
- current_function_uses_pic_offset_table = 0;
- current_function_cannot_inline = 0;
+ current_function_returns_pointer = POINTER_TYPE_P (TREE_TYPE (result));
- /* We have not yet needed to make a label to jump to for tail-recursion. */
- tail_recursion_label = 0;
+ current_function_needs_context
+ = (decl_function_context (current_function_decl) != 0
+ && ! DECL_NO_STATIC_CHAIN (current_function_decl));
+}
- /* We haven't had a need to make a save area for ap yet. */
- arg_pointer_save_area = 0;
+/* Reset cfun, and other non-struct-function variables to defaults as
+ appropriate for emitting rtl at the start of a function. */
- /* No stack slots allocated yet. */
- frame_offset = 0;
+static void
+prepare_function_start (tree fndecl)
+{
+ if (fndecl && DECL_SAVED_INSNS (fndecl))
+ cfun = DECL_SAVED_INSNS (fndecl);
+ else
+ allocate_struct_function (fndecl);
+ init_emit ();
+ init_varasm_status (cfun);
+ init_expr ();
- /* No SAVE_EXPRs in this function yet. */
- save_expr_regs = 0;
+ cse_not_expected = ! optimize;
- /* No RTL_EXPRs in this function yet. */
- rtl_expr_chain = 0;
+ /* Caller save not needed yet. */
+ caller_save_needed = 0;
- /* Set up to allocate temporaries. */
- init_temp_slots ();
+ /* We haven't done register allocation yet. */
+ reg_renumber = 0;
/* Indicate that we need to distinguish between the return value of the
present function and the return value of a function being called. */
@@ -6333,40 +6491,15 @@ prepare_function_start ()
/* Indicate we have no need of a frame pointer yet. */
frame_pointer_needed = 0;
-
- /* By default assume not stdarg. */
- current_function_stdarg = 0;
-
- /* We haven't made any trampolines for this function yet. */
- trampoline_list = 0;
-
- init_pending_stack_adjust ();
- inhibit_defer_pop = 0;
-
- current_function_outgoing_args_size = 0;
-
- current_function_funcdef_no = funcdef_no++;
-
- cfun->arc_profile = profile_arc_flag || flag_test_coverage;
-
- cfun->arc_profile = profile_arc_flag || flag_test_coverage;
-
- cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;
-
- cfun->max_jumptable_ents = 0;
-
- (*lang_hooks.function.init) (cfun);
- if (init_machine_status)
- cfun->machine = (*init_machine_status) ();
}
/* Initialize the rtl expansion mechanism so that we can do simple things
like generate sequences. This is used to provide a context during global
initialization of some passes. */
void
-init_dummy_function_start ()
+init_dummy_function_start (void)
{
- prepare_function_start ();
+ prepare_function_start (NULL);
}
/* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node)
@@ -6374,59 +6507,36 @@ init_dummy_function_start ()
of the function. */
void
-init_function_start (subr, filename, line)
- tree subr;
- const char *filename;
- int line;
+init_function_start (tree subr)
{
- prepare_function_start ();
-
- current_function_name = (*lang_hooks.decl_printable_name) (subr, 2);
- cfun->decl = subr;
-
- /* Nonzero if this is a nested function that uses a static chain. */
-
- current_function_needs_context
- = (decl_function_context (current_function_decl) != 0
- && ! DECL_NO_STATIC_CHAIN (current_function_decl));
+ prepare_function_start (subr);
/* Within function body, compute a type's size as soon it is laid out. */
immediate_size_expand++;
- /* Prevent ever trying to delete the first instruction of a function.
- Also tell final how to output a linenum before the function prologue.
- Note linenums could be missing, e.g. when compiling a Java .class file. */
- if (line > 0)
- emit_line_note (filename, line);
+ /* Prevent ever trying to delete the first instruction of a
+ function. Also tell final how to output a linenum before the
+ function prologue. Note linenums could be missing, e.g. when
+ compiling a Java .class file. */
+ if (DECL_SOURCE_LINE (subr))
+ emit_line_note (DECL_SOURCE_LOCATION (subr));
/* Make sure first insn is a note even if we don't want linenums.
This makes sure the first insn will never be deleted.
Also, final expects a note to appear there. */
- emit_note (NULL, NOTE_INSN_DELETED);
-
- /* Set flags used by final.c. */
- if (aggregate_value_p (DECL_RESULT (subr)))
- {
-#ifdef PCC_STATIC_STRUCT_RETURN
- current_function_returns_pcc_struct = 1;
-#endif
- current_function_returns_struct = 1;
- }
+ emit_note (NOTE_INSN_DELETED);
/* Warn if this value is an aggregate type,
regardless of which calling convention we are using for it. */
if (warn_aggregate_return
&& AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr))))
warning ("function returns an aggregate");
-
- current_function_returns_pointer
- = POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (subr)));
}
/* Make sure all values used by the optimization passes have sane
defaults. */
void
-init_function_for_compilation ()
+init_function_for_compilation (void)
{
reg_renumber = 0;
@@ -6444,7 +6554,7 @@ init_function_for_compilation ()
#endif
void
-expand_main_function ()
+expand_main_function (void)
{
#ifdef FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
if (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN)
@@ -6483,8 +6593,7 @@ expand_main_function ()
#endif
#ifndef HAS_INIT_SECTION
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, NAME__MAIN), LCT_NORMAL,
- VOIDmode, 0);
+ emit_library_call (init_one_libfunc (NAME__MAIN), LCT_NORMAL, VOIDmode, 0);
#endif
}
@@ -6495,8 +6604,7 @@ expand_main_function ()
TREE_VALUE of each node is a SAVE_EXPR. */
void
-expand_pending_sizes (pending_sizes)
- tree pending_sizes;
+expand_pending_sizes (tree pending_sizes)
{
tree tem;
@@ -6517,9 +6625,7 @@ expand_pending_sizes (pending_sizes)
the function's parameters, which must be run at any return statement. */
void
-expand_function_start (subr, parms_have_cleanups)
- tree subr;
- int parms_have_cleanups;
+expand_function_start (tree subr, int parms_have_cleanups)
{
tree tem;
rtx last_ptr = NULL_RTX;
@@ -6570,7 +6676,7 @@ expand_function_start (subr, parms_have_cleanups)
before any library calls that assign parms might generate. */
/* Decide whether to return the value in memory or in a register. */
- if (aggregate_value_p (DECL_RESULT (subr)))
+ if (aggregate_value_p (DECL_RESULT (subr), subr))
{
/* Returning something that won't go in a register. */
rtx value_address = 0;
@@ -6584,13 +6690,14 @@ expand_function_start (subr, parms_have_cleanups)
else
#endif
{
+ rtx sv = targetm.calls.struct_value_rtx (TREE_TYPE (subr), 1);
/* Expect to be passed the address of a place to store the value.
If it is passed as an argument, assign_parms will take care of
it. */
- if (struct_value_incoming_rtx)
+ if (sv)
{
value_address = gen_reg_rtx (Pmode);
- emit_move_insn (value_address, struct_value_incoming_rtx);
+ emit_move_insn (value_address, sv);
}
}
if (value_address)
@@ -6645,10 +6752,10 @@ expand_function_start (subr, parms_have_cleanups)
The move is supposed to make sdb output more accurate. */
/* Indicate the beginning of the function body,
as opposed to parm setup. */
- emit_note (NULL, NOTE_INSN_FUNCTION_BEG);
+ emit_note (NOTE_INSN_FUNCTION_BEG);
if (GET_CODE (get_last_insn ()) != NOTE)
- emit_note (NULL, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
parm_birth_insn = get_last_insn ();
context_display = 0;
@@ -6679,7 +6786,7 @@ expand_function_start (subr, parms_have_cleanups)
tem = decl_function_context (tem);
if (tem == 0)
break;
- /* Chain thru stack frames, assuming pointer to next lexical frame
+ /* Chain through stack frames, assuming pointer to next lexical frame
is found at the place we always store it. */
#ifdef FRAME_GROWS_DOWNWARD
last_ptr = plus_constant (last_ptr,
@@ -6722,7 +6829,7 @@ expand_function_start (subr, parms_have_cleanups)
/* After the display initializations is where the tail-recursion label
should go, if we end up needing one. Ensure we have a NOTE here
since some things (like trampolines) get placed before this. */
- tail_recursion_reentry = emit_note (NULL, NOTE_INSN_DELETED);
+ tail_recursion_reentry = emit_note (NOTE_INSN_DELETED);
/* Evaluate now the sizes of any types declared among the arguments. */
expand_pending_sizes (nreverse (get_pending_sizes ()));
@@ -6733,7 +6840,7 @@ expand_function_start (subr, parms_have_cleanups)
/* Undo the effects of init_dummy_function_start. */
void
-expand_dummy_function_end ()
+expand_dummy_function_end (void)
{
/* End any sequences that failed to be closed due to syntax errors. */
while (in_sequence_p ())
@@ -6751,9 +6858,7 @@ expand_dummy_function_end ()
the current function. */
void
-diddle_return_value (doit, arg)
- void (*doit) PARAMS ((rtx, void *));
- void *arg;
+diddle_return_value (void (*doit) (rtx, void *), void *arg)
{
rtx outgoing = current_function_return_rtx;
@@ -6777,15 +6882,13 @@ diddle_return_value (doit, arg)
}
static void
-do_clobber_return_reg (reg, arg)
- rtx reg;
- void *arg ATTRIBUTE_UNUSED;
+do_clobber_return_reg (rtx reg, void *arg ATTRIBUTE_UNUSED)
{
emit_insn (gen_rtx_CLOBBER (VOIDmode, reg));
}
void
-clobber_return_register ()
+clobber_return_register (void)
{
diddle_return_value (do_clobber_return_reg, NULL);
@@ -6802,32 +6905,36 @@ clobber_return_register ()
}
static void
-do_use_return_reg (reg, arg)
- rtx reg;
- void *arg ATTRIBUTE_UNUSED;
+do_use_return_reg (rtx reg, void *arg ATTRIBUTE_UNUSED)
{
emit_insn (gen_rtx_USE (VOIDmode, reg));
}
void
-use_return_register ()
+use_return_register (void)
{
diddle_return_value (do_use_return_reg, NULL);
}
-static GTY(()) rtx initial_trampoline;
+/* Possibly warn about unused parameters. */
+void
+do_warn_unused_parameter (tree fn)
+{
+ tree decl;
-/* Generate RTL for the end of the current function.
- FILENAME and LINE are the current position in the source file.
+ for (decl = DECL_ARGUMENTS (fn);
+ decl; decl = TREE_CHAIN (decl))
+ if (!TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
+ && DECL_NAME (decl) && !DECL_ARTIFICIAL (decl))
+ warning ("%Junused parameter '%D'", decl, decl);
+}
+
+static GTY(()) rtx initial_trampoline;
- It is up to language-specific callers to do cleanups for parameters--
- or else, supply 1 for END_BINDINGS and we will call expand_end_bindings. */
+/* Generate RTL for the end of the current function. */
void
-expand_function_end (filename, line, end_bindings)
- const char *filename;
- int line;
- int end_bindings;
+expand_function_end (void)
{
tree link;
rtx clobber_after;
@@ -6881,6 +6988,7 @@ expand_function_end (filename, line, end_bindings)
emit_block_move (blktramp, initial_trampoline,
GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
#endif
+ trampolines_created = 1;
INITIALIZE_TRAMPOLINE (tramp, XEXP (DECL_RTL (function), 0), context);
seq = get_insns ();
end_sequence ();
@@ -6909,21 +7017,12 @@ expand_function_end (filename, line, end_bindings)
}
}
- /* Warn about unused parms if extra warnings were specified. */
- /* Either ``-W -Wunused'' or ``-Wunused-parameter'' enables this
- warning. WARN_UNUSED_PARAMETER is negative when set by
- -Wunused. */
- if (warn_unused_parameter > 0
- || (warn_unused_parameter < 0 && extra_warnings))
- {
- tree decl;
-
- for (decl = DECL_ARGUMENTS (current_function_decl);
- decl; decl = TREE_CHAIN (decl))
- if (! TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL
- && DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
- warning_with_decl (decl, "unused parameter `%s'");
- }
+ /* Possibly warn about unused parameters.
+ When frontend does unit-at-a-time, the warning is already
+ issued at finalization time. */
+ if (warn_unused_parameter
+ && !lang_hooks.callgraph.expand_function)
+ do_warn_unused_parameter (current_function_decl);
/* Delete handlers for nonlocal gotos if nothing uses them. */
if (nonlocal_goto_handler_slots != 0
@@ -6941,10 +7040,18 @@ expand_function_end (filename, line, end_bindings)
clear_pending_stack_adjust ();
do_pending_stack_adjust ();
+ /* ??? This is a kludge. We want to ensure that instructions that
+ may trap are not moved into the epilogue by scheduling, because
+ we don't always emit unwind information for the epilogue.
+ However, not all machine descriptions define a blockage insn, so
+ emit an ASM_INPUT to act as one. */
+ if (flag_non_call_exceptions)
+ emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
+
/* Mark the end of the function body.
If control reaches this insn, the function can drop through
without returning a value. */
- emit_note (NULL, NOTE_INSN_FUNCTION_END);
+ emit_note (NOTE_INSN_FUNCTION_END);
/* Must mark the last line number note in the function, so that the test
coverage code can avoid counting the last line twice. This just tells
@@ -6952,11 +7059,12 @@ expand_function_end (filename, line, end_bindings)
already exists a copy of this note somewhere above. This line number
note is still needed for debugging though, so we can't delete it. */
if (flag_test_coverage)
- emit_note (NULL, NOTE_INSN_REPEATED_LINE_NUMBER);
+ emit_note (NOTE_INSN_REPEATED_LINE_NUMBER);
/* Output a linenumber for the end of the function.
SDB depends on this. */
- emit_line_note_force (filename, line);
+ force_next_line_note ();
+ emit_line_note (input_location);
/* Before the return label (if any), clobber the return
registers so that they are not propagated live to the rest of
@@ -6976,10 +7084,6 @@ expand_function_end (filename, line, end_bindings)
if (return_label)
emit_label (return_label);
- /* C++ uses this. */
- if (end_bindings)
- expand_end_bindings (0, 0, 0);
-
if (current_function_instrument_entry_exit)
{
rtx fun = DECL_RTL (current_function_decl);
@@ -7003,16 +7107,14 @@ expand_function_end (filename, line, end_bindings)
/* If we had calls to alloca, and this machine needs
an accurate stack pointer to exit the function,
insert some code to save and restore the stack pointer. */
-#ifdef EXIT_IGNORE_STACK
- if (! EXIT_IGNORE_STACK)
-#endif
- if (current_function_calls_alloca)
- {
- rtx tem = 0;
+ if (! EXIT_IGNORE_STACK
+ && current_function_calls_alloca)
+ {
+ rtx tem = 0;
- emit_stack_save (SAVE_FUNCTION, &tem, parm_birth_insn);
- emit_stack_restore (SAVE_FUNCTION, tem, NULL_RTX);
- }
+ emit_stack_save (SAVE_FUNCTION, &tem, parm_birth_insn);
+ emit_stack_restore (SAVE_FUNCTION, tem, NULL_RTX);
+ }
/* If scalar return value was computed in a pseudo-reg, or was a named
return value that got dumped to the stack, copy that to the hard
@@ -7046,10 +7148,9 @@ expand_function_end (filename, line, end_bindings)
{
int unsignedp = TREE_UNSIGNED (TREE_TYPE (decl_result));
-#ifdef PROMOTE_FUNCTION_RETURN
- promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
- &unsignedp, 1);
-#endif
+ if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
+ promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl),
+ &unsignedp, 1);
convert_move (real_decl_rtl, decl_rtl, unsignedp);
}
@@ -7062,6 +7163,7 @@ expand_function_end (filename, line, end_bindings)
emit_group_move (real_decl_rtl, decl_rtl);
else
emit_group_load (real_decl_rtl, decl_rtl,
+ TREE_TYPE (decl_result),
int_size_in_bytes (TREE_TYPE (decl_result)));
}
else
@@ -7094,12 +7196,9 @@ expand_function_end (filename, line, end_bindings)
assignment and USE below when inlining this function. */
REG_FUNCTION_VALUE_P (outgoing) = 1;
-#ifdef POINTERS_EXTEND_UNSIGNED
/* The address may be ptr_mode and OUTGOING may be Pmode. */
- if (GET_MODE (outgoing) != GET_MODE (value_address))
- value_address = convert_memory_address (GET_MODE (outgoing),
- value_address);
-#endif
+ value_address = convert_memory_address (GET_MODE (outgoing),
+ value_address);
emit_move_insn (outgoing, value_address);
@@ -7127,6 +7226,11 @@ expand_function_end (filename, line, end_bindings)
cfun->x_clobber_return_insn = after;
}
+ /* Output the label for the naked return from the function, if one is
+ expected. This is currently used only by __builtin_return. */
+ if (naked_return_label)
+ emit_label (naked_return_label);
+
/* ??? This should no longer be necessary since stupid is no longer with
us, but there are some parts of the compiler (eg reload_combine, and
sh mach_dep_reorg) that still try and compute their own lifetime info
@@ -7144,8 +7248,7 @@ expand_function_end (filename, line, end_bindings)
}
rtx
-get_arg_pointer_save_area (f)
- struct function *f;
+get_arg_pointer_save_area (struct function *f)
{
rtx ret = f->x_arg_pointer_save_area;
@@ -7179,9 +7282,7 @@ get_arg_pointer_save_area (f)
(a list of one or more insns). */
static void
-record_insns (insns, vecp)
- rtx insns;
- varray_type *vecp;
+record_insns (rtx insns, varray_type *vecp)
{
int i, len;
rtx tmp;
@@ -7205,13 +7306,23 @@ record_insns (insns, vecp)
}
}
+/* Set the locator of the insn chain starting at INSN to LOC. */
+static void
+set_insn_locators (rtx insn, int loc)
+{
+ while (insn != NULL_RTX)
+ {
+ if (INSN_P (insn))
+ INSN_LOCATOR (insn) = loc;
+ insn = NEXT_INSN (insn);
+ }
+}
+
/* Determine how many INSN_UIDs in VEC are part of INSN. Because we can
be running after reorg, SEQUENCE rtl is possible. */
static int
-contains (insn, vec)
- rtx insn;
- varray_type vec;
+contains (rtx insn, varray_type vec)
{
int i, j;
@@ -7235,8 +7346,7 @@ contains (insn, vec)
}
int
-prologue_epilogue_contains (insn)
- rtx insn;
+prologue_epilogue_contains (rtx insn)
{
if (contains (insn, prologue))
return 1;
@@ -7246,8 +7356,7 @@ prologue_epilogue_contains (insn)
}
int
-sibcall_epilogue_contains (insn)
- rtx insn;
+sibcall_epilogue_contains (rtx insn)
{
if (sibcall_epilogue)
return contains (insn, sibcall_epilogue);
@@ -7259,17 +7368,11 @@ sibcall_epilogue_contains (insn)
block_for_insn appropriately. */
static void
-emit_return_into_block (bb, line_note)
- basic_block bb;
- rtx line_note;
+emit_return_into_block (basic_block bb, rtx line_note)
{
- rtx p, end;
-
- p = NEXT_INSN (bb->end);
- end = emit_jump_insn_after (gen_return (), bb->end);
+ emit_jump_insn_after (gen_return (), BB_END (bb));
if (line_note)
- emit_line_note_after (NOTE_SOURCE_FILE (line_note),
- NOTE_LINE_NUMBER (line_note), PREV_INSN (bb->end));
+ emit_note_copy_after (line_note, PREV_INSN (BB_END (bb)));
}
#endif /* HAVE_return */
@@ -7313,24 +7416,25 @@ struct epi_info
rtx equiv_reg_src; /* If nonzero, the value that SP_EQUIV_REG
should be set to once we no longer need
its value. */
+ rtx const_equiv[FIRST_PSEUDO_REGISTER]; /* Any known constant equivalences
+ for registers. */
};
-static void handle_epilogue_set PARAMS ((rtx, struct epi_info *));
-static void emit_equiv_load PARAMS ((struct epi_info *));
+static void handle_epilogue_set (rtx, struct epi_info *);
+static void update_epilogue_consts (rtx, rtx, void *);
+static void emit_equiv_load (struct epi_info *);
/* Modify INSN, a list of one or more insns that is part of the epilogue, to
no modifications to the stack pointer. Return the new list of insns. */
static rtx
-keep_stack_depressed (insns)
- rtx insns;
+keep_stack_depressed (rtx insns)
{
int j;
struct epi_info info;
rtx insn, next;
- /* If the epilogue is just a single instruction, it ust be OK as is. */
-
+ /* If the epilogue is just a single instruction, it must be OK as is. */
if (NEXT_INSN (insns) == NULL_RTX)
return insns;
@@ -7342,6 +7446,9 @@ keep_stack_depressed (insns)
info.sp_offset = 0;
info.equiv_reg_src = 0;
+ for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
+ info.const_equiv[j] = 0;
+
insn = insns;
next = NULL_RTX;
while (insn != NULL_RTX)
@@ -7433,7 +7540,8 @@ keep_stack_depressed (insns)
&& !refers_to_regno_p (regno,
regno + HARD_REGNO_NREGS (regno,
Pmode),
- info.equiv_reg_src, NULL))
+ info.equiv_reg_src, NULL)
+ && info.const_equiv[regno] == 0)
break;
if (regno == FIRST_PSEUDO_REGISTER)
@@ -7489,6 +7597,8 @@ keep_stack_depressed (insns)
info.sp_equiv_reg = info.new_sp_equiv_reg;
info.sp_offset = info.new_sp_offset;
+ /* Now update any constants this insn sets. */
+ note_stores (PATTERN (insn), update_epilogue_consts, &info);
insn = next;
}
@@ -7503,9 +7613,7 @@ keep_stack_depressed (insns)
more insns. */
static void
-handle_epilogue_set (set, p)
- rtx set;
- struct epi_info *p;
+handle_epilogue_set (rtx set, struct epi_info *p)
{
/* First handle the case where we are setting SP. Record what it is being
set from. If unknown, abort. */
@@ -7514,11 +7622,18 @@ handle_epilogue_set (set, p)
if (SET_DEST (set) != stack_pointer_rtx)
abort ();
- if (GET_CODE (SET_SRC (set)) == PLUS
- && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
+ if (GET_CODE (SET_SRC (set)) == PLUS)
{
p->new_sp_equiv_reg = XEXP (SET_SRC (set), 0);
- p->new_sp_offset = INTVAL (XEXP (SET_SRC (set), 1));
+ if (GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
+ p->new_sp_offset = INTVAL (XEXP (SET_SRC (set), 1));
+ else if (GET_CODE (XEXP (SET_SRC (set), 1)) == REG
+ && REGNO (XEXP (SET_SRC (set), 1)) < FIRST_PSEUDO_REGISTER
+ && p->const_equiv[REGNO (XEXP (SET_SRC (set), 1))] != 0)
+ p->new_sp_offset
+ = INTVAL (p->const_equiv[REGNO (XEXP (SET_SRC (set), 1))]);
+ else
+ abort ();
}
else
p->new_sp_equiv_reg = SET_SRC (set), p->new_sp_offset = 0;
@@ -7541,11 +7656,16 @@ handle_epilogue_set (set, p)
there seems little point in handling that case. Note that we have
to allow for the case where we are setting the register set in
the previous part of a PARALLEL inside a single insn. But use the
- old offset for any updates within this insn. */
+ old offset for any updates within this insn. We must allow for the case
+ where the register is being set in a different (usually wider) mode than
+ Pmode). */
else if (p->new_sp_equiv_reg != 0 && reg_set_p (p->new_sp_equiv_reg, set))
{
- if (!rtx_equal_p (p->new_sp_equiv_reg, SET_DEST (set))
- || p->equiv_reg_src != 0)
+ if (p->equiv_reg_src != 0
+ || GET_CODE (p->new_sp_equiv_reg) != REG
+ || GET_CODE (SET_DEST (set)) != REG
+ || GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) > BITS_PER_WORD
+ || REGNO (p->new_sp_equiv_reg) != REGNO (SET_DEST (set)))
abort ();
else
p->equiv_reg_src
@@ -7568,16 +7688,38 @@ handle_epilogue_set (set, p)
}
}
+/* Update the tracking information for registers set to constants. */
+
+static void
+update_epilogue_consts (rtx dest, rtx x, void *data)
+{
+ struct epi_info *p = (struct epi_info *) data;
+
+ if (GET_CODE (dest) != REG || REGNO (dest) >= FIRST_PSEUDO_REGISTER)
+ return;
+ else if (GET_CODE (x) == CLOBBER || ! rtx_equal_p (dest, SET_DEST (x))
+ || GET_CODE (SET_SRC (x)) != CONST_INT)
+ p->const_equiv[REGNO (dest)] = 0;
+ else
+ p->const_equiv[REGNO (dest)] = SET_SRC (x);
+}
+
/* Emit an insn to do the load shown in p->equiv_reg_src, if needed. */
static void
-emit_equiv_load (p)
- struct epi_info *p;
+emit_equiv_load (struct epi_info *p)
{
if (p->equiv_reg_src != 0)
- emit_move_insn (p->sp_equiv_reg, p->equiv_reg_src);
+ {
+ rtx dest = p->sp_equiv_reg;
+
+ if (GET_MODE (p->equiv_reg_src) != GET_MODE (dest))
+ dest = gen_rtx_REG (GET_MODE (p->equiv_reg_src),
+ REGNO (p->sp_equiv_reg));
- p->equiv_reg_src = 0;
+ emit_move_insn (dest, p->equiv_reg_src);
+ p->equiv_reg_src = 0;
+ }
}
#endif
@@ -7586,8 +7728,7 @@ emit_equiv_load (p)
the epilogue begins. Update the basic block information when possible. */
void
-thread_prologue_and_epilogue_insns (f)
- rtx f ATTRIBUTE_UNUSED;
+thread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED)
{
int inserted = 0;
edge e;
@@ -7610,10 +7751,11 @@ thread_prologue_and_epilogue_insns (f)
/* Retain a map of the prologue insns. */
record_insns (seq, &prologue);
- prologue_end = emit_note (NULL, NOTE_INSN_PROLOGUE_END);
+ prologue_end = emit_note (NOTE_INSN_PROLOGUE_END);
seq = get_insns ();
end_sequence ();
+ set_insn_locators (seq, prologue_locator);
/* Can't deal with multiple successors of the entry block
at the moment. Function should always have at least one
@@ -7655,7 +7797,7 @@ thread_prologue_and_epilogue_insns (f)
last = e->src;
/* Verify that there are no active instructions in the last block. */
- label = last->end;
+ label = BB_END (last);
while (label && GET_CODE (label) != CODE_LABEL)
{
if (active_insn_p (label))
@@ -7663,7 +7805,7 @@ thread_prologue_and_epilogue_insns (f)
label = PREV_INSN (label);
}
- if (last->head == label && GET_CODE (label) == CODE_LABEL)
+ if (BB_HEAD (last) == label && GET_CODE (label) == CODE_LABEL)
{
rtx epilogue_line_note = NULL_RTX;
@@ -7687,7 +7829,7 @@ thread_prologue_and_epilogue_insns (f)
if (bb == ENTRY_BLOCK_PTR)
continue;
- jump = bb->end;
+ jump = BB_END (bb);
if ((GET_CODE (jump) != JUMP_INSN) || JUMP_LABEL (jump) != label)
continue;
@@ -7722,9 +7864,9 @@ thread_prologue_and_epilogue_insns (f)
/* Emit a return insn for the exit fallthru block. Whether
this is still reachable will be determined later. */
- emit_barrier_after (last->end);
+ emit_barrier_after (BB_END (last));
emit_return_into_block (last, epilogue_line_note);
- epilogue_end = last->end;
+ epilogue_end = BB_END (last);
last->succ->flags &= ~EDGE_FALLTHRU;
goto epilogue_done;
}
@@ -7745,7 +7887,7 @@ thread_prologue_and_epilogue_insns (f)
goto epilogue_done;
start_sequence ();
- epilogue_end = emit_note (NULL, NOTE_INSN_EPILOGUE_BEG);
+ epilogue_end = emit_note (NOTE_INSN_EPILOGUE_BEG);
seq = gen_epilogue ();
@@ -7761,6 +7903,7 @@ thread_prologue_and_epilogue_insns (f)
/* Retain a map of the epilogue insns. */
record_insns (seq, &epilogue);
+ set_insn_locators (seq, epilogue_locator);
seq = get_insns ();
end_sequence ();
@@ -7779,7 +7922,7 @@ epilogue_done:
for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
{
basic_block bb = e->src;
- rtx insn = bb->end;
+ rtx insn = BB_END (bb);
rtx i;
rtx newinsn;
@@ -7796,6 +7939,7 @@ epilogue_done:
avoid getting rid of sibcall epilogue insns. Do this before we
actually emit the sequence. */
record_insns (seq, &sibcall_epilogue);
+ set_insn_locators (seq, epilogue_locator);
i = PREV_INSN (insn);
newinsn = emit_insn_before (seq, insn);
@@ -7803,6 +7947,7 @@ epilogue_done:
#endif
#ifdef HAVE_prologue
+ /* This is probably all useless now that we use locators. */
if (prologue_end)
{
rtx insn, prev;
@@ -7835,7 +7980,7 @@ epilogue_done:
}
/* Find the last line number note in the first block. */
- for (insn = ENTRY_BLOCK_PTR->next_bb->end;
+ for (insn = BB_END (ENTRY_BLOCK_PTR->next_bb);
insn != prologue_end && insn;
insn = PREV_INSN (insn))
if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
@@ -7850,9 +7995,7 @@ epilogue_done:
insn = PREV_INSN (insn))
if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
{
- emit_line_note_after (NOTE_SOURCE_FILE (insn),
- NOTE_LINE_NUMBER (insn),
- prologue_end);
+ emit_note_copy_after (insn, prologue_end);
break;
}
}
@@ -7865,11 +8008,16 @@ epilogue_done:
/* Similarly, move any line notes that appear after the epilogue.
There is no need, however, to be quite so anal about the existence
- of such a note. */
+ of such a note. Also move the NOTE_INSN_FUNCTION_END and (possibly)
+ NOTE_INSN_FUNCTION_BEG notes, as those can be relevant for debug
+ info generation. */
for (insn = epilogue_end; insn; insn = next)
{
next = NEXT_INSN (insn);
- if (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) > 0)
+ if (GET_CODE (insn) == NOTE
+ && (NOTE_LINE_NUMBER (insn) > 0
+ || NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG
+ || NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END))
reorder_insns (insn, insn, PREV_INSN (epilogue_end));
}
}
@@ -7880,8 +8028,7 @@ epilogue_done:
scheduling and delayed branch scheduling. */
void
-reposition_prologue_and_epilogue_notes (f)
- rtx f ATTRIBUTE_UNUSED;
+reposition_prologue_and_epilogue_notes (rtx f ATTRIBUTE_UNUSED)
{
#if defined (HAVE_prologue) || defined (HAVE_epilogue)
rtx insn, last, note;
@@ -7911,8 +8058,6 @@ reposition_prologue_and_epilogue_notes (f)
if (last)
{
- rtx next;
-
/* Find the prologue-end note if we haven't already, and
move it to just after the last prologue insn. */
if (note == 0)
@@ -7923,8 +8068,6 @@ reposition_prologue_and_epilogue_notes (f)
break;
}
- next = NEXT_INSN (note);
-
/* Avoid placing note between CODE_LABEL and BASIC_BLOCK note. */
if (GET_CODE (last) == CODE_LABEL)
last = NEXT_INSN (last);
@@ -7976,11 +8119,18 @@ reposition_prologue_and_epilogue_notes (f)
/* Called once, at initialization, to initialize function.c. */
void
-init_function_once ()
+init_function_once (void)
{
VARRAY_INT_INIT (prologue, 0, "prologue");
VARRAY_INT_INIT (epilogue, 0, "epilogue");
VARRAY_INT_INIT (sibcall_epilogue, 0, "sibcall_epilogue");
}
+/* Returns the name of the current function. */
+const char *
+current_function_name (void)
+{
+ return (*lang_hooks.decl_printable_name) (cfun->decl, 2);
+}
+
#include "gt-function.h"
diff --git a/contrib/gcc/function.h b/contrib/gcc/function.h
index d3fb077fba86..3bbafe73c213 100644
--- a/contrib/gcc/function.h
+++ b/contrib/gcc/function.h
@@ -1,6 +1,6 @@
/* Structure for saving state for a nested function.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -19,6 +19,9 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
+#ifndef GCC_FUNCTION_H
+#define GCC_FUNCTION_H
+
struct var_refs_queue GTY(())
{
rtx modified;
@@ -62,7 +65,7 @@ struct emit_status GTY(())
/* The ends of the doubly-linked chain of rtl for the current function.
Both are reset to null at the start of rtl generation for the function.
-
+
start_sequence saves both of these on `sequence_stack' along with
`sequence_rtl_expr' and then starts a new, nested sequence of insns. */
rtx x_first_insn;
@@ -83,10 +86,9 @@ struct emit_status GTY(())
Reset to 1 for each function compiled. */
int x_cur_insn_uid;
- /* Line number and source file of the last line-number NOTE emitted.
+ /* Location the last line-number NOTE emitted.
This is used to avoid generating duplicates. */
- int x_last_linenum;
- const char *x_last_filename;
+ location_t x_last_location;
/* The length of the regno_pointer_align, regno_decl, and x_regno_reg_rtx
vectors. Since these vectors are needed during the expansion phase when
@@ -97,19 +99,15 @@ struct emit_status GTY(())
/* Indexed by pseudo register number, if nonzero gives the known alignment
for that pseudo (if REG_POINTER is set in x_regno_reg_rtx).
Allocated in parallel with x_regno_reg_rtx. */
- unsigned char * GTY ((length ("%h.regno_pointer_align_length")))
+ unsigned char * GTY ((length ("%h.x_reg_rtx_no")))
regno_pointer_align;
- /* Indexed by pseudo register number, if nonzero gives the decl
- corresponding to that register. */
- tree * GTY ((length ("%h.regno_pointer_align_length"))) regno_decl;
-
/* Indexed by pseudo register number, gives the rtx for that pseudo.
- Allocated in parallel with regno_pointer_align.
+ Allocated in parallel with regno_pointer_align.
Note MEM expressions can appear in this array due to the actions
of put_var_into_stack. */
- rtx * GTY ((length ("%h.regno_pointer_align_length"))) x_regno_reg_rtx;
+ rtx * GTY ((length ("%h.x_reg_rtx_no"))) x_regno_reg_rtx;
};
/* For backward compatibility... eventually these should all go away. */
@@ -119,7 +117,6 @@ struct emit_status GTY(())
#define seq_stack (cfun->emit->sequence_stack)
#define REGNO_POINTER_ALIGN(REGNO) (cfun->emit->regno_pointer_align[REGNO])
-#define REGNO_DECL(REGNO) (cfun->emit->regno_decl[REGNO])
struct expr_status GTY(())
{
@@ -186,9 +183,6 @@ struct function GTY(())
/* For function.c. */
- /* Name of this function. */
- const char *name;
-
/* Points to the FUNCTION_DECL of this function. */
tree decl;
@@ -273,6 +267,11 @@ struct function GTY(())
on machines which require execution of the epilogue on all returns. */
rtx x_return_label;
+ /* Label that will go on the end of function epilogue.
+ Jumping to this label serves as a "naked return" instruction
+ on machines which require execution of the epilogue on all returns. */
+ rtx x_naked_return_label;
+
/* Label and register for unswitching computed gotos. */
rtx computed_goto_common_label;
rtx computed_goto_common_reg;
@@ -356,7 +355,7 @@ struct function GTY(())
until no longer needed. CLEANUP_POINT_EXPRs define the lifetime
of TARGET_EXPRs. */
int x_target_temp_slot_level;
-
+
/* This slot is initialized as 0 and is added to
during the nested function. */
struct var_refs_queue *fixup_var_refs_queue;
@@ -383,6 +382,8 @@ struct function GTY(())
int stack_alignment_needed;
/* Preferred alignment of the end of stack frame. */
int preferred_stack_boundary;
+ /* Set when the call to function itself has been emit. */
+ bool recursive_call_emit;
/* Language-specific code can use this to store whatever it likes. */
struct language_function * language;
@@ -393,6 +394,23 @@ struct function GTY(())
delay list for them is recorded here. */
rtx epilogue_delay_list;
+ /* How commonly executed the function is. Initialized during branch
+ probabilities pass. */
+ enum function_frequency {
+ /* This function most likely won't be executed at all.
+ (set only when profile feedback is available). */
+ FUNCTION_FREQUENCY_UNLIKELY_EXECUTED,
+ /* The default value. */
+ FUNCTION_FREQUENCY_NORMAL,
+ /* Optimize this function hard
+ (set only when profile feedback is available). */
+ FUNCTION_FREQUENCY_HOT
+ } function_frequency;
+
+ /* Maximal number of entities in the single jumptable. Used to estimate
+ final flowgraph size. */
+ int max_jumptable_ents;
+
/* Collected bit flags. */
/* Nonzero if function being compiled needs to be given an address
@@ -402,7 +420,7 @@ struct function GTY(())
/* Nonzero if function being compiled needs to
return the address of where it has put a structure value. */
unsigned int returns_pcc_struct : 1;
-
+
/* Nonzero if the current function returns a pointer type. */
unsigned int returns_pointer : 1;
@@ -414,7 +432,7 @@ struct function GTY(())
/* Nonzero if function being compiled can call longjmp. */
unsigned int calls_longjmp : 1;
-
+
/* Nonzero if function being compiled can call alloca,
either as a subroutine or builtin. */
unsigned int calls_alloca : 1;
@@ -422,6 +440,9 @@ struct function GTY(())
/* Nonzero if the function calls __builtin_eh_return. */
unsigned int calls_eh_return : 1;
+ /* Nonzero if the function calls __builtin_constant_p. */
+ unsigned int calls_constant_p : 1;
+
/* Nonzero if function being compiled receives nonlocal gotos
from nested functions. */
unsigned int has_nonlocal_label : 1;
@@ -436,9 +457,10 @@ struct function GTY(())
/* Nonzero if the function being compiled issues a computed jump. */
unsigned int has_computed_jump : 1;
- /* Nonzero if the current function is a thunk (a lightweight function that
- just adjusts one of its arguments and forwards to another function), so
- we should try to cut corners where we can. */
+ /* Nonzero if the current function is a thunk, i.e., a lightweight
+ function implemented by the output_mi_thunk hook) that just
+ adjusts one of its arguments and forwards to another
+ function. */
unsigned int is_thunk : 1;
/* This bit is used by the exception handling logic. It is set if all
@@ -447,14 +469,11 @@ struct function GTY(())
function, however, should be treated as throwing if any of its callees
can throw. */
unsigned int all_throwers_are_sibcalls : 1;
-
+
/* Nonzero if instrumentation calls for function entry and exit should be
generated. */
unsigned int instrument_entry_exit : 1;
- /* Nonzero if arc profiling should be done for the function. */
- unsigned int arc_profile : 1;
-
/* Nonzero if profiling code should be generated. */
unsigned int profile : 1;
@@ -489,35 +508,30 @@ struct function GTY(())
/* Nonzero if the current function needs an lsda for exception handling. */
unsigned int uses_eh_lsda : 1;
- /* Nonzero if code to initialize arg_pointer_save_area has been emited. */
+ /* Nonzero if code to initialize arg_pointer_save_area has been emitted. */
unsigned int arg_pointer_save_area_init : 1;
- /* How commonly executed the function is. Initialized during branch
- probabilities pass. */
- enum function_frequency {
- /* This function most likely won't be executed at all.
- (set only when profile feedback is available). */
- FUNCTION_FREQUENCY_UNLIKELY_EXECUTED,
- /* The default value. */
- FUNCTION_FREQUENCY_NORMAL,
- /* Optimize this function hard
- (set only when profile feedback is available). */
- FUNCTION_FREQUENCY_HOT
- } function_frequency;
+ /* Flag for use by ther rtl inliner, to tell if the function has been
+ processed at least once. */
+ unsigned int rtl_inline_init : 1;
- /* Maximal number of entities in the single jumptable. Used to estimate
- final flowgraph size. */
- int max_jumptable_ents;
+ /* Nonzero if the rtl inliner has saved the function for inlining. */
+ unsigned int saved_for_inline : 1;
};
/* The function currently being compiled. */
extern GTY(()) struct function *cfun;
+/* Pointer to chain of `struct function' for containing functions. */
+extern GTY(()) struct function *outer_function_chain;
+
/* Nonzero if we've already converted virtual regs to hard regs. */
extern int virtuals_instantiated;
+/* Nonzero if at least one trampoline has been created. */
+extern int trampolines_created;
+
/* For backward compatibility... eventually these should all go away. */
-#define current_function_name (cfun->name)
#define current_function_pops_args (cfun->pops_args)
#define current_function_returns_struct (cfun->returns_struct)
#define current_function_returns_pcc_struct (cfun->returns_pcc_struct)
@@ -527,6 +541,7 @@ extern int virtuals_instantiated;
#define current_function_calls_alloca (cfun->calls_alloca)
#define current_function_calls_longjmp (cfun->calls_longjmp)
#define current_function_calls_eh_return (cfun->calls_eh_return)
+#define current_function_calls_constant_p (cfun->calls_constant_p)
#define current_function_has_computed_jump (cfun->has_computed_jump)
#define current_function_contains_functions (cfun->contains_functions)
#define current_function_is_thunk (cfun->is_thunk)
@@ -553,6 +568,7 @@ extern int virtuals_instantiated;
#define parm_reg_stack_loc (cfun->x_parm_reg_stack_loc)
#define cleanup_label (cfun->x_cleanup_label)
#define return_label (cfun->x_return_label)
+#define naked_return_label (cfun->x_naked_return_label)
#define save_expr_regs (cfun->x_save_expr_regs)
#define stack_slot_list (cfun->x_stack_slot_list)
#define parm_birth_insn (cfun->x_parm_birth_insn)
@@ -579,47 +595,52 @@ extern tree inline_function_decl;
/* Given a function decl for a containing function,
return the `struct function' for it. */
-struct function *find_function_data PARAMS ((tree));
+struct function *find_function_data (tree);
/* Set NOTE_BLOCK for each block note in the current function. */
-extern void identify_blocks PARAMS ((void));
+extern void identify_blocks (void);
/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END},
and create duplicate blocks. */
-extern void reorder_blocks PARAMS ((void));
+extern void reorder_blocks (void);
/* Set BLOCK_NUMBER for all the blocks in FN. */
-extern void number_blocks PARAMS ((tree));
+extern void number_blocks (tree);
/* Return size needed for stack frame based on slots so far allocated.
This size counts from zero. It is not rounded to STACK_BOUNDARY;
the caller may have to do that. */
-extern HOST_WIDE_INT get_frame_size PARAMS ((void));
+extern HOST_WIDE_INT get_frame_size (void);
/* Likewise, but for a different than the current function. */
-extern HOST_WIDE_INT get_func_frame_size PARAMS ((struct function *));
+extern HOST_WIDE_INT get_func_frame_size (struct function *);
/* A pointer to a function to create target specific, per-function
data structures. */
-extern struct machine_function * (*init_machine_status) PARAMS ((void));
+extern struct machine_function * (*init_machine_status) (void);
/* Save and restore status information for a nested function. */
-extern void restore_emit_status PARAMS ((struct function *));
-extern void free_after_parsing PARAMS ((struct function *));
-extern void free_after_compilation PARAMS ((struct function *));
-
-extern void init_varasm_status PARAMS ((struct function *));
+extern void restore_emit_status (struct function *);
+extern void free_after_parsing (struct function *);
+extern void free_after_compilation (struct function *);
-extern rtx get_first_block_beg PARAMS ((void));
+extern void init_varasm_status (struct function *);
#ifdef RTX_CODE
-extern void diddle_return_value PARAMS ((void (*)(rtx, void*), void*));
-extern void clobber_return_register PARAMS ((void));
-extern void use_return_register PARAMS ((void));
+extern void diddle_return_value (void (*)(rtx, void*), void*);
+extern void clobber_return_register (void);
+extern void use_return_register (void);
#endif
-extern rtx get_arg_pointer_save_area PARAMS ((struct function *));
+extern rtx get_arg_pointer_save_area (struct function *);
-extern void init_virtual_regs PARAMS ((struct emit_status *));
+extern void init_virtual_regs (struct emit_status *);
+
+/* Returns the name of the current function. */
+extern const char *current_function_name (void);
/* Called once, at initialization, to initialize function.c. */
-extern void init_function_once PARAMS ((void));
+extern void init_function_once (void);
+
+extern void do_warn_unused_parameter (tree);
+
+#endif /* GCC_FUNCTION_H */
diff --git a/contrib/gcc/gbl-ctors.h b/contrib/gcc/gbl-ctors.h
index 9ba79f02ddc6..2a56a9fb9fb2 100644
--- a/contrib/gcc/gbl-ctors.h
+++ b/contrib/gcc/gbl-ctors.h
@@ -2,7 +2,7 @@
for getting g++ file-scope static objects constructed. This file
will get included either by libgcc2.c (for systems that don't support
a .init section) or by crtstuff.c (for those that do).
- Copyright (C) 1991, 1995, 1996, 1998, 1999, 2000
+ Copyright (C) 1991, 1995, 1996, 1998, 1999, 2000, 2003
Free Software Foundation, Inc.
Contributed by Ron Guilmette (rfg@segfault.us.com)
@@ -38,10 +38,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
Note that this file should only be compiled with GCC.
*/
-#ifdef NEED_ATEXIT
-extern int atexit (void (*) (void));
-#endif
-
/* Declare a pointer to void function type. */
typedef void (*func_ptr) (void);
diff --git a/contrib/gcc/gcc.c b/contrib/gcc/gcc.c
index 08a37cdf947b..c9af5d928519 100644
--- a/contrib/gcc/gcc.c
+++ b/contrib/gcc/gcc.c
@@ -1,6 +1,6 @@
/* Compiler driver program that can handle many languages.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -72,6 +72,9 @@ compilation is specified by a string called a "spec". */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "multilib.h" /* before tm.h */
+#include "tm.h"
#include <signal.h>
#if ! defined( SIGCHLD ) && defined( SIGCLD )
# define SIGCHLD SIGCLD
@@ -86,7 +89,7 @@ compilation is specified by a string called a "spec". */
#include <sys/resource.h>
#endif
#if defined (HAVE_DECL_GETRUSAGE) && !HAVE_DECL_GETRUSAGE
-extern int getrusage PARAMS ((int, struct rusage *));
+extern int getrusage (int, struct rusage *);
#endif
/* By default there is no special suffix for target executables. */
@@ -109,14 +112,6 @@ extern int getrusage PARAMS ((int, struct rusage *));
#define TARGET_OBJECT_SUFFIX ".o"
#endif
-#ifndef VMS
-/* FIXME: the location independence code for VMS is hairier than this,
- and hasn't been written. */
-#ifndef DIR_UP
-#define DIR_UP ".."
-#endif /* DIR_UP */
-#endif /* VMS */
-
static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
/* Most every one is fine with LIBRARY_PATH. For some, it conflicts. */
@@ -197,11 +192,37 @@ static int target_help_flag;
static int report_times;
+/* Nonzero means place this string before uses of /, so that include
+ and library files can be found in an alternate location. */
+
+#ifdef TARGET_SYSTEM_ROOT
+static const char *target_system_root = TARGET_SYSTEM_ROOT;
+#else
+static const char *target_system_root = 0;
+#endif
+
+/* Nonzero means pass the updated target_system_root to the compiler. */
+
+static int target_system_root_changed;
+
+/* Nonzero means append this string to target_system_root. */
+
+static const char *target_sysroot_suffix = 0;
+
+/* Nonzero means append this string to target_system_root for headers. */
+
+static const char *target_sysroot_hdrs_suffix = 0;
+
/* Nonzero means write "temp" files in source directory
and use the source file's name in them, and don't delete them. */
static int save_temps_flag;
+/* Nonzero means use pipes to communicate between subprocesses.
+ Overridden by either of the above two flags. */
+
+static int use_pipes;
+
/* The compiler version. */
static const char *compiler_version;
@@ -266,69 +287,74 @@ static struct rusage rus, prus;
/* Forward declaration for prototypes. */
struct path_prefix;
-static void init_spec PARAMS ((void));
-static void store_arg PARAMS ((const char *, int, int));
-static char *load_specs PARAMS ((const char *));
-static void read_specs PARAMS ((const char *, int));
-static void set_spec PARAMS ((const char *, const char *));
-static struct compiler *lookup_compiler PARAMS ((const char *, size_t, const char *));
-static char *build_search_list PARAMS ((struct path_prefix *, const char *, int));
-static void putenv_from_prefixes PARAMS ((struct path_prefix *, const char *));
-static int access_check PARAMS ((const char *, int));
-static char *find_a_file PARAMS ((struct path_prefix *, const char *,
- int, int));
-static void add_prefix PARAMS ((struct path_prefix *, const char *,
- const char *, int, int, int *, int));
-static void translate_options PARAMS ((int *, const char *const **));
-static char *skip_whitespace PARAMS ((char *));
-static void delete_if_ordinary PARAMS ((const char *));
-static void delete_temp_files PARAMS ((void));
-static void delete_failure_queue PARAMS ((void));
-static void clear_failure_queue PARAMS ((void));
-static int check_live_switch PARAMS ((int, int));
-static const char *handle_braces PARAMS ((const char *));
-static const struct spec_function *lookup_spec_function PARAMS ((const char *));
-static const char *eval_spec_function PARAMS ((const char *, const char *));
-static const char *handle_spec_function PARAMS ((const char *));
-static char *save_string PARAMS ((const char *, int));
-static void set_collect_gcc_options PARAMS ((void));
-static int do_spec_1 PARAMS ((const char *, int, const char *));
-static int do_spec_2 PARAMS ((const char *));
-static void do_self_spec PARAMS ((const char *));
-static const char *find_file PARAMS ((const char *));
-static int is_directory PARAMS ((const char *, const char *, int));
-static void validate_switches PARAMS ((const char *));
-static void validate_all_switches PARAMS ((void));
-static void give_switch PARAMS ((int, int, int));
-static int used_arg PARAMS ((const char *, int));
-static int default_arg PARAMS ((const char *, int));
-static void set_multilib_dir PARAMS ((void));
-static void print_multilib_info PARAMS ((void));
-static void perror_with_name PARAMS ((const char *));
-static void pfatal_pexecute PARAMS ((const char *, const char *))
- ATTRIBUTE_NORETURN;
-static void notice PARAMS ((const char *, ...))
- ATTRIBUTE_PRINTF_1;
-static void display_help PARAMS ((void));
-static void add_preprocessor_option PARAMS ((const char *, int));
-static void add_assembler_option PARAMS ((const char *, int));
-static void add_linker_option PARAMS ((const char *, int));
-static void process_command PARAMS ((int, const char *const *));
-static int execute PARAMS ((void));
-static void alloc_args PARAMS ((void));
-static void clear_args PARAMS ((void));
-static void fatal_error PARAMS ((int));
+static void init_spec (void);
+static void store_arg (const char *, int, int);
+static char *load_specs (const char *);
+static void read_specs (const char *, int);
+static void set_spec (const char *, const char *);
+static struct compiler *lookup_compiler (const char *, size_t, const char *);
+static char *build_search_list (struct path_prefix *, const char *, int);
+static void putenv_from_prefixes (struct path_prefix *, const char *);
+static int access_check (const char *, int);
+static char *find_a_file (struct path_prefix *, const char *, int, int);
+static void add_prefix (struct path_prefix *, const char *, const char *,
+ int, int, int *, int);
+static void add_sysrooted_prefix (struct path_prefix *, const char *,
+ const char *, int, int, int *, int);
+static void translate_options (int *, const char *const **);
+static char *skip_whitespace (char *);
+static void delete_if_ordinary (const char *);
+static void delete_temp_files (void);
+static void delete_failure_queue (void);
+static void clear_failure_queue (void);
+static int check_live_switch (int, int);
+static const char *handle_braces (const char *);
+static inline bool input_suffix_matches (const char *, const char *);
+static inline bool switch_matches (const char *, const char *, int);
+static inline void mark_matching_switches (const char *, const char *, int);
+static inline void process_marked_switches (void);
+static const char *process_brace_body (const char *, const char *, const char *, int, int);
+static const struct spec_function *lookup_spec_function (const char *);
+static const char *eval_spec_function (const char *, const char *);
+static const char *handle_spec_function (const char *);
+static char *save_string (const char *, int);
+static void set_collect_gcc_options (void);
+static int do_spec_1 (const char *, int, const char *);
+static int do_spec_2 (const char *);
+static void do_option_spec (const char *, const char *);
+static void do_self_spec (const char *);
+static const char *find_file (const char *);
+static int is_directory (const char *, const char *, int);
+static const char *validate_switches (const char *);
+static void validate_all_switches (void);
+static inline void validate_switches_from_spec (const char *);
+static void give_switch (int, int);
+static int used_arg (const char *, int);
+static int default_arg (const char *, int);
+static void set_multilib_dir (void);
+static void print_multilib_info (void);
+static void perror_with_name (const char *);
+static void pfatal_pexecute (const char *, const char *) ATTRIBUTE_NORETURN;
+static void notice (const char *, ...) ATTRIBUTE_PRINTF_1;
+static void display_help (void);
+static void add_preprocessor_option (const char *, int);
+static void add_assembler_option (const char *, int);
+static void add_linker_option (const char *, int);
+static void process_command (int, const char **);
+static int execute (void);
+static void alloc_args (void);
+static void clear_args (void);
+static void fatal_error (int);
#ifdef ENABLE_SHARED_LIBGCC
-static void init_gcc_specs PARAMS ((struct obstack *,
- const char *, const char *,
- const char *));
+static void init_gcc_specs (struct obstack *, const char *, const char *,
+ const char *);
#endif
#if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
-static const char *convert_filename PARAMS ((const char *, int, int));
+static const char *convert_filename (const char *, int, int);
#endif
-static const char *if_exists_spec_function PARAMS ((int, const char **));
-static const char *if_exists_else_spec_function PARAMS ((int, const char **));
+static const char *if_exists_spec_function (int, const char **);
+static const char *if_exists_else_spec_function (int, const char **);
/* The Specs Language
@@ -363,6 +389,12 @@ or with constant text in a single argument.
with a file name chosen once per compilation, without regard
to any appended suffix (which was therefore treated just like
ordinary text), making such attacks more likely to succeed.
+ %|SUFFIX
+ like %g, but if -pipe is in effect, expands simply to "-".
+ %mSUFFIX
+ like %g, but if -pipe is in effect, expands to nothing. (We have both
+ %| and %m to accommodate differences between system assemblers; see
+ the AS_NEEDS_DASH_FOR_PIPED_INPUT target macro.)
%uSUFFIX
like %g, but generates a new temporary file name even if %uSUFFIX
was already seen.
@@ -391,6 +423,7 @@ or with constant text in a single argument.
%w marks the argument containing or following the %w as the
"output file" of this compilation. This puts the argument
into the sequence of arguments that %o will substitute later.
+ %V indicates that this compilation produces no "output file".
%W{...}
like %{...} but mark last argument supplied within
as a file to be deleted on failure.
@@ -409,12 +442,9 @@ or with constant text in a single argument.
except that %g, %u, and %U do not currently support additional
SUFFIX characters following %O as they would following, for
example, `.o'.
- %p substitutes the standard macro predefinitions for the
- current target machine. Use this when running cpp.
- %P like %p, but puts `__' before and after the name of each macro.
- (Except macros that already have __.)
- This is for ANSI C.
- %I Substitute a -iprefix option made from GCC_EXEC_PREFIX.
+ %I Substitute any of -iprefix (made from GCC_EXEC_PREFIX), -isysroot
+ (made from TARGET_SYSTEM_ROOT), and -isystem (made from COMPILER_PATH
+ and -B options) as necessary.
%s current argument is the name of a library or startup file of some sort.
Search for that file in a standard list of directories
and substitute the full name found.
@@ -425,12 +455,6 @@ or with constant text in a single argument.
%X Output the accumulated linker options specified by compilations.
%Y Output the accumulated assembler options specified by compilations.
%Z Output the accumulated preprocessor options specified by compilations.
- %v1 Substitute the major version number of GCC.
- (For version 2.5.3, this is 2.)
- %v2 Substitute the minor version number of GCC.
- (For version 2.5.3, this is 5.)
- %v3 Substitute the patch level number of GCC.
- (For version 2.5.3, this is 3.)
%a process ASM_SPEC as a spec.
This allows config.h to specify part of the spec for running as.
%A process ASM_FINAL_SPEC as a spec. A capital A is actually
@@ -448,10 +472,15 @@ or with constant text in a single argument.
%C process CPP_SPEC as a spec.
%1 process CC1_SPEC as a spec.
%2 process CC1PLUS_SPEC as a spec.
- %| output "-" if the input for the current command is coming from a pipe.
%* substitute the variable part of a matched option. (See below.)
Note that each comma in the substituted string is replaced by
a single space.
+ %<S remove all occurrences of -S from the command line.
+ Note - this command is position dependent. % commands in the
+ spec string before this one will see -S, % commands in the
+ spec string after this one will not.
+ %<S* remove all occurrences of all switches beginning with -S from the
+ command line.
%:function(args)
Call the named function FUNCTION, passing it ARGS. ARGS is
first processed as a nested spec string, then split into an
@@ -466,33 +495,40 @@ or with constant text in a single argument.
arguments. CC considers `-o foo' as being one switch whose
name starts with `o'. %{o*} would substitute this text,
including the space; thus, two arguments would be generated.
- %{^S*} likewise, but don't put a blank between a switch and any args.
%{S*&T*} likewise, but preserve order of S and T options (the order
- of S and T in the spec is not significant). Can be any number
- of ampersand-separated variables; for each the wild card is
- optional. Useful for CPP as %{D*&U*&A*}.
- %{S*:X} substitutes X if one or more switches whose names start with -S are
- specified to CC. Note that the tail part of the -S option
- (i.e. the part matched by the `*') will be substituted for each
- occurrence of %* within X.
- %{<S} remove all occurrences of -S from the command line.
- Note - this option is position dependent. % commands in the
- spec string before this option will see -S, % commands in the
- spec string after this option will not.
- %{S:X} substitutes X, but only if the -S switch was given to CC.
- %{!S:X} substitutes X, but only if the -S switch was NOT given to CC.
- %{|S:X} like %{S:X}, but if no S switch, substitute `-'.
- %{|!S:X} like %{!S:X}, but if there is an S switch, substitute `-'.
- %{.S:X} substitutes X, but only if processing a file with suffix S.
- %{!.S:X} substitutes X, but only if NOT processing a file with suffix S.
- %{S|P:X} substitutes X if either -S or -P was given to CC. This may be
- combined with ! and . as above binding stronger than the OR.
+ of S and T in the spec is not significant). Can be any number
+ of ampersand-separated variables; for each the wild card is
+ optional. Useful for CPP as %{D*&U*&A*}.
+
+ %{S:X} substitutes X, if the -S switch was given to CC.
+ %{!S:X} substitutes X, if the -S switch was NOT given to CC.
+ %{S*:X} substitutes X if one or more switches whose names start
+ with -S was given to CC. Normally X is substituted only
+ once, no matter how many such switches appeared. However,
+ if %* appears somewhere in X, then X will be substituted
+ once for each matching switch, with the %* replaced by the
+ part of that switch that matched the '*'.
+ %{.S:X} substitutes X, if processing a file with suffix S.
+ %{!.S:X} substitutes X, if NOT processing a file with suffix S.
+
+ %{S|T:X} substitutes X if either -S or -T was given to CC. This may be
+ combined with !, ., and * as above binding stronger than the OR.
+ If %* appears in X, all of the alternatives must be starred, and
+ only the first matching alternative is substituted.
+ %{S:X; if S was given to CC, substitutes X;
+ T:Y; else if T was given to CC, substitutes Y;
+ :D} else substitutes D. There can be as many clauses as you need.
+ This may be combined with ., !, |, and * as above.
+
%(Spec) processes a specification defined in a specs file as *Spec:
%[Spec] as above, but put __ around -D arguments
-The conditional text X in a %{S:X} or %{!S:X} construct may contain
+The conditional text X in a %{S:X} or similar construct may contain
other nested % constructs or spaces, or even newlines. They are
-processed as usual, as described above.
+processed as usual, as described above. Trailing white space in X is
+ignored. White space may also appear anywhere on the left side of the
+colon in these constructs, except between . or * and the corresponding
+word.
The -O, -f, -m, and -W switches are handled specifically in these
constructs. If another value of -O or the negated form of a -f, -m, or
@@ -622,6 +658,14 @@ proper position among the other output files. */
#define LINK_GCC_C_SEQUENCE_SPEC "%G %L %G"
#endif
+#ifndef LINK_PIE_SPEC
+#ifdef HAVE_LD_PIE
+#define LINK_PIE_SPEC "%{pie:-pie} "
+#else
+#define LINK_PIE_SPEC "%{pie:} "
+#endif
+#endif
+
/* -u* was put back because both BSD and SysV seem to support it. */
/* %{static:} simply prevents an error message if the target machine
doesn't handle -static. */
@@ -631,9 +675,10 @@ proper position among the other output files. */
#ifndef LINK_COMMAND_SPEC
#define LINK_COMMAND_SPEC "\
%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
- %(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t}\
- %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
- %{static:} %{L*} %(link_libgcc) %o %{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
+ %(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
+ %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
+ %{static:} %{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate:-lgcov}\
+ %{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
#endif
@@ -651,9 +696,16 @@ proper position among the other output files. */
# define STARTFILE_PREFIX_SPEC ""
#endif
+#ifndef SYSROOT_SUFFIX_SPEC
+# define SYSROOT_SUFFIX_SPEC ""
+#endif
+
+#ifndef SYSROOT_HEADERS_SUFFIX_SPEC
+# define SYSROOT_HEADERS_SUFFIX_SPEC ""
+#endif
+
static const char *asm_debug;
static const char *cpp_spec = CPP_SPEC;
-static const char *cpp_predefines = CPP_PREDEFINES;
static const char *cc1_spec = CC1_SPEC;
static const char *cc1plus_spec = CC1PLUS_SPEC;
static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
@@ -669,6 +721,8 @@ static const char *linker_name_spec = LINKER_NAME;
static const char *link_command_spec = LINK_COMMAND_SPEC;
static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
+static const char *sysroot_suffix_spec = SYSROOT_SUFFIX_SPEC;
+static const char *sysroot_hdrs_suffix_spec = SYSROOT_HEADERS_SUFFIX_SPEC;
/* Standard options to cpp, cc1, and as, to reduce duplication in specs.
There should be no need to override these in target dependent files,
@@ -686,16 +740,13 @@ static const char *trad_capable_cpp =
therefore no dependency entry, confuses make into thinking a .o
file that happens to exist is up-to-date. */
static const char *cpp_unique_options =
-"%{C:%{!E:%eGNU C does not support -C without using -E}}\
- %{CC:%{!E:%eGNU C does not support -CC without using -E}}\
+"%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}}\
%{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*} %{P} %I\
%{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
%{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
%{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
%{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
- %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3}\
- %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
- %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
+ %{trigraphs} %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
%{E|M|MM:%W{o*}}";
/* This contains cpp options which are common with cc1_options and are passed
@@ -705,7 +756,7 @@ static const char *cpp_unique_options =
in turn cause preprocessor symbols to be defined specially. */
static const char *cpp_options =
"%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
- %{O*} %{undef}";
+ %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef}";
/* This contains cpp options which are not passed when the preprocessor
output will be used by another program. */
@@ -715,7 +766,7 @@ static const char *cpp_debug_options = "%{d*}";
static const char *cc1_options =
"%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\
- -auxbase%{c|S:%{o*:-strip %*}%{!o*: %b}}%{!c:%{!S: %b}}\
+ %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}}\
%{g*} %{O*} %{W*&pedantic*} %{w} %{std*} %{ansi}\
%{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
%{Qn:-fno-ident} %{--help:--help}\
@@ -727,7 +778,11 @@ static const char *asm_options =
"%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
static const char *invoke_as =
-"%{!S:-o %{|!pipe:%g.s} |\n as %(asm_options) %{!pipe:%g.s} %A }";
+#ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
+"%{!S:-o %|.s |\n as %(asm_options) %|.s %A }";
+#else
+"%{!S:-o %|.s |\n as %(asm_options) %m.s %A }";
+#endif
/* Some compilers have limits on line lengths, and the multilib_select
and/or multilib_matches strings can be very long, so we build them at
@@ -737,7 +792,6 @@ static const char *multilib_select;
static const char *multilib_matches;
static const char *multilib_defaults;
static const char *multilib_exclusions;
-#include "multilib.h"
/* Check whether a particular argument is a default argument. */
@@ -753,6 +807,19 @@ static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
static const char *const driver_self_specs[] = { DRIVER_SELF_SPECS };
+#ifndef OPTION_DEFAULT_SPECS
+#define OPTION_DEFAULT_SPECS { "", "" }
+#endif
+
+struct default_spec
+{
+ const char *name;
+ const char *spec;
+};
+
+static const struct default_spec
+ option_default_specs[] = { OPTION_DEFAULT_SPECS };
+
struct user_specs
{
struct user_specs *next;
@@ -820,7 +887,7 @@ static const struct compiler default_compilers[] =
{".m", "#Objective-C", 0}, {".mi", "#Objective-C", 0},
{".cc", "#C++", 0}, {".cxx", "#C++", 0}, {".cpp", "#C++", 0},
{".cp", "#C++", 0}, {".c++", "#C++", 0}, {".C", "#C++", 0},
- {".ii", "#C++", 0},
+ {".CPP", "#C++", 0}, {".ii", "#C++", 0},
{".ads", "#Ada", 0}, {".adb", "#Ada", 0},
{".f", "#Fortran", 0}, {".for", "#Fortran", 0}, {".fpp", "#Fortran", 0},
{".F", "#Fortran", 0}, {".FOR", "#Fortran", 0}, {".FPP", "#Fortran", 0},
@@ -838,8 +905,9 @@ static const struct compiler default_compilers[] =
%{traditional|ftraditional:\
%eGNU C no longer supports -traditional without -E}\
%{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
- %(cpp_options) %{save-temps:%b.i} %{!save-temps:%g.i} \n\
- cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} %(cc1_options)}\
+ %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\
+ cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \
+ %(cc1_options)}\
%{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
cc1 %(cpp_unique_options) %(cc1_options)}}}\
%{!fsyntax-only:%(invoke_as)}}}}", 0},
@@ -848,9 +916,20 @@ static const struct compiler default_compilers[] =
%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0},
{".h", "@c-header", 0},
{"@c-header",
- "%{!E:%ecompilation of header file requested} \
- %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)",
- 0},
+ /* cc1 has an integrated ISO C preprocessor. We should invoke the
+ external preprocessor if -save-temps is given. */
+ "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
+ %{!E:%{!M:%{!MM:\
+ %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
+ %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\
+ cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \
+ %(cc1_options)\
+ -o %g.s %{!o*:--output-pch=%i.gch}\
+ %W{o*:--output-pch=%*}%V}\
+ %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
+ cc1 %(cpp_unique_options) %(cc1_options)\
+ -o %g.s %{!o*:--output-pch=%i.gch}\
+ %W{o*:--output-pch=%*}%V}}}}}}", 0},
{".i", "@cpp-output", 0},
{"@cpp-output",
"%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0},
@@ -859,12 +938,21 @@ static const struct compiler default_compilers[] =
"%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0},
{".S", "@assembler-with-cpp", 0},
{"@assembler-with-cpp",
+#ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
+ "%(trad_capable_cpp) -lang-asm %(cpp_options)\
+ %{E|M|MM:%(cpp_debug_options)}\
+ %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
+ as %(asm_debug) %(asm_options) %|.s %A }}}}"
+#else
"%(trad_capable_cpp) -lang-asm %(cpp_options)\
%{E|M|MM:%(cpp_debug_options)}\
- %{!M:%{!MM:%{!E:%{!S:-o %{|!pipe:%g.s} |\n\
- as %(asm_debug) %(asm_options) %{!pipe:%g.s} %A }}}}", 0},
+ %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
+ as %(asm_debug) %(asm_options) %m.s %A }}}}"
+#endif
+ , 0},
+
#include "specs.h"
- /* Mark end of table */
+ /* Mark end of table. */
{0, 0, 0}
};
@@ -957,6 +1045,7 @@ static const struct option_map option_map[] =
{"--param", "--param", "a"},
{"--pedantic", "-pedantic", 0},
{"--pedantic-errors", "-pedantic-errors", 0},
+ {"--pie", "-pie", 0},
{"--pipe", "-pipe", 0},
{"--prefix", "-B", "a"},
{"--preprocess", "-E", 0},
@@ -979,14 +1068,12 @@ static const struct option_map option_map[] =
{"--static", "-static", 0},
{"--std", "-std=", "aj"},
{"--symbolic", "-symbolic", 0},
- {"--target", "-b", "a"},
{"--time", "-time", 0},
{"--trace-includes", "-H", 0},
{"--traditional", "-traditional", 0},
{"--traditional-cpp", "-traditional-cpp", 0},
{"--trigraphs", "-trigraphs", 0},
{"--undefine-macro", "-U", "aj"},
- {"--use-version", "-V", "a"},
{"--user-dependencies", "-MM", 0},
{"--verbose", "-v", 0},
{"--warn-", "-W", "*j"},
@@ -1012,16 +1099,13 @@ static const struct {
and store its length in *ARGVC. */
static void
-translate_options (argcp, argvp)
- int *argcp;
- const char *const **argvp;
+translate_options (int *argcp, const char *const **argvp)
{
int i;
int argc = *argcp;
const char *const *argv = *argvp;
int newvsize = (argc + 2) * 2 * sizeof (const char *);
- const char **newv =
- (const char **) xmalloc (newvsize);
+ const char **newv = xmalloc (newvsize);
int newindex = 0;
i = 0;
@@ -1051,7 +1135,7 @@ translate_options (argcp, argvp)
}
newvsize += spaces * sizeof (const char *);
- newv = (const char **) xrealloc (newv, newvsize);
+ newv = xrealloc (newv, newvsize);
sp = target_option_translations[tott_idx].replacements;
np = xstrdup (sp);
@@ -1195,6 +1279,10 @@ translate_options (argcp, argvp)
nskip += 1;
else if (! strcmp (p, "Xlinker"))
nskip += 1;
+ else if (! strcmp (p, "Xpreprocessor"))
+ nskip += 1;
+ else if (! strcmp (p, "Xassembler"))
+ nskip += 1;
/* Watch out for an option at the end of the command line that
is missing arguments, and avoid skipping past the end of the
@@ -1220,8 +1308,7 @@ translate_options (argcp, argvp)
}
static char *
-skip_whitespace (p)
- char *p;
+skip_whitespace (char *p)
{
while (1)
{
@@ -1290,6 +1377,10 @@ static const char *just_machine_suffix = 0;
static const char *gcc_exec_prefix;
+/* Adjusted value of standard_libexec_prefix. */
+
+static const char *gcc_libexec_prefix;
+
/* Default prefixes to attach to command names. */
#ifdef CROSS_COMPILE /* Don't use these prefixes for a cross compiler. */
@@ -1309,23 +1400,9 @@ static const char *gcc_exec_prefix;
#define MD_STARTFILE_PREFIX_1 ""
#endif
-/* Supply defaults for the standard prefixes. */
-
-#ifndef STANDARD_EXEC_PREFIX
-#define STANDARD_EXEC_PREFIX "/usr/local/lib/gcc-lib/"
-#endif
-#ifndef STANDARD_STARTFILE_PREFIX
-#define STANDARD_STARTFILE_PREFIX "/usr/local/lib/"
-#endif
-#ifndef TOOLDIR_BASE_PREFIX
-#define TOOLDIR_BASE_PREFIX "/usr/local/"
-#endif
-#ifndef STANDARD_BINDIR_PREFIX
-#define STANDARD_BINDIR_PREFIX "/usr/local/bin"
-#endif
-
static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
-static const char *const standard_exec_prefix_1 = "/usr/lib/gcc/";
+static const char *const standard_exec_prefix_1 = "/usr/libexec/gcc/";
+static const char *const standard_exec_prefix_2 = "/usr/lib/gcc/";
static const char *md_exec_prefix = MD_EXEC_PREFIX;
static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
@@ -1339,6 +1416,8 @@ static const char *tooldir_prefix;
static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
+static const char *standard_libexec_prefix = STANDARD_LIBEXEC_PREFIX;
+
/* Subdirectory to use for locating libraries. Set by
set_multilib_dir based on the compilation options. */
@@ -1394,7 +1473,6 @@ static struct spec_list static_specs[] =
INIT_STATIC_SPEC ("libgcc", &libgcc_spec),
INIT_STATIC_SPEC ("startfile", &startfile_spec),
INIT_STATIC_SPEC ("switches_need_spaces", &switches_need_spaces),
- INIT_STATIC_SPEC ("predefines", &cpp_predefines),
INIT_STATIC_SPEC ("cross_compile", &cross_compile),
INIT_STATIC_SPEC ("version", &compiler_version),
INIT_STATIC_SPEC ("multilib", &multilib_select),
@@ -1409,6 +1487,8 @@ static struct spec_list static_specs[] =
INIT_STATIC_SPEC ("md_startfile_prefix", &md_startfile_prefix),
INIT_STATIC_SPEC ("md_startfile_prefix_1", &md_startfile_prefix_1),
INIT_STATIC_SPEC ("startfile_prefix_spec", &startfile_prefix_spec),
+ INIT_STATIC_SPEC ("sysroot_suffix_spec", &sysroot_suffix_spec),
+ INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec", &sysroot_hdrs_suffix_spec),
};
#ifdef EXTRA_SPECS /* additional specs needed */
@@ -1444,16 +1524,19 @@ static int processing_spec_function;
#ifdef ENABLE_SHARED_LIBGCC
static void
-init_gcc_specs (obstack, shared_name, static_name, eh_name)
- struct obstack *obstack;
- const char *shared_name;
- const char *static_name;
- const char *eh_name;
+init_gcc_specs (struct obstack *obstack, const char *shared_name,
+ const char *static_name, const char *eh_name)
{
char *buf;
buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name,
"}%{!static:%{!static-libgcc:",
+#ifdef HAVE_LD_AS_NEEDED
+ "%{!shared-libgcc:", static_name,
+ " --as-needed ", shared_name, " --no-as-needed}"
+ "%{shared-libgcc:", shared_name, "%{!shared: ", static_name,
+ "}",
+#else
"%{!shared:%{!shared-libgcc:", static_name, " ",
eh_name, "}%{shared-libgcc:", shared_name, " ",
static_name, "}}%{shared:",
@@ -1463,6 +1546,7 @@ init_gcc_specs (obstack, shared_name, static_name, eh_name)
#else
shared_name,
#endif
+#endif
"}}}", NULL);
obstack_grow (obstack, buf, strlen (buf));
@@ -1473,7 +1557,7 @@ init_gcc_specs (obstack, shared_name, static_name, eh_name)
/* Initialize the specs lookup routines. */
static void
-init_spec ()
+init_spec (void)
{
struct spec_list *next = (struct spec_list *) 0;
struct spec_list *sl = (struct spec_list *) 0;
@@ -1486,8 +1570,8 @@ init_spec ()
notice ("Using built-in specs.\n");
#ifdef EXTRA_SPECS
- extra_specs = (struct spec_list *)
- xcalloc (sizeof (struct spec_list), ARRAY_SIZE (extra_specs_1));
+ extra_specs = xcalloc (sizeof (struct spec_list),
+ ARRAY_SIZE (extra_specs_1));
for (i = ARRAY_SIZE (extra_specs_1) - 1; i >= 0; i--)
{
@@ -1556,12 +1640,14 @@ init_spec ()
#else
"-lgcc_s%M"
#endif
+ ,
+ "-lgcc",
+ "-lgcc_eh"
#ifdef USE_LIBUNWIND_EXCEPTIONS
" -lunwind"
#endif
- ,
- "-lgcc",
- "-lgcc_eh");
+ );
+
p += 5;
in_sep = 0;
}
@@ -1577,7 +1663,11 @@ init_spec ()
#endif
,
"libgcc.a%s",
- "libgcc_eh.a%s");
+ "libgcc_eh.a%s"
+#ifdef USE_LIBUNWIND_EXCEPTIONS
+ " -lunwind"
+#endif
+ );
p += 10;
in_sep = 0;
}
@@ -1617,9 +1707,7 @@ init_spec ()
current spec. */
static void
-set_spec (name, spec)
- const char *name;
- const char *spec;
+set_spec (const char *name, const char *spec)
{
struct spec_list *sl;
const char *old_spec;
@@ -1647,7 +1735,7 @@ set_spec (name, spec)
if (!sl)
{
/* Not found - make it. */
- sl = (struct spec_list *) xmalloc (sizeof (struct spec_list));
+ sl = xmalloc (sizeof (struct spec_list));
sl->name = xstrdup (name);
sl->name_len = name_len;
sl->ptr_spec = &sl->ptr;
@@ -1669,7 +1757,7 @@ set_spec (name, spec)
/* Free the old spec. */
if (old_spec && sl->alloc_p)
- free ((PTR) old_spec);
+ free ((void *) old_spec);
sl->alloc_p = 1;
}
@@ -1716,16 +1804,16 @@ static const char *programname;
/* Allocate the argument vector. */
static void
-alloc_args ()
+alloc_args (void)
{
argbuf_length = 10;
- argbuf = (const char **) xmalloc (argbuf_length * sizeof (const char *));
+ argbuf = xmalloc (argbuf_length * sizeof (const char *));
}
/* Clear out the vector of arguments (after a command is executed). */
static void
-clear_args ()
+clear_args (void)
{
argbuf_index = 0;
}
@@ -1738,14 +1826,10 @@ clear_args ()
and the file should be deleted if this compilation fails. */
static void
-store_arg (arg, delete_always, delete_failure)
- const char *arg;
- int delete_always, delete_failure;
+store_arg (const char *arg, int delete_always, int delete_failure)
{
if (argbuf_index + 1 == argbuf_length)
- argbuf
- = (const char **) xrealloc (argbuf,
- (argbuf_length *= 2) * sizeof (const char *));
+ argbuf = xrealloc (argbuf, (argbuf_length *= 2) * sizeof (const char *));
argbuf[argbuf_index++] = arg;
argbuf[argbuf_index] = 0;
@@ -1759,8 +1843,7 @@ store_arg (arg, delete_always, delete_failure)
a single \n. */
static char *
-load_specs (filename)
- const char *filename;
+load_specs (const char *filename)
{
int desc;
int readlen;
@@ -1824,9 +1907,7 @@ load_specs (filename)
Anything invalid in the file is a fatal error. */
static void
-read_specs (filename, main_p)
- const char *filename;
- int main_p;
+read_specs (const char *filename, int main_p)
{
char *buffer;
char *p;
@@ -1968,7 +2049,7 @@ read_specs (filename, main_p)
set_spec (p2, *(sl->ptr_spec));
if (sl->alloc_p)
- free ((PTR) *(sl->ptr_spec));
+ free ((void *) *(sl->ptr_spec));
*(sl->ptr_spec) = "";
sl->alloc_p = 0;
@@ -2038,9 +2119,8 @@ read_specs (filename, main_p)
{
/* Add this pair to the vector. */
compilers
- = ((struct compiler *)
- xrealloc (compilers,
- (n_compilers + 2) * sizeof (struct compiler)));
+ = xrealloc (compilers,
+ (n_compilers + 2) * sizeof (struct compiler));
compilers[n_compilers].suffix = suffix;
compilers[n_compilers].spec = spec;
@@ -2096,10 +2176,7 @@ static struct temp_file *failure_delete_queue;
otherwise delete it in any case. */
void
-record_temp_file (filename, always_delete, fail_delete)
- const char *filename;
- int always_delete;
- int fail_delete;
+record_temp_file (const char *filename, int always_delete, int fail_delete)
{
char *const name = xstrdup (filename);
@@ -2110,7 +2187,7 @@ record_temp_file (filename, always_delete, fail_delete)
if (! strcmp (name, temp->name))
goto already1;
- temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
+ temp = xmalloc (sizeof (struct temp_file));
temp->next = always_delete_queue;
temp->name = name;
always_delete_queue = temp;
@@ -2125,7 +2202,7 @@ record_temp_file (filename, always_delete, fail_delete)
if (! strcmp (name, temp->name))
goto already2;
- temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
+ temp = xmalloc (sizeof (struct temp_file));
temp->next = failure_delete_queue;
temp->name = name;
failure_delete_queue = temp;
@@ -2137,8 +2214,7 @@ record_temp_file (filename, always_delete, fail_delete)
/* Delete all the temporary files whose names we previously recorded. */
static void
-delete_if_ordinary (name)
- const char *name;
+delete_if_ordinary (const char *name)
{
struct stat st;
#ifdef DEBUG
@@ -2160,7 +2236,7 @@ delete_if_ordinary (name)
}
static void
-delete_temp_files ()
+delete_temp_files (void)
{
struct temp_file *temp;
@@ -2172,7 +2248,7 @@ delete_temp_files ()
/* Delete all the files to be deleted on error. */
static void
-delete_failure_queue ()
+delete_failure_queue (void)
{
struct temp_file *temp;
@@ -2181,7 +2257,7 @@ delete_failure_queue ()
}
static void
-clear_failure_queue ()
+clear_failure_queue (void)
{
failure_delete_queue = 0;
}
@@ -2193,10 +2269,8 @@ clear_failure_queue ()
It is also used by the --print-search-dirs flag. */
static char *
-build_search_list (paths, prefix, check_dir_p)
- struct path_prefix *paths;
- const char *prefix;
- int check_dir_p;
+build_search_list (struct path_prefix *paths, const char *prefix,
+ int check_dir_p)
{
int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
int just_suffix_len
@@ -2255,9 +2329,7 @@ build_search_list (paths, prefix, check_dir_p)
for collect. */
static void
-putenv_from_prefixes (paths, env_var)
- struct path_prefix *paths;
- const char *env_var;
+putenv_from_prefixes (struct path_prefix *paths, const char *env_var)
{
putenv (build_search_list (paths, env_var, 1));
}
@@ -2266,9 +2338,7 @@ putenv_from_prefixes (paths, env_var)
except that it never considers directories to be executable. */
static int
-access_check (name, mode)
- const char *name;
- int mode;
+access_check (const char *name, int mode)
{
if (mode == X_OK)
{
@@ -2287,10 +2357,8 @@ access_check (name, mode)
Return 0 if not found, otherwise return its name, allocated with malloc. */
static char *
-find_a_file (pprefix, name, mode, multilib)
- struct path_prefix *pprefix;
- const char *name;
- int mode, multilib;
+find_a_file (struct path_prefix *pprefix, const char *name, int mode,
+ int multilib)
{
char *temp;
const char *const file_suffix =
@@ -2332,7 +2400,7 @@ find_a_file (pprefix, name, mode, multilib)
/* Determine the filename to execute (special case for absolute paths). */
- if (IS_ABSOLUTE_PATHNAME (name))
+ if (IS_ABSOLUTE_PATH (name))
{
if (access (name, mode) == 0)
{
@@ -2450,7 +2518,7 @@ enum path_prefix_priority
PREFIX_PRIORITY_LAST
};
-/* Add an entry for PREFIX in PLIST. The PLIST is kept in assending
+/* Add an entry for PREFIX in PLIST. The PLIST is kept in ascending
order according to PRIORITY. Within each PRIORITY, new entries are
appended.
@@ -2465,15 +2533,9 @@ enum path_prefix_priority
2 means try both machine_suffix and just_machine_suffix. */
static void
-add_prefix (pprefix, prefix, component, priority, require_machine_suffix,
- warn, os_multilib)
- struct path_prefix *pprefix;
- const char *prefix;
- const char *component;
- /* enum prefix_priority */ int priority;
- int require_machine_suffix;
- int *warn;
- int os_multilib;
+add_prefix (struct path_prefix *pprefix, const char *prefix,
+ const char *component, /* enum prefix_priority */ int priority,
+ int require_machine_suffix, int *warn, int os_multilib)
{
struct prefix_list *pl, **prev;
int len;
@@ -2483,14 +2545,14 @@ add_prefix (pprefix, prefix, component, priority, require_machine_suffix,
prev = &(*prev)->next)
;
- /* Keep track of the longest prefix */
+ /* Keep track of the longest prefix. */
prefix = update_path (prefix, component);
len = strlen (prefix);
if (len > pprefix->max_len)
pprefix->max_len = len;
- pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
+ pl = xmalloc (sizeof (struct prefix_list));
pl->prefix = prefix;
pl->require_machine_suffix = require_machine_suffix;
pl->used_flag_ptr = warn;
@@ -2499,10 +2561,35 @@ add_prefix (pprefix, prefix, component, priority, require_machine_suffix,
if (warn)
*warn = 0;
- /* Insert after PREV */
+ /* Insert after PREV. */
pl->next = (*prev);
(*prev) = pl;
}
+
+/* Same as add_prefix, but prepending target_system_root to prefix. */
+static void
+add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
+ const char *component,
+ /* enum prefix_priority */ int priority,
+ int require_machine_suffix, int *warn, int os_multilib)
+{
+ if (!IS_ABSOLUTE_PATH (prefix))
+ abort ();
+
+ if (target_system_root)
+ {
+ if (target_sysroot_suffix)
+ prefix = concat (target_sysroot_suffix, prefix, NULL);
+ prefix = concat (target_system_root, prefix, NULL);
+
+ /* We have to override this because GCC's notion of sysroot
+ moves along with GCC. */
+ component = "GCC";
+ }
+
+ add_prefix (pprefix, prefix, component, priority,
+ require_machine_suffix, warn, os_multilib);
+}
/* Execute the command specified by the arguments on the current line of spec.
When using pipes, this includes several piped-together commands
@@ -2511,7 +2598,7 @@ add_prefix (pprefix, prefix, component, priority, require_machine_suffix,
Return 0 if successful, -1 if failed. */
static int
-execute ()
+execute (void)
{
int i;
int n_commands; /* # of command. */
@@ -2534,7 +2621,7 @@ execute ()
n_commands++;
/* Get storage for each command. */
- commands = (struct command *) alloca (n_commands * sizeof (struct command));
+ commands = alloca (n_commands * sizeof (struct command));
/* Split argbuf into its separate piped processes,
and record info about each one.
@@ -2604,7 +2691,14 @@ execute ()
}
fflush (stderr);
if (verbose_only_flag != 0)
- return 0;
+ {
+ /* verbose_only_flag should act as if the spec was
+ executed, so increment execution_count before
+ returning. This prevents spurious warnings about
+ unused linker input files, etc. */
+ execution_count++;
+ return 0;
+ }
#ifdef DEBUG
notice ("\nGo ahead? (y or n) ");
fflush (stderr);
@@ -2619,7 +2713,7 @@ execute ()
}
#ifdef ENABLE_VALGRIND_CHECKING
- /* Run the each command through valgrind. To simplifiy prepending the
+ /* Run the each command through valgrind. To simplify prepending the
path to valgrind and the option "-q" (for quiet operation unless
something triggers), we allocate a separate argv array. */
@@ -2667,7 +2761,7 @@ execute ()
pfatal_pexecute (errmsg_fmt, errmsg_arg);
if (string != commands[i].prog)
- free ((PTR) string);
+ free ((void *) string);
}
execution_count++;
@@ -2769,7 +2863,7 @@ See %s for instructions.",
0 when initialized
1 if the switch is true in a conditional spec,
-1 if false (overridden by a later switch)
- -2 if this switch should be ignored (used in %{<S})
+ -2 if this switch should be ignored (used in %<S)
The `validated' field is nonzero if any spec has looked at this switch;
if it remains zero at the end of the run, it must be meaningless. */
@@ -2803,6 +2897,11 @@ static struct infile *infiles;
int n_infiles;
+/* True if multiple input files are being compiled to a single
+ assembly file. */
+
+static bool combine_inputs;
+
/* This counts the number of libraries added by lang_specific_driver, so that
we can tell if there were any user supplied any files or libraries. */
@@ -2825,10 +2924,8 @@ static int *warn_std_ptr = 0;
is true if we should look for an object suffix. */
static const char *
-convert_filename (name, do_exe, do_obj)
- const char *name;
- int do_exe ATTRIBUTE_UNUSED;
- int do_obj ATTRIBUTE_UNUSED;
+convert_filename (const char *name, int do_exe ATTRIBUTE_UNUSED,
+ int do_obj ATTRIBUTE_UNUSED)
{
#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
int i;
@@ -2878,7 +2975,7 @@ convert_filename (name, do_exe, do_obj)
/* Display the command line switches accepted by gcc. */
static void
-display_help ()
+display_help (void)
{
printf (_("Usage: %s [options] file...\n"), programname);
fputs (_("Options:\n"), stdout);
@@ -2903,6 +3000,8 @@ display_help ()
fputs (_(" -Wa,<options> Pass comma-separated <options> on to the assembler\n"), stdout);
fputs (_(" -Wp,<options> Pass comma-separated <options> on to the preprocessor\n"), stdout);
fputs (_(" -Wl,<options> Pass comma-separated <options> on to the linker\n"), stdout);
+ fputs (_(" -Xassembler <arg> Pass <arg> on to the assembler\n"), stdout);
+ fputs (_(" -Xpreprocessor <arg> Pass <arg> on to the preprocessor\n"), stdout);
fputs (_(" -Xlinker <arg> Pass <arg> on to the linker\n"), stdout);
fputs (_(" -save-temps Do not delete intermediate files\n"), stdout);
fputs (_(" -pipe Use pipes rather than intermediate files\n"), stdout);
@@ -2936,56 +3035,44 @@ display_help ()
}
static void
-add_preprocessor_option (option, len)
- const char *option;
- int len;
+add_preprocessor_option (const char *option, int len)
{
n_preprocessor_options++;
if (! preprocessor_options)
- preprocessor_options
- = (char **) xmalloc (n_preprocessor_options * sizeof (char *));
+ preprocessor_options = xmalloc (n_preprocessor_options * sizeof (char *));
else
- preprocessor_options
- = (char **) xrealloc (preprocessor_options,
- n_preprocessor_options * sizeof (char *));
+ preprocessor_options = xrealloc (preprocessor_options,
+ n_preprocessor_options * sizeof (char *));
preprocessor_options [n_preprocessor_options - 1] =
save_string (option, len);
}
static void
-add_assembler_option (option, len)
- const char *option;
- int len;
+add_assembler_option (const char *option, int len)
{
n_assembler_options++;
if (! assembler_options)
- assembler_options
- = (char **) xmalloc (n_assembler_options * sizeof (char *));
+ assembler_options = xmalloc (n_assembler_options * sizeof (char *));
else
- assembler_options
- = (char **) xrealloc (assembler_options,
- n_assembler_options * sizeof (char *));
+ assembler_options = xrealloc (assembler_options,
+ n_assembler_options * sizeof (char *));
assembler_options [n_assembler_options - 1] = save_string (option, len);
}
static void
-add_linker_option (option, len)
- const char *option;
- int len;
+add_linker_option (const char *option, int len)
{
n_linker_options++;
if (! linker_options)
- linker_options
- = (char **) xmalloc (n_linker_options * sizeof (char *));
+ linker_options = xmalloc (n_linker_options * sizeof (char *));
else
- linker_options
- = (char **) xrealloc (linker_options,
- n_linker_options * sizeof (char *));
+ linker_options = xrealloc (linker_options,
+ n_linker_options * sizeof (char *));
linker_options [n_linker_options - 1] = save_string (option, len);
}
@@ -2994,9 +3081,7 @@ add_linker_option (option, len)
Store its length in `n_switches'. */
static void
-process_command (argc, argv)
- int argc;
- const char *const *argv;
+process_command (int argc, const char **argv)
{
int i;
const char *temp;
@@ -3041,7 +3126,7 @@ process_command (argc, argv)
char **new_argv;
char *new_argv0;
int baselen;
-
+
while (argc > 1 && argv[1][0] == '-'
&& (argv[1][1] == 'V' || argv[1][1] == 'b'))
{
@@ -3070,7 +3155,7 @@ process_command (argc, argv)
for (baselen = strlen (progname); baselen > 0; baselen--)
if (IS_DIR_SEPARATOR (progname[baselen-1]))
break;
- new_argv0 = xmemdup (progname, baselen,
+ new_argv0 = xmemdup (progname, baselen,
baselen + concat_length (new_version, new_machine,
"-gcc-", NULL) + 1);
strcpy (new_argv0 + baselen, new_machine);
@@ -3088,34 +3173,43 @@ process_command (argc, argv)
/* Set up the default search paths. If there is no GCC_EXEC_PREFIX,
see if we can create it from the pathname specified in argv[0]. */
+ gcc_libexec_prefix = standard_libexec_prefix;
#ifndef VMS
/* FIXME: make_relative_prefix doesn't yet work for VMS. */
if (!gcc_exec_prefix)
{
gcc_exec_prefix = make_relative_prefix (argv[0], standard_bindir_prefix,
standard_exec_prefix);
+ gcc_libexec_prefix = make_relative_prefix (argv[0],
+ standard_bindir_prefix,
+ standard_libexec_prefix);
if (gcc_exec_prefix)
putenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
}
+ else
+ gcc_libexec_prefix = make_relative_prefix (gcc_exec_prefix,
+ standard_exec_prefix,
+ standard_libexec_prefix);
+#else
#endif
if (gcc_exec_prefix)
{
int len = strlen (gcc_exec_prefix);
- if (len > (int) sizeof ("/lib/gcc-lib/") - 1
+ if (len > (int) sizeof ("/lib/gcc/") - 1
&& (IS_DIR_SEPARATOR (gcc_exec_prefix[len-1])))
{
- temp = gcc_exec_prefix + len - sizeof ("/lib/gcc-lib/") + 1;
+ temp = gcc_exec_prefix + len - sizeof ("/lib/gcc/") + 1;
if (IS_DIR_SEPARATOR (*temp)
&& strncmp (temp + 1, "lib", 3) == 0
&& IS_DIR_SEPARATOR (temp[4])
- && strncmp (temp + 5, "gcc-lib", 7) == 0)
- len -= sizeof ("/lib/gcc-lib/") - 1;
+ && strncmp (temp + 5, "gcc", 3) == 0)
+ len -= sizeof ("/lib/gcc/") - 1;
}
set_std_prefix (gcc_exec_prefix, len);
- add_prefix (&exec_prefixes, gcc_exec_prefix, "GCC",
+ add_prefix (&exec_prefixes, gcc_libexec_prefix, "GCC",
PREFIX_PRIORITY_LAST, 0, NULL, 0);
add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC",
PREFIX_PRIORITY_LAST, 0, NULL, 0);
@@ -3128,7 +3222,7 @@ process_command (argc, argv)
if (temp)
{
const char *startp, *endp;
- char *nstore = (char *) alloca (strlen (temp) + 3);
+ char *nstore = alloca (strlen (temp) + 3);
startp = endp = temp;
while (1)
@@ -3163,7 +3257,7 @@ process_command (argc, argv)
if (temp && *cross_compile == '0')
{
const char *startp, *endp;
- char *nstore = (char *) alloca (strlen (temp) + 3);
+ char *nstore = alloca (strlen (temp) + 3);
startp = endp = temp;
while (1)
@@ -3196,7 +3290,7 @@ process_command (argc, argv)
if (temp && *cross_compile == '0')
{
const char *startp, *endp;
- char *nstore = (char *) alloca (strlen (temp) + 3);
+ char *nstore = alloca (strlen (temp) + 3);
startp = endp = temp;
while (1)
@@ -3225,10 +3319,10 @@ process_command (argc, argv)
}
/* Convert new-style -- options to old-style. */
- translate_options (&argc, &argv);
+ translate_options (&argc, (const char *const **) &argv);
/* Do language-specific adjustment/addition of flags. */
- lang_specific_driver (&argc, &argv, &added_libraries);
+ lang_specific_driver (&argc, (const char *const **) &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.
@@ -3260,8 +3354,8 @@ process_command (argc, argv)
{
/* translate_options () has turned --version into -fversion. */
printf (_("%s (GCC) %s\n"), programname, version_string);
- fputs (_("Copyright (C) 2003 Free Software Foundation, Inc.\n"),
- stdout);
+ printf ("Copyright %s 2004 Free Software Foundation, Inc.\n",
+ _("(C)"));
fputs (_("This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
stdout);
@@ -3368,6 +3462,20 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
n_infiles++;
i++;
}
+ else if (strcmp (argv[i], "-Xpreprocessor") == 0)
+ {
+ if (i + 1 == argc)
+ fatal ("argument to `-Xpreprocessor' is missing");
+
+ add_preprocessor_option (argv[i+1], strlen (argv[i+1]));
+ }
+ else if (strcmp (argv[i], "-Xassembler") == 0)
+ {
+ if (i + 1 == argc)
+ fatal ("argument to `-Xassembler' is missing");
+
+ add_assembler_option (argv[i+1], strlen (argv[i+1]));
+ }
else if (strcmp (argv[i], "-l") == 0)
{
if (i + 1 == argc)
@@ -3385,8 +3493,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
}
else if (strcmp (argv[i], "-specs") == 0)
{
- struct user_specs *user = (struct user_specs *)
- xmalloc (sizeof (struct user_specs));
+ struct user_specs *user = xmalloc (sizeof (struct user_specs));
if (++i >= argc)
fatal ("argument to `-specs' is missing");
@@ -3400,8 +3507,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
}
else if (strncmp (argv[i], "-specs=", 7) == 0)
{
- struct user_specs *user = (struct user_specs *)
- xmalloc (sizeof (struct user_specs));
+ struct user_specs *user = xmalloc (sizeof (struct user_specs));
if (strlen (argv[i]) == 7)
fatal ("argument to `-specs=' is missing");
@@ -3415,6 +3521,13 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
}
else if (strcmp (argv[i], "-time") == 0)
report_times = 1;
+ else if (strcmp (argv[i], "-pipe") == 0)
+ {
+ /* -pipe has to go into the switches array as well as
+ setting a flag. */
+ use_pipes = 1;
+ n_switches++;
+ }
else if (strcmp (argv[i], "-###") == 0)
{
/* This is similar to -v except that there is no execution
@@ -3567,9 +3680,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
for (j = 0; j < ARRAY_SIZE (modify_target); j++)
if (! strcmp (argv[i], modify_target[j].sw))
{
- char *new_name
- = (char *) xmalloc (strlen (modify_target[j].str)
- + strlen (spec_machine));
+ char *new_name = xmalloc (strlen (modify_target[j].str)
+ + strlen (spec_machine));
const char *p, *r;
char *q;
int made_addition = 0;
@@ -3614,8 +3726,20 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
}
}
- if (have_c && have_o && lang_n_infiles > 1)
- fatal ("cannot specify -o with -c or -S and multiple compilations");
+ combine_inputs = (have_c && have_o && lang_n_infiles > 1);
+
+ if ((save_temps_flag || report_times) && use_pipes)
+ {
+ /* -save-temps overrides -pipe, so that temp files are produced */
+ if (save_temps_flag)
+ error ("warning: -pipe ignored because -save-temps specified");
+ /* -time overrides -pipe because we can't get correct stats when
+ multiple children are running at once. */
+ else if (report_times)
+ error ("warning: -pipe ignored because -time specified");
+
+ use_pipes = 0;
+ }
/* Set up the search paths before we go looking for config files. */
@@ -3624,17 +3748,21 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
/* Use 2 as fourth arg meaning try just the machine as a suffix,
as well as trying the machine and the version. */
#ifndef OS2
- add_prefix (&exec_prefixes, standard_exec_prefix, "GCC",
+ add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
+ add_prefix (&exec_prefixes, standard_libexec_prefix, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
add_prefix (&exec_prefixes, standard_exec_prefix_1, "BINUTILS",
PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
+ add_prefix (&exec_prefixes, standard_exec_prefix_2, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
#endif
add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
- add_prefix (&startfile_prefixes, standard_exec_prefix_1, "BINUTILS",
+ add_prefix (&startfile_prefixes, standard_exec_prefix_2, "BINUTILS",
PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
tooldir_prefix = concat (tooldir_base_prefix, spec_machine,
@@ -3647,7 +3775,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
directories, so that we can search both the user specified directory
and the standard place. */
- if (!IS_ABSOLUTE_PATHNAME (tooldir_prefix))
+ if (!IS_ABSOLUTE_PATH (tooldir_prefix))
{
if (gcc_exec_prefix)
{
@@ -3677,14 +3805,31 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
concat (tooldir_prefix, "lib", dir_separator_str, NULL),
"BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
+#if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
+ /* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
+ then consider it to relocate with the rest of the GCC installation
+ if GCC_EXEC_PREFIX is set.
+ ``make_relative_prefix'' is not compiled for VMS, so don't call it. */
+ if (target_system_root && gcc_exec_prefix)
+ {
+ char *tmp_prefix = make_relative_prefix (argv[0],
+ standard_bindir_prefix,
+ target_system_root);
+ if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0)
+ {
+ target_system_root = tmp_prefix;
+ target_system_root_changed = 1;
+ }
+ }
+#endif
+
/* More prefixes are enabled in main, after we read the specs file
and determine whether this is cross-compilation or not. */
/* Then create the space for the vectors and scan again. */
- switches = ((struct switchstr *)
- xmalloc ((n_switches + 1) * sizeof (struct switchstr)));
- infiles = (struct infile *) xmalloc ((n_infiles + 1) * sizeof (struct infile));
+ switches = xmalloc ((n_switches + 1) * sizeof (struct switchstr));
+ infiles = xmalloc ((n_infiles + 1) * sizeof (struct infile));
n_switches = 0;
n_infiles = 0;
last_language_n_infiles = -1;
@@ -3766,6 +3911,16 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
infiles[n_infiles].language = "*";
infiles[n_infiles++].name = argv[++i];
}
+ else if (strcmp (argv[i], "-Xassembler") == 0)
+ {
+ infiles[n_infiles].language = "*";
+ infiles[n_infiles++].name = argv[++i];
+ }
+ else if (strcmp (argv[i], "-Xpreprocessor") == 0)
+ {
+ infiles[n_infiles].language = "*";
+ infiles[n_infiles++].name = argv[++i];
+ }
else if (strcmp (argv[i], "-l") == 0)
{ /* POSIX allows separation of -l and the lib arg;
canonicalize by concatenating -l with its arg */
@@ -3783,17 +3938,6 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
;
else if (strcmp (argv[i], "-time") == 0)
;
- else if ((save_temps_flag || report_times)
- && strcmp (argv[i], "-pipe") == 0)
- {
- /* -save-temps overrides -pipe, so that temp files are produced */
- if (save_temps_flag)
- error ("warning: -pipe ignored because -save-temps specified");
- /* -time overrides -pipe because we can't get correct stats when
- multiple children are running at once. */
- else if (report_times)
- error ("warning: -pipe ignored because -time specified");
- }
else if (strcmp (argv[i], "-###") == 0)
;
else if (argv[i][0] == '-' && argv[i][1] != 0)
@@ -3834,7 +3978,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
if (i + n_args >= argc)
fatal ("argument to `-%s' is missing", p);
switches[n_switches].args
- = (const char **) xmalloc ((n_args + 1) * sizeof(const char *));
+ = xmalloc ((n_args + 1) * sizeof(const char *));
while (j < n_args)
switches[n_switches].args[j++] = argv[++i];
/* Null-terminate the vector. */
@@ -3844,13 +3988,12 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
{
/* On some systems, ld cannot handle some options without
a space. So split the option from its argument. */
- char *part1 = (char *) xmalloc (2);
+ char *part1 = xmalloc (2);
part1[0] = c;
part1[1] = '\0';
switches[n_switches].part1 = part1;
- switches[n_switches].args
- = (const char **) xmalloc (2 * sizeof (const char *));
+ switches[n_switches].args = xmalloc (2 * sizeof (const char *));
switches[n_switches].args[0] = xstrdup (p+1);
switches[n_switches].args[1] = 0;
}
@@ -3860,10 +4003,11 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
switches[n_switches].live_cond = SWITCH_OK;
switches[n_switches].validated = 0;
switches[n_switches].ordering = 0;
- /* These are always valid, since gcc.c itself understands it. */
+ /* These are always valid, since gcc.c itself understands them. */
if (!strcmp (p, "save-temps")
|| !strcmp (p, "static-libgcc")
- || !strcmp (p, "shared-libgcc"))
+ || !strcmp (p, "shared-libgcc")
+ || !strcmp (p, "pipe"))
switches[n_switches].validated = 1;
else
{
@@ -3930,11 +4074,11 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
infiles[n_infiles].name = 0;
}
-/* Store switches not filtered out by %{<S} in spec in COLLECT_GCC_OPTIONS
+/* Store switches not filtered out by %<S in spec in COLLECT_GCC_OPTIONS
and place that in the environment. */
static void
-set_collect_gcc_options ()
+set_collect_gcc_options (void)
{
int i;
int first_time;
@@ -3996,7 +4140,7 @@ set_collect_gcc_options ()
sans all directory names, and basename_length is the number
of characters starting there excluding the suffix .c or whatever. */
-const char *input_filename;
+static const char *input_filename;
static int input_file_number;
size_t input_filename_length;
static int basename_length;
@@ -4039,8 +4183,7 @@ static const char *suffix_subst;
Returns 0 if the spec is successfully processed; -1 if failed. */
int
-do_spec (spec)
- const char *spec;
+do_spec (const char *spec)
{
int value;
@@ -4063,9 +4206,11 @@ do_spec (spec)
}
static int
-do_spec_2 (spec)
- const char *spec;
+do_spec_2 (const char *spec)
{
+ const char *string;
+ int result;
+
clear_args ();
arg_going = 0;
delete_this_arg = 0;
@@ -4074,7 +4219,22 @@ do_spec_2 (spec)
input_from_pipe = 0;
suffix_subst = NULL;
- return do_spec_1 (spec, 0, NULL);
+ result = do_spec_1 (spec, 0, NULL);
+
+ /* End any pending argument. */
+ if (arg_going)
+ {
+ obstack_1grow (&obstack, 0);
+ string = obstack_finish (&obstack);
+ if (this_is_library_file)
+ string = find_file (string);
+ store_arg (string, delete_this_arg, this_is_output_file);
+ if (this_is_output_file)
+ outfiles[input_file_number] = string;
+ arg_going = 0;
+ }
+
+ return result;
}
@@ -4082,8 +4242,56 @@ do_spec_2 (spec)
of the switches/n_switches array. */
static void
-do_self_spec (spec)
- const char *spec;
+do_option_spec (const char *name, const char *spec)
+{
+ unsigned int i, value_count, value_len;
+ const char *p, *q, *value;
+ char *tmp_spec, *tmp_spec_p;
+
+ if (configure_default_options[0].name == NULL)
+ return;
+
+ for (i = 0; i < ARRAY_SIZE (configure_default_options); i++)
+ if (strcmp (configure_default_options[i].name, name) == 0)
+ break;
+ if (i == ARRAY_SIZE (configure_default_options))
+ return;
+
+ value = configure_default_options[i].value;
+ value_len = strlen (value);
+
+ /* Compute the size of the final spec. */
+ value_count = 0;
+ p = spec;
+ while ((p = strstr (p, "%(VALUE)")) != NULL)
+ {
+ p ++;
+ value_count ++;
+ }
+
+ /* Replace each %(VALUE) by the specified value. */
+ tmp_spec = alloca (strlen (spec) + 1
+ + value_count * (value_len - strlen ("%(VALUE)")));
+ tmp_spec_p = tmp_spec;
+ q = spec;
+ while ((p = strstr (q, "%(VALUE)")) != NULL)
+ {
+ memcpy (tmp_spec_p, q, p - q);
+ tmp_spec_p = tmp_spec_p + (p - q);
+ memcpy (tmp_spec_p, value, value_len);
+ tmp_spec_p += value_len;
+ q = p + strlen ("%(VALUE)");
+ }
+ strcpy (tmp_spec_p, q);
+
+ do_self_spec (tmp_spec);
+}
+
+/* Process the given spec string and add any new options to the end
+ of the switches/n_switches array. */
+
+static void
+do_self_spec (const char *spec)
{
do_spec_2 (spec);
do_spec_1 (" ", 0, NULL);
@@ -4129,10 +4337,7 @@ do_self_spec (spec)
and the command on that line reported an error. */
static int
-do_spec_1 (spec, inswitch, soft_matched_part)
- const char *spec;
- int inswitch;
- const char *soft_matched_part;
+do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
{
const char *p = spec;
int c;
@@ -4162,17 +4367,12 @@ do_spec_1 (spec, inswitch, soft_matched_part)
if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))
{
- for (i = 0; i < n_switches; i++)
- if (!strcmp (switches[i].part1, "pipe"))
- break;
-
/* A `|' before the newline means use a pipe here,
but only if -pipe was specified.
Otherwise, execute now and don't pass the `|' as an arg. */
- if (i < n_switches)
+ if (use_pipes)
{
input_from_pipe = 1;
- switches[i].validated = 1;
break;
}
else
@@ -4261,7 +4461,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
{
struct prefix_list *pl = startfile_prefixes.plist;
size_t bufsize = 100;
- char *buffer = (char *) xmalloc (bufsize);
+ char *buffer = xmalloc (bufsize);
int idx;
for (; pl; pl = pl->next)
@@ -4272,7 +4472,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
/* Relative directories always come from -B,
and it is better not to use them for searching
at run time. In particular, stage1 loses. */
- if (!IS_ABSOLUTE_PATHNAME (pl->prefix))
+ if (!IS_ABSOLUTE_PATH (pl->prefix))
continue;
#endif
/* Try subdirectory if there is one. */
@@ -4289,7 +4489,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
>= bufsize)
bufsize = (strlen (pl->prefix)
+ strlen (machine_suffix)) * 2 + 1;
- buffer = (char *) xrealloc (buffer, bufsize);
+ buffer = xrealloc (buffer, bufsize);
strcpy (buffer, pl->prefix);
strcat (buffer, machine_suffix);
if (is_directory (buffer, multilib_dir, 1))
@@ -4331,7 +4531,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
/* Remove slash from machine_suffix. */
if (strlen (machine_suffix) >= bufsize)
bufsize = strlen (machine_suffix) * 2 + 1;
- buffer = (char *) xrealloc (buffer, bufsize);
+ buffer = xrealloc (buffer, bufsize);
strcpy (buffer, machine_suffix);
idx = strlen (buffer);
if (IS_DIR_SEPARATOR (buffer[idx - 1]))
@@ -4352,7 +4552,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
/* Remove slash from pl->prefix. */
if (strlen (pl->prefix) >= bufsize)
bufsize = strlen (pl->prefix) * 2 + 1;
- buffer = (char *) xrealloc (buffer, bufsize);
+ buffer = xrealloc (buffer, bufsize);
strcpy (buffer, pl->prefix);
idx = strlen (buffer);
if (IS_DIR_SEPARATOR (buffer[idx - 1]))
@@ -4375,7 +4575,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
char *buf;
while (*p != 0 && *p != '\n')
p++;
- buf = (char *) alloca (p - q + 1);
+ buf = alloca (p - q + 1);
strncpy (buf, q, p - q);
buf[p - q] = 0;
error ("%s", buf);
@@ -4389,7 +4589,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
char *buf;
while (*p != 0 && *p != '\n')
p++;
- buf = (char *) alloca (p - q + 1);
+ buf = alloca (p - q + 1);
strncpy (buf, q, p - q);
buf[p - q] = 0;
notice ("%s\n", buf);
@@ -4402,10 +4602,10 @@ do_spec_1 (spec, inswitch, soft_matched_part)
{
struct stat st;
- /* If save_temps_flag is off, and the HOST_BIT_BUCKET is defined,
- and it is not a directory, and it is writable, use it.
- Otherwise, fall through and treat this like any other
- temporary file. */
+ /* If save_temps_flag is off, and the HOST_BIT_BUCKET is
+ defined, and it is not a directory, and it is
+ writable, use it. Otherwise, treat this like any
+ other temporary file. */
if ((!save_temps_flag)
&& (stat (HOST_BIT_BUCKET, &st) == 0) && (!S_ISDIR (st.st_mode))
@@ -4418,9 +4618,39 @@ do_spec_1 (spec, inswitch, soft_matched_part)
break;
}
}
+ goto create_temp_file;
+ case '|':
+ if (use_pipes)
+ {
+ obstack_1grow (&obstack, '-');
+ delete_this_arg = 0;
+ arg_going = 1;
+
+ /* consume suffix */
+ while (*p == '.' || ISALPHA ((unsigned char) *p))
+ p++;
+ if (p[0] == '%' && p[1] == 'O')
+ p += 2;
+
+ break;
+ }
+ goto create_temp_file;
+ case 'm':
+ if (use_pipes)
+ {
+ /* consume suffix */
+ while (*p == '.' || ISALPHA ((unsigned char) *p))
+ p++;
+ if (p[0] == '%' && p[1] == 'O')
+ p += 2;
+
+ break;
+ }
+ goto create_temp_file;
case 'g':
case 'u':
case 'U':
+ create_temp_file:
{
struct temp_name *t;
int suffix_length;
@@ -4441,8 +4671,8 @@ do_spec_1 (spec, inswitch, soft_matched_part)
else
{
saved_suffix
- = (char *) xmalloc (suffix_length
- + strlen (TARGET_OBJECT_SUFFIX));
+ = xmalloc (suffix_length
+ + strlen (TARGET_OBJECT_SUFFIX));
strncpy (saved_suffix, suffix, suffix_length);
strcpy (saved_suffix + suffix_length,
TARGET_OBJECT_SUFFIX);
@@ -4464,24 +4694,24 @@ do_spec_1 (spec, inswitch, soft_matched_part)
temp_filename = alloca (temp_filename_length + 1);
strncpy ((char *) temp_filename, input_basename, basename_length);
strncpy ((char *) temp_filename + basename_length, suffix,
- suffix_length);
+ suffix_length);
*((char *) temp_filename + temp_filename_length) = '\0';
if (strcmp (temp_filename, input_filename) != 0)
{
- struct stat st_temp;
+ struct stat st_temp;
- /* Note, set_input() resets input_stat_set to 0. */
- if (input_stat_set == 0)
- {
- input_stat_set = stat (input_filename, &input_stat);
- if (input_stat_set >= 0)
- input_stat_set = 1;
- }
+ /* Note, set_input() resets input_stat_set to 0. */
+ if (input_stat_set == 0)
+ {
+ input_stat_set = stat (input_filename, &input_stat);
+ if (input_stat_set >= 0)
+ input_stat_set = 1;
+ }
- /* If we have the stat for the input_filename
- and we can do the stat for the temp_filename
- then the they could still refer to the same
- file if st_dev/st_ino's are the same. */
+ /* If we have the stat for the input_filename
+ and we can do the stat for the temp_filename
+ then the they could still refer to the same
+ file if st_dev/st_ino's are the same. */
if (input_stat_set != 1
|| stat (temp_filename, &st_temp) < 0
@@ -4491,7 +4721,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
temp_filename = save_string (temp_filename,
temp_filename_length + 1);
obstack_grow (&obstack, temp_filename,
- temp_filename_length);
+ temp_filename_length);
arg_going = 1;
delete_this_arg = 0;
break;
@@ -4504,7 +4734,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
for (t = temp_names; t; t = t->next)
if (t->length == suffix_length
&& strncmp (t->suffix, suffix, suffix_length) == 0
- && t->unique == (c != 'g'))
+ && t->unique == (c == 'u' || c == 'U' || c == 'j'))
break;
/* Make a new association if needed. %u and %j
@@ -4513,7 +4743,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
{
if (t == 0)
{
- t = (struct temp_name *) xmalloc (sizeof (struct temp_name));
+ t = xmalloc (sizeof (struct temp_name));
t->next = temp_names;
temp_names = t;
}
@@ -4525,7 +4755,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
}
else
t->suffix = save_string (suffix, suffix_length);
- t->unique = (c != 'g');
+ t->unique = (c == 'u' || c == 'U' || c == 'j');
temp_filename = make_temp_file (t->suffix);
temp_filename_length = strlen (temp_filename);
t->filename = temp_filename;
@@ -4542,8 +4772,16 @@ do_spec_1 (spec, inswitch, soft_matched_part)
break;
case 'i':
- obstack_grow (&obstack, input_filename, input_filename_length);
- arg_going = 1;
+ if (combine_inputs)
+ {
+ for (i = 0; (int) i < n_infiles; i++)
+ store_arg (infiles[i].name, 0, 0);
+ }
+ else
+ {
+ obstack_grow (&obstack, input_filename, input_filename_length);
+ arg_going = 1;
+ }
break;
case 'I':
@@ -4559,6 +4797,18 @@ do_spec_1 (spec, inswitch, soft_matched_part)
do_spec_1 (" ", 0, NULL);
}
+ if (target_system_root_changed ||
+ (target_system_root && target_sysroot_hdrs_suffix))
+ {
+ do_spec_1 ("-isysroot", 1, NULL);
+ /* Make this a separate argument. */
+ do_spec_1 (" ", 0, NULL);
+ do_spec_1 (target_system_root, 1, NULL);
+ if (target_sysroot_hdrs_suffix)
+ do_spec_1 (target_sysroot_hdrs_suffix, 1, NULL);
+ do_spec_1 (" ", 0, NULL);
+ }
+
for (; pl; pl = pl->next)
{
do_spec_1 ("-isystem", 1, NULL);
@@ -4590,6 +4840,10 @@ do_spec_1 (spec, inswitch, soft_matched_part)
this_is_library_file = 1;
break;
+ case 'V':
+ outfiles[input_file_number] = NULL;
+ break;
+
case 'w':
this_is_output_file = 1;
break;
@@ -4603,6 +4857,18 @@ do_spec_1 (spec, inswitch, soft_matched_part)
p = handle_braces (p + 1);
if (p == 0)
return -1;
+ /* End any pending argument. */
+ if (arg_going)
+ {
+ obstack_1grow (&obstack, 0);
+ string = obstack_finish (&obstack);
+ if (this_is_library_file)
+ string = find_file (string);
+ store_arg (string, delete_this_arg, this_is_output_file);
+ if (this_is_output_file)
+ outfiles[input_file_number] = string;
+ arg_going = 0;
+ }
/* If any args were output, mark the last one for deletion
on failure. */
if (argbuf_index != cur_index)
@@ -4746,165 +5012,17 @@ do_spec_1 (spec, inswitch, soft_matched_part)
}
break;
- case 'p':
- {
- char *x = (char *) alloca (strlen (cpp_predefines) + 1);
- char *buf = x;
- const char *y;
-
- /* Copy all of the -D options in CPP_PREDEFINES into BUF. */
- y = cpp_predefines;
- while (*y != 0)
- {
- if (! strncmp (y, "-D", 2))
- /* Copy the whole option. */
- while (*y && *y != ' ' && *y != '\t')
- *x++ = *y++;
- else if (*y == ' ' || *y == '\t')
- /* Copy whitespace to the result. */
- *x++ = *y++;
- /* Don't copy other options. */
- else
- y++;
- }
-
- *x = 0;
-
- value = do_spec_1 (buf, 0, NULL);
- if (value != 0)
- return value;
- }
- break;
-
- case 'P':
- {
- char *x = (char *) alloca (strlen (cpp_predefines) * 4 + 1);
- char *buf = x;
- const char *y;
-
- /* Copy all of CPP_PREDEFINES into BUF,
- but force them all into the reserved name space if they
- aren't already there. The reserved name space is all
- identifiers beginning with two underscores or with one
- underscore and a capital letter. We do the forcing by
- adding up to two underscores to the beginning and end
- of each symbol. e.g. mips, _mips, mips_, and _mips_ all
- become __mips__. */
- y = cpp_predefines;
- while (*y != 0)
- {
- if (! strncmp (y, "-D", 2))
- {
- int flag = 0;
-
- *x++ = *y++;
- *x++ = *y++;
-
- if (*y != '_'
- || (*(y + 1) != '_'
- && ! ISUPPER ((unsigned char) *(y + 1))))
- {
- /* Stick __ at front of macro name. */
- if (*y != '_')
- *x++ = '_';
- *x++ = '_';
- /* Arrange to stick __ at the end as well. */
- flag = 1;
- }
-
- /* Copy the macro name. */
- while (*y && *y != '=' && *y != ' ' && *y != '\t')
- *x++ = *y++;
-
- if (flag)
- {
- if (x[-1] != '_')
- {
- if (x[-2] != '_')
- *x++ = '_';
- *x++ = '_';
- }
- }
-
- /* Copy the value given, if any. */
- while (*y && *y != ' ' && *y != '\t')
- *x++ = *y++;
- }
- else if (*y == ' ' || *y == '\t')
- /* Copy whitespace to the result. */
- *x++ = *y++;
- /* Don't copy -A options */
- else
- y++;
- }
- *x++ = ' ';
-
- /* Copy all of CPP_PREDEFINES into BUF,
- but put __ after every -D. */
- y = cpp_predefines;
- while (*y != 0)
- {
- if (! strncmp (y, "-D", 2))
- {
- y += 2;
-
- if (*y != '_'
- || (*(y + 1) != '_'
- && ! ISUPPER ((unsigned char) *(y + 1))))
- {
- /* Stick -D__ at front of macro name. */
- *x++ = '-';
- *x++ = 'D';
- if (*y != '_')
- *x++ = '_';
- *x++ = '_';
-
- /* Copy the macro name. */
- while (*y && *y != '=' && *y != ' ' && *y != '\t')
- *x++ = *y++;
-
- /* Copy the value given, if any. */
- while (*y && *y != ' ' && *y != '\t')
- *x++ = *y++;
- }
- else
- {
- /* Do not copy this macro - we have just done it before */
- while (*y && *y != ' ' && *y != '\t')
- y++;
- }
- }
- else if (*y == ' ' || *y == '\t')
- /* Copy whitespace to the result. */
- *x++ = *y++;
- /* Don't copy -A options. */
- else
- y++;
- }
- *x++ = ' ';
-
- /* Copy all of the -A options in CPP_PREDEFINES into BUF. */
- y = cpp_predefines;
- while (*y != 0)
- {
- if (! strncmp (y, "-A", 2))
- /* Copy the whole option. */
- while (*y && *y != ' ' && *y != '\t')
- *x++ = *y++;
- else if (*y == ' ' || *y == '\t')
- /* Copy whitespace to the result. */
- *x++ = *y++;
- /* Don't copy other options. */
- else
- y++;
- }
-
- *x = 0;
-
- value = do_spec_1 (buf, 0, NULL);
- if (value != 0)
- return value;
- }
+ case 'R':
+ /* We assume there is a directory
+ separator at the end of this string. */
+ if (target_system_root)
+ {
+ obstack_grow (&obstack, target_system_root,
+ strlen (target_system_root));
+ if (target_sysroot_suffix)
+ obstack_grow (&obstack, target_sysroot_suffix,
+ strlen (target_sysroot_suffix));
+ }
break;
case 'S':
@@ -4942,6 +5060,32 @@ do_spec_1 (spec, inswitch, soft_matched_part)
}
break;
+ /* Henceforth ignore the option(s) matching the pattern
+ after the %<. */
+ case '<':
+ {
+ unsigned len = 0;
+ int have_wildcard = 0;
+ int i;
+
+ while (p[len] && p[len] != ' ' && p[len] != '\t')
+ len++;
+
+ if (p[len-1] == '*')
+ have_wildcard = 1;
+
+ for (i = 0; i < n_switches; i++)
+ if (!strncmp (switches[i].part1, p, len - have_wildcard)
+ && (have_wildcard || switches[i].part1[len] == '\0'))
+ {
+ switches[i].live_cond = SWITCH_IGNORE;
+ switches[i].validated = 1;
+ }
+
+ p += len;
+ }
+ break;
+
case '*':
if (soft_matched_part)
{
@@ -4995,7 +5139,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
}
else
{
- char *x = (char *) alloca (strlen (name) * 2 + 1);
+ char *x = alloca (strlen (name) * 2 + 1);
char *buf = x;
const char *y = name;
int flag = 0;
@@ -5041,68 +5185,6 @@ do_spec_1 (spec, inswitch, soft_matched_part)
}
break;
- case 'v':
- {
- int c1 = *p++; /* Select first or second version number. */
- const char *v = compiler_version;
- const char *q;
- static const char zeroc = '0';
-
- /* The format of the version string is
- ([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)? */
-
- /* Ignore leading non-digits. i.e. "foo-" in "foo-2.7.2". */
- while (! ISDIGIT (*v))
- v++;
- if (v > compiler_version && v[-1] != '-')
- abort ();
-
- /* If desired, advance to second version number. */
- if (c1 >= '2')
- {
- /* Set V after the first period. */
- while (ISDIGIT (*v))
- v++;
- if (*v != '.')
- abort ();
- v++;
- }
-
- /* If desired, advance to third version number.
- But don't complain if it's not present */
- if (c1 == '3')
- {
- /* Set V after the second period. */
- while (ISDIGIT (*v))
- v++;
- if ((*v != 0) && (*v != ' ') && (*v != '.') && (*v != '-'))
- abort ();
- if (*v != 0)
- v++;
- }
-
- /* Set Q at the next period or at the end. */
- q = v;
- while (ISDIGIT (*q))
- q++;
- if (*q != 0 && q > v && *q != ' ' && *q != '.' && *q != '-')
- abort ();
-
- if (q > v)
- /* Put that part into the command. */
- obstack_grow (&obstack, v, q - v);
- else
- /* Default to "0" */
- obstack_grow (&obstack, &zeroc, 1);
- arg_going = 1;
- }
- break;
-
- case '|':
- if (input_from_pipe)
- do_spec_1 ("-", 0, NULL);
- break;
-
default:
error ("spec failure: unrecognized spec option '%c'", c);
break;
@@ -5113,7 +5195,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
/* Backslash: treat next character as ordinary. */
c = *p++;
- /* fall through */
+ /* Fall through. */
default:
/* Ordinary character: put it into the current argument. */
obstack_1grow (&obstack, c);
@@ -5140,8 +5222,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
/* Look up a spec function. */
static const struct spec_function *
-lookup_spec_function (name)
- const char *name;
+lookup_spec_function (const char *name)
{
static const struct spec_function * const spec_function_tables[] =
{
@@ -5164,8 +5245,7 @@ lookup_spec_function (name)
/* Evaluate a spec function. */
static const char *
-eval_spec_function (func, args)
- const char *func, *args;
+eval_spec_function (const char *func, const char *args)
{
const struct spec_function *sf;
const char *funcval;
@@ -5237,8 +5317,7 @@ eval_spec_function (func, args)
NULL if no processing is required. */
static const char *
-handle_spec_function (p)
- const char *p;
+handle_spec_function (const char *p)
{
char *func, *args;
const char *endp, *funcval;
@@ -5293,273 +5372,290 @@ handle_spec_function (p)
return p;
}
-/* Return 0 if we call do_spec_1 and that returns -1. */
+/* Inline subroutine of handle_braces. Returns true if the current
+ input suffix matches the atom bracketed by ATOM and END_ATOM. */
+static inline bool
+input_suffix_matches (const char *atom, const char *end_atom)
+{
+ return (input_suffix
+ && !strncmp (input_suffix, atom, end_atom - atom)
+ && input_suffix[end_atom - atom] == '\0');
+}
-static const char *
-handle_braces (p)
- const char *p;
+/* Inline subroutine of handle_braces. Returns true if a switch
+ matching the atom bracketed by ATOM and END_ATOM appeared on the
+ command line. */
+static inline bool
+switch_matches (const char *atom, const char *end_atom, int starred)
{
- const char *filter, *body = NULL, *endbody = NULL;
- int pipe_p = 0;
- int true_once = 0; /* If, in %{a|b:d}, at least one of a,b was seen. */
- int negate;
- int suffix;
- int include_blanks = 1;
- int elide_switch = 0;
- int ordered = 0;
-
- if (*p == '^')
- {
- /* A '^' after the open-brace means to not give blanks before args. */
- include_blanks = 0;
- ++p;
- }
+ int i;
+ int len = end_atom - atom;
+ int plen = starred ? len : -1;
- if (*p == '|')
- {
- /* A `|' after the open-brace means,
- if the test fails, output a single minus sign rather than nothing.
- This is used in %{|!pipe:...}. */
- pipe_p = 1;
- ++p;
- }
+ for (i = 0; i < n_switches; i++)
+ if (!strncmp (switches[i].part1, atom, len)
+ && (starred || switches[i].part1[len] == '\0')
+ && check_live_switch (i, plen))
+ return true;
- if (*p == '<')
- {
- /* A `<' after the open-brace means that the switch should be
- removed from the command-line. */
- elide_switch = 1;
- ++p;
- }
+ return false;
+}
-next_member:
- negate = suffix = 0;
+/* Inline subroutine of handle_braces. Mark all of the switches which
+ match ATOM (extends to END_ATOM; STARRED indicates whether there
+ was a star after the atom) for later processing. */
+static inline void
+mark_matching_switches (const char *atom, const char *end_atom, int starred)
+{
+ int i;
+ int len = end_atom - atom;
+ int plen = starred ? len : -1;
+
+ for (i = 0; i < n_switches; i++)
+ if (!strncmp (switches[i].part1, atom, len)
+ && (starred || switches[i].part1[len] == '\0')
+ && check_live_switch (i, plen))
+ switches[i].ordering = 1;
+}
- if (*p == '!')
- /* A `!' after the open-brace negates the condition:
- succeed if the specified switch is not present. */
- negate = 1, ++p;
+/* Inline subroutine of handle_braces. Process all the currently
+ marked switches through give_switch, and clear the marks. */
+static inline void
+process_marked_switches (void)
+{
+ int i;
- if (*p == '.')
- /* A `.' after the open-brace means test against the current suffix. */
- {
- if (pipe_p)
- abort ();
+ for (i = 0; i < n_switches; i++)
+ if (switches[i].ordering == 1)
+ {
+ switches[i].ordering = 0;
+ give_switch (i, 0);
+ }
+}
- suffix = 1;
- ++p;
- }
+/* Handle a %{ ... } construct. P points just inside the leading {.
+ Returns a pointer one past the end of the brace block, or 0
+ if we call do_spec_1 and that returns -1. */
- if (elide_switch && (negate || pipe_p || suffix))
- {
- /* It doesn't make sense to mix elision with other flags. We
- could fatal() here, but the standard seems to be to abort. */
- abort ();
- }
+static const char *
+handle_braces (const char *p)
+{
+ const char *atom, *end_atom;
+ const char *d_atom = NULL, *d_end_atom = NULL;
- next_ampersand:
- filter = p;
- while (*p != ':' && *p != '}' && *p != '|' && *p != '&')
- p++;
+ bool a_is_suffix;
+ bool a_is_starred;
+ bool a_is_negated;
+ bool a_matched;
- if (*p == '|' && (pipe_p || ordered))
- abort ();
+ bool a_must_be_last = false;
+ bool ordered_set = false;
+ bool disjunct_set = false;
+ bool disj_matched = false;
+ bool disj_starred = true;
+ bool n_way_choice = false;
+ bool n_way_matched = false;
- if (!body)
+#define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
+
+ do
{
- if (*p != '}' && *p != '&')
- {
- int count = 1;
- const char *q = p;
+ if (a_must_be_last)
+ abort ();
- while (*q++ != ':')
- continue;
- body = q;
+ /* Scan one "atom" (S in the description above of %{}, possibly
+ with !, ., or * modifiers). */
+ a_matched = a_is_suffix = a_is_starred = a_is_negated = false;
- while (count > 0)
- {
- if (*q == '{')
- count++;
- else if (*q == '}')
- count--;
- else if (*q == 0)
- fatal ("mismatched braces in specs");
- q++;
- }
- endbody = q;
- }
- else
- body = p, endbody = p + 1;
- }
+ SKIP_WHITE();
+ if (*p == '!')
+ p++, a_is_negated = true;
- if (suffix)
- {
- int found = (input_suffix != 0
- && (long) strlen (input_suffix) == (long) (p - filter)
- && strncmp (input_suffix, filter, p - filter) == 0);
+ SKIP_WHITE();
+ if (*p == '.')
+ p++, a_is_suffix = true;
- if (body[0] == '}')
- abort ();
+ atom = p;
+ while (ISIDNUM(*p) || *p == '-' || *p == '+' || *p == '='
+ || *p == ',' || *p == '.' || *p == '@')
+ p++;
+ end_atom = p;
- if (negate != found
- && do_spec_1 (save_string (body, endbody-body-1), 0, NULL) < 0)
- return 0;
- }
- else if (p[-1] == '*' && (p[0] == '}' || p[0] == '&'))
- {
- /* Substitute all matching switches as separate args. */
- int i;
+ if (*p == '*')
+ p++, a_is_starred = 1;
- for (i = 0; i < n_switches; i++)
- if (!strncmp (switches[i].part1, filter, p - 1 - filter)
- && check_live_switch (i, p - 1 - filter))
- {
- if (elide_switch)
- {
- switches[i].live_cond = SWITCH_IGNORE;
- switches[i].validated = 1;
- }
- else
- ordered = 1, switches[i].ordering = 1;
- }
- }
- else
- {
- /* Test for presence of the specified switch. */
- int i;
- int present = 0;
+ SKIP_WHITE();
+ if (*p == '&' || *p == '}')
+ {
+ /* Substitute the switch(es) indicated by the current atom. */
+ ordered_set = true;
+ if (disjunct_set || n_way_choice || a_is_negated || a_is_suffix
+ || atom == end_atom)
+ abort ();
+
+ mark_matching_switches (atom, end_atom, a_is_starred);
- /* If name specified ends in *, as in {x*:...},
- check for %* and handle that case. */
- if (p[-1] == '*' && !negate)
+ if (*p == '}')
+ process_marked_switches ();
+ }
+ else if (*p == '|' || *p == ':')
{
- int substitution;
- const char *r = body;
+ /* Substitute some text if the current atom appears as a switch
+ or suffix. */
+ disjunct_set = true;
+ if (ordered_set)
+ abort ();
- /* First see whether we have %*. */
- substitution = 0;
- while (r < endbody)
+ if (atom == end_atom)
{
- if (*r == '%' && r[1] == '*')
- substitution = 1;
- r++;
+ if (!n_way_choice || disj_matched || *p == '|'
+ || a_is_negated || a_is_suffix || a_is_starred)
+ abort ();
+
+ /* An empty term may appear as the last choice of an
+ N-way choice set; it means "otherwise". */
+ a_must_be_last = true;
+ disj_matched = !n_way_matched;
+ disj_starred = false;
}
- /* If we do, handle that case. */
- if (substitution)
+ else
{
- /* Substitute all matching switches as separate args.
- But do this by substituting for %*
- in the text that follows the colon. */
-
- unsigned hard_match_len = p - filter - 1;
- char *string = save_string (body, endbody - body - 1);
-
- for (i = 0; i < n_switches; i++)
- if (!strncmp (switches[i].part1, filter, hard_match_len)
- && check_live_switch (i, -1))
- {
- do_spec_1 (string, 0, &switches[i].part1[hard_match_len]);
- /* Pass any arguments this switch has. */
- give_switch (i, 1, 1);
- suffix_subst = NULL;
- }
-
- /* We didn't match. Try again. */
- if (*p++ == '|')
- goto next_member;
- return endbody;
+ if (a_is_suffix && a_is_starred)
+ abort ();
+
+ if (!a_is_starred)
+ disj_starred = false;
+
+ /* Don't bother testing this atom if we already have a
+ match. */
+ if (!disj_matched && !n_way_matched)
+ {
+ if (a_is_suffix)
+ a_matched = input_suffix_matches (atom, end_atom);
+ else
+ a_matched = switch_matches (atom, end_atom, a_is_starred);
+
+ if (a_matched != a_is_negated)
+ {
+ disj_matched = true;
+ d_atom = atom;
+ d_end_atom = end_atom;
+ }
+ }
}
- }
- /* If name specified ends in *, as in {x*:...},
- check for presence of any switch name starting with x. */
- if (p[-1] == '*')
- {
- for (i = 0; i < n_switches; i++)
+ if (*p == ':')
{
- unsigned hard_match_len = p - filter - 1;
+ /* Found the body, that is, the text to substitute if the
+ current disjunction matches. */
+ p = process_brace_body (p + 1, d_atom, d_end_atom, disj_starred,
+ disj_matched && !n_way_matched);
+ if (p == 0)
+ return 0;
- if (!strncmp (switches[i].part1, filter, hard_match_len)
- && check_live_switch (i, hard_match_len))
+ /* If we have an N-way choice, reset state for the next
+ disjunction. */
+ if (*p == ';')
{
- present = 1;
- break;
+ n_way_choice = true;
+ n_way_matched |= disj_matched;
+ disj_matched = false;
+ disj_starred = true;
+ d_atom = d_end_atom = NULL;
}
}
}
- /* Otherwise, check for presence of exact name specified. */
else
- {
- for (i = 0; i < n_switches; i++)
- {
- if (!strncmp (switches[i].part1, filter, p - filter)
- && switches[i].part1[p - filter] == 0
- && check_live_switch (i, -1))
- {
- present = 1;
- break;
- }
- }
- }
+ abort ();
+ }
+ while (*p++ != '}');
- /* If it is as desired (present for %{s...}, absent for %{!s...})
- then substitute either the switch or the specified
- conditional text. */
- if (present != negate)
- {
- if (elide_switch)
- {
- switches[i].live_cond = SWITCH_IGNORE;
- switches[i].validated = 1;
- }
- else if (ordered || *p == '&')
- ordered = 1, switches[i].ordering = 1;
- else if (*p == '}')
- give_switch (i, 0, include_blanks);
- else
- /* Even if many alternatives are matched, only output once. */
- true_once = 1;
- }
- else if (pipe_p)
+ return p;
+
+#undef SKIP_WHITE
+}
+
+/* Subroutine of handle_braces. Scan and process a brace substitution body
+ (X in the description of %{} syntax). P points one past the colon;
+ ATOM and END_ATOM bracket the first atom which was found to be true
+ (present) in the current disjunction; STARRED indicates whether all
+ the atoms in the current disjunction were starred (for syntax validation);
+ MATCHED indicates whether the disjunction matched or not, and therefore
+ whether or not the body is to be processed through do_spec_1 or just
+ skipped. Returns a pointer to the closing } or ;, or 0 if do_spec_1
+ returns -1. */
+
+static const char *
+process_brace_body (const char *p, const char *atom, const char *end_atom,
+ int starred, int matched)
+{
+ const char *body, *end_body;
+ unsigned int nesting_level;
+ bool have_subst = false;
+
+ /* Locate the closing } or ;, honoring nested braces.
+ Trim trailing whitespace. */
+ body = p;
+ nesting_level = 1;
+ for (;;)
+ {
+ if (*p == '{')
+ nesting_level++;
+ else if (*p == '}')
{
- /* Here if a %{|...} conditional fails: output a minus sign,
- which means "standard output" or "standard input". */
- do_spec_1 ("-", 0, NULL);
- return endbody;
+ if (!--nesting_level)
+ break;
}
+ else if (*p == ';' && nesting_level == 1)
+ break;
+ else if (*p == '%' && p[1] == '*' && nesting_level == 1)
+ have_subst = true;
+ else if (*p == '\0')
+ abort ();
+ p++;
}
- /* We didn't match; try again. */
- if (*p++ == '|')
- goto next_member;
+ end_body = p;
+ while (end_body[-1] == ' ' || end_body[-1] == '\t')
+ end_body--;
- if (p[-1] == '&')
- {
- body = 0;
- goto next_ampersand;
- }
+ if (have_subst && !starred)
+ abort ();
- if (ordered)
- {
- int i;
- /* Doing this set of switches later preserves their command-line
- ordering. This is needed for e.g. -U, -D and -A. */
- for (i = 0; i < n_switches; i++)
- if (switches[i].ordering == 1)
- {
- switches[i].ordering = 0;
- give_switch (i, 0, include_blanks);
- }
- }
- /* Process the spec just once, regardless of match count. */
- else if (true_once)
+ if (matched)
{
- if (do_spec_1 (save_string (body, endbody - body - 1),
- 0, NULL) < 0)
- return 0;
+ /* Copy the substitution body to permanent storage and execute it.
+ If have_subst is false, this is a simple matter of running the
+ body through do_spec_1... */
+ char *string = save_string (body, end_body - body);
+ if (!have_subst)
+ {
+ if (do_spec_1 (string, 0, NULL) < 0)
+ return 0;
+ }
+ else
+ {
+ /* ... but if have_subst is true, we have to process the
+ body once for each matching switch, with %* set to the
+ variant part of the switch. */
+ unsigned int hard_match_len = end_atom - atom;
+ int i;
+
+ for (i = 0; i < n_switches; i++)
+ if (!strncmp (switches[i].part1, atom, hard_match_len)
+ && check_live_switch (i, hard_match_len))
+ {
+ if (do_spec_1 (string, 0,
+ &switches[i].part1[hard_match_len]) < 0)
+ return 0;
+ /* Pass any arguments this switch has. */
+ give_switch (i, 1);
+ suffix_subst = NULL;
+ }
+ }
}
- return endbody;
+ return p;
}
/* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
@@ -5571,9 +5667,7 @@ next_member:
with the "no-", similarly for a switch with the "no-" prefix. */
static int
-check_live_switch (switchnum, prefix_length)
- int switchnum;
- int prefix_length;
+check_live_switch (int switchnum, int prefix_length)
{
const char *name = switches[switchnum].part1;
int i;
@@ -5644,16 +5738,10 @@ check_live_switch (switchnum, prefix_length)
the vector of switches gcc received, which is `switches'.
This cannot fail since it never finishes a command line.
- If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument.
-
- If INCLUDE_BLANKS is nonzero, then we include blanks before each argument
- of the switch. */
+ If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument. */
static void
-give_switch (switchnum, omit_first_word, include_blanks)
- int switchnum;
- int omit_first_word;
- int include_blanks;
+give_switch (int switchnum, int omit_first_word)
{
if (switches[switchnum].live_cond == SWITCH_IGNORE)
return;
@@ -5671,8 +5759,7 @@ give_switch (switchnum, omit_first_word, include_blanks)
{
const char *arg = *p;
- if (include_blanks)
- do_spec_1 (" ", 0, NULL);
+ do_spec_1 (" ", 0, NULL);
if (suffix_subst)
{
unsigned length = strlen (arg);
@@ -5704,8 +5791,7 @@ give_switch (switchnum, omit_first_word, include_blanks)
Return the absolute file name found. If nothing is found, return NAME. */
static const char *
-find_file (name)
- const char *name;
+find_file (const char *name)
{
char *newname;
@@ -5730,14 +5816,11 @@ find_file (name)
limit. */
static int
-is_directory (path1, path2, linker)
- const char *path1;
- const char *path2;
- int linker;
+is_directory (const char *path1, const char *path2, int linker)
{
int len1 = strlen (path1);
int len2 = strlen (path2);
- char *path = (char *) alloca (3 + len1 + len2);
+ char *path = alloca (3 + len1 + len2);
char *cp;
struct stat st;
@@ -5775,8 +5858,7 @@ is_directory (path1, path2, linker)
the input file named FILENAME. */
void
-set_input (filename)
- const char *filename;
+set_input (const char *filename)
{
const char *p;
@@ -5817,8 +5899,7 @@ set_input (filename)
/* On fatal signals, delete all the temporary files. */
static void
-fatal_error (signum)
- int signum;
+fatal_error (int signum)
{
signal (signum, SIG_DFL);
delete_failure_queue ();
@@ -5828,16 +5909,15 @@ fatal_error (signum)
kill (getpid (), signum);
}
-extern int main PARAMS ((int, const char *const *));
+extern int main (int, const char **);
int
-main (argc, argv)
- int argc;
- const char *const *argv;
+main (int argc, const char **argv)
{
size_t i;
int value;
int linker_was_run = 0;
+ int num_linker_inputs = 0;
char *explicit_link_files;
char *specs_file;
const char *p;
@@ -5941,18 +6021,11 @@ main (argc, argv)
process_command (argc, argv);
- /* Process DRIVER_SELF_SPECS, adding any new options to the end
- of the command line. */
-
- for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
- do_self_spec (driver_self_specs[i]);
-
/* Initialize the vector of specs to just the default.
This means one element containing 0s, as a terminator. */
- compilers = (struct compiler *) xmalloc (sizeof default_compilers);
- memcpy ((char *) compilers, (char *) default_compilers,
- sizeof default_compilers);
+ compilers = xmalloc (sizeof default_compilers);
+ memcpy (compilers, default_compilers, sizeof default_compilers);
n_compilers = n_default_compilers;
/* Read specs from a file if there is one. */
@@ -5970,9 +6043,8 @@ main (argc, argv)
/* We need to check standard_exec_prefix/just_machine_suffix/specs
for any override of as, ld and libraries. */
- specs_file = (char *) alloca (strlen (standard_exec_prefix)
- + strlen (just_machine_suffix)
- + sizeof ("specs"));
+ specs_file = alloca (strlen (standard_exec_prefix)
+ + strlen (just_machine_suffix) + sizeof ("specs"));
strcpy (specs_file, standard_exec_prefix);
strcat (specs_file, just_machine_suffix);
@@ -5980,35 +6052,87 @@ main (argc, argv)
if (access (specs_file, R_OK) == 0)
read_specs (specs_file, TRUE);
- /* If not cross-compiling, look for startfiles in the standard places.
- Similarly, don't add the standard prefixes if startfile handling
- will be under control of startfile_prefix_spec. */
- if (*cross_compile == '0' && *startfile_prefix_spec == 0)
+ /* Process any configure-time defaults specified for the command line
+ options, via OPTION_DEFAULT_SPECS. */
+ for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
+ do_option_spec (option_default_specs[i].name,
+ option_default_specs[i].spec);
+
+ /* Process DRIVER_SELF_SPECS, adding any new options to the end
+ of the command line. */
+
+ for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
+ do_self_spec (driver_self_specs[i]);
+
+ /* If not cross-compiling, look for executables in the standard
+ places. */
+ if (*cross_compile == '0')
{
if (*md_exec_prefix)
{
add_prefix (&exec_prefixes, md_exec_prefix, "GCC",
PREFIX_PRIORITY_LAST, 0, NULL, 0);
- add_prefix (&startfile_prefixes, md_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL, 0);
}
+ }
+
+ /* Process sysroot_suffix_spec. */
+ if (*sysroot_suffix_spec != 0
+ && do_spec_2 (sysroot_suffix_spec) == 0)
+ {
+ if (argbuf_index > 1)
+ error ("spec failure: more than one arg to SYSROOT_SUFFIX_SPEC.");
+ else if (argbuf_index == 1)
+ target_sysroot_suffix = xstrdup (argbuf[argbuf_index -1]);
+ }
+
+ /* Process sysroot_hdrs_suffix_spec. */
+ if (*sysroot_hdrs_suffix_spec != 0
+ && do_spec_2 (sysroot_hdrs_suffix_spec) == 0)
+ {
+ if (argbuf_index > 1)
+ error ("spec failure: more than one arg to SYSROOT_HEADERS_SUFFIX_SPEC.");
+ else if (argbuf_index == 1)
+ target_sysroot_hdrs_suffix = xstrdup (argbuf[argbuf_index -1]);
+ }
+
+ /* Look for startfiles in the standard places. */
+ if (*startfile_prefix_spec != 0
+ && do_spec_2 (startfile_prefix_spec) == 0
+ && do_spec_1 (" ", 0, NULL) == 0)
+ {
+ int ndx;
+ for (ndx = 0; ndx < argbuf_index; ndx++)
+ add_sysrooted_prefix (&startfile_prefixes, argbuf[ndx], "BINUTILS",
+ PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ }
+ /* We should eventually get rid of all these and stick to
+ startfile_prefix_spec exclusively. */
+ else if (*cross_compile == '0' || target_system_root)
+ {
+ if (*md_exec_prefix)
+ add_sysrooted_prefix (&startfile_prefixes, md_exec_prefix, "GCC",
+ PREFIX_PRIORITY_LAST, 0, NULL, 1);
if (*md_startfile_prefix)
- add_prefix (&startfile_prefixes, md_startfile_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix,
+ "GCC", PREFIX_PRIORITY_LAST, 0, NULL, 1);
if (*md_startfile_prefix_1)
- add_prefix (&startfile_prefixes, md_startfile_prefix_1, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix_1,
+ "GCC", PREFIX_PRIORITY_LAST, 0, NULL, 1);
/* If standard_startfile_prefix is relative, base it on
standard_exec_prefix. This lets us move the installed tree
as a unit. If GCC_EXEC_PREFIX is defined, base
- standard_startfile_prefix on that as well. */
- if (IS_ABSOLUTE_PATHNAME (standard_startfile_prefix))
- add_prefix (&startfile_prefixes, standard_startfile_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
- else
+ standard_startfile_prefix on that as well.
+
+ If the prefix is relative, only search it for native compilers;
+ otherwise we will search a directory containing host libraries. */
+ if (IS_ABSOLUTE_PATH (standard_startfile_prefix))
+ add_sysrooted_prefix (&startfile_prefixes,
+ standard_startfile_prefix, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ else if (*cross_compile == '0')
{
if (gcc_exec_prefix)
add_prefix (&startfile_prefixes,
@@ -6022,34 +6146,15 @@ main (argc, argv)
NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
}
- add_prefix (&startfile_prefixes, standard_startfile_prefix_1,
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
- add_prefix (&startfile_prefixes, standard_startfile_prefix_2,
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ add_sysrooted_prefix (&startfile_prefixes, standard_startfile_prefix_1,
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ add_sysrooted_prefix (&startfile_prefixes, standard_startfile_prefix_2,
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
#if 0 /* Can cause surprises, and one can use -B./ instead. */
add_prefix (&startfile_prefixes, "./", NULL,
PREFIX_PRIORITY_LAST, 1, NULL, 0);
#endif
}
- else
- {
- if (!IS_ABSOLUTE_PATHNAME (standard_startfile_prefix)
- && gcc_exec_prefix)
- add_prefix (&startfile_prefixes,
- concat (gcc_exec_prefix, machine_suffix,
- standard_startfile_prefix, NULL),
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
- }
-
- if (*startfile_prefix_spec != 0
- && do_spec_2 (startfile_prefix_spec) == 0
- && do_spec_1 (" ", 0, NULL) == 0)
- {
- int ndx;
- for (ndx = 0; ndx < argbuf_index; ndx++)
- add_prefix (&startfile_prefixes, argbuf[ndx], "BINUTILS",
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
- }
/* Process any user specified specs in the order given on the command
line. */
@@ -6201,13 +6306,34 @@ main (argc, argv)
i = n_infiles;
i += lang_specific_extra_outfiles;
- outfiles = (const char **) xcalloc (i, sizeof (char *));
+ outfiles = xcalloc (i, sizeof (char *));
/* Record which files were specified explicitly as link input. */
explicit_link_files = xcalloc (1, n_infiles);
- for (i = 0; (int) i < n_infiles; i++)
+ if (combine_inputs)
+ {
+ int lang_n_infiles = 0;
+ for (i = 0; (int) i < n_infiles; i++)
+ {
+ const char *name = infiles[i].name;
+ struct compiler *compiler
+ = lookup_compiler (name, strlen (name), infiles[i].language);
+ if (compiler == NULL)
+ error ("%s: linker input file unused because linking not done",
+ name);
+ else if (lang_n_infiles > 0 && compiler != input_file_compiler)
+ fatal ("cannot specify -o with -c or -S and multiple languages");
+ else
+ {
+ lang_n_infiles++;
+ input_file_compiler = compiler;
+ }
+ }
+ }
+
+ for (i = 0; (int) i < (combine_inputs ? 1 : n_infiles); i++)
{
int this_file_error = 0;
@@ -6222,9 +6348,10 @@ main (argc, argv)
/* Figure out which compiler from the file's suffix. */
- input_file_compiler
- = lookup_compiler (infiles[i].name, input_filename_length,
- infiles[i].language);
+ if (! combine_inputs)
+ input_file_compiler
+ = lookup_compiler (infiles[i].name, input_filename_length,
+ infiles[i].language);
if (input_file_compiler)
{
@@ -6277,9 +6404,15 @@ main (argc, argv)
error_count++;
}
+ /* Determine if there are any linker input files. */
+ num_linker_inputs = 0;
+ for (i = 0; (int) i < n_infiles; i++)
+ if (explicit_link_files[i] || outfiles[i] != NULL)
+ num_linker_inputs++;
+
/* Run ld to link all the compiler output files. */
- if (error_count == 0)
+ if (num_linker_inputs > 0 && error_count == 0)
{
int tmp = execution_count;
@@ -6332,10 +6465,7 @@ main (argc, argv)
or 0 if this file is to be passed to the linker. */
static struct compiler *
-lookup_compiler (name, length, language)
- const char *name;
- size_t length;
- const char *language;
+lookup_compiler (const char *name, size_t length, const char *language)
{
struct compiler *cp;
@@ -6401,9 +6531,7 @@ lookup_compiler (name, length, language)
}
static char *
-save_string (s, len)
- const char *s;
- int len;
+save_string (const char *s, int len)
{
char *result = xmalloc (len + 1);
@@ -6413,8 +6541,7 @@ save_string (s, len)
}
void
-pfatal_with_name (name)
- const char *name;
+pfatal_with_name (const char *name)
{
perror_with_name (name);
delete_temp_files ();
@@ -6422,16 +6549,13 @@ pfatal_with_name (name)
}
static void
-perror_with_name (name)
- const char *name;
+perror_with_name (const char *name)
{
error ("%s: %s", name, xstrerror (errno));
}
static void
-pfatal_pexecute (errmsg_fmt, errmsg_arg)
- const char *errmsg_fmt;
- const char *errmsg_arg;
+pfatal_pexecute (const char *errmsg_fmt, const char *errmsg_arg)
{
if (errmsg_arg)
{
@@ -6448,136 +6572,153 @@ pfatal_pexecute (errmsg_fmt, errmsg_arg)
pfatal_with_name (errmsg_fmt);
}
-/* Output an error message and exit */
+/* Output an error message and exit. */
void
-fancy_abort ()
+fancy_abort (void)
{
fatal ("internal gcc abort");
}
-/* Output an error message and exit */
+/* Output an error message and exit. */
void
-fatal VPARAMS ((const char *msgid, ...))
+fatal (const char *msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_list ap;
+
+ va_start (ap, msgid);
fprintf (stderr, "%s: ", programname);
vfprintf (stderr, _(msgid), ap);
- VA_CLOSE (ap);
+ va_end (ap);
fprintf (stderr, "\n");
delete_temp_files ();
exit (1);
}
void
-error VPARAMS ((const char *msgid, ...))
+error (const char *msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_list ap;
+ va_start (ap, msgid);
fprintf (stderr, "%s: ", programname);
vfprintf (stderr, _(msgid), ap);
- VA_CLOSE (ap);
+ va_end (ap);
fprintf (stderr, "\n");
}
static void
-notice VPARAMS ((const char *msgid, ...))
+notice (const char *msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_list ap;
+ va_start (ap, msgid);
vfprintf (stderr, _(msgid), ap);
- VA_CLOSE (ap);
+ va_end (ap);
}
+static inline void
+validate_switches_from_spec (const char *spec)
+{
+ const char *p = spec;
+ char c;
+ while ((c = *p++))
+ if (c == '%' && (*p == '{' || *p == '<' || (*p == 'W' && *++p == '{')))
+ /* We have a switch spec. */
+ p = validate_switches (p + 1);
+}
+
static void
-validate_all_switches ()
+validate_all_switches (void)
{
struct compiler *comp;
- const char *p;
- char c;
struct spec_list *spec;
for (comp = compilers; comp->spec; comp++)
- {
- p = comp->spec;
- while ((c = *p++))
- if (c == '%' && (*p == '{' || (*p == 'W' && *++p == '{')))
- /* We have a switch spec. */
- validate_switches (p + 1);
- }
+ validate_switches_from_spec (comp->spec);
/* Look through the linked list of specs read from the specs file. */
for (spec = specs; spec; spec = spec->next)
- {
- p = *(spec->ptr_spec);
- while ((c = *p++))
- if (c == '%' && (*p == '{' || (*p == 'W' && *++p == '{')))
- /* We have a switch spec. */
- validate_switches (p + 1);
- }
+ validate_switches_from_spec (*spec->ptr_spec);
- p = link_command_spec;
- while ((c = *p++))
- if (c == '%' && (*p == '{' || (*p == 'W' && *++p == '{')))
- /* We have a switch spec. */
- validate_switches (p + 1);
+ validate_switches_from_spec (link_command_spec);
}
/* Look at the switch-name that comes after START
and mark as valid all supplied switches that match it. */
-static void
-validate_switches (start)
- const char *start;
+static const char *
+validate_switches (const char *start)
{
const char *p = start;
- const char *filter;
+ const char *atom;
+ size_t len;
int i;
- int suffix;
+ bool suffix = false;
+ bool starred = false;
- if (*p == '|')
- ++p;
+#define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
next_member:
+ SKIP_WHITE ();
+
if (*p == '!')
- ++p;
+ p++;
- suffix = 0;
+ SKIP_WHITE ();
if (*p == '.')
- suffix = 1, ++p;
+ suffix = true, p++;
- filter = p;
- while (*p != ':' && *p != '}' && *p != '|' && *p != '&')
+ atom = p;
+ while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
+ || *p == ',' || *p == '.' || *p == '@')
p++;
+ len = p - atom;
- if (suffix)
- ;
- else if (p[-1] == '*')
+ if (*p == '*')
+ starred = true, p++;
+
+ SKIP_WHITE ();
+
+ if (!suffix)
{
/* Mark all matching switches as valid. */
for (i = 0; i < n_switches; i++)
- if (!strncmp (switches[i].part1, filter, p - filter - 1))
+ if (!strncmp (switches[i].part1, atom, len)
+ && (starred || switches[i].part1[len] == 0))
switches[i].validated = 1;
}
- else
+
+ if (*p) p++;
+ if (*p && (p[-1] == '|' || p[-1] == '&'))
+ goto next_member;
+
+ if (*p && p[-1] == ':')
{
- /* Mark an exact matching switch as valid. */
- for (i = 0; i < n_switches; i++)
+ while (*p && *p != ';' && *p != '}')
{
- if (!strncmp (switches[i].part1, filter, p - filter)
- && switches[i].part1[p - filter] == 0)
- switches[i].validated = 1;
+ if (*p == '%')
+ {
+ p++;
+ if (*p == '{' || *p == '<')
+ p = validate_switches (p+1);
+ else if (p[0] == 'W' && p[1] == '{')
+ p = validate_switches (p+2);
+ }
+ else
+ p++;
}
+
+ if (*p) p++;
+ if (*p && p[-1] == ';')
+ goto next_member;
}
- if (*p++ == '|' || p[-1] == '&')
- goto next_member;
+ return p;
+#undef SKIP_WHITE
}
struct mdswitchstr
@@ -6593,9 +6734,7 @@ static int n_mdswitches;
canonicalize the switches to keep only the ones we care about. */
static int
-used_arg (p, len)
- const char *p;
- int len;
+used_arg (const char *p, int len)
{
struct mswitchstr
{
@@ -6621,8 +6760,7 @@ used_arg (p, len)
if (*q == ';')
cnt++;
- matches =
- (struct mswitchstr *) alloca ((sizeof (struct mswitchstr)) * cnt);
+ matches = alloca ((sizeof (struct mswitchstr)) * cnt);
i = 0;
q = multilib_matches;
while (*q != '\0')
@@ -6654,8 +6792,7 @@ used_arg (p, len)
xmalloc from calling fatal, and prevents us from re-executing this
block of code. */
mswitches
- = (struct mswitchstr *)
- xmalloc (sizeof (struct mswitchstr)
+ = xmalloc (sizeof (struct mswitchstr)
* (n_mdswitches + (n_switches ? n_switches : 1)));
for (i = 0; i < n_switches; i++)
{
@@ -6733,9 +6870,7 @@ used_arg (p, len)
}
static int
-default_arg (p, len)
- const char *p;
- int len;
+default_arg (const char *p, int len)
{
int i;
@@ -6758,7 +6893,7 @@ default_arg (p, len)
will be used. */
static void
-set_multilib_dir ()
+set_multilib_dir (void)
{
const char *p;
unsigned int this_path_len;
@@ -6784,9 +6919,7 @@ set_multilib_dir ()
{
int i = 0;
- mdswitches
- = (struct mdswitchstr *) xmalloc (sizeof (struct mdswitchstr)
- * n_mdswitches);
+ mdswitches = xmalloc (sizeof (struct mdswitchstr) * n_mdswitches);
for (start = multilib_defaults; *start != '\0'; start = end + 1)
{
while (*start == ' ' || *start == '\t')
@@ -6794,7 +6927,7 @@ set_multilib_dir ()
if (*start == '\0')
break;
-
+
for (end = start + 1;
*end != ' ' && *end != '\t' && *end != '\0'; end++)
;
@@ -6993,7 +7126,7 @@ set_multilib_dir ()
the exclusions. */
static void
-print_multilib_info ()
+print_multilib_info (void)
{
const char *p = multilib_select;
const char *last_path = 0, *this_path;
@@ -7241,12 +7374,10 @@ print_multilib_info ()
(whose name has been expanded with %s). */
static const char *
-if_exists_spec_function (argc, argv)
- int argc;
- const char **argv;
+if_exists_spec_function (int argc, const char **argv)
{
/* Must have only one argument. */
- if (argc == 1 && IS_ABSOLUTE_PATHNAME (argv[0]) && ! access (argv[0], R_OK))
+ if (argc == 1 && IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
return argv[0];
return NULL;
@@ -7258,15 +7389,13 @@ if_exists_spec_function (argc, argv)
is returned if the first argument does not exist. */
static const char *
-if_exists_else_spec_function (argc, argv)
- int argc;
- const char **argv;
+if_exists_else_spec_function (int argc, const char **argv)
{
/* Must have exactly two arguments. */
if (argc != 2)
return NULL;
- if (IS_ABSOLUTE_PATHNAME (argv[0]) && ! access (argv[0], R_OK))
+ if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
return argv[0];
return argv[1];
diff --git a/contrib/gcc/gcc.h b/contrib/gcc/gcc.h
index 06691bd9f6b7..9df9ffd12522 100644
--- a/contrib/gcc/gcc.h
+++ b/contrib/gcc/gcc.h
@@ -1,5 +1,5 @@
/* Header file for modules that link with gcc.c
- Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -26,9 +26,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* The mapping of a spec function name to the C function that
implements it. */
struct spec_function
-{
+{
const char *name;
- const char *(*func) PARAMS ((int, const char **));
+ const char *(*func) (int, const char **);
};
/* This defines which switch letters take arguments. */
@@ -54,24 +54,21 @@ struct spec_function
/* These are exported by gcc.c. */
-extern int do_spec PARAMS ((const char *));
-extern void record_temp_file PARAMS ((const char *, int, int));
-extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
-extern const char *input_filename;
-extern size_t input_filename_length;
-extern void fatal PARAMS ((const char *, ...))
- ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-extern void error PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-extern void pfatal_with_name PARAMS ((const char *)) ATTRIBUTE_NORETURN;
-extern void set_input PARAMS ((const char *));
+extern int do_spec (const char *);
+extern void record_temp_file (const char *, int, int);
+extern void fancy_abort (void) ATTRIBUTE_NORETURN;
+extern void fatal (const char *, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+extern void error (const char *, ...) ATTRIBUTE_PRINTF_1;
+extern void pfatal_with_name (const char *) ATTRIBUTE_NORETURN;
+extern void set_input (const char *);
/* Spec files linked with gcc.c must provide definitions for these. */
/* Called before processing to change/add/remove arguments. */
-extern void lang_specific_driver PARAMS ((int *, const char *const **, int *));
+extern void lang_specific_driver (int *, const char *const **, int *);
/* Called before linking. Returns 0 on success and -1 on failure. */
-extern int lang_specific_pre_link PARAMS ((void));
+extern int lang_specific_pre_link (void);
extern int n_infiles;
diff --git a/contrib/gcc/gccbug.in b/contrib/gcc/gccbug.in
index 4da84150b6c5..34b1528814de 100755
--- a/contrib/gcc/gccbug.in
+++ b/contrib/gcc/gccbug.in
@@ -1,6 +1,6 @@
#!/bin/sh
# Submit a problem report to a GNATS site.
-# Copyright (C) 1993, 2000, 2001, 2002 Free Software Foundation, Inc.
+# Copyright (C) 1993, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
# Contributed by Brendan Kehoe (brendan@cygnus.com), based on a
# version written by Heinz G. Seidl (hgs@cygnus.com).
#
@@ -198,7 +198,7 @@ EOF
done
# spam does not need to be listed here
-CATEGORIES="ada bootstrap c++ c debug driver fortran inline-asm java libf2c libgcj libobjc libstdc++ middle-end objc optimization other preprocessor target web"
+CATEGORIES="ada bootstrap c++ c debug driver fortran inline-asm java libf2c libgcj libobjc libstdc++ middle-end objc other pch preprocessor rtl-optimization target tree-optimization web"
case "$FORMAT" in
lisp) echo "$CATEGORIES" | \
@@ -344,7 +344,11 @@ SEND-PR: support I need help with gcc.
host: @host@
build: @build@
target: @target@
+__EOF__
+ cat >> $file << \__EOF__
configured with: @gcc_config_arguments@
+__EOF__
+ cat >> $file << __EOF__
>Description:
$DESCRIPTION_C
>How-To-Repeat:
diff --git a/contrib/gcc/gccspec.c b/contrib/gcc/gccspec.c
index 6e538b1b744c..fce784b2ede5 100644
--- a/contrib/gcc/gccspec.c
+++ b/contrib/gcc/gccspec.c
@@ -1,5 +1,5 @@
/* Specific flags and argument handling of the C front-end.
- Copyright (C) 1999, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,14 +20,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "gcc.h"
/* Filter argc and argv before processing by the gcc driver proper. */
void
-lang_specific_driver (in_argc, in_argv, in_added_libraries)
- int *in_argc ATTRIBUTE_UNUSED;
- const char *const **in_argv ATTRIBUTE_UNUSED;
- int *in_added_libraries ATTRIBUTE_UNUSED;
+lang_specific_driver (int *in_argc ATTRIBUTE_UNUSED,
+ const char *const **in_argv ATTRIBUTE_UNUSED,
+ int *in_added_libraries ATTRIBUTE_UNUSED)
{
#ifdef ENABLE_SHARED_LIBGCC
int i;
@@ -72,7 +73,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
if (shared_libgcc)
{
/* Make sure to have room for the trailing NULL argument. */
- arglist = (const char **) xmalloc ((argc+2) * sizeof (char *));
+ arglist = xmalloc ((argc+2) * sizeof (char *));
i = 0;
do
@@ -94,7 +95,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
/* Called before linking. Returns 0 on success and -1 on failure. */
int
-lang_specific_pre_link ()
+lang_specific_pre_link (void)
{
return 0; /* Not used for C. */
}
@@ -102,7 +103,7 @@ lang_specific_pre_link ()
/* Number of extra output files that lang_specific_pre_link may generate. */
int lang_specific_extra_outfiles = 0; /* Not used for C. */
-/* Table of language-specific spec functions. */
+/* Table of language-specific spec functions. */
const struct spec_function lang_specific_spec_functions[] =
{
{ 0, 0 }
diff --git a/contrib/gcc/gcov-dump.c b/contrib/gcc/gcov-dump.c
new file mode 100644
index 000000000000..e0115622ab77
--- /dev/null
+++ b/contrib/gcc/gcov-dump.c
@@ -0,0 +1,436 @@
+/* Dump a gcov file, for debugging use.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Nathan Sidwell <nathan@codesourcery.com>
+
+Gcov 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.
+
+Gcov 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 Gcov; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "version.h"
+#include <getopt.h>
+#define IN_GCOV (-1)
+#include "gcov-io.h"
+#include "gcov-io.c"
+
+static void dump_file (const char *);
+static void print_prefix (const char *, unsigned, gcov_position_t);
+static void print_usage (void);
+static void print_version (void);
+static void tag_function (const char *, unsigned, unsigned);
+static void tag_blocks (const char *, unsigned, unsigned);
+static void tag_arcs (const char *, unsigned, unsigned);
+static void tag_lines (const char *, unsigned, unsigned);
+static void tag_counters (const char *, unsigned, unsigned);
+static void tag_summary (const char *, unsigned, unsigned);
+extern int main (int, char **);
+
+typedef struct tag_format
+{
+ unsigned tag;
+ char const *name;
+ void (*proc) (const char *, unsigned, unsigned);
+} tag_format_t;
+
+static int flag_dump_contents = 0;
+static int flag_dump_positions = 0;
+
+static const struct option options[] =
+{
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ { "long", no_argument, NULL, 'l' },
+ { "positions", no_argument, NULL, 'o' },
+ { 0, 0, 0, 0 }
+};
+
+static const tag_format_t tag_table[] =
+{
+ {0, "NOP", NULL},
+ {0, "UNKNOWN", NULL},
+ {0, "COUNTERS", tag_counters},
+ {GCOV_TAG_FUNCTION, "FUNCTION", tag_function},
+ {GCOV_TAG_BLOCKS, "BLOCKS", tag_blocks},
+ {GCOV_TAG_ARCS, "ARCS", tag_arcs},
+ {GCOV_TAG_LINES, "LINES", tag_lines},
+ {GCOV_TAG_OBJECT_SUMMARY, "OBJECT_SUMMARY", tag_summary},
+ {GCOV_TAG_PROGRAM_SUMMARY, "PROGRAM_SUMMARY", tag_summary},
+ {0, NULL, NULL}
+};
+
+int
+main (int argc ATTRIBUTE_UNUSED, char **argv)
+{
+ int opt;
+
+ while ((opt = getopt_long (argc, argv, "hlpv", options, NULL)) != -1)
+ {
+ switch (opt)
+ {
+ case 'h':
+ print_usage ();
+ break;
+ case 'v':
+ print_version ();
+ break;
+ case 'l':
+ flag_dump_contents = 1;
+ break;
+ case 'p':
+ flag_dump_positions = 1;
+ break;
+ default:
+ fprintf (stderr, "unknown flag `%c'\n", opt);
+ }
+ }
+
+ while (argv[optind])
+ dump_file (argv[optind++]);
+ return 0;
+}
+
+static void
+print_usage (void)
+{
+ printf ("Usage: gcov-dump [OPTION] ... gcovfiles\n");
+ printf ("Print coverage file contents\n");
+ printf (" -h, --help Print this help\n");
+ printf (" -v, --version Print version number\n");
+ printf (" -l, --long Dump record contents too\n");
+ printf (" -p, --positions Dump record positions\n");
+}
+
+static void
+print_version (void)
+{
+ printf ("gcov-dump (GCC) %s\n", version_string);
+ printf ("Copyright (C) 2003 Free Software Foundation, Inc.\n");
+ printf ("This is free software; see the source for copying conditions.\n"
+ "There is NO warranty; not even for MERCHANTABILITY or \n"
+ "FITNESS FOR A PARTICULAR PURPOSE.\n\n");
+}
+
+static void
+print_prefix (const char *filename, unsigned depth, gcov_position_t position)
+{
+ static const char prefix[] = " ";
+
+ printf ("%s:", filename);
+ if (flag_dump_positions)
+ printf ("%lu:", (unsigned long) position);
+ printf ("%.*s", (int) depth, prefix);
+}
+
+static void
+dump_file (const char *filename)
+{
+ unsigned tags[4];
+ unsigned depth = 0;
+
+ if (!gcov_open (filename, 1))
+ {
+ fprintf (stderr, "%s:cannot open\n", filename);
+ return;
+ }
+
+ /* magic */
+ {
+ unsigned magic = gcov_read_unsigned ();
+ unsigned version;
+ const char *type = NULL;
+ int endianness = 0;
+ char m[4], v[4];
+
+ if ((endianness = gcov_magic (magic, GCOV_DATA_MAGIC)))
+ type = "data";
+ else if ((endianness = gcov_magic (magic, GCOV_NOTE_MAGIC)))
+ type = "note";
+ else
+ {
+ printf ("%s:not a gcov file\n", filename);
+ gcov_close ();
+ return;
+ }
+ version = gcov_read_unsigned ();
+ GCOV_UNSIGNED2STRING (v, version);
+ GCOV_UNSIGNED2STRING (m, magic);
+
+ printf ("%s:%s:magic `%.4s':version `%.4s'%s\n", filename, type,
+ m, v, endianness < 0 ? " (swapped endianness)" : "");
+ if (version != GCOV_VERSION)
+ {
+ char e[4];
+
+ GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
+ printf ("%s:warning:current version is `%.4s'\n", filename, e);
+ }
+ }
+
+ /* stamp */
+ {
+ unsigned stamp = gcov_read_unsigned ();
+
+ printf ("%s:stamp %lu\n", filename, (unsigned long)stamp);
+ }
+
+ while (1)
+ {
+ gcov_position_t base, position = gcov_position ();
+ unsigned tag, length;
+ tag_format_t const *format;
+ unsigned tag_depth;
+ int error;
+ unsigned mask;
+
+ tag = gcov_read_unsigned ();
+ if (!tag)
+ break;
+ length = gcov_read_unsigned ();
+ base = gcov_position ();
+ mask = GCOV_TAG_MASK (tag) >> 1;
+ for (tag_depth = 4; mask; mask >>= 8)
+ {
+ if ((mask & 0xff) != 0xff)
+ {
+ printf ("%s:tag `%08x' is invalid\n", filename, tag);
+ break;
+ }
+ tag_depth--;
+ }
+ for (format = tag_table; format->name; format++)
+ if (format->tag == tag)
+ goto found;
+ format = &tag_table[GCOV_TAG_IS_COUNTER (tag) ? 2 : 1];
+ found:;
+ if (tag)
+ {
+ if (depth && depth < tag_depth)
+ {
+ if (!GCOV_TAG_IS_SUBTAG (tags[depth - 1], tag))
+ printf ("%s:tag `%08x' is incorrectly nested\n",
+ filename, tag);
+ }
+ depth = tag_depth;
+ tags[depth - 1] = tag;
+ }
+
+ print_prefix (filename, tag_depth, position);
+ printf ("%08x:%4u:%s", tag, length, format->name);
+ if (format->proc)
+ (*format->proc) (filename, tag, length);
+
+ printf ("\n");
+ if (flag_dump_contents && format->proc)
+ {
+ unsigned long actual_length = gcov_position () - base;
+
+ if (actual_length > length)
+ printf ("%s:record size mismatch %lu bytes overread\n",
+ filename, actual_length - length);
+ else if (length > actual_length)
+ printf ("%s:record size mismatch %lu bytes unread\n",
+ filename, length - actual_length);
+ }
+ gcov_sync (base, length);
+ if ((error = gcov_is_error ()))
+ {
+ printf (error < 0 ? "%s:counter overflow at %lu\n" :
+ "%s:read error at %lu\n", filename,
+ (long unsigned) gcov_position ());
+ break;
+ }
+ }
+ if (!gcov_is_eof ())
+ printf ("%s:early end of file\n", filename);
+ gcov_close ();
+}
+
+static void
+tag_function (const char *filename ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
+{
+ unsigned long pos = gcov_position ();
+
+ printf (" ident=%u", gcov_read_unsigned ());
+ printf (", checksum=0x%08x", gcov_read_unsigned ());
+
+ if (gcov_position () - pos < length)
+ {
+ const char *name;
+
+ name = gcov_read_string ();
+ printf (", `%s'", name ? name : "NULL");
+ name = gcov_read_string ();
+ printf (" %s", name ? name : "NULL");
+ printf (":%u", gcov_read_unsigned ());
+ }
+}
+
+static void
+tag_blocks (const char *filename ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
+{
+ unsigned n_blocks = GCOV_TAG_BLOCKS_NUM (length);
+
+ printf (" %u blocks", n_blocks);
+
+ if (flag_dump_contents)
+ {
+ unsigned ix;
+
+ for (ix = 0; ix != n_blocks; ix++)
+ {
+ if (!(ix & 7))
+ {
+ printf ("\n");
+ print_prefix (filename, 0, gcov_position ());
+ printf ("\t\t%u", ix);
+ }
+ printf (" %04x", gcov_read_unsigned ());
+ }
+ }
+}
+
+static void
+tag_arcs (const char *filename ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
+{
+ unsigned n_arcs = GCOV_TAG_ARCS_NUM (length);
+
+ printf (" %u arcs", n_arcs);
+ if (flag_dump_contents)
+ {
+ unsigned ix;
+ unsigned blockno = gcov_read_unsigned ();
+
+ for (ix = 0; ix != n_arcs; ix++)
+ {
+ unsigned dst, flags;
+
+ if (!(ix & 3))
+ {
+ printf ("\n");
+ print_prefix (filename, 0, gcov_position ());
+ printf ("\tblock %u:", blockno);
+ }
+ dst = gcov_read_unsigned ();
+ flags = gcov_read_unsigned ();
+ printf (" %u:%04x", dst, flags);
+ }
+ }
+}
+
+static void
+tag_lines (const char *filename ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
+{
+ if (flag_dump_contents)
+ {
+ unsigned blockno = gcov_read_unsigned ();
+ char const *sep = NULL;
+
+ while (1)
+ {
+ gcov_position_t position = gcov_position ();
+ const char *source = NULL;
+ unsigned lineno = gcov_read_unsigned ();
+
+ if (!lineno)
+ {
+ source = gcov_read_string ();
+ if (!source)
+ break;
+ sep = NULL;
+ }
+
+ if (!sep)
+ {
+ printf ("\n");
+ print_prefix (filename, 0, position);
+ printf ("\tblock %u:", blockno);
+ sep = "";
+ }
+ if (lineno)
+ {
+ printf ("%s%u", sep, lineno);
+ sep = ", ";
+ }
+ else
+ {
+ printf ("%s`%s'", sep, source);
+ sep = ":";
+ }
+ }
+ }
+}
+
+static void
+tag_counters (const char *filename ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
+{
+ static const char *const counter_names[] = GCOV_COUNTER_NAMES;
+ unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
+
+ printf (" %s %u counts",
+ counter_names[GCOV_COUNTER_FOR_TAG (tag)], n_counts);
+ if (flag_dump_contents)
+ {
+ unsigned ix;
+
+ for (ix = 0; ix != n_counts; ix++)
+ {
+ gcov_type count;
+
+ if (!(ix & 7))
+ {
+ printf ("\n");
+ print_prefix (filename, 0, gcov_position ());
+ printf ("\t\t%u", ix);
+ }
+
+ count = gcov_read_counter ();
+ printf (" ");
+ printf (HOST_WIDEST_INT_PRINT_DEC, count);
+ }
+ }
+}
+
+static void
+tag_summary (const char *filename ATTRIBUTE_UNUSED,
+ unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
+{
+ struct gcov_summary summary;
+ unsigned ix;
+
+ gcov_read_summary (&summary);
+ printf (" checksum=0x%08x", summary.checksum);
+
+ for (ix = 0; ix != GCOV_COUNTERS; ix++)
+ {
+ printf ("\n");
+ print_prefix (filename, 0, 0);
+ printf ("\t\tcounts=%u, runs=%u",
+ summary.ctrs[ix].num, summary.ctrs[ix].runs);
+
+ printf (", sum_all=" HOST_WIDEST_INT_PRINT_DEC,
+ (HOST_WIDEST_INT)summary.ctrs[ix].sum_all);
+ printf (", run_max=" HOST_WIDEST_INT_PRINT_DEC,
+ (HOST_WIDEST_INT)summary.ctrs[ix].run_max);
+ printf (", sum_max=" HOST_WIDEST_INT_PRINT_DEC,
+ (HOST_WIDEST_INT)summary.ctrs[ix].sum_max);
+ }
+}
diff --git a/contrib/gcc/gcov-io.c b/contrib/gcc/gcov-io.c
new file mode 100644
index 000000000000..0349fb821b21
--- /dev/null
+++ b/contrib/gcc/gcov-io.c
@@ -0,0 +1,544 @@
+/* File format for coverage information
+ Copyright (C) 1996, 1997, 1998, 2000, 2002,
+ 2003 Free Software Foundation, Inc.
+ Contributed by Bob Manson <manson@cygnus.com>.
+ Completely remangled by Nathan Sidwell <nathan@codesourcery.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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Routines declared in gcov-io.h. This file should be #included by
+ another source file, after having #included gcov-io.h. */
+
+#if !IN_GCOV
+static void gcov_write_block (unsigned);
+static gcov_unsigned_t *gcov_write_words (unsigned);
+#endif
+static const gcov_unsigned_t *gcov_read_words (unsigned);
+#if !IN_LIBGCOV
+static void gcov_allocate (unsigned);
+#endif
+
+static inline gcov_unsigned_t from_file (gcov_unsigned_t value)
+{
+#if !IN_LIBGCOV
+ if (gcov_var.endian)
+ {
+ value = (value >> 16) | (value << 16);
+ value = ((value & 0xff00ff) << 8) | ((value >> 8) & 0xff00ff);
+ }
+#endif
+ return value;
+}
+
+/* Open a gcov file. NAME is the name of the file to open and MODE
+ indicates whether a new file should be created, or an existing file
+ opened for modification. If MODE is >= 0 an existing file will be
+ opened, if possible, and if MODE is <= 0, a new file will be
+ created. Use MODE=0 to attempt to reopen an existing file and then
+ fall back on creating a new one. Return zero on failure, >0 on
+ opening an existing file and <0 on creating a new one. */
+
+GCOV_LINKAGE int
+#if IN_LIBGCOV
+gcov_open (const char *name)
+#else
+gcov_open (const char *name, int mode)
+#endif
+{
+#if IN_LIBGCOV
+ const int mode = 0;
+#endif
+#if GCOV_LOCKED
+ struct flock s_flock;
+ int fd;
+
+ s_flock.l_type = F_WRLCK;
+ s_flock.l_whence = SEEK_SET;
+ s_flock.l_start = 0;
+ s_flock.l_len = 0; /* Until EOF. */
+ s_flock.l_pid = getpid ();
+#endif
+
+ if (gcov_var.file)
+ abort ();
+ gcov_var.start = 0;
+ gcov_var.offset = gcov_var.length = 0;
+ gcov_var.overread = -1u;
+ gcov_var.error = 0;
+#if !IN_LIBGCOV
+ gcov_var.endian = 0;
+#endif
+#if GCOV_LOCKED
+ if (mode > 0)
+ fd = open (name, O_RDWR);
+ else
+ fd = open (name, O_RDWR | O_CREAT, 0666);
+ if (fd < 0)
+ return 0;
+
+ while (fcntl (fd, F_SETLKW, &s_flock) && errno == EINTR)
+ continue;
+
+ gcov_var.file = fdopen (fd, "r+b");
+ if (!gcov_var.file)
+ {
+ close (fd);
+ return 0;
+ }
+
+ if (mode > 0)
+ gcov_var.mode = 1;
+ else if (mode == 0)
+ {
+ struct stat st;
+
+ if (fstat (fd, &st) < 0)
+ {
+ fclose (gcov_var.file);
+ gcov_var.file = 0;
+ return 0;
+ }
+ if (st.st_size != 0)
+ gcov_var.mode = 1;
+ else
+ gcov_var.mode = mode * 2 + 1;
+ }
+ else
+ gcov_var.mode = mode * 2 + 1;
+#else
+ if (mode >= 0)
+ gcov_var.file = fopen (name, "r+b");
+ if (gcov_var.file)
+ gcov_var.mode = 1;
+ else if (mode <= 0)
+ {
+ gcov_var.file = fopen (name, "w+b");
+ if (gcov_var.file)
+ gcov_var.mode = mode * 2 + 1;
+ }
+ if (!gcov_var.file)
+ return 0;
+#endif
+
+ setbuf (gcov_var.file, (char *)0);
+
+ return 1;
+}
+
+/* Close the current gcov file. Flushes data to disk. Returns nonzero
+ on failure or error flag set. */
+
+GCOV_LINKAGE int
+gcov_close (void)
+{
+ if (gcov_var.file)
+ {
+#if !IN_GCOV
+ if (gcov_var.offset && gcov_var.mode < 0)
+ gcov_write_block (gcov_var.offset);
+#endif
+ fclose (gcov_var.file);
+ gcov_var.file = 0;
+ gcov_var.length = 0;
+ }
+#if !IN_LIBGCOV
+ free (gcov_var.buffer);
+ gcov_var.alloc = 0;
+ gcov_var.buffer = 0;
+#endif
+ gcov_var.mode = 0;
+ return gcov_var.error;
+}
+
+#if !IN_LIBGCOV
+/* Check if MAGIC is EXPECTED. Use it to determine endianness of the
+ file. Returns +1 for same endian, -1 for other endian and zero for
+ not EXPECTED. */
+
+GCOV_LINKAGE int
+gcov_magic (gcov_unsigned_t magic, gcov_unsigned_t expected)
+{
+ if (magic == expected)
+ return 1;
+ magic = (magic >> 16) | (magic << 16);
+ magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff);
+ if (magic == expected)
+ {
+ gcov_var.endian = 1;
+ return -1;
+ }
+ return 0;
+}
+#endif
+
+#if !IN_LIBGCOV
+static void
+gcov_allocate (unsigned length)
+{
+ size_t new_size = gcov_var.alloc;
+
+ if (!new_size)
+ new_size = GCOV_BLOCK_SIZE;
+ new_size += length;
+ new_size *= 2;
+
+ gcov_var.alloc = new_size;
+ gcov_var.buffer = xrealloc (gcov_var.buffer, new_size << 2);
+}
+#endif
+
+#if !IN_GCOV
+/* Write out the current block, if needs be. */
+
+static void
+gcov_write_block (unsigned size)
+{
+ if (fwrite (gcov_var.buffer, size << 2, 1, gcov_var.file) != 1)
+ gcov_var.error = 1;
+ gcov_var.start += size;
+ gcov_var.offset -= size;
+}
+
+/* Allocate space to write BYTES bytes to the gcov file. Return a
+ pointer to those bytes, or NULL on failure. */
+
+static gcov_unsigned_t *
+gcov_write_words (unsigned words)
+{
+ gcov_unsigned_t *result;
+
+ GCOV_CHECK_WRITING ();
+#if IN_LIBGCOV
+ if (gcov_var.offset >= GCOV_BLOCK_SIZE)
+ {
+ gcov_write_block (GCOV_BLOCK_SIZE);
+ if (gcov_var.offset)
+ {
+ GCOV_CHECK (gcov_var.offset == 1);
+ memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4);
+ }
+ }
+#else
+ if (gcov_var.offset + words > gcov_var.alloc)
+ gcov_allocate (gcov_var.offset + words);
+#endif
+ result = &gcov_var.buffer[gcov_var.offset];
+ gcov_var.offset += words;
+
+ return result;
+}
+
+/* Write unsigned VALUE to coverage file. Sets error flag
+ appropriately. */
+
+GCOV_LINKAGE void
+gcov_write_unsigned (gcov_unsigned_t value)
+{
+ gcov_unsigned_t *buffer = gcov_write_words (1);
+
+ buffer[0] = value;
+}
+
+/* Write counter VALUE to coverage file. Sets error flag
+ appropriately. */
+
+#if IN_LIBGCOV
+GCOV_LINKAGE void
+gcov_write_counter (gcov_type value)
+{
+ gcov_unsigned_t *buffer = gcov_write_words (2);
+
+ buffer[0] = (gcov_unsigned_t) value;
+ if (sizeof (value) > sizeof (gcov_unsigned_t))
+ buffer[1] = (gcov_unsigned_t) (value >> 32);
+ else
+ buffer[1] = 0;
+
+ if (value < 0)
+ gcov_var.error = -1;
+}
+#endif /* IN_LIBGCOV */
+
+#if !IN_LIBGCOV
+/* Write STRING to coverage file. Sets error flag on file
+ error, overflow flag on overflow */
+
+GCOV_LINKAGE void
+gcov_write_string (const char *string)
+{
+ unsigned length = 0;
+ unsigned alloc = 0;
+ gcov_unsigned_t *buffer;
+
+ if (string)
+ {
+ length = strlen (string);
+ alloc = (length + 4) >> 2;
+ }
+
+ buffer = gcov_write_words (1 + alloc);
+
+ buffer[0] = alloc;
+ buffer[alloc] = 0;
+ memcpy (&buffer[1], string, length);
+}
+#endif
+
+#if !IN_LIBGCOV
+/* Write a tag TAG and reserve space for the record length. Return a
+ value to be used for gcov_write_length. */
+
+GCOV_LINKAGE gcov_position_t
+gcov_write_tag (gcov_unsigned_t tag)
+{
+ gcov_position_t result = gcov_var.start + gcov_var.offset;
+ gcov_unsigned_t *buffer = gcov_write_words (2);
+
+ buffer[0] = tag;
+ buffer[1] = 0;
+
+ return result;
+}
+
+/* Write a record length using POSITION, which was returned by
+ gcov_write_tag. The current file position is the end of the
+ record, and is restored before returning. Returns nonzero on
+ overflow. */
+
+GCOV_LINKAGE void
+gcov_write_length (gcov_position_t position)
+{
+ unsigned offset;
+ gcov_unsigned_t length;
+ gcov_unsigned_t *buffer;
+
+ GCOV_CHECK_WRITING ();
+ GCOV_CHECK (position + 2 <= gcov_var.start + gcov_var.offset);
+ GCOV_CHECK (position >= gcov_var.start);
+ offset = position - gcov_var.start;
+ length = gcov_var.offset - offset - 2;
+ buffer = (gcov_unsigned_t *) &gcov_var.buffer[offset];
+ buffer[1] = length;
+ if (gcov_var.offset >= GCOV_BLOCK_SIZE)
+ gcov_write_block (gcov_var.offset);
+}
+
+#else /* IN_LIBGCOV */
+
+/* Write a tag TAG and length LENGTH. */
+
+GCOV_LINKAGE void
+gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length)
+{
+ gcov_unsigned_t *buffer = gcov_write_words (2);
+
+ buffer[0] = tag;
+ buffer[1] = length;
+}
+
+/* Write a summary structure to the gcov file. Return nonzero on
+ overflow. */
+
+GCOV_LINKAGE void
+gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary)
+{
+ unsigned ix;
+ const struct gcov_ctr_summary *csum;
+
+ gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH);
+ gcov_write_unsigned (summary->checksum);
+ for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
+ {
+ gcov_write_unsigned (csum->num);
+ gcov_write_unsigned (csum->runs);
+ gcov_write_counter (csum->sum_all);
+ gcov_write_counter (csum->run_max);
+ gcov_write_counter (csum->sum_max);
+ }
+}
+#endif /* IN_LIBGCOV */
+
+#endif /*!IN_GCOV */
+
+/* Return a pointer to read BYTES bytes from the gcov file. Returns
+ NULL on failure (read past EOF). */
+
+static const gcov_unsigned_t *
+gcov_read_words (unsigned words)
+{
+ const gcov_unsigned_t *result;
+ unsigned excess = gcov_var.length - gcov_var.offset;
+
+ GCOV_CHECK_READING ();
+ if (excess < words)
+ {
+ gcov_var.start += gcov_var.offset;
+#if IN_LIBGCOV
+ if (excess)
+ {
+ GCOV_CHECK (excess == 1);
+ memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4);
+ }
+#else
+ memmove (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, excess * 4);
+#endif
+ gcov_var.offset = 0;
+ gcov_var.length = excess;
+#if IN_LIBGCOV
+ GCOV_CHECK (!gcov_var.length || gcov_var.length == 1);
+ excess = GCOV_BLOCK_SIZE;
+#else
+ if (gcov_var.length + words > gcov_var.alloc)
+ gcov_allocate (gcov_var.length + words);
+ excess = gcov_var.alloc - gcov_var.length;
+#endif
+ excess = fread (gcov_var.buffer + gcov_var.length,
+ 1, excess << 2, gcov_var.file) >> 2;
+ gcov_var.length += excess;
+ if (gcov_var.length < words)
+ {
+ gcov_var.overread += words - gcov_var.length;
+ gcov_var.length = 0;
+ return 0;
+ }
+ }
+ result = &gcov_var.buffer[gcov_var.offset];
+ gcov_var.offset += words;
+ return result;
+}
+
+/* Read unsigned value from a coverage file. Sets error flag on file
+ error, overflow flag on overflow */
+
+GCOV_LINKAGE gcov_unsigned_t
+gcov_read_unsigned (void)
+{
+ gcov_unsigned_t value;
+ const gcov_unsigned_t *buffer = gcov_read_words (1);
+
+ if (!buffer)
+ return 0;
+ value = from_file (buffer[0]);
+ return value;
+}
+
+/* Read counter value from a coverage file. Sets error flag on file
+ error, overflow flag on overflow */
+
+GCOV_LINKAGE gcov_type
+gcov_read_counter (void)
+{
+ gcov_type value;
+ const gcov_unsigned_t *buffer = gcov_read_words (2);
+
+ if (!buffer)
+ return 0;
+ value = from_file (buffer[0]);
+ if (sizeof (value) > sizeof (gcov_unsigned_t))
+ value |= ((gcov_type) from_file (buffer[1])) << 32;
+ else if (buffer[1])
+ gcov_var.error = -1;
+
+ if (value < 0)
+ gcov_var.error = -1;
+ return value;
+}
+
+/* Read string from coverage file. Returns a pointer to a static
+ buffer, or NULL on empty string. You must copy the string before
+ calling another gcov function. */
+
+#if !IN_LIBGCOV
+GCOV_LINKAGE const char *
+gcov_read_string (void)
+{
+ unsigned length = gcov_read_unsigned ();
+
+ if (!length)
+ return 0;
+
+ return (const char *) gcov_read_words (length);
+}
+#endif
+
+GCOV_LINKAGE void
+gcov_read_summary (struct gcov_summary *summary)
+{
+ unsigned ix;
+ struct gcov_ctr_summary *csum;
+
+ summary->checksum = gcov_read_unsigned ();
+ for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
+ {
+ csum->num = gcov_read_unsigned ();
+ csum->runs = gcov_read_unsigned ();
+ csum->sum_all = gcov_read_counter ();
+ csum->run_max = gcov_read_counter ();
+ csum->sum_max = gcov_read_counter ();
+ }
+}
+
+#if !IN_LIBGCOV
+/* Reset to a known position. BASE should have been obtained from
+ gcov_position, LENGTH should be a record length. */
+
+GCOV_LINKAGE void
+gcov_sync (gcov_position_t base, gcov_unsigned_t length)
+{
+ GCOV_CHECK_READING ();
+ base += length;
+ if (base - gcov_var.start <= gcov_var.length)
+ gcov_var.offset = base - gcov_var.start;
+ else
+ {
+ gcov_var.offset = gcov_var.length = 0;
+ fseek (gcov_var.file, base << 2, SEEK_SET);
+ gcov_var.start = ftell (gcov_var.file) >> 2;
+ }
+}
+#endif
+
+#if IN_LIBGCOV
+/* Move to the a set position in a gcov file. BASE is zero to move to
+ the end, and nonzero to move to that position. */
+
+GCOV_LINKAGE void
+gcov_seek (gcov_position_t base)
+{
+ GCOV_CHECK_WRITING ();
+ if (gcov_var.offset)
+ gcov_write_block (gcov_var.offset);
+ fseek (gcov_var.file, base << 2, base ? SEEK_SET : SEEK_END);
+ gcov_var.start = ftell (gcov_var.file) >> 2;
+}
+#endif
+
+#if IN_GCOV > 0
+/* Return the modification time of the current gcov file. */
+
+GCOV_LINKAGE time_t
+gcov_time (void)
+{
+ struct stat status;
+
+ if (fstat (fileno (gcov_var.file), &status))
+ return 0;
+ else
+ return status.st_mtime;
+}
+#endif /* IN_GCOV */
diff --git a/contrib/gcc/gcov-io.h b/contrib/gcc/gcov-io.h
index 50d04a38bbab..e83c5163c90c 100644
--- a/contrib/gcc/gcov-io.h
+++ b/contrib/gcc/gcov-io.h
@@ -1,6 +1,8 @@
-/* Machine-independent I/O routines for gcov.
- Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
+/* File format for coverage information
+ Copyright (C) 1996, 1997, 1998, 2000, 2002,
+ 2003, 2004 Free Software Foundation, Inc.
Contributed by Bob Manson <manson@cygnus.com>.
+ Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
This file is part of GCC.
@@ -24,282 +26,574 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
- the executable file might be covered by the GNU General Public
- License. */
+ the executable file might be covered by the GNU General Public License. */
+
+/* Coverage information is held in two files. A notes file, which is
+ generated by the compiler, and a data file, which is generated
+ by the program under test. Both files use a similar structure. We
+ do not attempt to make these files backwards compatible with
+ previous versions, as you only need coverage information when
+ developing a program. We do hold version information, so that
+ mismatches can be detected, and we use a format that allows tools
+ to skip information they do not understand or are not interested
+ in.
+
+ Numbers are recorded in the 32 bit unsigned binary form of the
+ endianness of the machine generating the file. 64 bit numbers are
+ stored as two 32 bit numbers, the low part first. Strings are
+ padded with 1 to 4 NUL bytes, to bring the length up to a multiple
+ of 4. The number of 4 bytes is stored, followed by the padded
+ string. Zero length and NULL strings are simply stored as
+ a length of zero (they have no trailing NUL or padding).
+
+ int32: byte3 byte2 byte1 byte0 | byte0 byte1 byte2 byte3
+ int64: int32:low int32:high
+ string: int32:0 | int32:length char* char:0 padding
+ padding: | char:0 | char:0 char:0 | char:0 char:0 char:0
+ item: int32 | int64 | string
+
+ The basic format of the files is
+
+ file : int32:magic int32:version int32:stamp record*
+
+ The magic ident is different for the notes and the data files. The
+ magic ident is used to determine the endianness of the file, when
+ reading. The version is the same for both files and is derived
+ from gcc's version number. The stamp value is used to synchronize
+ note and data files and to synchronize merging within a data
+ file. It need not be an absolute time stamp, merely a ticker that
+ increments fast enough and cycles slow enough to distinguish
+ different compile/run/compile cycles.
+
+ Although the ident and version are formally 32 bit numbers, they
+ are derived from 4 character ASCII strings. The version number
+ consists of the single character major version number, a two
+ character minor version number (leading zero for versions less than
+ 10), and a single character indicating the status of the release.
+ That will be 'e' experimental, 'p' prerelease and 'r' for release.
+ Because, by good fortune, these are in alphabetical order, string
+ collating can be used to compare version strings. Be aware that
+ the 'e' designation will (naturally) be unstable and might be
+ incompatible with itself. For gcc 3.4 experimental, it would be
+ '304e' (0x33303465). When the major version reaches 10, the
+ letters A-Z will be used. Assuming minor increments releases every
+ 6 months, we have to make a major increment every 50 years.
+ Assuming major increments releases every 5 years, we're ok for the
+ next 155 years -- good enough for me.
+
+ A record has a tag, length and variable amount of data.
+
+ record: header data
+ header: int32:tag int32:length
+ data: item*
+
+ Records are not nested, but there is a record hierarchy. Tag
+ numbers reflect this hierarchy. Tags are unique across note and
+ data files. Some record types have a varying amount of data. The
+ LENGTH is the number of 4bytes that follow and is usually used to
+ determine how much data. The tag value is split into 4 8-bit
+ fields, one for each of four possible levels. The most significant
+ is allocated first. Unused levels are zero. Active levels are
+ odd-valued, so that the LSB of the level is one. A sub-level
+ incorporates the values of its superlevels. This formatting allows
+ you to determine the tag hierarchy, without understanding the tags
+ themselves, and is similar to the standard section numbering used
+ in technical documents. Level values [1..3f] are used for common
+ tags, values [41..9f] for the notes file and [a1..ff] for the data
+ file.
+
+ The basic block graph file contains the following records
+ note: unit function-graph*
+ unit: header int32:checksum string:source
+ function-graph: announce_function basic_blocks {arcs | lines}*
+ announce_function: header int32:ident int32:checksum
+ string:name string:source int32:lineno
+ basic_block: header int32:flags*
+ arcs: header int32:block_no arc*
+ arc: int32:dest_block int32:flags
+ lines: header int32:block_no line*
+ int32:0 string:NULL
+ line: int32:line_no | int32:0 string:filename
+
+ The BASIC_BLOCK record holds per-bb flags. The number of blocks
+ can be inferred from its data length. There is one ARCS record per
+ basic block. The number of arcs from a bb is implicit from the
+ data length. It enumerates the destination bb and per-arc flags.
+ There is one LINES record per basic block, it enumerates the source
+ lines which belong to that basic block. Source file names are
+ introduced by a line number of 0, following lines are from the new
+ source file. The initial source file for the function is NULL, but
+ the current source file should be remembered from one LINES record
+ to the next. The end of a block is indicated by an empty filename
+ - this does not reset the current source file. Note there is no
+ ordering of the ARCS and LINES records: they may be in any order,
+ interleaved in any manner. The current filename follows the order
+ the LINES records are stored in the file, *not* the ordering of the
+ blocks they are for.
+
+ The data file contains the following records.
+ data: {unit function-data* summary:object summary:program*}*
+ unit: header int32:checksum
+ function-data: announce_function arc_counts
+ announce_function: header int32:ident int32:checksum
+ arc_counts: header int64:count*
+ summary: int32:checksum {count-summary}GCOV_COUNTERS
+ count-summary: int32:num int32:runs int64:sum
+ int64:max int64:sum_max
+
+ The ANNOUNCE_FUNCTION record is the same as that in the note file,
+ but without the source location. The ARC_COUNTS gives the counter
+ values for those arcs that are instrumented. The SUMMARY records
+ give information about the whole object file and about the whole
+ program. The checksum is used for whole program summaries, and
+ disambiguates different programs which include the same
+ instrumented object file. There may be several program summaries,
+ each with a unique checksum. The object summary's checksum is zero.
+ Note that the data file might contain information from several runs
+ concatenated, or the data might be merged.
+
+ This file is included by both the compiler, gcov tools and the
+ runtime support library libgcov. IN_LIBGCOV and IN_GCOV are used to
+ distinguish which case is which. If IN_LIBGCOV is nonzero,
+ libgcov is being built. If IN_GCOV is nonzero, the gcov tools are
+ being built. Otherwise the compiler is being built. IN_GCOV may be
+ positive or negative. If positive, we are compiling a tool that
+ requires additional functions (see the code for knowledge of what
+ those functions are). */
#ifndef GCC_GCOV_IO_H
#define GCC_GCOV_IO_H
-#include <stdio.h>
-#include <sys/types.h>
-static int __fetch_long PARAMS ((long *, char *, size_t))
- ATTRIBUTE_UNUSED;
-static int __read_long PARAMS ((long *, FILE *, size_t))
- ATTRIBUTE_UNUSED;
-static int __write_long PARAMS ((long, FILE *, size_t))
- ATTRIBUTE_UNUSED;
-static int __fetch_gcov_type PARAMS ((gcov_type *, char *, size_t))
- ATTRIBUTE_UNUSED;
-static int __store_gcov_type PARAMS ((gcov_type, char *, size_t))
- ATTRIBUTE_UNUSED;
-static int __read_gcov_type PARAMS ((gcov_type *, FILE *, size_t))
- ATTRIBUTE_UNUSED;
-static int __write_gcov_type PARAMS ((gcov_type, FILE *, size_t))
- ATTRIBUTE_UNUSED;
-static int __write_gcov_string PARAMS ((const char *, size_t, FILE*, long))
- ATTRIBUTE_UNUSED;
-static int __read_gcov_string PARAMS ((char *, size_t, FILE*, long))
- ATTRIBUTE_UNUSED;
-
-/* These routines only work for signed values. */
-
-/* Store a portable representation of VALUE in DEST using BYTES*8-1 bits.
- Return a nonzero value if VALUE requires more than BYTES*8-1 bits
- to store. */
-
-static int
-__store_gcov_type (value, dest, bytes)
- gcov_type value;
- char *dest;
- size_t bytes;
+#if IN_LIBGCOV
+/* About the target */
+
+#if BITS_PER_UNIT == 8
+typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI)));
+typedef unsigned gcov_position_t __attribute__ ((mode (SI)));
+#if LONG_LONG_TYPE_SIZE > 32
+typedef signed gcov_type __attribute__ ((mode (DI)));
+#else
+typedef signed gcov_type __attribute__ ((mode (SI)));
+#endif
+#else
+#if BITS_PER_UNIT == 16
+typedef unsigned gcov_unsigned_t __attribute__ ((mode (HI)));
+typedef unsigned gcov_position_t __attribute__ ((mode (HI)));
+#if LONG_LONG_TYPE_SIZE > 32
+typedef signed gcov_type __attribute__ ((mode (SI)));
+#else
+typedef signed gcov_type __attribute__ ((mode (HI)));
+#endif
+#else
+typedef unsigned gcov_unsigned_t __attribute__ ((mode (QI)));
+typedef unsigned gcov_position_t __attribute__ ((mode (QI)));
+#if LONG_LONG_TYPE_SIZE > 32
+typedef signed gcov_type __attribute__ ((mode (HI)));
+#else
+typedef signed gcov_type __attribute__ ((mode (QI)));
+#endif
+#endif
+#endif
+
+
+#if defined (TARGET_HAS_F_SETLKW)
+#define GCOV_LOCKED 1
+#else
+#define GCOV_LOCKED 0
+#endif
+
+#else /* !IN_LIBGCOV */
+/* About the host */
+
+typedef unsigned gcov_unsigned_t;
+typedef unsigned gcov_position_t;
+/* gcov_type is typedef'd elsewhere for the compiler */
+#if IN_GCOV
+#define GCOV_LINKAGE static
+typedef HOST_WIDEST_INT gcov_type;
+#if IN_GCOV > 0
+#include <sys/types.h>
+#endif
+#else /*!IN_GCOV */
+#if LONG_LONG_TYPE_SIZE > 32
+#define GCOV_TYPE_NODE intDI_type_node
+#else
+#define GCOV_TYPE_NODE intSI_type_node
+#endif
+#endif
+
+#if defined (HOST_HAS_F_SETLKW)
+#define GCOV_LOCKED 1
+#else
+#define GCOV_LOCKED 0
+#endif
+
+#endif /* !IN_LIBGCOV */
+
+/* In gcov we want function linkage to be static. In libgcov we need
+ these functions to be extern, so prefix them with __gcov. In the
+ compiler we want it extern, so that they can be accessed from
+ elsewhere. */
+#if IN_LIBGCOV
+#define gcov_var __gcov_var
+#define gcov_open __gcov_open
+#define gcov_close __gcov_close
+#define gcov_write_tag_length __gcov_write_tag_length
+#define gcov_position __gcov_position
+#define gcov_seek __gcov_seek
+#define gcov_rewrite __gcov_rewrite
+#define gcov_is_error __gcov_is_error
+#define gcov_is_eof __gcov_is_eof
+#define gcov_write_unsigned __gcov_write_unsigned
+#define gcov_write_counter __gcov_write_counter
+#define gcov_write_summary __gcov_write_summary
+#define gcov_read_unsigned __gcov_read_unsigned
+#define gcov_read_counter __gcov_read_counter
+#define gcov_read_summary __gcov_read_summary
+
+/* Poison these, so they don't accidentally slip in. */
+#pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length
+#pragma GCC poison gcov_read_string gcov_sync gcov_time gcov_magic
+
+#endif
+
+#ifndef GCOV_LINKAGE
+#define GCOV_LINKAGE extern
+#endif
+
+/* File suffixes. */
+#define GCOV_DATA_SUFFIX ".gcda"
+#define GCOV_NOTE_SUFFIX ".gcno"
+
+/* File magic. Must not be palindromes. */
+#define GCOV_DATA_MAGIC ((gcov_unsigned_t)0x67636461) /* "gcda" */
+#define GCOV_NOTE_MAGIC ((gcov_unsigned_t)0x67636e6f) /* "gcno" */
+
+/* gcov-iov.h is automatically generated by the makefile from
+ version.c, it looks like
+ #define GCOV_VERSION ((gcov_unsigned_t)0x89abcdef)
+*/
+#include "gcov-iov.h"
+
+/* Convert a magic or version number to a 4 character string. */
+#define GCOV_UNSIGNED2STRING(ARRAY,VALUE) \
+ ((ARRAY)[0] = (char)((VALUE) >> 24), \
+ (ARRAY)[1] = (char)((VALUE) >> 16), \
+ (ARRAY)[2] = (char)((VALUE) >> 8), \
+ (ARRAY)[3] = (char)((VALUE) >> 0))
+
+/* The record tags. Values [1..3f] are for tags which may be in either
+ file. Values [41..9f] for those in the note file and [a1..ff] for
+ the data file. */
+
+#define GCOV_TAG_FUNCTION ((gcov_unsigned_t)0x01000000)
+#define GCOV_TAG_FUNCTION_LENGTH (2)
+#define GCOV_TAG_BLOCKS ((gcov_unsigned_t)0x01410000)
+#define GCOV_TAG_BLOCKS_LENGTH(NUM) (NUM)
+#define GCOV_TAG_BLOCKS_NUM(LENGTH) (LENGTH)
+#define GCOV_TAG_ARCS ((gcov_unsigned_t)0x01430000)
+#define GCOV_TAG_ARCS_LENGTH(NUM) (1 + (NUM) * 2)
+#define GCOV_TAG_ARCS_NUM(LENGTH) (((LENGTH) - 1) / 2)
+#define GCOV_TAG_LINES ((gcov_unsigned_t)0x01450000)
+#define GCOV_TAG_COUNTER_BASE ((gcov_unsigned_t)0x01a10000)
+#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 2)
+#define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2)
+#define GCOV_TAG_OBJECT_SUMMARY ((gcov_unsigned_t)0xa1000000)
+#define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000)
+#define GCOV_TAG_SUMMARY_LENGTH \
+ (1 + GCOV_COUNTERS_SUMMABLE * (2 + 3 * 2))
+
+/* Counters that are collected. */
+#define GCOV_COUNTER_ARCS 0 /* Arc transitions. */
+#define GCOV_COUNTERS_SUMMABLE 1 /* Counters which can be
+ summaried. */
+#define GCOV_FIRST_VALUE_COUNTER 1 /* The first of counters used for value
+ profiling. They must form a consecutive
+ interval and their order must match
+ the order of HIST_TYPEs in
+ value-prof.h. */
+#define GCOV_COUNTER_V_INTERVAL 1 /* Histogram of value inside an interval. */
+#define GCOV_COUNTER_V_POW2 2 /* Histogram of exact power2 logarithm
+ of a value. */
+#define GCOV_COUNTER_V_SINGLE 3 /* The most common value of expression. */
+#define GCOV_COUNTER_V_DELTA 4 /* The most common difference between
+ consecutive values of expression. */
+#define GCOV_LAST_VALUE_COUNTER 4 /* The last of counters used for value
+ profiling. */
+#define GCOV_COUNTERS 5
+
+/* Number of counters used for value profiling. */
+#define GCOV_N_VALUE_COUNTERS \
+ (GCOV_LAST_VALUE_COUNTER - GCOV_FIRST_VALUE_COUNTER + 1)
+
+ /* A list of human readable names of the counters */
+#define GCOV_COUNTER_NAMES {"arcs", "interval", "pow2", "single", "delta"}
+
+ /* Names of merge functions for counters. */
+#define GCOV_MERGE_FUNCTIONS {"__gcov_merge_add", \
+ "__gcov_merge_add", \
+ "__gcov_merge_add", \
+ "__gcov_merge_single", \
+ "__gcov_merge_delta"}
+
+/* Convert a counter index to a tag. */
+#define GCOV_TAG_FOR_COUNTER(COUNT) \
+ (GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17))
+/* Convert a tag to a counter. */
+#define GCOV_COUNTER_FOR_TAG(TAG) \
+ ((unsigned)(((TAG) - GCOV_TAG_COUNTER_BASE) >> 17))
+/* Check whether a tag is a counter tag. */
+#define GCOV_TAG_IS_COUNTER(TAG) \
+ (!((TAG) & 0xFFFF) && GCOV_COUNTER_FOR_TAG (TAG) < GCOV_COUNTERS)
+
+/* The tag level mask has 1's in the position of the inner levels, &
+ the lsb of the current level, and zero on the current and outer
+ levels. */
+#define GCOV_TAG_MASK(TAG) (((TAG) - 1) ^ (TAG))
+
+/* Return nonzero if SUB is an immediate subtag of TAG. */
+#define GCOV_TAG_IS_SUBTAG(TAG,SUB) \
+ (GCOV_TAG_MASK (TAG) >> 8 == GCOV_TAG_MASK (SUB) \
+ && !(((SUB) ^ (TAG)) & ~GCOV_TAG_MASK(TAG)))
+
+/* Return nonzero if SUB is at a sublevel to TAG. */
+#define GCOV_TAG_IS_SUBLEVEL(TAG,SUB) \
+ (GCOV_TAG_MASK (TAG) > GCOV_TAG_MASK (SUB))
+
+/* Basic block flags. */
+#define GCOV_BLOCK_UNEXPECTED (1 << 1)
+
+/* Arc flags. */
+#define GCOV_ARC_ON_TREE (1 << 0)
+#define GCOV_ARC_FAKE (1 << 1)
+#define GCOV_ARC_FALLTHROUGH (1 << 2)
+
+/* Structured records. */
+
+/* Cumulative counter data. */
+struct gcov_ctr_summary
{
- int upper_bit = (value < 0 ? 128 : 0);
- size_t i;
-
- if (value < 0)
- {
- gcov_type oldvalue = value;
- value = -value;
- if (oldvalue != -value)
- return 1;
- }
-
- for(i = 0 ; i < (sizeof (value) < bytes ? sizeof (value) : bytes) ; i++) {
- dest[i] = value & (i == (bytes - 1) ? 127 : 255);
- value = value / 256;
- }
-
- if (value && value != -1)
- return 1;
-
- for(; i < bytes ; i++)
- dest[i] = 0;
- dest[bytes - 1] |= upper_bit;
- return 0;
-}
-
-/* Retrieve a quantity containing BYTES*8-1 bits from SOURCE and store
- the result in DEST. Returns a nonzero value if the value in SOURCE
- will not fit in DEST. */
-
-static int
-__fetch_gcov_type (dest, source, bytes)
- gcov_type *dest;
- char *source;
- size_t bytes;
+ gcov_unsigned_t num; /* number of counters. */
+ gcov_unsigned_t runs; /* number of program runs */
+ gcov_type sum_all; /* sum of all counters accumulated. */
+ gcov_type run_max; /* maximum value on a single run. */
+ gcov_type sum_max; /* sum of individual run max values. */
+};
+
+/* Object & program summary record. */
+struct gcov_summary
{
- gcov_type value = 0;
- int i;
-
- for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
- if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
- return 1;
-
- for (; i >= 0; i--)
- value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 : 255));
+ gcov_unsigned_t checksum; /* checksum of program */
+ struct gcov_ctr_summary ctrs[GCOV_COUNTERS_SUMMABLE];
+};
+
+/* Structures embedded in coveraged program. The structures generated
+ by write_profile must match these. */
+
+#if IN_LIBGCOV
+/* Information about a single function. This uses the trailing array
+ idiom. The number of counters is determined from the counter_mask
+ in gcov_info. We hold an array of function info, so have to
+ explicitly calculate the correct array stride. */
+struct gcov_fn_info
+{
+ gcov_unsigned_t ident; /* unique ident of function */
+ gcov_unsigned_t checksum; /* function checksum */
+ unsigned n_ctrs[0]; /* instrumented counters */
+};
- if ((source[bytes - 1] & 128) && (value > 0))
- value = - value;
+/* Type of function used to merge counters. */
+typedef void (*gcov_merge_fn) (gcov_type *, gcov_unsigned_t);
- *dest = value;
- return 0;
-}
+/* Information about counters. */
+struct gcov_ctr_info
+{
+ gcov_unsigned_t num; /* number of counters. */
+ gcov_type *values; /* their values. */
+ gcov_merge_fn merge; /* The function used to merge them. */
+};
-static int
-__fetch_long (dest, source, bytes)
- long *dest;
- char *source;
- size_t bytes;
+/* Information about a single object file. */
+struct gcov_info
{
- long value = 0;
- int i;
+ gcov_unsigned_t version; /* expected version number */
+ struct gcov_info *next; /* link to next, used by libgcov */
- for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
- if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
- return 1;
+ gcov_unsigned_t stamp; /* uniquifying time stamp */
+ const char *filename; /* output file name */
+
+ unsigned n_functions; /* number of functions */
+ const struct gcov_fn_info *functions; /* table of functions */
- for (; i >= 0; i--)
- value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 : 255));
+ unsigned ctr_mask; /* mask of counters instrumented. */
+ struct gcov_ctr_info counts[0]; /* count data. The number of bits
+ set in the ctr_mask field
+ determines how big this array
+ is. */
+};
- if ((source[bytes - 1] & 128) && (value > 0))
- value = - value;
+/* Register a new object file module. */
+extern void __gcov_init (struct gcov_info *);
- *dest = value;
- return 0;
-}
+/* Called before fork, to avoid double counting. */
+extern void __gcov_flush (void);
-/* Write a BYTES*8-bit quantity to FILE, portably. Returns a nonzero
- value if the write fails, or if VALUE can't be stored in BYTES*8
- bits.
+/* The merge function that just sums the counters. */
+extern void __gcov_merge_add (gcov_type *, unsigned);
- Note that VALUE may not actually be large enough to hold BYTES*8
- bits, but BYTES characters will be written anyway.
+/* The merge function to choose the most common value. */
+extern void __gcov_merge_single (gcov_type *, unsigned);
- BYTES may be a maximum of 10. */
+/* The merge function to choose the most common difference between
+ consecutive values. */
+extern void __gcov_merge_delta (gcov_type *, unsigned);
+#endif /* IN_LIBGCOV */
-static int
-__write_gcov_type (value, file, bytes)
- gcov_type value;
- FILE *file;
- size_t bytes;
-{
- char c[10];
+#if IN_LIBGCOV >= 0
- if (bytes > 10 || __store_gcov_type (value, c, bytes))
- return 1;
- else
- return fwrite(c, 1, bytes, file) != bytes;
-}
+/* Optimum number of gcov_unsigned_t's read from or written to disk. */
+#define GCOV_BLOCK_SIZE (1 << 10)
-static int
-__write_long (value, file, bytes)
- long value;
- FILE *file;
- size_t bytes;
+GCOV_LINKAGE struct gcov_var
{
- char c[10];
-
- if (bytes > 10 || __store_gcov_type ((gcov_type)value, c, bytes))
- return 1;
- else
- return fwrite(c, 1, bytes, file) != bytes;
+ FILE *file;
+ gcov_position_t start; /* Position of first byte of block */
+ unsigned offset; /* Read/write position within the block. */
+ unsigned length; /* Read limit in the block. */
+ unsigned overread; /* Number of words overread. */
+ int error; /* < 0 overflow, > 0 disk error. */
+ int mode; /* < 0 writing, > 0 reading */
+#if IN_LIBGCOV
+ /* Holds one block plus 4 bytes, thus all coverage reads & writes
+ fit within this buffer and we always can transfer GCOV_BLOCK_SIZE
+ to and from the disk. libgcov never backtracks and only writes 4
+ or 8 byte objects. */
+ gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1];
+#else
+ int endian; /* Swap endianness. */
+ /* Holds a variable length block, as the compiler can write
+ strings and needs to backtrack. */
+ size_t alloc;
+ gcov_unsigned_t *buffer;
+#endif
+} gcov_var;
+
+/* Functions for reading and writing gcov files. In libgcov you can
+ open the file for reading then writing. Elsewhere you can open the
+ file either for reading or for writing. When reading a file you may
+ use the gcov_read_* functions, gcov_sync, gcov_position, &
+ gcov_error. When writing a file you may use the gcov_write
+ functions, gcov_seek & gcov_error. When a file is to be rewritten
+ you use the functions for reading, then gcov_rewrite then the
+ functions for writing. Your file may become corrupted if you break
+ these invariants. */
+#if IN_LIBGCOV
+GCOV_LINKAGE int gcov_open (const char */*name*/);
+#else
+GCOV_LINKAGE int gcov_open (const char */*name*/, int /*direction*/);
+GCOV_LINKAGE int gcov_magic (gcov_unsigned_t, gcov_unsigned_t);
+#endif
+GCOV_LINKAGE int gcov_close (void);
+
+/* Available everywhere. */
+static gcov_position_t gcov_position (void);
+static int gcov_is_error (void);
+static int gcov_is_eof (void);
+
+GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void);
+GCOV_LINKAGE gcov_type gcov_read_counter (void);
+GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *);
+
+#if IN_LIBGCOV
+/* Available only in libgcov */
+GCOV_LINKAGE void gcov_write_counter (gcov_type);
+GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t);
+GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
+ const struct gcov_summary *);
+static void gcov_truncate (void);
+static void gcov_rewrite (void);
+GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/);
+#else
+/* Available outside libgcov */
+GCOV_LINKAGE const char *gcov_read_string (void);
+GCOV_LINKAGE void gcov_sync (gcov_position_t /*base*/,
+ gcov_unsigned_t /*length */);
+#endif
+
+#if !IN_GCOV
+/* Available outside gcov */
+GCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t);
+#endif
+
+#if !IN_GCOV && !IN_LIBGCOV
+/* Available only in compiler */
+GCOV_LINKAGE void gcov_write_string (const char *);
+GCOV_LINKAGE gcov_position_t gcov_write_tag (gcov_unsigned_t);
+GCOV_LINKAGE void gcov_write_length (gcov_position_t /*position*/);
+#endif
+
+#if IN_GCOV > 0
+/* Available in gcov */
+GCOV_LINKAGE time_t gcov_time (void);
+#endif
+
+/* Make sure the library is used correctly. */
+#if ENABLE_CHECKING
+#define GCOV_CHECK(expr) ((expr) ? (void)0 : (void)abort ())
+#else
+#define GCOV_CHECK(expr)
+#endif
+#define GCOV_CHECK_READING() GCOV_CHECK(gcov_var.mode > 0)
+#define GCOV_CHECK_WRITING() GCOV_CHECK(gcov_var.mode < 0)
+
+/* Save the current position in the gcov file. */
+
+static inline gcov_position_t
+gcov_position (void)
+{
+ GCOV_CHECK_READING ();
+ return gcov_var.start + gcov_var.offset;
}
-/* Read a quantity containing BYTES bytes from FILE, portably. Return
- a nonzero value if the read fails or if the value will not fit
- in DEST.
-
- Note that DEST may not be large enough to hold all of the requested
- data, but the function will read BYTES characters anyway.
-
- BYTES may be a maximum of 10. */
+/* Return nonzero if we read to end of file. */
-static int
-__read_gcov_type (dest, file, bytes)
- gcov_type *dest;
- FILE *file;
- size_t bytes;
+static inline int
+gcov_is_eof (void)
{
- char c[10];
-
- if (bytes > 10 || fread(c, 1, bytes, file) != bytes)
- return 1;
- else
- return __fetch_gcov_type (dest, c, bytes);
+ return !gcov_var.overread;
}
-static int
-__read_long (dest, file, bytes)
- long *dest;
- FILE *file;
- size_t bytes;
-{
- char c[10];
+/* Return nonzero if the error flag is set. */
- if (bytes > 10 || fread(c, 1, bytes, file) != bytes)
- return 1;
- else
- return __fetch_long (dest, c, bytes);
+static inline int
+gcov_is_error (void)
+{
+ return gcov_var.file ? gcov_var.error : 1;
}
+#if IN_LIBGCOV
+/* Move to beginning of file and initialize for writing. */
-/* Writes string in gcov format. */
-
-static int
-__write_gcov_string (string, length, file, delim)
- const char *string;
- size_t length;
- FILE *file;
- long delim;
+static inline void
+gcov_rewrite (void)
{
- size_t temp = length + 1;
-
- /* delimiter */
- if (__write_long (delim, file, 4) != 0)
- return 1;
-
- if (__write_long (length, file, 4) != 0)
- return 1;
-
- if (fwrite (string, temp, 1, file) != 1)
- return 1;
-
- temp &= 3;
-
- if (temp)
- {
- char c[4];
-
- c[0] = c[1] = c[2] = c[3] = 0;
-
- if (fwrite (c, sizeof (char), 4 - temp, file) != 4 - temp)
- return 1;
- }
-
- if (__write_long (delim, file, 4) != 0)
- return 1;
-
- return 0;
+ GCOV_CHECK_READING ();
+ gcov_var.mode = -1;
+ gcov_var.start = 0;
+ gcov_var.offset = 0;
+ fseek (gcov_var.file, 0L, SEEK_SET);
}
-/* Reads string in gcov format. */
-
-
-static int
-__read_gcov_string (string, max_length, file, delim)
- char *string;
- size_t max_length;
- FILE *file;
- long delim;
+#ifdef __MINGW32__
+#define ftruncate _chsize
+#endif
+static inline void
+gcov_truncate (void)
{
- long delim_from_file;
- long length;
- long read_length;
- long tmp;
-
- if (__read_long (&delim_from_file, file, 4) != 0)
- return 1;
-
- if (delim_from_file != delim)
- return 1;
-
- if (__read_long (&length, file, 4) != 0)
- return 1;
-
- if (length > (long) max_length)
- read_length = max_length;
- else
- read_length = length;
-
- tmp = (((length + 1) - 1) / 4 + 1) * 4;
- /* This is the size occupied by the string in the file */
-
- if (fread (string, read_length, 1, file) != 1)
- return 1;
-
- string[read_length] = 0;
-
- if (fseek (file, tmp - read_length, SEEK_CUR) < 0)
- return 1;
-
- if (__read_long (&delim_from_file, file, 4) != 0)
- return 1;
-
- if (delim_from_file != delim)
- return 1;
-
- return 0;
+ ftruncate (fileno (gcov_var.file), 0L);
}
+#endif
+#endif /* IN_LIBGCOV >= 0 */
-#endif /* ! GCC_GCOV_IO_H */
+#endif /* GCC_GCOV_IO_H */
diff --git a/contrib/gcc/gcov-iov.c b/contrib/gcc/gcov-iov.c
new file mode 100644
index 000000000000..d6b39de3da1a
--- /dev/null
+++ b/contrib/gcc/gcov-iov.c
@@ -0,0 +1,68 @@
+/* Generate gcov version string from version.c. See gcov-io.h for
+ description of how the version string is generated.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Contributed by Nathan Sidwell <nathan@codesourcery.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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "bconfig.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "version.c" /* We want the actual string. */
+
+int main (int, char **);
+
+int
+main (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
+{
+ unsigned version = 0;
+ unsigned char v[4];
+ unsigned ix;
+ char const *ptr = version_string;
+ unsigned major, minor = 0;
+ char s = 0;
+
+ major = atoi (ptr);
+ while (*ptr && *ptr != '.')
+ ptr++;
+ if (*ptr)
+ minor = atoi (ptr + 1);
+ while (*ptr)
+ if (*ptr++ == '(')
+ {
+ s = *ptr;
+ break;
+ }
+
+ v[0] = (major < 10 ? '0' : 'A' - 10) + major;
+ v[1] = (minor / 10) + '0';
+ v[2] = (minor % 10) + '0';
+ v[3] = s ? s : '*';
+
+ for (ix = 0; ix != 4; ix++)
+ version = (version << 8) | v[ix];
+
+ printf ("/* Generated automatically by the program `%s'\n", argv[0]);
+ printf (" from `%s'. */\n", version_string);
+ printf ("\n");
+ printf ("#define GCOV_VERSION ((gcov_unsigned_t)%#08x) /* %.4s */\n",
+ version, v);
+
+ return 0;
+}
diff --git a/contrib/gcc/gcov.c b/contrib/gcc/gcov.c
index 94f9baad40b8..172f9e85651f 100644
--- a/contrib/gcc/gcov.c
+++ b/contrib/gcc/gcov.c
@@ -1,9 +1,10 @@
/* Gcov.c: prepend line execution counts and branch probabilities to a
source file.
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by James E. Wilson of Cygnus Support.
Mangled by Bob Manson of Cygnus Support.
+ Mangled further by Nathan Sidwell <nathan@codesourcery.com>
Gcov is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,14 +21,6 @@ along with Gcov; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* ??? The code in final.c that produces the struct bb assumes that there is
- no padding between the fields. This is not necessary true. The current
- code can only be trusted if longs and pointers are the same size. */
-
-/* ??? No need to print an execution count on every line, could just print
- it on the first line of each block, and only print it on a subsequent
- line in the same block if the count changes. */
-
/* ??? Print a list of the ten blocks with the highest execution counts,
and list the line numbers corresponding to those blocks. Also, perhaps
list the line numbers with the highest execution counts, only printing
@@ -36,291 +29,357 @@ Boston, MA 02111-1307, USA. */
/* ??? Should have an option to print the number of basic blocks, and the
percent of them that are covered. */
-/* ??? Does not correctly handle the case where two .bb files refer to the
- same included source file. For example, if one has a short file containing
- only inline functions, which is then included in two other files, then
- there will be two .bb files which refer to the include file, but there
- is no way to get the total execution counts for the included file, can
- only get execution counts for one or the other of the including files. */
+/* ??? Does not correctly handle the case where two .bb files refer to
+ the same included source file. For example, if one has a short
+ file containing only inline functions, which is then included in
+ two other files, then there will be two .bb files which refer to
+ the include file, but there is no way to get the total execution
+ counts for the included file, can only get execution counts for one
+ or the other of the including files. this can be fixed by --ratios
+ --long-file-names --preserve-paths and perl. */
+
+/* Need an option to show individual block counts, and show
+ probabilities of fall through arcs. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "intl.h"
#include "version.h"
#undef abort
#include <getopt.h>
-typedef HOST_WIDEST_INT gcov_type;
+#define IN_GCOV 1
#include "gcov-io.h"
+#include "gcov-io.c"
-/* The .bb file format consists of several lists of 4-byte integers
- which are the line numbers of each basic block in the file. Each
- list is terminated by a zero. These lists correspond to the basic
- blocks in the reconstructed program flow graph.
-
- A line number of -1 indicates that a source file name (padded to a
- long boundary) follows. The padded file name is followed by
- another -1 to make it easy to scan past file names. A -2 indicates
- that a function name (padded to a long boundary) follows; the name
- is followed by another -2 to make it easy to scan past the function
- name.
-
- The .bbg file contains enough info to enable gcov to reconstruct the
- program flow graph. The first word is the number of basic blocks,
- the second word is the number of arcs, followed by the list of arcs
- (source bb, dest bb pairs), then a -1, then the number of instrumented
- arcs followed by the instrumented arcs, followed by another -1. This
- is repeated for each function.
-
- The .da file contains the execution count for each instrumented branch.
-
- The .bb and .bbg files are created by giving GCC the -ftest-coverage option,
- and the .da files are created when an executable compiled with
- -fprofile-arcs is run. */
+/* The bbg file is generated by -ftest-coverage option. The da file is
+ generated by a program compiled with -fprofile-arcs. Their formats
+ are documented in gcov-io.h. */
/* The functions in this file for creating and solution program flow graphs
- are very similar to functions in the gcc source file profile.c. */
+ are very similar to functions in the gcc source file profile.c. In
+ some places we make use of the knowledge of how profile.c works to
+ select particular algorithms here. */
/* This is the size of the buffer used to read in source file lines. */
#define STRING_SIZE 200
-/* One copy of this structure is created for each source file mentioned in the
- .bb file. */
+struct function_info;
+struct block_info;
+struct source_info;
-struct sourcefile
-{
- char *name;
- int maxlineno;
- struct sourcefile *next;
-};
-
-/* This points to the head of the sourcefile structure list. */
+/* Describes an arc between two basic blocks. */
-struct sourcefile *sources;
+typedef struct arc_info
+{
+ /* source and destination blocks. */
+ struct block_info *src;
+ struct block_info *dst;
-/* One of these is dynamically created whenever we identify an arc in the
- function. */
+ /* transition counts. */
+ gcov_type count;
+ /* used in cycle search, so that we do not clobber original counts. */
+ gcov_type cs_count;
-struct adj_list
-{
- int source;
- int target;
- gcov_type arc_count;
unsigned int count_valid : 1;
unsigned int on_tree : 1;
unsigned int fake : 1;
unsigned int fall_through : 1;
-#if 0
- /* Not needed for gcov, but defined in profile.c. */
- rtx branch_insn;
-#endif
- struct adj_list *pred_next;
- struct adj_list *succ_next;
-};
-/* Count the number of basic blocks, and create an array of these structures,
- one for each bb in the function. */
+ /* Arc is for a function that abnormally returns. */
+ unsigned int is_call_non_return : 1;
-struct bb_info
-{
- struct adj_list *succ;
- struct adj_list *pred;
- gcov_type succ_count;
- gcov_type pred_count;
- gcov_type exec_count;
- unsigned int count_valid : 1;
- unsigned int on_tree : 1;
-#if 0
- /* Not needed for gcov, but defined in profile.c. */
- rtx first_insn;
-#endif
-};
+ /* Arc is for catch/setjump. */
+ unsigned int is_nonlocal_return : 1;
-/* When outputting branch probabilities, one of these structures is created
- for each branch/call. */
+ /* Is an unconditional branch. */
+ unsigned int is_unconditional : 1;
-struct arcdata
-{
- gcov_type hits;
- gcov_type total;
- int call_insn;
- struct arcdata *next;
-};
+ /* Loop making arc. */
+ unsigned int cycle : 1;
+
+ /* Next branch on line. */
+ struct arc_info *line_next;
-/* Used to save the list of bb_graphs, one per function. */
+ /* Links to next arc on src and dst lists. */
+ struct arc_info *succ_next;
+ struct arc_info *pred_next;
+} arc_t;
-struct bb_info_list
+/* Describes a basic block. Contains lists of arcs to successor and
+ predecessor blocks. */
+
+typedef struct block_info
{
- /* Indexed by block number, holds the basic block graph for one function. */
- struct bb_info *bb_graph;
- int num_blocks;
- struct bb_info_list *next;
-};
+ /* Chain of exit and entry arcs. */
+ arc_t *succ;
+ arc_t *pred;
+
+ /* Number of unprocessed exit and entry arcs. */
+ gcov_type num_succ;
+ gcov_type num_pred;
+
+ /* Block execution count. */
+ gcov_type count;
+ unsigned flags : 13;
+ unsigned count_valid : 1;
+ unsigned valid_chain : 1;
+ unsigned invalid_chain : 1;
+
+ /* Block is a call instrumenting site. */
+ unsigned is_call_site : 1; /* Does the call. */
+ unsigned is_call_return : 1; /* Is the return. */
+
+ /* Block is a landing pad for longjmp or throw. */
+ unsigned is_nonlocal_return : 1;
+
+ union
+ {
+ struct
+ {
+ /* Array of line numbers and source files. source files are
+ introduced by a linenumber of zero, the next 'line number' is
+ the number of the source file. Always starts with a source
+ file. */
+ unsigned *encoding;
+ unsigned num;
+ } line; /* Valid until blocks are linked onto lines */
+ struct
+ {
+ /* Single line graph cycle workspace. Used for all-blocks
+ mode. */
+ arc_t *arc;
+ unsigned ident;
+ } cycle; /* Used in all-blocks mode, after blocks are linked onto
+ lines. */
+ } u;
+
+ /* Temporary chain for solving graph, and for chaining blocks on one
+ line. */
+ struct block_info *chain;
+
+} block_t;
-/* Used to hold information about each line. */
-struct line_info
+/* Describes a single function. Contains an array of basic blocks. */
+
+typedef struct function_info
{
- gcov_type count; /* execution count */
- struct arcdata *branches; /* list of branch probabilities for line. */
- unsigned exists : 1; /* has code associated with it. */
-};
-
-struct coverage
+ /* Name of function. */
+ char *name;
+ unsigned ident;
+ unsigned checksum;
+
+ /* Array of basic blocks. */
+ block_t *blocks;
+ unsigned num_blocks;
+ unsigned blocks_executed;
+
+ /* Raw arc coverage counts. */
+ gcov_type *counts;
+ unsigned num_counts;
+
+ /* First line number. */
+ unsigned line;
+ struct source_info *src;
+
+ /* Next function in same source file. */
+ struct function_info *line_next;
+
+ /* Next function. */
+ struct function_info *next;
+} function_t;
+
+/* Describes coverage of a file or function. */
+
+typedef struct coverage_info
{
int lines;
int lines_executed;
-
+
int branches;
int branches_executed;
int branches_taken;
-
+
int calls;
int calls_executed;
-
+
char *name;
-};
+} coverage_t;
-/* Holds a list of function basic block graphs. */
+/* Describes a single line of source. Contains a chain of basic blocks
+ with code on it. */
-static struct bb_info_list *bb_graph_list = 0;
+typedef struct line_info
+{
+ gcov_type count; /* execution count */
+ union
+ {
+ arc_t *branches; /* branches from blocks that end on this
+ line. Used for branch-counts when not
+ all-blocks mode. */
+ block_t *blocks; /* blocks which start on this line. Used
+ in all-blocks mode. */
+ } u;
+ unsigned exists : 1;
+} line_t;
+
+/* Describes a file mentioned in the block graph. Contains an array
+ of line info. */
+
+typedef struct source_info
+{
+ /* Name of source file. */
+ char *name;
+ unsigned index;
-/* Modification time of data files. */
+ /* Array of line information. */
+ line_t *lines;
+ unsigned num_lines;
-static time_t bb_file_time;
+ coverage_t coverage;
-/* Name and file pointer of the input file for the basic block graph. */
+ /* Functions in this source file. These are in ascending line
+ number order. */
+ function_t *functions;
-static char *bbg_file_name;
-static FILE *bbg_file;
+ /* Next source file. */
+ struct source_info *next;
+} source_t;
-/* Name and file pointer of the input file for the arc count data. */
+/* Holds a list of function basic block graphs. */
-static char *da_file_name;
-static FILE *da_file;
+static function_t *functions;
+
+/* This points to the head of the sourcefile structure list. */
+
+static source_t *sources;
+
+/* This holds data summary information. */
+
+static struct gcov_summary object_summary;
+static unsigned program_count;
-/* Name and file pointer of the input file for the basic block line counts. */
+/* Modification time of graph file. */
-static char *bb_file_name;
-static FILE *bb_file;
+static time_t bbg_file_time;
-/* Holds the entire contents of the bb_file read into memory. */
+/* Name and file pointer of the input file for the basic block graph. */
-static char *bb_data;
+static char *bbg_file_name;
-/* Size of bb_data array in longs. */
+/* Stamp of the bbg file */
+static unsigned bbg_stamp;
-static long bb_data_size;
+/* Name and file pointer of the input file for the arc count data. */
-/* Name of the file mentioned on the command line. */
+static char *da_file_name;
-static char *input_file_name = 0;
+/* Output branch probabilities. */
-/* Output branch probabilities if true. */
+static int flag_branches = 0;
-static int output_branch_probs = 0;
+/* Show unconditional branches too. */
+static int flag_unconditional = 0;
/* Output a gcov file if this is true. This is on by default, and can
be turned off by the -n option. */
-static int output_gcov_file = 1;
+static int flag_gcov_file = 1;
+
+/* For included files, make the gcov output file name include the name
+ of the input source file. For example, if x.h is included in a.c,
+ then the output file name is a.c##x.h.gcov instead of x.h.gcov. */
-/* For included files, make the gcov output file name include the name of
- the input source file. For example, if x.h is included in a.c, then the
- output file name is a.c.x.h.gcov instead of x.h.gcov. This works only
- when a single source file is specified. */
+static int flag_long_names = 0;
-static int output_long_names = 0;
+/* Output count information for every basic block, not merely those
+ that contain line number information. */
+
+static int flag_all_blocks = 0;
/* Output summary info for each function. */
-static int output_function_summary = 0;
+static int flag_function_summary = 0;
-/* Object directory file prefix. This is the directory/file
- where .bb and .bbg files are looked for, if nonzero. */
+/* Object directory file prefix. This is the directory/file where the
+ graph and data files are looked for, if nonzero. */
static char *object_directory = 0;
/* Preserve all pathname components. Needed when object files and
- source files are in subdirectories. */
-static int preserve_paths = 0;
+ source files are in subdirectories. '/' is mangled as '#', '.' is
+ elided and '..' mangled to '^'. */
+
+static int flag_preserve_paths = 0;
/* Output the number of times a branch was taken as opposed to the percentage
- of times it was taken. Turned on by the -c option */
+ of times it was taken. */
-static int output_branch_counts = 0;
+static int flag_counts = 0;
/* Forward declarations. */
-static void process_args PARAMS ((int, char **));
-static void open_files PARAMS ((void));
-static void read_files PARAMS ((void));
-static void scan_for_source_files PARAMS ((void));
-static void output_data PARAMS ((struct sourcefile *));
-static void print_usage PARAMS ((int)) ATTRIBUTE_NORETURN;
-static void print_version PARAMS ((void)) ATTRIBUTE_NORETURN;
-static void init_arc PARAMS ((struct adj_list *, int, int, struct bb_info *));
-static struct adj_list *reverse_arcs PARAMS ((struct adj_list *));
-static gcov_type *read_profile PARAMS ((char *, long, int));
-static void create_program_flow_graph PARAMS ((struct bb_info_list *));
-static void solve_program_flow_graph PARAMS ((struct bb_info_list *));
-static void accumulate_branch_counts PARAMS ((struct coverage *,
- struct arcdata *));
-static void calculate_branch_probs PARAMS ((struct bb_info *,
- struct line_info *,
- struct coverage *));
-static void function_summary PARAMS ((struct coverage *, const char *));
-static void init_line_info PARAMS ((struct line_info *,
- struct coverage *, long));
-static void output_line_info PARAMS ((FILE *, const struct line_info *,
- const struct coverage *, long));
-static char *make_gcov_file_name PARAMS ((char *));
-static const char *format_hwint PARAMS ((HOST_WIDEST_INT, HOST_WIDEST_INT,
- int));
-
-extern int main PARAMS ((int, char **));
+static void fnotice (FILE *, const char *, ...) ATTRIBUTE_PRINTF_2;
+static int process_args (int, char **);
+static void print_usage (int) ATTRIBUTE_NORETURN;
+static void print_version (void) ATTRIBUTE_NORETURN;
+static void process_file (const char *);
+static void create_file_names (const char *);
+static source_t *find_source (const char *);
+static int read_graph_file (void);
+static int read_count_file (void);
+static void solve_flow_graph (function_t *);
+static void add_branch_counts (coverage_t *, const arc_t *);
+static void add_line_counts (coverage_t *, function_t *);
+static void function_summary (const coverage_t *, const char *);
+static const char *format_gcov (gcov_type, gcov_type, int);
+static void accumulate_line_counts (source_t *);
+static int output_branch_count (FILE *, int, const arc_t *);
+static void output_lines (FILE *, const source_t *);
+static char *make_gcov_file_name (const char *, const char *);
+static void release_structures (void);
+extern int main (int, char **);
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
- struct sourcefile *s_ptr;
-
- gcc_init_libintl ();
+ int argno;
- process_args (argc, argv);
-
- open_files ();
+ gcc_init_libintl ();
- read_files ();
+ argno = process_args (argc, argv);
+ if (optind == argc)
+ print_usage (true);
- scan_for_source_files ();
+ for (; argno != argc; argno++)
+ {
+ release_structures ();
- for (s_ptr = sources; s_ptr; s_ptr = s_ptr->next)
- output_data (s_ptr);
+ process_file (argv[argno]);
+ }
return 0;
}
-static void fnotice PARAMS ((FILE *, const char *, ...)) ATTRIBUTE_PRINTF_2;
static void
-fnotice VPARAMS ((FILE *file, const char *msgid, ...))
+fnotice (FILE *file, const char *msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, FILE *, file);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_list ap;
+ va_start (ap, msgid);
vfprintf (file, _(msgid), ap);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* More 'friendly' abort that prints the line and file.
config.h can #define abort fancy_abort if you like that sort of thing. */
-extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
+extern void fancy_abort (void) ATTRIBUTE_NORETURN;
void
-fancy_abort ()
+fancy_abort (void)
{
fnotice (stderr, "Internal gcov abort.\n");
exit (FATAL_EXIT_CODE);
@@ -330,15 +389,16 @@ fancy_abort ()
otherwise the output of --help. */
static void
-print_usage (error_p)
- int error_p;
+print_usage (int error_p)
{
FILE *file = error_p ? stderr : stdout;
int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
+
fnotice (file, "Usage: gcov [OPTION]... SOURCEFILE\n\n");
fnotice (file, "Print code coverage information.\n\n");
fnotice (file, " -h, --help Print this help, then exit\n");
fnotice (file, " -v, --version Print version number, then exit\n");
+ fnotice (file, " -a, --all-blocks Show information for every basic block\n");
fnotice (file, " -b, --branch-probabilities Include branch probabilities in output\n");
fnotice (file, " -c, --branch-counts Given counts of branches taken\n\
rather than percentages\n");
@@ -348,6 +408,7 @@ print_usage (error_p)
fnotice (file, " -f, --function-summaries Output summaries for each function\n");
fnotice (file, " -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
fnotice (file, " -p, --preserve-paths Preserve all pathname components\n");
+ fnotice (file, " -u, --unconditional-branches Show unconditional branch counts too\n");
fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
bug_report_url);
exit (status);
@@ -356,13 +417,15 @@ print_usage (error_p)
/* Print version information and exit. */
static void
-print_version ()
+print_version (void)
{
fnotice (stdout, "gcov (GCC) %s\n", version_string);
- fnotice (stdout, "Copyright (C) 2001 Free Software Foundation, Inc.\n");
+ fprintf (stdout, "Copyright %s 2004 Free Software Foundation, Inc.\n",
+ _("(C)"));
fnotice (stdout,
- "This is free software; see the source for copying conditions. There is NO\n\
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
+ _("This is free software; see the source for copying conditions.\n"
+ "There is NO warranty; not even for MERCHANTABILITY or \n"
+ "FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
exit (SUCCESS_EXIT_CODE);
}
@@ -370,6 +433,7 @@ static const struct option options[] =
{
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
+ { "all-blocks", no_argument, NULL, 'a' },
{ "branch-probabilities", no_argument, NULL, 'b' },
{ "branch-counts", no_argument, NULL, 'c' },
{ "no-output", no_argument, NULL, 'n' },
@@ -378,77 +442,189 @@ static const struct option options[] =
{ "preserve-paths", no_argument, NULL, 'p' },
{ "object-directory", required_argument, NULL, 'o' },
{ "object-file", required_argument, NULL, 'o' },
+ { "unconditional-branches", no_argument, NULL, 'u' },
+ { 0, 0, 0, 0 }
};
-/* Parse the command line. */
+/* Process args, return index to first non-arg. */
-static void
-process_args (argc, argv)
- int argc;
- char **argv;
+static int
+process_args (int argc, char **argv)
{
int opt;
- while ((opt = getopt_long (argc, argv, "hvbclnfo:p", options, NULL)) != -1)
+ while ((opt = getopt_long (argc, argv, "abcfhlno:puv", options, NULL)) != -1)
{
switch (opt)
{
- case 'h':
- print_usage (false);
- /* print_usage will exit. */
- case 'v':
- print_version ();
- /* print_version will exit. */
+ case 'a':
+ flag_all_blocks = 1;
+ break;
case 'b':
- output_branch_probs = 1;
+ flag_branches = 1;
break;
case 'c':
- output_branch_counts = 1;
+ flag_counts = 1;
break;
- case 'n':
- output_gcov_file = 0;
+ case 'f':
+ flag_function_summary = 1;
break;
+ case 'h':
+ print_usage (false);
+ /* print_usage will exit. */
case 'l':
- output_long_names = 1;
+ flag_long_names = 1;
break;
- case 'f':
- output_function_summary = 1;
+ case 'n':
+ flag_gcov_file = 0;
break;
case 'o':
object_directory = optarg;
break;
case 'p':
- preserve_paths = 1;
+ flag_preserve_paths = 1;
break;
+ case 'u':
+ flag_unconditional = 1;
+ break;
+ case 'v':
+ print_version ();
+ /* print_version will exit. */
default:
print_usage (true);
/* print_usage will exit. */
}
}
- if (optind != argc - 1)
- print_usage (true);
+ return optind;
+}
+
+/* Process a single source file. */
+
+static void
+process_file (const char *file_name)
+{
+ source_t *src;
+ function_t *fn;
+
+ create_file_names (file_name);
+ if (read_graph_file ())
+ return;
+
+ if (!functions)
+ {
+ fnotice (stderr, "%s:no functions found\n", bbg_file_name);
+ return;
+ }
+
+ if (read_count_file ())
+ return;
+
+ for (fn = functions; fn; fn = fn->next)
+ solve_flow_graph (fn);
+ for (src = sources; src; src = src->next)
+ src->lines = xcalloc (src->num_lines, sizeof (line_t));
+ for (fn = functions; fn; fn = fn->next)
+ {
+ coverage_t coverage;
+
+ memset (&coverage, 0, sizeof (coverage));
+ coverage.name = fn->name;
+ add_line_counts (flag_function_summary ? &coverage : NULL, fn);
+ if (flag_function_summary)
+ {
+ function_summary (&coverage, "Function");
+ fnotice (stdout, "\n");
+ }
+ }
- input_file_name = argv[optind];
+ for (src = sources; src; src = src->next)
+ {
+ accumulate_line_counts (src);
+ function_summary (&src->coverage, "File");
+ if (flag_gcov_file)
+ {
+ char *gcov_file_name = make_gcov_file_name (file_name, src->name);
+ FILE *gcov_file = fopen (gcov_file_name, "w");
+
+ if (gcov_file)
+ {
+ fnotice (stdout, "%s:creating `%s'\n",
+ src->name, gcov_file_name);
+ output_lines (gcov_file, src);
+ if (ferror (gcov_file))
+ fnotice (stderr, "%s:error writing output file `%s'\n",
+ src->name, gcov_file_name);
+ fclose (gcov_file);
+ }
+ else
+ fnotice (stderr, "%s:could not open output file `%s'\n",
+ src->name, gcov_file_name);
+ free (gcov_file_name);
+ }
+ fnotice (stdout, "\n");
+ }
}
+/* Release all memory used. */
+
+static void
+release_structures (void)
+{
+ function_t *fn;
+ source_t *src;
+
+ free (bbg_file_name);
+ free (da_file_name);
+ da_file_name = bbg_file_name = NULL;
+ bbg_file_time = 0;
+ bbg_stamp = 0;
+
+ while ((src = sources))
+ {
+ sources = src->next;
+
+ free (src->name);
+ free (src->lines);
+ }
-/* Find and open the .bb, .da, and .bbg files. If OBJECT_DIRECTORY is
- not specified, these are looked for in the current directory, and
- named from the basename of the input_file_name sans extension. If
+ while ((fn = functions))
+ {
+ unsigned ix;
+ block_t *block;
+
+ functions = fn->next;
+ for (ix = fn->num_blocks, block = fn->blocks; ix--; block++)
+ {
+ arc_t *arc, *arc_n;
+
+ for (arc = block->succ; arc; arc = arc_n)
+ {
+ arc_n = arc->succ_next;
+ free (arc);
+ }
+ }
+ free (fn->blocks);
+ free (fn->counts);
+ }
+}
+
+/* Generate the names of the graph and data files. If OBJECT_DIRECTORY
+ is not specified, these are looked for in the current directory,
+ and named from the basename of the FILE_NAME sans extension. If
OBJECT_DIRECTORY is specified and is a directory, the files are in
- that directory, but named from the basename of the input_file_name,
- sans extension. Otherwise OBJECT_DIRECTORY is taken to be the name
- of the object *file*, and the data files are named from that. */
+ that directory, but named from the basename of the FILE_NAME, sans
+ extension. Otherwise OBJECT_DIRECTORY is taken to be the name of
+ the object *file*, and the data files are named from that. */
static void
-open_files ()
+create_file_names (const char *file_name)
{
char *cptr;
char *name;
- int length = strlen (input_file_name);
+ int length = strlen (file_name);
int base;
-
+
if (object_directory && object_directory[0])
{
struct stat status;
@@ -456,7 +632,7 @@ open_files ()
length += strlen (object_directory) + 2;
name = xmalloc (length);
name[0] = 0;
-
+
base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
strcat (name, object_directory);
if (base && name[strlen (name) - 1] != '/')
@@ -468,662 +644,692 @@ open_files ()
name[0] = 0;
base = 1;
}
-
+
if (base)
{
- /* Append source file name */
- cptr = strrchr (input_file_name, '/');
- cptr = cptr ? cptr + 1 : input_file_name;
-
- strcat (name, cptr);
+ /* Append source file name. */
+ cptr = strrchr (file_name, '/');
+ strcat (name, cptr ? cptr + 1 : file_name);
}
+
/* Remove the extension. */
cptr = strrchr (name, '.');
if (cptr)
*cptr = 0;
-
- length = strlen (name);
- da_file_name = xmalloc (length + 4);
- bb_file_name = xmalloc (length + 4);
- bbg_file_name = xmalloc (length + 5);
-
- strcpy (da_file_name, name);
- strcpy (bb_file_name, name);
- strcpy (bbg_file_name, name);
- strcpy (da_file_name + length, ".da");
- strcpy (bb_file_name + length, ".bb");
- strcpy (bbg_file_name + length, ".bbg");
-
- bb_file = fopen (bb_file_name, "rb");
- if (bb_file == NULL)
- {
- fnotice (stderr, "Could not open basic block file %s.\n", bb_file_name);
- exit (FATAL_EXIT_CODE);
- }
- bbg_file = fopen (bbg_file_name, "rb");
- if (bbg_file == NULL)
- {
- fnotice (stderr, "Could not open program flow graph file %s.\n",
- bbg_file_name);
- exit (FATAL_EXIT_CODE);
- }
+ length = strlen (name);
- {
- struct stat status;
+ bbg_file_name = xmalloc (length + strlen (GCOV_NOTE_SUFFIX) + 1);
+ strcpy (bbg_file_name, name);
+ strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);
- if (!fstat (fileno (bb_file), &status))
- bb_file_time = status.st_mtime;
- }
-
- /* If none of the functions in the file were executed, then there won't
- be a .da file. Just assume that all counts are zero in this case. */
- da_file = fopen (da_file_name, "rb");
- if (da_file == NULL)
- {
- fnotice (stderr, "Could not open data file %s.\n", da_file_name);
- fnotice (stderr, "Assuming that all execution counts are zero.\n");
- }
+ da_file_name = xmalloc (length + strlen (GCOV_DATA_SUFFIX) + 1);
+ strcpy (da_file_name, name);
+ strcpy (da_file_name + length, GCOV_DATA_SUFFIX);
- /* Check for empty .bbg file. This indicates that there is no executable
- code in this source file. */
- /* Set the EOF condition if at the end of file. */
- ungetc (getc (bbg_file), bbg_file);
- if (feof (bbg_file))
- {
- fnotice (stderr, "No executable code associated with file %s.\n",
- input_file_name);
- exit (FATAL_EXIT_CODE);
- }
+ return;
}
-
-/* Initialize a new arc. */
-static void
-init_arc (arcptr, source, target, bb_graph)
- struct adj_list *arcptr;
- int source, target;
- struct bb_info *bb_graph;
+/* Find or create a source file structure for FILE_NAME. Copies
+ FILE_NAME on creation */
+
+static source_t *
+find_source (const char *file_name)
{
- arcptr->target = target;
- arcptr->source = source;
-
- arcptr->arc_count = 0;
- arcptr->count_valid = 0;
- arcptr->on_tree = 0;
- arcptr->fake = 0;
- arcptr->fall_through = 0;
-
- arcptr->succ_next = bb_graph[source].succ;
- bb_graph[source].succ = arcptr;
- bb_graph[source].succ_count++;
-
- arcptr->pred_next = bb_graph[target].pred;
- bb_graph[target].pred = arcptr;
- bb_graph[target].pred_count++;
-}
+ source_t *src;
-/* Reverse the arcs on an arc list. */
+ if (!file_name)
+ file_name = "<unknown>";
-static struct adj_list *
-reverse_arcs (arcptr)
- struct adj_list *arcptr;
-{
- struct adj_list *prev = 0;
- struct adj_list *next;
+ for (src = sources; src; src = src->next)
+ if (!strcmp (file_name, src->name))
+ return src;
- for ( ; arcptr; arcptr = next)
- {
- next = arcptr->succ_next;
- arcptr->succ_next = prev;
- prev = arcptr;
- }
+ src = xcalloc (1, sizeof (source_t));
+ src->name = xstrdup (file_name);
+ src->coverage.name = src->name;
+ src->index = sources ? sources->index + 1 : 1;
+ src->next = sources;
+ sources = src;
- return prev;
+ return src;
}
-/* Reads profiles from the .da file and compute a hybrid profile. */
+/* Read the graph file. Return nonzero on fatal error. */
-static gcov_type *
-read_profile (function_name, cfg_checksum, instr_arcs)
- char *function_name;
- long cfg_checksum;
- int instr_arcs;
+static int
+read_graph_file (void)
{
- int i;
- int okay = 1;
- gcov_type *profile;
- char *function_name_buffer;
- int function_name_buffer_len;
+ unsigned version;
+ unsigned current_tag = 0;
+ struct function_info *fn = NULL;
+ source_t *src = NULL;
+ unsigned ix;
+ unsigned tag;
+
+ if (!gcov_open (bbg_file_name, 1))
+ {
+ fnotice (stderr, "%s:cannot open graph file\n", bbg_file_name);
+ return 1;
+ }
+ bbg_file_time = gcov_time ();
+ if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
+ {
+ fnotice (stderr, "%s:not a gcov graph file\n", bbg_file_name);
+ gcov_close ();
+ return 1;
+ }
- profile = xmalloc (sizeof (gcov_type) * instr_arcs);
- function_name_buffer_len = strlen (function_name) + 1;
- function_name_buffer = xmalloc (function_name_buffer_len + 1);
+ version = gcov_read_unsigned ();
+ if (version != GCOV_VERSION)
+ {
+ char v[4], e[4];
- for (i = 0; i < instr_arcs; i++)
- profile[i] = 0;
+ GCOV_UNSIGNED2STRING (v, version);
+ GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
- if (!da_file)
- return profile;
+ fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n",
+ bbg_file_name, v, e);
+ }
+ bbg_stamp = gcov_read_unsigned ();
- rewind (da_file);
- while (1)
+ while ((tag = gcov_read_unsigned ()))
{
- long magic, extra_bytes;
- long func_count;
- int i;
+ unsigned length = gcov_read_unsigned ();
+ gcov_position_t base = gcov_position ();
- if (__read_long (&magic, da_file, 4) != 0)
- break;
-
- if (magic != -123)
+ if (tag == GCOV_TAG_FUNCTION)
{
- okay = 0;
- break;
+ char *function_name;
+ unsigned ident, checksum, lineno;
+ source_t *src;
+ function_t *probe, *prev;
+
+ ident = gcov_read_unsigned ();
+ checksum = gcov_read_unsigned ();
+ function_name = xstrdup (gcov_read_string ());
+ src = find_source (gcov_read_string ());
+ lineno = gcov_read_unsigned ();
+
+ fn = xcalloc (1, sizeof (function_t));
+ fn->name = function_name;
+ fn->ident = ident;
+ fn->checksum = checksum;
+ fn->src = src;
+ fn->line = lineno;
+
+ fn->next = functions;
+ functions = fn;
+ current_tag = tag;
+
+ if (lineno >= src->num_lines)
+ src->num_lines = lineno + 1;
+ /* Now insert it into the source file's list of
+ functions. Normally functions will be encountered in
+ ascending order, so a simple scan is quick. */
+ for (probe = src->functions, prev = NULL;
+ probe && probe->line > lineno;
+ prev = probe, probe = probe->line_next)
+ continue;
+ fn->line_next = probe;
+ if (prev)
+ prev->line_next = fn;
+ else
+ src->functions = fn;
}
-
- if (__read_long (&func_count, da_file, 4) != 0)
+ else if (fn && tag == GCOV_TAG_BLOCKS)
{
- okay = 0;
- break;
- }
+ if (fn->blocks)
+ fnotice (stderr, "%s:already seen blocks for `%s'\n",
+ bbg_file_name, fn->name);
+ else
+ {
+ unsigned ix, num_blocks = GCOV_TAG_BLOCKS_NUM (length);
+ fn->num_blocks = num_blocks;
- if (__read_long (&extra_bytes, da_file, 4) != 0)
- {
- okay = 0;
- break;
+ fn->blocks = xcalloc (fn->num_blocks, sizeof (block_t));
+ for (ix = 0; ix != num_blocks; ix++)
+ fn->blocks[ix].flags = gcov_read_unsigned ();
+ }
}
-
- /* skip extra data emited by __bb_exit_func. */
- fseek (da_file, extra_bytes, SEEK_CUR);
-
- for (i = 0; i < func_count; i++)
+ else if (fn && tag == GCOV_TAG_ARCS)
{
- long arc_count;
- long chksum;
- int j;
+ unsigned src = gcov_read_unsigned ();
+ unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
- if (__read_gcov_string
- (function_name_buffer, function_name_buffer_len, da_file,
- -1) != 0)
- {
- okay = 0;
- break;
- }
+ if (src >= fn->num_blocks || fn->blocks[src].succ)
+ goto corrupt;
- if (__read_long (&chksum, da_file, 4) != 0)
+ while (num_dests--)
{
- okay = 0;
- break;
- }
+ struct arc_info *arc;
+ unsigned dest = gcov_read_unsigned ();
+ unsigned flags = gcov_read_unsigned ();
- if (__read_long (&arc_count, da_file, 4) != 0)
- {
- okay = 0;
- break;
- }
+ if (dest >= fn->num_blocks)
+ goto corrupt;
+ arc = xcalloc (1, sizeof (arc_t));
- if (strcmp (function_name_buffer, function_name) != 0
- || arc_count != instr_arcs || chksum != cfg_checksum)
- {
- /* skip */
- if (fseek (da_file, arc_count * 8, SEEK_CUR) < 0)
+ arc->dst = &fn->blocks[dest];
+ arc->src = &fn->blocks[src];
+
+ arc->count = 0;
+ arc->count_valid = 0;
+ arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
+ arc->fake = !!(flags & GCOV_ARC_FAKE);
+ arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);
+
+ arc->succ_next = fn->blocks[src].succ;
+ fn->blocks[src].succ = arc;
+ fn->blocks[src].num_succ++;
+
+ arc->pred_next = fn->blocks[dest].pred;
+ fn->blocks[dest].pred = arc;
+ fn->blocks[dest].num_pred++;
+
+ if (arc->fake)
{
- okay = 0;
- break;
+ if (src)
+ {
+ /* Exceptional exit from this function, the
+ source block must be a call. */
+ fn->blocks[src].is_call_site = 1;
+ arc->is_call_non_return = 1;
+ }
+ else
+ {
+ /* Non-local return from a callee of this
+ function. The destination block is a catch or
+ setjmp. */
+ arc->is_nonlocal_return = 1;
+ fn->blocks[dest].is_nonlocal_return = 1;
+ }
}
- }
- else
- {
- gcov_type tmp;
- for (j = 0; j < arc_count; j++)
- if (__read_gcov_type (&tmp, da_file, 8) != 0)
- {
- okay = 0;
- break;
- }
- else
- {
- profile[j] += tmp;
- }
+ if (!arc->on_tree)
+ fn->num_counts++;
}
}
+ else if (fn && tag == GCOV_TAG_LINES)
+ {
+ unsigned blockno = gcov_read_unsigned ();
+ unsigned *line_nos = xcalloc (length - 1, sizeof (unsigned));
- if (!okay)
- break;
-
- }
-
- free (function_name_buffer);
+ if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
+ goto corrupt;
- if (!okay)
- {
- fprintf (stderr, ".da file corrupted!\n");
- free (profile);
- abort ();
- }
+ for (ix = 0; ; )
+ {
+ unsigned lineno = gcov_read_unsigned ();
- return profile;
-}
+ if (lineno)
+ {
+ if (!ix)
+ {
+ line_nos[ix++] = 0;
+ line_nos[ix++] = src->index;
+ }
+ line_nos[ix++] = lineno;
+ if (lineno >= src->num_lines)
+ src->num_lines = lineno + 1;
+ }
+ else
+ {
+ const char *file_name = gcov_read_string ();
-/* Construct the program flow graph from the .bbg file, and read in the data
- in the .da file. */
+ if (!file_name)
+ break;
+ src = find_source (file_name);
-static void
-create_program_flow_graph (bptr)
- struct bb_info_list *bptr;
-{
- long num_blocks, number_arcs, src, dest, flag_bits, num_arcs_per_block;
- int i;
- struct adj_list *arcptr;
- struct bb_info *bb_graph;
- long cfg_checksum;
- long instr_arcs = 0;
- gcov_type *profile;
- int profile_pos = 0;
- char *function_name;
- long function_name_len, tmp;
-
- /* Read function name. */
- __read_long (&tmp, bbg_file, 4); /* ignore -1. */
- __read_long (&function_name_len, bbg_file, 4);
- function_name = xmalloc (function_name_len + 1);
- fread (function_name, 1, function_name_len + 1, bbg_file);
-
- /* Skip padding. */
- tmp = (function_name_len + 1) % 4;
-
- if (tmp)
- fseek (bbg_file, 4 - tmp, SEEK_CUR);
-
- __read_long (&tmp, bbg_file, 4); /* ignore -1. */
-
- /* Read the cfg checksum. */
- __read_long (&cfg_checksum, bbg_file, 4);
-
- /* Read the number of blocks. */
- __read_long (&num_blocks, bbg_file, 4);
-
- /* Create an array of size bb number of bb_info structs. */
- bb_graph = (struct bb_info *) xcalloc (num_blocks, sizeof (struct bb_info));
-
- bptr->bb_graph = bb_graph;
- bptr->num_blocks = num_blocks;
-
- /* Read and create each arc from the .bbg file. */
- __read_long (&number_arcs, bbg_file, 4);
- for (i = 0; i < num_blocks; i++)
- {
- int j;
+ line_nos[ix++] = 0;
+ line_nos[ix++] = src->index;
+ }
+ }
- __read_long (&num_arcs_per_block, bbg_file, 4);
- for (j = 0; j < num_arcs_per_block; j++)
+ fn->blocks[blockno].u.line.encoding = line_nos;
+ fn->blocks[blockno].u.line.num = ix;
+ }
+ else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
{
- if (number_arcs-- < 0)
- abort ();
-
- src = i;
- __read_long (&dest, bbg_file, 4);
-
- arcptr = (struct adj_list *) xmalloc (sizeof (struct adj_list));
- init_arc (arcptr, src, dest, bb_graph);
-
- __read_long (&flag_bits, bbg_file, 4);
- if (flag_bits & 0x1)
- arcptr->on_tree++;
- else
- instr_arcs++;
- arcptr->fake = !! (flag_bits & 0x2);
- arcptr->fall_through = !! (flag_bits & 0x4);
+ fn = NULL;
+ current_tag = 0;
}
+ gcov_sync (base, length);
+ if (gcov_is_error ())
+ break;
}
+ if (!gcov_is_eof ())
+ {
+ corrupt:;
+ fnotice (stderr, "%s:corrupted\n", bbg_file_name);
+ gcov_close ();
+ return 1;
+ }
+ gcov_close ();
- if (number_arcs)
- abort ();
-
- /* Read and ignore the -1 separating the arc list from the arc list of the
- next function. */
- __read_long (&src, bbg_file, 4);
- if (src != -1)
- abort ();
+ /* We built everything backwards, so nreverse them all. */
- /* Must reverse the order of all succ arcs, to ensure that they match
- the order of the data in the .da file. */
+ /* Reverse sources. Not strictly necessary, but we'll then process
+ them in the 'expected' order. */
+ {
+ source_t *src, *src_p, *src_n;
+
+ for (src_p = NULL, src = sources; src; src_p = src, src = src_n)
+ {
+ src_n = src->next;
+ src->next = src_p;
+ }
+ sources = src_p;
+ }
- for (i = 0; i < num_blocks; i++)
- if (bb_graph[i].succ)
- bb_graph[i].succ = reverse_arcs (bb_graph[i].succ);
+ /* Reverse functions. */
+ {
+ function_t *fn, *fn_p, *fn_n;
- /* Read profile from the .da file. */
+ for (fn_p = NULL, fn = functions; fn; fn_p = fn, fn = fn_n)
+ {
+ unsigned ix;
- profile = read_profile (function_name, cfg_checksum, instr_arcs);
+ fn_n = fn->next;
+ fn->next = fn_p;
- /* For each arc not on the spanning tree, set its execution count from
- the .da file. */
+ /* Reverse the arcs. */
+ for (ix = fn->num_blocks; ix--;)
+ {
+ arc_t *arc, *arc_p, *arc_n;
+
+ for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
+ arc_p = arc, arc = arc_n)
+ {
+ arc_n = arc->succ_next;
+ arc->succ_next = arc_p;
+ }
+ fn->blocks[ix].succ = arc_p;
+
+ for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
+ arc_p = arc, arc = arc_n)
+ {
+ arc_n = arc->pred_next;
+ arc->pred_next = arc_p;
+ }
+ fn->blocks[ix].pred = arc_p;
+ }
+ }
+ functions = fn_p;
+ }
+ return 0;
+}
- /* The first count in the .da file is the number of times that the function
- was entered. This is the exec_count for block zero. */
+/* Reads profiles from the count file and attach to each
+ function. Return nonzero if fatal error. */
- /* This duplicates code in branch_prob in profile.c. */
+static int
+read_count_file (void)
+{
+ unsigned ix;
+ unsigned version;
+ unsigned tag;
+ function_t *fn = NULL;
+ int error = 0;
- for (i = 0; i < num_blocks; i++)
- for (arcptr = bb_graph[i].succ; arcptr; arcptr = arcptr->succ_next)
- if (! arcptr->on_tree)
- {
- arcptr->arc_count = profile[profile_pos++];
- arcptr->count_valid = 1;
- bb_graph[i].succ_count--;
- bb_graph[arcptr->target].pred_count--;
- }
- free (profile);
- free (function_name);
-}
+ if (!gcov_open (da_file_name, 1))
+ {
+ fnotice (stderr, "%s:cannot open data file\n", da_file_name);
+ return 1;
+ }
+ if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
+ {
+ fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
+ cleanup:;
+ gcov_close ();
+ return 1;
+ }
+ version = gcov_read_unsigned ();
+ if (version != GCOV_VERSION)
+ {
+ char v[4], e[4];
-static void
-solve_program_flow_graph (bptr)
- struct bb_info_list *bptr;
-{
- int passes, changes;
- gcov_type total;
- int i;
- struct adj_list *arcptr;
- struct bb_info *bb_graph;
- int num_blocks;
-
- num_blocks = bptr->num_blocks;
- bb_graph = bptr->bb_graph;
-
- /* For every block in the file,
- - if every exit/entrance arc has a known count, then set the block count
- - if the block count is known, and every exit/entrance arc but one has
- a known execution count, then set the count of the remaining arc
-
- As arc counts are set, decrement the succ/pred count, but don't delete
- the arc, that way we can easily tell when all arcs are known, or only
- one arc is unknown. */
-
- /* The order that the basic blocks are iterated through is important.
- Since the code that finds spanning trees starts with block 0, low numbered
- arcs are put on the spanning tree in preference to high numbered arcs.
- Hence, most instrumented arcs are at the end. Graph solving works much
- faster if we propagate numbers from the end to the start.
-
- This takes an average of slightly more than 3 passes. */
-
- changes = 1;
- passes = 0;
- while (changes)
+ GCOV_UNSIGNED2STRING (v, version);
+ GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
+
+ fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n",
+ da_file_name, v, e);
+ }
+ tag = gcov_read_unsigned ();
+ if (tag != bbg_stamp)
{
- passes++;
- changes = 0;
+ fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
+ goto cleanup;
+ }
- for (i = num_blocks - 1; i >= 0; i--)
+ while ((tag = gcov_read_unsigned ()))
+ {
+ unsigned length = gcov_read_unsigned ();
+ unsigned long base = gcov_position ();
+
+ if (tag == GCOV_TAG_OBJECT_SUMMARY)
+ gcov_read_summary (&object_summary);
+ else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
+ program_count++;
+ else if (tag == GCOV_TAG_FUNCTION)
{
- if (! bb_graph[i].count_valid)
+ unsigned ident = gcov_read_unsigned ();
+ struct function_info *fn_n = functions;
+
+ for (fn = fn ? fn->next : NULL; ; fn = fn->next)
{
- if (bb_graph[i].succ_count == 0)
- {
- total = 0;
- for (arcptr = bb_graph[i].succ; arcptr;
- arcptr = arcptr->succ_next)
- total += arcptr->arc_count;
- bb_graph[i].exec_count = total;
- bb_graph[i].count_valid = 1;
- changes = 1;
- }
- else if (bb_graph[i].pred_count == 0)
+ if (fn)
+ ;
+ else if ((fn = fn_n))
+ fn_n = NULL;
+ else
{
- total = 0;
- for (arcptr = bb_graph[i].pred; arcptr;
- arcptr = arcptr->pred_next)
- total += arcptr->arc_count;
- bb_graph[i].exec_count = total;
- bb_graph[i].count_valid = 1;
- changes = 1;
+ fnotice (stderr, "%s:unknown function `%u'\n",
+ da_file_name, ident);
+ break;
}
+ if (fn->ident == ident)
+ break;
}
- if (bb_graph[i].count_valid)
+
+ if (!fn)
+ ;
+ else if (gcov_read_unsigned () != fn->checksum)
{
- if (bb_graph[i].succ_count == 1)
- {
- total = 0;
- /* One of the counts will be invalid, but it is zero,
- so adding it in also doesn't hurt. */
- for (arcptr = bb_graph[i].succ; arcptr;
- arcptr = arcptr->succ_next)
- total += arcptr->arc_count;
- /* Calculate count for remaining arc by conservation. */
- total = bb_graph[i].exec_count - total;
- /* Search for the invalid arc, and set its count. */
- for (arcptr = bb_graph[i].succ; arcptr;
- arcptr = arcptr->succ_next)
- if (! arcptr->count_valid)
- break;
- if (! arcptr)
- abort ();
- arcptr->count_valid = 1;
- arcptr->arc_count = total;
- bb_graph[i].succ_count--;
-
- bb_graph[arcptr->target].pred_count--;
- changes = 1;
- }
- if (bb_graph[i].pred_count == 1)
- {
- total = 0;
- /* One of the counts will be invalid, but it is zero,
- so adding it in also doesn't hurt. */
- for (arcptr = bb_graph[i].pred; arcptr;
- arcptr = arcptr->pred_next)
- total += arcptr->arc_count;
- /* Calculate count for remaining arc by conservation. */
- total = bb_graph[i].exec_count - total;
- /* Search for the invalid arc, and set its count. */
- for (arcptr = bb_graph[i].pred; arcptr;
- arcptr = arcptr->pred_next)
- if (! arcptr->count_valid)
- break;
- if (! arcptr)
- abort ();
- arcptr->count_valid = 1;
- arcptr->arc_count = total;
- bb_graph[i].pred_count--;
-
- bb_graph[arcptr->source].succ_count--;
- changes = 1;
- }
+ mismatch:;
+ fnotice (stderr, "%s:profile mismatch for `%s'\n",
+ da_file_name, fn->name);
+ goto cleanup;
}
}
+ else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
+ {
+ if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts))
+ goto mismatch;
+
+ if (!fn->counts)
+ fn->counts = xcalloc (fn->num_counts, sizeof (gcov_type));
+
+ for (ix = 0; ix != fn->num_counts; ix++)
+ fn->counts[ix] += gcov_read_counter ();
+ }
+ gcov_sync (base, length);
+ if ((error = gcov_is_error ()))
+ break;
}
- /* If the graph has been correctly solved, every block will have a
- succ and pred count of zero. */
- for (i = 0; i < num_blocks; i++)
- if (bb_graph[i].succ_count || bb_graph[i].pred_count)
- abort ();
+ if (!gcov_is_eof ())
+ {
+ fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
+ da_file_name);
+ goto cleanup;
+ }
+
+ gcov_close ();
+ return 0;
}
+/* Solve the flow graph. Propagate counts from the instrumented arcs
+ to the blocks and the uninstrumented arcs. */
static void
-read_files ()
+solve_flow_graph (function_t *fn)
{
- struct stat buf;
- struct bb_info_list *list_end = 0;
- struct bb_info_list *b_ptr;
-
- while (! feof (bbg_file))
+ unsigned ix;
+ arc_t *arc;
+ gcov_type *count_ptr = fn->counts;
+ block_t *blk;
+ block_t *valid_blocks = NULL; /* valid, but unpropagated blocks. */
+ block_t *invalid_blocks = NULL; /* invalid, but inferable blocks. */
+
+ if (fn->num_blocks < 2)
+ fnotice (stderr, "%s:`%s' lacks entry and/or exit blocks\n",
+ bbg_file_name, fn->name);
+ else
{
- b_ptr = (struct bb_info_list *) xmalloc (sizeof (struct bb_info_list));
-
- b_ptr->next = 0;
- if (list_end)
- list_end->next = b_ptr;
+ if (fn->blocks[0].num_pred)
+ fnotice (stderr, "%s:`%s' has arcs to entry block\n",
+ bbg_file_name, fn->name);
else
- bb_graph_list = b_ptr;
- list_end = b_ptr;
-
- /* Read in the data in the .bbg file and reconstruct the program flow
- graph for one function. */
- create_program_flow_graph (b_ptr);
+ /* We can't deduce the entry block counts from the lack of
+ predecessors. */
+ fn->blocks[0].num_pred = ~(unsigned)0;
- /* Set the EOF condition if at the end of file. */
- ungetc (getc (bbg_file), bbg_file);
+ if (fn->blocks[fn->num_blocks - 1].num_succ)
+ fnotice (stderr, "%s:`%s' has arcs from exit block\n",
+ bbg_file_name, fn->name);
+ else
+ /* Likewise, we can't deduce exit block counts from the lack
+ of its successors. */
+ fn->blocks[fn->num_blocks - 1].num_succ = ~(unsigned)0;
}
- /* Calculate all of the basic block execution counts and branch
- taken probabilities. */
+ /* Propagate the measured counts, this must be done in the same
+ order as the code in profile.c */
+ for (ix = 0, blk = fn->blocks; ix != fn->num_blocks; ix++, blk++)
+ {
+ block_t const *prev_dst = NULL;
+ int out_of_order = 0;
+ int non_fake_succ = 0;
- for (b_ptr = bb_graph_list; b_ptr; b_ptr = b_ptr->next)
- solve_program_flow_graph (b_ptr);
+ for (arc = blk->succ; arc; arc = arc->succ_next)
+ {
+ if (!arc->fake)
+ non_fake_succ++;
- /* Read in all of the data from the .bb file. This info will be accessed
- sequentially twice. */
- stat (bb_file_name, &buf);
- bb_data_size = buf.st_size / 4;
+ if (!arc->on_tree)
+ {
+ if (count_ptr)
+ arc->count = *count_ptr++;
+ arc->count_valid = 1;
+ blk->num_succ--;
+ arc->dst->num_pred--;
+ }
+ if (prev_dst && prev_dst > arc->dst)
+ out_of_order = 1;
+ prev_dst = arc->dst;
+ }
+ if (non_fake_succ == 1)
+ {
+ /* If there is only one non-fake exit, it is an
+ unconditional branch. */
+ for (arc = blk->succ; arc; arc = arc->succ_next)
+ if (!arc->fake)
+ {
+ arc->is_unconditional = 1;
+ /* If this block is instrumenting a call, it might be
+ an artificial block. It is not artificial if it has
+ a non-fallthrough exit, or the destination of this
+ arc has more than one entry. Mark the destination
+ block as a return site, if none of those conditions
+ hold. */
+ if (blk->is_call_site && arc->fall_through
+ && arc->dst->pred == arc && !arc->pred_next)
+ arc->dst->is_call_return = 1;
+ }
+ }
- bb_data = (char *) xmalloc ((unsigned) buf.st_size);
- fread (bb_data, sizeof (char), buf.st_size, bb_file);
+ /* Sort the successor arcs into ascending dst order. profile.c
+ normally produces arcs in the right order, but sometimes with
+ one or two out of order. We're not using a particularly
+ smart sort. */
+ if (out_of_order)
+ {
+ arc_t *start = blk->succ;
+ unsigned changes = 1;
- fclose (bb_file);
- if (da_file)
- fclose (da_file);
- fclose (bbg_file);
-}
+ while (changes)
+ {
+ arc_t *arc, *arc_p, *arc_n;
+ changes = 0;
+ for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
+ {
+ if (arc->dst > arc_n->dst)
+ {
+ changes = 1;
+ if (arc_p)
+ arc_p->succ_next = arc_n;
+ else
+ start = arc_n;
+ arc->succ_next = arc_n->succ_next;
+ arc_n->succ_next = arc;
+ arc_p = arc_n;
+ }
+ else
+ {
+ arc_p = arc;
+ arc = arc_n;
+ }
+ }
+ }
+ blk->succ = start;
+ }
-/* Scan the data in the .bb file to find all source files referenced,
- and the largest line number mentioned in each one. */
+ /* Place it on the invalid chain, it will be ignored if that's
+ wrong. */
+ blk->invalid_chain = 1;
+ blk->chain = invalid_blocks;
+ invalid_blocks = blk;
+ }
-static void
-scan_for_source_files ()
-{
- struct sourcefile *s_ptr = NULL;
- char *ptr;
- long count;
- long line_num;
-
- /* Search the bb_data to find:
- 1) The number of sources files contained herein, and
- 2) The largest line number for each source file. */
-
- ptr = bb_data;
- sources = 0;
- for (count = 0; count < bb_data_size; count++)
+ while (invalid_blocks || valid_blocks)
{
- __fetch_long (&line_num, ptr, 4);
- ptr += 4;
- if (line_num == -1)
+ while ((blk = invalid_blocks))
+ {
+ gcov_type total = 0;
+ const arc_t *arc;
+
+ invalid_blocks = blk->chain;
+ blk->invalid_chain = 0;
+ if (!blk->num_succ)
+ for (arc = blk->succ; arc; arc = arc->succ_next)
+ total += arc->count;
+ else if (!blk->num_pred)
+ for (arc = blk->pred; arc; arc = arc->pred_next)
+ total += arc->count;
+ else
+ continue;
+
+ blk->count = total;
+ blk->count_valid = 1;
+ blk->chain = valid_blocks;
+ blk->valid_chain = 1;
+ valid_blocks = blk;
+ }
+ while ((blk = valid_blocks))
{
- /* A source file name follows. Check to see if we already have
- a sourcefile structure for this file. */
- s_ptr = sources;
- while (s_ptr && strcmp (s_ptr->name, ptr))
- s_ptr = s_ptr->next;
+ gcov_type total;
+ arc_t *arc, *inv_arc;
- if (s_ptr == 0)
+ valid_blocks = blk->chain;
+ blk->valid_chain = 0;
+ if (blk->num_succ == 1)
{
- /* No sourcefile structure for this file name exists, create
- a new one, and append it to the front of the sources list. */
- s_ptr = (struct sourcefile *) xmalloc (sizeof(struct sourcefile));
- s_ptr->name = xstrdup (ptr);
- s_ptr->maxlineno = 0;
- s_ptr->next = sources;
- sources = s_ptr;
+ block_t *dst;
+
+ total = blk->count;
+ inv_arc = NULL;
+ for (arc = blk->succ; arc; arc = arc->succ_next)
+ {
+ total -= arc->count;
+ if (!arc->count_valid)
+ inv_arc = arc;
+ }
+ dst = inv_arc->dst;
+ inv_arc->count_valid = 1;
+ inv_arc->count = total;
+ blk->num_succ--;
+ dst->num_pred--;
+ if (dst->count_valid)
+ {
+ if (dst->num_pred == 1 && !dst->valid_chain)
+ {
+ dst->chain = valid_blocks;
+ dst->valid_chain = 1;
+ valid_blocks = dst;
+ }
+ }
+ else
+ {
+ if (!dst->num_pred && !dst->invalid_chain)
+ {
+ dst->chain = invalid_blocks;
+ dst->invalid_chain = 1;
+ invalid_blocks = dst;
+ }
+ }
}
+ if (blk->num_pred == 1)
+ {
+ block_t *src;
- /* Scan past the file name. */
- {
- long delim;
- do {
- count++;
- __fetch_long (&delim, ptr, 4);
- ptr += 4;
- } while (delim != line_num);
- }
- }
- else if (line_num == -2)
- {
- long delim;
-
- /* A function name follows. Ignore it. */
- do {
- count++;
- __fetch_long (&delim, ptr, 4);
- ptr += 4;
- } while (delim != line_num);
- }
- /* There will be a zero before the first file name, in which case s_ptr
- will still be uninitialized. So, only try to set the maxlineno
- field if line_num is nonzero. */
- else if (line_num > 0)
- {
- if (s_ptr->maxlineno <= line_num)
- s_ptr->maxlineno = line_num + 1;
- }
- else if (line_num < 0)
- {
- /* Don't know what this is, but it's garbage. */
- abort ();
+ total = blk->count;
+ inv_arc = NULL;
+ for (arc = blk->pred; arc; arc = arc->pred_next)
+ {
+ total -= arc->count;
+ if (!arc->count_valid)
+ inv_arc = arc;
+ }
+ src = inv_arc->src;
+ inv_arc->count_valid = 1;
+ inv_arc->count = total;
+ blk->num_pred--;
+ src->num_succ--;
+ if (src->count_valid)
+ {
+ if (src->num_succ == 1 && !src->valid_chain)
+ {
+ src->chain = valid_blocks;
+ src->valid_chain = 1;
+ valid_blocks = src;
+ }
+ }
+ else
+ {
+ if (!src->num_succ && !src->invalid_chain)
+ {
+ src->chain = invalid_blocks;
+ src->invalid_chain = 1;
+ invalid_blocks = src;
+ }
+ }
+ }
}
}
+
+ /* If the graph has been correctly solved, every block will have a
+ valid count. */
+ for (ix = 0; ix < fn->num_blocks; ix++)
+ if (!fn->blocks[ix].count_valid)
+ {
+ fnotice (stderr, "%s:graph is unsolvable for `%s'\n",
+ bbg_file_name, fn->name);
+ break;
+ }
}
+
-/* Increment totals in FUNCTION according to arc A_PTR. */
+/* Increment totals in COVERAGE according to arc ARC. */
static void
-accumulate_branch_counts (function, a_ptr)
- struct coverage *function;
- struct arcdata *a_ptr;
+add_branch_counts (coverage_t *coverage, const arc_t *arc)
{
- if (a_ptr->call_insn)
- {
- function->calls++;
- if (a_ptr->total)
- function->calls_executed++;
- }
- else
+ if (arc->is_call_non_return)
{
- function->branches++;
- if (a_ptr->total)
- function->branches_executed++;
- if (a_ptr->hits)
- function->branches_taken++;
+ coverage->calls++;
+ if (arc->src->count)
+ coverage->calls_executed++;
}
-}
-
-/* Calculate the branch taken probabilities for all arcs branches at the
- end of this block. */
-
-static void
-calculate_branch_probs (block_ptr, line_info, function)
- struct bb_info *block_ptr;
- struct line_info *line_info;
- struct coverage *function;
-{
- gcov_type total;
- struct adj_list *arcptr;
-
- total = block_ptr->exec_count;
- for (arcptr = block_ptr->succ; arcptr; arcptr = arcptr->succ_next)
+ else if (!arc->is_unconditional)
{
- struct arcdata *a_ptr;
-
- /* Ignore fall through arcs as they aren't really branches. */
- if (arcptr->fall_through)
- continue;
-
- a_ptr = (struct arcdata *) xmalloc (sizeof (struct arcdata));
- a_ptr->total = total;
- a_ptr->hits = total ? arcptr->arc_count : 0;
- a_ptr->call_insn = arcptr->fake;
-
- if (function)
- accumulate_branch_counts (function, a_ptr);
- /* Prepend the new branch to the list. */
- a_ptr->next = line_info->branches;
- line_info->branches = a_ptr;
+ coverage->branches++;
+ if (arc->src->count)
+ coverage->branches_executed++;
+ if (arc->count)
+ coverage->branches_taken++;
}
}
@@ -1134,22 +1340,20 @@ calculate_branch_probs (block_ptr, line_info, function)
format TOP. Return pointer to a static string. */
static char const *
-format_hwint (top, bottom, dp)
- HOST_WIDEST_INT top, bottom;
- int dp;
+format_gcov (gcov_type top, gcov_type bottom, int dp)
{
static char buffer[20];
-
+
if (dp >= 0)
{
float ratio = bottom ? (float)top / bottom : 0;
int ix;
unsigned limit = 100;
unsigned percent;
-
+
for (ix = dp; ix--; )
limit *= 10;
-
+
percent = (unsigned) (ratio * limit + (float)0.5);
if (percent <= 0 && top)
percent = 1;
@@ -1169,8 +1373,8 @@ format_hwint (top, bottom, dp)
}
}
else
- sprintf (buffer, HOST_WIDEST_INT_PRINT_DEC, top);
-
+ sprintf (buffer, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT)top);
+
return buffer;
}
@@ -1178,42 +1382,38 @@ format_hwint (top, bottom, dp)
/* Output summary info for a function. */
static void
-function_summary (function, title)
- struct coverage *function;
- const char *title;
+function_summary (const coverage_t *coverage, const char *title)
{
- if (function->lines)
- fnotice (stdout, "%s of %d lines executed in %s %s\n",
- format_hwint (function->lines_executed,
- function->lines, 2),
- function->lines, title, function->name);
+ fnotice (stdout, "%s `%s'\n", title, coverage->name);
+
+ if (coverage->lines)
+ fnotice (stdout, "Lines executed:%s of %d\n",
+ format_gcov (coverage->lines_executed, coverage->lines, 2),
+ coverage->lines);
else
- fnotice (stdout, "No executable lines in %s %s\n",
- title, function->name);
+ fnotice (stdout, "No executable lines");
- if (output_branch_probs)
+ if (flag_branches)
{
- if (function->branches)
+ if (coverage->branches)
{
- fnotice (stdout, "%s of %d branches executed in %s %s\n",
- format_hwint (function->branches_executed,
- function->branches, 2),
- function->branches, title, function->name);
- fnotice (stdout,
- "%s of %d branches taken at least once in %s %s\n",
- format_hwint (function->branches_taken,
- function->branches, 2),
- function->branches, title, function->name);
+ fnotice (stdout, "Branches executed:%s of %d\n",
+ format_gcov (coverage->branches_executed,
+ coverage->branches, 2),
+ coverage->branches);
+ fnotice (stdout, "Taken at least once:%s of %d\n",
+ format_gcov (coverage->branches_taken,
+ coverage->branches, 2),
+ coverage->branches);
}
else
- fnotice (stdout, "No branches in %s %s\n", title, function->name);
- if (function->calls)
- fnotice (stdout, "%s of %d calls executed in %s %s\n",
- format_hwint (function->calls_executed,
- function->calls, 2),
- function->calls, title, function->name);
+ fnotice (stdout, "No branches\n");
+ if (coverage->calls)
+ fnotice (stdout, "Calls executed:%s of %d\n",
+ format_gcov (coverage->calls_executed, coverage->calls, 2),
+ coverage->calls);
else
- fnotice (stdout, "No calls in %s %s\n", title, function->name);
+ fnotice (stdout, "No calls\n");
}
}
@@ -1228,220 +1428,355 @@ function_summary (function, title)
removed and '..' components are renamed to '^'. */
static char *
-make_gcov_file_name (src_name)
- char *src_name;
+make_gcov_file_name (const char *input_name, const char *src_name)
{
char *cptr;
- char *name = xmalloc (strlen (src_name) + strlen (input_file_name) + 10);
-
+ char *name = xmalloc (strlen (src_name) + strlen (input_name) + 10);
+
name[0] = 0;
- if (output_long_names && strcmp (src_name, input_file_name))
+ if (flag_long_names && strcmp (src_name, input_name))
{
/* Generate the input filename part. */
- cptr = preserve_paths ? NULL : strrchr (input_file_name, '/');
- cptr = cptr ? cptr + 1 : input_file_name;
- strcat (name, cptr);
+ cptr = flag_preserve_paths ? NULL : strrchr (input_name, '/');
+ strcat (name, cptr ? cptr + 1 : input_name);
strcat (name, "##");
}
-
+
/* Generate the source filename part. */
- cptr = preserve_paths ? NULL : strrchr (src_name, '/');
- cptr = cptr ? cptr + 1 : src_name;
- strcat (name, cptr);
-
- if (preserve_paths)
+ cptr = flag_preserve_paths ? NULL : strrchr (src_name, '/');
+ strcat (name, cptr ? cptr + 1 : src_name);
+
+ if (flag_preserve_paths)
{
/* Convert '/' to '#', remove '/./', convert '/../' to '/^/' */
char *prev;
-
+
for (cptr = name; (cptr = strchr ((prev = cptr), '/'));)
- {
- unsigned shift = 0;
-
- if (prev + 1 == cptr && prev[0] == '.')
- {
- /* Remove '.' */
- shift = 2;
- }
- else if (prev + 2 == cptr && prev[0] == '.' && prev[1] == '.')
- {
- /* Convert '..' */
- shift = 1;
- prev[1] = '^';
- }
- else
- *cptr++ = '#';
- if (shift)
- {
- cptr = prev;
- do
- prev[0] = prev[shift];
+ {
+ unsigned shift = 0;
+
+ if (prev + 1 == cptr && prev[0] == '.')
+ {
+ /* Remove '.' */
+ shift = 2;
+ }
+ else if (prev + 2 == cptr && prev[0] == '.' && prev[1] == '.')
+ {
+ /* Convert '..' */
+ shift = 1;
+ prev[1] = '^';
+ }
+ else
+ *cptr++ = '#';
+ if (shift)
+ {
+ cptr = prev;
+ do
+ prev[0] = prev[shift];
while (*prev++);
- }
- }
+ }
+ }
}
-
- /* Don't strip off the ending for compatibility with tcov, since
- this results in confusion if there is more than one file with the
- same basename, e.g. tmp.c and tmp.h. */
+
strcat (name, ".gcov");
return name;
}
-/* Scan through the bb_data, and when the file name matches the
- source file name, then for each following line number, increment
+/* Scan through the bb_data for each line in the block, increment
the line number execution count indicated by the execution count of
the appropriate basic block. */
static void
-init_line_info (line_info, total, maxlineno)
- struct line_info *line_info;
- struct coverage *total;
- long maxlineno;
+add_line_counts (coverage_t *coverage, function_t *fn)
{
- long block_num = 0; /* current block number */
- struct bb_info *block_ptr = NULL; /* current block ptr */
- struct coverage function;
- struct coverage *func_ptr = NULL;
- struct bb_info_list *current_graph = NULL; /* Graph for current function. */
- int is_this_file = 0; /* We're scanning a block from the desired file. */
- char *ptr = bb_data;
- long count;
- long line_num;
- struct line_info *line_ptr = 0; /* line info ptr. */
-
- memset (&function, 0, sizeof (function));
- if (output_function_summary)
- func_ptr = &function;
-
- for (count = 0; count < bb_data_size; count++)
+ unsigned ix;
+ line_t *line = NULL; /* This is propagated from one iteration to the
+ next. */
+
+ /* Scan each basic block. */
+ for (ix = 0; ix != fn->num_blocks; ix++)
{
- __fetch_long (&line_num, ptr, 4);
- ptr += 4;
- if (line_num < 0)
+ block_t *block = &fn->blocks[ix];
+ unsigned *encoding;
+ const source_t *src = NULL;
+ unsigned jx;
+
+ if (block->count && ix && ix + 1 != fn->num_blocks)
+ fn->blocks_executed++;
+ for (jx = 0, encoding = block->u.line.encoding;
+ jx != block->u.line.num; jx++, encoding++)
+ if (!*encoding)
+ {
+ unsigned src_n = *++encoding;
+
+ for (src = sources; src->index != src_n; src = src->next)
+ continue;
+ jx++;
+ }
+ else
+ {
+ line = &src->lines[*encoding];
+
+ if (coverage)
+ {
+ if (!line->exists)
+ coverage->lines++;
+ if (!line->count && block->count)
+ coverage->lines_executed++;
+ }
+ line->exists = 1;
+ line->count += block->count;
+ }
+ free (block->u.line.encoding);
+ block->u.cycle.arc = NULL;
+ block->u.cycle.ident = ~0U;
+
+ if (!ix || ix + 1 == fn->num_blocks)
+ /* Entry or exit block */;
+ else if (flag_all_blocks)
{
- long delim;
-
- if (line_num == -1)
- {
- /* Marks the beginning of a file name. Check to see
- whether this is the filename we are currently
- collecting data for. */
- is_this_file = !strcmp (total->name, ptr);
- }
- else if (line_num == -2)
- {
- /* Marks the start of a new function. Advance to the
- next program flow graph. */
- if (!current_graph)
- current_graph = bb_graph_list;
- else
- {
- if (block_num == current_graph->num_blocks - 1)
- /* Last block falls through to exit. */
- ;
- else if (block_num == current_graph->num_blocks - 2)
- {
- if (output_branch_probs && is_this_file)
- calculate_branch_probs (block_ptr, line_ptr, func_ptr);
- }
- else
- {
- fnotice (stderr,
- "didn't use all bb entries of graph, function %s\n",
- function.name);
- fnotice (stderr, "block_num = %ld, num_blocks = %d\n",
- block_num, current_graph->num_blocks);
- }
- if (func_ptr && is_this_file)
- function_summary (func_ptr, "function");
- current_graph = current_graph->next;
- }
- block_num = 0;
- block_ptr = current_graph->bb_graph;
- memset (&function, 0, sizeof (function));
- function.name = ptr;
- }
- else
- {
- fnotice (stderr, "ERROR: unexpected line number %ld\n", line_num);
- abort ();
- }
+ line_t *block_line = line ? line : &fn->src->lines[fn->line];
- /* Scan past the string. */
- for (delim = 0; delim != line_num; count++)
+ block->chain = block_line->u.blocks;
+ block_line->u.blocks = block;
+ }
+ else if (flag_branches)
+ {
+ arc_t *arc;
+
+ for (arc = block->succ; arc; arc = arc->succ_next)
{
- __fetch_long (&delim, ptr, 4);
- ptr += 4;
+ arc->line_next = line->u.branches;
+ line->u.branches = arc;
+ if (coverage && !arc->is_unconditional)
+ add_branch_counts (coverage, arc);
}
}
- else if (!line_num)
+ }
+ if (!line)
+ fnotice (stderr, "%s:no lines for `%s'\n", bbg_file_name, fn->name);
+}
+
+/* Accumulate the line counts of a file. */
+
+static void
+accumulate_line_counts (source_t *src)
+{
+ line_t *line;
+ function_t *fn, *fn_p, *fn_n;
+ unsigned ix;
+
+ /* Reverse the function order. */
+ for (fn = src->functions, fn_p = NULL; fn;
+ fn_p = fn, fn = fn_n)
+ {
+ fn_n = fn->line_next;
+ fn->line_next = fn_p;
+ }
+ src->functions = fn_p;
+
+ for (ix = src->num_lines, line = src->lines; ix--; line++)
+ {
+ if (!flag_all_blocks)
{
- /* Marks the end of a block. */
- if (block_num >= current_graph->num_blocks)
+ arc_t *arc, *arc_p, *arc_n;
+
+ /* Total and reverse the branch information. */
+ for (arc = line->u.branches, arc_p = NULL; arc;
+ arc_p = arc, arc = arc_n)
{
- fnotice (stderr, "ERROR: too many basic blocks in function %s\n",
- function.name);
- abort ();
+ arc_n = arc->line_next;
+ arc->line_next = arc_p;
+
+ add_branch_counts (&src->coverage, arc);
}
-
- if (output_branch_probs && is_this_file)
- calculate_branch_probs (block_ptr, line_ptr, func_ptr);
-
- block_num++;
- block_ptr++;
+ line->u.branches = arc_p;
}
- else if (is_this_file)
+ else if (line->u.blocks)
{
- if (line_num >= maxlineno)
+ /* The user expects the line count to be the number of times
+ a line has been executed. Simply summing the block count
+ will give an artificially high number. The Right Thing
+ is to sum the entry counts to the graph of blocks on this
+ line, then find the elementary cycles of the local graph
+ and add the transition counts of those cycles. */
+ block_t *block, *block_p, *block_n;
+ gcov_type count = 0;
+
+ /* Reverse the block information. */
+ for (block = line->u.blocks, block_p = NULL; block;
+ block_p = block, block = block_n)
{
- fnotice (stderr, "ERROR: out of range line number in function %s\n",
- function.name);
- abort ();
+ block_n = block->chain;
+ block->chain = block_p;
+ block->u.cycle.ident = ix;
}
+ line->u.blocks = block_p;
- line_ptr = &line_info[line_num];
- if (func_ptr)
+ /* Sum the entry arcs. */
+ for (block = line->u.blocks; block; block = block->chain)
{
- if (!line_ptr->exists)
- func_ptr->lines++;
- if (!line_ptr->count && block_ptr->exec_count)
- func_ptr->lines_executed++;
+ arc_t *arc;
+
+ for (arc = block->pred; arc; arc = arc->pred_next)
+ {
+ if (arc->src->u.cycle.ident != ix)
+ count += arc->count;
+ if (flag_branches)
+ add_branch_counts (&src->coverage, arc);
+ }
+
+ /* Initialize the cs_count. */
+ for (arc = block->succ; arc; arc = arc->succ_next)
+ arc->cs_count = arc->count;
}
-
- /* Accumulate execution data for this line number. */
- line_ptr->count += block_ptr->exec_count;
- line_ptr->exists = 1;
+
+ /* Find the loops. This uses the algorithm described in
+ Tiernan 'An Efficient Search Algorithm to Find the
+ Elementary Circuits of a Graph', CACM Dec 1970. We hold
+ the P array by having each block point to the arc that
+ connects to the previous block. The H array is implicitly
+ held because of the arc ordering, and the block's
+ previous arc pointer.
+
+ Although the algorithm is O(N^3) for highly connected
+ graphs, at worst we'll have O(N^2), as most blocks have
+ only one or two exits. Most graphs will be small.
+
+ For each loop we find, locate the arc with the smallest
+ transition count, and add that to the cumulative
+ count. Decrease flow over the cycle and remove the arc
+ from consideration. */
+ for (block = line->u.blocks; block; block = block->chain)
+ {
+ block_t *head = block;
+ arc_t *arc;
+
+ next_vertex:;
+ arc = head->succ;
+ current_vertex:;
+ while (arc)
+ {
+ block_t *dst = arc->dst;
+ if (/* Already used that arc. */
+ arc->cycle
+ /* Not to same graph, or before first vertex. */
+ || dst->u.cycle.ident != ix
+ /* Already in path. */
+ || dst->u.cycle.arc)
+ {
+ arc = arc->succ_next;
+ continue;
+ }
+
+ if (dst == block)
+ {
+ /* Found a closing arc. */
+ gcov_type cycle_count = arc->cs_count;
+ arc_t *cycle_arc = arc;
+ arc_t *probe_arc;
+
+ /* Locate the smallest arc count of the loop. */
+ for (dst = head; (probe_arc = dst->u.cycle.arc);
+ dst = probe_arc->src)
+ if (cycle_count > probe_arc->cs_count)
+ {
+ cycle_count = probe_arc->cs_count;
+ cycle_arc = probe_arc;
+ }
+
+ count += cycle_count;
+ cycle_arc->cycle = 1;
+
+ /* Remove the flow from the cycle. */
+ arc->cs_count -= cycle_count;
+ for (dst = head; (probe_arc = dst->u.cycle.arc);
+ dst = probe_arc->src)
+ probe_arc->cs_count -= cycle_count;
+
+ /* Unwind to the cyclic arc. */
+ while (head != cycle_arc->src)
+ {
+ arc = head->u.cycle.arc;
+ head->u.cycle.arc = NULL;
+ head = arc->src;
+ }
+ /* Move on. */
+ arc = arc->succ_next;
+ continue;
+ }
+
+ /* Add new block to chain. */
+ dst->u.cycle.arc = arc;
+ head = dst;
+ goto next_vertex;
+ }
+ /* We could not add another vertex to the path. Remove
+ the last vertex from the list. */
+ arc = head->u.cycle.arc;
+ if (arc)
+ {
+ /* It was not the first vertex. Move onto next arc. */
+ head->u.cycle.arc = NULL;
+ head = arc->src;
+ arc = arc->succ_next;
+ goto current_vertex;
+ }
+ /* Mark this block as unusable. */
+ block->u.cycle.ident = ~0U;
+ }
+
+ line->count = count;
}
- }
-
- if (func_ptr && is_this_file)
- function_summary (func_ptr, "function");
-
- /* Calculate summary test coverage statistics. */
- for (line_num = 1, line_ptr = &line_info[line_num];
- line_num < maxlineno; line_num++, line_ptr++)
- {
- struct arcdata *a_ptr, *prev, *next;
-
- if (line_ptr->exists)
+
+ if (line->exists)
{
- total->lines++;
- if (line_ptr->count)
- total->lines_executed++;
+ src->coverage.lines++;
+ if (line->count)
+ src->coverage.lines_executed++;
}
+ }
+}
- /* Total and reverse the branch information. */
- for (a_ptr = line_ptr->branches, prev = NULL; a_ptr; a_ptr = next)
- {
- next = a_ptr->next;
- a_ptr->next = prev;
- prev = a_ptr;
+/* Ouput information about ARC number IX. Returns nonzero if
+ anything is output. */
- accumulate_branch_counts (total, a_ptr);
+static int
+output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
+{
+
+ if (arc->is_call_non_return)
+ {
+ if (arc->src->count)
+ {
+ fnotice (gcov_file, "call %2d returned %s\n", ix,
+ format_gcov (arc->src->count - arc->count,
+ arc->src->count, -flag_counts));
}
- line_ptr->branches = prev;
+ else
+ fnotice (gcov_file, "call %2d never executed\n", ix);
}
+ else if (!arc->is_unconditional)
+ {
+ if (arc->src->count)
+ fnotice (gcov_file, "branch %2d taken %s%s\n", ix,
+ format_gcov (arc->count, arc->src->count, -flag_counts),
+ arc->fall_through ? " (fallthrough)" : "");
+ else
+ fnotice (gcov_file, "branch %2d never executed\n", ix);
+ }
+ else if (flag_unconditional && !arc->dst->is_call_return)
+ {
+ if (arc->src->count)
+ fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
+ format_gcov (arc->count, arc->src->count, -flag_counts));
+ else
+ fnotice (gcov_file, "unconditional %2d never executed\n", ix);
+ }
+ else
+ return 0;
+ return 1;
+
}
/* Read in the source file one line at a time, and output that line to
@@ -1449,55 +1784,74 @@ init_line_info (line_info, total, maxlineno)
information. */
static void
-output_line_info (gcov_file, line_info, total, maxlineno)
- FILE *gcov_file;
- const struct line_info *line_info;
- const struct coverage *total;
- long maxlineno;
+output_lines (FILE *gcov_file, const source_t *src)
{
FILE *source_file;
- long line_num; /* current line number */
- const struct line_info *line_ptr; /* current line info ptr. */
- char string[STRING_SIZE]; /* line buffer. */
- char const *retval = ""; /* status of source file reading. */
-
- fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, total->name);
- fprintf (gcov_file, "%9s:%5d:Object:%s\n", "-", 0, bb_file_name);
-
- source_file = fopen (total->name, "r");
+ unsigned line_num; /* current line number. */
+ const line_t *line; /* current line info ptr. */
+ char string[STRING_SIZE]; /* line buffer. */
+ char const *retval = ""; /* status of source file reading. */
+ function_t *fn = src->functions;
+
+ fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->name);
+ fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
+ fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0, da_file_name);
+ fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0,
+ object_summary.ctrs[GCOV_COUNTER_ARCS].runs);
+ fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
+
+ source_file = fopen (src->name, "r");
if (!source_file)
{
- fnotice (stderr, "Could not open source file %s.\n", total->name);
+ fnotice (stderr, "%s:cannot open source file\n", src->name);
retval = NULL;
}
else
{
struct stat status;
-
+
if (!fstat (fileno (source_file), &status)
- && status.st_mtime > bb_file_time)
+ && status.st_mtime > bbg_file_time)
{
- fnotice (stderr, "Warning: source file %s is newer than %s\n",
- total->name, bb_file_name);
- fprintf (gcov_file, "%9s:%5d:Source is newer than compiler output\n",
+ fnotice (stderr, "%s:source file is newer than graph file `%s'\n",
+ src->name, bbg_file_name);
+ fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n",
"-", 0);
}
}
- for (line_num = 1, line_ptr = &line_info[line_num];
- line_num < maxlineno; line_num++, line_ptr++)
+ for (line_num = 1, line = &src->lines[line_num];
+ line_num < src->num_lines; line_num++, line++)
{
+ for (; fn && fn->line == line_num; fn = fn->line_next)
+ {
+ arc_t *arc = fn->blocks[fn->num_blocks - 1].pred;
+ gcov_type return_count = fn->blocks[fn->num_blocks - 1].count;
+
+ for (; arc; arc = arc->pred_next)
+ if (arc->fake)
+ return_count -= arc->count;
+
+ fprintf (gcov_file, "function %s", fn->name);
+ fprintf (gcov_file, " called %s",
+ format_gcov (fn->blocks[0].count, 0, -1));
+ fprintf (gcov_file, " returned %s",
+ format_gcov (return_count, fn->blocks[0].count, 0));
+ fprintf (gcov_file, " blocks executed %s",
+ format_gcov (fn->blocks_executed, fn->num_blocks - 2, 0));
+ fprintf (gcov_file, "\n");
+ }
+
/* For lines which don't exist in the .bb file, print '-' before
- the source line. For lines which exist but were never
- executed, print '#####' before the source line. Otherwise,
- print the execution count before the source line. There are
- 16 spaces of indentation added before the source line so that
- tabs won't be messed up. */
- fprintf (gcov_file, "%9s:%5ld:",
- !line_ptr->exists ? "-"
- : !line_ptr->count ? "#####"
- : format_hwint (line_ptr->count, 0, -1), line_num);
-
+ the source line. For lines which exist but were never
+ executed, print '#####' before the source line. Otherwise,
+ print the execution count before the source line. There are
+ 16 spaces of indentation added before the source line so that
+ tabs won't be messed up. */
+ fprintf (gcov_file, "%9s:%5u:",
+ !line->exists ? "-" : !line->count ? "#####"
+ : format_gcov (line->count, 0, -1), line_num);
+
if (retval)
{
/* Copy source line. */
@@ -1505,60 +1859,51 @@ output_line_info (gcov_file, line_info, total, maxlineno)
{
retval = fgets (string, STRING_SIZE, source_file);
if (!retval)
- {
- fnotice (stderr,
- "Unexpected EOF while reading source file %s.\n",
- total->name);
- break;
- }
+ break;
fputs (retval, gcov_file);
}
while (!retval[0] || retval[strlen (retval) - 1] != '\n');
}
if (!retval)
- fputs ("??\n", gcov_file);
-
- if (output_branch_probs)
+ fputs ("/*EOF*/\n", gcov_file);
+
+ if (flag_all_blocks)
{
- int i;
- struct arcdata *a_ptr;
-
- for (i = 0, a_ptr = line_ptr->branches; a_ptr;
- a_ptr = a_ptr->next, i++)
+ block_t *block;
+ arc_t *arc;
+ int ix, jx;
+
+ for (ix = jx = 0, block = line->u.blocks; block;
+ block = block->chain)
{
- if (a_ptr->call_insn)
- {
- if (a_ptr->total == 0)
- fnotice (gcov_file, "call %2d never executed\n", i);
- else
- fnotice
- (gcov_file, "call %2d returns %s\n", i,
- format_hwint (a_ptr->total - a_ptr->hits,
- a_ptr->total,
- -output_branch_counts));
- }
- else
- {
- if (a_ptr->total == 0)
- fnotice (gcov_file, "branch %2d never executed\n", i);
- else
- fnotice
- (gcov_file, "branch %2d taken %s\n", i,
- format_hwint (a_ptr->hits, a_ptr->total,
- -output_branch_counts));
- }
+ if (!block->is_call_return)
+ fprintf (gcov_file, "%9s:%5u-block %2d\n",
+ !line->exists ? "-" : !block->count ? "$$$$$"
+ : format_gcov (block->count, 0, -1),
+ line_num, ix++);
+ if (flag_branches)
+ for (arc = block->succ; arc; arc = arc->succ_next)
+ jx += output_branch_count (gcov_file, jx, arc);
}
}
+ else if (flag_branches)
+ {
+ int ix;
+ arc_t *arc;
+
+ for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
+ ix += output_branch_count (gcov_file, ix, arc);
+ }
}
-
+
/* Handle all remaining source lines. There may be lines after the
last line of code. */
if (retval)
{
for (; (retval = fgets (string, STRING_SIZE, source_file)); line_num++)
{
- fprintf (gcov_file, "%9s:%5ld:%s", "-", line_num, retval);
-
+ fprintf (gcov_file, "%9s:%5u:%s", "-", line_num, retval);
+
while (!retval[0] || retval[strlen (retval) - 1] != '\n')
{
retval = fgets (string, STRING_SIZE, source_file);
@@ -1568,67 +1913,7 @@ output_line_info (gcov_file, line_info, total, maxlineno)
}
}
}
-
+
if (source_file)
fclose (source_file);
}
-
-/* Calculate line execution counts, and output a .gcov file for source
- file S_PTR. Allocate an array big enough to hold a count for each
- line. Scan through the bb_data, and when the file name matches the
- current file name, then for each following line number, increment
- the line number execution count indicated by the execution count of
- the appropriate basic block. */
-
-static void
-output_data (s_ptr)
- struct sourcefile *s_ptr;
-{
- struct line_info *line_info /* line info data */
- = (struct line_info *) xcalloc (s_ptr->maxlineno,
- sizeof (struct line_info));
- long line_num;
- struct coverage total;
-
- memset (&total, 0, sizeof (total));
- total.name = s_ptr->name;
-
- init_line_info (line_info, &total, s_ptr->maxlineno);
- function_summary (&total, "file");
-
- if (output_gcov_file)
- {
- /* Now the statistics are ready. Read in the source file one
- line at a time, and output that line to the gcov file
- preceded by its execution information. */
-
- char *gcov_file_name = make_gcov_file_name (total.name);
- FILE *gcov_file = fopen (gcov_file_name, "w");
-
- if (gcov_file)
- {
- fnotice (stdout, "Creating %s.\n", gcov_file_name);
- output_line_info (gcov_file, line_info, &total, s_ptr->maxlineno);
- if (ferror (gcov_file))
- fnotice (stderr, "Error writing output file %s.\n",
- gcov_file_name);
- fclose (gcov_file);
- }
- else
- fnotice (stderr, "Could not open output file %s.\n", gcov_file_name);
- free (gcov_file_name);
- }
-
- /* Free data. */
- for (line_num = 1; line_num != s_ptr->maxlineno; line_num++)
- {
- struct arcdata *branch, *next;
-
- for (branch = line_info[line_num].branches; branch; branch = next)
- {
- next = branch->next;
- free (branch);
- }
- }
- free (line_info);
-}
diff --git a/contrib/gcc/gcse.c b/contrib/gcc/gcse.c
index 241357e9760c..c87673882d5e 100644
--- a/contrib/gcc/gcse.c
+++ b/contrib/gcc/gcse.c
@@ -1,6 +1,6 @@
/* Global common subexpression elimination/Partial redundancy elimination
and global constant/copy propagation for GNU compiler.
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@@ -145,9 +145,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
+#include "tree.h"
#include "tm_p.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -163,7 +166,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "params.h"
#include "cselib.h"
-
+#include "intl.h"
#include "obstack.h"
/* Propagate flow information through back edges and thus enable PRE's
@@ -297,14 +300,6 @@ static FILE *debug_stderr;
/* An obstack for our working variables. */
static struct obstack gcse_obstack;
-/* Nonzero for each mode that supports (set (reg) (reg)).
- This is trivially true for integer and floating point values.
- It may or may not be true for condition codes. */
-static char can_copy_p[(int) NUM_MACHINE_MODES];
-
-/* Nonzero if can_copy_p has been initialized. */
-static int can_copy_init_p;
-
struct reg_use {rtx reg_rtx; };
/* Hash table of expressions. */
@@ -468,15 +463,19 @@ struct ls_expr
{
struct expr * expr; /* Gcse expression reference for LM. */
rtx pattern; /* Pattern of this mem. */
+ rtx pattern_regs; /* List of registers mentioned by the mem. */
rtx loads; /* INSN list of loads seen. */
rtx stores; /* INSN list of stores seen. */
struct ls_expr * next; /* Next in the list. */
int invalid; /* Invalid for some reason. */
int index; /* If it maps to a bitmap index. */
- int hash_index; /* Index when in a hash table. */
+ unsigned int hash_index; /* Index when in a hash table. */
rtx reaching_reg; /* Register to use when re-writing. */
};
+/* Array of implicit set patterns indexed by basic block index. */
+static rtx *implicit_sets;
+
/* Head of the list of load/store memory refs. */
static struct ls_expr * pre_ldst_mems = NULL;
@@ -550,168 +549,172 @@ struct null_pointer_info
sbitmap *nonnull_killed;
};
-static void compute_can_copy PARAMS ((void));
-static char *gmalloc PARAMS ((unsigned int));
-static char *grealloc PARAMS ((char *, unsigned int));
-static char *gcse_alloc PARAMS ((unsigned long));
-static void alloc_gcse_mem PARAMS ((rtx));
-static void free_gcse_mem PARAMS ((void));
-static void alloc_reg_set_mem PARAMS ((int));
-static void free_reg_set_mem PARAMS ((void));
-static int get_bitmap_width PARAMS ((int, int, int));
-static void record_one_set PARAMS ((int, rtx));
-static void record_set_info PARAMS ((rtx, rtx, void *));
-static void compute_sets PARAMS ((rtx));
-static void hash_scan_insn PARAMS ((rtx, struct hash_table *, int));
-static void hash_scan_set PARAMS ((rtx, rtx, struct hash_table *));
-static void hash_scan_clobber PARAMS ((rtx, rtx, struct hash_table *));
-static void hash_scan_call PARAMS ((rtx, rtx, struct hash_table *));
-static int want_to_gcse_p PARAMS ((rtx));
-static int oprs_unchanged_p PARAMS ((rtx, rtx, int));
-static int oprs_anticipatable_p PARAMS ((rtx, rtx));
-static int oprs_available_p PARAMS ((rtx, rtx));
-static void insert_expr_in_table PARAMS ((rtx, enum machine_mode, rtx,
- int, int, struct hash_table *));
-static void insert_set_in_table PARAMS ((rtx, rtx, struct hash_table *));
-static unsigned int hash_expr PARAMS ((rtx, enum machine_mode, int *, int));
-static unsigned int hash_expr_1 PARAMS ((rtx, enum machine_mode, int *));
-static unsigned int hash_string_1 PARAMS ((const char *));
-static unsigned int hash_set PARAMS ((int, int));
-static int expr_equiv_p PARAMS ((rtx, rtx));
-static void record_last_reg_set_info PARAMS ((rtx, int));
-static void record_last_mem_set_info PARAMS ((rtx));
-static void record_last_set_info PARAMS ((rtx, rtx, void *));
-static void compute_hash_table PARAMS ((struct hash_table *));
-static void alloc_hash_table PARAMS ((int, struct hash_table *, int));
-static void free_hash_table PARAMS ((struct hash_table *));
-static void compute_hash_table_work PARAMS ((struct hash_table *));
-static void dump_hash_table PARAMS ((FILE *, const char *,
- struct hash_table *));
-static struct expr *lookup_expr PARAMS ((rtx, struct hash_table *));
-static struct expr *lookup_set PARAMS ((unsigned int, rtx, struct hash_table *));
-static struct expr *next_set PARAMS ((unsigned int, struct expr *));
-static void reset_opr_set_tables PARAMS ((void));
-static int oprs_not_set_p PARAMS ((rtx, rtx));
-static void mark_call PARAMS ((rtx));
-static void mark_set PARAMS ((rtx, rtx));
-static void mark_clobber PARAMS ((rtx, rtx));
-static void mark_oprs_set PARAMS ((rtx));
-static void alloc_cprop_mem PARAMS ((int, int));
-static void free_cprop_mem PARAMS ((void));
-static void compute_transp PARAMS ((rtx, int, sbitmap *, int));
-static void compute_transpout PARAMS ((void));
-static void compute_local_properties PARAMS ((sbitmap *, sbitmap *, sbitmap *,
- struct hash_table *));
-static void compute_cprop_data PARAMS ((void));
-static void find_used_regs PARAMS ((rtx *, void *));
-static int try_replace_reg PARAMS ((rtx, rtx, rtx));
-static struct expr *find_avail_set PARAMS ((int, rtx));
-static int cprop_jump PARAMS ((basic_block, rtx, rtx, rtx, rtx));
-static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *));
-static int load_killed_in_block_p PARAMS ((basic_block, int, rtx, int));
-static void canon_list_insert PARAMS ((rtx, rtx, void *));
-static int cprop_insn PARAMS ((rtx, int));
-static int cprop PARAMS ((int));
-static int one_cprop_pass PARAMS ((int, int));
-static bool constprop_register PARAMS ((rtx, rtx, rtx, int));
-static struct expr *find_bypass_set PARAMS ((int, int));
-static bool reg_killed_on_edge PARAMS ((rtx, edge));
-static int bypass_block PARAMS ((basic_block, rtx, rtx));
-static int bypass_conditional_jumps PARAMS ((void));
-static void alloc_pre_mem PARAMS ((int, int));
-static void free_pre_mem PARAMS ((void));
-static void compute_pre_data PARAMS ((void));
-static int pre_expr_reaches_here_p PARAMS ((basic_block, struct expr *,
- basic_block));
-static void insert_insn_end_bb PARAMS ((struct expr *, basic_block, int));
-static void pre_insert_copy_insn PARAMS ((struct expr *, rtx));
-static void pre_insert_copies PARAMS ((void));
-static int pre_delete PARAMS ((void));
-static int pre_gcse PARAMS ((void));
-static int one_pre_gcse_pass PARAMS ((int));
-static void add_label_notes PARAMS ((rtx, rtx));
-static void alloc_code_hoist_mem PARAMS ((int, int));
-static void free_code_hoist_mem PARAMS ((void));
-static void compute_code_hoist_vbeinout PARAMS ((void));
-static void compute_code_hoist_data PARAMS ((void));
-static int hoist_expr_reaches_here_p PARAMS ((basic_block, int, basic_block,
- char *));
-static void hoist_code PARAMS ((void));
-static int one_code_hoisting_pass PARAMS ((void));
-static void alloc_rd_mem PARAMS ((int, int));
-static void free_rd_mem PARAMS ((void));
-static void handle_rd_kill_set PARAMS ((rtx, int, basic_block));
-static void compute_kill_rd PARAMS ((void));
-static void compute_rd PARAMS ((void));
-static void alloc_avail_expr_mem PARAMS ((int, int));
-static void free_avail_expr_mem PARAMS ((void));
-static void compute_ae_gen PARAMS ((struct hash_table *));
-static int expr_killed_p PARAMS ((rtx, basic_block));
-static void compute_ae_kill PARAMS ((sbitmap *, sbitmap *, struct hash_table *));
-static int expr_reaches_here_p PARAMS ((struct occr *, struct expr *,
- basic_block, int));
-static rtx computing_insn PARAMS ((struct expr *, rtx));
-static int def_reaches_here_p PARAMS ((rtx, rtx));
-static int can_disregard_other_sets PARAMS ((struct reg_set **, rtx, int));
-static int handle_avail_expr PARAMS ((rtx, struct expr *));
-static int classic_gcse PARAMS ((void));
-static int one_classic_gcse_pass PARAMS ((int));
-static void invalidate_nonnull_info PARAMS ((rtx, rtx, void *));
-static int delete_null_pointer_checks_1 PARAMS ((unsigned int *,
- sbitmap *, sbitmap *,
- struct null_pointer_info *));
-static rtx process_insert_insn PARAMS ((struct expr *));
-static int pre_edge_insert PARAMS ((struct edge_list *, struct expr **));
-static int expr_reaches_here_p_work PARAMS ((struct occr *, struct expr *,
- basic_block, int, char *));
-static int pre_expr_reaches_here_p_work PARAMS ((basic_block, struct expr *,
- basic_block, char *));
-static struct ls_expr * ldst_entry PARAMS ((rtx));
-static void free_ldst_entry PARAMS ((struct ls_expr *));
-static void free_ldst_mems PARAMS ((void));
-static void print_ldst_list PARAMS ((FILE *));
-static struct ls_expr * find_rtx_in_ldst PARAMS ((rtx));
-static int enumerate_ldsts PARAMS ((void));
-static inline struct ls_expr * first_ls_expr PARAMS ((void));
-static inline struct ls_expr * next_ls_expr PARAMS ((struct ls_expr *));
-static int simple_mem PARAMS ((rtx));
-static void invalidate_any_buried_refs PARAMS ((rtx));
-static void compute_ld_motion_mems PARAMS ((void));
-static void trim_ld_motion_mems PARAMS ((void));
-static void update_ld_motion_stores PARAMS ((struct expr *));
-static void reg_set_info PARAMS ((rtx, rtx, void *));
-static int store_ops_ok PARAMS ((rtx, basic_block));
-static void find_moveable_store PARAMS ((rtx));
-static int compute_store_table PARAMS ((void));
-static int load_kills_store PARAMS ((rtx, rtx));
-static int find_loads PARAMS ((rtx, rtx));
-static int store_killed_in_insn PARAMS ((rtx, rtx));
-static int store_killed_after PARAMS ((rtx, rtx, basic_block));
-static int store_killed_before PARAMS ((rtx, rtx, basic_block));
-static void build_store_vectors PARAMS ((void));
-static void insert_insn_start_bb PARAMS ((rtx, basic_block));
-static int insert_store PARAMS ((struct ls_expr *, edge));
-static void replace_store_insn PARAMS ((rtx, rtx, basic_block));
-static void delete_store PARAMS ((struct ls_expr *,
- basic_block));
-static void free_store_memory PARAMS ((void));
-static void store_motion PARAMS ((void));
-static void free_insn_expr_list_list PARAMS ((rtx *));
-static void clear_modify_mem_tables PARAMS ((void));
-static void free_modify_mem_tables PARAMS ((void));
-static rtx gcse_emit_move_after PARAMS ((rtx, rtx, rtx));
-static void local_cprop_find_used_regs PARAMS ((rtx *, void *));
-static bool do_local_cprop PARAMS ((rtx, rtx, int, rtx*));
-static bool adjust_libcall_notes PARAMS ((rtx, rtx, rtx, rtx*));
-static void local_cprop_pass PARAMS ((int));
+static void compute_can_copy (void);
+static void *gmalloc (size_t) ATTRIBUTE_MALLOC;
+static void *gcalloc (size_t, size_t) ATTRIBUTE_MALLOC;
+static void *grealloc (void *, size_t);
+static void *gcse_alloc (unsigned long);
+static void alloc_gcse_mem (rtx);
+static void free_gcse_mem (void);
+static void alloc_reg_set_mem (int);
+static void free_reg_set_mem (void);
+static int get_bitmap_width (int, int, int);
+static void record_one_set (int, rtx);
+static void replace_one_set (int, rtx, rtx);
+static void record_set_info (rtx, rtx, void *);
+static void compute_sets (rtx);
+static void hash_scan_insn (rtx, struct hash_table *, int);
+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 int want_to_gcse_p (rtx);
+static bool gcse_constant_p (rtx);
+static int oprs_unchanged_p (rtx, rtx, int);
+static int oprs_anticipatable_p (rtx, rtx);
+static int oprs_available_p (rtx, 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 *);
+static unsigned int hash_expr (rtx, enum machine_mode, int *, int);
+static unsigned int hash_expr_1 (rtx, enum machine_mode, int *);
+static unsigned int hash_string_1 (const char *);
+static unsigned int hash_set (int, int);
+static int expr_equiv_p (rtx, 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, rtx, void *);
+static void compute_hash_table (struct hash_table *);
+static void alloc_hash_table (int, 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_expr (rtx, struct hash_table *);
+static struct expr *lookup_set (unsigned int, struct hash_table *);
+static struct expr *next_set (unsigned int, struct expr *);
+static void reset_opr_set_tables (void);
+static int oprs_not_set_p (rtx, rtx);
+static void mark_call (rtx);
+static void mark_set (rtx, rtx);
+static void mark_clobber (rtx, rtx);
+static void mark_oprs_set (rtx);
+static void alloc_cprop_mem (int, int);
+static void free_cprop_mem (void);
+static void compute_transp (rtx, int, sbitmap *, int);
+static void compute_transpout (void);
+static void compute_local_properties (sbitmap *, sbitmap *, sbitmap *,
+ struct hash_table *);
+static void compute_cprop_data (void);
+static void find_used_regs (rtx *, void *);
+static int try_replace_reg (rtx, rtx, rtx);
+static struct expr *find_avail_set (int, rtx);
+static int cprop_jump (basic_block, rtx, rtx, rtx, rtx);
+static void mems_conflict_for_gcse_p (rtx, rtx, void *);
+static int load_killed_in_block_p (basic_block, int, rtx, int);
+static void canon_list_insert (rtx, rtx, void *);
+static int cprop_insn (rtx, int);
+static int cprop (int);
+static void find_implicit_sets (void);
+static int one_cprop_pass (int, int, int);
+static bool constprop_register (rtx, rtx, rtx, int);
+static struct expr *find_bypass_set (int, int);
+static bool reg_killed_on_edge (rtx, edge);
+static int bypass_block (basic_block, rtx, rtx);
+static int bypass_conditional_jumps (void);
+static void alloc_pre_mem (int, int);
+static void free_pre_mem (void);
+static void compute_pre_data (void);
+static int pre_expr_reaches_here_p (basic_block, struct expr *,
+ basic_block);
+static void insert_insn_end_bb (struct expr *, basic_block, int);
+static void pre_insert_copy_insn (struct expr *, rtx);
+static void pre_insert_copies (void);
+static int pre_delete (void);
+static int pre_gcse (void);
+static int one_pre_gcse_pass (int);
+static void add_label_notes (rtx, rtx);
+static void alloc_code_hoist_mem (int, int);
+static void free_code_hoist_mem (void);
+static void compute_code_hoist_vbeinout (void);
+static void compute_code_hoist_data (void);
+static int hoist_expr_reaches_here_p (basic_block, int, basic_block, char *);
+static void hoist_code (void);
+static int one_code_hoisting_pass (void);
+static void alloc_rd_mem (int, int);
+static void free_rd_mem (void);
+static void handle_rd_kill_set (rtx, int, basic_block);
+static void compute_kill_rd (void);
+static void compute_rd (void);
+static void alloc_avail_expr_mem (int, int);
+static void free_avail_expr_mem (void);
+static void compute_ae_gen (struct hash_table *);
+static int expr_killed_p (rtx, basic_block);
+static void compute_ae_kill (sbitmap *, sbitmap *, struct hash_table *);
+static int expr_reaches_here_p (struct occr *, struct expr *, basic_block,
+ int);
+static rtx computing_insn (struct expr *, rtx);
+static int def_reaches_here_p (rtx, rtx);
+static int can_disregard_other_sets (struct reg_set **, rtx, int);
+static int handle_avail_expr (rtx, struct expr *);
+static int classic_gcse (void);
+static int one_classic_gcse_pass (int);
+static void invalidate_nonnull_info (rtx, rtx, void *);
+static int delete_null_pointer_checks_1 (unsigned int *, sbitmap *, sbitmap *,
+ struct null_pointer_info *);
+static rtx process_insert_insn (struct expr *);
+static int pre_edge_insert (struct edge_list *, struct expr **);
+static int expr_reaches_here_p_work (struct occr *, struct expr *,
+ basic_block, int, char *);
+static int pre_expr_reaches_here_p_work (basic_block, struct expr *,
+ basic_block, char *);
+static struct ls_expr * ldst_entry (rtx);
+static void free_ldst_entry (struct ls_expr *);
+static void free_ldst_mems (void);
+static void print_ldst_list (FILE *);
+static struct ls_expr * find_rtx_in_ldst (rtx);
+static int enumerate_ldsts (void);
+static inline struct ls_expr * first_ls_expr (void);
+static inline struct ls_expr * next_ls_expr (struct ls_expr *);
+static int simple_mem (rtx);
+static void invalidate_any_buried_refs (rtx);
+static void compute_ld_motion_mems (void);
+static void trim_ld_motion_mems (void);
+static void update_ld_motion_stores (struct expr *);
+static void reg_set_info (rtx, rtx, void *);
+static void reg_clear_last_set (rtx, rtx, void *);
+static bool store_ops_ok (rtx, int *);
+static rtx extract_mentioned_regs (rtx);
+static rtx extract_mentioned_regs_helper (rtx, rtx);
+static void find_moveable_store (rtx, int *, int *);
+static int compute_store_table (void);
+static bool load_kills_store (rtx, rtx, int);
+static bool find_loads (rtx, rtx, int);
+static bool store_killed_in_insn (rtx, rtx, rtx, int);
+static bool store_killed_after (rtx, rtx, rtx, basic_block, int *, rtx *);
+static bool store_killed_before (rtx, rtx, rtx, basic_block, int *);
+static void build_store_vectors (void);
+static void insert_insn_start_bb (rtx, basic_block);
+static int insert_store (struct ls_expr *, edge);
+static void remove_reachable_equiv_notes (basic_block, struct ls_expr *);
+static void replace_store_insn (rtx, rtx, basic_block, struct ls_expr *);
+static void delete_store (struct ls_expr *, basic_block);
+static void free_store_memory (void);
+static void store_motion (void);
+static void free_insn_expr_list_list (rtx *);
+static void clear_modify_mem_tables (void);
+static void free_modify_mem_tables (void);
+static rtx gcse_emit_move_after (rtx, rtx, rtx);
+static void local_cprop_find_used_regs (rtx *, void *);
+static bool do_local_cprop (rtx, rtx, int, rtx*);
+static bool adjust_libcall_notes (rtx, rtx, rtx, rtx*);
+static void local_cprop_pass (int);
+static bool is_too_expensive (const char *);
+
/* Entry point for global common subexpression elimination.
F is the first instruction in the function. */
int
-gcse_main (f, file)
- rtx f;
- FILE *file;
+gcse_main (rtx f, FILE *file)
{
int changed, pass;
/* Bytes used at start of pass. */
@@ -721,10 +724,6 @@ gcse_main (f, file)
/* Point to release obstack data from for each pass. */
char *gcse_obstack_bottom;
- /* Insertion of instructions on edges can create new basic blocks; we
- need the original basic block count so that we can properly deallocate
- arrays sized on the number of basic blocks originally in the cfg. */
- int orig_bb_count;
/* We do not construct an accurate cfg in functions which call
setjmp, so just punt to be safe. */
if (current_function_calls_setjmp)
@@ -744,47 +743,10 @@ gcse_main (f, file)
if (file)
dump_flow_info (file);
- orig_bb_count = n_basic_blocks;
- /* Return if there's nothing to do. */
- if (n_basic_blocks <= 1)
+ /* Return if there's nothing to do, or it is too expensive. */
+ if (n_basic_blocks <= 1 || is_too_expensive (_("GCSE disabled")))
return 0;
-
- /* Trying to perform global optimizations on flow graphs which have
- a high connectivity will take a long time and is unlikely to be
- particularly useful.
-
- In normal circumstances a cfg should have about twice as many edges
- as blocks. But we do not want to punish small functions which have
- a couple switch statements. So we require a relatively large number
- of basic blocks and the ratio of edges to blocks to be high. */
- if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
- {
- if (warn_disabled_optimization)
- warning ("GCSE disabled: %d > 1000 basic blocks and %d >= 20 edges/basic block",
- n_basic_blocks, n_edges / n_basic_blocks);
- return 0;
- }
-
- /* If allocating memory for the cprop bitmap would take up too much
- storage it's better just to disable the optimization. */
- if ((n_basic_blocks
- * SBITMAP_SET_SIZE (max_gcse_regno)
- * sizeof (SBITMAP_ELT_TYPE)) > MAX_GCSE_MEMORY)
- {
- if (warn_disabled_optimization)
- warning ("GCSE disabled: %d basic blocks and %d registers",
- n_basic_blocks, max_gcse_regno);
-
- return 0;
- }
-
- /* See what modes support reg/reg copy operations. */
- if (! can_copy_init_p)
- {
- compute_can_copy ();
- can_copy_init_p = 1;
- }
-
+
gcc_obstack_init (&gcse_obstack);
bytes_used = 0;
@@ -824,7 +786,7 @@ gcse_main (f, file)
/* Don't allow constant propagation to modify jumps
during this pass. */
- changed = one_cprop_pass (pass + 1, 0);
+ changed = one_cprop_pass (pass + 1, 0, 0);
if (optimize_size)
changed |= one_classic_gcse_pass (pass + 1);
@@ -837,13 +799,8 @@ gcse_main (f, file)
if (changed)
{
free_modify_mem_tables ();
- modify_mem_list
- = (rtx *) gmalloc (last_basic_block * sizeof (rtx));
- canon_modify_mem_list
- = (rtx *) gmalloc (last_basic_block * sizeof (rtx));
- memset ((char *) modify_mem_list, 0, last_basic_block * sizeof (rtx));
- memset ((char *) canon_modify_mem_list, 0, last_basic_block * sizeof (rtx));
- orig_bb_count = n_basic_blocks;
+ modify_mem_list = gcalloc (last_basic_block, sizeof (rtx));
+ canon_modify_mem_list = gcalloc (last_basic_block, sizeof (rtx));
}
free_reg_set_mem ();
alloc_reg_set_mem (max_reg_num ());
@@ -860,7 +817,7 @@ gcse_main (f, file)
partial redundancy elimination. */
free_gcse_mem ();
- /* It does not make sense to run code hoisting unless we optimizing
+ /* It does not make sense to run code hoisting unless we are optimizing
for code size -- it rarely makes programs faster, and can make
them bigger if we did partial redundancy elimination (when optimizing
for space, we use a classic gcse algorithm instead of partial
@@ -892,13 +849,13 @@ gcse_main (f, file)
max_gcse_regno = max_reg_num ();
alloc_gcse_mem (f);
/* This time, go ahead and allow cprop to alter jumps. */
- one_cprop_pass (pass + 1, 1);
+ one_cprop_pass (pass + 1, 1, 0);
free_gcse_mem ();
if (file)
{
fprintf (file, "GCSE of %s: %d basic blocks, ",
- current_function_name, n_basic_blocks);
+ current_function_name (), n_basic_blocks);
fprintf (file, "%d pass%s, %d bytes\n\n",
pass, pass > 1 ? "es" : "", max_pass_bytes);
}
@@ -909,75 +866,101 @@ gcse_main (f, file)
end_alias_analysis ();
allocate_reg_info (max_reg_num (), FALSE, FALSE);
- /* Store motion disabled until it is fixed. */
- if (0 && !optimize_size && flag_gcse_sm)
+ if (!optimize_size && flag_gcse_sm)
store_motion ();
+
/* Record where pseudo-registers are set. */
return run_jump_opt_after_gcse;
}
/* Misc. utilities. */
+/* Nonzero for each mode that supports (set (reg) (reg)).
+ This is trivially true for integer and floating point values.
+ It may or may not be true for condition codes. */
+static char can_copy[(int) NUM_MACHINE_MODES];
+
/* Compute which modes support reg/reg copy operations. */
static void
-compute_can_copy ()
+compute_can_copy (void)
{
int i;
#ifndef AVOID_CCMODE_COPIES
rtx reg, insn;
#endif
- memset (can_copy_p, 0, NUM_MACHINE_MODES);
+ memset (can_copy, 0, NUM_MACHINE_MODES);
start_sequence ();
for (i = 0; i < NUM_MACHINE_MODES; i++)
if (GET_MODE_CLASS (i) == MODE_CC)
{
#ifdef AVOID_CCMODE_COPIES
- can_copy_p[i] = 0;
+ can_copy[i] = 0;
#else
reg = gen_rtx_REG ((enum machine_mode) i, LAST_VIRTUAL_REGISTER + 1);
insn = emit_insn (gen_rtx_SET (VOIDmode, reg, reg));
if (recog (PATTERN (insn), insn, NULL) >= 0)
- can_copy_p[i] = 1;
+ can_copy[i] = 1;
#endif
}
else
- can_copy_p[i] = 1;
+ can_copy[i] = 1;
end_sequence ();
}
+
+/* Returns whether the mode supports reg/reg copy operations. */
+
+bool
+can_copy_p (enum machine_mode mode)
+{
+ static bool can_copy_init_p = false;
+
+ if (! can_copy_init_p)
+ {
+ compute_can_copy ();
+ can_copy_init_p = true;
+ }
+
+ return can_copy[mode] != 0;
+}
/* Cover function to xmalloc to record bytes allocated. */
-static char *
-gmalloc (size)
- unsigned int size;
+static void *
+gmalloc (size_t size)
{
bytes_used += size;
return xmalloc (size);
}
+/* Cover function to xcalloc to record bytes allocated. */
+
+static void *
+gcalloc (size_t nelem, size_t elsize)
+{
+ bytes_used += nelem * elsize;
+ return xcalloc (nelem, elsize);
+}
+
/* Cover function to xrealloc.
We don't record the additional size since we don't know it.
It won't affect memory usage stats much anyway. */
-static char *
-grealloc (ptr, size)
- char *ptr;
- unsigned int size;
+static void *
+grealloc (void *ptr, size_t size)
{
return xrealloc (ptr, size);
}
/* Cover function to obstack_alloc. */
-static char *
-gcse_alloc (size)
- unsigned long size;
+static void *
+gcse_alloc (unsigned long size)
{
bytes_used += size;
- return (char *) obstack_alloc (&gcse_obstack, size);
+ return obstack_alloc (&gcse_obstack, size);
}
/* Allocate memory for the cuid mapping array,
@@ -986,10 +969,9 @@ gcse_alloc (size)
This is called at the start of each pass. */
static void
-alloc_gcse_mem (f)
- rtx f;
+alloc_gcse_mem (rtx f)
{
- int i, n;
+ int i;
rtx insn;
/* Find the largest UID and create a mapping from UIDs to CUIDs.
@@ -997,9 +979,7 @@ alloc_gcse_mem (f)
and only apply to real insns. */
max_uid = get_max_uid ();
- n = (max_uid + 1) * sizeof (int);
- uid_cuid = (int *) gmalloc (n);
- memset ((char *) uid_cuid, 0, n);
+ uid_cuid = gcalloc (max_uid + 1, sizeof (int));
for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
{
if (INSN_P (insn))
@@ -1011,9 +991,7 @@ alloc_gcse_mem (f)
/* Create a table mapping cuids to insns. */
max_cuid = i;
- n = (max_cuid + 1) * sizeof (rtx);
- cuid_insn = (rtx *) gmalloc (n);
- memset ((char *) cuid_insn, 0, n);
+ cuid_insn = gcalloc (max_cuid + 1, sizeof (rtx));
for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn))
CUID_INSN (i++) = insn;
@@ -1022,14 +1000,11 @@ alloc_gcse_mem (f)
reg_set_bitmap = BITMAP_XMALLOC ();
/* Allocate vars to track sets of regs, memory per block. */
- reg_set_in_block = (sbitmap *) sbitmap_vector_alloc (last_basic_block,
- max_gcse_regno);
+ reg_set_in_block = sbitmap_vector_alloc (last_basic_block, max_gcse_regno);
/* Allocate array to keep a list of insns which modify memory in each
basic block. */
- modify_mem_list = (rtx *) gmalloc (last_basic_block * sizeof (rtx));
- canon_modify_mem_list = (rtx *) gmalloc (last_basic_block * sizeof (rtx));
- memset ((char *) modify_mem_list, 0, last_basic_block * sizeof (rtx));
- memset ((char *) canon_modify_mem_list, 0, last_basic_block * sizeof (rtx));
+ modify_mem_list = gcalloc (last_basic_block, sizeof (rtx));
+ canon_modify_mem_list = gcalloc (last_basic_block, sizeof (rtx));
modify_mem_list_set = BITMAP_XMALLOC ();
canon_modify_mem_list_set = BITMAP_XMALLOC ();
}
@@ -1037,7 +1012,7 @@ alloc_gcse_mem (f)
/* Free memory allocated by alloc_gcse_mem. */
static void
-free_gcse_mem ()
+free_gcse_mem (void)
{
free (uid_cuid);
free (cuid_insn);
@@ -1068,10 +1043,7 @@ free_gcse_mem ()
less space. */
static int
-get_bitmap_width (n, x, y)
- int n;
- int x;
- int y;
+get_bitmap_width (int n, int x, int y)
{
/* It's not really worth figuring out *exactly* how much memory will
be used by a particular choice. The important thing is to get
@@ -1121,11 +1093,7 @@ get_bitmap_width (n, x, y)
ABSALTERED. */
static void
-compute_local_properties (transp, comp, antloc, table)
- sbitmap *transp;
- sbitmap *comp;
- sbitmap *antloc;
- struct hash_table *table;
+compute_local_properties (sbitmap *transp, sbitmap *comp, sbitmap *antloc, struct hash_table *table)
{
unsigned int i;
@@ -1197,32 +1165,43 @@ compute_local_properties (transp, comp, antloc, table)
static struct obstack reg_set_obstack;
static void
-alloc_reg_set_mem (n_regs)
- int n_regs;
+alloc_reg_set_mem (int n_regs)
{
- unsigned int n;
-
reg_set_table_size = n_regs + REG_SET_TABLE_SLOP;
- n = reg_set_table_size * sizeof (struct reg_set *);
- reg_set_table = (struct reg_set **) gmalloc (n);
- memset ((char *) reg_set_table, 0, n);
+ reg_set_table = gcalloc (reg_set_table_size, sizeof (struct reg_set *));
gcc_obstack_init (&reg_set_obstack);
}
static void
-free_reg_set_mem ()
+free_reg_set_mem (void)
{
free (reg_set_table);
obstack_free (&reg_set_obstack, NULL);
}
+/* An OLD_INSN that used to set REGNO was replaced by NEW_INSN.
+ Update the corresponding `reg_set_table' entry accordingly.
+ We assume that NEW_INSN is not already recorded in reg_set_table[regno]. */
+
+static void
+replace_one_set (int regno, rtx old_insn, rtx new_insn)
+{
+ struct reg_set *reg_info;
+ if (regno >= reg_set_table_size)
+ return;
+ for (reg_info = reg_set_table[regno]; reg_info; reg_info = reg_info->next)
+ if (reg_info->insn == old_insn)
+ {
+ reg_info->insn = new_insn;
+ break;
+ }
+}
+
/* Record REGNO in the reg_set table. */
static void
-record_one_set (regno, insn)
- int regno;
- rtx insn;
+record_one_set (int regno, rtx insn)
{
/* Allocate a new reg_set element and link it onto the list. */
struct reg_set *new_reg_info;
@@ -1232,16 +1211,14 @@ record_one_set (regno, insn)
{
int new_size = regno + REG_SET_TABLE_SLOP;
- reg_set_table
- = (struct reg_set **) grealloc ((char *) reg_set_table,
- new_size * sizeof (struct reg_set *));
- memset ((char *) (reg_set_table + reg_set_table_size), 0,
+ reg_set_table = grealloc (reg_set_table,
+ new_size * sizeof (struct reg_set *));
+ memset (reg_set_table + reg_set_table_size, 0,
(new_size - reg_set_table_size) * sizeof (struct reg_set *));
reg_set_table_size = new_size;
}
- new_reg_info = (struct reg_set *) obstack_alloc (&reg_set_obstack,
- sizeof (struct reg_set));
+ new_reg_info = obstack_alloc (&reg_set_obstack, sizeof (struct reg_set));
bytes_used += sizeof (struct reg_set);
new_reg_info->insn = insn;
new_reg_info->next = reg_set_table[regno];
@@ -1253,9 +1230,7 @@ record_one_set (regno, insn)
occurring. */
static void
-record_set_info (dest, setter, data)
- rtx dest, setter ATTRIBUTE_UNUSED;
- void *data;
+record_set_info (rtx dest, rtx setter ATTRIBUTE_UNUSED, void *data)
{
rtx record_set_insn = (rtx) data;
@@ -1266,11 +1241,10 @@ record_set_info (dest, setter, data)
/* Scan the function and record each set of each pseudo-register.
This is called once, at the start of the gcse pass. See the comments for
- `reg_set_table' for further documenation. */
+ `reg_set_table' for further documentation. */
static void
-compute_sets (f)
- rtx f;
+compute_sets (rtx f)
{
rtx insn;
@@ -1297,8 +1271,7 @@ static basic_block current_bb;
static GTY(()) rtx test_insn;
static int
-want_to_gcse_p (x)
- rtx x;
+want_to_gcse_p (rtx x)
{
int num_clobbers = 0;
int icode;
@@ -1311,6 +1284,7 @@ want_to_gcse_p (x)
case CONST_DOUBLE:
case CONST_VECTOR:
case CALL:
+ case CONSTANT_P_RTX:
return 0;
default:
@@ -1348,9 +1322,7 @@ want_to_gcse_p (x)
or from INSN to the end of INSN's basic block (if AVAIL_P != 0). */
static int
-oprs_unchanged_p (x, insn, avail_p)
- rtx x, insn;
- int avail_p;
+oprs_unchanged_p (rtx x, rtx insn, int avail_p)
{
int i, j;
enum rtx_code code;
@@ -1443,9 +1415,8 @@ static rtx gcse_mem_operand;
gcse_mems_conflict_p to a nonzero value. */
static void
-mems_conflict_for_gcse_p (dest, setter, data)
- rtx dest, setter ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+mems_conflict_for_gcse_p (rtx dest, rtx setter ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
{
while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
@@ -1462,7 +1433,7 @@ mems_conflict_for_gcse_p (dest, setter, data)
/* If we are setting a MEM in our list of specially recognized MEMs,
don't mark as killed this time. */
- if (dest == gcse_mem_operand && pre_ldst_mems != NULL)
+ if (expr_equiv_p (dest, gcse_mem_operand) && pre_ldst_mems != NULL)
{
if (!find_rtx_in_ldst (dest))
gcse_mems_conflict_p = 1;
@@ -1483,11 +1454,7 @@ mems_conflict_for_gcse_p (dest, setter, data)
AVAIL_P to 0. */
static int
-load_killed_in_block_p (bb, uid_limit, x, avail_p)
- basic_block bb;
- int uid_limit;
- rtx x;
- int avail_p;
+load_killed_in_block_p (basic_block bb, int uid_limit, rtx x, int avail_p)
{
rtx list_entry = modify_mem_list[bb->index];
while (list_entry)
@@ -1530,8 +1497,7 @@ load_killed_in_block_p (bb, uid_limit, x, avail_p)
the start of INSN's basic block up to but not including INSN. */
static int
-oprs_anticipatable_p (x, insn)
- rtx x, insn;
+oprs_anticipatable_p (rtx x, rtx insn)
{
return oprs_unchanged_p (x, insn, 0);
}
@@ -1540,8 +1506,7 @@ oprs_anticipatable_p (x, insn)
INSN to the end of INSN's basic block. */
static int
-oprs_available_p (x, insn)
- rtx x, insn;
+oprs_available_p (rtx x, rtx insn)
{
return oprs_unchanged_p (x, insn, 1);
}
@@ -1550,16 +1515,14 @@ oprs_available_p (x, insn)
MODE is only used if X is a CONST_INT. DO_NOT_RECORD_P is a boolean
indicating if a volatile operand is found or if the expression contains
- something we don't want to insert in the table.
+ something we don't want to insert in the table. HASH_TABLE_SIZE is
+ the current size of the hash table to be probed.
??? One might want to merge this with canon_hash. Later. */
static unsigned int
-hash_expr (x, mode, do_not_record_p, hash_table_size)
- rtx x;
- enum machine_mode mode;
- int *do_not_record_p;
- int hash_table_size;
+hash_expr (rtx x, enum machine_mode mode, int *do_not_record_p,
+ int hash_table_size)
{
unsigned int hash;
@@ -1572,8 +1535,7 @@ hash_expr (x, mode, do_not_record_p, hash_table_size)
/* Hash a string. Just add its bytes up. */
static inline unsigned
-hash_string_1 (ps)
- const char *ps;
+hash_string_1 (const char *ps)
{
unsigned hash = 0;
const unsigned char *p = (const unsigned char *) ps;
@@ -1588,10 +1550,7 @@ hash_string_1 (ps)
/* Subroutine of hash_expr to do the actual work. */
static unsigned int
-hash_expr_1 (x, mode, do_not_record_p)
- rtx x;
- enum machine_mode mode;
- int *do_not_record_p;
+hash_expr_1 (rtx x, enum machine_mode mode, int *do_not_record_p)
{
int i, j;
unsigned hash = 0;
@@ -1599,7 +1558,7 @@ hash_expr_1 (x, mode, do_not_record_p)
const char *fmt;
/* Used to turn recursion into iteration. We can't rely on GCC's
- tail-recursion eliminatio since we need to keep accumulating values
+ tail-recursion elimination since we need to keep accumulating values
in HASH. */
if (x == 0)
@@ -1779,9 +1738,7 @@ hash_expr_1 (x, mode, do_not_record_p)
??? May need to make things more elaborate. Later, as necessary. */
static unsigned int
-hash_set (regno, hash_table_size)
- int regno;
- int hash_table_size;
+hash_set (int regno, int hash_table_size)
{
unsigned int hash;
@@ -1793,8 +1750,7 @@ hash_set (regno, hash_table_size)
??? Borrowed from cse.c. Might want to remerge with cse.c. Later. */
static int
-expr_equiv_p (x, y)
- rtx x, y;
+expr_equiv_p (rtx x, rtx y)
{
int i, j;
enum rtx_code code;
@@ -1804,7 +1760,7 @@ expr_equiv_p (x, y)
return 1;
if (x == 0 || y == 0)
- return x == y;
+ return 0;
code = GET_CODE (x);
if (code != GET_CODE (y))
@@ -1818,10 +1774,8 @@ expr_equiv_p (x, y)
{
case PC:
case CC0:
- return x == y;
-
case CONST_INT:
- return INTVAL (x) == INTVAL (y);
+ return 0;
case LABEL_REF:
return XEXP (x, 0) == XEXP (y, 0);
@@ -1838,6 +1792,10 @@ expr_equiv_p (x, y)
due to it being set with the different alias set. */
if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
return 0;
+
+ /* A volatile mem should not be considered equivalent to any other. */
+ if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
+ return 0;
break;
/* For commutative operations, check both orders. */
@@ -1943,12 +1901,8 @@ expr_equiv_p (x, y)
AVAIL_P is nonzero if X is an available expression. */
static void
-insert_expr_in_table (x, mode, insn, antic_p, avail_p, table)
- rtx x;
- enum machine_mode mode;
- rtx insn;
- int antic_p, avail_p;
- struct hash_table *table;
+insert_expr_in_table (rtx x, enum machine_mode mode, rtx insn, int antic_p,
+ int avail_p, struct hash_table *table)
{
int found, do_not_record_p;
unsigned int hash;
@@ -1977,7 +1931,7 @@ insert_expr_in_table (x, mode, insn, antic_p, avail_p, table)
if (! found)
{
- cur_expr = (struct expr *) gcse_alloc (sizeof (struct expr));
+ cur_expr = gcse_alloc (sizeof (struct expr));
bytes_used += sizeof (struct expr);
if (table->table[hash] == NULL)
/* This is the first pattern that hashed to this index. */
@@ -2016,7 +1970,7 @@ insert_expr_in_table (x, mode, insn, antic_p, avail_p, table)
else
{
/* First occurrence of this expression in this basic block. */
- antic_occr = (struct occr *) gcse_alloc (sizeof (struct occr));
+ antic_occr = gcse_alloc (sizeof (struct occr));
bytes_used += sizeof (struct occr);
/* First occurrence of this expression in any block? */
if (cur_expr->antic_occr == NULL)
@@ -2051,7 +2005,7 @@ insert_expr_in_table (x, mode, insn, antic_p, avail_p, table)
else
{
/* First occurrence of this expression in this basic block. */
- avail_occr = (struct occr *) gcse_alloc (sizeof (struct occr));
+ avail_occr = gcse_alloc (sizeof (struct occr));
bytes_used += sizeof (struct occr);
/* First occurrence of this expression in any block? */
@@ -2072,10 +2026,7 @@ insert_expr_in_table (x, mode, insn, antic_p, avail_p, table)
basic block. */
static void
-insert_set_in_table (x, insn, table)
- rtx x;
- rtx insn;
- struct hash_table *table;
+insert_set_in_table (rtx x, rtx insn, struct hash_table *table)
{
int found;
unsigned int hash;
@@ -2101,7 +2052,7 @@ insert_set_in_table (x, insn, table)
if (! found)
{
- cur_expr = (struct expr *) gcse_alloc (sizeof (struct expr));
+ cur_expr = gcse_alloc (sizeof (struct expr));
bytes_used += sizeof (struct expr);
if (table->table[hash] == NULL)
/* This is the first pattern that hashed to this index. */
@@ -2140,7 +2091,7 @@ insert_set_in_table (x, insn, table)
else
{
/* First occurrence of this expression in this basic block. */
- cur_occr = (struct occr *) gcse_alloc (sizeof (struct occr));
+ cur_occr = gcse_alloc (sizeof (struct occr));
bytes_used += sizeof (struct occr);
/* First occurrence of this expression in any block? */
@@ -2154,13 +2105,40 @@ insert_set_in_table (x, insn, table)
}
}
+/* Determine whether the rtx X should be treated as a constant for
+ the purposes of GCSE's constant propagation. */
+
+static bool
+gcse_constant_p (rtx x)
+{
+ /* Consider a COMPARE of two integers constant. */
+ if (GET_CODE (x) == COMPARE
+ && GET_CODE (XEXP (x, 0)) == CONST_INT
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ return true;
+
+
+ /* Consider a COMPARE of the same registers is a constant
+ if they are not floating point registers. */
+ if (GET_CODE(x) == COMPARE
+ && GET_CODE (XEXP (x, 0)) == REG
+ && GET_CODE (XEXP (x, 1)) == REG
+ && REGNO (XEXP (x, 0)) == REGNO (XEXP (x, 1))
+ && ! FLOAT_MODE_P (GET_MODE (XEXP (x, 0)))
+ && ! FLOAT_MODE_P (GET_MODE (XEXP (x, 1))))
+ return true;
+
+ if (GET_CODE (x) == CONSTANT_P_RTX)
+ return false;
+
+ return CONSTANT_P (x);
+}
+
/* Scan pattern PAT of INSN and add an entry to the hash TABLE (set or
expression one). */
static void
-hash_scan_set (pat, insn, table)
- rtx pat, insn;
- struct hash_table *table;
+hash_scan_set (rtx pat, rtx insn, struct hash_table *table)
{
rtx src = SET_SRC (pat);
rtx dest = SET_DEST (pat);
@@ -2177,14 +2155,14 @@ hash_scan_set (pat, insn, table)
/* If this is a single set and we are doing constant propagation,
see if a REG_NOTE shows this equivalent to a constant. */
if (table->set_p && (note = find_reg_equal_equiv_note (insn)) != 0
- && CONSTANT_P (XEXP (note, 0)))
+ && gcse_constant_p (XEXP (note, 0)))
src = XEXP (note, 0), pat = gen_rtx_SET (VOIDmode, dest, src);
/* Only record sets of pseudo-regs in the hash table. */
if (! table->set_p
&& regno >= FIRST_PSEUDO_REGISTER
/* Don't GCSE something if we can't do a reg/reg copy. */
- && can_copy_p [GET_MODE (dest)]
+ && can_copy_p (GET_MODE (dest))
/* GCSE commonly inserts instruction after the insn. We can't
do that easily for EH_REGION notes so disable GCSE on these
for now. */
@@ -2220,31 +2198,72 @@ hash_scan_set (pat, insn, table)
&& regno >= FIRST_PSEUDO_REGISTER
&& ((GET_CODE (src) == REG
&& REGNO (src) >= FIRST_PSEUDO_REGISTER
- && can_copy_p [GET_MODE (dest)]
+ && can_copy_p (GET_MODE (dest))
&& REGNO (src) != regno)
- || CONSTANT_P (src))
+ || gcse_constant_p (src))
/* A copy is not available if its src or dest is subsequently
modified. Here we want to search from INSN+1 on, but
oprs_available_p searches from INSN on. */
- && (insn == BLOCK_END (BLOCK_NUM (insn))
+ && (insn == BB_END (BLOCK_FOR_INSN (insn))
|| ((tmp = next_nonnote_insn (insn)) != NULL_RTX
&& oprs_available_p (pat, tmp))))
insert_set_in_table (pat, insn, table);
}
+ /* In case of store we want to consider the memory value as available in
+ the REG stored in that memory. This makes it possible to remove
+ redundant loads from due to stores to the same location. */
+ else if (flag_gcse_las && GET_CODE (src) == REG && GET_CODE (dest) == MEM)
+ {
+ unsigned int regno = REGNO (src);
+
+ /* Do not do this for constant/copy propagation. */
+ if (! table->set_p
+ /* Only record sets of pseudo-regs in the hash table. */
+ && regno >= FIRST_PSEUDO_REGISTER
+ /* Don't GCSE something if we can't do a reg/reg copy. */
+ && can_copy_p (GET_MODE (src))
+ /* GCSE commonly inserts instruction after the insn. We can't
+ do that easily for EH_REGION notes so disable GCSE on these
+ for now. */
+ && ! find_reg_note (insn, REG_EH_REGION, NULL_RTX)
+ /* Is SET_DEST something we want to gcse? */
+ && want_to_gcse_p (dest)
+ /* Don't CSE a nop. */
+ && ! set_noop_p (pat)
+ /* Don't GCSE if it has attached REG_EQUIV note.
+ At this point this only function parameters should have
+ REG_EQUIV notes and if the argument slot is used somewhere
+ explicitly, it means address of parameter has been taken,
+ so we should not extend the lifetime of the pseudo. */
+ && ((note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) == 0
+ || GET_CODE (XEXP (note, 0)) != MEM))
+ {
+ /* Stores are never anticipatable. */
+ int antic_p = 0;
+ /* An expression is not available if its operands are
+ subsequently modified, including this insn. It's also not
+ available if this is a branch, because we can't insert
+ a set after the branch. */
+ int avail_p = oprs_available_p (dest, insn)
+ && ! JUMP_P (insn);
+
+ /* Record the memory expression (DEST) in the hash table. */
+ insert_expr_in_table (dest, GET_MODE (dest), insn,
+ antic_p, avail_p, table);
+ }
+ }
}
static void
-hash_scan_clobber (x, insn, table)
- rtx x ATTRIBUTE_UNUSED, insn ATTRIBUTE_UNUSED;
- struct hash_table *table ATTRIBUTE_UNUSED;
+hash_scan_clobber (rtx x ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED,
+ struct hash_table *table ATTRIBUTE_UNUSED)
{
/* Currently nothing to do. */
}
static void
-hash_scan_call (x, insn, table)
- rtx x ATTRIBUTE_UNUSED, insn ATTRIBUTE_UNUSED;
- struct hash_table *table ATTRIBUTE_UNUSED;
+hash_scan_call (rtx x ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED,
+ struct hash_table *table ATTRIBUTE_UNUSED)
{
/* Currently nothing to do. */
}
@@ -2263,10 +2282,7 @@ hash_scan_call (x, insn, table)
not record any expressions. */
static void
-hash_scan_insn (insn, table, in_libcall_block)
- rtx insn;
- struct hash_table *table;
- int in_libcall_block;
+hash_scan_insn (rtx insn, struct hash_table *table, int in_libcall_block)
{
rtx pat = PATTERN (insn);
int i;
@@ -2299,10 +2315,7 @@ hash_scan_insn (insn, table, in_libcall_block)
}
static void
-dump_hash_table (file, name, table)
- FILE *file;
- const char *name;
- struct hash_table *table;
+dump_hash_table (FILE *file, const char *name, struct hash_table *table)
{
int i;
/* Flattened out table, so it's printed in proper order. */
@@ -2310,9 +2323,8 @@ dump_hash_table (file, name, table)
unsigned int *hash_val;
struct expr *expr;
- flat_table
- = (struct expr **) xcalloc (table->n_elems, sizeof (struct expr *));
- hash_val = (unsigned int *) xmalloc (table->n_elems * sizeof (unsigned int));
+ flat_table = xcalloc (table->n_elems, sizeof (struct expr *));
+ hash_val = xmalloc (table->n_elems * sizeof (unsigned int));
for (i = 0; i < (int) table->size; i++)
for (expr = table->table[i]; expr != NULL; expr = expr->next_same_hash)
@@ -2355,9 +2367,7 @@ dump_hash_table (file, name, table)
and is used to compute "transparency". */
static void
-record_last_reg_set_info (insn, regno)
- rtx insn;
- int regno;
+record_last_reg_set_info (rtx insn, int regno)
{
struct reg_avail_info *info = &reg_avail_info[regno];
int cuid = INSN_CUID (insn);
@@ -2377,10 +2387,8 @@ record_last_reg_set_info (insn, regno)
taken off pairwise. */
static void
-canon_list_insert (dest, unused1, v_insn)
- rtx dest ATTRIBUTE_UNUSED;
- rtx unused1 ATTRIBUTE_UNUSED;
- void * v_insn;
+canon_list_insert (rtx dest ATTRIBUTE_UNUSED, rtx unused1 ATTRIBUTE_UNUSED,
+ void * v_insn)
{
rtx dest_addr, insn;
int bb;
@@ -2415,8 +2423,7 @@ canon_list_insert (dest, unused1, v_insn)
a CALL_INSN). We merely need to record which insns modify memory. */
static void
-record_last_mem_set_info (insn)
- rtx insn;
+record_last_mem_set_info (rtx insn)
{
int bb = BLOCK_NUM (insn);
@@ -2443,9 +2450,7 @@ record_last_mem_set_info (insn)
the SET is taking place. */
static void
-record_last_set_info (dest, setter, data)
- rtx dest, setter ATTRIBUTE_UNUSED;
- void *data;
+record_last_set_info (rtx dest, rtx setter ATTRIBUTE_UNUSED, void *data)
{
rtx last_set_insn = (rtx) data;
@@ -2474,12 +2479,10 @@ record_last_set_info (dest, setter, data)
Currently src must be a pseudo-reg or a const_int.
- F is the first insn.
TABLE is the table computed. */
static void
-compute_hash_table_work (table)
- struct hash_table *table;
+compute_hash_table_work (struct hash_table *table)
{
unsigned int i;
@@ -2492,8 +2495,7 @@ compute_hash_table_work (table)
/* re-Cache any INSN_LIST nodes we have allocated. */
clear_modify_mem_tables ();
/* Some working arrays used to track first and last set in each block. */
- reg_avail_info = (struct reg_avail_info*)
- gmalloc (max_gcse_regno * sizeof (struct reg_avail_info));
+ reg_avail_info = gmalloc (max_gcse_regno * sizeof (struct reg_avail_info));
for (i = 0; i < max_gcse_regno; ++i)
reg_avail_info[i].last_bb = NULL;
@@ -2509,8 +2511,8 @@ compute_hash_table_work (table)
??? hard-reg reg_set_in_block computation
could be moved to compute_sets since they currently don't change. */
- for (insn = current_bb->head;
- insn && insn != NEXT_INSN (current_bb->end);
+ for (insn = BB_HEAD (current_bb);
+ insn && insn != NEXT_INSN (BB_END (current_bb));
insn = NEXT_INSN (insn))
{
if (! INSN_P (insn))
@@ -2536,10 +2538,16 @@ compute_hash_table_work (table)
note_stores (PATTERN (insn), record_last_set_info, insn);
}
+ /* Insert implicit sets in the hash table. */
+ if (table->set_p
+ && implicit_sets[current_bb->index] != NULL_RTX)
+ hash_scan_set (implicit_sets[current_bb->index],
+ BB_HEAD (current_bb), table);
+
/* The next pass builds the hash table. */
- for (insn = current_bb->head, in_libcall_block = 0;
- insn && insn != NEXT_INSN (current_bb->end);
+ for (insn = BB_HEAD (current_bb), in_libcall_block = 0;
+ insn && insn != NEXT_INSN (BB_END (current_bb));
insn = NEXT_INSN (insn))
if (INSN_P (insn))
{
@@ -2564,10 +2572,7 @@ compute_hash_table_work (table)
be created. */
static void
-alloc_hash_table (n_insns, table, set_p)
- int n_insns;
- struct hash_table *table;
- int set_p;
+alloc_hash_table (int n_insns, struct hash_table *table, int set_p)
{
int n;
@@ -2580,15 +2585,14 @@ alloc_hash_table (n_insns, table, set_p)
??? Later take some measurements. */
table->size |= 1;
n = table->size * sizeof (struct expr *);
- table->table = (struct expr **) gmalloc (n);
+ table->table = gmalloc (n);
table->set_p = set_p;
}
/* Free things allocated by alloc_hash_table. */
static void
-free_hash_table (table)
- struct hash_table *table;
+free_hash_table (struct hash_table *table)
{
free (table->table);
}
@@ -2597,13 +2601,11 @@ free_hash_table (table)
expression hash table. */
static void
-compute_hash_table (table)
- struct hash_table *table;
+compute_hash_table (struct hash_table *table)
{
/* Initialize count of number of entries in hash table. */
table->n_elems = 0;
- memset ((char *) table->table, 0,
- table->size * sizeof (struct expr *));
+ memset (table->table, 0, table->size * sizeof (struct expr *));
compute_hash_table_work (table);
}
@@ -2614,9 +2616,7 @@ compute_hash_table (table)
The result is a pointer to the table entry, or NULL if not found. */
static struct expr *
-lookup_expr (pat, table)
- rtx pat;
- struct hash_table *table;
+lookup_expr (rtx pat, struct hash_table *table)
{
int do_not_record_p;
unsigned int hash = hash_expr (pat, GET_MODE (pat), &do_not_record_p,
@@ -2634,31 +2634,19 @@ lookup_expr (pat, table)
return expr;
}
-/* Lookup REGNO in the set TABLE. If PAT is non-NULL look for the entry that
- matches it, otherwise return the first entry for REGNO. The result is a
- pointer to the table entry, or NULL if not found. */
+/* Lookup REGNO in the set TABLE. The result is a pointer to the
+ table entry, or NULL if not found. */
static struct expr *
-lookup_set (regno, pat, table)
- unsigned int regno;
- rtx pat;
- struct hash_table *table;
+lookup_set (unsigned int regno, struct hash_table *table)
{
unsigned int hash = hash_set (regno, table->size);
struct expr *expr;
expr = table->table[hash];
- if (pat)
- {
- while (expr && ! expr_equiv_p (expr->expr, pat))
- expr = expr->next_same_hash;
- }
- else
- {
- while (expr && REGNO (SET_DEST (expr->expr)) != regno)
- expr = expr->next_same_hash;
- }
+ while (expr && REGNO (SET_DEST (expr->expr)) != regno)
+ expr = expr->next_same_hash;
return expr;
}
@@ -2666,9 +2654,7 @@ lookup_set (regno, pat, table)
/* Return the next entry for REGNO in list EXPR. */
static struct expr *
-next_set (regno, expr)
- unsigned int regno;
- struct expr *expr;
+next_set (unsigned int regno, struct expr *expr)
{
do
expr = expr->next_same_hash;
@@ -2681,8 +2667,7 @@ next_set (regno, expr)
types may be mixed. */
static void
-free_insn_expr_list_list (listp)
- rtx *listp;
+free_insn_expr_list_list (rtx *listp)
{
rtx list, next;
@@ -2700,7 +2685,7 @@ free_insn_expr_list_list (listp)
/* Clear canon_modify_mem_list and modify_mem_list tables. */
static void
-clear_modify_mem_tables ()
+clear_modify_mem_tables (void)
{
int i;
@@ -2717,7 +2702,7 @@ clear_modify_mem_tables ()
/* Release memory used by modify_mem_list_set and canon_modify_mem_list_set. */
static void
-free_modify_mem_tables ()
+free_modify_mem_tables (void)
{
clear_modify_mem_tables ();
free (modify_mem_list);
@@ -2730,7 +2715,7 @@ free_modify_mem_tables ()
start of the block]. */
static void
-reset_opr_set_tables ()
+reset_opr_set_tables (void)
{
/* Maintain a bitmap of which regs have been set since beginning of
the block. */
@@ -2746,8 +2731,7 @@ reset_opr_set_tables ()
INSN's basic block. */
static int
-oprs_not_set_p (x, insn)
- rtx x, insn;
+oprs_not_set_p (rtx x, rtx insn)
{
int i, j;
enum rtx_code code;
@@ -2810,8 +2794,7 @@ oprs_not_set_p (x, insn)
/* Mark things set by a CALL. */
static void
-mark_call (insn)
- rtx insn;
+mark_call (rtx insn)
{
if (! CONST_OR_PURE_CALL_P (insn))
record_last_mem_set_info (insn);
@@ -2820,8 +2803,7 @@ mark_call (insn)
/* Mark things set by a SET. */
static void
-mark_set (pat, insn)
- rtx pat, insn;
+mark_set (rtx pat, rtx insn)
{
rtx dest = SET_DEST (pat);
@@ -2843,8 +2825,7 @@ mark_set (pat, insn)
/* Record things set by a CLOBBER. */
static void
-mark_clobber (pat, insn)
- rtx pat, insn;
+mark_clobber (rtx pat, rtx insn)
{
rtx clob = XEXP (pat, 0);
@@ -2861,8 +2842,7 @@ mark_clobber (pat, insn)
This data is used by oprs_not_set_p. */
static void
-mark_oprs_set (insn)
- rtx insn;
+mark_oprs_set (rtx insn)
{
rtx pat = PATTERN (insn);
int i;
@@ -2894,26 +2874,25 @@ mark_oprs_set (insn)
/* Allocate reaching def variables. */
static void
-alloc_rd_mem (n_blocks, n_insns)
- int n_blocks, n_insns;
+alloc_rd_mem (int n_blocks, int n_insns)
{
- rd_kill = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
+ rd_kill = sbitmap_vector_alloc (n_blocks, n_insns);
sbitmap_vector_zero (rd_kill, n_blocks);
- rd_gen = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
+ rd_gen = sbitmap_vector_alloc (n_blocks, n_insns);
sbitmap_vector_zero (rd_gen, n_blocks);
- reaching_defs = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
+ reaching_defs = sbitmap_vector_alloc (n_blocks, n_insns);
sbitmap_vector_zero (reaching_defs, n_blocks);
- rd_out = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_insns);
+ rd_out = sbitmap_vector_alloc (n_blocks, n_insns);
sbitmap_vector_zero (rd_out, n_blocks);
}
/* Free reaching def variables. */
static void
-free_rd_mem ()
+free_rd_mem (void)
{
sbitmap_vector_free (rd_kill);
sbitmap_vector_free (rd_gen);
@@ -2924,10 +2903,7 @@ free_rd_mem ()
/* Add INSN to the kills of BB. REGNO, set in BB, is killed by INSN. */
static void
-handle_rd_kill_set (insn, regno, bb)
- rtx insn;
- int regno;
- basic_block bb;
+handle_rd_kill_set (rtx insn, int regno, basic_block bb)
{
struct reg_set *this_reg;
@@ -2939,7 +2915,7 @@ handle_rd_kill_set (insn, regno, bb)
/* Compute the set of kill's for reaching definitions. */
static void
-compute_kill_rd ()
+compute_kill_rd (void)
{
int cuid;
unsigned int regno;
@@ -2994,7 +2970,7 @@ compute_kill_rd ()
expressions but applied to the gens and kills of reaching definitions. */
static void
-compute_rd ()
+compute_rd (void)
{
int changed, passes;
basic_block bb;
@@ -3025,24 +3001,23 @@ compute_rd ()
/* Allocate memory for available expression computation. */
static void
-alloc_avail_expr_mem (n_blocks, n_exprs)
- int n_blocks, n_exprs;
+alloc_avail_expr_mem (int n_blocks, int n_exprs)
{
- ae_kill = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
+ ae_kill = sbitmap_vector_alloc (n_blocks, n_exprs);
sbitmap_vector_zero (ae_kill, n_blocks);
- ae_gen = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
+ ae_gen = sbitmap_vector_alloc (n_blocks, n_exprs);
sbitmap_vector_zero (ae_gen, n_blocks);
- ae_in = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
+ ae_in = sbitmap_vector_alloc (n_blocks, n_exprs);
sbitmap_vector_zero (ae_in, n_blocks);
- ae_out = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
+ ae_out = sbitmap_vector_alloc (n_blocks, n_exprs);
sbitmap_vector_zero (ae_out, n_blocks);
}
static void
-free_avail_expr_mem ()
+free_avail_expr_mem (void)
{
sbitmap_vector_free (ae_kill);
sbitmap_vector_free (ae_gen);
@@ -3053,8 +3028,7 @@ free_avail_expr_mem ()
/* Compute the set of available expressions generated in each basic block. */
static void
-compute_ae_gen (expr_hash_table)
- struct hash_table *expr_hash_table;
+compute_ae_gen (struct hash_table *expr_hash_table)
{
unsigned int i;
struct expr *expr;
@@ -3073,9 +3047,7 @@ compute_ae_gen (expr_hash_table)
/* Return nonzero if expression X is killed in BB. */
static int
-expr_killed_p (x, bb)
- rtx x;
- basic_block bb;
+expr_killed_p (rtx x, basic_block bb)
{
int i, j;
enum rtx_code code;
@@ -3136,9 +3108,8 @@ expr_killed_p (x, bb)
/* Compute the set of available expressions killed in each basic block. */
static void
-compute_ae_kill (ae_gen, ae_kill, expr_hash_table)
- sbitmap *ae_gen, *ae_kill;
- struct hash_table *expr_hash_table;
+compute_ae_kill (sbitmap *ae_gen, sbitmap *ae_kill,
+ struct hash_table *expr_hash_table)
{
basic_block bb;
unsigned int i;
@@ -3176,12 +3147,8 @@ compute_ae_kill (ae_gen, ae_kill, expr_hash_table)
the closest such expression. */
static int
-expr_reaches_here_p_work (occr, expr, bb, check_self_loop, visited)
- struct occr *occr;
- struct expr *expr;
- basic_block bb;
- int check_self_loop;
- char *visited;
+expr_reaches_here_p_work (struct occr *occr, struct expr *expr,
+ basic_block bb, int check_self_loop, char *visited)
{
edge pred;
@@ -3238,14 +3205,11 @@ expr_reaches_here_p_work (occr, expr, bb, check_self_loop, visited)
memory allocated for that function is returned. */
static int
-expr_reaches_here_p (occr, expr, bb, check_self_loop)
- struct occr *occr;
- struct expr *expr;
- basic_block bb;
- int check_self_loop;
+expr_reaches_here_p (struct occr *occr, struct expr *expr, basic_block bb,
+ int check_self_loop)
{
int rval;
- char *visited = (char *) xcalloc (last_basic_block, 1);
+ char *visited = xcalloc (last_basic_block, 1);
rval = expr_reaches_here_p_work (occr, expr, bb, check_self_loop, visited);
@@ -3259,9 +3223,7 @@ expr_reaches_here_p (occr, expr, bb, check_self_loop)
Called only by handle_avail_expr. */
static rtx
-computing_insn (expr, insn)
- struct expr *expr;
- rtx insn;
+computing_insn (struct expr *expr, rtx insn)
{
basic_block bb = BLOCK_FOR_INSN (insn);
@@ -3324,8 +3286,7 @@ computing_insn (expr, insn)
Only called by can_disregard_other_sets. */
static int
-def_reaches_here_p (insn, def_insn)
- rtx insn, def_insn;
+def_reaches_here_p (rtx insn, rtx def_insn)
{
rtx reg;
@@ -3361,10 +3322,7 @@ def_reaches_here_p (insn, def_insn)
always safe to return zero. */
static int
-can_disregard_other_sets (addr_this_reg, insn, for_combine)
- struct reg_set **addr_this_reg;
- rtx insn;
- int for_combine;
+can_disregard_other_sets (struct reg_set **addr_this_reg, rtx insn, int for_combine)
{
int number_of_reaching_defs = 0;
struct reg_set *this_reg;
@@ -3409,9 +3367,7 @@ can_disregard_other_sets (addr_this_reg, insn, for_combine)
The result is nonzero if any changes were made. */
static int
-handle_avail_expr (insn, expr)
- rtx insn;
- struct expr *expr;
+handle_avail_expr (rtx insn, struct expr *expr)
{
rtx pat, insn_computes_expr, expr_set;
rtx to;
@@ -3425,8 +3381,11 @@ handle_avail_expr (insn, expr)
if (insn_computes_expr == NULL)
return 0;
expr_set = single_set (insn_computes_expr);
+ /* The set might be in a parallel with multiple sets; we could
+ probably handle that, but there's currently no easy way to find
+ the relevant sub-expression. */
if (!expr_set)
- abort ();
+ return 0;
found_setting = 0;
use_src = 0;
@@ -3567,7 +3526,7 @@ handle_avail_expr (insn, expr)
The result is nonzero if a change was made. */
static int
-classic_gcse ()
+classic_gcse (void)
{
int changed;
rtx insn;
@@ -3585,8 +3544,8 @@ classic_gcse ()
start of the block]. */
reset_opr_set_tables ();
- for (insn = bb->head;
- insn != NULL && insn != NEXT_INSN (bb->end);
+ for (insn = BB_HEAD (bb);
+ insn != NULL && insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
{
/* Is insn of form (set (pseudo-reg) ...)? */
@@ -3626,8 +3585,7 @@ classic_gcse ()
Return nonzero if a change was made. */
static int
-one_classic_gcse_pass (pass)
- int pass;
+one_classic_gcse_pass (int pass)
{
int changed = 0;
@@ -3659,7 +3617,7 @@ one_classic_gcse_pass (pass)
{
fprintf (gcse_file, "\n");
fprintf (gcse_file, "GCSE of %s, pass %d: %d bytes needed, %d substs,",
- current_function_name, pass, bytes_used, gcse_subst_count);
+ current_function_name (), pass, bytes_used, gcse_subst_count);
fprintf (gcse_file, "%d insns created\n", gcse_create_count);
}
@@ -3680,8 +3638,7 @@ static sbitmap *cprop_avout;
basic blocks. N_SETS is the number of sets. */
static void
-alloc_cprop_mem (n_blocks, n_sets)
- int n_blocks, n_sets;
+alloc_cprop_mem (int n_blocks, int n_sets)
{
cprop_pavloc = sbitmap_vector_alloc (n_blocks, n_sets);
cprop_absaltered = sbitmap_vector_alloc (n_blocks, n_sets);
@@ -3693,7 +3650,7 @@ alloc_cprop_mem (n_blocks, n_sets)
/* Free vars used by copy/const propagation. */
static void
-free_cprop_mem ()
+free_cprop_mem (void)
{
sbitmap_vector_free (cprop_pavloc);
sbitmap_vector_free (cprop_absaltered);
@@ -3708,11 +3665,7 @@ free_cprop_mem ()
bit in BMAP. */
static void
-compute_transp (x, indx, bmap, set_p)
- rtx x;
- int indx;
- sbitmap *bmap;
- int set_p;
+compute_transp (rtx x, int indx, sbitmap *bmap, int set_p)
{
int i, j;
basic_block bb;
@@ -3843,7 +3796,7 @@ compute_transp (x, indx, bmap, set_p)
propagation. */
static void
-compute_cprop_data ()
+compute_cprop_data (void)
{
compute_local_properties (cprop_absaltered, cprop_pavloc, NULL, &set_hash_table);
compute_available (cprop_pavloc, cprop_absaltered,
@@ -3870,9 +3823,7 @@ static int reg_use_count;
This doesn't hurt anything but it will slow things down. */
static void
-find_used_regs (xptr, data)
- rtx *xptr;
- void *data ATTRIBUTE_UNUSED;
+find_used_regs (rtx *xptr, void *data ATTRIBUTE_UNUSED)
{
int i, j;
enum rtx_code code;
@@ -3922,8 +3873,7 @@ find_used_regs (xptr, data)
Returns nonzero is successful. */
static int
-try_replace_reg (from, to, insn)
- rtx from, to, insn;
+try_replace_reg (rtx from, rtx to, rtx insn)
{
rtx note = find_reg_equal_equiv_note (insn);
rtx src = 0;
@@ -3943,6 +3893,11 @@ try_replace_reg (from, to, insn)
validate_change (insn, &SET_SRC (set), src, 0);
}
+ /* If there is already a NOTE, update the expression in it with our
+ replacement. */
+ if (note != 0)
+ XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), from, to);
+
if (!success && set && reg_mentioned_p (from, SET_SRC (set)))
{
/* If above failed and this is a single set, try to simplify the source of
@@ -3963,14 +3918,9 @@ try_replace_reg (from, to, insn)
note = set_unique_reg_note (insn, REG_EQUAL, copy_rtx (src));
}
- /* If there is already a NOTE, update the expression in it with our
- replacement. */
- else if (note != 0)
- XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0), from, to);
-
/* REG_EQUAL may get simplified into register.
We don't allow that. Remove that note. This code ought
- not to hapen, because previous code ought to syntetize
+ not to happen, because previous code ought to synthesize
reg-reg move, but be on the safe side. */
if (note && REG_P (XEXP (note, 0)))
remove_note (insn, note);
@@ -3982,9 +3932,7 @@ try_replace_reg (from, to, insn)
NULL no such set is found. */
static struct expr *
-find_avail_set (regno, insn)
- int regno;
- rtx insn;
+find_avail_set (int regno, rtx insn)
{
/* SET1 contains the last set found that can be returned to the caller for
use in a substitution. */
@@ -4002,7 +3950,7 @@ find_avail_set (regno, insn)
while (1)
{
rtx src;
- struct expr *set = lookup_set (regno, NULL_RTX, &set_hash_table);
+ struct expr *set = lookup_set (regno, &set_hash_table);
/* Find a set that is available at the start of the block
which contains INSN. */
@@ -4030,7 +3978,7 @@ find_avail_set (regno, insn)
If the source operand changed, we may still use it for the next
iteration of this loop, but we may not use it for substitutions. */
- if (CONSTANT_P (src) || oprs_not_set_p (src, insn))
+ if (gcse_constant_p (src) || oprs_not_set_p (src, insn))
set1 = set;
/* If the source of the set is anything except a register, then
@@ -4050,41 +3998,50 @@ find_avail_set (regno, insn)
/* Subroutine of cprop_insn that tries to propagate constants into
JUMP_INSNS. JUMP must be a conditional jump. If SETCC is non-NULL
- it is the instruction that immediately preceeds JUMP, and must be a
+ it is the instruction that immediately precedes JUMP, and must be a
single SET of a register. FROM is what we will try to replace,
SRC is the constant we will try to substitute for it. Returns nonzero
if a change was made. */
static int
-cprop_jump (bb, setcc, jump, from, src)
- basic_block bb;
- rtx setcc;
- rtx jump;
- rtx from;
- rtx src;
-{
- rtx new, new_set;
+cprop_jump (basic_block bb, rtx setcc, rtx jump, rtx from, rtx src)
+{
+ rtx new, set_src, note_src;
rtx set = pc_set (jump);
+ rtx note = find_reg_equal_equiv_note (jump);
+
+ if (note)
+ {
+ note_src = XEXP (note, 0);
+ if (GET_CODE (note_src) == EXPR_LIST)
+ note_src = NULL_RTX;
+ }
+ else note_src = NULL_RTX;
+
+ /* Prefer REG_EQUAL notes except those containing EXPR_LISTs. */
+ set_src = note_src ? note_src : SET_SRC (set);
- /* First substitute in the INSN condition as the SET_SRC of the JUMP,
- then substitute that given values in this expanded JUMP. */
- if (setcc != NULL
+ /* First substitute the SETCC condition into the JUMP instruction,
+ then substitute that given values into this expanded JUMP. */
+ if (setcc != NULL_RTX
&& !modified_between_p (from, setcc, jump)
&& !modified_between_p (src, setcc, jump))
{
+ rtx setcc_src;
rtx setcc_set = single_set (setcc);
- new_set = simplify_replace_rtx (SET_SRC (set),
- SET_DEST (setcc_set),
- SET_SRC (setcc_set));
+ rtx setcc_note = find_reg_equal_equiv_note (setcc);
+ setcc_src = (setcc_note && GET_CODE (XEXP (setcc_note, 0)) != EXPR_LIST)
+ ? XEXP (setcc_note, 0) : SET_SRC (setcc_set);
+ set_src = simplify_replace_rtx (set_src, SET_DEST (setcc_set),
+ setcc_src);
}
else
- new_set = set;
+ setcc = NULL_RTX;
- new = simplify_replace_rtx (new_set, from, src);
+ new = simplify_replace_rtx (set_src, from, src);
- /* If no simplification can be made, then try the next
- register. */
- if (rtx_equal_p (new, new_set) || rtx_equal_p (new, SET_SRC (set)))
+ /* If no simplification can be made, then try the next register. */
+ if (rtx_equal_p (new, SET_SRC (set)))
return 0;
/* If this is now a no-op delete it, otherwise this must be a valid insn. */
@@ -4094,11 +4051,27 @@ cprop_jump (bb, setcc, jump, from, src)
{
/* Ensure the value computed inside the jump insn to be equivalent
to one computed by setcc. */
- if (setcc
- && modified_in_p (new, setcc))
+ if (setcc && modified_in_p (new, setcc))
return 0;
if (! validate_change (jump, &SET_SRC (set), new, 0))
- return 0;
+ {
+ /* When (some) constants are not valid in a comparison, and there
+ are two registers to be replaced by constants before the entire
+ comparison can be folded into a constant, we need to keep
+ intermediate information in REG_EQUAL notes. For targets with
+ separate compare insns, such notes are added by try_replace_reg.
+ When we have a combined compare-and-branch instruction, however,
+ we need to attach a note to the branch itself to make this
+ optimization work. */
+
+ if (!rtx_equal_p (new, note_src))
+ set_unique_reg_note (jump, REG_EQUAL, copy_rtx (new));
+ return 0;
+ }
+
+ /* Remove REG_EQUAL note after simplification. */
+ if (note_src)
+ remove_note (jump, note);
/* If this has turned into an unconditional jump,
then put a barrier after it so that the unreachable
@@ -4130,11 +4103,7 @@ cprop_jump (bb, setcc, jump, from, src)
}
static bool
-constprop_register (insn, from, to, alter_jumps)
- rtx insn;
- rtx from;
- rtx to;
- int alter_jumps;
+constprop_register (rtx insn, rtx from, rtx to, int alter_jumps)
{
rtx sset;
@@ -4171,9 +4140,7 @@ constprop_register (insn, from, to, alter_jumps)
The result is nonzero if a change was made. */
static int
-cprop_insn (insn, alter_jumps)
- rtx insn;
- int alter_jumps;
+cprop_insn (rtx insn, int alter_jumps)
{
struct reg_use *reg_used;
int changed = 0;
@@ -4222,7 +4189,7 @@ cprop_insn (insn, alter_jumps)
src = SET_SRC (pat);
/* Constant propagation. */
- if (CONSTANT_P (src))
+ if (gcse_constant_p (src))
{
if (constprop_register (insn, reg_used->reg_rtx, src, alter_jumps))
{
@@ -4235,6 +4202,8 @@ cprop_insn (insn, alter_jumps)
print_rtl (gcse_file, src);
fprintf (gcse_file, "\n");
}
+ if (INSN_DELETED_P (insn))
+ return 1;
}
}
else if (GET_CODE (src) == REG
@@ -4270,9 +4239,7 @@ cprop_insn (insn, alter_jumps)
can legitimately make replacements. */
static void
-local_cprop_find_used_regs (xptr, data)
- rtx *xptr;
- void *data;
+local_cprop_find_used_regs (rtx *xptr, void *data)
{
rtx x = *xptr;
@@ -4310,16 +4277,12 @@ local_cprop_find_used_regs (xptr, data)
find_used_regs (xptr, data);
}
-
+
/* LIBCALL_SP is a zero-terminated array of insns at the end of a libcall;
their REG_EQUAL notes need updating. */
static bool
-do_local_cprop (x, insn, alter_jumps, libcall_sp)
- rtx x;
- rtx insn;
- int alter_jumps;
- rtx *libcall_sp;
+do_local_cprop (rtx x, rtx insn, int alter_jumps, rtx *libcall_sp)
{
rtx newreg = NULL, newcnst = NULL;
@@ -4343,7 +4306,7 @@ do_local_cprop (x, insn, alter_jumps, libcall_sp)
if (l->in_libcall)
continue;
- if (CONSTANT_P (this_rtx))
+ if (gcse_constant_p (this_rtx))
newcnst = this_rtx;
if (REG_P (this_rtx) && REGNO (this_rtx) >= FIRST_PSEUDO_REGISTER
/* Don't copy propagate if it has attached REG_EQUIV note.
@@ -4358,7 +4321,7 @@ do_local_cprop (x, insn, alter_jumps, libcall_sp)
if (newcnst && constprop_register (insn, x, newcnst, alter_jumps))
{
/* If we find a case where we can't fix the retval REG_EQUAL notes
- match the new register, we either have to abandom this replacement
+ match the new register, we either have to abandon this replacement
or fix delete_trivially_dead_insns to preserve the setting insn,
or make it delete the REG_EUAQL note, and fix up all passes that
require the REG_EQUAL note there. */
@@ -4398,8 +4361,7 @@ do_local_cprop (x, insn, alter_jumps, libcall_sp)
replaced with NEWVAL in INSN. Return true if all substitutions could
be made. */
static bool
-adjust_libcall_notes (oldreg, newval, insn, libcall_sp)
- rtx oldreg, newval, insn, *libcall_sp;
+adjust_libcall_notes (rtx oldreg, rtx newval, rtx insn, rtx *libcall_sp)
{
rtx end;
@@ -4435,8 +4397,7 @@ adjust_libcall_notes (oldreg, newval, insn, libcall_sp)
#define MAX_NESTED_LIBCALLS 9
static void
-local_cprop_pass (alter_jumps)
- int alter_jumps;
+local_cprop_pass (int alter_jumps)
{
rtx insn;
struct reg_use *reg_used;
@@ -4477,6 +4438,8 @@ local_cprop_pass (alter_jumps)
changed = true;
break;
}
+ if (INSN_DELETED_P (insn))
+ break;
}
while (reg_use_count);
}
@@ -4497,8 +4460,7 @@ local_cprop_pass (alter_jumps)
nonzero if a change was made. */
static int
-cprop (alter_jumps)
- int alter_jumps;
+cprop (int alter_jumps)
{
int changed;
basic_block bb;
@@ -4519,8 +4481,8 @@ cprop (alter_jumps)
start of the block]. */
reset_opr_set_tables ();
- for (insn = bb->head;
- insn != NULL && insn != NEXT_INSN (bb->end);
+ for (insn = BB_HEAD (bb);
+ insn != NULL && insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
if (INSN_P (insn))
{
@@ -4540,32 +4502,184 @@ cprop (alter_jumps)
return changed;
}
+/* Similar to get_condition, only the resulting condition must be
+ valid at JUMP, instead of at EARLIEST.
+
+ This differs from noce_get_condition in ifcvt.c in that we prefer not to
+ settle for the condition variable in the jump instruction being integral.
+ We prefer to be able to record the value of a user variable, rather than
+ the value of a temporary used in a condition. This could be solved by
+ recording the value of *every* register scaned by canonicalize_condition,
+ but this would require some code reorganization. */
+
+rtx
+fis_get_condition (rtx jump)
+{
+ rtx cond, set, tmp, insn, earliest;
+ bool reverse;
+
+ if (! any_condjump_p (jump))
+ return NULL_RTX;
+
+ set = pc_set (jump);
+ cond = XEXP (SET_SRC (set), 0);
+
+ /* If this branches to JUMP_LABEL when the condition is false,
+ reverse the condition. */
+ reverse = (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
+ && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump));
+
+ /* Use canonicalize_condition to do the dirty work of manipulating
+ MODE_CC values and COMPARE rtx codes. */
+ tmp = canonicalize_condition (jump, cond, reverse, &earliest, NULL_RTX,
+ false);
+ if (!tmp)
+ return NULL_RTX;
+
+ /* Verify that the given condition is valid at JUMP by virtue of not
+ having been modified since EARLIEST. */
+ for (insn = earliest; insn != jump; insn = NEXT_INSN (insn))
+ if (INSN_P (insn) && modified_in_p (tmp, insn))
+ break;
+ if (insn == jump)
+ return tmp;
+
+ /* The condition was modified. See if we can get a partial result
+ that doesn't follow all the reversals. Perhaps combine can fold
+ them together later. */
+ tmp = XEXP (tmp, 0);
+ if (!REG_P (tmp) || GET_MODE_CLASS (GET_MODE (tmp)) != MODE_INT)
+ return NULL_RTX;
+ tmp = canonicalize_condition (jump, cond, reverse, &earliest, tmp,
+ false);
+ if (!tmp)
+ return NULL_RTX;
+
+ /* For sanity's sake, re-validate the new result. */
+ for (insn = earliest; insn != jump; insn = NEXT_INSN (insn))
+ if (INSN_P (insn) && modified_in_p (tmp, insn))
+ return NULL_RTX;
+
+ return tmp;
+}
+
+/* Check the comparison COND to see if we can safely form an implicit set from
+ it. COND is either an EQ or NE comparison. */
+
+static bool
+implicit_set_cond_p (rtx cond)
+{
+ enum machine_mode mode = GET_MODE (XEXP (cond, 0));
+ rtx cst = XEXP (cond, 1);
+
+ /* We can't perform this optimization if either operand might be or might
+ contain a signed zero. */
+ if (HONOR_SIGNED_ZEROS (mode))
+ {
+ /* It is sufficient to check if CST is or contains a zero. We must
+ handle float, complex, and vector. If any subpart is a zero, then
+ the optimization can't be performed. */
+ /* ??? The complex and vector checks are not implemented yet. We just
+ always return zero for them. */
+ if (GET_CODE (cst) == CONST_DOUBLE)
+ {
+ REAL_VALUE_TYPE d;
+ REAL_VALUE_FROM_CONST_DOUBLE (d, cst);
+ if (REAL_VALUES_EQUAL (d, dconst0))
+ return 0;
+ }
+ else
+ return 0;
+ }
+
+ return gcse_constant_p (cst);
+}
+
+/* Find the implicit sets of a function. An "implicit set" is a constraint
+ on the value of a variable, implied by a conditional jump. For example,
+ following "if (x == 2)", the then branch may be optimized as though the
+ conditional performed an "explicit set", in this example, "x = 2". This
+ function records the set patterns that are implicit at the start of each
+ basic block. */
+
+static void
+find_implicit_sets (void)
+{
+ basic_block bb, dest;
+ unsigned int count;
+ rtx cond, new;
+
+ count = 0;
+ FOR_EACH_BB (bb)
+ /* Check for more than one successor. */
+ if (bb->succ && bb->succ->succ_next)
+ {
+ cond = fis_get_condition (BB_END (bb));
+
+ if (cond
+ && (GET_CODE (cond) == EQ || GET_CODE (cond) == NE)
+ && GET_CODE (XEXP (cond, 0)) == REG
+ && REGNO (XEXP (cond, 0)) >= FIRST_PSEUDO_REGISTER
+ && implicit_set_cond_p (cond))
+ {
+ dest = GET_CODE (cond) == EQ ? BRANCH_EDGE (bb)->dest
+ : FALLTHRU_EDGE (bb)->dest;
+
+ if (dest && ! dest->pred->pred_next
+ && dest != EXIT_BLOCK_PTR)
+ {
+ new = gen_rtx_SET (VOIDmode, XEXP (cond, 0),
+ XEXP (cond, 1));
+ implicit_sets[dest->index] = new;
+ if (gcse_file)
+ {
+ fprintf(gcse_file, "Implicit set of reg %d in ",
+ REGNO (XEXP (cond, 0)));
+ fprintf(gcse_file, "basic block %d\n", dest->index);
+ }
+ count++;
+ }
+ }
+ }
+
+ if (gcse_file)
+ fprintf (gcse_file, "Found %d implicit sets\n", count);
+}
+
/* Perform one copy/constant propagation pass.
- F is the first insn in the function.
- PASS is the pass count. */
+ PASS is the pass count. If CPROP_JUMPS is true, perform constant
+ propagation into conditional jumps. If BYPASS_JUMPS is true,
+ perform conditional jump bypassing optimizations. */
static int
-one_cprop_pass (pass, alter_jumps)
- int pass;
- int alter_jumps;
+one_cprop_pass (int pass, int cprop_jumps, int bypass_jumps)
{
int changed = 0;
const_prop_count = 0;
copy_prop_count = 0;
- local_cprop_pass (alter_jumps);
+ local_cprop_pass (cprop_jumps);
+
+ /* Determine implicit sets. */
+ implicit_sets = xcalloc (last_basic_block, sizeof (rtx));
+ find_implicit_sets ();
alloc_hash_table (max_cuid, &set_hash_table, 1);
compute_hash_table (&set_hash_table);
+
+ /* Free implicit_sets before peak usage. */
+ free (implicit_sets);
+ implicit_sets = NULL;
+
if (gcse_file)
dump_hash_table (gcse_file, "SET", &set_hash_table);
if (set_hash_table.n_elems > 0)
{
alloc_cprop_mem (last_basic_block, set_hash_table.n_elems);
compute_cprop_data ();
- changed = cprop (alter_jumps);
- if (alter_jumps)
+ changed = cprop (cprop_jumps);
+ if (bypass_jumps)
changed |= bypass_conditional_jumps ();
free_cprop_mem ();
}
@@ -4575,12 +4689,12 @@ one_cprop_pass (pass, alter_jumps)
if (gcse_file)
{
fprintf (gcse_file, "CPROP of %s, pass %d: %d bytes needed, ",
- current_function_name, pass, bytes_used);
+ current_function_name (), pass, bytes_used);
fprintf (gcse_file, "%d const props, %d copy props\n\n",
const_prop_count, copy_prop_count);
}
/* Global analysis may get into infinite loops for unreachable blocks. */
- if (changed && alter_jumps)
+ if (changed && cprop_jumps)
delete_unreachable_blocks ();
return changed;
@@ -4588,21 +4702,26 @@ one_cprop_pass (pass, alter_jumps)
/* Bypass conditional jumps. */
+/* The value of last_basic_block at the beginning of the jump_bypass
+ pass. The use of redirect_edge_and_branch_force may introduce new
+ basic blocks, but the data flow analysis is only valid for basic
+ block indices less than bypass_last_basic_block. */
+
+static int bypass_last_basic_block;
+
/* Find a set of REGNO to a constant that is available at the end of basic
block BB. Returns NULL if no such set is found. Based heavily upon
find_avail_set. */
static struct expr *
-find_bypass_set (regno, bb)
- int regno;
- int bb;
+find_bypass_set (int regno, int bb)
{
struct expr *result = 0;
for (;;)
{
rtx src;
- struct expr *set = lookup_set (regno, NULL_RTX, &set_hash_table);
+ struct expr *set = lookup_set (regno, &set_hash_table);
while (set)
{
@@ -4618,7 +4737,7 @@ find_bypass_set (regno, bb)
abort ();
src = SET_SRC (set->expr);
- if (CONSTANT_P (src))
+ if (gcse_constant_p (src))
result = set;
if (GET_CODE (src) != REG)
@@ -4637,9 +4756,7 @@ find_bypass_set (regno, bb)
valid prior to commit_edge_insertions. */
static bool
-reg_killed_on_edge (reg, e)
- rtx reg;
- edge e;
+reg_killed_on_edge (rtx reg, edge e)
{
rtx insn;
@@ -4656,18 +4773,17 @@ reg_killed_on_edge (reg, e)
JUMP. Otherwise, SETCC is NULL, and JUMP is the first insn of BB.
Returns nonzero if a change was made.
- During the jump bypassing pass, we may place copies of SETCC instuctions
+ During the jump bypassing pass, we may place copies of SETCC instructions
on CFG edges. The following routine must be careful to pay attention to
these inserted insns when performing its transformations. */
static int
-bypass_block (bb, setcc, jump)
- basic_block bb;
- rtx setcc, jump;
+bypass_block (basic_block bb, rtx setcc, rtx jump)
{
rtx insn, note;
edge e, enext, edest;
int i, change;
+ int may_be_loop_header;
insn = (setcc != NULL) ? setcc : jump;
@@ -4678,10 +4794,32 @@ bypass_block (bb, setcc, jump)
if (note)
find_used_regs (&XEXP (note, 0), NULL);
+ may_be_loop_header = false;
+ for (e = bb->pred; e; e = e->pred_next)
+ if (e->flags & EDGE_DFS_BACK)
+ {
+ may_be_loop_header = true;
+ break;
+ }
+
change = 0;
for (e = bb->pred; e; e = enext)
{
enext = e->pred_next;
+ if (e->flags & EDGE_COMPLEX)
+ continue;
+
+ /* We can't redirect edges from new basic blocks. */
+ if (e->src->index >= bypass_last_basic_block)
+ continue;
+
+ /* The irreducible loops created by redirecting of edges entering the
+ loop from outside would decrease effectiveness of some of the following
+ optimizations, so prevent this. */
+ if (may_be_loop_header
+ && !(e->flags & EDGE_DFS_BACK))
+ continue;
+
for (i = 0; i < reg_use_count; i++)
{
struct reg_use *reg_used = &reg_use_table[i];
@@ -4712,7 +4850,7 @@ bypass_block (bb, setcc, jump)
new = simplify_replace_rtx (src, reg_used->reg_rtx,
SET_SRC (set->expr));
- /* Jump bypassing may have already placed instructions on
+ /* Jump bypassing may have already placed instructions on
edges of the CFG. We can't bypass an outgoing edge that
has instructions associated with it, as these insns won't
get executed if the incoming edge is redirected. */
@@ -4736,12 +4874,27 @@ bypass_block (bb, setcc, jump)
else
dest = NULL;
- /* Once basic block indices are stable, we should be able
- to use redirect_edge_and_branch_force instead. */
- old_dest = e->dest;
- if (dest != NULL && dest != old_dest
- && redirect_edge_and_branch (e, dest))
+ /* Avoid unification of the edge with other edges from original
+ branch. We would end up emitting the instruction on "both"
+ edges. */
+
+ if (dest && setcc && !CC0_P (SET_DEST (PATTERN (setcc))))
{
+ edge e2;
+ for (e2 = e->src->succ; e2; e2 = e2->succ_next)
+ if (e2->dest == dest)
+ break;
+ if (e2)
+ dest = NULL;
+ }
+
+ old_dest = e->dest;
+ if (dest != NULL
+ && dest != old_dest
+ && dest != EXIT_BLOCK_PTR)
+ {
+ redirect_edge_and_branch_force (e, dest);
+
/* Copy the register setter to the redirected edge.
Don't copy CC0 setters, as CC0 is dead after jump. */
if (setcc)
@@ -4770,10 +4923,12 @@ bypass_block (bb, setcc, jump)
/* Find basic blocks with more than one predecessor that only contain a
single conditional jump. If the result of the comparison is known at
compile-time from any incoming edge, redirect that edge to the
- appropriate target. Returns nonzero if a change was made. */
+ appropriate target. Returns nonzero if a change was made.
+
+ This function is now mis-named, because we also handle indirect jumps. */
static int
-bypass_conditional_jumps ()
+bypass_conditional_jumps (void)
{
basic_block bb;
int changed;
@@ -4785,6 +4940,9 @@ bypass_conditional_jumps ()
if (ENTRY_BLOCK_PTR->next_bb == EXIT_BLOCK_PTR)
return 0;
+ bypass_last_basic_block = last_basic_block;
+ mark_dfs_back_edges ();
+
changed = 0;
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb->next_bb,
EXIT_BLOCK_PTR, next_bb)
@@ -4793,8 +4951,8 @@ bypass_conditional_jumps ()
if (bb->pred && bb->pred->pred_next)
{
setcc = NULL_RTX;
- for (insn = bb->head;
- insn != NULL && insn != NEXT_INSN (bb->end);
+ for (insn = BB_HEAD (bb);
+ insn != NULL && insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
if (GET_CODE (insn) == INSN)
{
@@ -4811,7 +4969,8 @@ bypass_conditional_jumps ()
}
else if (GET_CODE (insn) == JUMP_INSN)
{
- if (any_condjump_p (insn) && onlyjump_p (insn))
+ if ((any_condjump_p (insn) || computed_jump_p (insn))
+ && onlyjump_p (insn))
changed |= bypass_block (bb, setcc, insn);
break;
}
@@ -4821,7 +4980,7 @@ bypass_conditional_jumps ()
}
/* If we bypassed any register setting insns, we inserted a
- copy on the redirected edge. These need to be commited. */
+ copy on the redirected edge. These need to be committed. */
if (changed)
commit_edge_insertions();
@@ -4867,8 +5026,7 @@ static sbitmap pre_redundant_insns;
/* Allocate vars used for PRE analysis. */
static void
-alloc_pre_mem (n_blocks, n_exprs)
- int n_blocks, n_exprs;
+alloc_pre_mem (int n_blocks, int n_exprs)
{
transp = sbitmap_vector_alloc (n_blocks, n_exprs);
comp = sbitmap_vector_alloc (n_blocks, n_exprs);
@@ -4888,7 +5046,7 @@ alloc_pre_mem (n_blocks, n_exprs)
/* Free vars used for PRE analysis. */
static void
-free_pre_mem ()
+free_pre_mem (void)
{
sbitmap_vector_free (transp);
sbitmap_vector_free (comp);
@@ -4916,7 +5074,7 @@ free_pre_mem ()
/* Top level routine to do the dataflow analysis needed by PRE. */
static void
-compute_pre_data ()
+compute_pre_data (void)
{
sbitmap trapping_expr;
basic_block bb;
@@ -4987,11 +5145,7 @@ compute_pre_data ()
the closest such expression. */
static int
-pre_expr_reaches_here_p_work (occr_bb, expr, bb, visited)
- basic_block occr_bb;
- struct expr *expr;
- basic_block bb;
- char *visited;
+pre_expr_reaches_here_p_work (basic_block occr_bb, struct expr *expr, basic_block bb, char *visited)
{
edge pred;
@@ -5036,13 +5190,10 @@ pre_expr_reaches_here_p_work (occr_bb, expr, bb, visited)
memory allocated for that function is returned. */
static int
-pre_expr_reaches_here_p (occr_bb, expr, bb)
- basic_block occr_bb;
- struct expr *expr;
- basic_block bb;
+pre_expr_reaches_here_p (basic_block occr_bb, struct expr *expr, basic_block bb)
{
int rval;
- char *visited = (char *) xcalloc (last_basic_block, 1);
+ char *visited = xcalloc (last_basic_block, 1);
rval = pre_expr_reaches_here_p_work (occr_bb, expr, bb, visited);
@@ -5056,8 +5207,7 @@ pre_expr_reaches_here_p (occr_bb, expr, bb)
the value of BB. */
static rtx
-process_insert_insn (expr)
- struct expr *expr;
+process_insert_insn (struct expr *expr)
{
rtx reg = expr->reaching_reg;
rtx exp = copy_rtx (expr->expr);
@@ -5091,12 +5241,9 @@ process_insert_insn (expr)
no sense for code hoisting. */
static void
-insert_insn_end_bb (expr, bb, pre)
- struct expr *expr;
- basic_block bb;
- int pre;
+insert_insn_end_bb (struct expr *expr, basic_block bb, int pre)
{
- rtx insn = bb->end;
+ rtx insn = BB_END (bb);
rtx new_insn;
rtx reg = expr->reaching_reg;
int regno = REGNO (reg);
@@ -5111,7 +5258,7 @@ insert_insn_end_bb (expr, bb, pre)
pat_end = NEXT_INSN (pat_end);
/* If the last insn is a jump, insert EXPR in front [taking care to
- handle cc0, etc. properly]. Similary we need to care trapping
+ handle cc0, etc. properly]. Similarly we need to care trapping
instructions in presence of non-call exceptions. */
if (GET_CODE (insn) == JUMP_INSN
@@ -5152,7 +5299,7 @@ insert_insn_end_bb (expr, bb, pre)
}
#endif
/* FIXME: What if something in cc0/jump uses value set in new insn? */
- new_insn = emit_insn_before (pat, insn);
+ new_insn = emit_insn_before_noloc (pat, insn);
}
/* Likewise if the last insn is a call, as will happen in the presence
@@ -5163,7 +5310,7 @@ insert_insn_end_bb (expr, bb, pre)
/* Keeping in mind SMALL_REGISTER_CLASSES and parameters in registers,
we search backward and place the instructions before the first
parameter is loaded. Do this for everyone for consistency and a
- presumtion that we'll get better code elsewhere as well.
+ presumption that we'll get better code elsewhere as well.
It should always be the case that we can put these instructions
anywhere in the basic block with performing PRE optimizations.
@@ -5177,7 +5324,7 @@ insert_insn_end_bb (expr, bb, pre)
/* Since different machines initialize their parameter registers
in different orders, assume nothing. Collect the set of all
parameter registers. */
- insn = find_first_parameter_load (insn, bb->head);
+ insn = find_first_parameter_load (insn, BB_HEAD (bb));
/* If we found all the parameter loads, then we want to insert
before the first parameter load.
@@ -5191,10 +5338,10 @@ insert_insn_end_bb (expr, bb, pre)
|| NOTE_INSN_BASIC_BLOCK_P (insn))
insn = NEXT_INSN (insn);
- new_insn = emit_insn_before (pat, insn);
+ new_insn = emit_insn_before_noloc (pat, insn);
}
else
- new_insn = emit_insn_after (pat, insn);
+ new_insn = emit_insn_after_noloc (pat, insn);
while (1)
{
@@ -5223,9 +5370,7 @@ insert_insn_end_bb (expr, bb, pre)
the expressions fully redundant. */
static int
-pre_edge_insert (edge_list, index_map)
- struct edge_list *edge_list;
- struct expr **index_map;
+pre_edge_insert (struct edge_list *edge_list, struct expr **index_map)
{
int e, i, j, num_edges, set_size, did_insert = 0;
sbitmap *inserted;
@@ -5304,26 +5449,90 @@ pre_edge_insert (edge_list, index_map)
return did_insert;
}
-/* Copy the result of INSN to REG. INDX is the expression number. */
+/* Copy the result of EXPR->EXPR generated by INSN to EXPR->REACHING_REG.
+ Given "old_reg <- expr" (INSN), instead of adding after it
+ reaching_reg <- old_reg
+ it's better to do the following:
+ reaching_reg <- expr
+ old_reg <- reaching_reg
+ because this way copy propagation can discover additional PRE
+ opportunities. But if this fails, we try the old way.
+ When "expr" is a store, i.e.
+ given "MEM <- old_reg", instead of adding after it
+ reaching_reg <- old_reg
+ it's better to add it before as follows:
+ reaching_reg <- old_reg
+ MEM <- reaching_reg. */
static void
-pre_insert_copy_insn (expr, insn)
- struct expr *expr;
- rtx insn;
+pre_insert_copy_insn (struct expr *expr, rtx insn)
{
rtx reg = expr->reaching_reg;
int regno = REGNO (reg);
int indx = expr->bitmap_index;
- rtx set = single_set (insn);
- rtx new_insn;
+ rtx pat = PATTERN (insn);
+ rtx set, new_insn;
+ rtx old_reg;
+ int i;
- if (!set)
+ /* This block matches the logic in hash_scan_insn. */
+ if (GET_CODE (pat) == SET)
+ set = pat;
+ else if (GET_CODE (pat) == PARALLEL)
+ {
+ /* Search through the parallel looking for the set whose
+ source was the expression that we're interested in. */
+ set = NULL_RTX;
+ for (i = 0; i < XVECLEN (pat, 0); i++)
+ {
+ rtx x = XVECEXP (pat, 0, i);
+ if (GET_CODE (x) == SET
+ && expr_equiv_p (SET_SRC (x), expr->expr))
+ {
+ set = x;
+ break;
+ }
+ }
+ }
+ else
abort ();
- new_insn = emit_insn_after (gen_move_insn (reg, SET_DEST (set)), insn);
+ if (GET_CODE (SET_DEST (set)) == REG)
+ {
+ old_reg = SET_DEST (set);
+ /* Check if we can modify the set destination in the original insn. */
+ if (validate_change (insn, &SET_DEST (set), reg, 0))
+ {
+ new_insn = gen_move_insn (old_reg, reg);
+ new_insn = emit_insn_after (new_insn, insn);
+
+ /* Keep register set table up to date. */
+ replace_one_set (REGNO (old_reg), insn, new_insn);
+ record_one_set (regno, insn);
+ }
+ else
+ {
+ new_insn = gen_move_insn (reg, old_reg);
+ new_insn = emit_insn_after (new_insn, insn);
+
+ /* Keep register set table up to date. */
+ record_one_set (regno, new_insn);
+ }
+ }
+ else /* This is possible only in case of a store to memory. */
+ {
+ old_reg = SET_SRC (set);
+ new_insn = gen_move_insn (reg, old_reg);
+
+ /* Check if we can modify the set source in the original insn. */
+ if (validate_change (insn, &SET_SRC (set), reg, 0))
+ new_insn = emit_insn_before (new_insn, insn);
+ else
+ new_insn = emit_insn_after (new_insn, insn);
- /* Keep register set table up to date. */
- record_one_set (regno, new_insn);
+ /* Keep register set table up to date. */
+ record_one_set (regno, new_insn);
+ }
gcse_create_count++;
@@ -5332,16 +5541,15 @@ pre_insert_copy_insn (expr, insn)
"PRE: bb %d, insn %d, copy expression %d in insn %d to reg %d\n",
BLOCK_NUM (insn), INSN_UID (new_insn), indx,
INSN_UID (insn), regno);
- update_ld_motion_stores (expr);
}
/* Copy available expressions that reach the redundant expression
to `reaching_reg'. */
static void
-pre_insert_copies ()
+pre_insert_copies (void)
{
- unsigned int i;
+ unsigned int i, added_copy;
struct expr *expr;
struct occr *occr;
struct occr *avail;
@@ -5362,6 +5570,9 @@ pre_insert_copies ()
expression wasn't deleted anywhere. */
if (expr->reaching_reg == NULL)
continue;
+
+ /* Set when we add a copy for that expression. */
+ added_copy = 0;
for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
{
@@ -5386,19 +5597,23 @@ pre_insert_copies ()
BLOCK_FOR_INSN (occr->insn)))
continue;
+ added_copy = 1;
+
/* Copy the result of avail to reaching_reg. */
pre_insert_copy_insn (expr, insn);
avail->copied_p = 1;
}
}
+
+ if (added_copy)
+ update_ld_motion_stores (expr);
}
}
/* Emit move from SRC to DEST noting the equivalence with expression computed
in INSN. */
static rtx
-gcse_emit_move_after (src, dest, insn)
- rtx src, dest, insn;
+gcse_emit_move_after (rtx src, rtx dest, rtx insn)
{
rtx new;
rtx set = single_set (insn), set2;
@@ -5432,7 +5647,7 @@ gcse_emit_move_after (src, dest, insn)
Returns nonzero if a change is made. */
static int
-pre_delete ()
+pre_delete (void)
{
unsigned int i;
int changed;
@@ -5441,7 +5656,9 @@ pre_delete ()
changed = 0;
for (i = 0; i < expr_hash_table.size; i++)
- for (expr = expr_hash_table.table[i]; expr != NULL; expr = expr->next_same_hash)
+ for (expr = expr_hash_table.table[i];
+ expr != NULL;
+ expr = expr->next_same_hash)
{
int indx = expr->bitmap_index;
@@ -5454,12 +5671,10 @@ pre_delete ()
rtx set;
basic_block bb = BLOCK_FOR_INSN (insn);
- if (TEST_BIT (pre_delete_map[bb->index], indx))
+ /* We only delete insns that have a single_set. */
+ if (TEST_BIT (pre_delete_map[bb->index], indx)
+ && (set = single_set (insn)) != 0)
{
- set = single_set (insn);
- if (! set)
- abort ();
-
/* Create a pseudo-reg to store the result of reaching
expressions into. Get the mode for the new pseudo from
the mode of the original destination pseudo. */
@@ -5510,7 +5725,7 @@ pre_delete ()
redundancies. */
static int
-pre_gcse ()
+pre_gcse (void)
{
unsigned int i;
int did_insert, changed;
@@ -5520,7 +5735,7 @@ pre_gcse ()
/* Compute a mapping from expression number (`bitmap_index') to
hash table entry. */
- index_map = (struct expr **) xcalloc (expr_hash_table.n_elems, sizeof (struct expr *));
+ index_map = xcalloc (expr_hash_table.n_elems, sizeof (struct expr *));
for (i = 0; i < expr_hash_table.size; i++)
for (expr = expr_hash_table.table[i]; expr != NULL; expr = expr->next_same_hash)
index_map[expr->bitmap_index] = expr;
@@ -5557,8 +5772,7 @@ pre_gcse ()
Return nonzero if a change was made. */
static int
-one_pre_gcse_pass (pass)
- int pass;
+one_pre_gcse_pass (int pass)
{
int changed = 0;
@@ -5591,7 +5805,7 @@ one_pre_gcse_pass (pass)
if (gcse_file)
{
fprintf (gcse_file, "\nPRE GCSE of %s, pass %d: %d bytes needed, ",
- current_function_name, pass, bytes_used);
+ current_function_name (), pass, bytes_used);
fprintf (gcse_file, "%d substs, %d insns created\n",
gcse_subst_count, gcse_create_count);
}
@@ -5612,9 +5826,7 @@ one_pre_gcse_pass (pass)
necessary REG_LABEL notes. */
static void
-add_label_notes (x, insn)
- rtx x;
- rtx insn;
+add_label_notes (rtx x, rtx insn)
{
enum rtx_code code = GET_CODE (x);
int i, j;
@@ -5623,7 +5835,7 @@ add_label_notes (x, insn)
if (code == LABEL_REF && !LABEL_REF_NONLOCAL_P (x))
{
/* This code used to ignore labels that referred to dispatch tables to
- avoid flow generating (slighly) worse code.
+ avoid flow generating (slightly) worse code.
We no longer ignore such label references (see LABEL_REF handling in
mark_jump_label for additional information). */
@@ -5659,7 +5871,7 @@ add_label_notes (x, insn)
EH table sizes, this may not be worthwhile. */
static void
-compute_transpout ()
+compute_transpout (void)
{
basic_block bb;
unsigned int i;
@@ -5672,7 +5884,7 @@ compute_transpout ()
/* Note that flow inserted a nop a the end of basic blocks that
end in call instructions for reasons other than abnormal
control flow. */
- if (GET_CODE (bb->end) != CALL_INSN)
+ if (GET_CODE (BB_END (bb)) != CALL_INSN)
continue;
for (i = 0; i < expr_hash_table.size; i++)
@@ -5700,10 +5912,7 @@ compute_transpout ()
We ignore hard registers. */
static void
-invalidate_nonnull_info (x, setter, data)
- rtx x;
- rtx setter ATTRIBUTE_UNUSED;
- void *data;
+invalidate_nonnull_info (rtx x, rtx setter ATTRIBUTE_UNUSED, void *data)
{
unsigned int regno;
struct null_pointer_info *npi = (struct null_pointer_info *) data;
@@ -5728,12 +5937,9 @@ invalidate_nonnull_info (x, setter, data)
they are not our responsibility to free. */
static int
-delete_null_pointer_checks_1 (block_reg, nonnull_avin,
- nonnull_avout, npi)
- unsigned int *block_reg;
- sbitmap *nonnull_avin;
- sbitmap *nonnull_avout;
- struct null_pointer_info *npi;
+delete_null_pointer_checks_1 (unsigned int *block_reg, sbitmap *nonnull_avin,
+ sbitmap *nonnull_avout,
+ struct null_pointer_info *npi)
{
basic_block bb, current_block;
sbitmap *nonnull_local = npi->nonnull_local;
@@ -5760,8 +5966,8 @@ delete_null_pointer_checks_1 (block_reg, nonnull_avin,
/* Scan each insn in the basic block looking for memory references and
register sets. */
- stop_insn = NEXT_INSN (current_block->end);
- for (insn = current_block->head;
+ stop_insn = NEXT_INSN (BB_END (current_block));
+ for (insn = BB_HEAD (current_block);
insn != stop_insn;
insn = NEXT_INSN (insn))
{
@@ -5808,7 +6014,7 @@ delete_null_pointer_checks_1 (block_reg, nonnull_avin,
}
/* Now compute global properties based on the local properties. This
- is a classic global availablity algorithm. */
+ is a classic global availability algorithm. */
compute_available (nonnull_local, nonnull_killed,
nonnull_avout, nonnull_avin);
@@ -5816,7 +6022,7 @@ delete_null_pointer_checks_1 (block_reg, nonnull_avin,
against zero. */
FOR_EACH_BB (bb)
{
- rtx last_insn = bb->end;
+ rtx last_insn = BB_END (bb);
rtx condition, earliest;
int compare_and_branch;
@@ -5828,7 +6034,7 @@ delete_null_pointer_checks_1 (block_reg, nonnull_avin,
continue;
/* LAST_INSN is a conditional jump. Get its condition. */
- condition = get_condition (last_insn, &earliest);
+ condition = get_condition (last_insn, &earliest, false);
/* If we can't determine the condition then skip. */
if (! condition)
@@ -5862,11 +6068,13 @@ delete_null_pointer_checks_1 (block_reg, nonnull_avin,
something_changed = 1;
delete_insn (last_insn);
+#ifdef HAVE_cc0
if (compare_and_branch == 2)
delete_insn (earliest);
+#endif
purge_dead_edges (bb);
- /* Don't check this block again. (Note that BLOCK_END is
+ /* Don't check this block again. (Note that BB_END is
invalid here; we deleted the last instruction in the
block.) */
block_reg[bb->index] = 0;
@@ -5889,7 +6097,7 @@ delete_null_pointer_checks_1 (block_reg, nonnull_avin,
reference of that form, then we know the register can not have the value
zero at the conditional branch.
- So we merely need to compute the local properies and propagate that data
+ So we merely need to compute the local properties and propagate that data
around the cfg, then optimize where possible.
We run this pass two times. Once before CSE, then again after CSE. This
@@ -5900,36 +6108,24 @@ delete_null_pointer_checks_1 (block_reg, nonnull_avin,
This could probably be integrated with global cprop with a little work. */
int
-delete_null_pointer_checks (f)
- rtx f ATTRIBUTE_UNUSED;
+delete_null_pointer_checks (rtx f ATTRIBUTE_UNUSED)
{
sbitmap *nonnull_avin, *nonnull_avout;
unsigned int *block_reg;
basic_block bb;
int reg;
int regs_per_pass;
- int max_reg;
+ int max_reg = max_reg_num ();
struct null_pointer_info npi;
int something_changed = 0;
- /* If we have only a single block, then there's nothing to do. */
- if (n_basic_blocks <= 1)
- return 0;
-
- /* Trying to perform global optimizations on flow graphs which have
- a high connectivity will take a long time and is unlikely to be
- particularly useful.
-
- In normal circumstances a cfg should have about twice as many edges
- as blocks. But we do not want to punish small functions which have
- a couple switch statements. So we require a relatively large number
- of basic blocks and the ratio of edges to blocks to be high. */
- if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
+ /* If we have only a single block, or it is too expensive, give up. */
+ if (n_basic_blocks <= 1
+ || is_too_expensive (_ ("NULL pointer checks disabled")))
return 0;
/* We need four bitmaps, each with a bit for each register in each
basic block. */
- max_reg = max_reg_num ();
regs_per_pass = get_bitmap_width (4, last_basic_block, max_reg);
/* Allocate bitmaps to hold local and global properties. */
@@ -5941,10 +6137,10 @@ delete_null_pointer_checks (f)
/* Go through the basic blocks, seeing whether or not each block
ends with a conditional branch whose condition is a comparison
against zero. Record the register compared in BLOCK_REG. */
- block_reg = (unsigned int *) xcalloc (last_basic_block, sizeof (int));
+ block_reg = xcalloc (last_basic_block, sizeof (int));
FOR_EACH_BB (bb)
{
- rtx last_insn = bb->end;
+ rtx last_insn = BB_END (bb);
rtx condition, earliest, reg;
/* We only want conditional branches. */
@@ -5954,7 +6150,7 @@ delete_null_pointer_checks (f)
continue;
/* LAST_INSN is a conditional jump. Get its condition. */
- condition = get_condition (last_insn, &earliest);
+ condition = get_condition (last_insn, &earliest, false);
/* If we were unable to get the condition, or it is not an equality
comparison against zero then there's nothing we can do. */
@@ -6005,9 +6201,6 @@ static sbitmap *hoist_vbeout;
/* Hoistable expressions. */
static sbitmap *hoist_exprs;
-/* Dominator bitmaps. */
-dominance_info dominators;
-
/* ??? We could compute post dominators and run this algorithm in
reverse to perform tail merging, doing so would probably be
more effective than the tail merging code in jump.c.
@@ -6018,8 +6211,7 @@ dominance_info dominators;
/* Allocate vars used for code hoisting analysis. */
static void
-alloc_code_hoist_mem (n_blocks, n_exprs)
- int n_blocks, n_exprs;
+alloc_code_hoist_mem (int n_blocks, int n_exprs)
{
antloc = sbitmap_vector_alloc (n_blocks, n_exprs);
transp = sbitmap_vector_alloc (n_blocks, n_exprs);
@@ -6034,7 +6226,7 @@ alloc_code_hoist_mem (n_blocks, n_exprs)
/* Free vars used for code hoisting analysis. */
static void
-free_code_hoist_mem ()
+free_code_hoist_mem (void)
{
sbitmap_vector_free (antloc);
sbitmap_vector_free (transp);
@@ -6045,7 +6237,7 @@ free_code_hoist_mem ()
sbitmap_vector_free (hoist_exprs);
sbitmap_vector_free (transpout);
- free_dominance_info (dominators);
+ free_dominance_info (CDI_DOMINATORS);
}
/* Compute the very busy expressions at entry/exit from each block.
@@ -6054,7 +6246,7 @@ free_code_hoist_mem ()
compute the expression. */
static void
-compute_code_hoist_vbeinout ()
+compute_code_hoist_vbeinout (void)
{
int changed, passes;
basic_block bb;
@@ -6089,12 +6281,12 @@ compute_code_hoist_vbeinout ()
/* Top level routine to do the dataflow analysis needed by code hoisting. */
static void
-compute_code_hoist_data ()
+compute_code_hoist_data (void)
{
compute_local_properties (transp, comp, antloc, &expr_hash_table);
compute_transpout ();
compute_code_hoist_vbeinout ();
- dominators = calculate_dominance_info (CDI_DOMINATORS);
+ calculate_dominance_info (CDI_DOMINATORS);
if (gcse_file)
fprintf (gcse_file, "\n");
}
@@ -6113,11 +6305,7 @@ compute_code_hoist_data ()
paths. */
static int
-hoist_expr_reaches_here_p (expr_bb, expr_index, bb, visited)
- basic_block expr_bb;
- int expr_index;
- basic_block bb;
- char *visited;
+hoist_expr_reaches_here_p (basic_block expr_bb, int expr_index, basic_block bb, char *visited)
{
edge pred;
int visited_allocated_locally = 0;
@@ -6164,7 +6352,7 @@ hoist_expr_reaches_here_p (expr_bb, expr_index, bb, visited)
/* Actually perform code hoisting. */
static void
-hoist_code ()
+hoist_code (void)
{
basic_block bb, dominated;
basic_block *domby;
@@ -6178,7 +6366,7 @@ hoist_code ()
/* Compute a mapping from expression number (`bitmap_index') to
hash table entry. */
- index_map = (struct expr **) xcalloc (expr_hash_table.n_elems, sizeof (struct expr *));
+ index_map = xcalloc (expr_hash_table.n_elems, sizeof (struct expr *));
for (i = 0; i < expr_hash_table.size; i++)
for (expr = expr_hash_table.table[i]; expr != NULL; expr = expr->next_same_hash)
index_map[expr->bitmap_index] = expr;
@@ -6190,7 +6378,7 @@ hoist_code ()
int found = 0;
int insn_inserted_p;
- domby_len = get_dominated_by (dominators, bb, &domby);
+ domby_len = get_dominated_by (CDI_DOMINATORS, bb, &domby);
/* Examine each expression that is very busy at the exit of this
block. These are the potentially hoistable expressions. */
for (i = 0; i < hoist_vbeout[bb->index]->n_bits; i++)
@@ -6232,7 +6420,7 @@ hoist_code ()
to avoid any possible code expansion due to register
allocation issues; however experiments have shown that
the vast majority of hoistable expressions are only movable
- from two successors, so raising this threshhold is likely
+ from two successors, so raising this threshold is likely
to nullify any benefit we get from code hoisting. */
if (hoistable > 1)
{
@@ -6244,7 +6432,7 @@ hoist_code ()
/* If we found nothing to hoist, then quit now. */
if (! found)
{
- free (domby);
+ free (domby);
continue;
}
@@ -6330,7 +6518,7 @@ hoist_code ()
Return nonzero if a change was made. */
static int
-one_code_hoisting_pass ()
+one_code_hoisting_pass (void)
{
int changed = 0;
@@ -6381,30 +6569,31 @@ one_code_hoisting_pass ()
doesn't find one, we create one and initialize it. */
static struct ls_expr *
-ldst_entry (x)
- rtx x;
+ldst_entry (rtx x)
{
+ int do_not_record_p = 0;
struct ls_expr * ptr;
+ unsigned int hash;
- for (ptr = first_ls_expr(); ptr != NULL; ptr = next_ls_expr (ptr))
- if (expr_equiv_p (ptr->pattern, x))
- break;
+ hash = hash_expr_1 (x, GET_MODE (x), & do_not_record_p);
- if (!ptr)
- {
- ptr = (struct ls_expr *) xmalloc (sizeof (struct ls_expr));
+ for (ptr = pre_ldst_mems; ptr != NULL; ptr = ptr->next)
+ if (ptr->hash_index == hash && expr_equiv_p (ptr->pattern, x))
+ return ptr;
- ptr->next = pre_ldst_mems;
- ptr->expr = NULL;
- ptr->pattern = x;
- ptr->loads = NULL_RTX;
- ptr->stores = NULL_RTX;
- ptr->reaching_reg = NULL_RTX;
- ptr->invalid = 0;
- ptr->index = 0;
- ptr->hash_index = 0;
- pre_ldst_mems = ptr;
- }
+ ptr = xmalloc (sizeof (struct ls_expr));
+
+ ptr->next = pre_ldst_mems;
+ ptr->expr = NULL;
+ ptr->pattern = x;
+ ptr->pattern_regs = NULL_RTX;
+ ptr->loads = NULL_RTX;
+ ptr->stores = NULL_RTX;
+ ptr->reaching_reg = NULL_RTX;
+ ptr->invalid = 0;
+ ptr->index = 0;
+ ptr->hash_index = hash;
+ pre_ldst_mems = ptr;
return ptr;
}
@@ -6412,8 +6601,7 @@ ldst_entry (x)
/* Free up an individual ldst entry. */
static void
-free_ldst_entry (ptr)
- struct ls_expr * ptr;
+free_ldst_entry (struct ls_expr * ptr)
{
free_INSN_LIST_list (& ptr->loads);
free_INSN_LIST_list (& ptr->stores);
@@ -6424,7 +6612,7 @@ free_ldst_entry (ptr)
/* Free up all memory associated with the ldst list. */
static void
-free_ldst_mems ()
+free_ldst_mems (void)
{
while (pre_ldst_mems)
{
@@ -6441,8 +6629,7 @@ free_ldst_mems ()
/* Dump debugging info about the ldst list. */
static void
-print_ldst_list (file)
- FILE * file;
+print_ldst_list (FILE * file)
{
struct ls_expr * ptr;
@@ -6477,8 +6664,7 @@ print_ldst_list (file)
/* Returns 1 if X is in the list of ldst only expressions. */
static struct ls_expr *
-find_rtx_in_ldst (x)
- rtx x;
+find_rtx_in_ldst (rtx x)
{
struct ls_expr * ptr;
@@ -6492,7 +6678,7 @@ find_rtx_in_ldst (x)
/* Assign each element of the list of mems a monotonically increasing value. */
static int
-enumerate_ldsts ()
+enumerate_ldsts (void)
{
struct ls_expr * ptr;
int n = 0;
@@ -6506,16 +6692,15 @@ enumerate_ldsts ()
/* Return first item in the list. */
static inline struct ls_expr *
-first_ls_expr ()
+first_ls_expr (void)
{
return pre_ldst_mems;
}
-/* Return the next item in ther list after the specified one. */
+/* Return the next item in the list after the specified one. */
static inline struct ls_expr *
-next_ls_expr (ptr)
- struct ls_expr * ptr;
+next_ls_expr (struct ls_expr * ptr)
{
return ptr->next;
}
@@ -6527,8 +6712,7 @@ next_ls_expr (ptr)
ld_motion list, otherwise we let the usual aliasing take care of it. */
static int
-simple_mem (x)
- rtx x;
+simple_mem (rtx x)
{
if (GET_CODE (x) != MEM)
return 0;
@@ -6539,10 +6723,23 @@ simple_mem (x)
if (GET_MODE (x) == BLKmode)
return 0;
- if (!rtx_varies_p (XEXP (x, 0), 0))
- return 1;
+ /* If we are handling exceptions, we must be careful with memory references
+ that may trap. If we are not, the behavior is undefined, so we may just
+ continue. */
+ if (flag_non_call_exceptions && may_trap_p (x))
+ return 0;
- return 0;
+ if (side_effects_p (x))
+ return 0;
+
+ /* Do not consider function arguments passed on stack. */
+ if (reg_mentioned_p (stack_pointer_rtx, x))
+ return 0;
+
+ if (flag_float_store && FLOAT_MODE_P (GET_MODE (x)))
+ return 0;
+
+ return 1;
}
/* Make sure there isn't a buried reference in this pattern anywhere.
@@ -6554,8 +6751,7 @@ simple_mem (x)
fix it up. */
static void
-invalidate_any_buried_refs (x)
- rtx x;
+invalidate_any_buried_refs (rtx x)
{
const char * fmt;
int i, j;
@@ -6581,14 +6777,16 @@ invalidate_any_buried_refs (x)
}
}
-/* Find all the 'simple' MEMs which are used in LOADs and STORES. Simple
- being defined as MEM loads and stores to symbols, with no
- side effects and no registers in the expression. If there are any
- uses/defs which don't match this criteria, it is invalidated and
- trimmed out later. */
+/* Find all the 'simple' MEMs which are used in LOADs and STORES. Simple
+ being defined as MEM loads and stores to symbols, with no side effects
+ and no registers in the expression. For a MEM destination, we also
+ check that the insn is still valid if we replace the destination with a
+ REG, as is done in update_ld_motion_stores. If there are any uses/defs
+ which don't match this criteria, they are invalidated and trimmed out
+ later. */
static void
-compute_ld_motion_mems ()
+compute_ld_motion_mems (void)
{
struct ls_expr * ptr;
basic_block bb;
@@ -6598,11 +6796,11 @@ compute_ld_motion_mems ()
FOR_EACH_BB (bb)
{
- for (insn = bb->head;
- insn && insn != NEXT_INSN (bb->end);
+ for (insn = BB_HEAD (bb);
+ insn && insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
{
- if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+ if (INSN_P (insn))
{
if (GET_CODE (PATTERN (insn)) == SET)
{
@@ -6633,7 +6831,10 @@ compute_ld_motion_mems ()
ptr = ldst_entry (dest);
if (GET_CODE (src) != MEM
- && GET_CODE (src) != ASM_OPERANDS)
+ && GET_CODE (src) != ASM_OPERANDS
+ /* Check for REG manually since want_to_gcse_p
+ returns 0 for all REGs. */
+ && (REG_P (src) || want_to_gcse_p (src)))
ptr->stores = alloc_INSN_LIST (insn, ptr->stores);
else
ptr->invalid = 1;
@@ -6650,58 +6851,43 @@ compute_ld_motion_mems ()
expression list for pre gcse. */
static void
-trim_ld_motion_mems ()
+trim_ld_motion_mems (void)
{
- struct ls_expr * last = NULL;
- struct ls_expr * ptr = first_ls_expr ();
+ struct ls_expr * * last = & pre_ldst_mems;
+ struct ls_expr * ptr = pre_ldst_mems;
while (ptr != NULL)
{
- int del = ptr->invalid;
- struct expr * expr = NULL;
+ struct expr * expr;
/* Delete if entry has been made invalid. */
- if (!del)
+ if (! ptr->invalid)
{
- unsigned int i;
-
- del = 1;
/* Delete if we cannot find this mem in the expression list. */
- for (i = 0; i < expr_hash_table.size && del; i++)
- {
- for (expr = expr_hash_table.table[i];
- expr != NULL;
- expr = expr->next_same_hash)
- if (expr_equiv_p (expr->expr, ptr->pattern))
- {
- del = 0;
- break;
- }
- }
- }
+ unsigned int hash = ptr->hash_index % expr_hash_table.size;
- if (del)
- {
- if (last != NULL)
- {
- last->next = ptr->next;
- free_ldst_entry (ptr);
- ptr = last->next;
- }
- else
- {
- pre_ldst_mems = pre_ldst_mems->next;
- free_ldst_entry (ptr);
- ptr = pre_ldst_mems;
- }
+ for (expr = expr_hash_table.table[hash];
+ expr != NULL;
+ expr = expr->next_same_hash)
+ if (expr_equiv_p (expr->expr, ptr->pattern))
+ break;
}
else
+ expr = (struct expr *) 0;
+
+ if (expr)
{
/* Set the expression field if we are keeping it. */
- last = ptr;
ptr->expr = expr;
+ last = & ptr->next;
ptr = ptr->next;
}
+ else
+ {
+ *last = ptr->next;
+ free_ldst_entry (ptr);
+ ptr = * last;
+ }
}
/* Show the world what we've found. */
@@ -6712,13 +6898,12 @@ trim_ld_motion_mems ()
/* This routine will take an expression which we are replacing with
a reaching register, and update any stores that are needed if
that expression is in the ld_motion list. Stores are updated by
- copying their SRC to the reaching register, and then storeing
+ copying their SRC to the reaching register, and then storing
the reaching register into the store location. These keeps the
correct value in the reaching register for the loads. */
static void
-update_ld_motion_stores (expr)
- struct expr * expr;
+update_ld_motion_stores (struct expr * expr)
{
struct ls_expr * mem_ptr;
@@ -6728,10 +6913,10 @@ update_ld_motion_stores (expr)
matter to set the reaching reg everywhere... some might be
dead and should be eliminated later. */
- /* We replace SET mem = expr with
- SET reg = expr
- SET mem = reg , where reg is the
- reaching reg used in the load. */
+ /* We replace (set mem expr) with (set reg expr) (set mem reg)
+ where reg is the reaching reg used in the load. We checked in
+ compute_ld_motion_mems that we can replace (set mem expr) with
+ (set reg expr) in that insn. */
rtx list = mem_ptr->stores;
for ( ; list != NULL_RTX; list = XEXP (list, 1))
@@ -6755,7 +6940,7 @@ update_ld_motion_stores (expr)
fprintf (gcse_file, "\n");
}
- copy = gen_move_insn ( reg, SET_SRC (pat));
+ copy = gen_move_insn ( reg, copy_rtx (SET_SRC (pat)));
new = emit_insn_before (copy, insn);
record_one_set (REGNO (reg), new);
SET_SRC (pat) = reg;
@@ -6769,9 +6954,16 @@ update_ld_motion_stores (expr)
/* Store motion code. */
+#define ANTIC_STORE_LIST(x) ((x)->loads)
+#define AVAIL_STORE_LIST(x) ((x)->stores)
+#define LAST_AVAIL_CHECK_FAILURE(x) ((x)->reaching_reg)
+
/* This is used to communicate the target bitvector we want to use in the
reg_set_info routine when called via the note_stores mechanism. */
-static sbitmap * regvec;
+static int * regvec;
+
+/* And current insn, for the same routine. */
+static rtx compute_store_table_current_insn;
/* Used in computing the reverse edge graph bit vectors. */
static sbitmap * st_antloc;
@@ -6779,27 +6971,72 @@ static sbitmap * st_antloc;
/* Global holding the number of store expressions we are dealing with. */
static int num_stores;
-/* Checks to set if we need to mark a register set. Called from note_stores. */
+/* Checks to set if we need to mark a register set. Called from
+ note_stores. */
static void
-reg_set_info (dest, setter, data)
- rtx dest, setter ATTRIBUTE_UNUSED;
- void * data ATTRIBUTE_UNUSED;
+reg_set_info (rtx dest, rtx setter ATTRIBUTE_UNUSED,
+ void *data)
{
+ sbitmap bb_reg = data;
+
if (GET_CODE (dest) == SUBREG)
dest = SUBREG_REG (dest);
if (GET_CODE (dest) == REG)
- SET_BIT (*regvec, REGNO (dest));
+ {
+ regvec[REGNO (dest)] = INSN_UID (compute_store_table_current_insn);
+ if (bb_reg)
+ SET_BIT (bb_reg, REGNO (dest));
+ }
}
-/* Return nonzero if the register operands of expression X are killed
- anywhere in basic block BB. */
+/* Clear any mark that says that this insn sets dest. Called from
+ note_stores. */
-static int
-store_ops_ok (x, bb)
- rtx x;
- basic_block bb;
+static void
+reg_clear_last_set (rtx dest, rtx setter ATTRIBUTE_UNUSED,
+ void *data)
+{
+ int *dead_vec = data;
+
+ if (GET_CODE (dest) == SUBREG)
+ dest = SUBREG_REG (dest);
+
+ if (GET_CODE (dest) == REG &&
+ dead_vec[REGNO (dest)] == INSN_UID (compute_store_table_current_insn))
+ dead_vec[REGNO (dest)] = 0;
+}
+
+/* Return zero if some of the registers in list X are killed
+ due to set of registers in bitmap REGS_SET. */
+
+static bool
+store_ops_ok (rtx x, int *regs_set)
+{
+ rtx reg;
+
+ for (; x; x = XEXP (x, 1))
+ {
+ reg = XEXP (x, 0);
+ if (regs_set[REGNO(reg)])
+ return false;
+ }
+
+ return true;
+}
+
+/* Returns a list of registers mentioned in X. */
+static rtx
+extract_mentioned_regs (rtx x)
+{
+ return extract_mentioned_regs_helper (x, NULL_RTX);
+}
+
+/* Helper for extract_mentioned_regs; ACCUM is used to accumulate used
+ registers. */
+static rtx
+extract_mentioned_regs_helper (rtx x, rtx accum)
{
int i;
enum rtx_code code;
@@ -6809,15 +7046,13 @@ store_ops_ok (x, bb)
repeat:
if (x == 0)
- return 1;
+ return accum;
code = GET_CODE (x);
switch (code)
{
case REG:
- /* If a reg has changed after us in this
- block, the operand has been killed. */
- return TEST_BIT (reg_set_in_block[bb->index], REGNO (x));
+ return alloc_EXPR_LIST (0, x, accum);
case MEM:
x = XEXP (x, 0);
@@ -6827,7 +7062,8 @@ store_ops_ok (x, bb)
case PRE_INC:
case POST_DEC:
case POST_INC:
- return 0;
+ /* We do not run this function with arguments having side effects. */
+ abort ();
case PC:
case CC0: /*FIXME*/
@@ -6839,7 +7075,7 @@ store_ops_ok (x, bb)
case LABEL_REF:
case ADDR_VEC:
case ADDR_DIFF_VEC:
- return 1;
+ return accum;
default:
break;
@@ -6855,88 +7091,167 @@ store_ops_ok (x, bb)
rtx tem = XEXP (x, i);
/* If we are about to do the last recursive call
- needed at this level, change it into iteration.
- This function is called enough to be worth it. */
+ needed at this level, change it into iteration. */
if (i == 0)
{
x = tem;
goto repeat;
}
- if (! store_ops_ok (tem, bb))
- return 0;
+ accum = extract_mentioned_regs_helper (tem, accum);
}
else if (fmt[i] == 'E')
{
int j;
for (j = 0; j < XVECLEN (x, i); j++)
- {
- if (! store_ops_ok (XVECEXP (x, i, j), bb))
- return 0;
- }
+ accum = extract_mentioned_regs_helper (XVECEXP (x, i, j), accum);
}
}
- return 1;
+ return accum;
}
-/* Determine whether insn is MEM store pattern that we will consider moving. */
+/* Determine whether INSN is MEM store pattern that we will consider moving.
+ REGS_SET_BEFORE is bitmap of registers set before (and including) the
+ current insn, REGS_SET_AFTER is bitmap of registers set after (and
+ including) the insn in this basic block. We must be passing through BB from
+ head to end, as we are using this fact to speed things up.
+
+ The results are stored this way:
+
+ -- the first anticipatable expression is added into ANTIC_STORE_LIST
+ -- if the processed expression is not anticipatable, NULL_RTX is added
+ there instead, so that we can use it as indicator that no further
+ expression of this type may be anticipatable
+ -- if the expression is available, it is added as head of AVAIL_STORE_LIST;
+ consequently, all of them but this head are dead and may be deleted.
+ -- if the expression is not available, the insn due to that it fails to be
+ available is stored in reaching_reg.
+
+ The things are complicated a bit by fact that there already may be stores
+ to the same MEM from other blocks; also caller must take care of the
+ necessary cleanup of the temporary markers after end of the basic block.
+ */
static void
-find_moveable_store (insn)
- rtx insn;
+find_moveable_store (rtx insn, int *regs_set_before, int *regs_set_after)
{
struct ls_expr * ptr;
- rtx dest = PATTERN (insn);
+ rtx dest, set, tmp;
+ int check_anticipatable, check_available;
+ basic_block bb = BLOCK_FOR_INSN (insn);
- if (GET_CODE (dest) != SET
- || GET_CODE (SET_SRC (dest)) == ASM_OPERANDS)
+ set = single_set (insn);
+ if (!set)
return;
- dest = SET_DEST (dest);
+ dest = SET_DEST (set);
if (GET_CODE (dest) != MEM || MEM_VOLATILE_P (dest)
|| GET_MODE (dest) == BLKmode)
return;
- if (GET_CODE (XEXP (dest, 0)) != SYMBOL_REF)
- return;
+ if (side_effects_p (dest))
+ return;
- if (rtx_varies_p (XEXP (dest, 0), 0))
+ /* If we are handling exceptions, we must be careful with memory references
+ that may trap. If we are not, the behavior is undefined, so we may just
+ continue. */
+ if (flag_non_call_exceptions && may_trap_p (dest))
return;
ptr = ldst_entry (dest);
- ptr->stores = alloc_INSN_LIST (insn, ptr->stores);
+ if (!ptr->pattern_regs)
+ ptr->pattern_regs = extract_mentioned_regs (dest);
+
+ /* Do not check for anticipatability if we either found one anticipatable
+ store already, or tested for one and found out that it was killed. */
+ check_anticipatable = 0;
+ if (!ANTIC_STORE_LIST (ptr))
+ check_anticipatable = 1;
+ else
+ {
+ tmp = XEXP (ANTIC_STORE_LIST (ptr), 0);
+ if (tmp != NULL_RTX
+ && BLOCK_FOR_INSN (tmp) != bb)
+ check_anticipatable = 1;
+ }
+ if (check_anticipatable)
+ {
+ if (store_killed_before (dest, ptr->pattern_regs, insn, bb, regs_set_before))
+ tmp = NULL_RTX;
+ else
+ tmp = insn;
+ ANTIC_STORE_LIST (ptr) = alloc_INSN_LIST (tmp,
+ ANTIC_STORE_LIST (ptr));
+ }
+
+ /* It is not necessary to check whether store is available if we did
+ it successfully before; if we failed before, do not bother to check
+ until we reach the insn that caused us to fail. */
+ check_available = 0;
+ if (!AVAIL_STORE_LIST (ptr))
+ check_available = 1;
+ else
+ {
+ tmp = XEXP (AVAIL_STORE_LIST (ptr), 0);
+ if (BLOCK_FOR_INSN (tmp) != bb)
+ check_available = 1;
+ }
+ if (check_available)
+ {
+ /* Check that we have already reached the insn at that the check
+ failed last time. */
+ if (LAST_AVAIL_CHECK_FAILURE (ptr))
+ {
+ for (tmp = BB_END (bb);
+ tmp != insn && tmp != LAST_AVAIL_CHECK_FAILURE (ptr);
+ tmp = PREV_INSN (tmp))
+ continue;
+ if (tmp == insn)
+ check_available = 0;
+ }
+ else
+ check_available = store_killed_after (dest, ptr->pattern_regs, insn,
+ bb, regs_set_after,
+ &LAST_AVAIL_CHECK_FAILURE (ptr));
+ }
+ if (!check_available)
+ AVAIL_STORE_LIST (ptr) = alloc_INSN_LIST (insn, AVAIL_STORE_LIST (ptr));
}
-/* Perform store motion. Much like gcse, except we move expressions the
- other way by looking at the flowgraph in reverse. */
+/* Find available and anticipatable stores. */
static int
-compute_store_table ()
+compute_store_table (void)
{
int ret;
basic_block bb;
unsigned regno;
- rtx insn, pat;
+ rtx insn, pat, tmp;
+ int *last_set_in, *already_set;
+ struct ls_expr * ptr, **prev_next_ptr_ptr;
max_gcse_regno = max_reg_num ();
- reg_set_in_block = (sbitmap *) sbitmap_vector_alloc (last_basic_block,
+ reg_set_in_block = sbitmap_vector_alloc (last_basic_block,
max_gcse_regno);
sbitmap_vector_zero (reg_set_in_block, last_basic_block);
pre_ldst_mems = 0;
+ last_set_in = xcalloc (max_gcse_regno, sizeof (int));
+ already_set = xmalloc (sizeof (int) * max_gcse_regno);
/* Find all the stores we care about. */
FOR_EACH_BB (bb)
{
- regvec = & (reg_set_in_block[bb->index]);
- for (insn = bb->end;
- insn && insn != PREV_INSN (bb->end);
- insn = PREV_INSN (insn))
+ /* First compute the registers set in this block. */
+ regvec = last_set_in;
+
+ for (insn = BB_HEAD (bb);
+ insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
{
- /* Ignore anything that is not a normal insn. */
if (! INSN_P (insn))
continue;
@@ -6952,61 +7267,149 @@ compute_store_table ()
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (clobbers_all
|| TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
- SET_BIT (reg_set_in_block[bb->index], regno);
+ {
+ last_set_in[regno] = INSN_UID (insn);
+ SET_BIT (reg_set_in_block[bb->index], regno);
+ }
+ }
+
+ pat = PATTERN (insn);
+ compute_store_table_current_insn = insn;
+ note_stores (pat, reg_set_info, reg_set_in_block[bb->index]);
+ }
+
+ /* Now find the stores. */
+ memset (already_set, 0, sizeof (int) * max_gcse_regno);
+ regvec = already_set;
+ for (insn = BB_HEAD (bb);
+ insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
+ {
+ if (! INSN_P (insn))
+ continue;
+
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ bool clobbers_all = false;
+#ifdef NON_SAVING_SETJMP
+ if (NON_SAVING_SETJMP
+ && find_reg_note (insn, REG_SETJMP, NULL_RTX))
+ clobbers_all = true;
+#endif
+
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if (clobbers_all
+ || TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
+ already_set[regno] = 1;
}
pat = PATTERN (insn);
note_stores (pat, reg_set_info, NULL);
/* Now that we've marked regs, look for stores. */
- if (GET_CODE (pat) == SET)
- find_moveable_store (insn);
+ find_moveable_store (insn, already_set, last_set_in);
+
+ /* Unmark regs that are no longer set. */
+ compute_store_table_current_insn = insn;
+ note_stores (pat, reg_clear_last_set, last_set_in);
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ bool clobbers_all = false;
+#ifdef NON_SAVING_SETJMP
+ if (NON_SAVING_SETJMP
+ && find_reg_note (insn, REG_SETJMP, NULL_RTX))
+ clobbers_all = true;
+#endif
+
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if ((clobbers_all
+ || TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
+ && last_set_in[regno] == INSN_UID (insn))
+ last_set_in[regno] = 0;
+ }
+ }
+
+#ifdef ENABLE_CHECKING
+ /* last_set_in should now be all-zero. */
+ for (regno = 0; regno < max_gcse_regno; regno++)
+ if (last_set_in[regno] != 0)
+ abort ();
+#endif
+
+ /* Clear temporary marks. */
+ for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
+ {
+ LAST_AVAIL_CHECK_FAILURE(ptr) = NULL_RTX;
+ if (ANTIC_STORE_LIST (ptr)
+ && (tmp = XEXP (ANTIC_STORE_LIST (ptr), 0)) == NULL_RTX)
+ ANTIC_STORE_LIST (ptr) = XEXP (ANTIC_STORE_LIST (ptr), 1);
}
}
+ /* Remove the stores that are not available anywhere, as there will
+ be no opportunity to optimize them. */
+ for (ptr = pre_ldst_mems, prev_next_ptr_ptr = &pre_ldst_mems;
+ ptr != NULL;
+ ptr = *prev_next_ptr_ptr)
+ {
+ if (!AVAIL_STORE_LIST (ptr))
+ {
+ *prev_next_ptr_ptr = ptr->next;
+ free_ldst_entry (ptr);
+ }
+ else
+ prev_next_ptr_ptr = &ptr->next;
+ }
+
ret = enumerate_ldsts ();
if (gcse_file)
{
- fprintf (gcse_file, "Store Motion Expressions.\n");
+ fprintf (gcse_file, "ST_avail and ST_antic (shown under loads..)\n");
print_ldst_list (gcse_file);
}
+ free (last_set_in);
+ free (already_set);
return ret;
}
-/* Check to see if the load X is aliased with STORE_PATTERN. */
+/* Check to see if the load X is aliased with STORE_PATTERN.
+ AFTER is true if we are checking the case when STORE_PATTERN occurs
+ after the X. */
-static int
-load_kills_store (x, store_pattern)
- rtx x, store_pattern;
+static bool
+load_kills_store (rtx x, rtx store_pattern, int after)
{
- if (true_dependence (x, GET_MODE (x), store_pattern, rtx_addr_varies_p))
- return 1;
- return 0;
+ if (after)
+ return anti_dependence (x, store_pattern);
+ else
+ return true_dependence (store_pattern, GET_MODE (store_pattern), x,
+ rtx_addr_varies_p);
}
/* Go through the entire insn X, looking for any loads which might alias
- STORE_PATTERN. Return 1 if found. */
+ STORE_PATTERN. Return true if found.
+ AFTER is true if we are checking the case when STORE_PATTERN occurs
+ after the insn X. */
-static int
-find_loads (x, store_pattern)
- rtx x, store_pattern;
+static bool
+find_loads (rtx x, rtx store_pattern, int after)
{
const char * fmt;
int i, j;
- int ret = 0;
+ int ret = false;
if (!x)
- return 0;
+ return false;
if (GET_CODE (x) == SET)
x = SET_SRC (x);
if (GET_CODE (x) == MEM)
{
- if (load_kills_store (x, store_pattern))
- return 1;
+ if (load_kills_store (x, store_pattern, after))
+ return true;
}
/* Recursively process the insn. */
@@ -7015,215 +7418,225 @@ find_loads (x, store_pattern)
for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0 && !ret; i--)
{
if (fmt[i] == 'e')
- ret |= find_loads (XEXP (x, i), store_pattern);
+ ret |= find_loads (XEXP (x, i), store_pattern, after);
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- ret |= find_loads (XVECEXP (x, i, j), store_pattern);
+ ret |= find_loads (XVECEXP (x, i, j), store_pattern, after);
}
return ret;
}
/* Check if INSN kills the store pattern X (is aliased with it).
- Return 1 if it it does. */
+ AFTER is true if we are checking the case when store X occurs
+ after the insn. Return true if it it does. */
-static int
-store_killed_in_insn (x, insn)
- rtx x, insn;
+static bool
+store_killed_in_insn (rtx x, rtx x_regs, rtx insn, int after)
{
- if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
- return 0;
+ rtx reg, base, note;
+
+ if (!INSN_P (insn))
+ return false;
if (GET_CODE (insn) == CALL_INSN)
{
/* A normal or pure call might read from pattern,
but a const call will not. */
- return ! CONST_OR_PURE_CALL_P (insn) || pure_call_p (insn);
+ if (! CONST_OR_PURE_CALL_P (insn) || pure_call_p (insn))
+ return true;
+
+ /* But even a const call reads its parameters. Check whether the
+ base of some of registers used in mem is stack pointer. */
+ for (reg = x_regs; reg; reg = XEXP (reg, 1))
+ {
+ base = find_base_term (XEXP (reg, 0));
+ if (!base
+ || (GET_CODE (base) == ADDRESS
+ && GET_MODE (base) == Pmode
+ && XEXP (base, 0) == stack_pointer_rtx))
+ return true;
+ }
+
+ return false;
}
if (GET_CODE (PATTERN (insn)) == SET)
{
rtx pat = PATTERN (insn);
+ rtx dest = SET_DEST (pat);
+
+ if (GET_CODE (dest) == SIGN_EXTRACT
+ || GET_CODE (dest) == ZERO_EXTRACT)
+ dest = XEXP (dest, 0);
+
/* Check for memory stores to aliased objects. */
- if (GET_CODE (SET_DEST (pat)) == MEM && !expr_equiv_p (SET_DEST (pat), x))
- /* pretend its a load and check for aliasing. */
- if (find_loads (SET_DEST (pat), x))
- return 1;
- return find_loads (SET_SRC (pat), x);
+ if (GET_CODE (dest) == MEM
+ && !expr_equiv_p (dest, x))
+ {
+ if (after)
+ {
+ if (output_dependence (dest, x))
+ return true;
+ }
+ else
+ {
+ if (output_dependence (x, dest))
+ return true;
+ }
+ }
+ if (find_loads (SET_SRC (pat), x, after))
+ return true;
}
- else
- return find_loads (PATTERN (insn), x);
+ else if (find_loads (PATTERN (insn), x, after))
+ return true;
+
+ /* If this insn has a REG_EQUAL or REG_EQUIV note referencing a memory
+ location aliased with X, then this insn kills X. */
+ note = find_reg_equal_equiv_note (insn);
+ if (! note)
+ return false;
+ note = XEXP (note, 0);
+
+ /* However, if the note represents a must alias rather than a may
+ alias relationship, then it does not kill X. */
+ if (expr_equiv_p (note, x))
+ return false;
+
+ /* See if there are any aliased loads in the note. */
+ return find_loads (note, x, after);
}
-/* Returns 1 if the expression X is loaded or clobbered on or after INSN
- within basic block BB. */
+/* Returns true if the expression X is loaded or clobbered on or after INSN
+ within basic block BB. REGS_SET_AFTER is bitmap of registers set in
+ or after the insn. X_REGS is list of registers mentioned in X. If the store
+ is killed, return the last insn in that it occurs in FAIL_INSN. */
-static int
-store_killed_after (x, insn, bb)
- rtx x, insn;
- basic_block bb;
+static bool
+store_killed_after (rtx x, rtx x_regs, rtx insn, basic_block bb,
+ int *regs_set_after, rtx *fail_insn)
{
- rtx last = bb->end;
-
- if (insn == last)
- return 0;
+ rtx last = BB_END (bb), act;
- /* Check if the register operands of the store are OK in this block.
- Note that if registers are changed ANYWHERE in the block, we'll
- decide we can't move it, regardless of whether it changed above
- or below the store. This could be improved by checking the register
- operands while lookinng for aliasing in each insn. */
- if (!store_ops_ok (XEXP (x, 0), bb))
- return 1;
+ if (!store_ops_ok (x_regs, regs_set_after))
+ {
+ /* We do not know where it will happen. */
+ if (fail_insn)
+ *fail_insn = NULL_RTX;
+ return true;
+ }
- for ( ; insn && insn != NEXT_INSN (last); insn = NEXT_INSN (insn))
- if (store_killed_in_insn (x, insn))
- return 1;
+ /* Scan from the end, so that fail_insn is determined correctly. */
+ for (act = last; act != PREV_INSN (insn); act = PREV_INSN (act))
+ if (store_killed_in_insn (x, x_regs, act, false))
+ {
+ if (fail_insn)
+ *fail_insn = act;
+ return true;
+ }
- return 0;
+ return false;
}
-/* Returns 1 if the expression X is loaded or clobbered on or before INSN
- within basic block BB. */
-static int
-store_killed_before (x, insn, bb)
- rtx x, insn;
- basic_block bb;
+/* Returns true if the expression X is loaded or clobbered on or before INSN
+ within basic block BB. X_REGS is list of registers mentioned in X.
+ REGS_SET_BEFORE is bitmap of registers set before or in this insn. */
+static bool
+store_killed_before (rtx x, rtx x_regs, rtx insn, basic_block bb,
+ int *regs_set_before)
{
- rtx first = bb->head;
+ rtx first = BB_HEAD (bb);
- if (insn == first)
- return store_killed_in_insn (x, insn);
+ if (!store_ops_ok (x_regs, regs_set_before))
+ return true;
- /* Check if the register operands of the store are OK in this block.
- Note that if registers are changed ANYWHERE in the block, we'll
- decide we can't move it, regardless of whether it changed above
- or below the store. This could be improved by checking the register
- operands while lookinng for aliasing in each insn. */
- if (!store_ops_ok (XEXP (x, 0), bb))
- return 1;
-
- for ( ; insn && insn != PREV_INSN (first); insn = PREV_INSN (insn))
- if (store_killed_in_insn (x, insn))
- return 1;
+ for ( ; insn != PREV_INSN (first); insn = PREV_INSN (insn))
+ if (store_killed_in_insn (x, x_regs, insn, true))
+ return true;
- return 0;
+ return false;
}
-#define ANTIC_STORE_LIST(x) ((x)->loads)
-#define AVAIL_STORE_LIST(x) ((x)->stores)
-
-/* Given the table of available store insns at the end of blocks,
- determine which ones are not killed by aliasing, and generate
- the appropriate vectors for gen and killed. */
+/* Fill in available, anticipatable, transparent and kill vectors in
+ STORE_DATA, based on lists of available and anticipatable stores. */
static void
-build_store_vectors ()
+build_store_vectors (void)
{
- basic_block bb, b;
+ basic_block bb;
+ int *regs_set_in_block;
rtx insn, st;
struct ls_expr * ptr;
+ unsigned regno;
/* Build the gen_vector. This is any store in the table which is not killed
by aliasing later in its block. */
- ae_gen = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
+ ae_gen = sbitmap_vector_alloc (last_basic_block, num_stores);
sbitmap_vector_zero (ae_gen, last_basic_block);
- st_antloc = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
+ st_antloc = sbitmap_vector_alloc (last_basic_block, num_stores);
sbitmap_vector_zero (st_antloc, last_basic_block);
for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
{
- /* Put all the stores into either the antic list, or the avail list,
- or both. */
- rtx store_list = ptr->stores;
- ptr->stores = NULL_RTX;
-
- for (st = store_list; st != NULL; st = XEXP (st, 1))
+ for (st = AVAIL_STORE_LIST (ptr); st != NULL; st = XEXP (st, 1))
{
insn = XEXP (st, 0);
bb = BLOCK_FOR_INSN (insn);
- if (!store_killed_after (ptr->pattern, insn, bb))
- {
- /* If we've already seen an availale expression in this block,
- we can delete the one we saw already (It occurs earlier in
- the block), and replace it with this one). We'll copy the
- old SRC expression to an unused register in case there
- are any side effects. */
- if (TEST_BIT (ae_gen[bb->index], ptr->index))
- {
- /* Find previous store. */
- rtx st;
- for (st = AVAIL_STORE_LIST (ptr); st ; st = XEXP (st, 1))
- if (BLOCK_FOR_INSN (XEXP (st, 0)) == bb)
- break;
- if (st)
- {
- rtx r = gen_reg_rtx (GET_MODE (ptr->pattern));
- if (gcse_file)
- fprintf (gcse_file, "Removing redundant store:\n");
- replace_store_insn (r, XEXP (st, 0), bb);
- XEXP (st, 0) = insn;
- continue;
- }
- }
- SET_BIT (ae_gen[bb->index], ptr->index);
- AVAIL_STORE_LIST (ptr) = alloc_INSN_LIST (insn,
- AVAIL_STORE_LIST (ptr));
- }
-
- if (!store_killed_before (ptr->pattern, insn, bb))
+ /* If we've already seen an available expression in this block,
+ we can delete this one (It occurs earlier in the block). We'll
+ copy the SRC expression to an unused register in case there
+ are any side effects. */
+ if (TEST_BIT (ae_gen[bb->index], ptr->index))
{
- SET_BIT (st_antloc[BLOCK_NUM (insn)], ptr->index);
- ANTIC_STORE_LIST (ptr) = alloc_INSN_LIST (insn,
- ANTIC_STORE_LIST (ptr));
+ rtx r = gen_reg_rtx (GET_MODE (ptr->pattern));
+ if (gcse_file)
+ fprintf (gcse_file, "Removing redundant store:\n");
+ replace_store_insn (r, XEXP (st, 0), bb, ptr);
+ continue;
}
+ SET_BIT (ae_gen[bb->index], ptr->index);
}
- /* Free the original list of store insns. */
- free_INSN_LIST_list (&store_list);
+ for (st = ANTIC_STORE_LIST (ptr); st != NULL; st = XEXP (st, 1))
+ {
+ insn = XEXP (st, 0);
+ bb = BLOCK_FOR_INSN (insn);
+ SET_BIT (st_antloc[bb->index], ptr->index);
+ }
}
- ae_kill = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
+ ae_kill = sbitmap_vector_alloc (last_basic_block, num_stores);
sbitmap_vector_zero (ae_kill, last_basic_block);
- transp = (sbitmap *) sbitmap_vector_alloc (last_basic_block, num_stores);
+ transp = sbitmap_vector_alloc (last_basic_block, num_stores);
sbitmap_vector_zero (transp, last_basic_block);
+ regs_set_in_block = xmalloc (sizeof (int) * max_gcse_regno);
- for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
- FOR_EACH_BB (b)
- {
- if (store_killed_after (ptr->pattern, b->head, b))
- {
- /* The anticipatable expression is not killed if it's gen'd. */
- /*
- We leave this check out for now. If we have a code sequence
- in a block which looks like:
- ST MEMa = x
- L y = MEMa
- ST MEMa = z
- We should flag this as having an ANTIC expression, NOT
- transparent, NOT killed, and AVAIL.
- Unfortunately, since we haven't re-written all loads to
- use the reaching reg, we'll end up doing an incorrect
- Load in the middle here if we push the store down. It happens in
- gcc.c-torture/execute/960311-1.c with -O3
- If we always kill it in this case, we'll sometimes do
- uneccessary work, but it shouldn't actually hurt anything.
- if (!TEST_BIT (ae_gen[b], ptr->index)). */
- SET_BIT (ae_kill[b->index], ptr->index);
- }
- else
- SET_BIT (transp[b->index], ptr->index);
- }
+ FOR_EACH_BB (bb)
+ {
+ for (regno = 0; regno < max_gcse_regno; regno++)
+ regs_set_in_block[regno] = TEST_BIT (reg_set_in_block[bb->index], regno);
+
+ for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
+ {
+ if (store_killed_after (ptr->pattern, ptr->pattern_regs, BB_HEAD (bb),
+ bb, regs_set_in_block, NULL))
+ {
+ /* It should not be necessary to consider the expression
+ killed if it is both anticipatable and available. */
+ if (!TEST_BIT (st_antloc[bb->index], ptr->index)
+ || !TEST_BIT (ae_gen[bb->index], ptr->index))
+ SET_BIT (ae_kill[bb->index], ptr->index);
+ }
+ else
+ SET_BIT (transp[bb->index], ptr->index);
+ }
+ }
+
+ free (regs_set_in_block);
- /* Any block with no exits calls some non-returning function, so
- we better mark the store killed here, or we might not store to
- it at all. If we knew it was abort, we wouldn't have to store,
- but we don't know that for sure. */
if (gcse_file)
{
- fprintf (gcse_file, "ST_avail and ST_antic (shown under loads..)\n");
- print_ldst_list (gcse_file);
dump_sbitmap_vector (gcse_file, "st_antloc", "", st_antloc, last_basic_block);
dump_sbitmap_vector (gcse_file, "st_kill", "", ae_kill, last_basic_block);
dump_sbitmap_vector (gcse_file, "Transpt", "", transp, last_basic_block);
@@ -7231,17 +7644,15 @@ build_store_vectors ()
}
}
-/* Insert an instruction at the begining of a basic block, and update
- the BLOCK_HEAD if needed. */
+/* Insert an instruction at the beginning of a basic block, and update
+ the BB_HEAD if needed. */
static void
-insert_insn_start_bb (insn, bb)
- rtx insn;
- basic_block bb;
+insert_insn_start_bb (rtx insn, basic_block bb)
{
/* Insert at start of successor block. */
- rtx prev = PREV_INSN (bb->head);
- rtx before = bb->head;
+ rtx prev = PREV_INSN (BB_HEAD (bb));
+ rtx before = BB_HEAD (bb);
while (before != 0)
{
if (GET_CODE (before) != CODE_LABEL
@@ -7249,12 +7660,12 @@ insert_insn_start_bb (insn, bb)
|| NOTE_LINE_NUMBER (before) != NOTE_INSN_BASIC_BLOCK))
break;
prev = before;
- if (prev == bb->end)
+ if (prev == BB_END (bb))
break;
before = NEXT_INSN (before);
}
- insn = emit_insn_after (insn, prev);
+ insn = emit_insn_after_noloc (insn, prev);
if (gcse_file)
{
@@ -7270,9 +7681,7 @@ insert_insn_start_bb (insn, bb)
if an edge insertion was performed. */
static int
-insert_store (expr, e)
- struct ls_expr * expr;
- edge e;
+insert_store (struct ls_expr * expr, edge e)
{
rtx reg, insn;
basic_block bb;
@@ -7283,21 +7692,25 @@ insert_store (expr, e)
if (expr->reaching_reg == NULL_RTX)
return 0;
+ if (e->flags & EDGE_FAKE)
+ return 0;
+
reg = expr->reaching_reg;
- insn = gen_move_insn (expr->pattern, reg);
+ insn = gen_move_insn (copy_rtx (expr->pattern), reg);
/* If we are inserting this expression on ALL predecessor edges of a BB,
insert it at the start of the BB, and reset the insert bits on the other
edges so we don't try to insert it on the other edges. */
bb = e->dest;
for (tmp = e->dest->pred; tmp ; tmp = tmp->pred_next)
- {
- int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
- if (index == EDGE_INDEX_NO_EDGE)
- abort ();
- if (! TEST_BIT (pre_insert_map[index], expr->index))
- break;
- }
+ if (!(tmp->flags & EDGE_FAKE))
+ {
+ int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
+ if (index == EDGE_INDEX_NO_EDGE)
+ abort ();
+ if (! TEST_BIT (pre_insert_map[index], expr->index))
+ break;
+ }
/* If tmp is NULL, we found an insertion on every edge, blank the
insertion vector for these edges, and insert at the start of the BB. */
@@ -7333,16 +7746,88 @@ insert_store (expr, e)
return 1;
}
+/* Remove any REG_EQUAL or REG_EQUIV notes containing a reference to the
+ memory location in SMEXPR set in basic block BB.
+
+ This could be rather expensive. */
+
+static void
+remove_reachable_equiv_notes (basic_block bb, struct ls_expr *smexpr)
+{
+ edge *stack = xmalloc (sizeof (edge) * n_basic_blocks), act;
+ sbitmap visited = sbitmap_alloc (last_basic_block);
+ int stack_top = 0;
+ rtx last, insn, note;
+ rtx mem = smexpr->pattern;
+
+ sbitmap_zero (visited);
+ act = bb->succ;
+
+ while (1)
+ {
+ if (!act)
+ {
+ if (!stack_top)
+ {
+ free (stack);
+ sbitmap_free (visited);
+ return;
+ }
+ act = stack[--stack_top];
+ }
+ bb = act->dest;
+
+ if (bb == EXIT_BLOCK_PTR
+ || TEST_BIT (visited, bb->index)
+ || TEST_BIT (ae_kill[bb->index], smexpr->index))
+ {
+ act = act->succ_next;
+ continue;
+ }
+ SET_BIT (visited, bb->index);
+
+ if (TEST_BIT (st_antloc[bb->index], smexpr->index))
+ {
+ for (last = ANTIC_STORE_LIST (smexpr);
+ BLOCK_FOR_INSN (XEXP (last, 0)) != bb;
+ last = XEXP (last, 1))
+ continue;
+ last = XEXP (last, 0);
+ }
+ else
+ last = NEXT_INSN (BB_END (bb));
+
+ for (insn = BB_HEAD (bb); insn != last; insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ {
+ note = find_reg_equal_equiv_note (insn);
+ if (!note || !expr_equiv_p (XEXP (note, 0), mem))
+ continue;
+
+ if (gcse_file)
+ fprintf (gcse_file, "STORE_MOTION drop REG_EQUAL note at insn %d:\n",
+ INSN_UID (insn));
+ remove_note (insn, note);
+ }
+ act = act->succ_next;
+ if (bb->succ)
+ {
+ if (act)
+ stack[stack_top++] = act;
+ act = bb->succ;
+ }
+ }
+}
+
/* This routine will replace a store with a SET to a specified register. */
static void
-replace_store_insn (reg, del, bb)
- rtx reg, del;
- basic_block bb;
+replace_store_insn (rtx reg, rtx del, basic_block bb, struct ls_expr *smexpr)
{
- rtx insn;
+ rtx insn, mem, note, set, ptr;
- insn = gen_move_insn (reg, SET_SRC (PATTERN (del)));
+ mem = smexpr->pattern;
+ insn = gen_move_insn (reg, SET_SRC (single_set (del)));
insn = emit_insn_after (insn, del);
if (gcse_file)
@@ -7355,7 +7840,35 @@ replace_store_insn (reg, del, bb)
fprintf (gcse_file, "\n");
}
+ for (ptr = ANTIC_STORE_LIST (smexpr); ptr; ptr = XEXP (ptr, 1))
+ if (XEXP (ptr, 0) == del)
+ {
+ XEXP (ptr, 0) = insn;
+ break;
+ }
delete_insn (del);
+
+ /* Now we must handle REG_EQUAL notes whose contents is equal to the mem;
+ they are no longer accurate provided that they are reached by this
+ definition, so drop them. */
+ for (; insn != NEXT_INSN (BB_END (bb)); insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ {
+ set = single_set (insn);
+ if (!set)
+ continue;
+ if (expr_equiv_p (SET_DEST (set), mem))
+ return;
+ note = find_reg_equal_equiv_note (insn);
+ if (!note || !expr_equiv_p (XEXP (note, 0), mem))
+ continue;
+
+ if (gcse_file)
+ fprintf (gcse_file, "STORE_MOTION drop REG_EQUAL note at insn %d:\n",
+ INSN_UID (insn));
+ remove_note (insn, note);
+ }
+ remove_reachable_equiv_notes (bb, smexpr);
}
@@ -7363,18 +7876,13 @@ replace_store_insn (reg, del, bb)
the reaching_reg for later storing. */
static void
-delete_store (expr, bb)
- struct ls_expr * expr;
- basic_block bb;
+delete_store (struct ls_expr * expr, basic_block bb)
{
rtx reg, i, del;
if (expr->reaching_reg == NULL_RTX)
expr->reaching_reg = gen_reg_rtx (GET_MODE (expr->pattern));
-
- /* If there is more than 1 store, the earlier ones will be dead,
- but it doesn't hurt to replace them here. */
reg = expr->reaching_reg;
for (i = AVAIL_STORE_LIST (expr); i; i = XEXP (i, 1))
@@ -7384,7 +7892,7 @@ delete_store (expr, bb)
{
/* We know there is only one since we deleted redundant
ones during the available computation. */
- replace_store_insn (reg, del, bb);
+ replace_store_insn (reg, del, bb, expr);
break;
}
}
@@ -7393,7 +7901,7 @@ delete_store (expr, bb)
/* Free memory used by store motion. */
static void
-free_store_memory ()
+free_store_memory (void)
{
free_ldst_mems ();
@@ -7420,7 +7928,7 @@ free_store_memory ()
other way by looking at the flowgraph in reverse. */
static void
-store_motion ()
+store_motion (void)
{
basic_block bb;
int x;
@@ -7433,10 +7941,9 @@ store_motion ()
print_rtl (gcse_file, get_insns ());
}
-
init_alias_analysis ();
- /* Find all the stores that are live to the end of their block. */
+ /* Find all the available and anticipatable stores. */
num_stores = compute_store_table ();
if (num_stores == 0)
{
@@ -7445,9 +7952,10 @@ store_motion ()
return;
}
- /* Now compute whats actually available to move. */
- add_noreturn_fake_exit_edges ();
+ /* Now compute kill & transp vectors. */
build_store_vectors ();
+ add_noreturn_fake_exit_edges ();
+ connect_infinite_loops_to_exit ();
edge_list = pre_edge_rev_lcm (gcse_file, num_stores, transp, ae_gen,
st_antloc, ae_kill, &pre_insert_map,
@@ -7474,4 +7982,112 @@ store_motion ()
end_alias_analysis ();
}
+
+/* Entry point for jump bypassing optimization pass. */
+
+int
+bypass_jumps (FILE *file)
+{
+ int changed;
+
+ /* We do not construct an accurate cfg in functions which call
+ setjmp, so just punt to be safe. */
+ if (current_function_calls_setjmp)
+ return 0;
+
+ /* For calling dump_foo fns from gdb. */
+ debug_stderr = stderr;
+ gcse_file = file;
+
+ /* Identify the basic block information for this function, including
+ successors and predecessors. */
+ max_gcse_regno = max_reg_num ();
+
+ if (file)
+ dump_flow_info (file);
+
+ /* Return if there's nothing to do, or it is too expensive. */
+ if (n_basic_blocks <= 1 || is_too_expensive (_ ("jump bypassing disabled")))
+ return 0;
+
+ gcc_obstack_init (&gcse_obstack);
+ bytes_used = 0;
+
+ /* We need alias. */
+ init_alias_analysis ();
+
+ /* Record where pseudo-registers are set. This data is kept accurate
+ during each pass. ??? We could also record hard-reg information here
+ [since it's unchanging], however it is currently done during hash table
+ computation.
+
+ It may be tempting to compute MEM set information here too, but MEM sets
+ will be subject to code motion one day and thus we need to compute
+ information about memory sets when we build the hash tables. */
+
+ alloc_reg_set_mem (max_gcse_regno);
+ compute_sets (get_insns ());
+
+ max_gcse_regno = max_reg_num ();
+ alloc_gcse_mem (get_insns ());
+ changed = one_cprop_pass (1, 1, 1);
+ free_gcse_mem ();
+
+ if (file)
+ {
+ fprintf (file, "BYPASS of %s: %d basic blocks, ",
+ current_function_name (), n_basic_blocks);
+ fprintf (file, "%d bytes\n\n", bytes_used);
+ }
+
+ obstack_free (&gcse_obstack, NULL);
+ free_reg_set_mem ();
+
+ /* We are finished with alias. */
+ end_alias_analysis ();
+ allocate_reg_info (max_reg_num (), FALSE, FALSE);
+
+ return changed;
+}
+
+/* Return true if the graph is too expensive to optimize. PASS is the
+ optimization about to be performed. */
+
+static bool
+is_too_expensive (const char *pass)
+{
+ /* Trying to perform global optimizations on flow graphs which have
+ a high connectivity will take a long time and is unlikely to be
+ particularly useful.
+
+ In normal circumstances a cfg should have about twice as many
+ edges as blocks. But we do not want to punish small functions
+ which have a couple switch statements. Rather than simply
+ threshold the number of blocks, uses something with a more
+ graceful degradation. */
+ if (n_edges > 20000 + n_basic_blocks * 4)
+ {
+ if (warn_disabled_optimization)
+ warning ("%s: %d basic blocks and %d edges/basic block",
+ pass, n_basic_blocks, n_edges / n_basic_blocks);
+
+ return true;
+ }
+
+ /* If allocating memory for the cprop bitmap would take up too much
+ storage it's better just to disable the optimization. */
+ if ((n_basic_blocks
+ * SBITMAP_SET_SIZE (max_reg_num ())
+ * sizeof (SBITMAP_ELT_TYPE)) > MAX_GCSE_MEMORY)
+ {
+ if (warn_disabled_optimization)
+ warning ("%s: %d basic blocks and %d registers",
+ pass, n_basic_blocks, max_reg_num ());
+
+ return true;
+ }
+
+ return false;
+}
+
#include "gt-gcse.h"
diff --git a/contrib/gcc/gdbinit.in b/contrib/gcc/gdbinit.in
index cee1131b6aa5..ccc6504dda78 100644
--- a/contrib/gcc/gdbinit.in
+++ b/contrib/gcc/gdbinit.in
@@ -79,7 +79,7 @@ Print the rtx-code and machine mode of the rtx that is $.
end
define pi
-print $.fld[0].rtx@7
+print $.u.fld[0].rtx@7
end
document pi
diff --git a/contrib/gcc/gen-protos.c b/contrib/gcc/gen-protos.c
index 96aeef9ed253..ee8f0a17cd18 100644
--- a/contrib/gcc/gen-protos.c
+++ b/contrib/gcc/gen-protos.c
@@ -1,6 +1,6 @@
/* gen-protos.c - massages a list of prototypes, for use by fixproto.
Copyright (C) 1993, 1994, 1995, 1996, 1998,
- 1999 Free Software Foundation, Inc.
+ 1999, 2003 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
@@ -16,16 +16,18 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "scan.h"
#undef abort
int verbose = 0;
const char *progname;
-static void add_hash PARAMS ((const char *));
-static int parse_fn_proto PARAMS ((char *, char *, struct fn_decl *));
+static void add_hash (const char *);
+static int parse_fn_proto (char *, char *, struct fn_decl *);
#define HASH_SIZE 2503 /* a prime */
int hash_tab[HASH_SIZE];
@@ -33,8 +35,7 @@ int next_index;
int collisions;
static void
-add_hash (fname)
- const char *fname;
+add_hash (const char *fname)
{
int i, i0;
@@ -65,9 +66,7 @@ add_hash (fname)
The fields of FN point to the input string. */
static int
-parse_fn_proto (start, end, fn)
- char *start, *end;
- struct fn_decl *fn;
+parse_fn_proto (char *start, char *end, struct fn_decl *fn)
{
char *ptr;
int param_nesting = 1;
@@ -129,12 +128,8 @@ parse_fn_proto (start, end, fn)
return 1;
}
-extern int main PARAMS ((int, char **));
-
int
-main (argc, argv)
- int argc ATTRIBUTE_UNUSED;
- char **argv;
+main (int argc ATTRIBUTE_UNUSED, char **argv)
{
FILE *inf = stdin;
FILE *outf = stdout;
@@ -153,7 +148,7 @@ main (argc, argv)
/* A hash table entry of 0 means "unused" so reserve it. */
fprintf (outf, " {\"\", \"\", \"\", 0},\n");
next_index = 1;
-
+
for (;;)
{
int c = skip_spaces (inf, ' ');
@@ -190,6 +185,6 @@ main (argc, argv)
fprintf (stderr, "gen-protos: %d entries %d collisions\n",
next_index, collisions);
-
+
return 0;
}
diff --git a/contrib/gcc/genattr.c b/contrib/gcc/genattr.c
index 591e0d7997ef..49f368e53fce 100644
--- a/contrib/gcc/genattr.c
+++ b/contrib/gcc/genattr.c
@@ -1,5 +1,6 @@
/* Generate attribute information (insn-attr.h) from machine description.
- Copyright (C) 1991, 1994, 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1994, 1996, 1998, 1999, 2000, 2003
+ Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GCC.
@@ -20,8 +21,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "gensupport.h"
@@ -49,52 +52,46 @@ struct function_unit
struct range issue_delay; /* Range of issue delay values. */
};
-static void extend_range PARAMS ((struct range *, int, int));
-static void init_range PARAMS ((struct range *));
-static void write_upcase PARAMS ((const char *));
-static void gen_attr PARAMS ((rtx));
-static void write_units PARAMS ((int, struct range *, struct range *,
- struct range *, struct range *,
- struct range *));
+static void extend_range (struct range *, int, int);
+static void init_range (struct range *);
+static void write_upcase (const char *);
+static void gen_attr (rtx);
+static void write_units (int, struct range *, struct range *,
+ struct range *, struct range *,
+ struct range *);
static void
-extend_range (range, min, max)
- struct range *range;
- int min;
- int max;
+extend_range (struct range *range, int min, int max)
{
if (range->min > min) range->min = min;
if (range->max < max) range->max = max;
}
static void
-init_range (range)
- struct range *range;
+init_range (struct range *range)
{
range->min = 100000;
range->max = -1;
}
static void
-write_upcase (str)
- const char *str;
+write_upcase (const char *str)
{
for (; *str; str++)
putchar (TOUPPER(*str));
}
static void
-gen_attr (attr)
- rtx attr;
+gen_attr (rtx attr)
{
const char *p, *tag;
- int is_const = GET_CODE (XEXP (attr, 2)) == CONST;
+ int is_const = GET_CODE (XEXP (attr, 2)) == CONST;
printf ("#define HAVE_ATTR_%s\n", XSTR (attr, 0));
/* If numeric attribute, don't need to write an enum. */
p = XSTR (attr, 1);
if (*p == '\0')
- printf ("extern int get_attr_%s PARAMS ((%s));\n", XSTR (attr, 0),
+ printf ("extern int get_attr_%s (%s);\n", XSTR (attr, 0),
(is_const ? "void" : "rtx"));
else
{
@@ -111,7 +108,7 @@ gen_attr (attr)
}
fputs ("};\n", stdout);
- printf ("extern enum attr_%s get_attr_%s PARAMS ((%s));\n\n",
+ printf ("extern enum attr_%s get_attr_%s (%s);\n\n",
XSTR (attr, 0), XSTR (attr, 0), (is_const ? "void" : "rtx"));
}
@@ -120,29 +117,24 @@ gen_attr (attr)
if (! strcmp (XSTR (attr, 0), "length"))
{
puts ("\
-extern void shorten_branches PARAMS ((rtx));\n\
-extern int insn_default_length PARAMS ((rtx));\n\
-extern int insn_variable_length_p PARAMS ((rtx));\n\
-extern int insn_current_length PARAMS ((rtx));\n\n\
+extern void shorten_branches (rtx);\n\
+extern int insn_default_length (rtx);\n\
+extern int insn_variable_length_p (rtx);\n\
+extern int insn_current_length (rtx);\n\n\
#include \"insn-addr.h\"\n");
}
}
static void
-write_units (num_units, multiplicity, simultaneity,
- ready_cost, issue_delay, blockage)
- int num_units;
- struct range *multiplicity;
- struct range *simultaneity;
- struct range *ready_cost;
- struct range *issue_delay;
- struct range *blockage;
+write_units (int num_units, struct range *multiplicity, struct range *simultaneity,
+ struct range *ready_cost, struct range *issue_delay,
+ struct range *blockage)
{
int i, q_size;
printf ("#define INSN_SCHEDULING\n\n");
- printf ("extern int result_ready_cost PARAMS ((rtx));\n");
- printf ("extern int function_units_used PARAMS ((rtx));\n\n");
+ printf ("extern int result_ready_cost (rtx);\n");
+ printf ("extern int function_units_used (rtx);\n\n");
printf ("extern const struct function_unit_desc\n");
printf ("{\n");
printf (" const char *const name;\n");
@@ -151,11 +143,11 @@ write_units (num_units, multiplicity, simultaneity,
printf (" const int simultaneity;\n");
printf (" const int default_cost;\n");
printf (" const int max_issue_delay;\n");
- printf (" int (*const ready_cost_function) PARAMS ((rtx));\n");
- printf (" int (*const conflict_cost_function) PARAMS ((rtx, rtx));\n");
+ printf (" int (*const ready_cost_function) (rtx);\n");
+ printf (" int (*const conflict_cost_function) (rtx, rtx);\n");
printf (" const int max_blockage;\n");
- printf (" unsigned int (*const blockage_range_function) PARAMS ((rtx));\n");
- printf (" int (*const blockage_function) PARAMS ((rtx, rtx));\n");
+ printf (" unsigned int (*const blockage_range_function) (rtx);\n");
+ printf (" int (*const blockage_function) (rtx, rtx);\n");
printf ("} function_units[];\n\n");
printf ("#define FUNCTION_UNITS_SIZE %d\n", num_units);
printf ("#define MIN_MULTIPLICITY %d\n", multiplicity->min);
@@ -173,19 +165,15 @@ write_units (num_units, multiplicity, simultaneity,
printf ("#define BLOCKAGE_BITS %d\n", i + 1);
/* INSN_QUEUE_SIZE is a power of two larger than MAX_BLOCKAGE and
- MAX_READY_COST. This is the longest time an isnsn may be queued. */
+ MAX_READY_COST. This is the longest time an insn may be queued. */
i = MAX (blockage->max, ready_cost->max);
for (q_size = 1; q_size <= i; q_size <<= 1)
;
printf ("#define INSN_QUEUE_SIZE %d\n", q_size);
}
-extern int main PARAMS ((int, char **));
-
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
rtx desc;
int have_delay = 0;
@@ -222,7 +210,7 @@ main (argc, argv)
puts ("#define HAVE_ATTR_alternative");
puts ("#define get_attr_alternative(insn) which_alternative");
-
+
/* Read the machine description. */
while (1)
@@ -241,9 +229,9 @@ main (argc, argv)
if (! have_delay)
{
printf ("#define DELAY_SLOTS\n");
- printf ("extern int num_delay_slots PARAMS ((rtx));\n");
- printf ("extern int eligible_for_delay PARAMS ((rtx, int, rtx, int));\n\n");
- printf ("extern int const_num_delay_slots PARAMS ((rtx));\n\n");
+ printf ("extern int num_delay_slots (rtx);\n");
+ printf ("extern int eligible_for_delay (rtx, int, rtx, int);\n\n");
+ printf ("extern int const_num_delay_slots (rtx);\n\n");
have_delay = 1;
}
@@ -252,14 +240,14 @@ main (argc, argv)
if (XVECEXP (desc, 1, i + 1) && ! have_annul_true)
{
printf ("#define ANNUL_IFTRUE_SLOTS\n");
- printf ("extern int eligible_for_annul_true PARAMS ((rtx, int, rtx, int));\n");
+ printf ("extern int eligible_for_annul_true (rtx, int, rtx, int);\n");
have_annul_true = 1;
}
if (XVECEXP (desc, 1, i + 2) && ! have_annul_false)
{
printf ("#define ANNUL_IFFALSE_SLOTS\n");
- printf ("extern int eligible_for_annul_false PARAMS ((rtx, int, rtx, int));\n");
+ printf ("extern int eligible_for_annul_false (rtx, int, rtx, int);\n");
have_annul_false = 1;
}
}
@@ -280,8 +268,7 @@ main (argc, argv)
if (unit == 0)
{
- unit = (struct function_unit *)
- xmalloc (sizeof (struct function_unit));
+ unit = xmalloc (sizeof (struct function_unit));
unit->name = xstrdup (name);
unit->multiplicity = multiplicity;
unit->simultaneity = simultaneity;
@@ -359,6 +346,9 @@ main (argc, argv)
/* Output interface for pipeline hazards recognition based on
DFA (deterministic finite state automata. */
printf ("\n/* DFA based pipeline interface. */");
+ printf ("\n#ifndef AUTOMATON_ALTS\n");
+ printf ("#define AUTOMATON_ALTS 0\n");
+ printf ("#endif\n\n");
printf ("\n#ifndef AUTOMATON_STATE_ALTS\n");
printf ("#define AUTOMATON_STATE_ALTS 0\n");
printf ("#endif\n\n");
@@ -374,28 +364,30 @@ main (argc, argv)
printf (" same processor cycle. */\n");
printf ("#define MAX_DFA_ISSUE_RATE max_dfa_issue_rate\n\n");
printf ("/* Insn latency time defined in define_insn_reservation. */\n");
- printf ("extern int insn_default_latency PARAMS ((rtx));\n\n");
+ printf ("extern int insn_default_latency (rtx);\n\n");
printf ("/* Return nonzero if there is a bypass for given insn\n");
printf (" which is a data producer. */\n");
- printf ("extern int bypass_p PARAMS ((rtx));\n\n");
+ printf ("extern int bypass_p (rtx);\n\n");
printf ("/* Insn latency time on data consumed by the 2nd insn.\n");
printf (" Use the function if bypass_p returns nonzero for\n");
printf (" the 1st insn. */\n");
- printf ("extern int insn_latency PARAMS ((rtx, rtx));\n\n");
+ printf ("extern int insn_latency (rtx, rtx);\n\n");
+ printf ("\n#if AUTOMATON_ALTS\n");
printf ("/* The following function returns number of alternative\n");
printf (" reservations of given insn. It may be used for better\n");
printf (" insns scheduling heuristics. */\n");
- printf ("extern int insn_alts PARAMS ((rtx));\n\n");
+ printf ("extern int insn_alts (rtx);\n\n");
+ printf ("#endif\n\n");
printf ("/* Maximal possible number of insns waiting results being\n");
printf (" produced by insns whose execution is not finished. */\n");
printf ("extern int max_insn_queue_index;\n\n");
printf ("/* Pointer to data describing current state of DFA. */\n");
printf ("typedef void *state_t;\n\n");
printf ("/* Size of the data in bytes. */\n");
- printf ("extern int state_size PARAMS ((void));\n\n");
+ printf ("extern int state_size (void);\n\n");
printf ("/* Initiate given DFA state, i.e. Set up the state\n");
printf (" as all functional units were not reserved. */\n");
- printf ("extern void state_reset PARAMS ((state_t));\n");
+ printf ("extern void state_reset (state_t);\n");
printf ("/* The following function returns negative value if given\n");
printf (" insn can be issued in processor state described by given\n");
printf (" DFA state. In this case, the DFA state is changed to\n");
@@ -405,7 +397,7 @@ main (argc, argv)
printf (" for superscalar or VLIW processors. If the second\n");
printf (" parameter is NULL the function changes given DFA state\n");
printf (" as new processor cycle started. */\n");
- printf ("extern int state_transition PARAMS ((state_t, rtx));\n");
+ printf ("extern int state_transition (state_t, rtx);\n");
printf ("\n#if AUTOMATON_STATE_ALTS\n");
printf ("/* The following function returns number of possible\n");
printf (" alternative reservations of given insn in given\n");
@@ -413,12 +405,12 @@ main (argc, argv)
printf (" heuristics. By default the function is defined if\n");
printf (" macro AUTOMATON_STATE_ALTS is defined because its\n");
printf (" implementation may require much memory. */\n");
- printf ("extern int state_alts PARAMS ((state_t, rtx));\n");
+ printf ("extern int state_alts (state_t, rtx);\n");
printf ("#endif\n\n");
- printf ("extern int min_issue_delay PARAMS ((state_t, rtx));\n");
+ printf ("extern int min_issue_delay (state_t, rtx);\n");
printf ("/* The following function returns nonzero if no one insn\n");
printf (" can be issued in current DFA state. */\n");
- printf ("extern int state_dead_lock_p PARAMS ((state_t));\n");
+ printf ("extern int state_dead_lock_p (state_t);\n");
printf ("/* The function returns minimal delay of issue of the 2nd\n");
printf (" insn after issuing the 1st insn in given DFA state.\n");
printf (" The 1st insn should be issued in given state (i.e.\n");
@@ -426,25 +418,30 @@ main (argc, argv)
printf (" the insn and the state). Data dependencies between\n");
printf (" the insns are ignored by the function. */\n");
printf
- ("extern int min_insn_conflict_delay PARAMS ((state_t, rtx, rtx));\n");
+ ("extern int min_insn_conflict_delay (state_t, rtx, rtx);\n");
printf ("/* The following function outputs reservations for given\n");
printf (" insn as they are described in the corresponding\n");
printf (" define_insn_reservation. */\n");
- printf ("extern void print_reservation PARAMS ((FILE *, rtx));\n");
+ printf ("extern void print_reservation (FILE *, rtx);\n");
printf ("\n#if CPU_UNITS_QUERY\n");
printf ("/* The following function returns code of functional unit\n");
printf (" with given name (see define_cpu_unit). */\n");
- printf ("extern int get_cpu_unit_code PARAMS ((const char *));\n");
+ printf ("extern int get_cpu_unit_code (const char *);\n");
printf ("/* The following function returns nonzero if functional\n");
printf (" unit with given code is currently reserved in given\n");
printf (" DFA state. */\n");
- printf ("extern int cpu_unit_reservation_p PARAMS ((state_t, int));\n");
+ printf ("extern int cpu_unit_reservation_p (state_t, int);\n");
printf ("#endif\n\n");
+ printf ("/* Clean insn code cache. It should be called if there\n");
+ printf (" is a chance that condition value in a\n");
+ printf (" define_insn_reservation will be changed after\n");
+ printf (" last call of dfa_start. */\n");
+ printf ("extern void dfa_clean_insn_cache (void);\n\n");
printf ("/* Initiate and finish work with DFA. They should be\n");
printf (" called as the first and the last interface\n");
printf (" functions. */\n");
- printf ("extern void dfa_start PARAMS ((void));\n");
- printf ("extern void dfa_finish PARAMS ((void));\n");
+ printf ("extern void dfa_start (void);\n");
+ printf ("extern void dfa_finish (void);\n");
}
else
{
@@ -453,7 +450,7 @@ main (argc, argv)
printf ("typedef void *state_t;\n\n");
}
- /* Output flag masks for use by reorg.
+ /* Output flag masks for use by reorg.
Flags are used to hold branch direction and prediction information
for use by eligible_for_... */
@@ -474,8 +471,7 @@ main (argc, argv)
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
const char *
-get_insn_name (code)
- int code ATTRIBUTE_UNUSED;
+get_insn_name (int code ATTRIBUTE_UNUSED)
{
return NULL;
}
diff --git a/contrib/gcc/genattrtab.c b/contrib/gcc/genattrtab.c
index 47a6f00c25ea..56c62e386785 100644
--- a/contrib/gcc/genattrtab.c
+++ b/contrib/gcc/genattrtab.c
@@ -1,6 +1,6 @@
/* Generate code from machine description to compute values of attributes.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GCC.
@@ -100,8 +100,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), integrated))
#define ATTR_EQ_ATTR_P(RTX) (RTX_FLAG((RTX), volatil))
-#include "hconfig.h"
+#if 0
+#define strcmp_check(S1, S2) ((S1) == (S2) \
+ ? 0 \
+ : (strcmp ((S1), (S2)) \
+ ? 1 \
+ : (abort (), 0)))
+#else
+#define strcmp_check(S1, S2) ((S1) != (S2))
+#endif
+
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "ggc.h"
#include "gensupport.h"
@@ -173,16 +185,17 @@ struct attr_desc
{
char *name; /* Name of attribute. */
struct attr_desc *next; /* Next attribute. */
+ struct attr_value *first_value; /* First value of this attribute. */
+ struct attr_value *default_val; /* Default value for this attribute. */
+ int lineno : 24; /* Line number. */
unsigned is_numeric : 1; /* Values of this attribute are numeric. */
unsigned negative_ok : 1; /* Allow negative numeric values. */
unsigned unsigned_p : 1; /* Make the output function unsigned int. */
unsigned is_const : 1; /* Attribute value constant for each run. */
unsigned is_special : 1; /* Don't call `write_attr_set'. */
- unsigned func_units_p : 1; /* this is the function_units attribute */
- unsigned blockage_p : 1; /* this is the blockage range function */
- struct attr_value *first_value; /* First value of this attribute. */
- struct attr_value *default_val; /* Default value for this attribute. */
- int lineno; /* Line number. */
+ unsigned func_units_p : 1; /* This is the function_units attribute. */
+ unsigned blockage_p : 1; /* This is the blockage range function. */
+ unsigned static_p : 1; /* Make the output function static. */
};
#define NULL_ATTR (struct attr_desc *) NULL
@@ -336,6 +349,10 @@ static rtx true_rtx, false_rtx;
/* Used to reduce calls to `strcmp' */
static char *alternative_name;
+static const char *length_str;
+static const char *delay_type_str;
+static const char *delay_1_0_str;
+static const char *num_delay_slots_str;
/* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
called. */
@@ -362,109 +379,111 @@ int optimize = 0;
(EXP) = (XSTR ((EXP), 1) == current_alternative_string \
? true_rtx : false_rtx);
+#define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
+
/* These are referenced by rtlanal.c and hence need to be defined somewhere.
They won't actually be used. */
rtx global_rtl[GR_MAX];
rtx pic_offset_table_rtx;
-static void attr_hash_add_rtx PARAMS ((int, rtx));
-static void attr_hash_add_string PARAMS ((int, char *));
-static rtx attr_rtx PARAMS ((enum rtx_code, ...));
-static rtx attr_rtx_1 PARAMS ((enum rtx_code, va_list));
-static char *attr_string PARAMS ((const char *, int));
-static rtx check_attr_value PARAMS ((rtx, struct attr_desc *));
-static rtx convert_set_attr_alternative PARAMS ((rtx, struct insn_def *));
-static rtx convert_set_attr PARAMS ((rtx, struct insn_def *));
-static void check_defs PARAMS ((void));
-#if 0
-static rtx convert_const_symbol_ref PARAMS ((rtx, struct attr_desc *));
-#endif
-static rtx make_canonical PARAMS ((struct attr_desc *, rtx));
-static struct attr_value *get_attr_value PARAMS ((rtx, struct attr_desc *, int));
-static rtx copy_rtx_unchanging PARAMS ((rtx));
-static rtx copy_boolean PARAMS ((rtx));
-static void expand_delays PARAMS ((void));
-static rtx operate_exp PARAMS ((enum operator, rtx, rtx));
-static void expand_units PARAMS ((void));
-static rtx simplify_knowing PARAMS ((rtx, rtx));
-static rtx encode_units_mask PARAMS ((rtx));
-static void fill_attr PARAMS ((struct attr_desc *));
-static rtx substitute_address PARAMS ((rtx, rtx (*) (rtx), rtx (*) (rtx)));
-static void make_length_attrs PARAMS ((void));
-static rtx identity_fn PARAMS ((rtx));
-static rtx zero_fn PARAMS ((rtx));
-static rtx one_fn PARAMS ((rtx));
-static rtx max_fn PARAMS ((rtx));
-static void write_length_unit_log PARAMS ((void));
-static rtx simplify_cond PARAMS ((rtx, int, int));
-#if 0
-static rtx simplify_by_alternatives PARAMS ((rtx, int, int));
-#endif
-static rtx simplify_by_exploding PARAMS ((rtx));
-static int find_and_mark_used_attributes PARAMS ((rtx, rtx *, int *));
-static void unmark_used_attributes PARAMS ((rtx, struct dimension *, int));
-static int add_values_to_cover PARAMS ((struct dimension *));
-static int increment_current_value PARAMS ((struct dimension *, int));
-static rtx test_for_current_value PARAMS ((struct dimension *, int));
-static rtx simplify_with_current_value PARAMS ((rtx, struct dimension *, int));
-static rtx simplify_with_current_value_aux PARAMS ((rtx));
-static void clear_struct_flag PARAMS ((rtx));
-static int count_sub_rtxs PARAMS ((rtx, int));
-static void remove_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
-static void insert_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
-static rtx insert_right_side PARAMS ((enum rtx_code, rtx, rtx, int, int));
-static rtx make_alternative_compare PARAMS ((int));
-static int compute_alternative_mask PARAMS ((rtx, enum rtx_code));
-static rtx evaluate_eq_attr PARAMS ((rtx, rtx, int, int));
-static rtx simplify_and_tree PARAMS ((rtx, rtx *, int, int));
-static rtx simplify_or_tree PARAMS ((rtx, rtx *, int, int));
-static rtx simplify_test_exp PARAMS ((rtx, int, int));
-static rtx simplify_test_exp_in_temp PARAMS ((rtx, int, int));
-static void optimize_attrs PARAMS ((void));
-static void gen_attr PARAMS ((rtx, int));
-static int count_alternatives PARAMS ((rtx));
-static int compares_alternatives_p PARAMS ((rtx));
-static int contained_in_p PARAMS ((rtx, rtx));
-static void gen_insn PARAMS ((rtx, int));
-static void gen_delay PARAMS ((rtx, int));
-static void gen_unit PARAMS ((rtx, int));
-static void write_test_expr PARAMS ((rtx, int));
-static int max_attr_value PARAMS ((rtx, int*));
-static int or_attr_value PARAMS ((rtx, int*));
-static void walk_attr_value PARAMS ((rtx));
-static void write_attr_get PARAMS ((struct attr_desc *));
-static rtx eliminate_known_true PARAMS ((rtx, rtx, int, int));
-static void write_attr_set PARAMS ((struct attr_desc *, int, rtx,
- const char *, const char *, rtx,
- int, int));
-static void write_attr_case PARAMS ((struct attr_desc *, struct attr_value *,
- int, const char *, const char *, int, rtx));
-static void write_unit_name PARAMS ((const char *, int, const char *));
-static void write_attr_valueq PARAMS ((struct attr_desc *, const char *));
-static void write_attr_value PARAMS ((struct attr_desc *, rtx));
-static void write_upcase PARAMS ((const char *));
-static void write_indent PARAMS ((int));
-static void write_eligible_delay PARAMS ((const char *));
-static void write_function_unit_info PARAMS ((void));
-static void write_complex_function PARAMS ((struct function_unit *, const char *,
- const char *));
-static int write_expr_attr_cache PARAMS ((rtx, struct attr_desc *));
-static void write_toplevel_expr PARAMS ((rtx));
-static void write_const_num_delay_slots PARAMS ((void));
-static char *next_comma_elt PARAMS ((const char **));
-static struct attr_desc *find_attr PARAMS ((const char *, int));
-static struct attr_value *find_most_used PARAMS ((struct attr_desc *));
-static rtx find_single_value PARAMS ((struct attr_desc *));
-static void extend_range PARAMS ((struct range *, int, int));
-static rtx attr_eq PARAMS ((const char *, const char *));
-static const char *attr_numeral PARAMS ((int));
-static int attr_equal_p PARAMS ((rtx, rtx));
-static rtx attr_copy_rtx PARAMS ((rtx));
-static int attr_rtx_cost PARAMS ((rtx));
+static void attr_hash_add_rtx (int, rtx);
+static void attr_hash_add_string (int, char *);
+static rtx attr_rtx (enum rtx_code, ...);
+static rtx attr_rtx_1 (enum rtx_code, va_list);
+static char *attr_string (const char *, int);
+static rtx check_attr_value (rtx, struct attr_desc *);
+static rtx convert_set_attr_alternative (rtx, struct insn_def *);
+static rtx convert_set_attr (rtx, struct insn_def *);
+static void check_defs (void);
+static rtx make_canonical (struct attr_desc *, rtx);
+static struct attr_value *get_attr_value (rtx, struct attr_desc *, int);
+static rtx copy_rtx_unchanging (rtx);
+static rtx copy_boolean (rtx);
+static void expand_delays (void);
+static rtx operate_exp (enum operator, rtx, rtx);
+static void expand_units (void);
+static rtx simplify_knowing (rtx, rtx);
+static rtx encode_units_mask (rtx);
+static void fill_attr (struct attr_desc *);
+static rtx substitute_address (rtx, rtx (*) (rtx), rtx (*) (rtx));
+static void make_length_attrs (void);
+static rtx identity_fn (rtx);
+static rtx zero_fn (rtx);
+static rtx one_fn (rtx);
+static rtx max_fn (rtx);
+static void write_length_unit_log (void);
+static rtx simplify_cond (rtx, int, int);
+static rtx simplify_by_exploding (rtx);
+static int find_and_mark_used_attributes (rtx, rtx *, int *);
+static void unmark_used_attributes (rtx, struct dimension *, int);
+static int add_values_to_cover (struct dimension *);
+static int increment_current_value (struct dimension *, int);
+static rtx test_for_current_value (struct dimension *, int);
+static rtx simplify_with_current_value (rtx, struct dimension *, int);
+static rtx simplify_with_current_value_aux (rtx);
+static void clear_struct_flag (rtx);
+static void remove_insn_ent (struct attr_value *, struct insn_ent *);
+static void insert_insn_ent (struct attr_value *, struct insn_ent *);
+static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
+static rtx make_alternative_compare (int);
+static int compute_alternative_mask (rtx, enum rtx_code);
+static rtx evaluate_eq_attr (rtx, rtx, int, int);
+static rtx simplify_and_tree (rtx, rtx *, int, int);
+static rtx simplify_or_tree (rtx, rtx *, int, int);
+static rtx simplify_test_exp (rtx, int, int);
+static rtx simplify_test_exp_in_temp (rtx, int, int);
+static void optimize_attrs (void);
+static void gen_attr (rtx, int);
+static int count_alternatives (rtx);
+static int compares_alternatives_p (rtx);
+static int contained_in_p (rtx, rtx);
+static void gen_insn (rtx, int);
+static void gen_delay (rtx, int);
+static void gen_unit (rtx, int);
+static void write_test_expr (rtx, int);
+static int max_attr_value (rtx, int*);
+static int or_attr_value (rtx, int*);
+static void walk_attr_value (rtx);
+static void write_attr_get (struct attr_desc *);
+static rtx eliminate_known_true (rtx, rtx, int, int);
+static void write_attr_set (struct attr_desc *, int, rtx,
+ const char *, const char *, rtx,
+ int, int);
+static void write_attr_case (struct attr_desc *, struct attr_value *,
+ int, const char *, const char *, int, rtx);
+static void write_unit_name (const char *, int, const char *);
+static void write_attr_valueq (struct attr_desc *, const char *);
+static void write_attr_value (struct attr_desc *, rtx);
+static void write_upcase (const char *);
+static void write_indent (int);
+static void write_eligible_delay (const char *);
+static void write_function_unit_info (void);
+static void write_complex_function (struct function_unit *, const char *,
+ const char *);
+static int write_expr_attr_cache (rtx, struct attr_desc *);
+static void write_toplevel_expr (rtx);
+static void write_const_num_delay_slots (void);
+static char *next_comma_elt (const char **);
+static struct attr_desc *find_attr (const char **, int);
+static struct attr_value *find_most_used (struct attr_desc *);
+static rtx find_single_value (struct attr_desc *);
+static void extend_range (struct range *, int, int);
+static rtx attr_eq (const char *, const char *);
+static const char *attr_numeral (int);
+static int attr_equal_p (rtx, rtx);
+static rtx attr_copy_rtx (rtx);
+static int attr_rtx_cost (rtx);
+static bool attr_alt_subset_p (rtx, rtx);
+static bool attr_alt_subset_of_compl_p (rtx, rtx);
+static rtx attr_alt_intersection (rtx, rtx);
+static rtx attr_alt_union (rtx, rtx);
+static rtx attr_alt_complement (rtx);
+static bool attr_alt_bit_p (rtx, int);
+static rtx mk_attr_alt (int);
#define oballoc(size) obstack_alloc (hash_obstack, size)
-
+
/* Hash table for sharing RTL and strings. */
/* Each hash table slot is a bucket containing a chain of these structures.
@@ -499,14 +518,11 @@ struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
/* Add an entry to the hash table for RTL with hash code HASHCODE. */
static void
-attr_hash_add_rtx (hashcode, rtl)
- int hashcode;
- rtx rtl;
+attr_hash_add_rtx (int hashcode, rtx rtl)
{
struct attr_hash *h;
- h = (struct attr_hash *) obstack_alloc (hash_obstack,
- sizeof (struct attr_hash));
+ h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
h->hashcode = hashcode;
h->u.rtl = rtl;
h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
@@ -516,14 +532,11 @@ attr_hash_add_rtx (hashcode, rtl)
/* Add an entry to the hash table for STRING with hash code HASHCODE. */
static void
-attr_hash_add_string (hashcode, str)
- int hashcode;
- char *str;
+attr_hash_add_string (int hashcode, char *str)
{
struct attr_hash *h;
- h = (struct attr_hash *) obstack_alloc (hash_obstack,
- sizeof (struct attr_hash));
+ h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
h->hashcode = -hashcode;
h->u.str = str;
h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
@@ -541,9 +554,7 @@ attr_hash_add_string (hashcode, str)
rtx attr_rtx (code, [element1, ..., elementn]) */
static rtx
-attr_rtx_1 (code, p)
- enum rtx_code code;
- va_list p;
+attr_rtx_1 (enum rtx_code code, va_list p)
{
rtx rt_val = NULL_RTX;/* RTX to return to caller... */
int hashcode;
@@ -617,8 +628,7 @@ attr_rtx_1 (code, p)
{
char *arg0 = va_arg (p, char *);
- if (code == SYMBOL_REF)
- arg0 = attr_string (arg0, strlen (arg0));
+ arg0 = DEF_ATTR_STRING (arg0);
hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
@@ -717,14 +727,14 @@ attr_rtx_1 (code, p)
}
static rtx
-attr_rtx VPARAMS ((enum rtx_code code, ...))
+attr_rtx (enum rtx_code code, ...)
{
rtx result;
-
- VA_OPEN (p, code);
- VA_FIXEDARG (p, enum rtx_code, code);
+ va_list p;
+
+ va_start (p, code);
result = attr_rtx_1 (code, p);
- VA_CLOSE (p);
+ va_end (p);
return result;
}
@@ -734,34 +744,30 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
rtx attr_printf (len, format, [arg1, ..., argn]) */
char *
-attr_printf VPARAMS ((unsigned int len, const char *fmt, ...))
+attr_printf (unsigned int len, const char *fmt, ...)
{
char str[256];
+ va_list p;
+
+ va_start (p, fmt);
- VA_OPEN (p, fmt);
- VA_FIXEDARG (p, unsigned int, len);
- VA_FIXEDARG (p, const char *, fmt);
-
if (len > sizeof str - 1) /* Leave room for \0. */
abort ();
vsprintf (str, fmt, p);
- VA_CLOSE (p);
+ va_end (p);
- return attr_string (str, strlen (str));
+ return DEF_ATTR_STRING (str);
}
static rtx
-attr_eq (name, value)
- const char *name, *value;
+attr_eq (const char *name, const char *value)
{
- return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
- attr_string (value, strlen (value)));
+ return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
}
static const char *
-attr_numeral (n)
- int n;
+attr_numeral (int n)
{
return XSTR (make_numeric_value (n), 0);
}
@@ -770,9 +776,7 @@ attr_numeral (n)
to be null terminated) with LEN bytes. */
static char *
-attr_string (str, len)
- const char *str;
- int len;
+attr_string (const char *str, int len)
{
struct attr_hash *h;
int hashcode;
@@ -793,7 +797,7 @@ attr_string (str, len)
return h->u.str; /* <-- return if found. */
/* Not found; create a permanent copy and add it to the hash table. */
- new_str = (char *) obstack_alloc (hash_obstack, len + 1);
+ new_str = obstack_alloc (hash_obstack, len + 1);
memcpy (new_str, str, len);
new_str[len] = '\0';
attr_hash_add_string (hashcode, new_str);
@@ -806,20 +810,18 @@ attr_string (str, len)
then they can't be equal unless they are the same object. */
static int
-attr_equal_p (x, y)
- rtx x, y;
+attr_equal_p (rtx x, rtx y)
{
return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
&& rtx_equal_p (x, y)));
}
-
+
/* Copy an attribute value expression,
descending to all depths, but not copying any
permanent hashed subexpressions. */
static rtx
-attr_copy_rtx (orig)
- rtx orig;
+attr_copy_rtx (rtx orig)
{
rtx copy;
int i, j;
@@ -899,7 +901,7 @@ attr_copy_rtx (orig)
}
return copy;
}
-
+
/* Given a test expression for an attribute, ensure it is validly formed.
IS_CONST indicates whether the expression is constant for each compiler
run (a constant expression may not test any particular insn).
@@ -915,10 +917,7 @@ attr_copy_rtx (orig)
Return the new expression, if any. */
rtx
-check_attr_test (exp, is_const, lineno)
- rtx exp;
- int is_const;
- int lineno;
+check_attr_test (rtx exp, int is_const, int lineno)
{
struct attr_desc *attr;
struct attr_value *av;
@@ -937,16 +936,11 @@ check_attr_test (exp, is_const, lineno)
else if (n_comma_elts (XSTR (exp, 1)) == 1)
{
- attr = find_attr (XSTR (exp, 0), 0);
+ attr = find_attr (&XSTR (exp, 0), 0);
if (attr == NULL)
{
if (! strcmp (XSTR (exp, 0), "alternative"))
- {
- XSTR (exp, 0) = alternative_name;
- /* This can't be simplified any further. */
- ATTR_IND_SIMPLIFIED_P (exp) = 1;
- return exp;
- }
+ return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
else
fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
}
@@ -986,16 +980,29 @@ check_attr_test (exp, is_const, lineno)
}
else
{
- /* Make an IOR tree of the possible values. */
- orexp = false_rtx;
- name_ptr = XSTR (exp, 1);
- while ((p = next_comma_elt (&name_ptr)) != NULL)
+ if (! strcmp (XSTR (exp, 0), "alternative"))
{
- newexp = attr_eq (XSTR (exp, 0), p);
- orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
+ int set = 0;
+
+ name_ptr = XSTR (exp, 1);
+ while ((p = next_comma_elt (&name_ptr)) != NULL)
+ set |= 1 << atoi (p);
+
+ return mk_attr_alt (set);
}
+ else
+ {
+ /* Make an IOR tree of the possible values. */
+ orexp = false_rtx;
+ name_ptr = XSTR (exp, 1);
+ while ((p = next_comma_elt (&name_ptr)) != NULL)
+ {
+ newexp = attr_eq (XSTR (exp, 0), p);
+ orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
+ }
- return check_attr_test (orexp, is_const, lineno);
+ return check_attr_test (orexp, is_const, lineno);
+ }
}
break;
@@ -1056,7 +1063,7 @@ check_attr_test (exp, is_const, lineno)
return exp;
}
-
+
/* Given an expression, ensure that it is validly formed and that all named
attribute values are valid for the given attribute. Issue a fatal error
if not. If no attribute is specified, assume a numeric attribute.
@@ -1064,9 +1071,7 @@ check_attr_test (exp, is_const, lineno)
Return a perhaps modified replacement expression for the value. */
static rtx
-check_attr_value (exp, attr)
- rtx exp;
- struct attr_desc *attr;
+check_attr_value (rtx exp, struct attr_desc *attr)
{
struct attr_value *av;
const char *p;
@@ -1150,7 +1155,7 @@ check_attr_value (exp, attr)
have_error = 1;
break;
}
- /* FALLTHRU */
+ /* Fall through. */
case IOR:
case AND:
@@ -1159,6 +1164,10 @@ check_attr_value (exp, attr)
break;
case FFS:
+ case CLZ:
+ case CTZ:
+ case POPCOUNT:
+ case PARITY:
XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
break;
@@ -1185,7 +1194,7 @@ check_attr_value (exp, attr)
case ATTR:
{
- struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0);
+ struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
if (attr2 == NULL)
{
message_with_line (attr ? attr->lineno : 0,
@@ -1228,14 +1237,12 @@ check_attr_value (exp, attr)
return exp;
}
-
+
/* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
It becomes a COND with each test being (eq_attr "alternative "n") */
static rtx
-convert_set_attr_alternative (exp, id)
- rtx exp;
- struct insn_def *id;
+convert_set_attr_alternative (rtx exp, struct insn_def *id)
{
int num_alt = id->num_alternatives;
rtx condexp;
@@ -1267,14 +1274,12 @@ convert_set_attr_alternative (exp, id)
return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
}
-
+
/* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
static rtx
-convert_set_attr (exp, id)
- rtx exp;
- struct insn_def *id;
+convert_set_attr (rtx exp, struct insn_def *id)
{
rtx newexp;
const char *name_ptr;
@@ -1300,13 +1305,13 @@ convert_set_attr (exp, id)
return convert_set_attr_alternative (newexp, id);
}
-
+
/* Scan all definitions, checking for validity. Also, convert any SET_ATTR
and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
expressions. */
static void
-check_defs ()
+check_defs (void)
{
struct insn_def *id;
struct attr_desc *attr;
@@ -1349,7 +1354,7 @@ check_defs ()
if (value == NULL_RTX)
continue;
- if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
+ if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
{
message_with_line (id->lineno, "unknown attribute %s",
XSTR (XEXP (value, 0), 0));
@@ -1362,68 +1367,14 @@ check_defs ()
}
}
}
-
-#if 0
-/* Given a constant SYMBOL_REF expression, convert to a COND that
- explicitly tests each enumerated value. */
-
-static rtx
-convert_const_symbol_ref (exp, attr)
- rtx exp;
- struct attr_desc *attr;
-{
- rtx condexp;
- struct attr_value *av;
- int i;
- int num_alt = 0;
-
- for (av = attr->first_value; av; av = av->next)
- num_alt++;
-
- /* Make a COND with all tests but the last, and in the original order.
- Select the last value via the default. Note that the attr values
- are constructed in reverse order. */
-
- condexp = rtx_alloc (COND);
- XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
- av = attr->first_value;
- XEXP (condexp, 1) = av->value;
- for (i = num_alt - 2; av = av->next, i >= 0; i--)
- {
- char *p, *string;
- rtx value;
-
- string = p = (char *) oballoc (2
- + strlen (attr->name)
- + strlen (XSTR (av->value, 0)));
- strcpy (p, attr->name);
- strcat (p, "_");
- strcat (p, XSTR (av->value, 0));
- for (; *p != '\0'; p++)
- *p = TOUPPER (*p);
-
- value = attr_rtx (SYMBOL_REF, string);
- ATTR_IND_SIMPLIFIED_P (value) = 1;
-
- XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
-
- XVECEXP (condexp, 0, 2 * i + 1) = av->value;
- }
-
- return condexp;
-}
-#endif
-
/* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
expressions by converting them into a COND. This removes cases from this
program. Also, replace an attribute value of "*" with the default attribute
value. */
static rtx
-make_canonical (attr, exp)
- struct attr_desc *attr;
- rtx exp;
+make_canonical (struct attr_desc *attr, rtx exp)
{
int i;
rtx newexp;
@@ -1441,6 +1392,8 @@ make_canonical (attr, exp)
fatal ("(attr_value \"*\") used in invalid context");
exp = attr->default_val->value;
}
+ else
+ XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
break;
@@ -1451,21 +1404,8 @@ make_canonical (attr, exp)
This makes the COND something that won't be considered an arbitrary
expression by walk_attr_value. */
ATTR_IND_SIMPLIFIED_P (exp) = 1;
-#if 0
- /* ??? Why do we do this? With attribute values { A B C D E }, this
- tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
- than (x==E). */
- exp = convert_const_symbol_ref (exp, attr);
- ATTR_IND_SIMPLIFIED_P (exp) = 1;
- exp = check_attr_value (exp, attr);
- /* Goto COND case since this is now a COND. Note that while the
- new expression is rescanned, all symbol_ref notes are marked as
- unchanging. */
- goto cond;
-#else
exp = check_attr_value (exp, attr);
break;
-#endif
case IF_THEN_ELSE:
newexp = rtx_alloc (COND);
@@ -1509,15 +1449,25 @@ make_canonical (attr, exp)
}
static rtx
-copy_boolean (exp)
- rtx exp;
+copy_boolean (rtx exp)
{
if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
copy_boolean (XEXP (exp, 1)));
+ if (GET_CODE (exp) == MATCH_OPERAND)
+ {
+ XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
+ XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
+ }
+ else if (GET_CODE (exp) == EQ_ATTR)
+ {
+ XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
+ XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
+ }
+
return exp;
}
-
+
/* Given a value and an attribute description, return a `struct attr_value *'
that represents that value. This is either an existing structure, if the
value has been previously encountered, or a newly-created structure.
@@ -1528,10 +1478,7 @@ copy_boolean (exp)
alternatives. */
static struct attr_value *
-get_attr_value (value, attr, insn_code)
- rtx value;
- struct attr_desc *attr;
- int insn_code;
+get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
{
struct attr_value *av;
int num_alt = 0;
@@ -1551,7 +1498,7 @@ get_attr_value (value, attr, insn_code)
|| insn_alternatives[av->first_insn->insn_code]))
return av;
- av = (struct attr_value *) oballoc (sizeof (struct attr_value));
+ av = oballoc (sizeof (struct attr_value));
av->value = value;
av->next = attr->first_value;
attr->first_value = av;
@@ -1561,7 +1508,7 @@ get_attr_value (value, attr, insn_code)
return av;
}
-
+
/* After all DEFINE_DELAYs have been read in, create internal attributes
to generate the required routines.
@@ -1577,7 +1524,7 @@ get_attr_value (value, attr, insn_code)
information needed to handle delay slots. */
static void
-expand_delays ()
+expand_delays (void)
{
struct delay_desc *delay;
rtx condexp;
@@ -1598,7 +1545,7 @@ expand_delays ()
= make_numeric_value (XVECLEN (delay->def, 1) / 3);
}
- make_internal_attr ("*num_delay_slots", condexp, 0);
+ make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
/* If more than one delay type, do the same for computing the delay type. */
if (num_delays > 1)
@@ -1613,7 +1560,7 @@ expand_delays ()
XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
}
- make_internal_attr ("*delay_type", condexp, 1);
+ make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
}
/* For each delay possibility and delay slot, compute an eligibility
@@ -1631,7 +1578,7 @@ expand_delays ()
p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
"*delay_%d_%d", delay->num, i / 3);
- make_internal_attr (p, newexp, 1);
+ make_internal_attr (p, newexp, ATTR_SPECIAL);
if (have_annul_true)
{
@@ -1642,7 +1589,7 @@ expand_delays ()
make_numeric_value (0));
p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
"*annul_true_%d_%d", delay->num, i / 3);
- make_internal_attr (p, newexp, 1);
+ make_internal_attr (p, newexp, ATTR_SPECIAL);
}
if (have_annul_false)
@@ -1654,12 +1601,12 @@ expand_delays ()
make_numeric_value (0));
p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
"*annul_false_%d_%d", delay->num, i / 3);
- make_internal_attr (p, newexp, 1);
+ make_internal_attr (p, newexp, ATTR_SPECIAL);
}
}
}
}
-
+
/* This function is given a left and right side expression and an operator.
Each side is a conditional expression, each alternative of which has a
numerical value. The function returns another conditional expression
@@ -1669,9 +1616,7 @@ expand_delays ()
Since this is called early, it must also support IF_THEN_ELSE. */
static rtx
-operate_exp (op, left, right)
- enum operator op;
- rtx left, right;
+operate_exp (enum operator op, rtx left, rtx right)
{
int left_value, right_value;
rtx newexp;
@@ -1831,7 +1776,7 @@ operate_exp (op, left, right)
/* NOTREACHED */
return NULL;
}
-
+
/* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
construct a number of attributes.
@@ -1865,7 +1810,7 @@ operate_exp (op, left, right)
half gives the maximum value. */
static void
-expand_units ()
+expand_units (void)
{
struct function_unit *unit, **unit_num;
struct function_unit_op *op, **op_array, ***unit_ops;
@@ -1908,7 +1853,7 @@ expand_units ()
str = attr_printf ((strlen (unit->name) + sizeof "*_cost_"
+ MAX_DIGITS),
"*%s_cost_%d", unit->name, op->num);
- make_internal_attr (str, issue_exp, 1);
+ make_internal_attr (str, issue_exp, ATTR_SPECIAL);
}
/* Validate the condition. */
@@ -1964,17 +1909,15 @@ expand_units ()
unitsmask = attr_rtx (FFS, unitsmask);
}
- make_internal_attr ("*function_units_used", unitsmask, 10);
+ make_internal_attr ("*function_units_used", unitsmask,
+ (ATTR_NEGATIVE_OK | ATTR_FUNC_UNITS));
/* Create an array of ops for each unit. Add an extra unit for the
result_ready_cost function that has the ops of all other units. */
- unit_ops = (struct function_unit_op ***)
- xmalloc ((num_units + 1) * sizeof (struct function_unit_op **));
- unit_num = (struct function_unit **)
- xmalloc ((num_units + 1) * sizeof (struct function_unit *));
+ unit_ops = xmalloc ((num_units + 1) * sizeof (struct function_unit_op **));
+ unit_num = xmalloc ((num_units + 1) * sizeof (struct function_unit *));
- unit_num[num_units] = unit = (struct function_unit *)
- xmalloc (sizeof (struct function_unit));
+ unit_num[num_units] = unit = xmalloc (sizeof (struct function_unit));
unit->num = num_units;
unit->num_opclasses = 0;
@@ -1982,7 +1925,7 @@ expand_units ()
{
unit_num[num_units]->num_opclasses += unit->num_opclasses;
unit_num[unit->num] = unit;
- unit_ops[unit->num] = op_array = (struct function_unit_op **)
+ unit_ops[unit->num] = op_array =
xmalloc (unit->num_opclasses * sizeof (struct function_unit_op *));
for (op = unit->ops; op; op = op->next)
@@ -1990,7 +1933,7 @@ expand_units ()
}
/* Compose the array of ops for the extra unit. */
- unit_ops[num_units] = op_array = (struct function_unit_op **)
+ unit_ops[num_units] = op_array =
xmalloc (unit_num[num_units]->num_opclasses
* sizeof (struct function_unit_op *));
@@ -2083,7 +2026,7 @@ expand_units ()
every possible C.
The issue delay function for C is op->issue_exp and is used to
- write the `<name>_unit_conflict_cost' function. Symbolicly
+ write the `<name>_unit_conflict_cost' function. Symbolically
this is "ISSUE-DELAY (E,C)".
The pipeline delay results form the FIFO constraint on the
@@ -2138,7 +2081,7 @@ expand_units ()
str = attr_printf ((strlen (unit->name) + sizeof "*_block_"
+ MAX_DIGITS),
"*%s_block_%d", unit->name, op->num);
- make_internal_attr (str, blockage, 1);
+ make_internal_attr (str, blockage, ATTR_SPECIAL);
}
/* Record MAX (BLOCKAGE (*,*)). */
@@ -2172,18 +2115,20 @@ expand_units ()
str = attr_printf ((strlen (unit->name)
+ sizeof "*_unit_blockage_range"),
"*%s_unit_blockage_range", unit->name);
- make_internal_attr (str, newexp, 20);
+ make_internal_attr (str, newexp, (ATTR_STATIC|ATTR_BLOCKAGE|ATTR_UNSIGNED));
}
str = attr_printf (strlen (unit->name) + sizeof "*_unit_ready_cost",
"*%s_unit_ready_cost", unit->name);
+ make_internal_attr (str, readycost, ATTR_STATIC);
}
else
- str = "*result_ready_cost";
-
- /* Make an attribute for the ready_cost function. Simplifying
- further with simplify_by_exploding doesn't win. */
- make_internal_attr (str, readycost, 0);
+ {
+ /* Make an attribute for the ready_cost function. Simplifying
+ further with simplify_by_exploding doesn't win. */
+ str = "*result_ready_cost";
+ make_internal_attr (str, readycost, ATTR_NONE);
+ }
}
/* For each unit that requires a conflict cost function, make an attribute
@@ -2219,15 +2164,14 @@ expand_units ()
/* Simplifying caseexp with simplify_by_exploding doesn't win. */
str = attr_printf (strlen (unit->name) + sizeof "*_cases",
"*%s_cases", unit->name);
- make_internal_attr (str, caseexp, 1);
+ make_internal_attr (str, caseexp, ATTR_SPECIAL);
}
}
/* Simplify EXP given KNOWN_TRUE. */
static rtx
-simplify_knowing (exp, known_true)
- rtx exp, known_true;
+simplify_knowing (rtx exp, rtx known_true)
{
if (GET_CODE (exp) != CONST_STRING)
{
@@ -2249,8 +2193,7 @@ simplify_knowing (exp, known_true)
and only one unit is used or the one's complement of the bitmask. */
static rtx
-encode_units_mask (x)
- rtx x;
+encode_units_mask (rtx x)
{
int i;
int j;
@@ -2284,6 +2227,7 @@ encode_units_mask (x)
case PC:
case CC0:
case EQ_ATTR:
+ case EQ_ATTR_ALT:
return x;
default:
@@ -2311,14 +2255,13 @@ encode_units_mask (x)
}
return x;
}
-
+
/* Once all attributes and insns have been read and checked, we construct for
each attribute value a list of all the insns that have that value for
the attribute. */
static void
-fill_attr (attr)
- struct attr_desc *attr;
+fill_attr (struct attr_desc *attr)
{
struct attr_value *av;
struct insn_ent *ie;
@@ -2338,8 +2281,8 @@ fill_attr (attr)
value = NULL;
if (XVEC (id->def, id->vec_idx))
for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
- if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
- attr->name))
+ if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
+ attr->name))
value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
if (value == NULL)
@@ -2347,13 +2290,13 @@ fill_attr (attr)
else
av = get_attr_value (value, attr, id->insn_code);
- ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
+ ie = oballoc (sizeof (struct insn_ent));
ie->insn_code = id->insn_code;
ie->insn_index = id->insn_code;
insert_insn_ent (av, ie);
}
}
-
+
/* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
test that checks relative positions of insns (uses MATCH_DUP or PC).
If so, replace it with what is obtained by passing the expression to
@@ -2362,10 +2305,8 @@ fill_attr (attr)
return the value returned by NO_ADDRESS_FN applied to EXP. */
static rtx
-substitute_address (exp, no_address_fn, address_fn)
- rtx exp;
- rtx (*no_address_fn) PARAMS ((rtx));
- rtx (*address_fn) PARAMS ((rtx));
+substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
+ rtx (*address_fn) (rtx))
{
int i;
rtx newexp;
@@ -2415,7 +2356,7 @@ substitute_address (exp, no_address_fn, address_fn)
return (*no_address_fn) (exp);
}
-
+
/* Make new attributes from the `length' attribute. The following are made,
each corresponding to a function called from `shorten_branches' or
`get_attr_length':
@@ -2436,13 +2377,16 @@ substitute_address (exp, no_address_fn, address_fn)
*/
static void
-make_length_attrs ()
+make_length_attrs (void)
{
- static const char *const new_names[] = {"*insn_default_length",
- "*insn_variable_length_p",
- "*insn_current_length"};
- static rtx (*const no_address_fn[]) PARAMS ((rtx)) = {identity_fn, zero_fn, zero_fn};
- static rtx (*const address_fn[]) PARAMS ((rtx)) = {max_fn, one_fn, identity_fn};
+ static const char *new_names[] =
+ {
+ "*insn_default_length",
+ "*insn_variable_length_p",
+ "*insn_current_length"
+ };
+ static rtx (*const no_address_fn[]) (rtx) = {identity_fn, zero_fn, zero_fn};
+ static rtx (*const address_fn[]) (rtx) = {max_fn, one_fn, identity_fn};
size_t i;
struct attr_desc *length_attr, *new_attr;
struct attr_value *av, *new_av;
@@ -2450,7 +2394,7 @@ make_length_attrs ()
/* See if length attribute is defined. If so, it must be numeric. Make
it special so we don't output anything for it. */
- length_attr = find_attr ("length", 0);
+ length_attr = find_attr (&length_str, 0);
if (length_attr == 0)
return;
@@ -2466,8 +2410,8 @@ make_length_attrs ()
make_internal_attr (new_names[i],
substitute_address (length_attr->default_val->value,
no_address_fn[i], address_fn[i]),
- 0);
- new_attr = find_attr (new_names[i], 0);
+ ATTR_NONE);
+ new_attr = find_attr (&new_names[i], 0);
for (av = length_attr->first_value; av; av = av->next)
for (ie = av->first_insn; ie; ie = ie->next)
{
@@ -2475,7 +2419,7 @@ make_length_attrs ()
no_address_fn[i],
address_fn[i]),
new_attr, ie->insn_code);
- new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
+ new_ie = oballoc (sizeof (struct insn_ent));
new_ie->insn_code = ie->insn_code;
new_ie->insn_index = ie->insn_index;
insert_insn_ent (new_av, new_ie);
@@ -2486,38 +2430,34 @@ make_length_attrs ()
/* Utility functions called from above routine. */
static rtx
-identity_fn (exp)
- rtx exp;
+identity_fn (rtx exp)
{
return exp;
}
static rtx
-zero_fn (exp)
- rtx exp ATTRIBUTE_UNUSED;
+zero_fn (rtx exp ATTRIBUTE_UNUSED)
{
return make_numeric_value (0);
}
static rtx
-one_fn (exp)
- rtx exp ATTRIBUTE_UNUSED;
+one_fn (rtx exp ATTRIBUTE_UNUSED)
{
return make_numeric_value (1);
}
static rtx
-max_fn (exp)
- rtx exp;
+max_fn (rtx exp)
{
int unknown;
return make_numeric_value (max_attr_value (exp, &unknown));
}
static void
-write_length_unit_log ()
+write_length_unit_log (void)
{
- struct attr_desc *length_attr = find_attr ("length", 0);
+ struct attr_desc *length_attr = find_attr (&length_str, 0);
struct attr_value *av;
struct insn_ent *ie;
unsigned int length_unit_log, length_or;
@@ -2540,7 +2480,7 @@ write_length_unit_log ()
}
printf ("int length_unit_log = %u;\n", length_unit_log);
}
-
+
/* Take a COND expression and see if any of the conditions in it can be
simplified. If any are known true or known false for the particular insn
code, the COND can be further simplified.
@@ -2550,9 +2490,7 @@ write_length_unit_log ()
We do not modify EXP; rather, we make and return a new rtx. */
static rtx
-simplify_cond (exp, insn_code, insn_index)
- rtx exp;
- int insn_code, insn_index;
+simplify_cond (rtx exp, int insn_code, int insn_index)
{
int i, j;
/* We store the desired contents here,
@@ -2560,13 +2498,12 @@ simplify_cond (exp, insn_code, insn_index)
rtx defval = XEXP (exp, 1);
rtx new_defval = XEXP (exp, 1);
int len = XVECLEN (exp, 0);
- rtx *tests = (rtx *) xmalloc (len * sizeof (rtx));
+ rtx *tests = xmalloc (len * sizeof (rtx));
int allsame = 1;
- char *first_spacer;
rtx ret;
/* This lets us free all storage allocated below, if appropriate. */
- first_spacer = (char *) obstack_finish (rtl_obstack);
+ obstack_finish (rtl_obstack);
memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
@@ -2604,6 +2541,7 @@ simplify_cond (exp, insn_code, insn_index)
/* If test is false, discard it and its value. */
for (j = i; j < len - 2; j++)
tests[j] = tests[j + 2];
+ i -= 2;
len -= 2;
}
@@ -2620,6 +2558,7 @@ simplify_cond (exp, insn_code, insn_index)
for (j = i; j < len - 2; j++)
tests[j] = tests[j + 2];
len -= 2;
+ i -= 2;
}
else
@@ -2664,13 +2603,11 @@ simplify_cond (exp, insn_code, insn_index)
free (tests);
return ret;
}
-
+
/* Remove an insn entry from an attribute value. */
static void
-remove_insn_ent (av, ie)
- struct attr_value *av;
- struct insn_ent *ie;
+remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
{
struct insn_ent *previe;
@@ -2693,9 +2630,7 @@ remove_insn_ent (av, ie)
/* Insert an insn entry in an attribute value list. */
static void
-insert_insn_ent (av, ie)
- struct attr_value *av;
- struct insn_ent *ie;
+insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
{
ie->next = av->first_insn;
av->first_insn = ie;
@@ -2705,7 +2640,7 @@ insert_insn_ent (av, ie)
num_insn_ents++;
}
-
+
/* This is a utility routine to take an expression that is a tree of either
AND or IOR expressions and insert a new term. The new term will be
inserted at the right side of the first node whose code does not match
@@ -2716,11 +2651,7 @@ insert_insn_ent (av, ie)
If the `term' is itself a tree, all its leaves will be inserted. */
static rtx
-insert_right_side (code, exp, term, insn_code, insn_index)
- enum rtx_code code;
- rtx exp;
- rtx term;
- int insn_code, insn_index;
+insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
{
rtx newexp;
@@ -2772,7 +2703,7 @@ insert_right_side (code, exp, term, insn_code, insn_index)
return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
}
-
+
/* If we have an expression which AND's a bunch of
(not (eq_attrq "alternative" "n"))
terms, we may have covered all or all but one of the possible alternatives.
@@ -2782,9 +2713,7 @@ insert_right_side (code, exp, term, insn_code, insn_index)
bitmask indicating which alternatives are mentioned within EXP. */
static int
-compute_alternative_mask (exp, code)
- rtx exp;
- enum rtx_code code;
+compute_alternative_mask (rtx exp, enum rtx_code code)
{
const char *string;
if (GET_CODE (exp) == code)
@@ -2800,6 +2729,16 @@ compute_alternative_mask (exp, code)
&& XSTR (exp, 0) == alternative_name)
string = XSTR (exp, 1);
+ else if (GET_CODE (exp) == EQ_ATTR_ALT)
+ {
+ if (code == AND && XINT (exp, 1))
+ return XINT (exp, 0);
+
+ if (code == IOR && !XINT (exp, 1))
+ return XINT (exp, 0);
+
+ return 0;
+ }
else
return 0;
@@ -2812,22 +2751,11 @@ compute_alternative_mask (exp, code)
attribute with the value represented by that bit. */
static rtx
-make_alternative_compare (mask)
- int mask;
+make_alternative_compare (int mask)
{
- rtx newexp;
- int i;
-
- /* Find the bit. */
- for (i = 0; (mask & (1 << i)) == 0; i++)
- ;
-
- newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
- ATTR_IND_SIMPLIFIED_P (newexp) = 1;
-
- return newexp;
+ return mk_attr_alt (mask);
}
-
+
/* If we are processing an (eq_attr "attr" "value") test, we find the value
of "attr" for this insn code. From that value, we can compute a test
showing when the EQ_ATTR will be true. This routine performs that
@@ -2838,10 +2766,7 @@ make_alternative_compare (mask)
for the insn corresponding to INSN_CODE and INSN_INDEX. */
static rtx
-evaluate_eq_attr (exp, value, insn_code, insn_index)
- rtx exp;
- rtx value;
- int insn_code, insn_index;
+evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
{
rtx orexp, andexp;
rtx right;
@@ -2850,7 +2775,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
if (GET_CODE (value) == CONST_STRING)
{
- if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
+ if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
newexp = true_rtx;
else
newexp = false_rtx;
@@ -2874,7 +2799,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
newexp = attr_rtx (EQ, value,
attr_rtx (SYMBOL_REF,
- attr_string (string, strlen (string))));
+ DEF_ATTR_STRING (string)));
}
else if (GET_CODE (value) == COND)
{
@@ -2946,7 +2871,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
else
return newexp;
}
-
+
/* This routine is called when an AND of a term with a tree of AND's is
encountered. If the term or its complement is present in the tree, it
can be replaced with TRUE or FALSE, respectively.
@@ -2962,10 +2887,7 @@ evaluate_eq_attr (exp, value, insn_code, insn_index)
the term. */
static rtx
-simplify_and_tree (exp, pterm, insn_code, insn_index)
- rtx exp;
- rtx *pterm;
- int insn_code, insn_index;
+simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
{
rtx left, right;
rtx newexp;
@@ -2978,7 +2900,7 @@ simplify_and_tree (exp, pterm, insn_code, insn_index)
right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
{
- newexp = attr_rtx (GET_CODE (exp), left, right);
+ newexp = attr_rtx (AND, left, right);
exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
}
@@ -3001,7 +2923,7 @@ simplify_and_tree (exp, pterm, insn_code, insn_index)
if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
{
- newexp = attr_rtx (GET_CODE (exp), left, right);
+ newexp = attr_rtx (IOR, left, right);
exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
}
@@ -3019,12 +2941,26 @@ simplify_and_tree (exp, pterm, insn_code, insn_index)
else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
return false_rtx;
+ else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
+ {
+ if (attr_alt_subset_p (*pterm, exp))
+ return true_rtx;
+
+ if (attr_alt_subset_of_compl_p (*pterm, exp))
+ return false_rtx;
+
+ if (attr_alt_subset_p (exp, *pterm))
+ *pterm = true_rtx;
+
+ return exp;
+ }
+
else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
{
if (XSTR (exp, 0) != XSTR (*pterm, 0))
return exp;
- if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
+ if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
return true_rtx;
else
return false_rtx;
@@ -3036,7 +2972,7 @@ simplify_and_tree (exp, pterm, insn_code, insn_index)
if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
return exp;
- if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
+ if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
return false_rtx;
else
return true_rtx;
@@ -3048,7 +2984,7 @@ simplify_and_tree (exp, pterm, insn_code, insn_index)
if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
return exp;
- if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
+ if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
return false_rtx;
else
*pterm = true_rtx;
@@ -3077,14 +3013,11 @@ simplify_and_tree (exp, pterm, insn_code, insn_index)
return exp;
}
-
+
/* Similar to `simplify_and_tree', but for IOR trees. */
static rtx
-simplify_or_tree (exp, pterm, insn_code, insn_index)
- rtx exp;
- rtx *pterm;
- int insn_code, insn_index;
+simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
{
rtx left, right;
rtx newexp;
@@ -3147,11 +3080,11 @@ simplify_or_tree (exp, pterm, insn_code, insn_index)
return exp;
}
+
/* Compute approximate cost of the expression. Used to decide whether
expression is cheap enough for inline. */
static int
-attr_rtx_cost (x)
- rtx x;
+attr_rtx_cost (rtx x)
{
int cost = 0;
enum rtx_code code;
@@ -3165,9 +3098,13 @@ attr_rtx_cost (x)
return 10;
else
return 0;
+
+ case EQ_ATTR_ALT:
+ return 0;
+
case EQ_ATTR:
/* Alternatives don't result into function call. */
- if (!strcmp (XSTR (x, 0), "alternative"))
+ if (!strcmp_check (XSTR (x, 0), alternative_name))
return 0;
else
return 5;
@@ -3194,16 +3131,13 @@ attr_rtx_cost (x)
}
return cost;
}
-
/* Simplify test expression and use temporary obstack in order to avoid
- memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecesary simplifications
- and avoid unnecesary copying if possible. */
+ memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
+ and avoid unnecessary copying if possible. */
static rtx
-simplify_test_exp_in_temp (exp, insn_code, insn_index)
- rtx exp;
- int insn_code, insn_index;
+simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
{
rtx x;
struct obstack *old;
@@ -3218,6 +3152,146 @@ simplify_test_exp_in_temp (exp, insn_code, insn_index)
return attr_copy_rtx (x);
}
+/* Returns true if S1 is a subset of S2. */
+
+static bool
+attr_alt_subset_p (rtx s1, rtx s2)
+{
+ switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
+ {
+ case (0 << 1) | 0:
+ return !(XINT (s1, 0) &~ XINT (s2, 0));
+
+ case (0 << 1) | 1:
+ return !(XINT (s1, 0) & XINT (s2, 0));
+
+ case (1 << 1) | 0:
+ return false;
+
+ case (1 << 1) | 1:
+ return !(XINT (s2, 0) &~ XINT (s1, 0));
+
+ default:
+ abort ();
+ }
+}
+
+/* Returns true if S1 is a subset of complement of S2. */
+
+static bool attr_alt_subset_of_compl_p (rtx s1, rtx s2)
+{
+ switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
+ {
+ case (0 << 1) | 0:
+ return !(XINT (s1, 0) & XINT (s2, 0));
+
+ case (0 << 1) | 1:
+ return !(XINT (s1, 0) & ~XINT (s2, 0));
+
+ case (1 << 1) | 0:
+ return !(XINT (s2, 0) &~ XINT (s1, 0));
+
+ case (1 << 1) | 1:
+ return false;
+
+ default:
+ abort ();
+ }
+}
+
+/* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
+
+static rtx
+attr_alt_intersection (rtx s1, rtx s2)
+{
+ rtx result = rtx_alloc (EQ_ATTR_ALT);
+
+ switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
+ {
+ case (0 << 1) | 0:
+ XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
+ break;
+ case (0 << 1) | 1:
+ XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
+ break;
+ case (1 << 1) | 0:
+ XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
+ break;
+ case (1 << 1) | 1:
+ XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
+ break;
+ default:
+ abort ();
+ }
+ XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
+
+ return result;
+}
+
+/* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
+
+static rtx
+attr_alt_union (rtx s1, rtx s2)
+{
+ rtx result = rtx_alloc (EQ_ATTR_ALT);
+
+ switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
+ {
+ case (0 << 1) | 0:
+ XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
+ break;
+ case (0 << 1) | 1:
+ XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
+ break;
+ case (1 << 1) | 0:
+ XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
+ break;
+ case (1 << 1) | 1:
+ XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
+ break;
+ default:
+ abort ();
+ }
+
+ XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
+ return result;
+}
+
+/* Return EQ_ATTR_ALT expression representing complement of S. */
+
+static rtx
+attr_alt_complement (rtx s)
+{
+ rtx result = rtx_alloc (EQ_ATTR_ALT);
+
+ XINT (result, 0) = XINT (s, 0);
+ XINT (result, 1) = 1 - XINT (s, 1);
+
+ return result;
+}
+
+/* Tests whether a bit B belongs to the set represented by S. */
+
+static bool
+attr_alt_bit_p (rtx s, int b)
+{
+ return XINT (s, 1) ^ ((XINT (s, 0) >> b) & 1);
+}
+
+/* Return EQ_ATTR_ALT expression representing set containing elements set
+ in E. */
+
+static rtx
+mk_attr_alt (int e)
+{
+ rtx result = rtx_alloc (EQ_ATTR_ALT);
+
+ XINT (result, 0) = e;
+ XINT (result, 1) = 0;
+
+ return result;
+}
+
/* Given an expression, see if it can be simplified for a particular insn
code based on the values of other attributes being tested. This can
eliminate nested get_attr_... calls.
@@ -3228,9 +3302,7 @@ simplify_test_exp_in_temp (exp, insn_code, insn_index)
it occurs here! */
static rtx
-simplify_test_exp (exp, insn_code, insn_index)
- rtx exp;
- int insn_code, insn_index;
+simplify_test_exp (rtx exp, int insn_code, int insn_index)
{
rtx left, right;
struct attr_desc *attr;
@@ -3238,6 +3310,7 @@ simplify_test_exp (exp, insn_code, insn_index)
struct insn_ent *ie;
int i;
rtx newexp = exp;
+ bool left_alt, right_alt;
/* Don't re-simplify something we already simplified. */
if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
@@ -3255,6 +3328,13 @@ simplify_test_exp (exp, insn_code, insn_index)
if (left == false_rtx)
return false_rtx;
+ if (GET_CODE (left) == EQ_ATTR_ALT
+ && GET_CODE (right) == EQ_ATTR_ALT)
+ {
+ exp = attr_alt_intersection (left, right);
+ return simplify_test_exp (exp, insn_code, insn_index);
+ }
+
/* If either side is an IOR and we have (eq_attr "alternative" ..")
present on both sides, apply the distributive law since this will
yield simplifications. */
@@ -3294,15 +3374,25 @@ simplify_test_exp (exp, insn_code, insn_index)
/* See if all or all but one of the insn's alternatives are specified
in this tree. Optimize if so. */
- else if (insn_code >= 0
- && (GET_CODE (left) == AND
- || (GET_CODE (left) == NOT
- && GET_CODE (XEXP (left, 0)) == EQ_ATTR
- && XSTR (XEXP (left, 0), 0) == alternative_name)
- || GET_CODE (right) == AND
- || (GET_CODE (right) == NOT
- && GET_CODE (XEXP (right, 0)) == EQ_ATTR
- && XSTR (XEXP (right, 0), 0) == alternative_name)))
+ if (GET_CODE (left) == NOT)
+ left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
+ && XSTR (XEXP (left, 0), 0) == alternative_name);
+ else
+ left_alt = (GET_CODE (left) == EQ_ATTR_ALT
+ && XINT (left, 1));
+
+ if (GET_CODE (right) == NOT)
+ right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
+ && XSTR (XEXP (right, 0), 0) == alternative_name);
+ else
+ right_alt = (GET_CODE (right) == EQ_ATTR_ALT
+ && XINT (right, 1));
+
+ if (insn_code >= 0
+ && (GET_CODE (left) == AND
+ || left_alt
+ || GET_CODE (right) == AND
+ || right_alt))
{
i = compute_alternative_mask (exp, AND);
if (i & ~insn_alternatives[insn_code])
@@ -3344,6 +3434,13 @@ simplify_test_exp (exp, insn_code, insn_index)
if (right == true_rtx)
return true_rtx;
+ if (GET_CODE (left) == EQ_ATTR_ALT
+ && GET_CODE (right) == EQ_ATTR_ALT)
+ {
+ exp = attr_alt_union (left, right);
+ return simplify_test_exp (exp, insn_code, insn_index);
+ }
+
right = simplify_or_tree (right, &left, insn_code, insn_index);
if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
left = simplify_or_tree (left, &right, insn_code, insn_index);
@@ -3382,9 +3479,13 @@ simplify_test_exp (exp, insn_code, insn_index)
else if (insn_code >= 0
&& (GET_CODE (left) == IOR
+ || (GET_CODE (left) == EQ_ATTR_ALT
+ && !XINT (left, 1))
|| (GET_CODE (left) == EQ_ATTR
&& XSTR (left, 0) == alternative_name)
|| GET_CODE (right) == IOR
+ || (GET_CODE (right) == EQ_ATTR_ALT
+ && !XINT (right, 1))
|| (GET_CODE (right) == EQ_ATTR
&& XSTR (right, 0) == alternative_name)))
{
@@ -3434,11 +3535,17 @@ simplify_test_exp (exp, insn_code, insn_index)
if (left == false_rtx)
return true_rtx;
- else if (left == true_rtx)
+ if (left == true_rtx)
return false_rtx;
+ if (GET_CODE (left) == EQ_ATTR_ALT)
+ {
+ exp = attr_alt_complement (left);
+ return simplify_test_exp (exp, insn_code, insn_index);
+ }
+
/* Try to apply De`Morgan's laws. */
- else if (GET_CODE (left) == IOR)
+ if (GET_CODE (left) == IOR)
{
newexp = attr_rtx (AND,
attr_rtx (NOT, XEXP (left, 0)),
@@ -3460,16 +3567,30 @@ simplify_test_exp (exp, insn_code, insn_index)
}
break;
+ case EQ_ATTR_ALT:
+ if (current_alternative_string)
+ return attr_alt_bit_p (exp, atoi (current_alternative_string)) ? true_rtx : false_rtx;
+
+ if (!XINT (exp, 0))
+ return XINT (exp, 1) ? true_rtx : false_rtx;
+ break;
+
case EQ_ATTR:
if (current_alternative_string && XSTR (exp, 0) == alternative_name)
return (XSTR (exp, 1) == current_alternative_string
? true_rtx : false_rtx);
+ if (XSTR (exp, 0) == alternative_name)
+ {
+ newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
+ break;
+ }
+
/* Look at the value for this insn code in the specified attribute.
We normally can replace this comparison with the condition that
would give this insn the values being tested for. */
if (XSTR (exp, 0) != alternative_name
- && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
+ && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
for (av = attr->first_value; av; av = av->next)
for (ie = av->first_insn; ie; ie = ie->next)
if (ie->insn_code == insn_code)
@@ -3495,13 +3616,13 @@ simplify_test_exp (exp, insn_code, insn_index)
return newexp;
}
-
+
/* Optimize the attribute lists by seeing if we can determine conditional
values from the known values of other attributes. This will save subroutine
calls during the compilation. */
static void
-optimize_attrs ()
+optimize_attrs (void)
{
struct attr_desc *attr;
struct attr_value *av;
@@ -3526,17 +3647,13 @@ optimize_attrs ()
return;
/* Make 2 extra elements, for "code" values -2 and -1. */
- insn_code_values
- = (struct attr_value_list **) xmalloc ((insn_code_number + 2)
- * sizeof (struct attr_value_list *));
- memset ((char *) insn_code_values, 0,
- (insn_code_number + 2) * sizeof (struct attr_value_list *));
+ insn_code_values = xcalloc ((insn_code_number + 2),
+ sizeof (struct attr_value_list *));
/* Offset the table address so we can index by -2 or -1. */
insn_code_values += 2;
- iv = ivbuf = ((struct attr_value_list *)
- xmalloc (num_insn_ents * sizeof (struct attr_value_list)));
+ iv = ivbuf = xmalloc (num_insn_ents * sizeof (struct attr_value_list));
for (i = 0; i < MAX_ATTRS_INDEX; i++)
for (attr = attrs[i]; attr; attr = attr->next)
@@ -3574,13 +3691,6 @@ optimize_attrs ()
continue;
rtl_obstack = temp_obstack;
-#if 0 /* This was intended as a speed up, but it was slower. */
- if (insn_n_alternatives[ie->insn_code] > 6
- && count_sub_rtxs (av->value, 200) >= 200)
- newexp = simplify_by_alternatives (av->value, ie->insn_code,
- ie->insn_index);
- else
-#endif
newexp = av->value;
while (GET_CODE (newexp) == COND)
{
@@ -3607,46 +3717,12 @@ optimize_attrs ()
free (insn_code_values - 2);
}
-#if 0
-static rtx
-simplify_by_alternatives (exp, insn_code, insn_index)
- rtx exp;
- int insn_code, insn_index;
-{
- int i;
- int len = insn_n_alternatives[insn_code];
- rtx newexp = rtx_alloc (COND);
- rtx ultimate;
-
- XVEC (newexp, 0) = rtvec_alloc (len * 2);
-
- /* It will not matter what value we use as the default value
- of the new COND, since that default will never be used.
- Choose something of the right type. */
- for (ultimate = exp; GET_CODE (ultimate) == COND;)
- ultimate = XEXP (ultimate, 1);
- XEXP (newexp, 1) = ultimate;
-
- for (i = 0; i < insn_n_alternatives[insn_code]; i++)
- {
- current_alternative_string = attr_numeral (i);
- XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
- XVECEXP (newexp, 0, i * 2 + 1)
- = simplify_cond (exp, insn_code, insn_index);
- }
-
- current_alternative_string = 0;
- return simplify_cond (newexp, insn_code, insn_index);
-}
-#endif
-
/* If EXP is a suitable expression, reorganize it by constructing an
equivalent expression that is a COND with the tests being all combinations
of attribute values and the values being simple constants. */
static rtx
-simplify_by_exploding (exp)
- rtx exp;
+simplify_by_exploding (rtx exp)
{
rtx list = 0, link, condexp, defval = NULL_RTX;
struct dimension *space;
@@ -3668,7 +3744,7 @@ simplify_by_exploding (exp)
cover the domain of the attribute. This makes the expanded COND form
order independent. */
- space = (struct dimension *) xmalloc (ndim * sizeof (struct dimension));
+ space = xmalloc (ndim * sizeof (struct dimension));
total = 1;
for (ndim = 0; list; ndim++)
@@ -3678,7 +3754,10 @@ simplify_by_exploding (exp)
const char *name = XSTR (XEXP (list, 0), 0);
rtx *prev;
- if ((space[ndim].attr = find_attr (name, 0)) == 0
+ space[ndim].attr = find_attr (&name, 0);
+ XSTR (XEXP (list, 0), 0) = name;
+
+ if (space[ndim].attr == 0
|| space[ndim].attr->is_numeric)
{
unmark_used_attributes (list, space, ndim);
@@ -3690,7 +3769,7 @@ simplify_by_exploding (exp)
space[ndim].values = 0;
prev = &list;
for (link = list; link; link = *prev)
- if (! strcmp (XSTR (XEXP (link, 0), 0), name))
+ if (! strcmp_check (XSTR (XEXP (link, 0), 0), name))
{
space[ndim].num_values++;
*prev = XEXP (link, 1);
@@ -3723,8 +3802,8 @@ simplify_by_exploding (exp)
for (i = 0; i < ndim; i++)
space[i].current_value = space[i].values;
- condtest = (rtx *) xmalloc (total * sizeof (rtx));
- condval = (rtx *) xmalloc (total * sizeof (rtx));
+ condtest = xmalloc (total * sizeof (rtx));
+ condval = xmalloc (total * sizeof (rtx));
/* Expand the tests and values by iterating over all values in the
attribute space. */
@@ -3768,7 +3847,7 @@ simplify_by_exploding (exp)
/* Give up if nothing is constant. */
if (num_marks == 0)
ret = exp;
-
+
/* If all values are the default, use that. */
else if (total == most_tests)
ret = defval;
@@ -3800,9 +3879,7 @@ simplify_by_exploding (exp)
tests have known value. */
static int
-find_and_mark_used_attributes (exp, terms, nterms)
- rtx exp, *terms;
- int *nterms;
+find_and_mark_used_attributes (rtx exp, rtx *terms, int *nterms)
{
int i;
@@ -3853,10 +3930,7 @@ find_and_mark_used_attributes (exp, terms, nterms)
in the values of the NDIM-dimensional attribute space SPACE. */
static void
-unmark_used_attributes (list, space, ndim)
- rtx list;
- struct dimension *space;
- int ndim;
+unmark_used_attributes (rtx list, struct dimension *space, int ndim)
{
rtx link, exp;
int i;
@@ -3876,8 +3950,7 @@ unmark_used_attributes (list, space, ndim)
are tested. Return the updated number of values. */
static int
-add_values_to_cover (dim)
- struct dimension *dim;
+add_values_to_cover (struct dimension *dim)
{
struct attr_value *av;
rtx exp, link, *prev;
@@ -3941,9 +4014,7 @@ add_values_to_cover (dim)
and return FALSE if the increment overflowed. */
static int
-increment_current_value (space, ndim)
- struct dimension *space;
- int ndim;
+increment_current_value (struct dimension *space, int ndim)
{
int i;
@@ -3961,9 +4032,7 @@ increment_current_value (space, ndim)
NDIM-dimensional attribute space SPACE. */
static rtx
-test_for_current_value (space, ndim)
- struct dimension *space;
- int ndim;
+test_for_current_value (struct dimension *space, int ndim)
{
int i;
rtx exp = true_rtx;
@@ -3981,10 +4050,7 @@ test_for_current_value (space, ndim)
known EQ_ATTR expressions are set to FALSE. */
static rtx
-simplify_with_current_value (exp, space, ndim)
- rtx exp;
- struct dimension *space;
- int ndim;
+simplify_with_current_value (rtx exp, struct dimension *space, int ndim)
{
int i;
rtx x;
@@ -4014,8 +4080,7 @@ simplify_with_current_value (exp, space, ndim)
all EQ_ATTR expressions. */
static rtx
-simplify_with_current_value_aux (exp)
- rtx exp;
+simplify_with_current_value_aux (rtx exp)
{
int i;
rtx cond;
@@ -4089,12 +4154,11 @@ simplify_with_current_value_aux (exp)
abort ();
}
}
-
+
/* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
static void
-clear_struct_flag (x)
- rtx x;
+clear_struct_flag (rtx x)
{
int i;
int j;
@@ -4147,73 +4211,10 @@ clear_struct_flag (x)
}
}
-/* Return the number of RTX objects making up the expression X.
- But if we count more than MAX objects, stop counting. */
-
-static int
-count_sub_rtxs (x, max)
- rtx x;
- int max;
-{
- int i;
- int j;
- enum rtx_code code;
- const char *fmt;
- int total = 0;
-
- code = GET_CODE (x);
-
- switch (code)
- {
- case REG:
- case QUEUED:
- case CONST_INT:
- case CONST_DOUBLE:
- case CONST_VECTOR:
- case SYMBOL_REF:
- case CODE_LABEL:
- case PC:
- case CC0:
- case EQ_ATTR:
- case ATTR_FLAG:
- return 1;
-
- default:
- break;
- }
-
- /* Compare the elements. If any pair of corresponding elements
- fail to match, return 0 for the whole things. */
-
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (total >= max)
- return total;
-
- switch (fmt[i])
- {
- case 'V':
- case 'E':
- for (j = 0; j < XVECLEN (x, i); j++)
- total += count_sub_rtxs (XVECEXP (x, i, j), max);
- break;
-
- case 'e':
- total += count_sub_rtxs (XEXP (x, i), max);
- break;
- }
- }
- return total;
-
-}
-
/* Create table entries for DEFINE_ATTR. */
static void
-gen_attr (exp, lineno)
- rtx exp;
- int lineno;
+gen_attr (rtx exp, int lineno)
{
struct attr_desc *attr;
struct attr_value *av;
@@ -4222,7 +4223,7 @@ gen_attr (exp, lineno)
/* Make a new attribute structure. Check for duplicate by looking at
attr->default_val, since it is initialized by this routine. */
- attr = find_attr (XSTR (exp, 0), 1);
+ attr = find_attr (&XSTR (exp, 0), 1);
if (attr->default_val)
{
message_with_line (lineno, "duplicate definition for attribute %s",
@@ -4240,7 +4241,7 @@ gen_attr (exp, lineno)
name_ptr = XSTR (exp, 1);
while ((p = next_comma_elt (&name_ptr)) != NULL)
{
- av = (struct attr_value *) oballoc (sizeof (struct attr_value));
+ av = oballoc (sizeof (struct attr_value));
av->value = attr_rtx (CONST_STRING, p);
av->next = attr->first_value;
attr->first_value = av;
@@ -4264,7 +4265,7 @@ gen_attr (exp, lineno)
XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
}
- if (! strcmp (attr->name, "length") && ! attr->is_numeric)
+ if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
{
message_with_line (lineno,
"`length' attribute must take numeric values");
@@ -4275,14 +4276,13 @@ gen_attr (exp, lineno)
XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
}
-
+
/* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
alternatives in the constraints. Assume all MATCH_OPERANDs have the same
number of alternatives as this should be checked elsewhere. */
static int
-count_alternatives (exp)
- rtx exp;
+count_alternatives (rtx exp)
{
int i, j, n;
const char *fmt;
@@ -4314,13 +4314,12 @@ count_alternatives (exp)
return 0;
}
-
+
/* Returns nonzero if the given expression contains an EQ_ATTR with the
`alternative' attribute. */
static int
-compares_alternatives_p (exp)
- rtx exp;
+compares_alternatives_p (rtx exp)
{
int i, j;
const char *fmt;
@@ -4347,13 +4346,11 @@ compares_alternatives_p (exp)
return 0;
}
-
+
/* Returns nonzero is INNER is contained in EXP. */
static int
-contained_in_p (inner, exp)
- rtx inner;
- rtx exp;
+contained_in_p (rtx inner, rtx exp)
{
int i, j;
const char *fmt;
@@ -4380,17 +4377,15 @@ contained_in_p (inner, exp)
return 0;
}
-
+
/* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
static void
-gen_insn (exp, lineno)
- rtx exp;
- int lineno;
+gen_insn (rtx exp, int lineno)
{
struct insn_def *id;
- id = (struct insn_def *) oballoc (sizeof (struct insn_def));
+ id = oballoc (sizeof (struct insn_def));
id->next = defs;
defs = id;
id->def = exp;
@@ -4428,14 +4423,12 @@ gen_insn (exp, lineno)
abort ();
}
}
-
+
/* Process a DEFINE_DELAY. Validate the vector length, check if annul
true or annul false is specified, and make a `struct delay_desc'. */
static void
-gen_delay (def, lineno)
- rtx def;
- int lineno;
+gen_delay (rtx def, int lineno)
{
struct delay_desc *delay;
int i;
@@ -4456,14 +4449,14 @@ gen_delay (def, lineno)
have_annul_false = 1;
}
- delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
+ delay = oballoc (sizeof (struct delay_desc));
delay->def = def;
delay->num = ++num_delays;
delay->next = delays;
delay->lineno = lineno;
delays = delay;
}
-
+
/* Process a DEFINE_FUNCTION_UNIT.
This gives information about a function unit contained in the CPU.
@@ -4471,9 +4464,7 @@ gen_delay (def, lineno)
with information used later by `expand_unit'. */
static void
-gen_unit (def, lineno)
- rtx def;
- int lineno;
+gen_unit (rtx def, int lineno)
{
struct function_unit *unit;
struct function_unit_op *op;
@@ -4505,7 +4496,7 @@ gen_unit (def, lineno)
if (unit == 0)
{
- unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
+ unit = oballoc (sizeof (struct function_unit));
unit->name = name;
unit->multiplicity = multiplicity;
unit->simultaneity = simultaneity;
@@ -4518,9 +4509,11 @@ gen_unit (def, lineno)
unit->first_lineno = lineno;
units = unit;
}
+ else
+ XSTR (def, 0) = unit->name;
/* Make a new operation class structure entry and initialize it. */
- op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
+ op = oballoc (sizeof (struct function_unit_op));
op->condexp = condexp;
op->num = unit->num_opclasses++;
op->ready = ready_cost;
@@ -4554,7 +4547,7 @@ gen_unit (def, lineno)
which insns are used by the function unit. */
unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
}
-
+
/* Given a piece of RTX, print a C expression to test its truth value.
We use AND and IOR both for logical and bit-wise operations, so
interpret them as logical unless they are inside a comparison expression.
@@ -4564,9 +4557,7 @@ gen_unit (def, lineno)
a cached local variable instead of calling a function. */
static void
-write_test_expr (exp, flags)
- rtx exp;
- int flags;
+write_test_expr (rtx exp, int flags)
{
int comparison_operator = 0;
RTX_CODE code;
@@ -4699,6 +4690,52 @@ write_test_expr (exp, flags)
write_test_expr (XEXP (exp, 0), flags);
break;
+ case EQ_ATTR_ALT:
+ {
+ int set = XINT (exp, 0), bit = 0;
+
+ if (flags & 1)
+ fatal ("EQ_ATTR_ALT not valid inside comparison");
+
+ if (!set)
+ fatal ("Empty EQ_ATTR_ALT should be optimized out");
+
+ if (!(set & (set - 1)))
+ {
+ if (!(set & 0xffff))
+ {
+ bit += 16;
+ set >>= 16;
+ }
+ if (!(set & 0xff))
+ {
+ bit += 8;
+ set >>= 8;
+ }
+ if (!(set & 0xf))
+ {
+ bit += 4;
+ set >>= 4;
+ }
+ if (!(set & 0x3))
+ {
+ bit += 2;
+ set >>= 2;
+ }
+ if (!(set & 1))
+ bit++;
+
+ printf ("which_alternative %s= %d",
+ XINT (exp, 1) ? "!" : "=", bit);
+ }
+ else
+ {
+ printf ("%s((1 << which_alternative) & 0x%x)",
+ XINT (exp, 1) ? "!" : "", set);
+ }
+ }
+ break;
+
/* Comparison test of an attribute with a value. Most of these will
have been removed by optimization. Handle "alternative"
specially and give error if EQ_ATTR present inside a comparison. */
@@ -4712,7 +4749,7 @@ write_test_expr (exp, flags)
break;
}
- attr = find_attr (XSTR (exp, 0), 0);
+ attr = find_attr (&XSTR (exp, 0), 0);
if (! attr)
abort ();
@@ -4806,14 +4843,12 @@ write_test_expr (exp, flags)
printf (")");
}
-
+
/* Given an attribute value, return the maximum CONST_STRING argument
encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
static int
-max_attr_value (exp, unknownp)
- rtx exp;
- int *unknownp;
+max_attr_value (rtx exp, int *unknownp)
{
int current_max;
int i, n;
@@ -4855,9 +4890,7 @@ max_attr_value (exp, unknownp)
if the numeric value is not known. */
static int
-or_attr_value (exp, unknownp)
- rtx exp;
- int *unknownp;
+or_attr_value (rtx exp, int *unknownp)
{
int current_or;
int i;
@@ -4887,7 +4920,7 @@ or_attr_value (exp, unknownp)
return current_or;
}
-
+
/* Scan an attribute value, possibly a conditional, and record what actions
will be required to do any conditional tests in it.
@@ -4899,8 +4932,7 @@ or_attr_value (exp, unknownp)
*/
static void
-walk_attr_value (exp)
- rtx exp;
+walk_attr_value (rtx exp)
{
int i, j;
const char *fmt;
@@ -4924,10 +4956,14 @@ walk_attr_value (exp)
must_extract = 1;
return;
+ case EQ_ATTR_ALT:
+ must_extract = must_constrain = 1;
+ break;
+
case EQ_ATTR:
if (XSTR (exp, 0) == alternative_name)
must_extract = must_constrain = 1;
- else if (strcmp (XSTR (exp, 0), "length") == 0)
+ else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
length_used = 1;
return;
@@ -4962,12 +4998,11 @@ walk_attr_value (exp)
break;
}
}
-
+
/* Write out a function to obtain the attribute for a given INSN. */
static void
-write_attr_get (attr)
- struct attr_desc *attr;
+write_attr_get (struct attr_desc *attr)
{
struct attr_value *av, *common_av;
@@ -4975,23 +5010,10 @@ write_attr_get (attr)
switch we will generate. */
common_av = find_most_used (attr);
- /* Write out prototype of function. */
- if (!attr->is_numeric)
- printf ("extern enum attr_%s ", attr->name);
- else if (attr->unsigned_p)
- printf ("extern unsigned int ");
- else
- printf ("extern int ");
- /* If the attribute name starts with a star, the remainder is the name of
- the subroutine to use, instead of `get_attr_...'. */
- if (attr->name[0] == '*')
- printf ("%s PARAMS ((rtx));\n", &attr->name[1]);
- else
- printf ("get_attr_%s PARAMS ((%s));\n", attr->name,
- (attr->is_const ? "void" : "rtx"));
-
/* Write out start of function, then all values with explicit `case' lines,
then a `default', then the value with the most uses. */
+ if (attr->static_p)
+ printf ("static ");
if (!attr->is_numeric)
printf ("enum attr_%s\n", attr->name);
else if (attr->unsigned_p)
@@ -5002,12 +5024,12 @@ write_attr_get (attr)
/* If the attribute name starts with a star, the remainder is the name of
the subroutine to use, instead of `get_attr_...'. */
if (attr->name[0] == '*')
- printf ("%s (insn)\n", &attr->name[1]);
+ printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
else if (attr->is_const == 0)
- printf ("get_attr_%s (insn)\n", attr->name);
+ printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
else
{
- printf ("get_attr_%s ()\n", attr->name);
+ printf ("get_attr_%s (void)\n", attr->name);
printf ("{\n");
for (av = attr->first_value; av; av = av->next)
@@ -5020,7 +5042,6 @@ write_attr_get (attr)
return;
}
- printf (" rtx insn;\n");
printf ("{\n");
if (GET_CODE (common_av->value) == FFS)
@@ -5054,17 +5075,14 @@ write_attr_get (attr)
printf (" }\n}\n\n");
}
}
-
+
/* Given an AND tree of known true terms (because we are inside an `if' with
that as the condition or are in an `else' clause) and an expression,
replace any known true terms with TRUE. Use `simplify_and_tree' to do
the bulk of the work. */
static rtx
-eliminate_known_true (known_true, exp, insn_code, insn_index)
- rtx known_true;
- rtx exp;
- int insn_code, insn_index;
+eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
{
rtx term;
@@ -5085,22 +5103,16 @@ eliminate_known_true (known_true, exp, insn_code, insn_index)
return exp;
}
-
+
/* Write out a series of tests and assignment statements to perform tests and
sets of an attribute value. We are passed an indentation amount and prefix
and suffix strings to write around each attribute value (e.g., "return"
and ";"). */
static void
-write_attr_set (attr, indent, value, prefix, suffix, known_true,
- insn_code, insn_index)
- struct attr_desc *attr;
- int indent;
- rtx value;
- const char *prefix;
- const char *suffix;
- rtx known_true;
- int insn_code, insn_index;
+write_attr_set (struct attr_desc *attr, int indent, rtx value,
+ const char *prefix, const char *suffix, rtx known_true,
+ int insn_code, int insn_index)
{
if (GET_CODE (value) == COND)
{
@@ -5183,18 +5195,13 @@ write_attr_set (attr, indent, value, prefix, suffix, known_true,
printf ("%s\n", suffix);
}
}
-
+
/* Write out the computation for one attribute value. */
static void
-write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
- known_true)
- struct attr_desc *attr;
- struct attr_value *av;
- int write_case_lines;
- const char *prefix, *suffix;
- int indent;
- rtx known_true;
+write_attr_case (struct attr_desc *attr, struct attr_value *av,
+ int write_case_lines, const char *prefix, const char *suffix,
+ int indent, rtx known_true)
{
struct insn_ent *ie;
@@ -5254,13 +5261,11 @@ write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
}
printf ("\n");
}
-
+
/* Search for uses of non-const attributes and write code to cache them. */
static int
-write_expr_attr_cache (p, attr)
- rtx p;
- struct attr_desc *attr;
+write_expr_attr_cache (rtx p, struct attr_desc *attr)
{
const char *fmt;
int i, ie, j, je;
@@ -5309,8 +5314,7 @@ write_expr_attr_cache (p, attr)
expressions to cater to older compilers. */
static void
-write_toplevel_expr (p)
- rtx p;
+write_toplevel_expr (rtx p)
{
struct attr_desc *attr;
int i;
@@ -5338,14 +5342,11 @@ write_toplevel_expr (p)
write_test_expr (p, 3);
printf (";\n");
}
-
+
/* Utilities to write names in various forms. */
static void
-write_unit_name (prefix, num, suffix)
- const char *prefix;
- int num;
- const char *suffix;
+write_unit_name (const char *prefix, int num, const char *suffix)
{
struct function_unit *unit;
@@ -5360,9 +5361,7 @@ write_unit_name (prefix, num, suffix)
}
static void
-write_attr_valueq (attr, s)
- struct attr_desc *attr;
- const char *s;
+write_attr_valueq (struct attr_desc *attr, const char *s)
{
if (attr->is_numeric)
{
@@ -5407,9 +5406,7 @@ write_attr_valueq (attr, s)
}
static void
-write_attr_value (attr, value)
- struct attr_desc *attr;
- rtx value;
+write_attr_value (struct attr_desc *attr, rtx value)
{
int op;
@@ -5429,7 +5426,7 @@ write_attr_value (attr, value)
case ATTR:
{
- struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0);
+ struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
printf ("get_attr_%s (%s)", attr2->name,
(attr2->is_const ? "" : "insn"));
}
@@ -5465,8 +5462,7 @@ write_attr_value (attr, value)
}
static void
-write_upcase (str)
- const char *str;
+write_upcase (const char *str)
{
while (*str)
{
@@ -5477,8 +5473,7 @@ write_upcase (str)
}
static void
-write_indent (indent)
- int indent;
+write_indent (int indent)
{
for (; indent > 8; indent -= 8)
printf ("\t");
@@ -5486,7 +5481,7 @@ write_indent (indent)
for (; indent; indent--)
printf (" ");
}
-
+
/* Write a subroutine that is given an insn that requires a delay slot, a
delay slot ordinal, and a candidate insn. It returns nonzero if the
candidate can be placed in the specified delay slot of the insn.
@@ -5500,12 +5495,12 @@ write_indent (indent)
or "annul_false"). */
static void
-write_eligible_delay (kind)
- const char *kind;
+write_eligible_delay (const char *kind)
{
struct delay_desc *delay;
int max_slots;
char str[50];
+ const char *pstr;
struct attr_desc *attr;
struct attr_value *av, *common_av;
int i;
@@ -5521,12 +5516,8 @@ write_eligible_delay (kind)
/* Write function prelude. */
printf ("int\n");
- printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
+ printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
kind);
- printf (" rtx delay_insn ATTRIBUTE_UNUSED;\n");
- printf (" int slot;\n");
- printf (" rtx candidate_insn;\n");
- printf (" int flags ATTRIBUTE_UNUSED;\n");
printf ("{\n");
printf (" rtx insn;\n");
printf ("\n");
@@ -5538,7 +5529,7 @@ write_eligible_delay (kind)
if (num_delays > 1)
{
- attr = find_attr ("*delay_type", 0);
+ attr = find_attr (&delay_type_str, 0);
if (! attr)
abort ();
common_av = find_most_used (attr);
@@ -5567,7 +5558,7 @@ write_eligible_delay (kind)
printf (" switch (recog_memoized (insn))\n");
printf (" {\n");
- attr = find_attr ("*delay_1_0", 0);
+ attr = find_attr (&delay_1_0_str, 0);
if (! attr)
abort ();
common_av = find_most_used (attr);
@@ -5597,7 +5588,8 @@ write_eligible_delay (kind)
printf ("\t{\n");
sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
- attr = find_attr (str, 0);
+ pstr = str;
+ attr = find_attr (&pstr, 0);
if (! attr)
abort ();
common_av = find_most_used (attr);
@@ -5617,12 +5609,12 @@ write_eligible_delay (kind)
printf ("}\n\n");
}
-
+
/* Write routines to compute conflict cost for function units. Then write a
table describing the available function units. */
static void
-write_function_unit_info ()
+write_function_unit_info (void)
{
struct function_unit *unit;
int i;
@@ -5693,22 +5685,21 @@ write_function_unit_info ()
}
static void
-write_complex_function (unit, name, connection)
- struct function_unit *unit;
- const char *name, *connection;
+write_complex_function (struct function_unit *unit,
+ const char *name,
+ const char *connection)
{
struct attr_desc *case_attr, *attr;
struct attr_value *av, *common_av;
rtx value;
char str[256];
+ const char *pstr;
int using_case;
int i;
- printf ("static int %s_unit_%s PARAMS ((rtx, rtx));\n", unit->name, name);
printf ("static int\n");
- printf ("%s_unit_%s (executing_insn, candidate_insn)\n", unit->name, name);
- printf (" rtx executing_insn;\n");
- printf (" rtx candidate_insn;\n");
+ printf ("%s_unit_%s (rtx executing_insn, rtx candidate_insn)\n",
+ unit->name, name);
printf ("{\n");
printf (" rtx insn;\n");
printf (" int casenum;\n\n");
@@ -5720,7 +5711,8 @@ write_complex_function (unit, name, connection)
if (strlen (unit->name) + sizeof "*_cases" > 256)
abort ();
sprintf (str, "*%s_cases", unit->name);
- case_attr = find_attr (str, 0);
+ pstr = str;
+ case_attr = find_attr (&pstr, 0);
if (! case_attr)
abort ();
common_av = find_most_used (case_attr);
@@ -5754,7 +5746,8 @@ write_complex_function (unit, name, connection)
printf (" case %d:\n", i);
sprintf (str, "*%s_%s_%d", unit->name, connection, i);
- attr = find_attr (str, 0);
+ pstr = str;
+ attr = find_attr (&pstr, 0);
if (! attr)
abort ();
@@ -5785,7 +5778,7 @@ write_complex_function (unit, name, connection)
printf (" default:\n abort ();\n");
printf (" }\n}\n\n");
}
-
+
/* This page contains miscellaneous utility routines. */
/* Given a pointer to a (char *), return a malloc'ed string containing the
@@ -5793,8 +5786,7 @@ write_complex_function (unit, name, connection)
scanned, or the end-of-string. Return NULL if at end of string. */
static char *
-next_comma_elt (pstr)
- const char **pstr;
+next_comma_elt (const char **pstr)
{
const char *start;
@@ -5807,15 +5799,15 @@ next_comma_elt (pstr)
}
/* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
- is nonzero, build a new attribute, if one does not exist. */
+ is nonzero, build a new attribute, if one does not exist. *NAME_P is
+ replaced by a pointer to a canonical copy of the string. */
static struct attr_desc *
-find_attr (name, create)
- const char *name;
- int create;
+find_attr (const char **name_p, int create)
{
struct attr_desc *attr;
int index;
+ const char *name = *name_p;
/* Before we resort to using `strcmp', see if the string address matches
anywhere. In most cases, it should have been canonicalized to do so. */
@@ -5830,51 +5822,53 @@ find_attr (name, create)
/* Otherwise, do it the slow way. */
for (attr = attrs[index]; attr; attr = attr->next)
if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
- return attr;
+ {
+ *name_p = attr->name;
+ return attr;
+ }
if (! create)
return NULL;
- attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
- attr->name = attr_string (name, strlen (name));
+ attr = oballoc (sizeof (struct attr_desc));
+ attr->name = DEF_ATTR_STRING (name);
attr->first_value = attr->default_val = NULL;
attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
- attr->unsigned_p = attr->func_units_p = attr->blockage_p = 0;
+ attr->unsigned_p = attr->func_units_p = attr->blockage_p = attr->static_p = 0;
attr->next = attrs[index];
attrs[index] = attr;
+ *name_p = attr->name;
+
return attr;
}
/* Create internal attribute with the given default value. */
void
-make_internal_attr (name, value, special)
- const char *name;
- rtx value;
- int special;
+make_internal_attr (const char *name, rtx value, int special)
{
struct attr_desc *attr;
- attr = find_attr (name, 1);
+ attr = find_attr (&name, 1);
if (attr->default_val)
abort ();
attr->is_numeric = 1;
attr->is_const = 0;
- attr->is_special = (special & 1) != 0;
- attr->negative_ok = (special & 2) != 0;
- attr->unsigned_p = (special & 4) != 0;
- attr->func_units_p = (special & 8) != 0;
- attr->blockage_p = (special & 16) != 0;
+ attr->is_special = (special & ATTR_SPECIAL) != 0;
+ attr->negative_ok = (special & ATTR_NEGATIVE_OK) != 0;
+ attr->unsigned_p = (special & ATTR_UNSIGNED) != 0;
+ attr->func_units_p = (special & ATTR_FUNC_UNITS) != 0;
+ attr->blockage_p = (special & ATTR_BLOCKAGE) != 0;
+ attr->static_p = (special & ATTR_STATIC) != 0;
attr->default_val = get_attr_value (value, attr, -2);
}
/* Find the most used value of an attribute. */
static struct attr_value *
-find_most_used (attr)
- struct attr_desc *attr;
+find_most_used (struct attr_desc *attr)
{
struct attr_value *av;
struct attr_value *most_used;
@@ -5894,8 +5888,7 @@ find_most_used (attr)
return NULL. */
static rtx
-find_single_value (attr)
- struct attr_desc *attr;
+find_single_value (struct attr_desc *attr)
{
struct attr_value *av;
rtx unique_value;
@@ -5916,8 +5909,7 @@ find_single_value (attr)
/* Return (attr_value "n") */
rtx
-make_numeric_value (n)
- int n;
+make_numeric_value (int n)
{
static rtx int_values[20];
rtx exp;
@@ -5937,12 +5929,9 @@ make_numeric_value (n)
return exp;
}
-
+
static void
-extend_range (range, min, max)
- struct range *range;
- int min;
- int max;
+extend_range (struct range *range, int min, int max)
{
if (range->min > min)
range->min = min;
@@ -5951,58 +5940,28 @@ extend_range (range, min, max)
}
static rtx
-copy_rtx_unchanging (orig)
- rtx orig;
+copy_rtx_unchanging (rtx orig)
{
-#if 0
- rtx copy;
- RTX_CODE code;
-#endif
-
if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
return orig;
ATTR_CURR_SIMPLIFIED_P (orig) = 1;
return orig;
-
-#if 0
- code = GET_CODE (orig);
- switch (code)
- {
- case CONST_INT:
- case CONST_DOUBLE:
- case SYMBOL_REF:
- case CODE_LABEL:
- return orig;
-
- default:
- break;
- }
-
- copy = rtx_alloc (code);
- PUT_MODE (copy, GET_MODE (orig));
- ATTR_IND_SIMPLIFIED_P (copy) = 1;
-
- memcpy (&XEXP (copy, 0), &XEXP (orig, 0),
- GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
- return copy;
-#endif
}
/* Determine if an insn has a constant number of delay slots, i.e., the
number of delay slots is not a function of the length of the insn. */
static void
-write_const_num_delay_slots ()
+write_const_num_delay_slots (void)
{
- struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
+ struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
struct attr_value *av;
struct insn_ent *ie;
if (attr)
{
- printf ("int\nconst_num_delay_slots (insn)\n");
- printf (" rtx insn;\n");
+ printf ("int\nconst_num_delay_slots (rtx insn)\n");
printf ("{\n");
printf (" switch (recog_memoized (insn))\n");
printf (" {\n");
@@ -6025,13 +5984,9 @@ write_const_num_delay_slots ()
printf (" }\n}\n\n");
}
}
-
-extern int main PARAMS ((int, char **));
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
rtx desc;
struct attr_desc *attr;
@@ -6058,7 +6013,11 @@ main (argc, argv)
ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
- alternative_name = attr_string ("alternative", strlen ("alternative"));
+ alternative_name = DEF_ATTR_STRING ("alternative");
+ length_str = DEF_ATTR_STRING ("length");
+ delay_type_str = DEF_ATTR_STRING ("*delay_type");
+ delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
+ num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
printf ("/* Generated automatically by the program `genattrtab'\n\
from the machine description file `md'. */\n\n");
@@ -6097,39 +6056,47 @@ from the machine description file `md'. */\n\n");
case DEFINE_CPU_UNIT:
gen_cpu_unit (desc);
break;
-
+
case DEFINE_QUERY_CPU_UNIT:
gen_query_cpu_unit (desc);
break;
-
+
case DEFINE_BYPASS:
gen_bypass (desc);
break;
-
+
case EXCLUSION_SET:
gen_excl_set (desc);
break;
-
+
case PRESENCE_SET:
gen_presence_set (desc);
break;
-
+
+ case FINAL_PRESENCE_SET:
+ gen_final_presence_set (desc);
+ break;
+
case ABSENCE_SET:
gen_absence_set (desc);
break;
-
+
+ case FINAL_ABSENCE_SET:
+ gen_final_absence_set (desc);
+ break;
+
case DEFINE_AUTOMATON:
gen_automaton (desc);
break;
-
+
case AUTOMATA_OPTION:
gen_automata_option (desc);
break;
-
+
case DEFINE_RESERVATION:
gen_reserv (desc);
break;
-
+
case DEFINE_INSN_RESERVATION:
gen_insn_reserv (desc);
break;
@@ -6169,6 +6136,8 @@ from the machine description file `md'. */\n\n");
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
+ printf ("#include \"coretypes.h\"\n");
+ printf ("#include \"tm.h\"\n");
printf ("#include \"rtl.h\"\n");
printf ("#include \"tm_p.h\"\n");
printf ("#include \"insn-config.h\"\n");
@@ -6184,13 +6153,13 @@ from the machine description file `md'. */\n\n");
printf ("#define operands recog_data.operand\n\n");
/* Make `insn_alternatives'. */
- insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
+ insn_alternatives = oballoc (insn_code_number * sizeof (int));
for (id = defs; id; id = id->next)
if (id->insn_code >= 0)
insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
/* Make `insn_n_alternatives'. */
- insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
+ insn_n_alternatives = oballoc (insn_code_number * sizeof (int));
for (id = defs; id; id = id->next)
if (id->insn_code >= 0)
insn_n_alternatives[id->insn_code] = id->num_alternatives;
@@ -6226,7 +6195,18 @@ from the machine description file `md'. */\n\n");
for (attr = attrs[i]; attr; attr = attr->next)
{
if (! attr->is_special && ! attr->is_const)
- write_attr_get (attr);
+ {
+ int insn_alts_p;
+
+ insn_alts_p
+ = (attr->name [0] == '*'
+ && strcmp (&attr->name[1], INSN_ALTS_FUNC_NAME) == 0);
+ if (insn_alts_p)
+ printf ("\n#if AUTOMATON_ALTS\n");
+ write_attr_get (attr);
+ if (insn_alts_p)
+ printf ("#endif\n\n");
+ }
}
/* Write out delay eligibility information, if DEFINE_DELAY present.
@@ -6250,7 +6230,7 @@ from the machine description file `md'. */\n\n");
write_automata ();
}
- /* Write out constant delay slot info */
+ /* Write out constant delay slot info. */
write_const_num_delay_slots ();
write_length_unit_log ();
@@ -6261,8 +6241,7 @@ from the machine description file `md'. */\n\n");
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
const char *
-get_insn_name (code)
- int code ATTRIBUTE_UNUSED;
+get_insn_name (int code ATTRIBUTE_UNUSED)
{
return NULL;
}
diff --git a/contrib/gcc/genattrtab.h b/contrib/gcc/genattrtab.h
index ea1f23991eac..1af43c0a1916 100644
--- a/contrib/gcc/genattrtab.h
+++ b/contrib/gcc/genattrtab.h
@@ -1,43 +1,58 @@
/* External definitions of source files of genattrtab.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+/* Name of function (attribute) to translate insn into number of insn
+ alternatives reservation. */
+#define INSN_ALTS_FUNC_NAME "insn_alts"
+
/* Defined in genattrtab.c: */
-extern rtx check_attr_test PARAMS ((rtx, int, int));
-extern rtx make_numeric_value PARAMS ((int));
-extern void make_internal_attr PARAMS ((const char *, rtx, int));
-extern char *attr_printf PARAMS ((unsigned int, const char *, ...))
+extern rtx check_attr_test (rtx, int, int);
+extern rtx make_numeric_value (int);
+extern void make_internal_attr (const char *, rtx, int);
+extern char *attr_printf (unsigned int, const char *, ...)
ATTRIBUTE_PRINTF_2;
extern int num_dfa_decls;
/* Defined in genautomata.c: */
-extern void gen_cpu_unit PARAMS ((rtx));
-extern void gen_query_cpu_unit PARAMS ((rtx));
-extern void gen_bypass PARAMS ((rtx));
-extern void gen_excl_set PARAMS ((rtx));
-extern void gen_presence_set PARAMS ((rtx));
-extern void gen_absence_set PARAMS ((rtx));
-extern void gen_automaton PARAMS ((rtx));
-extern void gen_automata_option PARAMS ((rtx));
-extern void gen_reserv PARAMS ((rtx));
-extern void gen_insn_reserv PARAMS ((rtx));
-extern void initiate_automaton_gen PARAMS ((int, char **));
-extern void expand_automata PARAMS ((void));
-extern void write_automata PARAMS ((void));
+extern void gen_cpu_unit (rtx);
+extern void gen_query_cpu_unit (rtx);
+extern void gen_bypass (rtx);
+extern void gen_excl_set (rtx);
+extern void gen_presence_set (rtx);
+extern void gen_final_presence_set (rtx);
+extern void gen_absence_set (rtx);
+extern void gen_final_absence_set (rtx);
+extern void gen_automaton (rtx);
+extern void gen_automata_option (rtx);
+extern void gen_reserv (rtx);
+extern void gen_insn_reserv (rtx);
+extern void initiate_automaton_gen (int, char **);
+extern void expand_automata (void);
+extern void write_automata (void);
+
+/* Flags for make_internal_attr's `special' parameter. */
+#define ATTR_NONE 0
+#define ATTR_SPECIAL (1 << 0)
+#define ATTR_NEGATIVE_OK (1 << 1)
+#define ATTR_UNSIGNED (1 << 2)
+#define ATTR_FUNC_UNITS (1 << 3)
+#define ATTR_BLOCKAGE (1 << 4)
+#define ATTR_STATIC (1 << 5)
diff --git a/contrib/gcc/genautomata.c b/contrib/gcc/genautomata.c
index 8c48d6ad637a..b68c63c60b51 100644
--- a/contrib/gcc/genautomata.c
+++ b/contrib/gcc/genautomata.c
@@ -1,27 +1,27 @@
/* Pipeline hazard description translator.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Written by Vladimir Makarov <vmakarov@redhat.com>
-
-This file is part of GNU CC.
-GNU CC is free software; you can redistribute it and/or modify it
+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 2, or (at your option) any
later version.
-GNU CC is distributed in the hope that it will be useful, but WITHOUT
+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 GNU CC; see the file COPYING. If not, write to the Free
+along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* References:
-
+
1. Detecting pipeline structural hazards quickly. T. Proebsting,
C. Fraser. Proceedings of ACM SIGPLAN-SIGACT Symposium on
Principles of Programming Languages, pages 280--286, 1994.
@@ -39,8 +39,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
following:
1. New operator `|' (alternative) is permitted in functional unit
- reservation which can be treated deterministicly and
- non-deterministicly.
+ reservation which can be treated deterministically and
+ non-deterministically.
2. Possibility of usage of nondeterministic automata too.
@@ -48,7 +48,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
automaton state.
4. Several constructions to describe impossible reservations
- (`exclusion_set', `presence_set', and `absence_set').
+ (`exclusion_set', `presence_set', `final_presence_set',
+ `absence_set', and `final_absence_set').
5. No reverse automata are generated. Trace instruction scheduling
requires this. It can be easily added in the future if we
@@ -57,8 +58,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
6. Union of automaton states are not generated yet. It is planned
to be implemented. Such feature is needed to make more accurate
interlock insn scheduling to get state describing functional
- unit reservation in a joint CFG point.
-*/
+ unit reservation in a joint CFG point. */
/* This file code processes constructions of machine description file
which describes automaton used for recognition of processor pipeline
@@ -67,12 +67,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
The translator functions `gen_cpu_unit', `gen_query_cpu_unit',
`gen_bypass', `gen_excl_set', `gen_presence_set',
- `gen_absence_set', `gen_automaton', `gen_automata_option',
+ `gen_final_presence_set', `gen_absence_set',
+ `gen_final_absence_set', `gen_automaton', `gen_automata_option',
`gen_reserv', `gen_insn_reserv' are called from file
`genattrtab.c'. They transform RTL constructions describing
automata in .md file into internal representation convenient for
further processing.
-
+
The translator major function `expand_automata' processes the
description internal representation into finite state automaton.
It can be divided on:
@@ -85,7 +86,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
o optional transformation of nondeterministic finite state
automata into deterministic ones if the alternative operator
- `|' is treated nondeterministicly in the description (major
+ `|' is treated nondeterministically in the description (major
function is NDFA_to_DFA).
o optional minimization of the finite state automata by merging
@@ -100,8 +101,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
function are used by gcc instruction scheduler and may be some
other gcc code. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "obstack.h"
#include "errors.h"
@@ -164,7 +167,7 @@ struct unit_decl;
struct bypass_decl;
struct result_decl;
struct automaton_decl;
-struct unit_rel_decl;
+struct unit_pattern_rel_decl;
struct reserv_decl;
struct insn_reserv_decl;
struct decl;
@@ -179,6 +182,8 @@ struct oneof_regexp;
struct regexp;
struct description;
struct unit_set_el;
+struct pattern_set_el;
+struct pattern_reserv;
struct state;
struct alt_state;
struct arc;
@@ -191,6 +196,8 @@ typedef struct unit_decl *unit_decl_t;
typedef struct decl *decl_t;
typedef struct regexp *regexp_t;
typedef struct unit_set_el *unit_set_el_t;
+typedef struct pattern_set_el *pattern_set_el_t;
+typedef struct pattern_reserv *pattern_reserv_t;
typedef struct alt_state *alt_state_t;
typedef struct state *state_t;
typedef struct arc *arc_t;
@@ -201,314 +208,328 @@ typedef struct state_ainsn_table *state_ainsn_table_t;
/* Prototypes of functions gen_cpu_unit, gen_query_cpu_unit,
- gen_bypass, gen_excl_set, gen_presence_set, gen_absence_set,
- gen_automaton, gen_automata_option, gen_reserv, gen_insn_reserv,
+ gen_bypass, gen_excl_set, gen_presence_set, gen_final_presence_set,
+ gen_absence_set, gen_final_absence_set, gen_automaton,
+ gen_automata_option, gen_reserv, gen_insn_reserv,
initiate_automaton_gen, expand_automata, write_automata are
described on the file top because the functions are called from
function `main'. */
-static void *create_node PARAMS ((size_t));
-static void *copy_node PARAMS ((const void *, size_t));
-static char *check_name PARAMS ((char *, pos_t));
-static char *next_sep_el PARAMS ((char **, int, int));
-static int n_sep_els PARAMS ((char *, int, int));
-static char **get_str_vect PARAMS ((char *, int *, int, int));
-static regexp_t gen_regexp_el PARAMS ((char *));
-static regexp_t gen_regexp_repeat PARAMS ((char *));
-static regexp_t gen_regexp_allof PARAMS ((char *));
-static regexp_t gen_regexp_oneof PARAMS ((char *));
-static regexp_t gen_regexp_sequence PARAMS ((char *));
-static regexp_t gen_regexp PARAMS ((char *));
-
-static unsigned string_hash PARAMS ((const char *));
-static hashval_t automaton_decl_hash PARAMS ((const void *));
-static int automaton_decl_eq_p PARAMS ((const void *,
- const void *));
-static decl_t insert_automaton_decl PARAMS ((decl_t));
-static decl_t find_automaton_decl PARAMS ((char *));
-static void initiate_automaton_decl_table PARAMS ((void));
-static void finish_automaton_decl_table PARAMS ((void));
-
-static hashval_t insn_decl_hash PARAMS ((const void *));
-static int insn_decl_eq_p PARAMS ((const void *,
- const void *));
-static decl_t insert_insn_decl PARAMS ((decl_t));
-static decl_t find_insn_decl PARAMS ((char *));
-static void initiate_insn_decl_table PARAMS ((void));
-static void finish_insn_decl_table PARAMS ((void));
-
-static hashval_t decl_hash PARAMS ((const void *));
-static int decl_eq_p PARAMS ((const void *,
- const void *));
-static decl_t insert_decl PARAMS ((decl_t));
-static decl_t find_decl PARAMS ((char *));
-static void initiate_decl_table PARAMS ((void));
-static void finish_decl_table PARAMS ((void));
-
-static unit_set_el_t process_excls PARAMS ((char **, int, pos_t));
-static void add_excls PARAMS ((unit_set_el_t, unit_set_el_t,
- pos_t));
-static unit_set_el_t process_presence_absence
- PARAMS ((char **, int, pos_t, int));
-static void add_presence_absence PARAMS ((unit_set_el_t, unit_set_el_t,
- pos_t, int));
-static void process_decls PARAMS ((void));
-static struct bypass_decl *find_bypass PARAMS ((struct bypass_decl *,
- struct insn_reserv_decl *));
-static void check_automaton_usage PARAMS ((void));
-static regexp_t process_regexp PARAMS ((regexp_t));
-static void process_regexp_decls PARAMS ((void));
-static void check_usage PARAMS ((void));
-static int loop_in_regexp PARAMS ((regexp_t, decl_t));
-static void check_loops_in_regexps PARAMS ((void));
-static int process_regexp_cycles PARAMS ((regexp_t, int));
-static void evaluate_max_reserv_cycles PARAMS ((void));
-static void check_all_description PARAMS ((void));
-
-static ticker_t create_ticker PARAMS ((void));
-static void ticker_off PARAMS ((ticker_t *));
-static void ticker_on PARAMS ((ticker_t *));
-static int active_time PARAMS ((ticker_t));
-static void print_active_time PARAMS ((FILE *, ticker_t));
-
-static void add_advance_cycle_insn_decl PARAMS ((void));
-
-static alt_state_t get_free_alt_state PARAMS ((void));
-static void free_alt_state PARAMS ((alt_state_t));
-static void free_alt_states PARAMS ((alt_state_t));
-static int alt_state_cmp PARAMS ((const void *alt_state_ptr_1,
- const void *alt_state_ptr_2));
-static alt_state_t uniq_sort_alt_states PARAMS ((alt_state_t));
-static int alt_states_eq PARAMS ((alt_state_t, alt_state_t));
-static void initiate_alt_states PARAMS ((void));
-static void finish_alt_states PARAMS ((void));
-
-static reserv_sets_t alloc_empty_reserv_sets PARAMS ((void));
-static unsigned reserv_sets_hash_value PARAMS ((reserv_sets_t));
-static int reserv_sets_cmp PARAMS ((reserv_sets_t, reserv_sets_t));
-static int reserv_sets_eq PARAMS ((reserv_sets_t, reserv_sets_t));
-static void set_unit_reserv PARAMS ((reserv_sets_t, int, int));
-static int test_unit_reserv PARAMS ((reserv_sets_t, int, int));
-static int it_is_empty_reserv_sets PARAMS ((reserv_sets_t))
+static void *create_node (size_t);
+static void *copy_node (const void *, size_t);
+static char *check_name (char *, pos_t);
+static char *next_sep_el (char **, int, int);
+static int n_sep_els (char *, int, int);
+static char **get_str_vect (char *, int *, int, int);
+static void gen_presence_absence_set (rtx, int, int);
+static regexp_t gen_regexp_el (char *);
+static regexp_t gen_regexp_repeat (char *);
+static regexp_t gen_regexp_allof (char *);
+static regexp_t gen_regexp_oneof (char *);
+static regexp_t gen_regexp_sequence (char *);
+static regexp_t gen_regexp (char *);
+
+static unsigned string_hash (const char *);
+static unsigned automaton_decl_hash (const void *);
+static int automaton_decl_eq_p (const void *,
+ const void *);
+static decl_t insert_automaton_decl (decl_t);
+static decl_t find_automaton_decl (char *);
+static void initiate_automaton_decl_table (void);
+static void finish_automaton_decl_table (void);
+
+static hashval_t insn_decl_hash (const void *);
+static int insn_decl_eq_p (const void *,
+ const void *);
+static decl_t insert_insn_decl (decl_t);
+static decl_t find_insn_decl (char *);
+static void initiate_insn_decl_table (void);
+static void finish_insn_decl_table (void);
+
+static hashval_t decl_hash (const void *);
+static int decl_eq_p (const void *,
+ const void *);
+static decl_t insert_decl (decl_t);
+static decl_t find_decl (char *);
+static void initiate_decl_table (void);
+static void finish_decl_table (void);
+
+static unit_set_el_t process_excls (char **, int, pos_t);
+static void add_excls (unit_set_el_t, unit_set_el_t,
+ pos_t);
+static unit_set_el_t process_presence_absence_names
+ (char **, int, pos_t,
+ int, int);
+static pattern_set_el_t process_presence_absence_patterns
+ (char ***, int, pos_t,
+ int, int);
+static void add_presence_absence (unit_set_el_t,
+ pattern_set_el_t,
+ pos_t, int, int);
+static void process_decls (void);
+static struct bypass_decl *find_bypass (struct bypass_decl *,
+ struct insn_reserv_decl *);
+static void check_automaton_usage (void);
+static regexp_t process_regexp (regexp_t);
+static void process_regexp_decls (void);
+static void check_usage (void);
+static int loop_in_regexp (regexp_t, decl_t);
+static void check_loops_in_regexps (void);
+static void process_regexp_cycles (regexp_t, int, int,
+ int *, int *);
+static void evaluate_max_reserv_cycles (void);
+static void check_all_description (void);
+
+static ticker_t create_ticker (void);
+static void ticker_off (ticker_t *);
+static void ticker_on (ticker_t *);
+static int active_time (ticker_t);
+static void print_active_time (FILE *, ticker_t);
+
+static void add_advance_cycle_insn_decl (void);
+
+static alt_state_t get_free_alt_state (void);
+static void free_alt_state (alt_state_t);
+static void free_alt_states (alt_state_t);
+static int alt_state_cmp (const void *alt_state_ptr_1,
+ const void *alt_state_ptr_2);
+static alt_state_t uniq_sort_alt_states (alt_state_t);
+static int alt_states_eq (alt_state_t, alt_state_t);
+static void initiate_alt_states (void);
+static void finish_alt_states (void);
+
+static reserv_sets_t alloc_empty_reserv_sets (void);
+static unsigned reserv_sets_hash_value (reserv_sets_t);
+static int reserv_sets_cmp (reserv_sets_t, reserv_sets_t);
+static int reserv_sets_eq (reserv_sets_t, reserv_sets_t);
+static void set_unit_reserv (reserv_sets_t, int, int);
+static int test_unit_reserv (reserv_sets_t, int, int);
+static int it_is_empty_reserv_sets (reserv_sets_t)
ATTRIBUTE_UNUSED;
-static int reserv_sets_are_intersected PARAMS ((reserv_sets_t, reserv_sets_t));
-static void reserv_sets_shift PARAMS ((reserv_sets_t, reserv_sets_t));
-static void reserv_sets_or PARAMS ((reserv_sets_t, reserv_sets_t,
- reserv_sets_t));
-static void reserv_sets_and PARAMS ((reserv_sets_t, reserv_sets_t,
- reserv_sets_t))
+static int reserv_sets_are_intersected (reserv_sets_t, reserv_sets_t);
+static void reserv_sets_shift (reserv_sets_t, reserv_sets_t);
+static void reserv_sets_or (reserv_sets_t, reserv_sets_t,
+ reserv_sets_t);
+static void reserv_sets_and (reserv_sets_t, reserv_sets_t,
+ reserv_sets_t)
ATTRIBUTE_UNUSED;
-static void output_cycle_reservs PARAMS ((FILE *, reserv_sets_t,
- int, int));
-static void output_reserv_sets PARAMS ((FILE *, reserv_sets_t));
-static state_t get_free_state PARAMS ((int, automaton_t));
-static void free_state PARAMS ((state_t));
-static hashval_t state_hash PARAMS ((const void *));
-static int state_eq_p PARAMS ((const void *, const void *));
-static state_t insert_state PARAMS ((state_t));
-static void set_state_reserv PARAMS ((state_t, int, int));
-static int intersected_state_reservs_p PARAMS ((state_t, state_t));
-static state_t states_union PARAMS ((state_t, state_t));
-static state_t state_shift PARAMS ((state_t));
-static void initiate_states PARAMS ((void));
-static void finish_states PARAMS ((void));
-
-static void free_arc PARAMS ((arc_t));
-static void remove_arc PARAMS ((state_t, arc_t));
-static arc_t find_arc PARAMS ((state_t, state_t, ainsn_t));
-static arc_t add_arc PARAMS ((state_t, state_t, ainsn_t, int));
-static arc_t first_out_arc PARAMS ((state_t));
-static arc_t next_out_arc PARAMS ((arc_t));
-static void initiate_arcs PARAMS ((void));
-static void finish_arcs PARAMS ((void));
-
-static automata_list_el_t get_free_automata_list_el PARAMS ((void));
-static void free_automata_list_el PARAMS ((automata_list_el_t));
-static void free_automata_list PARAMS ((automata_list_el_t));
-static hashval_t automata_list_hash PARAMS ((const void *));
-static int automata_list_eq_p PARAMS ((const void *, const void *));
-static void initiate_automata_lists PARAMS ((void));
-static void automata_list_start PARAMS ((void));
-static void automata_list_add PARAMS ((automaton_t));
-static automata_list_el_t automata_list_finish PARAMS ((void));
-static void finish_automata_lists PARAMS ((void));
-
-static void initiate_excl_sets PARAMS ((void));
-static reserv_sets_t get_excl_set PARAMS ((reserv_sets_t));
-
-static void initiate_presence_absence_sets PARAMS ((void));
-static reserv_sets_t get_presence_absence_set PARAMS ((reserv_sets_t, int));
-
-static regexp_t copy_insn_regexp PARAMS ((regexp_t));
-static regexp_t transform_1 PARAMS ((regexp_t));
-static regexp_t transform_2 PARAMS ((regexp_t));
-static regexp_t transform_3 PARAMS ((regexp_t));
+static void output_cycle_reservs (FILE *, reserv_sets_t,
+ int, int);
+static void output_reserv_sets (FILE *, reserv_sets_t);
+static state_t get_free_state (int, automaton_t);
+static void free_state (state_t);
+static hashval_t state_hash (const void *);
+static int state_eq_p (const void *, const void *);
+static state_t insert_state (state_t);
+static void set_state_reserv (state_t, int, int);
+static int intersected_state_reservs_p (state_t, state_t);
+static state_t states_union (state_t, state_t, reserv_sets_t);
+static state_t state_shift (state_t, reserv_sets_t);
+static void initiate_states (void);
+static void finish_states (void);
+
+static void free_arc (arc_t);
+static void remove_arc (state_t, arc_t);
+static arc_t find_arc (state_t, state_t, ainsn_t);
+static arc_t add_arc (state_t, state_t, ainsn_t, int);
+static arc_t first_out_arc (state_t);
+static arc_t next_out_arc (arc_t);
+static void initiate_arcs (void);
+static void finish_arcs (void);
+
+static automata_list_el_t get_free_automata_list_el (void);
+static void free_automata_list_el (automata_list_el_t);
+static void free_automata_list (automata_list_el_t);
+static hashval_t automata_list_hash (const void *);
+static int automata_list_eq_p (const void *, const void *);
+static void initiate_automata_lists (void);
+static void automata_list_start (void);
+static void automata_list_add (automaton_t);
+static automata_list_el_t automata_list_finish (void);
+static void finish_automata_lists (void);
+
+static void initiate_excl_sets (void);
+static reserv_sets_t get_excl_set (reserv_sets_t);
+
+static pattern_reserv_t form_reserv_sets_list (pattern_set_el_t);
+static void initiate_presence_absence_pattern_sets (void);
+static int check_presence_pattern_sets (reserv_sets_t,
+ reserv_sets_t, int);
+static int check_absence_pattern_sets (reserv_sets_t, reserv_sets_t,
+ int);
+
+static regexp_t copy_insn_regexp (regexp_t);
+static regexp_t transform_1 (regexp_t);
+static regexp_t transform_2 (regexp_t);
+static regexp_t transform_3 (regexp_t);
static regexp_t regexp_transform_func
- PARAMS ((regexp_t, regexp_t (*) (regexp_t)));
-static regexp_t transform_regexp PARAMS ((regexp_t));
-static void transform_insn_regexps PARAMS ((void));
-
-static void process_unit_to_form_the_same_automaton_unit_lists
- PARAMS ((regexp_t, regexp_t, int));
-static void form_the_same_automaton_unit_lists_from_regexp PARAMS ((regexp_t));
-static void form_the_same_automaton_unit_lists PARAMS ((void));
-static void check_unit_distributions_to_automata PARAMS ((void));
-
-static int process_seq_for_forming_states PARAMS ((regexp_t, automaton_t,
- int));
-static void finish_forming_alt_state PARAMS ((alt_state_t,
- automaton_t));
-static void process_alts_for_forming_states PARAMS ((regexp_t,
- automaton_t, int));
-static void create_alt_states PARAMS ((automaton_t));
-
-static void form_ainsn_with_same_reservs PARAMS ((automaton_t));
-
-static void make_automaton PARAMS ((automaton_t));
-static void form_arcs_marked_by_insn PARAMS ((state_t));
-static void create_composed_state PARAMS ((state_t, arc_t, vla_ptr_t *));
-static void NDFA_to_DFA PARAMS ((automaton_t));
-static void pass_state_graph PARAMS ((state_t, void (*) (state_t)));
-static void pass_states PARAMS ((automaton_t,
- void (*) (state_t)));
-static void initiate_pass_states PARAMS ((void));
-static void add_achieved_state PARAMS ((state_t));
-static int set_out_arc_insns_equiv_num PARAMS ((state_t, int));
-static void clear_arc_insns_equiv_num PARAMS ((state_t));
-static void copy_equiv_class PARAMS ((vla_ptr_t *to,
- const vla_ptr_t *from));
-static int state_is_differed PARAMS ((state_t, int, int));
-static state_t init_equiv_class PARAMS ((state_t *states, int));
-static int partition_equiv_class PARAMS ((state_t *, int,
- vla_ptr_t *, int *));
-static void evaluate_equiv_classes PARAMS ((automaton_t, vla_ptr_t *));
-static void merge_states PARAMS ((automaton_t, vla_ptr_t *));
-static void set_new_cycle_flags PARAMS ((state_t));
-static void minimize_DFA PARAMS ((automaton_t));
-static void incr_states_and_arcs_nums PARAMS ((state_t));
-static void count_states_and_arcs PARAMS ((automaton_t, int *, int *));
-static void build_automaton PARAMS ((automaton_t));
-
-static void set_order_state_num PARAMS ((state_t));
-static void enumerate_states PARAMS ((automaton_t));
-
-static ainsn_t insert_ainsn_into_equiv_class PARAMS ((ainsn_t, ainsn_t));
-static void delete_ainsn_from_equiv_class PARAMS ((ainsn_t));
-static void process_insn_equiv_class PARAMS ((ainsn_t, arc_t *));
-static void process_state_for_insn_equiv_partition PARAMS ((state_t));
-static void set_insn_equiv_classes PARAMS ((automaton_t));
-
-static double estimate_one_automaton_bound PARAMS ((void));
-static int compare_max_occ_cycle_nums PARAMS ((const void *,
- const void *));
-static void units_to_automata_heuristic_distr PARAMS ((void));
-static ainsn_t create_ainsns PARAMS ((void));
-static void units_to_automata_distr PARAMS ((void));
-static void create_automata PARAMS ((void));
-
-static void form_regexp PARAMS ((regexp_t));
-static const char *regexp_representation PARAMS ((regexp_t));
-static void finish_regexp_representation PARAMS ((void));
-
-static void output_range_type PARAMS ((FILE *, long int, long int));
-static int longest_path_length PARAMS ((state_t));
-static void process_state_longest_path_length PARAMS ((state_t));
-static void output_dfa_max_issue_rate PARAMS ((void));
-static void output_vect PARAMS ((vect_el_t *, int));
-static void output_chip_member_name PARAMS ((FILE *, automaton_t));
-static void output_temp_chip_member_name PARAMS ((FILE *, automaton_t));
-static void output_translate_vect_name PARAMS ((FILE *, automaton_t));
-static void output_trans_full_vect_name PARAMS ((FILE *, automaton_t));
-static void output_trans_comb_vect_name PARAMS ((FILE *, automaton_t));
-static void output_trans_check_vect_name PARAMS ((FILE *, automaton_t));
-static void output_trans_base_vect_name PARAMS ((FILE *, automaton_t));
-static void output_state_alts_full_vect_name PARAMS ((FILE *, automaton_t));
-static void output_state_alts_comb_vect_name PARAMS ((FILE *, automaton_t));
-static void output_state_alts_check_vect_name PARAMS ((FILE *, automaton_t));
-static void output_state_alts_base_vect_name PARAMS ((FILE *, automaton_t));
-static void output_min_issue_delay_vect_name PARAMS ((FILE *, automaton_t));
-static void output_dead_lock_vect_name PARAMS ((FILE *, automaton_t));
-static void output_reserved_units_table_name PARAMS ((FILE *, automaton_t));
-static void output_state_member_type PARAMS ((FILE *, automaton_t));
-static void output_chip_definitions PARAMS ((void));
-static void output_translate_vect PARAMS ((automaton_t));
-static int comb_vect_p PARAMS ((state_ainsn_table_t));
-static state_ainsn_table_t create_state_ainsn_table PARAMS ((automaton_t));
+ (regexp_t, regexp_t (*) (regexp_t));
+static regexp_t transform_regexp (regexp_t);
+static void transform_insn_regexps (void);
+
+static void store_alt_unit_usage (regexp_t, regexp_t, int, int);
+static void check_regexp_units_distribution (const char *, regexp_t);
+static void check_unit_distributions_to_automata (void);
+
+static int process_seq_for_forming_states (regexp_t, automaton_t,
+ int);
+static void finish_forming_alt_state (alt_state_t,
+ automaton_t);
+static void process_alts_for_forming_states (regexp_t,
+ automaton_t, int);
+static void create_alt_states (automaton_t);
+
+static void form_ainsn_with_same_reservs (automaton_t);
+
+static reserv_sets_t form_reservs_matter (automaton_t);
+static void make_automaton (automaton_t);
+static void form_arcs_marked_by_insn (state_t);
+static int create_composed_state (state_t, arc_t, vla_ptr_t *);
+static void NDFA_to_DFA (automaton_t);
+static void pass_state_graph (state_t, void (*) (state_t));
+static void pass_states (automaton_t,
+ void (*) (state_t));
+static void initiate_pass_states (void);
+static void add_achieved_state (state_t);
+static int set_out_arc_insns_equiv_num (state_t, int);
+static void clear_arc_insns_equiv_num (state_t);
+static void copy_equiv_class (vla_ptr_t *to,
+ const vla_ptr_t *from);
+static int first_cycle_unit_presence (state_t, int);
+static int state_is_differed (state_t, state_t, int, int);
+static state_t init_equiv_class (state_t *states, int);
+static int partition_equiv_class (state_t *, int,
+ vla_ptr_t *, int *);
+static void evaluate_equiv_classes (automaton_t, vla_ptr_t *);
+static void merge_states (automaton_t, vla_ptr_t *);
+static void set_new_cycle_flags (state_t);
+static void minimize_DFA (automaton_t);
+static void incr_states_and_arcs_nums (state_t);
+static void count_states_and_arcs (automaton_t, int *, int *);
+static void build_automaton (automaton_t);
+
+static void set_order_state_num (state_t);
+static void enumerate_states (automaton_t);
+
+static ainsn_t insert_ainsn_into_equiv_class (ainsn_t, ainsn_t);
+static void delete_ainsn_from_equiv_class (ainsn_t);
+static void process_insn_equiv_class (ainsn_t, arc_t *);
+static void process_state_for_insn_equiv_partition (state_t);
+static void set_insn_equiv_classes (automaton_t);
+
+static double estimate_one_automaton_bound (void);
+static int compare_max_occ_cycle_nums (const void *,
+ const void *);
+static void units_to_automata_heuristic_distr (void);
+static ainsn_t create_ainsns (void);
+static void units_to_automata_distr (void);
+static void create_automata (void);
+
+static void form_regexp (regexp_t);
+static const char *regexp_representation (regexp_t);
+static void finish_regexp_representation (void);
+
+static void output_range_type (FILE *, long int, long int);
+static int longest_path_length (state_t);
+static void process_state_longest_path_length (state_t);
+static void output_dfa_max_issue_rate (void);
+static void output_vect (vect_el_t *, int);
+static void output_chip_member_name (FILE *, automaton_t);
+static void output_temp_chip_member_name (FILE *, automaton_t);
+static void output_translate_vect_name (FILE *, automaton_t);
+static void output_trans_full_vect_name (FILE *, automaton_t);
+static void output_trans_comb_vect_name (FILE *, automaton_t);
+static void output_trans_check_vect_name (FILE *, automaton_t);
+static void output_trans_base_vect_name (FILE *, automaton_t);
+static void output_state_alts_full_vect_name (FILE *, automaton_t);
+static void output_state_alts_comb_vect_name (FILE *, automaton_t);
+static void output_state_alts_check_vect_name (FILE *, automaton_t);
+static void output_state_alts_base_vect_name (FILE *, automaton_t);
+static void output_min_issue_delay_vect_name (FILE *, automaton_t);
+static void output_dead_lock_vect_name (FILE *, automaton_t);
+static void output_reserved_units_table_name (FILE *, automaton_t);
+static void output_state_member_type (FILE *, automaton_t);
+static void output_chip_definitions (void);
+static void output_translate_vect (automaton_t);
+static int comb_vect_p (state_ainsn_table_t);
+static state_ainsn_table_t create_state_ainsn_table (automaton_t);
static void output_state_ainsn_table
- PARAMS ((state_ainsn_table_t, char *, void (*) (FILE *, automaton_t),
- void (*) (FILE *, automaton_t), void (*) (FILE *, automaton_t),
- void (*) (FILE *, automaton_t)));
-static void add_vect PARAMS ((state_ainsn_table_t,
- int, vect_el_t *, int));
-static int out_state_arcs_num PARAMS ((state_t));
-static int compare_transition_els_num PARAMS ((const void *, const void *));
-static void add_vect_el PARAMS ((vla_hwint_t *,
- ainsn_t, int));
-static void add_states_vect_el PARAMS ((state_t));
-static void output_trans_table PARAMS ((automaton_t));
-static void output_state_alts_table PARAMS ((automaton_t));
-static int min_issue_delay_pass_states PARAMS ((state_t, ainsn_t));
-static int min_issue_delay PARAMS ((state_t, ainsn_t));
-static void initiate_min_issue_delay_pass_states PARAMS ((void));
-static void output_min_issue_delay_table PARAMS ((automaton_t));
-static void output_dead_lock_vect PARAMS ((automaton_t));
-static void output_reserved_units_table PARAMS ((automaton_t));
-static void output_tables PARAMS ((void));
-static void output_max_insn_queue_index_def PARAMS ((void));
-static void output_insn_code_cases PARAMS ((void (*) (automata_list_el_t)));
-static void output_automata_list_min_issue_delay_code PARAMS ((automata_list_el_t));
-static void output_internal_min_issue_delay_func PARAMS ((void));
-static void output_automata_list_transition_code PARAMS ((automata_list_el_t));
-static void output_internal_trans_func PARAMS ((void));
-static void output_internal_insn_code_evaluation PARAMS ((const char *,
- const char *, int));
-static void output_dfa_insn_code_func PARAMS ((void));
-static void output_trans_func PARAMS ((void));
-static void output_automata_list_state_alts_code PARAMS ((automata_list_el_t));
-static void output_internal_state_alts_func PARAMS ((void));
-static void output_state_alts_func PARAMS ((void));
-static void output_min_issue_delay_func PARAMS ((void));
-static void output_internal_dead_lock_func PARAMS ((void));
-static void output_dead_lock_func PARAMS ((void));
-static void output_internal_reset_func PARAMS ((void));
-static void output_size_func PARAMS ((void));
-static void output_reset_func PARAMS ((void));
-static void output_min_insn_conflict_delay_func PARAMS ((void));
-static void output_internal_insn_latency_func PARAMS ((void));
-static void output_insn_latency_func PARAMS ((void));
-static void output_print_reservation_func PARAMS ((void));
-static int units_cmp PARAMS ((const void *,
- const void *));
-static void output_get_cpu_unit_code_func PARAMS ((void));
-static void output_cpu_unit_reservation_p PARAMS ((void));
-static void output_dfa_start_func PARAMS ((void));
-static void output_dfa_finish_func PARAMS ((void));
-
-static void output_regexp PARAMS ((regexp_t ));
-static void output_unit_set_el_list PARAMS ((unit_set_el_t));
-static void output_description PARAMS ((void));
-static void output_automaton_name PARAMS ((FILE *, automaton_t));
-static void output_automaton_units PARAMS ((automaton_t));
-static void add_state_reservs PARAMS ((state_t));
-static void output_state_arcs PARAMS ((state_t));
-static int state_reservs_cmp PARAMS ((const void *,
- const void *));
-static void remove_state_duplicate_reservs PARAMS ((void));
-static void output_state PARAMS ((state_t));
-static void output_automaton_descriptions PARAMS ((void));
-static void output_statistics PARAMS ((FILE *));
-static void output_time_statistics PARAMS ((FILE *));
-static void generate PARAMS ((void));
-
-static void make_insn_alts_attr PARAMS ((void));
-static void make_internal_dfa_insn_code_attr PARAMS ((void));
-static void make_default_insn_latency_attr PARAMS ((void));
-static void make_bypass_attr PARAMS ((void));
-static const char *file_name_suffix PARAMS ((const char *));
-static const char *base_file_name PARAMS ((const char *));
-static void check_automata_insn_issues PARAMS ((void));
-static void add_automaton_state PARAMS ((state_t));
-static void form_important_insn_automata_lists PARAMS ((void));
+ (state_ainsn_table_t, char *, void (*) (FILE *, automaton_t),
+ void (*) (FILE *, automaton_t), void (*) (FILE *, automaton_t),
+ void (*) (FILE *, automaton_t));
+static void add_vect (state_ainsn_table_t,
+ int, vect_el_t *, int);
+static int out_state_arcs_num (state_t);
+static int compare_transition_els_num (const void *, const void *);
+static void add_vect_el (vla_hwint_t *,
+ ainsn_t, int);
+static void add_states_vect_el (state_t);
+static void output_trans_table (automaton_t);
+static void output_state_alts_table (automaton_t);
+static int min_issue_delay_pass_states (state_t, ainsn_t);
+static int min_issue_delay (state_t, ainsn_t);
+static void initiate_min_issue_delay_pass_states (void);
+static void output_min_issue_delay_table (automaton_t);
+static void output_dead_lock_vect (automaton_t);
+static void output_reserved_units_table (automaton_t);
+static void output_tables (void);
+static void output_max_insn_queue_index_def (void);
+static void output_insn_code_cases (void (*) (automata_list_el_t));
+static void output_automata_list_min_issue_delay_code (automata_list_el_t);
+static void output_internal_min_issue_delay_func (void);
+static void output_automata_list_transition_code (automata_list_el_t);
+static void output_internal_trans_func (void);
+static void output_internal_insn_code_evaluation (const char *,
+ const char *, int);
+static void output_dfa_insn_code_func (void);
+static void output_trans_func (void);
+static void output_automata_list_state_alts_code (automata_list_el_t);
+static void output_internal_state_alts_func (void);
+static void output_state_alts_func (void);
+static void output_min_issue_delay_func (void);
+static void output_internal_dead_lock_func (void);
+static void output_dead_lock_func (void);
+static void output_internal_reset_func (void);
+static void output_size_func (void);
+static void output_reset_func (void);
+static void output_min_insn_conflict_delay_func (void);
+static void output_internal_insn_latency_func (void);
+static void output_insn_latency_func (void);
+static void output_print_reservation_func (void);
+static int units_cmp (const void *,
+ const void *);
+static void output_get_cpu_unit_code_func (void);
+static void output_cpu_unit_reservation_p (void);
+static void output_dfa_clean_insn_cache_func (void);
+static void output_dfa_start_func (void);
+static void output_dfa_finish_func (void);
+
+static void output_regexp (regexp_t );
+static void output_unit_set_el_list (unit_set_el_t);
+static void output_pattern_set_el_list (pattern_set_el_t);
+static void output_description (void);
+static void output_automaton_name (FILE *, automaton_t);
+static void output_automaton_units (automaton_t);
+static void add_state_reservs (state_t);
+static void output_state_arcs (state_t);
+static int state_reservs_cmp (const void *,
+ const void *);
+static void remove_state_duplicate_reservs (void);
+static void output_state (state_t);
+static void output_automaton_descriptions (void);
+static void output_statistics (FILE *);
+static void output_time_statistics (FILE *);
+static void generate (void);
+
+static void make_insn_alts_attr (void);
+static void make_internal_dfa_insn_code_attr (void);
+static void make_default_insn_latency_attr (void);
+static void make_bypass_attr (void);
+static const char *file_name_suffix (const char *);
+static const char *base_file_name (const char *);
+static void check_automata_insn_issues (void);
+static void add_automaton_state (state_t);
+static void form_important_insn_automata_lists (void);
/* Undefined position. */
static pos_t no_pos = 0;
@@ -524,14 +545,14 @@ static struct obstack irp;
allocator when varray is used only. */
/* Start work with vla. */
-#define VLA_PTR_CREATE(vla, allocated_length, name) \
- do \
- { \
- vla_ptr_t *const vla_ptr = &(vla); \
- \
- VARRAY_GENERIC_PTR_INIT (vla_ptr->varray, allocated_length, name);\
- vla_ptr->length = 0; \
- } \
+#define VLA_PTR_CREATE(vla, allocated_length, name) \
+ do \
+ { \
+ vla_ptr_t *const _vla_ptr = &(vla); \
+ \
+ VARRAY_GENERIC_PTR_INIT (_vla_ptr->varray, allocated_length, name);\
+ _vla_ptr->length = 0; \
+ } \
while (0)
/* Finish work with the vla. */
@@ -554,23 +575,23 @@ static struct obstack irp;
undefined. */
#define VLA_PTR_EXPAND(vla, n) \
do { \
- vla_ptr_t *const expand_vla_ptr = &(vla); \
- const size_t new_length = (n) + expand_vla_ptr->length; \
+ vla_ptr_t *const _expand_vla_ptr = &(vla); \
+ const size_t _new_length = (n) + _expand_vla_ptr->length; \
\
- if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
- VARRAY_GROW (expand_vla_ptr->varray, \
- (new_length - expand_vla_ptr->length < 128 \
- ? expand_vla_ptr->length + 128 : new_length)); \
- expand_vla_ptr->length = new_length; \
+ if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length) \
+ VARRAY_GROW (_expand_vla_ptr->varray, \
+ (_new_length - _expand_vla_ptr->length < 128 \
+ ? _expand_vla_ptr->length + 128 : _new_length)); \
+ _expand_vla_ptr->length = _new_length; \
} while (0)
/* Add element to the end of the vla. */
-#define VLA_PTR_ADD(vla, ptr) \
- do { \
- vla_ptr_t *const vla_ptr = &(vla); \
- \
- VLA_PTR_EXPAND (*vla_ptr, 1); \
- VARRAY_GENERIC_PTR (vla_ptr->varray, vla_ptr->length - 1) = (ptr);\
+#define VLA_PTR_ADD(vla, ptr) \
+ do { \
+ vla_ptr_t *const _vla_ptr = &(vla); \
+ \
+ VLA_PTR_EXPAND (*_vla_ptr, 1); \
+ VARRAY_GENERIC_PTR (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr);\
} while (0)
/* Length of the vla in elements. */
@@ -585,10 +606,10 @@ static struct obstack irp;
#define VLA_HWINT_CREATE(vla, allocated_length, name) \
do { \
- vla_hwint_t *const vla_ptr = &(vla); \
+ vla_hwint_t *const _vla_ptr = &(vla); \
\
- VARRAY_WIDE_INT_INIT (vla_ptr->varray, allocated_length, name); \
- vla_ptr->length = 0; \
+ VARRAY_WIDE_INT_INIT (_vla_ptr->varray, allocated_length, name); \
+ _vla_ptr->length = 0; \
} while (0)
#define VLA_HWINT_DELETE(vla) VARRAY_FREE ((vla).varray)
@@ -599,22 +620,22 @@ static struct obstack irp;
#define VLA_HWINT_EXPAND(vla, n) \
do { \
- vla_hwint_t *const expand_vla_ptr = &(vla); \
- const size_t new_length = (n) + expand_vla_ptr->length; \
+ vla_hwint_t *const _expand_vla_ptr = &(vla); \
+ const size_t _new_length = (n) + _expand_vla_ptr->length; \
\
- if (VARRAY_SIZE (expand_vla_ptr->varray) < new_length) \
- VARRAY_GROW (expand_vla_ptr->varray, \
- (new_length - expand_vla_ptr->length < 128 \
- ? expand_vla_ptr->length + 128 : new_length)); \
- expand_vla_ptr->length = new_length; \
+ if (VARRAY_SIZE (_expand_vla_ptr->varray) < _new_length) \
+ VARRAY_GROW (_expand_vla_ptr->varray, \
+ (_new_length - _expand_vla_ptr->length < 128 \
+ ? _expand_vla_ptr->length + 128 : _new_length)); \
+ _expand_vla_ptr->length = _new_length; \
} while (0)
#define VLA_HWINT_ADD(vla, ptr) \
do { \
- vla_hwint_t *const vla_ptr = &(vla); \
+ vla_hwint_t *const _vla_ptr = &(vla); \
\
- VLA_HWINT_EXPAND (*vla_ptr, 1); \
- VARRAY_WIDE_INT (vla_ptr->varray, vla_ptr->length - 1) = (ptr); \
+ VLA_HWINT_EXPAND (*_vla_ptr, 1); \
+ VARRAY_WIDE_INT (_vla_ptr->varray, _vla_ptr->length - 1) = (ptr); \
} while (0)
#define VLA_HWINT_LENGTH(vla) ((vla).length)
@@ -637,6 +658,8 @@ static struct obstack irp;
#define NDFA_OPTION "-ndfa"
+#define PROGRESS_OPTION "-progress"
+
/* The following flags are set up by function `initiate_automaton_gen'. */
/* Make automata with nondeterministic reservation by insns (`-ndfa'). */
@@ -659,6 +682,10 @@ static int time_flag;
result automaton and statistics information (`-v'). */
static int v_flag;
+/* Flag of output of a progress bar showing how many states were
+ generated so far for automaton being processed (`-progress'). */
+static int progress_flag;
+
/* Flag of generating warning instead of error for non-critical errors
(`-w'). */
static int w_flag;
@@ -712,14 +739,6 @@ struct unit_decl
regexp. */
char unit_is_used;
- /* The following field value is used to form cyclic lists of units
- which should be in the same automaton because the unit is
- reserved not on all alternatives of a regexp on a cycle. */
- unit_decl_t the_same_automaton_unit;
- /* The following field is TRUE if we already reported that the unit
- is not in the same automaton. */
- int the_same_automaton_message_reported_p;
-
/* The following field value is order number (0, 1, ...) of given
unit. */
int unit_num;
@@ -731,24 +750,38 @@ struct unit_decl
which given unit occurs in insns. Zero value means that given
unit is not used in insns. */
int max_occ_cycle_num;
+ /* The following field value is minimal cycle number (0, ...) on
+ which given unit occurs in insns. -1 value means that given
+ unit is not used in insns. */
+ int min_occ_cycle_num;
/* The following list contains units which conflict with given
unit. */
unit_set_el_t excl_list;
- /* The following list contains units which are required to
+ /* The following list contains patterns which are required to
reservation of given unit. */
- unit_set_el_t presence_list;
- /* The following list contains units which should be not present in
- reservation for given unit. */
- unit_set_el_t absence_list;
+ pattern_set_el_t presence_list;
+ pattern_set_el_t final_presence_list;
+ /* The following list contains patterns which should be not present
+ in reservation for given unit. */
+ pattern_set_el_t absence_list;
+ pattern_set_el_t final_absence_list;
/* The following is used only when `query_p' has nonzero value.
This is query number for the unit. */
int query_num;
+ /* The following is the last cycle on which the unit was checked for
+ correct distributions of units to automata in a regexp. */
+ int last_distribution_check_cycle;
/* The following fields are defined by automaton generator. */
/* The following field value is number of the automaton to which
given unit belongs. */
int corresponding_automaton_num;
+ /* If the following value is not zero, the cpu unit is present in a
+ `exclusion_set' or in right part of a `presence_set',
+ `final_presence_set', `absence_set', and
+ `final_absence_set'define_query_cpu_unit. */
+ char in_set_p;
};
/* This describes define_bypass (see file rtl.def). */
@@ -788,15 +821,26 @@ struct automaton_decl
automaton_t corresponding_automaton;
};
-/* This describes unit relations: exclusion_set, presence_set, or
- absence_set (see file rtl.def). */
-struct unit_rel_decl
+/* This describes exclusion relations: exclusion_set (see file
+ rtl.def). */
+struct excl_rel_decl
{
- int names_num;
+ int all_names_num;
int first_list_length;
char *names [1];
};
+/* This describes unit relations: [final_]presence_set or
+ [final_]absence_set (see file rtl.def). */
+struct unit_pattern_rel_decl
+{
+ int final_p;
+ int names_num;
+ int patterns_num;
+ char **names;
+ char ***patterns;
+};
+
/* This describes define_reservation (see file rtl.def). */
struct reserv_decl
{
@@ -813,7 +857,7 @@ struct reserv_decl
int loop_pass_num;
};
-/* This describes define_insn_reservartion (see file rtl.def). */
+/* This describes define_insn_reservation (see file rtl.def). */
struct insn_reserv_decl
{
rtx condexp;
@@ -840,7 +884,7 @@ struct insn_reserv_decl
insn `cycle advancing'. */
regexp_t transformed_regexp;
/* The following field value is list of arcs marked given
- insn. The field is used in transfromation NDFA -> DFA. */
+ insn. The field is used in transformation NDFA -> DFA. */
arc_t arcs_marked_by_insn;
/* The two following fields are used during minimization of a finite state
automaton. */
@@ -870,9 +914,9 @@ struct decl
struct unit_decl unit;
struct bypass_decl bypass;
struct automaton_decl automaton;
- struct unit_rel_decl excl;
- struct unit_rel_decl presence;
- struct unit_rel_decl absence;
+ struct excl_rel_decl excl;
+ struct unit_pattern_rel_decl presence;
+ struct unit_pattern_rel_decl absence;
struct reserv_decl reserv;
struct insn_reserv_decl insn_reserv;
} decl;
@@ -960,7 +1004,7 @@ struct regexp
} regexp;
};
-/* Reperesents description of pipeline hazard description based on
+/* Represents description of pipeline hazard description based on
NDFA. */
struct description
{
@@ -991,22 +1035,41 @@ struct description
};
-
/* The following nodes are created in automaton checker. */
-/* The following nodes represent exclusion, presence, absence set for
- cpu units. Each element are accessed through only one excl_list,
- presence_list, absence_list. */
+/* The following nodes represent exclusion set for cpu units. Each
+ element is accessed through only one excl_list. */
struct unit_set_el
{
unit_decl_t unit_decl;
unit_set_el_t next_unit_set_el;
};
+/* The following nodes represent presence or absence pattern for cpu
+ units. Each element is accessed through only one presence_list or
+ absence_list. */
+struct pattern_set_el
+{
+ /* The number of units in unit_decls. */
+ int units_num;
+ /* The units forming the pattern. */
+ struct unit_decl **unit_decls;
+ pattern_set_el_t next_pattern_set_el;
+};
/* The following nodes are created in automaton generator. */
+
+/* The following nodes represent presence or absence pattern for cpu
+ units. Each element is accessed through only one element of
+ unit_presence_set_table or unit_absence_set_table. */
+struct pattern_reserv
+{
+ reserv_sets_t reserv;
+ pattern_reserv_t next_pattern_reserv;
+};
+
/* The following node type describes state automaton. The state may
be deterministic or non-deterministic. Non-deterministic state has
several component states which represent alternative cpu units
@@ -1033,11 +1096,12 @@ struct state
char it_was_placed_in_stack_for_NDFA_forming;
/* The following field is used to form DFA. */
char it_was_placed_in_stack_for_DFA_forming;
- /* The following field is used to transform NDFA to DFA. The field
- value is not NULL if the state is a compound state. In this case
- the value of field `unit_sets_list' is NULL. All states in the
- list are in the hash table. The list is formed through field
- `next_sorted_alt_state'. */
+ /* The following field is used to transform NDFA to DFA and DFA
+ minimization. The field value is not NULL if the state is a
+ compound state. In this case the value of field `unit_sets_list'
+ is NULL. All states in the list are in the hash table. The list
+ is formed through field `next_sorted_alt_state'. We should
+ support only one level of nesting state. */
alt_state_t component_states;
/* The following field is used for passing graph of states. */
int pass_num;
@@ -1087,7 +1151,7 @@ struct arc
state. */
arc_t next_out_arc;
/* List of arcs marked given insn is formed with the following
- field. The field is used in transfromation NDFA -> DFA. */
+ field. The field is used in transformation NDFA -> DFA. */
arc_t next_arc_marked_by_insn;
/* The following field is defined if NDFA_FLAG is zero. The member
value is number of alternative reservations which can be used for
@@ -1100,7 +1164,7 @@ struct arc
of automaton insn or which is part of NDFA. */
struct alt_state
{
- /* The following field is a determinist state which characterizes
+ /* The following field is a deterministic state which characterizes
unit reservations of the instruction. */
state_t state;
/* The following field refers to the next state which characterizes
@@ -1156,7 +1220,7 @@ struct ainsn
int important_p;
};
-/* The folowing describes an automaton for PHR. */
+/* The following describes an automaton for PHR. */
struct automaton
{
/* The following field value is the list of insn declarations for
@@ -1249,14 +1313,14 @@ struct state_ainsn_table
&(_decl)->decl.bypass; }))
#define DECL_AUTOMATON(d) __extension__ \
-(({ struct decl *const _decl = (d); \
+(({ struct decl *const _decl = (d); \
if (_decl->mode != dm_automaton) \
decl_mode_check_failed (_decl->mode, "dm_automaton", \
__FILE__, __LINE__, __FUNCTION__); \
&(_decl)->decl.automaton; }))
#define DECL_EXCL(d) __extension__ \
-(({ struct decl *const _decl = (d); \
+(({ struct decl *const _decl = (d); \
if (_decl->mode != dm_excl) \
decl_mode_check_failed (_decl->mode, "dm_excl", \
__FILE__, __LINE__, __FUNCTION__); \
@@ -1270,7 +1334,7 @@ struct state_ainsn_table
&(_decl)->decl.presence; }))
#define DECL_ABSENCE(d) __extension__ \
-(({ struct decl *const _decl = (d); \
+(({ struct decl *const _decl = (d); \
if (_decl->mode != dm_absence) \
decl_mode_check_failed (_decl->mode, "dm_absence", \
__FILE__, __LINE__, __FUNCTION__); \
@@ -1284,20 +1348,19 @@ struct state_ainsn_table
&(_decl)->decl.reserv; }))
#define DECL_INSN_RESERV(d) __extension__ \
-(({ struct decl *const _decl = (d); \
+(({ struct decl *const _decl = (d); \
if (_decl->mode != dm_insn_reserv) \
decl_mode_check_failed (_decl->mode, "dm_insn_reserv", \
__FILE__, __LINE__, __FUNCTION__); \
&(_decl)->decl.insn_reserv; }))
-static const char *decl_name PARAMS ((enum decl_mode));
-static void decl_mode_check_failed PARAMS ((enum decl_mode, const char *,
- const char *, int, const char *));
+static const char *decl_name (enum decl_mode);
+static void decl_mode_check_failed (enum decl_mode, const char *,
+ const char *, int, const char *);
/* Return string representation of declaration mode MODE. */
static const char *
-decl_name (mode)
- enum decl_mode mode;
+decl_name (enum decl_mode mode)
{
static char str [100];
@@ -1325,12 +1388,8 @@ decl_name (mode)
/* The function prints message about unexpected declaration and finish
the program. */
static void
-decl_mode_check_failed (mode, expected_mode_str, file, line, func)
- enum decl_mode mode;
- const char *expected_mode_str;
- const char *file;
- int line;
- const char *func;
+decl_mode_check_failed (enum decl_mode mode, const char *expected_mode_str,
+ const char *file, int line, const char *func)
{
fprintf
(stderr,
@@ -1382,16 +1441,15 @@ decl_mode_check_failed (mode, expected_mode_str, file, line, func)
__FILE__, __LINE__, __FUNCTION__); \
&(_regexp)->regexp.oneof; }))
-static const char *regexp_name PARAMS ((enum regexp_mode));
-static void regexp_mode_check_failed PARAMS ((enum regexp_mode, const char *,
- const char *, int,
- const char *));
+static const char *regexp_name (enum regexp_mode);
+static void regexp_mode_check_failed (enum regexp_mode, const char *,
+ const char *, int,
+ const char *);
/* Return string representation of regexp mode MODE. */
static const char *
-regexp_name (mode)
- enum regexp_mode mode;
+regexp_name (enum regexp_mode mode)
{
static char str [100];
@@ -1417,12 +1475,9 @@ regexp_name (mode)
/* The function prints message about unexpected regexp and finish the
program. */
static void
-regexp_mode_check_failed (mode, expected_mode_str, file, line, func)
- enum regexp_mode mode;
- const char *expected_mode_str;
- const char *file;
- int line;
- const char *func;
+regexp_mode_check_failed (enum regexp_mode mode,
+ const char *expected_mode_str,
+ const char *file, int line, const char *func)
{
fprintf
(stderr,
@@ -1453,8 +1508,7 @@ regexp_mode_check_failed (mode, expected_mode_str, file, line, func)
/* Create IR structure (node). */
static void *
-create_node (size)
- size_t size;
+create_node (size_t size)
{
void *result;
@@ -1468,9 +1522,7 @@ create_node (size)
/* Copy IR structure (node). */
static void *
-copy_node (from, size)
- const void *from;
- size_t size;
+copy_node (const void *from, size_t size)
{
void *const result = create_node (size);
memcpy (result, from, size);
@@ -1479,9 +1531,7 @@ copy_node (from, size)
/* The function checks that NAME does not contain quotes (`"'). */
static char *
-check_name (name, pos)
- char * name;
- pos_t pos ATTRIBUTE_UNUSED;
+check_name (char * name, pos_t pos ATTRIBUTE_UNUSED)
{
const char *str;
@@ -1491,7 +1541,7 @@ check_name (name, pos)
return name;
}
-/* Pointers top all declartions during IR generation are stored in the
+/* Pointers to all declarations during IR generation are stored in the
following. */
static vla_ptr_t decls;
@@ -1501,10 +1551,7 @@ static vla_ptr_t decls;
after the string scanned, or the end-of-string. Return NULL if at
end of string. */
static char *
-next_sep_el (pstr, sep, par_flag)
- char **pstr;
- int sep;
- int par_flag;
+next_sep_el (char **pstr, int sep, int par_flag)
{
char *out_str;
char *p;
@@ -1549,13 +1596,10 @@ next_sep_el (pstr, sep, par_flag)
/* Given a string and a separator, return the number of separated
elements in it, taking parentheses into account if PAR_FLAG has
- nonzero value. Return 0 for the null string, -1 if parantheses is
+ nonzero value. Return 0 for the null string, -1 if parentheses is
not balanced. */
static int
-n_sep_els (s, sep, par_flag)
- char *s;
- int sep;
- int par_flag;
+n_sep_els (char *s, int sep, int par_flag)
{
int n;
int pars_num;
@@ -1576,47 +1620,45 @@ n_sep_els (s, sep, par_flag)
/* Given a string and a separator, return vector of strings which are
elements in the string and number of elements through els_num.
- Take parentheses into account if PAR_FLAG has nonzero value.
- Return 0 for the null string, -1 if parantheses are not balanced. */
+ Take parentheses into account if PAREN_P has nonzero value. The
+ function also inserts the end marker NULL at the end of vector.
+ Return 0 for the null string, -1 if parentheses are not balanced. */
static char **
-get_str_vect (str, els_num, sep, par_flag)
- char *str;
- int *els_num;
- int sep;
- int par_flag;
+get_str_vect (char *str, int *els_num, int sep, int paren_p)
{
int i;
char **vect;
char **pstr;
- *els_num = n_sep_els (str, sep, par_flag);
+ *els_num = n_sep_els (str, sep, paren_p);
if (*els_num <= 0)
return NULL;
- obstack_blank (&irp, sizeof (char *) * (*els_num));
+ obstack_blank (&irp, sizeof (char *) * (*els_num + 1));
vect = (char **) obstack_base (&irp);
obstack_finish (&irp);
pstr = &str;
for (i = 0; i < *els_num; i++)
- vect [i] = next_sep_el (pstr, sep, par_flag);
- if (next_sep_el (pstr, sep, par_flag) != NULL)
+ vect [i] = next_sep_el (pstr, sep, paren_p);
+ if (next_sep_el (pstr, sep, paren_p) != NULL)
abort ();
+ vect [i] = NULL;
return vect;
}
-/* Process a DEFINE_CPU_UNIT.
+/* Process a DEFINE_CPU_UNIT.
This gives information about a unit contained in CPU. We fill a
struct unit_decl with information used later by `expand_automata'. */
void
-gen_cpu_unit (def)
- rtx def;
+gen_cpu_unit (rtx def)
{
decl_t decl;
char **str_cpu_units;
int vect_length;
int i;
- str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',', 0);
+ str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
+ FALSE);
if (str_cpu_units == NULL)
fatal ("invalid string `%s' in define_cpu_unit", XSTR (def, 0));
for (i = 0; i < vect_length; i++)
@@ -1627,25 +1669,27 @@ gen_cpu_unit (def)
DECL_UNIT (decl)->name = check_name (str_cpu_units [i], decl->pos);
DECL_UNIT (decl)->automaton_name = (char *) XSTR (def, 1);
DECL_UNIT (decl)->query_p = 0;
+ DECL_UNIT (decl)->min_occ_cycle_num = -1;
+ DECL_UNIT (decl)->in_set_p = 0;
VLA_PTR_ADD (decls, decl);
num_dfa_decls++;
}
}
-/* Process a DEFINE_QUERY_CPU_UNIT.
+/* Process a DEFINE_QUERY_CPU_UNIT.
This gives information about a unit contained in CPU. We fill a
struct unit_decl with information used later by `expand_automata'. */
void
-gen_query_cpu_unit (def)
- rtx def;
+gen_query_cpu_unit (rtx def)
{
decl_t decl;
char **str_cpu_units;
int vect_length;
int i;
- str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',', 0);
+ str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
+ FALSE);
if (str_cpu_units == NULL)
fatal ("invalid string `%s' in define_query_cpu_unit", XSTR (def, 0));
for (i = 0; i < vect_length; i++)
@@ -1661,14 +1705,13 @@ gen_query_cpu_unit (def)
}
}
-/* Process a DEFINE_BYPASS.
+/* Process a DEFINE_BYPASS.
This gives information about a unit contained in the CPU. We fill
in a struct bypass_decl with information used later by
`expand_automata'. */
void
-gen_bypass (def)
- rtx def;
+gen_bypass (rtx def)
{
decl_t decl;
char **out_insns;
@@ -1677,10 +1720,10 @@ gen_bypass (def)
int in_length;
int i, j;
- out_insns = get_str_vect ((char *) XSTR (def, 1), &out_length, ',', 0);
+ out_insns = get_str_vect ((char *) XSTR (def, 1), &out_length, ',', FALSE);
if (out_insns == NULL)
fatal ("invalid string `%s' in define_bypass", XSTR (def, 1));
- in_insns = get_str_vect ((char *) XSTR (def, 2), &in_length, ',', 0);
+ in_insns = get_str_vect ((char *) XSTR (def, 2), &in_length, ',', FALSE);
if (in_insns == NULL)
fatal ("invalid string `%s' in define_bypass", XSTR (def, 2));
for (i = 0; i < out_length; i++)
@@ -1698,14 +1741,13 @@ gen_bypass (def)
}
}
-/* Process an EXCLUSION_SET.
+/* Process an EXCLUSION_SET.
This gives information about a cpu unit conflicts. We fill a
- struct unit_rel_decl (excl) with information used later by
+ struct excl_rel_decl (excl) with information used later by
`expand_automata'. */
void
-gen_excl_set (def)
- rtx def;
+gen_excl_set (rtx def)
{
decl_t decl;
char **first_str_cpu_units;
@@ -1715,18 +1757,18 @@ gen_excl_set (def)
int i;
first_str_cpu_units
- = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', 0);
+ = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', FALSE);
if (first_str_cpu_units == NULL)
fatal ("invalid first string `%s' in exclusion_set", XSTR (def, 0));
second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
- 0);
+ FALSE);
if (second_str_cpu_units == NULL)
fatal ("invalid second string `%s' in exclusion_set", XSTR (def, 1));
length += first_vect_length;
decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
decl->mode = dm_excl;
decl->pos = 0;
- DECL_EXCL (decl)->names_num = length;
+ DECL_EXCL (decl)->all_names_num = length;
DECL_EXCL (decl)->first_list_length = first_vect_length;
for (i = 0; i < length; i++)
if (i < first_vect_length)
@@ -1738,101 +1780,134 @@ gen_excl_set (def)
num_dfa_decls++;
}
-/* Process a PRESENCE_SET.
+/* Process a PRESENCE_SET, a FINAL_PRESENCE_SET, an ABSENCE_SET,
+ FINAL_ABSENCE_SET (it is depended on PRESENCE_P and FINAL_P).
This gives information about a cpu unit reservation requirements.
- We fill a struct unit_rel_decl (presence) with information used
- later by `expand_automata'. */
-void
-gen_presence_set (def)
- rtx def;
+ We fill a struct unit_pattern_rel_decl with information used later
+ by `expand_automata'. */
+static void
+gen_presence_absence_set (rtx def, int presence_p, int final_p)
{
decl_t decl;
- char **first_str_cpu_units;
- char **second_str_cpu_units;
- int first_vect_length;
+ char **str_cpu_units;
+ char ***str_patterns;
+ int cpu_units_length;
int length;
+ int patterns_length;
int i;
- first_str_cpu_units
- = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', 0);
- if (first_str_cpu_units == NULL)
- fatal ("invalid first string `%s' in presence_set", XSTR (def, 0));
- second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
- 0);
- if (second_str_cpu_units == NULL)
- fatal ("invalid second string `%s' in presence_set", XSTR (def, 1));
- length += first_vect_length;
- decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
- decl->mode = dm_presence;
+ str_cpu_units = get_str_vect ((char *) XSTR (def, 0), &cpu_units_length, ',',
+ FALSE);
+ if (str_cpu_units == NULL)
+ fatal ((presence_p
+ ? (final_p
+ ? "invalid first string `%s' in final_presence_set"
+ : "invalid first string `%s' in presence_set")
+ : (final_p
+ ? "invalid first string `%s' in final_absence_set"
+ : "invalid first string `%s' in absence_set")),
+ XSTR (def, 0));
+ str_patterns = (char ***) get_str_vect ((char *) XSTR (def, 1),
+ &patterns_length, ',', FALSE);
+ if (str_patterns == NULL)
+ fatal ((presence_p
+ ? (final_p
+ ? "invalid second string `%s' in final_presence_set"
+ : "invalid second string `%s' in presence_set")
+ : (final_p
+ ? "invalid second string `%s' in final_absence_set"
+ : "invalid second string `%s' in absence_set")), XSTR (def, 1));
+ for (i = 0; i < patterns_length; i++)
+ {
+ str_patterns [i] = get_str_vect ((char *) str_patterns [i], &length, ' ',
+ FALSE);
+ if (str_patterns [i] == NULL)
+ abort ();
+ }
+ decl = create_node (sizeof (struct decl));
decl->pos = 0;
- DECL_PRESENCE (decl)->names_num = length;
- DECL_PRESENCE (decl)->first_list_length = first_vect_length;
- for (i = 0; i < length; i++)
- if (i < first_vect_length)
- DECL_PRESENCE (decl)->names [i] = first_str_cpu_units [i];
- else
- DECL_PRESENCE (decl)->names [i]
- = second_str_cpu_units [i - first_vect_length];
+ if (presence_p)
+ {
+ decl->mode = dm_presence;
+ DECL_PRESENCE (decl)->names_num = cpu_units_length;
+ DECL_PRESENCE (decl)->names = str_cpu_units;
+ DECL_PRESENCE (decl)->patterns = str_patterns;
+ DECL_PRESENCE (decl)->patterns_num = patterns_length;
+ DECL_PRESENCE (decl)->final_p = final_p;
+ }
+ else
+ {
+ decl->mode = dm_absence;
+ DECL_ABSENCE (decl)->names_num = cpu_units_length;
+ DECL_ABSENCE (decl)->names = str_cpu_units;
+ DECL_ABSENCE (decl)->patterns = str_patterns;
+ DECL_ABSENCE (decl)->patterns_num = patterns_length;
+ DECL_ABSENCE (decl)->final_p = final_p;
+ }
VLA_PTR_ADD (decls, decl);
num_dfa_decls++;
}
-/* Process an ABSENCE_SET.
+/* Process a PRESENCE_SET.
+
+ This gives information about a cpu unit reservation requirements.
+ We fill a struct unit_pattern_rel_decl (presence) with information
+ used later by `expand_automata'. */
+void
+gen_presence_set (rtx def)
+{
+ gen_presence_absence_set (def, TRUE, FALSE);
+}
+
+/* Process a FINAL_PRESENCE_SET.
This gives information about a cpu unit reservation requirements.
- We fill a struct unit_rel_decl (absence) with information used
- later by `expand_automata'. */
+ We fill a struct unit_pattern_rel_decl (presence) with information
+ used later by `expand_automata'. */
void
-gen_absence_set (def)
- rtx def;
+gen_final_presence_set (rtx def)
{
- decl_t decl;
- char **first_str_cpu_units;
- char **second_str_cpu_units;
- int first_vect_length;
- int length;
- int i;
+ gen_presence_absence_set (def, TRUE, TRUE);
+}
- first_str_cpu_units
- = get_str_vect ((char *) XSTR (def, 0), &first_vect_length, ',', 0);
- if (first_str_cpu_units == NULL)
- fatal ("invalid first string `%s' in absence_set", XSTR (def, 0));
- second_str_cpu_units = get_str_vect ((char *) XSTR (def, 1), &length, ',',
- 0);
- if (second_str_cpu_units == NULL)
- fatal ("invalid second string `%s' in absence_set", XSTR (def, 1));
- length += first_vect_length;
- decl = create_node (sizeof (struct decl) + (length - 1) * sizeof (char *));
- decl->mode = dm_absence;
- decl->pos = 0;
- DECL_ABSENCE (decl)->names_num = length;
- DECL_ABSENCE (decl)->first_list_length = first_vect_length;
- for (i = 0; i < length; i++)
- if (i < first_vect_length)
- DECL_ABSENCE (decl)->names [i] = first_str_cpu_units [i];
- else
- DECL_ABSENCE (decl)->names [i]
- = second_str_cpu_units [i - first_vect_length];
- VLA_PTR_ADD (decls, decl);
- num_dfa_decls++;
+/* Process an ABSENCE_SET.
+
+ This gives information about a cpu unit reservation requirements.
+ We fill a struct unit_pattern_rel_decl (absence) with information
+ used later by `expand_automata'. */
+void
+gen_absence_set (rtx def)
+{
+ gen_presence_absence_set (def, FALSE, FALSE);
}
-/* Process a DEFINE_AUTOMATON.
+/* Process a FINAL_ABSENCE_SET.
+
+ This gives information about a cpu unit reservation requirements.
+ We fill a struct unit_pattern_rel_decl (absence) with information
+ used later by `expand_automata'. */
+void
+gen_final_absence_set (rtx def)
+{
+ gen_presence_absence_set (def, FALSE, TRUE);
+}
+
+/* Process a DEFINE_AUTOMATON.
This gives information about a finite state automaton used for
recognizing pipeline hazards. We fill a struct automaton_decl
with information used later by `expand_automata'. */
void
-gen_automaton (def)
- rtx def;
+gen_automaton (rtx def)
{
decl_t decl;
char **str_automata;
int vect_length;
int i;
- str_automata = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',', 0);
+ str_automata = get_str_vect ((char *) XSTR (def, 0), &vect_length, ',',
+ FALSE);
if (str_automata == NULL)
fatal ("invalid string `%s' in define_automaton", XSTR (def, 0));
for (i = 0; i < vect_length; i++)
@@ -1846,24 +1921,25 @@ gen_automaton (def)
}
}
-/* Process an AUTOMATA_OPTION.
+/* Process an AUTOMATA_OPTION.
This gives information how to generate finite state automaton used
for recognizing pipeline hazards. */
void
-gen_automata_option (def)
- rtx def;
+gen_automata_option (rtx def)
{
- if (strcmp ((char *) XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
+ if (strcmp (XSTR (def, 0), NO_MINIMIZATION_OPTION + 1) == 0)
no_minimization_flag = 1;
- else if (strcmp ((char *) XSTR (def, 0), TIME_OPTION + 1) == 0)
+ else if (strcmp (XSTR (def, 0), TIME_OPTION + 1) == 0)
time_flag = 1;
- else if (strcmp ((char *) XSTR (def, 0), V_OPTION + 1) == 0)
+ else if (strcmp (XSTR (def, 0), V_OPTION + 1) == 0)
v_flag = 1;
- else if (strcmp ((char *) XSTR (def, 0), W_OPTION + 1) == 0)
+ else if (strcmp (XSTR (def, 0), W_OPTION + 1) == 0)
w_flag = 1;
- else if (strcmp ((char *) XSTR (def, 0), NDFA_OPTION + 1) == 0)
+ else if (strcmp (XSTR (def, 0), NDFA_OPTION + 1) == 0)
ndfa_flag = 1;
+ else if (strcmp (XSTR (def, 0), PROGRESS_OPTION + 1) == 0)
+ progress_flag = 1;
else
fatal ("invalid option `%s' in automata_option", XSTR (def, 0));
}
@@ -1877,8 +1953,7 @@ static char *reserv_str;
/* Parse an element in STR. */
static regexp_t
-gen_regexp_el (str)
- char *str;
+gen_regexp_el (char *str)
{
regexp_t regexp;
int len;
@@ -1907,8 +1982,7 @@ gen_regexp_el (str)
/* Parse construction `repeat' in STR. */
static regexp_t
-gen_regexp_repeat (str)
- char *str;
+gen_regexp_repeat (char *str)
{
regexp_t regexp;
regexp_t repeat;
@@ -1916,7 +1990,7 @@ gen_regexp_repeat (str)
int els_num;
int i;
- repeat_vect = get_str_vect (str, &els_num, '*', 1);
+ repeat_vect = get_str_vect (str, &els_num, '*', TRUE);
if (repeat_vect == NULL)
fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
if (els_num > 1)
@@ -1941,15 +2015,14 @@ gen_regexp_repeat (str)
/* Parse reservation STR which possibly contains separator '+'. */
static regexp_t
-gen_regexp_allof (str)
- char *str;
+gen_regexp_allof (char *str)
{
regexp_t allof;
char **allof_vect;
int els_num;
int i;
- allof_vect = get_str_vect (str, &els_num, '+', 1);
+ allof_vect = get_str_vect (str, &els_num, '+', TRUE);
if (allof_vect == NULL)
fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
if (els_num > 1)
@@ -1968,15 +2041,14 @@ gen_regexp_allof (str)
/* Parse reservation STR which possibly contains separator '|'. */
static regexp_t
-gen_regexp_oneof (str)
- char *str;
+gen_regexp_oneof (char *str)
{
regexp_t oneof;
char **oneof_vect;
int els_num;
int i;
- oneof_vect = get_str_vect (str, &els_num, '|', 1);
+ oneof_vect = get_str_vect (str, &els_num, '|', TRUE);
if (oneof_vect == NULL)
fatal ("invalid `%s' in reservation `%s'", str, reserv_str);
if (els_num > 1)
@@ -1995,15 +2067,14 @@ gen_regexp_oneof (str)
/* Parse reservation STR which possibly contains separator ','. */
static regexp_t
-gen_regexp_sequence (str)
- char *str;
+gen_regexp_sequence (char *str)
{
regexp_t sequence;
char **sequence_vect;
int els_num;
int i;
- sequence_vect = get_str_vect (str, &els_num, ',', 1);
+ sequence_vect = get_str_vect (str, &els_num, ',', TRUE);
if (els_num > 1)
{
sequence = create_node (sizeof (struct regexp)
@@ -2021,8 +2092,7 @@ gen_regexp_sequence (str)
/* Parse construction reservation STR. */
static regexp_t
-gen_regexp (str)
- char *str;
+gen_regexp (char *str)
{
reserv_str = str;
return gen_regexp_sequence (str);;
@@ -2034,8 +2104,7 @@ gen_regexp (str)
in a struct reserv_decl with information used later by
`expand_automata'. */
void
-gen_reserv (def)
- rtx def;
+gen_reserv (rtx def)
{
decl_t decl;
@@ -2054,8 +2123,7 @@ gen_reserv (def)
insn. We fill a struct insn_reserv_decl with information used
later by `expand_automata'. */
void
-gen_insn_reserv (def)
- rtx def;
+gen_insn_reserv (rtx def)
{
decl_t decl;
@@ -2075,8 +2143,7 @@ gen_insn_reserv (def)
/* The function evaluates hash value (0..UINT_MAX) of string. */
static unsigned
-string_hash (string)
- const char *string;
+string_hash (const char *string)
{
unsigned result, i;
@@ -2089,15 +2156,14 @@ string_hash (string)
/* This page contains abstract data `table of automaton declarations'.
Elements of the table is nodes representing automaton declarations.
- Key of the table elements is name of given automaton. Rememeber
+ Key of the table elements is name of given automaton. Remember
that automaton names have own space. */
/* The function evaluates hash value of an automaton declaration. The
function is used by abstract data `hashtab'. The function returns
hash value (0..UINT_MAX) of given automaton declaration. */
static hashval_t
-automaton_decl_hash (automaton_decl)
- const void *automaton_decl;
+automaton_decl_hash (const void *automaton_decl)
{
const decl_t decl = (decl_t) automaton_decl;
@@ -2111,9 +2177,8 @@ automaton_decl_hash (automaton_decl)
function returns 1 if the declarations have the same key, 0
otherwise. */
static int
-automaton_decl_eq_p (automaton_decl_1, automaton_decl_2)
- const void* automaton_decl_1;
- const void* automaton_decl_2;
+automaton_decl_eq_p (const void* automaton_decl_1,
+ const void* automaton_decl_2)
{
const decl_t decl1 = (decl_t) automaton_decl_1;
const decl_t decl2 = (decl_t) automaton_decl_2;
@@ -2135,8 +2200,7 @@ static htab_t automaton_decl_table;
declaration node in the table with the same key as given automaton
declaration node. */
static decl_t
-insert_automaton_decl (automaton_decl)
- decl_t automaton_decl;
+insert_automaton_decl (decl_t automaton_decl)
{
void **entry_ptr;
@@ -2156,8 +2220,7 @@ static struct decl work_automaton_decl;
declaration. The function returns node found in the table, NULL if
such node does not exist in the table. */
static decl_t
-find_automaton_decl (name)
- char *name;
+find_automaton_decl (char *name)
{
void *entry;
@@ -2172,7 +2235,7 @@ find_automaton_decl (name)
declaration with given name. The function must be called only once
before any work with the automaton declaration table. */
static void
-initiate_automaton_decl_table ()
+initiate_automaton_decl_table (void)
{
work_automaton_decl.mode = dm_automaton;
automaton_decl_table = htab_create (10, automaton_decl_hash,
@@ -2183,7 +2246,7 @@ initiate_automaton_decl_table ()
function `initiate_automaton_decl_table' is possible immediately
after this function call. */
static void
-finish_automaton_decl_table ()
+finish_automaton_decl_table (void)
{
htab_delete (automaton_decl_table);
}
@@ -2193,15 +2256,14 @@ finish_automaton_decl_table ()
/* This page contains abstract data `table of insn declarations'.
Elements of the table is nodes representing insn declarations. Key
of the table elements is name of given insn (in corresponding
- define_insn_reservation). Rememeber that insn names have own
+ define_insn_reservation). Remember that insn names have own
space. */
/* The function evaluates hash value of an insn declaration. The
function is used by abstract data `hashtab'. The function returns
hash value (0..UINT_MAX) of given insn declaration. */
static hashval_t
-insn_decl_hash (insn_decl)
- const void *insn_decl;
+insn_decl_hash (const void *insn_decl)
{
const decl_t decl = (decl_t) insn_decl;
@@ -2214,9 +2276,7 @@ insn_decl_hash (insn_decl)
The function is used by abstract data `hashtab'. The function
returns 1 if declarations have the same key, 0 otherwise. */
static int
-insn_decl_eq_p (insn_decl_1, insn_decl_2)
- const void *insn_decl_1;
- const void *insn_decl_2;
+insn_decl_eq_p (const void *insn_decl_1, const void *insn_decl_2)
{
const decl_t decl1 = (decl_t) insn_decl_1;
const decl_t decl2 = (decl_t) insn_decl_2;
@@ -2239,8 +2299,7 @@ static htab_t insn_decl_table;
already in the table. The function returns insn declaration node
in the table with the same key as given insn declaration node. */
static decl_t
-insert_insn_decl (insn_decl)
- decl_t insn_decl;
+insert_insn_decl (decl_t insn_decl)
{
void **entry_ptr;
@@ -2260,8 +2319,7 @@ static struct decl work_insn_decl;
declaration. The function returns node found in the table, NULL if
such node does not exist in the table. */
static decl_t
-find_insn_decl (name)
- char *name;
+find_insn_decl (char *name)
{
void *entry;
@@ -2276,7 +2334,7 @@ find_insn_decl (name)
declaration with given name. The function must be called only once
before any work with the insn declaration table. */
static void
-initiate_insn_decl_table ()
+initiate_insn_decl_table (void)
{
work_insn_decl.mode = dm_insn_reserv;
insn_decl_table = htab_create (10, insn_decl_hash, insn_decl_eq_p,
@@ -2287,7 +2345,7 @@ initiate_insn_decl_table ()
function `initiate_insn_decl_table' is possible immediately after
this function call. */
static void
-finish_insn_decl_table ()
+finish_insn_decl_table (void)
{
htab_delete (insn_decl_table);
}
@@ -2303,8 +2361,7 @@ finish_insn_decl_table ()
is used by abstract data `hashtab'. The function returns hash
value (0..UINT_MAX) of given declaration. */
static hashval_t
-decl_hash (decl)
- const void *decl;
+decl_hash (const void *decl)
{
const decl_t d = (const decl_t) decl;
@@ -2319,9 +2376,7 @@ decl_hash (decl)
function is used by abstract data `hashtab'. The function
returns 1 if the declarations have the same key, 0 otherwise. */
static int
-decl_eq_p (decl_1, decl_2)
- const void *decl_1;
- const void *decl_2;
+decl_eq_p (const void *decl_1, const void *decl_2)
{
const decl_t d1 = (const decl_t) decl_1;
const decl_t d2 = (const decl_t) decl_2;
@@ -2347,8 +2402,7 @@ static htab_t decl_table;
same key as given declaration node. */
static decl_t
-insert_decl (decl)
- decl_t decl;
+insert_decl (decl_t decl)
{
void **entry_ptr;
@@ -2367,8 +2421,7 @@ static struct decl work_decl;
returns node found in the table, NULL if such node does not exist
in the table. */
static decl_t
-find_decl (name)
- char *name;
+find_decl (char *name)
{
void *entry;
@@ -2383,7 +2436,7 @@ find_decl (name)
The function must be called only once before any work with the
declaration table. */
static void
-initiate_decl_table ()
+initiate_decl_table (void)
{
work_decl.mode = dm_unit;
decl_table = htab_create (10, decl_hash, decl_eq_p, (htab_del) 0);
@@ -2393,7 +2446,7 @@ initiate_decl_table ()
`initiate_declaration_table' is possible immediately after this
function call. */
static void
-finish_decl_table ()
+finish_decl_table (void)
{
htab_delete (decl_table);
}
@@ -2405,10 +2458,7 @@ finish_decl_table ()
/* Checking NAMES in an exclusion clause vector and returning formed
unit_set_el_list. */
static unit_set_el_t
-process_excls (names, num, excl_pos)
- char **names;
- int num;
- pos_t excl_pos ATTRIBUTE_UNUSED;
+process_excls (char **names, int num, pos_t excl_pos ATTRIBUTE_UNUSED)
{
unit_set_el_t el_list;
unit_set_el_t last_el;
@@ -2446,10 +2496,8 @@ process_excls (names, num, excl_pos)
list of the each element from DEST_LIST. Checking situation "unit
excludes itself". */
static void
-add_excls (dest_list, source_list, excl_pos)
- unit_set_el_t dest_list;
- unit_set_el_t source_list;
- pos_t excl_pos ATTRIBUTE_UNUSED;
+add_excls (unit_set_el_t dest_list, unit_set_el_t source_list,
+ pos_t excl_pos ATTRIBUTE_UNUSED)
{
unit_set_el_t dst;
unit_set_el_t src;
@@ -2492,15 +2540,13 @@ add_excls (dest_list, source_list, excl_pos)
}
}
-/* Checking NAMES in a presence clause vector and returning formed
- unit_set_el_list. The function is called only after processing all
- exclusion sets. */
+/* Checking NAMES in presence/absence clause and returning the
+ formed unit_set_el_list. The function is called only after
+ processing all exclusion sets. */
static unit_set_el_t
-process_presence_absence (names, num, req_pos, presence_p)
- char **names;
- int num;
- pos_t req_pos ATTRIBUTE_UNUSED;
- int presence_p;
+process_presence_absence_names (char **names, int num,
+ pos_t req_pos ATTRIBUTE_UNUSED,
+ int presence_p, int final_p)
{
unit_set_el_t el_list;
unit_set_el_t last_el;
@@ -2515,12 +2561,20 @@ process_presence_absence (names, num, req_pos, presence_p)
decl_in_table = find_decl (names [i]);
if (decl_in_table == NULL)
error ((presence_p
- ? "unit `%s' in presence set is not declared"
- : "unit `%s' in absence set is not declared"), names [i]);
+ ? (final_p
+ ? "unit `%s' in final presence set is not declared"
+ : "unit `%s' in presence set is not declared")
+ : (final_p
+ ? "unit `%s' in final absence set is not declared"
+ : "unit `%s' in absence set is not declared")), names [i]);
else if (decl_in_table->mode != dm_unit)
error ((presence_p
- ? "`%s' in presence set is not unit"
- : "`%s' in absence set is not unit"), names [i]);
+ ? (final_p
+ ? "`%s' in final presence set is not unit"
+ : "`%s' in presence set is not unit")
+ : (final_p
+ ? "`%s' in final absence set is not unit"
+ : "`%s' in absence set is not unit")), names [i]);
else
{
new_el = create_node (sizeof (struct unit_set_el));
@@ -2538,122 +2592,202 @@ process_presence_absence (names, num, req_pos, presence_p)
return el_list;
}
-/* The function adds each element from SOURCE_LIST to presence (if
+/* Checking NAMES in patterns of a presence/absence clause and
+ returning the formed pattern_set_el_list. The function is called
+ only after processing all exclusion sets. */
+static pattern_set_el_t
+process_presence_absence_patterns (char ***patterns, int num,
+ pos_t req_pos ATTRIBUTE_UNUSED,
+ int presence_p, int final_p)
+{
+ pattern_set_el_t el_list;
+ pattern_set_el_t last_el;
+ pattern_set_el_t new_el;
+ decl_t decl_in_table;
+ int i, j;
+
+ el_list = NULL;
+ last_el = NULL;
+ for (i = 0; i < num; i++)
+ {
+ for (j = 0; patterns [i] [j] != NULL; j++)
+ ;
+ new_el = create_node (sizeof (struct pattern_set_el)
+ + sizeof (struct unit_decl *) * j);
+ new_el->unit_decls
+ = (struct unit_decl **) ((char *) new_el
+ + sizeof (struct pattern_set_el));
+ new_el->next_pattern_set_el = NULL;
+ if (last_el == NULL)
+ el_list = last_el = new_el;
+ else
+ {
+ last_el->next_pattern_set_el = new_el;
+ last_el = last_el->next_pattern_set_el;
+ }
+ new_el->units_num = 0;
+ for (j = 0; patterns [i] [j] != NULL; j++)
+ {
+ decl_in_table = find_decl (patterns [i] [j]);
+ if (decl_in_table == NULL)
+ error ((presence_p
+ ? (final_p
+ ? "unit `%s' in final presence set is not declared"
+ : "unit `%s' in presence set is not declared")
+ : (final_p
+ ? "unit `%s' in final absence set is not declared"
+ : "unit `%s' in absence set is not declared")),
+ patterns [i] [j]);
+ else if (decl_in_table->mode != dm_unit)
+ error ((presence_p
+ ? (final_p
+ ? "`%s' in final presence set is not unit"
+ : "`%s' in presence set is not unit")
+ : (final_p
+ ? "`%s' in final absence set is not unit"
+ : "`%s' in absence set is not unit")),
+ patterns [i] [j]);
+ else
+ {
+ new_el->unit_decls [new_el->units_num]
+ = DECL_UNIT (decl_in_table);
+ new_el->units_num++;
+ }
+ }
+ }
+ return el_list;
+}
+
+/* The function adds each element from PATTERN_LIST to presence (if
PRESENCE_P) or absence list of the each element from DEST_LIST.
- Checking situations "unit requires own presence", "unit requires
- own absence", and "unit excludes and requires presence of ...".
- Remember that we process absence sets only after all presence
- sets. */
-static void
-add_presence_absence (dest_list, source_list, req_pos, presence_p)
- unit_set_el_t dest_list;
- unit_set_el_t source_list;
- pos_t req_pos ATTRIBUTE_UNUSED;
- int presence_p;
+ Checking situations "unit requires own absence", and "unit excludes
+ and requires presence of ...", "unit requires absence and presence
+ of ...", "units in (final) presence set belong to different
+ automata", and "units in (final) absence set belong to different
+ automata". Remember that we process absence sets only after all
+ presence sets. */
+static void
+add_presence_absence (unit_set_el_t dest_list,
+ pattern_set_el_t pattern_list,
+ pos_t req_pos ATTRIBUTE_UNUSED,
+ int presence_p, int final_p)
{
unit_set_el_t dst;
- unit_set_el_t src;
- unit_set_el_t curr_el;
- unit_set_el_t prev_el;
- unit_set_el_t copy;
+ pattern_set_el_t pat;
+ struct unit_decl *unit;
+ unit_set_el_t curr_excl_el;
+ pattern_set_el_t curr_pat_el;
+ pattern_set_el_t prev_el;
+ pattern_set_el_t copy;
+ int i;
+ int no_error_flag;
for (dst = dest_list; dst != NULL; dst = dst->next_unit_set_el)
- for (src = source_list; src != NULL; src = src->next_unit_set_el)
+ for (pat = pattern_list; pat != NULL; pat = pat->next_pattern_set_el)
{
- if (dst->unit_decl == src->unit_decl)
- {
- error ((presence_p
- ? "unit `%s' requires own presence"
- : "unit `%s' requires own absence"), src->unit_decl->name);
- continue;
- }
- if (dst->unit_decl->automaton_name != NULL
- && src->unit_decl->automaton_name != NULL
- && strcmp (dst->unit_decl->automaton_name,
- src->unit_decl->automaton_name) != 0)
- {
- error ((presence_p
- ? "units `%s' and `%s' in presence set belong to different automata"
- : "units `%s' and `%s' in absence set belong to different automata"),
- src->unit_decl->name, dst->unit_decl->name);
- continue;
- }
- for (curr_el = (presence_p
- ? dst->unit_decl->presence_list
- : dst->unit_decl->absence_list), prev_el = NULL;
- curr_el != NULL;
- prev_el = curr_el, curr_el = curr_el->next_unit_set_el)
- if (curr_el->unit_decl == src->unit_decl)
- break;
- if (curr_el == NULL)
+ for (i = 0; i < pat->units_num; i++)
{
- /* Element not found - insert if there is no error. */
- int no_error_flag = 1;
-
+ unit = pat->unit_decls [i];
+ if (dst->unit_decl == unit && pat->units_num == 1 && !presence_p)
+ {
+ error ("unit `%s' requires own absence", unit->name);
+ continue;
+ }
+ if (dst->unit_decl->automaton_name != NULL
+ && unit->automaton_name != NULL
+ && strcmp (dst->unit_decl->automaton_name,
+ unit->automaton_name) != 0)
+ {
+ error ((presence_p
+ ? (final_p
+ ? "units `%s' and `%s' in final presence set belong to different automata"
+ : "units `%s' and `%s' in presence set belong to different automata")
+ : (final_p
+ ? "units `%s' and `%s' in final absence set belong to different automata"
+ : "units `%s' and `%s' in absence set belong to different automata")),
+ unit->name, dst->unit_decl->name);
+ continue;
+ }
+ no_error_flag = 1;
if (presence_p)
- for (curr_el = dst->unit_decl->excl_list;
- curr_el != NULL;
- curr_el = curr_el->next_unit_set_el)
+ for (curr_excl_el = dst->unit_decl->excl_list;
+ curr_excl_el != NULL;
+ curr_excl_el = curr_excl_el->next_unit_set_el)
{
- if (src->unit_decl == curr_el->unit_decl)
+ if (unit == curr_excl_el->unit_decl && pat->units_num == 1)
{
if (!w_flag)
{
- error
- ("unit `%s' excludes and requires presence of `%s'",
- dst->unit_decl->name, src->unit_decl->name);
+ error ("unit `%s' excludes and requires presence of `%s'",
+ dst->unit_decl->name, unit->name);
no_error_flag = 0;
}
else
warning
("unit `%s' excludes and requires presence of `%s'",
- dst->unit_decl->name, src->unit_decl->name);
+ dst->unit_decl->name, unit->name);
}
}
- else
- for (curr_el = dst->unit_decl->presence_list;
- curr_el != NULL;
- curr_el = curr_el->next_unit_set_el)
- {
- if (src->unit_decl == curr_el->unit_decl)
- {
- if (!w_flag)
- {
- error
- ("unit `%s' requires absence and presence of `%s'",
- dst->unit_decl->name, src->unit_decl->name);
- no_error_flag = 0;
- }
- else
- warning
+ else if (pat->units_num == 1)
+ for (curr_pat_el = dst->unit_decl->presence_list;
+ curr_pat_el != NULL;
+ curr_pat_el = curr_pat_el->next_pattern_set_el)
+ if (curr_pat_el->units_num == 1
+ && unit == curr_pat_el->unit_decls [0])
+ {
+ if (!w_flag)
+ {
+ error
("unit `%s' requires absence and presence of `%s'",
- dst->unit_decl->name, src->unit_decl->name);
- }
- }
+ dst->unit_decl->name, unit->name);
+ no_error_flag = 0;
+ }
+ else
+ warning
+ ("unit `%s' requires absence and presence of `%s'",
+ dst->unit_decl->name, unit->name);
+ }
if (no_error_flag)
{
- copy = copy_node (src, sizeof (*src));
- copy->next_unit_set_el = NULL;
+ for (prev_el = (presence_p
+ ? (final_p
+ ? dst->unit_decl->final_presence_list
+ : dst->unit_decl->final_presence_list)
+ : (final_p
+ ? dst->unit_decl->final_absence_list
+ : dst->unit_decl->absence_list));
+ prev_el != NULL && prev_el->next_pattern_set_el != NULL;
+ prev_el = prev_el->next_pattern_set_el)
+ ;
+ copy = copy_node (pat, sizeof (*pat));
+ copy->next_pattern_set_el = NULL;
if (prev_el == NULL)
{
if (presence_p)
- dst->unit_decl->presence_list = copy;
+ {
+ if (final_p)
+ dst->unit_decl->final_presence_list = copy;
+ else
+ dst->unit_decl->presence_list = copy;
+ }
+ else if (final_p)
+ dst->unit_decl->final_absence_list = copy;
else
dst->unit_decl->absence_list = copy;
}
else
- prev_el->next_unit_set_el = copy;
+ prev_el->next_pattern_set_el = copy;
}
- }
- }
+ }
+ }
}
+
/* The function searches for bypass with given IN_INSN_RESERV in given
BYPASS_LIST. */
static struct bypass_decl *
-find_bypass (bypass_list, in_insn_reserv)
- struct bypass_decl *bypass_list;
- struct insn_reserv_decl *in_insn_reserv;
+find_bypass (struct bypass_decl *bypass_list,
+ struct insn_reserv_decl *in_insn_reserv)
{
struct bypass_decl *bypass;
@@ -2666,7 +2800,7 @@ find_bypass (bypass_list, in_insn_reserv)
/* The function processes pipeline description declarations, checks
their correctness, and forms exclusion/presence/absence sets. */
static void
-process_decls ()
+process_decls (void)
{
decl_t decl;
decl_t automaton_decl;
@@ -2832,7 +2966,7 @@ process_decls ()
}
}
- /* Check exclusion set declarations and form exclussion sets. */
+ /* Check exclusion set declarations and form exclusion sets. */
for (i = 0; i < description->decls_num; i++)
{
decl = description->decls [i];
@@ -2840,14 +2974,14 @@ process_decls ()
{
unit_set_el_t unit_set_el_list;
unit_set_el_t unit_set_el_list_2;
-
+
unit_set_el_list
= process_excls (DECL_EXCL (decl)->names,
DECL_EXCL (decl)->first_list_length, decl->pos);
unit_set_el_list_2
= process_excls (&DECL_EXCL (decl)->names
[DECL_EXCL (decl)->first_list_length],
- DECL_EXCL (decl)->names_num
+ DECL_EXCL (decl)->all_names_num
- DECL_EXCL (decl)->first_list_length,
decl->pos);
add_excls (unit_set_el_list, unit_set_el_list_2, decl->pos);
@@ -2862,21 +2996,20 @@ process_decls ()
if (decl->mode == dm_presence)
{
unit_set_el_t unit_set_el_list;
- unit_set_el_t unit_set_el_list_2;
-
+ pattern_set_el_t pattern_set_el_list;
+
unit_set_el_list
- = process_presence_absence
- (DECL_PRESENCE (decl)->names,
- DECL_PRESENCE (decl)->first_list_length, decl->pos, 1);
- unit_set_el_list_2
- = process_presence_absence
- (&DECL_PRESENCE (decl)->names
- [DECL_PRESENCE (decl)->first_list_length],
- DECL_PRESENCE (decl)->names_num
- - DECL_PRESENCE (decl)->first_list_length,
- decl->pos, 1);
- add_presence_absence (unit_set_el_list, unit_set_el_list_2,
- decl->pos, 1);
+ = process_presence_absence_names
+ (DECL_PRESENCE (decl)->names, DECL_PRESENCE (decl)->names_num,
+ decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
+ pattern_set_el_list
+ = process_presence_absence_patterns
+ (DECL_PRESENCE (decl)->patterns,
+ DECL_PRESENCE (decl)->patterns_num,
+ decl->pos, TRUE, DECL_PRESENCE (decl)->final_p);
+ add_presence_absence (unit_set_el_list, pattern_set_el_list,
+ decl->pos, TRUE,
+ DECL_PRESENCE (decl)->final_p);
}
}
@@ -2887,21 +3020,20 @@ process_decls ()
if (decl->mode == dm_absence)
{
unit_set_el_t unit_set_el_list;
- unit_set_el_t unit_set_el_list_2;
-
+ pattern_set_el_t pattern_set_el_list;
+
unit_set_el_list
- = process_presence_absence
- (DECL_ABSENCE (decl)->names,
- DECL_ABSENCE (decl)->first_list_length, decl->pos, 0);
- unit_set_el_list_2
- = process_presence_absence
- (&DECL_ABSENCE (decl)->names
- [DECL_ABSENCE (decl)->first_list_length],
- DECL_ABSENCE (decl)->names_num
- - DECL_ABSENCE (decl)->first_list_length,
- decl->pos, 0);
- add_presence_absence (unit_set_el_list, unit_set_el_list_2,
- decl->pos, 0);
+ = process_presence_absence_names
+ (DECL_ABSENCE (decl)->names, DECL_ABSENCE (decl)->names_num,
+ decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
+ pattern_set_el_list
+ = process_presence_absence_patterns
+ (DECL_ABSENCE (decl)->patterns,
+ DECL_ABSENCE (decl)->patterns_num,
+ decl->pos, FALSE, DECL_ABSENCE (decl)->final_p);
+ add_presence_absence (unit_set_el_list, pattern_set_el_list,
+ decl->pos, FALSE,
+ DECL_ABSENCE (decl)->final_p);
}
}
}
@@ -2910,7 +3042,7 @@ process_decls ()
the automaton is not used, the function fixes error/warning. The
following function must be called only after `process_decls'. */
static void
-check_automaton_usage ()
+check_automaton_usage (void)
{
decl_t decl;
int i;
@@ -2936,13 +3068,12 @@ check_automaton_usage ()
Remember that reserv_regexp does not exist before the function
call. */
static regexp_t
-process_regexp (regexp)
- regexp_t regexp;
+process_regexp (regexp_t regexp)
{
decl_t decl_in_table;
regexp_t new_regexp;
int i;
-
+
if (regexp->mode == rm_unit)
{
decl_in_table = find_decl (REGEXP_UNIT (regexp)->name);
@@ -2992,7 +3123,7 @@ process_regexp (regexp)
define_insn_reservation with the aid of function
`process_regexp'. */
static void
-process_regexp_decls ()
+process_regexp_decls (void)
{
decl_t decl;
int i;
@@ -3014,7 +3145,7 @@ process_regexp_decls ()
following function must be called only after `process_decls',
`process_regexp_decls'. */
static void
-check_usage ()
+check_usage (void)
{
decl_t decl;
int i;
@@ -3047,9 +3178,7 @@ static int curr_loop_pass_num;
contains given decl or reservations in given regexp refers for
given decl. */
static int
-loop_in_regexp (regexp, start_decl)
- regexp_t regexp;
- decl_t start_decl;
+loop_in_regexp (regexp_t regexp, decl_t start_decl)
{
int i;
@@ -3108,7 +3237,7 @@ loop_in_regexp (regexp, start_decl)
/* The following function fixes errors "cycle in definition ...". The
function uses function `loop_in_regexp' for that. */
static void
-check_loops_in_regexps ()
+check_loops_in_regexps (void)
{
decl_t decl;
int i;
@@ -3123,7 +3252,7 @@ check_loops_in_regexps ()
{
decl = description->decls [i];
curr_loop_pass_num = i;
-
+
if (decl->mode == dm_reserv)
{
DECL_RESERV (decl)->loop_pass_num = curr_loop_pass_num;
@@ -3139,81 +3268,102 @@ check_loops_in_regexps ()
}
/* The function recursively processes IR of reservation and defines
- max and min cycle for reservation of unit and for result in the
- reservation. */
-static int
-process_regexp_cycles (regexp, start_cycle)
- regexp_t regexp;
- int start_cycle;
+ max and min cycle for reservation of unit. */
+static void
+process_regexp_cycles (regexp_t regexp, int max_start_cycle,
+ int min_start_cycle, int *max_finish_cycle,
+ int *min_finish_cycle)
{
int i;
if (regexp->mode == rm_unit)
{
- if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < start_cycle)
- REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = start_cycle;
- return start_cycle;
+ if (REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num < max_start_cycle)
+ REGEXP_UNIT (regexp)->unit_decl->max_occ_cycle_num = max_start_cycle;
+ if (REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num > min_start_cycle
+ || REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num == -1)
+ REGEXP_UNIT (regexp)->unit_decl->min_occ_cycle_num = min_start_cycle;
+ *max_finish_cycle = max_start_cycle;
+ *min_finish_cycle = min_start_cycle;
}
else if (regexp->mode == rm_reserv)
- return process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
- start_cycle);
+ process_regexp_cycles (REGEXP_RESERV (regexp)->reserv_decl->regexp,
+ max_start_cycle, min_start_cycle,
+ max_finish_cycle, min_finish_cycle);
else if (regexp->mode == rm_repeat)
{
for (i = 0; i < REGEXP_REPEAT (regexp)->repeat_num; i++)
- start_cycle = process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
- start_cycle) + 1;
- return start_cycle;
+ {
+ process_regexp_cycles (REGEXP_REPEAT (regexp)->regexp,
+ max_start_cycle, min_start_cycle,
+ max_finish_cycle, min_finish_cycle);
+ max_start_cycle = *max_finish_cycle + 1;
+ min_start_cycle = *min_finish_cycle + 1;
+ }
}
else if (regexp->mode == rm_sequence)
{
for (i = 0; i <REGEXP_SEQUENCE (regexp)->regexps_num; i++)
- start_cycle
- = process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
- start_cycle) + 1;
- return start_cycle;
+ {
+ process_regexp_cycles (REGEXP_SEQUENCE (regexp)->regexps [i],
+ max_start_cycle, min_start_cycle,
+ max_finish_cycle, min_finish_cycle);
+ max_start_cycle = *max_finish_cycle + 1;
+ min_start_cycle = *min_finish_cycle + 1;
+ }
}
else if (regexp->mode == rm_allof)
{
- int finish_cycle = 0;
- int cycle;
+ int max_cycle = 0;
+ int min_cycle = 0;
for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
{
- cycle = process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
- start_cycle);
- if (finish_cycle < cycle)
- finish_cycle = cycle;
+ process_regexp_cycles (REGEXP_ALLOF (regexp)->regexps [i],
+ max_start_cycle, min_start_cycle,
+ max_finish_cycle, min_finish_cycle);
+ if (max_cycle < *max_finish_cycle)
+ max_cycle = *max_finish_cycle;
+ if (i == 0 || min_cycle > *min_finish_cycle)
+ min_cycle = *min_finish_cycle;
}
- return finish_cycle;
+ *max_finish_cycle = max_cycle;
+ *min_finish_cycle = min_cycle;
}
else if (regexp->mode == rm_oneof)
{
- int finish_cycle = 0;
- int cycle;
+ int max_cycle = 0;
+ int min_cycle = 0;
for (i = 0; i < REGEXP_ONEOF (regexp)->regexps_num; i++)
{
- cycle = process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
- start_cycle);
- if (finish_cycle < cycle)
- finish_cycle = cycle;
+ process_regexp_cycles (REGEXP_ONEOF (regexp)->regexps [i],
+ max_start_cycle, min_start_cycle,
+ max_finish_cycle, min_finish_cycle);
+ if (max_cycle < *max_finish_cycle)
+ max_cycle = *max_finish_cycle;
+ if (i == 0 || min_cycle > *min_finish_cycle)
+ min_cycle = *min_finish_cycle;
}
- return finish_cycle;
+ *max_finish_cycle = max_cycle;
+ *min_finish_cycle = min_cycle;
}
else
{
if (regexp->mode != rm_nothing)
abort ();
- return start_cycle;
+ *max_finish_cycle = max_start_cycle;
+ *min_finish_cycle = min_start_cycle;
}
}
/* The following function is called only for correct program. The
function defines max reservation of insns in cycles. */
static void
-evaluate_max_reserv_cycles ()
+evaluate_max_reserv_cycles (void)
{
int max_insn_cycles_num;
+ int min_insn_cycles_num;
decl_t decl;
int i;
@@ -3223,8 +3373,8 @@ evaluate_max_reserv_cycles ()
decl = description->decls [i];
if (decl->mode == dm_insn_reserv)
{
- max_insn_cycles_num
- = process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0);
+ process_regexp_cycles (DECL_INSN_RESERV (decl)->regexp, 0, 0,
+ &max_insn_cycles_num, &min_insn_cycles_num);
if (description->max_insn_reserv_cycles < max_insn_cycles_num)
description->max_insn_reserv_cycles = max_insn_cycles_num;
}
@@ -3235,7 +3385,7 @@ evaluate_max_reserv_cycles ()
/* The following function calls functions for checking all
description. */
static void
-check_all_description ()
+check_all_description (void)
{
process_decls ();
check_automaton_usage ();
@@ -3255,7 +3405,7 @@ check_all_description ()
/* The following function creates ticker and makes it active. */
static ticker_t
-create_ticker ()
+create_ticker (void)
{
ticker_t ticker;
@@ -3266,8 +3416,7 @@ create_ticker ()
/* The following function switches off given ticker. */
static void
-ticker_off (ticker)
- ticker_t *ticker;
+ticker_off (ticker_t *ticker)
{
if (ticker->incremented_off_time == 0)
ticker->incremented_off_time = get_run_time () + 1;
@@ -3275,8 +3424,7 @@ ticker_off (ticker)
/* The following function switches on given ticker. */
static void
-ticker_on (ticker)
- ticker_t *ticker;
+ticker_on (ticker_t *ticker)
{
if (ticker->incremented_off_time != 0)
{
@@ -3289,8 +3437,7 @@ ticker_on (ticker)
/* The following function returns current time in milliseconds since
the moment when given ticker was created. */
static int
-active_time (ticker)
- ticker_t ticker;
+active_time (ticker_t ticker)
{
if (ticker.incremented_off_time != 0)
return ticker.incremented_off_time - 1 - ticker.modified_creation_time;
@@ -3315,9 +3462,7 @@ active_time (ticker)
*/
static void
-print_active_time (f, ticker)
- FILE *f;
- ticker_t ticker;
+print_active_time (FILE *f, ticker_t ticker)
{
int msecs;
@@ -3331,7 +3476,7 @@ print_active_time (f, ticker)
really being created. This value is defined on the base of
argument of option `-split'. If the variable has zero value the
number of automata is defined by the constructions `%automaton'.
- This case occures when option `-split' is absent or has zero
+ This case occurs when option `-split' is absent or has zero
argument. If constructions `define_automaton' is absent only one
automaton is created. */
static int automata_num;
@@ -3365,7 +3510,7 @@ static ticker_t all_time;
/* Pseudo insn decl which denotes advancing cycle. */
static decl_t advance_cycle_insn_decl;
static void
-add_advance_cycle_insn_decl ()
+add_advance_cycle_insn_decl (void)
{
advance_cycle_insn_decl = create_node (sizeof (struct decl));
advance_cycle_insn_decl->mode = dm_insn_reserv;
@@ -3381,7 +3526,7 @@ add_advance_cycle_insn_decl ()
}
-/* Abstract data `alternative states' which reperesents
+/* Abstract data `alternative states' which represents
nondeterministic nature of the description (see comments for
structures alt_state and state). */
@@ -3395,9 +3540,9 @@ static int allocated_alt_states_num = 0;
#endif
/* The following function returns free node alt_state. It may be new
- allocated node or node freed eralier. */
-static alt_state_t
-get_free_alt_state ()
+ allocated node or node freed earlier. */
+static alt_state_t
+get_free_alt_state (void)
{
alt_state_t result;
@@ -3421,8 +3566,7 @@ get_free_alt_state ()
/* The function frees node ALT_STATE. */
static void
-free_alt_state (alt_state)
- alt_state_t alt_state;
+free_alt_state (alt_state_t alt_state)
{
if (alt_state == NULL)
return;
@@ -3432,8 +3576,7 @@ free_alt_state (alt_state)
/* The function frees list started with node ALT_STATE_LIST. */
static void
-free_alt_states (alt_states_list)
- alt_state_t alt_states_list;
+free_alt_states (alt_state_t alt_states_list)
{
alt_state_t curr_alt_state;
alt_state_t next_alt_state;
@@ -3449,9 +3592,7 @@ free_alt_states (alt_states_list)
/* The function compares unique numbers of alt states. */
static int
-alt_state_cmp (alt_state_ptr_1, alt_state_ptr_2)
- const void *alt_state_ptr_1;
- const void *alt_state_ptr_2;
+alt_state_cmp (const void *alt_state_ptr_1, const void *alt_state_ptr_2)
{
if ((*(alt_state_t *) alt_state_ptr_1)->state->unique_num
== (*(alt_state_t *) alt_state_ptr_2)->state->unique_num)
@@ -3466,9 +3607,8 @@ alt_state_cmp (alt_state_ptr_1, alt_state_ptr_2)
/* The function sorts ALT_STATES_LIST and removes duplicated alt
states from the list. The comparison key is alt state unique
number. */
-static alt_state_t
-uniq_sort_alt_states (alt_states_list)
- alt_state_t alt_states_list;
+static alt_state_t
+uniq_sort_alt_states (alt_state_t alt_states_list)
{
alt_state_t curr_alt_state;
vla_ptr_t alt_states;
@@ -3514,9 +3654,7 @@ uniq_sort_alt_states (alt_states_list)
/* The function checks equality of alt state lists. Remember that the
lists must be already sorted by the previous function. */
static int
-alt_states_eq (alt_states_1, alt_states_2)
- alt_state_t alt_states_1;
- alt_state_t alt_states_2;
+alt_states_eq (alt_state_t alt_states_1, alt_state_t alt_states_2)
{
while (alt_states_1 != NULL && alt_states_2 != NULL
&& alt_state_cmp (&alt_states_1, &alt_states_2) == 0)
@@ -3529,14 +3667,14 @@ alt_states_eq (alt_states_1, alt_states_2)
/* Initialization of the abstract data. */
static void
-initiate_alt_states ()
+initiate_alt_states (void)
{
first_free_alt_state = NULL;
}
/* Finishing work with the abstract data. */
static void
-finish_alt_states ()
+finish_alt_states (void)
{
}
@@ -3551,6 +3689,9 @@ finish_alt_states ()
#define SET_BIT(bitstring, bitno) \
(((char *) (bitstring)) [(bitno) / CHAR_BIT] |= 1 << (bitno) % CHAR_BIT)
+#define CLEAR_BIT(bitstring, bitno) \
+ (((char *) (bitstring)) [(bitno) / CHAR_BIT] &= ~(1 << (bitno) % CHAR_BIT))
+
/* Test if bit number bitno in the bitstring is set. The macro is not
side effect proof. */
#define TEST_BIT(bitstring, bitno) \
@@ -3581,8 +3722,8 @@ static vla_ptr_t units_container;
/* The start address of the array. */
static unit_decl_t *units_array;
-/* Empty reservation of maximal length. */
-static reserv_sets_t empty_reserv;
+/* Temporary reservation of maximal length. */
+static reserv_sets_t temp_reserv;
/* The state table itself is represented by the following variable. */
static htab_t state_table;
@@ -3601,7 +3742,7 @@ static int allocated_states_num = 0;
/* Allocate new reservation set. */
static reserv_sets_t
-alloc_empty_reserv_sets ()
+alloc_empty_reserv_sets (void)
{
reserv_sets_t result;
@@ -3614,8 +3755,7 @@ alloc_empty_reserv_sets ()
/* Hash value of reservation set. */
static unsigned
-reserv_sets_hash_value (reservs)
- reserv_sets_t reservs;
+reserv_sets_hash_value (reserv_sets_t reservs)
{
set_el_t hash_value;
unsigned result;
@@ -3649,9 +3789,7 @@ reserv_sets_hash_value (reservs)
/* Comparison of given reservation sets. */
static int
-reserv_sets_cmp (reservs_1, reservs_2)
- reserv_sets_t reservs_1;
- reserv_sets_t reservs_2;
+reserv_sets_cmp (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
{
int reservs_num;
set_el_t *reserv_ptr_1;
@@ -3678,9 +3816,7 @@ reserv_sets_cmp (reservs_1, reservs_2)
/* The function checks equality of the reservation sets. */
static int
-reserv_sets_eq (reservs_1, reservs_2)
- reserv_sets_t reservs_1;
- reserv_sets_t reservs_2;
+reserv_sets_eq (reserv_sets_t reservs_1, reserv_sets_t reservs_2)
{
return reserv_sets_cmp (reservs_1, reservs_2) == 0;
}
@@ -3688,10 +3824,7 @@ reserv_sets_eq (reservs_1, reservs_2)
/* Set up in the reservation set that unit with UNIT_NUM is used on
CYCLE_NUM. */
static void
-set_unit_reserv (reservs, cycle_num, unit_num)
- reserv_sets_t reservs;
- int cycle_num;
- int unit_num;
+set_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
{
if (cycle_num >= max_cycles_num)
abort ();
@@ -3702,10 +3835,7 @@ set_unit_reserv (reservs, cycle_num, unit_num)
/* Set up in the reservation set RESERVS that unit with UNIT_NUM is
used on CYCLE_NUM. */
static int
-test_unit_reserv (reservs, cycle_num, unit_num)
- reserv_sets_t reservs;
- int cycle_num;
- int unit_num;
+test_unit_reserv (reserv_sets_t reservs, int cycle_num, int unit_num)
{
if (cycle_num >= max_cycles_num)
abort ();
@@ -3716,8 +3846,7 @@ test_unit_reserv (reservs, cycle_num, unit_num)
/* The function checks that the reservation set represents no one unit
reservation. */
static int
-it_is_empty_reserv_sets (operand)
- reserv_sets_t operand;
+it_is_empty_reserv_sets (reserv_sets_t operand)
{
set_el_t *reserv_ptr;
int reservs_num;
@@ -3736,15 +3865,13 @@ it_is_empty_reserv_sets (operand)
i.e. there is a unit reservation on a cycle in both reservation
sets. */
static int
-reserv_sets_are_intersected (operand_1, operand_2)
- reserv_sets_t operand_1;
- reserv_sets_t operand_2;
+reserv_sets_are_intersected (reserv_sets_t operand_1,
+ reserv_sets_t operand_2)
{
set_el_t *el_ptr_1;
set_el_t *el_ptr_2;
set_el_t *cycle_ptr_1;
set_el_t *cycle_ptr_2;
- int nonzero_p;
if (operand_1 == NULL || operand_2 == NULL)
abort ();
@@ -3753,6 +3880,7 @@ reserv_sets_are_intersected (operand_1, operand_2)
el_ptr_1++, el_ptr_2++)
if (*el_ptr_1 & *el_ptr_2)
return 1;
+ reserv_sets_or (temp_reserv, operand_1, operand_2);
for (cycle_ptr_1 = operand_1, cycle_ptr_2 = operand_2;
cycle_ptr_1 < operand_1 + els_in_reservs;
cycle_ptr_1 += els_in_cycle_reserv, cycle_ptr_2 += els_in_cycle_reserv)
@@ -3762,36 +3890,26 @@ reserv_sets_are_intersected (operand_1, operand_2)
el_ptr_1++, el_ptr_2++)
if (*el_ptr_1 & *el_ptr_2)
return 1;
- nonzero_p = 0;
- for (el_ptr_1 = cycle_ptr_1,
- el_ptr_2 = get_presence_absence_set (cycle_ptr_2, 1);
- el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
- el_ptr_1++, el_ptr_2++)
- if (*el_ptr_1 & *el_ptr_2)
- break;
- else if (*el_ptr_2 != 0)
- nonzero_p = 1;
- if (nonzero_p && el_ptr_1 >= cycle_ptr_1 + els_in_cycle_reserv)
+ if (!check_presence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
+ return 1;
+ if (!check_presence_pattern_sets (temp_reserv + (cycle_ptr_2
+ - operand_2),
+ cycle_ptr_2, TRUE))
+ return 1;
+ if (!check_absence_pattern_sets (cycle_ptr_1, cycle_ptr_2, FALSE))
+ return 1;
+ if (!check_absence_pattern_sets (temp_reserv + (cycle_ptr_2 - operand_2),
+ cycle_ptr_2, TRUE))
return 1;
- for (el_ptr_1 = cycle_ptr_1,
- el_ptr_2 = get_presence_absence_set (cycle_ptr_2, 0);
- el_ptr_1 < cycle_ptr_1 + els_in_cycle_reserv;
- el_ptr_1++, el_ptr_2++)
- /* It looks like code for exclusion but exclusion set is
- made as symmetric relation preliminary. */
- if (*el_ptr_1 & *el_ptr_2)
- return 1;
}
return 0;
}
/* The function sets up RESULT bits by bits of OPERAND shifted on one
cpu cycle. The remaining bits of OPERAND (representing the last
- cycle unit reservations) are not chenged. */
+ cycle unit reservations) are not changed. */
static void
-reserv_sets_shift (result, operand)
- reserv_sets_t result;
- reserv_sets_t operand;
+reserv_sets_shift (reserv_sets_t result, reserv_sets_t operand)
{
int i;
@@ -3803,10 +3921,8 @@ reserv_sets_shift (result, operand)
/* OR of the reservation sets. */
static void
-reserv_sets_or (result, operand_1, operand_2)
- reserv_sets_t result;
- reserv_sets_t operand_1;
- reserv_sets_t operand_2;
+reserv_sets_or (reserv_sets_t result, reserv_sets_t operand_1,
+ reserv_sets_t operand_2)
{
set_el_t *el_ptr_1;
set_el_t *el_ptr_2;
@@ -3822,10 +3938,8 @@ reserv_sets_or (result, operand_1, operand_2)
/* AND of the reservation sets. */
static void
-reserv_sets_and (result, operand_1, operand_2)
- reserv_sets_t result;
- reserv_sets_t operand_1;
- reserv_sets_t operand_2;
+reserv_sets_and (reserv_sets_t result, reserv_sets_t operand_1,
+ reserv_sets_t operand_2)
{
set_el_t *el_ptr_1;
set_el_t *el_ptr_2;
@@ -3843,11 +3957,8 @@ reserv_sets_and (result, operand_1, operand_2)
cycle START_CYCLE in the reservation set. The function uses repeat
construction if REPETITION_NUM > 1. */
static void
-output_cycle_reservs (f, reservs, start_cycle, repetition_num)
- FILE *f;
- reserv_sets_t reservs;
- int start_cycle;
- int repetition_num;
+output_cycle_reservs (FILE *f, reserv_sets_t reservs, int start_cycle,
+ int repetition_num)
{
int unit_num;
int reserved_units_num;
@@ -3877,7 +3988,7 @@ output_cycle_reservs (f, reservs, start_cycle, repetition_num)
fprintf (f, NOTHING_NAME);
if (repetition_num <= 0)
abort ();
- if (reserved_units_num > 1)
+ if (repetition_num != 1 && reserved_units_num > 1)
fprintf (f, ")");
if (repetition_num != 1)
fprintf (f, "*%d", repetition_num);
@@ -3886,9 +3997,7 @@ output_cycle_reservs (f, reservs, start_cycle, repetition_num)
/* The function outputs string representation of units reservation in
the reservation set. */
static void
-output_reserv_sets (f, reservs)
- FILE *f;
- reserv_sets_t reservs;
+output_reserv_sets (FILE *f, reserv_sets_t reservs)
{
int start_cycle = 0;
int cycle;
@@ -3925,12 +4034,10 @@ output_reserv_sets (f, reservs)
}
/* The following function returns free node state for AUTOMATON. It
- may be new allocated node or node freed eralier. The function also
+ may be new allocated node or node freed earlier. The function also
allocates reservation set if WITH_RESERVS has nonzero value. */
static state_t
-get_free_state (with_reservs, automaton)
- int with_reservs;
- automaton_t automaton;
+get_free_state (int with_reservs, automaton_t automaton)
{
state_t result;
@@ -3971,8 +4078,7 @@ get_free_state (with_reservs, automaton)
/* The function frees node STATE. */
static void
-free_state (state)
- state_t state;
+free_state (state_t state)
{
free_alt_states (state->component_states);
VLA_PTR_ADD (free_states, state);
@@ -3983,8 +4089,7 @@ free_state (state)
it is formed from hash values of the component deterministic
states. One more key is order number of state automaton. */
static hashval_t
-state_hash (state)
- const void *state;
+state_hash (const void *state)
{
unsigned int hash_value;
alt_state_t alt_state;
@@ -4009,9 +4114,7 @@ state_hash (state)
/* Return nonzero value if the states are the same. */
static int
-state_eq_p (state_1, state_2)
- const void *state_1;
- const void *state_2;
+state_eq_p (const void *state_1, const void *state_2)
{
alt_state_t alt_state_1;
alt_state_t alt_state_2;
@@ -4042,8 +4145,7 @@ state_eq_p (state_1, state_2)
/* Insert STATE into the state table. */
static state_t
-insert_state (state)
- state_t state;
+insert_state (state_t state)
{
void **entry_ptr;
@@ -4056,10 +4158,7 @@ insert_state (state)
/* Add reservation of unit with UNIT_NUM on cycle CYCLE_NUM to
deterministic STATE. */
static void
-set_state_reserv (state, cycle_num, unit_num)
- state_t state;
- int cycle_num;
- int unit_num;
+set_state_reserv (state_t state, int cycle_num, int unit_num)
{
set_unit_reserv (state->reservs, cycle_num, unit_num);
}
@@ -4067,9 +4166,7 @@ set_state_reserv (state, cycle_num, unit_num)
/* Return nonzero value if the deterministic states contains a
reservation of the same cpu unit on the same cpu cycle. */
static int
-intersected_state_reservs_p (state1, state2)
- state_t state1;
- state_t state2;
+intersected_state_reservs_p (state_t state1, state_t state2)
{
if (state1->automaton != state2->automaton)
abort ();
@@ -4077,12 +4174,10 @@ intersected_state_reservs_p (state1, state2)
}
/* Return deterministic state (inserted into the table) which
- representing the automaton state whic is union of reservations of
- deterministic states. */
+ representing the automaton state which is union of reservations of
+ the deterministic states masked by RESERVS. */
static state_t
-states_union (state1, state2)
- state_t state1;
- state_t state2;
+states_union (state_t state1, state_t state2, reserv_sets_t reservs)
{
state_t result;
state_t state_in_table;
@@ -4091,6 +4186,7 @@ states_union (state1, state2)
abort ();
result = get_free_state (1, state1->automaton);
reserv_sets_or (result->reservs, state1->reservs, state2->reservs);
+ reserv_sets_and (result->reservs, result->reservs, reservs);
state_in_table = insert_state (result);
if (result != state_in_table)
{
@@ -4102,16 +4198,16 @@ states_union (state1, state2)
/* Return deterministic state (inserted into the table) which
represent the automaton state is obtained from deterministic STATE
- by advancing cpu cycle. */
+ by advancing cpu cycle and masking by RESERVS. */
static state_t
-state_shift (state)
- state_t state;
+state_shift (state_t state, reserv_sets_t reservs)
{
state_t result;
state_t state_in_table;
result = get_free_state (1, state->automaton);
reserv_sets_shift (result->reservs, state->reservs);
+ reserv_sets_and (result->reservs, result->reservs, reservs);
state_in_table = insert_state (result);
if (result != state_in_table)
{
@@ -4123,7 +4219,7 @@ state_shift (state)
/* Initialization of the abstract data. */
static void
-initiate_states ()
+initiate_states (void)
{
decl_t decl;
int i;
@@ -4147,12 +4243,12 @@ initiate_states ()
initiate_alt_states ();
VLA_PTR_CREATE (free_states, 1500, "free states");
state_table = htab_create (1500, state_hash, state_eq_p, (htab_del) 0);
- empty_reserv = alloc_empty_reserv_sets ();
+ temp_reserv = alloc_empty_reserv_sets ();
}
-/* Finisging work with the abstract data. */
+/* Finishing work with the abstract data. */
static void
-finish_states ()
+finish_states (void)
{
VLA_PTR_DELETE (units_container);
htab_delete (state_table);
@@ -4175,8 +4271,7 @@ static int allocated_arcs_num = 0;
/* The function frees node ARC. */
static void
-free_arc (arc)
- arc_t arc;
+free_arc (arc_t arc)
{
arc->next_out_arc = first_free_arc;
first_free_arc = arc;
@@ -4184,9 +4279,7 @@ free_arc (arc)
/* The function removes and frees ARC staring from FROM_STATE. */
static void
-remove_arc (from_state, arc)
- state_t from_state;
- arc_t arc;
+remove_arc (state_t from_state, arc_t arc)
{
arc_t prev_arc;
arc_t curr_arc;
@@ -4210,10 +4303,7 @@ remove_arc (from_state, arc)
/* The functions returns arc with given characteristics (or NULL if
the arc does not exist). */
static arc_t
-find_arc (from_state, to_state, insn)
- state_t from_state;
- state_t to_state;
- ainsn_t insn;
+find_arc (state_t from_state, state_t to_state, ainsn_t insn)
{
arc_t arc;
@@ -4227,11 +4317,8 @@ find_arc (from_state, to_state, insn)
and with given STATE_ALTS. The function returns added arc (or
already existing arc). */
static arc_t
-add_arc (from_state, to_state, ainsn, state_alts)
- state_t from_state;
- state_t to_state;
- ainsn_t ainsn;
- int state_alts;
+add_arc (state_t from_state, state_t to_state, ainsn_t ainsn,
+ int state_alts)
{
arc_t new_arc;
@@ -4265,30 +4352,28 @@ add_arc (from_state, to_state, ainsn, state_alts)
/* The function returns the first arc starting from STATE. */
static arc_t
-first_out_arc (state)
- state_t state;
+first_out_arc (state_t state)
{
return state->first_out_arc;
}
/* The function returns next out arc after ARC. */
static arc_t
-next_out_arc (arc)
- arc_t arc;
+next_out_arc (arc_t arc)
{
return arc->next_out_arc;
}
/* Initialization of the abstract data. */
static void
-initiate_arcs ()
+initiate_arcs (void)
{
first_free_arc = NULL;
}
/* Finishing work with the abstract data. */
static void
-finish_arcs ()
+finish_arcs (void)
{
}
@@ -4307,8 +4392,8 @@ static htab_t automata_list_table;
/* The following function returns free automata list el. It may be
new allocated node or node freed earlier. */
-static automata_list_el_t
-get_free_automata_list_el ()
+static automata_list_el_t
+get_free_automata_list_el (void)
{
automata_list_el_t result;
@@ -4327,8 +4412,7 @@ get_free_automata_list_el ()
/* The function frees node AUTOMATA_LIST_EL. */
static void
-free_automata_list_el (automata_list_el)
- automata_list_el_t automata_list_el;
+free_automata_list_el (automata_list_el_t automata_list_el)
{
if (automata_list_el == NULL)
return;
@@ -4338,8 +4422,7 @@ free_automata_list_el (automata_list_el)
/* The function frees list AUTOMATA_LIST. */
static void
-free_automata_list (automata_list)
- automata_list_el_t automata_list;
+free_automata_list (automata_list_el_t automata_list)
{
automata_list_el_t curr_automata_list_el;
automata_list_el_t next_automata_list_el;
@@ -4355,8 +4438,7 @@ free_automata_list (automata_list)
/* Hash value of AUTOMATA_LIST. */
static hashval_t
-automata_list_hash (automata_list)
- const void *automata_list;
+automata_list_hash (const void *automata_list)
{
unsigned int hash_value;
automata_list_el_t curr_automata_list_el;
@@ -4373,9 +4455,7 @@ automata_list_hash (automata_list)
/* Return nonzero value if the automata_lists are the same. */
static int
-automata_list_eq_p (automata_list_1, automata_list_2)
- const void *automata_list_1;
- const void *automata_list_2;
+automata_list_eq_p (const void *automata_list_1, const void *automata_list_2)
{
automata_list_el_t automata_list_el_1;
automata_list_el_t automata_list_el_2;
@@ -4392,7 +4472,7 @@ automata_list_eq_p (automata_list_1, automata_list_2)
/* Initialization of the abstract data. */
static void
-initiate_automata_lists ()
+initiate_automata_lists (void)
{
first_free_automata_list_el = NULL;
automata_list_table = htab_create (1500, automata_list_hash,
@@ -4402,15 +4482,14 @@ initiate_automata_lists ()
/* The following function starts new automata list and makes it the
current one. */
static void
-automata_list_start ()
+automata_list_start (void)
{
current_automata_list = NULL;
}
/* The following function adds AUTOMATON to the current list. */
static void
-automata_list_add (automaton)
- automaton_t automaton;
+automata_list_add (automaton_t automaton)
{
automata_list_el_t el;
@@ -4423,7 +4502,7 @@ automata_list_add (automaton)
/* The following function finishes forming the current list, inserts
it into the table and returns it. */
static automata_list_el_t
-automata_list_finish ()
+automata_list_finish (void)
{
void **entry_ptr;
@@ -4441,7 +4520,7 @@ automata_list_finish ()
/* Finishing work with the abstract data. */
static void
-finish_automata_lists ()
+finish_automata_lists (void)
{
htab_delete (automata_list_table);
}
@@ -4463,7 +4542,7 @@ static reserv_sets_t *unit_excl_set_table;
/* The following function forms the array containing exclusion sets
for each unit. */
static void
-initiate_excl_sets ()
+initiate_excl_sets (void)
{
decl_t decl;
reserv_sets_t unit_excl_set;
@@ -4489,7 +4568,10 @@ initiate_excl_sets ()
for (el = DECL_UNIT (decl)->excl_list;
el != NULL;
el = el->next_unit_set_el)
- SET_BIT (unit_excl_set, el->unit_decl->unit_num);
+ {
+ SET_BIT (unit_excl_set, el->unit_decl->unit_num);
+ el->unit_decl->in_set_p = TRUE;
+ }
unit_excl_set_table [DECL_UNIT (decl)->unit_num] = unit_excl_set;
}
}
@@ -4498,8 +4580,7 @@ initiate_excl_sets ()
/* The function sets up and return EXCL_SET which is union of
exclusion sets for each unit in IN_SET. */
static reserv_sets_t
-get_excl_set (in_set)
- reserv_sets_t in_set;
+get_excl_set (reserv_sets_t in_set)
{
int excl_char_num;
int chars_num;
@@ -4528,39 +4609,64 @@ get_excl_set (in_set)
-/* The page contains abstract data for work with presence/absence sets
- (see presence_set/absence_set in file rtl.def). */
+/* The page contains abstract data for work with presence/absence
+ pattern sets (see presence_set/absence_set in file rtl.def). */
-/* The following variables refer to correspondingly a presence and an
- absence set returned by get_presence_absence_set. This is bit
- string of length equal to cpu units number. */
-static reserv_sets_t presence_set, absence_set;
+/* The following arrays contain correspondingly presence, final
+ presence, absence, and final absence patterns for each unit. */
+static pattern_reserv_t *unit_presence_set_table;
+static pattern_reserv_t *unit_final_presence_set_table;
+static pattern_reserv_t *unit_absence_set_table;
+static pattern_reserv_t *unit_final_absence_set_table;
+
+/* The following function forms list of reservation sets for given
+ PATTERN_LIST. */
+static pattern_reserv_t
+form_reserv_sets_list (pattern_set_el_t pattern_list)
+{
+ pattern_set_el_t el;
+ pattern_reserv_t first, curr, prev;
+ int i;
-/* The following arrays contain correspondingly presence and absence
- sets for each unit. */
-static reserv_sets_t *unit_presence_set_table, *unit_absence_set_table;
+ prev = first = NULL;
+ for (el = pattern_list; el != NULL; el = el->next_pattern_set_el)
+ {
+ curr = create_node (sizeof (struct pattern_reserv));
+ curr->reserv = alloc_empty_reserv_sets ();
+ curr->next_pattern_reserv = NULL;
+ for (i = 0; i < el->units_num; i++)
+ {
+ SET_BIT (curr->reserv, el->unit_decls [i]->unit_num);
+ el->unit_decls [i]->in_set_p = TRUE;
+ }
+ if (prev != NULL)
+ prev->next_pattern_reserv = curr;
+ else
+ first = curr;
+ prev = curr;
+ }
+ return first;
+}
-/* The following function forms the array containing presence and
- absence sets for each unit */
+ /* The following function forms the array containing presence and
+ absence pattern sets for each unit. */
static void
-initiate_presence_absence_sets ()
+initiate_presence_absence_pattern_sets (void)
{
decl_t decl;
- reserv_sets_t unit_set;
- unit_set_el_t el;
int i;
- obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
- presence_set = (reserv_sets_t) obstack_base (&irp);
+ obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
+ unit_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
obstack_finish (&irp);
- obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
- unit_presence_set_table = (reserv_sets_t *) obstack_base (&irp);
+ obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
+ unit_final_presence_set_table = (pattern_reserv_t *) obstack_base (&irp);
obstack_finish (&irp);
- obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
- absence_set = (reserv_sets_t) obstack_base (&irp);
+ obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
+ unit_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
obstack_finish (&irp);
- obstack_blank (&irp, description->units_num * sizeof (reserv_sets_t));
- unit_absence_set_table = (reserv_sets_t *) obstack_base (&irp);
+ obstack_blank (&irp, description->units_num * sizeof (pattern_reserv_t));
+ unit_final_absence_set_table = (pattern_reserv_t *) obstack_base (&irp);
obstack_finish (&irp);
/* Evaluate unit presence/absence sets. */
for (i = 0; i < description->decls_num; i++)
@@ -4568,65 +4674,107 @@ initiate_presence_absence_sets ()
decl = description->decls [i];
if (decl->mode == dm_unit)
{
- obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
- unit_set = (reserv_sets_t) obstack_base (&irp);
- obstack_finish (&irp);
- memset (unit_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
- for (el = DECL_UNIT (decl)->presence_list;
- el != NULL;
- el = el->next_unit_set_el)
- SET_BIT (unit_set, el->unit_decl->unit_num);
- unit_presence_set_table [DECL_UNIT (decl)->unit_num] = unit_set;
-
- obstack_blank (&irp, els_in_cycle_reserv * sizeof (set_el_t));
- unit_set = (reserv_sets_t) obstack_base (&irp);
- obstack_finish (&irp);
- memset (unit_set, 0, els_in_cycle_reserv * sizeof (set_el_t));
- for (el = DECL_UNIT (decl)->absence_list;
- el != NULL;
- el = el->next_unit_set_el)
- SET_BIT (unit_set, el->unit_decl->unit_num);
- unit_absence_set_table [DECL_UNIT (decl)->unit_num] = unit_set;
+ unit_presence_set_table [DECL_UNIT (decl)->unit_num]
+ = form_reserv_sets_list (DECL_UNIT (decl)->presence_list);
+ unit_final_presence_set_table [DECL_UNIT (decl)->unit_num]
+ = form_reserv_sets_list (DECL_UNIT (decl)->final_presence_list);
+ unit_absence_set_table [DECL_UNIT (decl)->unit_num]
+ = form_reserv_sets_list (DECL_UNIT (decl)->absence_list);
+ unit_final_absence_set_table [DECL_UNIT (decl)->unit_num]
+ = form_reserv_sets_list (DECL_UNIT (decl)->final_absence_list);
}
}
}
-/* The function sets up and return PRESENCE_SET (if PRESENCE_P) or
- ABSENCE_SET which is union of corresponding sets for each unit in
- IN_SET. */
-static reserv_sets_t
-get_presence_absence_set (in_set, presence_p)
- reserv_sets_t in_set;
- int presence_p;
+/* The function checks that CHECKED_SET satisfies all presence pattern
+ sets for units in ORIGIONAL_SET. The function returns TRUE if it
+ is ok. */
+static int
+check_presence_pattern_sets (reserv_sets_t checked_set,
+ reserv_sets_t origional_set,
+ int final_p)
{
int char_num;
int chars_num;
int i;
int start_unit_num;
int unit_num;
+ int presence_p;
+ pattern_reserv_t pat_reserv;
chars_num = els_in_cycle_reserv * sizeof (set_el_t);
- if (presence_p)
- memset (presence_set, 0, chars_num);
- else
- memset (absence_set, 0, chars_num);
for (char_num = 0; char_num < chars_num; char_num++)
- if (((unsigned char *) in_set) [char_num])
+ if (((unsigned char *) origional_set) [char_num])
for (i = CHAR_BIT - 1; i >= 0; i--)
- if ((((unsigned char *) in_set) [char_num] >> i) & 1)
+ if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
{
start_unit_num = char_num * CHAR_BIT + i;
if (start_unit_num >= description->units_num)
- return (presence_p ? presence_set : absence_set);
- for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
- if (presence_p)
- presence_set [unit_num]
- |= unit_presence_set_table [start_unit_num] [unit_num];
- else
- absence_set [unit_num]
- |= unit_absence_set_table [start_unit_num] [unit_num];
+ break;
+ if ((final_p
+ && unit_final_presence_set_table [start_unit_num] == NULL)
+ || (!final_p
+ && unit_presence_set_table [start_unit_num] == NULL))
+ continue;
+ presence_p = FALSE;
+ for (pat_reserv = (final_p
+ ? unit_final_presence_set_table [start_unit_num]
+ : unit_presence_set_table [start_unit_num]);
+ pat_reserv != NULL;
+ pat_reserv = pat_reserv->next_pattern_reserv)
+ {
+ for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
+ if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
+ != pat_reserv->reserv [unit_num])
+ break;
+ presence_p = presence_p || unit_num >= els_in_cycle_reserv;
+ }
+ if (!presence_p)
+ return FALSE;
}
- return (presence_p ? presence_set : absence_set);
+ return TRUE;
+}
+
+/* The function checks that CHECKED_SET satisfies all absence pattern
+ sets for units in ORIGIONAL_SET. The function returns TRUE if it
+ is ok. */
+static int
+check_absence_pattern_sets (reserv_sets_t checked_set,
+ reserv_sets_t origional_set,
+ int final_p)
+{
+ int char_num;
+ int chars_num;
+ int i;
+ int start_unit_num;
+ int unit_num;
+ pattern_reserv_t pat_reserv;
+
+ chars_num = els_in_cycle_reserv * sizeof (set_el_t);
+ for (char_num = 0; char_num < chars_num; char_num++)
+ if (((unsigned char *) origional_set) [char_num])
+ for (i = CHAR_BIT - 1; i >= 0; i--)
+ if ((((unsigned char *) origional_set) [char_num] >> i) & 1)
+ {
+ start_unit_num = char_num * CHAR_BIT + i;
+ if (start_unit_num >= description->units_num)
+ break;
+ for (pat_reserv = (final_p
+ ? unit_final_absence_set_table [start_unit_num]
+ : unit_absence_set_table [start_unit_num]);
+ pat_reserv != NULL;
+ pat_reserv = pat_reserv->next_pattern_reserv)
+ {
+ for (unit_num = 0; unit_num < els_in_cycle_reserv; unit_num++)
+ if ((checked_set [unit_num] & pat_reserv->reserv [unit_num])
+ != pat_reserv->reserv [unit_num]
+ && pat_reserv->reserv [unit_num])
+ break;
+ if (unit_num >= els_in_cycle_reserv)
+ return FALSE;
+ }
+ }
+ return TRUE;
}
@@ -4642,8 +4790,7 @@ get_presence_absence_set (in_set, presence_p)
defined by define_reservation by corresponding value during making
the copy. */
static regexp_t
-copy_insn_regexp (regexp)
- regexp_t regexp;
+copy_insn_regexp (regexp_t regexp)
{
regexp_t result;
int i;
@@ -4701,8 +4848,7 @@ static int regexp_transformed_p;
/* The function makes transformation
A*N -> A, A, ... */
static regexp_t
-transform_1 (regexp)
- regexp_t regexp;
+transform_1 (regexp_t regexp)
{
int i;
int repeat_num;
@@ -4733,8 +4879,7 @@ transform_1 (regexp)
...+(A+B+...)+C+... -> ...+A+B+...+C+...
...|(A|B|...)|C|... -> ...|A|B|...|C|... */
static regexp_t
-transform_2 (regexp)
- regexp_t regexp;
+transform_2 (regexp_t regexp)
{
if (regexp->mode == rm_sequence)
{
@@ -4878,8 +5023,7 @@ transform_2 (regexp)
...+(A,B,...)+C+... -> (...+A+C+...),B,...
...+(A,B,...)+(C,D,...) -> (A+C),(B+D),... */
static regexp_t
-transform_3 (regexp)
- regexp_t regexp;
+transform_3 (regexp_t regexp)
{
if (regexp->mode == rm_sequence)
{
@@ -4933,10 +5077,13 @@ transform_3 (regexp)
}
else if (regexp->mode == rm_allof)
{
- regexp_t oneof = NULL, seq;
- int oneof_index = 0, max_seq_length, allof_length;
+ regexp_t oneof = NULL;
+ regexp_t seq;
+ int oneof_index = 0;
+ int max_seq_length, allof_length;
regexp_t result;
- regexp_t allof = NULL, allof_op = NULL;
+ regexp_t allof = NULL;
+ regexp_t allof_op = NULL;
int i, j;
for (i = 0; i < REGEXP_ALLOF (regexp)->regexps_num; i++)
@@ -4990,7 +5137,8 @@ transform_3 (regexp)
if (max_seq_length < REGEXP_SEQUENCE (seq)->regexps_num)
max_seq_length = REGEXP_SEQUENCE (seq)->regexps_num;
}
- else if (REGEXP_ALLOF (regexp)->regexps [i]->mode != rm_unit)
+ else if (REGEXP_ALLOF (regexp)->regexps [i]->mode != rm_unit
+ && REGEXP_ALLOF (regexp)->regexps [i]->mode != rm_nothing)
{
max_seq_length = 0;
break;
@@ -5020,7 +5168,9 @@ transform_3 (regexp)
}
else if (i == 0
&& (REGEXP_ALLOF (regexp)->regexps [j]->mode
- == rm_unit))
+ == rm_unit
+ || (REGEXP_ALLOF (regexp)->regexps [j]->mode
+ == rm_nothing)))
{
allof_op = REGEXP_ALLOF (regexp)->regexps [j];
allof_length++;
@@ -5052,7 +5202,9 @@ transform_3 (regexp)
}
else if (i == 0
&& (REGEXP_ALLOF (regexp)->regexps [j]->mode
- == rm_unit))
+ == rm_unit
+ || (REGEXP_ALLOF (regexp)->regexps [j]->mode
+ == rm_nothing)))
{
allof_op = REGEXP_ALLOF (regexp)->regexps [j];
REGEXP_ALLOF (allof)->regexps [allof_length]
@@ -5071,9 +5223,7 @@ transform_3 (regexp)
/* The function traverses IR of reservation and applies transformations
implemented by FUNC. */
static regexp_t
-regexp_transform_func (regexp, func)
- regexp_t regexp;
- regexp_t (*func) PARAMS ((regexp_t regexp));
+regexp_transform_func (regexp_t regexp, regexp_t (*func) (regexp_t regexp))
{
int i;
@@ -5100,10 +5250,9 @@ regexp_transform_func (regexp, func)
/* The function applies all transformations for IR representation of
reservation REGEXP. */
static regexp_t
-transform_regexp (regexp)
- regexp_t regexp;
+transform_regexp (regexp_t regexp)
{
- regexp = regexp_transform_func (regexp, transform_1);
+ regexp = regexp_transform_func (regexp, transform_1);
do
{
regexp_transformed_p = 0;
@@ -5114,18 +5263,18 @@ transform_regexp (regexp)
return regexp;
}
-/* The function applys all transformations for reservations of all
+/* The function applies all transformations for reservations of all
insn declarations. */
static void
-transform_insn_regexps ()
+transform_insn_regexps (void)
{
decl_t decl;
int i;
transform_time = create_ticker ();
add_advance_cycle_insn_decl ();
- fprintf (stderr, "Reservation transformation...");
- fflush (stderr);
+ if (progress_flag)
+ fprintf (stderr, "Reservation transformation...");
for (i = 0; i < description->decls_num; i++)
{
decl = description->decls [i];
@@ -5134,108 +5283,86 @@ transform_insn_regexps ()
= transform_regexp (copy_insn_regexp
(DECL_INSN_RESERV (decl)->regexp));
}
- fprintf (stderr, "done\n");
+ if (progress_flag)
+ fprintf (stderr, "done\n");
ticker_off (&transform_time);
- fflush (stderr);
}
-/* The following variable is an array indexed by cycle. Each element
- contains cyclic list of units which should be in the same cycle. */
-static unit_decl_t *the_same_automaton_lists;
+/* The following variable value is TRUE if the first annotated message
+ about units to automata distribution has been output. */
+static int annotation_message_reported_p;
+
+/* The following structure describes usage of a unit in a reservation. */
+struct unit_usage
+{
+ unit_decl_t unit_decl;
+ /* The following forms a list of units used on the same cycle in the
+ same alternative. */
+ struct unit_usage *next;
+};
+
+/* Obstack for unit_usage structures. */
+static struct obstack unit_usages;
+
+/* VLA for representation of array of pointers to unit usage
+ structures. There is an element for each combination of
+ (alternative number, cycle). Unit usages on given cycle in
+ alternative with given number are referred through element with
+ index equals to the cycle * number of all alternatives in the regexp
+ + the alternative number. */
+static vla_ptr_t cycle_alt_unit_usages;
-/* The function processes all alternative reservations on CYCLE in
- given REGEXP to check the UNIT is not reserved on the all
- alternatives. If it is true, the unit should be in the same
- automaton with other analogous units reserved on CYCLE in given
- REGEXP. */
+/* The following function creates the structure unit_usage for UNIT on
+ CYCLE in REGEXP alternative with ALT_NUM. The structure is made
+ accessed through cycle_alt_unit_usages. */
static void
-process_unit_to_form_the_same_automaton_unit_lists (unit, regexp, cycle)
- regexp_t unit;
- regexp_t regexp;
- int cycle;
+store_alt_unit_usage (regexp_t regexp, regexp_t unit, int cycle,
+ int alt_num)
{
- int i, k;
- regexp_t seq, allof;
- unit_decl_t unit_decl, last;
+ size_t i, length, old_length;
+ unit_decl_t unit_decl;
+ struct unit_usage *unit_usage_ptr;
+ int index;
- if (regexp == NULL || regexp->mode != rm_oneof)
+ if (regexp == NULL || regexp->mode != rm_oneof
+ || alt_num >= REGEXP_ONEOF (regexp)->regexps_num)
abort ();
unit_decl = REGEXP_UNIT (unit)->unit_decl;
- for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
- {
- seq = REGEXP_ONEOF (regexp)->regexps [i];
- if (seq->mode == rm_sequence)
- {
- if (cycle >= REGEXP_SEQUENCE (seq)->regexps_num)
- break;
- allof = REGEXP_SEQUENCE (seq)->regexps [cycle];
- if (allof->mode == rm_allof)
- {
- for (k = 0; k < REGEXP_ALLOF (allof)->regexps_num; k++)
- if (REGEXP_ALLOF (allof)->regexps [k]->mode == rm_unit
- && (REGEXP_UNIT (REGEXP_ALLOF (allof)->regexps [k])
- ->unit_decl == unit_decl))
- break;
- if (k >= REGEXP_ALLOF (allof)->regexps_num)
- break;
- }
- else if (allof->mode == rm_unit
- && REGEXP_UNIT (allof)->unit_decl != unit_decl)
- break;
- }
- else if (cycle != 0)
- break;
- else if (seq->mode == rm_allof)
- {
- for (k = 0; k < REGEXP_ALLOF (seq)->regexps_num; k++)
- if (REGEXP_ALLOF (seq)->regexps [k]->mode == rm_unit
- && (REGEXP_UNIT (REGEXP_ALLOF (seq)->regexps [k])->unit_decl
- == unit_decl))
- break;
- if (k >= REGEXP_ALLOF (seq)->regexps_num)
- break;
- }
- else if (seq->mode == rm_unit
- && REGEXP_UNIT (seq)->unit_decl != unit_decl)
- break;
- }
- if (i >= 0)
+ old_length = VLA_PTR_LENGTH (cycle_alt_unit_usages);
+ length = (cycle + 1) * REGEXP_ONEOF (regexp)->regexps_num;
+ if (old_length < length)
{
- if (the_same_automaton_lists [cycle] == NULL)
- the_same_automaton_lists [cycle] = unit_decl;
- else
- {
- for (last = the_same_automaton_lists [cycle];;)
- {
- if (last == unit_decl)
- return;
- if (last->the_same_automaton_unit
- == the_same_automaton_lists [cycle])
- break;
- last = last->the_same_automaton_unit;
- }
- last->the_same_automaton_unit = unit_decl->the_same_automaton_unit;
- unit_decl->the_same_automaton_unit
- = the_same_automaton_lists [cycle];
- }
+ VLA_PTR_EXPAND (cycle_alt_unit_usages, length - old_length);
+ for (i = old_length; i < length; i++)
+ VLA_PTR (cycle_alt_unit_usages, i) = NULL;
}
+ obstack_blank (&unit_usages, sizeof (struct unit_usage));
+ unit_usage_ptr = (struct unit_usage *) obstack_base (&unit_usages);
+ obstack_finish (&unit_usages);
+ unit_usage_ptr->unit_decl = unit_decl;
+ index = cycle * REGEXP_ONEOF (regexp)->regexps_num + alt_num;
+ unit_usage_ptr->next = VLA_PTR (cycle_alt_unit_usages, index);
+ VLA_PTR (cycle_alt_unit_usages, index) = unit_usage_ptr;
+ unit_decl->last_distribution_check_cycle = -1; /* undefined */
}
-/* The function processes given REGEXP to find units which should be
- in the same automaton. */
+/* The function processes given REGEXP to find units with the wrong
+ distribution. */
static void
-form_the_same_automaton_unit_lists_from_regexp (regexp)
- regexp_t regexp;
+check_regexp_units_distribution (const char *insn_reserv_name,
+ regexp_t regexp)
{
- int i, j, k;
+ int i, j, k, cycle;
regexp_t seq, allof, unit;
+ struct unit_usage *unit_usage_ptr, *other_unit_usage_ptr;
if (regexp == NULL || regexp->mode != rm_oneof)
return;
- for (i = 0; i < description->max_insn_reserv_cycles; i++)
- the_same_automaton_lists [i] = NULL;
+ /* Store all unit usages in the regexp: */
+ obstack_init (&unit_usages);
+ VLA_PTR_CREATE (cycle_alt_unit_usages, 100, "unit usages on cycles");
for (i = REGEXP_ONEOF (regexp)->regexps_num - 1; i >= 0; i--)
{
seq = REGEXP_ONEOF (regexp)->regexps [i];
@@ -5248,14 +5375,12 @@ form_the_same_automaton_unit_lists_from_regexp (regexp)
{
unit = REGEXP_ALLOF (allof)->regexps [k];
if (unit->mode == rm_unit)
- process_unit_to_form_the_same_automaton_unit_lists
- (unit, regexp, j);
+ store_alt_unit_usage (regexp, unit, j, i);
else if (unit->mode != rm_nothing)
abort ();
}
else if (allof->mode == rm_unit)
- process_unit_to_form_the_same_automaton_unit_lists
- (allof, regexp, j);
+ store_alt_unit_usage (regexp, allof, j, i);
else if (allof->mode != rm_nothing)
abort ();
}
@@ -5264,78 +5389,81 @@ form_the_same_automaton_unit_lists_from_regexp (regexp)
{
unit = REGEXP_ALLOF (seq)->regexps [k];
if (unit->mode == rm_unit)
- process_unit_to_form_the_same_automaton_unit_lists
- (unit, regexp, 0);
+ store_alt_unit_usage (regexp, unit, 0, i);
else if (unit->mode != rm_nothing)
abort ();
}
else if (seq->mode == rm_unit)
- process_unit_to_form_the_same_automaton_unit_lists (seq, regexp, 0);
+ store_alt_unit_usage (regexp, seq, 0, i);
else if (seq->mode != rm_nothing)
abort ();
}
-}
-
-/* The function initializes data to search for units which should be
- in the same automaton and call function
- `form_the_same_automaton_unit_lists_from_regexp' for each insn
- reservation regexp. */
-static void
-form_the_same_automaton_unit_lists ()
-{
- decl_t decl;
- int i;
-
- the_same_automaton_lists
- = (unit_decl_t *) xmalloc (description->max_insn_reserv_cycles
- * sizeof (unit_decl_t));
- for (i = 0; i < description->decls_num; i++)
+ /* Check distribution: */
+ for (i = 0; i < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages); i++)
{
- decl = description->decls [i];
- if (decl->mode == dm_unit)
- {
- DECL_UNIT (decl)->the_same_automaton_message_reported_p = FALSE;
- DECL_UNIT (decl)->the_same_automaton_unit = DECL_UNIT (decl);
- }
- }
- for (i = 0; i < description->decls_num; i++)
- {
- decl = description->decls [i];
- if (decl->mode == dm_insn_reserv)
- form_the_same_automaton_unit_lists_from_regexp
- (DECL_INSN_RESERV (decl)->transformed_regexp);
+ cycle = i / REGEXP_ONEOF (regexp)->regexps_num;
+ for (unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, i);
+ unit_usage_ptr != NULL;
+ unit_usage_ptr = unit_usage_ptr->next)
+ if (cycle != unit_usage_ptr->unit_decl->last_distribution_check_cycle)
+ {
+ unit_usage_ptr->unit_decl->last_distribution_check_cycle = cycle;
+ for (k = cycle * REGEXP_ONEOF (regexp)->regexps_num;
+ k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
+ && k == cycle * REGEXP_ONEOF (regexp)->regexps_num;
+ k++)
+ {
+ for (other_unit_usage_ptr = VLA_PTR (cycle_alt_unit_usages, k);
+ other_unit_usage_ptr != NULL;
+ other_unit_usage_ptr = other_unit_usage_ptr->next)
+ if (unit_usage_ptr->unit_decl->automaton_decl
+ == other_unit_usage_ptr->unit_decl->automaton_decl)
+ break;
+ if (other_unit_usage_ptr == NULL
+ && VLA_PTR (cycle_alt_unit_usages, k) != NULL)
+ break;
+ }
+ if (k < (int) VLA_PTR_LENGTH (cycle_alt_unit_usages)
+ && k == cycle * REGEXP_ONEOF (regexp)->regexps_num)
+ {
+ if (!annotation_message_reported_p)
+ {
+ fprintf (stderr, "\n");
+ error ("The following units do not satisfy units-automata distribution rule");
+ error (" (A unit of given unit automaton should be on each reserv. altern.)");
+ annotation_message_reported_p = TRUE;
+ }
+ error ("Unit %s, reserv. %s, cycle %d",
+ unit_usage_ptr->unit_decl->name, insn_reserv_name,
+ cycle);
+ }
+ }
}
- free (the_same_automaton_lists);
+ VLA_PTR_DELETE (cycle_alt_unit_usages);
+ obstack_free (&unit_usages, NULL);
}
-/* The function finds units which should be in the same automaton and,
- if they are not, reports about it. */
+/* The function finds units which violates units to automata
+ distribution rule. If the units exist, report about them. */
static void
-check_unit_distributions_to_automata ()
+check_unit_distributions_to_automata (void)
{
decl_t decl;
- unit_decl_t start_unit_decl, unit_decl;
int i;
- form_the_same_automaton_unit_lists ();
+ if (progress_flag)
+ fprintf (stderr, "Check unit distributions to automata...");
+ annotation_message_reported_p = FALSE;
for (i = 0; i < description->decls_num; i++)
{
decl = description->decls [i];
- if (decl->mode == dm_unit)
- {
- start_unit_decl = DECL_UNIT (decl);
- if (!start_unit_decl->the_same_automaton_message_reported_p)
- for (unit_decl = start_unit_decl->the_same_automaton_unit;
- unit_decl != start_unit_decl;
- unit_decl = unit_decl->the_same_automaton_unit)
- if (start_unit_decl->automaton_decl != unit_decl->automaton_decl)
- {
- error ("Units `%s' and `%s' should be in the same automaton",
- start_unit_decl->name, unit_decl->name);
- unit_decl->the_same_automaton_message_reported_p = TRUE;
- }
- }
+ if (decl->mode == dm_insn_reserv)
+ check_regexp_units_distribution
+ (DECL_INSN_RESERV (decl)->name,
+ DECL_INSN_RESERV (decl)->transformed_regexp);
}
+ if (progress_flag)
+ fprintf (stderr, "done\n");
}
@@ -5349,15 +5477,13 @@ static state_t state_being_formed;
/* Current alt_state being formed. */
static alt_state_t alt_state_being_formed;
-
+
/* This recursive function processes `,' and units in reservation
REGEXP for forming alt_states of AUTOMATON. It is believed that
CURR_CYCLE is start cycle of all reservation REGEXP. */
static int
-process_seq_for_forming_states (regexp, automaton, curr_cycle)
- regexp_t regexp;
- automaton_t automaton;
- int curr_cycle;
+process_seq_for_forming_states (regexp_t regexp, automaton_t automaton,
+ int curr_cycle)
{
int i;
@@ -5405,9 +5531,8 @@ process_seq_for_forming_states (regexp, automaton, curr_cycle)
/* This recursive function finishes forming ALT_STATE of AUTOMATON and
inserts alt_state into the table. */
static void
-finish_forming_alt_state (alt_state, automaton)
- alt_state_t alt_state;
- automaton_t automaton ATTRIBUTE_UNUSED;
+finish_forming_alt_state (alt_state_t alt_state,
+ automaton_t automaton ATTRIBUTE_UNUSED)
{
state_t state_in_table;
state_t corresponding_state;
@@ -5429,10 +5554,8 @@ static ainsn_t curr_ainsn;
forming alt_states of AUTOMATON. List of the alt states should
have the same order as in the description. */
static void
-process_alts_for_forming_states (regexp, automaton, inside_oneof_p)
- regexp_t regexp;
- automaton_t automaton;
- int inside_oneof_p;
+process_alts_for_forming_states (regexp_t regexp, automaton_t automaton,
+ int inside_oneof_p)
{
int i;
@@ -5464,8 +5587,7 @@ process_alts_for_forming_states (regexp, automaton, inside_oneof_p)
/* Create nodes alt_state for all AUTOMATON insns. */
static void
-create_alt_states (automaton)
- automaton_t automaton;
+create_alt_states (automaton_t automaton)
{
struct insn_reserv_decl *reserv_decl;
@@ -5493,8 +5615,7 @@ create_alt_states (automaton)
/* The function forms list of ainsns of AUTOMATON with the same
reservation. */
static void
-form_ainsn_with_same_reservs (automaton)
- automaton_t automaton;
+form_ainsn_with_same_reservs (automaton_t automaton)
{
ainsn_t curr_ainsn;
size_t i;
@@ -5538,11 +5659,39 @@ form_ainsn_with_same_reservs (automaton)
VLA_PTR_DELETE (last_insns);
}
+/* Forming unit reservations which can affect creating the automaton
+ states achieved from a given state. It permits to build smaller
+ automata in many cases. We would have the same automata after
+ the minimization without such optimization, but the automaton
+ right after the building could be huge. So in other words, usage
+ of reservs_matter means some minimization during building the
+ automaton. */
+static reserv_sets_t
+form_reservs_matter (automaton_t automaton)
+{
+ int cycle, unit;
+ reserv_sets_t reservs_matter = alloc_empty_reserv_sets();
+
+ for (cycle = 0; cycle < max_cycles_num; cycle++)
+ for (unit = 0; unit < description->units_num; unit++)
+ if (units_array [unit]->automaton_decl
+ == automaton->corresponding_automaton_decl
+ && (cycle >= units_array [unit]->min_occ_cycle_num
+ /* We can not remove queried unit from reservations. */
+ || units_array [unit]->query_p
+ /* We can not remove units which are used
+ `exclusion_set', `presence_set',
+ `final_presence_set', `absence_set', and
+ `final_absence_set'. */
+ || units_array [unit]->in_set_p))
+ set_unit_reserv (reservs_matter, cycle, unit);
+ return reservs_matter;
+}
+
/* The following function creates all states of nondeterministic (if
NDFA_FLAG has nonzero value) or deterministic AUTOMATON. */
static void
-make_automaton (automaton)
- automaton_t automaton;
+make_automaton (automaton_t automaton)
{
ainsn_t ainsn;
struct insn_reserv_decl *insn_reserv_decl;
@@ -5553,6 +5702,8 @@ make_automaton (automaton)
ainsn_t advance_cycle_ainsn;
arc_t added_arc;
vla_ptr_t state_stack;
+ int states_n;
+ reserv_sets_t reservs_matter = form_reservs_matter (automaton);
VLA_PTR_CREATE (state_stack, 150, "state stack");
/* Create the start state (empty state). */
@@ -5560,6 +5711,7 @@ make_automaton (automaton)
automaton->start_state = start_state;
start_state->it_was_placed_in_stack_for_NDFA_forming = 1;
VLA_PTR_ADD (state_stack, start_state);
+ states_n = 1;
while (VLA_PTR_LENGTH (state_stack) != 0)
{
state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
@@ -5583,12 +5735,15 @@ make_automaton (automaton)
state2 = alt_state->state;
if (!intersected_state_reservs_p (state, state2))
{
- state2 = states_union (state, state2);
+ state2 = states_union (state, state2, reservs_matter);
if (!state2->it_was_placed_in_stack_for_NDFA_forming)
{
state2->it_was_placed_in_stack_for_NDFA_forming
= 1;
VLA_PTR_ADD (state_stack, state2);
+ states_n++;
+ if (progress_flag && states_n % 100 == 0)
+ fprintf (stderr, ".");
}
added_arc = add_arc (state, state2, ainsn, 1);
if (!ndfa_flag)
@@ -5612,11 +5767,14 @@ make_automaton (automaton)
advance_cycle_ainsn = ainsn;
}
/* Add transition to advance cycle. */
- state2 = state_shift (state);
+ state2 = state_shift (state, reservs_matter);
if (!state2->it_was_placed_in_stack_for_NDFA_forming)
{
state2->it_was_placed_in_stack_for_NDFA_forming = 1;
VLA_PTR_ADD (state_stack, state2);
+ states_n++;
+ if (progress_flag && states_n % 100 == 0)
+ fprintf (stderr, ".");
}
if (advance_cycle_ainsn == NULL)
abort ();
@@ -5627,8 +5785,7 @@ make_automaton (automaton)
/* Foms lists of all arcs of STATE marked by the same ainsn. */
static void
-form_arcs_marked_by_insn (state)
- state_t state;
+form_arcs_marked_by_insn (state_t state)
{
decl_t decl;
arc_t arc;
@@ -5653,15 +5810,13 @@ form_arcs_marked_by_insn (state)
/* The function creates composed state (see comments for IR) from
ORIGINAL_STATE and list of arcs ARCS_MARKED_BY_INSN marked by the
same insn. If the composed state is not in STATE_STACK yet, it is
- popped to STATE_STACK. */
-static void
-create_composed_state (original_state, arcs_marked_by_insn, state_stack)
- state_t original_state;
- arc_t arcs_marked_by_insn;
- vla_ptr_t *state_stack;
+ pushed into STATE_STACK. */
+static int
+create_composed_state (state_t original_state, arc_t arcs_marked_by_insn,
+ vla_ptr_t *state_stack)
{
state_t state;
- alt_state_t curr_alt_state;
+ alt_state_t alt_state, curr_alt_state;
alt_state_t new_alt_state;
arc_t curr_arc;
arc_t next_arc;
@@ -5669,9 +5824,10 @@ create_composed_state (original_state, arcs_marked_by_insn, state_stack)
state_t temp_state;
alt_state_t canonical_alt_states_list;
int alts_number;
+ int new_state_p = 0;
if (arcs_marked_by_insn == NULL)
- return;
+ return new_state_p;
if (arcs_marked_by_insn->next_arc_marked_by_insn == NULL)
state = arcs_marked_by_insn->to_state;
else
@@ -5684,14 +5840,25 @@ create_composed_state (original_state, arcs_marked_by_insn, state_stack)
for (curr_arc = arcs_marked_by_insn;
curr_arc != NULL;
curr_arc = curr_arc->next_arc_marked_by_insn)
- {
- new_alt_state = get_free_alt_state ();
- new_alt_state->next_alt_state = curr_alt_state;
- new_alt_state->state = curr_arc->to_state;
- if (curr_arc->to_state->component_states != NULL)
- abort ();
- curr_alt_state = new_alt_state;
- }
+ if (curr_arc->to_state->component_states == NULL)
+ {
+ new_alt_state = get_free_alt_state ();
+ new_alt_state->next_alt_state = curr_alt_state;
+ new_alt_state->state = curr_arc->to_state;
+ curr_alt_state = new_alt_state;
+ }
+ else
+ for (alt_state = curr_arc->to_state->component_states;
+ alt_state != NULL;
+ alt_state = alt_state->next_sorted_alt_state)
+ {
+ new_alt_state = get_free_alt_state ();
+ new_alt_state->next_alt_state = curr_alt_state;
+ new_alt_state->state = alt_state->state;
+ if (alt_state->state->component_states != NULL)
+ abort ();
+ curr_alt_state = new_alt_state;
+ }
/* There are not identical sets in the alt state list. */
canonical_alt_states_list = uniq_sort_alt_states (curr_alt_state);
if (canonical_alt_states_list->next_sorted_alt_state == NULL)
@@ -5715,6 +5882,7 @@ create_composed_state (original_state, arcs_marked_by_insn, state_stack)
{
if (state->it_was_placed_in_stack_for_DFA_forming)
abort ();
+ new_state_p = 1;
for (curr_alt_state = state->component_states;
curr_alt_state != NULL;
curr_alt_state = curr_alt_state->next_sorted_alt_state)
@@ -5741,25 +5909,27 @@ create_composed_state (original_state, arcs_marked_by_insn, state_stack)
state->it_was_placed_in_stack_for_DFA_forming = 1;
VLA_PTR_ADD (*state_stack, state);
}
+ return new_state_p;
}
-/* The function transformes nondeterminstic AUTOMATON into
+/* The function transforms nondeterministic AUTOMATON into
deterministic. */
static void
-NDFA_to_DFA (automaton)
- automaton_t automaton;
+NDFA_to_DFA (automaton_t automaton)
{
state_t start_state;
state_t state;
decl_t decl;
vla_ptr_t state_stack;
int i;
+ int states_n;
VLA_PTR_CREATE (state_stack, 150, "state stack");
/* Create the start state (empty state). */
start_state = automaton->start_state;
start_state->it_was_placed_in_stack_for_DFA_forming = 1;
VLA_PTR_ADD (state_stack, start_state);
+ states_n = 1;
while (VLA_PTR_LENGTH (state_stack) != 0)
{
state = VLA_PTR (state_stack, VLA_PTR_LENGTH (state_stack) - 1);
@@ -5768,10 +5938,15 @@ NDFA_to_DFA (automaton)
for (i = 0; i < description->decls_num; i++)
{
decl = description->decls [i];
- if (decl->mode == dm_insn_reserv)
- create_composed_state
- (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
- &state_stack);
+ if (decl->mode == dm_insn_reserv
+ && create_composed_state
+ (state, DECL_INSN_RESERV (decl)->arcs_marked_by_insn,
+ &state_stack))
+ {
+ states_n++;
+ if (progress_flag && states_n % 100 == 0)
+ fprintf (stderr, ".");
+ }
}
}
VLA_PTR_DELETE (state_stack);
@@ -5784,9 +5959,7 @@ static int curr_state_graph_pass_num;
/* This recursive function passes all states achieved from START_STATE
and applies APPLIED_FUNC to them. */
static void
-pass_state_graph (start_state, applied_func)
- state_t start_state;
- void (*applied_func) PARAMS ((state_t state));
+pass_state_graph (state_t start_state, void (*applied_func) (state_t state))
{
arc_t arc;
@@ -5803,9 +5976,7 @@ pass_state_graph (start_state, applied_func)
/* This recursive function passes all states of AUTOMATON and applies
APPLIED_FUNC to them. */
static void
-pass_states (automaton, applied_func)
- automaton_t automaton;
- void (*applied_func) PARAMS ((state_t state));
+pass_states (automaton_t automaton, void (*applied_func) (state_t state))
{
curr_state_graph_pass_num++;
pass_state_graph (automaton->start_state, applied_func);
@@ -5813,7 +5984,7 @@ pass_states (automaton, applied_func)
/* The function initializes code for passing of all states. */
static void
-initiate_pass_states ()
+initiate_pass_states (void)
{
curr_state_graph_pass_num = 0;
}
@@ -5825,8 +5996,7 @@ static vla_ptr_t all_achieved_states;
/* This function is called by function pass_states to add an achieved
STATE. */
static void
-add_achieved_state (state)
- state_t state;
+add_achieved_state (state_t state)
{
VLA_PTR_ADD (all_achieved_states, state);
}
@@ -5836,9 +6006,7 @@ add_achieved_state (state)
nonzero value) or by equiv_class_num_2 of the destination state.
The function returns number of out arcs of STATE. */
static int
-set_out_arc_insns_equiv_num (state, odd_iteration_flag)
- state_t state;
- int odd_iteration_flag;
+set_out_arc_insns_equiv_num (state_t state, int odd_iteration_flag)
{
int state_out_arcs_num;
arc_t arc;
@@ -5865,8 +6033,7 @@ set_out_arc_insns_equiv_num (state, odd_iteration_flag)
/* The function clears equivalence numbers and alt_states in all insns
which mark all out arcs of STATE. */
static void
-clear_arc_insns_equiv_num (state)
- state_t state;
+clear_arc_insns_equiv_num (state_t state)
{
arc_t arc;
@@ -5880,9 +6047,7 @@ clear_arc_insns_equiv_num (state)
/* The function copies pointers to equivalent states from vla FROM
into vla TO. */
static void
-copy_equiv_class (to, from)
- vla_ptr_t *to;
- const vla_ptr_t *from;
+copy_equiv_class (vla_ptr_t *to, const vla_ptr_t *from)
{
state_t *class_ptr;
@@ -5893,19 +6058,34 @@ copy_equiv_class (to, from)
VLA_PTR_ADD (*to, *class_ptr);
}
+/* The following function returns TRUE if STATE reserves the unit with
+ UNIT_NUM on the first cycle. */
+static int
+first_cycle_unit_presence (state_t state, int unit_num)
+{
+ int presence_p;
+
+ if (state->component_states == NULL)
+ presence_p = test_unit_reserv (state->reservs, 0, unit_num);
+ else
+ presence_p
+ = test_unit_reserv (state->component_states->state->reservs,
+ 0, unit_num);
+ return presence_p;
+}
+
/* The function returns nonzero value if STATE is not equivalent to
- another state from the same current partition on equivalence
- classes Another state has ORIGINAL_STATE_OUT_ARCS_NUM number of
+ ANOTHER_STATE from the same current partition on equivalence
+ classes. Another state has ANOTHER_STATE_OUT_ARCS_NUM number of
output arcs. Iteration of making equivalence partition is defined
by ODD_ITERATION_FLAG. */
static int
-state_is_differed (state, original_state_out_arcs_num, odd_iteration_flag)
- state_t state;
- int original_state_out_arcs_num;
- int odd_iteration_flag;
+state_is_differed (state_t state, state_t another_state,
+ int another_state_out_arcs_num, int odd_iteration_flag)
{
arc_t arc;
int state_out_arcs_num;
+ int i, presence1_p, presence2_p;
state_out_arcs_num = 0;
for (arc = first_out_arc (state); arc != NULL; arc = next_out_arc (arc))
@@ -5918,15 +6098,25 @@ state_is_differed (state, original_state_out_arcs_num, odd_iteration_flag)
|| (arc->insn->insn_reserv_decl->state_alts != arc->state_alts))
return 1;
}
- return state_out_arcs_num != original_state_out_arcs_num;
+ if (state_out_arcs_num != another_state_out_arcs_num)
+ return 1;
+ /* Now we are looking at the states with the point of view of query
+ units. */
+ for (i = 0; i < description->units_num; i++)
+ if (units_array [i]->query_p)
+ {
+ presence1_p = first_cycle_unit_presence (state, i);
+ presence2_p = first_cycle_unit_presence (another_state, i);
+ if ((presence1_p && !presence2_p) || (!presence1_p && presence2_p))
+ return 1;
+ }
+ return 0;
}
/* The function makes initial partition of STATES on equivalent
classes. */
static state_t
-init_equiv_class (states, states_num)
- state_t *states;
- int states_num;
+init_equiv_class (state_t *states, int states_num)
{
state_t *state_ptr;
state_t result_equiv_class;
@@ -5943,18 +6133,15 @@ init_equiv_class (states, states_num)
/* The function processes equivalence class given by its pointer
EQUIV_CLASS_PTR on odd iteration if ODD_ITERATION_FLAG. If there
- are not equvalent states, the function partitions the class
+ are not equivalent states, the function partitions the class
removing nonequivalent states and placing them in
*NEXT_ITERATION_CLASSES, increments *NEW_EQUIV_CLASS_NUM_PTR ans
assigns it to the state equivalence number. If the class has been
partitioned, the function returns nonzero value. */
static int
-partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
- next_iteration_classes, new_equiv_class_num_ptr)
- state_t *equiv_class_ptr;
- int odd_iteration_flag;
- vla_ptr_t *next_iteration_classes;
- int *new_equiv_class_num_ptr;
+partition_equiv_class (state_t *equiv_class_ptr, int odd_iteration_flag,
+ vla_ptr_t *next_iteration_classes,
+ int *new_equiv_class_num_ptr)
{
state_t new_equiv_class;
int partition_p;
@@ -5983,7 +6170,7 @@ partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
curr_state = next_state)
{
next_state = curr_state->next_equiv_class_state;
- if (state_is_differed (curr_state, out_arcs_num,
+ if (state_is_differed (curr_state, first_state, out_arcs_num,
odd_iteration_flag))
{
/* Remove curr state from the class equivalence. */
@@ -6012,9 +6199,7 @@ partition_equiv_class (equiv_class_ptr, odd_iteration_flag,
/* The function finds equivalent states of AUTOMATON. */
static void
-evaluate_equiv_classes (automaton, equiv_classes)
- automaton_t automaton;
- vla_ptr_t *equiv_classes;
+evaluate_equiv_classes (automaton_t automaton, vla_ptr_t *equiv_classes)
{
state_t new_equiv_class;
int new_equiv_class_num;
@@ -6023,7 +6208,7 @@ evaluate_equiv_classes (automaton, equiv_classes)
vla_ptr_t next_iteration_classes;
state_t *equiv_class_ptr;
state_t *state_ptr;
-
+
VLA_PTR_CREATE (all_achieved_states, 1500, "all achieved states");
pass_states (automaton, add_achieved_state);
new_equiv_class = init_equiv_class (VLA_PTR_BEGIN (all_achieved_states),
@@ -6060,16 +6245,14 @@ evaluate_equiv_classes (automaton, equiv_classes)
/* The function merges equivalent states of AUTOMATON. */
static void
-merge_states (automaton, equiv_classes)
- automaton_t automaton;
- vla_ptr_t *equiv_classes;
+merge_states (automaton_t automaton, vla_ptr_t *equiv_classes)
{
state_t *equiv_class_ptr;
state_t curr_state;
state_t new_state;
state_t first_class_state;
alt_state_t alt_states;
- alt_state_t new_alt_state;
+ alt_state_t alt_state, new_alt_state;
arc_t curr_arc;
arc_t next_arc;
@@ -6090,12 +6273,27 @@ merge_states (automaton, equiv_classes)
curr_state = curr_state->next_equiv_class_state)
{
curr_state->equiv_class_state = new_state;
- new_alt_state = get_free_alt_state ();
- new_alt_state->state = curr_state;
- new_alt_state->next_sorted_alt_state = alt_states;
- alt_states = new_alt_state;
+ if (curr_state->component_states == NULL)
+ {
+ new_alt_state = get_free_alt_state ();
+ new_alt_state->state = curr_state;
+ new_alt_state->next_alt_state = alt_states;
+ alt_states = new_alt_state;
+ }
+ else
+ for (alt_state = curr_state->component_states;
+ alt_state != NULL;
+ alt_state = alt_state->next_sorted_alt_state)
+ {
+ new_alt_state = get_free_alt_state ();
+ new_alt_state->state = alt_state->state;
+ new_alt_state->next_alt_state = alt_states;
+ alt_states = new_alt_state;
+ }
}
- new_state->component_states = alt_states;
+ /* Its is important that alt states were sorted before and
+ after merging to have the same querying results. */
+ new_state->component_states = uniq_sort_alt_states (alt_states);
}
else
(*equiv_class_ptr)->equiv_class_state = *equiv_class_ptr;
@@ -6144,8 +6342,7 @@ merge_states (automaton, equiv_classes)
/* The function sets up new_cycle_p for states if there is arc to the
state marked by advance_cycle_insn_decl. */
static void
-set_new_cycle_flags (state)
- state_t state;
+set_new_cycle_flags (state_t state)
{
arc_t arc;
@@ -6158,8 +6355,7 @@ set_new_cycle_flags (state)
/* The top level function for minimization of deterministic
AUTOMATON. */
static void
-minimize_DFA (automaton)
- automaton_t automaton;
+minimize_DFA (automaton_t automaton)
{
vla_ptr_t equiv_classes;
@@ -6178,8 +6374,7 @@ static int curr_counted_arcs_num;
/* The function is called by function `pass_states' to count states
and arcs of an automaton. */
static void
-incr_states_and_arcs_nums (state)
- state_t state;
+incr_states_and_arcs_nums (state_t state)
{
arc_t arc;
@@ -6190,10 +6385,8 @@ incr_states_and_arcs_nums (state)
/* The function counts states and arcs of AUTOMATON. */
static void
-count_states_and_arcs (automaton, states_num, arcs_num)
- automaton_t automaton;
- int *states_num;
- int *arcs_num;
+count_states_and_arcs (automaton_t automaton, int *states_num,
+ int *arcs_num)
{
curr_counted_states_num = 0;
curr_counted_arcs_num = 0;
@@ -6206,20 +6399,41 @@ count_states_and_arcs (automaton, states_num, arcs_num)
recognition after checking and simplifying IR of the
description. */
static void
-build_automaton (automaton)
- automaton_t automaton;
+build_automaton (automaton_t automaton)
{
int states_num;
int arcs_num;
ticker_on (&NDFA_time);
+ if (progress_flag)
+ {
+ if (automaton->corresponding_automaton_decl == NULL)
+ fprintf (stderr, "Create anonymous automaton");
+ else
+ fprintf (stderr, "Create automaton `%s'",
+ automaton->corresponding_automaton_decl->name);
+ fprintf (stderr, " (1 dot is 100 new states):");
+ }
make_automaton (automaton);
+ if (progress_flag)
+ fprintf (stderr, " done\n");
ticker_off (&NDFA_time);
count_states_and_arcs (automaton, &states_num, &arcs_num);
automaton->NDFA_states_num = states_num;
automaton->NDFA_arcs_num = arcs_num;
ticker_on (&NDFA_to_DFA_time);
+ if (progress_flag)
+ {
+ if (automaton->corresponding_automaton_decl == NULL)
+ fprintf (stderr, "Make anonymous DFA");
+ else
+ fprintf (stderr, "Make DFA `%s'",
+ automaton->corresponding_automaton_decl->name);
+ fprintf (stderr, " (1 dot is 100 new states):");
+ }
NDFA_to_DFA (automaton);
+ if (progress_flag)
+ fprintf (stderr, " done\n");
ticker_off (&NDFA_to_DFA_time);
count_states_and_arcs (automaton, &states_num, &arcs_num);
automaton->DFA_states_num = states_num;
@@ -6227,7 +6441,17 @@ build_automaton (automaton)
if (!no_minimization_flag)
{
ticker_on (&minimize_time);
+ if (progress_flag)
+ {
+ if (automaton->corresponding_automaton_decl == NULL)
+ fprintf (stderr, "Minimize anonymous DFA...");
+ else
+ fprintf (stderr, "Minimize DFA `%s'...",
+ automaton->corresponding_automaton_decl->name);
+ }
minimize_DFA (automaton);
+ if (progress_flag)
+ fprintf (stderr, "done\n");
ticker_off (&minimize_time);
count_states_and_arcs (automaton, &states_num, &arcs_num);
automaton->minimal_DFA_states_num = states_num;
@@ -6246,8 +6470,7 @@ static int curr_state_order_num;
/* The function is called by function `pass_states' for enumerating
states. */
static void
-set_order_state_num (state)
- state_t state;
+set_order_state_num (state_t state)
{
state->order_state_num = curr_state_order_num;
curr_state_order_num++;
@@ -6255,8 +6478,7 @@ set_order_state_num (state)
/* The function enumerates all states of AUTOMATON. */
static void
-enumerate_states (automaton)
- automaton_t automaton;
+enumerate_states (automaton_t automaton)
{
curr_state_order_num = 0;
pass_states (automaton, set_order_state_num);
@@ -6271,9 +6493,8 @@ enumerate_states (automaton)
/* The function inserts AINSN into cyclic list
CYCLIC_EQUIV_CLASS_INSN_LIST of ainsns. */
static ainsn_t
-insert_ainsn_into_equiv_class (ainsn, cyclic_equiv_class_insn_list)
- ainsn_t ainsn;
- ainsn_t cyclic_equiv_class_insn_list;
+insert_ainsn_into_equiv_class (ainsn_t ainsn,
+ ainsn_t cyclic_equiv_class_insn_list)
{
if (cyclic_equiv_class_insn_list == NULL)
ainsn->next_equiv_class_insn = ainsn;
@@ -6289,8 +6510,7 @@ insert_ainsn_into_equiv_class (ainsn, cyclic_equiv_class_insn_list)
/* The function deletes equiv_class_insn into cyclic list of
equivalent ainsns. */
static void
-delete_ainsn_from_equiv_class (equiv_class_insn)
- ainsn_t equiv_class_insn;
+delete_ainsn_from_equiv_class (ainsn_t equiv_class_insn)
{
ainsn_t curr_equiv_class_insn;
ainsn_t prev_equiv_class_insn;
@@ -6309,9 +6529,7 @@ delete_ainsn_from_equiv_class (equiv_class_insn)
ainsns. INSN_ARCS_ARRAY is table: code of insn -> out arc of the
state. */
static void
-process_insn_equiv_class (ainsn, insn_arcs_array)
- ainsn_t ainsn;
- arc_t *insn_arcs_array;
+process_insn_equiv_class (ainsn_t ainsn, arc_t *insn_arcs_array)
{
ainsn_t next_insn;
ainsn_t curr_insn;
@@ -6342,8 +6560,7 @@ process_insn_equiv_class (ainsn, insn_arcs_array)
/* The function processes STATE in order to find equivalent ainsns. */
static void
-process_state_for_insn_equiv_partition (state)
- state_t state;
+process_state_for_insn_equiv_partition (state_t state)
{
arc_t arc;
arc_t *insn_arcs_array;
@@ -6365,8 +6582,7 @@ process_state_for_insn_equiv_partition (state)
/* The function searches for equivalent ainsns of AUTOMATON. */
static void
-set_insn_equiv_classes (automaton)
- automaton_t automaton;
+set_insn_equiv_classes (automaton_t automaton)
{
ainsn_t ainsn;
ainsn_t first_insn;
@@ -6428,7 +6644,7 @@ set_insn_equiv_classes (automaton)
/* The function estimate size of the single DFA used by PHR (pipeline
hazards recognizer). */
static double
-estimate_one_automaton_bound ()
+estimate_one_automaton_bound (void)
{
decl_t decl;
double one_automaton_estimation_bound;
@@ -6441,7 +6657,8 @@ estimate_one_automaton_bound ()
decl = description->decls [i];
if (decl->mode == dm_unit)
{
- root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num + 1.0)
+ root_value = exp (log (DECL_UNIT (decl)->max_occ_cycle_num
+ - DECL_UNIT (decl)->min_occ_cycle_num + 1.0)
/ automata_num);
if (MAX_FLOATING_POINT_VALUE_FOR_AUTOMATON_BOUND / root_value
> one_automaton_estimation_bound)
@@ -6451,12 +6668,11 @@ estimate_one_automaton_bound ()
return one_automaton_estimation_bound;
}
-/* The function compares unit declarations acoording to their maximal
+/* The function compares unit declarations according to their maximal
cycle in reservations. */
static int
-compare_max_occ_cycle_nums (unit_decl_1, unit_decl_2)
- const void *unit_decl_1;
- const void *unit_decl_2;
+compare_max_occ_cycle_nums (const void *unit_decl_1,
+ const void *unit_decl_2)
{
if ((DECL_UNIT (*(decl_t *) unit_decl_1)->max_occ_cycle_num)
< (DECL_UNIT (*(decl_t *) unit_decl_2)->max_occ_cycle_num))
@@ -6471,7 +6687,7 @@ compare_max_occ_cycle_nums (unit_decl_1, unit_decl_2)
/* The function makes heuristic assigning automata to units. Actually
efficacy of the algorithm has been checked yet??? */
static void
-units_to_automata_heuristic_distr ()
+units_to_automata_heuristic_distr (void)
{
double estimation_bound;
decl_t decl;
@@ -6528,7 +6744,7 @@ units_to_automata_heuristic_distr ()
insn is simply insn for given automaton which makes reservation
only of units of the automaton. */
static ainsn_t
-create_ainsns ()
+create_ainsns (void)
{
decl_t decl;
ainsn_t first_ainsn;
@@ -6560,11 +6776,11 @@ create_ainsns ()
/* The function assigns automata to units according to constructions
`define_automaton' in the description. */
static void
-units_to_automata_distr ()
+units_to_automata_distr (void)
{
decl_t decl;
int i;
-
+
for (i = 0; i < description->decls_num; i++)
{
decl = description->decls [i];
@@ -6586,7 +6802,7 @@ units_to_automata_distr ()
/* The function creates DFA(s) for fast pipeline hazards recognition
after checking and simplifying IR of the description. */
static void
-create_automata ()
+create_automata (void)
{
automaton_t curr_automaton;
automaton_t prev_automaton;
@@ -6659,19 +6875,23 @@ create_automata ()
curr_automaton != NULL;
curr_automaton = curr_automaton->next_automaton)
{
- if (curr_automaton->corresponding_automaton_decl == NULL)
- fprintf (stderr, "Create anonymous automaton ...");
- else
- fprintf (stderr, "Create automaton `%s'...",
- curr_automaton->corresponding_automaton_decl->name);
+ if (progress_flag)
+ {
+ if (curr_automaton->corresponding_automaton_decl == NULL)
+ fprintf (stderr, "Prepare anonymous automaton creation ... ");
+ else
+ fprintf (stderr, "Prepare automaton `%s' creation...",
+ curr_automaton->corresponding_automaton_decl->name);
+ }
create_alt_states (curr_automaton);
form_ainsn_with_same_reservs (curr_automaton);
+ if (progress_flag)
+ fprintf (stderr, "done\n");
build_automaton (curr_automaton);
enumerate_states (curr_automaton);
ticker_on (&equiv_time);
set_insn_equiv_classes (curr_automaton);
ticker_off (&equiv_time);
- fprintf (stderr, "done\n");
}
}
@@ -6685,11 +6905,10 @@ create_automata ()
/* This recursive function forms string representation of regexp
(without tailing '\0'). */
static void
-form_regexp (regexp)
- regexp_t regexp;
+form_regexp (regexp_t regexp)
{
int i;
-
+
if (regexp->mode == rm_unit || regexp->mode == rm_reserv)
{
const char *name = (regexp->mode == rm_unit
@@ -6758,8 +6977,7 @@ form_regexp (regexp)
/* The function returns string representation of REGEXP on IR
obstack. */
static const char *
-regexp_representation (regexp)
- regexp_t regexp;
+regexp_representation (regexp_t regexp)
{
form_regexp (regexp);
obstack_1grow (&irp, '\0');
@@ -6769,10 +6987,10 @@ regexp_representation (regexp)
/* The function frees memory allocated for last formed string
representation of regexp. */
static void
-finish_regexp_representation ()
+finish_regexp_representation (void)
{
int length = obstack_object_size (&irp);
-
+
obstack_blank_fast (&irp, -length);
}
@@ -6788,10 +7006,8 @@ finish_regexp_representation ()
approximation. */
static void
-output_range_type (f, min_range_value, max_range_value)
- FILE *f;
- long int min_range_value;
- long int max_range_value;
+output_range_type (FILE *f, long int min_range_value,
+ long int max_range_value)
{
if (min_range_value >= 0 && max_range_value <= 255)
fprintf (f, "unsigned char");
@@ -6816,19 +7032,18 @@ output_range_type (f, min_range_value, max_range_value)
`cycle advance' arcs. */
static int
-longest_path_length (state)
- state_t state;
+longest_path_length (state_t state)
{
arc_t arc;
int length, result;
-
+
if (state->longest_path_length == ON_THE_PATH)
/* We don't expect the path cycle here. Our graph may contain
only cycles with one state on the path not containing `cycle
advance' arcs -- see comment below. */
abort ();
else if (state->longest_path_length != UNDEFINED_LONGEST_PATH_LENGTH)
- /* We alreday visited the state. */
+ /* We already visited the state. */
return state->longest_path_length;
result = 0;
@@ -6855,8 +7070,7 @@ static int max_dfa_issue_rate;
from STATE to find MAX_DFA_ISSUE_RATE. */
static void
-process_state_longest_path_length (state)
- state_t state;
+process_state_longest_path_length (state_t state)
{
int value;
@@ -6874,7 +7088,7 @@ process_state_longest_path_length (state)
global variable and outputs its declaration. */
static void
-output_dfa_max_issue_rate ()
+output_dfa_max_issue_rate (void)
{
automaton_t automaton;
@@ -6892,9 +7106,7 @@ output_dfa_max_issue_rate ()
/* The function outputs all initialization values of VECT with length
vect_length. */
static void
-output_vect (vect, vect_length)
- vect_el_t *vect;
- int vect_length;
+output_vect (vect_el_t *vect, int vect_length)
{
int els_on_line;
@@ -6929,9 +7141,7 @@ output_vect (vect, vect_length)
/* The following is name of member which represents state of a DFA for
PHR. */
static void
-output_chip_member_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_chip_member_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "automaton_state_%d", automaton->automaton_order_num);
@@ -6943,9 +7153,7 @@ output_chip_member_name (f, automaton)
/* The following is name of temporary variable which stores state of a
DFA for PHR. */
static void
-output_temp_chip_member_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_temp_chip_member_name (FILE *f, automaton_t automaton)
{
fprintf (f, "_");
output_chip_member_name (f, automaton);
@@ -6958,9 +7166,7 @@ output_temp_chip_member_name (f, automaton)
/* Output name of translate vector for given automaton. */
static void
-output_translate_vect_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_translate_vect_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "translate_%d", automaton->automaton_order_num);
@@ -6970,9 +7176,7 @@ output_translate_vect_name (f, automaton)
/* Output name for simple transition table representation. */
static void
-output_trans_full_vect_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_trans_full_vect_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "transitions_%d", automaton->automaton_order_num);
@@ -6984,9 +7188,7 @@ output_trans_full_vect_name (f, automaton)
/* Output name of comb vector of the transition table for given
automaton. */
static void
-output_trans_comb_vect_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_trans_comb_vect_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "transitions_%d", automaton->automaton_order_num);
@@ -6998,9 +7200,7 @@ output_trans_comb_vect_name (f, automaton)
/* Output name of check vector of the transition table for given
automaton. */
static void
-output_trans_check_vect_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_trans_check_vect_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "check_%d", automaton->automaton_order_num);
@@ -7011,9 +7211,7 @@ output_trans_check_vect_name (f, automaton)
/* Output name of base vector of the transition table for given
automaton. */
static void
-output_trans_base_vect_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_trans_base_vect_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "base_%d", automaton->automaton_order_num);
@@ -7023,9 +7221,7 @@ output_trans_base_vect_name (f, automaton)
/* Output name for simple alternatives number representation. */
static void
-output_state_alts_full_vect_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_state_alts_full_vect_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "state_alts_%d", automaton->automaton_order_num);
@@ -7037,9 +7233,7 @@ output_state_alts_full_vect_name (f, automaton)
/* Output name of comb vector of the alternatives number table for given
automaton. */
static void
-output_state_alts_comb_vect_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_state_alts_comb_vect_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "state_alts_%d", automaton->automaton_order_num);
@@ -7051,9 +7245,7 @@ output_state_alts_comb_vect_name (f, automaton)
/* Output name of check vector of the alternatives number table for given
automaton. */
static void
-output_state_alts_check_vect_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_state_alts_check_vect_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "check_state_alts_%d", automaton->automaton_order_num);
@@ -7065,9 +7257,7 @@ output_state_alts_check_vect_name (f, automaton)
/* Output name of base vector of the alternatives number table for given
automaton. */
static void
-output_state_alts_base_vect_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_state_alts_base_vect_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "base_state_alts_%d", automaton->automaton_order_num);
@@ -7078,9 +7268,7 @@ output_state_alts_base_vect_name (f, automaton)
/* Output name of simple min issue delay table representation. */
static void
-output_min_issue_delay_vect_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_min_issue_delay_vect_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "min_issue_delay_%d", automaton->automaton_order_num);
@@ -7091,9 +7279,7 @@ output_min_issue_delay_vect_name (f, automaton)
/* Output name of deadlock vector for given automaton. */
static void
-output_dead_lock_vect_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_dead_lock_vect_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "dead_lock_%d", automaton->automaton_order_num);
@@ -7103,9 +7289,7 @@ output_dead_lock_vect_name (f, automaton)
/* Output name of reserved units table for AUTOMATON into file F. */
static void
-output_reserved_units_table_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_reserved_units_table_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "reserved_units_%d", automaton->automaton_order_num);
@@ -7165,6 +7349,8 @@ output_reserved_units_table_name (f, automaton)
#define CPU_UNIT_RESERVATION_P_FUNC_NAME "cpu_unit_reservation_p"
+#define DFA_CLEAN_INSN_CACHE_FUNC_NAME "dfa_clean_insn_cache"
+
#define DFA_START_FUNC_NAME "dfa_start"
#define DFA_FINISH_FUNC_NAME "dfa_finish"
@@ -7198,10 +7384,6 @@ output_reserved_units_table_name (f, automaton)
/* Name of result variable in some functions. */
#define RESULT_VARIABLE_NAME "res"
-/* Name of function (attribute) to translate insn into number of insn
- alternatives reservation. */
-#define INSN_ALTS_FUNC_NAME "insn_alts"
-
/* Name of function (attribute) to translate insn into internal insn
code. */
#define INTERNAL_DFA_INSN_CODE_FUNC_NAME "internal_dfa_insn_code"
@@ -7221,9 +7403,7 @@ output_reserved_units_table_name (f, automaton)
/* Output C type which is used for representation of codes of states
of AUTOMATON. */
static void
-output_state_member_type (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_state_member_type (FILE *f, automaton_t automaton)
{
output_range_type (f, 0, automaton->achieved_states_num);
}
@@ -7231,7 +7411,7 @@ output_state_member_type (f, automaton)
/* Output definition of the structure representing current DFA(s)
state(s). */
static void
-output_chip_definitions ()
+output_chip_definitions (void)
{
automaton_t automaton;
@@ -7255,10 +7435,9 @@ output_chip_definitions ()
/* The function outputs translate vector of internal insn code into
insn equivalence class number. The equivalence class number is
- used to access to table and vectors reprewsenting DFA(s). */
+ used to access to table and vectors representing DFA(s). */
static void
-output_translate_vect (automaton)
- automaton_t automaton;
+output_translate_vect (automaton_t automaton)
{
ainsn_t ainsn;
int insn_value;
@@ -7266,7 +7445,7 @@ output_translate_vect (automaton)
VLA_HWINT_CREATE (translate_vect, 250, "translate vector");
VLA_HWINT_EXPAND (translate_vect, description->insns_num);
- for (insn_value = 0; insn_value <= description->insns_num; insn_value++)
+ for (insn_value = 0; insn_value < description->insns_num; insn_value++)
/* Undefined value */
VLA_HWINT (translate_vect, insn_value) = automaton->insn_equiv_classes_num;
for (ainsn = automaton->ainsn_list; ainsn != NULL; ainsn = ainsn->next_ainsn)
@@ -7292,8 +7471,7 @@ static int undefined_vect_el_value;
/* The following function returns nonzero value if the best
representation of the table is comb vector. */
static int
-comb_vect_p (tab)
- state_ainsn_table_t tab;
+comb_vect_p (state_ainsn_table_t tab)
{
return (2 * VLA_HWINT_LENGTH (tab->full_vect)
> 5 * VLA_HWINT_LENGTH (tab->comb_vect));
@@ -7301,8 +7479,7 @@ comb_vect_p (tab)
/* The following function creates new table for AUTOMATON. */
static state_ainsn_table_t
-create_state_ainsn_table (automaton)
- automaton_t automaton;
+create_state_ainsn_table (automaton_t automaton)
{
state_ainsn_table_t tab;
int full_vect_length;
@@ -7330,16 +7507,11 @@ create_state_ainsn_table (automaton)
/* The following function outputs the best C representation of the
table TAB of given TABLE_NAME. */
static void
-output_state_ainsn_table (tab, table_name, output_full_vect_name_func,
- output_comb_vect_name_func,
- output_check_vect_name_func,
- output_base_vect_name_func)
- state_ainsn_table_t tab;
- char *table_name;
- void (*output_full_vect_name_func) PARAMS ((FILE *, automaton_t));
- void (*output_comb_vect_name_func) PARAMS ((FILE *, automaton_t));
- void (*output_check_vect_name_func) PARAMS ((FILE *, automaton_t));
- void (*output_base_vect_name_func) PARAMS ((FILE *, automaton_t));
+output_state_ainsn_table (state_ainsn_table_t tab, char *table_name,
+ void (*output_full_vect_name_func) (FILE *, automaton_t),
+ void (*output_comb_vect_name_func) (FILE *, automaton_t),
+ void (*output_check_vect_name_func) (FILE *, automaton_t),
+ void (*output_base_vect_name_func) (FILE *, automaton_t))
{
if (!comb_vect_p (tab))
{
@@ -7392,11 +7564,8 @@ output_state_ainsn_table (tab, table_name, output_full_vect_name_func,
elements pointed by VECT to table TAB as its line with number
VECT_NUM. */
static void
-add_vect (tab, vect_num, vect, vect_length)
- state_ainsn_table_t tab;
- int vect_num;
- vect_el_t *vect;
- int vect_length;
+add_vect (state_ainsn_table_t tab, int vect_num, vect_el_t *vect,
+ int vect_length)
{
int real_vect_length;
vect_el_t *comb_vect_start;
@@ -7481,6 +7650,10 @@ add_vect (tab, vect_num, vect, vect_length)
tab->min_comb_vect_el_value = vect [vect_index];
check_vect_start [comb_vect_index + vect_index] = vect_num;
}
+ if (tab->max_comb_vect_el_value < undefined_vect_el_value)
+ tab->max_comb_vect_el_value = undefined_vect_el_value;
+ if (tab->min_comb_vect_el_value > undefined_vect_el_value)
+ tab->min_comb_vect_el_value = undefined_vect_el_value;
if (tab->max_base_vect_el_value < comb_vect_index)
tab->max_base_vect_el_value = comb_vect_index;
if (tab->min_base_vect_el_value > comb_vect_index)
@@ -7490,8 +7663,7 @@ add_vect (tab, vect_num, vect, vect_length)
/* Return number of out arcs of STATE. */
static int
-out_state_arcs_num (state)
- state_t state;
+out_state_arcs_num (state_t state)
{
int result;
arc_t arc;
@@ -7509,9 +7681,8 @@ out_state_arcs_num (state)
/* Compare number of possible transitions from the states. */
static int
-compare_transition_els_num (state_ptr_1, state_ptr_2)
- const void *state_ptr_1;
- const void *state_ptr_2;
+compare_transition_els_num (const void *state_ptr_1,
+ const void *state_ptr_2)
{
int transition_els_num_1;
int transition_els_num_2;
@@ -7529,10 +7700,7 @@ compare_transition_els_num (state_ptr_1, state_ptr_2)
/* The function adds element EL_VALUE to vector VECT for a table state
x AINSN. */
static void
-add_vect_el (vect, ainsn, el_value)
- vla_hwint_t *vect;
- ainsn_t ainsn;
- int el_value;
+add_vect_el (vla_hwint_t *vect, ainsn_t ainsn, int el_value)
{
int equiv_class_num;
int vect_index;
@@ -7553,8 +7721,7 @@ static vla_ptr_t output_states_vect;
/* The function is called by function pass_states. The function adds
STATE to `output_states_vect'. */
static void
-add_states_vect_el (state)
- state_t state;
+add_states_vect_el (state_t state)
{
VLA_PTR_ADD (output_states_vect, state);
}
@@ -7562,8 +7729,7 @@ add_states_vect_el (state)
/* Form and output vectors (comb, check, base or full vector)
representing transition table of AUTOMATON. */
static void
-output_trans_table (automaton)
- automaton_t automaton;
+output_trans_table (automaton_t automaton)
{
state_t *state_ptr;
arc_t arc;
@@ -7611,8 +7777,7 @@ output_trans_table (automaton)
ainsn -> number of possible alternative reservations by the
ainsn. */
static void
-output_state_alts_table (automaton)
- automaton_t automaton;
+output_state_alts_table (automaton_t automaton)
{
state_t *state_ptr;
arc_t arc;
@@ -7659,15 +7824,12 @@ output_state_alts_table (automaton)
value for an ainsn and state. */
static int curr_state_pass_num;
-
/* This recursive function passes states to find minimal issue delay
value for AINSN. The state being visited is STATE. The function
returns minimal issue delay value for AINSN in STATE or -1 if we
enter into a loop. */
static int
-min_issue_delay_pass_states (state, ainsn)
- state_t state;
- ainsn_t ainsn;
+min_issue_delay_pass_states (state_t state, ainsn_t ainsn)
{
arc_t arc;
int min_insn_issue_delay, insn_issue_delay;
@@ -7709,9 +7871,7 @@ min_issue_delay_pass_states (state, ainsn)
The function can return negative value if we can not issue AINSN. We
will report about it later. */
static int
-min_issue_delay (state, ainsn)
- state_t state;
- ainsn_t ainsn;
+min_issue_delay (state_t state, ainsn_t ainsn)
{
curr_state_pass_num++;
state->min_insn_issue_delay = min_issue_delay_pass_states (state, ainsn);
@@ -7721,7 +7881,7 @@ min_issue_delay (state, ainsn)
/* The function initiates code for finding minimal issue delay values.
It should be called only once. */
static void
-initiate_min_issue_delay_pass_states ()
+initiate_min_issue_delay_pass_states (void)
{
curr_state_pass_num = 0;
}
@@ -7730,8 +7890,7 @@ initiate_min_issue_delay_pass_states ()
AUTOMATON. The table is state x ainsn -> minimal issue delay of
the ainsn. */
static void
-output_min_issue_delay_table (automaton)
- automaton_t automaton;
+output_min_issue_delay_table (automaton_t automaton)
{
vla_hwint_t min_issue_delay_vect;
vla_hwint_t compressed_min_issue_delay_vect;
@@ -7774,13 +7933,13 @@ output_min_issue_delay_table (automaton)
+ ainsn->insn_equiv_class_num) = min_delay;
}
}
- fprintf (output_file, "/* Vector of min issue delay of insns.*/\n");
+ fprintf (output_file, "/* Vector of min issue delay of insns. */\n");
fprintf (output_file, "static const ");
output_range_type (output_file, 0, automaton->max_min_delay);
fprintf (output_file, " ");
output_min_issue_delay_vect_name (output_file, automaton);
fprintf (output_file, "[] ATTRIBUTE_UNUSED = {\n");
- /* Compress the vector */
+ /* Compress the vector. */
if (automaton->max_min_delay < 2)
automaton->min_issue_delay_table_compression_factor = 8;
else if (automaton->max_min_delay < 4)
@@ -7824,8 +7983,7 @@ static int locked_states_num;
/* Form and output vector representing the locked states of
AUTOMATON. */
static void
-output_dead_lock_vect (automaton)
- automaton_t automaton;
+output_dead_lock_vect (automaton_t automaton)
{
state_t *state_ptr;
arc_t arc;
@@ -7870,8 +8028,7 @@ output_dead_lock_vect (automaton)
/* Form and output vector representing reserved units of the states of
AUTOMATON. */
static void
-output_reserved_units_table (automaton)
- automaton_t automaton;
+output_reserved_units_table (automaton_t automaton)
{
state_t *curr_state_ptr;
vla_hwint_t reserved_units_table;
@@ -7895,14 +8052,12 @@ output_reserved_units_table (automaton)
curr_state_ptr++)
{
for (i = 0; i < description->units_num; i++)
- if (units_array [i]->query_p)
- {
- if (test_unit_reserv ((*curr_state_ptr)->reservs, 0, i))
- VLA_HWINT (reserved_units_table,
- (*curr_state_ptr)->order_state_num * state_byte_size
- + units_array [i]->query_num / 8)
- += (1 << (units_array [i]->query_num % 8));
- }
+ if (units_array [i]->query_p
+ && first_cycle_unit_presence (*curr_state_ptr, i))
+ VLA_HWINT (reserved_units_table,
+ (*curr_state_ptr)->order_state_num * state_byte_size
+ + units_array [i]->query_num / 8)
+ += (1 << (units_array [i]->query_num % 8));
}
fprintf (output_file, "/* Vector for reserved units of states. */\n");
fprintf (output_file, "static const ");
@@ -7920,7 +8075,7 @@ output_reserved_units_table (automaton)
/* The function outputs all tables representing DFA(s) used for fast
pipeline hazards recognition. */
static void
-output_tables ()
+output_tables (void)
{
automaton_t automaton;
@@ -7940,13 +8095,10 @@ output_tables ()
AUTOMATON_STATE_ALTS_MACRO_NAME);
output_min_issue_delay_table (automaton);
output_dead_lock_vect (automaton);
- if (no_minimization_flag)
- {
- fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
- output_reserved_units_table (automaton);
- fprintf (output_file, "\n#endif /* #if %s */\n\n",
- CPU_UNITS_QUERY_MACRO_NAME);
- }
+ fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
+ output_reserved_units_table (automaton);
+ fprintf (output_file, "\n#endif /* #if %s */\n\n",
+ CPU_UNITS_QUERY_MACRO_NAME);
}
fprintf (output_file, "\n#define %s %d\n\n", ADVANCE_CYCLE_VALUE_NAME,
DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num);
@@ -7956,7 +8108,7 @@ output_tables ()
`max_insn_queue_index'. Its value is not less than maximal queue
length needed for the insn scheduler. */
static void
-output_max_insn_queue_index_def ()
+output_max_insn_queue_index_def (void)
{
int i, max, latency;
decl_t decl;
@@ -7986,11 +8138,11 @@ output_max_insn_queue_index_def ()
}
-/* The function outputs switch cases for insn reseravtions using
+/* The function outputs switch cases for insn reservations using
function *output_automata_list_code. */
static void
-output_insn_code_cases (output_automata_list_code)
- void (*output_automata_list_code) PARAMS ((automata_list_el_t));
+output_insn_code_cases (void (*output_automata_list_code)
+ (automata_list_el_t))
{
decl_t decl, decl2;
int i, j;
@@ -8030,8 +8182,7 @@ output_insn_code_cases (output_automata_list_code)
/* The function outputs a code for evaluation of a minimal delay of
issue of insns which have reservations in given AUTOMATA_LIST. */
static void
-output_automata_list_min_issue_delay_code (automata_list)
- automata_list_el_t automata_list;
+output_automata_list_min_issue_delay_code (automata_list_el_t automata_list)
{
automata_list_el_t el;
automaton_t automaton;
@@ -8082,15 +8233,12 @@ output_automata_list_min_issue_delay_code (automata_list)
/* Output function `internal_min_issue_delay'. */
static void
-output_internal_min_issue_delay_func ()
+output_internal_min_issue_delay_func (void)
{
- fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
- INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, CHIP_NAME);
fprintf (output_file,
- "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
+ "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
- CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
- CHIP_PARAMETER_NAME);
+ CHIP_NAME, CHIP_PARAMETER_NAME);
fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n int %s = -1;\n",
TEMPORARY_VARIABLE_NAME, RESULT_VARIABLE_NAME);
fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
@@ -8105,8 +8253,7 @@ output_internal_min_issue_delay_func ()
/* The function outputs a code changing state after issue of insns
which have reservations in given AUTOMATA_LIST. */
static void
-output_automata_list_transition_code (automata_list)
- automata_list_el_t automata_list;
+output_automata_list_transition_code (automata_list_el_t automata_list)
{
automata_list_el_t el, next_el;
@@ -8199,14 +8346,11 @@ output_automata_list_transition_code (automata_list)
/* Output function `internal_state_transition'. */
static void
-output_internal_trans_func ()
+output_internal_trans_func (void)
{
- fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
- INTERNAL_TRANSITION_FUNC_NAME, CHIP_NAME);
fprintf (output_file,
- "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s ATTRIBUTE_UNUSED;\n",
+ "static int\n%s (int %s, struct %s *%s ATTRIBUTE_UNUSED)\n",
INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
- CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME,
CHIP_NAME, CHIP_PARAMETER_NAME);
fprintf (output_file, "{\n int %s ATTRIBUTE_UNUSED;\n", TEMPORARY_VARIABLE_NAME);
fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
@@ -8229,10 +8373,9 @@ output_internal_trans_func ()
where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
code denotes CODE. */
static void
-output_internal_insn_code_evaluation (insn_name, insn_code_name, code)
- const char *insn_name;
- const char *insn_code_name;
- int code;
+output_internal_insn_code_evaluation (const char *insn_name,
+ const char *insn_code_name,
+ int code)
{
fprintf (output_file, "\n if (%s != 0)\n {\n", insn_name);
fprintf (output_file, " %s = %s (%s);\n", insn_code_name,
@@ -8244,49 +8387,62 @@ output_internal_insn_code_evaluation (insn_name, insn_code_name, code)
}
-/* The function outputs function `dfa_insn_code'. */
+/* This function outputs `dfa_insn_code' and its helper function
+ `dfa_insn_code_enlarge'. */
static void
-output_dfa_insn_code_func ()
+output_dfa_insn_code_func (void)
{
- fprintf (output_file, "#ifdef __GNUC__\n__inline__\n#endif\n");
- fprintf (output_file, "static int %s PARAMS ((rtx));\n",
- DFA_INSN_CODE_FUNC_NAME);
- fprintf (output_file, "static int\n%s (%s)\n\trtx %s;\n",
- DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME, INSN_PARAMETER_NAME);
- fprintf (output_file, "{\n int %s;\n int %s;\n\n",
- INTERNAL_INSN_CODE_NAME, TEMPORARY_VARIABLE_NAME);
- fprintf (output_file, " if (INSN_UID (%s) >= %s)\n {\n",
- INSN_PARAMETER_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
- fprintf (output_file, " %s = %s;\n %s = 2 * INSN_UID (%s);\n",
- TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
- DFA_INSN_CODES_LENGTH_VARIABLE_NAME, INSN_PARAMETER_NAME);
- fprintf (output_file, " %s = xrealloc (%s, %s * sizeof (int));\n",
+ /* Emacs c-mode gets really confused if there's a { or } in column 0
+ inside a string, so don't do that. */
+ fprintf (output_file, "\
+static void\n\
+dfa_insn_code_enlarge (int uid)\n\
+{\n\
+ int i = %s;\n\
+ %s = 2 * uid;\n\
+ %s = xrealloc (%s,\n\
+ %s * sizeof(int));\n\
+ for (; i < %s; i++)\n\
+ %s[i] = -1;\n}\n\n",
+ DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
+ DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
- DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
+ DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
+ DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
+ DFA_INSN_CODES_VARIABLE_NAME);
+ fprintf (output_file, "\
+static inline int\n%s (rtx %s)\n\
+{\n\
+ int uid = INSN_UID (%s);\n\
+ int %s;\n\n",
+ DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
+ INSN_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME);
+
fprintf (output_file,
- " for (; %s < %s; %s++)\n %s [%s] = -1;\n }\n",
- TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME,
- TEMPORARY_VARIABLE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
- TEMPORARY_VARIABLE_NAME);
- fprintf (output_file, " if ((%s = %s [INSN_UID (%s)]) < 0)\n {\n",
- INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME,
- INSN_PARAMETER_NAME);
- fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
- INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME);
- fprintf (output_file, " %s [INSN_UID (%s)] = %s;\n",
- DFA_INSN_CODES_VARIABLE_NAME, INSN_PARAMETER_NAME,
- INTERNAL_INSN_CODE_NAME);
- fprintf (output_file, " }\n return %s;\n}\n\n",
- INTERNAL_INSN_CODE_NAME);
+ " if (uid >= %s)\n dfa_insn_code_enlarge (uid);\n\n",
+ DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
+ fprintf (output_file, " %s = %s[uid];\n",
+ INTERNAL_INSN_CODE_NAME, DFA_INSN_CODES_VARIABLE_NAME);
+ fprintf (output_file, "\
+ if (%s < 0)\n\
+ {\n\
+ %s = %s (%s);\n\
+ %s[uid] = %s;\n\
+ }\n",
+ INTERNAL_INSN_CODE_NAME,
+ INTERNAL_INSN_CODE_NAME,
+ INTERNAL_DFA_INSN_CODE_FUNC_NAME, INSN_PARAMETER_NAME,
+ DFA_INSN_CODES_VARIABLE_NAME, INTERNAL_INSN_CODE_NAME);
+ fprintf (output_file, " return %s;\n}\n\n", INTERNAL_INSN_CODE_NAME);
}
/* The function outputs PHR interface function `state_transition'. */
static void
-output_trans_func ()
+output_trans_func (void)
{
- fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
- TRANSITION_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
- STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
+ fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
+ TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
+ INSN_PARAMETER_NAME);
fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
INTERNAL_INSN_CODE_NAME, -1);
@@ -8297,8 +8453,7 @@ output_trans_func ()
/* The function outputs a code for evaluation of alternative states
number for insns which have reservations in given AUTOMATA_LIST. */
static void
-output_automata_list_state_alts_code (automata_list)
- automata_list_el_t automata_list;
+output_automata_list_state_alts_code (automata_list_el_t automata_list)
{
automata_list_el_t el;
automaton_t automaton;
@@ -8358,15 +8513,12 @@ output_automata_list_state_alts_code (automata_list)
/* Output function `internal_state_alts'. */
static void
-output_internal_state_alts_func ()
+output_internal_state_alts_func (void)
{
- fprintf (output_file, "static int %s PARAMS ((int, struct %s *));\n",
- INTERNAL_STATE_ALTS_FUNC_NAME, CHIP_NAME);
fprintf (output_file,
- "static int\n%s (%s, %s)\n\tint %s;\n\tstruct %s *%s;\n",
+ "static int\n%s (int %s, struct %s *%s)\n",
INTERNAL_STATE_ALTS_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
- CHIP_PARAMETER_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME,
- CHIP_PARAMETER_NAME);
+ CHIP_NAME, CHIP_PARAMETER_NAME);
fprintf (output_file, "{\n int %s;\n", RESULT_VARIABLE_NAME);
fprintf (output_file, "\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
output_insn_code_cases (output_automata_list_state_alts_code);
@@ -8379,7 +8531,7 @@ output_internal_state_alts_func ()
/* The function outputs PHR interface function `state_alts'. */
static void
-output_state_alts_func ()
+output_state_alts_func (void)
{
fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
STATE_ALTS_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
@@ -8393,11 +8545,11 @@ output_state_alts_func ()
/* Output function `min_issue_delay'. */
static void
-output_min_issue_delay_func ()
+output_min_issue_delay_func (void)
{
- fprintf (output_file, "int\n%s (%s, %s)\n\t%s %s;\n\trtx %s;\n",
- MIN_ISSUE_DELAY_FUNC_NAME, STATE_NAME, INSN_PARAMETER_NAME,
- STATE_TYPE_NAME, STATE_NAME, INSN_PARAMETER_NAME);
+ fprintf (output_file, "int\n%s (%s %s, rtx %s)\n",
+ MIN_ISSUE_DELAY_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
+ INSN_PARAMETER_NAME);
fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
fprintf (output_file, " %s = %s (%s);\n", INTERNAL_INSN_CODE_NAME,
@@ -8407,22 +8559,19 @@ output_min_issue_delay_func ()
fprintf (output_file, " }\n else\n %s = %s;\n",
INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
fprintf (output_file, "\n return %s (%s, %s);\n",
- INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
+ INTERNAL_MIN_ISSUE_DELAY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
STATE_NAME);
fprintf (output_file, "}\n\n");
}
/* Output function `internal_dead_lock'. */
static void
-output_internal_dead_lock_func ()
+output_internal_dead_lock_func (void)
{
automaton_t automaton;
- fprintf (output_file, "static int %s PARAMS ((struct %s *));\n",
- INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME);
- fprintf (output_file, "static int\n%s (%s)\n\tstruct %s *%s;\n",
- INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_PARAMETER_NAME, CHIP_NAME,
- CHIP_PARAMETER_NAME);
+ fprintf (output_file, "static int\n%s (struct %s *%s)\n",
+ INTERNAL_DEAD_LOCK_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
fprintf (output_file, "{\n");
for (automaton = description->first_automaton;
automaton != NULL;
@@ -8439,55 +8588,50 @@ output_internal_dead_lock_func ()
/* The function outputs PHR interface function `state_dead_lock_p'. */
static void
-output_dead_lock_func ()
+output_dead_lock_func (void)
{
- fprintf (output_file, "int\n%s (%s)\n\t%s %s;\n",
- DEAD_LOCK_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
+ fprintf (output_file, "int\n%s (%s %s)\n",
+ DEAD_LOCK_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
fprintf (output_file, "{\n return %s (%s);\n}\n\n",
INTERNAL_DEAD_LOCK_FUNC_NAME, STATE_NAME);
}
/* Output function `internal_reset'. */
static void
-output_internal_reset_func ()
+output_internal_reset_func (void)
{
- fprintf (output_file, "static void %s PARAMS ((struct %s *));\n",
- INTERNAL_RESET_FUNC_NAME, CHIP_NAME);
- fprintf (output_file, "static void\n%s (%s)\n\tstruct %s *%s;\n",
- INTERNAL_RESET_FUNC_NAME, CHIP_PARAMETER_NAME,
- CHIP_NAME, CHIP_PARAMETER_NAME);
+ fprintf (output_file, "static inline void\n%s (struct %s *%s)\n",
+ INTERNAL_RESET_FUNC_NAME, CHIP_NAME, CHIP_PARAMETER_NAME);
fprintf (output_file, "{\n memset (%s, 0, sizeof (struct %s));\n}\n\n",
CHIP_PARAMETER_NAME, CHIP_NAME);
}
/* The function outputs PHR interface function `state_size'. */
static void
-output_size_func ()
+output_size_func (void)
{
- fprintf (output_file, "int\n%s ()\n", SIZE_FUNC_NAME);
+ fprintf (output_file, "int\n%s (void)\n", SIZE_FUNC_NAME);
fprintf (output_file, "{\n return sizeof (struct %s);\n}\n\n", CHIP_NAME);
}
/* The function outputs PHR interface function `state_reset'. */
static void
-output_reset_func ()
+output_reset_func (void)
{
- fprintf (output_file, "void\n%s (%s)\n\t %s %s;\n",
- RESET_FUNC_NAME, STATE_NAME, STATE_TYPE_NAME, STATE_NAME);
+ fprintf (output_file, "void\n%s (%s %s)\n",
+ RESET_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME);
fprintf (output_file, "{\n %s (%s);\n}\n\n", INTERNAL_RESET_FUNC_NAME,
STATE_NAME);
}
/* Output function `min_insn_conflict_delay'. */
static void
-output_min_insn_conflict_delay_func ()
+output_min_insn_conflict_delay_func (void)
{
fprintf (output_file,
- "int\n%s (%s, %s, %s)\n\t%s %s;\n\trtx %s;\n\trtx %s;\n",
- MIN_INSN_CONFLICT_DELAY_FUNC_NAME,
- STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
- STATE_TYPE_NAME, STATE_NAME,
- INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
+ "int\n%s (%s %s, rtx %s, rtx %s)\n",
+ MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
+ STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
fprintf (output_file, "{\n struct %s %s;\n int %s, %s;\n",
CHIP_NAME, CHIP_NAME, INTERNAL_INSN_CODE_NAME,
INTERNAL_INSN2_CODE_NAME);
@@ -8508,74 +8652,107 @@ output_min_insn_conflict_delay_func ()
/* Output function `internal_insn_latency'. */
static void
-output_internal_insn_latency_func ()
+output_internal_insn_latency_func (void)
{
decl_t decl;
struct bypass_decl *bypass;
- int i;
+ int i, j, col;
+ const char *tabletype = "unsigned char";
- fprintf (output_file, "static int %s PARAMS ((int, int, rtx, rtx));\n",
- INTERNAL_INSN_LATENCY_FUNC_NAME);
- fprintf (output_file, "static int\n%s (%s, %s, %s, %s)",
+ /* Find the smallest integer type that can hold all the default
+ latency values. */
+ for (i = 0; i < description->decls_num; i++)
+ if (description->decls[i]->mode == dm_insn_reserv)
+ {
+ decl = description->decls[i];
+ if (DECL_INSN_RESERV (decl)->default_latency > UCHAR_MAX
+ && tabletype[0] != 'i') /* Don't shrink it. */
+ tabletype = "unsigned short";
+ if (DECL_INSN_RESERV (decl)->default_latency > USHRT_MAX)
+ tabletype = "int";
+ }
+
+ fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
INTERNAL_INSN2_CODE_NAME, INSN_PARAMETER_NAME,
INSN2_PARAMETER_NAME);
- fprintf (output_file, "\n\tint %s;\n\tint %s;\n",
- INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
- fprintf (output_file,
- "\trtx %s ATTRIBUTE_UNUSED;\n\trtx %s ATTRIBUTE_UNUSED;\n",
- INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
- fprintf (output_file, "{\n switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
- for (i = 0; i < description->decls_num; i++)
+ fprintf (output_file, "{\n");
+
+ if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
{
- decl = description->decls [i];
- if (decl->mode == dm_insn_reserv)
- {
- fprintf (output_file, " case %d:\n",
- DECL_INSN_RESERV (decl)->insn_num);
- if (DECL_INSN_RESERV (decl)->bypass_list == NULL)
- fprintf (output_file, " return (%s != %s ? %d : 0);\n",
- INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
- DECL_INSN_RESERV (decl)->default_latency);
- else
- {
- fprintf (output_file, " switch (%s)\n {\n",
- INTERNAL_INSN2_CODE_NAME);
- for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
- bypass != NULL;
- bypass = bypass->next)
- {
- fprintf (output_file, " case %d:\n",
- bypass->in_insn_reserv->insn_num);
- if (bypass->bypass_guard_name == NULL)
- fprintf (output_file, " return %d;\n",
- bypass->latency);
- else
- fprintf (output_file,
- " return (%s (%s, %s) ? %d : %d);\n",
- bypass->bypass_guard_name, INSN_PARAMETER_NAME,
- INSN2_PARAMETER_NAME, bypass->latency,
- DECL_INSN_RESERV (decl)->default_latency);
- }
- fprintf (output_file, " default:\n");
- fprintf (output_file,
- " return (%s != %s ? %d : 0);\n }\n",
- INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
- DECL_INSN_RESERV (decl)->default_latency);
-
- }
- }
+ fputs (" return 0;\n}\n\n", output_file);
+ return;
}
- fprintf (output_file, " default:\n return 0;\n }\n}\n\n");
+
+ fprintf (output_file, " static const %s default_latencies[] =\n {",
+ tabletype);
+
+ for (i = 0, j = 0, col = 7; i < description->decls_num; i++)
+ if (description->decls[i]->mode == dm_insn_reserv
+ && description->decls[i] != advance_cycle_insn_decl)
+ {
+ if ((col = (col+1) % 8) == 0)
+ fputs ("\n ", output_file);
+ decl = description->decls[i];
+ if (j++ != DECL_INSN_RESERV (decl)->insn_num)
+ abort ();
+ fprintf (output_file, "% 4d,",
+ DECL_INSN_RESERV (decl)->default_latency);
+ }
+ if (j != DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)
+ abort ();
+ fputs ("\n };\n", output_file);
+
+ fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
+ INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
+ INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+
+ fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
+ for (i = 0; i < description->decls_num; i++)
+ if (description->decls[i]->mode == dm_insn_reserv
+ && DECL_INSN_RESERV (description->decls[i])->bypass_list)
+ {
+ decl = description->decls [i];
+ fprintf (output_file,
+ " case %d:\n switch (%s)\n {\n",
+ DECL_INSN_RESERV (decl)->insn_num,
+ INTERNAL_INSN2_CODE_NAME);
+ for (bypass = DECL_INSN_RESERV (decl)->bypass_list;
+ bypass != NULL;
+ bypass = bypass->next)
+ {
+ if (bypass->in_insn_reserv->insn_num
+ == DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)
+ abort ();
+ fprintf (output_file, " case %d:\n",
+ bypass->in_insn_reserv->insn_num);
+ if (bypass->bypass_guard_name == NULL)
+ fprintf (output_file, " return %d;\n",
+ bypass->latency);
+ else
+ {
+ fprintf (output_file,
+ " if (%s (%s, %s))\n",
+ bypass->bypass_guard_name, INSN_PARAMETER_NAME,
+ INSN2_PARAMETER_NAME);
+ fprintf (output_file,
+ " return %d;\n break;\n",
+ bypass->latency);
+ }
+ }
+ fputs (" }\n break;\n", output_file);
+ }
+
+ fprintf (output_file, " }\n return default_latencies[%s];\n}\n\n",
+ INTERNAL_INSN_CODE_NAME);
}
/* The function outputs PHR interface function `insn_latency'. */
static void
-output_insn_latency_func ()
+output_insn_latency_func (void)
{
- fprintf (output_file, "int\n%s (%s, %s)\n\trtx %s;\n\trtx %s;\n",
- INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME,
- INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
+ fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
+ INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
fprintf (output_file, "{\n int %s, %s;\n",
INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
@@ -8590,54 +8767,67 @@ output_insn_latency_func ()
/* The function outputs PHR interface function `print_reservation'. */
static void
-output_print_reservation_func ()
+output_print_reservation_func (void)
{
decl_t decl;
- int i;
+ int i, j;
- fprintf (output_file, "void\n%s (%s, %s)\n\tFILE *%s;\n\trtx %s;\n",
+ fprintf (output_file,
+ "void\n%s (FILE *%s, rtx %s ATTRIBUTE_UNUSED)\n{\n",
PRINT_RESERVATION_FUNC_NAME, FILE_PARAMETER_NAME,
- INSN_PARAMETER_NAME, FILE_PARAMETER_NAME,
INSN_PARAMETER_NAME);
- fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
- fprintf (output_file, "\n if (%s != 0)\n {\n", INSN_PARAMETER_NAME);
- fprintf (output_file, " %s = %s (%s);\n",
- INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
- INSN_PARAMETER_NAME);
- fprintf (output_file, " if (%s > %s)\n",
- INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
- fprintf (output_file, " {\n fprintf (%s, \"%s\");\n",
- FILE_PARAMETER_NAME, NOTHING_NAME);
- fprintf (output_file, " return;\n }\n");
- fprintf (output_file, " }\n else\n");
- fprintf (output_file,
- " {\n fprintf (%s, \"%s\");\n return;\n }\n",
- FILE_PARAMETER_NAME, NOTHING_NAME);
- fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
- for (i = 0; i < description->decls_num; i++)
+
+ if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
+ {
+ fprintf (output_file, " fputs (\"%s\", %s);\n}\n\n",
+ NOTHING_NAME, FILE_PARAMETER_NAME);
+ return;
+ }
+
+
+ fputs (" static const char *const reservation_names[] =\n {",
+ output_file);
+
+ for (i = 0, j = 0; i < description->decls_num; i++)
{
decl = description->decls [i];
if (decl->mode == dm_insn_reserv && decl != advance_cycle_insn_decl)
{
- fprintf (output_file,
- " case %d:\n", DECL_INSN_RESERV (decl)->insn_num);
- fprintf (output_file,
- " fprintf (%s, \"%s\");\n break;\n",
- FILE_PARAMETER_NAME,
- regexp_representation (DECL_INSN_RESERV (decl)->regexp));
- finish_regexp_representation ();
- }
+ if (j++ != DECL_INSN_RESERV (decl)->insn_num)
+ abort ();
+ fprintf (output_file, "\n \"%s\",",
+ regexp_representation (DECL_INSN_RESERV (decl)->regexp));
+ finish_regexp_representation ();
+ }
}
- fprintf (output_file, " default:\n fprintf (%s, \"%s\");\n }\n",
- FILE_PARAMETER_NAME, NOTHING_NAME);
- fprintf (output_file, "}\n\n");
+ if (j != DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num)
+ abort ();
+
+ fprintf (output_file, "\n \"%s\"\n };\n int %s;\n\n",
+ NOTHING_NAME, INTERNAL_INSN_CODE_NAME);
+
+ fprintf (output_file, " if (%s == 0)\n %s = %s;\n",
+ INSN_PARAMETER_NAME,
+ INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+ fprintf (output_file, " else\n\
+ {\n\
+ %s = %s (%s);\n\
+ if (%s > %s)\n\
+ %s = %s;\n\
+ }\n",
+ INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
+ INSN_PARAMETER_NAME,
+ INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
+ INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+
+ fprintf (output_file, " fputs (reservation_names[%s], %s);\n}\n\n",
+ INTERNAL_INSN_CODE_NAME, FILE_PARAMETER_NAME);
}
/* The following function is used to sort unit declaration by their
names. */
static int
-units_cmp (unit1, unit2)
- const void *unit1, *unit2;
+units_cmp (const void *unit1, const void *unit2)
{
const unit_decl_t u1 = *(unit_decl_t *) unit1;
const unit_decl_t u2 = *(unit_decl_t *) unit2;
@@ -8666,11 +8856,11 @@ units_cmp (unit1, unit2)
/* The following function outputs function to obtain internal cpu unit
code by the cpu unit name. */
static void
-output_get_cpu_unit_code_func ()
+output_get_cpu_unit_code_func (void)
{
int i;
unit_decl_t *units;
-
+
fprintf (output_file, "int\n%s (%s)\n\tconst char *%s;\n",
GET_CPU_UNIT_CODE_FUNC_NAME, CPU_UNIT_NAME_PARAMETER_NAME,
CPU_UNIT_NAME_PARAMETER_NAME);
@@ -8680,8 +8870,7 @@ output_get_cpu_unit_code_func ()
LOW_VARIABLE_NAME, MIDDLE_VARIABLE_NAME, HIGH_VARIABLE_NAME);
fprintf (output_file, " static struct %s %s [] =\n {\n",
NAME_CODE_STRUCT_NAME, NAME_CODE_TABLE_NAME);
- units = (unit_decl_t *) xmalloc (sizeof (unit_decl_t)
- * description->units_num);
+ units = xmalloc (sizeof (unit_decl_t) * description->units_num);
memcpy (units, units_array, sizeof (unit_decl_t) * description->units_num);
qsort (units, description->units_num, sizeof (unit_decl_t), units_cmp);
for (i = 0; i < description->units_num; i++)
@@ -8717,7 +8906,7 @@ output_get_cpu_unit_code_func ()
unit (its internal code will be passed as the function argument) in
given cpu state. */
static void
-output_cpu_unit_reservation_p ()
+output_cpu_unit_reservation_p (void)
{
automaton_t automaton;
@@ -8744,16 +8933,13 @@ output_cpu_unit_reservation_p ()
fprintf (output_file, " return 0;\n}\n\n");
}
-/* The function outputs PHR interface function `dfa_start'. */
+/* The function outputs PHR interface function `dfa_clean_insn_cache'. */
static void
-output_dfa_start_func ()
+output_dfa_clean_insn_cache_func (void)
{
fprintf (output_file,
- "void\n%s ()\n{\n int %s;\n\n %s = get_max_uid ();\n",
- DFA_START_FUNC_NAME, I_VARIABLE_NAME,
- DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
- fprintf (output_file, " %s = (int *) xmalloc (%s * sizeof (int));\n",
- DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
+ "void\n%s (void)\n{\n int %s;\n\n",
+ DFA_CLEAN_INSN_CACHE_FUNC_NAME, I_VARIABLE_NAME);
fprintf (output_file,
" for (%s = 0; %s < %s; %s++)\n %s [%s] = -1;\n}\n\n",
I_VARIABLE_NAME, I_VARIABLE_NAME,
@@ -8761,11 +8947,23 @@ output_dfa_start_func ()
DFA_INSN_CODES_VARIABLE_NAME, I_VARIABLE_NAME);
}
+/* The function outputs PHR interface function `dfa_start'. */
+static void
+output_dfa_start_func (void)
+{
+ fprintf (output_file,
+ "void\n%s (void)\n{\n %s = get_max_uid ();\n",
+ DFA_START_FUNC_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
+ fprintf (output_file, " %s = xmalloc (%s * sizeof (int));\n",
+ DFA_INSN_CODES_VARIABLE_NAME, DFA_INSN_CODES_LENGTH_VARIABLE_NAME);
+ fprintf (output_file, " %s ();\n}\n\n", DFA_CLEAN_INSN_CACHE_FUNC_NAME);
+}
+
/* The function outputs PHR interface function `dfa_finish'. */
static void
-output_dfa_finish_func ()
+output_dfa_finish_func (void)
{
- fprintf (output_file, "void\n%s ()\n{\n free (%s);\n}\n\n",
+ fprintf (output_file, "void\n%s (void)\n{\n free (%s);\n}\n\n",
DFA_FINISH_FUNC_NAME, DFA_INSN_CODES_VARIABLE_NAME);
}
@@ -8776,8 +8974,7 @@ output_dfa_finish_func ()
/* The function outputs string representation of IR reservation. */
static void
-output_regexp (regexp)
- regexp_t regexp;
+output_regexp (regexp_t regexp)
{
fprintf (output_description_file, "%s", regexp_representation (regexp));
finish_regexp_representation ();
@@ -8785,23 +8982,39 @@ output_regexp (regexp)
/* Output names of units in LIST separated by comma. */
static void
-output_unit_set_el_list (list)
- unit_set_el_t list;
+output_unit_set_el_list (unit_set_el_t list)
{
unit_set_el_t el;
for (el = list; el != NULL; el = el->next_unit_set_el)
{
if (el != list)
- fprintf (output_description_file, ",");
+ fprintf (output_description_file, ", ");
fprintf (output_description_file, "%s", el->unit_decl->name);
}
}
+/* Output patterns in LIST separated by comma. */
+static void
+output_pattern_set_el_list (pattern_set_el_t list)
+{
+ pattern_set_el_t el;
+ int i;
+
+ for (el = list; el != NULL; el = el->next_pattern_set_el)
+ {
+ if (el != list)
+ fprintf (output_description_file, ", ");
+ for (i = 0; i < el->units_num; i++)
+ fprintf (output_description_file, (i == 0 ? "%s" : " %s"),
+ el->unit_decls [i]->name);
+ }
+}
+
/* The function outputs string representation of IR define_reservation
and define_insn_reservation. */
static void
-output_description ()
+output_description (void)
{
decl_t decl;
int i;
@@ -8822,14 +9035,30 @@ output_description ()
{
fprintf (output_description_file, "unit %s presence_set: ",
DECL_UNIT (decl)->name);
- output_unit_set_el_list (DECL_UNIT (decl)->presence_list);
+ output_pattern_set_el_list (DECL_UNIT (decl)->presence_list);
+ fprintf (output_description_file, "\n");
+ }
+ if (DECL_UNIT (decl)->final_presence_list != NULL)
+ {
+ fprintf (output_description_file, "unit %s final_presence_set: ",
+ DECL_UNIT (decl)->name);
+ output_pattern_set_el_list
+ (DECL_UNIT (decl)->final_presence_list);
fprintf (output_description_file, "\n");
}
if (DECL_UNIT (decl)->absence_list != NULL)
{
fprintf (output_description_file, "unit %s absence_set: ",
DECL_UNIT (decl)->name);
- output_unit_set_el_list (DECL_UNIT (decl)->absence_list);
+ output_pattern_set_el_list (DECL_UNIT (decl)->absence_list);
+ fprintf (output_description_file, "\n");
+ }
+ if (DECL_UNIT (decl)->final_absence_list != NULL)
+ {
+ fprintf (output_description_file, "unit %s final_absence_set: ",
+ DECL_UNIT (decl)->name);
+ output_pattern_set_el_list
+ (DECL_UNIT (decl)->final_absence_list);
fprintf (output_description_file, "\n");
}
}
@@ -8840,9 +9069,8 @@ output_description ()
decl = description->decls [i];
if (decl->mode == dm_reserv)
{
- fprintf (output_description_file, "reservation ");
- fprintf (output_description_file, DECL_RESERV (decl)->name);
- fprintf (output_description_file, ": ");
+ fprintf (output_description_file, "reservation %s: ",
+ DECL_RESERV (decl)->name);
output_regexp (DECL_RESERV (decl)->regexp);
fprintf (output_description_file, "\n");
}
@@ -8867,9 +9095,7 @@ output_description ()
/* The function outputs name of AUTOMATON. */
static void
-output_automaton_name (f, automaton)
- FILE *f;
- automaton_t automaton;
+output_automaton_name (FILE *f, automaton_t automaton)
{
if (automaton->corresponding_automaton_decl == NULL)
fprintf (f, "#%d", automaton->automaton_order_num);
@@ -8883,8 +9109,7 @@ output_automaton_name (f, automaton)
/* The function outputs units name belonging to AUTOMATON. */
static void
-output_automaton_units (automaton)
- automaton_t automaton;
+output_automaton_units (automaton_t automaton)
{
decl_t decl;
char *name;
@@ -8915,7 +9140,7 @@ output_automaton_units (automaton)
curr_line_length += strlen (name) + 1;
fprintf (output_description_file, " ");
}
- fprintf (output_description_file, name);
+ fprintf (output_description_file, "%s", name);
}
}
if (!there_is_an_automaton_unit)
@@ -8929,8 +9154,7 @@ static vla_ptr_t state_reservs;
/* The function forms `state_reservs' for STATE. */
static void
-add_state_reservs (state)
- state_t state;
+add_state_reservs (state_t state)
{
alt_state_t curr_alt_state;
reserv_sets_t reservs;
@@ -8947,11 +9171,10 @@ add_state_reservs (state)
}
}
-/* The function outputs readable represenatation of all out arcs of
+/* The function outputs readable representation of all out arcs of
STATE. */
static void
-output_state_arcs (state)
- state_t state;
+output_state_arcs (state_t state)
{
arc_t arc;
ainsn_t ainsn;
@@ -8988,7 +9211,7 @@ output_state_arcs (state)
fprintf (output_description_file, ", ");
}
}
- fprintf (output_description_file, insn_name);
+ fprintf (output_description_file, "%s", insn_name);
ainsn = ainsn->next_same_reservs_insn;
}
while (ainsn != NULL);
@@ -9001,9 +9224,7 @@ output_state_arcs (state)
/* The following function is used for sorting possible cpu unit
reservation of a DFA state. */
static int
-state_reservs_cmp (reservs_ptr_1, reservs_ptr_2)
- const void *reservs_ptr_1;
- const void *reservs_ptr_2;
+state_reservs_cmp (const void *reservs_ptr_1, const void *reservs_ptr_2)
{
return reserv_sets_cmp (*(reserv_sets_t *) reservs_ptr_1,
*(reserv_sets_t *) reservs_ptr_2);
@@ -9012,7 +9233,7 @@ state_reservs_cmp (reservs_ptr_1, reservs_ptr_2)
/* The following function is used for sorting possible cpu unit
reservation of a DFA state. */
static void
-remove_state_duplicate_reservs ()
+remove_state_duplicate_reservs (void)
{
reserv_sets_t *reservs_ptr;
reserv_sets_t *last_formed_reservs_ptr;
@@ -9033,11 +9254,10 @@ remove_state_duplicate_reservs ()
/* The following function output readable representation of DFA(s)
state used for fast recognition of pipeline hazards. State is
- described by possible (current and scehduled) cpu unit
+ described by possible (current and scheduled) cpu unit
reservations. */
static void
-output_state (state)
- state_t state;
+output_state (state_t state)
{
reserv_sets_t *reservs_ptr;
@@ -9065,7 +9285,7 @@ output_state (state)
/* The following function output readable representation of
DFAs used for fast recognition of pipeline hazards. */
static void
-output_automaton_descriptions ()
+output_automaton_descriptions (void)
{
automaton_t automaton;
@@ -9089,10 +9309,10 @@ output_automaton_descriptions ()
/* The function outputs statistics about work of different phases of
DFA generator. */
static void
-output_statistics (f)
- FILE *f;
+output_statistics (FILE *f)
{
automaton_t automaton;
+ int states_num;
#ifndef NDEBUG
int transition_comb_vect_els = 0;
int transition_full_vect_els = 0;
@@ -9111,10 +9331,14 @@ output_statistics (f)
automaton->NDFA_states_num, automaton->NDFA_arcs_num);
fprintf (f, " %5d DFA states, %5d DFA arcs\n",
automaton->DFA_states_num, automaton->DFA_arcs_num);
+ states_num = automaton->DFA_states_num;
if (!no_minimization_flag)
- fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
- automaton->minimal_DFA_states_num,
- automaton->minimal_DFA_arcs_num);
+ {
+ fprintf (f, " %5d minimal DFA states, %5d minimal DFA arcs\n",
+ automaton->minimal_DFA_states_num,
+ automaton->minimal_DFA_arcs_num);
+ states_num = automaton->minimal_DFA_states_num;
+ }
fprintf (f, " %5d all insns %5d insn equivalence classes\n",
description->insns_num, automaton->insn_equiv_classes_num);
#ifndef NDEBUG
@@ -9132,18 +9356,18 @@ output_statistics (f)
? "use comb vect" : "use simple vect"));
fprintf
(f, "%5ld min delay table els, compression factor %d\n",
- (long) automaton->DFA_states_num * automaton->insn_equiv_classes_num,
+ (long) states_num * automaton->insn_equiv_classes_num,
automaton->min_issue_delay_table_compression_factor);
transition_comb_vect_els
+= VLA_HWINT_LENGTH (automaton->trans_table->comb_vect);
- transition_full_vect_els
+ transition_full_vect_els
+= VLA_HWINT_LENGTH (automaton->trans_table->full_vect);
state_alts_comb_vect_els
+= VLA_HWINT_LENGTH (automaton->state_alts_table->comb_vect);
state_alts_full_vect_els
+= VLA_HWINT_LENGTH (automaton->state_alts_table->full_vect);
min_issue_delay_vect_els
- += automaton->DFA_states_num * automaton->insn_equiv_classes_num;
+ += states_num * automaton->insn_equiv_classes_num;
#endif
}
#ifndef NDEBUG
@@ -9164,8 +9388,7 @@ output_statistics (f)
/* The function output times of work of different phases of DFA
generator. */
static void
-output_time_statistics (f)
- FILE *f;
+output_time_statistics (FILE *f)
{
fprintf (f, "\n transformation: ");
print_active_time (f, transform_time);
@@ -9187,11 +9410,11 @@ output_time_statistics (f)
fprintf (f, "\n");
}
-/* The function generates DFA (deterministic finate state automaton)
+/* The function generates DFA (deterministic finite state automaton)
for fast recognition of pipeline hazards. No errors during
checking must be fixed before this function call. */
static void
-generate ()
+generate (void)
{
automata_num = split_argument;
if (description->units_num < automata_num)
@@ -9201,7 +9424,7 @@ generate ()
initiate_automata_lists ();
initiate_pass_states ();
initiate_excl_sets ();
- initiate_presence_absence_sets ();
+ initiate_presence_absence_pattern_sets ();
automaton_generation_time = create_ticker ();
create_automata ();
ticker_off (&automaton_generation_time);
@@ -9212,7 +9435,7 @@ generate ()
/* The following function creates insn attribute whose values are
number alternatives in insn reservations. */
static void
-make_insn_alts_attr ()
+make_insn_alts_attr (void)
{
int i, insn_num;
decl_t decl;
@@ -9241,7 +9464,7 @@ make_insn_alts_attr ()
make_internal_attr (attr_printf (sizeof ("*")
+ strlen (INSN_ALTS_FUNC_NAME) + 1,
"*%s", INSN_ALTS_FUNC_NAME),
- condexp, 0);
+ condexp, ATTR_NONE);
}
@@ -9249,7 +9472,7 @@ make_insn_alts_attr ()
/* The following function creates attribute which is order number of
insn in pipeline hazard description translator. */
static void
-make_internal_dfa_insn_code_attr ()
+make_internal_dfa_insn_code_attr (void)
{
int i, insn_num;
decl_t decl;
@@ -9278,7 +9501,7 @@ make_internal_dfa_insn_code_attr ()
(attr_printf (sizeof ("*")
+ strlen (INTERNAL_DFA_INSN_CODE_FUNC_NAME) + 1,
"*%s", INTERNAL_DFA_INSN_CODE_FUNC_NAME),
- condexp, 0);
+ condexp, ATTR_STATIC);
}
@@ -9286,7 +9509,7 @@ make_internal_dfa_insn_code_attr ()
/* The following function creates attribute which order number of insn
in pipeline hazard description translator. */
static void
-make_default_insn_latency_attr ()
+make_default_insn_latency_attr (void)
{
int i, insn_num;
decl_t decl;
@@ -9312,7 +9535,7 @@ make_default_insn_latency_attr ()
make_internal_attr (attr_printf (sizeof ("*")
+ strlen (INSN_DEFAULT_LATENCY_FUNC_NAME)
+ 1, "*%s", INSN_DEFAULT_LATENCY_FUNC_NAME),
- condexp, 0);
+ condexp, ATTR_NONE);
}
@@ -9320,13 +9543,13 @@ make_default_insn_latency_attr ()
/* The following function creates attribute which returns 1 if given
output insn has bypassing and 0 otherwise. */
static void
-make_bypass_attr ()
+make_bypass_attr (void)
{
int i, bypass_insn;
int bypass_insns_num = 0;
decl_t decl;
rtx result_rtx;
-
+
for (i = 0; i < description->decls_num; i++)
{
decl = description->decls [i];
@@ -9361,7 +9584,7 @@ make_bypass_attr ()
make_internal_attr (attr_printf (sizeof ("*")
+ strlen (BYPASS_P_FUNC_NAME) + 1,
"*%s", BYPASS_P_FUNC_NAME),
- result_rtx, 0);
+ result_rtx, ATTR_NONE);
}
@@ -9376,8 +9599,7 @@ make_bypass_attr ()
/* The function returns suffix of given file name. The returned
string can not be changed. */
static const char *
-file_name_suffix (file_name)
- const char *file_name;
+file_name_suffix (const char *file_name)
{
const char *last_period;
@@ -9392,8 +9614,7 @@ file_name_suffix (file_name)
given file name itself if the directory name is absent. The
returned string can not be changed. */
static const char *
-base_file_name (file_name)
- const char *file_name;
+base_file_name (const char *file_name)
{
int directory_name_length;
@@ -9411,9 +9632,7 @@ base_file_name (file_name)
/* The following is top level function to initialize the work of
pipeline hazards description translator. */
void
-initiate_automaton_gen (argc, argv)
- int argc;
- char **argv;
+initiate_automaton_gen (int argc, char **argv)
{
const char *base_name;
int i;
@@ -9424,6 +9643,7 @@ initiate_automaton_gen (argc, argv)
time_flag = 0;
v_flag = 0;
w_flag = 0;
+ progress_flag = 0;
for (i = 2; i < argc; i++)
if (strcmp (argv [i], NO_MINIMIZATION_OPTION) == 0)
no_minimization_flag = 1;
@@ -9435,6 +9655,8 @@ initiate_automaton_gen (argc, argv)
w_flag = 1;
else if (strcmp (argv [i], NDFA_OPTION) == 0)
ndfa_flag = 1;
+ else if (strcmp (argv [i], PROGRESS_OPTION) == 0)
+ progress_flag = 1;
else if (strcmp (argv [i], "-split") == 0)
{
if (i + 1 >= argc)
@@ -9463,7 +9685,7 @@ initiate_automaton_gen (argc, argv)
/* The following function checks existence at least one arc marked by
each insn. */
static void
-check_automata_insn_issues ()
+check_automata_insn_issues (void)
{
automaton_t automaton;
ainsn_t ainsn, reserv_ainsn;
@@ -9512,8 +9734,7 @@ static vla_ptr_t automaton_states;
/* This function is called by function pass_states to add an achieved
STATE. */
static void
-add_automaton_state (state)
- state_t state;
+add_automaton_state (state_t state)
{
VLA_PTR_ADD (automaton_states, state);
}
@@ -9521,7 +9742,7 @@ add_automaton_state (state)
/* The following function forms list of important automata (whose
states may be changed after the insn issue) for each insn. */
static void
-form_important_insn_automata_lists ()
+form_important_insn_automata_lists (void)
{
automaton_t automaton;
state_t *state_ptr;
@@ -9587,7 +9808,7 @@ form_important_insn_automata_lists ()
/* The following is top level function to generate automat(a,on) for
fast recognition of pipeline hazards. */
void
-expand_automata ()
+expand_automata (void)
{
int i;
@@ -9606,10 +9827,11 @@ expand_automata ()
}
all_time = create_ticker ();
check_time = create_ticker ();
- fprintf (stderr, "Check description...");
- fflush (stderr);
+ if (progress_flag)
+ fprintf (stderr, "Check description...");
check_all_description ();
- fprintf (stderr, "done\n");
+ if (progress_flag)
+ fprintf (stderr, "done\n");
ticker_off (&check_time);
generation_time = create_ticker ();
if (!have_error)
@@ -9625,37 +9847,41 @@ expand_automata ()
if (!have_error)
{
form_important_insn_automata_lists ();
- fprintf (stderr, "Generation of attributes...");
- fflush (stderr);
+ if (progress_flag)
+ fprintf (stderr, "Generation of attributes...");
make_internal_dfa_insn_code_attr ();
make_insn_alts_attr ();
make_default_insn_latency_attr ();
make_bypass_attr ();
- fprintf (stderr, "done\n");
+ if (progress_flag)
+ fprintf (stderr, "done\n");
}
ticker_off (&generation_time);
ticker_off (&all_time);
- fprintf (stderr, "All other genattrtab stuff...");
- fflush (stderr);
+ if (progress_flag)
+ fprintf (stderr, "All other genattrtab stuff...");
}
/* The following is top level function to output PHR and to finish
work with pipeline description translator. */
void
-write_automata ()
+write_automata (void)
{
- fprintf (stderr, "done\n");
+ if (progress_flag)
+ fprintf (stderr, "done\n");
if (have_error)
fatal ("Errors in DFA description");
ticker_on (&all_time);
output_time = create_ticker ();
- fprintf (stderr, "Forming and outputing automata tables...");
- fflush (stderr);
+ if (progress_flag)
+ fprintf (stderr, "Forming and outputting automata tables...");
output_dfa_max_issue_rate ();
output_tables ();
- fprintf (stderr, "done\n");
- fprintf (stderr, "Output functions to work with automata...");
- fflush (stderr);
+ if (progress_flag)
+ {
+ fprintf (stderr, "done\n");
+ fprintf (stderr, "Output functions to work with automata...");
+ }
output_chip_definitions ();
output_max_insn_queue_index_def ();
output_internal_min_issue_delay_func ();
@@ -9681,17 +9907,17 @@ write_automata ()
output_internal_insn_latency_func ();
output_insn_latency_func ();
output_print_reservation_func ();
- if (no_minimization_flag)
- {
- fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
- output_get_cpu_unit_code_func ();
- output_cpu_unit_reservation_p ();
- fprintf (output_file, "\n#endif /* #if %s */\n\n",
- CPU_UNITS_QUERY_MACRO_NAME);
- }
+ /* Output function get_cpu_unit_code. */
+ fprintf (output_file, "\n#if %s\n\n", CPU_UNITS_QUERY_MACRO_NAME);
+ output_get_cpu_unit_code_func ();
+ output_cpu_unit_reservation_p ();
+ fprintf (output_file, "\n#endif /* #if %s */\n\n",
+ CPU_UNITS_QUERY_MACRO_NAME);
+ output_dfa_clean_insn_cache_func ();
output_dfa_start_func ();
output_dfa_finish_func ();
- fprintf (stderr, "done\n");
+ if (progress_flag)
+ fprintf (stderr, "done\n");
if (v_flag)
{
output_description_file = fopen (output_description_file_name, "w");
@@ -9700,11 +9926,12 @@ write_automata ()
perror (output_description_file_name);
exit (FATAL_EXIT_CODE);
}
- fprintf (stderr, "Output automata description...");
- fflush (stderr);
+ if (progress_flag)
+ fprintf (stderr, "Output automata description...");
output_description ();
output_automaton_descriptions ();
- fprintf (stderr, "done\n");
+ if (progress_flag)
+ fprintf (stderr, "done\n");
output_statistics (output_description_file);
}
output_statistics (stderr);
diff --git a/contrib/gcc/gencheck.c b/contrib/gcc/gencheck.c
index 9eda355fa372..58009a8ea3c8 100644
--- a/contrib/gcc/gencheck.c
+++ b/contrib/gcc/gencheck.c
@@ -1,5 +1,6 @@
/* Generate check macros for tree codes.
- Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -18,10 +19,12 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
-#define DEFTREECODE(SYM, NAME, TYPE, LEN) STRINGX(SYM),
+#define DEFTREECODE(SYM, NAME, TYPE, LEN) #SYM,
static const char *const tree_codes[] = {
#include "tree.def"
@@ -30,22 +33,18 @@ static const char *const tree_codes[] = {
(char*) 0
};
-static void usage PARAMS ((void));
+static void usage (void);
static void
-usage ()
+usage (void)
{
fputs ("Usage: gencheck\n", stderr);
}
-extern int main PARAMS ((int, char **));
-
int
-main (argc, argv)
- int argc;
- char **argv ATTRIBUTE_UNUSED;
+main (int argc, char **argv ATTRIBUTE_UNUSED)
{
- int i;
+ int i, j;
switch (argc)
{
@@ -61,10 +60,18 @@ main (argc, argv)
puts ("#ifndef GCC_TREE_CHECK_H");
puts ("#define GCC_TREE_CHECK_H\n");
+ /* Print macros for checks based on each of the tree code names. However,
+ since we include the tree nodes from all languages, we must check
+ for duplicate names to avoid defining the same macro twice. */
for (i = 0; tree_codes[i]; i++)
{
- printf ("#define %s_CHECK(t)\tTREE_CHECK (t, %s)\n",
- tree_codes[i], tree_codes[i]);
+ for (j = 0; j < i; j++)
+ if (strcmp (tree_codes[i], tree_codes[j]) == 0)
+ break;
+
+ if (i == j)
+ printf ("#define %s_CHECK(t)\tTREE_CHECK (t, %s)\n",
+ tree_codes[i], tree_codes[i]);
}
puts ("\n#endif /* GCC_TREE_CHECK_H */");
diff --git a/contrib/gcc/gencodes.c b/contrib/gcc/gencodes.c
index 5a292821c393..13aa2c58773f 100644
--- a/contrib/gcc/gencodes.c
+++ b/contrib/gcc/gencodes.c
@@ -2,7 +2,7 @@
- some macros CODE_FOR_... giving the insn_code_number value
for each of the defined standard insn names.
Copyright (C) 1987, 1991, 1995, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,18 +22,16 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "gensupport.h"
-static void gen_insn PARAMS ((rtx, int));
-
static void
-gen_insn (insn, code)
- rtx insn;
- int code;
+gen_insn (rtx insn, int code)
{
const char *name = XSTR (insn, 0);
int truth = maybe_eval_c_test (XSTR (insn, 2));
@@ -50,12 +48,8 @@ gen_insn (insn, code)
}
}
-extern int main PARAMS ((int, char **));
-
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
rtx desc;
@@ -109,8 +103,7 @@ enum insn_code {");
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
const char *
-get_insn_name (code)
- int code ATTRIBUTE_UNUSED;
+get_insn_name (int code ATTRIBUTE_UNUSED)
{
return NULL;
}
diff --git a/contrib/gcc/genconditions.c b/contrib/gcc/genconditions.c
index 02f80ee478de..692dc64add3b 100644
--- a/contrib/gcc/genconditions.c
+++ b/contrib/gcc/genconditions.c
@@ -1,20 +1,20 @@
/* Process machine description and calculate constant conditions.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -26,39 +26,38 @@
most of the programs that generate code from the machine
description can simply ignore the entire pattern. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "hashtab.h"
#include "gensupport.h"
-/* so we can include except.h in the generated file */
+/* so we can include except.h in the generated file. */
static int saw_eh_return;
static htab_t condition_table;
-static void add_condition PARAMS ((const char *));
-static void write_header PARAMS ((void));
-static void write_conditions PARAMS ((void));
-static int write_one_condition PARAMS ((PTR *, PTR));
-
-extern int main PARAMS ((int, char **));
+static void add_condition (const char *);
+static void write_header (void);
+static void write_conditions (void);
+static int write_one_condition (void **, void *);
/* Record the C test expression EXPR in the condition_table.
Duplicates clobber previous entries, which leaks memory, but
we don't care for this application. */
static void
-add_condition (expr)
- const char *expr;
+add_condition (const char *expr)
{
struct c_test *test;
if (expr[0] == 0)
return;
- test = (struct c_test *) xmalloc (sizeof (struct c_test));
+ test = xmalloc (sizeof (struct c_test));
test->expr = expr;
*(htab_find_slot (condition_table, test, INSERT)) = test;
@@ -67,13 +66,13 @@ add_condition (expr)
/* Generate the header for insn-conditions.c. */
static void
-write_header ()
+write_header (void)
{
puts ("\
/* Generated automatically by the program `genconditions' from the target\n\
machine description file. */\n\
\n\
-#include \"hconfig.h\"\n\
+#include \"bconfig.h\"\n\
#include \"insn-constants.h\"\n");
puts ("\
@@ -87,6 +86,8 @@ write_header ()
puts ("\
#include \"system.h\"\n\
+#include \"coretypes.h\"\n\
+#include \"tm.h\"\n\
#include \"rtl.h\"\n\
#include \"tm_p.h\"\n\
#include \"function.h\"\n");
@@ -117,8 +118,7 @@ write_header ()
/* Dummy external declarations. */\n\
extern rtx insn;\n\
extern rtx ins1;\n\
-extern rtx operands[];\n\
-extern int next_insn_tests_no_inequality PARAMS ((rtx));\n");
+extern rtx operands[];\n");
puts ("\
/* If we don't have __builtin_constant_p, or it's not acceptable in\n\
@@ -138,9 +138,7 @@ extern int next_insn_tests_no_inequality PARAMS ((rtx));\n");
MAYBE_EVAL (! optimize_size && ! TARGET_READ_MODIFY_WRITE) }, */
static int
-write_one_condition (slot, dummy)
- PTR *slot;
- PTR dummy ATTRIBUTE_UNUSED;
+write_one_condition (void **slot, void *dummy ATTRIBUTE_UNUSED)
{
const struct c_test *test = * (const struct c_test **) slot;
const char *p;
@@ -163,7 +161,7 @@ write_one_condition (slot, dummy)
/* Write out the complete conditions table, its size, and a flag
indicating that gensupport.c can now do insn elision. */
static void
-write_conditions ()
+write_conditions (void)
{
puts ("\
/* This table lists each condition found in the machine description.\n\
@@ -182,9 +180,7 @@ const struct c_test insn_conditions[] = {");
}
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
rtx desc;
int pattern_lineno; /* not used */
diff --git a/contrib/gcc/genconfig.c b/contrib/gcc/genconfig.c
index 795e31203565..c76bdb9d6459 100644
--- a/contrib/gcc/genconfig.c
+++ b/contrib/gcc/genconfig.c
@@ -1,7 +1,7 @@
/* Generate from machine description:
- some #define configuration flags.
- Copyright (C) 1987, 1991, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1991, 1997, 1998, 1999, 2000, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,8 +21,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "gensupport.h"
@@ -48,12 +50,12 @@ static int max_insns_per_peep2;
static int clobbers_seen_this_insn;
static int dup_operands_seen_this_insn;
-static void walk_insn_part PARAMS ((rtx, int, int));
-static void gen_insn PARAMS ((rtx));
-static void gen_expand PARAMS ((rtx));
-static void gen_split PARAMS ((rtx));
-static void gen_peephole PARAMS ((rtx));
-static void gen_peephole2 PARAMS ((rtx));
+static void walk_insn_part (rtx, int, int);
+static void gen_insn (rtx);
+static void gen_expand (rtx);
+static void gen_split (rtx);
+static void gen_peephole (rtx);
+static void gen_peephole2 (rtx);
/* RECOG_P will be nonzero if this pattern was seen in a context where it will
be used to recognize, rather than just generate an insn.
@@ -62,10 +64,7 @@ static void gen_peephole2 PARAMS ((rtx));
of a SET whose destination is not (pc). */
static void
-walk_insn_part (part, recog_p, non_pc_set_src)
- rtx part;
- int recog_p;
- int non_pc_set_src;
+walk_insn_part (rtx part, int recog_p, int non_pc_set_src)
{
int i, j;
RTX_CODE code;
@@ -169,8 +168,7 @@ walk_insn_part (part, recog_p, non_pc_set_src)
}
static void
-gen_insn (insn)
- rtx insn;
+gen_insn (rtx insn)
{
int i;
@@ -190,8 +188,7 @@ gen_insn (insn)
/* Similar but scan a define_expand. */
static void
-gen_expand (insn)
- rtx insn;
+gen_expand (rtx insn)
{
int i;
@@ -217,8 +214,7 @@ gen_expand (insn)
/* Similar but scan a define_split. */
static void
-gen_split (split)
- rtx split;
+gen_split (rtx split)
{
int i;
@@ -232,8 +228,7 @@ gen_split (split)
}
static void
-gen_peephole (peep)
- rtx peep;
+gen_peephole (rtx peep)
{
int i;
@@ -244,8 +239,7 @@ gen_peephole (peep)
}
static void
-gen_peephole2 (peep)
- rtx peep;
+gen_peephole2 (rtx peep)
{
int i, n;
@@ -263,12 +257,8 @@ gen_peephole2 (peep)
max_insns_per_peep2 = n;
}
-extern int main PARAMS ((int, char **));
-
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
rtx desc;
@@ -340,7 +330,14 @@ main (argc, argv)
printf ("#endif\n");
if (have_cc0_flag)
- printf ("#define HAVE_cc0 1\n");
+ {
+ printf ("#define HAVE_cc0 1\n");
+ printf ("#define CC0_P(X) ((X) == cc0_rtx)\n");
+ }
+ else
+ {
+ printf ("#define CC0_P(X) 0\n");
+ }
if (have_cmove_flag)
printf ("#define HAVE_conditional_move 1\n");
@@ -370,8 +367,7 @@ main (argc, argv)
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
const char *
-get_insn_name (code)
- int code ATTRIBUTE_UNUSED;
+get_insn_name (int code ATTRIBUTE_UNUSED)
{
return NULL;
}
diff --git a/contrib/gcc/genconstants.c b/contrib/gcc/genconstants.c
index 9208f0c00092..a49c5476d252 100644
--- a/contrib/gcc/genconstants.c
+++ b/contrib/gcc/genconstants.c
@@ -2,8 +2,8 @@
a series of #define statements, one for each constant named in
a (define_constants ...) pattern.
- Copyright (C) 1987, 1991, 1995, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1991, 1995, 1998, 1999, 2000, 2001, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -26,22 +26,21 @@ Boston, MA 02111-1307, USA. */
look at insn patterns, only (define_constants), and we want to
minimize dependencies. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "gensupport.h"
-static int print_md_constant PARAMS ((void **, void *));
-extern int main PARAMS ((int, char **));
+static int print_md_constant (void **, void *);
/* Called via traverse_md_constants; emit a #define for
the current constant definition. */
static int
-print_md_constant (slot, info)
- void **slot;
- void *info;
+print_md_constant (void **slot, void *info)
{
struct md_constant *def = *slot;
FILE *file = info;
@@ -51,9 +50,7 @@ print_md_constant (slot, info)
}
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
int dummy1, dummy2;
rtx desc;
diff --git a/contrib/gcc/genemit.c b/contrib/gcc/genemit.c
index cb6c06ccd18b..0e695d2729c3 100644
--- a/contrib/gcc/genemit.c
+++ b/contrib/gcc/genemit.c
@@ -1,6 +1,6 @@
/* Generate code from machine description to emit insns as rtl.
- Copyright (C) 1987, 1988, 1991, 1994, 1995, 1997, 1998, 1999, 2000, 2001
- Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1991, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
+ 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,8 +20,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "gensupport.h"
@@ -30,12 +32,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
static int max_opno;
static int max_dup_opno;
static int max_scratch_opno;
-static int register_constraints;
static int insn_code_number;
static int insn_index_number;
/* Data structure for recording the patterns of insns that have CLOBBERs.
- We use this to output a function that adds these CLOBBERs to a
+ We use this to output a function that adds these CLOBBERs to a
previously-allocated PARALLEL expression. */
struct clobber_pat
@@ -55,22 +56,21 @@ struct clobber_ent
struct clobber_ent *next;
};
-static void max_operand_1 PARAMS ((rtx));
-static int max_operand_vec PARAMS ((rtx, int));
-static void print_code PARAMS ((RTX_CODE));
-static void gen_exp PARAMS ((rtx, enum rtx_code, char *));
-static void gen_insn PARAMS ((rtx, int));
-static void gen_expand PARAMS ((rtx));
-static void gen_split PARAMS ((rtx));
-static void output_add_clobbers PARAMS ((void));
-static void output_added_clobbers_hard_reg_p PARAMS ((void));
-static void gen_rtx_scratch PARAMS ((rtx, enum rtx_code));
-static void output_peephole2_scratches PARAMS ((rtx));
+static void max_operand_1 (rtx);
+static int max_operand_vec (rtx, int);
+static void print_code (RTX_CODE);
+static void gen_exp (rtx, enum rtx_code, char *);
+static void gen_insn (rtx, int);
+static void gen_expand (rtx);
+static void gen_split (rtx);
+static void output_add_clobbers (void);
+static void output_added_clobbers_hard_reg_p (void);
+static void gen_rtx_scratch (rtx, enum rtx_code);
+static void output_peephole2_scratches (rtx);
static void
-max_operand_1 (x)
- rtx x;
+max_operand_1 (rtx x)
{
RTX_CODE code;
int i;
@@ -82,10 +82,6 @@ max_operand_1 (x)
code = GET_CODE (x);
- if (code == MATCH_OPERAND && XSTR (x, 2) != 0 && *XSTR (x, 2) != '\0')
- register_constraints = 1;
- if (code == MATCH_SCRATCH && XSTR (x, 1) != 0 && *XSTR (x, 1) != '\0')
- register_constraints = 1;
if (code == MATCH_OPERAND || code == MATCH_OPERATOR
|| code == MATCH_PARALLEL)
max_opno = MAX (max_opno, XINT (x, 0));
@@ -110,9 +106,7 @@ max_operand_1 (x)
}
static int
-max_operand_vec (insn, arg)
- rtx insn;
- int arg;
+max_operand_vec (rtx insn, int arg)
{
int len = XVECLEN (insn, arg);
int i;
@@ -128,8 +122,7 @@ max_operand_vec (insn, arg)
}
static void
-print_code (code)
- RTX_CODE code;
+print_code (RTX_CODE code)
{
const char *p1;
for (p1 = GET_RTX_NAME (code); *p1; p1++)
@@ -137,9 +130,7 @@ print_code (code)
}
static void
-gen_rtx_scratch (x, subroutine_type)
- rtx x;
- enum rtx_code subroutine_type;
+gen_rtx_scratch (rtx x, enum rtx_code subroutine_type)
{
if (subroutine_type == DEFINE_PEEPHOLE2)
{
@@ -155,10 +146,7 @@ gen_rtx_scratch (x, subroutine_type)
substituting any operand references appearing within. */
static void
-gen_exp (x, subroutine_type, used)
- rtx x;
- enum rtx_code subroutine_type;
- char *used;
+gen_exp (rtx x, enum rtx_code subroutine_type, char *used)
{
RTX_CODE code;
int i;
@@ -292,14 +280,12 @@ gen_exp (x, subroutine_type, used)
abort ();
}
printf (")");
-}
+}
/* Generate the `gen_...' function for a DEFINE_INSN. */
static void
-gen_insn (insn, lineno)
- rtx insn;
- int lineno;
+gen_insn (rtx insn, int lineno)
{
int operands;
int i;
@@ -326,8 +312,7 @@ gen_insn (insn, lineno)
if (i != XVECLEN (insn, 1) - 1)
{
struct clobber_pat *p;
- struct clobber_ent *link
- = (struct clobber_ent *) xmalloc (sizeof (struct clobber_ent));
+ struct clobber_ent *link = xmalloc (sizeof (struct clobber_ent));
int j;
link->code_number = insn_code_number;
@@ -347,7 +332,7 @@ gen_insn (insn, lineno)
rtx new = XEXP (XVECEXP (insn, 1, j), 0);
/* OLD and NEW are the same if both are to be a SCRATCH
- of the same mode,
+ of the same mode,
or if both are registers of the same mode and number. */
if (! (GET_MODE (old) == GET_MODE (new)
&& ((GET_CODE (old) == MATCH_SCRATCH
@@ -356,15 +341,15 @@ gen_insn (insn, lineno)
&& REGNO (old) == REGNO (new)))))
break;
}
-
+
if (j == XVECLEN (insn, 1))
break;
}
if (p == 0)
{
- p = (struct clobber_pat *) xmalloc (sizeof (struct clobber_pat));
-
+ p = xmalloc (sizeof (struct clobber_pat));
+
p->insns = 0;
p->pattern = insn;
p->first_clobber = i + 1;
@@ -386,26 +371,25 @@ gen_insn (insn, lineno)
printf ("/* %s:%d */\n", read_rtx_filename, lineno);
- /* Find out how many operands this function has,
- and also whether any of them have register constraints. */
- register_constraints = 0;
+ /* Find out how many operands this function has. */
operands = max_operand_vec (insn, 1);
if (max_dup_opno >= operands)
fatal ("match_dup operand number has no match_operand");
/* Output the function name and argument declarations. */
printf ("rtx\ngen_%s (", XSTR (insn, 0));
- for (i = 0; i < operands; i++)
- if (i)
- printf (", operand%d", i);
- else
- printf ("operand%d", i);
+ if (operands)
+ for (i = 0; i < operands; i++)
+ if (i)
+ printf (",\n\trtx operand%d ATTRIBUTE_UNUSED", i);
+ else
+ printf ("rtx operand%d ATTRIBUTE_UNUSED", i);
+ else
+ printf ("void");
printf (")\n");
- for (i = 0; i < operands; i++)
- printf (" rtx operand%d;\n", i);
printf ("{\n");
- /* Output code to construct and return the rtl for the instruction body */
+ /* Output code to construct and return the rtl for the instruction body. */
if (XVECLEN (insn, 1) == 1)
{
@@ -430,8 +414,7 @@ gen_insn (insn, lineno)
/* Generate the `gen_...' function for a DEFINE_EXPAND. */
static void
-gen_expand (expand)
- rtx expand;
+gen_expand (rtx expand)
{
int operands;
int i;
@@ -441,22 +424,20 @@ gen_expand (expand)
if (XVEC (expand, 1) == 0)
fatal ("define_expand for %s lacks a pattern", XSTR (expand, 0));
- /* Find out how many operands this function has,
- and also whether any of them have register constraints. */
- register_constraints = 0;
-
+ /* Find out how many operands this function has. */
operands = max_operand_vec (expand, 1);
/* Output the function name and argument declarations. */
printf ("rtx\ngen_%s (", XSTR (expand, 0));
- for (i = 0; i < operands; i++)
- if (i)
- printf (", operand%d", i);
- else
- printf ("operand%d", i);
+ if (operands)
+ for (i = 0; i < operands; i++)
+ if (i)
+ printf (",\n\trtx operand%d", i);
+ else
+ printf ("rtx operand%d", i);
+ else
+ printf ("void");
printf (")\n");
- for (i = 0; i < operands; i++)
- printf (" rtx operand%d;\n", i);
printf ("{\n");
/* If we don't have any C code to write, only one insn is being written,
@@ -567,8 +548,7 @@ gen_expand (expand)
/* Like gen_expand, but generates insns resulting from splitting SPLIT. */
static void
-gen_split (split)
- rtx split;
+gen_split (rtx split)
{
int i;
int operands;
@@ -594,18 +574,15 @@ gen_split (split)
/* Output the prototype, function name and argument declarations. */
if (GET_CODE (split) == DEFINE_PEEPHOLE2)
{
- printf ("extern rtx gen_%s_%d PARAMS ((rtx, rtx *));\n",
+ printf ("extern rtx gen_%s_%d (rtx, rtx *);\n",
name, insn_code_number);
- printf ("rtx\ngen_%s_%d (curr_insn, operands)\n",
- name, insn_code_number);
- printf (" rtx curr_insn ATTRIBUTE_UNUSED;\n");
- printf (" rtx *operands%s;\n", unused);
+ printf ("rtx\ngen_%s_%d (rtx curr_insn ATTRIBUTE_UNUSED, rtx *operands%s)\n",
+ name, insn_code_number, unused);
}
else
{
- printf ("extern rtx gen_split_%d PARAMS ((rtx *));\n", insn_code_number);
- printf ("rtx\ngen_%s_%d (operands)\n", name, insn_code_number);
- printf (" rtx *operands%s;\n", unused);
+ printf ("extern rtx gen_split_%d (rtx *);\n", insn_code_number);
+ printf ("rtx\ngen_%s_%d (rtx *operands%s)\n", name, insn_code_number, unused);
}
printf ("{\n");
@@ -683,14 +660,13 @@ gen_split (split)
the end of the vector. */
static void
-output_add_clobbers ()
+output_add_clobbers (void)
{
struct clobber_pat *clobber;
struct clobber_ent *ent;
int i;
- printf ("\n\nvoid\nadd_clobbers (pattern, insn_code_number)\n");
- printf (" rtx pattern ATTRIBUTE_UNUSED;\n int insn_code_number;\n");
+ printf ("\n\nvoid\nadd_clobbers (rtx pattern ATTRIBUTE_UNUSED, int insn_code_number)\n");
printf ("{\n");
printf (" switch (insn_code_number)\n");
printf (" {\n");
@@ -722,14 +698,13 @@ output_add_clobbers ()
hard reg and 0 if they just clobber SCRATCH. */
static void
-output_added_clobbers_hard_reg_p ()
+output_added_clobbers_hard_reg_p (void)
{
struct clobber_pat *clobber;
struct clobber_ent *ent;
int clobber_p, used;
- printf ("\n\nint\nadded_clobbers_hard_reg_p (insn_code_number)\n");
- printf (" int insn_code_number;\n");
+ printf ("\n\nint\nadded_clobbers_hard_reg_p (int insn_code_number)\n");
printf ("{\n");
printf (" switch (insn_code_number)\n");
printf (" {\n");
@@ -759,8 +734,7 @@ output_added_clobbers_hard_reg_p ()
scratch registers used by the peephole2 pattern in SPLIT. */
static void
-output_peephole2_scratches (split)
- rtx split;
+output_peephole2_scratches (rtx split)
{
int i;
int insn_nr = 0;
@@ -786,7 +760,7 @@ output_peephole2_scratches (split)
cur_insn_nr++;
printf (" if ((operands[%d] = peep2_find_free_register (%d, %d, \"%s\", %smode, &_regs_allocated)) == NULL_RTX)\n\
- return NULL;\n",
+ return NULL;\n",
XINT (elt, 0),
insn_nr, last_insn_nr,
XSTR (elt, 1),
@@ -798,12 +772,8 @@ output_peephole2_scratches (split)
}
}
-extern int main PARAMS ((int, char **));
-
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
rtx desc;
@@ -826,6 +796,8 @@ from the machine description file `md'. */\n\n");
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
+ printf ("#include \"coretypes.h\"\n");
+ printf ("#include \"tm.h\"\n");
printf ("#include \"rtl.h\"\n");
printf ("#include \"tm_p.h\"\n");
printf ("#include \"function.h\"\n");
@@ -892,8 +864,7 @@ from the machine description file `md'. */\n\n");
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
const char *
-get_insn_name (code)
- int code ATTRIBUTE_UNUSED;
+get_insn_name (int code ATTRIBUTE_UNUSED)
{
return NULL;
}
diff --git a/contrib/gcc/genextract.c b/contrib/gcc/genextract.c
index d52fc36f2d01..54be0ebeccc5 100644
--- a/contrib/gcc/genextract.c
+++ b/contrib/gcc/genextract.c
@@ -1,6 +1,6 @@
/* Generate code from machine description to extract operands from insn as rtl.
- Copyright (C) 1987, 1991, 1992, 1993, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1991, 1992, 1993, 1997, 1998, 1999, 2000, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,8 +20,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "insn-config.h"
@@ -29,7 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* This structure contains all the information needed to describe one
- set of extractions methods. Each method may be used by more than
+ set of extractions methods. Each method may be used by more than
one pattern if the operands are in the same place.
The string for each operand describes that path to the operand and
@@ -93,14 +95,13 @@ static int dupnums[MAX_DUP_OPERANDS];
static struct code_ptr *peepholes;
-static void gen_insn PARAMS ((rtx));
-static void walk_rtx PARAMS ((rtx, const char *));
-static void print_path PARAMS ((const char *));
-static void record_insn_name PARAMS ((int, const char *));
+static void gen_insn (rtx);
+static void walk_rtx (rtx, const char *);
+static void print_path (const char *);
+static void record_insn_name (int, const char *);
static void
-gen_insn (insn)
- rtx insn;
+gen_insn (rtx insn)
{
int i;
struct extraction *p;
@@ -128,7 +129,7 @@ gen_insn (insn)
walk_rtx (XVECEXP (insn, 1, i), path);
}
- link = (struct code_ptr *) xmalloc (sizeof (struct code_ptr));
+ link = xmalloc (sizeof (struct code_ptr));
link->insn_code = insn_code_number;
/* See if we find something that already had this extraction method. */
@@ -163,7 +164,7 @@ gen_insn (insn)
/* Otherwise, make a new extraction method. */
- p = (struct extraction *) xmalloc (sizeof (struct extraction));
+ p = xmalloc (sizeof (struct extraction));
p->op_count = op_count;
p->dup_count = dup_count;
p->next = extractions;
@@ -179,9 +180,7 @@ gen_insn (insn)
}
static void
-walk_rtx (x, path)
- rtx x;
- const char *path;
+walk_rtx (rtx x, const char *path)
{
RTX_CODE code;
int i;
@@ -220,11 +219,11 @@ walk_rtx (x, path)
duplocs[dup_count] = xstrdup (path);
dupnums[dup_count] = XINT (x, 0);
dup_count++;
-
- newpath = (char *) xmalloc (depth + 2);
+
+ newpath = xmalloc (depth + 2);
strcpy (newpath, path);
newpath[depth + 1] = 0;
-
+
for (i = XVECLEN (x, 1) - 1; i >= 0; i--)
{
newpath[depth] = (code == MATCH_OP_DUP ? '0' : 'a') + i;
@@ -232,12 +231,12 @@ walk_rtx (x, path)
}
free (newpath);
return;
-
+
case MATCH_OPERATOR:
oplocs[XINT (x, 0)] = xstrdup (path);
op_count = MAX (op_count, XINT (x, 0) + 1);
- newpath = (char *) xmalloc (depth + 2);
+ newpath = xmalloc (depth + 2);
strcpy (newpath, path);
newpath[depth + 1] = 0;
@@ -253,7 +252,7 @@ walk_rtx (x, path)
oplocs[XINT (x, 0)] = xstrdup (path);
op_count = MAX (op_count, XINT (x, 0) + 1);
- newpath = (char *) xmalloc (depth + 2);
+ newpath = xmalloc (depth + 2);
strcpy (newpath, path);
newpath[depth + 1] = 0;
@@ -273,7 +272,7 @@ walk_rtx (x, path)
break;
}
- newpath = (char *) xmalloc (depth + 2);
+ newpath = xmalloc (depth + 2);
strcpy (newpath, path);
newpath[depth + 1] = 0;
@@ -304,8 +303,7 @@ walk_rtx (x, path)
evaluate to the rtx at that point. */
static void
-print_path (path)
- const char *path;
+print_path (const char *path)
{
int len = strlen (path);
int i;
@@ -321,7 +319,7 @@ print_path (path)
/* We first write out the operations (XEXP or XVECEXP) in reverse
order, then write "insn", then the indices in forward order. */
- for (i = len - 1; i >=0 ; i--)
+ for (i = len - 1; i >= 0 ; i--)
{
if (ISLOWER(path[i]))
printf ("XVECEXP (");
@@ -330,7 +328,7 @@ print_path (path)
else
abort ();
}
-
+
printf ("pat");
for (i = 0; i < len; i++)
@@ -344,12 +342,9 @@ print_path (path)
}
}
-extern int main PARAMS ((int, char **));
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
rtx desc;
int i;
@@ -375,6 +370,8 @@ from the machine description file `md'. */\n\n");
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
+ printf ("#include \"coretypes.h\"\n");
+ printf ("#include \"tm.h\"\n");
printf ("#include \"rtl.h\"\n");
printf ("#include \"insn-config.h\"\n");
printf ("#include \"recog.h\"\n");
@@ -384,15 +381,16 @@ from the machine description file `md'. */\n\n");
of any missing operand whose numbers are skipped by a given pattern. */
printf ("static rtx junk ATTRIBUTE_UNUSED;\n");
- printf ("void\ninsn_extract (insn)\n");
- printf (" rtx insn;\n");
+ printf ("void\ninsn_extract (rtx insn)\n");
printf ("{\n");
printf (" rtx *ro = recog_data.operand;\n");
printf (" rtx **ro_loc = recog_data.operand_loc;\n");
printf (" rtx pat = PATTERN (insn);\n");
printf (" int i ATTRIBUTE_UNUSED;\n\n");
- printf (" memset (ro, 0, sizeof (*ro) * MAX_RECOG_OPERANDS);\n");
- printf (" memset (ro_loc, 0, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n");
+#ifdef ENABLE_CHECKING
+ printf (" memset (ro, 0xab, sizeof (*ro) * MAX_RECOG_OPERANDS);\n");
+ printf (" memset (ro_loc, 0xab, sizeof (*ro_loc) * MAX_RECOG_OPERANDS);\n");
+#endif
printf (" switch (INSN_CODE (insn))\n");
printf (" {\n");
printf (" case -1:\n");
@@ -416,8 +414,7 @@ from the machine description file `md'. */\n\n");
else if (GET_CODE (desc) == DEFINE_PEEPHOLE)
{
- struct code_ptr *link
- = (struct code_ptr *) xmalloc (sizeof (struct code_ptr));
+ struct code_ptr *link = xmalloc (sizeof (struct code_ptr));
link->insn_code = insn_code_number;
link->next = peepholes;
@@ -454,7 +451,7 @@ from the machine description file `md'. */\n\n");
else
printf (" case %d:\n", i);
}
-
+
for (i = 0; i < p->op_count; i++)
{
if (p->oplocs[i] == 0)
@@ -494,8 +491,7 @@ from the machine description file `md'. */\n\n");
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
const char *
-get_insn_name (code)
- int code ATTRIBUTE_UNUSED;
+get_insn_name (int code ATTRIBUTE_UNUSED)
{
if (code < insn_name_ptr_size)
return insn_name_ptr[code];
@@ -504,9 +500,7 @@ get_insn_name (code)
}
static void
-record_insn_name (code, name)
- int code;
- const char *name;
+record_insn_name (int code, const char *name)
{
static const char *last_real_name = "insn";
static int last_real_code = 0;
@@ -516,9 +510,8 @@ record_insn_name (code, name)
{
int new_size;
new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
- insn_name_ptr =
- (char **) xrealloc (insn_name_ptr, sizeof(char *) * new_size);
- memset (insn_name_ptr + insn_name_ptr_size, 0,
+ insn_name_ptr = xrealloc (insn_name_ptr, sizeof(char *) * new_size);
+ memset (insn_name_ptr + insn_name_ptr_size, 0,
sizeof(char *) * (new_size - insn_name_ptr_size));
insn_name_ptr_size = new_size;
}
@@ -533,6 +526,6 @@ record_insn_name (code, name)
last_real_name = new = xstrdup (name);
last_real_code = code;
}
-
+
insn_name_ptr[code] = new;
-}
+}
diff --git a/contrib/gcc/genflags.c b/contrib/gcc/genflags.c
index 948068167627..d3102739d881 100644
--- a/contrib/gcc/genflags.c
+++ b/contrib/gcc/genflags.c
@@ -2,7 +2,7 @@
- some flags HAVE_... saying which simple standard instructions are
available for this machine.
Copyright (C) 1987, 1991, 1995, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,8 +22,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "obstack.h"
#include "errors.h"
@@ -38,17 +40,16 @@ static int max_id_len;
/* Max operand encountered in a scan over some insn. */
static int max_opno;
-static void max_operand_1 PARAMS ((rtx));
-static int num_operands PARAMS ((rtx));
-static void gen_proto PARAMS ((rtx));
-static void gen_macro PARAMS ((const char *, int, int));
-static void gen_insn PARAMS ((rtx));
+static void max_operand_1 (rtx);
+static int num_operands (rtx);
+static void gen_proto (rtx);
+static void gen_macro (const char *, int, int);
+static void gen_insn (rtx);
/* Count the number of match_operand's found. */
static void
-max_operand_1 (x)
- rtx x;
+max_operand_1 (rtx x)
{
RTX_CODE code;
int i;
@@ -80,8 +81,7 @@ max_operand_1 (x)
}
static int
-num_operands (insn)
- rtx insn;
+num_operands (rtx insn)
{
int len = XVECLEN (insn, 1);
int i;
@@ -98,9 +98,7 @@ num_operands (insn)
of arguments it takes. Any missing arguments are assumed to be at
the end. */
static void
-gen_macro (name, real, expect)
- const char *name;
- int real, expect;
+gen_macro (const char *name, int real, int expect)
{
int i;
@@ -129,8 +127,7 @@ gen_macro (name, real, expect)
does nothing. */
static void
-gen_proto (insn)
- rtx insn;
+gen_proto (rtx insn)
{
int num = num_operands (insn);
int i;
@@ -157,9 +154,9 @@ gen_proto (insn)
}
if (truth != 0)
- printf ("extern rtx gen_%-*s PARAMS ((", max_id_len, name);
+ printf ("extern rtx gen_%-*s (", max_id_len, name);
else
- printf ("static inline rtx gen_%-*s PARAMS ((", max_id_len, name);
+ printf ("static inline rtx gen_%-*s (", max_id_len, name);
if (num == 0)
fputs ("void", stdout);
@@ -167,11 +164,11 @@ gen_proto (insn)
{
for (i = 1; i < num; i++)
fputs ("rtx, ", stdout);
-
+
fputs ("rtx", stdout);
}
- puts ("));");
+ puts (");");
/* Some back ends want to take the address of generator functions,
so we cannot simply use #define for these dummy definitions. */
@@ -182,21 +179,18 @@ gen_proto (insn)
{
putchar ('(');
for (i = 0; i < num-1; i++)
- printf ("%c, ", 'a' + i);
- printf ("%c)\n", 'a' + i);
- for (i = 0; i < num; i++)
- printf (" rtx %c ATTRIBUTE_UNUSED;\n", 'a' + i);
+ printf ("rtx %c ATTRIBUTE_UNUSED, ", 'a' + i);
+ printf ("rtx %c ATTRIBUTE_UNUSED)\n", 'a' + i);
}
else
- puts ("()");
+ puts ("(void)");
puts ("{\n return 0;\n}");
}
}
static void
-gen_insn (insn)
- rtx insn;
+gen_insn (rtx insn)
{
const char *name = XSTR (insn, 0);
const char *p;
@@ -215,7 +209,7 @@ gen_insn (insn)
max_id_len = len;
if (truth == 0)
- /* emit nothing */;
+ /* Emit nothing. */;
else if (truth == 1)
printf ("#define HAVE_%s 1\n", name);
else
@@ -236,12 +230,8 @@ gen_insn (insn)
obstack_grow (&obstack, &insn, sizeof (rtx));
}
-extern int main PARAMS ((int, char **));
-
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
rtx desc;
rtx dummy;
@@ -260,7 +250,7 @@ main (argc, argv)
if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
return (FATAL_EXIT_CODE);
-
+
puts ("/* Generated automatically by the program `genflags'");
puts (" from the machine description file `md'. */\n");
puts ("#ifndef GCC_INSN_FLAGS_H");
@@ -297,8 +287,7 @@ main (argc, argv)
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
const char *
-get_insn_name (code)
- int code ATTRIBUTE_UNUSED;
+get_insn_name (int code ATTRIBUTE_UNUSED)
{
return NULL;
}
diff --git a/contrib/gcc/gengenrtl.c b/contrib/gcc/gengenrtl.c
index 6bfd0ff77ee9..39f1dc26853f 100644
--- a/contrib/gcc/gengenrtl.c
+++ b/contrib/gcc/gengenrtl.c
@@ -1,5 +1,6 @@
/* Generate code to allocate RTL structures.
- Copyright (C) 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -19,47 +20,46 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
-#define NO_GENRTL_H
-#include "rtl.h"
-#undef abort
-
-#include "real.h"
-
struct rtx_definition
{
const char *const enumname, *const name, *const format;
};
-#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { STRINGX(ENUM), NAME, FORMAT },
+/* rtl.def needs CONST_DOUBLE_FORMAT, but we don't care what
+ CONST_DOUBLE_FORMAT is because we're not going to be generating
+ anything for CONST_DOUBLE anyway. */
+#define CONST_DOUBLE_FORMAT ""
+
+#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { #ENUM, NAME, FORMAT },
static const struct rtx_definition defs[] =
{
#include "rtl.def" /* rtl expressions are documented here */
};
+#define NUM_RTX_CODE ARRAY_SIZE(defs)
static const char *formats[NUM_RTX_CODE];
-static const char *type_from_format PARAMS ((int));
-static const char *accessor_from_format PARAMS ((int));
-static int special_format PARAMS ((const char *));
-static int special_rtx PARAMS ((int));
-static int excluded_rtx PARAMS ((int));
-static void find_formats PARAMS ((void));
-static void gendecl PARAMS ((const char *));
-static void genmacro PARAMS ((int));
-static void gendef PARAMS ((const char *));
-static void genlegend PARAMS ((void));
-static void genheader PARAMS ((void));
-static void gencode PARAMS ((void));
+static const char *type_from_format (int);
+static const char *accessor_from_format (int);
+static int special_format (const char *);
+static int special_rtx (int);
+static int excluded_rtx (int);
+static void find_formats (void);
+static void gendecl (const char *);
+static void genmacro (int);
+static void gendef (const char *);
+static void genlegend (void);
+static void genheader (void);
+static void gencode (void);
/* Decode a format letter into a C type string. */
static const char *
-type_from_format (c)
- int c;
+type_from_format (int c)
{
switch (c)
{
@@ -91,8 +91,7 @@ type_from_format (c)
/* Decode a format letter into the proper accessor function. */
static const char *
-accessor_from_format (c)
- int c;
+accessor_from_format (int c)
{
switch (c)
{
@@ -129,8 +128,7 @@ accessor_from_format (c)
the list of formats we write routines to create. */
static int
-special_format (fmt)
- const char *fmt;
+special_format (const char *fmt)
{
return (strchr (fmt, '*') != 0
|| strchr (fmt, 'V') != 0
@@ -143,8 +141,7 @@ special_format (fmt)
is a wrapper in emit-rtl.c). */
static int
-special_rtx (idx)
- int idx;
+special_rtx (int idx)
{
return (strcmp (defs[idx].enumname, "CONST_INT") == 0
|| strcmp (defs[idx].enumname, "REG") == 0
@@ -158,8 +155,7 @@ special_rtx (idx)
cannot have the obvious interface). */
static int
-excluded_rtx (idx)
- int idx;
+excluded_rtx (int idx)
{
return (strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0);
}
@@ -167,9 +163,9 @@ excluded_rtx (idx)
/* Place a list of all format specifiers we use into the array FORMAT. */
static void
-find_formats ()
+find_formats (void)
{
- int i;
+ unsigned int i;
for (i = 0; i < NUM_RTX_CODE; i++)
{
@@ -190,13 +186,12 @@ find_formats ()
/* Write the declarations for the routine to allocate RTL with FORMAT. */
static void
-gendecl (format)
- const char *format;
+gendecl (const char *format)
{
const char *p;
int i, pos;
- printf ("extern rtx gen_rtx_fmt_%s\tPARAMS ((RTX_CODE, ", format);
+ printf ("extern rtx gen_rtx_fmt_%s\t (RTX_CODE, ", format);
printf ("enum machine_mode mode");
/* Write each parameter that is needed and start a new line when the line
@@ -214,15 +209,14 @@ gendecl (format)
pos += ourlen;
}
- printf ("));\n");
+ printf (");\n");
}
/* Generate macros to generate RTL of code IDX using the functions we
write. */
static void
-genmacro (idx)
- int idx;
+genmacro (int idx)
{
const char *p;
int i;
@@ -255,8 +249,7 @@ genmacro (idx)
format is FORMAT. */
static void
-gendef (format)
- const char *format;
+gendef (const char *format)
{
const char *p;
int i, j;
@@ -264,23 +257,20 @@ gendef (format)
/* Start by writing the definition of the function name and the types
of the arguments. */
- printf ("rtx\ngen_rtx_fmt_%s (code, mode", format);
+ printf ("rtx\ngen_rtx_fmt_%s (RTX_CODE code, enum machine_mode mode", format);
for (p = format, i = 0; *p != 0; p++)
if (*p != '0')
- printf (", arg%d", i++);
+ printf (",\n\t%sarg%d", type_from_format (*p), i++);
- puts (")\n RTX_CODE code;\n enum machine_mode mode;");
- for (p = format, i = 0; *p != 0; p++)
- if (*p != '0')
- printf (" %sarg%d;\n", type_from_format (*p), i++);
+ puts (")");
/* Now write out the body of the function itself, which allocates
the memory and initializes it. */
puts ("{");
puts (" rtx rt;");
- printf (" rt = ggc_alloc_rtx (%d);\n", (int) strlen (format));
+ puts (" rt = ggc_alloc_rtx (code);\n");
- puts (" memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));\n");
+ puts (" memset (rt, 0, RTX_HDR_SIZE);\n");
puts (" PUT_CODE (rt, code);");
puts (" PUT_MODE (rt, mode);");
@@ -296,7 +286,7 @@ gendef (format)
/* Generate the documentation header for files we write. */
static void
-genlegend ()
+genlegend (void)
{
puts ("/* Generated automatically by gengenrtl from rtl.def. */\n");
}
@@ -304,9 +294,9 @@ genlegend ()
/* Generate the text of the header file we make, genrtl.h. */
static void
-genheader ()
+genheader (void)
{
- int i;
+ unsigned int i;
const char **fmt;
puts ("#ifndef GCC_GENRTL_H");
@@ -327,16 +317,17 @@ genheader ()
/* Generate the text of the code file we write, genrtl.c. */
static void
-gencode ()
+gencode (void)
{
const char **fmt;
puts ("#include \"config.h\"");
puts ("#include \"system.h\"");
+ puts ("#include \"coretypes.h\"");
+ puts ("#include \"tm.h\"");
puts ("#include \"obstack.h\"");
puts ("#include \"rtl.h\"");
puts ("#include \"ggc.h\"\n");
- puts ("extern struct obstack *rtl_obstack;\n");
for (fmt = formats; *fmt != 0; fmt++)
gendef (*fmt);
@@ -345,12 +336,9 @@ gencode ()
/* This is the main program. We accept only one argument, "-h", which
says we are writing the genrtl.h file. Otherwise we are writing the
genrtl.c file. */
-extern int main PARAMS ((int, char **));
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
find_formats ();
genlegend ();
diff --git a/contrib/gcc/gengtype-lex.l b/contrib/gcc/gengtype-lex.l
index 38e470de468d..2d0462beba5d 100644
--- a/contrib/gcc/gengtype-lex.l
+++ b/contrib/gcc/gengtype-lex.l
@@ -1,6 +1,6 @@
/* -*- indented-text -*- */
/* Process source files and output type information.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,7 +20,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
%{
-#include "hconfig.h"
+#include "bconfig.h"
+#include "coretypes.h"
#include "system.h"
#define malloc xmalloc
@@ -29,18 +30,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "gengtype.h"
#include "gengtype-yacc.h"
-#undef YY_USE_PROTOS
-#define YY_DECL int yylex ()
-
-static void update_lineno PARAMS ((const char *l, size_t len));
+static void update_lineno (const char *l, size_t len);
struct fileloc lexer_line;
int lexer_toplevel_done;
static void
-update_lineno (l, len)
- const char *l;
- size_t len;
+update_lineno (const char *l, size_t len)
{
while (len-- > 0)
if (*l++ == '\n')
@@ -51,7 +47,7 @@ update_lineno (l, len)
ID [[:alpha:]_][[:alnum:]_]*
WS [[:space:]]+
-IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|bool|size_t
+IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|bool|size_t|BOOL_BITFIELD
ITYPE {IWORD}({WS}{IWORD})*
%x in_struct in_struct_comment in_comment in_yacc_escape
@@ -133,7 +129,24 @@ ITYPE {IWORD}({WS}{IWORD})*
do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
update_lineno (yytext, yyleng);
}
-[^[:alnum:]_]typedef{WS}{ID}{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
+
+[^[:alnum:]_]typedef{WS}{ID}{WS}{ID}{WS}"(" {
+ char *namestart;
+ size_t namelen;
+ struct type *t;
+
+ for (namestart = yytext + yyleng - 2; ISSPACE (*namestart); namestart--)
+ ;
+ for (namelen = 1; !ISSPACE (namestart[-namelen]); namelen++)
+ ;
+ namestart -= namelen - 1;
+
+ t = create_scalar_type ("function type", sizeof ("function type")-1);
+ do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
+ update_lineno (yytext, yyleng);
+}
+
+[^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?PARAMS {
char *namestart;
size_t namelen;
struct type *t;
@@ -149,6 +162,22 @@ ITYPE {IWORD}({WS}{IWORD})*
update_lineno (yytext, yyleng);
}
+[^[:alnum:]_]typedef{WS}{ID}{WS}?"*"?{WS}?"("{WS}?"*"{WS}?{ID}{WS}?")"{WS}?"(" {
+ char *namestart;
+ size_t namelen;
+ struct type *t;
+
+ for (namestart = yytext + yyleng - 2; !ISIDNUM (*namestart); namestart--)
+ ;
+ for (namelen = 1; ISIDNUM (namestart[-namelen]); namelen++)
+ ;
+ namestart -= namelen - 1;
+
+ t = create_scalar_type ("function type", sizeof ("function type")-1);
+ do_typedef (xmemdup (namestart, namelen, namelen+1), t, &lexer_line);
+ update_lineno (yytext, yyleng);
+}
+
[^[:alnum:]_](typedef{WS})?(struct|union){WS}{ID}{WS}/"GTY" {
char *tagstart;
size_t taglen;
@@ -195,6 +224,8 @@ ITYPE {IWORD}({WS}{IWORD})*
^"%{" { BEGIN(in_yacc_escape); }
+^"@@".* /* Used for c-parse.in C/ObjC demarcation. */
+
{WS} { update_lineno (yytext, yyleng); }
"const"/[^[:alnum:]_] /* don't care */
@@ -304,15 +335,13 @@ ITYPE {IWORD}({WS}{IWORD})*
%%
void
-yyerror (s)
- const char *s;
+yyerror (const char *s)
{
error_at_line (&lexer_line, s);
}
void
-parse_file (fname)
- const char *fname;
+parse_file (const char *fname)
{
yyin = fopen (fname, "r");
lexer_line.file = fname;
diff --git a/contrib/gcc/gengtype-yacc.y b/contrib/gcc/gengtype-yacc.y
index 9ccea1a20336..928c962a584f 100644
--- a/contrib/gcc/gengtype-yacc.y
+++ b/contrib/gcc/gengtype-yacc.y
@@ -20,8 +20,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
%{
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "gengtype.h"
#define YYERROR_VERBOSE
%}
diff --git a/contrib/gcc/gengtype.c b/contrib/gcc/gengtype.c
index dbd8995774b3..1e1b09593606 100644
--- a/contrib/gcc/gengtype.c
+++ b/contrib/gcc/gengtype.c
@@ -1,5 +1,5 @@
/* Process source files and output type information.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -18,42 +18,45 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "gengtype.h"
#include "gtyp-gen.h"
+#define NO_GENRTL_H
+#include "rtl.h"
+#undef abort
+
/* Nonzero iff an error has occurred. */
static int hit_error = 0;
-static void gen_rtx_next PARAMS ((void));
-static void write_rtx_next PARAMS ((void));
-static void open_base_files PARAMS ((void));
-static void close_output_files PARAMS ((void));
+static void gen_rtx_next (void);
+static void write_rtx_next (void);
+static void open_base_files (void);
+static void close_output_files (void);
/* Report an error at POS, printing MSG. */
void
-error_at_line VPARAMS ((struct fileloc *pos, const char *msg, ...))
+error_at_line (struct fileloc *pos, const char *msg, ...)
{
- VA_OPEN (ap, msg);
- VA_FIXEDARG (ap, struct fileloc *, pos);
- VA_FIXEDARG (ap, const char *, msg);
+ va_list ap;
+
+ va_start (ap, msg);
fprintf (stderr, "%s:%d: ", pos->file, pos->line);
vfprintf (stderr, msg, ap);
fputc ('\n', stderr);
hit_error = 1;
- VA_CLOSE (ap);
+ va_end (ap);
}
/* vasprintf, but produces fatal message on out-of-memory. */
int
-xvasprintf (result, format, args)
- char ** result;
- const char *format;
- va_list args;
+xvasprintf (char **result, const char *format, va_list args)
{
int ret = vasprintf (result, format, args);
if (*result == NULL || ret < 0)
@@ -66,22 +69,22 @@ xvasprintf (result, format, args)
/* Wrapper for xvasprintf. */
char *
-xasprintf VPARAMS ((const char *format, ...))
+xasprintf (const char *format, ...)
{
char *result;
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
+ va_list ap;
+
+ va_start (ap, format);
xvasprintf (&result, format, ap);
- VA_CLOSE (ap);
+ va_end (ap);
return result;
}
/* The one and only TYPE_STRING. */
struct type string_type = {
- TYPE_STRING, NULL, NULL, GC_USED
- UNION_INIT_ZERO
-};
+ TYPE_STRING, NULL, NULL, GC_USED, {0}
+};
/* Lists of various things. */
@@ -90,19 +93,16 @@ static type_p structures;
static type_p param_structs;
static pair_p variables;
-static void do_scalar_typedef PARAMS ((const char *, struct fileloc *));
-static type_p find_param_structure
- PARAMS ((type_p t, type_p param[NUM_PARAM]));
-static type_p adjust_field_tree_exp PARAMS ((type_p t, options_p opt));
-static type_p adjust_field_rtx_def PARAMS ((type_p t, options_p opt));
+static void do_scalar_typedef (const char *, struct fileloc *);
+static type_p find_param_structure
+ (type_p t, type_p param[NUM_PARAM]);
+static type_p adjust_field_tree_exp (type_p t, options_p opt);
+static type_p adjust_field_rtx_def (type_p t, options_p opt);
/* Define S as a typedef to T at POS. */
void
-do_typedef (s, t, pos)
- const char *s;
- type_p t;
- struct fileloc *pos;
+do_typedef (const char *s, type_p t, struct fileloc *pos)
{
pair_p p;
@@ -128,9 +128,7 @@ do_typedef (s, t, pos)
/* Define S as a typename of a scalar. */
static void
-do_scalar_typedef (s, pos)
- const char *s;
- struct fileloc *pos;
+do_scalar_typedef (const char *s, struct fileloc *pos)
{
do_typedef (s, create_scalar_type (s, strlen (s)), pos);
}
@@ -138,9 +136,7 @@ do_scalar_typedef (s, pos)
/* Return the type previously defined for S. Use POS to report errors. */
type_p
-resolve_typedef (s, pos)
- const char *s;
- struct fileloc *pos;
+resolve_typedef (const char *s, struct fileloc *pos)
{
pair_p p;
for (p = typedefs; p != NULL; p = p->next)
@@ -154,26 +150,22 @@ resolve_typedef (s, pos)
at POS with fields FIELDS and options O. */
void
-new_structure (name, isunion, pos, fields, o)
- const char *name;
- int isunion;
- struct fileloc *pos;
- pair_p fields;
- options_p o;
+new_structure (const char *name, int isunion, struct fileloc *pos,
+ pair_p fields, options_p o)
{
type_p si;
type_p s = NULL;
lang_bitmap bitmap = get_base_file_bitmap (pos->file);
for (si = structures; si != NULL; si = si->next)
- if (strcmp (name, si->u.s.tag) == 0
+ if (strcmp (name, si->u.s.tag) == 0
&& UNION_P (si) == isunion)
{
type_p ls = NULL;
if (si->kind == TYPE_LANG_STRUCT)
{
ls = si;
-
+
for (si = ls->u.s.lang_struct; si != NULL; si = si->next)
if (si->u.s.bitmap == bitmap)
s = si;
@@ -202,7 +194,7 @@ new_structure (name, isunion, pos, fields, o)
}
break;
}
-
+
if (s == NULL)
{
s = xcalloc (1, sizeof (struct type));
@@ -232,14 +224,12 @@ new_structure (name, isunion, pos, fields, o)
was defined previously. */
type_p
-find_structure (name, isunion)
- const char *name;
- int isunion;
+find_structure (const char *name, int isunion)
{
type_p s;
for (s = structures; s != NULL; s = s->next)
- if (strcmp (name, s->u.s.tag) == 0
+ if (strcmp (name, s->u.s.tag) == 0
&& UNION_P (s) == isunion)
return s;
@@ -252,20 +242,18 @@ find_structure (name, isunion)
return s;
}
-/* Return the previously-defined parameterised structure for structure
- T and parameters PARAM, or a new parameterised empty structure or
+/* Return the previously-defined parameterized structure for structure
+ T and parameters PARAM, or a new parameterized empty structure or
union if none was defined previously. */
static type_p
-find_param_structure (t, param)
- type_p t;
- type_p param[NUM_PARAM];
+find_param_structure (type_p t, type_p param[NUM_PARAM])
{
type_p res;
-
+
for (res = param_structs; res; res = res->next)
if (res->u.param_struct.stru == t
- && memcmp (res->u.param_struct.param, param,
+ && memcmp (res->u.param_struct.param, param,
sizeof (type_p) * NUM_PARAM) == 0)
break;
if (res == NULL)
@@ -283,9 +271,7 @@ find_param_structure (t, param)
/* Return a scalar type with name NAME. */
type_p
-create_scalar_type (name, name_len)
- const char *name;
- size_t name_len;
+create_scalar_type (const char *name, size_t name_len)
{
type_p r = xcalloc (1, sizeof (struct type));
r->kind = TYPE_SCALAR;
@@ -296,8 +282,7 @@ create_scalar_type (name, name_len)
/* Return a pointer to T. */
type_p
-create_pointer (t)
- type_p t;
+create_pointer (type_p t)
{
if (! t->pointer_to)
{
@@ -312,12 +297,10 @@ create_pointer (t)
/* Return an array of length LEN. */
type_p
-create_array (t, len)
- type_p t;
- const char *len;
+create_array (type_p t, const char *len)
{
type_p v;
-
+
v = xcalloc (1, sizeof (*v));
v->kind = TYPE_ARRAY;
v->u.a.p = t;
@@ -329,11 +312,7 @@ create_array (t, len)
to `variables'. */
void
-note_variable (s, t, o, pos)
- const char *s;
- type_p t;
- options_p o;
- struct fileloc *pos;
+note_variable (const char *s, type_p t, options_p o, struct fileloc *pos)
{
pair_p n;
n = xmalloc (sizeof (*n));
@@ -345,62 +324,55 @@ note_variable (s, t, o, pos)
variables = n;
}
-enum rtx_code {
-#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
-#include "rtl.def"
-#undef DEF_RTL_EXPR
- NUM_RTX_CODE
-};
-
/* We really don't care how long a CONST_DOUBLE is. */
#define CONST_DOUBLE_FORMAT "ww"
-static const char * const rtx_format[NUM_RTX_CODE] = {
+const char * const rtx_format[NUM_RTX_CODE] = {
#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
#include "rtl.def"
#undef DEF_RTL_EXPR
};
-static int rtx_next[NUM_RTX_CODE];
+static int rtx_next_new[NUM_RTX_CODE];
/* Generate the contents of the rtx_next array. This really doesn't belong
in gengtype at all, but it's needed for adjust_field_rtx_def. */
static void
-gen_rtx_next ()
+gen_rtx_next (void)
{
int i;
for (i = 0; i < NUM_RTX_CODE; i++)
{
int k;
-
- rtx_next[i] = -1;
+
+ rtx_next_new[i] = -1;
if (strncmp (rtx_format[i], "iuu", 3) == 0)
- rtx_next[i] = 2;
+ rtx_next_new[i] = 2;
else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
- rtx_next[i] = 1;
- else
+ rtx_next_new[i] = 1;
+ else
for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
- rtx_next[i] = k;
+ rtx_next_new[i] = k;
}
}
/* Write out the contents of the rtx_next array. */
static void
-write_rtx_next ()
+write_rtx_next (void)
{
outf_p f = get_output_file_with_visibility (NULL);
int i;
-
+
oprintf (f, "\n/* Used to implement the RTX_NEXT macro. */\n");
oprintf (f, "const unsigned char rtx_next[NUM_RTX_CODE] = {\n");
for (i = 0; i < NUM_RTX_CODE; i++)
- if (rtx_next[i] == -1)
+ if (rtx_next_new[i] == -1)
oprintf (f, " 0,\n");
else
- oprintf (f,
- " offsetof (struct rtx_def, fld) + %d * sizeof (rtunion),\n",
- rtx_next[i]);
+ oprintf (f,
+ " RTX_HDR_SIZE + %d * sizeof (rtunion),\n",
+ rtx_next_new[i]);
oprintf (f, "};\n");
}
@@ -409,29 +381,27 @@ write_rtx_next ()
are based in a complex way on the type of RTL. */
static type_p
-adjust_field_rtx_def (t, opt)
- type_p t;
- options_p opt ATTRIBUTE_UNUSED;
+adjust_field_rtx_def (type_p t, options_p opt ATTRIBUTE_UNUSED)
{
pair_p flds = NULL;
options_p nodot;
int i;
type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
- type_p bitmap_tp, basic_block_tp;
+ type_p bitmap_tp, basic_block_tp, reg_attrs_tp;
static const char * const rtx_name[NUM_RTX_CODE] = {
#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
#include "rtl.def"
#undef DEF_RTL_EXPR
};
-
- if (t->kind != TYPE_ARRAY)
+
+ if (t->kind != TYPE_UNION)
{
- error_at_line (&lexer_line,
- "special `rtx_def' must be applied to an array");
+ error_at_line (&lexer_line,
+ "special `rtx_def' must be applied to a union");
return &string_type;
}
-
+
nodot = xmalloc (sizeof (*nodot));
nodot->next = NULL;
nodot->name = "dot";
@@ -441,6 +411,7 @@ adjust_field_rtx_def (t, opt)
rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
tree_tp = create_pointer (find_structure ("tree_node", 1));
mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
+ reg_attrs_tp = create_pointer (find_structure ("reg_attrs", 0));
bitmap_tp = create_pointer (find_structure ("bitmap_element_def", 0));
basic_block_tp = create_pointer (find_structure ("basic_block_def", 0));
scalar_tp = create_scalar_type ("rtunion scalar", 14);
@@ -448,31 +419,50 @@ adjust_field_rtx_def (t, opt)
{
pair_p note_flds = NULL;
int c;
-
- for (c = 0; c < 3; c++)
+
+ for (c = NOTE_INSN_BIAS; c <= NOTE_INSN_MAX; c++)
{
pair_p old_note_flds = note_flds;
-
+
note_flds = xmalloc (sizeof (*note_flds));
note_flds->line.file = __FILE__;
note_flds->line.line = __LINE__;
- note_flds->name = "rttree";
- note_flds->type = tree_tp;
note_flds->opt = xmalloc (sizeof (*note_flds->opt));
note_flds->opt->next = nodot;
note_flds->opt->name = "tag";
+ note_flds->opt->info = xasprintf ("%d", c);
note_flds->next = old_note_flds;
+
+ switch (c)
+ {
+ /* NOTE_INSN_MAX is used as the default field for line
+ number notes. */
+ case NOTE_INSN_MAX:
+ note_flds->opt->name = "default";
+ note_flds->name = "rtstr";
+ note_flds->type = &string_type;
+ break;
+
+ case NOTE_INSN_BLOCK_BEG:
+ case NOTE_INSN_BLOCK_END:
+ note_flds->name = "rttree";
+ note_flds->type = tree_tp;
+ break;
+
+ case NOTE_INSN_EXPECTED_VALUE:
+ note_flds->name = "rtx";
+ note_flds->type = rtx_tp;
+ break;
+
+ default:
+ note_flds->name = "rtint";
+ note_flds->type = scalar_tp;
+ break;
+ }
}
-
- note_flds->type = rtx_tp;
- note_flds->name = "rtx";
- note_flds->opt->info = "NOTE_INSN_EXPECTED_VALUE";
- note_flds->next->opt->info = "NOTE_INSN_BLOCK_BEG";
- note_flds->next->next->opt->info = "NOTE_INSN_BLOCK_END";
-
new_structure ("rtx_def_note_subunion", 1, &lexer_line, note_flds, NULL);
}
-
+
note_union_tp = find_structure ("rtx_def_note_subunion", 1);
for (i = 0; i < NUM_RTX_CODE; i++)
@@ -521,20 +511,26 @@ adjust_field_rtx_def (t, opt)
t = scalar_tp, subname = "rtint";
else if (i == REG && aindex == 1)
t = scalar_tp, subname = "rtint";
+ else if (i == REG && aindex == 2)
+ t = reg_attrs_tp, subname = "rtreg";
else if (i == SCRATCH && aindex == 0)
t = scalar_tp, subname = "rtint";
+ else if (i == SYMBOL_REF && aindex == 1)
+ t = scalar_tp, subname = "rtint";
+ else if (i == SYMBOL_REF && aindex == 2)
+ t = tree_tp, subname = "rttree";
else if (i == BARRIER && aindex >= 3)
t = scalar_tp, subname = "rtint";
else
{
- error_at_line (&lexer_line,
+ error_at_line (&lexer_line,
"rtx type `%s' has `0' in position %lu, can't handle",
rtx_name[i], (unsigned long) aindex);
t = &string_type;
subname = "rtint";
}
break;
-
+
case 's':
case 'S':
case 'T':
@@ -570,7 +566,7 @@ adjust_field_rtx_def (t, opt)
break;
default:
- error_at_line (&lexer_line,
+ error_at_line (&lexer_line,
"rtx type `%s' has `%c' in position %lu, can't handle",
rtx_name[i], rtx_format[i][aindex],
(unsigned long)aindex);
@@ -582,7 +578,7 @@ adjust_field_rtx_def (t, opt)
subfields = xmalloc (sizeof (*subfields));
subfields->next = old_subf;
subfields->type = t;
- subfields->name = xasprintf ("[%lu].%s", (unsigned long)aindex,
+ subfields->name = xasprintf (".fld[%lu].%s", (unsigned long)aindex,
subname);
subfields->line.file = __FILE__;
subfields->line.line = __LINE__;
@@ -601,14 +597,6 @@ adjust_field_rtx_def (t, opt)
subfields->opt->name = "skip";
subfields->opt->info = NULL;
}
- else if ((size_t) rtx_next[i] == aindex)
- {
- /* The 'next' field will be marked by the chain_next option. */
- subfields->opt = xmalloc (sizeof (*subfields->opt));
- subfields->opt->next = nodot;
- subfields->opt->name = "skip";
- subfields->opt->info = NULL;
- }
else
subfields->opt = nodot;
}
@@ -636,14 +624,12 @@ adjust_field_rtx_def (t, opt)
/* Handle `special("tree_exp")'. This is a special case for
field `operands' of struct tree_exp, which although it claims to contain
- pointers to trees, actually sometimes contains pointers to RTL too.
+ pointers to trees, actually sometimes contains pointers to RTL too.
Passed T, the old type of the field, and OPT its options. Returns
a new type for the field. */
static type_p
-adjust_field_tree_exp (t, opt)
- type_p t;
- options_p opt ATTRIBUTE_UNUSED;
+adjust_field_tree_exp (type_p t, options_p opt ATTRIBUTE_UNUSED)
{
pair_p flds;
options_p nodot;
@@ -657,16 +643,15 @@ adjust_field_tree_exp (t, opt)
{ "GOTO_SUBROUTINE_EXPR", 0, 2 },
{ "RTL_EXPR", 0, 2 },
{ "WITH_CLEANUP_EXPR", 2, 1 },
- { "METHOD_CALL_EXPR", 3, 1 }
};
-
+
if (t->kind != TYPE_ARRAY)
{
- error_at_line (&lexer_line,
+ error_at_line (&lexer_line,
"special `tree_exp' must be applied to an array");
return &string_type;
}
-
+
nodot = xmalloc (sizeof (*nodot));
nodot->next = NULL;
nodot->name = "dot";
@@ -689,16 +674,16 @@ adjust_field_tree_exp (t, opt)
flds->opt->name = "default";
flds->opt->info = "";
}
-
+
for (i = 0; i < ARRAY_SIZE (data); i++)
{
pair_p old_flds = flds;
pair_p subfields = NULL;
int r_index;
const char *sname;
-
- for (r_index = 0;
- r_index < data[i].first_rtl + data[i].num_rtl;
+
+ for (r_index = 0;
+ r_index < data[i].first_rtl + data[i].num_rtl;
r_index++)
{
pair_p old_subf = subfields;
@@ -740,12 +725,10 @@ adjust_field_tree_exp (t, opt)
- Converts structures for which a parameter is provided to
TYPE_PARAM_STRUCT;
- Handles "special" options.
-*/
+*/
type_p
-adjust_field_type (t, opt)
- type_p t;
- options_p opt;
+adjust_field_type (type_p t, options_p opt)
{
int length_p = 0;
const int pointer_p = t->kind == TYPE_POINTER;
@@ -755,7 +738,7 @@ adjust_field_type (t, opt)
for (i = 0; i < NUM_PARAM; i++)
params[i] = NULL;
-
+
for (; opt; opt = opt->next)
if (strcmp (opt->name, "length") == 0)
length_p = 1;
@@ -769,7 +752,7 @@ adjust_field_type (t, opt)
if (! UNION_OR_STRUCT_P (t)
&& (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
{
- error_at_line (&lexer_line,
+ error_at_line (&lexer_line,
"option `%s' may only be applied to structures or structure pointers",
opt->name);
return t;
@@ -797,7 +780,7 @@ adjust_field_type (t, opt)
if (params_p)
{
type_p realt;
-
+
if (pointer_p)
t = t->u.p;
realt = find_param_structure (t, params);
@@ -820,23 +803,20 @@ adjust_field_type (t, opt)
}
/* Create a union for YYSTYPE, as yacc would do it, given a fieldlist FIELDS
- and information about the correspondance between token types and fields
+ and information about the correspondence between token types and fields
in TYPEINFO. POS is used for error messages. */
void
-note_yacc_type (o, fields, typeinfo, pos)
- options_p o;
- pair_p fields;
- pair_p typeinfo;
- struct fileloc *pos;
+note_yacc_type (options_p o, pair_p fields, pair_p typeinfo,
+ struct fileloc *pos)
{
pair_p p;
pair_p *p_p;
-
+
for (p = typeinfo; p; p = p->next)
{
pair_p m;
-
+
if (p->name == NULL)
continue;
@@ -844,7 +824,7 @@ note_yacc_type (o, fields, typeinfo, pos)
{
pair_p pp;
int ok = 0;
-
+
for (pp = typeinfo; pp; pp = pp->next)
if (pp->type != (type_p) 1
&& strcmp (pp->opt->info, p->opt->info) == 0)
@@ -861,12 +841,12 @@ note_yacc_type (o, fields, typeinfo, pos)
p->type = m->type;
if (p->type == NULL)
{
- error_at_line (&p->line,
+ error_at_line (&p->line,
"couldn't match fieldname `%s'", p->name);
p->name = NULL;
}
}
-
+
p_p = &typeinfo;
while (*p_p)
{
@@ -883,20 +863,16 @@ note_yacc_type (o, fields, typeinfo, pos)
do_typedef ("YYSTYPE", find_structure ("yy_union", 1), pos);
}
-static void process_gc_options PARAMS ((options_p, enum gc_used_enum,
- int *, int *, int *));
-static void set_gc_used_type PARAMS ((type_p, enum gc_used_enum, type_p *));
-static void set_gc_used PARAMS ((pair_p));
+static void process_gc_options (options_p, enum gc_used_enum,
+ int *, int *, int *);
+static void set_gc_used_type (type_p, enum gc_used_enum, type_p *);
+static void set_gc_used (pair_p);
/* Handle OPT for set_gc_used_type. */
static void
-process_gc_options (opt, level, maybe_undef, pass_param, length)
- options_p opt;
- enum gc_used_enum level;
- int *maybe_undef;
- int *pass_param;
- int *length;
+process_gc_options (options_p opt, enum gc_used_enum level, int *maybe_undef,
+ int *pass_param, int *length)
{
options_p o;
for (o = opt; o; o = o->next)
@@ -913,14 +889,11 @@ process_gc_options (opt, level, maybe_undef, pass_param, length)
/* Set the gc_used field of T to LEVEL, and handle the types it references. */
static void
-set_gc_used_type (t, level, param)
- type_p t;
- enum gc_used_enum level;
- type_p param[NUM_PARAM];
+set_gc_used_type (type_p t, enum gc_used_enum level, type_p param[NUM_PARAM])
{
if (t->gc_used >= level)
return;
-
+
t->gc_used = level;
switch (t->kind)
@@ -940,7 +913,7 @@ set_gc_used_type (t, level, param)
int length = 0;
process_gc_options (f->opt, level, &maybe_undef, &pass_param,
&length);
-
+
if (length && f->type->kind == TYPE_POINTER)
set_gc_used_type (f->type->u.p, GC_USED, NULL);
else if (maybe_undef && f->type->kind == TYPE_POINTER)
@@ -961,7 +934,7 @@ set_gc_used_type (t, level, param)
case TYPE_ARRAY:
set_gc_used_type (t->u.a.p, GC_USED, param);
break;
-
+
case TYPE_LANG_STRUCT:
for (t = t->u.s.lang_struct; t; t = t->next)
set_gc_used_type (t, level, param);
@@ -979,7 +952,7 @@ set_gc_used_type (t, level, param)
else
level = GC_USED;
t->u.param_struct.stru->gc_used = GC_UNUSED;
- set_gc_used_type (t->u.param_struct.stru, level,
+ set_gc_used_type (t->u.param_struct.stru, level,
t->u.param_struct.param);
break;
@@ -991,8 +964,7 @@ set_gc_used_type (t, level, param)
/* Set the gc_used fields of all the types pointed to by VARIABLES. */
static void
-set_gc_used (variables)
- pair_p variables;
+set_gc_used (pair_p variables)
{
pair_p p;
for (p = variables; p; p = p->next)
@@ -1022,19 +994,17 @@ static int srcdir_len = 0;
#define NUM_BASE_FILES (ARRAY_SIZE (lang_dir_names) - 1)
outf_p base_files[NUM_BASE_FILES];
-static outf_p create_file PARAMS ((const char *, const char *));
-static const char * get_file_basename PARAMS ((const char *));
+static outf_p create_file (const char *, const char *);
+static const char * get_file_basename (const char *);
/* Create and return an outf_p for a new file for NAME, to be called
ONAME. */
static outf_p
-create_file (name, oname)
- const char *name;
- const char *oname;
+create_file (const char *name, const char *oname)
{
static const char *const hdr[] = {
- " Copyright (C) 2002 Free Software Foundation, Inc.\n",
+ " Copyright (C) 2003 Free Software Foundation, Inc.\n",
"\n",
"This file is part of GCC.\n",
"\n",
@@ -1057,7 +1027,7 @@ create_file (name, oname)
};
outf_p f;
size_t i;
-
+
f = xcalloc (sizeof (*f), 1);
f->next = output_files;
f->name = oname;
@@ -1070,15 +1040,14 @@ create_file (name, oname)
}
/* Print, like fprintf, to O. */
-void
-oprintf VPARAMS ((outf_p o, const char *format, ...))
+void
+oprintf (outf_p o, const char *format, ...)
{
char *s;
size_t slength;
-
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, outf_p, o);
- VA_FIXEDARG (ap, const char *, format);
+ va_list ap;
+
+ va_start (ap, format);
slength = xvasprintf (&s, format, ap);
if (o->bufused + slength > o->buflength)
@@ -1095,36 +1064,36 @@ oprintf VPARAMS ((outf_p o, const char *format, ...))
memcpy (o->buf + o->bufused, s, slength);
o->bufused += slength;
free (s);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Open the global header file and the language-specific header files. */
static void
-open_base_files ()
+open_base_files (void)
{
size_t i;
-
+
header_file = create_file ("GCC", "gtype-desc.h");
for (i = 0; i < NUM_BASE_FILES; i++)
- base_files[i] = create_file (lang_dir_names[i],
+ base_files[i] = create_file (lang_dir_names[i],
xasprintf ("gtype-%s.h", lang_dir_names[i]));
/* gtype-desc.c is a little special, so we create it here. */
{
/* The order of files here matters very much. */
static const char *const ifiles [] = {
- "config.h", "system.h", "varray.h", "hashtab.h", "splay-tree.h",
- "bitmap.h", "tree.h", "rtl.h", "function.h", "insn-config.h",
- "expr.h", "hard-reg-set.h", "basic-block.h", "cselib.h",
- "insn-addr.h", "ssa.h", "optabs.h", "libfuncs.h",
- "debug.h", "ggc.h",
+ "config.h", "system.h", "coretypes.h", "tm.h", "varray.h",
+ "hashtab.h", "splay-tree.h", "bitmap.h", "tree.h", "rtl.h",
+ "function.h", "insn-config.h", "expr.h", "hard-reg-set.h",
+ "basic-block.h", "cselib.h", "insn-addr.h", "optabs.h",
+ "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
NULL
};
const char *const *ifp;
outf_p gtype_desc_c;
-
+
gtype_desc_c = create_file ("GCC", "gtype-desc.c");
for (ifp = ifiles; *ifp; ifp++)
oprintf (gtype_desc_c, "#include \"%s\"\n", *ifp);
@@ -1134,21 +1103,18 @@ open_base_files ()
/* Determine the pathname to F relative to $(srcdir). */
static const char *
-get_file_basename (f)
- const char *f;
+get_file_basename (const char *f)
{
- size_t len;
const char *basename;
unsigned i;
-
+
basename = strrchr (f, '/');
-
+
if (!basename)
return f;
-
- len = strlen (f);
+
basename++;
-
+
for (i = 1; i < NUM_BASE_FILES; i++)
{
const char * s1;
@@ -1167,12 +1133,12 @@ get_file_basename (f)
break;
}
}
-
+
return basename;
}
/* Return a bitmap which has bit `1 << BASE_FILE_<lang>' set iff
- INPUT_FILE is used by <lang>.
+ INPUT_FILE is used by <lang>.
This function should be written to assume that a file _is_ used
if the situation is unclear. If it wrongly assumes a file _is_ used,
@@ -1180,15 +1146,14 @@ get_file_basename (f)
some GC roots may be missed, which is a much harder-to-debug problem. */
unsigned
-get_base_file_bitmap (input_file)
- const char *input_file;
+get_base_file_bitmap (const char *input_file)
{
const char *basename = get_file_basename (input_file);
const char *slashpos = strchr (basename, '/');
unsigned j;
unsigned k;
unsigned bitmap;
-
+
if (slashpos)
{
size_t i;
@@ -1220,7 +1185,7 @@ get_base_file_bitmap (input_file)
}
}
}
-
+
/* Otherwise, set all languages. */
if (!bitmap)
bitmap = (1 << NUM_BASE_FILES) - 1;
@@ -1233,8 +1198,7 @@ get_base_file_bitmap (input_file)
INPUT_FILE. */
outf_p
-get_output_file_with_visibility (input_file)
- const char *input_file;
+get_output_file_with_visibility (const char *input_file)
{
outf_p r;
size_t len;
@@ -1257,7 +1221,7 @@ get_output_file_with_visibility (input_file)
|| (len > 3 && memcmp (basename+len-3, ".in", 3) == 0))
{
char *s;
-
+
output_name = s = xasprintf ("gt-%s", basename);
for (; *s != '.'; s++)
if (! ISALNUM (*s) && *s != '-')
@@ -1269,10 +1233,10 @@ get_output_file_with_visibility (input_file)
output_name = "gt-c-common.h", for_name = "c-common.c";
else if (strcmp (basename, "c-tree.h") == 0)
output_name = "gt-c-decl.h", for_name = "c-decl.c";
- else
+ else
{
size_t i;
-
+
for (i = 0; i < NUM_BASE_FILES; i++)
if (memcmp (basename, lang_dir_names[i], strlen (lang_dir_names[i])) == 0
&& basename[strlen(lang_dir_names[i])] == '/')
@@ -1298,8 +1262,7 @@ get_output_file_with_visibility (input_file)
that uses INPUT_FILE. */
const char *
-get_output_file_name (input_file)
- const char *input_file;
+get_output_file_name (const char *input_file)
{
return get_output_file_with_visibility (input_file)->name;
}
@@ -1307,13 +1270,11 @@ get_output_file_name (input_file)
/* Copy the output to its final destination,
but don't unnecessarily change modification times. */
-static void close_output_files PARAMS ((void));
-
static void
-close_output_files ()
+close_output_files (void)
{
outf_p of;
-
+
for (of = output_files; of; of = of->next)
{
FILE * newfile;
@@ -1364,77 +1325,84 @@ struct flist {
outf_p f;
};
-static void output_escaped_param PARAMS ((outf_p , const char *, const char *,
- const char *, const char *,
- struct fileloc *));
-static void output_mangled_typename PARAMS ((outf_p, type_p));
-static void write_gc_structure_fields
- PARAMS ((outf_p , type_p, const char *, const char *, options_p,
- int, struct fileloc *, lang_bitmap, type_p *));
-static void write_gc_marker_routine_for_structure PARAMS ((type_p, type_p,
- type_p *));
-static void write_gc_types PARAMS ((type_p structures, type_p param_structs));
-static void write_enum_defn PARAMS ((type_p structures, type_p param_structs));
-static void put_mangled_filename PARAMS ((outf_p , const char *));
-static void finish_root_table PARAMS ((struct flist *flp, const char *pfx,
- const char *tname, const char *lastname,
- const char *name));
-static void write_gc_root PARAMS ((outf_p , pair_p, type_p, const char *, int,
- struct fileloc *, const char *));
-static void write_gc_roots PARAMS ((pair_p));
-
-static int gc_counter;
-
-/* Print PARAM to OF processing escapes. VAL references the current object,
- PREV_VAL the object containing the current object, ONAME is the name
- of the option and LINE is used to print error messages. */
+struct walk_type_data;
-static void
-output_escaped_param (of, param, val, prev_val, oname, line)
- outf_p of;
- const char *param;
- const char *val;
- const char *prev_val;
- const char *oname;
- struct fileloc *line;
+/* For scalars and strings, given the item in 'val'.
+ For structures, given a pointer to the item in 'val'.
+ For misc. pointers, given the item in 'val'.
+*/
+typedef void (*process_field_fn)
+ (type_p f, const struct walk_type_data *p);
+typedef void (*func_name_fn)
+ (type_p s, const struct walk_type_data *p);
+
+/* Parameters for write_types. */
+
+struct write_types_data
{
- const char *p;
-
- for (p = param; *p; p++)
- if (*p != '%')
- oprintf (of, "%c", *p);
- else switch (*++p)
- {
- case 'h':
- oprintf (of, "(%s)", val);
- break;
- case '0':
- oprintf (of, "(*x)");
- break;
- case '1':
- oprintf (of, "(%s)", prev_val);
- break;
- case 'a':
- {
- const char *pp = val + strlen (val);
- while (pp[-1] == ']')
- while (*pp != '[')
- pp--;
- oprintf (of, "%s", pp);
- }
- break;
- default:
- error_at_line (line, "`%s' option contains bad escape %c%c",
- oname, '%', *p);
- }
-}
+ const char *prefix;
+ const char *param_prefix;
+ const char *subfield_marker_routine;
+ const char *marker_routine;
+ const char *reorder_note_routine;
+ const char *comment;
+};
+
+static void output_escaped_param (struct walk_type_data *d,
+ const char *, const char *);
+static void output_mangled_typename (outf_p, type_p);
+static void walk_type (type_p t, struct walk_type_data *d);
+static void write_func_for_structure
+ (type_p orig_s, type_p s, type_p * param,
+ const struct write_types_data *wtd);
+static void write_types_process_field
+ (type_p f, const struct walk_type_data *d);
+static void write_types (type_p structures,
+ type_p param_structs,
+ const struct write_types_data *wtd);
+static void write_types_local_process_field
+ (type_p f, const struct walk_type_data *d);
+static void write_local_func_for_structure
+ (type_p orig_s, type_p s, type_p * param);
+static void write_local (type_p structures,
+ type_p param_structs);
+static void write_enum_defn (type_p structures, type_p param_structs);
+static int contains_scalar_p (type_p t);
+static void put_mangled_filename (outf_p , const char *);
+static void finish_root_table (struct flist *flp, const char *pfx,
+ const char *tname, const char *lastname,
+ const char *name);
+static void write_root (outf_p , pair_p, type_p, const char *, int,
+ struct fileloc *, const char *);
+static void write_array (outf_p f, pair_p v,
+ const struct write_types_data *wtd);
+static void write_roots (pair_p);
+
+/* Parameters for walk_type. */
+
+struct walk_type_data
+{
+ process_field_fn process_field;
+ const void *cookie;
+ outf_p of;
+ options_p opt;
+ const char *val;
+ const char *prev_val[4];
+ int indent;
+ int counter;
+ struct fileloc *line;
+ lang_bitmap bitmap;
+ type_p *param;
+ int used_length;
+ type_p orig_s;
+ const char *reorder_fn;
+ int needs_cast_p;
+};
/* Print a mangled name representing T to OF. */
static void
-output_mangled_typename (of, t)
- outf_p of;
- type_p t;
+output_mangled_typename (outf_p of, type_p t)
{
if (t == NULL)
oprintf (of, "Z");
@@ -1461,7 +1429,7 @@ output_mangled_typename (of, t)
for (i = 0; i < NUM_PARAM; i++)
if (t->u.param_struct.param[i] != NULL)
output_mangled_typename (of, t->u.param_struct.param[i]);
- output_mangled_typename (of, t->u.param_struct.stru);
+ output_mangled_typename (of, t->u.param_struct.stru);
}
break;
case TYPE_ARRAY:
@@ -1469,432 +1437,499 @@ output_mangled_typename (of, t)
}
}
-/* Write out code to OF which marks the fields of S. VAL references
- the current object, PREV_VAL the object containing the current
- object, OPTS is a list of options to apply, INDENT is the current
- indentation level, LINE is used to print error messages, BITMAP
- indicates which languages to print the structure for, and PARAM is
- the current parameter (from an enclosing param_is option). */
+/* Print PARAM to D->OF processing escapes. D->VAL references the
+ current object, D->PREV_VAL the object containing the current
+ object, ONAME is the name of the option and D->LINE is used to
+ print error messages. */
static void
-write_gc_structure_fields (of, s, val, prev_val, opts, indent, line, bitmap,
- param)
- outf_p of;
- type_p s;
- const char *val;
- const char *prev_val;
- options_p opts;
- int indent;
- struct fileloc *line;
- lang_bitmap bitmap;
- type_p * param;
+output_escaped_param (struct walk_type_data *d, const char *param,
+ const char *oname)
{
- pair_p f;
- int seen_default = 0;
+ const char *p;
- if (! s->u.s.line.file)
- error_at_line (line, "incomplete structure `%s'", s->u.s.tag);
- else if ((s->u.s.bitmap & bitmap) != bitmap)
- {
- error_at_line (line, "structure defined for mismatching languages");
- error_at_line (&s->u.s.line, "one structure defined here");
- }
-
- if (s->kind == TYPE_UNION)
- {
- const char *tagexpr = NULL;
- options_p oo;
-
- for (oo = opts; oo; oo = oo->next)
- if (strcmp (oo->name, "desc") == 0)
- tagexpr = (const char *)oo->info;
- if (tagexpr == NULL)
+ for (p = param; *p; p++)
+ if (*p != '%')
+ oprintf (d->of, "%c", *p);
+ else switch (*++p)
+ {
+ case 'h':
+ oprintf (d->of, "(%s)", d->prev_val[2]);
+ break;
+ case '0':
+ oprintf (d->of, "(%s)", d->prev_val[0]);
+ break;
+ case '1':
+ oprintf (d->of, "(%s)", d->prev_val[1]);
+ break;
+ case 'a':
{
- tagexpr = "1";
- error_at_line (line, "missing `desc' option");
+ const char *pp = d->val + strlen (d->val);
+ while (pp[-1] == ']')
+ while (*pp != '[')
+ pp--;
+ oprintf (d->of, "%s", pp);
}
+ break;
+ default:
+ error_at_line (d->line, "`%s' option contains bad escape %c%c",
+ oname, '%', *p);
+ }
+}
- oprintf (of, "%*sswitch (", indent, "");
- output_escaped_param (of, tagexpr, val, prev_val, "desc", line);
- oprintf (of, ")\n");
- indent += 2;
- oprintf (of, "%*s{\n", indent, "");
- }
-
- for (f = s->u.s.fields; f; f = f->next)
- {
- const char *tagid = NULL;
- const char *length = NULL;
- int skip_p = 0;
- int default_p = 0;
- int maybe_undef_p = 0;
- int use_param_num = -1;
- int use_params_p = 0;
- int needs_cast_p = 0;
- options_p oo;
- type_p t = f->type;
- const char *dot = ".";
-
- for (oo = f->opt; oo; oo = oo->next)
- if (strcmp (oo->name, "length") == 0)
- length = (const char *)oo->info;
- else if (strcmp (oo->name, "maybe_undef") == 0)
- maybe_undef_p = 1;
- else if (strcmp (oo->name, "tag") == 0)
- tagid = (const char *)oo->info;
- else if (strcmp (oo->name, "special") == 0)
- ;
- else if (strcmp (oo->name, "skip") == 0)
- skip_p = 1;
- else if (strcmp (oo->name, "default") == 0)
- default_p = 1;
- else if (strcmp (oo->name, "desc") == 0)
- ;
- else if (strcmp (oo->name, "descbits") == 0)
- ;
- else if (strcmp (oo->name, "param_is") == 0)
- ;
- else if (strncmp (oo->name, "use_param", 9) == 0
- && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
- use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
- else if (strcmp (oo->name, "use_params") == 0)
- use_params_p = 1;
- else if (strcmp (oo->name, "dot") == 0)
- dot = (const char *)oo->info;
- else
- error_at_line (&f->line, "unknown field option `%s'\n", oo->name);
+/* Call D->PROCESS_FIELD for every field (or subfield) of D->VAL,
+ which is of type T. Write code to D->OF to constrain execution (at
+ the point that D->PROCESS_FIELD is called) to the appropriate
+ cases. Call D->PROCESS_FIELD on subobjects before calling it on
+ pointers to those objects. D->PREV_VAL lists the objects
+ containing the current object, D->OPT is a list of options to
+ apply, D->INDENT is the current indentation level, D->LINE is used
+ to print error messages, D->BITMAP indicates which languages to
+ print the structure for, and D->PARAM is the current parameter
+ (from an enclosing param_is option). */
- if (skip_p)
- continue;
+static void
+walk_type (type_p t, struct walk_type_data *d)
+{
+ const char *length = NULL;
+ const char *desc = NULL;
+ int maybe_undef_p = 0;
+ int use_param_num = -1;
+ int use_params_p = 0;
+ options_p oo;
+
+ d->needs_cast_p = 0;
+ for (oo = d->opt; oo; oo = oo->next)
+ if (strcmp (oo->name, "length") == 0)
+ length = (const char *)oo->info;
+ else if (strcmp (oo->name, "maybe_undef") == 0)
+ maybe_undef_p = 1;
+ else if (strncmp (oo->name, "use_param", 9) == 0
+ && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
+ use_param_num = oo->name[9] == '\0' ? 0 : oo->name[9] - '0';
+ else if (strcmp (oo->name, "use_params") == 0)
+ use_params_p = 1;
+ else if (strcmp (oo->name, "desc") == 0)
+ desc = (const char *)oo->info;
+ else if (strcmp (oo->name, "dot") == 0)
+ ;
+ else if (strcmp (oo->name, "tag") == 0)
+ ;
+ else if (strcmp (oo->name, "special") == 0)
+ ;
+ else if (strcmp (oo->name, "skip") == 0)
+ ;
+ else if (strcmp (oo->name, "default") == 0)
+ ;
+ else if (strcmp (oo->name, "descbits") == 0)
+ ;
+ else if (strcmp (oo->name, "param_is") == 0)
+ ;
+ else if (strncmp (oo->name, "param", 5) == 0
+ && ISDIGIT (oo->name[5])
+ && strcmp (oo->name + 6, "_is") == 0)
+ ;
+ else if (strcmp (oo->name, "chain_next") == 0)
+ ;
+ else if (strcmp (oo->name, "chain_prev") == 0)
+ ;
+ else if (strcmp (oo->name, "reorder") == 0)
+ ;
+ else
+ error_at_line (d->line, "unknown option `%s'\n", oo->name);
- if (use_params_p)
- {
- int pointer_p = t->kind == TYPE_POINTER;
+ if (d->used_length)
+ length = NULL;
- if (pointer_p)
- t = t->u.p;
- t = find_param_structure (t, param);
- if (pointer_p)
- t = create_pointer (t);
- }
-
- if (use_param_num != -1)
+ if (use_params_p)
+ {
+ int pointer_p = t->kind == TYPE_POINTER;
+
+ if (pointer_p)
+ t = t->u.p;
+ if (! UNION_OR_STRUCT_P (t))
+ error_at_line (d->line, "`use_params' option on unimplemented type");
+ else
+ t = find_param_structure (t, d->param);
+ if (pointer_p)
+ t = create_pointer (t);
+ }
+
+ if (use_param_num != -1)
+ {
+ if (d->param != NULL && d->param[use_param_num] != NULL)
{
- if (param != NULL && param[use_param_num] != NULL)
- {
- type_p nt = param[use_param_num];
-
- if (t->kind == TYPE_ARRAY)
- nt = create_array (nt, t->u.a.len);
- else if (length != NULL && t->kind == TYPE_POINTER)
- nt = create_pointer (nt);
- needs_cast_p = (t->kind != TYPE_POINTER
- && nt->kind == TYPE_POINTER);
- t = nt;
- }
- else if (s->kind != TYPE_UNION)
- error_at_line (&f->line, "no parameter defined");
+ type_p nt = d->param[use_param_num];
+
+ if (t->kind == TYPE_ARRAY)
+ nt = create_array (nt, t->u.a.len);
+ else if (length != NULL && t->kind == TYPE_POINTER)
+ nt = create_pointer (nt);
+ d->needs_cast_p = (t->kind != TYPE_POINTER
+ && (nt->kind == TYPE_POINTER
+ || nt->kind == TYPE_STRING));
+ t = nt;
}
+ else
+ error_at_line (d->line, "no parameter defined for `%s'",
+ d->val);
+ }
- if (t->kind == TYPE_SCALAR
- || (t->kind == TYPE_ARRAY
- && t->u.a.p->kind == TYPE_SCALAR))
- continue;
-
- seen_default |= default_p;
-
- if (maybe_undef_p
- && (t->kind != TYPE_POINTER
- || t->u.p->kind != TYPE_STRUCT))
- error_at_line (&f->line,
- "field `%s' has invalid option `maybe_undef_p'\n",
- f->name);
- if (s->kind == TYPE_UNION)
- {
- if (tagid)
- {
- oprintf (of, "%*scase %s:\n", indent, "", tagid);
+ if (maybe_undef_p
+ && (t->kind != TYPE_POINTER || ! UNION_OR_STRUCT_P (t->u.p)))
+ {
+ error_at_line (d->line,
+ "field `%s' has invalid option `maybe_undef_p'\n",
+ d->val);
+ return;
+ }
- }
- else if (default_p)
- {
- oprintf (of, "%*sdefault:\n", indent, "");
- }
- else
- {
- error_at_line (&f->line, "field `%s' has no tag", f->name);
- continue;
- }
- indent += 2;
- }
-
- switch (t->kind)
- {
- case TYPE_STRING:
- /* Do nothing; strings go in the string pool. */
- break;
+ switch (t->kind)
+ {
+ case TYPE_SCALAR:
+ case TYPE_STRING:
+ d->process_field (t, d);
+ break;
- case TYPE_LANG_STRUCT:
+ case TYPE_POINTER:
+ {
+ if (maybe_undef_p
+ && t->u.p->u.s.line.file == NULL)
{
- type_p ti;
- for (ti = t->u.s.lang_struct; ti; ti = ti->next)
- if (ti->u.s.bitmap & bitmap)
- {
- t = ti;
- break;
- }
- if (ti == NULL)
+ oprintf (d->of, "%*sif (%s) abort();\n", d->indent, "", d->val);
+ break;
+ }
+
+ if (! length)
+ {
+ if (! UNION_OR_STRUCT_P (t->u.p)
+ && t->u.p->kind != TYPE_PARAM_STRUCT)
{
- error_at_line (&f->line,
- "structure not defined for this language");
+ error_at_line (d->line,
+ "field `%s' is pointer to unimplemented type",
+ d->val);
break;
}
+
+ d->process_field (t->u.p, d);
}
- /* Fall through... */
- case TYPE_STRUCT:
- case TYPE_UNION:
+ else
{
+ int loopcounter = d->counter++;
+ const char *oldval = d->val;
+ const char *oldprevval3 = d->prev_val[3];
char *newval;
- newval = xasprintf ("%s%s%s", val, dot, f->name);
- write_gc_structure_fields (of, t, newval, val, f->opt, indent,
- &f->line, bitmap, param);
+ oprintf (d->of, "%*sif (%s != NULL) {\n", d->indent, "", d->val);
+ d->indent += 2;
+ oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
+ oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
+ loopcounter, loopcounter);
+ output_escaped_param (d, length, "length");
+ oprintf (d->of, "); i%d++) {\n", loopcounter);
+ d->indent += 2;
+ d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
+ d->used_length = 1;
+ d->prev_val[3] = oldval;
+ walk_type (t->u.p, d);
free (newval);
- break;
+ d->val = oldval;
+ d->prev_val[3] = oldprevval3;
+ d->used_length = 0;
+ d->indent -= 2;
+ oprintf (d->of, "%*s}\n", d->indent, "");
+ d->process_field(t, d);
+ d->indent -= 2;
+ oprintf (d->of, "%*s}\n", d->indent, "");
}
+ }
+ break;
- case TYPE_POINTER:
- if (! length)
- {
- if (maybe_undef_p
- && t->u.p->u.s.line.file == NULL)
- oprintf (of, "%*sif (%s%s%s) abort();\n", indent, "",
- val, dot, f->name);
- else if (UNION_OR_STRUCT_P (t->u.p)
- || t->u.p->kind == TYPE_PARAM_STRUCT)
- {
- oprintf (of, "%*sgt_ggc_m_", indent, "");
- output_mangled_typename (of, t->u.p);
- oprintf (of, " (");
- if (needs_cast_p)
- oprintf (of, "(%s %s *)",
- UNION_P (t->u.p) ? "union" : "struct",
- t->u.p->u.s.tag);
- oprintf (of, "%s%s%s);\n", val, dot, f->name);
- }
- else
- error_at_line (&f->line, "field `%s' is pointer to scalar",
- f->name);
- break;
- }
- else if (t->u.p->kind == TYPE_SCALAR
- || t->u.p->kind == TYPE_STRING)
- oprintf (of, "%*sggc_mark (%s%s%s);\n", indent, "",
- val, dot, f->name);
- else
- {
- int loopcounter = ++gc_counter;
-
- oprintf (of, "%*sif (%s%s%s != NULL) {\n", indent, "",
- val, dot, f->name);
- indent += 2;
- oprintf (of, "%*ssize_t i%d;\n", indent, "", loopcounter);
- oprintf (of, "%*sggc_set_mark (%s%s%s);\n", indent, "",
- val, dot, f->name);
- oprintf (of, "%*sfor (i%d = 0; i%d < (size_t)(", indent, "",
- loopcounter, loopcounter);
- output_escaped_param (of, length, val, prev_val, "length", line);
- oprintf (of, "); i%d++) {\n", loopcounter);
- indent += 2;
- switch (t->u.p->kind)
- {
- case TYPE_STRUCT:
- case TYPE_UNION:
- {
- char *newval;
-
- newval = xasprintf ("%s%s%s[i%d]", val, dot, f->name,
- loopcounter);
- write_gc_structure_fields (of, t->u.p, newval, val,
- f->opt, indent, &f->line,
- bitmap, param);
- free (newval);
- break;
- }
- case TYPE_POINTER:
- if (UNION_OR_STRUCT_P (t->u.p->u.p)
- || t->u.p->u.p->kind == TYPE_PARAM_STRUCT)
- {
- oprintf (of, "%*sgt_ggc_m_", indent, "");
- output_mangled_typename (of, t->u.p->u.p);
- oprintf (of, " (%s%s%s[i%d]);\n", val, dot, f->name,
- loopcounter);
- }
- else
- error_at_line (&f->line,
- "field `%s' is array of pointer to scalar",
- f->name);
- break;
- default:
- error_at_line (&f->line,
- "field `%s' is array of unimplemented type",
- f->name);
- break;
- }
- indent -= 2;
- oprintf (of, "%*s}\n", indent, "");
- indent -= 2;
- oprintf (of, "%*s}\n", indent, "");
- }
+ case TYPE_ARRAY:
+ {
+ int loopcounter = d->counter++;
+ const char *oldval = d->val;
+ char *newval;
+
+ /* If it's an array of scalars, we optimize by not generating
+ any code. */
+ if (t->u.a.p->kind == TYPE_SCALAR)
break;
- case TYPE_ARRAY:
+ oprintf (d->of, "%*s{\n", d->indent, "");
+ d->indent += 2;
+ oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
+ oprintf (d->of, "%*sfor (i%d = 0; i%d < (size_t)(", d->indent, "",
+ loopcounter, loopcounter);
+ if (length)
+ output_escaped_param (d, length, "length");
+ else
+ oprintf (d->of, "%s", t->u.a.len);
+ oprintf (d->of, "); i%d++) {\n", loopcounter);
+ d->indent += 2;
+ d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
+ d->used_length = 1;
+ walk_type (t->u.a.p, d);
+ free (newval);
+ d->used_length = 0;
+ d->val = oldval;
+ d->indent -= 2;
+ oprintf (d->of, "%*s}\n", d->indent, "");
+ d->indent -= 2;
+ oprintf (d->of, "%*s}\n", d->indent, "");
+ }
+ break;
+
+ case TYPE_STRUCT:
+ case TYPE_UNION:
+ {
+ pair_p f;
+ const char *oldval = d->val;
+ const char *oldprevval1 = d->prev_val[1];
+ const char *oldprevval2 = d->prev_val[2];
+ const int union_p = t->kind == TYPE_UNION;
+ int seen_default_p = 0;
+ options_p o;
+
+ if (! t->u.s.line.file)
+ error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
+
+ if ((d->bitmap & t->u.s.bitmap) != d->bitmap)
{
- int loopcounter = ++gc_counter;
- type_p ta;
- int i;
-
- if (! length &&
- (strcmp (t->u.a.len, "0") == 0
- || strcmp (t->u.a.len, "1") == 0))
- error_at_line (&f->line,
- "field `%s' is array of size %s",
- f->name, t->u.a.len);
-
- /* Arrays of scalars can be ignored. */
- for (ta = t; ta->kind == TYPE_ARRAY; ta = ta->u.a.p)
- ;
- if (ta->kind == TYPE_SCALAR
- || ta->kind == TYPE_STRING)
- break;
+ error_at_line (d->line,
+ "structure `%s' defined for mismatching languages",
+ t->u.s.tag);
+ error_at_line (&t->u.s.line, "one structure defined here");
+ }
- oprintf (of, "%*s{\n", indent, "");
- indent += 2;
+ /* Some things may also be defined in the structure's options. */
+ for (o = t->u.s.opt; o; o = o->next)
+ if (! desc && strcmp (o->name, "desc") == 0)
+ desc = (const char *)o->info;
- for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
+ d->prev_val[2] = oldval;
+ d->prev_val[1] = oldprevval2;
+ if (union_p)
+ {
+ if (desc == NULL)
{
- oprintf (of, "%*ssize_t i%d_%d;\n",
- indent, "", loopcounter, i);
- oprintf (of, "%*sconst size_t ilimit%d_%d = (",
- indent, "", loopcounter, i);
- if (i == 0 && length != NULL)
- output_escaped_param (of, length, val, prev_val,
- "length", line);
- else
- oprintf (of, "%s", ta->u.a.len);
- oprintf (of, ");\n");
+ error_at_line (d->line, "missing `desc' option for union `%s'",
+ t->u.s.tag);
+ desc = "1";
}
-
- for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
+ oprintf (d->of, "%*sswitch (", d->indent, "");
+ output_escaped_param (d, desc, "desc");
+ oprintf (d->of, ")\n");
+ d->indent += 2;
+ oprintf (d->of, "%*s{\n", d->indent, "");
+ }
+ for (f = t->u.s.fields; f; f = f->next)
+ {
+ options_p oo;
+ const char *dot = ".";
+ const char *tagid = NULL;
+ int skip_p = 0;
+ int default_p = 0;
+ int use_param_p = 0;
+ char *newval;
+
+ d->reorder_fn = NULL;
+ for (oo = f->opt; oo; oo = oo->next)
+ if (strcmp (oo->name, "dot") == 0)
+ dot = (const char *)oo->info;
+ else if (strcmp (oo->name, "tag") == 0)
+ tagid = (const char *)oo->info;
+ else if (strcmp (oo->name, "skip") == 0)
+ skip_p = 1;
+ else if (strcmp (oo->name, "default") == 0)
+ default_p = 1;
+ else if (strcmp (oo->name, "reorder") == 0)
+ d->reorder_fn = (const char *)oo->info;
+ else if (strncmp (oo->name, "use_param", 9) == 0
+ && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
+ use_param_p = 1;
+
+ if (skip_p)
+ continue;
+
+ if (union_p && tagid)
{
- oprintf (of,
- "%*sfor (i%d_%d = 0; i%d_%d < ilimit%d_%d; i%d_%d++) {\n",
- indent, "", loopcounter, i, loopcounter, i,
- loopcounter, i, loopcounter, i);
- indent += 2;
+ oprintf (d->of, "%*scase %s:\n", d->indent, "", tagid);
+ d->indent += 2;
}
-
- if (ta->kind == TYPE_POINTER
- && (UNION_OR_STRUCT_P (ta->u.p)
- || ta->u.p->kind == TYPE_PARAM_STRUCT))
+ else if (union_p && default_p)
{
- oprintf (of, "%*sgt_ggc_m_", indent, "");
- output_mangled_typename (of, ta->u.p);
- oprintf (of, " (%s%s%s", val, dot, f->name);
- for (ta = t, i = 0;
- ta->kind == TYPE_ARRAY;
- ta = ta->u.a.p, i++)
- oprintf (of, "[i%d_%d]", loopcounter, i);
- oprintf (of, ");\n");
+ oprintf (d->of, "%*sdefault:\n", d->indent, "");
+ d->indent += 2;
+ seen_default_p = 1;
}
- else if (ta->kind == TYPE_STRUCT || ta->kind == TYPE_UNION)
+ else if (! union_p && (default_p || tagid))
+ error_at_line (d->line,
+ "can't use `%s' outside a union on field `%s'",
+ default_p ? "default" : "tag", f->name);
+ else if (union_p && ! (default_p || tagid)
+ && f->type->kind == TYPE_SCALAR)
{
- char *newval;
- int len;
-
- len = strlen (val) + strlen (f->name) + 2;
- for (ta = t; ta->kind == TYPE_ARRAY; ta = ta->u.a.p)
- len += sizeof ("[i_]") + 2*6;
-
- newval = xmalloc (len);
- sprintf (newval, "%s%s%s", val, dot, f->name);
- for (ta = t, i = 0;
- ta->kind == TYPE_ARRAY;
- ta = ta->u.a.p, i++)
- sprintf (newval + strlen (newval), "[i%d_%d]",
- loopcounter, i);
- write_gc_structure_fields (of, t->u.p, newval, val,
- f->opt, indent, &f->line, bitmap,
- param);
- free (newval);
+ fprintf (stderr,
+ "%s:%d: warning: field `%s' is missing `tag' or `default' option\n",
+ d->line->file, d->line->line, f->name);
+ continue;
}
- else if (ta->kind == TYPE_POINTER && ta->u.p->kind == TYPE_SCALAR
- && use_param_num != -1 && param == NULL)
- oprintf (of, "%*sabort();\n", indent, "");
- else
- error_at_line (&f->line,
- "field `%s' is array of unimplemented type",
+ else if (union_p && ! (default_p || tagid))
+ error_at_line (d->line,
+ "field `%s' is missing `tag' or `default' option",
f->name);
- for (ta = t, i = 0; ta->kind == TYPE_ARRAY; ta = ta->u.a.p, i++)
+
+ d->line = &f->line;
+ d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
+ d->opt = f->opt;
+
+ if (union_p && use_param_p && d->param == NULL)
+ oprintf (d->of, "%*sabort();\n", d->indent, "");
+ else
+ walk_type (f->type, d);
+
+ free (newval);
+
+ if (union_p)
{
- indent -= 2;
- oprintf (of, "%*s}\n", indent, "");
+ oprintf (d->of, "%*sbreak;\n", d->indent, "");
+ d->indent -= 2;
}
+ }
+ d->reorder_fn = NULL;
- indent -= 2;
- oprintf (of, "%*s}\n", indent, "");
- break;
+ d->val = oldval;
+ d->prev_val[1] = oldprevval1;
+ d->prev_val[2] = oldprevval2;
+
+ if (union_p && ! seen_default_p)
+ {
+ oprintf (d->of, "%*sdefault:\n", d->indent, "");
+ oprintf (d->of, "%*s break;\n", d->indent, "");
+ }
+ if (union_p)
+ {
+ oprintf (d->of, "%*s}\n", d->indent, "");
+ d->indent -= 2;
}
+ }
+ break;
- default:
- error_at_line (&f->line,
- "field `%s' is unimplemented type",
- f->name);
- break;
- }
-
- if (s->kind == TYPE_UNION)
- {
- oprintf (of, "%*sbreak;\n", indent, "");
- indent -= 2;
- }
+ case TYPE_LANG_STRUCT:
+ {
+ type_p nt;
+ for (nt = t->u.s.lang_struct; nt; nt = nt->next)
+ if ((d->bitmap & nt->u.s.bitmap) == d->bitmap)
+ break;
+ if (nt == NULL)
+ error_at_line (d->line, "structure `%s' differs between languages",
+ t->u.s.tag);
+ else
+ walk_type (nt, d);
+ }
+ break;
+
+ case TYPE_PARAM_STRUCT:
+ {
+ type_p *oldparam = d->param;
+
+ d->param = t->u.param_struct.param;
+ walk_type (t->u.param_struct.stru, d);
+ d->param = oldparam;
+ }
+ break;
+
+ default:
+ abort ();
}
- if (s->kind == TYPE_UNION)
+}
+
+/* process_field routine for marking routines. */
+
+static void
+write_types_process_field (type_p f, const struct walk_type_data *d)
+{
+ const struct write_types_data *wtd;
+ const char *cast = d->needs_cast_p ? "(void *)" : "";
+ wtd = (const struct write_types_data *) d->cookie;
+
+ switch (f->kind)
{
- if (! seen_default)
+ case TYPE_POINTER:
+ oprintf (d->of, "%*s%s (%s%s", d->indent, "",
+ wtd->subfield_marker_routine, cast, d->val);
+ if (wtd->param_prefix)
{
- oprintf (of, "%*sdefault:\n", indent, "");
- oprintf (of, "%*s break;\n", indent, "");
+ oprintf (d->of, ", %s", d->prev_val[3]);
+ if (d->orig_s)
+ {
+ oprintf (d->of, ", gt_%s_", wtd->param_prefix);
+ output_mangled_typename (d->of, d->orig_s);
+ }
+ else
+ oprintf (d->of, ", gt_%sa_%s", wtd->param_prefix, d->prev_val[0]);
}
- oprintf (of, "%*s}\n", indent, "");
- indent -= 2;
+ oprintf (d->of, ");\n");
+ if (d->reorder_fn && wtd->reorder_note_routine)
+ oprintf (d->of, "%*s%s (%s%s, %s, %s);\n", d->indent, "",
+ wtd->reorder_note_routine, cast, d->val,
+ d->prev_val[3], d->reorder_fn);
+ break;
+
+ case TYPE_STRING:
+ if (wtd->param_prefix == NULL)
+ break;
+
+ case TYPE_STRUCT:
+ case TYPE_UNION:
+ case TYPE_LANG_STRUCT:
+ case TYPE_PARAM_STRUCT:
+ oprintf (d->of, "%*sgt_%s_", d->indent, "", wtd->prefix);
+ output_mangled_typename (d->of, f);
+ oprintf (d->of, " (%s%s);\n", cast, d->val);
+ if (d->reorder_fn && wtd->reorder_note_routine)
+ oprintf (d->of, "%*s%s (%s%s, %s%s, %s);\n", d->indent, "",
+ wtd->reorder_note_routine, cast, d->val, cast, d->val,
+ d->reorder_fn);
+ break;
+
+ case TYPE_SCALAR:
+ break;
+
+ default:
+ abort ();
}
}
-/* Write out a marker routine for S. PARAM is the parameter from an
- enclosing PARAM_IS option. */
+/* For S, a structure that's part of ORIG_S, and using parameters
+ PARAM, write out a routine that:
+ - Takes a parameter, a void * but actually of type *S
+ - If SEEN_ROUTINE returns nonzero, calls write_types_process_field on each
+ field of S or its substructures and (in some cases) things
+ that are pointed to by S.
+*/
static void
-write_gc_marker_routine_for_structure (orig_s, s, param)
- type_p orig_s;
- type_p s;
- type_p * param;
+write_func_for_structure (type_p orig_s, type_p s, type_p *param,
+ const struct write_types_data *wtd)
{
- outf_p f;
const char *fn = s->u.s.line.file;
int i;
const char *chain_next = NULL;
const char *chain_prev = NULL;
options_p opt;
-
+ struct walk_type_data d;
+
/* This is a hack, and not the good kind either. */
for (i = NUM_PARAM - 1; i >= 0; i--)
- if (param && param[i] && param[i]->kind == TYPE_POINTER
+ if (param && param[i] && param[i]->kind == TYPE_POINTER
&& UNION_OR_STRUCT_P (param[i]->u.p))
fn = param[i]->u.p->u.s.line.file;
-
- f = get_output_file_with_visibility (fn);
-
+
+ memset (&d, 0, sizeof (d));
+ d.of = get_output_file_with_visibility (fn);
+
for (opt = s->u.s.opt; opt; opt = opt->next)
if (strcmp (opt->name, "chain_next") == 0)
chain_next = (const char *) opt->info;
@@ -1904,110 +1939,141 @@ write_gc_marker_routine_for_structure (orig_s, s, param)
if (chain_prev != NULL && chain_next == NULL)
error_at_line (&s->u.s.line, "chain_prev without chain_next");
- oprintf (f, "\n");
- oprintf (f, "void\n");
+ d.process_field = write_types_process_field;
+ d.cookie = wtd;
+ d.orig_s = orig_s;
+ d.opt = s->u.s.opt;
+ d.line = &s->u.s.line;
+ d.bitmap = s->u.s.bitmap;
+ d.param = param;
+ d.prev_val[0] = "*x";
+ d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
+ d.prev_val[3] = "x";
+ d.val = "(*x)";
+
+ oprintf (d.of, "\n");
+ oprintf (d.of, "void\n");
if (param == NULL)
- oprintf (f, "gt_ggc_mx_%s", s->u.s.tag);
+ oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
else
{
- oprintf (f, "gt_ggc_m_");
- output_mangled_typename (f, orig_s);
+ oprintf (d.of, "gt_%s_", wtd->prefix);
+ output_mangled_typename (d.of, orig_s);
}
- oprintf (f, " (x_p)\n");
- oprintf (f, " void *x_p;\n");
- oprintf (f, "{\n");
- oprintf (f, " %s %s * %sx = (%s %s *)x_p;\n",
+ oprintf (d.of, " (void *x_p)\n");
+ oprintf (d.of, "{\n");
+ oprintf (d.of, " %s %s * %sx = (%s %s *)x_p;\n",
s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
chain_next == NULL ? "const " : "",
s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
if (chain_next != NULL)
- oprintf (f, " %s %s * xlimit = x;\n",
+ oprintf (d.of, " %s %s * xlimit = x;\n",
s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
if (chain_next == NULL)
- oprintf (f, " if (ggc_test_and_set_mark (x))\n");
+ {
+ oprintf (d.of, " if (%s (x", wtd->marker_routine);
+ if (wtd->param_prefix)
+ {
+ oprintf (d.of, ", x, gt_%s_", wtd->param_prefix);
+ output_mangled_typename (d.of, orig_s);
+ }
+ oprintf (d.of, "))\n");
+ }
else
{
- oprintf (f, " while (ggc_test_and_set_mark (xlimit))\n");
- oprintf (f, " xlimit = (");
- output_escaped_param (f, chain_next, "*xlimit", "*xlimit",
- "chain_next", &s->u.s.line);
- oprintf (f, ");\n");
+ oprintf (d.of, " while (%s (xlimit", wtd->marker_routine);
+ if (wtd->param_prefix)
+ {
+ oprintf (d.of, ", xlimit, gt_%s_", wtd->param_prefix);
+ output_mangled_typename (d.of, orig_s);
+ }
+ oprintf (d.of, "))\n");
+ oprintf (d.of, " xlimit = (");
+ d.prev_val[2] = "*xlimit";
+ output_escaped_param (&d, chain_next, "chain_next");
+ oprintf (d.of, ");\n");
if (chain_prev != NULL)
{
- oprintf (f, " if (x != xlimit)\n");
- oprintf (f, " for (;;)\n");
- oprintf (f, " {\n");
- oprintf (f, " %s %s * const xprev = (",
+ oprintf (d.of, " if (x != xlimit)\n");
+ oprintf (d.of, " for (;;)\n");
+ oprintf (d.of, " {\n");
+ oprintf (d.of, " %s %s * const xprev = (",
s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
- output_escaped_param (f, chain_prev, "*x", "*x",
- "chain_prev", &s->u.s.line);
- oprintf (f, ");\n");
- oprintf (f, " if (xprev == NULL) break;\n");
- oprintf (f, " x = xprev;\n");
- oprintf (f, " ggc_set_mark (xprev);\n");
- oprintf (f, " }\n");
+
+ d.prev_val[2] = "*x";
+ output_escaped_param (&d, chain_prev, "chain_prev");
+ oprintf (d.of, ");\n");
+ oprintf (d.of, " if (xprev == NULL) break;\n");
+ oprintf (d.of, " x = xprev;\n");
+ oprintf (d.of, " (void) %s (xprev",
+ wtd->marker_routine);
+ if (wtd->param_prefix)
+ {
+ oprintf (d.of, ", xprev, gt_%s_", wtd->param_prefix);
+ output_mangled_typename (d.of, orig_s);
+ }
+ oprintf (d.of, ");\n");
+ oprintf (d.of, " }\n");
}
- oprintf (f, " while (x != xlimit)\n");
+ oprintf (d.of, " while (x != xlimit)\n");
}
- oprintf (f, " {\n");
-
- gc_counter = 0;
- write_gc_structure_fields (f, s, "(*x)", "not valid postage",
- s->u.s.opt, 6, &s->u.s.line, s->u.s.bitmap,
- param);
-
+ oprintf (d.of, " {\n");
+
+ d.prev_val[2] = "*x";
+ d.indent = 6;
+ walk_type (s, &d);
+
if (chain_next != NULL)
{
- oprintf (f, " x = (");
- output_escaped_param (f, chain_next, "*x", "*x",
- "chain_next", &s->u.s.line);
- oprintf (f, ");\n");
+ oprintf (d.of, " x = (");
+ output_escaped_param (&d, chain_next, "chain_next");
+ oprintf (d.of, ");\n");
}
- oprintf (f, " }\n");
- oprintf (f, "}\n");
+ oprintf (d.of, " }\n");
+ oprintf (d.of, "}\n");
}
/* Write out marker routines for STRUCTURES and PARAM_STRUCTS. */
static void
-write_gc_types (structures, param_structs)
- type_p structures;
- type_p param_structs;
+write_types (type_p structures, type_p param_structs,
+ const struct write_types_data *wtd)
{
type_p s;
-
- oprintf (header_file, "\n/* GC marker procedures. */\n");
+
+ oprintf (header_file, "\n/* %s*/\n", wtd->comment);
for (s = structures; s; s = s->next)
if (s->gc_used == GC_POINTED_TO
|| s->gc_used == GC_MAYBE_POINTED_TO)
{
options_p opt;
-
+
if (s->gc_used == GC_MAYBE_POINTED_TO
&& s->u.s.line.file == NULL)
continue;
- oprintf (header_file, "#define gt_ggc_m_");
+ oprintf (header_file, "#define gt_%s_", wtd->prefix);
output_mangled_typename (header_file, s);
oprintf (header_file, "(X) do { \\\n");
oprintf (header_file,
- " if (X != NULL) gt_ggc_mx_%s (X);\\\n", s->u.s.tag);
+ " if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
+ s->u.s.tag);
oprintf (header_file,
" } while (0)\n");
-
+
for (opt = s->u.s.opt; opt; opt = opt->next)
if (strcmp (opt->name, "ptr_alias") == 0)
{
type_p t = (type_p) opt->info;
- if (t->kind == TYPE_STRUCT
+ if (t->kind == TYPE_STRUCT
|| t->kind == TYPE_UNION
|| t->kind == TYPE_LANG_STRUCT)
oprintf (header_file,
- "#define gt_ggc_mx_%s gt_ggc_mx_%s\n",
- s->u.s.tag, t->u.s.tag);
+ "#define gt_%sx_%s gt_%sx_%s\n",
+ wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
else
- error_at_line (&s->u.s.line,
+ error_at_line (&s->u.s.line,
"structure alias is not a structure");
break;
}
@@ -2015,25 +2081,25 @@ write_gc_types (structures, param_structs)
continue;
/* Declare the marker procedure only once. */
- oprintf (header_file,
- "extern void gt_ggc_mx_%s PARAMS ((void *));\n",
- s->u.s.tag);
-
+ oprintf (header_file,
+ "extern void gt_%sx_%s (void *);\n",
+ wtd->prefix, s->u.s.tag);
+
if (s->u.s.line.file == NULL)
{
- fprintf (stderr, "warning: structure `%s' used but not defined\n",
+ fprintf (stderr, "warning: structure `%s' used but not defined\n",
s->u.s.tag);
continue;
}
-
+
if (s->kind == TYPE_LANG_STRUCT)
{
type_p ss;
for (ss = s->u.s.lang_struct; ss; ss = ss->next)
- write_gc_marker_routine_for_structure (s, ss, NULL);
+ write_func_for_structure (s, ss, NULL, wtd);
}
else
- write_gc_marker_routine_for_structure (s, s, NULL);
+ write_func_for_structure (s, s, NULL, wtd);
}
for (s = param_structs; s; s = s->next)
@@ -2043,37 +2109,207 @@ write_gc_types (structures, param_structs)
type_p stru = s->u.param_struct.stru;
/* Declare the marker procedure. */
- oprintf (header_file, "extern void gt_ggc_m_");
+ oprintf (header_file, "extern void gt_%s_", wtd->prefix);
output_mangled_typename (header_file, s);
- oprintf (header_file, " PARAMS ((void *));\n");
-
+ oprintf (header_file, " (void *);\n");
+
if (stru->u.s.line.file == NULL)
{
- fprintf (stderr, "warning: structure `%s' used but not defined\n",
+ fprintf (stderr, "warning: structure `%s' used but not defined\n",
s->u.s.tag);
continue;
}
-
+
if (stru->kind == TYPE_LANG_STRUCT)
{
type_p ss;
for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
- write_gc_marker_routine_for_structure (s, ss, param);
+ write_func_for_structure (s, ss, param, wtd);
}
else
- write_gc_marker_routine_for_structure (s, stru, param);
+ write_func_for_structure (s, stru, param, wtd);
+ }
+}
+
+static const struct write_types_data ggc_wtd =
+{
+ "ggc_m", NULL, "ggc_mark", "ggc_test_and_set_mark", NULL,
+ "GC marker procedures. "
+};
+
+static const struct write_types_data pch_wtd =
+{
+ "pch_n", "pch_p", "gt_pch_note_object", "gt_pch_note_object",
+ "gt_pch_note_reorder",
+ "PCH type-walking procedures. "
+};
+
+/* Write out the local pointer-walking routines. */
+
+/* process_field routine for local pointer-walking. */
+
+static void
+write_types_local_process_field (type_p f, const struct walk_type_data *d)
+{
+ switch (f->kind)
+ {
+ case TYPE_POINTER:
+ case TYPE_STRUCT:
+ case TYPE_UNION:
+ case TYPE_LANG_STRUCT:
+ case TYPE_PARAM_STRUCT:
+ case TYPE_STRING:
+ oprintf (d->of, "%*sif ((void *)(%s) == this_obj)\n", d->indent, "",
+ d->prev_val[3]);
+ oprintf (d->of, "%*s op (&(%s), cookie);\n", d->indent, "", d->val);
+ break;
+
+ case TYPE_SCALAR:
+ break;
+
+ default:
+ abort ();
+ }
+}
+
+/* For S, a structure that's part of ORIG_S, and using parameters
+ PARAM, write out a routine that:
+ - Is of type gt_note_pointers
+ - If calls PROCESS_FIELD on each field of S or its substructures.
+*/
+
+static void
+write_local_func_for_structure (type_p orig_s, type_p s, type_p *param)
+{
+ const char *fn = s->u.s.line.file;
+ int i;
+ struct walk_type_data d;
+
+ /* This is a hack, and not the good kind either. */
+ for (i = NUM_PARAM - 1; i >= 0; i--)
+ if (param && param[i] && param[i]->kind == TYPE_POINTER
+ && UNION_OR_STRUCT_P (param[i]->u.p))
+ fn = param[i]->u.p->u.s.line.file;
+
+ 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;
+ d.bitmap = s->u.s.bitmap;
+ d.param = param;
+ d.prev_val[0] = d.prev_val[2] = "*x";
+ d.prev_val[1] = "not valid postage"; /* Guarantee an error. */
+ d.prev_val[3] = "x";
+ d.val = "(*x)";
+
+ oprintf (d.of, "\n");
+ oprintf (d.of, "void\n");
+ oprintf (d.of, "gt_pch_p_");
+ output_mangled_typename (d.of, orig_s);
+ oprintf (d.of, " (void *this_obj ATTRIBUTE_UNUSED,\n\tvoid *x_p,\n\tgt_pointer_operator op ATTRIBUTE_UNUSED,\n\tvoid *cookie ATTRIBUTE_UNUSED)\n");
+ oprintf (d.of, "{\n");
+ oprintf (d.of, " %s %s * const x ATTRIBUTE_UNUSED = (%s %s *)x_p;\n",
+ s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
+ s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
+ d.indent = 2;
+ walk_type (s, &d);
+ oprintf (d.of, "}\n");
+}
+
+/* Write out local marker routines for STRUCTURES and PARAM_STRUCTS. */
+
+static void
+write_local (type_p structures, type_p param_structs)
+{
+ type_p s;
+
+ oprintf (header_file, "\n/* Local pointer-walking routines. */\n");
+ for (s = structures; s; s = s->next)
+ if (s->gc_used == GC_POINTED_TO
+ || s->gc_used == GC_MAYBE_POINTED_TO)
+ {
+ options_p opt;
+
+ if (s->u.s.line.file == NULL)
+ continue;
+
+ for (opt = s->u.s.opt; opt; opt = opt->next)
+ if (strcmp (opt->name, "ptr_alias") == 0)
+ {
+ type_p t = (type_p) opt->info;
+ if (t->kind == TYPE_STRUCT
+ || t->kind == TYPE_UNION
+ || t->kind == TYPE_LANG_STRUCT)
+ {
+ oprintf (header_file, "#define gt_pch_p_");
+ output_mangled_typename (header_file, s);
+ oprintf (header_file, " gt_pch_p_");
+ output_mangled_typename (header_file, t);
+ oprintf (header_file, "\n");
+ }
+ else
+ error_at_line (&s->u.s.line,
+ "structure alias is not a structure");
+ break;
+ }
+ if (opt)
+ continue;
+
+ /* Declare the marker procedure only once. */
+ oprintf (header_file, "extern void gt_pch_p_");
+ output_mangled_typename (header_file, s);
+ oprintf (header_file,
+ "\n (void *, void *, gt_pointer_operator, void *);\n");
+
+ if (s->kind == TYPE_LANG_STRUCT)
+ {
+ type_p ss;
+ for (ss = s->u.s.lang_struct; ss; ss = ss->next)
+ write_local_func_for_structure (s, ss, NULL);
+ }
+ else
+ write_local_func_for_structure (s, s, NULL);
+ }
+
+ for (s = param_structs; s; s = s->next)
+ if (s->gc_used == GC_POINTED_TO)
+ {
+ type_p * param = s->u.param_struct.param;
+ type_p stru = s->u.param_struct.stru;
+
+ /* Declare the marker procedure. */
+ oprintf (header_file, "extern void gt_pch_p_");
+ output_mangled_typename (header_file, s);
+ oprintf (header_file,
+ "\n (void *, void *, gt_pointer_operator, void *);\n");
+
+ if (stru->u.s.line.file == NULL)
+ {
+ fprintf (stderr, "warning: structure `%s' used but not defined\n",
+ s->u.s.tag);
+ continue;
+ }
+
+ if (stru->kind == TYPE_LANG_STRUCT)
+ {
+ type_p ss;
+ for (ss = stru->u.s.lang_struct; ss; ss = ss->next)
+ write_local_func_for_structure (s, ss, param);
+ }
+ else
+ write_local_func_for_structure (s, stru, param);
}
}
/* Write out the 'enum' definition for gt_types_enum. */
static void
-write_enum_defn (structures, param_structs)
- type_p structures;
- type_p param_structs;
+write_enum_defn (type_p structures, type_p param_structs)
{
type_p s;
-
+
oprintf (header_file, "\n/* Enumeration of types known. */\n");
oprintf (header_file, "enum gt_types_enum {\n");
for (s = structures; s; s = s->next)
@@ -2099,13 +2335,29 @@ write_enum_defn (structures, param_structs)
oprintf (header_file, "};\n");
}
+/* Might T contain any non-pointer elements? */
+
+static int
+contains_scalar_p (type_p t)
+{
+ switch (t->kind)
+ {
+ case TYPE_STRING:
+ case TYPE_POINTER:
+ return 0;
+ case TYPE_ARRAY:
+ return contains_scalar_p (t->u.a.p);
+ default:
+ /* Could also check for structures that have no non-pointer
+ fields, but there aren't enough of those to worry about. */
+ return 1;
+ }
+}
/* Mangle FN and print it to F. */
static void
-put_mangled_filename (f, fn)
- outf_p f;
- const char *fn;
+put_mangled_filename (outf_p f, const char *fn)
{
const char *name = get_output_file_name (fn);
for (; *name != 0; name++)
@@ -2120,16 +2372,11 @@ put_mangled_filename (f, fn)
the resulting code. */
static void
-finish_root_table (flp, pfx, lastname, tname, name)
- struct flist *flp;
- const char *pfx;
- const char *tname;
- const char *lastname;
- const char *name;
+finish_root_table (struct flist *flp, const char *pfx, const char *lastname,
+ const char *tname, const char *name)
{
struct flist *fli2;
- unsigned started_bitmap = 0;
-
+
for (fli2 = flp; fli2; fli2 = fli2->next)
if (fli2->started_p)
{
@@ -2147,13 +2394,22 @@ finish_root_table (flp, pfx, lastname, tname, name)
if (bitmap & 1)
{
oprintf (base_files[fnum],
- "extern const struct %s gt_ggc_%s_",
+ "extern const struct %s gt_%s_",
tname, pfx);
put_mangled_filename (base_files[fnum], fli2->name);
oprintf (base_files[fnum], "[];\n");
}
}
+ {
+ size_t fnum;
+ for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
+ oprintf (base_files [fnum],
+ "const struct %s * const %s[] = {\n",
+ tname, name);
+ }
+
+
for (fli2 = flp; fli2; fli2 = fli2->next)
if (fli2->started_p)
{
@@ -2165,29 +2421,19 @@ finish_root_table (flp, pfx, lastname, tname, name)
for (fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
if (bitmap & 1)
{
- if (! (started_bitmap & (1 << fnum)))
- {
- oprintf (base_files [fnum],
- "const struct %s * const %s[] = {\n",
- tname, name);
- started_bitmap |= 1 << fnum;
- }
- oprintf (base_files[fnum], " gt_ggc_%s_", pfx);
+ oprintf (base_files[fnum], " gt_%s_", pfx);
put_mangled_filename (base_files[fnum], fli2->name);
oprintf (base_files[fnum], ",\n");
}
}
{
- unsigned bitmap;
- int fnum;
-
- for (bitmap = started_bitmap, fnum = 0; bitmap != 0; fnum++, bitmap >>= 1)
- if (bitmap & 1)
- {
- oprintf (base_files[fnum], " NULL\n");
- oprintf (base_files[fnum], "};\n");
- }
+ size_t fnum;
+ for (fnum = 0; fnum < NUM_BASE_FILES; fnum++)
+ {
+ oprintf (base_files[fnum], " NULL\n");
+ oprintf (base_files[fnum], "};\n");
+ }
}
}
@@ -2197,14 +2443,8 @@ finish_root_table (flp, pfx, lastname, tname, name)
is nonzero iff we are building the root table for hash table caches. */
static void
-write_gc_root (f, v, type, name, has_length, line, if_marked)
- outf_p f;
- pair_p v;
- type_p type;
- const char *name;
- int has_length;
- struct fileloc *line;
- const char *if_marked;
+write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
+ struct fileloc *line, const char *if_marked)
{
switch (type->kind)
{
@@ -2216,7 +2456,7 @@ write_gc_root (f, v, type, name, has_length, line, if_marked)
int skip_p = 0;
const char *desc = NULL;
options_p o;
-
+
for (o = fld->opt; o; o = o->next)
if (strcmp (o->name, "skip") == 0)
skip_p = 1;
@@ -2226,26 +2466,26 @@ write_gc_root (f, v, type, name, has_length, line, if_marked)
error_at_line (line,
"field `%s' of global `%s' has unknown option `%s'",
fld->name, name, o->name);
-
+
if (skip_p)
continue;
else if (desc && fld->type->kind == TYPE_UNION)
{
pair_p validf = NULL;
pair_p ufld;
-
+
for (ufld = fld->type->u.s.fields; ufld; ufld = ufld->next)
{
const char *tag = NULL;
options_p oo;
-
+
for (oo = ufld->opt; oo; oo = oo->next)
if (strcmp (oo->name, "tag") == 0)
tag = (const char *)oo->info;
if (tag == NULL || strcmp (tag, desc) != 0)
continue;
if (validf != NULL)
- error_at_line (line,
+ error_at_line (line,
"both `%s.%s.%s' and `%s.%s.%s' have tag `%s'",
name, fld->name, validf->name,
name, fld->name, ufld->name,
@@ -2255,22 +2495,22 @@ write_gc_root (f, v, type, name, has_length, line, if_marked)
if (validf != NULL)
{
char *newname;
- newname = xasprintf ("%s.%s.%s",
+ newname = xasprintf ("%s.%s.%s",
name, fld->name, validf->name);
- write_gc_root (f, v, validf->type, newname, 0, line,
- if_marked);
+ write_root (f, v, validf->type, newname, 0, line,
+ if_marked);
free (newname);
}
}
else if (desc)
- error_at_line (line,
+ error_at_line (line,
"global `%s.%s' has `desc' option but is not union",
name, fld->name);
else
{
char *newname;
newname = xasprintf ("%s.%s", name, fld->name);
- write_gc_root (f, v, fld->type, newname, 0, line, if_marked);
+ write_root (f, v, fld->type, newname, 0, line, if_marked);
free (newname);
}
}
@@ -2281,19 +2521,19 @@ write_gc_root (f, v, type, name, has_length, line, if_marked)
{
char *newname;
newname = xasprintf ("%s[0]", name);
- write_gc_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
+ write_root (f, v, type->u.a.p, newname, has_length, line, if_marked);
free (newname);
}
break;
-
+
case TYPE_POINTER:
{
type_p ap, tp;
-
+
oprintf (f, " {\n");
oprintf (f, " &%s,\n", name);
oprintf (f, " 1");
-
+
for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
if (ap->u.a.len[0])
oprintf (f, " * (%s)", ap->u.a.len);
@@ -2304,26 +2544,30 @@ write_gc_root (f, v, type, name, has_length, line, if_marked)
for (ap = v->type; ap->kind == TYPE_ARRAY; ap = ap->u.a.p)
oprintf (f, "[0]");
oprintf (f, "),\n");
-
+
tp = type->u.p;
-
+
if (! has_length && UNION_OR_STRUCT_P (tp))
{
- oprintf (f, " &gt_ggc_mx_%s\n", tp->u.s.tag);
+ oprintf (f, " &gt_ggc_mx_%s,\n", tp->u.s.tag);
+ oprintf (f, " &gt_pch_nx_%s", tp->u.s.tag);
}
else if (! has_length && tp->kind == TYPE_PARAM_STRUCT)
{
oprintf (f, " &gt_ggc_m_");
output_mangled_typename (f, tp);
+ oprintf (f, ",\n &gt_pch_n_");
+ output_mangled_typename (f, tp);
}
else if (has_length
&& (tp->kind == TYPE_POINTER || UNION_OR_STRUCT_P (tp)))
{
- oprintf (f, " &gt_ggc_ma_%s", name);
+ oprintf (f, " &gt_ggc_ma_%s,\n", name);
+ oprintf (f, " &gt_pch_na_%s", name);
}
else
{
- error_at_line (line,
+ error_at_line (line,
"global `%s' is pointer to unimplemented type",
name);
}
@@ -2333,22 +2577,81 @@ write_gc_root (f, v, type, name, has_length, line, if_marked)
}
break;
- case TYPE_SCALAR:
case TYPE_STRING:
+ {
+ oprintf (f, " {\n");
+ oprintf (f, " &%s,\n", name);
+ oprintf (f, " 1, \n");
+ oprintf (f, " sizeof (%s),\n", v->name);
+ oprintf (f, " &gt_ggc_m_S,\n");
+ oprintf (f, " (gt_pointer_walker) &gt_pch_n_S\n");
+ oprintf (f, " },\n");
+ }
+ break;
+
+ case TYPE_SCALAR:
break;
-
+
default:
- error_at_line (line,
+ error_at_line (line,
"global `%s' is unimplemented type",
name);
}
}
+/* This generates a routine to walk an array. */
+
+static void
+write_array (outf_p f, pair_p v, const struct write_types_data *wtd)
+{
+ struct walk_type_data d;
+ char *prevval3;
+
+ memset (&d, 0, sizeof (d));
+ d.of = f;
+ d.cookie = wtd;
+ d.indent = 2;
+ d.line = &v->line;
+ d.opt = v->opt;
+ d.bitmap = get_base_file_bitmap (v->line.file);
+ d.param = NULL;
+
+ d.prev_val[3] = prevval3 = xasprintf ("&%s", v->name);
+
+ if (wtd->param_prefix)
+ {
+ oprintf (f, "static void gt_%sa_%s\n", wtd->param_prefix, v->name);
+ oprintf (f,
+ " (void *, void *, gt_pointer_operator, void *);\n");
+ oprintf (f, "static void gt_%sa_%s (void *this_obj ATTRIBUTE_UNUSED,\n",
+ wtd->param_prefix, v->name);
+ oprintf (d.of, " void *x_p ATTRIBUTE_UNUSED,\n");
+ oprintf (d.of, " gt_pointer_operator op ATTRIBUTE_UNUSED,\n");
+ oprintf (d.of, " void *cookie ATTRIBUTE_UNUSED)\n");
+ oprintf (d.of, "{\n");
+ d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
+ d.process_field = write_types_local_process_field;
+ walk_type (v->type, &d);
+ oprintf (f, "}\n\n");
+ }
+
+ d.opt = v->opt;
+ oprintf (f, "static void gt_%sa_%s (void *);\n",
+ wtd->prefix, v->name);
+ oprintf (f, "static void\ngt_%sa_%s (void *x_p ATTRIBUTE_UNUSED)\n",
+ wtd->prefix, v->name);
+ oprintf (f, "{\n");
+ d.prev_val[0] = d.prev_val[1] = d.prev_val[2] = d.val = v->name;
+ d.process_field = write_types_process_field;
+ walk_type (v->type, &d);
+ free (prevval3);
+ oprintf (f, "}\n\n");
+}
+
/* Output a table describing the locations and types of VARIABLES. */
static void
-write_gc_roots (variables)
- pair_p variables;
+write_roots (pair_p variables)
{
pair_p v;
struct flist *flp = NULL;
@@ -2368,14 +2671,14 @@ write_gc_roots (variables)
deletable_p = 1;
else if (strcmp (o->name, "param_is") == 0)
;
- else if (strncmp (o->name, "param", 5) == 0
+ else if (strncmp (o->name, "param", 5) == 0
&& ISDIGIT (o->name[5])
&& strcmp (o->name + 6, "_is") == 0)
;
else if (strcmp (o->name, "if_marked") == 0)
;
else
- error_at_line (&v->line,
+ error_at_line (&v->line,
"global `%s' has unknown option `%s'",
v->name, o->name);
@@ -2400,52 +2703,8 @@ write_gc_roots (variables)
&& (v->type->u.p->kind == TYPE_POINTER
|| v->type->u.p->kind == TYPE_STRUCT))
{
- oprintf (f, "static void gt_ggc_ma_%s PARAMS ((void *));\n",
- v->name);
- oprintf (f, "static void\ngt_ggc_ma_%s (x_p)\n void *x_p;\n",
- v->name);
- oprintf (f, "{\n");
- oprintf (f, " size_t i;\n");
-
- if (v->type->u.p->kind == TYPE_POINTER)
- {
- type_p s = v->type->u.p->u.p;
-
- oprintf (f, " %s %s ** const x = (%s %s **)x_p;\n",
- s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
- s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
- oprintf (f, " if (ggc_test_and_set_mark (x))\n");
- oprintf (f, " for (i = 0; i < (%s); i++)\n", length);
- if (! UNION_OR_STRUCT_P (s)
- && ! s->kind == TYPE_PARAM_STRUCT)
- {
- error_at_line (&v->line,
- "global `%s' has unsupported ** type",
- v->name);
- continue;
- }
-
- oprintf (f, " gt_ggc_m_");
- output_mangled_typename (f, s);
- oprintf (f, " (x[i]);\n");
- }
- else
- {
- type_p s = v->type->u.p;
-
- oprintf (f, " %s %s * const x = (%s %s *)x_p;\n",
- s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag,
- s->kind == TYPE_UNION ? "union" : "struct", s->u.s.tag);
- oprintf (f, " if (ggc_test_and_set_mark (x))\n");
- oprintf (f, " for (i = 0; i < (%s); i++)\n", length);
- oprintf (f, " {\n");
- write_gc_structure_fields (f, s, "x[i]", "x[i]",
- v->opt, 8, &v->line, s->u.s.bitmap,
- NULL);
- oprintf (f, " }\n");
- }
-
- oprintf (f, "}\n\n");
+ write_array (f, v, &ggc_wtd);
+ write_array (f, v, &pch_wtd);
}
}
@@ -2456,7 +2715,7 @@ write_gc_roots (variables)
int skip_p = 0;
int length_p = 0;
options_p o;
-
+
for (o = v->opt; o; o = o->next)
if (strcmp (o->name, "length") == 0)
length_p = 1;
@@ -2479,10 +2738,10 @@ write_gc_roots (variables)
oprintf (f, "[] = {\n");
}
- write_gc_root (f, v, v->type, v->name, length_p, &v->line, NULL);
+ write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
}
- finish_root_table (flp, "r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
+ finish_root_table (flp, "ggc_r", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
"gt_ggc_rtab");
for (v = variables; v; v = v->next)
@@ -2512,12 +2771,12 @@ write_gc_roots (variables)
put_mangled_filename (f, v->line.file);
oprintf (f, "[] = {\n");
}
-
- oprintf (f, " { &%s, 1, sizeof (%s), NULL },\n",
+
+ oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
v->name, v->name);
}
-
- finish_root_table (flp, "rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
+
+ finish_root_table (flp, "ggc_rd", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
"gt_ggc_deletable_rtab");
for (v = variables; v; v = v->next)
@@ -2527,7 +2786,7 @@ write_gc_roots (variables)
const char *if_marked = NULL;
int length_p = 0;
options_p o;
-
+
for (o = v->opt; o; o = o->next)
if (strcmp (o->name, "length") == 0)
length_p = 1;
@@ -2556,26 +2815,96 @@ write_gc_roots (variables)
put_mangled_filename (f, v->line.file);
oprintf (f, "[] = {\n");
}
-
- write_gc_root (f, v, v->type->u.p->u.param_struct.param[0],
+
+ write_root (f, v, v->type->u.p->u.param_struct.param[0],
v->name, length_p, &v->line, if_marked);
}
-
- finish_root_table (flp, "rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
+
+ finish_root_table (flp, "ggc_rc", "LAST_GGC_CACHE_TAB", "ggc_cache_tab",
"gt_ggc_cache_rtab");
+
+ for (v = variables; v; v = v->next)
+ {
+ outf_p f = get_output_file_with_visibility (v->line.file);
+ struct flist *fli;
+ int length_p = 0;
+ int if_marked_p = 0;
+ options_p o;
+
+ for (o = v->opt; o; o = o->next)
+ if (strcmp (o->name, "length") == 0)
+ length_p = 1;
+ else if (strcmp (o->name, "if_marked") == 0)
+ if_marked_p = 1;
+
+ if (! if_marked_p)
+ continue;
+
+ for (fli = flp; fli; fli = fli->next)
+ if (fli->f == f)
+ break;
+ if (! fli->started_p)
+ {
+ fli->started_p = 1;
+
+ oprintf (f, "const struct ggc_root_tab gt_pch_rc_");
+ put_mangled_filename (f, v->line.file);
+ oprintf (f, "[] = {\n");
+ }
+
+ write_root (f, v, v->type, v->name, length_p, &v->line, NULL);
+ }
+
+ finish_root_table (flp, "pch_rc", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
+ "gt_pch_cache_rtab");
+
+ for (v = variables; v; v = v->next)
+ {
+ outf_p f = get_output_file_with_visibility (v->line.file);
+ struct flist *fli;
+ int skip_p = 0;
+ options_p o;
+
+ for (o = v->opt; o; o = o->next)
+ if (strcmp (o->name, "deletable") == 0
+ || strcmp (o->name, "if_marked") == 0)
+ skip_p = 1;
+
+ if (skip_p)
+ continue;
+
+ if (! contains_scalar_p (v->type))
+ continue;
+
+ for (fli = flp; fli; fli = fli->next)
+ if (fli->f == f)
+ break;
+ if (! fli->started_p)
+ {
+ fli->started_p = 1;
+
+ oprintf (f, "const struct ggc_root_tab gt_pch_rs_");
+ put_mangled_filename (f, v->line.file);
+ oprintf (f, "[] = {\n");
+ }
+
+ oprintf (f, " { &%s, 1, sizeof (%s), NULL, NULL },\n",
+ v->name, v->name);
+ }
+
+ finish_root_table (flp, "pch_rs", "LAST_GGC_ROOT_TAB", "ggc_root_tab",
+ "gt_pch_scalar_rtab");
}
-extern int main PARAMS ((int argc, char **argv));
-int
-main(argc, argv)
- int argc ATTRIBUTE_UNUSED;
- char **argv ATTRIBUTE_UNUSED;
+extern int main (int argc, char **argv);
+int
+main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
{
unsigned i;
static struct fileloc pos = { __FILE__, __LINE__ };
unsigned j;
-
+
gen_rtx_next ();
srcdir_len = strlen (srcdir);
@@ -2585,10 +2914,10 @@ main(argc, argv)
do_scalar_typedef ("uint8", &pos);
do_scalar_typedef ("jword", &pos);
do_scalar_typedef ("JCF_u2", &pos);
+ do_scalar_typedef ("void", &pos);
+
+ do_typedef ("PTR", create_pointer (resolve_typedef ("void", &pos)), &pos);
- do_typedef ("PTR", create_pointer (create_scalar_type ("void",
- strlen ("void"))),
- &pos);
do_typedef ("HARD_REG_SET", create_array (
create_scalar_type ("unsigned long", strlen ("unsigned long")),
"2"), &pos);
@@ -2616,8 +2945,10 @@ main(argc, argv)
open_base_files ();
write_enum_defn (structures, param_structs);
- write_gc_types (structures, param_structs);
- write_gc_roots (variables);
+ write_types (structures, param_structs, &ggc_wtd);
+ write_types (structures, param_structs, &pch_wtd);
+ write_local (structures, param_structs);
+ write_roots (variables);
write_rtx_next ();
close_output_files ();
diff --git a/contrib/gcc/gengtype.h b/contrib/gcc/gengtype.h
index 0c23d95f44a6..3a3157ec3771 100644
--- a/contrib/gcc/gengtype.h
+++ b/contrib/gcc/gengtype.h
@@ -1,5 +1,5 @@
/* Process source files and output type information.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -111,36 +111,36 @@ extern struct fileloc lexer_line;
/* Print an error message. */
extern void error_at_line
- PARAMS ((struct fileloc *pos, const char *msg, ...)) ATTRIBUTE_PRINTF_2;
+ (struct fileloc *pos, const char *msg, ...) ATTRIBUTE_PRINTF_2;
/* Combines xmalloc() and vasprintf(). */
-extern int xvasprintf PARAMS ((char **, const char *, va_list))
+extern int xvasprintf (char **, const char *, va_list)
ATTRIBUTE_PRINTF (2, 0);
/* Like the above, but more convenient for quick coding. */
-extern char * xasprintf PARAMS ((const char *, ...))
+extern char * xasprintf (const char *, ...)
ATTRIBUTE_PRINTF_1;
/* Constructor routines for types. */
-extern void do_typedef PARAMS ((const char *s, type_p t, struct fileloc *pos));
-extern type_p resolve_typedef PARAMS ((const char *s, struct fileloc *pos));
-extern void new_structure PARAMS ((const char *name, int isunion,
- struct fileloc *pos, pair_p fields,
- options_p o));
-extern type_p find_structure PARAMS ((const char *s, int isunion));
-extern type_p create_scalar_type PARAMS ((const char *name, size_t name_len));
-extern type_p create_pointer PARAMS ((type_p t));
-extern type_p create_array PARAMS ((type_p t, const char *len));
-extern type_p adjust_field_type PARAMS ((type_p, options_p));
-extern void note_variable PARAMS ((const char *s, type_p t, options_p o,
- struct fileloc *pos));
-extern void note_yacc_type PARAMS ((options_p o, pair_p fields,
- pair_p typeinfo, struct fileloc *pos));
+extern void do_typedef (const char *s, type_p t, struct fileloc *pos);
+extern type_p resolve_typedef (const char *s, struct fileloc *pos);
+extern void new_structure (const char *name, int isunion,
+ struct fileloc *pos, pair_p fields,
+ options_p o);
+extern type_p find_structure (const char *s, int isunion);
+extern type_p create_scalar_type (const char *name, size_t name_len);
+extern type_p create_pointer (type_p t);
+extern type_p create_array (type_p t, const char *len);
+extern type_p adjust_field_type (type_p, options_p);
+extern void note_variable (const char *s, type_p t, options_p o,
+ struct fileloc *pos);
+extern void note_yacc_type (options_p o, pair_p fields,
+ pair_p typeinfo, struct fileloc *pos);
/* Lexer and parser routines, most automatically generated. */
-extern int yylex PARAMS((void));
-extern void yyerror PARAMS ((const char *));
-extern int yyparse PARAMS ((void));
-extern void parse_file PARAMS ((const char *name));
+extern int yylex (void);
+extern void yyerror (const char *);
+extern int yyparse (void);
+extern void parse_file (const char *name);
/* Output file handling. */
@@ -164,8 +164,8 @@ extern outf_p header_file;
made in INPUT_FILE and is linked into every language that uses
INPUT_FILE. */
extern outf_p get_output_file_with_visibility
- PARAMS ((const char *input_file));
-const char *get_output_file_name PARAMS ((const char *));
+ (const char *input_file);
+const char *get_output_file_name (const char *);
/* A list of output files suitable for definitions. There is one
BASE_FILES entry for each language. */
@@ -174,8 +174,8 @@ extern outf_p base_files[];
/* A bitmap that specifies which of BASE_FILES should be used to
output a definition that is different for each language and must be
defined once in each language that uses INPUT_FILE. */
-extern lang_bitmap get_base_file_bitmap PARAMS ((const char *input_file));
+extern lang_bitmap get_base_file_bitmap (const char *input_file);
/* Print, like fprintf, to O. */
-extern void oprintf PARAMS ((outf_p o, const char *S, ...))
+extern void oprintf (outf_p o, const char *S, ...)
ATTRIBUTE_PRINTF_2;
diff --git a/contrib/gcc/genmodes.c b/contrib/gcc/genmodes.c
new file mode 100644
index 000000000000..a09e45270657
--- /dev/null
+++ b/contrib/gcc/genmodes.c
@@ -0,0 +1,1220 @@
+/* Generate the machine mode enumeration and associated tables.
+ Copyright (C) 2003
+ 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "bconfig.h"
+#include "system.h"
+#include "errors.h"
+#include "hashtab.h"
+
+/* enum mode_class is normally defined by machmode.h but we can't
+ include that header here. */
+#include "mode-classes.def"
+
+#define DEF_MODE_CLASS(M) M
+enum mode_class { MODE_CLASSES, MAX_MODE_CLASS };
+#undef DEF_MODE_CLASS
+
+/* Text names of mode classes, for output. */
+#define DEF_MODE_CLASS(M) #M
+static const char *const mode_class_names[MAX_MODE_CLASS] =
+{
+ MODE_CLASSES
+};
+#undef DEF_MODE_CLASS
+#undef MODE_CLASSES
+
+#ifdef EXTRA_MODES_FILE
+# define HAVE_EXTRA_MODES 1
+#else
+# define HAVE_EXTRA_MODES 0
+# define EXTRA_MODES_FILE ""
+#endif
+
+/* Data structure for building up what we know about a mode.
+ They're clustered by mode class. */
+struct mode_data
+{
+ struct mode_data *next; /* next this class - arbitrary order */
+
+ const char *name; /* printable mode name -- SI, not SImode */
+ enum mode_class class; /* this mode class */
+ unsigned int precision; /* size in bits, equiv to TYPE_PRECISION */
+ unsigned int bytesize; /* storage size in addressable units */
+ unsigned int ncomponents; /* number of subunits */
+ unsigned int alignment; /* mode alignment */
+ const char *format; /* floating point format - MODE_FLOAT only */
+
+ struct mode_data *component; /* mode of components */
+ struct mode_data *wider; /* next wider mode */
+
+ struct mode_data *contained; /* Pointer to list of modes that have
+ this mode as a component. */
+ struct mode_data *next_cont; /* Next mode in that list. */
+
+ const char *file; /* file and line of definition, */
+ unsigned int line; /* for error reporting */
+};
+
+static struct mode_data *modes[MAX_MODE_CLASS];
+static unsigned int n_modes[MAX_MODE_CLASS];
+static struct mode_data *void_mode;
+
+static const struct mode_data blank_mode = {
+ 0, "<unknown>", MAX_MODE_CLASS,
+ -1, -1, -1, -1,
+ 0, 0, 0, 0, 0,
+ "<unknown>", 0
+};
+
+static htab_t modes_by_name;
+
+/* Data structure for recording target-specified runtime adjustments
+ to a particular mode. We support varying the byte size, the
+ alignment, and the floating point format. */
+struct mode_adjust
+{
+ struct mode_adjust *next;
+ struct mode_data *mode;
+ const char *adjustment;
+
+ const char *file;
+ unsigned int line;
+};
+
+static struct mode_adjust *adj_bytesize;
+static struct mode_adjust *adj_alignment;
+static struct mode_adjust *adj_format;
+
+/* Mode class operations. */
+static enum mode_class
+complex_class (enum mode_class class)
+{
+ switch (class)
+ {
+ case MODE_INT: return MODE_COMPLEX_INT;
+ case MODE_FLOAT: return MODE_COMPLEX_FLOAT;
+ default:
+ error ("no complex class for class %s", mode_class_names[class]);
+ return MODE_RANDOM;
+ }
+}
+
+static enum mode_class
+vector_class (enum mode_class class)
+{
+ switch (class)
+ {
+ case MODE_INT: return MODE_VECTOR_INT;
+ case MODE_FLOAT: return MODE_VECTOR_FLOAT;
+ default:
+ error ("no vector class for class %s", mode_class_names[class]);
+ return MODE_RANDOM;
+ }
+}
+
+/* Utility routines. */
+static inline struct mode_data *
+find_mode (const char *name)
+{
+ struct mode_data key;
+
+ key.name = name;
+ return htab_find (modes_by_name, &key);
+}
+
+static struct mode_data *
+new_mode (enum mode_class class, const char *name,
+ const char *file, unsigned int line)
+{
+ struct mode_data *m;
+
+ m = find_mode (name);
+ if (m)
+ {
+ error ("%s:%d: duplicate definition of mode \"%s\"",
+ trim_filename (file), line, name);
+ error ("%s:%d: previous definition here", m->file, m->line);
+ return m;
+ }
+
+ m = xmalloc (sizeof (struct mode_data));
+ memcpy (m, &blank_mode, sizeof (struct mode_data));
+ m->class = class;
+ m->name = name;
+ if (file)
+ m->file = trim_filename (file);
+ m->line = line;
+
+ m->next = modes[class];
+ modes[class] = m;
+ n_modes[class]++;
+
+ *htab_find_slot (modes_by_name, m, INSERT) = m;
+
+ return m;
+}
+
+static hashval_t
+hash_mode (const void *p)
+{
+ const struct mode_data *m = (const struct mode_data *)p;
+ return htab_hash_string (m->name);
+}
+
+static int
+eq_mode (const void *p, const void *q)
+{
+ const struct mode_data *a = (const struct mode_data *)p;
+ const struct mode_data *b = (const struct mode_data *)q;
+
+ return !strcmp (a->name, b->name);
+}
+
+#define for_all_modes(C, M) \
+ for (C = 0; C < MAX_MODE_CLASS; C++) \
+ for (M = modes[C]; M; M = M->next)
+
+static void ATTRIBUTE_UNUSED
+new_adjust (const char *name,
+ struct mode_adjust **category, const char *catname,
+ const char *adjustment,
+ enum mode_class required_class,
+ const char *file, unsigned int line)
+{
+ struct mode_data *mode = find_mode (name);
+ struct mode_adjust *a;
+
+ file = trim_filename (file);
+
+ if (!mode)
+ {
+ error ("%s:%d: no mode \"%s\"", file, line, name);
+ return;
+ }
+
+ if (required_class != MODE_RANDOM && mode->class != required_class)
+ {
+ error ("%s:%d: mode \"%s\" is not class %s",
+ file, line, name, mode_class_names[required_class] + 5);
+ return;
+ }
+
+ for (a = *category; a; a = a->next)
+ if (a->mode == mode)
+ {
+ error ("%s:%d: mode \"%s\" already has a %s adjustment",
+ file, line, name, catname);
+ error ("%s:%d: previous adjustment here", a->file, a->line);
+ return;
+ }
+
+ a = xmalloc (sizeof (struct mode_adjust));
+ a->mode = mode;
+ a->adjustment = adjustment;
+ a->file = file;
+ a->line = line;
+
+ a->next = *category;
+ *category = a;
+}
+
+/* Diagnose failure to meet expectations in a partially filled out
+ mode structure. */
+enum requirement { SET, UNSET, OPTIONAL };
+
+#define validate_field_(mname, fname, req, val, unset, file, line) do { \
+ switch (req) \
+ { \
+ case SET: \
+ if (val == unset) \
+ error ("%s:%d: (%s) field %s must be set", \
+ file, line, mname, fname); \
+ break; \
+ case UNSET: \
+ if (val != unset) \
+ error ("%s:%d: (%s) field %s must not be set", \
+ file, line, mname, fname); \
+ case OPTIONAL: \
+ break; \
+ } \
+} while (0)
+
+#define validate_field(M, F) \
+ validate_field_(M->name, #F, r_##F, M->F, blank_mode.F, M->file, M->line)
+
+static void
+validate_mode (struct mode_data *m,
+ enum requirement r_precision,
+ enum requirement r_bytesize,
+ enum requirement r_component,
+ enum requirement r_ncomponents,
+ enum requirement r_format)
+{
+ validate_field (m, precision);
+ validate_field (m, bytesize);
+ validate_field (m, component);
+ validate_field (m, ncomponents);
+ validate_field (m, format);
+}
+#undef validate_field
+#undef validate_field_
+
+/* Given a partially-filled-out mode structure, figure out what we can
+ and fill the rest of it in; die if it isn't enough. */
+static void
+complete_mode (struct mode_data *m)
+{
+ unsigned int alignment;
+
+ if (!m->name)
+ {
+ error ("%s:%d: mode with no name", m->file, m->line);
+ return;
+ }
+ if (m->class == MAX_MODE_CLASS)
+ {
+ error ("%s:%d: %smode has no mode class", m->file, m->line, m->name);
+ return;
+ }
+
+ switch (m->class)
+ {
+ case MODE_RANDOM:
+ /* Nothing more need be said. */
+ if (!strcmp (m->name, "VOID"))
+ void_mode = m;
+
+ validate_mode (m, UNSET, UNSET, UNSET, UNSET, UNSET);
+
+ m->precision = 0;
+ m->bytesize = 0;
+ m->ncomponents = 0;
+ m->component = 0;
+ break;
+
+ case MODE_CC:
+ /* Again, nothing more need be said. For historical reasons,
+ the size of a CC mode is four units. */
+ validate_mode (m, UNSET, UNSET, UNSET, UNSET, UNSET);
+
+ m->bytesize = 4;
+ m->ncomponents = 1;
+ m->component = 0;
+ break;
+
+ case MODE_INT:
+ case MODE_FLOAT:
+ /* A scalar mode must have a byte size, may have a bit size,
+ and must not have components. A float mode must have a
+ format. */
+ validate_mode (m, OPTIONAL, SET, UNSET, UNSET,
+ m->class == MODE_FLOAT ? SET : UNSET);
+
+ m->ncomponents = 1;
+ m->component = 0;
+ break;
+
+ case MODE_PARTIAL_INT:
+ /* A partial integer mode uses ->component to say what the
+ corresponding full-size integer mode is, and may also
+ specify a bit size. */
+ validate_mode (m, OPTIONAL, UNSET, SET, UNSET, UNSET);
+
+ m->bytesize = m->component->bytesize;
+
+ m->ncomponents = 1;
+ m->component = 0; /* ??? preserve this */
+ break;
+
+ case MODE_COMPLEX_INT:
+ case MODE_COMPLEX_FLOAT:
+ /* Complex modes should have a component indicated, but no more. */
+ validate_mode (m, UNSET, UNSET, SET, UNSET, UNSET);
+ m->ncomponents = 2;
+ if (m->component->precision != (unsigned int)-1)
+ m->precision = 2 * m->component->precision;
+ m->bytesize = 2 * m->component->bytesize;
+ break;
+
+ case MODE_VECTOR_INT:
+ case MODE_VECTOR_FLOAT:
+ /* Vector modes should have a component and a number of components. */
+ validate_mode (m, UNSET, UNSET, SET, SET, UNSET);
+ if (m->component->precision != (unsigned int)-1)
+ m->precision = m->ncomponents * m->component->precision;
+ m->bytesize = m->ncomponents * m->component->bytesize;
+ break;
+
+ default:
+ abort ();
+ }
+
+ /* If not already specified, the mode alignment defaults to the largest
+ power of two that divides the size of the object. Complex types are
+ not more aligned than their contents. */
+ if (m->class == MODE_COMPLEX_INT || m->class == MODE_COMPLEX_FLOAT)
+ alignment = m->component->bytesize;
+ else
+ alignment = m->bytesize;
+
+ m->alignment = alignment & (~alignment + 1);
+
+ /* If this mode has components, make the component mode point back
+ to this mode, for the sake of adjustments. */
+ if (m->component)
+ {
+ m->next_cont = m->component->contained;
+ m->component->contained = m;
+ }
+}
+
+static void
+complete_all_modes (void)
+{
+ struct mode_data *m;
+ enum mode_class c;
+
+ for_all_modes (c, m)
+ complete_mode (m);
+}
+
+/* For each mode in class CLASS, construct a corresponding complex mode. */
+#define COMPLEX_MODES(C) make_complex_modes(MODE_##C, __FILE__, __LINE__)
+static void
+make_complex_modes (enum mode_class class,
+ const char *file, unsigned int line)
+{
+ struct mode_data *m;
+ struct mode_data *c;
+ char buf[8];
+ enum mode_class cclass = complex_class (class);
+
+ if (cclass == MODE_RANDOM)
+ return;
+
+ for (m = modes[class]; m; m = m->next)
+ {
+ /* Skip BImode. FIXME: BImode probably shouldn't be MODE_INT. */
+ if (m->precision == 1)
+ continue;
+
+ if (strlen (m->name) >= sizeof buf)
+ {
+ error ("%s:%d:mode name \"%s\" is too long",
+ m->file, m->line, m->name);
+ continue;
+ }
+
+ /* Float complex modes are named SCmode, etc.
+ Int complex modes are named CSImode, etc.
+ This inconsistency should be eliminated. */
+ if (class == MODE_FLOAT)
+ {
+ char *p;
+ strncpy (buf, m->name, sizeof buf);
+ p = strchr (buf, 'F');
+ if (p == 0)
+ {
+ error ("%s:%d: float mode \"%s\" has no 'F'",
+ m->file, m->line, m->name);
+ continue;
+ }
+
+ *p = 'C';
+ }
+ else
+ snprintf (buf, sizeof buf, "C%s", m->name);
+
+ c = new_mode (cclass, xstrdup (buf), file, line);
+ c->component = m;
+ }
+}
+
+/* For all modes in class CLASS, construct vector modes of width
+ WIDTH, having as many components as necessary. */
+#define VECTOR_MODES(C, W) make_vector_modes(MODE_##C, W, __FILE__, __LINE__)
+static void
+make_vector_modes (enum mode_class class, unsigned int width,
+ const char *file, unsigned int line)
+{
+ struct mode_data *m;
+ struct mode_data *v;
+ char buf[8];
+ unsigned int ncomponents;
+ enum mode_class vclass = vector_class (class);
+
+ if (vclass == MODE_RANDOM)
+ return;
+
+ for (m = modes[class]; m; m = m->next)
+ {
+ /* Do not construct vector modes with only one element, or
+ vector modes where the element size doesn't divide the full
+ size evenly. */
+ ncomponents = width / m->bytesize;
+ if (ncomponents < 2)
+ continue;
+ if (width % m->bytesize)
+ continue;
+
+ /* Skip QFmode and BImode. FIXME: this special case should
+ not be necessary. */
+ if (class == MODE_FLOAT && m->bytesize == 1)
+ continue;
+ if (class == MODE_INT && m->precision == 1)
+ continue;
+
+ if ((size_t)snprintf (buf, sizeof buf, "V%u%s", ncomponents, m->name)
+ >= sizeof buf)
+ {
+ error ("%s:%d: mode name \"%s\" is too long",
+ m->file, m->line, m->name);
+ continue;
+ }
+
+ v = new_mode (vclass, xstrdup (buf), file, line);
+ v->component = m;
+ v->ncomponents = ncomponents;
+ }
+}
+
+/* Input. */
+
+#define _SPECIAL_MODE(C, N) make_special_mode(MODE_##C, #N, __FILE__, __LINE__)
+#define RANDOM_MODE(N) _SPECIAL_MODE (RANDOM, N)
+#define CC_MODE(N) _SPECIAL_MODE (CC, N)
+
+static void
+make_special_mode (enum mode_class class, const char *name,
+ const char *file, unsigned int line)
+{
+ new_mode (class, name, file, line);
+}
+
+#define INT_MODE(N, Y) FRACTIONAL_INT_MODE (N, -1, Y)
+#define FRACTIONAL_INT_MODE(N, B, Y) \
+ make_int_mode (#N, B, Y, __FILE__, __LINE__)
+
+static void
+make_int_mode (const char *name,
+ unsigned int precision, unsigned int bytesize,
+ const char *file, unsigned int line)
+{
+ struct mode_data *m = new_mode (MODE_INT, name, file, line);
+ m->bytesize = bytesize;
+ m->precision = precision;
+}
+
+#define FLOAT_MODE(N, Y, F) FRACTIONAL_FLOAT_MODE (N, -1, Y, F)
+#define FRACTIONAL_FLOAT_MODE(N, B, Y, F) \
+ make_float_mode (#N, B, Y, #F, __FILE__, __LINE__)
+
+static void
+make_float_mode (const char *name,
+ unsigned int precision, unsigned int bytesize,
+ const char *format,
+ const char *file, unsigned int line)
+{
+ struct mode_data *m = new_mode (MODE_FLOAT, name, file, line);
+ m->bytesize = bytesize;
+ m->precision = precision;
+ m->format = format;
+}
+
+#define RESET_FLOAT_FORMAT(N, F) \
+ reset_float_format (#N, #F, __FILE__, __LINE__)
+static void ATTRIBUTE_UNUSED
+reset_float_format (const char *name, const char *format,
+ const char *file, unsigned int line)
+{
+ struct mode_data *m = find_mode (name);
+ if (!m)
+ {
+ error ("%s:%d: no mode \"%s\"", file, line, name);
+ return;
+ }
+ if (m->class != MODE_FLOAT)
+ {
+ error ("%s:%d: mode \"%s\" is not class FLOAT", file, line, name);
+ return;
+ }
+ m->format = format;
+}
+
+/* Partial integer modes are specified by relation to a full integer mode.
+ For now, we do not attempt to narrow down their bit sizes. */
+#define PARTIAL_INT_MODE(M) \
+ make_partial_integer_mode (#M, "P" #M, -1, __FILE__, __LINE__)
+static void ATTRIBUTE_UNUSED
+make_partial_integer_mode (const char *base, const char *name,
+ unsigned int precision,
+ const char *file, unsigned int line)
+{
+ struct mode_data *m;
+ struct mode_data *component = find_mode (base);
+ if (!component)
+ {
+ error ("%s:%d: no mode \"%s\"", file, line, name);
+ return;
+ }
+ if (component->class != MODE_INT)
+ {
+ error ("%s:%d: mode \"%s\" is not class INT", file, line, name);
+ return;
+ }
+
+ m = new_mode (MODE_PARTIAL_INT, name, file, line);
+ m->precision = precision;
+ m->component = component;
+}
+
+/* A single vector mode can be specified by naming its component
+ mode and the number of components. */
+#define VECTOR_MODE(C, M, N) \
+ make_vector_mode (MODE_##C, #M, N, __FILE__, __LINE__);
+static void ATTRIBUTE_UNUSED
+make_vector_mode (enum mode_class bclass,
+ const char *base,
+ unsigned int ncomponents,
+ const char *file, unsigned int line)
+{
+ struct mode_data *v;
+ enum mode_class vclass = vector_class (bclass);
+ struct mode_data *component = find_mode (base);
+ char namebuf[8];
+
+ if (vclass == MODE_RANDOM)
+ return;
+ if (component == 0)
+ {
+ error ("%s:%d: no mode \"%s\"", file, line, base);
+ return;
+ }
+ if (component->class != bclass)
+ {
+ error ("%s:%d: mode \"%s\" is not class %s",
+ file, line, base, mode_class_names[bclass] + 5);
+ return;
+ }
+
+ if ((size_t)snprintf (namebuf, sizeof namebuf, "V%u%s",
+ ncomponents, base) >= sizeof namebuf)
+ {
+ error ("%s:%d: mode name \"%s\" is too long",
+ base, file, line);
+ return;
+ }
+
+ v = new_mode (vclass, xstrdup (namebuf), file, line);
+ v->ncomponents = ncomponents;
+ v->component = component;
+}
+
+/* Adjustability. */
+#define _ADD_ADJUST(A, M, X, C) \
+ new_adjust (#M, &adj_##A, #A, #X, MODE_##C, __FILE__, __LINE__)
+
+#define ADJUST_BYTESIZE(M, X) _ADD_ADJUST(bytesize, M, X, RANDOM)
+#define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST(alignment, M, X, RANDOM)
+#define ADJUST_FLOAT_FORMAT(M, X) _ADD_ADJUST(format, M, X, FLOAT)
+
+static void
+create_modes (void)
+{
+#include "machmode.def"
+}
+
+/* Processing. */
+
+/* Sort a list of modes into the order needed for the WIDER field:
+ major sort by precision, minor sort by component precision.
+
+ For instance:
+ QI < HI < SI < DI < TI
+ V4QI < V2HI < V8QI < V4HI < V2SI.
+
+ If the precision is not set, sort by the bytesize. A mode with
+ precision set gets sorted before a mode without precision set, if
+ they have the same bytesize; this is the right thing because
+ the precision must always be smaller than the bytesize * BITS_PER_UNIT.
+ We don't have to do anything special to get this done -- an unset
+ precision shows up as (unsigned int)-1, i.e. UINT_MAX. */
+static int
+cmp_modes (const void *a, const void *b)
+{
+ struct mode_data *m = *(struct mode_data **)a;
+ struct mode_data *n = *(struct mode_data **)b;
+
+ if (m->bytesize > n->bytesize)
+ return 1;
+ else if (m->bytesize < n->bytesize)
+ return -1;
+
+ if (m->precision > n->precision)
+ return 1;
+ else if (m->precision < n->precision)
+ return -1;
+
+ if (!m->component && !n->component)
+ return 0;
+
+ if (m->component->bytesize > n->component->bytesize)
+ return 1;
+ else if (m->component->bytesize < n->component->bytesize)
+ return -1;
+
+ if (m->component->precision > n->component->precision)
+ return 1;
+ else if (m->component->precision < n->component->precision)
+ return -1;
+
+ return 0;
+}
+
+static void
+calc_wider_mode (void)
+{
+ enum mode_class c;
+ struct mode_data *m;
+ struct mode_data **sortbuf;
+ unsigned int max_n_modes = 0;
+ unsigned int i, j;
+
+ for (c = 0; c < MAX_MODE_CLASS; c++)
+ max_n_modes = MAX (max_n_modes, n_modes[c]);
+
+ /* Allocate max_n_modes + 1 entries to leave room for the extra null
+ pointer assigned after the qsort call below. */
+ sortbuf = alloca ((max_n_modes + 1) * sizeof (struct mode_data *));
+
+ for (c = 0; c < MAX_MODE_CLASS; c++)
+ {
+ /* "wider" is not meaningful for MODE_RANDOM and MODE_CC.
+ However, we want these in textual order, and we have
+ precisely the reverse. */
+ if (c == MODE_RANDOM || c == MODE_CC)
+ {
+ struct mode_data *prev, *next;
+
+ for (prev = 0, m = modes[c]; m; m = next)
+ {
+ m->wider = void_mode;
+
+ /* this is nreverse */
+ next = m->next;
+ m->next = prev;
+ prev = m;
+ }
+ modes[c] = prev;
+ }
+ else
+ {
+ if (!modes[c])
+ continue;
+
+ for (i = 0, m = modes[c]; m; i++, m = m->next)
+ sortbuf[i] = m;
+
+ qsort (sortbuf, i, sizeof (struct mode_data *), cmp_modes);
+
+ sortbuf[i] = 0;
+ for (j = 0; j < i; j++)
+ sortbuf[j]->next = sortbuf[j]->wider = sortbuf[j + 1];
+
+
+ modes[c] = sortbuf[0];
+ }
+ }
+}
+
+/* Output routines. */
+
+#define tagged_printf(FMT, ARG, TAG) do { \
+ int count_; \
+ printf (" " FMT ",%n", ARG, &count_); \
+ printf ("%*s/* %s */\n", 27 - count_, "", TAG); \
+} while (0)
+
+#define print_decl(TYPE, NAME, ASIZE) \
+ puts ("\nconst " TYPE " " NAME "[" ASIZE "] =\n{");
+
+#define print_maybe_const_decl(TYPE, NAME, ASIZE, CATEGORY) \
+ printf ("\n" TYPE " " NAME "[" ASIZE "] = \n{\n", \
+ adj_##CATEGORY ? "" : "const ")
+
+#define print_closer() puts ("};")
+
+static void
+emit_insn_modes_h (void)
+{
+ enum mode_class c;
+ struct mode_data *m, *first, *last;
+
+ printf ("/* Generated automatically from machmode.def%s%s\n",
+ HAVE_EXTRA_MODES ? " and " : "",
+ EXTRA_MODES_FILE);
+
+ puts ("\
+ by genmodes. */\n\
+\n\
+#ifndef GCC_INSN_MODES_H\n\
+#define GCC_INSN_MODES_H\n\
+\n\
+enum machine_mode\n{");
+
+ for (c = 0; c < MAX_MODE_CLASS; c++)
+ for (m = modes[c]; m; m = m->next)
+ {
+ int count_;
+ printf (" %smode,%n", m->name, &count_);
+ printf ("%*s/* %s:%d */\n", 27 - count_, "",
+ trim_filename (m->file), m->line);
+ }
+
+ puts (" MAX_MACHINE_MODE,\n");
+
+ for (c = 0; c < MAX_MODE_CLASS; c++)
+ {
+ first = modes[c];
+ last = 0;
+ for (m = first; m; last = m, m = m->next)
+ ;
+
+ /* Don't use BImode for MIN_MODE_INT, since otherwise the middle
+ end will try to use it for bitfields in structures and the
+ like, which we do not want. Only the target md file should
+ generate BImode widgets. */
+ if (first && first->precision == 1)
+ first = first->next;
+
+ if (first && last)
+ printf (" MIN_%s = %smode,\n MAX_%s = %smode,\n\n",
+ mode_class_names[c], first->name,
+ mode_class_names[c], last->name);
+ else
+ printf (" MIN_%s = %smode,\n MAX_%s = %smode,\n\n",
+ mode_class_names[c], void_mode->name,
+ mode_class_names[c], void_mode->name);
+ }
+
+ puts ("\
+ NUM_MACHINE_MODES = MAX_MACHINE_MODE\n\
+};\n");
+
+ /* I can't think of a better idea, can you? */
+ printf ("#define CONST_MODE_SIZE%s\n", adj_bytesize ? "" : " const");
+ printf ("#define CONST_MODE_BASE_ALIGN%s\n", adj_alignment ? "" : " const");
+#if 0 /* disabled for backward compatibility, temporary */
+ printf ("#define CONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :" const");
+#endif
+ puts ("\
+\n\
+#endif /* insn-modes.h */");
+}
+
+static void
+emit_insn_modes_c_header (void)
+{
+ printf ("/* Generated automatically from machmode.def%s%s\n",
+ HAVE_EXTRA_MODES ? " and " : "",
+ EXTRA_MODES_FILE);
+
+ puts ("\
+ by genmodes. */\n\
+\n\
+#include \"config.h\"\n\
+#include \"system.h\"\n\
+#include \"coretypes.h\"\n\
+#include \"tm.h\"\n\
+#include \"machmode.h\"\n\
+#include \"real.h\"");
+}
+
+static void
+emit_min_insn_modes_c_header (void)
+{
+ printf ("/* Generated automatically from machmode.def%s%s\n",
+ HAVE_EXTRA_MODES ? " and " : "",
+ EXTRA_MODES_FILE);
+
+ puts ("\
+ by genmodes. */\n\
+\n\
+#include \"bconfig.h\"\n\
+#include \"system.h\"\n\
+#include \"machmode.h\"");
+}
+
+static void
+emit_mode_name (void)
+{
+ enum mode_class c;
+ struct mode_data *m;
+
+ print_decl ("char *const", "mode_name", "NUM_MACHINE_MODES");
+
+ for_all_modes (c, m)
+ printf (" \"%s\",\n", m->name);
+
+ print_closer ();
+}
+
+static void
+emit_mode_class (void)
+{
+ enum mode_class c;
+ struct mode_data *m;
+
+ print_decl ("unsigned char", "mode_class", "NUM_MACHINE_MODES");
+
+ for_all_modes (c, m)
+ tagged_printf ("%s", mode_class_names[m->class], m->name);
+
+ print_closer ();
+}
+
+static void
+emit_mode_precision (void)
+{
+ enum mode_class c;
+ struct mode_data *m;
+
+ print_decl ("unsigned short", "mode_precision", "NUM_MACHINE_MODES");
+
+ for_all_modes (c, m)
+ if (m->precision != (unsigned int)-1)
+ tagged_printf ("%u", m->precision, m->name);
+ else
+ tagged_printf ("%u*BITS_PER_UNIT", m->bytesize, m->name);
+
+ print_closer ();
+}
+
+static void
+emit_mode_size (void)
+{
+ enum mode_class c;
+ struct mode_data *m;
+
+ print_maybe_const_decl ("%sunsigned char", "mode_size",
+ "NUM_MACHINE_MODES", bytesize);
+
+ for_all_modes (c, m)
+ tagged_printf ("%u", m->bytesize, m->name);
+
+ print_closer ();
+}
+
+static void
+emit_mode_nunits (void)
+{
+ enum mode_class c;
+ struct mode_data *m;
+
+ print_decl ("unsigned char", "mode_nunits", "NUM_MACHINE_MODES");
+
+ for_all_modes (c, m)
+ tagged_printf ("%u", m->ncomponents, m->name);
+
+ print_closer ();
+}
+
+static void
+emit_mode_wider (void)
+{
+ enum mode_class c;
+ struct mode_data *m;
+
+ print_decl ("unsigned char", "mode_wider", "NUM_MACHINE_MODES");
+
+ for_all_modes (c, m)
+ tagged_printf ("%smode",
+ m->wider ? m->wider->name : void_mode->name,
+ m->name);
+
+ print_closer ();
+}
+
+static void
+emit_mode_mask (void)
+{
+ enum mode_class c;
+ struct mode_data *m;
+
+ print_decl ("unsigned HOST_WIDE_INT", "mode_mask_array",
+ "NUM_MACHINE_MODES");
+ puts ("\
+#define MODE_MASK(m) \\\n\
+ ((m) >= HOST_BITS_PER_WIDE_INT) \\\n\
+ ? ~(unsigned HOST_WIDE_INT) 0 \\\n\
+ : ((unsigned HOST_WIDE_INT) 1 << (m)) - 1\n");
+
+ for_all_modes (c, m)
+ if (m->precision != (unsigned int)-1)
+ tagged_printf ("MODE_MASK (%u)", m->precision, m->name);
+ else
+ tagged_printf ("MODE_MASK (%u*BITS_PER_UNIT)", m->bytesize, m->name);
+
+ puts ("#undef MODE_MASK");
+ print_closer ();
+}
+
+static void
+emit_mode_inner (void)
+{
+ enum mode_class c;
+ struct mode_data *m;
+
+ print_decl ("unsigned char", "mode_inner", "NUM_MACHINE_MODES");
+
+ for_all_modes (c, m)
+ tagged_printf ("%smode",
+ m->component ? m->component->name : void_mode->name,
+ m->name);
+
+ print_closer ();
+}
+
+static void
+emit_mode_base_align (void)
+{
+ enum mode_class c;
+ struct mode_data *m;
+
+ print_maybe_const_decl ("%sunsigned char",
+ "mode_base_align", "NUM_MACHINE_MODES",
+ alignment);
+
+ for_all_modes (c, m)
+ tagged_printf ("%u", m->alignment, m->name);
+
+ print_closer ();
+}
+
+static void
+emit_class_narrowest_mode (void)
+{
+ enum mode_class c;
+
+ print_decl ("unsigned char", "class_narrowest_mode", "MAX_MODE_CLASS");
+
+ for (c = 0; c < MAX_MODE_CLASS; c++)
+ /* Bleah, all this to get the comment right for MIN_MODE_INT. */
+ tagged_printf ("MIN_%s", mode_class_names[c],
+ modes[c]
+ ? (modes[c]->precision != 1
+ ? modes[c]->name
+ : (modes[c]->next
+ ? modes[c]->next->name
+ : void_mode->name))
+ : void_mode->name);
+
+ print_closer ();
+}
+
+static void
+emit_real_format_for_mode (void)
+{
+ struct mode_data *m;
+
+ /* The entities pointed to by this table are constant, whether
+ or not the table itself is constant.
+
+ For backward compatibility this table is always writable
+ (several targets modify it in OVERRIDE_OPTIONS). FIXME:
+ convert all said targets to use ADJUST_FORMAT instead. */
+#if 0
+ print_maybe_const_decl ("const struct real_format *%s",
+ "real_format_for_mode",
+ "MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1",
+ format);
+#else
+ print_decl ("struct real_format *\n", "real_format_for_mode",
+ "MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1");
+#endif
+
+ for (m = modes[MODE_FLOAT]; m; m = m->next)
+ if (!strcmp (m->format, "0"))
+ tagged_printf ("%s", m->format, m->name);
+ else
+ tagged_printf ("&%s", m->format, m->name);
+
+ print_closer ();
+}
+
+static void
+emit_mode_adjustments (void)
+{
+ struct mode_adjust *a;
+ struct mode_data *m;
+
+ puts ("\
+\nvoid\
+\ninit_adjust_machine_modes (void)\
+\n{\
+\n size_t s ATTRIBUTE_UNUSED;");
+
+ /* Size adjustments must be propagated to all containing modes.
+ A size adjustment forces us to recalculate the alignment too. */
+ for (a = adj_bytesize; a; a = a->next)
+ {
+ printf ("\n /* %s:%d */\n s = %s;\n",
+ a->file, a->line, a->adjustment);
+ printf (" mode_size[%smode] = s;\n", a->mode->name);
+ printf (" mode_base_align[%smode] = s & (~s + 1);\n",
+ a->mode->name);
+
+ for (m = a->mode->contained; m; m = m->next_cont)
+ {
+ switch (m->class)
+ {
+ case MODE_COMPLEX_INT:
+ case MODE_COMPLEX_FLOAT:
+ printf (" mode_size[%smode] = 2*s;\n", m->name);
+ printf (" mode_base_align[%smode] = s & (~s + 1);\n",
+ m->name);
+ break;
+
+ case MODE_VECTOR_INT:
+ case MODE_VECTOR_FLOAT:
+ printf (" mode_size[%smode] = %d*s;\n",
+ m->name, m->ncomponents);
+ printf (" mode_base_align[%smode] = (%d*s) & (~(%d*s)+1);\n",
+ m->name, m->ncomponents, m->ncomponents);
+ break;
+
+ default:
+ internal_error (
+ "mode %s is neither vector nor complex but contains %s",
+ m->name, a->mode->name);
+ /* NOTREACHED */
+ }
+ }
+ }
+
+ /* Alignment adjustments propagate too.
+ ??? This may not be the right thing for vector modes. */
+ for (a = adj_alignment; a; a = a->next)
+ {
+ printf ("\n /* %s:%d */\n s = %s;\n",
+ a->file, a->line, a->adjustment);
+ printf (" mode_base_align[%smode] = s;\n", a->mode->name);
+
+ for (m = a->mode->contained; m; m = m->next_cont)
+ {
+ switch (m->class)
+ {
+ case MODE_COMPLEX_INT:
+ case MODE_COMPLEX_FLOAT:
+ printf (" mode_base_align[%smode] = s;\n", m->name);
+ break;
+
+ case MODE_VECTOR_INT:
+ case MODE_VECTOR_FLOAT:
+ printf (" mode_base_align[%smode] = %d*s;\n",
+ m->name, m->ncomponents);
+ break;
+
+ default:
+ internal_error (
+ "mode %s is neither vector nor complex but contains %s",
+ m->name, a->mode->name);
+ /* NOTREACHED */
+ }
+ }
+ }
+
+ /* Real mode formats don't have to propagate anywhere. */
+ for (a = adj_format; a; a = a->next)
+ printf ("\n /* %s:%d */\n REAL_MODE_FORMAT (%smode) = %s;\n",
+ a->file, a->line, a->mode->name, a->adjustment);
+
+ puts ("}");
+}
+
+static void
+emit_insn_modes_c (void)
+{
+ emit_insn_modes_c_header ();
+ emit_mode_name ();
+ emit_mode_class ();
+ emit_mode_precision ();
+ emit_mode_size ();
+ emit_mode_nunits ();
+ emit_mode_wider ();
+ emit_mode_mask ();
+ emit_mode_inner ();
+ emit_mode_base_align ();
+ emit_class_narrowest_mode ();
+ emit_real_format_for_mode ();
+ emit_mode_adjustments ();
+}
+
+static void
+emit_min_insn_modes_c (void)
+{
+ emit_min_insn_modes_c_header ();
+ emit_mode_name ();
+ emit_mode_class ();
+ emit_mode_wider ();
+ emit_class_narrowest_mode ();
+}
+
+/* Master control. */
+int
+main(int argc, char **argv)
+{
+ bool gen_header = false, gen_min = false;
+ progname = argv[0];
+
+ if (argc == 1)
+ ;
+ else if (argc == 2 && !strcmp (argv[1], "-h"))
+ gen_header = true;
+ else if (argc == 2 && !strcmp (argv[1], "-m"))
+ gen_min = true;
+ else
+ {
+ error ("usage: %s [-h|-m] > file", progname);
+ return FATAL_EXIT_CODE;
+ }
+
+ modes_by_name = htab_create_alloc (64, hash_mode, eq_mode, 0, xcalloc, free);
+
+ create_modes ();
+ complete_all_modes ();
+
+ if (have_error)
+ return FATAL_EXIT_CODE;
+
+ calc_wider_mode ();
+
+ if (gen_header)
+ emit_insn_modes_h ();
+ else if (gen_min)
+ emit_min_insn_modes_c ();
+ else
+ emit_insn_modes_c ();
+
+ if (fflush (stdout) || fclose (stdout))
+ return FATAL_EXIT_CODE;
+ return SUCCESS_EXIT_CODE;
+}
diff --git a/contrib/gcc/genmultilib b/contrib/gcc/genmultilib
index ca3b71bdfa3d..3cac4e9ad7a2 100644
--- a/contrib/gcc/genmultilib
+++ b/contrib/gcc/genmultilib
@@ -1,6 +1,6 @@
#!/bin/sh
# Generates multilib.h.
-# Copyright (C) 1994, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995, 1996, 1997, 1999, 2002 Free Software Foundation, Inc.
#This file is part of GCC.
@@ -63,10 +63,15 @@
# for the rule to exclude a set. Options can be preceded with a '!' to
# match a logical NOT.
-# The optional sevenths argument is a list of OS subdirectory names.
-# The format is the same as of the second argument.
-# The difference is that second argument describes multilib directories
-# in GCC conventions, while this one the OS multilib convention.
+# The optional seventh argument is a list of OS subdirectory names.
+# The format is either the same as of the second argument, or a set of
+# mappings. When it is the same as the second argument, it describes
+# the multilib directories using OS conventions, rather than GCC
+# conventions. When it is a set of mappings of the form gccdir=osdir,
+# the left side gives the GCC convention and the right gives the
+# equivalent OS defined location. If the osdir part begins with a !,
+# the os directory names are used exclusively. Use the mapping when
+# there is no one-to-one equivalence between GCC levels and the OS.
# The last option should be "yes" if multilibs are enabled. If it is not
# "yes", all GCC multilib dir names will be ".".
@@ -120,6 +125,10 @@ enable_multilib=$8
echo "static const char *const multilib_raw[] = {"
+mkdir tmpmultilib.$$ || exit 1
+# Use cd ./foo to avoid CDPATH output.
+cd ./tmpmultilib.$$ || exit 1
+
# What we want to do is select all combinations of the sets in
# options. Each combination which includes a set of mutually
# exclusive options must then be output multiple times, once for each
@@ -161,11 +170,8 @@ chmod +x tmpmultilib
combinations=`initial=/ ./tmpmultilib ${options}`
-rm -f tmpmultilib
-
# If there exceptions, weed them out now
if [ -n "${exceptions}" ]; then
- rm -f tmpmultilib2
cat >tmpmultilib2 <<\EOF
#!/bin/sh
# This recursive script weeds out any combination of multilib
@@ -187,7 +193,6 @@ cat >>tmpmultilib2 <<\EOF
EOF
chmod +x tmpmultilib2
combinations=`./tmpmultilib2 ${combinations}`
- rm -f ./tmpmultilib2
fi
# Construct a sed pattern which will convert option names to directory
@@ -216,24 +221,44 @@ fi
# Construct a sed pattern which will convert option names to OS directory
# names.
toosdirnames=
+defaultosdirname=
if [ -n "${osdirnames}" ]; then
set x ${osdirnames}
shift
- for set in ${options}; do
- for opts in `echo ${set} | sed -e 's|/| |'g`; do
- patt="/"
- for opt in `echo ${opts} | sed -e 's_|_ _'g`; do
- if [ "$1" != "${opt}" ]; then
- toosdirnames="${toosdirnames} -e s|/${opt}/|/${1}/|g"
- patt="${patt}${1}/"
- if [ "${patt}" != "/${1}/" ]; then
- toosdirnames="${toosdirnames} -e s|${patt}|/${1}/|g"
+ while [ $# != 0 ] ; do
+ case "$1" in
+ .=*)
+ defaultosdirname=`echo $1 | sed 's|^.=|:|'`
+ shift
+ ;;
+ *=*)
+ patt=`echo $1 | sed -e 's|=|/$=/|'`
+ toosdirnames="${toosdirnames} -e s=^/${patt}/="
+ shift
+ ;;
+ *)
+ break
+ ;;
+ esac
+ done
+
+ if [ $# != 0 ]; then
+ for set in ${options}; do
+ for opts in `echo ${set} | sed -e 's|/| |'g`; do
+ patt="/"
+ for opt in `echo ${opts} | sed -e 's_|_ _'g`; do
+ if [ "$1" != "${opt}" ]; then
+ toosdirnames="${toosdirnames} -e s|/${opt}/|/${1}/|g"
+ patt="${patt}${1}/"
+ if [ "${patt}" != "/${1}/" ]; then
+ toosdirnames="${toosdirnames} -e s|${patt}|/${1}/|g"
+ fi
fi
- fi
+ done
+ shift
done
- shift
done
- done
+ fi
fi
# We need another recursive shell script to correctly handle positive
@@ -275,7 +300,7 @@ for set in ${options}; do
done
done
optout=`echo ${optout} | sed -e 's/^ //'`
-echo "\". ${optout};\","
+echo "\".${defaultosdirname} ${optout};\","
# Work over the list of combinations. We have to translate each one
# to use the directory names rather than the option names, we have to
@@ -298,8 +323,16 @@ for combo in ${combinations}; do
osdirout=`echo ${osdirout} | sed -e 's|^/||' -e 's|/$||g'`
if [ "x${enable_multilib}" != xyes ]; then
dirout=".:${osdirout}"
+ disable_multilib=yes
else
- dirout="${dirout}:${osdirout}"
+ case "${osdirout}" in
+ !*)
+ dirout=`echo ${osdirout} | sed 's/^!//'`
+ ;;
+ *)
+ dirout="${dirout}:${osdirout}"
+ ;;
+ esac
fi
else
if [ "x${enable_multilib}" != xyes ]; then
@@ -371,6 +404,13 @@ moptions=`echo ${options} | sed -e 's,[ ][ ]*, ,g'`
echo ""
echo "static const char *multilib_options = \"${moptions}\";"
-rm -f tmpmultilib2
+# Finally output the disable flag if specified
+if [ "x${disable_multilib}" = xyes ]; then
+ echo ""
+ echo "#define DISABLE_MULTILIB 1"
+fi
+
+cd ..
+rm -r tmpmultilib.$$
exit 0
diff --git a/contrib/gcc/genopinit.c b/contrib/gcc/genopinit.c
index ef4242a64cd4..5e1599ad80f1 100644
--- a/contrib/gcc/genopinit.c
+++ b/contrib/gcc/genopinit.c
@@ -1,6 +1,6 @@
/* Generate code to initialize optabs from machine description.
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,8 +20,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "gensupport.h"
@@ -57,32 +59,33 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
upper-case forms of the comparison, respectively. */
static const char * const optabs[] =
-{ "extendtab[$B][$A][0] = CODE_FOR_$(extend$a$b2$)",
- "extendtab[$B][$A][1] = CODE_FOR_$(zero_extend$a$b2$)",
- "fixtab[$A][$B][0] = CODE_FOR_$(fix$F$a$I$b2$)",
- "fixtab[$A][$B][1] = CODE_FOR_$(fixuns$F$a$b2$)",
- "fixtrunctab[$A][$B][0] = CODE_FOR_$(fix_trunc$F$a$I$b2$)",
- "fixtrunctab[$A][$B][1] = CODE_FOR_$(fixuns_trunc$F$a$I$b2$)",
- "floattab[$B][$A][0] = CODE_FOR_$(float$I$a$F$b2$)",
- "floattab[$B][$A][1] = CODE_FOR_$(floatuns$I$a$F$b2$)",
+{ "sext_optab->handlers[$B][$A].insn_code = CODE_FOR_$(extend$a$b2$)",
+ "zext_optab->handlers[$B][$A].insn_code = CODE_FOR_$(zero_extend$a$b2$)",
+ "sfix_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fix$F$a$I$b2$)",
+ "ufix_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fixuns$F$a$b2$)",
+ "sfixtrunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fix_trunc$F$a$I$b2$)",
+ "ufixtrunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(fixuns_trunc$F$a$I$b2$)",
+ "sfloat_optab->handlers[$B][$A].insn_code = CODE_FOR_$(float$I$a$F$b2$)",
+ "ufloat_optab->handlers[$B][$A].insn_code = CODE_FOR_$(floatuns$I$a$F$b2$)",
+ "trunc_optab->handlers[$B][$A].insn_code = CODE_FOR_$(trunc$a$b2$)",
"add_optab->handlers[$A].insn_code = CODE_FOR_$(add$P$a3$)",
- "addv_optab->handlers[(int) $A].insn_code =\n\
- add_optab->handlers[(int) $A].insn_code = CODE_FOR_$(add$F$a3$)",
- "addv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(addv$I$a3$)",
+ "addv_optab->handlers[$A].insn_code =\n\
+ add_optab->handlers[$A].insn_code = CODE_FOR_$(add$F$a3$)",
+ "addv_optab->handlers[$A].insn_code = CODE_FOR_$(addv$I$a3$)",
"sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$P$a3$)",
- "subv_optab->handlers[(int) $A].insn_code =\n\
- sub_optab->handlers[(int) $A].insn_code = CODE_FOR_$(sub$F$a3$)",
- "subv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(subv$I$a3$)",
+ "subv_optab->handlers[$A].insn_code =\n\
+ sub_optab->handlers[$A].insn_code = CODE_FOR_$(sub$F$a3$)",
+ "subv_optab->handlers[$A].insn_code = CODE_FOR_$(subv$I$a3$)",
"smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$P$a3$)",
- "smulv_optab->handlers[(int) $A].insn_code =\n\
- smul_optab->handlers[(int) $A].insn_code = CODE_FOR_$(mul$F$a3$)",
- "smulv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(mulv$I$a3$)",
+ "smulv_optab->handlers[$A].insn_code =\n\
+ smul_optab->handlers[$A].insn_code = CODE_FOR_$(mul$F$a3$)",
+ "smulv_optab->handlers[$A].insn_code = CODE_FOR_$(mulv$I$a3$)",
"umul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(umul$a3_highpart$)",
"smul_highpart_optab->handlers[$A].insn_code = CODE_FOR_$(smul$a3_highpart$)",
"smul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(mul$a$b3$)$N",
"umul_widen_optab->handlers[$B].insn_code = CODE_FOR_$(umul$a$b3$)$N",
"sdiv_optab->handlers[$A].insn_code = CODE_FOR_$(div$a3$)",
- "sdivv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(div$V$I$a3$)",
+ "sdivv_optab->handlers[$A].insn_code = CODE_FOR_$(div$V$I$a3$)",
"udiv_optab->handlers[$A].insn_code = CODE_FOR_$(udiv$I$a3$)",
"sdivmod_optab->handlers[$A].insn_code = CODE_FOR_$(divmod$a4$)",
"udivmod_optab->handlers[$A].insn_code = CODE_FOR_$(udivmod$a4$)",
@@ -103,26 +106,40 @@ static const char * const optabs[] =
"smax_optab->handlers[$A].insn_code = CODE_FOR_$(max$F$a3$)",
"umin_optab->handlers[$A].insn_code = CODE_FOR_$(umin$I$a3$)",
"umax_optab->handlers[$A].insn_code = CODE_FOR_$(umax$I$a3$)",
+ "pow_optab->handlers[$A].insn_code = CODE_FOR_$(pow$a3$)",
+ "atan2_optab->handlers[$A].insn_code = CODE_FOR_$(atan2$a3$)",
"neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$P$a2$)",
- "negv_optab->handlers[(int) $A].insn_code =\n\
- neg_optab->handlers[(int) $A].insn_code = CODE_FOR_$(neg$F$a2$)",
- "negv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(negv$I$a2$)",
+ "negv_optab->handlers[$A].insn_code =\n\
+ neg_optab->handlers[$A].insn_code = CODE_FOR_$(neg$F$a2$)",
+ "negv_optab->handlers[$A].insn_code = CODE_FOR_$(negv$I$a2$)",
"abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$P$a2$)",
- "absv_optab->handlers[(int) $A].insn_code =\n\
- abs_optab->handlers[(int) $A].insn_code = CODE_FOR_$(abs$F$a2$)",
- "absv_optab->handlers[(int) $A].insn_code = CODE_FOR_$(absv$I$a2$)",
+ "absv_optab->handlers[$A].insn_code =\n\
+ abs_optab->handlers[$A].insn_code = CODE_FOR_$(abs$F$a2$)",
+ "absv_optab->handlers[$A].insn_code = CODE_FOR_$(absv$I$a2$)",
"sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)",
+ "floor_optab->handlers[$A].insn_code = CODE_FOR_$(floor$a2$)",
+ "ceil_optab->handlers[$A].insn_code = CODE_FOR_$(ceil$a2$)",
+ "round_optab->handlers[$A].insn_code = CODE_FOR_$(round$a2$)",
+ "trunc_optab->handlers[$A].insn_code = CODE_FOR_$(trunc$a2$)",
+ "nearbyint_optab->handlers[$A].insn_code = CODE_FOR_$(nearbyint$a2$)",
"sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
"cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
"exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
"log_optab->handlers[$A].insn_code = CODE_FOR_$(log$a2$)",
+ "tan_optab->handlers[$A].insn_code = CODE_FOR_$(tan$a2$)",
+ "atan_optab->handlers[$A].insn_code = CODE_FOR_$(atan$a2$)",
"strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
"one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)",
"ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)",
+ "clz_optab->handlers[$A].insn_code = CODE_FOR_$(clz$a2$)",
+ "ctz_optab->handlers[$A].insn_code = CODE_FOR_$(ctz$a2$)",
+ "popcount_optab->handlers[$A].insn_code = CODE_FOR_$(popcount$a2$)",
+ "parity_optab->handlers[$A].insn_code = CODE_FOR_$(parity$a2$)",
"mov_optab->handlers[$A].insn_code = CODE_FOR_$(mov$a$)",
"movstrict_optab->handlers[$A].insn_code = CODE_FOR_$(movstrict$a$)",
"cmp_optab->handlers[$A].insn_code = CODE_FOR_$(cmp$a$)",
"tst_optab->handlers[$A].insn_code = CODE_FOR_$(tst$a$)",
+ "addcc_optab->handlers[$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$)",
@@ -133,13 +150,17 @@ static const char * const optabs[] =
"reload_in_optab[$A] = CODE_FOR_$(reload_in$a$)",
"reload_out_optab[$A] = CODE_FOR_$(reload_out$a$)",
"movstr_optab[$A] = CODE_FOR_$(movstr$a$)",
- "clrstr_optab[$A] = CODE_FOR_$(clrstr$a$)" };
+ "clrstr_optab[$A] = CODE_FOR_$(clrstr$a$)",
+ "cmpstr_optab[$A] = CODE_FOR_$(cmpstr$a$)",
+ "cmpmem_optab[$A] = CODE_FOR_$(cmpmem$a$)",
+ "vec_set_optab->handlers[$A].insn_code = CODE_FOR_$(vec_set$a$)",
+ "vec_extract_optab->handlers[$A].insn_code = CODE_FOR_$(vec_extract$a$)",
+ "vec_init_optab->handlers[$A].insn_code = CODE_FOR_$(vec_init$a$)" };
-static void gen_insn PARAMS ((rtx));
+static void gen_insn (rtx);
static void
-gen_insn (insn)
- rtx insn;
+gen_insn (rtx insn)
{
const char *name = XSTR (insn, 0);
int m1 = 0, m2 = 0, op = 0;
@@ -212,9 +233,9 @@ gen_insn (insn)
case 'b':
/* This loop will stop at the first prefix match, so
look through the modes in reverse order, in case
- EXTRA_CC_MODES was used and CC is a prefix of the
+ there are extra CC modes and CC is a prefix of the
CC modes (as it should be). */
- for (i = ((int) MAX_MACHINE_MODE) - 1; i >= 0; i--)
+ for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
{
for (p = GET_MODE_NAME(i), q = np; *p; p++, q++)
if (TOLOWER (*p) != *q)
@@ -288,16 +309,15 @@ gen_insn (insn)
putchar (TOLOWER (*np));
break;
case 'A':
- printf ("(int) %smode", GET_MODE_NAME(m1));
+ printf ("%smode", GET_MODE_NAME(m1));
break;
case 'B':
- printf ("(int) %smode", GET_MODE_NAME(m2));
+ printf ("%smode", GET_MODE_NAME(m2));
break;
case 'c':
printf ("%s", GET_RTX_NAME(op));
break;
case 'C':
- printf ("(int) ");
for (np = GET_RTX_NAME(op); *np; np++)
putchar (TOUPPER (*np));
break;
@@ -307,12 +327,10 @@ gen_insn (insn)
printf (";\n");
}
-extern int main PARAMS ((int, char **));
+extern int main (int, char **);
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
rtx desc;
@@ -329,6 +347,8 @@ from the machine description file `md'. */\n\n");
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
+ printf ("#include \"coretypes.h\"\n");
+ printf ("#include \"tm.h\"\n");
printf ("#include \"rtl.h\"\n");
printf ("#include \"flags.h\"\n");
printf ("#include \"insn-config.h\"\n");
@@ -337,7 +357,12 @@ from the machine description file `md'. */\n\n");
printf ("#include \"optabs.h\"\n");
printf ("#include \"reload.h\"\n\n");
- printf ("void\ninit_all_optabs ()\n{\n");
+ printf ("void\ninit_all_optabs (void)\n{\n");
+
+ puts ("\
+#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
+ int i, j;\n\
+#endif\n");
/* Read the machine description. */
@@ -353,7 +378,17 @@ from the machine description file `md'. */\n\n");
gen_insn (desc);
}
- printf ("}\n");
+ puts ("\
+\n\
+#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC\n\
+ /* This flag says the same insns that convert to a signed fixnum\n\
+ also convert validly to an unsigned one. */\n\
+ for (i = 0; i < NUM_MACHINE_MODES; i++)\n\
+ for (j = 0; j < NUM_MACHINE_MODES; j++)\n\
+ ufixtrunc_optab->handlers[i][j].insn_code\n\
+ = sfixtrunc_optab->handlers[i][j].insn_code;\n\
+#endif\n\
+}");
fflush (stdout);
return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
@@ -361,8 +396,7 @@ from the machine description file `md'. */\n\n");
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
const char *
-get_insn_name (code)
- int code ATTRIBUTE_UNUSED;
+get_insn_name (int code ATTRIBUTE_UNUSED)
{
return NULL;
}
diff --git a/contrib/gcc/genoutput.c b/contrib/gcc/genoutput.c
index 80b73fcb9156..9e27b276d0cc 100644
--- a/contrib/gcc/genoutput.c
+++ b/contrib/gcc/genoutput.c
@@ -1,6 +1,6 @@
/* Generate code from to output assembler insns as recognized from rtl.
- Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000
- Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002,
+ 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -85,8 +85,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
insn_data[24].template to be "clrd %0", and
insn_data[24].n_operands to be 1. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "gensupport.h"
@@ -97,8 +99,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define MAX_MAX_OPERANDS 40
-static int n_occurrences PARAMS ((int, const char *));
-static const char *strip_whitespace PARAMS ((const char *));
+static int n_occurrences (int, const char *);
+static const char *strip_whitespace (const char *);
/* insns in the machine description are assigned sequential code numbers
that are used by insn-recog.c (produced by genrecog) to communicate
@@ -171,26 +173,26 @@ struct data
static struct data *idata, **idata_end = &idata;
-static void output_prologue PARAMS ((void));
-static void output_predicate_decls PARAMS ((void));
-static void output_operand_data PARAMS ((void));
-static void output_insn_data PARAMS ((void));
-static void output_get_insn_name PARAMS ((void));
-static void scan_operands PARAMS ((struct data *, rtx, int, int));
-static int compare_operands PARAMS ((struct operand_data *,
- struct operand_data *));
-static void place_operands PARAMS ((struct data *));
-static void process_template PARAMS ((struct data *, const char *));
-static void validate_insn_alternatives PARAMS ((struct data *));
-static void validate_insn_operands PARAMS ((struct data *));
-static void gen_insn PARAMS ((rtx, int));
-static void gen_peephole PARAMS ((rtx, int));
-static void gen_expand PARAMS ((rtx, int));
-static void gen_split PARAMS ((rtx, int));
+static void output_prologue (void);
+static void output_operand_data (void);
+static void output_insn_data (void);
+static void output_get_insn_name (void);
+static void scan_operands (struct data *, rtx, int, int);
+static int compare_operands (struct operand_data *,
+ struct operand_data *);
+static void place_operands (struct data *);
+static void process_template (struct data *, const char *);
+static void validate_insn_alternatives (struct data *);
+static void validate_insn_operands (struct data *);
+static void gen_insn (rtx, int);
+static void gen_peephole (rtx, int);
+static void gen_expand (rtx, int);
+static void gen_split (rtx, int);
+static void check_constraint_len (void);
+static int constraint_len (const char *, int);
const char *
-get_insn_name (index)
- int index;
+get_insn_name (int index)
{
static char buf[100];
@@ -212,13 +214,15 @@ get_insn_name (index)
}
static void
-output_prologue ()
+output_prologue (void)
{
printf ("/* Generated automatically by the program `genoutput'\n\
from the machine description file `md'. */\n\n");
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
+ printf ("#include \"coretypes.h\"\n");
+ printf ("#include \"tm.h\"\n");
printf ("#include \"flags.h\"\n");
printf ("#include \"ggc.h\"\n");
printf ("#include \"rtl.h\"\n");
@@ -235,49 +239,11 @@ output_prologue ()
printf ("#include \"recog.h\"\n\n");
printf ("#include \"toplev.h\"\n");
printf ("#include \"output.h\"\n");
-}
-
-
-/* We need to define all predicates used. Keep a list of those we
- have defined so far. There normally aren't very many predicates
- used, so a linked list should be fast enough. */
-struct predicate { const char *name; struct predicate *next; };
-
-static void
-output_predicate_decls ()
-{
- struct predicate *predicates = 0;
- struct operand_data *d;
- struct predicate *p, *next;
-
- for (d = odata; d; d = d->next)
- if (d->predicate && d->predicate[0])
- {
- for (p = predicates; p; p = p->next)
- if (strcmp (p->name, d->predicate) == 0)
- break;
-
- if (p == 0)
- {
- printf ("extern int %s PARAMS ((rtx, enum machine_mode));\n",
- d->predicate);
- p = (struct predicate *) xmalloc (sizeof (struct predicate));
- p->name = d->predicate;
- p->next = predicates;
- predicates = p;
- }
- }
-
- printf ("\n\n");
- for (p = predicates; p; p = next)
- {
- next = p->next;
- free (p);
- }
+ printf ("#include \"target.h\"\n");
}
static void
-output_operand_data ()
+output_operand_data (void)
{
struct operand_data *d;
@@ -304,7 +270,7 @@ output_operand_data ()
}
static void
-output_insn_data ()
+output_insn_data (void)
{
struct data *d;
int name_offset = 0;
@@ -320,6 +286,7 @@ output_insn_data ()
break;
}
+ printf ("#if GCC_VERSION >= 2007\n__extension__\n#endif\n");
printf ("\nconst struct insn_data insn_data[] = \n{\n");
for (d = idata; d; d = d->next)
@@ -356,13 +323,22 @@ output_insn_data ()
switch (d->output_format)
{
case INSN_OUTPUT_FORMAT_NONE:
- printf (" 0,\n");
+ printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
+ printf (" { 0 },\n");
+ printf ("#else\n");
+ printf (" { 0, 0, 0 },\n");
+ printf ("#endif\n");
break;
case INSN_OUTPUT_FORMAT_SINGLE:
{
const char *p = d->template;
char prev = 0;
-
+
+ printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
+ printf (" { .single =\n");
+ printf ("#else\n");
+ printf (" {\n");
+ printf ("#endif\n");
printf (" \"");
while (*p)
{
@@ -379,11 +355,26 @@ output_insn_data ()
++p;
}
printf ("\",\n");
+ printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
+ printf (" },\n");
+ printf ("#else\n");
+ printf (" 0, 0 },\n");
+ printf ("#endif\n");
}
break;
case INSN_OUTPUT_FORMAT_MULTI:
+ printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
+ printf (" { .multi = output_%d },\n", d->code_number);
+ printf ("#else\n");
+ printf (" { 0, output_%d, 0 },\n", d->code_number);
+ printf ("#endif\n");
+ break;
case INSN_OUTPUT_FORMAT_FUNCTION:
- printf (" (const PTR) output_%d,\n", d->code_number);
+ printf ("#if HAVE_DESIGNATED_INITIALIZERS\n");
+ printf (" { .function = output_%d },\n", d->code_number);
+ printf ("#else\n");
+ printf (" { 0, 0, output_%d },\n", d->code_number);
+ printf ("#endif\n");
break;
default:
abort ();
@@ -406,13 +397,15 @@ output_insn_data ()
}
static void
-output_get_insn_name ()
+output_get_insn_name (void)
{
printf ("const char *\n");
- printf ("get_insn_name (code)\n");
- printf (" int code;\n");
+ printf ("get_insn_name (int code)\n");
printf ("{\n");
- printf (" return insn_data[code].name;\n");
+ printf (" if (code == NOOP_MOVE_INSN_CODE)\n");
+ printf (" return \"NOOP_MOVE\";\n");
+ printf (" else\n");
+ printf (" return insn_data[code].name;\n");
printf ("}\n");
}
@@ -428,11 +421,8 @@ static int max_opno;
static int num_dups;
static void
-scan_operands (d, part, this_address_p, this_strict_low)
- struct data *d;
- rtx part;
- int this_address_p;
- int this_strict_low;
+scan_operands (struct data *d, rtx part, int this_address_p,
+ int this_strict_low)
{
int i, j;
const char *format_ptr;
@@ -544,7 +534,7 @@ scan_operands (d, part, this_address_p, this_strict_low)
case STRICT_LOW_PART:
scan_operands (d, XEXP (part, 0), 0, 1);
return;
-
+
default:
break;
}
@@ -569,8 +559,7 @@ scan_operands (d, part, this_address_p, this_strict_low)
/* Compare two operands for content equality. */
static int
-compare_operands (d0, d1)
- struct operand_data *d0, *d1;
+compare_operands (struct operand_data *d0, struct operand_data *d1)
{
const char *p0, *p1;
@@ -608,8 +597,7 @@ compare_operands (d0, d1)
find a subsequence that is the same, or allocate a new one at the end. */
static void
-place_operands (d)
- struct data *d;
+place_operands (struct data *d)
{
struct operand_data *od, *od2;
int i;
@@ -663,9 +651,7 @@ place_operands (d)
templates, or C code to generate the assembler code template. */
static void
-process_template (d, template)
- struct data *d;
- const char *template;
+process_template (struct data *d, const char *template)
{
const char *cp;
int i;
@@ -676,12 +662,9 @@ process_template (d, template)
d->template = 0;
d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
- printf ("\nstatic const char *output_%d PARAMS ((rtx *, rtx));\n",
- d->code_number);
puts ("\nstatic const char *");
- printf ("output_%d (operands, insn)\n", d->code_number);
- puts (" rtx *operands ATTRIBUTE_UNUSED;");
- puts (" rtx insn ATTRIBUTE_UNUSED;");
+ printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)\n",
+ d->code_number);
puts ("{");
puts (template + 1);
@@ -734,8 +717,7 @@ process_template (d, template)
/* Check insn D for consistency in number of constraint alternatives. */
static void
-validate_insn_alternatives (d)
- struct data *d;
+validate_insn_alternatives (struct data *d)
{
int n = 0, start;
@@ -744,7 +726,51 @@ validate_insn_alternatives (d)
for (start = 0; start < d->n_operands; start++)
if (d->operand[start].n_alternatives > 0)
{
- if (n == 0)
+ int len, i;
+ const char *p;
+ char c;
+ int which_alternative = 0;
+ int alternative_count_unsure = 0;
+
+ for (p = d->operand[start].constraint; (c = *p); p += len)
+ {
+ len = CONSTRAINT_LEN (c, p);
+
+ if (len < 1 || (len > 1 && strchr (",#*+=&%!0123456789", c)))
+ {
+ message_with_line (d->lineno,
+ "invalid length %d for char '%c' in alternative %d of operand %d",
+ len, c, which_alternative, start);
+ len = 1;
+ have_error = 1;
+ }
+
+ if (c == ',')
+ {
+ which_alternative++;
+ continue;
+ }
+
+ for (i = 1; i < len; i++)
+ if (p[i] == '\0')
+ {
+ message_with_line (d->lineno,
+ "NUL in alternative %d of operand %d",
+ which_alternative, start);
+ alternative_count_unsure = 1;
+ break;
+ }
+ else if (strchr (",#*", p[i]))
+ {
+ message_with_line (d->lineno,
+ "'%c' in alternative %d of operand %d",
+ p[i], which_alternative, start);
+ alternative_count_unsure = 1;
+ }
+ }
+ if (alternative_count_unsure)
+ have_error = 1;
+ else if (n == 0)
n = d->operand[start].n_alternatives;
else if (n != d->operand[start].n_alternatives)
{
@@ -762,8 +788,7 @@ validate_insn_alternatives (d)
/* Verify that there are no gaps in operand numbers for INSNs. */
static void
-validate_insn_operands (d)
- struct data *d;
+validate_insn_operands (struct data *d)
{
int i;
@@ -780,11 +805,9 @@ validate_insn_operands (d)
a hairy output action, output a function for now. */
static void
-gen_insn (insn, lineno)
- rtx insn;
- int lineno;
+gen_insn (rtx insn, int lineno)
{
- struct data *d = (struct data *) xmalloc (sizeof (struct data));
+ struct data *d = xmalloc (sizeof (struct data));
int i;
d->code_number = next_code_number;
@@ -811,6 +834,7 @@ gen_insn (insn, lineno)
d->n_operands = max_opno + 1;
d->n_dups = num_dups;
+ check_constraint_len ();
validate_insn_operands (d);
validate_insn_alternatives (d);
place_operands (d);
@@ -822,11 +846,9 @@ gen_insn (insn, lineno)
If the insn has a hairy output action, output it now. */
static void
-gen_peephole (peep, lineno)
- rtx peep;
- int lineno;
+gen_peephole (rtx peep, int lineno)
{
- struct data *d = (struct data *) xmalloc (sizeof (struct data));
+ struct data *d = xmalloc (sizeof (struct data));
int i;
d->code_number = next_code_number;
@@ -862,11 +884,9 @@ gen_peephole (peep, lineno)
only for the purposes of `insn_gen_function'. */
static void
-gen_expand (insn, lineno)
- rtx insn;
- int lineno;
+gen_expand (rtx insn, int lineno)
{
- struct data *d = (struct data *) xmalloc (sizeof (struct data));
+ struct data *d = xmalloc (sizeof (struct data));
int i;
d->code_number = next_code_number;
@@ -907,11 +927,9 @@ gen_expand (insn, lineno)
only for reasons of consistency and to simplify genrecog. */
static void
-gen_split (split, lineno)
- rtx split;
- int lineno;
+gen_split (rtx split, int lineno)
{
- struct data *d = (struct data *) xmalloc (sizeof (struct data));
+ struct data *d = xmalloc (sizeof (struct data));
int i;
d->code_number = next_code_number;
@@ -944,12 +962,10 @@ gen_split (split, lineno)
place_operands (d);
}
-extern int main PARAMS ((int, char **));
+extern int main (int, char **);
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
rtx desc;
@@ -982,13 +998,12 @@ main (argc, argv)
if (GET_CODE (desc) == DEFINE_EXPAND)
gen_expand (desc, line_no);
if (GET_CODE (desc) == DEFINE_SPLIT
- || GET_CODE (desc) == DEFINE_PEEPHOLE2)
+ || GET_CODE (desc) == DEFINE_PEEPHOLE2)
gen_split (desc, line_no);
next_index_number++;
}
printf("\n\n");
- output_predicate_decls ();
output_operand_data ();
output_insn_data ();
output_get_insn_name ();
@@ -1002,9 +1017,7 @@ main (argc, argv)
-1 if S is the null string. */
static int
-n_occurrences (c, s)
- int c;
- const char *s;
+n_occurrences (int c, const char *s)
{
int n = 0;
@@ -1021,8 +1034,7 @@ n_occurrences (c, s)
Return a new string. */
static const char *
-strip_whitespace (s)
- const char *s;
+strip_whitespace (const char *s)
{
char *p, *q;
char ch;
@@ -1038,3 +1050,39 @@ strip_whitespace (s)
*p = '\0';
return q;
}
+
+/* Verify that DEFAULT_CONSTRAINT_LEN is used properly and not
+ tampered with. This isn't bullet-proof, but it should catch
+ most genuine mistakes. */
+static void
+check_constraint_len (void)
+{
+ const char *p;
+ int d;
+
+ for (p = ",#*+=&%!1234567890"; *p; p++)
+ for (d = -9; d < 9; d++)
+ if (constraint_len (p, d) != d)
+ abort ();
+}
+
+static int
+constraint_len (const char *p, int genoutput_default_constraint_len)
+{
+ /* Check that we still match defaults.h . First we do a generation-time
+ check that fails if the value is not the expected one... */
+ if (DEFAULT_CONSTRAINT_LEN (*p, p) != 1)
+ abort ();
+ /* And now a compile-time check that should give a diagnostic if the
+ definition doesn't exactly match. */
+#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
+ /* Now re-define DEFAULT_CONSTRAINT_LEN so that we can verify it is
+ being used. */
+#undef DEFAULT_CONSTRAINT_LEN
+#define DEFAULT_CONSTRAINT_LEN(C,STR) \
+ ((C) != *p || STR != p ? -1 : genoutput_default_constraint_len)
+ return CONSTRAINT_LEN (*p, p);
+ /* And set it back. */
+#undef DEFAULT_CONSTRAINT_LEN
+#define DEFAULT_CONSTRAINT_LEN(C,STR) 1
+}
diff --git a/contrib/gcc/genpeep.c b/contrib/gcc/genpeep.c
index 036f68812d17..4c6e64b79abd 100644
--- a/contrib/gcc/genpeep.c
+++ b/contrib/gcc/genpeep.c
@@ -1,6 +1,6 @@
/* Generate code from machine description to perform peephole optimizations.
Copyright (C) 1987, 1989, 1992, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,8 +20,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "gensupport.h"
@@ -51,14 +53,13 @@ static int n_operands;
static int insn_code_number = 0;
-static void gen_peephole PARAMS ((rtx));
-static void match_rtx PARAMS ((rtx, struct link *, int));
-static void print_path PARAMS ((struct link *));
-static void print_code PARAMS ((RTX_CODE));
+static void gen_peephole (rtx);
+static void match_rtx (rtx, struct link *, int);
+static void print_path (struct link *);
+static void print_code (RTX_CODE);
static void
-gen_peephole (peep)
- rtx peep;
+gen_peephole (rtx peep)
{
int ninsns = XVECLEN (peep, 0);
int i;
@@ -66,9 +67,6 @@ gen_peephole (peep)
n_operands = 0;
printf (" insn = ins1;\n");
-#if 0
- printf (" want_jump = 0;\n");
-#endif
for (i = 0; i < ninsns; i++)
{
@@ -84,14 +82,9 @@ gen_peephole (peep)
printf (" if (GET_CODE (insn) == CODE_LABEL\n\
|| GET_CODE (insn) == BARRIER)\n goto L%d;\n",
- insn_code_number);
+ insn_code_number);
}
-#if 0
- printf (" if (GET_CODE (insn) == JUMP_INSN)\n");
- printf (" want_jump = JUMP_LABEL (insn);\n");
-#endif
-
printf (" pat = PATTERN (insn);\n");
/* Walk the insn's pattern, remembering at all times the path
@@ -115,15 +108,6 @@ gen_peephole (peep)
printf (" PATTERN (ins1) = gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (%d, operands));\n", n_operands);
-#if 0
- printf (" if (want_jump && GET_CODE (ins1) != JUMP_INSN)\n");
- printf (" {\n");
- printf (" rtx insn2 = emit_jump_insn_before (PATTERN (ins1), ins1);\n");
- printf (" delete_related_insns (ins1);\n");
- printf (" ins1 = ins2;\n");
- printf (" }\n");
-#endif
-
/* Record this define_peephole's insn code in the insn,
as if it had been recognized to match this. */
printf (" INSN_CODE (ins1) = %d;\n",
@@ -141,10 +125,7 @@ gen_peephole (peep)
}
static void
-match_rtx (x, path, fail_label)
- rtx x;
- struct link *path;
- int fail_label;
+match_rtx (rtx x, struct link *path, int fail_label)
{
RTX_CODE code;
int i;
@@ -254,7 +235,7 @@ match_rtx (x, path, fail_label)
case ADDRESS:
match_rtx (XEXP (x, 0), path, fail_label);
return;
-
+
default:
break;
}
@@ -341,8 +322,7 @@ match_rtx (x, path, fail_label)
evaluate to the rtx at that point. */
static void
-print_path (path)
- struct link *path;
+print_path (struct link *path)
{
if (path == 0)
printf ("pat");
@@ -361,20 +341,17 @@ print_path (path)
}
static void
-print_code (code)
- RTX_CODE code;
+print_code (RTX_CODE code)
{
const char *p1;
for (p1 = GET_RTX_NAME (code); *p1; p1++)
putchar (TOUPPER(*p1));
}
-extern int main PARAMS ((int, char **));
+extern int main (int, char **);
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
rtx desc;
@@ -393,6 +370,8 @@ from the machine description file `md'. */\n\n");
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
+ printf ("#include \"coretypes.h\"\n");
+ printf ("#include \"tm.h\"\n");
printf ("#include \"insn-config.h\"\n");
printf ("#include \"rtl.h\"\n");
printf ("#include \"tm_p.h\"\n");
@@ -407,7 +386,7 @@ from the machine description file `md'. */\n\n");
printf ("extern rtx peep_operand[];\n\n");
printf ("#define operands peep_operand\n\n");
- printf ("rtx\npeephole (ins1)\n rtx ins1;\n{\n");
+ printf ("rtx\npeephole (rtx ins1)\n{\n");
printf (" rtx insn ATTRIBUTE_UNUSED, x ATTRIBUTE_UNUSED, pat ATTRIBUTE_UNUSED;\n\n");
/* Early out: no peepholes for insns followed by barriers. */
@@ -453,8 +432,7 @@ from the machine description file `md'. */\n\n");
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
const char *
-get_insn_name (code)
- int code ATTRIBUTE_UNUSED;
+get_insn_name (int code ATTRIBUTE_UNUSED)
{
return NULL;
}
diff --git a/contrib/gcc/genpreds.c b/contrib/gcc/genpreds.c
index cf8c0bd46ba5..e52e424dd3c0 100644
--- a/contrib/gcc/genpreds.c
+++ b/contrib/gcc/genpreds.c
@@ -2,7 +2,7 @@
- some macros CODE_FOR_... giving the insn_code_number value
for each of the defined standard insn names.
Copyright (C) 1987, 1991, 1995, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,17 +21,17 @@ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#define NO_GENRTL_H
#include "rtl.h"
-static void output_predicate_decls PARAMS ((void));
-extern int main PARAMS ((void));
static void
-output_predicate_decls ()
+output_predicate_decls (void)
{
#ifdef PREDICATE_CODES
static const struct {
@@ -44,14 +44,14 @@ output_predicate_decls ()
puts ("#ifdef RTX_CODE\n");
for (i = 0; i < ARRAY_SIZE (predicate); i++)
- printf ("extern int %s PARAMS ((rtx, enum machine_mode));\n",
+ printf ("extern int %s (rtx, enum machine_mode);\n",
predicate[i].name);
puts ("\n#endif /* RTX_CODE */\n");
#endif
}
int
-main ()
+main (void)
{
puts ("/* Generated automatically by the program `genpreds'. */\n");
puts ("#ifndef GCC_TM_PREDS_H");
diff --git a/contrib/gcc/genrecog.c b/contrib/gcc/genrecog.c
index 56b2680eb1fc..be7505b31ae9 100644
--- a/contrib/gcc/genrecog.c
+++ b/contrib/gcc/genrecog.c
@@ -1,6 +1,6 @@
/* Generate code from machine description to recognize rtl as insns.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -50,8 +50,10 @@
the new rtl is returned in an INSN list, and LAST_INSN will point
to the last recognized insn in the old sequence. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "errors.h"
#include "gensupport.h"
@@ -65,7 +67,7 @@ static char **insn_name_ptr = 0;
static int insn_name_ptr_size = 0;
/* A listhead of decision trees. The alternatives to a node are kept
- in a doublely-linked list so we can easily add nodes to the proper
+ in a doubly-linked list so we can easily add nodes to the proper
place when merging. */
struct decision_head
@@ -210,9 +212,7 @@ static const struct pred_table
{"indirect_operand", {SUBREG, MEM}},
{"comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU,
UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE,
- UNLT, LTGT}},
- {"mode_independent_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF,
- LABEL_REF, SUBREG, REG, MEM, ADDRESSOF}}
+ UNLT, LTGT}}
};
#define NUM_KNOWN_PREDS ARRAY_SIZE (preds)
@@ -227,101 +227,97 @@ static const char *const special_mode_pred_table[] = {
#define NUM_SPECIAL_MODE_PREDS ARRAY_SIZE (special_mode_pred_table)
static struct decision *new_decision
- PARAMS ((const char *, struct decision_head *));
+ (const char *, struct decision_head *);
static struct decision_test *new_decision_test
- PARAMS ((enum decision_type, struct decision_test ***));
+ (enum decision_type, struct decision_test ***);
static rtx find_operand
- PARAMS ((rtx, int));
+ (rtx, int, rtx);
static rtx find_matching_operand
- PARAMS ((rtx, int));
+ (rtx, int);
static void validate_pattern
- PARAMS ((rtx, rtx, rtx, int));
+ (rtx, rtx, rtx, int);
static struct decision *add_to_sequence
- PARAMS ((rtx, struct decision_head *, const char *, enum routine_type, int));
+ (rtx, struct decision_head *, const char *, enum routine_type, int);
static int maybe_both_true_2
- PARAMS ((struct decision_test *, struct decision_test *));
+ (struct decision_test *, struct decision_test *);
static int maybe_both_true_1
- PARAMS ((struct decision_test *, struct decision_test *));
+ (struct decision_test *, struct decision_test *);
static int maybe_both_true
- PARAMS ((struct decision *, struct decision *, int));
+ (struct decision *, struct decision *, int);
static int nodes_identical_1
- PARAMS ((struct decision_test *, struct decision_test *));
+ (struct decision_test *, struct decision_test *);
static int nodes_identical
- PARAMS ((struct decision *, struct decision *));
+ (struct decision *, struct decision *);
static void merge_accept_insn
- PARAMS ((struct decision *, struct decision *));
+ (struct decision *, struct decision *);
static void merge_trees
- PARAMS ((struct decision_head *, struct decision_head *));
+ (struct decision_head *, struct decision_head *);
static void factor_tests
- PARAMS ((struct decision_head *));
+ (struct decision_head *);
static void simplify_tests
- PARAMS ((struct decision_head *));
+ (struct decision_head *);
static int break_out_subroutines
- PARAMS ((struct decision_head *, int));
+ (struct decision_head *, int);
static void find_afterward
- PARAMS ((struct decision_head *, struct decision *));
+ (struct decision_head *, struct decision *);
static void change_state
- PARAMS ((const char *, const char *, struct decision *, const char *));
+ (const char *, const char *, struct decision *, const char *);
static void print_code
- PARAMS ((enum rtx_code));
+ (enum rtx_code);
static void write_afterward
- PARAMS ((struct decision *, struct decision *, const char *));
+ (struct decision *, struct decision *, const char *);
static struct decision *write_switch
- PARAMS ((struct decision *, int));
+ (struct decision *, int);
static void write_cond
- PARAMS ((struct decision_test *, int, enum routine_type));
+ (struct decision_test *, int, enum routine_type);
static void write_action
- PARAMS ((struct decision *, struct decision_test *, int, int,
- struct decision *, enum routine_type));
+ (struct decision *, struct decision_test *, int, int,
+ struct decision *, enum routine_type);
static int is_unconditional
- PARAMS ((struct decision_test *, enum routine_type));
+ (struct decision_test *, enum routine_type);
static int write_node
- PARAMS ((struct decision *, int, enum routine_type));
+ (struct decision *, int, enum routine_type);
static void write_tree_1
- PARAMS ((struct decision_head *, int, enum routine_type));
+ (struct decision_head *, int, enum routine_type);
static void write_tree
- PARAMS ((struct decision_head *, const char *, enum routine_type, int));
+ (struct decision_head *, const char *, enum routine_type, int);
static void write_subroutine
- PARAMS ((struct decision_head *, enum routine_type));
+ (struct decision_head *, enum routine_type);
static void write_subroutines
- PARAMS ((struct decision_head *, enum routine_type));
+ (struct decision_head *, enum routine_type);
static void write_header
- PARAMS ((void));
+ (void);
static struct decision_head make_insn_sequence
- PARAMS ((rtx, enum routine_type));
+ (rtx, enum routine_type);
static void process_tree
- PARAMS ((struct decision_head *, enum routine_type));
+ (struct decision_head *, enum routine_type);
static void record_insn_name
- PARAMS ((int, const char *));
+ (int, const char *);
static void debug_decision_0
- PARAMS ((struct decision *, int, int));
+ (struct decision *, int, int);
static void debug_decision_1
- PARAMS ((struct decision *, int));
+ (struct decision *, int);
static void debug_decision_2
- PARAMS ((struct decision_test *));
+ (struct decision_test *);
extern void debug_decision
- PARAMS ((struct decision *));
+ (struct decision *);
extern void debug_decision_list
- PARAMS ((struct decision *));
+ (struct decision *);
/* Create a new node in sequence after LAST. */
static struct decision *
-new_decision (position, last)
- const char *position;
- struct decision_head *last;
+new_decision (const char *position, struct decision_head *last)
{
- struct decision *new
- = (struct decision *) xmalloc (sizeof (struct decision));
+ struct decision *new = xcalloc (1, sizeof (struct decision));
- memset (new, 0, sizeof (*new));
new->success = *last;
new->position = xstrdup (position);
new->number = next_number++;
@@ -333,14 +329,12 @@ new_decision (position, last)
/* Create a new test and link it in at PLACE. */
static struct decision_test *
-new_decision_test (type, pplace)
- enum decision_type type;
- struct decision_test ***pplace;
+new_decision_test (enum decision_type type, struct decision_test ***pplace)
{
struct decision_test **place = *pplace;
struct decision_test *test;
- test = (struct decision_test *) xmalloc (sizeof (*test));
+ test = xmalloc (sizeof (*test));
test->next = *place;
test->type = type;
*place = test;
@@ -351,18 +345,19 @@ new_decision_test (type, pplace)
return test;
}
-/* Search for and return operand N. */
+/* Search for and return operand N, stop when reaching node STOP. */
static rtx
-find_operand (pattern, n)
- rtx pattern;
- int n;
+find_operand (rtx pattern, int n, rtx stop)
{
const char *fmt;
RTX_CODE code;
int i, j, len;
rtx r;
+ if (pattern == stop)
+ return stop;
+
code = GET_CODE (pattern);
if ((code == MATCH_SCRATCH
|| code == MATCH_INSN
@@ -379,18 +374,19 @@ find_operand (pattern, n)
switch (fmt[i])
{
case 'e': case 'u':
- if ((r = find_operand (XEXP (pattern, i), n)) != NULL_RTX)
+ if ((r = find_operand (XEXP (pattern, i), n, stop)) != NULL_RTX)
return r;
break;
case 'V':
if (! XVEC (pattern, i))
break;
- /* FALLTHRU */
+ /* Fall through. */
case 'E':
for (j = 0; j < XVECLEN (pattern, i); j++)
- if ((r = find_operand (XVECEXP (pattern, i, j), n)) != NULL_RTX)
+ if ((r = find_operand (XVECEXP (pattern, i, j), n, stop))
+ != NULL_RTX)
return r;
break;
@@ -409,9 +405,7 @@ find_operand (pattern, n)
constraint for operand N. */
static rtx
-find_matching_operand (pattern, n)
- rtx pattern;
- int n;
+find_matching_operand (rtx pattern, int n)
{
const char *fmt;
RTX_CODE code;
@@ -439,7 +433,7 @@ find_matching_operand (pattern, n)
case 'V':
if (! XVEC (pattern, i))
break;
- /* FALLTHRU */
+ /* Fall through. */
case 'E':
for (j = 0; j < XVECLEN (pattern, i); j++)
@@ -464,11 +458,7 @@ find_matching_operand (pattern, n)
'+' within a context that requires in-out constraints. */
static void
-validate_pattern (pattern, insn, set, set_code)
- rtx pattern;
- rtx insn;
- rtx set;
- int set_code;
+validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
{
const char *fmt;
RTX_CODE code;
@@ -480,7 +470,17 @@ validate_pattern (pattern, insn, set, set_code)
{
case MATCH_SCRATCH:
return;
-
+ case MATCH_DUP:
+ case MATCH_OP_DUP:
+ case MATCH_PAR_DUP:
+ if (find_operand (insn, XINT (pattern, 0), pattern) == pattern)
+ {
+ message_with_line (pattern_lineno,
+ "operand %i duplicated before defined",
+ XINT (pattern, 0));
+ error_count++;
+ }
+ break;
case MATCH_INSN:
case MATCH_OPERAND:
case MATCH_OPERATOR:
@@ -551,7 +551,7 @@ validate_pattern (pattern, insn, set, set_code)
{
const char constraints0 = XSTR (pattern, 2)[0];
- /* In DEFINE_EXPAND, DEFINE_SPLIT, and DEFINE_PEEPHOLE2, we
+ /* In DEFINE_EXPAND, DEFINE_SPLIT, and DEFINE_PEEPHOLE2, we
don't use the MATCH_OPERAND constraint, only the predicate.
This is confusing to folks doing new ports, so help them
not make the mistake. */
@@ -564,7 +564,7 @@ validate_pattern (pattern, insn, set, set_code)
"warning: constraints not supported in %s",
rtx_name[GET_CODE (insn)]);
}
-
+
/* A MATCH_OPERAND that is a SET should have an output reload. */
else if (set && constraints0)
{
@@ -588,7 +588,7 @@ validate_pattern (pattern, insn, set, set_code)
else if (constraints0 != '=' && constraints0 != '+')
{
message_with_line (pattern_lineno,
- "operand %d missing output reload",
+ "operand %d missing output reload",
XINT (pattern, 0));
error_count++;
}
@@ -647,17 +647,17 @@ validate_pattern (pattern, insn, set, set_code)
if (GET_CODE (dest) == STRICT_LOW_PART)
dest = XEXP (dest, 0);
- /* Find the referant for a DUP. */
+ /* Find the referent for a DUP. */
if (GET_CODE (dest) == MATCH_DUP
|| GET_CODE (dest) == MATCH_OP_DUP
|| GET_CODE (dest) == MATCH_PAR_DUP)
- dest = find_operand (insn, XINT (dest, 0));
+ dest = find_operand (insn, XINT (dest, 0), NULL);
if (GET_CODE (src) == MATCH_DUP
|| GET_CODE (src) == MATCH_OP_DUP
|| GET_CODE (src) == MATCH_PAR_DUP)
- src = find_operand (insn, XINT (src, 0));
+ src = find_operand (insn, XINT (src, 0), NULL);
dmode = GET_MODE (dest);
smode = GET_MODE (src);
@@ -765,12 +765,8 @@ validate_pattern (pattern, insn, set, set_code)
A pointer to the final node in the chain is returned. */
static struct decision *
-add_to_sequence (pattern, last, position, insn_type, top)
- rtx pattern;
- struct decision_head *last;
- const char *position;
- enum routine_type insn_type;
- int top;
+add_to_sequence (rtx pattern, struct decision_head *last, const char *position,
+ enum routine_type insn_type, int top)
{
RTX_CODE code;
struct decision *this, *sub;
@@ -786,7 +782,7 @@ add_to_sequence (pattern, last, position, insn_type, top)
if (depth > max_depth)
max_depth = depth;
- subpos = (char *) xmalloc (depth + 2);
+ subpos = xmalloc (depth + 2);
strcpy (subpos, position);
subpos[depth + 1] = 0;
@@ -830,7 +826,7 @@ add_to_sequence (pattern, last, position, insn_type, top)
beyond the end of the vector. */
test = new_decision_test (DT_veclen_ge, &place);
test->u.veclen = XVECLEN (pattern, 2);
- /* FALLTHRU */
+ /* Fall through. */
case MATCH_OPERAND:
case MATCH_SCRATCH:
@@ -1060,8 +1056,7 @@ add_to_sequence (pattern, last, position, insn_type, top)
Returns > 0 for "definitely both true" and < 0 for "maybe both true". */
static int
-maybe_both_true_2 (d1, d2)
- struct decision_test *d1, *d2;
+maybe_both_true_2 (struct decision_test *d1, struct decision_test *d2)
{
if (d1->type == d2->type)
{
@@ -1171,8 +1166,7 @@ maybe_both_true_2 (d1, d2)
Returns > 0 for "definitely both true" and < 0 for "maybe both true". */
static int
-maybe_both_true_1 (d1, d2)
- struct decision_test *d1, *d2;
+maybe_both_true_1 (struct decision_test *d1, struct decision_test *d2)
{
struct decision_test *t1, *t2;
@@ -1206,9 +1200,8 @@ maybe_both_true_1 (d1, d2)
recursively descend. */
static int
-maybe_both_true (d1, d2, toplevel)
- struct decision *d1, *d2;
- int toplevel;
+maybe_both_true (struct decision *d1, struct decision *d2,
+ int toplevel)
{
struct decision *p1, *p2;
int cmp;
@@ -1275,8 +1268,7 @@ maybe_both_true (d1, d2, toplevel)
/* A subroutine of nodes_identical. Examine two tests for equivalence. */
static int
-nodes_identical_1 (d1, d2)
- struct decision_test *d1, *d2;
+nodes_identical_1 (struct decision_test *d1, struct decision_test *d2)
{
switch (d1->type)
{
@@ -1323,8 +1315,7 @@ nodes_identical_1 (d1, d2)
consider different orderings on the tests. */
static int
-nodes_identical (d1, d2)
- struct decision *d1, *d2;
+nodes_identical (struct decision *d1, struct decision *d2)
{
struct decision_test *t1, *t2;
@@ -1360,8 +1351,7 @@ nodes_identical (d1, d2)
source machine description. */
static void
-merge_accept_insn (oldd, addd)
- struct decision *oldd, *addd;
+merge_accept_insn (struct decision *oldd, struct decision *addd)
{
struct decision_test *old, *add;
@@ -1405,8 +1395,7 @@ merge_accept_insn (oldd, addd)
/* Merge two decision trees OLDH and ADDH, modifying OLDH destructively. */
static void
-merge_trees (oldh, addh)
- struct decision_head *oldh, *addh;
+merge_trees (struct decision_head *oldh, struct decision_head *addh)
{
struct decision *next, *add;
@@ -1490,8 +1479,7 @@ merge_trees (oldh, addh)
(depending on the test type) to emit switch statements later. */
static void
-factor_tests (head)
- struct decision_head *head;
+factor_tests (struct decision_head *head)
{
struct decision *first, *next;
@@ -1576,8 +1564,7 @@ factor_tests (head)
predicates, remove them. */
static void
-simplify_tests (head)
- struct decision_head *head;
+simplify_tests (struct decision_head *head)
{
struct decision *tree;
@@ -1614,9 +1601,7 @@ simplify_tests (head)
that is generated. */
static int
-break_out_subroutines (head, initial)
- struct decision_head *head;
- int initial;
+break_out_subroutines (struct decision_head *head, int initial)
{
int size = 0;
struct decision *sub;
@@ -1636,9 +1621,7 @@ break_out_subroutines (head, initial)
when p is true. */
static void
-find_afterward (head, real_afterward)
- struct decision_head *head;
- struct decision *real_afterward;
+find_afterward (struct decision_head *head, struct decision *real_afterward)
{
struct decision *p, *q, *afterward;
@@ -1685,11 +1668,8 @@ find_afterward (head, real_afterward)
match multiple insns and we try to step past the end of the stream. */
static void
-change_state (oldpos, newpos, afterward, indent)
- const char *oldpos;
- const char *newpos;
- struct decision *afterward;
- const char *indent;
+change_state (const char *oldpos, const char *newpos,
+ struct decision *afterward, const char *indent)
{
int odepth = strlen (oldpos);
int ndepth = strlen (newpos);
@@ -1746,8 +1726,7 @@ change_state (oldpos, newpos, afterward, indent)
the name. */
static void
-print_code (code)
- enum rtx_code code;
+print_code (enum rtx_code code)
{
const char *p;
for (p = GET_RTX_NAME (code); *p; p++)
@@ -1757,10 +1736,8 @@ print_code (code)
/* Emit code to cross an afterward link -- change state and branch. */
static void
-write_afterward (start, afterward, indent)
- struct decision *start;
- struct decision *afterward;
- const char *indent;
+write_afterward (struct decision *start, struct decision *afterward,
+ const char *indent)
{
if (!afterward || start->subroutine_number > 0)
printf("%sgoto ret0;\n", indent);
@@ -1771,13 +1748,25 @@ write_afterward (start, afterward, indent)
}
}
+/* Emit a HOST_WIDE_INT as an integer constant expression. We need to take
+ special care to avoid "decimal constant is so large that it is unsigned"
+ warnings in the resulting code. */
+
+static void
+print_host_wide_int (HOST_WIDE_INT val)
+{
+ HOST_WIDE_INT min = (unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT-1);
+ if (val == min)
+ printf ("(" HOST_WIDE_INT_PRINT_DEC_C "-1)", val + 1);
+ else
+ printf (HOST_WIDE_INT_PRINT_DEC_C, val);
+}
+
/* Emit a switch statement, if possible, for an initial sequence of
nodes at START. Return the first node yet untested. */
static struct decision *
-write_switch (start, depth)
- struct decision *start;
- int depth;
+write_switch (struct decision *start, int depth)
{
struct decision *p = start;
enum decision_type type = p->tests->type;
@@ -1946,7 +1935,7 @@ write_switch (start, depth)
case DT_elt_one_int:
case DT_elt_zero_wide:
case DT_elt_zero_wide_safe:
- printf (HOST_WIDE_INT_PRINT_DEC_C, p->tests->u.intval);
+ print_host_wide_int (p->tests->u.intval);
break;
default:
abort ();
@@ -1966,7 +1955,7 @@ write_switch (start, depth)
}
else
{
- /* None of the other tests are ameanable. */
+ /* None of the other tests are amenable. */
return p;
}
}
@@ -1974,10 +1963,8 @@ write_switch (start, depth)
/* Emit code for one test. */
static void
-write_cond (p, depth, subroutine_type)
- struct decision_test *p;
- int depth;
- enum routine_type subroutine_type;
+write_cond (struct decision_test *p, int depth,
+ enum routine_type subroutine_type)
{
switch (p->type)
{
@@ -2005,7 +1992,7 @@ write_cond (p, depth, subroutine_type)
case DT_elt_zero_wide:
case DT_elt_zero_wide_safe:
printf ("XWINT (x%d, 0) == ", depth);
- printf (HOST_WIDE_INT_PRINT_DEC_C, p->u.intval);
+ print_host_wide_int (p->u.intval);
break;
case DT_veclen_ge:
@@ -2049,12 +2036,9 @@ write_cond (p, depth, subroutine_type)
perform a state change. For the `accept' tests we must do more work. */
static void
-write_action (p, test, depth, uncond, success, subroutine_type)
- struct decision *p;
- struct decision_test *test;
- int depth, uncond;
- struct decision *success;
- enum routine_type subroutine_type;
+write_action (struct decision *p, struct decision_test *test,
+ int depth, int uncond, struct decision *success,
+ enum routine_type subroutine_type)
{
const char *indent;
int want_close = 0;
@@ -2140,9 +2124,7 @@ write_action (p, test, depth, uncond, success, subroutine_type)
/* ??? is_unconditional is a stupid name for a tri-state function. */
static int
-is_unconditional (t, subroutine_type)
- struct decision_test *t;
- enum routine_type subroutine_type;
+is_unconditional (struct decision_test *t, enum routine_type subroutine_type)
{
if (t->type == DT_accept_op)
return 1;
@@ -2169,10 +2151,8 @@ is_unconditional (t, subroutine_type)
Return true if there is no fallthru path. */
static int
-write_node (p, depth, subroutine_type)
- struct decision *p;
- int depth;
- enum routine_type subroutine_type;
+write_node (struct decision *p, int depth,
+ enum routine_type subroutine_type)
{
struct decision_test *test, *last_test;
int uncond;
@@ -2208,10 +2188,8 @@ write_node (p, depth, subroutine_type)
/* Emit code for all of the sibling nodes of HEAD. */
static void
-write_tree_1 (head, depth, subroutine_type)
- struct decision_head *head;
- int depth;
- enum routine_type subroutine_type;
+write_tree_1 (struct decision_head *head, int depth,
+ enum routine_type subroutine_type)
{
struct decision *p, *next;
int uncond = 0;
@@ -2244,11 +2222,8 @@ write_tree_1 (head, depth, subroutine_type)
position at the node that branched to this node. */
static void
-write_tree (head, prevpos, type, initial)
- struct decision_head *head;
- const char *prevpos;
- enum routine_type type;
- int initial;
+write_tree (struct decision_head *head, const char *prevpos,
+ enum routine_type type, int initial)
{
struct decision *p = head->first;
@@ -2304,9 +2279,7 @@ write_tree (head, prevpos, type, initial)
node TREE. */
static void
-write_subroutine (head, type)
- struct decision_head *head;
- enum routine_type type;
+write_subroutine (struct decision_head *head, enum routine_type type)
{
int subfunction = head->first ? head->first->subroutine_number : 0;
const char *s_or_e;
@@ -2325,28 +2298,18 @@ write_subroutine (head, type)
switch (type)
{
case RECOG:
- printf ("%sint recog%s PARAMS ((rtx, rtx, int *));\n", s_or_e, extension);
printf ("%sint\n\
-recog%s (x0, insn, pnum_clobbers)\n\
- rtx x0 ATTRIBUTE_UNUSED;\n\
- rtx insn ATTRIBUTE_UNUSED;\n\
- int *pnum_clobbers ATTRIBUTE_UNUSED;\n", s_or_e, extension);
+recog%s (rtx x0 ATTRIBUTE_UNUSED,\n\trtx insn ATTRIBUTE_UNUSED,\n\tint *pnum_clobbers ATTRIBUTE_UNUSED)\n", s_or_e, extension);
break;
case SPLIT:
- printf ("%srtx split%s PARAMS ((rtx, rtx));\n", s_or_e, extension);
printf ("%srtx\n\
-split%s (x0, insn)\n\
- rtx x0 ATTRIBUTE_UNUSED;\n\
- rtx insn ATTRIBUTE_UNUSED;\n", s_or_e, extension);
+split%s (rtx x0 ATTRIBUTE_UNUSED, rtx insn ATTRIBUTE_UNUSED)\n",
+ s_or_e, extension);
break;
case PEEPHOLE2:
- printf ("%srtx peephole2%s PARAMS ((rtx, rtx, int *));\n",
- s_or_e, extension);
printf ("%srtx\n\
-peephole2%s (x0, insn, _pmatch_len)\n\
- rtx x0 ATTRIBUTE_UNUSED;\n\
- rtx insn ATTRIBUTE_UNUSED;\n\
- int *_pmatch_len ATTRIBUTE_UNUSED;\n", s_or_e, extension);
+peephole2%s (rtx x0 ATTRIBUTE_UNUSED,\n\trtx insn ATTRIBUTE_UNUSED,\n\tint *_pmatch_len ATTRIBUTE_UNUSED)\n",
+ s_or_e, extension);
break;
}
@@ -2371,9 +2334,7 @@ peephole2%s (x0, insn, _pmatch_len)\n\
subroutines, but did not write them out. Do so now. */
static void
-write_subroutines (head, type)
- struct decision_head *head;
- enum routine_type type;
+write_subroutines (struct decision_head *head, enum routine_type type)
{
struct decision *p;
@@ -2388,7 +2349,7 @@ write_subroutines (head, type)
/* Begin the output file. */
static void
-write_header ()
+write_header (void)
{
puts ("\
/* Generated automatically by the program `genrecog' from the target\n\
@@ -2396,6 +2357,8 @@ write_header ()
\n\
#include \"config.h\"\n\
#include \"system.h\"\n\
+#include \"coretypes.h\"\n\
+#include \"tm.h\"\n\
#include \"rtl.h\"\n\
#include \"tm_p.h\"\n\
#include \"function.h\"\n\
@@ -2448,9 +2411,7 @@ write_header ()
TYPE says what type of routine we are recognizing (RECOG or SPLIT). */
static struct decision_head
-make_insn_sequence (insn, type)
- rtx insn;
- enum routine_type type;
+make_insn_sequence (rtx insn, enum routine_type type)
{
rtx x;
const char *c_test = XSTR (insn, type == RECOG ? 2 : 1);
@@ -2532,7 +2493,7 @@ make_insn_sequence (insn, type)
switch (type)
{
case RECOG:
- /* If this is an DEFINE_INSN and X is a PARALLEL, see if it ends
+ /* If this is a DEFINE_INSN and X is a PARALLEL, see if it ends
with a group of CLOBBERs of (hard) registers or MATCH_SCRATCHes.
If so, set up to recognize the pattern without these CLOBBERs. */
@@ -2605,12 +2566,12 @@ make_insn_sequence (insn, type)
case SPLIT:
/* Define the subroutine we will call below and emit in genemit. */
- printf ("extern rtx gen_split_%d PARAMS ((rtx *));\n", next_insn_code);
+ printf ("extern rtx gen_split_%d (rtx *);\n", next_insn_code);
break;
case PEEPHOLE2:
/* Define the subroutine we will call below and emit in genemit. */
- printf ("extern rtx gen_peephole2_%d PARAMS ((rtx, rtx *));\n",
+ printf ("extern rtx gen_peephole2_%d (rtx, rtx *);\n",
next_insn_code);
break;
}
@@ -2619,9 +2580,7 @@ make_insn_sequence (insn, type)
}
static void
-process_tree (head, subroutine_type)
- struct decision_head *head;
- enum routine_type subroutine_type;
+process_tree (struct decision_head *head, enum routine_type subroutine_type)
{
if (head->first == NULL)
{
@@ -2648,12 +2607,10 @@ process_tree (head, subroutine_type)
write_subroutine (head, subroutine_type);
}
-extern int main PARAMS ((int, char **));
+extern int main (int, char **);
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
rtx desc;
struct decision_head recog_tree, split_tree, peephole2_tree, h;
@@ -2717,8 +2674,7 @@ main (argc, argv)
/* Define this so we can link with print-rtl.o to get debug_rtx function. */
const char *
-get_insn_name (code)
- int code;
+get_insn_name (int code)
{
if (code < insn_name_ptr_size)
return insn_name_ptr[code];
@@ -2727,9 +2683,7 @@ get_insn_name (code)
}
static void
-record_insn_name (code, name)
- int code;
- const char *name;
+record_insn_name (int code, const char *name)
{
static const char *last_real_name = "insn";
static int last_real_code = 0;
@@ -2739,8 +2693,7 @@ record_insn_name (code, name)
{
int new_size;
new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
- insn_name_ptr =
- (char **) xrealloc (insn_name_ptr, sizeof(char *) * new_size);
+ insn_name_ptr = xrealloc (insn_name_ptr, sizeof(char *) * new_size);
memset (insn_name_ptr + insn_name_ptr_size, 0,
sizeof(char *) * (new_size - insn_name_ptr_size));
insn_name_ptr_size = new_size;
@@ -2761,8 +2714,7 @@ record_insn_name (code, name)
}
static void
-debug_decision_2 (test)
- struct decision_test *test;
+debug_decision_2 (struct decision_test *test)
{
switch (test->type)
{
@@ -2782,12 +2734,10 @@ debug_decision_2 (test)
fprintf (stderr, "elt1_i=%d", (int) test->u.intval);
break;
case DT_elt_zero_wide:
- fprintf (stderr, "elt0_w=");
- fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, test->u.intval);
+ fprintf (stderr, "elt0_w=" HOST_WIDE_INT_PRINT_DEC, test->u.intval);
break;
case DT_elt_zero_wide_safe:
- fprintf (stderr, "elt0_ws=");
- fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, test->u.intval);
+ fprintf (stderr, "elt0_ws=" HOST_WIDE_INT_PRINT_DEC, test->u.intval);
break;
case DT_veclen_ge:
fprintf (stderr, "veclen>=%d", test->u.veclen);
@@ -2821,9 +2771,7 @@ debug_decision_2 (test)
}
static void
-debug_decision_1 (d, indent)
- struct decision *d;
- int indent;
+debug_decision_1 (struct decision *d, int indent)
{
int i;
struct decision_test *test;
@@ -2856,9 +2804,7 @@ debug_decision_1 (d, indent)
}
static void
-debug_decision_0 (d, indent, maxdepth)
- struct decision *d;
- int indent, maxdepth;
+debug_decision_0 (struct decision *d, int indent, int maxdepth)
{
struct decision *n;
int i;
@@ -2879,15 +2825,13 @@ debug_decision_0 (d, indent, maxdepth)
}
void
-debug_decision (d)
- struct decision *d;
+debug_decision (struct decision *d)
{
debug_decision_0 (d, 0, 1000000);
}
void
-debug_decision_list (d)
- struct decision *d;
+debug_decision_list (struct decision *d)
{
while (d)
{
diff --git a/contrib/gcc/gensupport.c b/contrib/gcc/gensupport.c
index 53172dd55b46..44e07eb06d52 100644
--- a/contrib/gcc/gensupport.c
+++ b/contrib/gcc/gensupport.c
@@ -1,5 +1,6 @@
/* Support routines for the various generation passes.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -18,8 +19,10 @@
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "obstack.h"
#include "errors.h"
@@ -66,8 +69,8 @@ static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
static struct queue_elem *other_queue;
static struct queue_elem **other_tail = &other_queue;
-static void queue_pattern PARAMS ((rtx, struct queue_elem ***,
- const char *, int));
+static void queue_pattern (rtx, struct queue_elem ***,
+ const char *, int);
/* Current maximum length of directory names in the search path
for include files. (Altered as we get more of them.) */
@@ -85,46 +88,45 @@ struct file_name_list *first_dir_md_include = 0; /* First dir to search */
struct file_name_list *first_bracket_include = 0;
struct file_name_list *last_dir_md_include = 0; /* Last in chain */
-static void remove_constraints PARAMS ((rtx));
-static void process_rtx PARAMS ((rtx, int));
-
-static int is_predicable PARAMS ((struct queue_elem *));
-static void identify_predicable_attribute PARAMS ((void));
-static int n_alternatives PARAMS ((const char *));
-static void collect_insn_data PARAMS ((rtx, int *, int *));
-static rtx alter_predicate_for_insn PARAMS ((rtx, int, int, int));
-static const char *alter_test_for_insn PARAMS ((struct queue_elem *,
- struct queue_elem *));
-static char *shift_output_template PARAMS ((char *, const char *, int));
-static const char *alter_output_for_insn PARAMS ((struct queue_elem *,
- struct queue_elem *,
- int, int));
-static void process_one_cond_exec PARAMS ((struct queue_elem *));
-static void process_define_cond_exec PARAMS ((void));
-static void process_include PARAMS ((rtx, int));
-static char *save_string PARAMS ((const char *, int));
+static void remove_constraints (rtx);
+static void process_rtx (rtx, int);
+
+static int is_predicable (struct queue_elem *);
+static void identify_predicable_attribute (void);
+static int n_alternatives (const char *);
+static void collect_insn_data (rtx, int *, int *);
+static rtx alter_predicate_for_insn (rtx, int, int, int);
+static const char *alter_test_for_insn (struct queue_elem *,
+ struct queue_elem *);
+static char *shift_output_template (char *, const char *, int);
+static const char *alter_output_for_insn (struct queue_elem *,
+ struct queue_elem *,
+ int, int);
+static void process_one_cond_exec (struct queue_elem *);
+static void process_define_cond_exec (void);
+static void process_include (rtx, int);
+static char *save_string (const char *, int);
void
-message_with_line VPARAMS ((int lineno, const char *msg, ...))
+message_with_line (int lineno, const char *msg, ...)
{
- VA_OPEN (ap, msg);
- VA_FIXEDARG (ap, int, lineno);
- VA_FIXEDARG (ap, const char *, msg);
+ va_list ap;
+
+ va_start (ap, msg);
fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
vfprintf (stderr, msg, ap);
fputc ('\n', stderr);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
the gensupport programs. */
rtx
-gen_rtx_CONST_INT (mode, arg)
- enum machine_mode mode ATTRIBUTE_UNUSED;
- HOST_WIDE_INT arg;
+gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT arg)
{
rtx rt = rtx_alloc (CONST_INT);
@@ -135,13 +137,10 @@ gen_rtx_CONST_INT (mode, arg)
/* Queue PATTERN on LIST_TAIL. */
static void
-queue_pattern (pattern, list_tail, filename, lineno)
- rtx pattern;
- struct queue_elem ***list_tail;
- const char *filename;
- int lineno;
+queue_pattern (rtx pattern, struct queue_elem ***list_tail,
+ const char *filename, int lineno)
{
- struct queue_elem *e = (struct queue_elem *) xmalloc (sizeof (*e));
+ struct queue_elem *e = xmalloc (sizeof (*e));
e->data = pattern;
e->filename = filename;
e->lineno = lineno;
@@ -153,8 +152,7 @@ queue_pattern (pattern, list_tail, filename, lineno)
/* Recursively remove constraints from an rtx. */
static void
-remove_constraints (part)
- rtx part;
+remove_constraints (rtx part)
{
int i, j;
const char *format_ptr;
@@ -184,13 +182,11 @@ remove_constraints (part)
}
}
-/* Process an include file assuming that it lives in gcc/config/{target}/
+/* Process an include file assuming that it lives in gcc/config/{target}/
if the include looks like (include "file"). */
static void
-process_include (desc, lineno)
- rtx desc;
- int lineno;
+process_include (rtx desc, int lineno)
{
const char *filename = XSTR (desc, 0);
const char *old_filename;
@@ -199,7 +195,7 @@ process_include (desc, lineno)
FILE *input_file;
/* If specified file name is absolute, skip the include stack. */
- if (! IS_ABSOLUTE_PATHNAME (filename))
+ if (! IS_ABSOLUTE_PATH (filename))
{
struct file_name_list *stackp;
@@ -210,7 +206,7 @@ process_include (desc, lineno)
pathname = concat (stackp->fname, sep, filename, NULL);
input_file = fopen (pathname, "r");
- if (input_file != NULL)
+ if (input_file != NULL)
goto success;
free (pathname);
}
@@ -263,12 +259,10 @@ process_include (desc, lineno)
fclose (input_file);
}
-/* Process a top level rtx in some way, queueing as appropriate. */
+/* Process a top level rtx in some way, queuing as appropriate. */
static void
-process_rtx (desc, lineno)
- rtx desc;
- int lineno;
+process_rtx (rtx desc, int lineno)
{
switch (GET_CODE (desc))
{
@@ -336,8 +330,7 @@ process_rtx (desc, lineno)
a DEFINE_INSN. */
static int
-is_predicable (elem)
- struct queue_elem *elem;
+is_predicable (struct queue_elem *elem)
{
rtvec vec = XVEC (elem->data, 4);
const char *value;
@@ -425,7 +418,7 @@ is_predicable (elem)
and its default. */
static void
-identify_predicable_attribute ()
+identify_predicable_attribute (void)
{
struct queue_elem *elem;
char *p_true, *p_false;
@@ -492,8 +485,7 @@ identify_predicable_attribute ()
/* Return the number of alternatives in constraint S. */
static int
-n_alternatives (s)
- const char *s;
+n_alternatives (const char *s)
{
int n = 1;
@@ -508,9 +500,7 @@ n_alternatives (s)
operands. */
static void
-collect_insn_data (pattern, palt, pmax)
- rtx pattern;
- int *palt, *pmax;
+collect_insn_data (rtx pattern, int *palt, int *pmax)
{
const char *fmt;
enum rtx_code code;
@@ -522,7 +512,7 @@ collect_insn_data (pattern, palt, pmax)
case MATCH_OPERAND:
i = n_alternatives (XSTR (pattern, 2));
*palt = (i > *palt ? i : *palt);
- /* FALLTHRU */
+ /* Fall through. */
case MATCH_OPERATOR:
case MATCH_SCRATCH:
@@ -550,7 +540,7 @@ collect_insn_data (pattern, palt, pmax)
case 'V':
if (XVEC (pattern, i) == NULL)
break;
- /* FALLTHRU */
+ /* Fall through. */
case 'E':
for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
@@ -566,9 +556,7 @@ collect_insn_data (pattern, palt, pmax)
}
static rtx
-alter_predicate_for_insn (pattern, alt, max_op, lineno)
- rtx pattern;
- int alt, max_op, lineno;
+alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno)
{
const char *fmt;
enum rtx_code code;
@@ -595,7 +583,7 @@ alter_predicate_for_insn (pattern, alt, max_op, lineno)
{
size_t c_len = strlen (c);
size_t len = alt * (c_len + 1);
- char *new_c = (char *) xmalloc (len);
+ char *new_c = xmalloc (len);
memcpy (new_c, c, c_len);
for (i = 1; i < alt; ++i)
@@ -607,7 +595,7 @@ alter_predicate_for_insn (pattern, alt, max_op, lineno)
XSTR (pattern, 2) = new_c;
}
}
- /* FALLTHRU */
+ /* Fall through. */
case MATCH_OPERATOR:
case MATCH_SCRATCH:
@@ -657,8 +645,8 @@ alter_predicate_for_insn (pattern, alt, max_op, lineno)
}
static const char *
-alter_test_for_insn (ce_elem, insn_elem)
- struct queue_elem *ce_elem, *insn_elem;
+alter_test_for_insn (struct queue_elem *ce_elem,
+ struct queue_elem *insn_elem)
{
const char *ce_test, *insn_test;
@@ -677,10 +665,7 @@ alter_test_for_insn (ce_elem, insn_elem)
adjusted string. */
static char *
-shift_output_template (new, old, disp)
- char *new;
- const char *old;
- int disp;
+shift_output_template (char *new, const char *old, int disp)
{
while (*old)
{
@@ -704,9 +689,9 @@ shift_output_template (new, old, disp)
}
static const char *
-alter_output_for_insn (ce_elem, insn_elem, alt, max_op)
- struct queue_elem *ce_elem, *insn_elem;
- int alt, max_op;
+alter_output_for_insn (struct queue_elem *ce_elem,
+ struct queue_elem *insn_elem,
+ int alt, int max_op)
{
const char *ce_out, *insn_out;
char *new, *p;
@@ -766,8 +751,7 @@ alter_output_for_insn (ce_elem, insn_elem, alt, max_op)
/* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
static void
-process_one_cond_exec (ce_elem)
- struct queue_elem *ce_elem;
+process_one_cond_exec (struct queue_elem *ce_elem)
{
struct queue_elem *insn_elem;
for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
@@ -843,7 +827,7 @@ process_one_cond_exec (ce_elem)
patterns appropriately. */
static void
-process_define_cond_exec ()
+process_define_cond_exec (void)
{
struct queue_elem *elem;
@@ -856,11 +840,9 @@ process_define_cond_exec ()
}
static char *
-save_string (s, len)
- const char *s;
- int len;
+save_string (const char *s, int len)
{
- register char *result = xmalloc (len + 1);
+ char *result = xmalloc (len + 1);
memcpy (result, s, len);
result[len] = 0;
@@ -871,9 +853,7 @@ save_string (s, len)
/* The entry point for initializing the reader. */
int
-init_md_reader_args (argc, argv)
- int argc;
- char **argv;
+init_md_reader_args (int argc, char **argv)
{
int i;
const char *in_fname;
@@ -896,8 +876,7 @@ init_md_reader_args (argc, argv)
{
struct file_name_list *dirtmp;
- dirtmp = (struct file_name_list *)
- xmalloc (sizeof (struct file_name_list));
+ dirtmp = xmalloc (sizeof (struct file_name_list));
dirtmp->next = 0; /* New one goes on the end */
if (first_dir_md_include == 0)
first_dir_md_include = dirtmp;
@@ -926,8 +905,7 @@ init_md_reader_args (argc, argv)
/* The entry point for initializing the reader. */
int
-init_md_reader (filename)
- const char *filename;
+init_md_reader (const char *filename)
{
FILE *input_file;
int c;
@@ -935,7 +913,7 @@ init_md_reader (filename)
char *lastsl;
lastsl = strrchr (filename, '/');
- if (lastsl != NULL)
+ if (lastsl != NULL)
base_dir = save_string (filename, lastsl - filename + 1 );
read_rtx_filename = filename;
@@ -951,8 +929,8 @@ init_md_reader (filename)
hash_c_test, cmp_c_test, NULL);
for (i = 0; i < n_insn_conditions; i++)
- *(htab_find_slot (condition_table, (PTR) &insn_conditions[i], INSERT))
- = (PTR) &insn_conditions[i];
+ *(htab_find_slot (condition_table, &insn_conditions[i], INSERT))
+ = (void *) &insn_conditions[i];
obstack_init (rtl_obstack);
errors = 0;
@@ -985,9 +963,7 @@ init_md_reader (filename)
/* The entry point for reading a single rtx from an md file. */
rtx
-read_md_rtx (lineno, seqnr)
- int *lineno;
- int *seqnr;
+read_md_rtx (int *lineno, int *seqnr)
{
struct queue_elem **queue, *elem;
rtx desc;
@@ -1050,8 +1026,7 @@ read_md_rtx (lineno, seqnr)
/* Compute a hash function of a c_test structure, which is keyed
by its ->expr field. */
hashval_t
-hash_c_test (x)
- const PTR x;
+hash_c_test (const void *x)
{
const struct c_test *a = (const struct c_test *) x;
const unsigned char *base, *s = (const unsigned char *) a->expr;
@@ -1077,9 +1052,7 @@ hash_c_test (x)
/* Compare two c_test expression structures. */
int
-cmp_c_test (x, y)
- const PTR x;
- const PTR y;
+cmp_c_test (const void *x, const void *y)
{
const struct c_test *a = (const struct c_test *) x;
const struct c_test *b = (const struct c_test *) y;
@@ -1092,8 +1065,7 @@ cmp_c_test (x, y)
at compile time. Returns a tristate: 1 for known true, 0 for
known false, -1 for unknown. */
int
-maybe_eval_c_test (expr)
- const char *expr;
+maybe_eval_c_test (const char *expr)
{
const struct c_test *test;
struct c_test dummy;
@@ -1105,7 +1077,7 @@ maybe_eval_c_test (expr)
return -1;
dummy.expr = expr;
- test = (const struct c_test *) htab_find (condition_table, &dummy);
+ test = htab_find (condition_table, &dummy);
if (!test)
abort ();
@@ -1115,8 +1087,7 @@ maybe_eval_c_test (expr)
/* Given a string, return the number of comma-separated elements in it.
Return 0 for the null string. */
int
-n_comma_elts (s)
- const char *s;
+n_comma_elts (const char *s)
{
int n;
@@ -1137,8 +1108,7 @@ n_comma_elts (s)
a comma and an element is ignored. */
const char *
-scan_comma_elt (pstr)
- const char **pstr;
+scan_comma_elt (const char **pstr)
{
const char *start;
const char *p = *pstr;
diff --git a/contrib/gcc/gensupport.h b/contrib/gcc/gensupport.h
index 8dbd0b70ea95..7ceccfbaeb11 100644
--- a/contrib/gcc/gensupport.h
+++ b/contrib/gcc/gensupport.h
@@ -1,5 +1,5 @@
/* Declarations for rtx-reader support for gen* routines.
- Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -24,11 +24,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
struct obstack;
extern struct obstack *rtl_obstack;
-extern int init_md_reader_args PARAMS ((int, char **));
-extern int init_md_reader PARAMS ((const char *));
-extern rtx read_md_rtx PARAMS ((int *, int *));
+extern int init_md_reader_args (int, char **);
+extern int init_md_reader (const char *);
+extern rtx read_md_rtx (int *, int *);
-extern void message_with_line PARAMS ((int, const char *, ...))
+extern void message_with_line (int, const char *, ...)
ATTRIBUTE_PRINTF_2;
/* Set this to 0 to disable automatic elision of insn patterns which
@@ -46,7 +46,7 @@ extern const int insn_elision_unavailable;
time, return its truth value; else return -1. The test must have
appeared somewhere in the machine description when genconditions
was run. */
-extern int maybe_eval_c_test PARAMS ((const char *));
+extern int maybe_eval_c_test (const char *);
/* This table should not be accessed directly; use maybe_eval_c_test. */
struct c_test
@@ -59,11 +59,11 @@ extern const struct c_test insn_conditions[];
extern const size_t n_insn_conditions;
#ifdef __HASHTAB_H__
-extern hashval_t hash_c_test PARAMS ((const PTR));
-extern int cmp_c_test PARAMS ((const PTR, const PTR));
+extern hashval_t hash_c_test (const void *);
+extern int cmp_c_test (const void *, const void *);
#endif
-extern int n_comma_elts PARAMS ((const char *));
-extern const char *scan_comma_elt PARAMS ((const char **));
+extern int n_comma_elts (const char *);
+extern const char *scan_comma_elt (const char **);
#endif /* GCC_GENSUPPORT_H */
diff --git a/contrib/gcc/ggc-common.c b/contrib/gcc/ggc-common.c
index 528b3f2260ef..ecd6624487c3 100644
--- a/contrib/gcc/ggc-common.c
+++ b/contrib/gcc/ggc-common.c
@@ -1,5 +1,6 @@
/* Simple garbage collection for the GNU compiler.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -23,19 +24,37 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
-#include "rtl.h"
-#include "tree.h"
-#include "tm_p.h"
+#include "coretypes.h"
#include "hashtab.h"
-#include "varray.h"
#include "ggc.h"
-#include "langhooks.h"
+#include "toplev.h"
#include "params.h"
+#include "hosthooks.h"
+
#ifdef HAVE_SYS_RESOURCE_H
# include <sys/resource.h>
#endif
+
+#ifdef HAVE_MMAP_FILE
+# include <sys/mman.h>
+# ifdef HAVE_MINCORE
+/* This is on Solaris. */
+# include <sys/types.h>
+# endif
+#endif
+
+#ifndef MAP_FAILED
+# define MAP_FAILED ((void *)-1)
+#endif
+
#ifdef ENABLE_VALGRIND_CHECKING
-#include <valgrind.h>
+# ifdef HAVE_VALGRIND_MEMCHECK_H
+# include <valgrind/memcheck.h>
+# elif defined HAVE_MEMCHECK_H
+# include <memcheck.h>
+# else
+# include <valgrind.h>
+# endif
#else
/* Avoid #ifdef:s when we can help it. */
#define VALGRIND_DISCARD(x)
@@ -44,53 +63,25 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Statistics about the allocation. */
static ggc_statistics *ggc_stats;
-static int ggc_htab_delete PARAMS ((void **, void *));
-static double ggc_rlimit_bound PARAMS ((double));
-
-/* Maintain global roots that are preserved during GC. */
-
-/* Global roots that are preserved during calls to gc. */
+struct traversal_state;
-struct ggc_root
-{
- struct ggc_root *next;
- void *base;
- int nelt;
- int size;
- void (*cb) PARAMS ((void *));
-};
-
-static struct ggc_root *roots;
+static int ggc_htab_delete (void **, void *);
+static hashval_t saving_htab_hash (const void *);
+static int saving_htab_eq (const void *, const void *);
+static int call_count (void **, void *);
+static int call_alloc (void **, void *);
+static int compare_ptr_data (const void *, const void *);
+static void relocate_ptrs (void *, void *);
+static void write_pch_globals (const struct ggc_root_tab * const *tab,
+ struct traversal_state *state);
+static double ggc_rlimit_bound (double);
-/* Add BASE as a new garbage collection root. It is an array of
- length NELT with each element SIZE bytes long. CB is a
- function that will be called with a pointer to each element
- of the array; it is the intention that CB call the appropriate
- routine to mark gc-able memory for that element. */
-
-void
-ggc_add_root (base, nelt, size, cb)
- void *base;
- int nelt, size;
- void (*cb) PARAMS ((void *));
-{
- struct ggc_root *x = (struct ggc_root *) xmalloc (sizeof (*x));
-
- x->next = roots;
- x->base = base;
- x->nelt = nelt;
- x->size = size;
- x->cb = cb;
-
- roots = x;
-}
+/* Maintain global roots that are preserved during GC. */
/* Process a slot of an htab by deleting it if it has not been marked. */
static int
-ggc_htab_delete (slot, info)
- void **slot;
- void *info;
+ggc_htab_delete (void **slot, void *info)
{
const struct ggc_cache_tab *r = (const struct ggc_cache_tab *) info;
@@ -105,9 +96,8 @@ ggc_htab_delete (slot, info)
/* Iterate through all registered roots and mark each element. */
void
-ggc_mark_roots ()
+ggc_mark_roots (void)
{
- struct ggc_root *x;
const struct ggc_root_tab *const *rt;
const struct ggc_root_tab *rti;
const struct ggc_cache_tab *const *ct;
@@ -123,29 +113,23 @@ ggc_mark_roots ()
for (i = 0; i < rti->nelt; i++)
(*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
- for (x = roots; x != NULL; x = x->next)
- {
- char *elt = x->base;
- int s = x->size, n = x->nelt;
- void (*cb) PARAMS ((void *)) = x->cb;
- int i;
-
- for (i = 0; i < n; ++i, elt += s)
- (*cb)(elt);
- }
+ ggc_mark_stringpool ();
/* Now scan all hash tables that have objects which are to be deleted if
they are not already marked. */
for (ct = gt_ggc_cache_rtab; *ct; ct++)
for (cti = *ct; cti->base != NULL; cti++)
if (*cti->base)
- htab_traverse (*cti->base, ggc_htab_delete, (PTR) cti);
+ {
+ ggc_set_mark (*cti->base);
+ htab_traverse_noresize (*cti->base, ggc_htab_delete, (void *) cti);
+ ggc_set_mark ((*cti->base)->entries);
+ }
}
/* Allocate a block of memory, then clear it. */
void *
-ggc_alloc_cleared (size)
- size_t size;
+ggc_alloc_cleared (size_t size)
{
void *buf = ggc_alloc (size);
memset (buf, 0, size);
@@ -154,9 +138,7 @@ ggc_alloc_cleared (size)
/* Resize a block of memory, possibly re-allocating it. */
void *
-ggc_realloc (x, size)
- void *x;
- size_t size;
+ggc_realloc (void *x, size_t size)
{
void *r;
size_t old_size;
@@ -174,7 +156,7 @@ ggc_realloc (x, size)
don't know that previously allocated size. Without that
knowledge we have to lose some initialization-tracking for the
old parts of the object. An alternative is to mark the whole
- old_size as reachable, but that would lose tracking of writes
+ old_size as reachable, but that would lose tracking of writes
after the end of the object (by small offsets). Discard the
handle to avoid handle leak. */
VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS ((char *) x + size,
@@ -201,12 +183,27 @@ ggc_realloc (x, size)
/* Like ggc_alloc_cleared, but performs a multiplication. */
void *
-ggc_calloc (s1, s2)
- size_t s1, s2;
+ggc_calloc (size_t s1, size_t s2)
{
return ggc_alloc_cleared (s1 * s2);
}
+/* These are for splay_tree_new_ggc. */
+void *
+ggc_splay_alloc (int sz, void *nl)
+{
+ if (nl != NULL)
+ abort ();
+ return ggc_alloc (sz);
+}
+
+void
+ggc_splay_dont_free (void * x ATTRIBUTE_UNUSED, void *nl)
+{
+ if (nl != NULL)
+ abort ();
+}
+
/* Print statistics that are independent of the collector in use. */
#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
? (x) \
@@ -216,12 +213,9 @@ ggc_calloc (s1, s2)
#define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
void
-ggc_print_common_statistics (stream, stats)
- FILE *stream;
- ggc_statistics *stats;
+ggc_print_common_statistics (FILE *stream ATTRIBUTE_UNUSED,
+ ggc_statistics *stats)
{
- int code;
-
/* Set the pointer so that during collection we will actually gather
the statistics. */
ggc_stats = stats;
@@ -229,66 +223,470 @@ ggc_print_common_statistics (stream, stats)
/* Then do one collection to fill in the statistics. */
ggc_collect ();
- /* Total the statistics. */
- for (code = 0; code < MAX_TREE_CODES; ++code)
+ /* At present, we don't really gather any interesting statistics. */
+
+ /* Don't gather statistics any more. */
+ ggc_stats = NULL;
+}
+
+/* Functions for saving and restoring GCable memory to disk. */
+
+static htab_t saving_htab;
+
+struct ptr_data
+{
+ void *obj;
+ void *note_ptr_cookie;
+ gt_note_pointers note_ptr_fn;
+ gt_handle_reorder reorder_fn;
+ size_t size;
+ void *new_addr;
+};
+
+#define POINTER_HASH(x) (hashval_t)((long)x >> 3)
+
+/* Register an object in the hash table. */
+
+int
+gt_pch_note_object (void *obj, void *note_ptr_cookie,
+ gt_note_pointers note_ptr_fn)
+{
+ struct ptr_data **slot;
+
+ if (obj == NULL || obj == (void *) 1)
+ return 0;
+
+ slot = (struct ptr_data **)
+ htab_find_slot_with_hash (saving_htab, obj, POINTER_HASH (obj),
+ INSERT);
+ if (*slot != NULL)
{
- stats->total_num_trees += stats->num_trees[code];
- stats->total_size_trees += stats->size_trees[code];
+ if ((*slot)->note_ptr_fn != note_ptr_fn
+ || (*slot)->note_ptr_cookie != note_ptr_cookie)
+ abort ();
+ return 0;
}
- for (code = 0; code < NUM_RTX_CODE; ++code)
+
+ *slot = xcalloc (sizeof (struct ptr_data), 1);
+ (*slot)->obj = obj;
+ (*slot)->note_ptr_fn = note_ptr_fn;
+ (*slot)->note_ptr_cookie = note_ptr_cookie;
+ if (note_ptr_fn == gt_pch_p_S)
+ (*slot)->size = strlen (obj) + 1;
+ else
+ (*slot)->size = ggc_get_size (obj);
+ return 1;
+}
+
+/* Register an object in the hash table. */
+
+void
+gt_pch_note_reorder (void *obj, void *note_ptr_cookie,
+ gt_handle_reorder reorder_fn)
+{
+ struct ptr_data *data;
+
+ if (obj == NULL || obj == (void *) 1)
+ return;
+
+ data = htab_find_with_hash (saving_htab, obj, POINTER_HASH (obj));
+ if (data == NULL
+ || data->note_ptr_cookie != note_ptr_cookie)
+ abort ();
+
+ data->reorder_fn = reorder_fn;
+}
+
+/* Hash and equality functions for saving_htab, callbacks for htab_create. */
+
+static hashval_t
+saving_htab_hash (const void *p)
+{
+ return POINTER_HASH (((struct ptr_data *)p)->obj);
+}
+
+static int
+saving_htab_eq (const void *p1, const void *p2)
+{
+ return ((struct ptr_data *)p1)->obj == p2;
+}
+
+/* Handy state for the traversal functions. */
+
+struct traversal_state
+{
+ FILE *f;
+ struct ggc_pch_data *d;
+ size_t count;
+ struct ptr_data **ptrs;
+ size_t ptrs_i;
+};
+
+/* Callbacks for htab_traverse. */
+
+static int
+call_count (void **slot, void *state_p)
+{
+ struct ptr_data *d = (struct ptr_data *)*slot;
+ struct traversal_state *state = (struct traversal_state *)state_p;
+
+ ggc_pch_count_object (state->d, d->obj, d->size, d->note_ptr_fn == gt_pch_p_S);
+ state->count++;
+ return 1;
+}
+
+static int
+call_alloc (void **slot, void *state_p)
+{
+ struct ptr_data *d = (struct ptr_data *)*slot;
+ struct traversal_state *state = (struct traversal_state *)state_p;
+
+ d->new_addr = ggc_pch_alloc_object (state->d, d->obj, d->size, d->note_ptr_fn == gt_pch_p_S);
+ state->ptrs[state->ptrs_i++] = d;
+ return 1;
+}
+
+/* Callback for qsort. */
+
+static int
+compare_ptr_data (const void *p1_p, const void *p2_p)
+{
+ struct ptr_data *p1 = *(struct ptr_data *const *)p1_p;
+ struct ptr_data *p2 = *(struct ptr_data *const *)p2_p;
+ return (((size_t)p1->new_addr > (size_t)p2->new_addr)
+ - ((size_t)p1->new_addr < (size_t)p2->new_addr));
+}
+
+/* Callbacks for note_ptr_fn. */
+
+static void
+relocate_ptrs (void *ptr_p, void *state_p)
+{
+ void **ptr = (void **)ptr_p;
+ struct traversal_state *state ATTRIBUTE_UNUSED
+ = (struct traversal_state *)state_p;
+ struct ptr_data *result;
+
+ if (*ptr == NULL || *ptr == (void *)1)
+ return;
+
+ result = htab_find_with_hash (saving_htab, *ptr, POINTER_HASH (*ptr));
+ if (result == NULL)
+ abort ();
+ *ptr = result->new_addr;
+}
+
+/* Write out, after relocation, the pointers in TAB. */
+static void
+write_pch_globals (const struct ggc_root_tab * const *tab,
+ struct traversal_state *state)
+{
+ const struct ggc_root_tab *const *rt;
+ const struct ggc_root_tab *rti;
+ size_t i;
+
+ for (rt = tab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ for (i = 0; i < rti->nelt; i++)
+ {
+ void *ptr = *(void **)((char *)rti->base + rti->stride * i);
+ struct ptr_data *new_ptr;
+ if (ptr == NULL || ptr == (void *)1)
+ {
+ if (fwrite (&ptr, sizeof (void *), 1, state->f)
+ != 1)
+ fatal_error ("can't write PCH file: %m");
+ }
+ else
+ {
+ new_ptr = htab_find_with_hash (saving_htab, ptr,
+ POINTER_HASH (ptr));
+ if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f)
+ != 1)
+ fatal_error ("can't write PCH file: %m");
+ }
+ }
+}
+
+/* Hold the information we need to mmap the file back in. */
+
+struct mmap_info
+{
+ size_t offset;
+ size_t size;
+ void *preferred_base;
+};
+
+/* Write out the state of the compiler to F. */
+
+void
+gt_pch_save (FILE *f)
+{
+ const struct ggc_root_tab *const *rt;
+ const struct ggc_root_tab *rti;
+ size_t i;
+ struct traversal_state state;
+ char *this_object = NULL;
+ size_t this_object_size = 0;
+ struct mmap_info mmi;
+ size_t page_size = getpagesize();
+
+ gt_pch_save_stringpool ();
+
+ saving_htab = htab_create (50000, saving_htab_hash, saving_htab_eq, free);
+
+ for (rt = gt_ggc_rtab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ for (i = 0; i < rti->nelt; i++)
+ (*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
+
+ for (rt = gt_pch_cache_rtab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ for (i = 0; i < rti->nelt; i++)
+ (*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
+
+ /* Prepare the objects for writing, determine addresses and such. */
+ state.f = f;
+ state.d = init_ggc_pch();
+ state.count = 0;
+ htab_traverse (saving_htab, call_count, &state);
+
+ mmi.size = ggc_pch_total_size (state.d);
+
+ /* Try to arrange things so that no relocation is necessary, but
+ don't try very hard. On most platforms, this will always work,
+ and on the rest it's a lot of work to do better.
+ (The extra work goes in HOST_HOOKS_GT_PCH_GET_ADDRESS and
+ HOST_HOOKS_GT_PCH_USE_ADDRESS.) */
+ mmi.preferred_base = host_hooks.gt_pch_get_address (mmi.size);
+
+#if HAVE_MMAP_FILE
+ if (mmi.preferred_base == NULL)
{
- stats->total_num_rtxs += stats->num_rtxs[code];
- stats->total_size_rtxs += stats->size_rtxs[code];
+ mmi.preferred_base = mmap (NULL, mmi.size,
+ PROT_READ | PROT_WRITE, MAP_PRIVATE,
+ fileno (state.f), 0);
+ if (mmi.preferred_base == (void *) MAP_FAILED)
+ mmi.preferred_base = NULL;
+ else
+ munmap (mmi.preferred_base, mmi.size);
}
+#endif /* HAVE_MMAP_FILE */
- /* Print the statistics for trees. */
- fprintf (stream, "\n%-17s%10s %16s %10s\n", "Tree",
- "Number", "Bytes", "% Total");
- for (code = 0; code < MAX_TREE_CODES; ++code)
- if (ggc_stats->num_trees[code])
- {
- fprintf (stream, "%-17s%10u%16ld%c %10.3f\n",
- tree_code_name[code],
- ggc_stats->num_trees[code],
- SCALE (ggc_stats->size_trees[code]),
- LABEL (ggc_stats->size_trees[code]),
- (100 * ((double) ggc_stats->size_trees[code])
- / ggc_stats->total_size_trees));
- }
- fprintf (stream,
- "%-17s%10u%16ld%c\n", "Total",
- ggc_stats->total_num_trees,
- SCALE (ggc_stats->total_size_trees),
- LABEL (ggc_stats->total_size_trees));
-
- /* Print the statistics for RTL. */
- fprintf (stream, "\n%-17s%10s %16s %10s\n", "RTX",
- "Number", "Bytes", "% Total");
- for (code = 0; code < NUM_RTX_CODE; ++code)
- if (ggc_stats->num_rtxs[code])
- {
- fprintf (stream, "%-17s%10u%16ld%c %10.3f\n",
- rtx_name[code],
- ggc_stats->num_rtxs[code],
- SCALE (ggc_stats->size_rtxs[code]),
- LABEL (ggc_stats->size_rtxs[code]),
- (100 * ((double) ggc_stats->size_rtxs[code])
- / ggc_stats->total_size_rtxs));
- }
- fprintf (stream,
- "%-17s%10u%16ld%c\n", "Total",
- ggc_stats->total_num_rtxs,
- SCALE (ggc_stats->total_size_rtxs),
- LABEL (ggc_stats->total_size_rtxs));
+ ggc_pch_this_base (state.d, mmi.preferred_base);
- /* Don't gather statistics any more. */
- ggc_stats = NULL;
+ state.ptrs = xmalloc (state.count * sizeof (*state.ptrs));
+ state.ptrs_i = 0;
+ htab_traverse (saving_htab, call_alloc, &state);
+ qsort (state.ptrs, state.count, sizeof (*state.ptrs), compare_ptr_data);
+
+ /* Write out all the scalar variables. */
+ for (rt = gt_pch_scalar_rtab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ if (fwrite (rti->base, rti->stride, 1, f) != 1)
+ fatal_error ("can't write PCH file: %m");
+
+ /* Write out all the global pointers, after translation. */
+ write_pch_globals (gt_ggc_rtab, &state);
+ write_pch_globals (gt_pch_cache_rtab, &state);
+
+ ggc_pch_prepare_write (state.d, state.f);
+
+ /* Pad the PCH file so that the mmapped area starts on a page boundary. */
+ {
+ long o;
+ o = ftell (state.f) + sizeof (mmi);
+ if (o == -1)
+ fatal_error ("can't get position in PCH file: %m");
+ mmi.offset = page_size - o % page_size;
+ if (mmi.offset == page_size)
+ mmi.offset = 0;
+ mmi.offset += o;
+ }
+ if (fwrite (&mmi, sizeof (mmi), 1, state.f) != 1)
+ fatal_error ("can't write PCH file: %m");
+ if (mmi.offset != 0
+ && fseek (state.f, mmi.offset, SEEK_SET) != 0)
+ fatal_error ("can't write padding to PCH file: %m");
+
+ /* Actually write out the objects. */
+ for (i = 0; i < state.count; i++)
+ {
+ if (this_object_size < state.ptrs[i]->size)
+ {
+ this_object_size = state.ptrs[i]->size;
+ this_object = xrealloc (this_object, this_object_size);
+ }
+ memcpy (this_object, state.ptrs[i]->obj, state.ptrs[i]->size);
+ if (state.ptrs[i]->reorder_fn != NULL)
+ state.ptrs[i]->reorder_fn (state.ptrs[i]->obj,
+ state.ptrs[i]->note_ptr_cookie,
+ relocate_ptrs, &state);
+ state.ptrs[i]->note_ptr_fn (state.ptrs[i]->obj,
+ state.ptrs[i]->note_ptr_cookie,
+ relocate_ptrs, &state);
+ ggc_pch_write_object (state.d, state.f, state.ptrs[i]->obj,
+ state.ptrs[i]->new_addr, state.ptrs[i]->size, state.ptrs[i]->note_ptr_fn == gt_pch_p_S);
+ if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S)
+ memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size);
+ }
+ ggc_pch_finish (state.d, state.f);
+ gt_pch_fixup_stringpool ();
+
+ free (state.ptrs);
+ htab_delete (saving_htab);
+}
+
+/* Read the state of the compiler back in from F. */
+
+void
+gt_pch_restore (FILE *f)
+{
+ const struct ggc_root_tab *const *rt;
+ const struct ggc_root_tab *rti;
+ size_t i;
+ struct mmap_info mmi;
+ void *addr;
+ bool needs_read;
+
+ /* Delete any deletable objects. This makes ggc_pch_read much
+ faster, as it can be sure that no GCable objects remain other
+ than the ones just read in. */
+ for (rt = gt_ggc_deletable_rtab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ memset (rti->base, 0, rti->stride);
+
+ /* Read in all the scalar variables. */
+ for (rt = gt_pch_scalar_rtab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ if (fread (rti->base, rti->stride, 1, f) != 1)
+ fatal_error ("can't read PCH file: %m");
+
+ /* Read in all the global pointers, in 6 easy loops. */
+ for (rt = gt_ggc_rtab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ for (i = 0; i < rti->nelt; i++)
+ if (fread ((char *)rti->base + rti->stride * i,
+ sizeof (void *), 1, f) != 1)
+ fatal_error ("can't read PCH file: %m");
+
+ for (rt = gt_pch_cache_rtab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ for (i = 0; i < rti->nelt; i++)
+ if (fread ((char *)rti->base + rti->stride * i,
+ sizeof (void *), 1, f) != 1)
+ fatal_error ("can't read PCH file: %m");
+
+ if (fread (&mmi, sizeof (mmi), 1, f) != 1)
+ fatal_error ("can't read PCH file: %m");
+
+ if (host_hooks.gt_pch_use_address (mmi.preferred_base, mmi.size))
+ {
+#if HAVE_MMAP_FILE
+ void *mmap_result;
+
+ mmap_result = mmap (mmi.preferred_base, mmi.size,
+ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
+ fileno (f), mmi.offset);
+
+ /* The file might not be mmap-able. */
+ needs_read = mmap_result == (void *) MAP_FAILED;
+
+ /* Sanity check for broken MAP_FIXED. */
+ if (! needs_read && mmap_result != mmi.preferred_base)
+ abort ();
+#else
+ needs_read = true;
+#endif
+ addr = mmi.preferred_base;
+ }
+ else
+ {
+#if HAVE_MMAP_FILE
+ addr = mmap (mmi.preferred_base, mmi.size,
+ PROT_READ | PROT_WRITE, MAP_PRIVATE,
+ fileno (f), mmi.offset);
+
+#if HAVE_MINCORE
+ if (addr != mmi.preferred_base)
+ {
+ size_t page_size = getpagesize();
+ char one_byte;
+
+ if (addr != (void *) MAP_FAILED)
+ munmap (addr, mmi.size);
+
+ /* We really want to be mapped at mmi.preferred_base
+ so we're going to resort to MAP_FIXED. But before,
+ make sure that we can do so without destroying a
+ previously mapped area, by looping over all pages
+ that would be affected by the fixed mapping. */
+ errno = 0;
+
+ for (i = 0; i < mmi.size; i+= page_size)
+ if (mincore ((char *)mmi.preferred_base + i, page_size,
+ (void *)&one_byte) == -1
+ && errno == ENOMEM)
+ continue; /* The page is not mapped. */
+ else
+ break;
+
+ if (i >= mmi.size)
+ addr = mmap (mmi.preferred_base, mmi.size,
+ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
+ fileno (f), mmi.offset);
+ }
+#endif /* HAVE_MINCORE */
+
+ needs_read = addr == (void *) MAP_FAILED;
+
+#else /* HAVE_MMAP_FILE */
+ needs_read = true;
+#endif /* HAVE_MMAP_FILE */
+ if (needs_read)
+ addr = xmalloc (mmi.size);
+ }
+
+ if (needs_read)
+ {
+ if (fseek (f, mmi.offset, SEEK_SET) != 0
+ || fread (&mmi, mmi.size, 1, f) != 1)
+ fatal_error ("can't read PCH file: %m");
+ }
+ else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0)
+ fatal_error ("can't read PCH file: %m");
+
+ ggc_pch_read (f, addr);
+
+ if (addr != mmi.preferred_base)
+ {
+ for (rt = gt_ggc_rtab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ for (i = 0; i < rti->nelt; i++)
+ {
+ char **ptr = (char **)((char *)rti->base + rti->stride * i);
+ if (*ptr != NULL)
+ *ptr += (size_t)addr - (size_t)mmi.preferred_base;
+ }
+
+ for (rt = gt_pch_cache_rtab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ for (i = 0; i < rti->nelt; i++)
+ {
+ char **ptr = (char **)((char *)rti->base + rti->stride * i);
+ if (*ptr != NULL)
+ *ptr += (size_t)addr - (size_t)mmi.preferred_base;
+ }
+
+ sorry ("had to relocate PCH");
+ }
+
+ gt_pch_restore_stringpool ();
}
/* Modify the bound based on rlimits. Keep the smallest number found. */
static double
-ggc_rlimit_bound (limit)
- double limit;
+ggc_rlimit_bound (double limit)
{
#if defined(HAVE_GETRLIMIT)
struct rlimit rlim;
@@ -317,13 +715,13 @@ ggc_rlimit_bound (limit)
/* Heuristic to set a default for GGC_MIN_EXPAND. */
int
-ggc_min_expand_heuristic()
+ggc_min_expand_heuristic (void)
{
double min_expand = physmem_total();
/* Adjust for rlimits. */
min_expand = ggc_rlimit_bound (min_expand);
-
+
/* The heuristic is a percentage equal to 30% + 70%*(RAM/1GB), yielding
a lower bound of 30% and an upper bound of 100% (when RAM >= 1GB). */
min_expand /= 1024*1024*1024;
@@ -336,15 +734,15 @@ ggc_min_expand_heuristic()
/* Heuristic to set a default for GGC_MIN_HEAPSIZE. */
int
-ggc_min_heapsize_heuristic()
+ggc_min_heapsize_heuristic (void)
{
double min_heap_kbytes = physmem_total();
/* Adjust for rlimits. */
min_heap_kbytes = ggc_rlimit_bound (min_heap_kbytes);
- min_heap_kbytes /= 1024; /* convert to Kbytes. */
-
+ min_heap_kbytes /= 1024; /* Convert to Kbytes. */
+
/* The heuristic is RAM/8, with a lower bound of 4M and an upper
bound of 128M (when RAM >= 1GB). */
min_heap_kbytes /= 8;
@@ -355,9 +753,9 @@ ggc_min_heapsize_heuristic()
}
void
-init_ggc_heuristics ()
+init_ggc_heuristics (void)
{
-#ifndef ENABLE_GC_ALWAYS_COLLECT
+#if !defined ENABLE_GC_CHECKING && !defined ENABLE_GC_ALWAYS_COLLECT
set_param_value ("ggc-min-expand", ggc_min_expand_heuristic());
set_param_value ("ggc-min-heapsize", ggc_min_heapsize_heuristic());
#endif
diff --git a/contrib/gcc/ggc-none.c b/contrib/gcc/ggc-none.c
index 3711475dc0b2..659bf931d091 100644
--- a/contrib/gcc/ggc-none.c
+++ b/contrib/gcc/ggc-none.c
@@ -1,5 +1,6 @@
/* Null garbage collection for the GNU compiler.
- Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -24,26 +25,38 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "ggc.h"
+struct alloc_zone *rtl_zone = NULL;
+struct alloc_zone *garbage_zone = NULL;
void *
-ggc_alloc (size)
- size_t size;
+ggc_alloc_typed (enum gt_types_enum gte ATTRIBUTE_UNUSED, size_t size)
{
return xmalloc (size);
}
void *
-ggc_alloc_cleared (size)
- size_t size;
+ggc_alloc (size_t size)
+{
+ return xmalloc (size);
+}
+
+void *
+ggc_alloc_zone (size_t size, struct alloc_zone *zone ATTRIBUTE_UNUSED)
+{
+ return xmalloc (size);
+}
+
+void *
+ggc_alloc_cleared (size_t size)
{
return xcalloc (size, 1);
}
void *
-ggc_realloc (x, size)
- void *x;
- size_t size;
+ggc_realloc (void *x, size_t size)
{
return xrealloc (x, size);
}
diff --git a/contrib/gcc/ggc-page.c b/contrib/gcc/ggc-page.c
index 3f5194abf8f2..bf18e3f00d7a 100644
--- a/contrib/gcc/ggc-page.c
+++ b/contrib/gcc/ggc-page.c
@@ -1,5 +1,5 @@
/* "Bag-of-pages" garbage collector for the GNU compiler.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,6 +20,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
@@ -29,7 +31,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "timevar.h"
#include "params.h"
#ifdef ENABLE_VALGRIND_CHECKING
-#include <valgrind.h>
+# ifdef HAVE_VALGRIND_MEMCHECK_H
+# include <valgrind/memcheck.h>
+# elif defined HAVE_MEMCHECK_H
+# include <memcheck.h>
+# else
+# include <valgrind.h>
+# endif
#else
/* Avoid #ifdef:s when we can help it. */
#define VALGRIND_DISCARD(x)
@@ -144,6 +152,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
the indicated ORDER. */
#define OBJECTS_PER_PAGE(ORDER) objects_per_page_table[ORDER]
+/* The number of objects in P. */
+#define OBJECTS_IN_PAGE(P) ((P)->bytes / OBJECT_SIZE ((P)->order))
+
/* The size of an object on a page of the indicated ORDER. */
#define OBJECT_SIZE(ORDER) object_size_table[ORDER]
@@ -162,7 +173,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define NUM_EXTRA_ORDERS ARRAY_SIZE (extra_order_size_table)
#define RTL_SIZE(NSLOTS) \
- (sizeof (struct rtx_def) + ((NSLOTS) - 1) * sizeof (rtunion))
+ (RTX_HDR_SIZE + (NSLOTS) * sizeof (rtunion))
+
+#define TREE_EXP_SIZE(OPS) \
+ (sizeof (struct tree_exp) + ((OPS) - 1) * sizeof (tree))
/* The Ith entry is the maximum size of an object to be stored in the
Ith extra order. Adding a new entry to this array is the *only*
@@ -171,8 +185,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
static const size_t extra_order_size_table[] = {
sizeof (struct tree_decl),
sizeof (struct tree_list),
- RTL_SIZE (2), /* REG, MEM, PLUS, etc. */
- RTL_SIZE (10), /* INSN, CALL_INSN, JUMP_INSN */
+ TREE_EXP_SIZE (2),
+ RTL_SIZE (2), /* MEM, PLUS, etc. */
+ RTL_SIZE (9), /* INSN */
};
/* The total number of orders. */
@@ -187,11 +202,7 @@ struct max_alignment {
char c;
union {
HOST_WIDEST_INT i;
-#ifdef HAVE_LONG_DOUBLE
long double d;
-#else
- double d;
-#endif
} u;
};
@@ -199,6 +210,15 @@ struct max_alignment {
#define MAX_ALIGNMENT (offsetof (struct max_alignment, u))
+/* Compute the smallest nonnegative number which when added to X gives
+ a multiple of F. */
+
+#define ROUND_UP_VALUE(x, f) ((f) - 1 - ((f) - 1 + (x)) % (f))
+
+/* Compute the smallest multiple of F that is >= X. */
+
+#define ROUND_UP(x, f) (CEIL (x, f) * (f))
+
/* The Ith entry is the number of objects on a page or order I. */
static unsigned objects_per_page_table[NUM_ORDERS];
@@ -213,7 +233,7 @@ static size_t object_size_table[NUM_ORDERS];
static struct
{
- unsigned int mult;
+ size_t mult;
unsigned int shift;
}
inverse_table[NUM_ORDERS];
@@ -381,7 +401,34 @@ static struct globals
zero otherwise. We allocate them all together, to enable a
better runtime data access pattern. */
unsigned long **save_in_use;
-
+#ifdef GATHER_STATISTICS
+ struct
+ {
+ /* Total memory allocated with ggc_alloc. */
+ unsigned long long total_allocated;
+ /* Total overhead for memory to be allocated with ggc_alloc. */
+ unsigned long long total_overhead;
+
+ /* Total allocations and overhead for sizes less than 32, 64 and 128.
+ These sizes are interesting because they are typical cache line
+ sizes. */
+
+ unsigned long long total_allocated_under32;
+ unsigned long long total_overhead_under32;
+
+ unsigned long long total_allocated_under64;
+ unsigned long long total_overhead_under64;
+
+ unsigned long long total_allocated_under128;
+ unsigned long long total_overhead_under128;
+
+ /* The allocations for each of the allocation orders. */
+ unsigned long long total_allocated_per_order[NUM_ORDERS];
+
+ /* The overhead for each of the allocation orders. */
+ unsigned long long total_overhead_per_order[NUM_ORDERS];
+ } stats;
+#endif
} G;
/* The size in bytes required to maintain a bitmap for the objects
@@ -398,45 +445,47 @@ static struct globals
/* Initial guess as to how many page table entries we might need. */
#define INITIAL_PTE_COUNT 128
-static int ggc_allocated_p PARAMS ((const void *));
-static page_entry *lookup_page_table_entry PARAMS ((const void *));
-static void set_page_table_entry PARAMS ((void *, page_entry *));
+static int ggc_allocated_p (const void *);
+static page_entry *lookup_page_table_entry (const void *);
+static void set_page_table_entry (void *, page_entry *);
#ifdef USING_MMAP
-static char *alloc_anon PARAMS ((char *, size_t));
+static char *alloc_anon (char *, size_t);
#endif
#ifdef USING_MALLOC_PAGE_GROUPS
-static size_t page_group_index PARAMS ((char *, char *));
-static void set_page_group_in_use PARAMS ((page_group *, char *));
-static void clear_page_group_in_use PARAMS ((page_group *, char *));
+static size_t page_group_index (char *, char *);
+static void set_page_group_in_use (page_group *, char *);
+static void clear_page_group_in_use (page_group *, char *);
#endif
-static struct page_entry * alloc_page PARAMS ((unsigned));
-static void free_page PARAMS ((struct page_entry *));
-static void release_pages PARAMS ((void));
-static void clear_marks PARAMS ((void));
-static void sweep_pages PARAMS ((void));
-static void ggc_recalculate_in_use_p PARAMS ((page_entry *));
-static void compute_inverse PARAMS ((unsigned));
-static inline void adjust_depth PARAMS ((void));
+static struct page_entry * alloc_page (unsigned);
+static void free_page (struct page_entry *);
+static void release_pages (void);
+static void clear_marks (void);
+static void sweep_pages (void);
+static void ggc_recalculate_in_use_p (page_entry *);
+static void compute_inverse (unsigned);
+static inline void adjust_depth (void);
+static void move_ptes_to_front (int, int);
#ifdef ENABLE_GC_CHECKING
-static void poison_pages PARAMS ((void));
+static void poison_pages (void);
#endif
-void debug_print_page_list PARAMS ((int));
-static void push_depth PARAMS ((unsigned int));
-static void push_by_depth PARAMS ((page_entry *, unsigned long *));
-
+void debug_print_page_list (int);
+static void push_depth (unsigned int);
+static void push_by_depth (page_entry *, unsigned long *);
+struct alloc_zone *rtl_zone = NULL;
+struct alloc_zone *tree_zone = NULL;
+struct alloc_zone *garbage_zone = NULL;
+
/* Push an entry onto G.depth. */
inline static void
-push_depth (i)
- unsigned int i;
+push_depth (unsigned int i)
{
if (G.depth_in_use >= G.depth_max)
{
G.depth_max *= 2;
- G.depth = (unsigned int *) xrealloc ((char *) G.depth,
- G.depth_max * sizeof (unsigned int));
+ G.depth = xrealloc (G.depth, G.depth_max * sizeof (unsigned int));
}
G.depth[G.depth_in_use++] = i;
}
@@ -444,24 +493,25 @@ push_depth (i)
/* Push an entry onto G.by_depth and G.save_in_use. */
inline static void
-push_by_depth (p, s)
- page_entry *p;
- unsigned long *s;
+push_by_depth (page_entry *p, unsigned long *s)
{
if (G.by_depth_in_use >= G.by_depth_max)
{
G.by_depth_max *= 2;
- G.by_depth = (page_entry **) xrealloc ((char *) G.by_depth,
- G.by_depth_max * sizeof (page_entry *));
- G.save_in_use = (unsigned long **) xrealloc ((char *) G.save_in_use,
- G.by_depth_max * sizeof (unsigned long *));
+ G.by_depth = xrealloc (G.by_depth,
+ G.by_depth_max * sizeof (page_entry *));
+ G.save_in_use = xrealloc (G.save_in_use,
+ G.by_depth_max * sizeof (unsigned long *));
}
G.by_depth[G.by_depth_in_use] = p;
G.save_in_use[G.by_depth_in_use++] = s;
}
-/* For the 3.3 release, we will avoid prefetch, as it isn't tested widely. */
+#if (GCC_VERSION < 3001)
#define prefetch(X) ((void) X)
+#else
+#define prefetch(X) __builtin_prefetch (X)
+#endif
#define save_in_use_p_i(__i) \
(G.save_in_use[__i])
@@ -471,8 +521,7 @@ push_by_depth (p, s)
/* Returns nonzero if P was allocated in GC'able memory. */
static inline int
-ggc_allocated_p (p)
- const void *p;
+ggc_allocated_p (const void *p)
{
page_entry ***base;
size_t L1, L2;
@@ -504,8 +553,7 @@ ggc_allocated_p (p)
Die (probably) if the object wasn't allocated via GC. */
static inline page_entry *
-lookup_page_table_entry(p)
- const void *p;
+lookup_page_table_entry (const void *p)
{
page_entry ***base;
size_t L1, L2;
@@ -530,9 +578,7 @@ lookup_page_table_entry(p)
/* Set the page table entry for a page. */
static void
-set_page_table_entry(p, entry)
- void *p;
- page_entry *entry;
+set_page_table_entry (void *p, page_entry *entry)
{
page_entry ***base;
size_t L1, L2;
@@ -547,7 +593,7 @@ set_page_table_entry(p, entry)
goto found;
/* Not found -- allocate a new table. */
- table = (page_table) xcalloc (1, sizeof(*table));
+ table = xcalloc (1, sizeof(*table));
table->next = G.lookup;
table->high_bits = high_bits;
G.lookup = table;
@@ -560,7 +606,7 @@ found:
L2 = LOOKUP_L2 (p);
if (base[L1] == NULL)
- base[L1] = (page_entry **) xcalloc (PAGE_L2_SIZE, sizeof (page_entry *));
+ base[L1] = xcalloc (PAGE_L2_SIZE, sizeof (page_entry *));
base[L1][L2] = entry;
}
@@ -568,16 +614,15 @@ found:
/* Prints the page-entry for object size ORDER, for debugging. */
void
-debug_print_page_list (order)
- int order;
+debug_print_page_list (int order)
{
page_entry *p;
- printf ("Head=%p, Tail=%p:\n", (PTR) G.pages[order],
- (PTR) G.page_tails[order]);
+ printf ("Head=%p, Tail=%p:\n", (void *) G.pages[order],
+ (void *) G.page_tails[order]);
p = G.pages[order];
while (p != NULL)
{
- printf ("%p(%1d|%3d) -> ", (PTR) p, p->context_depth,
+ printf ("%p(%1d|%3d) -> ", (void *) p, p->context_depth,
p->num_free_objects);
p = p->next;
}
@@ -591,9 +636,7 @@ debug_print_page_list (order)
compile error unless exactly one of the HAVE_* is defined. */
static inline char *
-alloc_anon (pref, size)
- char *pref ATTRIBUTE_UNUSED;
- size_t size;
+alloc_anon (char *pref ATTRIBUTE_UNUSED, size_t size)
{
#ifdef HAVE_MMAP_ANON
char *page = (char *) mmap (pref, size, PROT_READ | PROT_WRITE,
@@ -625,8 +668,7 @@ alloc_anon (pref, size)
/* Compute the index for this page into the page group. */
static inline size_t
-page_group_index (allocation, page)
- char *allocation, *page;
+page_group_index (char *allocation, char *page)
{
return (size_t) (page - allocation) >> G.lg_pagesize;
}
@@ -634,17 +676,13 @@ page_group_index (allocation, page)
/* Set and clear the in_use bit for this page in the page group. */
static inline void
-set_page_group_in_use (group, page)
- page_group *group;
- char *page;
+set_page_group_in_use (page_group *group, char *page)
{
group->in_use |= 1 << page_group_index (group->allocation, page);
}
static inline void
-clear_page_group_in_use (group, page)
- page_group *group;
- char *page;
+clear_page_group_in_use (page_group *group, char *page)
{
group->in_use &= ~(1 << page_group_index (group->allocation, page));
}
@@ -655,8 +693,7 @@ clear_page_group_in_use (group, page)
appropriate page_table list. */
static inline struct page_entry *
-alloc_page (order)
- unsigned order;
+alloc_page (unsigned order)
{
struct page_entry *entry, *p, **pp;
char *page;
@@ -717,7 +754,7 @@ alloc_page (order)
memory order. */
for (i = GGC_QUIRE_SIZE - 1; i >= 1; i--)
{
- e = (struct page_entry *) xcalloc (1, page_entry_size);
+ e = xcalloc (1, page_entry_size);
e->order = order;
e->bytes = G.pagesize;
e->page = page + (i << G.lg_pagesize);
@@ -789,7 +826,7 @@ alloc_page (order)
struct page_entry *e, *f = G.free_pages;
for (a = enda - G.pagesize; a != page; a -= G.pagesize)
{
- e = (struct page_entry *) xcalloc (1, page_entry_size);
+ e = xcalloc (1, page_entry_size);
e->order = order;
e->bytes = G.pagesize;
e->page = a;
@@ -803,7 +840,7 @@ alloc_page (order)
#endif
if (entry == NULL)
- entry = (struct page_entry *) xcalloc (1, page_entry_size);
+ entry = xcalloc (1, page_entry_size);
entry->bytes = entry_size;
entry->page = page;
@@ -829,7 +866,7 @@ alloc_page (order)
if (GGC_DEBUG_LEVEL >= 2)
fprintf (G.debug_file,
"Allocating page at %p, object size=%lu, data %p-%p\n",
- (PTR) entry, (unsigned long) OBJECT_SIZE (order), page,
+ (void *) entry, (unsigned long) OBJECT_SIZE (order), page,
page + entry_size - 1);
return entry;
@@ -839,7 +876,7 @@ alloc_page (order)
used by the top of the G.by_depth is used. */
static inline void
-adjust_depth ()
+adjust_depth (void)
{
page_entry *top;
@@ -847,8 +884,8 @@ adjust_depth ()
{
top = G.by_depth[G.by_depth_in_use-1];
- /* Peel back indicies in depth that index into by_depth, so that
- as new elements are added to by_depth, we note the indicies
+ /* Peel back indices in depth that index into by_depth, so that
+ as new elements are added to by_depth, we note the indices
of those elements, if they are for new context depths. */
while (G.depth_in_use > (size_t)top->context_depth+1)
--G.depth_in_use;
@@ -858,12 +895,11 @@ adjust_depth ()
/* For a page that is no longer needed, put it on the free page list. */
static inline void
-free_page (entry)
- page_entry *entry;
+free_page (page_entry *entry)
{
if (GGC_DEBUG_LEVEL >= 2)
fprintf (G.debug_file,
- "Deallocating page at %p, data %p-%p\n", (PTR) entry,
+ "Deallocating page at %p, data %p-%p\n", (void *) entry,
entry->page, entry->page + entry->bytes - 1);
/* Mark the page as inaccessible. Discard the handle to avoid handle
@@ -907,7 +943,7 @@ free_page (entry)
/* Release the free page cache to the system. */
static void
-release_pages ()
+release_pages (void)
{
#ifdef USING_MMAP
page_entry *p, *next;
@@ -992,12 +1028,26 @@ static unsigned char size_lookup[257] =
8
};
-/* Allocate a chunk of memory of SIZE bytes. If ZERO is nonzero, the
- memory is zeroed; otherwise, its contents are undefined. */
+/* Typed allocation function. Does nothing special in this collector. */
+
+void *
+ggc_alloc_typed (enum gt_types_enum type ATTRIBUTE_UNUSED, size_t size)
+{
+ return ggc_alloc (size);
+}
+
+/* Zone allocation function. Does nothing special in this collector. */
void *
-ggc_alloc (size)
- size_t size;
+ggc_alloc_zone (size_t size, struct alloc_zone *zone ATTRIBUTE_UNUSED)
+{
+ return ggc_alloc (size);
+}
+
+/* Allocate a chunk of memory of SIZE bytes. Its contents are undefined. */
+
+void *
+ggc_alloc (size_t size)
{
unsigned order, word, bit, object_offset;
struct page_entry *entry;
@@ -1120,11 +1170,36 @@ ggc_alloc (size)
information is used in deciding when to collect. */
G.allocated += OBJECT_SIZE (order);
+#ifdef GATHER_STATISTICS
+ {
+ G.stats.total_overhead += OBJECT_SIZE (order) - size;
+ G.stats.total_allocated += OBJECT_SIZE(order);
+ G.stats.total_overhead_per_order[order] += OBJECT_SIZE (order) - size;
+ G.stats.total_allocated_per_order[order] += OBJECT_SIZE (order);
+
+ if (size <= 32){
+ G.stats.total_overhead_under32 += OBJECT_SIZE (order) - size;
+ G.stats.total_allocated_under32 += OBJECT_SIZE(order);
+ }
+
+ if (size <= 64){
+ G.stats.total_overhead_under64 += OBJECT_SIZE (order) - size;
+ G.stats.total_allocated_under64 += OBJECT_SIZE(order);
+ }
+
+ if (size <= 128){
+ G.stats.total_overhead_under128 += OBJECT_SIZE (order) - size;
+ G.stats.total_allocated_under128 += OBJECT_SIZE(order);
+ }
+
+ }
+#endif
+
if (GGC_DEBUG_LEVEL >= 3)
fprintf (G.debug_file,
"Allocating object, requested size=%lu, actual=%lu at %p on %p\n",
(unsigned long) size, (unsigned long) OBJECT_SIZE (order), result,
- (PTR) entry);
+ (void *) entry);
return result;
}
@@ -1134,8 +1209,7 @@ ggc_alloc (size)
static objects, stack variables, or memory allocated with malloc. */
int
-ggc_set_mark (p)
- const void *p;
+ggc_set_mark (const void *p)
{
page_entry *entry;
unsigned bit, word;
@@ -1174,8 +1248,7 @@ ggc_set_mark (p)
static objects, stack variables, or memory allocated with malloc. */
int
-ggc_marked_p (p)
- const void *p;
+ggc_marked_p (const void *p)
{
page_entry *entry;
unsigned bit, word;
@@ -1201,8 +1274,7 @@ ggc_marked_p (p)
/* Return the size of the gc-able object P. */
size_t
-ggc_get_size (p)
- const void *p;
+ggc_get_size (const void *p)
{
page_entry *pe = lookup_page_table_entry (p);
return OBJECT_SIZE (pe->order);
@@ -1217,22 +1289,10 @@ ggc_get_size (p)
constants). */
static void
-compute_inverse (order)
- unsigned order;
+compute_inverse (unsigned order)
{
- unsigned size, inv, e;
-
- /* There can be only one object per "page" in a bucket for sizes
- larger than half a machine page; it will always have offset zero. */
- if (OBJECT_SIZE (order) > G.pagesize/2)
- {
- if (OBJECTS_PER_PAGE (order) != 1)
- abort ();
-
- DIV_MULT (order) = 1;
- DIV_SHIFT (order) = 0;
- return;
- }
+ size_t size, inv;
+ unsigned int e;
size = OBJECT_SIZE (order);
e = 0;
@@ -1252,7 +1312,7 @@ compute_inverse (order)
/* Initialize the ggc-mmap allocator. */
void
-init_ggc ()
+init_ggc (void)
{
unsigned order;
@@ -1262,7 +1322,7 @@ init_ggc ()
#ifdef HAVE_MMAP_DEV_ZERO
G.dev_zero_fd = open ("/dev/zero", O_RDONLY);
if (G.dev_zero_fd == -1)
- fatal_io_error ("open /dev/zero");
+ internal_error ("open /dev/zero: %m");
#endif
#if 0
@@ -1290,7 +1350,7 @@ init_ggc ()
}
/* We have a good page, might as well hold onto it... */
- e = (struct page_entry *) xcalloc (1, sizeof (struct page_entry));
+ e = xcalloc (1, sizeof (struct page_entry));
e->bytes = G.pagesize;
e->page = p;
e->next = G.free_pages;
@@ -1307,7 +1367,7 @@ init_ggc ()
/* If S is not a multiple of the MAX_ALIGNMENT, then round it up
so that we're sure of getting aligned memory. */
- s = CEIL (s, MAX_ALIGNMENT) * MAX_ALIGNMENT;
+ s = ROUND_UP (s, MAX_ALIGNMENT);
object_size_table[order] = s;
}
@@ -1336,19 +1396,33 @@ init_ggc ()
G.depth_in_use = 0;
G.depth_max = 10;
- G.depth = (unsigned int *) xmalloc (G.depth_max * sizeof (unsigned int));
+ G.depth = xmalloc (G.depth_max * sizeof (unsigned int));
G.by_depth_in_use = 0;
G.by_depth_max = INITIAL_PTE_COUNT;
- G.by_depth = (page_entry **) xmalloc (G.by_depth_max * sizeof (page_entry *));
- G.save_in_use = (unsigned long **) xmalloc (G.by_depth_max * sizeof (unsigned long *));
+ G.by_depth = xmalloc (G.by_depth_max * sizeof (page_entry *));
+ G.save_in_use = xmalloc (G.by_depth_max * sizeof (unsigned long *));
+}
+
+/* Start a new GGC zone. */
+
+struct alloc_zone *
+new_ggc_zone (const char *name ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+/* Destroy a GGC zone. */
+void
+destroy_ggc_zone (struct alloc_zone *zone ATTRIBUTE_UNUSED)
+{
}
/* Increment the `GC context'. Objects allocated in an outer context
are never freed, eliminating the need to register their roots. */
void
-ggc_push_context ()
+ggc_push_context (void)
{
++G.context_depth;
@@ -1361,15 +1435,14 @@ ggc_push_context ()
reflects reality. Recalculate NUM_FREE_OBJECTS as well. */
static void
-ggc_recalculate_in_use_p (p)
- page_entry *p;
+ggc_recalculate_in_use_p (page_entry *p)
{
unsigned int i;
size_t num_objects;
/* Because the past-the-end bit in in_use_p is always set, we
pretend there is one additional object. */
- num_objects = OBJECTS_PER_PAGE (p->order) + 1;
+ num_objects = OBJECTS_IN_PAGE (p) + 1;
/* Reset the free object count. */
p->num_free_objects = num_objects;
@@ -1399,7 +1472,7 @@ ggc_recalculate_in_use_p (p)
previous ggc_push_context are migrated to the outer context. */
void
-ggc_pop_context ()
+ggc_pop_context (void)
{
unsigned long omask;
unsigned int depth, i, e;
@@ -1417,7 +1490,7 @@ ggc_pop_context ()
G.context_depth_allocations &= omask - 1;
G.context_depth_collections &= omask - 1;
- /* The G.depth array is shortend so that the last index is the
+ /* The G.depth array is shortened so that the last index is the
context_depth of the top element of by_depth. */
if (depth+1 < G.depth_in_use)
e = G.depth[depth+1];
@@ -1426,7 +1499,7 @@ ggc_pop_context ()
/* We might not have any PTEs of depth depth. */
if (depth < G.depth_in_use)
- {
+ {
/* First we go through all the pages at depth depth to
recalculate the in use bits. */
@@ -1495,18 +1568,19 @@ ggc_pop_context ()
/* Unmark all objects. */
static inline void
-clear_marks ()
+clear_marks (void)
{
unsigned order;
for (order = 2; order < NUM_ORDERS; order++)
{
- size_t num_objects = OBJECTS_PER_PAGE (order);
- size_t bitmap_size = BITMAP_SIZE (num_objects + 1);
page_entry *p;
for (p = G.pages[order]; p != NULL; p = p->next)
{
+ size_t num_objects = OBJECTS_IN_PAGE (p);
+ size_t bitmap_size = BITMAP_SIZE (num_objects + 1);
+
#ifdef ENABLE_CHECKING
/* The data should be page-aligned. */
if ((size_t) p->page & (G.pagesize - 1))
@@ -1539,7 +1613,7 @@ clear_marks ()
because the `mark' bit doubles as an `unused' bit. */
static inline void
-sweep_pages ()
+sweep_pages (void)
{
unsigned order;
@@ -1549,7 +1623,7 @@ sweep_pages ()
placed at the end of the list. */
page_entry * const last = G.page_tails[order];
- size_t num_objects = OBJECTS_PER_PAGE (order);
+ size_t num_objects;
size_t live_objects;
page_entry *p, *previous;
int done;
@@ -1566,6 +1640,8 @@ sweep_pages ()
/* Loop until all entries have been examined. */
done = (p == last);
+ num_objects = OBJECTS_IN_PAGE (p);
+
/* Add all live objects on this page to the count of
allocated memory. */
live_objects = num_objects - p->num_free_objects;
@@ -1646,18 +1722,18 @@ sweep_pages ()
/* Clobber all free objects. */
static inline void
-poison_pages ()
+poison_pages (void)
{
unsigned order;
for (order = 2; order < NUM_ORDERS; order++)
{
- size_t num_objects = OBJECTS_PER_PAGE (order);
size_t size = OBJECT_SIZE (order);
page_entry *p;
for (p = G.pages[order]; p != NULL; p = p->next)
{
+ size_t num_objects;
size_t i;
if (p->context_depth != G.context_depth)
@@ -1667,6 +1743,7 @@ poison_pages ()
contexts. */
continue;
+ num_objects = OBJECTS_IN_PAGE (p);
for (i = 0; i < num_objects; i++)
{
size_t word, bit;
@@ -1695,7 +1772,7 @@ poison_pages ()
/* Top level mark-and-sweep routine. */
void
-ggc_collect ()
+ggc_collect (void)
{
/* Avoid frequent unnecessary work by skipping collection if the
total allocations haven't expanded much since the last
@@ -1749,7 +1826,7 @@ ggc_collect ()
#define LABEL(x) ((x) < 1024*10 ? ' ' : ((x) < 1024*1024*10 ? 'k' : 'M'))
void
-ggc_print_statistics ()
+ggc_print_statistics (void)
{
struct ggc_statistics stats;
unsigned int i;
@@ -1770,7 +1847,9 @@ ggc_print_statistics ()
/* Collect some information about the various sizes of
allocation. */
- fprintf (stderr, "\n%-5s %10s %10s %10s\n",
+ fprintf (stderr,
+ "Memory still allocated at the end of the compilation process\n");
+ fprintf (stderr, "%-5s %10s %10s %10s\n",
"Size", "Allocated", "Used", "Overhead");
for (i = 0; i < NUM_ORDERS; ++i)
{
@@ -1792,10 +1871,10 @@ ggc_print_statistics ()
{
allocated += p->bytes;
in_use +=
- (OBJECTS_PER_PAGE (i) - p->num_free_objects) * OBJECT_SIZE (i);
+ (OBJECTS_IN_PAGE (p) - p->num_free_objects) * OBJECT_SIZE (i);
overhead += (sizeof (page_entry) - sizeof (long)
- + BITMAP_SIZE (OBJECTS_PER_PAGE (i) + 1));
+ + BITMAP_SIZE (OBJECTS_IN_PAGE (p) + 1));
}
fprintf (stderr, "%-5lu %10lu%c %10lu%c %10lu%c\n",
(unsigned long) OBJECT_SIZE (i),
@@ -1808,4 +1887,330 @@ ggc_print_statistics ()
SCALE (G.bytes_mapped), LABEL (G.bytes_mapped),
SCALE (G.allocated), LABEL(G.allocated),
SCALE (total_overhead), LABEL (total_overhead));
+
+#ifdef GATHER_STATISTICS
+ {
+ fprintf (stderr, "\nTotal allocations and overheads during the compilation process\n");
+
+ fprintf (stderr, "Total Overhead: %10lld\n",
+ G.stats.total_overhead);
+ fprintf (stderr, "Total Allocated: %10lld\n",
+ G.stats.total_allocated);
+
+ fprintf (stderr, "Total Overhead under 32B: %10lld\n",
+ G.stats.total_overhead_under32);
+ fprintf (stderr, "Total Allocated under 32B: %10lld\n",
+ G.stats.total_allocated_under32);
+ fprintf (stderr, "Total Overhead under 64B: %10lld\n",
+ G.stats.total_overhead_under64);
+ fprintf (stderr, "Total Allocated under 64B: %10lld\n",
+ G.stats.total_allocated_under64);
+ fprintf (stderr, "Total Overhead under 128B: %10lld\n",
+ G.stats.total_overhead_under128);
+ fprintf (stderr, "Total Allocated under 128B: %10lld\n",
+ G.stats.total_allocated_under128);
+
+ for (i = 0; i < NUM_ORDERS; i++)
+ if (G.stats.total_allocated_per_order[i])
+ {
+ fprintf (stderr, "Total Overhead page size %7d: %10lld\n",
+ OBJECT_SIZE (i), G.stats.total_overhead_per_order[i]);
+ fprintf (stderr, "Total Allocated page size %7d: %10lld\n",
+ OBJECT_SIZE (i), G.stats.total_allocated_per_order[i]);
+ }
+ }
+#endif
+}
+
+struct ggc_pch_data
+{
+ struct ggc_pch_ondisk
+ {
+ unsigned totals[NUM_ORDERS];
+ } d;
+ size_t base[NUM_ORDERS];
+ size_t written[NUM_ORDERS];
+};
+
+struct ggc_pch_data *
+init_ggc_pch (void)
+{
+ return xcalloc (sizeof (struct ggc_pch_data), 1);
+}
+
+void
+ggc_pch_count_object (struct ggc_pch_data *d, void *x ATTRIBUTE_UNUSED,
+ size_t size, bool is_string ATTRIBUTE_UNUSED)
+{
+ unsigned order;
+
+ if (size <= 256)
+ order = size_lookup[size];
+ else
+ {
+ order = 9;
+ while (size > OBJECT_SIZE (order))
+ order++;
+ }
+
+ d->d.totals[order]++;
+}
+
+size_t
+ggc_pch_total_size (struct ggc_pch_data *d)
+{
+ size_t a = 0;
+ unsigned i;
+
+ for (i = 0; i < NUM_ORDERS; i++)
+ a += ROUND_UP (d->d.totals[i] * OBJECT_SIZE (i), G.pagesize);
+ return a;
+}
+
+void
+ggc_pch_this_base (struct ggc_pch_data *d, void *base)
+{
+ size_t a = (size_t) base;
+ unsigned i;
+
+ for (i = 0; i < NUM_ORDERS; i++)
+ {
+ d->base[i] = a;
+ a += ROUND_UP (d->d.totals[i] * OBJECT_SIZE (i), G.pagesize);
+ }
+}
+
+
+char *
+ggc_pch_alloc_object (struct ggc_pch_data *d, void *x ATTRIBUTE_UNUSED,
+ size_t size, bool is_string ATTRIBUTE_UNUSED)
+{
+ unsigned order;
+ char *result;
+
+ if (size <= 256)
+ order = size_lookup[size];
+ else
+ {
+ order = 9;
+ while (size > OBJECT_SIZE (order))
+ order++;
+ }
+
+ result = (char *) d->base[order];
+ d->base[order] += OBJECT_SIZE (order);
+ return result;
+}
+
+void
+ggc_pch_prepare_write (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
+ FILE *f ATTRIBUTE_UNUSED)
+{
+ /* Nothing to do. */
+}
+
+void
+ggc_pch_write_object (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
+ FILE *f, void *x, void *newx ATTRIBUTE_UNUSED,
+ size_t size, bool is_string ATTRIBUTE_UNUSED)
+{
+ unsigned order;
+ static const char emptyBytes[256];
+
+ if (size <= 256)
+ order = size_lookup[size];
+ else
+ {
+ order = 9;
+ while (size > OBJECT_SIZE (order))
+ order++;
+ }
+
+ if (fwrite (x, size, 1, f) != 1)
+ fatal_error ("can't write PCH file: %m");
+
+ /* If SIZE is not the same as OBJECT_SIZE(order), then we need to pad the
+ object out to OBJECT_SIZE(order). This happens for strings. */
+
+ if (size != OBJECT_SIZE (order))
+ {
+ unsigned padding = OBJECT_SIZE(order) - size;
+
+ /* To speed small writes, we use a nulled-out array that's larger
+ than most padding requests as the source for our null bytes. This
+ permits us to do the padding with fwrite() rather than fseek(), and
+ limits the chance the the OS may try to flush any outstanding
+ writes. */
+ if (padding <= sizeof(emptyBytes))
+ {
+ if (fwrite (emptyBytes, 1, padding, f) != padding)
+ fatal_error ("can't write PCH file");
+ }
+ else
+ {
+ /* Larger than our buffer? Just default to fseek. */
+ if (fseek (f, padding, SEEK_CUR) != 0)
+ fatal_error ("can't write PCH file");
+ }
+ }
+
+ d->written[order]++;
+ if (d->written[order] == d->d.totals[order]
+ && fseek (f, ROUND_UP_VALUE (d->d.totals[order] * OBJECT_SIZE (order),
+ G.pagesize),
+ SEEK_CUR) != 0)
+ fatal_error ("can't write PCH file: %m");
+}
+
+void
+ggc_pch_finish (struct ggc_pch_data *d, FILE *f)
+{
+ if (fwrite (&d->d, sizeof (d->d), 1, f) != 1)
+ fatal_error ("can't write PCH file: %m");
+ free (d);
+}
+
+/* Move the PCH PTE entries just added to the end of by_depth, to the
+ front. */
+
+static void
+move_ptes_to_front (int count_old_page_tables, int count_new_page_tables)
+{
+ unsigned i;
+
+ /* First, we swap the new entries to the front of the varrays. */
+ page_entry **new_by_depth;
+ unsigned long **new_save_in_use;
+
+ new_by_depth = xmalloc (G.by_depth_max * sizeof (page_entry *));
+ new_save_in_use = xmalloc (G.by_depth_max * sizeof (unsigned long *));
+
+ memcpy (&new_by_depth[0],
+ &G.by_depth[count_old_page_tables],
+ count_new_page_tables * sizeof (void *));
+ memcpy (&new_by_depth[count_new_page_tables],
+ &G.by_depth[0],
+ count_old_page_tables * sizeof (void *));
+ memcpy (&new_save_in_use[0],
+ &G.save_in_use[count_old_page_tables],
+ count_new_page_tables * sizeof (void *));
+ memcpy (&new_save_in_use[count_new_page_tables],
+ &G.save_in_use[0],
+ count_old_page_tables * sizeof (void *));
+
+ free (G.by_depth);
+ free (G.save_in_use);
+
+ G.by_depth = new_by_depth;
+ G.save_in_use = new_save_in_use;
+
+ /* Now update all the index_by_depth fields. */
+ for (i = G.by_depth_in_use; i > 0; --i)
+ {
+ page_entry *p = G.by_depth[i-1];
+ p->index_by_depth = i-1;
+ }
+
+ /* And last, we update the depth pointers in G.depth. The first
+ entry is already 0, and context 0 entries always start at index
+ 0, so there is nothing to update in the first slot. We need a
+ second slot, only if we have old ptes, and if we do, they start
+ at index count_new_page_tables. */
+ if (count_old_page_tables)
+ push_depth (count_new_page_tables);
+}
+
+void
+ggc_pch_read (FILE *f, void *addr)
+{
+ struct ggc_pch_ondisk d;
+ unsigned i;
+ char *offs = addr;
+ unsigned long count_old_page_tables;
+ unsigned long count_new_page_tables;
+
+ count_old_page_tables = G.by_depth_in_use;
+
+ /* We've just read in a PCH file. So, every object that used to be
+ allocated is now free. */
+ clear_marks ();
+#ifdef ENABLE_GC_CHECKING
+ poison_pages ();
+#endif
+
+ /* No object read from a PCH file should ever be freed. So, set the
+ context depth to 1, and set the depth of all the currently-allocated
+ pages to be 1 too. PCH pages will have depth 0. */
+ if (G.context_depth != 0)
+ abort ();
+ G.context_depth = 1;
+ for (i = 0; i < NUM_ORDERS; i++)
+ {
+ page_entry *p;
+ for (p = G.pages[i]; p != NULL; p = p->next)
+ p->context_depth = G.context_depth;
+ }
+
+ /* Allocate the appropriate page-table entries for the pages read from
+ the PCH file. */
+ if (fread (&d, sizeof (d), 1, f) != 1)
+ fatal_error ("can't read PCH file: %m");
+
+ for (i = 0; i < NUM_ORDERS; i++)
+ {
+ struct page_entry *entry;
+ char *pte;
+ size_t bytes;
+ size_t num_objs;
+ size_t j;
+
+ if (d.totals[i] == 0)
+ continue;
+
+ bytes = ROUND_UP (d.totals[i] * OBJECT_SIZE (i), G.pagesize);
+ num_objs = bytes / OBJECT_SIZE (i);
+ entry = xcalloc (1, (sizeof (struct page_entry)
+ - sizeof (long)
+ + BITMAP_SIZE (num_objs + 1)));
+ entry->bytes = bytes;
+ entry->page = offs;
+ entry->context_depth = 0;
+ offs += bytes;
+ entry->num_free_objects = 0;
+ entry->order = i;
+
+ for (j = 0;
+ j + HOST_BITS_PER_LONG <= num_objs + 1;
+ j += HOST_BITS_PER_LONG)
+ entry->in_use_p[j / HOST_BITS_PER_LONG] = -1;
+ for (; j < num_objs + 1; j++)
+ entry->in_use_p[j / HOST_BITS_PER_LONG]
+ |= 1L << (j % HOST_BITS_PER_LONG);
+
+ for (pte = entry->page;
+ pte < entry->page + entry->bytes;
+ pte += G.pagesize)
+ set_page_table_entry (pte, entry);
+
+ if (G.page_tails[i] != NULL)
+ G.page_tails[i]->next = entry;
+ else
+ G.pages[i] = entry;
+ G.page_tails[i] = entry;
+
+ /* We start off by just adding all the new information to the
+ end of the varrays, later, we will move the new information
+ to the front of the varrays, as the PCH page tables are at
+ context 0. */
+ push_by_depth (entry, 0);
+ }
+
+ /* Now, we update the various data structures that speed page table
+ handling. */
+ count_new_page_tables = G.by_depth_in_use - count_old_page_tables;
+
+ move_ptes_to_front (count_old_page_tables, count_new_page_tables);
+
+ /* Update the statistics. */
+ G.allocated = G.allocated_last_gc = offs - (char *)addr;
}
diff --git a/contrib/gcc/ggc-simple.c b/contrib/gcc/ggc-simple.c
index 30b8725c0056..4f8a4de9b43f 100644
--- a/contrib/gcc/ggc-simple.c
+++ b/contrib/gcc/ggc-simple.c
@@ -1,5 +1,6 @@
/* Simple garbage collection for the GNU compiler.
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,12 +21,15 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
#include "flags.h"
#include "varray.h"
#include "ggc.h"
+#include "toplev.h"
#include "timevar.h"
#include "params.h"
@@ -82,11 +86,7 @@ struct ggc_mem
/* Make sure the data is reasonably aligned. */
union {
HOST_WIDEST_INT i;
-#ifdef HAVE_LONG_DOUBLE
long double d;
-#else
- double d;
-#endif
} u;
};
@@ -110,25 +110,28 @@ static struct globals
/* Local function prototypes. */
-static void tree_insert PARAMS ((struct ggc_mem *));
-static int tree_lookup PARAMS ((struct ggc_mem *));
-static void clear_marks PARAMS ((struct ggc_mem *));
-static void sweep_objs PARAMS ((struct ggc_mem **));
-static void ggc_pop_context_1 PARAMS ((struct ggc_mem *, int));
+static void tree_insert (struct ggc_mem *);
+static int tree_lookup (struct ggc_mem *);
+static void clear_marks (struct ggc_mem *);
+static void sweep_objs (struct ggc_mem **);
+static void ggc_pop_context_1 (struct ggc_mem *, int);
/* For use from debugger. */
-extern void debug_ggc_tree PARAMS ((struct ggc_mem *, int));
+extern void debug_ggc_tree (struct ggc_mem *, int);
#ifdef GGC_BALANCE
-extern void debug_ggc_balance PARAMS ((void));
+extern void debug_ggc_balance (void);
#endif
-static void tally_leaves PARAMS ((struct ggc_mem *, int, size_t *, size_t *));
+static void tally_leaves (struct ggc_mem *, int, size_t *, size_t *);
+
+struct alloc_zone *rtl_zone = NULL;
+struct alloc_zone *tree_zone = NULL;
+struct alloc_zone *garbage_zone = NULL;
/* Insert V into the search tree. */
static inline void
-tree_insert (v)
- struct ggc_mem *v;
+tree_insert (struct ggc_mem *v)
{
size_t v_key = PTR_KEY (v);
struct ggc_mem *p, **pp;
@@ -144,8 +147,7 @@ tree_insert (v)
/* Return true if V is in the tree. */
static inline int
-tree_lookup (v)
- struct ggc_mem *v;
+tree_lookup (struct ggc_mem *v)
{
size_t v_key = PTR_KEY (v);
struct ggc_mem *p = G.root;
@@ -161,15 +163,30 @@ tree_lookup (v)
return 0;
}
+/* Typed allocation function. Does nothing special in this collector. */
+
+void *
+ggc_alloc_typed (enum gt_types_enum type ATTRIBUTE_UNUSED, size_t size)
+{
+ return ggc_alloc (size);
+}
+
+/* Zone allocation function. Does nothing special in this collector. */
+
+void *
+ggc_alloc_zone (size_t size, struct alloc_zone *zone ATTRIBUTE_UNUSED)
+{
+ return ggc_alloc (size);
+}
+
/* Alloc SIZE bytes of GC'able memory. If ZERO, clear the memory. */
void *
-ggc_alloc (size)
- size_t size;
+ggc_alloc (size_t size)
{
struct ggc_mem *x;
- x = (struct ggc_mem *) xmalloc (offsetof (struct ggc_mem, u) + size);
+ x = xmalloc (offsetof (struct ggc_mem, u) + size);
x->sub[0] = NULL;
x->sub[1] = NULL;
x->mark = 0;
@@ -190,8 +207,7 @@ ggc_alloc (size)
/* Mark a node. */
int
-ggc_set_mark (p)
- const void *p;
+ggc_set_mark (const void *p)
{
struct ggc_mem *x;
@@ -214,8 +230,7 @@ ggc_set_mark (p)
/* Return 1 if P has been marked, zero otherwise. */
int
-ggc_marked_p (p)
- const void *p;
+ggc_marked_p (const void *p)
{
struct ggc_mem *x;
@@ -231,8 +246,7 @@ ggc_marked_p (p)
/* Return the size of the gc-able object P. */
size_t
-ggc_get_size (p)
- const void *p;
+ggc_get_size (const void *p)
{
struct ggc_mem *x
= (struct ggc_mem *) ((const char *)p - offsetof (struct ggc_mem, u));
@@ -242,8 +256,7 @@ ggc_get_size (p)
/* Unmark all objects. */
static void
-clear_marks (x)
- struct ggc_mem *x;
+clear_marks (struct ggc_mem *x)
{
x->mark = 0;
if (x->sub[0])
@@ -255,8 +268,7 @@ clear_marks (x)
/* Free all objects in the current context that are not marked. */
static void
-sweep_objs (root)
- struct ggc_mem **root;
+sweep_objs (struct ggc_mem **root)
{
struct ggc_mem *x = *root;
if (!x)
@@ -305,7 +317,7 @@ sweep_objs (root)
/* The top level mark-and-sweep routine. */
void
-ggc_collect ()
+ggc_collect (void)
{
/* Avoid frequent unnecessary work by skipping collection if the
total allocations haven't expanded much since the last
@@ -348,7 +360,21 @@ ggc_collect ()
/* Called once to initialize the garbage collector. */
void
-init_ggc ()
+init_ggc (void)
+{
+}
+
+/* Start a new GGC zone. */
+
+struct alloc_zone *
+new_ggc_zone (const char *name ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+/* Destroy a GGC zone. */
+void
+destroy_ggc_zone (struct alloc_zone *zone ATTRIBUTE_UNUSED)
{
}
@@ -356,7 +382,7 @@ init_ggc ()
will not be collected while the new context is active. */
void
-ggc_push_context ()
+ggc_push_context (void)
{
G.context++;
@@ -370,7 +396,7 @@ ggc_push_context ()
will be merged with the old context. */
void
-ggc_pop_context ()
+ggc_pop_context (void)
{
G.context--;
if (G.root)
@@ -378,9 +404,7 @@ ggc_pop_context ()
}
static void
-ggc_pop_context_1 (x, c)
- struct ggc_mem *x;
- int c;
+ggc_pop_context_1 (struct ggc_mem *x, int c)
{
if (x->context > c)
x->context = c;
@@ -393,9 +417,7 @@ ggc_pop_context_1 (x, c)
/* Dump a tree. */
void
-debug_ggc_tree (p, indent)
- struct ggc_mem *p;
- int indent;
+debug_ggc_tree (struct ggc_mem *p, int indent)
{
int i;
@@ -410,7 +432,7 @@ debug_ggc_tree (p, indent)
for (i = 0; i < indent; ++i)
putc (' ', stderr);
- fprintf (stderr, "%lx %p\n", (unsigned long)PTR_KEY (p), p);
+ fprintf (stderr, "%lx %p\n", (unsigned long)PTR_KEY (p), (void *) p);
if (p->sub[1])
debug_ggc_tree (p->sub[1], indent + 1);
@@ -422,7 +444,7 @@ debug_ggc_tree (p, indent)
#include <math.h>
void
-debug_ggc_balance ()
+debug_ggc_balance (void)
{
size_t nleaf, sumdepth;
@@ -440,11 +462,7 @@ debug_ggc_balance ()
/* Used by debug_ggc_balance, and also by ggc_print_statistics. */
static void
-tally_leaves (x, depth, nleaf, sumdepth)
- struct ggc_mem *x;
- int depth;
- size_t *nleaf;
- size_t *sumdepth;
+tally_leaves (struct ggc_mem *x, int depth, size_t *nleaf, size_t *sumdepth)
{
if (! x->sub[0] && !x->sub[1])
{
@@ -469,7 +487,7 @@ tally_leaves (x, depth, nleaf, sumdepth)
/* Report on GC memory usage. */
void
-ggc_print_statistics ()
+ggc_print_statistics (void)
{
struct ggc_statistics stats;
size_t nleaf = 0, sumdepth = 0;
@@ -488,16 +506,83 @@ ggc_print_statistics ()
fprintf (stderr, "\n\
Total internal data (bytes)\t%ld%c\n\
-Number of leaves in tree\t%d\n\
+Number of leaves in tree\t%lu\n\
Average leaf depth\t\t%.1f\n",
SCALE(G.objects * offsetof (struct ggc_mem, u)),
LABEL(G.objects * offsetof (struct ggc_mem, u)),
- nleaf, (double)sumdepth / (double)nleaf);
+ (unsigned long)nleaf, (double)sumdepth / (double)nleaf);
/* Report overall memory usage. */
fprintf (stderr, "\n\
-Total objects allocated\t\t%d\n\
+Total objects allocated\t\t%ld\n\
Total memory in GC arena\t%ld%c\n",
- G.objects,
+ (unsigned long)G.objects,
SCALE(G.allocated), LABEL(G.allocated));
}
+
+struct ggc_pch_data *
+init_ggc_pch (void)
+{
+ sorry ("Generating PCH files is not supported when using ggc-simple.c");
+ /* It could be supported, but the code is not yet written. */
+ return NULL;
+}
+
+void
+ggc_pch_count_object (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
+ void *x ATTRIBUTE_UNUSED,
+ size_t size ATTRIBUTE_UNUSED,
+ bool is_string ATTRIBUTE_UNUSED)
+{
+}
+
+size_t
+ggc_pch_total_size (struct ggc_pch_data *d ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+void
+ggc_pch_this_base (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
+ void *base ATTRIBUTE_UNUSED)
+{
+}
+
+
+char *
+ggc_pch_alloc_object (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
+ void *x ATTRIBUTE_UNUSED,
+ size_t size ATTRIBUTE_UNUSED,
+ bool is_string ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+void
+ggc_pch_prepare_write (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
+ FILE * f ATTRIBUTE_UNUSED)
+{
+}
+
+void
+ggc_pch_write_object (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
+ FILE *f ATTRIBUTE_UNUSED, void *x ATTRIBUTE_UNUSED,
+ void *newx ATTRIBUTE_UNUSED,
+ size_t size ATTRIBUTE_UNUSED,
+ bool is_string ATTRIBUTE_UNUSED)
+{
+}
+
+void
+ggc_pch_finish (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
+ FILE *f ATTRIBUTE_UNUSED)
+{
+}
+
+void
+ggc_pch_read (FILE *f ATTRIBUTE_UNUSED, void *addr ATTRIBUTE_UNUSED)
+{
+ /* This should be impossible, since we won't generate any valid PCH
+ files for this configuration. */
+ abort ();
+}
diff --git a/contrib/gcc/ggc-zone.c b/contrib/gcc/ggc-zone.c
new file mode 100644
index 000000000000..355414fcbbc7
--- /dev/null
+++ b/contrib/gcc/ggc-zone.c
@@ -0,0 +1,1398 @@
+/* "Bag-of-pages" zone garbage collector for the GNU compiler.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
+ Contributed by Richard Henderson (rth@redhat.com) and Daniel Berlin
+ (dberlin@dberlin.org)
+
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "toplev.h"
+#include "varray.h"
+#include "flags.h"
+#include "ggc.h"
+#include "timevar.h"
+#include "params.h"
+#include "bitmap.h"
+
+#ifdef ENABLE_VALGRIND_CHECKING
+# ifdef HAVE_VALGRIND_MEMCHECK_H
+# include <valgrind/memcheck.h>
+# elif defined HAVE_MEMCHECK_H
+# include <memcheck.h>
+# else
+# include <valgrind.h>
+# endif
+#else
+/* Avoid #ifdef:s when we can help it. */
+#define VALGRIND_DISCARD(x)
+#define VALGRIND_MALLOCLIKE_BLOCK(w,x,y,z)
+#define VALGRIND_FREELIKE_BLOCK(x,y)
+#endif
+/* Prefer MAP_ANON(YMOUS) to /dev/zero, since we don't need to keep a
+ file open. Prefer either to valloc. */
+#ifdef HAVE_MMAP_ANON
+# undef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+# define MAP_FAILED -1
+# endif
+# if !defined (MAP_ANONYMOUS) && defined (MAP_ANON)
+# define MAP_ANONYMOUS MAP_ANON
+# endif
+# define USING_MMAP
+
+#endif
+
+#ifdef HAVE_MMAP_DEV_ZERO
+
+# include <sys/mman.h>
+# ifndef MAP_FAILED
+# define MAP_FAILED -1
+# endif
+# define USING_MMAP
+
+#endif
+
+#ifndef USING_MMAP
+#error "Zone collector requires mmap"
+#endif
+
+#if (GCC_VERSION < 3001)
+#define prefetch(X) ((void) X)
+#else
+#define prefetch(X) __builtin_prefetch (X)
+#endif
+
+/* NOTES:
+ If we track inter-zone pointers, we can mark single zones at a
+ time.
+ If we have a zone where we guarantee no inter-zone pointers, we
+ could mark that zone separately.
+ The garbage zone should not be marked, and we should return 1 in
+ ggc_set_mark for any object in the garbage zone, which cuts off
+ marking quickly. */
+/* Stategy:
+
+ This garbage-collecting allocator segregates objects into zones.
+ It also segregates objects into "large" and "small" bins. Large
+ objects are greater or equal to page size.
+
+ Pages for small objects are broken up into chunks, each of which
+ are described by a struct alloc_chunk. One can walk over all
+ chunks on the page by adding the chunk size to the chunk's data
+ address. The free space for a page exists in the free chunk bins.
+
+ Each page-entry also has a context depth, which is used to track
+ pushing and popping of allocation contexts. Only objects allocated
+ in the current (highest-numbered) context may be collected.
+
+ Empty pages (of all sizes) are kept on a single page cache list,
+ and are considered first when new pages are required; they are
+ deallocated at the start of the next collection if they haven't
+ been recycled by then. */
+
+/* Define GGC_DEBUG_LEVEL to print debugging information.
+ 0: No debugging output.
+ 1: GC statistics only.
+ 2: Page-entry allocations/deallocations as well.
+ 3: Object allocations as well.
+ 4: Object marks as well. */
+#define GGC_DEBUG_LEVEL (0)
+
+#ifndef HOST_BITS_PER_PTR
+#define HOST_BITS_PER_PTR HOST_BITS_PER_LONG
+#endif
+#ifdef COOKIE_CHECKING
+#define CHUNK_MAGIC 0x95321123
+#define DEADCHUNK_MAGIC 0x12817317
+#endif
+
+/* This structure manages small chunks. When the chunk is free, it's
+ linked with other chunks via free_next. When the chunk is allocated,
+ the data starts at u. Large chunks are allocated one at a time to
+ their own page, and so don't come in here.
+
+ The "type" field is a placeholder for a future change to do
+ generational collection. At present it is 0 when free and
+ and 1 when allocated. */
+
+struct alloc_chunk {
+#ifdef COOKIE_CHECKING
+ unsigned int magic;
+#endif
+ unsigned int type:1;
+ unsigned int typecode:14;
+ unsigned int large:1;
+ unsigned int size:15;
+ unsigned int mark:1;
+ union {
+ struct alloc_chunk *next_free;
+ char data[1];
+
+ /* Make sure the data is sufficiently aligned. */
+ HOST_WIDEST_INT align_i;
+#ifdef HAVE_LONG_DOUBLE
+ long double align_d;
+#else
+ double align_d;
+#endif
+ } u;
+} __attribute__ ((packed));
+
+#define CHUNK_OVERHEAD (offsetof (struct alloc_chunk, u))
+
+/* We maintain several bins of free lists for chunks for very small
+ objects. We never exhaustively search other bins -- if we don't
+ find one of the proper size, we allocate from the "larger" bin. */
+
+/* Decreasing the number of free bins increases the time it takes to allocate.
+ Similar with increasing max_free_bin_size without increasing num_free_bins.
+
+ After much histogramming of allocation sizes and time spent on gc,
+ on a PowerPC G4 7450 - 667 mhz, and a Pentium 4 - 2.8ghz,
+ these were determined to be the optimal values. */
+#define NUM_FREE_BINS 64
+#define MAX_FREE_BIN_SIZE 256
+#define FREE_BIN_DELTA (MAX_FREE_BIN_SIZE / NUM_FREE_BINS)
+#define SIZE_BIN_UP(SIZE) (((SIZE) + FREE_BIN_DELTA - 1) / FREE_BIN_DELTA)
+#define SIZE_BIN_DOWN(SIZE) ((SIZE) / FREE_BIN_DELTA)
+
+/* Marker used as chunk->size for a large object. Should correspond
+ to the size of the bitfield above. */
+#define LARGE_OBJECT_SIZE 0x7fff
+
+/* We use this structure to determine the alignment required for
+ allocations. For power-of-two sized allocations, that's not a
+ problem, but it does matter for odd-sized allocations. */
+
+struct max_alignment {
+ char c;
+ union {
+ HOST_WIDEST_INT i;
+#ifdef HAVE_LONG_DOUBLE
+ long double d;
+#else
+ double d;
+#endif
+ } u;
+};
+
+/* The biggest alignment required. */
+
+#define MAX_ALIGNMENT (offsetof (struct max_alignment, u))
+
+/* Compute the smallest nonnegative number which when added to X gives
+ a multiple of F. */
+
+#define ROUND_UP_VALUE(x, f) ((f) - 1 - ((f) - 1 + (x)) % (f))
+
+/* Compute the smallest multiple of F that is >= X. */
+
+#define ROUND_UP(x, f) (CEIL (x, f) * (f))
+
+
+/* A page_entry records the status of an allocation page. */
+typedef struct page_entry
+{
+ /* The next page-entry with objects of the same size, or NULL if
+ this is the last page-entry. */
+ struct page_entry *next;
+
+ /* The number of bytes allocated. (This will always be a multiple
+ of the host system page size.) */
+ size_t bytes;
+
+ /* How many collections we've survived. */
+ size_t survived;
+
+ /* The address at which the memory is allocated. */
+ char *page;
+
+ /* Context depth of this page. */
+ unsigned short context_depth;
+
+ /* Does this page contain small objects, or one large object? */
+ bool large_p;
+
+ /* The zone that this page entry belongs to. */
+ struct alloc_zone *zone;
+} page_entry;
+
+
+/* The global variables. */
+static struct globals
+{
+ /* The linked list of zones. */
+ struct alloc_zone *zones;
+
+ /* The system's page size. */
+ size_t pagesize;
+ size_t lg_pagesize;
+
+ /* A file descriptor open to /dev/zero for reading. */
+#if defined (HAVE_MMAP_DEV_ZERO)
+ int dev_zero_fd;
+#endif
+
+ /* The file descriptor for debugging output. */
+ FILE *debug_file;
+} G;
+
+/* The zone allocation structure. */
+struct alloc_zone
+{
+ /* Name of the zone. */
+ const char *name;
+
+ /* Linked list of pages in a zone. */
+ page_entry *pages;
+
+ /* Linked lists of free storage. Slots 1 ... NUM_FREE_BINS have chunks of size
+ FREE_BIN_DELTA. All other chunks are in slot 0. */
+ struct alloc_chunk *free_chunks[NUM_FREE_BINS + 1];
+
+ /* Bytes currently allocated. */
+ size_t allocated;
+
+ /* Bytes currently allocated at the end of the last collection. */
+ size_t allocated_last_gc;
+
+ /* Total amount of memory mapped. */
+ size_t bytes_mapped;
+
+ /* Bit N set if any allocations have been done at context depth N. */
+ unsigned long context_depth_allocations;
+
+ /* Bit N set if any collections have been done at context depth N. */
+ unsigned long context_depth_collections;
+
+ /* The current depth in the context stack. */
+ unsigned short context_depth;
+
+ /* A cache of free system pages. */
+ page_entry *free_pages;
+
+ /* Next zone in the linked list of zones. */
+ struct alloc_zone *next_zone;
+
+ /* True if this zone was collected during this collection. */
+ bool was_collected;
+
+ /* True if this zone should be destroyed after the next collection. */
+ bool dead;
+} main_zone;
+
+struct alloc_zone *rtl_zone;
+struct alloc_zone *garbage_zone;
+struct alloc_zone *tree_zone;
+
+/* Allocate pages in chunks of this size, to throttle calls to memory
+ allocation routines. The first page is used, the rest go onto the
+ free list. This cannot be larger than HOST_BITS_PER_INT for the
+ in_use bitmask for page_group. */
+#define GGC_QUIRE_SIZE 16
+
+static int ggc_allocated_p (const void *);
+#ifdef USING_MMAP
+static char *alloc_anon (char *, size_t, struct alloc_zone *);
+#endif
+static struct page_entry * alloc_small_page ( struct alloc_zone *);
+static struct page_entry * alloc_large_page (size_t, struct alloc_zone *);
+static void free_chunk (struct alloc_chunk *, size_t, struct alloc_zone *);
+static void free_page (struct page_entry *);
+static void release_pages (struct alloc_zone *);
+static void sweep_pages (struct alloc_zone *);
+static void * ggc_alloc_zone_1 (size_t, struct alloc_zone *, short);
+static bool ggc_collect_1 (struct alloc_zone *, bool);
+static void check_cookies (void);
+
+
+/* Returns nonzero if P was allocated in GC'able memory. */
+
+static inline int
+ggc_allocated_p (const void *p)
+{
+ struct alloc_chunk *chunk;
+ chunk = (struct alloc_chunk *) ((char *)p - CHUNK_OVERHEAD);
+#ifdef COOKIE_CHECKING
+ if (chunk->magic != CHUNK_MAGIC)
+ abort ();
+#endif
+ if (chunk->type == 1)
+ return true;
+ return false;
+}
+
+
+#ifdef USING_MMAP
+/* Allocate SIZE bytes of anonymous memory, preferably near PREF,
+ (if non-null). The ifdef structure here is intended to cause a
+ compile error unless exactly one of the HAVE_* is defined. */
+
+static inline char *
+alloc_anon (char *pref ATTRIBUTE_UNUSED, size_t size, struct alloc_zone *zone)
+{
+#ifdef HAVE_MMAP_ANON
+ char *page = (char *) mmap (pref, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#endif
+#ifdef HAVE_MMAP_DEV_ZERO
+ char *page = (char *) mmap (pref, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, G.dev_zero_fd, 0);
+#endif
+ VALGRIND_MALLOCLIKE_BLOCK(page, size, 0, 0);
+
+ if (page == (char *) MAP_FAILED)
+ {
+ perror ("virtual memory exhausted");
+ exit (FATAL_EXIT_CODE);
+ }
+
+ /* Remember that we allocated this memory. */
+ zone->bytes_mapped += size;
+ /* Pretend we don't have access to the allocated pages. We'll enable
+ access to smaller pieces of the area in ggc_alloc. Discard the
+ handle to avoid handle leak. */
+ VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS (page, size));
+ return page;
+}
+#endif
+
+/* Allocate a new page for allocating objects of size 2^ORDER,
+ and return an entry for it. */
+
+static inline struct page_entry *
+alloc_small_page (struct alloc_zone *zone)
+{
+ struct page_entry *entry;
+ char *page;
+
+ page = NULL;
+
+ /* Check the list of free pages for one we can use. */
+ entry = zone->free_pages;
+ if (entry != NULL)
+ {
+ /* Recycle the allocated memory from this page ... */
+ zone->free_pages = entry->next;
+ page = entry->page;
+
+
+ }
+#ifdef USING_MMAP
+ else
+ {
+ /* We want just one page. Allocate a bunch of them and put the
+ extras on the freelist. (Can only do this optimization with
+ mmap for backing store.) */
+ struct page_entry *e, *f = zone->free_pages;
+ int i;
+
+ page = alloc_anon (NULL, G.pagesize * GGC_QUIRE_SIZE, zone);
+
+ /* This loop counts down so that the chain will be in ascending
+ memory order. */
+ for (i = GGC_QUIRE_SIZE - 1; i >= 1; i--)
+ {
+ e = (struct page_entry *) xmalloc (sizeof (struct page_entry));
+ e->bytes = G.pagesize;
+ e->page = page + (i << G.lg_pagesize);
+ e->next = f;
+ f = e;
+ }
+
+ zone->free_pages = f;
+ }
+#endif
+ if (entry == NULL)
+ entry = (struct page_entry *) xmalloc (sizeof (struct page_entry));
+
+ entry->next = 0;
+ entry->bytes = G.pagesize;
+ entry->page = page;
+ entry->context_depth = zone->context_depth;
+ entry->large_p = false;
+ entry->zone = zone;
+ zone->context_depth_allocations |= (unsigned long)1 << zone->context_depth;
+
+ if (GGC_DEBUG_LEVEL >= 2)
+ fprintf (G.debug_file,
+ "Allocating %s page at %p, data %p-%p\n", entry->zone->name,
+ (PTR) entry, page, page + G.pagesize - 1);
+
+ return entry;
+}
+/* Compute the smallest multiple of F that is >= X. */
+
+#define ROUND_UP(x, f) (CEIL (x, f) * (f))
+
+/* Allocate a large page of size SIZE in ZONE. */
+
+static inline struct page_entry *
+alloc_large_page (size_t size, struct alloc_zone *zone)
+{
+ struct page_entry *entry;
+ char *page;
+ size = ROUND_UP (size, 1024);
+ page = (char *) xmalloc (size + CHUNK_OVERHEAD + sizeof (struct page_entry));
+ entry = (struct page_entry *) (page + size + CHUNK_OVERHEAD);
+
+ entry->next = 0;
+ entry->bytes = size;
+ entry->page = page;
+ entry->context_depth = zone->context_depth;
+ entry->large_p = true;
+ entry->zone = zone;
+ zone->context_depth_allocations |= (unsigned long)1 << zone->context_depth;
+
+ if (GGC_DEBUG_LEVEL >= 2)
+ fprintf (G.debug_file,
+ "Allocating %s large page at %p, data %p-%p\n", entry->zone->name,
+ (PTR) entry, page, page + size - 1);
+
+ return entry;
+}
+
+
+/* For a page that is no longer needed, put it on the free page list. */
+
+static inline void
+free_page (page_entry *entry)
+{
+ if (GGC_DEBUG_LEVEL >= 2)
+ fprintf (G.debug_file,
+ "Deallocating %s page at %p, data %p-%p\n", entry->zone->name, (PTR) entry,
+ entry->page, entry->page + entry->bytes - 1);
+
+ if (entry->large_p)
+ {
+ free (entry->page);
+ VALGRIND_FREELIKE_BLOCK (entry->page, entry->bytes);
+ }
+ else
+ {
+ /* Mark the page as inaccessible. Discard the handle to
+ avoid handle leak. */
+ VALGRIND_DISCARD (VALGRIND_MAKE_NOACCESS (entry->page, entry->bytes));
+
+ entry->next = entry->zone->free_pages;
+ entry->zone->free_pages = entry;
+ }
+}
+
+/* Release the free page cache to the system. */
+
+static void
+release_pages (struct alloc_zone *zone)
+{
+#ifdef USING_MMAP
+ page_entry *p, *next;
+ char *start;
+ size_t len;
+
+ /* Gather up adjacent pages so they are unmapped together. */
+ p = zone->free_pages;
+
+ while (p)
+ {
+ start = p->page;
+ next = p->next;
+ len = p->bytes;
+ free (p);
+ p = next;
+
+ while (p && p->page == start + len)
+ {
+ next = p->next;
+ len += p->bytes;
+ free (p);
+ p = next;
+ }
+
+ munmap (start, len);
+ zone->bytes_mapped -= len;
+ }
+
+ zone->free_pages = NULL;
+#endif
+}
+
+/* Place CHUNK of size SIZE on the free list for ZONE. */
+
+static inline void
+free_chunk (struct alloc_chunk *chunk, size_t size, struct alloc_zone *zone)
+{
+ size_t bin = 0;
+
+ bin = SIZE_BIN_DOWN (size);
+ if (bin == 0)
+ abort ();
+ if (bin > NUM_FREE_BINS)
+ bin = 0;
+#ifdef COOKIE_CHECKING
+ if (chunk->magic != CHUNK_MAGIC && chunk->magic != DEADCHUNK_MAGIC)
+ abort ();
+ chunk->magic = DEADCHUNK_MAGIC;
+#endif
+ chunk->u.next_free = zone->free_chunks[bin];
+ zone->free_chunks[bin] = chunk;
+ if (GGC_DEBUG_LEVEL >= 3)
+ fprintf (G.debug_file, "Deallocating object, chunk=%p\n", (void *)chunk);
+ VALGRIND_DISCARD (VALGRIND_MAKE_READABLE (chunk, sizeof (struct alloc_chunk)));
+}
+
+/* Allocate a chunk of memory of SIZE bytes. */
+
+static void *
+ggc_alloc_zone_1 (size_t size, struct alloc_zone *zone, short type)
+{
+ size_t bin = 0;
+ size_t lsize = 0;
+ struct page_entry *entry;
+ struct alloc_chunk *chunk, *lchunk, **pp;
+ void *result;
+
+ /* Align size, so that we're assured of aligned allocations. */
+ if (size < FREE_BIN_DELTA)
+ size = FREE_BIN_DELTA;
+ size = (size + MAX_ALIGNMENT - 1) & -MAX_ALIGNMENT;
+
+ /* Large objects are handled specially. */
+ if (size >= G.pagesize - 2*CHUNK_OVERHEAD - FREE_BIN_DELTA)
+ {
+ size = ROUND_UP (size, 1024);
+ entry = alloc_large_page (size, zone);
+ entry->survived = 0;
+ entry->next = entry->zone->pages;
+ entry->zone->pages = entry;
+
+ chunk = (struct alloc_chunk *) entry->page;
+ VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (chunk, sizeof (struct alloc_chunk)));
+ chunk->large = 1;
+ chunk->size = CEIL (size, 1024);
+
+ goto found;
+ }
+
+ /* First look for a tiny object already segregated into its own
+ size bucket. */
+ bin = SIZE_BIN_UP (size);
+ if (bin <= NUM_FREE_BINS)
+ {
+ chunk = zone->free_chunks[bin];
+ if (chunk)
+ {
+ zone->free_chunks[bin] = chunk->u.next_free;
+ VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (chunk, sizeof (struct alloc_chunk)));
+ goto found;
+ }
+ }
+
+ /* Failing that, look through the "other" bucket for a chunk
+ that is large enough. */
+ pp = &(zone->free_chunks[0]);
+ chunk = *pp;
+ while (chunk && chunk->size < size)
+ {
+ pp = &chunk->u.next_free;
+ chunk = *pp;
+ }
+
+ /* Failing that, allocate new storage. */
+ if (!chunk)
+ {
+ entry = alloc_small_page (zone);
+ entry->next = entry->zone->pages;
+ entry->zone->pages = entry;
+
+ chunk = (struct alloc_chunk *) entry->page;
+ VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (chunk, sizeof (struct alloc_chunk)));
+ chunk->size = G.pagesize - CHUNK_OVERHEAD;
+ chunk->large = 0;
+ }
+ else
+ {
+ *pp = chunk->u.next_free;
+ VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (chunk, sizeof (struct alloc_chunk)));
+ chunk->large = 0;
+ }
+ /* Release extra memory from a chunk that's too big. */
+ lsize = chunk->size - size;
+ if (lsize >= CHUNK_OVERHEAD + FREE_BIN_DELTA)
+ {
+ VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (chunk, sizeof (struct alloc_chunk)));
+ chunk->size = size;
+
+ lsize -= CHUNK_OVERHEAD;
+ lchunk = (struct alloc_chunk *)(chunk->u.data + size);
+ VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (lchunk, sizeof (struct alloc_chunk)));
+#ifdef COOKIE_CHECKING
+ lchunk->magic = CHUNK_MAGIC;
+#endif
+ lchunk->type = 0;
+ lchunk->mark = 0;
+ lchunk->size = lsize;
+ lchunk->large = 0;
+ free_chunk (lchunk, lsize, zone);
+ }
+ /* Calculate the object's address. */
+ found:
+#ifdef COOKIE_CHECKING
+ chunk->magic = CHUNK_MAGIC;
+#endif
+ chunk->type = 1;
+ chunk->mark = 0;
+ chunk->typecode = type;
+ result = chunk->u.data;
+
+#ifdef ENABLE_GC_CHECKING
+ /* Keep poisoning-by-writing-0xaf the object, in an attempt to keep the
+ exact same semantics in presence of memory bugs, regardless of
+ ENABLE_VALGRIND_CHECKING. We override this request below. Drop the
+ handle to avoid handle leak. */
+ VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (result, size));
+
+ /* `Poison' the entire allocated object. */
+ memset (result, 0xaf, size);
+#endif
+
+ /* Tell Valgrind that the memory is there, but its content isn't
+ defined. The bytes at the end of the object are still marked
+ unaccessible. */
+ VALGRIND_DISCARD (VALGRIND_MAKE_WRITABLE (result, size));
+
+ /* Keep track of how many bytes are being allocated. This
+ information is used in deciding when to collect. */
+ zone->allocated += size + CHUNK_OVERHEAD;
+
+ if (GGC_DEBUG_LEVEL >= 3)
+ fprintf (G.debug_file, "Allocating object, chunk=%p size=%lu at %p\n",
+ (void *)chunk, (unsigned long) size, result);
+
+ return result;
+}
+
+/* Allocate a SIZE of chunk memory of GTE type, into an appropriate zone
+ for that type. */
+
+void *
+ggc_alloc_typed (enum gt_types_enum gte, size_t size)
+{
+ switch (gte)
+ {
+ case gt_ggc_e_14lang_tree_node:
+ return ggc_alloc_zone_1 (size, tree_zone, gte);
+
+ case gt_ggc_e_7rtx_def:
+ return ggc_alloc_zone_1 (size, rtl_zone, gte);
+
+ case gt_ggc_e_9rtvec_def:
+ return ggc_alloc_zone_1 (size, rtl_zone, gte);
+
+ default:
+ return ggc_alloc_zone_1 (size, &main_zone, gte);
+ }
+}
+
+/* Normal ggc_alloc simply allocates into the main zone. */
+
+void *
+ggc_alloc (size_t size)
+{
+ return ggc_alloc_zone_1 (size, &main_zone, -1);
+}
+
+/* Zone allocation allocates into the specified zone. */
+
+void *
+ggc_alloc_zone (size_t size, struct alloc_zone *zone)
+{
+ return ggc_alloc_zone_1 (size, zone, -1);
+}
+
+/* If P is not marked, mark it and return false. Otherwise return true.
+ P must have been allocated by the GC allocator; it mustn't point to
+ static objects, stack variables, or memory allocated with malloc. */
+
+int
+ggc_set_mark (const void *p)
+{
+ struct alloc_chunk *chunk;
+
+ chunk = (struct alloc_chunk *) ((char *)p - CHUNK_OVERHEAD);
+#ifdef COOKIE_CHECKING
+ if (chunk->magic != CHUNK_MAGIC)
+ abort ();
+#endif
+ if (chunk->mark)
+ return 1;
+ chunk->mark = 1;
+
+ if (GGC_DEBUG_LEVEL >= 4)
+ fprintf (G.debug_file, "Marking %p\n", p);
+
+ return 0;
+}
+
+/* Return 1 if P has been marked, zero otherwise.
+ P must have been allocated by the GC allocator; it mustn't point to
+ static objects, stack variables, or memory allocated with malloc. */
+
+int
+ggc_marked_p (const void *p)
+{
+ struct alloc_chunk *chunk;
+
+ chunk = (struct alloc_chunk *) ((char *)p - CHUNK_OVERHEAD);
+#ifdef COOKIE_CHECKING
+ if (chunk->magic != CHUNK_MAGIC)
+ abort ();
+#endif
+ return chunk->mark;
+}
+
+/* Return the size of the gc-able object P. */
+
+size_t
+ggc_get_size (const void *p)
+{
+ struct alloc_chunk *chunk;
+
+ chunk = (struct alloc_chunk *) ((char *)p - CHUNK_OVERHEAD);
+#ifdef COOKIE_CHECKING
+ if (chunk->magic != CHUNK_MAGIC)
+ abort ();
+#endif
+ if (chunk->large)
+ return chunk->size * 1024;
+
+ return chunk->size;
+}
+
+/* Initialize the ggc-zone-mmap allocator. */
+void
+init_ggc (void)
+{
+ /* Set up the main zone by hand. */
+ main_zone.name = "Main zone";
+ G.zones = &main_zone;
+
+ /* Allocate the default zones. */
+ rtl_zone = new_ggc_zone ("RTL zone");
+ tree_zone = new_ggc_zone ("Tree zone");
+ garbage_zone = new_ggc_zone ("Garbage zone");
+
+ G.pagesize = getpagesize();
+ G.lg_pagesize = exact_log2 (G.pagesize);
+#ifdef HAVE_MMAP_DEV_ZERO
+ G.dev_zero_fd = open ("/dev/zero", O_RDONLY);
+ if (G.dev_zero_fd == -1)
+ abort ();
+#endif
+
+#if 0
+ G.debug_file = fopen ("ggc-mmap.debug", "w");
+ setlinebuf (G.debug_file);
+#else
+ G.debug_file = stdout;
+#endif
+
+#ifdef USING_MMAP
+ /* StunOS has an amazing off-by-one error for the first mmap allocation
+ after fiddling with RLIMIT_STACK. The result, as hard as it is to
+ believe, is an unaligned page allocation, which would cause us to
+ hork badly if we tried to use it. */
+ {
+ char *p = alloc_anon (NULL, G.pagesize, &main_zone);
+ struct page_entry *e;
+ if ((size_t)p & (G.pagesize - 1))
+ {
+ /* How losing. Discard this one and try another. If we still
+ can't get something useful, give up. */
+
+ p = alloc_anon (NULL, G.pagesize, &main_zone);
+ if ((size_t)p & (G.pagesize - 1))
+ abort ();
+ }
+
+ /* We have a good page, might as well hold onto it... */
+ e = (struct page_entry *) xmalloc (sizeof (struct page_entry));
+ e->bytes = G.pagesize;
+ e->page = p;
+ e->next = main_zone.free_pages;
+ main_zone.free_pages = e;
+ }
+#endif
+}
+
+/* Start a new GGC zone. */
+
+struct alloc_zone *
+new_ggc_zone (const char * name)
+{
+ struct alloc_zone *new_zone = xcalloc (1, sizeof (struct alloc_zone));
+ new_zone->name = name;
+ new_zone->next_zone = G.zones->next_zone;
+ G.zones->next_zone = new_zone;
+ return new_zone;
+}
+
+/* Destroy a GGC zone. */
+void
+destroy_ggc_zone (struct alloc_zone * dead_zone)
+{
+ struct alloc_zone *z;
+
+ for (z = G.zones; z && z->next_zone != dead_zone; z = z->next_zone)
+ /* Just find that zone. */ ;
+
+#ifdef ENABLE_CHECKING
+ /* We should have found the zone in the list. Anything else is fatal. */
+ if (!z)
+ abort ();
+#endif
+
+ /* z is dead, baby. z is dead. */
+ z->dead= true;
+}
+
+/* Increment the `GC context'. Objects allocated in an outer context
+ are never freed, eliminating the need to register their roots. */
+
+void
+ggc_push_context (void)
+{
+ struct alloc_zone *zone;
+ for (zone = G.zones; zone; zone = zone->next_zone)
+ ++(zone->context_depth);
+ /* Die on wrap. */
+ if (main_zone.context_depth >= HOST_BITS_PER_LONG)
+ abort ();
+}
+
+/* Decrement the `GC context'. All objects allocated since the
+ previous ggc_push_context are migrated to the outer context. */
+
+static void
+ggc_pop_context_1 (struct alloc_zone *zone)
+{
+ unsigned long omask;
+ unsigned depth;
+ page_entry *p;
+
+ depth = --(zone->context_depth);
+ omask = (unsigned long)1 << (depth + 1);
+
+ if (!((zone->context_depth_allocations | zone->context_depth_collections) & omask))
+ return;
+
+ zone->context_depth_allocations |= (zone->context_depth_allocations & omask) >> 1;
+ zone->context_depth_allocations &= omask - 1;
+ zone->context_depth_collections &= omask - 1;
+
+ /* Any remaining pages in the popped context are lowered to the new
+ current context; i.e. objects allocated in the popped context and
+ left over are imported into the previous context. */
+ for (p = zone->pages; p != NULL; p = p->next)
+ if (p->context_depth > depth)
+ p->context_depth = depth;
+}
+
+/* Pop all the zone contexts. */
+
+void
+ggc_pop_context (void)
+{
+ struct alloc_zone *zone;
+ for (zone = G.zones; zone; zone = zone->next_zone)
+ ggc_pop_context_1 (zone);
+}
+/* Poison the chunk. */
+#ifdef ENABLE_GC_CHECKING
+#define poison_chunk(CHUNK, SIZE) \
+ memset ((CHUNK)->u.data, 0xa5, (SIZE))
+#else
+#define poison_chunk(CHUNK, SIZE)
+#endif
+
+/* Free all empty pages and objects within a page for a given zone */
+
+static void
+sweep_pages (struct alloc_zone *zone)
+{
+ page_entry **pp, *p, *next;
+ struct alloc_chunk *chunk, *last_free, *end;
+ size_t last_free_size, allocated = 0;
+ bool nomarksinpage;
+ /* First, reset the free_chunks lists, since we are going to
+ re-free free chunks in hopes of coalescing them into large chunks. */
+ memset (zone->free_chunks, 0, sizeof (zone->free_chunks));
+ pp = &zone->pages;
+ for (p = zone->pages; p ; p = next)
+ {
+ next = p->next;
+ /* Large pages are all or none affairs. Either they are
+ completely empty, or they are completely full.
+
+ XXX: Should we bother to increment allocated. */
+ if (p->large_p)
+ {
+ if (((struct alloc_chunk *)p->page)->mark == 1)
+ {
+ ((struct alloc_chunk *)p->page)->mark = 0;
+ }
+ else
+ {
+ *pp = next;
+#ifdef ENABLE_GC_CHECKING
+ /* Poison the page. */
+ memset (p->page, 0xb5, p->bytes);
+#endif
+ free_page (p);
+ }
+ continue;
+ }
+
+ /* This page has now survived another collection. */
+ p->survived++;
+
+ /* Which leaves full and partial pages. Step through all chunks,
+ consolidate those that are free and insert them into the free
+ lists. Note that consolidation slows down collection
+ slightly. */
+
+ chunk = (struct alloc_chunk *)p->page;
+ end = (struct alloc_chunk *)(p->page + G.pagesize);
+ last_free = NULL;
+ last_free_size = 0;
+ nomarksinpage = true;
+ do
+ {
+ prefetch ((struct alloc_chunk *)(chunk->u.data + chunk->size));
+ if (chunk->mark || p->context_depth < zone->context_depth)
+ {
+ nomarksinpage = false;
+ if (last_free)
+ {
+ last_free->type = 0;
+ last_free->size = last_free_size;
+ last_free->mark = 0;
+ poison_chunk (last_free, last_free_size);
+ free_chunk (last_free, last_free_size, zone);
+ last_free = NULL;
+ }
+ if (chunk->mark)
+ {
+ allocated += chunk->size + CHUNK_OVERHEAD;
+ }
+ chunk->mark = 0;
+ }
+ else
+ {
+ if (last_free)
+ {
+ last_free_size += CHUNK_OVERHEAD + chunk->size;
+ }
+ else
+ {
+ last_free = chunk;
+ last_free_size = chunk->size;
+ }
+ }
+
+ chunk = (struct alloc_chunk *)(chunk->u.data + chunk->size);
+ }
+ while (chunk < end);
+
+ if (nomarksinpage)
+ {
+ *pp = next;
+#ifdef ENABLE_GC_CHECKING
+ /* Poison the page. */
+ memset (p->page, 0xb5, p->bytes);
+#endif
+ free_page (p);
+ continue;
+ }
+ else if (last_free)
+ {
+ last_free->type = 0;
+ last_free->size = last_free_size;
+ last_free->mark = 0;
+ poison_chunk (last_free, last_free_size);
+ free_chunk (last_free, last_free_size, zone);
+ }
+ pp = &p->next;
+ }
+
+ zone->allocated = allocated;
+}
+
+/* mark-and-sweep routine for collecting a single zone. NEED_MARKING
+ is true if we need to mark before sweeping, false if some other
+ zone collection has already performed marking for us. Returns true
+ if we collected, false otherwise. */
+
+static bool
+ggc_collect_1 (struct alloc_zone *zone, bool need_marking)
+{
+ if (!zone->dead)
+ {
+ /* Avoid frequent unnecessary work by skipping collection if the
+ total allocations haven't expanded much since the last
+ collection. */
+ float allocated_last_gc =
+ MAX (zone->allocated_last_gc,
+ (size_t) PARAM_VALUE (GGC_MIN_HEAPSIZE) * 1024);
+
+ float min_expand = allocated_last_gc * PARAM_VALUE (GGC_MIN_EXPAND) / 100;
+
+ if (zone->allocated < allocated_last_gc + min_expand)
+ return false;
+ }
+
+ if (!quiet_flag)
+ fprintf (stderr, " {%s GC %luk -> ",
+ zone->name, (unsigned long) zone->allocated / 1024);
+
+ /* Zero the total allocated bytes. This will be recalculated in the
+ sweep phase. */
+ zone->allocated = 0;
+
+ /* Release the pages we freed the last time we collected, but didn't
+ reuse in the interim. */
+ release_pages (zone);
+
+ /* Indicate that we've seen collections at this context depth. */
+ zone->context_depth_collections
+ = ((unsigned long)1 << (zone->context_depth + 1)) - 1;
+ if (need_marking)
+ ggc_mark_roots ();
+ sweep_pages (zone);
+ zone->was_collected = true;
+ zone->allocated_last_gc = zone->allocated;
+
+ if (!quiet_flag)
+ fprintf (stderr, "%luk}", (unsigned long) zone->allocated / 1024);
+ return true;
+}
+
+/* Calculate the average page survival rate in terms of number of
+ collections. */
+
+static float
+calculate_average_page_survival (struct alloc_zone *zone)
+{
+ float count = 0.0;
+ float survival = 0.0;
+ page_entry *p;
+ for (p = zone->pages; p; p = p->next)
+ {
+ count += 1.0;
+ survival += p->survived;
+ }
+ return survival/count;
+}
+
+/* Check the magic cookies all of the chunks contain, to make sure we
+ aren't doing anything stupid, like stomping on alloc_chunk
+ structures. */
+
+static inline void
+check_cookies (void)
+{
+#ifdef COOKIE_CHECKING
+ page_entry *p;
+ struct alloc_zone *zone;
+
+ for (zone = G.zones; zone; zone = zone->next_zone)
+ {
+ for (p = zone->pages; p; p = p->next)
+ {
+ if (!p->large_p)
+ {
+ struct alloc_chunk *chunk = (struct alloc_chunk *)p->page;
+ struct alloc_chunk *end = (struct alloc_chunk *)(p->page + G.pagesize);
+ do
+ {
+ if (chunk->magic != CHUNK_MAGIC && chunk->magic != DEADCHUNK_MAGIC)
+ abort ();
+ chunk = (struct alloc_chunk *)(chunk->u.data + chunk->size);
+ }
+ while (chunk < end);
+ }
+ }
+ }
+#endif
+}
+/* Top level collection routine. */
+
+void
+ggc_collect (void)
+{
+ struct alloc_zone *zone;
+ bool marked = false;
+ float f;
+
+ timevar_push (TV_GC);
+ check_cookies ();
+ /* Start by possibly collecting the main zone. */
+ main_zone.was_collected = false;
+ marked |= ggc_collect_1 (&main_zone, true);
+
+ /* In order to keep the number of collections down, we don't
+ collect other zones unless we are collecting the main zone. This
+ gives us roughly the same number of collections as we used to
+ have with the old gc. The number of collection is important
+ because our main slowdown (according to profiling) is now in
+ marking. So if we mark twice as often as we used to, we'll be
+ twice as slow. Hopefully we'll avoid this cost when we mark
+ zone-at-a-time. */
+
+ if (main_zone.was_collected)
+ {
+ struct alloc_zone *zone;
+
+ for (zone = main_zone.next_zone; zone; zone = zone->next_zone)
+ {
+ check_cookies ();
+ zone->was_collected = false;
+ marked |= ggc_collect_1 (zone, !marked);
+ }
+ }
+
+ /* Print page survival stats, if someone wants them. */
+ if (GGC_DEBUG_LEVEL >= 2)
+ {
+ for (zone = G.zones; zone; zone = zone->next_zone)
+ {
+ if (zone->was_collected)
+ {
+ f = calculate_average_page_survival (zone);
+ printf ("Average page survival in zone `%s' is %f\n",
+ zone->name, f);
+ }
+ }
+ }
+
+ /* Since we don't mark zone at a time right now, marking in any
+ zone means marking in every zone. So we have to clear all the
+ marks in all the zones that weren't collected already. */
+ if (marked)
+ {
+ page_entry *p;
+ for (zone = G.zones; zone; zone = zone->next_zone)
+ {
+ if (zone->was_collected)
+ continue;
+ for (p = zone->pages; p; p = p->next)
+ {
+ if (!p->large_p)
+ {
+ struct alloc_chunk *chunk = (struct alloc_chunk *)p->page;
+ struct alloc_chunk *end = (struct alloc_chunk *)(p->page + G.pagesize);
+ do
+ {
+ prefetch ((struct alloc_chunk *)(chunk->u.data + chunk->size));
+ if (chunk->mark || p->context_depth < zone->context_depth)
+ {
+ chunk->mark = 0;
+ }
+ chunk = (struct alloc_chunk *)(chunk->u.data + chunk->size);
+ }
+ while (chunk < end);
+ }
+ else
+ {
+ ((struct alloc_chunk *)p->page)->mark = 0;
+ }
+ }
+ }
+ }
+
+ /* Free dead zones. */
+ for (zone = G.zones; zone && zone->next_zone; zone = zone->next_zone)
+ {
+ if (zone->next_zone->dead)
+ {
+ struct alloc_zone *dead_zone = zone->next_zone;
+
+ printf ("Zone `%s' is dead and will be freed.\n", dead_zone->name);
+
+ /* The zone must be empty. */
+ if (dead_zone->allocated != 0)
+ abort ();
+
+ /* Unchain the dead zone, release all its pages and free it. */
+ zone->next_zone = zone->next_zone->next_zone;
+ release_pages (dead_zone);
+ free (dead_zone);
+ }
+ }
+
+ timevar_pop (TV_GC);
+}
+
+/* Print allocation statistics. */
+
+void
+ggc_print_statistics (void)
+{
+}
+
+struct ggc_pch_data
+{
+ struct ggc_pch_ondisk
+ {
+ unsigned total;
+ } d;
+ size_t base;
+ size_t written;
+};
+
+/* Initialize the PCH datastructure. */
+
+struct ggc_pch_data *
+init_ggc_pch (void)
+{
+ return xcalloc (sizeof (struct ggc_pch_data), 1);
+}
+
+/* Add the size of object X to the size of the PCH data. */
+
+void
+ggc_pch_count_object (struct ggc_pch_data *d, void *x ATTRIBUTE_UNUSED,
+ size_t size, bool is_string)
+{
+ if (!is_string)
+ {
+ d->d.total += size + CHUNK_OVERHEAD;
+ }
+ else
+ d->d.total += size;
+}
+
+/* Return the total size of the PCH data. */
+
+size_t
+ggc_pch_total_size (struct ggc_pch_data *d)
+{
+ return d->d.total;
+}
+
+/* Set the base address for the objects in the PCH file. */
+
+void
+ggc_pch_this_base (struct ggc_pch_data *d, void *base)
+{
+ d->base = (size_t) base;
+}
+
+/* Allocate a place for object X of size SIZE in the PCH file. */
+
+char *
+ggc_pch_alloc_object (struct ggc_pch_data *d, void *x,
+ size_t size, bool is_string)
+{
+ char *result;
+ result = (char *)d->base;
+ if (!is_string)
+ {
+ struct alloc_chunk *chunk = (struct alloc_chunk *) ((char *)x - CHUNK_OVERHEAD);
+ if (chunk->large)
+ d->base += ggc_get_size (x) + CHUNK_OVERHEAD;
+ else
+ d->base += chunk->size + CHUNK_OVERHEAD;
+ return result + CHUNK_OVERHEAD;
+ }
+ else
+ {
+ d->base += size;
+ return result;
+ }
+
+}
+
+/* Prepare to write out the PCH data to file F. */
+
+void
+ggc_pch_prepare_write (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
+ FILE *f ATTRIBUTE_UNUSED)
+{
+ /* Nothing to do. */
+}
+
+/* Write out object X of SIZE to file F. */
+
+void
+ggc_pch_write_object (struct ggc_pch_data *d ATTRIBUTE_UNUSED,
+ FILE *f, void *x, void *newx ATTRIBUTE_UNUSED,
+ size_t size, bool is_string)
+{
+ if (!is_string)
+ {
+ struct alloc_chunk *chunk = (struct alloc_chunk *) ((char *)x - CHUNK_OVERHEAD);
+ size = ggc_get_size (x);
+ if (fwrite (chunk, size + CHUNK_OVERHEAD, 1, f) != 1)
+ fatal_error ("can't write PCH file: %m");
+ d->written += size + CHUNK_OVERHEAD;
+ }
+ else
+ {
+ if (fwrite (x, size, 1, f) != 1)
+ fatal_error ("can't write PCH file: %m");
+ d->written += size;
+ }
+ if (d->written == d->d.total
+ && fseek (f, ROUND_UP_VALUE (d->d.total, G.pagesize), SEEK_CUR) != 0)
+ fatal_error ("can't write PCH file: %m");
+}
+
+void
+ggc_pch_finish (struct ggc_pch_data *d, FILE *f)
+{
+ if (fwrite (&d->d, sizeof (d->d), 1, f) != 1)
+ fatal_error ("can't write PCH file: %m");
+ free (d);
+}
+void
+ggc_pch_read (FILE *f, void *addr)
+{
+ struct ggc_pch_ondisk d;
+ struct page_entry *entry;
+ struct alloc_zone *pch_zone;
+ if (fread (&d, sizeof (d), 1, f) != 1)
+ fatal_error ("can't read PCH file: %m");
+ entry = xcalloc (1, sizeof (struct page_entry));
+ entry->bytes = d.total;
+ entry->page = addr;
+ entry->context_depth = 0;
+ pch_zone = new_ggc_zone ("PCH zone");
+ entry->zone = pch_zone;
+ entry->next = entry->zone->pages;
+ entry->zone->pages = entry;
+}
diff --git a/contrib/gcc/ggc.h b/contrib/gcc/ggc.h
index 69f2f6277177..8add2da33baa 100644
--- a/contrib/gcc/ggc.h
+++ b/contrib/gcc/ggc.h
@@ -1,5 +1,6 @@
/* Garbage collection for the GNU compiler.
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -18,8 +19,8 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "varray.h"
-#include "gtype-desc.h"
+#ifndef GCC_GGC_H
+#define GCC_GGC_H
/* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with
an external gc library that might be linked in. */
@@ -29,23 +30,53 @@ extern const char empty_string[]; /* empty string */
extern const char digit_vector[]; /* "0" .. "9" */
#define digit_string(d) (digit_vector + ((d) * 2))
-/* Manipulate global roots that are needed between calls to gc.
- THIS ROUTINE IS OBSOLETE, do not use it for new code. */
-extern void ggc_add_root PARAMS ((void *base, int nelt,
- int size, void (*)(void *)));
+/* Internal functions and data structures used by the GTY
+ machinery. */
+
+/* The first parameter is a pointer to a pointer, the second a cookie. */
+typedef void (*gt_pointer_operator) (void *, void *);
+
+#include "gtype-desc.h"
+
+/* One of these applies its third parameter (with cookie in the fourth
+ parameter) to each pointer in the object pointed to by the first
+ parameter, using the second parameter. */
+typedef void (*gt_note_pointers) (void *, void *, gt_pointer_operator,
+ void *);
+
+/* One of these is called before objects are re-ordered in memory.
+ The first parameter is the original object, the second is the
+ subobject that has had its pointers reordered, the third parameter
+ can compute the new values of a pointer when given the cookie in
+ the fourth parameter. */
+typedef void (*gt_handle_reorder) (void *, void *, gt_pointer_operator,
+ void *);
+
+/* Used by the gt_pch_n_* routines. Register an object in the hash table. */
+extern int gt_pch_note_object (void *, void *, gt_note_pointers);
+
+/* Used by the gt_pch_n_* routines. Register that an object has a reorder
+ function. */
+extern void gt_pch_note_reorder (void *, void *, gt_handle_reorder);
+
+/* Mark the object in the first parameter and anything it points to. */
+typedef void (*gt_pointer_walker) (void *);
/* Structures for the easy way to mark roots.
- In an array, terminated by having base == NULL.*/
+ In an array, terminated by having base == NULL. */
struct ggc_root_tab {
void *base;
size_t nelt;
size_t stride;
- void (*cb) PARAMS ((void *));
+ gt_pointer_walker cb;
+ gt_pointer_walker pchw;
};
-#define LAST_GGC_ROOT_TAB { NULL, 0, 0, NULL }
+#define LAST_GGC_ROOT_TAB { NULL, 0, 0, NULL, NULL }
/* Pointers to arrays of ggc_root_tab, terminated by NULL. */
extern const struct ggc_root_tab * const gt_ggc_rtab[];
extern const struct ggc_root_tab * const gt_ggc_deletable_rtab[];
+extern const struct ggc_root_tab * const gt_pch_cache_rtab[];
+extern const struct ggc_root_tab * const gt_pch_scalar_rtab[];
/* Structure for hash table cache marking. */
struct htab;
@@ -53,23 +84,19 @@ struct ggc_cache_tab {
struct htab * *base;
size_t nelt;
size_t stride;
- void (*cb) PARAMS ((void *));
- int (*marked_p) PARAMS ((const void *));
+ gt_pointer_walker cb;
+ gt_pointer_walker pchw;
+ int (*marked_p) (const void *);
};
-#define LAST_GGC_CACHE_TAB { NULL, 0, 0, NULL, NULL }
+#define LAST_GGC_CACHE_TAB { NULL, 0, 0, NULL, NULL, NULL }
/* Pointers to arrays of ggc_cache_tab, terminated by NULL. */
extern const struct ggc_cache_tab * const gt_ggc_cache_rtab[];
-extern void ggc_mark_roots PARAMS ((void));
-
/* If EXPR is not NULL and previously unmarked, mark it and evaluate
to true. Otherwise evaluate to false. */
#define ggc_test_and_set_mark(EXPR) \
((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1 && ! ggc_set_mark (EXPR))
-#define ggc_mark_rtx gt_ggc_m_7rtx_def
-#define ggc_mark_tree gt_ggc_m_9tree_node
-
#define ggc_mark(EXPR) \
do { \
const void *const a__ = (EXPR); \
@@ -77,107 +104,187 @@ extern void ggc_mark_roots PARAMS ((void));
ggc_set_mark (a__); \
} while (0)
-/* A GC implementation must provide these functions. */
+/* Actually set the mark on a particular region of memory, but don't
+ follow pointers. This function is called by ggc_mark_*. It
+ returns zero if the object was not previously marked; nonzero if
+ the object was already marked, or if, for any other reason,
+ pointers in this data structure should not be traversed. */
+extern int ggc_set_mark (const void *);
+
+/* Return 1 if P has been marked, zero otherwise.
+ P must have been allocated by the GC allocator; it mustn't point to
+ static objects, stack variables, or memory allocated with malloc. */
+extern int ggc_marked_p (const void *);
+
+/* Mark the entries in the string pool. */
+extern void ggc_mark_stringpool (void);
+
+/* Call ggc_set_mark on all the roots. */
+
+extern void ggc_mark_roots (void);
+
+/* Save and restore the string pool entries for PCH. */
+
+extern void gt_pch_save_stringpool (void);
+extern void gt_pch_fixup_stringpool (void);
+extern void gt_pch_restore_stringpool (void);
+
+/* PCH and GGC handling for strings, mostly trivial. */
+
+extern void gt_pch_p_S (void *, void *, gt_pointer_operator, void *);
+extern void gt_pch_n_S (const void *);
+extern void gt_ggc_m_S (void *);
+
+/* Initialize the string pool. */
+extern void init_stringpool (void);
+
+/* A GC implementation must provide these functions. They are internal
+ to the GC system. */
+
+/* Forward declare the zone structure. Only ggc_zone implements this. */
+struct alloc_zone;
/* Initialize the garbage collector. */
-extern void init_ggc PARAMS ((void));
-extern void init_stringpool PARAMS ((void));
+extern void init_ggc (void);
+
+/* Start a new GGC zone. */
+extern struct alloc_zone *new_ggc_zone (const char *);
+
+/* Free a complete GGC zone, destroying everything in it. */
+extern void destroy_ggc_zone (struct alloc_zone *);
/* Start a new GGC context. Memory allocated in previous contexts
will not be collected while the new context is active. */
-extern void ggc_push_context PARAMS ((void));
+extern void ggc_push_context (void);
/* Finish a GC context. Any uncollected memory in the new context
will be merged with the old context. */
-extern void ggc_pop_context PARAMS ((void));
-
+extern void ggc_pop_context (void);
+
+struct ggc_pch_data;
+
+/* Return a new ggc_pch_data structure. */
+extern struct ggc_pch_data *init_ggc_pch (void);
+
+/* The second parameter and third parameters give the address and size
+ of an object. Update the ggc_pch_data structure with as much of
+ that information as is necessary. The last argument should be true
+ if the object is a string. */
+extern void ggc_pch_count_object (struct ggc_pch_data *, void *, size_t, bool);
+
+/* Return the total size of the data to be written to hold all
+ the objects previously passed to ggc_pch_count_object. */
+extern size_t ggc_pch_total_size (struct ggc_pch_data *);
+
+/* The objects, when read, will most likely be at the address
+ in the second parameter. */
+extern void ggc_pch_this_base (struct ggc_pch_data *, void *);
+
+/* Assuming that the objects really do end up at the address
+ passed to ggc_pch_this_base, return the address of this object.
+ The last argument should be true if the object is a string. */
+extern char *ggc_pch_alloc_object (struct ggc_pch_data *, void *, size_t, bool);
+
+/* Write out any initial information required. */
+extern void ggc_pch_prepare_write (struct ggc_pch_data *, FILE *);
+/* Write out this object, including any padding. The last argument should be
+ true if the object is a string. */
+extern void ggc_pch_write_object (struct ggc_pch_data *, FILE *, void *,
+ void *, size_t, bool);
+/* All objects have been written, write out any final information
+ required. */
+extern void ggc_pch_finish (struct ggc_pch_data *, FILE *);
+
+/* A PCH file has just been read in at the address specified second
+ parameter. Set up the GC implementation for the new objects. */
+extern void ggc_pch_read (FILE *, void *);
+
+
/* Allocation. */
+/* For single pass garbage. */
+extern struct alloc_zone *garbage_zone;
+/* For regular rtl allocations. */
+extern struct alloc_zone *rtl_zone;
+/* For regular tree allocations. */
+extern struct alloc_zone *tree_zone;
+
/* The internal primitive. */
-extern void *ggc_alloc PARAMS ((size_t));
+extern void *ggc_alloc (size_t);
+/* Allocate an object into the specified allocation zone. */
+extern void *ggc_alloc_zone (size_t, struct alloc_zone *);
+/* Allocate an object of the specified type and size. */
+extern void *ggc_alloc_typed (enum gt_types_enum, size_t);
/* Like ggc_alloc, but allocates cleared memory. */
-extern void *ggc_alloc_cleared PARAMS ((size_t));
+extern void *ggc_alloc_cleared (size_t);
+/* Like ggc_alloc_zone, but allocates cleared memory. */
+extern void *ggc_alloc_cleared_zone (size_t, struct alloc_zone *);
/* Resize a block. */
-extern void *ggc_realloc PARAMS ((void *, size_t));
+extern void *ggc_realloc (void *, size_t);
/* Like ggc_alloc_cleared, but performs a multiplication. */
-extern void *ggc_calloc PARAMS ((size_t, size_t));
+extern void *ggc_calloc (size_t, size_t);
-#define ggc_alloc_rtx(NSLOTS) \
- ((struct rtx_def *) ggc_alloc (sizeof (struct rtx_def) \
- + ((NSLOTS) - 1) * sizeof (rtunion)))
+#define ggc_alloc_rtx(CODE) \
+ ((rtx) ggc_alloc_typed (gt_ggc_e_7rtx_def, RTX_SIZE (CODE)))
#define ggc_alloc_rtvec(NELT) \
- ((struct rtvec_def *) ggc_alloc (sizeof (struct rtvec_def) \
- + ((NELT) - 1) * sizeof (rtx)))
+ ((rtvec) ggc_alloc_typed (gt_ggc_e_9rtvec_def, sizeof (struct rtvec_def) \
+ + ((NELT) - 1) * sizeof (rtx)))
-#define ggc_alloc_tree(LENGTH) ((union tree_node *) ggc_alloc (LENGTH))
+#define ggc_alloc_tree(LENGTH) ((tree) ggc_alloc_zone (LENGTH, tree_zone))
#define htab_create_ggc(SIZE, HASH, EQ, DEL) \
htab_create_alloc (SIZE, HASH, EQ, DEL, ggc_calloc, NULL)
+#define splay_tree_new_ggc(COMPARE) \
+ splay_tree_new_with_allocator (COMPARE, NULL, NULL, \
+ &ggc_splay_alloc, &ggc_splay_dont_free, \
+ NULL)
+extern void *ggc_splay_alloc (int, void *);
+extern void ggc_splay_dont_free (void *, void *);
+
/* Allocate a gc-able string, and fill it with LENGTH bytes from CONTENTS.
If LENGTH is -1, then CONTENTS is assumed to be a
null-terminated string and the memory sized accordingly. */
-extern const char *ggc_alloc_string PARAMS ((const char *contents,
- int length));
+extern const char *ggc_alloc_string (const char *contents, int length);
/* Make a copy of S, in GC-able memory. */
#define ggc_strdup(S) ggc_alloc_string((S), -1)
/* Invoke the collector. Garbage collection occurs only when this
function is called, not during allocations. */
-extern void ggc_collect PARAMS ((void));
+extern void ggc_collect (void);
-/* Actually set the mark on a particular region of memory, but don't
- follow pointers. This function is called by ggc_mark_*. It
- returns zero if the object was not previously marked; nonzero if
- the object was already marked, or if, for any other reason,
- pointers in this data structure should not be traversed. */
-extern int ggc_set_mark PARAMS ((const void *));
+/* Return the number of bytes allocated at the indicated address. */
+extern size_t ggc_get_size (const void *);
-/* Return 1 if P has been marked, zero otherwise.
- P must have been allocated by the GC allocator; it mustn't point to
- static objects, stack variables, or memory allocated with malloc. */
-extern int ggc_marked_p PARAMS ((const void *));
+/* Write out all GCed objects to F. */
+extern void gt_pch_save (FILE *f);
+/* Read objects previously saved with gt_pch_save from F. */
+extern void gt_pch_restore (FILE *f);
+
/* Statistics. */
/* This structure contains the statistics common to all collectors.
Particular collectors can extend this structure. */
typedef struct ggc_statistics
{
- /* The Ith element is the number of nodes allocated with code I. */
- unsigned num_trees[256];
- /* The Ith element is the number of bytes allocated by nodes with
- code I. */
- size_t size_trees[256];
- /* The Ith element is the number of nodes allocated with code I. */
- unsigned num_rtxs[256];
- /* The Ith element is the number of bytes allocated by nodes with
- code I. */
- size_t size_rtxs[256];
- /* The total size of the tree nodes allocated. */
- size_t total_size_trees;
- /* The total size of the RTL nodes allocated. */
- size_t total_size_rtxs;
- /* The total number of tree nodes allocated. */
- unsigned total_num_trees;
- /* The total number of RTL nodes allocated. */
- unsigned total_num_rtxs;
+ /* At present, we don't really gather any interesting statistics. */
+ int unused;
} ggc_statistics;
-/* Return the number of bytes allocated at the indicated address. */
-extern size_t ggc_get_size PARAMS ((const void *));
-
/* Used by the various collectors to gather and print statistics that
do not depend on the collector in use. */
-extern void ggc_print_common_statistics PARAMS ((FILE *, ggc_statistics *));
+extern void ggc_print_common_statistics (FILE *, ggc_statistics *);
/* Print allocation statistics. */
-extern void ggc_print_statistics PARAMS ((void));
-extern void stringpool_statistics PARAMS ((void));
+extern void ggc_print_statistics (void);
+extern void stringpool_statistics (void);
/* Heuristics. */
-extern int ggc_min_expand_heuristic PARAMS ((void));
-extern int ggc_min_heapsize_heuristic PARAMS ((void));
-extern void init_ggc_heuristics PARAMS ((void));
+extern int ggc_min_expand_heuristic (void);
+extern int ggc_min_heapsize_heuristic (void);
+extern void init_ggc_heuristics (void);
+
+#endif
diff --git a/contrib/gcc/ginclude/float.h b/contrib/gcc/ginclude/float.h
index f501a8abe93b..75fcd5422d91 100644
--- a/contrib/gcc/ginclude/float.h
+++ b/contrib/gcc/ginclude/float.h
@@ -1,19 +1,19 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/ginclude/iso646.h b/contrib/gcc/ginclude/iso646.h
index 79f4fd7c7f97..f09672a97874 100644
--- a/contrib/gcc/ginclude/iso646.h
+++ b/contrib/gcc/ginclude/iso646.h
@@ -1,19 +1,19 @@
/* Copyright (C) 1997, 1999 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/ginclude/stdarg.h b/contrib/gcc/ginclude/stdarg.h
index e451c31c53f2..f178505e892e 100644
--- a/contrib/gcc/ginclude/stdarg.h
+++ b/contrib/gcc/ginclude/stdarg.h
@@ -1,19 +1,19 @@
/* Copyright (C) 1989, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/ginclude/stdbool.h b/contrib/gcc/ginclude/stdbool.h
index 33f7d3d4110b..93003e2b3468 100644
--- a/contrib/gcc/ginclude/stdbool.h
+++ b/contrib/gcc/ginclude/stdbool.h
@@ -1,19 +1,19 @@
/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
diff --git a/contrib/gcc/ginclude/stddef.h b/contrib/gcc/ginclude/stddef.h
index 2cd15899af10..1bb3e90bc9b1 100644
--- a/contrib/gcc/ginclude/stddef.h
+++ b/contrib/gcc/ginclude/stddef.h
@@ -1,19 +1,19 @@
/* Copyright (C) 1989, 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -409,10 +409,17 @@ typedef __WINT_TYPE__ wint_t;
#ifdef _STDDEF_H
-/* Offset of member MEMBER in a struct of type TYPE. */
-
+/* Offset of member MEMBER in a struct of type TYPE. */
+#ifndef __cplusplus
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-
+#else
+/* The cast to "char &" below avoids problems with user-defined
+ "operator &", which can appear in a POD type. */
+#define offsetof(TYPE, MEMBER) \
+ (__offsetof__ (reinterpret_cast <size_t> \
+ (&reinterpret_cast <char &> \
+ (static_cast<TYPE *> (0)->MEMBER))))
+#endif /* C++ */
#endif /* _STDDEF_H was defined this time */
#endif /* !_STDDEF_H && !_STDDEF_H_ && !_ANSI_STDDEF_H && !__STDDEF_H__
diff --git a/contrib/gcc/global.c b/contrib/gcc/global.c
index 0840b87b191a..de765b36731e 100644
--- a/contrib/gcc/global.c
+++ b/contrib/gcc/global.c
@@ -1,6 +1,6 @@
/* Allocate registers for pseudo-registers that span basic blocks.
Copyright (C) 1987, 1988, 1991, 1994, 1996, 1997, 1998,
- 1999, 2000, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "machmode.h"
#include "hard-reg-set.h"
@@ -287,24 +289,23 @@ static int n_regs_set;
static HARD_REG_SET eliminable_regset;
-static int allocno_compare PARAMS ((const PTR, const PTR));
-static void global_conflicts PARAMS ((void));
-static void mirror_conflicts PARAMS ((void));
-static void expand_preferences PARAMS ((void));
-static void prune_preferences PARAMS ((void));
-static void find_reg PARAMS ((int, HARD_REG_SET, int, int, int));
-static void record_one_conflict PARAMS ((int));
-static void record_conflicts PARAMS ((int *, int));
-static void mark_reg_store PARAMS ((rtx, rtx, void *));
-static void mark_reg_clobber PARAMS ((rtx, rtx, void *));
-static void mark_reg_conflicts PARAMS ((rtx));
-static void mark_reg_death PARAMS ((rtx));
-static void mark_reg_live_nc PARAMS ((int, enum machine_mode));
-static void set_preference PARAMS ((rtx, rtx));
-static void dump_conflicts PARAMS ((FILE *));
-static void reg_becomes_live PARAMS ((rtx, rtx, void *));
-static void reg_dies PARAMS ((int, enum machine_mode,
- struct insn_chain *));
+static int allocno_compare (const void *, const void *);
+static void global_conflicts (void);
+static void mirror_conflicts (void);
+static void expand_preferences (void);
+static void prune_preferences (void);
+static void find_reg (int, HARD_REG_SET, int, int, int);
+static void record_one_conflict (int);
+static void record_conflicts (int *, int);
+static void mark_reg_store (rtx, rtx, void *);
+static void mark_reg_clobber (rtx, rtx, void *);
+static void mark_reg_conflicts (rtx);
+static void mark_reg_death (rtx);
+static void mark_reg_live_nc (int, enum machine_mode);
+static void set_preference (rtx, rtx);
+static void dump_conflicts (FILE *);
+static void reg_becomes_live (rtx, rtx, void *);
+static void reg_dies (int, enum machine_mode, struct insn_chain *);
/* Perform allocation of pseudo-registers not allocated by local_alloc.
FILE is a file to output debugging information on,
@@ -314,8 +315,7 @@ static void reg_dies PARAMS ((int, enum machine_mode,
and we must not do any more for this function. */
int
-global_alloc (file)
- FILE *file;
+global_alloc (FILE *file)
{
int retval;
#ifdef ELIMINABLE_REGS
@@ -323,9 +323,7 @@ global_alloc (file)
#endif
int need_fp
= (! flag_omit_frame_pointer
-#ifdef EXIT_IGNORE_STACK
|| (current_function_calls_alloca && EXIT_IGNORE_STACK)
-#endif
|| FRAME_POINTER_REQUIRED);
size_t i;
@@ -343,22 +341,48 @@ global_alloc (file)
#ifdef ELIMINABLE_REGS
for (i = 0; i < ARRAY_SIZE (eliminables); i++)
{
- SET_HARD_REG_BIT (eliminable_regset, eliminables[i].from);
+ bool cannot_elim
+ = (! CAN_ELIMINATE (eliminables[i].from, eliminables[i].to)
+ || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp));
+
+ if (!regs_asm_clobbered[eliminables[i].from])
+ {
+ SET_HARD_REG_BIT (eliminable_regset, eliminables[i].from);
- if (! CAN_ELIMINATE (eliminables[i].from, eliminables[i].to)
- || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp))
- SET_HARD_REG_BIT (no_global_alloc_regs, eliminables[i].from);
+ if (cannot_elim)
+ SET_HARD_REG_BIT (no_global_alloc_regs, eliminables[i].from);
+ }
+ else if (cannot_elim)
+ error ("%s cannot be used in asm here",
+ reg_names[eliminables[i].from]);
+ else
+ regs_ever_live[eliminables[i].from] = 1;
}
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
- SET_HARD_REG_BIT (eliminable_regset, HARD_FRAME_POINTER_REGNUM);
- if (need_fp)
- SET_HARD_REG_BIT (no_global_alloc_regs, HARD_FRAME_POINTER_REGNUM);
+ if (!regs_asm_clobbered[HARD_FRAME_POINTER_REGNUM])
+ {
+ SET_HARD_REG_BIT (eliminable_regset, HARD_FRAME_POINTER_REGNUM);
+ if (need_fp)
+ SET_HARD_REG_BIT (no_global_alloc_regs, HARD_FRAME_POINTER_REGNUM);
+ }
+ else if (need_fp)
+ error ("%s cannot be used in asm here",
+ reg_names[HARD_FRAME_POINTER_REGNUM]);
+ else
+ regs_ever_live[HARD_FRAME_POINTER_REGNUM] = 1;
#endif
#else
- SET_HARD_REG_BIT (eliminable_regset, FRAME_POINTER_REGNUM);
- if (need_fp)
- SET_HARD_REG_BIT (no_global_alloc_regs, FRAME_POINTER_REGNUM);
+ if (!regs_asm_clobbered[FRAME_POINTER_REGNUM])
+ {
+ SET_HARD_REG_BIT (eliminable_regset, FRAME_POINTER_REGNUM);
+ if (need_fp)
+ SET_HARD_REG_BIT (no_global_alloc_regs, FRAME_POINTER_REGNUM);
+ }
+ else if (need_fp)
+ error ("%s cannot be used in asm here", reg_names[FRAME_POINTER_REGNUM]);
+ else
+ regs_ever_live[FRAME_POINTER_REGNUM] = 1;
#endif
/* Track which registers have already been used. Start with registers
@@ -398,14 +422,14 @@ global_alloc (file)
/* Establish mappings from register number to allocation number
and vice versa. In the process, count the allocnos. */
- reg_allocno = (int *) xmalloc (max_regno * sizeof (int));
+ reg_allocno = xmalloc (max_regno * sizeof (int));
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
reg_allocno[i] = -1;
/* Initialize the shared-hard-reg mapping
from the list of pairs that may share. */
- reg_may_share = (int *) xcalloc (max_regno, sizeof (int));
+ reg_may_share = xcalloc (max_regno, sizeof (int));
for (x = regs_may_share; x; x = XEXP (XEXP (x, 1), 1))
{
int r1 = REGNO (XEXP (x, 0));
@@ -436,7 +460,7 @@ global_alloc (file)
else
reg_allocno[i] = -1;
- allocno = (struct allocno *) xcalloc (max_allocno, sizeof (struct allocno));
+ allocno = xcalloc (max_allocno, sizeof (struct allocno));
for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
if (reg_allocno[i] >= 0)
@@ -454,9 +478,9 @@ global_alloc (file)
/* Calculate amount of usage of each hard reg by pseudos
allocated by local-alloc. This is to see if we want to
override it. */
- memset ((char *) local_reg_live_length, 0, sizeof local_reg_live_length);
- memset ((char *) local_reg_n_refs, 0, sizeof local_reg_n_refs);
- memset ((char *) local_reg_freq, 0, sizeof local_reg_freq);
+ memset (local_reg_live_length, 0, sizeof local_reg_live_length);
+ memset (local_reg_n_refs, 0, sizeof local_reg_n_refs);
+ memset (local_reg_freq, 0, sizeof local_reg_freq);
for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
if (reg_renumber[i] >= 0)
{
@@ -482,10 +506,9 @@ global_alloc (file)
/* We used to use alloca here, but the size of what it would try to
allocate would occasionally cause it to exceed the stack limit and
cause unpredictable core dumps. Some examples were > 2Mb in size. */
- conflicts = (INT_TYPE *) xcalloc (max_allocno * allocno_row_words,
- sizeof (INT_TYPE));
+ conflicts = xcalloc (max_allocno * allocno_row_words, sizeof (INT_TYPE));
- allocnos_live = (INT_TYPE *) xmalloc (allocno_row_words * sizeof (INT_TYPE));
+ allocnos_live = xmalloc (allocno_row_words * sizeof (INT_TYPE));
/* If there is work to be done (at least one reg to allocate),
perform global conflict analysis and allocate the regs. */
@@ -522,7 +545,7 @@ global_alloc (file)
/* Determine the order to allocate the remaining pseudo registers. */
- allocno_order = (int *) xmalloc (max_allocno * sizeof (int));
+ allocno_order = xmalloc (max_allocno * sizeof (int));
for (i = 0; i < (size_t) max_allocno; i++)
allocno_order[i] = i;
@@ -597,9 +620,7 @@ global_alloc (file)
Returns -1 (1) if *v1 should be allocated before (after) *v2. */
static int
-allocno_compare (v1p, v2p)
- const PTR v1p;
- const PTR v2p;
+allocno_compare (const void *v1p, const void *v2p)
{
int v1 = *(const int *)v1p, v2 = *(const int *)v2p;
/* Note that the quotient will never be bigger than
@@ -627,7 +648,7 @@ allocno_compare (v1p, v2p)
conflict matrices and preference tables. */
static void
-global_conflicts ()
+global_conflicts (void)
{
int i;
basic_block b;
@@ -635,13 +656,13 @@ global_conflicts ()
int *block_start_allocnos;
/* Make a vector that mark_reg_{store,clobber} will store in. */
- regs_set = (rtx *) xmalloc (max_parallel * sizeof (rtx) * 2);
+ regs_set = xmalloc (max_parallel * sizeof (rtx) * 2);
- block_start_allocnos = (int *) xmalloc (max_allocno * sizeof (int));
+ block_start_allocnos = xmalloc (max_allocno * sizeof (int));
FOR_EACH_BB (b)
{
- memset ((char *) allocnos_live, 0, allocno_row_words * sizeof (INT_TYPE));
+ memset (allocnos_live, 0, allocno_row_words * sizeof (INT_TYPE));
/* Initialize table of registers currently live
to the state at the beginning of this basic block.
@@ -693,7 +714,7 @@ global_conflicts ()
2. Y is live at some instruction on the path that
evaluates X.
- 3. Either X or Y is not evaluted on the path to P
+ 3. Either X or Y is not evaluated on the path to P
(ie it is used uninitialized) and thus the
conflict can be ignored.
@@ -701,29 +722,41 @@ global_conflicts ()
scan the instruction that makes either X or Y become live. */
record_conflicts (block_start_allocnos, ax);
-#ifdef STACK_REGS
+ /* Pseudos can't go in stack regs at the start of a basic block that
+ is reached by an abnormal edge. Likewise for call clobbered regs,
+ because because caller-save, fixup_abnormal_edges, and possibly
+ the table driven EH machinery are not quite ready to handle such
+ regs live across such edges. */
{
- /* Pseudos can't go in stack regs at the start of a basic block
- that is reached by an abnormal edge. */
-
edge e;
+
for (e = b->pred; e ; e = e->pred_next)
if (e->flags & EDGE_ABNORMAL)
break;
+
if (e != NULL)
{
+#ifdef STACK_REGS
EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, ax,
- {
- allocno[ax].no_stack_reg = 1;
- });
+ {
+ allocno[ax].no_stack_reg = 1;
+ });
for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
- record_one_conflict (ax);
+ record_one_conflict (ax);
+#endif
+
+ /* No need to record conflicts for call clobbered regs if we have
+ nonlocal labels around, as we don't ever try to allocate such
+ regs in this case. */
+ if (! current_function_has_nonlocal_label)
+ for (ax = 0; ax < FIRST_PSEUDO_REGISTER; ax++)
+ if (call_used_regs [ax])
+ record_one_conflict (ax);
}
}
-#endif
}
- insn = b->head;
+ insn = BB_HEAD (b);
/* Scan the code of this basic block, noting which allocnos
and hard regs are born or die. When one is born,
@@ -823,7 +856,7 @@ global_conflicts ()
}
}
- if (insn == b->end)
+ if (insn == BB_END (b))
break;
insn = NEXT_INSN (insn);
}
@@ -838,7 +871,7 @@ global_conflicts ()
merge any preferences between those allocnos. */
static void
-expand_preferences ()
+expand_preferences (void)
{
rtx insn;
rtx link;
@@ -889,11 +922,11 @@ expand_preferences ()
we will avoid using these registers. */
static void
-prune_preferences ()
+prune_preferences (void)
{
int i;
int num;
- int *allocno_to_order = (int *) xmalloc (max_allocno * sizeof (int));
+ int *allocno_to_order = xmalloc (max_allocno * sizeof (int));
/* Scan least most important to most important.
For each allocno, remove from preferences registers that cannot be used,
@@ -977,12 +1010,7 @@ prune_preferences ()
If not, do nothing. */
static void
-find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying)
- int num;
- HARD_REG_SET losers;
- int alt_regs_p;
- int accept_call_clobbered;
- int retrying;
+find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbered, int retrying)
{
int i, best_reg, pass;
HARD_REG_SET used, used1, used2;
@@ -1096,7 +1124,7 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying)
(j < lim
&& ! TEST_HARD_REG_BIT (used, j)
&& (REGNO_REG_CLASS (j)
- == REGNO_REG_CLASS (best_reg + (j - i))
+ == REGNO_REG_CLASS (best_reg + (j - i))
|| reg_class_subset_p (REGNO_REG_CLASS (j),
REGNO_REG_CLASS (best_reg + (j - i)))
|| reg_class_subset_p (REGNO_REG_CLASS (best_reg + (j - i)),
@@ -1135,7 +1163,7 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying)
(j < lim
&& ! TEST_HARD_REG_BIT (used, j)
&& (REGNO_REG_CLASS (j)
- == REGNO_REG_CLASS (best_reg + (j - i))
+ == REGNO_REG_CLASS (best_reg + (j - i))
|| reg_class_subset_p (REGNO_REG_CLASS (j),
REGNO_REG_CLASS (best_reg + (j - i)))
|| reg_class_subset_p (REGNO_REG_CLASS (best_reg + (j - i)),
@@ -1216,8 +1244,8 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying)
mode)
#endif
#ifdef STACK_REGS
- && (!allocno[num].no_stack_reg
- || regno < FIRST_STACK_REG || regno > LAST_STACK_REG)
+ && (!allocno[num].no_stack_reg
+ || regno < FIRST_STACK_REG || regno > LAST_STACK_REG)
#endif
)
{
@@ -1297,9 +1325,7 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying)
If FORBIDDEN_REGS is zero, no regs are forbidden. */
void
-retry_global_alloc (regno, forbidden_regs)
- int regno;
- HARD_REG_SET forbidden_regs;
+retry_global_alloc (int regno, HARD_REG_SET forbidden_regs)
{
int alloc_no = reg_allocno[regno];
if (alloc_no >= 0)
@@ -1330,8 +1356,7 @@ retry_global_alloc (regno, forbidden_regs)
reg_renumber before calling here. */
static void
-record_one_conflict (regno)
- int regno;
+record_one_conflict (int regno)
{
int j;
@@ -1374,24 +1399,16 @@ record_one_conflict (regno)
are currently live. Their bits are also flagged in allocnos_live. */
static void
-record_conflicts (allocno_vec, len)
- int *allocno_vec;
- int len;
+record_conflicts (int *allocno_vec, int len)
{
- int num;
- int ialloc_prod;
-
while (--len >= 0)
- {
- num = allocno_vec[len];
- ialloc_prod = num * allocno_row_words;
- IOR_HARD_REG_SET (allocno[num].hard_reg_conflicts, hard_regs_live);
- }
+ IOR_HARD_REG_SET (allocno[allocno_vec[len]].hard_reg_conflicts,
+ hard_regs_live);
}
/* If CONFLICTP (i, j) is true, make sure CONFLICTP (j, i) is also true. */
static void
-mirror_conflicts ()
+mirror_conflicts (void)
{
int i, j;
int rw = allocno_row_words;
@@ -1439,9 +1456,7 @@ mirror_conflicts ()
a REG_INC note was found for it). */
static void
-mark_reg_store (reg, setter, data)
- rtx reg, setter;
- void *data ATTRIBUTE_UNUSED;
+mark_reg_store (rtx reg, rtx setter, void *data ATTRIBUTE_UNUSED)
{
int regno;
@@ -1488,9 +1503,7 @@ mark_reg_store (reg, setter, data)
/* Like mark_reg_set except notice just CLOBBERs; ignore SETs. */
static void
-mark_reg_clobber (reg, setter, data)
- rtx reg, setter;
- void *data ATTRIBUTE_UNUSED;
+mark_reg_clobber (rtx reg, rtx setter, void *data ATTRIBUTE_UNUSED)
{
if (GET_CODE (setter) == CLOBBER)
mark_reg_store (reg, setter, data);
@@ -1500,8 +1513,7 @@ mark_reg_clobber (reg, setter, data)
Do not mark REG itself as live. */
static void
-mark_reg_conflicts (reg)
- rtx reg;
+mark_reg_conflicts (rtx reg)
{
int regno;
@@ -1540,8 +1552,7 @@ mark_reg_conflicts (reg)
Store a 0 in regs_live or allocnos_live for this register. */
static void
-mark_reg_death (reg)
- rtx reg;
+mark_reg_death (rtx reg)
{
int regno = REGNO (reg);
@@ -1577,9 +1588,7 @@ mark_reg_death (reg)
it is assumed that the caller will do that. */
static void
-mark_reg_live_nc (regno, mode)
- int regno;
- enum machine_mode mode;
+mark_reg_live_nc (int regno, enum machine_mode mode)
{
int last = regno + HARD_REGNO_NREGS (regno, mode);
while (regno < last)
@@ -1599,8 +1608,7 @@ mark_reg_live_nc (regno, mode)
pseudo-register to a hard register. */
static void
-set_preference (dest, src)
- rtx dest, src;
+set_preference (rtx dest, rtx src)
{
unsigned int src_regno, dest_regno;
/* Amount to add to the hard regno for SRC, or subtract from that for DEST,
@@ -1707,8 +1715,7 @@ set_preference (dest, src)
a use of TO. */
void
-mark_elimination (from, to)
- int from, to;
+mark_elimination (int from, int to)
{
basic_block bb;
@@ -1730,10 +1737,7 @@ static regset live_relevant_regs;
/* Record in live_relevant_regs and REGS_SET that register REG became live.
This is called via note_stores. */
static void
-reg_becomes_live (reg, setter, regs_set)
- rtx reg;
- rtx setter ATTRIBUTE_UNUSED;
- void *regs_set;
+reg_becomes_live (rtx reg, rtx setter ATTRIBUTE_UNUSED, void *regs_set)
{
int regno;
@@ -1764,10 +1768,7 @@ reg_becomes_live (reg, setter, regs_set)
/* Record in live_relevant_regs that register REGNO died. */
static void
-reg_dies (regno, mode, chain)
- int regno;
- enum machine_mode mode;
- struct insn_chain *chain;
+reg_dies (int regno, enum machine_mode mode, struct insn_chain *chain)
{
if (regno < FIRST_PSEUDO_REGISTER)
{
@@ -1791,8 +1792,7 @@ reg_dies (regno, mode, chain)
/* Walk the insns of the current function and build reload_insn_chain,
and record register life information. */
void
-build_insn_chain (first)
- rtx first;
+build_insn_chain (rtx first)
{
struct insn_chain **p = &reload_insn_chain;
struct insn_chain *prev = 0;
@@ -1805,7 +1805,7 @@ build_insn_chain (first)
{
struct insn_chain *c;
- if (first == b->head)
+ if (first == BB_HEAD (b))
{
int i;
@@ -1867,7 +1867,7 @@ build_insn_chain (first)
}
}
- if (first == b->end)
+ if (first == BB_END (b))
b = b->next_bb;
/* Stop after we pass the end of the last basic block. Verify that
@@ -1897,8 +1897,7 @@ build_insn_chain (first)
showing the information on which the allocation decisions are based. */
static void
-dump_conflicts (file)
- FILE *file;
+dump_conflicts (FILE *file)
{
int i;
int has_preferences;
@@ -1955,8 +1954,7 @@ dump_conflicts (file)
}
void
-dump_global_regs (file)
- FILE *file;
+dump_global_regs (FILE *file)
{
int i, j;
diff --git a/contrib/gcc/graph.c b/contrib/gcc/graph.c
index 572c6b26e24b..e663f8e3fd6a 100644
--- a/contrib/gcc/graph.c
+++ b/contrib/gcc/graph.c
@@ -1,5 +1,6 @@
/* Output routines for graphical representation.
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
This file is part of GCC.
@@ -21,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include <config.h>
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "flags.h"
@@ -37,25 +40,23 @@ static const char *const graph_ext[] =
/* vcg */ ".vcg",
};
-static void start_fct PARAMS ((FILE *));
-static void start_bb PARAMS ((FILE *, int));
-static void node_data PARAMS ((FILE *, rtx));
-static void draw_edge PARAMS ((FILE *, int, int, int, int));
-static void end_fct PARAMS ((FILE *));
-static void end_bb PARAMS ((FILE *));
+static void start_fct (FILE *);
+static void start_bb (FILE *, int);
+static void node_data (FILE *, rtx);
+static void draw_edge (FILE *, int, int, int, int);
+static void end_fct (FILE *);
+static void end_bb (FILE *);
/* Output text for new basic block. */
static void
-start_fct (fp)
- FILE *fp;
+start_fct (FILE *fp)
{
-
switch (graph_dump_format)
{
case vcg:
fprintf (fp, "\
graph: { title: \"%s\"\nfolding: 1\nhidden: 2\nnode: { title: \"%s.0\" }\n",
- current_function_name, current_function_name);
+ current_function_name (), current_function_name ());
break;
case no_graph:
break;
@@ -63,9 +64,7 @@ graph: { title: \"%s\"\nfolding: 1\nhidden: 2\nnode: { title: \"%s.0\" }\n",
}
static void
-start_bb (fp, bb)
- FILE *fp;
- int bb;
+start_bb (FILE *fp, int bb)
{
switch (graph_dump_format)
{
@@ -73,7 +72,7 @@ start_bb (fp, bb)
fprintf (fp, "\
graph: {\ntitle: \"%s.BB%d\"\nfolding: 1\ncolor: lightblue\n\
label: \"basic block %d",
- current_function_name, bb, bb);
+ current_function_name (), bb, bb);
break;
case no_graph:
break;
@@ -104,11 +103,8 @@ label: \"basic block %d",
}
static void
-node_data (fp, tmp_rtx)
- FILE *fp;
- rtx tmp_rtx;
+node_data (FILE *fp, rtx tmp_rtx)
{
-
if (PREV_INSN (tmp_rtx) == 0)
{
/* This is the first instruction. Add an edge from the starting
@@ -118,8 +114,8 @@ node_data (fp, tmp_rtx)
case vcg:
fprintf (fp, "\
edge: { sourcename: \"%s.0\" targetname: \"%s.%d\" }\n",
- current_function_name,
- current_function_name, XINT (tmp_rtx, 0));
+ current_function_name (),
+ current_function_name (), XINT (tmp_rtx, 0));
break;
case no_graph:
break;
@@ -131,7 +127,7 @@ edge: { sourcename: \"%s.0\" targetname: \"%s.%d\" }\n",
case vcg:
fprintf (fp, "node: {\n title: \"%s.%d\"\n color: %s\n \
label: \"%s %d\n",
- current_function_name, XINT (tmp_rtx, 0),
+ current_function_name (), XINT (tmp_rtx, 0),
GET_CODE (tmp_rtx) == NOTE ? "lightgrey"
: GET_CODE (tmp_rtx) == INSN ? "green"
: GET_CODE (tmp_rtx) == JUMP_INSN ? "darkgreen"
@@ -168,12 +164,7 @@ darkgrey\n shape: ellipse" : "white",
}
static void
-draw_edge (fp, from, to, bb_edge, class)
- FILE *fp;
- int from;
- int to;
- int bb_edge;
- int class;
+draw_edge (FILE *fp, int from, int to, int bb_edge, int class)
{
const char * color;
switch (graph_dump_format)
@@ -188,8 +179,8 @@ draw_edge (fp, from, to, bb_edge, class)
color = "color: green ";
fprintf (fp,
"edge: { sourcename: \"%s.%d\" targetname: \"%s.%d\" %s",
- current_function_name, from,
- current_function_name, to, color);
+ current_function_name (), from,
+ current_function_name (), to, color);
if (class)
fprintf (fp, "class: %d ", class);
fputs ("}\n", fp);
@@ -200,8 +191,7 @@ draw_edge (fp, from, to, bb_edge, class)
}
static void
-end_bb (fp)
- FILE *fp;
+end_bb (FILE *fp)
{
switch (graph_dump_format)
{
@@ -214,14 +204,13 @@ end_bb (fp)
}
static void
-end_fct (fp)
- FILE *fp;
+end_fct (FILE *fp)
{
switch (graph_dump_format)
{
case vcg:
fprintf (fp, "node: { title: \"%s.999999\" label: \"END\" }\n}\n",
- current_function_name);
+ current_function_name ());
break;
case no_graph:
break;
@@ -231,16 +220,13 @@ end_fct (fp)
/* Like print_rtl, but also print out live information for the start of each
basic block. */
void
-print_rtl_graph_with_bb (base, suffix, rtx_first)
- const char *base;
- const char *suffix;
- rtx rtx_first;
+print_rtl_graph_with_bb (const char *base, const char *suffix, rtx rtx_first)
{
rtx tmp_rtx;
size_t namelen = strlen (base);
size_t suffixlen = strlen (suffix);
size_t extlen = strlen (graph_ext[graph_dump_format]) + 1;
- char *buf = (char *) alloca (namelen + suffixlen + extlen);
+ char *buf = alloca (namelen + suffixlen + extlen);
FILE *fp;
if (basic_block_info == NULL)
@@ -260,10 +246,9 @@ print_rtl_graph_with_bb (base, suffix, rtx_first)
{
enum bb_state { NOT_IN_BB, IN_ONE_BB, IN_MULTIPLE_BB };
int max_uid = get_max_uid ();
- int *start = (int *) xmalloc (max_uid * sizeof (int));
- int *end = (int *) xmalloc (max_uid * sizeof (int));
- enum bb_state *in_bb_p = (enum bb_state *)
- xmalloc (max_uid * sizeof (enum bb_state));
+ int *start = xmalloc (max_uid * sizeof (int));
+ int *end = xmalloc (max_uid * sizeof (int));
+ enum bb_state *in_bb_p = xmalloc (max_uid * sizeof (enum bb_state));
basic_block bb;
int i;
@@ -276,14 +261,14 @@ print_rtl_graph_with_bb (base, suffix, rtx_first)
FOR_EACH_BB_REVERSE (bb)
{
rtx x;
- start[INSN_UID (bb->head)] = bb->index;
- end[INSN_UID (bb->end)] = bb->index;
- for (x = bb->head; x != NULL_RTX; x = NEXT_INSN (x))
+ start[INSN_UID (BB_HEAD (bb))] = bb->index;
+ end[INSN_UID (BB_END (bb))] = bb->index;
+ for (x = BB_HEAD (bb); x != NULL_RTX; x = NEXT_INSN (x))
{
in_bb_p[INSN_UID (x)]
= (in_bb_p[INSN_UID (x)] == NOT_IN_BB)
? IN_ONE_BB : IN_MULTIPLE_BB;
- if (x == bb->end)
+ if (x == BB_END (bb))
break;
}
}
@@ -337,7 +322,7 @@ print_rtl_graph_with_bb (base, suffix, rtx_first)
{
if (e->dest != EXIT_BLOCK_PTR)
{
- rtx block_head = e->dest->head;
+ rtx block_head = BB_HEAD (e->dest);
draw_edge (fp, INSN_UID (tmp_rtx),
INSN_UID (block_head),
@@ -400,14 +385,12 @@ print_rtl_graph_with_bb (base, suffix, rtx_first)
/* Similar as clean_dump_file, but this time for graph output files. */
void
-clean_graph_dump_file (base, suffix)
- const char *base;
- const char *suffix;
+clean_graph_dump_file (const char *base, const char *suffix)
{
size_t namelen = strlen (base);
size_t suffixlen = strlen (suffix);
size_t extlen = strlen (graph_ext[graph_dump_format]) + 1;
- char *buf = (char *) alloca (namelen + extlen + suffixlen);
+ char *buf = alloca (namelen + extlen + suffixlen);
FILE *fp;
memcpy (buf, base, namelen);
@@ -417,7 +400,7 @@ clean_graph_dump_file (base, suffix)
fp = fopen (buf, "w");
if (fp == NULL)
- fatal_io_error ("can't open %s", buf);
+ fatal_error ("can't open %s: %m", buf);
switch (graph_dump_format)
{
@@ -434,14 +417,12 @@ clean_graph_dump_file (base, suffix)
/* Do final work on the graph output file. */
void
-finish_graph_dump_file (base, suffix)
- const char *base;
- const char *suffix;
+finish_graph_dump_file (const char *base, const char *suffix)
{
size_t namelen = strlen (base);
size_t suffixlen = strlen (suffix);
size_t extlen = strlen (graph_ext[graph_dump_format]) + 1;
- char *buf = (char *) alloca (namelen + suffixlen + extlen);
+ char *buf = alloca (namelen + suffixlen + extlen);
FILE *fp;
memcpy (buf, base, namelen);
diff --git a/contrib/gcc/graph.h b/contrib/gcc/graph.h
index 1033df38928c..e69f3361660e 100644
--- a/contrib/gcc/graph.h
+++ b/contrib/gcc/graph.h
@@ -1,5 +1,5 @@
/* Header file for graph routines.
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,8 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_GRAPH_H
#define GCC_GRAPH_H
-extern void print_rtl_graph_with_bb PARAMS ((const char *, const char *, rtx));
-extern void clean_graph_dump_file PARAMS ((const char *, const char *));
-extern void finish_graph_dump_file PARAMS ((const char *, const char *));
+extern void print_rtl_graph_with_bb (const char *, const char *, rtx);
+extern void clean_graph_dump_file (const char *, const char *);
+extern void finish_graph_dump_file (const char *, const char *);
#endif /* ! GCC_GRAPH_H */
diff --git a/contrib/gcc/gthr-dce.h b/contrib/gcc/gthr-dce.h
index 622e465a795a..563754ea4401 100644
--- a/contrib/gcc/gthr-dce.h
+++ b/contrib/gcc/gthr-dce.h
@@ -425,13 +425,6 @@ __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
}
static inline int
-__gthread_key_dtor (UNUSED (__gthread_key_t key), UNUSED (void *ptr))
-{
- /* Nothing needed. */
- return 0;
-}
-
-static inline int
__gthread_key_delete (UNUSED (__gthread_key_t key))
{
/* Operation is not supported. */
diff --git a/contrib/gcc/gthr-gnat.c b/contrib/gcc/gthr-gnat.c
new file mode 100644
index 000000000000..586e7d1a188e
--- /dev/null
+++ b/contrib/gcc/gthr-gnat.c
@@ -0,0 +1,81 @@
+/* Threads compatibility routines for libgcc2. */
+/* Compile this one with gcc. */
+/* Copyright (C) 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
+
+#include "gthr-gnat.h"
+
+#ifdef __cplusplus
+#define UNUSED(x)
+#else
+#define UNUSED(x) x __attribute__((unused))
+#endif
+
+void __gnat_default_lock (void);
+void __gnat_default_unlock (void);
+
+void
+__gnat_default_lock (void)
+{
+ return;
+}
+
+void
+__gnat_default_unlock (void)
+{
+ return;
+}
+
+static void (*__gnat_task_lock) (void) = *__gnat_default_lock;
+static void (*__gnat_task_unlock) (void) = *__gnat_default_unlock;
+
+ void
+__gnat_install_locks (void (*lock) (void), void (*unlock) (void))
+{
+ __gnat_task_lock = lock;
+ __gnat_task_unlock = unlock;
+}
+
+int
+__gthread_active_p (void)
+{
+ return 0;
+}
+
+int
+__gthread_mutex_lock (__gthread_mutex_t * UNUSED (mutex))
+{
+ __gnat_task_lock ();
+ return 0;
+}
+
+int
+__gthread_mutex_unlock (__gthread_mutex_t * UNUSED (mutex))
+{
+ __gnat_task_unlock ();
+ return 0;
+}
diff --git a/contrib/gcc/gthr-gnat.h b/contrib/gcc/gthr-gnat.h
new file mode 100644
index 000000000000..727814197c08
--- /dev/null
+++ b/contrib/gcc/gthr-gnat.h
@@ -0,0 +1,43 @@
+/* Threads compatibility routines for libgcc2. */
+/* Compile this one with gcc. */
+/* Copyright (C) 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
+#ifndef GCC_GTHR_GNAT_H
+#define GCC_GTHR_GNAT_H
+
+/* Just provide compatibility for mutex handling. */
+
+typedef int __gthread_mutex_t;
+
+#define __GTHREAD_MUTEX_INIT 0
+
+extern void __gnat_install_locks (void (*lock) (void), void (*unlock) (void));
+extern int __gthread_active_p (void);
+extern int __gthread_mutex_lock (__gthread_mutex_t *);
+extern int __gthread_mutex_unlock (__gthread_mutex_t *);
+
+#endif /* ! GCC_GTHR_GNAT_H */
+
diff --git a/contrib/gcc/gthr-posix.c b/contrib/gcc/gthr-posix.c
new file mode 100644
index 000000000000..56bbad283011
--- /dev/null
+++ b/contrib/gcc/gthr-posix.c
@@ -0,0 +1,207 @@
+/* POSIX threads dummy routines for systems without weak definitions. */
+/* Compile this one with gcc. */
+/* Copyright (C) 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* As a special exception, if you link this library with other files,
+ some of which are compiled with GCC, to produce an executable,
+ this library does not by itself cause the resulting executable
+ to be covered by the GNU General Public License.
+ This exception does not however invalidate any other reasons why
+ the executable file might be covered by the GNU General Public License. */
+
+#include "tconfig.h"
+#include "tm.h"
+/* Define so we provide weak definitions of functions used by libobjc only. */
+#define _LIBOBJC_WEAK
+#include "gthr.h"
+
+int
+pthread_once (pthread_once_t *once ATTRIBUTE_UNUSED,
+ void (*func) (void) ATTRIBUTE_UNUSED)
+{
+ return -1;
+}
+
+int
+pthread_key_create (pthread_key_t *key ATTRIBUTE_UNUSED,
+ void (*dtor) (void *) ATTRIBUTE_UNUSED)
+{
+ return -1;
+}
+
+int
+pthread_key_delete (pthread_key_t key ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+void *
+pthread_getspecific (pthread_key_t key ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_setspecific (pthread_key_t key ATTRIBUTE_UNUSED,
+ const void *ptr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_create (pthread_t *thread ATTRIBUTE_UNUSED,
+ const pthread_attr_t *attr ATTRIBUTE_UNUSED,
+ void *(*start_routine) (void *) ATTRIBUTE_UNUSED,
+ void *arg ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_mutex_lock (pthread_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_mutex_trylock (pthread_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_mutex_unlock (pthread_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_cond_broadcast (pthread_cond_t *cond ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_cond_destroy (pthread_cond_t *cond ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_cond_init (pthread_cond_t *cond ATTRIBUTE_UNUSED,
+ const pthread_condattr_t *attr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_cond_signal (pthread_cond_t *cond ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_cond_wait (pthread_cond_t *cond ATTRIBUTE_UNUSED,
+ pthread_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+void
+pthread_exit (void *value_ptr ATTRIBUTE_UNUSED)
+{
+}
+
+int
+pthread_mutex_init (pthread_mutex_t *mutex ATTRIBUTE_UNUSED,
+ const pthread_mutexattr_t *attr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_mutex_destroy (pthread_mutex_t *mutex ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+pthread_t
+pthread_self (void)
+{
+ return (pthread_t) 0;
+}
+
+#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
+int
+sched_get_priority_max (int policy ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+sched_get_priority_min (int policy ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
+
+int
+sched_yield (void)
+{
+ return 0;
+}
+
+int
+pthread_attr_destroy (pthread_attr_t *attr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_attr_init (pthread_attr_t *attr ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_attr_setdetachstate (pthread_attr_t *attr ATTRIBUTE_UNUSED,
+ int detachstate ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
+int
+pthread_getschedparam (pthread_t thread ATTRIBUTE_UNUSED,
+ int *policy ATTRIBUTE_UNUSED,
+ struct sched_param *param ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+pthread_setschedparam (pthread_t thread ATTRIBUTE_UNUSED,
+ int policy ATTRIBUTE_UNUSED,
+ const struct sched_param *param ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
+
diff --git a/contrib/gcc/gthr-posix.h b/contrib/gcc/gthr-posix.h
index 9149e645ceb6..88234daae93a 100644
--- a/contrib/gcc/gthr-posix.h
+++ b/contrib/gcc/gthr-posix.h
@@ -1,6 +1,7 @@
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
-/* Copyright (C) 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -34,6 +35,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define __GTHREADS 1
+/* Some implementations of <pthread.h> require this to be defined. */
+#ifndef _REENTRANT
+#define _REENTRANT 1
+#endif
+
#include <pthread.h>
#include <unistd.h>
@@ -57,7 +63,7 @@ typedef pthread_mutex_t __gthread_mutex_t;
#pragma weak pthread_mutex_trylock
#pragma weak pthread_mutex_unlock
-#ifdef _LIBOBJC
+#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
/* Objective-C. */
#pragma weak pthread_cond_broadcast
#pragma weak pthread_cond_destroy
@@ -82,7 +88,7 @@ typedef pthread_mutex_t __gthread_mutex_t;
#pragma weak pthread_getschedparam
#pragma weak pthread_setschedparam
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
-#endif /* _LIBOBJC */
+#endif /* _LIBOBJC || _LIBOBJC_WEAK */
static inline int
__gthread_active_p (void)
@@ -462,16 +468,6 @@ __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
}
static inline int
-__gthread_key_dtor (__gthread_key_t key, void *ptr)
-{
- /* Just reset the key value to zero. */
- if (ptr)
- return pthread_setspecific (key, 0);
- else
- return 0;
-}
-
-static inline int
__gthread_key_delete (__gthread_key_t key)
{
return pthread_key_delete (key);
diff --git a/contrib/gcc/gthr-rtems.h b/contrib/gcc/gthr-rtems.h
index 8cb951ef5872..73152528aedd 100644
--- a/contrib/gcc/gthr-rtems.h
+++ b/contrib/gcc/gthr-rtems.h
@@ -1,4 +1,4 @@
-/* RTEMS threads compatibily routines for libgcc2 and libobjc.
+/* RTEMS threads compatibility routines for libgcc2 and libobjc.
by: Rosimildo da Silva( rdasilva@connecttel.com ) */
/* Compile this one with gcc. */
/* Copyright (C) 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
@@ -40,7 +40,7 @@ extern "C" {
#define __GTHREAD_MUTEX_INIT 0
#define __GTHREAD_MUTEX_INIT_FUNCTION rtems_gxx_mutex_init
-/* avoid depedency on rtems specific headers */
+/* Avoid dependency on rtems specific headers. */
typedef void *__gthread_key_t;
typedef int __gthread_once_t;
typedef void *__gthread_mutex_t;
@@ -54,7 +54,6 @@ typedef void *__gthread_mutex_t;
/* generic per task variables */
extern int rtems_gxx_once (__gthread_once_t *once, void (*func) (void));
extern int rtems_gxx_key_create (__gthread_key_t *key, void (*dtor) (void *));
-extern int rtems_gxx_key_dtor (__gthread_key_t key, void *ptr);
extern int rtems_gxx_key_delete (__gthread_key_t key);
extern void *rtems_gxx_getspecific (__gthread_key_t key);
extern int rtems_gxx_setspecific (__gthread_key_t key, const void *ptr);
@@ -87,12 +86,6 @@ __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
}
static inline int
-__gthread_key_dtor (__gthread_key_t key, void *ptr)
-{
- return rtems_gxx_key_dtor(key, ptr);
-}
-
-static inline int
__gthread_key_delete (__gthread_key_t key)
{
return rtems_gxx_key_delete (key);
diff --git a/contrib/gcc/gthr-solaris.h b/contrib/gcc/gthr-solaris.h
index 726223dbb7d0..33ddf7a363ca 100644
--- a/contrib/gcc/gthr-solaris.h
+++ b/contrib/gcc/gthr-solaris.h
@@ -417,13 +417,6 @@ __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
}
static inline int
-__gthread_key_dtor (__gthread_key_t key, void *ptr)
-{
- /* Nothing needed. */
- return 0;
-}
-
-static inline int
__gthread_key_delete (__gthread_key_t key)
{
/* Not possible. */
diff --git a/contrib/gcc/gthr-vxworks.h b/contrib/gcc/gthr-vxworks.h
index c85b5e535f37..4fb3b09404aa 100644
--- a/contrib/gcc/gthr-vxworks.h
+++ b/contrib/gcc/gthr-vxworks.h
@@ -32,279 +32,72 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifdef _LIBOBJC
-/* Thread local storage for a single thread */
-static void *thread_local_storage = NULL;
+/* libobjc requires the optional pthreads component. */
+#include "gthr-posix.h"
-/* Backend initialization functions */
-
-/* Initialize the threads subsystem. */
-int
-__gthread_objc_init_thread_system (void)
-{
- /* No thread support available */
- return -1;
-}
-
-/* Close the threads subsystem. */
-int
-__gthread_objc_close_thread_system (void)
-{
- /* No thread support available */
- return -1;
-}
-
-/* Backend thread functions */
-
-/* Create a new thread of execution. */
-objc_thread_t
-__gthread_objc_thread_detach (void (*func)(void *arg), void *arg)
-{
- /* No thread support available */
- return NULL;
-}
-
-/* Set the current thread's priority. */
-int
-__gthread_objc_thread_set_priority (int priority)
-{
- /* No thread support available */
- return -1;
-}
-
-/* Return the current thread's priority. */
-int
-__gthread_objc_thread_get_priority (void)
-{
- return OBJC_THREAD_INTERACTIVE_PRIORITY;
-}
-
-/* Yield our process time to another thread. */
-void
-__gthread_objc_thread_yield (void)
-{
- return;
-}
-
-/* Terminate the current thread. */
-int
-__gthread_objc_thread_exit (void)
-{
- /* No thread support available */
- /* Should we really exit the program */
- /* exit (&__objc_thread_exit_status); */
- return -1;
-}
-
-/* Returns an integer value which uniquely describes a thread. */
-objc_thread_t
-__gthread_objc_thread_id (void)
-{
- /* No thread support, use 1. */
- return (objc_thread_t) 1;
-}
-
-/* Sets the thread's local storage pointer. */
-int
-__gthread_objc_thread_set_data (void *value)
-{
- thread_local_storage = value;
- return 0;
-}
-
-/* Returns the thread's local storage pointer. */
-void *
-__gthread_objc_thread_get_data (void)
-{
- return thread_local_storage;
-}
-
-/* Backend mutex functions */
-
-/* Allocate a mutex. */
-int
-__gthread_objc_mutex_allocate (objc_mutex_t mutex)
-{
- return 0;
-}
-
-/* Deallocate a mutex. */
-int
-__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
-{
- return 0;
-}
-
-/* Grab a lock on a mutex. */
-int
-__gthread_objc_mutex_lock (objc_mutex_t mutex)
-{
- /* There can only be one thread, so we always get the lock */
- return 0;
-}
-
-/* Try to grab a lock on a mutex. */
-int
-__gthread_objc_mutex_trylock (objc_mutex_t mutex)
-{
- /* There can only be one thread, so we always get the lock */
- return 0;
-}
-
-/* Unlock the mutex */
-int
-__gthread_objc_mutex_unlock (objc_mutex_t mutex)
-{
- return 0;
-}
-
-/* Backend condition mutex functions */
-
-/* Allocate a condition. */
-int
-__gthread_objc_condition_allocate (objc_condition_t condition)
-{
- return 0;
-}
-
-/* Deallocate a condition. */
-int
-__gthread_objc_condition_deallocate (objc_condition_t condition)
-{
- return 0;
-}
-
-/* Wait on the condition */
-int
-__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
-{
- return 0;
-}
-
-/* Wake up all threads waiting on this condition. */
-int
-__gthread_objc_condition_broadcast (objc_condition_t condition)
-{
- return 0;
-}
-
-/* Wake up one thread waiting on this condition. */
-int
-__gthread_objc_condition_signal (objc_condition_t condition)
-{
- return 0;
-}
-
-#else /* _LIBOBJC */
-
-/* POSIX threads specific definitions.
- Easy, since the interface is just one-to-one mapping. */
+#else
#define __GTHREADS 1
+#define __gthread_active_p() 1
+
+/* Mutexes are easy, except that they need to be initialized at runtime. */
-#include <vxWorks.h>
#include <semLib.h>
-/* typedef void *SEM_ID; */
-typedef int __gthread_key_t;
-typedef char __gthread_once_t;
typedef SEM_ID __gthread_mutex_t;
+#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
-#define __GTHREAD_MUTEX_INIT 0
-#define __GTHREAD_ONCE_INIT 0
-
-#ifndef REG_SAVED_REG
-static inline int
-__gthread_once (__gthread_once_t *once, void (*func) (void))
-{
- (*func)();
- return 0;
-}
-
-extern __gthread_key_t eh_context_key;
-
-/* This is not the right way to do it, but the semantic of pthreads
- don't map well enough onto VxWorks. */
-
-static void
-__ehdtor (void *pTcb)
-{
- int tid = (int) pTcb;
- void *p = (void *) taskVarGet (tid, &eh_context_key);
- if (p != (void *) -1)
- {
- if (p)
- free (p);
- taskVarSet (tid, &eh_context_key, 0);
- }
-}
-
-/* This only works for the code in libgcc2.c. */
-
-static inline int
-__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
+static inline void
+__gthread_mutex_init_function (__gthread_mutex_t *mutex)
{
- *key = 0;
-
- /* Do this first so that the task variables are visible during the
- running of the delete hook. */
-
- taskVarInit ();
-
- /* We don't have a way to track dtor here, so instead, we
- register a generic routine that can cleanup any task. */
-
- taskDeleteHookAdd (__ehdtor);
-
- return 0;
+ *mutex = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
}
-#define __gthread_setspecific(key, ptr) \
- (key = (int) ptr, 0)
-
-static inline int
-__gthread_key_dtor (__gthread_key_t key, void *ptr)
-{
- /* Just reset the key value to zero. */
- if (ptr)
- return __gthread_setspecific (key, 0);
- else
- return 0;
-}
-
-#define __gthread_key_delete(key) \
- taskVarDelete (taskIdSelf (), &key)
-
-#define __gthread_getspecific(key) \
- ((key == 0) \
- ? ((taskVarAdd (taskIdSelf (), &key) != OK) \
- ? (__terminate (), (void *) 0) \
- : (void *) 0) \
- : (void *) key)
-#endif
-
static inline int
__gthread_mutex_lock (__gthread_mutex_t *mutex)
{
- if (*mutex == 0)
- *mutex = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
return semTake (*mutex, WAIT_FOREVER);
}
static inline int
__gthread_mutex_trylock (__gthread_mutex_t *mutex)
{
- if (*mutex == 0)
- *mutex = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
return semTake (*mutex, NO_WAIT);
}
static inline int
__gthread_mutex_unlock (__gthread_mutex_t *mutex)
{
- /* We could return the */
return semGive (*mutex);
}
-#endif /* _LIBOBJC */
+/* pthread_once is complicated enough that it's implemented
+ out-of-line. See config/vxlib.c. */
+
+typedef struct
+{
+ volatile unsigned char busy;
+ volatile unsigned char done;
+}
+__gthread_once_t;
+
+#define __GTHREAD_ONCE_INIT { 0, 0 }
+
+extern int __gthread_once (__gthread_once_t *once, void (*func)(void));
+
+/* Thread-specific data requires a great deal of effort, since VxWorks
+ is not really set up for it. See config/vxlib.c for the gory
+ details. All the TSD routines are sufficiently complex that they
+ need to be implemented out of line. */
+
+typedef unsigned int __gthread_key_t;
+
+extern int __gthread_key_create (__gthread_key_t *keyp, void (*dtor)(void *));
+extern int __gthread_key_delete (__gthread_key_t key);
+
+extern void *__gthread_getspecific (__gthread_key_t key);
+extern int __gthread_setspecific (__gthread_key_t key, void *ptr);
+
+#endif /* not _LIBOBJC */
-#endif /* ! GCC_GTHR_VXWORKS_H */
+#endif /* gthr-vxworks.h */
diff --git a/contrib/gcc/gthr-win32.h b/contrib/gcc/gthr-win32.h
index 38b8f04a12ad..93f157481a3e 100644
--- a/contrib/gcc/gthr-win32.h
+++ b/contrib/gcc/gthr-win32.h
@@ -1,6 +1,6 @@
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
-/* Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
Contributed by Mumit Khan <khan@xraylith.wisc.edu>.
This file is part of GCC.
@@ -365,7 +365,7 @@ __gthread_active_p (void)
#endif
}
-#ifdef __GTHREAD_HIDE_WIN32API
+#if __GTHREAD_HIDE_WIN32API
/* The implementations are in config/i386/gthr-win32.c in libgcc.a.
Only stubs are exposed to avoid polluting the C++ namespace with
@@ -397,13 +397,6 @@ __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
}
static inline int
-__gthread_key_dtor (__gthread_key_t key, void *ptr)
-{
- /* Nothing needed. */
- return 0;
-}
-
-static inline int
__gthread_key_delete (__gthread_key_t key)
{
return __gthr_win32_key_delete (key);
@@ -511,15 +504,6 @@ __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
return status;
}
-/* Currently, this routine is called only for Mingw runtime, and if
- -mthreads option is chosen to link in the thread support DLL. */
-static inline int
-__gthread_key_dtor (__gthread_key_t key, void *ptr)
-{
- /* Nothing needed. */
- return 0;
-}
-
static inline int
__gthread_key_delete (__gthread_key_t key)
{
diff --git a/contrib/gcc/gthr.h b/contrib/gcc/gthr.h
index b436bb6bb917..b05115436452 100644
--- a/contrib/gcc/gthr.h
+++ b/contrib/gcc/gthr.h
@@ -62,8 +62,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
int __gthread_key_create (__gthread_key_t *keyp, void (*dtor) (void *))
int __gthread_key_delete (__gthread_key_t key)
- int __gthread_key_dtor (__gthread_key_t key, void *ptr)
-
void *__gthread_getspecific (__gthread_key_t key)
int __gthread_setspecific (__gthread_key_t key, const void *ptr)
diff --git a/contrib/gcc/haifa-sched.c b/contrib/gcc/haifa-sched.c
index 5c9ab50f9ab2..2710132ec3e4 100644
--- a/contrib/gcc/haifa-sched.c
+++ b/contrib/gcc/haifa-sched.c
@@ -1,6 +1,6 @@
/* Instruction scheduling pass.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com)
@@ -123,8 +123,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
This pass must update information that subsequent passes expect to
be correct. Namely: reg_n_refs, reg_n_sets, reg_n_deaths,
- reg_n_calls_crossed, and reg_live_length. Also, BLOCK_HEAD,
- BLOCK_END.
+ reg_n_calls_crossed, and reg_live_length. Also, BB_HEAD, BB_END.
The information in the line number notes is carefully retained by
this pass. Notes that refer to the starting and ending of
@@ -134,6 +133,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "tm_p.h"
@@ -187,8 +188,7 @@ static int old_max_uid;
of the -fsched-verbose=N option. */
void
-fix_sched_param (param, val)
- const char *param, *val;
+fix_sched_param (const char *param, const char *val)
{
if (!strcmp (param, "verbose"))
sched_verbose_param = atoi (val);
@@ -303,24 +303,186 @@ struct ready_list
int n_ready;
};
+static int may_trap_exp (rtx, int);
+
+/* Nonzero iff the address is comprised from at most 1 register. */
+#define CONST_BASED_ADDRESS_P(x) \
+ (GET_CODE (x) == REG \
+ || ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS \
+ || (GET_CODE (x) == LO_SUM)) \
+ && (CONSTANT_P (XEXP (x, 0)) \
+ || CONSTANT_P (XEXP (x, 1)))))
+
+/* Returns a class that insn with GET_DEST(insn)=x may belong to,
+ as found by analyzing insn's expression. */
+
+static int
+may_trap_exp (rtx x, int is_store)
+{
+ enum rtx_code code;
+
+ if (x == 0)
+ return TRAP_FREE;
+ code = GET_CODE (x);
+ if (is_store)
+ {
+ if (code == MEM && may_trap_p (x))
+ return TRAP_RISKY;
+ else
+ return TRAP_FREE;
+ }
+ if (code == MEM)
+ {
+ /* The insn uses memory: a volatile load. */
+ if (MEM_VOLATILE_P (x))
+ return IRISKY;
+ /* An exception-free load. */
+ if (!may_trap_p (x))
+ return IFREE;
+ /* A load with 1 base register, to be further checked. */
+ if (CONST_BASED_ADDRESS_P (XEXP (x, 0)))
+ return PFREE_CANDIDATE;
+ /* No info on the load, to be further checked. */
+ return PRISKY_CANDIDATE;
+ }
+ else
+ {
+ const char *fmt;
+ int i, insn_class = TRAP_FREE;
+
+ /* Neither store nor load, check if it may cause a trap. */
+ if (may_trap_p (x))
+ return TRAP_RISKY;
+ /* Recursive step: walk the insn... */
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ {
+ int tmp_class = may_trap_exp (XEXP (x, i), is_store);
+ insn_class = WORST_CLASS (insn_class, tmp_class);
+ }
+ else if (fmt[i] == 'E')
+ {
+ int j;
+ for (j = 0; j < XVECLEN (x, i); j++)
+ {
+ int tmp_class = may_trap_exp (XVECEXP (x, i, j), is_store);
+ insn_class = WORST_CLASS (insn_class, tmp_class);
+ if (insn_class == TRAP_RISKY || insn_class == IRISKY)
+ break;
+ }
+ }
+ if (insn_class == TRAP_RISKY || insn_class == IRISKY)
+ break;
+ }
+ return insn_class;
+ }
+}
+
+/* Classifies insn for the purpose of verifying that it can be
+ moved speculatively, by examining it's patterns, returning:
+ TRAP_RISKY: store, or risky non-load insn (e.g. division by variable).
+ TRAP_FREE: non-load insn.
+ IFREE: load from a globally safe location.
+ IRISKY: volatile load.
+ PFREE_CANDIDATE, PRISKY_CANDIDATE: load that need to be checked for
+ being either PFREE or PRISKY. */
+
+int
+haifa_classify_insn (rtx insn)
+{
+ rtx pat = PATTERN (insn);
+ int tmp_class = TRAP_FREE;
+ int insn_class = TRAP_FREE;
+ enum rtx_code code;
+
+ if (GET_CODE (pat) == PARALLEL)
+ {
+ int i, len = XVECLEN (pat, 0);
+
+ for (i = len - 1; i >= 0; i--)
+ {
+ code = GET_CODE (XVECEXP (pat, 0, i));
+ switch (code)
+ {
+ case CLOBBER:
+ /* Test if it is a 'store'. */
+ tmp_class = may_trap_exp (XEXP (XVECEXP (pat, 0, i), 0), 1);
+ break;
+ case SET:
+ /* Test if it is a store. */
+ tmp_class = may_trap_exp (SET_DEST (XVECEXP (pat, 0, i)), 1);
+ if (tmp_class == TRAP_RISKY)
+ break;
+ /* Test if it is a load. */
+ tmp_class
+ = WORST_CLASS (tmp_class,
+ may_trap_exp (SET_SRC (XVECEXP (pat, 0, i)),
+ 0));
+ break;
+ case COND_EXEC:
+ case TRAP_IF:
+ tmp_class = TRAP_RISKY;
+ break;
+ default:
+ ;
+ }
+ insn_class = WORST_CLASS (insn_class, tmp_class);
+ if (insn_class == TRAP_RISKY || insn_class == IRISKY)
+ break;
+ }
+ }
+ else
+ {
+ code = GET_CODE (pat);
+ switch (code)
+ {
+ case CLOBBER:
+ /* Test if it is a 'store'. */
+ tmp_class = may_trap_exp (XEXP (pat, 0), 1);
+ break;
+ case SET:
+ /* Test if it is a store. */
+ tmp_class = may_trap_exp (SET_DEST (pat), 1);
+ if (tmp_class == TRAP_RISKY)
+ break;
+ /* Test if it is a load. */
+ tmp_class =
+ WORST_CLASS (tmp_class,
+ may_trap_exp (SET_SRC (pat), 0));
+ break;
+ case COND_EXEC:
+ case TRAP_IF:
+ tmp_class = TRAP_RISKY;
+ break;
+ default:;
+ }
+ insn_class = tmp_class;
+ }
+
+ return insn_class;
+}
+
/* Forward declarations. */
/* The scheduler using only DFA description should never use the
following five functions: */
-static unsigned int blockage_range PARAMS ((int, rtx));
-static void clear_units PARAMS ((void));
-static void schedule_unit PARAMS ((int, rtx, int));
-static int actual_hazard PARAMS ((int, rtx, int, int));
-static int potential_hazard PARAMS ((int, rtx, int));
-
-static int priority PARAMS ((rtx));
-static int rank_for_schedule PARAMS ((const PTR, const PTR));
-static void swap_sort PARAMS ((rtx *, int));
-static void queue_insn PARAMS ((rtx, int));
-static void schedule_insn PARAMS ((rtx, struct ready_list *, int));
-static void find_insn_reg_weight PARAMS ((int));
-static void adjust_priority PARAMS ((rtx));
-static void advance_one_cycle PARAMS ((void));
+static unsigned int blockage_range (int, rtx);
+static void clear_units (void);
+static void schedule_unit (int, rtx, int);
+static int actual_hazard (int, rtx, int, int);
+static int potential_hazard (int, rtx, int);
+
+static int priority (rtx);
+static int rank_for_schedule (const void *, const void *);
+static void swap_sort (rtx *, int);
+static void queue_insn (rtx, int);
+static int schedule_insn (rtx, struct ready_list *, int);
+static int find_set_reg_weight (rtx);
+static void find_insn_reg_weight (int);
+static void adjust_priority (rtx);
+static void advance_one_cycle (void);
/* Notes handling mechanism:
=========================
@@ -345,28 +507,29 @@ static void advance_one_cycle PARAMS ((void));
unlink_other_notes ()). After scheduling the block, these notes are
inserted at the beginning of the block (in schedule_block()). */
-static rtx unlink_other_notes PARAMS ((rtx, rtx));
-static rtx unlink_line_notes PARAMS ((rtx, rtx));
-static rtx reemit_notes PARAMS ((rtx, rtx));
+static rtx unlink_other_notes (rtx, rtx);
+static rtx unlink_line_notes (rtx, rtx);
+static rtx reemit_notes (rtx, rtx);
-static rtx *ready_lastpos PARAMS ((struct ready_list *));
-static void ready_sort PARAMS ((struct ready_list *));
-static rtx ready_remove_first PARAMS ((struct ready_list *));
+static rtx *ready_lastpos (struct ready_list *);
+static void ready_sort (struct ready_list *);
+static rtx ready_remove_first (struct ready_list *);
-static void queue_to_ready PARAMS ((struct ready_list *));
+static void queue_to_ready (struct ready_list *);
+static int early_queue_to_ready (state_t, struct ready_list *);
-static void debug_ready_list PARAMS ((struct ready_list *));
+static void debug_ready_list (struct ready_list *);
-static rtx move_insn1 PARAMS ((rtx, rtx));
-static rtx move_insn PARAMS ((rtx, rtx));
+static rtx move_insn1 (rtx, rtx);
+static rtx move_insn (rtx, rtx);
/* The following functions are used to implement multi-pass scheduling
on the first cycle. It is used only for DFA based scheduler. */
-static rtx ready_element PARAMS ((struct ready_list *, int));
-static rtx ready_remove PARAMS ((struct ready_list *, int));
-static int max_issue PARAMS ((struct ready_list *, int *));
+static rtx ready_element (struct ready_list *, int);
+static rtx ready_remove (struct ready_list *, int);
+static int max_issue (struct ready_list *, int *);
-static rtx choose_ready PARAMS ((struct ready_list *));
+static rtx choose_ready (struct ready_list *);
#endif /* INSN_SCHEDULING */
@@ -375,8 +538,7 @@ struct sched_info *current_sched_info;
#ifndef INSN_SCHEDULING
void
-schedule_insns (dump_file)
- FILE *dump_file ATTRIBUTE_UNUSED;
+schedule_insns (FILE *dump_file ATTRIBUTE_UNUSED)
{
}
#else
@@ -395,8 +557,7 @@ static rtx last_scheduled_insn;
should never use the following function. */
HAIFA_INLINE int
-insn_unit (insn)
- rtx insn;
+insn_unit (rtx insn)
{
int unit = INSN_UNIT (insn);
@@ -434,9 +595,7 @@ insn_unit (insn)
function. */
HAIFA_INLINE static unsigned int
-blockage_range (unit, insn)
- int unit;
- rtx insn;
+blockage_range (int unit, rtx insn)
{
unsigned int blockage = INSN_BLOCKAGE (insn);
unsigned int range;
@@ -489,8 +648,7 @@ static int unit_n_insns[1];
following function. */
rtx
-get_unit_last_insn (instance)
- int instance;
+get_unit_last_insn (int instance)
{
return unit_last_insn[instance];
}
@@ -498,19 +656,18 @@ get_unit_last_insn (instance)
/* Reset the function unit state to the null state. */
static void
-clear_units ()
+clear_units (void)
{
- memset ((char *) unit_last_insn, 0, sizeof (unit_last_insn));
- memset ((char *) unit_tick, 0, sizeof (unit_tick));
- memset ((char *) unit_n_insns, 0, sizeof (unit_n_insns));
+ memset (unit_last_insn, 0, sizeof (unit_last_insn));
+ memset (unit_tick, 0, sizeof (unit_tick));
+ memset (unit_n_insns, 0, sizeof (unit_n_insns));
}
/* Return the issue-delay of an insn. The scheduler using only DFA
description should never use the following function. */
HAIFA_INLINE int
-insn_issue_delay (insn)
- rtx insn;
+insn_issue_delay (rtx insn)
{
int i, delay = 0;
int unit = insn_unit (insn);
@@ -540,9 +697,7 @@ insn_issue_delay (insn)
use the following function. */
HAIFA_INLINE int
-actual_hazard_this_instance (unit, instance, insn, clock, cost)
- int unit, instance, clock, cost;
- rtx insn;
+actual_hazard_this_instance (int unit, int instance, rtx insn, int clock, int cost)
{
int tick = unit_tick[instance]; /* Issue time of the last issued insn. */
@@ -577,10 +732,8 @@ actual_hazard_this_instance (unit, instance, insn, clock, cost)
at time CLOCK. The scheduler using only DFA description should
never use the following function. */
-HAIFA_INLINE static void
-schedule_unit (unit, insn, clock)
- int unit, clock;
- rtx insn;
+static void
+schedule_unit (int unit, rtx insn, int clock)
{
int i;
@@ -611,10 +764,8 @@ schedule_unit (unit, insn, clock)
was COST. The scheduler using only DFA description should never
use the following function. */
-HAIFA_INLINE static int
-actual_hazard (unit, insn, clock, cost)
- int unit, clock, cost;
- rtx insn;
+static int
+actual_hazard (int unit, rtx insn, int clock, int cost)
{
int i;
@@ -663,9 +814,7 @@ actual_hazard (unit, insn, clock, cost)
the following function. */
HAIFA_INLINE static int
-potential_hazard (unit, insn, cost)
- int unit, cost;
- rtx insn;
+potential_hazard (int unit, rtx insn, int cost)
{
int i, ncost;
unsigned int minb, maxb;
@@ -708,8 +857,7 @@ potential_hazard (unit, insn, cost)
instruction results. */
HAIFA_INLINE int
-insn_cost (insn, link, used)
- rtx insn, link, used;
+insn_cost (rtx insn, rtx link, rtx used)
{
int cost = INSN_COST (insn);
@@ -731,10 +879,10 @@ insn_cost (insn, link, used)
cost = insn_default_latency (insn);
else
cost = result_ready_cost (insn);
-
+
if (cost < 0)
cost = 0;
-
+
INSN_COST (insn) = cost;
}
}
@@ -775,15 +923,14 @@ insn_cost (insn, link, used)
if (cost < 0)
cost = 0;
}
-
+
return cost;
}
/* Compute the priority number for INSN. */
static int
-priority (insn)
- rtx insn;
+priority (rtx insn)
{
rtx link;
@@ -825,7 +972,7 @@ priority (insn)
}
/* Macros and functions for keeping the priority queue sorted, and
- dealing with queueing and dequeueing of instructions. */
+ dealing with queuing and dequeuing of instructions. */
#define SCHED_SORT(READY, N_READY) \
do { if ((N_READY) == 2) \
@@ -839,9 +986,7 @@ while (0)
unstable. */
static int
-rank_for_schedule (x, y)
- const PTR x;
- const PTR y;
+rank_for_schedule (const void *x, const void *y)
{
rtx tmp = *(const rtx *) y;
rtx tmp2 = *(const rtx *) x;
@@ -849,15 +994,20 @@ rank_for_schedule (x, y)
int tmp_class, tmp2_class, depend_count1, depend_count2;
int val, priority_val, weight_val, info_val;
+ /* The insn in a schedule group should be issued the first. */
+ if (SCHED_GROUP_P (tmp) != SCHED_GROUP_P (tmp2))
+ return SCHED_GROUP_P (tmp2) ? 1 : -1;
+
/* Prefer insn with higher priority. */
priority_val = INSN_PRIORITY (tmp2) - INSN_PRIORITY (tmp);
+
if (priority_val)
return priority_val;
/* Prefer an insn with smaller contribution to registers-pressure. */
if (!reload_completed &&
(weight_val = INSN_REG_WEIGHT (tmp) - INSN_REG_WEIGHT (tmp2)))
- return (weight_val);
+ return weight_val;
info_val = (*current_sched_info->rank) (tmp, tmp2);
if (info_val)
@@ -915,9 +1065,7 @@ rank_for_schedule (x, y)
/* Resort the array A in which only element at index N may be out of order. */
HAIFA_INLINE static void
-swap_sort (a, n)
- rtx *a;
- int n;
+swap_sort (rtx *a, int n)
{
rtx insn = a[n - 1];
int i = n - 2;
@@ -935,9 +1083,7 @@ swap_sort (a, n)
chain for debugging purposes. */
HAIFA_INLINE static void
-queue_insn (insn, n_cycles)
- rtx insn;
- int n_cycles;
+queue_insn (rtx insn, int n_cycles)
{
int next_q = NEXT_Q_AFTER (q_ptr, n_cycles);
rtx link = alloc_INSN_LIST (insn, insn_queue[next_q]);
@@ -957,8 +1103,7 @@ queue_insn (insn, n_cycles)
with the lowest priority. */
HAIFA_INLINE static rtx *
-ready_lastpos (ready)
- struct ready_list *ready;
+ready_lastpos (struct ready_list *ready)
{
if (ready->n_ready == 0)
abort ();
@@ -969,9 +1114,7 @@ ready_lastpos (ready)
priority. */
HAIFA_INLINE void
-ready_add (ready, insn)
- struct ready_list *ready;
- rtx insn;
+ready_add (struct ready_list *ready, rtx insn)
{
if (ready->first == ready->n_ready)
{
@@ -988,8 +1131,7 @@ ready_add (ready, insn)
return it. */
HAIFA_INLINE static rtx
-ready_remove_first (ready)
- struct ready_list *ready;
+ready_remove_first (struct ready_list *ready)
{
rtx t;
if (ready->n_ready == 0)
@@ -1011,12 +1153,12 @@ ready_remove_first (ready)
N_READY - 1. */
HAIFA_INLINE static rtx
-ready_element (ready, index)
- struct ready_list *ready;
- int index;
+ready_element (struct ready_list *ready, int index)
{
+#ifdef ENABLE_CHECKING
if (ready->n_ready == 0 || index >= ready->n_ready)
abort ();
+#endif
return ready->vec[ready->first - index];
}
@@ -1025,9 +1167,7 @@ ready_element (ready, index)
has N_READY - 1. */
HAIFA_INLINE static rtx
-ready_remove (ready, index)
- struct ready_list *ready;
- int index;
+ready_remove (struct ready_list *ready, int index)
{
rtx t;
int i;
@@ -1048,8 +1188,7 @@ ready_remove (ready, index)
macro. */
HAIFA_INLINE static void
-ready_sort (ready)
- struct ready_list *ready;
+ready_sort (struct ready_list *ready)
{
rtx *first = ready_lastpos (ready);
SCHED_SORT (first, ready->n_ready);
@@ -1060,8 +1199,7 @@ ready_sort (ready)
provide a hook for the target to tweek itself. */
HAIFA_INLINE static void
-adjust_priority (prev)
- rtx prev;
+adjust_priority (rtx prev)
{
/* ??? There used to be code here to try and estimate how an insn
affected register lifetimes, but it did it by looking at REG_DEAD
@@ -1077,7 +1215,7 @@ adjust_priority (prev)
/* Advance time on one cycle. */
HAIFA_INLINE static void
-advance_one_cycle ()
+advance_one_cycle (void)
{
if (targetm.sched.use_dfa_pipeline_interface
&& (*targetm.sched.use_dfa_pipeline_interface) ())
@@ -1099,17 +1237,17 @@ static int last_clock_var;
/* INSN is the "currently executing insn". Launch each insn which was
waiting on INSN. READY is the ready list which contains the insns
- that are ready to fire. CLOCK is the current cycle.
- */
+ that are ready to fire. CLOCK is the current cycle. The function
+ returns necessary cycle advance after issuing the insn (it is not
+ zero for insns in a schedule group). */
-static void
-schedule_insn (insn, ready, clock)
- rtx insn;
- struct ready_list *ready;
- int clock;
+static int
+schedule_insn (rtx insn, struct ready_list *ready, int clock)
{
rtx link;
+ int advance = 0;
int unit = 0;
+ int premature_issue = 0;
if (!targetm.sched.use_dfa_pipeline_interface
|| !(*targetm.sched.use_dfa_pipeline_interface) ())
@@ -1122,7 +1260,7 @@ schedule_insn (insn, ready, clock)
char buf[2048];
print_insn (buf, insn, 0);
- buf[40]=0;
+ buf[40] = 0;
fprintf (sched_dump, ";;\t%3i--> %-40s:", clock, buf);
if (recog_memoized (insn) < 0)
@@ -1148,9 +1286,16 @@ schedule_insn (insn, ready, clock)
if (MAX_BLOCKAGE > 1 || issue_rate > 1 || sched_verbose)
schedule_unit (unit, insn, clock);
-
+
if (INSN_DEPEND (insn) == 0)
- return;
+ return 0;
+ }
+
+ if (INSN_TICK (insn) > clock)
+ {
+ /* 'insn' has been prematurely moved from the queue to the
+ ready list. */
+ premature_issue = INSN_TICK (insn) - clock;
}
for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
@@ -1158,7 +1303,7 @@ schedule_insn (insn, ready, clock)
rtx next = XEXP (link, 0);
int cost = insn_cost (insn, link, next);
- INSN_TICK (next) = MAX (INSN_TICK (next), clock + cost);
+ INSN_TICK (next) = MAX (INSN_TICK (next), clock + cost + premature_issue);
if ((INSN_DEP_COUNT (next) -= 1) == 0)
{
@@ -1175,7 +1320,8 @@ schedule_insn (insn, ready, clock)
if (effective_cost < 1)
fprintf (sched_dump, "into ready\n");
else
- fprintf (sched_dump, "into queue with cost=%d\n", effective_cost);
+ fprintf (sched_dump, "into queue with cost=%d\n",
+ effective_cost);
}
/* Adjust the priority of NEXT and either put it on the ready
@@ -1184,7 +1330,12 @@ schedule_insn (insn, ready, clock)
if (effective_cost < 1)
ready_add (ready, next);
else
- queue_insn (next, effective_cost);
+ {
+ queue_insn (next, effective_cost);
+
+ if (SCHED_GROUP_P (next) && advance < effective_cost)
+ advance = effective_cost;
+ }
}
}
@@ -1193,13 +1344,15 @@ schedule_insn (insn, ready, clock)
to issue on the same cycle as the previous insn. A machine
may use this information to decide how the instruction should
be aligned. */
- if (reload_completed && issue_rate > 1
+ if (issue_rate > 1
&& GET_CODE (PATTERN (insn)) != USE
&& GET_CODE (PATTERN (insn)) != CLOBBER)
{
- PUT_MODE (insn, clock > last_clock_var ? TImode : VOIDmode);
+ if (reload_completed)
+ PUT_MODE (insn, clock > last_clock_var ? TImode : VOIDmode);
last_clock_var = clock;
}
+ return advance;
}
/* Functions for handling of notes. */
@@ -1209,8 +1362,7 @@ schedule_insn (insn, ready, clock)
Returns the insn following the notes. */
static rtx
-unlink_other_notes (insn, tail)
- rtx insn, tail;
+unlink_other_notes (rtx insn, rtx tail)
{
rtx prev = PREV_INSN (insn);
@@ -1226,6 +1378,7 @@ unlink_other_notes (insn, tail)
/* See sched_analyze to see how these are handled. */
if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_END
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_END)
{
@@ -1245,8 +1398,7 @@ unlink_other_notes (insn, tail)
they can be reused. Returns the insn following the notes. */
static rtx
-unlink_line_notes (insn, tail)
- rtx insn, tail;
+unlink_line_notes (rtx insn, rtx tail)
{
rtx prev = PREV_INSN (insn);
@@ -1276,14 +1428,11 @@ unlink_line_notes (insn, tail)
/* Return the head and tail pointers of BB. */
void
-get_block_head_tail (b, headp, tailp)
- int b;
- rtx *headp;
- rtx *tailp;
+get_block_head_tail (int b, rtx *headp, rtx *tailp)
{
/* HEAD and TAIL delimit the basic block being scheduled. */
- rtx head = BLOCK_HEAD (b);
- rtx tail = BLOCK_END (b);
+ rtx head = BB_HEAD (BASIC_BLOCK (b));
+ rtx tail = BB_END (BASIC_BLOCK (b));
/* Don't include any notes or labels at the beginning of the
basic block, or notes at the ends of basic blocks. */
@@ -1306,8 +1455,7 @@ get_block_head_tail (b, headp, tailp)
/* Return nonzero if there are no real insns in the range [ HEAD, TAIL ]. */
int
-no_real_insns_p (head, tail)
- rtx head, tail;
+no_real_insns_p (rtx head, rtx tail)
{
while (head != NEXT_INSN (tail))
{
@@ -1323,8 +1471,7 @@ no_real_insns_p (head, tail)
block in which notes should be processed. */
void
-rm_line_notes (head, tail)
- rtx head, tail;
+rm_line_notes (rtx head, rtx tail)
{
rtx next_tail;
rtx insn;
@@ -1356,9 +1503,7 @@ rm_line_notes (head, tail)
the boundaries of the block in which notes should be processed. */
void
-save_line_notes (b, head, tail)
- int b;
- rtx head, tail;
+save_line_notes (int b, rtx head, rtx tail)
{
rtx next_tail;
@@ -1384,8 +1529,7 @@ save_line_notes (b, head, tail)
be processed. */
void
-restore_line_notes (head, tail)
- rtx head, tail;
+restore_line_notes (rtx head, rtx tail)
{
rtx line, note, prev, new;
int added_notes = 0;
@@ -1448,7 +1592,7 @@ restore_line_notes (head, tail)
insns list. */
void
-rm_redundant_line_notes ()
+rm_redundant_line_notes (void)
{
rtx line = 0;
rtx insn = get_insns ();
@@ -1497,9 +1641,7 @@ rm_redundant_line_notes ()
of notes ended by NOTE_LIST. */
void
-rm_other_notes (head, tail)
- rtx head;
- rtx tail;
+rm_other_notes (rtx head, rtx tail)
{
rtx next_tail;
rtx insn;
@@ -1534,11 +1676,35 @@ rm_other_notes (head, tail)
/* Functions for computation of registers live/usage info. */
+/* This function looks for a new register being defined.
+ If the destination register is already used by the source,
+ a new register is not needed. */
+
+static int
+find_set_reg_weight (rtx x)
+{
+ if (GET_CODE (x) == CLOBBER
+ && register_operand (SET_DEST (x), VOIDmode))
+ return 1;
+ if (GET_CODE (x) == SET
+ && register_operand (SET_DEST (x), VOIDmode))
+ {
+ if (GET_CODE (SET_DEST (x)) == REG)
+ {
+ if (!reg_mentioned_p (SET_DEST (x), SET_SRC (x)))
+ return 1;
+ else
+ return 0;
+ }
+ return 1;
+ }
+ return 0;
+}
+
/* Calculate INSN_REG_WEIGHT for all insns of a block. */
static void
-find_insn_reg_weight (b)
- int b;
+find_insn_reg_weight (int b)
{
rtx insn, next_tail, head, tail;
@@ -1556,21 +1722,16 @@ find_insn_reg_weight (b)
/* Increment weight for each register born here. */
x = PATTERN (insn);
- if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
- && register_operand (SET_DEST (x), VOIDmode))
- reg_weight++;
- else if (GET_CODE (x) == PARALLEL)
+ reg_weight += find_set_reg_weight (x);
+ if (GET_CODE (x) == PARALLEL)
{
int j;
for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
{
x = XVECEXP (PATTERN (insn), 0, j);
- if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
- && register_operand (SET_DEST (x), VOIDmode))
- reg_weight++;
+ reg_weight += find_set_reg_weight (x);
}
}
-
/* Decrement weight for each register that dies here. */
for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
{
@@ -1589,8 +1750,7 @@ static int clock_var;
/* Move insns that became ready to fire from queue to ready list. */
static void
-queue_to_ready (ready)
- struct ready_list *ready;
+queue_to_ready (struct ready_list *ready)
{
rtx insn;
rtx link;
@@ -1657,11 +1817,163 @@ queue_to_ready (ready)
}
}
+/* Used by early_queue_to_ready. Determines whether it is "ok" to
+ prematurely move INSN from the queue to the ready list. Currently,
+ if a target defines the hook 'is_costly_dependence', this function
+ uses the hook to check whether there exist any dependences which are
+ considered costly by the target, between INSN and other insns that
+ have already been scheduled. Dependences are checked up to Y cycles
+ back, with default Y=1; The flag -fsched-stalled-insns-dep=Y allows
+ controlling this value.
+ (Other considerations could be taken into account instead (or in
+ addition) depending on user flags and target hooks. */
+
+static bool
+ok_for_early_queue_removal (rtx insn)
+{
+ int n_cycles;
+ rtx prev_insn = last_scheduled_insn;
+
+ if (targetm.sched.is_costly_dependence)
+ {
+ for (n_cycles = flag_sched_stalled_insns_dep; n_cycles; n_cycles--)
+ {
+ for ( ; prev_insn; prev_insn = PREV_INSN (prev_insn))
+ {
+ rtx dep_link = 0;
+ int dep_cost;
+
+ if (GET_CODE (prev_insn) != NOTE)
+ {
+ dep_link = find_insn_list (insn, INSN_DEPEND (prev_insn));
+ if (dep_link)
+ {
+ dep_cost = insn_cost (prev_insn, dep_link, insn) ;
+ if (targetm.sched.is_costly_dependence (prev_insn, insn,
+ dep_link, dep_cost,
+ flag_sched_stalled_insns_dep - n_cycles))
+ return false;
+ }
+ }
+
+ if (GET_MODE (prev_insn) == TImode) /* end of dispatch group */
+ break;
+ }
+
+ if (!prev_insn)
+ break;
+ prev_insn = PREV_INSN (prev_insn);
+ }
+ }
+
+ return true;
+}
+
+
+/* Remove insns from the queue, before they become "ready" with respect
+ to FU latency considerations. */
+
+static int
+early_queue_to_ready (state_t state, struct ready_list *ready)
+{
+ rtx insn;
+ rtx link;
+ rtx next_link;
+ rtx prev_link;
+ bool move_to_ready;
+ int cost;
+ state_t temp_state = alloca (dfa_state_size);
+ int stalls;
+ int insns_removed = 0;
+
+ /*
+ Flag '-fsched-stalled-insns=X' determines the aggressiveness of this
+ function:
+
+ X == 0: There is no limit on how many queued insns can be removed
+ prematurely. (flag_sched_stalled_insns = -1).
+
+ X >= 1: Only X queued insns can be removed prematurely in each
+ invocation. (flag_sched_stalled_insns = X).
+
+ Otherwise: Early queue removal is disabled.
+ (flag_sched_stalled_insns = 0)
+ */
+
+ if (! flag_sched_stalled_insns)
+ return 0;
+
+ for (stalls = 0; stalls <= MAX_INSN_QUEUE_INDEX; stalls++)
+ {
+ if ((link = insn_queue[NEXT_Q_AFTER (q_ptr, stalls)]))
+ {
+ if (sched_verbose > 6)
+ fprintf (sched_dump, ";; look at index %d + %d\n", q_ptr, stalls);
+
+ prev_link = 0;
+ while (link)
+ {
+ next_link = XEXP (link, 1);
+ insn = XEXP (link, 0);
+ if (insn && sched_verbose > 6)
+ print_rtl_single (sched_dump, insn);
+
+ memcpy (temp_state, state, dfa_state_size);
+ if (recog_memoized (insn) < 0)
+ /* non-negative to indicate that it's not ready
+ to avoid infinite Q->R->Q->R... */
+ cost = 0;
+ else
+ cost = state_transition (temp_state, insn);
+
+ if (sched_verbose >= 6)
+ fprintf (sched_dump, "transition cost = %d\n", cost);
+
+ move_to_ready = false;
+ if (cost < 0)
+ {
+ move_to_ready = ok_for_early_queue_removal (insn);
+ if (move_to_ready == true)
+ {
+ /* move from Q to R */
+ q_size -= 1;
+ ready_add (ready, insn);
+
+ if (prev_link)
+ XEXP (prev_link, 1) = next_link;
+ else
+ insn_queue[NEXT_Q_AFTER (q_ptr, stalls)] = next_link;
+
+ free_INSN_LIST_node (link);
+
+ if (sched_verbose >= 2)
+ fprintf (sched_dump, ";;\t\tEarly Q-->Ready: insn %s\n",
+ (*current_sched_info->print_insn) (insn, 0));
+
+ insns_removed++;
+ if (insns_removed == flag_sched_stalled_insns)
+ /* remove only one insn from Q at a time */
+ return insns_removed;
+ }
+ }
+
+ if (move_to_ready == false)
+ prev_link = link;
+
+ link = next_link;
+ } /* while link */
+ } /* if link */
+
+ } /* for stalls.. */
+
+ return insns_removed;
+}
+
+
/* Print the ready list for debugging purposes. Callable from debugger. */
static void
-debug_ready_list (ready)
- struct ready_list *ready;
+debug_ready_list (struct ready_list *ready)
{
rtx *p;
int i;
@@ -1681,8 +1993,7 @@ debug_ready_list (ready)
/* move_insn1: Remove INSN from insn chain, and link it after LAST insn. */
static rtx
-move_insn1 (insn, last)
- rtx insn, last;
+move_insn1 (rtx insn, rtx last)
{
NEXT_INSN (PREV_INSN (insn)) = NEXT_INSN (insn);
PREV_INSN (NEXT_INSN (insn)) = PREV_INSN (insn);
@@ -1704,9 +2015,7 @@ move_insn1 (insn, last)
output by the instruction scheduler. Return the new value of LAST. */
static rtx
-reemit_notes (insn, last)
- rtx insn;
- rtx last;
+reemit_notes (rtx insn, rtx last)
{
rtx note, retval;
@@ -1729,38 +2038,16 @@ reemit_notes (insn, last)
return retval;
}
-/* Move INSN, and all insns which should be issued before it,
- due to SCHED_GROUP_P flag. Reemit notes if needed.
+/* Move INSN. Reemit notes if needed.
Return the last insn emitted by the scheduler, which is the
return value from the first call to reemit_notes. */
static rtx
-move_insn (insn, last)
- rtx insn, last;
+move_insn (rtx insn, rtx last)
{
rtx retval = NULL;
- /* If INSN has SCHED_GROUP_P set, then issue it and any other
- insns with SCHED_GROUP_P set first. */
- while (SCHED_GROUP_P (insn))
- {
- rtx prev = PREV_INSN (insn);
-
- /* Move a SCHED_GROUP_P insn. */
- move_insn1 (insn, last);
- /* If this is the first call to reemit_notes, then record
- its return value. */
- if (retval == NULL_RTX)
- retval = reemit_notes (insn, insn);
- else
- reemit_notes (insn, insn);
- /* Consume SCHED_GROUP_P flag. */
- SCHED_GROUP_P (insn) = 0;
- insn = prev;
- }
-
- /* Now move the first non SCHED_GROUP_P insn. */
move_insn1 (insn, last);
/* If this is the first call to reemit_notes, then record
@@ -1770,6 +2057,8 @@ move_insn (insn, last)
else
reemit_notes (insn, insn);
+ SCHED_GROUP_P (insn) = 0;
+
return retval;
}
@@ -1824,9 +2113,7 @@ static int cached_issue_rate = 0;
of the best insn in READY. The following function is used only for
first cycle multipass scheduling. */
static int
-max_issue (ready, index)
- struct ready_list *ready;
- int *index;
+max_issue (struct ready_list *ready, int *index)
{
int n, i, all, n_ready, best, delay, tries_num;
struct choice_entry *top;
@@ -1902,8 +2189,7 @@ max_issue (ready, index)
cycle multipass scheduling. */
static rtx
-choose_ready (ready)
- struct ready_list *ready;
+choose_ready (struct ready_list *ready)
{
int lookahead = 0;
@@ -1914,7 +2200,7 @@ choose_ready (ready)
else
{
/* Try to choose the better insn. */
- int index, i;
+ int index = 0, i;
rtx insn;
if (cached_first_cycle_multipass_dfa_lookahead != lookahead)
@@ -1930,7 +2216,10 @@ choose_ready (ready)
for (i = 1; i < ready->n_ready; i++)
{
insn = ready_element (ready, i);
- ready_try [i] = INSN_CODE (insn) < 0;
+ ready_try [i]
+ = (INSN_CODE (insn) < 0
+ || (targetm.sched.first_cycle_multipass_dfa_lookahead_guard
+ && !(*targetm.sched.first_cycle_multipass_dfa_lookahead_guard) (insn)));
}
if (max_issue (ready, &index) == 0)
return ready_remove_first (ready);
@@ -1943,8 +2232,7 @@ choose_ready (ready)
the instruction stream. */
rtx
-sched_emit_insn (pat)
- rtx pat;
+sched_emit_insn (rtx pat)
{
rtx insn = emit_insn_after (pat, last_scheduled_insn);
last_scheduled_insn = insn;
@@ -1955,15 +2243,13 @@ sched_emit_insn (pat)
possibly bringing insns from subsequent blocks in the same region. */
void
-schedule_block (b, rgn_n_insns)
- int b;
- int rgn_n_insns;
+schedule_block (int b, int rgn_n_insns)
{
struct ready_list ready;
- int i;
- int first_cycle_insn_p;
+ int i, first_cycle_insn_p;
int can_issue_more;
state_t temp_state = NULL; /* It is used for multipass scheduling. */
+ int sort_p, advance, start_clock_var;
/* Head/tail info for this block. */
rtx prev_head = current_sched_info->prev_head;
@@ -2005,7 +2291,7 @@ schedule_block (b, rgn_n_insns)
/* Allocate the ready list. */
ready.veclen = rgn_n_insns + 1 + issue_rate;
ready.first = ready.veclen - 1;
- ready.vec = (rtx *) xmalloc (ready.veclen * sizeof (rtx));
+ ready.vec = xmalloc (ready.veclen * sizeof (rtx));
ready.n_ready = 0;
if (targetm.sched.use_dfa_pipeline_interface
@@ -2013,13 +2299,11 @@ schedule_block (b, rgn_n_insns)
{
/* It is used for first cycle multipass scheduling. */
temp_state = alloca (dfa_state_size);
- ready_try = (char *) xmalloc ((rgn_n_insns + 1) * sizeof (char));
- memset (ready_try, 0, (rgn_n_insns + 1) * sizeof (char));
- choice_stack
- = (struct choice_entry *) xmalloc ((rgn_n_insns + 1)
- * sizeof (struct choice_entry));
+ ready_try = xcalloc ((rgn_n_insns + 1), sizeof (char));
+ choice_stack = xmalloc ((rgn_n_insns + 1)
+ * sizeof (struct choice_entry));
for (i = 0; i <= rgn_n_insns; i++)
- choice_stack[i].state = (state_t) xmalloc (dfa_state_size);
+ choice_stack[i].state = xmalloc (dfa_state_size);
}
(*current_sched_info->init_ready_list) (&ready);
@@ -2041,41 +2325,61 @@ schedule_block (b, rgn_n_insns)
else
max_insn_queue_index_macro_value = max_insn_queue_index;
- insn_queue = (rtx *) alloca ((MAX_INSN_QUEUE_INDEX + 1) * sizeof (rtx));
- memset ((char *) insn_queue, 0, (MAX_INSN_QUEUE_INDEX + 1) * sizeof (rtx));
+ insn_queue = alloca ((MAX_INSN_QUEUE_INDEX + 1) * sizeof (rtx));
+ memset (insn_queue, 0, (MAX_INSN_QUEUE_INDEX + 1) * sizeof (rtx));
last_clock_var = -1;
/* Start just before the beginning of time. */
clock_var = -1;
+ advance = 0;
+ sort_p = TRUE;
/* Loop until all the insns in BB are scheduled. */
while ((*current_sched_info->schedule_more_p) ())
{
- clock_var++;
+ do
+ {
+ start_clock_var = clock_var;
- advance_one_cycle ();
+ clock_var++;
- /* Add to the ready list all pending insns that can be issued now.
- If there are no ready insns, increment clock until one
- is ready and add all pending insns at that point to the ready
- list. */
- queue_to_ready (&ready);
+ advance_one_cycle ();
- if (ready.n_ready == 0)
- abort ();
+ /* Add to the ready list all pending insns that can be issued now.
+ If there are no ready insns, increment clock until one
+ is ready and add all pending insns at that point to the ready
+ list. */
+ queue_to_ready (&ready);
- if (sched_verbose >= 2)
- {
- fprintf (sched_dump, ";;\t\tReady list after queue_to_ready: ");
- debug_ready_list (&ready);
+ if (ready.n_ready == 0)
+ abort ();
+
+ if (sched_verbose >= 2)
+ {
+ fprintf (sched_dump, ";;\t\tReady list after queue_to_ready: ");
+ debug_ready_list (&ready);
+ }
+ advance -= clock_var - start_clock_var;
}
+ while (advance > 0);
- /* Sort the ready list based on priority. */
- ready_sort (&ready);
+ if (sort_p)
+ {
+ /* Sort the ready list based on priority. */
+ ready_sort (&ready);
+
+ if (sched_verbose >= 2)
+ {
+ fprintf (sched_dump, ";;\t\tReady list after ready_sort: ");
+ debug_ready_list (&ready);
+ }
+ }
/* Allow the target to reorder the list, typically for
better instruction bundling. */
- if (targetm.sched.reorder)
+ if (sort_p && targetm.sched.reorder
+ && (ready.n_ready == 0
+ || !SCHED_GROUP_P (ready_element (&ready, 0))))
can_issue_more =
(*targetm.sched.reorder) (sched_dump, sched_verbose,
ready_lastpos (&ready),
@@ -2089,6 +2393,7 @@ schedule_block (b, rgn_n_insns)
{
rtx insn;
int cost;
+ bool asm_p = false;
if (sched_verbose >= 2)
{
@@ -2103,25 +2408,52 @@ schedule_block (b, rgn_n_insns)
if (ready.n_ready == 0 || !can_issue_more
|| !(*current_sched_info->schedule_more_p) ())
break;
- insn = choose_ready (&ready);
+ insn = ready_remove_first (&ready);
cost = actual_hazard (insn_unit (insn), insn, clock_var, 0);
}
else
{
+ if (ready.n_ready == 0
+ && can_issue_more
+ && reload_completed)
+ {
+ /* Allow scheduling insns directly from the queue in case
+ there's nothing better to do (ready list is empty) but
+ there are still vacant dispatch slots in the current cycle. */
+ if (sched_verbose >= 6)
+ fprintf(sched_dump,";;\t\tSecond chance\n");
+ memcpy (temp_state, curr_state, dfa_state_size);
+ if (early_queue_to_ready (temp_state, &ready))
+ ready_sort (&ready);
+ }
+
if (ready.n_ready == 0 || !can_issue_more
|| state_dead_lock_p (curr_state)
|| !(*current_sched_info->schedule_more_p) ())
break;
-
+
/* Select and remove the insn from the ready list. */
- insn = choose_ready (&ready);
-
+ if (sort_p)
+ insn = choose_ready (&ready);
+ else
+ insn = ready_remove_first (&ready);
+
+ if (targetm.sched.dfa_new_cycle
+ && (*targetm.sched.dfa_new_cycle) (sched_dump, sched_verbose,
+ insn, last_clock_var,
+ clock_var, &sort_p))
+ {
+ ready_add (&ready, insn);
+ break;
+ }
+
+ sort_p = TRUE;
memcpy (temp_state, curr_state, dfa_state_size);
if (recog_memoized (insn) < 0)
{
- if (!first_cycle_insn_p
- && (GET_CODE (PATTERN (insn)) == ASM_INPUT
- || asm_noperands (PATTERN (insn)) >= 0))
+ asm_p = (GET_CODE (PATTERN (insn)) == ASM_INPUT
+ || asm_noperands (PATTERN (insn)) >= 0);
+ if (!first_cycle_insn_p && asm_p)
/* This is asm insn which is tryed to be issued on the
cycle not first. Issue it on the next cycle. */
cost = 1;
@@ -2143,32 +2475,32 @@ schedule_block (b, rgn_n_insns)
{
int j;
rtx bubble;
-
+
for (j = 0;
(bubble = (*targetm.sched.dfa_bubble) (j))
!= NULL_RTX;
j++)
{
memcpy (temp_state, curr_state, dfa_state_size);
-
+
if (state_transition (temp_state, bubble) < 0
&& state_transition (temp_state, insn) < 0)
break;
}
-
+
if (bubble != NULL_RTX)
{
if (insert_schedule_bubbles_p)
{
rtx copy;
-
+
copy = copy_rtx (PATTERN (bubble));
emit_insn_after (copy, last_scheduled_insn);
last_scheduled_insn
= NEXT_INSN (last_scheduled_insn);
INSN_CODE (last_scheduled_insn)
= INSN_CODE (bubble);
-
+
/* Annotate the same for the first insns
scheduling by using mode. */
PUT_MODE (last_scheduled_insn,
@@ -2176,20 +2508,20 @@ schedule_block (b, rgn_n_insns)
? clock_var - last_clock_var
: VOIDmode));
last_clock_var = clock_var;
-
+
if (sched_verbose >= 2)
{
fprintf (sched_dump,
";;\t\t--> scheduling bubble insn <<<%d>>>:reservation ",
INSN_UID (last_scheduled_insn));
-
+
if (recog_memoized (last_scheduled_insn)
< 0)
fprintf (sched_dump, "nothing");
else
print_reservation
(sched_dump, last_scheduled_insn);
-
+
fprintf (sched_dump, "\n");
}
}
@@ -2224,7 +2556,7 @@ schedule_block (b, rgn_n_insns)
cycle_issued_insns++;
memcpy (curr_state, temp_state, dfa_state_size);
}
-
+
if (targetm.sched.variable_issue)
can_issue_more =
(*targetm.sched.variable_issue) (sched_dump, sched_verbose,
@@ -2235,18 +2567,29 @@ schedule_block (b, rgn_n_insns)
&& GET_CODE (PATTERN (insn)) != CLOBBER)
can_issue_more--;
- schedule_insn (insn, &ready, clock_var);
+ advance = schedule_insn (insn, &ready, clock_var);
+
+ /* After issuing an asm insn we should start a new cycle. */
+ if (advance == 0 && asm_p)
+ advance = 1;
+ if (advance != 0)
+ break;
next:
first_cycle_insn_p = 0;
- if (targetm.sched.reorder2)
+ /* Sort the ready list based on priority. This must be
+ redone here, as schedule_insn may have readied additional
+ insns that will not be sorted correctly. */
+ if (ready.n_ready > 0)
+ ready_sort (&ready);
+
+ if (targetm.sched.reorder2
+ && (ready.n_ready == 0
+ || !SCHED_GROUP_P (ready_element (&ready, 0))))
{
- /* Sort the ready list based on priority. */
- if (ready.n_ready > 0)
- ready_sort (&ready);
can_issue_more =
- (*targetm.sched.reorder2) (sched_dump,sched_verbose,
+ (*targetm.sched.reorder2) (sched_dump, sched_verbose,
ready.n_ready
? ready_lastpos (&ready) : NULL,
&ready.n_ready, clock_var);
@@ -2282,6 +2625,27 @@ schedule_block (b, rgn_n_insns)
head = NEXT_INSN (prev_head);
tail = last_scheduled_insn;
+ if (!reload_completed)
+ {
+ rtx insn, link, next;
+
+ /* INSN_TICK (minimum clock tick at which the insn becomes
+ ready) may be not correct for the insn in the subsequent
+ blocks of the region. We should use a correct value of
+ `clock_var' or modify INSN_TICK. It is better to keep
+ clock_var value equal to 0 at the start of a basic block.
+ Therefore we modify INSN_TICK here. */
+ for (insn = head; insn != tail; insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ {
+ for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
+ {
+ next = XEXP (link, 0);
+ INSN_TICK (next) -= clock_var;
+ }
+ }
+ }
+
/* Restore-other-notes: NOTE_LIST is the end of a chain of notes
previously found among the insns. Insert them at the beginning
of the insns. */
@@ -2329,12 +2693,12 @@ schedule_block (b, rgn_n_insns)
/* Set_priorities: compute priority of each insn in the block. */
int
-set_priorities (head, tail)
- rtx head, tail;
+set_priorities (rtx head, rtx tail)
{
rtx insn;
int n_insn;
-
+ int sched_max_insns_priority =
+ current_sched_info->sched_max_insns_priority;
rtx prev_head;
prev_head = PREV_INSN (head);
@@ -2343,15 +2707,22 @@ set_priorities (head, tail)
return 0;
n_insn = 0;
+ sched_max_insns_priority = 0;
for (insn = tail; insn != prev_head; insn = PREV_INSN (insn))
{
if (GET_CODE (insn) == NOTE)
continue;
- if (!(SCHED_GROUP_P (insn)))
- n_insn++;
+ n_insn++;
(void) priority (insn);
+
+ if (INSN_PRIORITY_KNOWN (insn))
+ sched_max_insns_priority =
+ MAX (sched_max_insns_priority, INSN_PRIORITY (insn));
}
+ sched_max_insns_priority += 1;
+ current_sched_info->sched_max_insns_priority =
+ sched_max_insns_priority;
return n_insn;
}
@@ -2360,8 +2731,7 @@ set_priorities (head, tail)
for debugging output. */
void
-sched_init (dump_file)
- FILE *dump_file;
+sched_init (FILE *dump_file)
{
int luid;
basic_block b;
@@ -2399,7 +2769,7 @@ sched_init (dump_file)
pseudos which do not cross calls. */
old_max_uid = get_max_uid () + 1;
- h_i_d = (struct haifa_insn_data *) xcalloc (old_max_uid, sizeof (*h_i_d));
+ h_i_d = xcalloc (old_max_uid, sizeof (*h_i_d));
for (i = 0; i < old_max_uid; i++)
h_i_d [i].cost = -1;
@@ -2409,14 +2779,14 @@ sched_init (dump_file)
{
if (targetm.sched.init_dfa_pre_cycle_insn)
(*targetm.sched.init_dfa_pre_cycle_insn) ();
-
+
if (targetm.sched.init_dfa_post_cycle_insn)
(*targetm.sched.init_dfa_post_cycle_insn) ();
-
+
if (targetm.sched.first_cycle_multipass_dfa_lookahead
&& targetm.sched.init_dfa_bubbles)
(*targetm.sched.init_dfa_bubbles) ();
-
+
dfa_start ();
dfa_state_size = state_size ();
curr_state = xmalloc (dfa_state_size);
@@ -2425,7 +2795,7 @@ sched_init (dump_file)
h_i_d[0].luid = 0;
luid = 1;
FOR_EACH_BB (b)
- for (insn = b->head;; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (b); ; insn = NEXT_INSN (insn))
{
INSN_LUID (insn) = luid;
@@ -2437,7 +2807,7 @@ sched_init (dump_file)
if (GET_CODE (insn) != NOTE)
++luid;
- if (insn == b->end)
+ if (insn == BB_END (b))
break;
}
@@ -2449,7 +2819,7 @@ sched_init (dump_file)
{
rtx line;
- line_note_head = (rtx *) xcalloc (last_basic_block, sizeof (rtx));
+ line_note_head = xcalloc (last_basic_block, sizeof (rtx));
/* Save-line-note-head:
Determine the line-number at the start of each basic block.
@@ -2459,7 +2829,7 @@ sched_init (dump_file)
FOR_EACH_BB (b)
{
- for (line = b->head; line; line = PREV_INSN (line))
+ for (line = BB_HEAD (b); line; line = PREV_INSN (line))
if (GET_CODE (line) == NOTE && NOTE_LINE_NUMBER (line) > 0)
{
line_note_head[b->index] = line;
@@ -2467,7 +2837,7 @@ sched_init (dump_file)
}
/* Do a forward search as well, since we won't get to see the first
notes in a basic block. */
- for (line = b->head; line; line = NEXT_INSN (line))
+ for (line = BB_HEAD (b); line; line = NEXT_INSN (line))
{
if (INSN_P (line))
break;
@@ -2486,16 +2856,16 @@ sched_init (dump_file)
/* ??? Add a NOTE after the last insn of the last basic block. It is not
known why this is done. */
- insn = EXIT_BLOCK_PTR->prev_bb->end;
+ insn = BB_END (EXIT_BLOCK_PTR->prev_bb);
if (NEXT_INSN (insn) == 0
|| (GET_CODE (insn) != NOTE
&& GET_CODE (insn) != CODE_LABEL
/* Don't emit a NOTE if it would end up before a BARRIER. */
&& GET_CODE (NEXT_INSN (insn)) != BARRIER))
{
- emit_note_after (NOTE_INSN_DELETED, EXIT_BLOCK_PTR->prev_bb->end);
+ emit_note_after (NOTE_INSN_DELETED, BB_END (EXIT_BLOCK_PTR->prev_bb));
/* Make insn to appear outside BB. */
- EXIT_BLOCK_PTR->prev_bb->end = PREV_INSN (EXIT_BLOCK_PTR->prev_bb->end);
+ BB_END (EXIT_BLOCK_PTR->prev_bb) = PREV_INSN (BB_END (EXIT_BLOCK_PTR->prev_bb));
}
/* Compute INSN_REG_WEIGHT for all blocks. We must do this before
@@ -2507,7 +2877,7 @@ sched_init (dump_file)
/* Free global data used during insn scheduling. */
void
-sched_finish ()
+sched_finish (void)
{
free (h_i_d);
diff --git a/contrib/gcc/hard-reg-set.h b/contrib/gcc/hard-reg-set.h
index 53330cf28b76..a770180e3868 100644
--- a/contrib/gcc/hard-reg-set.h
+++ b/contrib/gcc/hard-reg-set.h
@@ -1,5 +1,5 @@
/* Sets (bit vectors) of hard registers, and operations on them.
- Copyright (C) 1987, 1992, 1994, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1992, 1994, 2000, 2003 Free Software Foundation, Inc.
This file is part of GCC
@@ -418,7 +418,7 @@ extern HARD_REG_SET losing_caller_save_reg_set;
/* Indexed by hard register number, contains 1 for registers that are
fixed use -- i.e. in fixed_regs -- or a function value return register
- or STRUCT_VALUE_REGNUM or STATIC_CHAIN_REGNUM. These are the
+ or TARGET_STRUCT_VALUE_RTX or STATIC_CHAIN_REGNUM. These are the
registers that cannot hold quantities across calls even if we are
willing to save and restore them. */
diff --git a/contrib/gcc/hashtab.c b/contrib/gcc/hashtab.c
index 9426a185178e..231fbc0dd7ad 100644
--- a/contrib/gcc/hashtab.c
+++ b/contrib/gcc/hashtab.c
@@ -1,5 +1,5 @@
/* An expandable hash tables datatype.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Vladimir Makarov (vmakarov@cygnus.com).
This file is part of the libiberty library.
@@ -195,6 +195,63 @@ htab_create_alloc (size, hash_f, eq_f, del_f, alloc_f, free_f)
return result;
}
+/* As above, but use the variants of alloc_f and free_f which accept
+ an extra argument. */
+
+htab_t
+htab_create_alloc_ex (size, hash_f, eq_f, del_f, alloc_arg, alloc_f,
+ free_f)
+ size_t size;
+ htab_hash hash_f;
+ htab_eq eq_f;
+ htab_del del_f;
+ PTR alloc_arg;
+ htab_alloc_with_arg alloc_f;
+ htab_free_with_arg free_f;
+{
+ htab_t result;
+
+ size = higher_prime_number (size);
+ result = (htab_t) (*alloc_f) (alloc_arg, 1, sizeof (struct htab));
+ if (result == NULL)
+ return NULL;
+ result->entries = (PTR *) (*alloc_f) (alloc_arg, size, sizeof (PTR));
+ if (result->entries == NULL)
+ {
+ if (free_f != NULL)
+ (*free_f) (alloc_arg, result);
+ return NULL;
+ }
+ result->size = size;
+ result->hash_f = hash_f;
+ result->eq_f = eq_f;
+ result->del_f = del_f;
+ result->alloc_arg = alloc_arg;
+ result->alloc_with_arg_f = alloc_f;
+ result->free_with_arg_f = free_f;
+ return result;
+}
+
+/* Update the function pointers and allocation parameter in the htab_t. */
+
+void
+htab_set_functions_ex (htab, hash_f, eq_f, del_f, alloc_arg, alloc_f, free_f)
+ htab_t htab;
+ htab_hash hash_f;
+ htab_eq eq_f;
+ htab_del del_f;
+ PTR alloc_arg;
+ htab_alloc_with_arg alloc_f;
+ htab_free_with_arg free_f;
+{
+ htab->hash_f = hash_f;
+ htab->eq_f = eq_f;
+ htab->del_f = del_f;
+ htab->alloc_arg = alloc_arg;
+ htab->alloc_with_arg_f = alloc_f;
+ htab->free_with_arg_f = free_f;
+}
+
/* These functions exist solely for backward compatibility. */
#undef htab_create
@@ -238,6 +295,11 @@ htab_delete (htab)
(*htab->free_f) (htab->entries);
(*htab->free_f) (htab);
}
+ else if (htab->free_with_arg_f != NULL)
+ {
+ (*htab->free_with_arg_f) (htab->alloc_arg, htab->entries);
+ (*htab->free_with_arg_f) (htab->alloc_arg, htab);
+ }
}
/* This function clears all entries in the given hash table. */
@@ -315,9 +377,20 @@ htab_expand (htab)
oentries = htab->entries;
olimit = oentries + htab->size;
- nsize = higher_prime_number (htab->size * 2);
-
- nentries = (PTR *) (*htab->alloc_f) (nsize, sizeof (PTR));
+ /* Resize only when table after removal of unused elements is either
+ too full or too empty. */
+ if ((htab->n_elements - htab->n_deleted) * 2 > htab->size
+ || ((htab->n_elements - htab->n_deleted) * 8 < htab->size
+ && htab->size > 32))
+ nsize = higher_prime_number ((htab->n_elements - htab->n_deleted) * 2);
+ else
+ nsize = htab->size;
+
+ if (htab->alloc_with_arg_f != NULL)
+ nentries = (PTR *) (*htab->alloc_with_arg_f) (htab->alloc_arg, nsize,
+ sizeof (PTR *));
+ else
+ nentries = (PTR *) (*htab->alloc_f) (nsize, sizeof (PTR *));
if (nentries == NULL)
return 0;
htab->entries = nentries;
@@ -344,6 +417,8 @@ htab_expand (htab)
if (htab->free_f != NULL)
(*htab->free_f) (oentries);
+ else if (htab->free_with_arg_f != NULL)
+ (*htab->free_with_arg_f) (htab->alloc_arg, oentries);
return 1;
}
@@ -460,14 +535,14 @@ htab_find_slot_with_hash (htab, element, hash, insert)
if (insert == NO_INSERT)
return NULL;
- htab->n_elements++;
-
if (first_deleted_slot)
{
+ htab->n_deleted--;
*first_deleted_slot = EMPTY_ENTRY;
return first_deleted_slot;
}
+ htab->n_elements++;
return &htab->entries[index];
}
@@ -532,13 +607,16 @@ htab_clear_slot (htab, slot)
argument. */
void
-htab_traverse (htab, callback, info)
+htab_traverse_noresize (htab, callback, info)
htab_t htab;
htab_trav callback;
PTR info;
{
- PTR *slot = htab->entries;
- PTR *limit = slot + htab->size;
+ PTR *slot;
+ PTR *limit;
+
+ slot = htab->entries;
+ limit = slot + htab->size;
do
{
@@ -551,6 +629,21 @@ htab_traverse (htab, callback, info)
while (++slot < limit);
}
+/* Like htab_traverse_noresize, but does resize the table when it is
+ too empty to improve effectivity of subsequent calls. */
+
+void
+htab_traverse (htab, callback, info)
+ htab_t htab;
+ htab_trav callback;
+ PTR info;
+{
+ if ((htab->n_elements - htab->n_deleted) * 8 < htab->size)
+ htab_expand (htab);
+
+ htab_traverse_noresize (htab, callback, info);
+}
+
/* Return the current size of given hash table. */
size_t
@@ -620,3 +713,141 @@ htab_hash_string (p)
return r;
}
+
+/* DERIVED FROM:
+--------------------------------------------------------------------
+lookup2.c, by Bob Jenkins, December 1996, Public Domain.
+hash(), hash2(), hash3, and mix() are externally useful functions.
+Routines to test the hash are included if SELF_TEST is defined.
+You can use this free for any purpose. It has no warranty.
+--------------------------------------------------------------------
+*/
+
+/*
+--------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+For every delta with one or two bit set, and the deltas of all three
+ high bits or all three low bits, whether the original value of a,b,c
+ is almost all zero or is uniformly distributed,
+* If mix() is run forward or backward, at least 32 bits in a,b,c
+ have at least 1/4 probability of changing.
+* If mix() is run forward, every bit of c will change between 1/3 and
+ 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
+mix() was built out of 36 single-cycle latency instructions in a
+ structure that could supported 2x parallelism, like so:
+ a -= b;
+ a -= c; x = (c>>13);
+ b -= c; a ^= x;
+ b -= a; x = (a<<8);
+ c -= a; b ^= x;
+ c -= b; x = (b>>13);
+ ...
+ Unfortunately, superscalar Pentiums and Sparcs can't take advantage
+ of that parallelism. They've also turned some of those single-cycle
+ latency instructions into multi-cycle latency instructions. Still,
+ this is the fastest good hash I could find. There were about 2^^68
+ to choose from. I only looked at a billion or so.
+--------------------------------------------------------------------
+*/
+/* same, but slower, works on systems that might have 8 byte hashval_t's */
+#define mix(a,b,c) \
+{ \
+ a -= b; a -= c; a ^= (c>>13); \
+ b -= c; b -= a; b ^= (a<< 8); \
+ c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \
+ a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \
+ b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
+ c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
+ a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
+ b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
+ c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
+}
+
+/*
+--------------------------------------------------------------------
+hash() -- hash a variable-length key into a 32-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ len : the length of the key, counting by bytes
+ level : can be any 4-byte value
+Returns a 32-bit value. Every bit of the key affects every bit of
+the return value. Every 1-bit and 2-bit delta achieves avalanche.
+About 36+6len instructions.
+
+The best hash table sizes are powers of 2. There is no need to do
+mod a prime (mod is sooo slow!). If you need less than 32 bits,
+use a bitmask. For example, if you need only 10 bits, do
+ h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (ub1 **)k, do it like this:
+ for (i=0, h=0; i<n; ++i) h = hash( k[i], len[i], h);
+
+By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
+code any way you wish, private, educational, or commercial. It's free.
+
+See http://burtleburtle.net/bob/hash/evahash.html
+Use for hash table lookup, or anything where one collision in 2^32 is
+acceptable. Do NOT use for cryptographic purposes.
+--------------------------------------------------------------------
+*/
+
+hashval_t iterative_hash (k_in, length, initval)
+ const PTR k_in; /* the key */
+ register size_t length; /* the length of the key */
+ register hashval_t initval; /* the previous hash, or an arbitrary value */
+{
+ register const unsigned char *k = (const unsigned char *)k_in;
+ register hashval_t a,b,c,len;
+
+ /* Set up the internal state */
+ len = length;
+ a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
+ c = initval; /* the previous hash value */
+
+ /*---------------------------------------- handle most of the key */
+#ifndef WORDS_BIGENDIAN
+ /* On a little-endian machine, if the data is 4-byte aligned we can hash
+ by word for better speed. This gives nondeterministic results on
+ big-endian machines. */
+ if (sizeof (hashval_t) == 4 && (((size_t)k)&3) == 0)
+ while (len >= 12) /* aligned */
+ {
+ a += *(hashval_t *)(k+0);
+ b += *(hashval_t *)(k+4);
+ c += *(hashval_t *)(k+8);
+ mix(a,b,c);
+ k += 12; len -= 12;
+ }
+ else /* unaligned */
+#endif
+ while (len >= 12)
+ {
+ a += (k[0] +((hashval_t)k[1]<<8) +((hashval_t)k[2]<<16) +((hashval_t)k[3]<<24));
+ b += (k[4] +((hashval_t)k[5]<<8) +((hashval_t)k[6]<<16) +((hashval_t)k[7]<<24));
+ c += (k[8] +((hashval_t)k[9]<<8) +((hashval_t)k[10]<<16)+((hashval_t)k[11]<<24));
+ mix(a,b,c);
+ k += 12; len -= 12;
+ }
+
+ /*------------------------------------- handle the last 11 bytes */
+ c += length;
+ switch(len) /* all the case statements fall through */
+ {
+ case 11: c+=((hashval_t)k[10]<<24);
+ case 10: c+=((hashval_t)k[9]<<16);
+ case 9 : c+=((hashval_t)k[8]<<8);
+ /* the first byte of c is reserved for the length */
+ case 8 : b+=((hashval_t)k[7]<<24);
+ case 7 : b+=((hashval_t)k[6]<<16);
+ case 6 : b+=((hashval_t)k[5]<<8);
+ case 5 : b+=k[4];
+ case 4 : a+=((hashval_t)k[3]<<24);
+ case 3 : a+=((hashval_t)k[2]<<16);
+ case 2 : a+=((hashval_t)k[1]<<8);
+ case 1 : a+=k[0];
+ /* case 0: nothing left to add */
+ }
+ mix(a,b,c);
+ /*-------------------------------------------- report the result */
+ return c;
+}
diff --git a/contrib/gcc/hashtab.h b/contrib/gcc/hashtab.h
index be866b51ee61..f7bd4ae69d38 100644
--- a/contrib/gcc/hashtab.h
+++ b/contrib/gcc/hashtab.h
@@ -1,5 +1,5 @@
/* An expandable hash tables datatype.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
Contributed by Vladimir Makarov (vmakarov@cygnus.com).
This program is free software; you can redistribute it and/or modify
@@ -76,10 +76,16 @@ typedef PTR (*htab_alloc) PARAMS ((size_t, size_t));
/* We also need a free() routine. */
typedef void (*htab_free) PARAMS ((PTR));
+/* Memory allocation and deallocation; variants which take an extra
+ argument. */
+typedef PTR (*htab_alloc_with_arg) PARAMS ((void *, size_t, size_t));
+typedef void (*htab_free_with_arg) PARAMS ((void *, void *));
+
/* Hash tables are of the following type. The structure
(implementation) of this type is not needed for using the hash
tables. All work with hash table should be executed only through
- functions mentioned below. */
+ functions mentioned below. The size of this structure is subject to
+ change. */
struct htab GTY(())
{
@@ -115,6 +121,11 @@ struct htab GTY(())
/* Pointers to allocate/free functions. */
htab_alloc alloc_f;
htab_free free_f;
+
+ /* Alternate allocate/free functions, which take an extra argument. */
+ PTR GTY((skip (""))) alloc_arg;
+ htab_alloc_with_arg alloc_with_arg_f;
+ htab_free_with_arg free_with_arg_f;
};
typedef struct htab *htab_t;
@@ -128,10 +139,20 @@ extern htab_t htab_create_alloc PARAMS ((size_t, htab_hash,
htab_eq, htab_del,
htab_alloc, htab_free));
+extern htab_t htab_create_alloc_ex PARAMS ((size_t, htab_hash,
+ htab_eq, htab_del,
+ PTR, htab_alloc_with_arg,
+ htab_free_with_arg));
+
/* Backward-compatibility functions. */
extern htab_t htab_create PARAMS ((size_t, htab_hash, htab_eq, htab_del));
extern htab_t htab_try_create PARAMS ((size_t, htab_hash, htab_eq, htab_del));
+extern void htab_set_functions_ex PARAMS ((htab_t, htab_hash,
+ htab_eq, htab_del,
+ PTR, htab_alloc_with_arg,
+ htab_free_with_arg));
+
extern void htab_delete PARAMS ((htab_t));
extern void htab_empty PARAMS ((htab_t));
@@ -147,6 +168,7 @@ extern void htab_clear_slot PARAMS ((htab_t, void **));
extern void htab_remove_elt PARAMS ((htab_t, void *));
extern void htab_traverse PARAMS ((htab_t, htab_trav, void *));
+extern void htab_traverse_noresize PARAMS ((htab_t, htab_trav, void *));
extern size_t htab_size PARAMS ((htab_t));
extern size_t htab_elements PARAMS ((htab_t));
@@ -161,6 +183,11 @@ extern htab_eq htab_eq_pointer;
/* A hash function for null-terminated strings. */
extern hashval_t htab_hash_string PARAMS ((const PTR));
+/* An iterative hash function for arbitrary data. */
+extern hashval_t iterative_hash PARAMS ((const PTR, size_t, hashval_t));
+/* Shorthand for hashing something with an intrinsic size. */
+#define iterative_hash_object(OB,INIT) iterative_hash (&OB, sizeof (OB), INIT)
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/contrib/gcc/hashtable.c b/contrib/gcc/hashtable.c
index ed1e81f0d389..58f19d055fc2 100644
--- a/contrib/gcc/hashtable.c
+++ b/contrib/gcc/hashtable.c
@@ -1,5 +1,5 @@
/* Hash tables.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2003 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
@@ -30,39 +30,16 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
existing entry with a potential new one. Also, the ability to
delete members from the table has been removed. */
-static unsigned int calc_hash PARAMS ((const unsigned char *, unsigned int));
-static void ht_expand PARAMS ((hash_table *));
-
-/* Let particular systems override the size of a chunk. */
-#ifndef OBSTACK_CHUNK_SIZE
-#define OBSTACK_CHUNK_SIZE 0
-#endif
- /* Let them override the alloc and free routines too. */
-#ifndef OBSTACK_CHUNK_ALLOC
-#define OBSTACK_CHUNK_ALLOC xmalloc
-#endif
-#ifndef OBSTACK_CHUNK_FREE
-#define OBSTACK_CHUNK_FREE free
-#endif
-
-/* Initialize an obstack. */
-void
-gcc_obstack_init (obstack)
- struct obstack *obstack;
-{
- _obstack_begin (obstack, OBSTACK_CHUNK_SIZE, 0,
- (void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
- (void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
-}
+static unsigned int calc_hash (const unsigned char *, size_t);
+static void ht_expand (hash_table *);
+static double approx_sqrt (double);
/* Calculate the hash of the string STR of length LEN. */
static unsigned int
-calc_hash (str, len)
- const unsigned char *str;
- unsigned int len;
+calc_hash (const unsigned char *str, size_t len)
{
- unsigned int n = len;
+ size_t n = len;
unsigned int r = 0;
#define HASHSTEP(r, c) ((r) * 67 + ((c) - 113));
@@ -76,20 +53,21 @@ calc_hash (str, len)
/* Initialize an identifier hashtable. */
hash_table *
-ht_create (order)
- unsigned int order;
+ht_create (unsigned int order)
{
unsigned int nslots = 1 << order;
hash_table *table;
- table = (hash_table *) xmalloc (sizeof (hash_table));
- memset (table, 0, sizeof (hash_table));
+ table = xcalloc (1, sizeof (hash_table));
/* Strings need no alignment. */
- gcc_obstack_init (&table->stack);
+ _obstack_begin (&table->stack, 0, 0,
+ (void *(*) (long)) xmalloc,
+ (void (*) (void *)) free);
+
obstack_alignment_mask (&table->stack) = 0;
- table->entries = (hashnode *) xcalloc (nslots, sizeof (hashnode));
+ table->entries = xcalloc (nslots, sizeof (hashnode));
table->nslots = nslots;
return table;
}
@@ -97,8 +75,7 @@ ht_create (order)
/* Frees all memory associated with a hash table. */
void
-ht_destroy (table)
- hash_table *table;
+ht_destroy (hash_table *table)
{
obstack_free (&table->stack, NULL);
free (table->entries);
@@ -114,11 +91,8 @@ ht_destroy (table)
CPP_ALLOCED and the item is assumed to be at the top of the
obstack. */
hashnode
-ht_lookup (table, str, len, insert)
- hash_table *table;
- const unsigned char *str;
- unsigned int len;
- enum ht_lookup_option insert;
+ht_lookup (hash_table *table, const unsigned char *str, size_t len,
+ enum ht_lookup_option insert)
{
unsigned int hash = calc_hash (str, len);
unsigned int hash2;
@@ -128,31 +102,46 @@ ht_lookup (table, str, len, insert)
sizemask = table->nslots - 1;
index = hash & sizemask;
-
- /* hash2 must be odd, so we're guaranteed to visit every possible
- location in the table during rehashing. */
- hash2 = ((hash * 17) & sizemask) | 1;
table->searches++;
- for (;;)
+ node = table->entries[index];
+
+ if (node != NULL)
{
- node = table->entries[index];
-
- if (node == NULL)
- break;
-
- if (node->hash_value == hash && HT_LEN (node) == len
- && !memcmp (HT_STR (node), str, len))
+ if (node->hash_value == hash
+ && HT_LEN (node) == (unsigned int) len
+ && !memcmp (HT_STR (node), str, len))
{
if (insert == HT_ALLOCED)
/* The string we search for was placed at the end of the
obstack. Release it. */
- obstack_free (&table->stack, (PTR) str);
+ obstack_free (&table->stack, (void *) str);
return node;
}
- index = (index + hash2) & sizemask;
- table->collisions++;
+ /* hash2 must be odd, so we're guaranteed to visit every possible
+ location in the table during rehashing. */
+ hash2 = ((hash * 17) & sizemask) | 1;
+
+ for (;;)
+ {
+ table->collisions++;
+ index = (index + hash2) & sizemask;
+ node = table->entries[index];
+ if (node == NULL)
+ break;
+
+ if (node->hash_value == hash
+ && HT_LEN (node) == (unsigned int) len
+ && !memcmp (HT_STR (node), str, len))
+ {
+ if (insert == HT_ALLOCED)
+ /* The string we search for was placed at the end of the
+ obstack. Release it. */
+ obstack_free (&table->stack, (void *) str);
+ return node;
+ }
+ }
}
if (insert == HT_NO_INSERT)
@@ -161,7 +150,7 @@ ht_lookup (table, str, len, insert)
node = (*table->alloc_node) (table);
table->entries[index] = node;
- HT_LEN (node) = len;
+ HT_LEN (node) = (unsigned int) len;
node->hash_value = hash;
if (insert == HT_ALLOC)
HT_STR (node) = obstack_copy0 (&table->stack, str, len);
@@ -178,14 +167,13 @@ ht_lookup (table, str, len, insert)
/* Double the size of a hash table, re-hashing existing entries. */
static void
-ht_expand (table)
- hash_table *table;
+ht_expand (hash_table *table)
{
hashnode *nentries, *p, *limit;
unsigned int size, sizemask;
size = table->nslots * 2;
- nentries = (hashnode *) xcalloc (size, sizeof (hashnode));
+ nentries = xcalloc (size, sizeof (hashnode));
sizemask = size - 1;
p = table->entries;
@@ -196,19 +184,18 @@ ht_expand (table)
unsigned int index, hash, hash2;
hash = (*p)->hash_value;
- hash2 = ((hash * 17) & sizemask) | 1;
index = hash & sizemask;
- for (;;)
+ if (nentries[index])
{
- if (! nentries[index])
+ hash2 = ((hash * 17) & sizemask) | 1;
+ do
{
- nentries[index] = *p;
- break;
+ index = (index + hash2) & sizemask;
}
-
- index = (index + hash2) & sizemask;
+ while (nentries[index]);
}
+ nentries[index] = *p;
}
while (++p < limit);
@@ -220,10 +207,7 @@ ht_expand (table)
/* For all nodes in TABLE, callback CB with parameters TABLE->PFILE,
the node, and V. */
void
-ht_forall (table, cb, v)
- hash_table *table;
- ht_cb cb;
- const PTR v;
+ht_forall (hash_table *table, ht_cb cb, const void *v)
{
hashnode *p, *limit;
@@ -241,8 +225,7 @@ ht_forall (table, cb, v)
/* Dump allocation statistics to stderr. */
void
-ht_dump_statistics (table)
- hash_table *table;
+ht_dump_statistics (hash_table *table)
{
size_t nelts, nids, overhead, headers;
size_t total_bytes, longest, sum_of_squares;
@@ -271,7 +254,7 @@ ht_dump_statistics (table)
nids++;
}
while (++p < limit);
-
+
nelts = table->nelements;
overhead = obstack_memory_used (&table->stack) - total_bytes;
headers = table->nslots * sizeof (hashnode);
@@ -306,9 +289,8 @@ ht_dump_statistics (table)
/* Return the approximate positive square root of a number N. This is for
statistical reports, not code generation. */
-double
-approx_sqrt (x)
- double x;
+static double
+approx_sqrt (double x)
{
double s, d;
diff --git a/contrib/gcc/hashtable.h b/contrib/gcc/hashtable.h
index 0649ad2b7da3..8efbf5c50e2e 100644
--- a/contrib/gcc/hashtable.h
+++ b/contrib/gcc/hashtable.h
@@ -1,5 +1,5 @@
/* Hash tables.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2003 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
@@ -19,6 +19,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define GCC_HASHTABLE_H
#include "obstack.h"
+#define GTY(x) /* nothing */
/* This is what each hash table entry points to. It may be embedded
deeply within another object. */
@@ -33,11 +34,6 @@ struct ht_identifier GTY(())
#define HT_LEN(NODE) ((NODE)->len)
#define HT_STR(NODE) ((NODE)->str)
-/* We want code outside cpplib, such as the compiler front-ends, to be
- able to include this header, and to be able to link with
- cpphashtbl.o without pulling in any other parts of cpplib. */
-
-struct cpp_reader;
typedef struct ht hash_table;
typedef struct ht_identifier *hashnode;
@@ -51,7 +47,7 @@ struct ht
hashnode *entries;
/* Call back. */
- hashnode (*alloc_node) PARAMS ((hash_table *));
+ hashnode (*alloc_node) (hash_table *);
unsigned int nslots; /* Total slots in the entries array. */
unsigned int nelements; /* Number of live elements. */
@@ -64,28 +60,22 @@ struct ht
unsigned int collisions;
};
-extern void gcc_obstack_init PARAMS ((struct obstack *));
-
/* Initialize the hashtable with 2 ^ order entries. */
-extern hash_table *ht_create PARAMS ((unsigned int order));
+extern hash_table *ht_create (unsigned int order);
/* Frees all memory associated with a hash table. */
-extern void ht_destroy PARAMS ((hash_table *));
+extern void ht_destroy (hash_table *);
-extern hashnode ht_lookup PARAMS ((hash_table *, const unsigned char *,
- unsigned int, enum ht_lookup_option));
+extern hashnode ht_lookup (hash_table *, const unsigned char *,
+ size_t, enum ht_lookup_option);
/* For all nodes in TABLE, make a callback. The callback takes
TABLE->PFILE, the node, and a PTR, and the callback sequence stops
if the callback returns zero. */
-typedef int (*ht_cb) PARAMS ((struct cpp_reader *, hashnode, const void *));
-extern void ht_forall PARAMS ((hash_table *, ht_cb, const void *));
+typedef int (*ht_cb) (struct cpp_reader *, hashnode, const void *);
+extern void ht_forall (hash_table *, ht_cb, const void *);
/* Dump allocation statistics to stderr. */
-extern void ht_dump_statistics PARAMS ((hash_table *));
-
-/* Approximate positive square root of a host double. This is for
- statistical reports, not code generation. */
-extern double approx_sqrt PARAMS ((double));
+extern void ht_dump_statistics (hash_table *);
#endif /* GCC_HASHTABLE_H */
diff --git a/contrib/gcc/hex.c b/contrib/gcc/hex.c
index 5f8229253494..e4c5dfa2f1dc 100644
--- a/contrib/gcc/hex.c
+++ b/contrib/gcc/hex.c
@@ -19,6 +19,11 @@ Boston, MA 02111-1307, USA. */
#include <stdio.h> /* for EOF */
#include "libiberty.h"
+#include "safe-ctype.h" /* for HOST_CHARSET_ASCII */
+
+#if EOF != -1
+ #error "hex.c requires EOF == -1"
+#endif
/*
@@ -39,13 +44,19 @@ or zero if it is not. Note that the value you pass will be cast to
@end deftypefn
-@deftypefn Extension int hex_value (int @var{c})
+@deftypefn Extension unsigned int hex_value (int @var{c})
Returns the numeric equivalent of the given character when interpreted
as a hexidecimal digit. The result is undefined if you pass an
invalid hex digit. Note that the value you pass will be cast to
@code{unsigned char} within the macro.
+The @code{hex_value} macro returns @code{unsigned int}, rather than
+signed @code{int}, to make it easier to use in parsing addresses from
+hex dump files: a signed @code{int} would be sign-extended when
+converted to a wider unsigned type --- like @code{bfd_vma}, on some
+systems.
+
@end deftypefn
@undocumented _hex_array_size
@@ -56,11 +67,9 @@ invalid hex digit. Note that the value you pass will be cast to
/* Are we ASCII? */
-#if '\n' == 0x0A && ' ' == 0x20 && '0' == 0x30 \
- && 'A' == 0x41 && 'a' == 0x61 && '!' == 0x21 \
- && EOF == -1
+#if HOST_CHARSET == HOST_CHARSET_ASCII
-const char _hex_value[_hex_array_size] =
+const unsigned char _hex_value[_hex_array_size] =
{
_hex_bad, _hex_bad, _hex_bad, _hex_bad, /* NUL SOH STX ETX */
_hex_bad, _hex_bad, _hex_bad, _hex_bad, /* EOT ENQ ACK BEL */
@@ -139,7 +148,7 @@ const char _hex_value[_hex_array_size] =
#else
-char _hex_value[_hex_array_size];
+unsigned char _hex_value[_hex_array_size];
#endif /* not ASCII */
diff --git a/contrib/gcc/hooks.c b/contrib/gcc/hooks.c
index 3f212ef3e1b6..a8cd665a45fa 100644
--- a/contrib/gcc/hooks.c
+++ b/contrib/gcc/hooks.c
@@ -1,5 +1,5 @@
/* General-purpose hooks.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 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
@@ -24,100 +24,206 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "hooks.h"
/* Generic hook that does absolutely zappo. */
void
-hook_void_void ()
+hook_void_void (void)
{
}
/* Generic hook that takes no arguments and returns false. */
bool
-hook_bool_void_false ()
+hook_bool_void_false (void)
{
return false;
}
+/* The same, but formally returning NO_REGS. */
+int
+hook_int_void_no_regs (void)
+{
+ return NO_REGS;
+}
+
+/* Generic hook that takes (bool) and returns false. */
+bool
+hook_bool_bool_false (bool a ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
+
/* Generic hook that takes (tree, int) and does nothing. */
void
-hook_void_tree_int (a, b)
- tree a ATTRIBUTE_UNUSED;
- int b ATTRIBUTE_UNUSED;
+hook_void_tree_int (tree a ATTRIBUTE_UNUSED, int b ATTRIBUTE_UNUSED)
{
}
/* Generic hook that takes (FILE *, const char *) and does nothing. */
void
-hook_void_FILEptr_constcharptr (a, b)
- FILE *a ATTRIBUTE_UNUSED;
- const char *b ATTRIBUTE_UNUSED;
+hook_void_FILEptr_constcharptr (FILE *a ATTRIBUTE_UNUSED, const char *b ATTRIBUTE_UNUSED)
+{
+}
+
+void
+hook_void_constcharptr (const char *a ATTRIBUTE_UNUSED)
{
}
/* Used for the TARGET_ASM_CAN_OUTPUT_MI_THUNK hook. */
bool
-hook_bool_tree_hwi_hwi_tree_false (a, b, c, d)
- tree a ATTRIBUTE_UNUSED;
- HOST_WIDE_INT b ATTRIBUTE_UNUSED;
- HOST_WIDE_INT c ATTRIBUTE_UNUSED;
- tree d ATTRIBUTE_UNUSED;
+hook_bool_tree_hwi_hwi_tree_false (tree a ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT b ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT c ATTRIBUTE_UNUSED,
+ tree d ATTRIBUTE_UNUSED)
{
return false;
}
bool
-hook_bool_tree_hwi_hwi_tree_true (a, b, c, d)
- tree a ATTRIBUTE_UNUSED;
- HOST_WIDE_INT b ATTRIBUTE_UNUSED;
- HOST_WIDE_INT c ATTRIBUTE_UNUSED;
- tree d ATTRIBUTE_UNUSED;
+hook_bool_tree_hwi_hwi_tree_true (tree a ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT b ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT c ATTRIBUTE_UNUSED,
+ tree d ATTRIBUTE_UNUSED)
{
return true;
}
bool
-default_can_output_mi_thunk_no_vcall (a, b, c, d)
- tree a ATTRIBUTE_UNUSED;
- HOST_WIDE_INT b ATTRIBUTE_UNUSED;
- HOST_WIDE_INT c;
- tree d ATTRIBUTE_UNUSED;
+hook_bool_constcharptr_size_t_false (const char *a ATTRIBUTE_UNUSED,
+ size_t b ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
+bool
+default_can_output_mi_thunk_no_vcall (tree a ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT b ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT c,
+ tree d ATTRIBUTE_UNUSED)
{
return c == 0;
}
/* ??? Used for comp_type_attributes, which ought to return bool. */
int
-hook_int_tree_tree_1 (a, b)
- tree a ATTRIBUTE_UNUSED;
- tree b ATTRIBUTE_UNUSED;
+hook_int_tree_tree_1 (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
{
return 1;
}
+int
+hook_int_rtx_0 (rtx a ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+int
+hook_int_void_0 (void)
+{
+ return 0;
+}
+
+int
+hook_int_size_t_constcharptr_int_0 (size_t a ATTRIBUTE_UNUSED,
+ const char *b ATTRIBUTE_UNUSED,
+ int c ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+unsigned int
+hook_uint_uint_constcharptrptr_0 (unsigned int a ATTRIBUTE_UNUSED,
+ const char **b ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
void
-hook_void_tree (a)
- tree a ATTRIBUTE_UNUSED;
+hook_void_tree (tree a ATTRIBUTE_UNUSED)
{
}
void
-hook_void_tree_treeptr (a, b)
- tree a ATTRIBUTE_UNUSED;
- tree *b ATTRIBUTE_UNUSED;
+hook_void_tree_treeptr (tree a ATTRIBUTE_UNUSED, tree *b ATTRIBUTE_UNUSED)
{
}
bool
-hook_bool_tree_false (a)
- tree a ATTRIBUTE_UNUSED;
+hook_bool_tree_false (tree a ATTRIBUTE_UNUSED)
{
return false;
}
bool
-hook_bool_rtx_false (a)
- rtx a ATTRIBUTE_UNUSED;
+hook_bool_tree_true (tree a ATTRIBUTE_UNUSED)
+{
+ return true;
+}
+
+bool
+hook_bool_tree_tree_false (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
+bool
+hook_bool_rtx_false (rtx a ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
+bool
+hook_bool_uintp_uintp_false (unsigned int *a ATTRIBUTE_UNUSED,
+ unsigned int *b ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
+bool
+hook_bool_rtx_int_int_intp_false (rtx a ATTRIBUTE_UNUSED,
+ int b ATTRIBUTE_UNUSED,
+ int c ATTRIBUTE_UNUSED,
+ int *d ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
+/* Generic hook that takes an rtx and returns it. */
+rtx
+hook_rtx_rtx_identity (rtx x)
+{
+ return x;
+}
+
+/* Generic hook that takes an rtx and returns NULL_RTX. */
+rtx
+hook_rtx_rtx_null (rtx x ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+/* Generic hook that takes a tree and an int and returns NULL_RTX. */
+rtx
+hook_rtx_tree_int_null (tree a ATTRIBUTE_UNUSED, int b ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+/* Generic hook that takes a size_t and returns NULL. */
+void *
+hook_voidp_size_t_null (size_t a ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+/* Generic hook that takes a size_t and a pointer and returns false. */
+bool
+hook_bool_voidp_size_t_false (void * a ATTRIBUTE_UNUSED,
+ size_t b ATTRIBUTE_UNUSED)
{
return false;
}
diff --git a/contrib/gcc/hooks.h b/contrib/gcc/hooks.h
index 8c28194f6aca..583b504bffe2 100644
--- a/contrib/gcc/hooks.h
+++ b/contrib/gcc/hooks.h
@@ -1,5 +1,5 @@
/* General-purpose hooks.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 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
@@ -22,23 +22,43 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef GCC_HOOKS_H
#define GCC_HOOKS_H
-bool hook_bool_void_false PARAMS ((void));
-bool hook_bool_tree_false PARAMS ((tree));
-bool hook_bool_tree_hwi_hwi_tree_false
- PARAMS ((tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
-bool hook_bool_tree_hwi_hwi_tree_true
- PARAMS ((tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
-bool hook_bool_rtx_false PARAMS ((rtx));
+extern bool hook_bool_void_false (void);
+extern bool hook_bool_bool_false (bool);
+extern bool hook_bool_tree_false (tree);
+extern bool hook_bool_tree_true (tree);
+extern bool hook_bool_tree_hwi_hwi_tree_false (tree, HOST_WIDE_INT, HOST_WIDE_INT,
+ tree);
+extern bool hook_bool_tree_hwi_hwi_tree_true (tree, HOST_WIDE_INT, HOST_WIDE_INT,
+ tree);
+extern bool hook_bool_rtx_false (rtx);
+extern bool hook_bool_uintp_uintp_false (unsigned int *, unsigned int *);
+extern bool hook_bool_rtx_int_int_intp_false (rtx, int, int, int *);
+extern bool hook_bool_constcharptr_size_t_false (const char *, size_t);
-void hook_void_tree_int PARAMS ((tree, int));
-void hook_void_void PARAMS ((void));
-void hook_void_FILEptr_constcharptr PARAMS ((FILE *, const char *));
-void hook_void_tree PARAMS ((tree));
-void hook_void_tree_treeptr PARAMS ((tree, tree *));
+extern void hook_void_tree_int (tree, int);
+extern void hook_void_void (void);
+extern void hook_void_FILEptr_constcharptr (FILE *, const char *);
+extern void hook_void_tree (tree);
+extern void hook_void_tree_treeptr (tree, tree *);
+extern void hook_void_constcharptr (const char *);
-int hook_int_tree_tree_1 PARAMS ((tree, tree));
+extern int hook_int_tree_tree_1 (tree, tree);
+extern int hook_int_rtx_0 (rtx);
+extern int hook_int_void_0 (void);
+extern int hook_int_size_t_constcharptr_int_0 (size_t, const char *, int);
+extern int hook_int_void_no_regs (void);
-bool default_can_output_mi_thunk_no_vcall
- PARAMS ((tree, HOST_WIDE_INT, HOST_WIDE_INT, tree));
+extern unsigned hook_uint_uint_constcharptrptr_0 (unsigned, const char **);
+
+extern bool default_can_output_mi_thunk_no_vcall (tree, HOST_WIDE_INT,
+ HOST_WIDE_INT, tree);
+
+extern bool hook_bool_tree_tree_false (tree, tree);
+
+extern rtx hook_rtx_rtx_identity (rtx);
+extern rtx hook_rtx_rtx_null (rtx);
+extern rtx hook_rtx_tree_int_null (tree, int);
+extern void * hook_voidp_size_t_null (size_t);
+extern bool hook_bool_voidp_size_t_false (void *, size_t);
#endif
diff --git a/contrib/gcc/host-default.c b/contrib/gcc/host-default.c
new file mode 100644
index 000000000000..b38d13aa0f9d
--- /dev/null
+++ b/contrib/gcc/host-default.c
@@ -0,0 +1,28 @@
+/* Default host-specific hook definitions.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "hosthooks.h"
+#include "hosthooks-def.h"
+
+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
diff --git a/contrib/gcc/hosthooks-def.h b/contrib/gcc/hosthooks-def.h
new file mode 100644
index 000000000000..b1a41e729889
--- /dev/null
+++ b/contrib/gcc/hosthooks-def.h
@@ -0,0 +1,37 @@
+/* Default macros to initialize the lang_hooks data structure.
+ Copyright 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef GCC_HOST_HOOKS_DEF_H
+#define GCC_HOST_HOOKS_DEF_H
+
+#include "hooks.h"
+
+#define HOST_HOOKS_EXTRA_SIGNALS hook_void_void
+#define HOST_HOOKS_GT_PCH_GET_ADDRESS hook_voidp_size_t_null
+#define HOST_HOOKS_GT_PCH_USE_ADDRESS hook_bool_voidp_size_t_false
+
+/* The structure is defined in hosthooks.h. */
+#define HOST_HOOKS_INITIALIZER { \
+ HOST_HOOKS_EXTRA_SIGNALS, \
+ HOST_HOOKS_GT_PCH_GET_ADDRESS, \
+ HOST_HOOKS_GT_PCH_USE_ADDRESS \
+}
+
+#endif /* GCC_HOST_HOOKS_DEF_H */
diff --git a/contrib/gcc/hosthooks.h b/contrib/gcc/hosthooks.h
new file mode 100644
index 000000000000..bbc28f69d4db
--- /dev/null
+++ b/contrib/gcc/hosthooks.h
@@ -0,0 +1,37 @@
+/* The host_hooks data structure.
+ Copyright 2003 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#ifndef GCC_HOST_HOOKS_H
+#define GCC_HOST_HOOKS_H
+
+struct host_hooks
+{
+ void (*extra_signals) (void);
+
+ void * (*gt_pch_get_address) (size_t);
+ bool (*gt_pch_use_address) (void *, size_t);
+
+ /* Whenever you add entries here, make sure you adjust hosthooks-def.h. */
+};
+
+/* Each host provides its own. */
+extern const struct host_hooks host_hooks;
+
+#endif /* GCC_LANG_HOOKS_H */
diff --git a/contrib/gcc/hwint.h b/contrib/gcc/hwint.h
index 6d645a00ea7c..4fed004cbf6c 100644
--- a/contrib/gcc/hwint.h
+++ b/contrib/gcc/hwint.h
@@ -15,152 +15,105 @@
#define HOST_BITS_PER_INT (CHAR_BIT * SIZEOF_INT)
#define HOST_BITS_PER_LONG (CHAR_BIT * SIZEOF_LONG)
+/* If HAVE_LONG_LONG and SIZEOF_LONG_LONG aren't defined, but
+ GCC_VERSION >= 3000, assume this is the second or later stage of a
+ bootstrap, we do have long long, and it's 64 bits. (This is
+ required by C99; we do have some ports that violate that assumption
+ but they're all cross-compile-only.) Just in case, force a
+ constraint violation if that assumption is incorrect. */
+#if !defined HAVE_LONG_LONG
+# if GCC_VERSION >= 3000
+# define HAVE_LONG_LONG 1
+# define SIZEOF_LONG_LONG 8
+extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
+# endif
+#endif
+
#ifdef HAVE_LONG_LONG
# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF_LONG_LONG)
-#else
+#endif
#ifdef HAVE___INT64
-# define HOST_BITS_PER_LONGLONG (CHAR_BIT * SIZEOF___INT64)
-#else
-/* If we're here and we're GCC, assume this is stage 2+ of a bootstrap
- and 'long long' has the width of the *target*'s long long. */
-# if GCC_VERSION > 3000
-# define HOST_BITS_PER_LONGLONG LONG_LONG_TYPE_SIZE
-# endif /* gcc */
+# define HOST_BITS_PER___INT64 (CHAR_BIT * SIZEOF___INT64)
#endif
-#endif /* no long long */
-/* Find the largest host integer type and set its size and type. */
+/* Set HOST_WIDE_INT. This should be the widest efficient host
+ integer type. It can be 32 or 64 bits, except that if we are
+ targeting a machine with 64-bit size_t then it has to be 64 bits.
-/* Use long long on the host if the target has a wider long type than
- the host. */
+ With a sane ABI, 'long' is the largest efficient host integer type.
+ Thus, we use that unless we have to use 'long long' or '__int64'
+ because we're targeting a 64-bit machine from a 32-bit host. */
-#if ! defined HOST_BITS_PER_WIDE_INT \
- && defined HOST_BITS_PER_LONGLONG \
- && (HOST_BITS_PER_LONGLONG > HOST_BITS_PER_LONG) \
- && (defined (LONG_LONG_MAX) || defined (LONGLONG_MAX) \
- || defined (LLONG_MAX) || defined (__GNUC__))
-
-# ifdef MAX_LONG_TYPE_SIZE
-# if MAX_LONG_TYPE_SIZE > HOST_BITS_PER_LONG
-# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONGLONG
-# define HOST_WIDE_INT long long
-# endif
-# else
-# if LONG_TYPE_SIZE > HOST_BITS_PER_LONG
+#if HOST_BITS_PER_LONG >= 64 || !defined NEED_64BIT_HOST_WIDE_INT
+# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
+# define HOST_WIDE_INT long
+#else
+# if HOST_BITS_PER_LONGLONG >= 64
# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONGLONG
# define HOST_WIDE_INT long long
-# endif
-# endif
-
-#endif
-
-#ifndef HOST_BITS_PER_WIDE_INT
-
-# if HOST_BITS_PER_LONG > HOST_BITS_PER_INT
-# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG
-# define HOST_WIDE_INT long
# else
-# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT
-# define HOST_WIDE_INT int
-# endif
-
-#endif /* ! HOST_BITS_PER_WIDE_INT */
-
-/* Provide defaults for the way to print a HOST_WIDE_INT
- in various manners. */
-
-#ifndef HOST_WIDE_INT_PRINT_DEC
-# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
-# define HOST_WIDE_INT_PRINT_DEC "%d"
-# define HOST_WIDE_INT_PRINT_DEC_C "%d"
-# define HOST_WIDE_INT_PRINT_DEC_SPACE "% *d"
-# else
-# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
-# define HOST_WIDE_INT_PRINT_DEC "%ld"
-# define HOST_WIDE_INT_PRINT_DEC_C "%ldL"
-# define HOST_WIDE_INT_PRINT_DEC_SPACE "% *ld"
+# if HOST_BITS_PER___INT64 >= 64
+# define HOST_BITS_PER_WIDE_INT HOST_BITS_PER___INT64
+# define HOST_WIDE_INT __int64
# else
-# define HOST_WIDE_INT_PRINT_DEC "%lld"
-# define HOST_WIDE_INT_PRINT_DEC_C "%lldLL"
-# define HOST_WIDE_INT_PRINT_DEC_SPACE "% *lld"
+ #error "Unable to find a suitable type for HOST_WIDE_INT"
# endif
# endif
-#endif /* ! HOST_WIDE_INT_PRINT_DEC */
+#endif
-#ifndef HOST_WIDE_INT_PRINT_UNSIGNED
-# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
-# define HOST_WIDE_INT_PRINT_UNSIGNED "%u"
-# define HOST_WIDE_INT_PRINT_UNSIGNED_SPACE "% *u"
-# else
-# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
-# define HOST_WIDE_INT_PRINT_UNSIGNED "%lu"
-# define HOST_WIDE_INT_PRINT_UNSIGNED_SPACE "% *lu"
-# else
-# define HOST_WIDE_INT_PRINT_UNSIGNED "%llu"
-# define HOST_WIDE_INT_PRINT_UNSIGNED_SPACE "% *llu"
-# endif
-# endif
-#endif /* ! HOST_WIDE_INT_PRINT_UNSIGNED */
+/* Various printf format strings for HOST_WIDE_INT. */
-#ifndef HOST_WIDE_INT_PRINT_HEX
-# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
-# define HOST_WIDE_INT_PRINT_HEX "0x%x"
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
+# define HOST_WIDE_INT_PRINT "l"
+# define HOST_WIDE_INT_PRINT_C "L"
+ /* 'long' might be 32 or 64 bits, and the number of leading zeroes
+ must be tweaked accordingly. */
+# if HOST_BITS_PER_WIDE_INT == 64
+# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%016lx"
# else
-# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
-# define HOST_WIDE_INT_PRINT_HEX "0x%lx"
-# else
-# define HOST_WIDE_INT_PRINT_HEX "0x%llx"
-# endif
+# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%08lx"
# endif
-#endif /* ! HOST_WIDE_INT_PRINT_HEX */
-
-#ifndef HOST_WIDE_INT_PRINT_DOUBLE_HEX
-# if HOST_BITS_PER_WIDE_INT == 64
-# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
-# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%x%016x"
-# else
-# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
-# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%016lx"
-# else
-# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%llx%016llx"
-# endif
-# endif
+#else
+# define HOST_WIDE_INT_PRINT "ll"
+# define HOST_WIDE_INT_PRINT_C "LL"
+ /* We can assume that 'long long' is at least 64 bits. */
+# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%llx%016llx"
+#endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */
+
+#define HOST_WIDE_INT_PRINT_DEC "%" HOST_WIDE_INT_PRINT "d"
+#define HOST_WIDE_INT_PRINT_DEC_C HOST_WIDE_INT_PRINT_DEC HOST_WIDE_INT_PRINT_C
+#define HOST_WIDE_INT_PRINT_UNSIGNED "%" HOST_WIDE_INT_PRINT "u"
+#define HOST_WIDE_INT_PRINT_HEX "0x%" HOST_WIDE_INT_PRINT "x"
+
+/* Set HOST_WIDEST_INT. This is a 64-bit type unless the compiler
+ in use has no 64-bit type at all; in that case it's 32 bits. */
+
+#if HOST_BITS_PER_WIDE_INT >= 64 \
+ || (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_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
+# define HOST_WIDEST_INT_PRINT_HEX HOST_WIDE_INT_PRINT_HEX
+# define HOST_WIDEST_INT_PRINT_DOUBLE_HEX HOST_WIDE_INT_PRINT_DOUBLE_HEX
+#else
+# if HOST_BITS_PER_LONGLONG >= 64
+# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG
+# define HOST_WIDEST_INT long long
# else
-# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
-# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%x%08x"
+# if HOST_BITS_PER___INT64 >= 64
+# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER___INT64
+# define HOST_WIDEST_INT __int64
# else
-# if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
-# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%lx%08lx"
-# else
-# define HOST_WIDE_INT_PRINT_DOUBLE_HEX "0x%llx%08llx"
-# endif
+ #error "This line should be impossible to reach"
# endif
# endif
-#endif /* ! HOST_WIDE_INT_PRINT_DOUBLE_HEX */
-
-/* Find HOST_WIDEST_INT and set its bit size, type and print macros.
- It will be the largest integer mode supported by the host which may
- (or may not) be larger than HOST_WIDE_INT. */
-
-#ifndef HOST_WIDEST_INT
-#if defined HOST_BITS_PER_LONGLONG \
- && HOST_BITS_PER_LONGLONG > HOST_BITS_PER_LONG
-# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG
-# define HOST_WIDEST_INT long long
-# define HOST_WIDEST_INT_PRINT_DEC "%lld"
-# define HOST_WIDEST_INT_PRINT_DEC_SPACE "% *lld"
-# define HOST_WIDEST_INT_PRINT_UNSIGNED "%llu"
-# define HOST_WIDEST_INT_PRINT_UNSIGNED_SPACE "% *llu"
-# define HOST_WIDEST_INT_PRINT_HEX "0x%llx"
-# else
-# define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONG
-# define HOST_WIDEST_INT long
-# define HOST_WIDEST_INT_PRINT_DEC "%ld"
-# define HOST_WIDEST_INT_PRINT_DEC_SPACE "% *ld"
-# define HOST_WIDEST_INT_PRINT_UNSIGNED "%lu"
-# define HOST_WIDEST_INT_PRINT_UNSIGNED_SPACE "% *lu"
-# define HOST_WIDEST_INT_PRINT_HEX "0x%lx"
-# endif /* long long wider than long */
-#endif /* ! HOST_WIDEST_INT */
+# define HOST_WIDEST_INT_PRINT_DEC "%lld"
+# define HOST_WIDEST_INT_PRINT_DEC_C "%lldLL"
+# define HOST_WIDEST_INT_PRINT_UNSIGNED "%llu"
+# define HOST_WIDEST_INT_PRINT_HEX "0x%llx"
+# define HOST_WIDEST_INT_PRINT_DOUBLE_HEX "0x%llx%016llx"
+#endif
#endif /* ! GCC_HWINT_H */
diff --git a/contrib/gcc/ifcvt.c b/contrib/gcc/ifcvt.c
index c3360043bd72..640ab2cf2f9c 100644
--- a/contrib/gcc/ifcvt.c
+++ b/contrib/gcc/ifcvt.c
@@ -1,5 +1,5 @@
/* If-conversion support.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,6 +20,8 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "regs.h"
@@ -33,8 +35,11 @@
#include "expr.h"
#include "real.h"
#include "output.h"
+#include "optabs.h"
#include "toplev.h"
#include "tm_p.h"
+#include "cfgloop.h"
+#include "target.h"
#ifndef HAVE_conditional_execution
@@ -70,8 +75,8 @@ static int num_possible_if_blocks;
execution. */
static int num_updated_if_blocks;
-/* # of basic blocks that were removed. */
-static int num_removed_blocks;
+/* # of changes made which require life information to be updated. */
+static int num_true_changes;
/* Whether conditional execution changes were made. */
static int cond_exec_changed_p;
@@ -79,51 +84,76 @@ static int cond_exec_changed_p;
/* True if life data ok at present. */
static bool life_data_ok;
-/* The post-dominator relation on the original block numbers. */
-static dominance_info post_dominators;
-
/* Forward references. */
-static int count_bb_insns PARAMS ((basic_block));
-static rtx first_active_insn PARAMS ((basic_block));
-static rtx last_active_insn PARAMS ((basic_block, int));
-static int seq_contains_jump PARAMS ((rtx));
-static basic_block block_fallthru PARAMS ((basic_block));
-static int cond_exec_process_insns PARAMS ((ce_if_block_t *,
- rtx, rtx, rtx, rtx, int));
-static rtx cond_exec_get_condition PARAMS ((rtx));
-static int cond_exec_process_if_block PARAMS ((ce_if_block_t *, int));
-static rtx noce_get_condition PARAMS ((rtx, rtx *));
-static int noce_operand_ok PARAMS ((rtx));
-static int noce_process_if_block PARAMS ((ce_if_block_t *));
-static int process_if_block PARAMS ((ce_if_block_t *));
-static void merge_if_block PARAMS ((ce_if_block_t *));
-static int find_cond_trap PARAMS ((basic_block, edge, edge));
-static basic_block find_if_header PARAMS ((basic_block, int));
-static int block_jumps_and_fallthru_p PARAMS ((basic_block, basic_block));
-static int find_if_block PARAMS ((ce_if_block_t *));
-static int find_if_case_1 PARAMS ((basic_block, edge, edge));
-static int find_if_case_2 PARAMS ((basic_block, edge, edge));
-static int find_memory PARAMS ((rtx *, void *));
-static int dead_or_predicable PARAMS ((basic_block, basic_block,
- basic_block, basic_block, int));
-static void noce_emit_move_insn PARAMS ((rtx, rtx));
-static rtx block_has_only_trap PARAMS ((basic_block));
+static int count_bb_insns (basic_block);
+static rtx first_active_insn (basic_block);
+static rtx last_active_insn (basic_block, int);
+static int seq_contains_jump (rtx);
+static basic_block block_fallthru (basic_block);
+static int cond_exec_process_insns (ce_if_block_t *, rtx, rtx, rtx, rtx, int);
+static rtx cond_exec_get_condition (rtx);
+static int cond_exec_process_if_block (ce_if_block_t *, int);
+static rtx noce_get_condition (rtx, rtx *);
+static int noce_operand_ok (rtx);
+static int noce_process_if_block (ce_if_block_t *);
+static int process_if_block (ce_if_block_t *);
+static void merge_if_block (ce_if_block_t *);
+static int find_cond_trap (basic_block, edge, edge);
+static basic_block find_if_header (basic_block, int);
+static int block_jumps_and_fallthru_p (basic_block, basic_block);
+static int find_if_block (ce_if_block_t *);
+static int find_if_case_1 (basic_block, edge, edge);
+static int find_if_case_2 (basic_block, edge, edge);
+static int find_memory (rtx *, void *);
+static int dead_or_predicable (basic_block, basic_block, basic_block,
+ basic_block, int);
+static void noce_emit_move_insn (rtx, rtx);
+static rtx block_has_only_trap (basic_block);
+static void mark_loop_exit_edges (void);
+/* Sets EDGE_LOOP_EXIT flag for all loop exits. */
+static void
+mark_loop_exit_edges (void)
+{
+ struct loops loops;
+ basic_block bb;
+ edge e;
+
+ flow_loops_find (&loops, LOOP_TREE);
+ free_dominance_info (CDI_DOMINATORS);
+
+ if (loops.num > 1)
+ {
+ FOR_EACH_BB (bb)
+ {
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ if (find_common_loop (bb->loop_father, e->dest->loop_father)
+ != bb->loop_father)
+ e->flags |= EDGE_LOOP_EXIT;
+ else
+ e->flags &= ~EDGE_LOOP_EXIT;
+ }
+ }
+ }
+
+ flow_loops_free (&loops);
+}
+
/* Count the number of non-jump active insns in BB. */
static int
-count_bb_insns (bb)
- basic_block bb;
+count_bb_insns (basic_block bb)
{
int count = 0;
- rtx insn = bb->head;
+ rtx insn = BB_HEAD (bb);
while (1)
{
if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == INSN)
count++;
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
insn = NEXT_INSN (insn);
}
@@ -134,21 +164,20 @@ count_bb_insns (bb)
/* Return the first non-jump active insn in the basic block. */
static rtx
-first_active_insn (bb)
- basic_block bb;
+first_active_insn (basic_block bb)
{
- rtx insn = bb->head;
+ rtx insn = BB_HEAD (bb);
if (GET_CODE (insn) == CODE_LABEL)
{
- if (insn == bb->end)
+ if (insn == BB_END (bb))
return NULL_RTX;
insn = NEXT_INSN (insn);
}
while (GET_CODE (insn) == NOTE)
{
- if (insn == bb->end)
+ if (insn == BB_END (bb))
return NULL_RTX;
insn = NEXT_INSN (insn);
}
@@ -162,12 +191,10 @@ first_active_insn (bb)
/* Return the last non-jump active (non-jump) insn in the basic block. */
static rtx
-last_active_insn (bb, skip_use_p)
- basic_block bb;
- int skip_use_p;
+last_active_insn (basic_block bb, int skip_use_p)
{
- rtx insn = bb->end;
- rtx head = bb->head;
+ rtx insn = BB_END (bb);
+ rtx head = BB_HEAD (bb);
while (GET_CODE (insn) == NOTE
|| GET_CODE (insn) == JUMP_INSN
@@ -186,14 +213,13 @@ last_active_insn (bb, skip_use_p)
return insn;
}
-/* It is possible, especially when having dealt with multi-word
+/* It is possible, especially when having dealt with multi-word
arithmetic, for the expanders to have emitted jumps. Search
through the sequence and return TRUE if a jump exists so that
we can abort the conversion. */
static int
-seq_contains_jump (insn)
- rtx insn;
+seq_contains_jump (rtx insn)
{
while (insn)
{
@@ -205,8 +231,7 @@ seq_contains_jump (insn)
}
static basic_block
-block_fallthru (bb)
- basic_block bb;
+block_fallthru (basic_block bb)
{
edge e;
@@ -223,13 +248,12 @@ block_fallthru (bb)
insns were processed. */
static int
-cond_exec_process_insns (ce_info, start, end, test, prob_val, mod_ok)
- ce_if_block_t *ce_info ATTRIBUTE_UNUSED; /* if block information */
- rtx start; /* first insn to look at */
- rtx end; /* last insn to look at */
- rtx test; /* conditional execution test */
- rtx prob_val; /* probability of branch taken. */
- int mod_ok; /* true if modifications ok last insn. */
+cond_exec_process_insns (ce_if_block_t *ce_info ATTRIBUTE_UNUSED,
+ /* if block information */rtx start,
+ /* first insn to look at */rtx end,
+ /* last insn to look at */rtx test,
+ /* conditional execution test */rtx prob_val,
+ /* probability of branch taken. */int mod_ok)
{
int must_be_last = FALSE;
rtx insn;
@@ -250,7 +274,7 @@ cond_exec_process_insns (ce_info, start, end, test, prob_val, mod_ok)
/* Remove USE insns that get in the way. */
if (reload_completed && GET_CODE (PATTERN (insn)) == USE)
{
- /* ??? Ug. Actually unlinking the thing is problematic,
+ /* ??? Ug. Actually unlinking the thing is problematic,
given what we'd have to coordinate with our callers. */
PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
@@ -314,8 +338,7 @@ cond_exec_process_insns (ce_info, start, end, test, prob_val, mod_ok)
/* Return the condition for a jump. Do not do any special processing. */
static rtx
-cond_exec_get_condition (jump)
- rtx jump;
+cond_exec_get_condition (rtx jump)
{
rtx test_if, cond;
@@ -346,9 +369,8 @@ cond_exec_get_condition (jump)
converting the block. */
static int
-cond_exec_process_if_block (ce_info, do_multiple_p)
- ce_if_block_t * ce_info; /* if block information */
- int do_multiple_p; /* != 0 if we should handle && and || blocks */
+cond_exec_process_if_block (ce_if_block_t * ce_info,
+ /* if block information */int do_multiple_p)
{
basic_block test_bb = ce_info->test_bb; /* last test block */
basic_block then_bb = ce_info->then_bb; /* THEN */
@@ -383,13 +405,13 @@ cond_exec_process_if_block (ce_info, do_multiple_p)
/* Find the conditional jump to the ELSE or JOIN part, and isolate
the test. */
- test_expr = cond_exec_get_condition (test_bb->end);
+ test_expr = cond_exec_get_condition (BB_END (test_bb));
if (! test_expr)
return FALSE;
/* If the conditional jump is more than just a conditional jump,
then we can not do conditional execution conversion on this block. */
- if (! onlyjump_p (test_bb->end))
+ if (! onlyjump_p (BB_END (test_bb)))
return FALSE;
/* Collect the bounds of where we're to search, skipping any labels, jumps
@@ -413,10 +435,10 @@ cond_exec_process_if_block (ce_info, do_multiple_p)
/* Map test_expr/test_jump into the appropriate MD tests to use on
the conditionally executed code. */
-
+
true_expr = test_expr;
- false_code = reversed_comparison_code (true_expr, test_bb->end);
+ false_code = reversed_comparison_code (true_expr, BB_END (test_bb));
if (false_code != UNKNOWN)
false_expr = gen_rtx_fmt_ee (false_code, GET_MODE (true_expr),
XEXP (true_expr, 0), XEXP (true_expr, 1));
@@ -428,12 +450,12 @@ cond_exec_process_if_block (ce_info, do_multiple_p)
conditional execution register from a comparison, it can do so here. */
IFCVT_MODIFY_TESTS (ce_info, true_expr, false_expr);
- /* See if the conversion failed */
+ /* See if the conversion failed. */
if (!true_expr || !false_expr)
goto fail;
#endif
- true_prob_val = find_reg_note (test_bb->end, REG_BR_PROB, NULL_RTX);
+ true_prob_val = find_reg_note (BB_END (test_bb), REG_BR_PROB, NULL_RTX);
if (true_prob_val)
{
true_prob_val = XEXP (true_prob_val, 0);
@@ -467,11 +489,11 @@ cond_exec_process_if_block (ce_info, do_multiple_p)
/* If the conditional jump is more than just a conditional jump, then
we can not do conditional execution conversion on this block. */
- if (! onlyjump_p (bb->end))
+ if (! onlyjump_p (BB_END (bb)))
goto fail;
/* Find the conditional jump and isolate the test. */
- t = cond_exec_get_condition (bb->end);
+ t = cond_exec_get_condition (BB_END (bb));
if (! t)
goto fail;
@@ -497,7 +519,7 @@ cond_exec_process_if_block (ce_info, do_multiple_p)
#ifdef IFCVT_MODIFY_MULTIPLE_TESTS
IFCVT_MODIFY_MULTIPLE_TESTS (ce_info, bb, t, f);
- /* See if the conversion failed */
+ /* See if the conversion failed. */
if (!t || !f)
goto fail;
#endif
@@ -539,7 +561,7 @@ cond_exec_process_if_block (ce_info, do_multiple_p)
}
#ifdef IFCVT_MODIFY_FINAL
- /* Do any machine dependent final modifications */
+ /* Do any machine dependent final modifications. */
IFCVT_MODIFY_FINAL (ce_info);
#endif
@@ -563,10 +585,10 @@ cond_exec_process_if_block (ce_info, do_multiple_p)
return FALSE;
}
-/* Used by noce_process_if_block to communicate with its subroutines.
+/* Used by noce_process_if_block to communicate with its subroutines.
The subroutines know that A and B may be evaluated freely. They
- know that X is a register. They should insert new instructions
+ know that X is a register. They should insert new instructions
before cond_earliest. */
struct noce_if_info
@@ -577,29 +599,25 @@ struct noce_if_info
rtx jump, cond, cond_earliest;
};
-static rtx noce_emit_store_flag PARAMS ((struct noce_if_info *,
- rtx, int, int));
-static int noce_try_store_flag PARAMS ((struct noce_if_info *));
-static int noce_try_store_flag_inc PARAMS ((struct noce_if_info *));
-static int noce_try_store_flag_constants PARAMS ((struct noce_if_info *));
-static int noce_try_store_flag_mask PARAMS ((struct noce_if_info *));
-static rtx noce_emit_cmove PARAMS ((struct noce_if_info *,
- rtx, enum rtx_code, rtx,
- rtx, rtx, rtx));
-static int noce_try_cmove PARAMS ((struct noce_if_info *));
-static int noce_try_cmove_arith PARAMS ((struct noce_if_info *));
-static rtx noce_get_alt_condition PARAMS ((struct noce_if_info *,
- rtx, rtx *));
-static int noce_try_minmax PARAMS ((struct noce_if_info *));
-static int noce_try_abs PARAMS ((struct noce_if_info *));
+static rtx noce_emit_store_flag (struct noce_if_info *, rtx, int, int);
+static int noce_try_move (struct noce_if_info *);
+static int noce_try_store_flag (struct noce_if_info *);
+static int noce_try_addcc (struct noce_if_info *);
+static int noce_try_store_flag_constants (struct noce_if_info *);
+static int noce_try_store_flag_mask (struct noce_if_info *);
+static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx,
+ rtx, rtx, rtx);
+static int noce_try_cmove (struct noce_if_info *);
+static int noce_try_cmove_arith (struct noce_if_info *);
+static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx *);
+static int noce_try_minmax (struct noce_if_info *);
+static int noce_try_abs (struct noce_if_info *);
/* Helper function for noce_try_store_flag*. */
static rtx
-noce_emit_store_flag (if_info, x, reversep, normalize)
- struct noce_if_info *if_info;
- rtx x;
- int reversep, normalize;
+noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep,
+ int normalize)
{
rtx cond = if_info->cond;
int cond_complex;
@@ -655,10 +673,11 @@ noce_emit_store_flag (if_info, x, reversep, normalize)
|| code == GEU || code == GTU), normalize);
}
-/* Emit instruction to move an rtx into STRICT_LOW_PART. */
+/* Emit instruction to move an rtx, possibly into STRICT_LOW_PART.
+ X is the destination/target and Y is the value to copy. */
+
static void
-noce_emit_move_insn (x, y)
- rtx x, y;
+noce_emit_move_insn (rtx x, rtx y)
{
enum machine_mode outmode, inmode;
rtx outer, inner;
@@ -679,6 +698,69 @@ noce_emit_move_insn (x, y)
GET_MODE_BITSIZE (inmode));
}
+/* Unshare sequence SEQ produced by if conversion. We care to mark
+ all arguments that may be shared with outer instruction stream. */
+static void
+unshare_ifcvt_sequence (struct noce_if_info *if_info, rtx seq)
+{
+ set_used_flags (if_info->x);
+ set_used_flags (if_info->cond);
+ unshare_all_rtl_in_chain (seq);
+}
+
+/* Convert "if (a != b) x = a; else x = b" into "x = a" and
+ "if (a == b) x = a; else x = b" into "x = b". */
+
+static int
+noce_try_move (struct noce_if_info *if_info)
+{
+ rtx cond = if_info->cond;
+ enum rtx_code code = GET_CODE (cond);
+ rtx y, seq;
+
+ if (code != NE && code != EQ)
+ return FALSE;
+
+ /* This optimization isn't valid if either A or B could be a NaN
+ or a signed zero. */
+ if (HONOR_NANS (GET_MODE (if_info->x))
+ || HONOR_SIGNED_ZEROS (GET_MODE (if_info->x)))
+ return FALSE;
+
+ /* Check whether the operands of the comparison are A and in
+ either order. */
+ if ((rtx_equal_p (if_info->a, XEXP (cond, 0))
+ && rtx_equal_p (if_info->b, XEXP (cond, 1)))
+ || (rtx_equal_p (if_info->a, XEXP (cond, 1))
+ && rtx_equal_p (if_info->b, XEXP (cond, 0))))
+ {
+ y = (code == EQ) ? if_info->a : if_info->b;
+
+ /* Avoid generating the move if the source is the destination. */
+ if (! rtx_equal_p (if_info->x, y))
+ {
+ start_sequence ();
+ noce_emit_move_insn (if_info->x, y);
+ seq = get_insns ();
+ unshare_ifcvt_sequence (if_info, seq);
+ end_sequence ();
+
+ /* Make sure that all of the instructions emitted are
+ recognizable. As an excersise for the reader, build
+ a general mechanism that allows proper placement of
+ required clobbers. */
+ for (y = seq; y ; y = NEXT_INSN (y))
+ if (recog_memoized (y) == -1)
+ return FALSE;
+
+ emit_insn_before_setloc (seq, if_info->jump,
+ INSN_LOCATOR (if_info->insn_a));
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
/* Convert "if (test) x = 1; else x = 0".
Only try 0 and STORE_FLAG_VALUE here. Other combinations will be
@@ -686,8 +768,7 @@ noce_emit_move_insn (x, y)
a go at the conversion. */
static int
-noce_try_store_flag (if_info)
- struct noce_if_info *if_info;
+noce_try_store_flag (struct noce_if_info *if_info)
{
int reversep;
rtx target, seq;
@@ -714,8 +795,9 @@ noce_try_store_flag (if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
+ unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
- emit_insn_before_scope (seq, if_info->jump, INSN_SCOPE (if_info->insn_a));
+ emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
return TRUE;
}
@@ -729,8 +811,7 @@ noce_try_store_flag (if_info)
/* Convert "if (test) x = a; else x = b", for A and B constant. */
static int
-noce_try_store_flag_constants (if_info)
- struct noce_if_info *if_info;
+noce_try_store_flag_constants (struct noce_if_info *if_info)
{
rtx target, seq;
int reversep;
@@ -780,7 +861,7 @@ noce_try_store_flag_constants (if_info)
return FALSE;
if (reversep)
- {
+ {
tmp = itrue; itrue = ifalse; ifalse = tmp;
diff = trunc_int_for_mode (-diff, mode);
}
@@ -845,12 +926,13 @@ noce_try_store_flag_constants (if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
+ unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
if (seq_contains_jump (seq))
return FALSE;
- emit_insn_before_scope (seq, if_info->jump, INSN_SCOPE (if_info->insn_a));
+ emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
return TRUE;
}
@@ -858,65 +940,96 @@ noce_try_store_flag_constants (if_info)
return FALSE;
}
-/* Convert "if (test) foo++" into "foo += (test != 0)", and
+/* Convert "if (test) foo++" into "foo += (test != 0)", and
similarly for "foo--". */
static int
-noce_try_store_flag_inc (if_info)
- struct noce_if_info *if_info;
+noce_try_addcc (struct noce_if_info *if_info)
{
rtx target, seq;
int subtract, normalize;
if (! no_new_pseudos
- && (BRANCH_COST >= 2
- || HAVE_incscc
- || HAVE_decscc)
- /* Should be no `else' case to worry about. */
- && if_info->b == if_info->x
&& GET_CODE (if_info->a) == PLUS
- && (XEXP (if_info->a, 1) == const1_rtx
- || XEXP (if_info->a, 1) == constm1_rtx)
- && rtx_equal_p (XEXP (if_info->a, 0), if_info->x)
+ && rtx_equal_p (XEXP (if_info->a, 0), if_info->b)
&& (reversed_comparison_code (if_info->cond, if_info->jump)
!= UNKNOWN))
{
- if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
- subtract = 0, normalize = 0;
- else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
- subtract = 1, normalize = 0;
- else
- subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1));
-
- start_sequence ();
-
- target = noce_emit_store_flag (if_info,
- gen_reg_rtx (GET_MODE (if_info->x)),
- 1, normalize);
+ rtx cond = if_info->cond;
+ enum rtx_code code = reversed_comparison_code (cond, if_info->jump);
- if (target)
- target = expand_simple_binop (GET_MODE (if_info->x),
- subtract ? MINUS : PLUS,
- if_info->x, target, if_info->x,
- 0, OPTAB_WIDEN);
- if (target)
+ /* First try to use addcc pattern. */
+ if (general_operand (XEXP (cond, 0), VOIDmode)
+ && general_operand (XEXP (cond, 1), VOIDmode))
{
- if (target != if_info->x)
- noce_emit_move_insn (if_info->x, target);
-
- seq = get_insns ();
+ start_sequence ();
+ target = emit_conditional_add (if_info->x, code,
+ XEXP (cond, 0),
+ XEXP (cond, 1),
+ VOIDmode,
+ if_info->b,
+ XEXP (if_info->a, 1),
+ GET_MODE (if_info->x),
+ (code == LTU || code == GEU
+ || code == LEU || code == GTU));
+ if (target)
+ {
+ if (target != if_info->x)
+ noce_emit_move_insn (if_info->x, target);
+
+ seq = get_insns ();
+ unshare_ifcvt_sequence (if_info, seq);
+ end_sequence ();
+ emit_insn_before_setloc (seq, if_info->jump,
+ INSN_LOCATOR (if_info->insn_a));
+ return TRUE;
+ }
end_sequence ();
+ }
- if (seq_contains_jump (seq))
- return FALSE;
+ /* If that fails, construct conditional increment or decrement using
+ setcc. */
+ if (BRANCH_COST >= 2
+ && (XEXP (if_info->a, 1) == const1_rtx
+ || XEXP (if_info->a, 1) == constm1_rtx))
+ {
+ start_sequence ();
+ if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
+ subtract = 0, normalize = 0;
+ else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
+ subtract = 1, normalize = 0;
+ else
+ subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1));
- emit_insn_before_scope (seq, if_info->jump,
- INSN_SCOPE (if_info->insn_a));
- return TRUE;
- }
+ target = noce_emit_store_flag (if_info,
+ gen_reg_rtx (GET_MODE (if_info->x)),
+ 1, normalize);
- end_sequence ();
+ if (target)
+ target = expand_simple_binop (GET_MODE (if_info->x),
+ subtract ? MINUS : PLUS,
+ if_info->b, target, if_info->x,
+ 0, OPTAB_WIDEN);
+ if (target)
+ {
+ if (target != if_info->x)
+ noce_emit_move_insn (if_info->x, target);
+
+ seq = get_insns ();
+ unshare_ifcvt_sequence (if_info, seq);
+ end_sequence ();
+
+ if (seq_contains_jump (seq))
+ return FALSE;
+
+ emit_insn_before_setloc (seq, if_info->jump,
+ INSN_LOCATOR (if_info->insn_a));
+
+ return TRUE;
+ }
+ end_sequence ();
+ }
}
return FALSE;
@@ -925,8 +1038,7 @@ noce_try_store_flag_inc (if_info)
/* Convert "if (test) x = 0;" to "x &= -(test == 0);" */
static int
-noce_try_store_flag_mask (if_info)
- struct noce_if_info *if_info;
+noce_try_store_flag_mask (struct noce_if_info *if_info)
{
rtx target, seq;
int reversep;
@@ -949,7 +1061,8 @@ noce_try_store_flag_mask (if_info)
reversep, -1);
if (target)
target = expand_simple_binop (GET_MODE (if_info->x), AND,
- if_info->x, target, if_info->x, 0,
+ if_info->x,
+ target, if_info->x, 0,
OPTAB_WIDEN);
if (target)
@@ -958,13 +1071,14 @@ noce_try_store_flag_mask (if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
+ unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
if (seq_contains_jump (seq))
return FALSE;
- emit_insn_before_scope (seq, if_info->jump,
- INSN_SCOPE (if_info->insn_a));
+ emit_insn_before_setloc (seq, if_info->jump,
+ INSN_LOCATOR (if_info->insn_a));
return TRUE;
}
@@ -978,10 +1092,8 @@ noce_try_store_flag_mask (if_info)
/* Helper function for noce_try_cmove and noce_try_cmove_arith. */
static rtx
-noce_emit_cmove (if_info, x, code, cmp_a, cmp_b, vfalse, vtrue)
- struct noce_if_info *if_info;
- rtx x, cmp_a, cmp_b, vfalse, vtrue;
- enum rtx_code code;
+noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
+ rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue)
{
/* If earliest == jump, try to build the cmove insn directly.
This is helpful when combine has created some complex condition
@@ -1024,7 +1136,7 @@ noce_emit_cmove (if_info, x, code, cmp_a, cmp_b, vfalse, vtrue)
#else
/* We'll never get here, as noce_process_if_block doesn't call the
functions involved. Ifdef code, however, should be discouraged
- because it leads to typos in the code not selected. However,
+ because it leads to typos in the code not selected. However,
emit_conditional_move won't exist either. */
return NULL_RTX;
#endif
@@ -1035,8 +1147,7 @@ noce_emit_cmove (if_info, x, code, cmp_a, cmp_b, vfalse, vtrue)
has had a go at it. */
static int
-noce_try_cmove (if_info)
- struct noce_if_info *if_info;
+noce_try_cmove (struct noce_if_info *if_info)
{
enum rtx_code code;
rtx target, seq;
@@ -1058,9 +1169,10 @@ noce_try_cmove (if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
+ unshare_ifcvt_sequence (if_info, seq);
end_sequence ();
- emit_insn_before_scope (seq, if_info->jump,
- INSN_SCOPE (if_info->insn_a));
+ emit_insn_before_setloc (seq, if_info->jump,
+ INSN_LOCATOR (if_info->insn_a));
return TRUE;
}
else
@@ -1076,8 +1188,7 @@ noce_try_cmove (if_info)
/* Try more complex cases involving conditional_move. */
static int
-noce_try_cmove_arith (if_info)
- struct noce_if_info *if_info;
+noce_try_cmove_arith (struct noce_if_info *if_info)
{
rtx a = if_info->a;
rtx b = if_info->b;
@@ -1113,7 +1224,7 @@ noce_try_cmove_arith (if_info)
if (test)
x = y;
*/
-
+
code = GET_CODE (if_info->cond);
insn_a = if_info->insn_a;
insn_b = if_info->insn_b;
@@ -1139,7 +1250,7 @@ noce_try_cmove_arith (if_info)
/* If either operand is complex, load it into a register first.
The best way to do this is to copy the original insn. In this
- way we preserve any clobbers etc that the insn may have had.
+ way we preserve any clobbers etc that the insn may have had.
This is of course not possible in the IS_MEM case. */
if (! general_operand (a, GET_MODE (a)))
{
@@ -1176,18 +1287,11 @@ noce_try_cmove_arith (if_info)
if (is_mem)
{
tmp = gen_reg_rtx (GET_MODE (b));
- tmp = emit_insn (gen_rtx_SET (VOIDmode, tmp, b));
+ tmp = emit_insn (gen_rtx_SET (VOIDmode,
+ tmp,
+ b));
}
- else if (! insn_b
-#if 0
- /* In the case we are going to duplicate insn originally
- present in the front of comparsion, verify that the
- comparsion didn't clobbered the operands. */
- || modified_between_p (SET_SRC (single_set (insn_b)),
- if_info->cond_earliest,
- NEXT_INSN (if_info->jump)))
-#endif
- )
+ else if (! insn_b)
goto end_seq_and_fail;
else
{
@@ -1230,8 +1334,9 @@ noce_try_cmove_arith (if_info)
noce_emit_move_insn (x, target);
tmp = get_insns ();
+ unshare_ifcvt_sequence (if_info, tmp);
end_sequence ();
- emit_insn_before_scope (tmp, if_info->jump, INSN_SCOPE (if_info->insn_a));
+ emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR (if_info->insn_a));
return TRUE;
end_seq_and_fail:
@@ -1244,10 +1349,8 @@ noce_try_cmove_arith (if_info)
For these we wish to know that it is A or B in the condition. */
static rtx
-noce_get_alt_condition (if_info, target, earliest)
- struct noce_if_info *if_info;
- rtx target;
- rtx *earliest;
+noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
+ rtx *earliest)
{
rtx cond, set, insn;
int reverse;
@@ -1368,7 +1471,7 @@ noce_get_alt_condition (if_info, target, earliest)
}
cond = canonicalize_condition (if_info->jump, cond, reverse,
- earliest, target);
+ earliest, target, false);
if (! cond || ! reg_mentioned_p (target, cond))
return NULL;
@@ -1393,9 +1496,8 @@ noce_get_alt_condition (if_info, target, earliest)
/* Convert "if (a < b) x = a; else x = b;" to "x = min(a, b);", etc. */
static int
-noce_try_minmax (if_info)
- struct noce_if_info *if_info;
-{
+noce_try_minmax (struct noce_if_info *if_info)
+{
rtx cond, earliest, target, seq;
enum rtx_code code, op;
int unsignedp;
@@ -1478,12 +1580,13 @@ noce_try_minmax (if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
- end_sequence ();
+ unshare_ifcvt_sequence (if_info, seq);
+ end_sequence ();
if (seq_contains_jump (seq))
return FALSE;
- emit_insn_before_scope (seq, if_info->jump, INSN_SCOPE (if_info->insn_a));
+ emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
if_info->cond = cond;
if_info->cond_earliest = earliest;
@@ -1493,9 +1596,8 @@ noce_try_minmax (if_info)
/* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", etc. */
static int
-noce_try_abs (if_info)
- struct noce_if_info *if_info;
-{
+noce_try_abs (struct noce_if_info *if_info)
+{
rtx cond, earliest, target, seq, a, b, c;
int negate;
@@ -1515,7 +1617,7 @@ noce_try_abs (if_info)
}
else
return FALSE;
-
+
cond = noce_get_alt_condition (if_info, b, &earliest);
if (!cond)
return FALSE;
@@ -1534,9 +1636,9 @@ noce_try_abs (if_info)
{
rtx insn, note = NULL;
for (insn = earliest;
- insn != if_info->test_bb->head;
+ insn != BB_HEAD (if_info->test_bb);
insn = PREV_INSN (insn))
- if (INSN_P (insn)
+ if (INSN_P (insn)
&& ((note = find_reg_note (insn, REG_EQUAL, c))
|| (note = find_reg_note (insn, REG_EQUIV, c))))
break;
@@ -1550,7 +1652,7 @@ noce_try_abs (if_info)
c = get_pool_constant (XEXP (c, 0));
/* Work around funny ideas get_condition has wrt canonicalization.
- Note that these rtx constants are known to be CONST_INT, and
+ Note that these rtx constants are known to be CONST_INT, and
therefore imply integer comparisons. */
if (c == constm1_rtx && GET_CODE (cond) == GT)
;
@@ -1579,9 +1681,9 @@ noce_try_abs (if_info)
start_sequence ();
- target = expand_simple_unop (GET_MODE (if_info->x), ABS, b, if_info->x, 0);
+ target = expand_abs_nojump (GET_MODE (if_info->x), b, if_info->x, 1);
- /* ??? It's a quandry whether cmove would be better here, especially
+ /* ??? It's a quandary whether cmove would be better here, especially
for integers. Perhaps combine will clean things up. */
if (target && negate)
target = expand_simple_unop (GET_MODE (target), NEG, target, if_info->x, 0);
@@ -1596,12 +1698,13 @@ noce_try_abs (if_info)
noce_emit_move_insn (if_info->x, target);
seq = get_insns ();
- end_sequence ();
+ unshare_ifcvt_sequence (if_info, seq);
+ end_sequence ();
if (seq_contains_jump (seq))
return FALSE;
- emit_insn_before_scope (seq, if_info->jump, INSN_SCOPE (if_info->insn_a));
+ emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
if_info->cond = cond;
if_info->cond_earliest = earliest;
@@ -1612,9 +1715,7 @@ noce_try_abs (if_info)
valid at JUMP, instead of at EARLIEST. */
static rtx
-noce_get_condition (jump, earliest)
- rtx jump;
- rtx *earliest;
+noce_get_condition (rtx jump, rtx *earliest)
{
rtx cond, set, tmp, insn;
bool reverse;
@@ -1646,7 +1747,8 @@ noce_get_condition (jump, earliest)
/* Otherwise, fall back on canonicalize_condition to do the dirty
work of manipulating MODE_CC values and COMPARE rtx codes. */
- tmp = canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX);
+ tmp = canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX,
+ false);
if (!tmp)
return NULL_RTX;
@@ -1665,7 +1767,8 @@ noce_get_condition (jump, earliest)
tmp = XEXP (tmp, 0);
if (!REG_P (tmp) || GET_MODE_CLASS (GET_MODE (tmp)) != MODE_INT)
return NULL_RTX;
- tmp = canonicalize_condition (jump, cond, reverse, earliest, tmp);
+ tmp = canonicalize_condition (jump, cond, reverse, earliest, tmp,
+ false);
if (!tmp)
return NULL_RTX;
@@ -1680,8 +1783,7 @@ noce_get_condition (jump, earliest)
/* Return true if OP is ok for if-then-else processing. */
static int
-noce_operand_ok (op)
- rtx op;
+noce_operand_ok (rtx op)
{
/* We special-case memories, so handle any of them with
no address side effects. */
@@ -1699,8 +1801,7 @@ noce_operand_ok (op)
successful at converting the block. */
static int
-noce_process_if_block (ce_info)
- struct ce_if_block * ce_info;
+noce_process_if_block (struct ce_if_block * ce_info)
{
basic_block test_bb = ce_info->test_bb; /* test block */
basic_block then_bb = ce_info->then_bb; /* THEN */
@@ -1735,7 +1836,7 @@ noce_process_if_block (ce_info)
}
/* If this is not a standard conditional jump, we can't parse it. */
- jump = test_bb->end;
+ jump = BB_END (test_bb);
cond = noce_get_condition (jump, &if_info.cond_earliest);
if (! cond)
return FALSE;
@@ -1800,7 +1901,7 @@ noce_process_if_block (ce_info)
/* If x has side effects then only the if-then-else form is safe to
convert. But even in that case we would need to restore any notes
- (such as REG_INC) at then end. That can be tricky if
+ (such as REG_INC) at then end. That can be tricky if
noce_emit_move_insn expands to more than one insn, so disable the
optimization entirely for now if there are side effects. */
if (side_effects_p (x))
@@ -1815,7 +1916,7 @@ noce_process_if_block (ce_info)
|| (SMALL_REGISTER_CLASSES
&& REGNO (x) < FIRST_PSEUDO_REGISTER))
{
- if (no_new_pseudos)
+ if (no_new_pseudos || GET_MODE (x) == BLKmode)
return FALSE;
x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART
? XEXP (x, 0) : x));
@@ -1851,8 +1952,8 @@ noce_process_if_block (ce_info)
{
rtx note;
- if (else_bb && insn_b == else_bb->end)
- else_bb->end = PREV_INSN (insn_b);
+ if (else_bb && insn_b == BB_END (else_bb))
+ BB_END (else_bb) = PREV_INSN (insn_b);
reorder_insns (insn_b, insn_b, PREV_INSN (jump));
/* If there was a REG_EQUAL note, delete it since it may have been
@@ -1866,11 +1967,32 @@ noce_process_if_block (ce_info)
x must be executed twice. */
else if (insn_b && side_effects_p (orig_x))
return FALSE;
-
+
x = orig_x;
goto success;
}
+ /* Disallow the "if (...) x = a;" form (with an implicit "else x = x;")
+ for most optimizations if writing to x may trap, i.e. its a memory
+ other than a static var or a stack slot. */
+ if (! set_b
+ && GET_CODE (orig_x) == MEM
+ && ! MEM_NOTRAP_P (orig_x)
+ && rtx_addr_can_trap_p (XEXP (orig_x, 0)))
+ {
+ if (HAVE_conditional_move)
+ {
+ if (noce_try_cmove (&if_info))
+ goto success;
+ if (! HAVE_conditional_execution
+ && noce_try_cmove_arith (&if_info))
+ goto success;
+ }
+ return FALSE;
+ }
+
+ if (noce_try_move (&if_info))
+ goto success;
if (noce_try_store_flag (&if_info))
goto success;
if (noce_try_minmax (&if_info))
@@ -1884,7 +2006,7 @@ noce_process_if_block (ce_info)
{
if (noce_try_store_flag_constants (&if_info))
goto success;
- if (noce_try_store_flag_inc (&if_info))
+ if (noce_try_addcc (&if_info))
goto success;
if (noce_try_store_flag_mask (&if_info))
goto success;
@@ -1917,11 +2039,13 @@ noce_process_if_block (ce_info)
if (orig_x != x)
{
start_sequence ();
- noce_emit_move_insn (copy_rtx (orig_x), x);
+ noce_emit_move_insn (orig_x, x);
insn_b = get_insns ();
+ set_used_flags (orig_x);
+ unshare_all_rtl_in_chain (insn_b);
end_sequence ();
- emit_insn_after_scope (insn_b, test_bb->end, INSN_SCOPE (insn_a));
+ emit_insn_after_setloc (insn_b, BB_END (test_bb), INSN_LOCATOR (insn_a));
}
/* Merge the blocks! */
@@ -1934,8 +2058,7 @@ noce_process_if_block (ce_info)
straight line code. Return true if successful. */
static int
-process_if_block (ce_info)
- struct ce_if_block * ce_info;
+process_if_block (struct ce_if_block * ce_info)
{
if (! reload_completed
&& noce_process_if_block (ce_info))
@@ -1965,8 +2088,7 @@ process_if_block (ce_info)
/* Merge the blocks and mark for local life update. */
static void
-merge_if_block (ce_info)
- struct ce_if_block * ce_info;
+merge_if_block (struct ce_if_block * ce_info)
{
basic_block test_bb = ce_info->test_bb; /* last test block */
basic_block then_bb = ce_info->then_bb; /* THEN */
@@ -1985,15 +2107,15 @@ merge_if_block (ce_info)
basic_block bb = test_bb;
basic_block last_test_bb = ce_info->last_test_bb;
basic_block fallthru = block_fallthru (bb);
-
+
do
{
bb = fallthru;
fallthru = block_fallthru (bb);
- if (post_dominators)
- delete_from_dominance_info (post_dominators, bb);
- merge_blocks_nomove (combo_bb, bb);
- num_removed_blocks++;
+ if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+ delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
+ merge_blocks (combo_bb, bb);
+ num_true_changes++;
}
while (bb != last_test_bb);
}
@@ -2007,10 +2129,10 @@ merge_if_block (ce_info)
if (combo_bb->global_live_at_end)
COPY_REG_SET (combo_bb->global_live_at_end,
then_bb->global_live_at_end);
- if (post_dominators)
- delete_from_dominance_info (post_dominators, then_bb);
- merge_blocks_nomove (combo_bb, then_bb);
- num_removed_blocks++;
+ if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+ delete_from_dominance_info (CDI_POST_DOMINATORS, then_bb);
+ merge_blocks (combo_bb, then_bb);
+ num_true_changes++;
}
/* The ELSE block, if it existed, had a label. That label count
@@ -2018,10 +2140,10 @@ merge_if_block (ce_info)
get their addresses taken. */
if (else_bb)
{
- if (post_dominators)
- delete_from_dominance_info (post_dominators, else_bb);
- merge_blocks_nomove (combo_bb, else_bb);
- num_removed_blocks++;
+ if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+ delete_from_dominance_info (CDI_POST_DOMINATORS, else_bb);
+ merge_blocks (combo_bb, else_bb);
+ num_true_changes++;
}
/* If there was no join block reported, that means it was not adjacent
@@ -2029,7 +2151,7 @@ merge_if_block (ce_info)
if (! join_bb)
{
- rtx last = combo_bb->end;
+ rtx last = BB_END (combo_bb);
/* The outgoing edge for the current COMBO block should already
be correct. Verify this. */
@@ -2064,7 +2186,7 @@ merge_if_block (ce_info)
Since we've already merged the TEST, THEN and ELSE blocks, we should
have only one remaining edge from our if-then-else diamond. If there
is more than one remaining edge, it must come from elsewhere. There
- may be zero incoming edges if the THEN block didn't actually join
+ may be zero incoming edges if the THEN block didn't actually join
back up (as with a call to abort). */
else if ((join_bb->pred == NULL
|| join_bb->pred->pred_next == NULL)
@@ -2075,10 +2197,10 @@ merge_if_block (ce_info)
COPY_REG_SET (combo_bb->global_live_at_end,
join_bb->global_live_at_end);
- if (post_dominators)
- delete_from_dominance_info (post_dominators, join_bb);
- merge_blocks_nomove (combo_bb, join_bb);
- num_removed_blocks++;
+ if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+ delete_from_dominance_info (CDI_POST_DOMINATORS, join_bb);
+ merge_blocks (combo_bb, join_bb);
+ num_true_changes++;
}
else
{
@@ -2104,9 +2226,7 @@ merge_if_block (ce_info)
first block if some transformation was done. Return NULL otherwise. */
static basic_block
-find_if_header (test_bb, pass)
- basic_block test_bb;
- int pass;
+find_if_header (basic_block test_bb, int pass)
{
ce_if_block_t ce_info;
edge then_edge;
@@ -2123,6 +2243,11 @@ find_if_header (test_bb, pass)
|| (else_edge->flags & EDGE_COMPLEX))
return NULL;
+ /* Nor exit the loop. */
+ if ((then_edge->flags & EDGE_LOOP_EXIT)
+ || (else_edge->flags & EDGE_LOOP_EXIT))
+ return NULL;
+
/* The THEN edge is canonically the one that falls through. */
if (then_edge->flags & EDGE_FALLTHRU)
;
@@ -2136,7 +2261,7 @@ find_if_header (test_bb, pass)
/* Otherwise this must be a multiway branch of some sort. */
return NULL;
- memset ((PTR) &ce_info, '\0', sizeof (ce_info));
+ memset (&ce_info, '\0', sizeof (ce_info));
ce_info.test_bb = test_bb;
ce_info.then_bb = then_edge->dest;
ce_info.else_bb = else_edge->dest;
@@ -2153,7 +2278,7 @@ find_if_header (test_bb, pass)
&& find_cond_trap (test_bb, then_edge, else_edge))
goto success;
- if (post_dominators
+ if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY
&& (! HAVE_conditional_execution || reload_completed))
{
if (find_if_case_1 (test_bb, then_edge, else_edge))
@@ -2176,9 +2301,7 @@ find_if_header (test_bb, pass)
of non-note, non-jump, non-USE/CLOBBER insns in the block. */
static int
-block_jumps_and_fallthru_p (cur_bb, target_bb)
- basic_block cur_bb;
- basic_block target_bb;
+block_jumps_and_fallthru_p (basic_block cur_bb, basic_block target_bb)
{
edge cur_edge;
int fallthru_p = FALSE;
@@ -2219,8 +2342,8 @@ block_jumps_and_fallthru_p (cur_bb, target_bb)
together for conditional execution support. ??? we should support
conditional execution support across calls for IA-64 some day, but
for now it makes the code simpler. */
- end = cur_bb->end;
- insn = cur_bb->head;
+ end = BB_END (cur_bb);
+ insn = BB_HEAD (cur_bb);
while (insn != NULL_RTX)
{
@@ -2247,8 +2370,7 @@ block_jumps_and_fallthru_p (cur_bb, target_bb)
Return TRUE if we were successful at converting the block. */
static int
-find_if_block (ce_info)
- struct ce_if_block * ce_info;
+find_if_block (struct ce_if_block * ce_info)
{
basic_block test_bb = ce_info->test_bb;
basic_block then_bb = ce_info->then_bb;
@@ -2276,7 +2398,7 @@ find_if_block (ce_info)
int max_insns = MAX_CONDITIONAL_EXECUTE;
int n_insns;
- /* Determine if the preceeding block is an && or || block. */
+ /* Determine if the preceding block is an && or || block. */
if ((n_insns = block_jumps_and_fallthru_p (bb, else_bb)) >= 0)
{
ce_info->and_and_p = TRUE;
@@ -2284,7 +2406,7 @@ find_if_block (ce_info)
}
else if ((n_insns = block_jumps_and_fallthru_p (bb, then_bb)) >= 0)
{
- ce_info->and_and_p = FALSE;
+ ce_info->and_and_p = FALSE;
target_bb = then_bb;
}
else
@@ -2352,7 +2474,7 @@ find_if_block (ce_info)
if (then_succ != NULL_EDGE
&& (then_succ->succ_next != NULL_EDGE
|| (then_succ->flags & EDGE_COMPLEX)
- || (flow2_completed && tablejump_p (then_bb->end))))
+ || (flow2_completed && tablejump_p (BB_END (then_bb), NULL, NULL))))
return FALSE;
/* If the THEN block has no successors, conditional execution can still
@@ -2365,11 +2487,11 @@ find_if_block (ce_info)
{
if (else_bb->pred->pred_next == NULL_EDGE)
{
- rtx last_insn = then_bb->end;
+ rtx last_insn = BB_END (then_bb);
while (last_insn
&& GET_CODE (last_insn) == NOTE
- && last_insn != then_bb->head)
+ && last_insn != BB_HEAD (then_bb))
last_insn = PREV_INSN (last_insn);
if (last_insn
@@ -2400,12 +2522,12 @@ find_if_block (ce_info)
&& else_bb->pred->pred_next == NULL_EDGE
&& else_succ->succ_next == NULL_EDGE
&& ! (else_succ->flags & EDGE_COMPLEX)
- && ! (flow2_completed && tablejump_p (else_bb->end)))
+ && ! (flow2_completed && tablejump_p (BB_END (else_bb), NULL, NULL)))
join_bb = else_succ->dest;
/* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination. */
else
- return FALSE;
+ return FALSE;
num_possible_if_blocks++;
@@ -2414,15 +2536,15 @@ find_if_block (ce_info)
fprintf (rtl_dump_file, "\nIF-THEN%s block found, pass %d, start block %d [insn %d], then %d [%d]",
(else_bb) ? "-ELSE" : "",
ce_info->pass,
- test_bb->index, (test_bb->head) ? (int)INSN_UID (test_bb->head) : -1,
- then_bb->index, (then_bb->head) ? (int)INSN_UID (then_bb->head) : -1);
+ test_bb->index, (BB_HEAD (test_bb)) ? (int)INSN_UID (BB_HEAD (test_bb)) : -1,
+ then_bb->index, (BB_HEAD (then_bb)) ? (int)INSN_UID (BB_HEAD (then_bb)) : -1);
if (else_bb)
fprintf (rtl_dump_file, ", else %d [%d]",
- else_bb->index, (else_bb->head) ? (int)INSN_UID (else_bb->head) : -1);
+ else_bb->index, (BB_HEAD (else_bb)) ? (int)INSN_UID (BB_HEAD (else_bb)) : -1);
fprintf (rtl_dump_file, ", join %d [%d]",
- join_bb->index, (join_bb->head) ? (int)INSN_UID (join_bb->head) : -1);
+ join_bb->index, (BB_HEAD (join_bb)) ? (int)INSN_UID (BB_HEAD (join_bb)) : -1);
if (ce_info->num_multiple_test_blocks > 0)
fprintf (rtl_dump_file, ", %d %s block%s last test %d [%d]",
@@ -2430,8 +2552,8 @@ find_if_block (ce_info)
(ce_info->and_and_p) ? "&&" : "||",
(ce_info->num_multiple_test_blocks == 1) ? "" : "s",
ce_info->last_test_bb->index,
- ((ce_info->last_test_bb->head)
- ? (int)INSN_UID (ce_info->last_test_bb->head)
+ ((BB_HEAD (ce_info->last_test_bb))
+ ? (int)INSN_UID (BB_HEAD (ce_info->last_test_bb))
: -1));
fputc ('\n', rtl_dump_file);
@@ -2467,9 +2589,7 @@ find_if_block (ce_info)
to a trap, into a conditional trap. */
static int
-find_cond_trap (test_bb, then_edge, else_edge)
- basic_block test_bb;
- edge then_edge, else_edge;
+find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
{
basic_block then_bb = then_edge->dest;
basic_block else_bb = else_edge->dest;
@@ -2494,7 +2614,7 @@ find_cond_trap (test_bb, then_edge, else_edge)
}
/* If this is not a standard conditional jump, we can't parse it. */
- jump = test_bb->end;
+ jump = BB_END (test_bb);
cond = noce_get_condition (jump, &cond_earliest);
if (! cond)
return FALSE;
@@ -2518,22 +2638,24 @@ find_cond_trap (test_bb, then_edge, else_edge)
}
/* Attempt to generate the conditional trap. */
- seq = gen_cond_trap (code, XEXP (cond, 0), XEXP (cond, 1),
+ seq = gen_cond_trap (code, XEXP (cond, 0),
+ XEXP (cond, 1),
TRAP_CODE (PATTERN (trap)));
if (seq == NULL)
return FALSE;
+ num_true_changes++;
+
/* Emit the new insns before cond_earliest. */
- emit_insn_before_scope (seq, cond_earliest, INSN_SCOPE (trap));
+ emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATOR (trap));
/* Delete the trap block if possible. */
remove_edge (trap_bb == then_bb ? then_edge : else_edge);
if (trap_bb->pred == NULL)
{
- if (post_dominators)
- delete_from_dominance_info (post_dominators, trap_bb);
- flow_delete_block (trap_bb);
- num_removed_blocks++;
+ if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+ delete_from_dominance_info (CDI_POST_DOMINATORS, trap_bb);
+ delete_block (trap_bb);
}
/* If the non-trap block and the test are now adjacent, merge them.
@@ -2542,7 +2664,7 @@ find_cond_trap (test_bb, then_edge, else_edge)
{
struct ce_if_block new_ce_info;
delete_insn (jump);
- memset ((PTR) &new_ce_info, '\0', sizeof (new_ce_info));
+ memset (&new_ce_info, '\0', sizeof (new_ce_info));
new_ce_info.test_bb = test_bb;
new_ce_info.then_bb = NULL;
new_ce_info.else_bb = NULL;
@@ -2565,12 +2687,11 @@ find_cond_trap (test_bb, then_edge, else_edge)
return TRUE;
}
-/* Subroutine of find_cond_trap: if BB contains only a trap insn,
+/* Subroutine of find_cond_trap: if BB contains only a trap insn,
return it. */
static rtx
-block_has_only_trap (bb)
- basic_block bb;
+block_has_only_trap (basic_block bb)
{
rtx trap;
@@ -2584,7 +2705,7 @@ block_has_only_trap (bb)
/* The only instruction in the THEN block must be the trap. */
trap = first_active_insn (bb);
- if (! (trap == bb->end
+ if (! (trap == BB_END (bb)
&& GET_CODE (PATTERN (trap)) == TRAP_IF
&& TRAP_CONDITION (PATTERN (trap)) == const_true_rtx))
return NULL_RTX;
@@ -2670,9 +2791,7 @@ block_has_only_trap (bb)
/* Tests for case 1 above. */
static int
-find_if_case_1 (test_bb, then_edge, else_edge)
- basic_block test_bb;
- edge then_edge, else_edge;
+find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
{
basic_block then_bb = then_edge->dest;
basic_block else_bb = else_edge->dest, new_bb;
@@ -2706,7 +2825,7 @@ find_if_case_1 (test_bb, then_edge, else_edge)
return FALSE;
/* Registers set are dead, or are predicable. */
- if (! dead_or_predicable (test_bb, then_bb, else_bb,
+ if (! dead_or_predicable (test_bb, then_bb, else_bb,
then_bb->succ->dest, 1))
return FALSE;
@@ -2716,12 +2835,12 @@ find_if_case_1 (test_bb, then_edge, else_edge)
bitmap_operation (test_bb->global_live_at_end,
else_bb->global_live_at_start,
then_bb->global_live_at_end, BITMAP_IOR);
-
+
new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb), else_bb);
then_bb_index = then_bb->index;
- if (post_dominators)
- delete_from_dominance_info (post_dominators, then_bb);
- flow_delete_block (then_bb);
+ if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+ delete_from_dominance_info (CDI_POST_DOMINATORS, then_bb);
+ delete_block (then_bb);
/* Make rest of code believe that the newly created block is the THEN_BB
block we removed. */
@@ -2729,13 +2848,13 @@ find_if_case_1 (test_bb, then_edge, else_edge)
{
new_bb->index = then_bb_index;
BASIC_BLOCK (then_bb_index) = new_bb;
- if (post_dominators)
- add_to_dominance_info (post_dominators, new_bb);
+ if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+ add_to_dominance_info (CDI_POST_DOMINATORS, new_bb);
}
/* We've possibly created jump to next insn, cleanup_cfg will solve that
later. */
- num_removed_blocks++;
+ num_true_changes++;
num_updated_if_blocks++;
return TRUE;
@@ -2744,9 +2863,7 @@ find_if_case_1 (test_bb, then_edge, else_edge)
/* Test for case 2 above. */
static int
-find_if_case_2 (test_bb, then_edge, else_edge)
- basic_block test_bb;
- edge then_edge, else_edge;
+find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
{
basic_block then_bb = then_edge->dest;
basic_block else_bb = else_edge->dest;
@@ -2770,11 +2887,11 @@ find_if_case_2 (test_bb, then_edge, else_edge)
return FALSE;
/* ELSE is predicted or SUCC(ELSE) postdominates THEN. */
- note = find_reg_note (test_bb->end, REG_BR_PROB, NULL_RTX);
+ note = find_reg_note (BB_END (test_bb), REG_BR_PROB, NULL_RTX);
if (note && INTVAL (XEXP (note, 0)) >= REG_BR_PROB_BASE / 2)
;
else if (else_succ->dest->index < 0
- || dominated_by_p (post_dominators, then_bb,
+ || dominated_by_p (CDI_POST_DOMINATORS, then_bb,
else_succ->dest))
;
else
@@ -2800,12 +2917,12 @@ find_if_case_2 (test_bb, then_edge, else_edge)
bitmap_operation (test_bb->global_live_at_end,
then_bb->global_live_at_start,
else_bb->global_live_at_end, BITMAP_IOR);
-
- if (post_dominators)
- delete_from_dominance_info (post_dominators, else_bb);
- flow_delete_block (else_bb);
- num_removed_blocks++;
+ if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+ delete_from_dominance_info (CDI_POST_DOMINATORS, else_bb);
+ delete_block (else_bb);
+
+ num_true_changes++;
num_updated_if_blocks++;
/* ??? We may now fallthru from one of THEN's successors into a join
@@ -2818,9 +2935,7 @@ find_if_case_2 (test_bb, then_edge, else_edge)
Return 1 if a memory is found. */
static int
-find_memory (px, data)
- rtx *px;
- void *data ATTRIBUTE_UNUSED;
+find_memory (rtx *px, void *data ATTRIBUTE_UNUSED)
{
return GET_CODE (*px) == MEM;
}
@@ -2834,18 +2949,16 @@ find_memory (px, data)
REVERSEP is true if the sense of the branch should be reversed. */
static int
-dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
- basic_block test_bb, merge_bb, other_bb;
- basic_block new_dest;
- int reversep;
+dead_or_predicable (basic_block test_bb, basic_block merge_bb,
+ basic_block other_bb, basic_block new_dest, int reversep)
{
rtx head, end, jump, earliest, old_dest, new_label = NULL_RTX;
- jump = test_bb->end;
+ jump = BB_END (test_bb);
/* Find the extent of the real code in the merge block. */
- head = merge_bb->head;
- end = merge_bb->end;
+ head = BB_HEAD (merge_bb);
+ end = BB_END (merge_bb);
if (GET_CODE (head) == CODE_LABEL)
head = NEXT_INSN (head);
@@ -2861,28 +2974,11 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
if (GET_CODE (end) == JUMP_INSN)
{
- rtx tmp, insn, label;
-
if (head == end)
{
head = end = NULL_RTX;
goto no_body;
}
-
- /* If there is a jump table following merge_bb, fail
- if there are any insn between head and PREV_INSN (end)
- references it. */
- if ((label = JUMP_LABEL (end)) != NULL_RTX
- && (tmp = NEXT_INSN (label)) != NULL_RTX
- && GET_CODE (tmp) == JUMP_INSN
- && (GET_CODE (PATTERN (tmp)) == ADDR_VEC
- || GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
- {
- for (insn = head; insn != PREV_INSN (end); insn = NEXT_INSN (insn))
- if (find_reg_note (insn, REG_LABEL, label))
- return FALSE;
- }
-
end = PREV_INSN (end);
}
@@ -2892,8 +2988,8 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
if (HAVE_conditional_execution)
{
/* In the conditional execution case, we have things easy. We know
- the condition is reversable. We don't have to check life info,
- becase we're going to conditionally execute the code anyway.
+ the condition is reversible. We don't have to check life info
+ because we're going to conditionally execute the code anyway.
All that's left is making sure the insns involved can actually
be predicated. */
@@ -2979,7 +3075,7 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
test_set = INITIALIZE_REG_SET (test_set_head);
/* ??? bb->local_set is only valid during calculate_global_regs_live,
- so we must recompute usage for MERGE_BB. Not so bad, I suppose,
+ so we must recompute usage for MERGE_BB. Not so bad, I suppose,
since we've already asserted that MERGE_BB is small. */
propagate_block (merge_bb, tmp, merge_set, merge_set, 0);
@@ -3082,8 +3178,8 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
/* Move the insns out of MERGE_BB to before the branch. */
if (head != NULL)
{
- if (end == merge_bb->end)
- merge_bb->end = PREV_INSN (head);
+ if (end == BB_END (merge_bb))
+ BB_END (merge_bb) = PREV_INSN (head);
if (squeeze_notes (&head, &end))
return TRUE;
@@ -3110,27 +3206,27 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
/* Main entry point for all if-conversion. */
void
-if_convert (x_life_data_ok)
- int x_life_data_ok;
+if_convert (int x_life_data_ok)
{
basic_block bb;
int pass;
num_possible_if_blocks = 0;
num_updated_if_blocks = 0;
- num_removed_blocks = 0;
+ num_true_changes = 0;
life_data_ok = (x_life_data_ok != 0);
+ if (! (* targetm.cannot_modify_jumps_p) ())
+ mark_loop_exit_edges ();
+
/* Free up basic_block_for_insn so that we don't have to keep it
- up to date, either here or in merge_blocks_nomove. */
+ up to date, either here or in merge_blocks. */
free_basic_block_vars (1);
/* Compute postdominators if we think we'll use them. */
- post_dominators = NULL;
if (HAVE_conditional_execution || life_data_ok)
- {
- post_dominators = calculate_dominance_info (CDI_POST_DOMINATORS);
- }
+ calculate_dominance_info (CDI_POST_DOMINATORS);
+
if (life_data_ok)
clear_bb_flags ();
@@ -3167,8 +3263,7 @@ if_convert (x_life_data_ok)
fprintf (rtl_dump_file, "\n\n========== no more changes\n");
#endif
- if (post_dominators)
- free_dominance_info (post_dominators);
+ free_dominance_info (CDI_POST_DOMINATORS);
if (rtl_dump_file)
fflush (rtl_dump_file);
@@ -3176,7 +3271,7 @@ if_convert (x_life_data_ok)
clear_aux_for_blocks ();
/* Rebuild life info for basic blocks that require it. */
- if (num_removed_blocks && life_data_ok)
+ if (num_true_changes && life_data_ok)
{
/* If we allocated new pseudos, we must resize the array for sched1. */
if (max_regno < max_reg_num ())
@@ -3199,8 +3294,8 @@ if_convert (x_life_data_ok)
"%d IF blocks converted.\n",
num_updated_if_blocks);
fprintf (rtl_dump_file,
- "%d basic blocks deleted.\n\n\n",
- num_removed_blocks);
+ "%d true changes made.\n\n\n",
+ num_true_changes);
}
#ifdef ENABLE_CHECKING
diff --git a/contrib/gcc/input.h b/contrib/gcc/input.h
index 28bb64818324..ff014f6d664f 100644
--- a/contrib/gcc/input.h
+++ b/contrib/gcc/input.h
@@ -1,6 +1,6 @@
/* Declarations for variables relating to reading the source file.
Used by parsers, lexical analyzers, and error message routines.
- Copyright (C) 1993, 1997, 1998, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1997, 1998, 2000, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -19,31 +19,45 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-/* Source file current line is coming from. */
-extern const char *input_filename;
+#ifndef GCC_INPUT_H
+#define GCC_INPUT_H
-/* Top-level source file. */
-extern const char *main_input_filename;
-
-/* Line number in current source file. */
-extern int lineno;
+/* The data structure used to record a location in a translation unit. */
+/* Long-term, we want to get rid of this and typedef fileline location_t. */
+struct location_s GTY (())
+{
+ /* The name of the source file involved. */
+ const char *file;
-/* Stream for reading from input file. */
-extern FILE *finput;
+ /* The line-location in the source file. */
+ int line;
+};
+typedef struct location_s location_t;
struct file_stack
- {
- const char *name;
- struct file_stack *next;
- int line;
- };
+{
+ struct file_stack *next;
+ location_t location;
+};
+
+/* Top-level source file. */
+extern const char *main_input_filename;
+
+extern location_t input_location;
+#define input_line (input_location.line)
+#define input_filename (input_location.file)
/* Stack of currently pending input files.
The line member is not accurate for the innermost file on the stack. */
extern struct file_stack *input_file_stack;
+/* Stack of EXPR_WITH_FILE_LOCATION nested expressions. */
+extern struct file_stack *expr_wfl_stack;
+
/* Incremented on each change to input_file_stack. */
extern int input_file_stack_tick;
-extern void push_srcloc PARAMS ((const char *name, int line));
-extern void pop_srcloc PARAMS ((void));
+extern void push_srcloc (const char *name, int line);
+extern void pop_srcloc (void);
+
+#endif
diff --git a/contrib/gcc/integrate.c b/contrib/gcc/integrate.c
index 7e36070f7ea5..d45bbfce2a50 100644
--- a/contrib/gcc/integrate.c
+++ b/contrib/gcc/integrate.c
@@ -1,6 +1,6 @@
/* Procedure integration for GCC.
- Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
@@ -72,29 +74,23 @@ typedef struct initial_value_struct GTY(()) {
initial_value_pair * GTY ((length ("%h.num_entries"))) entries;
} initial_value_struct;
-static void setup_initial_hard_reg_value_integration PARAMS ((struct function *, struct inline_remap *));
-
-static rtvec initialize_for_inline PARAMS ((tree));
-static void note_modified_parmregs PARAMS ((rtx, rtx, void *));
-static void integrate_parm_decls PARAMS ((tree, struct inline_remap *,
- rtvec));
-static tree integrate_decl_tree PARAMS ((tree,
- struct inline_remap *));
-static void subst_constants PARAMS ((rtx *, rtx,
- struct inline_remap *, int));
-static void set_block_origin_self PARAMS ((tree));
-static void set_block_abstract_flags PARAMS ((tree, int));
-static void process_reg_param PARAMS ((struct inline_remap *, rtx,
- rtx));
-void set_decl_abstract_flags PARAMS ((tree, int));
-static void mark_stores PARAMS ((rtx, rtx, void *));
-static void save_parm_insns PARAMS ((rtx, rtx));
-static void copy_insn_list PARAMS ((rtx, struct inline_remap *,
- rtx));
-static void copy_insn_notes PARAMS ((rtx, struct inline_remap *,
- int));
-static int compare_blocks PARAMS ((const PTR, const PTR));
-static int find_block PARAMS ((const PTR, const PTR));
+static void setup_initial_hard_reg_value_integration (struct function *,
+ struct inline_remap *);
+
+static rtvec initialize_for_inline (tree);
+static void note_modified_parmregs (rtx, rtx, void *);
+static void integrate_parm_decls (tree, struct inline_remap *, rtvec);
+static tree integrate_decl_tree (tree, struct inline_remap *);
+static void subst_constants (rtx *, rtx, struct inline_remap *, int);
+static void set_block_origin_self (tree);
+static void set_block_abstract_flags (tree, int);
+static void process_reg_param (struct inline_remap *, rtx, rtx);
+static void mark_stores (rtx, rtx, void *);
+static void save_parm_insns (rtx, rtx);
+static void copy_insn_list (rtx, struct inline_remap *, rtx);
+static void copy_insn_notes (rtx, struct inline_remap *, int);
+static int compare_blocks (const void *, const void *);
+static int find_block (const void *, const void *);
/* Used by copy_rtx_and_substitute; this indicates whether the function is
called for the purpose of inlining or some other purpose (i.e. loop
@@ -108,9 +104,7 @@ static struct function *inlining = 0;
explosions when the label_map gets very large. */
rtx
-get_label_from_map (map, i)
- struct inline_remap *map;
- int i;
+get_label_from_map (struct inline_remap *map, int i)
{
rtx x = map->label_map[i];
@@ -123,8 +117,7 @@ get_label_from_map (map, i)
/* Return false if the function FNDECL cannot be inlined on account of its
attributes, true otherwise. */
bool
-function_attribute_inlinable_p (fndecl)
- tree fndecl;
+function_attribute_inlinable_p (tree fndecl)
{
if (targetm.attribute_table)
{
@@ -150,8 +143,7 @@ function_attribute_inlinable_p (fndecl)
for the function's name. */
const char *
-function_cannot_inline_p (fndecl)
- tree fndecl;
+function_cannot_inline_p (tree fndecl)
{
rtx insn;
tree last = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
@@ -180,6 +172,9 @@ function_cannot_inline_p (fndecl)
if (current_function_calls_alloca)
return N_("function using alloca cannot be inline");
+ if (current_function_calls_longjmp)
+ return N_("function using longjmp cannot be inline");
+
if (current_function_calls_setjmp)
return N_("function using setjmp cannot be inline");
@@ -264,7 +259,7 @@ function_cannot_inline_p (fndecl)
}
/* If the function has a target specific attribute attached to it,
- then we assume that we should not inline it. This can be overriden
+ then we assume that we should not inline it. This can be overridden
by the target if it defines TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P. */
if (!function_attribute_inlinable_p (fndecl))
return N_("function with target specific attribute(s) cannot be inlined");
@@ -284,15 +279,14 @@ static int in_nonparm_insns;
needed to save FNDECL's insns and info for future inline expansion. */
static rtvec
-initialize_for_inline (fndecl)
- tree fndecl;
+initialize_for_inline (tree fndecl)
{
int i;
rtvec arg_vector;
tree parms;
/* Clear out PARMDECL_MAP. It was allocated in the caller's frame. */
- memset ((char *) parmdecl_map, 0, max_parm_reg * sizeof (tree));
+ memset (parmdecl_map, 0, max_parm_reg * sizeof (tree));
arg_vector = rtvec_alloc (list_length (DECL_ARGUMENTS (fndecl)));
for (parms = DECL_ARGUMENTS (fndecl), i = 0;
@@ -336,10 +330,7 @@ initialize_for_inline (fndecl)
TO_FN. */
tree
-copy_decl_for_inlining (decl, from_fn, to_fn)
- tree decl;
- tree from_fn;
- tree to_fn;
+copy_decl_for_inlining (tree decl, tree from_fn, tree to_fn)
{
tree copy;
@@ -396,7 +387,8 @@ copy_decl_for_inlining (decl, from_fn, to_fn)
DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);
/* The new variable/label has no RTL, yet. */
- SET_DECL_RTL (copy, NULL_RTX);
+ if (!TREE_STATIC (copy) && !DECL_EXTERNAL (copy))
+ SET_DECL_RTL (copy, NULL_RTX);
/* These args would always appear unused, if not for this. */
TREE_USED (copy) = 1;
@@ -407,10 +399,10 @@ copy_decl_for_inlining (decl, from_fn, to_fn)
;
else if (DECL_CONTEXT (decl) != from_fn)
/* Things that weren't in the scope of the function we're inlining
- from aren't in the scope we're inlining too, either. */
+ from aren't in the scope we're inlining to, either. */
;
else if (TREE_STATIC (decl))
- /* Function-scoped static variables should say in the original
+ /* Function-scoped static variables should stay in the original
function. */
;
else
@@ -441,8 +433,7 @@ copy_decl_for_inlining (decl, from_fn, to_fn)
functions at the end of compilation. */
void
-save_for_inline (fndecl)
- tree fndecl;
+save_for_inline (tree fndecl)
{
rtx insn;
rtvec argvec;
@@ -454,7 +445,7 @@ save_for_inline (fndecl)
for the parms, prior to elimination of virtual registers.
These values are needed for substituting parms properly. */
if (! flag_no_inline)
- parmdecl_map = (tree *) xmalloc (max_parm_reg * sizeof (tree));
+ parmdecl_map = xmalloc (max_parm_reg * sizeof (tree));
/* Make and emit a return-label if we have not already done so. */
@@ -504,7 +495,7 @@ save_for_inline (fndecl)
}
cfun->original_decl_initial = DECL_INITIAL (fndecl);
cfun->no_debugging_symbols = (write_symbols == NO_DEBUG);
- DECL_SAVED_INSNS (fndecl) = cfun;
+ cfun->saved_for_inline = 1;
/* Clean up. */
if (! flag_no_inline)
@@ -518,9 +509,7 @@ save_for_inline (fndecl)
register and track the new register's life. */
static void
-save_parm_insns (insn, first_nonparm_insn)
- rtx insn;
- rtx first_nonparm_insn;
+save_parm_insns (rtx insn, rtx first_nonparm_insn)
{
if (insn == NULL_RTX)
return;
@@ -554,10 +543,7 @@ save_parm_insns (insn, first_nonparm_insn)
/* Note whether a parameter is modified or not. */
static void
-note_modified_parmregs (reg, x, data)
- rtx reg;
- rtx x ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+note_modified_parmregs (rtx reg, rtx x ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED)
{
if (GET_CODE (reg) == REG && in_nonparm_insns
&& REGNO (reg) < max_parm_reg
@@ -588,9 +574,7 @@ varray_type global_const_equiv_varray;
Also, don't allow hard registers here; they might not be valid when
substituted into insns. */
static void
-process_reg_param (map, loc, copy)
- struct inline_remap *map;
- rtx loc, copy;
+process_reg_param (struct inline_remap *map, rtx loc, rtx copy)
{
if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG)
|| (GET_CODE (copy) == REG && REG_USERVAR_P (loc)
@@ -612,9 +596,7 @@ process_reg_param (map, loc, copy)
two pointers, because it may overflow sizeof(int). */
static int
-compare_blocks (v1, v2)
- const PTR v1;
- const PTR v2;
+compare_blocks (const void *v1, const void *v2)
{
tree b1 = *((const tree *) v1);
tree b2 = *((const tree *) v2);
@@ -630,9 +612,7 @@ compare_blocks (v1, v2)
an original block; the second to a remapped equivalent. */
static int
-find_block (v1, v2)
- const PTR v1;
- const PTR v2;
+find_block (const void *v1, const void *v2)
{
const union tree_node *b1 = (const union tree_node *) v1;
tree b2 = *((const tree *) v2);
@@ -658,13 +638,8 @@ find_block (v1, v2)
else an rtx for where the value is stored. */
rtx
-expand_inline_function (fndecl, parms, target, ignore, type,
- structure_value_addr)
- tree fndecl, parms;
- rtx target;
- int ignore;
- tree type;
- rtx structure_value_addr;
+expand_inline_function (tree fndecl, tree parms, rtx target, int ignore,
+ tree type, rtx structure_value_addr)
{
struct function *inlining_previous;
struct function *inl_f = DECL_SAVED_INSNS (fndecl);
@@ -735,6 +710,14 @@ expand_inline_function (fndecl, parms, target, ignore, type,
return (rtx) (size_t) -1;
}
+ /* If there is a TARGET which is a readonly BLKmode MEM and DECL_RESULT
+ is also a mem, we are going to lose the readonly on the stores, so don't
+ inline. */
+ if (target != 0 && GET_CODE (target) == MEM && GET_MODE (target) == BLKmode
+ && RTX_UNCHANGING_P (target) && DECL_RTL_SET_P (DECL_RESULT (fndecl))
+ && GET_CODE (DECL_RTL (DECL_RESULT (fndecl))) == MEM)
+ return (rtx) (size_t) -1;
+
/* Extra arguments are valid, but will be ignored below, so we must
evaluate them here for side-effects. */
for (; actual; actual = TREE_CHAIN (actual))
@@ -744,8 +727,8 @@ expand_inline_function (fndecl, parms, target, ignore, type,
/* Expand the function arguments. Do this first so that any
new registers get created before we allocate the maps. */
- arg_vals = (rtx *) xmalloc (nargs * sizeof (rtx));
- arg_trees = (tree *) xmalloc (nargs * sizeof (tree));
+ arg_vals = xmalloc (nargs * sizeof (rtx));
+ arg_trees = xmalloc (nargs * sizeof (tree));
for (formal = DECL_ARGUMENTS (fndecl), actual = parms, i = 0;
formal;
@@ -788,7 +771,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
abort ();
/* The mode if LOC and ARG can differ if LOC was a variable
- that had its mode promoted via PROMOTED_MODE. */
+ that had its mode promoted. */
arg_vals[i] = convert_modes (pmode,
TYPE_MODE (TREE_TYPE (arg)),
expand_expr (arg, NULL_RTX, mode,
@@ -801,6 +784,14 @@ expand_inline_function (fndecl, parms, target, ignore, type,
else
arg_vals[i] = 0;
+ /* If the formal type was const but the actual was not, we might
+ end up here with an rtx wrongly tagged unchanging in the caller's
+ context. Fix that. */
+ if (arg_vals[i] != 0
+ && (GET_CODE (arg_vals[i]) == REG || GET_CODE (arg_vals[i]) == MEM)
+ && ! TREE_READONLY (TREE_VALUE (actual)))
+ RTX_UNCHANGING_P (arg_vals[i]) = 0;
+
if (arg_vals[i] != 0
&& (! TREE_READONLY (formal)
/* If the parameter is not read-only, copy our argument through
@@ -832,22 +823,21 @@ expand_inline_function (fndecl, parms, target, ignore, type,
/* Allocate the structures we use to remap things. */
- map = (struct inline_remap *) xcalloc (1, sizeof (struct inline_remap));
+ map = xcalloc (1, sizeof (struct inline_remap));
map->fndecl = fndecl;
VARRAY_TREE_INIT (map->block_map, 10, "block_map");
- map->reg_map = (rtx *) xcalloc (max_regno, sizeof (rtx));
+ map->reg_map = xcalloc (max_regno, sizeof (rtx));
/* We used to use alloca here, but the size of what it would try to
allocate would occasionally cause it to exceed the stack limit and
cause unpredictable core dumps. */
- real_label_map
- = (rtx *) xmalloc ((max_labelno) * sizeof (rtx));
+ real_label_map = xmalloc ((max_labelno) * sizeof (rtx));
map->label_map = real_label_map;
map->local_return_label = NULL_RTX;
inl_max_uid = (inl_f->emit->x_cur_insn_uid + 1);
- map->insn_map = (rtx *) xcalloc (inl_max_uid, sizeof (rtx));
+ map->insn_map = xcalloc (inl_max_uid, sizeof (rtx));
map->min_insnno = 0;
map->max_insnno = inl_max_uid;
@@ -881,7 +871,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
insn that can be used as an insertion point. */
map->insns_at_start = get_last_insn ();
if (map->insns_at_start == 0)
- map->insns_at_start = emit_note (NULL, NOTE_INSN_DELETED);
+ map->insns_at_start = emit_note (NOTE_INSN_DELETED);
map->regno_pointer_align = inl_f->emit->regno_pointer_align;
map->x_regno_reg_rtx = inl_f->emit->x_regno_reg_rtx;
@@ -900,11 +890,16 @@ expand_inline_function (fndecl, parms, target, ignore, type,
if (inl_f->needs_context)
static_chain_value = lookup_static_chain (fndecl);
+ /* If the inlined function calls __builtin_constant_p, then we'll
+ need to call purge_builtin_constant_p on this function. */
+ if (inl_f->calls_constant_p)
+ current_function_calls_constant_p = 1;
+
if (GET_CODE (parm_insns) == NOTE
&& NOTE_LINE_NUMBER (parm_insns) > 0)
{
- rtx note = emit_note (NOTE_SOURCE_FILE (parm_insns),
- NOTE_LINE_NUMBER (parm_insns));
+ rtx note = emit_note_copy (parm_insns);
+
if (note)
RTX_INTEGRATED_P (note) = 1;
}
@@ -995,8 +990,8 @@ expand_inline_function (fndecl, parms, target, ignore, type,
&& ! (GET_CODE (XEXP (loc, 0)) == REG
&& REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER))
{
- rtx note = emit_note (DECL_SOURCE_FILE (formal),
- DECL_SOURCE_LINE (formal));
+ rtx note = emit_line_note (DECL_SOURCE_LOCATION (formal));
+
if (note)
RTX_INTEGRATED_P (note) = 1;
@@ -1018,7 +1013,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
REG_FUNCTION_RETURN_VALUE_P. */
map->inline_target = 0;
- loc = (DECL_RTL_SET_P (DECL_RESULT (fndecl))
+ loc = (DECL_RTL_SET_P (DECL_RESULT (fndecl))
? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX);
if (TYPE_MODE (type) == VOIDmode)
@@ -1036,7 +1031,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
else
{
if (! structure_value_addr
- || ! aggregate_value_p (DECL_RESULT (fndecl)))
+ || ! aggregate_value_p (DECL_RESULT (fndecl), fndecl))
abort ();
/* Pass the function the address in which to return a structure
@@ -1192,8 +1187,8 @@ expand_inline_function (fndecl, parms, target, ignore, type,
/* Initialize label_map. get_label_from_map will actually make
the labels. */
- memset ((char *) &map->label_map[min_labelno], 0,
- (max_labelno - min_labelno) * sizeof (rtx));
+ memset (&map->label_map[min_labelno], 0,
+ (max_labelno - min_labelno) * sizeof (rtx));
/* Make copies of the decls of the symbols in the inline function, so that
the copies of the variables get declared in the current function. Set
@@ -1283,15 +1278,15 @@ expand_inline_function (fndecl, parms, target, ignore, type,
This line number note is still needed for debugging though, so we can't
delete it. */
if (flag_test_coverage)
- emit_note (0, NOTE_INSN_REPEATED_LINE_NUMBER);
+ emit_note (NOTE_INSN_REPEATED_LINE_NUMBER);
- emit_line_note (input_filename, lineno);
+ emit_line_note (input_location);
/* If the function returns a BLKmode object in a register, copy it
out of the temp register into a BLKmode memory object. */
if (target
&& TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == BLKmode
- && ! aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
+ && ! aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)), fndecl))
target = copy_blkmode_from_reg (0, target, TREE_TYPE (TREE_TYPE (fndecl)));
if (structure_value_addr)
@@ -1327,10 +1322,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
register for the function. */
static void
-copy_insn_list (insns, map, static_chain_value)
- rtx insns;
- struct inline_remap *map;
- rtx static_chain_value;
+copy_insn_list (rtx insns, struct inline_remap *map, rtx static_chain_value)
{
int i;
rtx insn;
@@ -1429,7 +1421,7 @@ copy_insn_list (insns, map, static_chain_value)
gen_rtx_MEM (GET_MODE (static_chain_incoming_rtx),
SET_DEST (set));
- /* emit the instruction in case it is used for something
+ /* Emit the instruction in case it is used for something
other than setting the static chain; if it's not used,
it can always be removed as dead code */
copy = emit_insn (copy_rtx_and_substitute (pattern, map, 0));
@@ -1524,7 +1516,7 @@ copy_insn_list (insns, map, static_chain_value)
#else
try_constants (copy, map);
#endif
- INSN_SCOPE (copy) = INSN_SCOPE (insn);
+ INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
break;
case JUMP_INSN:
@@ -1545,7 +1537,7 @@ copy_insn_list (insns, map, static_chain_value)
cc0_insn = 0;
#endif
try_constants (copy, map);
- INSN_SCOPE (copy) = INSN_SCOPE (insn);
+ INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
/* If this used to be a conditional jump insn but whose branch
direction is now know, we must do something special. */
@@ -1613,7 +1605,7 @@ copy_insn_list (insns, map, static_chain_value)
SIBLING_CALL_P (copy) = SIBLING_CALL_P (insn);
CONST_OR_PURE_CALL_P (copy) = CONST_OR_PURE_CALL_P (insn);
- INSN_SCOPE (copy) = INSN_SCOPE (insn);
+ INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
/* Because the USAGE information potentially contains objects other
than hard registers, we need to copy it. */
@@ -1665,12 +1657,12 @@ copy_insn_list (insns, map, static_chain_value)
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
&& NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
{
- copy = emit_note (NOTE_SOURCE_FILE (insn),
- NOTE_LINE_NUMBER (insn));
- if (copy
- && (NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG
- || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END)
- && NOTE_BLOCK (insn))
+ copy = emit_note_copy (insn);
+ if (!copy)
+ /*Copied a line note, but line numbering is off*/;
+ else if ((NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_BEG
+ || NOTE_LINE_NUMBER (copy) == NOTE_INSN_BLOCK_END)
+ && NOTE_BLOCK (insn))
{
tree *mapped_block_p;
@@ -1686,8 +1678,7 @@ copy_insn_list (insns, map, static_chain_value)
else
NOTE_BLOCK (copy) = *mapped_block_p;
}
- else if (copy
- && NOTE_LINE_NUMBER (copy) == NOTE_INSN_EXPECTED_VALUE)
+ else if (NOTE_LINE_NUMBER (copy) == NOTE_INSN_EXPECTED_VALUE)
NOTE_EXPECTED_VALUE (copy)
= copy_rtx_and_substitute (NOTE_EXPECTED_VALUE (insn),
map, 0);
@@ -1712,10 +1703,7 @@ copy_insn_list (insns, map, static_chain_value)
that are valid across the entire function. */
static void
-copy_insn_notes (insns, map, eh_region_offset)
- rtx insns;
- struct inline_remap *map;
- int eh_region_offset;
+copy_insn_notes (rtx insns, struct inline_remap *map, int eh_region_offset)
{
rtx insn, new_insn;
@@ -1771,10 +1759,7 @@ copy_insn_notes (insns, map, eh_region_offset)
push all of those decls and give each one the corresponding home. */
static void
-integrate_parm_decls (args, map, arg_vector)
- tree args;
- struct inline_remap *map;
- rtvec arg_vector;
+integrate_parm_decls (tree args, struct inline_remap *map, rtvec arg_vector)
{
tree tail;
int i;
@@ -1807,9 +1792,7 @@ integrate_parm_decls (args, map, arg_vector)
no mapping is necessary. */
static tree
-integrate_decl_tree (let, map)
- tree let;
- struct inline_remap *map;
+integrate_decl_tree (tree let, struct inline_remap *map)
{
tree t;
tree new_block;
@@ -1839,14 +1822,6 @@ integrate_decl_tree (let, map)
subst_constants (&r, NULL_RTX, map, 1);
SET_DECL_RTL (d, r);
- if (GET_CODE (r) == REG)
- REGNO_DECL (REGNO (r)) = d;
- else if (GET_CODE (r) == CONCAT)
- {
- REGNO_DECL (REGNO (XEXP (r, 0))) = d;
- REGNO_DECL (REGNO (XEXP (r, 1))) = d;
- }
-
apply_change_group ();
}
@@ -1886,10 +1861,7 @@ integrate_decl_tree (let, map)
calling `force_const_mem'. */
rtx
-copy_rtx_and_substitute (orig, map, for_lhs)
- rtx orig;
- struct inline_remap *map;
- int for_lhs;
+copy_rtx_and_substitute (rtx orig, struct inline_remap *map, int for_lhs)
{
rtx copy, temp;
int i, j;
@@ -2038,7 +2010,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
{
if (!map->leaf_reg_map[regno][mode])
map->leaf_reg_map[regno][mode] = gen_rtx_REG (mode, regno);
- return map->leaf_reg_map[regno][mode];
+ return map->leaf_reg_map[regno][mode];
}
#endif
else
@@ -2118,7 +2090,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
if (NOTE_LINE_NUMBER (orig) != NOTE_INSN_DELETED_LABEL)
break;
- /* ... FALLTHRU ... */
+ /* Fall through. */
case CODE_LABEL:
LABEL_PRESERVE_P (get_label_from_map (map, CODE_LABEL_NUMBER (orig)))
= LABEL_PRESERVE_P (orig);
@@ -2188,11 +2160,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
#endif
temp = XEXP (temp, 0);
-
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (temp) != GET_MODE (orig))
- temp = convert_memory_address (GET_MODE (orig), temp);
-#endif
+ temp = convert_memory_address (GET_MODE (orig), temp);
return temp;
}
else if (GET_CODE (constant) == LABEL_REF)
@@ -2201,6 +2169,8 @@ copy_rtx_and_substitute (orig, map, for_lhs)
copy_rtx_and_substitute (constant, map, for_lhs)),
0);
}
+ else if (TREE_CONSTANT_POOL_ADDRESS_P (orig) && inlining)
+ notice_rtl_inlining_of_deferred_constant ();
return orig;
@@ -2266,7 +2236,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
MEM_COPY_ATTRIBUTES (copy, XEXP (orig, 0));
return
- gen_rtx_CALL (GET_MODE (orig), copy,
+ gen_rtx_CALL (GET_MODE (orig), copy,
copy_rtx_and_substitute (XEXP (orig, 1), map, 0));
}
break;
@@ -2371,8 +2341,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
switch (*format_ptr++)
{
case '0':
- /* Copy this through the wide int field; that's safest. */
- X0WINT (copy, i) = X0WINT (orig, i);
+ X0ANY (copy, i) = X0ANY (orig, i);
break;
case 'e':
@@ -2433,9 +2402,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
/* Substitute known constant values into INSN, if that is valid. */
void
-try_constants (insn, map)
- rtx insn;
- struct inline_remap *map;
+try_constants (rtx insn, struct inline_remap *map)
{
int i;
@@ -2450,6 +2417,14 @@ try_constants (insn, map)
subst_constants (&PATTERN (insn), insn, map, 0);
apply_change_group ();
+ /* Enforce consistency between the addresses in the regular insn flow
+ and the ones in CALL_INSN_FUNCTION_USAGE lists, if any. */
+ if (GET_CODE (insn) == CALL_INSN && CALL_INSN_FUNCTION_USAGE (insn))
+ {
+ subst_constants (&CALL_INSN_FUNCTION_USAGE (insn), insn, map, 1);
+ apply_change_group ();
+ }
+
/* Show we don't know the value of anything stored or clobbered. */
note_stores (PATTERN (insn), mark_stores, NULL);
map->last_pc_value = 0;
@@ -2499,11 +2474,7 @@ try_constants (insn, map)
If MEMONLY is nonzero, only make changes inside a MEM. */
static void
-subst_constants (loc, insn, map, memonly)
- rtx *loc;
- rtx insn;
- struct inline_remap *map;
- int memonly;
+subst_constants (rtx *loc, rtx insn, struct inline_remap *map, int memonly)
{
rtx x = *loc;
int i, j;
@@ -2577,7 +2548,7 @@ subst_constants (loc, insn, map, memonly)
integral mode and extracting the low part. */
subst_constants (&inner, NULL_RTX, map, 0);
new = simplify_gen_subreg (GET_MODE (x), inner,
- GET_MODE (SUBREG_REG (x)),
+ GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x));
if (new)
@@ -2615,10 +2586,7 @@ subst_constants (loc, insn, map, memonly)
{
src = SET_SRC (x);
if (GET_MODE_CLASS (GET_MODE (src)) == MODE_CC
-#ifdef HAVE_cc0
- || dest == cc0_rtx
-#endif
- )
+ || CC0_P (dest))
{
compare_mode = GET_MODE (XEXP (src, 0));
if (compare_mode == VOIDmode)
@@ -2670,9 +2638,7 @@ subst_constants (loc, insn, map, memonly)
|| REGNO (XEXP (src, 0)) == VIRTUAL_STACK_VARS_REGNUM)
&& CONSTANT_P (XEXP (src, 1)))
|| GET_CODE (src) == COMPARE
-#ifdef HAVE_cc0
- || dest == cc0_rtx
-#endif
+ || CC0_P (dest)
|| (dest == pc_rtx
&& (src == pc_rtx || GET_CODE (src) == RETURN
|| GET_CODE (src) == LABEL_REF))))
@@ -2686,10 +2652,7 @@ subst_constants (loc, insn, map, memonly)
if (compare_mode != VOIDmode
&& GET_CODE (src) == COMPARE
&& (GET_MODE_CLASS (GET_MODE (src)) == MODE_CC
-#ifdef HAVE_cc0
- || dest == cc0_rtx
-#endif
- )
+ || CC0_P (dest))
&& GET_MODE (XEXP (src, 0)) == VOIDmode
&& GET_MODE (XEXP (src, 1)) == VOIDmode)
{
@@ -2842,10 +2805,7 @@ subst_constants (loc, insn, map, memonly)
called from note_stores with parts of the new insn. */
static void
-mark_stores (dest, x, data)
- rtx dest;
- rtx x ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+mark_stores (rtx dest, rtx x ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED)
{
int regno = -1;
enum machine_mode mode = VOIDmode;
@@ -2894,8 +2854,7 @@ mark_stores (dest, x, data)
values to point to themselves. */
static void
-set_block_origin_self (stmt)
- tree stmt;
+set_block_origin_self (tree stmt)
{
if (BLOCK_ABSTRACT_ORIGIN (stmt) == NULL_TREE)
{
@@ -2933,8 +2892,7 @@ set_block_origin_self (stmt)
point to themselves. */
void
-set_decl_origin_self (decl)
- tree decl;
+set_decl_origin_self (tree decl)
{
if (DECL_ABSTRACT_ORIGIN (decl) == NULL_TREE)
{
@@ -2958,9 +2916,7 @@ set_decl_origin_self (decl)
(recursively) which are contained therein. */
static void
-set_block_abstract_flags (stmt, setting)
- tree stmt;
- int setting;
+set_block_abstract_flags (tree stmt, int setting)
{
tree local_decl;
tree subblock;
@@ -2985,9 +2941,7 @@ set_block_abstract_flags (stmt, setting)
blocks and sub-blocks (recursively) to the same setting. */
void
-set_decl_abstract_flags (decl, setting)
- tree decl;
- int setting;
+set_decl_abstract_flags (tree decl, int setting)
{
DECL_ABSTRACT (decl) = setting;
if (TREE_CODE (decl) == FUNCTION_DECL)
@@ -3009,8 +2963,7 @@ set_decl_abstract_flags (decl, setting)
static GTY(()) struct function *old_cfun;
void
-output_inline_function (fndecl)
- tree fndecl;
+output_inline_function (tree fndecl)
{
enum debug_info_type old_write_symbols = write_symbols;
const struct gcc_debug_hooks *const old_debug_hooks = debug_hooks;
@@ -3034,8 +2987,7 @@ output_inline_function (fndecl)
/* Make sure warnings emitted by the optimizers (e.g. control reaches
end of non-void function) is not wildly incorrect. */
- input_filename = DECL_SOURCE_FILE (fndecl);
- lineno = DECL_SOURCE_LINE (fndecl);
+ input_location = DECL_SOURCE_LOCATION (fndecl);
/* Compile this function all the way down to assembly code. As a
side effect this destroys the saved RTL representation, but
@@ -3054,9 +3006,7 @@ output_inline_function (fndecl)
the function. */
rtx
-get_hard_reg_initial_reg (fun, reg)
- struct function *fun;
- rtx reg;
+get_hard_reg_initial_reg (struct function *fun, rtx reg)
{
struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
int i;
@@ -3072,9 +3022,7 @@ get_hard_reg_initial_reg (fun, reg)
}
rtx
-has_func_hard_reg_initial_val (fun, reg)
- struct function *fun;
- rtx reg;
+has_func_hard_reg_initial_val (struct function *fun, rtx reg)
{
struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
int i;
@@ -3090,9 +3038,7 @@ has_func_hard_reg_initial_val (fun, reg)
}
rtx
-get_func_hard_reg_initial_val (fun, reg)
- struct function *fun;
- rtx reg;
+get_func_hard_reg_initial_val (struct function *fun, rtx reg)
{
struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
rtx rv = has_func_hard_reg_initial_val (fun, reg);
@@ -3102,20 +3048,19 @@ get_func_hard_reg_initial_val (fun, reg)
if (ivs == 0)
{
- fun->hard_reg_initial_vals = (void *) ggc_alloc (sizeof (initial_value_struct));
+ fun->hard_reg_initial_vals = ggc_alloc (sizeof (initial_value_struct));
ivs = fun->hard_reg_initial_vals;
ivs->num_entries = 0;
ivs->max_entries = 5;
- ivs->entries = (initial_value_pair *) ggc_alloc (5 * sizeof (initial_value_pair));
+ ivs->entries = ggc_alloc (5 * sizeof (initial_value_pair));
}
if (ivs->num_entries >= ivs->max_entries)
{
ivs->max_entries += 5;
- ivs->entries =
- (initial_value_pair *) ggc_realloc (ivs->entries,
- ivs->max_entries
- * sizeof (initial_value_pair));
+ ivs->entries = ggc_realloc (ivs->entries,
+ ivs->max_entries
+ * sizeof (initial_value_pair));
}
ivs->entries[ivs->num_entries].hard_reg = reg;
@@ -3125,25 +3070,19 @@ get_func_hard_reg_initial_val (fun, reg)
}
rtx
-get_hard_reg_initial_val (mode, regno)
- enum machine_mode mode;
- int regno;
+get_hard_reg_initial_val (enum machine_mode mode, int regno)
{
return get_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
}
rtx
-has_hard_reg_initial_val (mode, regno)
- enum machine_mode mode;
- int regno;
+has_hard_reg_initial_val (enum machine_mode mode, int regno)
{
return has_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
}
static void
-setup_initial_hard_reg_value_integration (inl_f, remap)
- struct function *inl_f;
- struct inline_remap *remap;
+setup_initial_hard_reg_value_integration (struct function *inl_f, struct inline_remap *remap)
{
struct initial_value_struct *ivs = inl_f->hard_reg_initial_vals;
int i;
@@ -3158,7 +3097,7 @@ setup_initial_hard_reg_value_integration (inl_f, remap)
void
-emit_initial_value_sets ()
+emit_initial_value_sets (void)
{
struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
int i;
@@ -3179,8 +3118,7 @@ emit_initial_value_sets ()
/* If the backend knows where to allocate pseudos for hard
register initial values, register these allocations now. */
void
-allocate_initial_values (reg_equiv_memory_loc)
- rtx *reg_equiv_memory_loc ATTRIBUTE_UNUSED;
+allocate_initial_values (rtx *reg_equiv_memory_loc ATTRIBUTE_UNUSED)
{
#ifdef ALLOCATE_INITIAL_VALUE
struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
diff --git a/contrib/gcc/integrate.h b/contrib/gcc/integrate.h
index b4d622767c9b..94bf2e738d47 100644
--- a/contrib/gcc/integrate.h
+++ b/contrib/gcc/integrate.h
@@ -1,5 +1,6 @@
-/* Function integration definitions for GNU C-Compiler
- Copyright (C) 1990, 1995, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+/* Function integration definitions for GCC
+ Copyright (C) 1990, 1995, 1998, 1999, 2000, 2001, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -39,7 +40,7 @@ struct inline_remap
copy_rtx_and_substitute. */
int integrating;
/* Definition of function be inlined. */
- union tree_node *fndecl;
+ tree fndecl;
/* Place to put insns needed at start of function. */
rtx insns_at_start;
/* Mapping from old BLOCKs to new BLOCKs. */
@@ -112,7 +113,7 @@ struct inline_remap
rtx dest;
rtx equiv;
} equiv_sets[MAX_RECOG_OPERANDS];
- /* Record the last thing assigned to pc. This is used for folded
+ /* Record the last thing assigned to pc. This is used for folded
conditional branch insns. */
rtx last_pc_value;
#ifdef HAVE_cc0
@@ -127,41 +128,39 @@ struct inline_remap
/* Return a copy of an rtx (as needed), substituting pseudo-register,
labels, and frame-pointer offsets as necessary. */
-extern rtx copy_rtx_and_substitute PARAMS ((rtx, struct inline_remap *, int));
+extern rtx copy_rtx_and_substitute (rtx, struct inline_remap *, int);
/* Return a pseudo that corresponds to the value in the specified hard
reg as of the start of the function (for inlined functions, the
value at the start of the parent function). */
-extern rtx get_hard_reg_initial_val PARAMS ((enum machine_mode, int));
+extern rtx get_hard_reg_initial_val (enum machine_mode, int);
/* Likewise, but for a different than the current function, or
arbitrary expression. */
-extern rtx get_func_hard_reg_initial_val PARAMS ((struct function *, rtx));
+extern rtx get_func_hard_reg_initial_val (struct function *, rtx);
/* Likewise, but iff someone else has caused it to become allocated. */
-extern rtx has_func_hard_reg_initial_val PARAMS ((struct function *, rtx));
+extern rtx has_func_hard_reg_initial_val (struct function *, rtx);
/* Likewise, but for common cases. */
-extern rtx has_hard_reg_initial_val PARAMS ((enum machine_mode, int));
+extern rtx has_hard_reg_initial_val (enum machine_mode, int);
/* If a pseudo represents an initial hard reg (or expression), return
it, else return NULL_RTX. */
-extern rtx get_hard_reg_initial_reg PARAMS ((struct function *, rtx));
+extern rtx get_hard_reg_initial_reg (struct function *, rtx);
/* Called from rest_of_compilation. */
-extern void emit_initial_value_sets PARAMS ((void));
-extern void allocate_initial_values PARAMS ((rtx *));
+extern void emit_initial_value_sets (void);
+extern void allocate_initial_values (rtx *);
/* Copy a declaration when one function is substituted inline into
another. */
-extern union tree_node *copy_decl_for_inlining PARAMS ((union tree_node *,
- union tree_node *,
- union tree_node *));
+extern tree copy_decl_for_inlining (tree, tree, tree);
/* Check whether there's any attribute in a function declaration that
makes the function uninlinable. Returns false if it finds any,
true otherwise. */
-extern bool function_attribute_inlinable_p PARAMS ((union tree_node *));
+extern bool function_attribute_inlinable_p (tree);
-extern void try_constants PARAMS ((rtx, struct inline_remap *));
+extern void try_constants (rtx, struct inline_remap *);
/* Return the label indicated. */
-extern rtx get_label_from_map PARAMS ((struct inline_remap *, int));
+extern rtx get_label_from_map (struct inline_remap *, int);
/* Set the label indicated. */
#define set_label_in_map(MAP, I, X) ((MAP)->label_map[I] = (X))
diff --git a/contrib/gcc/intl.c b/contrib/gcc/intl.c
index 87dad5135391..04613294ac41 100644
--- a/contrib/gcc/intl.c
+++ b/contrib/gcc/intl.c
@@ -1,5 +1,5 @@
/* Message translation utilities.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,6 +20,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "intl.h"
#ifdef ENABLE_NLS
@@ -30,7 +32,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
terminal, so it has be set to output messages correctly. */
void
-gcc_init_libintl ()
+gcc_init_libintl (void)
{
#ifdef HAVE_LC_MESSAGES
setlocale (LC_CTYPE, "");
@@ -43,4 +45,33 @@ gcc_init_libintl ()
(void) textdomain ("gcc");
}
+#if defined HAVE_WCHAR_H && defined HAVE_WORKING_MBSTOWCS && defined HAVE_WCSWIDTH
+#include <wchar.h>
+
+/* Returns the width in columns of MSGSTR, which came from gettext.
+ This is for indenting subsequent output. */
+
+size_t
+gcc_gettext_width (const char *msgstr)
+{
+ size_t nwcs = mbstowcs (0, msgstr, 0);
+ wchar_t *wmsgstr = alloca ((nwcs + 1) * sizeof (wchar_t));
+
+ mbstowcs (wmsgstr, msgstr, nwcs + 1);
+ return wcswidth (wmsgstr, nwcs);
+}
+
+#else /* no wcswidth */
+
+/* We don't have any way of knowing how wide the string is. Guess
+ the length of the string. */
+
+size_t
+gcc_gettext_width (const char *msgstr)
+{
+ return strlen (msgstr);
+}
+
#endif
+
+#endif /* ENABLE_NLS */
diff --git a/contrib/gcc/intl.h b/contrib/gcc/intl.h
index 8a9b35a66fd9..80a945b45f8e 100644
--- a/contrib/gcc/intl.h
+++ b/contrib/gcc/intl.h
@@ -1,5 +1,5 @@
/* intl.h - internationalization
- Copyright 1998, 2001 Free Software Foundation, Inc.
+ Copyright 1998, 2001, 2003 Free Software Foundation, Inc.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,18 +27,10 @@
# define setlocale(category, locale) (locale)
#endif
-#ifdef USE_INCLUDED_LIBINTL
-# include <intl/libgnuintl.h>
-#else
-# ifdef HAVE_LIBINTL_H
-# include <libintl.h>
-# else
-# undef ENABLE_NLS
-# endif
-#endif
-
#ifdef ENABLE_NLS
-extern void gcc_init_libintl PARAMS ((void));
+#include <libintl.h>
+extern void gcc_init_libintl (void);
+extern size_t gcc_gettext_width (const char *);
#else
/* Stubs. */
# undef textdomain
@@ -48,6 +40,7 @@ extern void gcc_init_libintl PARAMS ((void));
# undef gettext
# define gettext(msgid) (msgid)
# define gcc_init_libintl() /* nothing */
+# define gcc_gettext_width(s) strlen(s)
#endif
#ifndef _
@@ -55,7 +48,7 @@ extern void gcc_init_libintl PARAMS ((void));
#endif
#ifndef N_
-# define N_(msgid) (msgid)
+# define N_(msgid) msgid
#endif
#endif /* intl.h */
diff --git a/contrib/gcc/jump.c b/contrib/gcc/jump.c
index fffc8e7cbb1f..d2b53f8cf4b1 100644
--- a/contrib/gcc/jump.c
+++ b/contrib/gcc/jump.c
@@ -1,6 +1,6 @@
/* Optimize jump instructions, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
- 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -36,6 +36,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "flags.h"
@@ -48,9 +50,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "expr.h"
#include "real.h"
#include "except.h"
+#include "diagnostic.h"
#include "toplev.h"
#include "reload.h"
#include "predict.h"
+#include "timevar.h"
/* Optimize jump y; x: ... y: jumpif... x?
Don't know if it is worth bothering with. */
@@ -59,30 +63,28 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
or even change what is live at any point.
So perhaps let combiner do it. */
-static rtx next_nonnote_insn_in_loop PARAMS ((rtx));
-static int init_label_info PARAMS ((rtx));
-static void mark_all_labels PARAMS ((rtx));
-static int duplicate_loop_exit_test PARAMS ((rtx));
-static void delete_computation PARAMS ((rtx));
-static void redirect_exp_1 PARAMS ((rtx *, rtx, rtx, rtx));
-static int redirect_exp PARAMS ((rtx, rtx, rtx));
-static void invert_exp_1 PARAMS ((rtx));
-static int invert_exp PARAMS ((rtx));
-static int returnjump_p_1 PARAMS ((rtx *, void *));
-static void delete_prior_computation PARAMS ((rtx, rtx));
+static rtx next_nonnote_insn_in_loop (rtx);
+static void init_label_info (rtx);
+static void mark_all_labels (rtx);
+static int duplicate_loop_exit_test (rtx);
+static void delete_computation (rtx);
+static void redirect_exp_1 (rtx *, rtx, rtx, rtx);
+static int redirect_exp (rtx, rtx, rtx);
+static void invert_exp_1 (rtx);
+static int invert_exp (rtx);
+static int returnjump_p_1 (rtx *, void *);
+static void delete_prior_computation (rtx, rtx);
/* Alternate entry into the jump optimizer. This entry point only rebuilds
the JUMP_LABEL field in jumping insns and REG_LABEL notes in non-jumping
instructions. */
void
-rebuild_jump_labels (f)
- rtx f;
+rebuild_jump_labels (rtx f)
{
rtx insn;
- int max_uid = 0;
-
- max_uid = init_label_info (f) + 1;
+ timevar_push (TV_REBUILD_JUMP);
+ init_label_info (f);
mark_all_labels (f);
/* Keep track of labels used from static data; we don't track them
@@ -92,6 +94,7 @@ rebuild_jump_labels (f)
for (insn = forced_labels; insn; insn = XEXP (insn, 1))
if (GET_CODE (XEXP (insn, 0)) == CODE_LABEL)
LABEL_NUSES (XEXP (insn, 0))++;
+ timevar_pop (TV_REBUILD_JUMP);
}
/* Some old code expects exactly one BARRIER as the NEXT_INSN of a
@@ -103,7 +106,7 @@ rebuild_jump_labels (f)
old code is happy.
*/
void
-cleanup_barriers ()
+cleanup_barriers (void)
{
rtx insn, next, prev;
for (insn = get_insns (); insn; insn = next)
@@ -125,8 +128,7 @@ cleanup_barriers ()
This routine does not look inside SEQUENCEs. */
static rtx
-next_nonnote_insn_in_loop (insn)
- rtx insn;
+next_nonnote_insn_in_loop (rtx insn)
{
while (insn)
{
@@ -142,8 +144,7 @@ next_nonnote_insn_in_loop (insn)
}
void
-copy_loop_headers (f)
- rtx f;
+copy_loop_headers (rtx f)
{
rtx insn, next;
/* Now iterate optimizing jumps until nothing changes over one pass. */
@@ -172,8 +173,7 @@ copy_loop_headers (f)
}
void
-purge_line_number_notes (f)
- rtx f;
+purge_line_number_notes (rtx f)
{
rtx last_note = 0;
rtx insn;
@@ -208,44 +208,35 @@ purge_line_number_notes (f)
/* Initialize LABEL_NUSES and JUMP_LABEL fields. Delete any REG_LABEL
notes whose labels don't occur in the insn any more. Returns the
largest INSN_UID found. */
-static int
-init_label_info (f)
- rtx f;
+static void
+init_label_info (rtx f)
{
- int largest_uid = 0;
rtx insn;
for (insn = f; insn; insn = NEXT_INSN (insn))
- {
- if (GET_CODE (insn) == CODE_LABEL)
- LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
- else if (GET_CODE (insn) == JUMP_INSN)
- JUMP_LABEL (insn) = 0;
- else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
- {
- rtx note, next;
-
- for (note = REG_NOTES (insn); note; note = next)
- {
- next = XEXP (note, 1);
- if (REG_NOTE_KIND (note) == REG_LABEL
- && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
- remove_note (insn, note);
- }
- }
- if (INSN_UID (insn) > largest_uid)
- largest_uid = INSN_UID (insn);
- }
+ if (GET_CODE (insn) == CODE_LABEL)
+ LABEL_NUSES (insn) = (LABEL_PRESERVE_P (insn) != 0);
+ else if (GET_CODE (insn) == JUMP_INSN)
+ JUMP_LABEL (insn) = 0;
+ else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN)
+ {
+ rtx note, next;
- return largest_uid;
+ for (note = REG_NOTES (insn); note; note = next)
+ {
+ next = XEXP (note, 1);
+ if (REG_NOTE_KIND (note) == REG_LABEL
+ && ! reg_mentioned_p (XEXP (note, 0), PATTERN (insn)))
+ remove_note (insn, note);
+ }
+ }
}
/* Mark the label each jump jumps to.
Combine consecutive labels, and count uses of labels. */
static void
-mark_all_labels (f)
- rtx f;
+mark_all_labels (rtx f)
{
rtx insn;
@@ -309,8 +300,7 @@ mark_all_labels (f)
values of regno_first_uid and regno_last_uid. */
static int
-duplicate_loop_exit_test (loop_start)
- rtx loop_start;
+duplicate_loop_exit_test (rtx loop_start)
{
rtx insn, set, reg, p, link;
rtx copy = 0, first_copy = 0;
@@ -360,10 +350,6 @@ duplicate_loop_exit_test (loop_start)
break;
case JUMP_INSN:
case INSN:
- /* The code below would grossly mishandle REG_WAS_0 notes,
- so get rid of them here. */
- while ((p = find_reg_note (insn, REG_WAS_0, NULL_RTX)) != 0)
- remove_note (insn, p);
if (++num_insns > 20
|| find_reg_note (insn, REG_RETVAL, NULL_RTX)
|| find_reg_note (insn, REG_LIBCALL, NULL_RTX))
@@ -400,7 +386,7 @@ duplicate_loop_exit_test (loop_start)
/* We can do the replacement. Allocate reg_map if this is the
first replacement we found. */
if (reg_map == 0)
- reg_map = (rtx *) xcalloc (max_reg, sizeof (rtx));
+ reg_map = xcalloc (max_reg, sizeof (rtx));
REG_LOOP_TEST_P (reg) = 1;
@@ -432,7 +418,7 @@ duplicate_loop_exit_test (loop_start)
replace_regs (PATTERN (copy), reg_map, max_reg, 1);
mark_jump_label (PATTERN (copy), copy, 0);
- INSN_SCOPE (copy) = INSN_SCOPE (insn);
+ INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
/* Copy all REG_NOTES except REG_LABEL since mark_jump_label will
make them. */
@@ -458,7 +444,7 @@ duplicate_loop_exit_test (loop_start)
case JUMP_INSN:
copy = emit_jump_insn_before (copy_insn (PATTERN (insn)),
loop_start);
- INSN_SCOPE (copy) = INSN_SCOPE (insn);
+ INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
if (reg_map)
replace_regs (PATTERN (copy), reg_map, max_reg, 1);
mark_jump_label (PATTERN (copy), copy, 0);
@@ -548,9 +534,7 @@ duplicate_loop_exit_test (loop_start)
Return true if there were only such notes and no real instructions. */
bool
-squeeze_notes (startp, endp)
- rtx* startp;
- rtx* endp;
+squeeze_notes (rtx* startp, rtx* endp)
{
rtx start = *startp;
rtx end = *endp;
@@ -602,8 +586,7 @@ squeeze_notes (startp, endp)
/* Return the label before INSN, or put a new label there. */
rtx
-get_label_before (insn)
- rtx insn;
+get_label_before (rtx insn)
{
rtx label;
@@ -625,8 +608,7 @@ get_label_before (insn)
/* Return the label after INSN, or put a new label there. */
rtx
-get_label_after (insn)
- rtx insn;
+get_label_after (rtx insn)
{
rtx label;
@@ -650,9 +632,7 @@ get_label_after (insn)
description should define REVERSIBLE_CC_MODE and REVERSE_CONDITION macros
to help this function avoid overhead in these cases. */
enum rtx_code
-reversed_comparison_code_parts (code, arg0, arg1, insn)
- rtx insn, arg0, arg1;
- enum rtx_code code;
+reversed_comparison_code_parts (enum rtx_code code, rtx arg0, rtx arg1, rtx insn)
{
enum machine_mode mode;
@@ -688,7 +668,7 @@ reversed_comparison_code_parts (code, arg0, arg1, insn)
case NE:
case EQ:
/* It is always safe to reverse EQ and NE, even for the floating
- point. Similary the unsigned comparisons are never used for
+ point. Similarly the unsigned comparisons are never used for
floating point so we can reverse them in the default way. */
return reverse_condition (code);
case ORDERED:
@@ -708,11 +688,7 @@ reversed_comparison_code_parts (code, arg0, arg1, insn)
break;
}
- if (GET_MODE_CLASS (mode) == MODE_CC
-#ifdef HAVE_cc0
- || arg0 == cc0_rtx
-#endif
- )
+ if (GET_MODE_CLASS (mode) == MODE_CC || CC0_P (arg0))
{
rtx prev;
/* Try to search for the comparison to determine the real mode.
@@ -767,11 +743,10 @@ reversed_comparison_code_parts (code, arg0, arg1, insn)
return UNKNOWN;
}
-/* An wrapper around the previous function to take COMPARISON as rtx
+/* A wrapper around the previous function to take COMPARISON as rtx
expression. This simplifies many callers. */
enum rtx_code
-reversed_comparison_code (comparison, insn)
- rtx comparison, insn;
+reversed_comparison_code (rtx comparison, rtx insn)
{
if (GET_RTX_CLASS (GET_CODE (comparison)) != '<')
return UNKNOWN;
@@ -789,8 +764,7 @@ reversed_comparison_code (comparison, insn)
Use reversed_comparison_code instead. */
enum rtx_code
-reverse_condition (code)
- enum rtx_code code;
+reverse_condition (enum rtx_code code)
{
switch (code)
{
@@ -837,8 +811,7 @@ reverse_condition (code)
that the target will support them too... */
enum rtx_code
-reverse_condition_maybe_unordered (code)
- enum rtx_code code;
+reverse_condition_maybe_unordered (enum rtx_code code)
{
switch (code)
{
@@ -880,8 +853,7 @@ reverse_condition_maybe_unordered (code)
This IS safe for IEEE floating-point. */
enum rtx_code
-swap_condition (code)
- enum rtx_code code;
+swap_condition (enum rtx_code code)
{
switch (code)
{
@@ -928,8 +900,7 @@ swap_condition (code)
CODE is returned. */
enum rtx_code
-unsigned_condition (code)
- enum rtx_code code;
+unsigned_condition (enum rtx_code code)
{
switch (code)
{
@@ -958,8 +929,7 @@ unsigned_condition (code)
/* Similarly, return the signed version of a comparison. */
enum rtx_code
-signed_condition (code)
- enum rtx_code code;
+signed_condition (enum rtx_code code)
{
switch (code)
{
@@ -989,8 +959,7 @@ signed_condition (code)
truth of CODE1 implies the truth of CODE2. */
int
-comparison_dominates_p (code1, code2)
- enum rtx_code code1, code2;
+comparison_dominates_p (enum rtx_code code1, enum rtx_code code2)
{
/* UNKNOWN comparison codes can happen as a result of trying to revert
comparison codes.
@@ -1071,8 +1040,7 @@ comparison_dominates_p (code1, code2)
/* Return 1 if INSN is an unconditional jump and nothing else. */
int
-simplejump_p (insn)
- rtx insn;
+simplejump_p (rtx insn)
{
return (GET_CODE (insn) == JUMP_INSN
&& GET_CODE (PATTERN (insn)) == SET
@@ -1080,22 +1048,6 @@ simplejump_p (insn)
&& GET_CODE (SET_SRC (PATTERN (insn))) == LABEL_REF);
}
-/* Return 1 if INSN is an tablejump. */
-
-int
-tablejump_p (insn)
- rtx insn;
-{
- rtx table;
- return (GET_CODE (insn) == JUMP_INSN
- && JUMP_LABEL (insn)
- && NEXT_INSN (JUMP_LABEL (insn))
- && (table = next_active_insn (JUMP_LABEL (insn)))
- && GET_CODE (table) == JUMP_INSN
- && (GET_CODE (PATTERN (table)) == ADDR_VEC
- || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC));
-}
-
/* Return nonzero if INSN is a (possibly) conditional jump
and nothing more.
@@ -1103,8 +1055,7 @@ tablejump_p (insn)
branch and compare insns. Use any_condjump_p instead whenever possible. */
int
-condjump_p (insn)
- rtx insn;
+condjump_p (rtx insn)
{
rtx x = PATTERN (insn);
@@ -1134,8 +1085,7 @@ condjump_p (insn)
branch and compare insns. Use any_condjump_p instead whenever possible. */
int
-condjump_in_parallel_p (insn)
- rtx insn;
+condjump_in_parallel_p (rtx insn)
{
rtx x = PATTERN (insn);
@@ -1166,8 +1116,7 @@ condjump_in_parallel_p (insn)
/* Return set of PC, otherwise NULL. */
rtx
-pc_set (insn)
- rtx insn;
+pc_set (rtx insn)
{
rtx pat;
if (GET_CODE (insn) != JUMP_INSN)
@@ -1188,8 +1137,7 @@ pc_set (insn)
possibly bundled inside a PARALLEL. */
int
-any_uncondjump_p (insn)
- rtx insn;
+any_uncondjump_p (rtx insn)
{
rtx x = pc_set (insn);
if (!x)
@@ -1207,8 +1155,7 @@ any_uncondjump_p (insn)
Note that unlike condjump_p it returns false for unconditional jumps. */
int
-any_condjump_p (insn)
- rtx insn;
+any_condjump_p (rtx insn)
{
rtx x = pc_set (insn);
enum rtx_code a, b;
@@ -1228,8 +1175,7 @@ any_condjump_p (insn)
/* Return the label of a conditional jump. */
rtx
-condjump_label (insn)
- rtx insn;
+condjump_label (rtx insn)
{
rtx x = pc_set (insn);
@@ -1250,9 +1196,7 @@ condjump_label (insn)
/* Return true if INSN is a (possibly conditional) return insn. */
static int
-returnjump_p_1 (loc, data)
- rtx *loc;
- void *data ATTRIBUTE_UNUSED;
+returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
rtx x = *loc;
@@ -1261,8 +1205,7 @@ returnjump_p_1 (loc, data)
}
int
-returnjump_p (insn)
- rtx insn;
+returnjump_p (rtx insn)
{
if (GET_CODE (insn) != JUMP_INSN)
return 0;
@@ -1273,8 +1216,7 @@ returnjump_p (insn)
nothing more. */
int
-onlyjump_p (insn)
- rtx insn;
+onlyjump_p (rtx insn)
{
rtx set;
@@ -1298,10 +1240,8 @@ onlyjump_p (insn)
and has no side effects. */
int
-only_sets_cc0_p (x)
- rtx x;
+only_sets_cc0_p (rtx x)
{
-
if (! x)
return 0;
@@ -1317,10 +1257,8 @@ only_sets_cc0_p (x)
but also does other things. */
int
-sets_cc0_p (x)
- rtx x;
+sets_cc0_p (rtx x)
{
-
if (! x)
return 0;
@@ -1358,8 +1296,7 @@ sets_cc0_p (x)
a USE or CLOBBER. */
rtx
-follow_jumps (label)
- rtx label;
+follow_jumps (rtx label)
{
rtx insn;
rtx next;
@@ -1422,10 +1359,7 @@ follow_jumps (label)
that loop-optimization is done with. */
void
-mark_jump_label (x, insn, in_mem)
- rtx x;
- rtx insn;
- int in_mem;
+mark_jump_label (rtx x, rtx insn, int in_mem)
{
RTX_CODE code = GET_CODE (x);
int i;
@@ -1530,8 +1464,7 @@ mark_jump_label (x, insn, in_mem)
if that's what the previous thing was. */
void
-delete_jump (insn)
- rtx insn;
+delete_jump (rtx insn)
{
rtx set = single_set (insn);
@@ -1542,8 +1475,7 @@ delete_jump (insn)
/* Verify INSN is a BARRIER and delete it. */
void
-delete_barrier (insn)
- rtx insn;
+delete_barrier (rtx insn)
{
if (GET_CODE (insn) != BARRIER)
abort ();
@@ -1556,9 +1488,7 @@ delete_barrier (insn)
which is a REG_DEAD note associated with INSN. */
static void
-delete_prior_computation (note, insn)
- rtx note;
- rtx insn;
+delete_prior_computation (rtx note, rtx insn)
{
rtx our_prev;
rtx reg = XEXP (note, 0);
@@ -1684,8 +1614,7 @@ delete_prior_computation (note, insn)
delete the insn that set it. */
static void
-delete_computation (insn)
- rtx insn;
+delete_computation (rtx insn)
{
rtx note, next;
@@ -1729,16 +1658,15 @@ delete_computation (insn)
}
/* Delete insn INSN from the chain of insns and update label ref counts
- and delete insns now unreachable.
+ and delete insns now unreachable.
- Returns the first insn after INSN that was not deleted.
+ Returns the first insn after INSN that was not deleted.
Usage of this instruction is deprecated. Use delete_insn instead and
subsequent cfg_cleanup pass to delete unreachable code if needed. */
rtx
-delete_related_insns (insn)
- rtx insn;
+delete_related_insns (rtx insn)
{
int was_code_label = (GET_CODE (insn) == CODE_LABEL);
rtx note;
@@ -1781,10 +1709,7 @@ delete_related_insns (insn)
next = NEXT_INSN (next);
return next;
}
- else if ((lab_next = next_nonnote_insn (lab)) != NULL
- && GET_CODE (lab_next) == JUMP_INSN
- && (GET_CODE (PATTERN (lab_next)) == ADDR_VEC
- || GET_CODE (PATTERN (lab_next)) == ADDR_DIFF_VEC))
+ else if (tablejump_p (insn, NULL, &lab_next))
{
/* If we're deleting the tablejump, delete the dispatch table.
We may not be able to kill the label immediately preceding
@@ -1862,18 +1787,6 @@ delete_related_insns (insn)
return next;
}
-
-/* Advance from INSN till reaching something not deleted
- then return that. May return INSN itself. */
-
-rtx
-next_nondeleted_insn (insn)
- rtx insn;
-{
- while (INSN_DELETED_P (insn))
- insn = NEXT_INSN (insn);
- return insn;
-}
/* Delete a range of insns from FROM to TO, inclusive.
This is for the sake of peephole optimization, so assume
@@ -1881,8 +1794,7 @@ next_nondeleted_insn (insn)
peephole insn that will replace them. */
void
-delete_for_peephole (from, to)
- rtx from, to;
+delete_for_peephole (rtx from, rtx to)
{
rtx insn = from;
@@ -1926,8 +1838,7 @@ delete_for_peephole (from, to)
spurious warnings from this. */
void
-never_reached_warning (avoided_insn, finish)
- rtx avoided_insn, finish;
+never_reached_warning (rtx avoided_insn, rtx finish)
{
rtx insn;
rtx a_line_note = NULL;
@@ -1978,19 +1889,19 @@ never_reached_warning (avoided_insn, finish)
reached_end = 1;
}
if (two_avoided_lines && contains_insn)
- warning_with_file_and_line (NOTE_SOURCE_FILE (a_line_note),
- NOTE_LINE_NUMBER (a_line_note),
- "will never be executed");
+ {
+ location_t locus;
+ locus.file = NOTE_SOURCE_FILE (a_line_note);
+ locus.line = NOTE_LINE_NUMBER (a_line_note);
+ warning ("%Hwill never be executed", &locus);
+ }
}
/* Throughout LOC, redirect OLABEL to NLABEL. Treat null OLABEL or
NLABEL as a return. Accrue modifications into the change group. */
static void
-redirect_exp_1 (loc, olabel, nlabel, insn)
- rtx *loc;
- rtx olabel, nlabel;
- rtx insn;
+redirect_exp_1 (rtx *loc, rtx olabel, rtx nlabel, rtx insn)
{
rtx x = *loc;
RTX_CODE code = GET_CODE (x);
@@ -2045,9 +1956,7 @@ redirect_exp_1 (loc, olabel, nlabel, insn)
/* Similar, but apply the change group and report success or failure. */
static int
-redirect_exp (olabel, nlabel, insn)
- rtx olabel, nlabel;
- rtx insn;
+redirect_exp (rtx olabel, rtx nlabel, rtx insn)
{
rtx *loc;
@@ -2068,8 +1977,7 @@ redirect_exp (olabel, nlabel, insn)
not see how to do that. */
int
-redirect_jump_1 (jump, nlabel)
- rtx jump, nlabel;
+redirect_jump_1 (rtx jump, rtx nlabel)
{
int ochanges = num_validated_changes ();
rtx *loc;
@@ -2094,11 +2002,10 @@ redirect_jump_1 (jump, nlabel)
(this can only occur for NLABEL == 0). */
int
-redirect_jump (jump, nlabel, delete_unused)
- rtx jump, nlabel;
- int delete_unused;
+redirect_jump (rtx jump, rtx nlabel, int delete_unused)
{
rtx olabel = JUMP_LABEL (jump);
+ rtx note;
if (nlabel == olabel)
return 1;
@@ -2110,6 +2017,29 @@ redirect_jump (jump, nlabel, delete_unused)
if (nlabel)
++LABEL_NUSES (nlabel);
+ /* Update labels in any REG_EQUAL note. */
+ if ((note = find_reg_note (jump, REG_EQUAL, NULL_RTX)) != NULL_RTX)
+ {
+ if (nlabel && olabel)
+ {
+ rtx dest = XEXP (note, 0);
+
+ if (GET_CODE (dest) == IF_THEN_ELSE)
+ {
+ if (GET_CODE (XEXP (dest, 1)) == LABEL_REF
+ && XEXP (XEXP (dest, 1), 0) == olabel)
+ XEXP (XEXP (dest, 1), 0) = nlabel;
+ if (GET_CODE (XEXP (dest, 2)) == LABEL_REF
+ && XEXP (XEXP (dest, 2), 0) == olabel)
+ XEXP (XEXP (dest, 2), 0) = nlabel;
+ }
+ else
+ remove_note (jump, note);
+ }
+ else
+ remove_note (jump, note);
+ }
+
/* If we're eliding the jump over exception cleanups at the end of a
function, move the function end note so that -Wreturn-type works. */
if (olabel && nlabel
@@ -2130,8 +2060,7 @@ redirect_jump (jump, nlabel, delete_unused)
Accrue the modifications into the change group. */
static void
-invert_exp_1 (insn)
- rtx insn;
+invert_exp_1 (rtx insn)
{
RTX_CODE code;
rtx x = pc_set (insn);
@@ -2179,8 +2108,7 @@ invert_exp_1 (insn)
matches a pattern. */
static int
-invert_exp (insn)
- rtx insn;
+invert_exp (rtx insn)
{
invert_exp_1 (insn);
if (num_validated_changes () == 0)
@@ -2195,8 +2123,7 @@ invert_exp (insn)
inversion and redirection. */
int
-invert_jump_1 (jump, nlabel)
- rtx jump, nlabel;
+invert_jump_1 (rtx jump, rtx nlabel)
{
int ochanges;
@@ -2212,9 +2139,7 @@ invert_jump_1 (jump, nlabel)
NLABEL instead of where it jumps now. Return true if successful. */
int
-invert_jump (jump, nlabel, delete_unused)
- rtx jump, nlabel;
- int delete_unused;
+invert_jump (rtx jump, rtx nlabel, int delete_unused)
{
/* We have to either invert the condition and change the label or
do neither. Either operation could fail. We first try to invert
@@ -2226,6 +2151,11 @@ invert_jump (jump, nlabel, delete_unused)
if (redirect_jump (jump, nlabel, delete_unused))
{
+ /* Remove REG_EQUAL note if we have one. */
+ rtx note = find_reg_note (jump, REG_EQUAL, NULL_RTX);
+ if (note)
+ remove_note (jump, note);
+
invert_br_probabilities (jump);
return 1;
@@ -2253,8 +2183,7 @@ invert_jump (jump, nlabel, delete_unused)
case when the PLUS is inside a MEM. */
int
-rtx_renumbered_equal_p (x, y)
- rtx x, y;
+rtx_renumbered_equal_p (rtx x, rtx y)
{
int i;
RTX_CODE code = GET_CODE (x);
@@ -2334,10 +2263,8 @@ rtx_renumbered_equal_p (x, y)
case CC0:
case ADDR_VEC:
case ADDR_DIFF_VEC:
- return 0;
-
case CONST_INT:
- return INTVAL (x) == INTVAL (y);
+ return 0;
case LABEL_REF:
/* We can't assume nonlocal labels have their following insns yet. */
@@ -2418,7 +2345,7 @@ rtx_renumbered_equal_p (x, y)
case 'u':
if (XEXP (x, i) != XEXP (y, i))
return 0;
- /* fall through. */
+ /* Fall through. */
case '0':
break;
@@ -2443,8 +2370,7 @@ rtx_renumbered_equal_p (x, y)
return -1. Any rtx is valid for X. */
int
-true_regnum (x)
- rtx x;
+true_regnum (rtx x)
{
if (GET_CODE (x) == REG)
{
@@ -2465,8 +2391,7 @@ true_regnum (x)
/* Return regno of the register REG and handle subregs too. */
unsigned int
-reg_or_subregno (reg)
- rtx reg;
+reg_or_subregno (rtx reg)
{
if (REG_P (reg))
return REGNO (reg);
diff --git a/contrib/gcc/langhooks-def.h b/contrib/gcc/langhooks-def.h
index 83b8b45b67f7..7caab7809bec 100644
--- a/contrib/gcc/langhooks-def.h
+++ b/contrib/gcc/langhooks-def.h
@@ -1,21 +1,21 @@
/* Default macros to initialize the lang_hooks data structure.
- Copyright 2001, 2002 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <aoliva@redhat.com>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -28,72 +28,77 @@ struct diagnostic_context;
/* Provide a hook routine for alias sets that always returns 1. This is
used by languages that haven't deal with alias sets yet. */
-extern HOST_WIDE_INT hook_get_alias_set_0 PARAMS ((tree));
+extern HOST_WIDE_INT hook_get_alias_set_0 (tree);
/* Note to creators of new hooks:
The macros in this file should NOT be surrounded by a
#ifdef...#endif pair, since this file declares the defaults. Each
front end overrides any hooks it wishes to, in the file containing
- its struct lang_hooks, AFTER including this file.
-
- Prefix all default hooks with "lhd_". */
+ its struct lang_hooks, AFTER including this file. */
/* See langhooks.h for the definition and documentation of each hook. */
-extern void lhd_do_nothing PARAMS ((void));
-extern void lhd_do_nothing_t PARAMS ((tree));
-extern void lhd_do_nothing_i PARAMS ((int));
-extern void lhd_do_nothing_f PARAMS ((struct function *));
-extern int lhd_decode_option PARAMS ((int, char **));
-extern HOST_WIDE_INT lhd_get_alias_set PARAMS ((tree));
-extern tree lhd_return_tree PARAMS ((tree));
-extern tree lhd_return_null_tree PARAMS ((tree));
-extern int lhd_safe_from_p PARAMS ((rtx, tree));
-extern int lhd_staticp PARAMS ((tree));
-extern int lhd_unsafe_for_reeval PARAMS ((tree));
-extern void lhd_clear_binding_stack PARAMS ((void));
-extern void lhd_print_tree_nothing PARAMS ((FILE *, tree, int));
-extern const char *lhd_decl_printable_name PARAMS ((tree, int));
-extern rtx lhd_expand_expr PARAMS ((tree, rtx, enum machine_mode, int));
-extern void lhd_print_error_function PARAMS ((struct diagnostic_context *,
- const char *));
-extern void lhd_set_decl_assembler_name PARAMS ((tree));
-extern bool lhd_can_use_bit_fields_p PARAMS ((void));
-extern bool lhd_warn_unused_global_decl PARAMS ((tree));
-extern void lhd_incomplete_type_error PARAMS ((tree, tree));
-extern tree lhd_type_promotes_to PARAMS ((tree));
-extern bool lhd_decl_ok_for_sibcall PARAMS ((tree));
-extern tree lhd_expr_size PARAMS ((tree));
+extern void lhd_do_nothing (void);
+extern void lhd_do_nothing_t (tree);
+extern void lhd_do_nothing_i (int);
+extern void lhd_do_nothing_f (struct function *);
+extern bool lhd_post_options (const char **);
+extern HOST_WIDE_INT lhd_get_alias_set (tree);
+extern tree lhd_return_tree (tree);
+extern tree lhd_return_null_tree_v (void);
+extern tree lhd_return_null_tree (tree);
+extern tree lhd_do_nothing_iii_return_null_tree (int, int, int);
+extern int lhd_safe_from_p (rtx, tree);
+extern int lhd_staticp (tree);
+extern int lhd_unsafe_for_reeval (tree);
+extern void lhd_clear_binding_stack (void);
+extern void lhd_print_tree_nothing (FILE *, tree, int);
+extern const char *lhd_decl_printable_name (tree, int);
+extern rtx lhd_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
+extern void lhd_print_error_function (struct diagnostic_context *,
+ const char *);
+extern void lhd_set_decl_assembler_name (tree);
+extern bool lhd_can_use_bit_fields_p (void);
+extern bool lhd_warn_unused_global_decl (tree);
+extern void lhd_incomplete_type_error (tree, tree);
+extern tree lhd_type_promotes_to (tree);
+extern void lhd_register_builtin_type (tree, const char *);
+extern bool lhd_decl_ok_for_sibcall (tree);
+extern tree lhd_expr_size (tree);
+extern bool lhd_decl_uninit (tree);
+extern tree lhd_get_callee_fndecl (tree);
+extern size_t lhd_tree_size (enum tree_code);
/* Declarations of default tree inlining hooks. */
-tree lhd_tree_inlining_walk_subtrees PARAMS ((tree *, int *,
- walk_tree_fn,
- void *, void *));
-int lhd_tree_inlining_cannot_inline_tree_fn PARAMS ((tree *));
-int lhd_tree_inlining_disregard_inline_limits PARAMS ((tree));
-tree lhd_tree_inlining_add_pending_fn_decls PARAMS ((void *, tree));
-int lhd_tree_inlining_tree_chain_matters_p PARAMS ((tree));
-int lhd_tree_inlining_auto_var_in_fn_p PARAMS ((tree, tree));
-tree lhd_tree_inlining_copy_res_decl_for_inlining PARAMS ((tree, tree,
- tree, void *,
- int *, void *));
-int lhd_tree_inlining_anon_aggr_type_p PARAMS ((tree));
-int lhd_tree_inlining_start_inlining PARAMS ((tree));
-void lhd_tree_inlining_end_inlining PARAMS ((tree));
-tree lhd_tree_inlining_convert_parm_for_inlining PARAMS ((tree, tree, tree));
-
-void write_global_declarations PARAMS ((void));
+extern tree lhd_tree_inlining_walk_subtrees (tree *, int *, walk_tree_fn,
+ void *, void *);
+extern int lhd_tree_inlining_cannot_inline_tree_fn (tree *);
+extern int lhd_tree_inlining_disregard_inline_limits (tree);
+extern tree lhd_tree_inlining_add_pending_fn_decls (void *, tree);
+extern int lhd_tree_inlining_tree_chain_matters_p (tree);
+extern int lhd_tree_inlining_auto_var_in_fn_p (tree, tree);
+extern tree lhd_tree_inlining_copy_res_decl_for_inlining (tree, tree, tree,
+ void *, int *, tree);
+extern int lhd_tree_inlining_anon_aggr_type_p (tree);
+extern int lhd_tree_inlining_start_inlining (tree);
+extern void lhd_tree_inlining_end_inlining (tree);
+extern tree lhd_tree_inlining_convert_parm_for_inlining (tree, tree, tree, int);
+extern void lhd_initialize_diagnostics (struct diagnostic_context *);
+extern tree lhd_callgraph_analyze_expr (tree *, int *, tree);
+
#define LANG_HOOKS_NAME "GNU unknown"
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
-#define LANG_HOOKS_INIT lhd_do_nothing
+#define LANG_HOOKS_INIT hook_bool_void_false
#define LANG_HOOKS_FINISH lhd_do_nothing
#define LANG_HOOKS_PARSE_FILE lhd_do_nothing_i
#define LANG_HOOKS_CLEAR_BINDING_STACK lhd_clear_binding_stack
-#define LANG_HOOKS_INIT_OPTIONS lhd_do_nothing
-#define LANG_HOOKS_DECODE_OPTION lhd_decode_option
-#define LANG_HOOKS_POST_OPTIONS hook_bool_void_false
+#define LANG_HOOKS_INIT_OPTIONS hook_uint_uint_constcharptrptr_0
+#define LANG_HOOKS_INITIALIZE_DIAGNOSTICS lhd_initialize_diagnostics
+#define LANG_HOOKS_HANDLE_OPTION hook_int_size_t_constcharptr_int_0
+#define LANG_HOOKS_MISSING_ARGUMENT hook_bool_constcharptr_size_t_false
+#define LANG_HOOKS_POST_OPTIONS lhd_post_options
#define LANG_HOOKS_GET_ALIAS_SET lhd_get_alias_set
#define LANG_HOOKS_EXPAND_CONSTANT lhd_return_tree
#define LANG_HOOKS_EXPAND_EXPR lhd_expand_expr
@@ -101,13 +106,13 @@ void write_global_declarations PARAMS ((void));
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL lhd_do_nothing_t
#define LANG_HOOKS_UNSAFE_FOR_REEVAL lhd_unsafe_for_reeval
#define LANG_HOOKS_STATICP lhd_staticp
-#define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES lhd_do_nothing_t
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL lhd_do_nothing_t
#define LANG_HOOKS_UNSAVE_EXPR_NOW lhd_unsave_expr_now
#define LANG_HOOKS_MAYBE_BUILD_CLEANUP lhd_return_null_tree
#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME lhd_set_decl_assembler_name
#define LANG_HOOKS_CAN_USE_BIT_FIELDS_P lhd_can_use_bit_fields_p
#define LANG_HOOKS_HONOR_READONLY false
+#define LANG_HOOKS_NO_BODY_BLOCKS false
#define LANG_HOOKS_PRINT_STATISTICS lhd_do_nothing
#define LANG_HOOKS_PRINT_XNODE lhd_print_tree_nothing
#define LANG_HOOKS_PRINT_DECL lhd_print_tree_nothing
@@ -115,13 +120,20 @@ void write_global_declarations PARAMS ((void));
#define LANG_HOOKS_PRINT_IDENTIFIER lhd_print_tree_nothing
#define LANG_HOOKS_PRINT_ERROR_FUNCTION lhd_print_error_function
#define LANG_HOOKS_DECL_PRINTABLE_NAME lhd_decl_printable_name
+#define LANG_HOOKS_GET_CALLEE_FNDECL lhd_return_null_tree
#define LANG_HOOKS_EXPR_SIZE lhd_expr_size
+#define LANG_HOOKS_DECL_UNINIT lhd_decl_uninit
+#define LANG_HOOKS_TREE_SIZE lhd_tree_size
#define LANG_HOOKS_FUNCTION_INIT lhd_do_nothing_f
#define LANG_HOOKS_FUNCTION_FINAL lhd_do_nothing_f
#define LANG_HOOKS_FUNCTION_ENTER_NESTED lhd_do_nothing_f
#define LANG_HOOKS_FUNCTION_LEAVE_NESTED lhd_do_nothing_f
+#define LANG_HOOKS_RTL_EXPAND_START lhd_do_nothing
+#define LANG_HOOKS_RTL_EXPAND_STMT (void (*) (tree)) abort
+#define LANG_HOOKS_RTL_EXPAND_END lhd_do_nothing
+
/* Attribute hooks. */
#define LANG_HOOKS_ATTRIBUTE_TABLE NULL
#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE NULL
@@ -151,6 +163,8 @@ void write_global_declarations PARAMS ((void));
lhd_tree_inlining_end_inlining
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
lhd_tree_inlining_convert_parm_for_inlining
+#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS \
+ NULL
#define LANG_HOOKS_TREE_INLINING_INITIALIZER { \
LANG_HOOKS_TREE_INLINING_WALK_SUBTREES, \
@@ -164,8 +178,17 @@ void write_global_declarations PARAMS ((void));
LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P, \
LANG_HOOKS_TREE_INLINING_START_INLINING, \
LANG_HOOKS_TREE_INLINING_END_INLINING, \
- LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
-} \
+ LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING, \
+ LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS \
+}
+
+#define LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR lhd_callgraph_analyze_expr
+#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION NULL
+
+#define LANG_HOOKS_CALLGRAPH_INITIALIZER { \
+ LANG_HOOKS_CALLGRAPH_ANALYZE_EXPR, \
+ LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION, \
+}
#define LANG_HOOKS_FUNCTION_INITIALIZER { \
LANG_HOOKS_FUNCTION_INIT, \
@@ -174,9 +197,15 @@ void write_global_declarations PARAMS ((void));
LANG_HOOKS_FUNCTION_LEAVE_NESTED \
}
+#define LANG_HOOKS_RTL_EXPAND_INITIALIZER { \
+ LANG_HOOKS_RTL_EXPAND_START, \
+ LANG_HOOKS_RTL_EXPAND_STMT, \
+ LANG_HOOKS_RTL_EXPAND_END \
+}
+
/* Tree dump hooks. */
-int lhd_tree_dump_dump_tree PARAMS ((void *, tree));
-int lhd_tree_dump_type_quals PARAMS ((tree));
+extern bool lhd_tree_dump_dump_tree (void *, tree);
+extern int lhd_tree_dump_type_quals (tree);
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN lhd_tree_dump_dump_tree
#define LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN lhd_tree_dump_type_quals
@@ -191,6 +220,7 @@ int lhd_tree_dump_type_quals PARAMS ((tree));
#define LANG_HOOKS_MAKE_TYPE make_node
#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR lhd_incomplete_type_error
#define LANG_HOOKS_TYPE_PROMOTES_TO lhd_type_promotes_to
+#define LANG_HOOKS_REGISTER_BUILTIN_TYPE lhd_register_builtin_type
#define LANG_HOOKS_FOR_TYPES_INITIALIZER { \
LANG_HOOKS_MAKE_TYPE, \
@@ -200,6 +230,7 @@ int lhd_tree_dump_type_quals PARAMS ((tree));
LANG_HOOKS_SIGNED_TYPE, \
LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE, \
LANG_HOOKS_TYPE_PROMOTES_TO, \
+ LANG_HOOKS_REGISTER_BUILTIN_TYPE, \
LANG_HOOKS_INCOMPLETE_TYPE_ERROR \
}
@@ -211,8 +242,10 @@ int lhd_tree_dump_type_quals PARAMS ((tree));
#define LANG_HOOKS_SET_BLOCK set_block
#define LANG_HOOKS_PUSHDECL pushdecl
#define LANG_HOOKS_GETDECLS getdecls
+#define LANG_HOOKS_BUILTIN_TYPE_DECLS lhd_return_null_tree_v
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
#define LANG_HOOKS_WRITE_GLOBALS write_global_declarations
+#define LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE NULL
#define LANG_HOOKS_DECL_OK_FOR_SIBCALL lhd_decl_ok_for_sibcall
#define LANG_HOOKS_DECLS { \
@@ -223,8 +256,10 @@ int lhd_tree_dump_type_quals PARAMS ((tree));
LANG_HOOKS_SET_BLOCK, \
LANG_HOOKS_PUSHDECL, \
LANG_HOOKS_GETDECLS, \
+ LANG_HOOKS_BUILTIN_TYPE_DECLS, \
LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
LANG_HOOKS_WRITE_GLOBALS, \
+ LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE, \
LANG_HOOKS_DECL_OK_FOR_SIBCALL, \
}
@@ -232,8 +267,11 @@ int lhd_tree_dump_type_quals PARAMS ((tree));
#define LANG_HOOKS_INITIALIZER { \
LANG_HOOKS_NAME, \
LANG_HOOKS_IDENTIFIER_SIZE, \
+ LANG_HOOKS_TREE_SIZE, \
LANG_HOOKS_INIT_OPTIONS, \
- LANG_HOOKS_DECODE_OPTION, \
+ LANG_HOOKS_INITIALIZE_DIAGNOSTICS, \
+ LANG_HOOKS_HANDLE_OPTION, \
+ LANG_HOOKS_MISSING_ARGUMENT, \
LANG_HOOKS_POST_OPTIONS, \
LANG_HOOKS_INIT, \
LANG_HOOKS_FINISH, \
@@ -243,7 +281,6 @@ int lhd_tree_dump_type_quals PARAMS ((tree));
LANG_HOOKS_EXPAND_CONSTANT, \
LANG_HOOKS_EXPAND_EXPR, \
LANG_HOOKS_TRUTHVALUE_CONVERSION, \
- LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES, \
LANG_HOOKS_SAFE_FROM_P, \
LANG_HOOKS_FINISH_INCOMPLETE_DECL, \
LANG_HOOKS_UNSAFE_FOR_REEVAL, \
@@ -255,22 +292,27 @@ int lhd_tree_dump_type_quals PARAMS ((tree));
LANG_HOOKS_SET_DECL_ASSEMBLER_NAME, \
LANG_HOOKS_CAN_USE_BIT_FIELDS_P, \
LANG_HOOKS_HONOR_READONLY, \
+ LANG_HOOKS_NO_BODY_BLOCKS, \
LANG_HOOKS_PRINT_STATISTICS, \
LANG_HOOKS_PRINT_XNODE, \
LANG_HOOKS_PRINT_DECL, \
LANG_HOOKS_PRINT_TYPE, \
LANG_HOOKS_PRINT_IDENTIFIER, \
LANG_HOOKS_DECL_PRINTABLE_NAME, \
+ LANG_HOOKS_GET_CALLEE_FNDECL, \
LANG_HOOKS_PRINT_ERROR_FUNCTION, \
LANG_HOOKS_EXPR_SIZE, \
+ LANG_HOOKS_DECL_UNINIT, \
LANG_HOOKS_ATTRIBUTE_TABLE, \
LANG_HOOKS_COMMON_ATTRIBUTE_TABLE, \
LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE, \
LANG_HOOKS_FUNCTION_INITIALIZER, \
LANG_HOOKS_TREE_INLINING_INITIALIZER, \
+ LANG_HOOKS_CALLGRAPH_INITIALIZER, \
LANG_HOOKS_TREE_DUMP_INITIALIZER, \
LANG_HOOKS_DECLS, \
- LANG_HOOKS_FOR_TYPES_INITIALIZER \
+ LANG_HOOKS_FOR_TYPES_INITIALIZER, \
+ LANG_HOOKS_RTL_EXPAND_INITIALIZER \
}
#endif /* GCC_LANG_HOOKS_DEF_H */
diff --git a/contrib/gcc/langhooks.c b/contrib/gcc/langhooks.c
index 87211216e30d..a965193978d4 100644
--- a/contrib/gcc/langhooks.c
+++ b/contrib/gcc/langhooks.c
@@ -1,29 +1,30 @@
/* Default language-specific hooks.
- Copyright 2001, 2002 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <aoliva@redhat.com>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "tree.h"
-#include "c-tree.h"
#include "tree-inline.h"
#include "rtl.h"
#include "insn-config.h"
@@ -31,43 +32,51 @@ Boston, MA 02111-1307, USA. */
#include "flags.h"
#include "langhooks.h"
#include "langhooks-def.h"
+#include "ggc.h"
+#include "diagnostic.h"
/* Do nothing; in many cases the default hook. */
void
-lhd_do_nothing ()
+lhd_do_nothing (void)
{
}
/* Do nothing (tree). */
void
-lhd_do_nothing_t (t)
- tree t ATTRIBUTE_UNUSED;
+lhd_do_nothing_t (tree t ATTRIBUTE_UNUSED)
{
}
/* Do nothing (int). */
void
-lhd_do_nothing_i (i)
- int i ATTRIBUTE_UNUSED;
+lhd_do_nothing_i (int i ATTRIBUTE_UNUSED)
{
}
+/* Do nothing (int, int, int). Return NULL_TREE. */
+
+tree
+lhd_do_nothing_iii_return_null_tree (int i ATTRIBUTE_UNUSED,
+ int j ATTRIBUTE_UNUSED,
+ int k ATTRIBUTE_UNUSED)
+{
+ return NULL_TREE;
+}
+
/* Do nothing (function). */
void
-lhd_do_nothing_f (f)
- struct function *f ATTRIBUTE_UNUSED;
+lhd_do_nothing_f (struct function *f ATTRIBUTE_UNUSED)
{
}
/* Do nothing (return the tree node passed). */
tree
-lhd_return_tree (t)
- tree t;
+lhd_return_tree (tree t)
{
return t;
}
@@ -75,38 +84,40 @@ lhd_return_tree (t)
/* Do nothing (return NULL_TREE). */
tree
-lhd_return_null_tree (t)
- tree t ATTRIBUTE_UNUSED;
+lhd_return_null_tree_v (void)
{
return NULL_TREE;
}
-/* Do nothing; the default hook to decode an option. */
+/* Do nothing (return NULL_TREE). */
-int
-lhd_decode_option (argc, argv)
- int argc ATTRIBUTE_UNUSED;
- char **argv ATTRIBUTE_UNUSED;
+tree
+lhd_return_null_tree (tree t ATTRIBUTE_UNUSED)
{
- return 0;
+ return NULL_TREE;
+}
+
+/* The default post options hook. */
+
+bool
+lhd_post_options (const char **pfilename ATTRIBUTE_UNUSED)
+{
+ return false;
}
/* Called from by print-tree.c. */
void
-lhd_print_tree_nothing (file, node, indent)
- FILE *file ATTRIBUTE_UNUSED;
- tree node ATTRIBUTE_UNUSED;
- int indent ATTRIBUTE_UNUSED;
+lhd_print_tree_nothing (FILE *file ATTRIBUTE_UNUSED,
+ tree node ATTRIBUTE_UNUSED,
+ int indent ATTRIBUTE_UNUSED)
{
}
/* Called from safe_from_p. */
int
-lhd_safe_from_p (x, exp)
- rtx x ATTRIBUTE_UNUSED;
- tree exp ATTRIBUTE_UNUSED;
+lhd_safe_from_p (rtx x ATTRIBUTE_UNUSED, tree exp ATTRIBUTE_UNUSED)
{
return 1;
}
@@ -114,8 +125,7 @@ lhd_safe_from_p (x, exp)
/* Called from unsafe_for_reeval. */
int
-lhd_unsafe_for_reeval (t)
- tree t ATTRIBUTE_UNUSED;
+lhd_unsafe_for_reeval (tree t ATTRIBUTE_UNUSED)
{
return -1;
}
@@ -123,8 +133,7 @@ lhd_unsafe_for_reeval (t)
/* Called from staticp. */
int
-lhd_staticp (exp)
- tree exp ATTRIBUTE_UNUSED;
+lhd_staticp (tree exp ATTRIBUTE_UNUSED)
{
return 0;
}
@@ -132,8 +141,7 @@ lhd_staticp (exp)
/* Called from check_global_declarations. */
bool
-lhd_warn_unused_global_decl (decl)
- tree decl;
+lhd_warn_unused_global_decl (tree decl)
{
/* This is what used to exist in check_global_declarations. Probably
not many of these actually apply to non-C languages. */
@@ -148,10 +156,14 @@ lhd_warn_unused_global_decl (decl)
return true;
}
+/* Number for making the label on the next
+ static variable internal to a function. */
+
+static GTY(()) int var_labelno;
+
/* Set the DECL_ASSEMBLER_NAME for DECL. */
void
-lhd_set_decl_assembler_name (decl)
- tree decl;
+lhd_set_decl_assembler_name (tree decl)
{
/* The language-independent code should never use the
DECL_ASSEMBLER_NAME for lots of DECLs. Only FUNCTION_DECLs and
@@ -162,12 +174,28 @@ lhd_set_decl_assembler_name (decl)
&& (TREE_STATIC (decl)
|| DECL_EXTERNAL (decl)
|| TREE_PUBLIC (decl))))
- /* By default, assume the name to use in assembly code is the
- same as that used in the source language. (That's correct
- for C, and GCC used to set DECL_ASSEMBLER_NAME to the same
- value as DECL_NAME in build_decl, so this choice provides
- backwards compatibility with existing front-ends. */
- SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
+ {
+ /* By default, assume the name to use in assembly code is the
+ same as that used in the source language. (That's correct
+ for C, and GCC used to set DECL_ASSEMBLER_NAME to the same
+ value as DECL_NAME in build_decl, so this choice provides
+ backwards compatibility with existing front-ends.
+
+ Can't use just the variable's own name for a variable whose
+ scope is less than the whole compilation. Concatenate a
+ distinguishing number. */
+ if (!TREE_PUBLIC (decl) && DECL_CONTEXT (decl))
+ {
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
+ char *label;
+
+ ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
+ var_labelno++;
+ SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label));
+ }
+ else
+ SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
+ }
else
/* Nobody should ever be asking for the DECL_ASSEMBLER_NAME of
these DECLs -- unless they're in language-dependent code, in
@@ -177,7 +205,7 @@ lhd_set_decl_assembler_name (decl)
/* By default we always allow bit-field based optimizations. */
bool
-lhd_can_use_bit_fields_p ()
+lhd_can_use_bit_fields_p (void)
{
return true;
}
@@ -185,7 +213,7 @@ lhd_can_use_bit_fields_p ()
/* Provide a default routine to clear the binding stack. This is used
by languages that don't need to do anything special. */
void
-lhd_clear_binding_stack ()
+lhd_clear_binding_stack (void)
{
while (! (*lang_hooks.decls.global_bindings_p) ())
poplevel (0, 0, 0);
@@ -193,16 +221,21 @@ lhd_clear_binding_stack ()
/* Type promotion for variable arguments. */
tree
-lhd_type_promotes_to (type)
- tree type ATTRIBUTE_UNUSED;
+lhd_type_promotes_to (tree type ATTRIBUTE_UNUSED)
{
abort ();
}
+/* Registration of machine- or os-specific builtin types. */
+void
+lhd_register_builtin_type (tree type ATTRIBUTE_UNUSED,
+ const char* name ATTRIBUTE_UNUSED)
+{
+}
+
/* Invalid use of an incomplete type. */
void
-lhd_incomplete_type_error (value, type)
- tree value ATTRIBUTE_UNUSED, type;
+lhd_incomplete_type_error (tree value ATTRIBUTE_UNUSED, tree type)
{
if (TREE_CODE (type) == ERROR_MARK)
return;
@@ -214,8 +247,7 @@ lhd_incomplete_type_error (value, type)
is used by languages that don't need to do anything special. */
HOST_WIDE_INT
-lhd_get_alias_set (t)
- tree t ATTRIBUTE_UNUSED;
+lhd_get_alias_set (tree t ATTRIBUTE_UNUSED)
{
return -1;
}
@@ -224,8 +256,7 @@ lhd_get_alias_set (t)
used by languages that haven't deal with alias sets yet. */
HOST_WIDE_INT
-hook_get_alias_set_0 (t)
- tree t ATTRIBUTE_UNUSED;
+hook_get_alias_set_0 (tree t ATTRIBUTE_UNUSED)
{
return 0;
}
@@ -233,11 +264,10 @@ hook_get_alias_set_0 (t)
/* This is the default expand_expr function. */
rtx
-lhd_expand_expr (t, r, mm, em)
- tree t ATTRIBUTE_UNUSED;
- rtx r ATTRIBUTE_UNUSED;
- enum machine_mode mm ATTRIBUTE_UNUSED;
- int em ATTRIBUTE_UNUSED;
+lhd_expand_expr (tree t ATTRIBUTE_UNUSED, rtx r ATTRIBUTE_UNUSED,
+ enum machine_mode mm ATTRIBUTE_UNUSED,
+ int em ATTRIBUTE_UNUSED,
+ rtx *a ATTRIBUTE_UNUSED)
{
abort ();
}
@@ -245,9 +275,7 @@ lhd_expand_expr (t, r, mm, em)
/* This is the default decl_printable_name function. */
const char *
-lhd_decl_printable_name (decl, verbosity)
- tree decl;
- int verbosity ATTRIBUTE_UNUSED;
+lhd_decl_printable_name (tree decl, int verbosity ATTRIBUTE_UNUSED)
{
return IDENTIFIER_POINTER (DECL_NAME (decl));
}
@@ -264,12 +292,11 @@ lhd_decl_printable_name (decl, verbosity)
when the function is called. */
tree
-lhd_tree_inlining_walk_subtrees (tp,subtrees,func,data,htab)
- tree *tp ATTRIBUTE_UNUSED;
- int *subtrees ATTRIBUTE_UNUSED;
- walk_tree_fn func ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
- void *htab ATTRIBUTE_UNUSED;
+lhd_tree_inlining_walk_subtrees (tree *tp ATTRIBUTE_UNUSED,
+ int *subtrees ATTRIBUTE_UNUSED,
+ walk_tree_fn func ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED,
+ void *htab ATTRIBUTE_UNUSED)
{
return NULL_TREE;
}
@@ -279,8 +306,7 @@ lhd_tree_inlining_walk_subtrees (tp,subtrees,func,data,htab)
inlining a given function. */
int
-lhd_tree_inlining_cannot_inline_tree_fn (fnp)
- tree *fnp;
+lhd_tree_inlining_cannot_inline_tree_fn (tree *fnp)
{
if (flag_really_no_inline
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (*fnp)) == NULL)
@@ -294,8 +320,7 @@ lhd_tree_inlining_cannot_inline_tree_fn (fnp)
if it would exceed inlining limits. */
int
-lhd_tree_inlining_disregard_inline_limits (fn)
- tree fn;
+lhd_tree_inlining_disregard_inline_limits (tree fn)
{
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
return 1;
@@ -311,9 +336,7 @@ lhd_tree_inlining_disregard_inline_limits (fn)
returned. */
tree
-lhd_tree_inlining_add_pending_fn_decls (vafnp, pfn)
- void *vafnp ATTRIBUTE_UNUSED;
- tree pfn;
+lhd_tree_inlining_add_pending_fn_decls (void *vafnp ATTRIBUTE_UNUSED, tree pfn)
{
return pfn;
}
@@ -323,8 +346,7 @@ lhd_tree_inlining_add_pending_fn_decls (vafnp, pfn)
whether it should be walked, copied and preserved across copies. */
int
-lhd_tree_inlining_tree_chain_matters_p (t)
- tree t ATTRIBUTE_UNUSED;
+lhd_tree_inlining_tree_chain_matters_p (tree t ATTRIBUTE_UNUSED)
{
return 0;
}
@@ -333,8 +355,7 @@ lhd_tree_inlining_tree_chain_matters_p (t)
whether VT is an automatic variable defined in function FT. */
int
-lhd_tree_inlining_auto_var_in_fn_p (var, fn)
- tree var, fn;
+lhd_tree_inlining_auto_var_in_fn_p (tree var, tree fn)
{
return (DECL_P (var) && DECL_CONTEXT (var) == fn
&& (((TREE_CODE (var) == VAR_DECL || TREE_CODE (var) == PARM_DECL)
@@ -353,14 +374,16 @@ lhd_tree_inlining_auto_var_in_fn_p (var, fn)
match RES. */
tree
-lhd_tree_inlining_copy_res_decl_for_inlining (res, fn, caller,
- dm, ndp, texps)
- tree res, fn, caller;
- void *dm ATTRIBUTE_UNUSED;
- int *ndp ATTRIBUTE_UNUSED;
- void *texps ATTRIBUTE_UNUSED;
-{
- return copy_decl_for_inlining (res, fn, caller);
+lhd_tree_inlining_copy_res_decl_for_inlining (tree res, tree fn, tree caller,
+ void *dm ATTRIBUTE_UNUSED,
+ int *ndp ATTRIBUTE_UNUSED,
+ tree return_slot_addr ATTRIBUTE_UNUSED)
+{
+ if (return_slot_addr)
+ return build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (return_slot_addr)),
+ return_slot_addr);
+ else
+ return copy_decl_for_inlining (res, fn, caller);
}
/* lang_hooks.tree_inlining.anon_aggr_type_p determines whether T is a
@@ -368,8 +391,7 @@ lhd_tree_inlining_copy_res_decl_for_inlining (res, fn, caller,
i.e., one whose members are in the same scope as the union itself. */
int
-lhd_tree_inlining_anon_aggr_type_p (t)
- tree t ATTRIBUTE_UNUSED;
+lhd_tree_inlining_anon_aggr_type_p (tree t ATTRIBUTE_UNUSED)
{
return 0;
}
@@ -383,15 +405,13 @@ lhd_tree_inlining_anon_aggr_type_p (t)
avoid infinite recursion. */
int
-lhd_tree_inlining_start_inlining (fn)
- tree fn ATTRIBUTE_UNUSED;
+lhd_tree_inlining_start_inlining (tree fn ATTRIBUTE_UNUSED)
{
return 1;
}
void
-lhd_tree_inlining_end_inlining (fn)
- tree fn ATTRIBUTE_UNUSED;
+lhd_tree_inlining_end_inlining (tree fn ATTRIBUTE_UNUSED)
{
}
@@ -399,10 +419,10 @@ lhd_tree_inlining_end_inlining (fn)
language-specific conversion before assigning VALUE to PARM. */
tree
-lhd_tree_inlining_convert_parm_for_inlining (parm, value, fndecl)
- tree parm ATTRIBUTE_UNUSED;
- tree value;
- tree fndecl ATTRIBUTE_UNUSED;
+lhd_tree_inlining_convert_parm_for_inlining (tree parm ATTRIBUTE_UNUSED,
+ tree value,
+ tree fndecl ATTRIBUTE_UNUSED,
+ int argnum ATTRIBUTE_UNUSED)
{
return value;
}
@@ -411,20 +431,17 @@ lhd_tree_inlining_convert_parm_for_inlining (parm, value, fndecl)
nodes. Returns nonzero if it does not want the usual dumping of the
second argument. */
-int
-lhd_tree_dump_dump_tree (di, t)
- void *di ATTRIBUTE_UNUSED;
- tree t ATTRIBUTE_UNUSED;
+bool
+lhd_tree_dump_dump_tree (void *di ATTRIBUTE_UNUSED, tree t ATTRIBUTE_UNUSED)
{
- return 0;
+ return false;
}
/* lang_hooks.tree_dump.type_qual: Determine type qualifiers in a
language-specific way. */
int
-lhd_tree_dump_type_quals (t)
- tree t;
+lhd_tree_dump_type_quals (tree t)
{
return TYPE_QUALS (t);
}
@@ -433,8 +450,7 @@ lhd_tree_dump_type_quals (t)
in a language-specific way. Returns a tree for the size in bytes. */
tree
-lhd_expr_size (exp)
- tree exp;
+lhd_expr_size (tree exp)
{
if (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
&& DECL_SIZE_UNIT (exp) != 0)
@@ -442,21 +458,38 @@ lhd_expr_size (exp)
else
return size_in_bytes (TREE_TYPE (exp));
}
+/* lang_hooks.decl_uninit: Find out if a variable is uninitialized based
+ on DECL_INITIAL. */
+
+bool
+lhd_decl_uninit (tree t ATTRIBUTE_UNUSED)
+{
+ return false;
+}
+
+/* lang_hooks.tree_size: Determine the size of a tree with code C,
+ which is a language-specific tree code in category 'x'. The
+ default expects never to be called. */
+size_t
+lhd_tree_size (enum tree_code c ATTRIBUTE_UNUSED)
+{
+ abort ();
+ return 0;
+}
/* Return true if decl, which is a function decl, may be called by a
sibcall. */
bool
-lhd_decl_ok_for_sibcall (decl)
- tree decl ATTRIBUTE_UNUSED;
+lhd_decl_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED)
{
return true;
}
/* lang_hooks.decls.final_write_globals: perform final processing on
- global variables. */
+ global variables. */
void
-write_global_declarations ()
+write_global_declarations (void)
{
/* Really define vars that have had only a tentative definition.
Really output inline functions that must actually be callable
@@ -464,12 +497,12 @@ write_global_declarations ()
tree globals = (*lang_hooks.decls.getdecls) ();
int len = list_length (globals);
- tree *vec = (tree *) xmalloc (sizeof (tree) * len);
+ tree *vec = xmalloc (sizeof (tree) * len);
int i;
tree decl;
- /* Process the decls in reverse order--earliest first.
- Put them into VEC from back to front, then take out from front. */
+ /* Process the decls in reverse order--earliest first.
+ Put them into VEC from back to front, then take out from front. */
for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
vec[len - i - 1] = decl;
@@ -481,3 +514,52 @@ write_global_declarations ()
/* Clean up. */
free (vec);
}
+
+/* Called to perform language-specific initialization of CTX. */
+void
+lhd_initialize_diagnostics (struct diagnostic_context *ctx ATTRIBUTE_UNUSED)
+{
+}
+
+/* The default function to print out name of current function that caused
+ an error. */
+void
+lhd_print_error_function (diagnostic_context *context, const char *file)
+{
+ if (diagnostic_last_function_changed (context))
+ {
+ const char *old_prefix = context->printer->prefix;
+ char *new_prefix = file ? file_name_as_prefix (file) : NULL;
+
+ pp_set_prefix (context->printer, new_prefix);
+
+ if (current_function_decl == NULL)
+ pp_printf (context->printer, "At top level:");
+ else
+ {
+ if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
+ pp_printf
+ (context->printer, "In member function `%s':",
+ (*lang_hooks.decl_printable_name) (current_function_decl, 2));
+ else
+ pp_printf
+ (context->printer, "In function `%s':",
+ (*lang_hooks.decl_printable_name) (current_function_decl, 2));
+ }
+
+ diagnostic_set_last_function (context);
+ pp_flush (context->printer);
+ context->printer->prefix = old_prefix;
+ free ((char*) new_prefix);
+ }
+}
+
+tree
+lhd_callgraph_analyze_expr (tree *tp ATTRIBUTE_UNUSED,
+ int *walk_subtrees ATTRIBUTE_UNUSED,
+ tree decl ATTRIBUTE_UNUSED)
+{
+ return NULL;
+}
+
+#include "gt-langhooks.h"
diff --git a/contrib/gcc/langhooks.h b/contrib/gcc/langhooks.h
index 546e50e0fb97..199b79f237a1 100644
--- a/contrib/gcc/langhooks.h
+++ b/contrib/gcc/langhooks.h
@@ -1,20 +1,20 @@
/* The lang_hooks data structure.
- Copyright 2001, 2002 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -26,36 +26,39 @@ Boston, MA 02111-1307, USA. */
struct diagnostic_context;
/* A print hook for print_tree (). */
-typedef void (*lang_print_tree_hook) PARAMS ((FILE *, tree, int indent));
+typedef void (*lang_print_tree_hook) (FILE *, tree, int indent);
/* The following hooks are documented in langhooks.c. Must not be
NULL. */
struct lang_hooks_for_tree_inlining
{
- union tree_node *(*walk_subtrees) PARAMS ((union tree_node **, int *,
- union tree_node *(*)
- (union tree_node **,
- int *, void *),
- void *, void *));
- int (*cannot_inline_tree_fn) PARAMS ((union tree_node **));
- int (*disregard_inline_limits) PARAMS ((union tree_node *));
- union tree_node *(*add_pending_fn_decls) PARAMS ((void *,
- union tree_node *));
- int (*tree_chain_matters_p) PARAMS ((union tree_node *));
- int (*auto_var_in_fn_p) PARAMS ((union tree_node *, union tree_node *));
- union tree_node *(*copy_res_decl_for_inlining) PARAMS ((union tree_node *,
- union tree_node *,
- union tree_node *,
- void *, int *,
- void *));
- int (*anon_aggr_type_p) PARAMS ((union tree_node *));
- bool (*var_mod_type_p) PARAMS ((union tree_node *));
- int (*start_inlining) PARAMS ((union tree_node *));
- void (*end_inlining) PARAMS ((union tree_node *));
- union tree_node *(*convert_parm_for_inlining) PARAMS ((union tree_node *,
- union tree_node *,
- union tree_node *));
+ tree (*walk_subtrees) (tree *, int *,
+ tree (*) (tree *, int *, void *),
+ void *, void *);
+ int (*cannot_inline_tree_fn) (tree *);
+ int (*disregard_inline_limits) (tree);
+ tree (*add_pending_fn_decls) (void *, tree);
+ int (*tree_chain_matters_p) (tree);
+ int (*auto_var_in_fn_p) (tree, tree);
+ tree (*copy_res_decl_for_inlining) (tree, tree, tree,
+ void *, int *, tree);
+ int (*anon_aggr_type_p) (tree);
+ bool (*var_mod_type_p) (tree);
+ int (*start_inlining) (tree);
+ void (*end_inlining) (tree);
+ tree (*convert_parm_for_inlining) (tree, tree, tree, int);
+ int (*estimate_num_insns) (tree);
+};
+
+struct lang_hooks_for_callgraph
+{
+ /* The node passed is a language-specific tree node. If its contents
+ are relevant to use of other declarations, mark them. */
+ tree (*analyze_expr) (tree *, int *, tree);
+
+ /* Produce RTL for function passed as argument. */
+ void (*expand_function) (tree);
};
/* Lang hooks for management of language-specific data or status
@@ -63,16 +66,29 @@ struct lang_hooks_for_tree_inlining
struct lang_hooks_for_functions
{
/* Called when entering a function. */
- void (*init) PARAMS ((struct function *));
+ void (*init) (struct function *);
/* Called when leaving a function. */
- void (*final) PARAMS ((struct function *));
+ void (*final) (struct function *);
/* Called when entering a nested function. */
- void (*enter_nested) PARAMS ((struct function *));
+ void (*enter_nested) (struct function *);
/* Called when leaving a nested function. */
- void (*leave_nested) PARAMS ((struct function *));
+ void (*leave_nested) (struct function *);
+};
+
+/* Lang hooks for rtl code generation. */
+struct lang_hooks_for_rtl_expansion
+{
+ /* Called after expand_function_start, but before expanding the body. */
+ void (*start) (void);
+
+ /* Called to expand each statement. */
+ void (*stmt) (tree);
+
+ /* Called after expanding the body but before expand_function_end. */
+ void (*end) (void);
};
/* The following hooks are used by tree-dump.c. */
@@ -81,10 +97,10 @@ struct lang_hooks_for_tree_dump
{
/* Dump language-specific parts of tree nodes. Returns nonzero if it
does not want the usual dumping of the second argument. */
- int (*dump_tree) PARAMS ((void *, tree));
+ bool (*dump_tree) (void *, tree);
/* Determine type qualifiers in a language-specific way. */
- int (*type_quals) PARAMS ((tree));
+ int (*type_quals) (tree);
};
/* Hooks related to types. */
@@ -93,39 +109,48 @@ struct lang_hooks_for_types
{
/* Return a new type (with the indicated CODE), doing whatever
language-specific processing is required. */
- tree (*make_type) PARAMS ((enum tree_code));
+ tree (*make_type) (enum tree_code);
/* Given MODE and UNSIGNEDP, return a suitable type-tree with that
mode. */
- tree (*type_for_mode) PARAMS ((enum machine_mode, int));
+ tree (*type_for_mode) (enum machine_mode, int);
/* Given PRECISION and UNSIGNEDP, return a suitable type-tree for an
integer type with at least that precision. */
- tree (*type_for_size) PARAMS ((unsigned, int));
+ tree (*type_for_size) (unsigned, int);
/* Given an integer type T, return a type like T but unsigned.
If T is unsigned, the value is T. */
- tree (*unsigned_type) PARAMS ((tree));
+ tree (*unsigned_type) (tree);
/* Given an integer type T, return a type like T but signed.
If T is signed, the value is T. */
- tree (*signed_type) PARAMS ((tree));
+ tree (*signed_type) (tree);
/* Return a type the same as TYPE except unsigned or signed
according to UNSIGNEDP. */
- tree (*signed_or_unsigned_type) PARAMS ((int, tree));
+ tree (*signed_or_unsigned_type) (int, tree);
/* Given a type, apply default promotions to unnamed function
arguments and return the new type. Return the same type if no
change. Required by any language that supports variadic
arguments. The default hook aborts. */
- tree (*type_promotes_to) PARAMS ((tree));
+ tree (*type_promotes_to) (tree);
+
+ /* Register TYPE as a builtin type with the indicated NAME. The
+ TYPE is placed in the outermost lexical scope. The semantics
+ should be analogous to:
+
+ typedef TYPE NAME;
+
+ in C. The default hook ignores the declaration. */
+ void (*register_builtin_type) (tree, const char *);
/* This routine is called in tree.c to print an error message for
invalid use of an incomplete type. VALUE is the expression that
was used (or 0 if that isn't known) and TYPE is the type that was
invalid. */
- void (*incomplete_type_error) PARAMS ((tree value, tree type));
+ void (*incomplete_type_error) (tree value, tree type);
};
/* Language hooks related to decls and the symbol table. */
@@ -134,46 +159,52 @@ struct lang_hooks_for_decls
{
/* Enter a new lexical scope. Argument is always zero when called
from outside the front end. */
- void (*pushlevel) PARAMS ((int));
+ void (*pushlevel) (int);
/* Exit a lexical scope and return a BINDING for that scope.
Takes three arguments:
KEEP -- nonzero if there were declarations in this scope.
REVERSE -- reverse the order of decls before returning them.
FUNCTIONBODY -- nonzero if this level is the body of a function. */
- tree (*poplevel) PARAMS ((int, int, int));
+ tree (*poplevel) (int, int, int);
/* Returns nonzero if we are in the global binding level. Ada
returns -1 for an undocumented reason used in stor-layout.c. */
- int (*global_bindings_p) PARAMS ((void));
+ int (*global_bindings_p) (void);
/* Insert BLOCK at the end of the list of subblocks of the
current binding level. This is used when a BIND_EXPR is expanded,
to handle the BLOCK node inside the BIND_EXPR. */
- void (*insert_block) PARAMS ((tree));
+ void (*insert_block) (tree);
/* Set the BLOCK node for the current scope level. */
- void (*set_block) PARAMS ((tree));
+ void (*set_block) (tree);
/* Function to add a decl to the current scope level. Takes one
argument, a decl to add. Returns that decl, or, if the same
symbol is already declared, may return a different decl for that
name. */
- tree (*pushdecl) PARAMS ((tree));
+ tree (*pushdecl) (tree);
/* Returns the chain of decls so far in the current scope level. */
- tree (*getdecls) PARAMS ((void));
+ tree (*getdecls) (void);
+
+ /* Returns a chain of TYPE_DECLs for built-in types. */
+ tree (*builtin_type_decls) (void);
/* Returns true when we should warn for an unused global DECL.
We will already have checked that it has static binding. */
- bool (*warn_unused_global) PARAMS ((tree));
+ bool (*warn_unused_global) (tree);
/* Obtain a list of globals and do final output on them at end
of compilation */
- void (*final_write_globals) PARAMS ((void));
+ void (*final_write_globals) (void);
+
+ /* Do necessary preparations before assemble_variable can proceed. */
+ void (*prepare_assemble_variable) (tree);
/* True if this decl may be called via a sibcall. */
- bool (*ok_for_sibcall) PARAMS ((tree));
+ bool (*ok_for_sibcall) (tree);
};
/* Language-specific hooks. See langhooks-def.h for defaults. */
@@ -187,62 +218,72 @@ struct lang_hooks
identifier nodes long enough for the language-specific slots. */
size_t identifier_size;
+ /* Determines the size of any language-specific 'x' or 'c' nodes.
+ Since it is called from make_node, the only information available
+ is the tree code. Expected to abort on unrecognized codes. */
+ size_t (*tree_size) (enum tree_code);
+
/* The first callback made to the front end, for simple
- initialization needed before any calls to decode_option. */
- void (*init_options) PARAMS ((void));
-
- /* Function called with an option vector as argument, to decode a
- single option (typically starting with -f or -W or +). It should
- return the number of command-line arguments it uses if it handles
- the option, or 0 and not complain if it does not recognize the
- option. If this function returns a negative number, then its
- absolute value is the number of command-line arguments used, but,
- in addition, no language-independent option processing should be
- done for this option. */
- int (*decode_option) PARAMS ((int, char **));
-
- /* Called when all command line options have been parsed. Should do
- any required consistency checks, modifications etc. Complex
- initialization should be left to the "init" callback, since GC
- and the identifier hashes are set up between now and then.
-
- Should return zero unless the compiler back-end does not need to
- be initialized, such as with the -E option.
-
+ initialization needed before any calls to handle_option. Return
+ the language mask to filter the switch array with. */
+ unsigned int (*init_options) (unsigned int argc, const char **argv);
+
+ /* Callback used to perform language-specific initialization for the
+ global diagnostic context structure. */
+ void (*initialize_diagnostics) (struct diagnostic_context *);
+
+ /* Handle the switch CODE, which has real type enum opt_code from
+ options.h. If the switch takes an argument, it is passed in ARG
+ which points to permanent storage. The handler is responsible for
+ checking whether ARG is NULL, which indicates that no argument
+ was in fact supplied. For -f and -W switches, VALUE is 1 or 0
+ for the positive and negative forms respectively.
+
+ Return 1 if the switch is valid, 0 if invalid, and -1 if it's
+ valid and should not be treated as language-independent too. */
+ int (*handle_option) (size_t code, const char *arg, int value);
+
+ /* Return false to use the default complaint about a missing
+ argument, otherwise output a complaint and return true. */
+ bool (*missing_argument) (const char *opt, size_t code);
+
+ /* Called when all command line options have been parsed to allow
+ further processing and initialization
+
+ Should return true to indicate that a compiler back-end is
+ not required, such as with the -E option.
+
If errorcount is nonzero after this call the compiler exits
immediately and the finish hook is not called. */
- bool (*post_options) PARAMS ((void));
+ bool (*post_options) (const char **);
- /* Called after post_options, to initialize the front end. The main
- input filename is passed, which may be NULL; the front end should
- return the original filename (e.g. foo.i -> foo.c). Return NULL
- to indicate a serious error of some sort; in that case no
- compilation is performed, and the finish hook is called
- immediately. */
- const char * (*init) PARAMS ((const char *));
+ /* Called after post_options to initialize the front end. Return
+ false to indicate that no further compilation be performed, in
+ which case the finish hook is called immediately. */
+ bool (*init) (void);
/* Called at the end of compilation, as a finalizer. */
- void (*finish) PARAMS ((void));
+ void (*finish) (void);
/* Parses the entire file. The argument is nonzero to cause bison
parsers to dump debugging information during parsing. */
- void (*parse_file) PARAMS ((int));
+ void (*parse_file) (int);
/* Called immediately after parsing to clear the binding stack. */
- void (*clear_binding_stack) PARAMS ((void));
+ void (*clear_binding_stack) (void);
/* Called to obtain the alias set to be used for an expression or type.
Returns -1 if the language does nothing special for it. */
- HOST_WIDE_INT (*get_alias_set) PARAMS ((tree));
+ HOST_WIDE_INT (*get_alias_set) (tree);
/* Called with an expression that is to be processed as a constant.
Returns either the same expression or a language-independent
constant equivalent to its input. */
- tree (*expand_constant) PARAMS ((tree));
+ tree (*expand_constant) (tree);
/* Called by expand_expr for language-specific tree codes.
Fourth argument is actually an enum expand_modifier. */
- rtx (*expand_expr) PARAMS ((tree, rtx, enum machine_mode, int));
+ rtx (*expand_expr) (tree, rtx, enum machine_mode, int, rtx *);
/* Prepare expr to be an argument of a TRUTH_NOT_EXPR or other logical
operation.
@@ -255,11 +296,7 @@ struct lang_hooks
The result should be an expression of boolean type (if not an
error_mark_node). */
- tree (*truthvalue_conversion) PARAMS ((tree));
-
- /* Possibly apply default attributes to a function (represented by
- a FUNCTION_DECL). */
- void (*insert_default_attributes) PARAMS ((tree));
+ tree (*truthvalue_conversion) (tree);
/* Hook called by safe_from_p for language-specific tree codes. It is
up to the language front-end to install a hook if it has any such
@@ -268,55 +305,60 @@ struct lang_hooks
should not reexamine those pieces. This routine may recursively
call safe_from_p; it should always pass `0' as the TOP_P
parameter. */
- int (*safe_from_p) PARAMS ((rtx, tree));
+ int (*safe_from_p) (rtx, tree);
/* Function to finish handling an incomplete decl at the end of
compilation. Default hook is does nothing. */
- void (*finish_incomplete_decl) PARAMS ((tree));
+ void (*finish_incomplete_decl) (tree);
/* Function used by unsafe_for_reeval. A non-negative number is
returned directly from unsafe_for_reeval, a negative number falls
through. The default hook returns a negative number. */
- int (*unsafe_for_reeval) PARAMS ((tree));
+ int (*unsafe_for_reeval) (tree);
/* Mark EXP saying that we need to be able to take the address of
it; it should not be allocated in a register. Return true if
successful. */
- bool (*mark_addressable) PARAMS ((tree));
+ bool (*mark_addressable) (tree);
/* Hook called by staticp for language-specific tree codes. */
- int (*staticp) PARAMS ((tree));
+ int (*staticp) (tree);
/* Replace the DECL_LANG_SPECIFIC data, which may be NULL, of the
DECL_NODE with a newly GC-allocated copy. */
- void (*dup_lang_specific_decl) PARAMS ((tree));
+ void (*dup_lang_specific_decl) (tree);
/* Called before its argument, an UNSAVE_EXPR, is to be
unsaved. Modify it in-place so that all the evaluate only once
things are cleared out. */
- tree (*unsave_expr_now) PARAMS ((tree));
+ tree (*unsave_expr_now) (tree);
/* Called by expand_expr to build and return the cleanup-expression
for the passed TARGET_EXPR. Return NULL if there is none. */
- tree (*maybe_build_cleanup) PARAMS ((tree));
+ tree (*maybe_build_cleanup) (tree);
/* Set the DECL_ASSEMBLER_NAME for a node. If it is the sort of
thing that the assembler should talk about, set
DECL_ASSEMBLER_NAME to an appropriate IDENTIFIER_NODE.
Otherwise, set it to the ERROR_MARK_NODE to ensure that the
assembler does not talk about it. */
- void (*set_decl_assembler_name) PARAMS ((tree));
+ void (*set_decl_assembler_name) (tree);
/* Return nonzero if fold-const is free to use bit-field
optimizations, for instance in fold_truthop(). */
- bool (*can_use_bit_fields_p) PARAMS ((void));
+ bool (*can_use_bit_fields_p) (void);
/* Nonzero if TYPE_READONLY and TREE_READONLY should always be honored. */
bool honor_readonly;
+ /* Nonzero if this front end does not generate a dummy BLOCK between
+ the outermost scope of the function and the FUNCTION_DECL. See
+ is_body_block in stmt.c, and its callers. */
+ bool no_body_blocks;
+
/* The front end can add its own statistics to -fmem-report with
this hook. It should output to stderr. */
- void (*print_statistics) PARAMS ((void));
+ void (*print_statistics) (void);
/* Called by print_tree when there is a tree of class 'x' that it
doesn't know how to display. */
@@ -334,17 +376,23 @@ struct lang_hooks
necessary. 1: and scope information. 2: and any other
information that might be interesting, such as function parameter
types in C++. */
- const char *(*decl_printable_name) PARAMS ((tree decl, int verbosity));
+ const char *(*decl_printable_name) (tree decl, int verbosity);
+
+ /* Given a CALL_EXPR, return a function decl that is its target. */
+ tree (*lang_get_callee_fndecl) (tree);
/* Called by report_error_function to print out function name. */
- void (*print_error_function) PARAMS ((struct diagnostic_context *,
- const char *));
+ void (*print_error_function) (struct diagnostic_context *, const char *);
/* Called from expr_size to calculate the size of the value of an
expression in a language-dependent way. Returns a tree for the size
in bytes. A frontend can call lhd_expr_size to get the default
semantics in cases that it doesn't want to handle specially. */
- tree (*expr_size) PARAMS ((tree));
+ tree (*expr_size) (tree);
+
+ /* Called from uninitialized_vars_warning to find out if a variable is
+ uninitialized based on DECL_INITIAL. */
+ bool (*decl_uninit) (tree);
/* Pointers to machine-independent attribute tables, for front ends
using attribs.c. If one is NULL, it is ignored. Respectively, a
@@ -360,12 +408,16 @@ struct lang_hooks
struct lang_hooks_for_tree_inlining tree_inlining;
+ struct lang_hooks_for_callgraph callgraph;
+
struct lang_hooks_for_tree_dump tree_dump;
struct lang_hooks_for_decls decls;
struct lang_hooks_for_types types;
+ struct lang_hooks_for_rtl_expansion rtl_expand;
+
/* Whenever you add entries here, make sure you adjust langhooks-def.h
and langhooks.c accordingly. */
};
diff --git a/contrib/gcc/lbasename.c b/contrib/gcc/lbasename.c
index 43cb73f0a1d7..200a87f23871 100644
--- a/contrib/gcc/lbasename.c
+++ b/contrib/gcc/lbasename.c
@@ -40,25 +40,7 @@ and a path ending in @code{/} returns the empty string after it.
#include "ansidecl.h"
#include "libiberty.h"
#include "safe-ctype.h"
-
-#ifndef DIR_SEPARATOR
-# define DIR_SEPARATOR '/'
-#endif
-
-#if defined (_WIN32) || defined (__MSDOS__) \
- || defined (__DJGPP__) || defined (__OS2__)
-# define HAVE_DOS_BASED_FILE_SYSTEM
-# ifndef DIR_SEPARATOR_2
-# define DIR_SEPARATOR_2 '\\'
-# endif
-#endif
-
-#ifndef DIR_SEPARATOR_2
-# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
-#else
-# define IS_DIR_SEPARATOR(ch) \
- (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
-#endif
+#include "filenames.h"
const char *
lbasename (name)
diff --git a/contrib/gcc/lcm.c b/contrib/gcc/lcm.c
index bdbae429d4d0..c8669049a6a7 100644
--- a/contrib/gcc/lcm.c
+++ b/contrib/gcc/lcm.c
@@ -1,5 +1,6 @@
/* Generic partial redundancy elimination with lazy code motion support.
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -51,6 +52,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -61,38 +64,29 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "basic-block.h"
#include "output.h"
#include "tm_p.h"
+#include "function.h"
/* We want target macros for the mode switching code to be able to refer
to instruction attribute values. */
#include "insn-attr.h"
/* Edge based LCM routines. */
-static void compute_antinout_edge PARAMS ((sbitmap *, sbitmap *,
- sbitmap *, sbitmap *));
-static void compute_earliest PARAMS ((struct edge_list *, int,
- sbitmap *, sbitmap *,
- sbitmap *, sbitmap *,
- sbitmap *));
-static void compute_laterin PARAMS ((struct edge_list *, sbitmap *,
- sbitmap *, sbitmap *,
- sbitmap *));
-static void compute_insert_delete PARAMS ((struct edge_list *edge_list,
- sbitmap *, sbitmap *,
- sbitmap *, sbitmap *,
- sbitmap *));
+static void compute_antinout_edge (sbitmap *, sbitmap *, sbitmap *, sbitmap *);
+static void compute_earliest (struct edge_list *, int, sbitmap *, sbitmap *,
+ sbitmap *, sbitmap *, sbitmap *);
+static void compute_laterin (struct edge_list *, sbitmap *, sbitmap *,
+ sbitmap *, sbitmap *);
+static void compute_insert_delete (struct edge_list *edge_list, sbitmap *,
+ sbitmap *, sbitmap *, sbitmap *, sbitmap *);
/* Edge based LCM routines on a reverse flowgraph. */
-static void compute_farthest PARAMS ((struct edge_list *, int,
- sbitmap *, sbitmap *,
- sbitmap*, sbitmap *,
- sbitmap *));
-static void compute_nearerout PARAMS ((struct edge_list *, sbitmap *,
- sbitmap *, sbitmap *,
- sbitmap *));
-static void compute_rev_insert_delete PARAMS ((struct edge_list *edge_list,
- sbitmap *, sbitmap *,
- sbitmap *, sbitmap *,
- sbitmap *));
+static void compute_farthest (struct edge_list *, int, sbitmap *, sbitmap *,
+ sbitmap*, sbitmap *, sbitmap *);
+static void compute_nearerout (struct edge_list *, sbitmap *, sbitmap *,
+ sbitmap *, sbitmap *);
+static void compute_rev_insert_delete (struct edge_list *edge_list, sbitmap *,
+ sbitmap *, sbitmap *, sbitmap *,
+ sbitmap *);
/* Edge based lcm routines. */
@@ -101,11 +95,8 @@ static void compute_rev_insert_delete PARAMS ((struct edge_list *edge_list,
Other than that, its pretty much identical to compute_antinout. */
static void
-compute_antinout_edge (antloc, transp, antin, antout)
- sbitmap *antloc;
- sbitmap *transp;
- sbitmap *antin;
- sbitmap *antout;
+compute_antinout_edge (sbitmap *antloc, sbitmap *transp, sbitmap *antin,
+ sbitmap *antout)
{
basic_block bb;
edge e;
@@ -115,8 +106,7 @@ compute_antinout_edge (antloc, transp, antin, antout)
/* Allocate a worklist array/queue. Entries are only added to the
list if they were not already on the list. So the size is
bounded by the number of basic blocks. */
- qin = qout = worklist
- = (basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
+ qin = qout = worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
/* We want a maximal solution, so make an optimistic initialization of
ANTIN. */
@@ -126,7 +116,7 @@ compute_antinout_edge (antloc, transp, antin, antout)
optimistic initialization of ANTIN above. */
FOR_EACH_BB_REVERSE (bb)
{
- *qin++ =bb;
+ *qin++ = bb;
bb->aux = bb;
}
@@ -186,10 +176,9 @@ compute_antinout_edge (antloc, transp, antin, antout)
/* Compute the earliest vector for edge based lcm. */
static void
-compute_earliest (edge_list, n_exprs, antin, antout, avout, kill, earliest)
- struct edge_list *edge_list;
- int n_exprs;
- sbitmap *antin, *antout, *avout, *kill, *earliest;
+compute_earliest (struct edge_list *edge_list, int n_exprs, sbitmap *antin,
+ sbitmap *antout, sbitmap *avout, sbitmap *kill,
+ sbitmap *earliest)
{
sbitmap difference, temp_bitmap;
int x, num_edges;
@@ -255,9 +244,8 @@ compute_earliest (edge_list, n_exprs, antin, antout, avout, kill, earliest)
to compute it. */
static void
-compute_laterin (edge_list, earliest, antloc, later, laterin)
- struct edge_list *edge_list;
- sbitmap *earliest, *antloc, *later, *laterin;
+compute_laterin (struct edge_list *edge_list, sbitmap *earliest,
+ sbitmap *antloc, sbitmap *later, sbitmap *laterin)
{
int num_edges, i;
edge e;
@@ -270,7 +258,7 @@ compute_laterin (edge_list, earliest, antloc, later, laterin)
list if they were not already on the list. So the size is
bounded by the number of basic blocks. */
qin = qout = worklist
- = (basic_block *) xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
+ = xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
/* Initialize a mapping from each edge to its index. */
for (i = 0; i < num_edges; i++)
@@ -305,7 +293,7 @@ compute_laterin (edge_list, earliest, antloc, later, laterin)
qin = worklist;
/* Note that we do not use the last allocated element for our queue,
as EXIT_BLOCK is never inserted into it. In fact the above allocation
- of n_basic_blocks + 1 elements is not encessary. */
+ of n_basic_blocks + 1 elements is not necessary. */
qend = &worklist[n_basic_blocks];
qlen = n_basic_blocks;
@@ -358,10 +346,9 @@ compute_laterin (edge_list, earliest, antloc, later, laterin)
/* Compute the insertion and deletion points for edge based LCM. */
static void
-compute_insert_delete (edge_list, antloc, later, laterin,
- insert, delete)
- struct edge_list *edge_list;
- sbitmap *antloc, *later, *laterin, *insert, *delete;
+compute_insert_delete (struct edge_list *edge_list, sbitmap *antloc,
+ sbitmap *later, sbitmap *laterin, sbitmap *insert,
+ sbitmap *delete)
{
int x;
basic_block bb;
@@ -385,15 +372,9 @@ compute_insert_delete (edge_list, antloc, later, laterin,
map the insert vector to what edge an expression should be inserted on. */
struct edge_list *
-pre_edge_lcm (file, n_exprs, transp, avloc, antloc, kill, insert, delete)
- FILE *file ATTRIBUTE_UNUSED;
- int n_exprs;
- sbitmap *transp;
- sbitmap *avloc;
- sbitmap *antloc;
- sbitmap *kill;
- sbitmap **insert;
- sbitmap **delete;
+pre_edge_lcm (FILE *file ATTRIBUTE_UNUSED, int n_exprs, sbitmap *transp,
+ sbitmap *avloc, sbitmap *antloc, sbitmap *kill,
+ sbitmap **insert, sbitmap **delete)
{
sbitmap *antin, *antout, *earliest;
sbitmap *avin, *avout;
@@ -488,8 +469,8 @@ pre_edge_lcm (file, n_exprs, transp, avloc, antloc, kill, insert, delete)
Return the number of passes we performed to iterate to a solution. */
void
-compute_available (avloc, kill, avout, avin)
- sbitmap *avloc, *kill, *avout, *avin;
+compute_available (sbitmap *avloc, sbitmap *kill, sbitmap *avout,
+ sbitmap *avin)
{
edge e;
basic_block *worklist, *qin, *qout, *qend, bb;
@@ -498,8 +479,7 @@ compute_available (avloc, kill, avout, avin)
/* Allocate a worklist array/queue. Entries are only added to the
list if they were not already on the list. So the size is
bounded by the number of basic blocks. */
- qin = qout = worklist
- = (basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
+ qin = qout = worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
/* We want a maximal solution. */
sbitmap_vector_ones (avout, last_basic_block);
@@ -570,11 +550,9 @@ compute_available (avloc, kill, avout, avin)
/* Compute the farthest vector for edge based lcm. */
static void
-compute_farthest (edge_list, n_exprs, st_avout, st_avin, st_antin,
- kill, farthest)
- struct edge_list *edge_list;
- int n_exprs;
- sbitmap *st_avout, *st_avin, *st_antin, *kill, *farthest;
+compute_farthest (struct edge_list *edge_list, int n_exprs,
+ sbitmap *st_avout, sbitmap *st_avin, sbitmap *st_antin,
+ sbitmap *kill, sbitmap *farthest)
{
sbitmap difference, temp_bitmap;
int x, num_edges;
@@ -616,9 +594,8 @@ compute_farthest (edge_list, n_exprs, st_avout, st_avin, st_antin,
implementation can be found before compute_laterin. */
static void
-compute_nearerout (edge_list, farthest, st_avloc, nearer, nearerout)
- struct edge_list *edge_list;
- sbitmap *farthest, *st_avloc, *nearer, *nearerout;
+compute_nearerout (struct edge_list *edge_list, sbitmap *farthest,
+ sbitmap *st_avloc, sbitmap *nearer, sbitmap *nearerout)
{
int num_edges, i;
edge e;
@@ -629,8 +606,7 @@ compute_nearerout (edge_list, farthest, st_avloc, nearer, nearerout)
/* Allocate a worklist array/queue. Entries are only added to the
list if they were not already on the list. So the size is
bounded by the number of basic blocks. */
- tos = worklist
- = (basic_block *) xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
+ tos = worklist = xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
/* Initialize NEARER for each edge and build a mapping from an edge to
its index. */
@@ -699,10 +675,9 @@ compute_nearerout (edge_list, farthest, st_avloc, nearer, nearerout)
/* Compute the insertion and deletion points for edge based LCM. */
static void
-compute_rev_insert_delete (edge_list, st_avloc, nearer, nearerout,
- insert, delete)
- struct edge_list *edge_list;
- sbitmap *st_avloc, *nearer, *nearerout, *insert, *delete;
+compute_rev_insert_delete (struct edge_list *edge_list, sbitmap *st_avloc,
+ sbitmap *nearer, sbitmap *nearerout,
+ sbitmap *insert, sbitmap *delete)
{
int x;
basic_block bb;
@@ -726,16 +701,9 @@ compute_rev_insert_delete (edge_list, st_avloc, nearer, nearerout,
an expression should be inserted on. */
struct edge_list *
-pre_edge_rev_lcm (file, n_exprs, transp, st_avloc, st_antloc, kill,
- insert, delete)
- FILE *file ATTRIBUTE_UNUSED;
- int n_exprs;
- sbitmap *transp;
- sbitmap *st_avloc;
- sbitmap *st_antloc;
- sbitmap *kill;
- sbitmap **insert;
- sbitmap **delete;
+pre_edge_rev_lcm (FILE *file ATTRIBUTE_UNUSED, int n_exprs, sbitmap *transp,
+ sbitmap *st_avloc, sbitmap *st_antloc, sbitmap *kill,
+ sbitmap **insert, sbitmap **delete)
{
sbitmap *st_antin, *st_antout;
sbitmap *st_avout, *st_avin, *farthest;
@@ -746,8 +714,8 @@ pre_edge_rev_lcm (file, n_exprs, transp, st_avloc, st_antloc, kill,
edge_list = create_edge_list ();
num_edges = NUM_EDGES (edge_list);
- st_antin = (sbitmap *) sbitmap_vector_alloc (last_basic_block, n_exprs);
- st_antout = (sbitmap *) sbitmap_vector_alloc (last_basic_block, n_exprs);
+ st_antin = sbitmap_vector_alloc (last_basic_block, n_exprs);
+ st_antout = sbitmap_vector_alloc (last_basic_block, n_exprs);
sbitmap_vector_zero (st_antin, last_basic_block);
sbitmap_vector_zero (st_antout, last_basic_block);
compute_antinout_edge (st_antloc, transp, st_antin, st_antout);
@@ -847,9 +815,9 @@ pre_edge_rev_lcm (file, n_exprs, transp, st_avloc, st_antloc, kill,
The LCM algorithm is then run over the flow graph to determine where to
place the sets to the highest-priority value in respect of first the first
- insn in any one block. Any adjustments required to the transparancy
+ insn in any one block. Any adjustments required to the transparency
vectors are made, then the next iteration starts for the next-lower
- priority mode, till for each entity all modes are exhasted.
+ priority mode, till for each entity all modes are exhausted.
More details are located in the code for optimize_mode_switching(). */
@@ -884,11 +852,11 @@ static sbitmap *comp;
static sbitmap *delete;
static sbitmap *insert;
-static struct seginfo * new_seginfo PARAMS ((int, rtx, int, HARD_REG_SET));
-static void add_seginfo PARAMS ((struct bb_info *, struct seginfo *));
-static void reg_dies PARAMS ((rtx, HARD_REG_SET));
-static void reg_becomes_live PARAMS ((rtx, rtx, void *));
-static void make_preds_opaque PARAMS ((basic_block, int));
+static struct seginfo * new_seginfo (int, rtx, int, HARD_REG_SET);
+static void add_seginfo (struct bb_info *, struct seginfo *);
+static void reg_dies (rtx, HARD_REG_SET);
+static void reg_becomes_live (rtx, rtx, void *);
+static void make_preds_opaque (basic_block, int);
#endif
#ifdef OPTIMIZE_MODE_SWITCHING
@@ -897,11 +865,7 @@ static void make_preds_opaque PARAMS ((basic_block, int));
with the MODE, INSN, and basic block BB parameters. */
static struct seginfo *
-new_seginfo (mode, insn, bb, regs_live)
- int mode;
- rtx insn;
- int bb;
- HARD_REG_SET regs_live;
+new_seginfo (int mode, rtx insn, int bb, HARD_REG_SET regs_live)
{
struct seginfo *ptr;
ptr = xmalloc (sizeof (struct seginfo));
@@ -918,9 +882,7 @@ new_seginfo (mode, insn, bb, regs_live)
INFO is the structure to be linked in. */
static void
-add_seginfo (head, info)
- struct bb_info *head;
- struct seginfo *info;
+add_seginfo (struct bb_info *head, struct seginfo *info)
{
struct seginfo *ptr;
@@ -942,9 +904,7 @@ add_seginfo (head, info)
we are currently handling mode-switching for. */
static void
-make_preds_opaque (b, j)
- basic_block b;
- int j;
+make_preds_opaque (basic_block b, int j)
{
edge e;
@@ -963,9 +923,7 @@ make_preds_opaque (b, j)
/* Record in LIVE that register REG died. */
static void
-reg_dies (reg, live)
- rtx reg;
- HARD_REG_SET live;
+reg_dies (rtx reg, HARD_REG_SET live)
{
int regno, nregs;
@@ -983,10 +941,7 @@ reg_dies (reg, live)
This is called via note_stores. */
static void
-reg_becomes_live (reg, setter, live)
- rtx reg;
- rtx setter ATTRIBUTE_UNUSED;
- void *live;
+reg_becomes_live (rtx reg, rtx setter ATTRIBUTE_UNUSED, void *live)
{
int regno, nregs;
@@ -1003,12 +958,17 @@ reg_becomes_live (reg, setter, live)
SET_HARD_REG_BIT (* (HARD_REG_SET *) live, regno + nregs);
}
+/* Make sure if MODE_ENTRY is defined the MODE_EXIT is defined
+ and vice versa. */
+#if defined (MODE_ENTRY) != defined (MODE_EXIT)
+ #error "Both MODE_ENTRY and MODE_EXIT must be defined"
+#endif
+
/* Find all insns that need a particular mode setting, and insert the
necessary mode switches. Return true if we did work. */
int
-optimize_mode_switching (file)
- FILE *file;
+optimize_mode_switching (FILE *file)
{
rtx insn;
int e;
@@ -1036,12 +996,11 @@ optimize_mode_switching (file)
/* Create the list of segments within each basic block.
If NORMAL_MODE is defined, allow for two extra
blocks split from the entry and exit block. */
-#ifdef NORMAL_MODE
+#if defined (MODE_ENTRY) && defined (MODE_EXIT)
entry_exit_extra = 2;
#endif
bb_info[n_entities]
- = (struct bb_info *) xcalloc (last_basic_block + entry_exit_extra,
- sizeof **bb_info);
+ = xcalloc (last_basic_block + entry_exit_extra, sizeof **bb_info);
entity_map[n_entities++] = e;
if (num_modes[e] > max_num_modes)
max_num_modes = num_modes[e];
@@ -1050,7 +1009,7 @@ optimize_mode_switching (file)
if (! n_entities)
return 0;
-#ifdef NORMAL_MODE
+#if defined (MODE_ENTRY) && defined (MODE_EXIT)
{
/* Split the edge from the entry block and the fallthrough edge to the
exit block, so that we can note that there NORMAL_MODE is supplied /
@@ -1099,8 +1058,8 @@ optimize_mode_switching (file)
REG_SET_TO_HARD_REG_SET (live_now,
bb->global_live_at_start);
- for (insn = bb->head;
- insn != NULL && insn != NEXT_INSN (bb->end);
+ for (insn = BB_HEAD (bb);
+ insn != NULL && insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
{
if (INSN_P (insn))
@@ -1115,7 +1074,9 @@ optimize_mode_switching (file)
add_seginfo (info + bb->index, ptr);
RESET_BIT (transp[bb->index], j);
}
-
+#ifdef MODE_AFTER
+ last_mode = MODE_AFTER (last_mode, insn);
+#endif
/* Update LIVE_NOW. */
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_DEAD)
@@ -1132,13 +1093,13 @@ optimize_mode_switching (file)
/* Check for blocks without ANY mode requirements. */
if (last_mode == no_mode)
{
- ptr = new_seginfo (no_mode, bb->end, bb->index, live_now);
+ ptr = new_seginfo (no_mode, BB_END (bb), bb->index, live_now);
add_seginfo (info + bb->index, ptr);
}
}
-#ifdef NORMAL_MODE
+#if defined (MODE_ENTRY) && defined (MODE_EXIT)
{
- int mode = NORMAL_MODE (e);
+ int mode = MODE_ENTRY (e);
if (mode != no_mode)
{
@@ -1156,7 +1117,7 @@ optimize_mode_switching (file)
info[bb->index].computing = mode;
if (pre_exit)
- info[pre_exit->index].seginfo->mode = mode;
+ info[pre_exit->index].seginfo->mode = MODE_EXIT (e);
}
}
#endif /* NORMAL_MODE */
@@ -1240,8 +1201,8 @@ optimize_mode_switching (file)
if (eg->flags & EDGE_ABNORMAL)
{
emited = true;
- if (GET_CODE (src_bb->end) == JUMP_INSN)
- emit_insn_before (mode_set, src_bb->end);
+ if (GET_CODE (BB_END (src_bb)) == JUMP_INSN)
+ emit_insn_before (mode_set, BB_END (src_bb));
/* It doesn't make sense to switch to normal mode
after a CALL_INSN, so we're going to abort if we
find one. The cases in which a CALL_INSN may
@@ -1253,8 +1214,8 @@ optimize_mode_switching (file)
the call (it wouldn't make sense, anyway). In
the case of EH edges, EH entry points also start
in normal mode, so a similar reasoning applies. */
- else if (GET_CODE (src_bb->end) == INSN)
- emit_insn_after (mode_set, src_bb->end);
+ else if (GET_CODE (BB_END (src_bb)) == INSN)
+ emit_insn_after (mode_set, BB_END (src_bb));
else
abort ();
bb_info[j][src_bb->index].computing = mode;
@@ -1332,7 +1293,7 @@ optimize_mode_switching (file)
if (need_commit)
commit_edge_insertions ();
-#ifdef NORMAL_MODE
+#if defined (MODE_ENTRY) && defined (MODE_EXIT)
cleanup_cfg (CLEANUP_NO_INSN_DEL);
#else
if (!need_commit && !emited)
diff --git a/contrib/gcc/libfuncs.h b/contrib/gcc/libfuncs.h
index bb2aa17f3647..d4bd644f108d 100644
--- a/contrib/gcc/libfuncs.h
+++ b/contrib/gcc/libfuncs.h
@@ -24,18 +24,6 @@ Boston, MA 02111-1307, USA. */
/* Enumeration of indexes into libfunc_table. */
enum libfunc_index
{
- LTI_extendsfdf2,
- LTI_extendsfxf2,
- LTI_extendsftf2,
- LTI_extenddfxf2,
- LTI_extenddftf2,
-
- LTI_truncdfsf2,
- LTI_truncxfsf2,
- LTI_trunctfsf2,
- LTI_truncxfdf2,
- LTI_trunctfdf2,
-
LTI_abort,
LTI_memcpy,
LTI_memmove,
@@ -44,6 +32,7 @@ enum libfunc_index
LTI_bcmp,
LTI_memset,
LTI_bzero,
+ LTI_setbits,
LTI_unwind_resume,
LTI_eh_personality,
@@ -52,97 +41,12 @@ enum libfunc_index
LTI_unwind_sjlj_register,
LTI_unwind_sjlj_unregister,
- LTI_eqhf2,
- LTI_nehf2,
- LTI_gthf2,
- LTI_gehf2,
- LTI_lthf2,
- LTI_lehf2,
- LTI_unordhf2,
-
- LTI_eqsf2,
- LTI_nesf2,
- LTI_gtsf2,
- LTI_gesf2,
- LTI_ltsf2,
- LTI_lesf2,
- LTI_unordsf2,
-
- LTI_eqdf2,
- LTI_nedf2,
- LTI_gtdf2,
- LTI_gedf2,
- LTI_ltdf2,
- LTI_ledf2,
- LTI_unorddf2,
-
- LTI_eqxf2,
- LTI_nexf2,
- LTI_gtxf2,
- LTI_gexf2,
- LTI_ltxf2,
- LTI_lexf2,
- LTI_unordxf2,
-
- LTI_eqtf2,
- LTI_netf2,
- LTI_gttf2,
- LTI_getf2,
- LTI_lttf2,
- LTI_letf2,
- LTI_unordtf2,
-
- LTI_floatsisf,
- LTI_floatdisf,
- LTI_floattisf,
-
- LTI_floatsidf,
- LTI_floatdidf,
- LTI_floattidf,
-
- LTI_floatsixf,
- LTI_floatdixf,
- LTI_floattixf,
-
- LTI_floatsitf,
- LTI_floatditf,
- LTI_floattitf,
-
- LTI_fixsfsi,
- LTI_fixsfdi,
- LTI_fixsfti,
-
- LTI_fixdfsi,
- LTI_fixdfdi,
- LTI_fixdfti,
-
- LTI_fixxfsi,
- LTI_fixxfdi,
- LTI_fixxfti,
-
- LTI_fixtfsi,
- LTI_fixtfdi,
- LTI_fixtfti,
-
- LTI_fixunssfsi,
- LTI_fixunssfdi,
- LTI_fixunssfti,
-
- LTI_fixunsdfsi,
- LTI_fixunsdfdi,
- LTI_fixunsdfti,
-
- LTI_fixunsxfsi,
- LTI_fixunsxfdi,
- LTI_fixunsxfti,
-
- LTI_fixunstfsi,
- LTI_fixunstfdi,
- LTI_fixunstfti,
-
LTI_profile_function_entry,
LTI_profile_function_exit,
+ LTI_gcov_flush,
+ LTI_gcov_init,
+
LTI_MAX
};
@@ -151,17 +55,6 @@ enum libfunc_index
extern GTY(()) rtx libfunc_table[LTI_MAX];
/* Accessor macros for libfunc_table. */
-#define extendsfdf2_libfunc (libfunc_table[LTI_extendsfdf2])
-#define extendsfxf2_libfunc (libfunc_table[LTI_extendsfxf2])
-#define extendsftf2_libfunc (libfunc_table[LTI_extendsftf2])
-#define extenddfxf2_libfunc (libfunc_table[LTI_extenddfxf2])
-#define extenddftf2_libfunc (libfunc_table[LTI_extenddftf2])
-
-#define truncdfsf2_libfunc (libfunc_table[LTI_truncdfsf2])
-#define truncxfsf2_libfunc (libfunc_table[LTI_truncxfsf2])
-#define trunctfsf2_libfunc (libfunc_table[LTI_trunctfsf2])
-#define truncxfdf2_libfunc (libfunc_table[LTI_truncxfdf2])
-#define trunctfdf2_libfunc (libfunc_table[LTI_trunctfdf2])
#define abort_libfunc (libfunc_table[LTI_abort])
#define memcpy_libfunc (libfunc_table[LTI_memcpy])
@@ -171,6 +64,7 @@ extern GTY(()) rtx libfunc_table[LTI_MAX];
#define bcmp_libfunc (libfunc_table[LTI_bcmp])
#define memset_libfunc (libfunc_table[LTI_memset])
#define bzero_libfunc (libfunc_table[LTI_bzero])
+#define setbits_libfunc (libfunc_table[LTI_setbits])
#define unwind_resume_libfunc (libfunc_table[LTI_unwind_resume])
#define eh_personality_libfunc (libfunc_table[LTI_eh_personality])
@@ -180,95 +74,10 @@ extern GTY(()) rtx libfunc_table[LTI_MAX];
#define unwind_sjlj_unregister_libfunc \
(libfunc_table[LTI_unwind_sjlj_unregister])
-#define eqhf2_libfunc (libfunc_table[LTI_eqhf2])
-#define nehf2_libfunc (libfunc_table[LTI_nehf2])
-#define gthf2_libfunc (libfunc_table[LTI_gthf2])
-#define gehf2_libfunc (libfunc_table[LTI_gehf2])
-#define lthf2_libfunc (libfunc_table[LTI_lthf2])
-#define lehf2_libfunc (libfunc_table[LTI_lehf2])
-#define unordhf2_libfunc (libfunc_table[LTI_unordhf2])
-
-#define eqsf2_libfunc (libfunc_table[LTI_eqsf2])
-#define nesf2_libfunc (libfunc_table[LTI_nesf2])
-#define gtsf2_libfunc (libfunc_table[LTI_gtsf2])
-#define gesf2_libfunc (libfunc_table[LTI_gesf2])
-#define ltsf2_libfunc (libfunc_table[LTI_ltsf2])
-#define lesf2_libfunc (libfunc_table[LTI_lesf2])
-#define unordsf2_libfunc (libfunc_table[LTI_unordsf2])
-
-#define eqdf2_libfunc (libfunc_table[LTI_eqdf2])
-#define nedf2_libfunc (libfunc_table[LTI_nedf2])
-#define gtdf2_libfunc (libfunc_table[LTI_gtdf2])
-#define gedf2_libfunc (libfunc_table[LTI_gedf2])
-#define ltdf2_libfunc (libfunc_table[LTI_ltdf2])
-#define ledf2_libfunc (libfunc_table[LTI_ledf2])
-#define unorddf2_libfunc (libfunc_table[LTI_unorddf2])
-
-#define eqxf2_libfunc (libfunc_table[LTI_eqxf2])
-#define nexf2_libfunc (libfunc_table[LTI_nexf2])
-#define gtxf2_libfunc (libfunc_table[LTI_gtxf2])
-#define gexf2_libfunc (libfunc_table[LTI_gexf2])
-#define ltxf2_libfunc (libfunc_table[LTI_ltxf2])
-#define lexf2_libfunc (libfunc_table[LTI_lexf2])
-#define unordxf2_libfunc (libfunc_table[LTI_unordxf2])
-
-#define eqtf2_libfunc (libfunc_table[LTI_eqtf2])
-#define netf2_libfunc (libfunc_table[LTI_netf2])
-#define gttf2_libfunc (libfunc_table[LTI_gttf2])
-#define getf2_libfunc (libfunc_table[LTI_getf2])
-#define lttf2_libfunc (libfunc_table[LTI_lttf2])
-#define letf2_libfunc (libfunc_table[LTI_letf2])
-#define unordtf2_libfunc (libfunc_table[LTI_unordtf2])
-
-#define floatsisf_libfunc (libfunc_table[LTI_floatsisf])
-#define floatdisf_libfunc (libfunc_table[LTI_floatdisf])
-#define floattisf_libfunc (libfunc_table[LTI_floattisf])
-
-#define floatsidf_libfunc (libfunc_table[LTI_floatsidf])
-#define floatdidf_libfunc (libfunc_table[LTI_floatdidf])
-#define floattidf_libfunc (libfunc_table[LTI_floattidf])
-
-#define floatsixf_libfunc (libfunc_table[LTI_floatsixf])
-#define floatdixf_libfunc (libfunc_table[LTI_floatdixf])
-#define floattixf_libfunc (libfunc_table[LTI_floattixf])
-
-#define floatsitf_libfunc (libfunc_table[LTI_floatsitf])
-#define floatditf_libfunc (libfunc_table[LTI_floatditf])
-#define floattitf_libfunc (libfunc_table[LTI_floattitf])
-
-#define fixsfsi_libfunc (libfunc_table[LTI_fixsfsi])
-#define fixsfdi_libfunc (libfunc_table[LTI_fixsfdi])
-#define fixsfti_libfunc (libfunc_table[LTI_fixsfti])
-
-#define fixdfsi_libfunc (libfunc_table[LTI_fixdfsi])
-#define fixdfdi_libfunc (libfunc_table[LTI_fixdfdi])
-#define fixdfti_libfunc (libfunc_table[LTI_fixdfti])
-
-#define fixxfsi_libfunc (libfunc_table[LTI_fixxfsi])
-#define fixxfdi_libfunc (libfunc_table[LTI_fixxfdi])
-#define fixxfti_libfunc (libfunc_table[LTI_fixxfti])
-
-#define fixtfsi_libfunc (libfunc_table[LTI_fixtfsi])
-#define fixtfdi_libfunc (libfunc_table[LTI_fixtfdi])
-#define fixtfti_libfunc (libfunc_table[LTI_fixtfti])
-
-#define fixunssfsi_libfunc (libfunc_table[LTI_fixunssfsi])
-#define fixunssfdi_libfunc (libfunc_table[LTI_fixunssfdi])
-#define fixunssfti_libfunc (libfunc_table[LTI_fixunssfti])
-
-#define fixunsdfsi_libfunc (libfunc_table[LTI_fixunsdfsi])
-#define fixunsdfdi_libfunc (libfunc_table[LTI_fixunsdfdi])
-#define fixunsdfti_libfunc (libfunc_table[LTI_fixunsdfti])
-
-#define fixunsxfsi_libfunc (libfunc_table[LTI_fixunsxfsi])
-#define fixunsxfdi_libfunc (libfunc_table[LTI_fixunsxfdi])
-#define fixunsxfti_libfunc (libfunc_table[LTI_fixunsxfti])
-
-#define fixunstfsi_libfunc (libfunc_table[LTI_fixunstfsi])
-#define fixunstfdi_libfunc (libfunc_table[LTI_fixunstfdi])
-#define fixunstfti_libfunc (libfunc_table[LTI_fixunstfti])
-
#define profile_function_entry_libfunc (libfunc_table[LTI_profile_function_entry])
#define profile_function_exit_libfunc (libfunc_table[LTI_profile_function_exit])
+#define gcov_flush_libfunc (libfunc_table[LTI_gcov_flush])
+#define gcov_init_libfunc (libfunc_table[LTI_gcov_init])
+
#endif /* GCC_LIBFUNCS_H */
diff --git a/contrib/gcc/libgcc-darwin.ver b/contrib/gcc/libgcc-darwin.ver
new file mode 100644
index 000000000000..a1038a818450
--- /dev/null
+++ b/contrib/gcc/libgcc-darwin.ver
@@ -0,0 +1,219 @@
+GCC_3.0 {
+ # libgcc1 integer symbols
+ ___absvsi2
+ ___addvsi3
+ ___ashlsi3
+ ___ashrsi3
+ ___divsi3
+ ___lshrsi3
+ ___modsi3
+ ___mulsi3
+ ___mulvsi3
+ ___negvsi2
+ ___subvsi3
+ ___udivsi3
+ ___umodsi3
+
+ # libgcc1 floating point symbols
+ ___addsf3
+ ___adddf3
+ ___addxf3
+ ___addtf3
+ ___divsf3
+ ___divdf3
+ ___divxf3
+ ___divtf3
+ ___eqsf2
+ ___eqdf2
+ ___eqxf2
+ ___eqtf2
+ ___extenddfxf2
+ ___extenddftf2
+ ___extendsfdf2
+ ___extendsfxf2
+ ___extendsftf2
+ ___fixsfsi
+ ___fixdfsi
+ ___fixxfsi
+ ___fixtfsi
+ ___floatsisf
+ ___floatsidf
+ ___floatsixf
+ ___floatsitf
+ ___gesf2
+ ___gedf2
+ ___gexf2
+ ___getf2
+ ___gtsf2
+ ___gtdf2
+ ___gtxf2
+ ___gttf2
+ ___lesf2
+ ___ledf2
+ ___lexf2
+ ___letf2
+ ___ltsf2
+ ___ltdf2
+ ___ltxf2
+ ___lttf2
+ ___mulsf3
+ ___muldf3
+ ___mulxf3
+ ___multf3
+ ___negsf2
+ ___negdf2
+ ___negxf2
+ ___negtf2
+ ___nesf2
+ ___nedf2
+ ___nexf2
+ ___netf2
+ ___subsf3
+ ___subdf3
+ ___subxf3
+ ___subtf3
+ ___truncdfsf2
+ ___truncxfsf2
+ ___trunctfsf2
+ ___truncxfdf2
+ ___trunctfdf2
+
+ # libgcc2 DImode arithmetic (for 32-bit targets).
+ ___absvdi2
+ ___addvdi3
+ ___ashldi3
+ ___ashrdi3
+ ___cmpdi2
+ ___divdi3
+ ___ffsdi2
+ ___fixdfdi
+ ___fixsfdi
+ ___fixtfdi
+ ___fixxfdi
+ ___fixunsdfdi
+ ___fixunsdfsi
+ ___fixunssfsi
+ ___fixunssfdi
+ ___fixunstfdi
+ ___fixunstfsi
+ ___fixunsxfdi
+ ___fixunsxfsi
+ ___floatdidf
+ ___floatdisf
+ ___floatdixf
+ ___floatditf
+ ___lshrdi3
+ ___moddi3
+ ___muldi3
+ ___mulvdi3
+ ___negdi2
+ ___negvdi2
+ ___subvdi3
+ ___ucmpdi2
+ ___udivdi3
+ ___udivmoddi4
+ ___umoddi3
+
+ # libgcc2 TImode arithmetic (for 64-bit targets).
+ ___ashlti3
+ ___ashrti3
+ ___cmpti2
+ ___divti3
+ ___ffsti2
+ ___fixdfti
+ ___fixsfti
+ ___fixtfti
+ ___fixxfti
+ ___lshrti3
+ ___modti3
+ ___multi3
+ ___negti2
+ ___ucmpti2
+ ___udivmodti4
+ ___udivti3
+ ___umodti3
+ ___fixunsdfti
+ ___fixunssfti
+ ___fixunstfti
+ ___fixunsxfti
+ ___floattidf
+ ___floattisf
+ ___floattixf
+ ___floattitf
+
+ # Used to deal with trampoline initialization on some platforms
+ ___clear_cache
+
+ # EH symbols
+ __Unwind_DeleteException
+ __Unwind_Find_FDE
+ __Unwind_ForcedUnwind
+ __Unwind_GetGR
+ __Unwind_GetIP
+ __Unwind_GetLanguageSpecificData
+ __Unwind_GetRegionStart
+ __Unwind_GetTextRelBase
+ __Unwind_GetDataRelBase
+ __Unwind_RaiseException
+ __Unwind_Resume
+ __Unwind_SetGR
+ __Unwind_SetIP
+ ___deregister_frame
+ ___deregister_frame_info
+ ___deregister_frame_info_bases
+ ___register_frame
+ ___register_frame_info
+ ___register_frame_info_bases
+ ___register_frame_info_table
+ ___register_frame_info_table_bases
+ ___register_frame_table
+
+ # SjLj EH symbols
+ __Unwind_SjLj_Register
+ __Unwind_SjLj_Unregister
+ __Unwind_SjLj_RaiseException
+ __Unwind_SjLj_ForcedUnwind
+ __Unwind_SjLj_Resume
+}
+
+%inherit GCC_3.3 GCC_3.0
+GCC_3.3 {
+ __Unwind_FindEnclosingFunction
+ __Unwind_GetCFA
+ __Unwind_Backtrace
+ __Unwind_Resume_or_Rethrow
+ __Unwind_SjLj_Resume_or_Rethrow
+}
+
+%inherit GCC_3.3.1 GCC_3.3
+GCC_3.3.1 {
+ __gcc_personality_sj0
+ __gcc_personality_v0
+}
+
+%inherit GCC_3.3.2 GCC_3.3.1
+GCC_3.3.2 {
+}
+
+%inherit GCC_3.3.4 GCC_3.3.2
+GCC_3.3.4 {
+ __unorddf2
+ __unordsf2
+}
+
+%inherit GCC_3.4 GCC_3.3.4
+GCC_3.4 {
+ # bit scanning and counting built-ins
+ ___clzsi2
+ ___clzdi2
+ ___clzti2
+ ___ctzsi2
+ ___ctzdi2
+ ___ctzti2
+ ___popcountsi2
+ ___popcountdi2
+ ___popcountti2
+ ___paritysi2
+ ___paritydi2
+ ___parityti2
+}
diff --git a/contrib/gcc/libgcc-std.ver b/contrib/gcc/libgcc-std.ver
index 79e79fb512ea..2dc7bb6433da 100644
--- a/contrib/gcc/libgcc-std.ver
+++ b/contrib/gcc/libgcc-std.ver
@@ -194,3 +194,32 @@ GCC_3.3.1 {
%inherit GCC_3.3.2 GCC_3.3.1
GCC_3.3.2 {
}
+
+%inherit GCC_3.3.4 GCC_3.3.2
+GCC_3.3.4 {
+ __unorddf2
+ __unordsf2
+}
+
+%inherit GCC_3.4 GCC_3.3.4
+GCC_3.4 {
+ # bit scanning and counting built-ins
+ __clzsi2
+ __clzdi2
+ __clzti2
+ __ctzsi2
+ __ctzdi2
+ __ctzti2
+ __popcountsi2
+ __popcountdi2
+ __popcountti2
+ __paritysi2
+ __paritydi2
+ __parityti2
+}
+
+%inherit GCC_3.4.2 GCC_3.4
+GCC_3.4.2 {
+ # Used to deal with trampoline initialization on some platforms
+ __enable_execute_stack
+}
diff --git a/contrib/gcc/libgcc2.c b/contrib/gcc/libgcc2.c
index dea803def0d7..8d77a7ee8903 100644
--- a/contrib/gcc/libgcc2.c
+++ b/contrib/gcc/libgcc2.c
@@ -1,7 +1,7 @@
/* More subroutines needed by GCC output code on some machines. */
/* Compile this one with gcc. */
/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -29,18 +29,30 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
+
+/* We include auto-host.h here to get HAVE_GAS_HIDDEN. This is
+ supposedly valid even though this is a "target" file. */
+#include "auto-host.h"
+
/* It is incorrect to include config.h here, because this file is being
compiled for the target, and hence definitions concerning only the host
do not apply. */
-
#include "tconfig.h"
#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
/* Don't use `fancy_abort' here even if config.h says to use it. */
#ifdef abort
#undef abort
#endif
+#ifdef HAVE_GAS_HIDDEN
+#define ATTRIBUTE_HIDDEN __attribute__ ((__visibility__ ("hidden")))
+#else
+#define ATTRIBUTE_HIDDEN
+#endif
+
#include "libgcc2.h"
#ifdef DECLARE_LIBRARY_RENAMES
@@ -51,13 +63,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
DWtype
__negdi2 (DWtype u)
{
- DWunion w;
- DWunion uu;
-
- uu.ll = u;
-
- w.s.low = -uu.s.low;
- w.s.high = -uu.s.high - ((UWtype) w.s.low > 0);
+ const DWunion uu = {.ll = u};
+ const DWunion w = { {.low = -uu.s.low,
+ .high = -uu.s.high - ((UWtype) -uu.s.low > 0) } };
return w.ll;
}
@@ -67,9 +75,7 @@ __negdi2 (DWtype u)
Wtype
__addvsi3 (Wtype a, Wtype b)
{
- Wtype w;
-
- w = a + b;
+ const Wtype w = a + b;
if (b >= 0 ? w < a : w > a)
abort ();
@@ -82,9 +88,7 @@ __addvsi3 (Wtype a, Wtype b)
DWtype
__addvdi3 (DWtype a, DWtype b)
{
- DWtype w;
-
- w = a + b;
+ const DWtype w = a + b;
if (b >= 0 ? w < a : w > a)
abort ();
@@ -97,18 +101,12 @@ __addvdi3 (DWtype a, DWtype b)
Wtype
__subvsi3 (Wtype a, Wtype b)
{
-#ifdef L_addvsi3
- return __addvsi3 (a, (-b));
-#else
- DWtype w;
-
- w = a - b;
+ const DWtype w = a - b;
if (b >= 0 ? w > a : w < a)
abort ();
return w;
-#endif
}
#endif
@@ -116,30 +114,25 @@ __subvsi3 (Wtype a, Wtype b)
DWtype
__subvdi3 (DWtype a, DWtype b)
{
-#ifdef L_addvdi3
- return (a, (-b));
-#else
- DWtype w;
-
- w = a - b;
+ const DWtype w = a - b;
if (b >= 0 ? w > a : w < a)
abort ();
return w;
-#endif
}
#endif
#ifdef L_mulvsi3
+#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
Wtype
__mulvsi3 (Wtype a, Wtype b)
{
- DWtype w;
-
- w = a * b;
+ const DWtype w = (DWtype) a * (DWtype) b;
- if (((a >= 0) == (b >= 0)) ? w < 0 : w > 0)
+ if (((a >= 0) == (b >= 0))
+ ? (UDWtype) w > (UDWtype) (((DWtype) 1 << (WORD_SIZE - 1)) - 1)
+ : (UDWtype) w < (UDWtype) ((DWtype) -1 << (WORD_SIZE - 1)))
abort ();
return w;
@@ -150,9 +143,7 @@ __mulvsi3 (Wtype a, Wtype b)
Wtype
__negvsi2 (Wtype a)
{
- Wtype w;
-
- w = -a;
+ const Wtype w = -a;
if (a >= 0 ? w > 0 : w < 0)
abort ();
@@ -165,9 +156,7 @@ __negvsi2 (Wtype a)
DWtype
__negvdi2 (DWtype a)
{
- DWtype w;
-
- w = -a;
+ const DWtype w = -a;
if (a >= 0 ? w > 0 : w < 0)
abort ();
@@ -203,8 +192,8 @@ __absvdi2 (DWtype a)
DWtype w = a;
if (a < 0)
-#ifdef L_negvsi2
- w = __negvsi2 (a);
+#ifdef L_negvdi2
+ w = __negvdi2 (a);
#else
w = -a;
@@ -217,37 +206,144 @@ __absvdi2 (DWtype a)
#endif
#ifdef L_mulvdi3
+#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
DWtype
__mulvdi3 (DWtype u, DWtype v)
{
- DWtype w;
-
- w = u * v;
+ /* The unchecked multiplication needs 3 Wtype x Wtype multiplications,
+ but the checked multiplication needs only two. */
+ const DWunion uu = {.ll = u};
+ const DWunion vv = {.ll = v};
- if (((u >= 0) == (v >= 0)) ? w < 0 : w > 0)
- abort ();
+ if (__builtin_expect (uu.s.high == uu.s.low >> (WORD_SIZE - 1), 1))
+ {
+ /* u fits in a single Wtype. */
+ if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1))
+ {
+ /* v fits in a single Wtype as well. */
+ /* A single multiplication. No overflow risk. */
+ return (DWtype) uu.s.low * (DWtype) vv.s.low;
+ }
+ else
+ {
+ /* Two multiplications. */
+ DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
+ * (UDWtype) (UWtype) vv.s.low};
+ DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.low
+ * (UDWtype) (UWtype) vv.s.high};
+
+ if (vv.s.high < 0)
+ w1.s.high -= uu.s.low;
+ if (uu.s.low < 0)
+ w1.ll -= vv.ll;
+ w1.ll += (UWtype) w0.s.high;
+ if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1))
+ {
+ w0.s.high = w1.s.low;
+ return w0.ll;
+ }
+ }
+ }
+ else
+ {
+ if (__builtin_expect (vv.s.high == vv.s.low >> (WORD_SIZE - 1), 1))
+ {
+ /* v fits into a single Wtype. */
+ /* Two multiplications. */
+ DWunion w0 = {.ll = (UDWtype) (UWtype) uu.s.low
+ * (UDWtype) (UWtype) vv.s.low};
+ DWunion w1 = {.ll = (UDWtype) (UWtype) uu.s.high
+ * (UDWtype) (UWtype) vv.s.low};
+
+ if (uu.s.high < 0)
+ w1.s.high -= vv.s.low;
+ if (vv.s.low < 0)
+ w1.ll -= uu.ll;
+ w1.ll += (UWtype) w0.s.high;
+ if (__builtin_expect (w1.s.high == w1.s.low >> (WORD_SIZE - 1), 1))
+ {
+ w0.s.high = w1.s.low;
+ return w0.ll;
+ }
+ }
+ else
+ {
+ /* A few sign checks and a single multiplication. */
+ if (uu.s.high >= 0)
+ {
+ if (vv.s.high >= 0)
+ {
+ if (uu.s.high == 0 && vv.s.high == 0)
+ {
+ const DWtype w = (UDWtype) (UWtype) uu.s.low
+ * (UDWtype) (UWtype) vv.s.low;
+ if (__builtin_expect (w >= 0, 1))
+ return w;
+ }
+ }
+ else
+ {
+ if (uu.s.high == 0 && vv.s.high == (Wtype) -1)
+ {
+ DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
+ * (UDWtype) (UWtype) vv.s.low};
+
+ ww.s.high -= uu.s.low;
+ if (__builtin_expect (ww.s.high < 0, 1))
+ return ww.ll;
+ }
+ }
+ }
+ else
+ {
+ if (vv.s.high >= 0)
+ {
+ if (uu.s.high == (Wtype) -1 && vv.s.high == 0)
+ {
+ DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
+ * (UDWtype) (UWtype) vv.s.low};
+
+ ww.s.high -= vv.s.low;
+ if (__builtin_expect (ww.s.high < 0, 1))
+ return ww.ll;
+ }
+ }
+ else
+ {
+ if (uu.s.high == (Wtype) -1 && vv.s.high == (Wtype) - 1)
+ {
+ DWunion ww = {.ll = (UDWtype) (UWtype) uu.s.low
+ * (UDWtype) (UWtype) vv.s.low};
+
+ ww.s.high -= uu.s.low;
+ ww.s.high -= vv.s.low;
+ if (__builtin_expect (ww.s.high >= 0, 1))
+ return ww.ll;
+ }
+ }
+ }
+ }
+ }
- return w;
+ /* Overflow. */
+ abort ();
}
#endif
-/* Unless shift functions are defined whith full ANSI prototypes,
+/* Unless shift functions are defined with full ANSI prototypes,
parameter b will be promoted to int if word_type is smaller than an int. */
#ifdef L_lshrdi3
DWtype
__lshrdi3 (DWtype u, word_type b)
{
- DWunion w;
- word_type bm;
- DWunion uu;
-
if (b == 0)
return u;
- uu.ll = u;
+ const DWunion uu = {.ll = u};
+ const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
+ DWunion w;
- bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
if (bm <= 0)
{
w.s.high = 0;
@@ -255,7 +351,7 @@ __lshrdi3 (DWtype u, word_type b)
}
else
{
- UWtype carries = (UWtype) uu.s.high << bm;
+ const UWtype carries = (UWtype) uu.s.high << bm;
w.s.high = (UWtype) uu.s.high >> b;
w.s.low = ((UWtype) uu.s.low >> b) | carries;
@@ -269,16 +365,13 @@ __lshrdi3 (DWtype u, word_type b)
DWtype
__ashldi3 (DWtype u, word_type b)
{
- DWunion w;
- word_type bm;
- DWunion uu;
-
if (b == 0)
return u;
- uu.ll = u;
+ const DWunion uu = {.ll = u};
+ const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
+ DWunion w;
- bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
if (bm <= 0)
{
w.s.low = 0;
@@ -286,7 +379,7 @@ __ashldi3 (DWtype u, word_type b)
}
else
{
- UWtype carries = (UWtype) uu.s.low >> bm;
+ const UWtype carries = (UWtype) uu.s.low >> bm;
w.s.low = (UWtype) uu.s.low << b;
w.s.high = ((UWtype) uu.s.high << b) | carries;
@@ -300,16 +393,13 @@ __ashldi3 (DWtype u, word_type b)
DWtype
__ashrdi3 (DWtype u, word_type b)
{
- DWunion w;
- word_type bm;
- DWunion uu;
-
if (b == 0)
return u;
- uu.ll = u;
+ const DWunion uu = {.ll = u};
+ const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
+ DWunion w;
- bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
if (bm <= 0)
{
/* w.s.high = 1..1 or 0..0 */
@@ -318,7 +408,7 @@ __ashrdi3 (DWtype u, word_type b)
}
else
{
- UWtype carries = (UWtype) uu.s.high << bm;
+ const UWtype carries = (UWtype) uu.s.high << bm;
w.s.high = uu.s.high >> b;
w.s.low = ((UWtype) uu.s.low >> b) | carries;
@@ -328,14 +418,31 @@ __ashrdi3 (DWtype u, word_type b)
}
#endif
+#ifdef L_ffssi2
+#undef int
+extern int __ffsSI2 (UWtype u);
+int
+__ffsSI2 (UWtype u)
+{
+ UWtype count;
+
+ if (u == 0)
+ return 0;
+
+ count_trailing_zeros (count, u);
+ return count + 1;
+}
+#endif
+
#ifdef L_ffsdi2
-DWtype
-__ffsdi2 (DWtype u)
+#undef int
+extern int __ffsDI2 (DWtype u);
+int
+__ffsDI2 (DWtype u)
{
- DWunion uu;
+ const DWunion uu = {.ll = u};
UWtype word, count, add;
- uu.ll = u;
if (uu.s.low != 0)
word = uu.s.low, add = 0;
else if (uu.s.high != 0)
@@ -352,13 +459,10 @@ __ffsdi2 (DWtype u)
DWtype
__muldi3 (DWtype u, DWtype v)
{
- DWunion w;
- DWunion uu, vv;
-
- uu.ll = u,
- vv.ll = v;
+ const DWunion uu = {.ll = u};
+ const DWunion vv = {.ll = v};
+ DWunion w = {.ll = __umulsidi3 (uu.s.low, vv.s.low)};
- w.ll = __umulsidi3 (uu.s.low, vv.s.low);
w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high
+ (UWtype) uu.s.high * (UWtype) vv.s.low);
@@ -506,6 +610,170 @@ const UQItype __clz_tab[] =
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
};
#endif
+
+#ifdef L_clzsi2
+#undef int
+extern int __clzSI2 (UWtype x);
+int
+__clzSI2 (UWtype x)
+{
+ Wtype ret;
+
+ count_leading_zeros (ret, x);
+
+ return ret;
+}
+#endif
+
+#ifdef L_clzdi2
+#undef int
+extern int __clzDI2 (UDWtype x);
+int
+__clzDI2 (UDWtype x)
+{
+ const DWunion uu = {.ll = x};
+ UWtype word;
+ Wtype ret, add;
+
+ if (uu.s.high)
+ word = uu.s.high, add = 0;
+ else
+ word = uu.s.low, add = W_TYPE_SIZE;
+
+ count_leading_zeros (ret, word);
+ return ret + add;
+}
+#endif
+
+#ifdef L_ctzsi2
+#undef int
+extern int __ctzSI2 (UWtype x);
+int
+__ctzSI2 (UWtype x)
+{
+ Wtype ret;
+
+ count_trailing_zeros (ret, x);
+
+ return ret;
+}
+#endif
+
+#ifdef L_ctzdi2
+#undef int
+extern int __ctzDI2 (UDWtype x);
+int
+__ctzDI2 (UDWtype x)
+{
+ const DWunion uu = {.ll = x};
+ UWtype word;
+ Wtype ret, add;
+
+ if (uu.s.low)
+ word = uu.s.low, add = 0;
+ else
+ word = uu.s.high, add = W_TYPE_SIZE;
+
+ count_trailing_zeros (ret, word);
+ return ret + add;
+}
+#endif
+
+#if (defined (L_popcountsi2) || defined (L_popcountdi2) \
+ || defined (L_popcount_tab))
+extern const UQItype __popcount_tab[] ATTRIBUTE_HIDDEN;
+#endif
+
+#ifdef L_popcount_tab
+const UQItype __popcount_tab[] =
+{
+ 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
+};
+#endif
+
+#ifdef L_popcountsi2
+#undef int
+extern int __popcountSI2 (UWtype x);
+int
+__popcountSI2 (UWtype x)
+{
+ UWtype i, ret = 0;
+
+ for (i = 0; i < W_TYPE_SIZE; i += 8)
+ ret += __popcount_tab[(x >> i) & 0xff];
+
+ return ret;
+}
+#endif
+
+#ifdef L_popcountdi2
+#undef int
+extern int __popcountDI2 (UDWtype x);
+int
+__popcountDI2 (UDWtype x)
+{
+ UWtype i, ret = 0;
+
+ for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
+ ret += __popcount_tab[(x >> i) & 0xff];
+
+ return ret;
+}
+#endif
+
+#ifdef L_paritysi2
+#undef int
+extern int __paritySI2 (UWtype x);
+int
+__paritySI2 (UWtype x)
+{
+#if W_TYPE_SIZE > 64
+# error "fill out the table"
+#endif
+#if W_TYPE_SIZE > 32
+ x ^= x >> 32;
+#endif
+#if W_TYPE_SIZE > 16
+ x ^= x >> 16;
+#endif
+ x ^= x >> 8;
+ x ^= x >> 4;
+ x &= 0xf;
+ return (0x6996 >> x) & 1;
+}
+#endif
+
+#ifdef L_paritydi2
+#undef int
+extern int __parityDI2 (UDWtype x);
+int
+__parityDI2 (UDWtype x)
+{
+ const DWunion uu = {.ll = x};
+ UWtype nx = uu.s.low ^ uu.s.high;
+
+#if W_TYPE_SIZE > 64
+# error "fill out the table"
+#endif
+#if W_TYPE_SIZE > 32
+ nx ^= nx >> 32;
+#endif
+#if W_TYPE_SIZE > 16
+ nx ^= nx >> 16;
+#endif
+ nx ^= nx >> 8;
+ nx ^= nx >> 4;
+ nx &= 0xf;
+ return (0x6996 >> nx) & 1;
+}
+#endif
#ifdef L_udivmoddi4
@@ -516,16 +784,13 @@ static inline __attribute__ ((__always_inline__))
UDWtype
__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
{
- DWunion ww;
- DWunion nn, dd;
+ const DWunion nn = {.ll = n};
+ const DWunion dd = {.ll = d};
DWunion rr;
UWtype d0, d1, n0, n1, n2;
UWtype q0, q1;
UWtype b, bm;
- nn.ll = n;
- dd.ll = d;
-
d0 = dd.s.low;
d1 = dd.s.high;
n0 = nn.s.low;
@@ -725,8 +990,7 @@ __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
}
}
- ww.s.low = q0;
- ww.s.high = q1;
+ const DWunion ww = {{.low = q0, .high = q1}};
return ww.ll;
}
#endif
@@ -736,12 +1000,10 @@ DWtype
__divdi3 (DWtype u, DWtype v)
{
word_type c = 0;
- DWunion uu, vv;
+ DWunion uu = {.ll = u};
+ DWunion vv = {.ll = v};
DWtype w;
- uu.ll = u;
- vv.ll = v;
-
if (uu.s.high < 0)
c = ~c,
uu.ll = -uu.ll;
@@ -762,12 +1024,10 @@ DWtype
__moddi3 (DWtype u, DWtype v)
{
word_type c = 0;
- DWunion uu, vv;
+ DWunion uu = {.ll = u};
+ DWunion vv = {.ll = v};
DWtype w;
- uu.ll = u;
- vv.ll = v;
-
if (uu.s.high < 0)
c = ~c,
uu.ll = -uu.ll;
@@ -806,9 +1066,8 @@ __udivdi3 (UDWtype n, UDWtype d)
word_type
__cmpdi2 (DWtype a, DWtype b)
{
- DWunion au, bu;
-
- au.ll = a, bu.ll = b;
+ const DWunion au = {.ll = a};
+ const DWunion bu = {.ll = b};
if (au.s.high < bu.s.high)
return 0;
@@ -826,9 +1085,8 @@ __cmpdi2 (DWtype a, DWtype b)
word_type
__ucmpdi2 (DWtype a, DWtype b)
{
- DWunion au, bu;
-
- au.ll = a, bu.ll = b;
+ const DWunion au = {.ll = a};
+ const DWunion bu = {.ll = b};
if ((UWtype) au.s.high < (UWtype) bu.s.high)
return 0;
@@ -849,17 +1107,14 @@ __ucmpdi2 (DWtype a, DWtype b)
DWtype
__fixunstfDI (TFtype a)
{
- TFtype b;
- UDWtype v;
-
if (a < 0)
return 0;
/* Compute high word of result, as a flonum. */
- b = (a / HIGH_WORD_COEFF);
+ const TFtype b = (a / HIGH_WORD_COEFF);
/* Convert that to fixed (but not to DWtype!),
and shift it into the high word. */
- v = (UWtype) b;
+ UDWtype v = (UWtype) b;
v <<= WORD_SIZE;
/* Remove high part from the TFtype, leaving the low part as flonum. */
a -= (TFtype)v;
@@ -891,17 +1146,14 @@ __fixtfdi (TFtype a)
DWtype
__fixunsxfDI (XFtype a)
{
- XFtype b;
- UDWtype v;
-
if (a < 0)
return 0;
/* Compute high word of result, as a flonum. */
- b = (a / HIGH_WORD_COEFF);
+ const XFtype b = (a / HIGH_WORD_COEFF);
/* Convert that to fixed (but not to DWtype!),
and shift it into the high word. */
- v = (UWtype) b;
+ UDWtype v = (UWtype) b;
v <<= WORD_SIZE;
/* Remove high part from the XFtype, leaving the low part as flonum. */
a -= (XFtype)v;
@@ -933,28 +1185,18 @@ __fixxfdi (XFtype a)
DWtype
__fixunsdfDI (DFtype a)
{
- DFtype b;
- UDWtype v;
-
- if (a < 0)
- return 0;
-
- /* Compute high word of result, as a flonum. */
- b = (a / HIGH_WORD_COEFF);
- /* Convert that to fixed (but not to DWtype!),
- and shift it into the high word. */
- v = (UWtype) b;
- v <<= WORD_SIZE;
- /* Remove high part from the DFtype, leaving the low part as flonum. */
- a -= (DFtype)v;
- /* Convert that to fixed (but not to DWtype!) and add it in.
- Sometimes A comes out negative. This is significant, since
- A has more bits than a long int does. */
- if (a < 0)
- v -= (UWtype) (- a);
- else
- v += (UWtype) a;
- return v;
+ /* Get high part of result. The division here will just moves the radix
+ point and will not cause any rounding. Then the conversion to integral
+ type chops result as desired. */
+ const UWtype hi = a / HIGH_WORD_COEFF;
+
+ /* Get low part of result. Convert `hi' to floating type and scale it back,
+ then subtract this from the number being converted. This leaves the low
+ part. Convert that to integral type. */
+ const UWtype lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
+
+ /* Assemble result from the two parts. */
+ return ((UDWtype) hi << WORD_SIZE) | lo;
}
#endif
@@ -978,29 +1220,20 @@ __fixunssfDI (SFtype original_a)
/* Convert the SFtype to a DFtype, because that is surely not going
to lose any bits. Some day someone else can write a faster version
that avoids converting to DFtype, and verify it really works right. */
- DFtype a = original_a;
- DFtype b;
- UDWtype v;
+ const DFtype a = original_a;
- if (a < 0)
- return 0;
+ /* Get high part of result. The division here will just moves the radix
+ point and will not cause any rounding. Then the conversion to integral
+ type chops result as desired. */
+ const UWtype hi = a / HIGH_WORD_COEFF;
- /* Compute high word of result, as a flonum. */
- b = (a / HIGH_WORD_COEFF);
- /* Convert that to fixed (but not to DWtype!),
- and shift it into the high word. */
- v = (UWtype) b;
- v <<= WORD_SIZE;
- /* Remove high part from the DFtype, leaving the low part as flonum. */
- a -= (DFtype) v;
- /* Convert that to fixed (but not to DWtype!) and add it in.
- Sometimes A comes out negative. This is significant, since
- A has more bits than a long int does. */
- if (a < 0)
- v -= (UWtype) (- a);
- else
- v += (UWtype) a;
- return v;
+ /* Get low part of result. Convert `hi' to floating type and scale it back,
+ then subtract this from the number being converted. This leaves the low
+ part. Convert that to integral type. */
+ const UWtype lo = (a - ((DFtype) hi) * HIGH_WORD_COEFF);
+
+ /* Assemble result from the two parts. */
+ return ((UDWtype) hi << WORD_SIZE) | lo;
}
#endif
@@ -1022,9 +1255,7 @@ __fixsfdi (SFtype a)
XFtype
__floatdixf (DWtype u)
{
- XFtype d;
-
- d = (Wtype) (u >> WORD_SIZE);
+ XFtype d = (Wtype) (u >> WORD_SIZE);
d *= HIGH_HALFWORD_COEFF;
d *= HIGH_HALFWORD_COEFF;
d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
@@ -1041,9 +1272,7 @@ __floatdixf (DWtype u)
TFtype
__floatditf (DWtype u)
{
- TFtype d;
-
- d = (Wtype) (u >> WORD_SIZE);
+ TFtype d = (Wtype) (u >> WORD_SIZE);
d *= HIGH_HALFWORD_COEFF;
d *= HIGH_HALFWORD_COEFF;
d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
@@ -1060,9 +1289,7 @@ __floatditf (DWtype u)
DFtype
__floatdidf (DWtype u)
{
- DFtype d;
-
- d = (Wtype) (u >> WORD_SIZE);
+ DFtype d = (Wtype) (u >> WORD_SIZE);
d *= HIGH_HALFWORD_COEFF;
d *= HIGH_HALFWORD_COEFF;
d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
@@ -1083,11 +1310,6 @@ __floatdidf (DWtype u)
SFtype
__floatdisf (DWtype u)
{
- /* Do the calculation in DFmode
- so that we don't lose any of the precision of the high word
- while multiplying it. */
- DFtype f;
-
/* Protect against double-rounding error.
Represent any low-order bits, that might be truncated in DFmode,
by a bit that won't be lost. The bit can go in anywhere below the
@@ -1108,7 +1330,10 @@ __floatdisf (DWtype u)
}
}
}
- f = (Wtype) (u >> WORD_SIZE);
+ /* Do the calculation in DFmode
+ so that we don't lose any of the precision of the high word
+ while multiplying it. */
+ DFtype f = (Wtype) (u >> WORD_SIZE);
f *= HIGH_HALFWORD_COEFF;
f *= HIGH_HALFWORD_COEFF;
f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
@@ -1217,7 +1442,7 @@ __gcc_bcmp (const unsigned char *s1, const unsigned char *s2, size_t size)
{
while (size > 0)
{
- unsigned char c1 = *s1++, c2 = *s2++;
+ const unsigned char c1 = *s1++, c2 = *s2++;
if (c1 != c2)
return c1 - c2;
size--;
@@ -1249,453 +1474,34 @@ __eprintf (const char *string, const char *expression,
#endif
#endif
-#ifdef L_bb
-
-struct bb_function_info {
- long checksum;
- int arc_count;
- const char *name;
-};
-
-/* Structure emitted by --profile-arcs */
-struct bb
-{
- long zero_word;
- const char *filename;
- gcov_type *counts;
- long ncounts;
- struct bb *next;
-
- /* Older GCC's did not emit these fields. */
- long sizeof_bb;
- struct bb_function_info *function_infos;
-};
-
-#ifndef inhibit_libc
-
-/* Arc profile dumper. Requires atexit and stdio. */
-
-#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
-#include <stdio.h>
-
-#include "gcov-io.h"
-#include <string.h>
-#ifdef TARGET_HAS_F_SETLKW
-#include <fcntl.h>
-#include <errno.h>
-#endif
-
-/* Chain of per-object file bb structures. */
-static struct bb *bb_head;
-
-/* Dump the coverage counts. We merge with existing counts when
- possible, to avoid growing the .da files ad infinitum. */
-
-void
-__bb_exit_func (void)
-{
- struct bb *ptr;
- int i;
- gcov_type program_sum = 0;
- gcov_type program_max = 0;
- long program_arcs = 0;
- gcov_type merged_sum = 0;
- gcov_type merged_max = 0;
- long merged_arcs = 0;
-
-#if defined (TARGET_HAS_F_SETLKW)
- struct flock s_flock;
-
- s_flock.l_type = F_WRLCK;
- s_flock.l_whence = SEEK_SET;
- s_flock.l_start = 0;
- s_flock.l_len = 0; /* Until EOF. */
- s_flock.l_pid = getpid ();
-#endif
-
- /* Non-merged stats for this program. */
- for (ptr = bb_head; ptr; ptr = ptr->next)
- {
- for (i = 0; i < ptr->ncounts; i++)
- {
- program_sum += ptr->counts[i];
-
- if (ptr->counts[i] > program_max)
- program_max = ptr->counts[i];
- }
- program_arcs += ptr->ncounts;
- }
-
- for (ptr = bb_head; ptr; ptr = ptr->next)
- {
- FILE *da_file;
- gcov_type object_max = 0;
- gcov_type object_sum = 0;
- long object_functions = 0;
- int merging = 0;
- int error = 0;
- struct bb_function_info *fn_info;
- gcov_type *count_ptr;
-
- /* Open for modification */
- da_file = fopen (ptr->filename, "r+b");
-
- if (da_file)
- merging = 1;
- else
- {
- /* Try for appending */
- da_file = fopen (ptr->filename, "ab");
- /* Some old systems might not allow the 'b' mode modifier.
- Therefore, try to open without it. This can lead to a
- race condition so that when you delete and re-create the
- file, the file might be opened in text mode, but then,
- you shouldn't delete the file in the first place. */
- if (!da_file)
- da_file = fopen (ptr->filename, "a");
- }
-
- if (!da_file)
- {
- fprintf (stderr, "arc profiling: Can't open output file %s.\n",
- ptr->filename);
- ptr->filename = 0;
- continue;
- }
-
-#if defined (TARGET_HAS_F_SETLKW)
- /* After a fork, another process might try to read and/or write
- the same file simultanously. So if we can, lock the file to
- avoid race conditions. */
- while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
- && errno == EINTR)
- continue;
-#endif
- for (fn_info = ptr->function_infos; fn_info->arc_count != -1; fn_info++)
- object_functions++;
-
- if (merging)
- {
- /* Merge data from file. */
- long tmp_long;
- gcov_type tmp_gcov;
-
- if (/* magic */
- (__read_long (&tmp_long, da_file, 4) || tmp_long != -123l)
- /* functions in object file. */
- || (__read_long (&tmp_long, da_file, 4)
- || tmp_long != object_functions)
- /* extension block, skipped */
- || (__read_long (&tmp_long, da_file, 4)
- || fseek (da_file, tmp_long, SEEK_CUR)))
- {
- read_error:;
- fprintf (stderr, "arc profiling: Error merging output file %s.\n",
- ptr->filename);
- clearerr (da_file);
- }
- else
- {
- /* Merge execution counts for each function. */
- count_ptr = ptr->counts;
-
- for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
- fn_info++)
- {
- if (/* function name delim */
- (__read_long (&tmp_long, da_file, 4)
- || tmp_long != -1)
- /* function name length */
- || (__read_long (&tmp_long, da_file, 4)
- || tmp_long != (long) strlen (fn_info->name))
- /* skip string */
- || fseek (da_file, ((tmp_long + 1) + 3) & ~3, SEEK_CUR)
- /* function name delim */
- || (__read_long (&tmp_long, da_file, 4)
- || tmp_long != -1))
- goto read_error;
-
- if (/* function checksum */
- (__read_long (&tmp_long, da_file, 4)
- || tmp_long != fn_info->checksum)
- /* arc count */
- || (__read_long (&tmp_long, da_file, 4)
- || tmp_long != fn_info->arc_count))
- goto read_error;
-
- for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
- if (__read_gcov_type (&tmp_gcov, da_file, 8))
- goto read_error;
- else
- *count_ptr += tmp_gcov;
- }
- }
- fseek (da_file, 0, SEEK_SET);
- }
-
- /* Calculate the per-object statistics. */
- for (i = 0; i < ptr->ncounts; i++)
- {
- object_sum += ptr->counts[i];
-
- if (ptr->counts[i] > object_max)
- object_max = ptr->counts[i];
- }
- merged_sum += object_sum;
- if (merged_max < object_max)
- merged_max = object_max;
- merged_arcs += ptr->ncounts;
-
- /* Write out the data. */
- if (/* magic */
- __write_long (-123, da_file, 4)
- /* number of functions in object file. */
- || __write_long (object_functions, da_file, 4)
- /* length of extra data in bytes. */
- || __write_long ((4 + 8 + 8) + (4 + 8 + 8), da_file, 4)
-
- /* whole program statistics. If merging write per-object
- now, rewrite later */
- /* number of instrumented arcs. */
- || __write_long (merging ? ptr->ncounts : program_arcs, da_file, 4)
- /* sum of counters. */
- || __write_gcov_type (merging ? object_sum : program_sum, da_file, 8)
- /* maximal counter. */
- || __write_gcov_type (merging ? object_max : program_max, da_file, 8)
-
- /* per-object statistics. */
- /* number of counters. */
- || __write_long (ptr->ncounts, da_file, 4)
- /* sum of counters. */
- || __write_gcov_type (object_sum, da_file, 8)
- /* maximal counter. */
- || __write_gcov_type (object_max, da_file, 8))
- {
- write_error:;
- fprintf (stderr, "arc profiling: Error writing output file %s.\n",
- ptr->filename);
- error = 1;
- }
- else
- {
- /* Write execution counts for each function. */
- count_ptr = ptr->counts;
-
- for (fn_info = ptr->function_infos; fn_info->arc_count != -1;
- fn_info++)
- {
- if (__write_gcov_string (fn_info->name,
- strlen (fn_info->name), da_file, -1)
- || __write_long (fn_info->checksum, da_file, 4)
- || __write_long (fn_info->arc_count, da_file, 4))
- goto write_error;
-
- for (i = fn_info->arc_count; i > 0; i--, count_ptr++)
- if (__write_gcov_type (*count_ptr, da_file, 8))
- goto write_error; /* RIP Edsger Dijkstra */
- }
- }
-
- if (fclose (da_file))
- {
- fprintf (stderr, "arc profiling: Error closing output file %s.\n",
- ptr->filename);
- error = 1;
- }
- if (error || !merging)
- ptr->filename = 0;
- }
-
- /* Upate whole program statistics. */
- for (ptr = bb_head; ptr; ptr = ptr->next)
- if (ptr->filename)
- {
- FILE *da_file;
-
- da_file = fopen (ptr->filename, "r+b");
- if (!da_file)
- {
- fprintf (stderr, "arc profiling: Cannot reopen %s.\n",
- ptr->filename);
- continue;
- }
-
-#if defined (TARGET_HAS_F_SETLKW)
- while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
- && errno == EINTR)
- continue;
-#endif
-
- if (fseek (da_file, 4 * 3, SEEK_SET)
- /* number of instrumented arcs. */
- || __write_long (merged_arcs, da_file, 4)
- /* sum of counters. */
- || __write_gcov_type (merged_sum, da_file, 8)
- /* maximal counter. */
- || __write_gcov_type (merged_max, da_file, 8))
- fprintf (stderr, "arc profiling: Error updating program header %s.\n",
- ptr->filename);
- if (fclose (da_file))
- fprintf (stderr, "arc profiling: Error reclosing %s\n",
- ptr->filename);
- }
-}
-
-/* Add a new object file onto the bb chain. Invoked automatically
- when running an object file's global ctors. */
-
-void
-__bb_init_func (struct bb *blocks)
-{
- if (blocks->zero_word)
- return;
-
- /* Initialize destructor and per-thread data. */
- if (!bb_head)
- atexit (__bb_exit_func);
-
- /* Set up linked list. */
- blocks->zero_word = 1;
- blocks->next = bb_head;
- bb_head = blocks;
-}
-
-/* Called before fork or exec - write out profile information gathered so
- far and reset it to zero. This avoids duplication or loss of the
- profile information gathered so far. */
-
-void
-__bb_fork_func (void)
-{
- struct bb *ptr;
-
- __bb_exit_func ();
- for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
- {
- long i;
- for (i = ptr->ncounts - 1; i >= 0; i--)
- ptr->counts[i] = 0;
- }
-}
-
-#endif /* not inhibit_libc */
-#endif /* L_bb */
#ifdef L_clear_cache
/* Clear part of an instruction cache. */
-#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
-
void
__clear_cache (char *beg __attribute__((__unused__)),
char *end __attribute__((__unused__)))
{
#ifdef CLEAR_INSN_CACHE
CLEAR_INSN_CACHE (beg, end);
-#else
-#ifdef INSN_CACHE_SIZE
- static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
- static int initialized;
- int offset;
- void *start_addr
- void *end_addr;
- typedef (*function_ptr) (void);
-
-#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
- /* It's cheaper to clear the whole cache.
- Put in a series of jump instructions so that calling the beginning
- of the cache will clear the whole thing. */
-
- if (! initialized)
- {
- int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
- & -INSN_CACHE_LINE_WIDTH);
- int end_ptr = ptr + INSN_CACHE_SIZE;
-
- while (ptr < end_ptr)
- {
- *(INSTRUCTION_TYPE *)ptr
- = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
- ptr += INSN_CACHE_LINE_WIDTH;
- }
- *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
-
- initialized = 1;
- }
-
- /* Call the beginning of the sequence. */
- (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
- & -INSN_CACHE_LINE_WIDTH))
- ());
-
-#else /* Cache is large. */
-
- if (! initialized)
- {
- int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
- & -INSN_CACHE_LINE_WIDTH);
-
- while (ptr < (int) array + sizeof array)
- {
- *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
- ptr += INSN_CACHE_LINE_WIDTH;
- }
-
- initialized = 1;
- }
-
- /* Find the location in array that occupies the same cache line as BEG. */
-
- offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
- start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
- & -INSN_CACHE_PLANE_SIZE)
- + offset);
-
- /* Compute the cache alignment of the place to stop clearing. */
-#if 0 /* This is not needed for gcc's purposes. */
- /* If the block to clear is bigger than a cache plane,
- we clear the entire cache, and OFFSET is already correct. */
- if (end < beg + INSN_CACHE_PLANE_SIZE)
-#endif
- offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
- & -INSN_CACHE_LINE_WIDTH)
- & (INSN_CACHE_PLANE_SIZE - 1));
-
-#if INSN_CACHE_DEPTH > 1
- end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
- if (end_addr <= start_addr)
- end_addr += INSN_CACHE_PLANE_SIZE;
-
- for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
- {
- int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
- int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
-
- while (addr != stop)
- {
- /* Call the return instruction at ADDR. */
- ((function_ptr) addr) ();
-
- addr += INSN_CACHE_LINE_WIDTH;
- }
- }
-#else /* just one plane */
- do
- {
- /* Call the return instruction at START_ADDR. */
- ((function_ptr) start_addr) ();
-
- start_addr += INSN_CACHE_LINE_WIDTH;
- }
- while ((start_addr % INSN_CACHE_SIZE) != offset);
-#endif /* just one plane */
-#endif /* Cache is large */
-#endif /* Cache exists */
#endif /* CLEAR_INSN_CACHE */
}
#endif /* L_clear_cache */
+#ifdef L_enable_execute_stack
+/* Attempt to turn on execute permission for the stack. */
+
+#ifdef ENABLE_EXECUTE_STACK
+ ENABLE_EXECUTE_STACK
+#else
+void
+__enable_execute_stack (void *addr __attribute__((__unused__)))
+{}
+#endif /* ENABLE_EXECUTE_STACK */
+
+#endif /* L_enable_execute_stack */
+
#ifdef L_trampoline
/* Jump to a trampoline, loading the static chain address. */
@@ -1745,51 +1551,6 @@ mprotect (char *addr, int len, int prot)
#ifdef TRANSFER_FROM_TRAMPOLINE
TRANSFER_FROM_TRAMPOLINE
#endif
-
-#ifdef __sysV68__
-
-#include <sys/signal.h>
-#include <errno.h>
-
-/* Motorola forgot to put memctl.o in the libp version of libc881.a,
- so define it here, because we need it in __clear_insn_cache below */
-/* On older versions of this OS, no memctl or MCT_TEXT are defined;
- hence we enable this stuff only if MCT_TEXT is #define'd. */
-
-#ifdef MCT_TEXT
-asm("\n\
- global memctl\n\
-memctl:\n\
- movq &75,%d0\n\
- trap &0\n\
- bcc.b noerror\n\
- jmp cerror%\n\
-noerror:\n\
- movq &0,%d0\n\
- rts");
-#endif
-
-/* Clear instruction cache so we can call trampolines on stack.
- This is called from FINALIZE_TRAMPOLINE in mot3300.h. */
-
-void
-__clear_insn_cache (void)
-{
-#ifdef MCT_TEXT
- int save_errno;
-
- /* Preserve errno, because users would be surprised to have
- errno changing without explicitly calling any system-call. */
- save_errno = errno;
-
- /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache.
- No need to use an address derived from _start or %sp, as 0 works also. */
- memctl(0, 4096, MCT_TEXT);
- errno = save_errno;
-#endif
-}
-
-#endif /* __sysV68__ */
#endif /* L_trampoline */
#ifndef __CYGWIN__
@@ -1874,8 +1635,9 @@ __do_global_ctors (void)
For systems which support a .init section we use the .init section
to run __do_global_ctors, so we need not do anything here. */
+extern void SYMBOL__MAIN (void);
void
-SYMBOL__MAIN ()
+SYMBOL__MAIN (void)
{
/* Support recursive calls to `main': run initializers just once. */
static int initialized;
@@ -1917,79 +1679,4 @@ func_ptr __DTOR_LIST__[2];
#endif
#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
#endif /* L_ctors */
-
-#ifdef L_exit
-
-#include "gbl-ctors.h"
-
-#ifdef NEED_ATEXIT
-
-#ifndef ON_EXIT
-
-# include <errno.h>
-
-static func_ptr *atexit_chain = 0;
-static long atexit_chain_length = 0;
-static volatile long last_atexit_chain_slot = -1;
-
-int
-atexit (func_ptr func)
-{
- if (++last_atexit_chain_slot == atexit_chain_length)
- {
- atexit_chain_length += 32;
- if (atexit_chain)
- atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length
- * sizeof (func_ptr));
- else
- atexit_chain = (func_ptr *) malloc (atexit_chain_length
- * sizeof (func_ptr));
- if (! atexit_chain)
- {
- atexit_chain_length = 0;
- last_atexit_chain_slot = -1;
- errno = ENOMEM;
- return (-1);
- }
- }
- atexit_chain[last_atexit_chain_slot] = func;
- return (0);
-}
-
-extern void _cleanup (void);
-extern void _exit (int) __attribute__ ((__noreturn__));
-
-void
-exit (int status)
-{
- if (atexit_chain)
- {
- for ( ; last_atexit_chain_slot-- >= 0; )
- {
- (*atexit_chain[last_atexit_chain_slot + 1]) ();
- atexit_chain[last_atexit_chain_slot + 1] = 0;
- }
- free (atexit_chain);
- atexit_chain = 0;
- }
-#ifdef EXIT_BODY
- EXIT_BODY;
-#else
- _cleanup ();
-#endif
- _exit (status);
-}
-
-#else /* ON_EXIT */
-
-/* Simple; we just need a wrapper for ON_EXIT. */
-int
-atexit (func_ptr func)
-{
- return ON_EXIT (func);
-}
-
-#endif /* ON_EXIT */
-#endif /* NEED_ATEXIT */
-#endif /* L_exit */
diff --git a/contrib/gcc/libgcc2.h b/contrib/gcc/libgcc2.h
index f2dcb7c93938..0bd6d2eac6d1 100644
--- a/contrib/gcc/libgcc2.h
+++ b/contrib/gcc/libgcc2.h
@@ -35,19 +35,6 @@ extern void __clear_cache (char *, char *);
extern void __eprintf (const char *, const char *, unsigned int, const char *)
__attribute__ ((__noreturn__));
-struct bb;
-extern void __bb_exit_func (void);
-extern void __bb_init_func (struct bb *);
-extern void __bb_fork_func (void);
-
-#if LONG_TYPE_SIZE == GCOV_TYPE_SIZE
-typedef long gcov_type;
-#else
-typedef long long gcov_type;
-#endif
-
-extern gcov_type *__bb_find_arc_counters (void);
-
struct exception_descriptor;
extern short int __get_eh_table_language (struct exception_descriptor *);
extern short int __get_eh_table_version (struct exception_descriptor *);
@@ -82,15 +69,15 @@ typedef unsigned int UQItype __attribute__ ((mode (QI)));
typedef int HItype __attribute__ ((mode (HI)));
typedef unsigned int UHItype __attribute__ ((mode (HI)));
#if MIN_UNITS_PER_WORD > 1
-/* These typedefs are usually forbidden on dsp's with UNITS_PER_WORD 1 */
+/* These typedefs are usually forbidden on dsp's with UNITS_PER_WORD 1. */
typedef int SItype __attribute__ ((mode (SI)));
typedef unsigned int USItype __attribute__ ((mode (SI)));
#if LONG_LONG_TYPE_SIZE > 32
-/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 2 */
+/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 2. */
typedef int DItype __attribute__ ((mode (DI)));
typedef unsigned int UDItype __attribute__ ((mode (DI)));
#if MIN_UNITS_PER_WORD > 4
-/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 4 */
+/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 4. */
typedef int TItype __attribute__ ((mode (TI)));
typedef unsigned int UTItype __attribute__ ((mode (TI)));
#endif
@@ -203,7 +190,6 @@ typedef int word_type __attribute__ ((mode (__word__)));
#define __lshrdi3 __NDW(lshr,3)
#define __ashldi3 __NDW(ashl,3)
#define __ashrdi3 __NDW(ashr,3)
-#define __ffsdi2 __NDW(ffs,2)
#define __cmpdi2 __NDW(cmp,2)
#define __ucmpdi2 __NDW(ucmp,2)
#define __udivmoddi4 __NDW(udivmod,4)
@@ -224,6 +210,17 @@ typedef int word_type __attribute__ ((mode (__word__)));
#define __fixunsdfSI __NW(fixunsdf,)
#define __fixunssfSI __NW(fixunssf,)
+#define __ffsSI2 __NW(ffs,2)
+#define __clzSI2 __NW(clz,2)
+#define __ctzSI2 __NW(ctz,2)
+#define __popcountSI2 __NW(popcount,2)
+#define __paritySI2 __NW(parity,2)
+#define __ffsDI2 __NDW(ffs,2)
+#define __clzDI2 __NDW(clz,2)
+#define __ctzDI2 __NDW(ctz,2)
+#define __popcountDI2 __NDW(popcount,2)
+#define __parityDI2 __NDW(parity,2)
+
extern DWtype __muldi3 (DWtype, DWtype);
extern DWtype __divdi3 (DWtype, DWtype);
extern UDWtype __udivdi3 (UDWtype, UDWtype);
@@ -244,7 +241,6 @@ extern DWtype __negdi2 (DWtype);
extern DWtype __lshrdi3 (DWtype, word_type);
extern DWtype __ashldi3 (DWtype, word_type);
extern DWtype __ashrdi3 (DWtype, word_type);
-extern DWtype __ffsdi2 (DWtype);
/* __udiv_w_sdiv is static inline when building other libgcc2 portions. */
#if (!defined(L_udivdi3) && !defined(L_divdi3) && \
diff --git a/contrib/gcc/libgcov.c b/contrib/gcc/libgcov.c
new file mode 100644
index 000000000000..d5c97a2854d6
--- /dev/null
+++ b/contrib/gcc/libgcov.c
@@ -0,0 +1,583 @@
+/* Routines required for instrumenting a program. */
+/* Compile this one with gcc. */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003 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 2, or (at your option) any later
+version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* It is incorrect to include config.h here, because this file is being
+ compiled for the target, and hence definitions concerning only the host
+ do not apply. */
+
+#include "tconfig.h"
+#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
+
+#if defined(inhibit_libc)
+#define IN_LIBGCOV (-1)
+#else
+#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
+#include <stdio.h>
+#define IN_LIBGCOV 1
+#if defined(L_gcov)
+#define GCOV_LINKAGE /* nothing */
+#endif
+#endif
+#include "gcov-io.h"
+
+#if defined(inhibit_libc)
+/* If libc and its header files are not available, provide dummy functions. */
+
+#ifdef L_gcov
+void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
+void __gcov_flush (void) {}
+#endif
+
+#ifdef L_gcov_merge_add
+void __gcov_merge_add (gcov_type *counters __attribute__ ((unused)),
+ unsigned n_counters __attribute__ ((unused))) {}
+#endif
+
+#ifdef L_gcov_merge_single
+void __gcov_merge_single (gcov_type *counters __attribute__ ((unused)),
+ unsigned n_counters __attribute__ ((unused))) {}
+#endif
+
+#ifdef L_gcov_merge_delta
+void __gcov_merge_delta (gcov_type *counters __attribute__ ((unused)),
+ unsigned n_counters __attribute__ ((unused))) {}
+#endif
+
+#else
+
+#include <string.h>
+#if GCOV_LOCKED
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#endif
+
+#ifdef L_gcov
+#include "gcov-io.c"
+
+/* Chain of per-object gcov structures. */
+static struct gcov_info *gcov_list;
+
+/* A program checksum allows us to distinguish program data for an
+ object file included in multiple programs. */
+static gcov_unsigned_t gcov_crc32;
+
+static int
+gcov_version (struct gcov_info *ptr, gcov_unsigned_t version)
+{
+ if (version != GCOV_VERSION)
+ {
+ char v[4], e[4];
+
+ GCOV_UNSIGNED2STRING (v, version);
+ GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
+
+ fprintf (stderr,
+ "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
+ ptr->filename, e, v);
+ return 0;
+ }
+ return 1;
+}
+
+/* Dump the coverage counts. We merge with existing counts when
+ possible, to avoid growing the .da files ad infinitum. We use this
+ program's checksum to make sure we only accumulate whole program
+ statistics to the correct summary. An object file might be embedded
+ in two separate programs, and we must keep the two program
+ summaries separate. */
+
+static void
+gcov_exit (void)
+{
+ struct gcov_info *gi_ptr;
+ struct gcov_summary this_program;
+ struct gcov_summary all;
+ struct gcov_ctr_summary *cs_ptr;
+ const struct gcov_ctr_info *ci_ptr;
+ unsigned t_ix;
+ gcov_unsigned_t c_num;
+
+ memset (&all, 0, sizeof (all));
+ /* Find the totals for this execution. */
+ memset (&this_program, 0, sizeof (this_program));
+ for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
+ {
+ ci_ptr = gi_ptr->counts;
+ for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
+ {
+ if (!((1 << t_ix) & gi_ptr->ctr_mask))
+ continue;
+
+ cs_ptr = &this_program.ctrs[t_ix];
+ cs_ptr->num += ci_ptr->num;
+ for (c_num = 0; c_num < ci_ptr->num; c_num++)
+ {
+ cs_ptr->sum_all += ci_ptr->values[c_num];
+ if (cs_ptr->run_max < ci_ptr->values[c_num])
+ cs_ptr->run_max = ci_ptr->values[c_num];
+ }
+ ci_ptr++;
+ }
+ }
+
+ /* Now merge each file. */
+ for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
+ {
+ struct gcov_summary this_object;
+ struct gcov_summary object, program;
+ gcov_type *values[GCOV_COUNTERS];
+ const struct gcov_fn_info *fi_ptr;
+ unsigned fi_stride;
+ unsigned c_ix, f_ix, n_counts;
+ struct gcov_ctr_summary *cs_obj, *cs_tobj, *cs_prg, *cs_tprg, *cs_all;
+ int error = 0;
+ gcov_unsigned_t tag, length;
+ gcov_position_t summary_pos = 0;
+
+ memset (&this_object, 0, sizeof (this_object));
+ memset (&object, 0, sizeof (object));
+
+ /* Totals for this object file. */
+ ci_ptr = gi_ptr->counts;
+ for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
+ {
+ if (!((1 << t_ix) & gi_ptr->ctr_mask))
+ continue;
+
+ cs_ptr = &this_object.ctrs[t_ix];
+ cs_ptr->num += ci_ptr->num;
+ for (c_num = 0; c_num < ci_ptr->num; c_num++)
+ {
+ cs_ptr->sum_all += ci_ptr->values[c_num];
+ if (cs_ptr->run_max < ci_ptr->values[c_num])
+ cs_ptr->run_max = ci_ptr->values[c_num];
+ }
+
+ ci_ptr++;
+ }
+
+ c_ix = 0;
+ for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
+ if ((1 << t_ix) & gi_ptr->ctr_mask)
+ {
+ values[c_ix] = gi_ptr->counts[c_ix].values;
+ c_ix++;
+ }
+
+ /* Calculate the function_info stride. This depends on the
+ number of counter types being measured. */
+ fi_stride = sizeof (struct gcov_fn_info) + c_ix * sizeof (unsigned);
+ if (__alignof__ (struct gcov_fn_info) > sizeof (unsigned))
+ {
+ fi_stride += __alignof__ (struct gcov_fn_info) - 1;
+ fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1);
+ }
+
+ if (!gcov_open (gi_ptr->filename))
+ {
+ fprintf (stderr, "profiling:%s:Cannot open\n", gi_ptr->filename);
+ continue;
+ }
+
+ tag = gcov_read_unsigned ();
+ if (tag)
+ {
+ /* Merge data from file. */
+ if (tag != GCOV_DATA_MAGIC)
+ {
+ fprintf (stderr, "profiling:%s:Not a gcov data file\n",
+ gi_ptr->filename);
+ read_fatal:;
+ gcov_close ();
+ continue;
+ }
+ length = gcov_read_unsigned ();
+ if (!gcov_version (gi_ptr, length))
+ goto read_fatal;
+
+ length = gcov_read_unsigned ();
+ if (length != gi_ptr->stamp)
+ {
+ /* Read from a different compilation. Overwrite the
+ file. */
+ gcov_truncate ();
+ goto rewrite;
+ }
+
+ /* Merge execution counts for each function. */
+ for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
+ {
+ fi_ptr = (const struct gcov_fn_info *)
+ ((const char *) gi_ptr->functions + f_ix * fi_stride);
+ tag = gcov_read_unsigned ();
+ length = gcov_read_unsigned ();
+
+ /* Check function. */
+ if (tag != GCOV_TAG_FUNCTION
+ || length != GCOV_TAG_FUNCTION_LENGTH
+ || gcov_read_unsigned () != fi_ptr->ident
+ || gcov_read_unsigned () != fi_ptr->checksum)
+ {
+ read_mismatch:;
+ fprintf (stderr, "profiling:%s:Merge mismatch for %s\n",
+ gi_ptr->filename,
+ f_ix + 1 ? "function" : "summaries");
+ goto read_fatal;
+ }
+
+ c_ix = 0;
+ for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
+ {
+ gcov_merge_fn merge;
+
+ if (!((1 << t_ix) & gi_ptr->ctr_mask))
+ continue;
+
+ n_counts = fi_ptr->n_ctrs[c_ix];
+ merge = gi_ptr->counts[c_ix].merge;
+
+ tag = gcov_read_unsigned ();
+ length = gcov_read_unsigned ();
+ if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
+ || length != GCOV_TAG_COUNTER_LENGTH (n_counts))
+ goto read_mismatch;
+ (*merge) (values[c_ix], n_counts);
+ values[c_ix] += n_counts;
+ c_ix++;
+ }
+ if ((error = gcov_is_error ()))
+ goto read_error;
+ }
+
+ f_ix = ~0u;
+ /* Check program & object summary */
+ while (1)
+ {
+ gcov_position_t base = gcov_position ();
+ int is_program;
+
+ tag = gcov_read_unsigned ();
+ if (!tag)
+ break;
+ length = gcov_read_unsigned ();
+ is_program = tag == GCOV_TAG_PROGRAM_SUMMARY;
+ if (length != GCOV_TAG_SUMMARY_LENGTH
+ || (!is_program && tag != GCOV_TAG_OBJECT_SUMMARY))
+ goto read_mismatch;
+ gcov_read_summary (is_program ? &program : &object);
+ if ((error = gcov_is_error ()))
+ goto read_error;
+ if (is_program && program.checksum == gcov_crc32)
+ {
+ summary_pos = base;
+ goto rewrite;
+ }
+ }
+ }
+
+ if (!gcov_is_eof ())
+ {
+ read_error:;
+ fprintf (stderr, error < 0 ? "profiling:%s:Overflow merging\n"
+ : "profiling:%s:Error merging\n", gi_ptr->filename);
+ goto read_fatal;
+ }
+ rewrite:;
+ gcov_rewrite ();
+ if (!summary_pos)
+ memset (&program, 0, sizeof (program));
+
+ /* Merge the summaries. */
+ f_ix = ~0u;
+ for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
+ {
+ cs_obj = &object.ctrs[t_ix];
+ cs_tobj = &this_object.ctrs[t_ix];
+ cs_prg = &program.ctrs[t_ix];
+ cs_tprg = &this_program.ctrs[t_ix];
+ cs_all = &all.ctrs[t_ix];
+
+ if ((1 << t_ix) & gi_ptr->ctr_mask)
+ {
+ if (!cs_obj->runs++)
+ cs_obj->num = cs_tobj->num;
+ else if (cs_obj->num != cs_tobj->num)
+ goto read_mismatch;
+ cs_obj->sum_all += cs_tobj->sum_all;
+ if (cs_obj->run_max < cs_tobj->run_max)
+ cs_obj->run_max = cs_tobj->run_max;
+ cs_obj->sum_max += cs_tobj->run_max;
+
+ if (!cs_prg->runs++)
+ cs_prg->num = cs_tprg->num;
+ else if (cs_prg->num != cs_tprg->num)
+ goto read_mismatch;
+ cs_prg->sum_all += cs_tprg->sum_all;
+ if (cs_prg->run_max < cs_tprg->run_max)
+ cs_prg->run_max = cs_tprg->run_max;
+ cs_prg->sum_max += cs_tprg->run_max;
+ }
+ else if (cs_obj->num || cs_prg->num)
+ goto read_mismatch;
+
+ if (!cs_all->runs && cs_prg->runs)
+ memcpy (cs_all, cs_prg, sizeof (*cs_all));
+ else if (!all.checksum
+ && (!GCOV_LOCKED || cs_all->runs == cs_prg->runs)
+ && memcmp (cs_all, cs_prg, sizeof (*cs_all)))
+ {
+ fprintf (stderr, "profiling:%s:Invocation mismatch - some data files may have been removed%s",
+ gi_ptr->filename, GCOV_LOCKED
+ ? "" : " or concurrent update without locking support");
+ all.checksum = ~0u;
+ }
+ }
+
+ c_ix = 0;
+ for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
+ if ((1 << t_ix) & gi_ptr->ctr_mask)
+ {
+ values[c_ix] = gi_ptr->counts[c_ix].values;
+ c_ix++;
+ }
+
+ program.checksum = gcov_crc32;
+
+ /* Write out the data. */
+ gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
+ gcov_write_unsigned (gi_ptr->stamp);
+
+ /* Write execution counts for each function. */
+ for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
+ {
+ fi_ptr = (const struct gcov_fn_info *)
+ ((const char *) gi_ptr->functions + f_ix * fi_stride);
+
+ /* Announce function. */
+ gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
+ gcov_write_unsigned (fi_ptr->ident);
+ gcov_write_unsigned (fi_ptr->checksum);
+
+ c_ix = 0;
+ for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
+ {
+ gcov_type *c_ptr;
+
+ if (!((1 << t_ix) & gi_ptr->ctr_mask))
+ continue;
+
+ n_counts = fi_ptr->n_ctrs[c_ix];
+
+ gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
+ GCOV_TAG_COUNTER_LENGTH (n_counts));
+ c_ptr = values[c_ix];
+ while (n_counts--)
+ gcov_write_counter (*c_ptr++);
+
+ values[c_ix] = c_ptr;
+ c_ix++;
+ }
+ }
+
+ /* Object file summary. */
+ gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object);
+
+ /* Generate whole program statistics. */
+ gcov_seek (summary_pos);
+ gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program);
+ if ((error = gcov_close ()))
+ fprintf (stderr, error < 0 ?
+ "profiling:%s:Overflow writing\n" :
+ "profiling:%s:Error writing\n",
+ gi_ptr->filename);
+ }
+}
+
+/* Add a new object file onto the bb chain. Invoked automatically
+ when running an object file's global ctors. */
+
+void
+__gcov_init (struct gcov_info *info)
+{
+ if (!info->version)
+ return;
+ if (gcov_version (info, info->version))
+ {
+ const char *ptr = info->filename;
+ gcov_unsigned_t crc32 = gcov_crc32;
+
+ do
+ {
+ unsigned ix;
+ gcov_unsigned_t value = *ptr << 24;
+
+ for (ix = 8; ix--; value <<= 1)
+ {
+ gcov_unsigned_t feedback;
+
+ feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
+ crc32 <<= 1;
+ crc32 ^= feedback;
+ }
+ }
+ while (*ptr++);
+
+ gcov_crc32 = crc32;
+
+ if (!gcov_list)
+ atexit (gcov_exit);
+
+ info->next = gcov_list;
+ gcov_list = info;
+ }
+ info->version = 0;
+}
+
+/* Called before fork or exec - write out profile information gathered so
+ far and reset it to zero. This avoids duplication or loss of the
+ profile information gathered so far. */
+
+void
+__gcov_flush (void)
+{
+ const struct gcov_info *gi_ptr;
+
+ gcov_exit ();
+ for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
+ {
+ unsigned t_ix;
+ const struct gcov_ctr_info *ci_ptr;
+
+ for (t_ix = 0, ci_ptr = gi_ptr->counts; t_ix != GCOV_COUNTERS; t_ix++)
+ if ((1 << t_ix) & gi_ptr->ctr_mask)
+ {
+ memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
+ ci_ptr++;
+ }
+ }
+}
+
+#endif /* L_gcov */
+
+#ifdef L_gcov_merge_add
+/* The profile merging function that just adds the counters. It is given
+ an array COUNTERS of N_COUNTERS old counters and it reads the same number
+ of counters from the gcov file. */
+void
+__gcov_merge_add (gcov_type *counters, unsigned n_counters)
+{
+ for (; n_counters; counters++, n_counters--)
+ *counters += gcov_read_counter ();
+}
+#endif /* L_gcov_merge_add */
+
+#ifdef L_gcov_merge_single
+/* The profile merging function for choosing the most common value.
+ It is given an array COUNTERS of N_COUNTERS old counters and it
+ reads the same number of counters from the gcov file. The counters
+ are split into 3-tuples where the members of the tuple have
+ meanings:
+
+ -- the stored candidate on the most common value of the measured entity
+ -- counter
+ -- total number of evaluations of the value */
+void
+__gcov_merge_single (gcov_type *counters, unsigned n_counters)
+{
+ unsigned i, n_measures;
+ gcov_type value, counter, all;
+
+ GCOV_CHECK (!(n_counters % 3));
+ n_measures = n_counters / 3;
+ for (i = 0; i < n_measures; i++, counters += 3)
+ {
+ value = gcov_read_counter ();
+ counter = gcov_read_counter ();
+ all = gcov_read_counter ();
+
+ if (counters[0] == value)
+ counters[1] += counter;
+ else if (counter > counters[1])
+ {
+ counters[0] = value;
+ counters[1] = counter - counters[1];
+ }
+ else
+ counters[1] -= counter;
+ counters[2] += all;
+ }
+}
+#endif /* L_gcov_merge_single */
+
+#ifdef L_gcov_merge_delta
+/* The profile merging function for choosing the most common
+ difference between two consecutive evaluations of the value. It is
+ given an array COUNTERS of N_COUNTERS old counters and it reads the
+ same number of counters from the gcov file. The counters are split
+ into 4-tuples where the members of the tuple have meanings:
+
+ -- the last value of the measured entity
+ -- the stored candidate on the most common difference
+ -- counter
+ -- total number of evaluations of the value */
+void
+__gcov_merge_delta (gcov_type *counters, unsigned n_counters)
+{
+ unsigned i, n_measures;
+ gcov_type last, value, counter, all;
+
+ GCOV_CHECK (!(n_counters % 4));
+ n_measures = n_counters / 4;
+ for (i = 0; i < n_measures; i++, counters += 4)
+ {
+ last = gcov_read_counter ();
+ value = gcov_read_counter ();
+ counter = gcov_read_counter ();
+ all = gcov_read_counter ();
+
+ if (counters[1] == value)
+ counters[2] += counter;
+ else if (counter > counters[2])
+ {
+ counters[1] = value;
+ counters[2] = counter - counters[2];
+ }
+ else
+ counters[2] -= counter;
+ counters[3] += all;
+ }
+}
+#endif /* L_gcov_merge_delta */
+
+#endif /* inhibit_libc */
diff --git a/contrib/gcc/libiberty.h b/contrib/gcc/libiberty.h
index 53cfc21d78f3..761b2cf060ff 100644
--- a/contrib/gcc/libiberty.h
+++ b/contrib/gcc/libiberty.h
@@ -85,6 +85,10 @@ extern char *basename ();
extern const char *lbasename PARAMS ((const char *));
+/* A well-defined realpath () that is always compiled in. */
+
+extern char *lrealpath PARAMS ((const char *));
+
/* Concatenate an arbitrary number of strings. You must pass NULL as
the last argument of this function, to terminate the list of
strings. Allocates memory using xmalloc. */
@@ -250,12 +254,12 @@ extern double physmem_available PARAMS ((void));
#define _hex_array_size 256
#define _hex_bad 99
-extern const char _hex_value[_hex_array_size];
+extern const unsigned char _hex_value[_hex_array_size];
extern void hex_init PARAMS ((void));
#define hex_p(c) (hex_value (c) != _hex_bad)
/* If you change this, note well: Some code relies on side effects in
the argument being performed exactly once. */
-#define hex_value(c) (_hex_value[(unsigned char) (c)])
+#define hex_value(c) ((unsigned int) _hex_value[(unsigned char) (c)])
/* Definitions used by the pexecute routine. */
diff --git a/contrib/gcc/line-map.c b/contrib/gcc/line-map.c
index a0f3ee50bc0f..521c4e5c843e 100644
--- a/contrib/gcc/line-map.c
+++ b/contrib/gcc/line-map.c
@@ -1,5 +1,5 @@
/* Map logical line numbers to (source file, line number) pairs.
- Copyright (C) 2001
+ Copyright (C) 2001, 2003
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@@ -25,14 +25,12 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "line-map.h"
#include "intl.h"
-static void trace_include
- PARAMS ((const struct line_maps *, const struct line_map *));
+static void trace_include (const struct line_maps *, const struct line_map *);
/* Initialize a line map set. */
void
-init_line_maps (set)
- struct line_maps *set;
+linemap_init (struct line_maps *set)
{
set->maps = 0;
set->allocated = 0;
@@ -45,8 +43,7 @@ init_line_maps (set)
/* Free a line map set. */
void
-free_line_maps (set)
- struct line_maps *set;
+linemap_free (struct line_maps *set)
{
if (set->maps)
{
@@ -64,20 +61,22 @@ free_line_maps (set)
}
/* Add a mapping of logical source line to physical source file and
- line number. Ther text pointed to by TO_FILE must have a lifetime
- at least as long as the final call to lookup_line ().
+ line number.
+
+ The text pointed to by TO_FILE must have a lifetime
+ at least as long as the final call to lookup_line (). An empty
+ TO_FILE means standard input. If reason is LC_LEAVE, and
+ TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
+ natural values considering the file we are returning to.
FROM_LINE should be monotonic increasing across calls to this
- function. */
+ function. A call to this function can relocate the previous set of
+ maps, so any stored line_map pointers should not be used. */
const struct line_map *
-add_line_map (set, reason, sysp, from_line, to_file, to_line)
- struct line_maps *set;
- enum lc_reason reason;
- unsigned int sysp;
- unsigned int from_line;
- const char *to_file;
- unsigned int to_line;
+linemap_add (struct line_maps *set, enum lc_reason reason,
+ unsigned int sysp, source_location from_line,
+ const char *to_file, unsigned int to_line)
{
struct line_map *map;
@@ -87,12 +86,14 @@ add_line_map (set, reason, sysp, from_line, to_file, to_line)
if (set->used == set->allocated)
{
set->allocated = 2 * set->allocated + 256;
- set->maps = (struct line_map *)
- xrealloc (set->maps, set->allocated * sizeof (struct line_map));
+ set->maps = xrealloc (set->maps, set->allocated * sizeof (struct line_map));
}
map = &set->maps[set->used++];
+ if (to_file && *to_file == '\0')
+ to_file = "<stdin>";
+
/* If we don't keep our line maps consistent, we can easily
segfault. Don't rely on the client to do it for us. */
if (set->depth == 0)
@@ -104,9 +105,15 @@ add_line_map (set, reason, sysp, from_line, to_file, to_line)
if (MAIN_FILE_P (map - 1))
{
+ if (to_file == NULL)
+ {
+ set->depth--;
+ set->used--;
+ return NULL;
+ }
error = true;
- reason = LC_RENAME;
- from = map - 1;
+ reason = LC_RENAME;
+ from = map - 1;
}
else
{
@@ -137,8 +144,8 @@ add_line_map (set, reason, sysp, from_line, to_file, to_line)
if (reason == LC_ENTER)
{
+ map->included_from = set->depth == 0 ? -1 : (int) (set->used - 2);
set->depth++;
- map->included_from = set->used - 2;
if (set->trace_includes)
trace_include (set, map);
}
@@ -159,9 +166,7 @@ add_line_map (set, reason, sysp, from_line, to_file, to_line)
the list is sorted and we can use a binary search. */
const struct line_map *
-lookup_line (set, line)
- struct line_maps *set;
- unsigned int line;
+linemap_lookup (struct line_maps *set, source_location line)
{
unsigned int md, mn = 0, mx = set->used;
@@ -185,9 +190,8 @@ lookup_line (set, line)
the most recently listed stack is the same as the current one. */
void
-print_containing_files (set, map)
- struct line_maps *set;
- const struct line_map *map;
+linemap_print_containing_files (struct line_maps *set,
+ const struct line_map *map)
{
if (MAIN_FILE_P (map) || set->last_listed == map->included_from)
return;
@@ -223,9 +227,7 @@ print_containing_files (set, map)
/* Print an include trace, for e.g. the -H option of the preprocessor. */
static void
-trace_include (set, map)
- const struct line_maps *set;
- const struct line_map *map;
+trace_include (const struct line_maps *set, const struct line_map *map)
{
unsigned int i = set->depth;
diff --git a/contrib/gcc/line-map.h b/contrib/gcc/line-map.h
index 60201887f491..c57f51a66245 100644
--- a/contrib/gcc/line-map.h
+++ b/contrib/gcc/line-map.h
@@ -1,5 +1,5 @@
/* Map logical line numbers to (source file, line number) pairs.
- Copyright (C) 2001
+ Copyright (C) 2001, 2003
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@@ -30,6 +30,12 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
(e.g. a #line directive in C). */
enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME};
+/* A logical line number, i,e, an "index" into a line_map. */
+/* Long-term, we want to use this to replace struct location_s (in input.h),
+ and effectively typedef source_location location_t. */
+typedef unsigned int source_location;
+typedef source_location fileline; /* deprecated name */
+
/* The logical line FROM_LINE maps to physical source file TO_FILE at
line TO_LINE, and subsequently one-to-one until the next line_map
structure in the set. INCLUDED_FROM is an index into the set that
@@ -42,7 +48,7 @@ struct line_map
{
const char *to_file;
unsigned int to_line;
- unsigned int from_line;
+ source_location from_line;
int included_from;
ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
unsigned char sysp;
@@ -68,36 +74,37 @@ struct line_maps
};
/* Initialize a line map set. */
-extern void init_line_maps
- PARAMS ((struct line_maps *));
+extern void linemap_init (struct line_maps *);
/* Free a line map set. */
-extern void free_line_maps
- PARAMS ((struct line_maps *));
+extern void linemap_free (struct line_maps *);
/* Add a mapping of logical source line to physical source file and
- line number. The text pointed to by TO_FILE must have a lifetime
- at least as long as the line maps. If reason is LC_LEAVE, and
+ line number.
+
+ The text pointed to by TO_FILE must have a lifetime
+ at least as long as the final call to lookup_line (). An empty
+ TO_FILE means standard input. If reason is LC_LEAVE, and
TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
natural values considering the file we are returning to.
FROM_LINE should be monotonic increasing across calls to this
function. A call to this function can relocate the previous set of
maps, so any stored line_map pointers should not be used. */
-extern const struct line_map *add_line_map
- PARAMS ((struct line_maps *, enum lc_reason, unsigned int sysp,
- unsigned int from_line, const char *to_file, unsigned int to_line));
+extern const struct line_map *linemap_add
+ (struct line_maps *, enum lc_reason, unsigned int sysp,
+ source_location from_line, const char *to_file, unsigned int to_line);
/* Given a logical line, returns the map from which the corresponding
(source file, line) pair can be deduced. */
-extern const struct line_map *lookup_line
- PARAMS ((struct line_maps *, unsigned int));
+extern const struct line_map *linemap_lookup
+ (struct line_maps *, source_location);
/* Print the file names and line numbers of the #include commands
which led to the map MAP, if any, to stderr. Nothing is output if
the most recently listed stack is the same as the current one. */
-extern void print_containing_files
- PARAMS ((struct line_maps *, const struct line_map *));
+extern void linemap_print_containing_files (struct line_maps *,
+ const struct line_map *);
/* Converts a map and logical line to source line. */
#define SOURCE_LINE(MAP, LINE) ((LINE) + (MAP)->to_line - (MAP)->from_line)
diff --git a/contrib/gcc/lists.c b/contrib/gcc/lists.c
index 58d90d37756c..1e4a57a160fd 100644
--- a/contrib/gcc/lists.c
+++ b/contrib/gcc/lists.c
@@ -1,6 +1,6 @@
-/* List management for the GNU C-Compiler expander.
+/* List management for the GCC expander.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999 Free Software Foundation, Inc.
+ 1999, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,11 +21,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "ggc.h"
-static void free_list PARAMS ((rtx *, rtx *));
+static void free_list (rtx *, rtx *);
/* Functions for maintaining cache-able lists of EXPR_LIST and INSN_LISTs. */
@@ -41,8 +43,7 @@ static GTY ((deletable (""))) rtx unused_expr_list;
nodes of one type only. This is only called by free_EXPR_LIST_list
and free_INSN_LIST_list. */
static void
-free_list (listp, unused_listp)
- rtx *listp, *unused_listp;
+free_list (rtx *listp, rtx *unused_listp)
{
rtx link, prev_link;
@@ -64,8 +65,7 @@ free_list (listp, unused_listp)
node available, we'll use it, otherwise a call to gen_rtx_INSN_LIST
is made. */
rtx
-alloc_INSN_LIST (val, next)
- rtx val, next;
+alloc_INSN_LIST (rtx val, rtx next)
{
rtx r;
@@ -87,9 +87,7 @@ alloc_INSN_LIST (val, next)
node available, we'll use it, otherwise a call to gen_rtx_EXPR_LIST
is made. */
rtx
-alloc_EXPR_LIST (kind, val, next)
- int kind;
- rtx val, next;
+alloc_EXPR_LIST (int kind, rtx val, rtx next)
{
rtx r;
@@ -109,8 +107,7 @@ alloc_EXPR_LIST (kind, val, next)
/* This function will free up an entire list of EXPR_LIST nodes. */
void
-free_EXPR_LIST_list (listp)
- rtx *listp;
+free_EXPR_LIST_list (rtx *listp)
{
if (*listp == 0)
return;
@@ -119,8 +116,7 @@ free_EXPR_LIST_list (listp)
/* This function will free up an entire list of INSN_LIST nodes. */
void
-free_INSN_LIST_list (listp)
- rtx *listp;
+free_INSN_LIST_list (rtx *listp)
{
if (*listp == 0)
return;
@@ -129,8 +125,7 @@ free_INSN_LIST_list (listp)
/* This function will free up an individual EXPR_LIST node. */
void
-free_EXPR_LIST_node (ptr)
- rtx ptr;
+free_EXPR_LIST_node (rtx ptr)
{
XEXP (ptr, 1) = unused_expr_list;
unused_expr_list = ptr;
@@ -138,8 +133,7 @@ free_EXPR_LIST_node (ptr)
/* This function will free up an individual INSN_LIST node. */
void
-free_INSN_LIST_node (ptr)
- rtx ptr;
+free_INSN_LIST_node (rtx ptr)
{
XEXP (ptr, 1) = unused_insn_list;
unused_insn_list = ptr;
diff --git a/contrib/gcc/local-alloc.c b/contrib/gcc/local-alloc.c
index c2d6c0c610b4..61ff7fbc6b2b 100644
--- a/contrib/gcc/local-alloc.c
+++ b/contrib/gcc/local-alloc.c
@@ -1,6 +1,6 @@
/* Allocate registers within a basic block, for GNU compiler.
Copyright (C) 1987, 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -61,6 +61,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "hard-reg-set.h"
#include "rtl.h"
#include "tm_p.h"
@@ -106,7 +108,7 @@ struct qty
/* Number of words needed to hold the data in given quantity.
This depends on its machine mode. It is used for these purposes:
- 1. It is used in computing the relative importances of qtys,
+ 1. It is used in computing the relative importance of qtys,
which determines the order in which we look for regs for them.
2. It is used in rules that prevent tying several registers of
different sizes in a way that is geometrically impossible
@@ -269,43 +271,40 @@ static struct equivalence *reg_equiv;
/* Nonzero if we recorded an equivalence for a LABEL_REF. */
static int recorded_label_ref;
-static void alloc_qty PARAMS ((int, enum machine_mode, int, int));
-static void validate_equiv_mem_from_store PARAMS ((rtx, rtx, void *));
-static int validate_equiv_mem PARAMS ((rtx, rtx, rtx));
-static int equiv_init_varies_p PARAMS ((rtx));
-static int equiv_init_movable_p PARAMS ((rtx, int));
-static int contains_replace_regs PARAMS ((rtx));
-static int memref_referenced_p PARAMS ((rtx, rtx));
-static int memref_used_between_p PARAMS ((rtx, rtx, rtx));
-static void update_equiv_regs PARAMS ((void));
-static void no_equiv PARAMS ((rtx, rtx, void *));
-static void block_alloc PARAMS ((int));
-static int qty_sugg_compare PARAMS ((int, int));
-static int qty_sugg_compare_1 PARAMS ((const PTR, const PTR));
-static int qty_compare PARAMS ((int, int));
-static int qty_compare_1 PARAMS ((const PTR, const PTR));
-static int combine_regs PARAMS ((rtx, rtx, int, int, rtx, int));
-static int reg_meets_class_p PARAMS ((int, enum reg_class));
-static void update_qty_class PARAMS ((int, int));
-static void reg_is_set PARAMS ((rtx, rtx, void *));
-static void reg_is_born PARAMS ((rtx, int));
-static void wipe_dead_reg PARAMS ((rtx, int));
-static int find_free_reg PARAMS ((enum reg_class, enum machine_mode,
- int, int, int, int, int));
-static void mark_life PARAMS ((int, enum machine_mode, int));
-static void post_mark_life PARAMS ((int, enum machine_mode, int, int, int));
-static int no_conflict_p PARAMS ((rtx, rtx, rtx));
-static int requires_inout PARAMS ((const char *));
+static void alloc_qty (int, enum machine_mode, int, int);
+static void validate_equiv_mem_from_store (rtx, rtx, void *);
+static int validate_equiv_mem (rtx, rtx, rtx);
+static int equiv_init_varies_p (rtx);
+static int equiv_init_movable_p (rtx, int);
+static int contains_replace_regs (rtx);
+static int memref_referenced_p (rtx, rtx);
+static int memref_used_between_p (rtx, rtx, rtx);
+static void update_equiv_regs (void);
+static void no_equiv (rtx, rtx, void *);
+static void block_alloc (int);
+static int qty_sugg_compare (int, int);
+static int qty_sugg_compare_1 (const void *, const void *);
+static int qty_compare (int, int);
+static int qty_compare_1 (const void *, const void *);
+static int combine_regs (rtx, rtx, int, int, rtx, int);
+static int reg_meets_class_p (int, enum reg_class);
+static void update_qty_class (int, int);
+static void reg_is_set (rtx, rtx, void *);
+static void reg_is_born (rtx, int);
+static void wipe_dead_reg (rtx, int);
+static int find_free_reg (enum reg_class, enum machine_mode, int, int, int,
+ int, int);
+static void mark_life (int, enum machine_mode, int);
+static void post_mark_life (int, enum machine_mode, int, int, int);
+static int no_conflict_p (rtx, rtx, rtx);
+static int requires_inout (const char *);
/* Allocate a new quantity (new within current basic block)
for register number REGNO which is born at index BIRTH
within the block. MODE and SIZE are info on reg REGNO. */
static void
-alloc_qty (regno, mode, size, birth)
- int regno;
- enum machine_mode mode;
- int size, birth;
+alloc_qty (int regno, enum machine_mode mode, int size, int birth)
{
int qtyno = next_qty++;
@@ -327,7 +326,7 @@ alloc_qty (regno, mode, size, birth)
/* Main entry point of this file. */
int
-local_alloc ()
+local_alloc (void)
{
int i;
int max_qty;
@@ -357,16 +356,15 @@ local_alloc ()
See the declarations of these variables, above,
for what they mean. */
- qty = (struct qty *) xmalloc (max_qty * sizeof (struct qty));
- qty_phys_copy_sugg
- = (HARD_REG_SET *) xmalloc (max_qty * sizeof (HARD_REG_SET));
- qty_phys_num_copy_sugg = (short *) xmalloc (max_qty * sizeof (short));
- qty_phys_sugg = (HARD_REG_SET *) xmalloc (max_qty * sizeof (HARD_REG_SET));
- qty_phys_num_sugg = (short *) xmalloc (max_qty * sizeof (short));
+ qty = xmalloc (max_qty * sizeof (struct qty));
+ qty_phys_copy_sugg = xmalloc (max_qty * sizeof (HARD_REG_SET));
+ qty_phys_num_copy_sugg = xmalloc (max_qty * sizeof (short));
+ qty_phys_sugg = xmalloc (max_qty * sizeof (HARD_REG_SET));
+ qty_phys_num_sugg = xmalloc (max_qty * sizeof (short));
- reg_qty = (int *) xmalloc (max_regno * sizeof (int));
- reg_offset = (char *) xmalloc (max_regno * sizeof (char));
- reg_next_in_qty = (int *) xmalloc (max_regno * sizeof (int));
+ reg_qty = xmalloc (max_regno * sizeof (int));
+ reg_offset = xmalloc (max_regno * sizeof (char));
+ reg_next_in_qty = xmalloc (max_regno * sizeof (int));
/* Determine which pseudo-registers can be allocated by local-alloc.
In general, these are the registers used only in a single block and
@@ -410,7 +408,7 @@ local_alloc ()
else
{
#define CLEAR(vector) \
- memset ((char *) (vector), 0, (sizeof (*(vector))) * next_qty);
+ memset ((vector), 0, (sizeof (*(vector))) * next_qty);
CLEAR (qty_phys_copy_sugg);
CLEAR (qty_phys_num_copy_sugg);
@@ -447,10 +445,8 @@ static int equiv_mem_modified;
Called via note_stores. */
static void
-validate_equiv_mem_from_store (dest, set, data)
- rtx dest;
- rtx set ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+validate_equiv_mem_from_store (rtx dest, rtx set ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
{
if ((GET_CODE (dest) == REG
&& reg_overlap_mentioned_p (dest, equiv_mem))
@@ -467,10 +463,7 @@ validate_equiv_mem_from_store (dest, set, data)
Return 1 if MEMREF remains valid. */
static int
-validate_equiv_mem (start, reg, memref)
- rtx start;
- rtx reg;
- rtx memref;
+validate_equiv_mem (rtx start, rtx reg, rtx memref)
{
rtx insn;
rtx note;
@@ -516,8 +509,7 @@ validate_equiv_mem (start, reg, memref)
/* Returns zero if X is known to be invariant. */
static int
-equiv_init_varies_p (x)
- rtx x;
+equiv_init_varies_p (rtx x)
{
RTX_CODE code = GET_CODE (x);
int i;
@@ -546,7 +538,7 @@ equiv_init_varies_p (x)
if (MEM_VOLATILE_P (x))
return 1;
- /* FALLTHROUGH */
+ /* Fall through. */
default:
break;
@@ -576,9 +568,7 @@ equiv_init_varies_p (x)
or if they are not candidates for local_alloc and don't vary. */
static int
-equiv_init_movable_p (x, regno)
- rtx x;
- int regno;
+equiv_init_movable_p (rtx x, int regno)
{
int i, j;
const char *fmt;
@@ -613,7 +603,7 @@ equiv_init_movable_p (x, regno)
if (MEM_VOLATILE_P (x))
return 0;
- /* FALLTHROUGH */
+ /* Fall through. */
default:
break;
@@ -640,8 +630,7 @@ equiv_init_movable_p (x, regno)
/* TRUE if X uses any registers for which reg_equiv[REGNO].replace is true. */
static int
-contains_replace_regs (x)
- rtx x;
+contains_replace_regs (rtx x)
{
int i, j;
const char *fmt;
@@ -689,9 +678,7 @@ contains_replace_regs (x)
to MEMREF. */
static int
-memref_referenced_p (memref, x)
- rtx x;
- rtx memref;
+memref_referenced_p (rtx memref, rtx x)
{
int i, j;
const char *fmt;
@@ -760,10 +747,7 @@ memref_referenced_p (memref, x)
that would be affected by a store to MEMREF. */
static int
-memref_used_between_p (memref, start, end)
- rtx memref;
- rtx start;
- rtx end;
+memref_used_between_p (rtx memref, rtx start, rtx end)
{
rtx insn;
@@ -783,8 +767,7 @@ memref_used_between_p (memref, start, end)
go to spill these things to memory. */
int
-function_invariant_p (x)
- rtx x;
+function_invariant_p (rtx x)
{
if (CONSTANT_P (x))
return 1;
@@ -806,7 +789,7 @@ function_invariant_p (x)
completely. */
static void
-update_equiv_regs ()
+update_equiv_regs (void)
{
rtx insn;
basic_block bb;
@@ -814,7 +797,7 @@ update_equiv_regs ()
regset_head cleared_regs;
int clear_regnos = 0;
- reg_equiv = (struct equivalence *) xcalloc (max_regno, sizeof *reg_equiv);
+ reg_equiv = xcalloc (max_regno, sizeof *reg_equiv);
INIT_REG_SET (&cleared_regs);
init_alias_analysis ();
@@ -826,7 +809,9 @@ update_equiv_regs ()
{
loop_depth = bb->loop_depth;
- for (insn = bb->head; insn != NEXT_INSN (bb->end); insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb);
+ insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
{
rtx note;
rtx set;
@@ -920,7 +905,7 @@ update_equiv_regs ()
|| (CLASS_LIKELY_SPILLED_P (reg_preferred_class (regno))
&& GET_CODE (src) == MEM))
{
- /* This might be seting a SUBREG of a pseudo, a pseudo that is
+ /* This might be setting a SUBREG of a pseudo, a pseudo that is
also set somewhere else to a constant. */
note_stores (set, no_equiv, NULL);
continue;
@@ -1033,14 +1018,16 @@ update_equiv_regs ()
registers only used that once. If so, see if we can replace the
reference with the equivalent from. If we can, delete the
initializing reference and this register will go away. If we
- can't replace the reference, and the initialzing reference is
+ can't replace the reference, and the initializing reference is
within the same loop (or in an inner loop), then move the register
initialization just before the use, so that they are in the same
basic block. */
FOR_EACH_BB_REVERSE (bb)
{
loop_depth = bb->loop_depth;
- for (insn = bb->end; insn != PREV_INSN (bb->head); insn = PREV_INSN (insn))
+ for (insn = BB_END (bb);
+ insn != PREV_INSN (BB_HEAD (bb));
+ insn = PREV_INSN (insn))
{
rtx link;
@@ -1134,8 +1121,8 @@ update_equiv_regs ()
REG_N_CALLS_CROSSED (regno) = 0;
REG_LIVE_LENGTH (regno) = 2;
- if (insn == bb->head)
- bb->head = PREV_INSN (insn);
+ if (insn == BB_HEAD (bb))
+ BB_HEAD (bb) = PREV_INSN (insn);
/* Remember to clear REGNO from all basic block's live
info. */
@@ -1177,16 +1164,14 @@ update_equiv_regs ()
}
/* Mark REG as having no known equivalence.
- Some instructions might have been proceessed before and furnished
+ Some instructions might have been processed before and furnished
with REG_EQUIV notes for this register; these notes will have to be
removed.
STORE is the piece of RTL that does the non-constant / conflicting
assignment - a SET, CLOBBER or REG_INC note. It is currently not used,
but needs to be there because this function is called from note_stores. */
static void
-no_equiv (reg, store, data)
- rtx reg, store ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+no_equiv (rtx reg, rtx store ATTRIBUTE_UNUSED, void *data ATTRIBUTE_UNUSED)
{
int regno;
rtx list;
@@ -1210,8 +1195,7 @@ no_equiv (reg, store, data)
Only the pseudos that die but once can be handled. */
static void
-block_alloc (b)
- int b;
+block_alloc (int b)
{
int i, q;
rtx insn;
@@ -1224,21 +1208,20 @@ block_alloc (b)
/* Count the instructions in the basic block. */
- insn = BLOCK_END (b);
+ insn = BB_END (BASIC_BLOCK (b));
while (1)
{
if (GET_CODE (insn) != NOTE)
if (++insn_count > max_uid)
abort ();
- if (insn == BLOCK_HEAD (b))
+ if (insn == BB_HEAD (BASIC_BLOCK (b)))
break;
insn = PREV_INSN (insn);
}
/* +2 to leave room for a post_mark_life at the last insn and for
the birth of a CLOBBER in the first insn. */
- regs_live_at = (HARD_REG_SET *) xcalloc ((2 * insn_count + 2),
- sizeof (HARD_REG_SET));
+ regs_live_at = xcalloc ((2 * insn_count + 2), sizeof (HARD_REG_SET));
/* Initialize table of hardware registers currently live. */
@@ -1248,7 +1231,7 @@ block_alloc (b)
and assigns quantities to registers.
It computes which registers to tie. */
- insn = BLOCK_HEAD (b);
+ insn = BB_HEAD (BASIC_BLOCK (b));
while (1)
{
if (GET_CODE (insn) != NOTE)
@@ -1325,7 +1308,7 @@ block_alloc (b)
must match operand zero. In that case, skip any
operand that doesn't list operand 0 since we know that
the operand always conflicts with operand 0. We
- ignore commutatity in this case to keep things simple. */
+ ignore commutativity in this case to keep things simple. */
if (n_matching_alts == recog_data.n_alternatives
&& 0 == requires_inout (recog_data.constraints[i]))
continue;
@@ -1336,7 +1319,8 @@ block_alloc (b)
There may be more than one register, but we only try one
of them. */
if (recog_data.constraints[i][0] == 'p'
- || EXTRA_ADDRESS_CONSTRAINT (recog_data.constraints[i][0]))
+ || EXTRA_ADDRESS_CONSTRAINT (recog_data.constraints[i][0],
+ recog_data.constraints[i]))
while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT)
r1 = XEXP (r1, 0);
@@ -1479,7 +1463,7 @@ block_alloc (b)
IOR_HARD_REG_SET (regs_live_at[2 * insn_number], regs_live);
IOR_HARD_REG_SET (regs_live_at[2 * insn_number + 1], regs_live);
- if (insn == BLOCK_END (b))
+ if (insn == BB_END (BASIC_BLOCK (b)))
break;
insn = NEXT_INSN (insn);
@@ -1493,7 +1477,7 @@ block_alloc (b)
number of suggested registers they need so we allocate those with
the most restrictive needs first. */
- qty_order = (int *) xmalloc (next_qty * sizeof (int));
+ qty_order = xmalloc (next_qty * sizeof (int));
for (i = 0; i < next_qty; i++)
qty_order[i] = i;
@@ -1690,16 +1674,13 @@ block_alloc (b)
/ (qty[q].death - qty[q].birth)) * (10000 / REG_FREQ_MAX)))
static int
-qty_compare (q1, q2)
- int q1, q2;
+qty_compare (int q1, int q2)
{
return QTY_CMP_PRI (q2) - QTY_CMP_PRI (q1);
}
static int
-qty_compare_1 (q1p, q2p)
- const PTR q1p;
- const PTR q2p;
+qty_compare_1 (const void *q1p, const void *q2p)
{
int q1 = *(const int *) q1p, q2 = *(const int *) q2p;
int tem = QTY_CMP_PRI (q2) - QTY_CMP_PRI (q1);
@@ -1725,8 +1706,7 @@ qty_compare_1 (q1p, q2p)
: qty_phys_num_sugg[q] * FIRST_PSEUDO_REGISTER)
static int
-qty_sugg_compare (q1, q2)
- int q1, q2;
+qty_sugg_compare (int q1, int q2)
{
int tem = QTY_CMP_SUGG (q1) - QTY_CMP_SUGG (q2);
@@ -1737,9 +1717,7 @@ qty_sugg_compare (q1, q2)
}
static int
-qty_sugg_compare_1 (q1p, q2p)
- const PTR q1p;
- const PTR q2p;
+qty_sugg_compare_1 (const void *q1p, const void *q2p)
{
int q1 = *(const int *) q1p, q2 = *(const int *) q2p;
int tem = QTY_CMP_SUGG (q1) - QTY_CMP_SUGG (q2);
@@ -1764,7 +1742,7 @@ qty_sugg_compare_1 (q1p, q2p)
Combining registers means marking them as having the same quantity
and adjusting the offsets within the quantity if either of
- them is a SUBREG).
+ them is a SUBREG.
We don't actually combine a hard reg with a pseudo; instead
we just record the hard reg as the suggestion for the pseudo's quantity.
@@ -1775,19 +1753,15 @@ qty_sugg_compare_1 (q1p, q2p)
there is no REG_DEAD note on INSN. This occurs during the processing
of REG_NO_CONFLICT blocks.
- MAY_SAVE_COPYCOPY is nonzero if this insn is simply copying USEDREG to
+ MAY_SAVE_COPY is nonzero if this insn is simply copying USEDREG to
SETREG or if the input and output must share a register.
In that case, we record a hard reg suggestion in QTY_PHYS_COPY_SUGG.
There are elaborate checks for the validity of combining. */
static int
-combine_regs (usedreg, setreg, may_save_copy, insn_number, insn, already_dead)
- rtx usedreg, setreg;
- int may_save_copy;
- int insn_number;
- rtx insn;
- int already_dead;
+combine_regs (rtx usedreg, rtx setreg, int may_save_copy, int insn_number,
+ rtx insn, int already_dead)
{
int ureg, sreg;
int offset = 0;
@@ -1996,9 +1970,7 @@ combine_regs (usedreg, setreg, may_save_copy, insn_number, insn, already_dead)
True if REG's reg class either contains or is contained in CLASS. */
static int
-reg_meets_class_p (reg, class)
- int reg;
- enum reg_class class;
+reg_meets_class_p (int reg, enum reg_class class)
{
enum reg_class rclass = reg_preferred_class (reg);
return (reg_class_subset_p (rclass, class)
@@ -2008,9 +1980,7 @@ reg_meets_class_p (reg, class)
/* Update the class of QTYNO assuming that REG is being tied to it. */
static void
-update_qty_class (qtyno, reg)
- int qtyno;
- int reg;
+update_qty_class (int qtyno, int reg)
{
enum reg_class rclass = reg_preferred_class (reg);
if (reg_class_subset_p (rclass, qty[qtyno].min_class))
@@ -2031,10 +2001,7 @@ update_qty_class (qtyno, reg)
carry info from `block_alloc'. */
static void
-reg_is_set (reg, setter, data)
- rtx reg;
- rtx setter;
- void *data ATTRIBUTE_UNUSED;
+reg_is_set (rtx reg, rtx setter, void *data ATTRIBUTE_UNUSED)
{
/* Note that note_stores will only pass us a SUBREG if it is a SUBREG of
a hard register. These may actually not exist any more. */
@@ -2054,9 +2021,7 @@ reg_is_set (reg, setter, data)
BIRTH is the index at which this is happening. */
static void
-reg_is_born (reg, birth)
- rtx reg;
- int birth;
+reg_is_born (rtx reg, int birth)
{
int regno;
@@ -2095,9 +2060,7 @@ reg_is_born (reg, birth)
If OUTPUT_P is 1, then we extend the life past the end of this insn. */
static void
-wipe_dead_reg (reg, output_p)
- rtx reg;
- int output_p;
+wipe_dead_reg (rtx reg, int output_p)
{
int regno = REGNO (reg);
@@ -2162,14 +2125,9 @@ wipe_dead_reg (reg, output_p)
register is available. If not, return -1. */
static int
-find_free_reg (class, mode, qtyno, accept_call_clobbered, just_try_suggested,
- born_index, dead_index)
- enum reg_class class;
- enum machine_mode mode;
- int qtyno;
- int accept_call_clobbered;
- int just_try_suggested;
- int born_index, dead_index;
+find_free_reg (enum reg_class class, enum machine_mode mode, int qtyno,
+ int accept_call_clobbered, int just_try_suggested,
+ int born_index, int dead_index)
{
int i, ins;
HARD_REG_SET first_used, used;
@@ -2315,10 +2273,7 @@ find_free_reg (class, mode, qtyno, accept_call_clobbered, just_try_suggested,
is zero). */
static void
-mark_life (regno, mode, life)
- int regno;
- enum machine_mode mode;
- int life;
+mark_life (int regno, enum machine_mode mode, int life)
{
int j = HARD_REGNO_NREGS (regno, mode);
if (life)
@@ -2334,17 +2289,11 @@ mark_life (regno, mode, life)
to insn number DEATH (exclusive). */
static void
-post_mark_life (regno, mode, life, birth, death)
- int regno;
- enum machine_mode mode;
- int life, birth, death;
+post_mark_life (int regno, enum machine_mode mode, int life, int birth,
+ int death)
{
int j = HARD_REGNO_NREGS (regno, mode);
-#ifdef HARD_REG_SET
- /* Declare it register if it's a scalar. */
- register
-#endif
- HARD_REG_SET this_reg;
+ HARD_REG_SET this_reg;
CLEAR_HARD_REG_SET (this_reg);
while (--j >= 0)
@@ -2374,8 +2323,7 @@ post_mark_life (regno, mode, life, birth, death)
Otherwise, return 0. */
static int
-no_conflict_p (insn, r0, r1)
- rtx insn, r0 ATTRIBUTE_UNUSED, r1;
+no_conflict_p (rtx insn, rtx r0 ATTRIBUTE_UNUSED, rtx r1)
{
int ok = 0;
rtx note = find_reg_note (insn, REG_LIBCALL, NULL_RTX);
@@ -2415,57 +2363,62 @@ no_conflict_p (insn, r0, r1)
is acceptable. */
static int
-requires_inout (p)
- const char *p;
+requires_inout (const char *p)
{
char c;
int found_zero = 0;
int reg_allowed = 0;
int num_matching_alts = 0;
+ int len;
- while ((c = *p++))
- switch (c)
- {
- case '=': case '+': case '?':
- case '#': case '&': case '!':
- case '*': case '%':
- case 'm': case '<': case '>': case 'V': case 'o':
- case 'E': case 'F': case 'G': case 'H':
- case 's': case 'i': case 'n':
- case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P':
- case 'X':
- /* These don't say anything we care about. */
- break;
+ for ( ; (c = *p); p += len)
+ {
+ len = CONSTRAINT_LEN (c, p);
+ switch (c)
+ {
+ case '=': case '+': case '?':
+ case '#': case '&': case '!':
+ case '*': case '%':
+ case 'm': case '<': case '>': case 'V': case 'o':
+ case 'E': case 'F': case 'G': case 'H':
+ case 's': case 'i': case 'n':
+ case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P':
+ case 'X':
+ /* These don't say anything we care about. */
+ break;
- case ',':
- if (found_zero && ! reg_allowed)
- num_matching_alts++;
+ case ',':
+ if (found_zero && ! reg_allowed)
+ num_matching_alts++;
- found_zero = reg_allowed = 0;
- break;
+ found_zero = reg_allowed = 0;
+ break;
- case '0':
- found_zero = 1;
- break;
+ case '0':
+ found_zero = 1;
+ break;
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- /* Skip the balance of the matching constraint. */
- while (ISDIGIT (*p))
- p++;
- break;
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ /* Skip the balance of the matching constraint. */
+ do
+ p++;
+ while (ISDIGIT (*p));
+ len = 0;
+ break;
- default:
- if (REG_CLASS_FROM_LETTER (c) == NO_REGS
- && !EXTRA_ADDRESS_CONSTRAINT (c))
+ default:
+ if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS
+ && !EXTRA_ADDRESS_CONSTRAINT (c, p))
+ break;
+ /* Fall through. */
+ case 'p':
+ case 'g': case 'r':
+ reg_allowed = 1;
break;
- /* FALLTHRU */
- case 'p':
- case 'g': case 'r':
- reg_allowed = 1;
- break;
- }
+ }
+ }
if (found_zero && ! reg_allowed)
num_matching_alts++;
@@ -2474,8 +2427,7 @@ requires_inout (p)
}
void
-dump_local_alloc (file)
- FILE *file;
+dump_local_alloc (FILE *file)
{
int i;
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
diff --git a/contrib/gcc/longlong.h b/contrib/gcc/longlong.h
index b886f2bdc8d3..e59e71232630 100644
--- a/contrib/gcc/longlong.h
+++ b/contrib/gcc/longlong.h
@@ -111,10 +111,7 @@
#define umul_ppmm(ph, pl, m0, m1) \
do { \
UDItype __m0 = (m0), __m1 = (m1); \
- __asm__ ("umulh %r1,%2,%0" \
- : "=r" ((UDItype) ph) \
- : "%rJ" (__m0), \
- "rI" (__m1)); \
+ (ph) = __builtin_alpha_umulh (__m0, __m1); \
(pl) = __m0 * __m1; \
} while (0)
#define UMUL_TIME 46
@@ -128,30 +125,28 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype);
#define UDIV_TIME 220
#endif /* LONGLONG_STANDALONE */
#ifdef __alpha_cix__
-#define count_leading_zeros(COUNT,X) \
- __asm__("ctlz %1,%0" : "=r"(COUNT) : "r"(X))
-#define count_trailing_zeros(COUNT,X) \
- __asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X))
+#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clzl (X))
+#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctzl (X))
#define COUNT_LEADING_ZEROS_0 64
#else
-extern const UQItype __clz_tab[];
+extern const UQItype __clz_tab[] ATTRIBUTE_HIDDEN;
#define count_leading_zeros(COUNT,X) \
do { \
UDItype __xr = (X), __t, __a; \
- __asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr)); \
+ __t = __builtin_alpha_cmpbge (0, __xr); \
__a = __clz_tab[__t ^ 0xff] - 1; \
- __asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a)); \
+ __t = __builtin_alpha_extbl (__xr, __a); \
(COUNT) = 64 - (__clz_tab[__t] + __a*8); \
} while (0)
#define count_trailing_zeros(COUNT,X) \
do { \
UDItype __xr = (X), __t, __a; \
- __asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr)); \
+ __t = __builtin_alpha_cmpbge (0, __xr); \
__t = ~__t & -~__t; \
__a = ((__t & 0xCC) != 0) * 2; \
__a += ((__t & 0xF0) != 0) * 4; \
__a += ((__t & 0xAA) != 0); \
- __asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a)); \
+ __t = __builtin_alpha_extbl (__xr, __a); \
__a <<= 3; \
__t &= -__t; \
__a += ((__t & 0xCC) != 0) * 2; \
@@ -381,17 +376,17 @@ UDItype __umulsidi3 (USItype, USItype);
#if defined (__M32R__) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
/* The cmp clears the condition bit. */ \
- __asm__ ("cmp %0,%0\n\taddx %%5,%1\n\taddx %%3,%0" \
+ __asm__ ("cmp %0,%0\n\taddx %1,%5\n\taddx %0,%3" \
: "=r" ((USItype) (sh)), \
"=&r" ((USItype) (sl)) \
- : "%0" ((USItype) (ah)), \
+ : "0" ((USItype) (ah)), \
"r" ((USItype) (bh)), \
- "%1" ((USItype) (al)), \
+ "1" ((USItype) (al)), \
"r" ((USItype) (bl)) \
: "cbit")
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
/* The cmp clears the condition bit. */ \
- __asm__ ("cmp %0,%0\n\tsubx %5,%1\n\tsubx %3,%0" \
+ __asm__ ("cmp %0,%0\n\tsubx %1,%5\n\tsubx %0,%3" \
: "=r" ((USItype) (sh)), \
"=&r" ((USItype) (sl)) \
: "0" ((USItype) (ah)), \
@@ -448,7 +443,42 @@ UDItype __umulsidi3 (USItype, USItype);
"dmi" ((USItype) (d)))
#else /* not mc68020 */
-#if !defined(__mcf5200__)
+#if defined(__mcoldfire__)
+#define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("| Inlined umul_ppmm\n" \
+ " move%.l %2,%/d0\n" \
+ " move%.l %3,%/d1\n" \
+ " move%.l %/d0,%/d2\n" \
+ " swap %/d0\n" \
+ " move%.l %/d1,%/d3\n" \
+ " swap %/d1\n" \
+ " move%.w %/d2,%/d4\n" \
+ " mulu %/d3,%/d4\n" \
+ " mulu %/d1,%/d2\n" \
+ " mulu %/d0,%/d3\n" \
+ " mulu %/d0,%/d1\n" \
+ " move%.l %/d4,%/d0\n" \
+ " clr%.w %/d0\n" \
+ " swap %/d0\n" \
+ " add%.l %/d0,%/d2\n" \
+ " add%.l %/d3,%/d2\n" \
+ " jcc 1f\n" \
+ " add%.l %#65536,%/d1\n" \
+ "1: swap %/d2\n" \
+ " moveq %#0,%/d0\n" \
+ " move%.w %/d2,%/d0\n" \
+ " move%.w %/d4,%/d2\n" \
+ " move%.l %/d2,%1\n" \
+ " add%.l %/d1,%/d0\n" \
+ " move%.l %/d0,%0" \
+ : "=g" ((USItype) (xh)), \
+ "=g" ((USItype) (xl)) \
+ : "g" ((USItype) (a)), \
+ "g" ((USItype) (b)) \
+ : "d0", "d1", "d2", "d3", "d4")
+#define UMUL_TIME 100
+#define UDIV_TIME 400
+#else /* not ColdFire */
/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */
#define umul_ppmm(xh, xl, a, b) \
__asm__ ("| Inlined umul_ppmm\n" \
@@ -484,14 +514,16 @@ UDItype __umulsidi3 (USItype, USItype);
: "d0", "d1", "d2", "d3", "d4")
#define UMUL_TIME 100
#define UDIV_TIME 400
-#endif /* not mcf5200 */
+#endif /* not ColdFire */
#endif /* not mc68020 */
-/* The '020, '030, '040 and '060 have bitfield insns. */
-#if defined (__mc68020__) || defined(mc68020) \
- || defined(__mc68030__) || defined(mc68030) \
- || defined(__mc68040__) || defined(mc68040) \
- || defined(__mc68060__) || defined(mc68060)
+/* The '020, '030, '040 and '060 have bitfield insns.
+ cpu32 disguises as a 68020, but lacks them. */
+#if ( defined (__mc68020__) || defined(mc68020) \
+ || defined(__mc68030__) || defined(mc68030) \
+ || defined(__mc68040__) || defined(mc68040) \
+ || defined(__mc68060__) || defined(mc68060) ) \
+ && !defined(__mcpu32__)
#define count_leading_zeros(count, x) \
__asm__ ("bfffo %1{%b2:%b2},%0" \
: "=d" ((USItype) (count)) \
@@ -652,7 +684,7 @@ UDItype __umulsidi3 (USItype, USItype);
__asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x))
#define COUNT_LEADING_ZEROS_0 32
#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \
- || defined (__ppc__) || defined (PPC) || defined (__vxworks__)
+ || defined (__ppc__) || defined (PPC)
#define umul_ppmm(ph, pl, m0, m1) \
do { \
USItype __m0 = (m0), __m1 = (m1); \
@@ -1287,7 +1319,7 @@ UDItype __umulsidi3 (USItype, USItype);
#endif
#if !defined (count_leading_zeros)
-extern const UQItype __clz_tab[];
+extern const UQItype __clz_tab[] ATTRIBUTE_HIDDEN;
#define count_leading_zeros(count, x) \
do { \
UWtype __xr = (x); \
diff --git a/contrib/gcc/loop-init.c b/contrib/gcc/loop-init.c
new file mode 100644
index 000000000000..6dd146f99113
--- /dev/null
+++ b/contrib/gcc/loop-init.c
@@ -0,0 +1,220 @@
+/* Loop optimizer initialization routines.
+ Copyright (C) 2002, 2003, 2004 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "cfgloop.h"
+#include "cfglayout.h"
+
+static void fixup_loop_exit_succesor (basic_block, basic_block);
+
+/* Initialize loop optimizer. */
+
+struct loops *
+loop_optimizer_init (FILE *dumpfile)
+{
+ struct loops *loops = xcalloc (1, sizeof (struct loops));
+ edge e;
+
+ /* Initialize structures for layout changes. */
+ cfg_layout_initialize (0);
+
+ /* Avoid annoying special cases of edges going to exit
+ block. */
+ for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+ if ((e->flags & EDGE_FALLTHRU) && e->src->succ->succ_next)
+ split_edge (e);
+
+ /* Find the loops. */
+
+ if (flow_loops_find (loops, LOOP_TREE) <= 1)
+ {
+ basic_block bb;
+
+ /* No loops. */
+ flow_loops_free (loops);
+ free_dominance_info (CDI_DOMINATORS);
+ free (loops);
+
+ /* Make chain. */
+ FOR_EACH_BB (bb)
+ if (bb->next_bb != EXIT_BLOCK_PTR)
+ bb->rbi->next = bb->next_bb;
+ cfg_layout_finalize ();
+ return NULL;
+ }
+
+ /* Not going to update these. */
+ free (loops->cfg.rc_order);
+ loops->cfg.rc_order = NULL;
+ free (loops->cfg.dfs_order);
+ loops->cfg.dfs_order = NULL;
+
+ /* Create pre-headers. */
+ create_preheaders (loops, CP_SIMPLE_PREHEADERS);
+
+ /* Force all latches to have only single successor. */
+ force_single_succ_latches (loops);
+
+ /* Mark irreducible loops. */
+ mark_irreducible_loops (loops);
+
+ /* Dump loops. */
+ flow_loops_dump (loops, dumpfile, NULL, 1);
+
+#ifdef ENABLE_CHECKING
+ verify_dominators (CDI_DOMINATORS);
+ verify_loop_structure (loops);
+#endif
+
+ return loops;
+}
+
+/* The first basic block is moved after the second in the reorder chain. */
+static void
+fixup_loop_exit_succesor (basic_block exit_succ, basic_block latch)
+{
+ basic_block bb = exit_succ;
+ basic_block bb1 = latch;
+
+ if (!(bb && bb->rbi->next))
+ return;
+
+ if (!bb1)
+ return;
+
+
+ if (bb && bb->rbi->next)
+ {
+ basic_block c = ENTRY_BLOCK_PTR->next_bb;
+
+ while (c->rbi->next != bb)
+ c = c->rbi->next;
+
+ c->rbi->next = bb->rbi->next;
+ }
+
+ if(bb1->rbi->next == NULL)
+ {
+ bb1->rbi->next=bb;
+ bb->rbi->next=NULL;
+ }
+ else
+
+ {
+ basic_block tmp;
+
+ tmp = bb1->rbi->next;
+ bb1->rbi->next = bb;
+ bb->rbi->next = tmp;
+ }
+}
+
+/* Finalize loop optimizer. */
+void
+loop_optimizer_finalize (struct loops *loops, FILE *dumpfile)
+{
+ basic_block bb;
+ unsigned int i;
+
+ /* Finalize layout changes. */
+ /* Make chain. */
+ FOR_EACH_BB (bb)
+ if (bb->next_bb != EXIT_BLOCK_PTR)
+ bb->rbi->next = bb->next_bb;
+
+ /* Another dump. */
+ flow_loops_dump (loops, dumpfile, NULL, 1);
+
+ /* For loops ending with a branch and count instruction, move the basic
+ block found before the unrolling on the fallthru path of this branch,
+ after the unrolled code. This will allow branch simplification. */
+ for (i = 1; i < loops->num; i++)
+ {
+ struct loop *loop = loops->parray[i];
+ struct loop_desc *desc;
+ basic_block loop_real_latch, bb, bb_exit;
+ edge e;
+
+ if (loop == NULL)
+ continue;
+ if (!loop->simple)
+ continue;
+ if (!loop->has_desc)
+ continue;
+
+ if (loop->lpt_decision.decision != LPT_UNROLL_RUNTIME)
+ continue;
+
+ desc = &loop->desc;
+ if (desc == NULL)
+ continue;
+ if (loop->latch->pred == NULL)
+ continue;
+
+ loop_real_latch = loop->latch->pred->src;
+
+
+ if (desc->postincr)
+ continue;
+ if (!is_bct_cond (BB_END (loop_real_latch)))
+ continue;
+
+ for (e = loop_real_latch->succ; e ; e = e->succ_next)
+ if (e->flags & EDGE_FALLTHRU)
+ break;
+
+ if (e == NULL)
+ continue;
+
+ bb_exit = e->dest;
+
+ bb = NULL;
+
+ /* Leave the case of the bb_exit falling through to exit to
+ fixed_fallthru_exit_predecessor */
+ for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
+ if (e->flags & EDGE_FALLTHRU)
+ bb = e->src;
+
+ if (bb_exit == bb)
+ continue;
+
+ fixup_loop_exit_succesor (bb_exit, loop->latch);
+ }
+
+ /* Clean up. */
+ flow_loops_free (loops);
+ free_dominance_info (CDI_DOMINATORS);
+ free (loops);
+
+ /* Finalize changes. */
+ cfg_layout_finalize ();
+
+ /* Checking. */
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+}
diff --git a/contrib/gcc/loop-unroll.c b/contrib/gcc/loop-unroll.c
new file mode 100644
index 000000000000..aae175720fea
--- /dev/null
+++ b/contrib/gcc/loop-unroll.c
@@ -0,0 +1,1383 @@
+/* Loop unrolling and peeling.
+ Copyright (C) 2002, 2003, 2004 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "cfgloop.h"
+#include "cfglayout.h"
+#include "params.h"
+#include "output.h"
+#include "expr.h"
+/* We need to use the macro exact_log2. */
+#include "toplev.h"
+
+/* This pass performs loop unrolling and peeling. We only perform these
+ optimizations on innermost loops (with single exception) because
+ the impact on performance is greatest here, and we want to avoid
+ unnecessary code size growth. The gain is caused by greater sequentiality
+ of code, better code to optimize for further passes and in some cases
+ by fewer testings of exit conditions. The main problem is code growth,
+ that impacts performance negatively due to effect of caches.
+
+ What we do:
+
+ -- complete peeling of once-rolling loops; this is the above mentioned
+ exception, as this causes loop to be cancelled completely and
+ does not cause code growth
+ -- complete peeling of loops that roll (small) constant times.
+ -- simple peeling of first iterations of loops that do not roll much
+ (according to profile feedback)
+ -- unrolling of loops that roll constant times; this is almost always
+ win, as we get rid of exit condition tests.
+ -- unrolling of loops that roll number of times that we can compute
+ in runtime; we also get rid of exit condition tests here, but there
+ is the extra expense for calculating the number of iterations
+ -- simple unrolling of remaining loops; this is performed only if we
+ are asked to, as the gain is questionable in this case and often
+ it may even slow down the code
+ For more detailed descriptions of each of those, see comments at
+ appropriate function below.
+
+ There is a lot of parameters (defined and described in params.def) that
+ control how much we unroll/peel.
+
+ ??? A great problem is that we don't have a good way how to determine
+ how many times we should unroll the loop; the experiments I have made
+ showed that this choice may affect performance in order of several %.
+ */
+
+static void decide_unrolling_and_peeling (struct loops *, int);
+static void peel_loops_completely (struct loops *, int);
+static void decide_peel_simple (struct loop *, int);
+static void decide_peel_once_rolling (struct loop *, int);
+static void decide_peel_completely (struct loop *, int);
+static void decide_unroll_stupid (struct loop *, int);
+static void decide_unroll_constant_iterations (struct loop *, int);
+static void decide_unroll_runtime_iterations (struct loop *, int);
+static void peel_loop_simple (struct loops *, struct loop *);
+static void peel_loop_completely (struct loops *, struct loop *);
+static void unroll_loop_stupid (struct loops *, struct loop *);
+static void unroll_loop_constant_iterations (struct loops *, struct loop *);
+static void unroll_loop_runtime_iterations (struct loops *, struct loop *);
+static void expand_bct (edge, int);
+static bool discard_increment (struct loop *);
+
+/* Unroll and/or peel (depending on FLAGS) LOOPS. */
+void
+unroll_and_peel_loops (struct loops *loops, int flags)
+{
+ struct loop *loop, *next;
+ int check;
+
+ /* First perform complete loop peeling (it is almost surely a win,
+ and affects parameters for further decision a lot). */
+ peel_loops_completely (loops, flags);
+
+ /* Now decide rest of unrolling and peeling. */
+ decide_unrolling_and_peeling (loops, flags);
+
+ loop = loops->tree_root;
+ while (loop->inner)
+ loop = loop->inner;
+
+ /* Scan the loops, inner ones first. */
+ while (loop != loops->tree_root)
+ {
+ if (loop->next)
+ {
+ next = loop->next;
+ while (next->inner)
+ next = next->inner;
+ }
+ else
+ next = loop->outer;
+
+ check = 1;
+ /* And perform the appropriate transformations. */
+ switch (loop->lpt_decision.decision)
+ {
+ case LPT_PEEL_COMPLETELY:
+ /* Already done. */
+ abort ();
+ case LPT_PEEL_SIMPLE:
+ peel_loop_simple (loops, loop);
+ break;
+ case LPT_UNROLL_CONSTANT:
+ unroll_loop_constant_iterations (loops, loop);
+ break;
+ case LPT_UNROLL_RUNTIME:
+ unroll_loop_runtime_iterations (loops, loop);
+ break;
+ case LPT_UNROLL_STUPID:
+ unroll_loop_stupid (loops, loop);
+ break;
+ case LPT_NONE:
+ check = 0;
+ break;
+ default:
+ abort ();
+ }
+ if (check)
+ {
+#ifdef ENABLE_CHECKING
+ verify_dominators (CDI_DOMINATORS);
+ verify_loop_structure (loops);
+#endif
+ }
+ loop = next;
+ }
+}
+
+/* Check whether to peel LOOPS (depending on FLAGS) completely and do so. */
+static void
+peel_loops_completely (struct loops *loops, int flags)
+{
+ struct loop *loop, *next;
+
+ loop = loops->tree_root;
+ while (loop->inner)
+ loop = loop->inner;
+
+ while (loop != loops->tree_root)
+ {
+ if (loop->next)
+ {
+ next = loop->next;
+ while (next->inner)
+ next = next->inner;
+ }
+ else
+ next = loop->outer;
+
+ loop->lpt_decision.decision = LPT_NONE;
+ loop->has_desc = 0;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Considering loop %d for complete peeling\n",
+ loop->num);
+
+ loop->ninsns = num_loop_insns (loop);
+
+ decide_peel_once_rolling (loop, flags);
+ if (loop->lpt_decision.decision == LPT_NONE)
+ decide_peel_completely (loop, flags);
+
+ if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
+ {
+ peel_loop_completely (loops, loop);
+#ifdef ENABLE_CHECKING
+ verify_dominators (CDI_DOMINATORS);
+ verify_loop_structure (loops);
+#endif
+ }
+ loop = next;
+ }
+}
+
+/* Decide whether unroll or peel LOOPS (depending on FLAGS) and how much. */
+static void
+decide_unrolling_and_peeling (struct loops *loops, int flags)
+{
+ struct loop *loop = loops->tree_root, *next;
+
+ while (loop->inner)
+ loop = loop->inner;
+
+ /* Scan the loops, inner ones first. */
+ while (loop != loops->tree_root)
+ {
+ if (loop->next)
+ {
+ next = loop->next;
+ while (next->inner)
+ next = next->inner;
+ }
+ else
+ next = loop->outer;
+
+ loop->lpt_decision.decision = LPT_NONE;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Considering loop %d\n", loop->num);
+
+ /* Do not peel cold areas. */
+ if (!maybe_hot_bb_p (loop->header))
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not considering loop, cold area\n");
+ loop = next;
+ continue;
+ }
+
+ /* Can the loop be manipulated? */
+ if (!can_duplicate_loop_p (loop))
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ ";; Not considering loop, cannot duplicate\n");
+ loop = next;
+ continue;
+ }
+
+ /* Skip non-innermost loops. */
+ if (loop->inner)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not considering loop, is not innermost\n");
+ loop = next;
+ continue;
+ }
+
+ loop->ninsns = num_loop_insns (loop);
+ loop->av_ninsns = average_num_loop_insns (loop);
+
+ /* Try transformations one by one in decreasing order of
+ priority. */
+
+ decide_unroll_constant_iterations (loop, flags);
+ if (loop->lpt_decision.decision == LPT_NONE)
+ decide_unroll_runtime_iterations (loop, flags);
+ if (loop->lpt_decision.decision == LPT_NONE)
+ decide_unroll_stupid (loop, flags);
+ if (loop->lpt_decision.decision == LPT_NONE)
+ decide_peel_simple (loop, flags);
+
+ loop = next;
+ }
+}
+
+/* Decide whether the LOOP is once rolling and suitable for complete
+ peeling. */
+static void
+decide_peel_once_rolling (struct loop *loop, int flags ATTRIBUTE_UNUSED)
+{
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Considering peeling once rolling loop\n");
+
+ /* Is the loop small enough? */
+ if ((unsigned) PARAM_VALUE (PARAM_MAX_ONCE_PEELED_INSNS) < loop->ninsns)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not considering loop, is too big\n");
+ return;
+ }
+
+ /* Check for simple loops. */
+ loop->simple = simple_loop_p (loop, &loop->desc);
+ loop->has_desc = 1;
+
+ /* Check number of iterations. */
+ if (!loop->simple || !loop->desc.const_iter || loop->desc.niter != 0)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Unable to prove that the loop rolls exactly once\n");
+ return;
+ }
+
+ /* Success. */
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Decided to peel exactly once rolling loop\n");
+ loop->lpt_decision.decision = LPT_PEEL_COMPLETELY;
+}
+
+/* Decide whether the LOOP is suitable for complete peeling. */
+static void
+decide_peel_completely (struct loop *loop, int flags ATTRIBUTE_UNUSED)
+{
+ unsigned npeel;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Considering peeling completely\n");
+
+ /* Skip non-innermost loops. */
+ if (loop->inner)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not considering loop, is not innermost\n");
+ return;
+ }
+
+ /* Do not peel cold areas. */
+ if (!maybe_hot_bb_p (loop->header))
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not considering loop, cold area\n");
+ return;
+ }
+
+ /* Can the loop be manipulated? */
+ if (!can_duplicate_loop_p (loop))
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ ";; Not considering loop, cannot duplicate\n");
+ return;
+ }
+
+ /* npeel = number of iterations to peel. */
+ npeel = PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS) / loop->ninsns;
+ if (npeel > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEEL_TIMES))
+ npeel = PARAM_VALUE (PARAM_MAX_COMPLETELY_PEEL_TIMES);
+
+ /* Is the loop small enough? */
+ if (!npeel)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not considering loop, is too big\n");
+ return;
+ }
+
+ /* Check for simple loops. */
+ if (!loop->has_desc)
+ {
+ loop->simple = simple_loop_p (loop, &loop->desc);
+ loop->has_desc = 1;
+ }
+
+ /* Check number of iterations. */
+ if (!loop->simple || !loop->desc.const_iter)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Unable to prove that the loop iterates constant times\n");
+ return;
+ }
+
+ if (loop->desc.niter > npeel - 1)
+ {
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, ";; Not peeling loop completely, rolls too much (");
+ fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC,(HOST_WIDEST_INT) loop->desc.niter);
+ fprintf (rtl_dump_file, " iterations > %d [maximum peelings])\n", npeel);
+ }
+ return;
+ }
+
+ /* Success. */
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Decided to peel loop completely\n");
+ loop->lpt_decision.decision = LPT_PEEL_COMPLETELY;
+}
+
+/* Peel all iterations of LOOP, remove exit edges and cancel the loop
+ completely. The transformation done:
+
+ for (i = 0; i < 4; i++)
+ body;
+
+ ==>
+
+ i = 0;
+ body; i++;
+ body; i++;
+ body; i++;
+ body; i++;
+ */
+static void
+peel_loop_completely (struct loops *loops, struct loop *loop)
+{
+ sbitmap wont_exit;
+ unsigned HOST_WIDE_INT npeel;
+ unsigned n_remove_edges, i;
+ edge *remove_edges;
+ struct loop_desc *desc = &loop->desc;
+ bool discard_inc = false;
+ bool is_bct;
+
+ if ((is_bct = is_bct_cond (BB_END (loop->desc.out_edge->src))))
+ discard_inc = discard_increment (loop);
+
+ npeel = desc->niter;
+
+ if (npeel)
+ {
+ wont_exit = sbitmap_alloc (npeel + 1);
+ sbitmap_ones (wont_exit);
+ RESET_BIT (wont_exit, 0);
+ if (desc->may_be_zero)
+ RESET_BIT (wont_exit, 1);
+
+ remove_edges = xcalloc (npeel, sizeof (edge));
+ n_remove_edges = 0;
+
+ if (!duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
+ loops, npeel,
+ wont_exit, desc->out_edge, remove_edges, &n_remove_edges,
+ DLTHE_FLAG_UPDATE_FREQ))
+ abort ();
+
+ free (wont_exit);
+
+ /* Expand the branch and count. */
+ if (is_bct)
+ for (i = 0; i < n_remove_edges; i++)
+ expand_bct (remove_edges[i], discard_inc);
+
+ /* Remove the exit edges. */
+ for (i = 0; i < n_remove_edges; i++)
+ remove_path (loops, remove_edges[i]);
+ free (remove_edges);
+ }
+
+ /* Expand the branch and count. */
+ if (is_bct)
+ expand_bct (desc->in_edge, discard_inc);
+
+ /* Now remove the unreachable part of the last iteration and cancel
+ the loop. */
+ remove_path (loops, desc->in_edge);
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Peeled loop completely, %d times\n", (int) npeel);
+}
+
+/* Decide whether to unroll LOOP iterating constant number of times and how much. */
+static void
+decide_unroll_constant_iterations (struct loop *loop, int flags)
+{
+ unsigned nunroll, nunroll_by_av, best_copies, best_unroll = -1, n_copies, i;
+
+ if (!(flags & UAP_UNROLL))
+ {
+ /* We were not asked to, just return back silently. */
+ return;
+ }
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Considering unrolling loop with constant number of iterations\n");
+
+ /* nunroll = total number of copies of the original loop body in
+ unrolled loop (i.e. if it is 2, we have to duplicate loop body once. */
+ nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / loop->ninsns;
+ nunroll_by_av = PARAM_VALUE (PARAM_MAX_AVERAGE_UNROLLED_INSNS) / loop->av_ninsns;
+ if (nunroll > nunroll_by_av)
+ nunroll = nunroll_by_av;
+ if (nunroll > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES))
+ nunroll = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
+
+ /* Skip big loops. */
+ if (nunroll <= 1)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not considering loop, is too big\n");
+ return;
+ }
+
+ /* Check for simple loops. */
+ if (!loop->has_desc)
+ {
+ loop->simple = simple_loop_p (loop, &loop->desc);
+ loop->has_desc = 1;
+ }
+
+ /* Check number of iterations. */
+ if (!loop->simple || !loop->desc.const_iter)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Unable to prove that the loop iterates constant times\n");
+ return;
+ }
+
+ /* Check whether the loop rolls enough to consider. */
+ if (loop->desc.niter < 2 * nunroll)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not unrolling loop, doesn't roll\n");
+ return;
+ }
+
+ /* Success; now compute number of iterations to unroll. We alter
+ nunroll so that as few as possible copies of loop body are
+ necessary, while still not decreasing the number of unrollings
+ too much (at most by 1). */
+ best_copies = 2 * nunroll + 10;
+
+ i = 2 * nunroll + 2;
+ if ((unsigned) i - 1 >= loop->desc.niter)
+ i = loop->desc.niter - 2;
+
+ for (; i >= nunroll - 1; i--)
+ {
+ unsigned exit_mod = loop->desc.niter % (i + 1);
+
+ if (loop->desc.postincr)
+ n_copies = exit_mod + i + 1;
+ else if (exit_mod != (unsigned) i || loop->desc.may_be_zero)
+ n_copies = exit_mod + i + 2;
+ else
+ n_copies = i + 1;
+
+ if (n_copies < best_copies)
+ {
+ best_copies = n_copies;
+ best_unroll = i;
+ }
+ }
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; max_unroll %d (%d copies, initial %d).\n",
+ best_unroll + 1, best_copies, nunroll);
+
+ loop->lpt_decision.decision = LPT_UNROLL_CONSTANT;
+ loop->lpt_decision.times = best_unroll;
+}
+
+/* Unroll LOOP with constant number of iterations LOOP->LPT_DECISION.TIMES + 1
+ times. The transformation does this:
+
+ for (i = 0; i < 102; i++)
+ body;
+
+ ==>
+
+ i = 0;
+ body; i++;
+ body; i++;
+ while (i < 102)
+ {
+ body; i++;
+ body; i++;
+ body; i++;
+ body; i++;
+ }
+ */
+static void
+unroll_loop_constant_iterations (struct loops *loops, struct loop *loop)
+{
+ unsigned HOST_WIDE_INT niter;
+ unsigned exit_mod;
+ sbitmap wont_exit;
+ unsigned n_remove_edges, i;
+ edge *remove_edges;
+ unsigned max_unroll = loop->lpt_decision.times;
+ struct loop_desc *desc = &loop->desc;
+ bool discard_inc = false;
+ bool is_bct;
+
+ niter = desc->niter;
+
+ if (niter <= (unsigned) max_unroll + 1)
+ abort (); /* Should not get here (such loop should be peeled instead). */
+
+ exit_mod = niter % (max_unroll + 1);
+
+ wont_exit = sbitmap_alloc (max_unroll + 1);
+ sbitmap_ones (wont_exit);
+
+ remove_edges = xcalloc (max_unroll + exit_mod + 1, sizeof (edge));
+ n_remove_edges = 0;
+
+ /* For a loop ending with a branch and count for which the increment
+ of the count register will be discarded, adjust the initialization of
+ the count register. */
+ if ((is_bct = is_bct_cond (BB_END (desc->out_edge->src)))
+ && (discard_inc = discard_increment (loop)))
+ {
+ rtx ini_var;
+
+ rtx init_code;
+ int n_peel, new_bct_value;
+
+ /* Get expression for number of iterations. */
+ start_sequence ();
+
+ n_peel = (niter+1) % (max_unroll+1);
+ new_bct_value = (niter+1 - n_peel) / (max_unroll+1) ;
+ ini_var = GEN_INT (new_bct_value);
+
+ emit_move_insn (desc->var, ini_var);
+ init_code = get_insns ();
+ end_sequence ();
+
+ loop_split_edge_with (loop_preheader_edge (loop), init_code);
+ }
+
+ if (desc->postincr)
+ {
+ /* Counter is incremented after the exit test; leave exit test
+ in the first copy, so that the loops that start with test
+ of exit condition have continuous body after unrolling. */
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Condition on beginning of loop.\n");
+
+ /* Peel exit_mod iterations. */
+ RESET_BIT (wont_exit, 0);
+ if (desc->may_be_zero)
+ RESET_BIT (wont_exit, 1);
+
+ if (exit_mod
+ && !duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
+ loops, exit_mod,
+ wont_exit, desc->out_edge, remove_edges, &n_remove_edges,
+ DLTHE_FLAG_UPDATE_FREQ))
+ abort ();
+
+ SET_BIT (wont_exit, 1);
+ }
+ else
+ {
+ /* Leave exit test in last copy, for the same reason as above if
+ the loop tests the condition at the end of loop body. */
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Condition on end of loop.\n");
+
+ /* We know that niter >= max_unroll + 2; so we do not need to care of
+ case when we would exit before reaching the loop. So just peel
+ exit_mod + 1 iterations.
+ */
+ if (exit_mod != (unsigned) max_unroll || desc->may_be_zero)
+ {
+ RESET_BIT (wont_exit, 0);
+ if (desc->may_be_zero)
+ RESET_BIT (wont_exit, 1);
+
+ if (!duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
+ loops, exit_mod + 1,
+ wont_exit, desc->out_edge, remove_edges, &n_remove_edges,
+ DLTHE_FLAG_UPDATE_FREQ))
+ abort ();
+
+ SET_BIT (wont_exit, 0);
+ SET_BIT (wont_exit, 1);
+ }
+
+ RESET_BIT (wont_exit, max_unroll);
+ }
+
+ /* Now unroll the loop. */
+ if (!duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
+ loops, max_unroll,
+ wont_exit, desc->out_edge, remove_edges, &n_remove_edges,
+ DLTHE_FLAG_UPDATE_FREQ))
+ abort ();
+
+ free (wont_exit);
+
+ /* Expand the branch and count. */
+ if (is_bct)
+ for (i = 0; i < n_remove_edges; i++)
+ expand_bct (remove_edges[i], discard_inc);
+
+ /* Remove the edges. */
+ for (i = 0; i < n_remove_edges; i++)
+ remove_path (loops, remove_edges[i]);
+ free (remove_edges);
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Unrolled loop %d times, constant # of iterations %i insns\n",max_unroll, num_loop_insns (loop));
+}
+
+/* Decide whether to unroll LOOP iterating runtime computable number of times
+ and how much. */
+static void
+decide_unroll_runtime_iterations (struct loop *loop, int flags)
+{
+ unsigned nunroll, nunroll_by_av, i;
+
+ if (!(flags & UAP_UNROLL))
+ {
+ /* We were not asked to, just return back silently. */
+ return;
+ }
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Considering unrolling loop with runtime computable number of iterations\n");
+
+ /* nunroll = total number of copies of the original loop body in
+ unrolled loop (i.e. if it is 2, we have to duplicate loop body once. */
+ nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / loop->ninsns;
+ nunroll_by_av = PARAM_VALUE (PARAM_MAX_AVERAGE_UNROLLED_INSNS) / loop->av_ninsns;
+ if (nunroll > nunroll_by_av)
+ nunroll = nunroll_by_av;
+ if (nunroll > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES))
+ nunroll = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
+
+ /* Skip big loops. */
+ if (nunroll <= 1)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not considering loop, is too big\n");
+ return;
+ }
+
+ /* Check for simple loops. */
+ if (!loop->has_desc)
+ {
+ loop->simple = simple_loop_p (loop, &loop->desc);
+ loop->has_desc = 1;
+ }
+
+ /* Check simpleness. */
+ if (!loop->simple)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Unable to prove that the number of iterations can be counted in runtime\n");
+ return;
+ }
+
+ if (loop->desc.const_iter)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Loop iterates constant times\n");
+ return;
+ }
+
+ /* If we have profile feedback, check whether the loop rolls. */
+ if (loop->header->count && expected_loop_iterations (loop) < 2 * nunroll)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not unrolling loop, doesn't roll\n");
+ return;
+ }
+
+ /* Success; now force nunroll to be power of 2, as we are unable to
+ cope with overflows in computation of number of iterations. */
+ for (i = 1; 2 * i <= nunroll; i *= 2);
+
+ loop->lpt_decision.decision = LPT_UNROLL_RUNTIME;
+ loop->lpt_decision.times = i - 1;
+}
+
+/* Unroll LOOP for that we are able to count number of iterations in runtime
+ LOOP->LPT_DECISION.TIMES + 1 times. The transformation does this (with some
+ extra care for case n < 0):
+
+ for (i = 0; i < n; i++)
+ body;
+
+ ==>
+
+ i = 0;
+ mod = n % 4;
+
+ switch (mod)
+ {
+ case 3:
+ body; i++;
+ case 2:
+ body; i++;
+ case 1:
+ body; i++;
+ case 0: ;
+ }
+
+ while (i < n)
+ {
+ body; i++;
+ body; i++;
+ body; i++;
+ body; i++;
+ }
+ */
+static void
+unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
+{
+ rtx niter, init_code, branch_code, jump, label;
+ unsigned i, j, p;
+ basic_block preheader, *body, *dom_bbs, swtch, ezc_swtch;
+ unsigned n_dom_bbs;
+ sbitmap wont_exit;
+ int may_exit_copy;
+ unsigned n_peel, n_remove_edges;
+ edge *remove_edges, e;
+ bool extra_zero_check, last_may_exit;
+ unsigned max_unroll = loop->lpt_decision.times;
+ struct loop_desc *desc = &loop->desc;
+ bool discard_inc = false;
+ bool is_bct;
+
+ /* Remember blocks whose dominators will have to be updated. */
+ dom_bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
+ n_dom_bbs = 0;
+
+ body = get_loop_body (loop);
+ for (i = 0; i < loop->num_nodes; i++)
+ {
+ unsigned nldom;
+ basic_block *ldom;
+
+ nldom = get_dominated_by (CDI_DOMINATORS, body[i], &ldom);
+ for (j = 0; j < nldom; j++)
+ if (!flow_bb_inside_loop_p (loop, ldom[j]))
+ dom_bbs[n_dom_bbs++] = ldom[j];
+
+ free (ldom);
+ }
+ free (body);
+
+ if (desc->postincr)
+ {
+ /* Leave exit in first copy (for explanation why see comment in
+ unroll_loop_constant_iterations). */
+ may_exit_copy = 0;
+ n_peel = max_unroll - 1;
+ extra_zero_check = true;
+ last_may_exit = false;
+ }
+ else
+ {
+ /* Leave exit in last copy (for explanation why see comment in
+ unroll_loop_constant_iterations). */
+ may_exit_copy = max_unroll;
+ n_peel = max_unroll;
+ extra_zero_check = false;
+ last_may_exit = true;
+ }
+
+ /* Get expression for number of iterations. */
+ start_sequence ();
+ niter = count_loop_iterations (desc, NULL, NULL);
+ if (!niter)
+ abort ();
+ niter = force_operand (niter, NULL);
+
+ /* Count modulo by ANDing it with max_unroll; we use the fact that
+ the number of unrollings is a power of two, and thus this is correct
+ even if there is overflow in the computation. */
+ niter = expand_simple_binop (GET_MODE (desc->var), AND,
+ niter,
+ GEN_INT (max_unroll),
+ NULL_RTX, 0, OPTAB_LIB_WIDEN);
+
+ /* For a loop ending with a branch and count for which the increment
+ of the count register will be discarded, adjust the initialization of
+ the count register. */
+ if ((is_bct = is_bct_cond (BB_END (desc->out_edge->src)))
+ && (discard_inc = discard_increment (loop)))
+ {
+ rtx count, count2, count_unroll_mod;
+ int count_unroll;
+
+ /* start_sequence (); */
+
+ count = count_loop_iterations (desc, NULL, NULL);
+
+ count_unroll = loop->lpt_decision.times+1;
+
+
+
+ count_unroll_mod = GEN_INT (exact_log2 (count_unroll));
+ count = expand_simple_binop (GET_MODE (desc->var), LSHIFTRT,
+ count, count_unroll_mod,
+ 0, 0, OPTAB_LIB_WIDEN);
+
+ count2 = expand_simple_binop (GET_MODE (desc->var), PLUS,
+ count, GEN_INT (2),
+ 0, 0, OPTAB_LIB_WIDEN);
+
+ emit_move_insn (desc->var, count2);
+ }
+
+ init_code = get_insns ();
+ end_sequence ();
+
+ /* Precondition the loop. */
+ loop_split_edge_with (loop_preheader_edge (loop), init_code);
+
+ remove_edges = xcalloc (max_unroll + n_peel + 1, sizeof (edge));
+ n_remove_edges = 0;
+
+ wont_exit = sbitmap_alloc (max_unroll + 2);
+
+ /* Peel the first copy of loop body (almost always we must leave exit test
+ here; the only exception is when we have extra zero check and the number
+ of iterations is reliable (i.e. comes out of NE condition). Also record
+ the place of (possible) extra zero check. */
+ sbitmap_zero (wont_exit);
+ if (extra_zero_check && desc->cond == NE)
+ SET_BIT (wont_exit, 1);
+ ezc_swtch = loop_preheader_edge (loop)->src;
+ if (!duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
+ loops, 1,
+ wont_exit, desc->out_edge, remove_edges, &n_remove_edges,
+ DLTHE_FLAG_UPDATE_FREQ))
+ abort ();
+
+ /* Record the place where switch will be built for preconditioning. */
+ swtch = loop_split_edge_with (loop_preheader_edge (loop),
+ NULL_RTX);
+
+ for (i = 0; i < n_peel; i++)
+ {
+ /* Peel the copy. */
+ sbitmap_zero (wont_exit);
+ if (i != n_peel - 1 || !last_may_exit)
+ SET_BIT (wont_exit, 1);
+ if (!duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
+ loops, 1,
+ wont_exit, desc->out_edge, remove_edges, &n_remove_edges,
+ DLTHE_FLAG_UPDATE_FREQ))
+ abort ();
+
+ /* Create item for switch. */
+ j = n_peel - i - (extra_zero_check ? 0 : 1);
+ p = REG_BR_PROB_BASE / (i + 2);
+
+ /* If modulo is zero do not jumo to the header of the unrolled loops.
+ Jump instead to the last branch and count that precedes it. */
+ if (is_bct && discard_inc && (j == 0))
+ {
+ basic_block lastbb = loop_preheader_edge(loop)->src;
+ rtx split_after;
+
+ /* Skip dummy basic blocks generated during the unrolling. */
+ while (!is_bct_cond (BB_END (lastbb)))
+ lastbb = lastbb->pred->src;
+
+ split_after = PREV_INSN (BB_END (lastbb));
+
+ preheader = split_loop_bb (lastbb , split_after)->dest;
+ }
+ else
+ preheader = loop_split_edge_with (loop_preheader_edge (loop),
+ NULL_RTX);
+ label = block_label (preheader);
+ start_sequence ();
+ do_compare_rtx_and_jump (copy_rtx (niter), GEN_INT (j), EQ, 0,
+ GET_MODE (desc->var), NULL_RTX, NULL_RTX,
+ label);
+ jump = get_last_insn ();
+ JUMP_LABEL (jump) = label;
+ REG_NOTES (jump)
+ = gen_rtx_EXPR_LIST (REG_BR_PROB,
+ GEN_INT (p), REG_NOTES (jump));
+
+ LABEL_NUSES (label)++;
+ branch_code = get_insns ();
+ end_sequence ();
+
+ swtch = loop_split_edge_with (swtch->pred, branch_code);
+ set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
+ swtch->succ->probability = REG_BR_PROB_BASE - p;
+ e = make_edge (swtch, preheader,
+ swtch->succ->flags & EDGE_IRREDUCIBLE_LOOP);
+ e->probability = p;
+ }
+
+ if (extra_zero_check)
+ {
+ /* Add branch for zero iterations. */
+ p = REG_BR_PROB_BASE / (max_unroll + 1);
+ swtch = ezc_swtch;
+ preheader = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
+ label = block_label (preheader);
+ start_sequence ();
+ do_compare_rtx_and_jump (copy_rtx (niter), const0_rtx, EQ, 0,
+ GET_MODE (desc->var), NULL_RTX, NULL_RTX,
+ label);
+ jump = get_last_insn ();
+ JUMP_LABEL (jump) = label;
+ REG_NOTES (jump)
+ = gen_rtx_EXPR_LIST (REG_BR_PROB,
+ GEN_INT (p), REG_NOTES (jump));
+
+ LABEL_NUSES (label)++;
+ branch_code = get_insns ();
+ end_sequence ();
+
+ swtch = loop_split_edge_with (swtch->succ, branch_code);
+ set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
+ swtch->succ->probability = REG_BR_PROB_BASE - p;
+ e = make_edge (swtch, preheader,
+ swtch->succ->flags & EDGE_IRREDUCIBLE_LOOP);
+ e->probability = p;
+ }
+
+ /* Recount dominators for outer blocks. */
+ iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, n_dom_bbs);
+
+ /* And unroll loop. */
+
+ sbitmap_ones (wont_exit);
+ RESET_BIT (wont_exit, may_exit_copy);
+
+ if (!duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
+ loops, max_unroll,
+ wont_exit, desc->out_edge, remove_edges, &n_remove_edges,
+ DLTHE_FLAG_UPDATE_FREQ))
+ abort ();
+
+ free (wont_exit);
+
+ /* Expand the branch and count. */
+ if (is_bct)
+ for (i = 0; i < n_remove_edges; i++)
+ expand_bct (remove_edges[i], discard_inc);
+
+ /* Remove the edges. */
+ for (i = 0; i < n_remove_edges; i++)
+ remove_path (loops, remove_edges[i]);
+ free (remove_edges);
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ ";; Unrolled loop %d times, counting # of iterations in runtime, %i insns\n",
+ max_unroll, num_loop_insns (loop));
+}
+
+/* Decide whether to simply peel LOOP and how much. */
+static void
+decide_peel_simple (struct loop *loop, int flags)
+{
+ unsigned npeel;
+
+ if (!(flags & UAP_PEEL))
+ {
+ /* We were not asked to, just return back silently. */
+ return;
+ }
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Considering simply peeling loop\n");
+
+ /* npeel = number of iterations to peel. */
+ npeel = PARAM_VALUE (PARAM_MAX_PEELED_INSNS) / loop->ninsns;
+ if (npeel > (unsigned) PARAM_VALUE (PARAM_MAX_PEEL_TIMES))
+ npeel = PARAM_VALUE (PARAM_MAX_PEEL_TIMES);
+
+ /* Skip big loops. */
+ if (!npeel)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not considering loop, is too big\n");
+ return;
+ }
+
+ /* Check for simple loops. */
+ if (!loop->has_desc)
+ {
+ loop->simple = simple_loop_p (loop, &loop->desc);
+ loop->has_desc = 1;
+ }
+
+ /* Check number of iterations. */
+ if (loop->simple && loop->desc.const_iter)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Loop iterates constant times\n");
+ return;
+ }
+
+ /* Do not simply peel loops with branches inside -- it increases number
+ of mispredicts. */
+ if (loop->desc.n_branches > 1)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not peeling, contains branches\n");
+ return;
+ }
+
+ if (loop->header->count)
+ {
+ unsigned niter = expected_loop_iterations (loop);
+ if (niter + 1 > npeel)
+ {
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, ";; Not peeling loop, rolls too much (");
+ fprintf (rtl_dump_file, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) (niter + 1));
+ fprintf (rtl_dump_file, " iterations > %d [maximum peelings])\n", npeel);
+ }
+ return;
+ }
+ npeel = niter + 1;
+ }
+ else
+ {
+ /* For now we have no good heuristics to decide whether loop peeling
+ will be effective, so disable it. */
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ ";; Not peeling loop, no evidence it will be profitable\n");
+ return;
+ }
+
+ /* Success. */
+ loop->lpt_decision.decision = LPT_PEEL_SIMPLE;
+ loop->lpt_decision.times = npeel;
+}
+
+/* Peel a LOOP LOOP->LPT_DECISION.TIMES times. The transformation:
+ while (cond)
+ body;
+
+ ==>
+
+ if (!cond) goto end;
+ body;
+ if (!cond) goto end;
+ body;
+ while (cond)
+ body;
+ end: ;
+ */
+static void
+peel_loop_simple (struct loops *loops, struct loop *loop)
+{
+ sbitmap wont_exit;
+ unsigned npeel = loop->lpt_decision.times;
+
+ wont_exit = sbitmap_alloc (npeel + 1);
+ sbitmap_zero (wont_exit);
+
+ if (!duplicate_loop_to_header_edge (loop, loop_preheader_edge (loop),
+ loops, npeel, wont_exit, NULL, NULL, NULL,
+ DLTHE_FLAG_UPDATE_FREQ))
+ abort ();
+
+ free (wont_exit);
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Peeling loop %d times\n", npeel);
+}
+
+/* Decide whether to unroll LOOP stupidly and how much. */
+static void
+decide_unroll_stupid (struct loop *loop, int flags)
+{
+ unsigned nunroll, nunroll_by_av, i;
+
+ if (!(flags & UAP_UNROLL_ALL))
+ {
+ /* We were not asked to, just return back silently. */
+ return;
+ }
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Considering unrolling loop stupidly\n");
+
+ /* nunroll = total number of copies of the original loop body in
+ unrolled loop (i.e. if it is 2, we have to duplicate loop body once. */
+ nunroll = PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS) / loop->ninsns;
+ nunroll_by_av = PARAM_VALUE (PARAM_MAX_AVERAGE_UNROLLED_INSNS) / loop->av_ninsns;
+ if (nunroll > nunroll_by_av)
+ nunroll = nunroll_by_av;
+ if (nunroll > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLL_TIMES))
+ nunroll = PARAM_VALUE (PARAM_MAX_UNROLL_TIMES);
+
+ /* Skip big loops. */
+ if (nunroll <= 1)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not considering loop, is too big\n");
+ return;
+ }
+
+ /* Check for simple loops. */
+ if (!loop->has_desc)
+ {
+ loop->simple = simple_loop_p (loop, &loop->desc);
+ loop->has_desc = 1;
+ }
+
+ /* Check simpleness. */
+ if (loop->simple)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; The loop is simple\n");
+ return;
+ }
+
+ /* Do not unroll loops with branches inside -- it increases number
+ of mispredicts. */
+ if (loop->desc.n_branches > 1)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not unrolling, contains branches\n");
+ return;
+ }
+
+ /* If we have profile feedback, check whether the loop rolls. */
+ if (loop->header->count && expected_loop_iterations (loop) < 2 * nunroll)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not unrolling loop, doesn't roll\n");
+ return;
+ }
+
+ /* Success. Now force nunroll to be power of 2, as it seems that this
+ improves results (partially because of better alignments, partially
+ because of some dark magic). */
+ for (i = 1; 2 * i <= nunroll; i *= 2);
+
+ loop->lpt_decision.decision = LPT_UNROLL_STUPID;
+ loop->lpt_decision.times = i - 1;
+}
+
+/* Unroll a LOOP LOOP->LPT_DECISION.TIMES times. The transformation:
+ while (cond)
+ body;
+
+ ==>
+
+ while (cond)
+ {
+ body;
+ if (!cond) break;
+ body;
+ if (!cond) break;
+ body;
+ if (!cond) break;
+ body;
+ }
+ */
+static void
+unroll_loop_stupid (struct loops *loops, struct loop *loop)
+{
+ sbitmap wont_exit;
+ unsigned nunroll = loop->lpt_decision.times;
+
+ wont_exit = sbitmap_alloc (nunroll + 1);
+ sbitmap_zero (wont_exit);
+
+ if (!duplicate_loop_to_header_edge (loop, loop_latch_edge (loop),
+ loops, nunroll, wont_exit, NULL, NULL, NULL,
+ DLTHE_FLAG_UPDATE_FREQ))
+ abort ();
+
+ free (wont_exit);
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Unrolled loop %d times, %i insns\n",
+ nunroll, num_loop_insns (loop));
+}
+
+/* Expand a bct instruction in a branch and an increment.
+ If flag_inc is set, the induction variable does not need to be
+ incremented. */
+void expand_bct (edge e, int flag_inc)
+{
+ rtx bct_insn = BB_END (e->src);
+ rtx cmp;
+ rtx inc;
+ rtx seq;
+
+ rtx tgt;
+ rtx condition;
+ rtx label;
+ rtx reg;
+ rtx jump;
+ rtx pattern = PATTERN(bct_insn);
+
+ if (!(is_bct_cond(bct_insn)))
+ return;
+
+ inc = get_var_set_from_bct (bct_insn);
+ cmp = XVECEXP (pattern, 0, 0);
+ reg = SET_DEST (inc);
+
+ start_sequence ();
+ if (!flag_inc)
+ {
+ tgt = force_operand (XEXP (inc, 1), XEXP (inc, 0));
+ if (tgt != XEXP (inc, 0))
+ emit_move_insn (XEXP (inc, 0), tgt);
+ }
+
+ condition = XEXP (SET_SRC (cmp), 0);
+ label = XEXP (SET_SRC (cmp), 1);
+
+ do_compare_rtx_and_jump (copy_rtx (reg), XEXP (condition, 1),
+ GET_CODE (condition), 0,
+ GET_MODE (reg), NULL_RTX, NULL_RTX,
+ label);
+ jump = get_last_insn ();
+ JUMP_LABEL (jump) = label;
+ seq = get_insns ();
+ end_sequence ();
+ emit_insn_after (seq, bct_insn);
+
+ delete_insn (bct_insn);
+
+ return;
+}
+
+/* Check that the increment of the count register can be discarded. */
+bool
+discard_increment (struct loop *loop)
+{
+ struct loop_desc *desc = &loop->desc;
+ rtx inc, set_src, reg;
+ rtx bct_insn;
+ unsigned int i;
+ basic_block *body;
+
+ bct_insn = BB_END (desc->out_edge->src);
+ if (!is_bct_cond (bct_insn))
+ abort();
+
+ inc = get_var_set_from_bct (bct_insn);
+
+ /* Check that inc is of the form reg = reg - 1. */
+ reg = SET_DEST (inc);
+ set_src = SET_SRC (inc);
+
+ if (GET_CODE (set_src) != PLUS)
+ return false;
+
+ if (!rtx_equal_p (XEXP (set_src, 0), reg))
+ return false;
+
+ if (!CONSTANT_P (XEXP (set_src, 1)))
+ return false;
+
+ if (INTVAL (XEXP (set_src, 1)) != -1)
+ return false;
+
+ /* We need to check that the register has no other uses beside the branch and
+ count. */
+ body = get_loop_body (loop);
+ for(i=0; i < loop->num_nodes; i++)
+ {
+ if (reg_mentioned_p (desc->var, BB_HEAD (body[i])))
+ return false;
+
+ if (body[i] != desc->out_edge->src)
+ if (reg_mentioned_p (desc->var, BB_END (body[i])))
+ return false;
+
+ if (reg_used_between_p (desc->var, BB_HEAD (body[i]), BB_END (body[i])))
+ return false;
+ }
+
+ /* Check that the branch and count ends the latch. */
+ if (desc->out_edge->src != loop->latch)
+ {
+ rtx insn;
+
+ /* Latch is a dummy block generated by loop-init. */
+ if (BRANCH_EDGE(desc->out_edge->src)->dest != loop->latch)
+ return false;
+
+ for (insn = BB_HEAD (loop->latch); insn != NEXT_INSN (BB_END (loop->latch));
+ insn = NEXT_INSN (insn))
+ if (INSN_P (insn)) return false;
+ }
+
+ return true;
+}
+
diff --git a/contrib/gcc/loop-unswitch.c b/contrib/gcc/loop-unswitch.c
new file mode 100644
index 000000000000..4cfaa2f62554
--- /dev/null
+++ b/contrib/gcc/loop-unswitch.c
@@ -0,0 +1,409 @@
+/* Loop unswitching for GNU compiler.
+ Copyright (C) 2002, 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "cfgloop.h"
+#include "cfglayout.h"
+#include "params.h"
+#include "output.h"
+#include "expr.h"
+
+/* This pass moves constant conditions out of loops, duplicating the loop
+ in progress, i.e. this code:
+
+ while (loop_cond)
+ {
+ A;
+ if (cond)
+ branch1;
+ else
+ branch2;
+ B;
+ if (cond)
+ branch3;
+ C;
+ }
+ where nothing inside the loop alters cond is transformed
+ into
+
+ if (cond)
+ {
+ while (loop_cond)
+ {
+ A;
+ branch1;
+ B;
+ branch3;
+ C;
+ }
+ }
+ else
+ {
+ while (loop_cond)
+ {
+ A;
+ branch2;
+ B;
+ C;
+ }
+ }
+
+ Duplicating the loop might lead to code growth exponential in number of
+ branches inside loop, so we limit the number of unswitchings performed
+ in a single loop to PARAM_MAX_UNSWITCH_LEVEL. We only perform the
+ transformation on innermost loops, as the benefit of doing it on loops
+ containing subloops would not be very large compared to complications
+ with handling this case. */
+
+static struct loop *unswitch_loop (struct loops *, struct loop *,
+ basic_block);
+static void unswitch_single_loop (struct loops *, struct loop *, rtx, int);
+static bool may_unswitch_on_p (basic_block, struct loop *,
+ basic_block *);
+static rtx reversed_condition (rtx);
+
+/* Main entry point. Perform loop unswitching on all suitable LOOPS. */
+void
+unswitch_loops (struct loops *loops)
+{
+ int i, num;
+ struct loop *loop;
+
+ /* Go through inner loops (only original ones). */
+ num = loops->num;
+
+ for (i = 1; i < num; i++)
+ {
+ /* Removed loop? */
+ loop = loops->parray[i];
+ if (!loop)
+ continue;
+
+ if (loop->inner)
+ continue;
+
+ unswitch_single_loop (loops, loop, NULL_RTX, 0);
+#ifdef ENABLE_CHECKING
+ verify_dominators (CDI_DOMINATORS);
+ verify_loop_structure (loops);
+#endif
+ }
+}
+
+/* Checks whether we can unswitch LOOP on condition at end of BB -- one of its
+ basic blocks (for what it means see comments below). List of basic blocks
+ inside LOOP is provided in BODY to save time. */
+static bool
+may_unswitch_on_p (basic_block bb, struct loop *loop, basic_block *body)
+{
+ rtx test;
+ unsigned i;
+
+ /* BB must end in a simple conditional jump. */
+ if (!bb->succ || !bb->succ->succ_next || bb->succ->succ_next->succ_next)
+ return false;
+ if (!any_condjump_p (BB_END (bb)))
+ return false;
+
+ /* With branches inside loop. */
+ if (!flow_bb_inside_loop_p (loop, bb->succ->dest)
+ || !flow_bb_inside_loop_p (loop, bb->succ->succ_next->dest))
+ return false;
+
+ /* It must be executed just once each iteration (because otherwise we
+ are unable to update dominator/irreducible loop information correctly). */
+ if (!just_once_each_iteration_p (loop, bb))
+ return false;
+
+ /* Condition must be invariant. We use just a stupid test of invariantness
+ of the condition: all used regs must not be modified inside loop body. */
+ test = get_condition (BB_END (bb), NULL, true);
+ if (!test)
+ return false;
+
+ for (i = 0; i < loop->num_nodes; i++)
+ if (modified_between_p (test, BB_HEAD (body[i]), NEXT_INSN (BB_END (body[i]))))
+ return false;
+
+ return true;
+}
+
+/* Reverses CONDition; returns NULL if we cannot. */
+static rtx
+reversed_condition (rtx cond)
+{
+ enum rtx_code reversed;
+ reversed = reversed_comparison_code (cond, NULL);
+ if (reversed == UNKNOWN)
+ return NULL_RTX;
+ else
+ return gen_rtx_fmt_ee (reversed,
+ GET_MODE (cond), XEXP (cond, 0),
+ XEXP (cond, 1));
+}
+
+/* Unswitch single LOOP. COND_CHECKED holds list of conditions we already
+ unswitched on and are therefore known to be true in this LOOP. NUM is
+ number of unswitchings done; do not allow it to grow too much, it is too
+ easy to create example on that the code would grow exponentially. */
+static void
+unswitch_single_loop (struct loops *loops, struct loop *loop,
+ rtx cond_checked, int num)
+{
+ basic_block *bbs, bb;
+ struct loop *nloop;
+ unsigned i;
+ int true_first;
+ rtx cond, rcond, conds, rconds, acond, split_before;
+ int always_true;
+ int always_false;
+ int repeat;
+ edge e;
+
+ /* Do not unswitch too much. */
+ if (num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL))
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not unswitching anymore, hit max level\n");
+ return;
+ }
+
+ /* Only unswitch innermost loops. */
+ if (loop->inner)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not unswitching, not innermost loop\n");
+ return;
+ }
+
+ /* We must be able to duplicate loop body. */
+ if (!can_duplicate_loop_p (loop))
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not unswitching, can't duplicate loop\n");
+ return;
+ }
+
+ /* The loop should not be too large, to limit code growth. */
+ if (num_loop_insns (loop) > PARAM_VALUE (PARAM_MAX_UNSWITCH_INSNS))
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not unswitching, loop too big\n");
+ return;
+ }
+
+ /* Do not unswitch in cold areas. */
+ if (!maybe_hot_bb_p (loop->header))
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not unswitching, not hot area\n");
+ return;
+ }
+
+ /* Nor if the loop usually does not roll. */
+ if (expected_loop_iterations (loop) < 1)
+ {
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Not unswitching, loop iterations < 1\n");
+ return;
+ }
+
+ do
+ {
+ repeat = 0;
+
+ /* Find a bb to unswitch on. */
+ bbs = get_loop_body (loop);
+ for (i = 0; i < loop->num_nodes; i++)
+ if (may_unswitch_on_p (bbs[i], loop, bbs))
+ break;
+
+ if (i == loop->num_nodes)
+ {
+ free (bbs);
+ return;
+ }
+
+ if (!(cond = get_condition (BB_END (bbs[i]), &split_before, true)))
+ abort ();
+ rcond = reversed_condition (cond);
+
+ /* Check whether the result can be predicted. */
+ always_true = 0;
+ always_false = 0;
+ for (acond = cond_checked; acond; acond = XEXP (acond, 1))
+ {
+ if (rtx_equal_p (cond, XEXP (acond, 0)))
+ {
+ always_true = 1;
+ break;
+ }
+ if (rtx_equal_p (rcond, XEXP (acond, 0)))
+ {
+ always_false = 1;
+ break;
+ }
+ }
+
+ if (always_true)
+ {
+ /* Remove false path. */
+ for (e = bbs[i]->succ; !(e->flags & EDGE_FALLTHRU); e = e->succ_next);
+ remove_path (loops, e);
+ free (bbs);
+ repeat = 1;
+ }
+ else if (always_false)
+ {
+ /* Remove true path. */
+ for (e = bbs[i]->succ; e->flags & EDGE_FALLTHRU; e = e->succ_next);
+ remove_path (loops, e);
+ free (bbs);
+ repeat = 1;
+ }
+ } while (repeat);
+
+ /* We found the condition we can unswitch on. */
+ conds = alloc_EXPR_LIST (0, cond, cond_checked);
+ if (rcond)
+ rconds = alloc_EXPR_LIST (0, rcond, cond_checked);
+ else
+ rconds = cond_checked;
+
+ /* Separate condition in a single basic block. */
+ bb = split_loop_bb (bbs[i], PREV_INSN (split_before))->dest;
+ free (bbs);
+ true_first = !(bb->succ->flags & EDGE_FALLTHRU);
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, ";; Unswitching loop\n");
+
+ /* Unswitch the loop on this condition. */
+ nloop = unswitch_loop (loops, loop, bb);
+ if (!nloop)
+ abort ();
+
+ /* Invoke itself on modified loops. */
+ unswitch_single_loop (loops, nloop, true_first ? conds : rconds, num + 1);
+ unswitch_single_loop (loops, loop, true_first ? rconds : conds, num + 1);
+
+ free_EXPR_LIST_node (conds);
+ if (rcond)
+ free_EXPR_LIST_node (rconds);
+}
+
+/* Unswitch a LOOP w.r. to given basic block UNSWITCH_ON. We only support
+ unswitching of innermost loops. UNSWITCH_ON must be executed in every
+ iteration, i.e. it must dominate LOOP latch, and should only contain code
+ for the condition we unswitch on. Returns NULL if impossible, new
+ loop otherwise. */
+static struct loop *
+unswitch_loop (struct loops *loops, struct loop *loop, basic_block unswitch_on)
+{
+ edge entry, latch_edge;
+ basic_block switch_bb, unswitch_on_alt, src;
+ struct loop *nloop;
+ sbitmap zero_bitmap;
+ int irred_flag;
+
+ /* Some sanity checking. */
+ if (!flow_bb_inside_loop_p (loop, unswitch_on))
+ abort ();
+ if (!unswitch_on->succ || !unswitch_on->succ->succ_next ||
+ unswitch_on->succ->succ_next->succ_next)
+ abort ();
+ if (!just_once_each_iteration_p (loop, unswitch_on))
+ abort ();
+ if (loop->inner)
+ abort ();
+ if (!flow_bb_inside_loop_p (loop, unswitch_on->succ->dest))
+ abort ();
+ if (!flow_bb_inside_loop_p (loop, unswitch_on->succ->succ_next->dest))
+ abort ();
+
+ /* Will we be able to perform redirection? */
+ if (!any_condjump_p (BB_END (unswitch_on)))
+ return NULL;
+ if (!cfg_layout_can_duplicate_bb_p (unswitch_on))
+ return NULL;
+
+ entry = loop_preheader_edge (loop);
+
+ /* Make a copy. */
+ src = entry->src;
+ irred_flag = entry->flags & EDGE_IRREDUCIBLE_LOOP;
+ entry->flags &= ~EDGE_IRREDUCIBLE_LOOP;
+ zero_bitmap = sbitmap_alloc (2);
+ sbitmap_zero (zero_bitmap);
+ if (!duplicate_loop_to_header_edge (loop, entry, loops, 1,
+ zero_bitmap, NULL, NULL, NULL, 0))
+ return NULL;
+ free (zero_bitmap);
+ entry->flags |= irred_flag;
+
+ /* Record the block with condition we unswitch on. */
+ unswitch_on_alt = unswitch_on->rbi->copy;
+
+ /* Make a copy of the block containing the condition; we will use
+ it as switch to decide which loop we want to use. */
+ switch_bb = cfg_layout_duplicate_bb (unswitch_on, NULL);
+ if (irred_flag)
+ {
+ switch_bb->flags |= BB_IRREDUCIBLE_LOOP;
+ switch_bb->succ->flags |= EDGE_IRREDUCIBLE_LOOP;
+ switch_bb->succ->succ_next->flags |= EDGE_IRREDUCIBLE_LOOP;
+ }
+ else
+ {
+ switch_bb->flags &= ~BB_IRREDUCIBLE_LOOP;
+ switch_bb->succ->flags &= ~EDGE_IRREDUCIBLE_LOOP;
+ switch_bb->succ->succ_next->flags &= ~EDGE_IRREDUCIBLE_LOOP;
+ }
+ add_to_dominance_info (CDI_DOMINATORS, switch_bb);
+ unswitch_on->rbi->copy = unswitch_on_alt;
+
+ /* Loopify from the copy of LOOP body, constructing the new loop. */
+ for (latch_edge = loop->latch->rbi->copy->succ;
+ latch_edge->dest != loop->header;
+ latch_edge = latch_edge->succ_next);
+ nloop = loopify (loops, latch_edge,
+ loop->header->rbi->copy->pred, switch_bb);
+
+ /* Remove branches that are now unreachable in new loops. We rely on the
+ fact that cfg_layout_duplicate_bb reverses list of edges. */
+ remove_path (loops, unswitch_on->succ);
+ remove_path (loops, unswitch_on_alt->succ);
+
+ /* One of created loops do not have to be subloop of the outer loop now,
+ so fix its placement in loop data structure. */
+ fix_loop_placement (loop);
+ fix_loop_placement (nloop);
+
+ /* Preserve the simple loop preheaders. */
+ loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
+ loop_split_edge_with (loop_preheader_edge (nloop), NULL_RTX);
+
+ return nloop;
+}
diff --git a/contrib/gcc/loop.c b/contrib/gcc/loop.c
index c0888fa6ce28..5a47309b8e99 100644
--- a/contrib/gcc/loop.c
+++ b/contrib/gcc/loop.c
@@ -1,6 +1,6 @@
/* Perform various loop optimizations, including strength reduction.
Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,8 +22,16 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* This is the loop optimization pass of the compiler.
It finds invariant computations within loops and moves them
to the beginning of the loop. Then it identifies basic and
- general induction variables. Strength reduction is applied to the general
- induction variables, and induction variable elimination is applied to
+ general induction variables.
+
+ Basic induction variables (BIVs) are a pseudo registers which are set within
+ a loop only by incrementing or decrementing its value. General induction
+ variables (GIVs) are pseudo registers with a value which is a linear function
+ of a basic induction variable. BIVs are recognized by `basic_induction_var';
+ GIVs by `general_induction_var'.
+
+ Once induction variables are identified, strength reduction is applied to the
+ general induction variables, and induction variable elimination is applied to
the basic induction variables.
It also finds cases where
@@ -36,6 +44,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "function.h"
@@ -54,6 +64,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "predict.h"
#include "insn-flags.h"
#include "optabs.h"
+#include "cfgloop.h"
+#include "ggc.h"
/* Not really meaningful values, but at least something. */
#ifndef SIMULTANEOUS_PREFETCHES
@@ -68,7 +80,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define gen_prefetch(a,b,c) (abort(), NULL_RTX)
#endif
-/* Give up the prefetch optimizations once we exceed a given threshhold.
+/* Give up the prefetch optimizations once we exceed a given threshold.
It is unlikely that we would be able to optimize something in a loop
with so many detected prefetches. */
#define MAX_PREFETCHES 100
@@ -80,7 +92,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define PREFETCH_BLOCKS_BEFORE_LOOP_MIN 2
/* Parameterize some prefetch heuristics so they can be turned on and off
- easily for performance testing on new architecures. These can be
+ easily for performance testing on new architectures. These can be
defined in target-dependent files. */
/* Prefetch is worthwhile only when loads/stores are dense. */
@@ -169,10 +181,6 @@ struct loop **uid_loop;
int max_uid_for_loop;
-/* 1 + luid of last insn. */
-
-static int max_luid;
-
/* Number of loops detected in current function. Used as index to the
next few tables. */
@@ -205,6 +213,9 @@ struct movable
short savings; /* Number of insns we can move for this reg,
including other movables that force this
or match this one. */
+ ENUM_BITFIELD(machine_mode) savemode : 8; /* Nonzero means it is a mode for
+ a low part that we should avoid changing when
+ clearing the rest of the reg. */
unsigned int cond : 1; /* 1 if only conditionally movable */
unsigned int force : 1; /* 1 means MUST move this insn */
unsigned int global : 1; /* 1 means reg is live outside this loop */
@@ -221,9 +232,9 @@ struct movable
unsigned int move_insn_first:1;/* Same as above, if this is necessary for the
first insn of a consecutive sets group. */
unsigned int is_equiv : 1; /* 1 means a REG_EQUIV is present on INSN. */
- enum machine_mode savemode; /* Nonzero means it is a mode for a low part
- that we should avoid changing when clearing
- the rest of the reg. */
+ unsigned int insert_temp : 1; /* 1 means we copy to a new pseudo and replace
+ the original insn with a copy from that
+ pseudo, rather than deleting it. */
struct movable *match; /* First entry for same value */
struct movable *forces; /* An insn that must be moved if this is */
struct movable *next;
@@ -234,140 +245,121 @@ FILE *loop_dump_stream;
/* Forward declarations. */
-static void invalidate_loops_containing_label PARAMS ((rtx));
-static void find_and_verify_loops PARAMS ((rtx, struct loops *));
-static void mark_loop_jump PARAMS ((rtx, struct loop *));
-static void prescan_loop PARAMS ((struct loop *));
-static int reg_in_basic_block_p PARAMS ((rtx, rtx));
-static int consec_sets_invariant_p PARAMS ((const struct loop *,
- rtx, int, rtx));
-static int labels_in_range_p PARAMS ((rtx, int));
-static void count_one_set PARAMS ((struct loop_regs *, rtx, rtx, rtx *));
-static void note_addr_stored PARAMS ((rtx, rtx, void *));
-static void note_set_pseudo_multiple_uses PARAMS ((rtx, rtx, void *));
-static int loop_reg_used_before_p PARAMS ((const struct loop *, rtx, rtx));
-static void scan_loop PARAMS ((struct loop*, int));
+static void invalidate_loops_containing_label (rtx);
+static void find_and_verify_loops (rtx, struct loops *);
+static void mark_loop_jump (rtx, struct loop *);
+static void prescan_loop (struct loop *);
+static int reg_in_basic_block_p (rtx, rtx);
+static int consec_sets_invariant_p (const struct loop *, rtx, int, rtx);
+static int labels_in_range_p (rtx, int);
+static void count_one_set (struct loop_regs *, rtx, rtx, rtx *);
+static void note_addr_stored (rtx, rtx, void *);
+static void note_set_pseudo_multiple_uses (rtx, rtx, void *);
+static int loop_reg_used_before_p (const struct loop *, rtx, rtx);
+static rtx find_regs_nested (rtx, rtx);
+static void scan_loop (struct loop*, int);
#if 0
-static void replace_call_address PARAMS ((rtx, rtx, rtx));
+static void replace_call_address (rtx, rtx, rtx);
#endif
-static rtx skip_consec_insns PARAMS ((rtx, int));
-static int libcall_benefit PARAMS ((rtx));
-static void ignore_some_movables PARAMS ((struct loop_movables *));
-static void force_movables PARAMS ((struct loop_movables *));
-static void combine_movables PARAMS ((struct loop_movables *,
- struct loop_regs *));
-static int num_unmoved_movables PARAMS ((const struct loop *));
-static int regs_match_p PARAMS ((rtx, rtx, struct loop_movables *));
-static int rtx_equal_for_loop_p PARAMS ((rtx, rtx, struct loop_movables *,
- struct loop_regs *));
-static void add_label_notes PARAMS ((rtx, rtx));
-static void move_movables PARAMS ((struct loop *loop, struct loop_movables *,
- int, int));
-static void loop_movables_add PARAMS((struct loop_movables *,
- struct movable *));
-static void loop_movables_free PARAMS((struct loop_movables *));
-static int count_nonfixed_reads PARAMS ((const struct loop *, rtx));
-static void loop_bivs_find PARAMS((struct loop *));
-static void loop_bivs_init_find PARAMS((struct loop *));
-static void loop_bivs_check PARAMS((struct loop *));
-static void loop_givs_find PARAMS((struct loop *));
-static void loop_givs_check PARAMS((struct loop *));
-static int loop_biv_eliminable_p PARAMS((struct loop *, struct iv_class *,
- int, int));
-static int loop_giv_reduce_benefit PARAMS((struct loop *, struct iv_class *,
- struct induction *, rtx));
-static void loop_givs_dead_check PARAMS((struct loop *, struct iv_class *));
-static void loop_givs_reduce PARAMS((struct loop *, struct iv_class *));
-static void loop_givs_rescan PARAMS((struct loop *, struct iv_class *,
- rtx *));
-static void loop_ivs_free PARAMS((struct loop *));
-static void strength_reduce PARAMS ((struct loop *, int));
-static void find_single_use_in_loop PARAMS ((struct loop_regs *, rtx, rtx));
-static int valid_initial_value_p PARAMS ((rtx, rtx, int, rtx));
-static void find_mem_givs PARAMS ((const struct loop *, rtx, rtx, int, int));
-static void record_biv PARAMS ((struct loop *, struct induction *,
- rtx, rtx, rtx, rtx, rtx *,
- int, int));
-static void check_final_value PARAMS ((const struct loop *,
- struct induction *));
-static void loop_ivs_dump PARAMS((const struct loop *, FILE *, int));
-static void loop_iv_class_dump PARAMS((const struct iv_class *, FILE *, int));
-static void loop_biv_dump PARAMS((const struct induction *, FILE *, int));
-static void loop_giv_dump PARAMS((const struct induction *, FILE *, int));
-static void record_giv PARAMS ((const struct loop *, struct induction *,
- rtx, rtx, rtx, rtx, rtx, rtx, int,
- enum g_types, int, int, rtx *));
-static void update_giv_derive PARAMS ((const struct loop *, rtx));
-static void check_ext_dependent_givs PARAMS ((struct iv_class *,
- struct loop_info *));
-static int basic_induction_var PARAMS ((const struct loop *, rtx,
- enum machine_mode, rtx, rtx,
- rtx *, rtx *, rtx **));
-static rtx simplify_giv_expr PARAMS ((const struct loop *, rtx, rtx *, int *));
-static int general_induction_var PARAMS ((const struct loop *loop, rtx, rtx *,
- rtx *, rtx *, rtx *, int, int *,
- enum machine_mode));
-static int consec_sets_giv PARAMS ((const struct loop *, int, rtx,
- rtx, rtx, rtx *, rtx *, rtx *, rtx *));
-static int check_dbra_loop PARAMS ((struct loop *, int));
-static rtx express_from_1 PARAMS ((rtx, rtx, rtx));
-static rtx combine_givs_p PARAMS ((struct induction *, struct induction *));
-static int cmp_combine_givs_stats PARAMS ((const PTR, const PTR));
-static void combine_givs PARAMS ((struct loop_regs *, struct iv_class *));
-static int product_cheap_p PARAMS ((rtx, rtx));
-static int maybe_eliminate_biv PARAMS ((const struct loop *, struct iv_class *,
- int, int, int));
-static int maybe_eliminate_biv_1 PARAMS ((const struct loop *, rtx, rtx,
- struct iv_class *, int,
- basic_block, rtx));
-static int last_use_this_basic_block PARAMS ((rtx, rtx));
-static void record_initial PARAMS ((rtx, rtx, void *));
-static void update_reg_last_use PARAMS ((rtx, rtx));
-static rtx next_insn_in_loop PARAMS ((const struct loop *, rtx));
-static void loop_regs_scan PARAMS ((const struct loop *, int));
-static int count_insns_in_loop PARAMS ((const struct loop *));
-static int find_mem_in_note_1 PARAMS ((rtx *, void *));
-static rtx find_mem_in_note PARAMS ((rtx));
-static void load_mems PARAMS ((const struct loop *));
-static int insert_loop_mem PARAMS ((rtx *, void *));
-static int replace_loop_mem PARAMS ((rtx *, void *));
-static void replace_loop_mems PARAMS ((rtx, rtx, rtx, int));
-static int replace_loop_reg PARAMS ((rtx *, void *));
-static void replace_loop_regs PARAMS ((rtx insn, rtx, rtx));
-static void note_reg_stored PARAMS ((rtx, rtx, void *));
-static void try_copy_prop PARAMS ((const struct loop *, rtx, unsigned int));
-static void try_swap_copy_prop PARAMS ((const struct loop *, rtx,
- unsigned int));
-static int replace_label PARAMS ((rtx *, void *));
-static rtx check_insn_for_givs PARAMS((struct loop *, rtx, int, int));
-static rtx check_insn_for_bivs PARAMS((struct loop *, rtx, int, int));
-static rtx gen_add_mult PARAMS ((rtx, rtx, rtx, rtx));
-static void loop_regs_update PARAMS ((const struct loop *, rtx));
-static int iv_add_mult_cost PARAMS ((rtx, rtx, rtx, rtx));
-
-static rtx loop_insn_emit_after PARAMS((const struct loop *, basic_block,
- rtx, rtx));
-static rtx loop_call_insn_emit_before PARAMS((const struct loop *,
- basic_block, rtx, rtx));
-static rtx loop_call_insn_hoist PARAMS((const struct loop *, rtx));
-static rtx loop_insn_sink_or_swim PARAMS((const struct loop *, rtx));
-
-static void loop_dump_aux PARAMS ((const struct loop *, FILE *, int));
-static void loop_delete_insns PARAMS ((rtx, rtx));
-static HOST_WIDE_INT remove_constant_addition PARAMS ((rtx *));
-static rtx gen_load_of_final_value PARAMS ((rtx, rtx));
-void debug_ivs PARAMS ((const struct loop *));
-void debug_iv_class PARAMS ((const struct iv_class *));
-void debug_biv PARAMS ((const struct induction *));
-void debug_giv PARAMS ((const struct induction *));
-void debug_loop PARAMS ((const struct loop *));
-void debug_loops PARAMS ((const struct loops *));
-
-typedef struct rtx_pair
-{
- rtx r1;
- rtx r2;
-} rtx_pair;
+static rtx skip_consec_insns (rtx, int);
+static int libcall_benefit (rtx);
+static void ignore_some_movables (struct loop_movables *);
+static void force_movables (struct loop_movables *);
+static void combine_movables (struct loop_movables *, struct loop_regs *);
+static int num_unmoved_movables (const struct loop *);
+static int regs_match_p (rtx, rtx, struct loop_movables *);
+static int rtx_equal_for_loop_p (rtx, rtx, struct loop_movables *,
+ struct loop_regs *);
+static void add_label_notes (rtx, rtx);
+static void move_movables (struct loop *loop, struct loop_movables *, int,
+ int);
+static void loop_movables_add (struct loop_movables *, struct movable *);
+static void loop_movables_free (struct loop_movables *);
+static int count_nonfixed_reads (const struct loop *, rtx);
+static void loop_bivs_find (struct loop *);
+static void loop_bivs_init_find (struct loop *);
+static void loop_bivs_check (struct loop *);
+static void loop_givs_find (struct loop *);
+static void loop_givs_check (struct loop *);
+static int loop_biv_eliminable_p (struct loop *, struct iv_class *, int, int);
+static int loop_giv_reduce_benefit (struct loop *, struct iv_class *,
+ struct induction *, rtx);
+static void loop_givs_dead_check (struct loop *, struct iv_class *);
+static void loop_givs_reduce (struct loop *, struct iv_class *);
+static void loop_givs_rescan (struct loop *, struct iv_class *, rtx *);
+static void loop_ivs_free (struct loop *);
+static void strength_reduce (struct loop *, int);
+static void find_single_use_in_loop (struct loop_regs *, rtx, rtx);
+static int valid_initial_value_p (rtx, rtx, int, rtx);
+static void find_mem_givs (const struct loop *, rtx, rtx, int, int);
+static void record_biv (struct loop *, struct induction *, rtx, rtx, rtx,
+ rtx, rtx *, int, int);
+static void check_final_value (const struct loop *, struct induction *);
+static void loop_ivs_dump (const struct loop *, FILE *, int);
+static void loop_iv_class_dump (const struct iv_class *, FILE *, int);
+static void loop_biv_dump (const struct induction *, FILE *, int);
+static void loop_giv_dump (const struct induction *, FILE *, int);
+static void record_giv (const struct loop *, struct induction *, rtx, rtx,
+ rtx, rtx, rtx, rtx, int, enum g_types, int, int,
+ rtx *);
+static void update_giv_derive (const struct loop *, rtx);
+static void check_ext_dependent_givs (const struct loop *, struct iv_class *);
+static int basic_induction_var (const struct loop *, rtx, enum machine_mode,
+ rtx, rtx, rtx *, rtx *, rtx **);
+static rtx simplify_giv_expr (const struct loop *, rtx, rtx *, int *);
+static int general_induction_var (const struct loop *loop, rtx, rtx *, rtx *,
+ rtx *, rtx *, int, int *, enum machine_mode);
+static int consec_sets_giv (const struct loop *, int, rtx, rtx, rtx, rtx *,
+ rtx *, rtx *, rtx *);
+static int check_dbra_loop (struct loop *, int);
+static rtx express_from_1 (rtx, rtx, rtx);
+static rtx combine_givs_p (struct induction *, struct induction *);
+static int cmp_combine_givs_stats (const void *, const void *);
+static void combine_givs (struct loop_regs *, struct iv_class *);
+static int product_cheap_p (rtx, rtx);
+static int maybe_eliminate_biv (const struct loop *, struct iv_class *, int,
+ int, int);
+static int maybe_eliminate_biv_1 (const struct loop *, rtx, rtx,
+ struct iv_class *, int, basic_block, rtx);
+static int last_use_this_basic_block (rtx, rtx);
+static void record_initial (rtx, rtx, void *);
+static void update_reg_last_use (rtx, rtx);
+static rtx next_insn_in_loop (const struct loop *, rtx);
+static void loop_regs_scan (const struct loop *, int);
+static int count_insns_in_loop (const struct loop *);
+static int find_mem_in_note_1 (rtx *, void *);
+static rtx find_mem_in_note (rtx);
+static void load_mems (const struct loop *);
+static int insert_loop_mem (rtx *, void *);
+static int replace_loop_mem (rtx *, void *);
+static void replace_loop_mems (rtx, rtx, rtx, int);
+static int replace_loop_reg (rtx *, void *);
+static void replace_loop_regs (rtx insn, rtx, rtx);
+static void note_reg_stored (rtx, rtx, void *);
+static void try_copy_prop (const struct loop *, rtx, unsigned int);
+static void try_swap_copy_prop (const struct loop *, rtx, unsigned int);
+static rtx check_insn_for_givs (struct loop *, rtx, int, int);
+static rtx check_insn_for_bivs (struct loop *, rtx, int, int);
+static rtx gen_add_mult (rtx, rtx, rtx, rtx);
+static void loop_regs_update (const struct loop *, rtx);
+static int iv_add_mult_cost (rtx, rtx, rtx, rtx);
+
+static rtx loop_insn_emit_after (const struct loop *, basic_block, rtx, rtx);
+static rtx loop_call_insn_emit_before (const struct loop *, basic_block,
+ rtx, rtx);
+static rtx loop_call_insn_hoist (const struct loop *, rtx);
+static rtx loop_insn_sink_or_swim (const struct loop *, rtx);
+
+static void loop_dump_aux (const struct loop *, FILE *, int);
+static void loop_delete_insns (rtx, rtx);
+static HOST_WIDE_INT remove_constant_addition (rtx *);
+static rtx gen_load_of_final_value (rtx, rtx);
+void debug_ivs (const struct loop *);
+void debug_iv_class (const struct iv_class *);
+void debug_biv (const struct induction *);
+void debug_giv (const struct induction *);
+void debug_loop (const struct loop *);
+void debug_loops (const struct loops *);
typedef struct loop_replace_args
{
@@ -384,13 +376,12 @@ typedef struct loop_replace_args
/* Indirect_jump_in_function is computed once per function. */
static int indirect_jump_in_function;
-static int indirect_jump_in_function_p PARAMS ((rtx));
+static int indirect_jump_in_function_p (rtx);
-static int compute_luids PARAMS ((rtx, rtx, int));
+static int compute_luids (rtx, rtx, int);
-static int biv_elimination_giv_has_0_offset PARAMS ((struct induction *,
- struct induction *,
- rtx));
+static int biv_elimination_giv_has_0_offset (struct induction *,
+ struct induction *, rtx);
/* Benefit penalty, if a giv is not replaceable, i.e. must emit an insn to
copy the value of the strength reduced giv to its original register. */
@@ -400,7 +391,7 @@ static int copy_cost;
static int reg_address_cost;
void
-init_loop ()
+init_loop (void)
{
rtx reg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
@@ -415,9 +406,7 @@ init_loop ()
Start at insn START and stop just before END. Assign LUIDs
starting with PREV_LUID + 1. Return the last assigned LUID + 1. */
static int
-compute_luids (start, end, prev_luid)
- rtx start, end;
- int prev_luid;
+compute_luids (rtx start, rtx end, int prev_luid)
{
int i;
rtx insn;
@@ -444,11 +433,7 @@ compute_luids (start, end, prev_luid)
(or 0 if none should be output). */
void
-loop_optimize (f, dumpfile, flags)
- /* f is the first instruction of a chain of insns for one function */
- rtx f;
- FILE *dumpfile;
- int flags;
+loop_optimize (rtx f, FILE *dumpfile, int flags)
{
rtx insn;
int i;
@@ -485,13 +470,11 @@ loop_optimize (f, dumpfile, flags)
Leave some space for labels allocated by find_and_verify_loops. */
max_uid_for_loop = get_max_uid () + 1 + max_loop_num * 32;
- uid_luid = (int *) xcalloc (max_uid_for_loop, sizeof (int));
- uid_loop = (struct loop **) xcalloc (max_uid_for_loop,
- sizeof (struct loop *));
+ uid_luid = xcalloc (max_uid_for_loop, sizeof (int));
+ uid_loop = xcalloc (max_uid_for_loop, sizeof (struct loop *));
/* Allocate storage for array of loops. */
- loops->array = (struct loop *)
- xcalloc (loops->num, sizeof (struct loop));
+ loops->array = xcalloc (loops->num, sizeof (struct loop));
/* Find and process each loop.
First, find them, and record them in order of their beginnings. */
@@ -499,7 +482,7 @@ loop_optimize (f, dumpfile, flags)
/* Allocate and initialize auxiliary loop information. */
loops_info = xcalloc (loops->num, sizeof (struct loop_info));
- for (i = 0; i < loops->num; i++)
+ for (i = 0; i < (int) loops->num; i++)
loops->array[i].aux = loops_info + i;
/* Now find all register lifetimes. This must be done after
@@ -524,7 +507,7 @@ loop_optimize (f, dumpfile, flags)
/* find_and_verify_loops has already called compute_luids, but it
might have rearranged code afterwards, so we need to recompute
the luids now. */
- max_luid = compute_luids (f, NULL_RTX, 0);
+ compute_luids (f, NULL_RTX, 0);
/* Don't leave gaps in uid_luid for insns that have been
deleted. It is possible that the first or last insn
@@ -552,12 +535,18 @@ loop_optimize (f, dumpfile, flags)
struct loop *loop = &loops->array[i];
if (! loop->invalid && loop->end)
- scan_loop (loop, flags);
+ {
+ scan_loop (loop, flags);
+ ggc_collect ();
+ }
}
end_alias_analysis ();
/* Clean up. */
+ for (i = 0; i < (int) loops->num; i++)
+ free (loops_info[i].mems);
+
free (uid_luid);
free (uid_loop);
free (loops_info);
@@ -571,9 +560,7 @@ loop_optimize (f, dumpfile, flags)
bottom. */
static rtx
-next_insn_in_loop (loop, insn)
- const struct loop *loop;
- rtx insn;
+next_insn_in_loop (const struct loop *loop, rtx insn)
{
insn = NEXT_INSN (insn);
@@ -594,6 +581,32 @@ next_insn_in_loop (loop, insn)
return insn;
}
+/* Find any register references hidden inside X and add them to
+ the dependency list DEPS. This is used to look inside CLOBBER (MEM
+ when checking whether a PARALLEL can be pulled out of a loop. */
+
+static rtx
+find_regs_nested (rtx deps, rtx x)
+{
+ enum rtx_code code = GET_CODE (x);
+ if (code == REG)
+ deps = gen_rtx_EXPR_LIST (VOIDmode, x, deps);
+ else
+ {
+ const char *fmt = GET_RTX_FORMAT (code);
+ int i, j;
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ deps = find_regs_nested (deps, XEXP (x, i));
+ else if (fmt[i] == 'E')
+ for (j = 0; j < XVECLEN (x, i); j++)
+ deps = find_regs_nested (deps, XVECEXP (x, i, j));
+ }
+ }
+ return deps;
+}
+
/* Optimize one loop described by LOOP. */
/* ??? Could also move memory writes out of loops if the destination address
@@ -603,9 +616,7 @@ next_insn_in_loop (loop, insn)
write, then we can also mark the memory read as invariant. */
static void
-scan_loop (loop, flags)
- struct loop *loop;
- int flags;
+scan_loop (struct loop *loop, int flags)
{
struct loop_info *loop_info = LOOP_INFO (loop);
struct loop_regs *regs = LOOP_REGS (loop);
@@ -618,8 +629,6 @@ scan_loop (loop, flags)
/* 1 if we are scanning insns that might never be executed
due to a subroutine call which might exit before they are reached. */
int call_passed = 0;
- /* Jump insn that enters the loop, or 0 if control drops in. */
- rtx loop_entry_jump = 0;
/* Number of insns in the loop. */
int insn_count;
int tem;
@@ -687,24 +696,20 @@ scan_loop (loop, flags)
Start scan from there.
But record in LOOP->TOP the place where the end-test jumps
back to so we can scan that after the end of the loop. */
- if (GET_CODE (p) == JUMP_INSN)
- {
- loop_entry_jump = p;
-
+ if (GET_CODE (p) == JUMP_INSN
/* Loop entry must be unconditional jump (and not a RETURN) */
- if (any_uncondjump_p (p)
- && JUMP_LABEL (p) != 0
- /* Check to see whether the jump actually
- jumps out of the loop (meaning it's no loop).
- This case can happen for things like
- do {..} while (0). If this label was generated previously
- by loop, we can't tell anything about it and have to reject
- the loop. */
- && INSN_IN_RANGE_P (JUMP_LABEL (p), loop_start, loop_end))
- {
- loop->top = next_label (loop->scan_start);
- loop->scan_start = JUMP_LABEL (p);
- }
+ && any_uncondjump_p (p)
+ && JUMP_LABEL (p) != 0
+ /* Check to see whether the jump actually
+ jumps out of the loop (meaning it's no loop).
+ This case can happen for things like
+ do {..} while (0). If this label was generated previously
+ by loop, we can't tell anything about it and have to reject
+ the loop. */
+ && INSN_IN_RANGE_P (JUMP_LABEL (p), loop_start, loop_end))
+ {
+ loop->top = next_label (loop->scan_start);
+ loop->scan_start = JUMP_LABEL (p);
}
/* If LOOP->SCAN_START was an insn created by loop, we don't know its luid
@@ -774,6 +779,7 @@ scan_loop (loop, flags)
int tem1 = 0;
int tem2 = 0;
int move_insn = 0;
+ int insert_temp = 0;
rtx src = SET_SRC (set);
rtx dependencies = 0;
@@ -803,8 +809,10 @@ scan_loop (loop, flags)
}
}
- /* For parallels, add any possible uses to the depencies, as
- we can't move the insn without resolving them first. */
+ /* For parallels, add any possible uses to the dependencies, as
+ we can't move the insn without resolving them first.
+ MEMs inside CLOBBERs may also reference registers; these
+ count as implicit uses. */
if (GET_CODE (PATTERN (p)) == PARALLEL)
{
for (i = 0; i < XVECLEN (PATTERN (p), 0); i++)
@@ -814,9 +822,39 @@ scan_loop (loop, flags)
dependencies
= gen_rtx_EXPR_LIST (VOIDmode, XEXP (x, 0),
dependencies);
+ else if (GET_CODE (x) == CLOBBER
+ && GET_CODE (XEXP (x, 0)) == MEM)
+ dependencies = find_regs_nested (dependencies,
+ XEXP (XEXP (x, 0), 0));
}
}
+ if (/* The register is used in basic blocks other
+ than the one where it is set (meaning that
+ something after this point in the loop might
+ depend on its value before the set). */
+ ! reg_in_basic_block_p (p, SET_DEST (set))
+ /* And the set is not guaranteed to be executed once
+ the loop starts, or the value before the set is
+ needed before the set occurs...
+
+ ??? Note we have quadratic behavior here, mitigated
+ by the fact that the previous test will often fail for
+ large loops. Rather than re-scanning the entire loop
+ each time for register usage, we should build tables
+ of the register usage and use them here instead. */
+ && (maybe_never
+ || loop_reg_used_before_p (loop, set, p)))
+ /* It is unsafe to move the set. However, it may be OK to
+ move the source into a new pseudo, and substitute a
+ reg-to-reg copy for the original insn.
+
+ This code used to consider it OK to move a set of a variable
+ which was not created by the user and not used in an exit
+ test.
+ That behavior is incorrect and was removed. */
+ insert_temp = 1;
+
/* Don't try to optimize a MODE_CC set with a constant
source. It probably will be combined with a conditional
jump. */
@@ -829,28 +867,17 @@ scan_loop (loop, flags)
the benefit. */
else if (REGNO (SET_DEST (set)) >= max_reg_before_loop)
;
- else if (/* The register is used in basic blocks other
- than the one where it is set (meaning that
- something after this point in the loop might
- depend on its value before the set). */
- ! reg_in_basic_block_p (p, SET_DEST (set))
- /* And the set is not guaranteed to be executed once
- the loop starts, or the value before the set is
- needed before the set occurs...
-
- ??? Note we have quadratic behavior here, mitigated
- by the fact that the previous test will often fail for
- large loops. Rather than re-scanning the entire loop
- each time for register usage, we should build tables
- of the register usage and use them here instead. */
- && (maybe_never
- || loop_reg_used_before_p (loop, set, p)))
- /* It is unsafe to move the set.
-
- This code used to consider it OK to move a set of a variable
- which was not created by the user and not used in an exit
- test.
- That behavior is incorrect and was removed. */
+ /* Don't move the source and add a reg-to-reg copy:
+ - with -Os (this certainly increases size),
+ - if the mode doesn't support copy operations (obviously),
+ - if the source is already a reg (the motion will gain nothing),
+ - if the source is a legitimate constant (likewise). */
+ else if (insert_temp
+ && (optimize_size
+ || ! can_copy_p (GET_MODE (SET_SRC (set)))
+ || GET_CODE (SET_SRC (set)) == REG
+ || (CONSTANT_P (SET_SRC (set))
+ && LEGITIMATE_CONSTANT_P (SET_SRC (set)))))
;
else if ((tem = loop_invariant_p (loop, src))
&& (dependencies == 0
@@ -902,6 +929,7 @@ scan_loop (loop, flags)
|| (! (GET_CODE (SET_SRC (set)) == REG
&& (REGNO (SET_SRC (set))
< FIRST_PSEUDO_REGISTER))))
+ && regno >= FIRST_PSEUDO_REGISTER
/* This test is not redundant; SET_SRC (set) might be
a call-clobbered register and the life of REGNO
might span a call. */
@@ -927,7 +955,7 @@ scan_loop (loop, flags)
continue;
}
- m = (struct movable *) xmalloc (sizeof (struct movable));
+ m = xmalloc (sizeof (struct movable));
m->next = 0;
m->insn = p;
m->set_src = src;
@@ -941,6 +969,7 @@ scan_loop (loop, flags)
m->partial = 0;
m->move_insn = move_insn;
m->move_insn_first = 0;
+ m->insert_temp = insert_temp;
m->is_equiv = (find_reg_note (p, REG_EQUIV, NULL_RTX) != 0);
m->savemode = VOIDmode;
m->regno = regno;
@@ -1014,7 +1043,7 @@ scan_loop (loop, flags)
if (regs->array[regno].set_in_loop == 2)
{
struct movable *m;
- m = (struct movable *) xmalloc (sizeof (struct movable));
+ m = xmalloc (sizeof (struct movable));
m->next = 0;
m->insn = p;
m->set_dest = SET_DEST (set);
@@ -1025,6 +1054,7 @@ scan_loop (loop, flags)
m->forces = 0;
m->move_insn = 0;
m->move_insn_first = 0;
+ m->insert_temp = insert_temp;
m->partial = 1;
/* If the insn may not be executed on some cycles,
we can't clear the whole reg; clear just high part.
@@ -1123,10 +1153,12 @@ scan_loop (loop, flags)
/* Now consider each movable insn to decide whether it is worth moving.
Store 0 in regs->array[I].set_in_loop for each reg I that is moved.
- Generally this increases code size, so do not move moveables when
- optimizing for code size. */
+ For machines with few registers this increases code size, so do not
+ move moveables when optimizing for code size on such machines.
+ (The 18 below is the value for i386.) */
- if (! optimize_size)
+ if (!optimize_size
+ || (reg_class_size[GENERAL_REGS] > 18 && !loop_info->has_call))
{
move_movables (loop, movables, threshold, insn_count);
@@ -1201,9 +1233,7 @@ scan_loop (loop, flags)
mentioned in IN_THIS but not mentioned in NOT_IN_THIS. */
void
-record_excess_regs (in_this, not_in_this, output)
- rtx in_this, not_in_this;
- rtx *output;
+record_excess_regs (rtx in_this, rtx not_in_this, rtx *output)
{
enum rtx_code code;
const char *fmt;
@@ -1257,8 +1287,7 @@ record_excess_regs (in_this, not_in_this, output)
If there are one or more, return an EXPR_LIST containing all of them. */
rtx
-libcall_other_reg (insn, equiv)
- rtx insn, equiv;
+libcall_other_reg (rtx insn, rtx equiv)
{
rtx note = find_reg_note (insn, REG_RETVAL, NULL_RTX);
rtx p = XEXP (note, 0);
@@ -1282,8 +1311,7 @@ libcall_other_reg (insn, equiv)
are between INSN and the end of the basic block. */
static int
-reg_in_basic_block_p (insn, reg)
- rtx insn, reg;
+reg_in_basic_block_p (rtx insn, rtx reg)
{
int regno = REGNO (reg);
rtx p;
@@ -1336,8 +1364,7 @@ reg_in_basic_block_p (insn, reg)
value directly or can contain a library call. */
static int
-libcall_benefit (last)
- rtx last;
+libcall_benefit (rtx last)
{
rtx insn;
int benefit = 0;
@@ -1360,9 +1387,7 @@ libcall_benefit (last)
/* Skip COUNT insns from INSN, counting library calls as 1 insn. */
static rtx
-skip_consec_insns (insn, count)
- rtx insn;
- int count;
+skip_consec_insns (rtx insn, int count)
{
for (; count > 0; count--)
{
@@ -1389,8 +1414,7 @@ skip_consec_insns (insn, count)
was made later and so appears later on the chain. */
static void
-ignore_some_movables (movables)
- struct loop_movables *movables;
+ignore_some_movables (struct loop_movables *movables)
{
struct movable *m, *m1;
@@ -1421,8 +1445,7 @@ ignore_some_movables (movables)
since the second can be moved only if the first is. */
static void
-force_movables (movables)
- struct loop_movables *movables;
+force_movables (struct loop_movables *movables)
{
struct movable *m, *m1;
@@ -1447,12 +1470,18 @@ force_movables (movables)
m = 0;
/* Increase the priority of the moving the first insn
- since it permits the second to be moved as well. */
+ since it permits the second to be moved as well.
+ Likewise for insns already forced by the first insn. */
if (m != 0)
{
+ struct movable *m2;
+
m->forces = m1;
- m1->lifetime += m->lifetime;
- m1->savings += m->savings;
+ for (m2 = m1; m2; m2 = m2->forces)
+ {
+ m2->lifetime += m->lifetime;
+ m2->savings += m->savings;
+ }
}
}
}
@@ -1461,12 +1490,10 @@ force_movables (movables)
one register. */
static void
-combine_movables (movables, regs)
- struct loop_movables *movables;
- struct loop_regs *regs;
+combine_movables (struct loop_movables *movables, struct loop_regs *regs)
{
struct movable *m;
- char *matched_regs = (char *) xmalloc (regs->num);
+ char *matched_regs = xmalloc (regs->num);
enum machine_mode mode;
/* Regs that are set more than once are not allowed to match
@@ -1478,6 +1505,7 @@ combine_movables (movables, regs)
for (m = movables->head; m; m = m->next)
if (m->match == 0 && regs->array[m->regno].n_times_set == 1
&& m->regno >= FIRST_PSEUDO_REGISTER
+ && !m->insert_temp
&& !m->partial)
{
struct movable *m1;
@@ -1490,6 +1518,7 @@ combine_movables (movables, regs)
one match any later ones. So start this loop at m->next. */
for (m1 = m->next; m1; m1 = m1->next)
if (m != m1 && m1->match == 0
+ && !m1->insert_temp
&& regs->array[m1->regno].n_times_set == 1
&& m1->regno >= FIRST_PSEUDO_REGISTER
/* A reg used outside the loop mustn't be eliminated. */
@@ -1586,8 +1615,7 @@ combine_movables (movables, regs)
moved outside the loop. */
static int
-num_unmoved_movables (loop)
- const struct loop *loop;
+num_unmoved_movables (const struct loop *loop)
{
int num = 0;
struct movable *m;
@@ -1603,9 +1631,7 @@ num_unmoved_movables (loop)
/* Return 1 if regs X and Y will become the same if moved. */
static int
-regs_match_p (x, y, movables)
- rtx x, y;
- struct loop_movables *movables;
+regs_match_p (rtx x, rtx y, struct loop_movables *movables)
{
unsigned int xn = REGNO (x);
unsigned int yn = REGNO (y);
@@ -1632,10 +1658,8 @@ regs_match_p (x, y, movables)
equivalent constant, consider them equal. */
static int
-rtx_equal_for_loop_p (x, y, movables, regs)
- rtx x, y;
- struct loop_movables *movables;
- struct loop_regs *regs;
+rtx_equal_for_loop_p (rtx x, rtx y, struct loop_movables *movables,
+ struct loop_regs *regs)
{
int i;
int j;
@@ -1751,9 +1775,7 @@ rtx_equal_for_loop_p (x, y, movables, regs)
references is incremented once for each added note. */
static void
-add_label_notes (x, insns)
- rtx x;
- rtx insns;
+add_label_notes (rtx x, rtx insns)
{
enum rtx_code code = GET_CODE (x);
int i, j;
@@ -1763,7 +1785,7 @@ add_label_notes (x, insns)
if (code == LABEL_REF && !LABEL_REF_NONLOCAL_P (x))
{
/* This code used to ignore labels that referred to dispatch tables to
- avoid flow generating (slighly) worse code.
+ avoid flow generating (slightly) worse code.
We no longer ignore such label references (see LABEL_REF handling in
mark_jump_label for additional information). */
@@ -1793,11 +1815,8 @@ add_label_notes (x, insns)
other throughout. */
static void
-move_movables (loop, movables, threshold, insn_count)
- struct loop *loop;
- struct loop_movables *movables;
- int threshold;
- int insn_count;
+move_movables (struct loop *loop, struct loop_movables *movables,
+ int threshold, int insn_count)
{
struct loop_regs *regs = LOOP_REGS (loop);
int nregs = regs->num;
@@ -1809,8 +1828,8 @@ move_movables (loop, movables, threshold, insn_count)
/* Map of pseudo-register replacements to handle combining
when we move several insns that load the same value
into different pseudo-registers. */
- rtx *reg_map = (rtx *) xcalloc (nregs, sizeof (rtx));
- char *already_moved = (char *) xcalloc (nregs, sizeof (char));
+ rtx *reg_map = xcalloc (nregs, sizeof (rtx));
+ char *already_moved = xcalloc (nregs, sizeof (char));
for (m = movables->head; m; m = m->next)
{
@@ -1893,6 +1912,10 @@ move_movables (loop, movables, threshold, insn_count)
int count;
struct movable *m1;
rtx first = NULL_RTX;
+ rtx newreg = NULL_RTX;
+
+ if (m->insert_temp)
+ newreg = gen_reg_rtx (GET_MODE (m->set_dest));
/* Now move the insns that set the reg. */
@@ -1963,10 +1986,22 @@ move_movables (loop, movables, threshold, insn_count)
insn stream. */
while (p && GET_CODE (p) == NOTE)
p = NEXT_INSN (temp) = NEXT_INSN (p);
+
+ if (m->insert_temp)
+ {
+ /* Replace the original insn with a move from
+ our newly created temp. */
+ start_sequence ();
+ emit_move_insn (m->set_dest, newreg);
+ seq = get_insns ();
+ end_sequence ();
+ emit_insn_before (seq, p);
+ }
}
start_sequence ();
- emit_move_insn (m->set_dest, m->set_src);
+ emit_move_insn (m->insert_temp ? newreg : m->set_dest,
+ m->set_src);
seq = get_insns ();
end_sequence ();
@@ -2125,7 +2160,8 @@ move_movables (loop, movables, threshold, insn_count)
/* The SET_SRC might not be invariant, so we must
use the REG_EQUAL note. */
start_sequence ();
- emit_move_insn (m->set_dest, m->set_src);
+ emit_move_insn (m->insert_temp ? newreg : m->set_dest,
+ m->set_src);
seq = get_insns ();
end_sequence ();
@@ -2136,6 +2172,16 @@ move_movables (loop, movables, threshold, insn_count)
set_unique_reg_note (i1, m->is_equiv ? REG_EQUIV
: REG_EQUAL, m->set_src);
}
+ else if (m->insert_temp)
+ {
+ rtx *reg_map2 = xcalloc (REGNO (newreg),
+ sizeof(rtx));
+ reg_map2 [m->regno] = newreg;
+
+ i1 = loop_insn_hoist (loop, copy_rtx (PATTERN (p)));
+ replace_regs (i1, reg_map2, REGNO (newreg), 1);
+ free (reg_map2);
+ }
else
i1 = loop_insn_hoist (loop, PATTERN (p));
@@ -2184,40 +2230,55 @@ move_movables (loop, movables, threshold, insn_count)
insn stream. */
while (p && GET_CODE (p) == NOTE)
p = NEXT_INSN (temp) = NEXT_INSN (p);
+
+ if (m->insert_temp)
+ {
+ rtx seq;
+ /* Replace the original insn with a move from
+ our newly created temp. */
+ start_sequence ();
+ emit_move_insn (m->set_dest, newreg);
+ seq = get_insns ();
+ end_sequence ();
+ emit_insn_before (seq, p);
+ }
}
/* The more regs we move, the less we like moving them. */
threshold -= 3;
}
- /* Any other movable that loads the same register
- MUST be moved. */
- already_moved[regno] = 1;
-
- /* This reg has been moved out of one loop. */
- regs->array[regno].moved_once = 1;
+ m->done = 1;
- /* The reg set here is now invariant. */
- if (! m->partial)
+ if (!m->insert_temp)
{
- int i;
- for (i = 0; i < LOOP_REGNO_NREGS (regno, m->set_dest); i++)
- regs->array[regno+i].set_in_loop = 0;
- }
+ /* Any other movable that loads the same register
+ MUST be moved. */
+ already_moved[regno] = 1;
- m->done = 1;
+ /* This reg has been moved out of one loop. */
+ regs->array[regno].moved_once = 1;
- /* Change the length-of-life info for the register
- to say it lives at least the full length of this loop.
- This will help guide optimizations in outer loops. */
+ /* The reg set here is now invariant. */
+ if (! m->partial)
+ {
+ int i;
+ for (i = 0; i < LOOP_REGNO_NREGS (regno, m->set_dest); i++)
+ regs->array[regno+i].set_in_loop = 0;
+ }
- if (REGNO_FIRST_LUID (regno) > INSN_LUID (loop_start))
- /* This is the old insn before all the moved insns.
- We can't use the moved insn because it is out of range
- in uid_luid. Only the old insns have luids. */
- REGNO_FIRST_UID (regno) = INSN_UID (loop_start);
- if (REGNO_LAST_LUID (regno) < INSN_LUID (loop_end))
- REGNO_LAST_UID (regno) = INSN_UID (loop_end);
+ /* Change the length-of-life info for the register
+ to say it lives at least the full length of this loop.
+ This will help guide optimizations in outer loops. */
+
+ if (REGNO_FIRST_LUID (regno) > INSN_LUID (loop_start))
+ /* This is the old insn before all the moved insns.
+ We can't use the moved insn because it is out of range
+ in uid_luid. Only the old insns have luids. */
+ REGNO_FIRST_UID (regno) = INSN_UID (loop_start);
+ if (REGNO_LAST_LUID (regno) < INSN_LUID (loop_end))
+ REGNO_LAST_UID (regno) = INSN_UID (loop_end);
+ }
/* Combine with this moved insn any other matching movables. */
@@ -2249,7 +2310,7 @@ move_movables (loop, movables, threshold, insn_count)
and prevent further processing of it. */
m1->done = 1;
- /* if library call, delete all insns. */
+ /* If library call, delete all insns. */
if ((temp = find_reg_note (m1->insn, REG_RETVAL,
NULL_RTX)))
delete_insn_chain (XEXP (temp, 0), m1->insn);
@@ -2303,9 +2364,7 @@ move_movables (loop, movables, threshold, insn_count)
static void
-loop_movables_add (movables, m)
- struct loop_movables *movables;
- struct movable *m;
+loop_movables_add (struct loop_movables *movables, struct movable *m)
{
if (movables->head == 0)
movables->head = m;
@@ -2316,8 +2375,7 @@ loop_movables_add (movables, m)
static void
-loop_movables_free (movables)
- struct loop_movables *movables;
+loop_movables_free (struct loop_movables *movables)
{
struct movable *m;
struct movable *m_next;
@@ -2334,8 +2392,7 @@ loop_movables_free (movables)
REG is the address that MEM should have before the replacement. */
static void
-replace_call_address (x, reg, addr)
- rtx x, reg, addr;
+replace_call_address (rtx x, rtx reg, rtx addr)
{
enum rtx_code code;
int i;
@@ -2397,9 +2454,7 @@ replace_call_address (x, reg, addr)
in the rtx X. */
static int
-count_nonfixed_reads (loop, x)
- const struct loop *loop;
- rtx x;
+count_nonfixed_reads (const struct loop *loop, rtx x)
{
enum rtx_code code;
int i;
@@ -2453,8 +2508,7 @@ count_nonfixed_reads (loop, x)
list `store_mems' in LOOP. */
static void
-prescan_loop (loop)
- struct loop *loop;
+prescan_loop (struct loop *loop)
{
int level = 1;
rtx insn;
@@ -2523,6 +2577,30 @@ prescan_loop (loop)
loop_info->has_call = 1;
if (can_throw_internal (insn))
loop_info->has_multiple_exit_targets = 1;
+
+ /* Calls initializing constant objects have CLOBBER of MEM /u in the
+ attached FUNCTION_USAGE expression list, not accounted for by the
+ code above. We should note these to avoid missing dependencies in
+ later references. */
+ {
+ rtx fusage_entry;
+
+ for (fusage_entry = CALL_INSN_FUNCTION_USAGE (insn);
+ fusage_entry; fusage_entry = XEXP (fusage_entry, 1))
+ {
+ rtx fusage = XEXP (fusage_entry, 0);
+
+ if (GET_CODE (fusage) == CLOBBER
+ && GET_CODE (XEXP (fusage, 0)) == MEM
+ && RTX_UNCHANGING_P (XEXP (fusage, 0)))
+ {
+ note_stores (fusage, note_addr_stored, loop_info);
+ if (! loop_info->first_loop_store_insn
+ && loop_info->store_mems)
+ loop_info->first_loop_store_insn = insn;
+ }
+ }
+ }
break;
case JUMP_INSN:
@@ -2576,7 +2654,7 @@ prescan_loop (loop)
loop_info->has_multiple_exit_targets = 1;
}
}
- /* FALLTHRU */
+ /* Fall through. */
case INSN:
if (volatile_refs_p (PATTERN (insn)))
@@ -2639,8 +2717,7 @@ prescan_loop (loop)
/* Invalidate all loops containing LABEL. */
static void
-invalidate_loops_containing_label (label)
- rtx label;
+invalidate_loops_containing_label (rtx label)
{
struct loop *loop;
for (loop = uid_loop[INSN_UID (label)]; loop; loop = loop->outer)
@@ -2652,9 +2729,7 @@ invalidate_loops_containing_label (label)
to from outside the loop. */
static void
-find_and_verify_loops (f, loops)
- rtx f;
- struct loops *loops;
+find_and_verify_loops (rtx f, struct loops *loops)
{
rtx insn;
rtx label;
@@ -2990,9 +3065,7 @@ find_and_verify_loops (f, loops)
For speed, we assume that X is part of a pattern of a JUMP_INSN. */
static void
-mark_loop_jump (x, loop)
- rtx x;
- struct loop *loop;
+mark_loop_jump (rtx x, struct loop *loop)
{
struct loop *dest_loop;
struct loop *outer_loop;
@@ -3138,9 +3211,7 @@ mark_loop_jump (x, loop)
been previously created by loop.c). */
static int
-labels_in_range_p (insn, end)
- rtx insn;
- int end;
+labels_in_range_p (rtx insn, int end)
{
while (insn && INSN_LUID (insn) <= end)
{
@@ -3155,10 +3226,8 @@ labels_in_range_p (insn, end)
/* Record that a memory reference X is being set. */
static void
-note_addr_stored (x, y, data)
- rtx x;
- rtx y ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+note_addr_stored (rtx x, rtx y ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
{
struct loop_info *loop_info = data;
@@ -3190,10 +3259,7 @@ note_addr_stored (x, y, data)
used more than once. DATA is a pointer to a loop_regs structure. */
static void
-note_set_pseudo_multiple_uses (x, y, data)
- rtx x;
- rtx y ATTRIBUTE_UNUSED;
- void *data;
+note_set_pseudo_multiple_uses (rtx x, rtx y ATTRIBUTE_UNUSED, void *data)
{
struct loop_regs *regs = (struct loop_regs *) data;
@@ -3225,9 +3291,7 @@ note_set_pseudo_multiple_uses (x, y, data)
with anything stored in `loop_info->store_mems'. */
int
-loop_invariant_p (loop, x)
- const struct loop *loop;
- rtx x;
+loop_invariant_p (const struct loop *loop, rtx x)
{
struct loop_info *loop_info = LOOP_INFO (loop);
struct loop_regs *regs = LOOP_REGS (loop);
@@ -3258,7 +3322,7 @@ loop_invariant_p (loop, x)
We don't know the loop bounds here though, so just fail for all
labels. */
- if (flag_unroll_loops)
+ if (flag_old_unroll_loops)
return 0;
else
return 1;
@@ -3282,8 +3346,14 @@ loop_invariant_p (loop, x)
return 0;
/* Out-of-range regs can occur when we are called from unrolling.
- These have always been created by the unroller and are set in
- the loop, hence are never invariant. */
+ These registers created by the unroller are set in the loop,
+ hence are never invariant.
+ Other out-of-range regs can be generated by load_mems; those that
+ are written to in the loop are not invariant, while those that are
+ not written to are invariant. It would be easy for load_mems
+ to set n_times_set correctly for these registers, however, there
+ is no easy way to distinguish them from registers created by the
+ unroller. */
if (REGNO (x) >= (unsigned) regs->num)
return 0;
@@ -3365,10 +3435,8 @@ loop_invariant_p (loop, x)
and that its source is invariant. */
static int
-consec_sets_invariant_p (loop, reg, n_sets, insn)
- const struct loop *loop;
- int n_sets;
- rtx reg, insn;
+consec_sets_invariant_p (const struct loop *loop, rtx reg, int n_sets,
+ rtx insn)
{
struct loop_regs *regs = LOOP_REGS (loop);
rtx p = insn;
@@ -3441,9 +3509,7 @@ consec_sets_invariant_p (loop, reg, n_sets, insn)
that set REG are invariant according to TABLE. */
static int
-all_sets_invariant_p (reg, insn, table)
- rtx reg, insn;
- short *table;
+all_sets_invariant_p (rtx reg, rtx insn, short *table)
{
rtx p = insn;
int regno = REGNO (reg);
@@ -3471,10 +3537,7 @@ all_sets_invariant_p (reg, insn, table)
a different insn, set USAGE[REGNO] to const0_rtx. */
static void
-find_single_use_in_loop (regs, insn, x)
- struct loop_regs *regs;
- rtx insn;
- rtx x;
+find_single_use_in_loop (struct loop_regs *regs, rtx insn, rtx x)
{
enum rtx_code code = GET_CODE (x);
const char *fmt = GET_RTX_FORMAT (code);
@@ -3512,10 +3575,7 @@ find_single_use_in_loop (regs, insn, x)
in X. */
static void
-count_one_set (regs, insn, x, last_set)
- struct loop_regs *regs;
- rtx insn, x;
- rtx *last_set;
+count_one_set (struct loop_regs *regs, rtx insn, rtx x, rtx *last_set)
{
if (GET_CODE (x) == CLOBBER && GET_CODE (XEXP (x, 0)) == REG)
/* Don't move a reg that has an explicit clobber.
@@ -3541,7 +3601,7 @@ count_one_set (regs, insn, x, last_set)
it must be set in two basic blocks, so it cannot
be moved out of the loop. */
if (regs->array[regno].set_in_loop > 0
- && last_set == 0)
+ && last_set[regno] == 0)
regs->array[regno+i].may_not_optimize = 1;
/* If this is not first setting in current basic block,
see if reg was used in between previous one and this.
@@ -3567,9 +3627,7 @@ count_one_set (regs, insn, x, last_set)
from an inner loop past two loops. */
static int
-loop_reg_used_before_p (loop, set, insn)
- const struct loop *loop;
- rtx set, insn;
+loop_reg_used_before_p (const struct loop *loop, rtx set, rtx insn)
{
rtx reg = SET_DEST (set);
rtx p;
@@ -3617,16 +3675,14 @@ struct check_store_data
int mem_write;
};
-static void check_store PARAMS ((rtx, rtx, void *));
-static void emit_prefetch_instructions PARAMS ((struct loop *));
-static int rtx_equal_for_prefetch_p PARAMS ((rtx, rtx));
+static void check_store (rtx, rtx, void *);
+static void emit_prefetch_instructions (struct loop *);
+static int rtx_equal_for_prefetch_p (rtx, rtx);
/* Set mem_write when mem_address is found. Used as callback to
note_stores. */
static void
-check_store (x, pat, data)
- rtx x, pat ATTRIBUTE_UNUSED;
- void *data;
+check_store (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
{
struct check_store_data *d = (struct check_store_data *) data;
@@ -3636,14 +3692,13 @@ check_store (x, pat, data)
/* Like rtx_equal_p, but attempts to swap commutative operands. This is
important to get some addresses combined. Later more sophisticated
- transformations can be added when necesary.
+ transformations can be added when necessary.
??? Same trick with swapping operand is done at several other places.
It can be nice to develop some common way to handle this. */
static int
-rtx_equal_for_prefetch_p (x, y)
- rtx x, y;
+rtx_equal_for_prefetch_p (rtx x, rtx y)
{
int i;
int j;
@@ -3725,8 +3780,7 @@ rtx_equal_for_prefetch_p (x, y)
and return it. */
static HOST_WIDE_INT
-remove_constant_addition (x)
- rtx *x;
+remove_constant_addition (rtx *x)
{
HOST_WIDE_INT addval = 0;
rtx exp = *x;
@@ -3788,8 +3842,7 @@ remove_constant_addition (x)
controlled by defined symbols that can be overridden for each target. */
static void
-emit_prefetch_instructions (loop)
- struct loop *loop;
+emit_prefetch_instructions (struct loop *loop)
{
int num_prefetches = 0;
int num_real_prefetches = 0;
@@ -4121,11 +4174,9 @@ emit_prefetch_instructions (loop)
" density: %d%%; bytes_accessed: %u; total_bytes: %u\n",
(int) (info[i].bytes_accessed * 100 / info[i].stride),
info[i].bytes_accessed, info[i].total_bytes);
- fprintf (loop_dump_stream, " index: ");
- fprintf (loop_dump_stream, HOST_WIDE_INT_PRINT_DEC, info[i].index);
- fprintf (loop_dump_stream, "; stride: ");
- fprintf (loop_dump_stream, HOST_WIDE_INT_PRINT_DEC, info[i].stride);
- fprintf (loop_dump_stream, "; address: ");
+ fprintf (loop_dump_stream, " index: " HOST_WIDE_INT_PRINT_DEC
+ "; stride: " HOST_WIDE_INT_PRINT_DEC "; address: ",
+ info[i].index, info[i].stride);
print_rtl (loop_dump_stream, info[i].base_address);
fprintf (loop_dump_stream, "\n");
}
@@ -4166,8 +4217,8 @@ emit_prefetch_instructions (loop)
{
rtx reg = gen_reg_rtx (Pmode);
loop_iv_add_mult_emit_before (loop, loc, const1_rtx,
- GEN_INT (bytes_ahead), reg,
- 0, before_insn);
+ GEN_INT (bytes_ahead), reg,
+ 0, before_insn);
loc = reg;
}
@@ -4234,14 +4285,6 @@ emit_prefetch_instructions (loop)
return;
}
-/* A "basic induction variable" or biv is a pseudo reg that is set
- (within this loop) only by incrementing or decrementing it. */
-/* A "general induction variable" or giv is a pseudo reg whose
- value is a linear function of a biv. */
-
-/* Bivs are recognized by `basic_induction_var';
- Givs by `general_induction_var'. */
-
/* Communication with routines called via `note_stores'. */
static rtx note_insn;
@@ -4288,9 +4331,7 @@ static rtx addr_placeholder;
loop iteration.
*/
void
-for_each_insn_in_loop (loop, fncall)
- struct loop *loop;
- loop_insn_callback fncall;
+for_each_insn_in_loop (struct loop *loop, loop_insn_callback fncall)
{
int not_every_iteration = 0;
int maybe_multiple = 0;
@@ -4428,8 +4469,7 @@ for_each_insn_in_loop (loop, fncall)
}
static void
-loop_bivs_find (loop)
- struct loop *loop;
+loop_bivs_find (struct loop *loop)
{
struct loop_regs *regs = LOOP_REGS (loop);
struct loop_ivs *ivs = LOOP_IVS (loop);
@@ -4477,8 +4517,7 @@ loop_bivs_find (loop)
/* Determine how BIVS are initialized by looking through pre-header
extended basic block. */
static void
-loop_bivs_init_find (loop)
- struct loop *loop;
+loop_bivs_init_find (struct loop *loop)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
/* Temporary list pointers for traversing ivs->list. */
@@ -4533,8 +4572,7 @@ loop_bivs_init_find (loop)
initial value from any initializing insns set up above. (This is done
in two passes to avoid missing SETs in a PARALLEL.) */
static void
-loop_bivs_check (loop)
- struct loop *loop;
+loop_bivs_check (struct loop *loop)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
/* Temporary list pointers for traversing ivs->list. */
@@ -4589,8 +4627,7 @@ loop_bivs_check (loop)
/* Search the loop for general induction variables. */
static void
-loop_givs_find (loop)
- struct loop* loop;
+loop_givs_find (struct loop* loop)
{
for_each_insn_in_loop (loop, check_insn_for_givs);
}
@@ -4601,8 +4638,7 @@ loop_givs_find (loop)
can be calculated. */
static void
-loop_givs_check (loop)
- struct loop *loop;
+loop_givs_check (struct loop *loop)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
struct iv_class *bl;
@@ -4624,11 +4660,8 @@ loop_givs_check (loop)
be. */
static int
-loop_biv_eliminable_p (loop, bl, threshold, insn_count)
- struct loop *loop;
- struct iv_class *bl;
- int threshold;
- int insn_count;
+loop_biv_eliminable_p (struct loop *loop, struct iv_class *bl,
+ int threshold, int insn_count)
{
/* For architectures with a decrement_and_branch_until_zero insn,
don't do this if we put a REG_NONNEG note on the endtest for this
@@ -4676,9 +4709,7 @@ loop_biv_eliminable_p (loop, bl, threshold, insn_count)
/* Reduce each giv of BL that we have decided to reduce. */
static void
-loop_givs_reduce (loop, bl)
- struct loop *loop;
- struct iv_class *bl;
+loop_givs_reduce (struct loop *loop, struct iv_class *bl)
{
struct induction *v;
@@ -4815,9 +4846,7 @@ loop_givs_reduce (loop, bl)
eliminate a biv. */
static void
-loop_givs_dead_check (loop, bl)
- struct loop *loop ATTRIBUTE_UNUSED;
- struct iv_class *bl;
+loop_givs_dead_check (struct loop *loop ATTRIBUTE_UNUSED, struct iv_class *bl)
{
struct induction *v;
@@ -4841,10 +4870,7 @@ loop_givs_dead_check (loop, bl)
static void
-loop_givs_rescan (loop, bl, reg_map)
- struct loop *loop;
- struct iv_class *bl;
- rtx *reg_map;
+loop_givs_rescan (struct loop *loop, struct iv_class *bl, rtx *reg_map)
{
struct induction *v;
@@ -4920,13 +4946,13 @@ loop_givs_rescan (loop, bl, reg_map)
gen_move_insn (v->dest_reg,
v->new_reg));
- /* The original insn may have a REG_EQUAL note. This note is
- now incorrect and may result in invalid substitutions later.
- The original insn is dead, but may be part of a libcall
- sequence, which doesn't seem worth the bother of handling. */
- note = find_reg_note (original_insn, REG_EQUAL, NULL_RTX);
- if (note)
- remove_note (original_insn, note);
+ /* The original insn may have a REG_EQUAL note. This note is
+ now incorrect and may result in invalid substitutions later.
+ The original insn is dead, but may be part of a libcall
+ sequence, which doesn't seem worth the bother of handling. */
+ note = find_reg_note (original_insn, REG_EQUAL, NULL_RTX);
+ if (note)
+ remove_note (original_insn, note);
}
/* When a loop is reversed, givs which depend on the reversed
@@ -4955,11 +4981,9 @@ loop_givs_rescan (loop, bl, reg_map)
static int
-loop_giv_reduce_benefit (loop, bl, v, test_reg)
- struct loop *loop ATTRIBUTE_UNUSED;
- struct iv_class *bl;
- struct induction *v;
- rtx test_reg;
+loop_giv_reduce_benefit (struct loop *loop ATTRIBUTE_UNUSED,
+ struct iv_class *bl, struct induction *v,
+ rtx test_reg)
{
int add_cost;
int benefit;
@@ -5032,8 +5056,7 @@ loop_giv_reduce_benefit (loop, bl, v, test_reg)
/* Free IV structures for LOOP. */
static void
-loop_ivs_free (loop)
- struct loop *loop;
+loop_ivs_free (struct loop *loop)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
struct iv_class *iv = ivs->list;
@@ -5073,9 +5096,7 @@ loop_ivs_free (loop)
must check regnos to make sure they are in bounds. */
static void
-strength_reduce (loop, flags)
- struct loop *loop;
- int flags;
+strength_reduce (struct loop *loop, int flags)
{
struct loop_info *loop_info = LOOP_INFO (loop);
struct loop_regs *regs = LOOP_REGS (loop);
@@ -5099,7 +5120,7 @@ strength_reduce (loop, flags)
addr_placeholder = gen_reg_rtx (Pmode);
ivs->n_regs = max_reg_before_loop;
- ivs->regs = (struct iv *) xcalloc (ivs->n_regs, sizeof (struct iv));
+ ivs->regs = xcalloc (ivs->n_regs, sizeof (struct iv));
/* Find all BIVs in loop. */
loop_bivs_find (loop);
@@ -5153,7 +5174,7 @@ strength_reduce (loop, flags)
Some givs might have been made from biv increments, so look at
ivs->reg_iv_type for a suitable size. */
reg_map_size = ivs->n_regs;
- reg_map = (rtx *) xcalloc (reg_map_size, sizeof (rtx));
+ reg_map = xcalloc (reg_map_size, sizeof (rtx));
/* Examine each iv class for feasibility of strength reduction/induction
variable elimination. */
@@ -5174,7 +5195,7 @@ strength_reduce (loop, flags)
/* Check each extension dependent giv in this class to see if its
root biv is safe from wrapping in the interior mode. */
- check_ext_dependent_givs (bl, loop_info);
+ check_ext_dependent_givs (loop, bl);
/* Combine all giv's for this iv_class. */
combine_givs (regs, bl);
@@ -5389,11 +5410,8 @@ strength_reduce (loop, flags)
/*Record all basic induction variables calculated in the insn. */
static rtx
-check_insn_for_bivs (loop, p, not_every_iteration, maybe_multiple)
- struct loop *loop;
- rtx p;
- int not_every_iteration;
- int maybe_multiple;
+check_insn_for_bivs (struct loop *loop, rtx p, int not_every_iteration,
+ int maybe_multiple)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
rtx set;
@@ -5419,8 +5437,7 @@ check_insn_for_bivs (loop, p, not_every_iteration, maybe_multiple)
/* It is a possible basic induction variable.
Create and initialize an induction structure for it. */
- struct induction *v
- = (struct induction *) xmalloc (sizeof (struct induction));
+ struct induction *v = xmalloc (sizeof (struct induction));
record_biv (loop, v, p, dest_reg, inc_val, mult_val, location,
not_every_iteration, maybe_multiple);
@@ -5437,11 +5454,8 @@ check_insn_for_bivs (loop, p, not_every_iteration, maybe_multiple)
A register is a giv if: it is only set once, it is a function of a
biv and a constant (or invariant), and it is not a biv. */
static rtx
-check_insn_for_givs (loop, p, not_every_iteration, maybe_multiple)
- struct loop *loop;
- rtx p;
- int not_every_iteration;
- int maybe_multiple;
+check_insn_for_givs (struct loop *loop, rtx p, int not_every_iteration,
+ int maybe_multiple)
{
struct loop_regs *regs = LOOP_REGS (loop);
@@ -5486,8 +5500,7 @@ check_insn_for_givs (loop, p, not_every_iteration, maybe_multiple)
&add_val, &mult_val, &ext_val,
&last_consec_insn))))
{
- struct induction *v
- = (struct induction *) xmalloc (sizeof (struct induction));
+ struct induction *v = xmalloc (sizeof (struct induction));
/* If this is a library call, increase benefit. */
if (find_reg_note (p, REG_RETVAL, NULL_RTX))
@@ -5504,14 +5517,10 @@ check_insn_for_givs (loop, p, not_every_iteration, maybe_multiple)
}
}
-#ifndef DONT_REDUCE_ADDR
/* Look for givs which are memory addresses. */
- /* This resulted in worse code on a VAX 8600. I wonder if it
- still does. */
if (GET_CODE (p) == INSN)
find_mem_givs (loop, PATTERN (p), p, not_every_iteration,
maybe_multiple);
-#endif
/* Update the status of whether giv can derive other givs. This can
change when we pass a label or an insn that updates a biv. */
@@ -5530,11 +5539,7 @@ check_insn_for_givs (loop, p, not_every_iteration, maybe_multiple)
INSN is the insn containing X. */
static int
-valid_initial_value_p (x, insn, call_seen, loop_start)
- rtx x;
- rtx insn;
- int call_seen;
- rtx loop_start;
+valid_initial_value_p (rtx x, rtx insn, int call_seen, rtx loop_start)
{
if (CONSTANT_P (x))
return 1;
@@ -5564,14 +5569,11 @@ valid_initial_value_p (x, insn, call_seen, loop_start)
as a possible giv. INSN is the insn whose pattern X comes from.
NOT_EVERY_ITERATION is 1 if the insn might not be executed during
every loop iteration. MAYBE_MULTIPLE is 1 if the insn might be executed
- more thanonce in each loop iteration. */
+ more than once in each loop iteration. */
static void
-find_mem_givs (loop, x, insn, not_every_iteration, maybe_multiple)
- const struct loop *loop;
- rtx x;
- rtx insn;
- int not_every_iteration, maybe_multiple;
+find_mem_givs (const struct loop *loop, rtx x, rtx insn,
+ int not_every_iteration, int maybe_multiple)
{
int i, j;
enum rtx_code code;
@@ -5615,8 +5617,7 @@ find_mem_givs (loop, x, insn, not_every_iteration, maybe_multiple)
GET_MODE (x)))
{
/* Found one; record it. */
- struct induction *v
- = (struct induction *) xmalloc (sizeof (struct induction));
+ struct induction *v = xmalloc (sizeof (struct induction));
record_giv (loop, v, insn, src_reg, addr_placeholder, mult_val,
add_val, ext_val, benefit, DEST_ADDR,
@@ -5661,17 +5662,9 @@ find_mem_givs (loop, x, insn, not_every_iteration, maybe_multiple)
executed exactly once per iteration. */
static void
-record_biv (loop, v, insn, dest_reg, inc_val, mult_val, location,
- not_every_iteration, maybe_multiple)
- struct loop *loop;
- struct induction *v;
- rtx insn;
- rtx dest_reg;
- rtx inc_val;
- rtx mult_val;
- rtx *location;
- int not_every_iteration;
- int maybe_multiple;
+record_biv (struct loop *loop, struct induction *v, rtx insn, rtx dest_reg,
+ rtx inc_val, rtx mult_val, rtx *location,
+ int not_every_iteration, int maybe_multiple)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
struct iv_class *bl;
@@ -5697,7 +5690,7 @@ record_biv (loop, v, insn, dest_reg, inc_val, mult_val, location,
{
/* Create and initialize new iv_class. */
- bl = (struct iv_class *) xmalloc (sizeof (struct iv_class));
+ bl = xmalloc (sizeof (struct iv_class));
bl->regno = REGNO (dest_reg);
bl->biv = 0;
@@ -5708,7 +5701,7 @@ record_biv (loop, v, insn, dest_reg, inc_val, mult_val, location,
/* Set initial value to the reg itself. */
bl->initial_value = dest_reg;
bl->final_value = 0;
- /* We haven't seen the initializing insn yet */
+ /* We haven't seen the initializing insn yet. */
bl->init_insn = 0;
bl->init_set = 0;
bl->initial_test = 0;
@@ -5762,18 +5755,10 @@ record_biv (loop, v, insn, dest_reg, inc_val, mult_val, location,
LOCATION points to the place where this giv's value appears in INSN. */
static void
-record_giv (loop, v, insn, src_reg, dest_reg, mult_val, add_val, ext_val,
- benefit, type, not_every_iteration, maybe_multiple, location)
- const struct loop *loop;
- struct induction *v;
- rtx insn;
- rtx src_reg;
- rtx dest_reg;
- rtx mult_val, add_val, ext_val;
- int benefit;
- enum g_types type;
- int not_every_iteration, maybe_multiple;
- rtx *location;
+record_giv (const struct loop *loop, struct induction *v, rtx insn,
+ rtx src_reg, rtx dest_reg, rtx mult_val, rtx add_val,
+ rtx ext_val, int benefit, enum g_types type,
+ int not_every_iteration, int maybe_multiple, rtx *location)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
struct induction *b;
@@ -5781,7 +5766,7 @@ record_giv (loop, v, insn, src_reg, dest_reg, mult_val, add_val, ext_val,
rtx set = single_set (insn);
rtx temp;
- /* Attempt to prove constantness of the values. Don't let simplity_rtx
+ /* Attempt to prove constantness of the values. Don't let simplify_rtx
undo the MULT canonicalization that we performed earlier. */
temp = simplify_rtx (add_val);
if (temp
@@ -5976,16 +5961,10 @@ record_giv (loop, v, insn, src_reg, dest_reg, mult_val, add_val, ext_val,
have been identified. */
static void
-check_final_value (loop, v)
- const struct loop *loop;
- struct induction *v;
+check_final_value (const struct loop *loop, struct induction *v)
{
- struct loop_ivs *ivs = LOOP_IVS (loop);
- struct iv_class *bl;
rtx final_value = 0;
- bl = REG_IV_CLASS (ivs, REGNO (v->src_reg));
-
/* DEST_ADDR givs will never reach here, because they are always marked
replaceable above in record_giv. */
@@ -6130,9 +6109,7 @@ check_final_value (loop, v)
The cases we look at are when a label or an update to a biv is passed. */
static void
-update_giv_derive (loop, p)
- const struct loop *loop;
- rtx p;
+update_giv_derive (const struct loop *loop, rtx p)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
struct iv_class *bl;
@@ -6172,6 +6149,10 @@ update_giv_derive (loop, p)
if (GET_CODE (p) == CODE_LABEL || GET_CODE (p) == JUMP_INSN
|| biv->insn == p)
{
+ /* Skip if location is the same as a previous one. */
+ if (biv->same)
+ continue;
+
for (giv = bl->giv; giv; giv = giv->next_iv)
{
/* If cant_derive is already true, there is no point in
@@ -6242,7 +6223,7 @@ update_giv_derive (loop, p)
*MULT_VAL to CONST0_RTX, and store the invariant into *INC_VAL.
We also want to detect a BIV when it corresponds to a variable
- whose mode was promoted via PROMOTED_MODE. In that case, an increment
+ whose mode was promoted. In that case, an increment
of the variable may be a PLUS that adds a SUBREG of that variable to
an invariant and then sign- or zero-extends the result of the PLUS
into the variable.
@@ -6263,15 +6244,9 @@ update_giv_derive (loop, p)
If we cannot find a biv, we return 0. */
static int
-basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val, location)
- const struct loop *loop;
- rtx x;
- enum machine_mode mode;
- rtx dest_reg;
- rtx p;
- rtx *inc_val;
- rtx *mult_val;
- rtx **location;
+basic_induction_var (const struct loop *loop, rtx x, enum machine_mode mode,
+ rtx dest_reg, rtx p, rtx *inc_val, rtx *mult_val,
+ rtx **location)
{
enum rtx_code code;
rtx *argp, arg;
@@ -6306,7 +6281,7 @@ basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val, location)
/* convert_modes can emit new instructions, e.g. when arg is a loop
invariant MEM and dest_reg has a different mode.
These instructions would be emitted after the end of the function
- and then *inc_val would be an unitialized pseudo.
+ and then *inc_val would be an uninitialized pseudo.
Detect this and bail in this case.
Other alternatives to solve this can be introducing a convert_modes
variant which is allowed to fail but not allowed to emit new
@@ -6419,6 +6394,9 @@ basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val, location)
return 0;
case SIGN_EXTEND:
+ /* Ignore this BIV if signed arithmetic overflow is defined. */
+ if (flag_wrapv)
+ return 0;
return basic_induction_var (loop, XEXP (x, 0), GET_MODE (XEXP (x, 0)),
dest_reg, p, inc_val, mult_val, location);
@@ -6465,17 +6443,10 @@ basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val, location)
such that the value of X is biv * mult + add; */
static int
-general_induction_var (loop, x, src_reg, add_val, mult_val, ext_val,
- is_addr, pbenefit, addr_mode)
- const struct loop *loop;
- rtx x;
- rtx *src_reg;
- rtx *add_val;
- rtx *mult_val;
- rtx *ext_val;
- int is_addr;
- int *pbenefit;
- enum machine_mode addr_mode;
+general_induction_var (const struct loop *loop, rtx x, rtx *src_reg,
+ rtx *add_val, rtx *mult_val, rtx *ext_val,
+ int is_addr, int *pbenefit,
+ enum machine_mode addr_mode)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
rtx orig_x = x;
@@ -6574,15 +6545,11 @@ general_induction_var (loop, x, src_reg, add_val, mult_val, ext_val,
*BENEFIT will be incremented by the benefit of any sub-giv encountered. */
-static rtx sge_plus PARAMS ((enum machine_mode, rtx, rtx));
-static rtx sge_plus_constant PARAMS ((rtx, rtx));
+static rtx sge_plus (enum machine_mode, rtx, rtx);
+static rtx sge_plus_constant (rtx, rtx);
static rtx
-simplify_giv_expr (loop, x, ext_val, benefit)
- const struct loop *loop;
- rtx x;
- rtx *ext_val;
- int *benefit;
+simplify_giv_expr (const struct loop *loop, rtx x, rtx *ext_val, int *benefit)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
struct loop_regs *regs = LOOP_REGS (loop);
@@ -6756,7 +6723,7 @@ simplify_giv_expr (loop, x, ext_val, benefit)
arg1)),
ext_val, benefit);
}
- /* Porpagate the MULT expressions to the intermost nodes. */
+ /* Propagate the MULT expressions to the innermost nodes. */
else if (GET_CODE (arg0) == PLUS)
{
/* (invar_0 + invar_1) * invar_2. Distribute. */
@@ -7007,8 +6974,7 @@ simplify_giv_expr (loop, x, ext_val, benefit)
CONST_INT in the summation. It is only used by simplify_giv_expr. */
static rtx
-sge_plus_constant (x, c)
- rtx x, c;
+sge_plus_constant (rtx x, rtx c)
{
if (GET_CODE (x) == CONST_INT)
return GEN_INT (INTVAL (x) + INTVAL (c));
@@ -7033,9 +6999,7 @@ sge_plus_constant (x, c)
}
static rtx
-sge_plus (mode, x, y)
- enum machine_mode mode;
- rtx x, y;
+sge_plus (enum machine_mode mode, rtx x, rtx y)
{
while (GET_CODE (y) == PLUS)
{
@@ -7073,17 +7037,9 @@ sge_plus (mode, x, y)
*MULT_VAL and *ADD_VAL. */
static int
-consec_sets_giv (loop, first_benefit, p, src_reg, dest_reg,
- add_val, mult_val, ext_val, last_consec_insn)
- const struct loop *loop;
- int first_benefit;
- rtx p;
- rtx src_reg;
- rtx dest_reg;
- rtx *add_val;
- rtx *mult_val;
- rtx *ext_val;
- rtx *last_consec_insn;
+consec_sets_giv (const struct loop *loop, int first_benefit, rtx p,
+ rtx src_reg, rtx dest_reg, rtx *add_val, rtx *mult_val,
+ rtx *ext_val, rtx *last_consec_insn)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
struct loop_regs *regs = LOOP_REGS (loop);
@@ -7105,7 +7061,7 @@ consec_sets_giv (loop, first_benefit, p, src_reg, dest_reg,
if (REG_IV_TYPE (ivs, REGNO (dest_reg)) != UNKNOWN_INDUCT)
return 0;
- v = (struct induction *) alloca (sizeof (struct induction));
+ v = alloca (sizeof (struct induction));
v->src_reg = src_reg;
v->mult_val = *mult_val;
v->add_val = *add_val;
@@ -7189,8 +7145,7 @@ consec_sets_giv (loop, first_benefit, p, src_reg, dest_reg,
subtracting variables. */
static rtx
-express_from_1 (a, b, mult)
- rtx a, b, mult;
+express_from_1 (rtx a, rtx b, rtx mult)
{
/* If MULT is zero, then A*MULT is zero, and our expression is B. */
@@ -7288,8 +7243,7 @@ express_from_1 (a, b, mult)
}
rtx
-express_from (g1, g2)
- struct induction *g1, *g2;
+express_from (struct induction *g1, struct induction *g2)
{
rtx mult, add;
@@ -7300,6 +7254,9 @@ express_from (g1, g2)
&& GET_CODE (g2->mult_val) == CONST_INT)
{
if (g1->mult_val == const0_rtx
+ || (g1->mult_val == constm1_rtx
+ && INTVAL (g2->mult_val)
+ == (HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1))
|| INTVAL (g2->mult_val) % INTVAL (g1->mult_val) != 0)
return NULL_RTX;
mult = GEN_INT (INTVAL (g2->mult_val) / INTVAL (g1->mult_val));
@@ -7370,8 +7327,7 @@ express_from (g1, g2)
used to represent G1. */
static rtx
-combine_givs_p (g1, g2)
- struct induction *g1, *g2;
+combine_givs_p (struct induction *g1, struct induction *g2)
{
rtx comb, ret;
@@ -7402,21 +7358,8 @@ combine_givs_p (g1, g2)
the expression of G2 in terms of G1 can be used. */
if (ret != NULL_RTX
&& g2->giv_type == DEST_ADDR
- && memory_address_p (GET_MODE (g2->mem), ret)
- /* ??? Looses, especially with -fforce-addr, where *g2->location
- will always be a register, and so anything more complicated
- gets discarded. */
-#if 0
-#ifdef ADDRESS_COST
- && ADDRESS_COST (tem) <= ADDRESS_COST (*g2->location)
-#else
- && rtx_cost (tem, MEM) <= rtx_cost (*g2->location, MEM)
-#endif
-#endif
- )
- {
- return ret;
- }
+ && memory_address_p (GET_MODE (g2->mem), ret))
+ return ret;
return NULL_RTX;
}
@@ -7426,10 +7369,9 @@ combine_givs_p (g1, g2)
make the giv illegal. */
static void
-check_ext_dependent_givs (bl, loop_info)
- struct iv_class *bl;
- struct loop_info *loop_info;
+check_ext_dependent_givs (const struct loop *loop, struct iv_class *bl)
{
+ struct loop_info *loop_info = LOOP_INFO (loop);
int ze_ok = 0, se_ok = 0, info_ok = 0;
enum machine_mode biv_mode = GET_MODE (bl->biv->src_reg);
HOST_WIDE_INT start_val;
@@ -7440,9 +7382,6 @@ check_ext_dependent_givs (bl, loop_info)
/* Make sure the iteration data is available. We must have
constants in order to be certain of no overflow. */
- /* ??? An unknown iteration count with an increment of +-1
- combined with friendly exit tests of against an invariant
- value is also ameanable to optimization. Not implemented. */
if (loop_info->n_iterations > 0
&& bl->initial_value
&& GET_CODE (bl->initial_value) == CONST_INT
@@ -7464,7 +7403,7 @@ check_ext_dependent_givs (bl, loop_info)
neg_incr = 1, abs_incr = -abs_incr;
total_incr = abs_incr * loop_info->n_iterations;
- /* Check for host arithmatic overflow. */
+ /* Check for host arithmetic overflow. */
if (total_incr / loop_info->n_iterations == abs_incr)
{
unsigned HOST_WIDE_INT u_max;
@@ -7477,7 +7416,7 @@ check_ext_dependent_givs (bl, loop_info)
/* Check zero extension of biv ok. */
if (start_val >= 0
- /* Check for host arithmatic overflow. */
+ /* Check for host arithmetic overflow. */
&& (neg_incr
? u_end_val < u_start_val
: u_end_val > u_start_val)
@@ -7495,7 +7434,7 @@ check_ext_dependent_givs (bl, loop_info)
keep this fact in mind -- myself included on occasion.
So leave alone with the signed overflow optimizations. */
if (start_val >= -s_max - 1
- /* Check for host arithmatic overflow. */
+ /* Check for host arithmetic overflow. */
&& (neg_incr
? s_end_val < start_val
: s_end_val > start_val)
@@ -7509,6 +7448,37 @@ check_ext_dependent_givs (bl, loop_info)
}
}
+ /* If we know the BIV is compared at run-time against an
+ invariant value, and the increment is +/- 1, we may also
+ be able to prove that the BIV cannot overflow. */
+ else if (bl->biv->src_reg == loop_info->iteration_var
+ && loop_info->comparison_value
+ && loop_invariant_p (loop, loop_info->comparison_value)
+ && (incr = biv_total_increment (bl))
+ && GET_CODE (incr) == CONST_INT)
+ {
+ /* If the increment is +1, and the exit test is a <,
+ the BIV cannot overflow. (For <=, we have the
+ problematic case that the comparison value might
+ be the maximum value of the range.) */
+ if (INTVAL (incr) == 1)
+ {
+ if (loop_info->comparison_code == LT)
+ se_ok = ze_ok = 1;
+ else if (loop_info->comparison_code == LTU)
+ ze_ok = 1;
+ }
+
+ /* Likewise for increment -1 and exit test >. */
+ if (INTVAL (incr) == -1)
+ {
+ if (loop_info->comparison_code == GT)
+ se_ok = ze_ok = 1;
+ else if (loop_info->comparison_code == GTU)
+ ze_ok = 1;
+ }
+ }
+
/* Invalidate givs that fail the tests. */
for (v = bl->giv; v; v = v->next_iv)
if (v->ext_dependent)
@@ -7530,8 +7500,9 @@ check_ext_dependent_givs (bl, loop_info)
signed or unsigned, so to safely truncate we must satisfy
both. The initial check here verifies the BIV itself;
once that is successful we may check its range wrt the
- derived GIV. */
- if (se_ok && ze_ok)
+ derived GIV. This works only if we were able to determine
+ constant start and end values above. */
+ if (se_ok && ze_ok && info_ok)
{
enum machine_mode outer_mode = GET_MODE (v->ext_dependent);
unsigned HOST_WIDE_INT max = GET_MODE_MASK (outer_mode) >> 1;
@@ -7588,9 +7559,7 @@ check_ext_dependent_givs (bl, loop_info)
/* Generate a version of VALUE in a mode appropriate for initializing V. */
rtx
-extend_value_for_giv (v, value)
- struct induction *v;
- rtx value;
+extend_value_for_giv (struct induction *v, rtx value)
{
rtx ext_dep = v->ext_dependent;
@@ -7615,9 +7584,7 @@ struct combine_givs_stats
};
static int
-cmp_combine_givs_stats (xp, yp)
- const PTR xp;
- const PTR yp;
+cmp_combine_givs_stats (const void *xp, const void *yp)
{
const struct combine_givs_stats * const x =
(const struct combine_givs_stats *) xp;
@@ -7637,9 +7604,7 @@ cmp_combine_givs_stats (xp, yp)
giv. Also, update BENEFIT and related fields for cost/benefit analysis. */
static void
-combine_givs (regs, bl)
- struct loop_regs *regs;
- struct iv_class *bl;
+combine_givs (struct loop_regs *regs, struct iv_class *bl)
{
/* Additional benefit to add for being combined multiple times. */
const int extra_benefit = 3;
@@ -7655,15 +7620,14 @@ combine_givs (regs, bl)
if (!g1->ignore)
giv_count++;
- giv_array
- = (struct induction **) alloca (giv_count * sizeof (struct induction *));
+ giv_array = alloca (giv_count * sizeof (struct induction *));
i = 0;
for (g1 = bl->giv; g1; g1 = g1->next_iv)
if (!g1->ignore)
giv_array[i++] = g1;
- stats = (struct combine_givs_stats *) xcalloc (giv_count, sizeof (*stats));
- can_combine = (rtx *) xcalloc (giv_count, giv_count * sizeof (rtx));
+ stats = xcalloc (giv_count, sizeof (*stats));
+ can_combine = xcalloc (giv_count, giv_count * sizeof (rtx));
for (i = 0; i < giv_count; i++)
{
@@ -7807,14 +7771,12 @@ restart:
free (can_combine);
}
-/* Generate sequence for REG = B * M + A. */
+/* Generate sequence for REG = B * M + A. B is the initial value of
+ the basic induction variable, M a multiplicative constant, A an
+ additive constant and REG the destination register. */
static rtx
-gen_add_mult (b, m, a, reg)
- rtx b; /* initial value of basic induction variable */
- rtx m; /* multiplicative constant */
- rtx a; /* additive constant */
- rtx reg; /* destination register */
+gen_add_mult (rtx b, rtx m, rtx a, rtx reg)
{
rtx seq;
rtx result;
@@ -7834,47 +7796,33 @@ gen_add_mult (b, m, a, reg)
/* Update registers created in insn sequence SEQ. */
static void
-loop_regs_update (loop, seq)
- const struct loop *loop ATTRIBUTE_UNUSED;
- rtx seq;
+loop_regs_update (const struct loop *loop ATTRIBUTE_UNUSED, rtx seq)
{
rtx insn;
/* Update register info for alias analysis. */
- if (seq == NULL_RTX)
- return;
-
- if (INSN_P (seq))
+ insn = seq;
+ while (insn != NULL_RTX)
{
- insn = seq;
- while (insn != NULL_RTX)
- {
- rtx set = single_set (insn);
+ rtx set = single_set (insn);
- if (set && GET_CODE (SET_DEST (set)) == REG)
- record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
+ if (set && GET_CODE (SET_DEST (set)) == REG)
+ record_base_value (REGNO (SET_DEST (set)), SET_SRC (set), 0);
- insn = NEXT_INSN (insn);
- }
+ insn = NEXT_INSN (insn);
}
- else if (GET_CODE (seq) == SET
- && GET_CODE (SET_DEST (seq)) == REG)
- record_base_value (REGNO (SET_DEST (seq)), SET_SRC (seq), 0);
}
-/* EMIT code before BEFORE_BB/BEFORE_INSN to set REG = B * M + A. */
+/* EMIT code before BEFORE_BB/BEFORE_INSN to set REG = B * M + A. B
+ is the initial value of the basic induction variable, M a
+ multiplicative constant, A an additive constant and REG the
+ destination register. */
void
-loop_iv_add_mult_emit_before (loop, b, m, a, reg, before_bb, before_insn)
- const struct loop *loop;
- rtx b; /* initial value of basic induction variable */
- rtx m; /* multiplicative constant */
- rtx a; /* additive constant */
- rtx reg; /* destination register */
- basic_block before_bb;
- rtx before_insn;
+loop_iv_add_mult_emit_before (const struct loop *loop, rtx b, rtx m, rtx a,
+ rtx reg, basic_block before_bb, rtx before_insn)
{
rtx seq;
@@ -7901,15 +7849,13 @@ loop_iv_add_mult_emit_before (loop, b, m, a, reg, before_bb, before_insn)
}
-/* Emit insns in loop pre-header to set REG = B * M + A. */
+/* Emit insns in loop pre-header to set REG = B * M + A. B is the
+ initial value of the basic induction variable, M a multiplicative
+ constant, A an additive constant and REG the destination
+ register. */
void
-loop_iv_add_mult_sink (loop, b, m, a, reg)
- const struct loop *loop;
- rtx b; /* initial value of basic induction variable */
- rtx m; /* multiplicative constant */
- rtx a; /* additive constant */
- rtx reg; /* destination register */
+loop_iv_add_mult_sink (const struct loop *loop, rtx b, rtx m, rtx a, rtx reg)
{
rtx seq;
@@ -7931,15 +7877,12 @@ loop_iv_add_mult_sink (loop, b, m, a, reg)
}
-/* Emit insns after loop to set REG = B * M + A. */
+/* Emit insns after loop to set REG = B * M + A. B is the initial
+ value of the basic induction variable, M a multiplicative constant,
+ A an additive constant and REG the destination register. */
void
-loop_iv_add_mult_hoist (loop, b, m, a, reg)
- const struct loop *loop;
- rtx b; /* initial value of basic induction variable */
- rtx m; /* multiplicative constant */
- rtx a; /* additive constant */
- rtx reg; /* destination register */
+loop_iv_add_mult_hoist (const struct loop *loop, rtx b, rtx m, rtx a, rtx reg)
{
rtx seq;
@@ -7960,11 +7903,7 @@ loop_iv_add_mult_hoist (loop, b, m, a, reg)
sequence. */
static int
-iv_add_mult_cost (b, m, a, reg)
- rtx b; /* initial value of basic induction variable */
- rtx m; /* multiplicative constant */
- rtx a; /* additive constant */
- rtx reg; /* destination register */
+iv_add_mult_cost (rtx b, rtx m, rtx a, rtx reg)
{
int cost = 0;
rtx last, result;
@@ -7994,9 +7933,7 @@ iv_add_mult_cost (b, m, a, reg)
??? thing, generate wasted RTL just to see if something is possible. */
static int
-product_cheap_p (a, b)
- rtx a;
- rtx b;
+product_cheap_p (rtx a, rtx b)
{
rtx tmp;
int win, n_insns;
@@ -8072,15 +8009,14 @@ product_cheap_p (a, b)
final_[bg]iv_value. */
static int
-check_dbra_loop (loop, insn_count)
- struct loop *loop;
- int insn_count;
+check_dbra_loop (struct loop *loop, int insn_count)
{
struct loop_info *loop_info = LOOP_INFO (loop);
struct loop_regs *regs = LOOP_REGS (loop);
struct loop_ivs *ivs = LOOP_IVS (loop);
struct iv_class *bl;
rtx reg;
+ enum machine_mode mode;
rtx jump_label;
rtx final_value;
rtx start_value;
@@ -8106,7 +8042,7 @@ check_dbra_loop (loop, insn_count)
/* Try to compute whether the compare/branch at the loop end is one or
two instructions. */
- get_condition (jump, &first_compare);
+ get_condition (jump, &first_compare, false);
if (first_compare == jump)
compare_and_branch = 1;
else if (first_compare == prev_nonnote_insn (jump))
@@ -8143,6 +8079,22 @@ check_dbra_loop (loop, insn_count)
break;
}
+ /* Try swapping the comparison to identify a suitable biv. */
+ if (!bl)
+ for (bl = ivs->list; bl; bl = bl->next)
+ if (bl->biv_count == 1
+ && ! bl->biv->maybe_multiple
+ && bl->biv->dest_reg == XEXP (comparison, 1)
+ && ! reg_used_between_p (regno_reg_rtx[bl->regno], bl->biv->insn,
+ first_compare))
+ {
+ comparison = gen_rtx_fmt_ee (swap_condition (GET_CODE (comparison)),
+ VOIDmode,
+ XEXP (comparison, 1),
+ XEXP (comparison, 0));
+ break;
+ }
+
if (! bl)
return 0;
@@ -8151,9 +8103,7 @@ check_dbra_loop (loop, insn_count)
In this case, add a reg_note REG_NONNEG, which allows the
m68k DBRA instruction to be used. */
- if (((GET_CODE (comparison) == GT
- && GET_CODE (XEXP (comparison, 1)) == CONST_INT
- && INTVAL (XEXP (comparison, 1)) == -1)
+ if (((GET_CODE (comparison) == GT && XEXP (comparison, 1) == constm1_rtx)
|| (GET_CODE (comparison) == NE && XEXP (comparison, 1) == const0_rtx))
&& GET_CODE (bl->biv->add_val) == CONST_INT
&& INTVAL (bl->biv->add_val) < 0)
@@ -8167,7 +8117,7 @@ check_dbra_loop (loop, insn_count)
&& (INTVAL (bl->initial_value)
% (-INTVAL (bl->biv->add_val))) == 0)
{
- /* register always nonnegative, add REG_NOTE to branch */
+ /* Register always nonnegative, add REG_NOTE to branch. */
if (! find_reg_note (jump, REG_NONNEG, NULL_RTX))
REG_NOTES (jump)
= gen_rtx_EXPR_LIST (REG_NONNEG, bl->biv->dest_reg,
@@ -8189,7 +8139,8 @@ check_dbra_loop (loop, insn_count)
before_comparison = get_condition_for_loop (loop, p);
if (before_comparison
&& XEXP (before_comparison, 0) == bl->biv->dest_reg
- && GET_CODE (before_comparison) == LT
+ && (GET_CODE (before_comparison) == LT
+ || GET_CODE (before_comparison) == LTU)
&& XEXP (before_comparison, 1) == const0_rtx
&& ! reg_set_between_p (bl->biv->dest_reg, p, loop_start)
&& INTVAL (bl->biv->add_val) == -1)
@@ -8245,9 +8196,11 @@ check_dbra_loop (loop, insn_count)
&& REGNO (SET_DEST (set)) == bl->regno)
/* An insn that sets the biv is okay. */
;
- else if ((p == prev_nonnote_insn (prev_nonnote_insn (loop_end))
- || p == prev_nonnote_insn (loop_end))
- && reg_mentioned_p (bivreg, PATTERN (p)))
+ else if (!reg_mentioned_p (bivreg, PATTERN (p)))
+ /* An insn that doesn't mention the biv is okay. */
+ ;
+ else if (p == prev_nonnote_insn (prev_nonnote_insn (loop_end))
+ || p == prev_nonnote_insn (loop_end))
{
/* If either of these insns uses the biv and sets a pseudo
that has more than one usage, then the biv has uses
@@ -8261,7 +8214,7 @@ check_dbra_loop (loop, insn_count)
break;
}
}
- else if (reg_mentioned_p (bivreg, PATTERN (p)))
+ else
{
no_use_except_counting = 0;
break;
@@ -8358,7 +8311,8 @@ check_dbra_loop (loop, insn_count)
/* for constants, LE gets turned into LT */
&& (GET_CODE (comparison) == LT
|| (GET_CODE (comparison) == LE
- && no_use_except_counting)))
+ && no_use_except_counting)
+ || GET_CODE (comparison) == LTU))
{
HOST_WIDE_INT add_val, add_adjust, comparison_val = 0;
rtx initial_value, comparison_value;
@@ -8366,6 +8320,7 @@ check_dbra_loop (loop, insn_count)
enum rtx_code cmp_code;
int comparison_const_width;
unsigned HOST_WIDE_INT comparison_sign_mask;
+ bool keep_first_compare;
add_val = INTVAL (bl->biv->add_val);
comparison_value = XEXP (comparison, 1);
@@ -8483,6 +8438,7 @@ check_dbra_loop (loop, insn_count)
/* Save some info needed to produce the new insns. */
reg = bl->biv->dest_reg;
+ mode = GET_MODE (reg);
jump_label = condjump_label (PREV_INSN (loop_end));
new_add_val = GEN_INT (-INTVAL (bl->biv->add_val));
@@ -8494,12 +8450,12 @@ check_dbra_loop (loop, insn_count)
if (initial_value == const0_rtx
&& GET_CODE (comparison_value) == CONST_INT)
{
- start_value = GEN_INT (comparison_val - add_adjust);
+ start_value
+ = gen_int_mode (comparison_val - add_adjust, mode);
loop_insn_hoist (loop, gen_move_insn (reg, start_value));
}
else if (GET_CODE (initial_value) == CONST_INT)
{
- enum machine_mode mode = GET_MODE (reg);
rtx offset = GEN_INT (-INTVAL (initial_value) - add_adjust);
rtx add_insn = gen_add3_insn (reg, comparison_value, offset);
@@ -8515,7 +8471,6 @@ check_dbra_loop (loop, insn_count)
}
else if (! add_adjust)
{
- enum machine_mode mode = GET_MODE (reg);
rtx sub_insn = gen_sub3_insn (reg, comparison_value,
initial_value);
@@ -8558,13 +8513,26 @@ check_dbra_loop (loop, insn_count)
not delete the label. */
LABEL_NUSES (XEXP (jump_label, 0))++;
+ /* If we have a separate comparison insn that does more
+ than just set cc0, the result of the comparison might
+ be used outside the loop. */
+ keep_first_compare = (compare_and_branch == 2
+#ifdef HAVE_CC0
+ && sets_cc0_p (first_compare) <= 0
+#endif
+ );
+
/* Emit an insn after the end of the loop to set the biv's
proper exit value if it is used anywhere outside the loop. */
- if ((REGNO_LAST_UID (bl->regno) != INSN_UID (first_compare))
+ if (keep_first_compare
+ || (REGNO_LAST_UID (bl->regno) != INSN_UID (first_compare))
|| ! bl->init_insn
|| REGNO_FIRST_UID (bl->regno) != INSN_UID (bl->init_insn))
loop_insn_sink (loop, gen_load_of_final_value (reg, final_value));
+ if (keep_first_compare)
+ loop_insn_sink (loop, PATTERN (first_compare));
+
/* Delete compare/branch at end of loop. */
delete_related_insns (PREV_INSN (loop_end));
if (compare_and_branch == 2)
@@ -8573,7 +8541,7 @@ check_dbra_loop (loop, insn_count)
/* Add new compare/branch insn at end of loop. */
start_sequence ();
emit_cmp_and_jump_insns (reg, const0_rtx, cmp_code, NULL_RTX,
- GET_MODE (reg), 0,
+ mode, 0,
XEXP (jump_label, 0));
tem = get_insns ();
end_sequence ();
@@ -8667,11 +8635,8 @@ check_dbra_loop (loop, insn_count)
start of the loop. */
static int
-maybe_eliminate_biv (loop, bl, eliminate_p, threshold, insn_count)
- const struct loop *loop;
- struct iv_class *bl;
- int eliminate_p;
- int threshold, insn_count;
+maybe_eliminate_biv (const struct loop *loop, struct iv_class *bl,
+ int eliminate_p, int threshold, int insn_count)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
rtx reg = bl->biv->dest_reg;
@@ -8744,8 +8709,7 @@ maybe_eliminate_biv (loop, bl, eliminate_p, threshold, insn_count)
Return nonzero if INSN is first. */
int
-loop_insn_first_p (insn, reference)
- rtx insn, reference;
+loop_insn_first_p (rtx insn, rtx reference)
{
rtx p, q;
@@ -8778,9 +8742,8 @@ loop_insn_first_p (insn, reference)
the offset that we have to take into account due to auto-increment /
div derivation is zero. */
static int
-biv_elimination_giv_has_0_offset (biv, giv, insn)
- struct induction *biv, *giv;
- rtx insn;
+biv_elimination_giv_has_0_offset (struct induction *biv,
+ struct induction *giv, rtx insn)
{
/* If the giv V had the auto-inc address optimization applied
to it, and INSN occurs between the giv insn and the biv
@@ -8808,13 +8771,9 @@ biv_elimination_giv_has_0_offset (biv, giv, insn)
start of the loop (when WHERE_INSN is zero). */
static int
-maybe_eliminate_biv_1 (loop, x, insn, bl, eliminate_p, where_bb, where_insn)
- const struct loop *loop;
- rtx x, insn;
- struct iv_class *bl;
- int eliminate_p;
- basic_block where_bb;
- rtx where_insn;
+maybe_eliminate_biv_1 (const struct loop *loop, rtx x, rtx insn,
+ struct iv_class *bl, int eliminate_p,
+ basic_block where_bb, rtx where_insn)
{
enum rtx_code code = GET_CODE (x);
rtx reg = bl->biv->dest_reg;
@@ -9183,9 +9142,7 @@ maybe_eliminate_biv_1 (loop, x, insn, bl, eliminate_p, where_bb, where_insn)
is in an insn following INSN in the same basic block. */
static int
-last_use_this_basic_block (reg, insn)
- rtx reg;
- rtx insn;
+last_use_this_basic_block (rtx reg, rtx insn)
{
rtx n;
for (n = insn;
@@ -9202,10 +9159,7 @@ last_use_this_basic_block (reg, insn)
just record the location of the set and process it later. */
static void
-record_initial (dest, set, data)
- rtx dest;
- rtx set;
- void *data ATTRIBUTE_UNUSED;
+record_initial (rtx dest, rtx set, void *data ATTRIBUTE_UNUSED)
{
struct loop_ivs *ivs = (struct loop_ivs *) data;
struct iv_class *bl;
@@ -9231,9 +9185,7 @@ record_initial (dest, set, data)
use it. X must be a source expression only. */
static void
-update_reg_last_use (x, insn)
- rtx x;
- rtx insn;
+update_reg_last_use (rtx x, rtx insn)
{
/* Check for the case where INSN does not have a valid luid. In this case,
there is no need to modify the regno_last_uid, as this can only happen
@@ -9283,15 +9235,12 @@ update_reg_last_use (x, insn)
If WANT_REG is nonzero, we wish the condition to be relative to that
register, if possible. Therefore, do not canonicalize the condition
- further. */
+ further. If ALLOW_CC_MODE is nonzero, allow the condition returned
+ to be a compare to a CC mode register. */
rtx
-canonicalize_condition (insn, cond, reverse, earliest, want_reg)
- rtx insn;
- rtx cond;
- int reverse;
- rtx *earliest;
- rtx want_reg;
+canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest,
+ rtx want_reg, int allow_cc_mode)
{
enum rtx_code code;
rtx prev = insn;
@@ -9470,14 +9419,16 @@ canonicalize_condition (insn, cond, reverse, earliest, want_reg)
/* If OP0 is the result of a comparison, we weren't able to find what
was really being compared, so fail. */
- if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
+ if (!allow_cc_mode
+ && GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
return 0;
/* Canonicalize any ordered comparison with integers involving equality
if we can do computations in the relevant mode and we do not
overflow. */
- if (GET_CODE (op1) == CONST_INT
+ if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_CC
+ && GET_CODE (op1) == CONST_INT
&& GET_MODE (op0) != VOIDmode
&& GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT)
{
@@ -9517,11 +9468,9 @@ canonicalize_condition (insn, cond, reverse, earliest, want_reg)
}
}
-#ifdef HAVE_cc0
/* Never return CC0; return zero instead. */
- if (op0 == cc0_rtx)
+ if (CC0_P (op0))
return 0;
-#endif
return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
}
@@ -9534,12 +9483,13 @@ canonicalize_condition (insn, cond, reverse, earliest, want_reg)
If EARLIEST is nonzero, it is a pointer to a place where the earliest
insn used in locating the condition was found. If a replacement test
of the condition is desired, it should be placed in front of that
- insn and we will be sure that the inputs are still valid. */
+ insn and we will be sure that the inputs are still valid.
+
+ If ALLOW_CC_MODE is nonzero, allow the condition returned to be a
+ compare CC mode register. */
rtx
-get_condition (jump, earliest)
- rtx jump;
- rtx *earliest;
+get_condition (rtx jump, rtx *earliest, int allow_cc_mode)
{
rtx cond;
int reverse;
@@ -9559,18 +9509,17 @@ get_condition (jump, earliest)
= GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
&& XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump);
- return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX);
+ return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX,
+ allow_cc_mode);
}
/* Similar to above routine, except that we also put an invariant last
unless both operands are invariants. */
rtx
-get_condition_for_loop (loop, x)
- const struct loop *loop;
- rtx x;
+get_condition_for_loop (const struct loop *loop, rtx x)
{
- rtx comparison = get_condition (x, (rtx*) 0);
+ rtx comparison = get_condition (x, (rtx*) 0, false);
if (comparison == 0
|| ! loop_invariant_p (loop, XEXP (comparison, 0))
@@ -9586,8 +9535,7 @@ get_condition_for_loop (loop, x)
This is taken mostly from flow.c; similar code exists elsewhere
in the compiler. It may be useful to put this into rtlanal.c. */
static int
-indirect_jump_in_function_p (start)
- rtx start;
+indirect_jump_in_function_p (rtx start)
{
rtx insn;
@@ -9603,9 +9551,7 @@ indirect_jump_in_function_p (start)
This function is called from prescan_loop via for_each_rtx. */
static int
-insert_loop_mem (mem, data)
- rtx *mem;
- void *data ATTRIBUTE_UNUSED;
+insert_loop_mem (rtx *mem, void *data ATTRIBUTE_UNUSED)
{
struct loop_info *loop_info = data;
int i;
@@ -9641,6 +9587,8 @@ insert_loop_mem (mem, data)
for (i = 0; i < loop_info->mems_idx; ++i)
if (rtx_equal_p (m, loop_info->mems[i].mem))
{
+ if (MEM_VOLATILE_P (m) && !MEM_VOLATILE_P (loop_info->mems[i].mem))
+ loop_info->mems[i].mem = m;
if (GET_MODE (m) != GET_MODE (loop_info->mems[i].mem))
/* The modes of the two memory accesses are different. If
this happens, something tricky is going on, and we just
@@ -9658,9 +9606,8 @@ insert_loop_mem (mem, data)
else
loop_info->mems_allocated = 32;
- loop_info->mems = (loop_mem_info *)
- xrealloc (loop_info->mems,
- loop_info->mems_allocated * sizeof (loop_mem_info));
+ loop_info->mems = xrealloc (loop_info->mems,
+ loop_info->mems_allocated * sizeof (loop_mem_info));
}
/* Actually insert the MEM. */
@@ -9693,9 +9640,7 @@ insert_loop_mem (mem, data)
optimize register I. */
static void
-loop_regs_scan (loop, extra_size)
- const struct loop *loop;
- int extra_size;
+loop_regs_scan (const struct loop *loop, int extra_size)
{
struct loop_regs *regs = LOOP_REGS (loop);
int old_nregs;
@@ -9713,8 +9658,7 @@ loop_regs_scan (loop, extra_size)
{
regs->size = regs->num + extra_size;
- regs->array = (struct loop_reg *)
- xrealloc (regs->array, regs->size * sizeof (*regs->array));
+ regs->array = xrealloc (regs->array, regs->size * sizeof (*regs->array));
/* Zero the new elements. */
memset (regs->array + old_nregs, 0,
@@ -9729,7 +9673,7 @@ loop_regs_scan (loop, extra_size)
regs->array[i].single_usage = NULL_RTX;
}
- last_set = (rtx *) xcalloc (regs->num, sizeof (rtx));
+ last_set = xcalloc (regs->num, sizeof (rtx));
/* Scan the loop, recording register usage. */
for (insn = loop->top ? loop->top : loop->start; insn != loop->end;
@@ -9765,8 +9709,8 @@ loop_regs_scan (loop, extra_size)
if (GET_CODE (insn) == CALL_INSN)
{
rtx link;
- for (link = CALL_INSN_FUNCTION_USAGE (insn);
- link;
+ for (link = CALL_INSN_FUNCTION_USAGE (insn);
+ link;
link = XEXP (link, 1))
{
rtx op, reg;
@@ -9810,8 +9754,7 @@ loop_regs_scan (loop, extra_size)
/* Returns the number of real INSNs in the LOOP. */
static int
-count_insns_in_loop (loop)
- const struct loop *loop;
+count_insns_in_loop (const struct loop *loop)
{
int count = 0;
rtx insn;
@@ -9827,8 +9770,7 @@ count_insns_in_loop (loop)
/* Move MEMs into registers for the duration of the loop. */
static void
-load_mems (loop)
- const struct loop *loop;
+load_mems (const struct loop *loop)
{
struct loop_info *loop_info = LOOP_INFO (loop);
struct loop_regs *regs = LOOP_REGS (loop);
@@ -10157,28 +10099,12 @@ load_mems (loop)
}
}
+ /* Now, we need to replace all references to the previous exit
+ label with the new one. */
if (label != NULL_RTX && end_label != NULL_RTX)
- {
- /* Now, we need to replace all references to the previous exit
- label with the new one. */
- rtx_pair rr;
- rr.r1 = end_label;
- rr.r2 = label;
-
- for (p = loop->start; p != loop->end; p = NEXT_INSN (p))
- {
- for_each_rtx (&p, replace_label, &rr);
-
- /* If this is a JUMP_INSN, then we also need to fix the JUMP_LABEL
- field. This is not handled by for_each_rtx because it doesn't
- handle unprinted ('0') fields. We need to update JUMP_LABEL
- because the immediately following unroll pass will use it.
- replace_label would not work anyways, because that only handles
- LABEL_REFs. */
- if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) == end_label)
- JUMP_LABEL (p) = label;
- }
- }
+ for (p = loop->start; p != loop->end; p = NEXT_INSN (p))
+ if (GET_CODE (p) == JUMP_INSN && JUMP_LABEL (p) == end_label)
+ redirect_jump (p, label, false);
cselib_finish ();
}
@@ -10193,9 +10119,7 @@ struct note_reg_stored_arg
/* Called via note_stores, record in SET_SEEN whether X, which is written,
is equal to ARG. */
static void
-note_reg_stored (x, setter, arg)
- rtx x, setter ATTRIBUTE_UNUSED;
- void *arg;
+note_reg_stored (rtx x, rtx setter ATTRIBUTE_UNUSED, void *arg)
{
struct note_reg_stored_arg *t = (struct note_reg_stored_arg *) arg;
if (t->reg == x)
@@ -10208,10 +10132,7 @@ note_reg_stored (x, setter, arg)
is not used after the loop. */
static void
-try_copy_prop (loop, replacement, regno)
- const struct loop *loop;
- rtx replacement;
- unsigned int regno;
+try_copy_prop (const struct loop *loop, rtx replacement, unsigned int regno)
{
/* This is the reg that we are copying from. */
rtx reg_rtx = regno_reg_rtx[regno];
@@ -10308,9 +10229,7 @@ try_copy_prop (loop, replacement, regno)
with NOTE_INSN_DELETED notes. */
static void
-loop_delete_insns (first, last)
- rtx first;
- rtx last;
+loop_delete_insns (rtx first, rtx last)
{
while (1)
{
@@ -10334,10 +10253,8 @@ loop_delete_insns (first, last)
this pseudo followed immediately by a move insn that sets
REPLACEMENT with REGNO. */
static void
-try_swap_copy_prop (loop, replacement, regno)
- const struct loop *loop;
- rtx replacement;
- unsigned int regno;
+try_swap_copy_prop (const struct loop *loop, rtx replacement,
+ unsigned int regno)
{
rtx insn;
rtx set = NULL_RTX;
@@ -10418,9 +10335,7 @@ try_swap_copy_prop (loop, replacement, regno)
/* Worker function for find_mem_in_note, called via for_each_rtx. */
static int
-find_mem_in_note_1 (x, data)
- rtx *x;
- void *data;
+find_mem_in_note_1 (rtx *x, void *data)
{
if (*x != NULL_RTX && GET_CODE (*x) == MEM)
{
@@ -10434,23 +10349,20 @@ find_mem_in_note_1 (x, data)
/* Returns the first MEM found in NOTE by depth-first search. */
static rtx
-find_mem_in_note (note)
- rtx note;
+find_mem_in_note (rtx note)
{
if (note && for_each_rtx (&note, find_mem_in_note_1, &note))
return note;
return NULL_RTX;
}
-
+
/* Replace MEM with its associated pseudo register. This function is
called from load_mems via for_each_rtx. DATA is actually a pointer
to a structure describing the instruction currently being scanned
and the MEM we are currently replacing. */
static int
-replace_loop_mem (mem, data)
- rtx *mem;
- void *data;
+replace_loop_mem (rtx *mem, void *data)
{
loop_replace_args *args = (loop_replace_args *) data;
rtx m = *mem;
@@ -10484,11 +10396,7 @@ replace_loop_mem (mem, data)
}
static void
-replace_loop_mems (insn, mem, reg, written)
- rtx insn;
- rtx mem;
- rtx reg;
- int written;
+replace_loop_mems (rtx insn, rtx mem, rtx reg, int written)
{
loop_replace_args args;
@@ -10524,9 +10432,7 @@ replace_loop_mems (insn, mem, reg, written)
a structure of arguments. */
static int
-replace_loop_reg (px, data)
- rtx *px;
- void *data;
+replace_loop_reg (rtx *px, void *data)
{
rtx x = *px;
loop_replace_args *args = (loop_replace_args *) data;
@@ -10541,10 +10447,7 @@ replace_loop_reg (px, data)
}
static void
-replace_loop_regs (insn, reg, replacement)
- rtx insn;
- rtx reg;
- rtx replacement;
+replace_loop_regs (rtx insn, rtx reg, rtx replacement)
{
loop_replace_args args;
@@ -10554,45 +10457,14 @@ replace_loop_regs (insn, reg, replacement)
for_each_rtx (&insn, replace_loop_reg, &args);
}
-
-/* Replace occurrences of the old exit label for the loop with the new
- one. DATA is an rtx_pair containing the old and new labels,
- respectively. */
-
-static int
-replace_label (x, data)
- rtx *x;
- void *data;
-{
- rtx l = *x;
- rtx old_label = ((rtx_pair *) data)->r1;
- rtx new_label = ((rtx_pair *) data)->r2;
-
- if (l == NULL_RTX)
- return 0;
-
- if (GET_CODE (l) != LABEL_REF)
- return 0;
-
- if (XEXP (l, 0) != old_label)
- return 0;
-
- XEXP (l, 0) = new_label;
- ++LABEL_NUSES (new_label);
- --LABEL_NUSES (old_label);
-
- return 0;
-}
/* Emit insn for PATTERN after WHERE_INSN in basic block WHERE_BB
(ignored in the interim). */
static rtx
-loop_insn_emit_after (loop, where_bb, where_insn, pattern)
- const struct loop *loop ATTRIBUTE_UNUSED;
- basic_block where_bb ATTRIBUTE_UNUSED;
- rtx where_insn;
- rtx pattern;
+loop_insn_emit_after (const struct loop *loop ATTRIBUTE_UNUSED,
+ basic_block where_bb ATTRIBUTE_UNUSED, rtx where_insn,
+ rtx pattern)
{
return emit_insn_after (pattern, where_insn);
}
@@ -10603,11 +10475,9 @@ loop_insn_emit_after (loop, where_bb, where_insn, pattern)
otherwise hoist PATTERN into the loop pre-header. */
rtx
-loop_insn_emit_before (loop, where_bb, where_insn, pattern)
- const struct loop *loop;
- basic_block where_bb ATTRIBUTE_UNUSED;
- rtx where_insn;
- rtx pattern;
+loop_insn_emit_before (const struct loop *loop,
+ basic_block where_bb ATTRIBUTE_UNUSED,
+ rtx where_insn, rtx pattern)
{
if (! where_insn)
return loop_insn_hoist (loop, pattern);
@@ -10619,11 +10489,9 @@ loop_insn_emit_before (loop, where_bb, where_insn, pattern)
WHERE_BB (ignored in the interim) within the loop. */
static rtx
-loop_call_insn_emit_before (loop, where_bb, where_insn, pattern)
- const struct loop *loop ATTRIBUTE_UNUSED;
- basic_block where_bb ATTRIBUTE_UNUSED;
- rtx where_insn;
- rtx pattern;
+loop_call_insn_emit_before (const struct loop *loop ATTRIBUTE_UNUSED,
+ basic_block where_bb ATTRIBUTE_UNUSED,
+ rtx where_insn, rtx pattern)
{
return emit_call_insn_before (pattern, where_insn);
}
@@ -10632,9 +10500,7 @@ loop_call_insn_emit_before (loop, where_bb, where_insn, pattern)
/* Hoist insn for PATTERN into the loop pre-header. */
rtx
-loop_insn_hoist (loop, pattern)
- const struct loop *loop;
- rtx pattern;
+loop_insn_hoist (const struct loop *loop, rtx pattern)
{
return loop_insn_emit_before (loop, 0, loop->start, pattern);
}
@@ -10643,9 +10509,7 @@ loop_insn_hoist (loop, pattern)
/* Hoist call insn for PATTERN into the loop pre-header. */
static rtx
-loop_call_insn_hoist (loop, pattern)
- const struct loop *loop;
- rtx pattern;
+loop_call_insn_hoist (const struct loop *loop, rtx pattern)
{
return loop_call_insn_emit_before (loop, 0, loop->start, pattern);
}
@@ -10654,18 +10518,15 @@ loop_call_insn_hoist (loop, pattern)
/* Sink insn for PATTERN after the loop end. */
rtx
-loop_insn_sink (loop, pattern)
- const struct loop *loop;
- rtx pattern;
+loop_insn_sink (const struct loop *loop, rtx pattern)
{
return loop_insn_emit_before (loop, 0, loop->sink, pattern);
}
-/* bl->final_value can be eighter general_operand or PLUS of general_operand
- and constant. Emit sequence of intructions to load it into REG */
+/* bl->final_value can be either general_operand or PLUS of general_operand
+ and constant. Emit sequence of instructions to load it into REG. */
static rtx
-gen_load_of_final_value (reg, final_value)
- rtx reg, final_value;
+gen_load_of_final_value (rtx reg, rtx final_value)
{
rtx seq;
start_sequence ();
@@ -10683,9 +10544,7 @@ gen_load_of_final_value (reg, final_value)
since this is slightly more efficient. */
static rtx
-loop_insn_sink_or_swim (loop, pattern)
- const struct loop *loop;
- rtx pattern;
+loop_insn_sink_or_swim (const struct loop *loop, rtx pattern)
{
if (loop->exit_count)
return loop_insn_hoist (loop, pattern);
@@ -10694,10 +10553,7 @@ loop_insn_sink_or_swim (loop, pattern)
}
static void
-loop_ivs_dump (loop, file, verbose)
- const struct loop *loop;
- FILE *file;
- int verbose;
+loop_ivs_dump (const struct loop *loop, FILE *file, int verbose)
{
struct iv_class *bl;
int iv_num = 0;
@@ -10719,10 +10575,8 @@ loop_ivs_dump (loop, file, verbose)
static void
-loop_iv_class_dump (bl, file, verbose)
- const struct iv_class *bl;
- FILE *file;
- int verbose ATTRIBUTE_UNUSED;
+loop_iv_class_dump (const struct iv_class *bl, FILE *file,
+ int verbose ATTRIBUTE_UNUSED)
{
struct induction *v;
rtx incr;
@@ -10784,10 +10638,7 @@ loop_iv_class_dump (bl, file, verbose)
static void
-loop_biv_dump (v, file, verbose)
- const struct induction *v;
- FILE *file;
- int verbose;
+loop_biv_dump (const struct induction *v, FILE *file, int verbose)
{
if (! v || ! file)
return;
@@ -10810,10 +10661,7 @@ loop_biv_dump (v, file, verbose)
static void
-loop_giv_dump (v, file, verbose)
- const struct induction *v;
- FILE *file;
- int verbose;
+loop_giv_dump (const struct induction *v, FILE *file, int verbose)
{
if (! v || ! file)
return;
@@ -10874,32 +10722,28 @@ loop_giv_dump (v, file, verbose)
void
-debug_ivs (loop)
- const struct loop *loop;
+debug_ivs (const struct loop *loop)
{
loop_ivs_dump (loop, stderr, 1);
}
void
-debug_iv_class (bl)
- const struct iv_class *bl;
+debug_iv_class (const struct iv_class *bl)
{
loop_iv_class_dump (bl, stderr, 1);
}
void
-debug_biv (v)
- const struct induction *v;
+debug_biv (const struct induction *v)
{
loop_biv_dump (v, stderr, 1);
}
void
-debug_giv (v)
- const struct induction *v;
+debug_giv (const struct induction *v)
{
loop_giv_dump (v, stderr, 1);
}
@@ -10918,10 +10762,8 @@ debug_giv (v)
#define LOOP_INSN_UID(INSN) ((INSN) ? INSN_UID (INSN) : -1)
static void
-loop_dump_aux (loop, file, verbose)
- const struct loop *loop;
- FILE *file;
- int verbose ATTRIBUTE_UNUSED;
+loop_dump_aux (const struct loop *loop, FILE *file,
+ int verbose ATTRIBUTE_UNUSED)
{
rtx label;
@@ -10930,18 +10772,18 @@ loop_dump_aux (loop, file, verbose)
/* Print diagnostics to compare our concept of a loop with
what the loop notes say. */
- if (! PREV_INSN (loop->first->head)
- || GET_CODE (PREV_INSN (loop->first->head)) != NOTE
- || NOTE_LINE_NUMBER (PREV_INSN (loop->first->head))
+ if (! PREV_INSN (BB_HEAD (loop->first))
+ || GET_CODE (PREV_INSN (BB_HEAD (loop->first))) != NOTE
+ || NOTE_LINE_NUMBER (PREV_INSN (BB_HEAD (loop->first)))
!= NOTE_INSN_LOOP_BEG)
fprintf (file, ";; No NOTE_INSN_LOOP_BEG at %d\n",
- INSN_UID (PREV_INSN (loop->first->head)));
- if (! NEXT_INSN (loop->last->end)
- || GET_CODE (NEXT_INSN (loop->last->end)) != NOTE
- || NOTE_LINE_NUMBER (NEXT_INSN (loop->last->end))
+ INSN_UID (PREV_INSN (BB_HEAD (loop->first))));
+ if (! NEXT_INSN (BB_END (loop->last))
+ || GET_CODE (NEXT_INSN (BB_END (loop->last))) != NOTE
+ || NOTE_LINE_NUMBER (NEXT_INSN (BB_END (loop->last)))
!= NOTE_INSN_LOOP_END)
fprintf (file, ";; No NOTE_INSN_LOOP_END at %d\n",
- INSN_UID (NEXT_INSN (loop->last->end)));
+ INSN_UID (NEXT_INSN (BB_END (loop->last))));
if (loop->start)
{
@@ -10985,8 +10827,7 @@ loop_dump_aux (loop, file, verbose)
/* Call this function from the debugger to dump LOOP. */
void
-debug_loop (loop)
- const struct loop *loop;
+debug_loop (const struct loop *loop)
{
flow_loop_dump (loop, stderr, loop_dump_aux, 1);
}
@@ -10994,8 +10835,7 @@ debug_loop (loop)
/* Call this function from the debugger to dump LOOPS. */
void
-debug_loops (loops)
- const struct loops *loops;
+debug_loops (const struct loops *loops)
{
flow_loops_dump (loops, stderr, loop_dump_aux, 1);
}
diff --git a/contrib/gcc/loop.h b/contrib/gcc/loop.h
index 1dffdddec2e0..f2f870ce2769 100644
--- a/contrib/gcc/loop.h
+++ b/contrib/gcc/loop.h
@@ -1,5 +1,5 @@
-/* Loop optimization definitions for GNU C-Compiler
- Copyright (C) 1991, 1995, 1998, 1999, 2000, 2001, 2002
+/* Loop optimization definitions for GCC
+ Copyright (C) 1991, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@@ -49,9 +49,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
(INSN_UID (INSN) < max_uid_for_loop ? uid_luid[INSN_UID (INSN)] \
: (abort (), -1))
-#define REGNO_FIRST_LUID(REGNO) uid_luid[REGNO_FIRST_UID (REGNO)]
-#define REGNO_LAST_LUID(REGNO) uid_luid[REGNO_LAST_UID (REGNO)]
-
+#define REGNO_FIRST_LUID(REGNO) \
+ (REGNO_FIRST_UID (REGNO) < max_uid_for_loop \
+ ? uid_luid[REGNO_FIRST_UID (REGNO)] \
+ : 0)
+#define REGNO_LAST_LUID(REGNO) \
+ (REGNO_LAST_UID (REGNO) < max_uid_for_loop \
+ ? uid_luid[REGNO_LAST_UID (REGNO)] \
+ : INT_MAX)
/* A "basic induction variable" or biv is a pseudo reg that is set
(within this loop) only by incrementing or decrementing it. */
@@ -396,34 +401,32 @@ extern FILE *loop_dump_stream;
/* Forward declarations for non-static functions declared in loop.c and
unroll.c. */
-int loop_invariant_p PARAMS ((const struct loop *, rtx));
-rtx get_condition_for_loop PARAMS ((const struct loop *, rtx));
-void loop_iv_add_mult_hoist PARAMS ((const struct loop *, rtx, rtx, rtx, rtx));
-void loop_iv_add_mult_sink PARAMS ((const struct loop *, rtx, rtx, rtx, rtx));
-void loop_iv_add_mult_emit_before PARAMS ((const struct loop *, rtx,
- rtx, rtx, rtx,
- basic_block, rtx));
-rtx express_from PARAMS ((struct induction *, struct induction *));
-rtx extend_value_for_giv PARAMS ((struct induction *, rtx));
-
-void unroll_loop PARAMS ((struct loop *, int, int));
-rtx biv_total_increment PARAMS ((const struct iv_class *));
-unsigned HOST_WIDE_INT loop_iterations PARAMS ((struct loop *));
-int precondition_loop_p PARAMS ((const struct loop *,
- rtx *, rtx *, rtx *,
- enum machine_mode *mode));
-rtx final_biv_value PARAMS ((const struct loop *, struct iv_class *));
-rtx final_giv_value PARAMS ((const struct loop *, struct induction *));
-void emit_unrolled_add PARAMS ((rtx, rtx, rtx));
-int back_branch_in_range_p PARAMS ((const struct loop *, rtx));
-
-int loop_insn_first_p PARAMS ((rtx, rtx));
-typedef rtx (*loop_insn_callback) PARAMS ((struct loop *, rtx, int, int));
-void for_each_insn_in_loop PARAMS ((struct loop *, loop_insn_callback));
-rtx loop_insn_emit_before PARAMS((const struct loop *, basic_block,
- rtx, rtx));
-rtx loop_insn_sink PARAMS((const struct loop *, rtx));
-rtx loop_insn_hoist PARAMS((const struct loop *, rtx));
+extern int loop_invariant_p (const struct loop *, rtx);
+extern rtx get_condition_for_loop (const struct loop *, rtx);
+extern void loop_iv_add_mult_hoist (const struct loop *, rtx, rtx, rtx, rtx);
+extern void loop_iv_add_mult_sink (const struct loop *, rtx, rtx, rtx, rtx);
+extern void loop_iv_add_mult_emit_before (const struct loop *, rtx, rtx,
+ rtx, rtx, basic_block, rtx);
+extern rtx express_from (struct induction *, struct induction *);
+extern rtx extend_value_for_giv (struct induction *, rtx);
+
+extern void unroll_loop (struct loop *, int, int);
+extern rtx biv_total_increment (const struct iv_class *);
+extern unsigned HOST_WIDE_INT loop_iterations (struct loop *);
+extern int precondition_loop_p (const struct loop *, rtx *, rtx *, rtx *,
+ enum machine_mode *mode);
+extern rtx final_biv_value (const struct loop *, struct iv_class *);
+extern rtx final_giv_value (const struct loop *, struct induction *);
+extern void emit_unrolled_add (rtx, rtx, rtx);
+extern int back_branch_in_range_p (const struct loop *, rtx);
+
+extern int loop_insn_first_p (rtx, rtx);
+typedef rtx (*loop_insn_callback) (struct loop *, rtx, int, int);
+extern void for_each_insn_in_loop (struct loop *, loop_insn_callback);
+extern rtx loop_insn_emit_before (const struct loop *, basic_block, rtx, rtx);
+extern rtx loop_insn_sink (const struct loop *, rtx);
+extern rtx loop_insn_hoist (const struct loop *, rtx);
/* Forward declarations for non-static functions declared in doloop.c. */
-int doloop_optimize PARAMS ((const struct loop *));
+extern rtx doloop_condition_get (rtx);
+extern int doloop_optimize (const struct loop *);
diff --git a/contrib/gcc/machmode.def b/contrib/gcc/machmode.def
index 5013e1f7cbe7..0b6c6771dbae 100644
--- a/contrib/gcc/machmode.def
+++ b/contrib/gcc/machmode.def
@@ -1,6 +1,7 @@
/* This file contains the definitions and documentation for the
machine modes used in the GNU compiler.
- Copyright (C) 1987, 1992, 1994, 1997, 1998, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1992, 1994, 1997, 1998, 2000, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -31,142 +32,192 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
has a machine mode which describes data of that type or the
data of the variable declared. */
-/* The first argument is the internal name of the machine mode
- used in the C source.
- By convention these are in UPPER_CASE, except for the word "mode".
-
- The second argument is the name of the machine mode in the
- external ASCII format used for reading and printing RTL and trees.
- By convention these names in UPPER_CASE.
-
- Third argument states the kind of representation:
- MODE_INT - integer
- MODE_FLOAT - floating
- MODE_PARTIAL_INT - PQImode, PHImode, PSImode and PDImode
- MODE_CC - modes used for representing the condition code in a register
- MODE_COMPLEX_INT, MODE_COMPLEX_FLOAT - complex number
- MODE_VECTOR_INT, MODE_VECTOR_FLOAT - vector
- MODE_RANDOM - anything else
-
- Fourth argument is the relative size of the object, in bits,
- so we can have modes smaller than 1 byte.
-
- Fifth argument is the relative size of the object, in bytes.
- It is zero when the size is meaningless or not determined.
- A byte's size is determined by BITS_PER_UNIT in tm.h.
-
- Sixth arg is the relative size of subunits of the object.
- It is same as the fifth argument except for complexes and vectors,
- since they are really made of many equal size subunits.
-
- Seventh arg is next wider natural mode of the same class. 0 if
- there is none. Vector modes use this field to point to the next
- vector size, so we can iterate through the different vectors modes.
- The ordering is by increasing byte size, with QI coming before HI,
- HI before SI, etc.
-
- Eigth arg is the mode of the internal elements in a vector or
- complex, and VOIDmode if not applicable.
-*/
+/* This file is included by the genmodes program. Its text is the
+ body of a function. Do not rely on this, it will change in the
+ future.
+
+ The following statements can be used in this file -- all have
+ the form of a C macro call. In their arguments:
+
+ A CLASS argument must be one of the constants defined in
+ mode-classes.def, less the leading MODE_ prefix; some statements
+ that take CLASS arguments have restructions on which classes are
+ acceptable. For instance, INT.
+
+ A MODE argument must be the printable name of a machine mode,
+ without quotation marks or trailing "mode". For instance, SI.
+
+ A PRECISION, BYTESIZE, or COUNT argument must be a positive integer
+ constant.
+
+ A FORMAT argument must be one of the real_mode_format structures
+ declared in real.h, or else a literal 0. Do not put a leading &
+ on the argument.
+
+ An EXPR argument must be a syntactically valid C expression.
+ If an EXPR contains commas, you may need to write an extra pair of
+ parentheses around it, so it appears to be a single argument to the
+ statement.
+
+ This file defines only those modes which are of use on almost all
+ machines. Other modes can be defined in the target-specific
+ mode definition file, config/ARCH/ARCH-modes.def.
+
+ Order matters in this file in so far as statements which refer to
+ other modes must appear after the modes they refer to. However,
+ statements which do not refer to other modes may appear in any
+ order.
+
+ RANDOM_MODE (MODE);
+ declares MODE to be of class RANDOM.
+
+ CC_MODE (MODE);
+ declares MODE to be of class CC.
+
+ INT_MODE (MODE, BYTESIZE);
+ declares MODE to be of class INT and BYTESIZE bytes wide.
+ All of the bits of its representation are significant.
+
+ FRACTIONAL_INT_MODE (MODE, PRECISION, BYTESIZE);
+ declares MODE to be of class INT, BYTESIZE bytes wide in
+ storage, but with only PRECISION significant bits.
+
+ FLOAT_MODE (MODE, BYTESIZE, FORMAT);
+ declares MODE to be of class FLOAT and BYTESIZE bytes wide,
+ using floating point format FORMAT.
+ All of the bits of its representation are significant.
+
+ FRACTIONAL_FLOAT_MODE (MODE, PRECISION, BYTESIZE, FORMAT);
+ declares MODE to be of class FLOAT, BYTESIZE bytes wide in
+ storage, but with only PRECISION significant bits, using
+ floating point format FORMAT.
+
+ RESET_FLOAT_FORMAT (MODE, FORMAT);
+ changes the format of MODE, which must be class FLOAT,
+ to FORMAT. Use in an ARCH-modes.def to reset the format
+ of one of the float modes defined in this file.
+
+ PARTIAL_INT_MODE (MODE);
+ declares a mode of class PARTIAL_INT with the same size as
+ MODE (which must be an INT mode). The name of the new mode
+ is made by prefixing a P to the name MODE. This statement
+ may grow a PRECISION argument in the future.
+
+ VECTOR_MODE (CLASS, MODE, COUNT);
+ Declare a vector mode whose component mode is MODE (of class
+ CLASS) with COUNT components. CLASS must be INT or FLOAT.
+ The name of the vector mode takes the form VnX where n is
+ COUNT in decimal and X is MODE.
+
+ VECTOR_MODES (CLASS, WIDTH);
+ For all modes presently declared in class CLASS, construct
+ corresponding vector modes having width WIDTH. Modes whose
+ byte sizes do not evenly divide WIDTH are ignored, as are
+ modes that would produce vector modes with only one component,
+ and modes smaller than one byte (if CLASS is INT) or smaller
+ than two bytes (if CLASS is FLOAT). CLASS must be INT or
+ FLOAT. The names follow the same rule as VECTOR_MODE uses.
+
+ COMPLEX_MODES (CLASS);
+ For all modes presently declared in class CLASS, construct
+ corresponding complex modes. Modes smaller than one byte
+ are ignored. For FLOAT modes, the names are derived by
+ replacing the 'F' in the mode name with a 'C'. (It is an
+ error if there is no 'F'. For INT modes, the names are
+ derived by prefixing a C to the name.
+
+ ADJUST_BYTESIZE (MODE, EXPR);
+ ADJUST_ALIGNMENT (MODE, EXPR);
+ ADJUST_FLOAT_FORMAT (MODE, EXPR);
+ Arrange for the byte size, alignment, or floating point format
+ of MODE to be adjustable at run time. EXPR will be executed
+ once after processing all command line options, and should
+ evaluate to the desired byte size, alignment, or format.
+
+ Unlike a FORMAT argument, if you are adjusting a float format
+ you must put an & in front of the name of each format structure.
+
+ Note: If a mode is ever made which is more than 255 bytes wide,
+ machmode.h and genmodes.c will have to be changed to allocate
+ more space for the mode_size and mode_alignment arrays. */
/* VOIDmode is used when no mode needs to be specified,
as for example on CONST_INT RTL expressions. */
-DEF_MACHMODE (VOIDmode, "VOID", MODE_RANDOM, 0, 0, 0, VOIDmode, VOIDmode)
-
-DEF_MACHMODE (BImode, "BI", MODE_INT, 1, 1, 1, QImode, VOIDmode)
-DEF_MACHMODE (QImode, "QI", MODE_INT, BITS_PER_UNIT, 1, 1, HImode, VOIDmode)
-DEF_MACHMODE (HImode, "HI", MODE_INT, BITS_PER_UNIT*2, 2, 2, SImode, VOIDmode)
-DEF_MACHMODE (SImode, "SI", MODE_INT, BITS_PER_UNIT*4, 4, 4, DImode, VOIDmode)
-DEF_MACHMODE (DImode, "DI", MODE_INT, BITS_PER_UNIT*8, 8, 8, TImode, VOIDmode)
-DEF_MACHMODE (TImode, "TI", MODE_INT, BITS_PER_UNIT*16, 16, 16, OImode, VOIDmode)
-DEF_MACHMODE (OImode, "OI", MODE_INT, BITS_PER_UNIT*32, 32, 32, VOIDmode, VOIDmode)
-
-/* Pointers on some machines use these types to distinguish them from
- ints. Useful if a pointer is 4 bytes but has some bits that are
- not significant, so it is really not quite as wide as an integer. */
-DEF_MACHMODE (PQImode, "PQI", MODE_PARTIAL_INT, BITS_PER_UNIT, 1, 1, PHImode, VOIDmode)
-DEF_MACHMODE (PHImode, "PHI", MODE_PARTIAL_INT, BITS_PER_UNIT*2, 2, 2, PSImode, VOIDmode)
-DEF_MACHMODE (PSImode, "PSI", MODE_PARTIAL_INT, BITS_PER_UNIT*4, 4, 4, PDImode, VOIDmode)
-DEF_MACHMODE (PDImode, "PDI", MODE_PARTIAL_INT, BITS_PER_UNIT*8, 8, 8, VOIDmode, VOIDmode)
-
-DEF_MACHMODE (QFmode, "QF", MODE_FLOAT, BITS_PER_UNIT, 1, 1, HFmode, VOIDmode)
-DEF_MACHMODE (HFmode, "HF", MODE_FLOAT, BITS_PER_UNIT*2, 2, 2, TQFmode, VOIDmode)
-DEF_MACHMODE (TQFmode, "TQF", MODE_FLOAT, BITS_PER_UNIT*3, 3, 3, SFmode, VOIDmode) /* MIL-STD-1750A */
-DEF_MACHMODE (SFmode, "SF", MODE_FLOAT, BITS_PER_UNIT*4, 4, 4, DFmode, VOIDmode)
-DEF_MACHMODE (DFmode, "DF", MODE_FLOAT, BITS_PER_UNIT*8, 8, 8, XFmode, VOIDmode)
-DEF_MACHMODE (XFmode, "XF", MODE_FLOAT, BITS_PER_UNIT*12, 12, 12, TFmode, VOIDmode) /* IEEE extended */
-DEF_MACHMODE (TFmode, "TF", MODE_FLOAT, BITS_PER_UNIT*16, 16, 16, VOIDmode, VOIDmode)
+RANDOM_MODE (VOID);
-/* Complex modes. */
-DEF_MACHMODE (QCmode, "QC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*2, 2, 1, HCmode, QFmode)
-DEF_MACHMODE (HCmode, "HC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*4, 4, 2, SCmode, HFmode)
-DEF_MACHMODE (SCmode, "SC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*8, 8, 4, DCmode, SFmode)
-DEF_MACHMODE (DCmode, "DC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*16, 16, 8, XCmode, DFmode)
-DEF_MACHMODE (XCmode, "XC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*24, 24, 12, TCmode, XFmode)
-DEF_MACHMODE (TCmode, "TC", MODE_COMPLEX_FLOAT, BITS_PER_UNIT*32, 32, 16, VOIDmode, TFmode)
-
-DEF_MACHMODE (CQImode, "CQI", MODE_COMPLEX_INT, BITS_PER_UNIT*2, 2, 1, CHImode, QImode)
-DEF_MACHMODE (CHImode, "CHI", MODE_COMPLEX_INT, BITS_PER_UNIT*4, 4, 2, CSImode, HImode)
-DEF_MACHMODE (CSImode, "CSI", MODE_COMPLEX_INT, BITS_PER_UNIT*8, 8, 4, CDImode, SImode)
-DEF_MACHMODE (CDImode, "CDI", MODE_COMPLEX_INT, BITS_PER_UNIT*16, 16, 8, CTImode, DImode)
-DEF_MACHMODE (CTImode, "CTI", MODE_COMPLEX_INT, BITS_PER_UNIT*32, 32, 16, COImode, TImode)
-DEF_MACHMODE (COImode, "COI", MODE_COMPLEX_INT, BITS_PER_UNIT*64, 64, 32, VOIDmode, OImode)
+/* BLKmode is used for structures, arrays, etc.
+ that fit no more specific mode. */
+RANDOM_MODE (BLK);
-/* Vector modes. */
-/* The wider mode field for vectors follows in order of increasing bit
- size with QI coming before HI, HI before SI, and SI before DI
- within same bit sizes. */
-DEF_MACHMODE (V1DImode, "V1DI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 8, V2QImode, DImode)
-DEF_MACHMODE (V2QImode, "V2QI", MODE_VECTOR_INT, BITS_PER_UNIT*2, 2, 1, V4QImode, QImode)
-DEF_MACHMODE (V2HImode, "V2HI", MODE_VECTOR_INT, BITS_PER_UNIT*4, 4, 2, V8QImode, HImode)
-DEF_MACHMODE (V2SImode, "V2SI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 4, V16QImode, SImode)
-DEF_MACHMODE (V2DImode, "V2DI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 8, V8SImode, DImode)
+/* Single bit mode used for booleans. */
+FRACTIONAL_INT_MODE (BI, 1, 1);
-DEF_MACHMODE (V4QImode, "V4QI", MODE_VECTOR_INT, BITS_PER_UNIT*4, 4, 1, V2HImode, QImode)
-DEF_MACHMODE (V4HImode, "V4HI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 2, V2SImode, HImode)
-DEF_MACHMODE (V4SImode, "V4SI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 4, V2DImode, SImode)
-DEF_MACHMODE (V4DImode, "V4DI", MODE_VECTOR_INT, BITS_PER_UNIT*32, 32, 8, V8DImode, DImode)
+/* Basic integer modes. We go up to TI in generic code (128 bits).
+ The name OI is reserved for a 256-bit type (needed by some back ends).
+ FIXME TI shouldn't be generically available either. */
+INT_MODE (QI, 1);
+INT_MODE (HI, 2);
+INT_MODE (SI, 4);
+INT_MODE (DI, 8);
+INT_MODE (TI, 16);
-DEF_MACHMODE (V8QImode, "V8QI", MODE_VECTOR_INT, BITS_PER_UNIT*8, 8, 1, V4HImode, QImode)
-DEF_MACHMODE (V8HImode, "V8HI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 2, V4SImode, HImode)
-DEF_MACHMODE (V8SImode, "V8SI", MODE_VECTOR_INT, BITS_PER_UNIT*32, 32, 4, V4DImode, SImode)
-DEF_MACHMODE (V8DImode, "V8DI", MODE_VECTOR_INT, BITS_PER_UNIT*64, 64, 8, VOIDmode, DImode)
+/* No partial integer modes are defined by default. */
-DEF_MACHMODE (V16QImode, "V16QI", MODE_VECTOR_INT, BITS_PER_UNIT*16, 16, 1, V8HImode, QImode)
+/* Basic floating point modes. SF and DF are the only modes provided
+ by default. The names QF, HF, XF, and TF are reserved for targets
+ that need 1-word, 2-word, 80-bit, or 128-bit float types respectively.
-DEF_MACHMODE (V2SFmode, "V2SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*8, 8, 4, V4SFmode, SFmode)
-DEF_MACHMODE (V2DFmode, "V2DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 8, V8SFmode, DFmode)
+ These are the IEEE mappings. They can be overridden with
+ RESET_FLOAT_FORMAT or at runtime (in OVERRIDE_OPTIONS). */
-DEF_MACHMODE (V4SFmode, "V4SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*16, 16, 4, V2DFmode, SFmode)
-DEF_MACHMODE (V4DFmode, "V4DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*32, 32, 8, V8DFmode, DFmode)
+FLOAT_MODE (SF, 4, ieee_single_format);
+FLOAT_MODE (DF, 8, ieee_double_format);
-DEF_MACHMODE (V8SFmode, "V8SF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*32, 32, 4,V4DFmode, SFmode)
-DEF_MACHMODE (V8DFmode, "V8DF", MODE_VECTOR_FLOAT, BITS_PER_UNIT*64, 64, 8, VOIDmode, DFmode)
-DEF_MACHMODE (V16SFmode, "V16SF", MODE_VECTOR_FLOAT, 512, 64, 4, VOIDmode, SFmode)
+/* Basic CC modes.
+ FIXME define this only for targets that need it. */
+CC_MODE (CC);
-/* BLKmode is used for structures, arrays, etc.
- that fit no more specific mode. */
-DEF_MACHMODE (BLKmode, "BLK", MODE_RANDOM, 0, 0, 0, VOIDmode, VOIDmode)
-
-/* The modes for representing the condition codes come last. CCmode
- is always defined. Additional modes for the condition code can be
- specified in the EXTRA_CC_MODES header. All MODE_CC modes are the
- same width as SImode and have VOIDmode as their next wider mode. */
-
-/* We do not use CC() for CCmode to avoid a warning about use of
- function-like macros with no arguments. */
-DEF_MACHMODE (CCmode, "CC", MODE_CC, BITS_PER_UNIT*4, 4, 4, VOIDmode, VOIDmode)
-
-#ifdef EXTRA_MODES_FILE
-#define CC(N) \
- DEF_MACHMODE (CONCAT2 (N,mode), STRINGX (N), \
- MODE_CC, BITS_PER_UNIT*4, 4, 4, VOIDmode, VOIDmode)
-#include EXTRA_MODES_FILE
-#undef CC
+/* Allow the target to specify additional modes of various kinds. */
+#if HAVE_EXTRA_MODES
+# include EXTRA_MODES_FILE
#endif
+/* Complex modes. */
+COMPLEX_MODES (INT);
+COMPLEX_MODES (FLOAT);
+
+/* Vector modes. */
+VECTOR_MODES (INT, 2); /* V2QI */
+VECTOR_MODES (INT, 4); /* V4QI V2HI */
+VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
+VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */
+/* VECTOR_MODES (INT, 32); V8SI V4DI */
+/* VECTOR_MODES (INT, 64); V8DI */
+
+VECTOR_MODE (INT, SI, 8)
+VECTOR_MODE (INT, DI, 4);
+VECTOR_MODE (INT, DI, 8);
+
+/* PPC uses this to distinguish between DImode passed in
+ float registers and DImode passed in vector registers.
+ It would be in rs6000-modes.def but it's referenced in
+ c-common.c. FIXME. */
+
+VECTOR_MODE (INT, DI, 1);
+
+VECTOR_MODES (FLOAT, 4); /* V2HF */
+VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */
+VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */
+/* VECTOR_MODES (FLOAT, 32); V8SF V4DF */
+/* VECTOR_MODES (FLOAT, 64); V16SF V8DF */
+
+VECTOR_MODE (FLOAT, SF, 8);
+VECTOR_MODE (FLOAT, SF, 16);
+VECTOR_MODE (FLOAT, DF, 4);
+VECTOR_MODE (FLOAT, DF, 8);
+
/* The symbol Pmode stands for one of the above machine modes (usually SImode).
- The tm file specifies which one. It is not a distinct mode. */
+ The tm.h file specifies which one. It is not a distinct mode. */
/*
Local variables:
diff --git a/contrib/gcc/machmode.h b/contrib/gcc/machmode.h
index 46247d573434..c978c0a9b52e 100644
--- a/contrib/gcc/machmode.h
+++ b/contrib/gcc/machmode.h
@@ -1,5 +1,5 @@
-/* Machine mode definitions for GNU C-Compiler; included by rtl.h and tree.h.
- Copyright (C) 1991, 1993, 1994, 1996, 1998, 1999, 2000, 2001
+/* Machine mode definitions for GCC; included by rtl.h and tree.h.
+ Copyright (C) 1991, 1993, 1994, 1996, 1998, 1999, 2000, 2001, 2003
Free Software Foundation, Inc.
This file is part of GCC.
@@ -23,34 +23,26 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define HAVE_MACHINE_MODES
/* Make an enum class that gives all the machine modes. */
-
-#define DEF_MACHMODE(SYM, NAME, TYPE, BITSIZE, SIZE, UNIT, WIDER, INNER) SYM,
-
-enum machine_mode {
-#include "machmode.def"
-MAX_MACHINE_MODE };
-
-#undef DEF_MACHMODE
-
-#ifndef NUM_MACHINE_MODES
-#define NUM_MACHINE_MODES (int) MAX_MACHINE_MODE
-#endif
+#include "insn-modes.h"
/* Get the name of mode MODE as a string. */
extern const char * const mode_name[NUM_MACHINE_MODES];
-#define GET_MODE_NAME(MODE) (mode_name[(int) (MODE)])
+#define GET_MODE_NAME(MODE) mode_name[MODE]
+
+/* Mode classes. */
-enum mode_class { MODE_RANDOM, MODE_INT, MODE_FLOAT, MODE_PARTIAL_INT, MODE_CC,
- MODE_COMPLEX_INT, MODE_COMPLEX_FLOAT,
- MODE_VECTOR_INT, MODE_VECTOR_FLOAT,
- MAX_MODE_CLASS};
+#include "mode-classes.def"
+#define DEF_MODE_CLASS(M) M
+enum mode_class { MODE_CLASSES, MAX_MODE_CLASS };
+#undef DEF_MODE_CLASS
+#undef MODE_CLASSES
/* Get the general kind of object that mode MODE represents
(integer, floating, complex, etc.) */
-extern const enum mode_class mode_class[NUM_MACHINE_MODES];
-#define GET_MODE_CLASS(MODE) (mode_class[(int) (MODE)])
+extern const unsigned char mode_class[NUM_MACHINE_MODES];
+#define GET_MODE_CLASS(MODE) mode_class[MODE]
/* Nonzero if MODE is an integral mode. */
#define INTEGRAL_MODE_P(MODE) \
@@ -84,87 +76,79 @@ extern const enum mode_class mode_class[NUM_MACHINE_MODES];
#define SCALAR_FLOAT_MODE_P(MODE) \
(GET_MODE_CLASS (MODE) == MODE_FLOAT)
-/* Get the size in bytes of an object of mode MODE. */
-
-extern const unsigned char mode_size[NUM_MACHINE_MODES];
-#define GET_MODE_SIZE(MODE) (mode_size[(int) (MODE)])
-
-/* Get the size in bytes of the basic parts of an object of mode MODE. */
-
-extern const unsigned char mode_unit_size[NUM_MACHINE_MODES];
-#define GET_MODE_UNIT_SIZE(MODE) (mode_unit_size[(int) (MODE)])
-
-/* Get the number of units in the object. */
-
-#define GET_MODE_NUNITS(MODE) \
- ((GET_MODE_UNIT_SIZE ((MODE)) == 0) ? 0 \
- : (GET_MODE_SIZE ((MODE)) / GET_MODE_UNIT_SIZE ((MODE))))
+/* Get the size in bytes and bits of an object of mode MODE. */
-/* Get the size in bits of an object of mode MODE. */
+extern CONST_MODE_SIZE unsigned char mode_size[NUM_MACHINE_MODES];
+#define GET_MODE_SIZE(MODE) ((unsigned short) mode_size[MODE])
+#define GET_MODE_BITSIZE(MODE) ((unsigned short) (GET_MODE_SIZE (MODE) * BITS_PER_UNIT))
-extern const unsigned short mode_bitsize[NUM_MACHINE_MODES];
-#define GET_MODE_BITSIZE(MODE) (mode_bitsize[(int) (MODE)])
-
-#endif /* not HAVE_MACHINE_MODES */
-
-#if defined HOST_WIDE_INT && ! defined GET_MODE_MASK
+/* Get the number of value bits of an object of mode MODE. */
+extern const unsigned short mode_precision[NUM_MACHINE_MODES];
+#define GET_MODE_PRECISION(MODE) mode_precision[MODE]
/* Get a bitmask containing 1 for all bits in a word
that fit within mode MODE. */
extern const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES];
-#define GET_MODE_MASK(MODE) mode_mask_array[(int) (MODE)]
-
-extern const enum machine_mode inner_mode_array[NUM_MACHINE_MODES];
+#define GET_MODE_MASK(MODE) mode_mask_array[MODE]
/* Return the mode of the inner elements in a vector. */
-#define GET_MODE_INNER(MODE) inner_mode_array[(int) (MODE)]
+extern const unsigned char mode_inner[NUM_MACHINE_MODES];
+#define GET_MODE_INNER(MODE) mode_inner[MODE]
-#endif /* defined (HOST_WIDE_INT) && ! defined GET_MODE_MASK */
+/* Get the size in bytes of the basic parts of an object of mode MODE. */
-#if ! defined GET_MODE_WIDER_MODE || ! defined GET_MODE_ALIGNMENT \
- || ! defined GET_CLASS_NARROWEST_MODE
+#define GET_MODE_UNIT_SIZE(MODE) \
+ (GET_MODE_INNER (MODE) == VOIDmode \
+ ? GET_MODE_SIZE (MODE) \
+ : GET_MODE_SIZE (GET_MODE_INNER (MODE)))
+
+/* Get the number of units in the object. */
+
+extern const unsigned char mode_nunits[NUM_MACHINE_MODES];
+#define GET_MODE_NUNITS(MODE) mode_nunits[MODE]
/* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */
-extern const unsigned char mode_wider_mode[NUM_MACHINE_MODES];
-#define GET_MODE_WIDER_MODE(MODE) ((enum machine_mode)mode_wider_mode[(int) (MODE)])
+extern const unsigned char mode_wider[NUM_MACHINE_MODES];
+#define GET_MODE_WIDER_MODE(MODE) mode_wider[MODE]
/* Return the mode for data of a given size SIZE and mode class CLASS.
If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE.
The value is BLKmode if no other mode is found. */
-extern enum machine_mode mode_for_size PARAMS ((unsigned int,
- enum mode_class, int));
+extern enum machine_mode mode_for_size (unsigned int, enum mode_class, int);
/* Similar, but find the smallest mode for a given width. */
-extern enum machine_mode smallest_mode_for_size
- PARAMS ((unsigned int, enum mode_class));
+extern enum machine_mode smallest_mode_for_size (unsigned int,
+ enum mode_class);
/* Return an integer mode of the exact same size as the input mode,
or BLKmode on failure. */
-extern enum machine_mode int_mode_for_mode PARAMS ((enum machine_mode));
+extern enum machine_mode int_mode_for_mode (enum machine_mode);
/* Find the best mode to use to access a bit field. */
-extern enum machine_mode get_best_mode PARAMS ((int, int, unsigned int,
- enum machine_mode, int));
+extern enum machine_mode get_best_mode (int, int, unsigned int,
+ enum machine_mode, int);
/* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */
-extern unsigned get_mode_alignment PARAMS ((enum machine_mode));
+extern CONST_MODE_BASE_ALIGN unsigned char mode_base_align[NUM_MACHINE_MODES];
+
+extern unsigned get_mode_alignment (enum machine_mode);
#define GET_MODE_ALIGNMENT(MODE) get_mode_alignment (MODE)
/* For each class, get the narrowest mode in that class. */
-extern const enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
-#define GET_CLASS_NARROWEST_MODE(CLASS) class_narrowest_mode[(int) (CLASS)]
+extern const unsigned char class_narrowest_mode[MAX_MODE_CLASS];
+#define GET_CLASS_NARROWEST_MODE(CLASS) class_narrowest_mode[CLASS]
/* Define the integer modes whose sizes are BITS_PER_UNIT and BITS_PER_WORD
and the mode whose class is Pmode and whose size is POINTER_SIZE. */
@@ -173,5 +157,7 @@ extern enum machine_mode byte_mode;
extern enum machine_mode word_mode;
extern enum machine_mode ptr_mode;
-#endif /* ! defined GET_MODE_WIDER_MODE || ! defined GET_MODE_ALIGNMENT
- || ! defined GET_CLASS_NARROWEST_MODE */
+/* Target-dependent machine mode initialization - in insn-modes.c. */
+extern void init_adjust_machine_modes (void);
+
+#endif /* not HAVE_MACHINE_MODES */
diff --git a/contrib/gcc/main.c b/contrib/gcc/main.c
index 49418bd05d70..16a936e58b7e 100644
--- a/contrib/gcc/main.c
+++ b/contrib/gcc/main.c
@@ -19,18 +19,18 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
-int main PARAMS ((int argc, char **argv));
+int main (int argc, char **argv);
/* We define main() to call toplev_main(), which is defined in toplev.c.
We do this in a separate file in order to allow the language front-end
to define a different main(), if it so desires. */
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
- return toplev_main (argc, argv);
+ return toplev_main (argc, (const char **) argv);
}
diff --git a/contrib/gcc/mips-tdump.c b/contrib/gcc/mips-tdump.c
index d7040d95b70a..e25c175ef54d 100644
--- a/contrib/gcc/mips-tdump.c
+++ b/contrib/gcc/mips-tdump.c
@@ -1,5 +1,5 @@
/* Read and manage MIPS symbol tables from object modules.
- Copyright (C) 1991, 1994, 1995, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1991, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2003
Free Software Foundation, Inc.
Contributed by hartzell@boulder.colorado.edu,
Rewritten by meissner@osf.org.
@@ -23,6 +23,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "version.h"
#ifdef index
#undef index
#endif
@@ -32,6 +35,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "mips/a.out.h"
#endif /* CROSS_COMPILE */
+/* Include getopt.h for the sake of getopt_long. */
+#include "getopt.h"
+
#ifndef MIPS_IS_STAB
/* Macros for mips-tfile.c to encapsulate stabs in ECOFF, and for
and mips-tdump.c to print them out. This is used on the Alpha,
@@ -207,6 +213,8 @@ int want_line = 0; /* print line numbers */
int want_rfd = 0; /* print relative file desc's */
int want_scope = 0; /* print scopes for every symbol */
int tfile = 0; /* no global header file */
+int version = 0; /* print version # */
+int verbose = 0;
int tfile_fd; /* file descriptor of .T file */
off_t tfile_offset; /* current offset in .T file */
scope_t *cur_scope = 0; /* list of active scopes */
@@ -226,19 +234,19 @@ ulong *rfile_desc; /* relative file tables */
PDR *proc_desc; /* procedure tables */
/* Forward reference for functions. */
-static PTR read_seek PARAMS ((PTR, size_t, off_t, const char *));
-static void read_tfile PARAMS ((void));
-static void print_global_hdr PARAMS ((struct filehdr *));
-static void print_sym_hdr PARAMS ((HDRR *));
-static void print_file_desc PARAMS ((FDR *, int));
-static void print_symbol PARAMS ((SYMR *, int, const char *, AUXU *, int, FDR *));
-static void print_aux PARAMS ((AUXU, int, int));
-static void emit_aggregate PARAMS ((char *, AUXU, AUXU, const char *, FDR *));
-static const char *st_to_string PARAMS ((st_t));
-static const char *sc_to_string PARAMS ((sc_t));
-static const char *glevel_to_string PARAMS ((glevel_t));
-static const char *lang_to_string PARAMS ((lang_t));
-static const char *type_to_string PARAMS ((AUXU *, int, FDR *));
+static void *read_seek (void *, size_t, off_t, const char *);
+static void read_tfile (void);
+static void print_global_hdr (struct filehdr *);
+static void print_sym_hdr (HDRR *);
+static void print_file_desc (FDR *, int);
+static void print_symbol (SYMR *, int, const char *, AUXU *, int, FDR *);
+static void print_aux (AUXU, int, int);
+static void emit_aggregate (char *, AUXU, AUXU, const char *, FDR *);
+static const char *st_to_string (st_t);
+static const char *sc_to_string (sc_t);
+static const char *glevel_to_string (glevel_t);
+static const char *lang_to_string (lang_t);
+static const char *type_to_string (AUXU *, int, FDR *);
extern char *optarg;
extern int optind;
@@ -252,15 +260,22 @@ const struct {const short code; const char string[10];} stab_names[] = {
#undef __define_stab
};
+/* Command line options for getopt_long. */
+
+static const struct option options[] =
+{
+ { "version", 0, 0, 'V' },
+ { "verbose", 0, 0, 'v' },
+ { 0, 0, 0, 0 }
+};
-/* Read some bytes at a specified location, and return a pointer. */
-
-static PTR
-read_seek (ptr, size, offset, context)
- PTR ptr; /* pointer to buffer or NULL */
- size_t size; /* # bytes to read */
- off_t offset; /* offset to read at */
- const char *context; /* context for error message */
+/* Read some bytes at a specified location, and return a pointer.
+ Read_seek takes a pointer PTR to a buffer or NULL and reads SIZE
+ bytes from offset OFFSET. In case of errors CONTEXT is used as
+ error message. */
+
+static void *
+read_seek (void *ptr, size_t size, off_t offset, const char *context)
{
long read_size = 0;
@@ -292,8 +307,7 @@ read_seek (ptr, size, offset, context)
/* Convert language code to string format. */
static const char *
-lang_to_string (lang)
- lang_t lang;
+lang_to_string (lang_t lang)
{
switch (lang)
{
@@ -315,8 +329,7 @@ lang_to_string (lang)
/* Convert storage class to string. */
static const char *
-sc_to_string(storage_class)
- sc_t storage_class;
+sc_to_string (sc_t storage_class)
{
switch(storage_class)
{
@@ -353,8 +366,7 @@ sc_to_string(storage_class)
/* Convert symbol type to string. */
static const char *
-st_to_string(symbol_type)
- st_t symbol_type;
+st_to_string (st_t symbol_type)
{
switch(symbol_type)
{
@@ -394,8 +406,7 @@ st_to_string(symbol_type)
/* Convert debug level to string. */
static const char *
-glevel_to_string (g_level)
- glevel_t g_level;
+glevel_to_string (glevel_t g_level)
{
switch(g_level)
{
@@ -407,15 +418,12 @@ glevel_to_string (g_level)
return "??";
}
-
+
/* Convert the type information to string format. */
static const char *
-type_to_string (aux_ptr, index, fdp)
- AUXU *aux_ptr;
- int index;
- FDR *fdp;
+type_to_string (AUXU *aux_ptr, int index, FDR *fdp)
{
AUXU u;
struct qual {
@@ -725,8 +733,7 @@ type_to_string (aux_ptr, index, fdp)
/* Print out the global file header for object files. */
static void
-print_global_hdr (ptr)
- struct filehdr *ptr;
+print_global_hdr (struct filehdr *ptr)
{
char *time = ctime ((time_t *)&ptr->f_timdat);
ushort flags = ptr->f_flags;
@@ -780,8 +787,7 @@ print_global_hdr (ptr)
/* Print out the symbolic header. */
static void
-print_sym_hdr (sym_ptr)
- HDRR *sym_ptr;
+print_sym_hdr (HDRR *sym_ptr)
{
int width = 20;
@@ -854,13 +860,8 @@ print_sym_hdr (sym_ptr)
/* Print out a symbol. */
static void
-print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
- SYMR *sym_ptr;
- int number;
- const char *strbase;
- AUXU *aux_base;
- int ifd;
- FDR *fdp;
+print_symbol (SYMR *sym_ptr, int number, const char *strbase, AUXU *aux_base,
+ int ifd, FDR *fdp)
{
sc_t storage_class = (sc_t) sym_ptr->sc;
st_t symbol_type = (st_t) sym_ptr->st;
@@ -883,7 +884,7 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
if (want_scope)
{
if (free_scope == (scope_t *) 0)
- scope_ptr = (scope_t *) xmalloc (sizeof (scope_t));
+ scope_ptr = xmalloc (sizeof (scope_t));
else
{
scope_ptr = free_scope;
@@ -937,7 +938,7 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
if (want_scope)
{
if (free_scope == (scope_t *) 0)
- scope_ptr = (scope_t *) xmalloc (sizeof (scope_t));
+ scope_ptr = xmalloc (sizeof (scope_t));
else
{
scope_ptr = free_scope;
@@ -1034,10 +1035,7 @@ print_symbol (sym_ptr, number, strbase, aux_base, ifd, fdp)
/* Print out a word from the aux. table in various formats. */
static void
-print_aux (u, auxi, used)
- AUXU u;
- int auxi;
- int used;
+print_aux (AUXU u, int auxi, int used)
{
printf ("\t%s#%-5d %11ld, [%4ld/%7ld], [%2d %1d:%1d %1x:%1x:%1x:%1x:%1x:%1x]\n",
(used) ? " " : "* ",
@@ -1060,20 +1058,15 @@ print_aux (u, auxi, used)
/* Write aggregate information to a string. */
static void
-emit_aggregate (string, u, u2, which, fdp)
- char *string;
- AUXU u;
- AUXU u2;
- const char *which;
- FDR *fdp;
+emit_aggregate (char *string, AUXU u, AUXU u2, const char *which, FDR *fdp)
{
unsigned int ifd = u.rndx.rfd;
unsigned int index = u.rndx.index;
const char *name;
-
+
if (ifd == ST_RFDESCAPE)
ifd = u2.isym;
-
+
/* An ifd of -1 is an opaque type. An escaped index of 0 is a
struct return type of a procedure compiled without -g. */
if (ifd == 0xffffffff
@@ -1089,7 +1082,7 @@ emit_aggregate (string, u, u2, which, fdp)
fdp = &file_desc[rfile_desc[fdp->rfdBase + ifd]];
name = &l_strings[fdp->issBase + l_symbols[index + fdp->isymBase].iss];
}
-
+
sprintf (string,
"%s %s { ifd = %u, index = %u }",
which, name, ifd, index);
@@ -1100,24 +1093,22 @@ emit_aggregate (string, u, u2, which, fdp)
procedures, and line numbers within it. */
static void
-print_file_desc (fdp, number)
- FDR *fdp;
- int number;
+print_file_desc (FDR *fdp, int number)
{
char *str_base;
AUXU *aux_base;
int symi, pdi;
int width = 20;
char *used_base;
-
- str_base = l_strings + fdp->issBase;
+
+ str_base = l_strings + fdp->issBase;
aux_base = aux_symbols + fdp->iauxBase;
used_base = aux_used + (aux_base - aux_symbols);
printf ("\nFile #%d, \"%s\"\n\n",
number,
fdp->rss != issNil ? str_base + fdp->rss : "<unknown>");
-
+
printf (" Name index = %-10ld Readin = %s\n",
(long) fdp->rss, (fdp->fReadin) ? "Yes" : "No");
@@ -1187,7 +1178,7 @@ print_file_desc (fdp, number)
if (want_scope && cur_scope != (scope_t *) 0)
printf ("\n Warning scope does not start at 0!\n");
- /*
+ /*
* print the info about the symbol table.
*/
printf ("\n There are %lu local symbols, starting at %lu\n",
@@ -1240,7 +1231,7 @@ print_file_desc (fdp, number)
}
}
- /*
+ /*
* do the procedure descriptors.
*/
printf ("\n There are %lu procedure descriptor entries, ", (ulong) fdp->cpd);
@@ -1328,18 +1319,17 @@ print_file_desc (fdp, number)
/* Read in the portions of the .T file that we will print out. */
static void
-read_tfile ()
+read_tfile (void)
{
short magic;
off_t sym_hdr_offset = 0;
- (void) read_seek ((PTR) &magic, sizeof (magic), (off_t) 0, "Magic number");
+ read_seek (&magic, sizeof (magic), 0, "Magic number");
if (!tfile)
{
/* Print out the global header, since this is not a T-file. */
- (void) read_seek ((PTR) &global_hdr, sizeof (global_hdr), (off_t) 0,
- "Global file header");
+ read_seek (&global_hdr, sizeof (global_hdr), 0, "Global file header");
print_global_hdr (&global_hdr);
@@ -1352,87 +1342,60 @@ read_tfile ()
sym_hdr_offset = global_hdr.f_symptr;
}
- (void) read_seek ((PTR) &sym_hdr,
- sizeof (sym_hdr),
- sym_hdr_offset,
- "Symbolic header");
+ read_seek (&sym_hdr, sizeof (sym_hdr), sym_hdr_offset, "Symbolic header");
print_sym_hdr (&sym_hdr);
- lines = (LINER *) read_seek (NULL,
- sym_hdr.cbLine,
- sym_hdr.cbLineOffset,
- "Line numbers");
+ lines = read_seek (NULL, sym_hdr.cbLine, sym_hdr.cbLineOffset,
+ "Line numbers");
- dense_nums = (DNR *) read_seek (NULL,
- sym_hdr.idnMax * sizeof (DNR),
- sym_hdr.cbDnOffset,
- "Dense numbers");
+ dense_nums = read_seek (NULL, sym_hdr.idnMax * sizeof (DNR),
+ sym_hdr.cbDnOffset, "Dense numbers");
- proc_desc = (PDR *) read_seek (NULL,
- sym_hdr.ipdMax * sizeof (PDR),
- sym_hdr.cbPdOffset,
- "Procedure tables");
+ proc_desc = read_seek (NULL, sym_hdr.ipdMax * sizeof (PDR),
+ sym_hdr.cbPdOffset, "Procedure tables");
- l_symbols = (SYMR *) read_seek (NULL,
- sym_hdr.isymMax * sizeof (SYMR),
- sym_hdr.cbSymOffset,
- "Local symbols");
+ l_symbols = read_seek (NULL, sym_hdr.isymMax * sizeof (SYMR),
+ sym_hdr.cbSymOffset, "Local symbols");
- opt_symbols = (OPTR *) read_seek (NULL,
- sym_hdr.ioptMax * sizeof (OPTR),
- sym_hdr.cbOptOffset,
- "Optimization symbols");
+ opt_symbols = read_seek (NULL, sym_hdr.ioptMax * sizeof (OPTR),
+ sym_hdr.cbOptOffset, "Optimization symbols");
- aux_symbols = (AUXU *) read_seek (NULL,
- sym_hdr.iauxMax * sizeof (AUXU),
- sym_hdr.cbAuxOffset,
- "Auxiliary symbols");
+ aux_symbols = read_seek (NULL, sym_hdr.iauxMax * sizeof (AUXU),
+ sym_hdr.cbAuxOffset, "Auxiliary symbols");
if (sym_hdr.iauxMax > 0)
aux_used = xcalloc (sym_hdr.iauxMax, 1);
- l_strings = (char *) read_seek (NULL,
- sym_hdr.issMax,
- sym_hdr.cbSsOffset,
- "Local string table");
-
- e_strings = (char *) read_seek (NULL,
- sym_hdr.issExtMax,
- sym_hdr.cbSsExtOffset,
- "External string table");
-
- file_desc = (FDR *) read_seek (NULL,
- sym_hdr.ifdMax * sizeof (FDR),
- sym_hdr.cbFdOffset,
- "File tables");
-
- rfile_desc = (ulong *) read_seek (NULL,
- sym_hdr.crfd * sizeof (ulong),
- sym_hdr.cbRfdOffset,
- "Relative file tables");
-
- e_symbols = (EXTR *) read_seek (NULL,
- sym_hdr.iextMax * sizeof (EXTR),
- sym_hdr.cbExtOffset,
- "External symbols");
+ l_strings = read_seek (NULL, sym_hdr.issMax,
+ sym_hdr.cbSsOffset, "Local string table");
+
+ e_strings = read_seek (NULL, sym_hdr.issExtMax,
+ sym_hdr.cbSsExtOffset, "External string table");
+
+ file_desc = read_seek (NULL, sym_hdr.ifdMax * sizeof (FDR),
+ sym_hdr.cbFdOffset, "File tables");
+
+ rfile_desc = read_seek (NULL, sym_hdr.crfd * sizeof (ulong),
+ sym_hdr.cbRfdOffset, "Relative file tables");
+
+ e_symbols = read_seek (NULL, sym_hdr.iextMax * sizeof (EXTR),
+ sym_hdr.cbExtOffset, "External symbols");
}
-extern int main PARAMS ((int, char **));
+extern int main (int, char **);
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
int i, opt;
/*
* Process arguments
*/
- while ((opt = getopt (argc, argv, "alrst")) != EOF)
+ while ((opt = getopt_long (argc, argv, "alrsvt", options, NULL)) != -1)
switch (opt)
{
default: errors++; break;
@@ -1440,10 +1403,35 @@ main (argc, argv)
case 'l': want_line++; break; /* print line numbers */
case 'r': want_rfd++; break; /* print relative fd's */
case 's': want_scope++; break; /* print scope info */
- case 't': tfile++; break; /* this is a tfile (without header), and not a .o */
+ case 'v': verbose++; break; /* print version # */
+ case 'V': version++; break; /* print version # */
+ case 't': tfile++; break; /* this is a tfile (without header),
+ and not a .o */
}
- if (errors || optind != argc - 1)
+ if (version)
+ {
+ printf ("mips-tdump (GCC) %s\n", version_string);
+ fputs ("Copyright (C) 2003 Free Software Foundation, Inc.\n", stdout);
+ fputs ("This is free software; see the source for copying conditions. There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n",
+ stdout);
+ exit (0);
+ }
+
+ if (optind != argc - 1)
+ errors++;
+
+ if (verbose || errors)
+ {
+ fprintf (stderr, "mips-tdump (GCC) %s", version_string);
+#ifdef TARGET_VERSION
+ TARGET_VERSION;
+#endif
+ fputc ('\n', stderr);
+ }
+
+ if (errors)
{
fprintf (stderr, "Calling Sequence:\n");
fprintf (stderr, "\t%s [-alrst] <object-or-T-file>\n", argv[0]);
@@ -1454,6 +1442,7 @@ main (argc, argv)
fprintf (stderr, "\t-r Print out relative file descriptors.\n");
fprintf (stderr, "\t-s Print out the current scopes for an item.\n");
fprintf (stderr, "\t-t Assume there is no global header (ie, a T-file).\n");
+ fprintf (stderr, "\t-v Print program version.\n");
return 1;
}
@@ -1504,7 +1493,7 @@ main (argc, argv)
for (i = 0; i < sym_hdr.ifdMax; i++)
print_file_desc (&file_desc[i], i);
- /*
+ /*
* Print the external symbols.
*/
want_scope = 0; /* scope info is meaning for extern symbols */
diff --git a/contrib/gcc/mips-tfile.c b/contrib/gcc/mips-tfile.c
index e354c9108f0b..9b333063e34d 100644
--- a/contrib/gcc/mips-tfile.c
+++ b/contrib/gcc/mips-tfile.c
@@ -2,10 +2,10 @@
contain debugging information specified by the GNU compiler
in the form of comments (the mips assembler does not support
assembly access to debug information).
- Copyright (C) 1991, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
- Free Software Foundation, Inc.
+ Copyright (C) 1991, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Meissner (meissner@cygnus.com).
-
+
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
@@ -98,31 +98,31 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
array, pointer, function, etc. qualifiers. The
current base types that I have documentation for are:
- btNil -- undefined
+ btNil -- undefined
btAdr -- address - integer same size as ptr
- btChar -- character
- btUChar -- unsigned character
- btShort -- short
- btUShort -- unsigned short
- btInt -- int
- btUInt -- unsigned int
- btLong -- long
- btULong -- unsigned long
- btFloat -- float (real)
- btDouble -- Double (real)
- btStruct -- Structure (Record)
- btUnion -- Union (variant)
- btEnum -- Enumerated
- btTypedef -- defined via a typedef isymRef
- btRange -- subrange of int
- btSet -- pascal sets
- btComplex -- fortran complex
- btDComplex -- fortran double complex
- btIndirect -- forward or unnamed typedef
- btFixedDec -- Fixed Decimal
- btFloatDec -- Float Decimal
- btString -- Varying Length Character String
- btBit -- Aligned Bit String
+ btChar -- character
+ btUChar -- unsigned character
+ btShort -- short
+ btUShort -- unsigned short
+ btInt -- int
+ btUInt -- unsigned int
+ btLong -- long
+ btULong -- unsigned long
+ btFloat -- float (real)
+ btDouble -- Double (real)
+ btStruct -- Structure (Record)
+ btUnion -- Union (variant)
+ btEnum -- Enumerated
+ btTypedef -- defined via a typedef isymRef
+ btRange -- subrange of int
+ btSet -- pascal sets
+ btComplex -- fortran complex
+ btDComplex -- fortran double complex
+ btIndirect -- forward or unnamed typedef
+ btFixedDec -- Fixed Decimal
+ btFloatDec -- Float Decimal
+ btString -- Varying Length Character String
+ btBit -- Aligned Bit String
btPicture -- Picture
btVoid -- Void (MIPS cc revision >= 2.00)
@@ -130,12 +130,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
current type qualifier fields I have documentation for
are:
- tqNil -- no more qualifiers
- tqPtr -- pointer
- tqProc -- procedure
- tqArray -- array
- tqFar -- 8086 far pointers
- tqVol -- volatile
+ tqNil -- no more qualifiers
+ tqPtr -- pointer
+ tqProc -- procedure
+ tqArray -- array
+ tqFar -- 8086 far pointers
+ tqVol -- volatile
The dense number table is used in the front ends, and disappears by
@@ -163,7 +163,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
Each file table has offsets for where the line numbers, local
strings, local symbols, and procedure table starts from within the
- global tables, and the indexs are reset to 0 for each of those
+ global tables, and the indices are reset to 0 for each of those
tables for the file.
The procedure table contains the binary equivalents of the .ent
@@ -244,7 +244,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
}
Mips-tdump produces the following information:
-
+
Global file header:
magic number 0x162
# sections 2
@@ -253,12 +253,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
symbolic header size 96
optional header 56
flags 0x0
-
+
Symbolic header, magic number = 0x7009, vstamp = 1.31:
-
+
Info Offset Number Bytes
==== ====== ====== =====
-
+
Line numbers 380 4 4 [13]
Dense numbers 0 0 0
Procedures Tables 384 1 52
@@ -270,14 +270,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
File Tables 1008 2 144
Relative Files 0 0 0
External Symbols 1152 20 320
-
+
File #0, "hello2.c"
-
+
Name index = 1 Readin = No
Merge = No Endian = LITTLE
Debug level = G2 Language = C
Adr = 0x00000000
-
+
Info Start Number Size Offset
==== ===== ====== ==== ======
Local strings 0 15 15 784
@@ -287,7 +287,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
Procedures 0 1 52 384
Auxiliary symbols 0 14 56 628
Relative Files 0 0 0 0
-
+
There are 6 local symbols, starting at 436
Symbol# 0: "hello2.c"
@@ -602,6 +602,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "version.h"
#include "intl.h"
@@ -609,6 +611,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define saber_stop()
#endif
+/* Include getopt.h for the sake of getopt_long. */
+#include "getopt.h"
+
#ifndef __LINE__
#define __LINE__ 0
#endif
@@ -631,13 +636,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* The following might be called from obstack or malloc,
so they can't be static. */
-extern void pfatal_with_name
- PARAMS ((const char *)) ATTRIBUTE_NORETURN;
-extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
- void botch PARAMS ((const char *)) ATTRIBUTE_NORETURN;
+extern void pfatal_with_name (const char *) ATTRIBUTE_NORETURN;
+extern void fancy_abort (void) ATTRIBUTE_NORETURN;
+extern void botch (const char *) ATTRIBUTE_NORETURN;
-extern void fatal PARAMS ((const char *format, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-extern void error PARAMS ((const char *format, ...)) ATTRIBUTE_PRINTF_1;
+extern void fatal (const char *format, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
+extern void error (const char *format, ...) ATTRIBUTE_PRINTF_1;
#ifndef MIPS_DEBUGGING_INFO
@@ -649,7 +653,7 @@ static const char *progname;
static const char *input_name;
int
-main ()
+main (void)
{
fprintf (stderr, "Mips-tfile should only be run on a MIPS computer!\n");
exit (1);
@@ -893,13 +897,10 @@ enum alloc_type {
pages. On systems with a BSD malloc that define USE_MALLOC, the
MAX_CLUSTER_PAGES should be 1 less than a power of two, since malloc
adds its overhead, and rounds up to the next power of 2. Pages are
- linked together via a linked list.
-
- If PAGE_SIZE is > 4096, the string length in the shash_t structure
- can't be represented (assuming there are strings > 4096 bytes). */
+ linked together via a linked list. */
#ifndef PAGE_SIZE
-#define PAGE_SIZE 4096 /* size of varray pages */
+#define PAGE_SIZE 32768 /* size of varray pages */
#endif
#define PAGE_USIZE ((Size_t) PAGE_SIZE)
@@ -948,6 +949,13 @@ typedef struct varray {
OBJECTS_PER_PAGE (type), /* objects_last_page */ \
}
+#define INITIALIZE_VARRAY(x,type) \
+do { \
+ (x)->object_size = sizeof (type); \
+ (x)->objects_per_page = OBJECTS_PER_PAGE (type); \
+ (x)->objects_last_page = OBJECTS_PER_PAGE (type); \
+} while (0)
+
/* Master type for indexes within the symbol table. */
typedef unsigned long symint_t;
@@ -1064,90 +1072,8 @@ typedef struct efdr {
} efdr_t;
/* Pre-initialized extended file structure. */
-static efdr_t init_file =
-{
- { /* FDR structure */
-#ifdef __alpha
- 0, /* adr: memory address of beginning of file */
- 0, /* cbLineOffset: byte offset from header for this file ln's */
- 0, /* cbLine: size of lines for this file */
- 0, /* cbSs: number of bytes in the ss */
- 0, /* rss: file name (of source, if known) */
- 0, /* issBase: file's string space */
- 0, /* isymBase: beginning of symbols */
- 0, /* csym: count file's of symbols */
- 0, /* ilineBase: file's line symbols */
- 0, /* cline: count of file's line symbols */
- 0, /* ioptBase: file's optimization entries */
- 0, /* copt: count of file's optimization entries */
- 0, /* ipdFirst: start of procedures for this file */
- 0, /* cpd: count of procedures for this file */
- 0, /* iauxBase: file's auxiliary entries */
- 0, /* caux: count of file's auxiliary entries */
- 0, /* rfdBase: index into the file indirect table */
- 0, /* crfd: count file indirect entries */
- langC, /* lang: language for this file */
- 1, /* fMerge: whether this file can be merged */
- 0, /* fReadin: true if read in (not just created) */
-#ifdef HOST_WORDS_BIG_ENDIAN
- 1, /* fBigendian: if 1, compiled on big endian machine */
-#else
- 0, /* fBigendian: if 1, compiled on big endian machine */
-#endif
- 0, /* fTrim: whether the symbol table was trimmed */
- GLEVEL_2, /* glevel: level this file was compiled with */
- 0, /* reserved: reserved for future use */
-#else
- 0, /* adr: memory address of beginning of file */
- 0, /* rss: file name (of source, if known) */
- 0, /* issBase: file's string space */
- 0, /* cbSs: number of bytes in the ss */
- 0, /* isymBase: beginning of symbols */
- 0, /* csym: count file's of symbols */
- 0, /* ilineBase: file's line symbols */
- 0, /* cline: count of file's line symbols */
- 0, /* ioptBase: file's optimization entries */
- 0, /* copt: count of file's optimization entries */
- 0, /* ipdFirst: start of procedures for this file */
- 0, /* cpd: count of procedures for this file */
- 0, /* iauxBase: file's auxiliary entries */
- 0, /* caux: count of file's auxiliary entries */
- 0, /* rfdBase: index into the file indirect table */
- 0, /* crfd: count file indirect entries */
- langC, /* lang: language for this file */
- 1, /* fMerge: whether this file can be merged */
- 0, /* fReadin: true if read in (not just created) */
-#ifdef HOST_WORDS_BIG_ENDIAN
- 1, /* fBigendian: if 1, compiled on big endian machine */
-#else
- 0, /* fBigendian: if 1, compiled on big endian machine */
-#endif
- GLEVEL_2, /* glevel: level this file was compiled with */
- 0, /* reserved: reserved for future use */
- 0, /* cbLineOffset: byte offset from header for this file ln's */
- 0, /* cbLine: size of lines for this file */
-#endif
- },
-
- (FDR *) 0, /* orig_fdr: original file header pointer */
- (char *) 0, /* name: pointer to filename */
- 0, /* name_len: length of filename */
- 0, /* void_type: ptr to aux node for void type */
- 0, /* int_type: ptr to aux node for int type */
- (scope_t *) 0, /* cur_scope: current scope being processed */
- 0, /* file_index: current file # */
- 0, /* nested_scopes: # nested scopes */
- INIT_VARRAY (char), /* strings: local string varray */
- INIT_VARRAY (SYMR), /* symbols: local symbols varray */
- INIT_VARRAY (PDR), /* procs: procedure varray */
- INIT_VARRAY (AUXU), /* aux_syms: auxiliary symbols varray */
-
- (struct efdr *) 0, /* next_file: next file structure */
-
- (shash_t **) 0, /* shash_head: string hash table */
- { 0 }, /* thash_head: type hash table */
-};
-
+static int init_file_initialized = 0;
+static efdr_t init_file;
static efdr_t *first_file; /* first file descriptor */
static efdr_t **last_file_ptr = &first_file; /* file descriptor tail */
@@ -1568,8 +1494,8 @@ static SYMR *cur_oproc_begin = (SYMR *) 0; /* original proc. sym begin info *
static SYMR *cur_oproc_end = (SYMR *) 0; /* original proc. sym end info */
static PDR *cur_oproc_ptr = (PDR *) 0; /* current original procedure*/
static thead_t *cur_tag_head = (thead_t *) 0;/* current tag head */
-static long file_offset = 0; /* current file offset */
-static long max_file_offset = 0; /* maximum file offset */
+static unsigned long file_offset = 0; /* current file offset */
+static unsigned long max_file_offset = 0; /* maximum file offset */
static FILE *object_stream = (FILE *) 0; /* file desc. to output .o */
static FILE *obj_in_stream = (FILE *) 0; /* file desc. to input .o */
static char *progname = (char *) 0; /* program name for errors */
@@ -1581,8 +1507,9 @@ static char *cur_line_ptr = (char *) 0; /* ptr within current line */
static unsigned cur_line_nbytes = 0; /* # bytes for current line */
static unsigned cur_line_alloc = 0; /* # bytes total in buffer */
static long line_number = 0; /* current input line number */
-static int debug = 0; /* trace functions */
-static int version = 0; /* print version # */
+static int debug = 0; /* trace functions */
+static int version = 0; /* print version # */
+static int verbose = 0;
static int had_errors = 0; /* != 0 if errors were found */
static int rename_output = 0; /* != 0 if rename output file*/
static int delete_input = 0; /* != 0 if delete input after done */
@@ -1603,107 +1530,64 @@ static const char stabs_symbol[] = STABS_SYMBOL;
#define STATIC static
#endif
-STATIC int out_of_bounds PARAMS ((symint_t, symint_t, const char *, int));
-
-STATIC shash_t *hash_string PARAMS ((const char *,
- Ptrdiff_t,
- shash_t **,
- symint_t *));
-
-STATIC symint_t add_string PARAMS ((varray_t *,
- shash_t **,
- const char *,
- const char *,
- shash_t **));
-
-STATIC symint_t add_local_symbol
- PARAMS ((const char *,
- const char *,
- st_t,
- sc_t,
- symint_t,
- symint_t));
-
-STATIC symint_t add_ext_symbol PARAMS ((EXTR *,
- int));
-
-STATIC symint_t add_aux_sym_symint
- PARAMS ((symint_t));
-
-STATIC symint_t add_aux_sym_rndx
- PARAMS ((int, symint_t));
-
-STATIC symint_t add_aux_sym_tir PARAMS ((type_info_t *,
- hash_state_t,
- thash_t **));
-
-STATIC tag_t * get_tag PARAMS ((const char *,
- const char *,
- symint_t,
- bt_t));
-
-STATIC void add_unknown_tag PARAMS ((tag_t *));
-
-STATIC void add_procedure PARAMS ((const char *,
- const char *));
-
-STATIC void add_file PARAMS ((const char *,
- const char *));
-
-STATIC void add_bytes PARAMS ((varray_t *,
- char *,
- Size_t));
-
-STATIC void add_varray_page PARAMS ((varray_t *));
-
-STATIC void update_headers PARAMS ((void));
-
-STATIC void write_varray PARAMS ((varray_t *, off_t, const char *));
-STATIC void write_object PARAMS ((void));
-STATIC const char *st_to_string PARAMS ((st_t));
-STATIC const char *sc_to_string PARAMS ((sc_t));
-STATIC char *read_line PARAMS ((void));
-STATIC void parse_input PARAMS ((void));
-STATIC void mark_stabs PARAMS ((const char *));
-STATIC void parse_begin PARAMS ((const char *));
-STATIC void parse_bend PARAMS ((const char *));
-STATIC void parse_def PARAMS ((const char *));
-STATIC void parse_end PARAMS ((const char *));
-STATIC void parse_ent PARAMS ((const char *));
-STATIC void parse_file PARAMS ((const char *));
-STATIC void parse_stabs_common
- PARAMS ((const char *, const char *, const char *));
-STATIC void parse_stabs PARAMS ((const char *));
-STATIC void parse_stabn PARAMS ((const char *));
-STATIC page_t *read_seek PARAMS ((Size_t, off_t, const char *));
-STATIC void copy_object PARAMS ((void));
-
-STATIC void catch_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
-STATIC page_t *allocate_page PARAMS ((void));
-
-STATIC page_t *allocate_multiple_pages
- PARAMS ((Size_t));
-
-STATIC void free_multiple_pages
- PARAMS ((page_t *, Size_t));
+STATIC int out_of_bounds (symint_t, symint_t, const char *, int);
+STATIC shash_t *hash_string (const char *, Ptrdiff_t, shash_t **, symint_t *);
+STATIC symint_t add_string (varray_t *, shash_t **, const char *, const char *,
+ shash_t **);
+STATIC symint_t add_local_symbol (const char *, const char *, st_t, sc_t,
+ symint_t, symint_t);
+STATIC symint_t add_ext_symbol (EXTR *, int);
+STATIC symint_t add_aux_sym_symint (symint_t);
+STATIC symint_t add_aux_sym_rndx (int, symint_t);
+STATIC symint_t add_aux_sym_tir (type_info_t *, hash_state_t, thash_t **);
+STATIC tag_t * get_tag (const char *, const char *, symint_t, bt_t);
+STATIC void add_unknown_tag (tag_t *);
+STATIC void add_procedure (const char *, const char *);
+STATIC void initialize_init_file (void);
+STATIC void add_file (const char *, const char *);
+STATIC void add_bytes (varray_t *, char *, Size_t);
+STATIC void add_varray_page (varray_t *);
+STATIC void update_headers (void);
+STATIC void write_varray (varray_t *, off_t, const char *);
+STATIC void write_object (void);
+STATIC const char *st_to_string (st_t);
+STATIC const char *sc_to_string (sc_t);
+STATIC char *read_line (void);
+STATIC void parse_input (void);
+STATIC void mark_stabs (const char *);
+STATIC void parse_begin (const char *);
+STATIC void parse_bend (const char *);
+STATIC void parse_def (const char *);
+STATIC void parse_end (const char *);
+STATIC void parse_ent (const char *);
+STATIC void parse_file (const char *);
+STATIC void parse_stabs_common (const char *, const char *, const char *);
+STATIC void parse_stabs (const char *);
+STATIC void parse_stabn (const char *);
+STATIC page_t *read_seek (Size_t, off_t, const char *);
+STATIC void copy_object (void);
+
+STATIC void catch_signal (int) ATTRIBUTE_NORETURN;
+STATIC page_t *allocate_page (void);
+STATIC page_t *allocate_multiple_pages (Size_t);
+STATIC void free_multiple_pages (page_t *, Size_t);
#ifndef MALLOC_CHECK
-STATIC page_t *allocate_cluster
- PARAMS ((Size_t));
+STATIC page_t *allocate_cluster (Size_t);
#endif
-STATIC forward_t *allocate_forward PARAMS ((void));
-STATIC scope_t *allocate_scope PARAMS ((void));
-STATIC shash_t *allocate_shash PARAMS ((void));
-STATIC tag_t *allocate_tag PARAMS ((void));
-STATIC thash_t *allocate_thash PARAMS ((void));
-STATIC thead_t *allocate_thead PARAMS ((void));
-STATIC vlinks_t *allocate_vlinks PARAMS ((void));
+STATIC forward_t *allocate_forward (void);
+STATIC scope_t *allocate_scope (void);
+STATIC shash_t *allocate_shash (void);
+STATIC tag_t *allocate_tag (void);
+STATIC thash_t *allocate_thash (void);
+STATIC thead_t *allocate_thead (void);
+STATIC vlinks_t *allocate_vlinks (void);
-STATIC void free_forward PARAMS ((forward_t *));
-STATIC void free_scope PARAMS ((scope_t *));
-STATIC void free_tag PARAMS ((tag_t *));
-STATIC void free_thead PARAMS ((thead_t *));
+STATIC void free_forward (forward_t *);
+STATIC void free_scope (scope_t *);
+STATIC void free_tag (tag_t *);
+STATIC void free_thead (thead_t *);
extern char *optarg;
extern int optind;
@@ -1717,7 +1601,7 @@ extern int opterr;
typedef struct _pseudo_ops {
const char *const name; /* pseudo-op in ascii */
const int len; /* length of name to compare */
- void (*const func) PARAMS ((const char *)); /* function to handle line */
+ void (*const func) (const char *); /* function to handle line */
} pseudo_ops_t;
static const pseudo_ops_t pseudo_ops[] = {
@@ -1735,17 +1619,25 @@ static const pseudo_ops_t pseudo_ops[] = {
};
+/* Command line options for getopt_long. */
+
+static const struct option options[] =
+{
+ { "version", 0, 0, 'V' },
+ { "verbose", 0, 0, 'v' },
+ { 0, 0, 0, 0 }
+};
+
/* Add a page to a varray object. */
STATIC void
-add_varray_page (vp)
- varray_t *vp; /* varray to add page to */
+add_varray_page (varray_t *vp)
{
vlinks_t *new_links = allocate_vlinks ();
#ifdef MALLOC_CHECK
if (vp->object_size > 1)
- new_links->datum = (page_t *) xcalloc (1, vp->object_size);
+ new_links->datum = xcalloc (1, vp->object_size);
else
#endif
new_links->datum = allocate_page ();
@@ -1772,11 +1664,8 @@ add_varray_page (vp)
#define HASHBITS 30
STATIC shash_t *
-hash_string (text, hash_len, hash_tbl, ret_hash_index)
- const char *text; /* ptr to text to hash */
- Ptrdiff_t hash_len; /* length of the text */
- shash_t **hash_tbl; /* hash table */
- symint_t *ret_hash_index; /* ptr to store hash index */
+hash_string (const char *text, Ptrdiff_t hash_len, shash_t **hash_tbl,
+ symint_t *ret_hash_index)
{
unsigned long hi;
Ptrdiff_t i;
@@ -1804,16 +1693,15 @@ hash_string (text, hash_len, hash_tbl, ret_hash_index)
/* Add a string (and null pad) to one of the string tables. A
- consequence of hashing strings, is that we don't let strings
- cross page boundaries. The extra nulls will be ignored. */
+ consequence of hashing strings, is that we don't let strings cross
+ page boundaries. The extra nulls will be ignored. VP is a string
+ virtual array, HASH_TBL a pointer to the hash table, the string
+ starts at START and the position one byte after the string is given
+ with END_P1, the resulting hash pointer is returned in RET_HASH. */
STATIC symint_t
-add_string (vp, hash_tbl, start, end_p1, ret_hash)
- varray_t *vp; /* string virtual array */
- shash_t **hash_tbl; /* ptr to hash table */
- const char *start; /* 1st byte in string */
- const char *end_p1; /* 1st byte after string */
- shash_t **ret_hash; /* return hash pointer */
+add_string (varray_t *vp, shash_t **hash_tbl, const char *start,
+ const char *end_p1, shash_t **ret_hash)
{
Ptrdiff_t len = end_p1 - start;
shash_t *hash_ptr;
@@ -1858,16 +1746,14 @@ add_string (vp, hash_tbl, start, end_p1, ret_hash)
}
-/* Add a local symbol. */
+/* Add a local symbol. The symbol string starts at STR_START and the
+ first byte after it is makred by STR_END_P1. The symbol has type
+ TYPE and storage class STORAGE and value VALUE. INDX is an index
+ to local/aux. symbols. */
STATIC symint_t
-add_local_symbol (str_start, str_end_p1, type, storage, value, indx)
- const char *str_start; /* first byte in string */
- const char *str_end_p1; /* first byte after string */
- st_t type; /* symbol type */
- sc_t storage; /* storage class */
- symint_t value; /* value of symbol */
- symint_t indx; /* index to local/aux. syms */
+add_local_symbol (const char *str_start, const char *str_end_p1, st_t type,
+ sc_t storage, symint_t value, symint_t indx)
{
symint_t ret;
SYMR *psym;
@@ -2036,12 +1922,11 @@ add_local_symbol (str_start, str_end_p1, type, storage, value, indx)
}
-/* Add an external symbol. */
+/* Add an external symbol with symbol pointer ESYM and file index
+ IFD. */
STATIC symint_t
-add_ext_symbol (esym, ifd)
- EXTR *esym; /* symbol pointer */
- int ifd; /* file index */
+add_ext_symbol (EXTR *esym, int ifd)
{
const char *str_start; /* first byte in string */
const char *str_end_p1; /* first byte after string */
@@ -2093,8 +1978,7 @@ add_ext_symbol (esym, ifd)
/* Add an auxiliary symbol (passing a symint). */
STATIC symint_t
-add_aux_sym_symint (aux_word)
- symint_t aux_word; /* auxiliary information word */
+add_aux_sym_symint (symint_t aux_word)
{
AUXU *aux_ptr;
efdr_t *file_ptr = cur_file_ptr;
@@ -2113,9 +1997,7 @@ add_aux_sym_symint (aux_word)
/* Add an auxiliary symbol (passing a file/symbol index combo). */
STATIC symint_t
-add_aux_sym_rndx (file_index, sym_index)
- int file_index;
- symint_t sym_index;
+add_aux_sym_rndx (int file_index, symint_t sym_index)
{
AUXU *aux_ptr;
efdr_t *file_ptr = cur_file_ptr;
@@ -2136,10 +2018,7 @@ add_aux_sym_rndx (file_index, sym_index)
type qualifiers). */
STATIC symint_t
-add_aux_sym_tir (t, state, hash_tbl)
- type_info_t *t; /* current type information */
- hash_state_t state; /* whether to hash type or not */
- thash_t **hash_tbl; /* pointer to hash table to use */
+add_aux_sym_tir (type_info_t *t, hash_state_t state, thash_t **hash_tbl)
{
AUXU *aux_ptr;
efdr_t *file_ptr = cur_file_ptr;
@@ -2223,7 +2102,7 @@ add_aux_sym_tir (t, state, hash_tbl)
ret = vp->num_allocated++;
/* Add bitfield length if it exists.
-
+
NOTE: Mips documentation claims bitfield goes at the end of the
AUX record, but the DECstation compiler emits it here.
(This would only make a difference for enum bitfields.)
@@ -2298,11 +2177,11 @@ add_aux_sym_tir (t, state, hash_tbl)
/* Add a tag to the tag table (unless it already exists). */
STATIC tag_t *
-get_tag (tag_start, tag_end_p1, indx, basic_type)
- const char *tag_start; /* 1st byte of tag name */
- const char *tag_end_p1; /* 1st byte after tag name */
- symint_t indx; /* index of tag start block */
- bt_t basic_type; /* bt_Struct, bt_Union, or bt_Enum */
+get_tag (const char *tag_start, /* 1st byte of tag name */
+ const char *tag_end_p1, /* 1st byte after tag name */
+ symint_t indx, /* index of tag start block */
+ bt_t basic_type) /* bt_Struct, bt_Union, or bt_Enum */
+
{
shash_t *hash_ptr;
tag_t *tag_ptr;
@@ -2350,8 +2229,7 @@ get_tag (tag_start, tag_end_p1, indx, basic_type)
/* Add an unknown {struct, union, enum} tag. */
STATIC void
-add_unknown_tag (ptag)
- tag_t *ptag; /* pointer to tag information */
+add_unknown_tag (tag_t *ptag)
{
shash_t *hash_ptr = ptag->hash_ptr;
char *name_start = hash_ptr->string;
@@ -2410,9 +2288,8 @@ add_unknown_tag (ptag)
this procedure, use that to initialize the current PDR. */
STATIC void
-add_procedure (func_start, func_end_p1)
- const char *func_start; /* 1st byte of func name */
- const char *func_end_p1; /* 1st byte after func name */
+add_procedure (const char *func_start, /* 1st byte of func name */
+ const char *func_end_p1) /* 1st byte after func name */
{
PDR *new_proc_ptr;
efdr_t *file_ptr = cur_file_ptr;
@@ -2471,14 +2348,36 @@ add_procedure (func_start, func_end_p1)
}
+/* Initialize the init_file structure. */
+
+STATIC void
+initialize_init_file (void)
+{
+ memset (&init_file, 0, sizeof (init_file));
+
+ init_file.fdr.lang = langC;
+ init_file.fdr.fMerge = 1;
+ init_file.fdr.glevel = GLEVEL_2;
+
+#ifdef HOST_WORDS_BIG_ENDIAN
+ init_file.fdr.fBigendian = 1;
+#endif
+
+ INITIALIZE_VARRAY (&init_file.strings, char);
+ INITIALIZE_VARRAY (&init_file.symbols, SYMR);
+ INITIALIZE_VARRAY (&init_file.procs, PDR);
+ INITIALIZE_VARRAY (&init_file.aux_syms, AUXU);
+
+ init_file_initialized = 1;
+}
+
/* Add a new filename, and set up all of the file relative
virtual arrays (strings, symbols, aux syms, etc.). Record
where the current file structure lives. */
STATIC void
-add_file (file_start, file_end_p1)
- const char *file_start; /* first byte in string */
- const char *file_end_p1; /* first byte after string */
+add_file (const char *file_start, /* first byte in string */
+ const char *file_end_p1) /* first byte after string */
{
static char zero_bytes[2] = { '\0', '\0' };
@@ -2509,6 +2408,9 @@ add_file (file_start, file_end_p1)
if (file_desc.objects_last_page == file_desc.objects_per_page)
add_varray_page (&file_desc);
+ if (! init_file_initialized)
+ initialize_init_file ();
+
file_ptr = cur_file_ptr
= &file_desc.last->datum->file[ file_desc.objects_last_page++ ];
*file_ptr = init_file;
@@ -2556,10 +2458,9 @@ add_file (file_start, file_end_p1)
/* Add a stream of random bytes to a varray. */
STATIC void
-add_bytes (vp, input_ptr, nitems)
- varray_t *vp; /* virtual array to add too */
- char *input_ptr; /* start of the bytes */
- Size_t nitems; /* # items to move */
+add_bytes (varray_t *vp, /* virtual array to add too */
+ char *input_ptr, /* start of the bytes */
+ Size_t nitems) /* # items to move */
{
Size_t move_items;
Size_t move_bytes;
@@ -2595,8 +2496,7 @@ add_bytes (vp, input_ptr, nitems)
/* Convert storage class to string. */
STATIC const char *
-sc_to_string (storage_class)
- sc_t storage_class;
+sc_to_string (sc_t storage_class)
{
switch (storage_class)
{
@@ -2633,8 +2533,7 @@ sc_to_string (storage_class)
/* Convert symbol type to string. */
STATIC const char *
-st_to_string (symbol_type)
- st_t symbol_type;
+st_to_string (st_t symbol_type)
{
switch (symbol_type)
{
@@ -2670,7 +2569,7 @@ st_to_string (symbol_type)
semi-colon, and return each logical line independently. */
STATIC char *
-read_line ()
+read_line (void)
{
static int line_split_p = 0;
int string_p = 0;
@@ -2746,8 +2645,7 @@ read_line ()
which gives the location of the start of the block. */
STATIC void
-parse_begin (start)
- const char *start; /* start of directive */
+parse_begin (const char *start)
{
const char *end_p1; /* end of label */
int ch;
@@ -2798,8 +2696,7 @@ parse_begin (start)
which gives the location of the end of the block. */
STATIC void
-parse_bend (start)
- const char *start; /* start of directive */
+parse_bend (const char *start)
{
const char *end_p1; /* end of label */
int ch;
@@ -2857,8 +2754,7 @@ parse_bend (start)
.tag specify a tag for a struct, union, or enum. */
STATIC void
-parse_def (name_start)
- const char *name_start; /* start of directive */
+parse_def (const char *name_start)
{
const char *dir_start; /* start of current directive*/
const char *dir_end_p1; /* end+1 of current directive*/
@@ -2923,7 +2819,7 @@ parse_def (name_start)
&& memcmp (dir_start, ".endef", sizeof (".endef")-1) == 0)
break;
- /* Pick up the subdirective now */
+ /* Pick up the subdirective now. */
for (dir_end_p1 = dir_start+1;
(ch = *dir_end_p1) != ' ' && ch != '\t';
dir_end_p1++)
@@ -2948,7 +2844,7 @@ parse_def (name_start)
{
int ch2;
arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
- if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
+ if (arg_end_p1 != arg_start || ((ch2 = *arg_end_p1) != ';') || ch2 != ',')
arg_was_number++;
}
@@ -3004,7 +2900,7 @@ parse_def (name_start)
{
int ch2;
arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
- if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
+ if (arg_end_p1 != arg_start || ((ch2 = *arg_end_p1) != ';') || ch2 != ',')
arg_was_number++;
if (t_ptr == &temp_array[0])
@@ -3078,7 +2974,7 @@ parse_def (name_start)
{
int ch2;
arg_number = strtol (arg_start, (char **) &arg_end_p1, 0);
- if (arg_end_p1 != arg_start || (ch2 = *arg_end_p1 != ';') || ch2 != ',')
+ if (arg_end_p1 != arg_start || ((ch2 = *arg_end_p1) != ';') || ch2 != ',')
arg_was_number++;
if (t_ptr == &temp_array[0])
@@ -3177,7 +3073,7 @@ parse_def (name_start)
class, symbol type, etc. */
else
{
- shash_t *orig_hash_ptr; /* hash within orig sym table*/
+ shash_t *orig_hash_ptr; /* hash within orig sym table*/
shash_t *ext_hash_ptr; /* hash within ext. sym table*/
ext_hash_ptr = hash_string (arg_start,
@@ -3384,7 +3280,7 @@ parse_def (name_start)
value,
indx);
- /* deal with struct, union, and enum tags. */
+ /* Deal with struct, union, and enum tags. */
if (symbol_type == st_Block)
{
/* Create or update the tag information. */
@@ -3432,8 +3328,7 @@ bomb_out:
/* Parse .end directives. */
STATIC void
-parse_end (start)
- const char *start; /* start of directive */
+parse_end (const char *start)
{
const char *start_func, *end_func_p1;
int ch;
@@ -3495,8 +3390,7 @@ parse_end (start)
/* Parse .ent directives. */
STATIC void
-parse_ent (start)
- const char *start; /* start of directive */
+parse_ent (const char *start)
{
const char *start_func, *end_func_p1;
int ch;
@@ -3533,8 +3427,7 @@ parse_ent (start)
/* Parse .file directives. */
STATIC void
-parse_file (start)
- const char *start; /* start of directive */
+parse_file (const char *start)
{
char *p;
char *start_name, *end_name_p1;
@@ -3561,8 +3454,7 @@ parse_file (start)
/* Make sure the @stabs symbol is emitted. */
static void
-mark_stabs (start)
- const char *start ATTRIBUTE_UNUSED; /* Start of directive (ignored) */
+mark_stabs (const char *start ATTRIBUTE_UNUSED)
{
if (!stabs_seen)
{
@@ -3606,10 +3498,9 @@ mark_stabs (start)
value a numeric value or an address. */
STATIC void
-parse_stabs_common (string_start, string_end, rest)
- const char *string_start; /* start of string or NULL */
- const char *string_end; /* end+1 of string or NULL */
- const char *rest; /* rest of the directive. */
+parse_stabs_common (const char *string_start, /* start of string or NULL */
+ const char *string_end, /* end+1 of string or NULL */
+ const char *rest) /* rest of the directive. */
{
efdr_t *save_file_ptr = cur_file_ptr;
symint_t code;
@@ -3805,8 +3696,7 @@ parse_stabs_common (string_start, string_end, rest)
STATIC void
-parse_stabs (start)
- const char *start; /* start of directive */
+parse_stabs (const char *start)
{
const char *end = strchr (start+1, '"');
@@ -3821,8 +3711,7 @@ parse_stabs (start)
STATIC void
-parse_stabn (start)
- const char *start; /* start of directive */
+parse_stabn (const char *start)
{
parse_stabs_common ((const char *) 0, (const char *) 0, start);
}
@@ -3832,7 +3721,7 @@ parse_stabn (start)
if needed. */
STATIC void
-parse_input ()
+parse_input (void)
{
char *p;
Size_t i;
@@ -3852,7 +3741,7 @@ parse_input ()
while ((p = read_line ()) != (char *) 0)
{
- /* Skip leading blanks */
+ /* Skip leading blanks. */
while (ISSPACE ((unsigned char)*p))
p++;
@@ -3895,7 +3784,7 @@ parse_input ()
to write out the .T file. */
STATIC void
-update_headers ()
+update_headers (void)
{
symint_t i;
efdr_t *file_ptr;
@@ -3951,7 +3840,7 @@ update_headers ()
hash_ptr = hash_string (str,
(Ptrdiff_t) len,
&file_ptr->shash_head[0],
- (symint_t *) 0);
+ (symint_t *) 0);
if (hash_ptr == (shash_t *) 0)
{
(void) add_local_symbol (str, str + len,
@@ -4081,10 +3970,9 @@ update_headers ()
/* Write out a varray at a given location. */
STATIC void
-write_varray (vp, offset, str)
- varray_t *vp; /* virtual array */
- off_t offset; /* offset to write varray to */
- const char *str; /* string to print out when tracing */
+write_varray (varray_t *vp, /* virtual array */
+ off_t offset, /* offset to write varray to */
+ const char *str) /* string to print out when tracing */
{
int num_write, sys_write;
vlinks_t *ptr;
@@ -4093,14 +3981,12 @@ write_varray (vp, offset, str)
return;
if (debug)
- {
- fputs ("\twarray\tvp = ", stderr);
- fprintf (stderr, HOST_PTR_PRINTF, (PTR) vp);
- fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
- (unsigned long) offset, vp->num_allocated * vp->object_size, str);
- }
-
- if (file_offset != offset
+ fprintf (stderr, "\twarray\tvp = " HOST_PTR_PRINTF
+ ", offset = %7lu, size = %7lu, %s\n",
+ (void *) vp, (unsigned long) offset,
+ vp->num_allocated * vp->object_size, str);
+
+ if (file_offset != (unsigned long) offset
&& fseek (object_stream, (long) offset, SEEK_SET) < 0)
pfatal_with_name (object_name);
@@ -4110,7 +3996,7 @@ write_varray (vp, offset, str)
? vp->objects_last_page * vp->object_size
: vp->objects_per_page * vp->object_size;
- sys_write = fwrite ((PTR) ptr->datum, 1, num_write, object_stream);
+ sys_write = fwrite (ptr->datum, 1, num_write, object_stream);
if (sys_write <= 0)
pfatal_with_name (object_name);
@@ -4128,21 +4014,19 @@ write_varray (vp, offset, str)
/* Write out the symbol table in the object file. */
STATIC void
-write_object ()
+write_object (void)
{
int sys_write;
efdr_t *file_ptr;
off_t offset;
if (debug)
- {
- fputs ("\n\twrite\tvp = ", stderr);
- fprintf (stderr, HOST_PTR_PRINTF, (PTR) &symbolic_header);
- fprintf (stderr, ", offset = %7u, size = %7lu, %s\n",
- 0, (unsigned long) sizeof (symbolic_header), "symbolic header");
- }
+ fprintf (stderr, "\n\twrite\tvp = " HOST_PTR_PRINTF
+ ", offset = %7u, size = %7lu, %s\n",
+ (void *) &symbolic_header, 0,
+ (unsigned long) sizeof (symbolic_header), "symbolic header");
- sys_write = fwrite ((PTR) &symbolic_header,
+ sys_write = fwrite (&symbolic_header,
1,
sizeof (symbolic_header),
object_stream);
@@ -4163,20 +4047,17 @@ write_object ()
{
long sys_write;
- if (file_offset != symbolic_header.cbLineOffset
+ if (file_offset != (unsigned long) symbolic_header.cbLineOffset
&& fseek (object_stream, symbolic_header.cbLineOffset, SEEK_SET) != 0)
pfatal_with_name (object_name);
if (debug)
- {
- fputs ("\twrite\tvp = ", stderr);
- fprintf (stderr, HOST_PTR_PRINTF, (PTR) &orig_linenum);
- fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
- (long) symbolic_header.cbLineOffset,
- (long) symbolic_header.cbLine, "Line numbers");
- }
+ fprintf (stderr, "\twrite\tvp = " HOST_PTR_PRINTF
+ ", offset = %7lu, size = %7lu, %s\n",
+ (void *) &orig_linenum, (long) symbolic_header.cbLineOffset,
+ (long) symbolic_header.cbLine, "Line numbers");
- sys_write = fwrite ((PTR) orig_linenum,
+ sys_write = fwrite (orig_linenum,
1,
symbolic_header.cbLine,
object_stream);
@@ -4198,20 +4079,17 @@ write_object ()
long sys_write;
long num_write = symbolic_header.ioptMax * sizeof (OPTR);
- if (file_offset != symbolic_header.cbOptOffset
+ if (file_offset != (unsigned long) symbolic_header.cbOptOffset
&& fseek (object_stream, symbolic_header.cbOptOffset, SEEK_SET) != 0)
pfatal_with_name (object_name);
if (debug)
- {
- fputs ("\twrite\tvp = ", stderr);
- fprintf (stderr, HOST_PTR_PRINTF, (PTR) &orig_opt_syms);
- fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
- (long) symbolic_header.cbOptOffset,
- num_write, "Optimizer symbols");
- }
+ fprintf (stderr, "\twrite\tvp = " HOST_PTR_PRINTF
+ ", offset = %7lu, size = %7lu, %s\n",
+ (void *) &orig_opt_syms, (long) symbolic_header.cbOptOffset,
+ num_write, "Optimizer symbols");
- sys_write = fwrite ((PTR) orig_opt_syms,
+ sys_write = fwrite (orig_opt_syms,
1,
num_write,
object_stream);
@@ -4285,7 +4163,7 @@ write_object ()
if (symbolic_header.ifdMax > 0) /* file tables */
{
offset = symbolic_header.cbFdOffset;
- if (file_offset != offset
+ if (file_offset != (unsigned long) offset
&& fseek (object_stream, (long) offset, SEEK_SET) < 0)
pfatal_with_name (object_name);
@@ -4295,13 +4173,10 @@ write_object ()
file_ptr = file_ptr->next_file)
{
if (debug)
- {
- fputs ("\twrite\tvp = ", stderr);
- fprintf (stderr, HOST_PTR_PRINTF, (PTR) &file_ptr->fdr);
- fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
- file_offset, (unsigned long) sizeof (FDR),
- "File header");
- }
+ fprintf (stderr, "\twrite\tvp = " HOST_PTR_PRINTF
+ ", offset = %7lu, size = %7lu, %s\n",
+ (void *) &file_ptr->fdr, file_offset,
+ (unsigned long) sizeof (FDR), "File header");
sys_write = fwrite (&file_ptr->fdr,
1,
@@ -4326,18 +4201,15 @@ write_object ()
long sys_write;
symint_t num_write = symbolic_header.crfd * sizeof (symint_t);
- if (file_offset != symbolic_header.cbRfdOffset
+ if (file_offset != (unsigned long) symbolic_header.cbRfdOffset
&& fseek (object_stream, symbolic_header.cbRfdOffset, SEEK_SET) != 0)
pfatal_with_name (object_name);
if (debug)
- {
- fputs ("\twrite\tvp = ", stderr);
- fprintf (stderr, HOST_PTR_PRINTF, (PTR) &orig_rfds);
- fprintf (stderr, ", offset = %7lu, size = %7lu, %s\n",
- (long) symbolic_header.cbRfdOffset,
- num_write, "Relative file descriptors");
- }
+ fprintf (stderr, "\twrite\tvp = " HOST_PTR_PRINTF
+ ", offset = %7lu, size = %7lu, %s\n",
+ (void *) &orig_rfds, (long) symbolic_header.cbRfdOffset,
+ num_write, "Relative file descriptors");
sys_write = fwrite (orig_rfds,
1,
@@ -4367,10 +4239,9 @@ write_object ()
/* Read some bytes at a specified location, and return a pointer. */
STATIC page_t *
-read_seek (size, offset, str)
- Size_t size; /* # bytes to read */
- off_t offset; /* offset to read at */
- const char *str; /* name for tracing */
+read_seek (Size_t size, /* # bytes to read */
+ off_t offset, /* offset to read at */
+ const char *str) /* name for tracing */
{
page_t *ptr;
long sys_read = 0;
@@ -4386,12 +4257,12 @@ read_seek (size, offset, str)
#ifndef MALLOC_CHECK
ptr = allocate_multiple_pages ((size + PAGE_USIZE - 1) / PAGE_USIZE);
#else
- ptr = (page_t *) xcalloc (1, size);
+ ptr = xcalloc (1, size);
#endif
/* If we need to seek, and the distance is nearby, just do some reads,
to speed things up. */
- if (file_offset != offset)
+ if (file_offset != (unsigned long) offset)
{
symint_t difference = offset - file_offset;
@@ -4413,7 +4284,7 @@ read_seek (size, offset, str)
pfatal_with_name (obj_in_name);
}
- sys_read = fread ((PTR) ptr, 1, size, obj_in_stream);
+ sys_read = fread (ptr, 1, size, obj_in_stream);
if (sys_read <= 0)
pfatal_with_name (obj_in_name);
@@ -4437,7 +4308,7 @@ read_seek (size, offset, str)
symbol table. */
STATIC void
-copy_object ()
+copy_object (void)
{
char buffer[ PAGE_SIZE ];
int sys_read;
@@ -4456,7 +4327,7 @@ copy_object ()
|| fseek (obj_in_stream, 0L, SEEK_SET) != 0)
pfatal_with_name (obj_in_name);
- sys_read = fread ((PTR) &orig_file_header,
+ sys_read = fread (&orig_file_header,
1,
sizeof (struct filehdr),
obj_in_stream);
@@ -4483,7 +4354,7 @@ copy_object ()
if (fseek (obj_in_stream, (long) orig_file_header.f_symptr, SEEK_SET) != 0)
pfatal_with_name (input_name);
- sys_read = fread ((PTR) &orig_sym_hdr,
+ sys_read = fread (&orig_sym_hdr,
1,
sizeof (orig_sym_hdr),
obj_in_stream);
@@ -4508,68 +4379,68 @@ copy_object ()
file_offset = orig_file_header.f_symptr + sizeof (struct filehdr);
if (orig_sym_hdr.cbLine > 0) /* line numbers */
- orig_linenum = (char *) read_seek ((Size_t) orig_sym_hdr.cbLine,
+ orig_linenum = (char *) read_seek (orig_sym_hdr.cbLine,
orig_sym_hdr.cbLineOffset,
"Line numbers");
if (orig_sym_hdr.ipdMax > 0) /* procedure tables */
- orig_procs = (PDR *) read_seek ((Size_t) orig_sym_hdr.ipdMax * sizeof (PDR),
+ orig_procs = (PDR *) read_seek (orig_sym_hdr.ipdMax * sizeof (PDR),
orig_sym_hdr.cbPdOffset,
"Procedure tables");
if (orig_sym_hdr.isymMax > 0) /* local symbols */
- orig_local_syms = (SYMR *) read_seek ((Size_t) orig_sym_hdr.isymMax * sizeof (SYMR),
+ orig_local_syms = (SYMR *) read_seek (orig_sym_hdr.isymMax * sizeof (SYMR),
orig_sym_hdr.cbSymOffset,
"Local symbols");
if (orig_sym_hdr.iauxMax > 0) /* aux symbols */
- orig_aux_syms = (AUXU *) read_seek ((Size_t) orig_sym_hdr.iauxMax * sizeof (AUXU),
+ orig_aux_syms = (AUXU *) read_seek (orig_sym_hdr.iauxMax * sizeof (AUXU),
orig_sym_hdr.cbAuxOffset,
"Aux. symbols");
if (orig_sym_hdr.issMax > 0) /* local strings */
- orig_local_strs = (char *) read_seek ((Size_t) orig_sym_hdr.issMax,
+ orig_local_strs = (char *) read_seek (orig_sym_hdr.issMax,
orig_sym_hdr.cbSsOffset,
"Local strings");
if (orig_sym_hdr.issExtMax > 0) /* external strings */
- orig_ext_strs = (char *) read_seek ((Size_t) orig_sym_hdr.issExtMax,
+ orig_ext_strs = (char *) read_seek (orig_sym_hdr.issExtMax,
orig_sym_hdr.cbSsExtOffset,
"External strings");
if (orig_sym_hdr.ifdMax > 0) /* file tables */
- orig_files = (FDR *) read_seek ((Size_t) orig_sym_hdr.ifdMax * sizeof (FDR),
+ orig_files = (FDR *) read_seek (orig_sym_hdr.ifdMax * sizeof (FDR),
orig_sym_hdr.cbFdOffset,
"File tables");
if (orig_sym_hdr.crfd > 0) /* relative file descriptors */
- orig_rfds = (symint_t *) read_seek ((Size_t) orig_sym_hdr.crfd * sizeof (symint_t),
+ orig_rfds = (symint_t *) read_seek (orig_sym_hdr.crfd * sizeof (symint_t),
orig_sym_hdr.cbRfdOffset,
"Relative file descriptors");
if (orig_sym_hdr.issExtMax > 0) /* external symbols */
- orig_ext_syms = (EXTR *) read_seek ((Size_t) orig_sym_hdr.iextMax * sizeof (EXTR),
+ orig_ext_syms = (EXTR *) read_seek (orig_sym_hdr.iextMax * sizeof (EXTR),
orig_sym_hdr.cbExtOffset,
"External symbols");
if (orig_sym_hdr.idnMax > 0) /* dense numbers */
{
- orig_dense = (DNR *) read_seek ((Size_t) orig_sym_hdr.idnMax * sizeof (DNR),
+ orig_dense = (DNR *) read_seek (orig_sym_hdr.idnMax * sizeof (DNR),
orig_sym_hdr.cbDnOffset,
"Dense numbers");
- add_bytes (&dense_num, (char *) orig_dense, (Size_t) orig_sym_hdr.idnMax);
+ add_bytes (&dense_num, (char *) orig_dense, orig_sym_hdr.idnMax);
}
if (orig_sym_hdr.ioptMax > 0) /* opt symbols */
- orig_opt_syms = (OPTR *) read_seek ((Size_t) orig_sym_hdr.ioptMax * sizeof (OPTR),
+ orig_opt_syms = (OPTR *) read_seek (orig_sym_hdr.ioptMax * sizeof (OPTR),
orig_sym_hdr.cbOptOffset,
"Optimizer symbols");
/* Abort if the symbol table is not last. */
- if (max_file_offset != stat_buf.st_size)
+ if (max_file_offset != (unsigned long) stat_buf.st_size)
fatal ("symbol table is not last (symbol table ends at %ld, .o ends at %ld",
max_file_offset,
(long) stat_buf.st_size);
@@ -4593,7 +4464,7 @@ copy_object ()
(in case there are duplicate filenames, we collapse them into one
file section, the MIPS assembler may or may not collapse them). */
- remap_file_number = (int *) alloca (sizeof (int) * orig_sym_hdr.ifdMax);
+ remap_file_number = alloca (sizeof (int) * orig_sym_hdr.ifdMax);
for (fd = delete_ifd; fd < orig_sym_hdr.ifdMax; fd++)
{
@@ -4623,7 +4494,7 @@ copy_object ()
for (es = 0; es < orig_sym_hdr.iextMax; es++)
{
EXTR *eptr = orig_ext_syms + es;
- unsigned ifd = eptr->ifd;
+ int ifd = eptr->ifd;
(void) add_ext_symbol (eptr, ((long) ifd < orig_sym_hdr.ifdMax)
? remap_file_number[ ifd ] : ifd );
@@ -4781,7 +4652,7 @@ copy_object ()
num_write
= (remaining <= (int) sizeof (buffer))
? remaining : (int) sizeof (buffer);
- sys_read = fread ((PTR) buffer, 1, num_write, obj_in_stream);
+ sys_read = fread (buffer, 1, num_write, obj_in_stream);
if (sys_read <= 0)
pfatal_with_name (obj_in_name);
@@ -4806,12 +4677,10 @@ copy_object ()
/* Ye olde main program. */
-extern int main PARAMS ((int, char **));
+extern int main (int, char **);
int
-main (argc, argv)
- int argc;
- char **argv;
+main (int argc, char **argv)
{
int iflag = 0;
char *p = strrchr (argv[0], '/');
@@ -4854,7 +4723,7 @@ main (argc, argv)
void_type_info = type_info_init;
void_type_info.basic_type = bt_Void;
- while ((option = getopt (argc, argv, "d:i:I:o:v")) != EOF)
+ while ((option = getopt_long (argc, argv, "d:i:I:o:v", options, NULL)) != -1)
switch (option)
{
default:
@@ -4874,7 +4743,7 @@ main (argc, argv)
else
rename_output = 1;
- /* fall through to 'i' case. */
+ /* Fall through to 'i' case. */
case 'i':
if (obj_in_name == (char *) 0)
@@ -4894,10 +4763,24 @@ main (argc, argv)
break;
case 'v':
+ verbose++;
+ break;
+
+ case 'V':
version++;
break;
}
+ if (version)
+ {
+ printf (_("mips-tfile (GCC) %s\n"), version_string);
+ fputs ("Copyright (C) 2004 Free Software Foundation, Inc.\n", stdout);
+ fputs (_("This is free software; see the source for copying conditions. There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
+ stdout);
+ exit (0);
+ }
+
if (obj_in_name == (char *) 0 && optind <= argc - 2)
obj_in_name = argv[--argc];
@@ -4913,7 +4796,19 @@ main (argc, argv)
delete_input = 1;
}
- if (object_name == (char *) 0 || had_errors || optind != argc - 1)
+ if (optind != argc - 1)
+ had_errors++;
+
+ if (verbose || had_errors)
+ {
+ fprintf (stderr, _("mips-tfile (GCC) %s"), version_string);
+#ifdef TARGET_VERSION
+ TARGET_VERSION;
+#endif
+ fputc ('\n', stderr);
+ }
+
+ if (object_name == (char *) 0 || had_errors)
{
fprintf (stderr, _("Calling Sequence:\n"));
fprintf (stderr, _("\tmips-tfile [-d <num>] [-v] [-i <o-in-file>] -o <o-out-file> <s-file> (or)\n"));
@@ -4928,16 +4823,6 @@ main (argc, argv)
return 1;
}
-
- if (version)
- {
- fprintf (stderr, _("mips-tfile version %s"), version_string);
-#ifdef TARGET_VERSION
- TARGET_VERSION;
-#endif
- fputc ('\n', stderr);
- }
-
if (obj_in_name == (char *) 0)
obj_in_name = object_name;
@@ -5028,8 +4913,7 @@ main (argc, argv)
/* Catch a signal and exit without dumping core. */
STATIC void
-catch_signal (signum)
- int signum;
+catch_signal (int signum)
{
(void) signal (signum, SIG_DFL); /* just in case... */
fatal ("%s", strsignal (signum));
@@ -5039,8 +4923,7 @@ catch_signal (signum)
Also include a system error message based on `errno'. */
void
-pfatal_with_name (msg)
- const char *msg;
+pfatal_with_name (const char *msg)
{
int save_errno = errno; /* just in case.... */
if (line_number > 0)
@@ -5063,11 +4946,10 @@ pfatal_with_name (msg)
ORIG_xxx macros, but the function never returns. */
static int
-out_of_bounds (indx, max, str, prog_line)
- symint_t indx; /* index that is out of bounds */
- symint_t max; /* maximum index */
- const char *str; /* string to print out */
- int prog_line; /* line number within mips-tfile.c */
+out_of_bounds (symint_t indx, /* index that is out of bounds */
+ symint_t max, /* maximum index */
+ const char *str, /* string to print out */
+ int prog_line) /* line number within mips-tfile.c */
{
if (indx < max) /* just in case */
return 0;
@@ -5088,10 +4970,9 @@ out_of_bounds (indx, max, str, prog_line)
#ifdef USE_MALLOC
STATIC page_t *
-allocate_cluster (npages)
- Size_t npages;
+allocate_cluster (Size_t npages)
{
- page_t *value = (page_t *) xcalloc (npages, PAGE_USIZE);
+ page_t *value = xcalloc (npages, PAGE_USIZE);
if (debug > 3)
fprintf (stderr, "\talloc\tnpages = %d, value = 0x%.8x\n", npages, value);
@@ -5102,8 +4983,7 @@ allocate_cluster (npages)
#else /* USE_MALLOC */
STATIC page_t *
-allocate_cluster (npages)
- Size_t npages;
+allocate_cluster (Size_t npages)
{
page_t *ptr = (page_t *) sbrk (0); /* current sbreak */
unsigned long offset = ((unsigned long) ptr) & (PAGE_SIZE - 1);
@@ -5120,12 +5000,8 @@ allocate_cluster (npages)
pfatal_with_name ("allocate_cluster");
if (debug > 3)
- {
- fprintf (stderr, "\talloc\tnpages = %lu, value = ",
- (unsigned long) npages);
- fprintf (stderr, HOST_PTR_PRINTF, (PTR) ptr);
- fputs ("\n", stderr);
- }
+ fprintf (stderr, "\talloc\tnpages = %lu, value = " HOST_PTR_PRINTF "\n",
+ (unsigned long) npages, (void *) ptr);
return ptr;
}
@@ -5142,8 +5018,7 @@ static unsigned pages_left = 0;
/* Allocate some pages (which is initialized to 0). */
STATIC page_t *
-allocate_multiple_pages (npages)
- Size_t npages;
+allocate_multiple_pages (Size_t npages)
{
#ifndef MALLOC_CHECK
if (pages_left == 0 && npages < MAX_CLUSTER_PAGES)
@@ -5163,7 +5038,7 @@ allocate_multiple_pages (npages)
return allocate_cluster (npages);
#else /* MALLOC_CHECK */
- return (page_t *) xcalloc (npages, PAGE_SIZE);
+ return xcalloc (npages, PAGE_SIZE);
#endif /* MALLOC_CHECK */
}
@@ -5172,9 +5047,7 @@ allocate_multiple_pages (npages)
/* Release some pages. */
STATIC void
-free_multiple_pages (page_ptr, npages)
- page_t *page_ptr;
- Size_t npages;
+free_multiple_pages (page_t *page_ptr, Size_t npages)
{
#ifndef MALLOC_CHECK
if (pages_left == 0)
@@ -5194,7 +5067,7 @@ free_multiple_pages (page_ptr, npages)
the free pages is done right after an allocate. */
#else /* MALLOC_CHECK */
- free ((char *) page_ptr);
+ free (page_ptr);
#endif /* MALLOC_CHECK */
}
@@ -5203,7 +5076,7 @@ free_multiple_pages (page_ptr, npages)
/* Allocate one page (which is initialized to 0). */
STATIC page_t *
-allocate_page ()
+allocate_page (void)
{
#ifndef MALLOC_CHECK
if (pages_left == 0)
@@ -5216,7 +5089,7 @@ allocate_page ()
return cluster_ptr++;
#else /* MALLOC_CHECK */
- return (page_t *) xcalloc (1, PAGE_SIZE);
+ return xcalloc (1, PAGE_SIZE);
#endif /* MALLOC_CHECK */
}
@@ -5225,7 +5098,7 @@ allocate_page ()
/* Allocate scoping information. */
STATIC scope_t *
-allocate_scope ()
+allocate_scope (void)
{
scope_t *ptr;
static scope_t initial_scope;
@@ -5252,7 +5125,7 @@ allocate_scope ()
}
#else
- ptr = (scope_t *) xmalloc (sizeof (scope_t));
+ ptr = xmalloc (sizeof (scope_t));
#endif
@@ -5264,8 +5137,7 @@ allocate_scope ()
/* Free scoping information. */
STATIC void
-free_scope (ptr)
- scope_t *ptr;
+free_scope (scope_t *ptr)
{
alloc_counts[ (int) alloc_type_scope ].total_free++;
@@ -5274,7 +5146,7 @@ free_scope (ptr)
alloc_counts[ (int) alloc_type_scope ].free_list.f_scope = ptr;
#else
- free ((PTR) ptr);
+ free (ptr);
#endif
}
@@ -5283,7 +5155,7 @@ free_scope (ptr)
/* Allocate links for pages in a virtual array. */
STATIC vlinks_t *
-allocate_vlinks ()
+allocate_vlinks (void)
{
vlinks_t *ptr;
static vlinks_t initial_vlinks;
@@ -5303,7 +5175,7 @@ allocate_vlinks ()
alloc_counts[ (int) alloc_type_vlinks ].unallocated = unallocated;
#else
- ptr = (vlinks_t *) xmalloc (sizeof (vlinks_t));
+ ptr = xmalloc (sizeof (vlinks_t));
#endif
@@ -5316,7 +5188,7 @@ allocate_vlinks ()
/* Allocate string hash buckets. */
STATIC shash_t *
-allocate_shash ()
+allocate_shash (void)
{
shash_t *ptr;
static shash_t initial_shash;
@@ -5336,7 +5208,7 @@ allocate_shash ()
alloc_counts[ (int) alloc_type_shash ].unallocated = unallocated;
#else
- ptr = (shash_t *) xmalloc (sizeof (shash_t));
+ ptr = xmalloc (sizeof (shash_t));
#endif
@@ -5349,7 +5221,7 @@ allocate_shash ()
/* Allocate type hash buckets. */
STATIC thash_t *
-allocate_thash ()
+allocate_thash (void)
{
thash_t *ptr;
static thash_t initial_thash;
@@ -5369,7 +5241,7 @@ allocate_thash ()
alloc_counts[ (int) alloc_type_thash ].unallocated = unallocated;
#else
- ptr = (thash_t *) xmalloc (sizeof (thash_t));
+ ptr = xmalloc (sizeof (thash_t));
#endif
@@ -5382,7 +5254,7 @@ allocate_thash ()
/* Allocate structure, union, or enum tag information. */
STATIC tag_t *
-allocate_tag ()
+allocate_tag (void)
{
tag_t *ptr;
static tag_t initial_tag;
@@ -5409,7 +5281,7 @@ allocate_tag ()
}
#else
- ptr = (tag_t *) xmalloc (sizeof (tag_t));
+ ptr = xmalloc (sizeof (tag_t));
#endif
@@ -5421,8 +5293,7 @@ allocate_tag ()
/* Free scoping information. */
STATIC void
-free_tag (ptr)
- tag_t *ptr;
+free_tag (tag_t *ptr)
{
alloc_counts[ (int) alloc_type_tag ].total_free++;
@@ -5431,7 +5302,7 @@ free_tag (ptr)
alloc_counts[ (int) alloc_type_tag ].free_list.f_tag = ptr;
#else
- free ((PTR) ptr);
+ free (ptr);
#endif
}
@@ -5440,7 +5311,7 @@ free_tag (ptr)
/* Allocate forward reference to a yet unknown tag. */
STATIC forward_t *
-allocate_forward ()
+allocate_forward (void)
{
forward_t *ptr;
static forward_t initial_forward;
@@ -5467,7 +5338,7 @@ allocate_forward ()
}
#else
- ptr = (forward_t *) xmalloc (sizeof (forward_t));
+ ptr = xmalloc (sizeof (forward_t));
#endif
@@ -5479,8 +5350,7 @@ allocate_forward ()
/* Free scoping information. */
STATIC void
-free_forward (ptr)
- forward_t *ptr;
+free_forward (forward_t *ptr)
{
alloc_counts[ (int) alloc_type_forward ].total_free++;
@@ -5489,7 +5359,7 @@ free_forward (ptr)
alloc_counts[ (int) alloc_type_forward ].free_list.f_forward = ptr;
#else
- free ((PTR) ptr);
+ free (ptr);
#endif
}
@@ -5498,7 +5368,7 @@ free_forward (ptr)
/* Allocate head of type hash list. */
STATIC thead_t *
-allocate_thead ()
+allocate_thead (void)
{
thead_t *ptr;
static thead_t initial_thead;
@@ -5525,7 +5395,7 @@ allocate_thead ()
}
#else
- ptr = (thead_t *) xmalloc (sizeof (thead_t));
+ ptr = xmalloc (sizeof (thead_t));
#endif
@@ -5537,8 +5407,7 @@ allocate_thead ()
/* Free scoping information. */
STATIC void
-free_thead (ptr)
- thead_t *ptr;
+free_thead (thead_t *ptr)
{
alloc_counts[ (int) alloc_type_thead ].total_free++;
@@ -5547,7 +5416,7 @@ free_thead (ptr)
alloc_counts[ (int) alloc_type_thead ].free_list.f_thead = ptr;
#else
- free ((PTR) ptr);
+ free (ptr);
#endif
}
@@ -5555,14 +5424,14 @@ free_thead (ptr)
#endif /* MIPS_DEBUGGING_INFO */
-/* Output an error message and exit */
+/* Output an error message and exit. */
-/*VARARGS*/
void
-fatal VPARAMS ((const char *format, ...))
+fatal (const char *format, ...)
{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, const char *, format);
+ va_list ap;
+
+ va_start (ap, format);
if (line_number > 0)
fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
@@ -5570,7 +5439,7 @@ fatal VPARAMS ((const char *format, ...))
fprintf (stderr, "%s:", progname);
vfprintf (stderr, format, ap);
- VA_CLOSE (ap);
+ va_end (ap);
fprintf (stderr, "\n");
if (line_number > 0)
fprintf (stderr, "line:\t%s\n", cur_line_start);
@@ -5579,12 +5448,12 @@ fatal VPARAMS ((const char *format, ...))
exit (1);
}
-/*VARARGS*/
void
-error VPARAMS ((const char *format, ...))
+error (const char *format, ...)
{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, char *, format);
+ va_list ap;
+
+ va_start (ap, format);
if (line_number > 0)
fprintf (stderr, "%s, %s:%ld ", progname, input_name, line_number);
@@ -5597,7 +5466,7 @@ error VPARAMS ((const char *format, ...))
fprintf (stderr, "line:\t%s\n", cur_line_start);
had_errors++;
- VA_CLOSE (ap);
+ va_end (ap);
saber_stop ();
}
@@ -5606,7 +5475,7 @@ error VPARAMS ((const char *format, ...))
config.h can #define abort fancy_abort if you like that sort of thing. */
void
-fancy_abort ()
+fancy_abort (void)
{
fatal ("internal abort");
}
@@ -5616,8 +5485,7 @@ fancy_abort ()
it calls this function to report clobberage. */
void
-botch (s)
- const char *s;
+botch (const char *s)
{
fatal ("%s", s);
}
diff --git a/contrib/gcc/mkconfig.sh b/contrib/gcc/mkconfig.sh
index cc87ccb37e8c..70d9a23d92d1 100644
--- a/contrib/gcc/mkconfig.sh
+++ b/contrib/gcc/mkconfig.sh
@@ -1,26 +1,54 @@
#! /bin/sh
-# Generate gcc's config.h, which is not your normal autoconf-generated
-# config.h (that's auto-(host|build).h). $1 is the file to generate.
-# TM_DEFINES, HEADERS, XM_DEFINES, and possibly TARGET_CPU_DEFAULT are
-# expected to be set in the environment.
+# Copyright (C) 2001, 2002 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 2, 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 COPYING. If not, write to
+# the Free Software Foundation, 59 Temple Place - Suite 330,
+# Boston MA 02111-1307, USA.
+
+
+# Generate gcc's various configuration headers:
+# config.h, tconfig.h, bconfig.h, tm.h, and tm_p.h.
+# $1 is the file to generate. DEFINES, HEADERS, and possibly
+# TARGET_CPU_DEFAULT are expected to be set in the environment.
if [ -z "$1" ]; then
- echo "Usage: TM_DEFINES='list' HEADERS='list' XM_DEFINES='list' mkconfig.sh FILE" >&2
+ echo "Usage: DEFINES='list' HEADERS='list' \\" >&2
+ echo " [TARGET_CPU_DEFAULT='default'] mkconfig.sh FILE" >&2
exit 1
fi
output=$1
rm -f ${output}T
+# This converts a file name into header guard macro format.
+hg_sed_expr='y,abcdefghijklmnopqrstuvwxyz./,ABCDEFGHIJKLMNOPQRSTUVWXYZ__,'
+header_guard=GCC_`echo ${output} | sed -e ${hg_sed_expr}`
+
+# Add multiple inclusion protection guard, part one.
+echo "#ifndef ${header_guard}" >> ${output}T
+echo "#define ${header_guard}" >> ${output}T
+
# Define TARGET_CPU_DEFAULT if the system wants one.
# This substitutes for lots of *.h files.
if [ "$TARGET_CPU_DEFAULT" != "" ]; then
echo "#define TARGET_CPU_DEFAULT ($TARGET_CPU_DEFAULT)" >> ${output}T
fi
-# Provide defines for other target machine macros to be used everywhere.
-for def in $TM_DEFINES; do
+# Provide defines for other macros set in config.gcc for this file.
+for def in $DEFINES; do
echo "#ifndef $def" | sed 's/=.*//' >> ${output}T
echo "# define $def" | sed 's/=/ /' >> ${output}T
echo "#endif" >> ${output}T
@@ -29,66 +57,35 @@ done
# The first entry in HEADERS may be auto-host.h or auto-build.h;
# it wants to be included even when not -DIN_GCC.
if [ -n "$HEADERS" ]; then
- set $HEADERS; first=$1
- case $first in auto-* )
- echo "#include \"$first\"" >> ${output}T
+ set $HEADERS
+ case "$1" in auto-* )
+ echo "#include \"$1\"" >> ${output}T
shift
- HEADERS=$*
;;
esac
+ if [ $# -ge 1 ]; then
+ echo '#ifdef IN_GCC' >> ${output}T
+ for file in "$@"; do
+ echo "# include \"$file\"" >> ${output}T
+ done
+ echo '#endif' >> ${output}T
+ fi
fi
-# Provide three core typedefs used by everything, if we are compiling
-# GCC. These used to be found in rtl.h and tree.h, but this is no
-# longer practical. Providing these in config.h/tconfig.h/hconfig.h
-# rather than system.h allows the typedefs to be used anywhere in GCC.
-case $output in
- *config.h | *hconfig.h | *tconfig.h)
- cat >> ${output}T <<EOF
-#ifdef IN_GCC
-/* Provide three core typedefs used by everything, if we are compiling
- GCC. These used to be found in rtl.h and tree.h, but this is no
- longer practical. Providing these here rather that system.h allows
- the typedefs to be used everywhere within GCC. */
-struct rtx_def;
-typedef struct rtx_def *rtx;
-struct rtvec_def;
-typedef struct rtvec_def *rtvec;
-union tree_node;
-typedef union tree_node *tree;
-#endif
-#define GTY(x)
-EOF
- ;;
-esac
-
-if [ -n "$HEADERS" ]; then
- echo '#ifdef IN_GCC' >> ${output}T
- for file in $HEADERS; do
- echo "# include \"$file\"" >> ${output}T
- done
- echo '#endif' >> ${output}T
-fi
-
-for def in $XM_DEFINES; do
- echo "#ifndef $def" | sed 's/=.*//' >> ${output}T
- echo "# define $def" | sed 's/=/ /' >> ${output}T
- echo "#endif" >> ${output}T
-done
+# If this is tconfig.h, now define USED_FOR_TARGET. If this is tm.h,
+# now include insn-constants.h and insn-flags.h only if IN_GCC is
+# defined but neither GENERATOR_FILE nor USED_FOR_TARGET is defined.
+# (Much of this is temporary.)
-# If this is tm_p.h, include tm-preds.h unconditionally.
-# If this is tconfig.h or hconfig.h, include no more files.
-# Otherwise, include insn-constants.h and insn-flags.h,
-# but only if GENERATOR_FILE is not defined.
case $output in
- *tm_p.h)
- echo "#include \"tm-preds.h\"" >> ${output}T
- ;;
- *tconfig.h | *hconfig.h)
+ tconfig.h )
+ cat >> ${output}T <<EOF
+#define USED_FOR_TARGET
+EOF
;;
- *)
+ tm.h )
cat >> ${output}T <<EOF
-#ifndef GENERATOR_FILE
+#if defined IN_GCC && !defined GENERATOR_FILE && !defined USED_FOR_TARGET
# include "insn-constants.h"
# include "insn-flags.h"
#endif
@@ -96,6 +93,9 @@ EOF
;;
esac
+# Add multiple inclusion protection guard, part two.
+echo "#endif /* ${header_guard} */" >> ${output}T
+
# Avoid changing the actual file if possible.
if [ -f $output ] && cmp ${output}T $output >/dev/null 2>&1; then
echo $output is unchanged >&2
diff --git a/contrib/gcc/mkdeps.c b/contrib/gcc/mkdeps.c
index 2c3006312718..23af9d83f780 100644
--- a/contrib/gcc/mkdeps.c
+++ b/contrib/gcc/mkdeps.c
@@ -1,5 +1,5 @@
/* Dependency generator for Makefile fragments.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Zack Weinberg, Mar 2000
This program is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@ struct deps
unsigned int deps_size;
};
-static const char *munge PARAMS ((const char *));
+static const char *munge (const char *);
/* Given a filename, quote characters in that filename which are
significant to Make. Note that it's not possible to quote all such
@@ -45,10 +45,9 @@ static const char *munge PARAMS ((const char *));
not properly handled. It isn't possible to get this right in any
current version of Make. (??? Still true? Old comment referred to
3.76.1.) */
-
+
static const char *
-munge (filename)
- const char *filename;
+munge (const char *filename)
{
int len;
const char *p, *q;
@@ -109,9 +108,9 @@ munge (filename)
/* Public routines. */
struct deps *
-deps_init ()
+deps_init (void)
{
- struct deps *d = (struct deps *) xmalloc (sizeof (struct deps));
+ struct deps *d = xmalloc (sizeof (struct deps));
/* Allocate space for the vectors only if we need it. */
@@ -127,22 +126,21 @@ deps_init ()
}
void
-deps_free (d)
- struct deps *d;
+deps_free (struct deps *d)
{
unsigned int i;
if (d->targetv)
{
for (i = 0; i < d->ntargets; i++)
- free ((PTR) d->targetv[i]);
+ free ((void *) d->targetv[i]);
free (d->targetv);
}
if (d->depv)
{
for (i = 0; i < d->ndeps; i++)
- free ((PTR) d->depv[i]);
+ free ((void *) d->depv[i]);
free (d->depv);
}
@@ -152,15 +150,12 @@ deps_free (d)
/* Adds a target T. We make a copy, so it need not be a permanent
string. QUOTE is true if the string should be quoted. */
void
-deps_add_target (d, t, quote)
- struct deps *d;
- const char *t;
- int quote;
+deps_add_target (struct deps *d, const char *t, int quote)
{
if (d->ntargets == d->targets_size)
{
d->targets_size = d->targets_size * 2 + 4;
- d->targetv = (const char **) xrealloc (d->targetv,
+ d->targetv = xrealloc (d->targetv,
d->targets_size * sizeof (const char *));
}
@@ -176,9 +171,7 @@ deps_add_target (d, t, quote)
string as the default target in interpreted as stdin. The string
is quoted for MAKE. */
void
-deps_add_default_target (d, tgt)
- struct deps *d;
- const char *tgt;
+deps_add_default_target (struct deps *d, const char *tgt)
{
/* Only if we have no targets. */
if (d->ntargets)
@@ -192,41 +185,35 @@ deps_add_default_target (d, tgt)
# define TARGET_OBJECT_SUFFIX ".o"
#endif
const char *start = lbasename (tgt);
- char *o = (char *) alloca (strlen (start) + strlen (TARGET_OBJECT_SUFFIX) + 1);
+ char *o = alloca (strlen (start) + strlen (TARGET_OBJECT_SUFFIX) + 1);
char *suffix;
strcpy (o, start);
-
+
suffix = strrchr (o, '.');
if (!suffix)
suffix = o + strlen (o);
strcpy (suffix, TARGET_OBJECT_SUFFIX);
-
+
deps_add_target (d, o, 1);
}
}
void
-deps_add_dep (d, t)
- struct deps *d;
- const char *t;
+deps_add_dep (struct deps *d, const char *t)
{
t = munge (t); /* Also makes permanent copy. */
if (d->ndeps == d->deps_size)
{
d->deps_size = d->deps_size * 2 + 8;
- d->depv = (const char **)
- xrealloc (d->depv, d->deps_size * sizeof (const char *));
+ d->depv = xrealloc (d->depv, d->deps_size * sizeof (const char *));
}
d->depv[d->ndeps++] = t;
}
void
-deps_write (d, fp, colmax)
- const struct deps *d;
- FILE *fp;
- unsigned int colmax;
+deps_write (const struct deps *d, FILE *fp, unsigned int colmax)
{
unsigned int size, i, column;
@@ -273,11 +260,9 @@ deps_write (d, fp, colmax)
}
putc ('\n', fp);
}
-
+
void
-deps_phony_targets (d, fp)
- const struct deps *d;
- FILE *fp;
+deps_phony_targets (const struct deps *d, FILE *fp)
{
unsigned int i;
@@ -289,3 +274,72 @@ deps_phony_targets (d, fp)
putc ('\n', fp);
}
}
+
+/* Write out a deps buffer to a file, in a form that can be read back
+ with deps_restore. Returns nonzero on error, in which case the
+ error number will be in errno. */
+
+int
+deps_save (struct deps *deps, FILE *f)
+{
+ unsigned int i;
+
+ /* The cppreader structure contains makefile dependences. Write out this
+ structure. */
+
+ /* The number of dependences. */
+ if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1)
+ return -1;
+ /* The length of each dependence followed by the string. */
+ for (i = 0; i < deps->ndeps; i++)
+ {
+ size_t num_to_write = strlen (deps->depv[i]);
+ if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1)
+ return -1;
+ if (fwrite (deps->depv[i], num_to_write, 1, f) != 1)
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Read back dependency information written with deps_save into
+ the deps buffer. The third argument may be NULL, in which case
+ the dependency information is just skipped, or it may be a filename,
+ in which case that filename is skipped. */
+
+int
+deps_restore (struct deps *deps, FILE *fd, const char *self)
+{
+ unsigned int i, count;
+ size_t num_to_read;
+ size_t buf_size = 512;
+ char *buf = xmalloc (buf_size);
+
+ /* Number of dependences. */
+ if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
+ return -1;
+
+ /* The length of each dependence string, followed by the string. */
+ for (i = 0; i < count; i++)
+ {
+ /* Read in # bytes in string. */
+ if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t))
+ return -1;
+ if (buf_size < num_to_read + 1)
+ {
+ buf_size = num_to_read + 1 + 127;
+ buf = xrealloc (buf, buf_size);
+ }
+ if (fread (buf, 1, num_to_read, fd) != num_to_read)
+ return -1;
+ buf[num_to_read] = '\0';
+
+ /* Generate makefile dependencies from .pch if -nopch-deps. */
+ if (self != NULL && strcmp (buf, self) != 0)
+ deps_add_dep (deps, buf);
+ }
+
+ free (buf);
+ return 0;
+}
diff --git a/contrib/gcc/mkdeps.h b/contrib/gcc/mkdeps.h
index fa79b86591b5..745ba1f50418 100644
--- a/contrib/gcc/mkdeps.h
+++ b/contrib/gcc/mkdeps.h
@@ -1,5 +1,5 @@
/* Dependency generator for Makefile fragments.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
Contributed by Zack Weinberg, Mar 2000
This program is free software; you can redistribute it and/or modify it
@@ -29,34 +29,44 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
struct deps;
/* Create a deps buffer. */
-extern struct deps *deps_init PARAMS ((void));
+extern struct deps *deps_init (void);
/* Destroy a deps buffer. */
-extern void deps_free PARAMS ((struct deps *));
+extern void deps_free (struct deps *);
/* Add a target (appears on left side of the colon) to the deps list. Takes
a boolean indicating whether to quote the target for MAKE. */
-extern void deps_add_target PARAMS ((struct deps *, const char *, int));
+extern void deps_add_target (struct deps *, const char *, int);
/* Sets the default target if none has been given already. An empty
- string as the default target in interpreted as stdin. */
-extern void deps_add_default_target PARAMS ((struct deps *, const char *));
+ string as the default target is interpreted as stdin. */
+extern void deps_add_default_target (struct deps *, const char *);
/* Add a dependency (appears on the right side of the colon) to the
deps list. Dependencies will be printed in the order that they
were entered with this function. By convention, the first
dependency entered should be the primary source file. */
-extern void deps_add_dep PARAMS ((struct deps *, const char *));
+extern void deps_add_dep (struct deps *, const char *);
/* Write out a deps buffer to a specified file. The third argument
is the number of columns to word-wrap at (0 means don't wrap). */
-extern void deps_write PARAMS ((const struct deps *, FILE *,
- unsigned int));
+extern void deps_write (const struct deps *, FILE *, unsigned int);
+
+/* Write out a deps buffer to a file, in a form that can be read back
+ with deps_restore. Returns nonzero on error, in which case the
+ error number will be in errno. */
+extern int deps_save (struct deps *, FILE *);
+
+/* Read back dependency information written with deps_save into
+ the deps buffer. The third argument may be NULL, in which case
+ the dependency information is just skipped, or it may be a filename,
+ in which case that filename is skipped. */
+extern int deps_restore (struct deps *, FILE *, const char *);
/* For each dependency *except the first*, emit a dummy rule for that
file, causing it to depend on nothing. This is used to work around
the intermediate-file deletion misfeature in Make, in some
automatic dependency schemes. */
-extern void deps_phony_targets PARAMS ((const struct deps *, FILE *));
+extern void deps_phony_targets (const struct deps *, FILE *);
#endif /* ! GCC_MKDEPS_H */
diff --git a/contrib/gcc/mkheaders.in b/contrib/gcc/mkheaders.in
index a97c49edf594..23cb9317dd9e 100644
--- a/contrib/gcc/mkheaders.in
+++ b/contrib/gcc/mkheaders.in
@@ -21,7 +21,7 @@
# Basic information
target=@target@
-target_alias=@target_alias@
+target_noncanonical=@target_noncanonical@
version=@gcc_version@
VERBOSE=0
@@ -64,18 +64,22 @@ local_prefix=@local_prefix@
exec_prefix=@exec_prefix@
# Directory in which to put the directories used by the compiler.
libdir=@libdir@
-# Directory in which the compiler finds executables, libraries, etc.
-libsubdir=${libdir}/gcc-lib/${target_alias}/${version}
+libexecdir=@libexecdir@
+# Directory in which the compiler finds libraries, etc.
+libsubdir=${libdir}/gcc-lib/${target_noncanonical}/${version}
+# Directory in which the compiler finds executables
+libexecsubdir=${libexecdir}/gcc/${target_noncanonical}/${version}
# Since gcc_tooldir does not exist at build-time, use -B${build_tooldir}/bin/
-build_tooldir=${exec_prefix}/${target_alias}
+build_tooldir=${exec_prefix}/${target_noncanonical}
# Directory to search for site-specific includes.
local_includedir=${local_prefix}/include
includedir=${prefix}/include
-itoolsdir=${libsubdir}/install-tools
+itoolsdir=${libexecsubdir}/install-tools
+itoolsdatadir=${libsubdir}/install-tools
incdir=${libsubdir}/include
-. ${itoolsdir}/mkheaders.conf
+. ${itoolsdatadir}/mkheaders.conf
cd ${itoolsdir}
rm -rf ${incdir}/*
@@ -88,11 +92,11 @@ if [ x${STMP_FIXINC} != x ] ; then
if [ -f ${incdir}/limits.h ]; then
mv ${incdir}/limits.h ${incdir}/syslimits.h
else
- cp gsyslimits.h ${incdir}/syslimits.h
+ cp ${itoolsdatadir}/gsyslimits.h ${incdir}/syslimits.h
fi
fi
-cp include/* ${incdir}
+cp ${itoolsdatadir}/include/* ${incdir}
if [ x${STMP_FIXPROTO} != x ] ; then
mkinstalldirs="${SHELL} ${itoolsdir}/mkinstalldirs"
diff --git a/contrib/gcc/mklibgcc.in b/contrib/gcc/mklibgcc.in
index 16e9fde52c38..806fc9eea035 100644
--- a/contrib/gcc/mklibgcc.in
+++ b/contrib/gcc/mklibgcc.in
@@ -9,9 +9,8 @@
#
# objext
# LIB1ASMFUNCS
-# LIB2FUNCS_1
-# LIB2FUNCS_2
# LIB2FUNCS_ST
+# LIBGCOV
# LIB2ADD
# LIB2ADD_ST
# LIB2ADDEH
@@ -44,6 +43,16 @@ echo
echo 'force:'
echo
+# Library members defined in libgcc2.c.
+lib2funcs='_muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3
+ _cmpdi2 _ucmpdi2 _floatdidf _floatdisf _fixunsdfsi _fixunssfsi
+ _fixunsdfdi _fixdfdi _fixunssfdi _fixsfdi _fixxfdi _fixunsxfdi
+ _floatdixf _fixunsxfsi _fixtfdi _fixunstfdi _floatditf _clear_cache
+ _enable_execute_stack _trampoline __main _absvsi2 _absvdi2 _addvsi3
+ _addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 _negvsi2 _negvdi2 _ctors
+ _ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2 _ctzsi2 _ctzdi2 _popcount_tab
+ _popcountsi2 _popcountdi2 _paritysi2 _paritydi2'
+
# Disable SHLIB_LINK if shared libgcc not enabled.
if [ "@enable_shared@" = "no" ]; then
SHLIB_LINK=""
@@ -63,7 +72,10 @@ make_compile='$(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
LANGUAGES="$(LANGUAGES)"'
# Dependencies for libgcc2.c
-libgcc2_c_dep='stmp-dirs $(srcdir)/libgcc2.c $(CONFIG_H) $(MACHMODE_H) longlong.h gbl-ctors.h config.status stmp-int-hdrs tsystem.h'" $LIB2ADDEHDEP"
+libgcc2_c_dep='stmp-dirs $(srcdir)/libgcc2.c $(CONFIG_H) coretypes.h $(TM_H) $(MACHMODE_H) longlong.h gbl-ctors.h config.status stmp-int-hdrs tsystem.h'" $LIB2ADDEHDEP"
+
+# Dependencies for libgcov.c
+libgcov_c_dep='stmp-dirs $(srcdir)/libgcov.c $(CONFIG_H) coretypes.h $(TM_H) $(MACHMODE_H) longlong.h gbl-ctors.h config.status stmp-int-hdrs tsystem.h $(srcdir)/gcov-io.h $(srcdir)/gcov-io.c gcov-iov.h'
# Dependencies for fp-bit.c
fpbit_c_dep='stmp-dirs config.status tsystem.h'
@@ -84,14 +96,11 @@ for name in $LIB1ASMFUNCS; do
echo " $gcc_compile" $flags -DL$name -xassembler-with-cpp \
-c '$(srcdir)/config/$(LIB1ASMSRC)' -o $out
- # Remove any objects from LIB2FUNCS and LIB2_DIVMOD_FUNCS that are
+ # Remove any objects from lib2funcs and LIB2_DIVMOD_FUNCS that are
# defined as optimized assembly code in LIB1ASMFUNCS.
- LIB2FUNCS_1=`echo $LIB2FUNCS_1 | sed -e 's/^'$name' //' \
- -e 's/ '$name' / /' \
- -e 's/ '$name'$//'`
- LIB2FUNCS_2=`echo $LIB2FUNCS_2 | sed -e 's/^'$name' //' \
- -e 's/ '$name' / /' \
- -e 's/ '$name'$//'`
+ lib2funcs=`echo $lib2funcs | sed -e 's/^'$name' //' \
+ -e 's/ '$name' / /' \
+ -e 's/ '$name'$//'`
LIB2_DIVMOD_FUNCS=`echo $LIB2_DIVMOD_FUNCS | sed -e 's/^'$name' //' \
-e 's/ '$name' / /' \
-e 's/ '$name'$//'`
@@ -107,7 +116,7 @@ libgcc2_objs=""
libgcc2_st_objs=""
libgcc2_eh_objs=""
-for name in $LIB2FUNCS_1 $LIB2FUNCS_2; do
+for name in $lib2funcs; do
for ml in $MULTILIBS; do
dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
@@ -249,6 +258,25 @@ for file in $LIB2ADD_ST; do
libgcc2_st_objs="$libgcc2_st_objs ${oname}${objext}"
done
+#
+# build libgcov components
+#
+
+libgcov_objs=""
+
+for name in $LIBGCOV; do
+ for ml in $MULTILIBS; do
+ dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
+ flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
+ out="libgcc/${dir}/${name}${objext}"
+
+ echo $out: $libgcov_c_dep
+ echo " $gcc_compile" '$(MAYBE_USE_COLLECT2)' $flags -DL$name \
+ -c '$(srcdir)/libgcov.c' -o $out
+ done
+ libgcov_objs="$libgcov_objs ${name}${objext}"
+done
+
# SHLIB_MKMAP
# SHLIB_MKMAP_OPTS
# SHLIB_MAPFILES
@@ -275,16 +303,28 @@ for ml in $MULTILIBS; do
libgcc_st_objs="$libgcc_st_objs libgcc/${dir}/$o"
done
+ libgcov_a_objs=""
+ for o in $libgcov_objs; do
+ libgcov_a_objs="$libgcov_a_objs libgcc/${dir}/$o"
+ done
+
if [ "$SHLIB_LINK" -a "$SHLIB_MKMAP" ]; then
mapfile="libgcc/${dir}/libgcc.map"
tmpmapfile="libgcc/${dir}/tmp-libgcc.map"
- echo ""
- echo "${mapfile}: $SHLIB_MKMAP $SHLIB_MAPFILES $libgcc_sh_objs"
- echo ' { $(NM_FOR_TARGET)'" $SHLIB_NM_FLAGS $libgcc_sh_objs; echo %%; \\"
- echo " cat $SHLIB_MAPFILES | sed -e "'"/^[ ]*#/d" -e '\''s/^%\(if\|else\|elif\|endif\|define\)/#\1/'\'" \\"
- echo " | $gcc_compile $flags -E -xassembler-with-cpp -; \\"
- echo ' } | $(AWK)'" -f $SHLIB_MKMAP $SHLIB_MKMAP_OPTS > ${tmpmapfile}"
- echo ' mv '"$tmpmapfile"' $@'
+ # This uses a here document instead of echos because some shells
+ # will convert the \1 in the second sed command to a control-A.
+ # The behavior of here documents is more predictable.
+ cat <<EOF
+
+${mapfile}: $SHLIB_MKMAP $SHLIB_MAPFILES $libgcc_sh_objs
+ { \$(NM_FOR_TARGET) $SHLIB_NM_FLAGS $libgcc_sh_objs; echo %%; \\
+ cat $SHLIB_MAPFILES \\
+ | sed -e '/^[ ]*#/d' \\
+ -e 's/^%\(if\|else\|elif\|endif\|define\)/#\1/' \\
+ | $gcc_compile $flags -E -xassembler-with-cpp -; \\
+ } | \$(AWK) -f $SHLIB_MKMAP $SHLIB_MKMAP_OPTS > ${tmpmapfile}
+ mv '$tmpmapfile' \$@
+EOF
fi
shlib_deps="$shlib_deps $mapfile"
@@ -299,11 +339,17 @@ for ml in $MULTILIBS; do
if [ "@libgcc_visibility@" = yes -a "$SHLIB_LINK" ]; then
libgcc_a_objs=
echo ""
+ echo "libgcc/${dir}/stacknote.s: stmp-dirs"
+ echo ' @( echo | $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) '${flags}' -S -o - -xc - | grep .note.GNU-stack || : ) > $@.tmp'
+ echo ' @mv -f $@.tmp $@'
+ echo ""
for o in $libgcc_objs $libgcc_st_objs; do
# .oS objects will have all non-local symbol definitions .hidden
oS=`echo ${o} | sed s~${objext}'$~.oS~g'`
- echo "${oS}: stmp-dirs ${o}"
- echo ' @$(NM_FOR_TARGET) '${SHLIB_NM_FLAGS} ${o}' | $(AWK) '\''NF == 3 { print "\t.hidden", $$3 }'\'' | $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) '${flags}' -r -nostdinc -nostdlib -o $@ '${o}' -xassembler -'
+ echo "${oS}: stmp-dirs libgcc/${dir}/stacknote.s ${o}"
+ # non-GNU nm emits three fields even for undefined and typeless symbols,
+ # so explicitly omit them
+ echo ' ( $(NM_FOR_TARGET) '${SHLIB_NM_FLAGS} ${o}' | $(AWK) '\''NF == 3 && $$2 !~ /^[UN]$$/ { print "\t.hidden", $$3 }'\''; cat libgcc/${dir}/stacknote.s ) | $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) '${flags}' -r -nostdinc -nostdlib -o $@ '${o}' -xassembler -'
libgcc_a_objs="${libgcc_a_objs} ${oS}"
done
fi
@@ -318,9 +364,13 @@ for ml in $MULTILIBS; do
echo "${dir}/libgcc.a: stmp-dirs $libgcc_a_objs"
echo " -rm -rf ${dir}/libgcc.a"
echo ' $(AR_CREATE_FOR_TARGET)' ${dir}/libgcc.a $libgcc_a_objs
- echo ' if $(RANLIB_TEST_FOR_TARGET) ; then' \\
- echo ' $(RANLIB_FOR_TARGET)' ${dir}/libgcc.a ';' \\
- echo ' else true; fi;'
+ echo ' $(RANLIB_FOR_TARGET)' ${dir}/libgcc.a
+
+ echo ""
+ echo "${dir}/libgcov.a: stmp-dirs $libgcov_a_objs"
+ echo " -rm -rf ${dir}/libgcov.a"
+ echo ' $(AR_CREATE_FOR_TARGET)' ${dir}/libgcov.a $libgcov_a_objs
+ echo ' $(RANLIB_FOR_TARGET)' ${dir}/libgcov.a
if [ "$SHLIB_LINK" ]; then
@@ -328,9 +378,7 @@ for ml in $MULTILIBS; do
echo "${dir}/libgcc_eh.a: stmp-dirs $libgcc_eh_objs"
echo " -rm -rf ${dir}/libgcc_eh.a"
echo ' $(AR_CREATE_FOR_TARGET)' ${dir}/libgcc_eh.a $libgcc_eh_objs
- echo ' if $(RANLIB_TEST_FOR_TARGET) ; then' \\
- echo ' $(RANLIB_FOR_TARGET)' ${dir}/libgcc_eh.a ';' \\
- echo ' else true; fi;'
+ echo ' $(RANLIB_FOR_TARGET)' ${dir}/libgcc_eh.a
if [ -z "$SHLIB_MULTILIB" ]; then
if [ "$dir" = . ]; then
@@ -340,6 +388,7 @@ for ml in $MULTILIBS; do
fi
shlib_so_name="$shlib_base_name"
shlib_dir=
+ shlib_slibdir_qual=
if [ -n "$MULTILIB_OSDIRNAMES" ]; then
if [ "$dir" != . ]; then
gcc_multilib_dir=`./xgcc -B./ $flags --print-multi-directory`
@@ -349,8 +398,12 @@ for ml in $MULTILIBS; do
os_multilib_base=`echo $os_multilib_dir | sed -n "s~/${gcc_multilib_sup}\$~~p"`
if [ -z "$os_multilib_base" ]; then
shlib_so_name=libgcc_s
+ if [ "$os_multilib_dir" != "." ]; then
+ shlib_slibdir_qual="/$os_multilib_dir"
+ fi
else
shlib_so_name=libgcc_s_`echo $gcc_multilib_sup | sed s,/,_,g`
+ shlib_slibdir_qual="/$os_multilib_base"
fi
fi
fi
@@ -363,7 +416,8 @@ for ml in $MULTILIBS; do
-e "s%@shlib_base_name@%$shlib_base_name%g" \
-e "s%@shlib_map_file@%$mapfile%g" \
-e "s%@shlib_so_name@%$shlib_so_name%g" \
- -e "s%@shlib_dir@%$shlib_dir%g"
+ -e "s%@shlib_dir@%$shlib_dir%g" \
+ -e "s%@shlib_slibdir_qual@%%g"
elif [ "$SHLIB_MULTILIB" = "$dir" ]; then
shlib_base_name="libgcc_s";
echo ""
@@ -375,7 +429,8 @@ for ml in $MULTILIBS; do
-e "s%@shlib_base_name@%$shlib_base_name%g" \
-e "s%@shlib_map_file@%$mapfile%g" \
-e "s%@shlib_so_name@%$shlib_base_name%g" \
- -e "s%@shlib_dir@%%g"
+ -e "s%@shlib_dir@%%g" \
+ -e "s%@shlib_slibdir_qual@%%g"
fi
fi
done
@@ -384,16 +439,18 @@ dirs=libgcc
for ml in $MULTILIBS; do
dir=`echo ${ml} | sed -e 's/;.*$//' -e 's/=/$(EQ)/g'`
if [ $dir != . ]; then
- dirs="$dirs libgcc/${dir}"
+ dirs="$dirs ${dir} libgcc/${dir}"
fi
done
echo ''
echo 'libgcc-stage-start:'
echo ' for dir in '"${dirs}"'; do \'
-echo ' if [ -d $(stage)/$$dir ]; then true; else mkdir $(stage)/$$dir; fi; \'
+echo ' if [ -d $(stage)/$$dir ]; then true; else '$mkinstalldirs' $(stage)/$$dir; fi; \'
echo ' done'
echo ' -for dir in '"${dirs}"'; do \'
echo ' mv $$dir/*'"${objext}"' $(stage)/$$dir; \'
+echo ' test ! -f $$dir/stacknote.s || mv $$dir/stacknote.s $(stage)/$$dir; \'
+echo ' test ! -f $$dir/libgcc.a || mv $$dir/lib* $(stage)/$$dir; \'
echo ' done'
echo ""
@@ -405,7 +462,7 @@ for ml in $MULTILIBS; do
if [ $dir != . ]; then
dirs="$dirs ${dir} libgcc/${dir}"
fi
- all="$all ${dir}/libgcc.a"
+ all="$all ${dir}/libgcc.a ${dir}/libgcov.a"
if [ "$SHLIB_LINK" ]; then
all="$all ${dir}/libgcc_eh.a"
if [ -z "$SHLIB_MULTILIB" ]; then
@@ -460,12 +517,14 @@ for ml in $MULTILIBS; do
flags=`echo ${ml} | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`;
if [ $dir != . ]; then
ldir='$(DESTDIR)$(libsubdir)'/$dir
- echo " if [ -d $ldir ]; then true; else mkdir $ldir; chmod a+rx $ldir; fi;"
+ echo " if [ -d $ldir ]; then true; else $mkinstalldirs $ldir; chmod a+rx $ldir; fi;"
else
ldir='$(DESTDIR)$(libsubdir)'
fi
echo ' $(INSTALL_DATA)' ${dir}/libgcc.a ${ldir}/
echo ' $(RANLIB_FOR_TARGET)' ${ldir}/libgcc.a
+ echo ' $(INSTALL_DATA)' ${dir}/libgcov.a ${ldir}/
+ echo ' $(RANLIB_FOR_TARGET)' ${ldir}/libgcov.a
if [ "$SHLIB_LINK" ]; then
echo ' $(INSTALL_DATA)' ${dir}/libgcc_eh.a ${ldir}/
diff --git a/contrib/gcc/mode-classes.def b/contrib/gcc/mode-classes.def
new file mode 100644
index 000000000000..d154493ebcc3
--- /dev/null
+++ b/contrib/gcc/mode-classes.def
@@ -0,0 +1,31 @@
+/* Machine mode class definitions for GCC.
+ Copyright (C) 2003
+ 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#define MODE_CLASSES \
+ DEF_MODE_CLASS (MODE_RANDOM), /* other */ \
+ DEF_MODE_CLASS (MODE_CC), /* condition code in a register */ \
+ DEF_MODE_CLASS (MODE_INT), /* integer */ \
+ DEF_MODE_CLASS (MODE_PARTIAL_INT), /* integer with padding bits */ \
+ DEF_MODE_CLASS (MODE_FLOAT), /* floating point */ \
+ DEF_MODE_CLASS (MODE_COMPLEX_INT), /* complex numbers */ \
+ DEF_MODE_CLASS (MODE_COMPLEX_FLOAT), \
+ DEF_MODE_CLASS (MODE_VECTOR_INT), /* SIMD vectors */ \
+ DEF_MODE_CLASS (MODE_VECTOR_FLOAT)
diff --git a/contrib/gcc/objc/Make-lang.in b/contrib/gcc/objc/Make-lang.in
index 480f96b3f9e3..5d88a44c50e7 100644
--- a/contrib/gcc/objc/Make-lang.in
+++ b/contrib/gcc/objc/Make-lang.in
@@ -1,20 +1,21 @@
# Top level -*- makefile -*- fragment for GNU Objective-C
-# Copyright (C) 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
-#This file is part of GNU CC.
+#This file is part of GCC.
-#GNU CC is free software; you can redistribute it and/or modify
+#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 2, or (at your option)
#any later version.
-#GNU CC is distributed in the hope that it will be useful,
+#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 GNU CC; see the file COPYING. If not, write to
+#along with GCC; see the file COPYING. If not, write to
#the Free Software Foundation, 59 Temple Place - Suite 330,
#Boston, MA 02111-1307, USA.
@@ -22,10 +23,9 @@
# Each language makefile fragment must provide the following targets:
#
# foo.all.build, foo.all.cross, foo.start.encap, foo.rest.encap,
-# foo.info, foo.dvi,
-# foo.install-normal, foo.install-common, foo.install-info, foo.install-man,
+# foo.install-normal, foo.install-common, foo.install-man,
# foo.uninstall,
-# foo.mostlyclean, foo.clean, foo.distclean, foo.extraclean,
+# foo.mostlyclean, foo.clean, foo.distclean,
# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4
#
# where `foo' is the name of the language.
@@ -46,58 +46,46 @@ OBJECTIVE-C objective-c: cc1obj$(exeext)
# Use maximal warnings for this front end.
objc-warn = $(STRICT_WARN)
+# Bison-1.75 output yields (harmless) -Wtraditional warnings
+objc/objc-parse.o-warn = -Wno-error
# Language-specific object files for Objective C.
-OBJC_OBJS = objc-lang.o objc-parse.o objc-act.o $(C_AND_OBJC_OBJS)
+OBJC_OBJS = objc/objc-lang.o objc/objc-parse.o objc/objc-act.o
-cc1obj$(exeext): $(OBJC_OBJS) $(BACKEND) $(LIBDEPS)
- $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(OBJC_OBJS) $(BACKEND) $(LIBS)
+cc1obj$(exeext): $(OBJC_OBJS) $(C_AND_OBJC_OBJS) $(BACKEND) $(LIBDEPS)
+ $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \
+ $(OBJC_OBJS) $(C_AND_OBJC_OBJS) $(BACKEND) $(LIBS)
# Objective C language specific files.
-objc-lang.o : $(srcdir)/objc/objc-lang.c \
- $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(srcdir)/c-tree.h \
- $(srcdir)/c-common.h $(srcdir)/toplev.h $(srcdir)/objc/objc-act.h \
- $(srcdir)/langhooks.h $(srcdir)/langhooks-def.h
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \
- -c $(srcdir)/objc/objc-lang.c $(OUTPUT_OPTION)
-
-objc-parse.o : $(srcdir)/objc/objc-parse.c \
- $(CONFIG_H) $(TREE_H) $(C_COMMON_H) $(srcdir)/toplev.h $(srcdir)/ggc.h \
- $(srcdir)/c-pragma.h $(srcdir)/c-tree.h \
- $(srcdir)/input.h $(srcdir)/flags.h $(srcdir)/output.h \
- $(srcdir)/objc/objc-act.h $(SYSTEM_H)
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \
- -c $(srcdir)/objc/objc-parse.c $(OUTPUT_OPTION)
-
-po-generated: $(srcdir)/objc/objc-parse.c
-$(srcdir)/objc/objc-parse.c : $(srcdir)/objc/objc-parse.y
- cd $(srcdir)/objc; \
- if $(BISON) $(BISONFLAGS) -o op$$$$.c objc-parse.y ; then \
- test -f op$$$$.output && mv -f op$$$$.output objc-parse.output ; \
- mv -f op$$$$.c objc-parse.c ; \
- else \
- rm -f op$$$$.* ; \
- false ; \
- fi
-
-$(srcdir)/objc/objc-parse.y: $(srcdir)/c-parse.in
+objc/objc-lang.o : objc/objc-lang.c \
+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) c-tree.h \
+ c-common.h toplev.h objc/objc-act.h langhooks.h $(LANGHOOKS_DEF_H)
+
+objc/objc-parse.o : objc/objc-parse.c \
+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(C_TREE_H) \
+ toplev.h $(GGC_H) c-pragma.h input.h flags.h output.h objc/objc-act.h
+
+objc/objc-act.o : objc/objc-act.c \
+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) $(TM_P_H) \
+ $(EXPR_H) $(TARGET_H) $(C_TREE_H) diagnostic.h toplev.h flags.h \
+ objc/objc-act.h input.h function.h output.h debug.h langhooks.h \
+ $(LANGHOOKS_DEF_H) gt-objc-objc-act.h gtype-objc.h
+
+objc.srcextra: objc/objc-parse.c objc/objc-parse.y
+ -cp -p $^ $(srcdir)/objc
+
+objc/objc-parse.c : objc/objc-parse.y
+ -$(BISON) $(BISONFLAGS) -o $@ $<
+
+objc/objc-parse.y: c-parse.in
echo '/*WARNING: This file is automatically generated!*/' >tmp-objc-prs.y
- sed -e "/^ifc$$/,/^end ifc$$/d" \
- -e "/^ifobjc$$/d" -e "/^end ifobjc$$/d" \
- $(srcdir)/c-parse.in >>tmp-objc-prs.y
- $(SHELL) $(srcdir)/move-if-change tmp-objc-prs.y $(srcdir)/objc/objc-parse.y
-
-objc-act.o : $(srcdir)/objc/objc-act.c \
- $(CONFIG_H) $(TREE_H) $(RTL_H) $(SYSTEM_H) $(EXPR_H) $(TARGET_H) \
- $(C_COMMON_H) $(srcdir)/c-tree.h $(srcdir)/diagnostic.h \
- $(srcdir)/toplev.h $(srcdir)/flags.h $(srcdir)/objc/objc-act.h \
- $(srcdir)/input.h $(srcdir)/function.h $(srcdir)/output.h $(srcdir)/debug.h \
- $(srcdir)/langhooks.h $(LANGHOOKS_DEF_H) gtype-objc.h
- $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \
- -c $(srcdir)/objc/objc-act.c
+ sed -e "/^@@ifc.*/,/^@@end_ifc.*/d" \
+ -e "/^@@ifobjc.*/d" -e "/^@@end_ifobjc.*/d" < $< >>tmp-objc-prs.y
+ $(SHELL) $(srcdir)/move-if-change tmp-objc-prs.y $@
gtype-objc.h : s-gtype ; @true
+gt-objc-objc-act.h : s-gtype ; @true
#
# Build hooks:
@@ -106,10 +94,16 @@ objc.all.build:
objc.all.cross:
objc.start.encap:
objc.rest.encap:
-
objc.info:
-objc.dvi:
-objc.generated-manpages:
+objc.man:
+objc.srcinfo:
+objc.srcman:
+
+objc.tags: force
+ cd $(srcdir)/objc; etags -o TAGS.sub *.y *.c *.h; \
+ etags --include TAGS.sub --include ../TAGS.sub
+
+lang_checks += check-objc
#
# Install hooks:
@@ -119,8 +113,6 @@ objc.install-normal:
objc.install-common:
-objc.install-info:
-
objc.install-man:
objc.uninstall:
@@ -131,6 +123,7 @@ objc.uninstall:
objc.mostlyclean:
-rm -f tmp-objc-prs.y
-rm -f objc/*$(objext) objc/xforward objc/fflags
+ -rm -f objc/objc-parse.y objc/objc-parse.c objc/objc-parse.output
-rm -f objc/*$(coverageexts)
objc.clean: objc.mostlyclean
-rm -rf objc-headers
@@ -138,23 +131,21 @@ objc.distclean:
-rm -f objc/Makefile objc/Make-host objc/Make-target
-rm -f objc/config.status objc/config.cache
-rm -f objc-parse.output
-objc.extraclean:
objc.maintainer-clean:
- -rm -f $(srcdir)/objc/objc-parse.y
- -rm -f $(srcdir)/objc/objc-parse.c $(srcdir)/objc/objc-parse.output
+ -rm -f $(srcdir)/objc/objc-parse.y $(srcdir)/objc/objc-parse.c
#
# Stage hooks:
objc.stage1: stage1-start
-mv objc/*$(objext) stage1/objc
- -mv cc1obj$(exeext) stage1
objc.stage2: stage2-start
-mv objc/*$(objext) stage2/objc
- -mv cc1obj$(exeext) stage2
objc.stage3: stage3-start
-mv objc/*$(objext) stage3/objc
- -mv cc1obj$(exeext) stage3
objc.stage4: stage4-start
-mv objc/*$(objext) stage4/objc
- -mv cc1obj$(exeext) stage4
+objc.stageprofile: stageprofile-start
+ -mv objc/*$(objext) stageprofile/objc
+objc.stagefeedback: stagefeedback-start
+ -mv objc/*$(objext) stagefeedback/objc
diff --git a/contrib/gcc/objc/config-lang.in b/contrib/gcc/objc/config-lang.in
index d79ac13e978f..91b86d8d573c 100644
--- a/contrib/gcc/objc/config-lang.in
+++ b/contrib/gcc/objc/config-lang.in
@@ -1,20 +1,21 @@
# Top level configure fragment for GNU Objective-C
-# Copyright (C) 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
-#This file is part of GNU CC.
+#This file is part of GCC.
-#GNU CC is free software; you can redistribute it and/or modify
+#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 2, or (at your option)
#any later version.
-#GNU CC is distributed in the hope that it will be useful,
+#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 GNU CC; see the file COPYING. If not, write to
+#along with GCC; see the file COPYING. If not, write to
#the Free Software Foundation, 59 Temple Place - Suite 330,
#Boston, MA 02111-1307, USA.
@@ -29,8 +30,8 @@ language="objc"
compilers="cc1obj\$(exeext)"
-stagestuff=""
+stagestuff="cc1obj\$(exeext)"
target_libs=target-libobjc
-gtfiles="\$(srcdir)/objc/objc-act.h \$(srcdir)/c-parse.in \$(srcdir)/c-tree.h \$(srcdir)/c-decl.c \$(srcdir)/c-objc-common.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c \$(srcdir)/c-parse.in"
+gtfiles="\$(srcdir)/objc/objc-act.h \$(srcdir)/c-parse.in \$(srcdir)/c-tree.h \$(srcdir)/c-decl.c \$(srcdir)/c-objc-common.c \$(srcdir)/c-common.c \$(srcdir)/c-common.h \$(srcdir)/c-pragma.c \$(srcdir)/objc/objc-act.c"
diff --git a/contrib/gcc/objc/lang-specs.h b/contrib/gcc/objc/lang-specs.h
index 540a9ae02eb7..fe34bed83fca 100644
--- a/contrib/gcc/objc/lang-specs.h
+++ b/contrib/gcc/objc/lang-specs.h
@@ -1,20 +1,21 @@
/* Definitions for specs for Objective-C.
- Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2002, 2002, 2003
+ Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -23,19 +24,31 @@ Boston, MA 02111-1307, USA. */
{".m", "@objective-c", 0},
{"@objective-c",
- /* cc1obj has an integrated ISO C preprocessor. We should invoke the
- external preprocessor if -save-temps or -traditional is given. */
"%{E|M|MM:%(trad_capable_cpp)\
-lang-objc %(cpp_options) %(cpp_debug_options)}\
%{!E:%{!M:%{!MM:\
%{traditional|ftraditional|traditional-cpp:\
%eGNU Objective C no longer supports traditional compilation}\
- %{save-temps|no-integrated-cpp:cc1obj -E %(cpp_options) %{save-temps:%b.mi} %{!save-temps:%g.mi} \n\
- cc1obj -fpreprocessed %{save-temps:%b.mi} %{!save-temps:%g.mi} %(cc1_options) %{gen-decls}}\
+ %{save-temps|no-integrated-cpp:cc1obj -E %(cpp_options) -o %{save-temps:%b.mi} %{!save-temps:%g.mi} \n\
+ cc1obj -fpreprocessed %{save-temps:%b.mi} %{!save-temps:%g.mi} %(cc1_options) %{print-objc-runtime-info} %{gen-decls}}\
%{!save-temps:%{!no-integrated-cpp:\
- cc1obj %(cpp_unique_options) %(cc1_options) %{gen-decls}}}\
+ cc1obj %(cpp_unique_options) %(cc1_options) %{print-objc-runtime-info} %{gen-decls}}}\
%{!fsyntax-only:%(invoke_as)}}}}", 0},
{".mi", "@objc-cpp-output", 0},
{"@objc-cpp-output",
- "%{!M:%{!MM:%{!E:cc1obj -fpreprocessed %i %(cc1_options) %{gen-decls}\
+ "%{!M:%{!MM:%{!E:cc1obj -fpreprocessed %i %(cc1_options) %{print-objc-runtime-info} %{gen-decls}\
%{!fsyntax-only:%(invoke_as)}}}}", 0},
+ {"@objective-c-header",
+ "%{E|M|MM:cc1obj -E %{traditional|ftraditional|traditional-cpp:-traditional-cpp}\
+ %(cpp_options) %(cpp_debug_options)}\
+ %{!E:%{!M:%{!MM:\
+ %{traditional|ftraditional|traditional-cpp:\
+%eGNU Objective C no longer supports traditional compilation}\
+ %{save-temps|no-integrated-cpp:cc1obj -E %(cpp_options) -o %{save-temps:%b.mi} %{!save-temps:%g.mi} \n\
+ cc1obj -fpreprocessed %b.mi %(cc1_options) %{print-objc-runtime-info} %{gen-decls}\
+ -o %g.s %{!o*:--output-pch=%i.gch}\
+ %W{o*:--output-pch=%*}%V}\
+ %{!save-temps:%{!no-integrated-cpp:\
+ cc1obj %(cpp_unique_options) %(cc1_options) %{print-objc-runtime-info} %{gen-decls}\
+ -o %g.s %{!o*:--output-pch=%i.gch}\
+ %W{o*:--output-pch=%*}%V}}}}}", 0},
diff --git a/contrib/gcc/objc/objc-act.c b/contrib/gcc/objc/objc-act.c
index 018ba04f9998..b1762cfcce14 100644
--- a/contrib/gcc/objc/objc-act.c
+++ b/contrib/gcc/objc/objc-act.c
@@ -1,22 +1,22 @@
/* Implement classes and message passing for Objective C.
- Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
- Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Steve Naroff.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -41,8 +41,11 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
+#include "tm_p.h"
#include "expr.h"
#include "c-tree.h"
#include "c-common.h"
@@ -54,9 +57,13 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "toplev.h"
#include "ggc.h"
+#include "varray.h"
#include "debug.h"
#include "target.h"
#include "diagnostic.h"
+#include "cgraph.h"
+
+#define OBJC_VOID_AT_END build_tree_list (NULL_TREE, void_type_node)
/* This is the default way of generating a method name. */
/* I am not sure it is really correct.
@@ -85,19 +92,16 @@ Boston, MA 02111-1307, USA. */
#define OBJC_FORWARDING_MIN_OFFSET 0
#endif
-
/* Set up for use of obstacks. */
#include "obstack.h"
/* This obstack is used to accumulate the encoding of a data type. */
static struct obstack util_obstack;
-/* This points to the beginning of obstack contents,
- so we can free the whole contents. */
-char *util_firstobj;
-/* for encode_method_def */
-#include "rtl.h"
+/* This points to the beginning of obstack contents, so we can free
+ the whole contents. */
+char *util_firstobj;
/* The version identifies which language generation and runtime
the module (file) was compiled for, and is recorded in the
@@ -114,69 +118,76 @@ char *util_firstobj;
/* Used by compile_file. */
-static void init_objc PARAMS ((void));
-static void finish_objc PARAMS ((void));
+static void init_objc (void);
+static void finish_objc (void);
/* Code generation. */
-static void synth_module_prologue PARAMS ((void));
-static tree build_constructor PARAMS ((tree, tree));
-static rtx build_module_descriptor PARAMS ((void));
-static tree init_module_descriptor PARAMS ((tree));
-static tree build_objc_method_call PARAMS ((int, tree, tree,
- tree, tree, tree));
-static void generate_strings PARAMS ((void));
-static tree get_proto_encoding PARAMS ((tree));
-static void build_selector_translation_table PARAMS ((void));
-
-static tree objc_add_static_instance PARAMS ((tree, tree));
-
-static tree build_ivar_template PARAMS ((void));
-static tree build_method_template PARAMS ((void));
-static tree build_private_template PARAMS ((tree));
-static void build_class_template PARAMS ((void));
-static void build_selector_template PARAMS ((void));
-static void build_category_template PARAMS ((void));
-static tree build_super_template PARAMS ((void));
-static tree build_category_initializer PARAMS ((tree, tree, tree,
- tree, tree, tree));
-static tree build_protocol_initializer PARAMS ((tree, tree, tree,
- tree, tree));
-
-static void synth_forward_declarations PARAMS ((void));
-static void generate_ivar_lists PARAMS ((void));
-static void generate_dispatch_tables PARAMS ((void));
-static void generate_shared_structures PARAMS ((void));
-static tree generate_protocol_list PARAMS ((tree));
-static void generate_forward_declaration_to_string_table PARAMS ((void));
-static void build_protocol_reference PARAMS ((tree));
-
-static tree build_keyword_selector PARAMS ((tree));
-static tree synth_id_with_class_suffix PARAMS ((const char *, tree));
-
-static void generate_static_references PARAMS ((void));
-static int check_methods_accessible PARAMS ((tree, tree,
- int));
-static void encode_aggregate_within PARAMS ((tree, int, int,
- int, int));
-static const char *objc_demangle PARAMS ((const char *));
-static void objc_expand_function_end PARAMS ((void));
+static void synth_module_prologue (void);
+static tree objc_build_constructor (tree, tree);
+static rtx build_module_descriptor (void);
+static tree init_module_descriptor (tree);
+static tree build_objc_method_call (int, tree, tree, tree, tree);
+static void generate_strings (void);
+static tree get_proto_encoding (tree);
+static void build_selector_translation_table (void);
+
+static tree objc_add_static_instance (tree, tree);
+
+static void build_objc_exception_stuff (void);
+static tree objc_declare_variable (enum rid, tree, tree, tree);
+static tree objc_enter_block (void);
+static tree objc_exit_block (void);
+static void objc_build_try_enter_fragment (void);
+static void objc_build_try_exit_fragment (void);
+static void objc_build_extract_fragment (void);
+static tree objc_build_extract_expr (void);
+
+static tree build_ivar_template (void);
+static tree build_method_template (void);
+static tree build_private_template (tree);
+static void build_class_template (void);
+static void build_selector_template (void);
+static void build_category_template (void);
+static tree lookup_method_in_hash_lists (tree, int);
+static void build_super_template (void);
+static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
+static tree build_protocol_initializer (tree, tree, tree, tree, tree);
+static void synth_forward_declarations (void);
+static int ivar_list_length (tree);
+static tree get_class_ivars (tree, int);
+static void generate_ivar_lists (void);
+static void generate_dispatch_tables (void);
+static void generate_shared_structures (void);
+static tree generate_protocol_list (tree);
+static void generate_forward_declaration_to_string_table (void);
+static void build_protocol_reference (tree);
+
+static tree build_keyword_selector (tree);
+static tree synth_id_with_class_suffix (const char *, tree);
+
+static void generate_static_references (void);
+static int check_methods_accessible (tree, tree, int);
+static void encode_aggregate_within (tree, int, int, int, int);
+static const char *objc_demangle (const char *);
+static void objc_expand_function_end (void);
/* Hash tables to manage the global pool of method prototypes. */
hash *nst_method_hash_list = 0;
hash *cls_method_hash_list = 0;
-static size_t hash_func PARAMS ((tree));
-static void hash_init PARAMS ((void));
-static void hash_enter PARAMS ((hash *, tree));
-static hash hash_lookup PARAMS ((hash *, tree));
-static void hash_add_attr PARAMS ((hash, tree));
-static tree lookup_method PARAMS ((tree, tree));
-static tree lookup_instance_method_static PARAMS ((tree, tree));
-static tree lookup_class_method_static PARAMS ((tree, tree));
-static tree add_class PARAMS ((tree));
-static void add_category PARAMS ((tree, tree));
+static size_t hash_func (tree);
+static void hash_init (void);
+static void hash_enter (hash *, tree);
+static hash hash_lookup (hash *, tree);
+static void hash_add_attr (hash, tree);
+static tree lookup_method (tree, tree);
+static tree lookup_method_static (tree, tree, int);
+static void add_method_to_hash_list (hash *, tree);
+static tree add_class (tree);
+static void add_category (tree, tree);
+static inline tree lookup_category (tree, tree);
enum string_section
{
@@ -185,112 +196,105 @@ enum string_section
meth_var_types /* method and variable type descriptors */
};
-static tree add_objc_string PARAMS ((tree,
- enum string_section));
-static tree get_objc_string_decl PARAMS ((tree,
- enum string_section));
-static tree build_objc_string_decl PARAMS ((enum string_section));
-static tree build_selector_reference_decl PARAMS ((void));
+static tree add_objc_string (tree, enum string_section);
+static tree get_objc_string_decl (tree, enum string_section);
+static tree build_objc_string_decl (enum string_section);
+static tree build_selector_reference_decl (void);
/* Protocol additions. */
-static tree add_protocol PARAMS ((tree));
-static tree lookup_protocol PARAMS ((tree));
-static void check_protocol_recursively PARAMS ((tree, tree));
-static tree lookup_and_install_protocols PARAMS ((tree));
+static tree add_protocol (tree);
+static tree lookup_protocol (tree);
+static void check_protocol_recursively (tree, tree);
+static tree lookup_and_install_protocols (tree);
/* Type encoding. */
-static void encode_type_qualifiers PARAMS ((tree));
-static void encode_pointer PARAMS ((tree, int, int));
-static void encode_array PARAMS ((tree, int, int));
-static void encode_aggregate PARAMS ((tree, int, int));
-static void encode_bitfield PARAMS ((int));
-static void encode_type PARAMS ((tree, int, int));
-static void encode_field_decl PARAMS ((tree, int, int));
-
-static void really_start_method PARAMS ((tree, tree));
-static int comp_method_with_proto PARAMS ((tree, tree));
-static int comp_proto_with_proto PARAMS ((tree, tree));
-static tree get_arg_type_list PARAMS ((tree, int, int));
-static tree expr_last PARAMS ((tree));
+static void encode_type_qualifiers (tree);
+static void encode_pointer (tree, int, int);
+static void encode_array (tree, int, int);
+static void encode_aggregate (tree, int, int);
+static void encode_next_bitfield (int);
+static void encode_gnu_bitfield (int, tree, int);
+static void encode_type (tree, int, int);
+static void encode_field_decl (tree, int, int);
+
+static void really_start_method (tree, tree);
+static int comp_method_with_proto (tree, tree);
+static int objc_types_are_equivalent (tree, tree);
+static int comp_proto_with_proto (tree, tree);
+static tree get_arg_type_list (tree, int, int);
+static tree objc_expr_last (tree);
+static void synth_self_and_ucmd_args (void);
/* Utilities for debugging and error diagnostics. */
-static void warn_with_method PARAMS ((const char *, int, tree));
-static void error_with_ivar PARAMS ((const char *, tree, tree));
-static char *gen_method_decl PARAMS ((tree, char *));
-static char *gen_declaration PARAMS ((tree, char *));
-static void gen_declaration_1 PARAMS ((tree, char *));
-static char *gen_declarator PARAMS ((tree, char *,
- const char *));
-static int is_complex_decl PARAMS ((tree));
-static void adorn_decl PARAMS ((tree, char *));
-static void dump_interface PARAMS ((FILE *, tree));
+static void warn_with_method (const char *, int, tree);
+static void error_with_ivar (const char *, tree, tree);
+static char *gen_method_decl (tree, char *);
+static char *gen_declaration (tree, char *);
+static void gen_declaration_1 (tree, char *);
+static char *gen_declarator (tree, char *, const char *);
+static int is_complex_decl (tree);
+static void adorn_decl (tree, char *);
+static void dump_interface (FILE *, tree);
/* Everything else. */
-static tree define_decl PARAMS ((tree, tree));
-static tree lookup_method_in_protocol_list PARAMS ((tree, tree, int));
-static tree lookup_protocol_in_reflist PARAMS ((tree, tree));
-static tree create_builtin_decl PARAMS ((enum tree_code,
- tree, const char *));
-static void setup_string_decl PARAMS ((void));
-static void build_string_class_template PARAMS ((void));
-static tree my_build_string PARAMS ((int, const char *));
-static void build_objc_symtab_template PARAMS ((void));
-static tree init_def_list PARAMS ((tree));
-static tree init_objc_symtab PARAMS ((tree));
-static void forward_declare_categories PARAMS ((void));
-static void generate_objc_symtab_decl PARAMS ((void));
-static tree build_selector PARAMS ((tree));
-static tree build_typed_selector_reference PARAMS ((tree, tree));
-static tree build_selector_reference PARAMS ((tree));
-static tree build_class_reference_decl PARAMS ((void));
-static void add_class_reference PARAMS ((tree));
-static tree build_protocol_template PARAMS ((void));
-static tree build_descriptor_table_initializer PARAMS ((tree, tree));
-static tree build_method_prototype_list_template PARAMS ((tree, int));
-static tree build_method_prototype_template PARAMS ((void));
-static int forwarding_offset PARAMS ((tree));
-static tree encode_method_prototype PARAMS ((tree, tree));
-static tree generate_descriptor_table PARAMS ((tree, const char *,
- int, tree, tree));
-static void generate_method_descriptors PARAMS ((tree));
-static tree build_tmp_function_decl PARAMS ((void));
-static void hack_method_prototype PARAMS ((tree, tree));
-static void generate_protocol_references PARAMS ((tree));
-static void generate_protocols PARAMS ((void));
-static void check_ivars PARAMS ((tree, tree));
-static tree build_ivar_list_template PARAMS ((tree, int));
-static tree build_method_list_template PARAMS ((tree, int));
-static tree build_ivar_list_initializer PARAMS ((tree, tree));
-static tree generate_ivars_list PARAMS ((tree, const char *,
- int, tree));
-static tree build_dispatch_table_initializer PARAMS ((tree, tree));
-static tree generate_dispatch_table PARAMS ((tree, const char *,
- int, tree));
-static tree build_shared_structure_initializer PARAMS ((tree, tree, tree, tree,
- tree, int, tree, tree,
- tree));
-static void generate_category PARAMS ((tree));
-static int is_objc_type_qualifier PARAMS ((tree));
-static tree adjust_type_for_id_default PARAMS ((tree));
-static tree check_duplicates PARAMS ((hash));
-static tree receiver_is_class_object PARAMS ((tree));
-static int check_methods PARAMS ((tree, tree, int));
-static int conforms_to_protocol PARAMS ((tree, tree));
-static void check_protocol PARAMS ((tree, const char *,
- const char *));
-static void check_protocols PARAMS ((tree, const char *,
- const char *));
-static tree encode_method_def PARAMS ((tree));
-static void gen_declspecs PARAMS ((tree, char *, int));
-static void generate_classref_translation_entry PARAMS ((tree));
-static void handle_class_ref PARAMS ((tree));
-static void generate_struct_by_value_array PARAMS ((void))
+static tree define_decl (tree, tree);
+static tree lookup_method_in_protocol_list (tree, tree, int);
+static tree lookup_protocol_in_reflist (tree, tree);
+static tree create_builtin_decl (enum tree_code, tree, const char *);
+static void setup_string_decl (void);
+static int check_string_class_template (void);
+static tree my_build_string (int, const char *);
+static void build_objc_symtab_template (void);
+static tree init_def_list (tree);
+static tree init_objc_symtab (tree);
+static tree build_metadata_decl (const char *, tree);
+static void forward_declare_categories (void);
+static void generate_objc_symtab_decl (void);
+static tree build_selector (tree);
+static tree build_typed_selector_reference (tree, tree);
+static tree build_selector_reference (tree);
+static tree build_class_reference_decl (void);
+static void add_class_reference (tree);
+static tree build_protocol_template (void);
+static tree build_descriptor_table_initializer (tree, tree);
+static tree build_method_prototype_list_template (tree, int);
+static tree build_method_prototype_template (void);
+static tree objc_method_parm_type (tree);
+static int objc_encoded_type_size (tree);
+static tree encode_method_prototype (tree);
+static tree generate_descriptor_table (tree, const char *, int, tree, tree);
+static void generate_method_descriptors (tree);
+static void generate_protocol_references (tree);
+static void generate_protocols (void);
+static void check_ivars (tree, tree);
+static tree build_ivar_list_template (tree, int);
+static tree build_method_list_template (tree, int);
+static tree build_ivar_list_initializer (tree, tree);
+static tree generate_ivars_list (tree, const char *, int, tree);
+static tree build_dispatch_table_initializer (tree, tree);
+static tree generate_dispatch_table (tree, const char *, int, tree);
+static tree build_shared_structure_initializer (tree, tree, tree, tree,
+ tree, int, tree, tree, tree);
+static void generate_category (tree);
+static int is_objc_type_qualifier (tree);
+static tree adjust_type_for_id_default (tree);
+static tree check_duplicates (hash, int, int);
+static tree receiver_is_class_object (tree, int, int);
+static int check_methods (tree, tree, int);
+static int conforms_to_protocol (tree, tree);
+static void check_protocol (tree, const char *, const char *);
+static void check_protocols (tree, const char *, const char *);
+static void gen_declspecs (tree, char *, int);
+static void generate_classref_translation_entry (tree);
+static void handle_class_ref (tree);
+static void generate_struct_by_value_array (void)
ATTRIBUTE_NORETURN;
-static void encode_complete_bitfield PARAMS ((int, tree, int));
+static void mark_referenced_methods (void);
+static void generate_objc_image_info (void);
/*** Private Interface (data) ***/
@@ -319,7 +323,7 @@ static void encode_complete_bitfield PARAMS ((int, tree, int));
/* Note that the string object global name is only needed for the
NeXT runtime. */
-#define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
+#define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
#define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
@@ -327,19 +331,71 @@ static const char *TAG_GETCLASS;
static const char *TAG_GETMETACLASS;
static const char *TAG_MSGSEND;
static const char *TAG_MSGSENDSUPER;
+/* The NeXT Objective-C messenger may have two extra entry points, for use
+ when returning a structure. */
+static const char *TAG_MSGSEND_STRET;
+static const char *TAG_MSGSENDSUPER_STRET;
static const char *TAG_EXECCLASS;
static const char *default_constant_string_class_name;
+/* Runtime metadata flags. */
+#define CLS_FACTORY 0x0001L
+#define CLS_META 0x0002L
+
+#define OBJC_MODIFIER_STATIC 0x00000001
+#define OBJC_MODIFIER_FINAL 0x00000002
+#define OBJC_MODIFIER_PUBLIC 0x00000004
+#define OBJC_MODIFIER_PRIVATE 0x00000008
+#define OBJC_MODIFIER_PROTECTED 0x00000010
+#define OBJC_MODIFIER_NATIVE 0x00000020
+#define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
+#define OBJC_MODIFIER_ABSTRACT 0x00000080
+#define OBJC_MODIFIER_VOLATILE 0x00000100
+#define OBJC_MODIFIER_TRANSIENT 0x00000200
+#define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
+
+#define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
+#define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
+#define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
+#define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
+#define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
+#define TAG_EXCEPTIONMATCH "objc_exception_match"
+#define TAG_EXCEPTIONTHROW "objc_exception_throw"
+#define TAG_SYNCENTER "objc_sync_enter"
+#define TAG_SYNCEXIT "objc_sync_exit"
+#define TAG_SETJMP "_setjmp"
+#define TAG_RETURN_STRUCT "objc_return_struct"
+
+#define UTAG_EXCDATA "_objc_exception_data"
+#define UTAG_EXCDATA_VAR "_stackExceptionData"
+#define UTAG_CAUGHTEXC_VAR "_caughtException"
+#define UTAG_RETHROWEXC_VAR "_rethrowException"
+#define UTAG_EVALONCE_VAR "_eval_once"
+
+struct val_stack {
+ long val;
+ struct val_stack *next;
+};
+static struct val_stack *catch_count_stack, *exc_binding_stack;
+
+/* useful for debugging */
+static int if_nesting_count;
+static int blk_nesting_count;
+
+static void val_stack_push (struct val_stack **, long);
+static void val_stack_pop (struct val_stack **);
+
/* The OCTI_... enumeration itself is in objc/objc-act.h. */
tree objc_global_trees[OCTI_MAX];
-static void handle_impent PARAMS ((struct imp_entry *));
+static void handle_impent (struct imp_entry *);
struct imp_entry *imp_list = 0;
int imp_count = 0; /* `@implementation' */
int cat_count = 0; /* `@category' */
-static int method_slot = 0; /* Used by start_method_def, */
+/* Use to generate method labels. */
+static int method_slot = 0;
#define BUFSIZE 1024
@@ -369,7 +425,7 @@ static int generating_instance_variables = 0;
the transition point between the two possibilities. */
static void
-generate_struct_by_value_array ()
+generate_struct_by_value_array (void)
{
tree type;
tree field_decl, field_decl_chain;
@@ -400,12 +456,12 @@ generate_struct_by_value_array ()
chainon (field_decl_chain, field_decl);
}
finish_struct (type, field_decl_chain, NULL_TREE);
-
- aggregate_in_mem[i] = aggregate_value_p (type);
+
+ aggregate_in_mem[i] = aggregate_value_p (type, 0);
if (!aggregate_in_mem[i])
found = 1;
}
-
+
/* We found some structures that are returned in registers instead of memory
so output the necessary data. */
if (found)
@@ -414,31 +470,29 @@ generate_struct_by_value_array ()
if (!aggregate_in_mem[i])
break;
printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
-
+
/* The first member of the structure is always 0 because we don't handle
structures with 0 members */
printf ("static int struct_forward_array[] = {\n 0");
-
+
for (j = 1; j <= i; j++)
printf (", %d", aggregate_in_mem[j]);
printf ("\n};\n");
}
-
+
exit (0);
}
-const char *
-objc_init (filename)
- const char *filename;
+bool
+objc_init (void)
{
- filename = c_objc_common_init (filename);
- if (filename == NULL)
- return filename;
+ if (c_objc_common_init () == false)
+ return false;
/* Force the line number back to 0; check_newline will have
raised it to 1, which will make the builtin functions appear
not to be built in. */
- lineno = 0;
+ input_line = 0;
/* If gen_declaration desired, open the output file. */
if (flag_gen_declaration)
@@ -446,7 +500,7 @@ objc_init (filename)
register char * const dumpname = concat (dump_base_name, ".decl", NULL);
gen_declaration_file = fopen (dumpname, "w");
if (gen_declaration_file == 0)
- fatal_io_error ("can't open %s", dumpname);
+ fatal_error ("can't open %s: %m", dumpname);
free (dumpname);
}
@@ -456,6 +510,8 @@ objc_init (filename)
TAG_GETMETACLASS = "objc_getMetaClass";
TAG_MSGSEND = "objc_msgSend";
TAG_MSGSENDSUPER = "objc_msgSendSuper";
+ TAG_MSGSEND_STRET = "objc_msgSend_stret";
+ TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
TAG_EXECCLASS = "__objc_execClass";
default_constant_string_class_name = "NSConstantString";
}
@@ -465,6 +521,8 @@ objc_init (filename)
TAG_GETMETACLASS = "objc_get_meta_class";
TAG_MSGSEND = "objc_msg_lookup";
TAG_MSGSENDSUPER = "objc_msg_lookup_super";
+ /* GNU runtime does not provide special functions to support
+ structure-returning methods. */
TAG_EXECCLASS = "__objc_exec_class";
default_constant_string_class_name = "NXConstantString";
flag_typed_selectors = 1;
@@ -477,12 +535,13 @@ objc_init (filename)
if (print_struct_values)
generate_struct_by_value_array ();
- return filename;
+ return true;
}
void
-finish_file ()
+finish_file (void)
{
+ mark_referenced_methods ();
c_objc_common_finish_file ();
/* Finalize Objective-C runtime data. No need to generate tables
@@ -495,32 +554,16 @@ finish_file ()
}
static tree
-define_decl (declarator, declspecs)
- tree declarator;
- tree declspecs;
+define_decl (tree declarator, tree declspecs)
{
tree decl = start_decl (declarator, declspecs, 0, NULL_TREE);
finish_decl (decl, NULL_TREE, NULL_TREE);
return decl;
}
-/* Return 1 if LHS and RHS are compatible types for assignment or
- various other operations. Return 0 if they are incompatible, and
- return -1 if we choose to not decide. When the operation is
- REFLEXIVE, check for compatibility in either direction.
-
- For statically typed objects, an assignment of the form `a' = `b'
- is permitted if:
-
- `a' is of type "id",
- `a' and `b' are the same class type, or
- `a' and `b' are of class types A and B such that B is a descendant of A. */
-
static tree
-lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
- tree rproto_list;
- tree sel_name;
- int class_meth;
+lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
+ int class_meth)
{
tree rproto, p;
tree fnd = 0;
@@ -552,9 +595,7 @@ lookup_method_in_protocol_list (rproto_list, sel_name, class_meth)
}
static tree
-lookup_protocol_in_reflist (rproto_list, lproto)
- tree rproto_list;
- tree lproto;
+lookup_protocol_in_reflist (tree rproto_list, tree lproto)
{
tree rproto, p;
@@ -607,10 +648,7 @@ lookup_protocol_in_reflist (rproto_list, lproto)
*/
int
-objc_comptypes (lhs, rhs, reflexive)
- tree lhs;
- tree rhs;
- int reflexive;
+objc_comptypes (tree lhs, tree rhs, int reflexive)
{
/* New clause for protocols. */
@@ -634,20 +672,20 @@ objc_comptypes (lhs, rhs, reflexive)
if (rhs_is_proto)
{
rproto_list = TYPE_PROTOCOL_LIST (rhs);
-
+
if (!reflexive)
{
/* An assignment between objects of type 'id
<Protocol>'; make sure the protocol on the lhs is
supported by the object on the rhs. */
- for (lproto = lproto_list; lproto;
+ for (lproto = lproto_list; lproto;
lproto = TREE_CHAIN (lproto))
{
p = TREE_VALUE (lproto);
rproto = lookup_protocol_in_reflist (rproto_list, p);
if (!rproto)
- warning
+ warning
("object does not conform to the `%s' protocol",
IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
}
@@ -659,20 +697,20 @@ objc_comptypes (lhs, rhs, reflexive)
of type 'id <Protocol>'. Check that either the
protocol on the lhs is supported by the object on
the rhs, or viceversa. */
-
+
/* Check if the protocol on the lhs is supported by the
object on the rhs. */
- for (lproto = lproto_list; lproto;
+ for (lproto = lproto_list; lproto;
lproto = TREE_CHAIN (lproto))
{
p = TREE_VALUE (lproto);
rproto = lookup_protocol_in_reflist (rproto_list, p);
-
+
if (!rproto)
{
/* Check failed - check if the protocol on the rhs
is supported by the object on the lhs. */
- for (rproto = rproto_list; rproto;
+ for (rproto = rproto_list; rproto;
rproto = TREE_CHAIN (rproto))
{
p = TREE_VALUE (rproto);
@@ -694,7 +732,7 @@ objc_comptypes (lhs, rhs, reflexive)
/* <Protocol> = <class> * */
else if (TYPED_OBJECT (TREE_TYPE (rhs)))
{
- tree rname = TYPE_NAME (TREE_TYPE (rhs));
+ tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
tree rinter;
/* Make sure the protocol is supported by the object on
@@ -735,18 +773,18 @@ objc_comptypes (lhs, rhs, reflexive)
if (!rproto)
warning ("class `%s' does not implement the `%s' protocol",
- IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))),
+ IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
}
return 1;
}
/* <Protocol> = id */
- else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
+ else if (OBJC_TYPE_NAME (TREE_TYPE (rhs)) == objc_object_id)
{
return 1;
}
/* <Protocol> = Class */
- else if (TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
+ else if (OBJC_TYPE_NAME (TREE_TYPE (rhs)) == objc_class_id)
{
return 0;
}
@@ -760,13 +798,13 @@ objc_comptypes (lhs, rhs, reflexive)
{
if (reflexive)
{
- tree rname = TYPE_NAME (TREE_TYPE (lhs));
+ tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
tree rinter;
tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
-
+
/* Make sure the protocol is supported by the object on
the lhs. */
- for (rproto = rproto_list; rproto;
+ for (rproto = rproto_list; rproto;
rproto = TREE_CHAIN (rproto))
{
tree p = TREE_VALUE (rproto);
@@ -786,9 +824,9 @@ objc_comptypes (lhs, rhs, reflexive)
lhs. */
if (!lproto)
{
- lproto_list = TYPE_PROTOCOL_LIST
+ lproto_list = TYPE_PROTOCOL_LIST
(TREE_TYPE (lhs));
- lproto = lookup_protocol_in_reflist
+ lproto = lookup_protocol_in_reflist
(lproto_list, p);
}
@@ -801,14 +839,14 @@ objc_comptypes (lhs, rhs, reflexive)
p);
cat = CLASS_CATEGORY_LIST (cat);
}
-
- rinter = lookup_interface (CLASS_SUPER_NAME
+
+ rinter = lookup_interface (CLASS_SUPER_NAME
(rinter));
}
-
+
if (!lproto)
warning ("class `%s' does not implement the `%s' protocol",
- IDENTIFIER_POINTER (TYPE_NAME
+ IDENTIFIER_POINTER (OBJC_TYPE_NAME
(TREE_TYPE (lhs))),
IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
}
@@ -818,12 +856,12 @@ objc_comptypes (lhs, rhs, reflexive)
return 0;
}
/* id = <Protocol> */
- else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
+ else if (OBJC_TYPE_NAME (TREE_TYPE (lhs)) == objc_object_id)
{
return 1;
}
/* Class = <Protocol> */
- else if (TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
+ else if (OBJC_TYPE_NAME (TREE_TYPE (lhs)) == objc_class_id)
{
return 0;
}
@@ -852,28 +890,28 @@ objc_comptypes (lhs, rhs, reflexive)
}
/* `id' = `<class> *' `<class> *' = `id': always allow it.
- Please note that
+ Please note that
'Object *o = [[Object alloc] init]; falls
in the case <class> * = `id'.
*/
- if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
- || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
+ if ((OBJC_TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs))
+ || (OBJC_TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs)))
return 1;
/* `id' = `Class', `Class' = `id' */
- else if ((TYPE_NAME (lhs) == objc_object_id
- && TYPE_NAME (rhs) == objc_class_id)
- || (TYPE_NAME (lhs) == objc_class_id
- && TYPE_NAME (rhs) == objc_object_id))
+ else if ((OBJC_TYPE_NAME (lhs) == objc_object_id
+ && OBJC_TYPE_NAME (rhs) == objc_class_id)
+ || (OBJC_TYPE_NAME (lhs) == objc_class_id
+ && OBJC_TYPE_NAME (rhs) == objc_object_id))
return 1;
/* `<class> *' = `<class> *' */
else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
{
- tree lname = TYPE_NAME (lhs);
- tree rname = TYPE_NAME (rhs);
+ tree lname = OBJC_TYPE_NAME (lhs);
+ tree rname = OBJC_TYPE_NAME (rhs);
tree inter;
if (lname == rname)
@@ -900,26 +938,24 @@ objc_comptypes (lhs, rhs, reflexive)
return -1;
}
-/* Called from c-decl.c before all calls to rest_of_decl_compilation. */
+/* Called from finish_decl. */
void
-objc_check_decl (decl)
- tree decl;
+objc_check_decl (tree decl)
{
tree type = TREE_TYPE (decl);
- if (TREE_CODE (type) == RECORD_TYPE
- && TREE_STATIC_TEMPLATE (type)
- && type != constant_string_type)
- error_with_decl (decl, "`%s' cannot be statically allocated");
+ if (TREE_CODE (type) != RECORD_TYPE)
+ return;
+ if (TYPE_NAME (type) && (type = is_class_name (TYPE_NAME (type))))
+ error ("statically allocated instance of Objective-C class `%s'",
+ IDENTIFIER_POINTER (type));
}
/* Implement static typing. At this point, we know we have an interface. */
tree
-get_static_reference (interface, protocols)
- tree interface;
- tree protocols;
+get_static_reference (tree interface, tree protocols)
{
tree type = xref_tag (RECORD_TYPE, interface);
@@ -935,7 +971,7 @@ get_static_reference (interface, protocols)
/* Look up protocols and install in lang specific list. Note
that the protocol list can have a different lifetime than T! */
- TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
+ SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
/* This forces a new pointer type to be created later
(in build_pointer_type)...so that the new template
@@ -950,8 +986,7 @@ get_static_reference (interface, protocols)
}
tree
-get_object_reference (protocols)
- tree protocols;
+get_object_reference (tree protocols)
{
tree type_decl = lookup_name (objc_id_id);
tree type;
@@ -984,7 +1019,7 @@ get_object_reference (protocols)
TYPE_NEXT_VARIANT (m) = t;
/* Look up protocols...and install in lang specific list */
- TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols);
+ SET_TYPE_PROTOCOL_LIST (t, lookup_and_install_protocols (protocols));
/* This forces a new pointer type to be created later
(in build_pointer_type)...so that the new template
@@ -1001,10 +1036,8 @@ get_object_reference (protocols)
PROTO, the protocol to check, and LIST, a list of protocol it
conforms to. */
-static void
-check_protocol_recursively (proto, list)
- tree proto;
- tree list;
+static void
+check_protocol_recursively (tree proto, tree list)
{
tree p;
@@ -1017,19 +1050,20 @@ check_protocol_recursively (proto, list)
if (pp == proto)
fatal_error ("protocol `%s' has circular dependency",
- IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
+ IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
if (pp)
check_protocol_recursively (proto, PROTOCOL_LIST (pp));
}
}
+/* Look up PROTOCOLS, and return a list of those that are found.
+ If none are found, return NULL. */
+
static tree
-lookup_and_install_protocols (protocols)
- tree protocols;
+lookup_and_install_protocols (tree protocols)
{
tree proto;
- tree prev = NULL;
- tree return_value = protocols;
+ tree return_value = NULL_TREE;
for (proto = protocols; proto; proto = TREE_CHAIN (proto))
{
@@ -1037,20 +1071,11 @@ lookup_and_install_protocols (protocols)
tree p = lookup_protocol (ident);
if (!p)
- {
- error ("cannot find protocol declaration for `%s'",
- IDENTIFIER_POINTER (ident));
- if (prev)
- TREE_CHAIN (prev) = TREE_CHAIN (proto);
- else
- return_value = TREE_CHAIN (proto);
- }
+ error ("cannot find protocol declaration for `%s'",
+ IDENTIFIER_POINTER (ident));
else
- {
- /* Replace identifier with actual protocol node. */
- TREE_VALUE (proto) = p;
- prev = proto;
- }
+ return_value = chainon (return_value,
+ build_tree_list (NULL_TREE, p));
}
return return_value;
@@ -1061,10 +1086,7 @@ lookup_and_install_protocols (protocols)
TYPE is its data type. */
static tree
-create_builtin_decl (code, type, name)
- enum tree_code code;
- tree type;
- const char *name;
+create_builtin_decl (enum tree_code code, tree type, const char *name)
{
tree decl = build_decl (code, get_identifier (name), type);
@@ -1073,21 +1095,31 @@ create_builtin_decl (code, type, name)
TREE_STATIC (decl) = 1;
make_decl_rtl (decl, 0);
pushdecl (decl);
+ DECL_ARTIFICIAL (decl) = 1;
}
- DECL_ARTIFICIAL (decl) = 1;
return decl;
}
/* Find the decl for the constant string class. */
static void
-setup_string_decl ()
+setup_string_decl (void)
{
if (!string_class_decl)
{
if (!constant_string_global_id)
- constant_string_global_id = get_identifier (STRING_OBJECT_GLOBAL_NAME);
+ {
+ char *name;
+ size_t length;
+ /* %s in format will provide room for terminating null */
+ length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
+ + strlen (constant_string_class_name);
+ name = xmalloc (length);
+ sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
+ constant_string_class_name);
+ constant_string_global_id = get_identifier (name);
+ }
string_class_decl = lookup_name (constant_string_global_id);
}
}
@@ -1097,17 +1129,16 @@ setup_string_decl ()
Model:
- type_spec--------->sc_spec
- (tree_list) (tree_list)
- | |
- | |
- identifier_node identifier_node */
+ type_spec--------->sc_spec
+ (tree_list) (tree_list)
+ | |
+ | |
+ identifier_node identifier_node */
static void
-synth_module_prologue ()
+synth_module_prologue (void)
{
tree temp_type;
- tree super_p;
/* Defined in `objc.h' */
objc_object_id = get_identifier (TAG_OBJECT);
@@ -1120,8 +1151,10 @@ synth_module_prologue ()
objc_class_id = get_identifier (TAG_CLASS);
objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id));
+ temp_type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
+ objc_declare_class (tree_cons (NULL_TREE, temp_type, NULL_TREE));
protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
- get_identifier (PROTOCOL_OBJECT_CLASS_NAME)));
+ temp_type));
/* Declare type of selector-objects that represent an operation name. */
@@ -1133,7 +1166,8 @@ synth_module_prologue ()
/* Forward declare type, or else the prototype for msgSendSuper will
complain. */
- super_p = build_pointer_type (xref_tag (RECORD_TYPE,
+ /* `struct objc_super *' */
+ super_type = build_pointer_type (xref_tag (RECORD_TYPE,
get_identifier (TAG_SUPER)));
@@ -1158,14 +1192,21 @@ synth_module_prologue ()
pushdecl (umsg_decl);
}
else
- umsg_decl = builtin_function (TAG_MSGSEND, temp_type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
+ {
+ umsg_decl = builtin_function (TAG_MSGSEND,
+ temp_type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
+ /* id objc_msgSendNonNil (id, SEL, ...); */
+ umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
+ temp_type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
+ }
/* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
temp_type
= build_function_type (id_type,
- tree_cons (NULL_TREE, super_p,
+ tree_cons (NULL_TREE, super_type,
tree_cons (NULL_TREE, selector_type,
NULL_TREE)));
@@ -1173,13 +1214,68 @@ synth_module_prologue ()
temp_type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
+ /* The NeXT runtime defines the following additional entry points,
+ used for dispatching calls to methods returning structs:
+
+ #if defined(__cplusplus)
+ id objc_msgSend_stret(id self, SEL op, ...);
+ id objc_msgSendSuper_stret(struct objc_super *super, SEL op, ...);
+ #else
+ void objc_msgSend_stret(void * stretAddr, id self, SEL op, ...);
+ void objc_msgSendSuper_stret(void * stretAddr, struct objc_super *super,
+ SEL op, ...);
+ #endif
+
+ struct objc_return_struct objc_msgSendNonNil_stret(id self, SEL op, ...);
+
+ These prototypes appear in <objc/objc-runtime.h>; however, they
+ CANNOT BE USED DIRECTLY. In order to call one of the ..._stret
+ functions, the function must first be cast to a signature that
+ corresponds to the actual ObjC method being invoked. This is
+ what is done by the build_objc_method_call() routine below. */
+
+ if (flag_next_runtime)
+ {
+ tree objc_return_struct_type
+ = xref_tag (RECORD_TYPE,
+ get_identifier (TAG_RETURN_STRUCT));
+
+ tree stret_temp_type
+ = build_function_type (id_type,
+ tree_cons (NULL_TREE, id_type,
+ tree_cons (NULL_TREE, selector_type,
+ NULL_TREE)));
+
+ umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
+ stret_temp_type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
+ stret_temp_type
+ = build_function_type (objc_return_struct_type,
+ tree_cons (NULL_TREE, id_type,
+ tree_cons (NULL_TREE, selector_type,
+ NULL_TREE)));
+
+ umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
+ stret_temp_type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
+
+ stret_temp_type
+ = build_function_type (id_type,
+ tree_cons (NULL_TREE, super_type,
+ tree_cons (NULL_TREE, selector_type,
+ NULL_TREE)));
+
+ umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
+ stret_temp_type, 0, NOT_BUILT_IN, 0,
+ NULL_TREE);
+ }
+
/* id objc_getClass (const char *); */
temp_type = build_function_type (id_type,
- tree_cons (NULL_TREE,
- const_string_type_node,
- tree_cons (NULL_TREE, void_type_node,
- NULL_TREE)));
+ tree_cons (NULL_TREE,
+ const_string_type_node,
+ OBJC_VOID_AT_END));
objc_get_class_decl
= builtin_function (TAG_GETCLASS, temp_type, 0, NOT_BUILT_IN,
@@ -1188,8 +1284,11 @@ synth_module_prologue ()
/* id objc_getMetaClass (const char *); */
objc_get_meta_class_decl
- = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
+ = builtin_function (TAG_GETMETACLASS, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+
+ build_super_template ();
+ if (flag_next_runtime)
+ build_objc_exception_stuff ();
/* static SEL _OBJC_SELECTOR_TABLE[]; */
@@ -1229,92 +1328,104 @@ synth_module_prologue ()
constant_string_class_name = default_constant_string_class_name;
constant_string_id = get_identifier (constant_string_class_name);
- constant_string_type = xref_tag (RECORD_TYPE, constant_string_id);
+ objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
+
+ /* Pre-build the following entities - for speed/convenience. */
+ self_id = get_identifier ("self");
+ ucmd_id = get_identifier ("_cmd");
+#ifndef OBJCPLUS
+ /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
+ unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
+#endif
}
-/* Predefine the following data type:
+/* Ensure that the ivar list for NSConstantString/NXConstantString
+ (or whatever was specified via `-fconstant-string-class')
+ contains fields at least as large as the following three, so that
+ the runtime can stomp on them with confidence:
- struct STRING_OBJECT_CLASS_NAME
+ struct STRING_OBJECT_CLASS_NAME
{
Object isa;
char *cString;
unsigned int length;
}; */
-static void
-build_string_class_template ()
+static int
+check_string_class_template (void)
{
- tree field_decl, field_decl_chain;
+ tree field_decl = TYPE_FIELDS (constant_string_type);
- field_decl = create_builtin_decl (FIELD_DECL, id_type, "isa");
- field_decl_chain = field_decl;
+#define AT_LEAST_AS_LARGE_AS(F, T) \
+ (F && TREE_CODE (F) == FIELD_DECL \
+ && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
+ >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
- field_decl = create_builtin_decl (FIELD_DECL,
- build_pointer_type (char_type_node),
- "cString");
- chainon (field_decl_chain, field_decl);
+ if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
+ return 0;
- field_decl = create_builtin_decl (FIELD_DECL, unsigned_type_node, "length");
- chainon (field_decl_chain, field_decl);
+ field_decl = TREE_CHAIN (field_decl);
+ if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
+ return 0;
+
+ field_decl = TREE_CHAIN (field_decl);
+ return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
- finish_struct (constant_string_type, field_decl_chain, NULL_TREE);
+#undef AT_LEAST_AS_LARGE_AS
}
+/* Avoid calling `check_string_class_template ()' more than once. */
+static GTY(()) int string_layout_checked;
+
/* Custom build_string which sets TREE_TYPE! */
static tree
-my_build_string (len, str)
- int len;
- const char *str;
+my_build_string (int len, const char *str)
{
return fix_string_type (build_string (len, str));
}
/* Given a chain of STRING_CST's, build a static instance of
- NXConstantString which points at the concatenation of those strings.
- We place the string object in the __string_objects section of the
- __OBJC segment. The Objective-C runtime will initialize the isa
- pointers of the string objects to point at the NXConstantString
- class object. */
+ NXConstantString which points at the concatenation of those
+ strings. We place the string object in the __string_objects
+ section of the __OBJC segment. The Objective-C runtime will
+ initialize the isa pointers of the string objects to point at the
+ NXConstantString class object. */
tree
-build_objc_string_object (strings)
- tree strings;
+build_objc_string_object (tree string)
{
- tree string, initlist, constructor;
+ tree initlist, constructor, constant_string_class;
int length;
- if (lookup_interface (constant_string_id) == NULL_TREE)
+ string = fix_string_type (string);
+
+ constant_string_class = lookup_interface (constant_string_id);
+ if (!constant_string_class
+ || !(constant_string_type
+ = CLASS_STATIC_TEMPLATE (constant_string_class)))
{
error ("cannot find interface declaration for `%s'",
IDENTIFIER_POINTER (constant_string_id));
return error_mark_node;
}
- add_class_reference (constant_string_id);
-
- if (TREE_CHAIN (strings))
- {
- varray_type vstrings;
- VARRAY_TREE_INIT (vstrings, 32, "strings");
-
- for (; strings ; strings = TREE_CHAIN (strings))
- VARRAY_PUSH_TREE (vstrings, strings);
-
- string = combine_strings (vstrings);
- }
- else
- string = strings;
-
- string = fix_string_type (string);
-
+ /* Call to 'combine_strings' has been moved above. */
TREE_SET_CODE (string, STRING_CST);
length = TREE_STRING_LENGTH (string) - 1;
- /* We could not properly create NXConstantString in synth_module_prologue,
- because that's called before debugging is initialized. Do it now. */
- if (TYPE_FIELDS (constant_string_type) == NULL_TREE)
- build_string_class_template ();
+ if (!string_layout_checked)
+ {
+ /* The NSConstantString/NXConstantString ivar layout is now
+ known. */
+ if (!check_string_class_template ())
+ {
+ error ("interface `%s' does not have valid constant string layout",
+ IDENTIFIER_POINTER (constant_string_id));
+ return error_mark_node;
+ }
+ add_class_reference (constant_string_id);
+ }
/* & ((NXConstantString) { NULL, string, length }) */
@@ -1342,7 +1453,8 @@ build_objc_string_object (strings)
= tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)),
initlist);
initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist);
- constructor = build_constructor (constant_string_type, nreverse (initlist));
+ constructor = objc_build_constructor (constant_string_type,
+ nreverse (initlist));
if (!flag_next_runtime)
{
@@ -1355,11 +1467,11 @@ build_objc_string_object (strings)
/* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
+static GTY(()) int num_static_inst;
+
static tree
-objc_add_static_instance (constructor, class_decl)
- tree constructor, class_decl;
+objc_add_static_instance (tree constructor, tree class_decl)
{
- static int num_static_inst;
tree *chain, decl;
char buf[256];
@@ -1371,7 +1483,7 @@ objc_add_static_instance (constructor, class_decl)
if (!*chain)
{
*chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
- add_objc_string (TYPE_NAME (class_decl), class_names);
+ add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
}
sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
@@ -1397,8 +1509,7 @@ objc_add_static_instance (constructor, class_decl)
with type TYPE and elements ELTS. */
static tree
-build_constructor (type, elts)
- tree type, elts;
+objc_build_constructor (tree type, tree elts)
{
tree constructor, f, e;
@@ -1420,11 +1531,16 @@ build_constructor (type, elts)
TREE_VALUE (e) = convert (TREE_TYPE (f), TREE_VALUE (e));
}
- constructor = build (CONSTRUCTOR, type, NULL_TREE, elts);
+ constructor = build_constructor (type, elts);
TREE_CONSTANT (constructor) = 1;
TREE_STATIC (constructor) = 1;
TREE_READONLY (constructor) = 1;
+#ifdef OBJCPLUS
+ /* zlaski 2001-Apr-02: mark this as a call to a constructor, as required by
+ build_unary_op (wasn't true in 2.7.2.1 days) */
+ TREE_HAS_CONSTRUCTOR (constructor) = 1;
+#endif
return constructor;
}
@@ -1442,9 +1558,9 @@ build_constructor (type, elts)
}; */
static void
-build_objc_symtab_template ()
+build_objc_symtab_template (void)
{
- tree field_decl, field_decl_chain, index;
+ tree field_decl, field_decl_chain;
objc_symtab_template
= start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
@@ -1477,18 +1593,20 @@ build_objc_symtab_template ()
"cat_def_cnt");
chainon (field_decl_chain, field_decl);
- /* void *defs[cls_def_cnt + cat_def_cnt]; */
-
- if (!flag_next_runtime)
- index = build_index_type (build_int_2 (imp_count + cat_count, 0));
- else
- index = build_index_type (build_int_2 (imp_count + cat_count - 1,
- imp_count == 0 && cat_count == 0
- ? -1 : 0));
- field_decl = create_builtin_decl (FIELD_DECL,
- build_array_type (ptr_type_node, index),
- "defs");
- chainon (field_decl_chain, field_decl);
+ if (imp_count || cat_count || !flag_next_runtime)
+ {
+ /* void *defs[imp_count + cat_count (+ 1)]; */
+ /* NB: The index is one less than the size of the array. */
+ int index = imp_count + cat_count
+ + (flag_next_runtime? -1: 0);
+ field_decl = create_builtin_decl
+ (FIELD_DECL,
+ build_array_type
+ (ptr_type_node,
+ build_index_type (build_int_2 (index, 0))),
+ "defs");
+ chainon (field_decl_chain, field_decl);
+ }
finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
}
@@ -1497,8 +1615,7 @@ build_objc_symtab_template ()
This is a CONSTRUCTOR. */
static tree
-init_def_list (type)
- tree type;
+init_def_list (tree type)
{
tree expr, initlist = NULL_TREE;
struct imp_entry *impent;
@@ -1536,14 +1653,13 @@ init_def_list (type)
initlist = tree_cons (NULL_TREE, expr, initlist);
}
- return build_constructor (type, nreverse (initlist));
+ return objc_build_constructor (type, nreverse (initlist));
}
/* Construct the initial value for all of _objc_symtab. */
static tree
-init_objc_symtab (type)
- tree type;
+init_objc_symtab (tree type)
{
tree initlist;
@@ -1571,7 +1687,7 @@ init_objc_symtab (type)
/* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
- if (imp_count || cat_count || static_instances_decl)
+ if (imp_count || cat_count || !flag_next_runtime)
{
tree field = TYPE_FIELDS (type);
@@ -1581,14 +1697,34 @@ init_objc_symtab (type)
initlist);
}
- return build_constructor (type, nreverse (initlist));
+ return objc_build_constructor (type, nreverse (initlist));
+}
+
+/* Generate forward declarations for metadata such as
+ 'OBJC_CLASS_...'. */
+
+static tree
+build_metadata_decl (const char *name, tree type)
+{
+ tree decl, decl_specs;
+ /* extern struct TYPE NAME_<name>; */
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
+ decl_specs = tree_cons (NULL_TREE, type, decl_specs);
+ decl = define_decl (synth_id_with_class_suffix
+ (name,
+ objc_implementation_context),
+ decl_specs);
+ TREE_USED (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ TREE_PUBLIC (decl) = 0;
+ return decl;
}
/* Push forward-declarations of all the categories so that
init_def_list can use them in a CONSTRUCTOR. */
static void
-forward_declare_categories ()
+forward_declare_categories (void)
{
struct imp_entry *impent;
tree sav = objc_implementation_context;
@@ -1599,19 +1735,19 @@ forward_declare_categories ()
{
/* Set an invisible arg to synth_id_with_class_suffix. */
objc_implementation_context = impent->imp_context;
- impent->class_decl
- = create_builtin_decl (VAR_DECL, objc_category_template,
- IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context)));
+ /* extern struct objc_category _OBJC_CATEGORY_<name>; */
+ impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
+ objc_category_template);
}
}
objc_implementation_context = sav;
}
-/* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
+/* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
and initialized appropriately. */
static void
-generate_objc_symtab_decl ()
+generate_objc_symtab_decl (void)
{
tree sc_spec;
@@ -1642,8 +1778,7 @@ generate_objc_symtab_decl ()
}
static tree
-init_module_descriptor (type)
- tree type;
+init_module_descriptor (tree type)
{
tree initlist, expr;
@@ -1670,7 +1805,7 @@ init_module_descriptor (type)
expr = build_int_2 (0, 0);
initlist = tree_cons (NULL_TREE, expr, initlist);
- return build_constructor (type, nreverse (initlist));
+ return objc_build_constructor (type, nreverse (initlist));
}
/* Write out the data structures to describe Objective C classes defined.
@@ -1681,7 +1816,7 @@ init_module_descriptor (type)
struct objc_module { ... } _OBJC_MODULE = { ... }; */
static rtx
-build_module_descriptor ()
+build_module_descriptor (void)
{
tree decl_specs, field_decl, field_decl_chain;
@@ -1692,24 +1827,21 @@ build_module_descriptor ()
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
field_decl = get_identifier ("version");
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
/* long size; */
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
field_decl = get_identifier ("size");
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* char *name; */
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* struct objc_symtab *symtab; */
@@ -1717,8 +1849,7 @@ build_module_descriptor ()
decl_specs = get_identifier (UTAG_SYMTAB);
decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
@@ -1762,7 +1893,8 @@ build_module_descriptor ()
get_identifier (TAG_EXECCLASS),
build_function_type (void_type_node,
tree_cons (NULL_TREE, ptr_type_node,
- void_list_node_1)));
+ OBJC_VOID_AT_END)));
+
DECL_EXTERNAL (execclass_decl) = 1;
DECL_ARTIFICIAL (execclass_decl) = 1;
TREE_PUBLIC (execclass_decl) = 1;
@@ -1776,7 +1908,7 @@ build_module_descriptor ()
start_function (void_list_node_1,
build_nt (CALL_EXPR, init_function_name,
tree_cons (NULL_TREE, NULL_TREE,
- void_list_node_1),
+ OBJC_VOID_AT_END),
NULL_TREE),
NULL_TREE);
store_parm_decls ();
@@ -1797,7 +1929,7 @@ build_module_descriptor ()
c_expand_expr_stmt (decelerator);
- finish_function (0, 0);
+ finish_function ();
return XEXP (DECL_RTL (init_function_decl), 0);
}
@@ -1806,7 +1938,7 @@ build_module_descriptor ()
/* extern const char _OBJC_STRINGS[]; */
static void
-generate_forward_declaration_to_string_table ()
+generate_forward_declaration_to_string_table (void)
{
tree sc_spec, decl_specs, expr_decl;
@@ -1822,9 +1954,7 @@ generate_forward_declaration_to_string_table ()
/* Return the DECL of the string IDENT in the SECTION. */
static tree
-get_objc_string_decl (ident, section)
- tree ident;
- enum string_section section;
+get_objc_string_decl (tree ident, enum string_section section)
{
tree chain;
@@ -1849,7 +1979,7 @@ get_objc_string_decl (ident, section)
for the array built. */
static void
-generate_static_references ()
+generate_static_references (void)
{
tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE;
tree class_name, class, decl, initlist;
@@ -1879,7 +2009,7 @@ generate_static_references ()
/* Output {class_name, ...}. */
class = TREE_VALUE (cl_chain);
- class_name = get_objc_string_decl (TYPE_NAME (class), class_names);
+ class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
initlist = build_tree_list (NULL_TREE,
build_unary_op (ADDR_EXPR, class_name, 1));
@@ -1894,7 +2024,7 @@ generate_static_references ()
/* Output {..., NULL}. */
initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
- expr = build_constructor (TREE_TYPE (decl), nreverse (initlist));
+ expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
finish_decl (decl, expr, NULL_TREE);
TREE_USED (decl) = 1;
@@ -1917,7 +2047,7 @@ generate_static_references ()
TREE_USED (static_instances_decl) = 1;
DECL_CONTEXT (static_instances_decl) = 0;
DECL_ARTIFICIAL (static_instances_decl) = 1;
- expr = build_constructor (TREE_TYPE (static_instances_decl),
+ expr = objc_build_constructor (TREE_TYPE (static_instances_decl),
nreverse (decls));
finish_decl (static_instances_decl, expr, NULL_TREE);
}
@@ -1925,7 +2055,7 @@ generate_static_references ()
/* Output all strings. */
static void
-generate_strings ()
+generate_strings (void)
{
tree sc_spec, decl_specs, expr_decl;
tree chain, string_expr;
@@ -1977,22 +2107,22 @@ generate_strings ()
}
}
+static GTY(()) int selector_reference_idx;
+
static tree
-build_selector_reference_decl ()
+build_selector_reference_decl (void)
{
tree decl, ident;
char buf[256];
- static int idx = 0;
- sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++);
+ sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
ident = get_identifier (buf);
decl = build_decl (VAR_DECL, ident, selector_type);
DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 1;
+ TREE_PUBLIC (decl) = 0;
TREE_USED (decl) = 1;
- TREE_READONLY (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
DECL_CONTEXT (decl) = 0;
@@ -2005,8 +2135,7 @@ build_selector_reference_decl ()
/* Just a handy wrapper for add_objc_string. */
static tree
-build_selector (ident)
- tree ident;
+build_selector (tree ident)
{
tree expr = add_objc_string (ident, meth_var_names);
if (flag_typed_selectors)
@@ -2016,7 +2145,7 @@ build_selector (ident)
}
static void
-build_selector_translation_table ()
+build_selector_translation_table (void)
{
tree sc_spec, decl_specs;
tree chain, initlist = NULL_TREE;
@@ -2044,12 +2173,12 @@ build_selector_translation_table ()
if (!found)
{
/* Adjust line number for warning message. */
- int save_lineno = lineno;
+ int save_lineno = input_line;
if (flag_next_runtime && TREE_PURPOSE (chain))
- lineno = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
+ input_line = DECL_SOURCE_LINE (TREE_PURPOSE (chain));
warning ("creating selector for non existant method %s",
IDENTIFIER_POINTER (TREE_VALUE (chain)));
- lineno = save_lineno;
+ input_line = save_lineno;
}
}
@@ -2076,7 +2205,7 @@ build_selector_translation_table ()
if (flag_next_runtime)
finish_decl (decl, expr, NULL_TREE);
- else
+ else
{
if (flag_typed_selectors)
{
@@ -2084,11 +2213,11 @@ build_selector_translation_table ()
tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
eltlist = tree_cons (NULL_TREE, encoding, eltlist);
- expr = build_constructor (objc_selector_template,
- nreverse (eltlist));
+ expr = objc_build_constructor (objc_selector_template,
+ nreverse (eltlist));
}
initlist = tree_cons (NULL_TREE, expr, initlist);
-
+
}
}
@@ -2100,29 +2229,24 @@ build_selector_translation_table ()
/* NULL terminate the list and fix the decl for output. */
initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = objc_ellipsis_node;
- initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
- nreverse (initlist));
+ initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
+ nreverse (initlist));
finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE);
current_function_decl = NULL_TREE;
}
}
static tree
-get_proto_encoding (proto)
- tree proto;
+get_proto_encoding (tree proto)
{
tree encoding;
if (proto)
{
- tree tmp_decl;
-
if (! METHOD_ENCODING (proto))
{
- tmp_decl = build_tmp_function_decl ();
- hack_method_prototype (proto, tmp_decl);
- encoding = encode_method_prototype (proto, tmp_decl);
- METHOD_ENCODING (proto) = encoding;
- }
+ encoding = encode_method_prototype (proto);
+ METHOD_ENCODING (proto) = encoding;
+ }
else
encoding = METHOD_ENCODING (proto);
@@ -2136,8 +2260,7 @@ get_proto_encoding (proto)
identifier_node that represent the selector. */
static tree
-build_typed_selector_reference (ident, prototype)
- tree ident, prototype;
+build_typed_selector_reference (tree ident, tree prototype)
{
tree *chain = &sel_ref_chain;
tree expr;
@@ -2163,8 +2286,7 @@ build_typed_selector_reference (ident, prototype)
}
static tree
-build_selector_reference (ident)
- tree ident;
+build_selector_reference (tree ident)
{
tree *chain = &sel_ref_chain;
tree expr;
@@ -2192,22 +2314,22 @@ build_selector_reference (ident)
build_int_2 (index, 0)));
}
+static GTY(()) int class_reference_idx;
+
static tree
-build_class_reference_decl ()
+build_class_reference_decl (void)
{
tree decl, ident;
char buf[256];
- static int idx = 0;
- sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++);
+ sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
ident = get_identifier (buf);
decl = build_decl (VAR_DECL, ident, objc_class_type);
DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 1;
+ TREE_PUBLIC (decl) = 0;
TREE_USED (decl) = 1;
- TREE_READONLY (decl) = 1;
DECL_CONTEXT (decl) = 0;
DECL_ARTIFICIAL (decl) = 1;
@@ -2221,8 +2343,7 @@ build_class_reference_decl ()
it. */
static void
-add_class_reference (ident)
- tree ident;
+add_class_reference (tree ident)
{
tree chain;
@@ -2250,10 +2371,27 @@ add_class_reference (ident)
reference variable. */
tree
-get_class_reference (ident)
- tree ident;
+get_class_reference (tree ident)
{
- if (flag_next_runtime)
+ tree orig_ident;
+
+#ifdef OBJCPLUS
+ if (processing_template_decl)
+ /* Must wait until template instantiation time. */
+ return build_min_nt (CLASS_REFERENCE_EXPR, ident);
+ if (TREE_CODE (ident) == TYPE_DECL)
+ ident = DECL_NAME (ident);
+#endif
+ orig_ident = ident;
+
+ if (!(ident = is_class_name (ident)))
+ {
+ error ("`%s' is not an Objective-C class name or alias",
+ IDENTIFIER_POINTER (orig_ident));
+ return error_mark_node;
+ }
+
+ if (flag_next_runtime && !flag_zero_link)
{
tree *chain;
tree decl;
@@ -2290,9 +2428,7 @@ get_class_reference (ident)
to decls for the strings. */
static tree
-add_objc_string (ident, section)
- tree ident;
- enum string_section section;
+add_objc_string (tree ident, enum string_section section)
{
tree *chain, decl;
@@ -2320,15 +2456,15 @@ add_objc_string (ident, section)
return build_unary_op (ADDR_EXPR, decl, 1);
}
+static GTY(()) int class_names_idx;
+static GTY(()) int meth_var_names_idx;
+static GTY(()) int meth_var_types_idx;
+
static tree
-build_objc_string_decl (section)
- enum string_section section;
+build_objc_string_decl (enum string_section section)
{
tree decl, ident;
char buf[256];
- static int class_names_idx = 0;
- static int meth_var_names_idx = 0;
- static int meth_var_types_idx = 0;
if (section == class_names)
sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
@@ -2341,13 +2477,12 @@ build_objc_string_decl (section)
decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 1;
+ TREE_PUBLIC (decl) = 0;
TREE_USED (decl) = 1;
- TREE_READONLY (decl) = 1;
TREE_CONSTANT (decl) = 1;
DECL_CONTEXT (decl) = 0;
DECL_ARTIFICIAL (decl) = 1;
-
+
make_decl_rtl (decl, 0);
pushdecl_top_level (decl);
@@ -2356,39 +2491,51 @@ build_objc_string_decl (section)
void
-objc_declare_alias (alias_ident, class_ident)
- tree alias_ident;
- tree class_ident;
+objc_declare_alias (tree alias_ident, tree class_ident)
{
- if (is_class_name (class_ident) != class_ident)
+ tree underlying_class;
+
+#ifdef OBJCPLUS
+ if (current_namespace != global_namespace) {
+ error ("Objective-C declarations may only appear in global scope");
+ }
+#endif /* OBJCPLUS */
+
+ if (!(underlying_class = is_class_name (class_ident)))
warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
else if (is_class_name (alias_ident))
warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
else
- alias_chain = tree_cons (class_ident, alias_ident, alias_chain);
+ alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
}
void
-objc_declare_class (ident_list)
- tree ident_list;
+objc_declare_class (tree ident_list)
{
tree list;
+#ifdef OBJCPLUS
+ if (current_namespace != global_namespace) {
+ error ("Objective-C declarations may only appear in global scope");
+ }
+#endif /* OBJCPLUS */
for (list = ident_list; list; list = TREE_CHAIN (list))
{
tree ident = TREE_VALUE (list);
- tree decl;
- if ((decl = lookup_name (ident)))
+ if (! is_class_name (ident))
{
- error ("`%s' redeclared as different kind of symbol",
- IDENTIFIER_POINTER (ident));
- error_with_decl (decl, "previous declaration of `%s'");
- }
+ tree record = lookup_name (ident);
+
+ if (record && ! TREE_STATIC_TEMPLATE (record))
+ {
+ error ("`%s' redeclared as different kind of symbol",
+ IDENTIFIER_POINTER (ident));
+ error ("%Jprevious declaration of '%D'",
+ record, record);
+ }
- if (! is_class_name (ident))
- {
- tree record = xref_tag (RECORD_TYPE, ident);
+ record = xref_tag (RECORD_TYPE, ident);
TREE_STATIC_TEMPLATE (record) = 1;
class_chain = tree_cons (NULL_TREE, ident, class_chain);
}
@@ -2396,11 +2543,25 @@ objc_declare_class (ident_list)
}
tree
-is_class_name (ident)
- tree ident;
+is_class_name (tree ident)
{
tree chain;
+ if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
+ && identifier_global_value (ident))
+ ident = identifier_global_value (ident);
+ while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
+ ident = TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
+
+#ifdef OBJCPLUS
+ if (ident && TREE_CODE (ident) == RECORD_TYPE)
+ ident = TYPE_NAME (ident);
+ if (ident && TREE_CODE (ident) == TYPE_DECL)
+ ident = DECL_NAME (ident);
+#endif
+ if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
+ return NULL_TREE;
+
if (lookup_interface (ident))
return ident;
@@ -2419,48 +2580,94 @@ is_class_name (ident)
return 0;
}
+/* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
+ class instance. This is needed by other parts of the compiler to
+ handle ObjC types gracefully. */
+
tree
-objc_is_id (ident)
- tree ident;
+objc_is_object_ptr (tree type)
{
- /* NB: This function may be called before the ObjC front-end
- has been initialized, in which case ID_TYPE will be NULL. */
- return (id_type && ident && TYPE_P (ident) && IS_ID (ident))
- ? id_type
- : NULL_TREE;
+ type = TYPE_MAIN_VARIANT (type);
+ if (!type || TREE_CODE (type) != POINTER_TYPE)
+ return 0;
+ /* NB: This function may be called before the ObjC front-end has
+ been initialized, in which case ID_TYPE will be NULL. */
+ if (id_type && type && TYPE_P (type)
+ && (IS_ID (type)
+ || TREE_TYPE (type) == TREE_TYPE (objc_class_type)))
+ return type;
+ return is_class_name (OBJC_TYPE_NAME (TREE_TYPE (type)));
}
tree
-lookup_interface (ident)
- tree ident;
+lookup_interface (tree ident)
{
tree chain;
+#ifdef OBJCPLUS
+ if (ident && TREE_CODE (ident) == TYPE_DECL)
+ ident = DECL_NAME (ident);
+#endif
for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
{
if (ident == CLASS_NAME (chain))
- return chain;
+ return chain;
}
return NULL_TREE;
}
+/* Implement @defs (<classname>) within struct bodies. */
+
+tree
+get_class_ivars_from_name (tree class_name)
+{
+ tree interface = lookup_interface (class_name);
+ tree field, fields = NULL_TREE;
+
+ if (interface)
+ {
+ tree raw_ivar = get_class_ivars (interface, 1);
+
+ /* Regenerate the FIELD_DECLs for the enclosing struct. */
+ for (; raw_ivar; raw_ivar = TREE_CHAIN (raw_ivar))
+ {
+ field = grokfield (TREE_PURPOSE (TREE_VALUE (raw_ivar)),
+ TREE_PURPOSE (raw_ivar),
+ TREE_VALUE (TREE_VALUE (raw_ivar)));
+#ifdef OBJCPLUS
+ finish_member_declaration (field);
+#else
+ fields = chainon (fields, field);
+#endif
+ }
+ }
+ else
+ error ("cannot find interface declaration for `%s'",
+ IDENTIFIER_POINTER (class_name));
+
+ return fields;
+}
+
/* Used by: build_private_template, continue_class,
and for @defs constructs. */
-tree
-get_class_ivars (interface)
- tree interface;
+static tree
+get_class_ivars (tree interface, int raw)
{
tree my_name, super_name, ivar_chain;
my_name = CLASS_NAME (interface);
super_name = CLASS_SUPER_NAME (interface);
- ivar_chain = CLASS_IVARS (interface);
-
- /* Save off a pristine copy of the leaf ivars (i.e, those not
- inherited from a super class). */
- if (!CLASS_OWN_IVARS (interface))
- CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
+ if (raw)
+ ivar_chain = CLASS_RAW_IVARS (interface);
+ else
+ {
+ ivar_chain = CLASS_IVARS (interface);
+ /* Save off a pristine copy of the leaf ivars (i.e, those not
+ inherited from a super class). */
+ if (!CLASS_OWN_IVARS (interface))
+ CLASS_OWN_IVARS (interface) = copy_list (ivar_chain);
+ }
while (super_name)
{
@@ -2484,7 +2691,7 @@ get_class_ivars (interface)
my_name = CLASS_NAME (interface);
super_name = CLASS_SUPER_NAME (interface);
- op1 = CLASS_OWN_IVARS (interface);
+ op1 = (raw ? CLASS_RAW_IVARS (interface) : CLASS_OWN_IVARS (interface));
if (op1)
{
tree head = copy_list (op1);
@@ -2495,17 +2702,698 @@ get_class_ivars (interface)
ivar_chain = head;
}
}
+
return ivar_chain;
}
+static tree
+objc_enter_block (void)
+{
+ tree block;
+
+#ifdef OBJCPLUS
+ block = begin_compound_stmt (0);
+#else
+ block = c_begin_compound_stmt ();
+ pushlevel (0);
+ clear_last_expr ();
+ add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
+#endif
+
+ objc_exception_block_stack = tree_cons (NULL_TREE, block,
+ objc_exception_block_stack);
+
+ blk_nesting_count++;
+ return block;
+}
+
+static tree
+objc_exit_block (void)
+{
+ tree block = TREE_VALUE (objc_exception_block_stack);
+#ifndef OBJCPLUS
+ tree scope_stmt, inner;
+#endif
+
+ objc_clear_super_receiver ();
+#ifdef OBJCPLUS
+ finish_compound_stmt (0, block);
+#else
+ scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
+ inner = poplevel (KEEP_MAYBE, 1, 0);
+
+ SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
+ = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
+ = inner;
+ RECHAIN_STMTS (block, COMPOUND_BODY (block));
+#endif
+ last_expr_type = NULL_TREE;
+ objc_exception_block_stack = TREE_CHAIN (objc_exception_block_stack);
+
+ blk_nesting_count--;
+ return block;
+}
+
+static tree
+objc_declare_variable (enum rid scspec, tree name, tree type, tree init)
+{
+ tree decl;
+
+ type = tree_cons (NULL_TREE, type,
+ tree_cons (NULL_TREE, ridpointers[(int) scspec],
+ NULL_TREE));
+ TREE_STATIC (type) = 1;
+ decl = start_decl (name, type, (init != NULL_TREE), NULL_TREE);
+ finish_decl (decl, init, NULL_TREE);
+ /* This prevents `unused variable' warnings when compiling with -Wall. */
+ TREE_USED (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ return decl;
+}
+
+tree
+objc_build_throw_stmt (tree throw_expr)
+{
+ tree func_params;
+
+ if (!flag_objc_exceptions)
+ fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
+
+ if (!throw_expr && objc_caught_exception)
+ throw_expr = TREE_VALUE (objc_caught_exception);
+
+ if (!throw_expr)
+ {
+ error ("`@throw;' (rethrow) used outside of a `@catch' block");
+ return error_mark_node;
+ }
+
+ func_params = tree_cons (NULL_TREE, throw_expr, NULL_TREE);
+
+ assemble_external (objc_exception_throw_decl);
+ return c_expand_expr_stmt (build_function_call (objc_exception_throw_decl,
+ func_params));
+}
+
+static void
+val_stack_push (struct val_stack **nc, long val)
+{
+ struct val_stack *new_elem = xmalloc (sizeof (struct val_stack));
+ new_elem->val = val;
+ new_elem->next = *nc;
+ *nc = new_elem;
+}
+
+static void
+val_stack_pop (struct val_stack **nc)
+{
+ struct val_stack *old_elem = *nc;
+ *nc = old_elem->next;
+ free (old_elem);
+}
+
+static void
+objc_build_try_enter_fragment (void)
+{
+ /* objc_exception_try_enter(&_stackExceptionData);
+ if (!_setjmp(&_stackExceptionData.buf)) { */
+
+ tree func_params, if_stmt, cond;
+
+ func_params
+ = tree_cons (NULL_TREE,
+ build_unary_op (ADDR_EXPR,
+ TREE_VALUE (objc_stack_exception_data),
+ 0),
+ NULL_TREE);
+
+ assemble_external (objc_exception_try_enter_decl);
+ c_expand_expr_stmt (build_function_call
+ (objc_exception_try_enter_decl, func_params));
+
+ if_stmt = c_begin_if_stmt ();
+ if_nesting_count++;
+ /* If <setjmp.h> has been included, the _setjmp prototype has
+ acquired a real, breathing type for its parameter. Cast our
+ argument to that type. */
+ func_params
+ = tree_cons (NULL_TREE,
+ build_c_cast (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))
+ ? TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
+ : ptr_type_node,
+ build_unary_op
+ (ADDR_EXPR,
+ build_component_ref (TREE_VALUE (objc_stack_exception_data),
+ get_identifier ("buf")), 0)),
+ NULL_TREE);
+ assemble_external (objc_setjmp_decl);
+ cond = build_unary_op (TRUTH_NOT_EXPR,
+ build_function_call (objc_setjmp_decl, func_params),
+ 0);
+ c_expand_start_cond (c_common_truthvalue_conversion (cond),
+ 0, if_stmt);
+ objc_enter_block ();
+}
+
+static tree
+objc_build_extract_expr (void)
+{
+ /* ... = objc_exception_extract(&_stackExceptionData); */
+
+ tree func_params
+ = tree_cons (NULL_TREE,
+ build_unary_op (ADDR_EXPR,
+ TREE_VALUE (objc_stack_exception_data), 0),
+ NULL_TREE);
+
+ assemble_external (objc_exception_extract_decl);
+ return build_function_call (objc_exception_extract_decl, func_params);
+}
+
+static void
+objc_build_try_exit_fragment (void)
+{
+ /* objc_exception_try_exit(&_stackExceptionData); */
+
+ tree func_params
+ = tree_cons (NULL_TREE,
+ build_unary_op (ADDR_EXPR,
+ TREE_VALUE (objc_stack_exception_data), 0),
+ NULL_TREE);
+
+ assemble_external (objc_exception_try_exit_decl);
+ c_expand_expr_stmt (build_function_call (objc_exception_try_exit_decl,
+ func_params));
+}
+
+static void
+objc_build_extract_fragment (void)
+{
+ /* } else {
+ _rethrowException = objc_exception_extract(&_stackExceptionData);
+ } */
+
+ objc_exit_block ();
+ c_finish_then ();
+
+ c_expand_start_else ();
+ objc_enter_block ();
+ c_expand_expr_stmt (build_modify_expr
+ (TREE_VALUE (objc_rethrow_exception),
+ NOP_EXPR,
+ objc_build_extract_expr ()));
+ objc_exit_block ();
+ c_finish_else ();
+ c_expand_end_cond ();
+ if_nesting_count--;
+}
+
+tree
+objc_build_try_prologue (void)
+{
+ /* { // new scope
+ struct _objc_exception_data _stackExceptionData;
+ volatile id _rethrowException = nil;
+ { // begin TRY-CATCH scope
+ objc_exception_try_enter(&_stackExceptionData);
+ if (!_setjmp(&_stackExceptionData.buf)) { */
+
+ tree try_catch_block;
+
+ if (!flag_objc_exceptions)
+ fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
+
+ objc_mark_locals_volatile ((void *)(exc_binding_stack
+ ? exc_binding_stack->val
+ : 0));
+ objc_enter_block ();
+ objc_stack_exception_data
+ = tree_cons (NULL_TREE,
+ objc_declare_variable (RID_AUTO,
+ get_identifier (UTAG_EXCDATA_VAR),
+ xref_tag (RECORD_TYPE,
+ get_identifier (UTAG_EXCDATA)),
+ NULL_TREE),
+ objc_stack_exception_data);
+ objc_rethrow_exception = tree_cons (NULL_TREE,
+ objc_declare_variable (RID_VOLATILE,
+ get_identifier (UTAG_RETHROWEXC_VAR),
+ id_type,
+ build_int_2 (0, 0)),
+ objc_rethrow_exception);
+
+ try_catch_block = objc_enter_block ();
+ val_stack_push (&exc_binding_stack, (long) get_current_scope ());
+ objc_build_try_enter_fragment ();
+
+ return try_catch_block;
+}
+
+void
+objc_build_try_epilogue (int also_catch_prologue)
+{
+ if (also_catch_prologue)
+ {
+ /* } else {
+ register id _caughtException = objc_exception_extract( &_stackExceptionData);
+ objc_exception_try_enter(&_stackExceptionData);
+ if(!_setjmp(&_stackExceptionData.buf)) {
+ if (0) { */
+
+ tree if_stmt;
+
+ objc_exit_block ();
+ c_finish_then ();
+
+ c_expand_start_else ();
+ objc_enter_block ();
+ objc_caught_exception
+ = tree_cons (NULL_TREE,
+ objc_declare_variable (RID_REGISTER,
+ get_identifier (UTAG_CAUGHTEXC_VAR),
+ id_type,
+ objc_build_extract_expr ()),
+ objc_caught_exception);
+ objc_build_try_enter_fragment ();
+ val_stack_push (&catch_count_stack, 1);
+ if_stmt = c_begin_if_stmt ();
+ if_nesting_count++;
+ c_expand_start_cond (c_common_truthvalue_conversion (boolean_false_node),
+ 0, if_stmt);
+ objc_enter_block ();
+
+ /* Start a new chain of @catch statements for this @try. */
+ objc_catch_type = tree_cons (objc_catch_type, NULL_TREE, NULL_TREE);
+ }
+ else
+ { /* !also_catch_prologue */
+
+ /* } else {
+ _rethrowException = objc_exception_extract( &_stackExceptionData);
+ }
+ } */
+ objc_build_extract_fragment ();
+ objc_exit_block ();
+ }
+}
+
+void
+objc_build_catch_stmt (tree catch_expr)
+{
+ /* } else if (objc_exception_match(objc_get_class("SomeClass"), _caughtException)) {
+ register SomeClass *e = _caughtException; */
+
+ tree if_stmt, cond, func_params, prev_catch, var_name, var_type;
+ int catch_id;
+
+#ifndef OBJCPLUS
+ /* Yet another C/C++ impedance mismatch. */
+ catch_expr = TREE_PURPOSE (catch_expr);
+#endif
+
+ var_name = TREE_VALUE (catch_expr);
+ var_type = TREE_VALUE (TREE_PURPOSE (catch_expr));
+ if (TREE_CODE (var_name) == INDIRECT_REF)
+ var_name = TREE_OPERAND (var_name, 0);
+ if (TREE_CODE (var_type) == TYPE_DECL
+ || TREE_CODE (var_type) == POINTER_TYPE)
+ var_type = TREE_TYPE (var_type);
+ catch_id = (var_type == TREE_TYPE (id_type));
+
+ if (!flag_objc_exceptions)
+ fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
+
+ if (!(catch_id || TYPED_OBJECT (var_type)))
+ fatal_error ("`@catch' parameter is not a known Objective-C class type");
+
+ /* Examine previous @catch clauses for the current @try block for
+ superclasses of the 'var_type' class. */
+ for (prev_catch = objc_catch_type; TREE_VALUE (prev_catch);
+ prev_catch = TREE_CHAIN (prev_catch))
+ {
+ if (TREE_VALUE (prev_catch) == TREE_TYPE (id_type))
+ {
+ warning ("Exception already handled by preceding `@catch(id)'");
+ break;
+ }
+ else if (!catch_id
+ && objc_comptypes (TREE_VALUE (prev_catch), var_type, 0) == 1)
+ warning ("Exception of type `%s *' already handled by `@catch (%s *)'",
+ IDENTIFIER_POINTER (OBJC_TYPE_NAME (var_type)),
+ IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_VALUE (prev_catch))));
+ }
+
+ objc_catch_type = tree_cons (NULL_TREE, var_type, objc_catch_type);
+
+ objc_exit_block ();
+ c_finish_then ();
+
+ c_expand_start_else ();
+ catch_count_stack->val++;
+ if_stmt = c_begin_if_stmt ();
+ if_nesting_count++;
+
+ if (catch_id)
+ cond = integer_one_node;
+ else
+ {
+ cond = get_class_reference (OBJC_TYPE_NAME (var_type));
+
+ func_params
+ = tree_cons (NULL_TREE, cond,
+ tree_cons (NULL_TREE,
+ TREE_VALUE (objc_caught_exception),
+ NULL_TREE));
+ assemble_external (objc_exception_match_decl);
+ cond = build_function_call (objc_exception_match_decl, func_params);
+ }
+
+ c_expand_start_cond (c_common_truthvalue_conversion (cond),
+ 0, if_stmt);
+ objc_enter_block ();
+ objc_declare_variable (RID_REGISTER, var_name,
+ build_pointer_type (var_type),
+ TREE_VALUE (objc_caught_exception));
+}
+
+void
+objc_build_catch_epilogue (void)
+{
+ /* } else {
+ _rethrowException = _caughtException;
+ objc_exception_try_exit(&_stackExceptionData);
+ }
+ } else {
+ _rethrowException = objc_exception_extract(&_stackExceptionData);
+ }
+ }
+ } // end TRY-CATCH scope
+ */
+
+ objc_exit_block ();
+ c_finish_then ();
+
+ c_expand_start_else ();
+ objc_enter_block ();
+ c_expand_expr_stmt
+ (build_modify_expr
+ (TREE_VALUE (objc_rethrow_exception),
+ NOP_EXPR,
+ TREE_VALUE (objc_caught_exception)));
+ objc_build_try_exit_fragment ();
+ objc_exit_block ();
+ while (catch_count_stack->val--)
+ {
+ c_finish_else (); /* close off all the nested ifs ! */
+ c_expand_end_cond ();
+ if_nesting_count--;
+ }
+ val_stack_pop (&catch_count_stack);
+ objc_caught_exception = TREE_CHAIN (objc_caught_exception);
+
+ objc_build_extract_fragment ();
+
+ objc_exit_block ();
+ c_finish_else ();
+ c_expand_end_cond ();
+ if_nesting_count--;
+ objc_exit_block ();
+
+ /* Return to enclosing chain of @catch statements (if any). */
+ while (TREE_VALUE (objc_catch_type))
+ objc_catch_type = TREE_CHAIN (objc_catch_type);
+ objc_catch_type = TREE_PURPOSE (objc_catch_type);
+}
+
+tree
+objc_build_finally_prologue (void)
+{
+ /* { // begin FINALLY scope
+ if (!_rethrowException) {
+ objc_exception_try_exit(&_stackExceptionData);
+ } */
+
+ tree blk = objc_enter_block ();
+
+ tree if_stmt = c_begin_if_stmt ();
+ if_nesting_count++;
+
+ c_expand_start_cond (c_common_truthvalue_conversion
+ (build_unary_op
+ (TRUTH_NOT_EXPR,
+ TREE_VALUE (objc_rethrow_exception), 0)),
+ 0, if_stmt);
+ objc_enter_block ();
+ objc_build_try_exit_fragment ();
+ objc_exit_block ();
+ c_finish_then ();
+ c_expand_end_cond ();
+ if_nesting_count--;
+
+ return blk;
+}
+
+tree
+objc_build_finally_epilogue (void)
+{
+ /* if (_rethrowException) {
+ objc_exception_throw(_rethrowException);
+ }
+ } // end FINALLY scope
+ } */
+
+ tree if_stmt = c_begin_if_stmt ();
+ if_nesting_count++;
+
+ c_expand_start_cond
+ (c_common_truthvalue_conversion (TREE_VALUE (objc_rethrow_exception)),
+ 0, if_stmt);
+ objc_enter_block ();
+ objc_build_throw_stmt (TREE_VALUE (objc_rethrow_exception));
+ objc_exit_block ();
+ c_finish_then ();
+ c_expand_end_cond ();
+ if_nesting_count--;
+
+ objc_exit_block ();
+ objc_rethrow_exception = TREE_CHAIN (objc_rethrow_exception);
+ objc_stack_exception_data = TREE_CHAIN (objc_stack_exception_data);
+
+ val_stack_pop (&exc_binding_stack);
+ return objc_exit_block ();
+}
+
+tree
+objc_build_try_catch_finally_stmt (int has_catch, int has_finally)
+{
+ /* NB: The operative assumption here is that TRY_FINALLY_EXPR will
+ deal with all exits from 'try_catch_blk' and route them through
+ 'finally_blk'. */
+ tree outer_blk = objc_build_finally_epilogue ();
+ tree prec_stmt = TREE_CHAIN (TREE_CHAIN (COMPOUND_BODY (outer_blk)));
+ tree try_catch_blk = TREE_CHAIN (prec_stmt), try_catch_expr;
+ tree finally_blk = TREE_CHAIN (try_catch_blk), finally_expr;
+ tree succ_stmt = TREE_CHAIN (finally_blk);
+ tree try_finally_stmt, try_finally_expr;
+
+ if (!flag_objc_exceptions)
+ fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
+
+ /* It is an error to have a @try block without a @catch and/or @finally
+ (even though sensible code can be generated nonetheless). */
+
+ if (!has_catch && !has_finally)
+ error ("`@try' without `@catch' or `@finally'");
+
+ /* We shall now do something truly disgusting. We shall remove the
+ 'try_catch_blk' and 'finally_blk' from the 'outer_blk' statement
+ chain, and replace them with a TRY_FINALLY_EXPR statement! If
+ this doesn't work, we will have to learn (from Per/gcj) how to
+ construct the 'outer_blk' lazily. */
+
+ TREE_CHAIN (try_catch_blk) = TREE_CHAIN (finally_blk) = NULL_TREE;
+ try_catch_expr = build1 (STMT_EXPR, void_type_node, try_catch_blk);
+ TREE_SIDE_EFFECTS (try_catch_expr) = 1;
+ finally_expr = build1 (STMT_EXPR, void_type_node, finally_blk);
+ TREE_SIDE_EFFECTS (finally_expr) = 1;
+ try_finally_expr = build (TRY_FINALLY_EXPR, void_type_node, try_catch_expr,
+ finally_expr);
+ TREE_SIDE_EFFECTS (try_finally_expr) = 1;
+ try_finally_stmt = build_stmt (EXPR_STMT, try_finally_expr);
+ TREE_CHAIN (prec_stmt) = try_finally_stmt;
+ TREE_CHAIN (try_finally_stmt) = succ_stmt;
+
+ return outer_blk; /* the whole enchilada */
+}
+
+void
+objc_build_synchronized_prologue (tree sync_expr)
+{
+ /* {
+ id _eval_once = <sync_expr>;
+ @try {
+ objc_sync_enter( _eval_once ); */
+
+ tree func_params;
+
+ if (!flag_objc_exceptions)
+ fatal_error ("Use `-fobjc-exceptions' to enable Objective-C exception syntax");
+
+ objc_enter_block ();
+ objc_eval_once
+ = tree_cons (NULL_TREE,
+ objc_declare_variable (RID_AUTO,
+ get_identifier (UTAG_EVALONCE_VAR),
+ id_type,
+ sync_expr),
+ objc_eval_once);
+ objc_build_try_prologue ();
+ objc_enter_block ();
+ func_params = tree_cons (NULL_TREE,
+ TREE_VALUE (objc_eval_once),
+ NULL_TREE);
+
+ assemble_external (objc_sync_enter_decl);
+ c_expand_expr_stmt (build_function_call
+ (objc_sync_enter_decl, func_params));
+}
+
+tree
+objc_build_synchronized_epilogue (void)
+{
+ /* }
+ @finally {
+ objc_sync_exit( _eval_once );
+ }
+ } */
+
+ tree func_params;
+
+ objc_exit_block ();
+ objc_build_try_epilogue (0);
+ objc_build_finally_prologue ();
+ func_params = tree_cons (NULL_TREE, TREE_VALUE (objc_eval_once),
+ NULL_TREE);
+
+ assemble_external (objc_sync_exit_decl);
+ c_expand_expr_stmt (build_function_call (objc_sync_exit_decl,
+ func_params));
+ objc_build_try_catch_finally_stmt (0, 1);
+
+ return objc_exit_block ();
+}
+
+/* Predefine the following data type:
+
+ struct _objc_exception_data
+ {
+ int buf[_JBLEN];
+ void *pointers[4];
+ }; */
+
+/* The following yuckiness should prevent users from having to #include
+ <setjmp.h> in their code... */
+
+#ifdef TARGET_POWERPC
+/* snarfed from /usr/include/ppc/setjmp.h */
+#define _JBLEN (26 + 36 + 129 + 1)
+#else
+/* snarfed from /usr/include/i386/{setjmp,signal}.h */
+#define _JBLEN 18
+#endif
+
+static void
+build_objc_exception_stuff (void)
+{
+ tree field_decl, field_decl_chain, index, temp_type;
+
+ /* Suppress outputting debug symbols, because
+ dbxout_init hasn't been called yet. */
+ enum debug_info_type save_write_symbols = write_symbols;
+ const struct gcc_debug_hooks *save_hooks = debug_hooks;
+
+ write_symbols = NO_DEBUG;
+ debug_hooks = &do_nothing_debug_hooks;
+ objc_exception_data_template
+ = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
+
+ /* int buf[_JBLEN]; */
+
+ index = build_index_type (build_int_2 (_JBLEN - 1, 0));
+ field_decl = create_builtin_decl (FIELD_DECL,
+ build_array_type (integer_type_node, index),
+ "buf");
+ field_decl_chain = field_decl;
+
+ /* void *pointers[4]; */
+
+ index = build_index_type (build_int_2 (4 - 1, 0));
+ field_decl = create_builtin_decl (FIELD_DECL,
+ build_array_type (ptr_type_node, index),
+ "pointers");
+ chainon (field_decl_chain, field_decl);
+
+ finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
+
+ /* int _setjmp(...); */
+ /* If the user includes <setjmp.h>, this shall be superceded by
+ 'int _setjmp(jmp_buf);' */
+ temp_type = build_function_type (integer_type_node, NULL_TREE);
+ objc_setjmp_decl
+ = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+
+ /* id objc_exception_extract(struct _objc_exception_data *); */
+ temp_type
+ = build_function_type (id_type,
+ tree_cons (NULL_TREE,
+ build_pointer_type (objc_exception_data_template),
+ OBJC_VOID_AT_END));
+ objc_exception_extract_decl
+ = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ /* void objc_exception_try_enter(struct _objc_exception_data *); */
+ /* void objc_exception_try_exit(struct _objc_exception_data *); */
+ temp_type
+ = build_function_type (void_type_node,
+ tree_cons (NULL_TREE,
+ build_pointer_type (objc_exception_data_template),
+ OBJC_VOID_AT_END));
+ objc_exception_try_enter_decl
+ = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ objc_exception_try_exit_decl
+ = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ /* void objc_exception_throw(id) __attribute__((noreturn)); */
+ /* void objc_sync_enter(id); */
+ /* void objc_sync_exit(id); */
+ temp_type = build_function_type (void_type_node,
+ tree_cons (NULL_TREE, id_type,
+ OBJC_VOID_AT_END));
+ objc_exception_throw_decl
+ = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ DECL_ATTRIBUTES (objc_exception_throw_decl)
+ = tree_cons (get_identifier ("noreturn"), NULL_TREE, NULL_TREE);
+ objc_sync_enter_decl
+ = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ objc_sync_exit_decl
+ = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ /* int objc_exception_match(id, id); */
+ temp_type = build_function_type (integer_type_node,
+ tree_cons (NULL_TREE, id_type,
+ tree_cons (NULL_TREE, id_type,
+ OBJC_VOID_AT_END)));
+ objc_exception_match_decl
+ = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+
+ write_symbols = save_write_symbols;
+ debug_hooks = save_hooks;
+}
+
/* struct <classname> {
struct objc_class *isa;
...
}; */
static tree
-build_private_template (class)
- tree class;
+build_private_template (tree class)
{
tree ivar_context;
@@ -2517,8 +3405,7 @@ build_private_template (class)
else
{
uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
-
- ivar_context = get_class_ivars (class);
+ ivar_context = get_class_ivars (class, 0);
finish_struct (uprivate_record, ivar_context, NULL_TREE);
@@ -2547,7 +3434,7 @@ build_private_template (class)
}; */
static tree
-build_protocol_template ()
+build_protocol_template (void)
{
tree decl_specs, field_decl, field_decl_chain;
tree template;
@@ -2559,8 +3446,7 @@ build_protocol_template ()
decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
get_identifier (UTAG_CLASS)));
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
/* char *protocol_name; */
@@ -2568,8 +3454,7 @@ build_protocol_template ()
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* struct objc_protocol **protocol_list; */
@@ -2578,8 +3463,7 @@ build_protocol_template ()
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* struct objc_method_list *instance_methods; */
@@ -2590,8 +3474,7 @@ build_protocol_template ()
get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* struct objc_method_list *class_methods; */
@@ -2602,17 +3485,14 @@ build_protocol_template ()
get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
return finish_struct (template, field_decl_chain, NULL_TREE);
}
static tree
-build_descriptor_table_initializer (type, entries)
- tree type;
- tree entries;
+build_descriptor_table_initializer (tree type, tree entries)
{
tree initlist = NULL_TREE;
@@ -2631,27 +3511,27 @@ build_descriptor_table_initializer (type, entries)
initlist
= tree_cons (NULL_TREE,
- build_constructor (type, nreverse (eltlist)), initlist);
+ objc_build_constructor (type, nreverse (eltlist)),
+ initlist);
entries = TREE_CHAIN (entries);
}
while (entries);
- return build_constructor (build_array_type (type, 0), nreverse (initlist));
+ return objc_build_constructor (build_array_type (type, 0),
+ nreverse (initlist));
}
/* struct objc_method_prototype_list {
int count;
struct objc_method_prototype {
- SEL name;
- char *types;
+ SEL name;
+ char *types;
} list[1];
}; */
static tree
-build_method_prototype_list_template (list_type, size)
- tree list_type;
- int size;
+build_method_prototype_list_template (tree list_type, int size)
{
tree objc_ivar_list_record;
tree decl_specs, field_decl, field_decl_chain;
@@ -2664,9 +3544,7 @@ build_method_prototype_list_template (list_type, size)
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
field_decl = get_identifier ("method_count");
-
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
/* struct objc_method method_list[]; */
@@ -2674,9 +3552,7 @@ build_method_prototype_list_template (list_type, size)
decl_specs = build_tree_list (NULL_TREE, list_type);
field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
build_int_2 (size, 0));
-
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
@@ -2685,7 +3561,7 @@ build_method_prototype_list_template (list_type, size)
}
static tree
-build_method_prototype_template ()
+build_method_prototype_template (void)
{
tree proto_record;
tree decl_specs, field_decl, field_decl_chain;
@@ -2697,16 +3573,13 @@ build_method_prototype_template ()
decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE,
get_identifier (TAG_SELECTOR)), NULL_TREE);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
-
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
finish_struct (proto_record, field_decl_chain, NULL_TREE);
@@ -2714,118 +3587,97 @@ build_method_prototype_template ()
return proto_record;
}
-/* True if last call to forwarding_offset yielded a register offset. */
-static int offset_is_register;
+static tree
+objc_method_parm_type (tree type)
+{
+ type = groktypename (TREE_TYPE (type));
+ if (TREE_CODE (type) == TYPE_DECL)
+ type = TREE_TYPE (type);
+ return TYPE_MAIN_VARIANT (type);
+}
static int
-forwarding_offset (parm)
- tree parm;
+objc_encoded_type_size (tree type)
{
- int offset_in_bytes;
-
- if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM)
- {
- rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0);
-
- /* ??? Here we assume that the parm address is indexed
- off the frame pointer or arg pointer.
- If that is not true, we produce meaningless results,
- but do not crash. */
- if (GET_CODE (addr) == PLUS
- && GET_CODE (XEXP (addr, 1)) == CONST_INT)
- offset_in_bytes = INTVAL (XEXP (addr, 1));
- else
- offset_in_bytes = 0;
-
- offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET;
- offset_is_register = 0;
- }
- else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG)
- {
- int regno = REGNO (DECL_INCOMING_RTL (parm));
- offset_in_bytes = apply_args_register_offset (regno);
- offset_is_register = 1;
- }
- else
- return 0;
-
- /* This is the case where the parm is passed as an int or double
- and it is converted to a char, short or float and stored back
- in the parmlist. In this case, describe the parm
- with the variable's declared type, and adjust the address
- if the least significant bytes (which we are using) are not
- the first ones. */
- if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm))
- offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)))
- - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm))));
+ int sz = int_size_in_bytes (type);
- return offset_in_bytes;
+ /* Make all integer and enum types at least as large
+ as an int. */
+ if (sz > 0 && (TREE_CODE (type) == INTEGER_TYPE
+ || TREE_CODE (type) == BOOLEAN_TYPE
+ || TREE_CODE (type) == ENUMERAL_TYPE))
+ sz = MAX (sz, int_size_in_bytes (integer_type_node));
+ /* Treat arrays as pointers, since that's how they're
+ passed in. */
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ sz = int_size_in_bytes (ptr_type_node);
+ return sz;
}
static tree
-encode_method_prototype (method_decl, func_decl)
- tree method_decl;
- tree func_decl;
+encode_method_prototype (tree method_decl)
{
tree parms;
- int stack_size, i;
- tree user_args;
- HOST_WIDE_INT max_parm_end = 0;
+ int parm_offset, i;
char buf[40];
tree result;
/* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
- /* C type. */
- encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
+ /* Encode return type. */
+ encode_type (objc_method_parm_type (method_decl),
obstack_object_size (&util_obstack),
OBJC_ENCODE_INLINE_DEFS);
/* Stack size. */
- for (parms = DECL_ARGUMENTS (func_decl); parms;
+ /* The first two arguments (self and _cmd) are pointers; account for
+ their size. */
+ i = int_size_in_bytes (ptr_type_node);
+ parm_offset = 2 * i;
+ for (parms = METHOD_SEL_ARGS (method_decl); parms;
parms = TREE_CHAIN (parms))
{
- HOST_WIDE_INT parm_end = (forwarding_offset (parms)
- + int_size_in_bytes (TREE_TYPE (parms)));
+ tree type = objc_method_parm_type (parms);
+ int sz = objc_encoded_type_size (type);
- if (!offset_is_register && max_parm_end < parm_end)
- max_parm_end = parm_end;
+ /* If a type size is not known, bail out. */
+ if (sz < 0)
+ {
+ error ("%Jtype '%D' does not have a known size",
+ type, type);
+ /* Pretend that the encoding succeeded; the compilation will
+ fail nevertheless. */
+ goto finish_encoding;
+ }
+ parm_offset += sz;
}
- stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
-
- sprintf (buf, "%d", stack_size);
+ sprintf (buf, "%d@0:%d", parm_offset, i);
obstack_grow (&util_obstack, buf, strlen (buf));
- user_args = METHOD_SEL_ARGS (method_decl);
-
/* Argument types. */
- for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms;
- parms = TREE_CHAIN (parms), i++)
+ parm_offset = 2 * i;
+ for (parms = METHOD_SEL_ARGS (method_decl); parms;
+ parms = TREE_CHAIN (parms))
{
+ tree type = objc_method_parm_type (parms);
+
/* Process argument qualifiers for user supplied arguments. */
- if (i > 1)
- {
- encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args)));
- user_args = TREE_CHAIN (user_args);
- }
+ encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
/* Type. */
- encode_type (TREE_TYPE (parms),
- obstack_object_size (&util_obstack),
+ encode_type (type, obstack_object_size (&util_obstack),
OBJC_ENCODE_INLINE_DEFS);
/* Compute offset. */
- sprintf (buf, "%d", forwarding_offset (parms));
+ sprintf (buf, "%d", parm_offset);
+ parm_offset += objc_encoded_type_size (type);
- /* Indicate register. */
- if (offset_is_register)
- obstack_1grow (&util_obstack, '+');
-
obstack_grow (&util_obstack, buf, strlen (buf));
}
+ finish_encoding:
obstack_1grow (&util_obstack, '\0');
result = get_identifier (obstack_finish (&util_obstack));
obstack_free (&util_obstack, util_firstobj);
@@ -2833,12 +3685,8 @@ encode_method_prototype (method_decl, func_decl)
}
static tree
-generate_descriptor_table (type, name, size, list, proto)
- tree type;
- const char *name;
- int size;
- tree list;
- tree proto;
+generate_descriptor_table (tree type, const char *name, int size, tree list,
+ tree proto)
{
tree sc_spec, decl_specs, decl, initlist;
@@ -2852,15 +3700,14 @@ generate_descriptor_table (type, name, size, list, proto)
initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0));
initlist = tree_cons (NULL_TREE, list, initlist);
- finish_decl (decl, build_constructor (type, nreverse (initlist)),
+ finish_decl (decl, objc_build_constructor (type, nreverse (initlist)),
NULL_TREE);
return decl;
}
static void
-generate_method_descriptors (protocol)
- tree protocol;
+generate_method_descriptors (tree protocol)
{
tree initlist, chain, method_list_template;
tree cast, variable_length_type;
@@ -2883,7 +3730,7 @@ generate_method_descriptors (protocol)
= build_method_prototype_list_template (objc_method_prototype_template,
size);
- initlist
+ initlist
= build_descriptor_table_initializer (objc_method_prototype_template,
chain);
@@ -2918,104 +3765,8 @@ generate_method_descriptors (protocol)
UOBJC_INSTANCE_METHODS_decl = 0;
}
-/* Generate a temporary FUNCTION_DECL node to be used in
- hack_method_prototype below. */
-
-static tree
-build_tmp_function_decl ()
-{
- tree decl_specs, expr_decl, parms;
- static int xxx = 0;
- char buffer[80];
-
- /* struct objc_object *objc_xxx (id, SEL, ...); */
- pushlevel (0);
- decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
- push_parm_decl (build_tree_list
- (build_tree_list (decl_specs,
- build1 (INDIRECT_REF, NULL_TREE,
- NULL_TREE)),
- NULL_TREE));
-
- decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE,
- get_identifier (TAG_SELECTOR)));
- expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE);
-
- push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl),
- NULL_TREE));
- parms = get_parm_info (0);
- poplevel (0, 0, 0);
-
- decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
- sprintf (buffer, "__objc_tmp_%x", xxx++);
- expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE);
- expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl);
-
- return define_decl (expr_decl, decl_specs);
-}
-
-/* Generate the prototypes for protocol methods. This is used to
- generate method encodings for these.
-
- NST_METHODS is the method to generate a _DECL node for TMP_DECL is
- a decl node to be used. This is also where the return value is
- given. */
-
-static void
-hack_method_prototype (nst_methods, tmp_decl)
- tree nst_methods;
- tree tmp_decl;
-{
- tree parms;
- tree parm;
-
- /* Hack to avoid problem with static typing of self arg. */
- TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL);
- start_method_def (nst_methods);
- TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL);
-
- if (METHOD_ADD_ARGS (nst_methods) == objc_ellipsis_node)
- parms = get_parm_info (0); /* we have a `, ...' */
- else
- parms = get_parm_info (1); /* place a `void_at_end' */
-
- poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
-
- /* Usually called from store_parm_decls -> init_function_start. */
-
- DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms);
-
- if (current_function_decl)
- abort ();
- current_function_decl = tmp_decl;
-
- {
- /* Code taken from start_function. */
- tree restype = TREE_TYPE (TREE_TYPE (tmp_decl));
- /* Promote the value to int before returning it. */
- if (TREE_CODE (restype) == INTEGER_TYPE
- && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
- restype = integer_type_node;
- DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype);
- }
-
- for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm))
- DECL_CONTEXT (parm) = tmp_decl;
-
- init_function_start (tmp_decl, "objc-act", 0);
-
- /* Typically called from expand_function_start for function definitions. */
- assign_parms (tmp_decl);
-
- /* install return type */
- TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods));
-
- current_function_decl = NULL;
-}
-
static void
-generate_protocol_references (plist)
- tree plist;
+generate_protocol_references (tree plist)
{
tree lproto;
@@ -3047,10 +3798,10 @@ generate_protocol_references (plist)
@protocol() or from a class/category implementation). These
statically allocated objects can be referred to via the static
(that is, private to this module) symbols _OBJC_PROTOCOL_n.
-
+
The statically allocated Protocol objects that we generate here
need to be fixed up at runtime in order to be used: the 'isa'
- pointer of the objects need to be set up to point to the 'Protocol'
+ pointer of the objects need to be set up to point to the 'Protocol'
class, as known at runtime.
The NeXT runtime fixes up all protocols at program startup time,
@@ -3073,16 +3824,15 @@ generate_protocol_references (plist)
being referenced multiple times when compiled with the GNU runtime,
and end up being fixed up multiple times at runtime inizialization.
But that doesn't hurt, it's just a little inefficient. */
+
static void
-generate_protocols ()
+generate_protocols (void)
{
- tree p, tmp_decl, encoding;
+ tree p, encoding;
tree sc_spec, decl_specs, decl;
tree initlist, protocol_name_expr, refs_decl, refs_expr;
tree cast_type2;
- tmp_decl = build_tmp_function_decl ();
-
if (! objc_protocol_template)
objc_protocol_template = build_protocol_template ();
@@ -3107,8 +3857,7 @@ generate_protocols ()
{
if (! METHOD_ENCODING (nst_methods))
{
- hack_method_prototype (nst_methods, tmp_decl);
- encoding = encode_method_prototype (nst_methods, tmp_decl);
+ encoding = encode_method_prototype (nst_methods);
METHOD_ENCODING (nst_methods) = encoding;
}
nst_methods = TREE_CHAIN (nst_methods);
@@ -3118,8 +3867,7 @@ generate_protocols ()
{
if (! METHOD_ENCODING (cls_methods))
{
- hack_method_prototype (cls_methods, tmp_decl);
- encoding = encode_method_prototype (cls_methods, tmp_decl);
+ encoding = encode_method_prototype (cls_methods);
METHOD_ENCODING (cls_methods) = encoding;
}
@@ -3175,13 +3923,9 @@ generate_protocols ()
}
static tree
-build_protocol_initializer (type, protocol_name, protocol_list,
- instance_methods, class_methods)
- tree type;
- tree protocol_name;
- tree protocol_list;
- tree instance_methods;
- tree class_methods;
+build_protocol_initializer (tree type, tree protocol_name,
+ tree protocol_list, tree instance_methods,
+ tree class_methods)
{
tree initlist = NULL_TREE, expr;
tree cast_type;
@@ -3218,7 +3962,7 @@ build_protocol_initializer (type, protocol_name, protocol_list,
initlist = tree_cons (NULL_TREE, expr, initlist);
}
- return build_constructor (type, nreverse (initlist));
+ return objc_build_constructor (type, nreverse (initlist));
}
/* struct objc_category {
@@ -3230,7 +3974,7 @@ build_protocol_initializer (type, protocol_name, protocol_list,
}; */
static void
-build_category_template ()
+build_category_template (void)
{
tree decl_specs, field_decl, field_decl_chain;
@@ -3241,16 +3985,14 @@ build_category_template ()
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
/* char *class_name; */
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* struct objc_method_list *instance_methods; */
@@ -3260,8 +4002,7 @@ build_category_template ()
get_identifier (UTAG_METHOD_LIST)));
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* struct objc_method_list *class_methods; */
@@ -3271,8 +4012,7 @@ build_category_template ()
get_identifier (UTAG_METHOD_LIST)));
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* struct objc_protocol **protocol_list; */
@@ -3283,8 +4023,7 @@ build_category_template ()
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
@@ -3296,28 +4035,26 @@ build_category_template ()
}; */
static void
-build_selector_template ()
+build_selector_template (void)
{
tree decl_specs, field_decl, field_decl_chain;
- objc_selector_template
+ objc_selector_template
= start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
/* void *sel_id; */
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
/* char *sel_type; */
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
@@ -3340,11 +4077,18 @@ build_selector_template ()
struct objc_class *sibling_class;
}
struct objc_protocol_list *protocols;
+ if (flag_next_runtime)
+ void *sel_id;
void *gc_object_type;
}; */
+/* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
+ the NeXT/Apple runtime; still, the compiler must generate them to
+ maintain backward binary compatibility (and to allow for future
+ expansion). */
+
static void
-build_class_template ()
+build_class_template (void)
{
tree decl_specs, field_decl, field_decl_chain;
@@ -3355,8 +4099,7 @@ build_class_template ()
decl_specs = build_tree_list (NULL_TREE, objc_class_template);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
/* struct objc_class *super_class; */
@@ -3364,40 +4107,35 @@ build_class_template ()
decl_specs = build_tree_list (NULL_TREE, objc_class_template);
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* char *name; */
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* long version; */
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
field_decl = get_identifier ("version");
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* long info; */
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
field_decl = get_identifier ("info");
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* long instance_size; */
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]);
field_decl = get_identifier ("instance_size");
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* struct objc_ivar_list *ivars; */
@@ -3406,8 +4144,7 @@ build_class_template ()
xref_tag (RECORD_TYPE,
get_identifier (UTAG_IVAR_LIST)));
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* struct objc_method_list *methods; */
@@ -3416,8 +4153,7 @@ build_class_template ()
xref_tag (RECORD_TYPE,
get_identifier (UTAG_METHOD_LIST)));
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
if (flag_next_runtime)
@@ -3428,8 +4164,7 @@ build_class_template ()
xref_tag (RECORD_TYPE,
get_identifier ("objc_cache")));
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache"));
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
}
else
@@ -3440,8 +4175,7 @@ build_class_template ()
xref_tag (RECORD_TYPE,
get_identifier ("sarray")));
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable"));
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* struct objc_class *subclass_list; */
@@ -3449,8 +4183,7 @@ build_class_template ()
decl_specs = build_tree_list (NULL_TREE, objc_class_template);
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list"));
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* struct objc_class *sibling_class; */
@@ -3458,38 +4191,38 @@ build_class_template ()
decl_specs = build_tree_list (NULL_TREE, objc_class_template);
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class"));
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
}
/* struct objc_protocol **protocol_list; */
- decl_specs = build_tree_list (NULL_TREE,
+ decl_specs = build_tree_list (NULL_TREE,
xref_tag (RECORD_TYPE,
get_identifier (UTAG_PROTOCOL)));
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list"));
field_decl
= build1 (INDIRECT_REF, NULL_TREE, field_decl);
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
- /* void *sel_id; */
+ if (flag_next_runtime)
+ {
+ /* void *sel_id; */
- decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
- field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
- chainon (field_decl_chain, field_decl);
+ decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
+ field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id"));
+ field_decl
+ = grokfield (field_decl, decl_specs, NULL_TREE);
+ chainon (field_decl_chain, field_decl);
+ }
/* void *gc_object_type; */
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type"));
- field_decl
- = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
@@ -3498,28 +4231,17 @@ build_class_template ()
/* Generate appropriate forward declarations for an implementation. */
static void
-synth_forward_declarations ()
+synth_forward_declarations (void)
{
- tree sc_spec, decl_specs, an_id;
-
- /* extern struct objc_class _OBJC_CLASS_<my_name>; */
-
- an_id = synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context);
-
- sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]);
- decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
- UOBJC_CLASS_decl = define_decl (an_id, decl_specs);
- TREE_USED (UOBJC_CLASS_decl) = 1;
- DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1;
-
- /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
+ tree an_id;
- an_id = synth_id_with_class_suffix ("_OBJC_METACLASS",
- objc_implementation_context);
+ /* static struct objc_class _OBJC_CLASS_<my_name>; */
+ UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
+ objc_class_template);
- UOBJC_METACLASS_decl = define_decl (an_id, decl_specs);
- TREE_USED (UOBJC_METACLASS_decl) = 1;
- DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1;
+ /* static struct objc_class _OBJC_METACLASS_<my_name>; */
+ UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
+ objc_class_template);
/* Pre-build the following entities - for speed/convenience. */
@@ -3529,26 +4251,15 @@ synth_forward_declarations ()
}
static void
-error_with_ivar (message, decl, rawdecl)
- const char *message;
- tree decl;
- tree rawdecl;
+error_with_ivar (const char *message, tree decl, tree rawdecl)
{
- diagnostic_count_diagnostic (global_dc, DK_ERROR);
-
- diagnostic_report_current_function (global_dc);
-
- error_with_file_and_line (DECL_SOURCE_FILE (decl),
- DECL_SOURCE_LINE (decl),
- "%s `%s'",
- message, gen_declaration (rawdecl, errbuf));
+ error ("%J%s `%s'", decl,
+ message, gen_declaration (rawdecl, errbuf));
}
static void
-check_ivars (inter, imp)
- tree inter;
- tree imp;
+check_ivars (tree inter, tree imp)
{
tree intdecls = CLASS_IVARS (inter);
tree impdecls = CLASS_IVARS (imp);
@@ -3559,6 +4270,10 @@ check_ivars (inter, imp)
{
tree t1, t2;
+#ifdef OBJCPLUS
+ if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
+ intdecls = TREE_CHAIN (intdecls);
+#endif
if (intdecls == 0 && impdecls == 0)
break;
if (intdecls == 0 || impdecls == 0)
@@ -3569,7 +4284,9 @@ check_ivars (inter, imp)
t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
- if (!comptypes (t1, t2))
+ if (!comptypes (t1, t2, false)
+ || !tree_int_cst_equal (TREE_VALUE (TREE_VALUE (rawintdecls)),
+ TREE_VALUE (TREE_VALUE (rawimpdecls))))
{
if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
{
@@ -3600,24 +4317,30 @@ check_ivars (inter, imp)
}
}
-/* Set super_type to the data type node for struct objc_super *,
- first defining struct objc_super itself.
+/* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
This needs to be done just once per compilation. */
-static tree
-build_super_template ()
+static void
+build_super_template (void)
{
- tree record, decl_specs, field_decl, field_decl_chain;
+ tree decl_specs, field_decl, field_decl_chain;
- record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
+ /* Suppress outputting debug symbols, because
+ dbxout_init hasn't been called yet. */
+ enum debug_info_type save_write_symbols = write_symbols;
+ const struct gcc_debug_hooks *save_hooks = debug_hooks;
+
+ write_symbols = NO_DEBUG;
+ debug_hooks = &do_nothing_debug_hooks;
+
+ objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
/* struct objc_object *self; */
decl_specs = build_tree_list (NULL_TREE, objc_object_reference);
field_decl = get_identifier ("self");
field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl);
- field_decl = grokfield (input_filename, lineno,
- field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
/* struct objc_class *class; */
@@ -3626,18 +4349,13 @@ build_super_template ()
decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs));
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class"));
- field_decl = grokfield (input_filename, lineno,
- field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
- finish_struct (record, field_decl_chain, NULL_TREE);
+ finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
- /* `struct objc_super *' */
- super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE,
- record),
- build1 (INDIRECT_REF,
- NULL_TREE, NULL_TREE)));
- return record;
+ write_symbols = save_write_symbols;
+ debug_hooks = save_hooks;
}
/* struct objc_ivar {
@@ -3647,7 +4365,7 @@ build_super_template ()
}; */
static tree
-build_ivar_template ()
+build_ivar_template (void)
{
tree objc_ivar_id, objc_ivar_record;
tree decl_specs, field_decl, field_decl_chain;
@@ -3660,8 +4378,7 @@ build_ivar_template ()
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name"));
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
/* char *ivar_type; */
@@ -3669,8 +4386,7 @@ build_ivar_template ()
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type"));
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* int ivar_offset; */
@@ -3678,8 +4394,7 @@ build_ivar_template ()
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
field_decl = get_identifier ("ivar_offset");
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
@@ -3693,9 +4408,7 @@ build_ivar_template ()
}; */
static tree
-build_ivar_list_template (list_type, size)
- tree list_type;
- int size;
+build_ivar_list_template (tree list_type, int size)
{
tree objc_ivar_list_record;
tree decl_specs, field_decl, field_decl_chain;
@@ -3707,8 +4420,7 @@ build_ivar_list_template (list_type, size)
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
field_decl = get_identifier ("ivar_count");
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
/* struct objc_ivar ivar_list[]; */
@@ -3717,8 +4429,7 @@ build_ivar_list_template (list_type, size)
field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"),
build_int_2 (size, 0));
- field_decl = grokfield (input_filename, lineno,
- field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
@@ -3733,9 +4444,7 @@ build_ivar_list_template (list_type, size)
}; */
static tree
-build_method_list_template (list_type, size)
- tree list_type;
- int size;
+build_method_list_template (tree list_type, int size)
{
tree objc_ivar_list_record;
tree decl_specs, field_decl, field_decl_chain;
@@ -3746,13 +4455,12 @@ build_method_list_template (list_type, size)
decl_specs
= build_tree_list
- (NULL_TREE,
+ (NULL_TREE,
xref_tag (RECORD_TYPE,
get_identifier (UTAG_METHOD_PROTOTYPE_LIST)));
field_decl
= build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next"));
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
/* int method_count; */
@@ -3760,8 +4468,7 @@ build_method_list_template (list_type, size)
decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]);
field_decl = get_identifier ("method_count");
- field_decl = grokfield (input_filename, lineno,
- field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* struct objc_method method_list[]; */
@@ -3770,8 +4477,7 @@ build_method_list_template (list_type, size)
field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"),
build_int_2 (size, 0));
- field_decl = grokfield (input_filename, lineno,
- field_decl, decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
@@ -3780,9 +4486,7 @@ build_method_list_template (list_type, size)
}
static tree
-build_ivar_list_initializer (type, field_decl)
- tree type;
- tree field_decl;
+build_ivar_list_initializer (tree type, tree field_decl)
{
tree initlist = NULL_TREE;
@@ -3817,23 +4521,21 @@ build_ivar_list_initializer (type, field_decl)
/* Set offset. */
ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
- initlist = tree_cons (NULL_TREE,
- build_constructor (type, nreverse (ivar)),
+ initlist = tree_cons (NULL_TREE,
+ objc_build_constructor (type, nreverse (ivar)),
initlist);
-
- field_decl = TREE_CHAIN (field_decl);
+ do
+ field_decl = TREE_CHAIN (field_decl);
+ while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
}
while (field_decl);
- return build_constructor (build_array_type (type, 0), nreverse (initlist));
+ return objc_build_constructor (build_array_type (type, 0),
+ nreverse (initlist));
}
static tree
-generate_ivars_list (type, name, size, list)
- tree type;
- const char *name;
- int size;
- tree list;
+generate_ivars_list (tree type, const char *name, int size, tree list)
{
tree sc_spec, decl_specs, decl, initlist;
@@ -3847,14 +4549,27 @@ generate_ivars_list (type, name, size, list)
initlist = tree_cons (NULL_TREE, list, initlist);
finish_decl (decl,
- build_constructor (TREE_TYPE (decl), nreverse (initlist)),
+ objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
NULL_TREE);
return decl;
}
+/* Count only the fields occurring in T. */
+static int
+ivar_list_length (tree t)
+{
+ int count = 0;
+
+ for (; t; t = TREE_CHAIN (t))
+ if (TREE_CODE (t) == FIELD_DECL)
+ ++count;
+
+ return count;
+}
+
static void
-generate_ivar_lists ()
+generate_ivar_lists (void)
{
tree initlist, ivar_list_template, chain;
tree cast, variable_length_type;
@@ -3878,7 +4593,7 @@ generate_ivar_lists ()
if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
&& (chain = TYPE_FIELDS (objc_class_template)))
{
- size = list_length (chain);
+ size = ivar_list_length (chain);
ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
initlist = build_ivar_list_initializer (objc_ivar_template, chain);
@@ -3894,7 +4609,7 @@ generate_ivar_lists ()
chain = CLASS_IVARS (implementation_template);
if (chain)
{
- size = list_length (chain);
+ size = ivar_list_length (chain);
ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
initlist = build_ivar_list_initializer (objc_ivar_template, chain);
@@ -3910,9 +4625,7 @@ generate_ivar_lists ()
}
static tree
-build_dispatch_table_initializer (type, entries)
- tree type;
- tree entries;
+build_dispatch_table_initializer (tree type, tree entries)
{
tree initlist = NULL_TREE;
@@ -3927,39 +4640,40 @@ build_dispatch_table_initializer (type, entries)
/* Generate the method encoding if we don't have one already. */
if (! METHOD_ENCODING (entries))
METHOD_ENCODING (entries) =
- encode_method_def (METHOD_DEFINITION (entries));
+ encode_method_prototype (entries);
elemlist = tree_cons (NULL_TREE,
add_objc_string (METHOD_ENCODING (entries),
meth_var_types),
elemlist);
- elemlist = tree_cons (NULL_TREE,
+ elemlist = tree_cons (NULL_TREE,
build_unary_op (ADDR_EXPR,
METHOD_DEFINITION (entries), 1),
elemlist);
- initlist = tree_cons (NULL_TREE,
- build_constructor (type, nreverse (elemlist)),
+ initlist = tree_cons (NULL_TREE,
+ objc_build_constructor (type, nreverse (elemlist)),
initlist);
entries = TREE_CHAIN (entries);
}
while (entries);
- return build_constructor (build_array_type (type, 0), nreverse (initlist));
+ return objc_build_constructor (build_array_type (type, 0),
+ nreverse (initlist));
}
/* To accomplish method prototyping without generating all kinds of
inane warnings, the definition of the dispatch table entries were
changed from:
- struct objc_method { SEL _cmd; ...; id (*_imp)(); };
+ struct objc_method { SEL _cmd; ...; id (*_imp)(); };
to:
- struct objc_method { SEL _cmd; ...; void *_imp; }; */
+ struct objc_method { SEL _cmd; ...; void *_imp; }; */
static tree
-build_method_template ()
+build_method_template (void)
{
tree _SLT_record;
tree decl_specs, field_decl, field_decl_chain;
@@ -3973,23 +4687,20 @@ build_method_template ()
NULL_TREE);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd"));
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
field_decl_chain = field_decl;
decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE);
field_decl = build1 (INDIRECT_REF, NULL_TREE,
get_identifier ("method_types"));
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
/* void *_imp; */
decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE);
field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp"));
- field_decl = grokfield (input_filename, lineno, field_decl,
- decl_specs, NULL_TREE);
+ field_decl = grokfield (field_decl, decl_specs, NULL_TREE);
chainon (field_decl_chain, field_decl);
finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
@@ -3999,11 +4710,7 @@ build_method_template ()
static tree
-generate_dispatch_table (type, name, size, list)
- tree type;
- const char *name;
- int size;
- tree list;
+generate_dispatch_table (tree type, const char *name, int size, tree list)
{
tree sc_spec, decl_specs, decl, initlist;
@@ -4018,14 +4725,38 @@ generate_dispatch_table (type, name, size, list)
initlist = tree_cons (NULL_TREE, list, initlist);
finish_decl (decl,
- build_constructor (TREE_TYPE (decl), nreverse (initlist)),
+ objc_build_constructor (TREE_TYPE (decl), nreverse (initlist)),
NULL_TREE);
return decl;
}
static void
-generate_dispatch_tables ()
+mark_referenced_methods (void)
+{
+ struct imp_entry *impent;
+ tree chain;
+
+ for (impent = imp_list; impent; impent = impent->next)
+ {
+ chain = CLASS_CLS_METHODS (impent->imp_context);
+ while (chain)
+ {
+ cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
+ chain = TREE_CHAIN (chain);
+ }
+
+ chain = CLASS_NST_METHODS (impent->imp_context);
+ while (chain)
+ {
+ cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
+ chain = TREE_CHAIN (chain);
+ }
+ }
+}
+
+static void
+generate_dispatch_tables (void)
{
tree initlist, chain, method_list_template;
tree cast, variable_length_type;
@@ -4093,8 +4824,7 @@ generate_dispatch_tables ()
}
static tree
-generate_protocol_list (i_or_p)
- tree i_or_p;
+generate_protocol_list (tree i_or_p)
{
tree initlist, decl_specs, sc_spec;
tree refs_decl, expr_decl, lproto, e, plist;
@@ -4172,22 +4902,17 @@ generate_protocol_list (i_or_p)
refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE);
DECL_CONTEXT (refs_decl) = NULL_TREE;
- finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl),
- nreverse (initlist)),
+ finish_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
+ nreverse (initlist)),
NULL_TREE);
return refs_decl;
}
static tree
-build_category_initializer (type, cat_name, class_name,
- instance_methods, class_methods, protocol_list)
- tree type;
- tree cat_name;
- tree class_name;
- tree instance_methods;
- tree class_methods;
- tree protocol_list;
+build_category_initializer (tree type, tree cat_name, tree class_name,
+ tree instance_methods, tree class_methods,
+ tree protocol_list)
{
tree initlist = NULL_TREE, expr;
@@ -4227,7 +4952,7 @@ build_category_initializer (type, cat_name, class_name,
initlist = tree_cons (NULL_TREE, expr, initlist);
}
- return build_constructor (type, nreverse (initlist));
+ return objc_build_constructor (type, nreverse (initlist));
}
/* struct objc_class {
@@ -4247,21 +4972,16 @@ build_category_initializer (type, cat_name, class_name,
struct objc_class *sibling_class;
}
struct objc_protocol_list *protocols;
+ if (flag_next_runtime)
+ void *sel_id;
void *gc_object_type;
}; */
static tree
-build_shared_structure_initializer (type, isa, super, name, size, status,
- dispatch_table, ivar_list, protocol_list)
- tree type;
- tree isa;
- tree super;
- tree name;
- tree size;
- int status;
- tree dispatch_table;
- tree ivar_list;
- tree protocol_list;
+build_shared_structure_initializer (tree type, tree isa, tree super,
+ tree name, tree size, int status,
+ tree dispatch_table, tree ivar_list,
+ tree protocol_list)
{
tree initlist = NULL_TREE, expr;
@@ -4335,17 +5055,32 @@ build_shared_structure_initializer (type, isa, super, name, size, status,
initlist = tree_cons (NULL_TREE, expr, initlist);
}
+ if (flag_next_runtime)
+ /* sel_id = NULL */
+ initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
+
/* gc_object_type = NULL */
initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist);
- return build_constructor (type, nreverse (initlist));
+ return objc_build_constructor (type, nreverse (initlist));
+}
+
+/* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
+
+static inline tree
+lookup_category (tree class, tree cat_name)
+{
+ tree category = CLASS_CATEGORY_LIST (class);
+
+ while (category && CLASS_SUPER_NAME (category) != cat_name)
+ category = CLASS_CATEGORY_LIST (category);
+ return category;
}
/* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
static void
-generate_category (cat)
- tree cat;
+generate_category (tree cat)
{
tree sc_spec, decl_specs, decl;
tree initlist, cat_name_expr, class_name_expr;
@@ -4356,15 +5091,8 @@ generate_category (cat)
class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
- category = CLASS_CATEGORY_LIST (implementation_template);
-
- /* find the category interface from the class it is associated with */
- while (category)
- {
- if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
- break;
- category = CLASS_CATEGORY_LIST (category);
- }
+ category = lookup_category (implementation_template,
+ CLASS_SUPER_NAME (cat));
if (category && CLASS_PROTOCOL_LIST (category))
{
@@ -4387,7 +5115,6 @@ generate_category (cat)
UOBJC_CLASS_METHODS_decl,
protocol_decl);
- TREE_USED (decl) = 1;
finish_decl (decl, initlist, NULL_TREE);
}
@@ -4395,7 +5122,7 @@ generate_category (cat)
static struct objc_class _OBJC_CLASS_Foo={ ... }; */
static void
-generate_shared_structures ()
+generate_shared_structures (void)
{
tree sc_spec, decl_specs, decl;
tree name_expr, super_expr, root_expr;
@@ -4498,9 +5225,7 @@ generate_shared_structures ()
}
static tree
-synth_id_with_class_suffix (preamble, ctxt)
- const char *preamble;
- tree ctxt;
+synth_id_with_class_suffix (const char *preamble, tree ctxt)
{
char *string;
if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
@@ -4535,13 +5260,12 @@ synth_id_with_class_suffix (preamble, ctxt)
}
else
abort ();
-
+
return get_identifier (string);
}
static int
-is_objc_type_qualifier (node)
- tree node;
+is_objc_type_qualifier (tree node)
{
return (TREE_CODE (node) == IDENTIFIER_NODE
&& (node == ridpointers [(int) RID_CONST]
@@ -4558,8 +5282,7 @@ is_objc_type_qualifier (node)
type of id (otherwise grokdeclarator will default to int). */
static tree
-adjust_type_for_id_default (type)
- tree type;
+adjust_type_for_id_default (tree type)
{
tree declspecs, chain;
@@ -4575,7 +5298,7 @@ adjust_type_for_id_default (type)
chain = TREE_CHAIN (chain))
{
if (TYPED_OBJECT (TREE_VALUE (chain))
- && !(TREE_VALUE (type)
+ && !(TREE_VALUE (type)
&& TREE_CODE (TREE_VALUE (type)) == INDIRECT_REF))
error ("can not use an object as parameter to a method\n");
if (!is_objc_type_qualifier (TREE_VALUE (chain)))
@@ -4588,28 +5311,25 @@ adjust_type_for_id_default (type)
}
/* Usage:
- keyworddecl:
- selector ':' '(' typename ')' identifier
-
+ keyworddecl:
+ selector ':' '(' typename ')' identifier
+
Purpose:
- Transform an Objective-C keyword argument into
- the C equivalent parameter declarator.
-
+ Transform an Objective-C keyword argument into
+ the C equivalent parameter declarator.
+
In: key_name, an "identifier_node" (optional).
- arg_type, a "tree_list" (optional).
- arg_name, an "identifier_node".
-
+ arg_type, a "tree_list" (optional).
+ arg_name, an "identifier_node".
+
Note: It would be really nice to strongly type the preceding
- arguments in the function prototype; however, then I
- could not use the "accessor" macros defined in "tree.h".
-
+ arguments in the function prototype; however, then I
+ could not use the "accessor" macros defined in "tree.h".
+
Out: an instance of "keyword_decl". */
tree
-build_keyword_decl (key_name, arg_type, arg_name)
- tree key_name;
- tree arg_type;
- tree arg_name;
+build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
{
tree keyword_decl;
@@ -4628,8 +5348,7 @@ build_keyword_decl (key_name, arg_type, arg_name)
/* Given a chain of keyword_decl's, synthesize the full keyword selector. */
static tree
-build_keyword_selector (selector)
- tree selector;
+build_keyword_selector (tree selector)
{
int len = 0;
tree key_chain, key_name;
@@ -4661,7 +5380,13 @@ build_keyword_selector (selector)
if (TREE_CODE (selector) == KEYWORD_DECL)
key_name = KEYWORD_KEY_NAME (key_chain);
else if (TREE_CODE (selector) == TREE_LIST)
- key_name = TREE_PURPOSE (key_chain);
+ {
+ key_name = TREE_PURPOSE (key_chain);
+ /* The keyword decl chain will later be used as a function argument
+ chain. Unhook the selector itself so as to not confuse other
+ parts of the compiler. */
+ TREE_PURPOSE (key_chain) = NULL_TREE;
+ }
else
abort ();
@@ -4676,11 +5401,8 @@ build_keyword_selector (selector)
/* Used for declarations and definitions. */
tree
-build_method_decl (code, ret_type, selector, add_args)
- enum tree_code code;
- tree ret_type;
- tree selector;
- tree add_args;
+build_method_decl (enum tree_code code, tree ret_type, tree selector,
+ tree add_args)
{
tree method_decl;
@@ -4711,18 +5433,16 @@ build_method_decl (code, ret_type, selector, add_args)
#define METHOD_DEF 0
#define METHOD_REF 1
-/* Used by `build_objc_method_call' and `comp_method_types'. Return
+/* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
an argument list for method METH. CONTEXT is either METHOD_DEF or
METHOD_REF, saying whether we are trying to define a method or call
one. SUPERFLAG says this is for a send to super; this makes a
difference for the NeXT calling sequence in which the lookup and
- the method call are done together. */
+ the method call are done together. If METH is null, user-defined
+ arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
static tree
-get_arg_type_list (meth, context, superflag)
- tree meth;
- int context;
- int superflag;
+get_arg_type_list (tree meth, int context, int superflag)
{
tree arglist, akey;
@@ -4737,6 +5457,11 @@ get_arg_type_list (meth, context, superflag)
/* Selector type - will eventually change to `int'. */
chainon (arglist, build_tree_list (NULL_TREE, selector_type));
+ /* No actual method prototype given -- assume that remaining arguments
+ are `...'. */
+ if (!meth)
+ return arglist;
+
/* Build a list of argument types. */
for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
{
@@ -4756,14 +5481,13 @@ get_arg_type_list (meth, context, superflag)
}
else
/* finalize the arglist...simulate get_parm_info (1) */
- chainon (arglist, build_tree_list (NULL_TREE, void_type_node));
+ chainon (arglist, OBJC_VOID_AT_END);
return arglist;
}
static tree
-check_duplicates (hsh)
- hash hsh;
+check_duplicates (hash hsh, int methods, int is_class)
{
tree meth = NULL_TREE;
@@ -4773,16 +5497,26 @@ check_duplicates (hsh)
if (hsh->list)
{
- /* We have two methods with the same name and different types. */
+ /* We have two or more methods with the same name but
+ different types. */
attr loop;
- char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+';
- warning ("multiple declarations for method `%s'",
+ warning ("multiple %s named `%c%s' found",
+ methods ? "methods" : "selectors",
+ (is_class ? '+' : '-'),
IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
- warn_with_method ("using", type, meth);
+ warn_with_method (methods ? "using" : "found",
+ ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
+ ? '-'
+ : '+'),
+ meth);
for (loop = hsh->list; loop; loop = loop->next)
- warn_with_method ("also found", type, loop->value);
+ warn_with_method ("also found",
+ ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
+ ? '-'
+ : '+'),
+ loop->value);
}
}
return meth;
@@ -4794,52 +5528,53 @@ check_duplicates (hsh)
used. */
static tree
-receiver_is_class_object (receiver)
- tree receiver;
+receiver_is_class_object (tree receiver, int self, int super)
{
tree chain, exp, arg;
- /* The receiver is 'self' in the context of a class method. */
+ /* The receiver is 'self' or 'super' in the context of a class method. */
if (objc_method_context
- && receiver == self_decl
- && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
- {
- return CLASS_NAME (objc_implementation_context);
- }
-
+ && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
+ && (self || super))
+ return (super
+ ? CLASS_SUPER_NAME (implementation_template)
+ : CLASS_NAME (implementation_template));
+
if (flag_next_runtime)
{
/* The receiver is a variable created by
build_class_reference_decl. */
if (TREE_CODE (receiver) == VAR_DECL
- && TREE_TYPE (receiver) == objc_class_type)
- /* Look up the identifier. */
+ && TREE_TYPE (TREE_TYPE (receiver)) == TREE_TYPE (objc_class_type))
+ /* Look up the identifier. */
for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
if (TREE_PURPOSE (chain) == receiver)
- return TREE_VALUE (chain);
- }
- else
- {
- /* The receiver is a function call that returns an id. Check if
- it is a call to objc_getClass, if so, pick up the class name. */
- if (TREE_CODE (receiver) == CALL_EXPR
- && (exp = TREE_OPERAND (receiver, 0))
- && TREE_CODE (exp) == ADDR_EXPR
- && (exp = TREE_OPERAND (exp, 0))
- && TREE_CODE (exp) == FUNCTION_DECL
- && exp == objc_get_class_decl
- /* We have a call to objc_getClass! */
- && (arg = TREE_OPERAND (receiver, 1))
- && TREE_CODE (arg) == TREE_LIST
- && (arg = TREE_VALUE (arg)))
- {
- STRIP_NOPS (arg);
- if (TREE_CODE (arg) == ADDR_EXPR
- && (arg = TREE_OPERAND (arg, 0))
- && TREE_CODE (arg) == STRING_CST)
- /* Finally, we have the class name. */
- return get_identifier (TREE_STRING_POINTER (arg));
- }
+ return TREE_VALUE (chain);
+ }
+
+ /* The receiver is a function call that returns an id. Check if
+ it is a call to objc_getClass, if so, pick up the class name. */
+ if (TREE_CODE (receiver) == CALL_EXPR
+ && (exp = TREE_OPERAND (receiver, 0))
+ && TREE_CODE (exp) == ADDR_EXPR
+ && (exp = TREE_OPERAND (exp, 0))
+ && TREE_CODE (exp) == FUNCTION_DECL
+ /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
+ prototypes for objc_get_class(). Thankfuly, they seem to share the
+ same function type. */
+ && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
+ && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
+ /* We have a call to objc_get_class/objc_getClass! */
+ && (arg = TREE_OPERAND (receiver, 1))
+ && TREE_CODE (arg) == TREE_LIST
+ && (arg = TREE_VALUE (arg)))
+ {
+ STRIP_NOPS (arg);
+ if (TREE_CODE (arg) == ADDR_EXPR
+ && (arg = TREE_OPERAND (arg, 0))
+ && TREE_CODE (arg) == STRING_CST)
+ /* Finally, we have the class name. */
+ return get_identifier (TREE_STRING_POINTER (arg));
}
return 0;
}
@@ -4851,7 +5586,7 @@ receiver_is_class_object (receiver)
static tree current_objc_message_selector = 0;
tree
-objc_message_selector ()
+objc_message_selector (void)
{
return current_objc_message_selector;
}
@@ -4864,8 +5599,7 @@ objc_message_selector ()
(*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
tree
-build_message_expr (mess)
- tree mess;
+build_message_expr (tree mess)
{
tree receiver = TREE_PURPOSE (mess);
tree sel_name;
@@ -4908,223 +5642,195 @@ build_message_expr (mess)
method_params = args;
}
+#ifdef OBJCPLUS
+ if (processing_template_decl)
+ /* Must wait until template instantiation time. */
+ return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
+ method_params);
+#endif
+
return finish_message_expr (receiver, sel_name, method_params);
}
+/* Look up method SEL_NAME that would be suitable for receiver
+ of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
+ nonzero), and report on any duplicates. */
+
+static tree
+lookup_method_in_hash_lists (tree sel_name, int is_class)
+{
+ hash method_prototype = NULL;
+
+ if (!is_class)
+ method_prototype = hash_lookup (nst_method_hash_list,
+ sel_name);
+
+ if (!method_prototype)
+ {
+ method_prototype = hash_lookup (cls_method_hash_list,
+ sel_name);
+ is_class = 1;
+ }
+
+ return check_duplicates (method_prototype, 1, is_class);
+}
+
/* The 'finish_message_expr' routine is called from within
'build_message_expr' for non-template functions. In the case of
C++ template functions, it is called from 'build_expr_from_tree'
(in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
-
+
tree
-finish_message_expr (receiver, sel_name, method_params)
- tree receiver, sel_name, method_params;
-{
- tree method_prototype = NULL_TREE, class_ident = NULL_TREE;
- tree selector, self_object, retval;
- int statically_typed = 0, statically_allocated = 0;
-
- /* Determine receiver type. */
- tree rtype = TREE_TYPE (receiver);
- int super = IS_SUPER (rtype);
-
- if (! super)
- {
- if (TREE_STATIC_TEMPLATE (rtype))
- statically_allocated = 1;
- else if (TREE_CODE (rtype) == POINTER_TYPE
- && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype)))
- statically_typed = 1;
- else if ((flag_next_runtime
- || (IS_ID (rtype)))
- && (class_ident = receiver_is_class_object (receiver)))
- ;
- else if (! IS_ID (rtype)
- /* Allow any type that matches objc_class_type. */
- && ! comptypes (rtype, objc_class_type))
+finish_message_expr (tree receiver, tree sel_name, tree method_params)
+{
+ tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
+ tree selector, retval, is_class;
+ int self, super, have_cast;
+
+ /* Extract the receiver of the message, as well as its type
+ (where the latter may take the form of a cast or be inferred
+ from the implementation context). */
+ rtype = receiver;
+ while (TREE_CODE (rtype) == COMPOUND_EXPR
+ || TREE_CODE (rtype) == MODIFY_EXPR
+ || TREE_CODE (rtype) == NOP_EXPR
+ || TREE_CODE (rtype) == COMPONENT_REF)
+ rtype = TREE_OPERAND (rtype, 0);
+ self = (rtype == self_decl);
+ super = (rtype == UOBJC_SUPER_decl);
+ rtype = TREE_TYPE (receiver);
+ have_cast = (TREE_CODE (receiver) == NOP_EXPR
+ || (TREE_CODE (receiver) == COMPOUND_EXPR
+ && !IS_SUPER (rtype)));
+
+ /* If the receiver is a class object, retrieve the corresponding
+ @interface, if one exists. */
+ is_class = receiver_is_class_object (receiver, self, super);
+
+ /* Now determine the receiver type (if an explicit cast has not been
+ provided). */
+ if (!have_cast)
+ {
+ if (is_class)
+ rtype = lookup_interface (is_class);
+ /* Handle `self' and `super'. */
+ else if (super)
{
- warning ("invalid receiver type `%s'",
- gen_declaration (rtype, errbuf));
+ if (!CLASS_SUPER_NAME (implementation_template))
+ {
+ error ("no super class declared in @interface for `%s'",
+ IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
+ return error_mark_node;
+ }
+ rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
}
- if (statically_allocated)
- receiver = build_unary_op (ADDR_EXPR, receiver, 0);
-
- /* Don't evaluate the receiver twice. */
- receiver = save_expr (receiver);
- self_object = receiver;
+ else if (self)
+ rtype = lookup_interface (CLASS_NAME (implementation_template));
}
- else
- /* If sending to `super', use current self as the object. */
- self_object = self_decl;
- /* Determine operation return type. */
-
- if (super)
+ /* If receiver is of type `id' or `Class' (or if the @interface for a
+ class is not visible), we shall be satisfied with the existence of
+ any instance or class method. */
+ if (!rtype || IS_ID (rtype)
+ || TREE_TYPE (rtype) == TREE_TYPE (objc_class_type))
{
- tree iface;
-
- if (CLASS_SUPER_NAME (implementation_template))
+ if (!rtype)
+ rtype = xref_tag (RECORD_TYPE, is_class);
+ else if (IS_ID (rtype))
{
- iface
- = lookup_interface (CLASS_SUPER_NAME (implementation_template));
-
- if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
- method_prototype = lookup_instance_method_static (iface, sel_name);
- else
- method_prototype = lookup_class_method_static (iface, sel_name);
-
- if (iface && !method_prototype)
- warning ("`%s' does not respond to `%s'",
- IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)),
- IDENTIFIER_POINTER (sel_name));
+ rprotos = TYPE_PROTOCOL_LIST (rtype);
+ rtype = NULL_TREE;
}
else
- {
- error ("no super class declared in interface for `%s'",
- IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
- return error_mark_node;
- }
+ is_class = TYPE_NAME (rtype) = get_identifier ("Class");
- }
- else if (statically_allocated)
- {
- tree ctype = TREE_TYPE (rtype);
- tree iface = lookup_interface (TYPE_NAME (rtype));
-
- if (iface)
- method_prototype = lookup_instance_method_static (iface, sel_name);
-
- if (! method_prototype && ctype && TYPE_PROTOCOL_LIST (ctype))
+ if (rprotos)
method_prototype
- = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
- sel_name, 0);
-
- if (!method_prototype)
- warning ("`%s' does not respond to `%s'",
- IDENTIFIER_POINTER (TYPE_NAME (rtype)),
- IDENTIFIER_POINTER (sel_name));
+ = lookup_method_in_protocol_list (rprotos, sel_name,
+ is_class != NULL_TREE);
+ if (!method_prototype && !rprotos)
+ method_prototype
+ = lookup_method_in_hash_lists (sel_name,
+ is_class != NULL_TREE);
}
- else if (statically_typed)
+ else
{
- tree ctype = TREE_TYPE (rtype);
-
- /* `self' is now statically_typed. All methods should be visible
- within the context of the implementation. */
- if (objc_implementation_context
- && CLASS_NAME (objc_implementation_context) == TYPE_NAME (ctype))
+ tree orig_rtype = rtype, saved_rtype;
+
+ if (TREE_CODE (rtype) == POINTER_TYPE)
+ rtype = TREE_TYPE (rtype);
+ /* Traverse typedef aliases */
+ while (TREE_CODE (rtype) == RECORD_TYPE && TYPE_NAME (rtype)
+ && TREE_CODE (TYPE_NAME (rtype)) == TYPE_DECL
+ && DECL_ORIGINAL_TYPE (TYPE_NAME (rtype)))
+ rtype = DECL_ORIGINAL_TYPE (TYPE_NAME (rtype));
+ saved_rtype = rtype;
+ if (TYPED_OBJECT (rtype))
{
- method_prototype
- = lookup_instance_method_static (implementation_template,
- sel_name);
-
- if (! method_prototype && TYPE_PROTOCOL_LIST (ctype))
- method_prototype
- = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype),
- sel_name, 0);
-
- if (! method_prototype
- && implementation_template != objc_implementation_context)
- /* The method is not published in the interface. Check
- locally. */
- method_prototype
- = lookup_method (CLASS_NST_METHODS (objc_implementation_context),
- sel_name);
+ rprotos = TYPE_PROTOCOL_LIST (rtype);
+ rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
}
- else
- {
- tree iface;
-
- if ((iface = lookup_interface (TYPE_NAME (ctype))))
- method_prototype = lookup_instance_method_static (iface, sel_name);
-
- if (! method_prototype)
- {
- tree protocol_list = TYPE_PROTOCOL_LIST (ctype);
- if (protocol_list)
- method_prototype
- = lookup_method_in_protocol_list (protocol_list,
- sel_name, 0);
- }
- }
-
- if (!method_prototype)
- warning ("`%s' does not respond to `%s'",
- IDENTIFIER_POINTER (TYPE_NAME (ctype)),
- IDENTIFIER_POINTER (sel_name));
- }
- else if (class_ident)
- {
- if (objc_implementation_context
- && CLASS_NAME (objc_implementation_context) == class_ident)
+ /* If we could not find an @interface declaration, we must have
+ only seen a @class declaration; so, we cannot say anything
+ more intelligent about which methods the receiver will
+ understand. */
+ if (!rtype)
+ rtype = saved_rtype;
+ else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
+ || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
{
+ /* We have a valid ObjC class name. Look up the method name
+ in the published @interface for the class (and its
+ superclasses). */
method_prototype
- = lookup_class_method_static (implementation_template, sel_name);
+ = lookup_method_static (rtype, sel_name, is_class != NULL_TREE);
- if (!method_prototype
- && implementation_template != objc_implementation_context)
- /* The method is not published in the interface. Check
- locally. */
+ /* If the method was not found in the @interface, it may still
+ exist locally as part of the @implementation. */
+ if (!method_prototype && objc_implementation_context
+ && CLASS_NAME (objc_implementation_context)
+ == OBJC_TYPE_NAME (rtype))
method_prototype
- = lookup_method (CLASS_CLS_METHODS (objc_implementation_context),
- sel_name);
+ = lookup_method
+ ((is_class
+ ? CLASS_CLS_METHODS (objc_implementation_context)
+ : CLASS_NST_METHODS (objc_implementation_context)),
+ sel_name);
+
+ /* If we haven't found a candidate method by now, try looking for
+ it in the protocol list. */
+ if (!method_prototype && rprotos)
+ method_prototype
+ = lookup_method_in_protocol_list (rprotos, sel_name,
+ is_class != NULL_TREE);
}
else
{
- tree iface;
-
- if ((iface = lookup_interface (class_ident)))
- method_prototype = lookup_class_method_static (iface, sel_name);
+ warning ("invalid receiver type `%s'",
+ gen_declaration (orig_rtype, errbuf));
+ rtype = rprotos = NULL_TREE;
}
+ }
- if (!method_prototype)
- {
- warning ("cannot find class (factory) method");
- warning ("return type for `%s' defaults to id",
- IDENTIFIER_POINTER (sel_name));
- }
- }
- else if (IS_PROTOCOL_QUALIFIED_ID (rtype))
+ if (!method_prototype)
{
- /* An anonymous object that has been qualified with a protocol. */
+ static bool warn_missing_methods = false;
- tree protocol_list = TYPE_PROTOCOL_LIST (rtype);
-
- method_prototype = lookup_method_in_protocol_list (protocol_list,
- sel_name, 0);
-
- if (!method_prototype)
- {
- hash hsh;
-
- warning ("method `%s' not implemented by protocol",
- IDENTIFIER_POINTER (sel_name));
-
- /* Try and find the method signature in the global pools. */
-
- if (!(hsh = hash_lookup (nst_method_hash_list, sel_name)))
- hsh = hash_lookup (cls_method_hash_list, sel_name);
-
- if (!(method_prototype = check_duplicates (hsh)))
- warning ("return type defaults to id");
- }
- }
- else
- {
- hash hsh;
-
- /* We think we have an instance...loophole: extern id Object; */
- hsh = hash_lookup (nst_method_hash_list, sel_name);
-
- if (!hsh)
- /* For various loopholes */
- hsh = hash_lookup (cls_method_hash_list, sel_name);
-
- method_prototype = check_duplicates (hsh);
- if (!method_prototype)
+ if (rtype)
+ warning ("`%s' may not respond to `%c%s'",
+ IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
+ (is_class ? '+' : '-'),
+ IDENTIFIER_POINTER (sel_name));
+ if (rprotos)
+ warning ("`%c%s' not implemented by protocol(s)",
+ (is_class ? '+' : '-'),
+ IDENTIFIER_POINTER (sel_name));
+ if (!warn_missing_methods)
{
- warning ("cannot find method");
- warning ("return type for `%s' defaults to id",
- IDENTIFIER_POINTER (sel_name));
+ warning ("(Messages without a matching method signature");
+ warning ("will be assumed to return `id' and accept");
+ warning ("`...' as arguments.)");
+ warn_missing_methods = true;
}
}
@@ -5140,7 +5846,7 @@ finish_message_expr (receiver, sel_name, method_params)
selector = build_selector_reference (sel_name);
retval = build_objc_method_call (super, method_prototype,
- receiver, self_object,
+ receiver,
selector, method_params);
current_objc_message_selector = 0;
@@ -5156,75 +5862,66 @@ finish_message_expr (receiver, sel_name, method_params)
If SUPER_FLAG is nonzero, we look up the superclass's method. */
static tree
-build_objc_method_call (super_flag, method_prototype, lookup_object, object,
- selector, method_params)
- int super_flag;
- tree method_prototype, lookup_object, object, selector, method_params;
-{
- tree sender = (super_flag ? umsg_super_decl : umsg_decl);
- tree rcv_p = (super_flag
- ? build_pointer_type (xref_tag (RECORD_TYPE,
- get_identifier (TAG_SUPER)))
- : id_type);
+build_objc_method_call (int super_flag, tree method_prototype,
+ tree lookup_object, tree selector,
+ tree method_params)
+{
+ tree sender = (super_flag ? umsg_super_decl :
+ (!flag_next_runtime || flag_nil_receivers
+ ? umsg_decl
+ : umsg_nonnil_decl));
+ tree rcv_p = (super_flag ? super_type : id_type);
+
+ /* If a prototype for the method to be called exists, then cast
+ the sender's return type and arguments to match that of the method.
+ Otherwise, leave sender as is. */
+ tree ret_type
+ = (method_prototype
+ ? groktypename (TREE_TYPE (method_prototype))
+ : id_type);
+ tree sender_cast
+ = build_pointer_type
+ (build_function_type
+ (ret_type,
+ get_arg_type_list
+ (method_prototype, METHOD_REF, super_flag)));
+
+ lookup_object = build_c_cast (rcv_p, lookup_object);
if (flag_next_runtime)
{
- if (! method_prototype)
- {
- method_params = tree_cons (NULL_TREE, lookup_object,
- tree_cons (NULL_TREE, selector,
- method_params));
- assemble_external (sender);
- return build_function_call (sender, method_params);
- }
- else
- {
- /* This is a real kludge, but it is used only for the Next.
- Clobber the data type of SENDER temporarily to accept
- all the arguments for this operation, and to return
- whatever this operation returns. */
- tree arglist = NULL_TREE, retval, savarg, savret;
- tree ret_type = groktypename (TREE_TYPE (method_prototype));
-
- /* Save the proper contents of SENDER's data type. */
- savarg = TYPE_ARG_TYPES (TREE_TYPE (sender));
- savret = TREE_TYPE (TREE_TYPE (sender));
-
- /* Install this method's argument types. */
- arglist = get_arg_type_list (method_prototype, METHOD_REF,
- super_flag);
- TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist;
-
- /* Install this method's return type. */
- TREE_TYPE (TREE_TYPE (sender)) = ret_type;
-
- /* Call SENDER with all the parameters. This will do type
- checking using the arg types for this method. */
- method_params = tree_cons (NULL_TREE, lookup_object,
- tree_cons (NULL_TREE, selector,
- method_params));
- assemble_external (sender);
- retval = build_function_call (sender, method_params);
-
- /* Restore SENDER's return/argument types. */
- TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg;
- TREE_TYPE (TREE_TYPE (sender)) = savret;
- return retval;
- }
+ /* If we are returning a struct in memory, and the address
+ of that memory location is passed as a hidden first
+ argument, then change which messenger entry point this
+ expr will call. NB: Note that sender_cast remains
+ unchanged (it already has a struct return type). */
+ if (!targetm.calls.struct_value_rtx (0, 0)
+ && (TREE_CODE (ret_type) == RECORD_TYPE
+ || TREE_CODE (ret_type) == UNION_TYPE)
+ && targetm.calls.return_in_memory (ret_type, 0))
+ sender = (super_flag ? umsg_super_stret_decl :
+ flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
+
+ method_params = tree_cons (NULL_TREE, lookup_object,
+ tree_cons (NULL_TREE, selector,
+ method_params));
+ TREE_USED (sender) = 1;
+ assemble_external (sender);
+ /* We want to cast the sender, not convert it. */
+ return build_function_call (build_c_cast (sender_cast, sender),
+ method_params);
}
else
{
- /* This is the portable way.
- First call the lookup function to get a pointer to the method,
- then cast the pointer, then call it with the method arguments. */
- tree method;
-
- /* Avoid trouble since we may evaluate each of these twice. */
- object = save_expr (object);
- selector = save_expr (selector);
-
- lookup_object = build_c_cast (rcv_p, lookup_object);
+ /* This is the portable (GNU) way. */
+ tree method, object;
+ /* First, call the lookup function to get a pointer to the method,
+ then cast the pointer, then call it with the method arguments.
+ Use SAVE_EXPR to avoid evaluating the receiver twice. */
+ lookup_object = save_expr (lookup_object);
+ object = (super_flag ? self_decl : lookup_object);
+ TREE_USED (sender) = 1;
assemble_external (sender);
method
= build_function_call (sender,
@@ -5232,37 +5929,22 @@ build_objc_method_call (super_flag, method_prototype, lookup_object, object,
tree_cons (NULL_TREE, selector,
NULL_TREE)));
- /* If we have a method prototype, construct the data type this
- method needs, and cast what we got from SENDER into a pointer
- to that type. */
- if (method_prototype)
- {
- tree arglist = get_arg_type_list (method_prototype, METHOD_REF,
- super_flag);
- tree valtype = groktypename (TREE_TYPE (method_prototype));
- tree fake_function_type = build_function_type (valtype, arglist);
- TREE_TYPE (method) = build_pointer_type (fake_function_type);
- }
- else
- TREE_TYPE (method)
- = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE));
-
/* Pass the object to the method. */
+ TREE_USED (method) = 1;
assemble_external (method);
- return build_function_call (method,
- tree_cons (NULL_TREE, object,
- tree_cons (NULL_TREE, selector,
- method_params)));
+ return build_function_call
+ (build_c_cast (sender_cast, method),
+ tree_cons (NULL_TREE, object,
+ tree_cons (NULL_TREE, selector, method_params)));
}
}
static void
-build_protocol_reference (p)
- tree p;
+build_protocol_reference (tree p)
{
tree decl, ident, ptype;
- /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
+ /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
ptype
@@ -5270,13 +5952,13 @@ build_protocol_reference (p)
objc_protocol_template),
NULL_TREE));
- if (IDENTIFIER_GLOBAL_VALUE (ident))
- decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */
+ if (identifier_global_value (ident))
+ decl = identifier_global_value (ident); /* Set by pushdecl. */
else
{
decl = build_decl (VAR_DECL, ident, ptype);
DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 1;
+ TREE_PUBLIC (decl) = 0;
TREE_USED (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
@@ -5290,8 +5972,7 @@ build_protocol_reference (p)
/* This function is called by the parser when (and only when) a
@protocol() expression is found, in order to compile it. */
tree
-build_protocol_expr (protoname)
- tree protoname;
+build_protocol_expr (tree protoname)
{
tree expr;
tree p = lookup_protocol (protoname);
@@ -5328,10 +6009,10 @@ build_protocol_expr (protoname)
/* This type is a struct containing the fields of a Protocol
object. (Cfr. protocol_type instead is the type of a pointer
to such a struct). */
- tree protocol_struct_type = xref_tag
+ tree protocol_struct_type = xref_tag
(RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
tree *chain;
-
+
/* Look for the list of Protocol statically allocated instances
to fixup at runtime. Create a new list to hold Protocol
statically allocated instances, if the list is not found. At
@@ -5343,16 +6024,16 @@ build_protocol_expr (protoname)
if (!*chain)
{
*chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
- add_objc_string (TYPE_NAME (protocol_struct_type),
+ add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
class_names);
}
-
+
/* Add this statically allocated instance to the Protocol list. */
- TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
+ TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
PROTOCOL_FORWARD_DECL (p),
TREE_PURPOSE (*chain));
}
-
+
return expr;
}
@@ -5361,8 +6042,7 @@ build_protocol_expr (protoname)
is found, in order to compile it. It is only called by the parser
and only to compile a @selector(). */
tree
-build_selector_expr (selnamelist)
- tree selnamelist;
+build_selector_expr (tree selnamelist)
{
tree selname;
@@ -5386,20 +6066,20 @@ build_selector_expr (selnamelist)
/* First try with instance methods. */
hsh = hash_lookup (nst_method_hash_list, selname);
-
+
/* If not found, try with class methods. */
if (!hsh)
{
hsh = hash_lookup (cls_method_hash_list, selname);
}
-
+
/* If still not found, print out a warning. */
if (!hsh)
{
warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
}
}
-
+
if (flag_typed_selectors)
return build_typed_selector_reference (selname, 0);
@@ -5408,8 +6088,7 @@ build_selector_expr (selnamelist)
}
tree
-build_encode_expr (type)
- tree type;
+build_encode_expr (tree type)
{
tree result;
const char *string;
@@ -5426,8 +6105,7 @@ build_encode_expr (type)
}
tree
-build_ivar_reference (id)
- tree id;
+build_ivar_reference (tree id)
{
if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
{
@@ -5451,23 +6129,24 @@ build_ivar_reference (id)
/* Compute a hash value for a given method SEL_NAME. */
static size_t
-hash_func (sel_name)
- tree sel_name;
+hash_func (tree sel_name)
{
- const unsigned char *s
+ const unsigned char *s
= (const unsigned char *)IDENTIFIER_POINTER (sel_name);
size_t h = 0;
-
+
while (*s)
h = h * 67 + *s++ - 113;
- return h;
+ return h;
}
-
+
static void
-hash_init ()
+hash_init (void)
{
- nst_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
- cls_method_hash_list = (hash *) ggc_calloc (SIZEHASHTABLE, sizeof (hash));
+ nst_method_hash_list
+ = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
+ cls_method_hash_list
+ = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
}
/* WARNING!!!! hash_enter is called with a method, and will peek
@@ -5476,9 +6155,7 @@ hash_init ()
entry's key (method) for comparison. */
static void
-hash_enter (hashlist, method)
- hash *hashlist;
- tree method;
+hash_enter (hash *hashlist, tree method)
{
hash obj;
int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
@@ -5492,9 +6169,7 @@ hash_enter (hashlist, method)
}
static hash
-hash_lookup (hashlist, sel_name)
- hash *hashlist;
- tree sel_name;
+hash_lookup (hash *hashlist, tree sel_name)
{
hash target;
@@ -5511,9 +6186,7 @@ hash_lookup (hashlist, sel_name)
}
static void
-hash_add_attr (entry, value)
- hash entry;
- tree value;
+hash_add_attr (hash entry, tree value)
{
attr obj;
@@ -5525,9 +6198,7 @@ hash_add_attr (entry, value)
}
static tree
-lookup_method (mchain, method)
- tree mchain;
- tree method;
+lookup_method (tree mchain, tree method)
{
tree key;
@@ -5547,204 +6218,138 @@ lookup_method (mchain, method)
}
static tree
-lookup_instance_method_static (interface, ident)
- tree interface;
- tree ident;
+lookup_method_static (tree interface, tree ident, int is_class)
{
+ tree meth = NULL_TREE, root_inter = NULL_TREE;
tree inter = interface;
- tree chain = CLASS_NST_METHODS (inter);
- tree meth = NULL_TREE;
- do
+ while (inter)
{
+ tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
+ tree category = inter;
+
+ /* First, look up the method in the class itself. */
if ((meth = lookup_method (chain, ident)))
return meth;
- if (CLASS_CATEGORY_LIST (inter))
+ /* Failing that, look for the method in each category of the class. */
+ while ((category = CLASS_CATEGORY_LIST (category)))
{
- tree category = CLASS_CATEGORY_LIST (inter);
- chain = CLASS_NST_METHODS (category);
-
- do
- {
- if ((meth = lookup_method (chain, ident)))
- return meth;
-
- /* Check for instance methods in protocols in categories. */
- if (CLASS_PROTOCOL_LIST (category))
- {
- if ((meth = (lookup_method_in_protocol_list
- (CLASS_PROTOCOL_LIST (category), ident, 0))))
- return meth;
- }
-
- if ((category = CLASS_CATEGORY_LIST (category)))
- chain = CLASS_NST_METHODS (category);
- }
- while (category);
- }
+ chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
- if (CLASS_PROTOCOL_LIST (inter))
- {
- if ((meth = (lookup_method_in_protocol_list
- (CLASS_PROTOCOL_LIST (inter), ident, 0))))
+ /* Check directly in each category. */
+ if ((meth = lookup_method (chain, ident)))
return meth;
- }
-
- if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
- chain = CLASS_NST_METHODS (inter);
- }
- while (inter);
-
- return meth;
-}
-
-static tree
-lookup_class_method_static (interface, ident)
- tree interface;
- tree ident;
-{
- tree inter = interface;
- tree chain = CLASS_CLS_METHODS (inter);
- tree meth = NULL_TREE;
- tree root_inter = NULL_TREE;
- do
- {
- if ((meth = lookup_method (chain, ident)))
- return meth;
-
- if (CLASS_CATEGORY_LIST (inter))
- {
- tree category = CLASS_CATEGORY_LIST (inter);
- chain = CLASS_CLS_METHODS (category);
-
- do
+ /* Failing that, check in each category's protocols. */
+ if (CLASS_PROTOCOL_LIST (category))
{
- if ((meth = lookup_method (chain, ident)))
+ if ((meth = (lookup_method_in_protocol_list
+ (CLASS_PROTOCOL_LIST (category), ident, is_class))))
return meth;
-
- /* Check for class methods in protocols in categories. */
- if (CLASS_PROTOCOL_LIST (category))
- {
- if ((meth = (lookup_method_in_protocol_list
- (CLASS_PROTOCOL_LIST (category), ident, 1))))
- return meth;
- }
-
- if ((category = CLASS_CATEGORY_LIST (category)))
- chain = CLASS_CLS_METHODS (category);
}
- while (category);
}
- /* Check for class methods in protocols. */
+ /* If not found in categories, check in protocols of the main class. */
if (CLASS_PROTOCOL_LIST (inter))
{
if ((meth = (lookup_method_in_protocol_list
- (CLASS_PROTOCOL_LIST (inter), ident, 1))))
+ (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
return meth;
}
+ /* Failing that, climb up the inheritance hierarchy. */
root_inter = inter;
- if ((inter = lookup_interface (CLASS_SUPER_NAME (inter))))
- chain = CLASS_CLS_METHODS (inter);
+ inter = lookup_interface (CLASS_SUPER_NAME (inter));
}
while (inter);
/* If no class (factory) method was found, check if an _instance_
method of the same name exists in the root class. This is what
- the Objective-C runtime will do. */
- return lookup_instance_method_static (root_inter, ident);
+ the Objective-C runtime will do. If an instance method was not
+ found, return 0. */
+ return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
}
-tree
-add_class_method (class, method)
- tree class;
- tree method;
+/* Add the method to the hash list if it doesn't contain an identical
+ method already. */
+static void
+add_method_to_hash_list (hash *hash_list, tree method)
{
- tree mth;
hash hsh;
- if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method)))
- {
- /* put method on list in reverse order */
- TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
- CLASS_CLS_METHODS (class) = method;
- }
- else
- {
- if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
- error ("duplicate definition of class method `%s'",
- IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
- else
- {
- /* Check types; if different, complain. */
- if (!comp_proto_with_proto (method, mth))
- error ("duplicate declaration of class method `%s'",
- IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
- }
- }
-
- if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method))))
+ if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
{
/* Install on a global chain. */
- hash_enter (cls_method_hash_list, method);
+ hash_enter (hash_list, method);
}
else
{
- /* Check types; if different, add to a list. */
- if (!comp_proto_with_proto (method, hsh->key))
- hash_add_attr (hsh, method);
+ /* Check types against those; if different, add to a list. */
+ attr loop;
+ int already_there = comp_proto_with_proto (method, hsh->key);
+ for (loop = hsh->list; !already_there && loop; loop = loop->next)
+ already_there |= comp_proto_with_proto (method, loop->value);
+ if (!already_there)
+ hash_add_attr (hsh, method);
}
- return method;
}
-
+
tree
-add_instance_method (class, method)
- tree class;
- tree method;
+objc_add_method (tree class, tree method, int is_class)
{
tree mth;
- hash hsh;
- if (!(mth = lookup_method (CLASS_NST_METHODS (class), method)))
+ if (!(mth = lookup_method (is_class ? CLASS_CLS_METHODS (class) : CLASS_NST_METHODS (class), method)))
{
- /* Put method on list in reverse order. */
- TREE_CHAIN (method) = CLASS_NST_METHODS (class);
- CLASS_NST_METHODS (class) = method;
+ /* put method on list in reverse order */
+ if (is_class)
+ {
+ TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
+ CLASS_CLS_METHODS (class) = method;
+ }
+ else
+ {
+ TREE_CHAIN (method) = CLASS_NST_METHODS (class);
+ CLASS_NST_METHODS (class) = method;
+ }
}
else
{
- if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
- error ("duplicate definition of instance method `%s'",
- IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
- else
- {
- /* Check types; if different, complain. */
- if (!comp_proto_with_proto (method, mth))
- error ("duplicate declaration of instance method `%s'",
- IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
- }
+ /* When processing an @interface for a class or category, give hard
+ errors on methods with identical selectors but differing argument
+ and/or return types. We do not do this for @implementations, because
+ C/C++ will do it for us (i.e., there will be duplicate function
+ definition errors). */
+ if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
+ || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
+ && !comp_proto_with_proto (method, mth))
+ error ("duplicate declaration of method `%c%s'",
+ is_class ? '+' : '-', IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
}
- if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method))))
- {
- /* Install on a global chain. */
- hash_enter (nst_method_hash_list, method);
- }
+ if (is_class)
+ add_method_to_hash_list (cls_method_hash_list, method);
else
{
- /* Check types; if different, add to a list. */
- if (!comp_proto_with_proto (method, hsh->key))
- hash_add_attr (hsh, method);
+ add_method_to_hash_list (nst_method_hash_list, method);
+
+ /* Instance methods in root classes (and categories thereof)
+ may acts as class methods as a last resort. */
+ if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
+ || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
+ class = lookup_interface (CLASS_NAME (class));
+
+ if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
+ && !CLASS_SUPER_NAME (class))
+ add_method_to_hash_list (cls_method_hash_list, method);
}
+
return method;
}
static tree
-add_class (class)
- tree class;
+add_class (tree class)
{
/* Put interfaces on list in reverse order. */
TREE_CHAIN (class) = interface_chain;
@@ -5753,24 +6358,22 @@ add_class (class)
}
static void
-add_category (class, category)
- tree class;
- tree category;
+add_category (tree class, tree category)
{
/* Put categories on list in reverse order. */
- tree cat = CLASS_CATEGORY_LIST (class);
+ tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
- while (cat)
+ if (cat)
{
- if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category))
- warning ("duplicate interface declaration for category `%s(%s)'",
- IDENTIFIER_POINTER (CLASS_NAME (class)),
- IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
- cat = CLASS_CATEGORY_LIST (cat);
+ warning ("duplicate interface declaration for category `%s(%s)'",
+ IDENTIFIER_POINTER (CLASS_NAME (class)),
+ IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
+ }
+ else
+ {
+ CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
+ CLASS_CATEGORY_LIST (class) = category;
}
-
- CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
- CLASS_CATEGORY_LIST (class) = category;
}
/* Called after parsing each instance variable declaration. Necessary to
@@ -5779,24 +6382,64 @@ add_category (class, category)
PUBLIC is 1 for public, 0 for protected, and 2 for private. */
tree
-add_instance_variable (class, public, declarator, declspecs, width)
- tree class;
- int public;
- tree declarator;
- tree declspecs;
- tree width;
+add_instance_variable (tree class, int public, tree declarator,
+ tree declspecs, tree width)
{
- tree field_decl, raw_decl;
-
- raw_decl = build_tree_list (declspecs, declarator);
+ tree field_decl = grokfield (declarator, declspecs, width);
+ tree field_type = TREE_TYPE (field_decl);
+ const char *ivar_name = DECL_NAME (field_decl)
+ ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
+ : "<unnamed>";
+ tree raw_decl;
- if (CLASS_RAW_IVARS (class))
- chainon (CLASS_RAW_IVARS (class), raw_decl);
- else
- CLASS_RAW_IVARS (class) = raw_decl;
+#ifdef OBJCPLUS
+ if (TREE_CODE (field_type) == REFERENCE_TYPE)
+ {
+ error ("illegal reference type specified for instance variable `%s'",
+ ivar_name);
+ /* Return class as is without adding this ivar. */
+ return class;
+ }
+#endif
- field_decl = grokfield (input_filename, lineno,
- declarator, declspecs, width);
+ if (field_type == error_mark_node || !TYPE_SIZE (field_type)
+ || TYPE_SIZE (field_type) == error_mark_node
+ /* 'type[0]' is allowed, but 'type[]' is not! */
+#ifdef OBJCPLUS
+ || (TYPE_SIZE (field_type) == bitsize_zero_node
+ && !TREE_OPERAND (declarator, 1))
+#endif
+ )
+ {
+ error ("instance variable `%s' has unknown size", ivar_name);
+ /* Return class as is without adding this ivar. */
+ return class;
+ }
+
+#ifdef OBJCPLUS
+ /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
+ cannot be ivars; ditto for classes with vtables. */
+ if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
+ {
+ const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
+ if(TYPE_POLYMORPHIC_P (field_type)) {
+ /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
+ error ("type `%s' has virtual member functions", type_name);
+ error ("illegal aggregate type `%s' specified for instance variable `%s'",
+ type_name, ivar_name);
+ /* Return class as is without adding this ivar. */
+ return class;
+ }
+ /* user-defined constructors and destructors are not known to Obj-C and
+ hence will not be called. This may or may not be a problem. */
+ if (TYPE_NEEDS_CONSTRUCTING (field_type))
+ warning ("type `%s' has a user-defined constructor", type_name);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
+ warning ("type `%s' has a user-defined destructor", type_name);
+ warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
+ }
+#endif
/* Overload the public attribute, it is not used for FIELD_DECLs. */
switch (public)
@@ -5821,18 +6464,14 @@ add_instance_variable (class, public, declarator, declspecs, width)
}
- if (CLASS_IVARS (class))
- chainon (CLASS_IVARS (class), field_decl);
- else
- CLASS_IVARS (class) = field_decl;
-
+ raw_decl = build_tree_list (declspecs, build_tree_list (declarator, width));
+ CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), raw_decl);
+ CLASS_IVARS (class) = chainon (CLASS_IVARS (class), field_decl);
return class;
}
tree
-is_ivar (decl_chain, ident)
- tree decl_chain;
- tree ident;
+is_ivar (tree decl_chain, tree ident)
{
for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
if (DECL_NAME (decl_chain) == ident)
@@ -5843,26 +6482,17 @@ is_ivar (decl_chain, ident)
/* True if the ivar is private and we are not in its implementation. */
int
-is_private (decl)
- tree decl;
+is_private (tree decl)
{
- if (TREE_PRIVATE (decl)
- && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl)))
- {
- error ("instance variable `%s' is declared private",
- IDENTIFIER_POINTER (DECL_NAME (decl)));
- return 1;
- }
- else
- return 0;
+ return (TREE_PRIVATE (decl)
+ && ! is_ivar (CLASS_IVARS (implementation_template),
+ DECL_NAME (decl)));
}
/* We have an instance variable reference;, check to see if it is public. */
int
-is_public (expr, identifier)
- tree expr;
- tree identifier;
+is_public (tree expr, tree identifier)
{
tree basetype = TREE_TYPE (expr);
enum tree_code code = TREE_CODE (basetype);
@@ -5872,10 +6502,10 @@ is_public (expr, identifier)
{
if (TREE_STATIC_TEMPLATE (basetype))
{
- if (!lookup_interface (TYPE_NAME (basetype)))
+ if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
{
error ("cannot find interface declaration for `%s'",
- IDENTIFIER_POINTER (TYPE_NAME (basetype)));
+ IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
return 0;
}
@@ -5893,9 +6523,27 @@ is_public (expr, identifier)
|| (TREE_CODE (objc_implementation_context)
== CATEGORY_IMPLEMENTATION_TYPE))
&& (CLASS_NAME (objc_implementation_context)
- == TYPE_NAME (basetype))))
- return ! is_private (decl);
+ == OBJC_TYPE_NAME (basetype))))
+ {
+ int private = is_private (decl);
+
+ if (private)
+ error ("instance variable `%s' is declared private",
+ IDENTIFIER_POINTER (DECL_NAME (decl)));
+ return !private;
+ }
+ /* The 2.95.2 compiler sometimes allowed C functions to access
+ non-@public ivars. We will let this slide for now... */
+ if (!objc_method_context)
+ {
+ warning ("instance variable `%s' is %s; "
+ "this will be a hard error in the future",
+ IDENTIFIER_POINTER (identifier),
+ TREE_PRIVATE (decl) ? "@private" : "@protected");
+ return 1;
+ }
+
error ("instance variable `%s' is declared %s",
IDENTIFIER_POINTER (identifier),
TREE_PRIVATE (decl) ? "private" : "protected");
@@ -5916,10 +6564,7 @@ is_public (expr, identifier)
/* Make sure all entries in CHAIN are also in LIST. */
static int
-check_methods (chain, list, mtype)
- tree chain;
- tree list;
- int mtype;
+check_methods (tree chain, tree list, int mtype)
{
int first = 1;
@@ -5953,9 +6598,7 @@ check_methods (chain, list, mtype)
/* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
static int
-conforms_to_protocol (class, protocol)
- tree class;
- tree protocol;
+conforms_to_protocol (tree class, tree protocol)
{
if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
{
@@ -5977,14 +6620,11 @@ conforms_to_protocol (class, protocol)
return 1;
}
-/* Make sure all methods in CHAIN are accessible as MTYPE methods in
+/* Make sure all methods in CHAIN are accessible as MTYPE methods in
CONTEXT. This is one of two mechanisms to check protocol integrity. */
static int
-check_methods_accessible (chain, context, mtype)
- tree chain;
- tree context;
- int mtype;
+check_methods_accessible (tree chain, tree context, int mtype)
{
int first = 1;
tree list;
@@ -6001,17 +6641,17 @@ check_methods_accessible (chain, context, mtype)
list = CLASS_NST_METHODS (context);
if (lookup_method (list, chain))
- break;
+ break;
else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
|| TREE_CODE (context) == CLASS_INTERFACE_TYPE)
- context = (CLASS_SUPER_NAME (context)
+ context = (CLASS_SUPER_NAME (context)
? lookup_interface (CLASS_SUPER_NAME (context))
: NULL_TREE);
else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
|| TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
- context = (CLASS_NAME (context)
+ context = (CLASS_NAME (context)
? lookup_interface (CLASS_NAME (context))
: NULL_TREE);
else
@@ -6046,12 +6686,9 @@ check_methods_accessible (chain, context, mtype)
/* Check whether the current interface (accessible via
'objc_implementation_context') actually implements protocol P, along
with any protocols that P inherits. */
-
+
static void
-check_protocol (p, type, name)
- tree p;
- const char *type;
- const char *name;
+check_protocol (tree p, const char *type, const char *name)
{
if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
{
@@ -6081,7 +6718,7 @@ check_protocol (p, type, name)
warning ("%s `%s' does not fully implement the `%s' protocol",
type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
}
-
+
/* Check protocols recursively. */
if (PROTOCOL_LIST (p))
{
@@ -6089,7 +6726,7 @@ check_protocol (p, type, name)
tree super_class =
lookup_interface (CLASS_SUPER_NAME (implementation_template));
- while (subs)
+ while (subs)
{
tree sub = TREE_VALUE (subs);
@@ -6101,16 +6738,13 @@ check_protocol (p, type, name)
}
}
}
-
+
/* Check whether the current interface (accessible via
'objc_implementation_context') actually implements the protocols listed
in PROTO_LIST. */
-
+
static void
-check_protocols (proto_list, type, name)
- tree proto_list;
- const char *type;
- const char *name;
+check_protocols (tree proto_list, const char *type, const char *name)
{
for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
{
@@ -6126,14 +6760,17 @@ check_protocols (proto_list, type, name)
CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
tree
-start_class (code, class_name, super_name, protocol_list)
- enum tree_code code;
- tree class_name;
- tree super_name;
- tree protocol_list;
+start_class (enum tree_code code, tree class_name, tree super_name,
+ tree protocol_list)
{
tree class, decl;
+#ifdef OBJCPLUS
+ if (current_namespace != global_namespace) {
+ error ("Objective-C declarations may only appear in global scope");
+ }
+#endif /* OBJCPLUS */
+
if (objc_implementation_context)
{
warning ("`@end' missing in implementation context");
@@ -6143,17 +6780,19 @@ start_class (code, class_name, super_name, protocol_list)
}
class = make_node (code);
- TYPE_BINFO (class) = make_tree_vec (6);
+ TYPE_BINFO (class) = make_tree_vec (CLASS_BINFO_ELTS);
CLASS_NAME (class) = class_name;
CLASS_SUPER_NAME (class) = super_name;
CLASS_CLS_METHODS (class) = NULL_TREE;
- if (! is_class_name (class_name) && (decl = lookup_name (class_name)))
+ if (! is_class_name (class_name)
+ && (decl = lookup_name (class_name)))
{
error ("`%s' redeclared as different kind of symbol",
IDENTIFIER_POINTER (class_name));
- error_with_decl (decl, "previous declaration of `%s'");
+ error ("%Jprevious declaration of '%D'",
+ decl, decl);
}
if (code == CLASS_IMPLEMENTATION_TYPE)
@@ -6172,17 +6811,6 @@ start_class (code, class_name, super_name, protocol_list)
implemented_classes);
}
- /* Pre-build the following entities - for speed/convenience. */
- if (!self_id)
- self_id = get_identifier ("self");
- if (!ucmd_id)
- ucmd_id = get_identifier ("_cmd");
- if (!unused_list)
- unused_list
- = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
- if (!objc_super_template)
- objc_super_template = build_super_template ();
-
/* Reset for multiple classes per file. */
method_slot = 0;
@@ -6213,7 +6841,7 @@ start_class (code, class_name, super_name, protocol_list)
else if (! super_name)
{
- CLASS_SUPER_NAME (objc_implementation_context)
+ CLASS_SUPER_NAME (objc_implementation_context)
= CLASS_SUPER_NAME (implementation_template);
}
}
@@ -6221,8 +6849,12 @@ start_class (code, class_name, super_name, protocol_list)
else if (code == CLASS_INTERFACE_TYPE)
{
if (lookup_interface (class_name))
- warning ("duplicate interface declaration for class `%s'",
- IDENTIFIER_POINTER (class_name));
+#ifdef OBJCPLUS
+ error ("duplicate interface declaration for class `%s'",
+#else
+ warning ("duplicate interface declaration for class `%s'",
+#endif
+ IDENTIFIER_POINTER (class_name));
else
add_class (class);
@@ -6255,17 +6887,6 @@ start_class (code, class_name, super_name, protocol_list)
else if (code == CATEGORY_IMPLEMENTATION_TYPE)
{
- /* Pre-build the following entities for speed/convenience. */
- if (!self_id)
- self_id = get_identifier ("self");
- if (!ucmd_id)
- ucmd_id = get_identifier ("_cmd");
- if (!unused_list)
- unused_list
- = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
- if (!objc_super_template)
- objc_super_template = build_super_template ();
-
/* Reset for multiple classes per file. */
method_slot = 0;
@@ -6286,8 +6907,7 @@ start_class (code, class_name, super_name, protocol_list)
}
tree
-continue_class (class)
- tree class;
+continue_class (tree class)
{
if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
|| TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
@@ -6329,11 +6949,10 @@ continue_class (class)
else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
{
- tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class));
-
- if (!TYPE_FIELDS (record))
+ if (!CLASS_STATIC_TEMPLATE (class))
{
- finish_struct (record, get_class_ivars (class), NULL_TREE);
+ tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
+ finish_struct (record, get_class_ivars (class, 0), NULL_TREE);
CLASS_STATIC_TEMPLATE (class) = record;
/* Mark this record as a class template for static typing. */
@@ -6350,8 +6969,7 @@ continue_class (class)
/* This is called once we see the "@end" in an interface/implementation. */
void
-finish_class (class)
- tree class;
+finish_class (tree class)
{
if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
{
@@ -6374,15 +6992,7 @@ finish_class (class)
else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
{
- tree category = CLASS_CATEGORY_LIST (implementation_template);
-
- /* Find the category interface from the class it is associated with. */
- while (category)
- {
- if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category))
- break;
- category = CLASS_CATEGORY_LIST (category);
- }
+ tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
if (category)
{
@@ -6417,8 +7027,7 @@ finish_class (class)
}
static tree
-add_protocol (protocol)
- tree protocol;
+add_protocol (tree protocol)
{
/* Put protocol on list in reverse order. */
TREE_CHAIN (protocol) = protocol_chain;
@@ -6427,8 +7036,7 @@ add_protocol (protocol)
}
static tree
-lookup_protocol (ident)
- tree ident;
+lookup_protocol (tree ident)
{
tree chain;
@@ -6443,11 +7051,16 @@ lookup_protocol (ident)
they are already declared or defined, the function has no effect. */
void
-objc_declare_protocols (names)
- tree names;
+objc_declare_protocols (tree names)
{
tree list;
+#ifdef OBJCPLUS
+ if (current_namespace != global_namespace) {
+ error ("Objective-C declarations may only appear in global scope");
+ }
+#endif /* OBJCPLUS */
+
for (list = names; list; list = TREE_CHAIN (list))
{
tree name = TREE_VALUE (list);
@@ -6467,13 +7080,16 @@ objc_declare_protocols (names)
}
tree
-start_protocol (code, name, list)
- enum tree_code code;
- tree name;
- tree list;
+start_protocol (enum tree_code code, tree name, tree list)
{
tree protocol;
+#ifdef OBJCPLUS
+ if (current_namespace != global_namespace) {
+ error ("Objective-C declarations may only appear in global scope");
+ }
+#endif /* OBJCPLUS */
+
/* This is as good a place as any. Need to invoke
push_tag_toplevel. */
if (!objc_protocol_template)
@@ -6510,8 +7126,7 @@ start_protocol (code, name, list)
}
void
-finish_protocol (protocol)
- tree protocol ATTRIBUTE_UNUSED;
+finish_protocol (tree protocol ATTRIBUTE_UNUSED)
{
}
@@ -6520,8 +7135,7 @@ finish_protocol (protocol)
??? What is the FORMAT? Someone please document this! */
static void
-encode_type_qualifiers (declspecs)
- tree declspecs;
+encode_type_qualifiers (tree declspecs)
{
tree spec;
@@ -6547,19 +7161,16 @@ encode_type_qualifiers (declspecs)
/* Encode a pointer type. */
static void
-encode_pointer (type, curtype, format)
- tree type;
- int curtype;
- int format;
+encode_pointer (tree type, int curtype, int format)
{
tree pointer_to = TREE_TYPE (type);
if (TREE_CODE (pointer_to) == RECORD_TYPE)
{
- if (TYPE_NAME (pointer_to)
- && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
+ if (OBJC_TYPE_NAME (pointer_to)
+ && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
{
- const char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to));
+ const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
{
@@ -6597,8 +7208,15 @@ encode_pointer (type, curtype, format)
else if (TREE_CODE (pointer_to) == INTEGER_TYPE
&& TYPE_MODE (pointer_to) == QImode)
{
- obstack_1grow (&util_obstack, '*');
- return;
+ tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
+ ? OBJC_TYPE_NAME (pointer_to)
+ : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
+
+ if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
+ {
+ obstack_1grow (&util_obstack, '*');
+ return;
+ }
}
/* We have a type that does not get special treatment. */
@@ -6609,10 +7227,7 @@ encode_pointer (type, curtype, format)
}
static void
-encode_array (type, curtype, format)
- tree type;
- int curtype;
- int format;
+encode_array (tree type, int curtype, int format)
{
tree an_int_cst = TYPE_SIZE (type);
tree array_of = TREE_TYPE (type);
@@ -6636,131 +7251,75 @@ encode_array (type, curtype, format)
}
static void
-encode_aggregate_within (type, curtype, format, left, right)
- tree type;
- int curtype;
- int format;
- int left;
- int right;
-{
- /* The RECORD_TYPE may in fact be a typedef! For purposes
- of encoding, we need the real underlying enchilada. */
- if (TYPE_MAIN_VARIANT (type))
- type = TYPE_MAIN_VARIANT (type);
-
- if (obstack_object_size (&util_obstack) > 0
- && *(obstack_next_free (&util_obstack) - 1) == '^')
- {
- tree name = TYPE_NAME (type);
-
- /* we have a reference; this is a NeXT extension. */
-
- if (obstack_object_size (&util_obstack) - curtype == 1
- && format == OBJC_ENCODE_INLINE_DEFS)
- {
- /* Output format of struct for first level only. */
- tree fields = TYPE_FIELDS (type);
-
- if (name && TREE_CODE (name) == IDENTIFIER_NODE)
- {
- obstack_1grow (&util_obstack, left);
- obstack_grow (&util_obstack,
- IDENTIFIER_POINTER (name),
- strlen (IDENTIFIER_POINTER (name)));
- obstack_1grow (&util_obstack, '=');
- }
- else
- {
- obstack_1grow (&util_obstack, left);
- obstack_grow (&util_obstack, "?=", 2);
- }
-
- for ( ; fields; fields = TREE_CHAIN (fields))
- encode_field_decl (fields, curtype, format);
-
- obstack_1grow (&util_obstack, right);
- }
-
- else if (name && TREE_CODE (name) == IDENTIFIER_NODE)
- {
- obstack_1grow (&util_obstack, left);
- obstack_grow (&util_obstack,
- IDENTIFIER_POINTER (name),
- strlen (IDENTIFIER_POINTER (name)));
- obstack_1grow (&util_obstack, right);
- }
-
- else
- {
- /* We have an untagged structure or a typedef. */
- obstack_1grow (&util_obstack, left);
- obstack_1grow (&util_obstack, '?');
- obstack_1grow (&util_obstack, right);
- }
- }
-
+encode_aggregate_within (tree type, int curtype, int format, int left,
+ int right)
+{
+ tree name;
+ /* NB: aggregates that are pointed to have slightly different encoding
+ rules in that you never encode the names of instance variables. */
+ int pointed_to
+ = (obstack_object_size (&util_obstack) > 0
+ && *(obstack_next_free (&util_obstack) - 1) == '^');
+ int inline_contents
+ = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
+ && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
+
+ /* Traverse struct aliases; it is important to get the
+ original struct and its tag name (if any). */
+ type = TYPE_MAIN_VARIANT (type);
+ name = OBJC_TYPE_NAME (type);
+ /* Open parenth/bracket. */
+ obstack_1grow (&util_obstack, left);
+
+ /* Encode the struct/union tag name, or '?' if a tag was
+ not provided. Typedef aliases do not qualify. */
+ if (name && TREE_CODE (name) == IDENTIFIER_NODE
+#ifdef OBJCPLUS
+ /* Did this struct have a tag? */
+ && !TYPE_WAS_ANONYMOUS (type)
+#endif
+ )
+ obstack_grow (&util_obstack,
+ IDENTIFIER_POINTER (name),
+ strlen (IDENTIFIER_POINTER (name)));
else
+ obstack_1grow (&util_obstack, '?');
+
+ /* Encode the types (and possibly names) of the inner fields,
+ if required. */
+ if (inline_contents)
{
- tree name = TYPE_NAME (type);
tree fields = TYPE_FIELDS (type);
- if (format == OBJC_ENCODE_INLINE_DEFS
- || generating_instance_variables)
+ obstack_1grow (&util_obstack, '=');
+ for (; fields; fields = TREE_CHAIN (fields))
{
- obstack_1grow (&util_obstack, left);
- if (name && TREE_CODE (name) == IDENTIFIER_NODE)
- obstack_grow (&util_obstack,
- IDENTIFIER_POINTER (name),
- strlen (IDENTIFIER_POINTER (name)));
- else
- obstack_1grow (&util_obstack, '?');
-
- obstack_1grow (&util_obstack, '=');
-
- for (; fields; fields = TREE_CHAIN (fields))
+#ifdef OBJCPLUS
+ /* C++ static members, and things that are not fields at all,
+ should not appear in the encoding. */
+ if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
+ continue;
+#endif
+ if (generating_instance_variables && !pointed_to)
{
- if (generating_instance_variables)
- {
- tree fname = DECL_NAME (fields);
-
- obstack_1grow (&util_obstack, '"');
- if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
- {
- obstack_grow (&util_obstack,
- IDENTIFIER_POINTER (fname),
- strlen (IDENTIFIER_POINTER (fname)));
- }
-
- obstack_1grow (&util_obstack, '"');
- }
-
- encode_field_decl (fields, curtype, format);
+ tree fname = DECL_NAME (fields);
+
+ obstack_1grow (&util_obstack, '"');
+ if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
+ obstack_grow (&util_obstack,
+ IDENTIFIER_POINTER (fname),
+ strlen (IDENTIFIER_POINTER (fname)));
+ obstack_1grow (&util_obstack, '"');
}
-
- obstack_1grow (&util_obstack, right);
- }
-
- else
- {
- obstack_1grow (&util_obstack, left);
- if (name && TREE_CODE (name) == IDENTIFIER_NODE)
- obstack_grow (&util_obstack,
- IDENTIFIER_POINTER (name),
- strlen (IDENTIFIER_POINTER (name)));
- else
- /* We have an untagged structure or a typedef. */
- obstack_1grow (&util_obstack, '?');
-
- obstack_1grow (&util_obstack, right);
+ encode_field_decl (fields, curtype, format);
}
}
+ /* Close parenth/bracket. */
+ obstack_1grow (&util_obstack, right);
}
static void
-encode_aggregate (type, curtype, format)
- tree type;
- int curtype;
- int format;
+encode_aggregate (tree type, int curtype, int format)
{
enum tree_code code = TREE_CODE (type);
@@ -6768,12 +7327,12 @@ encode_aggregate (type, curtype, format)
{
case RECORD_TYPE:
{
- encode_aggregate_within(type, curtype, format, '{', '}');
+ encode_aggregate_within (type, curtype, format, '{', '}');
break;
}
case UNION_TYPE:
{
- encode_aggregate_within(type, curtype, format, '(', ')');
+ encode_aggregate_within (type, curtype, format, '(', ')');
break;
}
@@ -6786,19 +7345,11 @@ encode_aggregate (type, curtype, format)
}
}
-/* Support bitfields. The current version of Objective-C does not support
- them. The string will consist of one or more "b:n"'s where n is an
- integer describing the width of the bitfield. Currently, classes in
- the kit implement a method "-(char *)describeBitfieldStruct:" that
- simulates this. If they do not implement this method, the archiver
- assumes the bitfield is 16 bits wide (padded if necessary) and packed
- according to the GNU compiler. After looking at the "kit", it appears
- that all classes currently rely on this default behavior, rather than
- hand generating this string (which is tedious). */
+/* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
+ field type. */
static void
-encode_bitfield (width)
- int width;
+encode_next_bitfield (int width)
{
char buffer[40];
sprintf (buffer, "b%d", width);
@@ -6806,70 +7357,50 @@ encode_bitfield (width)
}
/* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
-
static void
-encode_type (type, curtype, format)
- tree type;
- int curtype;
- int format;
+encode_type (tree type, int curtype, int format)
{
enum tree_code code = TREE_CODE (type);
+ char c;
if (code == INTEGER_TYPE)
{
- if (integer_zerop (TYPE_MIN_VALUE (type)))
+ switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
{
- /* Unsigned integer types. */
-
- if (TYPE_MODE (type) == QImode)
- obstack_1grow (&util_obstack, 'C');
- else if (TYPE_MODE (type) == HImode)
- obstack_1grow (&util_obstack, 'S');
- else if (TYPE_MODE (type) == SImode)
- {
- if (type == long_unsigned_type_node)
- obstack_1grow (&util_obstack, 'L');
- else
- obstack_1grow (&util_obstack, 'I');
- }
- else if (TYPE_MODE (type) == DImode)
- obstack_1grow (&util_obstack, 'Q');
- }
-
- else
- /* Signed integer types. */
- {
- if (TYPE_MODE (type) == QImode)
- obstack_1grow (&util_obstack, 'c');
- else if (TYPE_MODE (type) == HImode)
- obstack_1grow (&util_obstack, 's');
- else if (TYPE_MODE (type) == SImode)
- {
- if (type == long_integer_type_node)
- obstack_1grow (&util_obstack, 'l');
- else
- obstack_1grow (&util_obstack, 'i');
- }
-
- else if (TYPE_MODE (type) == DImode)
- obstack_1grow (&util_obstack, 'q');
+ case 8: c = TREE_UNSIGNED (type) ? 'C' : 'c'; break;
+ case 16: c = TREE_UNSIGNED (type) ? 'S' : 's'; break;
+ case 32:
+ if (type == long_unsigned_type_node
+ || type == long_integer_type_node)
+ c = TREE_UNSIGNED (type) ? 'L' : 'l';
+ else
+ c = TREE_UNSIGNED (type) ? 'I' : 'i';
+ break;
+ case 64: c = TREE_UNSIGNED (type) ? 'Q' : 'q'; break;
+ default: abort ();
}
+ obstack_1grow (&util_obstack, c);
}
else if (code == REAL_TYPE)
{
/* Floating point types. */
-
- if (TYPE_MODE (type) == SFmode)
- obstack_1grow (&util_obstack, 'f');
- else if (TYPE_MODE (type) == DFmode
- || TYPE_MODE (type) == TFmode)
- obstack_1grow (&util_obstack, 'd');
+ switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
+ {
+ case 32: c = 'f'; break;
+ case 64:
+ case 128: c = 'd'; break;
+ default: abort ();
+ }
+ obstack_1grow (&util_obstack, c);
}
else if (code == VOID_TYPE)
obstack_1grow (&util_obstack, 'v');
+ else if (code == BOOLEAN_TYPE)
+ obstack_1grow (&util_obstack, 'B');
+
else if (code == ARRAY_TYPE)
encode_array (type, curtype, format);
@@ -6884,10 +7415,7 @@ encode_type (type, curtype, format)
}
static void
-encode_complete_bitfield (position, type, size)
- int position;
- tree type;
- int size;
+encode_gnu_bitfield (int position, tree type, int size)
{
enum tree_code code = TREE_CODE (type);
char buffer[40];
@@ -6943,39 +7471,37 @@ encode_complete_bitfield (position, type, size)
}
static void
-encode_field_decl (field_decl, curtype, format)
- tree field_decl;
- int curtype;
- int format;
+encode_field_decl (tree field_decl, int curtype, int format)
{
tree type;
+#ifdef OBJCPLUS
+ /* C++ static members, and things that are not fields at all,
+ should not appear in the encoding. */
+ if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
+ return;
+#endif
+
type = TREE_TYPE (field_decl);
- /* If this field is obviously a bitfield, or is a bitfield that has been
- clobbered to look like a ordinary integer mode, go ahead and generate
- the bitfield typing information. */
- if (flag_next_runtime)
+ /* Generate the bitfield typing information, if needed. Note the difference
+ between GNU and NeXT runtimes. */
+ if (DECL_BIT_FIELD_TYPE (field_decl))
{
- if (DECL_BIT_FIELD_TYPE (field_decl))
- encode_bitfield (tree_low_cst (DECL_SIZE (field_decl), 1));
+ int size = tree_low_cst (DECL_SIZE (field_decl), 1);
+
+ if (flag_next_runtime)
+ encode_next_bitfield (size);
else
- encode_type (TREE_TYPE (field_decl), curtype, format);
+ encode_gnu_bitfield (int_bit_position (field_decl),
+ DECL_BIT_FIELD_TYPE (field_decl), size);
}
else
- {
- if (DECL_BIT_FIELD_TYPE (field_decl))
- encode_complete_bitfield (int_bit_position (field_decl),
- DECL_BIT_FIELD_TYPE (field_decl),
- tree_low_cst (DECL_SIZE (field_decl), 1));
- else
- encode_type (TREE_TYPE (field_decl), curtype, format);
- }
+ encode_type (TREE_TYPE (field_decl), curtype, format);
}
static tree
-expr_last (complex_expr)
- tree complex_expr;
+objc_expr_last (tree complex_expr)
{
tree next;
@@ -6985,26 +7511,14 @@ expr_last (complex_expr)
return complex_expr;
}
-
-/* Transform a method definition into a function definition as follows:
- - synthesize the first two arguments, "self" and "_cmd". */
-void
-start_method_def (method)
- tree method;
+static void
+synth_self_and_ucmd_args (void)
{
tree decl_specs;
- /* Required to implement _msgSuper. */
- objc_method_context = method;
- UOBJC_SUPER_decl = NULL_TREE;
-
- /* Must be called BEFORE start_function. */
- pushlevel (0);
-
- /* Generate prototype declarations for arguments..."new-style". */
-
- if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
+ if (objc_method_context
+ && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
decl_specs = build_tree_list (NULL_TREE, uprivate_record);
else
/* Really a `struct objc_class *'. However, we allow people to
@@ -7023,6 +7537,23 @@ start_method_def (method)
(build_tree_list (decl_specs,
build1 (INDIRECT_REF, NULL_TREE, ucmd_id)),
unused_list));
+}
+
+/* Transform a method definition into a function definition as follows:
+ - synthesize the first two arguments, "self" and "_cmd". */
+
+void
+start_method_def (tree method)
+{
+ /* Required to implement _msgSuper. */
+ objc_method_context = method;
+ UOBJC_SUPER_decl = NULL_TREE;
+
+ /* Must be called BEFORE start_function. */
+ pushlevel (0);
+
+ /* Generate prototype declarations for arguments..."new-style". */
+ synth_self_and_ucmd_args ();
/* Generate argument declarations if a keyword_decl. */
if (METHOD_SEL_ARGS (method))
@@ -7035,7 +7566,7 @@ start_method_def (method)
if (arg_decl)
{
- tree last_expr = expr_last (arg_decl);
+ tree last_expr = objc_expr_last (arg_decl);
/* Unite the abstract decl with its name. */
TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist);
@@ -7043,8 +7574,10 @@ start_method_def (method)
(build_tree_list (arg_spec, arg_decl),
NULL_TREE));
+#ifndef OBJCPLUS
/* Unhook: restore the abstract declarator. */
TREE_OPERAND (last_expr, 0) = NULL_TREE;
+#endif
}
else
@@ -7075,29 +7608,17 @@ start_method_def (method)
}
static void
-warn_with_method (message, mtype, method)
- const char *message;
- int mtype;
- tree method;
+warn_with_method (const char *message, int mtype, tree method)
{
- if (!diagnostic_count_diagnostic (global_dc, DK_WARNING))
- return;
-
- diagnostic_report_current_function (global_dc);
-
/* Add a readable method name to the warning. */
- warning_with_file_and_line (DECL_SOURCE_FILE (method),
- DECL_SOURCE_LINE (method),
- "%s `%c%s'",
- message, mtype,
- gen_method_decl (method, errbuf));
+ warning ("%J%s `%c%s'", method,
+ message, mtype, gen_method_decl (method, errbuf));
}
/* Return 1 if METHOD is consistent with PROTO. */
static int
-comp_method_with_proto (method, proto)
- tree method, proto;
+comp_method_with_proto (tree method, tree proto)
{
/* Create a function template node at most once. */
if (!function1_template)
@@ -7109,30 +7630,61 @@ comp_method_with_proto (method, proto)
/* install return type */
TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
- return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
+ return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template,
+ false);
}
-/* Return 1 if PROTO1 is consistent with PROTO2. */
+/* Return 1 if TYPE1 is equivalent to TYPE2. */
static int
-comp_proto_with_proto (proto0, proto1)
- tree proto0, proto1;
+objc_types_are_equivalent (tree type1, tree type2)
{
- /* Create a couple of function_template nodes at most once. */
- if (!function1_template)
- function1_template = make_node (FUNCTION_TYPE);
- if (!function2_template)
- function2_template = make_node (FUNCTION_TYPE);
+ if (type1 == type2)
+ return 1;
+ if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
+ return 0;
+ type1 = TYPE_PROTOCOL_LIST (type1);
+ type2 = TYPE_PROTOCOL_LIST (type2);
+ if (list_length (type1) == list_length (type2))
+ {
+ for (; type2; type2 = TREE_CHAIN (type2))
+ if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
+ return 0;
+ return 1;
+ }
+ return 0;
+}
+
+/* Return 1 if PROTO1 is equivalent to PROTO2. */
+
+static int
+comp_proto_with_proto (tree proto1, tree proto2)
+{
+ tree type1, type2;
+
+ /* The following test is needed in case there are hashing
+ collisions. */
+ if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
+ return 0;
- /* Install argument types; normally set by build_function_type. */
- TYPE_ARG_TYPES (function1_template) = get_arg_type_list (proto0, METHOD_REF, 0);
- TYPE_ARG_TYPES (function2_template) = get_arg_type_list (proto1, METHOD_REF, 0);
+ /* Compare return types. */
+ type1 = groktypename (TREE_TYPE (proto1));
+ type2 = groktypename (TREE_TYPE (proto2));
- /* Install return type. */
- TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
- TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
+ if (!objc_types_are_equivalent (type1, type2))
+ return 0;
+
+ /* Compare argument types. */
+ for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
+ type2 = get_arg_type_list (proto2, METHOD_REF, 0);
+ type1 && type2;
+ type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
+ {
+ if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
+ return 0;
+ }
- return comptypes (function1_template, function2_template);
+ return (!type1 && !type2);
}
/* - Generate an identifier for the function. the format is "_n_cls",
@@ -7142,8 +7694,7 @@ comp_proto_with_proto (proto0, proto1)
- If we have a prototype, check for type consistency. */
static void
-really_start_method (method, parmlist)
- tree method, parmlist;
+really_start_method (tree method, tree parmlist)
{
tree sc_spec, ret_spec, ret_decl, decl_specs;
tree method_decl, method_id;
@@ -7172,6 +7723,12 @@ really_start_method (method, parmlist)
method_id = get_identifier (buf);
+#ifdef OBJCPLUS
+ /* Objective-C methods cannot be overloaded, so we don't need
+ the type encoding appended. It looks bad anyway... */
+ push_lang_context (lang_name_c);
+#endif
+
method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE);
/* Check the declarator portion of the return type for the method. */
@@ -7179,7 +7736,7 @@ really_start_method (method, parmlist)
{
/* Unite the complex decl (specified in the abstract decl) with the
function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
- tree save_expr = expr_last (ret_decl);
+ tree save_expr = objc_expr_last (ret_decl);
TREE_OPERAND (save_expr, 0) = method_decl;
method_decl = ret_decl;
@@ -7202,38 +7759,72 @@ really_start_method (method, parmlist)
TREE_VALUE (TREE_TYPE (method)) = NULL_TREE;
}
+#ifdef OBJCPLUS
+ /* set self_decl from the first argument...this global is used by
+ * build_ivar_reference().build_indirect_ref().
+ */
+ self_decl = DECL_ARGUMENTS (current_function_decl);
+
+ /* snaroff (3/28/96): when compiling with -Wall, this suppresses
+ * the following: warning:unused parameter `struct objc_selector * _cmd'
+ */
+ TREE_USED (self_decl) = 1;
+ TREE_USED (TREE_CHAIN (self_decl)) = 1;
+ /* Ditto for the underlying (static) C function. */
+ TREE_USED (current_function_decl) = 1;
+ pop_lang_context ();
+#endif
+
METHOD_DEFINITION (method) = current_function_decl;
/* Check consistency...start_function, pushdecl, duplicate_decls. */
if (implementation_template != objc_implementation_context)
{
- tree proto;
-
- if (TREE_CODE (method) == INSTANCE_METHOD_DECL)
- proto = lookup_instance_method_static (implementation_template,
- METHOD_SEL_NAME (method));
- else
- proto = lookup_class_method_static (implementation_template,
- METHOD_SEL_NAME (method));
+ tree proto
+ = lookup_method_static (implementation_template,
+ METHOD_SEL_NAME (method),
+ TREE_CODE (method) == CLASS_METHOD_DECL);
- if (proto && ! comp_method_with_proto (method, proto))
+ if (proto)
{
- char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
+ if (!comp_method_with_proto (method, proto))
+ {
+ char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
- warn_with_method ("conflicting types for", type, method);
- warn_with_method ("previous declaration of", type, proto);
+ warn_with_method ("conflicting types for", type, method);
+ warn_with_method ("previous declaration of", type, proto);
+ }
+ }
+ else
+ {
+ /* We have a method @implementation even though we did not
+ see a corresponding @interface declaration (which is allowed
+ by Objective-C rules). Go ahead and place the method in
+ the @interface anyway, so that message dispatch lookups
+ will see it. */
+ tree interface = implementation_template;
+
+ if (TREE_CODE (objc_implementation_context)
+ == CATEGORY_IMPLEMENTATION_TYPE)
+ interface = lookup_category
+ (interface,
+ CLASS_SUPER_NAME (objc_implementation_context));
+
+ if (interface)
+ objc_add_method (interface, copy_node (method),
+ TREE_CODE (method) == CLASS_METHOD_DECL);
}
}
}
/* The following routine is always called...this "architecture" is to
accommodate "old-style" variable length selectors.
-
+
- a:a b:b // prototype ; id c; id d; // old-style. */
void
-continue_method_def ()
+continue_method_def (void)
{
tree parmlist;
@@ -7243,34 +7834,18 @@ continue_method_def ()
else
parmlist = get_parm_info (1); /* place a `void_at_end' */
+#ifndef OBJCPLUS
/* Set self_decl from the first argument...this global is used by
build_ivar_reference calling build_indirect_ref. */
self_decl = TREE_PURPOSE (parmlist);
+#endif /* !OBJCPLUS */
poplevel (0, 0, 0);
really_start_method (objc_method_context, parmlist);
store_parm_decls ();
}
-/* Called by the parser, from the `pushlevel' production. */
-
-void
-add_objc_decls ()
-{
- if (!UOBJC_SUPER_decl)
- {
- UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER),
- build_tree_list (NULL_TREE,
- objc_super_template),
- 0, NULL_TREE);
-
- finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
-
- /* This prevents `unused variable' warnings when compiling with -Wall. */
- TREE_USED (UOBJC_SUPER_decl) = 1;
- DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
- }
-}
+static void *UOBJC_SUPER_scope = 0;
/* _n_Method (id self, SEL sel, ...)
{
@@ -7279,12 +7854,28 @@ add_objc_decls ()
} */
tree
-get_super_receiver ()
+get_super_receiver (void)
{
if (objc_method_context)
{
tree super_expr, super_expr_list;
+ if (!UOBJC_SUPER_decl)
+ {
+ UOBJC_SUPER_decl = start_decl (get_identifier (TAG_SUPER),
+ build_tree_list (NULL_TREE,
+ objc_super_template),
+ 0, NULL_TREE);
+
+ finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
+
+ /* This prevents `unused variable' warnings when compiling with -Wall. */
+ TREE_USED (UOBJC_SUPER_decl) = 1;
+ DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1;
+
+ UOBJC_SUPER_scope = get_current_scope ();
+ }
+
/* Set receiver to self. */
super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
@@ -7320,17 +7911,18 @@ get_super_receiver ()
return error_mark_node;
}
- if (flag_next_runtime)
+ if (flag_next_runtime && !flag_zero_link)
{
super_class = get_class_reference (super_name);
if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
- /* Cast the super class to 'id', since the user may not have
- included <objc/objc-class.h>, leaving 'struct objc_class'
- an incomplete type. */
+ /* If we are in a class method, we must retrieve the
+ _metaclass_ for the current class, pointed at by
+ the class's "isa" pointer. The following assumes that
+ "isa" is the first ivar in a class (which it must be). */
super_class
- = build_component_ref (build_indirect_ref
- (build_c_cast (id_type, super_class), "->"),
- get_identifier ("isa"));
+ = build_indirect_ref
+ (build_c_cast (build_pointer_type (objc_class_type),
+ super_class), "unary *");
}
else
{
@@ -7347,8 +7939,10 @@ get_super_receiver ()
IDENTIFIER_POINTER (super_name))));
}
- TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref);
- super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class);
+ super_expr
+ = build_modify_expr (super_expr, NOP_EXPR,
+ build_c_cast (TREE_TYPE (super_expr),
+ super_class));
}
chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr));
@@ -7365,74 +7959,45 @@ get_super_receiver ()
}
}
-static tree
-encode_method_def (func_decl)
- tree func_decl;
-{
- tree parms;
- int stack_size;
- HOST_WIDE_INT max_parm_end = 0;
- char buffer[40];
- tree result;
+/* When exiting a scope, sever links to a 'super' declaration (if any)
+ therein contained. */
- /* Return type. */
- encode_type (TREE_TYPE (TREE_TYPE (func_decl)),
- obstack_object_size (&util_obstack),
- OBJC_ENCODE_INLINE_DEFS);
-
- /* Stack size. */
- for (parms = DECL_ARGUMENTS (func_decl); parms;
- parms = TREE_CHAIN (parms))
- {
- HOST_WIDE_INT parm_end = (forwarding_offset (parms)
- + int_size_in_bytes (TREE_TYPE (parms)));
-
- if (! offset_is_register && parm_end > max_parm_end)
- max_parm_end = parm_end;
- }
-
- stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET;
-
- sprintf (buffer, "%d", stack_size);
- obstack_grow (&util_obstack, buffer, strlen (buffer));
-
- /* Argument types. */
- for (parms = DECL_ARGUMENTS (func_decl); parms;
- parms = TREE_CHAIN (parms))
- {
- /* Type. */
- encode_type (TREE_TYPE (parms),
- obstack_object_size (&util_obstack),
- OBJC_ENCODE_INLINE_DEFS);
-
- /* Compute offset. */
- sprintf (buffer, "%d", forwarding_offset (parms));
-
- /* Indicate register. */
- if (offset_is_register)
- obstack_1grow (&util_obstack, '+');
-
- obstack_grow (&util_obstack, buffer, strlen (buffer));
- }
-
- /* Null terminate string. */
- obstack_1grow (&util_obstack, 0);
- result = get_identifier (obstack_finish (&util_obstack));
- obstack_free (&util_obstack, util_firstobj);
- return result;
+void
+objc_clear_super_receiver (void)
+{
+ if (objc_method_context
+ && UOBJC_SUPER_scope == get_current_scope ()) {
+ UOBJC_SUPER_decl = 0;
+ UOBJC_SUPER_scope = 0;
+ }
}
static void
-objc_expand_function_end ()
+objc_expand_function_end (void)
{
- METHOD_ENCODING (objc_method_context) = encode_method_def (current_function_decl);
+ /* This routine may also get called for C functions, including those
+ nested within ObjC methods. In such cases, method encoding is
+ meaningless. */
+ if (objc_method_context == NULL_TREE
+ || DECL_INITIAL (objc_method_context) != current_function_decl)
+ return;
+
+ METHOD_ENCODING (objc_method_context)
+ = encode_method_prototype (objc_method_context);
}
void
-finish_method_def ()
+finish_method_def (void)
{
lang_expand_function_end = objc_expand_function_end;
- finish_function (0, 1);
+ /* We cannot validly inline ObjC methods, at least not without a language
+ extension to declare that a method need not be dynamically
+ dispatched, so suppress all thoughts of doing so. */
+ DECL_INLINE (current_function_decl) = 0;
+ DECL_UNINLINABLE (current_function_decl) = 1;
+ current_function_cannot_inline = "methods cannot be inlined";
+
+ finish_function ();
lang_expand_function_end = NULL;
/* Required to implement _msgSuper. This must be done AFTER finish_function,
@@ -7442,8 +8007,7 @@ finish_method_def ()
#if 0
int
-lang_report_error_function (decl)
- tree decl;
+lang_report_error_function (tree decl)
{
if (objc_method_context)
{
@@ -7458,8 +8022,7 @@ lang_report_error_function (decl)
#endif
static int
-is_complex_decl (type)
- tree type;
+is_complex_decl (tree type)
{
return (TREE_CODE (type) == ARRAY_TYPE
|| TREE_CODE (type) == FUNCTION_TYPE
@@ -7472,9 +8035,7 @@ is_complex_decl (type)
static char tmpbuf[256];
static void
-adorn_decl (decl, str)
- tree decl;
- char *str;
+adorn_decl (tree decl, char *str)
{
enum tree_code code = TREE_CODE (decl);
@@ -7574,10 +8135,7 @@ adorn_decl (decl, str)
}
static char *
-gen_declarator (decl, buf, name)
- tree decl;
- char *buf;
- const char *name;
+gen_declarator (tree decl, char *buf, const char *name)
{
if (decl)
{
@@ -7666,10 +8224,7 @@ gen_declarator (decl, buf, name)
}
static void
-gen_declspecs (declspecs, buf, raw)
- tree declspecs;
- char *buf;
- int raw;
+gen_declspecs (tree declspecs, char *buf, int raw)
{
if (raw)
{
@@ -7684,13 +8239,13 @@ gen_declspecs (declspecs, buf, raw)
strcat (buf, IDENTIFIER_POINTER (aspec));
else if (TREE_CODE (aspec) == RECORD_TYPE)
{
- if (TYPE_NAME (aspec))
+ if (OBJC_TYPE_NAME (aspec))
{
tree protocol_list = TYPE_PROTOCOL_LIST (aspec);
if (! TREE_STATIC_TEMPLATE (aspec))
strcat (buf, "struct ");
- strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
+ strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
/* NEW!!! */
if (protocol_list)
@@ -7717,11 +8272,11 @@ gen_declspecs (declspecs, buf, raw)
else if (TREE_CODE (aspec) == UNION_TYPE)
{
- if (TYPE_NAME (aspec))
+ if (OBJC_TYPE_NAME (aspec))
{
if (! TREE_STATIC_TEMPLATE (aspec))
strcat (buf, "union ");
- strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
+ strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
}
else
strcat (buf, "untagged union");
@@ -7729,11 +8284,11 @@ gen_declspecs (declspecs, buf, raw)
else if (TREE_CODE (aspec) == ENUMERAL_TYPE)
{
- if (TYPE_NAME (aspec))
+ if (OBJC_TYPE_NAME (aspec))
{
if (! TREE_STATIC_TEMPLATE (aspec))
strcat (buf, "enum ");
- strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec)));
+ strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (aspec)));
}
else
strcat (buf, "untagged enum");
@@ -7823,14 +8378,14 @@ gen_declspecs (declspecs, buf, raw)
break;
case RECORD_TYPE:
- if (TYPE_NAME (declspecs)
- && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
+ if (OBJC_TYPE_NAME (declspecs)
+ && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
{
tree protocol_list = TYPE_PROTOCOL_LIST (declspecs);
if (! TREE_STATIC_TEMPLATE (declspecs))
strcat (buf, "struct ");
- strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
+ strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
if (protocol_list)
{
@@ -7857,11 +8412,11 @@ gen_declspecs (declspecs, buf, raw)
break;
case UNION_TYPE:
- if (TYPE_NAME (declspecs)
- && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
+ if (OBJC_TYPE_NAME (declspecs)
+ && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
{
strcat (buf, "union ");
- strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
+ strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
strcat (buf, " ");
}
@@ -7870,11 +8425,11 @@ gen_declspecs (declspecs, buf, raw)
break;
case ENUMERAL_TYPE:
- if (TYPE_NAME (declspecs)
- && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
+ if (OBJC_TYPE_NAME (declspecs)
+ && TREE_CODE (OBJC_TYPE_NAME (declspecs)) == IDENTIFIER_NODE)
{
strcat (buf, "enum ");
- strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs)));
+ strcat (buf, IDENTIFIER_POINTER (OBJC_TYPE_NAME (declspecs)));
strcat (buf, " ");
}
@@ -7910,7 +8465,7 @@ gen_declspecs (declspecs, buf, raw)
}
}
break;
-
+
default:
break;
}
@@ -7921,9 +8476,7 @@ gen_declspecs (declspecs, buf, raw)
buffer, overwriting the buffer. */
static char *
-gen_declaration (atype_or_adecl, buf)
- tree atype_or_adecl;
- char *buf;
+gen_declaration (tree atype_or_adecl, char *buf)
{
buf[0] = '\0';
gen_declaration_1 (atype_or_adecl, buf);
@@ -7934,9 +8487,7 @@ gen_declaration (atype_or_adecl, buf)
given buffer. */
static void
-gen_declaration_1 (atype_or_adecl, buf)
- tree atype_or_adecl;
- char *buf;
+gen_declaration_1 (tree atype_or_adecl, char *buf)
{
char declbuf[256];
@@ -7944,9 +8495,17 @@ gen_declaration_1 (atype_or_adecl, buf)
{
tree declspecs; /* "identifier_node", "record_type" */
tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */
+ tree width = NULL_TREE; /* for bitfields */
/* We have a "raw", abstract declarator (typename). */
declarator = TREE_VALUE (atype_or_adecl);
+ /* In the case of raw ivars, the declarator itself is a list,
+ and contains bitfield widths. */
+ if (declarator && TREE_CODE (declarator) == TREE_LIST)
+ {
+ width = TREE_VALUE (declarator);
+ declarator = TREE_PURPOSE (declarator);
+ }
declspecs = TREE_PURPOSE (atype_or_adecl);
gen_declspecs (declspecs, buf, 1);
@@ -7955,6 +8514,9 @@ gen_declaration_1 (atype_or_adecl, buf)
strcat (buf, " ");
strcat (buf, gen_declarator (declarator, declbuf, ""));
}
+ if (width)
+ sprintf (buf + strlen (buf), ": " HOST_WIDE_INT_PRINT_UNSIGNED,
+ TREE_INT_CST_LOW (width));
}
else
@@ -8025,9 +8587,7 @@ gen_declaration_1 (atype_or_adecl, buf)
buffer (overwriting) and return a pointer to the buffer. */
static char *
-gen_method_decl (method, buf)
- tree method;
- char *buf;
+gen_method_decl (tree method, char *buf)
{
tree chain;
@@ -8094,9 +8654,7 @@ gen_method_decl (method, buf)
prints out an @interface declaration of all classes compiled in
this run); potentially useful for debugging the compiler too. */
static void
-dump_interface (fp, chain)
- FILE *fp;
- tree chain;
+dump_interface (FILE *fp, tree chain)
{
/* FIXME: A heap overflow here whenever a method (or ivar)
declaration is so long that it doesn't fit in the buffer. The
@@ -8110,13 +8668,13 @@ dump_interface (fp, chain)
fprintf (fp, "\n@interface %s", my_name);
- /* CLASS_SUPER_NAME is used to store the superclass name for
+ /* CLASS_SUPER_NAME is used to store the superclass name for
classes, and the category name for categories. */
if (CLASS_SUPER_NAME (chain))
{
const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
-
- if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
+
+ if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
|| TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
{
fprintf (fp, " (%s)\n", name);
@@ -8159,8 +8717,7 @@ dump_interface (fp, chain)
/* Demangle function for Objective-C */
static const char *
-objc_demangle (mangled)
- const char *mangled;
+objc_demangle (const char *mangled)
{
char *demangled, *cp;
@@ -8215,15 +8772,13 @@ objc_demangle (mangled)
}
const char *
-objc_printable_name (decl, kind)
- tree decl;
- int kind ATTRIBUTE_UNUSED;
+objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
{
return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
}
static void
-init_objc ()
+init_objc (void)
{
gcc_obstack_init (&util_obstack);
util_firstobj = (char *) obstack_finish (&util_obstack);
@@ -8234,7 +8789,7 @@ init_objc ()
}
static void
-finish_objc ()
+finish_objc (void)
{
struct imp_entry *impent;
tree chain;
@@ -8254,10 +8809,6 @@ finish_objc ()
generate_forward_declaration_to_string_table ();
-#ifdef OBJC_PROLOGUE
- OBJC_PROLOGUE;
-#endif
-
/* Process the static instances here because initialization of objc_symtab
depends on them. */
if (objc_static_instances)
@@ -8274,7 +8825,7 @@ finish_objc ()
UOBJC_CLASS_decl = impent->class_decl;
UOBJC_METACLASS_decl = impent->meta_decl;
-
+
/* Dump the @interface of each class as we compile it, if the
-gen-decls option is in use. TODO: Dump the classes in the
order they were found, rather than in reverse order as we
@@ -8283,7 +8834,7 @@ finish_objc ()
{
dump_interface (gen_declaration_file, objc_implementation_context);
}
-
+
if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
{
/* all of the following reference the string pool... */
@@ -8306,6 +8857,9 @@ finish_objc ()
if (protocol_chain)
generate_protocols ();
+ if (flag_replace_objc_classes && imp_list)
+ generate_objc_image_info ();
+
if (objc_implementation_context || class_names_chain || objc_static_instances
|| meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
{
@@ -8343,36 +8897,12 @@ finish_objc ()
selector which has multiple methods. */
for (slot = 0; slot < SIZEHASHTABLE; slot++)
- for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
- if (hsh->list)
- {
- tree meth = hsh->key;
- char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
- ? '-' : '+');
- attr loop;
-
- warning ("potential selector conflict for method `%s'",
- IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
- warn_with_method ("found", type, meth);
- for (loop = hsh->list; loop; loop = loop->next)
- warn_with_method ("found", type, loop->value);
- }
-
- for (slot = 0; slot < SIZEHASHTABLE; slot++)
- for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
- if (hsh->list)
- {
- tree meth = hsh->key;
- char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL
- ? '-' : '+');
- attr loop;
-
- warning ("potential selector conflict for method `%s'",
- IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
- warn_with_method ("found", type, meth);
- for (loop = hsh->list; loop; loop = loop->next)
- warn_with_method ("found", type, loop->value);
- }
+ {
+ for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
+ check_duplicates (hsh, 0, 1);
+ for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
+ check_duplicates (hsh, 0, 1);
+ }
}
warn_missing_braces = save_warn_missing_braces;
@@ -8381,8 +8911,7 @@ finish_objc ()
/* Subroutines of finish_objc. */
static void
-generate_classref_translation_entry (chain)
- tree chain;
+generate_classref_translation_entry (tree chain)
{
tree expr, name, decl_specs, decl, sc_spec;
tree type;
@@ -8408,8 +8937,7 @@ generate_classref_translation_entry (chain)
}
static void
-handle_class_ref (chain)
- tree chain;
+handle_class_ref (tree chain)
{
const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
char *string = (char *) alloca (strlen (name) + 30);
@@ -8449,8 +8977,7 @@ handle_class_ref (chain)
}
static void
-handle_impent (impent)
- struct imp_entry *impent;
+handle_impent (struct imp_entry *impent)
{
char *string;
@@ -8511,10 +9038,41 @@ handle_impent (impent)
}
}
+/* The Fix-and-Countinue functionality available in Mac OS X 10.3 and
+ later requires that ObjC translation units participating in F&C be
+ specially marked. The following routine accomplishes this. */
+
+/* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
+
+static void
+generate_objc_image_info (void)
+{
+ tree sc_spec, decl, initlist;
+
+ sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
+ decl
+ = start_decl (get_identifier ("_OBJC_IMAGE_INFO"),
+ tree_cons (NULL_TREE,
+ build_array_type
+ (integer_type_node,
+ build_index_type (build_int_2 (1, 0))),
+ sc_spec),
+ 1,
+ NULL_TREE);
+
+ initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0));
+ initlist = tree_cons (NULL_TREE, build_int_2 (1, 0), initlist);
+ initlist = build_constructor (TREE_TYPE (decl), nreverse (initlist));
+
+ TREE_USED (decl) = DECL_IGNORED_P (decl) = DECL_ARTIFICIAL (decl) = 1;
+ TREE_CONSTANT (initlist) = TREE_STATIC (initlist) = 1;
+ finish_decl (decl, initlist, NULL_TREE);
+}
+
/* Look up ID as an instance variable. */
+
tree
-lookup_objc_ivar (id)
- tree id;
+lookup_objc_ivar (tree id)
{
tree decl;
@@ -8524,7 +9082,7 @@ lookup_objc_ivar (id)
else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
{
if (is_private (decl))
- return error_mark_node;
+ return 0;
else
return build_ivar_reference (id);
}
@@ -8532,4 +9090,5 @@ lookup_objc_ivar (id)
return 0;
}
+#include "gt-objc-objc-act.h"
#include "gtype-objc.h"
diff --git a/contrib/gcc/objc/objc-act.h b/contrib/gcc/objc/objc-act.h
index af10387c3978..abbf65627311 100644
--- a/contrib/gcc/objc/objc-act.h
+++ b/contrib/gcc/objc/objc-act.h
@@ -1,20 +1,21 @@
/* Declarations for objc-act.c.
- Copyright (C) 1990, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1990, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -23,57 +24,70 @@ Boston, MA 02111-1307, USA. */
/*** Public Interface (procedures) ***/
-const char *objc_init PARAMS ((const char *));
-const char *objc_printable_name PARAMS ((tree, int));
+bool objc_init (void);
+const char *objc_printable_name (tree, int);
/* used by yyparse */
-void finish_file PARAMS ((void));
-tree start_class PARAMS ((enum tree_code, tree, tree, tree));
-tree continue_class PARAMS ((tree));
-void finish_class PARAMS ((tree));
-void start_method_def PARAMS ((tree));
-void continue_method_def PARAMS ((void));
-void finish_method_def PARAMS ((void));
-tree start_protocol PARAMS ((enum tree_code, tree, tree));
-void finish_protocol PARAMS ((tree));
-void add_objc_decls PARAMS ((void));
-
-tree is_ivar PARAMS ((tree, tree));
-int is_private PARAMS ((tree));
-int is_public PARAMS ((tree, tree));
-tree add_instance_variable PARAMS ((tree, int, tree, tree, tree));
-tree add_class_method PARAMS ((tree, tree));
-tree add_instance_method PARAMS ((tree, tree));
-tree get_super_receiver PARAMS ((void));
-tree get_class_ivars PARAMS ((tree));
-tree get_class_reference PARAMS ((tree));
-tree get_static_reference PARAMS ((tree, tree));
-tree get_object_reference PARAMS ((tree));
-tree build_message_expr PARAMS ((tree));
-tree finish_message_expr PARAMS ((tree, tree, tree));
-tree build_selector_expr PARAMS ((tree));
-tree build_ivar_reference PARAMS ((tree));
-tree build_keyword_decl PARAMS ((tree, tree, tree));
-tree build_method_decl PARAMS ((enum tree_code, tree, tree, tree));
-tree build_protocol_expr PARAMS ((tree));
-tree build_objc_string_object PARAMS ((tree));
-
-void objc_declare_alias PARAMS ((tree, tree));
-void objc_declare_class PARAMS ((tree));
-void objc_declare_protocols PARAMS ((tree));
+void finish_file (void);
+tree start_class (enum tree_code, tree, tree, tree);
+tree continue_class (tree);
+void finish_class (tree);
+void start_method_def (tree);
+void continue_method_def (void);
+void finish_method_def (void);
+tree start_protocol (enum tree_code, tree, tree);
+void finish_protocol (tree);
+
+tree objc_build_throw_stmt (tree);
+tree objc_build_try_catch_finally_stmt (int, int);
+void objc_build_synchronized_prologue (tree);
+tree objc_build_synchronized_epilogue (void);
+tree objc_build_try_prologue (void);
+void objc_build_try_epilogue (int);
+void objc_build_catch_stmt (tree);
+void objc_build_catch_epilogue (void);
+tree objc_build_finally_prologue (void);
+tree objc_build_finally_epilogue (void);
+
+tree is_ivar (tree, tree);
+int is_private (tree);
+int is_public (tree, tree);
+tree add_instance_variable (tree, int, tree, tree, tree);
+tree objc_add_method (tree, tree, int);
+tree get_super_receiver (void);
+void objc_clear_super_receiver (void);
+tree get_class_ivars_from_name (tree);
+tree get_class_reference (tree);
+tree get_static_reference (tree, tree);
+tree get_object_reference (tree);
+tree build_message_expr (tree);
+tree finish_message_expr (tree, tree, tree);
+tree build_selector_expr (tree);
+tree build_ivar_reference (tree);
+tree build_keyword_decl (tree, tree, tree);
+tree build_method_decl (enum tree_code, tree, tree, tree);
+tree build_protocol_expr (tree);
+tree build_objc_string_object (tree);
+
+void objc_declare_alias (tree, tree);
+void objc_declare_class (tree);
+void objc_declare_protocols (tree);
/* the following routines are used to implement statically typed objects */
-int objc_comptypes PARAMS ((tree, tree, int));
-void objc_check_decl PARAMS ((tree));
+int objc_comptypes (tree, tree, int);
+void objc_check_decl (tree);
/* NeXT extensions */
-tree build_encode_expr PARAMS ((tree));
+tree build_encode_expr (tree);
/* Objective-C structures */
+#define CLASS_BINFO_ELTS 6
+#define PROTOCOL_BINFO_ELTS 2
+
/* KEYWORD_DECL */
#define KEYWORD_KEY_NAME(DECL) ((DECL)->decl.name)
#define KEYWORD_ARG_NAME(DECL) ((DECL)->decl.arguments)
@@ -89,7 +103,7 @@ tree build_encode_expr PARAMS ((tree));
CATEGORY_INTERFACE_TYPE, CATEGORY_IMPLEMENTATION_TYPE,
PROTOCOL_INTERFACE_TYPE */
#define CLASS_NAME(CLASS) ((CLASS)->type.name)
-#define CLASS_SUPER_NAME(CLASS) ((CLASS)->type.context)
+#define CLASS_SUPER_NAME(CLASS) (TYPE_CHECK (CLASS)->type.context)
#define CLASS_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 0)
#define CLASS_RAW_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1)
#define CLASS_NST_METHODS(CLASS) ((CLASS)->type.minval)
@@ -104,22 +118,33 @@ tree build_encode_expr PARAMS ((tree));
#define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval)
#define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1)
#define PROTOCOL_DEFINED(CLASS) TREE_USED (CLASS)
-#define TYPE_PROTOCOL_LIST(TYPE) ((TYPE)->type.context)
+/* We need to distinguish TYPE_PROTOCOL_LISTs from TYPE_CONTEXTs, both of which
+ are stored in the same accessor slot. */
+#define TYPE_PROTOCOL_LIST(TYPE) \
+ ((TYPE_CHECK (TYPE)->type.context \
+ && TREE_CODE ((TYPE)->type.context) == TREE_LIST) \
+ ? (TYPE)->type.context : NULL_TREE)
+#define SET_TYPE_PROTOCOL_LIST(TYPE, P) (TYPE_CHECK (TYPE)->type.context = (P))
/* Set by `continue_class' and checked by `is_public'. */
#define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
#define TYPED_OBJECT(type) \
(TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
+#define OBJC_TYPE_NAME(type) TYPE_NAME(type)
/* Define the Objective-C or Objective-C++ language-specific tree codes. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
enum objc_tree_code {
-#ifdef OBJCPLUS
+#if defined (GCC_CP_TREE_H)
LAST_BASE_TREE_CODE = LAST_CPLUS_TREE_CODE,
-#else
+#else
+#if defined (GCC_C_TREE_H)
LAST_BASE_TREE_CODE = LAST_C_TREE_CODE,
+#else
+ #error You must include <c-tree.h> or <cp/cp-tree.h> before <objc/objc-act.h>
+#endif
#endif
#include "objc-tree.def"
LAST_OBJC_TREE_CODE
@@ -146,7 +171,7 @@ struct hashed_entry GTY(())
extern GTY ((length ("SIZEHASHTABLE"))) hash *nst_method_hash_list;
extern GTY ((length ("SIZEHASHTABLE"))) hash *cls_method_hash_list;
-#define SIZEHASHTABLE 257
+#define SIZEHASHTABLE 257
/* Objective-C/Objective-C++ @implementation list. */
@@ -177,6 +202,8 @@ enum objc_tree_index
OCTI_SELF_DECL,
OCTI_UMSG_DECL,
OCTI_UMSG_SUPER_DECL,
+ OCTI_UMSG_STRET_DECL,
+ OCTI_UMSG_SUPER_STRET_DECL,
OCTI_GET_CLASS_DECL,
OCTI_GET_MCLASS_DECL,
OCTI_SUPER_TYPE,
@@ -240,7 +267,25 @@ enum objc_tree_index
OCTI_CNST_STR_GLOB_ID,
OCTI_STRING_CLASS_DECL,
OCTI_SUPER_DECL,
-
+ OCTI_UMSG_NONNIL_DECL,
+ OCTI_UMSG_NONNIL_STRET_DECL,
+ OCTI_STORAGE_CLS,
+ OCTI_EXCEPTION_EXTRACT_DECL,
+ OCTI_EXCEPTION_TRY_ENTER_DECL,
+ OCTI_EXCEPTION_TRY_EXIT_DECL,
+ OCTI_EXCEPTION_MATCH_DECL,
+ OCTI_EXCEPTION_THROW_DECL,
+ OCTI_SYNC_ENTER_DECL,
+ OCTI_SYNC_EXIT_DECL,
+ OCTI_SETJMP_DECL,
+ OCTI_EXCDATA_TEMPL,
+ OCTI_STACK_EXCEPTION_DATA_DECL,
+ OCTI_LOCAL_EXCEPTION_DECL,
+ OCTI_RETHROW_EXCEPTION_DECL,
+ OCTI_EVAL_ONCE_DECL,
+ OCTI_EXCEPTION_BLK_STACK,
+ OCTI_CATCH_TYPE,
+
OCTI_MAX
};
@@ -262,6 +307,8 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX];
#define self_decl objc_global_trees[OCTI_SELF_DECL]
#define umsg_decl objc_global_trees[OCTI_UMSG_DECL]
#define umsg_super_decl objc_global_trees[OCTI_UMSG_SUPER_DECL]
+#define umsg_stret_decl objc_global_trees[OCTI_UMSG_STRET_DECL]
+#define umsg_super_stret_decl objc_global_trees[OCTI_UMSG_SUPER_STRET_DECL]
#define objc_get_class_decl objc_global_trees[OCTI_GET_CLASS_DECL]
#define objc_get_meta_class_decl \
objc_global_trees[OCTI_GET_MCLASS_DECL]
@@ -280,7 +327,7 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX];
#define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
(IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
#define IS_SUPER(TYPE) \
- (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
+ (TREE_CODE (TYPE) == POINTER_TYPE && TREE_TYPE (TYPE) == objc_super_template)
#define class_chain objc_global_trees[OCTI_CLS_CHAIN]
#define alias_chain objc_global_trees[OCTI_ALIAS_CHAIN]
@@ -334,6 +381,33 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX];
#define ucls_super_ref objc_global_trees[OCTI_UCLS_SUPER_REF]
#define uucls_super_ref objc_global_trees[OCTI_UUCLS_SUPER_REF]
+#define umsg_nonnil_decl objc_global_trees[OCTI_UMSG_NONNIL_DECL]
+#define umsg_nonnil_stret_decl objc_global_trees[OCTI_UMSG_NONNIL_STRET_DECL]
+#define objc_storage_class objc_global_trees[OCTI_STORAGE_CLS]
+#define objc_exception_extract_decl \
+ objc_global_trees[OCTI_EXCEPTION_EXTRACT_DECL]
+#define objc_exception_try_enter_decl \
+ objc_global_trees[OCTI_EXCEPTION_TRY_ENTER_DECL]
+#define objc_exception_try_exit_decl \
+ objc_global_trees[OCTI_EXCEPTION_TRY_EXIT_DECL]
+#define objc_exception_match_decl \
+ objc_global_trees[OCTI_EXCEPTION_MATCH_DECL]
+#define objc_exception_throw_decl \
+ objc_global_trees[OCTI_EXCEPTION_THROW_DECL]
+#define objc_sync_enter_decl objc_global_trees[OCTI_SYNC_ENTER_DECL]
+#define objc_sync_exit_decl objc_global_trees[OCTI_SYNC_EXIT_DECL]
+#define objc_exception_data_template \
+ objc_global_trees[OCTI_EXCDATA_TEMPL]
+#define objc_setjmp_decl objc_global_trees[OCTI_SETJMP_DECL]
+#define objc_stack_exception_data \
+ objc_global_trees[OCTI_STACK_EXCEPTION_DATA_DECL]
+#define objc_caught_exception objc_global_trees[OCTI_LOCAL_EXCEPTION_DECL]
+#define objc_rethrow_exception objc_global_trees[OCTI_RETHROW_EXCEPTION_DECL]
+#define objc_eval_once objc_global_trees[OCTI_EVAL_ONCE_DECL]
+#define objc_exception_block_stack \
+ objc_global_trees[OCTI_EXCEPTION_BLK_STACK]
+#define objc_catch_type objc_global_trees[OCTI_CATCH_TYPE]
+
#define objc_method_template objc_global_trees[OCTI_METH_TEMPL]
#define objc_ivar_template objc_global_trees[OCTI_IVAR_TEMPL]
#define objc_symtab_template objc_global_trees[OCTI_SYMTAB_TEMPL]
@@ -344,7 +418,7 @@ extern GTY(()) tree objc_global_trees[OCTI_MAX];
objc_global_trees[OCTI_METH_PROTO_TEMPL]
#define function1_template objc_global_trees[OCTI_FUNCTION1_TEMPL]
#define function2_template objc_global_trees[OCTI_FUNCTION2_TEMPL]
-
+
#define objc_object_id objc_global_trees[OCTI_OBJ_ID]
#define objc_class_id objc_global_trees[OCTI_CLS_ID]
#define objc_id_id objc_global_trees[OCTI_ID_ID]
diff --git a/contrib/gcc/objc/objc-lang.c b/contrib/gcc/objc/objc-lang.c
index 73e6204c43b2..3f70122302c4 100644
--- a/contrib/gcc/objc/objc-lang.c
+++ b/contrib/gcc/objc/objc-lang.c
@@ -1,26 +1,28 @@
/* Language-dependent hooks for Objective-C.
- Copyright 2001, 2002 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Ziemowit Laski <zlaski@apple.com>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "c-tree.h"
#include "c-common.h"
@@ -29,7 +31,7 @@ Boston, MA 02111-1307, USA. */
#include "langhooks.h"
#include "langhooks-def.h"
-static void objc_init_options PARAMS ((void));
+enum c_language_kind c_language = clk_objc;
#undef LANG_HOOKS_NAME
#define LANG_HOOKS_NAME "GNU Objective-C"
@@ -38,9 +40,13 @@ static void objc_init_options PARAMS ((void));
#undef LANG_HOOKS_FINISH
#define LANG_HOOKS_FINISH c_common_finish
#undef LANG_HOOKS_INIT_OPTIONS
-#define LANG_HOOKS_INIT_OPTIONS objc_init_options
-#undef LANG_HOOKS_DECODE_OPTION
-#define LANG_HOOKS_DECODE_OPTION c_common_decode_option
+#define LANG_HOOKS_INIT_OPTIONS c_common_init_options
+#undef LANG_HOOKS_HANDLE_OPTION
+#define LANG_HOOKS_HANDLE_OPTION c_common_handle_option
+#undef LANG_HOOKS_HANDLE_FILENAME
+#define LANG_HOOKS_HANDLE_FILENAME c_common_handle_filename
+#undef LANG_HOOKS_MISSING_ARGUMENT
+#define LANG_HOOKS_MISSING_ARGUMENT c_common_missing_argument
#undef LANG_HOOKS_POST_OPTIONS
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
#undef LANG_HOOKS_GET_ALIAS_SET
@@ -55,14 +61,16 @@ static void objc_init_options PARAMS ((void));
#define LANG_HOOKS_MARK_ADDRESSABLE c_mark_addressable
#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion
-#undef LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES
-#define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES c_insert_default_attributes
#undef LANG_HOOKS_FINISH_INCOMPLETE_DECL
#define LANG_HOOKS_FINISH_INCOMPLETE_DECL c_finish_incomplete_decl
#undef LANG_HOOKS_UNSAFE_FOR_REEVAL
#define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval
#undef LANG_HOOKS_STATICP
#define LANG_HOOKS_STATICP c_staticp
+#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
+#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME c_static_assembler_name
+#undef LANG_HOOKS_NO_BODY_BLOCKS
+#define LANG_HOOKS_NO_BODY_BLOCKS true
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL c_dup_lang_specific_decl
#undef LANG_HOOKS_PRINT_IDENTIFIER
@@ -71,12 +79,17 @@ static void objc_init_options PARAMS ((void));
#define LANG_HOOKS_DECL_PRINTABLE_NAME objc_printable_name
#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL c_warn_unused_global_decl
+#undef LANG_HOOKS_DECL_UNINIT
+#define LANG_HOOKS_DECL_UNINIT c_decl_uninit
#undef LANG_HOOKS_FUNCTION_ENTER_NESTED
#define LANG_HOOKS_FUNCTION_ENTER_NESTED c_push_function_context
#undef LANG_HOOKS_FUNCTION_LEAVE_NESTED
#define LANG_HOOKS_FUNCTION_LEAVE_NESTED c_pop_function_context
+#undef LANG_HOOKS_RTL_EXPAND_STMT
+#define LANG_HOOKS_RTL_EXPAND_STMT expand_stmt
+
/* Attribute hooks. */
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE c_common_attribute_table
@@ -96,6 +109,11 @@ static void objc_init_options PARAMS ((void));
#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING
#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
c_convert_parm_for_inlining
+#undef LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS
+#define LANG_HOOKS_TREE_INLINING_ESTIMATE_NUM_INSNS c_estimate_num_insns
+
+#undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
+#define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION c_expand_body
#undef LANG_HOOKS_TYPE_FOR_MODE
#define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode
@@ -112,6 +130,9 @@ static void objc_init_options PARAMS ((void));
#undef LANG_HOOKS_TYPE_PROMOTES_TO
#define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to
+#undef LANG_HOOKS_WRITE_GLOBALS
+#define LANG_HOOKS_WRITE_GLOBALS c_write_global_declarations
+
/* Each front end provides its own hooks, for toplev.c. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@@ -158,10 +179,3 @@ const char * const tree_code_name[] = {
#include "objc-tree.def"
};
#undef DEFTREECODE
-
-static void
-objc_init_options ()
-{
- flag_objc = 1;
- c_common_init_options (clk_c);
-}
diff --git a/contrib/gcc/objc/objc-tree.def b/contrib/gcc/objc/objc-tree.def
index 979556f0fa15..aa2e40feb0b0 100644
--- a/contrib/gcc/objc/objc-tree.def
+++ b/contrib/gcc/objc/objc-tree.def
@@ -1,23 +1,23 @@
/* This file contains the definitions and documentation for the
additional tree codes used in the Objective C front end (see tree.def
for the standard codes).
- Copyright (C) 1990, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1990, 1997, 1998, 1999, 2000, 2001, 2003
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -33,3 +33,7 @@ DEFTREECODE (PROTOCOL_INTERFACE_TYPE, "protocol_interface_type", 't', 0)
DEFTREECODE (KEYWORD_DECL, "keyword_decl", 'd', 0)
DEFTREECODE (INSTANCE_METHOD_DECL, "instance_method_decl", 'd', 0)
DEFTREECODE (CLASS_METHOD_DECL, "class_method_decl", 'd', 0)
+
+/* Objective-C expressions. */
+DEFTREECODE (MESSAGE_SEND_EXPR, "message_send_expr", 'e', 3)
+DEFTREECODE (CLASS_REFERENCE_EXPR, "class_reference_expr", 'e', 1)
diff --git a/contrib/gcc/obstack.h b/contrib/gcc/obstack.h
index d86d9f2c4263..5496ff24071a 100644
--- a/contrib/gcc/obstack.h
+++ b/contrib/gcc/obstack.h
@@ -343,7 +343,7 @@ extern int obstack_exit_failure;
#endif
-#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
+#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))
#define obstack_blank_fast(h,n) ((h)->next_free += (n))
@@ -411,7 +411,7 @@ __extension__ \
({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + 1 > __o->chunk_limit) \
_obstack_newchunk (__o, 1); \
- *(__o->next_free)++ = (datum); \
+ obstack_1grow_fast (__o, datum); \
(void) 0; })
/* These assume that the obstack alignment is good enough for pointers or ints,
@@ -423,19 +423,28 @@ __extension__ \
({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
_obstack_newchunk (__o, sizeof (void *)); \
- *((void **)__o->next_free)++ = ((void *)datum); \
- (void) 0; })
+ obstack_ptr_grow_fast (__o, datum); })
# define obstack_int_grow(OBSTACK,datum) \
__extension__ \
({ struct obstack *__o = (OBSTACK); \
if (__o->next_free + sizeof (int) > __o->chunk_limit) \
_obstack_newchunk (__o, sizeof (int)); \
- *((int *)__o->next_free)++ = ((int)datum); \
+ obstack_int_grow_fast (__o, datum); })
+
+# define obstack_ptr_grow_fast(OBSTACK,aptr) \
+__extension__ \
+({ struct obstack *__o1 = (OBSTACK); \
+ *(const void **) __o1->next_free = (aptr); \
+ __o1->next_free += sizeof (const void *); \
(void) 0; })
-# define obstack_ptr_grow_fast(h,aptr) (*((void **) (h)->next_free)++ = (void *)aptr)
-# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint)
+# define obstack_int_grow_fast(OBSTACK,aint) \
+__extension__ \
+({ struct obstack *__o1 = (OBSTACK); \
+ *(int *) __o1->next_free = (aint); \
+ __o1->next_free += sizeof (int); \
+ (void) 0; })
# define obstack_blank(OBSTACK,length) \
__extension__ \
@@ -443,7 +452,7 @@ __extension__ \
int __len = (length); \
if (__o->chunk_limit - __o->next_free < __len) \
_obstack_newchunk (__o, __len); \
- __o->next_free += __len; \
+ obstack_blank_fast (__o, __len); \
(void) 0; })
# define obstack_alloc(OBSTACK,length) \
@@ -530,26 +539,29 @@ __extension__ \
# define obstack_1grow(h,datum) \
( (((h)->next_free + 1 > (h)->chunk_limit) \
? (_obstack_newchunk ((h), 1), 0) : 0), \
- (*((h)->next_free)++ = (datum)))
+ obstack_1grow_fast (h, datum))
# define obstack_ptr_grow(h,datum) \
( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
- (*((char **) (((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *) datum)))
+ obstack_ptr_grow_fast (h, datum))
# define obstack_int_grow(h,datum) \
( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
- (*((int *) (((h)->next_free+=sizeof(int))-sizeof(int))) = ((int) datum)))
+ obstack_int_grow_fast (h, datum))
+
+# define obstack_ptr_grow_fast(h,aptr) \
+ (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
-# define obstack_ptr_grow_fast(h,aptr) (*((char **) (h)->next_free)++ = (char *) aptr)
-# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint)
+# define obstack_int_grow_fast(h,aint) \
+ (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr))
# define obstack_blank(h,length) \
( (h)->temp = (length), \
(((h)->chunk_limit - (h)->next_free < (h)->temp) \
? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
- ((h)->next_free += (h)->temp))
+ obstack_blank_fast (h, (h)->temp))
# define obstack_alloc(h,length) \
(obstack_blank ((h), (length)), obstack_finish ((h)))
diff --git a/contrib/gcc/optabs.c b/contrib/gcc/optabs.c
index d4eb640a71cb..3d85a06fc38e 100644
--- a/contrib/gcc/optabs.c
+++ b/contrib/gcc/optabs.c
@@ -1,6 +1,6 @@
/* Expand the basic unary and binary arithmetic operations, for GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
/* Include insn-config.h before expr.h so that HAVE_conditional_move
@@ -41,6 +43,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "real.h"
#include "basic-block.h"
+#include "target.h"
/* Each optab contains info on how this target machine
can perform a particular operation
@@ -55,13 +58,8 @@ optab optab_table[OTI_MAX];
rtx libfunc_table[LTI_MAX];
-/* Tables of patterns for extending one integer mode to another. */
-enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
-
-/* Tables of patterns for converting between fixed and floating point. */
-enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
-enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
-enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
+/* Tables of patterns for converting one mode to another. */
+convert_optab convert_optab_table[CTI_MAX];
/* Contains the optab used for each rtx code. */
optab code_to_optab[NUM_RTX_CODE + 1];
@@ -91,41 +89,44 @@ enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
the code to be used in the trap insn and all other fields are ignored. */
static GTY(()) rtx trap_rtx;
-static int add_equal_note PARAMS ((rtx, rtx, enum rtx_code, rtx, rtx));
-static rtx widen_operand PARAMS ((rtx, enum machine_mode,
- enum machine_mode, int, int));
-static int expand_cmplxdiv_straight PARAMS ((rtx, rtx, rtx, rtx,
- rtx, rtx, enum machine_mode,
- int, enum optab_methods,
- enum mode_class, optab));
-static int expand_cmplxdiv_wide PARAMS ((rtx, rtx, rtx, rtx,
- rtx, rtx, enum machine_mode,
- int, enum optab_methods,
- enum mode_class, optab));
-static void prepare_cmp_insn PARAMS ((rtx *, rtx *, enum rtx_code *, rtx,
- enum machine_mode *, int *,
- enum can_compare_purpose));
-static enum insn_code can_fix_p PARAMS ((enum machine_mode, enum machine_mode,
- int, int *));
-static enum insn_code can_float_p PARAMS ((enum machine_mode,
- enum machine_mode,
- int));
-static rtx ftruncify PARAMS ((rtx));
-static optab new_optab PARAMS ((void));
-static inline optab init_optab PARAMS ((enum rtx_code));
-static inline optab init_optabv PARAMS ((enum rtx_code));
-static void init_libfuncs PARAMS ((optab, int, int, const char *, int));
-static void init_integral_libfuncs PARAMS ((optab, const char *, int));
-static void init_floating_libfuncs PARAMS ((optab, const char *, int));
-static void emit_cmp_and_jump_insn_1 PARAMS ((rtx, rtx, enum machine_mode,
- enum rtx_code, int, rtx));
-static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
- enum machine_mode *, int *));
-static rtx expand_vector_binop PARAMS ((enum machine_mode, optab,
- rtx, rtx, rtx, int,
- enum optab_methods));
-static rtx expand_vector_unop PARAMS ((enum machine_mode, optab, rtx, rtx,
- int));
+static int add_equal_note (rtx, rtx, enum rtx_code, rtx, rtx);
+static rtx widen_operand (rtx, enum machine_mode, enum machine_mode, int,
+ int);
+static int expand_cmplxdiv_straight (rtx, rtx, rtx, rtx, rtx, rtx,
+ enum machine_mode, int,
+ enum optab_methods, enum mode_class,
+ optab);
+static int expand_cmplxdiv_wide (rtx, rtx, rtx, rtx, rtx, rtx,
+ enum machine_mode, int, enum optab_methods,
+ enum mode_class, optab);
+static void prepare_cmp_insn (rtx *, rtx *, enum rtx_code *, rtx,
+ enum machine_mode *, int *,
+ enum can_compare_purpose);
+static enum insn_code can_fix_p (enum machine_mode, enum machine_mode, int,
+ int *);
+static enum insn_code can_float_p (enum machine_mode, enum machine_mode, int);
+static rtx ftruncify (rtx);
+static optab new_optab (void);
+static convert_optab new_convert_optab (void);
+static inline optab init_optab (enum rtx_code);
+static inline optab init_optabv (enum rtx_code);
+static inline convert_optab init_convert_optab (enum rtx_code);
+static void init_libfuncs (optab, int, int, const char *, int);
+static void init_integral_libfuncs (optab, const char *, int);
+static void init_floating_libfuncs (optab, const char *, int);
+static void init_interclass_conv_libfuncs (convert_optab, const char *,
+ enum mode_class, enum mode_class);
+static void init_intraclass_conv_libfuncs (convert_optab, const char *,
+ enum mode_class, bool);
+static void emit_cmp_and_jump_insn_1 (rtx, rtx, enum machine_mode,
+ enum rtx_code, int, rtx);
+static void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *,
+ enum machine_mode *, int *);
+static rtx expand_vector_binop (enum machine_mode, optab, rtx, rtx, rtx, int,
+ enum optab_methods);
+static rtx expand_vector_unop (enum machine_mode, optab, rtx, rtx, int);
+static rtx widen_clz (enum machine_mode, rtx, rtx);
+static rtx expand_parity (enum machine_mode, rtx, rtx);
#ifndef HAVE_conditional_trap
#define HAVE_conditional_trap 0
@@ -143,11 +144,7 @@ static rtx expand_vector_unop PARAMS ((enum machine_mode, optab, rtx, rtx,
again, ensuring that TARGET is not one of the operands. */
static int
-add_equal_note (insns, target, code, op0, op1)
- rtx insns;
- rtx target;
- enum rtx_code code;
- rtx op0, op1;
+add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
{
rtx last_insn, insn, set;
rtx note;
@@ -174,11 +171,9 @@ add_equal_note (insns, target, code, op0, op1)
return 1;
if (! rtx_equal_p (SET_DEST (set), target)
- /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
- SUBREG. */
+ /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
&& (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
- || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
- target)))
+ || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
return 1;
/* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
@@ -208,16 +203,13 @@ add_equal_note (insns, target, code, op0, op1)
/* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
- not actually do a sign-extend or zero-extend, but can leave the
+ not actually do a sign-extend or zero-extend, but can leave the
higher-order bits of the result rtx undefined, for example, in the case
of logical operations, but not right shifts. */
static rtx
-widen_operand (op, mode, oldmode, unsignedp, no_extend)
- rtx op;
- enum machine_mode mode, oldmode;
- int unsignedp;
- int no_extend;
+widen_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode,
+ int unsignedp, int no_extend)
{
rtx result;
@@ -250,14 +242,10 @@ widen_operand (op, mode, oldmode, unsignedp, no_extend)
/* Generate code to perform a straightforward complex divide. */
static int
-expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
- unsignedp, methods, class, binoptab)
- rtx real0, real1, imag0, imag1, realr, imagr;
- enum machine_mode submode;
- int unsignedp;
- enum optab_methods methods;
- enum mode_class class;
- optab binoptab;
+expand_cmplxdiv_straight (rtx real0, rtx real1, rtx imag0, rtx imag1,
+ rtx realr, rtx imagr, enum machine_mode submode,
+ int unsignedp, enum optab_methods methods,
+ enum mode_class class, optab binoptab)
{
rtx divisor;
rtx real_t, imag_t;
@@ -267,7 +255,7 @@ expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
optab this_sub_optab = sub_optab;
optab this_neg_optab = neg_optab;
optab this_mul_optab = smul_optab;
-
+
if (binoptab == sdivv_optab)
{
this_add_optab = addv_optab;
@@ -308,7 +296,7 @@ expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
/* Calculate the dividend. */
real_t = expand_binop (submode, this_mul_optab, real0, real1,
NULL_RTX, unsignedp, methods);
-
+
imag_t = expand_binop (submode, this_mul_optab, real0, imag1,
NULL_RTX, unsignedp, methods);
@@ -333,7 +321,7 @@ expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
real_t = expand_binop (submode, this_add_optab, temp1, temp2,
NULL_RTX, unsignedp, methods);
-
+
temp1 = expand_binop (submode, this_mul_optab, imag0, real1,
NULL_RTX, unsignedp, methods);
@@ -382,14 +370,10 @@ expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
/* Generate code to perform a wide-input-range-acceptable complex divide. */
static int
-expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode,
- unsignedp, methods, class, binoptab)
- rtx real0, real1, imag0, imag1, realr, imagr;
- enum machine_mode submode;
- int unsignedp;
- enum optab_methods methods;
- enum mode_class class;
- optab binoptab;
+expand_cmplxdiv_wide (rtx real0, rtx real1, rtx imag0, rtx imag1, rtx realr,
+ rtx imagr, enum machine_mode submode, int unsignedp,
+ enum optab_methods methods, enum mode_class class,
+ optab binoptab)
{
rtx ratio, divisor;
rtx real_t, imag_t;
@@ -408,7 +392,7 @@ expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode,
this_neg_optab = negv_optab;
this_mul_optab = smulv_optab;
}
-
+
/* Don't fetch these from memory more than once. */
real0 = force_reg (submode, real0);
real1 = force_reg (submode, real1);
@@ -646,13 +630,9 @@ expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode,
the operation to perform, not an optab pointer. All other
arguments are the same. */
rtx
-expand_simple_binop (mode, code, op0, op1, target, unsignedp, methods)
- enum machine_mode mode;
- enum rtx_code code;
- rtx op0, op1;
- rtx target;
- int unsignedp;
- enum optab_methods methods;
+expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
+ rtx op1, rtx target, int unsignedp,
+ enum optab_methods methods)
{
optab binop = code_to_optab[(int) code];
if (binop == 0)
@@ -673,13 +653,8 @@ expand_simple_binop (mode, code, op0, op1, target, unsignedp, methods)
this may or may not be TARGET. */
rtx
-expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
- enum machine_mode mode;
- optab binoptab;
- rtx op0, op1;
- rtx target;
- int unsignedp;
- enum optab_methods methods;
+expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
+ rtx target, int unsignedp, enum optab_methods methods)
{
enum optab_methods next_methods
= (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
@@ -705,8 +680,17 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
if (flag_force_mem)
{
- op0 = force_not_mem (op0);
- op1 = force_not_mem (op1);
+ /* Load duplicate non-volatile operands once. */
+ if (rtx_equal_p (op0, op1) && ! volatile_refs_p (op0))
+ {
+ op0 = force_not_mem (op0);
+ op1 = op0;
+ }
+ else
+ {
+ op0 = force_not_mem (op0);
+ op1 = force_not_mem (op1);
+ }
}
/* If subtracting an integer constant, convert this into an addition of
@@ -1066,7 +1050,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
if (inter != 0)
inter = expand_binop (word_mode, binoptab, outof_input,
op1, outof_target, unsignedp, next_methods);
-
+
if (inter != 0 && inter != outof_target)
emit_move_insn (outof_target, inter);
}
@@ -1272,7 +1256,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
if (i > 0)
{
rtx newx;
-
+
/* Add/subtract previous carry to main result. */
newx = expand_binop (word_mode,
normalizep == 1 ? binoptab : otheroptab,
@@ -1300,16 +1284,17 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
}
carry_in = carry_out;
- }
+ }
if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
{
- if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
+ if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
+ || ! rtx_equal_p (target, xtarget))
{
rtx temp = emit_move_insn (target, xtarget);
set_unique_reg_note (temp,
- REG_EQUAL,
+ REG_EQUAL,
gen_rtx_fmt_ee (binoptab->code, mode,
copy_rtx (xop0),
copy_rtx (xop1)));
@@ -1327,7 +1312,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
/* If we want to multiply two two-word values and have normal and widening
multiplies of single-word values, we can do this with three smaller
multiplications. Note that we do not make a REG_NO_CONFLICT block here
- because we are not operating on one word at a time.
+ because we are not operating on one word at a time.
The multiplication proceeds as follows:
_______________________
@@ -1481,7 +1466,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
emit_move_insn (product_high, temp);
if (temp != 0)
- temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
+ temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
NULL_RTX, 0, OPTAB_DIRECT);
if (temp != 0)
@@ -1500,7 +1485,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
{
temp = emit_move_insn (product, product);
set_unique_reg_note (temp,
- REG_EQUAL,
+ REG_EQUAL,
gen_rtx_fmt_ee (MULT, mode,
copy_rtx (op0),
copy_rtx (op1)));
@@ -1536,24 +1521,17 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
rtx real0 = 0, imag0 = 0;
rtx real1 = 0, imag1 = 0;
rtx realr, imagr, res;
- rtx seq;
- rtx equiv_value;
+ rtx seq, result;
int ok = 0;
- /* Find the correct mode for the real and imaginary parts */
- enum machine_mode submode = GET_MODE_INNER(mode);
+ /* Find the correct mode for the real and imaginary parts. */
+ enum machine_mode submode = GET_MODE_INNER (mode);
if (submode == BLKmode)
abort ();
- if (! target)
- target = gen_reg_rtx (mode);
-
start_sequence ();
- realr = gen_realpart (submode, target);
- imagr = gen_imagpart (submode, target);
-
if (GET_MODE (op0) == mode)
{
real0 = gen_realpart (submode, op0);
@@ -1573,6 +1551,10 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
if (real0 == 0 || real1 == 0 || ! (imag0 != 0 || imag1 != 0))
abort ();
+ result = gen_reg_rtx (mode);
+ realr = gen_realpart (submode, result);
+ imagr = gen_imagpart (submode, result);
+
switch (binoptab->code)
{
case PLUS:
@@ -1642,8 +1624,13 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
temp1 = expand_binop (submode, binoptab, real0, imag1,
NULL_RTX, unsignedp, methods);
- temp2 = expand_binop (submode, binoptab, real1, imag0,
- NULL_RTX, unsignedp, methods);
+ /* Avoid expanding redundant multiplication for the common
+ case of squaring a complex number. */
+ if (rtx_equal_p (real0, real1) && rtx_equal_p (imag0, imag1))
+ temp2 = temp1;
+ else
+ temp2 = expand_binop (submode, binoptab, real1, imag0,
+ NULL_RTX, unsignedp, methods);
if (temp1 == 0 || temp2 == 0)
break;
@@ -1691,7 +1678,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
case DIV:
/* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
-
+
if (imag1 == 0)
{
/* (a+ib) / (c+i0) = (a/c) + i(b/c) */
@@ -1749,7 +1736,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
}
}
break;
-
+
default:
abort ();
}
@@ -1759,16 +1746,10 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
if (ok)
{
- if (binoptab->code != UNKNOWN)
- equiv_value
- = gen_rtx_fmt_ee (binoptab->code, mode,
- copy_rtx (op0), copy_rtx (op1));
- else
- equiv_value = 0;
-
- emit_no_conflict_block (seq, target, op0, op1, equiv_value);
-
- return target;
+ rtx equiv = gen_rtx_fmt_ee (binoptab->code, mode,
+ copy_rtx (op0), copy_rtx (op1));
+ emit_no_conflict_block (seq, result, op0, op1, equiv);
+ return result;
}
}
@@ -1891,13 +1872,9 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
/* Like expand_binop, but for open-coding vectors binops. */
static rtx
-expand_vector_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
- enum machine_mode mode;
- optab binoptab;
- rtx op0, op1;
- rtx target;
- int unsignedp;
- enum optab_methods methods;
+expand_vector_binop (enum machine_mode mode, optab binoptab, rtx op0,
+ rtx op1, rtx target, int unsignedp,
+ enum optab_methods methods)
{
enum machine_mode submode, tmode;
int size, elts, subsize, subbitsize, i;
@@ -2018,12 +1995,8 @@ expand_vector_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
/* Like expand_unop but for open-coding vector unops. */
static rtx
-expand_vector_unop (mode, unoptab, op0, target, unsignedp)
- enum machine_mode mode;
- optab unoptab;
- rtx op0;
- rtx target;
- int unsignedp;
+expand_vector_unop (enum machine_mode mode, optab unoptab, rtx op0,
+ rtx target, int unsignedp)
{
enum machine_mode submode, tmode;
int size, elts, subsize, subbitsize, i;
@@ -2049,7 +2022,7 @@ expand_vector_unop (mode, unoptab, op0, target, unsignedp)
/* Avoid infinite recursion when an
error has left us with the wrong mode. */
&& GET_MODE (op0) == mode)
- {
+ {
rtx temp;
temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
target, unsignedp, OPTAB_DIRECT);
@@ -2122,12 +2095,9 @@ expand_vector_unop (mode, unoptab, op0, target, unsignedp)
of an unsigned wider operation, since the result would be the same. */
rtx
-sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
- enum machine_mode mode;
- optab uoptab, soptab;
- rtx op0, op1, target;
- int unsignedp;
- enum optab_methods methods;
+sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
+ rtx op0, rtx op1, rtx target, int unsignedp,
+ enum optab_methods methods)
{
rtx temp;
optab direct_optab = unsignedp ? uoptab : soptab;
@@ -2184,11 +2154,8 @@ sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
Returns 1 if this operation can be performed; 0 if not. */
int
-expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
- optab binoptab;
- rtx op0, op1;
- rtx targ0, targ1;
- int unsignedp;
+expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
+ int unsignedp)
{
enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
enum mode_class class;
@@ -2269,7 +2236,7 @@ expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
|| ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
abort ();
-
+
pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
if (pat)
{
@@ -2316,12 +2283,8 @@ expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
the operation to perform, not an optab pointer. All other
arguments are the same. */
rtx
-expand_simple_unop (mode, code, op0, target, unsignedp)
- enum machine_mode mode;
- enum rtx_code code;
- rtx op0;
- rtx target;
- int unsignedp;
+expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
+ rtx target, int unsignedp)
{
optab unop = code_to_optab[(int) code];
if (unop == 0)
@@ -2330,6 +2293,83 @@ expand_simple_unop (mode, code, op0, target, unsignedp)
return expand_unop (mode, unop, op0, target, unsignedp);
}
+/* Try calculating
+ (clz:narrow x)
+ as
+ (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)). */
+static rtx
+widen_clz (enum machine_mode mode, rtx op0, rtx target)
+{
+ enum mode_class class = GET_MODE_CLASS (mode);
+ if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
+ {
+ enum machine_mode wider_mode;
+ for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
+ wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+ {
+ if (clz_optab->handlers[(int) wider_mode].insn_code
+ != CODE_FOR_nothing)
+ {
+ rtx xop0, temp, last;
+
+ last = get_last_insn ();
+
+ if (target == 0)
+ target = gen_reg_rtx (mode);
+ xop0 = widen_operand (op0, wider_mode, mode, true, false);
+ temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
+ if (temp != 0)
+ temp = expand_binop (wider_mode, sub_optab, temp,
+ GEN_INT (GET_MODE_BITSIZE (wider_mode)
+ - GET_MODE_BITSIZE (mode)),
+ target, true, OPTAB_DIRECT);
+ if (temp == 0)
+ delete_insns_since (last);
+
+ return temp;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Try calculating (parity x) as (and (popcount x) 1), where
+ popcount can also be done in a wider mode. */
+static rtx
+expand_parity (enum machine_mode mode, rtx op0, rtx target)
+{
+ enum mode_class class = GET_MODE_CLASS (mode);
+ if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
+ {
+ enum machine_mode wider_mode;
+ for (wider_mode = mode; wider_mode != VOIDmode;
+ wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+ {
+ if (popcount_optab->handlers[(int) wider_mode].insn_code
+ != CODE_FOR_nothing)
+ {
+ rtx xop0, temp, last;
+
+ last = get_last_insn ();
+
+ if (target == 0)
+ target = gen_reg_rtx (mode);
+ xop0 = widen_operand (op0, wider_mode, mode, true, false);
+ temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
+ true);
+ if (temp != 0)
+ temp = expand_binop (wider_mode, and_optab, temp, GEN_INT (1),
+ target, true, OPTAB_DIRECT);
+ if (temp == 0)
+ delete_insns_since (last);
+
+ return temp;
+ }
+ }
+ }
+ return 0;
+}
+
/* Generate code to perform an operation specified by UNOPTAB
on operand OP0, with result having machine-mode MODE.
@@ -2342,12 +2382,8 @@ expand_simple_unop (mode, code, op0, target, unsignedp)
this may or may not be TARGET. */
rtx
-expand_unop (mode, unoptab, op0, target, unsignedp)
- enum machine_mode mode;
- optab unoptab;
- rtx op0;
- rtx target;
- int unsignedp;
+expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
+ int unsignedp)
{
enum mode_class class;
enum machine_mode wider_mode;
@@ -2401,7 +2437,7 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
}
emit_insn (pat);
-
+
return temp;
}
else
@@ -2410,6 +2446,16 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
/* It can't be done in this mode. Can we open-code it in a wider mode? */
+ /* Widening clz needs special treatment. */
+ if (unoptab == clz_optab)
+ {
+ temp = widen_clz (mode, op0, target);
+ if (temp)
+ return temp;
+ else
+ goto try_libcall;
+ }
+
if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
wider_mode = GET_MODE_WIDER_MODE (wider_mode))
@@ -2426,7 +2472,7 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
(unoptab == neg_optab
|| unoptab == one_cmpl_optab)
&& class == MODE_INT);
-
+
temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
unsignedp);
@@ -2490,7 +2536,7 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
rtx x;
rtx seq;
- /* Find the correct mode for the real and imaginary parts */
+ /* Find the correct mode for the real and imaginary parts. */
enum machine_mode submode = GET_MODE_INNER (mode);
if (submode == BLKmode)
@@ -2498,7 +2544,7 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
if (target == 0)
target = gen_reg_rtx (mode);
-
+
start_sequence ();
target_piece = gen_imagpart (submode, target);
@@ -2524,22 +2570,90 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
return target;
}
+ /* Try negating floating point values by flipping the sign bit. */
+ if (unoptab->code == NEG && class == MODE_FLOAT
+ && GET_MODE_BITSIZE (mode) <= 2 * HOST_BITS_PER_WIDE_INT)
+ {
+ const struct real_format *fmt = REAL_MODE_FORMAT (mode);
+ enum machine_mode imode = int_mode_for_mode (mode);
+ int bitpos = (fmt != 0) ? fmt->signbit : -1;
+
+ if (imode != BLKmode && bitpos >= 0 && fmt->has_signed_zero)
+ {
+ HOST_WIDE_INT hi, lo;
+ rtx last = get_last_insn ();
+
+ /* Handle targets with different FP word orders. */
+ if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+ {
+ int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
+ int word = nwords - (bitpos / BITS_PER_WORD) - 1;
+ bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
+ }
+
+ if (bitpos < HOST_BITS_PER_WIDE_INT)
+ {
+ hi = 0;
+ lo = (HOST_WIDE_INT) 1 << bitpos;
+ }
+ else
+ {
+ hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
+ lo = 0;
+ }
+ temp = expand_binop (imode, xor_optab,
+ gen_lowpart (imode, op0),
+ immed_double_const (lo, hi, imode),
+ NULL_RTX, 1, OPTAB_LIB_WIDEN);
+ if (temp != 0)
+ {
+ rtx insn;
+ if (target == 0)
+ target = gen_reg_rtx (mode);
+ insn = emit_move_insn (target, gen_lowpart (mode, temp));
+ set_unique_reg_note (insn, REG_EQUAL,
+ gen_rtx_fmt_e (NEG, mode,
+ copy_rtx (op0)));
+ return target;
+ }
+ delete_insns_since (last);
+ }
+ }
+
+ /* Try calculating parity (x) as popcount (x) % 2. */
+ if (unoptab == parity_optab)
+ {
+ temp = expand_parity (mode, op0, target);
+ if (temp)
+ return temp;
+ }
+
+ try_libcall:
/* Now try a library call in this mode. */
if (unoptab->handlers[(int) mode].libfunc)
{
rtx insns;
rtx value;
+ enum machine_mode outmode = mode;
+
+ /* All of these functions return small values. Thus we choose to
+ have them return something that isn't a double-word. */
+ if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
+ || unoptab == popcount_optab || unoptab == parity_optab)
+ outmode
+ = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
start_sequence ();
/* Pass 1 for NO_QUEUE so we don't lose any increments
if the libcall is cse'd or moved. */
value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
- NULL_RTX, LCT_CONST, mode, 1, op0, mode);
+ NULL_RTX, LCT_CONST, outmode,
+ 1, op0, mode);
insns = get_insns ();
end_sequence ();
- target = gen_reg_rtx (mode);
+ target = gen_reg_rtx (outmode);
emit_libcall_block (insns, target, value,
gen_rtx_fmt_e (unoptab->code, mode, op0));
@@ -2570,10 +2684,18 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
(unoptab == neg_optab
|| unoptab == one_cmpl_optab)
&& class == MODE_INT);
-
+
temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
unsignedp);
+ /* If we are generating clz using wider mode, adjust the
+ result. */
+ if (unoptab == clz_optab && temp != 0)
+ temp = expand_binop (wider_mode, sub_optab, temp,
+ GEN_INT (GET_MODE_BITSIZE (wider_mode)
+ - GET_MODE_BITSIZE (mode)),
+ target, true, OPTAB_DIRECT);
+
if (temp)
{
if (class != MODE_INT)
@@ -2595,7 +2717,7 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
/* If there is no negate operation, try doing a subtract from zero.
The US Software GOFAST library needs this. */
if (unoptab->code == NEG)
- {
+ {
rtx temp;
temp = expand_binop (mode,
unoptab == negv_optab ? subv_optab : sub_optab,
@@ -2604,7 +2726,7 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
if (temp)
return temp;
}
-
+
return 0;
}
@@ -2618,14 +2740,10 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
*/
rtx
-expand_abs (mode, op0, target, result_unsignedp, safe)
- enum machine_mode mode;
- rtx op0;
- rtx target;
- int result_unsignedp;
- int safe;
+expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
+ int result_unsignedp)
{
- rtx temp, op1;
+ rtx temp;
if (! flag_trapv)
result_unsignedp = 1;
@@ -2636,6 +2754,56 @@ expand_abs (mode, op0, target, result_unsignedp, safe)
if (temp != 0)
return temp;
+ /* For floating point modes, try clearing the sign bit. */
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT
+ && GET_MODE_BITSIZE (mode) <= 2 * HOST_BITS_PER_WIDE_INT)
+ {
+ const struct real_format *fmt = REAL_MODE_FORMAT (mode);
+ enum machine_mode imode = int_mode_for_mode (mode);
+ int bitpos = (fmt != 0) ? fmt->signbit : -1;
+
+ if (imode != BLKmode && bitpos >= 0)
+ {
+ HOST_WIDE_INT hi, lo;
+ rtx last = get_last_insn ();
+
+ /* Handle targets with different FP word orders. */
+ if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+ {
+ int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
+ int word = nwords - (bitpos / BITS_PER_WORD) - 1;
+ bitpos = word * BITS_PER_WORD + bitpos % BITS_PER_WORD;
+ }
+
+ if (bitpos < HOST_BITS_PER_WIDE_INT)
+ {
+ hi = 0;
+ lo = (HOST_WIDE_INT) 1 << bitpos;
+ }
+ else
+ {
+ hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
+ lo = 0;
+ }
+ temp = expand_binop (imode, and_optab,
+ gen_lowpart (imode, op0),
+ immed_double_const (~lo, ~hi, imode),
+ NULL_RTX, 1, OPTAB_LIB_WIDEN);
+ if (temp != 0)
+ {
+ rtx insn;
+ if (target == 0)
+ target = gen_reg_rtx (mode);
+ insn = emit_move_insn (target, gen_lowpart (mode, temp));
+ set_unique_reg_note (insn, REG_EQUAL,
+ gen_rtx_fmt_e (ABS, mode,
+ copy_rtx (op0)));
+ return target;
+ }
+ delete_insns_since (last);
+ }
+ }
+
/* If we have a MAX insn, we can do this as MAX (x, -x). */
if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
@@ -2672,6 +2840,22 @@ expand_abs (mode, op0, target, result_unsignedp, safe)
return temp;
}
+ return NULL_RTX;
+}
+
+rtx
+expand_abs (enum machine_mode mode, rtx op0, rtx target,
+ int result_unsignedp, int safe)
+{
+ rtx temp, op1;
+
+ if (! flag_trapv)
+ result_unsignedp = 1;
+
+ temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
+ if (temp != 0)
+ return temp;
+
/* If that does not win, use conditional jump and negate. */
/* It is safe to use the target if it is the same
@@ -2695,7 +2879,7 @@ expand_abs (mode, op0, target, result_unsignedp, safe)
compare word by word. Rely on CSE to optimize constant cases. */
if (GET_MODE_CLASS (mode) == MODE_INT
&& ! can_compare_p (GE, mode, ccp_jump))
- do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
+ do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
NULL_RTX, op1);
else
do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
@@ -2720,11 +2904,8 @@ expand_abs (mode, op0, target, result_unsignedp, safe)
UNSIGNEDP is relevant for complex integer modes. */
rtx
-expand_complex_abs (mode, op0, target, unsignedp)
- enum machine_mode mode;
- rtx op0;
- rtx target;
- int unsignedp;
+expand_complex_abs (enum machine_mode mode, rtx op0, rtx target,
+ int unsignedp)
{
enum mode_class class = GET_MODE_CLASS (mode);
enum machine_mode wider_mode;
@@ -2783,16 +2964,16 @@ expand_complex_abs (mode, op0, target, unsignedp)
if (pat)
{
if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
- && ! add_equal_note (pat, temp, this_abs_optab->code, xop0,
+ && ! add_equal_note (pat, temp, this_abs_optab->code, xop0,
NULL_RTX))
{
delete_insns_since (last);
- return expand_unop (mode, this_abs_optab, op0, NULL_RTX,
+ return expand_unop (mode, this_abs_optab, op0, NULL_RTX,
unsignedp);
}
emit_insn (pat);
-
+
return temp;
}
else
@@ -2804,7 +2985,7 @@ expand_complex_abs (mode, op0, target, unsignedp)
for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
wider_mode = GET_MODE_WIDER_MODE (wider_mode))
{
- if (this_abs_optab->handlers[(int) wider_mode].insn_code
+ if (this_abs_optab->handlers[(int) wider_mode].insn_code
!= CODE_FOR_nothing)
{
rtx xop0 = op0;
@@ -2920,11 +3101,7 @@ expand_complex_abs (mode, op0, target, unsignedp)
the value that is stored into TARGET. */
void
-emit_unop_insn (icode, target, op0, code)
- int icode;
- rtx target;
- rtx op0;
- enum rtx_code code;
+emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
{
rtx temp;
enum machine_mode mode0 = insn_data[icode].operand[1].mode;
@@ -2953,7 +3130,7 @@ emit_unop_insn (icode, target, op0, code)
if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
add_equal_note (pat, temp, code, op0, NULL_RTX);
-
+
emit_insn (pat);
if (temp != target)
@@ -2974,7 +3151,7 @@ emit_unop_insn (icode, target, op0, code)
INSNS is a block of code generated to perform the operation, not including
the CLOBBER and final copy. All insns that compute intermediate values
- are first emitted, followed by the block as described above.
+ are first emitted, followed by the block as described above.
TARGET, OP0, and OP1 are the output and inputs of the operations,
respectively. OP1 may be zero for a unary operation.
@@ -2989,11 +3166,7 @@ emit_unop_insn (icode, target, op0, code)
The final insn emitted is returned. */
rtx
-emit_no_conflict_block (insns, target, op0, op1, equiv)
- rtx insns;
- rtx target;
- rtx op0, op1;
- rtx equiv;
+emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
{
rtx prev, next, first, last, insn;
@@ -3014,7 +3187,7 @@ emit_no_conflict_block (insns, target, op0, op1, equiv)
next = NEXT_INSN (insn);
- /* Some ports (cris) create an libcall regions at their own. We must
+ /* Some ports (cris) create a libcall regions at their own. We must
avoid any potential nesting of LIBCALLs. */
if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
remove_note (insn, note);
@@ -3130,11 +3303,7 @@ emit_no_conflict_block (insns, target, op0, op1, equiv)
block is delimited by REG_RETVAL and REG_LIBCALL notes. */
void
-emit_libcall_block (insns, target, result, equiv)
- rtx insns;
- rtx target;
- rtx result;
- rtx equiv;
+emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
{
rtx final_dest = target;
rtx prev, next, first, last, insn;
@@ -3143,7 +3312,7 @@ emit_libcall_block (insns, target, result, equiv)
into a MEM later. Protect the libcall block from this change. */
if (! REG_P (target) || REG_USERVAR_P (target))
target = gen_reg_rtx (GET_MODE (target));
-
+
/* If we're using non-call exceptions, a libcall corresponding to an
operation that may trap may also trap. */
if (flag_non_call_exceptions && may_trap_p (equiv))
@@ -3152,7 +3321,7 @@ emit_libcall_block (insns, target, result, equiv)
if (GET_CODE (insn) == CALL_INSN)
{
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
-
+
if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
remove_note (insn, note);
}
@@ -3166,7 +3335,7 @@ emit_libcall_block (insns, target, result, equiv)
if (GET_CODE (insn) == CALL_INSN)
{
rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
-
+
if (note != 0)
XEXP (note, 0) = GEN_INT (-1);
else
@@ -3185,7 +3354,7 @@ emit_libcall_block (insns, target, result, equiv)
rtx set = single_set (insn);
rtx note;
- /* Some ports (cris) create an libcall regions at their own. We must
+ /* Some ports (cris) create a libcall regions at their own. We must
avoid any potential nesting of LIBCALLs. */
if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
remove_note (insn, note);
@@ -3213,6 +3382,11 @@ emit_libcall_block (insns, target, result, equiv)
add_insn (insn);
}
+
+ /* Some ports use a loop to copy large arguments onto the stack.
+ Don't move anything outside such a loop. */
+ if (GET_CODE (insn) == CODE_LABEL)
+ break;
}
prev = get_last_insn ();
@@ -3277,8 +3451,7 @@ emit_libcall_block (insns, target, result, equiv)
/* Generate code to store zero in X. */
void
-emit_clr_insn (x)
- rtx x;
+emit_clr_insn (rtx x)
{
emit_move_insn (x, const0_rtx);
}
@@ -3287,8 +3460,7 @@ emit_clr_insn (x)
assuming it contains zero beforehand. */
void
-emit_0_to_1_insn (x)
- rtx x;
+emit_0_to_1_insn (rtx x)
{
emit_move_insn (x, const1_rtx);
}
@@ -3298,14 +3470,12 @@ emit_0_to_1_insn (x)
comparison code we will be using.
??? Actually, CODE is slightly weaker than that. A target is still
- required to implement all of the normal bcc operations, but not
+ required to implement all of the normal bcc operations, but not
required to implement all (or any) of the unordered bcc operations. */
-
+
int
-can_compare_p (code, mode, purpose)
- enum rtx_code code;
- enum machine_mode mode;
- enum can_compare_purpose purpose;
+can_compare_p (enum rtx_code code, enum machine_mode mode,
+ enum can_compare_purpose purpose)
{
do
{
@@ -3353,13 +3523,9 @@ can_compare_p (code, mode, purpose)
should perform the comparison on the modified values. */
static void
-prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose)
- rtx *px, *py;
- enum rtx_code *pcomparison;
- rtx size;
- enum machine_mode *pmode;
- int *punsignedp;
- enum can_compare_purpose purpose;
+prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
+ enum machine_mode *pmode, int *punsignedp,
+ enum can_compare_purpose purpose)
{
enum machine_mode mode = *pmode;
rtx x = *px, y = *py;
@@ -3375,8 +3541,17 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose)
if (mode != BLKmode && flag_force_mem)
{
- x = force_not_mem (x);
- y = force_not_mem (y);
+ /* Load duplicate non-volatile operands once. */
+ if (rtx_equal_p (x, y) && ! volatile_refs_p (x))
+ {
+ x = force_not_mem (x);
+ y = x;
+ }
+ else
+ {
+ x = force_not_mem (x);
+ y = force_not_mem (y);
+ }
}
/* If we are inside an appropriately-short loop and one operand is an
@@ -3405,77 +3580,87 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose)
if (mode == BLKmode)
{
+ enum machine_mode cmp_mode, result_mode;
+ enum insn_code cmp_code;
+ tree length_type;
+ rtx libfunc;
rtx result;
- enum machine_mode result_mode;
- rtx opalign ATTRIBUTE_UNUSED
+ rtx opalign
= GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
+ if (size == 0)
+ abort ();
+
emit_queue ();
x = protect_from_queue (x, 0);
y = protect_from_queue (y, 0);
+ size = protect_from_queue (size, 0);
- if (size == 0)
- abort ();
-#ifdef HAVE_cmpstrqi
- if (HAVE_cmpstrqi
- && GET_CODE (size) == CONST_INT
- && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
- {
- result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
- result = gen_reg_rtx (result_mode);
- emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
- }
- else
-#endif
-#ifdef HAVE_cmpstrhi
- if (HAVE_cmpstrhi
- && GET_CODE (size) == CONST_INT
- && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
- {
- result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
- result = gen_reg_rtx (result_mode);
- emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
- }
- else
-#endif
-#ifdef HAVE_cmpstrsi
- if (HAVE_cmpstrsi)
+ /* Try to use a memory block compare insn - either cmpstr
+ or cmpmem will do. */
+ for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+ cmp_mode != VOIDmode;
+ cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
{
- result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
+ cmp_code = cmpmem_optab[cmp_mode];
+ if (cmp_code == CODE_FOR_nothing)
+ cmp_code = cmpstr_optab[cmp_mode];
+ if (cmp_code == CODE_FOR_nothing)
+ continue;
+
+ /* Must make sure the size fits the insn's mode. */
+ if ((GET_CODE (size) == CONST_INT
+ && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
+ || (GET_MODE_BITSIZE (GET_MODE (size))
+ > GET_MODE_BITSIZE (cmp_mode)))
+ continue;
+
+ result_mode = insn_data[cmp_code].operand[0].mode;
result = gen_reg_rtx (result_mode);
- size = protect_from_queue (size, 0);
- emit_insn (gen_cmpstrsi (result, x, y,
- convert_to_mode (SImode, size, 1),
- opalign));
+ 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;
+ return;
}
- else
-#endif
- {
+
+ /* Otherwise call a library function, memcmp if we've got it,
+ bcmp otherwise. */
#ifdef TARGET_MEM_FUNCTIONS
- result = emit_library_call_value (memcmp_libfunc, NULL_RTX, LCT_PURE_MAKE_BLOCK,
- TYPE_MODE (integer_type_node), 3,
- XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
- convert_to_mode (TYPE_MODE (sizetype), size,
- TREE_UNSIGNED (sizetype)),
- TYPE_MODE (sizetype));
+ libfunc = memcmp_libfunc;
+ length_type = sizetype;
#else
- result = emit_library_call_value (bcmp_libfunc, NULL_RTX, LCT_PURE_MAKE_BLOCK,
- TYPE_MODE (integer_type_node), 3,
- XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
- convert_to_mode (TYPE_MODE (integer_type_node),
- size,
- TREE_UNSIGNED (integer_type_node)),
- TYPE_MODE (integer_type_node));
+ libfunc = bcmp_libfunc;
+ length_type = integer_type_node;
#endif
-
- result_mode = TYPE_MODE (integer_type_node);
- }
+ result_mode = TYPE_MODE (integer_type_node);
+ cmp_mode = TYPE_MODE (length_type);
+ size = convert_to_mode (TYPE_MODE (length_type), size,
+ TREE_UNSIGNED (length_type));
+
+ result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
+ result_mode, 3,
+ XEXP (x, 0), Pmode,
+ XEXP (y, 0), Pmode,
+ size, cmp_mode);
*px = result;
*py = const0_rtx;
*pmode = result_mode;
return;
}
+ /* Don't allow operands to the compare to trap, as that can put the
+ compare and branch in different basic blocks. */
+ if (flag_non_call_exceptions)
+ {
+ if (may_trap_p (x))
+ x = force_reg (mode, x);
+ if (may_trap_p (y))
+ y = force_reg (mode, y);
+ }
+
*px = x;
*py = y;
if (can_compare_p (*pcomparison, mode, purpose))
@@ -3518,12 +3703,8 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose)
that it is accepted by the operand predicate. Return the new value. */
rtx
-prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
- int icode;
- rtx x;
- int opnum;
- enum machine_mode mode, wider_mode;
- int unsignedp;
+prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
+ enum machine_mode wider_mode, int unsignedp)
{
x = protect_from_queue (x, 0);
@@ -3547,12 +3728,8 @@ prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
be NULL_RTX which indicates that only a comparison is to be generated. */
static void
-emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
- rtx x, y;
- enum machine_mode mode;
- enum rtx_code comparison;
- int unsignedp;
- rtx label;
+emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
+ enum rtx_code comparison, int unsignedp, rtx label)
{
rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
enum mode_class class = GET_MODE_CLASS (mode);
@@ -3565,9 +3742,9 @@ emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
PUT_MODE (test, wider_mode);
if (label)
- {
+ {
icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
-
+
if (icode != CODE_FOR_nothing
&& (*insn_data[icode].operand[0].predicate) (test, wider_mode))
{
@@ -3631,13 +3808,8 @@ emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
void
-emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, label)
- rtx x, y;
- enum rtx_code comparison;
- rtx size;
- enum machine_mode mode;
- int unsignedp;
- rtx label;
+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;
@@ -3673,12 +3845,8 @@ emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, label)
/* Like emit_cmp_and_jump_insns, but generate only the comparison. */
void
-emit_cmp_insn (x, y, comparison, size, mode, unsignedp)
- rtx x, y;
- enum rtx_code comparison;
- rtx size;
- enum machine_mode mode;
- int unsignedp;
+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);
}
@@ -3687,354 +3855,123 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp)
COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
static void
-prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
- rtx *px, *py;
- enum rtx_code *pcomparison;
- enum machine_mode *pmode;
- int *punsignedp;
+prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
+ enum machine_mode *pmode, int *punsignedp)
{
enum rtx_code comparison = *pcomparison;
- rtx tmp;
- rtx x = *px = protect_from_queue (*px, 0);
- rtx y = *py = protect_from_queue (*py, 0);
- enum machine_mode mode = GET_MODE (x);
+ enum rtx_code swapped = swap_condition (comparison);
+ rtx x = protect_from_queue (*px, 0);
+ rtx y = protect_from_queue (*py, 0);
+ enum machine_mode orig_mode = GET_MODE (x);
+ enum machine_mode mode;
+ rtx value, target, insns, equiv;
rtx libfunc = 0;
- rtx result;
-
- if (mode == HFmode)
- switch (comparison)
- {
- case EQ:
- libfunc = eqhf2_libfunc;
- break;
-
- case NE:
- libfunc = nehf2_libfunc;
- break;
-
- case GT:
- libfunc = gthf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = LT;
- libfunc = lthf2_libfunc;
- }
- break;
-
- case GE:
- libfunc = gehf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = LE;
- libfunc = lehf2_libfunc;
- }
- break;
-
- case LT:
- libfunc = lthf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = GT;
- libfunc = gthf2_libfunc;
- }
- break;
-
- case LE:
- libfunc = lehf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = GE;
- libfunc = gehf2_libfunc;
- }
- break;
-
- case UNORDERED:
- libfunc = unordhf2_libfunc;
- break;
-
- default:
- break;
- }
- else if (mode == SFmode)
- switch (comparison)
- {
- case EQ:
- libfunc = eqsf2_libfunc;
- break;
-
- case NE:
- libfunc = nesf2_libfunc;
- break;
- case GT:
- libfunc = gtsf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = LT;
- libfunc = ltsf2_libfunc;
- }
- break;
-
- case GE:
- libfunc = gesf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = LE;
- libfunc = lesf2_libfunc;
- }
- break;
-
- case LT:
- libfunc = ltsf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = GT;
- libfunc = gtsf2_libfunc;
- }
- break;
-
- case LE:
- libfunc = lesf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = GE;
- libfunc = gesf2_libfunc;
- }
- break;
-
- case UNORDERED:
- libfunc = unordsf2_libfunc;
- break;
-
- default:
- break;
- }
- else if (mode == DFmode)
- switch (comparison)
- {
- case EQ:
- libfunc = eqdf2_libfunc;
- break;
-
- case NE:
- libfunc = nedf2_libfunc;
- break;
-
- case GT:
- libfunc = gtdf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = LT;
- libfunc = ltdf2_libfunc;
- }
- break;
-
- case GE:
- libfunc = gedf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = LE;
- libfunc = ledf2_libfunc;
- }
- break;
-
- case LT:
- libfunc = ltdf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = GT;
- libfunc = gtdf2_libfunc;
- }
- break;
-
- case LE:
- libfunc = ledf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = GE;
- libfunc = gedf2_libfunc;
- }
- break;
-
- case UNORDERED:
- libfunc = unorddf2_libfunc;
- break;
-
- default:
- break;
- }
- else if (mode == XFmode)
- switch (comparison)
- {
- case EQ:
- libfunc = eqxf2_libfunc;
- break;
-
- case NE:
- libfunc = nexf2_libfunc;
- break;
-
- case GT:
- libfunc = gtxf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = LT;
- libfunc = ltxf2_libfunc;
- }
- break;
-
- case GE:
- libfunc = gexf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = LE;
- libfunc = lexf2_libfunc;
- }
- break;
-
- case LT:
- libfunc = ltxf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = GT;
- libfunc = gtxf2_libfunc;
- }
- break;
-
- case LE:
- libfunc = lexf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = GE;
- libfunc = gexf2_libfunc;
- }
- break;
-
- case UNORDERED:
- libfunc = unordxf2_libfunc;
- break;
-
- default:
- break;
- }
- else if (mode == TFmode)
- switch (comparison)
- {
- case EQ:
- libfunc = eqtf2_libfunc;
- break;
-
- case NE:
- libfunc = netf2_libfunc;
- break;
-
- case GT:
- libfunc = gttf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = LT;
- libfunc = lttf2_libfunc;
- }
- break;
-
- case GE:
- libfunc = getf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = LE;
- libfunc = letf2_libfunc;
- }
+ for (mode = orig_mode; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
+ {
+ if ((libfunc = code_to_optab[comparison]->handlers[mode].libfunc))
break;
- case LT:
- libfunc = lttf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = GT;
- libfunc = gttf2_libfunc;
- }
- break;
+ if ((libfunc = code_to_optab[swapped]->handlers[mode].libfunc))
+ {
+ rtx tmp;
+ tmp = x; x = y; y = tmp;
+ comparison = swapped;
+ break;
+ }
+ }
- case LE:
- libfunc = letf2_libfunc;
- if (libfunc == NULL_RTX)
- {
- tmp = x; x = y; y = tmp;
- *pcomparison = GE;
- libfunc = getf2_libfunc;
- }
- break;
+ if (mode == VOIDmode)
+ abort ();
- case UNORDERED:
- libfunc = unordtf2_libfunc;
- break;
+ if (mode != orig_mode)
+ {
+ x = convert_to_mode (mode, x, 0);
+ y = convert_to_mode (mode, y, 0);
+ }
- default:
- break;
- }
+ /* Attach a REG_EQUAL note describing the semantics of the libcall to
+ the RTL. The allows the RTL optimizers to delete the libcall if the
+ condition can be determined at compile-time. */
+ if (comparison == UNORDERED)
+ {
+ rtx temp = simplify_gen_relational (NE, word_mode, mode, x, x);
+ equiv = simplify_gen_relational (NE, word_mode, mode, y, y);
+ equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
+ temp, const_true_rtx, equiv);
+ }
else
{
- enum machine_mode wider_mode;
-
- for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
- wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+ equiv = simplify_gen_relational (comparison, word_mode, mode, x, y);
+ if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
{
- if ((cmp_optab->handlers[(int) wider_mode].insn_code
- != CODE_FOR_nothing)
- || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
+ rtx true_rtx, false_rtx;
+
+ switch (comparison)
{
- x = protect_from_queue (x, 0);
- y = protect_from_queue (y, 0);
- *px = convert_to_mode (wider_mode, x, 0);
- *py = convert_to_mode (wider_mode, y, 0);
- prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
- return;
+ case EQ:
+ true_rtx = const0_rtx;
+ false_rtx = const_true_rtx;
+ break;
+
+ case NE:
+ true_rtx = const_true_rtx;
+ false_rtx = const0_rtx;
+ break;
+
+ case GT:
+ true_rtx = const1_rtx;
+ false_rtx = const0_rtx;
+ break;
+
+ case GE:
+ true_rtx = const0_rtx;
+ false_rtx = constm1_rtx;
+ break;
+
+ case LT:
+ true_rtx = constm1_rtx;
+ false_rtx = const0_rtx;
+ break;
+
+ case LE:
+ true_rtx = const0_rtx;
+ false_rtx = const1_rtx;
+ break;
+
+ default:
+ abort ();
}
+ equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
+ equiv, true_rtx, false_rtx);
}
- abort ();
}
- if (libfunc == 0)
- abort ();
+ start_sequence ();
+ value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
+ word_mode, 2, x, mode, y, mode);
+ insns = get_insns ();
+ end_sequence ();
- result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
- word_mode, 2, x, mode, y, mode);
- *px = result;
+ target = gen_reg_rtx (word_mode);
+ emit_libcall_block (insns, target, value, equiv);
+
+
+ if (comparison == UNORDERED
+ || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
+ comparison = NE;
+
+ *px = target;
*py = const0_rtx;
*pmode = word_mode;
- if (comparison == UNORDERED)
- *pcomparison = NE;
-#ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
- else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
- *pcomparison = NE;
-#endif
+ *pcomparison = comparison;
*punsignedp = 0;
}
/* Generate code to indirectly jump to a location given in the rtx LOC. */
void
-emit_indirect_jump (loc)
- rtx loc;
+emit_indirect_jump (rtx loc)
{
if (! ((*insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate)
(loc, Pmode)))
@@ -4061,15 +3998,9 @@ emit_indirect_jump (loc)
is not supported. */
rtx
-emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
- unsignedp)
- rtx target;
- enum rtx_code code;
- rtx op0, op1;
- enum machine_mode cmode;
- rtx op2, op3;
- enum machine_mode mode;
- int unsignedp;
+emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
+ enum machine_mode cmode, rtx op2, rtx op3,
+ enum machine_mode mode, int unsignedp)
{
rtx tem, subtarget, comparison, insn;
enum insn_code icode;
@@ -4089,9 +4020,9 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
/* get_condition will prefer to generate LT and GT even if the old
comparison was against zero, so undo that canonicalization here since
comparisons against zero are cheaper. */
- if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
+ if (code == LT && op1 == const1_rtx)
code = LE, op1 = const0_rtx;
- else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
+ else if (code == GT && op1 == constm1_rtx)
code = GE, op1 = const0_rtx;
if (cmode == VOIDmode)
@@ -4150,7 +4081,7 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
/* Everything should now be in the suitable form, so emit the compare insn
and then the conditional move. */
- comparison
+ comparison
= compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
/* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
@@ -4159,7 +4090,7 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
situation. */
if (GET_CODE (comparison) != code)
return NULL_RTX;
-
+
insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
/* If that failed, then give up. */
@@ -4183,8 +4114,7 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
comparisons, and vice versa. How do we handle them? */
int
-can_conditionally_move_p (mode)
- enum machine_mode mode;
+can_conditionally_move_p (enum machine_mode mode)
{
if (movcc_gen_code[mode] != CODE_FOR_nothing)
return 1;
@@ -4193,9 +4123,132 @@ can_conditionally_move_p (mode)
}
#endif /* HAVE_conditional_move */
+
+/* Emit a conditional addition instruction if the machine supports one for that
+ condition and machine mode.
+
+ OP0 and OP1 are the operands that should be compared using CODE. CMODE is
+ the mode to use should they be constants. If it is VOIDmode, they cannot
+ both be constants.
+
+ OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
+ should be stored there. MODE is the mode to use should they be constants.
+ If it is VOIDmode, they cannot both be constants.
+
+ The result is either TARGET (perhaps modified) or NULL_RTX if the operation
+ is not supported. */
+
+rtx
+emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
+ enum machine_mode cmode, rtx op2, rtx op3,
+ enum machine_mode mode, int unsignedp)
+{
+ rtx tem, subtarget, comparison, insn;
+ enum insn_code icode;
+ enum rtx_code reversed;
+
+ /* 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);
+ }
+
+ /* get_condition will prefer to generate LT and GT even if the old
+ comparison was against zero, so undo that canonicalization here since
+ comparisons against zero are cheaper. */
+ if (code == LT && op1 == const1_rtx)
+ code = LE, op1 = const0_rtx;
+ else if (code == GT && op1 == constm1_rtx)
+ code = GE, op1 = const0_rtx;
+
+ if (cmode == VOIDmode)
+ cmode = GET_MODE (op0);
+
+ if (swap_commutative_operands_p (op2, op3)
+ && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
+ != UNKNOWN))
+ {
+ tem = op2;
+ op2 = op3;
+ op3 = tem;
+ code = reversed;
+ }
+
+ if (mode == VOIDmode)
+ mode = GET_MODE (op2);
+
+ icode = addcc_optab->handlers[(int) mode].insn_code;
+
+ if (icode == CODE_FOR_nothing)
+ return 0;
+
+ if (flag_force_mem)
+ {
+ op2 = force_not_mem (op2);
+ op3 = force_not_mem (op3);
+ }
+
+ if (target)
+ target = protect_from_queue (target, 1);
+ else
+ target = gen_reg_rtx (mode);
+
+ subtarget = target;
+
+ emit_queue ();
+
+ op2 = protect_from_queue (op2, 0);
+ op3 = protect_from_queue (op3, 0);
+
+ /* If the insn doesn't accept these operands, put them in pseudos. */
+
+ if (! (*insn_data[icode].operand[0].predicate)
+ (subtarget, insn_data[icode].operand[0].mode))
+ subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
+
+ if (! (*insn_data[icode].operand[2].predicate)
+ (op2, insn_data[icode].operand[2].mode))
+ op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
+
+ if (! (*insn_data[icode].operand[3].predicate)
+ (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. */
+
+ comparison
+ = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
+
+ /* ??? 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)
+ return NULL_RTX;
+
+ insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
+
+ /* If that failed, then give up. */
+ if (insn == 0)
+ return 0;
+
+ emit_insn (insn);
+
+ if (subtarget != target)
+ convert_move (target, subtarget, 0);
+
+ return target;
+}
-/* These functions generate an insn body and return it
- rather than emitting the insn.
+/* These functions attempt to generate an insn body, rather than
+ emitting the insn, but if the gen function already emits them, we
+ make no attempt to turn them back into naked patterns.
They do not protect from queued increments,
because they may be used 1) in protect_from_queue itself
@@ -4204,10 +4257,9 @@ can_conditionally_move_p (mode)
/* Generate and return an insn body to add Y to X. */
rtx
-gen_add2_insn (x, y)
- rtx x, y;
+gen_add2_insn (rtx x, rtx y)
{
- int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
+ int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
if (! ((*insn_data[icode].operand[0].predicate)
(x, insn_data[icode].operand[0].mode))
@@ -4223,8 +4275,7 @@ gen_add2_insn (x, y)
/* Generate and return an insn body to add r1 and c,
storing the result in r0. */
rtx
-gen_add3_insn (r0, r1, c)
- rtx r0, r1, c;
+gen_add3_insn (rtx r0, rtx r1, rtx c)
{
int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
@@ -4241,15 +4292,14 @@ gen_add3_insn (r0, r1, c)
}
int
-have_add2_insn (x, y)
- rtx x, y;
+have_add2_insn (rtx x, rtx y)
{
int icode;
if (GET_MODE (x) == VOIDmode)
abort ();
- icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
+ icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
if (icode == CODE_FOR_nothing)
return 0;
@@ -4268,10 +4318,9 @@ have_add2_insn (x, y)
/* Generate and return an insn body to subtract Y from X. */
rtx
-gen_sub2_insn (x, y)
- rtx x, y;
+gen_sub2_insn (rtx x, rtx y)
{
- int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
+ int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
if (! ((*insn_data[icode].operand[0].predicate)
(x, insn_data[icode].operand[0].mode))
@@ -4287,8 +4336,7 @@ gen_sub2_insn (x, y)
/* Generate and return an insn body to subtract r1 and c,
storing the result in r0. */
rtx
-gen_sub3_insn (r0, r1, c)
- rtx r0, r1, c;
+gen_sub3_insn (rtx r0, rtx r1, rtx c)
{
int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
@@ -4305,15 +4353,14 @@ gen_sub3_insn (r0, r1, c)
}
int
-have_sub2_insn (x, y)
- rtx x, y;
+have_sub2_insn (rtx x, rtx y)
{
int icode;
if (GET_MODE (x) == VOIDmode)
abort ();
- icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
+ icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
if (icode == CODE_FOR_nothing)
return 0;
@@ -4333,72 +4380,10 @@ have_sub2_insn (x, y)
It may be a list of insns, if one insn isn't enough. */
rtx
-gen_move_insn (x, y)
- rtx x, y;
+gen_move_insn (rtx x, rtx y)
{
- enum machine_mode mode = GET_MODE (x);
- enum insn_code insn_code;
rtx seq;
- if (mode == VOIDmode)
- mode = GET_MODE (y);
-
- insn_code = mov_optab->handlers[(int) mode].insn_code;
-
- /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
- find a mode to do it in. If we have a movcc, use it. Otherwise,
- find the MODE_INT mode of the same width. */
-
- if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
- {
- enum machine_mode tmode = VOIDmode;
- rtx x1 = x, y1 = y;
-
- if (mode != CCmode
- && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
- tmode = CCmode;
- else
- for (tmode = QImode; tmode != VOIDmode;
- tmode = GET_MODE_WIDER_MODE (tmode))
- if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
- break;
-
- if (tmode == VOIDmode)
- abort ();
-
- /* Get X and Y in TMODE. We can't use gen_lowpart here because it
- may call change_address which is not appropriate if we were
- called when a reload was in progress. We don't have to worry
- about changing the address since the size in bytes is supposed to
- be the same. Copy the MEM to change the mode and move any
- substitutions from the old MEM to the new one. */
-
- if (reload_in_progress)
- {
- x = gen_lowpart_common (tmode, x1);
- if (x == 0 && GET_CODE (x1) == MEM)
- {
- x = adjust_address_nv (x1, tmode, 0);
- copy_replacements (x1, x);
- }
-
- y = gen_lowpart_common (tmode, y1);
- if (y == 0 && GET_CODE (y1) == MEM)
- {
- y = adjust_address_nv (y1, tmode, 0);
- copy_replacements (y1, y);
- }
- }
- else
- {
- x = gen_lowpart (tmode, x);
- y = gen_lowpart (tmode, y);
- }
-
- insn_code = mov_optab->handlers[(int) tmode].insn_code;
- return (GEN_FCN (insn_code) (x, y));
- }
-
start_sequence ();
emit_move_insn_1 (x, y);
seq = get_insns ();
@@ -4411,28 +4396,28 @@ gen_move_insn (x, y)
no such operation exists, CODE_FOR_nothing will be returned. */
enum insn_code
-can_extend_p (to_mode, from_mode, unsignedp)
- enum machine_mode to_mode, from_mode;
- int unsignedp;
+can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
+ int unsignedp)
{
+ convert_optab tab;
#ifdef HAVE_ptr_extend
if (unsignedp < 0)
return CODE_FOR_ptr_extend;
- else
#endif
- return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
+
+ tab = unsignedp ? zext_optab : sext_optab;
+ return tab->handlers[to_mode][from_mode].insn_code;
}
/* Generate the body of an insn to extend Y (with mode MFROM)
into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
rtx
-gen_extend_insn (x, y, mto, mfrom, unsignedp)
- rtx x, y;
- enum machine_mode mto, mfrom;
- int unsignedp;
+gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
+ enum machine_mode mfrom, int unsignedp)
{
- return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
+ enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
+ return GEN_FCN (icode) (x, y);
}
/* can_fix_p and can_float_p say whether the target machine
@@ -4445,30 +4430,41 @@ gen_extend_insn (x, y, mto, mfrom, unsignedp)
an explicit FTRUNC insn before the fix insn; otherwise 0. */
static enum insn_code
-can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
- enum machine_mode fltmode, fixmode;
- int unsignedp;
- int *truncp_ptr;
+can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
+ int unsignedp, int *truncp_ptr)
{
- *truncp_ptr = 0;
- if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
- != CODE_FOR_nothing)
- return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
+ convert_optab tab;
+ enum insn_code icode;
+
+ tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
+ icode = tab->handlers[fixmode][fltmode].insn_code;
+ if (icode != CODE_FOR_nothing)
+ {
+ *truncp_ptr = 0;
+ return icode;
+ }
- if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
+ tab = unsignedp ? ufix_optab : sfix_optab;
+ icode = tab->handlers[fixmode][fltmode].insn_code;
+ if (icode != CODE_FOR_nothing
+ && ftrunc_optab->handlers[fltmode].insn_code != CODE_FOR_nothing)
{
*truncp_ptr = 1;
- return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
+ return icode;
}
+
+ *truncp_ptr = 0;
return CODE_FOR_nothing;
}
static enum insn_code
-can_float_p (fltmode, fixmode, unsignedp)
- enum machine_mode fixmode, fltmode;
- int unsignedp;
+can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
+ int unsignedp)
{
- return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
+ convert_optab tab;
+
+ tab = unsignedp ? ufloat_optab : sfloat_optab;
+ return tab->handlers[fltmode][fixmode].insn_code;
}
/* Generate code to convert FROM to floating point
@@ -4478,9 +4474,7 @@ can_float_p (fltmode, fixmode, unsignedp)
if it is negative. */
void
-expand_float (to, from, unsignedp)
- rtx to, from;
- int unsignedp;
+expand_float (rtx to, rtx from, int unsignedp)
{
enum insn_code icode;
rtx target = to;
@@ -4568,7 +4562,7 @@ expand_float (to, from, unsignedp)
rtx temp1;
rtx neglabel = gen_label_rtx ();
- /* Don't use TARGET if it isn't a register, is a hard register,
+ /* Don't use TARGET if it isn't a register, is a hard register,
or is the wrong mode. */
if (GET_CODE (target) != REG
|| REGNO (target) < FIRST_PSEUDO_REGISTER
@@ -4597,7 +4591,7 @@ expand_float (to, from, unsignedp)
NULL_RTX, 1, OPTAB_LIB_WIDEN);
temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
NULL_RTX, 1);
- temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
+ temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
OPTAB_LIB_WIDEN);
expand_float (target, temp, 0);
@@ -4630,7 +4624,7 @@ expand_float (to, from, unsignedp)
emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
0, label);
-
+
real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
temp = expand_binop (fmode, add_optab, target,
CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
@@ -4643,12 +4637,12 @@ expand_float (to, from, unsignedp)
goto done;
}
- /* No hardware instruction available; call a library routine to convert from
- SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
+ /* No hardware instruction available; call a library routine. */
{
- rtx libfcn;
+ rtx libfunc;
rtx insns;
rtx value;
+ convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
to = protect_from_queue (to, 1);
from = protect_from_queue (from, 0);
@@ -4659,56 +4653,13 @@ expand_float (to, from, unsignedp)
if (flag_force_mem)
from = force_not_mem (from);
- if (GET_MODE (to) == SFmode)
- {
- if (GET_MODE (from) == SImode)
- libfcn = floatsisf_libfunc;
- else if (GET_MODE (from) == DImode)
- libfcn = floatdisf_libfunc;
- else if (GET_MODE (from) == TImode)
- libfcn = floattisf_libfunc;
- else
- abort ();
- }
- else if (GET_MODE (to) == DFmode)
- {
- if (GET_MODE (from) == SImode)
- libfcn = floatsidf_libfunc;
- else if (GET_MODE (from) == DImode)
- libfcn = floatdidf_libfunc;
- else if (GET_MODE (from) == TImode)
- libfcn = floattidf_libfunc;
- else
- abort ();
- }
- else if (GET_MODE (to) == XFmode)
- {
- if (GET_MODE (from) == SImode)
- libfcn = floatsixf_libfunc;
- else if (GET_MODE (from) == DImode)
- libfcn = floatdixf_libfunc;
- else if (GET_MODE (from) == TImode)
- libfcn = floattixf_libfunc;
- else
- abort ();
- }
- else if (GET_MODE (to) == TFmode)
- {
- if (GET_MODE (from) == SImode)
- libfcn = floatsitf_libfunc;
- else if (GET_MODE (from) == DImode)
- libfcn = floatditf_libfunc;
- else if (GET_MODE (from) == TImode)
- libfcn = floattitf_libfunc;
- else
- abort ();
- }
- else
+ libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
+ if (!libfunc)
abort ();
start_sequence ();
- value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
+ value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
GET_MODE (to), 1, from,
GET_MODE (from));
insns = get_insns ();
@@ -4736,23 +4687,19 @@ expand_float (to, from, unsignedp)
and store in TO. FROM must be floating point. */
static rtx
-ftruncify (x)
- rtx x;
+ftruncify (rtx x)
{
rtx temp = gen_reg_rtx (GET_MODE (x));
return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
}
void
-expand_fix (to, from, unsignedp)
- rtx to, from;
- int unsignedp;
+expand_fix (rtx to, rtx from, int unsignedp)
{
enum insn_code icode;
rtx target = to;
enum machine_mode fmode, imode;
int must_trunc = 0;
- rtx libfcn = 0;
/* We first try to find a pair of modes, one real and one integer, at
least as wide as FROM and TO, respectively, in which we can open-code
@@ -4799,15 +4746,26 @@ expand_fix (to, from, unsignedp)
one plus the highest signed number, convert, and add it back.
We only need to check all real modes, since we know we didn't find
- anything with a wider integer mode. */
+ anything with a wider integer mode.
+
+ This code used to extend FP value into mode wider than the destination.
+ This is not needed. Consider, for instance conversion from SFmode
+ into DImode.
+
+ The hot path trought the code is dealing with inputs smaller than 2^63
+ and doing just the conversion, so there is no bits to lose.
+
+ In the other path we know the value is positive in the range 2^63..2^64-1
+ inclusive. (as for other imput overflow happens and result is undefined)
+ So we know that the most important bit set in mantissa corresponds to
+ 2^63. The subtraction of 2^63 should not generate any rounding as it
+ simply clears out that bit. The rest is trivial. */
if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
for (fmode = GET_MODE (from); fmode != VOIDmode;
fmode = GET_MODE_WIDER_MODE (fmode))
- /* Make sure we won't lose significant bits doing this. */
- if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
- && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
- &must_trunc))
+ if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
+ &must_trunc))
{
int bitsize;
REAL_VALUE_TYPE offset;
@@ -4882,57 +4840,16 @@ expand_fix (to, from, unsignedp)
expand_fix (target, from, unsignedp);
}
- else if (GET_MODE (from) == SFmode)
- {
- if (GET_MODE (to) == SImode)
- libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
- else if (GET_MODE (to) == DImode)
- libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
- else if (GET_MODE (to) == TImode)
- libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
- else
- abort ();
- }
- else if (GET_MODE (from) == DFmode)
- {
- if (GET_MODE (to) == SImode)
- libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
- else if (GET_MODE (to) == DImode)
- libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
- else if (GET_MODE (to) == TImode)
- libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
- else
- abort ();
- }
- else if (GET_MODE (from) == XFmode)
- {
- if (GET_MODE (to) == SImode)
- libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
- else if (GET_MODE (to) == DImode)
- libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
- else if (GET_MODE (to) == TImode)
- libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
- else
- abort ();
- }
- else if (GET_MODE (from) == TFmode)
- {
- if (GET_MODE (to) == SImode)
- libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
- else if (GET_MODE (to) == DImode)
- libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
- else if (GET_MODE (to) == TImode)
- libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
- else
- abort ();
- }
else
- abort ();
-
- if (libfcn)
{
rtx insns;
rtx value;
+ rtx libfunc;
+
+ convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
+ libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
+ if (!libfunc)
+ abort ();
to = protect_from_queue (to, 1);
from = protect_from_queue (from, 0);
@@ -4942,7 +4859,7 @@ expand_fix (to, from, unsignedp)
start_sequence ();
- value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
+ value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
GET_MODE (to), 1, from,
GET_MODE (from));
insns = get_insns ();
@@ -4952,7 +4869,7 @@ expand_fix (to, from, unsignedp)
gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
GET_MODE (to), from));
}
-
+
if (target != to)
{
if (GET_MODE (to) == GET_MODE (target))
@@ -4965,9 +4882,7 @@ expand_fix (to, from, unsignedp)
/* Report whether we have an instruction to perform the operation
specified by CODE on operands of mode MODE. */
int
-have_insn_for (code, mode)
- enum rtx_code code;
- enum machine_mode mode;
+have_insn_for (enum rtx_code code, enum machine_mode mode)
{
return (code_to_optab[(int) code] != 0
&& (code_to_optab[(int) code]->handlers[(int) mode].insn_code
@@ -4976,10 +4891,10 @@ have_insn_for (code, mode)
/* Create a blank optab. */
static optab
-new_optab ()
+new_optab (void)
{
int i;
- optab op = (optab) ggc_alloc (sizeof (struct optab));
+ optab op = ggc_alloc (sizeof (struct optab));
for (i = 0; i < NUM_MACHINE_MODES; i++)
{
op->handlers[i].insn_code = CODE_FOR_nothing;
@@ -4989,11 +4904,24 @@ new_optab ()
return op;
}
+static convert_optab
+new_convert_optab (void)
+{
+ int i, j;
+ convert_optab op = ggc_alloc (sizeof (struct convert_optab));
+ for (i = 0; i < NUM_MACHINE_MODES; i++)
+ for (j = 0; j < NUM_MACHINE_MODES; j++)
+ {
+ op->handlers[i][j].insn_code = CODE_FOR_nothing;
+ op->handlers[i][j].libfunc = 0;
+ }
+ return op;
+}
+
/* Same, but fill in its code as CODE, and write it into the
code_to_optab table. */
static inline optab
-init_optab (code)
- enum rtx_code code;
+init_optab (enum rtx_code code)
{
optab op = new_optab ();
op->code = code;
@@ -5004,18 +4932,26 @@ init_optab (code)
/* Same, but fill in its code as CODE, and do _not_ write it into
the code_to_optab table. */
static inline optab
-init_optabv (code)
- enum rtx_code code;
+init_optabv (enum rtx_code code)
{
optab op = new_optab ();
op->code = code;
return op;
}
+/* Conversion optabs never go in the code_to_optab table. */
+static inline convert_optab
+init_convert_optab (enum rtx_code code)
+{
+ convert_optab op = new_convert_optab ();
+ op->code = code;
+ return op;
+}
+
/* Initialize the libfunc fields of an entire group of entries in some
optab. Each entry is set equal to a string consisting of a leading
pair of underscores followed by a generic operation name followed by
- a mode name (downshifted to lower case) followed by a single character
+ a mode name (downshifted to lowercase) followed by a single character
representing the number of operands for the given operation (which is
usually one of the characters '2', '3', or '4').
@@ -5030,12 +4966,8 @@ init_optabv (code)
*/
static void
-init_libfuncs (optable, first_mode, last_mode, opname, suffix)
- optab optable;
- int first_mode;
- int last_mode;
- const char *opname;
- int suffix;
+init_libfuncs (optab optable, int first_mode, int last_mode,
+ const char *opname, int suffix)
{
int mode;
unsigned opname_len = strlen (opname);
@@ -5060,8 +4992,7 @@ init_libfuncs (optable, first_mode, last_mode, opname, suffix)
*p = '\0';
optable->handlers[(int) mode].libfunc
- = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
- p - libfunc_name));
+ = init_one_libfunc (ggc_alloc_string (libfunc_name, p - libfunc_name));
}
}
@@ -5071,12 +5002,14 @@ init_libfuncs (optable, first_mode, last_mode, opname, suffix)
routine. (See above). */
static void
-init_integral_libfuncs (optable, opname, suffix)
- optab optable;
- const char *opname;
- int suffix;
+init_integral_libfuncs (optab optable, const char *opname, int suffix)
{
- init_libfuncs (optable, SImode, TImode, opname, suffix);
+ int maxsize = 2*BITS_PER_WORD;
+ if (maxsize < LONG_LONG_TYPE_SIZE)
+ maxsize = LONG_LONG_TYPE_SIZE;
+ init_libfuncs (optable, word_mode,
+ mode_for_size (maxsize, MODE_INT, 0),
+ opname, suffix);
}
/* Initialize the libfunc fields of an entire group of entries in some
@@ -5085,18 +5018,129 @@ init_integral_libfuncs (optable, opname, suffix)
routine. (See above). */
static void
-init_floating_libfuncs (optable, opname, suffix)
- optab optable;
- const char *opname;
- int suffix;
+init_floating_libfuncs (optab optable, const char *opname, int suffix)
+{
+ init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
+}
+
+/* Initialize the libfunc fields of an entire group of entries of an
+ inter-mode-class conversion optab. The string formation rules are
+ similar to the ones for init_libfuncs, above, but instead of having
+ a mode name and an operand count these functions have two mode names
+ and no operand count. */
+static void
+init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
+ enum mode_class from_class,
+ enum mode_class to_class)
+{
+ enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
+ enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
+ size_t opname_len = strlen (opname);
+ size_t max_mname_len = 0;
+
+ enum machine_mode fmode, tmode;
+ const char *fname, *tname;
+ const char *q;
+ char *libfunc_name, *suffix;
+ char *p;
+
+ for (fmode = first_from_mode;
+ fmode != VOIDmode;
+ fmode = GET_MODE_WIDER_MODE (fmode))
+ max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
+
+ for (tmode = first_to_mode;
+ tmode != VOIDmode;
+ tmode = GET_MODE_WIDER_MODE (tmode))
+ max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
+
+ libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
+ libfunc_name[0] = '_';
+ libfunc_name[1] = '_';
+ memcpy (&libfunc_name[2], opname, opname_len);
+ suffix = libfunc_name + opname_len + 2;
+
+ for (fmode = first_from_mode; fmode != VOIDmode;
+ fmode = GET_MODE_WIDER_MODE (fmode))
+ for (tmode = first_to_mode; tmode != VOIDmode;
+ tmode = GET_MODE_WIDER_MODE (tmode))
+ {
+ fname = GET_MODE_NAME (fmode);
+ tname = GET_MODE_NAME (tmode);
+
+ p = suffix;
+ for (q = fname; *q; p++, q++)
+ *p = TOLOWER (*q);
+ for (q = tname; *q; p++, q++)
+ *p = TOLOWER (*q);
+
+ *p = '\0';
+
+ tab->handlers[tmode][fmode].libfunc
+ = init_one_libfunc (ggc_alloc_string (libfunc_name,
+ p - libfunc_name));
+ }
+}
+
+/* Initialize the libfunc fields of an entire group of entries of an
+ intra-mode-class conversion optab. The string formation rules are
+ similar to the ones for init_libfunc, above. WIDENING says whether
+ the optab goes from narrow to wide modes or vice versa. These functions
+ have two mode names _and_ an operand count. */
+static void
+init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
+ enum mode_class class, bool widening)
{
- init_libfuncs (optable, SFmode, TFmode, opname, suffix);
+ enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
+ size_t opname_len = strlen (opname);
+ size_t max_mname_len = 0;
+
+ enum machine_mode nmode, wmode;
+ const char *nname, *wname;
+ const char *q;
+ char *libfunc_name, *suffix;
+ char *p;
+
+ for (nmode = first_mode; nmode != VOIDmode;
+ nmode = GET_MODE_WIDER_MODE (nmode))
+ max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
+
+ libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
+ libfunc_name[0] = '_';
+ libfunc_name[1] = '_';
+ memcpy (&libfunc_name[2], opname, opname_len);
+ suffix = libfunc_name + opname_len + 2;
+
+ for (nmode = first_mode; nmode != VOIDmode;
+ nmode = GET_MODE_WIDER_MODE (nmode))
+ for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
+ wmode = GET_MODE_WIDER_MODE (wmode))
+ {
+ nname = GET_MODE_NAME (nmode);
+ wname = GET_MODE_NAME (wmode);
+
+ p = suffix;
+ for (q = widening ? nname : wname; *q; p++, q++)
+ *p = TOLOWER (*q);
+ for (q = widening ? wname : nname; *q; p++, q++)
+ *p = TOLOWER (*q);
+
+ *p++ = '2';
+ *p = '\0';
+
+ tab->handlers[widening ? wmode : nmode]
+ [widening ? nmode : wmode].libfunc
+ = init_one_libfunc (ggc_alloc_string (libfunc_name,
+ p - libfunc_name));
+ }
}
+
rtx
-init_one_libfunc (name)
- const char *name;
+init_one_libfunc (const char *name)
{
+ rtx symbol;
+
/* Create a FUNCTION_DECL that can be passed to
targetm.encode_section_info. */
/* ??? We don't have any type information except for this is
@@ -5107,40 +5151,49 @@ init_one_libfunc (name)
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
- /* Return the symbol_ref from the mem rtx. */
- return XEXP (DECL_RTL (decl), 0);
+ symbol = XEXP (DECL_RTL (decl), 0);
+
+ /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
+ are the flags assigned by targetm.encode_section_info. */
+ SYMBOL_REF_DECL (symbol) = 0;
+
+ return symbol;
+}
+
+/* Call this to reset the function entry for one optab (OPTABLE) in mode
+ MODE to NAME, which should be either 0 or a string constant. */
+void
+set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
+{
+ if (name)
+ optable->handlers[mode].libfunc = init_one_libfunc (name);
+ else
+ optable->handlers[mode].libfunc = 0;
+}
+
+/* Call this to reset the function entry for one conversion optab
+ (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
+ either 0 or a string constant. */
+void
+set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
+ enum machine_mode fmode, const char *name)
+{
+ if (name)
+ optable->handlers[tmode][fmode].libfunc = init_one_libfunc (name);
+ else
+ optable->handlers[tmode][fmode].libfunc = 0;
}
/* Call this once to initialize the contents of the optabs
appropriately for the current target machine. */
void
-init_optabs ()
+init_optabs (void)
{
- unsigned int i, j, k;
+ unsigned int i;
/* Start by initializing all tables to contain CODE_FOR_nothing. */
- for (i = 0; i < ARRAY_SIZE (fixtab); i++)
- for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
- for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
- fixtab[i][j][k] = CODE_FOR_nothing;
-
- for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
- for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
- for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
- fixtrunctab[i][j][k] = CODE_FOR_nothing;
-
- for (i = 0; i < ARRAY_SIZE (floattab); i++)
- for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
- for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
- floattab[i][j][k] = CODE_FOR_nothing;
-
- for (i = 0; i < ARRAY_SIZE (extendtab); i++)
- for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
- for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
- extendtab[i][j][k] = CODE_FOR_nothing;
-
for (i = 0; i < NUM_RTX_CODE; i++)
setcc_gen_code[i] = CODE_FOR_nothing;
@@ -5179,6 +5232,8 @@ init_optabs ()
smax_optab = init_optab (SMAX);
umin_optab = init_optab (UMIN);
umax_optab = init_optab (UMAX);
+ pow_optab = init_optab (UNKNOWN);
+ atan2_optab = init_optab (UNKNOWN);
/* These three have codes assigned exclusively for the sake of
have_insn_for. */
@@ -5188,27 +5243,64 @@ init_optabs ()
ucmp_optab = init_optab (UNKNOWN);
tst_optab = init_optab (UNKNOWN);
+
+ eq_optab = init_optab (EQ);
+ ne_optab = init_optab (NE);
+ gt_optab = init_optab (GT);
+ ge_optab = init_optab (GE);
+ lt_optab = init_optab (LT);
+ le_optab = init_optab (LE);
+ unord_optab = init_optab (UNORDERED);
+
neg_optab = init_optab (NEG);
negv_optab = init_optabv (NEG);
abs_optab = init_optab (ABS);
absv_optab = init_optabv (ABS);
+ addcc_optab = init_optab (UNKNOWN);
one_cmpl_optab = init_optab (NOT);
ffs_optab = init_optab (FFS);
+ clz_optab = init_optab (CLZ);
+ ctz_optab = init_optab (CTZ);
+ popcount_optab = init_optab (POPCOUNT);
+ parity_optab = init_optab (PARITY);
sqrt_optab = init_optab (SQRT);
+ floor_optab = init_optab (UNKNOWN);
+ ceil_optab = init_optab (UNKNOWN);
+ round_optab = init_optab (UNKNOWN);
+ btrunc_optab = init_optab (UNKNOWN);
+ nearbyint_optab = init_optab (UNKNOWN);
sin_optab = init_optab (UNKNOWN);
cos_optab = init_optab (UNKNOWN);
exp_optab = init_optab (UNKNOWN);
log_optab = init_optab (UNKNOWN);
+ tan_optab = init_optab (UNKNOWN);
+ atan_optab = init_optab (UNKNOWN);
strlen_optab = init_optab (UNKNOWN);
cbranch_optab = init_optab (UNKNOWN);
cmov_optab = init_optab (UNKNOWN);
cstore_optab = init_optab (UNKNOWN);
push_optab = init_optab (UNKNOWN);
+ vec_extract_optab = init_optab (UNKNOWN);
+ vec_set_optab = init_optab (UNKNOWN);
+ vec_init_optab = init_optab (UNKNOWN);
+ /* Conversions. */
+ sext_optab = init_convert_optab (SIGN_EXTEND);
+ zext_optab = init_convert_optab (ZERO_EXTEND);
+ trunc_optab = init_convert_optab (TRUNCATE);
+ sfix_optab = init_convert_optab (FIX);
+ ufix_optab = init_convert_optab (UNSIGNED_FIX);
+ sfixtrunc_optab = init_convert_optab (UNKNOWN);
+ ufixtrunc_optab = init_convert_optab (UNKNOWN);
+ sfloat_optab = init_convert_optab (FLOAT);
+ ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
+
for (i = 0; i < NUM_MACHINE_MODES; i++)
{
movstr_optab[i] = CODE_FOR_nothing;
clrstr_optab[i] = CODE_FOR_nothing;
+ cmpstr_optab[i] = CODE_FOR_nothing;
+ cmpmem_optab[i] = CODE_FOR_nothing;
#ifdef HAVE_SECONDARY_RELOADS
reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
@@ -5218,14 +5310,6 @@ init_optabs ()
/* Fill in the optabs with the insns we support. */
init_all_optabs ();
-#ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
- /* This flag says the same insns that convert to a signed fixnum
- also convert validly to an unsigned one. */
- for (i = 0; i < NUM_MACHINE_MODES; i++)
- for (j = 0; j < NUM_MACHINE_MODES; j++)
- fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
-#endif
-
/* Initialize the optabs with the names of the library functions. */
init_integral_libfuncs (add_optab, "add", '3');
init_floating_libfuncs (add_optab, "add", '3');
@@ -5266,78 +5350,44 @@ init_optabs ()
init_floating_libfuncs (negv_optab, "neg", '2');
init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
init_integral_libfuncs (ffs_optab, "ffs", '2');
+ init_integral_libfuncs (clz_optab, "clz", '2');
+ init_integral_libfuncs (ctz_optab, "ctz", '2');
+ init_integral_libfuncs (popcount_optab, "popcount", '2');
+ init_integral_libfuncs (parity_optab, "parity", '2');
/* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
init_integral_libfuncs (cmp_optab, "cmp", '2');
init_integral_libfuncs (ucmp_optab, "ucmp", '2');
init_floating_libfuncs (cmp_optab, "cmp", '2');
-#ifdef MULSI3_LIBCALL
- smul_optab->handlers[(int) SImode].libfunc
- = init_one_libfunc (MULSI3_LIBCALL);
-#endif
-#ifdef MULDI3_LIBCALL
- smul_optab->handlers[(int) DImode].libfunc
- = init_one_libfunc (MULDI3_LIBCALL);
-#endif
-
-#ifdef DIVSI3_LIBCALL
- sdiv_optab->handlers[(int) SImode].libfunc
- = init_one_libfunc (DIVSI3_LIBCALL);
-#endif
-#ifdef DIVDI3_LIBCALL
- sdiv_optab->handlers[(int) DImode].libfunc
- = init_one_libfunc (DIVDI3_LIBCALL);
-#endif
-
-#ifdef UDIVSI3_LIBCALL
- udiv_optab->handlers[(int) SImode].libfunc
- = init_one_libfunc (UDIVSI3_LIBCALL);
-#endif
-#ifdef UDIVDI3_LIBCALL
- udiv_optab->handlers[(int) DImode].libfunc
- = init_one_libfunc (UDIVDI3_LIBCALL);
-#endif
-
-#ifdef MODSI3_LIBCALL
- smod_optab->handlers[(int) SImode].libfunc
- = init_one_libfunc (MODSI3_LIBCALL);
-#endif
-#ifdef MODDI3_LIBCALL
- smod_optab->handlers[(int) DImode].libfunc
- = init_one_libfunc (MODDI3_LIBCALL);
-#endif
-
-#ifdef UMODSI3_LIBCALL
- umod_optab->handlers[(int) SImode].libfunc
- = init_one_libfunc (UMODSI3_LIBCALL);
-#endif
-#ifdef UMODDI3_LIBCALL
- umod_optab->handlers[(int) DImode].libfunc
- = init_one_libfunc (UMODDI3_LIBCALL);
-#endif
-
- /* Use cabs for DC complex abs, since systems generally have cabs.
- Don't define any libcall for SCmode, so that cabs will be used. */
- abs_optab->handlers[(int) DCmode].libfunc
- = init_one_libfunc ("cabs");
+ /* EQ etc are floating point only. */
+ init_floating_libfuncs (eq_optab, "eq", '2');
+ init_floating_libfuncs (ne_optab, "ne", '2');
+ init_floating_libfuncs (gt_optab, "gt", '2');
+ init_floating_libfuncs (ge_optab, "ge", '2');
+ init_floating_libfuncs (lt_optab, "lt", '2');
+ init_floating_libfuncs (le_optab, "le", '2');
+ init_floating_libfuncs (unord_optab, "unord", '2');
+
+ /* Conversions. */
+ init_interclass_conv_libfuncs (sfloat_optab, "float", MODE_INT, MODE_FLOAT);
+ init_interclass_conv_libfuncs (sfix_optab, "fix", MODE_FLOAT, MODE_INT);
+ init_interclass_conv_libfuncs (ufix_optab, "fixuns", MODE_FLOAT, MODE_INT);
+
+ /* sext_optab is also used for FLOAT_EXTEND. */
+ init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
+ init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
+
+ /* Use cabs for double complex abs, since systems generally have cabs.
+ Don't define any libcall for float complex, so that cabs will be used. */
+ if (complex_double_type_node)
+ abs_optab->handlers[TYPE_MODE (complex_double_type_node)].libfunc
+ = init_one_libfunc ("cabs");
/* The ffs function operates on `int'. */
ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
= init_one_libfunc ("ffs");
- extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
- extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
- extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
- extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
- extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
-
- truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
- truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
- trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
- truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
- trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
-
abort_libfunc = init_one_libfunc ("abort");
memcpy_libfunc = init_one_libfunc ("memcpy");
memmove_libfunc = init_one_libfunc ("memmove");
@@ -5346,6 +5396,7 @@ init_optabs ()
bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
memset_libfunc = init_one_libfunc ("memset");
bzero_libfunc = init_one_libfunc ("bzero");
+ setbits_libfunc = init_one_libfunc ("__setbits");
unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
? "_Unwind_SjLj_Resume"
@@ -5361,116 +5412,28 @@ init_optabs ()
unwind_sjlj_unregister_libfunc
= init_one_libfunc ("_Unwind_SjLj_Unregister");
- eqhf2_libfunc = init_one_libfunc ("__eqhf2");
- nehf2_libfunc = init_one_libfunc ("__nehf2");
- gthf2_libfunc = init_one_libfunc ("__gthf2");
- gehf2_libfunc = init_one_libfunc ("__gehf2");
- lthf2_libfunc = init_one_libfunc ("__lthf2");
- lehf2_libfunc = init_one_libfunc ("__lehf2");
- unordhf2_libfunc = init_one_libfunc ("__unordhf2");
-
- eqsf2_libfunc = init_one_libfunc ("__eqsf2");
- nesf2_libfunc = init_one_libfunc ("__nesf2");
- gtsf2_libfunc = init_one_libfunc ("__gtsf2");
- gesf2_libfunc = init_one_libfunc ("__gesf2");
- ltsf2_libfunc = init_one_libfunc ("__ltsf2");
- lesf2_libfunc = init_one_libfunc ("__lesf2");
- unordsf2_libfunc = init_one_libfunc ("__unordsf2");
-
- eqdf2_libfunc = init_one_libfunc ("__eqdf2");
- nedf2_libfunc = init_one_libfunc ("__nedf2");
- gtdf2_libfunc = init_one_libfunc ("__gtdf2");
- gedf2_libfunc = init_one_libfunc ("__gedf2");
- ltdf2_libfunc = init_one_libfunc ("__ltdf2");
- ledf2_libfunc = init_one_libfunc ("__ledf2");
- unorddf2_libfunc = init_one_libfunc ("__unorddf2");
-
- eqxf2_libfunc = init_one_libfunc ("__eqxf2");
- nexf2_libfunc = init_one_libfunc ("__nexf2");
- gtxf2_libfunc = init_one_libfunc ("__gtxf2");
- gexf2_libfunc = init_one_libfunc ("__gexf2");
- ltxf2_libfunc = init_one_libfunc ("__ltxf2");
- lexf2_libfunc = init_one_libfunc ("__lexf2");
- unordxf2_libfunc = init_one_libfunc ("__unordxf2");
-
- eqtf2_libfunc = init_one_libfunc ("__eqtf2");
- netf2_libfunc = init_one_libfunc ("__netf2");
- gttf2_libfunc = init_one_libfunc ("__gttf2");
- getf2_libfunc = init_one_libfunc ("__getf2");
- lttf2_libfunc = init_one_libfunc ("__lttf2");
- letf2_libfunc = init_one_libfunc ("__letf2");
- unordtf2_libfunc = init_one_libfunc ("__unordtf2");
-
- floatsisf_libfunc = init_one_libfunc ("__floatsisf");
- floatdisf_libfunc = init_one_libfunc ("__floatdisf");
- floattisf_libfunc = init_one_libfunc ("__floattisf");
-
- floatsidf_libfunc = init_one_libfunc ("__floatsidf");
- floatdidf_libfunc = init_one_libfunc ("__floatdidf");
- floattidf_libfunc = init_one_libfunc ("__floattidf");
-
- floatsixf_libfunc = init_one_libfunc ("__floatsixf");
- floatdixf_libfunc = init_one_libfunc ("__floatdixf");
- floattixf_libfunc = init_one_libfunc ("__floattixf");
-
- floatsitf_libfunc = init_one_libfunc ("__floatsitf");
- floatditf_libfunc = init_one_libfunc ("__floatditf");
- floattitf_libfunc = init_one_libfunc ("__floattitf");
-
- fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
- fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
- fixsfti_libfunc = init_one_libfunc ("__fixsfti");
-
- fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
- fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
- fixdfti_libfunc = init_one_libfunc ("__fixdfti");
-
- fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
- fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
- fixxfti_libfunc = init_one_libfunc ("__fixxfti");
-
- fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
- fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
- fixtfti_libfunc = init_one_libfunc ("__fixtfti");
-
- fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
- fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
- fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
-
- fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
- fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
- fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
-
- fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
- fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
- fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
-
- fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
- fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
- fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
-
/* For function entry/exit instrumentation. */
profile_function_entry_libfunc
= init_one_libfunc ("__cyg_profile_func_enter");
profile_function_exit_libfunc
= init_one_libfunc ("__cyg_profile_func_exit");
+ gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
+ gcov_init_libfunc = init_one_libfunc ("__gcov_init");
+
if (HAVE_conditional_trap)
trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
-#ifdef INIT_TARGET_OPTABS
/* Allow the target to add more libcalls or rename some, etc. */
- INIT_TARGET_OPTABS;
-#endif
+ targetm.init_libfuncs ();
}
/* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
CODE. Return 0 on failure. */
rtx
-gen_cond_trap (code, op1, op2, tcode)
- enum rtx_code code ATTRIBUTE_UNUSED;
- rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
+gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
+ rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
{
enum machine_mode mode = GET_MODE (op1);
enum insn_code icode;
diff --git a/contrib/gcc/optabs.h b/contrib/gcc/optabs.h
index fd80d8267202..4f39e359b79a 100644
--- a/contrib/gcc/optabs.h
+++ b/contrib/gcc/optabs.h
@@ -1,5 +1,5 @@
/* Definitions for code generation pass of GNU compiler.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -38,19 +38,32 @@ Boston, MA 02111-1307, USA. */
A few optabs, such as move_optab and cmp_optab, are used
by special code. */
+struct optab_handlers GTY(())
+{
+ enum insn_code insn_code;
+ rtx libfunc;
+};
+
struct optab GTY(())
{
enum rtx_code code;
- struct optab_handlers {
- enum insn_code insn_code;
- rtx libfunc;
- } handlers [NUM_MACHINE_MODES];
+ struct optab_handlers handlers[NUM_MACHINE_MODES];
};
typedef struct optab * 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 GTY(())
+{
+ enum rtx_code code;
+ struct optab_handlers handlers[NUM_MACHINE_MODES][NUM_MACHINE_MODES];
+};
+typedef struct convert_optab *convert_optab;
+
/* Given an enum insn_code, access the function to construct
the body of that kind of insn. */
-#define GEN_FCN(CODE) (*insn_data[(int) (CODE)].genfun)
+#define GEN_FCN(CODE) (insn_data[CODE].genfun)
/* Enumeration of valid indexes into optab_table. */
enum optab_index
@@ -93,7 +106,7 @@ enum optab_index
/* Arithmetic shift left */
OTI_ashl,
/* Logical shift right */
- OTI_lshr,
+ OTI_lshr,
/* Arithmetic shift right */
OTI_ashr,
/* Rotate left */
@@ -108,6 +121,10 @@ enum optab_index
OTI_umin,
/* Unsigned maximum value */
OTI_umax,
+ /* Power */
+ OTI_pow,
+ /* Arc tangent of y/x */
+ OTI_atan2,
/* Move instruction. */
OTI_mov,
@@ -123,8 +140,12 @@ enum optab_index
OTI_absv,
/* Bitwise not */
OTI_one_cmpl,
- /* Find first bit set */
+ /* Bit scanning and counting */
OTI_ffs,
+ OTI_clz,
+ OTI_ctz,
+ OTI_popcount,
+ OTI_parity,
/* Square root */
OTI_sqrt,
/* Sine */
@@ -135,6 +156,16 @@ enum optab_index
OTI_exp,
/* Natural Logarithm */
OTI_log,
+ /* Rounding functions */
+ OTI_floor,
+ OTI_ceil,
+ OTI_trunc,
+ OTI_round,
+ OTI_nearbyint,
+ /* Tangent */
+ OTI_tan,
+ /* Inverse tangent */
+ OTI_atan,
/* Compare insn; two operands. */
OTI_cmp,
@@ -143,6 +174,15 @@ enum optab_index
/* tst insn; compare one operand against 0 */
OTI_tst,
+ /* Floating point comparison optabs - used primarily for libfuncs */
+ OTI_eq,
+ OTI_ne,
+ OTI_gt,
+ OTI_ge,
+ OTI_lt,
+ OTI_le,
+ OTI_unord,
+
/* String length */
OTI_strlen,
@@ -150,10 +190,20 @@ enum optab_index
OTI_cbranch,
OTI_cmov,
OTI_cstore,
-
+
/* Push instruction. */
OTI_push,
+ /* Conditional add instruction. */
+ OTI_addcc,
+
+ /* Set specified field of vector operand. */
+ OTI_vec_set,
+ /* Extract specified field of vector operand. */
+ OTI_vec_extract,
+ /* Initialize vector operand. */
+ OTI_vec_init,
+
OTI_MAX
};
@@ -189,6 +239,8 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define smax_optab (optab_table[OTI_smax])
#define umin_optab (optab_table[OTI_umin])
#define umax_optab (optab_table[OTI_umax])
+#define pow_optab (optab_table[OTI_pow])
+#define atan2_optab (optab_table[OTI_atan2])
#define mov_optab (optab_table[OTI_mov])
#define movstrict_optab (optab_table[OTI_movstrict])
@@ -199,30 +251,77 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define absv_optab (optab_table[OTI_absv])
#define one_cmpl_optab (optab_table[OTI_one_cmpl])
#define ffs_optab (optab_table[OTI_ffs])
+#define clz_optab (optab_table[OTI_clz])
+#define ctz_optab (optab_table[OTI_ctz])
+#define popcount_optab (optab_table[OTI_popcount])
+#define parity_optab (optab_table[OTI_parity])
#define sqrt_optab (optab_table[OTI_sqrt])
#define sin_optab (optab_table[OTI_sin])
#define cos_optab (optab_table[OTI_cos])
#define exp_optab (optab_table[OTI_exp])
#define log_optab (optab_table[OTI_log])
+#define floor_optab (optab_table[OTI_floor])
+#define ceil_optab (optab_table[OTI_ceil])
+#define btrunc_optab (optab_table[OTI_trunc])
+#define round_optab (optab_table[OTI_round])
+#define nearbyint_optab (optab_table[OTI_nearbyint])
+#define tan_optab (optab_table[OTI_tan])
+#define atan_optab (optab_table[OTI_atan])
#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])
+#define gt_optab (optab_table[OTI_gt])
+#define ge_optab (optab_table[OTI_ge])
+#define lt_optab (optab_table[OTI_lt])
+#define le_optab (optab_table[OTI_le])
+#define unord_optab (optab_table[OTI_unord])
+
#define strlen_optab (optab_table[OTI_strlen])
#define cbranch_optab (optab_table[OTI_cbranch])
#define cmov_optab (optab_table[OTI_cmov])
#define cstore_optab (optab_table[OTI_cstore])
#define push_optab (optab_table[OTI_push])
+#define addcc_optab (optab_table[OTI_addcc])
+
+#define vec_set_optab (optab_table[OTI_vec_set])
+#define vec_extract_optab (optab_table[OTI_vec_extract])
+#define vec_init_optab (optab_table[OTI_vec_init])
+
+/* Conversion optabs have their own table and indexes. */
+enum convert_optab_index
+{
+ CTI_sext,
+ CTI_zext,
+ CTI_trunc,
+
+ CTI_sfix,
+ CTI_ufix,
-/* Tables of patterns for extending one integer mode to another. */
-extern enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
+ CTI_sfixtrunc,
+ CTI_ufixtrunc,
-/* Tables of patterns for converting between fixed and floating point. */
-extern enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
-extern enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
-extern enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
+ CTI_sfloat,
+ CTI_ufloat,
+
+ CTI_MAX
+};
+
+extern GTY(()) convert_optab convert_optab_table[CTI_MAX];
+
+#define sext_optab (convert_optab_table[CTI_sext])
+#define zext_optab (convert_optab_table[CTI_zext])
+#define trunc_optab (convert_optab_table[CTI_trunc])
+#define sfix_optab (convert_optab_table[CTI_sfix])
+#define ufix_optab (convert_optab_table[CTI_ufix])
+#define sfixtrunc_optab (convert_optab_table[CTI_sfixtrunc])
+#define ufixtrunc_optab (convert_optab_table[CTI_ufixtrunc])
+#define sfloat_optab (convert_optab_table[CTI_sfloat])
+#define ufloat_optab (convert_optab_table[CTI_ufloat])
/* These arrays record the insn_code of insns that may be needed to
perform input and output reloads of special objects. They provide a
@@ -231,10 +330,10 @@ extern enum insn_code reload_in_optab[NUM_MACHINE_MODES];
extern enum insn_code reload_out_optab[NUM_MACHINE_MODES];
/* Contains the optab used for each rtx code. */
-extern optab code_to_optab[NUM_RTX_CODE + 1];
+extern GTY(()) optab code_to_optab[NUM_RTX_CODE + 1];
-typedef rtx (*rtxfun) PARAMS ((rtx));
+typedef rtx (*rtxfun) (rtx);
/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
gives the gen_function to make a branch to test that condition. */
@@ -260,45 +359,51 @@ extern enum insn_code movstr_optab[NUM_MACHINE_MODES];
/* This array records the insn_code of insns to perform block clears. */
extern enum insn_code clrstr_optab[NUM_MACHINE_MODES];
+/* These arrays record the insn_code of two different kinds of insns
+ to perform block compares. */
+extern enum insn_code cmpstr_optab[NUM_MACHINE_MODES];
+extern enum insn_code cmpmem_optab[NUM_MACHINE_MODES];
+
/* Define functions given in optabs.c. */
/* Expand a binary operation given optab and rtx operands. */
-extern rtx expand_binop PARAMS ((enum machine_mode, optab, rtx, rtx, rtx,
- int, enum optab_methods));
+extern rtx expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int,
+ enum optab_methods);
/* Expand a binary operation with both signed and unsigned forms. */
-extern rtx sign_expand_binop PARAMS ((enum machine_mode, optab, optab, rtx,
- rtx, rtx, int, enum optab_methods));
+extern rtx sign_expand_binop (enum machine_mode, optab, optab, rtx, rtx,
+ rtx, int, enum optab_methods);
/* Generate code to perform an operation on two operands with two results. */
-extern int expand_twoval_binop PARAMS ((optab, rtx, rtx, rtx, rtx, int));
+extern int expand_twoval_binop (optab, rtx, rtx, rtx, rtx, int);
/* Expand a unary arithmetic operation given optab rtx operand. */
-extern rtx expand_unop PARAMS ((enum machine_mode, optab, rtx, rtx, int));
+extern rtx expand_unop (enum machine_mode, optab, rtx, rtx, int);
/* Expand the absolute value operation. */
-extern rtx expand_abs PARAMS ((enum machine_mode, rtx, rtx, int, int));
+extern rtx expand_abs_nojump (enum machine_mode, rtx, rtx, int);
+extern rtx expand_abs (enum machine_mode, rtx, rtx, int, int);
/* Expand the complex absolute value operation. */
-extern rtx expand_complex_abs PARAMS ((enum machine_mode, rtx, rtx, int));
+extern rtx expand_complex_abs (enum machine_mode, rtx, rtx, int);
/* Generate an instruction with a given INSN_CODE with an output and
an input. */
-extern void emit_unop_insn PARAMS ((int, rtx, rtx, enum rtx_code));
+extern void emit_unop_insn (int, rtx, rtx, enum rtx_code);
/* Emit code to perform a series of operations on a multi-word quantity, one
word at a time. */
-extern rtx emit_no_conflict_block PARAMS ((rtx, rtx, rtx, rtx, rtx));
+extern rtx emit_no_conflict_block (rtx, rtx, rtx, rtx, rtx);
/* Emit one rtl instruction to store zero in specified rtx. */
-extern void emit_clr_insn PARAMS ((rtx));
+extern void emit_clr_insn (rtx);
/* Emit one rtl insn to store 1 in specified rtx assuming it contains 0. */
-extern void emit_0_to_1_insn PARAMS ((rtx));
+extern void emit_0_to_1_insn (rtx);
/* Emit one rtl insn to compare two rtx's. */
-extern void emit_cmp_insn PARAMS ((rtx, rtx, enum rtx_code, rtx,
- enum machine_mode, int));
+extern void emit_cmp_insn (rtx, rtx, enum rtx_code, rtx, enum machine_mode,
+ int);
/* The various uses that a comparison can have; used by can_compare_p:
jumps, conditional moves, store flag operations. */
@@ -311,30 +416,34 @@ enum can_compare_purpose
/* Nonzero if a compare of mode MODE can be done straightforwardly
(without splitting it into pieces). */
-extern int can_compare_p PARAMS ((enum rtx_code, enum machine_mode,
- enum can_compare_purpose));
+extern int can_compare_p (enum rtx_code, enum machine_mode,
+ enum can_compare_purpose);
-extern rtx prepare_operand PARAMS ((int, rtx, int, enum machine_mode,
- enum machine_mode, int));
+extern rtx prepare_operand (int, rtx, int, enum machine_mode,
+ enum machine_mode, int);
/* Return the INSN_CODE to use for an extend operation. */
-extern enum insn_code can_extend_p PARAMS ((enum machine_mode,
- enum machine_mode, int));
+extern enum insn_code can_extend_p (enum machine_mode, enum machine_mode, int);
/* Generate the body of an insn to extend Y (with mode MFROM)
into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
-extern rtx gen_extend_insn PARAMS ((rtx, rtx, enum machine_mode,
- enum machine_mode, int));
+extern rtx gen_extend_insn (rtx, rtx, enum machine_mode,
+ enum machine_mode, int);
/* Initialize the tables that control conversion between fixed and
floating values. */
-extern void init_fixtab PARAMS ((void));
-extern void init_floattab PARAMS ((void));
+extern void init_fixtab (void);
+extern void init_floattab (void);
+
+/* Call this to reset the function entry for one optab. */
+extern void set_optab_libfunc (optab, enum machine_mode, const char *);
+extern void set_conv_libfunc (convert_optab, enum machine_mode,
+ enum machine_mode, const char *);
/* Generate code for a FLOAT_EXPR. */
-extern void expand_float PARAMS ((rtx, rtx, int));
+extern void expand_float (rtx, rtx, int);
/* Generate code for a FIX_EXPR. */
-extern void expand_fix PARAMS ((rtx, rtx, int));
+extern void expand_fix (rtx, rtx, int);
#endif /* GCC_OPTABS_H */
diff --git a/contrib/gcc/opts.c b/contrib/gcc/opts.c
new file mode 100644
index 000000000000..ff50ad197392
--- /dev/null
+++ b/contrib/gcc/opts.c
@@ -0,0 +1,1878 @@
+/* Command line option handling.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Neil Booth.
+
+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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "intl.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "rtl.h"
+#include "ggc.h"
+#include "output.h"
+#include "langhooks.h"
+#include "opts.h"
+#include "options.h"
+#include "flags.h"
+#include "toplev.h"
+#include "params.h"
+#include "diagnostic.h"
+#include "tm_p.h" /* For OPTIMIZATION_OPTIONS. */
+#include "insn-attr.h" /* For INSN_SCHEDULING. */
+
+/* Value of the -G xx switch, and whether it was passed or not. */
+unsigned HOST_WIDE_INT g_switch_value;
+bool g_switch_set;
+
+/* True if we should exit after parsing options. */
+bool exit_after_options;
+
+/* If -version. */
+bool version_flag;
+
+/* Print various extra warnings. -W/-Wextra. */
+bool extra_warnings;
+
+/* Don't print warning messages. -w. */
+bool inhibit_warnings;
+
+/* Treat warnings as errors. -Werror. */
+bool warnings_are_errors;
+
+/* Warn if a function returns an aggregate, since there are often
+ incompatible calling conventions for doing this. */
+bool warn_aggregate_return;
+
+/* Nonzero means warn about pointer casts that increase the required
+ alignment of the target type (and might therefore lead to a crash
+ due to a misaligned access). */
+bool warn_cast_align;
+
+/* Nonzero means warn about uses of __attribute__((deprecated))
+ declarations. */
+bool warn_deprecated_decl = true;
+
+/* Warn when an optimization pass is disabled. */
+bool warn_disabled_optimization;
+
+/* Nonzero means warn if inline function is too large. */
+bool warn_inline;
+
+/* True to warn about any objects definitions whose size is larger
+ than N bytes. Also want about function definitions whose returned
+ values are larger than N bytes, where N is `larger_than_size'. */
+bool warn_larger_than;
+HOST_WIDE_INT larger_than_size;
+
+/* Warn about functions which might be candidates for attribute noreturn. */
+bool warn_missing_noreturn;
+
+/* True to warn about code which is never reached. */
+bool warn_notreached;
+
+/* Warn if packed attribute on struct is unnecessary and inefficient. */
+bool warn_packed;
+
+/* Warn when gcc pads a structure to an alignment boundary. */
+bool warn_padded;
+
+/* True means warn about all declarations which shadow others. */
+bool warn_shadow;
+
+/* Nonzero means warn about constructs which might not be
+ strict-aliasing safe. */
+bool warn_strict_aliasing;
+
+/* True to warn if a switch on an enum, that does not have a default
+ case, fails to have a case for every enum value. */
+bool warn_switch;
+
+/* Warn if a switch does not have a default case. */
+bool warn_switch_default;
+
+/* Warn if a switch on an enum fails to have a case for every enum
+ value (regardless of the presence or otherwise of a default case). */
+bool warn_switch_enum;
+
+/* Don't suppress warnings from system headers. -Wsystem-headers. */
+bool warn_system_headers;
+
+/* True to warn about variables used before they are initialized. */
+int warn_uninitialized;
+
+/* True to warn about unused variables, functions et.al. */
+bool warn_unused_function;
+bool warn_unused_label;
+bool warn_unused_parameter;
+bool warn_unused_variable;
+bool warn_unused_value;
+
+/* Hack for cooperation between set_Wunused and set_Wextra. */
+static bool maybe_warn_unused_parameter;
+
+/* Type(s) of debugging information we are producing (if any). See
+ flags.h for the definitions of the different possible types of
+ debugging information. */
+enum debug_info_type write_symbols = NO_DEBUG;
+
+/* Level of debugging information we are producing. See flags.h for
+ the definitions of the different possible levels. */
+enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
+
+/* Nonzero means use GNU-only extensions in the generated symbolic
+ debugging information. Currently, this only has an effect when
+ write_symbols is set to DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */
+bool use_gnu_debug_info_extensions;
+
+/* Columns of --help display. */
+static unsigned int columns = 80;
+
+/* What to print when a switch has no documentation. */
+static const char undocumented_msg[] = N_("This switch lacks documentation");
+
+/* Used for bookkeeping on whether user set these flags so
+ -fprofile-use/-fprofile-generate does not use them. */
+static bool profile_arc_flag_set, flag_profile_values_set;
+static bool flag_unroll_loops_set, flag_tracer_set;
+static bool flag_value_profile_transformations_set;
+static bool flag_peel_loops_set, flag_branch_probabilities_set;
+
+/* Input file names. */
+const char **in_fnames;
+unsigned num_in_fnames;
+
+static size_t find_opt (const char *, int);
+static int common_handle_option (size_t scode, const char *arg, int value);
+static void handle_param (const char *);
+static void set_Wextra (int);
+static unsigned int handle_option (const char **argv, unsigned int lang_mask);
+static char *write_langs (unsigned int lang_mask);
+static void complain_wrong_lang (const char *, const struct cl_option *,
+ unsigned int lang_mask);
+static void handle_options (unsigned int, const char **, unsigned int);
+static void wrap_help (const char *help, const char *item, unsigned int);
+static void print_help (void);
+static void print_param_help (void);
+static void print_filtered_help (unsigned int flag);
+static unsigned int print_switch (const char *text, unsigned int indent);
+static void set_debug_level (enum debug_info_type type, int extended,
+ const char *arg);
+
+/* Perform a binary search to find which option the command-line INPUT
+ matches. Returns its index in the option array, and N_OPTS
+ (cl_options_count) on failure.
+
+ This routine is quite subtle. A normal binary search is not good
+ enough because some options can be suffixed with an argument, and
+ multiple sub-matches can occur, e.g. input of "-pedantic" matching
+ the initial substring of "-pedantic-errors".
+
+ A more complicated example is -gstabs. It should match "-g" with
+ an argument of "stabs". Suppose, however, that the number and list
+ of switches are such that the binary search tests "-gen-decls"
+ before having tested "-g". This doesn't match, and as "-gen-decls"
+ is less than "-gstabs", it will become the lower bound of the
+ binary search range, and "-g" will never be seen. To resolve this
+ issue, opts.sh makes "-gen-decls" point, via the back_chain member,
+ to "-g" so that failed searches that end between "-gen-decls" and
+ the lexicographically subsequent switch know to go back and see if
+ "-g" causes a match (which it does in this example).
+
+ This search is done in such a way that the longest match for the
+ front end in question wins. If there is no match for the current
+ front end, the longest match for a different front end is returned
+ (or N_OPTS if none) and the caller emits an error message. */
+static size_t
+find_opt (const char *input, int lang_mask)
+{
+ size_t mn, mx, md, opt_len;
+ size_t match_wrong_lang;
+ int comp;
+
+ mn = 0;
+ mx = cl_options_count;
+
+ /* Find mn such this lexicographical inequality holds:
+ cl_options[mn] <= input < cl_options[mn + 1]. */
+ while (mx - mn > 1)
+ {
+ md = (mn + mx) / 2;
+ opt_len = cl_options[md].opt_len;
+ comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
+
+ if (comp < 0)
+ mx = md;
+ else
+ mn = md;
+ }
+
+ /* This is the switch that is the best match but for a different
+ front end, or cl_options_count if there is no match at all. */
+ match_wrong_lang = cl_options_count;
+
+ /* Backtrace the chain of possible matches, returning the longest
+ one, if any, that fits best. With current GCC switches, this
+ loop executes at most twice. */
+ do
+ {
+ const struct cl_option *opt = &cl_options[mn];
+
+ /* Is this switch a prefix of the input? */
+ if (!strncmp (input, opt->opt_text + 1, opt->opt_len))
+ {
+ /* If language is OK, and the match is exact or the switch
+ takes a joined argument, return it. */
+ if ((opt->flags & lang_mask)
+ && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
+ return mn;
+
+ /* If we haven't remembered a prior match, remember this
+ one. Any prior match is necessarily better. */
+ if (match_wrong_lang == cl_options_count)
+ match_wrong_lang = mn;
+ }
+
+ /* Try the next possibility. This is cl_options_count if there
+ are no more. */
+ mn = opt->back_chain;
+ }
+ while (mn != cl_options_count);
+
+ /* Return the best wrong match, or cl_options_count if none. */
+ return match_wrong_lang;
+}
+
+/* If ARG is a non-negative integer made up solely of digits, return its
+ value, otherwise return -1. */
+static int
+integral_argument (const char *arg)
+{
+ const char *p = arg;
+
+ while (*p && ISDIGIT (*p))
+ p++;
+
+ if (*p == '\0')
+ return atoi (arg);
+
+ return -1;
+}
+
+/* Return a malloced slash-separated list of languages in MASK. */
+static char *
+write_langs (unsigned int mask)
+{
+ unsigned int n = 0, len = 0;
+ const char *lang_name;
+ char *result;
+
+ for (n = 0; (lang_name = lang_names[n]) != 0; n++)
+ if (mask & (1U << n))
+ len += strlen (lang_name) + 1;
+
+ result = xmalloc (len);
+ len = 0;
+ for (n = 0; (lang_name = lang_names[n]) != 0; n++)
+ if (mask & (1U << n))
+ {
+ if (len)
+ result[len++] = '/';
+ strcpy (result + len, lang_name);
+ len += strlen (lang_name);
+ }
+
+ result[len] = 0;
+
+ return result;
+}
+
+/* Complain that switch OPT_INDEX does not apply to this front end. */
+static void
+complain_wrong_lang (const char *text, const struct cl_option *option,
+ unsigned int lang_mask)
+{
+ char *ok_langs, *bad_lang;
+
+ ok_langs = write_langs (option->flags);
+ bad_lang = write_langs (lang_mask);
+
+ /* Eventually this should become a hard error IMO. */
+ warning ("command line option \"%s\" is valid for %s but not for %s",
+ text, ok_langs, bad_lang);
+
+ free (ok_langs);
+ free (bad_lang);
+}
+
+/* Handle the switch beginning at ARGV for the language indicated by
+ LANG_MASK. Returns the number of switches consumed. */
+static unsigned int
+handle_option (const char **argv, unsigned int lang_mask)
+{
+ size_t opt_index;
+ const char *opt, *arg = 0;
+ char *dup = 0;
+ int value = 1;
+ unsigned int result = 0;
+ const struct cl_option *option;
+
+ opt = argv[0];
+
+ /* Drop the "no-" from negative switches. */
+ if ((opt[1] == 'W' || opt[1] == 'f')
+ && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
+ {
+ size_t len = strlen (opt) - 3;
+
+ dup = xmalloc (len + 1);
+ dup[0] = '-';
+ dup[1] = opt[1];
+ memcpy (dup + 2, opt + 5, len - 2 + 1);
+ opt = dup;
+ value = 0;
+ }
+
+ opt_index = find_opt (opt + 1, lang_mask | CL_COMMON);
+ if (opt_index == cl_options_count)
+ goto done;
+
+ option = &cl_options[opt_index];
+
+ /* Reject negative form of switches that don't take negatives as
+ unrecognized. */
+ if (!value && (option->flags & CL_REJECT_NEGATIVE))
+ goto done;
+
+ /* We've recognized this switch. */
+ result = 1;
+
+ /* Sort out any argument the switch takes. */
+ if (option->flags & CL_JOINED)
+ {
+ /* Have arg point to the original switch. This is because
+ some code, such as disable_builtin_function, expects its
+ argument to be persistent until the program exits. */
+ arg = argv[0] + cl_options[opt_index].opt_len + 1;
+ if (!value)
+ arg += strlen ("no-");
+
+ if (*arg == '\0' && !(option->flags & CL_MISSING_OK))
+ {
+ if (option->flags & CL_SEPARATE)
+ {
+ arg = argv[1];
+ result = 2;
+ }
+ else
+ /* Missing argument. */
+ arg = NULL;
+ }
+ }
+ else if (option->flags & CL_SEPARATE)
+ {
+ arg = argv[1];
+ result = 2;
+ }
+
+ /* Now we've swallowed any potential argument, complain if this
+ is a switch for a different front end. */
+ if (!(option->flags & (lang_mask | CL_COMMON)))
+ {
+ complain_wrong_lang (argv[0], option, lang_mask);
+ goto done;
+ }
+
+ if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE)))
+ {
+ if (!(*lang_hooks.missing_argument) (opt, opt_index))
+ error ("missing argument to \"%s\"", opt);
+ goto done;
+ }
+
+ /* If the switch takes an integer, convert it. */
+ if (arg && (option->flags & CL_UINTEGER))
+ {
+ value = integral_argument (arg);
+ if (value == -1)
+ {
+ error ("argument to \"%s\" should be a non-negative integer",
+ option->opt_text);
+ goto done;
+ }
+ }
+
+ if (option->flags & lang_mask)
+ if ((*lang_hooks.handle_option) (opt_index, arg, value) == 0)
+ result = 0;
+
+ if (result && (option->flags & CL_COMMON))
+ if (common_handle_option (opt_index, arg, value) == 0)
+ result = 0;
+
+ done:
+ if (dup)
+ free (dup);
+ return result;
+}
+
+/* Decode and handle the vector of command line options. LANG_MASK
+ contains has a single bit set representing the current
+ language. */
+static void
+handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
+{
+ unsigned int n, i;
+
+ for (i = 1; i < argc; i += n)
+ {
+ const char *opt = argv[i];
+
+ /* Interpret "-" or a non-switch as a file name. */
+ if (opt[0] != '-' || opt[1] == '\0')
+ {
+ if (main_input_filename == NULL)
+ main_input_filename = opt;
+ add_input_filename (opt);
+ n = 1;
+ continue;
+ }
+
+ n = handle_option (argv + i, lang_mask);
+
+ if (!n)
+ {
+ n = 1;
+ error ("unrecognized command line option \"%s\"", opt);
+ }
+ }
+}
+
+/* Handle FILENAME from the command line. */
+void
+add_input_filename (const char *filename)
+{
+ num_in_fnames++;
+ in_fnames = xrealloc (in_fnames, num_in_fnames * sizeof (in_fnames[0]));
+ in_fnames[num_in_fnames - 1] = filename;
+}
+
+/* Parse command line options and set default flag values. Do minimal
+ options processing. */
+void
+decode_options (unsigned int argc, const char **argv)
+{
+ unsigned int i, lang_mask;
+
+ /* Perform language-specific options initialization. */
+ lang_mask = (*lang_hooks.init_options) (argc, argv);
+
+ lang_hooks.initialize_diagnostics (global_dc);
+
+ /* Scan to see what optimization level has been specified. That will
+ determine the default value of many flags. */
+ for (i = 1; i < argc; i++)
+ {
+ if (!strcmp (argv[i], "-O"))
+ {
+ optimize = 1;
+ optimize_size = 0;
+ }
+ else if (argv[i][0] == '-' && argv[i][1] == 'O')
+ {
+ /* Handle -Os, -O2, -O3, -O69, ... */
+ const char *p = &argv[i][2];
+
+ if ((p[0] == 's') && (p[1] == 0))
+ {
+ optimize_size = 1;
+
+ /* Optimizing for size forces optimize to be 2. */
+ optimize = 2;
+ }
+ else
+ {
+ const int optimize_val = read_integral_parameter (p, p - 2, -1);
+ if (optimize_val != -1)
+ {
+ optimize = optimize_val;
+ optimize_size = 0;
+ }
+ }
+ }
+ }
+
+ if (!optimize)
+ {
+ flag_merge_constants = 0;
+ }
+
+ if (optimize >= 1)
+ {
+ flag_defer_pop = 1;
+ flag_thread_jumps = 1;
+#ifdef DELAY_SLOTS
+ flag_delayed_branch = 1;
+#endif
+#ifdef CAN_DEBUG_WITHOUT_FP
+ flag_omit_frame_pointer = 1;
+#endif
+ flag_guess_branch_prob = 1;
+ flag_cprop_registers = 1;
+ flag_loop_optimize = 1;
+ flag_if_conversion = 1;
+ flag_if_conversion2 = 1;
+ }
+
+ if (optimize >= 2)
+ {
+ flag_crossjumping = 1;
+ flag_optimize_sibling_calls = 1;
+ flag_cse_follow_jumps = 1;
+ flag_cse_skip_blocks = 1;
+ flag_gcse = 1;
+ flag_expensive_optimizations = 1;
+ flag_strength_reduce = 1;
+ flag_rerun_cse_after_loop = 1;
+ flag_rerun_loop_opt = 1;
+ flag_caller_saves = 1;
+ flag_force_mem = 1;
+ flag_peephole2 = 1;
+#ifdef INSN_SCHEDULING
+ flag_schedule_insns = 1;
+ flag_schedule_insns_after_reload = 1;
+#endif
+ flag_regmove = 1;
+ flag_strict_aliasing = 1;
+ flag_delete_null_pointer_checks = 1;
+ flag_reorder_blocks = 1;
+ flag_reorder_functions = 1;
+ flag_unit_at_a_time = 1;
+ }
+
+ if (optimize >= 3)
+ {
+ flag_inline_functions = 1;
+ flag_rename_registers = 1;
+ flag_unswitch_loops = 1;
+ flag_web = 1;
+ }
+
+ if (optimize < 2 || optimize_size)
+ {
+ align_loops = 1;
+ align_jumps = 1;
+ align_labels = 1;
+ align_functions = 1;
+
+ /* Don't reorder blocks when optimizing for size because extra
+ jump insns may be created; also barrier may create extra padding.
+
+ More correctly we should have a block reordering mode that tried
+ to minimize the combined size of all the jumps. This would more
+ or less automatically remove extra jumps, but would also try to
+ use more short jumps instead of long jumps. */
+ flag_reorder_blocks = 0;
+ }
+
+ /* Initialize whether `char' is signed. */
+ flag_signed_char = DEFAULT_SIGNED_CHAR;
+#ifdef DEFAULT_SHORT_ENUMS
+ /* Initialize how much space enums occupy, by default. */
+ flag_short_enums = DEFAULT_SHORT_ENUMS;
+#endif
+
+ /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
+ modify it. */
+ target_flags = 0;
+ set_target_switch ("");
+
+ /* Unwind tables are always present in an ABI-conformant IA-64
+ object file, so the default should be ON. */
+#ifdef IA64_UNWIND_INFO
+ flag_unwind_tables = IA64_UNWIND_INFO;
+#endif
+
+#ifdef OPTIMIZATION_OPTIONS
+ /* Allow default optimizations to be specified on a per-machine basis. */
+ OPTIMIZATION_OPTIONS (optimize, optimize_size);
+#endif
+
+ handle_options (argc, argv, lang_mask);
+
+ if (flag_pie)
+ flag_pic = flag_pie;
+ if (flag_pic && !flag_pie)
+ flag_shlib = 1;
+
+ if (flag_no_inline == 2)
+ flag_no_inline = 0;
+ else
+ flag_really_no_inline = flag_no_inline;
+
+ /* Set flag_no_inline before the post_options () hook. The C front
+ ends use it to determine tree inlining defaults. FIXME: such
+ code should be lang-independent when all front ends use tree
+ inlining, in which case it, and this condition, should be moved
+ to the top of process_options() instead. */
+ if (optimize == 0)
+ {
+ /* Inlining does not work if not optimizing,
+ so force it not to be done. */
+ flag_no_inline = 1;
+ warn_inline = 0;
+
+ /* The c_decode_option function and decode_option hook set
+ this to `2' if -Wall is used, so we can avoid giving out
+ lots of errors for people who don't realize what -Wall does. */
+ if (warn_uninitialized == 1)
+ warning ("-Wuninitialized is not supported without -O");
+ }
+
+ if (flag_really_no_inline == 2)
+ flag_really_no_inline = flag_no_inline;
+}
+
+/* Handle target- and language-independent options. Return zero to
+ generate an "unknown option" message. */
+static int
+common_handle_option (size_t scode, const char *arg,
+ int value ATTRIBUTE_UNUSED)
+{
+ enum opt_code code = (enum opt_code) scode;
+
+ switch (code)
+ {
+ default:
+ abort ();
+
+ case OPT__help:
+ print_help ();
+ exit_after_options = true;
+ break;
+
+ case OPT__param:
+ handle_param (arg);
+ break;
+
+ case OPT__target_help:
+ display_target_options ();
+ exit_after_options = true;
+ break;
+
+ case OPT__version:
+ print_version (stderr, "");
+ exit_after_options = true;
+ break;
+
+ case OPT_G:
+ g_switch_value = value;
+ g_switch_set = true;
+ break;
+
+ case OPT_O:
+ case OPT_Os:
+ /* Currently handled in a prescan. */
+ break;
+
+ case OPT_W:
+ /* For backward compatibility, -W is the same as -Wextra. */
+ set_Wextra (value);
+ break;
+
+ case OPT_Waggregate_return:
+ warn_aggregate_return = value;
+ break;
+
+ case OPT_Wcast_align:
+ warn_cast_align = value;
+ break;
+
+ case OPT_Wdeprecated_declarations:
+ warn_deprecated_decl = value;
+ break;
+
+ case OPT_Wdisabled_optimization:
+ warn_disabled_optimization = value;
+ break;
+
+ case OPT_Werror:
+ warnings_are_errors = value;
+ break;
+
+ case OPT_Wextra:
+ set_Wextra (value);
+ break;
+
+ case OPT_Winline:
+ warn_inline = value;
+ break;
+
+ case OPT_Wlarger_than_:
+ larger_than_size = value;
+ warn_larger_than = value != -1;
+ break;
+
+ case OPT_Wmissing_noreturn:
+ warn_missing_noreturn = value;
+ break;
+
+ case OPT_Wpacked:
+ warn_packed = value;
+ break;
+
+ case OPT_Wpadded:
+ warn_padded = value;
+ break;
+
+ case OPT_Wshadow:
+ warn_shadow = value;
+ break;
+
+ case OPT_Wstrict_aliasing:
+ warn_strict_aliasing = value;
+ break;
+
+ case OPT_Wswitch:
+ warn_switch = value;
+ break;
+
+ case OPT_Wswitch_default:
+ warn_switch_default = value;
+ break;
+
+ case OPT_Wswitch_enum:
+ warn_switch_enum = value;
+ break;
+
+ case OPT_Wsystem_headers:
+ warn_system_headers = value;
+ break;
+
+ case OPT_Wuninitialized:
+ warn_uninitialized = value;
+ break;
+
+ case OPT_Wunreachable_code:
+ warn_notreached = value;
+ break;
+
+ case OPT_Wunused:
+ set_Wunused (value);
+ break;
+
+ case OPT_Wunused_function:
+ warn_unused_function = value;
+ break;
+
+ case OPT_Wunused_label:
+ warn_unused_label = value;
+ break;
+
+ case OPT_Wunused_parameter:
+ warn_unused_parameter = value;
+ break;
+
+ case OPT_Wunused_value:
+ warn_unused_value = value;
+ break;
+
+ case OPT_Wunused_variable:
+ warn_unused_variable = value;
+ break;
+
+ case OPT_aux_info:
+ case OPT_aux_info_:
+ aux_info_file_name = arg;
+ flag_gen_aux_info = 1;
+ break;
+
+ case OPT_auxbase:
+ aux_base_name = arg;
+ break;
+
+ case OPT_auxbase_strip:
+ {
+ char *tmp = xstrdup (arg);
+ strip_off_ending (tmp, strlen (tmp));
+ if (tmp[0])
+ aux_base_name = tmp;
+ }
+ break;
+
+ case OPT_d:
+ decode_d_option (arg);
+ break;
+
+ case OPT_dumpbase:
+ dump_base_name = arg;
+ break;
+
+ case OPT_fPIC:
+ flag_pic = value + value;
+ break;
+
+ case OPT_fPIE:
+ flag_pie = value + value;
+ break;
+
+ case OPT_fabi_version_:
+ flag_abi_version = value;
+ break;
+
+ case OPT_falign_functions:
+ align_functions = !value;
+ break;
+
+ case OPT_falign_functions_:
+ align_functions = value;
+ break;
+
+ case OPT_falign_jumps:
+ align_jumps = !value;
+ break;
+
+ case OPT_falign_jumps_:
+ align_jumps = value;
+ break;
+
+ case OPT_falign_labels:
+ align_labels = !value;
+ break;
+
+ case OPT_falign_labels_:
+ align_labels = value;
+ break;
+
+ case OPT_falign_loops:
+ align_loops = !value;
+ break;
+
+ case OPT_falign_loops_:
+ align_loops = value;
+ break;
+
+ case OPT_fargument_alias:
+ flag_argument_noalias = !value;
+ break;
+
+ case OPT_fargument_noalias:
+ flag_argument_noalias = value;
+ break;
+
+ case OPT_fargument_noalias_global:
+ flag_argument_noalias = value + value;
+ break;
+
+ case OPT_fasynchronous_unwind_tables:
+ flag_asynchronous_unwind_tables = value;
+ break;
+
+ case OPT_fbounds_check:
+ flag_bounds_check = value;
+ break;
+
+ case OPT_fbranch_count_reg:
+ flag_branch_on_count_reg = value;
+ break;
+
+ case OPT_fbranch_probabilities:
+ flag_branch_probabilities_set = true;
+ flag_branch_probabilities = value;
+ break;
+
+ case OPT_fbranch_target_load_optimize:
+ flag_branch_target_load_optimize = value;
+ break;
+
+ case OPT_fbranch_target_load_optimize2:
+ flag_branch_target_load_optimize2 = value;
+ break;
+
+ case OPT_fcall_used_:
+ fix_register (arg, 0, 1);
+ break;
+
+ case OPT_fcall_saved_:
+ fix_register (arg, 0, 0);
+ break;
+
+ case OPT_fcaller_saves:
+ flag_caller_saves = value;
+ break;
+
+ case OPT_fcommon:
+ flag_no_common = !value;
+ break;
+
+ case OPT_fcprop_registers:
+ flag_cprop_registers = value;
+ break;
+
+ case OPT_fcrossjumping:
+ flag_crossjumping = value;
+ break;
+
+ case OPT_fcse_follow_jumps:
+ flag_cse_follow_jumps = value;
+ break;
+
+ case OPT_fcse_skip_blocks:
+ flag_cse_skip_blocks = value;
+ break;
+
+ case OPT_fdata_sections:
+ flag_data_sections = value;
+ break;
+
+ case OPT_fdefer_pop:
+ flag_defer_pop = value;
+ break;
+
+ case OPT_fdelayed_branch:
+ flag_delayed_branch = value;
+ break;
+
+ case OPT_fdelete_null_pointer_checks:
+ flag_delete_null_pointer_checks = value;
+ break;
+
+ case OPT_fdiagnostics_show_location_:
+ if (!strcmp (arg, "once"))
+ diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
+ else if (!strcmp (arg, "every-line"))
+ diagnostic_prefixing_rule (global_dc)
+ = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
+ else
+ return 0;
+ break;
+
+ case OPT_fdump_unnumbered:
+ flag_dump_unnumbered = value;
+ break;
+
+ case OPT_feliminate_dwarf2_dups:
+ flag_eliminate_dwarf2_dups = value;
+ break;
+
+ case OPT_feliminate_unused_debug_types:
+ flag_eliminate_unused_debug_types = value;
+ break;
+
+ case OPT_feliminate_unused_debug_symbols:
+ flag_debug_only_used_symbols = value;
+ break;
+
+ case OPT_fexceptions:
+ flag_exceptions = value;
+ break;
+
+ case OPT_fexpensive_optimizations:
+ flag_expensive_optimizations = value;
+ break;
+
+ case OPT_ffast_math:
+ set_fast_math_flags (value);
+ break;
+
+ case OPT_ffinite_math_only:
+ flag_finite_math_only = value;
+ break;
+
+ case OPT_ffixed_:
+ fix_register (arg, 1, 1);
+ break;
+
+ case OPT_ffunction_cse:
+ flag_no_function_cse = !value;
+ break;
+
+ case OPT_ffloat_store:
+ flag_float_store = value;
+ break;
+
+ case OPT_fforce_addr:
+ flag_force_addr = value;
+ break;
+
+ case OPT_fforce_mem:
+ flag_force_mem = value;
+ break;
+
+ case OPT_ffunction_sections:
+ flag_function_sections = value;
+ break;
+
+ case OPT_fgcse:
+ flag_gcse = value;
+ break;
+
+ case OPT_fgcse_lm:
+ flag_gcse_lm = value;
+ break;
+
+ case OPT_fgcse_sm:
+ flag_gcse_sm = value;
+ break;
+
+ case OPT_fgcse_las:
+ flag_gcse_las = value;
+ break;
+
+ case OPT_fguess_branch_probability:
+ flag_guess_branch_prob = value;
+ break;
+
+ case OPT_fident:
+ flag_no_ident = !value;
+ break;
+
+ case OPT_fif_conversion:
+ flag_if_conversion = value;
+ break;
+
+ case OPT_fif_conversion2:
+ flag_if_conversion2 = value;
+ break;
+
+ case OPT_finhibit_size_directive:
+ flag_inhibit_size_directive = value;
+ break;
+
+ case OPT_finline:
+ flag_no_inline = !value;
+ break;
+
+ case OPT_finline_functions:
+ flag_inline_functions = value;
+ break;
+
+ case OPT_finline_limit_:
+ case OPT_finline_limit_eq:
+ set_param_value ("max-inline-insns-single", value / 2);
+ set_param_value ("max-inline-insns-auto", value / 2);
+ set_param_value ("max-inline-insns-rtl", value);
+ break;
+
+ case OPT_finstrument_functions:
+ flag_instrument_function_entry_exit = value;
+ break;
+
+ case OPT_fkeep_inline_functions:
+ flag_keep_inline_functions =value;
+ break;
+
+ case OPT_fkeep_static_consts:
+ flag_keep_static_consts = value;
+ break;
+
+ case OPT_fleading_underscore:
+ flag_leading_underscore = value;
+ break;
+
+ case OPT_floop_optimize:
+ flag_loop_optimize = value;
+ break;
+
+ case OPT_fmath_errno:
+ flag_errno_math = value;
+ break;
+
+ case OPT_fmem_report:
+ mem_report = value;
+ break;
+
+ case OPT_fmerge_all_constants:
+ flag_merge_constants = value + value;
+ break;
+
+ case OPT_fmerge_constants:
+ flag_merge_constants = value;
+ break;
+
+ case OPT_fmessage_length_:
+ pp_set_line_maximum_length (global_dc->printer, value);
+ break;
+
+ case OPT_fmove_all_movables:
+ flag_move_all_movables = value;
+ break;
+
+ case OPT_fnew_ra:
+ flag_new_regalloc = value;
+ break;
+
+ case OPT_fnon_call_exceptions:
+ flag_non_call_exceptions = value;
+ break;
+
+ case OPT_fold_unroll_all_loops:
+ flag_old_unroll_all_loops = value;
+ break;
+
+ case OPT_fold_unroll_loops:
+ flag_old_unroll_loops = value;
+ break;
+
+ case OPT_fomit_frame_pointer:
+ flag_omit_frame_pointer = value;
+ break;
+
+ case OPT_foptimize_register_move:
+ flag_regmove = value;
+ break;
+
+ case OPT_foptimize_sibling_calls:
+ flag_optimize_sibling_calls = value;
+ break;
+
+ case OPT_fpack_struct:
+ flag_pack_struct = value;
+ break;
+
+ case OPT_fpeel_loops:
+ flag_peel_loops_set = true;
+ flag_peel_loops = value;
+ break;
+
+ case OPT_fpcc_struct_return:
+ flag_pcc_struct_return = value;
+ break;
+
+ case OPT_fpeephole:
+ flag_no_peephole = !value;
+ break;
+
+ case OPT_fpeephole2:
+ flag_peephole2 = value;
+ break;
+
+ case OPT_fpic:
+ flag_pic = value;
+ break;
+
+ case OPT_fpie:
+ flag_pie = value;
+ break;
+
+ case OPT_fprefetch_loop_arrays:
+ flag_prefetch_loop_arrays = value;
+ break;
+
+ case OPT_fprofile:
+ profile_flag = value;
+ break;
+
+ case OPT_fprofile_arcs:
+ profile_arc_flag_set = true;
+ profile_arc_flag = value;
+ break;
+
+ case OPT_fprofile_use:
+ if (!flag_branch_probabilities_set)
+ flag_branch_probabilities = value;
+ if (!flag_profile_values_set)
+ flag_profile_values = value;
+ if (!flag_unroll_loops_set)
+ flag_unroll_loops = value;
+ if (!flag_peel_loops_set)
+ flag_peel_loops = value;
+ if (!flag_tracer_set)
+ flag_tracer = value;
+ if (!flag_value_profile_transformations_set)
+ flag_value_profile_transformations = value;
+ break;
+
+ case OPT_fprofile_generate:
+ if (!profile_arc_flag_set)
+ profile_arc_flag = value;
+ if (!flag_profile_values_set)
+ flag_profile_values = value;
+ if (!flag_value_profile_transformations_set)
+ flag_value_profile_transformations = value;
+ break;
+
+ case OPT_fprofile_values:
+ flag_profile_values_set = true;
+ flag_profile_values = value;
+ break;
+
+ case OPT_fvpt:
+ flag_value_profile_transformations_set = value;
+ flag_value_profile_transformations = value;
+ break;
+
+ case OPT_frandom_seed:
+ /* The real switch is -fno-random-seed. */
+ if (value)
+ return 0;
+ flag_random_seed = NULL;
+ break;
+
+ case OPT_frandom_seed_:
+ flag_random_seed = arg;
+ break;
+
+ case OPT_freduce_all_givs:
+ flag_reduce_all_givs = value;
+ break;
+
+ case OPT_freg_struct_return:
+ flag_pcc_struct_return = !value;
+ break;
+
+ case OPT_fregmove:
+ flag_regmove = value;
+ break;
+
+ case OPT_frename_registers:
+ flag_rename_registers = value;
+ break;
+
+ case OPT_freorder_blocks:
+ flag_reorder_blocks = value;
+ break;
+
+ case OPT_freorder_functions:
+ flag_reorder_functions = value;
+ break;
+
+ case OPT_frerun_cse_after_loop:
+ flag_rerun_cse_after_loop = value;
+ break;
+
+ case OPT_frerun_loop_opt:
+ flag_rerun_loop_opt = value;
+ break;
+
+ case OPT_frounding_math:
+ flag_rounding_math = value;
+ break;
+
+ case OPT_fsched_interblock:
+ flag_schedule_interblock = value;
+ break;
+
+ case OPT_fsched_spec:
+ flag_schedule_speculative = value;
+ break;
+
+ case OPT_fsched_spec_load:
+ flag_schedule_speculative_load = value;
+ break;
+
+ case OPT_fsched_spec_load_dangerous:
+ flag_schedule_speculative_load_dangerous = value;
+ break;
+
+ case OPT_fsched_verbose_:
+#ifdef INSN_SCHEDULING
+ fix_sched_param ("verbose", arg);
+ break;
+#else
+ return 0;
+#endif
+
+ case OPT_fsched2_use_superblocks:
+ flag_sched2_use_superblocks = value;
+ break;
+
+ case OPT_fsched2_use_traces:
+ flag_sched2_use_traces = value;
+ break;
+
+ case OPT_fschedule_insns:
+ flag_schedule_insns = value;
+ break;
+
+ case OPT_fschedule_insns2:
+ flag_schedule_insns_after_reload = value;
+ break;
+
+ case OPT_fsched_stalled_insns:
+ flag_sched_stalled_insns = value;
+ break;
+
+ case OPT_fsched_stalled_insns_:
+ flag_sched_stalled_insns = value;
+ if (flag_sched_stalled_insns == 0)
+ flag_sched_stalled_insns = -1;
+ break;
+
+ case OPT_fsched_stalled_insns_dep:
+ flag_sched_stalled_insns_dep = 1;
+ break;
+
+ case OPT_fsched_stalled_insns_dep_:
+ flag_sched_stalled_insns_dep = value;
+ break;
+
+ case OPT_fshared_data:
+ flag_shared_data = value;
+ break;
+
+ case OPT_fsignaling_nans:
+ flag_signaling_nans = value;
+ break;
+
+ case OPT_fsingle_precision_constant:
+ flag_single_precision_constant = value;
+ break;
+
+ case OPT_fstack_check:
+ flag_stack_check = value;
+ break;
+
+ case OPT_fstack_limit:
+ /* The real switch is -fno-stack-limit. */
+ if (value)
+ return 0;
+ stack_limit_rtx = NULL_RTX;
+ break;
+
+ case OPT_fstack_limit_register_:
+ {
+ int reg = decode_reg_name (arg);
+ if (reg < 0)
+ error ("unrecognized register name \"%s\"", arg);
+ else
+ stack_limit_rtx = gen_rtx_REG (Pmode, reg);
+ }
+ break;
+
+ case OPT_fstack_limit_symbol_:
+ stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (arg));
+ break;
+
+ case OPT_fstrength_reduce:
+ flag_strength_reduce = value;
+ break;
+
+ case OPT_fstrict_aliasing:
+ flag_strict_aliasing = value;
+ break;
+
+ case OPT_fsyntax_only:
+ flag_syntax_only = value;
+ break;
+
+ case OPT_ftest_coverage:
+ flag_test_coverage = value;
+ break;
+
+ case OPT_fthread_jumps:
+ flag_thread_jumps = value;
+ break;
+
+ case OPT_ftime_report:
+ time_report = value;
+ break;
+
+ case OPT_ftls_model_:
+ if (!strcmp (arg, "global-dynamic"))
+ flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
+ else if (!strcmp (arg, "local-dynamic"))
+ flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC;
+ else if (!strcmp (arg, "initial-exec"))
+ flag_tls_default = TLS_MODEL_INITIAL_EXEC;
+ else if (!strcmp (arg, "local-exec"))
+ flag_tls_default = TLS_MODEL_LOCAL_EXEC;
+ else
+ warning ("unknown tls-model \"%s\"", arg);
+ break;
+
+ case OPT_ftracer:
+ flag_tracer_set = true;
+ flag_tracer = value;
+ break;
+
+ case OPT_ftrapping_math:
+ flag_trapping_math = value;
+ break;
+
+ case OPT_ftrapv:
+ flag_trapv = value;
+ break;
+
+ case OPT_funit_at_a_time:
+ flag_unit_at_a_time = value;
+ break;
+
+ case OPT_funroll_all_loops:
+ flag_unroll_all_loops = value;
+ break;
+
+ case OPT_funroll_loops:
+ flag_unroll_loops_set = true;
+ flag_unroll_loops = value;
+ break;
+
+ case OPT_funsafe_math_optimizations:
+ flag_unsafe_math_optimizations = value;
+ break;
+
+ case OPT_funswitch_loops:
+ flag_unswitch_loops = value;
+ break;
+
+ case OPT_funwind_tables:
+ flag_unwind_tables = value;
+ break;
+
+ case OPT_fverbose_asm:
+ flag_verbose_asm = value;
+ break;
+
+ case OPT_fweb:
+ flag_web = value;
+ break;
+
+ case OPT_fwrapv:
+ flag_wrapv = value;
+ break;
+
+ case OPT_fwritable_strings:
+ flag_writable_strings = value;
+ if (flag_writable_strings)
+ inform ("-fwritable-strings is deprecated; "
+ "see documentation for details");
+ break;
+
+ case OPT_fzero_initialized_in_bss:
+ flag_zero_initialized_in_bss = value;
+ break;
+
+ case OPT_g:
+ set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg);
+ break;
+
+ case OPT_gcoff:
+ set_debug_level (SDB_DEBUG, false, arg);
+ break;
+
+ case OPT_gdwarf_2:
+ set_debug_level (DWARF2_DEBUG, false, arg);
+ break;
+
+ case OPT_ggdb:
+ set_debug_level (NO_DEBUG, 2, arg);
+ break;
+
+ case OPT_gstabs:
+ case OPT_gstabs_:
+ set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg);
+ break;
+
+ case OPT_gvms:
+ set_debug_level (VMS_DEBUG, false, arg);
+ break;
+
+ case OPT_gxcoff:
+ case OPT_gxcoff_:
+ set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg);
+ break;
+
+ case OPT_m:
+ set_target_switch (arg);
+ break;
+
+ case OPT_o:
+ asm_file_name = arg;
+ break;
+
+ case OPT_p:
+ profile_flag = 1;
+ break;
+
+ case OPT_pedantic:
+ pedantic = 1;
+ break;
+
+ case OPT_pedantic_errors:
+ flag_pedantic_errors = pedantic = 1;
+ break;
+
+ case OPT_quiet:
+ quiet_flag = 1;
+ break;
+
+ case OPT_version:
+ version_flag = 1;
+ break;
+
+ case OPT_w:
+ inhibit_warnings = true;
+ break;
+ }
+
+ return 1;
+}
+
+/* Handle --param NAME=VALUE. */
+static void
+handle_param (const char *carg)
+{
+ char *equal, *arg;
+ int value;
+
+ arg = xstrdup (carg);
+ equal = strchr (arg, '=');
+ if (!equal)
+ error ("%s: --param arguments should be of the form NAME=VALUE", arg);
+ else
+ {
+ value = integral_argument (equal + 1);
+ if (value == -1)
+ error ("invalid --param value `%s'", equal + 1);
+ else
+ {
+ *equal = '\0';
+ set_param_value (arg, value);
+ }
+ }
+
+ free (arg);
+}
+
+/* Handle -W and -Wextra. */
+static void
+set_Wextra (int setting)
+{
+ extra_warnings = setting;
+ warn_unused_value = setting;
+ warn_unused_parameter = (setting && maybe_warn_unused_parameter);
+
+ /* We save the value of warn_uninitialized, since if they put
+ -Wuninitialized on the command line, we need to generate a
+ warning about not using it without also specifying -O. */
+ if (setting == 0)
+ warn_uninitialized = 0;
+ else if (warn_uninitialized != 1)
+ warn_uninitialized = 2;
+}
+
+/* Initialize unused warning flags. */
+void
+set_Wunused (int setting)
+{
+ warn_unused_function = setting;
+ warn_unused_label = setting;
+ /* Unused function parameter warnings are reported when either
+ ``-Wextra -Wunused'' or ``-Wunused-parameter'' is specified.
+ Thus, if -Wextra has already been seen, set warn_unused_parameter;
+ otherwise set maybe_warn_extra_parameter, which will be picked up
+ by set_Wextra. */
+ maybe_warn_unused_parameter = setting;
+ warn_unused_parameter = (setting && extra_warnings);
+ warn_unused_variable = setting;
+ warn_unused_value = setting;
+}
+
+/* The following routines are useful in setting all the flags that
+ -ffast-math and -fno-fast-math imply. */
+void
+set_fast_math_flags (int set)
+{
+ flag_trapping_math = !set;
+ flag_unsafe_math_optimizations = set;
+ flag_finite_math_only = set;
+ flag_errno_math = !set;
+ if (set)
+ {
+ flag_signaling_nans = 0;
+ flag_rounding_math = 0;
+ }
+}
+
+/* Return true iff flags are set as if -ffast-math. */
+bool
+fast_math_flags_set_p (void)
+{
+ return (!flag_trapping_math
+ && flag_unsafe_math_optimizations
+ && flag_finite_math_only
+ && !flag_errno_math);
+}
+
+/* Handle a debug output -g switch. EXTENDED is true or false to support
+ extended output (2 is special and means "-ggdb" was given). */
+static void
+set_debug_level (enum debug_info_type type, int extended, const char *arg)
+{
+ static bool type_explicit;
+
+ use_gnu_debug_info_extensions = extended;
+
+ if (type == NO_DEBUG)
+ {
+ if (write_symbols == NO_DEBUG)
+ {
+ write_symbols = PREFERRED_DEBUGGING_TYPE;
+
+ if (extended == 2)
+ {
+#ifdef DWARF2_DEBUGGING_INFO
+ write_symbols = DWARF2_DEBUG;
+#elif defined DBX_DEBUGGING_INFO
+ write_symbols = DBX_DEBUG;
+#endif
+ }
+
+ if (write_symbols == NO_DEBUG)
+ warning ("target system does not support debug output");
+ }
+ }
+ else
+ {
+ /* Does it conflict with an already selected type? */
+ if (type_explicit && write_symbols != NO_DEBUG && type != write_symbols)
+ error ("debug format \"%s\" conflicts with prior selection",
+ debug_type_names[type]);
+ write_symbols = type;
+ type_explicit = true;
+ }
+
+ /* A debug flag without a level defaults to level 2. */
+ if (*arg == '\0')
+ {
+ if (!debug_info_level)
+ debug_info_level = 2;
+ }
+ else
+ {
+ debug_info_level = integral_argument (arg);
+ if (debug_info_level == (unsigned int) -1)
+ error ("unrecognised debug output level \"%s\"", arg);
+ else if (debug_info_level > 3)
+ error ("debug output level %s is too high", arg);
+ }
+}
+
+/* Output --help text. */
+static void
+print_help (void)
+{
+ size_t i;
+ const char *p;
+
+ GET_ENVIRONMENT (p, "COLUMNS");
+ if (p)
+ {
+ int value = atoi (p);
+ if (value > 0)
+ columns = value;
+ }
+
+ puts (_("The following options are language-independent:\n"));
+
+ print_filtered_help (CL_COMMON);
+ print_param_help ();
+
+ for (i = 0; lang_names[i]; i++)
+ {
+ printf (_("The %s front end recognizes the following options:\n\n"),
+ lang_names[i]);
+ print_filtered_help (1U << i);
+ }
+
+ display_target_options ();
+}
+
+/* Print the help for --param. */
+static void
+print_param_help (void)
+{
+ size_t i;
+
+ puts (_("The --param option recognizes the following as parameters:\n"));
+
+ for (i = 0; i < LAST_PARAM; i++)
+ {
+ const char *help = compiler_params[i].help;
+ const char *param = compiler_params[i].option;
+
+ if (help == NULL || *help == '\0')
+ help = undocumented_msg;
+
+ /* Get the translation. */
+ help = _(help);
+
+ wrap_help (help, param, strlen (param));
+ }
+
+ putchar ('\n');
+}
+
+/* Print help for a specific front-end, etc. */
+static void
+print_filtered_help (unsigned int flag)
+{
+ unsigned int i, len, filter, indent = 0;
+ bool duplicates = false;
+ const char *help, *opt, *tab;
+ static char *printed;
+
+ if (flag == CL_COMMON)
+ {
+ filter = flag;
+ if (!printed)
+ printed = xmalloc (cl_options_count);
+ memset (printed, 0, cl_options_count);
+ }
+ else
+ {
+ /* Don't print COMMON options twice. */
+ filter = flag | CL_COMMON;
+
+ for (i = 0; i < cl_options_count; i++)
+ {
+ if ((cl_options[i].flags & filter) != flag)
+ continue;
+
+ /* Skip help for internal switches. */
+ if (cl_options[i].flags & CL_UNDOCUMENTED)
+ continue;
+
+ /* Skip switches that have already been printed, mark them to be
+ listed later. */
+ if (printed[i])
+ {
+ duplicates = true;
+ indent = print_switch (cl_options[i].opt_text, indent);
+ }
+ }
+
+ if (duplicates)
+ {
+ putchar ('\n');
+ putchar ('\n');
+ }
+ }
+
+ for (i = 0; i < cl_options_count; i++)
+ {
+ if ((cl_options[i].flags & filter) != flag)
+ continue;
+
+ /* Skip help for internal switches. */
+ if (cl_options[i].flags & CL_UNDOCUMENTED)
+ continue;
+
+ /* Skip switches that have already been printed. */
+ if (printed[i])
+ continue;
+
+ printed[i] = true;
+
+ help = cl_options[i].help;
+ if (!help)
+ help = undocumented_msg;
+
+ /* Get the translation. */
+ help = _(help);
+
+ tab = strchr (help, '\t');
+ if (tab)
+ {
+ len = tab - help;
+ opt = help;
+ help = tab + 1;
+ }
+ else
+ {
+ opt = cl_options[i].opt_text;
+ len = strlen (opt);
+ }
+
+ wrap_help (help, opt, len);
+ }
+
+ putchar ('\n');
+}
+
+/* Output ITEM, of length ITEM_WIDTH, in the left column, followed by
+ word-wrapped HELP in a second column. */
+static unsigned int
+print_switch (const char *text, unsigned int indent)
+{
+ unsigned int len = strlen (text) + 1; /* trailing comma */
+
+ if (indent)
+ {
+ putchar (',');
+ if (indent + len > columns)
+ {
+ putchar ('\n');
+ putchar (' ');
+ indent = 1;
+ }
+ }
+ else
+ putchar (' ');
+
+ putchar (' ');
+ fputs (text, stdout);
+
+ return indent + len + 1;
+}
+
+/* Output ITEM, of length ITEM_WIDTH, in the left column, followed by
+ word-wrapped HELP in a second column. */
+static void
+wrap_help (const char *help, const char *item, unsigned int item_width)
+{
+ unsigned int col_width = 27;
+ unsigned int remaining, room, len;
+
+ remaining = strlen (help);
+
+ do
+ {
+ room = columns - 3 - MAX (col_width, item_width);
+ if (room > columns)
+ room = 0;
+ len = remaining;
+
+ if (room < len)
+ {
+ unsigned int i;
+
+ for (i = 0; help[i]; i++)
+ {
+ if (i >= room && len != remaining)
+ break;
+ if (help[i] == ' ')
+ len = i;
+ else if ((help[i] == '-' || help[i] == '/')
+ && help[i + 1] != ' '
+ && i > 0 && ISALPHA (help[i - 1]))
+ len = i + 1;
+ }
+ }
+
+ printf( " %-*.*s %.*s\n", col_width, item_width, item, len, help);
+ item_width = 0;
+ while (help[len] == ' ')
+ len++;
+ help += len;
+ remaining -= len;
+ }
+ while (remaining);
+}
diff --git a/contrib/gcc/opts.h b/contrib/gcc/opts.h
new file mode 100644
index 000000000000..eb7c868120be
--- /dev/null
+++ b/contrib/gcc/opts.h
@@ -0,0 +1,56 @@
+/* Command line option handling.
+ Copyright (C) 2002, 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef GCC_OPTS_H
+#define GCC_OPTS_H
+
+extern void decode_options (unsigned int argc, const char **argv);
+extern void add_input_filename (const char *filename);
+
+struct cl_option
+{
+ const char *opt_text;
+ const char *help;
+ unsigned short back_chain;
+ unsigned char opt_len;
+ unsigned int flags;
+};
+
+extern const struct cl_option cl_options[];
+extern const unsigned int cl_options_count;
+extern const char *const lang_names[];
+
+#define CL_JOINED (1 << 24) /* If takes joined argument. */
+#define CL_SEPARATE (1 << 25) /* If takes a separate argument. */
+#define CL_REJECT_NEGATIVE (1 << 26) /* Reject no- form. */
+#define CL_MISSING_OK (1 << 27) /* Missing argument OK (joined). */
+#define CL_UINTEGER (1 << 28) /* Argument is an integer >=0. */
+#define CL_COMMON (1 << 29) /* Language-independent. */
+#define CL_UNDOCUMENTED (1 << 30) /* Do not output with --help. */
+
+/* Input file names. */
+
+extern const char **in_fnames;
+
+/* The count of input filenames. */
+
+extern unsigned num_in_fnames;
+
+#endif
diff --git a/contrib/gcc/opts.sh b/contrib/gcc/opts.sh
new file mode 100644
index 000000000000..871c85542115
--- /dev/null
+++ b/contrib/gcc/opts.sh
@@ -0,0 +1,175 @@
+#!/bin/sh
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# Contributed by Neil Booth, May 2003.
+#
+# 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 2, 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, write to the Free Software
+# Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Usage: opts.sh moveifchange srcdir outfile.c outfile.h file1.opt [ ...]
+
+# Always operate in the C locale.
+LANG=C
+LANGUAGE=C
+LC_ALL=C
+export LANG LANGUAGE LC_ALL
+
+# Set AWK if environment has not already set it.
+AWK=${AWK-awk}
+
+SORT=sort # Could be /bin/sort or /usr/bin/sort
+
+MOVEIFCHANGE=$1; shift
+C_FILE=$1; shift
+H_FILE=$1; shift
+TMP_C_FILE=tmp-${C_FILE}
+TMP_H_FILE=tmp-${H_FILE}
+
+${AWK} '
+ # Ignore comments and blank lines
+ /^[ \t]*(;|$)/ { next }
+ # Note that RS="" falls foul of gawk 3.1.2 bugs
+ /^[^ \t]/ { record = $0
+ do { getline tmp;
+ if (!(tmp ~ "^[ \t]*(;|$)"))
+ record = record "\034" tmp
+ } while (tmp != "")
+ print record
+ }
+' "$@" | ${SORT} | ${AWK} '
+ function switch_flags (flags, result)
+ {
+ flags = " " flags " "
+ result = "0"
+ for (j = 0; j < n_langs; j++) {
+ regex = " " langs[j] " "
+ gsub ( "\\+", "\\+", regex )
+ if (flags ~ regex)
+ result = result " | " macros[j]
+ }
+ if (flags ~ " Common ") result = result " | CL_COMMON"
+ if (flags ~ " Joined ") result = result " | CL_JOINED"
+ if (flags ~ " JoinedOrMissing ") \
+ result = result " | CL_JOINED | CL_MISSING_OK"
+ if (flags ~ " Separate ") result = result " | CL_SEPARATE"
+ if (flags ~ " RejectNegative ") result = result " | CL_REJECT_NEGATIVE"
+ if (flags ~ " UInteger ") result = result " | CL_UINTEGER"
+ if (flags ~ " Undocumented ") result = result " | CL_UNDOCUMENTED"
+ sub( "^0 \\| ", "", result )
+ return result
+ }
+
+ BEGIN {
+ FS = "\034"
+ n_opts = 0
+ n_langs = 0
+ }
+
+# Collect the text and flags of each option into an array
+ {
+ if ($1 == "Language") {
+ langs[n_langs] = $2
+ n_langs++;
+ } else {
+ opts[n_opts] = $1
+ flags[n_opts] = $2
+ help[n_opts] = $3
+ n_opts++;
+ }
+ }
+
+# Dump out an enumeration into a .h file, and an array of options into a
+# C file. Combine the flags of duplicate options.
+ END {
+ c_file = "'${TMP_C_FILE}'"
+ h_file = "'${TMP_H_FILE}'"
+ realh_file = "'${H_FILE}'"
+ comma = ","
+
+ print "/* This file is auto-generated by opts.sh. */\n" > c_file
+ print "#include <intl.h>" >> c_file
+ print "#include \"" realh_file "\"" >> c_file
+ print "#include \"opts.h\"\n" >> c_file
+ print "const char * const lang_names[] =\n{" >> c_file
+
+ print "/* This file is auto-generated by opts.sh. */\n" > h_file
+ for (i = 0; i < n_langs; i++) {
+ macros[i] = "CL_" langs[i]
+ gsub( "[^A-Za-z0-9_]", "X", macros[i] )
+ s = substr(" ", length (macros[i]))
+ print "#define " macros[i] s " (1 << " i ")" >> h_file
+ print " \"" langs[i] "\"," >> c_file
+ }
+
+ print " 0\n};\n" >> c_file
+ print "const unsigned int cl_options_count = N_OPTS;\n" >> c_file
+ print "const struct cl_option cl_options[] =\n{" >> c_file
+
+ print "\nenum opt_code\n{" >> h_file
+
+ for (i = 0; i < n_opts; i++)
+ back_chain[i] = "N_OPTS";
+
+ for (i = 0; i < n_opts; i++) {
+ # Combine the flags of identical switches. Switches
+ # appear many times if they are handled by many front
+ # ends, for example.
+ while( i + 1 != n_opts && opts[i] == opts[i + 1] ) {
+ flags[i + 1] = flags[i] " " flags[i + 1];
+ i++;
+ }
+
+ len = length (opts[i]);
+ enum = "OPT_" opts[i]
+ if (opts[i] == "finline-limit=")
+ enum = enum "eq"
+ gsub ("[^A-Za-z0-9]", "_", enum)
+
+ # If this switch takes joined arguments, back-chain all
+ # subsequent switches to it for which it is a prefix. If
+ # a later switch S is a longer prefix of a switch T, T
+ # will be back-chained to S in a later iteration of this
+ # for() loop, which is what we want.
+ if (flags[i] ~ "Joined") {
+ for (j = i + 1; j < n_opts; j++) {
+ if (substr (opts[j], 1, len) != opts[i])
+ break;
+ back_chain[j] = enum;
+ }
+ }
+
+ s = substr(" ", length (opts[i]))
+ if (i + 1 == n_opts)
+ comma = ""
+
+ if (help[i] == "")
+ hlp = "0"
+ else
+ hlp = "N_(\"" help[i] "\")";
+
+ printf(" %s,%s/* -%s */\n", enum, s, opts[i]) >> h_file
+ printf(" { \"-%s\",\n %s,\n %s, %u, %s }%s\n",
+ opts[i], hlp, back_chain[i], len,
+ switch_flags(flags[i]), comma) >> c_file
+ }
+
+ print " N_OPTS\n};" >> h_file
+ print "};" >> c_file
+ }
+'
+
+# Copy the newly generated files back to the correct names only if different.
+# This is to prevent a cascade of file rebuilds when not necessary.
+${MOVEIFCHANGE} ${TMP_H_FILE} ${H_FILE}
+${MOVEIFCHANGE} ${TMP_C_FILE} ${C_FILE}
diff --git a/contrib/gcc/output.h b/contrib/gcc/output.h
index 0f0897190821..05a3743726f5 100644
--- a/contrib/gcc/output.h
+++ b/contrib/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 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,220 +20,214 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
+#ifndef GCC_OUTPUT_H
+#define GCC_OUTPUT_H
+
/* Compute branch alignments based on frequency information in the CFG. */
-extern void compute_alignments PARAMS ((void));
+extern void compute_alignments (void);
/* Initialize data in final at the beginning of a compilation. */
-extern void init_final PARAMS ((const char *));
-
-/* Called at end of source file,
- to output the block-profiling table for this entire compilation. */
-extern void end_final PARAMS ((const char *));
+extern void init_final (const char *);
/* Enable APP processing of subsequent output.
Used before the output from an `asm' statement. */
-extern void app_enable PARAMS ((void));
+extern void app_enable (void);
/* Disable APP processing of subsequent output.
Called from varasm.c before most kinds of output. */
-extern void app_disable PARAMS ((void));
+extern void app_disable (void);
/* Return the number of slots filled in the current
delayed branch sequence (we don't count the insn needing the
delay slot). Zero if not in a delayed branch sequence. */
-extern int dbr_sequence_length PARAMS ((void));
+extern int dbr_sequence_length (void);
/* Indicate that branch shortening hasn't yet been done. */
-extern void init_insn_lengths PARAMS ((void));
+extern void init_insn_lengths (void);
/* Obtain the current length of an insn. If branch shortening has been done,
get its actual length. Otherwise, get its maximum length. */
-extern int get_attr_length PARAMS ((rtx));
+extern int get_attr_length (rtx);
/* Make a pass over all insns and compute their actual lengths by shortening
any branches of variable length if possible. */
-extern void shorten_branches PARAMS ((rtx));
+extern void shorten_branches (rtx);
/* Output assembler code for the start of a function,
and initialize some of the variables in this file
for the new function. The label for the function and associated
assembler pseudo-ops have already been output in
`assemble_start_function'. */
-extern void final_start_function PARAMS ((rtx, FILE *, int));
+extern void final_start_function (rtx, FILE *, int);
/* Output assembler code for the end of a function.
For clarity, args are same as those of `final_start_function'
even though not all of them are needed. */
-extern void final_end_function PARAMS ((void));
+extern void final_end_function (void);
/* Output assembler code for some insns: all or part of a function. */
-extern void final PARAMS ((rtx, FILE *, int, int));
+extern void final (rtx, FILE *, int, int);
/* The final scan for one insn, INSN. Args are same as in `final', except
that INSN is the insn being scanned. Value returned is the next insn to
be scanned. */
-extern rtx final_scan_insn PARAMS ((rtx, FILE *, int, int, int));
+extern rtx final_scan_insn (rtx, FILE *, int, int, int, int *);
/* Replace a SUBREG with a REG or a MEM, based on the thing it is a
subreg of. */
-extern rtx alter_subreg PARAMS ((rtx *));
+extern rtx alter_subreg (rtx *);
/* Report inconsistency between the assembler template and the operands.
In an `asm', it's the user's fault; otherwise, the compiler's fault. */
-extern void output_operand_lossage PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
+extern void output_operand_lossage (const char *, ...) ATTRIBUTE_PRINTF_1;
/* Output a string of assembler code, substituting insn operands.
Defined in final.c. */
-extern void output_asm_insn PARAMS ((const char *, rtx *));
+extern void output_asm_insn (const char *, rtx *);
/* Compute a worst-case reference address of a branch so that it
can be safely used in the presence of aligned labels.
Defined in final.c. */
-extern int insn_current_reference_address PARAMS ((rtx));
+extern int insn_current_reference_address (rtx);
/* Find the alignment associated with a CODE_LABEL.
Defined in final.c. */
-extern int label_to_alignment PARAMS ((rtx));
+extern int label_to_alignment (rtx);
/* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol. */
-extern void output_asm_label PARAMS ((rtx));
+extern void output_asm_label (rtx);
/* Print a memory reference operand for address X
using machine-dependent assembler syntax. */
-extern void output_address PARAMS ((rtx));
+extern void output_address (rtx);
/* Print an integer constant expression in assembler syntax.
Addition and subtraction are the only arithmetic
that may appear in these expressions. */
-extern void output_addr_const PARAMS ((FILE *, rtx));
+extern void output_addr_const (FILE *, rtx);
/* Output a string of assembler code, substituting numbers, strings
and fixed syntactic prefixes. */
-extern void asm_fprintf PARAMS ((FILE *file, const char *p, ...));
+#if GCC_VERSION >= 3004
+#define ATTRIBUTE_ASM_FPRINTF(m, n) __attribute__ ((__format__ (__asm_fprintf__, m, n))) ATTRIBUTE_NONNULL(m)
+/* This is a magic identifier which allows GCC to figure out the type
+ of HOST_WIDE_INT for %wd specifier checks. You must issue this
+ typedef before using the __asm_fprintf__ format attribute. */
+typedef HOST_WIDE_INT __gcc_host_wide_int__;
+#else
+#define ATTRIBUTE_ASM_FPRINTF(m, n) ATTRIBUTE_NONNULL(m)
+#endif
+
+extern void asm_fprintf (FILE *file, const char *p, ...)
+ ATTRIBUTE_ASM_FPRINTF(2, 3);
/* Split up a CONST_DOUBLE or integer constant rtx into two rtx's for single
words. */
-extern void split_double PARAMS ((rtx, rtx *, rtx *));
+extern void split_double (rtx, rtx *, rtx *);
/* Return nonzero if this function has no function calls. */
-extern int leaf_function_p PARAMS ((void));
+extern int leaf_function_p (void);
/* Return 1 if branch is a forward branch.
Uses insn_shuid array, so it works only in the final pass. May be used by
output templates to add branch prediction hints, for example. */
-extern int final_forward_branch_p PARAMS ((rtx));
+extern int final_forward_branch_p (rtx);
/* Return 1 if this function uses only the registers that can be
safely renumbered. */
-extern int only_leaf_regs_used PARAMS ((void));
+extern int only_leaf_regs_used (void);
/* Scan IN_RTX and its subexpressions, and renumber all regs into those
available in leaf functions. */
-extern void leaf_renumber_regs_insn PARAMS ((rtx));
+extern void leaf_renumber_regs_insn (rtx);
/* Locate the proper template for the given insn-code. */
-extern const char *get_insn_template PARAMS ((int, rtx));
+extern const char *get_insn_template (int, rtx);
/* Add function NAME to the weak symbols list. VALUE is a weak alias
associated with NAME. */
-extern int add_weak PARAMS ((tree, const char *, const char *));
+extern int add_weak (tree, const char *, const char *);
/* Functions in flow.c */
-extern void allocate_for_life_analysis PARAMS ((void));
-extern int regno_uninitialized PARAMS ((unsigned int));
-extern int regno_clobbered_at_setjmp PARAMS ((int));
-extern void find_basic_blocks PARAMS ((rtx, int, FILE *));
-extern bool cleanup_cfg PARAMS ((int));
-extern bool delete_unreachable_blocks PARAMS ((void));
-extern void check_function_return_warnings PARAMS ((void));
+extern void allocate_for_life_analysis (void);
+extern int regno_uninitialized (unsigned int);
+extern int regno_clobbered_at_setjmp (int);
+extern void find_basic_blocks (rtx, int, FILE *);
+extern bool cleanup_cfg (int);
+extern bool delete_unreachable_blocks (void);
+extern void check_function_return_warnings (void);
/* Functions in varasm.c. */
/* Tell assembler to switch to text section. */
-extern void text_section PARAMS ((void));
+extern void text_section (void);
/* Tell assembler to switch to data section. */
-extern void data_section PARAMS ((void));
-
-/* Tell assembler to make sure its in the data section. */
-extern void force_data_section PARAMS ((void));
+extern void data_section (void);
/* Tell assembler to switch to read-only data section. This is normally
the text section. */
-extern void readonly_data_section PARAMS ((void));
+extern void readonly_data_section (void);
/* Determine if we're in the text section. */
-extern int in_text_section PARAMS ((void));
+extern int in_text_section (void);
#ifdef CTORS_SECTION_ASM_OP
-extern void ctors_section PARAMS ((void));
+extern void ctors_section (void);
#endif
#ifdef DTORS_SECTION_ASM_OP
-extern void dtors_section PARAMS ((void));
+extern void dtors_section (void);
#endif
#ifdef BSS_SECTION_ASM_OP
-extern void bss_section PARAMS ((void));
-#endif
-
-#ifdef CONST_SECTION_ASM_OP
-extern void const_section PARAMS ((void));
+extern void bss_section (void);
#endif
#ifdef INIT_SECTION_ASM_OP
-extern void init_section PARAMS ((void));
+extern void init_section (void);
#endif
#ifdef FINI_SECTION_ASM_OP
-extern void fini_section PARAMS ((void));
+extern void fini_section (void);
#endif
#ifdef EXPORTS_SECTION_ASM_OP
-extern void exports_section PARAMS ((void));
-#endif
-
-#ifdef TDESC_SECTION_ASM_OP
-extern void tdesc_section PARAMS ((void));
+extern void exports_section (void);
#endif
#ifdef DRECTVE_SECTION_ASM_OP
-extern void drectve_section PARAMS ((void));
+extern void drectve_section (void);
#endif
#ifdef SDATA_SECTION_ASM_OP
-extern void sdata_section PARAMS ((void));
-#endif
-
-#ifdef RDATA_SECTION_ASM_OP
-extern void rdata_section PARAMS ((void));
+extern void sdata_section (void);
#endif
/* Tell assembler to change to section NAME for DECL.
If DECL is NULL, just switch to section NAME.
If NAME is NULL, get the name from DECL.
If RELOC is 1, the initializer for DECL contains relocs. */
-extern void named_section PARAMS ((tree, const char *, int));
+extern void named_section (tree, const char *, int);
/* Tell assembler to switch to the section for function DECL. */
-extern void function_section PARAMS ((tree));
+extern void function_section (tree);
/* Tell assembler to switch to the section for string merging. */
-extern void mergeable_string_section PARAMS ((tree, unsigned HOST_WIDE_INT,
- unsigned int));
+extern void mergeable_string_section (tree, unsigned HOST_WIDE_INT,
+ unsigned int);
/* Tell assembler to switch to the section for constant merging. */
-extern void mergeable_constant_section PARAMS ((enum machine_mode,
- unsigned HOST_WIDE_INT,
- unsigned int));
+extern void mergeable_constant_section (enum machine_mode,
+ unsigned HOST_WIDE_INT, unsigned int);
/* Declare DECL to be a weak symbol. */
-extern void declare_weak PARAMS ((tree));
+extern void declare_weak (tree);
/* Merge weak status. */
-extern void merge_weak PARAMS ((tree, tree));
+extern void merge_weak (tree, tree);
/* Emit any pending weak declarations. */
-extern void weak_finish PARAMS ((void));
+extern void weak_finish (void);
/* Decode an `asm' spec for a declaration as a register name.
Return the register number, or -1 if nothing specified,
@@ -242,32 +236,29 @@ extern void weak_finish PARAMS ((void));
or -4 if ASMSPEC is `memory' and is not recognized.
Accept an exact spelling or a decimal number.
Prefixes such as % are optional. */
-extern int decode_reg_name PARAMS ((const char *));
+extern int decode_reg_name (const char *);
/* Make the rtl for variable VAR be volatile.
Use this only for static variables. */
-extern void make_var_volatile PARAMS ((tree));
-
-/* Output alignment directive to align for constant expression EXP. */
-extern void assemble_constant_align PARAMS ((tree));
+extern void make_var_volatile (tree);
-extern void assemble_alias PARAMS ((tree, tree));
+extern void assemble_alias (tree, tree);
-extern void default_assemble_visibility PARAMS ((tree, int));
+extern void default_assemble_visibility (tree, int);
/* Output a string of literal assembler code
for an `asm' keyword used between functions. */
-extern void assemble_asm PARAMS ((tree));
+extern void assemble_asm (tree);
/* Output assembler code for the constant pool of a function and associated
with defining the name of the function. DECL describes the function.
NAME is the function's name. For the constant pool, we use the current
constant pool data. */
-extern void assemble_start_function PARAMS ((tree, const char *));
+extern void assemble_start_function (tree, const char *);
/* Output assembler code associated with defining the size of the
function. DECL describes the function. NAME is the function's name. */
-extern void assemble_end_function PARAMS ((tree, const char *));
+extern void assemble_end_function (tree, const char *);
/* Assemble everything that is needed for a variable or function declaration.
Not used for automatic variables, and not used for function definitions.
@@ -278,36 +269,36 @@ extern void assemble_end_function PARAMS ((tree, const char *));
to define things that have had only tentative definitions.
DONT_OUTPUT_DATA if nonzero means don't actually output the
initial value (that will be done by the caller). */
-extern void assemble_variable PARAMS ((tree, int, int, int));
+extern void assemble_variable (tree, int, int, int);
/* Output something to declare an external symbol to the assembler.
(Most assemblers don't need this, so we normally output nothing.)
Do nothing if DECL is not external. */
-extern void assemble_external PARAMS ((tree));
+extern void assemble_external (tree);
/* Assemble code to leave SIZE bytes of zeros. */
-extern void assemble_zeros PARAMS ((int));
+extern void assemble_zeros (unsigned HOST_WIDE_INT);
/* Assemble an alignment pseudo op for an ALIGN-bit boundary. */
-extern void assemble_align PARAMS ((int));
-extern void assemble_eh_align PARAMS ((int));
+extern void assemble_align (int);
+extern void assemble_eh_align (int);
/* Assemble a string constant with the specified C string as contents. */
-extern void assemble_string PARAMS ((const char *, int));
+extern void assemble_string (const char *, int);
/* Similar, for calling a library function FUN. */
-extern void assemble_external_libcall PARAMS ((rtx));
+extern void assemble_external_libcall (rtx);
/* Assemble a label named NAME. */
-extern void assemble_label PARAMS ((const char *));
-extern void assemble_eh_label PARAMS ((const char *));
+extern void assemble_label (const char *);
+extern void assemble_eh_label (const char *);
/* Output to FILE a reference to the assembler name of a C-level name NAME.
If NAME starts with a *, the rest of NAME is output verbatim.
Otherwise NAME is transformed in an implementation-defined way
(usually by the addition of an underscore).
Many macros in the tm file are defined to call this function. */
-extern void assemble_name PARAMS ((FILE *, const char *));
+extern void assemble_name (FILE *, const char *);
/* Return the assembler directive for creating a given kind of integer
object. SIZE is the number of bytes in the object and ALIGNED_P
@@ -316,20 +307,20 @@ extern void assemble_name PARAMS ((FILE *, const char *));
The returned string should be printed at the start of a new line and
be followed immediately by the object's initial value. */
-extern const char *integer_asm_op PARAMS ((int, int));
+extern const char *integer_asm_op (int, int);
/* Use directive OP to assemble an integer object X. Print OP at the
start of the line, followed immediately by the value of X. */
-extern void assemble_integer_with_op PARAMS ((const char *, rtx));
+extern void assemble_integer_with_op (const char *, rtx);
/* The default implementation of the asm_out.integer target hook. */
-extern bool default_assemble_integer PARAMS ((rtx, unsigned int, int));
+extern bool default_assemble_integer (rtx, unsigned int, int);
/* Assemble the integer constant X into an object of SIZE bytes. ALIGN is
the alignment of the integer in bits. Return 1 if we were able to output
the constant, otherwise 0. If FORCE is nonzero, abort if we can't output
the constant. */
-extern bool assemble_integer PARAMS ((rtx, unsigned, unsigned, int));
+extern bool assemble_integer (rtx, unsigned, unsigned, int);
/* An interface to assemble_integer for the common case in which a value is
fully aligned and must be printed. VALUE is the value of the integer
@@ -339,27 +330,18 @@ extern bool assemble_integer PARAMS ((rtx, unsigned, unsigned, int));
#ifdef REAL_VALUE_TYPE_SIZE
/* Assemble the floating-point constant D into an object of size MODE. */
-extern void assemble_real PARAMS ((REAL_VALUE_TYPE,
- enum machine_mode,
- unsigned));
+extern void assemble_real (REAL_VALUE_TYPE, enum machine_mode, unsigned);
#endif
-/* Start deferring output of subconstants. */
-extern void defer_addressed_constants PARAMS ((void));
-
-/* Stop deferring output of subconstants,
- and output now all those that have been deferred. */
-extern void output_deferred_addressed_constants PARAMS ((void));
-
/* Return the size of the constant pool. */
-extern int get_pool_size PARAMS ((void));
+extern int get_pool_size (void);
#ifdef HAVE_peephole
-extern rtx peephole PARAMS ((rtx));
+extern rtx peephole (rtx);
#endif
/* Write all the constants in the constant pool. */
-extern void output_constant_pool PARAMS ((const char *, tree));
+extern void output_constant_pool (const char *, tree);
/* Return nonzero if VALUE is a valid constant-valued expression
for use in initializing a static variable; one that can be an
@@ -370,7 +352,7 @@ extern void output_constant_pool PARAMS ((const char *, tree));
We assume that VALUE has been folded as much as possible;
therefore, we do not need to check for such things as
arithmetic-combinations of integers. */
-extern tree initializer_constant_valid_p PARAMS ((tree, tree));
+extern tree initializer_constant_valid_p (tree, 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.
@@ -380,8 +362,7 @@ extern tree initializer_constant_valid_p PARAMS ((tree, tree));
with zeros if necessary. SIZE must always be specified.
ALIGN is the alignment in bits that may be assumed for the data. */
-extern void output_constant PARAMS ((tree, HOST_WIDE_INT,
- unsigned int));
+extern void output_constant (tree, unsigned HOST_WIDE_INT, unsigned int);
/* When outputting delayed branch sequences, this rtx holds the
sequence being output. It is null when no delayed branch
@@ -441,10 +422,10 @@ extern FILE *rtl_dump_file;
#endif
/* Nonnull if the insn currently being emitted was a COND_EXEC pattern. */
-extern struct rtx_def *current_insn_predicate;
+extern rtx current_insn_predicate;
/* Last insn processed by final_scan_insn. */
-extern struct rtx_def *current_output_insn;
+extern rtx current_output_insn;
/* Nonzero while outputting an `asm' with operands.
This means that inconsistencies are the user's fault, so don't abort.
@@ -453,25 +434,31 @@ extern rtx this_is_asm_operands;
/* Decide whether DECL needs to be in a writable section.
RELOC is the same as for SELECT_SECTION. */
-extern bool decl_readonly_section PARAMS ((tree, int));
-extern bool decl_readonly_section_1 PARAMS ((tree, int, int));
+extern bool decl_readonly_section (tree, int);
+extern bool decl_readonly_section_1 (tree, int, int);
+
+/* This can be used to compute RELOC for the function above, when
+ given a constant expression. */
+extern int compute_reloc_for_constant (tree);
/* User label prefix in effect for this compilation. */
extern const char *user_label_prefix;
/* Default target function prologue and epilogue assembler output. */
-extern void default_function_pro_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
+extern void default_function_pro_epilogue (FILE *, HOST_WIDE_INT);
/* Tell assembler to switch to the section for the exception table. */
-extern void default_exception_section PARAMS ((void));
+extern void default_exception_section (void);
/* Tell assembler to switch to the section for the EH frames. */
-extern void default_eh_frame_section PARAMS ((void));
+extern void named_section_eh_frame_section (void);
+extern void collect2_eh_frame_section (void);
+extern void default_eh_frame_section (void);
/* Default target hook that outputs nothing to a stream. */
-extern void no_asm_to_stream PARAMS ((FILE *));
+extern void no_asm_to_stream (FILE *);
-/* Flags controling properties of a section. */
+/* Flags controlling properties of a section. */
#define SECTION_ENTSIZE 0x000ff /* entity size in section */
#define SECTION_CODE 0x00100 /* contains code */
#define SECTION_WRITE 0x00200 /* data is writable */
@@ -488,53 +475,45 @@ extern void no_asm_to_stream PARAMS ((FILE *));
#define SECTION_NOTYPE 0x80000 /* don't output @progbits */
#define SECTION_MACH_DEP 0x100000 /* subsequent bits reserved for target */
-extern unsigned int get_named_section_flags PARAMS ((const char *));
-extern bool set_named_section_flags PARAMS ((const char *, unsigned int));
-extern void named_section_flags PARAMS ((const char *, unsigned int));
-extern bool named_section_first_declaration PARAMS((const char *));
-
-union tree_node;
-extern unsigned int default_section_type_flags PARAMS ((union tree_node *,
- const char *, int));
-extern unsigned int default_section_type_flags_1 PARAMS ((union tree_node *,
- const char *,
- int, int));
-
-extern void default_no_named_section PARAMS ((const char *, unsigned int));
-extern void default_elf_asm_named_section PARAMS ((const char *, unsigned int));
-extern void default_coff_asm_named_section PARAMS ((const char *,
- unsigned int));
-extern void default_pe_asm_named_section PARAMS ((const char *, unsigned int));
-
-extern void default_stabs_asm_out_destructor PARAMS ((struct rtx_def *, int));
-extern void default_named_section_asm_out_destructor PARAMS ((struct rtx_def *,
- int));
-extern void default_dtor_section_asm_out_destructor PARAMS ((struct rtx_def *,
- int));
-extern void default_stabs_asm_out_constructor PARAMS ((struct rtx_def *, int));
-extern void default_named_section_asm_out_constructor PARAMS ((struct rtx_def *,
- int));
-extern void default_ctor_section_asm_out_constructor PARAMS ((struct rtx_def *,
- int));
-
-extern void default_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT));
-extern void default_elf_select_section PARAMS ((tree, int,
- unsigned HOST_WIDE_INT));
-extern void default_elf_select_section_1 PARAMS ((tree, int,
- unsigned HOST_WIDE_INT, int));
-extern void default_unique_section PARAMS ((tree, int));
-extern void default_unique_section_1 PARAMS ((tree, int, int));
-extern void default_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
-extern void default_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
-extern const char *default_strip_name_encoding PARAMS ((const char *));
-extern bool default_binds_local_p PARAMS ((tree));
-extern bool default_binds_local_p_1 PARAMS ((tree, int));
-extern void default_globalize_label PARAMS ((FILE *, const char *));
-
-/* Emit data for vtable gc for GNU binutils. */
-extern void assemble_vtable_entry PARAMS ((struct rtx_def *, HOST_WIDE_INT));
-extern void assemble_vtable_inherit PARAMS ((struct rtx_def *,
- struct rtx_def *));
+extern unsigned int get_named_section_flags (const char *);
+extern bool set_named_section_flags (const char *, unsigned int);
+extern void named_section_flags (const char *, unsigned int);
+extern bool named_section_first_declaration (const char *);
+extern unsigned int default_section_type_flags (tree, const char *, int);
+extern unsigned int default_section_type_flags_1 (tree, const char *, int, int);
+
+extern void default_no_named_section (const char *, unsigned int);
+extern void default_elf_asm_named_section (const char *, unsigned int);
+extern void default_coff_asm_named_section (const char *, unsigned int);
+extern void default_pe_asm_named_section (const char *, unsigned int);
+
+extern void default_stabs_asm_out_destructor (rtx, int);
+extern void default_named_section_asm_out_destructor (rtx, int);
+extern void default_dtor_section_asm_out_destructor (rtx, int);
+extern void default_stabs_asm_out_constructor (rtx, int);
+extern void default_named_section_asm_out_constructor (rtx, int);
+extern void default_ctor_section_asm_out_constructor (rtx, int);
+
+extern void default_select_section (tree, int, unsigned HOST_WIDE_INT);
+extern void default_elf_select_section (tree, int, unsigned HOST_WIDE_INT);
+extern void default_elf_select_section_1 (tree, int,
+ unsigned HOST_WIDE_INT, int);
+extern void default_unique_section (tree, int);
+extern void default_unique_section_1 (tree, int, int);
+extern void default_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
+extern void default_elf_select_rtx_section (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
+extern void default_encode_section_info (tree, rtx, int);
+extern const char *default_strip_name_encoding (const char *);
+extern bool default_binds_local_p (tree);
+extern bool default_binds_local_p_1 (tree, int);
+extern void default_globalize_label (FILE *, const char *);
+extern void default_internal_label (FILE *, const char *, unsigned long);
+extern void default_file_start (void);
+extern void file_end_indicate_exec_stack (void);
+extern bool default_valid_pointer_mode (enum machine_mode);
+
+extern int default_address_cost (rtx);
+
+#endif /* ! GCC_OUTPUT_H */
diff --git a/contrib/gcc/params.c b/contrib/gcc/params.c
index 72c67bebf3bf..e109d3adb3fe 100644
--- a/contrib/gcc/params.c
+++ b/contrib/gcc/params.c
@@ -1,5 +1,5 @@
/* params.c - Run-time parameters.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Written by Mark Mitchell <mark@codesourcery.com>.
This file is part of GCC.
@@ -23,6 +23,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "params.h"
#include "toplev.h"
@@ -38,15 +40,11 @@ static size_t num_compiler_params;
/* Add the N PARAMS to the current list of compiler parameters. */
void
-add_params (params, n)
- const param_info params[];
- size_t n;
+add_params (const param_info params[], size_t n)
{
/* Allocate enough space for the new parameters. */
- compiler_params =
- ((param_info *)
- xrealloc (compiler_params,
- (num_compiler_params + n) * sizeof (param_info)));
+ compiler_params = xrealloc (compiler_params,
+ (num_compiler_params + n) * sizeof (param_info));
/* Copy them into the table. */
memcpy (compiler_params + num_compiler_params,
params,
@@ -58,9 +56,7 @@ add_params (params, n)
/* Set the VALUE associated with the parameter given by NAME. */
void
-set_param_value (name, value)
- const char *name;
- int value;
+set_param_value (const char *name, int value)
{
size_t i;
diff --git a/contrib/gcc/params.def b/contrib/gcc/params.def
index 977d7407b7cf..dc826634af73 100644
--- a/contrib/gcc/params.def
+++ b/contrib/gcc/params.def
@@ -39,7 +39,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
of a function counted in internal gcc instructions (not in
real machine instructions) that is eligible for inlining
by the tree inliner.
- The default value is 300.
+ The default value is 500.
Only functions marked inline (or methods defined in the class
definition for C++) are affected by this, unless you set the
-finline-functions (included in -O3) compiler option.
@@ -51,7 +51,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE,
"max-inline-insns-single",
"The maximum number of instructions in a single function eligible for inlining",
- 300)
+ 500)
/* The single function inlining limit for functions that are
inlined by virtue of -finline-functions (-O3).
@@ -59,56 +59,11 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE,
that is applied to functions marked inlined (or defined in the
class declaration in C++) given by the "max-inline-insns-single"
parameter.
- The default value is 300. */
+ The default value is 150. */
DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO,
"max-inline-insns-auto",
"The maximum number of instructions when automatically inlining",
- 300)
-
-/* The repeated inlining limit. After this number of instructions
- (in the internal gcc representation, not real machine instructions)
- got inlined by repeated inlining, gcc starts to decrease the maximum
- number of inlinable instructions in the tree inliner.
- This is done by a linear function, see "max-inline-slope" parameter.
- It is necessary in order to limit the compile-time resources, that
- could otherwise become very high.
- It is recommended to set this value to twice the value of the single
- function limit (set by the "max-inline-insns-single" parameter) or
- higher. The default value is 600.
- Higher values mean that more inlining is done, resulting in
- better performance of the code, at the expense of higher
- compile-time resource (time, memory) requirements and larger
- binaries. */
-DEFPARAM (PARAM_MAX_INLINE_INSNS,
- "max-inline-insns",
- "The maximum number of instructions by repeated inlining before gcc starts to throttle inlining",
- 600)
-
-/* After the repeated inline limit has been exceeded (see
- "max-inline-insns" parameter), a linear function is used to
- decrease the size of single functions eligible for inlining.
- The slope of this linear function is given the negative
- reciprocal value (-1/x) of this parameter.
- The default value is 32.
- This linear function is used until it falls below a minimum
- value specified by the "min-inline-insns" parameter. */
-DEFPARAM (PARAM_MAX_INLINE_SLOPE,
- "max-inline-slope",
- "The slope of the linear function throttling inlining after the recursive inlining limit has been reached is given by the negative reciprocal value of this parameter",
- 32)
-
-/* When gcc has inlined so many instructions (by repeated
- inlining) that the throttling limits the inlining very much,
- inlining for very small functions is still desirable to
- achieve good runtime performance. The size of single functions
- (measured in gcc instructions) which will still be eligible for
- inlining then is given by this parameter. It defaults to 130.
- Only much later (after exceeding 128 times the recursive limit)
- inlining is cut down completely. */
-DEFPARAM (PARAM_MIN_INLINE_INSNS,
- "min-inline-insns",
- "The number of instructions in a single functions still eligible to inlining after a lot recursive inlining",
- 130)
+ 100)
/* For languages that (still) use the RTL inliner, we can specify
limits for the RTL inliner separately.
@@ -152,6 +107,19 @@ DEFPARAM(PARAM_MAX_PENDING_LIST_LENGTH,
"The maximum length of scheduling's pending operations list",
32)
+DEFPARAM(PARAM_LARGE_FUNCTION_INSNS,
+ "large-function-insns",
+ "The size of function body to be considered large",
+ 3000)
+DEFPARAM(PARAM_LARGE_FUNCTION_GROWTH,
+ "large-function-growth",
+ "Maximal growth due to inlining of large function (in percent)",
+ 100)
+DEFPARAM(PARAM_INLINE_UNIT_GROWTH,
+ "inline-unit-growth",
+ "how much can given compilation unit grow because of the inlining (in percent)",
+ 50)
+
/* The GCSE optimization will be disabled if it would require
significantly more memory than this value. */
DEFPARAM(PARAM_MAX_GCSE_MEMORY,
@@ -165,11 +133,63 @@ DEFPARAM(PARAM_MAX_GCSE_PASSES,
1)
/* This parameter limits the number of insns in a loop that will be unrolled,
- and by how much the loop is unrolled. */
+ and by how much the loop is unrolled.
+
+ This limit should be at most half of the peeling limits: loop unroller
+ decides to not unroll loops that iterate fewer than 2*number of allowed
+ unrollings and thus we would have loops that are neither peeled or unrooled
+ otherwise. */
DEFPARAM(PARAM_MAX_UNROLLED_INSNS,
"max-unrolled-insns",
"The maximum number of instructions to consider to unroll in a loop",
- 100)
+ 200)
+/* This parameter limits how many times the loop is unrolled depending
+ on number of insns really executed in each iteration. */
+DEFPARAM(PARAM_MAX_AVERAGE_UNROLLED_INSNS,
+ "max-average-unrolled-insns",
+ "The maximum number of instructions to consider to unroll in a loop on average",
+ 80)
+/* The maximum number of unrollings of a single loop. */
+DEFPARAM(PARAM_MAX_UNROLL_TIMES,
+ "max-unroll-times",
+ "The maximum number of unrollings of a single loop",
+ 8)
+/* The maximum number of insns of a peeled loop. */
+DEFPARAM(PARAM_MAX_PEELED_INSNS,
+ "max-peeled-insns",
+ "The maximum number of insns of a peeled loop",
+ 400)
+/* The maximum number of peelings of a single loop. */
+DEFPARAM(PARAM_MAX_PEEL_TIMES,
+ "max-peel-times",
+ "The maximum number of peelings of a single loop",
+ 16)
+/* The maximum number of insns of a peeled loop. */
+DEFPARAM(PARAM_MAX_COMPLETELY_PEELED_INSNS,
+ "max-completely-peeled-insns",
+ "The maximum number of insns of a completely peeled loop",
+ 400)
+/* The maximum number of peelings of a single loop that is peeled completely. */
+DEFPARAM(PARAM_MAX_COMPLETELY_PEEL_TIMES,
+ "max-completely-peel-times",
+ "The maximum number of peelings of a single loop that is peeled completely",
+ 16)
+/* The maximum number of insns of a peeled loop that rolls only once. */
+DEFPARAM(PARAM_MAX_ONCE_PEELED_INSNS,
+ "max-once-peeled-insns",
+ "The maximum number of insns of a peeled loop that rolls only once",
+ 400)
+
+/* The maximum number of insns of an unswitched loop. */
+DEFPARAM(PARAM_MAX_UNSWITCH_INSNS,
+ "max-unswitch-insns",
+ "The maximum number of insns of an unswitched loop",
+ 50)
+/* The maximum level of recursion in unswitch_single_loop. */
+DEFPARAM(PARAM_MAX_UNSWITCH_LEVEL,
+ "max-unswitch-level",
+ "The maximum number of unswitchings in a single loop",
+ 3)
DEFPARAM(HOT_BB_COUNT_FRACTION,
"hot-bb-count-fraction",
@@ -193,22 +213,22 @@ must be covered by trace formation. Used when profile feedback is not available"
75)
DEFPARAM(TRACER_MAX_CODE_GROWTH,
"tracer-max-code-growth",
- "Maximal code growth caused by tail duplication (in percents)",
+ "Maximal code growth caused by tail duplication (in percent)",
100)
DEFPARAM(TRACER_MIN_BRANCH_RATIO,
"tracer-min-branch-ratio",
"Stop reverse growth if the reverse probability of best edge is less \
-than this threshold (in percents)",
+than this threshold (in percent)",
10)
DEFPARAM(TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK,
"tracer-min-branch-probability-feedback",
"Stop forward growth if the probability of best edge is less than \
-this threshold (in percents). Used when profile feedback is available",
- 30)
+this threshold (in percent). Used when profile feedback is available",
+ 80)
DEFPARAM(TRACER_MIN_BRANCH_PROBABILITY,
"tracer-min-branch-probability",
"Stop forward growth if the probability of best edge is less than \
-this threshold (in percents). Used when profile feedback is not available",
+this threshold (in percent). Used when profile feedback is not available",
50)
/* The maximum number of incoming edges to consider for crossjumping. */
@@ -217,6 +237,17 @@ DEFPARAM(PARAM_MAX_CROSSJUMP_EDGES,
"The maximum number of incoming edges to consider for crossjumping",
100)
+/* The maximum length of path considered in cse. */
+DEFPARAM(PARAM_MAX_CSE_PATH_LENGTH,
+ "max-cse-path-length",
+ "The maximum length of path considered in cse",
+ 10)
+
+DEFPARAM(PARAM_MAX_CSELIB_MEMORY_LOCATIONS,
+ "max-cselib-memory-locations",
+ "The maximum memory locations recorded by cselib",
+ 500)
+
#ifdef ENABLE_GC_ALWAYS_COLLECT
# define GGC_MIN_EXPAND_DEFAULT 0
# define GGC_MIN_HEAPSIZE_DEFAULT 0
@@ -228,17 +259,22 @@ DEFPARAM(PARAM_MAX_CROSSJUMP_EDGES,
DEFPARAM(GGC_MIN_EXPAND,
"ggc-min-expand",
"Minimum heap expansion to trigger garbage collection, as \
-a percentage of the total size of the heap.",
+a percentage of the total size of the heap",
GGC_MIN_EXPAND_DEFAULT)
DEFPARAM(GGC_MIN_HEAPSIZE,
"ggc-min-heapsize",
- "Minimum heap size before we start collecting garbage, in kilobytes.",
+ "Minimum heap size before we start collecting garbage, in kilobytes",
GGC_MIN_HEAPSIZE_DEFAULT)
#undef GGC_MIN_EXPAND_DEFAULT
#undef GGC_MIN_HEAPSIZE_DEFAULT
+DEFPARAM(PARAM_MAX_RELOAD_SEARCH_INSNS,
+ "max-reload-search-insns",
+ "The maximum number of instructions to search backward when looking for equivalent reload",
+ 100)
+
/*
Local variables:
mode:c
diff --git a/contrib/gcc/params.h b/contrib/gcc/params.h
index caddf853da5f..0a784454ccd1 100644
--- a/contrib/gcc/params.h
+++ b/contrib/gcc/params.h
@@ -1,5 +1,5 @@
/* params.h - Run-time parameters.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
Written by Mark Mitchell <mark@codesourcery.com>.
This file is part of GCC.
@@ -59,13 +59,11 @@ extern param_info *compiler_params;
/* Add the N PARAMS to the current list of compiler parameters. */
-extern void add_params
- PARAMS ((const param_info params[], size_t n));
+extern void add_params (const param_info params[], size_t n);
/* Set the VALUE associated with the parameter given by NAME. */
-extern void set_param_value
- PARAMS ((const char *name, int value));
+extern void set_param_value (const char *name, int value);
/* The parameters in use by language-independent code. */
diff --git a/contrib/gcc/pex-unix.c b/contrib/gcc/pex-unix.c
new file mode 100644
index 000000000000..14fe71ed09c0
--- /dev/null
+++ b/contrib/gcc/pex-unix.c
@@ -0,0 +1,166 @@
+/* Utilities to execute a program in a subprocess (possibly linked by pipes
+ with other subprocesses), and wait for it. Generic Unix version
+ (also used for UWIN and VMS).
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003
+ Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If not,
+write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "pex-common.h"
+
+#include <stdio.h>
+#include <errno.h>
+#ifdef NEED_DECLARATION_ERRNO
+extern int errno;
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#ifndef HAVE_WAITPID
+#define waitpid(pid, status, flags) wait(status)
+#endif
+
+extern int execv ();
+extern int execvp ();
+
+int
+pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
+ const char *program;
+ char * const *argv;
+ const char *this_pname;
+ const char *temp_base ATTRIBUTE_UNUSED;
+ char **errmsg_fmt, **errmsg_arg;
+ int flags;
+{
+ int (*func)() = (flags & PEXECUTE_SEARCH ? execvp : execv);
+ int pid;
+ int pdes[2];
+ int input_desc, output_desc;
+ int retries, sleep_interval;
+ /* Pipe waiting from last process, to be used as input for the next one.
+ Value is STDIN_FILE_NO if no pipe is waiting
+ (i.e. the next command is the first of a group). */
+ static int last_pipe_input;
+
+ /* If this is the first process, initialize. */
+ if (flags & PEXECUTE_FIRST)
+ last_pipe_input = STDIN_FILE_NO;
+
+ input_desc = last_pipe_input;
+
+ /* If this isn't the last process, make a pipe for its output,
+ and record it as waiting to be the input to the next process. */
+ if (! (flags & PEXECUTE_LAST))
+ {
+ if (pipe (pdes) < 0)
+ {
+ *errmsg_fmt = "pipe";
+ *errmsg_arg = NULL;
+ return -1;
+ }
+ output_desc = pdes[WRITE_PORT];
+ last_pipe_input = pdes[READ_PORT];
+ }
+ else
+ {
+ /* Last process. */
+ output_desc = STDOUT_FILE_NO;
+ last_pipe_input = STDIN_FILE_NO;
+ }
+
+ /* Fork a subprocess; wait and retry if it fails. */
+ sleep_interval = 1;
+ pid = -1;
+ for (retries = 0; retries < 4; retries++)
+ {
+ pid = fork ();
+ if (pid >= 0)
+ break;
+ sleep (sleep_interval);
+ sleep_interval *= 2;
+ }
+
+ switch (pid)
+ {
+ case -1:
+ *errmsg_fmt = "fork";
+ *errmsg_arg = NULL;
+ return -1;
+
+ case 0: /* child */
+ /* Move the input and output pipes into place, if necessary. */
+ if (input_desc != STDIN_FILE_NO)
+ {
+ close (STDIN_FILE_NO);
+ dup (input_desc);
+ close (input_desc);
+ }
+ if (output_desc != STDOUT_FILE_NO)
+ {
+ close (STDOUT_FILE_NO);
+ dup (output_desc);
+ close (output_desc);
+ }
+
+ /* Close the parent's descs that aren't wanted here. */
+ if (last_pipe_input != STDIN_FILE_NO)
+ close (last_pipe_input);
+
+ /* Exec the program. */
+ (*func) (program, argv);
+
+ fprintf (stderr, "%s: ", this_pname);
+ fprintf (stderr, install_error_msg, program);
+ fprintf (stderr, ": %s\n", xstrerror (errno));
+ exit (-1);
+ /* NOTREACHED */
+ return 0;
+
+ default:
+ /* In the parent, after forking.
+ Close the descriptors that we made for this child. */
+ if (input_desc != STDIN_FILE_NO)
+ close (input_desc);
+ if (output_desc != STDOUT_FILE_NO)
+ close (output_desc);
+
+ /* Return child's process number. */
+ return pid;
+ }
+}
+
+int
+pwait (pid, status, flags)
+ int pid;
+ int *status;
+ int flags ATTRIBUTE_UNUSED;
+{
+ /* ??? Here's an opportunity to canonicalize the values in STATUS.
+ Needed? */
+ pid = waitpid (pid, status, 0);
+ return pid;
+}
diff --git a/contrib/gcc/postreload.c b/contrib/gcc/postreload.c
new file mode 100644
index 000000000000..6f567f07f9e9
--- /dev/null
+++ b/contrib/gcc/postreload.c
@@ -0,0 +1,1560 @@
+/* Perform simple optimizations to clean up the result of reload.
+ Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+
+#include "machmode.h"
+#include "hard-reg-set.h"
+#include "rtl.h"
+#include "tm_p.h"
+#include "obstack.h"
+#include "insn-config.h"
+#include "flags.h"
+#include "function.h"
+#include "expr.h"
+#include "optabs.h"
+#include "regs.h"
+#include "basic-block.h"
+#include "reload.h"
+#include "recog.h"
+#include "output.h"
+#include "cselib.h"
+#include "real.h"
+#include "toplev.h"
+#include "except.h"
+#include "tree.h"
+
+static int reload_cse_noop_set_p (rtx);
+static void reload_cse_simplify (rtx, rtx);
+static void reload_cse_regs_1 (rtx);
+static int reload_cse_simplify_set (rtx, rtx);
+static int reload_cse_simplify_operands (rtx, rtx);
+
+static void reload_combine (void);
+static void reload_combine_note_use (rtx *, rtx);
+static void reload_combine_note_store (rtx, rtx, void *);
+
+static void reload_cse_move2add (rtx);
+static void move2add_note_store (rtx, rtx, void *);
+
+/* Call cse / combine like post-reload optimization phases.
+ FIRST is the first instruction. */
+void
+reload_cse_regs (rtx first ATTRIBUTE_UNUSED)
+{
+ reload_cse_regs_1 (first);
+ reload_combine ();
+ reload_cse_move2add (first);
+ if (flag_expensive_optimizations)
+ reload_cse_regs_1 (first);
+}
+
+/* See whether a single set SET is a noop. */
+static int
+reload_cse_noop_set_p (rtx set)
+{
+ if (cselib_reg_set_mode (SET_DEST (set)) != GET_MODE (SET_DEST (set)))
+ return 0;
+
+ return rtx_equal_for_cselib_p (SET_DEST (set), SET_SRC (set));
+}
+
+/* Try to simplify INSN. */
+static void
+reload_cse_simplify (rtx insn, rtx testreg)
+{
+ rtx body = PATTERN (insn);
+
+ if (GET_CODE (body) == SET)
+ {
+ int count = 0;
+
+ /* Simplify even if we may think it is a no-op.
+ We may think a memory load of a value smaller than WORD_SIZE
+ is redundant because we haven't taken into account possible
+ implicit extension. reload_cse_simplify_set() will bring
+ this out, so it's safer to simplify before we delete. */
+ count += reload_cse_simplify_set (body, insn);
+
+ if (!count && reload_cse_noop_set_p (body))
+ {
+ rtx value = SET_DEST (body);
+ if (REG_P (value)
+ && ! REG_FUNCTION_VALUE_P (value))
+ value = 0;
+ delete_insn_and_edges (insn);
+ return;
+ }
+
+ if (count > 0)
+ apply_change_group ();
+ else
+ reload_cse_simplify_operands (insn, testreg);
+ }
+ else if (GET_CODE (body) == PARALLEL)
+ {
+ int i;
+ int count = 0;
+ rtx value = NULL_RTX;
+
+ /* If every action in a PARALLEL is a noop, we can delete
+ the entire PARALLEL. */
+ for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
+ {
+ rtx part = XVECEXP (body, 0, i);
+ if (GET_CODE (part) == SET)
+ {
+ if (! reload_cse_noop_set_p (part))
+ break;
+ if (REG_P (SET_DEST (part))
+ && REG_FUNCTION_VALUE_P (SET_DEST (part)))
+ {
+ if (value)
+ break;
+ value = SET_DEST (part);
+ }
+ }
+ else if (GET_CODE (part) != CLOBBER)
+ break;
+ }
+
+ if (i < 0)
+ {
+ delete_insn_and_edges (insn);
+ /* We're done with this insn. */
+ return;
+ }
+
+ /* It's not a no-op, but we can try to simplify it. */
+ for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
+ if (GET_CODE (XVECEXP (body, 0, i)) == SET)
+ count += reload_cse_simplify_set (XVECEXP (body, 0, i), insn);
+
+ if (count > 0)
+ apply_change_group ();
+ else
+ reload_cse_simplify_operands (insn, testreg);
+ }
+}
+
+/* Do a very simple CSE pass over the hard registers.
+
+ This function detects no-op moves where we happened to assign two
+ different pseudo-registers to the same hard register, and then
+ copied one to the other. Reload will generate a useless
+ instruction copying a register to itself.
+
+ This function also detects cases where we load a value from memory
+ into two different registers, and (if memory is more expensive than
+ registers) changes it to simply copy the first register into the
+ second register.
+
+ Another optimization is performed that scans the operands of each
+ instruction to see whether the value is already available in a
+ hard register. It then replaces the operand with the hard register
+ if possible, much like an optional reload would. */
+
+static void
+reload_cse_regs_1 (rtx first)
+{
+ rtx insn;
+ rtx testreg = gen_rtx_REG (VOIDmode, -1);
+
+ cselib_init ();
+ init_alias_analysis ();
+
+ for (insn = first; insn; insn = NEXT_INSN (insn))
+ {
+ if (INSN_P (insn))
+ reload_cse_simplify (insn, testreg);
+
+ cselib_process_insn (insn);
+ }
+
+ /* Clean up. */
+ end_alias_analysis ();
+ cselib_finish ();
+}
+
+/* Try to simplify a single SET instruction. SET is the set pattern.
+ INSN is the instruction it came from.
+ This function only handles one case: if we set a register to a value
+ which is not a register, we try to find that value in some other register
+ and change the set into a register copy. */
+
+static int
+reload_cse_simplify_set (rtx set, rtx insn)
+{
+ int did_change = 0;
+ int dreg;
+ rtx src;
+ enum reg_class dclass;
+ int old_cost;
+ cselib_val *val;
+ struct elt_loc_list *l;
+#ifdef LOAD_EXTEND_OP
+ enum rtx_code extend_op = NIL;
+#endif
+
+ dreg = true_regnum (SET_DEST (set));
+ if (dreg < 0)
+ return 0;
+
+ src = SET_SRC (set);
+ if (side_effects_p (src) || true_regnum (src) >= 0)
+ return 0;
+
+ dclass = REGNO_REG_CLASS (dreg);
+
+#ifdef LOAD_EXTEND_OP
+ /* When replacing a memory with a register, we need to honor assumptions
+ that combine made wrt the contents of sign bits. We'll do this by
+ generating an extend instruction instead of a reg->reg copy. Thus
+ the destination must be a register that we can widen. */
+ if (GET_CODE (src) == MEM
+ && GET_MODE_BITSIZE (GET_MODE (src)) < BITS_PER_WORD
+ && (extend_op = LOAD_EXTEND_OP (GET_MODE (src))) != NIL
+ && GET_CODE (SET_DEST (set)) != REG)
+ return 0;
+#endif
+
+ val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0);
+ if (! val)
+ return 0;
+
+ /* If memory loads are cheaper than register copies, don't change them. */
+ if (GET_CODE (src) == MEM)
+ old_cost = MEMORY_MOVE_COST (GET_MODE (src), dclass, 1);
+ else if (GET_CODE (src) == REG)
+ old_cost = REGISTER_MOVE_COST (GET_MODE (src),
+ REGNO_REG_CLASS (REGNO (src)), dclass);
+ else
+ old_cost = rtx_cost (src, SET);
+
+ for (l = val->locs; l; l = l->next)
+ {
+ rtx this_rtx = l->loc;
+ int this_cost;
+
+ if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx, 0))
+ {
+#ifdef LOAD_EXTEND_OP
+ if (extend_op != NIL)
+ {
+ HOST_WIDE_INT this_val;
+
+ /* ??? I'm lazy and don't wish to handle CONST_DOUBLE. Other
+ constants, such as SYMBOL_REF, cannot be extended. */
+ if (GET_CODE (this_rtx) != CONST_INT)
+ continue;
+
+ this_val = INTVAL (this_rtx);
+ switch (extend_op)
+ {
+ case ZERO_EXTEND:
+ this_val &= GET_MODE_MASK (GET_MODE (src));
+ break;
+ case SIGN_EXTEND:
+ /* ??? In theory we're already extended. */
+ if (this_val == trunc_int_for_mode (this_val, GET_MODE (src)))
+ break;
+ default:
+ abort ();
+ }
+ this_rtx = GEN_INT (this_val);
+ }
+#endif
+ this_cost = rtx_cost (this_rtx, SET);
+ }
+ else if (GET_CODE (this_rtx) == REG)
+ {
+#ifdef LOAD_EXTEND_OP
+ if (extend_op != NIL)
+ {
+ this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx);
+ this_cost = rtx_cost (this_rtx, SET);
+ }
+ else
+#endif
+ this_cost = REGISTER_MOVE_COST (GET_MODE (this_rtx),
+ REGNO_REG_CLASS (REGNO (this_rtx)),
+ dclass);
+ }
+ else
+ continue;
+
+ /* If equal costs, prefer registers over anything else. That
+ tends to lead to smaller instructions on some machines. */
+ if (this_cost < old_cost
+ || (this_cost == old_cost
+ && GET_CODE (this_rtx) == REG
+ && GET_CODE (SET_SRC (set)) != REG))
+ {
+#ifdef LOAD_EXTEND_OP
+ if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) < BITS_PER_WORD
+ && extend_op != NIL
+#ifdef CANNOT_CHANGE_MODE_CLASS
+ && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SET_DEST (set)),
+ word_mode,
+ REGNO_REG_CLASS (REGNO (SET_DEST (set))))
+#endif
+ )
+ {
+ rtx wide_dest = gen_rtx_REG (word_mode, REGNO (SET_DEST (set)));
+ ORIGINAL_REGNO (wide_dest) = ORIGINAL_REGNO (SET_DEST (set));
+ validate_change (insn, &SET_DEST (set), wide_dest, 1);
+ }
+#endif
+
+ validate_change (insn, &SET_SRC (set), copy_rtx (this_rtx), 1);
+ old_cost = this_cost, did_change = 1;
+ }
+ }
+
+ return did_change;
+}
+
+/* Try to replace operands in INSN with equivalent values that are already
+ in registers. This can be viewed as optional reloading.
+
+ For each non-register operand in the insn, see if any hard regs are
+ known to be equivalent to that operand. Record the alternatives which
+ can accept these hard registers. Among all alternatives, select the
+ ones which are better or equal to the one currently matching, where
+ "better" is in terms of '?' and '!' constraints. Among the remaining
+ alternatives, select the one which replaces most operands with
+ hard registers. */
+
+static int
+reload_cse_simplify_operands (rtx insn, rtx testreg)
+{
+ int i, j;
+
+ /* For each operand, all registers that are equivalent to it. */
+ HARD_REG_SET equiv_regs[MAX_RECOG_OPERANDS];
+
+ const char *constraints[MAX_RECOG_OPERANDS];
+
+ /* Vector recording how bad an alternative is. */
+ int *alternative_reject;
+ /* Vector recording how many registers can be introduced by choosing
+ this alternative. */
+ int *alternative_nregs;
+ /* Array of vectors recording, for each operand and each alternative,
+ which hard register to substitute, or -1 if the operand should be
+ left as it is. */
+ int *op_alt_regno[MAX_RECOG_OPERANDS];
+ /* Array of alternatives, sorted in order of decreasing desirability. */
+ int *alternative_order;
+
+ extract_insn (insn);
+
+ if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0)
+ return 0;
+
+ /* Figure out which alternative currently matches. */
+ if (! constrain_operands (1))
+ fatal_insn_not_found (insn);
+
+ alternative_reject = alloca (recog_data.n_alternatives * sizeof (int));
+ alternative_nregs = alloca (recog_data.n_alternatives * sizeof (int));
+ alternative_order = alloca (recog_data.n_alternatives * sizeof (int));
+ memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int));
+ memset (alternative_nregs, 0, recog_data.n_alternatives * sizeof (int));
+
+ /* For each operand, find out which regs are equivalent. */
+ for (i = 0; i < recog_data.n_operands; i++)
+ {
+ cselib_val *v;
+ struct elt_loc_list *l;
+ rtx op;
+ enum machine_mode mode;
+
+ CLEAR_HARD_REG_SET (equiv_regs[i]);
+
+ /* cselib blows up on CODE_LABELs. Trying to fix that doesn't seem
+ right, so avoid the problem here. Likewise if we have a constant
+ and the insn pattern doesn't tell us the mode we need. */
+ if (GET_CODE (recog_data.operand[i]) == CODE_LABEL
+ || (CONSTANT_P (recog_data.operand[i])
+ && recog_data.operand_mode[i] == VOIDmode))
+ continue;
+
+ op = recog_data.operand[i];
+ mode = GET_MODE (op);
+#ifdef LOAD_EXTEND_OP
+ if (GET_CODE (op) == MEM
+ && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
+ && LOAD_EXTEND_OP (mode) != NIL)
+ {
+ rtx set = single_set (insn);
+
+ /* We might have multiple sets, some of which do implict
+ extension. Punt on this for now. */
+ if (! set)
+ continue;
+ /* If the destination is a also MEM or a STRICT_LOW_PART, no
+ extension applies.
+ Also, if there is an explicit extension, we don't have to
+ worry about an implicit one. */
+ else if (GET_CODE (SET_DEST (set)) == MEM
+ || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART
+ || GET_CODE (SET_SRC (set)) == ZERO_EXTEND
+ || GET_CODE (SET_SRC (set)) == SIGN_EXTEND)
+ ; /* Continue ordinary processing. */
+#ifdef CANNOT_CHANGE_MODE_CLASS
+ /* If the register cannot change mode to word_mode, it follows that
+ it cannot have been used in word_mode. */
+ else if (GET_CODE (SET_DEST (set)) == REG
+ && CANNOT_CHANGE_MODE_CLASS (GET_MODE (SET_DEST (set)),
+ word_mode,
+ REGNO_REG_CLASS (REGNO (SET_DEST (set)))))
+ ; /* Continue ordinary processing. */
+#endif
+ /* If this is a straight load, make the extension explicit. */
+ else if (GET_CODE (SET_DEST (set)) == REG
+ && recog_data.n_operands == 2
+ && SET_SRC (set) == op
+ && SET_DEST (set) == recog_data.operand[1-i])
+ {
+ validate_change (insn, recog_data.operand_loc[i],
+ gen_rtx_fmt_e (LOAD_EXTEND_OP (mode),
+ word_mode, op),
+ 1);
+ validate_change (insn, recog_data.operand_loc[1-i],
+ gen_rtx_REG (word_mode, REGNO (SET_DEST (set))),
+ 1);
+ if (! apply_change_group ())
+ return 0;
+ return reload_cse_simplify_operands (insn, testreg);
+ }
+ else
+ /* ??? There might be arithmetic operations with memory that are
+ safe to optimize, but is it worth the trouble? */
+ continue;
+ }
+#endif /* LOAD_EXTEND_OP */
+ v = cselib_lookup (op, recog_data.operand_mode[i], 0);
+ if (! v)
+ continue;
+
+ for (l = v->locs; l; l = l->next)
+ if (GET_CODE (l->loc) == REG)
+ SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc));
+ }
+
+ for (i = 0; i < recog_data.n_operands; i++)
+ {
+ enum machine_mode mode;
+ int regno;
+ const char *p;
+
+ op_alt_regno[i] = alloca (recog_data.n_alternatives * sizeof (int));
+ for (j = 0; j < recog_data.n_alternatives; j++)
+ op_alt_regno[i][j] = -1;
+
+ p = constraints[i] = recog_data.constraints[i];
+ mode = recog_data.operand_mode[i];
+
+ /* Add the reject values for each alternative given by the constraints
+ for this operand. */
+ j = 0;
+ while (*p != '\0')
+ {
+ char c = *p++;
+ if (c == ',')
+ j++;
+ else if (c == '?')
+ alternative_reject[j] += 3;
+ else if (c == '!')
+ alternative_reject[j] += 300;
+ }
+
+ /* We won't change operands which are already registers. We
+ also don't want to modify output operands. */
+ regno = true_regnum (recog_data.operand[i]);
+ if (regno >= 0
+ || constraints[i][0] == '='
+ || constraints[i][0] == '+')
+ continue;
+
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ {
+ int class = (int) NO_REGS;
+
+ if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
+ continue;
+
+ REGNO (testreg) = regno;
+ PUT_MODE (testreg, mode);
+
+ /* We found a register equal to this operand. Now look for all
+ alternatives that can accept this register and have not been
+ assigned a register they can use yet. */
+ j = 0;
+ p = constraints[i];
+ for (;;)
+ {
+ char c = *p;
+
+ switch (c)
+ {
+ case '=': case '+': case '?':
+ case '#': case '&': case '!':
+ case '*': case '%':
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case 'm': case '<': case '>': case 'V': case 'o':
+ case 'E': case 'F': case 'G': case 'H':
+ case 's': case 'i': case 'n':
+ case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P':
+ case 'p': case 'X':
+ /* These don't say anything we care about. */
+ break;
+
+ case 'g': case 'r':
+ class = reg_class_subunion[(int) class][(int) GENERAL_REGS];
+ break;
+
+ default:
+ class
+ = (reg_class_subunion
+ [(int) class]
+ [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]);
+ break;
+
+ case ',': case '\0':
+ /* See if REGNO fits this alternative, and set it up as the
+ replacement register if we don't have one for this
+ alternative yet and the operand being replaced is not
+ a cheap CONST_INT. */
+ if (op_alt_regno[i][j] == -1
+ && reg_fits_class_p (testreg, class, 0, mode)
+ && (GET_CODE (recog_data.operand[i]) != CONST_INT
+ || (rtx_cost (recog_data.operand[i], SET)
+ > rtx_cost (testreg, SET))))
+ {
+ alternative_nregs[j]++;
+ op_alt_regno[i][j] = regno;
+ }
+ j++;
+ break;
+ }
+ p += CONSTRAINT_LEN (c, p);
+
+ if (c == '\0')
+ break;
+ }
+ }
+ }
+
+ /* Record all alternatives which are better or equal to the currently
+ matching one in the alternative_order array. */
+ for (i = j = 0; i < recog_data.n_alternatives; i++)
+ if (alternative_reject[i] <= alternative_reject[which_alternative])
+ alternative_order[j++] = i;
+ recog_data.n_alternatives = j;
+
+ /* Sort it. Given a small number of alternatives, a dumb algorithm
+ won't hurt too much. */
+ for (i = 0; i < recog_data.n_alternatives - 1; i++)
+ {
+ int best = i;
+ int best_reject = alternative_reject[alternative_order[i]];
+ int best_nregs = alternative_nregs[alternative_order[i]];
+ int tmp;
+
+ for (j = i + 1; j < recog_data.n_alternatives; j++)
+ {
+ int this_reject = alternative_reject[alternative_order[j]];
+ int this_nregs = alternative_nregs[alternative_order[j]];
+
+ if (this_reject < best_reject
+ || (this_reject == best_reject && this_nregs < best_nregs))
+ {
+ best = j;
+ best_reject = this_reject;
+ best_nregs = this_nregs;
+ }
+ }
+
+ tmp = alternative_order[best];
+ alternative_order[best] = alternative_order[i];
+ alternative_order[i] = tmp;
+ }
+
+ /* Substitute the operands as determined by op_alt_regno for the best
+ alternative. */
+ j = alternative_order[0];
+
+ for (i = 0; i < recog_data.n_operands; i++)
+ {
+ enum machine_mode mode = recog_data.operand_mode[i];
+ if (op_alt_regno[i][j] == -1)
+ continue;
+
+ validate_change (insn, recog_data.operand_loc[i],
+ gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
+ }
+
+ for (i = recog_data.n_dups - 1; i >= 0; i--)
+ {
+ int op = recog_data.dup_num[i];
+ enum machine_mode mode = recog_data.operand_mode[op];
+
+ if (op_alt_regno[op][j] == -1)
+ continue;
+
+ validate_change (insn, recog_data.dup_loc[i],
+ gen_rtx_REG (mode, op_alt_regno[op][j]), 1);
+ }
+
+ return apply_change_group ();
+}
+
+/* If reload couldn't use reg+reg+offset addressing, try to use reg+reg
+ addressing now.
+ This code might also be useful when reload gave up on reg+reg addressing
+ because of clashes between the return register and INDEX_REG_CLASS. */
+
+/* The maximum number of uses of a register we can keep track of to
+ replace them with reg+reg addressing. */
+#define RELOAD_COMBINE_MAX_USES 6
+
+/* INSN is the insn where a register has ben used, and USEP points to the
+ location of the register within the rtl. */
+struct reg_use { rtx insn, *usep; };
+
+/* If the register is used in some unknown fashion, USE_INDEX is negative.
+ If it is dead, USE_INDEX is RELOAD_COMBINE_MAX_USES, and STORE_RUID
+ indicates where it becomes live again.
+ Otherwise, USE_INDEX is the index of the last encountered use of the
+ register (which is first among these we have seen since we scan backwards),
+ OFFSET contains the constant offset that is added to the register in
+ all encountered uses, and USE_RUID indicates the first encountered, i.e.
+ last, of these uses.
+ STORE_RUID is always meaningful if we only want to use a value in a
+ register in a different place: it denotes the next insn in the insn
+ stream (i.e. the last encountered) that sets or clobbers the register. */
+static struct
+ {
+ struct reg_use reg_use[RELOAD_COMBINE_MAX_USES];
+ int use_index;
+ rtx offset;
+ int store_ruid;
+ int use_ruid;
+ } reg_state[FIRST_PSEUDO_REGISTER];
+
+/* Reverse linear uid. This is increased in reload_combine while scanning
+ the instructions from last to first. It is used to set last_label_ruid
+ and the store_ruid / use_ruid fields in reg_state. */
+static int reload_combine_ruid;
+
+#define LABEL_LIVE(LABEL) \
+ (label_live[CODE_LABEL_NUMBER (LABEL) - min_labelno])
+
+static void
+reload_combine (void)
+{
+ rtx insn, set;
+ int first_index_reg = -1;
+ int last_index_reg = 0;
+ int i;
+ basic_block bb;
+ unsigned int r;
+ int last_label_ruid;
+ int min_labelno, n_labels;
+ HARD_REG_SET ever_live_at_start, *label_live;
+
+ /* If reg+reg can be used in offsetable memory addresses, the main chunk of
+ reload has already used it where appropriate, so there is no use in
+ trying to generate it now. */
+ if (double_reg_address_ok && INDEX_REG_CLASS != NO_REGS)
+ return;
+
+ /* To avoid wasting too much time later searching for an index register,
+ determine the minimum and maximum index register numbers. */
+ for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
+ if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], r))
+ {
+ if (first_index_reg == -1)
+ first_index_reg = r;
+
+ last_index_reg = r;
+ }
+
+ /* If no index register is available, we can quit now. */
+ if (first_index_reg == -1)
+ return;
+
+ /* Set up LABEL_LIVE and EVER_LIVE_AT_START. The register lifetime
+ information is a bit fuzzy immediately after reload, but it's
+ still good enough to determine which registers are live at a jump
+ destination. */
+ min_labelno = get_first_label_num ();
+ n_labels = max_label_num () - min_labelno;
+ label_live = xmalloc (n_labels * sizeof (HARD_REG_SET));
+ CLEAR_HARD_REG_SET (ever_live_at_start);
+
+ FOR_EACH_BB_REVERSE (bb)
+ {
+ insn = BB_HEAD (bb);
+ if (GET_CODE (insn) == CODE_LABEL)
+ {
+ HARD_REG_SET live;
+
+ REG_SET_TO_HARD_REG_SET (live,
+ bb->global_live_at_start);
+ compute_use_by_pseudos (&live,
+ bb->global_live_at_start);
+ COPY_HARD_REG_SET (LABEL_LIVE (insn), live);
+ IOR_HARD_REG_SET (ever_live_at_start, live);
+ }
+ }
+
+ /* Initialize last_label_ruid, reload_combine_ruid and reg_state. */
+ last_label_ruid = reload_combine_ruid = 0;
+ for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
+ {
+ reg_state[r].store_ruid = reload_combine_ruid;
+ if (fixed_regs[r])
+ reg_state[r].use_index = -1;
+ else
+ reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
+ }
+
+ for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
+ {
+ rtx note;
+
+ /* We cannot do our optimization across labels. Invalidating all the use
+ information we have would be costly, so we just note where the label
+ is and then later disable any optimization that would cross it. */
+ if (GET_CODE (insn) == CODE_LABEL)
+ last_label_ruid = reload_combine_ruid;
+ else if (GET_CODE (insn) == BARRIER)
+ for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
+ if (! fixed_regs[r])
+ reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
+
+ if (! INSN_P (insn))
+ continue;
+
+ reload_combine_ruid++;
+
+ /* Look for (set (REGX) (CONST_INT))
+ (set (REGX) (PLUS (REGX) (REGY)))
+ ...
+ ... (MEM (REGX)) ...
+ and convert it to
+ (set (REGZ) (CONST_INT))
+ ...
+ ... (MEM (PLUS (REGZ) (REGY)))... .
+
+ First, check that we have (set (REGX) (PLUS (REGX) (REGY)))
+ and that we know all uses of REGX before it dies.
+ Also, explicitly check that REGX != REGY; our life information
+ does not yet show whether REGY changes in this insn. */
+ set = single_set (insn);
+ if (set != NULL_RTX
+ && GET_CODE (SET_DEST (set)) == REG
+ && (HARD_REGNO_NREGS (REGNO (SET_DEST (set)),
+ GET_MODE (SET_DEST (set)))
+ == 1)
+ && GET_CODE (SET_SRC (set)) == PLUS
+ && GET_CODE (XEXP (SET_SRC (set), 1)) == REG
+ && rtx_equal_p (XEXP (SET_SRC (set), 0), SET_DEST (set))
+ && !rtx_equal_p (XEXP (SET_SRC (set), 1), SET_DEST (set))
+ && last_label_ruid < reg_state[REGNO (SET_DEST (set))].use_ruid)
+ {
+ rtx reg = SET_DEST (set);
+ rtx plus = SET_SRC (set);
+ rtx base = XEXP (plus, 1);
+ rtx prev = prev_nonnote_insn (insn);
+ rtx prev_set = prev ? single_set (prev) : NULL_RTX;
+ unsigned int regno = REGNO (reg);
+ rtx const_reg = NULL_RTX;
+ rtx reg_sum = NULL_RTX;
+
+ /* Now, we need an index register.
+ We'll set index_reg to this index register, const_reg to the
+ register that is to be loaded with the constant
+ (denoted as REGZ in the substitution illustration above),
+ and reg_sum to the register-register that we want to use to
+ substitute uses of REG (typically in MEMs) with.
+ First check REG and BASE for being index registers;
+ we can use them even if they are not dead. */
+ if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
+ || TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
+ REGNO (base)))
+ {
+ const_reg = reg;
+ reg_sum = plus;
+ }
+ else
+ {
+ /* Otherwise, look for a free index register. Since we have
+ checked above that neither REG nor BASE are index registers,
+ if we find anything at all, it will be different from these
+ two registers. */
+ for (i = first_index_reg; i <= last_index_reg; i++)
+ {
+ if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
+ i)
+ && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
+ && reg_state[i].store_ruid <= reg_state[regno].use_ruid
+ && HARD_REGNO_NREGS (i, GET_MODE (reg)) == 1)
+ {
+ rtx index_reg = gen_rtx_REG (GET_MODE (reg), i);
+
+ const_reg = index_reg;
+ reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base);
+ break;
+ }
+ }
+ }
+
+ /* Check that PREV_SET is indeed (set (REGX) (CONST_INT)) and that
+ (REGY), i.e. BASE, is not clobbered before the last use we'll
+ create. */
+ if (prev_set != 0
+ && GET_CODE (SET_SRC (prev_set)) == CONST_INT
+ && rtx_equal_p (SET_DEST (prev_set), reg)
+ && reg_state[regno].use_index >= 0
+ && (reg_state[REGNO (base)].store_ruid
+ <= reg_state[regno].use_ruid)
+ && reg_sum != 0)
+ {
+ int i;
+
+ /* Change destination register and, if necessary, the
+ constant value in PREV, the constant loading instruction. */
+ validate_change (prev, &SET_DEST (prev_set), const_reg, 1);
+ if (reg_state[regno].offset != const0_rtx)
+ validate_change (prev,
+ &SET_SRC (prev_set),
+ GEN_INT (INTVAL (SET_SRC (prev_set))
+ + INTVAL (reg_state[regno].offset)),
+ 1);
+
+ /* Now for every use of REG that we have recorded, replace REG
+ with REG_SUM. */
+ for (i = reg_state[regno].use_index;
+ i < RELOAD_COMBINE_MAX_USES; i++)
+ validate_change (reg_state[regno].reg_use[i].insn,
+ reg_state[regno].reg_use[i].usep,
+ /* Each change must have its own
+ replacement. */
+ copy_rtx (reg_sum), 1);
+
+ if (apply_change_group ())
+ {
+ rtx *np;
+
+ /* Delete the reg-reg addition. */
+ delete_insn (insn);
+
+ if (reg_state[regno].offset != const0_rtx)
+ /* Previous REG_EQUIV / REG_EQUAL notes for PREV
+ are now invalid. */
+ for (np = &REG_NOTES (prev); *np;)
+ {
+ if (REG_NOTE_KIND (*np) == REG_EQUAL
+ || REG_NOTE_KIND (*np) == REG_EQUIV)
+ *np = XEXP (*np, 1);
+ else
+ np = &XEXP (*np, 1);
+ }
+
+ reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
+ reg_state[REGNO (const_reg)].store_ruid
+ = reload_combine_ruid;
+ continue;
+ }
+ }
+ }
+
+ note_stores (PATTERN (insn), reload_combine_note_store, NULL);
+
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ rtx link;
+
+ for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
+ if (call_used_regs[r])
+ {
+ reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
+ reg_state[r].store_ruid = reload_combine_ruid;
+ }
+
+ for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
+ link = XEXP (link, 1))
+ {
+ rtx usage_rtx = XEXP (XEXP (link, 0), 0);
+ if (GET_CODE (usage_rtx) == REG)
+ {
+ unsigned int i;
+ unsigned int start_reg = REGNO (usage_rtx);
+ unsigned int num_regs =
+ HARD_REGNO_NREGS (start_reg, GET_MODE (usage_rtx));
+ unsigned int end_reg = start_reg + num_regs - 1;
+ for (i = start_reg; i <= end_reg; i++)
+ if (GET_CODE (XEXP (link, 0)) == CLOBBER)
+ {
+ reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
+ reg_state[i].store_ruid = reload_combine_ruid;
+ }
+ else
+ reg_state[i].use_index = -1;
+ }
+ }
+
+ }
+ else if (GET_CODE (insn) == JUMP_INSN
+ && GET_CODE (PATTERN (insn)) != RETURN)
+ {
+ /* Non-spill registers might be used at the call destination in
+ some unknown fashion, so we have to mark the unknown use. */
+ HARD_REG_SET *live;
+
+ if ((condjump_p (insn) || condjump_in_parallel_p (insn))
+ && JUMP_LABEL (insn))
+ live = &LABEL_LIVE (JUMP_LABEL (insn));
+ else
+ live = &ever_live_at_start;
+
+ for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; --i)
+ if (TEST_HARD_REG_BIT (*live, i))
+ reg_state[i].use_index = -1;
+ }
+
+ reload_combine_note_use (&PATTERN (insn), insn);
+ for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ {
+ if (REG_NOTE_KIND (note) == REG_INC
+ && GET_CODE (XEXP (note, 0)) == REG)
+ {
+ int regno = REGNO (XEXP (note, 0));
+
+ reg_state[regno].store_ruid = reload_combine_ruid;
+ reg_state[regno].use_index = -1;
+ }
+ }
+ }
+
+ free (label_live);
+}
+
+/* Check if DST is a register or a subreg of a register; if it is,
+ update reg_state[regno].store_ruid and reg_state[regno].use_index
+ accordingly. Called via note_stores from reload_combine. */
+
+static void
+reload_combine_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED)
+{
+ int regno = 0;
+ int i;
+ enum machine_mode mode = GET_MODE (dst);
+
+ if (GET_CODE (dst) == SUBREG)
+ {
+ regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
+ GET_MODE (SUBREG_REG (dst)),
+ SUBREG_BYTE (dst),
+ GET_MODE (dst));
+ dst = SUBREG_REG (dst);
+ }
+ if (GET_CODE (dst) != REG)
+ return;
+ regno += REGNO (dst);
+
+ /* note_stores might have stripped a STRICT_LOW_PART, so we have to be
+ careful with registers / register parts that are not full words.
+
+ Similarly for ZERO_EXTRACT and SIGN_EXTRACT. */
+ if (GET_CODE (set) != SET
+ || GET_CODE (SET_DEST (set)) == ZERO_EXTRACT
+ || GET_CODE (SET_DEST (set)) == SIGN_EXTRACT
+ || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
+ {
+ for (i = HARD_REGNO_NREGS (regno, mode) - 1 + regno; i >= regno; i--)
+ {
+ reg_state[i].use_index = -1;
+ reg_state[i].store_ruid = reload_combine_ruid;
+ }
+ }
+ else
+ {
+ for (i = HARD_REGNO_NREGS (regno, mode) - 1 + regno; i >= regno; i--)
+ {
+ reg_state[i].store_ruid = reload_combine_ruid;
+ reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
+ }
+ }
+}
+
+/* XP points to a piece of rtl that has to be checked for any uses of
+ registers.
+ *XP is the pattern of INSN, or a part of it.
+ Called from reload_combine, and recursively by itself. */
+static void
+reload_combine_note_use (rtx *xp, rtx insn)
+{
+ rtx x = *xp;
+ enum rtx_code code = x->code;
+ const char *fmt;
+ int i, j;
+ rtx offset = const0_rtx; /* For the REG case below. */
+
+ switch (code)
+ {
+ case SET:
+ if (GET_CODE (SET_DEST (x)) == REG)
+ {
+ reload_combine_note_use (&SET_SRC (x), insn);
+ return;
+ }
+ break;
+
+ case USE:
+ /* If this is the USE of a return value, we can't change it. */
+ if (GET_CODE (XEXP (x, 0)) == REG && REG_FUNCTION_VALUE_P (XEXP (x, 0)))
+ {
+ /* Mark the return register as used in an unknown fashion. */
+ rtx reg = XEXP (x, 0);
+ int regno = REGNO (reg);
+ int nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg));
+
+ while (--nregs >= 0)
+ reg_state[regno + nregs].use_index = -1;
+ return;
+ }
+ break;
+
+ case CLOBBER:
+ if (GET_CODE (SET_DEST (x)) == REG)
+ {
+ /* No spurious CLOBBERs of pseudo registers may remain. */
+ if (REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER)
+ abort ();
+ return;
+ }
+ break;
+
+ case PLUS:
+ /* We are interested in (plus (reg) (const_int)) . */
+ if (GET_CODE (XEXP (x, 0)) != REG
+ || GET_CODE (XEXP (x, 1)) != CONST_INT)
+ break;
+ offset = XEXP (x, 1);
+ x = XEXP (x, 0);
+ /* Fall through. */
+ case REG:
+ {
+ int regno = REGNO (x);
+ int use_index;
+ int nregs;
+
+ /* No spurious USEs of pseudo registers may remain. */
+ if (regno >= FIRST_PSEUDO_REGISTER)
+ abort ();
+
+ nregs = HARD_REGNO_NREGS (regno, GET_MODE (x));
+
+ /* We can't substitute into multi-hard-reg uses. */
+ if (nregs > 1)
+ {
+ while (--nregs >= 0)
+ reg_state[regno + nregs].use_index = -1;
+ return;
+ }
+
+ /* If this register is already used in some unknown fashion, we
+ can't do anything.
+ If we decrement the index from zero to -1, we can't store more
+ uses, so this register becomes used in an unknown fashion. */
+ use_index = --reg_state[regno].use_index;
+ if (use_index < 0)
+ return;
+
+ if (use_index != RELOAD_COMBINE_MAX_USES - 1)
+ {
+ /* We have found another use for a register that is already
+ used later. Check if the offsets match; if not, mark the
+ register as used in an unknown fashion. */
+ if (! rtx_equal_p (offset, reg_state[regno].offset))
+ {
+ reg_state[regno].use_index = -1;
+ return;
+ }
+ }
+ else
+ {
+ /* This is the first use of this register we have seen since we
+ marked it as dead. */
+ reg_state[regno].offset = offset;
+ reg_state[regno].use_ruid = reload_combine_ruid;
+ }
+ reg_state[regno].reg_use[use_index].insn = insn;
+ reg_state[regno].reg_use[use_index].usep = xp;
+ return;
+ }
+
+ default:
+ break;
+ }
+
+ /* Recursively process the components of X. */
+ fmt = GET_RTX_FORMAT (code);
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ reload_combine_note_use (&XEXP (x, i), insn);
+ else if (fmt[i] == 'E')
+ {
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ reload_combine_note_use (&XVECEXP (x, i, j), insn);
+ }
+ }
+}
+
+/* See if we can reduce the cost of a constant by replacing a move
+ with an add. We track situations in which a register is set to a
+ constant or to a register plus a constant. */
+/* We cannot do our optimization across labels. Invalidating all the
+ information about register contents we have would be costly, so we
+ use move2add_last_label_luid to note where the label is and then
+ later disable any optimization that would cross it.
+ reg_offset[n] / reg_base_reg[n] / reg_mode[n] are only valid if
+ reg_set_luid[n] is greater than move2add_last_label_luid. */
+static int reg_set_luid[FIRST_PSEUDO_REGISTER];
+
+/* If reg_base_reg[n] is negative, register n has been set to
+ reg_offset[n] in mode reg_mode[n] .
+ If reg_base_reg[n] is non-negative, register n has been set to the
+ sum of reg_offset[n] and the value of register reg_base_reg[n]
+ before reg_set_luid[n], calculated in mode reg_mode[n] . */
+static HOST_WIDE_INT reg_offset[FIRST_PSEUDO_REGISTER];
+static int reg_base_reg[FIRST_PSEUDO_REGISTER];
+static enum machine_mode reg_mode[FIRST_PSEUDO_REGISTER];
+
+/* move2add_luid is linearly increased while scanning the instructions
+ from first to last. It is used to set reg_set_luid in
+ reload_cse_move2add and move2add_note_store. */
+static int move2add_luid;
+
+/* move2add_last_label_luid is set whenever a label is found. Labels
+ invalidate all previously collected reg_offset data. */
+static int move2add_last_label_luid;
+
+/* ??? We don't know how zero / sign extension is handled, hence we
+ can't go from a narrower to a wider mode. */
+#define MODES_OK_FOR_MOVE2ADD(OUTMODE, INMODE) \
+ (GET_MODE_SIZE (OUTMODE) == GET_MODE_SIZE (INMODE) \
+ || (GET_MODE_SIZE (OUTMODE) <= GET_MODE_SIZE (INMODE) \
+ && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (OUTMODE), \
+ GET_MODE_BITSIZE (INMODE))))
+
+static void
+reload_cse_move2add (rtx first)
+{
+ int i;
+ rtx insn;
+
+ for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
+ reg_set_luid[i] = 0;
+
+ move2add_last_label_luid = 0;
+ move2add_luid = 2;
+ for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
+ {
+ rtx pat, note;
+
+ if (GET_CODE (insn) == CODE_LABEL)
+ {
+ move2add_last_label_luid = move2add_luid;
+ /* We're going to increment move2add_luid twice after a
+ label, so that we can use move2add_last_label_luid + 1 as
+ the luid for constants. */
+ move2add_luid++;
+ continue;
+ }
+ if (! INSN_P (insn))
+ continue;
+ pat = PATTERN (insn);
+ /* For simplicity, we only perform this optimization on
+ straightforward SETs. */
+ if (GET_CODE (pat) == SET
+ && GET_CODE (SET_DEST (pat)) == REG)
+ {
+ rtx reg = SET_DEST (pat);
+ int regno = REGNO (reg);
+ rtx src = SET_SRC (pat);
+
+ /* Check if we have valid information on the contents of this
+ register in the mode of REG. */
+ if (reg_set_luid[regno] > move2add_last_label_luid
+ && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[regno]))
+ {
+ /* Try to transform (set (REGX) (CONST_INT A))
+ ...
+ (set (REGX) (CONST_INT B))
+ to
+ (set (REGX) (CONST_INT A))
+ ...
+ (set (REGX) (plus (REGX) (CONST_INT B-A)))
+ or
+ (set (REGX) (CONST_INT A))
+ ...
+ (set (STRICT_LOW_PART (REGX)) (CONST_INT B))
+ */
+
+ if (GET_CODE (src) == CONST_INT && reg_base_reg[regno] < 0)
+ {
+ rtx new_src =
+ GEN_INT (trunc_int_for_mode (INTVAL (src)
+ - reg_offset[regno],
+ GET_MODE (reg)));
+ /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
+ use (set (reg) (reg)) instead.
+ We don't delete this insn, nor do we convert it into a
+ note, to avoid losing register notes or the return
+ value flag. jump2 already knows how to get rid of
+ no-op moves. */
+ if (new_src == const0_rtx)
+ {
+ /* If the constants are different, this is a
+ truncation, that, if turned into (set (reg)
+ (reg)), would be discarded. Maybe we should
+ try a truncMN pattern? */
+ if (INTVAL (src) == reg_offset [regno])
+ validate_change (insn, &SET_SRC (pat), reg, 0);
+ }
+ else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET)
+ && have_add2_insn (reg, new_src))
+ {
+ rtx newpat = gen_rtx_SET (VOIDmode,
+ reg,
+ gen_rtx_PLUS (GET_MODE (reg),
+ reg,
+ new_src));
+ validate_change (insn, &PATTERN (insn), newpat, 0);
+ }
+ else
+ {
+ enum machine_mode narrow_mode;
+ for (narrow_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+ narrow_mode != GET_MODE (reg);
+ narrow_mode = GET_MODE_WIDER_MODE (narrow_mode))
+ {
+ if (have_insn_for (STRICT_LOW_PART, narrow_mode)
+ && ((reg_offset[regno]
+ & ~GET_MODE_MASK (narrow_mode))
+ == (INTVAL (src)
+ & ~GET_MODE_MASK (narrow_mode))))
+ {
+ rtx narrow_reg = gen_rtx_REG (narrow_mode,
+ REGNO (reg));
+ rtx narrow_src =
+ GEN_INT (trunc_int_for_mode (INTVAL (src),
+ narrow_mode));
+ rtx new_set =
+ gen_rtx_SET (VOIDmode,
+ gen_rtx_STRICT_LOW_PART (VOIDmode,
+ narrow_reg),
+ narrow_src);
+ if (validate_change (insn, &PATTERN (insn),
+ new_set, 0))
+ break;
+ }
+ }
+ }
+ reg_set_luid[regno] = move2add_luid;
+ reg_mode[regno] = GET_MODE (reg);
+ reg_offset[regno] = INTVAL (src);
+ continue;
+ }
+
+ /* Try to transform (set (REGX) (REGY))
+ (set (REGX) (PLUS (REGX) (CONST_INT A)))
+ ...
+ (set (REGX) (REGY))
+ (set (REGX) (PLUS (REGX) (CONST_INT B)))
+ to
+ (set (REGX) (REGY))
+ (set (REGX) (PLUS (REGX) (CONST_INT A)))
+ ...
+ (set (REGX) (plus (REGX) (CONST_INT B-A))) */
+ else if (GET_CODE (src) == REG
+ && reg_set_luid[regno] == reg_set_luid[REGNO (src)]
+ && reg_base_reg[regno] == reg_base_reg[REGNO (src)]
+ && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg),
+ reg_mode[REGNO (src)]))
+ {
+ rtx next = next_nonnote_insn (insn);
+ rtx set = NULL_RTX;
+ if (next)
+ set = single_set (next);
+ if (set
+ && SET_DEST (set) == reg
+ && GET_CODE (SET_SRC (set)) == PLUS
+ && XEXP (SET_SRC (set), 0) == reg
+ && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
+ {
+ rtx src3 = XEXP (SET_SRC (set), 1);
+ HOST_WIDE_INT added_offset = INTVAL (src3);
+ HOST_WIDE_INT base_offset = reg_offset[REGNO (src)];
+ HOST_WIDE_INT regno_offset = reg_offset[regno];
+ rtx new_src =
+ GEN_INT (trunc_int_for_mode (added_offset
+ + base_offset
+ - regno_offset,
+ GET_MODE (reg)));
+ int success = 0;
+
+ if (new_src == const0_rtx)
+ /* See above why we create (set (reg) (reg)) here. */
+ success
+ = validate_change (next, &SET_SRC (set), reg, 0);
+ else if ((rtx_cost (new_src, PLUS)
+ < COSTS_N_INSNS (1) + rtx_cost (src3, SET))
+ && have_add2_insn (reg, new_src))
+ {
+ rtx newpat = gen_rtx_SET (VOIDmode,
+ reg,
+ gen_rtx_PLUS (GET_MODE (reg),
+ reg,
+ new_src));
+ success
+ = validate_change (next, &PATTERN (next),
+ newpat, 0);
+ }
+ if (success)
+ delete_insn (insn);
+ insn = next;
+ reg_mode[regno] = GET_MODE (reg);
+ reg_offset[regno] =
+ trunc_int_for_mode (added_offset + base_offset,
+ GET_MODE (reg));
+ continue;
+ }
+ }
+ }
+ }
+
+ for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+ {
+ if (REG_NOTE_KIND (note) == REG_INC
+ && GET_CODE (XEXP (note, 0)) == REG)
+ {
+ /* Reset the information about this register. */
+ int regno = REGNO (XEXP (note, 0));
+ if (regno < FIRST_PSEUDO_REGISTER)
+ reg_set_luid[regno] = 0;
+ }
+ }
+ note_stores (PATTERN (insn), move2add_note_store, NULL);
+
+ /* If INSN is a conditional branch, we try to extract an
+ implicit set out of it. */
+ if (any_condjump_p (insn) && onlyjump_p (insn))
+ {
+ rtx cnd = fis_get_condition (insn);
+
+ if (cnd != NULL_RTX
+ && GET_CODE (cnd) == NE
+ && GET_CODE (XEXP (cnd, 0)) == REG
+ /* The following two checks, which are also in
+ move2add_note_store, are intended to reduce the
+ number of calls to gen_rtx_SET to avoid memory
+ allocation if possible. */
+ && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0)))
+ && HARD_REGNO_NREGS (REGNO (XEXP (cnd, 0)), GET_MODE (XEXP (cnd, 0))) == 1
+ && GET_CODE (XEXP (cnd, 1)) == CONST_INT)
+ {
+ rtx implicit_set =
+ gen_rtx_SET (VOIDmode, XEXP (cnd, 0), XEXP (cnd, 1));
+ move2add_note_store (SET_DEST (implicit_set), implicit_set, 0);
+ }
+ }
+
+ /* If this is a CALL_INSN, all call used registers are stored with
+ unknown values. */
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
+ {
+ if (call_used_regs[i])
+ /* Reset the information about this register. */
+ reg_set_luid[i] = 0;
+ }
+ }
+ }
+}
+
+/* SET is a SET or CLOBBER that sets DST.
+ Update reg_set_luid, reg_offset and reg_base_reg accordingly.
+ Called from reload_cse_move2add via note_stores. */
+
+static void
+move2add_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED)
+{
+ unsigned int regno = 0;
+ unsigned int i;
+ enum machine_mode mode = GET_MODE (dst);
+
+ if (GET_CODE (dst) == SUBREG)
+ {
+ regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
+ GET_MODE (SUBREG_REG (dst)),
+ SUBREG_BYTE (dst),
+ GET_MODE (dst));
+ dst = SUBREG_REG (dst);
+ }
+
+ /* Some targets do argument pushes without adding REG_INC notes. */
+
+ if (GET_CODE (dst) == MEM)
+ {
+ dst = XEXP (dst, 0);
+ if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
+ || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC)
+ reg_set_luid[REGNO (XEXP (dst, 0))] = 0;
+ return;
+ }
+ if (GET_CODE (dst) != REG)
+ return;
+
+ regno += REGNO (dst);
+
+ if (SCALAR_INT_MODE_P (mode)
+ && HARD_REGNO_NREGS (regno, mode) == 1 && GET_CODE (set) == SET
+ && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
+ && GET_CODE (SET_DEST (set)) != SIGN_EXTRACT
+ && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
+ {
+ rtx src = SET_SRC (set);
+ rtx base_reg;
+ HOST_WIDE_INT offset;
+ int base_regno;
+ /* This may be different from mode, if SET_DEST (set) is a
+ SUBREG. */
+ enum machine_mode dst_mode = GET_MODE (dst);
+
+ switch (GET_CODE (src))
+ {
+ case PLUS:
+ if (GET_CODE (XEXP (src, 0)) == REG)
+ {
+ base_reg = XEXP (src, 0);
+
+ if (GET_CODE (XEXP (src, 1)) == CONST_INT)
+ offset = INTVAL (XEXP (src, 1));
+ else if (GET_CODE (XEXP (src, 1)) == REG
+ && (reg_set_luid[REGNO (XEXP (src, 1))]
+ > move2add_last_label_luid)
+ && (MODES_OK_FOR_MOVE2ADD
+ (dst_mode, reg_mode[REGNO (XEXP (src, 1))])))
+ {
+ if (reg_base_reg[REGNO (XEXP (src, 1))] < 0)
+ offset = reg_offset[REGNO (XEXP (src, 1))];
+ /* Maybe the first register is known to be a
+ constant. */
+ else if (reg_set_luid[REGNO (base_reg)]
+ > move2add_last_label_luid
+ && (MODES_OK_FOR_MOVE2ADD
+ (dst_mode, reg_mode[REGNO (XEXP (src, 1))]))
+ && reg_base_reg[REGNO (base_reg)] < 0)
+ {
+ offset = reg_offset[REGNO (base_reg)];
+ base_reg = XEXP (src, 1);
+ }
+ else
+ goto invalidate;
+ }
+ else
+ goto invalidate;
+
+ break;
+ }
+
+ goto invalidate;
+
+ case REG:
+ base_reg = src;
+ offset = 0;
+ break;
+
+ case CONST_INT:
+ /* Start tracking the register as a constant. */
+ reg_base_reg[regno] = -1;
+ reg_offset[regno] = INTVAL (SET_SRC (set));
+ /* We assign the same luid to all registers set to constants. */
+ reg_set_luid[regno] = move2add_last_label_luid + 1;
+ reg_mode[regno] = mode;
+ return;
+
+ default:
+ invalidate:
+ /* Invalidate the contents of the register. */
+ reg_set_luid[regno] = 0;
+ return;
+ }
+
+ base_regno = REGNO (base_reg);
+ /* If information about the base register is not valid, set it
+ up as a new base register, pretending its value is known
+ starting from the current insn. */
+ if (reg_set_luid[base_regno] <= move2add_last_label_luid)
+ {
+ reg_base_reg[base_regno] = base_regno;
+ reg_offset[base_regno] = 0;
+ reg_set_luid[base_regno] = move2add_luid;
+ reg_mode[base_regno] = mode;
+ }
+ else if (! MODES_OK_FOR_MOVE2ADD (dst_mode,
+ reg_mode[base_regno]))
+ goto invalidate;
+
+ reg_mode[regno] = mode;
+
+ /* Copy base information from our base register. */
+ reg_set_luid[regno] = reg_set_luid[base_regno];
+ reg_base_reg[regno] = reg_base_reg[base_regno];
+
+ /* Compute the sum of the offsets or constants. */
+ reg_offset[regno] = trunc_int_for_mode (offset
+ + reg_offset[base_regno],
+ dst_mode);
+ }
+ else
+ {
+ unsigned int endregno = regno + HARD_REGNO_NREGS (regno, mode);
+
+ for (i = regno; i < endregno; i++)
+ /* Reset the information about this register. */
+ reg_set_luid[i] = 0;
+ }
+}
diff --git a/contrib/gcc/predict.c b/contrib/gcc/predict.c
index 3ad11e78536f..f2b4068df1ac 100644
--- a/contrib/gcc/predict.c
+++ b/contrib/gcc/predict.c
@@ -1,5 +1,5 @@
/* Branch prediction routines for the GNU compiler.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -30,6 +30,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
@@ -45,16 +47,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "recog.h"
#include "expr.h"
#include "predict.h"
-#include "profile.h"
-#include "real.h"
+#include "coverage.h"
+#include "sreal.h"
#include "params.h"
#include "target.h"
#include "loop.h"
+#include "cfgloop.h"
/* real constants: 0, 1, 1-1/REG_BR_PROB_BASE, REG_BR_PROB_BASE,
1/REG_BR_PROB_BASE, 0.5, BB_FREQ_MAX. */
-static REAL_VALUE_TYPE real_zero, real_one, real_almost_one, real_br_prob_base,
- real_inv_br_prob_base, real_one_half, real_bb_freq_max;
+static sreal real_zero, real_one, real_almost_one, real_br_prob_base,
+ real_inv_br_prob_base, real_one_half, real_bb_freq_max;
/* Random guesstimation given names. */
#define PROB_VERY_UNLIKELY (REG_BR_PROB_BASE / 10 - 1)
@@ -62,25 +65,19 @@ static REAL_VALUE_TYPE real_zero, real_one, real_almost_one, real_br_prob_base,
#define PROB_VERY_LIKELY (REG_BR_PROB_BASE - PROB_VERY_UNLIKELY)
#define PROB_ALWAYS (REG_BR_PROB_BASE)
-static bool predicted_by_p PARAMS ((basic_block,
- enum br_predictor));
-static void combine_predictions_for_insn PARAMS ((rtx, basic_block));
-static void dump_prediction PARAMS ((enum br_predictor, int,
- basic_block, int));
-static void estimate_loops_at_level PARAMS ((struct loop *loop));
-static void propagate_freq PARAMS ((struct loop *));
-static void estimate_bb_frequencies PARAMS ((struct loops *));
-static void counts_to_freqs PARAMS ((void));
-static void process_note_predictions PARAMS ((basic_block, int *,
- dominance_info,
- dominance_info));
-static void process_note_prediction PARAMS ((basic_block, int *,
- dominance_info,
- dominance_info, int, int));
-static bool last_basic_block_p PARAMS ((basic_block));
-static void compute_function_frequency PARAMS ((void));
-static void choose_function_section PARAMS ((void));
-static bool can_predict_insn_p PARAMS ((rtx));
+static bool predicted_by_p (basic_block, enum br_predictor);
+static void combine_predictions_for_insn (rtx, basic_block);
+static void dump_prediction (enum br_predictor, int, basic_block, int);
+static void estimate_loops_at_level (struct loop *loop);
+static void propagate_freq (struct loop *);
+static void estimate_bb_frequencies (struct loops *);
+static void counts_to_freqs (void);
+static void process_note_predictions (basic_block, int *);
+static void process_note_prediction (basic_block, int *, int, int);
+static bool last_basic_block_p (basic_block);
+static void compute_function_frequency (void);
+static void choose_function_section (void);
+static bool can_predict_insn_p (rtx);
/* Information we hold about each branch predictor.
Filled using information from predict.def. */
@@ -111,17 +108,14 @@ static const struct predictor_info predictor_info[]= {
#undef DEF_PREDICTOR
/* Return true in case BB can be CPU intensive and should be optimized
- for maximal perofmrance. */
+ for maximal performance. */
bool
-maybe_hot_bb_p (bb)
- basic_block bb;
+maybe_hot_bb_p (basic_block bb)
{
- if (profile_info.count_profiles_merged
- && flag_branch_probabilities
+ if (profile_info && flag_branch_probabilities
&& (bb->count
- < profile_info.max_counter_in_program
- / PARAM_VALUE (HOT_BB_COUNT_FRACTION)))
+ < profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION)))
return false;
if (bb->frequency < BB_FREQ_MAX / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION))
return false;
@@ -131,14 +125,11 @@ maybe_hot_bb_p (bb)
/* Return true in case BB is cold and should be optimized for size. */
bool
-probably_cold_bb_p (bb)
- basic_block bb;
+probably_cold_bb_p (basic_block bb)
{
- if (profile_info.count_profiles_merged
- && flag_branch_probabilities
+ if (profile_info && flag_branch_probabilities
&& (bb->count
- < profile_info.max_counter_in_program
- / PARAM_VALUE (HOT_BB_COUNT_FRACTION)))
+ < profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION)))
return true;
if (bb->frequency < BB_FREQ_MAX / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION))
return true;
@@ -147,13 +138,10 @@ probably_cold_bb_p (bb)
/* Return true in case BB is probably never executed. */
bool
-probably_never_executed_bb_p (bb)
- basic_block bb;
+probably_never_executed_bb_p (basic_block bb)
{
- if (profile_info.count_profiles_merged
- && flag_branch_probabilities)
- return ((bb->count + profile_info.count_profiles_merged / 2)
- / profile_info.count_profiles_merged) == 0;
+ if (profile_info && flag_branch_probabilities)
+ return ((bb->count + profile_info->runs / 2) / profile_info->runs) == 0;
return false;
}
@@ -161,14 +149,12 @@ probably_never_executed_bb_p (bb)
PREDICTOR. */
static bool
-predicted_by_p (bb, predictor)
- basic_block bb;
- enum br_predictor predictor;
+predicted_by_p (basic_block bb, enum br_predictor predictor)
{
rtx note;
- if (!INSN_P (bb->end))
+ if (!INSN_P (BB_END (bb)))
return false;
- for (note = REG_NOTES (bb->end); note; note = XEXP (note, 1))
+ for (note = REG_NOTES (BB_END (bb)); note; note = XEXP (note, 1))
if (REG_NOTE_KIND (note) == REG_BR_PRED
&& INTVAL (XEXP (XEXP (note, 0), 0)) == (int)predictor)
return true;
@@ -176,10 +162,7 @@ predicted_by_p (bb, predictor)
}
void
-predict_insn (insn, predictor, probability)
- rtx insn;
- int probability;
- enum br_predictor predictor;
+predict_insn (rtx insn, enum br_predictor predictor, int probability)
{
if (!any_condjump_p (insn))
abort ();
@@ -197,10 +180,8 @@ predict_insn (insn, predictor, probability)
/* Predict insn by given predictor. */
void
-predict_insn_def (insn, predictor, taken)
- rtx insn;
- enum br_predictor predictor;
- enum prediction taken;
+predict_insn_def (rtx insn, enum br_predictor predictor,
+ enum prediction taken)
{
int probability = predictor_info[(int) predictor].hitrate;
@@ -213,13 +194,10 @@ predict_insn_def (insn, predictor, taken)
/* Predict edge E with given probability if possible. */
void
-predict_edge (e, predictor, probability)
- edge e;
- int probability;
- enum br_predictor predictor;
+predict_edge (edge e, enum br_predictor predictor, int probability)
{
rtx last_insn;
- last_insn = e->src->end;
+ last_insn = BB_END (e->src);
/* We can store the branch prediction information only about
conditional jumps. */
@@ -237,8 +215,7 @@ predict_edge (e, predictor, probability)
At the moment we represent predictions only on conditional
jumps, not at computed jump or other complicated cases. */
static bool
-can_predict_insn_p (insn)
- rtx insn;
+can_predict_insn_p (rtx insn)
{
return (GET_CODE (insn) == JUMP_INSN
&& any_condjump_p (insn)
@@ -248,10 +225,8 @@ can_predict_insn_p (insn)
/* Predict edge E by given predictor if possible. */
void
-predict_edge_def (e, predictor, taken)
- edge e;
- enum br_predictor predictor;
- enum prediction taken;
+predict_edge_def (edge e, enum br_predictor predictor,
+ enum prediction taken)
{
int probability = predictor_info[(int) predictor].hitrate;
@@ -265,8 +240,7 @@ predict_edge_def (e, predictor, taken)
to be done each time we invert the condition used by the jump. */
void
-invert_br_probabilities (insn)
- rtx insn;
+invert_br_probabilities (rtx insn)
{
rtx note;
@@ -281,11 +255,8 @@ invert_br_probabilities (insn)
/* Dump information about the branch prediction to the output file. */
static void
-dump_prediction (predictor, probability, bb, used)
- enum br_predictor predictor;
- int probability;
- basic_block bb;
- int used;
+dump_prediction (enum br_predictor predictor, int probability,
+ basic_block bb, int used)
{
edge e = bb->succ;
@@ -318,9 +289,7 @@ dump_prediction (predictor, probability, bb, used)
note if not already present. Remove now useless REG_BR_PRED notes. */
static void
-combine_predictions_for_insn (insn, bb)
- rtx insn;
- basic_block bb;
+combine_predictions_for_insn (rtx insn, basic_block bb)
{
rtx prob_note = find_reg_note (insn, REG_BR_PROB, 0);
rtx *pnote = &REG_NOTES (insn);
@@ -420,29 +389,46 @@ combine_predictions_for_insn (insn, bb)
predictions). */
void
-estimate_probability (loops_info)
- struct loops *loops_info;
+estimate_probability (struct loops *loops_info)
{
- dominance_info dominators, post_dominators;
basic_block bb;
- int i;
+ unsigned i;
connect_infinite_loops_to_exit ();
- dominators = calculate_dominance_info (CDI_DOMINATORS);
- post_dominators = calculate_dominance_info (CDI_POST_DOMINATORS);
+ calculate_dominance_info (CDI_DOMINATORS);
+ calculate_dominance_info (CDI_POST_DOMINATORS);
/* Try to predict out blocks in a loop that are not part of a
natural loop. */
for (i = 1; i < loops_info->num; i++)
{
basic_block bb, *bbs;
- int j;
+ unsigned j;
int exits;
struct loop *loop = loops_info->parray[i];
+ struct loop_desc desc;
+ unsigned HOST_WIDE_INT niter;
- flow_loop_scan (loops_info, loop, LOOP_EXIT_EDGES);
+ flow_loop_scan (loop, LOOP_EXIT_EDGES);
exits = loop->num_exits;
+ if (simple_loop_p (loop, &desc) && desc.const_iter)
+ {
+ int prob;
+ niter = desc.niter + 1;
+ if (niter == 0) /* We might overflow here. */
+ niter = desc.niter;
+
+ prob = (REG_BR_PROB_BASE
+ - (REG_BR_PROB_BASE + niter /2) / niter);
+ /* Branch prediction algorithm gives 0 frequency for everything
+ after the end of loop for loop having 0 probability to finish. */
+ if (prob == REG_BR_PROB_BASE)
+ prob = REG_BR_PROB_BASE - 1;
+ predict_edge (desc.in_edge, PRED_LOOP_ITERATIONS,
+ prob);
+ }
+
bbs = get_loop_body (loop);
for (j = 0; j < loop->num_nodes; j++)
{
@@ -455,7 +441,7 @@ estimate_probability (loops_info)
statements construct loops via "non-loop" constructs
in the source language and are better to be handled
separately. */
- if (!can_predict_insn_p (bb->end)
+ if (!can_predict_insn_p (BB_END (bb))
|| predicted_by_p (bb, PRED_CONTINUE))
continue;
@@ -470,7 +456,7 @@ estimate_probability (loops_info)
}
/* Loop exit heuristics - predict an edge exiting the loop if the
- conditinal has no loop header successors as not taken. */
+ conditional has no loop header successors as not taken. */
if (!header_found)
for (e = bb->succ; e; e = e->succ_next)
if (e->dest->index < 0
@@ -481,12 +467,15 @@ estimate_probability (loops_info)
- predictor_info [(int) PRED_LOOP_EXIT].hitrate)
/ exits);
}
+
+ /* Free basic blocks from get_loop_body. */
+ free (bbs);
}
/* Attempt to predict conditional jumps using a number of heuristics. */
FOR_EACH_BB (bb)
{
- rtx last_insn = bb->end;
+ rtx last_insn = BB_END (bb);
rtx cond, earliest;
edge e;
@@ -510,8 +499,8 @@ estimate_probability (loops_info)
/* Look for block we are guarding (ie we dominate it,
but it doesn't postdominate us). */
if (e->dest != EXIT_BLOCK_PTR && e->dest != bb
- && dominated_by_p (dominators, e->dest, e->src)
- && !dominated_by_p (post_dominators, e->src, e->dest))
+ && dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
+ && !dominated_by_p (CDI_POST_DOMINATORS, e->src, e->dest))
{
rtx insn;
@@ -519,7 +508,7 @@ estimate_probability (loops_info)
is improbable. This is because such calls are often used
to signal exceptional situations such as printing error
messages. */
- for (insn = e->dest->head; insn != NEXT_INSN (e->dest->end);
+ for (insn = BB_HEAD (e->dest); insn != NEXT_INSN (BB_END (e->dest));
insn = NEXT_INSN (insn))
if (GET_CODE (insn) == CALL_INSN
/* Constant and pure calls are hardly used to signalize
@@ -532,7 +521,7 @@ estimate_probability (loops_info)
}
}
- cond = get_condition (last_insn, &earliest);
+ cond = get_condition (last_insn, &earliest, false);
if (! cond)
continue;
@@ -565,12 +554,12 @@ estimate_probability (loops_info)
case EQ:
case UNEQ:
/* Floating point comparisons appears to behave in a very
- inpredictable way because of special role of = tests in
+ unpredictable way because of special role of = tests in
FP code. */
if (FLOAT_MODE_P (GET_MODE (XEXP (cond, 0))))
;
/* Comparisons with 0 are often used for booleans and there is
- nothing usefull to predict about them. */
+ nothing useful to predict about them. */
else if (XEXP (cond, 1) == const0_rtx
|| XEXP (cond, 0) == const0_rtx)
;
@@ -581,12 +570,12 @@ estimate_probability (loops_info)
case NE:
case LTGT:
/* Floating point comparisons appears to behave in a very
- inpredictable way because of special role of = tests in
+ unpredictable way because of special role of = tests in
FP code. */
if (FLOAT_MODE_P (GET_MODE (XEXP (cond, 0))))
;
/* Comparisons with 0 are often used for booleans and there is
- nothing usefull to predict about them. */
+ nothing useful to predict about them. */
else if (XEXP (cond, 1) == const0_rtx
|| XEXP (cond, 0) == const0_rtx)
;
@@ -623,13 +612,12 @@ estimate_probability (loops_info)
/* Attach the combined probability to each conditional jump. */
FOR_EACH_BB (bb)
- if (GET_CODE (bb->end) == JUMP_INSN
- && any_condjump_p (bb->end)
+ if (GET_CODE (BB_END (bb)) == JUMP_INSN
+ && any_condjump_p (BB_END (bb))
&& bb->succ->succ_next != NULL)
- combine_predictions_for_insn (bb->end, bb);
+ combine_predictions_for_insn (BB_END (bb), bb);
- free_dominance_info (post_dominators);
- free_dominance_info (dominators);
+ free_dominance_info (CDI_POST_DOMINATORS);
remove_fake_edges ();
estimate_bb_frequencies (loops_info);
@@ -640,7 +628,7 @@ estimate_probability (loops_info)
values. */
void
-expected_value_to_br_prob ()
+expected_value_to_br_prob (void)
{
rtx insn, cond, ev = NULL_RTX, ev_reg = NULL_RTX;
@@ -688,7 +676,7 @@ expected_value_to_br_prob ()
(lt r70, r71)
Could use cselib to try and reduce this further. */
cond = XEXP (SET_SRC (pc_set (insn)), 0);
- cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg);
+ cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg, false);
if (! cond || XEXP (cond, 0) != ev_reg
|| GET_CODE (XEXP (cond, 1)) != CONST_INT)
continue;
@@ -708,11 +696,10 @@ expected_value_to_br_prob ()
}
}
-/* Check whether this is the last basic block of function. Commonly tehre
- is one extra common cleanup block. */
+/* Check whether this is the last basic block of function. Commonly
+ there is one extra common cleanup block. */
static bool
-last_basic_block_p (bb)
- basic_block bb;
+last_basic_block_p (basic_block bb)
{
if (bb == EXIT_BLOCK_PTR)
return false;
@@ -723,20 +710,14 @@ last_basic_block_p (bb)
&& bb->succ->dest->next_bb == EXIT_BLOCK_PTR));
}
-/* Sets branch probabilities according to PREDiction and FLAGS. HEADS[bb->index]
- should be index of basic block in that we need to alter branch predictions
- (i.e. the first of our dominators such that we do not post-dominate it)
- (but we fill this information on demand, so -1 may be there in case this
- was not needed yet). */
+/* Sets branch probabilities according to PREDiction and
+ FLAGS. HEADS[bb->index] should be index of basic block in that we
+ need to alter branch predictions (i.e. the first of our dominators
+ such that we do not post-dominate it) (but we fill this information
+ on demand, so -1 may be there in case this was not needed yet). */
static void
-process_note_prediction (bb, heads, dominators, post_dominators, pred, flags)
- basic_block bb;
- int *heads;
- dominance_info dominators;
- dominance_info post_dominators;
- int pred;
- int flags;
+process_note_prediction (basic_block bb, int *heads, int pred, int flags)
{
edge e;
int y;
@@ -750,18 +731,18 @@ process_note_prediction (bb, heads, dominators, post_dominators, pred, flags)
find first dominator that we do not post-dominate (we are
using already known members of heads array). */
basic_block ai = bb;
- basic_block next_ai = get_immediate_dominator (dominators, bb);
+ basic_block next_ai = get_immediate_dominator (CDI_DOMINATORS, bb);
int head;
while (heads[next_ai->index] < 0)
{
- if (!dominated_by_p (post_dominators, next_ai, bb))
+ if (!dominated_by_p (CDI_POST_DOMINATORS, next_ai, bb))
break;
heads[next_ai->index] = ai->index;
ai = next_ai;
- next_ai = get_immediate_dominator (dominators, next_ai);
+ next_ai = get_immediate_dominator (CDI_DOMINATORS, next_ai);
}
- if (!dominated_by_p (post_dominators, next_ai, bb))
+ if (!dominated_by_p (CDI_POST_DOMINATORS, next_ai, bb))
head = next_ai->index;
else
head = heads[next_ai->index];
@@ -779,11 +760,11 @@ process_note_prediction (bb, heads, dominators, post_dominators, pred, flags)
/* Now find the edge that leads to our branch and aply the prediction. */
- if (y == last_basic_block || !can_predict_insn_p (BASIC_BLOCK (y)->end))
+ if (y == last_basic_block || !can_predict_insn_p (BB_END (BASIC_BLOCK (y))))
return;
for (e = BASIC_BLOCK (y)->succ; e; e = e->succ_next)
if (e->dest->index >= 0
- && dominated_by_p (post_dominators, e->dest, bb))
+ && dominated_by_p (CDI_POST_DOMINATORS, e->dest, bb))
predict_edge_def (e, pred, taken);
}
@@ -792,22 +773,18 @@ process_note_prediction (bb, heads, dominators, post_dominators, pred, flags)
process_note_prediction. */
static void
-process_note_predictions (bb, heads, dominators, post_dominators)
- basic_block bb;
- int *heads;
- dominance_info dominators;
- dominance_info post_dominators;
+process_note_predictions (basic_block bb, int *heads)
{
rtx insn;
edge e;
- /* Additionaly, we check here for blocks with no successors. */
+ /* Additionally, we check here for blocks with no successors. */
int contained_noreturn_call = 0;
int was_bb_head = 0;
int noreturn_block = 1;
- for (insn = bb->end; insn;
- was_bb_head |= (insn == bb->head), insn = PREV_INSN (insn))
+ for (insn = BB_END (bb); insn;
+ was_bb_head |= (insn == BB_HEAD (bb)), insn = PREV_INSN (insn))
{
if (GET_CODE (insn) != NOTE)
{
@@ -829,8 +806,6 @@ process_note_predictions (bb, heads, dominators, post_dominators)
/* Process single prediction note. */
process_note_prediction (bb,
heads,
- dominators,
- post_dominators,
alg, (int) NOTE_PREDICTION_FLAGS (insn));
delete_insn (insn);
}
@@ -843,10 +818,7 @@ process_note_predictions (bb, heads, dominators, post_dominators)
/* This block ended from other reasons than because of return.
If it is because of noreturn call, this should certainly not
be taken. Otherwise it is probably some error recovery. */
- process_note_prediction (bb,
- heads,
- dominators,
- post_dominators, PRED_NORETURN, NOT_TAKEN);
+ process_note_prediction (bb, heads, PRED_NORETURN, NOT_TAKEN);
}
}
@@ -854,18 +826,17 @@ process_note_predictions (bb, heads, dominators, post_dominators)
branch probabilities. */
void
-note_prediction_to_br_prob ()
+note_prediction_to_br_prob (void)
{
basic_block bb;
- dominance_info post_dominators, dominators;
int *heads;
/* To enable handling of noreturn blocks. */
add_noreturn_fake_exit_edges ();
connect_infinite_loops_to_exit ();
- post_dominators = calculate_dominance_info (CDI_POST_DOMINATORS);
- dominators = calculate_dominance_info (CDI_DOMINATORS);
+ calculate_dominance_info (CDI_POST_DOMINATORS);
+ calculate_dominance_info (CDI_DOMINATORS);
heads = xmalloc (sizeof (int) * last_basic_block);
memset (heads, -1, sizeof (int) * last_basic_block);
@@ -874,10 +845,10 @@ note_prediction_to_br_prob ()
/* Process all prediction notes. */
FOR_EACH_BB (bb)
- process_note_predictions (bb, heads, dominators, post_dominators);
+ process_note_predictions (bb, heads);
- free_dominance_info (post_dominators);
- free_dominance_info (dominators);
+ free_dominance_info (CDI_POST_DOMINATORS);
+ free_dominance_info (CDI_DOMINATORS);
free (heads);
remove_fake_edges ();
@@ -889,13 +860,13 @@ note_prediction_to_br_prob ()
typedef struct block_info_def
{
/* Estimated frequency of execution of basic_block. */
- REAL_VALUE_TYPE frequency;
+ sreal frequency;
/* To keep queue of basic blocks to process. */
basic_block next;
- /* True if block needs to be visited in prop_freqency. */
- int tovisit:1;
+ /* True if block needs to be visited in propagate_freq. */
+ unsigned int tovisit:1;
/* Number of predecessors we need to visit first. */
int npredecessors;
@@ -907,9 +878,9 @@ typedef struct edge_info_def
/* In case edge is an loopback edge, the probability edge will be reached
in case header is. Estimated number of iterations of the loop can be
then computed as 1 / (1 - back_edge_prob). */
- REAL_VALUE_TYPE back_edge_prob;
+ sreal back_edge_prob;
/* True if the edge is an loopback edge in the natural loop. */
- int back_edge:1;
+ unsigned int back_edge:1;
} *edge_info;
#define BLOCK_INFO(B) ((block_info) (B)->aux)
@@ -919,8 +890,7 @@ typedef struct edge_info_def
Propagate the frequencies for LOOP. */
static void
-propagate_freq (loop)
- struct loop *loop;
+propagate_freq (struct loop *loop)
{
basic_block head = loop->header;
basic_block bb;
@@ -952,7 +922,7 @@ propagate_freq (loop)
last = head;
for (bb = head; bb; bb = nextbb)
{
- REAL_VALUE_TYPE cyclic_probability, frequency;
+ sreal cyclic_probability, frequency;
memcpy (&cyclic_probability, &real_zero, sizeof (real_zero));
memcpy (&frequency, &real_zero, sizeof (real_zero));
@@ -972,40 +942,42 @@ propagate_freq (loop)
for (e = bb->pred; e; e = e->pred_next)
if (EDGE_INFO (e)->back_edge)
{
- REAL_ARITHMETIC (cyclic_probability, PLUS_EXPR,
- cyclic_probability,
- EDGE_INFO (e)->back_edge_prob);
+ sreal_add (&cyclic_probability, &cyclic_probability,
+ &EDGE_INFO (e)->back_edge_prob);
}
else if (!(e->flags & EDGE_DFS_BACK))
{
- REAL_VALUE_TYPE tmp;
+ sreal tmp;
/* frequency += (e->probability
* BLOCK_INFO (e->src)->frequency /
REG_BR_PROB_BASE); */
- REAL_VALUE_FROM_INT (tmp, e->probability, 0,
- TYPE_MODE (double_type_node));
- REAL_ARITHMETIC (tmp, MULT_EXPR, tmp,
- BLOCK_INFO (e->src)->frequency);
- REAL_ARITHMETIC (tmp, MULT_EXPR, tmp, real_inv_br_prob_base);
- REAL_ARITHMETIC (frequency, PLUS_EXPR, frequency, tmp);
+ sreal_init (&tmp, e->probability, 0);
+ sreal_mul (&tmp, &tmp, &BLOCK_INFO (e->src)->frequency);
+ sreal_mul (&tmp, &tmp, &real_inv_br_prob_base);
+ sreal_add (&frequency, &frequency, &tmp);
}
- if (REAL_VALUES_IDENTICAL (cyclic_probability, real_zero))
- memcpy (&BLOCK_INFO (bb)->frequency, &frequency, sizeof (frequency));
+ if (sreal_compare (&cyclic_probability, &real_zero) == 0)
+ {
+ memcpy (&BLOCK_INFO (bb)->frequency, &frequency,
+ sizeof (frequency));
+ }
else
{
- if (REAL_VALUES_LESS (real_almost_one, cyclic_probability))
- memcpy (&cyclic_probability, &real_almost_one, sizeof (real_zero));
+ if (sreal_compare (&cyclic_probability, &real_almost_one) > 0)
+ {
+ memcpy (&cyclic_probability, &real_almost_one,
+ sizeof (real_almost_one));
+ }
- /* BLOCK_INFO (bb)->frequency = frequency / (1 - cyclic_probability)
- */
+ /* BLOCK_INFO (bb)->frequency = frequency
+ / (1 - cyclic_probability) */
- REAL_ARITHMETIC (cyclic_probability, MINUS_EXPR, real_one,
- cyclic_probability);
- REAL_ARITHMETIC (BLOCK_INFO (bb)->frequency,
- RDIV_EXPR, frequency, cyclic_probability);
+ sreal_sub (&cyclic_probability, &real_one, &cyclic_probability);
+ sreal_div (&BLOCK_INFO (bb)->frequency,
+ &frequency, &cyclic_probability);
}
}
@@ -1015,18 +987,16 @@ propagate_freq (loop)
for (e = bb->succ; e; e = e->succ_next)
if (e->dest == head)
{
- REAL_VALUE_TYPE tmp;
+ sreal tmp;
/* EDGE_INFO (e)->back_edge_prob
= ((e->probability * BLOCK_INFO (bb)->frequency)
/ REG_BR_PROB_BASE); */
- REAL_VALUE_FROM_INT (tmp, e->probability, 0,
- TYPE_MODE (double_type_node));
- REAL_ARITHMETIC (tmp, MULT_EXPR, tmp,
- BLOCK_INFO (bb)->frequency);
- REAL_ARITHMETIC (EDGE_INFO (e)->back_edge_prob,
- MULT_EXPR, tmp, real_inv_br_prob_base);
+ sreal_init (&tmp, e->probability, 0);
+ sreal_mul (&tmp, &tmp, &BLOCK_INFO (bb)->frequency);
+ sreal_mul (&EDGE_INFO (e)->back_edge_prob,
+ &tmp, &real_inv_br_prob_base);
}
/* Propagate to successor blocks. */
@@ -1051,8 +1021,7 @@ propagate_freq (loop)
/* Estimate probabilities of loopback edges in loops at same nest level. */
static void
-estimate_loops_at_level (first_loop)
- struct loop *first_loop;
+estimate_loops_at_level (struct loop *first_loop)
{
struct loop *loop;
@@ -1060,10 +1029,10 @@ estimate_loops_at_level (first_loop)
{
edge e;
basic_block *bbs;
- int i;
+ unsigned i;
estimate_loops_at_level (loop->inner);
-
+
if (loop->latch->succ) /* Do not do this for dummy function loop. */
{
/* Find current loop back edge and mark it. */
@@ -1082,9 +1051,9 @@ estimate_loops_at_level (first_loop)
/* Convert counts measured by profile driven feedback to frequencies. */
static void
-counts_to_freqs ()
+counts_to_freqs (void)
{
- HOST_WIDEST_INT count_max = 1;
+ gcov_type count_max = 1;
basic_block bb;
FOR_EACH_BB (bb)
@@ -1096,12 +1065,11 @@ counts_to_freqs ()
/* Return true if function is likely to be expensive, so there is no point to
optimize performance of prologue, epilogue or do inlining at the expense
- of code size growth. THRESHOLD is the limit of number of isntructions
+ of code size growth. THRESHOLD is the limit of number of instructions
function can execute at average to be still considered not expensive. */
bool
-expensive_function_p (threshold)
- int threshold;
+expensive_function_p (int threshold)
{
unsigned int sum = 0;
basic_block bb;
@@ -1124,7 +1092,7 @@ expensive_function_p (threshold)
{
rtx insn;
- for (insn = bb->head; insn != NEXT_INSN (bb->end);
+ for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
if (active_insn_p (insn))
{
@@ -1140,32 +1108,35 @@ expensive_function_p (threshold)
/* Estimate basic blocks frequency by given branch probabilities. */
static void
-estimate_bb_frequencies (loops)
- struct loops *loops;
+estimate_bb_frequencies (struct loops *loops)
{
basic_block bb;
- REAL_VALUE_TYPE freq_max;
- enum machine_mode double_mode = TYPE_MODE (double_type_node);
+ sreal freq_max;
if (flag_branch_probabilities)
counts_to_freqs ();
else
{
- REAL_VALUE_FROM_INT (real_zero, 0, 0, double_mode);
- REAL_VALUE_FROM_INT (real_one, 1, 0, double_mode);
- REAL_VALUE_FROM_INT (real_br_prob_base, REG_BR_PROB_BASE, 0, double_mode);
- REAL_VALUE_FROM_INT (real_bb_freq_max, BB_FREQ_MAX, 0, double_mode);
- REAL_VALUE_FROM_INT (real_one_half, 2, 0, double_mode);
- REAL_ARITHMETIC (real_one_half, RDIV_EXPR, real_one, real_one_half);
- REAL_ARITHMETIC (real_inv_br_prob_base, RDIV_EXPR, real_one, real_br_prob_base);
- REAL_ARITHMETIC (real_almost_one, MINUS_EXPR, real_one, real_inv_br_prob_base);
+ static int real_values_initialized = 0;
+
+ if (!real_values_initialized)
+ {
+ real_values_initialized = 1;
+ sreal_init (&real_zero, 0, 0);
+ sreal_init (&real_one, 1, 0);
+ sreal_init (&real_br_prob_base, REG_BR_PROB_BASE, 0);
+ sreal_init (&real_bb_freq_max, BB_FREQ_MAX, 0);
+ sreal_init (&real_one_half, 1, -1);
+ sreal_div (&real_inv_br_prob_base, &real_one, &real_br_prob_base);
+ sreal_sub (&real_almost_one, &real_one, &real_inv_br_prob_base);
+ }
mark_dfs_back_edges ();
/* Fill in the probability values in flowgraph based on the REG_BR_PROB
notes. */
FOR_EACH_BB (bb)
{
- rtx last_insn = bb->end;
+ rtx last_insn = BB_END (bb);
if (!can_predict_insn_p (last_insn))
{
@@ -1199,11 +1170,10 @@ estimate_bb_frequencies (loops)
BLOCK_INFO (bb)->tovisit = 0;
for (e = bb->succ; e; e = e->succ_next)
{
- REAL_VALUE_FROM_INT (EDGE_INFO (e)->back_edge_prob,
- e->probability, 0, double_mode);
- REAL_ARITHMETIC (EDGE_INFO (e)->back_edge_prob,
- MULT_EXPR, EDGE_INFO (e)->back_edge_prob,
- real_inv_br_prob_base);
+ sreal_init (&EDGE_INFO (e)->back_edge_prob, e->probability, 0);
+ sreal_mul (&EDGE_INFO (e)->back_edge_prob,
+ &EDGE_INFO (e)->back_edge_prob,
+ &real_inv_br_prob_base);
}
}
@@ -1213,21 +1183,17 @@ estimate_bb_frequencies (loops)
memcpy (&freq_max, &real_zero, sizeof (real_zero));
FOR_EACH_BB (bb)
- if (REAL_VALUES_LESS
- (freq_max, BLOCK_INFO (bb)->frequency))
- memcpy (&freq_max, &BLOCK_INFO (bb)->frequency,
- sizeof (freq_max));
-
- REAL_ARITHMETIC (freq_max, RDIV_EXPR, real_bb_freq_max, freq_max);
+ if (sreal_compare (&freq_max, &BLOCK_INFO (bb)->frequency) < 0)
+ memcpy (&freq_max, &BLOCK_INFO (bb)->frequency, sizeof (freq_max));
+ sreal_div (&freq_max, &real_bb_freq_max, &freq_max);
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
{
- REAL_VALUE_TYPE tmp;
+ sreal tmp;
- REAL_ARITHMETIC (tmp, MULT_EXPR, BLOCK_INFO (bb)->frequency,
- freq_max);
- REAL_ARITHMETIC (tmp, PLUS_EXPR, tmp, real_one_half);
- bb->frequency = REAL_VALUE_UNSIGNED_FIX (tmp);
+ sreal_mul (&tmp, &BLOCK_INFO (bb)->frequency, &freq_max);
+ sreal_add (&tmp, &tmp, &real_one_half);
+ bb->frequency = sreal_to_int (&tmp);
}
free_aux_for_blocks ();
@@ -1240,12 +1206,11 @@ estimate_bb_frequencies (loops)
/* Decide whether function is hot, cold or unlikely executed. */
static void
-compute_function_frequency ()
+compute_function_frequency (void)
{
basic_block bb;
- if (!profile_info.count_profiles_merged
- || !flag_branch_probabilities)
+ if (!profile_info || !flag_branch_probabilities)
return;
cfun->function_frequency = FUNCTION_FREQUENCY_UNLIKELY_EXECUTED;
FOR_EACH_BB (bb)
@@ -1262,12 +1227,12 @@ compute_function_frequency ()
/* Choose appropriate section for the function. */
static void
-choose_function_section ()
+choose_function_section (void)
{
if (DECL_SECTION_NAME (current_function_decl)
|| !targetm.have_named_sections
/* Theoretically we can split the gnu.linkonce text section too,
- but this requires more work as the frequency needs to match
+ but this requires more work as the frequency needs to match
for all generated objects so we need to merge the frequency
of all instances. For now just never set frequency for these. */
|| DECL_ONE_ONLY (current_function_decl))
diff --git a/contrib/gcc/predict.def b/contrib/gcc/predict.def
index 238e0f262fcb..25c51025e312 100644
--- a/contrib/gcc/predict.def
+++ b/contrib/gcc/predict.def
@@ -1,6 +1,5 @@
-/* This file contains the definitions and documentation for the
- builtins used in the GNU compiler.
- Copyright (C) 2001 Free Software Foundation, Inc.
+/* Definitions for the branch prediction routines in the GNU compiler.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/contrib/gcc/predict.h b/contrib/gcc/predict.h
index a936b5689461..d0741dc704dc 100644
--- a/contrib/gcc/predict.h
+++ b/contrib/gcc/predict.h
@@ -1,6 +1,5 @@
-/* This file contains the definitions and documentation for the
- builtins used in the GNU compiler.
- Copyright (C) 2001 Free Software Foundation, Inc.
+/* Definitions for branch prediction routines in the GNU compiler.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -37,13 +36,11 @@ enum prediction
/* Flags for NOTE_PREDICTION */
#define IS_TAKEN 1 /* Predict edges to the block as taken. */
-extern void predict_insn_def PARAMS ((rtx, enum br_predictor,
- enum prediction));
-extern void predict_insn PARAMS ((rtx, enum br_predictor, int));
+extern void predict_insn_def (rtx, enum br_predictor, enum prediction);
+extern void predict_insn (rtx, enum br_predictor, int);
-/* Avoid unneeded dependency on basic_block.h */
+/* Avoid unneeded dependency on basic_block.h. */
#ifdef BASIC_BLOCK
-extern void predict_edge PARAMS ((edge, enum br_predictor, int));
-extern void predict_edge_def PARAMS ((edge, enum br_predictor,
- enum prediction));
+extern void predict_edge (edge, enum br_predictor, int);
+extern void predict_edge_def (edge, enum br_predictor, enum prediction);
#endif
diff --git a/contrib/gcc/prefix.c b/contrib/gcc/prefix.c
index 06930fee2ab1..df556aaa30c0 100644
--- a/contrib/gcc/prefix.c
+++ b/contrib/gcc/prefix.c
@@ -1,5 +1,5 @@
/* Utility to update paths from internal to external forms.
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
This file is part of GCC.
@@ -67,6 +67,8 @@ Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
#include <windows.h>
#endif
@@ -74,21 +76,20 @@ Boston, MA 02111-1307, USA. */
static const char *std_prefix = PREFIX;
-static const char *get_key_value PARAMS ((char *));
-static char *translate_name PARAMS ((char *));
-static char *save_string PARAMS ((const char *, int));
-static void tr PARAMS ((char *, int, int));
+static const char *get_key_value (char *);
+static char *translate_name (char *);
+static char *save_string (const char *, int);
+static void tr (char *, int, int);
#if defined(_WIN32) && defined(ENABLE_WIN32_REGISTRY)
-static char *lookup_key PARAMS ((char *));
+static char *lookup_key (char *);
static HKEY reg_key = (HKEY) INVALID_HANDLE_VALUE;
#endif
/* Given KEY, as above, return its value. */
static const char *
-get_key_value (key)
- char *key;
+get_key_value (char *key)
{
const char *prefix = 0;
char *temp = 0;
@@ -112,9 +113,7 @@ get_key_value (key)
/* Return a copy of a string that has been placed in the heap. */
static char *
-save_string (s, len)
- const char *s;
- int len;
+save_string (const char *s, int len)
{
char *result = xmalloc (len + 1);
@@ -128,8 +127,7 @@ save_string (s, len)
/* Look up "key" in the registry, as above. */
static char *
-lookup_key (key)
- char *key;
+lookup_key (char *key)
{
char *dst;
DWORD size;
@@ -157,12 +155,12 @@ lookup_key (key)
}
size = 32;
- dst = (char *) xmalloc (size);
+ dst = xmalloc (size);
res = RegQueryValueExA (reg_key, key, 0, &type, dst, &size);
if (res == ERROR_MORE_DATA && type == REG_SZ)
{
- dst = (char *) xrealloc (dst, size);
+ dst = xrealloc (dst, size);
res = RegQueryValueExA (reg_key, key, 0, &type, dst, &size);
}
@@ -181,8 +179,7 @@ lookup_key (key)
Otherwise, return the given name. */
static char *
-translate_name (name)
- char *name;
+translate_name (char *name)
{
char code;
char *key, *old_name;
@@ -200,7 +197,7 @@ translate_name (name)
keylen++)
;
- key = (char *) alloca (keylen + 1);
+ key = alloca (keylen + 1);
strncpy (key, &name[1], keylen);
key[keylen] = 0;
@@ -231,9 +228,7 @@ translate_name (name)
/* In a NUL-terminated STRING, replace character C1 with C2 in-place. */
static void
-tr (string, c1, c2)
- char *string;
- int c1, c2;
+tr (char *string, int c1, int c2)
{
do
{
@@ -248,9 +243,7 @@ tr (string, c1, c2)
freeing it. */
char *
-update_path (path, key)
- const char *path;
- const char *key;
+update_path (const char *path, const char *key)
{
char *result, *p;
@@ -348,11 +341,9 @@ update_path (path, key)
return result;
}
-/* Reset the standard prefix */
+/* Reset the standard prefix. */
void
-set_std_prefix (prefix, len)
- const char *prefix;
- int len;
+set_std_prefix (const char *prefix, int len)
{
std_prefix = save_string (prefix, len);
}
diff --git a/contrib/gcc/prefix.h b/contrib/gcc/prefix.h
index ca8ee19dc3ec..25f2115962b8 100644
--- a/contrib/gcc/prefix.h
+++ b/contrib/gcc/prefix.h
@@ -1,5 +1,5 @@
/* Provide prototypes for functions exported from prefix.c.
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA. */
/* Update PATH using KEY if PATH starts with PREFIX. The returned
string is always malloc-ed, and the caller is responsible for
freeing it. */
-extern char *update_path PARAMS ((const char *path, const char *key));
-extern void set_std_prefix PARAMS ((const char *, int));
+extern char *update_path (const char *path, const char *key);
+extern void set_std_prefix (const char *, int);
#endif /* ! GCC_PREFIX_H */
diff --git a/contrib/gcc/pretty-print.c b/contrib/gcc/pretty-print.c
new file mode 100644
index 000000000000..993fde7a6d69
--- /dev/null
+++ b/contrib/gcc/pretty-print.c
@@ -0,0 +1,548 @@
+/* Various declarations for language-independent pretty-print subroutines.
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#undef FLOAT /* This is for hpux. They should change hpux. */
+#undef FFS /* Some systems define this in param.h. */
+#include "system.h"
+#include "coretypes.h"
+#include "pretty-print.h"
+
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+
+/* A pointer to the formatted diagnostic message. */
+#define pp_formatted_text_data(PP) \
+ ((const char *) obstack_base (&pp_base (PP)->buffer->obstack))
+
+/* Format an integer given by va_arg (ARG, type-specifier T) where
+ type-specifier is a precision modifier as indicated by PREC. F is
+ a string used to construct the appropriate format-specifier. */
+#define pp_integer_with_precision(PP, ARG, PREC, T, F) \
+ do \
+ switch (PREC) \
+ { \
+ case 0: \
+ pp_scalar (PP, "%" F, va_arg (ARG, T)); \
+ break; \
+ \
+ case 1: \
+ pp_scalar (PP, "%l" F, va_arg (ARG, long T)); \
+ break; \
+ \
+ case 2: \
+ pp_scalar (PP, "%ll" F, va_arg (ARG, long long T)); \
+ break; \
+ \
+ default: \
+ break; \
+ } \
+ while (0)
+
+
+/* Subroutine of pp_set_maximum_length. Set up PRETTY-PRINTER's
+ internal maximum characters per line. */
+static void
+pp_set_real_maximum_length (pretty_printer *pp)
+{
+ /* If we're told not to wrap lines then do the obvious thing. In case
+ we'll emit prefix only once per message, it is appropriate
+ not to increase unnecessarily the line-length cut-off. */
+ if (!pp_is_wrapping_line (pp)
+ || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_ONCE
+ || pp_prefixing_rule (pp) == DIAGNOSTICS_SHOW_PREFIX_NEVER)
+ pp->maximum_length = pp_line_cutoff (pp);
+ else
+ {
+ int prefix_length = pp->prefix ? strlen (pp->prefix) : 0;
+ /* If the prefix is ridiculously too long, output at least
+ 32 characters. */
+ if (pp_line_cutoff (pp) - prefix_length < 32)
+ pp->maximum_length = pp_line_cutoff (pp) + 32;
+ else
+ pp->maximum_length = pp_line_cutoff (pp);
+ }
+}
+
+/* Clear PRETTY-PRINTER's output state. */
+static inline void
+pp_clear_state (pretty_printer *pp)
+{
+ pp->emitted_prefix = false;
+ pp_indentation (pp) = 0;
+}
+
+/* Flush the formatted text of PRETTY-PRINTER onto the attached stream. */
+static inline void
+pp_write_text_to_stream (pretty_printer *pp)
+{
+ const char *text = pp_formatted_text (pp);
+ fputs (text, pp->buffer->stream);
+ pp_clear_output_area (pp);
+}
+
+/* Wrap a text delimited by START and END into PRETTY-PRINTER. */
+static void
+pp_wrap_text (pretty_printer *pp, const char *start, const char *end)
+{
+ bool wrapping_line = pp_is_wrapping_line (pp);
+
+ while (start != end)
+ {
+ /* Dump anything bordered by whitespaces. */
+ {
+ const char *p = start;
+ while (p != end && !ISBLANK (*p) && *p != '\n')
+ ++p;
+ if (wrapping_line
+ && p - start >= pp_remaining_character_count_for_line (pp))
+ pp_newline (pp);
+ pp_append_text (pp, start, p);
+ start = p;
+ }
+
+ if (start != end && ISBLANK (*start))
+ {
+ pp_space (pp);
+ ++start;
+ }
+ if (start != end && *start == '\n')
+ {
+ pp_newline (pp);
+ ++start;
+ }
+ }
+}
+
+/* Same as pp_wrap_text but wrap text only when in line-wrapping mode. */
+static inline void
+pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end)
+{
+ if (pp_is_wrapping_line (pp))
+ pp_wrap_text (pp, start, end);
+ else
+ pp_append_text (pp, start, end);
+}
+
+/* Append to the output area of PRETTY-PRINTER a string specified by its
+ STARTing character and LENGTH. */
+static inline void
+pp_append_r (pretty_printer *pp, const char *start, int length)
+{
+ obstack_grow (&pp->buffer->obstack, start, length);
+ pp->buffer->line_length += length;
+}
+
+/* Insert enough spaces into the output area of PRETTY-PRINTER to bring
+ the column position to the current indentation level, assuming that a
+ newline has just been written to the buffer. */
+void
+pp_base_indent (pretty_printer *pp)
+{
+ int n = pp_indentation (pp);
+ int i;
+
+ for (i = 0; i < n; ++i)
+ pp_space (pp);
+}
+
+/* Format a message pointed to by TEXT. The following format specifiers are
+ recognized as being client independent:
+ %d, %i: (signed) integer in base ten.
+ %u: unsigned integer in base ten.
+ %o: unsigned integer in base eight.
+ %x: unsigned integer in base sixteen.
+ %ld, %li, %lo, %lu, %lx: long versions of the above.
+ %lld, %lli, %llo, %llu, %llx: long long versions.
+ %wd, %wi, %wo, %wu, %wx: HOST_WIDE_INT versions.
+ %c: character.
+ %s: string.
+ %p: pointer.
+ %m: strerror(text->err_no) - does not consume a value from args_ptr.
+ %%: `%'.
+ %*.s: a substring the length of which is specified by an integer.
+ %H: location_t. */
+void
+pp_base_format_text (pretty_printer *pp, text_info *text)
+{
+ for (; *text->format_spec; ++text->format_spec)
+ {
+ int precision = 0;
+ bool wide = false;
+
+ /* Ignore text. */
+ {
+ const char *p = text->format_spec;
+ while (*p && *p != '%')
+ ++p;
+ pp_wrap_text (pp, text->format_spec, p);
+ text->format_spec = p;
+ }
+
+ if (*text->format_spec == '\0')
+ break;
+
+ /* We got a '%'. Parse precision modifiers, if any. */
+ switch (*++text->format_spec)
+ {
+ case 'w':
+ wide = true;
+ ++text->format_spec;
+ break;
+
+ case 'l':
+ do
+ ++precision;
+ while (*++text->format_spec == 'l');
+ break;
+
+ default:
+ break;
+ }
+ /* We don't support precision beyond that of "long long". */
+ if (precision > 2)
+ abort();
+
+ switch (*text->format_spec)
+ {
+ case 'c':
+ pp_character (pp, va_arg (*text->args_ptr, int));
+ break;
+
+ case 'd':
+ case 'i':
+ if (wide)
+ pp_wide_integer (pp, va_arg (*text->args_ptr, HOST_WIDE_INT));
+ else
+ pp_integer_with_precision
+ (pp, *text->args_ptr, precision, int, "d");
+ break;
+
+ case 'o':
+ if (wide)
+ pp_scalar (pp, "%" HOST_WIDE_INT_PRINT "o",
+ va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
+ else
+ pp_integer_with_precision
+ (pp, *text->args_ptr, precision, unsigned, "u");
+ break;
+
+ case 's':
+ pp_string (pp, va_arg (*text->args_ptr, const char *));
+ break;
+
+ case 'p':
+ pp_pointer (pp, va_arg (*text->args_ptr, void *));
+ break;
+
+ case 'u':
+ if (wide)
+ pp_scalar (pp, HOST_WIDE_INT_PRINT_UNSIGNED,
+ va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
+ else
+ pp_integer_with_precision
+ (pp, *text->args_ptr, precision, unsigned, "u");
+ break;
+
+ case 'x':
+ if (wide)
+ pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
+ va_arg (*text->args_ptr, unsigned HOST_WIDE_INT));
+ else
+ pp_integer_with_precision
+ (pp, *text->args_ptr, precision, unsigned, "x");
+ break;
+
+ case 'm':
+ pp_string (pp, xstrerror (text->err_no));
+ break;
+
+ case '%':
+ pp_character (pp, '%');
+ break;
+
+ case 'H':
+ {
+ const location_t *locus = va_arg (*text->args_ptr, location_t *);
+ pp_string (pp, "file '");
+ pp_string (pp, locus->file);
+ pp_string (pp, "', line ");
+ pp_decimal_int (pp, locus->line);
+ }
+ break;
+
+ case '.':
+ {
+ int n;
+ const char *s;
+ /* We handle no precision specifier but `%.*s'. */
+ if (*++text->format_spec != '*')
+ abort ();
+ else if (*++text->format_spec != 's')
+ abort ();
+ n = va_arg (*text->args_ptr, int);
+ s = va_arg (*text->args_ptr, const char *);
+ pp_append_text (pp, s, s + n);
+ }
+ break;
+
+ default:
+ if (!pp_format_decoder (pp) || !(*pp_format_decoder (pp)) (pp, text))
+ {
+ /* Hmmm. The client failed to install a format translator
+ but called us with an unrecognized format. Or, maybe, the
+ translated string just contains an invalid format, or
+ has formats in the wrong order. Sorry. */
+ abort ();
+ }
+ }
+ }
+}
+
+/* Helper subroutine of output_verbatim and verbatim. Do the appropriate
+ settings needed by BUFFER for a verbatim formatting. */
+void
+pp_base_format_verbatim (pretty_printer *pp, text_info *text)
+{
+ diagnostic_prefixing_rule_t rule = pp_prefixing_rule (pp);
+ int line_cutoff = pp_line_cutoff (pp);
+
+ /* Set verbatim mode. */
+ pp->prefixing_rule = DIAGNOSTICS_SHOW_PREFIX_NEVER;
+ pp_line_cutoff (pp) = 0;
+ /* Do the actual formatting. */
+ pp_format_text (pp, text);
+ /* Restore previous settings. */
+ pp_prefixing_rule (pp) = rule;
+ pp_line_cutoff (pp) = line_cutoff;
+}
+
+/* Flush the content of BUFFER onto the attached stream. */
+void
+pp_base_flush (pretty_printer *pp)
+{
+ pp_write_text_to_stream (pp);
+ pp_clear_state (pp);
+ fputc ('\n', pp->buffer->stream);
+ fflush (pp->buffer->stream);
+ pp_needs_newline (pp) = false;
+}
+
+/* Sets the number of maximum characters per line PRETTY-PRINTER can
+ output in line-wrapping mode. A LENGTH value 0 suppresses
+ line-wrapping. */
+void
+pp_base_set_line_maximum_length (pretty_printer *pp, int length)
+{
+ pp_line_cutoff (pp) = length;
+ pp_set_real_maximum_length (pp);
+}
+
+/* Clear PRETTY-PRINTER output area text info. */
+void
+pp_base_clear_output_area (pretty_printer *pp)
+{
+ obstack_free (&pp->buffer->obstack, obstack_base (&pp->buffer->obstack));
+ pp->buffer->line_length = 0;
+}
+
+/* Set PREFIX for PRETTY-PRINTER. */
+void
+pp_base_set_prefix (pretty_printer *pp, const char *prefix)
+{
+ pp->prefix = prefix;
+ pp_set_real_maximum_length (pp);
+ pp->emitted_prefix = false;
+ pp_indentation (pp) = 0;
+}
+
+/* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */
+void
+pp_base_destroy_prefix (pretty_printer *pp)
+{
+ if (pp->prefix != NULL)
+ {
+ free ((char *) pp->prefix);
+ pp->prefix = NULL;
+ }
+}
+
+/* Write out PRETTY-PRINTER's prefix. */
+void
+pp_base_emit_prefix (pretty_printer *pp)
+{
+ if (pp->prefix != NULL)
+ {
+ switch (pp_prefixing_rule (pp))
+ {
+ default:
+ case DIAGNOSTICS_SHOW_PREFIX_NEVER:
+ break;
+
+ case DIAGNOSTICS_SHOW_PREFIX_ONCE:
+ if (pp->emitted_prefix)
+ {
+ pp_base_indent (pp);
+ break;
+ }
+ pp_indentation (pp) += 3;
+ /* Fall through. */
+
+ case DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE:
+ {
+ int prefix_length = strlen (pp->prefix);
+ pp_append_r (pp, pp->prefix, prefix_length);
+ pp->emitted_prefix = true;
+ }
+ break;
+ }
+ }
+}
+
+/* Construct a PRETTY-PRINTER with PREFIX and of MAXIMUM_LENGTH
+ characters per line. */
+void
+pp_construct (pretty_printer *pp, const char *prefix, int maximum_length)
+{
+ memset (pp, 0, sizeof (pretty_printer));
+ pp->buffer = xcalloc (1, sizeof (output_buffer));
+ obstack_init (&pp->buffer->obstack);
+ pp->buffer->stream = stderr;
+ pp_line_cutoff (pp) = maximum_length;
+ pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
+ pp_set_prefix (pp, prefix);
+}
+
+/* Append a string delimited by START and END to the output area of
+ PRETTY-PRINTER. No line wrapping is done. However, if beginning a
+ new line then emit PRETTY-PRINTER's prefix and skip any leading
+ whitespace if appropriate. The caller must ensure that it is
+ safe to do so. */
+void
+pp_base_append_text (pretty_printer *pp, const char *start, const char *end)
+{
+ /* Emit prefix and skip whitespace if we're starting a new line. */
+ if (pp->buffer->line_length == 0)
+ {
+ pp_emit_prefix (pp);
+ if (pp_is_wrapping_line (pp))
+ while (start != end && *start == ' ')
+ ++start;
+ }
+ pp_append_r (pp, start, end - start);
+}
+
+/* Finishes constructing a NULL-terminated character string representing
+ the PRETTY-PRINTED text. */
+const char *
+pp_base_formatted_text (pretty_printer *pp)
+{
+ obstack_1grow (&pp->buffer->obstack, '\0');
+ return pp_formatted_text_data (pp);
+}
+
+/* Return a pointer to the last character emitted in PRETTY-PRINTER's
+ output area. A NULL pointer means no character available. */
+const char *
+pp_base_last_position_in_text (const pretty_printer *pp)
+{
+ const char *p = NULL;
+ struct obstack *text = &pp->buffer->obstack;
+
+ if (obstack_base (text) != obstack_next_free (text))
+ p = ((const char *) obstack_next_free (text)) - 1;
+ return p;
+}
+
+/* Return the amount of characters PRETTY-PRINTER can accept to
+ make a full line. Meaningful only in line-wrapping mode. */
+int
+pp_base_remaining_character_count_for_line (pretty_printer *pp)
+{
+ return pp->maximum_length - pp->buffer->line_length;
+}
+
+
+/* Format a message into BUFFER a la printf. */
+void
+pp_printf (pretty_printer *pp, const char *msg, ...)
+{
+ text_info text;
+ va_list ap;
+
+ va_start (ap, msg);
+ text.err_no = errno;
+ text.args_ptr = &ap;
+ text.format_spec = msg;
+ pp_format_text (pp, &text);
+ va_end (ap);
+}
+
+
+/* Output MESSAGE verbatim into BUFFER. */
+void
+pp_verbatim (pretty_printer *pp, const char *msg, ...)
+{
+ text_info text;
+ va_list ap;
+
+ va_start (ap, msg);
+ text.err_no = errno;
+ text.args_ptr = &ap;
+ text.format_spec = msg;
+ pp_format_verbatim (pp, &text);
+ va_end (ap);
+}
+
+
+
+/* Have PRETTY-PRINTER start a new line. */
+void
+pp_base_newline (pretty_printer *pp)
+{
+ obstack_1grow (&pp->buffer->obstack, '\n');
+ pp->buffer->line_length = 0;
+}
+
+/* Have PRETTY-PRINTER add a CHARACTER. */
+void
+pp_base_character (pretty_printer *pp, int c)
+{
+ if (pp_is_wrapping_line (pp)
+ && pp_remaining_character_count_for_line (pp) <= 0)
+ {
+ pp_newline (pp);
+ if (ISSPACE (c))
+ return;
+ }
+ obstack_1grow (&pp->buffer->obstack, c);
+ ++pp->buffer->line_length;
+}
+
+/* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
+ be line-wrapped if in appropriate mode. */
+void
+pp_base_string (pretty_printer *pp, const char *str)
+{
+ pp_maybe_wrap_text (pp, str, str + (str ? strlen (str) : 0));
+}
+
+
diff --git a/contrib/gcc/pretty-print.h b/contrib/gcc/pretty-print.h
index 5efb9e73078a..1691aec274a9 100644
--- a/contrib/gcc/pretty-print.h
+++ b/contrib/gcc/pretty-print.h
@@ -1,5 +1,5 @@
/* Various declarations for language-independent pretty-print subroutines.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
@@ -22,7 +22,47 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_PRETTY_PRINT_H
#define GCC_PRETTY_PRINT_H
-#include "diagnostic.h"
+#include "obstack.h"
+#include "input.h"
+
+/* The type of a text to be formatted according a format specification
+ along with a list of things. */
+typedef struct
+{
+ const char *format_spec;
+ va_list *args_ptr;
+ int err_no; /* for %m */
+} text_info;
+
+/* How often diagnostics are prefixed by their locations:
+ o DIAGNOSTICS_SHOW_PREFIX_NEVER: never - not yet supported;
+ o DIAGNOSTICS_SHOW_PREFIX_ONCE: emit only once;
+ o DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE: emit each time a physical
+ line is started. */
+typedef enum
+{
+ DIAGNOSTICS_SHOW_PREFIX_ONCE = 0x0,
+ DIAGNOSTICS_SHOW_PREFIX_NEVER = 0x1,
+ DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE = 0x2
+} diagnostic_prefixing_rule_t;
+
+/* The output buffer datatype. This is best seen as an abstract datatype
+ whose fields should not be accessed directly by clients. */
+typedef struct
+{
+ /* The obstack where the text is built up. */
+ struct obstack obstack;
+
+ /* Where to output formatted text. */
+ FILE *stream;
+
+ /* The amount of characters output so far. */
+ int line_length;
+
+ /* This must be large enough to hold any printed integer or
+ floating-point value. */
+ char digit_buffer[128];
+} output_buffer;
/* The type of pretty-printer flags passed to clients. */
typedef unsigned int pp_flags;
@@ -32,69 +72,190 @@ typedef enum
pp_none, pp_before, pp_after
} pp_padding;
+/* The type of a hook that formats client-specific data onto a pretty_pinter.
+ A client-supplied formatter returns true if everything goes well,
+ otherwise it returns false. */
+typedef struct pretty_print_info pretty_printer;
+typedef bool (*printer_fn) (pretty_printer *, text_info *);
+
+/* Client supplied function used to decode formats. */
+#define pp_format_decoder(PP) pp_base (PP)->format_decoder
+
+/* TRUE if a newline character needs to be added before further
+ formatting. */
+#define pp_needs_newline(PP) pp_base (PP)->need_newline
+
+/* Maximum characters per line in automatic line wrapping mode.
+ Zero means don't wrap lines. */
+#define pp_line_cutoff(PP) pp_base (PP)->ideal_maximum_length
+
+/* True if PRETTY-PTINTER is in line-wrapping mode. */
+#define pp_is_wrapping_line(PP) (pp_line_cutoff (PP) > 0)
+
+/* Prefixing rule used in formatting a diagnostic message. */
+#define pp_prefixing_rule(PP) pp_base (PP)->prefixing_rule
+
+/* The amount of whitespace to be emitted when starting a new line. */
+#define pp_indentation(PP) pp_base (PP)->indent_skip
+
+/* The data structure that contains the bare minimum required to do
+ proper pretty-printing. Clients may derived from this structure
+ and add additional fields they need. */
struct pretty_print_info
{
/* Where we print external representation of ENTITY. */
output_buffer *buffer;
- pp_flags flags;
+
+ /* The prefix for each new line. */
+ const char *prefix;
+
/* Where to put whitespace around the entity being formatted. */
pp_padding padding;
+
+ /* The real upper bound of number of characters per line, taking into
+ account the case of a very very looong prefix. */
+ int maximum_length;
+
+ /* The ideal upper bound of number of characters per line, as suggested
+ by front-end. */
+ int ideal_maximum_length;
+
+ /* Indentation count. */
+ int indent_skip;
+
+ /* Current prefixing rule. */
+ diagnostic_prefixing_rule_t prefixing_rule;
+
+ /* If non-NULL, this function formats a TEXT into the BUFFER. When called,
+ TEXT->format_spec points to a format code. FORMAT_DECODER should call
+ pp_string (and related functions) to add data to the BUFFER.
+ FORMAT_DECODER can read arguments from *TEXT->args_pts using VA_ARG.
+ If the BUFFER needs additional characters from the format string, it
+ should advance the TEXT->format_spec as it goes. When FORMAT_DECODER
+ returns, TEXT->format_spec should point to the last character processed.
+ */
+ printer_fn format_decoder;
+
+ /* Nonzero if current PREFIX was emitted at least once. */
+ bool emitted_prefix;
+
+ /* Nonzero means one should emit a newline before outputting anything. */
+ bool need_newline;
};
-#define pp_left_paren(PPI) output_add_character (pp_buffer (PPI), '(')
-#define pp_right_paren(PPI) output_add_character (pp_buffer (PPI), ')')
-#define pp_left_bracket(PPI) output_add_character (pp_buffer (PPI), '[')
-#define pp_right_bracket(PPI) output_add_character (pp_buffer (PPI), ']')
-#define pp_left_brace(PPI) output_add_character (pp_buffer (PPI), '{')
-#define pp_right_brace(PPI) output_add_character (pp_buffer (PPI), '}')
-#define pp_semicolon(PPI) output_add_character (pp_buffer (PPI), ';')
-#define pp_comma(PPI) output_add_string (pp_buffer (PPI), ", ")
-#define pp_dot(PPI) output_add_character (pp_buffer (PPI), '.')
-#define pp_colon(PPI) output_add_character (pp_buffer (PPI), ':')
-#define pp_colon_colon(PPI) output_add_string (pp_buffer (PPI), "::")
-#define pp_arrow(PPI) output_add_string (pp_buffer (PPI), "->")
-#define pp_equal(PPI) output_add_character (pp_buffer (PPI), '=')
-#define pp_question(PPI) output_add_character (pp_buffer (PPI), '?')
-#define pp_bar(PPI) output_add_character (pp_buffer (PPI), '|')
-#define pp_carret(PPI) output_add_character (pp_buffer (PPI), '^')
-#define pp_ampersand(PPI) output_add_character (pp_buffer (PPI), '&')
-#define pp_less(PPI) output_add_character (pp_buffer (PPI), '<')
-#define pp_greater(PPI) output_add_character (pp_buffer (PPI), '>')
-#define pp_plus(PPI) output_add_character (pp_buffer (PPI), '+')
-#define pp_minus(PPI) output_add_character (pp_buffer (PPI), '-')
-#define pp_star(PPI) output_add_character (pp_buffer (PPI), '*')
-#define pp_slash(PPI) output_add_character (pp_buffer (PPI), '/')
-#define pp_modulo(PPI) output_add_character (pp_buffer (PPI), '%')
-#define pp_exclamation(PPI) output_add_character (pp_buffer (PPI), '!')
-#define pp_complement(PPI) output_add_character (pp_buffer (PPI), '~')
-#define pp_quote(PPI) output_add_character (pp_buffer (PPI), '\'')
-#define pp_backquote(PPI) output_add_character (pp_buffer (PPI), '`')
-#define pp_doublequote(PPI) output_add_character (pp_buffer (PPI), '"')
-#define pp_newline(PPI) output_add_newline (pp_buffer (PPI))
-#define pp_character(PPI, C) output_add_character (pp_buffer (PPI), C)
-#define pp_whitespace(PPI) output_add_space (pp_buffer (PPI))
-#define pp_indentation(PPI) output_indentation (pp_buffer (PPI))
-#define pp_newline_and_indent(PPI, N) \
- do { \
- pp_indentation (PPI) += N; \
- pp_newline (PPI); \
+#define pp_set_line_maximum_length(PP, L) \
+ pp_base_set_line_maximum_length (pp_base (PP), L)
+#define pp_set_prefix(PP, P) pp_base_set_prefix (pp_base (PP), P)
+#define pp_destroy_prefix(PP) pp_base_destroy_prefix (pp_base (PP))
+#define pp_remaining_character_count_for_line(PP) \
+ pp_base_remaining_character_count_for_line (pp_base (PP))
+#define pp_clear_output_area(PP) \
+ pp_base_clear_output_area (pp_base (PP))
+#define pp_formatted_text(PP) pp_base_formatted_text (pp_base (PP))
+#define pp_last_position_in_text(PP) \
+ pp_base_last_position_in_text (pp_base (PP))
+#define pp_emit_prefix(PP) pp_base_emit_prefix (pp_base (PP))
+#define pp_append_text(PP, B, E) \
+ pp_base_append_text (pp_base (PP), B, E)
+#define pp_flush(PP) pp_base_flush (pp_base (PP))
+#define pp_format_text(PP, TI) pp_base_format_text (pp_base (PP), TI)
+#define pp_format_verbatim(PP, TI) \
+ pp_base_format_verbatim (pp_base (PP), TI)
+
+#define pp_character(PP, C) pp_base_character (pp_base (PP), C)
+#define pp_string(PP, S) pp_base_string (pp_base (PP), S)
+#define pp_newline(PP) pp_base_newline (pp_base (PP))
+
+#define pp_space(PP) pp_character (PP, ' ')
+#define pp_left_paren(PP) pp_character (PP, '(')
+#define pp_right_paren(PP) pp_character (PP, ')')
+#define pp_left_bracket(PP) pp_character (PP, '[')
+#define pp_right_bracket(PP) pp_character (PP, ']')
+#define pp_left_brace(PP) pp_character (PP, '{')
+#define pp_right_brace(PP) pp_character (PP, '}')
+#define pp_semicolon(PP) pp_character (PP, ';')
+#define pp_comma(PP) pp_string (PP, ", ")
+#define pp_dot(PP) pp_character (PP, '.')
+#define pp_colon(PP) pp_character (PP, ':')
+#define pp_colon_colon(PP) pp_string (PP, "::")
+#define pp_arrow(PP) pp_string (PP, "->")
+#define pp_equal(PP) pp_character (PP, '=')
+#define pp_question(PP) pp_character (PP, '?')
+#define pp_bar(PP) pp_character (PP, '|')
+#define pp_carret(PP) pp_character (PP, '^')
+#define pp_ampersand(PP) pp_character (PP, '&')
+#define pp_less(PP) pp_character (PP, '<')
+#define pp_greater(PP) pp_character (PP, '>')
+#define pp_plus(PP) pp_character (PP, '+')
+#define pp_minus(PP) pp_character (PP, '-')
+#define pp_star(PP) pp_character (PP, '*')
+#define pp_slash(PP) pp_character (PP, '/')
+#define pp_modulo(PP) pp_character (PP, '%')
+#define pp_exclamation(PP) pp_character (PP, '!')
+#define pp_complement(PP) pp_character (PP, '~')
+#define pp_quote(PP) pp_character (PP, '\'')
+#define pp_backquote(PP) pp_character (PP, '`')
+#define pp_doublequote(PP) pp_character (PP, '"')
+#define pp_newline_and_indent(PP, N) \
+ do { \
+ pp_indentation (PP) += N; \
+ pp_newline (PP); \
+ pp_base_indent (pp_base (PP)); \
+ pp_needs_newline (PP) = false; \
} while (0)
-#define pp_separate_with(PPI, C) \
- do { \
- pp_character (PPI, C); \
- pp_whitespace (PPI); \
+#define pp_maybe_newline_and_indent(PP, N) \
+ if (pp_needs_newline (PP)) pp_newline_and_indent (PP, N)
+#define pp_separate_with(PP, C) \
+ do { \
+ pp_character (PP, C); \
+ pp_space (PP); \
} while (0)
-#define pp_format_scalar(PPI, F, S) \
- output_formatted_scalar (pp_buffer (PPI), F, S)
-#define pp_wide_integer(PPI, I) \
- pp_format_scalar (PPI, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) I)
-#define pp_pointer(PPI, P) pp_format_scalar (PPI, "%p", p)
-
-#define pp_identifier(PPI, ID) output_add_string (pp_buffer (PPI), ID)
-#define pp_tree_identifier(PPI, T) pp_identifier(PPI, IDENTIFIER_POINTER (T))
-
-#define pp_unsupported_tree(PPI, T) \
- output_verbatim (pp_buffer(PPI), "#`%s' not supported by %s#",\
- tree_code_name[(int) TREE_CODE (T)], __FUNCTION__)
+#define pp_scalar(PP, FORMAT, SCALAR) \
+ do \
+ { \
+ sprintf (pp_buffer (PP)->digit_buffer, FORMAT, SCALAR); \
+ pp_string (PP, pp_buffer (PP)->digit_buffer); \
+ } \
+ while (0)
+#define pp_decimal_int(PP, I) pp_scalar (PP, "%d", I)
+#define pp_wide_integer(PP, I) \
+ pp_scalar (PP, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) I)
+#define pp_pointer(PP, P) pp_scalar (PP, "%p", P)
+
+#define pp_identifier(PP, ID) pp_string (PP, ID)
+#define pp_tree_identifier(PP, T) \
+ pp_append_text(PP, IDENTIFIER_POINTER (T), \
+ IDENTIFIER_POINTER (T) + IDENTIFIER_LENGTH (T))
+
+#define pp_unsupported_tree(PP, T) \
+ pp_verbatim (pp_base (PP), "#`%s' not supported by %s#", \
+ tree_code_name[(int) TREE_CODE (T)], __FUNCTION__)
+
+
+#define pp_buffer(PP) pp_base (PP)->buffer
+/* Clients that directly derive from pretty_printer need to override
+ this macro to return a pointer to the base pretty_printer structure. */
+#define pp_base(PP) (PP)
+
+extern void pp_construct (pretty_printer *, const char *, int);
+extern void pp_base_set_line_maximum_length (pretty_printer *, int);
+extern void pp_base_set_prefix (pretty_printer *, const char *);
+extern void pp_base_destroy_prefix (pretty_printer *);
+extern int pp_base_remaining_character_count_for_line (pretty_printer *);
+extern void pp_base_clear_output_area (pretty_printer *);
+extern const char *pp_base_formatted_text (pretty_printer *);
+extern const char *pp_base_last_position_in_text (const pretty_printer *);
+extern void pp_base_emit_prefix (pretty_printer *);
+extern void pp_base_append_text (pretty_printer *, const char *, const char *);
+extern void pp_printf (pretty_printer *, const char *, ...) ATTRIBUTE_PRINTF_2;
+extern void pp_verbatim (pretty_printer *, const char *, ...);
+extern void pp_base_flush (pretty_printer *);
+extern void pp_base_format_text (pretty_printer *, text_info *);
+extern void pp_base_format_verbatim (pretty_printer *, text_info *);
+
+extern void pp_base_indent (pretty_printer *);
+extern void pp_base_newline (pretty_printer *);
+extern void pp_base_character (pretty_printer *, int);
+extern void pp_base_string (pretty_printer *, const char *);
#endif /* GCC_PRETTY_PRINT_H */
diff --git a/contrib/gcc/print-rtl.c b/contrib/gcc/print-rtl.c
index 0a0ac9e0427c..f5e30fe97827 100644
--- a/contrib/gcc/print-rtl.c
+++ b/contrib/gcc/print-rtl.c
@@ -1,4 +1,4 @@
-/* Print RTL for GNU C Compiler.
+/* Print RTL for GCC.
Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000, 2002, 2003
Free Software Foundation, Inc.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
/* We don't want the tree code checking code for the access to the
@@ -32,23 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "flags.h"
#include "hard-reg-set.h"
#include "basic-block.h"
-
-/* How to print out a register name.
- We don't use PRINT_REG because some definitions of PRINT_REG
- don't work here. */
-#ifndef DEBUG_PRINT_REG
-#define DEBUG_PRINT_REG(RTX, CODE, FILE) \
- fprintf ((FILE), "%d %s", REGNO (RTX), reg_names[REGNO (RTX)])
-#endif
-
-/* Array containing all of the register names */
-
-#ifdef DEBUG_REGISTER_NAMES
-static const char * const debug_reg_names[] = DEBUG_REGISTER_NAMES;
-#define reg_names debug_reg_names
-#else
-const char * reg_names[] = REGISTER_NAMES;
-#endif
+#include "tm_p.h"
static FILE *outfile;
@@ -56,7 +42,7 @@ static int sawclose = 0;
static int indent;
-static void print_rtx PARAMS ((rtx));
+static void print_rtx (rtx);
/* String printed at beginning of each RTL when it is dumped.
This string is set to ASM_COMMENT_START when the RTL is dumped in
@@ -78,9 +64,7 @@ int dump_for_graph;
static int debug_call_placeholder_verbose;
void
-print_mem_expr (outfile, expr)
- FILE *outfile;
- tree expr;
+print_mem_expr (FILE *outfile, tree expr)
{
if (TREE_CODE (expr) == COMPONENT_REF)
{
@@ -109,8 +93,7 @@ print_mem_expr (outfile, expr)
/* Print IN_RTX onto OUTFILE. This is the recursive part of printing. */
static void
-print_rtx (in_rtx)
- rtx in_rtx;
+print_rtx (rtx in_rtx)
{
int i = 0;
int j;
@@ -237,9 +220,22 @@ print_rtx (in_rtx)
{
if (REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx))
fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
- break;
}
- if (i == 4 && GET_CODE (in_rtx) == NOTE)
+#ifndef GENERATOR_FILE
+ else if (i == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
+ {
+ int flags = SYMBOL_REF_FLAGS (in_rtx);
+ if (flags)
+ fprintf (outfile, " [flags 0x%x]", flags);
+ }
+ else if (i == 2 && GET_CODE (in_rtx) == SYMBOL_REF)
+ {
+ tree decl = SYMBOL_REF_DECL (in_rtx);
+ if (decl)
+ print_node_brief (outfile, "", decl, 0);
+ }
+#endif
+ else if (i == 4 && GET_CODE (in_rtx) == NOTE)
{
switch (NOTE_LINE_NUMBER (in_rtx))
{
@@ -359,15 +355,22 @@ print_rtx (in_rtx)
fprintf (outfile, " ");
fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i));
if (! flag_simple)
- {
- fprintf (outfile, " [");
- fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, XWINT (in_rtx, i));
- fprintf (outfile, "]");
- }
+ fprintf (outfile, " [" HOST_WIDE_INT_PRINT_HEX "]",
+ XWINT (in_rtx, i));
break;
case 'i':
- if (i == 6 && GET_CODE (in_rtx) == NOTE)
+ if (i == 4 && INSN_P (in_rtx))
+ {
+#ifndef GENERATOR_FILE
+ /* Pretty-print insn locators. Ignore scoping as it is mostly
+ redundant with line number information and do not print anything
+ when there is no location information available. */
+ if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
+ fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
+#endif
+ }
+ else if (i == 6 && GET_CODE (in_rtx) == NOTE)
{
/* This field is only used for NOTE_INSN_DELETED_LABEL, and
other times often contains garbage from INSN->NOTE death. */
@@ -379,11 +382,10 @@ print_rtx (in_rtx)
int value = XINT (in_rtx, i);
const char *name;
+#ifndef GENERATOR_FILE
if (GET_CODE (in_rtx) == REG && value < FIRST_PSEUDO_REGISTER)
- {
- fputc (' ', outfile);
- DEBUG_PRINT_REG (in_rtx, 0, outfile);
- }
+ fprintf (outfile, " %d %s", REGNO (in_rtx),
+ reg_names[REGNO (in_rtx)]);
else if (GET_CODE (in_rtx) == REG
&& value <= LAST_VIRTUAL_REGISTER)
{
@@ -401,12 +403,28 @@ print_rtx (in_rtx)
fprintf (outfile, " %d virtual-reg-%d", value,
value-FIRST_VIRTUAL_REGISTER);
}
- else if (flag_dump_unnumbered
+ else
+#endif
+ if (flag_dump_unnumbered
&& (is_insn || GET_CODE (in_rtx) == NOTE))
fputc ('#', outfile);
else
fprintf (outfile, " %d", value);
+ if (GET_CODE (in_rtx) == REG && REG_ATTRS (in_rtx))
+ {
+ fputs (" [", outfile);
+ if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx))
+ fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
+ if (REG_EXPR (in_rtx))
+ print_mem_expr (outfile, REG_EXPR (in_rtx));
+
+ if (REG_OFFSET (in_rtx))
+ fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
+ REG_OFFSET (in_rtx));
+ fputs (" ]", outfile);
+ }
+
if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
&& XINT (in_rtx, i) >= 0
&& (name = get_insn_name (XINT (in_rtx, i))) != NULL)
@@ -468,8 +486,7 @@ print_rtx (in_rtx)
break;
case 't':
- putc (' ', outfile);
- fprintf (outfile, HOST_PTR_PRINTF, (char *) XTREE (in_rtx, i));
+ fprintf (outfile, " " HOST_PTR_PRINTF, (void *) XTREE (in_rtx, i));
break;
case '*':
@@ -493,25 +510,18 @@ print_rtx (in_rtx)
{
#ifndef GENERATOR_FILE
case MEM:
- fputs (" [", outfile);
- fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx));
+ fprintf (outfile, " [" HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx));
if (MEM_EXPR (in_rtx))
print_mem_expr (outfile, MEM_EXPR (in_rtx));
if (MEM_OFFSET (in_rtx))
- {
- fputc ('+', outfile);
- fprintf (outfile, HOST_WIDE_INT_PRINT_DEC,
- INTVAL (MEM_OFFSET (in_rtx)));
- }
+ fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
+ INTVAL (MEM_OFFSET (in_rtx)));
if (MEM_SIZE (in_rtx))
- {
- fputs (" S", outfile);
- fprintf (outfile, HOST_WIDE_INT_PRINT_DEC,
- INTVAL (MEM_SIZE (in_rtx)));
- }
+ fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC,
+ INTVAL (MEM_SIZE (in_rtx)));
if (MEM_ALIGN (in_rtx) != 1)
fprintf (outfile, " A%u", MEM_ALIGN (in_rtx));
@@ -609,10 +619,7 @@ print_rtx (in_rtx)
characters. */
void
-print_inline_rtx (outf, x, ind)
- FILE *outf;
- rtx x;
- int ind;
+print_inline_rtx (FILE *outf, rtx x, int ind)
{
int oldsaw = sawclose;
int oldindent = indent;
@@ -628,8 +635,7 @@ print_inline_rtx (outf, x, ind)
/* Call this function from the debugger to see what X looks like. */
void
-debug_rtx (x)
- rtx x;
+debug_rtx (rtx x)
{
outfile = stderr;
sawclose = 0;
@@ -649,9 +655,7 @@ int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */
EG: -5 prints 2 rtx's on either side (in addition to the specified rtx). */
void
-debug_rtx_list (x, n)
- rtx x;
- int n;
+debug_rtx_list (rtx x, int n)
{
int i,count;
rtx insn;
@@ -678,8 +682,7 @@ debug_rtx_list (x, n)
/* Call this function to print an rtx list from START to END inclusive. */
void
-debug_rtx_range (start, end)
- rtx start, end;
+debug_rtx_range (rtx start, rtx end)
{
while (1)
{
@@ -696,9 +699,7 @@ debug_rtx_range (start, end)
The found insn is returned to enable further debugging analysis. */
rtx
-debug_rtx_find (x, uid)
- rtx x;
- int uid;
+debug_rtx_find (rtx x, int uid)
{
while (x != 0 && INSN_UID (x) != uid)
x = NEXT_INSN (x);
@@ -721,9 +722,7 @@ debug_rtx_find (x, uid)
If RTX_FIRST is not an insn, then it alone is printed, with no newline. */
void
-print_rtl (outf, rtx_first)
- FILE *outf;
- rtx rtx_first;
+print_rtl (FILE *outf, rtx rtx_first)
{
rtx tmp_rtx;
@@ -764,9 +763,7 @@ print_rtl (outf, rtx_first)
/* Return nonzero if we actually printed anything. */
int
-print_rtl_single (outf, x)
- FILE *outf;
- rtx x;
+print_rtl_single (FILE *outf, rtx x)
{
outfile = outf;
sawclose = 0;
@@ -786,9 +783,7 @@ print_rtl_single (outf, x)
if RTX is a CONST_INT then print in decimal format. */
void
-print_simple_rtl (outf, x)
- FILE *outf;
- rtx x;
+print_simple_rtl (FILE *outf, rtx x)
{
flag_simple = 1;
print_rtl (outf, x);
diff --git a/contrib/gcc/print-tree.c b/contrib/gcc/print-tree.c
index 05ca52b3c56b..2965d6ee5749 100644
--- a/contrib/gcc/print-tree.c
+++ b/contrib/gcc/print-tree.c
@@ -1,6 +1,6 @@
-/* Prints out tree in human readable form - GNU C-compiler
+/* Prints out tree in human readable form - GCC
Copyright (C) 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "real.h"
#include "ggc.h"
@@ -45,23 +47,19 @@ static struct bucket **table;
down to a depth of six. */
void
-debug_tree (node)
- tree node;
+debug_tree (tree node)
{
- table = (struct bucket **) xcalloc (HASH_SIZE, sizeof (struct bucket *));
+ table = xcalloc (HASH_SIZE, sizeof (struct bucket *));
print_node (stderr, "", node, 0);
+ free (table);
table = 0;
- fprintf (stderr, "\n");
+ putc ('\n', stderr);
}
/* Print a node in brief fashion, with just the code, address and name. */
void
-print_node_brief (file, prefix, node, indent)
- FILE *file;
- const char *prefix;
- tree node;
- int indent;
+print_node_brief (FILE *file, const char *prefix, tree node, int indent)
{
char class;
@@ -74,8 +72,8 @@ print_node_brief (file, prefix, node, indent)
name if any. */
if (indent > 0)
fprintf (file, " ");
- fprintf (file, "%s <%s ", prefix, tree_code_name[(int) TREE_CODE (node)]);
- fprintf (file, HOST_PTR_PRINTF, (char *) node);
+ fprintf (file, "%s <%s " HOST_PTR_PRINTF,
+ prefix, tree_code_name[(int) TREE_CODE (node)], (char *) node);
if (class == 'd')
{
@@ -108,11 +106,8 @@ print_node_brief (file, prefix, node, indent)
fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW (node));
else if (TREE_INT_CST_HIGH (node) == -1
&& TREE_INT_CST_LOW (node) != 0)
- {
- fprintf (file, "-");
- fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED,
- -TREE_INT_CST_LOW (node));
- }
+ fprintf (file, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
+ -TREE_INT_CST_LOW (node));
else
fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
@@ -141,9 +136,7 @@ print_node_brief (file, prefix, node, indent)
}
void
-indent_to (file, column)
- FILE *file;
- int column;
+indent_to (FILE *file, int column)
{
int i;
@@ -158,11 +151,7 @@ indent_to (file, column)
starting in column INDENT. */
void
-print_node (file, prefix, node, indent)
- FILE *file;
- const char *prefix;
- tree node;
- int indent;
+print_node (FILE *file, const char *prefix, tree node, int indent)
{
int hash;
struct bucket *b;
@@ -193,7 +182,7 @@ print_node (file, prefix, node, indent)
return;
}
- /* It is unsafe to look at any other filds of an ERROR_MARK node. */
+ /* It is unsafe to look at any other fields of an ERROR_MARK node. */
if (TREE_CODE (node) == ERROR_MARK)
{
print_node_brief (file, prefix, node, indent);
@@ -211,7 +200,7 @@ print_node (file, prefix, node, indent)
}
/* Add this node to the table. */
- b = (struct bucket *) xmalloc (sizeof (struct bucket));
+ b = xmalloc (sizeof (struct bucket));
b->node = node;
b->next = table[hash];
table[hash] = b;
@@ -220,8 +209,8 @@ print_node (file, prefix, node, indent)
indent_to (file, indent);
/* Print the slot this node is in, and its code, and address. */
- fprintf (file, "%s <%s ", prefix, tree_code_name[(int) TREE_CODE (node)]);
- fprintf (file, HOST_PTR_PRINTF, (char *) node);
+ fprintf (file, "%s <%s " HOST_PTR_PRINTF,
+ prefix, tree_code_name[(int) TREE_CODE (node)], (void *) node);
/* Print the name, if any. */
if (class == 'd')
@@ -273,7 +262,7 @@ print_node (file, prefix, node, indent)
if (TREE_USED (node))
fputs (" used", file);
if (TREE_NOTHROW (node))
- fputs (" nothrow", file);
+ fputs (TYPE_P (node) ? " align-ok" : " nothrow", file);
if (TREE_PUBLIC (node))
fputs (" public", file);
if (TREE_PRIVATE (node))
@@ -328,14 +317,10 @@ print_node (file, prefix, node, indent)
if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
fputs (" suppress-debug", file);
- if (TREE_CODE (node) == FUNCTION_DECL && DID_INLINE_FUNC (node))
- fputs (" autoinline", file);
- else if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node))
- fputs (" inline", file);
+ if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node))
+ fputs (DECL_DECLARED_INLINE_P (node) ? " inline" : " autoinline", file);
if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
fputs (" built-in", file);
- if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN_NONANSI (node))
- fputs (" built-in-nonansi", file);
if (TREE_CODE (node) == FUNCTION_DECL && DECL_NO_STATIC_CHAIN (node))
fputs (" no-static-chain", file);
@@ -399,11 +384,8 @@ print_node (file, prefix, node, indent)
fprintf (file, " align %d", DECL_ALIGN (node));
if (TREE_CODE (node) == FIELD_DECL)
- {
- fprintf (file, " offset_align ");
- fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED,
- DECL_OFFSET_ALIGN (node));
- }
+ fprintf (file, " offset_align " HOST_WIDE_INT_PRINT_UNSIGNED,
+ DECL_OFFSET_ALIGN (node));
}
else if (DECL_BUILT_IN (node))
{
@@ -416,11 +398,8 @@ print_node (file, prefix, node, indent)
}
if (DECL_POINTER_ALIAS_SET_KNOWN_P (node))
- {
- fprintf (file, " alias set ");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC,
- DECL_POINTER_ALIAS_SET (node));
- }
+ fprintf (file, " alias set " HOST_WIDE_INT_PRINT_DEC,
+ DECL_POINTER_ALIAS_SET (node));
if (TREE_CODE (node) == FIELD_DECL)
{
@@ -464,8 +443,8 @@ print_node (file, prefix, node, indent)
&& DECL_SAVED_INSNS (node) != 0)
{
indent_to (file, indent + 4);
- fprintf (file, "saved-insns ");
- fprintf (file, HOST_PTR_PRINTF, (char *) DECL_SAVED_INSNS (node));
+ fprintf (file, "saved-insns " HOST_PTR_PRINTF,
+ (void *) DECL_SAVED_INSNS (node));
}
/* Print the decl chain only if decl is at second level. */
@@ -502,9 +481,6 @@ print_node (file, prefix, node, indent)
else if (TREE_CODE (node) == ARRAY_TYPE
&& TYPE_NONALIASED_COMPONENT (node))
fputs (" nonaliased-component", file);
- else if (TREE_CODE (node) == FUNCTION_TYPE
- && TYPE_AMBIENT_BOUNDEDNESS (node))
- fputs (" ambient-boundedness", file);
if (TYPE_PACKED (node))
fputs (" packed", file);
@@ -537,10 +513,9 @@ print_node (file, prefix, node, indent)
if (TYPE_USER_ALIGN (node))
fprintf (file, " user");
- fprintf (file, " align %d", TYPE_ALIGN (node));
- fprintf (file, " symtab %d", TYPE_SYMTAB_ADDRESS (node));
- fprintf (file, " alias set ");
- fprintf (file, HOST_WIDE_INT_PRINT_DEC, TYPE_ALIAS_SET (node));
+ fprintf (file, " align %d symtab %d alias set " HOST_WIDE_INT_PRINT_DEC,
+ TYPE_ALIGN (node), TYPE_SYMTAB_ADDRESS (node),
+ TYPE_ALIAS_SET (node));
print_node (file, "attributes", TYPE_ATTRIBUTES (node), indent + 4);
@@ -622,7 +597,7 @@ print_node (file, prefix, node, indent)
indent_to (file, indent + 4);
fprintf (file, "rtl %d ", i);
if (TREE_OPERAND (node, i))
- print_rtl (file, (struct rtx_def *) TREE_OPERAND (node, i));
+ print_rtl (file, (rtx) TREE_OPERAND (node, i));
else
fprintf (file, "(nil)");
fprintf (file, "\n");
@@ -661,11 +636,8 @@ print_node (file, prefix, node, indent)
TREE_INT_CST_LOW (node));
else if (TREE_INT_CST_HIGH (node) == -1
&& TREE_INT_CST_LOW (node) != 0)
- {
- fprintf (file, "-");
- fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED,
- -TREE_INT_CST_LOW (node));
- }
+ fprintf (file, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
+ -TREE_INT_CST_LOW (node));
else
fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
TREE_INT_CST_HIGH (node), TREE_INT_CST_LOW (node));
diff --git a/contrib/gcc/profile.c b/contrib/gcc/profile.c
index a70dc6176215..b7b39a2f5a89 100644
--- a/contrib/gcc/profile.c
+++ b/contrib/gcc/profile.c
@@ -1,6 +1,6 @@
/* Calculate branch probabilities, and basic block execution counts.
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
- 2000, 2001 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
based on some ideas from Dain Samples of UC Berkeley.
Further mangling by Bob Manson, Cygnus Support.
@@ -39,61 +39,37 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
edges must be on the spanning tree. We also attempt to place
EDGE_CRITICAL edges on the spanning tree.
- The two auxiliary files generated are <dumpbase>.bb and
- <dumpbase>.bbg. The former contains the BB->linenumber
- mappings, and the latter describes the BB graph.
-
- The BB file contains line numbers for each block. For each basic
- block, a zero count is output (to mark the start of a block), then
- the line numbers of that block are listed. A zero ends the file
- too.
-
- The BBG file contains a count of the blocks, followed by edge
- information, for every edge in the graph. The edge information
- lists the source and target block numbers, and a bit mask
- describing the type of edge.
-
- The BB and BBG file formats are fully described in the gcov
- documentation. */
+ The auxiliary file generated is <dumpbase>.bbg. The format is
+ described in full in gcov-io.h. */
/* ??? Register allocation should use basic block execution counts to
give preference to the most commonly executed blocks. */
-/* ??? The .da files are not safe. Changing the program after creating .da
- files or using different options when compiling with -fbranch-probabilities
- can result the arc data not matching the program. Maybe add instrumented
- arc count to .bbg file? Maybe check whether PFG matches the .bbg file? */
-
/* ??? Should calculate branch probabilities before instrumenting code, since
then we can use arc counts to help decide which arcs to instrument. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
-#include "tree.h"
#include "flags.h"
-#include "insn-config.h"
#include "output.h"
#include "regs.h"
#include "expr.h"
#include "function.h"
#include "toplev.h"
-#include "ggc.h"
-#include "hard-reg-set.h"
-#include "basic-block.h"
-#include "gcov-io.h"
-#include "target.h"
-#include "profile.h"
-#include "libfuncs.h"
-#include "langhooks.h"
+#include "coverage.h"
+#include "value-prof.h"
+#include "tree.h"
/* Additional information about the edges we need. */
struct edge_info {
unsigned int count_valid : 1;
-
+
/* Is on the spanning tree. */
unsigned int on_tree : 1;
-
+
/* Pretend this edge does not exist (it is abnormal and we've
inserted a fake to compensate). */
unsigned int ignore : 1;
@@ -110,31 +86,9 @@ struct bb_info {
#define EDGE_INFO(e) ((struct edge_info *) (e)->aux)
#define BB_INFO(b) ((struct bb_info *) (b)->aux)
-/* Keep all basic block indexes nonnegative in the gcov output. Index 0
- is used for entry block, last block exit block. */
-#define BB_TO_GCOV_INDEX(bb) ((bb) == ENTRY_BLOCK_PTR ? 0 \
- : ((bb) == EXIT_BLOCK_PTR \
- ? last_basic_block + 1 : (bb)->index + 1))
-
-/* Instantiate the profile info structure. */
-
-struct profile_info profile_info;
-
-/* Name and file pointer of the output file for the basic block graph. */
+/* Counter summary from the last set of coverage counts read. */
-static FILE *bbg_file;
-
-/* Name and file pointer of the input file for the arc count data. */
-
-static FILE *da_file;
-static char *da_file_name;
-
-/* Pointer of the output file for the basic block/line number map. */
-static FILE *bb_file;
-
-/* Last source file name written to bb_file. */
-
-static char *last_bb_file_name;
+const struct gcov_ctr_summary *profile_info;
/* Collect statistics on the performance of this pass for the entire source
file. */
@@ -151,264 +105,161 @@ static int total_num_never_executed;
static int total_num_branches;
/* Forward declarations. */
-static void find_spanning_tree PARAMS ((struct edge_list *));
-static void init_edge_profiler PARAMS ((void));
-static rtx gen_edge_profiler PARAMS ((int));
-static void instrument_edges PARAMS ((struct edge_list *));
-static void output_gcov_string PARAMS ((const char *, long));
-static void compute_branch_probabilities PARAMS ((void));
-static gcov_type * get_exec_counts PARAMS ((void));
-static long compute_checksum PARAMS ((void));
-static basic_block find_group PARAMS ((basic_block));
-static void union_groups PARAMS ((basic_block, basic_block));
-
-/* If nonzero, we need to output a constructor to set up the
- per-object-file data. */
-static int need_func_profiler = 0;
+static void find_spanning_tree (struct edge_list *);
+static rtx gen_edge_profiler (int);
+static rtx gen_interval_profiler (struct histogram_value *, unsigned,
+ unsigned);
+static rtx gen_pow2_profiler (struct histogram_value *, unsigned, unsigned);
+static rtx gen_one_value_profiler (struct histogram_value *, unsigned,
+ unsigned);
+static rtx gen_const_delta_profiler (struct histogram_value *, unsigned,
+ unsigned);
+static unsigned instrument_edges (struct edge_list *);
+static void instrument_values (unsigned, struct histogram_value *);
+static void compute_branch_probabilities (void);
+static void compute_value_histograms (unsigned, struct histogram_value *);
+static gcov_type * get_exec_counts (void);
+static basic_block find_group (basic_block);
+static void union_groups (basic_block, basic_block);
+
/* Add edge instrumentation code to the entire insn chain.
F is the first insn of the chain.
NUM_BLOCKS is the number of basic blocks found in F. */
-static void
-instrument_edges (el)
- struct edge_list *el;
+static unsigned
+instrument_edges (struct edge_list *el)
{
- int num_instr_edges = 0;
+ unsigned num_instr_edges = 0;
int num_edges = NUM_EDGES (el);
basic_block bb;
+
remove_fake_edges ();
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
{
- edge e = bb->succ;
- while (e)
+ edge e;
+
+ for (e = bb->succ; e; e = e->succ_next)
{
struct edge_info *inf = EDGE_INFO (e);
+
if (!inf->ignore && !inf->on_tree)
{
+ rtx edge_profile;
+
if (e->flags & EDGE_ABNORMAL)
abort ();
if (rtl_dump_file)
fprintf (rtl_dump_file, "Edge %d to %d instrumented%s\n",
e->src->index, e->dest->index,
EDGE_CRITICAL_P (e) ? " (and split)" : "");
- need_func_profiler = 1;
- insert_insn_on_edge (
- gen_edge_profiler (total_num_edges_instrumented
- + num_instr_edges++), e);
+ edge_profile = gen_edge_profiler (num_instr_edges++);
+ insert_insn_on_edge (edge_profile, e);
+ rebuild_jump_labels (e->insns);
}
- e = e->succ_next;
}
}
- profile_info.count_edges_instrumented_now = num_instr_edges;
- total_num_edges_instrumented += num_instr_edges;
- profile_info.count_instrumented_edges = total_num_edges_instrumented;
-
total_num_blocks_created += num_edges;
if (rtl_dump_file)
fprintf (rtl_dump_file, "%d edges instrumented\n", num_instr_edges);
-
- commit_edge_insertions_watch_calls ();
+ return num_instr_edges;
}
-/* Output STRING to bb_file, surrounded by DELIMITER. */
-
+/* Add code to measure histograms list of VALUES of length N_VALUES. */
static void
-output_gcov_string (string, delimiter)
- const char *string;
- long delimiter;
-{
- size_t temp;
-
- /* Write a delimiter to indicate that a file name follows. */
- __write_long (delimiter, bb_file, 4);
-
- /* Write the string. */
- temp = strlen (string) + 1;
- fwrite (string, temp, 1, bb_file);
-
- /* Append a few zeros, to align the output to a 4 byte boundary. */
- temp = temp & 0x3;
- if (temp)
- {
- char c[4];
-
- c[0] = c[1] = c[2] = c[3] = 0;
- fwrite (c, sizeof (char), 4 - temp, bb_file);
- }
-
- /* Store another delimiter in the .bb file, just to make it easy to find
- the end of the file name. */
- __write_long (delimiter, bb_file, 4);
-}
-
-
-/* Computes hybrid profile for all matching entries in da_file.
- Sets max_counter_in_program as a side effect. */
-
-static gcov_type *
-get_exec_counts ()
+instrument_values (unsigned n_values, struct histogram_value *values)
{
- int num_edges = 0;
- basic_block bb;
- int okay = 1, i;
- int mismatch = 0;
- gcov_type *profile;
- char *function_name_buffer;
- int function_name_buffer_len;
- gcov_type max_counter_in_run;
- const char *name = IDENTIFIER_POINTER
- (DECL_ASSEMBLER_NAME (current_function_decl));
-
- profile_info.max_counter_in_program = 0;
- profile_info.count_profiles_merged = 0;
-
- /* No .da file, no execution counts. */
- if (!da_file)
- return 0;
-
- /* Count the edges to be (possibly) instrumented. */
-
- FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
- {
- edge e;
- for (e = bb->succ; e; e = e->succ_next)
- if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
- num_edges++;
- }
-
- /* now read and combine all matching profiles. */
+ rtx sequence;
+ unsigned i, t;
+ edge e;
- profile = xmalloc (sizeof (gcov_type) * num_edges);
- rewind (da_file);
- function_name_buffer_len = strlen (name) + 1;
- function_name_buffer = xmalloc (function_name_buffer_len + 1);
+ /* Emit code to generate the histograms before the insns. */
- for (i = 0; i < num_edges; i++)
- profile[i] = 0;
-
- while (1)
+ for (i = 0; i < n_values; i++)
{
- long magic, extra_bytes;
- long func_count;
- int i;
-
- if (__read_long (&magic, da_file, 4) != 0)
- break;
-
- if (magic != -123)
+ e = split_block (BLOCK_FOR_INSN (values[i].insn),
+ PREV_INSN (values[i].insn));
+ switch (values[i].type)
{
- okay = 0;
+ case HIST_TYPE_INTERVAL:
+ t = GCOV_COUNTER_V_INTERVAL;
break;
- }
- if (__read_long (&func_count, da_file, 4) != 0)
- {
- okay = 0;
+ case HIST_TYPE_POW2:
+ t = GCOV_COUNTER_V_POW2;
break;
- }
- if (__read_long (&extra_bytes, da_file, 4) != 0)
- {
- okay = 0;
+ case HIST_TYPE_SINGLE_VALUE:
+ t = GCOV_COUNTER_V_SINGLE;
break;
- }
-
- fseek (da_file, 4 + 8, SEEK_CUR);
- /* read the maximal counter. */
- __read_gcov_type (&max_counter_in_run, da_file, 8);
+ case HIST_TYPE_CONST_DELTA:
+ t = GCOV_COUNTER_V_DELTA;
+ break;
- /* skip the rest of "statistics" emited by __bb_exit_func. */
- fseek (da_file, extra_bytes - (4 + 8 + 8), SEEK_CUR);
+ default:
+ abort ();
+ }
+ if (!coverage_counter_alloc (t, values[i].n_counters))
+ continue;
- for (i = 0; i < func_count; i++)
+ switch (values[i].type)
{
- long arc_count;
- long chksum;
- int j;
-
- if (__read_gcov_string
- (function_name_buffer, function_name_buffer_len, da_file,
- -1) != 0)
- {
- okay = 0;
- break;
- }
-
- if (__read_long (&chksum, da_file, 4) != 0)
- {
- okay = 0;
- break;
- }
+ case HIST_TYPE_INTERVAL:
+ sequence = gen_interval_profiler (values + i, t, 0);
+ break;
- if (__read_long (&arc_count, da_file, 4) != 0)
- {
- okay = 0;
- break;
- }
+ case HIST_TYPE_POW2:
+ sequence = gen_pow2_profiler (values + i, t, 0);
+ break;
- if (strcmp (function_name_buffer, name) != 0)
- {
- /* skip */
- if (fseek (da_file, arc_count * 8, SEEK_CUR) < 0)
- {
- okay = 0;
- break;
- }
- }
- else if (arc_count != num_edges
- || chksum != profile_info.current_function_cfg_checksum)
- okay = 0, mismatch = 1;
- else
- {
- gcov_type tmp;
+ case HIST_TYPE_SINGLE_VALUE:
+ sequence = gen_one_value_profiler (values + i, t, 0);
+ break;
- profile_info.max_counter_in_program += max_counter_in_run;
- profile_info.count_profiles_merged++;
+ case HIST_TYPE_CONST_DELTA:
+ sequence = gen_const_delta_profiler (values + i, t, 0);
+ break;
- for (j = 0; j < arc_count; j++)
- if (__read_gcov_type (&tmp, da_file, 8) != 0)
- {
- okay = 0;
- break;
- }
- else
- {
- profile[j] += tmp;
- }
- }
+ default:
+ abort ();
}
- if (!okay)
- break;
-
+ safe_insert_insn_on_edge (sequence, e);
}
+}
+
- free (function_name_buffer);
+/* Computes hybrid profile for all matching entries in da_file. */
- if (!okay)
- {
- if (mismatch)
- error
- ("Profile does not match flowgraph of function %s (out of date?)",
- current_function_name);
- else
- error (".da file corrupted");
- free (profile);
- return 0;
- }
- if (rtl_dump_file)
+static gcov_type *
+get_exec_counts (void)
+{
+ unsigned num_edges = 0;
+ basic_block bb;
+ gcov_type *counts;
+
+ /* Count the edges to be (possibly) instrumented. */
+ FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
{
- fprintf(rtl_dump_file, "Merged %i profiles with maximal count %i.\n",
- profile_info.count_profiles_merged,
- (int)profile_info.max_counter_in_program);
+ edge e;
+ for (e = bb->succ; e; e = e->succ_next)
+ if (!EDGE_INFO (e)->ignore && !EDGE_INFO (e)->on_tree)
+ num_edges++;
}
- return profile;
+ counts = get_coverage_counts (GCOV_COUNTER_ARCS, num_edges, &profile_info);
+ if (!counts)
+ return NULL;
+
+ if (rtl_dump_file && profile_info)
+ fprintf(rtl_dump_file, "Merged %u profiles with maximal count %u.\n",
+ profile_info->runs, (unsigned) profile_info->sum_max);
+
+ return counts;
}
@@ -416,7 +267,7 @@ get_exec_counts ()
Annotate them accordingly. */
static void
-compute_branch_probabilities ()
+compute_branch_probabilities (void)
{
basic_block bb;
int i;
@@ -429,6 +280,22 @@ compute_branch_probabilities ()
gcov_type *exec_counts = get_exec_counts ();
int exec_counts_pos = 0;
+ /* Very simple sanity checks so we catch bugs in our profiling code. */
+ if (profile_info)
+ {
+ if (profile_info->run_max * profile_info->runs < profile_info->sum_max)
+ {
+ error ("corrupted profile info: run_max * runs < sum_max");
+ exec_counts = NULL;
+ }
+
+ if (profile_info->sum_all < profile_info->sum_max)
+ {
+ error ("corrupted profile info: sum_all is smaller than sum_max");
+ exec_counts = NULL;
+ }
+ }
+
/* Attach extra info block to each bb. */
alloc_aux_for_blocks (sizeof (struct bb_info));
@@ -464,6 +331,11 @@ compute_branch_probabilities ()
if (exec_counts)
{
e->count = exec_counts[exec_counts_pos++];
+ if (e->count > profile_info->sum_max)
+ {
+ error ("corrupted profile info: edge from %i to %i exceeds maximal count",
+ bb->index, e->dest->index);
+ }
}
else
e->count = 0;
@@ -574,9 +446,9 @@ compute_branch_probabilities ()
for (e = bb->pred; e; e = e->pred_next)
total += e->count;
- /* Seedgeh for the invalid edge, and set its count. */
+ /* Search for the invalid edge, and set its count. */
for (e = bb->pred; e; e = e->pred_next)
- if (! EDGE_INFO (e)->count_valid && ! EDGE_INFO (e)->ignore)
+ if (!EDGE_INFO (e)->count_valid && !EDGE_INFO (e)->ignore)
break;
/* Calculate count for remaining edge by conservation. */
@@ -620,24 +492,49 @@ compute_branch_probabilities ()
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
{
edge e;
- gcov_type total;
rtx note;
- total = bb->count;
- if (total)
+ if (bb->count < 0)
{
- for (e = bb->succ; e; e = e->succ_next)
+ error ("corrupted profile info: number of iterations for basic block %d thought to be %i",
+ bb->index, (int)bb->count);
+ bb->count = 0;
+ }
+ for (e = bb->succ; e; e = e->succ_next)
+ {
+ /* Function may return twice in the cased the called function is
+ setjmp or calls fork, but we can't represent this by extra
+ edge from the entry, since extra edge from the exit is
+ already present. We get negative frequency from the entry
+ point. */
+ if ((e->count < 0
+ && e->dest == EXIT_BLOCK_PTR)
+ || (e->count > bb->count
+ && e->dest != EXIT_BLOCK_PTR))
{
- e->probability = (e->count * REG_BR_PROB_BASE + total / 2) / total;
- if (e->probability < 0 || e->probability > REG_BR_PROB_BASE)
- {
- error ("corrupted profile info: prob for %d-%d thought to be %d",
- e->src->index, e->dest->index, e->probability);
- e->probability = REG_BR_PROB_BASE / 2;
- }
+ rtx insn = BB_END (bb);
+
+ while (GET_CODE (insn) != CALL_INSN
+ && insn != BB_HEAD (bb)
+ && keep_with_call_p (insn))
+ insn = PREV_INSN (insn);
+ if (GET_CODE (insn) == CALL_INSN)
+ e->count = e->count < 0 ? 0 : bb->count;
+ }
+ if (e->count < 0 || e->count > bb->count)
+ {
+ error ("corrupted profile info: number of executions for edge %d-%d thought to be %i",
+ e->src->index, e->dest->index,
+ (int)e->count);
+ e->count = bb->count / 2;
}
+ }
+ if (bb->count)
+ {
+ for (e = bb->succ; e; e = e->succ_next)
+ e->probability = (e->count * REG_BR_PROB_BASE + bb->count / 2) / bb->count;
if (bb->index >= 0
- && any_condjump_p (bb->end)
+ && any_condjump_p (BB_END (bb))
&& bb->succ->succ_next)
{
int prob;
@@ -657,24 +554,27 @@ compute_branch_probabilities ()
index = 19;
hist_br_prob[index]++;
- note = find_reg_note (bb->end, REG_BR_PROB, 0);
+ note = find_reg_note (BB_END (bb), REG_BR_PROB, 0);
/* There may be already note put by some other pass, such
as builtin_expect expander. */
if (note)
XEXP (note, 0) = GEN_INT (prob);
else
- REG_NOTES (bb->end)
+ REG_NOTES (BB_END (bb))
= gen_rtx_EXPR_LIST (REG_BR_PROB, GEN_INT (prob),
- REG_NOTES (bb->end));
+ REG_NOTES (BB_END (bb)));
num_branches++;
}
}
- /* Otherwise distribute the probabilities evenly so we get sane sum.
- Use simple heuristics that if there are normal edges, give all abnormals
- frequency of 0, otherwise distribute the frequency over abnormals
- (this is the case of noreturn calls). */
+ /* Otherwise distribute the probabilities evenly so we get sane
+ sum. Use simple heuristics that if there are normal edges,
+ give all abnormals frequency of 0, otherwise distribute the
+ frequency over abnormals (this is the case of noreturn
+ calls). */
else
{
+ int total = 0;
+
for (e = bb->succ; e; e = e->succ_next)
if (!(e->flags & (EDGE_COMPLEX | EDGE_FAKE)))
total ++;
@@ -694,7 +594,7 @@ compute_branch_probabilities ()
e->probability = REG_BR_PROB_BASE / total;
}
if (bb->index >= 0
- && any_condjump_p (bb->end)
+ && any_condjump_p (BB_END (bb))
&& bb->succ->succ_next)
num_branches++, num_never_executed;
}
@@ -721,34 +621,63 @@ compute_branch_probabilities ()
}
free_aux_for_blocks ();
- if (exec_counts)
- free (exec_counts);
}
-/* Compute checksum for the current function. */
-
-#define CHSUM_HASH 500000003
-#define CHSUM_SHIFT 2
-
-static long
-compute_checksum ()
+/* Load value histograms for N_VALUES values whose description is stored
+ in VALUES array from .da file. */
+static void
+compute_value_histograms (unsigned n_values, struct histogram_value *values)
{
- long chsum = 0;
- basic_block bb;
-
- FOR_EACH_BB (bb)
+ unsigned i, j, t, any;
+ unsigned n_histogram_counters[GCOV_N_VALUE_COUNTERS];
+ gcov_type *histogram_counts[GCOV_N_VALUE_COUNTERS];
+ gcov_type *act_count[GCOV_N_VALUE_COUNTERS];
+ gcov_type *aact_count;
+
+ for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
+ n_histogram_counters[t] = 0;
+
+ for (i = 0; i < n_values; i++)
+ n_histogram_counters[(int) (values[i].type)] += values[i].n_counters;
+
+ any = 0;
+ for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
{
- edge e;
-
- for (e = bb->succ; e; e = e->succ_next)
+ if (!n_histogram_counters[t])
{
- chsum = ((chsum << CHSUM_SHIFT) + (BB_TO_GCOV_INDEX (e->dest) + 1)) % CHSUM_HASH;
+ histogram_counts[t] = NULL;
+ continue;
}
- chsum = (chsum << CHSUM_SHIFT) % CHSUM_HASH;
+ histogram_counts[t] =
+ get_coverage_counts (COUNTER_FOR_HIST_TYPE (t),
+ n_histogram_counters[t], NULL);
+ if (histogram_counts[t])
+ any = 1;
+ act_count[t] = histogram_counts[t];
}
+ if (!any)
+ return;
- return chsum;
+ for (i = 0; i < n_values; i++)
+ {
+ rtx hist_list = NULL_RTX;
+ t = (int) (values[i].type);
+
+ aact_count = act_count[t];
+ act_count[t] += values[i].n_counters;
+ for (j = values[i].n_counters; j > 0; j--)
+ hist_list = alloc_EXPR_LIST (0, GEN_INT (aact_count[j - 1]), hist_list);
+ hist_list = alloc_EXPR_LIST (0, copy_rtx (values[i].value), hist_list);
+ hist_list = alloc_EXPR_LIST (0, GEN_INT (values[i].type), hist_list);
+ REG_NOTES (values[i].insn) =
+ alloc_EXPR_LIST (REG_VALUE_PROFILE, hist_list,
+ REG_NOTES (values[i].insn));
+ }
+
+ for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
+ if (histogram_counts[t])
+ free (histogram_counts[t]);
}
/* Instrument and/or analyze program behavior based on program flow graph.
@@ -768,24 +697,15 @@ compute_checksum ()
Main entry point of this file. */
void
-branch_prob ()
+branch_prob (void)
{
basic_block bb;
- int i;
- int num_edges, ignored_edges;
+ unsigned i;
+ unsigned num_edges, ignored_edges;
+ unsigned num_instrumented;
struct edge_list *el;
- const char *name = IDENTIFIER_POINTER
- (DECL_ASSEMBLER_NAME (current_function_decl));
-
- profile_info.current_function_cfg_checksum = compute_checksum ();
-
- if (rtl_dump_file)
- fprintf (rtl_dump_file, "CFG checksum is %ld\n",
- profile_info.current_function_cfg_checksum);
-
- /* Start of a function. */
- if (flag_test_coverage)
- output_gcov_string (name, (long) -2);
+ unsigned n_values = 0;
+ struct histogram_value *values = NULL;
total_num_times_called++;
@@ -805,36 +725,13 @@ branch_prob ()
{
int need_exit_edge = 0, need_entry_edge = 0;
int have_exit_edge = 0, have_entry_edge = 0;
- rtx insn;
edge e;
- /* Add fake edges from entry block to the call insns that may return
- twice. The CFG is not quite correct then, as call insn plays more
- role of CODE_LABEL, but for our purposes, everything should be OK,
- as we never insert code to the beggining of basic block. */
- for (insn = bb->head; insn != NEXT_INSN (bb->end);
- insn = NEXT_INSN (insn))
- {
- if (GET_CODE (insn) == CALL_INSN
- && find_reg_note (insn, REG_SETJMP, NULL))
- {
- if (GET_CODE (bb->head) == CODE_LABEL
- || insn != NEXT_INSN (bb->head))
- {
- e = split_block (bb, PREV_INSN (insn));
- make_edge (ENTRY_BLOCK_PTR, e->dest, EDGE_FAKE);
- break;
- }
- else
- {
- /* We should not get abort here, as call to setjmp should not
- be the very first instruction of function. */
- if (bb == ENTRY_BLOCK_PTR)
- abort ();
- make_edge (ENTRY_BLOCK_PTR, bb, EDGE_FAKE);
- }
- }
- }
+ /* Functions returning multiple times are not handled by extra edges.
+ Instead we simply allow negative counts on edges from exit to the
+ block past call and corresponding probabilities. We can't go
+ with the extra edges because that would result in flowgraph that
+ needs to have fake edges outside the spanning tree. */
for (e = bb->succ; e; e = e->succ_next)
{
@@ -895,70 +792,6 @@ branch_prob ()
verify_flow_info ();
#endif
- /* Output line number information about each basic block for
- GCOV utility. */
- if (flag_test_coverage)
- {
- FOR_EACH_BB (bb)
- {
- rtx insn = bb->head;
- static int ignore_next_note = 0;
-
- /* We are looking for line number notes. Search backward before
- basic block to find correct ones. */
- insn = prev_nonnote_insn (insn);
- if (!insn)
- insn = get_insns ();
- else
- insn = NEXT_INSN (insn);
-
- /* Output a zero to the .bb file to indicate that a new
- block list is starting. */
- __write_long (0, bb_file, 4);
-
- while (insn != bb->end)
- {
- if (GET_CODE (insn) == NOTE)
- {
- /* Must ignore the line number notes that immediately
- follow the end of an inline function to avoid counting
- it twice. There is a note before the call, and one
- after the call. */
- if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_REPEATED_LINE_NUMBER)
- ignore_next_note = 1;
- else if (NOTE_LINE_NUMBER (insn) > 0)
- {
- if (ignore_next_note)
- ignore_next_note = 0;
- else
- {
- /* If this is a new source file, then output the
- file's name to the .bb file. */
- if (! last_bb_file_name
- || strcmp (NOTE_SOURCE_FILE (insn),
- last_bb_file_name))
- {
- if (last_bb_file_name)
- free (last_bb_file_name);
- last_bb_file_name
- = xstrdup (NOTE_SOURCE_FILE (insn));
- output_gcov_string (NOTE_SOURCE_FILE (insn),
- (long)-1);
- }
- /* Output the line number to the .bb file. Must be
- done after the output_bb_profile_data() call, and
- after the file name is written, to ensure that it
- is correctly handled by gcov. */
- __write_long (NOTE_LINE_NUMBER (insn), bb_file, 4);
- }
- }
- }
- insn = NEXT_INSN (insn);
- }
- }
- __write_long (0, bb_file, 4);
- }
-
/* Create spanning tree from basic block graph, mark each edge that is
on the spanning tree. We insert as many abnormal and critical edges
as possible to minimize number of edge splits necessary. */
@@ -967,15 +800,20 @@ branch_prob ()
/* Fake edges that are not on the tree will not be instrumented, so
mark them ignored. */
- for (i = 0; i < num_edges; i++)
+ for (num_instrumented = i = 0; i < num_edges; i++)
{
edge e = INDEX_EDGE (el, i);
struct edge_info *inf = EDGE_INFO (e);
- if ((e->flags & EDGE_FAKE) && !inf->ignore && !inf->on_tree)
+
+ if (inf->ignore || inf->on_tree)
+ /*NOP*/;
+ else if (e->flags & EDGE_FAKE)
{
inf->ignore = 1;
ignored_edges++;
}
+ else
+ num_instrumented++;
}
total_num_blocks += n_basic_blocks + 2;
@@ -990,82 +828,174 @@ branch_prob ()
if (rtl_dump_file)
fprintf (rtl_dump_file, "%d ignored edges\n", ignored_edges);
- /* Create a .bbg file from which gcov can reconstruct the basic block
- graph. First output the number of basic blocks, and then for every
- edge output the source and target basic block numbers.
- NOTE: The format of this file must be compatible with gcov. */
+ /* Write the data from which gcov can reconstruct the basic block
+ graph. */
- if (flag_test_coverage)
+ /* Basic block flags */
+ if (coverage_begin_output ())
{
- int flag_bits;
+ gcov_position_t offset;
- __write_gcov_string (name, strlen (name), bbg_file, -1);
+ offset = gcov_write_tag (GCOV_TAG_BLOCKS);
+ for (i = 0; i != (unsigned) (n_basic_blocks + 2); i++)
+ gcov_write_unsigned (0);
+ gcov_write_length (offset);
+ }
- /* write checksum. */
- __write_long (profile_info.current_function_cfg_checksum, bbg_file, 4);
+ /* Keep all basic block indexes nonnegative in the gcov output.
+ Index 0 is used for entry block, last index is for exit block.
+ */
+ ENTRY_BLOCK_PTR->index = -1;
+ EXIT_BLOCK_PTR->index = last_basic_block;
+#define BB_TO_GCOV_INDEX(bb) ((bb)->index + 1)
- /* The plus 2 stands for entry and exit block. */
- __write_long (n_basic_blocks + 2, bbg_file, 4);
- __write_long (num_edges - ignored_edges + 1, bbg_file, 4);
+ /* Arcs */
+ if (coverage_begin_output ())
+ {
+ gcov_position_t offset;
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
{
edge e;
- long count = 0;
- for (e = bb->succ; e; e = e->succ_next)
- if (!EDGE_INFO (e)->ignore)
- count++;
- __write_long (count, bbg_file, 4);
+ offset = gcov_write_tag (GCOV_TAG_ARCS);
+ gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
for (e = bb->succ; e; e = e->succ_next)
{
struct edge_info *i = EDGE_INFO (e);
if (!i->ignore)
{
- flag_bits = 0;
+ unsigned flag_bits = 0;
+
if (i->on_tree)
- flag_bits |= 0x1;
+ flag_bits |= GCOV_ARC_ON_TREE;
if (e->flags & EDGE_FAKE)
- flag_bits |= 0x2;
+ flag_bits |= GCOV_ARC_FAKE;
if (e->flags & EDGE_FALLTHRU)
- flag_bits |= 0x4;
+ flag_bits |= GCOV_ARC_FALLTHROUGH;
- __write_long (BB_TO_GCOV_INDEX (e->dest), bbg_file, 4);
- __write_long (flag_bits, bbg_file, 4);
+ gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest));
+ gcov_write_unsigned (flag_bits);
}
}
+
+ gcov_write_length (offset);
+ }
+ }
+
+ /* Line numbers. */
+ if (coverage_begin_output ())
+ {
+ char const *prev_file_name = NULL;
+ gcov_position_t offset;
+
+ FOR_EACH_BB (bb)
+ {
+ rtx insn = BB_HEAD (bb);
+ int ignore_next_note = 0;
+
+ offset = 0;
+
+ /* We are looking for line number notes. Search backward
+ before basic block to find correct ones. */
+ insn = prev_nonnote_insn (insn);
+ if (!insn)
+ insn = get_insns ();
+ else
+ insn = NEXT_INSN (insn);
+
+ while (insn != BB_END (bb))
+ {
+ if (GET_CODE (insn) == NOTE)
+ {
+ /* Must ignore the line number notes that
+ immediately follow the end of an inline function
+ to avoid counting it twice. There is a note
+ before the call, and one after the call. */
+ if (NOTE_LINE_NUMBER (insn)
+ == NOTE_INSN_REPEATED_LINE_NUMBER)
+ ignore_next_note = 1;
+ else if (NOTE_LINE_NUMBER (insn) <= 0)
+ /*NOP*/;
+ else if (ignore_next_note)
+ ignore_next_note = 0;
+ else
+ {
+ if (!offset)
+ {
+ offset = gcov_write_tag (GCOV_TAG_LINES);
+ gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
+ }
+
+ /* If this is a new source file, then output the
+ file's name to the .bb file. */
+ if (!prev_file_name
+ || strcmp (NOTE_SOURCE_FILE (insn),
+ prev_file_name))
+ {
+ prev_file_name = NOTE_SOURCE_FILE (insn);
+ gcov_write_unsigned (0);
+ gcov_write_string (prev_file_name);
+ }
+ gcov_write_unsigned (NOTE_LINE_NUMBER (insn));
+ }
+ }
+ insn = NEXT_INSN (insn);
+ }
+
+ if (offset)
+ {
+ /* A file of NULL indicates the end of run. */
+ gcov_write_unsigned (0);
+ gcov_write_string (NULL);
+ gcov_write_length (offset);
+ }
}
- /* Emit fake loopback edge for EXIT block to maintain compatibility with
- old gcov format. */
- __write_long (1, bbg_file, 4);
- __write_long (0, bbg_file, 4);
- __write_long (0x1, bbg_file, 4);
-
- /* Emit a -1 to separate the list of all edges from the list of
- loop back edges that follows. */
- __write_long (-1, bbg_file, 4);
+ }
+ ENTRY_BLOCK_PTR->index = ENTRY_BLOCK;
+ EXIT_BLOCK_PTR->index = EXIT_BLOCK;
+#undef BB_TO_GCOV_INDEX
+
+ if (flag_profile_values)
+ {
+ life_analysis (get_insns (), NULL, PROP_DEATH_NOTES);
+ find_values_to_profile (&n_values, &values);
+ allocate_reg_info (max_reg_num (), FALSE, FALSE);
}
if (flag_branch_probabilities)
- compute_branch_probabilities ();
+ {
+ compute_branch_probabilities ();
+ if (flag_profile_values)
+ compute_value_histograms (n_values, values);
+ }
/* For each edge not on the spanning tree, add counting code as rtl. */
-
- if (profile_arc_flag)
+ if (profile_arc_flag
+ && coverage_counter_alloc (GCOV_COUNTER_ARCS, num_instrumented))
{
- instrument_edges (el);
+ unsigned n_instrumented = instrument_edges (el);
+
+ if (n_instrumented != num_instrumented)
+ abort ();
+
+ if (flag_profile_values)
+ instrument_values (n_values, values);
+
+ /* Commit changes done by instrumentation. */
+ commit_edge_insertions_watch_calls ();
allocate_reg_info (max_reg_num (), FALSE, FALSE);
}
remove_fake_edges ();
+ free_aux_for_edges ();
/* Re-merge split basic blocks and the mess introduced by
insert_insn_on_edge. */
cleanup_cfg (profile_arc_flag ? CLEANUP_EXPENSIVE : 0);
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
- free_aux_for_edges ();
free_edge_list (el);
}
@@ -1073,8 +1003,7 @@ branch_prob ()
aux fields. */
static basic_block
-find_group (bb)
- basic_block bb;
+find_group (basic_block bb)
{
basic_block group = bb, bb1;
@@ -1092,8 +1021,7 @@ find_group (bb)
}
static void
-union_groups (bb1, bb2)
- basic_block bb1, bb2;
+union_groups (basic_block bb1, basic_block bb2)
{
basic_block bb1g = find_group (bb1);
basic_block bb2g = find_group (bb2);
@@ -1114,8 +1042,7 @@ union_groups (bb1, bb2)
are more expensive to instrument. */
static void
-find_spanning_tree (el)
- struct edge_list *el;
+find_spanning_tree (struct edge_list *el)
{
int i;
int num_edges = NUM_EDGES (el);
@@ -1135,8 +1062,7 @@ find_spanning_tree (el)
{
edge e = INDEX_EDGE (el, i);
if (((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_FAKE))
- || e->dest == EXIT_BLOCK_PTR
- )
+ || e->dest == EXIT_BLOCK_PTR)
&& !EDGE_INFO (e)->ignore
&& (find_group (e->src) != find_group (e->dest)))
{
@@ -1152,9 +1078,8 @@ find_spanning_tree (el)
for (i = 0; i < num_edges; i++)
{
edge e = INDEX_EDGE (el, i);
- if ((EDGE_CRITICAL_P (e))
- && !EDGE_INFO (e)->ignore
- && (find_group (e->src) != find_group (e->dest)))
+ if (EDGE_CRITICAL_P (e) && !EDGE_INFO (e)->ignore
+ && find_group (e->src) != find_group (e->dest))
{
if (rtl_dump_file)
fprintf (rtl_dump_file, "Critical edge %d to %d put to tree\n",
@@ -1168,8 +1093,8 @@ find_spanning_tree (el)
for (i = 0; i < num_edges; i++)
{
edge e = INDEX_EDGE (el, i);
- if (find_group (e->src) != find_group (e->dest)
- && !EDGE_INFO (e)->ignore)
+ if (!EDGE_INFO (e)->ignore
+ && find_group (e->src) != find_group (e->dest))
{
if (rtl_dump_file)
fprintf (rtl_dump_file, "Normal edge %d to %d put to tree\n",
@@ -1186,50 +1111,10 @@ find_spanning_tree (el)
/* Perform file-level initialization for branch-prob processing. */
void
-init_branch_prob (filename)
- const char *filename;
+init_branch_prob (void)
{
- int len = strlen (filename);
int i;
- if (flag_test_coverage)
- {
- char *data_file, *bbg_file_name;
-
- /* Open an output file for the basic block/line number map. */
- data_file = (char *) alloca (len + 4);
- strcpy (data_file, filename);
- strcat (data_file, ".bb");
- if ((bb_file = fopen (data_file, "wb")) == 0)
- fatal_io_error ("can't open %s", data_file);
-
- /* Open an output file for the program flow graph. */
- bbg_file_name = (char *) alloca (len + 5);
- strcpy (bbg_file_name, filename);
- strcat (bbg_file_name, ".bbg");
- if ((bbg_file = fopen (bbg_file_name, "wb")) == 0)
- fatal_io_error ("can't open %s", bbg_file_name);
-
- /* Initialize to zero, to ensure that the first file name will be
- written to the .bb file. */
- last_bb_file_name = 0;
- }
-
- da_file_name = (char *) xmalloc (len + 4);
- strcpy (da_file_name, filename);
- strcat (da_file_name, ".da");
-
- if (flag_branch_probabilities)
- {
- da_file = fopen (da_file_name, "rb");
- if (!da_file)
- warning ("file %s not found, execution counts assumed to be zero",
- da_file_name);
- }
-
- if (profile_arc_flag)
- init_edge_profiler ();
-
total_num_blocks = 0;
total_num_edges = 0;
total_num_edges_ignored = 0;
@@ -1247,18 +1132,8 @@ init_branch_prob (filename)
is completed. */
void
-end_branch_prob ()
+end_branch_prob (void)
{
- if (flag_test_coverage)
- {
- fclose (bb_file);
- fclose (bbg_file);
- unlink (da_file_name);
- }
-
- if (flag_branch_probabilities && da_file)
- fclose (da_file);
-
if (rtl_dump_file)
{
fprintf (rtl_dump_file, "\n");
@@ -1292,41 +1167,122 @@ end_branch_prob ()
}
}
}
+
-/* The label used by the edge profiling code. */
+/* Output instructions as RTL to increment the edge execution count. */
-static GTY(()) rtx profiler_label;
+static rtx
+gen_edge_profiler (int edgeno)
+{
+ rtx ref = coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
+ rtx tmp;
+ enum machine_mode mode = GET_MODE (ref);
+ rtx sequence;
-/* Initialize the profiler_label. */
+ start_sequence ();
+ ref = validize_mem (ref);
-static void
-init_edge_profiler ()
-{
- /* Generate and save a copy of this so it can be shared. */
- char buf[20];
- ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 2);
- profiler_label = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
+ tmp = expand_simple_binop (mode, PLUS, ref, const1_rtx,
+ ref, 0, OPTAB_WIDEN);
+
+ if (tmp != ref)
+ emit_move_insn (copy_rtx (ref), tmp);
+
+ sequence = get_insns ();
+ end_sequence ();
+ return sequence;
}
-/* Output instructions as RTL to increment the edge execution count. */
+/* Output instructions as RTL to increment the interval histogram counter.
+ VALUE is the expression whose value is profiled. TAG is the tag of the
+ section for counters, BASE is offset of the counter position. */
static rtx
-gen_edge_profiler (edgeno)
- int edgeno;
+gen_interval_profiler (struct histogram_value *value, unsigned tag,
+ unsigned base)
{
- enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
- rtx mem_ref, tmp;
+ unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
+ enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
+ rtx mem_ref, tmp, tmp1, mr, val;
rtx sequence;
+ rtx more_label = gen_label_rtx ();
+ rtx less_label = gen_label_rtx ();
+ rtx end_of_code_label = gen_label_rtx ();
+ int per_counter = gcov_size / BITS_PER_UNIT;
start_sequence ();
- tmp = force_reg (Pmode, profiler_label);
- tmp = plus_constant (tmp, GCOV_TYPE_SIZE / BITS_PER_UNIT * edgeno);
- mem_ref = validize_mem (gen_rtx_MEM (mode, tmp));
+ if (value->seq)
+ emit_insn (value->seq);
+
+ mr = gen_reg_rtx (Pmode);
+
+ tmp = coverage_counter_ref (tag, base);
+ tmp = force_reg (Pmode, XEXP (tmp, 0));
+
+ val = expand_simple_binop (value->mode, MINUS,
+ copy_rtx (value->value),
+ GEN_INT (value->hdata.intvl.int_start),
+ NULL_RTX, 0, OPTAB_WIDEN);
+
+ if (value->hdata.intvl.may_be_more)
+ do_compare_rtx_and_jump (copy_rtx (val), GEN_INT (value->hdata.intvl.steps),
+ GE, 0, value->mode, NULL_RTX, NULL_RTX, more_label);
+ if (value->hdata.intvl.may_be_less)
+ do_compare_rtx_and_jump (copy_rtx (val), const0_rtx, LT, 0, value->mode,
+ NULL_RTX, NULL_RTX, less_label);
+
+ /* We are in range. */
+ tmp1 = expand_simple_binop (value->mode, MULT,
+ copy_rtx (val), GEN_INT (per_counter),
+ NULL_RTX, 0, OPTAB_WIDEN);
+ tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp), tmp1, mr,
+ 0, OPTAB_WIDEN);
+ if (tmp1 != mr)
+ emit_move_insn (copy_rtx (mr), tmp1);
+
+ if (value->hdata.intvl.may_be_more
+ || value->hdata.intvl.may_be_less)
+ {
+ emit_jump_insn (gen_jump (end_of_code_label));
+ emit_barrier ();
+ }
+
+ /* Above the interval. */
+ if (value->hdata.intvl.may_be_more)
+ {
+ emit_label (more_label);
+ tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp),
+ GEN_INT (per_counter * value->hdata.intvl.steps),
+ mr, 0, OPTAB_WIDEN);
+ if (tmp1 != mr)
+ emit_move_insn (copy_rtx (mr), tmp1);
+ if (value->hdata.intvl.may_be_less)
+ {
+ emit_jump_insn (gen_jump (end_of_code_label));
+ emit_barrier ();
+ }
+ }
+
+ /* Below the interval. */
+ if (value->hdata.intvl.may_be_less)
+ {
+ emit_label (less_label);
+ tmp1 = expand_simple_binop (Pmode, PLUS, copy_rtx (tmp),
+ GEN_INT (per_counter * (value->hdata.intvl.steps
+ + (value->hdata.intvl.may_be_more ? 1 : 0))),
+ mr, 0, OPTAB_WIDEN);
+ if (tmp1 != mr)
+ emit_move_insn (copy_rtx (mr), tmp1);
+ }
- set_mem_alias_set (mem_ref, new_alias_set ());
+ if (value->hdata.intvl.may_be_more
+ || value->hdata.intvl.may_be_less)
+ emit_label (end_of_code_label);
- tmp = expand_simple_binop (mode, PLUS, mem_ref, const1_rtx,
+ mem_ref = validize_mem (gen_rtx_MEM (mode, mr));
+
+ tmp = expand_simple_binop (mode, PLUS, copy_rtx (mem_ref), const1_rtx,
mem_ref, 0, OPTAB_WIDEN);
if (tmp != mem_ref)
@@ -1334,93 +1290,202 @@ gen_edge_profiler (edgeno)
sequence = get_insns ();
end_sequence ();
+ rebuild_jump_labels (sequence);
return sequence;
}
-/* Output code for a constructor that will invoke __bb_init_func, if
- this has not already been done. */
+/* Output instructions as RTL to increment the power of two histogram counter.
+ VALUE is the expression whose value is profiled. TAG is the tag of the
+ section for counters, BASE is offset of the counter position. */
-void
-output_func_start_profiler ()
+static rtx
+gen_pow2_profiler (struct histogram_value *value, unsigned tag, unsigned base)
{
- tree fnname, fndecl;
- char *name;
- char buf[20];
- const char *cfnname;
- rtx table_address;
- enum machine_mode mode = mode_for_size (GCOV_TYPE_SIZE, MODE_INT, 0);
- int save_flag_inline_functions = flag_inline_functions;
-
- /* It's either already been output, or we don't need it because we're
- not doing profile-edges. */
- if (! need_func_profiler)
- return;
+ unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
+ enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
+ rtx mem_ref, tmp, mr, uval;
+ rtx sequence;
+ rtx end_of_code_label = gen_label_rtx ();
+ rtx loop_label = gen_label_rtx ();
+ int per_counter = gcov_size / BITS_PER_UNIT;
+
+ start_sequence ();
+
+ if (value->seq)
+ emit_insn (value->seq);
+
+ mr = gen_reg_rtx (Pmode);
+ tmp = coverage_counter_ref (tag, base);
+ tmp = force_reg (Pmode, XEXP (tmp, 0));
+ emit_move_insn (mr, tmp);
+
+ uval = gen_reg_rtx (value->mode);
+ emit_move_insn (uval, copy_rtx (value->value));
- need_func_profiler = 0;
+ /* Check for non-power of 2. */
+ if (value->hdata.pow2.may_be_other)
+ {
+ do_compare_rtx_and_jump (copy_rtx (uval), const0_rtx, LE, 0, value->mode,
+ NULL_RTX, NULL_RTX, end_of_code_label);
+ tmp = expand_simple_binop (value->mode, PLUS, copy_rtx (uval),
+ constm1_rtx, NULL_RTX, 0, OPTAB_WIDEN);
+ tmp = expand_simple_binop (value->mode, AND, copy_rtx (uval), tmp,
+ NULL_RTX, 0, OPTAB_WIDEN);
+ do_compare_rtx_and_jump (tmp, const0_rtx, NE, 0, value->mode, NULL_RTX,
+ NULL_RTX, end_of_code_label);
+ }
+
+ /* Count log_2(value). */
+ emit_label (loop_label);
- /* Synthesize a constructor function to invoke __bb_init_func with a
- pointer to this object file's profile block. */
+ tmp = expand_simple_binop (Pmode, PLUS, copy_rtx (mr), GEN_INT (per_counter), mr, 0, OPTAB_WIDEN);
+ if (tmp != mr)
+ emit_move_insn (copy_rtx (mr), tmp);
- /* Try and make a unique name given the "file function name".
+ tmp = expand_simple_binop (value->mode, ASHIFTRT, copy_rtx (uval), const1_rtx,
+ uval, 0, OPTAB_WIDEN);
+ if (tmp != uval)
+ emit_move_insn (copy_rtx (uval), tmp);
- And no, I don't like this either. */
+ do_compare_rtx_and_jump (copy_rtx (uval), const0_rtx, NE, 0, value->mode,
+ NULL_RTX, NULL_RTX, loop_label);
- fnname = get_file_function_name ('I');
- cfnname = IDENTIFIER_POINTER (fnname);
- name = concat (cfnname, "GCOV", NULL);
- fnname = get_identifier (name);
- free (name);
+ /* Increase the counter. */
+ emit_label (end_of_code_label);
+
+ mem_ref = validize_mem (gen_rtx_MEM (mode, mr));
+
+ tmp = expand_simple_binop (mode, PLUS, copy_rtx (mem_ref), const1_rtx,
+ mem_ref, 0, OPTAB_WIDEN);
+
+ if (tmp != mem_ref)
+ emit_move_insn (copy_rtx (mem_ref), tmp);
+
+ sequence = get_insns ();
+ end_sequence ();
+ rebuild_jump_labels (sequence);
+ return sequence;
+}
+
+/* Output instructions as RTL for code to find the most common value.
+ VALUE is the expression whose value is profiled. TAG is the tag of the
+ section for counters, BASE is offset of the counter position. */
+
+static rtx
+gen_one_value_profiler (struct histogram_value *value, unsigned tag,
+ unsigned base)
+{
+ unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
+ enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
+ rtx stored_value_ref, counter_ref, all_ref, stored_value, counter, all;
+ rtx tmp, uval;
+ rtx sequence;
+ rtx same_label = gen_label_rtx ();
+ rtx zero_label = gen_label_rtx ();
+ rtx end_of_code_label = gen_label_rtx ();
+
+ start_sequence ();
- fndecl = build_decl (FUNCTION_DECL, fnname,
- build_function_type (void_type_node, NULL_TREE));
- DECL_EXTERNAL (fndecl) = 0;
+ if (value->seq)
+ emit_insn (value->seq);
- /* It can be a static function as long as collect2 does not have
- to scan the object file to find its ctor/dtor routine. */
- TREE_PUBLIC (fndecl) = ! targetm.have_ctors_dtors;
+ stored_value_ref = coverage_counter_ref (tag, base);
+ counter_ref = coverage_counter_ref (tag, base + 1);
+ all_ref = coverage_counter_ref (tag, base + 2);
+ stored_value = validize_mem (stored_value_ref);
+ counter = validize_mem (counter_ref);
+ all = validize_mem (all_ref);
- TREE_USED (fndecl) = 1;
+ uval = gen_reg_rtx (mode);
+ convert_move (uval, copy_rtx (value->value), 0);
- DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
+ /* Check if the stored value matches. */
+ do_compare_rtx_and_jump (copy_rtx (uval), copy_rtx (stored_value), EQ,
+ 0, mode, NULL_RTX, NULL_RTX, same_label);
- fndecl = (*lang_hooks.decls.pushdecl) (fndecl);
- rest_of_decl_compilation (fndecl, 0, 1, 0);
- announce_function (fndecl);
- current_function_decl = fndecl;
- DECL_INITIAL (fndecl) = error_mark_node;
- make_decl_rtl (fndecl, NULL);
- init_function_start (fndecl, input_filename, lineno);
- (*lang_hooks.decls.pushlevel) (0);
- expand_function_start (fndecl, 0);
- cfun->arc_profile = 0;
+ /* Does not match; check whether the counter is zero. */
+ do_compare_rtx_and_jump (copy_rtx (counter), const0_rtx, EQ, 0, mode,
+ NULL_RTX, NULL_RTX, zero_label);
- /* Actually generate the code to call __bb_init_func. */
- ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", 0);
- table_address = force_reg (Pmode,
- gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)));
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__bb_init_func"), LCT_NORMAL,
- mode, 1, table_address, Pmode);
+ /* The counter is not zero yet. */
+ tmp = expand_simple_binop (mode, PLUS, copy_rtx (counter), constm1_rtx,
+ counter, 0, OPTAB_WIDEN);
- expand_function_end (input_filename, lineno, 0);
- (*lang_hooks.decls.poplevel) (1, 0, 1);
+ if (tmp != counter)
+ emit_move_insn (copy_rtx (counter), tmp);
- /* Since fndecl isn't in the list of globals, it would never be emitted
- when it's considered to be 'safe' for inlining, so turn off
- flag_inline_functions. */
- flag_inline_functions = 0;
+ emit_jump_insn (gen_jump (end_of_code_label));
+ emit_barrier ();
- rest_of_compilation (fndecl);
+ emit_label (zero_label);
+ /* Set new value. */
+ emit_move_insn (copy_rtx (stored_value), copy_rtx (uval));
- /* Reset flag_inline_functions to its original value. */
- flag_inline_functions = save_flag_inline_functions;
+ emit_label (same_label);
+ /* Increase the counter. */
+ tmp = expand_simple_binop (mode, PLUS, copy_rtx (counter), const1_rtx,
+ counter, 0, OPTAB_WIDEN);
- if (! quiet_flag)
- fflush (asm_out_file);
- current_function_decl = NULL_TREE;
+ if (tmp != counter)
+ emit_move_insn (copy_rtx (counter), tmp);
- if (targetm.have_ctors_dtors)
- (* targetm.asm_out.constructor) (XEXP (DECL_RTL (fndecl), 0),
- DEFAULT_INIT_PRIORITY);
+ emit_label (end_of_code_label);
+
+ /* Increase the counter of all executions; this seems redundant given
+ that ve have counts for edges in cfg, but it may happen that some
+ optimization will change the counts for the block (either because
+ it is unable to update them correctly, or because it will duplicate
+ the block or its part). */
+ tmp = expand_simple_binop (mode, PLUS, copy_rtx (all), const1_rtx,
+ all, 0, OPTAB_WIDEN);
+
+ if (tmp != all)
+ emit_move_insn (copy_rtx (all), tmp);
+ sequence = get_insns ();
+ end_sequence ();
+ rebuild_jump_labels (sequence);
+ return sequence;
}
-#include "gt-profile.h"
+/* Output instructions as RTL for code to find the most common value of
+ a difference between two evaluations of an expression.
+ VALUE is the expression whose value is profiled. TAG is the tag of the
+ section for counters, BASE is offset of the counter position. */
+
+static rtx
+gen_const_delta_profiler (struct histogram_value *value, unsigned tag,
+ unsigned base)
+{
+ struct histogram_value one_value_delta;
+ unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
+ enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
+ rtx stored_value_ref, stored_value, tmp, uval;
+ rtx sequence;
+
+ start_sequence ();
+
+ if (value->seq)
+ emit_insn (value->seq);
+
+ stored_value_ref = coverage_counter_ref (tag, base);
+ stored_value = validize_mem (stored_value_ref);
+
+ uval = gen_reg_rtx (mode);
+ convert_move (uval, copy_rtx (value->value), 0);
+ tmp = expand_simple_binop (mode, MINUS,
+ copy_rtx (uval), copy_rtx (stored_value),
+ NULL_RTX, 0, OPTAB_WIDEN);
+
+ one_value_delta.value = tmp;
+ one_value_delta.mode = mode;
+ one_value_delta.seq = NULL_RTX;
+ one_value_delta.insn = value->insn;
+ one_value_delta.type = HIST_TYPE_SINGLE_VALUE;
+ emit_insn (gen_one_value_profiler (&one_value_delta, tag, base + 1));
+
+ emit_move_insn (copy_rtx (stored_value), uval);
+ sequence = get_insns ();
+ end_sequence ();
+ rebuild_jump_labels (sequence);
+ return sequence;
+}
diff --git a/contrib/gcc/protoize.c b/contrib/gcc/protoize.c
index e039d6d47750..0dd91e242196 100644
--- a/contrib/gcc/protoize.c
+++ b/contrib/gcc/protoize.c
@@ -1,6 +1,6 @@
/* Protoize program - Original version by Ron Guilmette (rfg@segfault.us.com).
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "intl.h"
#include "cppdefault.h"
@@ -46,11 +48,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#endif
/* Macro to see if the paths match. */
-#ifdef HAVE_DOS_BASED_FILE_SYSTEM
-#define IS_SAME_PATH(a,b) (strcasecmp (a, b) == 0)
-#else
-#define IS_SAME_PATH(a,b) (strcmp (a, b) == 0)
-#endif
+#define IS_SAME_PATH(a,b) (FILENAME_CMP (a, b) == 0)
/* Suffix for aux-info files. */
#ifdef __MSDOS__
@@ -73,45 +71,43 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define CPLUS_FILE_SUFFIX "C"
#endif
-static void usage PARAMS ((void)) ATTRIBUTE_NORETURN;
-static void aux_info_corrupted PARAMS ((void)) ATTRIBUTE_NORETURN;
-static void declare_source_confusing PARAMS ((const char *)) ATTRIBUTE_NORETURN;
-static const char *shortpath PARAMS ((const char *, const char *));
-extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
-static void notice PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-static char *savestring PARAMS ((const char *, unsigned int));
-static char *dupnstr PARAMS ((const char *, size_t));
-static const char *substr PARAMS ((const char *, const char * const));
-static int safe_read PARAMS ((int, PTR, int));
-static void safe_write PARAMS ((int, PTR, int, const char *));
-static void save_pointers PARAMS ((void));
-static void restore_pointers PARAMS ((void));
-static int is_id_char PARAMS ((int));
-static int in_system_include_dir PARAMS ((const char *));
-static int directory_specified_p PARAMS ((const char *));
-static int file_excluded_p PARAMS ((const char *));
-static char *unexpand_if_needed PARAMS ((const char *));
-static char *abspath PARAMS ((const char *, const char *));
-static int is_abspath PARAMS ((const char *));
-static void check_aux_info PARAMS ((int));
-static const char *find_corresponding_lparen PARAMS ((const char *));
-static int referenced_file_is_newer PARAMS ((const char *, time_t));
-static void save_def_or_dec PARAMS ((const char *, int));
-static void munge_compile_params PARAMS ((const char *));
-static int gen_aux_info_file PARAMS ((const char *));
-static void process_aux_info_file PARAMS ((const char *, int, int));
-static int identify_lineno PARAMS ((const char *));
-static void check_source PARAMS ((int, const char *));
-static const char *seek_to_line PARAMS ((int));
-static const char *forward_to_next_token_char PARAMS ((const char *));
-static void output_bytes PARAMS ((const char *, size_t));
-static void output_string PARAMS ((const char *));
-static void output_up_to PARAMS ((const char *));
-static int other_variable_style_function PARAMS ((const char *));
-static const char *find_rightmost_formals_list PARAMS ((const char *));
-static void do_cleaning PARAMS ((char *, const char *));
-static const char *careful_find_l_paren PARAMS ((const char *));
-static void do_processing PARAMS ((void));
+static void usage (void) ATTRIBUTE_NORETURN;
+static void aux_info_corrupted (void) ATTRIBUTE_NORETURN;
+static void declare_source_confusing (const char *) ATTRIBUTE_NORETURN;
+static const char *shortpath (const char *, const char *);
+extern void fancy_abort (void) ATTRIBUTE_NORETURN;
+static void notice (const char *, ...) ATTRIBUTE_PRINTF_1;
+static char *savestring (const char *, unsigned int);
+static char *dupnstr (const char *, size_t);
+static int safe_read (int, void *, int);
+static void safe_write (int, void *, int, const char *);
+static void save_pointers (void);
+static void restore_pointers (void);
+static int is_id_char (int);
+static int in_system_include_dir (const char *);
+static int directory_specified_p (const char *);
+static int file_excluded_p (const char *);
+static char *unexpand_if_needed (const char *);
+static char *abspath (const char *, const char *);
+static void check_aux_info (int);
+static const char *find_corresponding_lparen (const char *);
+static int referenced_file_is_newer (const char *, time_t);
+static void save_def_or_dec (const char *, int);
+static void munge_compile_params (const char *);
+static int gen_aux_info_file (const char *);
+static void process_aux_info_file (const char *, int, int);
+static int identify_lineno (const char *);
+static void check_source (int, const char *);
+static const char *seek_to_line (int);
+static const char *forward_to_next_token_char (const char *);
+static void output_bytes (const char *, size_t);
+static void output_string (const char *);
+static void output_up_to (const char *);
+static int other_variable_style_function (const char *);
+static const char *find_rightmost_formals_list (const char *);
+static void do_cleaning (char *, const char *);
+static const char *careful_find_l_paren (const char *);
+static void do_processing (void);
/* Look for these where the `const' qualifier is intentionally cast aside. */
#define NONCONST
@@ -138,12 +134,12 @@ static const char * const aux_info_suffix = AUX_INFO_SUFFIX;
static const char * const save_suffix = SAVE_SUFFIX;
+#ifndef UNPROTOIZE
+
/* String to attach to C filenames renamed to C++. */
static const char * const cplus_suffix = CPLUS_FILE_SUFFIX;
-#ifndef UNPROTOIZE
-
/* File name of the file which contains descriptions of standard system
routines. Note that we never actually do anything with this file per se,
but we do read in its corresponding aux_info file. */
@@ -199,8 +195,8 @@ struct string_list
struct string_list *next;
};
-static struct string_list *string_list_cons PARAMS ((const char *,
- struct string_list *));
+static struct string_list *string_list_cons (const char *,
+ struct string_list *);
/* List of directories in which files should be converted. */
@@ -225,9 +221,7 @@ struct string_list *exclude_list;
static const char * const other_var_style = "stdarg";
#else /* !defined (UNPROTOIZE) */
static const char * const other_var_style = "varargs";
-/* Note that this is a string containing the expansion of va_alist.
- But in `main' we discard all but the first token. */
-static const char *varargs_style_indicator = STRINGX (va_alist);
+static const char *varargs_style_indicator = "va_alist";
#endif /* !defined (UNPROTOIZE) */
/* The following two types are used to create hash tables. In this program,
@@ -247,29 +241,29 @@ typedef struct file_info_struct file_info;
typedef struct f_list_chain_item_struct f_list_chain_item;
#ifndef UNPROTOIZE
-static int is_syscalls_file PARAMS ((const file_info *));
-static void rename_c_file PARAMS ((const hash_table_entry *));
-static const def_dec_info *find_extern_def PARAMS ((const def_dec_info *,
- const def_dec_info *));
-static const def_dec_info *find_static_definition PARAMS ((const def_dec_info *));
-static void connect_defs_and_decs PARAMS ((const hash_table_entry *));
-static void add_local_decl PARAMS ((const def_dec_info *, const char *));
-static void add_global_decls PARAMS ((const file_info *, const char *));
+static int is_syscalls_file (const file_info *);
+static void rename_c_file (const hash_table_entry *);
+static const def_dec_info *find_extern_def (const def_dec_info *,
+ const def_dec_info *);
+static const def_dec_info *find_static_definition (const def_dec_info *);
+static void connect_defs_and_decs (const hash_table_entry *);
+static void add_local_decl (const def_dec_info *, const char *);
+static void add_global_decls (const file_info *, const char *);
#endif /* ! UNPROTOIZE */
-static int needs_to_be_converted PARAMS ((const file_info *));
-static void visit_each_hash_node PARAMS ((const hash_table_entry *,
- void (*)(const hash_table_entry *)));
-static hash_table_entry *add_symbol PARAMS ((hash_table_entry *, const char *));
-static hash_table_entry *lookup PARAMS ((hash_table_entry *, const char *));
-static void free_def_dec PARAMS ((def_dec_info *));
-static file_info *find_file PARAMS ((const char *, int));
-static void reverse_def_dec_list PARAMS ((const hash_table_entry *));
-static void edit_fn_declaration PARAMS ((const def_dec_info *, const char *));
-static int edit_formals_lists PARAMS ((const char *, unsigned int,
- const def_dec_info *));
-static void edit_fn_definition PARAMS ((const def_dec_info *, const char *));
-static void scan_for_missed_items PARAMS ((const file_info *));
-static void edit_file PARAMS ((const hash_table_entry *));
+static int needs_to_be_converted (const file_info *);
+static void visit_each_hash_node (const hash_table_entry *,
+ void (*)(const hash_table_entry *));
+static hash_table_entry *add_symbol (hash_table_entry *, const char *);
+static hash_table_entry *lookup (hash_table_entry *, const char *);
+static void free_def_dec (def_dec_info *);
+static file_info *find_file (const char *, int);
+static void reverse_def_dec_list (const hash_table_entry *);
+static void edit_fn_declaration (const def_dec_info *, const char *);
+static int edit_formals_lists (const char *, unsigned int,
+ const def_dec_info *);
+static void edit_fn_definition (const def_dec_info *, const char *);
+static void scan_for_missed_items (const file_info *);
+static void edit_file (const hash_table_entry *);
/* In the struct below, note that the "_info" field has two different uses
depending on the type of hash table we are in (i.e. either the filenames
@@ -511,24 +505,22 @@ static char * saved_repl_write_ptr;
/* Translate and output an error message. */
static void
-notice VPARAMS ((const char *msgid, ...))
+notice (const char *msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, const char *, msgid);
-
+ va_list ap;
+
+ va_start (ap, msgid);
vfprintf (stderr, _(msgid), ap);
- VA_CLOSE (ap);
+ va_end (ap);
}
/* Make a copy of a string INPUT with size SIZE. */
static char *
-savestring (input, size)
- const char *input;
- unsigned int size;
+savestring (const char *input, unsigned int size)
{
- char *output = (char *) xmalloc (size + 1);
+ char *output = xmalloc (size + 1);
strcpy (output, input);
return output;
}
@@ -537,7 +529,7 @@ savestring (input, size)
config.h can #define abort fancy_abort if you like that sort of thing. */
void
-fancy_abort ()
+fancy_abort (void)
{
notice ("%s: internal abort\n", pname);
exit (FATAL_EXIT_CODE);
@@ -547,49 +539,20 @@ fancy_abort ()
allocated area. */
static char *
-dupnstr (s, n)
- const char *s;
- size_t n;
+dupnstr (const char *s, size_t n)
{
- char *ret_val = (char *) xmalloc (n + 1);
+ char *ret_val = xmalloc (n + 1);
strncpy (ret_val, s, n);
ret_val[n] = '\0';
return ret_val;
}
-
-/* Return a pointer to the first occurrence of s2 within s1 or NULL if s2
- does not occur within s1. Assume neither s1 nor s2 are null pointers. */
-
-static const char *
-substr (s1, s2)
- const char *s1;
- const char *const s2;
-{
- for (; *s1 ; s1++)
- {
- const char *p1;
- const char *p2;
- int c;
-
- for (p1 = s1, p2 = s2; (c = *p2); p1++, p2++)
- if (*p1 != c)
- goto outer;
- return s1;
-outer:
- ;
- }
- return 0;
-}
/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
retrying if necessary. Return the actual number of bytes read. */
static int
-safe_read (desc, ptr, len)
- int desc;
- PTR ptr;
- int len;
+safe_read (int desc, void *ptr, int len)
{
int left = len;
while (left > 0) {
@@ -615,11 +578,7 @@ safe_read (desc, ptr, len)
retrying if necessary, and treating any real error as fatal. */
static void
-safe_write (desc, ptr, len, out_fname)
- int desc;
- PTR ptr;
- int len;
- const char *out_fname;
+safe_write (int desc, void *ptr, int len, const char *out_fname)
{
while (len > 0) {
int written = write (desc, ptr, len);
@@ -643,7 +602,7 @@ safe_write (desc, ptr, len, out_fname)
/* Get setup to recover in case the edit we are about to do goes awry. */
static void
-save_pointers ()
+save_pointers (void)
{
saved_clean_read_ptr = clean_read_ptr;
saved_repl_write_ptr = repl_write_ptr;
@@ -653,7 +612,7 @@ save_pointers ()
too confusing in the source code we are trying to edit. */
static void
-restore_pointers ()
+restore_pointers (void)
{
clean_read_ptr = saved_clean_read_ptr;
repl_write_ptr = saved_repl_write_ptr;
@@ -662,8 +621,7 @@ restore_pointers ()
/* Return true if the given character is a valid identifier character. */
static int
-is_id_char (ch)
- int ch;
+is_id_char (int ch)
{
return (ISIDNUM (ch) || (ch == '$'));
}
@@ -672,7 +630,7 @@ is_id_char (ch)
exit with nonzero status. */
static void
-usage ()
+usage (void)
{
#ifdef UNPROTOIZE
notice ("%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n",
@@ -689,12 +647,11 @@ usage ()
include directories. */
static int
-in_system_include_dir (path)
- const char *path;
+in_system_include_dir (const char *path)
{
const struct default_include *p;
- if (! is_abspath (path))
+ if (! IS_ABSOLUTE_PATH (path))
abort (); /* Must be an absolutized filename. */
for (p = cpp_include_defaults; p->fname; p++)
@@ -712,7 +669,7 @@ in_system_include_dir (path)
static int
file_could_be_converted (const char *path)
{
- char *const dir_name = (char *) alloca (strlen (path) + 1);
+ char *const dir_name = alloca (strlen (path) + 1);
if (access (path, R_OK))
return 0;
@@ -816,8 +773,7 @@ file_normally_convertible (const char *path)
file. Return false otherwise. */
static int
-is_syscalls_file (fi_p)
- const file_info *fi_p;
+is_syscalls_file (const file_info *fi_p)
{
char const *f = fi_p->hash_entry->symbol;
size_t fl = strlen (f), sysl = sizeof (syscalls_filename) - 1;
@@ -836,8 +792,7 @@ is_syscalls_file (fi_p)
by connect_defs_and_decs. */
static int
-needs_to_be_converted (file_p)
- const file_info *file_p;
+needs_to_be_converted (const file_info *file_p)
{
const def_dec_info *ddp;
@@ -875,8 +830,7 @@ needs_to_be_converted (file_p)
that should be converted. */
static int
-directory_specified_p (name)
- const char *name;
+directory_specified_p (const char *name)
{
struct string_list *p;
@@ -902,8 +856,7 @@ directory_specified_p (name)
/* Return 1 if the file named NAME should be excluded from conversion. */
static int
-file_excluded_p (name)
- const char *name;
+file_excluded_p (const char *name)
{
struct string_list *p;
int len = strlen (name);
@@ -920,12 +873,9 @@ file_excluded_p (name)
STRING is the new element value, and REST holds the remaining elements. */
static struct string_list *
-string_list_cons (string, rest)
- const char *string;
- struct string_list *rest;
+string_list_cons (const char *string, struct string_list *rest)
{
- struct string_list *temp
- = (struct string_list *) xmalloc (sizeof (struct string_list));
+ struct string_list *temp = xmalloc (sizeof (struct string_list));
temp->next = rest;
temp->name = string;
@@ -942,9 +892,8 @@ string_list_cons (string, rest)
argument. */
static void
-visit_each_hash_node (hash_tab_p, func)
- const hash_table_entry *hash_tab_p;
- void (*func) PARAMS ((const hash_table_entry *));
+visit_each_hash_node (const hash_table_entry *hash_tab_p,
+ void (*func) (const hash_table_entry *))
{
const hash_table_entry *primary;
@@ -965,9 +914,7 @@ visit_each_hash_node (hash_tab_p, func)
called. */
static hash_table_entry *
-add_symbol (p, s)
- hash_table_entry *p;
- const char *s;
+add_symbol (hash_table_entry *p, const char *s)
{
p->hash_next = NULL;
p->symbol = xstrdup (s);
@@ -982,9 +929,7 @@ add_symbol (p, s)
hash table entry for the given name. */
static hash_table_entry *
-lookup (hash_tab_p, search_symbol)
- hash_table_entry *hash_tab_p;
- const char *search_symbol;
+lookup (hash_table_entry *hash_tab_p, const char *search_symbol)
{
int hash_value = 0;
const char *search_symbol_char_p = search_symbol;
@@ -1004,7 +949,7 @@ lookup (hash_tab_p, search_symbol)
if (!strcmp (p->symbol, search_symbol))
return p;
}
- p->hash_next = (hash_table_entry *) xmalloc (sizeof (hash_table_entry));
+ p->hash_next = xmalloc (sizeof (hash_table_entry));
p = p->hash_next;
return add_symbol (p, search_symbol);
}
@@ -1015,10 +960,9 @@ lookup (hash_tab_p, search_symbol)
stuff it pointed to. */
static void
-free_def_dec (p)
- def_dec_info *p;
+free_def_dec (def_dec_info *p)
{
- free ((NONCONST PTR) p->ansi_decl);
+ free ((NONCONST void *) p->ansi_decl);
#ifndef UNPROTOIZE
{
@@ -1028,7 +972,7 @@ free_def_dec (p)
for (curr = p->f_list_chain; curr; curr = next)
{
next = curr->chain_next;
- free ((NONCONST PTR) curr);
+ free ((NONCONST void *) curr);
}
}
#endif /* !defined (UNPROTOIZE) */
@@ -1042,8 +986,7 @@ free_def_dec (p)
return a pointer to the unexpanded copy. Otherwise return NULL. */
static char *
-unexpand_if_needed (aux_info_line)
- const char *aux_info_line;
+unexpand_if_needed (const char *aux_info_line)
{
static char *line_buf = 0;
static int line_buf_size = 0;
@@ -1055,7 +998,7 @@ unexpand_if_needed (aux_info_line)
if (line_buf == 0)
{
line_buf_size = 1024;
- line_buf = (char *) xmalloc (line_buf_size);
+ line_buf = xmalloc (line_buf_size);
}
copy_p = line_buf;
@@ -1078,7 +1021,7 @@ unexpand_if_needed (aux_info_line)
int offset = copy_p - line_buf;
line_buf_size *= 2;
line_buf_size += size;
- line_buf = (char *) xrealloc (line_buf, line_buf_size);
+ line_buf = xrealloc (line_buf, line_buf_size);
copy_p = line_buf + offset;
}
strcpy (copy_p, unexp_p->contracted);
@@ -1095,7 +1038,7 @@ unexpand_if_needed (aux_info_line)
{
int offset = copy_p - line_buf;
line_buf_size *= 2;
- line_buf = (char *) xrealloc (line_buf, line_buf_size);
+ line_buf = xrealloc (line_buf, line_buf_size);
copy_p = line_buf + offset;
}
*copy_p++ = *s++;
@@ -1105,7 +1048,7 @@ continue_outer: ;
{
int offset = copy_p - line_buf;
line_buf_size *= 2;
- line_buf = (char *) xrealloc (line_buf, line_buf_size);
+ line_buf = xrealloc (line_buf, line_buf_size);
copy_p = line_buf + offset;
}
*copy_p++ = '\n';
@@ -1114,20 +1057,6 @@ continue_outer: ;
return (got_unexpanded ? savestring (line_buf, copy_p - line_buf) : 0);
}
-/* Return 1 if pathname is absolute. */
-
-static int
-is_abspath (path)
- const char *path;
-{
- return (IS_DIR_SEPARATOR (path[0])
-#ifdef HAVE_DOS_BASED_FILE_SYSTEM
- /* Check for disk name on MS-DOS-based systems. */
- || (path[0] && path[1] == ':' && IS_DIR_SEPARATOR (path[2]))
-#endif
- );
-}
-
/* Return the absolutized filename for the given relative
filename. Note that if that filename is already absolute, it may
still be returned in a modified form because this routine also
@@ -1139,14 +1068,11 @@ is_abspath (path)
NULL. */
static char *
-abspath (cwd, rel_filename)
- const char *cwd;
- const char *rel_filename;
+abspath (const char *cwd, const char *rel_filename)
{
/* Setup the current working directory as needed. */
const char *const cwd2 = (cwd) ? cwd : cwd_buffer;
- char *const abs_buffer
- = (char *) alloca (strlen (cwd2) + strlen (rel_filename) + 2);
+ char *const abs_buffer = alloca (strlen (cwd2) + strlen (rel_filename) + 2);
char *endp = abs_buffer;
char *outp, *inp;
@@ -1156,7 +1082,7 @@ abspath (cwd, rel_filename)
{
const char *src_p;
- if (! is_abspath (rel_filename))
+ if (! IS_ABSOLUTE_PATH (rel_filename))
{
src_p = cwd2;
while ((*endp++ = *src_p++))
@@ -1258,9 +1184,7 @@ abspath (cwd, rel_filename)
subpart of the original filename is actually a symbolic link. */
static const char *
-shortpath (cwd, filename)
- const char *cwd;
- const char *filename;
+shortpath (const char *cwd, const char *filename)
{
char *rel_buffer;
char *rel_buf_p;
@@ -1270,7 +1194,7 @@ shortpath (cwd, filename)
size_t filename_len = strlen (filename);
path_p = abspath (cwd, filename);
- rel_buf_p = rel_buffer = (char *) xmalloc (filename_len);
+ rel_buf_p = rel_buffer = xmalloc (filename_len);
while (*cwd_p && IS_SAME_PATH_CHAR (*cwd_p, *path_p))
{
@@ -1347,9 +1271,7 @@ shortpath (cwd, filename)
That is probably a bug in AIX, but might as well avoid the warning. */
static file_info *
-find_file (filename, do_not_stat)
- const char *filename;
- int do_not_stat;
+find_file (const char *filename, int do_not_stat)
{
hash_table_entry *hash_entry_p;
@@ -1359,7 +1281,7 @@ find_file (filename, do_not_stat)
else
{
struct stat stat_buf;
- file_info *file_p = (file_info *) xmalloc (sizeof (file_info));
+ file_info *file_p = xmalloc (sizeof (file_info));
/* If we cannot get status on any given source file, give a warning
and then just set its time of last modification to infinity. */
@@ -1390,7 +1312,7 @@ find_file (filename, do_not_stat)
messed up. */
static void
-aux_info_corrupted ()
+aux_info_corrupted (void)
{
notice ("\n%s: fatal error: aux info file corrupted at line %d\n",
pname, current_aux_info_lineno);
@@ -1401,8 +1323,7 @@ aux_info_corrupted ()
/* Check to see that a condition is true. This is kind of like an assert. */
static void
-check_aux_info (cond)
- int cond;
+check_aux_info (int cond)
{
if (! cond)
aux_info_corrupted ();
@@ -1413,8 +1334,7 @@ check_aux_info (cond)
return a pointer to it. */
static const char *
-find_corresponding_lparen (p)
- const char *p;
+find_corresponding_lparen (const char *p)
{
const char *q;
int paren_depth;
@@ -1440,9 +1360,7 @@ find_corresponding_lparen (p)
file was created. If so, return nonzero, else return zero. */
static int
-referenced_file_is_newer (l, aux_info_mtime)
- const char *l;
- time_t aux_info_mtime;
+referenced_file_is_newer (const char *l, time_t aux_info_mtime)
{
const char *p;
file_info *fi_p;
@@ -1461,7 +1379,7 @@ referenced_file_is_newer (l, aux_info_mtime)
#endif
)
p++;
- filename = (char *) alloca ((size_t) (p - filename_start) + 1);
+ filename = alloca ((size_t) (p - filename_start) + 1);
strncpy (filename, filename_start, (size_t) (p - filename_start));
filename[p-filename_start] = '\0';
}
@@ -1492,13 +1410,11 @@ referenced_file_is_newer (l, aux_info_mtime)
pertaining to this particular function name. */
static void
-save_def_or_dec (l, is_syscalls)
- const char *l;
- int is_syscalls;
+save_def_or_dec (const char *l, int is_syscalls)
{
const char *p;
const char *semicolon_p;
- def_dec_info *def_dec_p = (def_dec_info *) xmalloc (sizeof (def_dec_info));
+ def_dec_info *def_dec_p = xmalloc (sizeof (def_dec_info));
#ifndef UNPROTOIZE
def_dec_p->written = 0;
@@ -1523,7 +1439,7 @@ save_def_or_dec (l, is_syscalls)
#endif
)
p++;
- filename = (char *) alloca ((size_t) (p - filename_start) + 1);
+ filename = alloca ((size_t) (p - filename_start) + 1);
strncpy (filename, filename_start, (size_t) (p - filename_start));
filename[p-filename_start] = '\0';
@@ -1653,8 +1569,7 @@ save_def_or_dec (l, is_syscalls)
const char *left_paren_p = find_corresponding_lparen (p);
#ifndef UNPROTOIZE
{
- f_list_chain_item *cip
- = (f_list_chain_item *) xmalloc (sizeof (f_list_chain_item));
+ f_list_chain_item *cip = xmalloc (sizeof (f_list_chain_item));
cip->formals_list
= dupnstr (left_paren_p + 1, (size_t) (p - (left_paren_p+1)));
@@ -1696,7 +1611,7 @@ save_def_or_dec (l, is_syscalls)
/* p now points to the leftmost character of the function name. */
{
- char *fn_string = (char *) alloca (past_fn - p + 1);
+ char *fn_string = alloca (past_fn - p + 1);
strncpy (fn_string, p, (size_t) (past_fn - p));
fn_string[past_fn-p] = '\0';
@@ -1887,13 +1802,12 @@ save_def_or_dec (l, is_syscalls)
and adding '-aux-info AUXFILE -S -o /dev/null INFILE' at the end. */
static void
-munge_compile_params (params_list)
- const char *params_list;
+munge_compile_params (const char *params_list)
{
/* Build up the contents in a temporary vector
that is so big that to has to be big enough. */
const char **temp_params
- = (const char **) alloca ((strlen (params_list) + 8) * sizeof (char *));
+ = alloca ((strlen (params_list) + 8) * sizeof (char *));
int param_count = 0;
const char *param;
struct stat st;
@@ -1962,8 +1876,7 @@ munge_compile_params (params_list)
/* Make a copy of the compile_params in heap space. */
- compile_params
- = (const char **) xmalloc (sizeof (char *) * (param_count+1));
+ compile_params = xmalloc (sizeof (char *) * (param_count+1));
memcpy (compile_params, temp_params, sizeof (char *) * param_count);
}
@@ -1973,8 +1886,7 @@ munge_compile_params (params_list)
The result is a boolean indicating success. */
static int
-gen_aux_info_file (base_filename)
- const char *base_filename;
+gen_aux_info_file (const char *base_filename)
{
if (!input_file_name_index)
munge_compile_params ("");
@@ -2036,14 +1948,11 @@ gen_aux_info_file (base_filename)
Save all of the important stuff for later. */
static void
-process_aux_info_file (base_source_filename, keep_it, is_syscalls)
- const char *base_source_filename;
- int keep_it;
- int is_syscalls;
+process_aux_info_file (const char *base_source_filename, int keep_it,
+ int is_syscalls)
{
size_t base_len = strlen (base_source_filename);
- char * aux_info_filename
- = (char *) alloca (base_len + strlen (aux_info_suffix) + 1);
+ char * aux_info_filename = alloca (base_len + strlen (aux_info_suffix) + 1);
char *aux_info_base;
char *aux_info_limit;
char *aux_info_relocated_name;
@@ -2264,7 +2173,7 @@ start_over: ;
continue;
aux_info_second_line = p;
aux_info_relocated_name = 0;
- if (! is_abspath (invocation_filename))
+ if (! IS_ABSOLUTE_PATH (invocation_filename))
{
/* INVOCATION_FILENAME is relative;
append it to BASE_SOURCE_FILENAME's dir. */
@@ -2368,13 +2277,12 @@ start_over: ;
function implements the -C option. */
static void
-rename_c_file (hp)
- const hash_table_entry *hp;
+rename_c_file (const hash_table_entry *hp)
{
const char *filename = hp->symbol;
int last_char_index = strlen (filename) - 1;
- char *const new_filename = (char *) alloca (strlen (filename)
- + strlen (cplus_suffix) + 1);
+ char *const new_filename = alloca (strlen (filename)
+ + strlen (cplus_suffix) + 1);
/* Note that we don't care here if the given file was converted or not. It
is possible that the given file was *not* converted, simply because there
@@ -2411,8 +2319,7 @@ rename_c_file (hp)
order here. */
static void
-reverse_def_dec_list (hp)
- const hash_table_entry *hp;
+reverse_def_dec_list (const hash_table_entry *hp)
{
file_info *file_p = hp->fip;
def_dec_info *prev = NULL;
@@ -2453,9 +2360,7 @@ reverse_def_dec_list (hp)
contains all of the correct prototypes for system functions. */
static const def_dec_info *
-find_extern_def (head, user)
- const def_dec_info *head;
- const def_dec_info *user;
+find_extern_def (const def_dec_info *head, const def_dec_info *user)
{
const def_dec_info *dd_p;
const def_dec_info *extern_def_p = NULL;
@@ -2584,11 +2489,11 @@ find_extern_def (head, user)
{
/* Why copy this string into `needed' at all?
Why not just use user->ansi_decl without copying? */
- char *needed = (char *) alloca (strlen (user->ansi_decl) + 1);
+ char *needed = alloca (strlen (user->ansi_decl) + 1);
char *p;
strcpy (needed, user->ansi_decl);
- p = (NONCONST char *) substr (needed, user->hash_entry->symbol)
+ p = strstr (needed, user->hash_entry->symbol)
+ strlen (user->hash_entry->symbol) + 2;
/* Avoid having ??? in the string. */
*p++ = '?';
@@ -2616,8 +2521,7 @@ find_extern_def (head, user)
from the def_dec_info record pointer which is passed in. */
static const def_dec_info *
-find_static_definition (user)
- const def_dec_info *user;
+find_static_definition (const def_dec_info *user)
{
const def_dec_info *head = user->hash_entry->ddip;
const def_dec_info *dd_p;
@@ -2666,8 +2570,7 @@ find_static_definition (user)
more details. */
static void
-connect_defs_and_decs (hp)
- const hash_table_entry *hp;
+connect_defs_and_decs (const hash_table_entry *hp)
{
const def_dec_info *dd_p;
const def_dec_info *extern_def_p = NULL;
@@ -2791,8 +2694,7 @@ connect_defs_and_decs (hp)
original source line number that the given pointer points into. */
static int
-identify_lineno (clean_p)
- const char *clean_p;
+identify_lineno (const char *clean_p)
{
int line_num = 1;
const char *scan_p;
@@ -2806,8 +2708,7 @@ identify_lineno (clean_p)
/* Issue an error message and give up on doing this particular edit. */
static void
-declare_source_confusing (clean_p)
- const char *clean_p;
+declare_source_confusing (const char *clean_p)
{
if (!quiet_flag)
{
@@ -2827,9 +2728,7 @@ declare_source_confusing (clean_p)
converting this particular source file. */
static void
-check_source (cond, clean_p)
- int cond;
- const char *clean_p;
+check_source (int cond, const char *clean_p)
{
if (!cond)
declare_source_confusing (clean_p);
@@ -2851,8 +2750,7 @@ check_source (cond, clean_p)
of the in-core cleaned buffer again. */
static const char *
-seek_to_line (n)
- int n;
+seek_to_line (int n)
{
if (n < last_known_line_number)
abort ();
@@ -2871,8 +2769,7 @@ seek_to_line (n)
to the next non-whitespace character which follows it. */
static const char *
-forward_to_next_token_char (ptr)
- const char *ptr;
+forward_to_next_token_char (const char *ptr)
{
for (++ptr; ISSPACE ((const unsigned char)*ptr);
check_source (++ptr < clean_text_limit, 0))
@@ -2885,14 +2782,12 @@ forward_to_next_token_char (ptr)
buffer ultimately go through here. */
static void
-output_bytes (str, len)
- const char *str;
- size_t len;
+output_bytes (const char *str, size_t len)
{
if ((repl_write_ptr + 1) + len >= repl_text_limit)
{
size_t new_size = (repl_text_limit - repl_text_base) << 1;
- char *new_buf = (char *) xrealloc (repl_text_base, new_size);
+ char *new_buf = xrealloc (repl_text_base, new_size);
repl_write_ptr = new_buf + (repl_write_ptr - repl_text_base);
repl_text_base = new_buf;
@@ -2906,8 +2801,7 @@ output_bytes (str, len)
the current output buffer. */
static void
-output_string (str)
- const char *str;
+output_string (const char *str)
{
output_bytes (str, strlen (str));
}
@@ -2932,8 +2826,7 @@ output_string (str)
byte pointed to by the argument pointer `p'. */
static void
-output_up_to (p)
- const char *p;
+output_up_to (const char *p)
{
size_t copy_length = (size_t) (p - clean_read_ptr);
const char *copy_start = orig_text_base+(clean_read_ptr-clean_text_base)+1;
@@ -2952,15 +2845,14 @@ output_up_to (p)
otherwise. */
static int
-other_variable_style_function (ansi_header)
- const char *ansi_header;
+other_variable_style_function (const char *ansi_header)
{
#ifdef UNPROTOIZE
/* See if we have a stdarg function, or a function which has stdarg style
parameters or a stdarg style return type. */
- return substr (ansi_header, "...") != 0;
+ return strstr (ansi_header, "...") != 0;
#else /* !defined (UNPROTOIZE) */
@@ -2974,7 +2866,7 @@ other_variable_style_function (ansi_header)
{
const char *candidate;
- if ((candidate = substr (p, varargs_style_indicator)) == 0)
+ if ((candidate = strstr (p, varargs_style_indicator)) == 0)
return 0;
else
if (!is_id_char (candidate[-1]) && !is_id_char (candidate[len]))
@@ -2991,9 +2883,8 @@ other_variable_style_function (ansi_header)
below. */
static void
-edit_fn_declaration (def_dec_p, clean_text_p)
- const def_dec_info *def_dec_p;
- const char *volatile clean_text_p;
+edit_fn_declaration (const def_dec_info *def_dec_p,
+ const char *volatile clean_text_p)
{
const char *start_formals;
const char *end_formals;
@@ -3207,10 +3098,8 @@ edit_fn_declaration (def_dec_p, clean_text_p)
function doesn't match the one expected). */
static int
-edit_formals_lists (end_formals, f_list_count, def_dec_p)
- const char *end_formals;
- unsigned int f_list_count;
- const def_dec_info *def_dec_p;
+edit_formals_lists (const char *end_formals, unsigned int f_list_count,
+ const def_dec_info *def_dec_p)
{
const char *start_formals;
int depth;
@@ -3318,8 +3207,7 @@ edit_formals_lists (end_formals, f_list_count, def_dec_p)
definition header. */
static const char *
-find_rightmost_formals_list (clean_text_p)
- const char *clean_text_p;
+find_rightmost_formals_list (const char *clean_text_p)
{
const char *end_formals;
@@ -3436,9 +3324,7 @@ find_rightmost_formals_list (clean_text_p)
parameter type checking. */
static void
-add_local_decl (def_dec_p, clean_text_p)
- const def_dec_info *def_dec_p;
- const char *clean_text_p;
+add_local_decl (const def_dec_info *def_dec_p, const char *clean_text_p)
{
const char *start_of_block;
const char *function_to_edit = def_dec_p->hash_entry->symbol;
@@ -3543,9 +3429,7 @@ add_local_decl (def_dec_p, clean_text_p)
and then insert the new explicit declaration at that point in the file. */
static void
-add_global_decls (file_p, clean_text_p)
- const file_info *file_p;
- const char *clean_text_p;
+add_global_decls (const file_info *file_p, const char *clean_text_p)
{
const def_dec_info *dd_p;
const char *scan_p;
@@ -3634,9 +3518,7 @@ add_global_decls (file_p, clean_text_p)
separate routine above. */
static void
-edit_fn_definition (def_dec_p, clean_text_p)
- const def_dec_info *def_dec_p;
- const char *clean_text_p;
+edit_fn_definition (const def_dec_info *def_dec_p, const char *clean_text_p)
{
const char *end_formals;
const char *function_to_edit = def_dec_p->hash_entry->symbol;
@@ -3778,9 +3660,7 @@ edit_fn_definition (def_dec_p, clean_text_p)
into whitespace. Also, whiteout string and character literals. */
static void
-do_cleaning (new_clean_text_base, new_clean_text_limit)
- char *new_clean_text_base;
- const char *new_clean_text_limit;
+do_cleaning (char *new_clean_text_base, const char *new_clean_text_limit)
{
char *scan_p;
int non_whitespace_since_newline = 0;
@@ -3884,8 +3764,7 @@ regular:
and return a pointer to it. */
static const char *
-careful_find_l_paren (p)
- const char *p;
+careful_find_l_paren (const char *p)
{
const char *q;
int paren_depth;
@@ -3923,8 +3802,7 @@ careful_find_l_paren (p)
I will probably try to do this in a later version though. */
static void
-scan_for_missed_items (file_p)
- const file_info *file_p;
+scan_for_missed_items (const file_info *file_p)
{
static const char *scan_p;
const char *limit = clean_text_limit - 3;
@@ -3981,7 +3859,7 @@ scan_for_missed_items (file_p)
goto not_missed;
{
- char *func_name = (char *) alloca (id_length + 1);
+ char *func_name = alloca (id_length + 1);
static const char * const stmt_keywords[]
= { "if", "else", "do", "while", "for", "switch", "case", "return", 0 };
const char * const *stmt_keyword;
@@ -4039,8 +3917,7 @@ scan_for_missed_items (file_p)
preprocessing directives make the editing a whole lot easier. */
static void
-edit_file (hp)
- const hash_table_entry *hp;
+edit_file (const hash_table_entry *hp)
{
struct stat stat_buf;
const file_info *file_p = hp->fip;
@@ -4105,12 +3982,12 @@ edit_file (hp)
/* Allocate a buffer to hold the original text. */
- orig_text_base = new_orig_text_base = (char *) xmalloc (orig_size + 2);
+ orig_text_base = new_orig_text_base = xmalloc (orig_size + 2);
orig_text_limit = new_orig_text_limit = new_orig_text_base + orig_size;
/* Allocate a buffer to hold the cleaned-up version of the original text. */
- clean_text_base = new_clean_text_base = (char *) xmalloc (orig_size + 2);
+ clean_text_base = new_clean_text_base = xmalloc (orig_size + 2);
clean_text_limit = new_clean_text_limit = new_clean_text_base + orig_size;
clean_read_ptr = clean_text_base - 1;
@@ -4120,7 +3997,7 @@ edit_file (hp)
buffer can be expanded later as needed. */
repl_size = orig_size + (orig_size >> 2) + 4096;
- repl_text_base = (char *) xmalloc (repl_size + 2);
+ repl_text_base = xmalloc (repl_size + 2);
repl_text_limit = repl_text_base + repl_size - 1;
repl_write_ptr = repl_text_base - 1;
@@ -4178,7 +4055,7 @@ edit_file (hp)
{
int clean_file;
size_t clean_size = orig_text_limit - orig_text_base;
- char *const clean_filename = (char *) alloca (strlen (convert_filename) + 6 + 1);
+ char *const clean_filename = alloca (strlen (convert_filename) + 6 + 1);
/* Open (and create) the clean file. */
@@ -4278,7 +4155,7 @@ edit_file (hp)
if (!nosave_flag)
{
char *new_filename
- = (char *) xmalloc (strlen (convert_filename) + strlen (save_suffix) + 2);
+ = xmalloc (strlen (convert_filename) + strlen (save_suffix) + 2);
strcpy (new_filename, convert_filename);
#ifdef __MSDOS__
@@ -4379,7 +4256,7 @@ edit_file (hp)
in the command line. */
static void
-do_processing ()
+do_processing (void)
{
const char * const *base_pp;
const char * const * const end_pps
@@ -4405,8 +4282,8 @@ do_processing ()
if (nondefault_syscalls_dir)
{
syscalls_absolute_filename
- = (char *) xmalloc (strlen (nondefault_syscalls_dir) + 1
- + sizeof (syscalls_filename));
+ = xmalloc (strlen (nondefault_syscalls_dir) + 1
+ + sizeof (syscalls_filename));
strcpy (syscalls_absolute_filename, nondefault_syscalls_dir);
}
else
@@ -4417,10 +4294,10 @@ do_processing ()
default_syscalls_dir = standard_exec_prefix;
}
syscalls_absolute_filename
- = (char *) xmalloc (strlen (default_syscalls_dir) + 0
- + strlen (target_machine) + 1
- + strlen (target_version) + 1
- + sizeof (syscalls_filename));
+ = xmalloc (strlen (default_syscalls_dir) + 0
+ + strlen (target_machine) + 1
+ + strlen (target_version) + 1
+ + sizeof (syscalls_filename));
strcpy (syscalls_absolute_filename, default_syscalls_dir);
strcat (syscalls_absolute_filename, target_machine);
strcat (syscalls_absolute_filename, "/");
@@ -4504,12 +4381,10 @@ static const struct option longopts[] =
{0, 0, 0, 0}
};
-extern int main PARAMS ((int, char **const));
+extern int main (int, char **const);
int
-main (argc, argv)
- int argc;
- char **const argv;
+main (int argc, char **const argv)
{
int longind;
int c;
@@ -4625,7 +4500,7 @@ main (argc, argv)
/* Now actually make a list of the base source filenames. */
base_source_filenames
- = (const char **) xmalloc ((n_base_source_files + 1) * sizeof (char *));
+ = xmalloc ((n_base_source_files + 1) * sizeof (char *));
n_base_source_files = 0;
for (; optind < argc; optind++)
{
diff --git a/contrib/gcc/ra-build.c b/contrib/gcc/ra-build.c
index db2979a0120a..a305921c2508 100644
--- a/contrib/gcc/ra-build.c
+++ b/contrib/gcc/ra-build.c
@@ -1,5 +1,5 @@
/* Graph coloring register allocator
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Michael Matz <matz@suse.de>
and Daniel Berlin <dan@cgsoftware.com>
@@ -20,6 +20,8 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "insn-config.h"
@@ -34,7 +36,7 @@
#include "ggc.h"
#include "ra.h"
-/* This file is part of the graph coloring register alloctor.
+/* This file is part of the graph coloring register allocator.
It deals with building the interference graph. When rebuilding
the graph for a function after spilling, we rebuild only those
parts needed, i.e. it works incrementally.
@@ -46,7 +48,7 @@
conflicts. By connecting the uses and defs, which reach each other, webs
(or live ranges) are built conceptually.
- The second part (make_webs() and childs) deals with converting that
+ The second part (make_webs() and children) deals with converting that
structure to the nodes and edges, on which our interference graph is
built. For each root web part constructed above, an instance of struct
web is created. For all subregs of pseudos, which matter for allocation,
@@ -66,60 +68,59 @@
struct curr_use;
-static unsigned HOST_WIDE_INT rtx_to_undefined PARAMS ((rtx));
-static bitmap find_sub_conflicts PARAMS ((struct web_part *, unsigned int));
-static bitmap get_sub_conflicts PARAMS ((struct web_part *, unsigned int));
-static unsigned int undef_to_size_word PARAMS ((rtx, unsigned HOST_WIDE_INT *));
-static bitmap undef_to_bitmap PARAMS ((struct web_part *,
- unsigned HOST_WIDE_INT *));
-static struct web_part * find_web_part_1 PARAMS ((struct web_part *));
+static unsigned HOST_WIDE_INT rtx_to_undefined (rtx);
+static bitmap find_sub_conflicts (struct web_part *, unsigned int);
+static bitmap get_sub_conflicts (struct web_part *, unsigned int);
+static unsigned int undef_to_size_word (rtx, unsigned HOST_WIDE_INT *);
+static bitmap undef_to_bitmap (struct web_part *,
+ unsigned HOST_WIDE_INT *);
+static struct web_part * find_web_part_1 (struct web_part *);
static struct web_part * union_web_part_roots
- PARAMS ((struct web_part *, struct web_part *));
-static int defuse_overlap_p_1 PARAMS ((rtx, struct curr_use *));
-static int live_out_1 PARAMS ((struct df *, struct curr_use *, rtx));
-static int live_out PARAMS ((struct df *, struct curr_use *, rtx));
-static rtx live_in_edge PARAMS (( struct df *, struct curr_use *, edge));
-static void live_in PARAMS ((struct df *, struct curr_use *, rtx));
-static int copy_insn_p PARAMS ((rtx, rtx *, rtx *));
-static void remember_move PARAMS ((rtx));
-static void handle_asm_insn PARAMS ((struct df *, rtx));
-static void prune_hardregs_for_mode PARAMS ((HARD_REG_SET *,
- enum machine_mode));
-static void init_one_web_common PARAMS ((struct web *, rtx));
-static void init_one_web PARAMS ((struct web *, rtx));
-static void reinit_one_web PARAMS ((struct web *, rtx));
-static struct web * add_subweb PARAMS ((struct web *, rtx));
-static struct web * add_subweb_2 PARAMS ((struct web *, unsigned int));
-static void init_web_parts PARAMS ((struct df *));
-static void copy_conflict_list PARAMS ((struct web *));
-static void add_conflict_edge PARAMS ((struct web *, struct web *));
-static void build_inverse_webs PARAMS ((struct web *));
-static void copy_web PARAMS ((struct web *, struct web_link **));
-static void compare_and_free_webs PARAMS ((struct web_link **));
-static void init_webs_defs_uses PARAMS ((void));
-static unsigned int parts_to_webs_1 PARAMS ((struct df *, struct web_link **,
- struct df_link *));
-static void parts_to_webs PARAMS ((struct df *));
-static void reset_conflicts PARAMS ((void));
+ (struct web_part *, struct web_part *);
+static int defuse_overlap_p_1 (rtx, struct curr_use *);
+static int live_out_1 (struct df *, struct curr_use *, rtx);
+static int live_out (struct df *, struct curr_use *, rtx);
+static rtx live_in_edge ( struct df *, struct curr_use *, edge);
+static void live_in (struct df *, struct curr_use *, rtx);
+static int copy_insn_p (rtx, rtx *, rtx *);
+static void remember_move (rtx);
+static void handle_asm_insn (struct df *, rtx);
+static void prune_hardregs_for_mode (HARD_REG_SET *, enum machine_mode);
+static void init_one_web_common (struct web *, rtx);
+static void init_one_web (struct web *, rtx);
+static void reinit_one_web (struct web *, rtx);
+static struct web * add_subweb (struct web *, rtx);
+static struct web * add_subweb_2 (struct web *, unsigned int);
+static void init_web_parts (struct df *);
+static void copy_conflict_list (struct web *);
+static void add_conflict_edge (struct web *, struct web *);
+static void build_inverse_webs (struct web *);
+static void copy_web (struct web *, struct web_link **);
+static void compare_and_free_webs (struct web_link **);
+static void init_webs_defs_uses (void);
+static unsigned int parts_to_webs_1 (struct df *, struct web_link **,
+ struct df_link *);
+static void parts_to_webs (struct df *);
+static void reset_conflicts (void);
#if 0
-static void check_conflict_numbers PARAMS ((void));
+static void check_conflict_numbers (void)
#endif
-static void conflicts_between_webs PARAMS ((struct df *));
-static void remember_web_was_spilled PARAMS ((struct web *));
-static void detect_spill_temps PARAMS ((void));
-static int contains_pseudo PARAMS ((rtx));
-static int want_to_remat PARAMS ((rtx x));
-static void detect_remat_webs PARAMS ((void));
-static void determine_web_costs PARAMS ((void));
-static void detect_webs_set_in_cond_jump PARAMS ((void));
-static void make_webs PARAMS ((struct df *));
-static void moves_to_webs PARAMS ((struct df *));
-static void connect_rmw_web_parts PARAMS ((struct df *));
-static void update_regnos_mentioned PARAMS ((void));
-static void livethrough_conflicts_bb PARAMS ((basic_block));
-static void init_bb_info PARAMS ((void));
-static void free_bb_info PARAMS ((void));
-static void build_web_parts_and_conflicts PARAMS ((struct df *));
+static void conflicts_between_webs (struct df *);
+static void remember_web_was_spilled (struct web *);
+static void detect_spill_temps (void);
+static int contains_pseudo (rtx);
+static int want_to_remat (rtx x);
+static void detect_remat_webs (void);
+static void determine_web_costs (void);
+static void detect_webs_set_in_cond_jump (void);
+static void make_webs (struct df *);
+static void moves_to_webs (struct df *);
+static void connect_rmw_web_parts (struct df *);
+static void update_regnos_mentioned (void);
+static void livethrough_conflicts_bb (basic_block);
+static void init_bb_info (void);
+static void free_bb_info (void);
+static void build_web_parts_and_conflicts (struct df *);
/* A sbitmap of DF_REF_IDs of uses, which are live over an abnormal
@@ -179,8 +180,7 @@ struct ra_bb_info
as an integer. */
unsigned int
-rtx_to_bits (x)
- rtx x;
+rtx_to_bits (rtx x)
{
unsigned int len, beg;
len = GET_MODE_SIZE (GET_MODE (x));
@@ -191,8 +191,7 @@ rtx_to_bits (x)
/* X is a REG or SUBREG rtx. Return the bytes it touches as a bitmask. */
static unsigned HOST_WIDE_INT
-rtx_to_undefined (x)
- rtx x;
+rtx_to_undefined (rtx x)
{
unsigned int len, beg;
unsigned HOST_WIDE_INT ret;
@@ -223,10 +222,7 @@ int *number_seen;
not NULL. */
static int
-copy_insn_p (insn, source, target)
- rtx insn;
- rtx *source;
- rtx *target;
+copy_insn_p (rtx insn, rtx *source, rtx *target)
{
rtx d, s;
unsigned int d_regno, s_regno;
@@ -306,9 +302,7 @@ copy_insn_p (insn, source, target)
exist yet in WP. */
static bitmap
-find_sub_conflicts (wp, size_word)
- struct web_part *wp;
- unsigned int size_word;
+find_sub_conflicts (struct web_part *wp, unsigned int size_word)
{
struct tagged_conflict *cl;
cl = wp->sub_conflicts;
@@ -322,15 +316,12 @@ find_sub_conflicts (wp, size_word)
doesn't exist. I.e. this never returns NULL. */
static bitmap
-get_sub_conflicts (wp, size_word)
- struct web_part *wp;
- unsigned int size_word;
+get_sub_conflicts (struct web_part *wp, unsigned int size_word)
{
bitmap b = find_sub_conflicts (wp, size_word);
if (!b)
{
- struct tagged_conflict *cl =
- (struct tagged_conflict *) ra_alloc (sizeof *cl);
+ struct tagged_conflict *cl = ra_alloc (sizeof *cl);
cl->conflicts = BITMAP_XMALLOC ();
cl->size_word = size_word;
cl->next = wp->sub_conflicts;
@@ -367,7 +358,7 @@ static struct undef_table_s {
/* Interpret *UNDEFINED as bitmask where each bit corresponds to a byte.
A set bit means an undefined byte. Factor all undefined bytes into
groups, and return a size/ofs pair of consecutive undefined bytes,
- but according to certain borders. Clear out those bits corrsponding
+ but according to certain borders. Clear out those bits corresponding
to bytes overlaid by that size/ofs pair. REG is only used for
the mode, to detect if it's a floating mode or not.
@@ -381,9 +372,7 @@ static struct undef_table_s {
*/
static unsigned int
-undef_to_size_word (reg, undefined)
- rtx reg;
- unsigned HOST_WIDE_INT *undefined;
+undef_to_size_word (rtx reg, unsigned HOST_WIDE_INT *undefined)
{
/* When only the lower four bits are possibly set, we use
a fast lookup table. */
@@ -396,8 +385,9 @@ undef_to_size_word (reg, undefined)
}
/* Otherwise we handle certain cases directly. */
- switch (*undefined)
- {
+ if (*undefined <= 0xffff)
+ switch ((int) *undefined)
+ {
case 0x00f0 : *undefined = 0; return BL_TO_WORD (4, 4);
case 0x00ff : *undefined = 0; return BL_TO_WORD (0, 8);
case 0x0f00 : *undefined = 0; return BL_TO_WORD (8, 4);
@@ -411,29 +401,25 @@ undef_to_size_word (reg, undefined)
case 0xff00 : *undefined = 0; return BL_TO_WORD (8, 8);
case 0xfff0 : *undefined = 0xf0; return BL_TO_WORD (8, 8);
case 0xffff : *undefined = 0; return BL_TO_WORD (0, 16);
+ }
- /* And if nothing matched fall back to the general solution.
- For now unknown undefined bytes are converted to sequences
- of maximal length 4 bytes. We could make this larger if
- necessary. */
- default :
- {
- unsigned HOST_WIDE_INT u = *undefined;
- int word;
- struct undef_table_s tab;
- for (word = 0; (u & 15) == 0; word += 4)
- u >>= 4;
- u = u & 15;
- tab = undef_table[u];
- u = tab.new_undef;
- u = (*undefined & ~((unsigned HOST_WIDE_INT)15 << word))
- | (u << word);
- *undefined = u;
- /* Size remains the same, only the begin is moved up move bytes. */
- return tab.size_word + BL_TO_WORD (word, 0);
- }
- break;
- }
+ /* And if nothing matched fall back to the general solution. For
+ now unknown undefined bytes are converted to sequences of maximal
+ length 4 bytes. We could make this larger if necessary. */
+ {
+ unsigned HOST_WIDE_INT u = *undefined;
+ int word;
+ struct undef_table_s tab;
+ for (word = 0; (u & 15) == 0; word += 4)
+ u >>= 4;
+ u = u & 15;
+ tab = undef_table[u];
+ u = tab.new_undef;
+ u = (*undefined & ~((unsigned HOST_WIDE_INT)15 << word)) | (u << word);
+ *undefined = u;
+ /* Size remains the same, only the begin is moved up move bytes. */
+ return tab.size_word + BL_TO_WORD (word, 0);
+ }
}
/* Put the above three functions together. For a set of undefined bytes
@@ -442,9 +428,7 @@ undef_to_size_word (reg, undefined)
covered by the part for that bitmap. */
static bitmap
-undef_to_bitmap (wp, undefined)
- struct web_part *wp;
- unsigned HOST_WIDE_INT *undefined;
+undef_to_bitmap (struct web_part *wp, unsigned HOST_WIDE_INT *undefined)
{
unsigned int size_word = undef_to_size_word (DF_REF_REAL_REG (wp->ref),
undefined);
@@ -455,8 +439,7 @@ undef_to_bitmap (wp, undefined)
it compresses the path. P may not be NULL. */
static struct web_part *
-find_web_part_1 (p)
- struct web_part *p;
+find_web_part_1 (struct web_part *p)
{
struct web_part *r = p;
struct web_part *p_next;
@@ -482,14 +465,13 @@ find_web_part_1 (p)
The root of the resulting (possibly larger) web part is returned. */
static struct web_part *
-union_web_part_roots (r1, r2)
- struct web_part *r1, *r2;
+union_web_part_roots (struct web_part *r1, struct web_part *r2)
{
if (r1 != r2)
{
/* The new root is the smaller (pointerwise) of both. This is crucial
to make the construction of webs from web parts work (so, when
- scanning all parts, we see the roots before all it's childs).
+ scanning all parts, we see the roots before all its children).
Additionally this ensures, that if the web has a def at all, than
the root is a def (because all def parts are before use parts in the
web_parts[] array), or put another way, as soon, as the root of a
@@ -546,7 +528,7 @@ union_web_part_roots (r1, r2)
return r1;
}
-/* Convenience macro, that is cabable of unioning also non-roots. */
+/* Convenience macro, that is capable of unioning also non-roots. */
#define union_web_parts(p1, p2) \
((p1 == p2) ? find_web_part (p1) \
: union_web_part_roots (find_web_part (p1), find_web_part (p2)))
@@ -554,8 +536,7 @@ union_web_part_roots (r1, r2)
/* Remember that we've handled a given move, so we don't reprocess it. */
static void
-remember_move (insn)
- rtx insn;
+remember_move (rtx insn)
{
if (!TEST_BIT (move_handled, INSN_UID (insn)))
{
@@ -581,13 +562,13 @@ remember_move (insn)
/* XXX for now we don't remember move insns involving any subregs.
Those would be difficult to coalesce (we would need to implement
handling of all the subwebs in the allocator, including that such
- subwebs could be source and target of coalesing). */
+ subwebs could be source and target of coalescing). */
if (GET_CODE (s) == REG && GET_CODE (d) == REG)
{
- struct move *m = (struct move *) ra_calloc (sizeof (struct move));
+ struct move *m = ra_calloc (sizeof (struct move));
struct move_list *ml;
m->insn = insn;
- ml = (struct move_list *) ra_alloc (sizeof (struct move_list));
+ ml = ra_alloc (sizeof (struct move_list));
ml->move = m;
ml->next = wl_moves;
wl_moves = ml;
@@ -623,7 +604,7 @@ struct curr_use {
4 if both are SUBREG's of different size, but have bytes in common.
-1 is a special case, for when DEF and USE refer to the same regno, but
have for other reasons no bits in common (can only happen with
- subregs refering to different words, or to words which already were
+ subregs referring to different words, or to words which already were
defined for this USE).
Furthermore it modifies use->undefined to clear the bits which get defined
by DEF (only for cases with partial overlap).
@@ -631,9 +612,7 @@ struct curr_use {
otherwise a test is needed to track the already defined bytes. */
static int
-defuse_overlap_p_1 (def, use)
- rtx def;
- struct curr_use *use;
+defuse_overlap_p_1 (rtx def, struct curr_use *use)
{
int mode = 0;
if (def == use->x)
@@ -668,10 +647,10 @@ defuse_overlap_p_1 (def, use)
if they refer to the same word. */
if (SUBREG_BYTE (def) == SUBREG_BYTE (use->x))
return 1;
- /* Now the more difficult part: the same regno is refered, but the
+ /* Now the more difficult part: the same regno is referred, but the
sizes of the references or the words differ. E.g.
(subreg:SI (reg:CDI a) 0) and (subreg:DI (reg:CDI a) 2) do not
- overlap, wereas the latter overlaps with (subreg:SI (reg:CDI a) 3).
+ overlap, whereas the latter overlaps with (subreg:SI (reg:CDI a) 3).
*/
{
unsigned HOST_WIDE_INT old_u;
@@ -710,10 +689,7 @@ defuse_overlap_p_1 (def, use)
this insn. */
static int
-live_out_1 (df, use, insn)
- struct df *df ATTRIBUTE_UNUSED;
- struct curr_use *use;
- rtx insn;
+live_out_1 (struct df *df ATTRIBUTE_UNUSED, struct curr_use *use, rtx insn)
{
int defined = 0;
int uid = INSN_UID (insn);
@@ -865,10 +841,7 @@ live_out_1 (df, use, insn)
this insn). */
static inline int
-live_out (df, use, insn)
- struct df *df;
- struct curr_use *use;
- rtx insn;
+live_out (struct df *df, struct curr_use *use, rtx insn)
{
unsigned int uid = INSN_UID (insn);
if (visit_trace[uid].wp
@@ -896,10 +869,7 @@ live_out (df, use, insn)
which uses are live at the end of that basic block. */
static rtx
-live_in_edge (df, use, e)
- struct df *df;
- struct curr_use *use;
- edge e;
+live_in_edge (struct df *df, struct curr_use *use, edge e)
{
struct ra_bb_info *info_pred;
rtx next_insn;
@@ -914,7 +884,7 @@ live_in_edge (df, use, e)
use->live_over_abnormal = 1;
bitmap_set_bit (live_at_end[e->src->index], DF_REF_ID (use->wp->ref));
info_pred = (struct ra_bb_info *) e->src->aux;
- next_insn = e->src->end;
+ next_insn = BB_END (e->src);
/* If the last insn of the pred. block doesn't completely define the
current use, we need to check the block. */
@@ -929,7 +899,7 @@ live_in_edge (df, use, e)
creation to later. */
bitmap_set_bit (info_pred->live_throughout,
DF_REF_ID (use->wp->ref));
- next_insn = e->src->head;
+ next_insn = BB_HEAD (e->src);
}
return next_insn;
}
@@ -945,10 +915,7 @@ live_in_edge (df, use, e)
def-use chains, and all defs during that chain are noted. */
static void
-live_in (df, use, insn)
- struct df *df;
- struct curr_use *use;
- rtx insn;
+live_in (struct df *df, struct curr_use *use, rtx insn)
{
unsigned int loc_vpass = visited_pass;
@@ -962,7 +929,7 @@ live_in (df, use, insn)
basic_block bb = BLOCK_FOR_INSN (insn);
number_seen[uid]++;
- /* We want to be as fast as possible, so explicitely write
+ /* We want to be as fast as possible, so explicitly write
this loop. */
for (insn = PREV_INSN (insn); insn && !INSN_P (insn);
insn = PREV_INSN (insn))
@@ -1008,7 +975,7 @@ live_in (df, use, insn)
pass. */
static void
-update_regnos_mentioned ()
+update_regnos_mentioned (void)
{
int last_uid = last_max_uid;
rtx insn;
@@ -1044,14 +1011,13 @@ update_regnos_mentioned ()
}
}
-/* Handle the uses which reach a block end, but were defered due
+/* Handle the uses which reach a block end, but were deferred due
to it's regno not being mentioned in that block. This adds the
remaining conflicts and updates also the crosses_call and
spanned_deaths members. */
static void
-livethrough_conflicts_bb (bb)
- basic_block bb;
+livethrough_conflicts_bb (basic_block bb)
{
struct ra_bb_info *info = (struct ra_bb_info *) bb->aux;
rtx insn;
@@ -1060,14 +1026,14 @@ livethrough_conflicts_bb (bb)
unsigned int deaths = 0;
unsigned int contains_call = 0;
- /* If there are no defered uses, just return. */
+ /* If there are no deferred uses, just return. */
if ((first = bitmap_first_set_bit (info->live_throughout)) < 0)
return;
/* First collect the IDs of all defs, count the number of death
containing insns, and if there's some call_insn here. */
all_defs = BITMAP_XMALLOC ();
- for (insn = bb->head; insn; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); insn; insn = NEXT_INSN (insn))
{
if (INSN_P (insn))
{
@@ -1082,7 +1048,7 @@ livethrough_conflicts_bb (bb)
if (GET_CODE (insn) == CALL_INSN)
contains_call = 1;
}
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
}
@@ -1108,13 +1074,12 @@ livethrough_conflicts_bb (bb)
building live ranges. */
static void
-init_bb_info ()
+init_bb_info (void)
{
basic_block bb;
FOR_ALL_BB (bb)
{
- struct ra_bb_info *info =
- (struct ra_bb_info *) xcalloc (1, sizeof *info);
+ struct ra_bb_info *info = xcalloc (1, sizeof *info);
info->regnos_mentioned = BITMAP_XMALLOC ();
info->live_throughout = BITMAP_XMALLOC ();
info->old_aux = bb->aux;
@@ -1125,7 +1090,7 @@ init_bb_info ()
/* Free that per basic block info. */
static void
-free_bb_info ()
+free_bb_info (void)
{
basic_block bb;
FOR_ALL_BB (bb)
@@ -1139,20 +1104,18 @@ free_bb_info ()
}
/* Toplevel function for the first part of this file.
- Connect web parts, thereby implicitely building webs, and remember
+ Connect web parts, thereby implicitly building webs, and remember
their conflicts. */
static void
-build_web_parts_and_conflicts (df)
- struct df *df;
+build_web_parts_and_conflicts (struct df *df)
{
struct df_link *link;
struct curr_use use;
basic_block bb;
- number_seen = (int *) xcalloc (get_max_uid (), sizeof (int));
- visit_trace = (struct visit_trace *) xcalloc (get_max_uid (),
- sizeof (visit_trace[0]));
+ number_seen = xcalloc (get_max_uid (), sizeof (int));
+ visit_trace = xcalloc (get_max_uid (), sizeof (visit_trace[0]));
update_regnos_mentioned ();
/* Here's the main loop.
@@ -1202,8 +1165,7 @@ build_web_parts_and_conflicts (df)
read-mod-write instruction), so we must reconnect such webs. */
static void
-connect_rmw_web_parts (df)
- struct df *df;
+connect_rmw_web_parts (struct df *df)
{
unsigned int i;
@@ -1232,9 +1194,7 @@ connect_rmw_web_parts (df)
/* Deletes all hardregs from *S which are not allowed for MODE. */
static void
-prune_hardregs_for_mode (s, mode)
- HARD_REG_SET *s;
- enum machine_mode mode;
+prune_hardregs_for_mode (HARD_REG_SET *s, enum machine_mode mode)
{
AND_HARD_REG_SET (*s, hardregs_for_mode[(int) mode]);
}
@@ -1242,9 +1202,7 @@ prune_hardregs_for_mode (s, mode)
/* Initialize the members of a web, which are deducible from REG. */
static void
-init_one_web_common (web, reg)
- struct web *web;
- rtx reg;
+init_one_web_common (struct web *web, rtx reg)
{
if (GET_CODE (reg) != REG)
abort ();
@@ -1253,7 +1211,7 @@ init_one_web_common (web, reg)
web->orig_x = reg;
if (!web->dlink)
{
- web->dlink = (struct dlist *) ra_calloc (sizeof (struct dlist));
+ web->dlink = ra_calloc (sizeof (struct dlist));
DLIST_WEB (web->dlink) = web;
}
/* XXX
@@ -1306,10 +1264,9 @@ init_one_web_common (web, reg)
AND_COMPL_HARD_REG_SET (web->usable_regs, never_use_colors);
prune_hardregs_for_mode (&web->usable_regs,
PSEUDO_REGNO_MODE (web->regno));
-#ifdef CLASS_CANNOT_CHANGE_MODE
+#ifdef CANNOT_CHANGE_MODE_CLASS
if (web->mode_changed)
- AND_COMPL_HARD_REG_SET (web->usable_regs, reg_class_contents[
- (int) CLASS_CANNOT_CHANGE_MODE]);
+ AND_COMPL_HARD_REG_SET (web->usable_regs, invalid_mode_change_regs);
#endif
web->num_freedom = hard_regs_count (web->usable_regs);
web->num_freedom -= web->add_hardregs;
@@ -1322,9 +1279,7 @@ init_one_web_common (web, reg)
/* Initializes WEBs members from REG or zero them. */
static void
-init_one_web (web, reg)
- struct web *web;
- rtx reg;
+init_one_web (struct web *web, rtx reg)
{
memset (web, 0, sizeof (struct web));
init_one_web_common (web, reg);
@@ -1336,9 +1291,7 @@ init_one_web (web, reg)
members. */
static void
-reinit_one_web (web, reg)
- struct web *web;
- rtx reg;
+reinit_one_web (struct web *web, rtx reg)
{
web->old_color = web->color + 1;
init_one_web_common (web, reg);
@@ -1352,6 +1305,7 @@ reinit_one_web (web, reg)
web->artificial = 0;
web->live_over_abnormal = 0;
web->mode_changed = 0;
+ web->subreg_stripped = 0;
web->move_related = 0;
web->in_load = 0;
web->target_of_spilled_move = 0;
@@ -1378,14 +1332,12 @@ reinit_one_web (web, reg)
becomes its super web). It must not exist already. */
static struct web *
-add_subweb (web, reg)
- struct web *web;
- rtx reg;
+add_subweb (struct web *web, rtx reg)
{
struct web *w;
if (GET_CODE (reg) != SUBREG)
abort ();
- w = (struct web *) xmalloc (sizeof (struct web));
+ w = xmalloc (sizeof (struct web));
/* Copy most content from parent-web. */
*w = *web;
/* And initialize the private stuff. */
@@ -1406,9 +1358,7 @@ add_subweb (web, reg)
In difference to add_subweb() this marks the new subweb as artificial. */
static struct web *
-add_subweb_2 (web, size_word)
- struct web *web;
- unsigned int size_word;
+add_subweb_2 (struct web *web, unsigned int size_word)
{
/* To get a correct mode for the to be produced subreg, we don't want to
simply do a mode_for_size() for the mode_class of the whole web.
@@ -1435,8 +1385,7 @@ add_subweb_2 (web, size_word)
/* Initialize all the web parts we are going to need. */
static void
-init_web_parts (df)
- struct df *df;
+init_web_parts (struct df *df)
{
int regno;
unsigned int no;
@@ -1510,8 +1459,7 @@ init_web_parts (df)
new conflicts, we copy it here to orig_conflict_list. */
static void
-copy_conflict_list (web)
- struct web *web;
+copy_conflict_list (struct web *web)
{
struct conflict_link *cl;
if (web->orig_conflict_list || web->have_orig_conflicts)
@@ -1520,7 +1468,7 @@ copy_conflict_list (web)
for (cl = web->conflict_list; cl; cl = cl->next)
{
struct conflict_link *ncl;
- ncl = (struct conflict_link *) ra_alloc (sizeof *ncl);
+ ncl = ra_alloc (sizeof *ncl);
ncl->t = cl->t;
ncl->sub = NULL;
ncl->next = web->orig_conflict_list;
@@ -1530,7 +1478,7 @@ copy_conflict_list (web)
struct sub_conflict *sl, *nsl;
for (sl = cl->sub; sl; sl = sl->next)
{
- nsl = (struct sub_conflict *) ra_alloc (sizeof *nsl);
+ nsl = ra_alloc (sizeof *nsl);
nsl->s = sl->s;
nsl->t = sl->t;
nsl->next = ncl->sub;
@@ -1543,15 +1491,14 @@ copy_conflict_list (web)
/* Possibly add an edge from web FROM to TO marking a conflict between
those two. This is one half of marking a complete conflict, which notes
in FROM, that TO is a conflict. Adding TO to FROM's conflicts might
- make other conflicts superflous, because the current TO overlaps some web
+ make other conflicts superfluous, because the current TO overlaps some web
already being in conflict with FROM. In this case the smaller webs are
deleted from the conflict list. Likewise if TO is overlapped by a web
already in the list, it isn't added at all. Note, that this can only
happen, if SUBREG webs are involved. */
static void
-add_conflict_edge (from, to)
- struct web *from, *to;
+add_conflict_edge (struct web *from, struct web *to)
{
if (from->type != PRECOLORED)
{
@@ -1572,7 +1519,7 @@ add_conflict_edge (from, to)
copy_conflict_list (pfrom);
if (!TEST_BIT (sup_igraph, (pfrom->id * num_webs + pto->id)))
{
- cl = (struct conflict_link *) ra_alloc (sizeof (*cl));
+ cl = ra_alloc (sizeof (*cl));
cl->t = pto;
cl->sub = NULL;
cl->next = pfrom->conflict_list;
@@ -1597,7 +1544,7 @@ add_conflict_edge (from, to)
means we are not interested in this subconflict. */
if (!may_delete || cl->sub != NULL)
{
- sl = (struct sub_conflict *) ra_alloc (sizeof (*sl));
+ sl = ra_alloc (sizeof (*sl));
sl->s = from;
sl->t = to;
sl->next = cl->sub;
@@ -1616,8 +1563,7 @@ add_conflict_edge (from, to)
already. */
void
-record_conflict (web1, web2)
- struct web *web1, *web2;
+record_conflict (struct web *web1, struct web *web2)
{
unsigned int id1 = web1->id, id2 = web2->id;
unsigned int index = igraph_index (id1, id2);
@@ -1669,8 +1615,7 @@ record_conflict (web1, web2)
possible to exactly specify (W-Wy) for all already existing subwebs Wy. */
static void
-build_inverse_webs (web)
- struct web *web;
+build_inverse_webs (struct web *web)
{
struct web *sweb = web->subreg_next;
unsigned HOST_WIDE_INT undef;
@@ -1695,12 +1640,10 @@ build_inverse_webs (web)
Used for consistency checking. */
static void
-copy_web (web, wl)
- struct web *web;
- struct web_link **wl;
+copy_web (struct web *web, struct web_link **wl)
{
- struct web *cweb = (struct web *) xmalloc (sizeof *cweb);
- struct web_link *link = (struct web_link *) ra_alloc (sizeof *link);
+ struct web *cweb = xmalloc (sizeof *cweb);
+ struct web_link *link = ra_alloc (sizeof *link);
link->next = *wl;
*wl = link;
link->web = cweb;
@@ -1711,8 +1654,7 @@ copy_web (web, wl)
with the global webs of the same ID. For consistency checking. */
static void
-compare_and_free_webs (link)
- struct web_link **link;
+compare_and_free_webs (struct web_link **link)
{
struct web_link *wl;
for (wl = *link; wl; wl = wl->next)
@@ -1720,17 +1662,21 @@ compare_and_free_webs (link)
struct web *web1 = wl->web;
struct web *web2 = ID2WEB (web1->id);
if (web1->regno != web2->regno
- || web1->crosses_call != web2->crosses_call
- || web1->live_over_abnormal != web2->live_over_abnormal
|| web1->mode_changed != web2->mode_changed
|| !rtx_equal_p (web1->orig_x, web2->orig_x)
|| web1->type != web2->type
/* Only compare num_defs/num_uses with non-hardreg webs.
E.g. the number of uses of the framepointer changes due to
inserting spill code. */
- || (web1->type != PRECOLORED &&
- (web1->num_uses != web2->num_uses
- || web1->num_defs != web2->num_defs)))
+ || (web1->type != PRECOLORED
+ && (web1->num_uses != web2->num_uses
+ || web1->num_defs != web2->num_defs))
+ /* Similarly, if the framepointer was unreferenced originally
+ but we added spills, these fields may not match. */
+ || (web1->type != PRECOLORED
+ && web1->crosses_call != web2->crosses_call)
+ || (web1->type != PRECOLORED
+ && web1->live_over_abnormal != web2->live_over_abnormal))
abort ();
if (web1->type != PRECOLORED)
{
@@ -1757,7 +1703,7 @@ compare_and_free_webs (link)
/* Setup and fill uses[] and defs[] arrays of the webs. */
static void
-init_webs_defs_uses ()
+init_webs_defs_uses (void)
{
struct dlist *d;
for (d = WEBS(INITIAL); d; d = d->next)
@@ -1773,11 +1719,9 @@ init_webs_defs_uses ()
continue;
}
if (web->num_defs)
- web->defs = (struct ref **) xmalloc (web->num_defs *
- sizeof (web->defs[0]));
+ web->defs = xmalloc (web->num_defs * sizeof (web->defs[0]));
if (web->num_uses)
- web->uses = (struct ref **) xmalloc (web->num_uses *
- sizeof (web->uses[0]));
+ web->uses = xmalloc (web->num_uses * sizeof (web->uses[0]));
def_i = use_i = 0;
for (link = web->temp_refs; link; link = link->next)
{
@@ -1797,10 +1741,8 @@ init_webs_defs_uses ()
up use2web and def2web arrays. */
static unsigned int
-parts_to_webs_1 (df, copy_webs, all_refs)
- struct df *df;
- struct web_link **copy_webs;
- struct df_link *all_refs;
+parts_to_webs_1 (struct df *df, struct web_link **copy_webs,
+ struct df_link *all_refs)
{
unsigned int i;
unsigned int webnum;
@@ -1837,7 +1779,7 @@ parts_to_webs_1 (df, copy_webs, all_refs)
allocate a new one. */
if (ra_pass == 1)
{
- web = (struct web *) xmalloc (sizeof (struct web));
+ web = xmalloc (sizeof (struct web));
newid = last_num_webs++;
init_one_web (web, GET_CODE (reg) == SUBREG
? SUBREG_REG (reg) : reg);
@@ -1870,7 +1812,7 @@ parts_to_webs_1 (df, copy_webs, all_refs)
else
{
/* Else allocate a new one. */
- web = (struct web *) xmalloc (sizeof (struct web));
+ web = xmalloc (sizeof (struct web));
newid = last_num_webs++;
}
}
@@ -1909,6 +1851,9 @@ parts_to_webs_1 (df, copy_webs, all_refs)
if ((DF_REF_FLAGS (ref) & DF_REF_MODE_CHANGE) != 0
&& web->regno >= FIRST_PSEUDO_REGISTER)
web->mode_changed = 1;
+ if ((DF_REF_FLAGS (ref) & DF_REF_STRIPPED) != 0
+ && web->regno >= FIRST_PSEUDO_REGISTER)
+ web->subreg_stripped = 1;
if (i >= def_id
&& TEST_BIT (live_over_abnormal, ref_id))
web->live_over_abnormal = 1;
@@ -1958,6 +1903,9 @@ parts_to_webs_1 (df, copy_webs, all_refs)
if ((DF_REF_FLAGS (ref) & DF_REF_MODE_CHANGE) != 0
&& web->regno >= FIRST_PSEUDO_REGISTER)
web->mode_changed = 1;
+ if ((DF_REF_FLAGS (ref) & DF_REF_STRIPPED) != 0
+ && web->regno >= FIRST_PSEUDO_REGISTER)
+ web->subreg_stripped = 1;
/* Setup def2web, or use2web, and increment num_defs or num_uses. */
if (i < def_id)
@@ -2012,8 +1960,7 @@ parts_to_webs_1 (df, copy_webs, all_refs)
other (i.e. without creating the conflict edges). */
static void
-parts_to_webs (df)
- struct df *df;
+parts_to_webs (struct df *df)
{
unsigned int i;
unsigned int webnum;
@@ -2023,8 +1970,7 @@ parts_to_webs (df)
num_subwebs = 0;
/* First build webs and ordinary subwebs. */
- all_refs = (struct df_link *) xcalloc (df->def_id + df->use_id,
- sizeof (all_refs[0]));
+ all_refs = xcalloc (df->def_id + df->use_id, sizeof (all_refs[0]));
webnum = parts_to_webs_1 (df, &copy_webs, all_refs);
/* Setup the webs for hardregs which are still missing (weren't
@@ -2032,7 +1978,7 @@ parts_to_webs (df)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (!hardreg2web[i])
{
- struct web *web = (struct web *) xmalloc (sizeof (struct web));
+ struct web *web = xmalloc (sizeof (struct web));
init_one_web (web, gen_rtx_REG (reg_raw_mode[i], i));
web->id = last_num_webs++;
hardreg2web[web->regno] = web;
@@ -2080,7 +2026,7 @@ parts_to_webs (df)
}
/* Now that everyone has an ID, we can setup the id2web array. */
- id2web = (struct web **) xcalloc (webnum, sizeof (id2web[0]));
+ id2web = xcalloc (webnum, sizeof (id2web[0]));
for (d = WEBS(INITIAL); d; d = d->next)
{
struct web *web = DLIST_WEB (d);
@@ -2098,7 +2044,7 @@ parts_to_webs (df)
sbitmap_zero (igraph);
sbitmap_zero (sup_igraph);
- /* Distibute the references to their webs. */
+ /* Distribute the references to their webs. */
init_webs_defs_uses ();
/* And do some sanity checks if old webs, and those recreated from the
really are the same. */
@@ -2112,7 +2058,7 @@ parts_to_webs (df)
conflicts. */
static void
-reset_conflicts ()
+reset_conflicts (void)
{
unsigned int i;
bitmap newwebs = BITMAP_XMALLOC ();
@@ -2147,7 +2093,7 @@ reset_conflicts ()
{
*pcl = NULL;
/* Useless conflicts will be rebuilt completely. But check
- for cleanlyness, as the web might have come from the
+ for cleanliness, as the web might have come from the
free list. */
if (bitmap_first_set_bit (web->useless_conflicts) >= 0)
abort ();
@@ -2194,7 +2140,7 @@ reset_conflicts ()
#if 0
static void
-check_conflict_numbers ()
+check_conflict_numbers (void)
{
unsigned int i;
for (i = 0; i < num_webs; i++)
@@ -2225,8 +2171,7 @@ check_conflict_numbers ()
in reality conflict get the same color. */
static void
-conflicts_between_webs (df)
- struct df *df;
+conflicts_between_webs (struct df *df)
{
unsigned int i;
#ifdef STACK_REGS
@@ -2234,7 +2179,7 @@ conflicts_between_webs (df)
#endif
bitmap ignore_defs = BITMAP_XMALLOC ();
unsigned int have_ignored;
- unsigned int *pass_cache = (unsigned int *) xcalloc (num_webs, sizeof (int));
+ unsigned int *pass_cache = xcalloc (num_webs, sizeof (int));
unsigned int pass = 0;
if (ra_pass > 1)
@@ -2324,8 +2269,7 @@ conflicts_between_webs (df)
accordingly. */
static void
-remember_web_was_spilled (web)
- struct web *web;
+remember_web_was_spilled (struct web *web)
{
int i;
unsigned int found_size = 0;
@@ -2361,10 +2305,9 @@ remember_web_was_spilled (web)
reg_class_contents[(int) GENERAL_REGS]);
AND_COMPL_HARD_REG_SET (web->usable_regs, never_use_colors);
prune_hardregs_for_mode (&web->usable_regs, PSEUDO_REGNO_MODE (web->regno));
-#ifdef CLASS_CANNOT_CHANGE_MODE
+#ifdef CANNOT_CHANGE_MODE_CLASS
if (web->mode_changed)
- AND_COMPL_HARD_REG_SET (web->usable_regs, reg_class_contents[
- (int) CLASS_CANNOT_CHANGE_MODE]);
+ AND_COMPL_HARD_REG_SET (web->usable_regs, invalid_mode_change_regs);
#endif
web->num_freedom = hard_regs_count (web->usable_regs);
if (!web->num_freedom)
@@ -2406,7 +2349,7 @@ remember_web_was_spilled (web)
if it will be spillable in this pass. */
static void
-detect_spill_temps ()
+detect_spill_temps (void)
{
struct dlist *d;
bitmap already = BITMAP_XMALLOC ();
@@ -2427,7 +2370,7 @@ detect_spill_temps ()
continue;
/* A web with only defs and no uses can't be spilled. Nevertheless
- it must get a color, as it takes away an register from all webs
+ it must get a color, as it takes away a register from all webs
live at these defs. So we make it a short web. */
if (web->num_uses == 0)
web->spill_temp = 3;
@@ -2510,8 +2453,7 @@ detect_spill_temps ()
/* Returns nonzero if the rtx MEM refers somehow to a stack location. */
int
-memref_is_stack_slot (mem)
- rtx mem;
+memref_is_stack_slot (rtx mem)
{
rtx ad = XEXP (mem, 0);
rtx x;
@@ -2528,8 +2470,7 @@ memref_is_stack_slot (mem)
/* Returns nonzero, if rtx X somewhere contains any pseudo register. */
static int
-contains_pseudo (x)
- rtx x;
+contains_pseudo (rtx x)
{
const char *fmt;
int i;
@@ -2567,8 +2508,7 @@ contains_pseudo (x)
static GTY(()) rtx remat_test_insn;
static int
-want_to_remat (x)
- rtx x;
+want_to_remat (rtx x)
{
int num_clobbers = 0;
int icode;
@@ -2606,7 +2546,7 @@ want_to_remat (x)
and that value is simple enough, and want_to_remat() holds for it. */
static void
-detect_remat_webs ()
+detect_remat_webs (void)
{
struct dlist *d;
for (d = WEBS(INITIAL); d; d = d->next)
@@ -2651,7 +2591,7 @@ detect_remat_webs ()
oldwebs can't have their references changed. The
incremental machinery barfs on that. */
|| (!rtx_unstable_p (src) && !contains_pseudo (src))
- /* Additionally also memrefs to stack-slots are usefull, when
+ /* Additionally also memrefs to stack-slots are useful, when
we created them ourself. They might not have set their
unchanging flag set, but nevertheless they are stable across
the livetime in question. */
@@ -2673,7 +2613,7 @@ detect_remat_webs ()
/* Determine the spill costs of all webs. */
static void
-determine_web_costs ()
+determine_web_costs (void)
{
struct dlist *d;
for (d = WEBS(INITIAL); d; d = d->next)
@@ -2730,14 +2670,14 @@ determine_web_costs ()
which destroys the CFG. (Somewhen we want to deal with that XXX) */
static void
-detect_webs_set_in_cond_jump ()
+detect_webs_set_in_cond_jump (void)
{
basic_block bb;
FOR_EACH_BB (bb)
- if (GET_CODE (bb->end) == JUMP_INSN)
+ if (GET_CODE (BB_END (bb)) == JUMP_INSN)
{
struct df_link *link;
- for (link = DF_INSN_DEFS (df, bb->end); link; link = link->next)
+ for (link = DF_INSN_DEFS (df, BB_END (bb)); link; link = link->next)
if (link->ref && DF_REF_REGNO (link->ref) >= FIRST_PSEUDO_REGISTER)
{
struct web *web = def2web[DF_REF_ID (link->ref)];
@@ -2753,8 +2693,7 @@ detect_webs_set_in_cond_jump ()
though. */
static void
-make_webs (df)
- struct df *df;
+make_webs (struct df *df)
{
/* First build all the webs itself. They are not related with
others yet. */
@@ -2772,8 +2711,7 @@ make_webs (df)
/* Distribute moves to the corresponding webs. */
static void
-moves_to_webs (df)
- struct df *df;
+moves_to_webs (struct df *df)
{
struct df_link *link;
struct move_list *ml;
@@ -2823,8 +2761,7 @@ moves_to_webs (df)
for (; test && test->move != m; test = test->next);
if (! test)
{
- newml = (struct move_list*)
- ra_alloc (sizeof (struct move_list));
+ newml = ra_alloc (sizeof (struct move_list));
newml->move = m;
newml->next = m->source_web->moves;
m->source_web->moves = newml;
@@ -2833,8 +2770,7 @@ moves_to_webs (df)
for (; test && test->move != m; test = test->next);
if (! test)
{
- newml = (struct move_list*)
- ra_alloc (sizeof (struct move_list));
+ newml = ra_alloc (sizeof (struct move_list));
newml->move = m;
newml->next = m->target_web->moves;
m->target_web->moves = newml;
@@ -2853,9 +2789,7 @@ moves_to_webs (df)
and constrain the allocator too much. */
static void
-handle_asm_insn (df, insn)
- struct df *df;
- rtx insn;
+handle_asm_insn (struct df *df, rtx insn)
{
const char *constraints[MAX_RECOG_OPERANDS];
enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
@@ -2931,13 +2865,13 @@ handle_asm_insn (df, insn)
CLEAR_HARD_REG_SET (allowed);
while (1)
{
- char c = *p++;
+ char c = *p;
if (c == '\0' || c == ',' || c == '#')
{
/* End of one alternative - mark the regs in the current
- class, and reset the class.
- */
+ class, and reset the class. */
+ p++;
IOR_HARD_REG_SET (allowed, reg_class_contents[cls]);
if (cls != NO_REGS)
nothing_allowed = 0;
@@ -2975,15 +2909,17 @@ handle_asm_insn (df, insn)
default:
cls =
(int) reg_class_subunion[cls][(int)
- REG_CLASS_FROM_LETTER (c)];
+ REG_CLASS_FROM_CONSTRAINT (c,
+ p)];
}
+ p += CONSTRAINT_LEN (c, p);
}
/* Now make conflicts between this web, and all hardregs, which
are not allowed by the constraints. */
if (nothing_allowed)
{
- /* If we had no real constraints nothing was explicitely
+ /* If we had no real constraints nothing was explicitly
allowed, so we allow the whole class (i.e. we make no
additional conflicts). */
CLEAR_HARD_REG_SET (conflict);
@@ -3025,8 +2961,7 @@ handle_asm_insn (df, insn)
and conflicts. */
void
-build_i_graph (df)
- struct df *df;
+build_i_graph (struct df *df)
{
rtx insn;
@@ -3053,14 +2988,13 @@ build_i_graph (df)
}
/* Allocates or reallocates most memory for the interference graph and
- assiciated structures. If it reallocates memory (meaning, this is not
+ associated structures. If it reallocates memory (meaning, this is not
the first pass), this also changes some structures to reflect the
additional entries in various array, and the higher number of
defs and uses. */
void
-ra_build_realloc (df)
- struct df *df;
+ra_build_realloc (struct df *df)
{
struct web_part *last_web_parts = web_parts;
struct web **last_def2web = def2web;
@@ -3069,10 +3003,8 @@ ra_build_realloc (df)
unsigned int i;
struct dlist *d;
move_handled = sbitmap_alloc (get_max_uid () );
- web_parts = (struct web_part *) xcalloc (df->def_id + df->use_id,
- sizeof web_parts[0]);
- def2web = (struct web **) xcalloc (df->def_id + df->use_id,
- sizeof def2web[0]);
+ web_parts = xcalloc (df->def_id + df->use_id, sizeof web_parts[0]);
+ def2web = xcalloc (df->def_id + df->use_id, sizeof def2web[0]);
use2web = &def2web[df->def_id];
live_over_abnormal = sbitmap_alloc (df->use_id);
sbitmap_zero (live_over_abnormal);
@@ -3162,14 +3094,12 @@ ra_build_realloc (df)
if (!last_max_uid)
{
/* Setup copy cache, for copy_insn_p (). */
- copy_cache = (struct copy_p_cache *)
- xcalloc (get_max_uid (), sizeof (copy_cache[0]));
+ copy_cache = xcalloc (get_max_uid (), sizeof (copy_cache[0]));
init_bb_info ();
}
else
{
- copy_cache = (struct copy_p_cache *)
- xrealloc (copy_cache, get_max_uid () * sizeof (copy_cache[0]));
+ copy_cache = xrealloc (copy_cache, get_max_uid () * sizeof (copy_cache[0]));
memset (&copy_cache[last_max_uid], 0,
(get_max_uid () - last_max_uid) * sizeof (copy_cache[0]));
}
@@ -3178,7 +3108,7 @@ ra_build_realloc (df)
/* Free up/clear some memory, only needed for one pass. */
void
-ra_build_free ()
+ra_build_free (void)
{
struct dlist *d;
unsigned int i;
@@ -3238,8 +3168,7 @@ ra_build_free ()
/* Free all memory for the interference graph structures. */
void
-ra_build_free_all (df)
- struct df *df;
+ra_build_free_all (struct df *df)
{
unsigned int i;
diff --git a/contrib/gcc/ra-colorize.c b/contrib/gcc/ra-colorize.c
index 5db6474447c7..fd4660ab9e0a 100644
--- a/contrib/gcc/ra-colorize.c
+++ b/contrib/gcc/ra-colorize.c
@@ -20,6 +20,8 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "function.h"
@@ -45,54 +47,54 @@
Additionally there is a custom step to locally improve the overall
spill cost of the colored graph (recolor_spills). */
-static void push_list PARAMS ((struct dlist *, struct dlist **));
-static void push_list_end PARAMS ((struct dlist *, struct dlist **));
-static void free_dlist PARAMS ((struct dlist **));
-static void put_web_at_end PARAMS ((struct web *, enum node_type));
-static void put_move PARAMS ((struct move *, enum move_type));
-static void build_worklists PARAMS ((struct df *));
-static void enable_move PARAMS ((struct web *));
-static void decrement_degree PARAMS ((struct web *, int));
-static void simplify PARAMS ((void));
-static void remove_move_1 PARAMS ((struct web *, struct move *));
-static void remove_move PARAMS ((struct web *, struct move *));
-static void add_worklist PARAMS ((struct web *));
-static int ok PARAMS ((struct web *, struct web *));
-static int conservative PARAMS ((struct web *, struct web *));
-static inline unsigned int simplify_p PARAMS ((enum node_type));
-static void combine PARAMS ((struct web *, struct web *));
-static void coalesce PARAMS ((void));
-static void freeze_moves PARAMS ((struct web *));
-static void freeze PARAMS ((void));
-static void select_spill PARAMS ((void));
-static int color_usable_p PARAMS ((int, HARD_REG_SET, HARD_REG_SET,
- enum machine_mode));
-int get_free_reg PARAMS ((HARD_REG_SET, HARD_REG_SET, enum machine_mode));
-static int get_biased_reg PARAMS ((HARD_REG_SET, HARD_REG_SET, HARD_REG_SET,
- HARD_REG_SET, enum machine_mode));
-static int count_long_blocks PARAMS ((HARD_REG_SET, int));
-static char * hardregset_to_string PARAMS ((HARD_REG_SET));
-static void calculate_dont_begin PARAMS ((struct web *, HARD_REG_SET *));
-static void colorize_one_web PARAMS ((struct web *, int));
-static void assign_colors PARAMS ((void));
-static void try_recolor_web PARAMS ((struct web *));
-static void insert_coalesced_conflicts PARAMS ((void));
-static int comp_webs_maxcost PARAMS ((const void *, const void *));
-static void recolor_spills PARAMS ((void));
-static void check_colors PARAMS ((void));
-static void restore_conflicts_from_coalesce PARAMS ((struct web *));
-static void break_coalesced_spills PARAMS ((void));
-static void unalias_web PARAMS ((struct web *));
-static void break_aliases_to_web PARAMS ((struct web *));
-static void break_precolored_alias PARAMS ((struct web *));
-static void init_web_pairs PARAMS ((void));
-static void add_web_pair_cost PARAMS ((struct web *, struct web *,
- unsigned HOST_WIDE_INT, unsigned int));
-static int comp_web_pairs PARAMS ((const void *, const void *));
-static void sort_and_combine_web_pairs PARAMS ((int));
-static void aggressive_coalesce PARAMS ((void));
-static void extended_coalesce_2 PARAMS ((void));
-static void check_uncoalesced_moves PARAMS ((void));
+static void push_list (struct dlist *, struct dlist **);
+static void push_list_end (struct dlist *, struct dlist **);
+static void free_dlist (struct dlist **);
+static void put_web_at_end (struct web *, enum node_type);
+static void put_move (struct move *, enum move_type);
+static void build_worklists (struct df *);
+static void enable_move (struct web *);
+static void decrement_degree (struct web *, int);
+static void simplify (void);
+static void remove_move_1 (struct web *, struct move *);
+static void remove_move (struct web *, struct move *);
+static void add_worklist (struct web *);
+static int ok (struct web *, struct web *);
+static int conservative (struct web *, struct web *);
+static inline unsigned int simplify_p (enum node_type);
+static void combine (struct web *, struct web *);
+static void coalesce (void);
+static void freeze_moves (struct web *);
+static void freeze (void);
+static void select_spill (void);
+static int color_usable_p (int, HARD_REG_SET, HARD_REG_SET,
+ enum machine_mode);
+int get_free_reg (HARD_REG_SET, HARD_REG_SET, enum machine_mode);
+static int get_biased_reg (HARD_REG_SET, HARD_REG_SET, HARD_REG_SET,
+ HARD_REG_SET, enum machine_mode);
+static int count_long_blocks (HARD_REG_SET, int);
+static char * hardregset_to_string (HARD_REG_SET);
+static void calculate_dont_begin (struct web *, HARD_REG_SET *);
+static void colorize_one_web (struct web *, int);
+static void assign_colors (void);
+static void try_recolor_web (struct web *);
+static void insert_coalesced_conflicts (void);
+static int comp_webs_maxcost (const void *, const void *);
+static void recolor_spills (void);
+static void check_colors (void);
+static void restore_conflicts_from_coalesce (struct web *);
+static void break_coalesced_spills (void);
+static void unalias_web (struct web *);
+static void break_aliases_to_web (struct web *);
+static void break_precolored_alias (struct web *);
+static void init_web_pairs (void);
+static void add_web_pair_cost (struct web *, struct web *,
+ unsigned HOST_WIDE_INT, unsigned int);
+static int comp_web_pairs (const void *, const void *);
+static void sort_and_combine_web_pairs (int);
+static void aggressive_coalesce (void);
+static void extended_coalesce_2 (void);
+static void check_uncoalesced_moves (void);
static struct dlist *mv_worklist, *mv_coalesced, *mv_constrained;
static struct dlist *mv_frozen, *mv_active;
@@ -100,9 +102,7 @@ static struct dlist *mv_frozen, *mv_active;
/* Push a node onto the front of the list. */
static void
-push_list (x, list)
- struct dlist *x;
- struct dlist **list;
+push_list (struct dlist *x, struct dlist **list)
{
if (x->next || x->prev)
abort ();
@@ -113,9 +113,7 @@ push_list (x, list)
}
static void
-push_list_end (x, list)
- struct dlist *x;
- struct dlist **list;
+push_list_end (struct dlist *x, struct dlist **list)
{
if (x->prev || x->next)
abort ();
@@ -133,9 +131,7 @@ push_list_end (x, list)
/* Remove a node from the list. */
void
-remove_list (x, list)
- struct dlist *x;
- struct dlist **list;
+remove_list (struct dlist *x, struct dlist **list)
{
struct dlist *y = x->prev;
if (y)
@@ -151,8 +147,7 @@ remove_list (x, list)
/* Pop the front of the list. */
struct dlist *
-pop_list (list)
- struct dlist **list;
+pop_list (struct dlist **list)
{
struct dlist *r = *list;
if (r)
@@ -163,8 +158,7 @@ pop_list (list)
/* Free the given double linked list. */
static void
-free_dlist (list)
- struct dlist **list;
+free_dlist (struct dlist **list)
{
*list = NULL;
}
@@ -174,9 +168,7 @@ free_dlist (list)
Inline, because it's called with constant TYPE every time. */
inline void
-put_web (web, type)
- struct web *web;
- enum node_type type;
+put_web (struct web *web, enum node_type type)
{
switch (type)
{
@@ -214,7 +206,7 @@ put_web (web, type)
they are coalesced to. */
void
-reset_lists ()
+reset_lists (void)
{
struct dlist *d;
unsigned int i;
@@ -268,9 +260,7 @@ reset_lists ()
list. Additionally TYPE may not be SIMPLIFY. */
static void
-put_web_at_end (web, type)
- struct web *web;
- enum node_type type;
+put_web_at_end (struct web *web, enum node_type type)
{
if (type == PRECOLORED)
type = INITIAL;
@@ -284,8 +274,7 @@ put_web_at_end (web, type)
its current type). */
void
-remove_web_from_list (web)
- struct web *web;
+remove_web_from_list (struct web *web)
{
if (web->type == PRECOLORED)
remove_list (web->dlink, &WEBS(INITIAL));
@@ -296,9 +285,7 @@ remove_web_from_list (web)
/* Give MOVE the TYPE, and link it into the correct list. */
static inline void
-put_move (move, type)
- struct move *move;
- enum move_type type;
+put_move (struct move *move, enum move_type type)
{
switch (type)
{
@@ -326,8 +313,7 @@ put_move (move, type)
/* Build the worklists we are going to process. */
static void
-build_worklists (df)
- struct df *df ATTRIBUTE_UNUSED;
+build_worklists (struct df *df ATTRIBUTE_UNUSED)
{
struct dlist *d, *d_next;
struct move_list *ml;
@@ -336,7 +322,7 @@ build_worklists (df)
backed by a new pseudo, but conceptually can stand for a stackslot,
i.e. it doesn't really matter if they get a color or not), on
the SELECT stack first, those with lowest cost first. This way
- they will be colored last, so do not contrain the coloring of the
+ they will be colored last, so do not constrain the coloring of the
normal webs. But still those with the highest count are colored
before, i.e. get a color more probable. The use of stackregs is
a pure optimization, and all would work, if we used real stackslots
@@ -346,7 +332,7 @@ build_worklists (df)
unsigned int i, num, max_num;
struct web **order2web;
max_num = num_webs - num_subwebs;
- order2web = (struct web **) xmalloc (max_num * sizeof (order2web[0]));
+ order2web = xmalloc (max_num * sizeof (order2web[0]));
for (i = 0, num = 0; i < max_num; i++)
if (id2web[i]->regno >= max_normal_pseudo)
order2web[num++] = id2web[i];
@@ -395,7 +381,7 @@ build_worklists (df)
if (ml->move)
{
struct move *m = ml->move;
- d = (struct dlist *) ra_calloc (sizeof (struct dlist));
+ d = ra_calloc (sizeof (struct dlist));
DLIST_MOVE (d) = m;
m->dlink = d;
put_move (m, WORKLIST);
@@ -405,8 +391,7 @@ build_worklists (df)
/* Enable the active moves, in which WEB takes part, to be processed. */
static void
-enable_move (web)
- struct web *web;
+enable_move (struct web *web)
{
struct move_list *ml;
for (ml = web->moves; ml; ml = ml->next)
@@ -422,9 +407,7 @@ enable_move (web)
now smaller than its freedom. */
static void
-decrement_degree (web, dec)
- struct web *web;
- int dec;
+decrement_degree (struct web *web, int dec)
{
int before = web->num_conflicts;
web->num_conflicts -= dec;
@@ -452,7 +435,7 @@ decrement_degree (web, dec)
/* Repeatedly simplify the nodes on the simplify worklists. */
static void
-simplify ()
+simplify (void)
{
struct dlist *d;
struct web *web;
@@ -491,9 +474,7 @@ simplify ()
/* Helper function to remove a move from the movelist of the web. */
static void
-remove_move_1 (web, move)
- struct web *web;
- struct move *move;
+remove_move_1 (struct web *web, struct move *move)
{
struct move_list *ml = web->moves;
if (!ml)
@@ -514,9 +495,7 @@ remove_move_1 (web, move)
not in the list anymore. */
static void
-remove_move (web, move)
- struct web *web;
- struct move *move;
+remove_move (struct web *web, struct move *move)
{
struct move_list *ml;
remove_move_1 (web, move);
@@ -528,8 +507,7 @@ remove_move (web, move)
/* Merge the moves for the two webs into the first web's movelist. */
void
-merge_moves (u, v)
- struct web *u, *v;
+merge_moves (struct web *u, struct web *v)
{
regset seen;
struct move_list *ml, *ml_next;
@@ -553,8 +531,7 @@ merge_moves (u, v)
/* Add a web to the simplify worklist, from the freeze worklist. */
static void
-add_worklist (web)
- struct web *web;
+add_worklist (struct web *web)
{
if (web->type != PRECOLORED && !web->moves
&& web->num_conflicts < NUM_REGS (web))
@@ -567,8 +544,7 @@ add_worklist (web)
/* Precolored node coalescing heuristic. */
static int
-ok (target, source)
- struct web *target, *source;
+ok (struct web *target, struct web *source)
{
struct conflict_link *wl;
int i;
@@ -642,7 +618,7 @@ ok (target, source)
{
/* The main webs do _not_ conflict, only some parts of both. This
means, that 4 is possibly true, so we need to check this too.
- For this we go thru all sub conflicts between T and C, and see if
+ For this we go through all sub conflicts between T and C, and see if
the target part of C already conflicts with S. When this is not
the case we disallow coalescing. */
struct sub_conflict *sl;
@@ -659,8 +635,7 @@ ok (target, source)
/* Non-precolored node coalescing heuristic. */
static int
-conservative (target, source)
- struct web *target, *source;
+conservative (struct web *target, struct web *source)
{
unsigned int k;
unsigned int loop;
@@ -697,8 +672,7 @@ conservative (target, source)
was passed in. */
struct web *
-alias (web)
- struct web *web;
+alias (struct web *web)
{
while (web->type == COALESCED)
web = web->alias;
@@ -709,8 +683,7 @@ alias (web)
SIMPLIFY types. */
static inline unsigned int
-simplify_p (type)
- enum node_type type;
+simplify_p (enum node_type type)
{
return type == SIMPLIFY || type == SIMPLIFY_SPILL || type == SIMPLIFY_FAT;
}
@@ -718,8 +691,7 @@ simplify_p (type)
/* Actually combine two webs, that can be coalesced. */
static void
-combine (u, v)
- struct web *u, *v;
+combine (struct web *u, struct web *v)
{
int i;
struct conflict_link *wl;
@@ -848,7 +820,7 @@ combine (u, v)
This is used only for iterated coalescing. */
static void
-coalesce ()
+coalesce (void)
{
struct dlist *d = pop_list (&mv_worklist);
struct move *m = DLIST_MOVE (d);
@@ -894,8 +866,7 @@ coalesce ()
/* Freeze the moves associated with the web. Used for iterated coalescing. */
static void
-freeze_moves (web)
- struct web *web;
+freeze_moves (struct web *web)
{
struct move_list *ml, *ml_next;
for (ml = web->moves; ml; ml = ml_next)
@@ -926,7 +897,7 @@ freeze_moves (web)
coalescing). */
static void
-freeze ()
+freeze (void)
{
struct dlist *d = pop_list (&WEBS(FREEZE));
put_web (DLIST_WEB (d), SIMPLIFY);
@@ -936,17 +907,16 @@ freeze ()
/* The current spill heuristic. Returns a number for a WEB.
Webs with higher numbers are selected later. */
-static unsigned HOST_WIDE_INT (*spill_heuristic) PARAMS ((struct web *));
+static unsigned HOST_WIDE_INT (*spill_heuristic) (struct web *);
-static unsigned HOST_WIDE_INT default_spill_heuristic PARAMS ((struct web *));
+static unsigned HOST_WIDE_INT default_spill_heuristic (struct web *);
/* Our default heuristic is similar to spill_cost / num_conflicts.
Just scaled for integer arithmetic, and it favors coalesced webs,
and webs which span more insns with deaths. */
static unsigned HOST_WIDE_INT
-default_spill_heuristic (web)
- struct web *web;
+default_spill_heuristic (struct web *web)
{
unsigned HOST_WIDE_INT ret;
unsigned int divisor = 1;
@@ -968,7 +938,7 @@ default_spill_heuristic (web)
*actually* spill until we need to). */
static void
-select_spill ()
+select_spill (void)
{
unsigned HOST_WIDE_INT best = (unsigned HOST_WIDE_INT) -1;
struct dlist *bestd = NULL;
@@ -1014,10 +984,8 @@ select_spill ()
free colors, and MODE, returns nonzero of color C is still usable. */
static int
-color_usable_p (c, dont_begin_colors, free_colors, mode)
- int c;
- HARD_REG_SET dont_begin_colors, free_colors;
- enum machine_mode mode;
+color_usable_p (int c, HARD_REG_SET dont_begin_colors,
+ HARD_REG_SET free_colors, enum machine_mode mode)
{
if (!TEST_HARD_REG_BIT (dont_begin_colors, c)
&& TEST_HARD_REG_BIT (free_colors, c)
@@ -1046,9 +1014,8 @@ color_usable_p (c, dont_begin_colors, free_colors, mode)
block could be found. */
int
-get_free_reg (dont_begin_colors, free_colors, mode)
- HARD_REG_SET dont_begin_colors, free_colors;
- enum machine_mode mode;
+get_free_reg (HARD_REG_SET dont_begin_colors, HARD_REG_SET free_colors,
+ enum machine_mode mode)
{
int c;
int last_resort_reg = -1;
@@ -1097,9 +1064,9 @@ get_free_reg (dont_begin_colors, free_colors, mode)
only do the last two steps. */
static int
-get_biased_reg (dont_begin_colors, bias, prefer_colors, free_colors, mode)
- HARD_REG_SET dont_begin_colors, bias, prefer_colors, free_colors;
- enum machine_mode mode;
+get_biased_reg (HARD_REG_SET dont_begin_colors, HARD_REG_SET bias,
+ HARD_REG_SET prefer_colors, HARD_REG_SET free_colors,
+ enum machine_mode mode)
{
int c = -1;
HARD_REG_SET s;
@@ -1130,9 +1097,7 @@ get_biased_reg (dont_begin_colors, bias, prefer_colors, free_colors, mode)
in FREE_COLORS. */
static int
-count_long_blocks (free_colors, len)
- HARD_REG_SET free_colors;
- int len;
+count_long_blocks (HARD_REG_SET free_colors, int len)
{
int i, j;
int count = 0;
@@ -1156,8 +1121,7 @@ count_long_blocks (free_colors, len)
of hardreg sets. Note that this string is statically allocated. */
static char *
-hardregset_to_string (s)
- HARD_REG_SET s;
+hardregset_to_string (HARD_REG_SET s)
{
static char string[/*FIRST_PSEUDO_REGISTER + 30*/1024];
#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDE_INT
@@ -1188,9 +1152,7 @@ hardregset_to_string (s)
3 can't be used as begin color. */
static void
-calculate_dont_begin (web, result)
- struct web *web;
- HARD_REG_SET *result;
+calculate_dont_begin (struct web *web, HARD_REG_SET *result)
{
struct conflict_link *wl;
HARD_REG_SET dont_begin;
@@ -1252,7 +1214,7 @@ calculate_dont_begin (web, result)
}
}
/* The next if() only gets true, if there was no wl->sub at all, in
- which case we are only making one go thru this loop with W being
+ which case we are only making one go through this loop with W being
a whole web. */
if (!sl)
break;
@@ -1277,16 +1239,13 @@ calculate_dont_begin (web, result)
register starved machines, so we try to avoid this. */
static void
-colorize_one_web (web, hard)
- struct web *web;
- int hard;
+colorize_one_web (struct web *web, int hard)
{
struct conflict_link *wl;
HARD_REG_SET colors, dont_begin;
int c = -1;
int bestc = -1;
int neighbor_needs= 0;
- struct web *fat_neighbor = NULL;
struct web *fats_parent = NULL;
int num_fat = 0;
int long_blocks = 0;
@@ -1294,6 +1253,8 @@ colorize_one_web (web, hard)
HARD_REG_SET fat_colors;
HARD_REG_SET bias;
+ CLEAR_HARD_REG_SET (fat_colors);
+
if (web->regno >= max_normal_pseudo)
hard = 0;
@@ -1319,7 +1280,6 @@ colorize_one_web (web, hard)
&& w->add_hardregs >= neighbor_needs)
{
neighbor_needs = w->add_hardregs;
- fat_neighbor = w;
fats_parent = ptarget;
num_fat++;
}
@@ -1348,7 +1308,7 @@ colorize_one_web (web, hard)
HARD_REG_SET call_clobbered;
/* Here we choose a hard-reg for the current web. For non spill
- temporaries we first search in the hardregs for it's prefered
+ temporaries we first search in the hardregs for it's preferred
class, then, if we found nothing appropriate, in those of the
alternate class. For spill temporaries we only search in
usable_regs of this web (which is probably larger than that of
@@ -1368,10 +1328,9 @@ colorize_one_web (web, hard)
else
COPY_HARD_REG_SET (colors,
usable_regs[reg_preferred_class (web->regno)]);
-#ifdef CLASS_CANNOT_CHANGE_MODE
+#ifdef CANNOT_CHANGE_MODE_CLASS
if (web->mode_changed)
- AND_COMPL_HARD_REG_SET (colors, reg_class_contents[
- (int) CLASS_CANNOT_CHANGE_MODE]);
+ AND_COMPL_HARD_REG_SET (colors, invalid_mode_change_regs);
#endif
COPY_HARD_REG_SET (call_clobbered, colors);
AND_HARD_REG_SET (call_clobbered, call_used_reg_set);
@@ -1402,10 +1361,9 @@ colorize_one_web (web, hard)
else
IOR_HARD_REG_SET (colors, usable_regs
[reg_alternate_class (web->regno)]);
-#ifdef CLASS_CANNOT_CHANGE_MODE
+#ifdef CANNOT_CHANGE_MODE_CLASS
if (web->mode_changed)
- AND_COMPL_HARD_REG_SET (colors, reg_class_contents[
- (int) CLASS_CANNOT_CHANGE_MODE]);
+ AND_COMPL_HARD_REG_SET (colors, invalid_mode_change_regs);
#endif
COPY_HARD_REG_SET (call_clobbered, colors);
AND_HARD_REG_SET (call_clobbered, call_used_reg_set);
@@ -1475,7 +1433,7 @@ colorize_one_web (web, hard)
even if we spill this one here, the situation won't become better
in the next iteration. It probably will have the same conflicts,
those will have the same colors, and we would come here again, for
- all parts, in which this one gets splitted by the spill. This
+ all parts, in which this one gets split by the spill. This
can result in endless iteration spilling the same register again and
again. That's why we try to find a neighbor, which spans more
instructions that ourself, and got a color, and try to spill _that_.
@@ -1510,7 +1468,7 @@ colorize_one_web (web, hard)
struct web *aw = alias (w);
/* If we are a spill-temp, we also look at webs coalesced
to precolored ones. Otherwise we only look at webs which
- themself were colored, or coalesced to one. */
+ themselves were colored, or coalesced to one. */
if (aw->type == PRECOLORED && w != aw && web->spill_temp
&& flag_ra_optimistic_coalescing)
{
@@ -1559,7 +1517,7 @@ colorize_one_web (web, hard)
set_cand (6, aw);
/* For boehm-gc/misc.c. If we are a difficult spilltemp,
also coalesced neighbors are a chance, _even_ if they
- too are spilltemps. At least their coalscing can be
+ too are spilltemps. At least their coalescing can be
broken up, which may be reset usable_regs, and makes
it easier colorable. */
if (web->spill_temp != 2 && aw->is_coalesced
@@ -1664,15 +1622,13 @@ colorize_one_web (web, hard)
colors of coalesced webs. */
static void
-assign_colors ()
+assign_colors (void)
{
struct dlist *d;
while (WEBS(SELECT))
{
- struct web *web;
d = pop_list (&WEBS(SELECT));
- web = DLIST_WEB (d);
colorize_one_web (DLIST_WEB (d), 1);
}
@@ -1695,8 +1651,7 @@ assign_colors ()
be aware, that currently this pass is quite slow. */
static void
-try_recolor_web (web)
- struct web *web;
+try_recolor_web (struct web *web)
{
struct conflict_link *wl;
unsigned HOST_WIDE_INT *cost_neighbors;
@@ -1704,11 +1659,10 @@ try_recolor_web (web)
int newcol, c;
HARD_REG_SET precolored_neighbors, spill_temps;
HARD_REG_SET possible_begin, wide_seen;
- cost_neighbors = (unsigned HOST_WIDE_INT *)
- xcalloc (FIRST_PSEUDO_REGISTER, sizeof (cost_neighbors[0]));
+ cost_neighbors = xcalloc (FIRST_PSEUDO_REGISTER, sizeof (cost_neighbors[0]));
/* For each hard-regs count the number of preceding hardregs, which
would overlap this color, if used in WEB's mode. */
- min_color = (unsigned int *) xcalloc (FIRST_PSEUDO_REGISTER, sizeof (int));
+ min_color = xcalloc (FIRST_PSEUDO_REGISTER, sizeof (int));
CLEAR_HARD_REG_SET (possible_begin);
for (c = 0; c < FIRST_PSEUDO_REGISTER; c++)
{
@@ -1750,7 +1704,7 @@ try_recolor_web (web)
}
/* Mark colors for which some wide webs are involved. For
those the independent sets are not simply one-node graphs, so
- they can't be recolored independ from their neighborhood. This
+ they can't be recolored independent from their neighborhood. This
means, that our cost calculation can be incorrect (assuming it
can avoid spilling a web because it thinks some colors are available,
although it's neighbors which itself need recoloring might take
@@ -1807,7 +1761,7 @@ try_recolor_web (web)
remove_list (web->dlink, &WEBS(SPILLED));
put_web (web, COLORED);
web->color = newcol;
- old_colors = (int *) xcalloc (num_webs, sizeof (int));
+ old_colors = xcalloc (num_webs, sizeof (int));
for (wl = web->conflict_list; wl; wl = wl_next)
{
struct web *web2 = alias (wl->t);
@@ -1872,7 +1826,7 @@ try_recolor_web (web)
else if (web2->type == SELECT)
/* This means, that WEB2 once was a part of a coalesced
web, which got spilled in the above colorize_one_web()
- call, and whose parts then got splitted and put back
+ call, and whose parts then got split and put back
onto the SELECT stack. As the cause for that splitting
(the coloring of WEB) was worthless, we should again
coalesce the parts, as they were before. For now we
@@ -1898,7 +1852,7 @@ try_recolor_web (web)
isn't used anymore, e.g. on a completely colored graph. */
static void
-insert_coalesced_conflicts ()
+insert_coalesced_conflicts (void)
{
struct dlist *d;
for (d = WEBS(COALESCED); 0 && d; d = d->next)
@@ -1952,8 +1906,7 @@ insert_coalesced_conflicts ()
largest cost first. */
static int
-comp_webs_maxcost (w1, w2)
- const void *w1, *w2;
+comp_webs_maxcost (const void *w1, const void *w2)
{
struct web *web1 = *(struct web **)w1;
struct web *web2 = *(struct web **)w2;
@@ -1969,12 +1922,12 @@ comp_webs_maxcost (w1, w2)
how this is done. This just calls it for each spilled web. */
static void
-recolor_spills ()
+recolor_spills (void)
{
unsigned int i, num;
struct web **order2web;
num = num_webs - num_subwebs;
- order2web = (struct web **) xmalloc (num * sizeof (order2web[0]));
+ order2web = xmalloc (num * sizeof (order2web[0]));
for (i = 0; i < num; i++)
{
order2web[i] = id2web[i];
@@ -2006,7 +1959,7 @@ recolor_spills ()
not being in usable regs. */
static void
-check_colors ()
+check_colors (void)
{
unsigned int i;
for (i = 0; i < num_webs - num_subwebs; i++)
@@ -2028,7 +1981,7 @@ check_colors ()
if (!TEST_HARD_REG_BIT (web->usable_regs, aweb->color + c))
abort ();
/* Search the original (pre-coalesce) conflict list. In the current
- one some inprecise conflicts may be noted (due to combine() or
+ one some imprecise conflicts may be noted (due to combine() or
insert_coalesced_conflicts() relocating partial conflicts) making
it look like some wide webs are in conflict and having the same
color. */
@@ -2084,8 +2037,7 @@ check_colors ()
back onto SELECT stack. */
static void
-unalias_web (web)
- struct web *web;
+unalias_web (struct web *web)
{
web->alias = NULL;
web->is_coalesced = 0;
@@ -2113,8 +2065,7 @@ unalias_web (web)
Somewhen we'll change this to be more sane. */
static void
-break_aliases_to_web (web)
- struct web *web;
+break_aliases_to_web (struct web *web)
{
struct dlist *d, *d_next;
if (web->type != SPILLED)
@@ -2156,8 +2107,7 @@ break_aliases_to_web (web)
from initially coalescing both. */
static void
-break_precolored_alias (web)
- struct web *web;
+break_precolored_alias (struct web *web)
{
struct web *pre = web->alias;
struct conflict_link *wl;
@@ -2225,8 +2175,7 @@ break_precolored_alias (web)
and break up the coalescing. */
static void
-restore_conflicts_from_coalesce (web)
- struct web *web;
+restore_conflicts_from_coalesce (struct web *web)
{
struct conflict_link **pcl;
struct conflict_link *wl;
@@ -2332,7 +2281,7 @@ restore_conflicts_from_coalesce (web)
there are any spilled coalesce targets. */
static void
-break_coalesced_spills ()
+break_coalesced_spills (void)
{
int changed = 0;
while (1)
@@ -2400,7 +2349,7 @@ static unsigned int num_web_pairs;
/* Clear the hash table of web pairs. */
static void
-init_web_pairs ()
+init_web_pairs (void)
{
memset (web_pair_hash, 0, sizeof web_pair_hash);
num_web_pairs = 0;
@@ -2412,10 +2361,8 @@ init_web_pairs ()
already in, cumulate the costs and conflict number. */
static void
-add_web_pair_cost (web1, web2, cost, conflicts)
- struct web *web1, *web2;
- unsigned HOST_WIDE_INT cost;
- unsigned int conflicts;
+add_web_pair_cost (struct web *web1, struct web *web2,
+ unsigned HOST_WIDE_INT cost, unsigned int conflicts)
{
unsigned int hash;
struct web_pair *p;
@@ -2433,7 +2380,7 @@ add_web_pair_cost (web1, web2, cost, conflicts)
p->conflicts += conflicts;
return;
}
- p = (struct web_pair *) ra_alloc (sizeof *p);
+ p = ra_alloc (sizeof *p);
p->next_hash = web_pair_hash[hash];
p->next_list = web_pair_list;
p->smaller = web1;
@@ -2450,8 +2397,7 @@ add_web_pair_cost (web1, web2, cost, conflicts)
when the moves are removed) come first. */
static int
-comp_web_pairs (w1, w2)
- const void *w1, *w2;
+comp_web_pairs (const void *w1, const void *w2)
{
struct web_pair *p1 = *(struct web_pair **)w1;
struct web_pair *p2 = *(struct web_pair **)w2;
@@ -2471,15 +2417,14 @@ comp_web_pairs (w1, w2)
with the most savings. */
static void
-sort_and_combine_web_pairs (for_move)
- int for_move;
+sort_and_combine_web_pairs (int for_move)
{
unsigned int i;
struct web_pair **sorted;
struct web_pair *p;
if (!num_web_pairs)
return;
- sorted = (struct web_pair **) xmalloc (num_web_pairs * sizeof (sorted[0]));
+ sorted = xmalloc (num_web_pairs * sizeof (sorted[0]));
for (p = web_pair_list, i = 0; p; p = p->next_list)
sorted[i++] = p;
if (i != num_web_pairs)
@@ -2523,7 +2468,7 @@ sort_and_combine_web_pairs (for_move)
giving the most saving if coalesced. */
static void
-aggressive_coalesce ()
+aggressive_coalesce (void)
{
struct dlist *d;
struct move *m;
@@ -2582,7 +2527,7 @@ aggressive_coalesce ()
all insns, and for each insn, through all defs and uses. */
static void
-extended_coalesce_2 ()
+extended_coalesce_2 (void)
{
rtx insn;
struct ra_insn_info info;
@@ -2627,7 +2572,7 @@ extended_coalesce_2 ()
/* Check if we forgot to coalesce some moves. */
static void
-check_uncoalesced_moves ()
+check_uncoalesced_moves (void)
{
struct move_list *ml;
struct move *m;
@@ -2661,8 +2606,7 @@ check_uncoalesced_moves ()
produces a list of spilled, colored and coalesced nodes. */
void
-ra_colorize_graph (df)
- struct df *df;
+ra_colorize_graph (struct df *df)
{
if (rtl_dump_file)
dump_igraph (df);
@@ -2707,7 +2651,7 @@ ra_colorize_graph (df)
/* Initialize this module. */
-void ra_colorize_init ()
+void ra_colorize_init (void)
{
/* FIXME: Choose spill heuristic for platform if we have one */
spill_heuristic = default_spill_heuristic;
@@ -2717,14 +2661,14 @@ void ra_colorize_init ()
memory). */
void
-ra_colorize_free_all ()
+ra_colorize_free_all (void)
{
struct dlist *d;
while ((d = pop_list (&WEBS(FREE))) != NULL)
put_web (DLIST_WEB (d), INITIAL);
while ((d = pop_list (&WEBS(INITIAL))) != NULL)
{
- struct web *web =DLIST_WEB (d);
+ struct web *web = DLIST_WEB (d);
struct web *wnext;
web->orig_conflict_list = NULL;
web->conflict_list = NULL;
diff --git a/contrib/gcc/ra-debug.c b/contrib/gcc/ra-debug.c
index 8daa63d04563..26aac12df0ed 100644
--- a/contrib/gcc/ra-debug.c
+++ b/contrib/gcc/ra-debug.c
@@ -20,6 +20,8 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "insn-config.h"
#include "recog.h"
@@ -34,10 +36,10 @@
/* This file contains various dumping and debug functions for
the graph coloring register allocator. */
-static void ra_print_rtx_1op PARAMS ((FILE *, rtx));
-static void ra_print_rtx_2op PARAMS ((FILE *, rtx));
-static void ra_print_rtx_3op PARAMS ((FILE *, rtx));
-static void ra_print_rtx_object PARAMS ((FILE *, rtx));
+static void ra_print_rtx_1op (FILE *, rtx);
+static void ra_print_rtx_2op (FILE *, rtx);
+static void ra_print_rtx_3op (FILE *, rtx);
+static void ra_print_rtx_object (FILE *, rtx);
/* The hardregs as names, for debugging. */
static const char *const reg_class_names[] = REG_CLASS_NAMES;
@@ -46,14 +48,14 @@ static const char *const reg_class_names[] = REG_CLASS_NAMES;
have any bits in common. */
void
-ra_debug_msg VPARAMS ((unsigned int level, const char *format, ...))
+ra_debug_msg (unsigned int level, const char *format, ...)
{
- VA_OPEN (ap, format);
- VA_FIXEDARG (ap, unsigned int, level);
- VA_FIXEDARG (ap, const char *, format);
+ va_list ap;
+
+ va_start (ap, format);
if ((debug_new_regalloc & level) != 0 && rtl_dump_file != NULL)
vfprintf (rtl_dump_file, format, ap);
- VA_CLOSE (ap);
+ va_end (ap);
}
@@ -68,9 +70,7 @@ ra_debug_msg VPARAMS ((unsigned int level, const char *format, ...))
"op(Y)" to FILE. */
static void
-ra_print_rtx_1op (file, x)
- FILE *file;
- rtx x;
+ra_print_rtx_1op (FILE *file, rtx x)
{
enum rtx_code code = GET_CODE (x);
rtx op0 = XEXP (x, 0);
@@ -104,9 +104,7 @@ ra_print_rtx_1op (file, x)
to FILE. */
static void
-ra_print_rtx_2op (file, x)
- FILE *file;
- rtx x;
+ra_print_rtx_2op (FILE *file, rtx x)
{
int infix = 1;
const char *opname = "shitop";
@@ -169,9 +167,7 @@ ra_print_rtx_2op (file, x)
I.e. X is either an IF_THEN_ELSE, or a bitmap operation. */
static void
-ra_print_rtx_3op (file, x)
- FILE *file;
- rtx x;
+ra_print_rtx_3op (FILE *file, rtx x)
{
enum rtx_code code = GET_CODE (x);
rtx op0 = XEXP (x, 0);
@@ -206,9 +202,7 @@ ra_print_rtx_3op (file, x)
is a hardreg, whose name is NULL, or empty. */
static void
-ra_print_rtx_object (file, x)
- FILE *file;
- rtx x;
+ra_print_rtx_object (FILE *file, rtx x)
{
enum rtx_code code = GET_CODE (x);
enum machine_mode mode = GET_MODE (x);
@@ -342,10 +336,7 @@ ra_print_rtx_object (file, x)
the preceding and following insn. */
void
-ra_print_rtx (file, x, with_pn)
- FILE *file;
- rtx x;
- int with_pn;
+ra_print_rtx (FILE *file, rtx x, int with_pn)
{
enum rtx_code code;
char class;
@@ -515,10 +506,7 @@ ra_print_rtx (file, x, with_pn)
/* This only calls ra_print_rtx(), but emits a final newline. */
void
-ra_print_rtx_top (file, x, with_pn)
- FILE *file;
- rtx x;
- int with_pn;
+ra_print_rtx_top (FILE *file, rtx x, int with_pn)
{
ra_print_rtx (file, x, with_pn);
fprintf (file, "\n");
@@ -527,8 +515,7 @@ ra_print_rtx_top (file, x, with_pn)
/* Callable from gdb. This prints rtx X onto stderr. */
void
-ra_debug_rtx (x)
- rtx x;
+ra_debug_rtx (rtx x)
{
ra_print_rtx_top (stderr, x, 1);
}
@@ -537,16 +524,16 @@ ra_debug_rtx (x)
The first and last insn are emitted with UIDs of prev and next insns. */
void
-ra_debug_bbi (bbi)
- int bbi;
+ra_debug_bbi (int bbi)
{
basic_block bb = BASIC_BLOCK (bbi);
rtx insn;
- for (insn = bb->head; insn; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); insn; insn = NEXT_INSN (insn))
{
- ra_print_rtx_top (stderr, insn, (insn == bb->head || insn == bb->end));
+ ra_print_rtx_top (stderr, insn,
+ (insn == BB_HEAD (bb) || insn == BB_END (bb)));
fprintf (stderr, "\n");
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
}
}
@@ -555,9 +542,7 @@ ra_debug_bbi (bbi)
or emit a window of NUM insns around INSN, to stderr. */
void
-ra_debug_insns (insn, num)
- rtx insn;
- int num;
+ra_debug_insns (rtx insn, int num)
{
int i, count = (num == 0 ? 1 : num < 0 ? -num : num);
if (num < 0)
@@ -576,9 +561,7 @@ ra_debug_insns (insn, num)
some notes, if flag_ra_dump_notes is zero. */
void
-ra_print_rtl_with_bb (file, insn)
- FILE *file;
- rtx insn;
+ra_print_rtl_with_bb (FILE *file, rtx insn)
{
basic_block last_bb, bb;
unsigned int num = 0;
@@ -626,7 +609,7 @@ ra_print_rtl_with_bb (file, insn)
graph, and prints the findings. */
void
-dump_number_seen ()
+dump_number_seen (void)
{
#define N 17
int num[N];
@@ -652,8 +635,7 @@ dump_number_seen ()
/* Dump the interference graph, the move list and the webs. */
void
-dump_igraph (df)
- struct df *df ATTRIBUTE_UNUSED;
+dump_igraph (struct df *df ATTRIBUTE_UNUSED)
{
struct move_list *ml;
unsigned int def1, def2;
@@ -666,7 +648,8 @@ dump_igraph (df)
for (def1 = 0; def1 < num_webs; def1++)
{
int num1 = num;
- for (num2=0, def2 = 0; def2 < num_webs; def2++)
+ num2 = 0;
+ for (def2 = 0; def2 < num_webs; def2++)
if (def1 != def2 && TEST_BIT (igraph, igraph_index (def1, def2)))
{
if (num1 == num)
@@ -711,10 +694,10 @@ dump_igraph (df)
ra_debug_msg (DUMP_WEBS, " sub %d", SUBREG_BYTE (web->orig_x));
ra_debug_msg (DUMP_WEBS, " par %d", find_web_for_subweb (web)->id);
}
- ra_debug_msg (DUMP_WEBS, " +%d (span %d, cost ",
- web->add_hardregs, web->span_deaths);
- ra_debug_msg (DUMP_WEBS, HOST_WIDE_INT_PRINT_DEC, web->spill_cost);
- ra_debug_msg (DUMP_WEBS, ") (%s)", reg_class_names[web->regclass]);
+ ra_debug_msg (DUMP_WEBS, " +%d (span %d, cost "
+ HOST_WIDE_INT_PRINT_DEC ") (%s)",
+ web->add_hardregs, web->span_deaths, web->spill_cost,
+ reg_class_names[web->regclass]);
if (web->spill_temp == 1)
ra_debug_msg (DUMP_WEBS, " (spilltemp)");
else if (web->spill_temp == 2)
@@ -738,7 +721,7 @@ dump_igraph (df)
to my custom graph colorizer. */
void
-dump_igraph_machine ()
+dump_igraph_machine (void)
{
unsigned int i;
@@ -798,7 +781,7 @@ dump_igraph_machine ()
and emits information, if the resulting insns are strictly valid. */
void
-dump_constraints ()
+dump_constraints (void)
{
rtx insn;
int i;
@@ -815,7 +798,7 @@ dump_constraints ()
int uid = INSN_UID (insn);
int o;
/* Don't simply force rerecognition, as combine might left us
- with some unrecongnizable ones, which later leads to aborts
+ with some unrecognizable ones, which later leads to aborts
in regclass, if we now destroy the remembered INSN_CODE(). */
/*INSN_CODE (insn) = -1;*/
code = recog_memoized (insn);
@@ -851,9 +834,7 @@ dump_constraints ()
preceded by a custom message MSG, with debug level LEVEL. */
void
-dump_graph_cost (level, msg)
- unsigned int level;
- const char *msg;
+dump_graph_cost (unsigned int level, const char *msg)
{
unsigned int i;
unsigned HOST_WIDE_INT cost;
@@ -867,16 +848,15 @@ dump_graph_cost (level, msg)
if (alias (web)->type == SPILLED)
cost += web->orig_spill_cost;
}
- ra_debug_msg (level, " spill cost of graph (%s) = ", msg ? msg : "");
- ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, cost);
- ra_debug_msg (level, "\n");
+ ra_debug_msg (level, " spill cost of graph (%s) = "
+ HOST_WIDE_INT_PRINT_UNSIGNED "\n",
+ msg ? msg : "", cost);
}
/* Dump the color assignment per web, the coalesced and spilled webs. */
void
-dump_ra (df)
- struct df *df ATTRIBUTE_UNUSED;
+dump_ra (struct df *df ATTRIBUTE_UNUSED)
{
struct web *web;
struct dlist *d;
@@ -910,10 +890,7 @@ dump_ra (df)
(loads, stores and copies). */
void
-dump_static_insn_cost (file, message, prefix)
- FILE *file;
- const char *message;
- const char *prefix;
+dump_static_insn_cost (FILE *file, const char *message, const char *prefix)
{
struct cost
{
@@ -935,7 +912,7 @@ dump_static_insn_cost (file, message, prefix)
{
unsigned HOST_WIDE_INT block_cost = bb->frequency;
rtx insn, set;
- for (insn = bb->head; insn; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); insn; insn = NEXT_INSN (insn))
{
/* Yes, yes. We don't calculate the costs precisely.
Only for "simple enough" insns. Those containing single
@@ -974,7 +951,7 @@ dump_static_insn_cost (file, message, prefix)
pcost->count++;
}
}
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
}
}
@@ -982,30 +959,23 @@ dump_static_insn_cost (file, message, prefix)
if (!prefix)
prefix = "";
fprintf (file, "static insn cost %s\n", message ? message : "");
- fprintf (file, " %soverall:\tnum=%6d\tcost=", prefix, overall.count);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, overall.cost);
- fprintf (file, "\n");
- fprintf (file, " %sloads:\tnum=%6d\tcost=", prefix, load.count);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, load.cost);
- fprintf (file, "\n");
- fprintf (file, " %sstores:\tnum=%6d\tcost=", prefix, store.count);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, store.cost);
- fprintf (file, "\n");
- fprintf (file, " %sregcopy:\tnum=%6d\tcost=", prefix, regcopy.count);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, regcopy.cost);
- fprintf (file, "\n");
- fprintf (file, " %sselfcpy:\tnum=%6d\tcost=", prefix, selfcopy.count);
- fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, selfcopy.cost);
- fprintf (file, "\n");
+ fprintf (file, " %soverall:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n",
+ prefix, overall.count, overall.cost);
+ fprintf (file, " %sloads:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n",
+ prefix, load.count, load.cost);
+ fprintf (file, " %sstores:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n",
+ prefix, store.count, store.cost);
+ fprintf (file, " %sregcopy:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n",
+ prefix, regcopy.count, regcopy.cost);
+ fprintf (file, " %sselfcpy:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n",
+ prefix, selfcopy.count, selfcopy.cost);
}
/* Returns nonzero, if WEB1 and WEB2 have some possible
hardregs in common. */
int
-web_conflicts_p (web1, web2)
- struct web *web1;
- struct web *web2;
+web_conflicts_p (struct web *web1, struct web *web2)
{
if (web1->type == PRECOLORED && web2->type == PRECOLORED)
return 0;
@@ -1022,8 +992,7 @@ web_conflicts_p (web1, web2)
/* Dump all uids of insns in which WEB is mentioned. */
void
-dump_web_insns (web)
- struct web *web;
+dump_web_insns (struct web *web)
{
unsigned int i;
@@ -1049,8 +1018,7 @@ dump_web_insns (web)
/* Dump conflicts for web WEB. */
void
-dump_web_conflicts (web)
- struct web *web;
+dump_web_conflicts (struct web *web)
{
int num = 0;
unsigned int def2;
@@ -1101,11 +1069,10 @@ dump_web_conflicts (web)
/* Output HARD_REG_SET to stderr. */
void
-debug_hard_reg_set (set)
- HARD_REG_SET set;
+debug_hard_reg_set (HARD_REG_SET set)
{
int i;
- for (i=0; i < FIRST_PSEUDO_REGISTER; ++i)
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
{
if (TEST_HARD_REG_BIT (set, i))
{
diff --git a/contrib/gcc/ra-rewrite.c b/contrib/gcc/ra-rewrite.c
index 61645e22a1d3..44fde7ddd2f3 100644
--- a/contrib/gcc/ra-rewrite.c
+++ b/contrib/gcc/ra-rewrite.c
@@ -1,5 +1,5 @@
/* Graph coloring register allocator
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Michael Matz <matz@suse.de>
and Daniel Berlin <dan@cgsoftware.com>.
@@ -20,6 +20,8 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "function.h"
@@ -42,33 +44,32 @@
struct rewrite_info;
struct rtx_list;
-static void spill_coalescing PARAMS ((sbitmap, sbitmap));
-static unsigned HOST_WIDE_INT spill_prop_savings PARAMS ((struct web *,
- sbitmap));
-static void spill_prop_insert PARAMS ((struct web *, sbitmap, sbitmap));
-static int spill_propagation PARAMS ((sbitmap, sbitmap, sbitmap));
-static void spill_coalprop PARAMS ((void));
-static void allocate_spill_web PARAMS ((struct web *));
-static void choose_spill_colors PARAMS ((void));
-static void rewrite_program PARAMS ((bitmap));
-static void remember_slot PARAMS ((struct rtx_list **, rtx));
-static int slots_overlap_p PARAMS ((rtx, rtx));
-static void delete_overlapping_slots PARAMS ((struct rtx_list **, rtx));
-static int slot_member_p PARAMS ((struct rtx_list *, rtx));
-static void insert_stores PARAMS ((bitmap));
-static int spill_same_color_p PARAMS ((struct web *, struct web *));
-static bool is_partly_live_1 PARAMS ((sbitmap, struct web *));
-static void update_spill_colors PARAMS ((HARD_REG_SET *, struct web *, int));
-static int spill_is_free PARAMS ((HARD_REG_SET *, struct web *));
-static void emit_loads PARAMS ((struct rewrite_info *, int, rtx));
-static void reloads_to_loads PARAMS ((struct rewrite_info *, struct ref **,
- unsigned int, struct web **));
-static void rewrite_program2 PARAMS ((bitmap));
-static void mark_refs_for_checking PARAMS ((struct web *, bitmap));
-static void detect_web_parts_to_rebuild PARAMS ((void));
-static void delete_useless_defs PARAMS ((void));
-static void detect_non_changed_webs PARAMS ((void));
-static void reset_changed_flag PARAMS ((void));
+static void spill_coalescing (sbitmap, sbitmap);
+static unsigned HOST_WIDE_INT spill_prop_savings (struct web *, sbitmap);
+static void spill_prop_insert (struct web *, sbitmap, sbitmap);
+static int spill_propagation (sbitmap, sbitmap, sbitmap);
+static void spill_coalprop (void);
+static void allocate_spill_web (struct web *);
+static void choose_spill_colors (void);
+static void rewrite_program (bitmap);
+static void remember_slot (struct rtx_list **, rtx);
+static int slots_overlap_p (rtx, rtx);
+static void delete_overlapping_slots (struct rtx_list **, rtx);
+static int slot_member_p (struct rtx_list *, rtx);
+static void insert_stores (bitmap);
+static int spill_same_color_p (struct web *, struct web *);
+static bool is_partly_live_1 (sbitmap, struct web *);
+static void update_spill_colors (HARD_REG_SET *, struct web *, int);
+static int spill_is_free (HARD_REG_SET *, struct web *);
+static void emit_loads (struct rewrite_info *, int, rtx);
+static void reloads_to_loads (struct rewrite_info *, struct ref **,
+ unsigned int, struct web **);
+static void rewrite_program2 (bitmap);
+static void mark_refs_for_checking (struct web *, bitmap);
+static void detect_web_parts_to_rebuild (void);
+static void delete_useless_defs (void);
+static void detect_non_changed_webs (void);
+static void reset_changed_flag (void);
/* For tracking some statistics, we count the number (and cost)
of deleted move insns. */
@@ -82,8 +83,7 @@ static unsigned HOST_WIDE_INT deleted_move_cost;
reduces memory shuffling. */
static void
-spill_coalescing (coalesce, spilled)
- sbitmap coalesce, spilled;
+spill_coalescing (sbitmap coalesce, sbitmap spilled)
{
struct move_list *ml;
struct move *m;
@@ -158,9 +158,7 @@ spill_coalescing (coalesce, spilled)
SPILLED, in terms of removed move insn cost. */
static unsigned HOST_WIDE_INT
-spill_prop_savings (web, spilled)
- struct web *web;
- sbitmap spilled;
+spill_prop_savings (struct web *web, sbitmap spilled)
{
unsigned HOST_WIDE_INT savings = 0;
struct move_list *ml;
@@ -194,9 +192,7 @@ spill_prop_savings (web, spilled)
to LIST and PROCESSED. */
static void
-spill_prop_insert (web, list, processed)
- struct web *web;
- sbitmap list, processed;
+spill_prop_insert (struct web *web, sbitmap list, sbitmap processed)
{
struct move_list *ml;
struct move *m;
@@ -230,8 +226,7 @@ spill_prop_insert (web, list, processed)
of all webs processed so far, so we don't do work twice. */
static int
-spill_propagation (to_prop, spilled, processed)
- sbitmap to_prop, spilled, processed;
+spill_propagation (sbitmap to_prop, sbitmap spilled, sbitmap processed)
{
int id;
int again = 0;
@@ -273,7 +268,7 @@ spill_propagation (to_prop, spilled, processed)
spill coalescing and spill propagation, until nothing changes. */
static void
-spill_coalprop ()
+spill_coalprop (void)
{
sbitmap spilled, processed, to_prop;
struct dlist *d;
@@ -309,8 +304,7 @@ spill_coalprop ()
MEM references. */
static void
-allocate_spill_web (web)
- struct web *web;
+allocate_spill_web (struct web *web)
{
int regno = web->regno;
rtx slot;
@@ -324,11 +318,10 @@ allocate_spill_web (web)
spilling. The heuristic isn't good in any way. */
static void
-choose_spill_colors ()
+choose_spill_colors (void)
{
struct dlist *d;
- unsigned HOST_WIDE_INT *costs = (unsigned HOST_WIDE_INT *)
- xmalloc (FIRST_PSEUDO_REGISTER * sizeof (costs[0]));
+ unsigned HOST_WIDE_INT *costs = xmalloc (FIRST_PSEUDO_REGISTER * sizeof (costs[0]));
for (d = WEBS(SPILLED); d; d = d->next)
{
struct web *web = DLIST_WEB (d);
@@ -396,8 +389,7 @@ static bitmap useless_defs;
deaths. */
static void
-rewrite_program (new_deaths)
- bitmap new_deaths;
+rewrite_program (bitmap new_deaths)
{
unsigned int i;
struct dlist *d;
@@ -452,8 +444,8 @@ rewrite_program (new_deaths)
end_sequence ();
emit_insn_before (insns, insn);
- if (bb->head == insn)
- bb->head = NEXT_INSN (prev);
+ if (BB_HEAD (bb) == insn)
+ BB_HEAD (bb) = NEXT_INSN (prev);
for (insn = PREV_INSN (insn); insn != prev;
insn = PREV_INSN (insn))
{
@@ -500,8 +492,8 @@ rewrite_program (new_deaths)
if (insns)
{
emit_insn_after (insns, insn);
- if (bb->end == insn)
- bb->end = PREV_INSN (following);
+ if (BB_END (bb) == insn)
+ BB_END (bb) = PREV_INSN (following);
for (insn = insns; insn != following; insn = NEXT_INSN (insn))
{
set_block_for_insn (insn, bb);
@@ -537,13 +529,11 @@ struct rtx_list
/* Adds X to *LIST. */
static void
-remember_slot (list, x)
- struct rtx_list **list;
- rtx x;
+remember_slot (struct rtx_list **list, rtx x)
{
struct rtx_list *l;
/* PRE: X is not already in LIST. */
- l = (struct rtx_list *) ra_alloc (sizeof (*l));
+ l = ra_alloc (sizeof (*l));
l->next = *list;
l->x = x;
*list = l;
@@ -555,8 +545,7 @@ remember_slot (list, x)
(plus (basereg) (const_inst x)), otherwise they overlap. */
static int
-slots_overlap_p (s1, s2)
- rtx s1, s2;
+slots_overlap_p (rtx s1, rtx s2)
{
rtx base1, base2;
HOST_WIDE_INT ofs1 = 0, ofs2 = 0;
@@ -606,9 +595,7 @@ slots_overlap_p (s1, s2)
of slots_overlap_p(). */
static void
-delete_overlapping_slots (list, x)
- struct rtx_list **list;
- rtx x;
+delete_overlapping_slots (struct rtx_list **list, rtx x)
{
while (*list)
{
@@ -622,9 +609,7 @@ delete_overlapping_slots (list, x)
/* Returns nonzero, of X is member of LIST. */
static int
-slot_member_p (list, x)
- struct rtx_list *list;
- rtx x;
+slot_member_p (struct rtx_list *list, rtx x)
{
for (;list; list = list->next)
if (rtx_equal_p (list->x, x))
@@ -639,8 +624,7 @@ slot_member_p (list, x)
containing deaths. */
static void
-insert_stores (new_deaths)
- bitmap new_deaths;
+insert_stores (bitmap new_deaths)
{
rtx insn;
rtx last_slot = NULL_RTX;
@@ -701,8 +685,8 @@ insert_stores (new_deaths)
if (insns)
{
emit_insn_after (insns, insn);
- if (bb->end == insn)
- bb->end = PREV_INSN (following);
+ if (BB_END (bb) == insn)
+ BB_END (bb) = PREV_INSN (following);
for (ni = insns; ni != following; ni = NEXT_INSN (ni))
{
set_block_for_insn (ni, bb);
@@ -749,8 +733,7 @@ insert_stores (new_deaths)
they are not the same width. */
static int
-spill_same_color_p (web1, web2)
- struct web *web1, *web2;
+spill_same_color_p (struct web *web1, struct web *web2)
{
int c1, size1, c2, size2;
if ((c1 = alias (web1)->color) < 0 || c1 == an_unusable_color)
@@ -771,9 +754,7 @@ spill_same_color_p (web1, web2)
subwebs (or WEB itself) is live. */
static bool
-is_partly_live_1 (live, web)
- sbitmap live;
- struct web *web;
+is_partly_live_1 (sbitmap live, struct web *web)
{
do
if (TEST_BIT (live, web->id))
@@ -792,10 +773,7 @@ is_partly_live_1 (live, web)
is nonzero), or remove them. */
static void
-update_spill_colors (in_use, web, add)
- HARD_REG_SET *in_use;
- struct web *web;
- int add;
+update_spill_colors (HARD_REG_SET *in_use, struct web *web, int add)
{
int c, size;
if ((c = alias (find_web_for_subweb (web))->color) < 0
@@ -824,9 +802,7 @@ update_spill_colors (in_use, web, add)
Generally, if WEB can't be left colorized return 1. */
static int
-spill_is_free (in_use, web)
- HARD_REG_SET *in_use;
- struct web *web;
+spill_is_free (HARD_REG_SET *in_use, struct web *web)
{
int c, size;
if ((c = alias (web)->color) < 0)
@@ -880,10 +856,7 @@ struct rewrite_info
loads. LAST_BLOCK_INSN is the last insn of the current basic block. */
static void
-emit_loads (ri, nl_first_reload, last_block_insn)
- struct rewrite_info *ri;
- int nl_first_reload;
- rtx last_block_insn;
+emit_loads (struct rewrite_info *ri, int nl_first_reload, rtx last_block_insn)
{
int j;
for (j = ri->nl_size; j;)
@@ -968,8 +941,8 @@ emit_loads (ri, nl_first_reload, last_block_insn)
rtx foll = NEXT_INSN (after);
bb = BLOCK_FOR_INSN (after);
emit_insn_after (ni, after);
- if (bb->end == after)
- bb->end = PREV_INSN (foll);
+ if (BB_END (bb) == after)
+ BB_END (bb) = PREV_INSN (foll);
for (ni = NEXT_INSN (after); ni != foll; ni = NEXT_INSN (ni))
{
set_block_for_insn (ni, bb);
@@ -981,8 +954,8 @@ emit_loads (ri, nl_first_reload, last_block_insn)
rtx prev = PREV_INSN (before);
bb = BLOCK_FOR_INSN (before);
emit_insn_before (ni, before);
- if (bb->head == before)
- bb->head = NEXT_INSN (prev);
+ if (BB_HEAD (bb) == before)
+ BB_HEAD (bb) = NEXT_INSN (prev);
for (; ni != before; ni = NEXT_INSN (ni))
{
set_block_for_insn (ni, bb);
@@ -1017,11 +990,8 @@ emit_loads (ri, nl_first_reload, last_block_insn)
and whose colors isn't free anymore, on the needed_loads list. */
static void
-reloads_to_loads (ri, refs, num_refs, ref2web)
- struct rewrite_info *ri;
- struct ref **refs;
- unsigned int num_refs;
- struct web **ref2web;
+reloads_to_loads (struct rewrite_info *ri, struct ref **refs,
+ unsigned int num_refs, struct web **ref2web)
{
unsigned int n;
int num_reloads = ri->num_reloads;
@@ -1080,14 +1050,13 @@ reloads_to_loads (ri, refs, num_refs, ref2web)
containing deaths). */
static void
-rewrite_program2 (new_deaths)
- bitmap new_deaths;
+rewrite_program2 (bitmap new_deaths)
{
- basic_block bb;
+ basic_block bb = NULL;
int nl_first_reload;
struct rewrite_info ri;
rtx insn;
- ri.needed_loads = (struct web **) xmalloc (num_webs * sizeof (struct web *));
+ ri.needed_loads = xmalloc (num_webs * sizeof (struct web *));
ri.need_reload = BITMAP_XMALLOC ();
ri.scratch = BITMAP_XMALLOC ();
ri.live = sbitmap_alloc (num_webs);
@@ -1444,9 +1413,7 @@ rewrite_program2 (new_deaths)
Also remember all IDs of its uses in USES_AS_BITMAP. */
static void
-mark_refs_for_checking (web, uses_as_bitmap)
- struct web *web;
- bitmap uses_as_bitmap;
+mark_refs_for_checking (struct web *web, bitmap uses_as_bitmap)
{
unsigned int i;
for (i = 0; i < web->num_uses; i++)
@@ -1472,7 +1439,7 @@ mark_refs_for_checking (web, uses_as_bitmap)
information, we will rebuild. */
static void
-detect_web_parts_to_rebuild ()
+detect_web_parts_to_rebuild (void)
{
bitmap uses_as_bitmap;
unsigned int i, pass;
@@ -1487,7 +1454,7 @@ detect_web_parts_to_rebuild ()
sbitmap_zero (already_webs);
/* We need to recheck all uses of all webs involved in spilling (and the
uses added by spill insns, but those are not analyzed yet).
- Those are the spilled webs themself, webs coalesced to spilled ones,
+ Those are the spilled webs themselves, webs coalesced to spilled ones,
and webs conflicting with any of them. */
for (pass = 0; pass < 2; pass++)
for (d = (pass == 0) ? WEBS(SPILLED) : WEBS(COALESCED); d; d = d->next)
@@ -1543,7 +1510,7 @@ detect_web_parts_to_rebuild ()
/* We also recheck unconditionally all uses of any hardregs. This means
we _can_ delete all these uses from the live_at_end[] bitmaps.
- And because we sometimes delete insn refering to hardregs (when
+ And because we sometimes delete insn referring to hardregs (when
they became useless because they setup a rematerializable pseudo, which
then was rematerialized), some of those uses will go away with the next
df_analyse(). This means we even _must_ delete those uses from
@@ -1584,7 +1551,7 @@ static unsigned HOST_WIDE_INT deleted_def_cost;
which wasn't live. Try to delete all those insns. */
static void
-delete_useless_defs ()
+delete_useless_defs (void)
{
unsigned int i;
/* If the insn only sets the def without any sideeffect (besides
@@ -1612,7 +1579,7 @@ delete_useless_defs ()
in this pass). */
static void
-detect_non_changed_webs ()
+detect_non_changed_webs (void)
{
struct dlist *d, *d_next;
for (d = WEBS(SPILLED); d; d = d_next)
@@ -1638,7 +1605,7 @@ detect_non_changed_webs ()
/* Before spilling we clear the changed flags for all spilled webs. */
static void
-reset_changed_flag ()
+reset_changed_flag (void)
{
struct dlist *d;
for (d = WEBS(SPILLED); d; d = d->next)
@@ -1651,7 +1618,7 @@ reset_changed_flag ()
building the interference graph in the next pass. */
void
-actual_spill ()
+actual_spill (void)
{
int i;
bitmap new_deaths = BITMAP_XMALLOC ();
@@ -1686,8 +1653,7 @@ static bitmap regnos_coalesced_to_hardregs;
use those pseudos and set up ra_reg_renumber. */
void
-emit_colors (df)
- struct df *df;
+emit_colors (struct df *df)
{
unsigned int i;
int si;
@@ -1748,7 +1714,7 @@ emit_colors (df)
}
ra_max_regno = max_regno = max_reg_num ();
allocate_reg_info (max_regno, FALSE, FALSE);
- ra_reg_renumber = (short *) xmalloc (max_regno * sizeof (short));
+ ra_reg_renumber = xmalloc (max_regno * sizeof (short));
for (si = 0; si < max_regno; si++)
ra_reg_renumber[si] = -1;
@@ -1839,7 +1805,7 @@ emit_colors (df)
/* Delete some coalesced moves from the insn stream. */
void
-delete_moves ()
+delete_moves (void)
{
struct move_list *ml;
struct web *s, *t;
@@ -1884,7 +1850,7 @@ delete_moves ()
}
}
-/* Due to resons documented elsewhere we create different pseudos
+/* Due to reasons documented elsewhere we create different pseudos
for all webs coalesced to hardregs. For these parts life_analysis()
might have added REG_DEAD notes without considering, that only this part
but not the whole coalesced web dies. The RTL is correct, there is no
@@ -1897,7 +1863,7 @@ delete_moves ()
that comes later) Bah. */
void
-remove_suspicious_death_notes ()
+remove_suspicious_death_notes (void)
{
rtx insn;
for (insn = get_insns(); insn; insn = NEXT_INSN (insn))
@@ -1926,8 +1892,7 @@ remove_suspicious_death_notes ()
is nonzero, also free ra_reg_renumber and reset ra_max_regno. */
void
-setup_renumber (free_it)
- int free_it;
+setup_renumber (int free_it)
{
int i;
max_regno = max_reg_num ();
@@ -1948,27 +1913,26 @@ setup_renumber (free_it)
and removed moves or useless defs. */
void
-dump_cost (level)
- unsigned int level;
+dump_cost (unsigned int level)
{
ra_debug_msg (level, "Instructions for spilling\n added:\n");
- ra_debug_msg (level, " loads =%d cost=", emitted_spill_loads);
- ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, spill_load_cost);
- ra_debug_msg (level, "\n stores=%d cost=", emitted_spill_stores);
- ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, spill_store_cost);
- ra_debug_msg (level, "\n remat =%d cost=", emitted_remat);
- ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, spill_remat_cost);
- ra_debug_msg (level, "\n removed:\n moves =%d cost=", deleted_move_insns);
- ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, deleted_move_cost);
- ra_debug_msg (level, "\n others=%d cost=", deleted_def_insns);
- ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, deleted_def_cost);
- ra_debug_msg (level, "\n");
+ ra_debug_msg (level, " loads =%d cost=" HOST_WIDE_INT_PRINT_UNSIGNED "\n",
+ emitted_spill_loads, spill_load_cost);
+ ra_debug_msg (level, " stores=%d cost=" HOST_WIDE_INT_PRINT_UNSIGNED "\n",
+ emitted_spill_stores, spill_store_cost);
+ ra_debug_msg (level, " remat =%d cost=" HOST_WIDE_INT_PRINT_UNSIGNED "\n",
+ emitted_remat, spill_remat_cost);
+ ra_debug_msg (level, " removed:\n moves =%d cost="
+ HOST_WIDE_INT_PRINT_UNSIGNED "\n",
+ deleted_move_insns, deleted_move_cost);
+ ra_debug_msg (level, " others=%d cost=" HOST_WIDE_INT_PRINT_UNSIGNED "\n",
+ deleted_def_insns, deleted_def_cost);
}
/* Initialization of the rewrite phase. */
void
-ra_rewrite_init ()
+ra_rewrite_init (void)
{
emitted_spill_loads = 0;
emitted_spill_stores = 0;
diff --git a/contrib/gcc/ra.c b/contrib/gcc/ra.c
index ab52b4224712..5884197dca23 100644
--- a/contrib/gcc/ra.c
+++ b/contrib/gcc/ra.c
@@ -1,5 +1,5 @@
/* Graph coloring register allocator
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Michael Matz <matz@suse.de>
and Daniel Berlin <dan@cgsoftware.com>.
@@ -20,6 +20,8 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "insn-config.h"
@@ -73,7 +75,7 @@
* Lattice based rematerialization
* create definitions of ever-life regs at the beginning of
the insn chain
- * insert loads as soon, stores as late as possile
+ * insert loads as soon, stores as late as possible
* insert spill insns as outward as possible (either looptree, or LCM)
* reuse stack-slots
* delete coalesced insns. Partly done. The rest can only go, when we get
@@ -83,16 +85,16 @@
*/
static struct obstack ra_obstack;
-static void create_insn_info PARAMS ((struct df *));
-static void free_insn_info PARAMS ((void));
-static void alloc_mem PARAMS ((struct df *));
-static void free_mem PARAMS ((struct df *));
-static void free_all_mem PARAMS ((struct df *df));
-static int one_pass PARAMS ((struct df *, int));
-static void check_df PARAMS ((struct df *));
-static void init_ra PARAMS ((void));
+static void create_insn_info (struct df *);
+static void free_insn_info (void);
+static void alloc_mem (struct df *);
+static void free_mem (struct df *);
+static void free_all_mem (struct df *df);
+static int one_pass (struct df *, int);
+static void check_df (struct df *);
+static void init_ra (void);
-void reg_alloc PARAMS ((void));
+void reg_alloc (void);
/* These global variables are "internal" to the register allocator.
They are all documented at their declarations in ra.h. */
@@ -146,6 +148,7 @@ HARD_REG_SET never_use_colors;
HARD_REG_SET usable_regs[N_REG_CLASSES];
unsigned int num_free_regs[N_REG_CLASSES];
HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES];
+HARD_REG_SET invalid_mode_change_regs;
unsigned char byte2bitcount[256];
unsigned int debug_new_regalloc = -1;
@@ -162,8 +165,7 @@ int flag_ra_dump_notes = 0;
is done. Allocate an object of SIZE bytes. */
void *
-ra_alloc (size)
- size_t size;
+ra_alloc (size_t size)
{
return obstack_alloc (&ra_obstack, size);
}
@@ -171,8 +173,7 @@ ra_alloc (size)
/* Like ra_alloc(), but clear the returned memory. */
void *
-ra_calloc (size)
- size_t size;
+ra_calloc (size_t size)
{
void *p = obstack_alloc (&ra_obstack, size);
memset (p, 0, size);
@@ -182,8 +183,7 @@ ra_calloc (size)
/* Returns the number of hardregs in HARD_REG_SET RS. */
int
-hard_regs_count (rs)
- HARD_REG_SET rs;
+hard_regs_count (HARD_REG_SET rs)
{
int count = 0;
#ifdef HARD_REG_SET
@@ -217,8 +217,7 @@ hard_regs_count (rs)
be basically valid. */
rtx
-ra_emit_move_insn (x, y)
- rtx x, y;
+ra_emit_move_insn (rtx x, rtx y)
{
enum machine_mode mode = GET_MODE (x);
if (GET_MODE_CLASS (mode) == MODE_CC)
@@ -235,8 +234,7 @@ static struct ref **refs_for_insn_df;
all valid defs and uses in an insn. */
static void
-create_insn_info (df)
- struct df *df;
+create_insn_info (struct df *df)
{
rtx insn;
struct ref **act_refs;
@@ -285,7 +283,7 @@ create_insn_info (df)
/* Free the insn_df structures. */
static void
-free_insn_info ()
+free_insn_info (void)
{
free (refs_for_insn_df);
refs_for_insn_df = NULL;
@@ -299,9 +297,7 @@ free_insn_info ()
represented by WEB. Returns the matching subweb or NULL. */
struct web *
-find_subweb (web, reg)
- struct web *web;
- rtx reg;
+find_subweb (struct web *web, rtx reg)
{
struct web *w;
if (GET_CODE (reg) != SUBREG)
@@ -317,9 +313,7 @@ find_subweb (web, reg)
a collection of the needed size and offset (in bytes). */
struct web *
-find_subweb_2 (web, size_word)
- struct web *web;
- unsigned int size_word;
+find_subweb_2 (struct web *web, unsigned int size_word)
{
struct web *w = web;
if (size_word == GET_MODE_SIZE (GET_MODE (web->orig_x)))
@@ -337,8 +331,7 @@ find_subweb_2 (web, size_word)
/* Returns the superweb for SUBWEB. */
struct web *
-find_web_for_subweb_1 (subweb)
- struct web *subweb;
+find_web_for_subweb_1 (struct web *subweb)
{
while (subweb->parent_web)
subweb = subweb->parent_web;
@@ -349,8 +342,7 @@ find_web_for_subweb_1 (subweb)
Return 1 if they do. */
int
-hard_regs_intersect_p (a, b)
- HARD_REG_SET *a, *b;
+hard_regs_intersect_p (HARD_REG_SET *a, HARD_REG_SET *b)
{
HARD_REG_SET c;
COPY_HARD_REG_SET (c, *a);
@@ -365,15 +357,13 @@ lose:
register allocator. */
static void
-alloc_mem (df)
- struct df *df;
+alloc_mem (struct df *df)
{
int i;
ra_build_realloc (df);
if (!live_at_end)
{
- live_at_end = (bitmap *) xmalloc ((last_basic_block + 2)
- * sizeof (bitmap));
+ live_at_end = xmalloc ((last_basic_block + 2) * sizeof (bitmap));
for (i = 0; i < last_basic_block + 2; i++)
live_at_end[i] = BITMAP_XMALLOC ();
live_at_end += 2;
@@ -384,8 +374,7 @@ alloc_mem (df)
/* Free the memory which isn't necessary for the next pass. */
static void
-free_mem (df)
- struct df *df ATTRIBUTE_UNUSED;
+free_mem (struct df *df ATTRIBUTE_UNUSED)
{
free_insn_info ();
ra_build_free ();
@@ -395,8 +384,7 @@ free_mem (df)
it's done. */
static void
-free_all_mem (df)
- struct df *df;
+free_all_mem (struct df *df)
{
unsigned int i;
live_at_end -= 2;
@@ -416,9 +404,7 @@ static long ticks_rebuild;
was added, i.e. if the allocator needs to rerun. */
static int
-one_pass (df, rebuild)
- struct df *df;
- int rebuild;
+one_pass (struct df *df, int rebuild)
{
long ticks = clock ();
int something_spilled;
@@ -459,7 +445,7 @@ one_pass (df, rebuild)
/* Initialize various arrays for the register allocator. */
static void
-init_ra ()
+init_ra (void)
{
int i;
HARD_REG_SET rs;
@@ -469,9 +455,7 @@ init_ra ()
#endif
int need_fp
= (! flag_omit_frame_pointer
-#ifdef EXIT_IGNORE_STACK
|| (current_function_calls_alloca && EXIT_IGNORE_STACK)
-#endif
|| FRAME_POINTER_REQUIRED);
ra_colorize_init ();
@@ -553,6 +537,23 @@ init_ra ()
COPY_HARD_REG_SET (hardregs_for_mode[i], rs);
}
+ CLEAR_HARD_REG_SET (invalid_mode_change_regs);
+#ifdef CANNOT_CHANGE_MODE_CLASS
+ if (0)
+ for (i = 0; i < NUM_MACHINE_MODES; i++)
+ {
+ enum machine_mode from = (enum machine_mode) i;
+ enum machine_mode to;
+ for (to = VOIDmode; to < MAX_MACHINE_MODE; ++to)
+ {
+ int r;
+ for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
+ if (REG_CANNOT_CHANGE_MODE_P (from, to, r))
+ SET_HARD_REG_BIT (invalid_mode_change_regs, r);
+ }
+ }
+#endif
+
for (an_unusable_color = 0; an_unusable_color < FIRST_PSEUDO_REGISTER;
an_unusable_color++)
if (TEST_HARD_REG_BIT (never_use_colors, an_unusable_color))
@@ -573,8 +574,7 @@ init_ra ()
invariances we expect. */
static void
-check_df (df)
- struct df *df;
+check_df (struct df *df)
{
struct df_link *link;
rtx insn;
@@ -644,7 +644,7 @@ check_df (df)
/* Main register allocator entry point. */
void
-reg_alloc ()
+reg_alloc (void)
{
int changed;
FILE *ra_dump_file = rtl_dump_file;
@@ -655,7 +655,7 @@ reg_alloc ()
/* If this is an empty function we shouldn't do all the following,
but instead just setup what's necessary, and return. */
- /* We currently rely on the existance of the return value USE as
+ /* We currently rely on the existence of the return value USE as
one of the last insns. Add it if it's not there anymore. */
if (last)
{
@@ -663,7 +663,7 @@ reg_alloc ()
for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
{
basic_block bb = e->src;
- last = bb->end;
+ last = BB_END (bb);
if (!INSN_P (last) || GET_CODE (PATTERN (last)) != USE)
{
rtx insns;
@@ -679,7 +679,7 @@ reg_alloc ()
/* Setup debugging levels. */
switch (0)
{
- /* Some usefull presets of the debug level, I often use. */
+ /* Some useful presets of the debug level, I often use. */
case 0: debug_new_regalloc = DUMP_EVER; break;
case 1: debug_new_regalloc = DUMP_COSTS; break;
case 2: debug_new_regalloc = DUMP_IGRAPH_M; break;
@@ -696,7 +696,7 @@ reg_alloc ()
/* Run regclass first, so we know the preferred and alternate classes
for each pseudo. Deactivate emitting of debug info, if it's not
- explicitely requested. */
+ explicitly requested. */
if ((debug_new_regalloc & DUMP_REGCLASS) == 0)
rtl_dump_file = NULL;
regclass (get_insns (), max_reg_num (), rtl_dump_file);
@@ -753,7 +753,7 @@ reg_alloc ()
chains per insn, and per regno. In later passes only update
that info from the new and modified insns. */
df_analyse (df, (ra_pass == 1) ? 0 : (bitmap) -1,
- DF_HARD_REGS | DF_RD_CHAIN | DF_RU_CHAIN);
+ DF_HARD_REGS | DF_RD_CHAIN | DF_RU_CHAIN | DF_FOR_REGALLOC);
if ((debug_new_regalloc & DUMP_DF) != 0)
{
@@ -805,7 +805,7 @@ reg_alloc ()
/* Those new pseudos need to have their REFS count set. */
reg_scan_update (get_insns (), NULL, max_regno);
max_regno = max_reg_num ();
- /* And they need usefull classes too. */
+ /* And they need useful classes too. */
regclass (get_insns (), max_reg_num (), rtl_dump_file);
rtl_dump_file = ra_dump_file;
@@ -887,7 +887,7 @@ reg_alloc ()
"after allocation/spilling, before reload", NULL);
/* Allocate the reg_equiv_memory_loc array for reload. */
- reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx));
+ reg_equiv_memory_loc = xcalloc (max_regno, sizeof (rtx));
/* And possibly initialize it. */
allocate_initial_values (reg_equiv_memory_loc);
/* And one last regclass pass just before reload. */
diff --git a/contrib/gcc/ra.h b/contrib/gcc/ra.h
index d3c1f1ae43ed..252d85cadbd3 100644
--- a/contrib/gcc/ra.h
+++ b/contrib/gcc/ra.h
@@ -1,5 +1,5 @@
/* Graph coloring register allocator
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Matz <matz@suse.de>
and Daniel Berlin <dan@cgsoftware.com>.
@@ -62,7 +62,7 @@ struct tagged_conflict
In the process of building the interference graph web parts are
connected together, if they have common instructions and reference the
same register. That way live ranges are build (by connecting defs and
- uses) and implicitely complete webs (by connecting web parts in common
+ uses) and implicitly complete webs (by connecting web parts in common
uses). */
struct web_part
{
@@ -168,6 +168,11 @@ struct web
was illegal for hardregs in CLASS_CANNOT_CHANGE_MODE. */
unsigned int mode_changed:1;
+ /* Nonzero if some references of this web, where in subreg context,
+ but the actual subreg is already stripped (i.e. we don't know the
+ outer mode of the actual reference). */
+ unsigned int subreg_stripped:1;
+
/* Nonzero, when this web stems from the last pass of the allocator,
and all info is still valid (i.e. it wasn't spilled). */
unsigned int old_web:1;
@@ -258,7 +263,7 @@ struct web
/* Number of usable colors in usable_regs. */
int num_freedom;
- /* After successfull coloring the graph each web gets a new reg rtx,
+ /* After successful coloring the graph each web gets a new reg rtx,
with which the original uses and defs are replaced. This is it. */
rtx reg_rtx;
@@ -378,7 +383,7 @@ extern sbitmap igraph;
/* This is the bitmap of all (even partly) conflicting super webs.
If bit I*num_webs+J or J*num_webs+I is set, then I and J (both being
super web indices) conflict, maybe only partially. Note the
- assymetry. */
+ asymmetry. */
extern sbitmap sup_igraph;
/* After the first pass, and when interference region spilling is
@@ -430,7 +435,7 @@ extern struct df *df;
which backward reach the end of B. */
extern bitmap *live_at_end;
-/* One pass is: collecting registers refs, buiding I-graph, spilling.
+/* One pass is: collecting registers refs, building I-graph, spilling.
And this is how often we already ran that for the current function. */
extern int ra_pass;
@@ -461,7 +466,7 @@ extern struct dlist *web_lists[(int) LAST_NODE_TYPE];
/* The largest DF_REF_ID of defs resp. uses, as it was in the
last pass. In the first pass this is zero. Used to distinguish new
- from old refrences. */
+ from old references. */
extern unsigned int last_def_id;
extern unsigned int last_use_id;
@@ -491,12 +496,14 @@ extern HARD_REG_SET usable_regs[N_REG_CLASSES];
/* For each class C the count of hardregs in usable_regs[C]. */
extern unsigned int num_free_regs[N_REG_CLASSES];
/* For each mode M the hardregs, which are MODE_OK for M, and have
- enough space behind them to hold an M value. Additinally
+ enough space behind them to hold an M value. Additionally
if reg R is OK for mode M, but it needs two hardregs, then R+1 will
also be set here, even if R+1 itself is not OK for M. I.e. this
represent the possible resources which could be taken away be a value
in mode M. */
extern HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES];
+/* The set of hardregs, for which _any_ mode change is invalid. */
+extern HARD_REG_SET invalid_mode_change_regs;
/* For 0 <= I <= 255, the number of bits set in I. Used to calculate
the number of set bits in a HARD_REG_SET. */
extern unsigned char byte2bitcount[256];
@@ -556,69 +563,67 @@ extern int flag_ra_break_aliases;
extern int flag_ra_merge_spill_costs;
/* Nonzero if we want to spill at every use, instead of at deaths,
- or intereference region borders. */
+ or interference region borders. */
extern int flag_ra_spill_every_use;
/* Nonzero to output all notes in the debug dumps. */
extern int flag_ra_dump_notes;
-extern inline void * ra_alloc PARAMS ((size_t));
-extern inline void * ra_calloc PARAMS ((size_t));
-extern int hard_regs_count PARAMS ((HARD_REG_SET));
-extern rtx ra_emit_move_insn PARAMS ((rtx, rtx));
-extern void ra_debug_msg PARAMS ((unsigned int,
- const char *, ...)) ATTRIBUTE_PRINTF_2;
-extern int hard_regs_intersect_p PARAMS ((HARD_REG_SET *, HARD_REG_SET *));
-extern unsigned int rtx_to_bits PARAMS ((rtx));
-extern struct web * find_subweb PARAMS ((struct web *, rtx));
-extern struct web * find_subweb_2 PARAMS ((struct web *, unsigned int));
-extern struct web * find_web_for_subweb_1 PARAMS ((struct web *));
+extern void * ra_alloc (size_t);
+extern void * ra_calloc (size_t);
+extern int hard_regs_count (HARD_REG_SET);
+extern rtx ra_emit_move_insn (rtx, rtx);
+extern void ra_debug_msg (unsigned int, const char *, ...) ATTRIBUTE_PRINTF_2;
+extern int hard_regs_intersect_p (HARD_REG_SET *, HARD_REG_SET *);
+extern unsigned int rtx_to_bits (rtx);
+extern struct web * find_subweb (struct web *, rtx);
+extern struct web * find_subweb_2 (struct web *, unsigned int);
+extern struct web * find_web_for_subweb_1 (struct web *);
#define find_web_for_subweb(w) (((w)->parent_web) \
? find_web_for_subweb_1 ((w)->parent_web) \
: (w))
-extern void ra_build_realloc PARAMS ((struct df *));
-extern void ra_build_free PARAMS ((void));
-extern void ra_build_free_all PARAMS ((struct df *));
-extern void ra_colorize_init PARAMS ((void));
-extern void ra_colorize_free_all PARAMS ((void));
-extern void ra_rewrite_init PARAMS ((void));
-
-extern void ra_print_rtx PARAMS ((FILE *, rtx, int));
-extern void ra_print_rtx_top PARAMS ((FILE *, rtx, int));
-extern void ra_debug_rtx PARAMS ((rtx));
-extern void ra_debug_insns PARAMS ((rtx, int));
-extern void ra_debug_bbi PARAMS ((int));
-extern void ra_print_rtl_with_bb PARAMS ((FILE *, rtx));
-extern void dump_igraph PARAMS ((struct df *));
-extern void dump_igraph_machine PARAMS ((void));
-extern void dump_constraints PARAMS ((void));
-extern void dump_cost PARAMS ((unsigned int));
-extern void dump_graph_cost PARAMS ((unsigned int, const char *));
-extern void dump_ra PARAMS ((struct df *));
-extern void dump_number_seen PARAMS ((void));
-extern void dump_static_insn_cost PARAMS ((FILE *, const char *,
- const char *));
-extern void dump_web_conflicts PARAMS ((struct web *));
-extern void dump_web_insns PARAMS ((struct web*));
-extern int web_conflicts_p PARAMS ((struct web *, struct web *));
-extern void debug_hard_reg_set PARAMS ((HARD_REG_SET));
-
-extern void remove_list PARAMS ((struct dlist *, struct dlist **));
-extern struct dlist * pop_list PARAMS ((struct dlist **));
-extern void record_conflict PARAMS ((struct web *, struct web *));
-extern int memref_is_stack_slot PARAMS ((rtx));
-extern void build_i_graph PARAMS ((struct df *));
-extern void put_web PARAMS ((struct web *, enum node_type));
-extern void remove_web_from_list PARAMS ((struct web *));
-extern void reset_lists PARAMS ((void));
-extern struct web * alias PARAMS ((struct web *));
-extern void merge_moves PARAMS ((struct web *, struct web *));
-extern void ra_colorize_graph PARAMS ((struct df *));
-
-extern void actual_spill PARAMS ((void));
-extern void emit_colors PARAMS ((struct df *));
-extern void delete_moves PARAMS ((void));
-extern void setup_renumber PARAMS ((int));
-extern void remove_suspicious_death_notes PARAMS ((void));
+extern void ra_build_realloc (struct df *);
+extern void ra_build_free (void);
+extern void ra_build_free_all (struct df *);
+extern void ra_colorize_init (void);
+extern void ra_colorize_free_all (void);
+extern void ra_rewrite_init (void);
+
+extern void ra_print_rtx (FILE *, rtx, int);
+extern void ra_print_rtx_top (FILE *, rtx, int);
+extern void ra_debug_rtx (rtx);
+extern void ra_debug_insns (rtx, int);
+extern void ra_debug_bbi (int);
+extern void ra_print_rtl_with_bb (FILE *, rtx);
+extern void dump_igraph (struct df *);
+extern void dump_igraph_machine (void);
+extern void dump_constraints (void);
+extern void dump_cost (unsigned int);
+extern void dump_graph_cost (unsigned int, const char *);
+extern void dump_ra (struct df *);
+extern void dump_number_seen (void);
+extern void dump_static_insn_cost (FILE *, const char *, const char *);
+extern void dump_web_conflicts (struct web *);
+extern void dump_web_insns (struct web*);
+extern int web_conflicts_p (struct web *, struct web *);
+extern void debug_hard_reg_set (HARD_REG_SET);
+
+extern void remove_list (struct dlist *, struct dlist **);
+extern struct dlist * pop_list (struct dlist **);
+extern void record_conflict (struct web *, struct web *);
+extern int memref_is_stack_slot (rtx);
+extern void build_i_graph (struct df *);
+extern void put_web (struct web *, enum node_type);
+extern void remove_web_from_list (struct web *);
+extern void reset_lists (void);
+extern struct web * alias (struct web *);
+extern void merge_moves (struct web *, struct web *);
+extern void ra_colorize_graph (struct df *);
+
+extern void actual_spill (void);
+extern void emit_colors (struct df *);
+extern void delete_moves (void);
+extern void setup_renumber (int);
+extern void remove_suspicious_death_notes (void);
diff --git a/contrib/gcc/read-rtl.c b/contrib/gcc/read-rtl.c
index 5efd5dc9a202..629390997c25 100644
--- a/contrib/gcc/read-rtl.c
+++ b/contrib/gcc/read-rtl.c
@@ -1,5 +1,6 @@
-/* RTL reader for GNU C Compiler.
- Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002
+/* RTL reader for GCC.
+ Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003
Free Software Foundation, Inc.
This file is part of GCC.
@@ -19,26 +20,28 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "obstack.h"
#include "hashtab.h"
static htab_t md_constants;
-static void fatal_with_file_and_line PARAMS ((FILE *, const char *, ...))
+static void fatal_with_file_and_line (FILE *, const char *, ...)
ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
-static void fatal_expected_char PARAMS ((FILE *, int, int)) ATTRIBUTE_NORETURN;
-static void read_name PARAMS ((char *, FILE *));
-static char *read_string PARAMS ((struct obstack *, FILE *, int));
-static char *read_quoted_string PARAMS ((struct obstack *, FILE *));
-static char *read_braced_string PARAMS ((struct obstack *, FILE *));
-static void read_escape PARAMS ((struct obstack *, FILE *));
-static hashval_t def_hash PARAMS ((const void *));
-static int def_name_eq_p PARAMS ((const void *, const void *));
-static void read_constants PARAMS ((FILE *infile, char *tmp_char));
-static void validate_const_int PARAMS ((FILE *, const char *));
+static void fatal_expected_char (FILE *, int, int) ATTRIBUTE_NORETURN;
+static void read_name (char *, FILE *);
+static char *read_string (struct obstack *, FILE *, int);
+static char *read_quoted_string (struct obstack *, FILE *);
+static char *read_braced_string (struct obstack *, FILE *);
+static void read_escape (struct obstack *, FILE *);
+static hashval_t def_hash (const void *);
+static int def_name_eq_p (const void *, const void *);
+static void read_constants (FILE *infile, char *tmp_char);
+static void validate_const_int (FILE *, const char *);
/* Subroutines of read_rtx. */
@@ -49,15 +52,14 @@ int read_rtx_lineno = 1;
const char *read_rtx_filename = "<unknown>";
static void
-fatal_with_file_and_line VPARAMS ((FILE *infile, const char *msg, ...))
+fatal_with_file_and_line (FILE *infile, const char *msg, ...)
{
char context[64];
size_t i;
int c;
+ va_list ap;
- VA_OPEN (ap, msg);
- VA_FIXEDARG (ap, FILE *, infile);
- VA_FIXEDARG (ap, const char *, msg);
+ va_start (ap, msg);
fprintf (stderr, "%s:%d: ", read_rtx_filename, read_rtx_lineno);
vfprintf (stderr, msg, ap);
@@ -78,7 +80,7 @@ fatal_with_file_and_line VPARAMS ((FILE *infile, const char *msg, ...))
fprintf (stderr, "%s:%d: following context is `%s'\n",
read_rtx_filename, read_rtx_lineno, context);
- VA_CLOSE (ap);
+ va_end (ap);
exit (1);
}
@@ -86,9 +88,7 @@ fatal_with_file_and_line VPARAMS ((FILE *infile, const char *msg, ...))
invalid data. */
static void
-fatal_expected_char (infile, expected_c, actual_c)
- FILE *infile;
- int expected_c, actual_c;
+fatal_expected_char (FILE *infile, int expected_c, int actual_c)
{
fatal_with_file_and_line (infile, "expected character `%c', found `%c'",
expected_c, actual_c);
@@ -100,8 +100,7 @@ fatal_expected_char (infile, expected_c, actual_c)
Tools such as genflags use this function. */
int
-read_skip_spaces (infile)
- FILE *infile;
+read_skip_spaces (FILE *infile)
{
int c;
@@ -153,9 +152,7 @@ read_skip_spaces (infile)
It is terminated by any of the punctuation chars of rtx printed syntax. */
static void
-read_name (str, infile)
- char *str;
- FILE *infile;
+read_name (char *str, FILE *infile)
{
char *p;
int c;
@@ -206,9 +203,7 @@ read_name (str, infile)
/* Subroutine of the string readers. Handles backslash escapes.
Caller has read the backslash, but not placed it into the obstack. */
static void
-read_escape (ob, infile)
- struct obstack *ob;
- FILE *infile;
+read_escape (struct obstack *ob, FILE *infile)
{
int c = getc (infile);
@@ -261,9 +256,7 @@ read_escape (ob, infile)
/* Read a double-quoted string onto the obstack. Caller has scanned
the leading quote. */
static char *
-read_quoted_string (ob, infile)
- struct obstack *ob;
- FILE *infile;
+read_quoted_string (struct obstack *ob, FILE *infile)
{
int c;
@@ -291,17 +284,17 @@ read_quoted_string (ob, infile)
scanned the leading brace. Note that unlike quoted strings,
the outermost braces _are_ included in the string constant. */
static char *
-read_braced_string (ob, infile)
- struct obstack *ob;
- FILE *infile;
+read_braced_string (struct obstack *ob, FILE *infile)
{
int c;
int brace_depth = 1; /* caller-processed */
+ unsigned long starting_read_rtx_lineno = read_rtx_lineno;
obstack_1grow (ob, '{');
while (brace_depth)
{
c = getc (infile); /* Read the string */
+
if (c == '\n')
read_rtx_lineno++;
else if (c == '{')
@@ -313,6 +306,10 @@ read_braced_string (ob, infile)
read_escape (ob, infile);
continue;
}
+ else if (c == EOF)
+ fatal_with_file_and_line
+ (infile, "missing closing } for opening brace on line %lu",
+ starting_read_rtx_lineno);
obstack_1grow (ob, c);
}
@@ -326,10 +323,7 @@ read_braced_string (ob, infile)
and dispatch to the appropriate string constant reader. */
static char *
-read_string (ob, infile, star_if_braced)
- struct obstack *ob;
- FILE *infile;
- int star_if_braced;
+read_string (struct obstack *ob, FILE *infile, int star_if_braced)
{
char *stringbuf;
int saw_paren = 0;
@@ -366,9 +360,10 @@ read_string (ob, infile, star_if_braced)
/* Provide a version of a function to read a long long if the system does
not provide one. */
#if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !defined(HAVE_ATOLL) && !defined(HAVE_ATOQ)
+HOST_WIDE_INT atoll (const char *);
+
HOST_WIDE_INT
-atoll (p)
- const char *p;
+atoll (const char *p)
{
int neg = 0;
HOST_WIDE_INT tmp_wide;
@@ -402,8 +397,7 @@ atoll (p)
/* Given a constant definition, return a hash code for its name. */
static hashval_t
-def_hash (def)
- const void *def;
+def_hash (const void *def)
{
unsigned result, i;
const char *string = ((const struct md_constant *) def)->name;
@@ -415,8 +409,7 @@ def_hash (def)
/* Given two constant definitions, return true if they have the same name. */
static int
-def_name_eq_p (def1, def2)
- const void *def1, *def2;
+def_name_eq_p (const void *def1, const void *def2)
{
return ! strcmp (((const struct md_constant *) def1)->name,
((const struct md_constant *) def2)->name);
@@ -426,9 +419,7 @@ def_name_eq_p (def1, def2)
to read a name or number into. Process a define_constants directive,
starting with the optional space after the "define_constants". */
static void
-read_constants (infile, tmp_char)
- FILE *infile;
- char *tmp_char;
+read_constants (FILE *infile, char *tmp_char)
{
int c;
htab_t defs;
@@ -484,18 +475,14 @@ read_constants (infile, tmp_char)
a pointer a pointer to the constant definition and INFO.
Stops when CALLBACK returns zero. */
void
-traverse_md_constants (callback, info)
- htab_trav callback;
- void *info;
+traverse_md_constants (htab_trav callback, void *info)
{
if (md_constants)
htab_traverse (md_constants, callback, info);
}
static void
-validate_const_int (infile, string)
- FILE *infile;
- const char *string;
+validate_const_int (FILE *infile, const char *string)
{
const char *cp;
int valid = 1;
@@ -520,8 +507,7 @@ validate_const_int (infile, string)
the utilities gen*.c that construct C code from machine descriptions. */
rtx
-read_rtx (infile)
- FILE *infile;
+read_rtx (FILE *infile)
{
int i, j;
RTX_CODE tmp_code;
@@ -650,7 +636,7 @@ again:
{
ungetc (c, infile);
list_counter++;
- obstack_ptr_grow (&vector_stack, (PTR) read_rtx (infile));
+ obstack_ptr_grow (&vector_stack, read_rtx (infile));
}
if (list_counter > 0)
{
diff --git a/contrib/gcc/real.c b/contrib/gcc/real.c
index f775226c1ed4..11927ee59cf8 100644
--- a/contrib/gcc/real.c
+++ b/contrib/gcc/real.c
@@ -1,8 +1,8 @@
/* real.c - software floating point emulation.
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Stephen L. Moshier (moshier@world.std.com).
- Re-written by Richard Henderson <rth@redhat.com>
+ Re-written by Richard Henderson <rth@redhat.com>
This file is part of GCC.
@@ -23,13 +23,15 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "toplev.h"
#include "real.h"
#include "tm_p.h"
/* The floating point model used internally is not exactly IEEE 754
- compliant, and close to the description in the ISO C standard,
+ compliant, and close to the description in the ISO C99 standard,
section 5.2.4.2.2 Characteristics of floating types.
Specifically
@@ -47,21 +49,21 @@
significand is fractional. Normalized significands are in the
range [0.5, 1.0).
- A requirement of the model is that P be larger than than the
- largest supported target floating-point type by at least 2 bits.
- This gives us proper rounding when we truncate to the target type.
- In addition, E must be large enough to hold the smallest supported
- denormal number in a normalized form.
+ A requirement of the model is that P be larger than the largest
+ supported target floating-point type by at least 2 bits. This gives
+ us proper rounding when we truncate to the target type. In addition,
+ E must be large enough to hold the smallest supported denormal number
+ in a normalized form.
Both of these requirements are easily satisfied. The largest target
significand is 113 bits; we store at least 160. The smallest
- denormal number fits in 17 exponent bits; we store 29.
+ denormal number fits in 17 exponent bits; we store 27.
- Note that the decimal string conversion routines are sensitive to
- rounding error. Since the raw arithmetic routines do not themselves
+ Note that the decimal string conversion routines are sensitive to
+ rounding errors. Since the raw arithmetic routines do not themselves
have guard digits or rounding, the computation of 10**exp can
accumulate more than a few digits of error. The previous incarnation
- of real.c successfully used a 144 bit fraction; given the current
+ of real.c successfully used a 144-bit fraction; given the current
layout of REAL_VALUE_TYPE we're forced to expand to at least 160 bits.
Target floating point models that use base 16 instead of base 2
@@ -77,70 +79,54 @@
#error "Some constant folding done by hand to avoid shift count warnings"
#endif
-static void get_zero PARAMS ((REAL_VALUE_TYPE *, int));
-static void get_canonical_qnan PARAMS ((REAL_VALUE_TYPE *, int));
-static void get_canonical_snan PARAMS ((REAL_VALUE_TYPE *, int));
-static void get_inf PARAMS ((REAL_VALUE_TYPE *, int));
-static bool sticky_rshift_significand PARAMS ((REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *,
- unsigned int));
-static void rshift_significand PARAMS ((REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *,
- unsigned int));
-static void lshift_significand PARAMS ((REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *,
- unsigned int));
-static void lshift_significand_1 PARAMS ((REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *));
-static bool add_significands PARAMS ((REAL_VALUE_TYPE *r,
- const REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *));
-static bool sub_significands PARAMS ((REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *, int));
-static void neg_significand PARAMS ((REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *));
-static int cmp_significands PARAMS ((const REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *));
-static int cmp_significand_0 PARAMS ((const REAL_VALUE_TYPE *));
-static void set_significand_bit PARAMS ((REAL_VALUE_TYPE *, unsigned int));
-static void clear_significand_bit PARAMS ((REAL_VALUE_TYPE *, unsigned int));
-static bool test_significand_bit PARAMS ((REAL_VALUE_TYPE *, unsigned int));
-static void clear_significand_below PARAMS ((REAL_VALUE_TYPE *,
- unsigned int));
-static bool div_significands PARAMS ((REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *));
-static void normalize PARAMS ((REAL_VALUE_TYPE *));
-
-static void do_add PARAMS ((REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *, int));
-static void do_multiply PARAMS ((REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *));
-static void do_divide PARAMS ((REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *));
-static int do_compare PARAMS ((const REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *, int));
-static void do_fix_trunc PARAMS ((REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *));
-
-static unsigned long rtd_divmod PARAMS ((REAL_VALUE_TYPE *,
- REAL_VALUE_TYPE *));
-
-static const REAL_VALUE_TYPE * ten_to_ptwo PARAMS ((int));
-static const REAL_VALUE_TYPE * ten_to_mptwo PARAMS ((int));
-static const REAL_VALUE_TYPE * real_digit PARAMS ((int));
-static void times_pten PARAMS ((REAL_VALUE_TYPE *, int));
-
-static void round_for_format PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *));
+static void get_zero (REAL_VALUE_TYPE *, int);
+static void get_canonical_qnan (REAL_VALUE_TYPE *, int);
+static void get_canonical_snan (REAL_VALUE_TYPE *, int);
+static void get_inf (REAL_VALUE_TYPE *, int);
+static bool sticky_rshift_significand (REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *, unsigned int);
+static void rshift_significand (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ unsigned int);
+static void lshift_significand (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ unsigned int);
+static void lshift_significand_1 (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
+static bool add_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *);
+static bool sub_significands (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *, int);
+static void neg_significand (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
+static int cmp_significands (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
+static int cmp_significand_0 (const REAL_VALUE_TYPE *);
+static void set_significand_bit (REAL_VALUE_TYPE *, unsigned int);
+static void clear_significand_bit (REAL_VALUE_TYPE *, unsigned int);
+static bool test_significand_bit (REAL_VALUE_TYPE *, unsigned int);
+static void clear_significand_below (REAL_VALUE_TYPE *, unsigned int);
+static bool div_significands (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *);
+static void normalize (REAL_VALUE_TYPE *);
+
+static bool do_add (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *, int);
+static bool do_multiply (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *);
+static bool do_divide (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *);
+static int do_compare (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int);
+static void do_fix_trunc (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
+
+static unsigned long rtd_divmod (REAL_VALUE_TYPE *, REAL_VALUE_TYPE *);
+
+static const REAL_VALUE_TYPE * ten_to_ptwo (int);
+static const REAL_VALUE_TYPE * ten_to_mptwo (int);
+static const REAL_VALUE_TYPE * real_digit (int);
+static void times_pten (REAL_VALUE_TYPE *, int);
+
+static void round_for_format (const struct real_format *, REAL_VALUE_TYPE *);
/* Initialize R with a positive zero. */
static inline void
-get_zero (r, sign)
- REAL_VALUE_TYPE *r;
- int sign;
+get_zero (REAL_VALUE_TYPE *r, int sign)
{
memset (r, 0, sizeof (*r));
r->sign = sign;
@@ -149,31 +135,26 @@ get_zero (r, sign)
/* Initialize R with the canonical quiet NaN. */
static inline void
-get_canonical_qnan (r, sign)
- REAL_VALUE_TYPE *r;
- int sign;
+get_canonical_qnan (REAL_VALUE_TYPE *r, int sign)
{
memset (r, 0, sizeof (*r));
r->class = rvc_nan;
r->sign = sign;
- r->sig[SIGSZ-1] = SIG_MSB >> 1;
+ r->canonical = 1;
}
static inline void
-get_canonical_snan (r, sign)
- REAL_VALUE_TYPE *r;
- int sign;
+get_canonical_snan (REAL_VALUE_TYPE *r, int sign)
{
memset (r, 0, sizeof (*r));
r->class = rvc_nan;
r->sign = sign;
- r->sig[SIGSZ-1] = SIG_MSB >> 2;
+ r->signalling = 1;
+ r->canonical = 1;
}
static inline void
-get_inf (r, sign)
- REAL_VALUE_TYPE *r;
- int sign;
+get_inf (REAL_VALUE_TYPE *r, int sign)
{
memset (r, 0, sizeof (*r));
r->class = rvc_inf;
@@ -185,10 +166,8 @@ get_inf (r, sign)
significand of R. If any one bits are shifted out, return true. */
static bool
-sticky_rshift_significand (r, a, n)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *a;
- unsigned int n;
+sticky_rshift_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
+ unsigned int n)
{
unsigned long sticky = 0;
unsigned int i, ofs = 0;
@@ -226,10 +205,8 @@ sticky_rshift_significand (r, a, n)
significand of R. */
static void
-rshift_significand (r, a, n)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *a;
- unsigned int n;
+rshift_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
+ unsigned int n)
{
unsigned int i, ofs = n / HOST_BITS_PER_LONG;
@@ -257,10 +234,8 @@ rshift_significand (r, a, n)
significand of R. */
static void
-lshift_significand (r, a, n)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *a;
- unsigned int n;
+lshift_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
+ unsigned int n)
{
unsigned int i, ofs = n / HOST_BITS_PER_LONG;
@@ -285,9 +260,7 @@ lshift_significand (r, a, n)
/* Likewise, but N is specialized to 1. */
static inline void
-lshift_significand_1 (r, a)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *a;
+lshift_significand_1 (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
{
unsigned int i;
@@ -300,9 +273,8 @@ lshift_significand_1 (r, a)
true if there was carry out of the most significant word. */
static inline bool
-add_significands (r, a, b)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *a, *b;
+add_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
+ const REAL_VALUE_TYPE *b)
{
bool carry = false;
int i;
@@ -331,10 +303,8 @@ add_significands (r, a, b)
Return true if there was borrow out of the most significant word. */
static inline bool
-sub_significands (r, a, b, carry)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *a, *b;
- int carry;
+sub_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
+ const REAL_VALUE_TYPE *b, int carry)
{
int i;
@@ -355,14 +325,12 @@ sub_significands (r, a, b, carry)
}
return carry;
-}
+}
/* Negate the significand A, placing the result in R. */
static inline void
-neg_significand (r, a)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *a;
+neg_significand (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
{
bool carry = true;
int i;
@@ -386,13 +354,12 @@ neg_significand (r, a)
r->sig[i] = ri;
}
-}
+}
/* Compare significands. Return tri-state vs zero. */
-static inline int
-cmp_significands (a, b)
- const REAL_VALUE_TYPE *a, *b;
+static inline int
+cmp_significands (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b)
{
int i;
@@ -412,9 +379,8 @@ cmp_significands (a, b)
/* Return true if A is nonzero. */
-static inline int
-cmp_significand_0 (a)
- const REAL_VALUE_TYPE *a;
+static inline int
+cmp_significand_0 (const REAL_VALUE_TYPE *a)
{
int i;
@@ -428,9 +394,7 @@ cmp_significand_0 (a)
/* Set bit N of the significand of R. */
static inline void
-set_significand_bit (r, n)
- REAL_VALUE_TYPE *r;
- unsigned int n;
+set_significand_bit (REAL_VALUE_TYPE *r, unsigned int n)
{
r->sig[n / HOST_BITS_PER_LONG]
|= (unsigned long)1 << (n % HOST_BITS_PER_LONG);
@@ -439,9 +403,7 @@ set_significand_bit (r, n)
/* Clear bit N of the significand of R. */
static inline void
-clear_significand_bit (r, n)
- REAL_VALUE_TYPE *r;
- unsigned int n;
+clear_significand_bit (REAL_VALUE_TYPE *r, unsigned int n)
{
r->sig[n / HOST_BITS_PER_LONG]
&= ~((unsigned long)1 << (n % HOST_BITS_PER_LONG));
@@ -450,9 +412,7 @@ clear_significand_bit (r, n)
/* Test bit N of the significand of R. */
static inline bool
-test_significand_bit (r, n)
- REAL_VALUE_TYPE *r;
- unsigned int n;
+test_significand_bit (REAL_VALUE_TYPE *r, unsigned int n)
{
/* ??? Compiler bug here if we return this expression directly.
The conversion to bool strips the "&1" and we wind up testing
@@ -464,9 +424,7 @@ test_significand_bit (r, n)
/* Clear bits 0..N-1 of the significand of R. */
static void
-clear_significand_below (r, n)
- REAL_VALUE_TYPE *r;
- unsigned int n;
+clear_significand_below (REAL_VALUE_TYPE *r, unsigned int n)
{
int i, w = n / HOST_BITS_PER_LONG;
@@ -480,9 +438,8 @@ clear_significand_below (r, n)
true if the division was inexact. */
static inline bool
-div_significands (r, a, b)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *a, *b;
+div_significands (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
+ const REAL_VALUE_TYPE *b)
{
REAL_VALUE_TYPE u;
int i, bit = SIGNIFICAND_BITS - 1;
@@ -518,8 +475,7 @@ div_significands (r, a, b)
exponent is large enough to handle target denormals normalized.) */
static void
-normalize (r)
- REAL_VALUE_TYPE *r;
+normalize (REAL_VALUE_TYPE *r)
{
int shift = 0, exp;
int i, j;
@@ -560,13 +516,12 @@ normalize (r)
}
}
-/* Return R = A + (SUBTRACT_P ? -B : B). */
+/* Calculate R = A + (SUBTRACT_P ? -B : B). Return true if the
+ result may be inexact due to a loss of precision. */
-static void
-do_add (r, a, b, subtract_p)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *a, *b;
- int subtract_p;
+static bool
+do_add (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
+ const REAL_VALUE_TYPE *b, int subtract_p)
{
int dexp, sign, exp;
REAL_VALUE_TYPE t;
@@ -581,7 +536,7 @@ do_add (r, a, b, subtract_p)
case CLASS2 (rvc_zero, rvc_zero):
/* -0 + -0 = -0, -0 - +0 = -0; all other cases yield +0. */
get_zero (r, sign & !subtract_p);
- return;
+ return false;
case CLASS2 (rvc_zero, rvc_normal):
case CLASS2 (rvc_zero, rvc_inf):
@@ -595,7 +550,7 @@ do_add (r, a, b, subtract_p)
/* R + Inf = Inf. */
*r = *b;
r->sign = sign ^ subtract_p;
- return;
+ return false;
case CLASS2 (rvc_normal, rvc_zero):
case CLASS2 (rvc_inf, rvc_zero):
@@ -607,7 +562,7 @@ do_add (r, a, b, subtract_p)
case CLASS2 (rvc_inf, rvc_normal):
/* Inf + R = Inf. */
*r = *a;
- return;
+ return false;
case CLASS2 (rvc_inf, rvc_inf):
if (subtract_p)
@@ -616,7 +571,7 @@ do_add (r, a, b, subtract_p)
else
/* Inf + Inf = Inf. */
*r = *a;
- return;
+ return false;
case CLASS2 (rvc_normal, rvc_normal):
break;
@@ -646,7 +601,7 @@ do_add (r, a, b, subtract_p)
{
*r = *a;
r->sign = sign;
- return;
+ return true;
}
inexact |= sticky_rshift_significand (&t, b, dexp);
@@ -677,7 +632,7 @@ do_add (r, a, b, subtract_p)
if (++exp > MAX_EXP)
{
get_inf (r, sign);
- return;
+ return true;
}
}
}
@@ -695,18 +650,20 @@ do_add (r, a, b, subtract_p)
r->sign = 0;
else
r->sig[0] |= inexact;
+
+ return inexact;
}
-/* Return R = A * B. */
+/* Calculate R = A * B. Return true if the result may be inexact. */
-static void
-do_multiply (r, a, b)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *a, *b;
+static bool
+do_multiply (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
+ const REAL_VALUE_TYPE *b)
{
REAL_VALUE_TYPE u, t, *rr;
unsigned int i, j, k;
int sign = a->sign ^ b->sign;
+ bool inexact = false;
switch (CLASS2 (a->class, b->class))
{
@@ -715,7 +672,7 @@ do_multiply (r, a, b)
case CLASS2 (rvc_normal, rvc_zero):
/* +-0 * ANY = 0 with appropriate sign. */
get_zero (r, sign);
- return;
+ return false;
case CLASS2 (rvc_zero, rvc_nan):
case CLASS2 (rvc_normal, rvc_nan):
@@ -724,7 +681,7 @@ do_multiply (r, a, b)
/* ANY * NaN = NaN. */
*r = *b;
r->sign = sign;
- return;
+ return false;
case CLASS2 (rvc_nan, rvc_zero):
case CLASS2 (rvc_nan, rvc_normal):
@@ -732,21 +689,20 @@ do_multiply (r, a, b)
/* NaN * ANY = NaN. */
*r = *a;
r->sign = sign;
- return;
+ return false;
case CLASS2 (rvc_zero, rvc_inf):
case CLASS2 (rvc_inf, rvc_zero):
/* 0 * Inf = NaN */
get_canonical_qnan (r, sign);
- return;
+ return false;
case CLASS2 (rvc_inf, rvc_inf):
case CLASS2 (rvc_normal, rvc_inf):
case CLASS2 (rvc_inf, rvc_normal):
/* Inf * Inf = Inf, R * Inf = Inf */
- overflow:
get_inf (r, sign);
- return;
+ return false;
case CLASS2 (rvc_normal, rvc_normal):
break;
@@ -796,13 +752,19 @@ do_multiply (r, a, b)
+ (b->exp - (1-j)*(HOST_BITS_PER_LONG/2)));
if (exp > MAX_EXP)
- goto overflow;
+ {
+ get_inf (r, sign);
+ return true;
+ }
if (exp < -MAX_EXP)
- /* Would underflow to zero, which we shouldn't bother adding. */
- continue;
+ {
+ /* Would underflow to zero, which we shouldn't bother adding. */
+ inexact = true;
+ continue;
+ }
+ memset (&u, 0, sizeof (u));
u.class = rvc_normal;
- u.sign = 0;
u.exp = exp;
for (k = j; k < SIGSZ * 2; k += 2)
@@ -817,21 +779,22 @@ do_multiply (r, a, b)
}
normalize (&u);
- do_add (rr, rr, &u, 0);
+ inexact |= do_add (rr, rr, &u, 0);
}
}
rr->sign = sign;
if (rr != r)
*r = t;
+
+ return inexact;
}
-/* Return R = A / B. */
+/* Calculate R = A / B. Return true if the result may be inexact. */
-static void
-do_divide (r, a, b)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *a, *b;
+static bool
+do_divide (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a,
+ const REAL_VALUE_TYPE *b)
{
int exp, sign = a->sign ^ b->sign;
REAL_VALUE_TYPE t, *rr;
@@ -844,23 +807,22 @@ do_divide (r, a, b)
case CLASS2 (rvc_inf, rvc_inf):
/* Inf / Inf = NaN. */
get_canonical_qnan (r, sign);
- return;
+ return false;
case CLASS2 (rvc_zero, rvc_normal):
case CLASS2 (rvc_zero, rvc_inf):
/* 0 / ANY = 0. */
case CLASS2 (rvc_normal, rvc_inf):
/* R / Inf = 0. */
- underflow:
get_zero (r, sign);
- return;
+ return false;
case CLASS2 (rvc_normal, rvc_zero):
/* R / 0 = Inf. */
case CLASS2 (rvc_inf, rvc_zero):
/* Inf / 0 = Inf. */
get_inf (r, sign);
- return;
+ return false;
case CLASS2 (rvc_zero, rvc_nan):
case CLASS2 (rvc_normal, rvc_nan):
@@ -869,7 +831,7 @@ do_divide (r, a, b)
/* ANY / NaN = NaN. */
*r = *b;
r->sign = sign;
- return;
+ return false;
case CLASS2 (rvc_nan, rvc_zero):
case CLASS2 (rvc_nan, rvc_normal):
@@ -877,13 +839,12 @@ do_divide (r, a, b)
/* NaN / ANY = NaN. */
*r = *a;
r->sign = sign;
- return;
+ return false;
case CLASS2 (rvc_inf, rvc_normal):
/* Inf / R = Inf. */
- overflow:
get_inf (r, sign);
- return;
+ return false;
case CLASS2 (rvc_normal, rvc_normal):
break;
@@ -897,14 +858,22 @@ do_divide (r, a, b)
else
rr = r;
+ /* Make sure all fields in the result are initialized. */
+ get_zero (rr, 0);
rr->class = rvc_normal;
rr->sign = sign;
exp = a->exp - b->exp + 1;
if (exp > MAX_EXP)
- goto overflow;
+ {
+ get_inf (r, sign);
+ return true;
+ }
if (exp < -MAX_EXP)
- goto underflow;
+ {
+ get_zero (r, sign);
+ return true;
+ }
rr->exp = exp;
inexact = div_significands (rr, a, b);
@@ -915,15 +884,16 @@ do_divide (r, a, b)
if (rr != r)
*r = t;
+
+ return inexact;
}
/* Return a tri-state comparison of A vs B. Return NAN_RESULT if
one of the two operands is a NaN. */
static int
-do_compare (a, b, nan_result)
- const REAL_VALUE_TYPE *a, *b;
- int nan_result;
+do_compare (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b,
+ int nan_result)
{
int ret;
@@ -978,9 +948,7 @@ do_compare (a, b, nan_result)
/* Return A truncated to an integral value toward zero. */
static void
-do_fix_trunc (r, a)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *a;
+do_fix_trunc (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *a)
{
*r = *a;
@@ -1007,10 +975,8 @@ do_fix_trunc (r, a)
For a unary operation, leave OP1 NULL. */
void
-real_arithmetic (r, icode, op0, op1)
- REAL_VALUE_TYPE *r;
- int icode;
- const REAL_VALUE_TYPE *op0, *op1;
+real_arithmetic (REAL_VALUE_TYPE *r, int icode, const REAL_VALUE_TYPE *op0,
+ const REAL_VALUE_TYPE *op1)
{
enum tree_code code = icode;
@@ -1072,9 +1038,8 @@ real_arithmetic (r, icode, op0, op1)
/* Legacy. Similar, but return the result directly. */
REAL_VALUE_TYPE
-real_arithmetic2 (icode, op0, op1)
- int icode;
- const REAL_VALUE_TYPE *op0, *op1;
+real_arithmetic2 (int icode, const REAL_VALUE_TYPE *op0,
+ const REAL_VALUE_TYPE *op1)
{
REAL_VALUE_TYPE r;
real_arithmetic (&r, icode, op0, op1);
@@ -1082,9 +1047,8 @@ real_arithmetic2 (icode, op0, op1)
}
bool
-real_compare (icode, op0, op1)
- int icode;
- const REAL_VALUE_TYPE *op0, *op1;
+real_compare (int icode, const REAL_VALUE_TYPE *op0,
+ const REAL_VALUE_TYPE *op1)
{
enum tree_code code = icode;
@@ -1125,8 +1089,7 @@ real_compare (icode, op0, op1)
/* Return floor log2(R). */
int
-real_exponent (r)
- const REAL_VALUE_TYPE *r;
+real_exponent (const REAL_VALUE_TYPE *r)
{
switch (r->class)
{
@@ -1145,10 +1108,7 @@ real_exponent (r)
/* R = OP0 * 2**EXP. */
void
-real_ldexp (r, op0, exp)
- REAL_VALUE_TYPE *r;
- const REAL_VALUE_TYPE *op0;
- int exp;
+real_ldexp (REAL_VALUE_TYPE *r, const REAL_VALUE_TYPE *op0, int exp)
{
*r = *op0;
switch (r->class)
@@ -1176,8 +1136,7 @@ real_ldexp (r, op0, exp)
/* Determine whether a floating-point value X is infinite. */
bool
-real_isinf (r)
- const REAL_VALUE_TYPE *r;
+real_isinf (const REAL_VALUE_TYPE *r)
{
return (r->class == rvc_inf);
}
@@ -1185,8 +1144,7 @@ real_isinf (r)
/* Determine whether a floating-point value X is a NaN. */
bool
-real_isnan (r)
- const REAL_VALUE_TYPE *r;
+real_isnan (const REAL_VALUE_TYPE *r)
{
return (r->class == rvc_nan);
}
@@ -1194,8 +1152,7 @@ real_isnan (r)
/* Determine whether a floating-point value X is negative. */
bool
-real_isneg (r)
- const REAL_VALUE_TYPE *r;
+real_isneg (const REAL_VALUE_TYPE *r)
{
return r->sign;
}
@@ -1203,17 +1160,15 @@ real_isneg (r)
/* Determine whether a floating-point value X is minus zero. */
bool
-real_isnegzero (r)
- const REAL_VALUE_TYPE *r;
+real_isnegzero (const REAL_VALUE_TYPE *r)
{
return r->sign && r->class == rvc_zero;
}
/* Compare two floating-point objects for bitwise identity. */
-extern bool
-real_identical (a, b)
- const REAL_VALUE_TYPE *a, *b;
+bool
+real_identical (const REAL_VALUE_TYPE *a, const REAL_VALUE_TYPE *b)
{
int i;
@@ -1226,22 +1181,29 @@ real_identical (a, b)
{
case rvc_zero:
case rvc_inf:
- break;
+ return true;
case rvc_normal:
if (a->exp != b->exp)
- return false;
- /* FALLTHRU */
+ return false;
+ break;
+
case rvc_nan:
- for (i = 0; i < SIGSZ; ++i)
- if (a->sig[i] != b->sig[i])
- return false;
+ if (a->signalling != b->signalling)
+ return false;
+ /* The significand is ignored for canonical NaNs. */
+ if (a->canonical || b->canonical)
+ return a->canonical == b->canonical;
break;
default:
abort ();
}
+ for (i = 0; i < SIGSZ; ++i)
+ if (a->sig[i] != b->sig[i])
+ return false;
+
return true;
}
@@ -1249,14 +1211,12 @@ real_identical (a, b)
mode MODE. Return true if successful. */
bool
-exact_real_inverse (mode, r)
- enum machine_mode mode;
- REAL_VALUE_TYPE *r;
+exact_real_inverse (enum machine_mode mode, REAL_VALUE_TYPE *r)
{
const REAL_VALUE_TYPE *one = real_digit (1);
REAL_VALUE_TYPE u;
int i;
-
+
if (r->class != rvc_normal)
return false;
@@ -1270,7 +1230,7 @@ exact_real_inverse (mode, r)
/* Find the inverse and truncate to the required mode. */
do_divide (&u, one, r);
real_convert (&u, mode, &u);
-
+
/* The rounding may have overflowed. */
if (u.class != rvc_normal)
return false;
@@ -1287,8 +1247,7 @@ exact_real_inverse (mode, r)
/* Render R as an integer. */
HOST_WIDE_INT
-real_to_integer (r)
- const REAL_VALUE_TYPE *r;
+real_to_integer (const REAL_VALUE_TYPE *r)
{
unsigned HOST_WIDE_INT i;
@@ -1309,6 +1268,10 @@ real_to_integer (r)
case rvc_normal:
if (r->exp <= 0)
goto underflow;
+ /* Only force overflow for unsigned overflow. Signed overflow is
+ undefined, so it doesn't matter what we return, and some callers
+ expect to be able to use this routine for both signed and
+ unsigned conversions. */
if (r->exp > HOST_BITS_PER_WIDE_INT)
goto overflow;
@@ -1337,9 +1300,8 @@ real_to_integer (r)
/* Likewise, but to an integer pair, HI+LOW. */
void
-real_to_integer2 (plow, phigh, r)
- HOST_WIDE_INT *plow, *phigh;
- const REAL_VALUE_TYPE *r;
+real_to_integer2 (HOST_WIDE_INT *plow, HOST_WIDE_INT *phigh,
+ const REAL_VALUE_TYPE *r)
{
REAL_VALUE_TYPE t;
HOST_WIDE_INT low, high;
@@ -1369,6 +1331,10 @@ real_to_integer2 (plow, phigh, r)
exp = r->exp;
if (exp <= 0)
goto underflow;
+ /* Only force overflow for unsigned overflow. Signed overflow is
+ undefined, so it doesn't matter what we return, and some callers
+ expect to be able to use this routine for both signed and
+ unsigned conversions. */
if (exp > 2*HOST_BITS_PER_WIDE_INT)
goto overflow;
@@ -1414,8 +1380,7 @@ real_to_integer2 (plow, phigh, r)
small. */
static unsigned long
-rtd_divmod (num, den)
- REAL_VALUE_TYPE *num, *den;
+rtd_divmod (REAL_VALUE_TYPE *num, REAL_VALUE_TYPE *den)
{
unsigned long q, msb;
int expn = num->exp, expd = den->exp;
@@ -1453,11 +1418,8 @@ rtd_divmod (num, den)
#define M_LOG10_2 0.30102999566398119521
void
-real_to_decimal (str, r_orig, buf_size, digits, crop_trailing_zeros)
- char *str;
- const REAL_VALUE_TYPE *r_orig;
- size_t buf_size, digits;
- int crop_trailing_zeros;
+real_to_decimal (char *str, const REAL_VALUE_TYPE *r_orig, size_t buf_size,
+ size_t digits, int crop_trailing_zeros)
{
const REAL_VALUE_TYPE *one, *ten;
REAL_VALUE_TYPE r, pten, u, v;
@@ -1529,7 +1491,7 @@ real_to_decimal (str, r_orig, buf_size, digits, crop_trailing_zeros)
/* Iterate over the bits of the possible powers of 10 that might
be present in U and eliminate them. That is, if we find that
- 10**2**M divides U evenly, keep the division and increase
+ 10**2**M divides U evenly, keep the division and increase
DEC_EXP by 2**M. */
do
{
@@ -1550,7 +1512,7 @@ real_to_decimal (str, r_orig, buf_size, digits, crop_trailing_zeros)
r = u;
/* Find power of 10. Do this by dividing out 10**2**M when
- this is larger than the current remainder. Fill PTEN with
+ this is larger than the current remainder. Fill PTEN with
the power of 10 that we compute. */
if (r.exp > 0)
{
@@ -1705,7 +1667,7 @@ real_to_decimal (str, r_orig, buf_size, digits, crop_trailing_zeros)
dec_exp++;
}
}
-
+
/* Insert the decimal point. */
first[0] = first[1];
first[1] = '.';
@@ -1725,11 +1687,8 @@ real_to_decimal (str, r_orig, buf_size, digits, crop_trailing_zeros)
strip trailing zeros. */
void
-real_to_hexadecimal (str, r, buf_size, digits, crop_trailing_zeros)
- char *str;
- const REAL_VALUE_TYPE *r;
- size_t buf_size, digits;
- int crop_trailing_zeros;
+real_to_hexadecimal (char *str, const REAL_VALUE_TYPE *r, size_t buf_size,
+ size_t digits, int crop_trailing_zeros)
{
int i, j, exp = r->exp;
char *p, *first;
@@ -1795,9 +1754,7 @@ real_to_hexadecimal (str, r, buf_size, digits, crop_trailing_zeros)
assumed to have been syntax checked already. */
void
-real_from_string (r, str)
- REAL_VALUE_TYPE *r;
- const char *str;
+real_from_string (REAL_VALUE_TYPE *r, const char *str)
{
int exp = 0;
bool sign = false;
@@ -1812,7 +1769,7 @@ real_from_string (r, str)
else if (*str == '+')
str++;
- if (str[0] == '0' && str[1] == 'x')
+ if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
{
/* Hexadecimal floating point. */
int pos = SIGNIFICAND_BITS - 4, d;
@@ -1981,9 +1938,7 @@ real_from_string (r, str)
/* Legacy. Similar, but return the result directly. */
REAL_VALUE_TYPE
-real_from_string2 (s, mode)
- const char *s;
- enum machine_mode mode;
+real_from_string2 (const char *s, enum machine_mode mode)
{
REAL_VALUE_TYPE r;
@@ -1997,12 +1952,9 @@ real_from_string2 (s, mode)
/* Initialize R from the integer pair HIGH+LOW. */
void
-real_from_integer (r, mode, low, high, unsigned_p)
- REAL_VALUE_TYPE *r;
- enum machine_mode mode;
- unsigned HOST_WIDE_INT low;
- HOST_WIDE_INT high;
- int unsigned_p;
+real_from_integer (REAL_VALUE_TYPE *r, enum machine_mode mode,
+ unsigned HOST_WIDE_INT low, HOST_WIDE_INT high,
+ int unsigned_p)
{
if (low == 0 && high == 0)
get_zero (r, 0);
@@ -2049,8 +2001,7 @@ real_from_integer (r, mode, low, high, unsigned_p)
/* Returns 10**2**N. */
static const REAL_VALUE_TYPE *
-ten_to_ptwo (n)
- int n;
+ten_to_ptwo (int n)
{
static REAL_VALUE_TYPE tens[EXP_BITS];
@@ -2082,8 +2033,7 @@ ten_to_ptwo (n)
/* Returns 10**(-2**N). */
static const REAL_VALUE_TYPE *
-ten_to_mptwo (n)
- int n;
+ten_to_mptwo (int n)
{
static REAL_VALUE_TYPE tens[EXP_BITS];
@@ -2099,8 +2049,7 @@ ten_to_mptwo (n)
/* Returns N. */
static const REAL_VALUE_TYPE *
-real_digit (n)
- int n;
+real_digit (int n)
{
static REAL_VALUE_TYPE num[10];
@@ -2116,9 +2065,7 @@ real_digit (n)
/* Multiply R by 10**EXP. */
static void
-times_pten (r, exp)
- REAL_VALUE_TYPE *r;
- int exp;
+times_pten (REAL_VALUE_TYPE *r, int exp)
{
REAL_VALUE_TYPE pten, *rr;
bool negative = (exp < 0);
@@ -2144,8 +2091,7 @@ times_pten (r, exp)
/* Fills R with +Inf. */
void
-real_inf (r)
- REAL_VALUE_TYPE *r;
+real_inf (REAL_VALUE_TYPE *r)
{
get_inf (r, 0);
}
@@ -2156,15 +2102,12 @@ real_inf (r)
if the string was successfully parsed. */
bool
-real_nan (r, str, quiet, mode)
- REAL_VALUE_TYPE *r;
- const char *str;
- int quiet;
- enum machine_mode mode;
+real_nan (REAL_VALUE_TYPE *r, const char *str, int quiet,
+ enum machine_mode mode)
{
const struct real_format *fmt;
- fmt = real_format_for_mode[mode - QFmode];
+ fmt = REAL_MODE_FORMAT (mode);
if (fmt == NULL)
abort ();
@@ -2233,40 +2176,46 @@ real_nan (r, str, quiet, mode)
/* Shift the significand into place such that the bits
are in the most significant bits for the format. */
- lshift_significand (r, r, SIGNIFICAND_BITS - fmt->p);
+ lshift_significand (r, r, SIGNIFICAND_BITS - fmt->pnan);
/* Our MSB is always unset for NaNs. */
r->sig[SIGSZ-1] &= ~SIG_MSB;
/* Force quiet or signalling NaN. */
- if (quiet)
- r->sig[SIGSZ-1] |= SIG_MSB >> 1;
- else
- r->sig[SIGSZ-1] &= ~(SIG_MSB >> 1);
-
- /* Force at least one bit of the significand set. */
- for (d = 0; d < SIGSZ; ++d)
- if (r->sig[d])
- break;
- if (d == SIGSZ)
- r->sig[SIGSZ-1] |= SIG_MSB >> 2;
-
- /* Our intermediate format forces QNaNs to have MSB-1 set.
- If the target format has QNaNs with the top bit unset,
- mirror the output routines and invert the top two bits. */
- if (!fmt->qnan_msb_set)
- r->sig[SIGSZ-1] ^= (SIG_MSB >> 1) | (SIG_MSB >> 2);
+ r->signalling = !quiet;
}
return true;
}
+/* Fills R with the largest finite value representable in mode MODE.
+ If SIGN is nonzero, R is set to the most negative finite value. */
+
+void
+real_maxval (REAL_VALUE_TYPE *r, int sign, enum machine_mode mode)
+{
+ const struct real_format *fmt;
+ int np2;
+
+ fmt = REAL_MODE_FORMAT (mode);
+ if (fmt == NULL)
+ abort ();
+
+ r->class = rvc_normal;
+ r->sign = sign;
+ r->signalling = 0;
+ r->canonical = 0;
+ r->exp = fmt->emax * fmt->log2_b;
+
+ np2 = SIGNIFICAND_BITS - fmt->p * fmt->log2_b;
+ memset (r->sig, -1, SIGSZ * sizeof (unsigned long));
+ clear_significand_below (r, np2);
+}
+
/* Fills R with 2**N. */
void
-real_2expN (r, n)
- REAL_VALUE_TYPE *r;
- int n;
+real_2expN (REAL_VALUE_TYPE *r, int n)
{
memset (r, 0, sizeof (*r));
@@ -2285,9 +2234,7 @@ real_2expN (r, n)
static void
-round_for_format (fmt, r)
- const struct real_format *fmt;
- REAL_VALUE_TYPE *r;
+round_for_format (const struct real_format *fmt, REAL_VALUE_TYPE *r)
{
int p2, np2, i, w;
unsigned long sticky;
@@ -2315,14 +2262,6 @@ round_for_format (fmt, r)
case rvc_nan:
clear_significand_below (r, np2);
-
- /* If we've cleared the entire significand, we need one bit
- set for this to continue to be a NaN. */
- for (i = 0; i < SIGSZ; ++i)
- if (r->sig[i])
- break;
- if (i == SIGSZ)
- r->sig[SIGSZ-1] = SIG_MSB >> 2;
return;
case rvc_normal:
@@ -2426,14 +2365,12 @@ round_for_format (fmt, r)
/* Extend or truncate to a new mode. */
void
-real_convert (r, mode, a)
- REAL_VALUE_TYPE *r;
- enum machine_mode mode;
- const REAL_VALUE_TYPE *a;
+real_convert (REAL_VALUE_TYPE *r, enum machine_mode mode,
+ const REAL_VALUE_TYPE *a)
{
const struct real_format *fmt;
- fmt = real_format_for_mode[mode - QFmode];
+ fmt = REAL_MODE_FORMAT (mode);
if (fmt == NULL)
abort ();
@@ -2448,9 +2385,7 @@ real_convert (r, mode, a)
/* Legacy. Likewise, except return the struct directly. */
REAL_VALUE_TYPE
-real_value_truncate (mode, a)
- enum machine_mode mode;
- REAL_VALUE_TYPE a;
+real_value_truncate (enum machine_mode mode, REAL_VALUE_TYPE a)
{
REAL_VALUE_TYPE r;
real_convert (&r, mode, &a);
@@ -2460,9 +2395,7 @@ real_value_truncate (mode, a)
/* Return true if truncating to MODE is exact. */
bool
-exact_real_truncate (mode, a)
- enum machine_mode mode;
- const REAL_VALUE_TYPE *a;
+exact_real_truncate (enum machine_mode mode, const REAL_VALUE_TYPE *a)
{
REAL_VALUE_TYPE t;
real_convert (&t, mode, a);
@@ -2476,10 +2409,8 @@ exact_real_truncate (mode, a)
Legacy: return word 0 for implementing REAL_VALUE_TO_TARGET_SINGLE. */
long
-real_to_target_fmt (buf, r_orig, fmt)
- long *buf;
- const REAL_VALUE_TYPE *r_orig;
- const struct real_format *fmt;
+real_to_target_fmt (long *buf, const REAL_VALUE_TYPE *r_orig,
+ const struct real_format *fmt)
{
REAL_VALUE_TYPE r;
long buf1;
@@ -2497,14 +2428,11 @@ real_to_target_fmt (buf, r_orig, fmt)
/* Similar, but look up the format from MODE. */
long
-real_to_target (buf, r, mode)
- long *buf;
- const REAL_VALUE_TYPE *r;
- enum machine_mode mode;
+real_to_target (long *buf, const REAL_VALUE_TYPE *r, enum machine_mode mode)
{
const struct real_format *fmt;
- fmt = real_format_for_mode[mode - QFmode];
+ fmt = REAL_MODE_FORMAT (mode);
if (fmt == NULL)
abort ();
@@ -2516,41 +2444,35 @@ real_to_target (buf, r, mode)
long, no matter the size of the host long. */
void
-real_from_target_fmt (r, buf, fmt)
- REAL_VALUE_TYPE *r;
- const long *buf;
- const struct real_format *fmt;
+real_from_target_fmt (REAL_VALUE_TYPE *r, const long *buf,
+ const struct real_format *fmt)
{
(*fmt->decode) (fmt, r, buf);
-}
+}
/* Similar, but look up the format from MODE. */
void
-real_from_target (r, buf, mode)
- REAL_VALUE_TYPE *r;
- const long *buf;
- enum machine_mode mode;
+real_from_target (REAL_VALUE_TYPE *r, const long *buf, enum machine_mode mode)
{
const struct real_format *fmt;
- fmt = real_format_for_mode[mode - QFmode];
+ fmt = REAL_MODE_FORMAT (mode);
if (fmt == NULL)
abort ();
(*fmt->decode) (fmt, r, buf);
-}
+}
/* Return the number of bits in the significand for MODE. */
/* ??? Legacy. Should get access to real_format directly. */
int
-significand_size (mode)
- enum machine_mode mode;
+significand_size (enum machine_mode mode)
{
const struct real_format *fmt;
- fmt = real_format_for_mode[mode - QFmode];
+ fmt = REAL_MODE_FORMAT (mode);
if (fmt == NULL)
return 0;
@@ -2562,8 +2484,7 @@ significand_size (mode)
but I didn't want to pull hashtab.h into real.h. */
unsigned int
-real_hash (r)
- const REAL_VALUE_TYPE *r;
+real_hash (const REAL_VALUE_TYPE *r)
{
unsigned int h;
size_t i;
@@ -2573,43 +2494,46 @@ real_hash (r)
{
case rvc_zero:
case rvc_inf:
- break;
+ return h;
case rvc_normal:
h |= r->exp << 3;
- /* FALLTHRU */
+ break;
case rvc_nan:
- if (sizeof(unsigned long) > sizeof(unsigned int))
- for (i = 0; i < SIGSZ; ++i)
- {
- unsigned long s = r->sig[i];
- h ^= s ^ (s >> (HOST_BITS_PER_LONG / 2));
- }
- else
- for (i = 0; i < SIGSZ; ++i)
- h ^= r->sig[i];
+ if (r->signalling)
+ h ^= (unsigned int)-1;
+ if (r->canonical)
+ return h;
break;
default:
abort ();
}
+ if (sizeof(unsigned long) > sizeof(unsigned int))
+ for (i = 0; i < SIGSZ; ++i)
+ {
+ unsigned long s = r->sig[i];
+ h ^= s ^ (s >> (HOST_BITS_PER_LONG / 2));
+ }
+ else
+ for (i = 0; i < SIGSZ; ++i)
+ h ^= r->sig[i];
+
return h;
}
/* IEEE single-precision format. */
-static void encode_ieee_single PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_ieee_single PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
+static void encode_ieee_single (const struct real_format *fmt,
+ long *, const REAL_VALUE_TYPE *);
+static void decode_ieee_single (const struct real_format *,
+ REAL_VALUE_TYPE *, const long *);
static void
-encode_ieee_single (fmt, buf, r)
- const struct real_format *fmt;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_ieee_single (const struct real_format *fmt, long *buf,
+ const REAL_VALUE_TYPE *r)
{
unsigned long image, sig, exp;
unsigned long sign = r->sign;
@@ -2633,10 +2557,23 @@ encode_ieee_single (fmt, buf, r)
case rvc_nan:
if (fmt->has_nans)
{
+ if (r->canonical)
+ sig = 0;
+ if (r->signalling == fmt->qnan_msb_set)
+ sig &= ~(1 << 22);
+ else
+ sig |= 1 << 22;
+ /* We overload qnan_msb_set here: it's only clear for
+ mips_ieee_single, which wants all mantissa bits but the
+ quiet/signalling one set in canonical NaNs (at least
+ Quiet ones). */
+ if (r->canonical && !fmt->qnan_msb_set)
+ sig |= (1 << 22) - 1;
+ else if (sig == 0)
+ sig = 1 << 21;
+
image |= 255 << 23;
image |= sig;
- if (!fmt->qnan_msb_set)
- image ^= 1 << 23 | 1 << 22;
}
else
image |= 0x7fffffff;
@@ -2662,10 +2599,8 @@ encode_ieee_single (fmt, buf, r)
}
static void
-decode_ieee_single (fmt, r, buf)
- const struct real_format *fmt;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_ieee_single (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+ const long *buf)
{
unsigned long image = buf[0] & 0xffffffff;
bool sign = (image >> 31) & 1;
@@ -2694,8 +2629,8 @@ decode_ieee_single (fmt, r, buf)
{
r->class = rvc_nan;
r->sign = sign;
- if (!fmt->qnan_msb_set)
- image ^= (SIG_MSB >> 1 | SIG_MSB >> 2);
+ r->signalling = (((image >> (HOST_BITS_PER_LONG - 2)) & 1)
+ ^ fmt->qnan_msb_set);
r->sig[SIGSZ-1] = image;
}
else
@@ -2713,15 +2648,17 @@ decode_ieee_single (fmt, r, buf)
}
}
-const struct real_format ieee_single_format =
+const struct real_format ieee_single_format =
{
encode_ieee_single,
decode_ieee_single,
2,
1,
24,
+ 24,
-125,
128,
+ 31,
true,
true,
true,
@@ -2729,19 +2666,35 @@ const struct real_format ieee_single_format =
true
};
+const struct real_format mips_single_format =
+ {
+ encode_ieee_single,
+ decode_ieee_single,
+ 2,
+ 1,
+ 24,
+ 24,
+ -125,
+ 128,
+ 31,
+ true,
+ true,
+ true,
+ true,
+ false
+ };
+
/* IEEE double-precision format. */
-static void encode_ieee_double PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_ieee_double PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
+static void encode_ieee_double (const struct real_format *fmt,
+ long *, const REAL_VALUE_TYPE *);
+static void decode_ieee_double (const struct real_format *,
+ REAL_VALUE_TYPE *, const long *);
static void
-encode_ieee_double (fmt, buf, r)
- const struct real_format *fmt;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_ieee_double (const struct real_format *fmt, long *buf,
+ const REAL_VALUE_TYPE *r)
{
unsigned long image_lo, image_hi, sig_lo, sig_hi, exp;
bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
@@ -2781,10 +2734,26 @@ encode_ieee_double (fmt, buf, r)
case rvc_nan:
if (fmt->has_nans)
{
+ if (r->canonical)
+ sig_hi = sig_lo = 0;
+ if (r->signalling == fmt->qnan_msb_set)
+ sig_hi &= ~(1 << 19);
+ else
+ sig_hi |= 1 << 19;
+ /* We overload qnan_msb_set here: it's only clear for
+ mips_ieee_single, which wants all mantissa bits but the
+ quiet/signalling one set in canonical NaNs (at least
+ Quiet ones). */
+ if (r->canonical && !fmt->qnan_msb_set)
+ {
+ sig_hi |= (1 << 19) - 1;
+ sig_lo = 0xffffffff;
+ }
+ else if (sig_hi == 0 && sig_lo == 0)
+ sig_hi = 1 << 18;
+
image_hi |= 2047 << 20;
image_hi |= sig_hi;
- if (!fmt->qnan_msb_set)
- image_hi ^= 1 << 19 | 1 << 18;
image_lo = sig_lo;
}
else
@@ -2818,10 +2787,8 @@ encode_ieee_double (fmt, buf, r)
}
static void
-decode_ieee_double (fmt, r, buf)
- const struct real_format *fmt;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_ieee_double (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+ const long *buf)
{
unsigned long image_hi, image_lo;
bool sign;
@@ -2874,6 +2841,7 @@ decode_ieee_double (fmt, r, buf)
{
r->class = rvc_nan;
r->sign = sign;
+ r->signalling = ((image_hi >> 30) & 1) ^ fmt->qnan_msb_set;
if (HOST_BITS_PER_LONG == 32)
{
r->sig[SIGSZ-1] = image_hi;
@@ -2881,9 +2849,6 @@ decode_ieee_double (fmt, r, buf)
}
else
r->sig[SIGSZ-1] = (image_hi << 31 << 1) | image_lo;
-
- if (!fmt->qnan_msb_set)
- r->sig[SIGSZ-1] ^= (SIG_MSB >> 1 | SIG_MSB >> 2);
}
else
{
@@ -2906,15 +2871,17 @@ decode_ieee_double (fmt, r, buf)
}
}
-const struct real_format ieee_double_format =
+const struct real_format ieee_double_format =
{
encode_ieee_double,
decode_ieee_double,
2,
1,
53,
+ 53,
-1021,
1024,
+ 63,
true,
true,
true,
@@ -2922,28 +2889,36 @@ const struct real_format ieee_double_format =
true
};
-
-/* IEEE extended double precision format. This comes in three
- flavours: Intel's as a 12 byte image, Intel's as a 16 byte image,
- and Motorola's. */
-
-static void encode_ieee_extended PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_ieee_extended PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
-
-static void encode_ieee_extended_128 PARAMS ((const struct real_format *fmt,
- long *,
- const REAL_VALUE_TYPE *));
-static void decode_ieee_extended_128 PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *,
- const long *));
+const struct real_format mips_double_format =
+ {
+ encode_ieee_double,
+ decode_ieee_double,
+ 2,
+ 1,
+ 53,
+ 53,
+ -1021,
+ 1024,
+ 63,
+ true,
+ true,
+ true,
+ true,
+ false
+ };
+
+/* IEEE extended real format. This comes in three flavors: Intel's as
+ a 12 byte image, Intel's as a 16 byte image, and Motorola's. Intel
+ 12- and 16-byte images may be big- or little endian; Motorola's is
+ always big endian. */
+
+/* Helper subroutine which converts from the internal format to the
+ 12-byte little-endian Intel format. Functions below adjust this
+ for the other possible formats. */
static void
-encode_ieee_extended (fmt, buf, r)
- const struct real_format *fmt;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_ieee_extended (const struct real_format *fmt, long *buf,
+ const REAL_VALUE_TYPE *r)
{
unsigned long image_hi, sig_hi, sig_lo;
bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
@@ -2988,8 +2963,12 @@ encode_ieee_extended (fmt, buf, r)
sig_hi = sig_lo >> 31 >> 1;
sig_lo &= 0xffffffff;
}
- if (!fmt->qnan_msb_set)
- sig_hi ^= 1 << 30 | 1 << 29;
+ if (r->signalling == fmt->qnan_msb_set)
+ sig_hi &= ~(1 << 30);
+ else
+ sig_hi |= 1 << 30;
+ if ((sig_hi & 0x7fffffff) == 0 && sig_lo == 0)
+ sig_hi = 1 << 29;
/* Intel requires the explicit integer bit to be set, otherwise
it considers the value a "pseudo-nan". Motorola docs say it
@@ -3009,11 +2988,11 @@ encode_ieee_extended (fmt, buf, r)
/* 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.
+ Which means we're off by one.
Except for Motorola, which consider exp=0 and explicit
integer bit set to continue to be normalized. In theory
- this descrepency has been taken care of by the difference
+ this discrepancy has been taken care of by the difference
in fmt->emin in round_for_format. */
if (denormal)
@@ -3044,36 +3023,74 @@ encode_ieee_extended (fmt, buf, r)
abort ();
}
+ buf[0] = sig_lo, buf[1] = sig_hi, buf[2] = image_hi;
+}
+
+/* Convert from the internal format to the 12-byte Motorola format
+ for an IEEE extended real. */
+static void
+encode_ieee_extended_motorola (const struct real_format *fmt, long *buf,
+ const REAL_VALUE_TYPE *r)
+{
+ long intermed[3];
+ encode_ieee_extended (fmt, intermed, r);
+
+ /* Motorola chips are assumed always to be big-endian. Also, the
+ padding in a Motorola extended real goes between the exponent and
+ the mantissa. At this point the mantissa is entirely within
+ elements 0 and 1 of intermed, and the exponent entirely within
+ element 2, so all we have to do is swap the order around, and
+ shift element 2 left 16 bits. */
+ buf[0] = intermed[2] << 16;
+ buf[1] = intermed[1];
+ buf[2] = intermed[0];
+}
+
+/* Convert from the internal format to the 12-byte Intel format for
+ an IEEE extended real. */
+static void
+encode_ieee_extended_intel_96 (const struct real_format *fmt, long *buf,
+ const REAL_VALUE_TYPE *r)
+{
if (FLOAT_WORDS_BIG_ENDIAN)
- buf[0] = image_hi << 16, buf[1] = sig_hi, buf[2] = sig_lo;
+ {
+ /* All the padding in an Intel-format extended real goes at the high
+ end, which in this case is after the mantissa, not the exponent.
+ Therefore we must shift everything down 16 bits. */
+ long intermed[3];
+ encode_ieee_extended (fmt, intermed, r);
+ buf[0] = ((intermed[2] << 16) | ((unsigned long)(intermed[1] & 0xFFFF0000) >> 16));
+ buf[1] = ((intermed[1] << 16) | ((unsigned long)(intermed[0] & 0xFFFF0000) >> 16));
+ buf[2] = (intermed[0] << 16);
+ }
else
- buf[0] = sig_lo, buf[1] = sig_hi, buf[2] = image_hi;
+ /* encode_ieee_extended produces what we want directly. */
+ encode_ieee_extended (fmt, buf, r);
}
+/* Convert from the internal format to the 16-byte Intel format for
+ an IEEE extended real. */
static void
-encode_ieee_extended_128 (fmt, buf, r)
- const struct real_format *fmt;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_ieee_extended_intel_128 (const struct real_format *fmt, long *buf,
+ const REAL_VALUE_TYPE *r)
{
- buf[3 * !FLOAT_WORDS_BIG_ENDIAN] = 0;
- encode_ieee_extended (fmt, buf+!!FLOAT_WORDS_BIG_ENDIAN, r);
+ /* All the padding in an Intel-format extended real goes at the high end. */
+ encode_ieee_extended_intel_96 (fmt, buf, r);
+ buf[3] = 0;
}
+/* As above, we have a helper function which converts from 12-byte
+ little-endian Intel format to internal format. Functions below
+ adjust for the other possible formats. */
static void
-decode_ieee_extended (fmt, r, buf)
- const struct real_format *fmt;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_ieee_extended (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+ const long *buf)
{
unsigned long image_hi, sig_hi, sig_lo;
bool sign;
int exp;
- if (FLOAT_WORDS_BIG_ENDIAN)
- image_hi = buf[0] >> 16, sig_hi = buf[1], sig_lo = buf[2];
- else
- sig_lo = buf[0], sig_hi = buf[1], image_hi = buf[2];
+ sig_lo = buf[0], sig_hi = buf[1], image_hi = buf[2];
sig_lo &= 0xffffffff;
sig_hi &= 0xffffffff;
image_hi &= 0xffffffff;
@@ -3120,6 +3137,7 @@ decode_ieee_extended (fmt, r, buf)
{
r->class = rvc_nan;
r->sign = sign;
+ r->signalling = ((sig_hi >> 30) & 1) ^ fmt->qnan_msb_set;
if (HOST_BITS_PER_LONG == 32)
{
r->sig[SIGSZ-1] = sig_hi;
@@ -3127,9 +3145,6 @@ decode_ieee_extended (fmt, r, buf)
}
else
r->sig[SIGSZ-1] = (sig_hi << 31 << 1) | sig_lo;
-
- if (!fmt->qnan_msb_set)
- r->sig[SIGSZ-1] ^= (SIG_MSB >> 1 | SIG_MSB >> 2);
}
else
{
@@ -3152,24 +3167,69 @@ decode_ieee_extended (fmt, r, buf)
}
}
+/* Convert from the internal format to the 12-byte Motorola format
+ for an IEEE extended real. */
+static void
+decode_ieee_extended_motorola (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+ const long *buf)
+{
+ long intermed[3];
+
+ /* Motorola chips are assumed always to be big-endian. Also, the
+ padding in a Motorola extended real goes between the exponent and
+ the mantissa; remove it. */
+ intermed[0] = buf[2];
+ intermed[1] = buf[1];
+ intermed[2] = (unsigned long)buf[0] >> 16;
+
+ decode_ieee_extended (fmt, r, intermed);
+}
+
+/* Convert from the internal format to the 12-byte Intel format for
+ an IEEE extended real. */
+static void
+decode_ieee_extended_intel_96 (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+ const long *buf)
+{
+ if (FLOAT_WORDS_BIG_ENDIAN)
+ {
+ /* All the padding in an Intel-format extended real goes at the high
+ end, which in this case is after the mantissa, not the exponent.
+ Therefore we must shift everything up 16 bits. */
+ long intermed[3];
+
+ intermed[0] = (((unsigned long)buf[2] >> 16) | (buf[1] << 16));
+ intermed[1] = (((unsigned long)buf[1] >> 16) | (buf[0] << 16));
+ intermed[2] = ((unsigned long)buf[0] >> 16);
+
+ decode_ieee_extended (fmt, r, intermed);
+ }
+ else
+ /* decode_ieee_extended produces what we want directly. */
+ decode_ieee_extended (fmt, r, buf);
+}
+
+/* Convert from the internal format to the 16-byte Intel format for
+ an IEEE extended real. */
static void
-decode_ieee_extended_128 (fmt, r, buf)
- const struct real_format *fmt;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_ieee_extended_intel_128 (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+ const long *buf)
{
- decode_ieee_extended (fmt, r, buf+!!FLOAT_WORDS_BIG_ENDIAN);
+ /* All the padding in an Intel-format extended real goes at the high end. */
+ decode_ieee_extended_intel_96 (fmt, r, buf);
}
-const struct real_format ieee_extended_motorola_format =
+const struct real_format ieee_extended_motorola_format =
{
- encode_ieee_extended,
- decode_ieee_extended,
+ encode_ieee_extended_motorola,
+ decode_ieee_extended_motorola,
2,
1,
64,
+ 64,
-16382,
16384,
+ 95,
true,
true,
true,
@@ -3177,15 +3237,17 @@ const struct real_format ieee_extended_motorola_format =
true
};
-const struct real_format ieee_extended_intel_96_format =
+const struct real_format ieee_extended_intel_96_format =
{
- encode_ieee_extended,
- decode_ieee_extended,
+ encode_ieee_extended_intel_96,
+ decode_ieee_extended_intel_96,
2,
1,
64,
+ 64,
-16381,
16384,
+ 79,
true,
true,
true,
@@ -3193,15 +3255,17 @@ const struct real_format ieee_extended_intel_96_format =
true
};
-const struct real_format ieee_extended_intel_128_format =
+const struct real_format ieee_extended_intel_128_format =
{
- encode_ieee_extended_128,
- decode_ieee_extended_128,
+ encode_ieee_extended_intel_128,
+ decode_ieee_extended_intel_128,
2,
1,
64,
+ 64,
-16381,
16384,
+ 79,
true,
true,
true,
@@ -3211,15 +3275,17 @@ const struct real_format ieee_extended_intel_128_format =
/* The following caters to i386 systems that set the rounding precision
to 53 bits instead of 64, e.g. FreeBSD. */
-const struct real_format ieee_extended_intel_96_round_53_format =
+const struct real_format ieee_extended_intel_96_round_53_format =
{
- encode_ieee_extended,
- decode_ieee_extended,
+ encode_ieee_extended_intel_96,
+ decode_ieee_extended_intel_96,
2,
1,
53,
+ 53,
-16381,
16384,
+ 79,
true,
true,
true,
@@ -3236,97 +3302,76 @@ const struct real_format ieee_extended_intel_96_round_53_format =
ignored. Zeroes, Infinities, and NaNs are set in both doubles
due to precedent. */
-static void encode_ibm_extended PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_ibm_extended PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
+static void encode_ibm_extended (const struct real_format *fmt,
+ long *, const REAL_VALUE_TYPE *);
+static void decode_ibm_extended (const struct real_format *,
+ REAL_VALUE_TYPE *, const long *);
static void
-encode_ibm_extended (fmt, buf, r)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_ibm_extended (const struct real_format *fmt, long *buf,
+ const REAL_VALUE_TYPE *r)
{
- REAL_VALUE_TYPE u, v;
-
- switch (r->class)
- {
- case rvc_zero:
- /* Both doubles have sign bit set. */
- buf[0] = FLOAT_WORDS_BIG_ENDIAN ? r->sign << 31 : 0;
- buf[1] = FLOAT_WORDS_BIG_ENDIAN ? 0 : r->sign << 31;
- buf[2] = buf[0];
- buf[3] = buf[1];
- break;
+ REAL_VALUE_TYPE u, normr, v;
+ const struct real_format *base_fmt;
- case rvc_inf:
- case rvc_nan:
- /* Both doubles set to Inf / NaN. */
- encode_ieee_double (&ieee_double_format, &buf[0], r);
- buf[2] = buf[0];
- buf[3] = buf[1];
- return;
-
- case rvc_normal:
- /* u = IEEE double precision portion of significand. */
- u = *r;
- clear_significand_below (&u, SIGNIFICAND_BITS - 53);
-
- normalize (&u);
- /* If the upper double is zero, we have a denormal double, so
- move it to the first double and leave the second as zero. */
- if (u.class == rvc_zero)
- {
- v = u;
- u = *r;
- normalize (&u);
- }
- else
- {
- /* v = remainder containing additional 53 bits of significand. */
- do_add (&v, r, &u, 1);
- round_for_format (&ieee_double_format, &v);
- }
+ base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format;
- round_for_format (&ieee_double_format, &u);
+ /* Renormlize R before doing any arithmetic on it. */
+ normr = *r;
+ if (normr.class == rvc_normal)
+ normalize (&normr);
- encode_ieee_double (&ieee_double_format, &buf[0], &u);
- encode_ieee_double (&ieee_double_format, &buf[2], &v);
- break;
+ /* u = IEEE double precision portion of significand. */
+ u = normr;
+ round_for_format (base_fmt, &u);
+ encode_ieee_double (base_fmt, &buf[0], &u);
- default:
- abort ();
+ if (u.class == rvc_normal)
+ {
+ do_add (&v, &normr, &u, 1);
+ /* Call round_for_format since we might need to denormalize. */
+ round_for_format (base_fmt, &v);
+ encode_ieee_double (base_fmt, &buf[2], &v);
+ }
+ else
+ {
+ /* Inf, NaN, 0 are all representable as doubles, so the
+ least-significant part can be 0.0. */
+ buf[2] = 0;
+ buf[3] = 0;
}
}
static void
-decode_ibm_extended (fmt, r, buf)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_ibm_extended (const struct real_format *fmt ATTRIBUTE_UNUSED, REAL_VALUE_TYPE *r,
+ const long *buf)
{
REAL_VALUE_TYPE u, v;
+ const struct real_format *base_fmt;
- decode_ieee_double (&ieee_double_format, &u, &buf[0]);
+ base_fmt = fmt->qnan_msb_set ? &ieee_double_format : &mips_double_format;
+ decode_ieee_double (base_fmt, &u, &buf[0]);
if (u.class != rvc_zero && u.class != rvc_inf && u.class != rvc_nan)
{
- decode_ieee_double (&ieee_double_format, &v, &buf[2]);
+ decode_ieee_double (base_fmt, &v, &buf[2]);
do_add (r, &u, &v, 0);
}
else
*r = u;
}
-const struct real_format ibm_extended_format =
+const struct real_format ibm_extended_format =
{
encode_ibm_extended,
decode_ibm_extended,
2,
1,
53 + 53,
+ 53,
-1021 + 53,
1024,
+ -1,
true,
true,
true,
@@ -3334,19 +3379,35 @@ const struct real_format ibm_extended_format =
true
};
+const struct real_format mips_extended_format =
+ {
+ encode_ibm_extended,
+ decode_ibm_extended,
+ 2,
+ 1,
+ 53 + 53,
+ 53,
+ -1021 + 53,
+ 1024,
+ -1,
+ true,
+ true,
+ true,
+ true,
+ false
+ };
+
/* IEEE quad precision format. */
-static void encode_ieee_quad PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_ieee_quad PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
+static void encode_ieee_quad (const struct real_format *fmt,
+ long *, const REAL_VALUE_TYPE *);
+static void decode_ieee_quad (const struct real_format *,
+ REAL_VALUE_TYPE *, const long *);
static void
-encode_ieee_quad (fmt, buf, r)
- const struct real_format *fmt;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_ieee_quad (const struct real_format *fmt, long *buf,
+ const REAL_VALUE_TYPE *r)
{
unsigned long image3, image2, image1, image0, exp;
bool denormal = (r->sig[SIGSZ-1] & SIG_MSB) == 0;
@@ -3381,7 +3442,12 @@ encode_ieee_quad (fmt, buf, r)
{
image3 |= 32767 << 16;
- if (HOST_BITS_PER_LONG == 32)
+ if (r->canonical)
+ {
+ /* Don't use bits from the significand. The
+ initialization above is right. */
+ }
+ else if (HOST_BITS_PER_LONG == 32)
{
image0 = u.sig[0];
image1 = u.sig[1];
@@ -3397,9 +3463,21 @@ encode_ieee_quad (fmt, buf, r)
image0 &= 0xffffffff;
image2 &= 0xffffffff;
}
-
- if (!fmt->qnan_msb_set)
- image3 ^= 1 << 15 | 1 << 14;
+ if (r->signalling == fmt->qnan_msb_set)
+ image3 &= ~0x8000;
+ else
+ image3 |= 0x8000;
+ /* We overload qnan_msb_set here: it's only clear for
+ mips_ieee_single, which wants all mantissa bits but the
+ quiet/signalling one set in canonical NaNs (at least
+ Quiet ones). */
+ if (r->canonical && !fmt->qnan_msb_set)
+ {
+ image3 |= 0x7fff;
+ image2 = image1 = image0 = 0xffffffff;
+ }
+ else if (((image3 & 0xffff) | image2 | image1 | image0) == 0)
+ image3 |= 0x4000;
}
else
{
@@ -3459,10 +3537,8 @@ encode_ieee_quad (fmt, buf, r)
}
static void
-decode_ieee_quad (fmt, r, buf)
- const struct real_format *fmt;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_ieee_quad (const struct real_format *fmt, REAL_VALUE_TYPE *r,
+ const long *buf)
{
unsigned long image3, image2, image1, image0;
bool sign;
@@ -3524,6 +3600,7 @@ decode_ieee_quad (fmt, r, buf)
{
r->class = rvc_nan;
r->sign = sign;
+ r->signalling = ((image3 >> 15) & 1) ^ fmt->qnan_msb_set;
if (HOST_BITS_PER_LONG == 32)
{
@@ -3538,9 +3615,6 @@ decode_ieee_quad (fmt, r, buf)
r->sig[1] = (image3 << 31 << 1) | image2;
}
lshift_significand (r, r, SIGNIFICAND_BITS - 113);
-
- if (!fmt->qnan_msb_set)
- r->sig[SIGSZ-1] ^= (SIG_MSB >> 1 | SIG_MSB >> 2);
}
else
{
@@ -3571,50 +3645,68 @@ decode_ieee_quad (fmt, r, buf)
}
}
-const struct real_format ieee_quad_format =
+const struct real_format ieee_quad_format =
{
encode_ieee_quad,
decode_ieee_quad,
2,
1,
113,
+ 113,
-16381,
16384,
+ 127,
true,
true,
true,
true,
true
};
+
+const struct real_format mips_quad_format =
+ {
+ encode_ieee_quad,
+ decode_ieee_quad,
+ 2,
+ 1,
+ 113,
+ 113,
+ -16381,
+ 16384,
+ 127,
+ true,
+ true,
+ true,
+ true,
+ false
+ };
/* Descriptions of VAX floating point formats can be found beginning at
- http://www.openvms.compaq.com:8000/73final/4515/4515pro_013.html#f_floating_point_format
+ http://h71000.www7.hp.com/doc/73FINAL/4515/4515pro_013.html#f_floating_point_format
The thing to remember is that they're almost IEEE, except for word
order, exponent bias, and the lack of infinities, nans, and denormals.
We don't implement the H_floating format here, simply because neither
the VAX or Alpha ports use it. */
-
-static void encode_vax_f PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_vax_f PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
-static void encode_vax_d PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_vax_d PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
-static void encode_vax_g PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_vax_g PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
+
+static void encode_vax_f (const struct real_format *fmt,
+ long *, const REAL_VALUE_TYPE *);
+static void decode_vax_f (const struct real_format *,
+ REAL_VALUE_TYPE *, const long *);
+static void encode_vax_d (const struct real_format *fmt,
+ long *, const REAL_VALUE_TYPE *);
+static void decode_vax_d (const struct real_format *,
+ REAL_VALUE_TYPE *, const long *);
+static void encode_vax_g (const struct real_format *fmt,
+ long *, const REAL_VALUE_TYPE *);
+static void decode_vax_g (const struct real_format *,
+ REAL_VALUE_TYPE *, const long *);
static void
-encode_vax_f (fmt, buf, r)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_vax_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
+ const REAL_VALUE_TYPE *r)
{
unsigned long sign, exp, sig, image;
@@ -3649,10 +3741,8 @@ encode_vax_f (fmt, buf, r)
}
static void
-decode_vax_f (fmt, r, buf)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_vax_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
+ REAL_VALUE_TYPE *r, const long *buf)
{
unsigned long image = buf[0] & 0xffffffff;
int exp = (image >> 7) & 0xff;
@@ -3671,10 +3761,8 @@ decode_vax_f (fmt, r, buf)
}
static void
-encode_vax_d (fmt, buf, r)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_vax_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
+ const REAL_VALUE_TYPE *r)
{
unsigned long image0, image1, sign = r->sign << 15;
@@ -3727,10 +3815,8 @@ encode_vax_d (fmt, buf, r)
}
static void
-decode_vax_d (fmt, r, buf)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_vax_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
+ REAL_VALUE_TYPE *r, const long *buf)
{
unsigned long image0, image1;
int exp;
@@ -3742,7 +3828,7 @@ decode_vax_d (fmt, r, buf)
image0 &= 0xffffffff;
image1 &= 0xffffffff;
- exp = (image0 >> 7) & 0x7f;
+ exp = (image0 >> 7) & 0xff;
memset (r, 0, sizeof (*r));
@@ -3775,10 +3861,8 @@ decode_vax_d (fmt, r, buf)
}
static void
-encode_vax_g (fmt, buf, r)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_vax_g (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
+ const REAL_VALUE_TYPE *r)
{
unsigned long image0, image1, sign = r->sign << 15;
@@ -3831,10 +3915,8 @@ encode_vax_g (fmt, buf, r)
}
static void
-decode_vax_g (fmt, r, buf)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_vax_g (const struct real_format *fmt ATTRIBUTE_UNUSED,
+ REAL_VALUE_TYPE *r, const long *buf)
{
unsigned long image0, image1;
int exp;
@@ -3878,15 +3960,17 @@ decode_vax_g (fmt, r, buf)
}
}
-const struct real_format vax_f_format =
+const struct real_format vax_f_format =
{
encode_vax_f,
decode_vax_f,
2,
1,
24,
+ 24,
-127,
127,
+ 15,
false,
false,
false,
@@ -3894,15 +3978,17 @@ const struct real_format vax_f_format =
false
};
-const struct real_format vax_d_format =
+const struct real_format vax_d_format =
{
encode_vax_d,
decode_vax_d,
2,
1,
56,
+ 56,
-127,
127,
+ 15,
false,
false,
false,
@@ -3910,15 +3996,17 @@ const struct real_format vax_d_format =
false
};
-const struct real_format vax_g_format =
+const struct real_format vax_g_format =
{
encode_vax_g,
decode_vax_g,
2,
1,
53,
+ 53,
-1023,
1023,
+ 15,
false,
false,
false,
@@ -3933,20 +4021,18 @@ const struct real_format vax_g_format =
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/DZ9AR001/9.1?DT=19930923083613
*/
-static void encode_i370_single PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_i370_single PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
-static void encode_i370_double PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_i370_double PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
+static void encode_i370_single (const struct real_format *fmt,
+ long *, const REAL_VALUE_TYPE *);
+static void decode_i370_single (const struct real_format *,
+ REAL_VALUE_TYPE *, const long *);
+static void encode_i370_double (const struct real_format *fmt,
+ long *, const REAL_VALUE_TYPE *);
+static void decode_i370_double (const struct real_format *,
+ REAL_VALUE_TYPE *, const long *);
static void
-encode_i370_single (fmt, buf, r)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_i370_single (const struct real_format *fmt ATTRIBUTE_UNUSED,
+ long *buf, const REAL_VALUE_TYPE *r)
{
unsigned long sign, exp, sig, image;
@@ -3977,10 +4063,8 @@ encode_i370_single (fmt, buf, r)
}
static void
-decode_i370_single (fmt, r, buf)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_i370_single (const struct real_format *fmt ATTRIBUTE_UNUSED,
+ REAL_VALUE_TYPE *r, const long *buf)
{
unsigned long sign, sig, image = buf[0];
int exp;
@@ -4002,10 +4086,8 @@ decode_i370_single (fmt, r, buf)
}
static void
-encode_i370_double (fmt, buf, r)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_i370_double (const struct real_format *fmt ATTRIBUTE_UNUSED,
+ long *buf, const REAL_VALUE_TYPE *r)
{
unsigned long sign, exp, image_hi, image_lo;
@@ -4053,10 +4135,8 @@ encode_i370_double (fmt, buf, r)
}
static void
-decode_i370_double (fmt, r, buf)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_i370_double (const struct real_format *fmt ATTRIBUTE_UNUSED,
+ REAL_VALUE_TYPE *r, const long *buf)
{
unsigned long sign, image_hi, image_lo;
int exp;
@@ -4098,8 +4178,10 @@ const struct real_format i370_single_format =
16,
4,
6,
+ 6,
-64,
63,
+ 31,
false,
false,
false, /* ??? The encoding does allow for "unnormals". */
@@ -4114,8 +4196,10 @@ const struct real_format i370_double_format =
16,
4,
14,
+ 14,
-64,
63,
+ 63,
false,
false,
false, /* ??? The encoding does allow for "unnormals". */
@@ -4142,23 +4226,21 @@ const struct real_format i370_double_format =
See http://www-s.ti.com/sc/psheets/spru063c/spru063c.pdf */
-static void encode_c4x_single PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_c4x_single PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
-static void encode_c4x_extended PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_c4x_extended PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
+static void encode_c4x_single (const struct real_format *fmt,
+ long *, const REAL_VALUE_TYPE *);
+static void decode_c4x_single (const struct real_format *,
+ REAL_VALUE_TYPE *, const long *);
+static void encode_c4x_extended (const struct real_format *fmt,
+ long *, const REAL_VALUE_TYPE *);
+static void decode_c4x_extended (const struct real_format *,
+ REAL_VALUE_TYPE *, const long *);
static void
-encode_c4x_single (fmt, buf, r)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_c4x_single (const struct real_format *fmt ATTRIBUTE_UNUSED,
+ long *buf, const REAL_VALUE_TYPE *r)
{
unsigned long image, exp, sig;
-
+
switch (r->class)
{
case rvc_zero:
@@ -4194,10 +4276,8 @@ encode_c4x_single (fmt, buf, r)
}
static void
-decode_c4x_single (fmt, r, buf)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_c4x_single (const struct real_format *fmt ATTRIBUTE_UNUSED,
+ REAL_VALUE_TYPE *r, const long *buf)
{
unsigned long image = buf[0];
unsigned long sig;
@@ -4229,13 +4309,11 @@ decode_c4x_single (fmt, r, buf)
}
static void
-encode_c4x_extended (fmt, buf, r)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_c4x_extended (const struct real_format *fmt ATTRIBUTE_UNUSED,
+ long *buf, const REAL_VALUE_TYPE *r)
{
unsigned long exp, sig;
-
+
switch (r->class)
{
case rvc_zero:
@@ -4281,10 +4359,8 @@ encode_c4x_extended (fmt, buf, r)
}
static void
-decode_c4x_extended (fmt, r, buf)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_c4x_extended (const struct real_format *fmt ATTRIBUTE_UNUSED,
+ REAL_VALUE_TYPE *r, const long *buf)
{
unsigned long sig;
int exp, sf;
@@ -4321,15 +4397,17 @@ decode_c4x_extended (fmt, r, buf)
}
}
-const struct real_format c4x_single_format =
+const struct real_format c4x_single_format =
{
encode_c4x_single,
decode_c4x_single,
2,
1,
24,
+ 24,
-126,
128,
+ -1,
false,
false,
false,
@@ -4337,15 +4415,17 @@ const struct real_format c4x_single_format =
false
};
-const struct real_format c4x_extended_format =
+const struct real_format c4x_extended_format =
{
encode_c4x_extended,
decode_c4x_extended,
2,
1,
32,
+ 32,
-126,
128,
+ -1,
false,
false,
false,
@@ -4359,58 +4439,210 @@ const struct real_format c4x_extended_format =
The encode and decode routines exist only to satisfy our paranoia
harness. */
-static void encode_internal PARAMS ((const struct real_format *fmt,
- long *, const REAL_VALUE_TYPE *));
-static void decode_internal PARAMS ((const struct real_format *,
- REAL_VALUE_TYPE *, const long *));
+static void encode_internal (const struct real_format *fmt,
+ long *, const REAL_VALUE_TYPE *);
+static void decode_internal (const struct real_format *,
+ REAL_VALUE_TYPE *, const long *);
static void
-encode_internal (fmt, buf, r)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- long *buf;
- const REAL_VALUE_TYPE *r;
+encode_internal (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
+ const REAL_VALUE_TYPE *r)
{
memcpy (buf, r, sizeof (*r));
}
static void
-decode_internal (fmt, r, buf)
- const struct real_format *fmt ATTRIBUTE_UNUSED;
- REAL_VALUE_TYPE *r;
- const long *buf;
+decode_internal (const struct real_format *fmt ATTRIBUTE_UNUSED,
+ REAL_VALUE_TYPE *r, const long *buf)
{
memcpy (r, buf, sizeof (*r));
}
-const struct real_format real_internal_format =
+const struct real_format real_internal_format =
{
encode_internal,
decode_internal,
2,
1,
SIGNIFICAND_BITS - 2,
+ SIGNIFICAND_BITS - 2,
-MAX_EXP,
MAX_EXP,
+ -1,
true,
true,
false,
true,
- true
+ true
};
-/* Set up default mode to format mapping for IEEE. Everyone else has
- to set these values in OVERRIDE_OPTIONS. */
+/* Calculate the square root of X in mode MODE, and store the result
+ in R. Return TRUE if the operation does not raise an exception.
+ For details see "High Precision Division and Square Root",
+ Alan H. Karp and Peter Markstein, HP Lab Report 93-93-42, June
+ 1993. http://www.hpl.hp.com/techreports/93/HPL-93-42.pdf. */
-const struct real_format *real_format_for_mode[TFmode - QFmode + 1] =
+bool
+real_sqrt (REAL_VALUE_TYPE *r, enum machine_mode mode,
+ const REAL_VALUE_TYPE *x)
{
- NULL, /* QFmode */
- NULL, /* HFmode */
- NULL, /* TQFmode */
- &ieee_single_format, /* SFmode */
- &ieee_double_format, /* DFmode */
-
- /* We explicitly don't handle XFmode. There are two formats,
- pretty much equally common. Choose one in OVERRIDE_OPTIONS. */
- NULL, /* XFmode */
- &ieee_quad_format /* TFmode */
-};
+ static REAL_VALUE_TYPE halfthree;
+ static bool init = false;
+ REAL_VALUE_TYPE h, t, i;
+ int iter, exp;
+
+ /* sqrt(-0.0) is -0.0. */
+ if (real_isnegzero (x))
+ {
+ *r = *x;
+ return false;
+ }
+
+ /* Negative arguments return NaN. */
+ if (real_isneg (x))
+ {
+ get_canonical_qnan (r, 0);
+ return false;
+ }
+
+ /* Infinity and NaN return themselves. */
+ if (real_isinf (x) || real_isnan (x))
+ {
+ *r = *x;
+ return false;
+ }
+
+ if (!init)
+ {
+ do_add (&halfthree, &dconst1, &dconsthalf, 0);
+ init = true;
+ }
+
+ /* Initial guess for reciprocal sqrt, i. */
+ exp = real_exponent (x);
+ real_ldexp (&i, &dconst1, -exp/2);
+
+ /* Newton's iteration for reciprocal sqrt, i. */
+ for (iter = 0; iter < 16; iter++)
+ {
+ /* i(n+1) = i(n) * (1.5 - 0.5*i(n)*i(n)*x). */
+ do_multiply (&t, x, &i);
+ do_multiply (&h, &t, &i);
+ do_multiply (&t, &h, &dconsthalf);
+ do_add (&h, &halfthree, &t, 1);
+ do_multiply (&t, &i, &h);
+
+ /* Check for early convergence. */
+ if (iter >= 6 && real_identical (&i, &t))
+ break;
+
+ /* ??? Unroll loop to avoid copying. */
+ i = t;
+ }
+
+ /* Final iteration: r = i*x + 0.5*i*x*(1.0 - i*(i*x)). */
+ do_multiply (&t, x, &i);
+ do_multiply (&h, &t, &i);
+ do_add (&i, &dconst1, &h, 1);
+ do_multiply (&h, &t, &i);
+ do_multiply (&i, &dconsthalf, &h);
+ do_add (&h, &t, &i, 0);
+
+ /* ??? We need a Tuckerman test to get the last bit. */
+
+ real_convert (r, mode, &h);
+ return true;
+}
+
+/* Calculate X raised to the integer exponent N in mode MODE and store
+ the result in R. Return true if the result may be inexact due to
+ loss of precision. The algorithm is the classic "left-to-right binary
+ method" described in section 4.6.3 of Donald Knuth's "Seminumerical
+ Algorithms", "The Art of Computer Programming", Volume 2. */
+
+bool
+real_powi (REAL_VALUE_TYPE *r, enum machine_mode mode,
+ const REAL_VALUE_TYPE *x, HOST_WIDE_INT n)
+{
+ unsigned HOST_WIDE_INT bit;
+ REAL_VALUE_TYPE t;
+ bool inexact = false;
+ bool init = false;
+ bool neg;
+ int i;
+
+ if (n == 0)
+ {
+ *r = dconst1;
+ return false;
+ }
+ else if (n < 0)
+ {
+ /* Don't worry about overflow, from now on n is unsigned. */
+ neg = true;
+ n = -n;
+ }
+ else
+ neg = false;
+
+ t = *x;
+ bit = (unsigned HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1);
+ for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
+ {
+ if (init)
+ {
+ inexact |= do_multiply (&t, &t, &t);
+ if (n & bit)
+ inexact |= do_multiply (&t, &t, x);
+ }
+ else if (n & bit)
+ init = true;
+ bit >>= 1;
+ }
+
+ if (neg)
+ inexact |= do_divide (&t, &dconst1, &t);
+
+ real_convert (r, mode, &t);
+ return inexact;
+}
+
+/* Round X to the nearest integer not larger in absolute value, i.e.
+ towards zero, placing the result in R in mode MODE. */
+
+void
+real_trunc (REAL_VALUE_TYPE *r, enum machine_mode mode,
+ const REAL_VALUE_TYPE *x)
+{
+ do_fix_trunc (r, x);
+ if (mode != VOIDmode)
+ real_convert (r, mode, r);
+}
+
+/* Round X to the largest integer not greater in value, i.e. round
+ down, placing the result in R in mode MODE. */
+
+void
+real_floor (REAL_VALUE_TYPE *r, enum machine_mode mode,
+ const REAL_VALUE_TYPE *x)
+{
+ do_fix_trunc (r, x);
+ if (! real_identical (r, x) && r->sign)
+ do_add (r, r, &dconstm1, 0);
+ if (mode != VOIDmode)
+ real_convert (r, mode, r);
+}
+
+/* Round X to the smallest integer not less then argument, i.e. round
+ up, placing the result in R in mode MODE. */
+
+void
+real_ceil (REAL_VALUE_TYPE *r, enum machine_mode mode,
+ const REAL_VALUE_TYPE *x)
+{
+ do_fix_trunc (r, x);
+ if (! real_identical (r, x) && ! r->sign)
+ do_add (r, r, &dconst1, 0);
+ if (mode != VOIDmode)
+ real_convert (r, mode, r);
+}
diff --git a/contrib/gcc/real.h b/contrib/gcc/real.h
index 7568a9e3279f..3620d50580a7 100644
--- a/contrib/gcc/real.h
+++ b/contrib/gcc/real.h
@@ -1,6 +1,6 @@
/* Definitions of floating-point access for GNU compiler.
- Copyright (C) 1989, 1991, 1994, 1996, 1997, 1998,
- 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1989, 1991, 1994, 1996, 1997, 1998, 1999,
+ 2000, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -35,7 +35,7 @@ enum real_value_class {
};
#define SIGNIFICAND_BITS (128 + HOST_BITS_PER_LONG)
-#define EXP_BITS (32 - 3)
+#define EXP_BITS (32 - 5)
#define MAX_EXP ((1 << (EXP_BITS - 1)) - 1)
#define SIGSZ (SIGNIFICAND_BITS / HOST_BITS_PER_LONG)
#define SIG_MSB ((unsigned long)1 << (HOST_BITS_PER_LONG - 1))
@@ -44,6 +44,8 @@ struct real_value GTY(())
{
ENUM_BITFIELD (real_value_class) class : 2;
unsigned int sign : 1;
+ unsigned int signalling : 1;
+ unsigned int canonical : 1;
signed int exp : EXP_BITS;
unsigned long sig[SIGSZ];
};
@@ -104,10 +106,10 @@ extern char test_real_width
struct real_format
{
/* Move to and from the target bytes. */
- void (*encode) PARAMS ((const struct real_format *, long *,
- const REAL_VALUE_TYPE *));
- void (*decode) PARAMS ((const struct real_format *, REAL_VALUE_TYPE *,
- const long *));
+ void (*encode) (const struct real_format *, long *,
+ const REAL_VALUE_TYPE *);
+ void (*decode) (const struct real_format *, REAL_VALUE_TYPE *,
+ const long *);
/* The radix of the exponent and digits of the significand. */
int b;
@@ -118,12 +120,18 @@ struct real_format
/* Size of the significand in digits of radix B. */
int p;
+ /* Size of the significant of a NaN, in digits of radix B. */
+ int pnan;
+
/* The minimum negative integer, x, such that b**(x-1) is normalized. */
int emin;
/* The maximum integer, x, such that b**(x-1) is representable. */
int emax;
+ /* The bit position of the sign bit, or -1 for a complex encoding. */
+ int signbit;
+
/* Properties of the format. */
bool has_nans;
bool has_inf;
@@ -135,96 +143,95 @@ struct real_format
/* The target format used for each floating floating point mode.
Indexed by MODE - QFmode. */
-extern const struct real_format *real_format_for_mode[TFmode - QFmode + 1];
+extern const struct real_format *
+ real_format_for_mode[MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1];
+#define REAL_MODE_FORMAT(MODE) (real_format_for_mode[(MODE) - MIN_MODE_FLOAT])
/* Declare functions in real.c. */
/* Binary or unary arithmetic on tree_code. */
-extern void real_arithmetic PARAMS ((REAL_VALUE_TYPE *, int,
- const REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *));
+extern void real_arithmetic (REAL_VALUE_TYPE *, int, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *);
/* Compare reals by tree_code. */
-extern bool real_compare PARAMS ((int, const REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *));
+extern bool real_compare (int, const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
/* Determine whether a floating-point value X is infinite. */
-extern bool real_isinf PARAMS ((const REAL_VALUE_TYPE *));
+extern bool real_isinf (const REAL_VALUE_TYPE *);
/* Determine whether a floating-point value X is a NaN. */
-extern bool real_isnan PARAMS ((const REAL_VALUE_TYPE *));
+extern bool real_isnan (const REAL_VALUE_TYPE *);
/* Determine whether a floating-point value X is negative. */
-extern bool real_isneg PARAMS ((const REAL_VALUE_TYPE *));
+extern bool real_isneg (const REAL_VALUE_TYPE *);
/* Determine whether a floating-point value X is minus zero. */
-extern bool real_isnegzero PARAMS ((const REAL_VALUE_TYPE *));
+extern bool real_isnegzero (const REAL_VALUE_TYPE *);
/* Compare two floating-point objects for bitwise identity. */
-extern bool real_identical PARAMS ((const REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *));
+extern bool real_identical (const REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *);
/* Extend or truncate to a new mode. */
-extern void real_convert PARAMS ((REAL_VALUE_TYPE *,
- enum machine_mode,
- const REAL_VALUE_TYPE *));
+extern void real_convert (REAL_VALUE_TYPE *, enum machine_mode,
+ const REAL_VALUE_TYPE *);
/* Return true if truncating to NEW is exact. */
-extern bool exact_real_truncate PARAMS ((enum machine_mode,
- const REAL_VALUE_TYPE *));
+extern bool exact_real_truncate (enum machine_mode, const REAL_VALUE_TYPE *);
/* Render R as a decimal floating point constant. */
-extern void real_to_decimal PARAMS ((char *, const REAL_VALUE_TYPE *,
- size_t, size_t, int));
+extern void real_to_decimal (char *, const REAL_VALUE_TYPE *, size_t,
+ size_t, int);
/* Render R as a hexadecimal floating point constant. */
-extern void real_to_hexadecimal PARAMS ((char *, const REAL_VALUE_TYPE *,
- size_t, size_t, int));
+extern void real_to_hexadecimal (char *, const REAL_VALUE_TYPE *,
+ size_t, size_t, int);
/* Render R as an integer. */
-extern HOST_WIDE_INT real_to_integer PARAMS ((const REAL_VALUE_TYPE *));
-extern void real_to_integer2 PARAMS ((HOST_WIDE_INT *, HOST_WIDE_INT *,
- const REAL_VALUE_TYPE *));
+extern HOST_WIDE_INT real_to_integer (const REAL_VALUE_TYPE *);
+extern void real_to_integer2 (HOST_WIDE_INT *, HOST_WIDE_INT *,
+ const REAL_VALUE_TYPE *);
/* Initialize R from a decimal or hexadecimal string. */
-extern void real_from_string PARAMS ((REAL_VALUE_TYPE *, const char *));
+extern void real_from_string (REAL_VALUE_TYPE *, const char *);
/* Initialize R from an integer pair HIGH/LOW. */
-extern void real_from_integer PARAMS ((REAL_VALUE_TYPE *,
- enum machine_mode,
- unsigned HOST_WIDE_INT,
- HOST_WIDE_INT, int));
+extern void real_from_integer (REAL_VALUE_TYPE *, enum machine_mode,
+ unsigned HOST_WIDE_INT, HOST_WIDE_INT, int);
-extern long real_to_target_fmt PARAMS ((long *, const REAL_VALUE_TYPE *,
- const struct real_format *));
-extern long real_to_target PARAMS ((long *, const REAL_VALUE_TYPE *,
- enum machine_mode));
+extern long real_to_target_fmt (long *, const REAL_VALUE_TYPE *,
+ const struct real_format *);
+extern long real_to_target (long *, const REAL_VALUE_TYPE *, enum machine_mode);
-extern void real_from_target_fmt PARAMS ((REAL_VALUE_TYPE *, const long *,
- const struct real_format *));
-extern void real_from_target PARAMS ((REAL_VALUE_TYPE *, const long *,
- enum machine_mode));
+extern void real_from_target_fmt (REAL_VALUE_TYPE *, const long *,
+ const struct real_format *);
+extern void real_from_target (REAL_VALUE_TYPE *, const long *,
+ enum machine_mode);
-extern void real_inf PARAMS ((REAL_VALUE_TYPE *));
+extern void real_inf (REAL_VALUE_TYPE *);
-extern bool real_nan PARAMS ((REAL_VALUE_TYPE *, const char *,
- int, enum machine_mode));
+extern bool real_nan (REAL_VALUE_TYPE *, const char *, int, enum machine_mode);
-extern void real_2expN PARAMS ((REAL_VALUE_TYPE *, int));
+extern void real_maxval (REAL_VALUE_TYPE *, int, enum machine_mode);
-extern unsigned int real_hash PARAMS ((const REAL_VALUE_TYPE *));
+extern void real_2expN (REAL_VALUE_TYPE *, int);
+
+extern unsigned int real_hash (const REAL_VALUE_TYPE *);
/* Target formats defined in real.c. */
extern const struct real_format ieee_single_format;
+extern const struct real_format mips_single_format;
extern const struct real_format ieee_double_format;
+extern const struct real_format mips_double_format;
extern const struct real_format ieee_extended_motorola_format;
extern const struct real_format ieee_extended_intel_96_format;
extern const struct real_format ieee_extended_intel_96_round_53_format;
extern const struct real_format ieee_extended_intel_128_format;
extern const struct real_format ibm_extended_format;
+extern const struct real_format mips_extended_format;
extern const struct real_format ieee_quad_format;
+extern const struct real_format mips_quad_format;
extern const struct real_format vax_f_format;
extern const struct real_format vax_d_format;
extern const struct real_format vax_g_format;
@@ -275,14 +282,14 @@ extern const struct real_format real_internal_format;
#define REAL_VALUE_FROM_UNSIGNED_INT(r, lo, hi, mode) \
real_from_integer (&(r), mode, lo, hi, 1)
-extern REAL_VALUE_TYPE real_value_truncate PARAMS ((enum machine_mode,
- REAL_VALUE_TYPE));
+extern REAL_VALUE_TYPE real_value_truncate (enum machine_mode,
+ REAL_VALUE_TYPE);
#define REAL_VALUE_TO_INT(plow, phigh, r) \
real_to_integer2 (plow, phigh, &(r))
-extern REAL_VALUE_TYPE real_arithmetic2 PARAMS ((int, const REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *));
+extern REAL_VALUE_TYPE real_arithmetic2 (int, const REAL_VALUE_TYPE *,
+ const REAL_VALUE_TYPE *);
#define REAL_VALUE_NEGATE(X) \
real_arithmetic2 (NEGATE_EXPR, &(X), NULL)
@@ -290,10 +297,9 @@ extern REAL_VALUE_TYPE real_arithmetic2 PARAMS ((int, const REAL_VALUE_TYPE *,
#define REAL_VALUE_ABS(X) \
real_arithmetic2 (ABS_EXPR, &(X), NULL)
-extern int significand_size PARAMS ((enum machine_mode));
+extern int significand_size (enum machine_mode);
-extern REAL_VALUE_TYPE real_from_string2 PARAMS ((const char *,
- enum machine_mode));
+extern REAL_VALUE_TYPE real_from_string2 (const char *, enum machine_mode);
#define REAL_VALUE_ATOF(s, m) \
real_from_string2 (s, m)
@@ -311,25 +317,30 @@ extern REAL_VALUE_TYPE real_from_string2 PARAMS ((const char *,
/* ??? These were added for Paranoia support. */
/* Return floor log2(R). */
-extern int real_exponent PARAMS ((const REAL_VALUE_TYPE *));
+extern int real_exponent (const REAL_VALUE_TYPE *);
/* R = A * 2**EXP. */
-extern void real_ldexp PARAMS ((REAL_VALUE_TYPE *,
- const REAL_VALUE_TYPE *, int));
+extern void real_ldexp (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int);
/* **** End of software floating point emulator interface macros **** */
-/* Constant real values 0, 1, 2, and -1. */
+/* Constant real values 0, 1, 2, 3, 10, -1, -2, 0.5 and 1/3. */
extern REAL_VALUE_TYPE dconst0;
extern REAL_VALUE_TYPE dconst1;
extern REAL_VALUE_TYPE dconst2;
+extern REAL_VALUE_TYPE dconst3;
+extern REAL_VALUE_TYPE dconst10;
extern REAL_VALUE_TYPE dconstm1;
+extern REAL_VALUE_TYPE dconstm2;
+extern REAL_VALUE_TYPE dconsthalf;
+extern REAL_VALUE_TYPE dconstthird;
+extern REAL_VALUE_TYPE dconstpi;
+extern REAL_VALUE_TYPE dconste;
/* Function to return a real value (not a tree node)
from a given integer constant. */
-REAL_VALUE_TYPE real_value_from_int_cst PARAMS ((union tree_node *,
- union tree_node *));
+REAL_VALUE_TYPE real_value_from_int_cst (tree, tree);
/* Given a CONST_DOUBLE in FROM, store into TO the value it represents. */
#define REAL_VALUE_FROM_CONST_DOUBLE(to, from) \
@@ -338,14 +349,28 @@ REAL_VALUE_TYPE real_value_from_int_cst PARAMS ((union tree_node *,
/* Return a CONST_DOUBLE with value R and mode M. */
#define CONST_DOUBLE_FROM_REAL_VALUE(r, m) \
const_double_from_real_value (r, m)
-extern rtx const_double_from_real_value PARAMS ((REAL_VALUE_TYPE,
- enum machine_mode));
+extern rtx const_double_from_real_value (REAL_VALUE_TYPE, enum machine_mode);
/* Replace R by 1/R in the given machine mode, if the result is exact. */
-extern bool exact_real_inverse PARAMS ((enum machine_mode, REAL_VALUE_TYPE *));
+extern bool exact_real_inverse (enum machine_mode, REAL_VALUE_TYPE *);
/* In tree.c: wrap up a REAL_VALUE_TYPE in a tree node. */
-extern tree build_real PARAMS ((tree, REAL_VALUE_TYPE));
-
+extern tree build_real (tree, REAL_VALUE_TYPE);
+
+/* Calculate R as the square root of X in the given machine mode. */
+extern bool real_sqrt (REAL_VALUE_TYPE *, enum machine_mode,
+ const REAL_VALUE_TYPE *);
+
+/* Calculate R as X raised to the integer exponent N in mode MODE. */
+extern bool real_powi (REAL_VALUE_TYPE *, enum machine_mode,
+ const REAL_VALUE_TYPE *, HOST_WIDE_INT);
+
+/* Standard round to integer value functions. */
+extern void real_trunc (REAL_VALUE_TYPE *, enum machine_mode,
+ const REAL_VALUE_TYPE *);
+extern void real_floor (REAL_VALUE_TYPE *, enum machine_mode,
+ const REAL_VALUE_TYPE *);
+extern void real_ceil (REAL_VALUE_TYPE *, enum machine_mode,
+ const REAL_VALUE_TYPE *);
#endif /* ! GCC_REAL_H */
diff --git a/contrib/gcc/recog.c b/contrib/gcc/recog.c
index bd42a5b5363a..2224c5ac8f43 100644
--- a/contrib/gcc/recog.c
+++ b/contrib/gcc/recog.c
@@ -1,6 +1,6 @@
/* Subroutines used by or related to instruction recognition.
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "insn-config.h"
@@ -54,10 +56,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#endif
#endif
-static void validate_replace_rtx_1 PARAMS ((rtx *, rtx, rtx, rtx));
-static rtx *find_single_use_1 PARAMS ((rtx, rtx *));
-static void validate_replace_src_1 PARAMS ((rtx *, void *));
-static rtx split_insn PARAMS ((rtx));
+static void validate_replace_rtx_1 (rtx *, rtx, rtx, rtx);
+static rtx *find_single_use_1 (rtx, rtx *);
+static void validate_replace_src_1 (rtx *, void *);
+static rtx split_insn (rtx);
/* Nonzero means allow operands to be volatile.
This should be 0 if you are generating rtl, such as if you are calling
@@ -86,18 +88,21 @@ int which_alternative;
int reload_completed;
+/* Nonzero after thread_prologue_and_epilogue_insns has run. */
+int epilogue_completed;
+
/* Initialize data used by the function `recog'.
This must be called once in the compilation of a function
before any insn recognition may be done in the function. */
void
-init_recog_no_volatile ()
+init_recog_no_volatile (void)
{
volatile_ok = 0;
}
void
-init_recog ()
+init_recog (void)
{
volatile_ok = 1;
}
@@ -112,8 +117,7 @@ init_recog ()
through this one. (The only exception is in combine.c.) */
int
-recog_memoized_1 (insn)
- rtx insn;
+recog_memoized_1 (rtx insn)
{
if (INSN_CODE (insn) < 0)
INSN_CODE (insn) = recog (PATTERN (insn), insn, 0);
@@ -124,8 +128,7 @@ recog_memoized_1 (insn)
and that the operands mentioned in it are legitimate. */
int
-check_asm_operands (x)
- rtx x;
+check_asm_operands (rtx x)
{
int noperands;
rtx *operands;
@@ -147,8 +150,8 @@ check_asm_operands (x)
if (noperands == 0)
return 1;
- operands = (rtx *) alloca (noperands * sizeof (rtx));
- constraints = (const char **) alloca (noperands * sizeof (char *));
+ operands = alloca (noperands * sizeof (rtx));
+ constraints = alloca (noperands * sizeof (char *));
decode_asm_operands (x, operands, NULL, constraints, NULL);
@@ -201,11 +204,7 @@ static int num_changes = 0;
Otherwise, perform the change and return 1. */
int
-validate_change (object, loc, new, in_group)
- rtx object;
- rtx *loc;
- rtx new;
- int in_group;
+validate_change (rtx object, rtx *loc, rtx new, int in_group)
{
rtx old = *loc;
@@ -227,9 +226,7 @@ validate_change (object, loc, new, in_group)
else
changes_allocated *= 2;
- changes =
- (change_t*) xrealloc (changes,
- sizeof (change_t) * changes_allocated);
+ changes = xrealloc (changes, sizeof (change_t) * changes_allocated);
}
changes[num_changes].object = object;
@@ -259,8 +256,7 @@ validate_change (object, loc, new, in_group)
were valid; i.e. whether INSN can still be recognized. */
int
-insn_invalid_p (insn)
- rtx insn;
+insn_invalid_p (rtx insn)
{
rtx pat = PATTERN (insn);
int num_clobbers = 0;
@@ -310,7 +306,7 @@ insn_invalid_p (insn)
/* Return number of changes made and not validated yet. */
int
-num_changes_pending ()
+num_changes_pending (void)
{
return num_changes;
}
@@ -319,7 +315,7 @@ num_changes_pending ()
Return 1 if all changes are valid, zero otherwise. */
int
-apply_change_group ()
+apply_change_group (void)
{
int i;
rtx last_validated = NULL_RTX;
@@ -337,7 +333,7 @@ apply_change_group ()
{
rtx object = changes[i].object;
- /* if there is no object to test or if it is the same as the one we
+ /* If there is no object to test or if it is the same as the one we
already tested, ignore it. */
if (object == 0 || object == last_validated)
continue;
@@ -420,7 +416,7 @@ apply_change_group ()
/* Return the number of changes so far in the current group. */
int
-num_validated_changes ()
+num_validated_changes (void)
{
return num_changes;
}
@@ -428,8 +424,7 @@ num_validated_changes ()
/* Retract the changes numbered NUM and up. */
void
-cancel_changes (num)
- int num;
+cancel_changes (int num)
{
int i;
@@ -448,9 +443,7 @@ cancel_changes (num)
validate_change passing OBJECT. */
static void
-validate_replace_rtx_1 (loc, from, to, object)
- rtx *loc;
- rtx from, to, object;
+validate_replace_rtx_1 (rtx *loc, rtx from, rtx to, rtx object)
{
int i, j;
const char *fmt;
@@ -483,16 +476,38 @@ validate_replace_rtx_1 (loc, from, to, object)
return;
}
- /* Call ourself recursively to perform the replacements. */
+ /* Call ourself recursively to perform the replacements.
+ We must not replace inside already replaced expression, otherwise we
+ get infinite recursion for replacements like (reg X)->(subreg (reg X))
+ done by regmove, so we must special case shared ASM_OPERANDS. */
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ if (GET_CODE (x) == PARALLEL)
{
- if (fmt[i] == 'e')
- validate_replace_rtx_1 (&XEXP (x, i), from, to, object);
- else if (fmt[i] == 'E')
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object);
+ for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
+ {
+ if (j && GET_CODE (XVECEXP (x, 0, j)) == SET
+ && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == ASM_OPERANDS)
+ {
+ /* Verify that operands are really shared. */
+ if (ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (x, 0, 0))) !=
+ ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (x, 0, j))))
+ abort ();
+ validate_replace_rtx_1 (&SET_DEST (XVECEXP (x, 0, j)),
+ from, to, object);
+ }
+ else
+ validate_replace_rtx_1 (&XVECEXP (x, 0, j), from, to, object);
+ }
}
+ else
+ for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ validate_replace_rtx_1 (&XEXP (x, i), from, to, object);
+ else if (fmt[i] == 'E')
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object);
+ }
/* If we didn't substitute, there is nothing more to do. */
if (num_changes == prev_changes)
@@ -631,8 +646,7 @@ validate_replace_rtx_1 (loc, from, to, object)
if INSN is still valid. */
int
-validate_replace_rtx_subexp (from, to, insn, loc)
- rtx from, to, insn, *loc;
+validate_replace_rtx_subexp (rtx from, rtx to, rtx insn, rtx *loc)
{
validate_replace_rtx_1 (loc, from, to, insn);
return apply_change_group ();
@@ -642,8 +656,7 @@ validate_replace_rtx_subexp (from, to, insn, loc)
changes have been made, validate by seeing if INSN is still valid. */
int
-validate_replace_rtx (from, to, insn)
- rtx from, to, insn;
+validate_replace_rtx (rtx from, rtx to, rtx insn)
{
validate_replace_rtx_1 (&PATTERN (insn), from, to, insn);
return apply_change_group ();
@@ -652,8 +665,7 @@ validate_replace_rtx (from, to, insn)
/* Try replacing every occurrence of FROM in INSN with TO. */
void
-validate_replace_rtx_group (from, to, insn)
- rtx from, to, insn;
+validate_replace_rtx_group (rtx from, rtx to, rtx insn)
{
validate_replace_rtx_1 (&PATTERN (insn), from, to, insn);
}
@@ -667,9 +679,7 @@ struct validate_replace_src_data
};
static void
-validate_replace_src_1 (x, data)
- rtx *x;
- void *data;
+validate_replace_src_1 (rtx *x, void *data)
{
struct validate_replace_src_data *d
= (struct validate_replace_src_data *) data;
@@ -681,8 +691,7 @@ validate_replace_src_1 (x, data)
SET_DESTs. */
void
-validate_replace_src_group (from, to, insn)
- rtx from, to, insn;
+validate_replace_src_group (rtx from, rtx to, rtx insn)
{
struct validate_replace_src_data d;
@@ -692,11 +701,10 @@ validate_replace_src_group (from, to, insn)
note_uses (&PATTERN (insn), validate_replace_src_1, &d);
}
-/* Same as validate_repalace_src_group, but validate by seeing if
+/* Same as validate_replace_src_group, but validate by seeing if
INSN is still valid. */
int
-validate_replace_src (from, to, insn)
- rtx from, to, insn;
+validate_replace_src (rtx from, rtx to, rtx insn)
{
validate_replace_src_group (from, to, insn);
return apply_change_group ();
@@ -708,8 +716,7 @@ validate_replace_src (from, to, insn)
EQ and NE tests do not count. */
int
-next_insn_tests_no_inequality (insn)
- rtx insn;
+next_insn_tests_no_inequality (rtx insn)
{
rtx next = next_cc0_user (insn);
@@ -722,34 +729,6 @@ next_insn_tests_no_inequality (insn)
|| GET_CODE (next) == CALL_INSN)
&& ! inequality_comparisons_p (PATTERN (next)));
}
-
-#if 0 /* This is useless since the insn that sets the cc's
- must be followed immediately by the use of them. */
-/* Return 1 if the CC value set up by INSN is not used. */
-
-int
-next_insns_test_no_inequality (insn)
- rtx insn;
-{
- rtx next = NEXT_INSN (insn);
-
- for (; next != 0; next = NEXT_INSN (next))
- {
- if (GET_CODE (next) == CODE_LABEL
- || GET_CODE (next) == BARRIER)
- return 1;
- if (GET_CODE (next) == NOTE)
- continue;
- if (inequality_comparisons_p (PATTERN (next)))
- return 0;
- if (sets_cc0_p (PATTERN (next)) == 1)
- return 1;
- if (! reg_mentioned_p (cc0_rtx, PATTERN (next)))
- return 1;
- }
- return 1;
-}
-#endif
#endif
/* This is used by find_single_use to locate an rtx that contains exactly one
@@ -758,9 +737,7 @@ next_insns_test_no_inequality (insn)
DEST that are being used to totally replace it are not counted. */
static rtx *
-find_single_use_1 (dest, loc)
- rtx dest;
- rtx *loc;
+find_single_use_1 (rtx dest, rtx *loc)
{
rtx x = *loc;
enum rtx_code code = GET_CODE (x);
@@ -871,10 +848,7 @@ find_single_use_1 (dest, loc)
and last insn referencing DEST. */
rtx *
-find_single_use (dest, insn, ploc)
- rtx dest;
- rtx insn;
- rtx *ploc;
+find_single_use (rtx dest, rtx insn, rtx *ploc)
{
rtx next;
rtx *result;
@@ -937,9 +911,7 @@ find_single_use (dest, insn, ploc)
class NO_REGS, see the comment for `register_operand'. */
int
-general_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+general_operand (rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
@@ -994,7 +966,7 @@ general_operand (op, mode)
return 0;
/* FLOAT_MODE subregs can't be paradoxical. Combine will occasionally
- create such rtl, and we must reject it. */
+ create such rtl, and we must reject it. */
if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT
&& GET_MODE_SIZE (GET_MODE (op)) > GET_MODE_SIZE (GET_MODE (sub)))
return 0;
@@ -1041,9 +1013,7 @@ general_operand (op, mode)
expressions in the machine description. */
int
-address_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+address_operand (rtx op, enum machine_mode mode)
{
return memory_address_p (mode, op);
}
@@ -1063,9 +1033,7 @@ address_operand (op, mode)
it is most consistent to keep this function from accepting them. */
int
-register_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+register_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return 0;
@@ -1116,9 +1084,7 @@ register_operand (op, mode)
/* Return 1 for a register in Pmode; ignore the tested mode. */
int
-pmode_register_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
+pmode_register_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return register_operand (op, Pmode);
}
@@ -1127,9 +1093,7 @@ pmode_register_operand (op, mode)
or a hard register. */
int
-scratch_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+scratch_operand (rtx op, enum machine_mode mode)
{
if (GET_MODE (op) != mode && mode != VOIDmode)
return 0;
@@ -1145,9 +1109,7 @@ scratch_operand (op, mode)
expressions in the machine description. */
int
-immediate_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+immediate_operand (rtx op, enum machine_mode mode)
{
/* Don't accept CONST_INT or anything similar
if the caller wants something floating. */
@@ -1179,9 +1141,7 @@ immediate_operand (op, mode)
/* Returns 1 if OP is an operand that is a CONST_INT. */
int
-const_int_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+const_int_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != CONST_INT)
return 0;
@@ -1197,9 +1157,7 @@ const_int_operand (op, mode)
floating-point number. */
int
-const_double_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+const_double_operand (rtx op, enum machine_mode mode)
{
/* Don't accept CONST_INT or anything similar
if the caller wants something floating. */
@@ -1216,9 +1174,7 @@ const_double_operand (op, mode)
/* Return 1 if OP is a general operand that is not an immediate operand. */
int
-nonimmediate_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+nonimmediate_operand (rtx op, enum machine_mode mode)
{
return (general_operand (op, mode) && ! CONSTANT_P (op));
}
@@ -1226,9 +1182,7 @@ nonimmediate_operand (op, mode)
/* Return 1 if OP is a register reference or immediate value of mode MODE. */
int
-nonmemory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+nonmemory_operand (rtx op, enum machine_mode mode)
{
if (CONSTANT_P (op))
{
@@ -1282,9 +1236,7 @@ nonmemory_operand (op, mode)
expressions in the machine description. */
int
-push_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+push_operand (rtx op, enum machine_mode mode)
{
unsigned int rounded_size = GET_MODE_SIZE (mode);
@@ -1314,7 +1266,7 @@ push_operand (op, mode)
#ifdef STACK_GROWS_DOWNWARD
|| INTVAL (XEXP (XEXP (op, 1), 1)) != - (int) rounded_size
#else
- || INTVAL (XEXP (XEXP (op, 1), 1)) != rounded_size
+ || INTVAL (XEXP (XEXP (op, 1), 1)) != (int) rounded_size
#endif
)
return 0;
@@ -1330,9 +1282,7 @@ push_operand (op, mode)
expressions in the machine description. */
int
-pop_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+pop_operand (rtx op, enum machine_mode mode)
{
if (GET_CODE (op) != MEM)
return 0;
@@ -1351,9 +1301,7 @@ pop_operand (op, mode)
/* Return 1 if ADDR is a valid memory address for mode MODE. */
int
-memory_address_p (mode, addr)
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx addr;
+memory_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx addr)
{
if (GET_CODE (addr) == ADDRESSOF)
return 1;
@@ -1372,9 +1320,7 @@ memory_address_p (mode, addr)
expressions in the machine description. */
int
-memory_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+memory_operand (rtx op, enum machine_mode mode)
{
rtx inner;
@@ -1397,9 +1343,7 @@ memory_operand (op, mode)
that is, a memory reference whose address is a general_operand. */
int
-indirect_operand (op, mode)
- rtx op;
- enum machine_mode mode;
+indirect_operand (rtx op, enum machine_mode mode)
{
/* Before reload, a SUBREG isn't in memory (see memory_operand, above). */
if (! reload_completed
@@ -1432,9 +1376,7 @@ indirect_operand (op, mode)
MATCH_OPERATOR to recognize all the branch insns. */
int
-comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode;
+comparison_operator (rtx op, enum machine_mode mode)
{
return ((mode == VOIDmode || GET_MODE (op) == mode)
&& GET_RTX_CLASS (GET_CODE (op)) == '<');
@@ -1445,8 +1387,7 @@ comparison_operator (op, mode)
Otherwise return -1. */
int
-asm_noperands (body)
- rtx body;
+asm_noperands (rtx body)
{
switch (GET_CODE (body))
{
@@ -1530,12 +1471,8 @@ asm_noperands (body)
we don't store that info. */
const char *
-decode_asm_operands (body, operands, operand_locs, constraints, modes)
- rtx body;
- rtx *operands;
- rtx **operand_locs;
- const char **constraints;
- enum machine_mode *modes;
+decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
+ const char **constraints, enum machine_mode *modes)
{
int i;
int noperands;
@@ -1667,9 +1604,7 @@ decode_asm_operands (body, operands, operand_locs, constraints, modes)
Return > 0 if ok, = 0 if bad, < 0 if inconclusive. */
int
-asm_operand_ok (op, constraint)
- rtx op;
- const char *constraint;
+asm_operand_ok (rtx op, const char *constraint)
{
int result = 0;
@@ -1679,18 +1614,21 @@ asm_operand_ok (op, constraint)
while (*constraint)
{
- char c = *constraint++;
+ char c = *constraint;
+ int len;
switch (c)
{
+ case ',':
+ constraint++;
+ continue;
case '=':
case '+':
case '*':
case '%':
- case '?':
case '!':
case '#':
case '&':
- case ',':
+ case '?':
break;
case '0': case '1': case '2': case '3': case '4':
@@ -1699,25 +1637,27 @@ asm_operand_ok (op, constraint)
proper matching constraint, but we can't actually fail
the check if they didn't. Indicate that results are
inconclusive. */
- while (ISDIGIT (*constraint))
+ do
constraint++;
- result = -1;
- break;
+ while (ISDIGIT (*constraint));
+ if (! result)
+ result = -1;
+ continue;
case 'p':
if (address_operand (op, VOIDmode))
- return 1;
+ result = 1;
break;
case 'm':
case 'V': /* non-offsettable */
if (memory_operand (op, VOIDmode))
- return 1;
+ result = 1;
break;
case 'o': /* offsettable */
if (offsettable_nonstrict_memref_p (op))
- return 1;
+ result = 1;
break;
case '<':
@@ -1732,7 +1672,7 @@ asm_operand_ok (op, constraint)
&& (1
|| GET_CODE (XEXP (op, 0)) == PRE_DEC
|| GET_CODE (XEXP (op, 0)) == POST_DEC))
- return 1;
+ result = 1;
break;
case '>':
@@ -1740,7 +1680,7 @@ asm_operand_ok (op, constraint)
&& (1
|| GET_CODE (XEXP (op, 0)) == PRE_INC
|| GET_CODE (XEXP (op, 0)) == POST_INC))
- return 1;
+ result = 1;
break;
case 'E':
@@ -1748,18 +1688,18 @@ asm_operand_ok (op, constraint)
if (GET_CODE (op) == CONST_DOUBLE
|| (GET_CODE (op) == CONST_VECTOR
&& GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT))
- return 1;
+ result = 1;
break;
case 'G':
if (GET_CODE (op) == CONST_DOUBLE
- && CONST_DOUBLE_OK_FOR_LETTER_P (op, 'G'))
- return 1;
+ && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, 'G', constraint))
+ result = 1;
break;
case 'H':
if (GET_CODE (op) == CONST_DOUBLE
- && CONST_DOUBLE_OK_FOR_LETTER_P (op, 'H'))
- return 1;
+ && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, 'H', constraint))
+ result = 1;
break;
case 's':
@@ -1767,7 +1707,7 @@ asm_operand_ok (op, constraint)
|| (GET_CODE (op) == CONST_DOUBLE
&& GET_MODE (op) == VOIDmode))
break;
- /* FALLTHRU */
+ /* Fall through. */
case 'i':
if (CONSTANT_P (op)
@@ -1775,94 +1715,97 @@ asm_operand_ok (op, constraint)
&& (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
#endif
)
- return 1;
+ result = 1;
break;
case 'n':
if (GET_CODE (op) == CONST_INT
|| (GET_CODE (op) == CONST_DOUBLE
&& GET_MODE (op) == VOIDmode))
- return 1;
+ result = 1;
break;
case 'I':
if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'))
- return 1;
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'I', constraint))
+ result = 1;
break;
case 'J':
if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), 'J'))
- return 1;
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'J', constraint))
+ result = 1;
break;
case 'K':
if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), 'K'))
- return 1;
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'K', constraint))
+ result = 1;
break;
case 'L':
if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'))
- return 1;
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'L', constraint))
+ result = 1;
break;
case 'M':
if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), 'M'))
- return 1;
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'M', constraint))
+ result = 1;
break;
case 'N':
if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), 'N'))
- return 1;
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'N', constraint))
+ result = 1;
break;
case 'O':
if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), 'O'))
- return 1;
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'O', constraint))
+ result = 1;
break;
case 'P':
if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), 'P'))
- return 1;
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), 'P', constraint))
+ result = 1;
break;
case 'X':
- return 1;
+ result = 1;
+ break;
case 'g':
if (general_operand (op, VOIDmode))
- return 1;
+ result = 1;
break;
default:
/* For all other letters, we first check for a register class,
otherwise it is an EXTRA_CONSTRAINT. */
- if (REG_CLASS_FROM_LETTER (c) != NO_REGS)
+ if (REG_CLASS_FROM_CONSTRAINT (c, constraint) != NO_REGS)
{
case 'r':
if (GET_MODE (op) == BLKmode)
break;
if (register_operand (op, VOIDmode))
- return 1;
- }
-#ifdef EXTRA_CONSTRAINT
- if (EXTRA_CONSTRAINT (op, c))
- return 1;
- if (EXTRA_MEMORY_CONSTRAINT (c))
- {
- /* Every memory operand can be reloaded to fit. */
- if (memory_operand (op, VOIDmode))
- return 1;
- }
- if (EXTRA_ADDRESS_CONSTRAINT (c))
- {
- /* Every address operand can be reloaded to fit. */
- if (address_operand (op, VOIDmode))
- return 1;
+ result = 1;
}
+#ifdef EXTRA_CONSTRAINT_STR
+ else if (EXTRA_CONSTRAINT_STR (op, c, constraint))
+ result = 1;
+ else if (EXTRA_MEMORY_CONSTRAINT (c, constraint)
+ /* Every memory operand can be reloaded to fit. */
+ && memory_operand (op, VOIDmode))
+ result = 1;
+ else if (EXTRA_ADDRESS_CONSTRAINT (c, constraint)
+ /* Every address operand can be reloaded to fit. */
+ && address_operand (op, VOIDmode))
+ result = 1;
#endif
break;
}
+ len = CONSTRAINT_LEN (c, constraint);
+ do
+ constraint++;
+ while (--len && *constraint);
+ if (len)
+ return 0;
}
return result;
@@ -1873,8 +1816,7 @@ asm_operand_ok (op, constraint)
Otherwise, return a null pointer. */
rtx *
-find_constant_term_loc (p)
- rtx *p;
+find_constant_term_loc (rtx *p)
{
rtx *tem;
enum rtx_code code = GET_CODE (*p);
@@ -1927,8 +1869,7 @@ find_constant_term_loc (p)
don't use it before reload. */
int
-offsettable_memref_p (op)
- rtx op;
+offsettable_memref_p (rtx op)
{
return ((GET_CODE (op) == MEM)
&& offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)));
@@ -1938,8 +1879,7 @@ offsettable_memref_p (op)
consider pseudo-regs valid as index or base regs. */
int
-offsettable_nonstrict_memref_p (op)
- rtx op;
+offsettable_nonstrict_memref_p (rtx op)
{
return ((GET_CODE (op) == MEM)
&& offsettable_address_p (0, GET_MODE (op), XEXP (op, 0)));
@@ -1956,16 +1896,13 @@ offsettable_nonstrict_memref_p (op)
for the sake of use in reload.c. */
int
-offsettable_address_p (strictp, mode, y)
- int strictp;
- enum machine_mode mode;
- rtx y;
+offsettable_address_p (int strictp, enum machine_mode mode, rtx y)
{
enum rtx_code ycode = GET_CODE (y);
rtx z;
rtx y1 = y;
rtx *y2;
- int (*addressp) PARAMS ((enum machine_mode, rtx)) =
+ int (*addressp) (enum machine_mode, rtx) =
(strictp ? strict_memory_address_p : memory_address_p);
unsigned int mode_sz = GET_MODE_SIZE (mode);
@@ -2031,8 +1968,7 @@ offsettable_address_p (strictp, mode, y)
because the amount of the increment depends on the mode. */
int
-mode_dependent_address_p (addr)
- rtx addr ATTRIBUTE_UNUSED; /* Maybe used in GO_IF_MODE_DEPENDENT_ADDRESS. */
+mode_dependent_address_p (rtx addr ATTRIBUTE_UNUSED /* Maybe used in GO_IF_MODE_DEPENDENT_ADDRESS. */)
{
GO_IF_MODE_DEPENDENT_ADDRESS (addr, win);
return 0;
@@ -2040,59 +1976,32 @@ mode_dependent_address_p (addr)
win: ATTRIBUTE_UNUSED_LABEL
return 1;
}
-
-/* Return 1 if OP is a general operand
- other than a memory ref with a mode dependent address. */
-
-int
-mode_independent_operand (op, mode)
- enum machine_mode mode;
- rtx op;
-{
- rtx addr;
-
- if (! general_operand (op, mode))
- return 0;
-
- if (GET_CODE (op) != MEM)
- return 1;
-
- addr = XEXP (op, 0);
- GO_IF_MODE_DEPENDENT_ADDRESS (addr, lose);
- return 1;
- /* Label `lose' might (not) be used via GO_IF_MODE_DEPENDENT_ADDRESS. */
- lose: ATTRIBUTE_UNUSED_LABEL
- return 0;
-}
/* Like extract_insn, but save insn extracted and don't extract again, when
called again for the same insn expecting that recog_data still contain the
valid information. This is used primary by gen_attr infrastructure that
often does extract insn again and again. */
void
-extract_insn_cached (insn)
- rtx insn;
+extract_insn_cached (rtx insn)
{
if (recog_data.insn == insn && INSN_CODE (insn) >= 0)
return;
extract_insn (insn);
recog_data.insn = insn;
}
-/* Do cached extract_insn, constrain_operand and complain about failures.
+/* Do cached extract_insn, constrain_operands and complain about failures.
Used by insn_attrtab. */
void
-extract_constrain_insn_cached (insn)
- rtx insn;
+extract_constrain_insn_cached (rtx insn)
{
extract_insn_cached (insn);
if (which_alternative == -1
&& !constrain_operands (reload_completed))
fatal_insn_not_found (insn);
}
-/* Do cached constrain_operand and complain about failures. */
+/* Do cached constrain_operands and complain about failures. */
int
-constrain_operands_cached (strict)
- int strict;
+constrain_operands_cached (int strict)
{
if (which_alternative == -1)
return constrain_operands (strict);
@@ -2103,8 +2012,7 @@ constrain_operands_cached (strict)
/* Analyze INSN and fill in recog_data. */
void
-extract_insn (insn)
- rtx insn;
+extract_insn (rtx insn)
{
int i;
int icode;
@@ -2203,11 +2111,14 @@ extract_insn (insn)
information from the constraint strings into a more usable form.
The collected data is stored in recog_op_alt. */
void
-preprocess_constraints ()
+preprocess_constraints (void)
{
int i;
- memset (recog_op_alt, 0, sizeof recog_op_alt);
+ for (i = 0; i < recog_data.n_operands; i++)
+ memset (recog_op_alt[i], 0, (recog_data.n_alternatives
+ * sizeof (struct operand_alternative)));
+
for (i = 0; i < recog_data.n_operands; i++)
{
int j;
@@ -2231,13 +2142,16 @@ preprocess_constraints ()
for (;;)
{
- char c = *p++;
+ char c = *p;
if (c == '#')
do
- c = *p++;
+ c = *++p;
while (c != ',' && c != '\0');
if (c == ',' || c == '\0')
- break;
+ {
+ p++;
+ break;
+ }
switch (c)
{
@@ -2263,11 +2177,11 @@ preprocess_constraints ()
case '5': case '6': case '7': case '8': case '9':
{
char *end;
- op_alt[j].matches = strtoul (p - 1, &end, 10);
+ op_alt[j].matches = strtoul (p, &end, 10);
recog_op_alt[op_alt[j].matches][j].matched = i;
p = end;
}
- break;
+ continue;
case 'm':
op_alt[j].memory_ok = 1;
@@ -2299,22 +2213,28 @@ preprocess_constraints ()
break;
default:
- if (EXTRA_MEMORY_CONSTRAINT (c))
+ if (EXTRA_MEMORY_CONSTRAINT (c, p))
{
op_alt[j].memory_ok = 1;
break;
}
- if (EXTRA_ADDRESS_CONSTRAINT (c))
+ if (EXTRA_ADDRESS_CONSTRAINT (c, p))
{
op_alt[j].is_address = 1;
- op_alt[j].class = reg_class_subunion[(int) op_alt[j].class]
- [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+ op_alt[j].class
+ = (reg_class_subunion
+ [(int) op_alt[j].class]
+ [(int) MODE_BASE_REG_CLASS (VOIDmode)]);
break;
}
- op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) REG_CLASS_FROM_LETTER ((unsigned char) c)];
+ op_alt[j].class
+ = (reg_class_subunion
+ [(int) op_alt[j].class]
+ [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]);
break;
}
+ p += CONSTRAINT_LEN (c, p);
}
}
}
@@ -2329,7 +2249,7 @@ preprocess_constraints ()
alternative of constraints was matched: 0 for the first alternative,
1 for the next, etc.
- In addition, when two operands are match
+ In addition, when two operands are required to match
and it happens that the output operand is (reg) while the
input operand is --(reg) or ++(reg) (a pre-inc or pre-dec),
make the output operand look like the input.
@@ -2353,8 +2273,7 @@ struct funny_match
};
int
-constrain_operands (strict)
- int strict;
+constrain_operands (int strict)
{
const char *constraints[MAX_RECOG_OPERANDS];
int matching_operands[MAX_RECOG_OPERANDS];
@@ -2388,6 +2307,7 @@ constrain_operands (strict)
int offset = 0;
int win = 0;
int val;
+ int len;
earlyclobber[opno] = 0;
@@ -2412,9 +2332,16 @@ constrain_operands (strict)
if (*p == 0 || *p == ',')
win = 1;
- while (*p && (c = *p++) != ',')
- switch (c)
+ do
+ switch (c = *p, len = CONSTRAINT_LEN (c, p), c)
{
+ case '\0':
+ len = 0;
+ break;
+ case ',':
+ c = '\0';
+ break;
+
case '?': case '!': case '*': case '%':
case '=': case '+':
break;
@@ -2422,8 +2349,10 @@ constrain_operands (strict)
case '#':
/* Ignore rest of this alternative as far as
constraint checking is concerned. */
- while (*p && *p != ',')
+ do
p++;
+ while (*p && *p != ',');
+ len = 0;
break;
case '&':
@@ -2445,7 +2374,7 @@ constrain_operands (strict)
char *end;
int match;
- match = strtoul (p - 1, &end, 10);
+ match = strtoul (p, &end, 10);
p = end;
if (strict < 0)
@@ -2480,6 +2409,7 @@ constrain_operands (strict)
funny_match[funny_match_index++].other = match;
}
}
+ len = 0;
break;
case 'p':
@@ -2515,12 +2445,25 @@ constrain_operands (strict)
break;
case 'm':
- if (GET_CODE (op) == MEM
- /* Before reload, accept what reload can turn into mem. */
- || (strict < 0 && CONSTANT_P (op))
- /* During reload, accept a pseudo */
- || (reload_in_progress && GET_CODE (op) == REG
- && REGNO (op) >= FIRST_PSEUDO_REGISTER))
+ /* Memory operands must be valid, to the extent
+ required by STRICT. */
+ if (GET_CODE (op) == MEM)
+ {
+ if (strict > 0
+ && !strict_memory_address_p (GET_MODE (op),
+ XEXP (op, 0)))
+ break;
+ if (strict == 0
+ && !memory_address_p (GET_MODE (op), XEXP (op, 0)))
+ break;
+ win = 1;
+ }
+ /* Before reload, accept what reload can turn into mem. */
+ else if (strict < 0 && CONSTANT_P (op))
+ win = 1;
+ /* During reload, accept a pseudo */
+ else if (reload_in_progress && GET_CODE (op) == REG
+ && REGNO (op) >= FIRST_PSEUDO_REGISTER)
win = 1;
break;
@@ -2549,7 +2492,7 @@ constrain_operands (strict)
case 'G':
case 'H':
if (GET_CODE (op) == CONST_DOUBLE
- && CONST_DOUBLE_OK_FOR_LETTER_P (op, c))
+ && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p))
win = 1;
break;
@@ -2579,7 +2522,7 @@ constrain_operands (strict)
case 'O':
case 'P':
if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), c))
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p))
win = 1;
break;
@@ -2610,7 +2553,8 @@ constrain_operands (strict)
{
enum reg_class class;
- class = (c == 'r' ? GENERAL_REGS : REG_CLASS_FROM_LETTER (c));
+ class = (c == 'r'
+ ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, p));
if (class != NO_REGS)
{
if (strict < 0
@@ -2622,35 +2566,29 @@ constrain_operands (strict)
&& reg_fits_class_p (op, class, offset, mode)))
win = 1;
}
-#ifdef EXTRA_CONSTRAINT
- else if (EXTRA_CONSTRAINT (op, c))
+#ifdef EXTRA_CONSTRAINT_STR
+ else if (EXTRA_CONSTRAINT_STR (op, c, p))
win = 1;
- if (EXTRA_MEMORY_CONSTRAINT (c))
- {
- /* Every memory operand can be reloaded to fit. */
- if (strict < 0 && GET_CODE (op) == MEM)
- win = 1;
-
- /* Before reload, accept what reload can turn into mem. */
- if (strict < 0 && CONSTANT_P (op))
- win = 1;
-
- /* During reload, accept a pseudo */
- if (reload_in_progress && GET_CODE (op) == REG
- && REGNO (op) >= FIRST_PSEUDO_REGISTER)
- win = 1;
- }
- if (EXTRA_ADDRESS_CONSTRAINT (c))
- {
- /* Every address operand can be reloaded to fit. */
- if (strict < 0)
- win = 1;
- }
+ else if (EXTRA_MEMORY_CONSTRAINT (c, p)
+ /* Every memory operand can be reloaded to fit. */
+ && ((strict < 0 && GET_CODE (op) == MEM)
+ /* Before reload, accept what reload can turn
+ into mem. */
+ || (strict < 0 && CONSTANT_P (op))
+ /* During reload, accept a pseudo */
+ || (reload_in_progress && GET_CODE (op) == REG
+ && REGNO (op) >= FIRST_PSEUDO_REGISTER)))
+ win = 1;
+ else if (EXTRA_ADDRESS_CONSTRAINT (c, p)
+ /* Every address operand can be reloaded to fit. */
+ && strict < 0)
+ win = 1;
#endif
break;
}
}
+ while (p += len, c);
constraints[opno] = p;
/* If this operand did not win somehow,
@@ -2718,11 +2656,8 @@ constrain_operands (strict)
If REG occupies multiple hard regs, all of them must be in CLASS. */
int
-reg_fits_class_p (operand, class, offset, mode)
- rtx operand;
- enum reg_class class;
- int offset;
- enum machine_mode mode;
+reg_fits_class_p (rtx operand, enum reg_class class, int offset,
+ enum machine_mode mode)
{
int regno = REGNO (operand);
if (regno < FIRST_PSEUDO_REGISTER
@@ -2742,67 +2677,46 @@ reg_fits_class_p (operand, class, offset, mode)
return 0;
}
-/* Split single instruction. Helper function for split_all_insns.
- Return last insn in the sequence if successful, or NULL if unsuccessful. */
+/* Split single instruction. Helper function for split_all_insns and
+ split_all_insns_noflow. Return last insn in the sequence if successful,
+ or NULL if unsuccessful. */
+
static rtx
-split_insn (insn)
- rtx insn;
+split_insn (rtx insn)
{
- rtx set;
- if (!INSN_P (insn))
- ;
- /* Don't split no-op move insns. These should silently
- disappear later in final. Splitting such insns would
- break the code that handles REG_NO_CONFLICT blocks. */
+ /* Split insns here to get max fine-grain parallelism. */
+ rtx first = PREV_INSN (insn);
+ rtx last = try_split (PATTERN (insn), insn, 1);
- else if ((set = single_set (insn)) != NULL && set_noop_p (set))
- {
- /* Nops get in the way while scheduling, so delete them
- now if register allocation has already been done. It
- is too risky to try to do this before register
- allocation, and there are unlikely to be very many
- nops then anyways. */
- if (reload_completed)
- delete_insn_and_edges (insn);
- }
- else
- {
- /* Split insns here to get max fine-grain parallelism. */
- rtx first = PREV_INSN (insn);
- rtx last = try_split (PATTERN (insn), insn, 1);
+ if (last == insn)
+ return NULL_RTX;
+
+ /* try_split returns the NOTE that INSN became. */
+ PUT_CODE (insn, NOTE);
+ NOTE_SOURCE_FILE (insn) = 0;
+ NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- if (last != insn)
+ /* ??? Coddle to md files that generate subregs in post-reload
+ splitters instead of computing the proper hard register. */
+ if (reload_completed && first != last)
+ {
+ first = NEXT_INSN (first);
+ for (;;)
{
- /* try_split returns the NOTE that INSN became. */
- PUT_CODE (insn, NOTE);
- NOTE_SOURCE_FILE (insn) = 0;
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
-
- /* ??? Coddle to md files that generate subregs in post-
- reload splitters instead of computing the proper
- hard register. */
- if (reload_completed && first != last)
- {
- first = NEXT_INSN (first);
- while (1)
- {
- if (INSN_P (first))
- cleanup_subreg_operands (first);
- if (first == last)
- break;
- first = NEXT_INSN (first);
- }
- }
- return last;
+ if (INSN_P (first))
+ cleanup_subreg_operands (first);
+ if (first == last)
+ break;
+ first = NEXT_INSN (first);
}
}
- return NULL_RTX;
+ return last;
}
+
/* Split all insns in the function. If UPD_LIFE, update life info after. */
void
-split_all_insns (upd_life)
- int upd_life;
+split_all_insns (int upd_life)
{
sbitmap blocks;
bool changed;
@@ -2817,26 +2731,54 @@ split_all_insns (upd_life)
rtx insn, next;
bool finish = false;
- for (insn = bb->head; !finish ; insn = next)
+ for (insn = BB_HEAD (bb); !finish ; insn = next)
{
- rtx last;
-
/* Can't use `next_real_insn' because that might go across
CODE_LABELS and short-out basic blocks. */
next = NEXT_INSN (insn);
- finish = (insn == bb->end);
- last = split_insn (insn);
- if (last)
+ finish = (insn == BB_END (bb));
+ if (INSN_P (insn))
{
- /* The split sequence may include barrier, but the
- BB boundary we are interested in will be set to previous
- one. */
-
- while (GET_CODE (last) == BARRIER)
- last = PREV_INSN (last);
- SET_BIT (blocks, bb->index);
- changed = true;
- insn = last;
+ rtx set = single_set (insn);
+
+ /* Don't split no-op move insns. These should silently
+ disappear later in final. Splitting such insns would
+ break the code that handles REG_NO_CONFLICT blocks. */
+ if (set && set_noop_p (set))
+ {
+ /* Nops get in the way while scheduling, so delete them
+ now if register allocation has already been done. It
+ is too risky to try to do this before register
+ allocation, and there are unlikely to be very many
+ nops then anyways. */
+ if (reload_completed)
+ {
+ /* If the no-op set has a REG_UNUSED note, we need
+ to update liveness information. */
+ if (find_reg_note (insn, REG_UNUSED, NULL_RTX))
+ {
+ SET_BIT (blocks, bb->index);
+ changed = true;
+ }
+ /* ??? Is life info affected by deleting edges? */
+ delete_insn_and_edges (insn);
+ }
+ }
+ else
+ {
+ rtx last = split_insn (insn);
+ if (last)
+ {
+ /* The split sequence may include barrier, but the
+ BB boundary we are interested in will be set to
+ previous one. */
+
+ while (GET_CODE (last) == BARRIER)
+ last = PREV_INSN (last);
+ SET_BIT (blocks, bb->index);
+ changed = true;
+ }
+ }
}
}
}
@@ -2863,19 +2805,38 @@ split_all_insns (upd_life)
}
/* Same as split_all_insns, but do not expect CFG to be available.
- Used by machine depedent reorg passes. */
+ Used by machine dependent reorg passes. */
void
-split_all_insns_noflow ()
+split_all_insns_noflow (void)
{
rtx next, insn;
for (insn = get_insns (); insn; insn = next)
{
next = NEXT_INSN (insn);
- split_insn (insn);
+ if (INSN_P (insn))
+ {
+ /* Don't split no-op move insns. These should silently
+ disappear later in final. Splitting such insns would
+ break the code that handles REG_NO_CONFLICT blocks. */
+ rtx set = single_set (insn);
+ if (set && set_noop_p (set))
+ {
+ /* Nops get in the way while scheduling, so delete them
+ now if register allocation has already been done. It
+ is too risky to try to do this before register
+ allocation, and there are unlikely to be very many
+ nops then anyways.
+
+ ??? Should we use delete_insn when the CFG isn't valid? */
+ if (reload_completed)
+ delete_insn_and_edges (insn);
+ }
+ else
+ split_insn (insn);
+ }
}
- return;
}
#ifdef HAVE_peephole2
@@ -2898,8 +2859,7 @@ static int peep2_current;
in a multi-insn pattern. */
rtx
-peep2_next_insn (n)
- int n;
+peep2_next_insn (int n)
{
if (n >= MAX_INSNS_PER_PEEP2 + 1)
abort ();
@@ -2917,9 +2877,7 @@ peep2_next_insn (n)
after `current'. */
int
-peep2_regno_dead_p (ofs, regno)
- int ofs;
- int regno;
+peep2_regno_dead_p (int ofs, int regno)
{
if (ofs >= MAX_INSNS_PER_PEEP2 + 1)
abort ();
@@ -2937,9 +2895,7 @@ peep2_regno_dead_p (ofs, regno)
/* Similarly for a REG. */
int
-peep2_reg_dead_p (ofs, reg)
- int ofs;
- rtx reg;
+peep2_reg_dead_p (int ofs, rtx reg)
{
int regno, n;
@@ -2973,11 +2929,8 @@ peep2_reg_dead_p (ofs, reg)
returned. */
rtx
-peep2_find_free_register (from, to, class_str, mode, reg_set)
- int from, to;
- const char *class_str;
- enum machine_mode mode;
- HARD_REG_SET *reg_set;
+peep2_find_free_register (int from, int to, const char *class_str,
+ enum machine_mode mode, HARD_REG_SET *reg_set)
{
static int search_ofs;
enum reg_class class;
@@ -3011,7 +2964,7 @@ peep2_find_free_register (from, to, class_str, mode, reg_set)
}
class = (class_str[0] == 'r' ? GENERAL_REGS
- : REG_CLASS_FROM_LETTER (class_str[0]));
+ : REG_CLASS_FROM_CONSTRAINT (class_str[0], class_str));
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
@@ -3075,8 +3028,7 @@ peep2_find_free_register (from, to, class_str, mode, reg_set)
/* Perform the peephole2 optimization pass. */
void
-peephole2_optimize (dump_file)
- FILE *dump_file ATTRIBUTE_UNUSED;
+peephole2_optimize (FILE *dump_file ATTRIBUTE_UNUSED)
{
regset_head rs_heads[MAX_INSNS_PER_PEEP2 + 2];
rtx insn, prev;
@@ -3125,7 +3077,7 @@ peephole2_optimize (dump_file)
pbi = init_propagate_block_info (bb, live, NULL, NULL, PROP_DEATH_NOTES);
#endif
- for (insn = bb->end; ; insn = prev)
+ for (insn = BB_END (bb); ; insn = prev)
{
prev = PREV_INSN (insn);
if (INSN_P (insn))
@@ -3214,8 +3166,8 @@ peephole2_optimize (dump_file)
REG_EH_REGION, NULL_RTX);
/* Replace the old sequence with the new. */
- try = emit_insn_after_scope (try, peep2_insn_data[i].insn,
- INSN_SCOPE (peep2_insn_data[i].insn));
+ try = emit_insn_after_setloc (try, peep2_insn_data[i].insn,
+ INSN_LOCATOR (peep2_insn_data[i].insn));
before_try = PREV_INSN (insn);
delete_insn_chain (insn, peep2_insn_data[i].insn);
@@ -3241,7 +3193,7 @@ peephole2_optimize (dump_file)
XEXP (note, 0),
REG_NOTES (x));
- if (x != bb->end && eh_edge)
+ if (x != BB_END (bb) && eh_edge)
{
edge nfte, nehe;
int flags;
@@ -3325,7 +3277,7 @@ peephole2_optimize (dump_file)
}
}
- if (insn == bb->head)
+ if (insn == BB_HEAD (bb))
break;
}
@@ -3366,8 +3318,7 @@ peephole2_optimize (dump_file)
SETs inside. */
int
-store_data_bypass_p (out_insn, in_insn)
- rtx out_insn, in_insn;
+store_data_bypass_p (rtx out_insn, rtx in_insn)
{
rtx out_set, in_set;
@@ -3417,8 +3368,7 @@ store_data_bypass_p (out_insn, in_insn)
of insn categorization may be any JUMP or CALL insn. */
int
-if_test_bypass_p (out_insn, in_insn)
- rtx out_insn, in_insn;
+if_test_bypass_p (rtx out_insn, rtx in_insn)
{
rtx out_set, in_set;
diff --git a/contrib/gcc/recog.h b/contrib/gcc/recog.h
index 86af35f721f6..a36c89655e61 100644
--- a/contrib/gcc/recog.h
+++ b/contrib/gcc/recog.h
@@ -1,5 +1,5 @@
/* Declarations for interface to insn recognizer and insn-output.c.
- Copyright (C) 1987, 1996, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1987, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@@ -54,9 +54,9 @@ struct operand_alternative
/* Nonzero if '&' was found in the constraint string. */
unsigned int earlyclobber:1;
/* Nonzero if 'm' was found in the constraint string. */
- unsigned int memory_ok:1;
+ unsigned int memory_ok:1;
/* Nonzero if 'o' was found in the constraint string. */
- unsigned int offmem_ok:1;
+ unsigned int offmem_ok:1;
/* Nonzero if 'V' was found in the constraint string. */
unsigned int nonoffmem_ok:1;
/* Nonzero if '<' was found in the constraint string. */
@@ -71,76 +71,73 @@ struct operand_alternative
};
-extern void init_recog PARAMS ((void));
-extern void init_recog_no_volatile PARAMS ((void));
-extern int recog_memoized_1 PARAMS ((rtx));
-extern int check_asm_operands PARAMS ((rtx));
-extern int asm_operand_ok PARAMS ((rtx, const char *));
-extern int validate_change PARAMS ((rtx, rtx *, rtx, int));
-extern int insn_invalid_p PARAMS ((rtx));
-extern int apply_change_group PARAMS ((void));
-extern int num_validated_changes PARAMS ((void));
-extern void cancel_changes PARAMS ((int));
-extern int constrain_operands PARAMS ((int));
-extern int constrain_operands_cached PARAMS ((int));
-extern int memory_address_p PARAMS ((enum machine_mode, rtx));
-extern int strict_memory_address_p PARAMS ((enum machine_mode, rtx));
-extern int validate_replace_rtx_subexp PARAMS ((rtx, rtx, rtx, rtx *));
-extern int validate_replace_rtx PARAMS ((rtx, rtx, rtx));
-extern void validate_replace_rtx_group PARAMS ((rtx, rtx, rtx));
-extern int validate_replace_src PARAMS ((rtx, rtx, rtx));
-extern void validate_replace_src_group PARAMS ((rtx, rtx, rtx));
-extern int num_changes_pending PARAMS ((void));
+extern void init_recog (void);
+extern void init_recog_no_volatile (void);
+extern int recog_memoized_1 (rtx);
+extern int check_asm_operands (rtx);
+extern int asm_operand_ok (rtx, const char *);
+extern int validate_change (rtx, rtx *, rtx, int);
+extern int insn_invalid_p (rtx);
+extern int apply_change_group (void);
+extern int num_validated_changes (void);
+extern void cancel_changes (int);
+extern int constrain_operands (int);
+extern int constrain_operands_cached (int);
+extern int memory_address_p (enum machine_mode, rtx);
+extern int strict_memory_address_p (enum machine_mode, rtx);
+extern int validate_replace_rtx_subexp (rtx, rtx, rtx, rtx *);
+extern int validate_replace_rtx (rtx, rtx, rtx);
+extern void validate_replace_rtx_group (rtx, rtx, rtx);
+extern int validate_replace_src (rtx, rtx, rtx);
+extern void validate_replace_src_group (rtx, rtx, rtx);
+extern int num_changes_pending (void);
#ifdef HAVE_cc0
-extern int next_insn_tests_no_inequality PARAMS ((rtx));
+extern int next_insn_tests_no_inequality (rtx);
#endif
-extern int reg_fits_class_p PARAMS ((rtx, enum reg_class, int,
- enum machine_mode));
-extern rtx *find_single_use PARAMS ((rtx, rtx, rtx *));
-
-extern int general_operand PARAMS ((rtx, enum machine_mode));
-extern int address_operand PARAMS ((rtx, enum machine_mode));
-extern int register_operand PARAMS ((rtx, enum machine_mode));
-extern int pmode_register_operand PARAMS ((rtx, enum machine_mode));
-extern int scratch_operand PARAMS ((rtx, enum machine_mode));
-extern int immediate_operand PARAMS ((rtx, enum machine_mode));
-extern int const_int_operand PARAMS ((rtx, enum machine_mode));
-extern int const_double_operand PARAMS ((rtx, enum machine_mode));
-extern int nonimmediate_operand PARAMS ((rtx, enum machine_mode));
-extern int nonmemory_operand PARAMS ((rtx, enum machine_mode));
-extern int push_operand PARAMS ((rtx, enum machine_mode));
-extern int pop_operand PARAMS ((rtx, enum machine_mode));
-extern int memory_operand PARAMS ((rtx, enum machine_mode));
-extern int indirect_operand PARAMS ((rtx, enum machine_mode));
-extern int mode_independent_operand PARAMS ((rtx, enum machine_mode));
-extern int comparison_operator PARAMS ((rtx, enum machine_mode));
-
-extern int offsettable_memref_p PARAMS ((rtx));
-extern int offsettable_nonstrict_memref_p PARAMS ((rtx));
-extern int offsettable_address_p PARAMS ((int, enum machine_mode, rtx));
-extern int mode_dependent_address_p PARAMS ((rtx));
-
-extern int recog PARAMS ((rtx, rtx, int *));
-extern void add_clobbers PARAMS ((rtx, int));
-extern int added_clobbers_hard_reg_p PARAMS ((int));
-extern void insn_extract PARAMS ((rtx));
-extern void extract_insn PARAMS ((rtx));
-extern void extract_constrain_insn_cached PARAMS ((rtx));
-extern void extract_insn_cached PARAMS ((rtx));
-extern void preprocess_constraints PARAMS ((void));
-extern rtx peep2_next_insn PARAMS ((int));
-extern int peep2_regno_dead_p PARAMS ((int, int));
-extern int peep2_reg_dead_p PARAMS ((int, rtx));
+extern int reg_fits_class_p (rtx, enum reg_class, int, enum machine_mode);
+extern rtx *find_single_use (rtx, rtx, rtx *);
+
+extern int general_operand (rtx, enum machine_mode);
+extern int address_operand (rtx, enum machine_mode);
+extern int register_operand (rtx, enum machine_mode);
+extern int pmode_register_operand (rtx, enum machine_mode);
+extern int scratch_operand (rtx, enum machine_mode);
+extern int immediate_operand (rtx, enum machine_mode);
+extern int const_int_operand (rtx, enum machine_mode);
+extern int const_double_operand (rtx, enum machine_mode);
+extern int nonimmediate_operand (rtx, enum machine_mode);
+extern int nonmemory_operand (rtx, enum machine_mode);
+extern int push_operand (rtx, enum machine_mode);
+extern int pop_operand (rtx, enum machine_mode);
+extern int memory_operand (rtx, enum machine_mode);
+extern int indirect_operand (rtx, enum machine_mode);
+extern int comparison_operator (rtx, enum machine_mode);
+
+extern int offsettable_memref_p (rtx);
+extern int offsettable_nonstrict_memref_p (rtx);
+extern int offsettable_address_p (int, enum machine_mode, rtx);
+extern int mode_dependent_address_p (rtx);
+
+extern int recog (rtx, rtx, int *);
+extern void add_clobbers (rtx, int);
+extern int added_clobbers_hard_reg_p (int);
+extern void insn_extract (rtx);
+extern void extract_insn (rtx);
+extern void extract_constrain_insn_cached (rtx);
+extern void extract_insn_cached (rtx);
+extern void preprocess_constraints (void);
+extern rtx peep2_next_insn (int);
+extern int peep2_regno_dead_p (int, int);
+extern int peep2_reg_dead_p (int, rtx);
#ifdef CLEAR_HARD_REG_SET
-extern rtx peep2_find_free_register PARAMS ((int, int, const char *,
- enum machine_mode,
- HARD_REG_SET *));
+extern rtx peep2_find_free_register (int, int, const char *,
+ enum machine_mode, HARD_REG_SET *);
#endif
-extern void peephole2_optimize PARAMS ((FILE *));
-extern rtx peephole2_insns PARAMS ((rtx, rtx, int *));
+extern void peephole2_optimize (FILE *);
+extern rtx peephole2_insns (rtx, rtx, int *);
-extern int store_data_bypass_p PARAMS ((rtx, rtx));
-extern int if_test_bypass_p PARAMS ((rtx, rtx));
+extern int store_data_bypass_p (rtx, rtx);
+extern int if_test_bypass_p (rtx, rtx);
/* Nonzero means volatile operands are recognized. */
extern int volatile_ok;
@@ -183,7 +180,7 @@ struct recog_data
char dup_num[MAX_DUP_OPERANDS];
/* ??? Note that these are `char' instead of `unsigned char' to (try to)
- avoid certain lossage from K&R C, wherein `unsigned char' default
+ avoid certain lossage from K&R C, wherein `unsigned char' default
promotes to `unsigned int' instead of `int' as in ISO C. As of 1999,
the most common places to bootstrap from K&R C are SunOS and HPUX,
both of which have signed characters by default. The only other
@@ -214,9 +211,9 @@ extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS][MAX_RECOG_ALT
/* A table defined in insn-output.c that give information about
each insn-code value. */
-typedef int (*insn_operand_predicate_fn) PARAMS ((rtx, enum machine_mode));
-typedef const char * (*insn_output_fn) PARAMS ((rtx *, rtx));
-typedef rtx (*insn_gen_fn) PARAMS ((rtx, ...));
+typedef int (*insn_operand_predicate_fn) (rtx, enum machine_mode);
+typedef const char * (*insn_output_fn) (rtx *, rtx);
+typedef rtx (*insn_gen_fn) (rtx, ...);
struct insn_operand_data
{
@@ -224,7 +221,7 @@ struct insn_operand_data
const char *const constraint;
- const ENUM_BITFIELD(machine_mode) mode : 16;
+ ENUM_BITFIELD(machine_mode) const mode : 16;
const char strict_low;
@@ -241,7 +238,19 @@ struct insn_operand_data
struct insn_data
{
const char *const name;
- const PTR output;
+#if HAVE_DESIGNATED_INITIALIZERS
+ union {
+ const char *single;
+ const char *const *multi;
+ insn_output_fn function;
+ } output;
+#else
+ struct {
+ const char *single;
+ const char *const *multi;
+ insn_output_fn function;
+ } output;
+#endif
const insn_gen_fn genfun;
const struct insn_operand_data *const operand;
diff --git a/contrib/gcc/reg-stack.c b/contrib/gcc/reg-stack.c
index 8e6731b8c7bf..9a6c89bf310b 100644
--- a/contrib/gcc/reg-stack.c
+++ b/contrib/gcc/reg-stack.c
@@ -1,6 +1,6 @@
/* Register to Stack convert for GNU compiler.
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -153,6 +153,8 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
@@ -234,45 +236,41 @@ static rtx nan;
/* Forward declarations */
-static int stack_regs_mentioned_p PARAMS ((rtx pat));
-static void straighten_stack PARAMS ((rtx, stack));
-static void pop_stack PARAMS ((stack, int));
-static rtx *get_true_reg PARAMS ((rtx *));
-
-static int check_asm_stack_operands PARAMS ((rtx));
-static int get_asm_operand_n_inputs PARAMS ((rtx));
-static rtx stack_result PARAMS ((tree));
-static void replace_reg PARAMS ((rtx *, int));
-static void remove_regno_note PARAMS ((rtx, enum reg_note,
- unsigned int));
-static int get_hard_regnum PARAMS ((stack, rtx));
-static rtx emit_pop_insn PARAMS ((rtx, stack, rtx,
- enum emit_where));
-static void emit_swap_insn PARAMS ((rtx, stack, rtx));
-static void move_for_stack_reg PARAMS ((rtx, stack, rtx));
-static int swap_rtx_condition_1 PARAMS ((rtx));
-static int swap_rtx_condition PARAMS ((rtx));
-static void compare_for_stack_reg PARAMS ((rtx, stack, rtx));
-static void subst_stack_regs_pat PARAMS ((rtx, stack, rtx));
-static void subst_asm_stack_regs PARAMS ((rtx, stack));
-static void subst_stack_regs PARAMS ((rtx, stack));
-static void change_stack PARAMS ((rtx, stack, stack,
- enum emit_where));
-static int convert_regs_entry PARAMS ((void));
-static void convert_regs_exit PARAMS ((void));
-static int convert_regs_1 PARAMS ((FILE *, basic_block));
-static int convert_regs_2 PARAMS ((FILE *, basic_block));
-static int convert_regs PARAMS ((FILE *));
-static void print_stack PARAMS ((FILE *, stack));
-static rtx next_flags_user PARAMS ((rtx));
-static void record_label_references PARAMS ((rtx, rtx));
-static bool compensate_edge PARAMS ((edge, FILE *));
+static int stack_regs_mentioned_p (rtx pat);
+static void straighten_stack (rtx, stack);
+static void pop_stack (stack, int);
+static rtx *get_true_reg (rtx *);
+
+static int check_asm_stack_operands (rtx);
+static int get_asm_operand_n_inputs (rtx);
+static rtx stack_result (tree);
+static void replace_reg (rtx *, int);
+static void remove_regno_note (rtx, enum reg_note, unsigned int);
+static int get_hard_regnum (stack, rtx);
+static rtx emit_pop_insn (rtx, stack, rtx, enum emit_where);
+static void emit_swap_insn (rtx, stack, rtx);
+static bool move_for_stack_reg (rtx, stack, rtx);
+static int swap_rtx_condition_1 (rtx);
+static int swap_rtx_condition (rtx);
+static void compare_for_stack_reg (rtx, stack, rtx);
+static bool subst_stack_regs_pat (rtx, stack, rtx);
+static void subst_asm_stack_regs (rtx, stack);
+static bool subst_stack_regs (rtx, stack);
+static void change_stack (rtx, stack, stack, enum emit_where);
+static int convert_regs_entry (void);
+static void convert_regs_exit (void);
+static int convert_regs_1 (FILE *, basic_block);
+static int convert_regs_2 (FILE *, basic_block);
+static int convert_regs (FILE *);
+static void print_stack (FILE *, stack);
+static rtx next_flags_user (rtx);
+static void record_label_references (rtx, rtx);
+static bool compensate_edge (edge, FILE *);
/* Return nonzero if any stack register is mentioned somewhere within PAT. */
static int
-stack_regs_mentioned_p (pat)
- rtx pat;
+stack_regs_mentioned_p (rtx pat)
{
const char *fmt;
int i;
@@ -301,8 +299,7 @@ stack_regs_mentioned_p (pat)
/* Return nonzero if INSN mentions stacked registers, else return zero. */
int
-stack_regs_mentioned (insn)
- rtx insn;
+stack_regs_mentioned (rtx insn)
{
unsigned int uid, max;
int test;
@@ -334,13 +331,12 @@ stack_regs_mentioned (insn)
static rtx ix86_flags_rtx;
static rtx
-next_flags_user (insn)
- rtx insn;
+next_flags_user (rtx insn)
{
/* Search forward looking for the first use of this value.
Stop at block boundaries. */
- while (insn != current_block->end)
+ while (insn != BB_END (current_block))
{
insn = NEXT_INSN (insn);
@@ -357,9 +353,7 @@ next_flags_user (insn)
after this insn. */
static void
-straighten_stack (insn, regstack)
- rtx insn;
- stack regstack;
+straighten_stack (rtx insn, stack regstack)
{
struct stack_def temp_stack;
int top;
@@ -382,9 +376,7 @@ straighten_stack (insn, regstack)
/* Pop a register from the stack. */
static void
-pop_stack (regstack, regno)
- stack regstack;
- int regno;
+pop_stack (stack regstack, int regno)
{
int top = regstack->top;
@@ -414,10 +406,8 @@ pop_stack (regstack, regno)
code duplication created when the converter inserts pop insns on
the edges. */
-void
-reg_to_stack (first, file)
- rtx first;
- FILE *file;
+bool
+reg_to_stack (rtx first, FILE *file)
{
basic_block bb;
int i;
@@ -432,11 +422,15 @@ reg_to_stack (first, file)
if (regs_ever_live[i])
break;
if (i > LAST_STACK_REG)
- return;
+ return false;
/* Ok, floating point instructions exist. If not optimizing,
- build the CFG and run life analysis. */
- if (!optimize)
+ build the CFG and run life analysis.
+ Also need to rebuild life when superblock scheduling is done
+ as it don't update liveness yet. */
+ if (!optimize
+ || (flag_sched2_use_superblocks
+ && flag_schedule_insns_after_reload))
{
count_or_remove_death_notes (NULL, 1);
life_analysis (first, file, PROP_DEATH_NOTES);
@@ -448,7 +442,7 @@ reg_to_stack (first, file)
FOR_EACH_BB_REVERSE (bb)
{
edge e;
- for (e = bb->pred; e; e=e->pred_next)
+ for (e = bb->pred; e; e = e->pred_next)
if (!(e->flags & EDGE_DFS_BACK)
&& e->src != ENTRY_BLOCK_PTR)
BLOCK_INFO (bb)->predecessors++;
@@ -473,7 +467,7 @@ reg_to_stack (first, file)
/* A QNaN for initializing uninitialized variables.
??? We can't load from constant memory in PIC mode, because
- we're insertting these instructions before the prologue and
+ we're inserting these instructions before the prologue and
the PIC register hasn't been set up. In that case, fall back
on zero, which we can get from `ldz'. */
@@ -493,6 +487,7 @@ reg_to_stack (first, file)
convert_regs (file);
free_aux_for_blocks ();
+ return true;
}
/* Check PAT, which is in INSN, for LABEL_REFs. Add INSN to the
@@ -500,8 +495,7 @@ reg_to_stack (first, file)
reference. */
static void
-record_label_references (insn, pat)
- rtx insn, pat;
+record_label_references (rtx insn, rtx pat)
{
enum rtx_code code = GET_CODE (pat);
int i;
@@ -554,8 +548,7 @@ record_label_references (insn, pat)
PAT that stopped the search. */
static rtx *
-get_true_reg (pat)
- rtx *pat;
+get_true_reg (rtx *pat)
{
for (;;)
switch (GET_CODE (*pat))
@@ -592,8 +585,7 @@ static bool any_malformed_asm;
numbers below refer to that explanation. */
static int
-check_asm_stack_operands (insn)
- rtx insn;
+check_asm_stack_operands (rtx insn)
{
int i;
int n_clobbers;
@@ -638,7 +630,7 @@ check_asm_stack_operands (insn)
if (GET_CODE (body) == PARALLEL)
{
- clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx));
+ clobber_reg = alloca (XVECLEN (body, 0) * sizeof (rtx));
for (i = 0; i < XVECLEN (body, 0); i++)
if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
@@ -744,7 +736,7 @@ check_asm_stack_operands (insn)
malformed_asm = 1;
}
- /* Enfore rule #3: If any input operand uses the "f" constraint, all
+ /* Enforce rule #3: If any input operand uses the "f" constraint, all
output constraints must use the "&" earlyclobber.
??? Detect this more deterministically by having constrain_asm_operands
@@ -781,8 +773,7 @@ check_asm_stack_operands (insn)
placed. */
static int
-get_asm_operand_n_inputs (body)
- rtx body;
+get_asm_operand_n_inputs (rtx body)
{
if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body));
@@ -805,14 +796,13 @@ get_asm_operand_n_inputs (body)
return the REG. Otherwise, return 0. */
static rtx
-stack_result (decl)
- tree decl;
+stack_result (tree decl)
{
rtx result;
/* If the value is supposed to be returned in memory, then clearly
it is not returned in a stack register. */
- if (aggregate_value_p (DECL_RESULT (decl)))
+ if (aggregate_value_p (DECL_RESULT (decl), decl))
return 0;
result = DECL_RTL_IF_SET (DECL_RESULT (decl));
@@ -839,9 +829,7 @@ stack_result (decl)
the desired hard REGNO. */
static void
-replace_reg (reg, regno)
- rtx *reg;
- int regno;
+replace_reg (rtx *reg, int regno)
{
if (regno < FIRST_STACK_REG || regno > LAST_STACK_REG
|| ! STACK_REG_P (*reg))
@@ -861,10 +849,7 @@ replace_reg (reg, regno)
number REGNO from INSN. Remove only one such note. */
static void
-remove_regno_note (insn, note, regno)
- rtx insn;
- enum reg_note note;
- unsigned int regno;
+remove_regno_note (rtx insn, enum reg_note note, unsigned int regno)
{
rtx *note_link, this;
@@ -887,9 +872,7 @@ remove_regno_note (insn, note, regno)
returned if the register is not found. */
static int
-get_hard_regnum (regstack, reg)
- stack regstack;
- rtx reg;
+get_hard_regnum (stack regstack, rtx reg)
{
int i;
@@ -911,11 +894,7 @@ get_hard_regnum (regstack, reg)
cases the movdf pattern to pop. */
static rtx
-emit_pop_insn (insn, regstack, reg, where)
- rtx insn;
- stack regstack;
- rtx reg;
- enum emit_where where;
+emit_pop_insn (rtx insn, stack regstack, rtx reg, enum emit_where where)
{
rtx pop_insn, pop_rtx;
int hard_regno;
@@ -970,10 +949,7 @@ emit_pop_insn (insn, regstack, reg, where)
If REG is already at the top of the stack, no insn is emitted. */
static void
-emit_swap_insn (insn, regstack, reg)
- rtx insn;
- stack regstack;
- rtx reg;
+emit_swap_insn (rtx insn, stack regstack, rtx reg)
{
int hard_regno;
rtx swap_rtx;
@@ -997,10 +973,10 @@ emit_swap_insn (insn, regstack, reg)
/* Find the previous insn involving stack regs, but don't pass a
block boundary. */
i1 = NULL;
- if (current_block && insn != current_block->head)
+ if (current_block && insn != BB_HEAD (current_block))
{
rtx tmp = PREV_INSN (insn);
- rtx limit = PREV_INSN (current_block->head);
+ rtx limit = PREV_INSN (BB_HEAD (current_block));
while (tmp != limit)
{
if (GET_CODE (tmp) == CODE_LABEL
@@ -1046,24 +1022,23 @@ emit_swap_insn (insn, regstack, reg)
if (i1)
emit_insn_after (swap_rtx, i1);
else if (current_block)
- emit_insn_before (swap_rtx, current_block->head);
+ emit_insn_before (swap_rtx, BB_HEAD (current_block));
else
emit_insn_before (swap_rtx, insn);
}
/* Handle a move to or from a stack register in PAT, which is in INSN.
- REGSTACK is the current stack. */
+ REGSTACK is the current stack. Return whether a control flow insn
+ was deleted in the process. */
-static void
-move_for_stack_reg (insn, regstack, pat)
- rtx insn;
- stack regstack;
- rtx pat;
+static bool
+move_for_stack_reg (rtx insn, stack regstack, rtx pat)
{
rtx *psrc = get_true_reg (&SET_SRC (pat));
rtx *pdest = get_true_reg (&SET_DEST (pat));
rtx src, dest;
rtx note;
+ bool control_flow_insn_deleted = false;
src = *psrc; dest = *pdest;
@@ -1093,21 +1068,17 @@ move_for_stack_reg (insn, regstack, pat)
If so, just pop the src. */
if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
+ emit_pop_insn (insn, regstack, src, EMIT_AFTER);
+ else
{
- emit_pop_insn (insn, regstack, src, EMIT_AFTER);
-
- delete_insn (insn);
- return;
+ regstack->reg[i] = REGNO (dest);
+ SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
+ CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
}
- regstack->reg[i] = REGNO (dest);
-
- SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
- CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
-
+ control_flow_insn_deleted |= control_flow_insn_p (insn);
delete_insn (insn);
-
- return;
+ return control_flow_insn_deleted;
}
/* The source reg does not die. */
@@ -1122,8 +1093,9 @@ move_for_stack_reg (insn, regstack, pat)
if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
emit_pop_insn (insn, regstack, dest, EMIT_AFTER);
+ control_flow_insn_deleted |= control_flow_insn_p (insn);
delete_insn (insn);
- return;
+ return control_flow_insn_deleted;
}
/* The destination ought to be dead. */
@@ -1151,7 +1123,7 @@ move_for_stack_reg (insn, regstack, pat)
regstack->top--;
CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
}
- else if ((GET_MODE (src) == XFmode || GET_MODE (src) == TFmode)
+ else if ((GET_MODE (src) == XFmode)
&& regstack->top < REG_STACK_SIZE - 1)
{
/* A 387 cannot write an XFmode value to a MEM without
@@ -1164,10 +1136,7 @@ move_for_stack_reg (insn, regstack, pat)
rtx push_rtx, push_insn;
rtx top_stack_reg = FP_MODE_REG (FIRST_STACK_REG, GET_MODE (src));
- if (GET_MODE (src) == TFmode)
- push_rtx = gen_movtf (top_stack_reg, top_stack_reg);
- else
- push_rtx = gen_movxf (top_stack_reg, top_stack_reg);
+ push_rtx = gen_movxf (top_stack_reg, top_stack_reg);
push_insn = emit_insn_before (push_rtx, insn);
REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, top_stack_reg,
REG_NOTES (insn));
@@ -1195,6 +1164,8 @@ move_for_stack_reg (insn, regstack, pat)
}
else
abort ();
+
+ return control_flow_insn_deleted;
}
/* Swap the condition on a branch, if there is one. Return true if we
@@ -1202,8 +1173,7 @@ move_for_stack_reg (insn, regstack, pat)
such. */
static int
-swap_rtx_condition_1 (pat)
- rtx pat;
+swap_rtx_condition_1 (rtx pat)
{
const char *fmt;
int i, r = 0;
@@ -1234,8 +1204,7 @@ swap_rtx_condition_1 (pat)
}
static int
-swap_rtx_condition (insn)
- rtx insn;
+swap_rtx_condition (rtx insn)
{
rtx pat = PATTERN (insn);
@@ -1263,7 +1232,7 @@ swap_rtx_condition (insn)
/* Search forward looking for the first use of this value.
Stop at block boundaries. */
- while (insn != current_block->end)
+ while (insn != BB_END (current_block))
{
insn = NEXT_INSN (insn);
if (INSN_P (insn) && reg_mentioned_p (dest, insn))
@@ -1322,10 +1291,7 @@ swap_rtx_condition (insn)
set up. */
static void
-compare_for_stack_reg (insn, regstack, pat_src)
- rtx insn;
- stack regstack;
- rtx pat_src;
+compare_for_stack_reg (rtx insn, stack regstack, rtx pat_src)
{
rtx *src1, *src2;
rtx src1_note, src2_note;
@@ -1411,15 +1377,14 @@ compare_for_stack_reg (insn, regstack, pat_src)
}
/* Substitute new registers in PAT, which is part of INSN. REGSTACK
- is the current register layout. */
+ is the current register layout. Return whether a control flow insn
+ was deleted in the process. */
-static void
-subst_stack_regs_pat (insn, regstack, pat)
- rtx insn;
- stack regstack;
- rtx pat;
+static bool
+subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
{
rtx *dest, *src;
+ bool control_flow_insn_deleted = false;
switch (GET_CODE (pat))
{
@@ -1431,7 +1396,7 @@ subst_stack_regs_pat (insn, regstack, pat)
&& find_regno_note (insn, REG_DEAD, REGNO (*src)))
{
emit_pop_insn (insn, regstack, *src, EMIT_AFTER);
- return;
+ return control_flow_insn_deleted;
}
/* ??? Uninitialized USE should not happen. */
else if (get_hard_regnum (regstack, *src) == -1)
@@ -1465,7 +1430,7 @@ subst_stack_regs_pat (insn, regstack, pat)
abort ();
}
remove_note (insn, note);
- replace_reg (dest, LAST_STACK_REG);
+ replace_reg (dest, FIRST_STACK_REG + 1);
}
else
{
@@ -1481,7 +1446,7 @@ subst_stack_regs_pat (insn, regstack, pat)
FP_MODE_REG (REGNO (*dest), SFmode),
nan);
PATTERN (insn) = pat;
- move_for_stack_reg (insn, regstack, pat);
+ control_flow_insn_deleted |= move_for_stack_reg (insn, regstack, pat);
}
if (! note && COMPLEX_MODE_P (GET_MODE (*dest))
&& get_hard_regnum (regstack, FP_MODE_REG (REGNO (*dest), DFmode)) == -1)
@@ -1490,7 +1455,7 @@ subst_stack_regs_pat (insn, regstack, pat)
FP_MODE_REG (REGNO (*dest) + 1, SFmode),
nan);
PATTERN (insn) = pat;
- move_for_stack_reg (insn, regstack, pat);
+ control_flow_insn_deleted |= move_for_stack_reg (insn, regstack, pat);
}
}
}
@@ -1513,7 +1478,7 @@ subst_stack_regs_pat (insn, regstack, pat)
&& (GET_CODE (*src) == REG || GET_CODE (*src) == MEM
|| GET_CODE (*src) == CONST_DOUBLE)))
{
- move_for_stack_reg (insn, regstack, pat);
+ control_flow_insn_deleted |= move_for_stack_reg (insn, regstack, pat);
break;
}
@@ -1688,7 +1653,7 @@ subst_stack_regs_pat (insn, regstack, pat)
replace_reg (dest, get_hard_regnum (regstack, *dest));
}
- /* Keep operand 1 maching with destination. */
+ /* Keep operand 1 matching with destination. */
if (GET_RTX_CLASS (GET_CODE (pat_src)) == 'c'
&& REG_P (*src1) && REG_P (*src2)
&& REGNO (*src1) != REGNO (*dest))
@@ -1704,6 +1669,8 @@ subst_stack_regs_pat (insn, regstack, pat)
{
case UNSPEC_SIN:
case UNSPEC_COS:
+ case UNSPEC_FRNDINT:
+ case UNSPEC_F2XM1:
/* These insns only operate on the top of the stack. */
src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
@@ -1725,6 +1692,75 @@ subst_stack_regs_pat (insn, regstack, pat)
replace_reg (src1, FIRST_STACK_REG);
break;
+ case UNSPEC_FPATAN:
+ case UNSPEC_FYL2X:
+ case UNSPEC_FSCALE:
+ /* These insns operate on the top two stack slots. */
+
+ src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
+ src2 = get_true_reg (&XVECEXP (pat_src, 0, 1));
+
+ src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+ src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
+
+ {
+ struct stack_def temp_stack;
+ int regno, j, k, temp;
+
+ temp_stack = *regstack;
+
+ /* Place operand 1 at the top of stack. */
+ regno = get_hard_regnum (&temp_stack, *src1);
+ if (regno < 0)
+ abort ();
+ if (regno != FIRST_STACK_REG)
+ {
+ k = temp_stack.top - (regno - FIRST_STACK_REG);
+ j = temp_stack.top;
+
+ temp = temp_stack.reg[k];
+ temp_stack.reg[k] = temp_stack.reg[j];
+ temp_stack.reg[j] = temp;
+ }
+
+ /* Place operand 2 next on the stack. */
+ regno = get_hard_regnum (&temp_stack, *src2);
+ if (regno < 0)
+ abort ();
+ if (regno != FIRST_STACK_REG + 1)
+ {
+ k = temp_stack.top - (regno - FIRST_STACK_REG);
+ j = temp_stack.top - 1;
+
+ temp = temp_stack.reg[k];
+ temp_stack.reg[k] = temp_stack.reg[j];
+ temp_stack.reg[j] = temp;
+ }
+
+ change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
+ }
+
+ replace_reg (src1, FIRST_STACK_REG);
+ replace_reg (src2, FIRST_STACK_REG + 1);
+
+ if (src1_note)
+ replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
+ if (src2_note)
+ replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1);
+
+ /* Pop both input operands from the stack. */
+ CLEAR_HARD_REG_BIT (regstack->reg_set,
+ regstack->reg[regstack->top]);
+ CLEAR_HARD_REG_BIT (regstack->reg_set,
+ regstack->reg[regstack->top - 1]);
+ regstack->top -= 2;
+
+ /* Push the result back onto the stack. */
+ regstack->reg[++regstack->top] = REGNO (*dest);
+ SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+ replace_reg (dest, FIRST_STACK_REG);
+ break;
+
case UNSPEC_SAHF:
/* (unspec [(unspec [(compare)] UNSPEC_FNSTSW)] UNSPEC_SAHF)
The combination matches the PPRO fcomi instruction. */
@@ -1733,7 +1769,7 @@ subst_stack_regs_pat (insn, regstack, pat)
if (GET_CODE (pat_src) != UNSPEC
|| XINT (pat_src, 1) != UNSPEC_FNSTSW)
abort ();
- /* FALLTHRU */
+ /* Fall through. */
case UNSPEC_FNSTSW:
/* Combined fcomp+fnstsw generated for doing well with
@@ -1846,6 +1882,8 @@ subst_stack_regs_pat (insn, regstack, pat)
default:
break;
}
+
+ return control_flow_insn_deleted;
}
/* Substitute hard regnums for any stack regs in INSN, which has
@@ -1859,9 +1897,7 @@ subst_stack_regs_pat (insn, regstack, pat)
requirements, since record_asm_stack_regs removes any problem asm. */
static void
-subst_asm_stack_regs (insn, regstack)
- rtx insn;
- stack regstack;
+subst_asm_stack_regs (rtx insn, stack regstack)
{
rtx body = PATTERN (insn);
int alt;
@@ -1912,9 +1948,9 @@ subst_asm_stack_regs (insn, regstack)
for (i = 0, note = REG_NOTES (insn); note; note = XEXP (note, 1))
i++;
- note_reg = (rtx *) alloca (i * sizeof (rtx));
- note_loc = (rtx **) alloca (i * sizeof (rtx *));
- note_kind = (enum reg_note *) alloca (i * sizeof (enum reg_note));
+ note_reg = alloca (i * sizeof (rtx));
+ note_loc = alloca (i * sizeof (rtx *));
+ note_kind = alloca (i * sizeof (enum reg_note));
n_notes = 0;
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
@@ -1945,8 +1981,8 @@ subst_asm_stack_regs (insn, regstack)
if (GET_CODE (body) == PARALLEL)
{
- clobber_reg = (rtx *) alloca (XVECLEN (body, 0) * sizeof (rtx));
- clobber_loc = (rtx **) alloca (XVECLEN (body, 0) * sizeof (rtx *));
+ clobber_reg = alloca (XVECLEN (body, 0) * sizeof (rtx));
+ clobber_loc = alloca (XVECLEN (body, 0) * sizeof (rtx *));
for (i = 0; i < XVECLEN (body, 0); i++)
if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
@@ -2145,14 +2181,14 @@ subst_asm_stack_regs (insn, regstack)
/* Substitute stack hard reg numbers for stack virtual registers in
INSN. Non-stack register numbers are not changed. REGSTACK is the
current stack content. Insns may be emitted as needed to arrange the
- stack for the 387 based on the contents of the insn. */
+ stack for the 387 based on the contents of the insn. Return whether
+ a control flow insn was deleted in the process. */
-static void
-subst_stack_regs (insn, regstack)
- rtx insn;
- stack regstack;
+static bool
+subst_stack_regs (rtx insn, stack regstack)
{
rtx *note_link, note;
+ bool control_flow_insn_deleted = false;
int i;
if (GET_CODE (insn) == CALL_INSN)
@@ -2193,25 +2229,27 @@ subst_stack_regs (insn, regstack)
Any REG_UNUSED notes will be handled by subst_asm_stack_regs. */
subst_asm_stack_regs (insn, regstack);
- return;
+ return control_flow_insn_deleted;
}
if (GET_CODE (PATTERN (insn)) == PARALLEL)
for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
{
if (stack_regs_mentioned_p (XVECEXP (PATTERN (insn), 0, i)))
- subst_stack_regs_pat (insn, regstack,
- XVECEXP (PATTERN (insn), 0, i));
+ control_flow_insn_deleted
+ |= subst_stack_regs_pat (insn, regstack,
+ XVECEXP (PATTERN (insn), 0, i));
}
else
- subst_stack_regs_pat (insn, regstack, PATTERN (insn));
+ control_flow_insn_deleted
+ |= subst_stack_regs_pat (insn, regstack, PATTERN (insn));
}
/* subst_stack_regs_pat may have deleted a no-op insn. If so, any
REG_UNUSED will already have been dealt with, so just return. */
if (GET_CODE (insn) == NOTE || INSN_DELETED_P (insn))
- return;
+ return control_flow_insn_deleted;
/* If there is a REG_UNUSED note on a stack register on this insn,
the indicated reg must be popped. The REG_UNUSED note is removed,
@@ -2227,6 +2265,8 @@ subst_stack_regs (insn, regstack)
}
else
note_link = &XEXP (note, 1);
+
+ return control_flow_insn_deleted;
}
/* Change the organization of the stack so that it fits a new basic
@@ -2242,11 +2282,7 @@ subst_stack_regs (insn, regstack)
is no longer needed once this has executed. */
static void
-change_stack (insn, old, new, where)
- rtx insn;
- stack old;
- stack new;
- enum emit_where where;
+change_stack (rtx insn, stack old, stack new, enum emit_where where)
{
int reg;
int update_end = 0;
@@ -2256,7 +2292,7 @@ change_stack (insn, old, new, where)
if (where == EMIT_AFTER)
{
- if (current_block && current_block->end == insn)
+ if (current_block && BB_END (current_block) == insn)
update_end = 1;
insn = NEXT_INSN (insn);
}
@@ -2339,15 +2375,13 @@ change_stack (insn, old, new, where)
}
if (update_end)
- current_block->end = PREV_INSN (insn);
+ BB_END (current_block) = PREV_INSN (insn);
}
/* Print stack configuration. */
static void
-print_stack (file, s)
- FILE *file;
- stack s;
+print_stack (FILE *file, stack s)
{
if (! file)
return;
@@ -2375,7 +2409,7 @@ print_stack (file, s)
commit_edge_insertions needs to be called. */
static int
-convert_regs_entry ()
+convert_regs_entry (void)
{
int inserted = 0;
edge e;
@@ -2405,7 +2439,7 @@ convert_regs_entry ()
the push/pop code happy, and to not scrog the register stack, we
must put something in these registers. Use a QNaN.
- Note that we are insertting converted code here. This code is
+ Note that we are inserting converted code here. This code is
never seen by the convert_regs pass. */
for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
@@ -2438,7 +2472,7 @@ convert_regs_entry ()
be `empty', or the function return value at top-of-stack. */
static void
-convert_regs_exit ()
+convert_regs_exit (void)
{
int value_reg_low, value_reg_high;
stack output_stack;
@@ -2473,9 +2507,7 @@ convert_regs_exit ()
target block, or copy stack info into the stack of the successor
of the successor hasn't been processed yet. */
static bool
-compensate_edge (e, file)
- edge e;
- FILE *file;
+compensate_edge (edge e, FILE *file)
{
basic_block block = e->src, target = e->dest;
block_info bi = BLOCK_INFO (block);
@@ -2504,7 +2536,7 @@ compensate_edge (e, file)
/* change_stack kills values in regstack. */
tmpstack = regstack;
- change_stack (block->end, &tmpstack, target_stack, EMIT_AFTER);
+ change_stack (BB_END (block), &tmpstack, target_stack, EMIT_AFTER);
return false;
}
@@ -2575,8 +2607,8 @@ compensate_edge (e, file)
/* change_stack kills values in regstack. */
tmpstack = regstack;
- change_stack (block->end, &tmpstack, target_stack,
- (GET_CODE (block->end) == JUMP_INSN
+ change_stack (BB_END (block), &tmpstack, target_stack,
+ (GET_CODE (BB_END (block)) == JUMP_INSN
? EMIT_BEFORE : EMIT_AFTER));
}
else
@@ -2593,7 +2625,7 @@ compensate_edge (e, file)
start_sequence ();
/* ??? change_stack needs some point to emit insns after. */
- after = emit_note (NULL, NOTE_INSN_DELETED);
+ after = emit_note (NOTE_INSN_DELETED);
tmpstack = regstack;
change_stack (after, &tmpstack, target_stack, EMIT_BEFORE);
@@ -2610,15 +2642,14 @@ compensate_edge (e, file)
/* Convert stack register references in one block. */
static int
-convert_regs_1 (file, block)
- FILE *file;
- basic_block block;
+convert_regs_1 (FILE *file, basic_block block)
{
struct stack_def regstack;
block_info bi = BLOCK_INFO (block);
int deleted, inserted, reg;
rtx insn, next;
edge e, beste = NULL;
+ bool control_flow_insn_deleted = false;
inserted = 0;
deleted = 0;
@@ -2683,7 +2714,7 @@ convert_regs_1 (file, block)
/* Process all insns in this block. Keep track of NEXT so that we
don't process insns emitted while substituting in INSN. */
- next = block->head;
+ next = BB_HEAD (block);
regstack = bi->stack_in;
do
{
@@ -2693,7 +2724,7 @@ convert_regs_1 (file, block)
/* Ensure we have not missed a block boundary. */
if (next == NULL)
abort ();
- if (insn == block->end)
+ if (insn == BB_END (block))
next = NULL;
/* Don't bother processing unless there is a stack reg
@@ -2707,8 +2738,7 @@ convert_regs_1 (file, block)
INSN_UID (insn));
print_stack (file, &regstack);
}
- subst_stack_regs (insn, &regstack);
- deleted |= (GET_CODE (insn) == NOTE || INSN_DELETED_P (insn));
+ control_flow_insn_deleted |= subst_stack_regs (insn, &regstack);
}
}
while (next);
@@ -2723,7 +2753,7 @@ convert_regs_1 (file, block)
print_stack (file, &regstack);
}
- insn = block->end;
+ insn = BB_END (block);
if (GET_CODE (insn) == JUMP_INSN)
insn = PREV_INSN (insn);
@@ -2747,8 +2777,7 @@ convert_regs_1 (file, block)
set = gen_rtx_SET (VOIDmode, FP_MODE_REG (reg, SFmode),
nan);
insn = emit_insn_after (set, insn);
- subst_stack_regs (insn, &regstack);
- deleted |= (GET_CODE (insn) == NOTE || INSN_DELETED_P (insn));
+ control_flow_insn_deleted |= subst_stack_regs (insn, &regstack);
}
}
@@ -2758,12 +2787,18 @@ convert_regs_1 (file, block)
called at the end of convert_regs. The order in which we process the
blocks ensures that we never delete an already processed edge.
+ Note that, at this point, the CFG may have been damaged by the emission
+ of instructions after an abnormal call, which moves the basic block end
+ (and is the reason why we call fixup_abnormal_edges later). So we must
+ be sure that the trapping insn has been deleted before trying to purge
+ dead edges, otherwise we risk purging valid edges.
+
??? We are normally supposed not to delete trapping insns, so we pretend
that the insns deleted above don't actually trap. It would have been
better to detect this earlier and avoid creating the EH edge in the first
place, still, but we don't have enough information at that time. */
- if (deleted)
+ if (control_flow_insn_deleted)
purge_dead_edges (block);
/* Something failed if the stack lives don't match. If we had malformed
@@ -2804,9 +2839,7 @@ convert_regs_1 (file, block)
/* Convert registers in all blocks reachable from BLOCK. */
static int
-convert_regs_2 (file, block)
- FILE *file;
- basic_block block;
+convert_regs_2 (FILE *file, basic_block block)
{
basic_block *stack, *sp;
int inserted;
@@ -2815,7 +2848,7 @@ convert_regs_2 (file, block)
is only processed after all its predecessors. The number of predecessors
of every block has already been computed. */
- stack = (basic_block *) xmalloc (sizeof (*stack) * n_basic_blocks);
+ stack = xmalloc (sizeof (*stack) * n_basic_blocks);
sp = stack;
*sp++ = block;
@@ -2861,8 +2894,7 @@ convert_regs_2 (file, block)
to the stack-like registers the 387 uses. */
static int
-convert_regs (file)
- FILE *file;
+convert_regs (FILE *file)
{
int inserted;
basic_block b;
diff --git a/contrib/gcc/regclass.c b/contrib/gcc/regclass.c
index 45c69d8b89a1..2e4dc61be32f 100644
--- a/contrib/gcc/regclass.c
+++ b/contrib/gcc/regclass.c
@@ -1,6 +1,6 @@
/* Compute register class preferences for pseudo-registers.
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996
- 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -26,6 +26,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "hard-reg-set.h"
#include "rtl.h"
#include "expr.h"
@@ -41,14 +43,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "output.h"
#include "ggc.h"
+#include "timevar.h"
-#ifndef REGISTER_MOVE_COST
-#define REGISTER_MOVE_COST(m, x, y) 2
-#endif
-
-static void init_reg_sets_1 PARAMS ((void));
-static void init_reg_modes PARAMS ((void));
-static void init_reg_autoinc PARAMS ((void));
+static void init_reg_sets_1 (void);
+static void init_reg_autoinc (void);
/* If we have auto-increment or auto-decrement and we can have secondary
reloads, we are not allowed to use classes requiring secondary
@@ -181,12 +179,9 @@ enum reg_class reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES];
enum reg_class reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];
-/* Array containing all of the register names. Unless
- DEBUG_REGISTER_NAMES is defined, use the copy in print-rtl.c. */
+/* Array containing all of the register names. */
-#ifdef DEBUG_REGISTER_NAMES
const char * reg_names[] = REGISTER_NAMES;
-#endif
/* For each hard register, the widest mode object that it can contain.
This will be a MODE_INT mode if the register can hold integers. Otherwise
@@ -262,7 +257,7 @@ static int no_global_reg_vars = 0;
Once this is done, various switches may override. */
void
-init_reg_sets ()
+init_reg_sets (void)
{
int i, j;
@@ -297,7 +292,7 @@ init_reg_sets ()
`fixed_regs' and `call_used_regs', convert them to HARD_REG_SETs. */
static void
-init_reg_sets_1 ()
+init_reg_sets_1 (void)
{
unsigned int i, j;
unsigned int /* enum machine_mode */ m;
@@ -312,7 +307,7 @@ init_reg_sets_1 ()
/* Compute number of hard regs in each class. */
- memset ((char *) reg_class_size, 0, sizeof reg_class_size);
+ memset (reg_class_size, 0, sizeof reg_class_size);
for (i = 0; i < N_REG_CLASSES; i++)
for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
if (TEST_HARD_REG_BIT (reg_class_contents[i], j))
@@ -326,10 +321,7 @@ init_reg_sets_1 ()
{
for (j = 0; j < N_REG_CLASSES; j++)
{
-#ifdef HARD_REG_SET
- register /* Declare it register if it's a scalar. */
-#endif
- HARD_REG_SET c;
+ HARD_REG_SET c;
int k;
COPY_HARD_REG_SET (c, reg_class_contents[i]);
@@ -341,7 +333,7 @@ init_reg_sets_1 ()
continue;
subclass1:
- /* keep the largest subclass */ /* SPEE 900308 */
+ /* Keep the largest subclass. */ /* SPEE 900308 */
GO_IF_HARD_REG_SUBSET (reg_class_contents[k],
reg_class_contents[(int) reg_class_subunion[i][j]],
subclass2);
@@ -360,10 +352,7 @@ init_reg_sets_1 ()
{
for (j = 0; j < N_REG_CLASSES; j++)
{
-#ifdef HARD_REG_SET
- register /* Declare it register if it's a scalar. */
-#endif
- HARD_REG_SET c;
+ HARD_REG_SET c;
int k;
COPY_HARD_REG_SET (c, reg_class_contents[i]);
@@ -458,7 +447,7 @@ init_reg_sets_1 ()
;
#endif
#ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
- else if (i == PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
+ else if (i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
;
#endif
else if (0
@@ -547,14 +536,14 @@ init_reg_sets_1 ()
These values are used to record death information for individual registers
(as opposed to a multi-register mode). */
-static void
-init_reg_modes ()
+void
+init_reg_modes_once (void)
{
int i;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
- reg_raw_mode[i] = choose_hard_reg_mode (i, 1);
+ reg_raw_mode[i] = choose_hard_reg_mode (i, 1, false);
/* If we couldn't find a valid mode, just use the previous mode.
??? One situation in which we need to do this is on the mips where
@@ -570,14 +559,12 @@ init_reg_modes ()
initialize the register modes. */
void
-init_regs ()
+init_regs (void)
{
/* This finishes what was started by init_reg_sets, but couldn't be done
until after register usage was specified. */
init_reg_sets_1 ();
- init_reg_modes ();
-
init_reg_autoinc ();
}
@@ -585,7 +572,7 @@ init_regs ()
memory_move_secondary_cost. */
void
-init_fake_stack_mems ()
+init_fake_stack_mems (void)
{
#ifdef HAVE_SECONDARY_RELOADS
{
@@ -603,10 +590,7 @@ init_fake_stack_mems ()
Only needed if secondary reloads are required for memory moves. */
int
-memory_move_secondary_cost (mode, class, in)
- enum machine_mode mode;
- enum reg_class class;
- int in;
+memory_move_secondary_cost (enum machine_mode mode, enum reg_class class, int in)
{
enum reg_class altclass;
int partial_cost = 0;
@@ -657,12 +641,12 @@ memory_move_secondary_cost (mode, class, in)
#endif
/* Return a machine mode that is legitimate for hard reg REGNO and large
- enough to save nregs. If we can't find one, return VOIDmode. */
+ enough to save nregs. If we can't find one, return VOIDmode.
+ If CALL_SAVED is true, only consider modes that are call saved. */
enum machine_mode
-choose_hard_reg_mode (regno, nregs)
- unsigned int regno ATTRIBUTE_UNUSED;
- unsigned int nregs;
+choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
+ unsigned int nregs, bool call_saved)
{
unsigned int /* enum machine_mode */ m;
enum machine_mode found_mode = VOIDmode, mode;
@@ -675,7 +659,8 @@ choose_hard_reg_mode (regno, nregs)
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
if ((unsigned) HARD_REGNO_NREGS (regno, mode) == nregs
- && HARD_REGNO_MODE_OK (regno, mode))
+ && HARD_REGNO_MODE_OK (regno, mode)
+ && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
found_mode = mode;
if (found_mode != VOIDmode)
@@ -685,7 +670,8 @@ choose_hard_reg_mode (regno, nregs)
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
if ((unsigned) HARD_REGNO_NREGS (regno, mode) == nregs
- && HARD_REGNO_MODE_OK (regno, mode))
+ && HARD_REGNO_MODE_OK (regno, mode)
+ && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
found_mode = mode;
if (found_mode != VOIDmode)
@@ -695,7 +681,8 @@ choose_hard_reg_mode (regno, nregs)
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
if ((unsigned) HARD_REGNO_NREGS (regno, mode) == nregs
- && HARD_REGNO_MODE_OK (regno, mode))
+ && HARD_REGNO_MODE_OK (regno, mode)
+ && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
found_mode = mode;
if (found_mode != VOIDmode)
@@ -705,7 +692,8 @@ choose_hard_reg_mode (regno, nregs)
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
if ((unsigned) HARD_REGNO_NREGS (regno, mode) == nregs
- && HARD_REGNO_MODE_OK (regno, mode))
+ && HARD_REGNO_MODE_OK (regno, mode)
+ && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
found_mode = mode;
if (found_mode != VOIDmode)
@@ -716,7 +704,8 @@ choose_hard_reg_mode (regno, nregs)
{
mode = (enum machine_mode) m;
if ((unsigned) HARD_REGNO_NREGS (regno, mode) == nregs
- && HARD_REGNO_MODE_OK (regno, mode))
+ && HARD_REGNO_MODE_OK (regno, mode)
+ && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
return mode;
}
@@ -729,9 +718,7 @@ choose_hard_reg_mode (regno, nregs)
call-used register if CALL_USED. */
void
-fix_register (name, fixed, call_used)
- const char *name;
- int fixed, call_used;
+fix_register (const char *name, int fixed, int call_used)
{
int i;
@@ -775,8 +762,7 @@ fix_register (name, fixed, call_used)
/* Mark register number I as global. */
void
-globalize_reg (i)
- int i;
+globalize_reg (int i)
{
if (fixed_regs[i] == 0 && no_global_reg_vars)
error ("global register variable follows a function definition");
@@ -818,7 +804,7 @@ struct costs
int mem_cost;
};
-/* Structure used to record preferrences of given pseudo. */
+/* Structure used to record preferences of given pseudo. */
struct reg_pref
{
/* (enum reg_class) prefclass is the preferred class. */
@@ -842,7 +828,7 @@ static struct costs *costs;
static struct costs init_cost;
-/* Record preferrences of each pseudo.
+/* Record preferences of each pseudo.
This is available after `regclass' is run. */
static struct reg_pref *reg_pref;
@@ -855,27 +841,25 @@ static struct reg_pref *reg_pref_buffer;
static int frequency;
-static rtx scan_one_insn PARAMS ((rtx, int));
-static void record_operand_costs PARAMS ((rtx, struct costs *, struct reg_pref *));
-static void dump_regclass PARAMS ((FILE *));
-static void record_reg_classes PARAMS ((int, int, rtx *, enum machine_mode *,
- const char **, rtx,
- struct costs *, struct reg_pref *));
-static int copy_cost PARAMS ((rtx, enum machine_mode,
- enum reg_class, int));
-static void record_address_regs PARAMS ((rtx, enum reg_class, int));
+static rtx scan_one_insn (rtx, int);
+static void record_operand_costs (rtx, struct costs *, struct reg_pref *);
+static void dump_regclass (FILE *);
+static void record_reg_classes (int, int, rtx *, enum machine_mode *,
+ const char **, rtx, struct costs *,
+ struct reg_pref *);
+static int copy_cost (rtx, enum machine_mode, enum reg_class, int);
+static void record_address_regs (rtx, enum reg_class, int);
#ifdef FORBIDDEN_INC_DEC_CLASSES
-static int auto_inc_dec_reg_p PARAMS ((rtx, enum machine_mode));
+static int auto_inc_dec_reg_p (rtx, enum machine_mode);
#endif
-static void reg_scan_mark_refs PARAMS ((rtx, rtx, int, unsigned int));
+static void reg_scan_mark_refs (rtx, rtx, int, unsigned int);
/* Return the reg_class in which pseudo reg number REGNO is best allocated.
This function is sometimes called before the info has been computed.
When that happens, just return GENERAL_REGS, which is innocuous. */
enum reg_class
-reg_preferred_class (regno)
- int regno;
+reg_preferred_class (int regno)
{
if (reg_pref == 0)
return GENERAL_REGS;
@@ -883,8 +867,7 @@ reg_preferred_class (regno)
}
enum reg_class
-reg_alternate_class (regno)
- int regno;
+reg_alternate_class (int regno)
{
if (reg_pref == 0)
return ALL_REGS;
@@ -895,7 +878,7 @@ reg_alternate_class (regno)
/* Initialize some global data for this pass. */
void
-regclass_init ()
+regclass_init (void)
{
int i;
@@ -913,8 +896,7 @@ regclass_init ()
/* Dump register costs. */
static void
-dump_regclass (dump)
- FILE *dump;
+dump_regclass (FILE *dump)
{
static const char *const reg_class_names[] = REG_CLASS_NAMES;
int i;
@@ -946,10 +928,8 @@ dump_regclass (dump)
/* Calculate the costs of insn operands. */
static void
-record_operand_costs (insn, op_costs, reg_pref)
- rtx insn;
- struct costs *op_costs;
- struct reg_pref *reg_pref;
+record_operand_costs (rtx insn, struct costs *op_costs,
+ struct reg_pref *reg_pref)
{
const char *constraints[MAX_RECOG_OPERANDS];
enum machine_mode modes[MAX_RECOG_OPERANDS];
@@ -978,7 +958,7 @@ record_operand_costs (insn, op_costs, reg_pref)
record_address_regs (XEXP (recog_data.operand[i], 0),
MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
else if (constraints[i][0] == 'p'
- || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
+ || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i]))
record_address_regs (recog_data.operand[i],
MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
}
@@ -1019,9 +999,7 @@ record_operand_costs (insn, op_costs, reg_pref)
there. */
static rtx
-scan_one_insn (insn, pass)
- rtx insn;
- int pass;
+scan_one_insn (rtx insn, int pass)
{
enum rtx_code code = GET_CODE (insn);
enum rtx_code pat_code;
@@ -1101,8 +1079,8 @@ scan_one_insn (insn, pass)
{
basic_block b;
FOR_EACH_BB (b)
- if (insn == b->head)
- b->head = newinsn;
+ if (insn == BB_HEAD (b))
+ BB_HEAD (b) = newinsn;
}
/* This makes one more setting of new insns's dest. */
@@ -1148,7 +1126,7 @@ scan_one_insn (insn, pass)
pseudos that are auto-incremented or auto-decremented. */
static void
-init_reg_autoinc ()
+init_reg_autoinc (void)
{
#ifdef FORBIDDEN_INC_DEC_CLASSES
int i;
@@ -1204,10 +1182,7 @@ init_reg_autoinc ()
This pass comes just before local register allocation. */
void
-regclass (f, nregs, dump)
- rtx f;
- int nregs;
- FILE *dump;
+regclass (rtx f, int nregs, FILE *dump)
{
rtx insn;
int i;
@@ -1215,11 +1190,11 @@ regclass (f, nregs, dump)
init_recog ();
- costs = (struct costs *) xmalloc (nregs * sizeof (struct costs));
+ costs = xmalloc (nregs * sizeof (struct costs));
#ifdef FORBIDDEN_INC_DEC_CLASSES
- in_inc_dec = (char *) xmalloc (nregs);
+ in_inc_dec = xmalloc (nregs);
#endif /* FORBIDDEN_INC_DEC_CLASSES */
@@ -1236,7 +1211,7 @@ regclass (f, nregs, dump)
fprintf (dump, "\n\nPass %i\n\n",pass);
/* Zero out our accumulation of the cost of each class for each reg. */
- memset ((char *) costs, 0, nregs * sizeof (struct costs));
+ memset (costs, 0, nregs * sizeof (struct costs));
#ifdef FORBIDDEN_INC_DEC_CLASSES
memset (in_inc_dec, 0, nregs);
@@ -1259,10 +1234,10 @@ regclass (f, nregs, dump)
aggressive than the assumptions made elsewhere and is being
tried as an experiment. */
frequency = REG_FREQ_FROM_BB (bb);
- for (insn = bb->head; ; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
{
insn = scan_one_insn (insn, pass);
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
}
}
@@ -1396,16 +1371,10 @@ regclass (f, nregs, dump)
alternatives. */
static void
-record_reg_classes (n_alts, n_ops, ops, modes,
- constraints, insn, op_costs, reg_pref)
- int n_alts;
- int n_ops;
- rtx *ops;
- enum machine_mode *modes;
- const char **constraints;
- rtx insn;
- struct costs *op_costs;
- struct reg_pref *reg_pref;
+record_reg_classes (int n_alts, int n_ops, rtx *ops,
+ enum machine_mode *modes, const char **constraints,
+ rtx insn, struct costs *op_costs,
+ struct reg_pref *reg_pref)
{
int alt;
int i, j;
@@ -1442,7 +1411,7 @@ record_reg_classes (n_alts, n_ops, ops, modes,
if (*p == 0)
{
if (GET_CODE (op) == REG && REGNO (op) >= FIRST_PSEUDO_REGISTER)
- memset ((char *) &this_op_costs[i], 0, sizeof this_op_costs[i]);
+ memset (&this_op_costs[i], 0, sizeof this_op_costs[i]);
continue;
}
@@ -1556,154 +1525,161 @@ record_reg_classes (n_alts, n_ops, ops, modes,
any of the constraints. Collect the valid register classes
and see if this operand accepts memory. */
- while (*p && (c = *p++) != ',')
- switch (c)
- {
- case '*':
- /* Ignore the next letter for this pass. */
- p++;
- break;
-
- case '?':
- alt_cost += 2;
- case '!': case '#': case '&':
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- break;
+ while ((c = *p))
+ {
+ switch (c)
+ {
+ case ',':
+ break;
+ case '*':
+ /* Ignore the next letter for this pass. */
+ c = *++p;
+ break;
- case 'p':
- allows_addr = 1;
- win = address_operand (op, GET_MODE (op));
- /* We know this operand is an address, so we want it to be
- allocated to a register that can be the base of an
- address, ie BASE_REG_CLASS. */
- classes[i]
- = reg_class_subunion[(int) classes[i]]
- [(int) MODE_BASE_REG_CLASS (VOIDmode)];
- break;
+ case '?':
+ alt_cost += 2;
+ case '!': case '#': case '&':
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ break;
- case 'm': case 'o': case 'V':
- /* It doesn't seem worth distinguishing between offsettable
- and non-offsettable addresses here. */
- allows_mem[i] = 1;
- if (GET_CODE (op) == MEM)
- win = 1;
- break;
+ case 'p':
+ allows_addr = 1;
+ win = address_operand (op, GET_MODE (op));
+ /* We know this operand is an address, so we want it to be
+ allocated to a register that can be the base of an
+ address, ie BASE_REG_CLASS. */
+ classes[i]
+ = reg_class_subunion[(int) classes[i]]
+ [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+ break;
- case '<':
- if (GET_CODE (op) == MEM
- && (GET_CODE (XEXP (op, 0)) == PRE_DEC
- || GET_CODE (XEXP (op, 0)) == POST_DEC))
- win = 1;
- break;
+ case 'm': case 'o': case 'V':
+ /* It doesn't seem worth distinguishing between offsettable
+ and non-offsettable addresses here. */
+ allows_mem[i] = 1;
+ if (GET_CODE (op) == MEM)
+ win = 1;
+ break;
- case '>':
- if (GET_CODE (op) == MEM
- && (GET_CODE (XEXP (op, 0)) == PRE_INC
- || GET_CODE (XEXP (op, 0)) == POST_INC))
- win = 1;
- break;
+ case '<':
+ if (GET_CODE (op) == MEM
+ && (GET_CODE (XEXP (op, 0)) == PRE_DEC
+ || GET_CODE (XEXP (op, 0)) == POST_DEC))
+ win = 1;
+ break;
- case 'E':
- case 'F':
- if (GET_CODE (op) == CONST_DOUBLE
- || (GET_CODE (op) == CONST_VECTOR
- && (GET_MODE_CLASS (GET_MODE (op))
- == MODE_VECTOR_FLOAT)))
- win = 1;
- break;
+ case '>':
+ if (GET_CODE (op) == MEM
+ && (GET_CODE (XEXP (op, 0)) == PRE_INC
+ || GET_CODE (XEXP (op, 0)) == POST_INC))
+ win = 1;
+ break;
- case 'G':
- case 'H':
- if (GET_CODE (op) == CONST_DOUBLE
- && CONST_DOUBLE_OK_FOR_LETTER_P (op, c))
- win = 1;
- break;
+ case 'E':
+ case 'F':
+ if (GET_CODE (op) == CONST_DOUBLE
+ || (GET_CODE (op) == CONST_VECTOR
+ && (GET_MODE_CLASS (GET_MODE (op))
+ == MODE_VECTOR_FLOAT)))
+ win = 1;
+ break;
- case 's':
- if (GET_CODE (op) == CONST_INT
- || (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode))
+ case 'G':
+ case 'H':
+ if (GET_CODE (op) == CONST_DOUBLE
+ && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p))
+ win = 1;
break;
- case 'i':
- if (CONSTANT_P (op)
+
+ case 's':
+ if (GET_CODE (op) == CONST_INT
+ || (GET_CODE (op) == CONST_DOUBLE
+ && GET_MODE (op) == VOIDmode))
+ break;
+ case 'i':
+ if (CONSTANT_P (op)
#ifdef LEGITIMATE_PIC_OPERAND_P
- && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
+ && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
#endif
- )
- win = 1;
- break;
+ )
+ win = 1;
+ break;
- case 'n':
- if (GET_CODE (op) == CONST_INT
- || (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode))
- win = 1;
- break;
+ case 'n':
+ if (GET_CODE (op) == CONST_INT
+ || (GET_CODE (op) == CONST_DOUBLE
+ && GET_MODE (op) == VOIDmode))
+ win = 1;
+ break;
- case 'I':
- case 'J':
- case 'K':
- case 'L':
- case 'M':
- case 'N':
- case 'O':
- case 'P':
- if (GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (op), c))
- win = 1;
- break;
+ case 'I':
+ case 'J':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'N':
+ case 'O':
+ case 'P':
+ if (GET_CODE (op) == CONST_INT
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p))
+ win = 1;
+ break;
- case 'X':
- win = 1;
- break;
+ case 'X':
+ win = 1;
+ break;
- case 'g':
- if (GET_CODE (op) == MEM
- || (CONSTANT_P (op)
+ case 'g':
+ if (GET_CODE (op) == MEM
+ || (CONSTANT_P (op)
#ifdef LEGITIMATE_PIC_OPERAND_P
- && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
+ && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
#endif
- ))
- win = 1;
- allows_mem[i] = 1;
- case 'r':
- classes[i]
- = reg_class_subunion[(int) classes[i]][(int) GENERAL_REGS];
- break;
-
- default:
- if (REG_CLASS_FROM_LETTER (c) != NO_REGS)
+ ))
+ win = 1;
+ allows_mem[i] = 1;
+ case 'r':
classes[i]
- = reg_class_subunion[(int) classes[i]]
- [(int) REG_CLASS_FROM_LETTER (c)];
-#ifdef EXTRA_CONSTRAINT
- else if (EXTRA_CONSTRAINT (op, c))
- win = 1;
+ = reg_class_subunion[(int) classes[i]][(int) GENERAL_REGS];
+ break;
- if (EXTRA_MEMORY_CONSTRAINT (c))
- {
- /* Every MEM can be reloaded to fit. */
- allows_mem[i] = 1;
- if (GET_CODE (op) == MEM)
- win = 1;
- }
- if (EXTRA_ADDRESS_CONSTRAINT (c))
- {
- /* Every address can be reloaded to fit. */
- allows_addr = 1;
- if (address_operand (op, GET_MODE (op)))
- win = 1;
- /* We know this operand is an address, so we want it to be
- allocated to a register that can be the base of an
- address, ie BASE_REG_CLASS. */
+ default:
+ if (REG_CLASS_FROM_CONSTRAINT (c, p) != NO_REGS)
classes[i]
= reg_class_subunion[(int) classes[i]]
- [(int) MODE_BASE_REG_CLASS (VOIDmode)];
- }
+ [(int) REG_CLASS_FROM_CONSTRAINT (c, p)];
+#ifdef EXTRA_CONSTRAINT_STR
+ else if (EXTRA_CONSTRAINT_STR (op, c, p))
+ win = 1;
+
+ if (EXTRA_MEMORY_CONSTRAINT (c, p))
+ {
+ /* Every MEM can be reloaded to fit. */
+ allows_mem[i] = 1;
+ if (GET_CODE (op) == MEM)
+ win = 1;
+ }
+ if (EXTRA_ADDRESS_CONSTRAINT (c, p))
+ {
+ /* Every address can be reloaded to fit. */
+ allows_addr = 1;
+ if (address_operand (op, GET_MODE (op)))
+ win = 1;
+ /* We know this operand is an address, so we want it to
+ be allocated to a register that can be the base of an
+ address, ie BASE_REG_CLASS. */
+ classes[i]
+ = reg_class_subunion[(int) classes[i]]
+ [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+ }
#endif
+ break;
+ }
+ p += CONSTRAINT_LEN (c, p);
+ if (c == ',')
break;
- }
+ }
constraints[i] = p;
@@ -1822,7 +1798,7 @@ record_reg_classes (n_alts, n_ops, ops, modes,
we may want to adjust the cost of that register class to -1.
Avoid the adjustment if the source does not die to avoid stressing of
- register allocator by preferrencing two coliding registers into single
+ register allocator by preferrencing two colliding registers into single
class.
Also avoid the adjustment if a copy between registers of the class
@@ -1880,11 +1856,8 @@ record_reg_classes (n_alts, n_ops, ops, modes,
X must not be a pseudo. */
static int
-copy_cost (x, mode, class, to_p)
- rtx x;
- enum machine_mode mode ATTRIBUTE_UNUSED;
- enum reg_class class;
- int to_p ATTRIBUTE_UNUSED;
+copy_cost (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED,
+ enum reg_class class, int to_p ATTRIBUTE_UNUSED)
{
#ifdef HAVE_SECONDARY_RELOADS
enum reg_class secondary_class = NO_REGS;
@@ -1945,10 +1918,7 @@ copy_cost (x, mode, class, to_p)
can represent half-cost adjustments). */
static void
-record_address_regs (x, class, scale)
- rtx x;
- enum reg_class class;
- int scale;
+record_address_regs (rtx x, enum reg_class class, int scale)
{
enum rtx_code code = GET_CODE (x);
@@ -2129,9 +2099,7 @@ record_address_regs (x, class, scale)
to an object of MODE. */
static int
-auto_inc_dec_reg_p (reg, mode)
- rtx reg;
- enum machine_mode mode;
+auto_inc_dec_reg_p (rtx reg, enum machine_mode mode)
{
if (HAVE_POST_INCREMENT
&& memory_address_p (mode, gen_rtx_POST_INC (Pmode, reg)))
@@ -2165,10 +2133,7 @@ static unsigned int reg_n_max;
RENUMBER_P is nonzero, allocate the reg_renumber array also. */
void
-allocate_reg_info (num_regs, new_p, renumber_p)
- size_t num_regs;
- int new_p;
- int renumber_p;
+allocate_reg_info (size_t num_regs, int new_p, int renumber_p)
{
size_t size_info;
size_t size_renumber;
@@ -2179,42 +2144,42 @@ allocate_reg_info (num_regs, new_p, renumber_p)
{
size_t old_allocated = regno_allocated;
- regno_allocated = num_regs + (num_regs / 20); /* add some slop space */
+ regno_allocated = num_regs + (num_regs / 20); /* Add some slop space. */
size_renumber = regno_allocated * sizeof (short);
if (!reg_n_info)
{
VARRAY_REG_INIT (reg_n_info, regno_allocated, "reg_n_info");
- renumber = (short *) xmalloc (size_renumber);
- reg_pref_buffer = (struct reg_pref *) xmalloc (regno_allocated
- * sizeof (struct reg_pref));
+ renumber = xmalloc (size_renumber);
+ reg_pref_buffer = xmalloc (regno_allocated
+ * sizeof (struct reg_pref));
}
else
{
VARRAY_GROW (reg_n_info, regno_allocated);
- if (new_p) /* if we're zapping everything, no need to realloc */
+ if (new_p) /* If we're zapping everything, no need to realloc. */
{
free ((char *) renumber);
free ((char *) reg_pref);
- renumber = (short *) xmalloc (size_renumber);
- reg_pref_buffer = (struct reg_pref *) xmalloc (regno_allocated
- * sizeof (struct reg_pref));
+ renumber = xmalloc (size_renumber);
+ reg_pref_buffer = xmalloc (regno_allocated
+ * sizeof (struct reg_pref));
}
else
{
- renumber = (short *) xrealloc ((char *) renumber, size_renumber);
- reg_pref_buffer = (struct reg_pref *) xrealloc ((char *) reg_pref_buffer,
- regno_allocated
- * sizeof (struct reg_pref));
+ renumber = xrealloc (renumber, size_renumber);
+ reg_pref_buffer = xrealloc (reg_pref_buffer,
+ regno_allocated
+ * sizeof (struct reg_pref));
}
}
size_info = (regno_allocated - old_allocated) * sizeof (reg_info)
+ sizeof (struct reg_info_data) - sizeof (reg_info);
- reg_data = (struct reg_info_data *) xcalloc (size_info, 1);
+ reg_data = xcalloc (size_info, 1);
reg_data->min_index = old_allocated;
reg_data->max_index = regno_allocated - 1;
reg_data->next = reg_info_head;
@@ -2244,8 +2209,8 @@ allocate_reg_info (num_regs, new_p, renumber_p)
if (!reg_data->used_p) /* page just allocated with calloc */
reg_data->used_p = 1; /* no need to zero */
else
- memset ((char *) &reg_data->data[local_min], 0,
- sizeof (reg_info) * (max - min_index - local_min + 1));
+ memset (&reg_data->data[local_min], 0,
+ sizeof (reg_info) * (max - min_index - local_min + 1));
for (i = min_index+local_min; i <= max; i++)
{
@@ -2272,7 +2237,7 @@ allocate_reg_info (num_regs, new_p, renumber_p)
/* Free up the space allocated by allocate_reg_info. */
void
-free_reg_info ()
+free_reg_info (void)
{
if (reg_n_info)
{
@@ -2318,32 +2283,32 @@ int max_parallel;
static int max_set_parallel;
void
-reg_scan (f, nregs, repeat)
- rtx f;
- unsigned int nregs;
- int repeat ATTRIBUTE_UNUSED;
+reg_scan (rtx f, unsigned int nregs, int repeat ATTRIBUTE_UNUSED)
{
rtx insn;
+ timevar_push (TV_REG_SCAN);
+
allocate_reg_info (nregs, TRUE, FALSE);
max_parallel = 3;
max_set_parallel = 0;
for (insn = f; insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == INSN
- || GET_CODE (insn) == CALL_INSN
- || GET_CODE (insn) == JUMP_INSN)
+ if (INSN_P (insn))
{
- if (GET_CODE (PATTERN (insn)) == PARALLEL
- && XVECLEN (PATTERN (insn), 0) > max_parallel)
- max_parallel = XVECLEN (PATTERN (insn), 0);
- reg_scan_mark_refs (PATTERN (insn), insn, 0, 0);
+ rtx pat = PATTERN (insn);
+ if (GET_CODE (pat) == PARALLEL
+ && XVECLEN (pat, 0) > max_parallel)
+ max_parallel = XVECLEN (pat, 0);
+ reg_scan_mark_refs (pat, insn, 0, 0);
if (REG_NOTES (insn))
reg_scan_mark_refs (REG_NOTES (insn), insn, 1, 0);
}
max_parallel += max_set_parallel;
+
+ timevar_pop (TV_REG_SCAN);
}
/* Update 'regscan' information by looking at the insns
@@ -2352,24 +2317,20 @@ reg_scan (f, nregs, repeat)
such a REG. We only update information for those. */
void
-reg_scan_update (first, last, old_max_regno)
- rtx first;
- rtx last;
- unsigned int old_max_regno;
+reg_scan_update (rtx first, rtx last, unsigned int old_max_regno)
{
rtx insn;
allocate_reg_info (max_reg_num (), FALSE, FALSE);
for (insn = first; insn != last; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == INSN
- || GET_CODE (insn) == CALL_INSN
- || GET_CODE (insn) == JUMP_INSN)
+ if (INSN_P (insn))
{
- if (GET_CODE (PATTERN (insn)) == PARALLEL
- && XVECLEN (PATTERN (insn), 0) > max_parallel)
- max_parallel = XVECLEN (PATTERN (insn), 0);
- reg_scan_mark_refs (PATTERN (insn), insn, 0, old_max_regno);
+ rtx pat = PATTERN (insn);
+ if (GET_CODE (pat) == PARALLEL
+ && XVECLEN (pat, 0) > max_parallel)
+ max_parallel = XVECLEN (pat, 0);
+ reg_scan_mark_refs (pat, insn, 0, old_max_regno);
if (REG_NOTES (insn))
reg_scan_mark_refs (REG_NOTES (insn), insn, 1, old_max_regno);
@@ -2382,11 +2343,7 @@ reg_scan_update (first, last, old_max_regno)
greater than or equal to MIN_REGNO. */
static void
-reg_scan_mark_refs (x, insn, note_flag, min_regno)
- rtx x;
- rtx insn;
- int note_flag;
- unsigned int min_regno;
+reg_scan_mark_refs (rtx x, rtx insn, int note_flag, unsigned int min_regno)
{
enum rtx_code code;
rtx dest;
@@ -2449,6 +2406,8 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
REG_N_SETS (REGNO (reg))++;
REG_N_REFS (REGNO (reg))++;
}
+ else if (GET_CODE (reg) == MEM)
+ reg_scan_mark_refs (XEXP (reg, 0), insn, note_flag, min_regno);
}
break;
@@ -2489,7 +2448,7 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
&& REGNO (SET_DEST (x)) >= min_regno
/* If the destination pseudo is set more than once, then other
sets might not be to a pointer value (consider access to a
- union in two threads of control in the presense of global
+ union in two threads of control in the presence of global
optimizations). So only set REG_POINTER on the destination
pseudo if this is the only set of that pseudo. */
&& REG_N_SETS (REGNO (SET_DEST (x))) == 1
@@ -2521,7 +2480,7 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
REG_POINTER (SET_DEST (x)) = 1;
/* If this is setting a register from a register or from a simple
- conversion of a register, propagate REG_DECL. */
+ conversion of a register, propagate REG_EXPR. */
if (GET_CODE (dest) == REG)
{
rtx src = SET_SRC (x);
@@ -2532,10 +2491,10 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
|| (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)))
src = XEXP (src, 0);
- if (GET_CODE (src) == REG && REGNO_DECL (REGNO (src)) == 0)
- REGNO_DECL (REGNO (src)) = REGNO_DECL (REGNO (dest));
- else if (GET_CODE (src) == REG && REGNO_DECL (REGNO (dest)) == 0)
- REGNO_DECL (REGNO (dest)) = REGNO_DECL (REGNO (src));
+ if (!REG_ATTRS (dest) && REG_P (src))
+ REG_ATTRS (dest) = REG_ATTRS (src);
+ if (!REG_ATTRS (dest) && GET_CODE (src) == MEM)
+ set_reg_attrs_from_mem (dest, src);
}
/* ... fall through ... */
@@ -2563,9 +2522,7 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
is also in C2. */
int
-reg_class_subset_p (c1, c2)
- enum reg_class c1;
- enum reg_class c2;
+reg_class_subset_p (enum reg_class c1, enum reg_class c2)
{
if (c1 == c2) return 1;
@@ -2581,14 +2538,9 @@ reg_class_subset_p (c1, c2)
/* Return nonzero if there is a register that is in both C1 and C2. */
int
-reg_classes_intersect_p (c1, c2)
- enum reg_class c1;
- enum reg_class c2;
+reg_classes_intersect_p (enum reg_class c1, enum reg_class c2)
{
-#ifdef HARD_REG_SET
- register
-#endif
- HARD_REG_SET c;
+ HARD_REG_SET c;
if (c1 == c2) return 1;
@@ -2608,7 +2560,7 @@ reg_classes_intersect_p (c1, c2)
/* Release any memory allocated by register sets. */
void
-regset_release_memory ()
+regset_release_memory (void)
{
bitmap_release_memory ();
}
@@ -2618,10 +2570,8 @@ regset_release_memory ()
their mode from FROM to any mode in which REGNO was encountered. */
void
-cannot_change_mode_set_regs (used, from, regno)
- HARD_REG_SET *used;
- enum machine_mode from;
- unsigned int regno;
+cannot_change_mode_set_regs (HARD_REG_SET *used, enum machine_mode from,
+ unsigned int regno)
{
enum machine_mode to;
int n, i;
@@ -2642,10 +2592,8 @@ cannot_change_mode_set_regs (used, from, regno)
mode. */
bool
-invalid_mode_change_p (regno, class, from_mode)
- unsigned int regno;
- enum reg_class class;
- enum machine_mode from_mode;
+invalid_mode_change_p (unsigned int regno, enum reg_class class,
+ enum machine_mode from_mode)
{
enum machine_mode to_mode;
int n;
diff --git a/contrib/gcc/regmove.c b/contrib/gcc/regmove.c
index cb5e547cecd5..8dcd05486f23 100644
--- a/contrib/gcc/regmove.c
+++ b/contrib/gcc/regmove.c
@@ -1,6 +1,6 @@
/* Move registers around to reduce number of move instructions needed.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -27,6 +27,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h" /* stdio.h must precede rtl.h for FFS. */
#include "tm_p.h"
#include "insn-config.h"
@@ -51,11 +53,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define STACK_GROWS_DOWNWARD 0
#endif
-static int perhaps_ends_bb_p PARAMS ((rtx));
-static int optimize_reg_copy_1 PARAMS ((rtx, rtx, rtx));
-static void optimize_reg_copy_2 PARAMS ((rtx, rtx, rtx));
-static void optimize_reg_copy_3 PARAMS ((rtx, rtx, rtx));
-static void copy_src_to_dest PARAMS ((rtx, rtx, rtx, int));
+static int perhaps_ends_bb_p (rtx);
+static int optimize_reg_copy_1 (rtx, rtx, rtx);
+static void optimize_reg_copy_2 (rtx, rtx, rtx);
+static void optimize_reg_copy_3 (rtx, rtx, rtx);
+static void copy_src_to_dest (rtx, rtx, rtx, int);
static int *regmove_bb_head;
struct match {
@@ -65,26 +67,24 @@ struct match {
int early_clobber[MAX_RECOG_OPERANDS];
};
-static rtx discover_flags_reg PARAMS ((void));
-static void mark_flags_life_zones PARAMS ((rtx));
-static void flags_set_1 PARAMS ((rtx, rtx, void *));
-
-static int try_auto_increment PARAMS ((rtx, rtx, rtx, rtx, HOST_WIDE_INT, int));
-static int find_matches PARAMS ((rtx, struct match *));
-static void replace_in_call_usage PARAMS ((rtx *, unsigned int, rtx, rtx));
-static int fixup_match_1 PARAMS ((rtx, rtx, rtx, rtx, rtx, int, int, int, FILE *))
-;
-static int reg_is_remote_constant_p PARAMS ((rtx, rtx, rtx));
-static int stable_and_no_regs_but_for_p PARAMS ((rtx, rtx, rtx));
-static int regclass_compatible_p PARAMS ((int, int));
-static int replacement_quality PARAMS ((rtx));
-static int fixup_match_2 PARAMS ((rtx, rtx, rtx, rtx, FILE *));
+static rtx discover_flags_reg (void);
+static void mark_flags_life_zones (rtx);
+static void flags_set_1 (rtx, rtx, void *);
+
+static int try_auto_increment (rtx, rtx, rtx, rtx, HOST_WIDE_INT, int);
+static int find_matches (rtx, struct match *);
+static void replace_in_call_usage (rtx *, unsigned int, rtx, rtx);
+static int fixup_match_1 (rtx, rtx, rtx, rtx, rtx, int, int, int, FILE *);
+static int reg_is_remote_constant_p (rtx, rtx, rtx);
+static int stable_and_no_regs_but_for_p (rtx, rtx, rtx);
+static int regclass_compatible_p (int, int);
+static int replacement_quality (rtx);
+static int fixup_match_2 (rtx, rtx, rtx, rtx, FILE *);
/* Return nonzero if registers with CLASS1 and CLASS2 can be merged without
causing too much register allocation problems. */
static int
-regclass_compatible_p (class0, class1)
- int class0, class1;
+regclass_compatible_p (int class0, int class1)
{
return (class0 == class1
|| (reg_class_subset_p (class0, class1)
@@ -98,10 +98,8 @@ regclass_compatible_p (class0, class1)
Iff INC_INSN_SET is nonzero, inc_insn has a destination different from src.
Return nonzero for success. */
static int
-try_auto_increment (insn, inc_insn, inc_insn_set, reg, increment, pre)
- rtx reg, insn, inc_insn ,inc_insn_set;
- HOST_WIDE_INT increment;
- int pre;
+try_auto_increment (rtx insn, rtx inc_insn, rtx inc_insn_set, rtx reg,
+ HOST_WIDE_INT increment, int pre)
{
enum rtx_code inc_code;
@@ -165,7 +163,7 @@ try_auto_increment (insn, inc_insn, inc_insn_set, reg, increment, pre)
if no flags were found. Return pc_rtx if we got confused. */
static rtx
-discover_flags_reg ()
+discover_flags_reg (void)
{
rtx tmp;
tmp = gen_rtx_REG (word_mode, 10000);
@@ -218,8 +216,7 @@ static rtx flags_set_1_rtx;
static int flags_set_1_set;
static void
-mark_flags_life_zones (flags)
- rtx flags;
+mark_flags_life_zones (rtx flags)
{
int flags_regno;
int flags_nregs;
@@ -259,8 +256,8 @@ mark_flags_life_zones (flags)
rtx insn, end;
int live;
- insn = block->head;
- end = block->end;
+ insn = BB_HEAD (block);
+ end = BB_END (block);
/* Look out for the (unlikely) case of flags being live across
basic block boundaries. */
@@ -317,9 +314,7 @@ mark_flags_life_zones (flags)
/* A subroutine of mark_flags_life_zones, called through note_stores. */
static void
-flags_set_1 (x, pat, data)
- rtx x, pat;
- void *data ATTRIBUTE_UNUSED;
+flags_set_1 (rtx x, rtx pat, void *data ATTRIBUTE_UNUSED)
{
if (GET_CODE (pat) == SET
&& reg_overlap_mentioned_p (x, flags_set_1_rtx))
@@ -334,8 +329,7 @@ static int *regno_src_regno;
a candidate for tying to a hard register, since the output might in
turn be a candidate to be tied to a different hard register. */
static int
-replacement_quality (reg)
- rtx reg;
+replacement_quality (rtx reg)
{
int src_regno;
@@ -366,8 +360,7 @@ replacement_quality (reg)
/* Return 1 if INSN might end a basic block. */
-static int perhaps_ends_bb_p (insn)
- rtx insn;
+static int perhaps_ends_bb_p (rtx insn)
{
switch (GET_CODE (insn))
{
@@ -382,7 +375,7 @@ static int perhaps_ends_bb_p (insn)
very conservative. */
if (nonlocal_goto_handler_labels)
return 1;
- /* FALLTHRU */
+ /* Fall through. */
default:
return can_throw_internal (insn);
}
@@ -400,10 +393,7 @@ static int perhaps_ends_bb_p (insn)
register-register copy. */
static int
-optimize_reg_copy_1 (insn, dest, src)
- rtx insn;
- rtx dest;
- rtx src;
+optimize_reg_copy_1 (rtx insn, rtx dest, rtx src)
{
rtx p, q;
rtx note;
@@ -599,10 +589,7 @@ optimize_reg_copy_1 (insn, dest, src)
this for hard registers since the substitutions we may make might fail. */
static void
-optimize_reg_copy_2 (insn, dest, src)
- rtx insn;
- rtx dest;
- rtx src;
+optimize_reg_copy_2 (rtx insn, rtx dest, rtx src)
{
rtx p, q;
rtx set;
@@ -655,15 +642,12 @@ optimize_reg_copy_2 (insn, dest, src)
}
/* INSN is a ZERO_EXTEND or SIGN_EXTEND of SRC to DEST.
Look if SRC dies there, and if it is only set once, by loading
- it from memory. If so, try to encorporate the zero/sign extension
+ it from memory. If so, try to incorporate the zero/sign extension
into the memory read, change SRC to the mode of DEST, and alter
the remaining accesses to use the appropriate SUBREG. This allows
SRC and DEST to be tied later. */
static void
-optimize_reg_copy_3 (insn, dest, src)
- rtx insn;
- rtx dest;
- rtx src;
+optimize_reg_copy_3 (rtx insn, rtx dest, rtx src)
{
rtx src_reg = XEXP (src, 0);
int src_no = REGNO (src_reg);
@@ -694,7 +678,7 @@ optimize_reg_copy_3 (insn, dest, src)
|| SET_DEST (set) != src_reg)
return;
- /* Be conserative: although this optimization is also valid for
+ /* Be conservative: although this optimization is also valid for
volatile memory references, that could cause trouble in later passes. */
if (MEM_VOLATILE_P (SET_SRC (set)))
return;
@@ -722,7 +706,7 @@ optimize_reg_copy_3 (insn, dest, src)
if (! INSN_P (p))
continue;
- /* Make a tenative change. */
+ /* Make a tentative change. */
validate_replace_rtx_group (src_reg, subreg, p);
}
@@ -748,11 +732,7 @@ optimize_reg_copy_3 (insn, dest, src)
instead moving the value to dest directly before the operation. */
static void
-copy_src_to_dest (insn, src, dest, old_max_uid)
- rtx insn;
- rtx src;
- rtx dest;
- int old_max_uid;
+copy_src_to_dest (rtx insn, rtx src, rtx dest, int old_max_uid)
{
rtx seq;
rtx link;
@@ -830,7 +810,7 @@ copy_src_to_dest (insn, src, dest, old_max_uid)
bb = regmove_bb_head[insn_uid];
if (bb >= 0)
{
- BLOCK_HEAD (bb) = move_insn;
+ BB_HEAD (BASIC_BLOCK (bb)) = move_insn;
regmove_bb_head[insn_uid] = -1;
}
}
@@ -869,10 +849,7 @@ copy_src_to_dest (insn, src, dest, old_max_uid)
the first insn in the function. */
static int
-reg_is_remote_constant_p (reg, insn, first)
- rtx reg;
- rtx insn;
- rtx first;
+reg_is_remote_constant_p (rtx reg, rtx insn, rtx first)
{
rtx p;
@@ -933,13 +910,11 @@ reg_is_remote_constant_p (reg, insn, first)
(set (reg100) (plus reg100 offset2-offset1)) */
/* ??? What does this comment mean? */
-/* cse disrupts preincrement / postdecrement squences when it finds a
+/* cse disrupts preincrement / postdecrement sequences when it finds a
hard register as ultimate source, like the frame pointer. */
static int
-fixup_match_2 (insn, dst, src, offset, regmove_dump_file)
- rtx insn, dst, src, offset;
- FILE *regmove_dump_file;
+fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset, FILE *regmove_dump_file)
{
rtx p, dst_death = 0;
int length, num_calls = 0;
@@ -1061,10 +1036,7 @@ fixup_match_2 (insn, dst, src, offset, regmove_dump_file)
(or 0 if none should be output). */
void
-regmove_optimize (f, nregs, regmove_dump_file)
- rtx f;
- int nregs;
- FILE *regmove_dump_file;
+regmove_optimize (rtx f, int nregs, FILE *regmove_dump_file)
{
int old_max_uid = get_max_uid ();
rtx insn;
@@ -1080,16 +1052,16 @@ regmove_optimize (f, nregs, regmove_dump_file)
return;
/* Find out where a potential flags register is live, and so that we
- can supress some optimizations in those zones. */
+ can suppress some optimizations in those zones. */
mark_flags_life_zones (discover_flags_reg ());
- regno_src_regno = (int *) xmalloc (sizeof *regno_src_regno * nregs);
+ regno_src_regno = xmalloc (sizeof *regno_src_regno * nregs);
for (i = nregs; --i >= 0; ) regno_src_regno[i] = -1;
- regmove_bb_head = (int *) xmalloc (sizeof (int) * (old_max_uid + 1));
+ regmove_bb_head = xmalloc (sizeof (int) * (old_max_uid + 1));
for (i = old_max_uid; i >= 0; i--) regmove_bb_head[i] = -1;
FOR_EACH_BB (bb)
- regmove_bb_head[INSN_UID (bb->head)] = bb->index;
+ regmove_bb_head[INSN_UID (BB_HEAD (bb))] = bb->index;
/* A forward/backward pass. Replace output operands with input operands. */
@@ -1287,7 +1259,8 @@ regmove_optimize (f, nregs, regmove_dump_file)
if (GET_CODE (dst) != REG
|| REGNO (dst) < FIRST_PSEUDO_REGISTER
|| REG_LIVE_LENGTH (REGNO (dst)) < 0
- || RTX_UNCHANGING_P (dst))
+ || RTX_UNCHANGING_P (dst)
+ || GET_MODE (src) != GET_MODE (dst))
continue;
/* If the operands already match, then there is nothing to do. */
@@ -1347,7 +1320,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
it produces worse code, as it eliminates no copy
instructions and the copy emitted will be produced by
reload anyway. On patterns with multiple alternatives,
- there may be better sollution availble.
+ there may be better solution available.
In particular this change produced slower code for numeric
i387 programs. */
@@ -1507,7 +1480,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
}
/* If we weren't able to replace any of the alternatives, try an
- alternative appoach of copying the source to the destination. */
+ alternative approach of copying the source to the destination. */
if (!success && copy_src != NULL_RTX)
copy_src_to_dest (insn, copy_src, copy_dst, old_max_uid);
@@ -1518,13 +1491,13 @@ regmove_optimize (f, nregs, regmove_dump_file)
ends. Fix that here. */
FOR_EACH_BB (bb)
{
- rtx end = bb->end;
+ rtx end = BB_END (bb);
rtx new = end;
rtx next = NEXT_INSN (new);
while (next != 0 && INSN_UID (next) >= old_max_uid
- && (bb->next_bb == EXIT_BLOCK_PTR || bb->next_bb->head != next))
+ && (bb->next_bb == EXIT_BLOCK_PTR || BB_HEAD (bb->next_bb) != next))
new = next, next = NEXT_INSN (new);
- bb->end = new;
+ BB_END (bb) = new;
}
done:
@@ -1540,9 +1513,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
Initialize the info in MATCHP based on the constraints. */
static int
-find_matches (insn, matchp)
- rtx insn;
- struct match *matchp;
+find_matches (rtx insn, struct match *matchp)
{
int likely_spilled[MAX_RECOG_OPERANDS];
int op_no;
@@ -1578,47 +1549,50 @@ find_matches (insn, matchp)
if (*p == ',')
i++;
- while ((c = *p++) != '\0' && c != ',')
- switch (c)
- {
- case '=':
- break;
- case '+':
- break;
- case '&':
- matchp->early_clobber[op_no] = 1;
- break;
- case '%':
- matchp->commutative[op_no] = op_no + 1;
- matchp->commutative[op_no + 1] = op_no;
- break;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
+ while ((c = *p) != '\0' && c != ',')
+ {
+ switch (c)
{
- char *end;
- unsigned long match_ul = strtoul (p - 1, &end, 10);
- int match = match_ul;
+ case '=':
+ break;
+ case '+':
+ break;
+ case '&':
+ matchp->early_clobber[op_no] = 1;
+ break;
+ case '%':
+ matchp->commutative[op_no] = op_no + 1;
+ matchp->commutative[op_no + 1] = op_no;
+ break;
- p = end;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ {
+ char *end;
+ unsigned long match_ul = strtoul (p, &end, 10);
+ int match = match_ul;
- if (match < op_no && likely_spilled[match])
- break;
- matchp->with[op_no] = match;
- any_matches = 1;
- if (matchp->commutative[op_no] >= 0)
- matchp->with[matchp->commutative[op_no]] = match;
- }
- break;
+ p = end;
+
+ if (match < op_no && likely_spilled[match])
+ continue;
+ matchp->with[op_no] = match;
+ any_matches = 1;
+ if (matchp->commutative[op_no] >= 0)
+ matchp->with[matchp->commutative[op_no]] = match;
+ }
+ continue;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h':
case 'j': case 'k': case 'l': case 'p': case 'q': case 't': case 'u':
case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
case 'C': case 'D': case 'W': case 'Y': case 'Z':
- if (CLASS_LIKELY_SPILLED_P (REG_CLASS_FROM_LETTER ((unsigned char) c)))
+ if (CLASS_LIKELY_SPILLED_P (REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p) ))
likely_spilled[op_no] = 1;
break;
}
+ p += CONSTRAINT_LEN (c, p);
+ }
}
return any_matches;
}
@@ -1627,11 +1601,7 @@ find_matches (insn, matchp)
assumed to be in INSN. */
static void
-replace_in_call_usage (loc, dst_reg, src, insn)
- rtx *loc;
- unsigned int dst_reg;
- rtx src;
- rtx insn;
+replace_in_call_usage (rtx *loc, unsigned int dst_reg, rtx src, rtx insn)
{
rtx x = *loc;
enum rtx_code code;
@@ -1670,18 +1640,16 @@ replace_in_call_usage (loc, dst_reg, src, insn)
Return nonzero for success. */
static int
-fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
- match_number, regmove_dump_file)
- rtx insn, set, src, src_subreg, dst;
- int backward, operand_number, match_number;
- FILE *regmove_dump_file;
+fixup_match_1 (rtx insn, rtx set, rtx src, rtx src_subreg, rtx dst,
+ int backward, int operand_number, int match_number,
+ FILE *regmove_dump_file)
{
rtx p;
rtx post_inc = 0, post_inc_set = 0, search_end = 0;
int success = 0;
int num_calls = 0, s_num_calls = 0;
enum rtx_code code = NOTE;
- HOST_WIDE_INT insn_const = 0, newconst;
+ HOST_WIDE_INT insn_const = 0, newconst = 0;
rtx overlap = 0; /* need to move insn ? */
rtx src_note = find_reg_note (insn, REG_DEAD, src), dst_note = NULL_RTX;
int length, s_length;
@@ -2064,7 +2032,7 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
}
-/* return nonzero if X is stable and mentions no regsiters but for
+/* Return nonzero if X is stable and mentions no registers but for
mentioning SRC or mentioning / changing DST . If in doubt, presume
it is unstable.
The rationale is that we want to check if we can move an insn easily
@@ -2073,8 +2041,7 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number,
leave the burden to update REG_DEAD / REG_UNUSED notes, so we don't
want any registers but SRC and DST. */
static int
-stable_and_no_regs_but_for_p (x, src, dst)
- rtx x, src, dst;
+stable_and_no_regs_but_for_p (rtx x, rtx src, rtx dst)
{
RTX_CODE code = GET_CODE (x);
switch (GET_RTX_CLASS (code))
@@ -2097,7 +2064,7 @@ stable_and_no_regs_but_for_p (x, src, dst)
if (code == MEM
&& ! stable_and_no_regs_but_for_p (XEXP (x, 0), src, dst))
return 0;
- /* fall through */
+ /* Fall through. */
default:
return ! rtx_unstable_p (x);
}
@@ -2134,21 +2101,21 @@ struct csa_memlist
struct csa_memlist *next;
};
-static int stack_memref_p PARAMS ((rtx));
-static rtx single_set_for_csa PARAMS ((rtx));
-static void free_csa_memlist PARAMS ((struct csa_memlist *));
-static struct csa_memlist *record_one_stack_memref
- PARAMS ((rtx, rtx *, struct csa_memlist *));
-static int try_apply_stack_adjustment
- PARAMS ((rtx, struct csa_memlist *, HOST_WIDE_INT, HOST_WIDE_INT));
-static void combine_stack_adjustments_for_block PARAMS ((basic_block));
-static int record_stack_memrefs PARAMS ((rtx *, void *));
+static int stack_memref_p (rtx);
+static rtx single_set_for_csa (rtx);
+static void free_csa_memlist (struct csa_memlist *);
+static struct csa_memlist *record_one_stack_memref (rtx, rtx *,
+ struct csa_memlist *);
+static int try_apply_stack_adjustment (rtx, struct csa_memlist *,
+ HOST_WIDE_INT, HOST_WIDE_INT);
+static void combine_stack_adjustments_for_block (basic_block);
+static int record_stack_memrefs (rtx *, void *);
/* Main entry point for stack adjustment combination. */
void
-combine_stack_adjustments ()
+combine_stack_adjustments (void)
{
basic_block bb;
@@ -2159,8 +2126,7 @@ combine_stack_adjustments ()
/* Recognize a MEM of the form (sp) or (plus sp const). */
static int
-stack_memref_p (x)
- rtx x;
+stack_memref_p (rtx x)
{
if (GET_CODE (x) != MEM)
return 0;
@@ -2180,8 +2146,7 @@ stack_memref_p (x)
tying fp and sp adjustments. */
static rtx
-single_set_for_csa (insn)
- rtx insn;
+single_set_for_csa (rtx insn)
{
int i;
rtx tmp = single_set (insn);
@@ -2215,8 +2180,7 @@ single_set_for_csa (insn)
/* Free the list of csa_memlist nodes. */
static void
-free_csa_memlist (memlist)
- struct csa_memlist *memlist;
+free_csa_memlist (struct csa_memlist *memlist)
{
struct csa_memlist *next;
for (; memlist ; memlist = next)
@@ -2230,13 +2194,11 @@ free_csa_memlist (memlist)
It is already known that the memory is stack_memref_p. */
static struct csa_memlist *
-record_one_stack_memref (insn, mem, next_memlist)
- rtx insn, *mem;
- struct csa_memlist *next_memlist;
+record_one_stack_memref (rtx insn, rtx *mem, struct csa_memlist *next_memlist)
{
struct csa_memlist *ml;
- ml = (struct csa_memlist *) xmalloc (sizeof (*ml));
+ ml = xmalloc (sizeof (*ml));
if (XEXP (*mem, 0) == stack_pointer_rtx)
ml->sp_offset = 0;
@@ -2254,10 +2216,8 @@ record_one_stack_memref (insn, mem, next_memlist)
as each of the memories in MEMLIST. Return true on success. */
static int
-try_apply_stack_adjustment (insn, memlist, new_adjust, delta)
- rtx insn;
- struct csa_memlist *memlist;
- HOST_WIDE_INT new_adjust, delta;
+try_apply_stack_adjustment (rtx insn, struct csa_memlist *memlist, HOST_WIDE_INT new_adjust,
+ HOST_WIDE_INT delta)
{
struct csa_memlist *ml;
rtx set;
@@ -2293,9 +2253,7 @@ struct record_stack_memrefs_data
};
static int
-record_stack_memrefs (xp, data)
- rtx *xp;
- void *data;
+record_stack_memrefs (rtx *xp, void *data)
{
rtx x = *xp;
struct record_stack_memrefs_data *d =
@@ -2317,14 +2275,14 @@ record_stack_memrefs (xp, data)
return 1;
case REG:
/* ??? We want be able to handle non-memory stack pointer
- references later. For now just discard all insns refering to
+ references later. For now just discard all insns referring to
stack pointer outside mem expressions. We would probably
want to teach validate_replace to simplify expressions first.
We can't just compare with STACK_POINTER_RTX because the
reference to the stack pointer might be in some other mode.
- In particular, an explict clobber in an asm statement will
- result in a QImode clober. */
+ In particular, an explicit clobber in an asm statement will
+ result in a QImode clobber. */
if (REGNO (x) == STACK_POINTER_REGNUM)
return 1;
break;
@@ -2337,8 +2295,7 @@ record_stack_memrefs (xp, data)
/* Subroutine of combine_stack_adjustments, called for each basic block. */
static void
-combine_stack_adjustments_for_block (bb)
- basic_block bb;
+combine_stack_adjustments_for_block (basic_block bb)
{
HOST_WIDE_INT last_sp_adjust = 0;
rtx last_sp_set = NULL_RTX;
@@ -2347,9 +2304,9 @@ combine_stack_adjustments_for_block (bb)
struct record_stack_memrefs_data data;
bool end_of_block = false;
- for (insn = bb->head; !end_of_block ; insn = next)
+ for (insn = BB_HEAD (bb); !end_of_block ; insn = next)
{
- end_of_block = insn == bb->end;
+ end_of_block = insn == BB_END (bb);
next = NEXT_INSN (insn);
if (! INSN_P (insn))
@@ -2382,7 +2339,7 @@ combine_stack_adjustments_for_block (bb)
adjustment is now too large for a constant addition,
we cannot merge the two stack adjustments.
- Also we need to be carefull to not move stack pointer
+ Also we need to be careful to not move stack pointer
such that we create stack accesses outside the allocated
area. We can combine an allocation into the first insn,
or a deallocation into the second insn. We can not
diff --git a/contrib/gcc/regrename.c b/contrib/gcc/regrename.c
index 9b7dfd6d3c5a..e725ee932daf 100644
--- a/contrib/gcc/regrename.c
+++ b/contrib/gcc/regrename.c
@@ -1,5 +1,5 @@
/* Register renaming for the GNU compiler.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "insn-config.h"
@@ -49,7 +51,7 @@ struct du_chain
rtx insn;
rtx *loc;
- enum reg_class class;
+ ENUM_BITFIELD(reg_class) class : 16;
unsigned int need_caller_save_reg:1;
unsigned int earlyclobber:1;
};
@@ -76,28 +78,25 @@ static const char * const scan_actions_name[] =
static struct obstack rename_obstack;
-static void do_replace PARAMS ((struct du_chain *, int));
-static void scan_rtx_reg PARAMS ((rtx, rtx *, enum reg_class,
- enum scan_actions, enum op_type, int));
-static void scan_rtx_address PARAMS ((rtx, rtx *, enum reg_class,
- enum scan_actions, enum machine_mode));
-static void scan_rtx PARAMS ((rtx, rtx *, enum reg_class,
- enum scan_actions, enum op_type, int));
-static struct du_chain *build_def_use PARAMS ((basic_block));
-static void dump_def_use_chain PARAMS ((struct du_chain *));
-static void note_sets PARAMS ((rtx, rtx, void *));
-static void clear_dead_regs PARAMS ((HARD_REG_SET *, enum machine_mode, rtx));
-static void merge_overlapping_regs PARAMS ((basic_block, HARD_REG_SET *,
- struct du_chain *));
+static void do_replace (struct du_chain *, int);
+static void scan_rtx_reg (rtx, rtx *, enum reg_class,
+ enum scan_actions, enum op_type, int);
+static void scan_rtx_address (rtx, rtx *, enum reg_class,
+ enum scan_actions, enum machine_mode);
+static void scan_rtx (rtx, rtx *, enum reg_class, enum scan_actions,
+ enum op_type, int);
+static struct du_chain *build_def_use (basic_block);
+static void dump_def_use_chain (struct du_chain *);
+static void note_sets (rtx, rtx, void *);
+static void clear_dead_regs (HARD_REG_SET *, enum machine_mode, rtx);
+static void merge_overlapping_regs (basic_block, HARD_REG_SET *,
+ struct du_chain *);
/* Called through note_stores from update_life. Find sets of registers, and
record them in *DATA (which is actually a HARD_REG_SET *). */
static void
-note_sets (x, set, data)
- rtx x;
- rtx set ATTRIBUTE_UNUSED;
- void *data;
+note_sets (rtx x, rtx set ATTRIBUTE_UNUSED, void *data)
{
HARD_REG_SET *pset = (HARD_REG_SET *) data;
unsigned int regno;
@@ -119,10 +118,7 @@ note_sets (x, set, data)
in the list NOTES. */
static void
-clear_dead_regs (pset, kind, notes)
- HARD_REG_SET *pset;
- enum machine_mode kind;
- rtx notes;
+clear_dead_regs (HARD_REG_SET *pset, enum machine_mode kind, rtx notes)
{
rtx note;
for (note = notes; note; note = XEXP (note, 1))
@@ -145,17 +141,15 @@ clear_dead_regs (pset, kind, notes)
its lifetime and set the corresponding bits in *PSET. */
static void
-merge_overlapping_regs (b, pset, chain)
- basic_block b;
- HARD_REG_SET *pset;
- struct du_chain *chain;
+merge_overlapping_regs (basic_block b, HARD_REG_SET *pset,
+ struct du_chain *chain)
{
struct du_chain *t = chain;
rtx insn;
HARD_REG_SET live;
REG_SET_TO_HARD_REG_SET (live, b->global_live_at_start);
- insn = b->head;
+ insn = BB_HEAD (b);
while (t)
{
/* Search forward until the next reference to the register to be
@@ -190,7 +184,7 @@ merge_overlapping_regs (b, pset, chain)
/* Perform register renaming on the current function. */
void
-regrename_optimize ()
+regrename_optimize (void)
{
int tick[FIRST_PSEUDO_REGISTER];
int this_tick = 0;
@@ -200,7 +194,7 @@ regrename_optimize ()
memset (tick, 0, sizeof tick);
gcc_obstack_init (&rename_obstack);
- first_obj = (char *) obstack_alloc (&rename_obstack, 0);
+ first_obj = obstack_alloc (&rename_obstack, 0);
FOR_EACH_BB (bb)
{
@@ -236,7 +230,7 @@ regrename_optimize ()
CLEAR_HARD_REG_SET (regs_seen);
while (all_chains)
{
- int new_reg, best_new_reg = -1;
+ int new_reg, best_new_reg;
int n_uses;
struct du_chain *this = all_chains;
struct du_chain *tmp, *last;
@@ -246,6 +240,8 @@ regrename_optimize ()
all_chains = this->next_chain;
+ best_new_reg = reg;
+
#if 0 /* This just disables optimization opportunities. */
/* Only rename once we've seen the reg more than once. */
if (! TEST_HARD_REG_BIT (regs_seen, reg))
@@ -326,8 +322,7 @@ regrename_optimize ()
break;
if (! tmp)
{
- if (best_new_reg == -1
- || tick[best_new_reg] > tick[new_reg])
+ if (tick[best_new_reg] > tick[new_reg])
best_new_reg = new_reg;
}
}
@@ -340,15 +335,16 @@ regrename_optimize ()
fprintf (rtl_dump_file, " crosses a call");
}
- if (best_new_reg == -1)
+ if (best_new_reg == reg)
{
+ tick[reg] = ++this_tick;
if (rtl_dump_file)
- fprintf (rtl_dump_file, "; no available registers\n");
+ fprintf (rtl_dump_file, "; no available better choice\n");
continue;
}
do_replace (this, best_new_reg);
- tick[best_new_reg] = this_tick++;
+ tick[best_new_reg] = ++this_tick;
if (rtl_dump_file)
fprintf (rtl_dump_file, ", renamed as %s\n", reg_names[best_new_reg]);
@@ -368,16 +364,17 @@ regrename_optimize ()
}
static void
-do_replace (chain, reg)
- struct du_chain *chain;
- int reg;
+do_replace (struct du_chain *chain, int reg)
{
while (chain)
{
unsigned int regno = ORIGINAL_REGNO (*chain->loc);
+ struct reg_attrs * attr = REG_ATTRS (*chain->loc);
+
*chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg);
if (regno >= FIRST_PSEUDO_REGISTER)
ORIGINAL_REGNO (*chain->loc) = regno;
+ REG_ATTRS (*chain->loc) = attr;
chain = chain->next_use;
}
}
@@ -387,13 +384,8 @@ static struct du_chain *open_chains;
static struct du_chain *closed_chains;
static void
-scan_rtx_reg (insn, loc, class, action, type, earlyclobber)
- rtx insn;
- rtx *loc;
- enum reg_class class;
- enum scan_actions action;
- enum op_type type;
- int earlyclobber;
+scan_rtx_reg (rtx insn, rtx *loc, enum reg_class class,
+ enum scan_actions action, enum op_type type, int earlyclobber)
{
struct du_chain **p;
rtx x = *loc;
@@ -405,8 +397,8 @@ scan_rtx_reg (insn, loc, class, action, type, earlyclobber)
{
if (type == OP_OUT)
{
- struct du_chain *this = (struct du_chain *)
- obstack_alloc (&rename_obstack, sizeof (struct du_chain));
+ struct du_chain *this
+ = obstack_alloc (&rename_obstack, sizeof (struct du_chain));
this->next_use = 0;
this->next_chain = open_chains;
this->loc = loc;
@@ -460,8 +452,7 @@ scan_rtx_reg (insn, loc, class, action, type, earlyclobber)
be replaced with, terminate the chain. */
if (class != NO_REGS)
{
- this = (struct du_chain *)
- obstack_alloc (&rename_obstack, sizeof (struct du_chain));
+ this = obstack_alloc (&rename_obstack, sizeof (struct du_chain));
this->next_use = 0;
this->next_chain = (*p)->next_chain;
this->loc = loc;
@@ -514,12 +505,8 @@ scan_rtx_reg (insn, loc, class, action, type, earlyclobber)
BASE_REG_CLASS depending on how the register is being considered. */
static void
-scan_rtx_address (insn, loc, class, action, mode)
- rtx insn;
- rtx *loc;
- enum reg_class class;
- enum scan_actions action;
- enum machine_mode mode;
+scan_rtx_address (rtx insn, rtx *loc, enum reg_class class,
+ enum scan_actions action, enum machine_mode mode)
{
rtx x = *loc;
RTX_CODE code = GET_CODE (x);
@@ -651,13 +638,8 @@ scan_rtx_address (insn, loc, class, action, mode)
}
static void
-scan_rtx (insn, loc, class, action, type, earlyclobber)
- rtx insn;
- rtx *loc;
- enum reg_class class;
- enum scan_actions action;
- enum op_type type;
- int earlyclobber;
+scan_rtx (rtx insn, rtx *loc, enum reg_class class,
+ enum scan_actions action, enum op_type type, int earlyclobber)
{
const char *fmt;
rtx x = *loc;
@@ -741,14 +723,13 @@ scan_rtx (insn, loc, class, action, type, earlyclobber)
/* Build def/use chain. */
static struct du_chain *
-build_def_use (bb)
- basic_block bb;
+build_def_use (basic_block bb)
{
rtx insn;
open_chains = closed_chains = NULL;
- for (insn = bb->head; ; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
{
if (INSN_P (insn))
{
@@ -973,7 +954,7 @@ build_def_use (bb)
scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead,
OP_IN, 0);
}
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
}
@@ -986,8 +967,7 @@ build_def_use (bb)
printed in reverse order as that's how we build them. */
static void
-dump_def_use_chain (chains)
- struct du_chain *chains;
+dump_def_use_chain (struct du_chain *chains)
{
while (chains)
{
@@ -1031,42 +1011,36 @@ struct value_data
unsigned int max_value_regs;
};
-static void kill_value_regno PARAMS ((unsigned, struct value_data *));
-static void kill_value PARAMS ((rtx, struct value_data *));
-static void set_value_regno PARAMS ((unsigned, enum machine_mode,
- struct value_data *));
-static void init_value_data PARAMS ((struct value_data *));
-static void kill_clobbered_value PARAMS ((rtx, rtx, void *));
-static void kill_set_value PARAMS ((rtx, rtx, void *));
-static int kill_autoinc_value PARAMS ((rtx *, void *));
-static void copy_value PARAMS ((rtx, rtx, struct value_data *));
-static bool mode_change_ok PARAMS ((enum machine_mode, enum machine_mode,
- unsigned int));
-static rtx maybe_mode_change PARAMS ((enum machine_mode, enum machine_mode,
- enum machine_mode, unsigned int,
- unsigned int));
-static rtx find_oldest_value_reg PARAMS ((enum reg_class, rtx,
- struct value_data *));
-static bool replace_oldest_value_reg PARAMS ((rtx *, enum reg_class, rtx,
- struct value_data *));
-static bool replace_oldest_value_addr PARAMS ((rtx *, enum reg_class,
- enum machine_mode, rtx,
- struct value_data *));
-static bool replace_oldest_value_mem PARAMS ((rtx, rtx, struct value_data *));
-static bool copyprop_hardreg_forward_1 PARAMS ((basic_block,
- struct value_data *));
-extern void debug_value_data PARAMS ((struct value_data *));
+static void kill_value_regno (unsigned, struct value_data *);
+static void kill_value (rtx, struct value_data *);
+static void set_value_regno (unsigned, enum machine_mode, struct value_data *);
+static void init_value_data (struct value_data *);
+static void kill_clobbered_value (rtx, rtx, void *);
+static void kill_set_value (rtx, rtx, void *);
+static int kill_autoinc_value (rtx *, void *);
+static void copy_value (rtx, rtx, struct value_data *);
+static bool mode_change_ok (enum machine_mode, enum machine_mode,
+ unsigned int);
+static rtx maybe_mode_change (enum machine_mode, enum machine_mode,
+ enum machine_mode, unsigned int, unsigned int);
+static rtx find_oldest_value_reg (enum reg_class, rtx, struct value_data *);
+static bool replace_oldest_value_reg (rtx *, enum reg_class, rtx,
+ struct value_data *);
+static bool replace_oldest_value_addr (rtx *, enum reg_class,
+ enum machine_mode, rtx,
+ struct value_data *);
+static bool replace_oldest_value_mem (rtx, rtx, struct value_data *);
+static bool copyprop_hardreg_forward_1 (basic_block, struct value_data *);
+extern void debug_value_data (struct value_data *);
#ifdef ENABLE_CHECKING
-static void validate_value_data PARAMS ((struct value_data *));
+static void validate_value_data (struct value_data *);
#endif
/* Kill register REGNO. This involves removing it from any value lists,
and resetting the value mode to VOIDmode. */
static void
-kill_value_regno (regno, vd)
- unsigned int regno;
- struct value_data *vd;
+kill_value_regno (unsigned int regno, struct value_data *vd)
{
unsigned int i, next;
@@ -1097,9 +1071,7 @@ kill_value_regno (regno, vd)
so that we mind the mode the register is in. */
static void
-kill_value (x, vd)
- rtx x;
- struct value_data *vd;
+kill_value (rtx x, struct value_data *vd)
{
/* SUBREGS are supposed to have been eliminated by now. But some
ports, e.g. i386 sse, use them to smuggle vector type information
@@ -1139,10 +1111,8 @@ kill_value (x, vd)
/* Remember that REGNO is valid in MODE. */
static void
-set_value_regno (regno, mode, vd)
- unsigned int regno;
- enum machine_mode mode;
- struct value_data *vd;
+set_value_regno (unsigned int regno, enum machine_mode mode,
+ struct value_data *vd)
{
unsigned int nregs;
@@ -1156,8 +1126,7 @@ set_value_regno (regno, mode, vd)
/* Initialize VD such that there are no known relationships between regs. */
static void
-init_value_data (vd)
- struct value_data *vd;
+init_value_data (struct value_data *vd)
{
int i;
for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
@@ -1172,10 +1141,7 @@ init_value_data (vd)
/* Called through note_stores. If X is clobbered, kill its value. */
static void
-kill_clobbered_value (x, set, data)
- rtx x;
- rtx set;
- void *data;
+kill_clobbered_value (rtx x, rtx set, void *data)
{
struct value_data *vd = data;
if (GET_CODE (set) == CLOBBER)
@@ -1186,10 +1152,7 @@ kill_clobbered_value (x, set, data)
current value and install it as the root of its own value list. */
static void
-kill_set_value (x, set, data)
- rtx x;
- rtx set;
- void *data;
+kill_set_value (rtx x, rtx set, void *data)
{
struct value_data *vd = data;
if (GET_CODE (set) != CLOBBER)
@@ -1205,9 +1168,7 @@ kill_set_value (x, set, data)
own value list. */
static int
-kill_autoinc_value (px, data)
- rtx *px;
- void *data;
+kill_autoinc_value (rtx *px, void *data)
{
rtx x = *px;
struct value_data *vd = data;
@@ -1227,10 +1188,7 @@ kill_autoinc_value (px, data)
to reflect that SRC contains an older copy of the shared value. */
static void
-copy_value (dest, src, vd)
- rtx dest;
- rtx src;
- struct value_data *vd;
+copy_value (rtx dest, rtx src, struct value_data *vd)
{
unsigned int dr = REGNO (dest);
unsigned int sr = REGNO (src);
@@ -1306,9 +1264,8 @@ copy_value (dest, src, vd)
/* Return true if a mode change from ORIG to NEW is allowed for REGNO. */
static bool
-mode_change_ok (orig_mode, new_mode, regno)
- enum machine_mode orig_mode, new_mode;
- unsigned int regno ATTRIBUTE_UNUSED;
+mode_change_ok (enum machine_mode orig_mode, enum machine_mode new_mode,
+ unsigned int regno ATTRIBUTE_UNUSED)
{
if (GET_MODE_SIZE (orig_mode) < GET_MODE_SIZE (new_mode))
return false;
@@ -1326,9 +1283,9 @@ mode_change_ok (orig_mode, new_mode, regno)
Return a NEW_MODE rtx for REGNO if that's OK, otherwise return NULL_RTX. */
static rtx
-maybe_mode_change (orig_mode, copy_mode, new_mode, regno, copy_regno)
- enum machine_mode orig_mode, copy_mode, new_mode;
- unsigned int regno, copy_regno;
+maybe_mode_change (enum machine_mode orig_mode, enum machine_mode copy_mode,
+ enum machine_mode new_mode, unsigned int regno,
+ unsigned int copy_regno ATTRIBUTE_UNUSED)
{
if (orig_mode == new_mode)
return gen_rtx_raw_REG (new_mode, regno);
@@ -1358,10 +1315,7 @@ maybe_mode_change (orig_mode, copy_mode, new_mode, regno, copy_regno)
of that oldest register, otherwise return NULL. */
static rtx
-find_oldest_value_reg (class, reg, vd)
- enum reg_class class;
- rtx reg;
- struct value_data *vd;
+find_oldest_value_reg (enum reg_class class, rtx reg, struct value_data *vd)
{
unsigned int regno = REGNO (reg);
enum machine_mode mode = GET_MODE (reg);
@@ -1385,14 +1339,19 @@ find_oldest_value_reg (class, reg, vd)
{
enum machine_mode oldmode = vd->e[i].mode;
rtx new;
+ unsigned int last;
- if (TEST_HARD_REG_BIT (reg_class_contents[class], i)
- && (new = maybe_mode_change (oldmode, vd->e[regno].mode, mode, i,
- regno)))
- {
- ORIGINAL_REGNO (new) = ORIGINAL_REGNO (reg);
- return new;
- }
+ for (last = i; last < i + HARD_REGNO_NREGS (i, mode); last++)
+ if (!TEST_HARD_REG_BIT (reg_class_contents[class], last))
+ return NULL_RTX;
+
+ new = maybe_mode_change (oldmode, vd->e[regno].mode, mode, i, regno);
+ if (new)
+ {
+ ORIGINAL_REGNO (new) = ORIGINAL_REGNO (reg);
+ REG_ATTRS (new) = REG_ATTRS (reg);
+ return new;
+ }
}
return NULL_RTX;
@@ -1402,11 +1361,8 @@ find_oldest_value_reg (class, reg, vd)
in register class CLASS. Return true if successfully replaced. */
static bool
-replace_oldest_value_reg (loc, class, insn, vd)
- rtx *loc;
- enum reg_class class;
- rtx insn;
- struct value_data *vd;
+replace_oldest_value_reg (rtx *loc, enum reg_class class, rtx insn,
+ struct value_data *vd)
{
rtx new = find_oldest_value_reg (class, *loc, vd);
if (new)
@@ -1426,12 +1382,9 @@ replace_oldest_value_reg (loc, class, insn, vd)
BASE_REG_CLASS depending on how the register is being considered. */
static bool
-replace_oldest_value_addr (loc, class, mode, insn, vd)
- rtx *loc;
- enum reg_class class;
- enum machine_mode mode;
- rtx insn;
- struct value_data *vd;
+replace_oldest_value_addr (rtx *loc, enum reg_class class,
+ enum machine_mode mode, rtx insn,
+ struct value_data *vd)
{
rtx x = *loc;
RTX_CODE code = GET_CODE (x);
@@ -1561,10 +1514,7 @@ replace_oldest_value_addr (loc, class, mode, insn, vd)
/* Similar to replace_oldest_value_reg, but X contains a memory. */
static bool
-replace_oldest_value_mem (x, insn, vd)
- rtx x;
- rtx insn;
- struct value_data *vd;
+replace_oldest_value_mem (rtx x, rtx insn, struct value_data *vd)
{
return replace_oldest_value_addr (&XEXP (x, 0),
MODE_BASE_REG_CLASS (GET_MODE (x)),
@@ -1574,14 +1524,12 @@ replace_oldest_value_mem (x, insn, vd)
/* Perform the forward copy propagation on basic block BB. */
static bool
-copyprop_hardreg_forward_1 (bb, vd)
- basic_block bb;
- struct value_data *vd;
+copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
{
bool changed = false;
rtx insn;
- for (insn = bb->head; ; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
{
int n_ops, i, alt, predicated;
bool is_asm;
@@ -1589,7 +1537,7 @@ copyprop_hardreg_forward_1 (bb, vd)
if (! INSN_P (insn))
{
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
else
continue;
@@ -1684,6 +1632,7 @@ copyprop_hardreg_forward_1 (bb, vd)
if (validate_change (insn, &SET_SRC (set), new, 0))
{
ORIGINAL_REGNO (new) = ORIGINAL_REGNO (src);
+ REG_ATTRS (new) = REG_ATTRS (src);
if (rtl_dump_file)
fprintf (rtl_dump_file,
"insn %u: replaced reg %u with %u\n",
@@ -1764,7 +1713,7 @@ copyprop_hardreg_forward_1 (bb, vd)
if (set && REG_P (SET_DEST (set)) && REG_P (SET_SRC (set)))
copy_value (SET_DEST (set), SET_SRC (set), vd);
- if (insn == bb->end)
+ if (insn == BB_END (bb))
break;
}
@@ -1774,7 +1723,7 @@ copyprop_hardreg_forward_1 (bb, vd)
/* Main entry point for the forward copy propagation optimization. */
void
-copyprop_hardreg_forward ()
+copyprop_hardreg_forward (void)
{
struct value_data *all_vd;
bool need_refresh;
@@ -1789,7 +1738,7 @@ copyprop_hardreg_forward ()
/* If a block has a single predecessor, that we've already
processed, begin with the value data that was live at
the end of the predecessor block. */
- /* ??? Ought to use more intelligent queueing of blocks. */
+ /* ??? Ought to use more intelligent queuing of blocks. */
if (bb->pred)
for (bbp = bb; bbp && bbp != bb->pred->src; bbp = bbp->prev_bb);
if (bb->pred
@@ -1826,8 +1775,7 @@ copyprop_hardreg_forward ()
/* Dump the value chain data to stderr. */
void
-debug_value_data (vd)
- struct value_data *vd;
+debug_value_data (struct value_data *vd)
{
HARD_REG_SET set;
unsigned int i, j;
@@ -1882,8 +1830,7 @@ debug_value_data (vd)
#ifdef ENABLE_CHECKING
static void
-validate_value_data (vd)
- struct value_data *vd;
+validate_value_data (struct value_data *vd)
{
HARD_REG_SET set;
unsigned int i, j;
diff --git a/contrib/gcc/regs.h b/contrib/gcc/regs.h
index 2e838e329398..9c9edccb26b8 100644
--- a/contrib/gcc/regs.h
+++ b/contrib/gcc/regs.h
@@ -1,6 +1,6 @@
/* Define per-register tables for data flow info and register allocation.
Copyright (C) 1987, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -60,7 +60,7 @@ typedef struct reg_info_def
int live_length; /* # of instructions (REG n) is live */
int calls_crossed; /* # of calls (REG n) is live across */
int basic_block; /* # of basic blocks (REG n) is used in */
- char changes_mode; /* whether (SUBREG (REG n)) exists and
+ char changes_mode; /* whether (SUBREG (REG n)) exists and
is illegal. */
} reg_info;
@@ -76,7 +76,7 @@ extern bitmap_head subregs_of_mode;
#define REG_FREQ(N) (VARRAY_REG (reg_n_info, N)->freq)
-/* The weights for each insn varries from 0 to REG_FREQ_BASE.
+/* The weights for each insn varries from 0 to REG_FREQ_BASE.
This constant does not need to be high, as in infrequently executed
regions we want to count instructions equivalently to optimize for
size instead of speed. */
@@ -153,14 +153,13 @@ extern bitmap_head subregs_of_mode;
extern short *reg_renumber;
-/* Vector indexed by hardware reg
- saying whether that reg is ever used. */
+/* Vector indexed by hardware reg saying whether that reg is ever used. */
extern char regs_ever_live[FIRST_PSEUDO_REGISTER];
-/* Vector indexed by hardware reg giving its name. */
+/* Like regs_ever_live, but saying whether reg is set by asm statements. */
-extern const char * reg_names[FIRST_PSEUDO_REGISTER];
+extern char regs_asm_clobbered[FIRST_PSEUDO_REGISTER];
/* For each hard register, the widest mode object that it can contain.
This will be a MODE_INT mode if the register can hold integers. Otherwise
@@ -214,14 +213,14 @@ extern int caller_save_needed;
/* Select a register mode required for caller save of hard regno REGNO. */
#ifndef HARD_REGNO_CALLER_SAVE_MODE
#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \
- choose_hard_reg_mode (REGNO, NREGS)
+ choose_hard_reg_mode (REGNO, NREGS, false)
#endif
-/* Registers that get partially clobbered by a call in a given mode.
+/* Registers that get partially clobbered by a call in a given mode.
These must not be call used registers. */
#ifndef HARD_REGNO_CALL_PART_CLOBBERED
#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) 0
#endif
/* Allocate reg_n_info tables */
-extern void allocate_reg_info PARAMS ((size_t, int, int));
+extern void allocate_reg_info (size_t, int, int);
diff --git a/contrib/gcc/reload.c b/contrib/gcc/reload.c
index b151af738538..0dfac2ccdf83 100644
--- a/contrib/gcc/reload.c
+++ b/contrib/gcc/reload.c
@@ -1,6 +1,6 @@
/* Search an insn for pseudo regs that must be in hard regs and are not.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -88,6 +88,8 @@ a register with any other reload. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "insn-config.h"
@@ -102,10 +104,7 @@ a register with any other reload. */
#include "output.h"
#include "function.h"
#include "toplev.h"
-
-#ifndef REGISTER_MOVE_COST
-#define REGISTER_MOVE_COST(m, x, y) 2
-#endif
+#include "params.h"
#ifndef REGNO_MODE_OK_FOR_BASE_P
#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
@@ -174,6 +173,7 @@ struct decomposition
static rtx secondary_memlocs[NUM_MACHINE_MODES];
static rtx secondary_memlocs_elim[NUM_MACHINE_MODES][MAX_RECOG_OPERANDS];
+static int secondary_memlocs_elim_used = 0;
#endif
/* The instruction we are doing reloads for;
@@ -236,43 +236,41 @@ static int output_reloadnum;
: (type)))
#ifdef HAVE_SECONDARY_RELOADS
-static int push_secondary_reload PARAMS ((int, rtx, int, int, enum reg_class,
- enum machine_mode, enum reload_type,
- enum insn_code *));
+static int push_secondary_reload (int, rtx, int, int, enum reg_class,
+ enum machine_mode, enum reload_type,
+ enum insn_code *);
#endif
-static enum reg_class find_valid_class PARAMS ((enum machine_mode, int,
- unsigned int));
-static int reload_inner_reg_of_subreg PARAMS ((rtx, enum machine_mode, int));
-static void push_replacement PARAMS ((rtx *, int, enum machine_mode));
-static void dup_replacements PARAMS ((rtx *, rtx *));
-static void combine_reloads PARAMS ((void));
-static int find_reusable_reload PARAMS ((rtx *, rtx, enum reg_class,
- enum reload_type, int, int));
-static rtx find_dummy_reload PARAMS ((rtx, rtx, rtx *, rtx *,
- enum machine_mode, enum machine_mode,
- enum reg_class, int, int));
-static int hard_reg_set_here_p PARAMS ((unsigned int, unsigned int, rtx));
-static struct decomposition decompose PARAMS ((rtx));
-static int immune_p PARAMS ((rtx, rtx, struct decomposition));
-static int alternative_allows_memconst PARAMS ((const char *, int));
-static rtx find_reloads_toplev PARAMS ((rtx, int, enum reload_type, int,
- int, rtx, int *));
-static rtx make_memloc PARAMS ((rtx, int));
-static int maybe_memory_address_p PARAMS ((enum machine_mode, rtx, rtx *));
-static int find_reloads_address PARAMS ((enum machine_mode, rtx *, rtx, rtx *,
- int, enum reload_type, int, rtx));
-static rtx subst_reg_equivs PARAMS ((rtx, rtx));
-static rtx subst_indexed_address PARAMS ((rtx));
-static void update_auto_inc_notes PARAMS ((rtx, int, int));
-static int find_reloads_address_1 PARAMS ((enum machine_mode, rtx, int, rtx *,
- int, enum reload_type,int, rtx));
-static void find_reloads_address_part PARAMS ((rtx, rtx *, enum reg_class,
- enum machine_mode, int,
- enum reload_type, int));
-static rtx find_reloads_subreg_address PARAMS ((rtx, int, int,
- enum reload_type, int, rtx));
-static void copy_replacements_1 PARAMS ((rtx *, rtx *, int));
-static int find_inc_amount PARAMS ((rtx, rtx));
+static enum reg_class find_valid_class (enum machine_mode, int, unsigned int);
+static int reload_inner_reg_of_subreg (rtx, enum machine_mode, int);
+static void push_replacement (rtx *, int, enum machine_mode);
+static void dup_replacements (rtx *, rtx *);
+static void combine_reloads (void);
+static int find_reusable_reload (rtx *, rtx, enum reg_class,
+ enum reload_type, int, int);
+static rtx find_dummy_reload (rtx, rtx, rtx *, rtx *, enum machine_mode,
+ enum machine_mode, enum reg_class, int, int);
+static int hard_reg_set_here_p (unsigned int, unsigned int, rtx);
+static struct decomposition decompose (rtx);
+static int immune_p (rtx, rtx, struct decomposition);
+static int alternative_allows_memconst (const char *, int);
+static rtx find_reloads_toplev (rtx, int, enum reload_type, int, int, rtx,
+ int *);
+static rtx make_memloc (rtx, int);
+static int maybe_memory_address_p (enum machine_mode, rtx, rtx *);
+static int find_reloads_address (enum machine_mode, rtx *, rtx, rtx *,
+ int, enum reload_type, int, rtx);
+static rtx subst_reg_equivs (rtx, rtx);
+static rtx subst_indexed_address (rtx);
+static void update_auto_inc_notes (rtx, int, int);
+static int find_reloads_address_1 (enum machine_mode, rtx, int, rtx *,
+ int, enum reload_type,int, rtx);
+static void find_reloads_address_part (rtx, rtx *, enum reg_class,
+ enum machine_mode, int,
+ enum reload_type, int);
+static rtx find_reloads_subreg_address (rtx, int, int, enum reload_type,
+ int, rtx);
+static void copy_replacements_1 (rtx *, rtx *, int);
+static int find_inc_amount (rtx, rtx);
#ifdef HAVE_SECONDARY_RELOADS
@@ -286,16 +284,10 @@ static int find_inc_amount PARAMS ((rtx, rtx));
need a secondary reload. */
static int
-push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
- type, picode)
- int in_p;
- rtx x;
- int opnum;
- int optional;
- enum reg_class reload_class;
- enum machine_mode reload_mode;
- enum reload_type type;
- enum insn_code *picode;
+push_secondary_reload (int in_p, rtx x, int opnum, int optional,
+ enum reg_class reload_class,
+ enum machine_mode reload_mode, enum reload_type type,
+ enum insn_code *picode)
{
enum reg_class class = NO_REGS;
enum machine_mode mode = reload_mode;
@@ -380,11 +372,13 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
insn_class = ALL_REGS;
else
{
- char insn_letter
- = insn_data[(int) icode].operand[!in_p].constraint[in_p];
+ const char *insn_constraint
+ = &insn_data[(int) icode].operand[!in_p].constraint[in_p];
+ char insn_letter = *insn_constraint;
insn_class
= (insn_letter == 'r' ? GENERAL_REGS
- : REG_CLASS_FROM_LETTER ((unsigned char) insn_letter));
+ : REG_CLASS_FROM_CONSTRAINT ((unsigned char) insn_letter,
+ insn_constraint));
if (insn_class == NO_REGS)
abort ();
@@ -402,11 +396,14 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
mode = insn_data[(int) icode].operand[2].mode;
else
{
- char t_letter = insn_data[(int) icode].operand[2].constraint[2];
+ const char *t_constraint
+ = &insn_data[(int) icode].operand[2].constraint[2];
+ char t_letter = *t_constraint;
class = insn_class;
t_mode = insn_data[(int) icode].operand[2].mode;
t_class = (t_letter == 'r' ? GENERAL_REGS
- : REG_CLASS_FROM_LETTER ((unsigned char) t_letter));
+ : REG_CLASS_FROM_CONSTRAINT ((unsigned char) t_letter,
+ t_constraint));
t_icode = icode;
icode = CODE_FOR_nothing;
}
@@ -585,11 +582,8 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
call find_reloads_address on the location being returned. */
rtx
-get_secondary_mem (x, mode, opnum, type)
- rtx x ATTRIBUTE_UNUSED;
- enum machine_mode mode;
- int opnum;
- enum reload_type type;
+get_secondary_mem (rtx x ATTRIBUTE_UNUSED, enum machine_mode mode,
+ int opnum, enum reload_type type)
{
rtx loc;
int mem_valid;
@@ -651,15 +645,17 @@ get_secondary_mem (x, mode, opnum, type)
}
secondary_memlocs_elim[(int) mode][opnum] = loc;
+ if (secondary_memlocs_elim_used <= (int)mode)
+ secondary_memlocs_elim_used = (int)mode + 1;
return loc;
}
/* Clear any secondary memory locations we've made. */
void
-clear_secondary_mem ()
+clear_secondary_mem (void)
{
- memset ((char *) secondary_memlocs, 0, sizeof secondary_memlocs);
+ memset (secondary_memlocs, 0, sizeof secondary_memlocs);
}
#endif /* SECONDARY_MEMORY_NEEDED */
@@ -668,16 +664,14 @@ clear_secondary_mem ()
Abort if no such class exists. */
static enum reg_class
-find_valid_class (m1, n, dest_regno)
- enum machine_mode m1 ATTRIBUTE_UNUSED;
- int n;
- unsigned int dest_regno;
+find_valid_class (enum machine_mode m1 ATTRIBUTE_UNUSED, int n,
+ unsigned int dest_regno ATTRIBUTE_UNUSED)
{
int best_cost = -1;
int class;
int regno;
enum reg_class best_class = NO_REGS;
- enum reg_class dest_class = REGNO_REG_CLASS (dest_regno);
+ enum reg_class dest_class ATTRIBUTE_UNUSED = REGNO_REG_CLASS (dest_regno);
unsigned int best_size = 0;
int cost;
@@ -719,11 +713,8 @@ find_valid_class (m1, n, dest_regno)
DONT_SHARE is nonzero if we can't share any input-only reload for IN. */
static int
-find_reusable_reload (p_in, out, class, type, opnum, dont_share)
- rtx *p_in, out;
- enum reg_class class;
- enum reload_type type;
- int opnum, dont_share;
+find_reusable_reload (rtx *p_in, rtx out, enum reg_class class,
+ enum reload_type type, int opnum, int dont_share)
{
rtx in = *p_in;
int i;
@@ -796,10 +787,7 @@ find_reusable_reload (p_in, out, class, type, opnum, dont_share)
SUBREG_REG expression. */
static int
-reload_inner_reg_of_subreg (x, mode, output)
- rtx x;
- enum machine_mode mode;
- int output;
+reload_inner_reg_of_subreg (rtx x, enum machine_mode mode, int output)
{
rtx inner;
@@ -819,13 +807,6 @@ reload_inner_reg_of_subreg (x, mode, output)
|| REGNO (inner) >= FIRST_PSEUDO_REGISTER)
return 0;
- if (!subreg_offset_representable_p
- (REGNO (SUBREG_REG (x)),
- GET_MODE (SUBREG_REG (x)),
- SUBREG_BYTE (x),
- GET_MODE (x)))
- return 1;
-
/* If INNER is not ok for MODE, then INNER will need reloading. */
if (! HARD_REGNO_MODE_OK (subreg_regno (x), mode))
return 1;
@@ -840,6 +821,56 @@ reload_inner_reg_of_subreg (x, mode, output)
!= (int) HARD_REGNO_NREGS (REGNO (inner), GET_MODE (inner))));
}
+/* Return nonzero if IN can be reloaded into REGNO with mode MODE without
+ requiring an extra reload register. The caller has already found that
+ IN contains some reference to REGNO, so check that we can produce the
+ new value in a single step. E.g. if we have
+ (set (reg r13) (plus (reg r13) (const int 1))), and there is an
+ instruction that adds one to a register, this should succeed.
+ However, if we have something like
+ (set (reg r13) (plus (reg r13) (const int 999))), and the constant 999
+ needs to be loaded into a register first, we need a separate reload
+ register.
+ Such PLUS reloads are generated by find_reload_address_part.
+ The out-of-range PLUS expressions are usually introduced in the instruction
+ patterns by register elimination and substituting pseudos without a home
+ by their function-invariant equivalences. */
+static int
+can_reload_into (rtx in, int regno, enum machine_mode mode)
+{
+ rtx dst, test_insn;
+ int r = 0;
+ struct recog_data save_recog_data;
+
+ /* For matching constraints, we often get notional input reloads where
+ we want to use the original register as the reload register. I.e.
+ technically this is a non-optional input-output reload, but IN is
+ already a valid register, and has been chosen as the reload register.
+ Speed this up, since it trivially works. */
+ if (GET_CODE (in) == REG)
+ return 1;
+
+ /* To test MEMs properly, we'd have to take into account all the reloads
+ that are already scheduled, which can become quite complicated.
+ And since we've already handled address reloads for this MEM, it
+ should always succeed anyway. */
+ if (GET_CODE (in) == MEM)
+ return 1;
+
+ /* If we can make a simple SET insn that does the job, everything should
+ be fine. */
+ dst = gen_rtx_REG (mode, regno);
+ test_insn = make_insn_raw (gen_rtx_SET (VOIDmode, dst, in));
+ save_recog_data = recog_data;
+ if (recog_memoized (test_insn) >= 0)
+ {
+ extract_insn (test_insn);
+ r = constrain_operands (1);
+ }
+ recog_data = save_recog_data;
+ return r;
+}
+
/* Record one reload that needs to be performed.
IN is an rtx saying where the data are to be found before this instruction.
OUT says where they must be stored after the instruction.
@@ -874,16 +905,10 @@ reload_inner_reg_of_subreg (x, mode, output)
distinguish them. */
int
-push_reload (in, out, inloc, outloc, class,
- inmode, outmode, strict_low, optional, opnum, type)
- rtx in, out;
- rtx *inloc, *outloc;
- enum reg_class class;
- enum machine_mode inmode, outmode;
- int strict_low;
- int optional;
- int opnum;
- enum reload_type type;
+push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
+ enum reg_class class, enum machine_mode inmode,
+ enum machine_mode outmode, int strict_low, int optional,
+ int opnum, enum reload_type type)
{
int i;
int dont_share = 0;
@@ -1124,7 +1149,7 @@ push_reload (in, out, inloc, outloc, class,
|| (GET_CODE (SUBREG_REG (out)) == REG
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
&& REG_CANNOT_CHANGE_MODE_P (REGNO (SUBREG_REG (out)),
- GET_MODE (SUBREG_REG (out)),
+ GET_MODE (SUBREG_REG (out)),
outmode))
#endif
))
@@ -1532,7 +1557,11 @@ push_reload (in, out, inloc, outloc, class,
regno + offs))
break;
- if (offs == nregs)
+ if (offs == nregs
+ && (! (refers_to_regno_for_reload_p
+ (regno, (regno + HARD_REGNO_NREGS (regno, inmode)),
+ in, (rtx *)0))
+ || can_reload_into (in, regno, inmode)))
{
rld[i].reg_rtx = gen_rtx_REG (rel_mode, regno);
break;
@@ -1553,10 +1582,7 @@ push_reload (in, out, inloc, outloc, class,
This is used in insn patterns that use match_dup. */
static void
-push_replacement (loc, reloadnum, mode)
- rtx *loc;
- int reloadnum;
- enum machine_mode mode;
+push_replacement (rtx *loc, int reloadnum, enum machine_mode mode)
{
if (replace_reloads)
{
@@ -1573,9 +1599,7 @@ push_replacement (loc, reloadnum, mode)
This is used in insn patterns that use match_dup. */
static void
-dup_replacements (dup_loc, orig_loc)
- rtx *dup_loc;
- rtx *orig_loc;
+dup_replacements (rtx *dup_loc, rtx *orig_loc)
{
int i, n = n_replacements;
@@ -1591,8 +1615,7 @@ dup_replacements (dup_loc, orig_loc)
reload TO. */
void
-transfer_replacements (to, from)
- int to, from;
+transfer_replacements (int to, int from)
{
int i;
@@ -1606,8 +1629,7 @@ transfer_replacements (to, from)
cancel the reloads that were supposed to load them.
Return nonzero if we canceled any reloads. */
int
-remove_address_replacements (in_rtx)
- rtx in_rtx;
+remove_address_replacements (rtx in_rtx)
{
int i, j;
char reload_flags[MAX_RELOADS];
@@ -1653,7 +1675,7 @@ remove_address_replacements (in_rtx)
class and does not appear in the value being output-reloaded. */
static void
-combine_reloads ()
+combine_reloads (void)
{
int i;
int output_reload = -1;
@@ -1850,14 +1872,9 @@ combine_reloads ()
is safe from the earlyclobber). */
static rtx
-find_dummy_reload (real_in, real_out, inloc, outloc,
- inmode, outmode, class, for_real, earlyclobber)
- rtx real_in, real_out;
- rtx *inloc, *outloc;
- enum machine_mode inmode, outmode;
- enum reg_class class;
- int for_real;
- int earlyclobber;
+find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
+ enum machine_mode inmode, enum machine_mode outmode,
+ enum reg_class class, int for_real, int earlyclobber)
{
rtx in = real_in;
rtx out = real_out;
@@ -2008,8 +2025,7 @@ find_dummy_reload (real_in, real_out, inloc, outloc,
/* Return 1 if X is an operand of an insn that is being earlyclobbered. */
int
-earlyclobber_operand_p (x)
- rtx x;
+earlyclobber_operand_p (rtx x)
{
int i;
@@ -2026,9 +2042,7 @@ earlyclobber_operand_p (x)
X should be the body of an instruction. */
static int
-hard_reg_set_here_p (beg_regno, end_regno, x)
- unsigned int beg_regno, end_regno;
- rtx x;
+hard_reg_set_here_p (unsigned int beg_regno, unsigned int end_regno, rtx x)
{
if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
{
@@ -2063,9 +2077,7 @@ hard_reg_set_here_p (beg_regno, end_regno, x)
hard reg. */
int
-strict_memory_address_p (mode, addr)
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx addr;
+strict_memory_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx addr)
{
GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
return 0;
@@ -2090,8 +2102,7 @@ strict_memory_address_p (mode, addr)
because that is natural in (SET output (... input ...)). */
int
-operands_match_p (x, y)
- rtx x, y;
+operands_match_p (rtx x, rtx y)
{
int i;
RTX_CODE code = GET_CODE (x);
@@ -2137,10 +2148,10 @@ operands_match_p (x, y)
(reg:SI 1) will be considered the same register. */
if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD
&& i < FIRST_PSEUDO_REGISTER)
- i += (GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD) - 1;
+ i += HARD_REGNO_NREGS (i, GET_MODE (x)) - 1;
if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (y)) > UNITS_PER_WORD
&& j < FIRST_PSEUDO_REGISTER)
- j += (GET_MODE_SIZE (GET_MODE (y)) / UNITS_PER_WORD) - 1;
+ j += HARD_REGNO_NREGS (j, GET_MODE (y)) - 1;
return i == j;
}
@@ -2242,8 +2253,7 @@ operands_match_p (x, y)
so we set the SAFE field. */
static struct decomposition
-decompose (x)
- rtx x;
+decompose (rtx x)
{
struct decomposition val;
int all_const = 0;
@@ -2381,9 +2391,7 @@ decompose (x)
Y is also described by YDATA, which should be decompose (Y). */
static int
-immune_p (x, y, ydata)
- rtx x, y;
- struct decomposition ydata;
+immune_p (rtx x, rtx y, struct decomposition ydata)
{
struct decomposition xdata;
@@ -2426,8 +2434,7 @@ immune_p (x, y, ydata)
/* Similar, but calls decompose. */
int
-safe_from_earlyclobber (op, clobber)
- rtx op, clobber;
+safe_from_earlyclobber (rtx op, rtx clobber)
{
struct decomposition early_data;
@@ -2458,11 +2465,8 @@ safe_from_earlyclobber (op, clobber)
commutative operands, reg_equiv_address substitution, or whatever. */
int
-find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
- rtx insn;
- int replace, ind_levels;
- int live_known;
- short *reload_reg_p;
+find_reloads (rtx insn, int replace, int ind_levels, int live_known,
+ short *reload_reg_p)
{
int insn_code_number;
int i, j;
@@ -2539,7 +2543,12 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
/* The eliminated forms of any secondary memory locations are per-insn, so
clear them out here. */
- memset ((char *) secondary_memlocs_elim, 0, sizeof secondary_memlocs_elim);
+ if (secondary_memlocs_elim_used)
+ {
+ memset (secondary_memlocs_elim, 0,
+ sizeof (secondary_memlocs_elim[0]) * secondary_memlocs_elim_used);
+ secondary_memlocs_elim_used = 0;
+ }
#endif
/* Dispose quickly of (set (reg..) (reg..)) if both have hard regs and it
@@ -2591,8 +2600,9 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
/* Scan this operand's constraint to see if it is an output operand,
an in-out operand, is commutative, or should match another. */
- while ((c = *p++))
+ while ((c = *p))
{
+ p += CONSTRAINT_LEN (c, p);
if (c == '=')
modified[i] = RELOAD_WRITE;
else if (c == '+')
@@ -2603,7 +2613,17 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
if (i == noperands - 1)
abort ();
- commutative = i;
+ /* We currently only support one commutative pair of
+ operands. Some existing asm code currently uses more
+ than one pair. Previously, that would usually work,
+ but sometimes it would crash the compiler. We
+ continue supporting that case as well as we can by
+ silently ignoring all but the first pair. In the
+ future we may handle it correctly. */
+ if (commutative < 0)
+ commutative = i;
+ else if (!this_insn_is_asm)
+ abort ();
}
else if (ISDIGIT (c))
{
@@ -2669,7 +2689,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
/* Ignore things like match_operator operands. */
;
else if (constraints[i][0] == 'p'
- || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
+ || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i]))
{
address_operand_reloaded[i]
= find_reloads_address (recog_data.operand_mode[i], (rtx*) 0,
@@ -2839,6 +2859,8 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
for (i = 0; i < noperands; i++)
{
char *p = constraints[i];
+ char *end;
+ int len;
int win = 0;
int did_match = 0;
/* 0 => this operand can be reloaded somehow for this alternative. */
@@ -2846,6 +2868,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
/* 0 => this operand can be reloaded if the alternative allows regs. */
int winreg = 0;
int c;
+ int m;
rtx operand = recog_data.operand[i];
int offset = 0;
/* Nonzero means this is a MEM that must be reloaded into a reg
@@ -2910,11 +2933,11 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
This is doubly true if WORD_REGISTER_OPERATIONS. In
this case eliminate_regs has left non-paradoxical
- subregs for push_reloads to see. Make sure it does
+ subregs for push_reload to see. Make sure it does
by forcing the reload.
??? When is it right at this stage to have a subreg
- of a mem that is _not_ to be handled specialy? IMO
+ of a mem that is _not_ to be handled specially? IMO
those should have been reduced to just a mem. */
|| ((GET_CODE (operand) == MEM
|| (GET_CODE (operand)== REG
@@ -2924,7 +2947,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
< BIGGEST_ALIGNMENT)
&& (GET_MODE_SIZE (operand_mode[i])
> GET_MODE_SIZE (GET_MODE (operand))))
- || (GET_CODE (operand) == MEM && BYTES_BIG_ENDIAN)
+ || BYTES_BIG_ENDIAN
#ifdef LOAD_EXTEND_OP
|| (GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
&& (GET_MODE_SIZE (GET_MODE (operand))
@@ -2960,16 +2983,22 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
or set WINREG if this operand could fit after reloads
provided the constraint allows some registers. */
- while (*p && (c = *p++) != ',')
- switch (c)
+ do
+ switch ((c = *p, len = CONSTRAINT_LEN (c, p)), c)
{
+ case '\0':
+ len = 0;
+ break;
+ case ',':
+ c = '\0';
+ break;
+
case '=': case '+': case '*':
break;
case '%':
- /* The last operand should not be marked commutative. */
- if (i != noperands - 1)
- commutative = i;
+ /* We only support one commutative marker, the first
+ one. We already set commutative above. */
break;
case '?':
@@ -2983,15 +3012,19 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
case '#':
/* Ignore rest of this alternative as far as
reloading is concerned. */
- while (*p && *p != ',')
+ do
p++;
+ while (*p && *p != ',');
+ len = 0;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
- c = strtoul (p - 1, &p, 10);
+ m = strtoul (p, &end, 10);
+ p = end;
+ len = 0;
- this_alternative_matches[i] = c;
+ this_alternative_matches[i] = m;
/* We are supposed to match a previous operand.
If we do, we win if that one did.
If we do not, count both of the operands as losers.
@@ -2999,7 +3032,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
only a single reload insn will be needed to make
the two operands win. As a result, this alternative
may be rejected when it is actually desirable.) */
- if ((swapped && (c != commutative || i != commutative + 1))
+ if ((swapped && (m != commutative || i != commutative + 1))
/* If we are matching as if two operands were swapped,
also pretend that operands_match had been computed
with swapped.
@@ -3007,22 +3040,22 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
don't exchange them, because operands_match is valid
only on one side of its diagonal. */
? (operands_match
- [(c == commutative || c == commutative + 1)
- ? 2 * commutative + 1 - c : c]
+ [(m == commutative || m == commutative + 1)
+ ? 2 * commutative + 1 - m : m]
[(i == commutative || i == commutative + 1)
? 2 * commutative + 1 - i : i])
- : operands_match[c][i])
+ : operands_match[m][i])
{
/* If we are matching a non-offsettable address where an
offsettable address was expected, then we must reject
this combination, because we can't reload it. */
- if (this_alternative_offmemok[c]
- && GET_CODE (recog_data.operand[c]) == MEM
- && this_alternative[c] == (int) NO_REGS
- && ! this_alternative_win[c])
+ if (this_alternative_offmemok[m]
+ && GET_CODE (recog_data.operand[m]) == MEM
+ && this_alternative[m] == (int) NO_REGS
+ && ! this_alternative_win[m])
bad = 1;
- did_match = this_alternative_win[c];
+ did_match = this_alternative_win[m];
}
else
{
@@ -3030,21 +3063,21 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
rtx value;
/* Retroactively mark the operand we had to match
as a loser, if it wasn't already. */
- if (this_alternative_win[c])
+ if (this_alternative_win[m])
losers++;
- this_alternative_win[c] = 0;
- if (this_alternative[c] == (int) NO_REGS)
+ this_alternative_win[m] = 0;
+ if (this_alternative[m] == (int) NO_REGS)
bad = 1;
/* But count the pair only once in the total badness of
this alternative, if the pair can be a dummy reload. */
value
= find_dummy_reload (recog_data.operand[i],
- recog_data.operand[c],
+ recog_data.operand[m],
recog_data.operand_loc[i],
- recog_data.operand_loc[c],
- operand_mode[i], operand_mode[c],
- this_alternative[c], -1,
- this_alternative_earlyclobber[c]);
+ recog_data.operand_loc[m],
+ operand_mode[i], operand_mode[m],
+ this_alternative[m], -1,
+ this_alternative_earlyclobber[m]);
if (value != 0)
losers--;
@@ -3052,7 +3085,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
/* This can be fixed with reloads if the operand
we are supposed to match can be fixed with reloads. */
badop = 0;
- this_alternative[i] = this_alternative[c];
+ this_alternative[i] = this_alternative[m];
/* If we have to reload this operand and some previous
operand also had to match the same thing as this
@@ -3171,7 +3204,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
case 'G':
case 'H':
if (GET_CODE (operand) == CONST_DOUBLE
- && CONST_DOUBLE_OK_FOR_LETTER_P (operand, c))
+ && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (operand, c, p))
win = 1;
break;
@@ -3205,7 +3238,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
case 'O':
case 'P':
if (GET_CODE (operand) == CONST_INT
- && CONST_OK_FOR_LETTER_P (INTVAL (operand), c))
+ && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operand), c, p))
win = 1;
break;
@@ -3238,28 +3271,29 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
goto reg;
default:
- if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
+ if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS)
{
-#ifdef EXTRA_CONSTRAINT
- if (EXTRA_MEMORY_CONSTRAINT (c))
+#ifdef EXTRA_CONSTRAINT_STR
+ if (EXTRA_MEMORY_CONSTRAINT (c, p))
{
if (force_reload)
break;
- if (EXTRA_CONSTRAINT (operand, c))
+ if (EXTRA_CONSTRAINT_STR (operand, c, p))
win = 1;
/* If the address was already reloaded,
we win as well. */
- if (GET_CODE (operand) == MEM && address_reloaded[i])
+ else if (GET_CODE (operand) == MEM
+ && address_reloaded[i])
win = 1;
/* Likewise if the address will be reloaded because
reg_equiv_address is nonzero. For reg_equiv_mem
we have to check. */
- if (GET_CODE (operand) == REG
- && REGNO (operand) >= FIRST_PSEUDO_REGISTER
- && reg_renumber[REGNO (operand)] < 0
- && ((reg_equiv_mem[REGNO (operand)] != 0
- && EXTRA_CONSTRAINT (reg_equiv_mem[REGNO (operand)], c))
- || (reg_equiv_address[REGNO (operand)] != 0)))
+ else if (GET_CODE (operand) == REG
+ && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+ && reg_renumber[REGNO (operand)] < 0
+ && ((reg_equiv_mem[REGNO (operand)] != 0
+ && EXTRA_CONSTRAINT_STR (reg_equiv_mem[REGNO (operand)], c, p))
+ || (reg_equiv_address[REGNO (operand)] != 0)))
win = 1;
/* If we didn't already win, we can reload
@@ -3272,9 +3306,9 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
offmemok = 1;
break;
}
- if (EXTRA_ADDRESS_CONSTRAINT (c))
+ if (EXTRA_ADDRESS_CONSTRAINT (c, p))
{
- if (EXTRA_CONSTRAINT (operand, c))
+ if (EXTRA_CONSTRAINT_STR (operand, c, p))
win = 1;
/* If we didn't already win, we can reload
@@ -3284,14 +3318,16 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
break;
}
- if (EXTRA_CONSTRAINT (operand, c))
+ if (EXTRA_CONSTRAINT_STR (operand, c, p))
win = 1;
#endif
break;
}
this_alternative[i]
- = (int) reg_class_subunion[this_alternative[i]][(int) REG_CLASS_FROM_LETTER (c)];
+ = (int) (reg_class_subunion
+ [this_alternative[i]]
+ [(int) REG_CLASS_FROM_CONSTRAINT (c, p)]);
reg:
if (GET_MODE (operand) == BLKmode)
break;
@@ -3302,6 +3338,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
win = 1;
break;
}
+ while ((p += len), c);
constraints[i] = p;
@@ -3375,6 +3412,12 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
&& ! const_to_mem)
bad = 1;
+#ifdef DISPARAGE_RELOAD_CLASS
+ reject
+ += DISPARAGE_RELOAD_CLASS (operand,
+ (enum reg_class) this_alternative[i]);
+#endif
+
/* We prefer to reload pseudos over reloading other things,
since such reloads may be able to be eliminated later.
If we are reloading a SCRATCH, we won't be generating any
@@ -4319,16 +4362,26 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
for (i = 0; i < n_reloads; i++)
if (rld[i].when_needed == RELOAD_FOR_INPUT
&& GET_CODE (PATTERN (insn)) == SET
- && GET_CODE (SET_DEST (PATTERN (insn))) == REG
- && SET_SRC (PATTERN (insn)) == rld[i].in)
+ && GET_CODE (SET_DEST (PATTERN (insn))) == REG
+ && SET_SRC (PATTERN (insn)) == rld[i].in)
{
- rtx dest = SET_DEST (PATTERN (insn));
+ rtx dest = SET_DEST (PATTERN (insn));
unsigned int regno = REGNO (dest);
- if (regno < FIRST_PSEUDO_REGISTER
- && TEST_HARD_REG_BIT (reg_class_contents[rld[i].class], regno)
- && HARD_REGNO_MODE_OK (regno, rld[i].mode))
- rld[i].reg_rtx = dest;
+ if (regno < FIRST_PSEUDO_REGISTER
+ && TEST_HARD_REG_BIT (reg_class_contents[rld[i].class], regno)
+ && HARD_REGNO_MODE_OK (regno, rld[i].mode))
+ {
+ int nr = HARD_REGNO_NREGS (regno, rld[i].mode);
+ int ok = 1, nri;
+
+ for (nri = 1; nri < nr; nri ++)
+ if (! TEST_HARD_REG_BIT (reg_class_contents[rld[i].class], regno + nri))
+ ok = 0;
+
+ if (ok)
+ rld[i].reg_rtx = dest;
+ }
}
return retval;
@@ -4338,9 +4391,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
accepts a memory operand with constant address. */
static int
-alternative_allows_memconst (constraint, altnum)
- const char *constraint;
- int altnum;
+alternative_allows_memconst (const char *constraint, int altnum)
{
int c;
/* Skip alternatives before the one requested. */
@@ -4351,8 +4402,9 @@ alternative_allows_memconst (constraint, altnum)
}
/* Scan the requested alternative for 'm' or 'o'.
If one of them is present, this alternative accepts memory constants. */
- while ((c = *constraint++) && c != ',' && c != '#')
- if (c == 'm' || c == 'o' || EXTRA_MEMORY_CONSTRAINT (c))
+ for (; (c = *constraint) && c != ',' && c != '#';
+ constraint += CONSTRAINT_LEN (c, constraint))
+ if (c == 'm' || c == 'o' || EXTRA_MEMORY_CONSTRAINT (c, constraint))
return 1;
return 0;
}
@@ -4380,15 +4432,9 @@ alternative_allows_memconst (constraint, altnum)
result of find_reloads_address. */
static rtx
-find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest, insn,
- address_reloaded)
- rtx x;
- int opnum;
- enum reload_type type;
- int ind_levels;
- int is_set_dest;
- rtx insn;
- int *address_reloaded;
+find_reloads_toplev (rtx x, int opnum, enum reload_type type,
+ int ind_levels, int is_set_dest, rtx insn,
+ int *address_reloaded)
{
RTX_CODE code = GET_CODE (x);
@@ -4532,9 +4578,7 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest, insn,
This mem ref is not shared with anything. */
static rtx
-make_memloc (ad, regno)
- rtx ad;
- int regno;
+make_memloc (rtx ad, int regno)
{
/* We must rerun eliminate_regs, in case the elimination
offsets have changed. */
@@ -4557,14 +4601,11 @@ make_memloc (ad, regno)
}
/* Returns true if AD could be turned into a valid memory reference
- to mode MODE by reloading the part pointed to by PART into a
+ to mode MODE by reloading the part pointed to by PART into a
register. */
static int
-maybe_memory_address_p (mode, ad, part)
- enum machine_mode mode;
- rtx ad;
- rtx *part;
+maybe_memory_address_p (enum machine_mode mode, rtx ad, rtx *part)
{
int retv;
rtx tem = *part;
@@ -4602,15 +4643,9 @@ maybe_memory_address_p (mode, ad, part)
to a hard register, and frame pointer elimination. */
static int
-find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
- enum machine_mode mode;
- rtx *memrefloc;
- rtx ad;
- rtx *loc;
- int opnum;
- enum reload_type type;
- int ind_levels;
- rtx insn;
+find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
+ rtx *loc, int opnum, enum reload_type type,
+ int ind_levels, rtx insn)
{
int regno;
int removed_and = 0;
@@ -4858,7 +4893,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
of it.
Handle all base registers here, not just fp/ap/sp, because on some
- targets (namely Sparc) we can also get invalid addresses from preventive
+ targets (namely SPARC) we can also get invalid addresses from preventive
subreg big-endian corrections made by find_reloads_toplev.
If we decide to do something, it must be that `double_reg_address_ok'
@@ -4873,7 +4908,15 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
&& GET_CODE (XEXP (ad, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (ad, 0), 0)) == REG
&& REGNO (XEXP (XEXP (ad, 0), 0)) < FIRST_PSEUDO_REGISTER
- && REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 0), mode)
+ && (REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 0), mode)
+ || XEXP (XEXP (ad, 0), 0) == frame_pointer_rtx
+#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+ || XEXP (XEXP (ad, 0), 0) == hard_frame_pointer_rtx
+#endif
+#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ || XEXP (XEXP (ad, 0), 0) == arg_pointer_rtx
+#endif
+ || XEXP (XEXP (ad, 0), 0) == stack_pointer_rtx)
&& ! maybe_memory_address_p (mode, ad, &XEXP (XEXP (ad, 0), 1)))
{
*loc = ad = gen_rtx_PLUS (GET_MODE (ad),
@@ -4893,7 +4936,15 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
&& GET_CODE (XEXP (ad, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (ad, 0), 1)) == REG
&& REGNO (XEXP (XEXP (ad, 0), 1)) < FIRST_PSEUDO_REGISTER
- && REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 1), mode)
+ && (REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 1), mode)
+ || XEXP (XEXP (ad, 0), 1) == frame_pointer_rtx
+#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+ || XEXP (XEXP (ad, 0), 1) == hard_frame_pointer_rtx
+#endif
+#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ || XEXP (XEXP (ad, 0), 1) == arg_pointer_rtx
+#endif
+ || XEXP (XEXP (ad, 0), 1) == stack_pointer_rtx)
&& ! maybe_memory_address_p (mode, ad, &XEXP (XEXP (ad, 0), 0)))
{
*loc = ad = gen_rtx_PLUS (GET_MODE (ad),
@@ -4963,9 +5014,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
front of it for pseudos that we have to replace with stack slots. */
static rtx
-subst_reg_equivs (ad, insn)
- rtx ad;
- rtx insn;
+subst_reg_equivs (rtx ad, rtx insn)
{
RTX_CODE code = GET_CODE (ad);
int i;
@@ -5036,8 +5085,7 @@ subst_reg_equivs (ad, insn)
This routine assumes both inputs are already in canonical form. */
rtx
-form_sum (x, y)
- rtx x, y;
+form_sum (rtx x, rtx y)
{
rtx tem;
enum machine_mode mode = GET_MODE (x);
@@ -5091,8 +5139,7 @@ form_sum (x, y)
In all other cases, return ADDR. */
static rtx
-subst_indexed_address (addr)
- rtx addr;
+subst_indexed_address (rtx addr)
{
rtx op0 = 0, op1 = 0, op2 = 0;
rtx tem;
@@ -5149,17 +5196,15 @@ subst_indexed_address (addr)
RELOADNUM is the reload number. */
static void
-update_auto_inc_notes (insn, regno, reloadnum)
- rtx insn ATTRIBUTE_UNUSED;
- int regno ATTRIBUTE_UNUSED;
- int reloadnum ATTRIBUTE_UNUSED;
+update_auto_inc_notes (rtx insn ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED,
+ int reloadnum ATTRIBUTE_UNUSED)
{
#ifdef AUTO_INC_DEC
rtx link;
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_INC
- && REGNO (XEXP (link, 0)) == regno)
+ && (int) REGNO (XEXP (link, 0)) == regno)
push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
#endif
}
@@ -5189,15 +5234,9 @@ update_auto_inc_notes (insn, regno, reloadnum)
could have addressing modes that this does not handle right. */
static int
-find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
- enum machine_mode mode;
- rtx x;
- int context;
- rtx *loc;
- int opnum;
- enum reload_type type;
- int ind_levels;
- rtx insn;
+find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
+ rtx *loc, int opnum, enum reload_type type,
+ int ind_levels, rtx insn)
{
RTX_CODE code = GET_CODE (x);
@@ -5240,7 +5279,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
GET_MODE (orig_op1))));
}
/* Plus in the index register may be created only as a result of
- register remateralization for expresion like &localvar*4. Reload it.
+ register remateralization for expression like &localvar*4. Reload it.
It may be possible to combine the displacement on the outer level,
but it is probably not worthwhile to do so. */
if (context)
@@ -5366,7 +5405,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
/* Handle a register that is equivalent to a memory location
which cannot be addressed directly. */
- if (reg_equiv_memory_loc[regno] != 0
+ if (reg_equiv_memory_loc[regno] != 0
&& (reg_equiv_address[regno] != 0
|| num_not_at_initial_offset))
{
@@ -5664,7 +5703,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
needless copies if SUBREG_REG is multi-word. */
if (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
{
- int regno = subreg_regno (x);
+ int regno ATTRIBUTE_UNUSED = subreg_regno (x);
if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
: REGNO_MODE_OK_FOR_BASE_P (regno, mode)))
@@ -5730,14 +5769,9 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
supports. */
static void
-find_reloads_address_part (x, loc, class, mode, opnum, type, ind_levels)
- rtx x;
- rtx *loc;
- enum reg_class class;
- enum machine_mode mode;
- int opnum;
- enum reload_type type;
- int ind_levels;
+find_reloads_address_part (rtx x, rtx *loc, enum reg_class class,
+ enum machine_mode mode, int opnum,
+ enum reload_type type, int ind_levels)
{
if (CONSTANT_P (x)
&& (! LEGITIMATE_CONSTANT_P (x)
@@ -5790,14 +5824,8 @@ find_reloads_address_part (x, loc, class, mode, opnum, type, ind_levels)
stack slots. */
static rtx
-find_reloads_subreg_address (x, force_replace, opnum, type,
- ind_levels, insn)
- rtx x;
- int force_replace;
- int opnum;
- enum reload_type type;
- int ind_levels;
- rtx insn;
+find_reloads_subreg_address (rtx x, int force_replace, int opnum,
+ enum reload_type type, int ind_levels, rtx insn)
{
int regno = REGNO (SUBREG_REG (x));
@@ -5819,9 +5847,16 @@ find_reloads_subreg_address (x, force_replace, opnum, type,
if (force_replace
|| ! rtx_equal_p (tem, reg_equiv_mem[regno]))
{
- int offset = SUBREG_BYTE (x);
unsigned outer_size = GET_MODE_SIZE (GET_MODE (x));
unsigned inner_size = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
+ int offset;
+
+ /* For big-endian paradoxical subregs, SUBREG_BYTE does not
+ hold the correct (negative) byte offset. */
+ if (BYTES_BIG_ENDIAN && outer_size > inner_size)
+ offset = inner_size - outer_size;
+ else
+ offset = SUBREG_BYTE (x);
XEXP (tem, 0) = plus_constant (XEXP (tem, 0), offset);
PUT_MODE (tem, GET_MODE (x));
@@ -5876,8 +5911,7 @@ find_reloads_subreg_address (x, force_replace, opnum, type,
Return the rtx that X translates into; usually X, but modified. */
void
-subst_reloads (insn)
- rtx insn;
+subst_reloads (rtx insn)
{
int i;
@@ -5927,7 +5961,7 @@ subst_reloads (insn)
do the wrong thing if RELOADREG is multi-word. RELOADREG
will always be a REG here. */
if (GET_MODE (reloadreg) != r->mode && r->mode != VOIDmode)
- reloadreg = gen_rtx_REG (r->mode, REGNO (reloadreg));
+ reloadreg = reload_adjust_reg_for_mode (reloadreg, r->mode);
/* If we are putting this into a SUBREG and RELOADREG is a
SUBREG, we would be making nested SUBREGs, so we have to fix
@@ -5967,8 +6001,7 @@ subst_reloads (insn)
copies to locations in Y, a copy of X. */
void
-copy_replacements (x, y)
- rtx x, y;
+copy_replacements (rtx x, rtx y)
{
/* We can't support X being a SUBREG because we might then need to know its
location if something inside it was replaced. */
@@ -5979,10 +6012,7 @@ copy_replacements (x, y)
}
static void
-copy_replacements_1 (px, py, orig_replacements)
- rtx *px;
- rtx *py;
- int orig_replacements;
+copy_replacements_1 (rtx *px, rtx *py, int orig_replacements)
{
int i, j;
rtx x, y;
@@ -6029,9 +6059,7 @@ copy_replacements_1 (px, py, orig_replacements)
/* Change any replacements being done to *X to be done to *Y. */
void
-move_replacements (x, y)
- rtx *x;
- rtx *y;
+move_replacements (rtx *x, rtx *y)
{
int i;
@@ -6049,8 +6077,7 @@ move_replacements (x, y)
Otherwise, return *LOC. */
rtx
-find_replacement (loc)
- rtx *loc;
+find_replacement (rtx *loc)
{
struct replacement *r;
@@ -6120,10 +6147,8 @@ find_replacement (loc)
look at equivalences for pseudos that didn't get hard registers. */
int
-refers_to_regno_for_reload_p (regno, endregno, x, loc)
- unsigned int regno, endregno;
- rtx x;
- rtx *loc;
+refers_to_regno_for_reload_p (unsigned int regno, unsigned int endregno,
+ rtx x, rtx *loc)
{
int i;
unsigned int r;
@@ -6246,8 +6271,7 @@ refers_to_regno_for_reload_p (regno, endregno, x, loc)
that we look at equivalences for pseudos that didn't get hard registers. */
int
-reg_overlap_mentioned_for_reload_p (x, in)
- rtx x, in;
+reg_overlap_mentioned_for_reload_p (rtx x, rtx in)
{
int regno, endregno;
@@ -6290,8 +6314,22 @@ reg_overlap_mentioned_for_reload_p (x, in)
|| GET_CODE (x) == CC0)
return reg_mentioned_p (x, in);
else if (GET_CODE (x) == PLUS)
- return (reg_overlap_mentioned_for_reload_p (XEXP (x, 0), in)
- || reg_overlap_mentioned_for_reload_p (XEXP (x, 1), in));
+ {
+ /* We actually want to know if X is mentioned somewhere inside IN.
+ We must not say that (plus (sp) (const_int 124)) is in
+ (plus (sp) (const_int 64)), since that can lead to incorrect reload
+ allocation when spuriously changing a RELOAD_FOR_OUTPUT_ADDRESS
+ into a RELOAD_OTHER on behalf of another RELOAD_OTHER. */
+ while (GET_CODE (in) == MEM)
+ in = XEXP (in, 0);
+ if (GET_CODE (in) == REG)
+ return 0;
+ else if (GET_CODE (in) == PLUS)
+ return (reg_overlap_mentioned_for_reload_p (x, XEXP (in, 0))
+ || reg_overlap_mentioned_for_reload_p (x, XEXP (in, 1)));
+ else return (reg_overlap_mentioned_for_reload_p (XEXP (x, 0), in)
+ || reg_overlap_mentioned_for_reload_p (XEXP (x, 1), in));
+ }
else
abort ();
@@ -6305,8 +6343,7 @@ reg_overlap_mentioned_for_reload_p (x, in)
registers. */
int
-refers_to_mem_for_reload_p (x)
- rtx x;
+refers_to_mem_for_reload_p (rtx x)
{
const char *fmt;
int i;
@@ -6356,14 +6393,8 @@ refers_to_mem_for_reload_p (x)
as if it were a constant except that sp is required to be unchanging. */
rtx
-find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
- rtx goal;
- rtx insn;
- enum reg_class class;
- int other;
- short *reload_reg_p;
- int goalreg;
- enum machine_mode mode;
+find_equiv_reg (rtx goal, rtx insn, enum reg_class class, int other,
+ short *reload_reg_p, int goalreg, enum machine_mode mode)
{
rtx p = insn;
rtx goaltry, valtry, value, where;
@@ -6376,6 +6407,7 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
int need_stable_sp = 0;
int nregs;
int valuenregs;
+ int num = 0;
if (goal == 0)
regno = goalreg;
@@ -6416,6 +6448,7 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
else
return 0;
+ num = 0;
/* Scan insns back from INSN, looking for one that copies
a value into or out of GOAL.
Stop and give up if we reach a label. */
@@ -6423,7 +6456,9 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
while (1)
{
p = PREV_INSN (p);
- if (p == 0 || GET_CODE (p) == CODE_LABEL)
+ num++;
+ if (p == 0 || GET_CODE (p) == CODE_LABEL
+ || num > PARAM_VALUE (PARAM_MAX_RELOAD_SEARCH_INSNS))
return 0;
if (GET_CODE (p) == INSN
@@ -6811,8 +6846,7 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
The value is always positive. */
static int
-find_inc_amount (x, inced)
- rtx x, inced;
+find_inc_amount (rtx x, rtx inced)
{
enum rtx_code code = GET_CODE (x);
const char *fmt;
@@ -6867,11 +6901,8 @@ find_inc_amount (x, inced)
If SETS is nonzero, also consider SETs. */
int
-regno_clobbered_p (regno, insn, mode, sets)
- unsigned int regno;
- rtx insn;
- enum machine_mode mode;
- int sets;
+regno_clobbered_p (unsigned int regno, rtx insn, enum machine_mode mode,
+ int sets)
{
unsigned int nregs = HARD_REGNO_NREGS (regno, mode);
unsigned int endregno = regno + nregs;
@@ -6907,6 +6938,24 @@ regno_clobbered_p (regno, insn, mode, sets)
return 0;
}
+/* Find the low part, with mode MODE, of a hard regno RELOADREG. */
+rtx
+reload_adjust_reg_for_mode (rtx reloadreg, enum machine_mode mode)
+{
+ int regno;
+
+ if (GET_MODE (reloadreg) == mode)
+ return reloadreg;
+
+ regno = REGNO (reloadreg);
+
+ if (WORDS_BIG_ENDIAN)
+ regno += HARD_REGNO_NREGS (regno, GET_MODE (reloadreg))
+ - HARD_REGNO_NREGS (regno, mode);
+
+ return gen_rtx_REG (mode, regno);
+}
+
static const char *const reload_when_needed_name[] =
{
"RELOAD_FOR_INPUT",
@@ -6927,8 +6976,7 @@ static const char * const reg_class_names[] = REG_CLASS_NAMES;
/* These functions are used to print the variables set by 'find_reloads' */
void
-debug_reload_to_stream (f)
- FILE *f;
+debug_reload_to_stream (FILE *f)
{
int r;
const char *prefix;
@@ -7023,7 +7071,7 @@ debug_reload_to_stream (f)
}
void
-debug_reload ()
+debug_reload (void)
{
debug_reload_to_stream (stderr);
}
diff --git a/contrib/gcc/reload.h b/contrib/gcc/reload.h
index 046322459124..9a5e33c843a2 100644
--- a/contrib/gcc/reload.h
+++ b/contrib/gcc/reload.h
@@ -1,6 +1,6 @@
/* Communication between reload.c and reload1.c.
Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1997, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -44,7 +44,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define MEMORY_MOVE_COST(MODE,CLASS,IN) 4
#endif
#endif
-extern int memory_move_secondary_cost PARAMS ((enum machine_mode, enum reg_class, int));
+extern int memory_move_secondary_cost (enum machine_mode, enum reg_class, int);
/* Maximum number of reloads we can need. */
#define MAX_RELOADS (2 * MAX_RECOG_OPERANDS * (MAX_REGS_PER_ADDRESS + 1))
@@ -68,14 +68,14 @@ extern int memory_move_secondary_cost PARAMS ((enum machine_mode, enum reg_class
reloads; usually secondary reloads
RELOAD_OTHER none of the above, usually multiple uses
RELOAD_FOR_OTHER_ADDRESS reload for part of the address of an input
- that is marked RELOAD_OTHER.
+ that is marked RELOAD_OTHER.
This used to be "enum reload_when_needed" but some debuggers have trouble
with an enum tag and variable of the same name. */
enum reload_type
{
- RELOAD_FOR_INPUT, RELOAD_FOR_OUTPUT, RELOAD_FOR_INSN,
+ RELOAD_FOR_INPUT, RELOAD_FOR_OUTPUT, RELOAD_FOR_INSN,
RELOAD_FOR_INPUT_ADDRESS, RELOAD_FOR_INPADDR_ADDRESS,
RELOAD_FOR_OUTPUT_ADDRESS, RELOAD_FOR_OUTADDR_ADDRESS,
RELOAD_FOR_OPERAND_ADDRESS, RELOAD_FOR_OPADDR_ADDR,
@@ -147,7 +147,7 @@ struct reload
addressing an output, for addressing a non-reloaded mem ref, or for
unspecified purposes (i.e., more than one of the above). */
enum reload_type when_needed;
-
+
/* Nonzero for an optional reload. Optional reloads are ignored unless the
value is already sitting in a register. */
unsigned int optional:1;
@@ -203,7 +203,7 @@ struct needs
/* This structure describes instructions which are relevant for reload.
Apart from all regular insns, this also includes CODE_LABELs, since they
must be examined for register elimination. */
-struct insn_chain
+struct insn_chain
{
/* Links to the neighbor instructions. */
struct insn_chain *next, *prev;
@@ -247,141 +247,144 @@ struct insn_chain
extern struct insn_chain *reload_insn_chain;
/* Allocate a new insn_chain structure. */
-extern struct insn_chain *new_insn_chain PARAMS ((void));
+extern struct insn_chain *new_insn_chain (void);
-extern void compute_use_by_pseudos PARAMS ((HARD_REG_SET *, regset));
+extern void compute_use_by_pseudos (HARD_REG_SET *, regset);
#endif
/* Functions from reload.c: */
-/* Return a memory location that will be used to copy X in mode MODE.
+/* Return a memory location that will be used to copy X in mode MODE.
If we haven't already made a location for this mode in this insn,
call find_reloads_address on the location being returned. */
-extern rtx get_secondary_mem PARAMS ((rtx, enum machine_mode,
- int, enum reload_type));
+extern rtx get_secondary_mem (rtx, enum machine_mode, int, enum reload_type);
/* Clear any secondary memory locations we've made. */
-extern void clear_secondary_mem PARAMS ((void));
+extern void clear_secondary_mem (void);
/* Transfer all replacements that used to be in reload FROM to be in
reload TO. */
-extern void transfer_replacements PARAMS ((int, int));
+extern void transfer_replacements (int, int);
/* IN_RTX is the value loaded by a reload that we now decided to inherit,
or a subpart of it. If we have any replacements registered for IN_RTX,
- chancel the reloads that were supposed to load them.
- Return nonzero if we chanceled any reloads. */
-extern int remove_address_replacements PARAMS ((rtx in_rtx));
+ cancel the reloads that were supposed to load them.
+ Return nonzero if we canceled any reloads. */
+extern int remove_address_replacements (rtx in_rtx);
/* Like rtx_equal_p except that it allows a REG and a SUBREG to match
if they are the same hard reg, and has special hacks for
autoincrement and autodecrement. */
-extern int operands_match_p PARAMS ((rtx, rtx));
+extern int operands_match_p (rtx, rtx);
/* Return 1 if altering OP will not modify the value of CLOBBER. */
-extern int safe_from_earlyclobber PARAMS ((rtx, rtx));
+extern int safe_from_earlyclobber (rtx, rtx);
/* Search the body of INSN for values that need reloading and record them
with push_reload. REPLACE nonzero means record also where the values occur
so that subst_reloads can be used. */
-extern int find_reloads PARAMS ((rtx, int, int, int, short *));
+extern int find_reloads (rtx, int, int, int, short *);
/* Compute the sum of X and Y, making canonicalizations assumed in an
address, namely: sum constant integers, surround the sum of two
constants with a CONST, put the constant as the second operand, and
group the constant on the outermost sum. */
-extern rtx form_sum PARAMS ((rtx, rtx));
+extern rtx form_sum (rtx, rtx);
/* Substitute into the current INSN the registers into which we have reloaded
the things that need reloading. */
-extern void subst_reloads PARAMS ((rtx));
+extern void subst_reloads (rtx);
/* Make a copy of any replacements being done into X and move those copies
to locations in Y, a copy of X. We only look at the highest level of
the RTL. */
-extern void copy_replacements PARAMS ((rtx, rtx));
+extern void copy_replacements (rtx, rtx);
/* Change any replacements being done to *X to be done to *Y */
-extern void move_replacements PARAMS ((rtx *x, rtx *y));
+extern void move_replacements (rtx *x, rtx *y);
/* If LOC was scheduled to be replaced by something, return the replacement.
Otherwise, return *LOC. */
-extern rtx find_replacement PARAMS ((rtx *));
+extern rtx find_replacement (rtx *);
/* Return nonzero if register in range [REGNO, ENDREGNO)
appears either explicitly or implicitly in X
other than being stored into. */
-extern int refers_to_regno_for_reload_p PARAMS ((unsigned int, unsigned int,
- rtx, rtx *));
+extern int refers_to_regno_for_reload_p (unsigned int, unsigned int,
+ rtx, rtx *);
/* Nonzero if modifying X will affect IN. */
-extern int reg_overlap_mentioned_for_reload_p PARAMS ((rtx, rtx));
+extern int reg_overlap_mentioned_for_reload_p (rtx, rtx);
/* Return nonzero if anything in X contains a MEM. Look also for pseudo
registers. */
-extern int refers_to_mem_for_reload_p PARAMS ((rtx));
+extern int refers_to_mem_for_reload_p (rtx);
/* Check the insns before INSN to see if there is a suitable register
containing the same value as GOAL. */
-extern rtx find_equiv_reg PARAMS ((rtx, rtx, enum reg_class, int, short *,
- int, enum machine_mode));
+extern rtx find_equiv_reg (rtx, rtx, enum reg_class, int, short *,
+ int, enum machine_mode);
/* Return 1 if register REGNO is the subject of a clobber in insn INSN. */
-extern int regno_clobbered_p PARAMS ((unsigned int, rtx, enum machine_mode,
- int));
+extern int regno_clobbered_p (unsigned int, rtx, enum machine_mode, int);
/* Return 1 if X is an operand of an insn that is being earlyclobbered. */
-extern int earlyclobber_operand_p PARAMS ((rtx));
+extern int earlyclobber_operand_p (rtx);
/* Record one reload that needs to be performed. */
-extern int push_reload PARAMS ((rtx, rtx, rtx *, rtx *, enum reg_class,
- enum machine_mode, enum machine_mode,
- int, int, int, enum reload_type));
+extern int push_reload (rtx, rtx, rtx *, rtx *, enum reg_class,
+ enum machine_mode, enum machine_mode,
+ int, int, int, enum reload_type);
-/* Functions in reload1.c: */
+/* Functions in postreload.c: */
+extern void reload_cse_regs (rtx);
-extern void reload_cse_regs PARAMS ((rtx));
-extern int reloads_conflict PARAMS ((int, int));
+/* Functions in reload1.c: */
+extern int reloads_conflict (int, int);
/* Initialize the reload pass once per compilation. */
-extern void init_reload PARAMS ((void));
+extern void init_reload (void);
/* The reload pass itself. */
-extern int reload PARAMS ((rtx, int));
+extern int reload (rtx, int);
/* Mark the slots in regs_ever_live for the hard regs
used by pseudo-reg number REGNO. */
-extern void mark_home_live PARAMS ((int));
+extern void mark_home_live (int);
/* Scan X and replace any eliminable registers (such as fp) with a
replacement (such as sp), plus an offset. */
-extern rtx eliminate_regs PARAMS ((rtx, enum machine_mode, rtx));
+extern rtx eliminate_regs (rtx, enum machine_mode, rtx);
/* Emit code to perform a reload from IN (which may be a reload register) to
OUT (which may also be a reload register). IN or OUT is from operand
OPNUM with reload type TYPE. */
-extern rtx gen_reload PARAMS ((rtx, rtx, int, enum reload_type));
+extern rtx gen_reload (rtx, rtx, int, enum reload_type);
/* Deallocate the reload register used by reload number R. */
-extern void deallocate_reload_reg PARAMS ((int r));
+extern void deallocate_reload_reg (int r);
/* Functions in caller-save.c: */
/* Initialize for caller-save. */
-extern void init_caller_save PARAMS ((void));
+extern void init_caller_save (void);
/* Initialize save areas by showing that we haven't allocated any yet. */
-extern void init_save_areas PARAMS ((void));
+extern void init_save_areas (void);
/* Allocate save areas for any hard registers that might need saving. */
-extern void setup_save_areas PARAMS ((void));
+extern void setup_save_areas (void);
/* Find the places where hard regs are live across calls and save them. */
-extern void save_call_clobbered_regs PARAMS ((void));
+extern void save_call_clobbered_regs (void);
/* Replace (subreg (reg)) with the appropriate (reg) for any operands. */
-extern void cleanup_subreg_operands PARAMS ((rtx));
+extern void cleanup_subreg_operands (rtx);
/* Debugging support. */
-extern void debug_reload_to_stream PARAMS ((FILE *));
-extern void debug_reload PARAMS ((void));
+extern void debug_reload_to_stream (FILE *);
+extern void debug_reload (void);
+
+/* Compute the actual register we should reload to, in case we're
+ reloading to/from a register that is wider than a word. */
+extern rtx reload_adjust_reg_for_mode (rtx, enum machine_mode);
diff --git a/contrib/gcc/reload1.c b/contrib/gcc/reload1.c
index 3000f617398f..1055de8059a2 100644
--- a/contrib/gcc/reload1.c
+++ b/contrib/gcc/reload1.c
@@ -1,6 +1,6 @@
/* Reload pseudo regs into hard regs for insns that require hard regs.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "machmode.h"
#include "hard-reg-set.h"
@@ -37,7 +39,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "reload.h"
#include "recog.h"
#include "output.h"
-#include "cselib.h"
#include "real.h"
#include "toplev.h"
#include "except.h"
@@ -76,14 +77,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
reload needs, spilling, assigning reload registers to use for
fixing up each insn, and generating the new insns to copy values
into the reload registers. */
-
-#ifndef REGISTER_MOVE_COST
-#define REGISTER_MOVE_COST(m, x, y) 2
-#endif
-
-#ifndef LOCAL_REGNO
-#define LOCAL_REGNO(REGNO) 0
-#endif
/* During reload_as_needed, element N contains a REG rtx for the hard reg
into which reg N has been reloaded (perhaps for a previous insn). */
@@ -145,6 +138,11 @@ static HARD_REG_SET reg_reloaded_valid;
This is only valid if reg_reloaded_contents is set and valid. */
static HARD_REG_SET reg_reloaded_dead;
+/* Indicate whether the register's current value is one that is not
+ safe to retain across a call, even for registers that are normally
+ call-saved. */
+static HARD_REG_SET reg_reloaded_call_part_clobbered;
+
/* Number of spill-regs so far; number of valid elements of spill_regs. */
static int n_spills;
@@ -284,12 +282,6 @@ static char *reload_insn_firstobj;
examine. */
struct insn_chain *reload_insn_chain;
-#ifdef TREE_CODE
-extern tree current_function_decl;
-#else
-extern union tree_node *current_function_decl;
-#endif
-
/* List of all insns needing reloads. */
static struct insn_chain *insns_need_reload;
@@ -302,12 +294,12 @@ struct elim_table
{
int from; /* Register number to be eliminated. */
int to; /* Register number used as replacement. */
- int initial_offset; /* Initial difference between values. */
- int can_eliminate; /* Non-zero if this elimination can be done. */
+ HOST_WIDE_INT initial_offset; /* Initial difference between values. */
+ int can_eliminate; /* Nonzero if this elimination can be done. */
int can_eliminate_previous; /* Value of CAN_ELIMINATE in previous scan over
insns made by reload. */
- int offset; /* Current offset between the two regs. */
- int previous_offset; /* Offset at end of previous insn. */
+ HOST_WIDE_INT offset; /* Current offset between the two regs. */
+ HOST_WIDE_INT previous_offset;/* Offset at end of previous insn. */
int ref_outside_mem; /* "to" has been referenced outside a MEM. */
rtx from_rtx; /* REG rtx for the register to be eliminated.
We cannot simply compare the number since
@@ -361,110 +353,83 @@ static int num_eliminable_invariants;
static int first_label_num;
static char *offsets_known_at;
-static int (*offsets_at)[NUM_ELIMINABLE_REGS];
+static HOST_WIDE_INT (*offsets_at)[NUM_ELIMINABLE_REGS];
/* Number of labels in the current function. */
static int num_labels;
-static void replace_pseudos_in_call_usage PARAMS ((rtx *,
- enum machine_mode,
- rtx));
-static void maybe_fix_stack_asms PARAMS ((void));
-static void copy_reloads PARAMS ((struct insn_chain *));
-static void calculate_needs_all_insns PARAMS ((int));
-static int find_reg PARAMS ((struct insn_chain *, int));
-static void find_reload_regs PARAMS ((struct insn_chain *));
-static void select_reload_regs PARAMS ((void));
-static void delete_caller_save_insns PARAMS ((void));
-
-static void spill_failure PARAMS ((rtx, enum reg_class));
-static void count_spilled_pseudo PARAMS ((int, int, int));
-static void delete_dead_insn PARAMS ((rtx));
-static void alter_reg PARAMS ((int, int));
-static void set_label_offsets PARAMS ((rtx, rtx, int));
-static void check_eliminable_occurrences PARAMS ((rtx));
-static void elimination_effects PARAMS ((rtx, enum machine_mode));
-static int eliminate_regs_in_insn PARAMS ((rtx, int));
-static void update_eliminable_offsets PARAMS ((void));
-static void mark_not_eliminable PARAMS ((rtx, rtx, void *));
-static void set_initial_elim_offsets PARAMS ((void));
-static void verify_initial_elim_offsets PARAMS ((void));
-static void set_initial_label_offsets PARAMS ((void));
-static void set_offsets_for_label PARAMS ((rtx));
-static void init_elim_table PARAMS ((void));
-static void update_eliminables PARAMS ((HARD_REG_SET *));
-static void spill_hard_reg PARAMS ((unsigned int, int));
-static int finish_spills PARAMS ((int));
-static void ior_hard_reg_set PARAMS ((HARD_REG_SET *, HARD_REG_SET *));
-static void scan_paradoxical_subregs PARAMS ((rtx));
-static void count_pseudo PARAMS ((int));
-static void order_regs_for_reload PARAMS ((struct insn_chain *));
-static void reload_as_needed PARAMS ((int));
-static void forget_old_reloads_1 PARAMS ((rtx, rtx, void *));
-static int reload_reg_class_lower PARAMS ((const PTR, const PTR));
-static void mark_reload_reg_in_use PARAMS ((unsigned int, int,
- enum reload_type,
- enum machine_mode));
-static void clear_reload_reg_in_use PARAMS ((unsigned int, int,
- enum reload_type,
- enum machine_mode));
-static int reload_reg_free_p PARAMS ((unsigned int, int,
- enum reload_type));
-static int reload_reg_free_for_value_p PARAMS ((int, int, int,
- enum reload_type,
- rtx, rtx, int, int));
-static int free_for_value_p PARAMS ((int, enum machine_mode, int,
- enum reload_type, rtx, rtx,
- int, int));
-static int reload_reg_reaches_end_p PARAMS ((unsigned int, int,
- enum reload_type));
-static int allocate_reload_reg PARAMS ((struct insn_chain *, int,
- int));
-static int conflicts_with_override PARAMS ((rtx));
-static void failed_reload PARAMS ((rtx, int));
-static int set_reload_reg PARAMS ((int, int));
-static void choose_reload_regs_init PARAMS ((struct insn_chain *, rtx *));
-static void choose_reload_regs PARAMS ((struct insn_chain *));
-static void merge_assigned_reloads PARAMS ((rtx));
-static void emit_input_reload_insns PARAMS ((struct insn_chain *,
- struct reload *, rtx, int));
-static void emit_output_reload_insns PARAMS ((struct insn_chain *,
- struct reload *, int));
-static void do_input_reload PARAMS ((struct insn_chain *,
- struct reload *, int));
-static void do_output_reload PARAMS ((struct insn_chain *,
- struct reload *, int));
-static void emit_reload_insns PARAMS ((struct insn_chain *));
-static void delete_output_reload PARAMS ((rtx, int, int));
-static void delete_address_reloads PARAMS ((rtx, rtx));
-static void delete_address_reloads_1 PARAMS ((rtx, rtx, rtx));
-static rtx inc_for_reload PARAMS ((rtx, rtx, rtx, int));
-static void reload_cse_regs_1 PARAMS ((rtx));
-static int reload_cse_noop_set_p PARAMS ((rtx));
-static int reload_cse_simplify_set PARAMS ((rtx, rtx));
-static int reload_cse_simplify_operands PARAMS ((rtx, rtx));
-static void reload_combine PARAMS ((void));
-static void reload_combine_note_use PARAMS ((rtx *, rtx));
-static void reload_combine_note_store PARAMS ((rtx, rtx, void *));
-static void reload_cse_move2add PARAMS ((rtx));
-static void move2add_note_store PARAMS ((rtx, rtx, void *));
+static void replace_pseudos_in (rtx *, enum machine_mode, rtx);
+static void maybe_fix_stack_asms (void);
+static void copy_reloads (struct insn_chain *);
+static void calculate_needs_all_insns (int);
+static int find_reg (struct insn_chain *, int);
+static void find_reload_regs (struct insn_chain *);
+static void select_reload_regs (void);
+static void delete_caller_save_insns (void);
+
+static void spill_failure (rtx, enum reg_class);
+static void count_spilled_pseudo (int, int, int);
+static void delete_dead_insn (rtx);
+static void alter_reg (int, int);
+static void set_label_offsets (rtx, rtx, int);
+static void check_eliminable_occurrences (rtx);
+static void elimination_effects (rtx, enum machine_mode);
+static int eliminate_regs_in_insn (rtx, int);
+static void update_eliminable_offsets (void);
+static void mark_not_eliminable (rtx, rtx, void *);
+static void set_initial_elim_offsets (void);
+static void verify_initial_elim_offsets (void);
+static void set_initial_label_offsets (void);
+static void set_offsets_for_label (rtx);
+static void init_elim_table (void);
+static void update_eliminables (HARD_REG_SET *);
+static void spill_hard_reg (unsigned int, int);
+static int finish_spills (int);
+static void ior_hard_reg_set (HARD_REG_SET *, HARD_REG_SET *);
+static void scan_paradoxical_subregs (rtx);
+static void count_pseudo (int);
+static void order_regs_for_reload (struct insn_chain *);
+static void reload_as_needed (int);
+static void forget_old_reloads_1 (rtx, rtx, void *);
+static int reload_reg_class_lower (const void *, const void *);
+static void mark_reload_reg_in_use (unsigned int, int, enum reload_type,
+ enum machine_mode);
+static void clear_reload_reg_in_use (unsigned int, int, enum reload_type,
+ enum machine_mode);
+static int reload_reg_free_p (unsigned int, int, enum reload_type);
+static int reload_reg_free_for_value_p (int, int, int, enum reload_type,
+ rtx, rtx, int, int);
+static int free_for_value_p (int, enum machine_mode, int, enum reload_type,
+ rtx, rtx, int, int);
+static int reload_reg_reaches_end_p (unsigned int, int, enum reload_type);
+static int allocate_reload_reg (struct insn_chain *, int, int);
+static int conflicts_with_override (rtx);
+static void failed_reload (rtx, int);
+static int set_reload_reg (int, int);
+static void choose_reload_regs_init (struct insn_chain *, rtx *);
+static void choose_reload_regs (struct insn_chain *);
+static void merge_assigned_reloads (rtx);
+static void emit_input_reload_insns (struct insn_chain *, struct reload *,
+ rtx, int);
+static void emit_output_reload_insns (struct insn_chain *, struct reload *,
+ int);
+static void do_input_reload (struct insn_chain *, struct reload *, int);
+static void do_output_reload (struct insn_chain *, struct reload *, int);
+static void emit_reload_insns (struct insn_chain *);
+static void delete_output_reload (rtx, int, int);
+static void delete_address_reloads (rtx, rtx);
+static void delete_address_reloads_1 (rtx, rtx, rtx);
+static rtx inc_for_reload (rtx, rtx, rtx, int);
#ifdef AUTO_INC_DEC
-static void add_auto_inc_notes PARAMS ((rtx, rtx));
+static void add_auto_inc_notes (rtx, rtx);
#endif
-static void copy_eh_notes PARAMS ((rtx, rtx));
-static HOST_WIDE_INT sext_for_mode PARAMS ((enum machine_mode,
- HOST_WIDE_INT));
-static void failed_reload PARAMS ((rtx, int));
-static int set_reload_reg PARAMS ((int, int));
-static void reload_cse_simplify PARAMS ((rtx, rtx));
-void fixup_abnormal_edges PARAMS ((void));
-extern void dump_needs PARAMS ((struct insn_chain *));
+static void copy_eh_notes (rtx, rtx);
/* Initialize the reload pass once per compilation. */
void
-init_reload ()
+init_reload (void)
{
int i;
@@ -511,7 +476,7 @@ init_reload ()
/* Initialize obstack for our rtl allocation. */
gcc_obstack_init (&reload_obstack);
- reload_startobj = (char *) obstack_alloc (&reload_obstack, 0);
+ reload_startobj = obstack_alloc (&reload_obstack, 0);
INIT_REG_SET (&spilled_pseudos);
INIT_REG_SET (&pseudos_counted);
@@ -522,14 +487,13 @@ static struct insn_chain *unused_insn_chains = 0;
/* Allocate an empty insn_chain structure. */
struct insn_chain *
-new_insn_chain ()
+new_insn_chain (void)
{
struct insn_chain *c;
if (unused_insn_chains == 0)
{
- c = (struct insn_chain *)
- obstack_alloc (&reload_obstack, sizeof (struct insn_chain));
+ c = obstack_alloc (&reload_obstack, sizeof (struct insn_chain));
INIT_REG_SET (&c->live_throughout);
INIT_REG_SET (&c->dead_or_set);
}
@@ -549,9 +513,7 @@ new_insn_chain ()
allocated to pseudos in regset FROM. */
void
-compute_use_by_pseudos (to, from)
- HARD_REG_SET *to;
- regset from;
+compute_use_by_pseudos (HARD_REG_SET *to, regset from)
{
unsigned int regno;
@@ -583,10 +545,7 @@ compute_use_by_pseudos (to, from)
equivalences. */
static void
-replace_pseudos_in_call_usage (loc, mem_mode, usage)
- rtx *loc;
- enum machine_mode mem_mode;
- rtx usage;
+replace_pseudos_in (rtx *loc, enum machine_mode mem_mode, rtx usage)
{
rtx x = *loc;
enum rtx_code code;
@@ -608,7 +567,7 @@ replace_pseudos_in_call_usage (loc, mem_mode, usage)
if (x != *loc)
{
*loc = x;
- replace_pseudos_in_call_usage (loc, mem_mode, usage);
+ replace_pseudos_in (loc, mem_mode, usage);
return;
}
@@ -628,7 +587,7 @@ replace_pseudos_in_call_usage (loc, mem_mode, usage)
}
else if (code == MEM)
{
- replace_pseudos_in_call_usage (& XEXP (x, 0), GET_MODE (x), usage);
+ replace_pseudos_in (& XEXP (x, 0), GET_MODE (x), usage);
return;
}
@@ -636,10 +595,10 @@ replace_pseudos_in_call_usage (loc, mem_mode, usage)
fmt = GET_RTX_FORMAT (code);
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
if (*fmt == 'e')
- replace_pseudos_in_call_usage (&XEXP (x, i), mem_mode, usage);
+ replace_pseudos_in (&XEXP (x, i), mem_mode, usage);
else if (*fmt == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
- replace_pseudos_in_call_usage (& XVECEXP (x, i, j), mem_mode, usage);
+ replace_pseudos_in (& XVECEXP (x, i, j), mem_mode, usage);
}
@@ -667,9 +626,7 @@ static int failure;
and we must not do any more for this function. */
int
-reload (first, global)
- rtx first;
- int global;
+reload (rtx first, int global)
{
int i;
rtx insn;
@@ -681,11 +638,11 @@ reload (first, global)
failure = 0;
- reload_firstobj = (char *) obstack_alloc (&reload_obstack, 0);
+ reload_firstobj = obstack_alloc (&reload_obstack, 0);
/* Make sure that the last insn in the chain
is not something that needs reloading. */
- emit_note (NULL, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
/* Enable find_equiv_reg to distinguish insns made by reload. */
reload_first_uid = get_max_uid ();
@@ -696,8 +653,8 @@ reload (first, global)
#endif
/* We don't have a stack slot for any spill reg yet. */
- memset ((char *) spill_stack_slot, 0, sizeof spill_stack_slot);
- memset ((char *) spill_stack_slot_width, 0, sizeof spill_stack_slot_width);
+ memset (spill_stack_slot, 0, sizeof spill_stack_slot);
+ memset (spill_stack_slot_width, 0, sizeof spill_stack_slot_width);
/* Initialize the save area information for caller-save, in case some
are needed. */
@@ -717,6 +674,17 @@ reload (first, global)
if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
regs_ever_live[i] = 1;
+#ifdef NON_SAVING_SETJMP
+ /* A function that calls setjmp should save and restore all the
+ call-saved registers on a system where longjmp clobbers them. */
+ if (NON_SAVING_SETJMP && current_function_calls_setjmp)
+ {
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (! call_used_regs[i])
+ regs_ever_live[i] = 1;
+ }
+#endif
+
/* Find all the pseudo registers that didn't get hard regs
but do have known equivalent constants or memory slots.
These include parameters (known equivalent to parameter slots)
@@ -727,26 +695,22 @@ reload (first, global)
Record memory equivalents in reg_mem_equiv so they can
be substituted eventually by altering the REG-rtx's. */
- reg_equiv_constant = (rtx *) xcalloc (max_regno, sizeof (rtx));
- reg_equiv_mem = (rtx *) xcalloc (max_regno, sizeof (rtx));
- reg_equiv_init = (rtx *) xcalloc (max_regno, sizeof (rtx));
- reg_equiv_address = (rtx *) xcalloc (max_regno, sizeof (rtx));
- reg_max_ref_width = (unsigned int *) xcalloc (max_regno, sizeof (int));
- reg_old_renumber = (short *) xcalloc (max_regno, sizeof (short));
+ reg_equiv_constant = xcalloc (max_regno, sizeof (rtx));
+ reg_equiv_mem = xcalloc (max_regno, sizeof (rtx));
+ reg_equiv_init = xcalloc (max_regno, sizeof (rtx));
+ reg_equiv_address = xcalloc (max_regno, sizeof (rtx));
+ reg_max_ref_width = xcalloc (max_regno, sizeof (int));
+ reg_old_renumber = xcalloc (max_regno, sizeof (short));
memcpy (reg_old_renumber, reg_renumber, max_regno * sizeof (short));
- pseudo_forbidden_regs
- = (HARD_REG_SET *) xmalloc (max_regno * sizeof (HARD_REG_SET));
- pseudo_previous_regs
- = (HARD_REG_SET *) xcalloc (max_regno, sizeof (HARD_REG_SET));
+ pseudo_forbidden_regs = xmalloc (max_regno * sizeof (HARD_REG_SET));
+ pseudo_previous_regs = xcalloc (max_regno, sizeof (HARD_REG_SET));
CLEAR_HARD_REG_SET (bad_spill_regs_global);
/* Look for REG_EQUIV notes; record what each pseudo is equivalent to.
Also find all paradoxical subregs and find largest such for each pseudo.
On machines with small register classes, record hard registers that
- are used for user variables. These can never be used for spills.
- Also look for a "constant" REG_SETJMP. This means that all
- caller-saved registers must be marked live. */
+ are used for user variables. These can never be used for spills. */
num_eliminable_invariants = 0;
for (insn = first; insn; insn = NEXT_INSN (insn))
@@ -760,12 +724,6 @@ reload (first, global)
&& GET_MODE (insn) != VOIDmode)
PUT_MODE (insn, VOIDmode);
- if (GET_CODE (insn) == CALL_INSN
- && find_reg_note (insn, REG_SETJMP, NULL))
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (! call_used_regs[i])
- regs_ever_live[i] = 1;
-
if (set != 0 && GET_CODE (SET_DEST (set)) == REG)
{
rtx note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
@@ -789,8 +747,18 @@ reload (first, global)
that is not a legitimate memory operand. As later
stages of reload assume that all addresses found
in the reg_equiv_* arrays were originally legitimate,
- we ignore such REG_EQUIV notes. */
- if (memory_operand (x, VOIDmode))
+ we ignore such REG_EQUIV notes.
+
+ It also can happen that a REG_EQUIV note contains a MEM
+ that carries the /u flag, for example when GCSE turns
+ the load of a constant into a move from a pseudo that
+ already contains the constant and attaches a REG_EQUAL
+ note to the insn, which is later promoted to REQ_EQUIV
+ by local-alloc. If the destination pseudo happens not
+ to be assigned to a hard reg, it will be replaced by
+ the MEM as the destination of the move, thus generating
+ a store to a possibly read-only memory location. */
+ if (memory_operand (x, VOIDmode) && ! RTX_UNCHANGING_P (x))
{
/* Always unshare the equivalence, so we can
substitute into this insn without touching the
@@ -862,9 +830,7 @@ reload (first, global)
allocate would occasionally cause it to exceed the stack limit and
cause a core dump. */
offsets_known_at = xmalloc (num_labels);
- offsets_at
- = (int (*)[NUM_ELIMINABLE_REGS])
- xmalloc (num_labels * NUM_ELIMINABLE_REGS * sizeof (int));
+ offsets_at = xmalloc (num_labels * NUM_ELIMINABLE_REGS * sizeof (HOST_WIDE_INT));
/* Alter each pseudo-reg rtx to contain its hard reg number.
Assign stack slots to the pseudos that lack hard regs or equivalents.
@@ -996,7 +962,7 @@ reload (first, global)
{
save_call_clobbered_regs ();
/* That might have allocated new insn_chain structures. */
- reload_firstobj = (char *) obstack_alloc (&reload_obstack, 0);
+ reload_firstobj = obstack_alloc (&reload_obstack, 0);
}
calculate_needs_all_insns (global);
@@ -1192,9 +1158,8 @@ reload (first, global)
rtx *pnote;
if (GET_CODE (insn) == CALL_INSN)
- replace_pseudos_in_call_usage (& CALL_INSN_FUNCTION_USAGE (insn),
- VOIDmode,
- CALL_INSN_FUNCTION_USAGE (insn));
+ replace_pseudos_in (& CALL_INSN_FUNCTION_USAGE (insn),
+ VOIDmode, CALL_INSN_FUNCTION_USAGE (insn));
if ((GET_CODE (PATTERN (insn)) == USE
/* We mark with QImode USEs introduced by reload itself. */
@@ -1204,7 +1169,7 @@ reload (first, global)
&& (GET_CODE (XEXP (PATTERN (insn), 0)) != MEM
|| GET_MODE (XEXP (PATTERN (insn), 0)) != BLKmode
|| (GET_CODE (XEXP (XEXP (PATTERN (insn), 0), 0)) != SCRATCH
- && XEXP (XEXP (PATTERN (insn), 0), 0)
+ && XEXP (XEXP (PATTERN (insn), 0), 0)
!= stack_pointer_rtx))
&& (GET_CODE (XEXP (PATTERN (insn), 0)) != REG
|| ! REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))))
@@ -1213,6 +1178,13 @@ reload (first, global)
continue;
}
+ /* Some CLOBBERs may survive until here and still reference unassigned
+ pseudos with const equivalent, which may in turn cause ICE in later
+ passes if the reference remains in place. */
+ if (GET_CODE (PATTERN (insn)) == CLOBBER)
+ replace_pseudos_in (& XEXP (PATTERN (insn), 0),
+ VOIDmode, PATTERN (insn));
+
pnote = &REG_NOTES (insn);
while (*pnote != 0)
{
@@ -1291,6 +1263,14 @@ reload (first, global)
by this, so unshare everything here. */
unshare_all_rtl_again (first);
+#ifdef STACK_BOUNDARY
+ /* init_emit has set the alignment of the hard frame pointer
+ to STACK_BOUNDARY. It is very likely no longer valid if
+ the hard frame pointer was used for register allocation. */
+ if (!frame_pointer_needed)
+ REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT;
+#endif
+
return failure;
}
@@ -1302,7 +1282,7 @@ reload (first, global)
The whole thing is rather sick, I'm afraid. */
static void
-maybe_fix_stack_asms ()
+maybe_fix_stack_asms (void)
{
#ifdef STACK_REGS
const char *constraints[MAX_RECOG_OPERANDS];
@@ -1348,7 +1328,7 @@ maybe_fix_stack_asms ()
for (;;)
{
- char c = *p++;
+ char c = *p;
if (c == '\0' || c == ',' || c == '#')
{
@@ -1356,6 +1336,7 @@ maybe_fix_stack_asms ()
class, and reset the class. */
IOR_HARD_REG_SET (allowed, reg_class_contents[cls]);
cls = NO_REGS;
+ p++;
if (c == '#')
do {
c = *p++;
@@ -1386,13 +1367,14 @@ maybe_fix_stack_asms ()
break;
default:
- if (EXTRA_ADDRESS_CONSTRAINT (c))
+ if (EXTRA_ADDRESS_CONSTRAINT (c, p))
cls = (int) reg_class_subunion[cls]
[(int) MODE_BASE_REG_CLASS (VOIDmode)];
else
cls = (int) reg_class_subunion[cls]
- [(int) REG_CLASS_FROM_LETTER (c)];
+ [(int) REG_CLASS_FROM_CONSTRAINT (c, p)];
}
+ p += CONSTRAINT_LEN (c, p);
}
}
/* Those of the registers which are clobbered, but allowed by the
@@ -1413,30 +1395,27 @@ maybe_fix_stack_asms ()
/* Copy the global variables n_reloads and rld into the corresponding elts
of CHAIN. */
static void
-copy_reloads (chain)
- struct insn_chain *chain;
+copy_reloads (struct insn_chain *chain)
{
chain->n_reloads = n_reloads;
- chain->rld
- = (struct reload *) obstack_alloc (&reload_obstack,
- n_reloads * sizeof (struct reload));
+ chain->rld = obstack_alloc (&reload_obstack,
+ n_reloads * sizeof (struct reload));
memcpy (chain->rld, rld, n_reloads * sizeof (struct reload));
- reload_insn_firstobj = (char *) obstack_alloc (&reload_obstack, 0);
+ reload_insn_firstobj = obstack_alloc (&reload_obstack, 0);
}
/* Walk the chain of insns, and determine for each whether it needs reloads
and/or eliminations. Build the corresponding insns_need_reload list, and
set something_needs_elimination as appropriate. */
static void
-calculate_needs_all_insns (global)
- int global;
+calculate_needs_all_insns (int global)
{
struct insn_chain **pprev_reload = &insns_need_reload;
struct insn_chain *chain, *next = 0;
something_needs_elimination = 0;
- reload_insn_firstobj = (char *) obstack_alloc (&reload_obstack, 0);
+ reload_insn_firstobj = obstack_alloc (&reload_obstack, 0);
for (chain = reload_insn_chain; chain != 0; chain = next)
{
rtx insn = chain->insn;
@@ -1544,9 +1523,7 @@ calculate_needs_all_insns (global)
should be handled first. *P1 and *P2 are the reload numbers. */
static int
-reload_reg_class_lower (r1p, r2p)
- const PTR r1p;
- const PTR r2p;
+reload_reg_class_lower (const void *r1p, const void *r2p)
{
int r1 = *(const short *) r1p, r2 = *(const short *) r2p;
int t;
@@ -1588,8 +1565,7 @@ static int spill_add_cost[FIRST_PSEUDO_REGISTER];
/* Update the spill cost arrays, considering that pseudo REG is live. */
static void
-count_pseudo (reg)
- int reg;
+count_pseudo (int reg)
{
int freq = REG_FREQ (reg);
int r = reg_renumber[reg];
@@ -1615,8 +1591,7 @@ count_pseudo (reg)
contents of BAD_SPILL_REGS for the insn described by CHAIN. */
static void
-order_regs_for_reload (chain)
- struct insn_chain *chain;
+order_regs_for_reload (struct insn_chain *chain)
{
int i;
HARD_REG_SET used_by_pseudos;
@@ -1666,8 +1641,7 @@ static HARD_REG_SET used_spill_regs_local;
update SPILL_COST/SPILL_ADD_COST. */
static void
-count_spilled_pseudo (spilled, spilled_nregs, reg)
- int spilled, spilled_nregs, reg;
+count_spilled_pseudo (int spilled, int spilled_nregs, int reg)
{
int r = reg_renumber[reg];
int nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (reg));
@@ -1686,9 +1660,7 @@ count_spilled_pseudo (spilled, spilled_nregs, reg)
/* Find reload register to use for reload number ORDER. */
static int
-find_reg (chain, order)
- struct insn_chain *chain;
- int order;
+find_reg (struct insn_chain *chain, int order)
{
int rnum = reload_order[order];
struct reload *rl = rld + rnum;
@@ -1794,8 +1766,7 @@ find_reg (chain, order)
for a smaller class even though it belongs to that class. */
static void
-find_reload_regs (chain)
- struct insn_chain *chain;
+find_reload_regs (struct insn_chain *chain)
{
int i;
@@ -1855,7 +1826,7 @@ find_reload_regs (chain)
}
static void
-select_reload_regs ()
+select_reload_regs (void)
{
struct insn_chain *chain;
@@ -1868,7 +1839,7 @@ select_reload_regs ()
/* Delete all insns that were inserted by emit_caller_save_insns during
this iteration. */
static void
-delete_caller_save_insns ()
+delete_caller_save_insns (void)
{
struct insn_chain *c = reload_insn_chain;
@@ -1900,9 +1871,7 @@ delete_caller_save_insns ()
INSN should be one of the insns which needed this particular spill reg. */
static void
-spill_failure (insn, class)
- rtx insn;
- enum reg_class class;
+spill_failure (rtx insn, enum reg_class class)
{
static const char *const reg_class_names[] = REG_CLASS_NAMES;
if (asm_noperands (PATTERN (insn)) >= 0)
@@ -1920,8 +1889,7 @@ spill_failure (insn, class)
data that is dead in INSN. */
static void
-delete_dead_insn (insn)
- rtx insn;
+delete_dead_insn (rtx insn)
{
rtx prev = prev_real_insn (insn);
rtx prev_dest;
@@ -1949,9 +1917,7 @@ delete_dead_insn (insn)
can share one stack slot. */
static void
-alter_reg (i, from_reg)
- int i;
- int from_reg;
+alter_reg (int i, int from_reg)
{
/* When outputting an inline function, this can happen
for a reg that isn't actually used. */
@@ -2072,9 +2038,10 @@ alter_reg (i, from_reg)
/* If we have a decl for the original register, set it for the
memory. If this is a shared MEM, make a copy. */
- if (REGNO_DECL (i))
+ if (REG_EXPR (regno_reg_rtx[i])
+ && TREE_CODE_CLASS (TREE_CODE (REG_EXPR (regno_reg_rtx[i]))) == 'd')
{
- rtx decl = DECL_RTL_IF_SET (REGNO_DECL (i));
+ rtx decl = DECL_RTL_IF_SET (REG_EXPR (regno_reg_rtx[i]));
/* We can do this only for the DECLs home pseudo, not for
any copies of it, since otherwise when the stack slot
@@ -2085,7 +2052,7 @@ alter_reg (i, from_reg)
if (from_reg != -1 && spill_stack_slot[from_reg] == x)
x = copy_rtx (x);
- set_mem_expr (x, REGNO_DECL (i));
+ set_mem_attrs_from_reg (x, regno_reg_rtx[i]);
}
}
@@ -2098,8 +2065,7 @@ alter_reg (i, from_reg)
used by pseudo-reg number REGNO. */
void
-mark_home_live (regno)
- int regno;
+mark_home_live (int regno)
{
int i, lim;
@@ -2122,10 +2088,7 @@ mark_home_live (regno)
current offset. */
static void
-set_label_offsets (x, insn, initial_p)
- rtx x;
- rtx insn;
- int initial_p;
+set_label_offsets (rtx x, rtx insn, int initial_p)
{
enum rtx_code code = GET_CODE (x);
rtx tem;
@@ -2288,10 +2251,7 @@ set_label_offsets (x, insn, initial_p)
the proper thing. */
rtx
-eliminate_regs (x, mem_mode, insn)
- rtx x;
- enum machine_mode mem_mode;
- rtx insn;
+eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
{
enum rtx_code code = GET_CODE (x);
struct elim_table *ep;
@@ -2535,6 +2495,10 @@ eliminate_regs (x, mem_mode, insn)
case ABS:
case SQRT:
case FFS:
+ case CLZ:
+ case CTZ:
+ case POPCOUNT:
+ case PARITY:
new = eliminate_regs (XEXP (x, 0), mem_mode, insn);
if (new != XEXP (x, 0))
return gen_rtx_fmt_e (code, GET_MODE (x), new);
@@ -2545,7 +2509,7 @@ eliminate_regs (x, mem_mode, insn)
Convert (subreg (mem)) to (mem) if not paradoxical.
Also, if we have a non-paradoxical (subreg (pseudo)) and the
pseudo didn't get a hard reg, we must replace this with the
- eliminated version of the memory location because push_reloads
+ eliminated version of the memory location because push_reload
may do the replacement in certain circumstances. */
if (GET_CODE (SUBREG_REG (x)) == REG
&& (GET_MODE_SIZE (GET_MODE (x))
@@ -2572,7 +2536,7 @@ eliminate_regs (x, mem_mode, insn)
happen to the entire word. Moreover, it will use the
(reg:m2 R) later, expecting all bits to be preserved.
So if the number of words is the same, preserve the
- subreg so that push_reloads can see it. */
+ subreg so that push_reload can see it. */
&& ! ((x_size - 1) / UNITS_PER_WORD
== (new_size -1 ) / UNITS_PER_WORD)
#endif
@@ -2628,9 +2592,7 @@ eliminate_regs (x, mem_mode, insn)
if (new != XEXP (x, i) && ! copied)
{
rtx new_x = rtx_alloc (code);
- memcpy (new_x, x,
- (sizeof (*new_x) - sizeof (new_x->fld)
- + sizeof (new_x->fld[0]) * GET_RTX_LENGTH (code)));
+ memcpy (new_x, x, RTX_SIZE (code));
x = new_x;
copied = 1;
}
@@ -2649,10 +2611,7 @@ eliminate_regs (x, mem_mode, insn)
if (! copied)
{
rtx new_x = rtx_alloc (code);
- memcpy (new_x, x,
- (sizeof (*new_x) - sizeof (new_x->fld)
- + (sizeof (new_x->fld[0])
- * GET_RTX_LENGTH (code))));
+ memcpy (new_x, x, RTX_SIZE (code));
x = new_x;
copied = 1;
}
@@ -2672,10 +2631,7 @@ eliminate_regs (x, mem_mode, insn)
the mode of an enclosing MEM rtx, or VOIDmode if not within a MEM. */
static void
-elimination_effects (x, mem_mode)
- rtx x;
- enum machine_mode mem_mode;
-
+elimination_effects (rtx x, enum machine_mode mem_mode)
{
enum rtx_code code = GET_CODE (x);
struct elim_table *ep;
@@ -2766,6 +2722,10 @@ elimination_effects (x, mem_mode)
case ABS:
case SQRT:
case FFS:
+ case CLZ:
+ case CTZ:
+ case POPCOUNT:
+ case PARITY:
elimination_effects (XEXP (x, 0), mem_mode);
return;
@@ -2868,8 +2828,7 @@ elimination_effects (x, mem_mode)
eliminable. */
static void
-check_eliminable_occurrences (x)
- rtx x;
+check_eliminable_occurrences (rtx x)
{
const char *fmt;
int i;
@@ -2918,9 +2877,7 @@ check_eliminable_occurrences (x)
is returned. Otherwise, 1 is returned. */
static int
-eliminate_regs_in_insn (insn, replace)
- rtx insn;
- int replace;
+eliminate_regs_in_insn (rtx insn, int replace)
{
int icode = recog_memoized (insn);
rtx old_body = PATTERN (insn);
@@ -2928,7 +2885,7 @@ eliminate_regs_in_insn (insn, replace)
rtx old_set = single_set (insn);
rtx new_body;
int val = 0;
- int i, any_changes;
+ int i;
rtx substed_operand[MAX_RECOG_OPERANDS];
rtx orig_operand[MAX_RECOG_OPERANDS];
struct elim_table *ep;
@@ -2962,7 +2919,7 @@ eliminate_regs_in_insn (insn, replace)
{
rtx base = SET_SRC (old_set);
rtx base_insn = insn;
- int offset = 0;
+ HOST_WIDE_INT offset = 0;
while (base != ep->to_rtx)
{
@@ -3045,7 +3002,7 @@ eliminate_regs_in_insn (insn, replace)
&& REGNO (XEXP (SET_SRC (old_set), 0)) < FIRST_PSEUDO_REGISTER)
{
rtx reg = XEXP (SET_SRC (old_set), 0);
- int offset = INTVAL (XEXP (SET_SRC (old_set), 1));
+ HOST_WIDE_INT offset = INTVAL (XEXP (SET_SRC (old_set), 1));
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
if (ep->from_rtx == reg && ep->can_eliminate)
@@ -3103,7 +3060,6 @@ eliminate_regs_in_insn (insn, replace)
/* Eliminate all eliminable registers occurring in operands that
can be handled by reload. */
extract_insn (insn);
- any_changes = 0;
for (i = 0; i < recog_data.n_operands; i++)
{
orig_operand[i] = recog_data.operand[i];
@@ -3129,7 +3085,7 @@ eliminate_regs_in_insn (insn, replace)
substed_operand[i] = eliminate_regs (recog_data.operand[i], 0,
replace ? insn : NULL_RTX);
if (substed_operand[i] != orig_operand[i])
- val = any_changes = 1;
+ val = 1;
/* Terminate the search in check_eliminable_occurrences at
this point. */
*recog_data.operand_loc[i] = 0;
@@ -3267,7 +3223,7 @@ eliminate_regs_in_insn (insn, replace)
grow downward) for each elimination pair. */
static void
-update_eliminable_offsets ()
+update_eliminable_offsets (void)
{
struct elim_table *ep;
@@ -3295,10 +3251,7 @@ update_eliminable_offsets ()
the insns of the function. */
static void
-mark_not_eliminable (dest, x, data)
- rtx dest;
- rtx x;
- void *data ATTRIBUTE_UNUSED;
+mark_not_eliminable (rtx dest, rtx x, void *data ATTRIBUTE_UNUSED)
{
unsigned int i;
@@ -3330,9 +3283,9 @@ mark_not_eliminable (dest, x, data)
cause incorrect code to be generated if we did not check for it. */
static void
-verify_initial_elim_offsets ()
+verify_initial_elim_offsets (void)
{
- int t;
+ HOST_WIDE_INT t;
#ifdef ELIMINABLE_REGS
struct elim_table *ep;
@@ -3353,7 +3306,7 @@ verify_initial_elim_offsets ()
/* Reset all offsets on eliminable registers to their initial values. */
static void
-set_initial_elim_offsets ()
+set_initial_elim_offsets (void)
{
struct elim_table *ep = reg_eliminate;
@@ -3379,7 +3332,7 @@ set_initial_elim_offsets ()
For all other labels, show that we don't know the offsets. */
static void
-set_initial_label_offsets ()
+set_initial_label_offsets (void)
{
rtx x;
memset (offsets_known_at, 0, num_labels);
@@ -3393,8 +3346,7 @@ set_initial_label_offsets ()
by INSN. */
static void
-set_offsets_for_label (insn)
- rtx insn;
+set_offsets_for_label (rtx insn)
{
unsigned int i;
int label_nr = CODE_LABEL_NUMBER (insn);
@@ -3417,8 +3369,7 @@ set_offsets_for_label (insn)
since they can't have changed. */
static void
-update_eliminables (pset)
- HARD_REG_SET *pset;
+update_eliminables (HARD_REG_SET *pset)
{
int previous_frame_pointer_needed = frame_pointer_needed;
struct elim_table *ep;
@@ -3494,7 +3445,7 @@ update_eliminables (pset)
/* Initialize the table of registers to eliminate. */
static void
-init_elim_table ()
+init_elim_table (void)
{
struct elim_table *ep;
#ifdef ELIMINABLE_REGS
@@ -3502,13 +3453,11 @@ init_elim_table ()
#endif
if (!reg_eliminate)
- reg_eliminate = (struct elim_table *)
- xcalloc (sizeof (struct elim_table), NUM_ELIMINABLE_REGS);
+ reg_eliminate = xcalloc (sizeof (struct elim_table), NUM_ELIMINABLE_REGS);
/* Does this function require a frame pointer? */
frame_pointer_needed = (! flag_omit_frame_pointer
-#ifdef EXIT_IGNORE_STACK
/* ?? If EXIT_IGNORE_STACK is set, we will not save
and restore sp for alloca. So we can't eliminate
the frame pointer in that case. At some point,
@@ -3516,7 +3465,6 @@ init_elim_table ()
sp-adjusting insns for this case. */
|| (current_function_calls_alloca
&& EXIT_IGNORE_STACK)
-#endif
|| FRAME_POINTER_REQUIRED);
num_eliminable = 0;
@@ -3561,9 +3509,7 @@ init_elim_table ()
Return nonzero if any pseudos needed to be kicked out. */
static void
-spill_hard_reg (regno, cant_eliminate)
- unsigned int regno;
- int cant_eliminate;
+spill_hard_reg (unsigned int regno, int cant_eliminate)
{
int i;
@@ -3590,8 +3536,7 @@ spill_hard_reg (regno, cant_eliminate)
from within EXECUTE_IF_SET_IN_REG_SET. Hence this awkwardness. */
static void
-ior_hard_reg_set (set1, set2)
- HARD_REG_SET *set1, *set2;
+ior_hard_reg_set (HARD_REG_SET *set1, HARD_REG_SET *set2)
{
IOR_HARD_REG_SET (*set1, *set2);
}
@@ -3602,8 +3547,7 @@ ior_hard_reg_set (set1, set2)
spill_regs array for use by choose_reload_regs. */
static int
-finish_spills (global)
- int global;
+finish_spills (int global)
{
struct insn_chain *chain;
int something_changed = 0;
@@ -3653,7 +3597,7 @@ finish_spills (global)
/* Retry global register allocation if possible. */
if (global)
{
- memset ((char *) pseudo_forbidden_regs, 0, max_regno * sizeof (HARD_REG_SET));
+ memset (pseudo_forbidden_regs, 0, max_regno * sizeof (HARD_REG_SET));
/* For every insn that needs reloads, set the registers used as spill
regs in pseudo_forbidden_regs for every pseudo live across the
insn. */
@@ -3752,8 +3696,7 @@ finish_spills (global)
forbidden from being used for spill registers. */
static void
-scan_paradoxical_subregs (x)
- rtx x;
+scan_paradoxical_subregs (rtx x)
{
int i;
const char *fmt;
@@ -3816,8 +3759,7 @@ scan_paradoxical_subregs (x)
as the insns are scanned. */
static void
-reload_as_needed (live_known)
- int live_known;
+reload_as_needed (int live_known)
{
struct insn_chain *chain;
#if defined (AUTO_INC_DEC)
@@ -3825,17 +3767,18 @@ reload_as_needed (live_known)
#endif
rtx x;
- memset ((char *) spill_reg_rtx, 0, sizeof spill_reg_rtx);
- memset ((char *) spill_reg_store, 0, sizeof spill_reg_store);
- reg_last_reload_reg = (rtx *) xcalloc (max_regno, sizeof (rtx));
- reg_has_output_reload = (char *) xmalloc (max_regno);
+ memset (spill_reg_rtx, 0, sizeof spill_reg_rtx);
+ memset (spill_reg_store, 0, sizeof spill_reg_store);
+ reg_last_reload_reg = xcalloc (max_regno, sizeof (rtx));
+ reg_has_output_reload = xmalloc (max_regno);
CLEAR_HARD_REG_SET (reg_reloaded_valid);
+ CLEAR_HARD_REG_SET (reg_reloaded_call_part_clobbered);
set_initial_elim_offsets ();
for (chain = reload_insn_chain; chain; chain = chain->next)
{
- rtx prev;
+ rtx prev = 0;
rtx insn = chain->insn;
rtx old_next = NEXT_INSN (insn);
@@ -3978,7 +3921,7 @@ reload_as_needed (live_known)
REGNO (rld[i].reg_rtx))
/* Make sure it is the inc/dec pseudo, and not
some other (e.g. output operand) pseudo. */
- && (reg_reloaded_contents[REGNO (rld[i].reg_rtx)]
+ && ((unsigned) reg_reloaded_contents[REGNO (rld[i].reg_rtx)]
== REGNO (XEXP (in_reg, 0))))
{
@@ -4045,7 +3988,7 @@ reload_as_needed (live_known)
REGNO (rld[i].reg_rtx))
/* Make sure it is the inc/dec pseudo, and not
some other (e.g. output operand) pseudo. */
- && (reg_reloaded_contents[REGNO (rld[i].reg_rtx)]
+ && ((unsigned) reg_reloaded_contents[REGNO (rld[i].reg_rtx)]
== REGNO (XEXP (in_reg, 0))))
{
SET_HARD_REG_BIT (reg_is_output_reload,
@@ -4077,9 +4020,13 @@ reload_as_needed (live_known)
CLEAR_HARD_REG_SET (reg_reloaded_valid);
/* Don't assume a reload reg is still good after a call insn
- if it is a call-used reg. */
+ if it is a call-used reg, or if it contains a value that will
+ be partially clobbered by the call. */
else if (GET_CODE (insn) == CALL_INSN)
+ {
AND_COMPL_HARD_REG_SET (reg_reloaded_valid, call_used_reg_set);
+ AND_COMPL_HARD_REG_SET (reg_reloaded_valid, reg_reloaded_call_part_clobbered);
+ }
}
/* Clean up. */
@@ -4095,10 +4042,8 @@ reload_as_needed (live_known)
or it may be a pseudo reg that was reloaded from. */
static void
-forget_old_reloads_1 (x, ignored, data)
- rtx x;
- rtx ignored ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
+forget_old_reloads_1 (rtx x, rtx ignored ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
{
unsigned int regno;
unsigned int nr;
@@ -4136,6 +4081,7 @@ forget_old_reloads_1 (x, ignored, data)
|| ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i))
{
CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
+ CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, regno + i);
spill_reg_store[regno + i] = 0;
}
}
@@ -4194,11 +4140,8 @@ static HARD_REG_SET reg_used_in_insn;
actually used. */
static void
-mark_reload_reg_in_use (regno, opnum, type, mode)
- unsigned int regno;
- int opnum;
- enum reload_type type;
- enum machine_mode mode;
+mark_reload_reg_in_use (unsigned int regno, int opnum, enum reload_type type,
+ enum machine_mode mode)
{
unsigned int nregs = HARD_REGNO_NREGS (regno, mode);
unsigned int i;
@@ -4259,11 +4202,8 @@ mark_reload_reg_in_use (regno, opnum, type, mode)
/* Similarly, but show REGNO is no longer in use for a reload. */
static void
-clear_reload_reg_in_use (regno, opnum, type, mode)
- unsigned int regno;
- int opnum;
- enum reload_type type;
- enum machine_mode mode;
+clear_reload_reg_in_use (unsigned int regno, int opnum,
+ enum reload_type type, enum machine_mode mode)
{
unsigned int nregs = HARD_REGNO_NREGS (regno, mode);
unsigned int start_regno, end_regno, r;
@@ -4371,10 +4311,7 @@ clear_reload_reg_in_use (regno, opnum, type, mode)
specified by OPNUM and TYPE. */
static int
-reload_reg_free_p (regno, opnum, type)
- unsigned int regno;
- int opnum;
- enum reload_type type;
+reload_reg_free_p (unsigned int regno, int opnum, enum reload_type type)
{
int i;
@@ -4389,6 +4326,7 @@ reload_reg_free_p (regno, opnum, type)
/* In use for anything means we can't use it for RELOAD_OTHER. */
if (TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno))
return 0;
@@ -4537,10 +4475,7 @@ reload_reg_free_p (regno, opnum, type)
in case the reg has already been marked in use. */
static int
-reload_reg_reaches_end_p (regno, opnum, type)
- unsigned int regno;
- int opnum;
- enum reload_type type;
+reload_reg_reaches_end_p (unsigned int regno, int opnum, enum reload_type type)
{
int i;
@@ -4570,6 +4505,7 @@ reload_reg_reaches_end_p (regno, opnum, type)
return 0;
return (! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
+ && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
&& ! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
&& ! TEST_HARD_REG_BIT (reload_reg_used, regno));
@@ -4670,8 +4606,7 @@ reload_reg_reaches_end_p (regno, opnum, type)
This function uses the same algorithm as reload_reg_free_p above. */
int
-reloads_conflict (r1, r2)
- int r1, r2;
+reloads_conflict (int r1, int r2)
{
enum reload_type r1_type = rld[r1].when_needed;
enum reload_type r2_type = rld[r2].when_needed;
@@ -4762,14 +4697,9 @@ int reload_spill_index[MAX_RELOADS];
(possibly comprising multiple hard registers) that we are considering. */
static int
-reload_reg_free_for_value_p (start_regno, regno, opnum, type, value, out,
- reloadnum, ignore_address_reloads)
- int start_regno, regno;
- int opnum;
- enum reload_type type;
- rtx value, out;
- int reloadnum;
- int ignore_address_reloads;
+reload_reg_free_for_value_p (int start_regno, int regno, int opnum,
+ enum reload_type type, rtx value, rtx out,
+ int reloadnum, int ignore_address_reloads)
{
int time1;
/* Set if we see an input reload that must not share its reload register
@@ -5006,15 +4936,9 @@ reload_reg_free_for_value_p (start_regno, regno, opnum, type, value, out,
register. */
static int
-free_for_value_p (regno, mode, opnum, type, value, out, reloadnum,
- ignore_address_reloads)
- int regno;
- enum machine_mode mode;
- int opnum;
- enum reload_type type;
- rtx value, out;
- int reloadnum;
- int ignore_address_reloads;
+free_for_value_p (int regno, enum machine_mode mode, int opnum,
+ enum reload_type type, rtx value, rtx out, int reloadnum,
+ int ignore_address_reloads)
{
int nregs = HARD_REGNO_NREGS (regno, mode);
while (nregs-- > 0)
@@ -5029,8 +4953,7 @@ free_for_value_p (regno, mode, opnum, type, value, out, reloadnum,
overriding inheritance. Return nonzero if so. */
static int
-conflicts_with_override (x)
- rtx x;
+conflicts_with_override (rtx x)
{
int i;
for (i = 0; i < n_reloads; i++)
@@ -5043,9 +4966,7 @@ conflicts_with_override (x)
/* Give an error message saying we failed to find a reload for INSN,
and clear out reload R. */
static void
-failed_reload (insn, r)
- rtx insn;
- int r;
+failed_reload (rtx insn, int r)
{
if (asm_noperands (PATTERN (insn)) < 0)
/* It's the compiler's fault. */
@@ -5066,8 +4987,7 @@ failed_reload (insn, r)
for reload R. If it's valid, get an rtx for it. Return nonzero if
successful. */
static int
-set_reload_reg (i, r)
- int i, r;
+set_reload_reg (int i, int r)
{
int regno;
rtx reg = spill_reg_rtx[i];
@@ -5122,10 +5042,8 @@ set_reload_reg (i, r)
we didn't change anything. */
static int
-allocate_reload_reg (chain, r, last_reload)
- struct insn_chain *chain ATTRIBUTE_UNUSED;
- int r;
- int last_reload;
+allocate_reload_reg (struct insn_chain *chain ATTRIBUTE_UNUSED, int r,
+ int last_reload)
{
int i, pass, count;
@@ -5246,9 +5164,7 @@ allocate_reload_reg (chain, r, last_reload)
is the array we use to restore the reg_rtx field for every reload. */
static void
-choose_reload_regs_init (chain, save_reload_reg_rtx)
- struct insn_chain *chain;
- rtx *save_reload_reg_rtx;
+choose_reload_regs_init (struct insn_chain *chain, rtx *save_reload_reg_rtx)
{
int i;
@@ -5256,8 +5172,8 @@ choose_reload_regs_init (chain, save_reload_reg_rtx)
rld[i].reg_rtx = save_reload_reg_rtx[i];
memset (reload_inherited, 0, MAX_RELOADS);
- memset ((char *) reload_inheritance_insn, 0, MAX_RELOADS * sizeof (rtx));
- memset ((char *) reload_override_in, 0, MAX_RELOADS * sizeof (rtx));
+ memset (reload_inheritance_insn, 0, MAX_RELOADS * sizeof (rtx));
+ memset (reload_override_in, 0, MAX_RELOADS * sizeof (rtx));
CLEAR_HARD_REG_SET (reload_reg_used);
CLEAR_HARD_REG_SET (reload_reg_used_at_all);
@@ -5307,8 +5223,7 @@ choose_reload_regs_init (chain, save_reload_reg_rtx)
finding a reload reg in the proper class. */
static void
-choose_reload_regs (chain)
- struct insn_chain *chain;
+choose_reload_regs (struct insn_chain *chain)
{
rtx insn = chain->insn;
int i, j;
@@ -5671,14 +5586,27 @@ choose_reload_regs (chain)
/* If we found a spill reg, reject it unless it is free
and of the desired class. */
- if (equiv != 0
- && ((TEST_HARD_REG_BIT (reload_reg_used_at_all, regno)
+ if (equiv != 0)
+ {
+ int regs_used = 0;
+ int bad_for_class = 0;
+ int max_regno = regno + rld[r].nregs;
+
+ for (i = regno; i < max_regno; i++)
+ {
+ regs_used |= TEST_HARD_REG_BIT (reload_reg_used_at_all,
+ i);
+ bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
+ i);
+ }
+
+ if ((regs_used
&& ! free_for_value_p (regno, rld[r].mode,
rld[r].opnum, rld[r].when_needed,
rld[r].in, rld[r].out, r, 1))
- || ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
- regno)))
- equiv = 0;
+ || bad_for_class)
+ equiv = 0;
+ }
if (equiv != 0 && ! HARD_REGNO_MODE_OK (regno, rld[r].mode))
equiv = 0;
@@ -5931,7 +5859,7 @@ choose_reload_regs (chain)
if (reload_override_in[j])
rld[j].in = reload_override_in[j];
- /* If this reload won't be done because it has been cancelled or is
+ /* If this reload won't be done because it has been canceled or is
optional and not inherited, clear reload_reg_rtx so other
routines (such as subst_reloads) don't get confused. */
for (j = 0; j < n_reloads; j++)
@@ -5990,8 +5918,7 @@ choose_reload_regs (chain)
remove_address_replacements. */
void
-deallocate_reload_reg (r)
- int r;
+deallocate_reload_reg (int r)
{
int regno;
@@ -6019,8 +5946,7 @@ deallocate_reload_reg (r)
prevent redundant code. */
static void
-merge_assigned_reloads (insn)
- rtx insn;
+merge_assigned_reloads (rtx insn)
{
int i, j;
@@ -6160,11 +6086,8 @@ static HARD_REG_SET reg_reloaded_died;
has the number J. OLD contains the value to be used as input. */
static void
-emit_input_reload_insns (chain, rl, old, j)
- struct insn_chain *chain;
- struct reload *rl;
- rtx old;
- int j;
+emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
+ rtx old, int j)
{
rtx insn = chain->insn;
rtx reloadreg = rl->reg_rtx;
@@ -6256,7 +6179,7 @@ emit_input_reload_insns (chain, rl, old, j)
or memory. */
if (oldequiv != 0
- && ((REGNO_REG_CLASS (regno) != rl->class
+ && (((enum reg_class) REGNO_REG_CLASS (regno) != rl->class
&& (REGISTER_MOVE_COST (mode, REGNO_REG_CLASS (regno),
rl->class)
>= MEMORY_MOVE_COST (mode, rl->class, 1)))
@@ -6312,7 +6235,7 @@ emit_input_reload_insns (chain, rl, old, j)
must always be a REG here. */
if (GET_MODE (reloadreg) != mode)
- reloadreg = gen_rtx_REG (mode, REGNO (reloadreg));
+ reloadreg = reload_adjust_reg_for_mode (reloadreg, mode);
while (GET_CODE (oldequiv) == SUBREG && GET_MODE (oldequiv) != mode)
oldequiv = SUBREG_REG (oldequiv);
if (GET_MODE (oldequiv) != VOIDmode
@@ -6561,8 +6484,8 @@ emit_input_reload_insns (chain, rl, old, j)
oldequiv = old, real_oldequiv = real_old;
else
second_reload_reg
- = gen_rtx_REG (new_mode,
- REGNO (second_reload_reg));
+ = reload_adjust_reg_for_mode (second_reload_reg,
+ new_mode);
}
}
}
@@ -6651,10 +6574,8 @@ emit_input_reload_insns (chain, rl, old, j)
/* Generate insns to for the output reload RL, which is for the insn described
by CHAIN and has the number J. */
static void
-emit_output_reload_insns (chain, rl, j)
- struct insn_chain *chain;
- struct reload *rl;
- int j;
+emit_output_reload_insns (struct insn_chain *chain, struct reload *rl,
+ int j)
{
rtx reloadreg = rl->reg_rtx;
rtx insn = chain->insn;
@@ -6684,7 +6605,7 @@ emit_output_reload_insns (chain, rl, j)
}
if (GET_MODE (reloadreg) != mode)
- reloadreg = gen_rtx_REG (mode, REGNO (reloadreg));
+ reloadreg = reload_adjust_reg_for_mode (reloadreg, mode);
#ifdef SECONDARY_OUTPUT_RELOAD_CLASS
@@ -6725,7 +6646,7 @@ emit_output_reload_insns (chain, rl, j)
= rld[secondary_reload].secondary_out_icode;
if (GET_MODE (reloadreg) != mode)
- reloadreg = gen_rtx_REG (mode, REGNO (reloadreg));
+ reloadreg = reload_adjust_reg_for_mode (reloadreg, mode);
if (tertiary_icode != CODE_FOR_nothing)
{
@@ -6865,12 +6786,8 @@ emit_output_reload_insns (chain, rl, j)
/* Do input reloading for reload RL, which is for the insn described by CHAIN
and has the number J. */
static void
-do_input_reload (chain, rl, j)
- struct insn_chain *chain;
- struct reload *rl;
- int j;
+do_input_reload (struct insn_chain *chain, struct reload *rl, int j)
{
- int expect_occurrences = 1;
rtx insn = chain->insn;
rtx old = (rl->in && GET_CODE (rl->in) == MEM
? rl->in_reg : rl->in);
@@ -6891,11 +6808,7 @@ do_input_reload (chain, rl, j)
&& GET_CODE (rl->in_reg) == MEM
&& reload_spill_index[j] >= 0
&& TEST_HARD_REG_BIT (reg_reloaded_valid, reload_spill_index[j]))
- {
- expect_occurrences
- = count_occurrences (PATTERN (insn), rl->in, 0) == 1 ? 0 : -1;
- rl->in = regno_reg_rtx[reg_reloaded_contents[reload_spill_index[j]]];
- }
+ rl->in = regno_reg_rtx[reg_reloaded_contents[reload_spill_index[j]]];
/* If we are reloading a register that was recently stored in with an
output-reload, see if we can prove there was
@@ -6928,10 +6841,7 @@ do_input_reload (chain, rl, j)
??? At some point we need to support handling output reloads of
JUMP_INSNs or insns that set cc0. */
static void
-do_output_reload (chain, rl, j)
- struct insn_chain *chain;
- struct reload *rl;
- int j;
+do_output_reload (struct insn_chain *chain, struct reload *rl, int j)
{
rtx note, old;
rtx insn = chain->insn;
@@ -7000,8 +6910,7 @@ do_output_reload (chain, rl, j)
/* Output insns to reload values in and out of the chosen reload regs. */
static void
-emit_reload_insns (chain)
- struct insn_chain *chain;
+emit_reload_insns (struct insn_chain *chain)
{
rtx insn = chain->insn;
@@ -7157,7 +7066,10 @@ emit_reload_insns (chain)
If consecutive registers are used, clear them all. */
for (k = 0; k < nr; k++)
+ {
CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);
+ CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, i + k);
+ }
/* Maybe the spill reg contains a copy of reload_out. */
if (rld[r].out != 0
@@ -7204,6 +7116,8 @@ emit_reload_insns (chain)
: nregno + k);
reg_reloaded_insn[i + k] = insn;
SET_HARD_REG_BIT (reg_reloaded_valid, i + k);
+ if (HARD_REGNO_CALL_PART_CLOBBERED (i + k, GET_MODE (out)))
+ SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered, i + k);
}
}
@@ -7221,14 +7135,16 @@ emit_reload_insns (chain)
{
int nregno;
int nnr;
+ rtx in;
if (GET_CODE (rld[r].in) == REG
&& REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER)
- nregno = REGNO (rld[r].in);
+ in = rld[r].in;
else if (GET_CODE (rld[r].in_reg) == REG)
- nregno = REGNO (rld[r].in_reg);
+ in = rld[r].in_reg;
else
- nregno = REGNO (XEXP (rld[r].in_reg, 0));
+ in = XEXP (rld[r].in_reg, 0);
+ nregno = REGNO (in);
nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
: HARD_REGNO_NREGS (nregno,
@@ -7260,6 +7176,8 @@ emit_reload_insns (chain)
: nregno + k);
reg_reloaded_insn[i + k] = insn;
SET_HARD_REG_BIT (reg_reloaded_valid, i + k);
+ if (HARD_REGNO_CALL_PART_CLOBBERED (i + k, GET_MODE (in)))
+ SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered, i + k);
}
}
}
@@ -7346,6 +7264,10 @@ emit_reload_insns (chain)
reg_reloaded_insn[src_regno + nr] = store_insn;
CLEAR_HARD_REG_BIT (reg_reloaded_dead, src_regno + nr);
SET_HARD_REG_BIT (reg_reloaded_valid, src_regno + nr);
+ if (HARD_REGNO_CALL_PART_CLOBBERED (src_regno + nr,
+ GET_MODE (src_reg)))
+ SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
+ src_regno + nr);
SET_HARD_REG_BIT (reg_is_output_reload, src_regno + nr);
if (note)
SET_HARD_REG_BIT (reg_reloaded_died, src_regno);
@@ -7353,6 +7275,10 @@ emit_reload_insns (chain)
CLEAR_HARD_REG_BIT (reg_reloaded_died, src_regno);
}
reg_last_reload_reg[nregno] = src_reg;
+ /* We have to set reg_has_output_reload here, or else
+ forget_old_reloads_1 will clear reg_last_reload_reg
+ right away. */
+ reg_has_output_reload[nregno] = 1;
}
}
else
@@ -7374,11 +7300,7 @@ emit_reload_insns (chain)
Returns first insn emitted. */
rtx
-gen_reload (out, in, opnum, type)
- rtx out;
- rtx in;
- int opnum;
- enum reload_type type;
+gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
{
rtx last = get_last_insn ();
rtx tem;
@@ -7598,10 +7520,7 @@ gen_reload (out, in, opnum, type)
certain that reload J doesn't use REG any longer for input. */
static void
-delete_output_reload (insn, j, last_reload_reg)
- rtx insn;
- int j;
- int last_reload_reg;
+delete_output_reload (rtx insn, int j, int last_reload_reg)
{
rtx output_reload_insn = spill_reg_store[last_reload_reg];
rtx reg = spill_reg_stored_to[last_reload_reg];
@@ -7697,7 +7616,7 @@ delete_output_reload (insn, j, last_reload_reg)
/* The caller has already checked that REG dies or is set in INSN.
It has also checked that we are optimizing, and thus some
- inaccurancies in the debugging information are acceptable.
+ inaccuracies in the debugging information are acceptable.
So we could just delete output_reload_insn. But in some cases
we can improve the debugging information without sacrificing
optimization - maybe even improving the code: See if the pseudo
@@ -7768,8 +7687,7 @@ delete_output_reload (insn, j, last_reload_reg)
reload registers used in DEAD_INSN that are not used till CURRENT_INSN.
CURRENT_INSN is being reloaded, so we have to check its reloads too. */
static void
-delete_address_reloads (dead_insn, current_insn)
- rtx dead_insn, current_insn;
+delete_address_reloads (rtx dead_insn, rtx current_insn)
{
rtx set = single_set (dead_insn);
rtx set2, dst, prev, next;
@@ -7805,8 +7723,7 @@ delete_address_reloads (dead_insn, current_insn)
/* Subfunction of delete_address_reloads: process registers found in X. */
static void
-delete_address_reloads_1 (dead_insn, x, current_insn)
- rtx dead_insn, x, current_insn;
+delete_address_reloads_1 (rtx dead_insn, rtx x, rtx current_insn)
{
rtx prev, set, dst, i2;
int i, j;
@@ -7899,7 +7816,7 @@ delete_address_reloads_1 (dead_insn, x, current_insn)
return;
/* ??? We can't finish the loop here, because dst might be
allocated to a pseudo in this block if no reload in this
- block needs any of the clsses containing DST - see
+ block needs any of the classes containing DST - see
spill_hard_reg. There is no easy way to tell this, so we
have to scan till the end of the basic block. */
}
@@ -7924,10 +7841,7 @@ delete_address_reloads_1 (dead_insn, x, current_insn)
Return the instruction that stores into RELOADREG. */
static rtx
-inc_for_reload (reloadreg, in, value, inc_amount)
- rtx reloadreg;
- rtx in, value;
- int inc_amount;
+inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount)
{
/* REG or MEM to be copied and incremented. */
rtx incloc = XEXP (value, 0);
@@ -8016,1404 +7930,9 @@ inc_for_reload (reloadreg, in, value, inc_amount)
return store;
}
-
-/* See whether a single set SET is a noop. */
-static int
-reload_cse_noop_set_p (set)
- rtx set;
-{
- return rtx_equal_for_cselib_p (SET_DEST (set), SET_SRC (set));
-}
-
-/* Try to simplify INSN. */
-static void
-reload_cse_simplify (insn, testreg)
- rtx insn;
- rtx testreg;
-{
- rtx body = PATTERN (insn);
-
- if (GET_CODE (body) == SET)
- {
- int count = 0;
-
- /* Simplify even if we may think it is a no-op.
- We may think a memory load of a value smaller than WORD_SIZE
- is redundant because we haven't taken into account possible
- implicit extension. reload_cse_simplify_set() will bring
- this out, so it's safer to simplify before we delete. */
- count += reload_cse_simplify_set (body, insn);
-
- if (!count && reload_cse_noop_set_p (body))
- {
- rtx value = SET_DEST (body);
- if (REG_P (value)
- && ! REG_FUNCTION_VALUE_P (value))
- value = 0;
- delete_insn_and_edges (insn);
- return;
- }
-
- if (count > 0)
- apply_change_group ();
- else
- reload_cse_simplify_operands (insn, testreg);
- }
- else if (GET_CODE (body) == PARALLEL)
- {
- int i;
- int count = 0;
- rtx value = NULL_RTX;
-
- /* If every action in a PARALLEL is a noop, we can delete
- the entire PARALLEL. */
- for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
- {
- rtx part = XVECEXP (body, 0, i);
- if (GET_CODE (part) == SET)
- {
- if (! reload_cse_noop_set_p (part))
- break;
- if (REG_P (SET_DEST (part))
- && REG_FUNCTION_VALUE_P (SET_DEST (part)))
- {
- if (value)
- break;
- value = SET_DEST (part);
- }
- }
- else if (GET_CODE (part) != CLOBBER)
- break;
- }
-
- if (i < 0)
- {
- delete_insn_and_edges (insn);
- /* We're done with this insn. */
- return;
- }
-
- /* It's not a no-op, but we can try to simplify it. */
- for (i = XVECLEN (body, 0) - 1; i >= 0; --i)
- if (GET_CODE (XVECEXP (body, 0, i)) == SET)
- count += reload_cse_simplify_set (XVECEXP (body, 0, i), insn);
-
- if (count > 0)
- apply_change_group ();
- else
- reload_cse_simplify_operands (insn, testreg);
- }
-}
-
-/* Do a very simple CSE pass over the hard registers.
-
- This function detects no-op moves where we happened to assign two
- different pseudo-registers to the same hard register, and then
- copied one to the other. Reload will generate a useless
- instruction copying a register to itself.
-
- This function also detects cases where we load a value from memory
- into two different registers, and (if memory is more expensive than
- registers) changes it to simply copy the first register into the
- second register.
-
- Another optimization is performed that scans the operands of each
- instruction to see whether the value is already available in a
- hard register. It then replaces the operand with the hard register
- if possible, much like an optional reload would. */
-
-static void
-reload_cse_regs_1 (first)
- rtx first;
-{
- rtx insn;
- rtx testreg = gen_rtx_REG (VOIDmode, -1);
-
- cselib_init ();
- init_alias_analysis ();
-
- for (insn = first; insn; insn = NEXT_INSN (insn))
- {
- if (INSN_P (insn))
- reload_cse_simplify (insn, testreg);
-
- cselib_process_insn (insn);
- }
-
- /* Clean up. */
- end_alias_analysis ();
- cselib_finish ();
-}
-
-/* Call cse / combine like post-reload optimization phases.
- FIRST is the first instruction. */
-void
-reload_cse_regs (first)
- rtx first;
-{
- reload_cse_regs_1 (first);
- reload_combine ();
- reload_cse_move2add (first);
- if (flag_expensive_optimizations)
- reload_cse_regs_1 (first);
-}
-
-/* Try to simplify a single SET instruction. SET is the set pattern.
- INSN is the instruction it came from.
- This function only handles one case: if we set a register to a value
- which is not a register, we try to find that value in some other register
- and change the set into a register copy. */
-
-static int
-reload_cse_simplify_set (set, insn)
- rtx set;
- rtx insn;
-{
- int did_change = 0;
- int dreg;
- rtx src;
- enum reg_class dclass;
- int old_cost;
- cselib_val *val;
- struct elt_loc_list *l;
-#ifdef LOAD_EXTEND_OP
- enum rtx_code extend_op = NIL;
-#endif
-
- dreg = true_regnum (SET_DEST (set));
- if (dreg < 0)
- return 0;
-
- src = SET_SRC (set);
- if (side_effects_p (src) || true_regnum (src) >= 0)
- return 0;
-
- dclass = REGNO_REG_CLASS (dreg);
-
-#ifdef LOAD_EXTEND_OP
- /* When replacing a memory with a register, we need to honor assumptions
- that combine made wrt the contents of sign bits. We'll do this by
- generating an extend instruction instead of a reg->reg copy. Thus
- the destination must be a register that we can widen. */
- if (GET_CODE (src) == MEM
- && GET_MODE_BITSIZE (GET_MODE (src)) < BITS_PER_WORD
- && (extend_op = LOAD_EXTEND_OP (GET_MODE (src))) != NIL
- && GET_CODE (SET_DEST (set)) != REG)
- return 0;
-#endif
-
- /* If memory loads are cheaper than register copies, don't change them. */
- if (GET_CODE (src) == MEM)
- old_cost = MEMORY_MOVE_COST (GET_MODE (src), dclass, 1);
- else if (CONSTANT_P (src))
- old_cost = rtx_cost (src, SET);
- else if (GET_CODE (src) == REG)
- old_cost = REGISTER_MOVE_COST (GET_MODE (src),
- REGNO_REG_CLASS (REGNO (src)), dclass);
- else
- /* ??? */
- old_cost = rtx_cost (src, SET);
-
- val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0);
- if (! val)
- return 0;
- for (l = val->locs; l; l = l->next)
- {
- rtx this_rtx = l->loc;
- int this_cost;
-
- if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx, 0))
- {
-#ifdef LOAD_EXTEND_OP
- if (extend_op != NIL)
- {
- HOST_WIDE_INT this_val;
-
- /* ??? I'm lazy and don't wish to handle CONST_DOUBLE. Other
- constants, such as SYMBOL_REF, cannot be extended. */
- if (GET_CODE (this_rtx) != CONST_INT)
- continue;
-
- this_val = INTVAL (this_rtx);
- switch (extend_op)
- {
- case ZERO_EXTEND:
- this_val &= GET_MODE_MASK (GET_MODE (src));
- break;
- case SIGN_EXTEND:
- /* ??? In theory we're already extended. */
- if (this_val == trunc_int_for_mode (this_val, GET_MODE (src)))
- break;
- default:
- abort ();
- }
- this_rtx = GEN_INT (this_val);
- }
-#endif
- this_cost = rtx_cost (this_rtx, SET);
- }
- else if (GET_CODE (this_rtx) == REG)
- {
-#ifdef LOAD_EXTEND_OP
- if (extend_op != NIL)
- {
- this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx);
- this_cost = rtx_cost (this_rtx, SET);
- }
- else
-#endif
- this_cost = REGISTER_MOVE_COST (GET_MODE (this_rtx),
- REGNO_REG_CLASS (REGNO (this_rtx)),
- dclass);
- }
- else
- continue;
-
- /* If equal costs, prefer registers over anything else. That
- tends to lead to smaller instructions on some machines. */
- if (this_cost < old_cost
- || (this_cost == old_cost
- && GET_CODE (this_rtx) == REG
- && GET_CODE (SET_SRC (set)) != REG))
- {
-#ifdef LOAD_EXTEND_OP
- if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) < BITS_PER_WORD
- && extend_op != NIL
-#ifdef CANNOT_CHANGE_MODE_CLASS
- && !CANNOT_CHANGE_MODE_CLASS (GET_MODE (SET_DEST (set)),
- word_mode,
- REGNO_REG_CLASS (REGNO (SET_DEST (set))))
-#endif
- )
- {
- rtx wide_dest = gen_rtx_REG (word_mode, REGNO (SET_DEST (set)));
- ORIGINAL_REGNO (wide_dest) = ORIGINAL_REGNO (SET_DEST (set));
- validate_change (insn, &SET_DEST (set), wide_dest, 1);
- }
-#endif
-
- validate_change (insn, &SET_SRC (set), copy_rtx (this_rtx), 1);
- old_cost = this_cost, did_change = 1;
- }
- }
-
- return did_change;
-}
-
-/* Try to replace operands in INSN with equivalent values that are already
- in registers. This can be viewed as optional reloading.
-
- For each non-register operand in the insn, see if any hard regs are
- known to be equivalent to that operand. Record the alternatives which
- can accept these hard registers. Among all alternatives, select the
- ones which are better or equal to the one currently matching, where
- "better" is in terms of '?' and '!' constraints. Among the remaining
- alternatives, select the one which replaces most operands with
- hard registers. */
-
-static int
-reload_cse_simplify_operands (insn, testreg)
- rtx insn;
- rtx testreg;
-{
- int i, j;
-
- /* For each operand, all registers that are equivalent to it. */
- HARD_REG_SET equiv_regs[MAX_RECOG_OPERANDS];
-
- const char *constraints[MAX_RECOG_OPERANDS];
-
- /* Vector recording how bad an alternative is. */
- int *alternative_reject;
- /* Vector recording how many registers can be introduced by choosing
- this alternative. */
- int *alternative_nregs;
- /* Array of vectors recording, for each operand and each alternative,
- which hard register to substitute, or -1 if the operand should be
- left as it is. */
- int *op_alt_regno[MAX_RECOG_OPERANDS];
- /* Array of alternatives, sorted in order of decreasing desirability. */
- int *alternative_order;
-
- extract_insn (insn);
-
- if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0)
- return 0;
-
- /* Figure out which alternative currently matches. */
- if (! constrain_operands (1))
- fatal_insn_not_found (insn);
-
- alternative_reject = (int *) alloca (recog_data.n_alternatives * sizeof (int));
- alternative_nregs = (int *) alloca (recog_data.n_alternatives * sizeof (int));
- alternative_order = (int *) alloca (recog_data.n_alternatives * sizeof (int));
- memset ((char *) alternative_reject, 0, recog_data.n_alternatives * sizeof (int));
- memset ((char *) alternative_nregs, 0, recog_data.n_alternatives * sizeof (int));
-
- /* For each operand, find out which regs are equivalent. */
- for (i = 0; i < recog_data.n_operands; i++)
- {
- cselib_val *v;
- struct elt_loc_list *l;
-
- CLEAR_HARD_REG_SET (equiv_regs[i]);
-
- /* cselib blows up on CODE_LABELs. Trying to fix that doesn't seem
- right, so avoid the problem here. Likewise if we have a constant
- and the insn pattern doesn't tell us the mode we need. */
- if (GET_CODE (recog_data.operand[i]) == CODE_LABEL
- || (CONSTANT_P (recog_data.operand[i])
- && recog_data.operand_mode[i] == VOIDmode))
- continue;
-
- v = cselib_lookup (recog_data.operand[i], recog_data.operand_mode[i], 0);
- if (! v)
- continue;
-
- for (l = v->locs; l; l = l->next)
- if (GET_CODE (l->loc) == REG)
- SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc));
- }
-
- for (i = 0; i < recog_data.n_operands; i++)
- {
- enum machine_mode mode;
- int regno;
- const char *p;
-
- op_alt_regno[i] = (int *) alloca (recog_data.n_alternatives * sizeof (int));
- for (j = 0; j < recog_data.n_alternatives; j++)
- op_alt_regno[i][j] = -1;
-
- p = constraints[i] = recog_data.constraints[i];
- mode = recog_data.operand_mode[i];
-
- /* Add the reject values for each alternative given by the constraints
- for this operand. */
- j = 0;
- while (*p != '\0')
- {
- char c = *p++;
- if (c == ',')
- j++;
- else if (c == '?')
- alternative_reject[j] += 3;
- else if (c == '!')
- alternative_reject[j] += 300;
- }
-
- /* We won't change operands which are already registers. We
- also don't want to modify output operands. */
- regno = true_regnum (recog_data.operand[i]);
- if (regno >= 0
- || constraints[i][0] == '='
- || constraints[i][0] == '+')
- continue;
-
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- {
- int class = (int) NO_REGS;
-
- if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
- continue;
-
- REGNO (testreg) = regno;
- PUT_MODE (testreg, mode);
-
- /* We found a register equal to this operand. Now look for all
- alternatives that can accept this register and have not been
- assigned a register they can use yet. */
- j = 0;
- p = constraints[i];
- for (;;)
- {
- char c = *p++;
-
- switch (c)
- {
- case '=': case '+': case '?':
- case '#': case '&': case '!':
- case '*': case '%':
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case 'm': case '<': case '>': case 'V': case 'o':
- case 'E': case 'F': case 'G': case 'H':
- case 's': case 'i': case 'n':
- case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P':
- case 'p': case 'X':
- /* These don't say anything we care about. */
- break;
-
- case 'g': case 'r':
- class = reg_class_subunion[(int) class][(int) GENERAL_REGS];
- break;
-
- default:
- class
- = reg_class_subunion[(int) class][(int) REG_CLASS_FROM_LETTER ((unsigned char) c)];
- break;
-
- case ',': case '\0':
- /* See if REGNO fits this alternative, and set it up as the
- replacement register if we don't have one for this
- alternative yet and the operand being replaced is not
- a cheap CONST_INT. */
- if (op_alt_regno[i][j] == -1
- && reg_fits_class_p (testreg, class, 0, mode)
- && (GET_CODE (recog_data.operand[i]) != CONST_INT
- || (rtx_cost (recog_data.operand[i], SET)
- > rtx_cost (testreg, SET))))
- {
- alternative_nregs[j]++;
- op_alt_regno[i][j] = regno;
- }
- j++;
- break;
- }
-
- if (c == '\0')
- break;
- }
- }
- }
-
- /* Record all alternatives which are better or equal to the currently
- matching one in the alternative_order array. */
- for (i = j = 0; i < recog_data.n_alternatives; i++)
- if (alternative_reject[i] <= alternative_reject[which_alternative])
- alternative_order[j++] = i;
- recog_data.n_alternatives = j;
-
- /* Sort it. Given a small number of alternatives, a dumb algorithm
- won't hurt too much. */
- for (i = 0; i < recog_data.n_alternatives - 1; i++)
- {
- int best = i;
- int best_reject = alternative_reject[alternative_order[i]];
- int best_nregs = alternative_nregs[alternative_order[i]];
- int tmp;
-
- for (j = i + 1; j < recog_data.n_alternatives; j++)
- {
- int this_reject = alternative_reject[alternative_order[j]];
- int this_nregs = alternative_nregs[alternative_order[j]];
-
- if (this_reject < best_reject
- || (this_reject == best_reject && this_nregs < best_nregs))
- {
- best = j;
- best_reject = this_reject;
- best_nregs = this_nregs;
- }
- }
-
- tmp = alternative_order[best];
- alternative_order[best] = alternative_order[i];
- alternative_order[i] = tmp;
- }
-
- /* Substitute the operands as determined by op_alt_regno for the best
- alternative. */
- j = alternative_order[0];
-
- for (i = 0; i < recog_data.n_operands; i++)
- {
- enum machine_mode mode = recog_data.operand_mode[i];
- if (op_alt_regno[i][j] == -1)
- continue;
-
- validate_change (insn, recog_data.operand_loc[i],
- gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
- }
-
- for (i = recog_data.n_dups - 1; i >= 0; i--)
- {
- int op = recog_data.dup_num[i];
- enum machine_mode mode = recog_data.operand_mode[op];
-
- if (op_alt_regno[op][j] == -1)
- continue;
-
- validate_change (insn, recog_data.dup_loc[i],
- gen_rtx_REG (mode, op_alt_regno[op][j]), 1);
- }
-
- return apply_change_group ();
-}
-
-/* If reload couldn't use reg+reg+offset addressing, try to use reg+reg
- addressing now.
- This code might also be useful when reload gave up on reg+reg addresssing
- because of clashes between the return register and INDEX_REG_CLASS. */
-
-/* The maximum number of uses of a register we can keep track of to
- replace them with reg+reg addressing. */
-#define RELOAD_COMBINE_MAX_USES 6
-
-/* INSN is the insn where a register has ben used, and USEP points to the
- location of the register within the rtl. */
-struct reg_use { rtx insn, *usep; };
-
-/* If the register is used in some unknown fashion, USE_INDEX is negative.
- If it is dead, USE_INDEX is RELOAD_COMBINE_MAX_USES, and STORE_RUID
- indicates where it becomes live again.
- Otherwise, USE_INDEX is the index of the last encountered use of the
- register (which is first among these we have seen since we scan backwards),
- OFFSET contains the constant offset that is added to the register in
- all encountered uses, and USE_RUID indicates the first encountered, i.e.
- last, of these uses.
- STORE_RUID is always meaningful if we only want to use a value in a
- register in a different place: it denotes the next insn in the insn
- stream (i.e. the last ecountered) that sets or clobbers the register. */
-static struct
- {
- struct reg_use reg_use[RELOAD_COMBINE_MAX_USES];
- int use_index;
- rtx offset;
- int store_ruid;
- int use_ruid;
- } reg_state[FIRST_PSEUDO_REGISTER];
-
-/* Reverse linear uid. This is increased in reload_combine while scanning
- the instructions from last to first. It is used to set last_label_ruid
- and the store_ruid / use_ruid fields in reg_state. */
-static int reload_combine_ruid;
-
-#define LABEL_LIVE(LABEL) \
- (label_live[CODE_LABEL_NUMBER (LABEL) - min_labelno])
-
-static void
-reload_combine ()
-{
- rtx insn, set;
- int first_index_reg = -1;
- int last_index_reg = 0;
- int i;
- basic_block bb;
- unsigned int r;
- int last_label_ruid;
- int min_labelno, n_labels;
- HARD_REG_SET ever_live_at_start, *label_live;
-
- /* If reg+reg can be used in offsetable memory addresses, the main chunk of
- reload has already used it where appropriate, so there is no use in
- trying to generate it now. */
- if (double_reg_address_ok && INDEX_REG_CLASS != NO_REGS)
- return;
-
- /* To avoid wasting too much time later searching for an index register,
- determine the minimum and maximum index register numbers. */
- for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
- if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], r))
- {
- if (first_index_reg == -1)
- first_index_reg = r;
-
- last_index_reg = r;
- }
-
- /* If no index register is available, we can quit now. */
- if (first_index_reg == -1)
- return;
-
- /* Set up LABEL_LIVE and EVER_LIVE_AT_START. The register lifetime
- information is a bit fuzzy immediately after reload, but it's
- still good enough to determine which registers are live at a jump
- destination. */
- min_labelno = get_first_label_num ();
- n_labels = max_label_num () - min_labelno;
- label_live = (HARD_REG_SET *) xmalloc (n_labels * sizeof (HARD_REG_SET));
- CLEAR_HARD_REG_SET (ever_live_at_start);
-
- FOR_EACH_BB_REVERSE (bb)
- {
- insn = bb->head;
- if (GET_CODE (insn) == CODE_LABEL)
- {
- HARD_REG_SET live;
-
- REG_SET_TO_HARD_REG_SET (live,
- bb->global_live_at_start);
- compute_use_by_pseudos (&live,
- bb->global_live_at_start);
- COPY_HARD_REG_SET (LABEL_LIVE (insn), live);
- IOR_HARD_REG_SET (ever_live_at_start, live);
- }
- }
-
- /* Initialize last_label_ruid, reload_combine_ruid and reg_state. */
- last_label_ruid = reload_combine_ruid = 0;
- for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
- {
- reg_state[r].store_ruid = reload_combine_ruid;
- if (fixed_regs[r])
- reg_state[r].use_index = -1;
- else
- reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
- }
-
- for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
- {
- rtx note;
-
- /* We cannot do our optimization across labels. Invalidating all the use
- information we have would be costly, so we just note where the label
- is and then later disable any optimization that would cross it. */
- if (GET_CODE (insn) == CODE_LABEL)
- last_label_ruid = reload_combine_ruid;
- else if (GET_CODE (insn) == BARRIER)
- for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
- if (! fixed_regs[r])
- reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
-
- if (! INSN_P (insn))
- continue;
-
- reload_combine_ruid++;
-
- /* Look for (set (REGX) (CONST_INT))
- (set (REGX) (PLUS (REGX) (REGY)))
- ...
- ... (MEM (REGX)) ...
- and convert it to
- (set (REGZ) (CONST_INT))
- ...
- ... (MEM (PLUS (REGZ) (REGY)))... .
-
- First, check that we have (set (REGX) (PLUS (REGX) (REGY)))
- and that we know all uses of REGX before it dies. */
- set = single_set (insn);
- if (set != NULL_RTX
- && GET_CODE (SET_DEST (set)) == REG
- && (HARD_REGNO_NREGS (REGNO (SET_DEST (set)),
- GET_MODE (SET_DEST (set)))
- == 1)
- && GET_CODE (SET_SRC (set)) == PLUS
- && GET_CODE (XEXP (SET_SRC (set), 1)) == REG
- && rtx_equal_p (XEXP (SET_SRC (set), 0), SET_DEST (set))
- && last_label_ruid < reg_state[REGNO (SET_DEST (set))].use_ruid)
- {
- rtx reg = SET_DEST (set);
- rtx plus = SET_SRC (set);
- rtx base = XEXP (plus, 1);
- rtx prev = prev_nonnote_insn (insn);
- rtx prev_set = prev ? single_set (prev) : NULL_RTX;
- unsigned int regno = REGNO (reg);
- rtx const_reg = NULL_RTX;
- rtx reg_sum = NULL_RTX;
-
- /* Now, we need an index register.
- We'll set index_reg to this index register, const_reg to the
- register that is to be loaded with the constant
- (denoted as REGZ in the substitution illustration above),
- and reg_sum to the register-register that we want to use to
- substitute uses of REG (typically in MEMs) with.
- First check REG and BASE for being index registers;
- we can use them even if they are not dead. */
- if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
- || TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
- REGNO (base)))
- {
- const_reg = reg;
- reg_sum = plus;
- }
- else
- {
- /* Otherwise, look for a free index register. Since we have
- checked above that neiter REG nor BASE are index registers,
- if we find anything at all, it will be different from these
- two registers. */
- for (i = first_index_reg; i <= last_index_reg; i++)
- {
- if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
- i)
- && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES
- && reg_state[i].store_ruid <= reg_state[regno].use_ruid
- && HARD_REGNO_NREGS (i, GET_MODE (reg)) == 1)
- {
- rtx index_reg = gen_rtx_REG (GET_MODE (reg), i);
-
- const_reg = index_reg;
- reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base);
- break;
- }
- }
- }
-
- /* Check that PREV_SET is indeed (set (REGX) (CONST_INT)) and that
- (REGY), i.e. BASE, is not clobbered before the last use we'll
- create. */
- if (prev_set != 0
- && GET_CODE (SET_SRC (prev_set)) == CONST_INT
- && rtx_equal_p (SET_DEST (prev_set), reg)
- && reg_state[regno].use_index >= 0
- && (reg_state[REGNO (base)].store_ruid
- <= reg_state[regno].use_ruid)
- && reg_sum != 0)
- {
- int i;
-
- /* Change destination register and, if necessary, the
- constant value in PREV, the constant loading instruction. */
- validate_change (prev, &SET_DEST (prev_set), const_reg, 1);
- if (reg_state[regno].offset != const0_rtx)
- validate_change (prev,
- &SET_SRC (prev_set),
- GEN_INT (INTVAL (SET_SRC (prev_set))
- + INTVAL (reg_state[regno].offset)),
- 1);
-
- /* Now for every use of REG that we have recorded, replace REG
- with REG_SUM. */
- for (i = reg_state[regno].use_index;
- i < RELOAD_COMBINE_MAX_USES; i++)
- validate_change (reg_state[regno].reg_use[i].insn,
- reg_state[regno].reg_use[i].usep,
- /* Each change must have its own
- replacement. */
- copy_rtx (reg_sum), 1);
-
- if (apply_change_group ())
- {
- rtx *np;
-
- /* Delete the reg-reg addition. */
- delete_insn (insn);
-
- if (reg_state[regno].offset != const0_rtx)
- /* Previous REG_EQUIV / REG_EQUAL notes for PREV
- are now invalid. */
- for (np = &REG_NOTES (prev); *np;)
- {
- if (REG_NOTE_KIND (*np) == REG_EQUAL
- || REG_NOTE_KIND (*np) == REG_EQUIV)
- *np = XEXP (*np, 1);
- else
- np = &XEXP (*np, 1);
- }
-
- reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
- reg_state[REGNO (const_reg)].store_ruid
- = reload_combine_ruid;
- continue;
- }
- }
- }
-
- note_stores (PATTERN (insn), reload_combine_note_store, NULL);
-
- if (GET_CODE (insn) == CALL_INSN)
- {
- rtx link;
-
- for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
- if (call_used_regs[r])
- {
- reg_state[r].use_index = RELOAD_COMBINE_MAX_USES;
- reg_state[r].store_ruid = reload_combine_ruid;
- }
-
- for (link = CALL_INSN_FUNCTION_USAGE (insn); link;
- link = XEXP (link, 1))
- {
- rtx usage_rtx = XEXP (XEXP (link, 0), 0);
- if (GET_CODE (usage_rtx) == REG)
- {
- unsigned int i;
- unsigned int start_reg = REGNO (usage_rtx);
- unsigned int num_regs =
- HARD_REGNO_NREGS (start_reg, GET_MODE (usage_rtx));
- unsigned int end_reg = start_reg + num_regs - 1;
- for (i = start_reg; i <= end_reg; i++)
- if (GET_CODE (XEXP (link, 0)) == CLOBBER)
- {
- reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
- reg_state[i].store_ruid = reload_combine_ruid;
- }
- else
- reg_state[i].use_index = -1;
- }
- }
-
- }
- else if (GET_CODE (insn) == JUMP_INSN
- && GET_CODE (PATTERN (insn)) != RETURN)
- {
- /* Non-spill registers might be used at the call destination in
- some unknown fashion, so we have to mark the unknown use. */
- HARD_REG_SET *live;
-
- if ((condjump_p (insn) || condjump_in_parallel_p (insn))
- && JUMP_LABEL (insn))
- live = &LABEL_LIVE (JUMP_LABEL (insn));
- else
- live = &ever_live_at_start;
-
- for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; --i)
- if (TEST_HARD_REG_BIT (*live, i))
- reg_state[i].use_index = -1;
- }
-
- reload_combine_note_use (&PATTERN (insn), insn);
- for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
- {
- if (REG_NOTE_KIND (note) == REG_INC
- && GET_CODE (XEXP (note, 0)) == REG)
- {
- int regno = REGNO (XEXP (note, 0));
-
- reg_state[regno].store_ruid = reload_combine_ruid;
- reg_state[regno].use_index = -1;
- }
- }
- }
-
- free (label_live);
-}
-
-/* Check if DST is a register or a subreg of a register; if it is,
- update reg_state[regno].store_ruid and reg_state[regno].use_index
- accordingly. Called via note_stores from reload_combine. */
-
-static void
-reload_combine_note_store (dst, set, data)
- rtx dst, set;
- void *data ATTRIBUTE_UNUSED;
-{
- int regno = 0;
- int i;
- enum machine_mode mode = GET_MODE (dst);
-
- if (GET_CODE (dst) == SUBREG)
- {
- regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
- GET_MODE (SUBREG_REG (dst)),
- SUBREG_BYTE (dst),
- GET_MODE (dst));
- dst = SUBREG_REG (dst);
- }
- if (GET_CODE (dst) != REG)
- return;
- regno += REGNO (dst);
-
- /* note_stores might have stripped a STRICT_LOW_PART, so we have to be
- careful with registers / register parts that are not full words.
-
- Similarly for ZERO_EXTRACT and SIGN_EXTRACT. */
- if (GET_CODE (set) != SET
- || GET_CODE (SET_DEST (set)) == ZERO_EXTRACT
- || GET_CODE (SET_DEST (set)) == SIGN_EXTRACT
- || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART)
- {
- for (i = HARD_REGNO_NREGS (regno, mode) - 1 + regno; i >= regno; i--)
- {
- reg_state[i].use_index = -1;
- reg_state[i].store_ruid = reload_combine_ruid;
- }
- }
- else
- {
- for (i = HARD_REGNO_NREGS (regno, mode) - 1 + regno; i >= regno; i--)
- {
- reg_state[i].store_ruid = reload_combine_ruid;
- reg_state[i].use_index = RELOAD_COMBINE_MAX_USES;
- }
- }
-}
-
-/* XP points to a piece of rtl that has to be checked for any uses of
- registers.
- *XP is the pattern of INSN, or a part of it.
- Called from reload_combine, and recursively by itself. */
-static void
-reload_combine_note_use (xp, insn)
- rtx *xp, insn;
-{
- rtx x = *xp;
- enum rtx_code code = x->code;
- const char *fmt;
- int i, j;
- rtx offset = const0_rtx; /* For the REG case below. */
-
- switch (code)
- {
- case SET:
- if (GET_CODE (SET_DEST (x)) == REG)
- {
- reload_combine_note_use (&SET_SRC (x), insn);
- return;
- }
- break;
-
- case USE:
- /* If this is the USE of a return value, we can't change it. */
- if (GET_CODE (XEXP (x, 0)) == REG && REG_FUNCTION_VALUE_P (XEXP (x, 0)))
- {
- /* Mark the return register as used in an unknown fashion. */
- rtx reg = XEXP (x, 0);
- int regno = REGNO (reg);
- int nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg));
-
- while (--nregs >= 0)
- reg_state[regno + nregs].use_index = -1;
- return;
- }
- break;
-
- case CLOBBER:
- if (GET_CODE (SET_DEST (x)) == REG)
- {
- /* No spurious CLOBBERs of pseudo registers may remain. */
- if (REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER)
- abort ();
- return;
- }
- break;
-
- case PLUS:
- /* We are interested in (plus (reg) (const_int)) . */
- if (GET_CODE (XEXP (x, 0)) != REG
- || GET_CODE (XEXP (x, 1)) != CONST_INT)
- break;
- offset = XEXP (x, 1);
- x = XEXP (x, 0);
- /* Fall through. */
- case REG:
- {
- int regno = REGNO (x);
- int use_index;
- int nregs;
-
- /* No spurious USEs of pseudo registers may remain. */
- if (regno >= FIRST_PSEUDO_REGISTER)
- abort ();
-
- nregs = HARD_REGNO_NREGS (regno, GET_MODE (x));
-
- /* We can't substitute into multi-hard-reg uses. */
- if (nregs > 1)
- {
- while (--nregs >= 0)
- reg_state[regno + nregs].use_index = -1;
- return;
- }
-
- /* If this register is already used in some unknown fashion, we
- can't do anything.
- If we decrement the index from zero to -1, we can't store more
- uses, so this register becomes used in an unknown fashion. */
- use_index = --reg_state[regno].use_index;
- if (use_index < 0)
- return;
-
- if (use_index != RELOAD_COMBINE_MAX_USES - 1)
- {
- /* We have found another use for a register that is already
- used later. Check if the offsets match; if not, mark the
- register as used in an unknown fashion. */
- if (! rtx_equal_p (offset, reg_state[regno].offset))
- {
- reg_state[regno].use_index = -1;
- return;
- }
- }
- else
- {
- /* This is the first use of this register we have seen since we
- marked it as dead. */
- reg_state[regno].offset = offset;
- reg_state[regno].use_ruid = reload_combine_ruid;
- }
- reg_state[regno].reg_use[use_index].insn = insn;
- reg_state[regno].reg_use[use_index].usep = xp;
- return;
- }
-
- default:
- break;
- }
-
- /* Recursively process the components of X. */
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e')
- reload_combine_note_use (&XEXP (x, i), insn);
- else if (fmt[i] == 'E')
- {
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
- reload_combine_note_use (&XVECEXP (x, i, j), insn);
- }
- }
-}
-
-/* See if we can reduce the cost of a constant by replacing a move
- with an add. We track situations in which a register is set to a
- constant or to a register plus a constant. */
-/* We cannot do our optimization across labels. Invalidating all the
- information about register contents we have would be costly, so we
- use move2add_last_label_luid to note where the label is and then
- later disable any optimization that would cross it.
- reg_offset[n] / reg_base_reg[n] / reg_mode[n] are only valid if
- reg_set_luid[n] is greater than last_label_luid[n] . */
-static int reg_set_luid[FIRST_PSEUDO_REGISTER];
-
-/* If reg_base_reg[n] is negative, register n has been set to
- reg_offset[n] in mode reg_mode[n] .
- If reg_base_reg[n] is non-negative, register n has been set to the
- sum of reg_offset[n] and the value of register reg_base_reg[n]
- before reg_set_luid[n], calculated in mode reg_mode[n] . */
-static HOST_WIDE_INT reg_offset[FIRST_PSEUDO_REGISTER];
-static int reg_base_reg[FIRST_PSEUDO_REGISTER];
-static enum machine_mode reg_mode[FIRST_PSEUDO_REGISTER];
-
-/* move2add_luid is linearily increased while scanning the instructions
- from first to last. It is used to set reg_set_luid in
- reload_cse_move2add and move2add_note_store. */
-static int move2add_luid;
-
-/* move2add_last_label_luid is set whenever a label is found. Labels
- invalidate all previously collected reg_offset data. */
-static int move2add_last_label_luid;
-
-/* Generate a CONST_INT and force it in the range of MODE. */
-
-static HOST_WIDE_INT
-sext_for_mode (mode, value)
- enum machine_mode mode;
- HOST_WIDE_INT value;
-{
- HOST_WIDE_INT cval = value & GET_MODE_MASK (mode);
- int width = GET_MODE_BITSIZE (mode);
-
- /* If MODE is narrower than HOST_WIDE_INT and CVAL is a negative number,
- sign extend it. */
- if (width > 0 && width < HOST_BITS_PER_WIDE_INT
- && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0)
- cval |= (HOST_WIDE_INT) -1 << width;
-
- return cval;
-}
-
-/* ??? We don't know how zero / sign extension is handled, hence we
- can't go from a narrower to a wider mode. */
-#define MODES_OK_FOR_MOVE2ADD(OUTMODE, INMODE) \
- (GET_MODE_SIZE (OUTMODE) == GET_MODE_SIZE (INMODE) \
- || (GET_MODE_SIZE (OUTMODE) <= GET_MODE_SIZE (INMODE) \
- && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (OUTMODE), \
- GET_MODE_BITSIZE (INMODE))))
-
-static void
-reload_cse_move2add (first)
- rtx first;
-{
- int i;
- rtx insn;
-
- for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
- reg_set_luid[i] = 0;
-
- move2add_last_label_luid = 0;
- move2add_luid = 2;
- for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++)
- {
- rtx pat, note;
-
- if (GET_CODE (insn) == CODE_LABEL)
- {
- move2add_last_label_luid = move2add_luid;
- /* We're going to increment move2add_luid twice after a
- label, so that we can use move2add_last_label_luid + 1 as
- the luid for constants. */
- move2add_luid++;
- continue;
- }
- if (! INSN_P (insn))
- continue;
- pat = PATTERN (insn);
- /* For simplicity, we only perform this optimization on
- straightforward SETs. */
- if (GET_CODE (pat) == SET
- && GET_CODE (SET_DEST (pat)) == REG)
- {
- rtx reg = SET_DEST (pat);
- int regno = REGNO (reg);
- rtx src = SET_SRC (pat);
-
- /* Check if we have valid information on the contents of this
- register in the mode of REG. */
- if (reg_set_luid[regno] > move2add_last_label_luid
- && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[regno]))
- {
- /* Try to transform (set (REGX) (CONST_INT A))
- ...
- (set (REGX) (CONST_INT B))
- to
- (set (REGX) (CONST_INT A))
- ...
- (set (REGX) (plus (REGX) (CONST_INT B-A))) */
-
- if (GET_CODE (src) == CONST_INT && reg_base_reg[regno] < 0)
- {
- int success = 0;
- rtx new_src = GEN_INT (sext_for_mode (GET_MODE (reg),
- INTVAL (src)
- - reg_offset[regno]));
- /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
- use (set (reg) (reg)) instead.
- We don't delete this insn, nor do we convert it into a
- note, to avoid losing register notes or the return
- value flag. jump2 already knowns how to get rid of
- no-op moves. */
- if (new_src == const0_rtx)
- success = validate_change (insn, &SET_SRC (pat), reg, 0);
- else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET)
- && have_add2_insn (reg, new_src))
- success = validate_change (insn, &PATTERN (insn),
- gen_add2_insn (reg, new_src), 0);
- reg_set_luid[regno] = move2add_luid;
- reg_mode[regno] = GET_MODE (reg);
- reg_offset[regno] = INTVAL (src);
- continue;
- }
-
- /* Try to transform (set (REGX) (REGY))
- (set (REGX) (PLUS (REGX) (CONST_INT A)))
- ...
- (set (REGX) (REGY))
- (set (REGX) (PLUS (REGX) (CONST_INT B)))
- to
- (REGX) (REGY))
- (set (REGX) (PLUS (REGX) (CONST_INT A)))
- ...
- (set (REGX) (plus (REGX) (CONST_INT B-A))) */
- else if (GET_CODE (src) == REG
- && reg_set_luid[regno] == reg_set_luid[REGNO (src)]
- && reg_base_reg[regno] == reg_base_reg[REGNO (src)]
- && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg),
- reg_mode[REGNO (src)]))
- {
- rtx next = next_nonnote_insn (insn);
- rtx set = NULL_RTX;
- if (next)
- set = single_set (next);
- if (set
- && SET_DEST (set) == reg
- && GET_CODE (SET_SRC (set)) == PLUS
- && XEXP (SET_SRC (set), 0) == reg
- && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
- {
- rtx src3 = XEXP (SET_SRC (set), 1);
- HOST_WIDE_INT added_offset = INTVAL (src3);
- HOST_WIDE_INT base_offset = reg_offset[REGNO (src)];
- HOST_WIDE_INT regno_offset = reg_offset[regno];
- rtx new_src = GEN_INT (sext_for_mode (GET_MODE (reg),
- added_offset
- + base_offset
- - regno_offset));
- int success = 0;
-
- if (new_src == const0_rtx)
- /* See above why we create (set (reg) (reg)) here. */
- success
- = validate_change (next, &SET_SRC (set), reg, 0);
- else if ((rtx_cost (new_src, PLUS)
- < COSTS_N_INSNS (1) + rtx_cost (src3, SET))
- && have_add2_insn (reg, new_src))
- success
- = validate_change (next, &PATTERN (next),
- gen_add2_insn (reg, new_src), 0);
- if (success)
- delete_insn (insn);
- insn = next;
- reg_mode[regno] = GET_MODE (reg);
- reg_offset[regno] = sext_for_mode (GET_MODE (reg),
- added_offset
- + base_offset);
- continue;
- }
- }
- }
- }
-
- for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
- {
- if (REG_NOTE_KIND (note) == REG_INC
- && GET_CODE (XEXP (note, 0)) == REG)
- {
- /* Reset the information about this register. */
- int regno = REGNO (XEXP (note, 0));
- if (regno < FIRST_PSEUDO_REGISTER)
- reg_set_luid[regno] = 0;
- }
- }
- note_stores (PATTERN (insn), move2add_note_store, NULL);
- /* If this is a CALL_INSN, all call used registers are stored with
- unknown values. */
- if (GET_CODE (insn) == CALL_INSN)
- {
- for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
- {
- if (call_used_regs[i])
- /* Reset the information about this register. */
- reg_set_luid[i] = 0;
- }
- }
- }
-}
-
-/* SET is a SET or CLOBBER that sets DST.
- Update reg_set_luid, reg_offset and reg_base_reg accordingly.
- Called from reload_cse_move2add via note_stores. */
-
-static void
-move2add_note_store (dst, set, data)
- rtx dst, set;
- void *data ATTRIBUTE_UNUSED;
-{
- unsigned int regno = 0;
- unsigned int i;
- enum machine_mode mode = GET_MODE (dst);
-
- if (GET_CODE (dst) == SUBREG)
- {
- regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)),
- GET_MODE (SUBREG_REG (dst)),
- SUBREG_BYTE (dst),
- GET_MODE (dst));
- dst = SUBREG_REG (dst);
- }
-
- /* Some targets do argument pushes without adding REG_INC notes. */
-
- if (GET_CODE (dst) == MEM)
- {
- dst = XEXP (dst, 0);
- if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC
- || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC)
- reg_set_luid[REGNO (XEXP (dst, 0))] = 0;
- return;
- }
- if (GET_CODE (dst) != REG)
- return;
-
- regno += REGNO (dst);
-
- if (HARD_REGNO_NREGS (regno, mode) == 1 && GET_CODE (set) == SET
- && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
- && GET_CODE (SET_DEST (set)) != SIGN_EXTRACT
- && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART)
- {
- rtx src = SET_SRC (set);
- rtx base_reg;
- HOST_WIDE_INT offset;
- int base_regno;
- /* This may be different from mode, if SET_DEST (set) is a
- SUBREG. */
- enum machine_mode dst_mode = GET_MODE (dst);
-
- switch (GET_CODE (src))
- {
- case PLUS:
- if (GET_CODE (XEXP (src, 0)) == REG)
- {
- base_reg = XEXP (src, 0);
-
- if (GET_CODE (XEXP (src, 1)) == CONST_INT)
- offset = INTVAL (XEXP (src, 1));
- else if (GET_CODE (XEXP (src, 1)) == REG
- && (reg_set_luid[REGNO (XEXP (src, 1))]
- > move2add_last_label_luid)
- && (MODES_OK_FOR_MOVE2ADD
- (dst_mode, reg_mode[REGNO (XEXP (src, 1))])))
- {
- if (reg_base_reg[REGNO (XEXP (src, 1))] < 0)
- offset = reg_offset[REGNO (XEXP (src, 1))];
- /* Maybe the first register is known to be a
- constant. */
- else if (reg_set_luid[REGNO (base_reg)]
- > move2add_last_label_luid
- && (MODES_OK_FOR_MOVE2ADD
- (dst_mode, reg_mode[REGNO (XEXP (src, 1))]))
- && reg_base_reg[REGNO (base_reg)] < 0)
- {
- offset = reg_offset[REGNO (base_reg)];
- base_reg = XEXP (src, 1);
- }
- else
- goto invalidate;
- }
- else
- goto invalidate;
-
- break;
- }
-
- goto invalidate;
-
- case REG:
- base_reg = src;
- offset = 0;
- break;
-
- case CONST_INT:
- /* Start tracking the register as a constant. */
- reg_base_reg[regno] = -1;
- reg_offset[regno] = INTVAL (SET_SRC (set));
- /* We assign the same luid to all registers set to constants. */
- reg_set_luid[regno] = move2add_last_label_luid + 1;
- reg_mode[regno] = mode;
- return;
-
- default:
- invalidate:
- /* Invalidate the contents of the register. */
- reg_set_luid[regno] = 0;
- return;
- }
-
- base_regno = REGNO (base_reg);
- /* If information about the base register is not valid, set it
- up as a new base register, pretending its value is known
- starting from the current insn. */
- if (reg_set_luid[base_regno] <= move2add_last_label_luid)
- {
- reg_base_reg[base_regno] = base_regno;
- reg_offset[base_regno] = 0;
- reg_set_luid[base_regno] = move2add_luid;
- reg_mode[base_regno] = mode;
- }
- else if (! MODES_OK_FOR_MOVE2ADD (dst_mode,
- reg_mode[base_regno]))
- goto invalidate;
-
- reg_mode[regno] = mode;
-
- /* Copy base information from our base register. */
- reg_set_luid[regno] = reg_set_luid[base_regno];
- reg_base_reg[regno] = reg_base_reg[base_regno];
-
- /* Compute the sum of the offsets or constants. */
- reg_offset[regno] = sext_for_mode (dst_mode,
- offset
- + reg_offset[base_regno]);
- }
- else
- {
- unsigned int endregno = regno + HARD_REGNO_NREGS (regno, mode);
-
- for (i = regno; i < endregno; i++)
- /* Reset the information about this register. */
- reg_set_luid[i] = 0;
- }
-}
-
#ifdef AUTO_INC_DEC
static void
-add_auto_inc_notes (insn, x)
- rtx insn;
- rtx x;
+add_auto_inc_notes (rtx insn, rtx x)
{
enum rtx_code code = GET_CODE (x);
const char *fmt;
@@ -9441,9 +7960,7 @@ add_auto_inc_notes (insn, x)
/* Copy EH notes from an insn to its reloads. */
static void
-copy_eh_notes (insn, x)
- rtx insn;
- rtx x;
+copy_eh_notes (rtx insn, rtx x)
{
rtx eh_note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
if (eh_note)
@@ -9465,7 +7982,7 @@ copy_eh_notes (insn, x)
Similar handle instructions throwing exceptions internally. */
void
-fixup_abnormal_edges ()
+fixup_abnormal_edges (void)
{
bool inserted = false;
basic_block bb;
@@ -9484,9 +8001,10 @@ fixup_abnormal_edges ()
== (EDGE_ABNORMAL | EDGE_EH))
break;
}
- if (e && GET_CODE (bb->end) != CALL_INSN && !can_throw_internal (bb->end))
+ if (e && GET_CODE (BB_END (bb)) != CALL_INSN
+ && !can_throw_internal (BB_END (bb)))
{
- rtx insn = bb->end, stop = NEXT_INSN (bb->end);
+ rtx insn = BB_END (bb), stop = NEXT_INSN (BB_END (bb));
rtx next;
for (e = bb->succ; e; e = e->succ_next)
if (e->flags & EDGE_FALLTHRU)
@@ -9495,11 +8013,11 @@ fixup_abnormal_edges ()
be already deleted. */
while ((GET_CODE (insn) == INSN || GET_CODE (insn) == NOTE)
&& !can_throw_internal (insn)
- && insn != bb->head)
+ && insn != BB_HEAD (bb))
insn = PREV_INSN (insn);
if (GET_CODE (insn) != CALL_INSN && !can_throw_internal (insn))
abort ();
- bb->end = insn;
+ BB_END (bb) = insn;
inserted = true;
insn = NEXT_INSN (insn);
while (insn && insn != stop)
@@ -9513,7 +8031,7 @@ fixup_abnormal_edges ()
If it's placed after a trapping call (i.e. that
call is the last insn anyway), we have no fallthru
edge. Simply delete this use and don't try to insert
- on the non-existant edge. */
+ on the non-existent edge. */
if (GET_CODE (PATTERN (insn)) != USE)
{
/* We're not deleting it, we're moving it. */
@@ -9528,6 +8046,14 @@ fixup_abnormal_edges ()
}
}
}
+ /* We've possibly turned single trapping insn into multiple ones. */
+ if (flag_non_call_exceptions)
+ {
+ sbitmap blocks;
+ blocks = sbitmap_alloc (last_basic_block);
+ sbitmap_ones (blocks);
+ find_many_sub_basic_blocks (blocks);
+ }
if (inserted)
commit_edge_insertions ();
}
diff --git a/contrib/gcc/reorg.c b/contrib/gcc/reorg.c
index 3fdf941ad793..f3cf61ddaa3c 100644
--- a/contrib/gcc/reorg.c
+++ b/contrib/gcc/reorg.c
@@ -1,6 +1,6 @@
/* Perform instruction reorganizations for delay slot filling.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu).
Hacked by Michael Tiemann (tiemann@cygnus.com).
@@ -122,6 +122,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "tm_p.h"
@@ -175,53 +177,52 @@ static int *uid_to_ruid;
/* Highest valid index in `uid_to_ruid'. */
static int max_uid;
-static int stop_search_p PARAMS ((rtx, int));
-static int resource_conflicts_p PARAMS ((struct resources *,
- struct resources *));
-static int insn_references_resource_p PARAMS ((rtx, struct resources *, int));
-static int insn_sets_resource_p PARAMS ((rtx, struct resources *, int));
-static rtx find_end_label PARAMS ((void));
-static rtx emit_delay_sequence PARAMS ((rtx, rtx, int));
-static rtx add_to_delay_list PARAMS ((rtx, rtx));
-static rtx delete_from_delay_slot PARAMS ((rtx));
-static void delete_scheduled_jump PARAMS ((rtx));
-static void note_delay_statistics PARAMS ((int, int));
+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 rtx find_end_label (void);
+static rtx emit_delay_sequence (rtx, rtx, int);
+static rtx add_to_delay_list (rtx, rtx);
+static rtx delete_from_delay_slot (rtx);
+static void delete_scheduled_jump (rtx);
+static void note_delay_statistics (int, int);
#if defined(ANNUL_IFFALSE_SLOTS) || defined(ANNUL_IFTRUE_SLOTS)
-static rtx optimize_skip PARAMS ((rtx));
+static rtx optimize_skip (rtx);
#endif
-static int get_jump_flags PARAMS ((rtx, rtx));
-static int rare_destination PARAMS ((rtx));
-static int mostly_true_jump PARAMS ((rtx, rtx));
-static rtx get_branch_condition PARAMS ((rtx, rtx));
-static int condition_dominates_p PARAMS ((rtx, rtx));
-static int redirect_with_delay_slots_safe_p PARAMS ((rtx, rtx, rtx));
-static int redirect_with_delay_list_safe_p PARAMS ((rtx, rtx, rtx));
-static int check_annul_list_true_false PARAMS ((int, rtx));
-static rtx steal_delay_list_from_target PARAMS ((rtx, rtx, rtx, rtx,
- struct resources *,
- struct resources *,
- struct resources *,
- int, int *, int *, rtx *));
-static rtx steal_delay_list_from_fallthrough PARAMS ((rtx, rtx, rtx, rtx,
- struct resources *,
- struct resources *,
- struct resources *,
- int, int *, int *));
-static void try_merge_delay_insns PARAMS ((rtx, rtx));
-static rtx redundant_insn PARAMS ((rtx, rtx, rtx));
-static int own_thread_p PARAMS ((rtx, rtx, int));
-static void update_block PARAMS ((rtx, rtx));
-static int reorg_redirect_jump PARAMS ((rtx, rtx));
-static void update_reg_dead_notes PARAMS ((rtx, rtx));
-static void fix_reg_dead_note PARAMS ((rtx, rtx));
-static void update_reg_unused_notes PARAMS ((rtx, rtx));
-static void fill_simple_delay_slots PARAMS ((int));
-static rtx fill_slots_from_thread PARAMS ((rtx, rtx, rtx, rtx, int, int,
- int, int, int *, rtx));
-static void fill_eager_delay_slots PARAMS ((void));
-static void relax_delay_slots PARAMS ((rtx));
+static int get_jump_flags (rtx, rtx);
+static int rare_destination (rtx);
+static int mostly_true_jump (rtx, rtx);
+static rtx get_branch_condition (rtx, rtx);
+static int condition_dominates_p (rtx, rtx);
+static int redirect_with_delay_slots_safe_p (rtx, rtx, rtx);
+static int redirect_with_delay_list_safe_p (rtx, rtx, rtx);
+static int check_annul_list_true_false (int, rtx);
+static rtx steal_delay_list_from_target (rtx, rtx, rtx, rtx,
+ struct resources *,
+ struct resources *,
+ struct resources *,
+ int, int *, int *, rtx *);
+static rtx steal_delay_list_from_fallthrough (rtx, rtx, rtx, rtx,
+ struct resources *,
+ struct resources *,
+ struct resources *,
+ int, int *, int *);
+static void try_merge_delay_insns (rtx, rtx);
+static rtx redundant_insn (rtx, rtx, rtx);
+static int own_thread_p (rtx, rtx, int);
+static void update_block (rtx, rtx);
+static int reorg_redirect_jump (rtx, rtx);
+static void update_reg_dead_notes (rtx, rtx);
+static void fix_reg_dead_note (rtx, rtx);
+static void update_reg_unused_notes (rtx, rtx);
+static void fill_simple_delay_slots (int);
+static rtx fill_slots_from_thread (rtx, rtx, rtx, rtx, int, int, int, int,
+ int *, rtx);
+static void fill_eager_delay_slots (void);
+static void relax_delay_slots (rtx);
#ifdef HAVE_return
-static void make_return_insns PARAMS ((rtx));
+static void make_return_insns (rtx);
#endif
/* Return TRUE if this insn should stop the search for insn to fill delay
@@ -229,9 +230,7 @@ static void make_return_insns PARAMS ((rtx));
In all cases, jumps terminate the search. */
static int
-stop_search_p (insn, labels_p)
- rtx insn;
- int labels_p;
+stop_search_p (rtx insn, int labels_p)
{
if (insn == 0)
return 1;
@@ -271,8 +270,7 @@ stop_search_p (insn, labels_p)
resource set contains a volatile memory reference. Otherwise, return FALSE. */
static int
-resource_conflicts_p (res1, res2)
- struct resources *res1, *res2;
+resource_conflicts_p (struct resources *res1, struct resources *res2)
{
if ((res1->cc && res2->cc) || (res1->memory && res2->memory)
|| (res1->unch_memory && res2->unch_memory)
@@ -303,10 +301,8 @@ resource_conflicts_p (res1, res2)
a large block of complex code. */
static int
-insn_references_resource_p (insn, res, include_delayed_effects)
- rtx insn;
- struct resources *res;
- int include_delayed_effects;
+insn_references_resource_p (rtx insn, struct resources *res,
+ int include_delayed_effects)
{
struct resources insn_res;
@@ -321,10 +317,8 @@ insn_references_resource_p (insn, res, include_delayed_effects)
in front of mark_set_resources for details. */
static int
-insn_sets_resource_p (insn, res, include_delayed_effects)
- rtx insn;
- struct resources *res;
- int include_delayed_effects;
+insn_sets_resource_p (rtx insn, struct resources *res,
+ int include_delayed_effects)
{
struct resources insn_sets;
@@ -337,7 +331,7 @@ insn_sets_resource_p (insn, res, include_delayed_effects)
none, make one. */
static rtx
-find_end_label ()
+find_end_label (void)
{
rtx insn;
@@ -434,10 +428,7 @@ find_end_label ()
Returns the SEQUENCE that replaces INSN. */
static rtx
-emit_delay_sequence (insn, list, length)
- rtx insn;
- rtx list;
- int length;
+emit_delay_sequence (rtx insn, rtx list, int length)
{
int i = 1;
rtx li;
@@ -501,6 +492,12 @@ emit_delay_sequence (insn, list, length)
PREV_INSN (tem) = XVECEXP (seq, 0, i - 1);
NEXT_INSN (XVECEXP (seq, 0, i - 1)) = tem;
+ /* SPARC assembler, for instance, emit warning when debug info is output
+ into the delay slot. */
+ if (INSN_LOCATOR (tem) && !INSN_LOCATOR (seq_insn))
+ INSN_LOCATOR (seq_insn) = INSN_LOCATOR (tem);
+ INSN_LOCATOR (tem) = 0;
+
for (note = REG_NOTES (tem); note; note = next)
{
next = XEXP (note, 1);
@@ -554,9 +551,7 @@ emit_delay_sequence (insn, list, length)
be in the order in which the insns are to be executed. */
static rtx
-add_to_delay_list (insn, delay_list)
- rtx insn;
- rtx delay_list;
+add_to_delay_list (rtx insn, rtx delay_list)
{
/* If we have an empty list, just make a new list element. If
INSN has its block number recorded, clear it since we may
@@ -579,8 +574,7 @@ add_to_delay_list (insn, delay_list)
produce an insn with no delay slots. Return the new insn. */
static rtx
-delete_from_delay_slot (insn)
- rtx insn;
+delete_from_delay_slot (rtx insn)
{
rtx trial, seq_insn, seq, prev;
rtx delay_list = 0;
@@ -637,8 +631,7 @@ delete_from_delay_slot (insn)
the insn that sets CC0 for it and delete it too. */
static void
-delete_scheduled_jump (insn)
- rtx insn;
+delete_scheduled_jump (rtx insn)
{
/* Delete the insn that sets cc0 for us. On machines without cc0, we could
delete the insn that sets the condition code, but it is hard to find it.
@@ -695,8 +688,7 @@ static int num_filled_delays[NUM_REORG_FUNCTIONS][MAX_DELAY_HISTOGRAM+1][MAX_REO
static int reorg_pass_number;
static void
-note_delay_statistics (slots_filled, index)
- int slots_filled, index;
+note_delay_statistics (int slots_filled, int index)
{
num_insns_needing_delays[index][reorg_pass_number]++;
if (slots_filled > MAX_DELAY_HISTOGRAM)
@@ -739,8 +731,7 @@ note_delay_statistics (slots_filled, index)
of delay slots required. */
static rtx
-optimize_skip (insn)
- rtx insn;
+optimize_skip (rtx insn)
{
rtx trial = next_nonnote_insn (insn);
rtx next_trial = next_active_insn (trial);
@@ -821,8 +812,7 @@ optimize_skip (insn)
are predicted as very likely taken. */
static int
-get_jump_flags (insn, label)
- rtx insn, label;
+get_jump_flags (rtx insn, rtx label)
{
int flags;
@@ -885,8 +875,7 @@ get_jump_flags (insn, label)
return 0. */
static int
-rare_destination (insn)
- rtx insn;
+rare_destination (rtx insn)
{
int jump_count = 0;
rtx next;
@@ -937,8 +926,7 @@ rare_destination (insn)
CONDITION, if nonzero, is the condition that JUMP_INSN is testing. */
static int
-mostly_true_jump (jump_insn, condition)
- rtx jump_insn, condition;
+mostly_true_jump (rtx jump_insn, rtx condition)
{
rtx target_label = JUMP_LABEL (jump_insn);
rtx insn, note;
@@ -1060,9 +1048,7 @@ mostly_true_jump (jump_insn, condition)
type of jump, or it doesn't go to TARGET, return 0. */
static rtx
-get_branch_condition (insn, target)
- rtx insn;
- rtx target;
+get_branch_condition (rtx insn, rtx target)
{
rtx pat = PATTERN (insn);
rtx src;
@@ -1108,9 +1094,7 @@ get_branch_condition (insn, target)
INSN, i.e., if INSN will always branch if CONDITION is true. */
static int
-condition_dominates_p (condition, insn)
- rtx condition;
- rtx insn;
+condition_dominates_p (rtx condition, rtx insn)
{
rtx other_condition = get_branch_condition (insn, JUMP_LABEL (insn));
enum rtx_code code = GET_CODE (condition);
@@ -1136,8 +1120,7 @@ condition_dominates_p (condition, insn)
any insns already in the delay slot of JUMP. */
static int
-redirect_with_delay_slots_safe_p (jump, newlabel, seq)
- rtx jump, newlabel, seq;
+redirect_with_delay_slots_safe_p (rtx jump, rtx newlabel, rtx seq)
{
int flags, i;
rtx pat = PATTERN (seq);
@@ -1171,8 +1154,7 @@ redirect_with_delay_slots_safe_p (jump, newlabel, seq)
any insns we wish to place in the delay slot of JUMP. */
static int
-redirect_with_delay_list_safe_p (jump, newlabel, delay_list)
- rtx jump, newlabel, delay_list;
+redirect_with_delay_list_safe_p (rtx jump, rtx newlabel, rtx delay_list)
{
int flags, i;
rtx li;
@@ -1205,9 +1187,7 @@ redirect_with_delay_list_safe_p (jump, newlabel, delay_list)
If not, return 0; otherwise return 1. */
static int
-check_annul_list_true_false (annul_true_p, delay_list)
- int annul_true_p;
- rtx delay_list;
+check_annul_list_true_false (int annul_true_p, rtx delay_list)
{
rtx temp;
@@ -1247,18 +1227,12 @@ check_annul_list_true_false (annul_true_p, delay_list)
execution should continue. */
static rtx
-steal_delay_list_from_target (insn, condition, seq, delay_list,
- sets, needed, other_needed,
- slots_to_fill, pslots_filled, pannul_p,
- pnew_thread)
- rtx insn, condition;
- rtx seq;
- rtx delay_list;
- struct resources *sets, *needed, *other_needed;
- int slots_to_fill;
- int *pslots_filled;
- int *pannul_p;
- rtx *pnew_thread;
+steal_delay_list_from_target (rtx insn, rtx condition, rtx seq,
+ rtx delay_list, struct resources *sets,
+ struct resources *needed,
+ struct resources *other_needed,
+ int slots_to_fill, int *pslots_filled,
+ int *pannul_p, rtx *pnew_thread)
{
rtx temp;
int slots_remaining = slots_to_fill - *pslots_filled;
@@ -1386,16 +1360,12 @@ steal_delay_list_from_target (insn, condition, seq, delay_list,
for INSN since unconditional branches are much easier to fill. */
static rtx
-steal_delay_list_from_fallthrough (insn, condition, seq,
- delay_list, sets, needed, other_needed,
- slots_to_fill, pslots_filled, pannul_p)
- rtx insn, condition;
- rtx seq;
- rtx delay_list;
- struct resources *sets, *needed, *other_needed;
- int slots_to_fill;
- int *pslots_filled;
- int *pannul_p;
+steal_delay_list_from_fallthrough (rtx insn, rtx condition, rtx seq,
+ rtx delay_list, struct resources *sets,
+ struct resources *needed,
+ struct resources *other_needed,
+ int slots_to_fill, int *pslots_filled,
+ int *pannul_p)
{
int i;
int flags;
@@ -1470,8 +1440,7 @@ steal_delay_list_from_fallthrough (insn, condition, seq,
we delete the merged insn. */
static void
-try_merge_delay_insns (insn, thread)
- rtx insn, thread;
+try_merge_delay_insns (rtx insn, rtx thread)
{
rtx trial, next_trial;
rtx delay_insn = XVECEXP (PATTERN (insn), 0, 0);
@@ -1652,7 +1621,7 @@ try_merge_delay_insns (insn, thread)
If we are not careful, this routine can take up a significant fraction
of the total compilation time (4%), but only wins rarely. Hence we
speed this routine up by making two passes. The first pass goes back
- until it hits a label and sees if it find an insn with an identical
+ until it hits a label and sees if it finds an insn with an identical
pattern. Only in this (relatively rare) event does it check for
data conflicts.
@@ -1661,10 +1630,7 @@ try_merge_delay_insns (insn, thread)
gain in rare cases. */
static rtx
-redundant_insn (insn, target, delay_list)
- rtx insn;
- rtx target;
- rtx delay_list;
+redundant_insn (rtx insn, rtx target, rtx delay_list)
{
rtx target_main = target;
rtx ipat = PATTERN (insn);
@@ -1871,10 +1837,7 @@ redundant_insn (insn, target, delay_list)
finding an active insn, we do not own this thread. */
static int
-own_thread_p (thread, label, allow_fallthrough)
- rtx thread;
- rtx label;
- int allow_fallthrough;
+own_thread_p (rtx thread, rtx label, int allow_fallthrough)
{
rtx active_insn;
rtx insn;
@@ -1918,9 +1881,7 @@ own_thread_p (thread, label, allow_fallthrough)
BARRIER in relax_delay_slots. */
static void
-update_block (insn, where)
- rtx insn;
- rtx where;
+update_block (rtx insn, rtx where)
{
/* Ignore if this was in a delay slot and it came from the target of
a branch. */
@@ -1939,9 +1900,7 @@ update_block (insn, where)
the basic block containing the jump. */
static int
-reorg_redirect_jump (jump, nlabel)
- rtx jump;
- rtx nlabel;
+reorg_redirect_jump (rtx jump, rtx nlabel)
{
incr_ticks_for_insn (jump);
return redirect_jump (jump, nlabel, 1);
@@ -1959,8 +1918,7 @@ reorg_redirect_jump (jump, nlabel)
is dead because it sees a REG_DEAD note immediately before a CODE_LABEL. */
static void
-update_reg_dead_notes (insn, delayed_insn)
- rtx insn, delayed_insn;
+update_reg_dead_notes (rtx insn, rtx delayed_insn)
{
rtx p, link, next;
@@ -1993,8 +1951,7 @@ update_reg_dead_notes (insn, delayed_insn)
confused into thinking the register is dead. */
static void
-fix_reg_dead_note (start_insn, stop_insn)
- rtx start_insn, stop_insn;
+fix_reg_dead_note (rtx start_insn, rtx stop_insn)
{
rtx p, link, next;
@@ -2024,8 +1981,7 @@ fix_reg_dead_note (start_insn, stop_insn)
does. */
static void
-update_reg_unused_notes (insn, redundant_insn)
- rtx insn, redundant_insn;
+update_reg_unused_notes (rtx insn, rtx redundant_insn)
{
rtx link, next;
@@ -2058,8 +2014,7 @@ update_reg_unused_notes (insn, redundant_insn)
through FINAL_SEQUENCE. */
static void
-fill_simple_delay_slots (non_jumps_p)
- int non_jumps_p;
+fill_simple_delay_slots (int non_jumps_p)
{
rtx insn, pat, trial, next_trial;
int i;
@@ -2403,7 +2358,9 @@ fill_simple_delay_slots (non_jumps_p)
&& eligible_for_delay (insn, slots_filled, next_trial, flags)
&& ! can_throw_internal (trial))
{
- rtx new_label = next_active_insn (next_trial);
+ /* See comment in relax_delay_slots about necessity of using
+ next_real_insn here. */
+ rtx new_label = next_real_insn (next_trial);
if (new_label != 0)
new_label = get_label_before (new_label);
@@ -2472,10 +2429,8 @@ fill_simple_delay_slots (non_jumps_p)
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
SET_HARD_REG_BIT (needed.regs, HARD_FRAME_POINTER_REGNUM);
#endif
-#ifdef EXIT_IGNORE_STACK
if (! EXIT_IGNORE_STACK
|| current_function_sp_is_unchanging)
-#endif
SET_HARD_REG_BIT (needed.regs, STACK_POINTER_REGNUM);
}
else
@@ -2562,17 +2517,10 @@ fill_simple_delay_slots (non_jumps_p)
slot. We then adjust the jump to point after the insns we have taken. */
static rtx
-fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
- thread_if_true, own_thread,
- slots_to_fill, pslots_filled, delay_list)
- rtx insn;
- rtx condition;
- rtx thread, opposite_thread;
- int likely;
- int thread_if_true;
- int own_thread;
- int slots_to_fill, *pslots_filled;
- rtx delay_list;
+fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
+ rtx opposite_thread, int likely, int thread_if_true,
+ int own_thread, int slots_to_fill,
+ int *pslots_filled, rtx delay_list)
{
rtx new_thread;
struct resources opposite_needed, set, needed;
@@ -2817,11 +2765,13 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
that would make the replacement into the insn invalid. We also can't
do this if it modifies our source, because it might be an earlyclobber
operand. This latter test also prevents updating the contents of
- a PRE_INC. */
+ a PRE_INC. We also can't do this if there's overlap of source and
+ destination. Overlap may happen for larger-than-register-size modes. */
if (GET_CODE (trial) == INSN && GET_CODE (pat) == SET
&& GET_CODE (SET_SRC (pat)) == REG
- && GET_CODE (SET_DEST (pat)) == REG)
+ && GET_CODE (SET_DEST (pat)) == REG
+ && !reg_overlap_mentioned_p (SET_DEST (pat), SET_SRC (pat)))
{
rtx next = next_nonnote_insn (trial);
@@ -2987,7 +2937,7 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
if safe. */
static void
-fill_eager_delay_slots ()
+fill_eager_delay_slots (void)
{
rtx insn;
int i;
@@ -3014,7 +2964,7 @@ fill_eager_delay_slots ()
delay slots only in certain circumstances which may depend on
nearby insns (which change due to reorg's actions).
- For example, the PA port normally has delay slots for unconditional
+ For example, the PA port normally has delay slots for unconditional
jumps.
However, the PA port claims such jumps do not have a delay slot
@@ -3115,8 +3065,7 @@ fill_eager_delay_slots ()
threading. */
static void
-relax_delay_slots (first)
- rtx first;
+relax_delay_slots (rtx first)
{
rtx insn, next, pat;
rtx trial, delay_insn, target_label;
@@ -3136,7 +3085,9 @@ relax_delay_slots (first)
&& (target_label = JUMP_LABEL (insn)) != 0)
{
target_label = follow_jumps (target_label);
- target_label = prev_label (next_active_insn (target_label));
+ /* See comment further down why we must use next_real_insn here,
+ instead of next_active_insn. */
+ target_label = prev_label (next_real_insn (target_label));
if (target_label == 0)
target_label = find_end_label ();
@@ -3481,8 +3432,7 @@ relax_delay_slots (first)
RETURN as well. */
static void
-make_return_insns (first)
- rtx first;
+make_return_insns (rtx first)
{
rtx insn, jump_insn, pat;
rtx real_return_label = end_of_function_label;
@@ -3613,9 +3563,7 @@ make_return_insns (first)
/* Try to find insns to place in delay slots. */
void
-dbr_schedule (first, file)
- rtx first;
- FILE *file;
+dbr_schedule (rtx first, FILE *file)
{
rtx insn, next, epilogue_insn = 0;
int i;
@@ -3647,7 +3595,7 @@ dbr_schedule (first, file)
epilogue_insn = insn;
}
- uid_to_ruid = (int *) xmalloc ((max_uid + 1) * sizeof (int));
+ uid_to_ruid = xmalloc ((max_uid + 1) * sizeof (int));
for (i = 0, insn = first; insn; i++, insn = NEXT_INSN (insn))
uid_to_ruid[INSN_UID (insn)] = i;
@@ -3655,7 +3603,7 @@ dbr_schedule (first, file)
if (unfilled_firstobj == 0)
{
gcc_obstack_init (&unfilled_slots_obstack);
- unfilled_firstobj = (rtx *) obstack_alloc (&unfilled_slots_obstack, 0);
+ unfilled_firstobj = obstack_alloc (&unfilled_slots_obstack, 0);
}
for (insn = next_active_insn (first); insn; insn = next_active_insn (insn))
@@ -3689,8 +3637,8 @@ dbr_schedule (first, file)
end_of_function_label = 0;
/* Initialize the statistics for this function. */
- memset ((char *) num_insns_needing_delays, 0, sizeof num_insns_needing_delays);
- memset ((char *) num_filled_delays, 0, sizeof num_filled_delays);
+ memset (num_insns_needing_delays, 0, sizeof num_insns_needing_delays);
+ memset (num_filled_delays, 0, sizeof num_filled_delays);
/* Now do the delay slot filling. Try everything twice in case earlier
changes make more slots fillable. */
@@ -3730,7 +3678,7 @@ dbr_schedule (first, file)
obstack_free (&unfilled_slots_obstack, unfilled_firstobj);
/* It is not clear why the line below is needed, but it does seem to be. */
- unfilled_firstobj = (rtx *) obstack_alloc (&unfilled_slots_obstack, 0);
+ unfilled_firstobj = obstack_alloc (&unfilled_slots_obstack, 0);
if (file)
{
@@ -3763,8 +3711,8 @@ dbr_schedule (first, file)
fprintf (file, "\n");
}
}
- memset ((char *) total_delay_slots, 0, sizeof total_delay_slots);
- memset ((char *) total_annul_slots, 0, sizeof total_annul_slots);
+ memset (total_delay_slots, 0, sizeof total_delay_slots);
+ memset (total_annul_slots, 0, sizeof total_annul_slots);
for (insn = first; insn; insn = NEXT_INSN (insn))
{
if (! INSN_DELETED_P (insn)
@@ -3843,5 +3791,17 @@ dbr_schedule (first, file)
}
free_resource_info ();
free (uid_to_ruid);
+#ifdef DELAY_SLOTS_FOR_EPILOGUE
+ /* SPARC assembler, for instance, emit warning when debug info is output
+ into the delay slot. */
+ {
+ rtx link;
+
+ for (link = current_function_epilogue_delay_list;
+ link;
+ link = XEXP (link, 1))
+ INSN_LOCATOR (XEXP (link, 0)) = 0;
+ }
+#endif
}
#endif /* DELAY_SLOTS */
diff --git a/contrib/gcc/resource.c b/contrib/gcc/resource.c
index a72dd9ce1a4f..240cf2323344 100644
--- a/contrib/gcc/resource.c
+++ b/contrib/gcc/resource.c
@@ -1,5 +1,6 @@
/* Definitions for computing resource usage of specific insns.
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "tm_p.h"
@@ -76,21 +79,18 @@ static HARD_REG_SET current_live_regs;
static HARD_REG_SET pending_dead_regs;
-static void update_live_status PARAMS ((rtx, rtx, void *));
-static int find_basic_block PARAMS ((rtx, int));
-static rtx next_insn_no_annul PARAMS ((rtx));
-static rtx find_dead_or_set_registers PARAMS ((rtx, struct resources*,
- rtx*, int, struct resources,
- struct resources));
+static void update_live_status (rtx, rtx, void *);
+static int find_basic_block (rtx, int);
+static rtx next_insn_no_annul (rtx);
+static rtx find_dead_or_set_registers (rtx, struct resources*,
+ rtx*, int, struct resources,
+ struct resources);
/* Utility function called from mark_target_live_regs via note_stores.
It deadens any CLOBBERed registers and livens any SET registers. */
static void
-update_live_status (dest, x, data)
- rtx dest;
- rtx x;
- void *data ATTRIBUTE_UNUSED;
+update_live_status (rtx dest, rtx x, void *data ATTRIBUTE_UNUSED)
{
int first_regno, last_regno;
int i;
@@ -129,9 +129,7 @@ update_live_status (dest, x, data)
correct. */
static int
-find_basic_block (insn, search_limit)
- rtx insn;
- int search_limit;
+find_basic_block (rtx insn, int search_limit)
{
basic_block bb;
@@ -157,7 +155,7 @@ find_basic_block (insn, search_limit)
insn = next_nonnote_insn (insn))
{
FOR_EACH_BB (bb)
- if (insn == bb->head)
+ if (insn == BB_HEAD (bb))
return bb->index;
}
@@ -168,8 +166,7 @@ find_basic_block (insn, search_limit)
an annulled branch. */
static rtx
-next_insn_no_annul (insn)
- rtx insn;
+next_insn_no_annul (rtx insn)
{
if (insn)
{
@@ -208,10 +205,8 @@ next_insn_no_annul (insn)
CALL_INSNs. */
void
-mark_referenced_resources (x, res, include_delayed_effects)
- rtx x;
- struct resources *res;
- int include_delayed_effects;
+mark_referenced_resources (rtx x, struct resources *res,
+ int include_delayed_effects)
{
enum rtx_code code = GET_CODE (x);
int i, j;
@@ -441,12 +436,9 @@ mark_referenced_resources (x, res, include_delayed_effects)
number of unconditional branches. */
static rtx
-find_dead_or_set_registers (target, res, jump_target, jump_count, set, needed)
- rtx target;
- struct resources *res;
- rtx *jump_target;
- int jump_count;
- struct resources set, needed;
+find_dead_or_set_registers (rtx target, struct resources *res,
+ rtx *jump_target, int jump_count,
+ struct resources set, struct resources needed)
{
HARD_REG_SET scratch;
rtx insn, next;
@@ -624,7 +616,7 @@ find_dead_or_set_registers (target, res, jump_target, jump_count, set, needed)
/* Given X, a part of an insn, and a pointer to a `struct resource',
RES, indicate which resources are modified by the insn. If
MARK_TYPE is MARK_SRC_DEST_CALL, also mark resources potentially
- set by the called routine. If MARK_TYPE is MARK_DEST, only mark SET_DESTs
+ set by the called routine.
If IN_DEST is nonzero, it means we are inside a SET. Otherwise,
objects are being referenced instead of set.
@@ -636,11 +628,8 @@ find_dead_or_set_registers (target, res, jump_target, jump_count, set, needed)
our computation and thus may be placed in a delay slot. */
void
-mark_set_resources (x, res, in_dest, mark_type)
- rtx x;
- struct resources *res;
- int in_dest;
- enum mark_resource_type mark_type;
+mark_set_resources (rtx x, struct resources *res, int in_dest,
+ enum mark_resource_type mark_type)
{
enum rtx_code code;
int i, j;
@@ -727,8 +716,7 @@ mark_set_resources (x, res, in_dest, mark_type)
|| GET_CODE (SET_SRC (x)) != CALL),
mark_type);
- if (mark_type != MARK_DEST)
- mark_set_resources (SET_SRC (x), res, 0, MARK_SRC_DEST);
+ mark_set_resources (SET_SRC (x), res, 0, MARK_SRC_DEST);
return;
case CLOBBER:
@@ -758,12 +746,9 @@ mark_set_resources (x, res, in_dest, mark_type)
case SIGN_EXTRACT:
case ZERO_EXTRACT:
- if (! (mark_type == MARK_DEST && in_dest))
- {
- mark_set_resources (XEXP (x, 0), res, in_dest, MARK_SRC_DEST);
- mark_set_resources (XEXP (x, 1), res, 0, MARK_SRC_DEST);
- mark_set_resources (XEXP (x, 2), res, 0, MARK_SRC_DEST);
- }
+ mark_set_resources (XEXP (x, 0), res, in_dest, MARK_SRC_DEST);
+ mark_set_resources (XEXP (x, 1), res, 0, MARK_SRC_DEST);
+ mark_set_resources (XEXP (x, 2), res, 0, MARK_SRC_DEST);
return;
case MEM:
@@ -810,13 +795,6 @@ mark_set_resources (x, res, in_dest, mark_type)
}
return;
- case STRICT_LOW_PART:
- if (! (mark_type == MARK_DEST && in_dest))
- {
- mark_set_resources (XEXP (x, 0), res, 0, MARK_SRC_DEST);
- return;
- }
-
case UNSPEC_VOLATILE:
case ASM_INPUT:
/* Traditional asm's are always volatile. */
@@ -900,10 +878,7 @@ mark_set_resources (x, res, in_dest, mark_type)
init_resource_info () was invoked before we are called. */
void
-mark_target_live_regs (insns, target, res)
- rtx insns;
- rtx target;
- struct resources *res;
+mark_target_live_regs (rtx insns, rtx target, struct resources *res)
{
int b = -1;
unsigned int i;
@@ -938,7 +913,7 @@ mark_target_live_regs (insns, target, res)
information, we can get it from there unless the insn at the
start of the basic block has been deleted. */
if (tinfo && tinfo->block != -1
- && ! INSN_DELETED_P (BLOCK_HEAD (tinfo->block)))
+ && ! INSN_DELETED_P (BB_HEAD (BASIC_BLOCK (tinfo->block))))
b = tinfo->block;
}
@@ -961,7 +936,7 @@ mark_target_live_regs (insns, target, res)
{
/* Allocate a place to put our results and chain it into the
hash table. */
- tinfo = (struct target_info *) xmalloc (sizeof (struct target_info));
+ tinfo = xmalloc (sizeof (struct target_info));
tinfo->uid = INSN_UID (target);
tinfo->block = b;
tinfo->next
@@ -1004,7 +979,7 @@ mark_target_live_regs (insns, target, res)
/* Get starting and ending insn, handling the case where each might
be a SEQUENCE. */
- start_insn = (b == 0 ? insns : BLOCK_HEAD (b));
+ start_insn = (b == 0 ? insns : BB_HEAD (BASIC_BLOCK (b)));
stop_insn = target;
if (GET_CODE (start_insn) == INSN
@@ -1170,8 +1145,7 @@ mark_target_live_regs (insns, target, res)
This should be invoked before the first call to mark_target_live_regs. */
void
-init_resource_info (epilogue_insn)
- rtx epilogue_insn;
+init_resource_info (rtx epilogue_insn)
{
int i;
@@ -1193,10 +1167,8 @@ init_resource_info (epilogue_insn)
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
SET_HARD_REG_BIT (end_of_function_needs.regs, HARD_FRAME_POINTER_REGNUM);
#endif
-#ifdef EXIT_IGNORE_STACK
if (! EXIT_IGNORE_STACK
|| current_function_sp_is_unchanging)
-#endif
SET_HARD_REG_BIT (end_of_function_needs.regs, STACK_POINTER_REGNUM);
}
else
@@ -1238,16 +1210,15 @@ init_resource_info (epilogue_insn)
MARK_SRC_DEST_CALL);
/* Allocate and initialize the tables used by mark_target_live_regs. */
- target_hash_table = (struct target_info **)
- xcalloc (TARGET_HASH_PRIME, sizeof (struct target_info *));
- bb_ticks = (int *) xcalloc (last_basic_block, sizeof (int));
+ target_hash_table = xcalloc (TARGET_HASH_PRIME, sizeof (struct target_info *));
+ bb_ticks = xcalloc (last_basic_block, sizeof (int));
}
-/* Free up the resources allcated to mark_target_live_regs (). This
+/* Free up the resources allocated to mark_target_live_regs (). This
should be invoked after the last call to mark_target_live_regs (). */
void
-free_resource_info ()
+free_resource_info (void)
{
if (target_hash_table != NULL)
{
@@ -1279,8 +1250,7 @@ free_resource_info ()
/* Clear any hashed information that we have stored for INSN. */
void
-clear_hashed_info_for_insn (insn)
- rtx insn;
+clear_hashed_info_for_insn (rtx insn)
{
struct target_info *tinfo;
@@ -1299,8 +1269,7 @@ clear_hashed_info_for_insn (insn)
/* Increment the tick count for the basic block that contains INSN. */
void
-incr_ticks_for_insn (insn)
- rtx insn;
+incr_ticks_for_insn (rtx insn)
{
int b = find_basic_block (insn, MAX_DELAY_SLOT_LIVE_SEARCH);
@@ -1311,9 +1280,7 @@ incr_ticks_for_insn (insn)
/* Add TRIAL to the set of resources used at the end of the current
function. */
void
-mark_end_of_function_resources (trial, include_delayed_effects)
- rtx trial;
- int include_delayed_effects;
+mark_end_of_function_resources (rtx trial, int include_delayed_effects)
{
mark_referenced_resources (trial, &end_of_function_needs,
include_delayed_effects);
diff --git a/contrib/gcc/resource.h b/contrib/gcc/resource.h
index fc2330c8e151..96eff6ed1ff1 100644
--- a/contrib/gcc/resource.h
+++ b/contrib/gcc/resource.h
@@ -1,5 +1,5 @@
/* Definitions for computing resource usage of specific insns.
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -37,16 +37,15 @@ struct resources
enum mark_resource_type
{
MARK_SRC_DEST = 0,
- MARK_SRC_DEST_CALL = 1,
- MARK_DEST = 2
+ MARK_SRC_DEST_CALL = 1
};
-extern void mark_target_live_regs PARAMS ((rtx, rtx, struct resources *));
-extern void mark_set_resources PARAMS ((rtx, struct resources *, int,
- enum mark_resource_type));
-extern void mark_referenced_resources PARAMS ((rtx, struct resources *, int));
-extern void clear_hashed_info_for_insn PARAMS ((rtx));
-extern void incr_ticks_for_insn PARAMS ((rtx));
-extern void mark_end_of_function_resources PARAMS ((rtx, int));
-extern void init_resource_info PARAMS ((rtx));
-extern void free_resource_info PARAMS ((void));
+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 clear_hashed_info_for_insn (rtx);
+extern void incr_ticks_for_insn (rtx);
+extern void mark_end_of_function_resources (rtx, int);
+extern void init_resource_info (rtx);
+extern void free_resource_info (void);
diff --git a/contrib/gcc/rtl-error.c b/contrib/gcc/rtl-error.c
index 2b660c94fb7b..72ef094b112a 100644
--- a/contrib/gcc/rtl-error.c
+++ b/contrib/gcc/rtl-error.c
@@ -1,5 +1,5 @@
-/* RTL specific diagnostic subroutines for the GNU C compiler
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+/* RTL specific diagnostic subroutines for GCC
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
This file is part of GCC.
@@ -23,6 +23,8 @@ Boston, MA 02111-1307, USA. */
#undef FLOAT /* This is for hpux. They should change hpux. */
#undef FFS /* Some systems define this in param.h. */
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "insn-attr.h"
#include "insn-config.h"
@@ -31,19 +33,16 @@ Boston, MA 02111-1307, USA. */
#include "intl.h"
#include "diagnostic.h"
-static void file_and_line_for_asm PARAMS ((rtx, const char **, int *));
-static void diagnostic_for_asm PARAMS ((rtx, const char *, va_list *,
- diagnostic_t));
+static location_t location_for_asm (rtx);
+static void diagnostic_for_asm (rtx, const char *, va_list *, diagnostic_t);
-/* Figure file and line of the given INSN. */
-static void
-file_and_line_for_asm (insn, pfile, pline)
- rtx insn;
- const char **pfile;
- int *pline;
+/* Figure the location of the given INSN. */
+static location_t
+location_for_asm (rtx insn)
{
rtx body = PATTERN (insn);
rtx asmop;
+ location_t loc;
/* Find the (or one of the) ASM_OPERANDS in the insn. */
if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
@@ -61,63 +60,51 @@ file_and_line_for_asm (insn, pfile, pline)
if (asmop)
{
- *pfile = ASM_OPERANDS_SOURCE_FILE (asmop);
- *pline = ASM_OPERANDS_SOURCE_LINE (asmop);
+ loc.file = ASM_OPERANDS_SOURCE_FILE (asmop);
+ loc.line = ASM_OPERANDS_SOURCE_LINE (asmop);
}
else
- {
- *pfile = input_filename;
- *pline = lineno;
- }
+ loc = input_location;
+ return loc;
}
/* Report a diagnostic MESSAGE (an errror or a WARNING) at the line number
of the insn INSN. This is used only when INSN is an `asm' with operands,
and each ASM_OPERANDS records its own source file and line. */
static void
-diagnostic_for_asm (insn, msg, args_ptr, kind)
- rtx insn;
- const char *msg;
- va_list *args_ptr;
- diagnostic_t kind;
+diagnostic_for_asm (rtx insn, const char *msg, va_list *args_ptr,
+ diagnostic_t kind)
{
diagnostic_info diagnostic;
- diagnostic_set_info (&diagnostic, msg, args_ptr, NULL, 0, kind);
- file_and_line_for_asm (insn, &diagnostic.location.file,
- &diagnostic.location.line);
+ diagnostic_set_info (&diagnostic, msg, args_ptr,
+ location_for_asm (insn), kind);
report_diagnostic (&diagnostic);
}
void
-error_for_asm VPARAMS ((rtx insn, const char *msgid, ...))
+error_for_asm (rtx insn, const char *msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, rtx, insn);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_list ap;
+ va_start (ap, msgid);
diagnostic_for_asm (insn, msgid, &ap, DK_ERROR);
- VA_CLOSE (ap);
+ va_end (ap);
}
void
-warning_for_asm VPARAMS ((rtx insn, const char *msgid, ...))
+warning_for_asm (rtx insn, const char *msgid, ...)
{
- VA_OPEN (ap, msgid);
- VA_FIXEDARG (ap, rtx, insn);
- VA_FIXEDARG (ap, const char *, msgid);
+ va_list ap;
+ va_start (ap, msgid);
diagnostic_for_asm (insn, msgid, &ap, DK_WARNING);
- VA_CLOSE (ap);
+ va_end (ap);
}
void
-_fatal_insn (msgid, insn, file, line, function)
- const char *msgid;
- rtx insn;
- const char *file;
- int line;
- const char *function;
+_fatal_insn (const char *msgid, rtx insn, const char *file, int line,
+ const char *function)
{
error ("%s", _(msgid));
@@ -130,11 +117,8 @@ _fatal_insn (msgid, insn, file, line, function)
}
void
-_fatal_insn_not_found (insn, file, line, function)
- rtx insn;
- const char *file;
- int line;
- const char *function;
+_fatal_insn_not_found (rtx insn, const char *file, int line,
+ const char *function)
{
if (INSN_CODE (insn) < 0)
_fatal_insn ("unrecognizable insn:", insn, file, line, function);
@@ -142,4 +126,3 @@ _fatal_insn_not_found (insn, file, line, function)
_fatal_insn ("insn does not satisfy its constraints:",
insn, file, line, function);
}
-
diff --git a/contrib/gcc/rtl.c b/contrib/gcc/rtl.c
index 8c6de3c7370c..313e2cb2b5c3 100644
--- a/contrib/gcc/rtl.c
+++ b/contrib/gcc/rtl.c
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "real.h"
#include "ggc.h"
@@ -48,115 +50,6 @@ const char * const rtx_name[NUM_RTX_CODE] = {
#undef DEF_RTL_EXPR
-/* Indexed by machine mode, gives the name of that machine mode.
- This name does not include the letters "mode". */
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) NAME,
-
-const char * const mode_name[NUM_MACHINE_MODES] = {
-#include "machmode.def"
-};
-
-#undef DEF_MACHMODE
-
-/* Indexed by machine mode, gives the class mode for GET_MODE_CLASS. */
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) CLASS,
-
-const enum mode_class mode_class[NUM_MACHINE_MODES] = {
-#include "machmode.def"
-};
-
-#undef DEF_MACHMODE
-
-/* Indexed by machine mode, gives the length of the mode, in bits.
- GET_MODE_BITSIZE uses this. */
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) BITSIZE,
-
-const unsigned short mode_bitsize[NUM_MACHINE_MODES] = {
-#include "machmode.def"
-};
-
-#undef DEF_MACHMODE
-
-/* Indexed by machine mode, gives the length of the mode, in bytes.
- GET_MODE_SIZE uses this. */
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) SIZE,
-
-const unsigned char mode_size[NUM_MACHINE_MODES] = {
-#include "machmode.def"
-};
-
-#undef DEF_MACHMODE
-
-/* Indexed by machine mode, gives the length of the mode's subunit.
- GET_MODE_UNIT_SIZE uses this. */
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) UNIT,
-
-const unsigned char mode_unit_size[NUM_MACHINE_MODES] = {
-#include "machmode.def" /* machine modes are documented here */
-};
-
-#undef DEF_MACHMODE
-
-/* Indexed by machine mode, gives next wider natural mode
- (QI -> HI -> SI -> DI, etc.) Widening multiply instructions
- use this. */
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) \
- (unsigned char) WIDER,
-
-const unsigned char mode_wider_mode[NUM_MACHINE_MODES] = {
-#include "machmode.def" /* machine modes are documented here */
-};
-
-#undef DEF_MACHMODE
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) \
- ((BITSIZE) >= HOST_BITS_PER_WIDE_INT) ? ~(unsigned HOST_WIDE_INT) 0 : ((unsigned HOST_WIDE_INT) 1 << (BITSIZE)) - 1,
-
-/* Indexed by machine mode, gives mask of significant bits in mode. */
-
-const unsigned HOST_WIDE_INT mode_mask_array[NUM_MACHINE_MODES] = {
-#include "machmode.def"
-};
-
-#undef DEF_MACHMODE
-
-#define DEF_MACHMODE(SYM, NAME, CLASS, BITSIZE, SIZE, UNIT, WIDER, INNER) INNER,
-
-/* Indexed by machine mode, gives the mode of the inner elements in a
- vector type. */
-
-const enum machine_mode inner_mode_array[NUM_MACHINE_MODES] = {
-#include "machmode.def"
-};
-
-/* Indexed by mode class, gives the narrowest mode for each class.
- The Q modes are always of width 1 (2 for complex) - it is impossible
- for any mode to be narrower.
-
- Note that we use QImode instead of BImode for MODE_INT, since
- otherwise the middle end will try to use it for bitfields in
- structures and the like, which we do not want. Only the target
- md file should generate BImode widgets. */
-
-const enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS] = {
- /* MODE_RANDOM */ VOIDmode,
- /* MODE_INT */ QImode,
- /* MODE_FLOAT */ QFmode,
- /* MODE_PARTIAL_INT */ PQImode,
- /* MODE_CC */ CCmode,
- /* MODE_COMPLEX_INT */ CQImode,
- /* MODE_COMPLEX_FLOAT */ QCmode,
- /* MODE_VECTOR_INT */ V1DImode,
- /* MODE_VECTOR_FLOAT */ V2SFmode
-};
-
-
/* Indexed by rtx code, gives a sequence of operand-types for
rtx's of that code. The sequence is a C string in which
each character describes one operand. */
@@ -203,6 +96,18 @@ const char rtx_class[NUM_RTX_CODE] = {
#undef DEF_RTL_EXPR
};
+/* Indexed by rtx code, gives the size of the rtx in bytes. */
+
+const unsigned char rtx_size[NUM_RTX_CODE] = {
+#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) \
+ ((ENUM) == CONST_INT || (ENUM) == CONST_DOUBLE \
+ ? RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (HOST_WIDE_INT) \
+ : RTX_HDR_SIZE + (sizeof FORMAT - 1) * sizeof (rtunion)),
+
+#include "rtl.def"
+#undef DEF_RTL_EXPR
+};
+
/* Names for kinds of NOTEs and REG_NOTEs. */
const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS] =
@@ -223,23 +128,30 @@ const char * const note_insn_name[NOTE_INSN_MAX - NOTE_INSN_BIAS] =
const char * const reg_note_name[] =
{
"", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_EQUAL",
- "REG_WAS_0", "REG_RETVAL", "REG_LIBCALL", "REG_NONNEG",
+ "REG_RETVAL", "REG_LIBCALL", "REG_NONNEG",
"REG_NO_CONFLICT", "REG_UNUSED", "REG_CC_SETTER", "REG_CC_USER",
"REG_LABEL", "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
- "REG_NOALIAS", "REG_SAVE_AREA", "REG_BR_PRED",
+ "REG_VALUE_PROFILE", "REG_NOALIAS", "REG_SAVE_AREA", "REG_BR_PRED",
"REG_FRAME_RELATED_EXPR", "REG_EH_CONTEXT", "REG_EH_REGION",
"REG_SAVE_NOTE", "REG_MAYBE_DEAD", "REG_NORETURN",
"REG_NON_LOCAL_GOTO", "REG_SETJMP", "REG_ALWAYS_RETURN",
"REG_VTABLE_REF"
};
+
+#ifdef GATHER_STATISTICS
+static int rtx_alloc_counts[(int) LAST_AND_UNUSED_RTX_CODE];
+static int rtx_alloc_sizes[(int) LAST_AND_UNUSED_RTX_CODE];
+static int rtvec_alloc_counts;
+static int rtvec_alloc_sizes;
+#endif
+
/* Allocate an rtx vector of N elements.
Store the length, and initialize all elements to zero. */
rtvec
-rtvec_alloc (n)
- int n;
+rtvec_alloc (int n)
{
rtvec rt;
@@ -248,6 +160,12 @@ rtvec_alloc (n)
memset (&rt->elem[0], 0, n * sizeof (rtx));
PUT_NUM_ELEM (rt, n);
+
+#ifdef GATHER_STATISTICS
+ rtvec_alloc_counts++;
+ rtvec_alloc_sizes += n * sizeof (rtx);
+#endif
+
return rt;
}
@@ -255,20 +173,24 @@ rtvec_alloc (n)
all the rest is initialized to zero. */
rtx
-rtx_alloc (code)
- RTX_CODE code;
+rtx_alloc (RTX_CODE code)
{
rtx rt;
- int n = GET_RTX_LENGTH (code);
- rt = ggc_alloc_rtx (n);
+ rt = ggc_alloc_rtx (code);
/* We want to clear everything up to the FLD array. Normally, this
is one int, but we don't want to assume that and it isn't very
portable anyway; this is. */
- memset (rt, 0, sizeof (struct rtx_def) - sizeof (rtunion));
+ memset (rt, 0, RTX_HDR_SIZE);
PUT_CODE (rt, code);
+
+#ifdef GATHER_STATISTICS
+ rtx_alloc_counts[code]++;
+ rtx_alloc_sizes[code] += RTX_SIZE (code);
+#endif
+
return rt;
}
@@ -278,8 +200,7 @@ rtx_alloc (code)
except for those few rtx codes that are sharable. */
rtx
-copy_rtx (orig)
- rtx orig;
+copy_rtx (rtx orig)
{
rtx copy;
int i, j;
@@ -328,7 +249,7 @@ copy_rtx (orig)
all fields need copying, and then clear the fields that should
not be copied. That is the sensible default behavior, and forces
us to explicitly document why we are *not* copying a flag. */
- memcpy (copy, orig, sizeof (struct rtx_def) - sizeof (rtunion));
+ memcpy (copy, orig, RTX_HDR_SIZE);
/* We do not copy the USED flag, which is used as a mark bit during
walks over the RTL. */
@@ -344,7 +265,7 @@ copy_rtx (orig)
for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
{
- copy->fld[i] = orig->fld[i];
+ copy->u.fld[i] = orig->u.fld[i];
switch (*format_ptr++)
{
case 'e':
@@ -384,16 +305,12 @@ copy_rtx (orig)
/* Create a new copy of an rtx. Only copy just one level. */
rtx
-shallow_copy_rtx (orig)
- rtx orig;
+shallow_copy_rtx (rtx orig)
{
- RTX_CODE code = GET_CODE (orig);
- size_t n = GET_RTX_LENGTH (code);
- rtx copy = ggc_alloc_rtx (n);
-
- memcpy (copy, orig,
- sizeof (struct rtx_def) + sizeof (rtunion) * (n - 1));
+ rtx copy;
+ copy = ggc_alloc_rtx (GET_CODE (orig));
+ memcpy (copy, orig, RTX_SIZE (GET_CODE (orig)));
return copy;
}
@@ -407,8 +324,7 @@ int generating_concat_p;
This is the Lisp function EQUAL for rtx arguments. */
int
-rtx_equal_p (x, y)
- rtx x, y;
+rtx_equal_p (rtx x, rtx y)
{
int i;
int j;
@@ -461,7 +377,7 @@ rtx_equal_p (x, y)
}
/* Compare the elements. If any pair of corresponding elements
- fail to match, return 0 for the whole things. */
+ fail to match, return 0 for the whole thing. */
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
@@ -521,15 +437,41 @@ rtx_equal_p (x, y)
}
return 1;
}
+
+void dump_rtx_statistics (void)
+{
+#ifdef GATHER_STATISTICS
+ int i;
+ int total_counts = 0;
+ int total_sizes = 0;
+ fprintf (stderr, "\nRTX Kind Count Bytes\n");
+ fprintf (stderr, "---------------------------------------\n");
+ for (i = 0; i < LAST_AND_UNUSED_RTX_CODE; i++)
+ if (rtx_alloc_counts[i])
+ {
+ fprintf (stderr, "%-20s %7d %10d\n", GET_RTX_NAME (i),
+ rtx_alloc_counts[i], rtx_alloc_sizes[i]);
+ total_counts += rtx_alloc_counts[i];
+ total_sizes += rtx_alloc_sizes[i];
+ }
+ if (rtvec_alloc_counts)
+ {
+ fprintf (stderr, "%-20s %7d %10d\n", "rtvec",
+ rtvec_alloc_counts, rtvec_alloc_sizes);
+ total_counts += rtvec_alloc_counts;
+ total_sizes += rtvec_alloc_sizes;
+ }
+ fprintf (stderr, "---------------------------------------\n");
+ fprintf (stderr, "%-20s %7d %10d\n",
+ "Total", total_counts, total_sizes);
+ fprintf (stderr, "---------------------------------------\n");
+#endif
+}
#if defined ENABLE_RTL_CHECKING && (GCC_VERSION >= 2007)
void
-rtl_check_failed_bounds (r, n, file, line, func)
- rtx r;
- int n;
- const char *file;
- int line;
- const char *func;
+rtl_check_failed_bounds (rtx r, int n, const char *file, int line,
+ const char *func)
{
internal_error
("RTL check: access of elt %d of `%s' with last elt %d in %s, at %s:%d",
@@ -538,13 +480,8 @@ rtl_check_failed_bounds (r, n, file, line, func)
}
void
-rtl_check_failed_type1 (r, n, c1, file, line, func)
- rtx r;
- int n;
- int c1;
- const char *file;
- int line;
- const char *func;
+rtl_check_failed_type1 (rtx r, int n, int c1, const char *file, int line,
+ const char *func)
{
internal_error
("RTL check: expected elt %d type '%c', have '%c' (rtx %s) in %s, at %s:%d",
@@ -553,14 +490,8 @@ rtl_check_failed_type1 (r, n, c1, file, line, func)
}
void
-rtl_check_failed_type2 (r, n, c1, c2, file, line, func)
- rtx r;
- int n;
- int c1;
- int c2;
- const char *file;
- int line;
- const char *func;
+rtl_check_failed_type2 (rtx r, int n, int c1, int c2, const char *file,
+ int line, const char *func)
{
internal_error
("RTL check: expected elt %d type '%c' or '%c', have '%c' (rtx %s) in %s, at %s:%d",
@@ -569,12 +500,8 @@ rtl_check_failed_type2 (r, n, c1, c2, file, line, func)
}
void
-rtl_check_failed_code1 (r, code, file, line, func)
- rtx r;
- enum rtx_code code;
- const char *file;
- int line;
- const char *func;
+rtl_check_failed_code1 (rtx r, enum rtx_code code, const char *file,
+ int line, const char *func)
{
internal_error ("RTL check: expected code `%s', have `%s' in %s, at %s:%d",
GET_RTX_NAME (code), GET_RTX_NAME (GET_CODE (r)), func,
@@ -582,12 +509,8 @@ rtl_check_failed_code1 (r, code, file, line, func)
}
void
-rtl_check_failed_code2 (r, code1, code2, file, line, func)
- rtx r;
- enum rtx_code code1, code2;
- const char *file;
- int line;
- const char *func;
+rtl_check_failed_code2 (rtx r, enum rtx_code code1, enum rtx_code code2,
+ const char *file, int line, const char *func)
{
internal_error
("RTL check: expected code `%s' or `%s', have `%s' in %s, at %s:%d",
@@ -597,12 +520,8 @@ rtl_check_failed_code2 (r, code1, code2, file, line, func)
/* XXX Maybe print the vector? */
void
-rtvec_check_failed_bounds (r, n, file, line, func)
- rtvec r;
- int n;
- const char *file;
- int line;
- const char *func;
+rtvec_check_failed_bounds (rtvec r, int n, const char *file, int line,
+ const char *func)
{
internal_error
("RTL check: access of elt %d of vector with last elt %d in %s, at %s:%d",
@@ -612,12 +531,8 @@ rtvec_check_failed_bounds (r, n, file, line, func)
#if defined ENABLE_RTL_FLAG_CHECKING
void
-rtl_check_failed_flag (name, r, file, line, func)
- const char *name;
- rtx r;
- const char *file;
- int line;
- const char *func;
+rtl_check_failed_flag (const char *name, rtx r, const char *file,
+ int line, const char *func)
{
internal_error
("RTL flag check: %s used with unexpected rtx code `%s' in %s, at %s:%d",
diff --git a/contrib/gcc/rtl.def b/contrib/gcc/rtl.def
index d281406fee47..9306abc7a063 100644
--- a/contrib/gcc/rtl.def
+++ b/contrib/gcc/rtl.def
@@ -39,7 +39,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
These names are stored in rtx_name[].
By convention these are the internal (field 1) names in lower_case.
- 3. The print format, and type of each rtx->fld[] (field) in this rtx.
+ 3. The print format, and type of each rtx->u.fld[] (field) in this rtx.
These formats are stored in rtx_format[].
The meaning of the formats is documented in front of this array in rtl.c
@@ -358,9 +358,8 @@ DEF_RTL_EXPR(ADDRESS, "address", "e", 'm')
DEF_RTL_EXPR(DEFINE_CPU_UNIT, "define_cpu_unit", "sS", 'x')
/* (define_query_cpu_unit string [string]) describes cpu functional
- units analogously to define_cpu_unit. If we use automaton without
- minimization, the reservation of such units can be queried for
- automaton state. */
+ units analogously to define_cpu_unit. The reservation of such
+ units can be queried for automaton state. */
DEF_RTL_EXPR(DEFINE_QUERY_CPU_UNIT, "define_query_cpu_unit", "sS", 'x')
/* (exclusion_set string string) means that each CPU functional unit
@@ -370,28 +369,80 @@ DEF_RTL_EXPR(DEFINE_QUERY_CPU_UNIT, "define_query_cpu_unit", "sS", 'x')
for description CPU with fully pipelined floating point functional
unit which can execute simultaneously only single floating point
insns or only double floating point insns. All CPU functional
- units in a set should belong the same automaton. */
+ units in a set should belong to the same automaton. */
DEF_RTL_EXPR(EXCLUSION_SET, "exclusion_set", "ss", 'x')
/* (presence_set string string) means that each CPU functional unit in
- the first string can not be reserved unless at least one of units
- whose names are in the second string is reserved. This is an
- asymmetric relation. CPU units in the string are separated by
- commas. For example, it is useful for description that slot1 is
- reserved after slot0 reservation for VLIW processor. All CPU
- functional units in a set should belong the same automaton. */
+ the first string can not be reserved unless at least one of pattern
+ of units whose names are in the second string is reserved. This is
+ an asymmetric relation. CPU units or unit patterns in the strings
+ are separated by commas. Pattern is one unit name or unit names
+ separated by white-spaces.
+
+ For example, it is useful for description that slot1 is reserved
+ after slot0 reservation for a VLIW processor. We could describe it
+ by the following construction
+
+ (presence_set "slot1" "slot0")
+
+ Or slot1 is reserved only after slot0 and unit b0 reservation. In
+ this case we could write
+
+ (presence_set "slot1" "slot0 b0")
+
+ All CPU functional units in a set should belong to the same
+ automaton. */
DEF_RTL_EXPR(PRESENCE_SET, "presence_set", "ss", 'x')
+/* (final_presence_set string string) is analogous to `presence_set'.
+ The difference between them is when checking is done. When an
+ instruction is issued in given automaton state reflecting all
+ current and planned unit reservations, the automaton state is
+ changed. The first state is a source state, the second one is a
+ result state. Checking for `presence_set' is done on the source
+ state reservation, checking for `final_presence_set' is done on the
+ result reservation. This construction is useful to describe a
+ reservation which is actually two subsequent reservations. For
+ example, if we use
+
+ (presence_set "slot1" "slot0")
+
+ the following insn will be never issued (because slot1 requires
+ slot0 which is absent in the source state).
+
+ (define_reservation "insn_and_nop" "slot0 + slot1")
+
+ but it can be issued if we use analogous `final_presence_set'. */
+DEF_RTL_EXPR(FINAL_PRESENCE_SET, "final_presence_set", "ss", 'x')
+
/* (absence_set string string) means that each CPU functional unit in
- the first string can not be reserved only if each unit whose name
- is in the second string is not reserved. This is an asymmetric
- relation (actually exclusion set is analogous to this one but it is
- symmetric). CPU units in the string are separated by commas. For
- example, it is useful for description that slot0 can not be
- reserved after slot1 or slot2 reservation for VLIW processor. All
- CPU functional units in a set should belong the same automaton. */
+ the first string can be reserved only if each pattern of units
+ whose names are in the second string is not reserved. This is an
+ asymmetric relation (actually exclusion set is analogous to this
+ one but it is symmetric). CPU units or unit patterns in the string
+ are separated by commas. Pattern is one unit name or unit names
+ separated by white-spaces.
+
+ For example, it is useful for description that slot0 can not be
+ reserved after slot1 or slot2 reservation for a VLIW processor. We
+ could describe it by the following construction
+
+ (absence_set "slot2" "slot0, slot1")
+
+ Or slot2 can not be reserved if slot0 and unit b0 are reserved or
+ slot1 and unit b1 are reserved . In this case we could write
+
+ (absence_set "slot2" "slot0 b0, slot1 b1")
+
+ All CPU functional units in a set should to belong the same
+ automaton. */
DEF_RTL_EXPR(ABSENCE_SET, "absence_set", "ss", 'x')
+/* (final_absence_set string string) is analogous to `absence_set' but
+ checking is done on the result (state) reservation. See comments
+ for `final_presence_set'. */
+DEF_RTL_EXPR(FINAL_ABSENCE_SET, "final_absence_set", "ss", 'x')
+
/* (define_bypass number out_insn_names in_insn_names) names bypass
with given latency (the first number) from insns given by the first
string (see define_insn_reservation) into insns given by the second
@@ -416,8 +467,8 @@ DEF_RTL_EXPR(DEFINE_AUTOMATON, "define_automaton", "s", 'x')
automata. Currently there are the following options:
o "no-minimization" which makes no minimization of automata. This
- is only worth to do when we are going to query CPU functional
- unit reservations in an automaton state.
+ is only worth to do when we are debugging the description and
+ need to look more accurately at reservations of states.
o "time" which means printing additional time statistics about
generation of automata.
@@ -429,7 +480,10 @@ DEF_RTL_EXPR(DEFINE_AUTOMATON, "define_automaton", "s", 'x')
o "w" which means generation of warning instead of error for
non-critical errors.
- o "ndfa" which makes nondeterministic finite state automata. */
+ o "ndfa" which makes nondeterministic finite state automata.
+
+ o "progress" which means output of a progress bar showing how many
+ states were generated so far for automaton being processed. */
DEF_RTL_EXPR(AUTOMATA_OPTION, "automata_option", "s", 'x')
/* (define_reservation string string) names reservation (the first
@@ -477,7 +531,7 @@ DEF_RTL_EXPR(DEFINE_RESERVATION, "define_reservation", "ss", 'x')
first regular expression *and* the reservation described by the
second regular expression *and* etc.
- 4. "*" is used for convinience and simply means sequence in
+ 4. "*" is used for convenience and simply means sequence in
which the regular expression are repeated NUMBER times with
cycle advancing (see ",").
@@ -531,6 +585,10 @@ DEF_RTL_EXPR(SET_ATTR_ALTERNATIVE, "set_attr_alternative", "sE", 'x')
attribute name and the second is the comparison value. */
DEF_RTL_EXPR(EQ_ATTR, "eq_attr", "ss", 'x')
+/* A special case of the above representing a set of alternatives. The first
+ operand is bitmap of the set, the second one is the default value. */
+DEF_RTL_EXPR(EQ_ATTR_ALT, "eq_attr_alt", "ii", 'x')
+
/* A conditional expression which is true if the specified flag is
true for the insn being scheduled in reorg.
@@ -547,43 +605,41 @@ DEF_RTL_EXPR (ATTR_FLAG, "attr_flag", "s", 'x')
All formats must start with "iuu" to handle the chain.
Each insn expression holds an rtl instruction and its semantics
during back-end processing.
- See macros's in "rtl.h" for the meaning of each rtx->fld[].
+ See macros's in "rtl.h" for the meaning of each rtx->u.fld[].
---------------------------------------------------------------------- */
/* An instruction that cannot jump. */
-DEF_RTL_EXPR(INSN, "insn", "iuuBteiee", 'i')
+DEF_RTL_EXPR(INSN, "insn", "iuuBieiee", 'i')
/* An instruction that can possibly jump.
- Fields ( rtx->fld[] ) have exact same meaning as INSN's. */
-DEF_RTL_EXPR(JUMP_INSN, "jump_insn", "iuuBteiee0", 'i')
+ Fields ( rtx->u.fld[] ) have exact same meaning as INSN's. */
+DEF_RTL_EXPR(JUMP_INSN, "jump_insn", "iuuBieiee0", 'i')
/* An instruction that can possibly call a subroutine
but which will not change which instruction comes next
in the current function.
- Field ( rtx->fld[9] ) is CALL_INSN_FUNCTION_USAGE.
- All other fields ( rtx->fld[] ) have exact same meaning as INSN's. */
-DEF_RTL_EXPR(CALL_INSN, "call_insn", "iuuBteieee", 'i')
+ Field ( rtx->u.fld[9] ) is CALL_INSN_FUNCTION_USAGE.
+ All other fields ( rtx->u.fld[] ) have exact same meaning as INSN's. */
+DEF_RTL_EXPR(CALL_INSN, "call_insn", "iuuBieieee", 'i')
/* A marker that indicates that control will not flow through. */
DEF_RTL_EXPR(BARRIER, "barrier", "iuu000000", 'x')
/* Holds a label that is followed by instructions.
Operand:
- 5: is used in jump.c for the use-count of the label.
- 6: is used in flow.c to point to the chain of label_ref's to this label.
- 7: is a number that is unique in the entire compilation.
- 8: is the user-given name of the label, if any. */
+ 4: is used in jump.c for the use-count of the label.
+ 5: is used in flow.c to point to the chain of label_ref's to this label.
+ 6: is a number that is unique in the entire compilation.
+ 7: is the user-given name of the label, if any. */
DEF_RTL_EXPR(CODE_LABEL, "code_label", "iuuB00is", 'x')
/* Say where in the code a source line starts, for symbol table's sake.
Operand:
- 5: filename, if line number > 0, note-specific data otherwise.
- 6: line number if > 0, enum note_insn otherwise.
- 7: unique number if line number == note_insn_deleted_label.
- 8-9: padding so that notes and insns are the same size, and thus
- allocated from the same page ordering. */
-DEF_RTL_EXPR(NOTE, "note", "iuuB0ni00", 'x')
+ 4: filename, if line number > 0, note-specific data otherwise.
+ 5: line number if > 0, enum note_insn otherwise.
+ 6: unique number if line number == note_insn_deleted_label. */
+DEF_RTL_EXPR(NOTE, "note", "iuuB0ni", 'x')
/* ----------------------------------------------------------------------
Top level constituents of INSN, JUMP_INSN and CALL_INSN.
@@ -758,7 +814,7 @@ DEF_RTL_EXPR(VALUE, "value", "0", 'o')
pseudo register that got turned into a hard register.
This rtx needs to have as many (or more) fields as a MEM, since we
can change REG rtx's into MEMs during reload. */
-DEF_RTL_EXPR(REG, "reg", "i0", 'o')
+DEF_RTL_EXPR(REG, "reg", "i00", 'o')
/* A scratch register. This represents a register used only within a
single insn. It will be turned into a REG during register allocation
@@ -807,11 +863,12 @@ DEF_RTL_EXPR(MEM, "mem", "e0", 'o')
LABEL_NEXTREF and CONTAINING_INSN. */
DEF_RTL_EXPR(LABEL_REF, "label_ref", "u00", 'o')
-/* Reference to a named label: the string that is the first operand,
- with `_' added implicitly in front.
- Exception: if the first character explicitly given is `*',
- to give it to the assembler, remove the `*' and do not add `_'. */
-DEF_RTL_EXPR(SYMBOL_REF, "symbol_ref", "s", 'o')
+/* Reference to a named label:
+ Operand 0: label name
+ Operand 1: flags (see SYMBOL_FLAG_* in rtl.h)
+ Operand 2: tree from which this symbol is derived, or null.
+ This is either a DECL node, or some kind of constant. */
+DEF_RTL_EXPR(SYMBOL_REF, "symbol_ref", "s00", 'o')
/* The condition code register is represented, in our imagination,
as a register holding a value that can be compared to zero.
@@ -958,7 +1015,7 @@ DEF_RTL_EXPR(GTU, "gtu", "ee", '<')
DEF_RTL_EXPR(LEU, "leu", "ee", '<')
DEF_RTL_EXPR(LTU, "ltu", "ee", '<')
-/* Additional floating point unordered comparision flavors. */
+/* Additional floating point unordered comparison flavors. */
DEF_RTL_EXPR(UNORDERED, "unordered", "ee", '<')
DEF_RTL_EXPR(ORDERED, "ordered", "ee", '<')
@@ -1017,6 +1074,18 @@ DEF_RTL_EXPR(SQRT, "sqrt", "e", '1')
or 0 if arg is 0. */
DEF_RTL_EXPR(FFS, "ffs", "e", '1')
+/* Count leading zeros. */
+DEF_RTL_EXPR(CLZ, "clz", "e", '1')
+
+/* Count trailing zeros. */
+DEF_RTL_EXPR(CTZ, "ctz", "e", '1')
+
+/* Population count (number of 1 bits). */
+DEF_RTL_EXPR(POPCOUNT, "popcount", "e", '1')
+
+/* Population parity (number of 1 bits modulo 2). */
+DEF_RTL_EXPR(PARITY, "parity", "e", '1')
+
/* Reference to a signed bit-field of specified size and position.
Operand 0 is the memory unit (usually SImode or QImode) which
contains the field's first bit. Operand 1 is the width, in bits.
@@ -1146,20 +1215,6 @@ DEF_RTL_EXPR(SS_TRUNCATE, "ss_truncate", "e", '1')
/* Unsigned saturating truncate. */
DEF_RTL_EXPR(US_TRUNCATE, "us_truncate", "e", '1')
-/* The SSA phi operator.
-
- The argument is a vector of 2N rtxes. Element 2N+1 is a CONST_INT
- containing the block number of the predecessor through which control
- has passed when the register at element 2N is used.
-
- Note that PHI may only appear at the beginning of a basic block.
-
- ??? There may be multiple PHI insns, but they are all evaluated
- in parallel. This probably ought to be changed to use a real
- PARALLEL, as that would be less confusing and more in the spirit
- of canonical RTL. It is, however, easier to manipulate this way. */
-DEF_RTL_EXPR(PHI, "phi", "E", 'x')
-
/*
Local variables:
diff --git a/contrib/gcc/rtl.h b/contrib/gcc/rtl.h
index a2cb1dbf1ab9..27455f22da58 100644
--- a/contrib/gcc/rtl.h
+++ b/contrib/gcc/rtl.h
@@ -1,6 +1,6 @@
-/* Register Transfer Language (RTL) definitions for GNU C-Compiler
+/* Register Transfer Language (RTL) definitions for GCC
Copyright (C) 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -25,6 +25,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
struct function;
#include "machmode.h"
+#include "input.h"
#undef FFS /* Some systems predefine this symbol; don't let it interfere. */
#undef FLOAT /* Likewise. */
@@ -63,6 +64,7 @@ extern const char * const rtx_format[NUM_RTX_CODE];
extern const char rtx_class[NUM_RTX_CODE];
#define GET_RTX_CLASS(CODE) (rtx_class[(int) (CODE)])
+extern const unsigned char rtx_size[NUM_RTX_CODE];
extern const unsigned char rtx_next[NUM_RTX_CODE];
/* The flags and bitfields of an ADDR_DIFF_VEC. BASE is the base label
@@ -103,11 +105,19 @@ typedef struct mem_attrs GTY(())
unsigned int align; /* Alignment of MEM in bits. */
} mem_attrs;
+/* Structure used to describe the attributes of a REG in similar way as
+ mem_attrs does for MEM above. */
+
+typedef struct reg_attrs GTY(())
+{
+ tree decl; /* decl corresponding to REG. */
+ HOST_WIDE_INT offset; /* Offset from start of DECL. */
+} reg_attrs;
+
/* Common union for an element of an rtx. */
union rtunion_def
{
- HOST_WIDE_INT rtwint;
int rtint;
unsigned int rtuint;
const char *rtstr;
@@ -120,12 +130,13 @@ union rtunion_def
tree rttree;
struct basic_block_def *bb;
mem_attrs *rtmem;
+ reg_attrs *rtreg;
};
typedef union rtunion_def rtunion;
/* RTL expression ("rtx"). */
-struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
+struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
chain_prev ("RTX_PREV (&%h)")))
{
/* The kind of expression this is. */
@@ -175,8 +186,9 @@ struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and
from the target of a branch. Valid from reorg until end of compilation;
cleared before used.
- 1 in an INSN or related rtx if this insn is dead code. Valid only during
- dead-code elimination phase; cleared before use. */
+ 1 in an INSN, JUMP_INSN or CALL_INSN or related rtx if this insn is
+ dead code. Valid only during dead-code elimination phase; cleared
+ before use. */
unsigned int in_struct : 1;
/* At the end of RTL generation, 1 if this rtx is used. This is used for
copying shared structure. See `unshare_all_rtl'.
@@ -203,10 +215,18 @@ struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
/* The first element of the operands of this rtx.
The number of operands and their types are controlled
by the `code' field, according to rtl.def. */
- rtunion GTY ((special ("rtx_def"),
- desc ("GET_CODE (&%0)"))) fld[1];
+ union u {
+ rtunion fld[1];
+ HOST_WIDE_INT hwint[1];
+ } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u;
};
+/* The size in bytes of an rtx header (code, mode and flags). */
+#define RTX_HDR_SIZE offsetof (struct rtx_def, u)
+
+/* The size in bytes of an rtx with code CODE. */
+#define RTX_SIZE(CODE) rtx_size[CODE]
+
#define NULL_RTX (rtx) 0
/* The "next" and "previous" RTX, relative to this one. */
@@ -229,10 +249,10 @@ struct rtx_def GTY((chain_next ("RTX_NEXT (&%h)"),
/* Define macros to access the `code' field of the rtx. */
#define GET_CODE(RTX) ((enum rtx_code) (RTX)->code)
-#define PUT_CODE(RTX, CODE) ((RTX)->code = (ENUM_BITFIELD(rtx_code)) (CODE))
+#define PUT_CODE(RTX, CODE) ((RTX)->code = (CODE))
#define GET_MODE(RTX) ((enum machine_mode) (RTX)->mode)
-#define PUT_MODE(RTX, MODE) ((RTX)->mode = (ENUM_BITFIELD(machine_mode)) (MODE))
+#define PUT_MODE(RTX, MODE) ((RTX)->mode = (MODE))
/* RTL vector. These appear inside RTX's when there is a need
for a variable number of things. The principle use is inside
@@ -263,13 +283,6 @@ struct rtvec_def GTY(()) {
/* Predicate yielding nonzero iff X is a barrier insn. */
#define BARRIER_P(X) (GET_CODE (X) == BARRIER)
-/* Predicate yielding nonzero iff X is cc0. */
-#ifdef HAVE_cc0
-#define CC0_P(X) ((X) == cc0_rtx)
-#else
-#define CC0_P(X) 0
-#endif
-
/* Predicate yielding nonzero iff X is a data for a jump table. */
#define JUMP_TABLE_DATA_P(INSN) \
(JUMP_P (INSN) && (GET_CODE (PATTERN (INSN)) == ADDR_VEC || \
@@ -298,7 +311,7 @@ struct rtvec_def GTY(()) {
if (GET_RTX_FORMAT(_code)[_n] != C1) \
rtl_check_failed_type1 (_rtx, _n, C1, __FILE__, __LINE__, \
__FUNCTION__); \
- &_rtx->fld[_n]; }))
+ &_rtx->u.fld[_n]; }))
#define RTL_CHECK2(RTX, N, C1, C2) __extension__ \
(*({ rtx const _rtx = (RTX); const int _n = (N); \
@@ -310,14 +323,14 @@ struct rtvec_def GTY(()) {
&& GET_RTX_FORMAT(_code)[_n] != C2) \
rtl_check_failed_type2 (_rtx, _n, C1, C2, __FILE__, __LINE__, \
__FUNCTION__); \
- &_rtx->fld[_n]; }))
+ &_rtx->u.fld[_n]; }))
#define RTL_CHECKC1(RTX, N, C) __extension__ \
(*({ rtx const _rtx = (RTX); const int _n = (N); \
if (GET_CODE (_rtx) != (C)) \
rtl_check_failed_code1 (_rtx, (C), __FILE__, __LINE__, \
__FUNCTION__); \
- &_rtx->fld[_n]; }))
+ &_rtx->u.fld[_n]; }))
#define RTL_CHECKC2(RTX, N, C1, C2) __extension__ \
(*({ rtx const _rtx = (RTX); const int _n = (N); \
@@ -325,7 +338,7 @@ struct rtvec_def GTY(()) {
if (_code != (C1) && _code != (C2)) \
rtl_check_failed_code2 (_rtx, (C1), (C2), __FILE__, __LINE__, \
__FUNCTION__); \
- &_rtx->fld[_n]; }))
+ &_rtx->u.fld[_n]; }))
#define RTVEC_ELT(RTVEC, I) __extension__ \
(*({ rtvec const _rtvec = (RTVEC); const int _i = (I); \
@@ -334,32 +347,52 @@ struct rtvec_def GTY(()) {
__FUNCTION__); \
&_rtvec->elem[_i]; }))
-extern void rtl_check_failed_bounds PARAMS ((rtx, int,
- const char *, int, const char *))
+#define XWINT(RTX, N) __extension__ \
+(*({ rtx const _rtx = (RTX); const int _n = (N); \
+ const enum rtx_code _code = GET_CODE (_rtx); \
+ if (_n < 0 || _n >= GET_RTX_LENGTH (_code)) \
+ rtl_check_failed_bounds (_rtx, _n, __FILE__, __LINE__, \
+ __FUNCTION__); \
+ if (GET_RTX_FORMAT(_code)[_n] != 'w') \
+ rtl_check_failed_type1 (_rtx, _n, 'w', __FILE__, __LINE__, \
+ __FUNCTION__); \
+ &_rtx->u.hwint[_n]; }))
+
+#define XCWINT(RTX, N, C) __extension__ \
+(*({ rtx const _rtx = (RTX); \
+ if (GET_CODE (_rtx) != (C)) \
+ rtl_check_failed_code1 (_rtx, (C), __FILE__, __LINE__, \
+ __FUNCTION__); \
+ &_rtx->u.hwint[N]; }))
+
+extern void rtl_check_failed_bounds (rtx, int, const char *, int,
+ const char *)
ATTRIBUTE_NORETURN;
-extern void rtl_check_failed_type1 PARAMS ((rtx, int, int,
- const char *, int, const char *))
+extern void rtl_check_failed_type1 (rtx, int, int, const char *, int,
+ const char *)
ATTRIBUTE_NORETURN;
-extern void rtl_check_failed_type2 PARAMS ((rtx, int, int, int,
- const char *, int, const char *))
+extern void rtl_check_failed_type2 (rtx, int, int, int, const char *,
+ int, const char *)
ATTRIBUTE_NORETURN;
-extern void rtl_check_failed_code1 PARAMS ((rtx, enum rtx_code,
- const char *, int, const char *))
+extern void rtl_check_failed_code1 (rtx, enum rtx_code, const char *,
+ int, const char *)
ATTRIBUTE_NORETURN;
-extern void rtl_check_failed_code2 PARAMS ((rtx, enum rtx_code, enum rtx_code,
- const char *, int, const char *))
+extern void rtl_check_failed_code2 (rtx, enum rtx_code, enum rtx_code,
+ const char *, int, const char *)
ATTRIBUTE_NORETURN;
-extern void rtvec_check_failed_bounds PARAMS ((rtvec, int,
- const char *, int, const char *))
+extern void rtvec_check_failed_bounds (rtvec, int, const char *, int,
+ const char *)
ATTRIBUTE_NORETURN;
#else /* not ENABLE_RTL_CHECKING */
-#define RTL_CHECK1(RTX, N, C1) ((RTX)->fld[N])
-#define RTL_CHECK2(RTX, N, C1, C2) ((RTX)->fld[N])
-#define RTL_CHECKC1(RTX, N, C) ((RTX)->fld[N])
-#define RTL_CHECKC2(RTX, N, C1, C2) ((RTX)->fld[N])
+#define RTL_CHECK1(RTX, N, C1) ((RTX)->u.fld[N])
+#define RTL_CHECK2(RTX, N, C1, C2) ((RTX)->u.fld[N])
+#define RTL_CHECKC1(RTX, N, C) ((RTX)->u.fld[N])
+#define RTL_CHECKC2(RTX, N, C1, C2) ((RTX)->u.fld[N])
#define RTVEC_ELT(RTVEC, I) ((RTVEC)->elem[I])
+#define XWINT(RTX, N) ((RTX)->u.hwint[N])
+#define XCWINT(RTX, N, C) ((RTX)->u.hwint[N])
#endif
@@ -373,75 +406,75 @@ extern void rtvec_check_failed_bounds PARAMS ((rtvec, int,
({ rtx const _rtx = (RTX); \
if (GET_CODE(_rtx) != C1) \
rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \
- __FUNCTION__); \
+ __FUNCTION__); \
_rtx; })
#define RTL_FLAG_CHECK2(NAME, RTX, C1, C2) __extension__ \
({ rtx const _rtx = (RTX); \
if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2) \
rtl_check_failed_flag (NAME,_rtx, __FILE__, __LINE__, \
- __FUNCTION__); \
+ __FUNCTION__); \
_rtx; })
#define RTL_FLAG_CHECK3(NAME, RTX, C1, C2, C3) __extension__ \
({ rtx const _rtx = (RTX); \
- if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \
+ if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \
&& GET_CODE(_rtx) != C3) \
rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \
- __FUNCTION__); \
+ __FUNCTION__); \
_rtx; })
#define RTL_FLAG_CHECK4(NAME, RTX, C1, C2, C3, C4) __extension__ \
({ rtx const _rtx = (RTX); \
- if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \
+ if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \
&& GET_CODE(_rtx) != C3 && GET_CODE(_rtx) != C4) \
rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \
- __FUNCTION__); \
+ __FUNCTION__); \
_rtx; })
#define RTL_FLAG_CHECK5(NAME, RTX, C1, C2, C3, C4, C5) __extension__ \
({ rtx const _rtx = (RTX); \
- if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \
+ if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \
&& GET_CODE(_rtx) != C3 && GET_CODE(_rtx) != C4 \
&& GET_CODE(_rtx) != C5) \
rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \
- __FUNCTION__); \
+ __FUNCTION__); \
_rtx; })
#define RTL_FLAG_CHECK6(NAME, RTX, C1, C2, C3, C4, C5, C6) \
__extension__ \
({ rtx const _rtx = (RTX); \
- if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \
+ if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \
&& GET_CODE(_rtx) != C3 && GET_CODE(_rtx) != C4 \
&& GET_CODE(_rtx) != C5 && GET_CODE(_rtx) != C6) \
rtl_check_failed_flag (NAME,_rtx, __FILE__, __LINE__, \
- __FUNCTION__); \
+ __FUNCTION__); \
_rtx; })
#define RTL_FLAG_CHECK7(NAME, RTX, C1, C2, C3, C4, C5, C6, C7) \
__extension__ \
({ rtx const _rtx = (RTX); \
- if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \
+ if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \
&& GET_CODE(_rtx) != C3 && GET_CODE(_rtx) != C4 \
&& GET_CODE(_rtx) != C5 && GET_CODE(_rtx) != C6 \
&& GET_CODE(_rtx) != C7) \
rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \
- __FUNCTION__); \
+ __FUNCTION__); \
_rtx; })
#define RTL_FLAG_CHECK8(NAME, RTX, C1, C2, C3, C4, C5, C6, C7, C8) \
__extension__ \
({ rtx const _rtx = (RTX); \
- if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \
+ if (GET_CODE(_rtx) != C1 && GET_CODE(_rtx) != C2 \
&& GET_CODE(_rtx) != C3 && GET_CODE(_rtx) != C4 \
&& GET_CODE(_rtx) != C5 && GET_CODE(_rtx) != C6 \
&& GET_CODE(_rtx) != C7 && GET_CODE(_rtx) != C8) \
rtl_check_failed_flag (NAME, _rtx, __FILE__, __LINE__, \
- __FUNCTION__); \
+ __FUNCTION__); \
_rtx; })
-extern void rtl_check_failed_flag PARAMS ((const char *, rtx, const char *,
- int, const char *))
+extern void rtl_check_failed_flag (const char *, rtx, const char *,
+ int, const char *)
ATTRIBUTE_NORETURN
;
@@ -451,7 +484,7 @@ extern void rtl_check_failed_flag PARAMS ((const char *, rtx, const char *,
#define RTL_FLAG_CHECK2(NAME, RTX, C1, C2) (RTX)
#define RTL_FLAG_CHECK3(NAME, RTX, C1, C2, C3) (RTX)
#define RTL_FLAG_CHECK4(NAME, RTX, C1, C2, C3, C4) (RTX)
-#define RTL_FLAG_CHECK5(NAME, RTX, C1, C2, C3, C4, C5) (RTX)
+#define RTL_FLAG_CHECK5(NAME, RTX, C1, C2, C3, C4, C5) (RTX)
#define RTL_FLAG_CHECK6(NAME, RTX, C1, C2, C3, C4, C5, C6) (RTX)
#define RTL_FLAG_CHECK7(NAME, RTX, C1, C2, C3, C4, C5, C6, C7) (RTX)
#define RTL_FLAG_CHECK8(NAME, RTX, C1, C2, C3, C4, C5, C6, C7, C8) (RTX)
@@ -470,7 +503,6 @@ do { \
_rtx->volatil = 0; \
} while (0)
-#define XWINT(RTX, N) (RTL_CHECK1 (RTX, N, 'w').rtwint)
#define XINT(RTX, N) (RTL_CHECK2 (RTX, N, 'i', 'n').rtint)
#define XSTR(RTX, N) (RTL_CHECK2 (RTX, N, 's', 'S').rtstr)
#define XEXP(RTX, N) (RTL_CHECK2 (RTX, N, 'e', 'u').rtx)
@@ -484,10 +516,9 @@ do { \
#define XVECEXP(RTX, N, M) RTVEC_ELT (XVEC (RTX, N), M)
#define XVECLEN(RTX, N) GET_NUM_ELEM (XVEC (RTX, N))
-/* These are like XWINT, etc. except that they expect a '0' field instead
+/* These are like XINT, etc. except that they expect a '0' field instead
of the normal type code. */
-#define X0WINT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rtwint)
#define X0INT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rtint)
#define X0UINT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rtuint)
#define X0STR(RTX, N) (RTL_CHECK1 (RTX, N, '0').rtstr)
@@ -499,9 +530,12 @@ do { \
#define X0BBDEF(RTX, N) (RTL_CHECK1 (RTX, N, '0').bb)
#define X0ADVFLAGS(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_addr_diff_vec_flags)
#define X0CSELIB(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_cselib)
-#define X0MEMATTR(RTX, N) (RTL_CHECK1 (RTX, N, '0').rtmem)
+#define X0MEMATTR(RTX, N) (RTL_CHECKC1 (RTX, N, MEM).rtmem)
+#define X0REGATTR(RTX, N) (RTL_CHECKC1 (RTX, N, REG).rtreg)
+
+/* Access a '0' field with any type. */
+#define X0ANY(RTX, N) RTL_CHECK1 (RTX, N, '0')
-#define XCWINT(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rtwint)
#define XCINT(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rtint)
#define XCUINT(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rtuint)
#define XCSTR(RTX, N, C) (RTL_CHECKC1 (RTX, N, C).rtstr)
@@ -533,7 +567,7 @@ do { \
#define NEXT_INSN(INSN) XEXP (INSN, 2)
#define BLOCK_FOR_INSN(INSN) XBBDEF (INSN, 3)
-#define INSN_SCOPE(INSN) XTREE (INSN, 4)
+#define INSN_LOCATOR(INSN) XINT (INSN, 4)
/* The body of an insn. */
#define PATTERN(INSN) XEXP (INSN, 5)
@@ -579,7 +613,7 @@ do { \
/* 1 if RTX is an insn that is dead code. Valid only for dead-code
elimination phase. */
#define INSN_DEAD_CODE_P(RTX) \
- (RTL_FLAG_CHECK1("INSN_DEAD_CODE_P", (RTX), INSN)->in_struct)
+ (RTL_FLAG_CHECK3("INSN_DEAD_CODE_P", (RTX), INSN, CALL_INSN, JUMP_INSN)->in_struct)
/* 1 if RTX is an insn in a delay slot and is from the target of the branch.
If the branch insn has INSN_ANNULLED_BRANCH_P set, this insn should only be
@@ -627,12 +661,6 @@ enum reg_note
but it can be used for cse. */
REG_EQUAL,
- /* The register set in this insn held 0 before the insn. The contents of
- the note is the insn that stored the 0. If that insn is deleted or
- patched to a NOTE, the REG_WAS_0 is inoperative. The REG_WAS_0 note
- is actually an INSN_LIST, not an EXPR_LIST. */
- REG_WAS_0,
-
/* This insn copies the return-value of a library call out of the hard reg
for return values. This note is actually an INSN_LIST and it points to
the first insn involved in setting up arguments for the call. flow.c
@@ -668,7 +696,7 @@ enum reg_note
REG_CC_SETTER, REG_CC_USER,
/* Points to a CODE_LABEL. Used by non-JUMP_INSNs to say that the
- CODE_LABEL contained in the REG_LABEL note is used by the insn.
+ CODE_LABEL contained in the REG_LABEL note is used by the insn.
This note is an INSN_LIST. */
REG_LABEL,
@@ -684,6 +712,11 @@ enum reg_note
return. */
REG_BR_PROB,
+ /* REG_VALUE_PROFILE is attached when the profile is read in to an insn
+ before that the code to profile the value is inserted. It contains
+ the results of profiling. */
+ REG_VALUE_PROFILE,
+
/* Attached to a call insn; indicates that the call is malloc-like and
that the pointer returned cannot alias anything else. */
REG_NOALIAS,
@@ -719,14 +752,14 @@ enum reg_note
/* Indicates that this insn (which is part of the prologue) computes
a value which might not be used later, and if so it's OK to delete
- the insn. Normally, deleting any insn in the prologue is an error.
+ the insn. Normally, deleting any insn in the prologue is an error.
At present the parameter is unused and set to (const_int 0). */
REG_MAYBE_DEAD,
/* Indicates that a call does not return. */
REG_NORETURN,
- /* Indicates that an indirect jump is a non-local goto instead of a
+ /* Indicates that an indirect jump is a non-local goto instead of a
computed goto. */
REG_NON_LOCAL_GOTO,
@@ -777,7 +810,9 @@ extern const char * const reg_note_name[];
between ints and pointers if we use a different macro for the block number.)
*/
-#define NOTE_SOURCE_FILE(INSN) XCSTR (INSN, 4, NOTE)
+/* Opaque data. */
+#define NOTE_DATA(INSN) RTL_CHECKC1 (INSN, 4, NOTE)
+#define NOTE_SOURCE_FILE(INSN) XCSTR (INSN, 4, NOTE)
#define NOTE_BLOCK(INSN) XCTREE (INSN, 4, NOTE)
#define NOTE_EH_HANDLER(INSN) XCINT (INSN, 4, NOTE)
#define NOTE_BASIC_BLOCK(INSN) XCBBDEF (INSN, 4, NOTE)
@@ -790,7 +825,7 @@ extern const char * const reg_note_name[];
#define NOTE_LINE_NUMBER(INSN) XCINT (INSN, 5, NOTE)
/* Nonzero if INSN is a note marking the beginning of a basic block. */
-#define NOTE_INSN_BASIC_BLOCK_P(INSN) \
+#define NOTE_INSN_BASIC_BLOCK_P(INSN) \
(GET_CODE (INSN) == NOTE \
&& NOTE_LINE_NUMBER (INSN) == NOTE_INSN_BASIC_BLOCK)
@@ -862,7 +897,7 @@ enum insn_note
their homes, etc. */
NOTE_INSN_FUNCTION_BEG,
- /* These note where exception handling regions begin and end.
+ /* These note where exception handling regions begin and end.
Uses NOTE_EH_HANDLER to identify the region in question. */
NOTE_INSN_EH_REGION_BEG,
NOTE_INSN_EH_REGION_END,
@@ -1010,7 +1045,7 @@ enum label_kind
/* For a CONST_DOUBLE:
For a DImode, there are two integers CONST_DOUBLE_LOW is the
low-order word and ..._HIGH the high-order.
- For a float, there is a REAL_VALUE_TYPE structure, and
+ For a float, there is a REAL_VALUE_TYPE structure, and
CONST_DOUBLE_REAL_VALUE(r) is a pointer to it. */
#define CONST_DOUBLE_LOW(r) XCWINT (r, 0, CONST_DOUBLE)
#define CONST_DOUBLE_HIGH(r) XCWINT (r, 1, CONST_DOUBLE)
@@ -1029,16 +1064,12 @@ enum label_kind
#define SUBREG_BYTE(RTX) XCUINT (RTX, 1, SUBREG)
/* in rtlanal.c */
-extern unsigned int subreg_lsb PARAMS ((rtx));
-extern unsigned int subreg_regno_offset PARAMS ((unsigned int,
- enum machine_mode,
- unsigned int,
- enum machine_mode));
-extern bool subreg_offset_representable_p PARAMS ((unsigned int,
- enum machine_mode,
- unsigned int,
- enum machine_mode));
-extern unsigned int subreg_regno PARAMS ((rtx));
+extern unsigned int subreg_lsb (rtx);
+extern unsigned int subreg_regno_offset (unsigned int, enum machine_mode,
+ unsigned int, enum machine_mode);
+extern bool subreg_offset_representable_p (unsigned int, enum machine_mode,
+ unsigned int, enum machine_mode);
+extern unsigned int subreg_regno (rtx);
/* 1 if RTX is a subreg containing a reg that is already known to be
sign- or zero-extended from the mode of the subreg to the mode of
@@ -1131,15 +1162,16 @@ do { \
in the block and provide defaults if none specified. */
#define MEM_ATTRS(RTX) X0MEMATTR (RTX, 1)
+/* The register attribute block. We provide access macros for each value
+ in the block and provide defaults if none specified. */
+#define REG_ATTRS(RTX) X0REGATTR (RTX, 2)
+
/* For a MEM rtx, the alias set. If 0, this MEM is not in any alias
set, and may alias anything. Otherwise, the MEM can only alias
- MEMs in the same alias set. This value is set in a
+ MEMs in a conflicting alias set. This value is set in a
language-dependent manner in the front-end, and should not be
- altered in the back-end. These set numbers are tested for zero,
- and compared for equality; they have no other significance. In
- some front-ends, these numbers may correspond in some way to types,
- or other language-level entities, but they need not, and the
- back-end makes no such assumptions. */
+ altered in the back-end. These set numbers are tested with
+ alias_sets_conflict_p. */
#define MEM_ALIAS_SET(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->alias)
/* For a MEM rtx, the decl it is known to refer to, if it is known to
@@ -1164,6 +1196,14 @@ do { \
: (STRICT_ALIGNMENT && GET_MODE (RTX) != BLKmode \
? GET_MODE_ALIGNMENT (GET_MODE (RTX)) : BITS_PER_UNIT))
+/* For a REG rtx, the decl it is known to refer to, if it is known to
+ refer to part of a DECL. */
+#define REG_EXPR(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->decl)
+
+/* For a MEM rtx, the offset from the start of MEM_DECL, if known, as a
+ RTX that is always a CONST_INT. */
+#define REG_OFFSET(RTX) (REG_ATTRS (RTX) == 0 ? 0 : REG_ATTRS (RTX)->offset)
+
/* Copy the attributes that apply to memory locations from RHS to LHS. */
#define MEM_COPY_ATTRIBUTES(LHS, RHS) \
(MEM_VOLATILE_P (LHS) = MEM_VOLATILE_P (RHS), \
@@ -1216,14 +1256,16 @@ do { \
#define COND_EXEC_TEST(RTX) XCEXP (RTX, 0, COND_EXEC)
#define COND_EXEC_CODE(RTX) XCEXP (RTX, 1, COND_EXEC)
-/* 1 if RTX is a symbol_ref that addresses this function's constants pool. */
+/* 1 if RTX is a symbol_ref that addresses this function's rtl
+ constants pool. */
#define CONSTANT_POOL_ADDRESS_P(RTX) \
(RTL_FLAG_CHECK1("CONSTANT_POOL_ADDRESS_P", (RTX), SYMBOL_REF)->unchanging)
-/* 1 if RTX is a symbol_ref that addresses this function's string constant
- pool */
-#define STRING_POOL_ADDRESS_P(RTX) \
- (RTL_FLAG_CHECK1("STRING_POOL_ADDRESS_P", (RTX), SYMBOL_REF)->frame_related)
+/* 1 if RTX is a symbol_ref that addresses a value in the file's
+ tree constant pool. This information is private to varasm.c. */
+#define TREE_CONSTANT_POOL_ADDRESS_P(RTX) \
+ (RTL_FLAG_CHECK1("TREE_CONSTANT_POOL_ADDRESS_P", \
+ (RTX), SYMBOL_REF)->frame_related)
/* Used if RTX is a symbol_ref, for machine-specific purposes. */
#define SYMBOL_REF_FLAG(RTX) \
@@ -1238,6 +1280,47 @@ do { \
#define SYMBOL_REF_WEAK(RTX) \
(RTL_FLAG_CHECK1("SYMBOL_REF_WEAK", (RTX), SYMBOL_REF)->integrated)
+/* The tree (decl or constant) associated with the symbol, or null. */
+#define SYMBOL_REF_DECL(RTX) X0TREE ((RTX), 2)
+
+/* A set of flags on a symbol_ref that are, in some respects, redundant with
+ information derivable from the tree decl associated with this symbol.
+ Except that we build a *lot* of SYMBOL_REFs that aren't associated with a
+ decl. In some cases this is a bug. But beyond that, it's nice to cache
+ this information to avoid recomputing it. Finally, this allows space for
+ the target to store more than one bit of information, as with
+ SYMBOL_REF_FLAG. */
+#define SYMBOL_REF_FLAGS(RTX) X0INT ((RTX), 1)
+
+/* These flags are common enough to be defined for all targets. They
+ are computed by the default version of targetm.encode_section_info. */
+
+/* Set if this symbol is a function. */
+#define SYMBOL_FLAG_FUNCTION (1 << 0)
+#define SYMBOL_REF_FUNCTION_P(RTX) \
+ ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_FUNCTION) != 0)
+/* Set if targetm.binds_local_p is true. */
+#define SYMBOL_FLAG_LOCAL (1 << 1)
+#define SYMBOL_REF_LOCAL_P(RTX) \
+ ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_LOCAL) != 0)
+/* Set if targetm.in_small_data_p is true. */
+#define SYMBOL_FLAG_SMALL (1 << 2)
+#define SYMBOL_REF_SMALL_P(RTX) \
+ ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_SMALL) != 0)
+/* The three-bit field at [5:3] is true for TLS variables; use
+ SYMBOL_REF_TLS_MODEL to extract the field as an enum tls_model. */
+#define SYMBOL_FLAG_TLS_SHIFT 3
+#define SYMBOL_REF_TLS_MODEL(RTX) \
+ ((enum tls_model) ((SYMBOL_REF_FLAGS (RTX) >> SYMBOL_FLAG_TLS_SHIFT) & 7))
+/* Set if this symbol is not defined in this translation unit. */
+#define SYMBOL_FLAG_EXTERNAL (1 << 6)
+#define SYMBOL_REF_EXTERNAL_P(RTX) \
+ ((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_EXTERNAL) != 0)
+
+/* Subsequent bits are available for the target to use. */
+#define SYMBOL_FLAG_MACH_DEP_SHIFT 7
+#define SYMBOL_FLAG_MACH_DEP (1 << SYMBOL_FLAG_MACH_DEP_SHIFT)
+
/* Define a macro to look for REG_INC notes,
but save time on machines where they never exist. */
@@ -1344,234 +1427,228 @@ extern int generating_concat_p;
/* Generally useful functions. */
/* In expmed.c */
-extern int ceil_log2 PARAMS ((unsigned HOST_WIDE_INT));
+extern int ceil_log2 (unsigned HOST_WIDE_INT);
#define plus_constant(X, C) plus_constant_wide ((X), (HOST_WIDE_INT) (C))
/* In builtins.c */
-extern rtx expand_builtin_expect_jump PARAMS ((tree, rtx, rtx));
+extern rtx expand_builtin_expect_jump (tree, rtx, rtx);
+extern void purge_builtin_constant_p (void);
/* In explow.c */
-extern void set_stack_check_libfunc PARAMS ((rtx));
-extern HOST_WIDE_INT trunc_int_for_mode PARAMS ((HOST_WIDE_INT,
- enum machine_mode));
-extern rtx plus_constant_wide PARAMS ((rtx, HOST_WIDE_INT));
-extern rtx plus_constant_for_output_wide PARAMS ((rtx, HOST_WIDE_INT));
-extern void optimize_save_area_alloca PARAMS ((rtx));
+extern void set_stack_check_libfunc (rtx);
+extern HOST_WIDE_INT trunc_int_for_mode (HOST_WIDE_INT, enum machine_mode);
+extern rtx plus_constant_wide (rtx, HOST_WIDE_INT);
+extern rtx plus_constant_for_output_wide (rtx, HOST_WIDE_INT);
+extern void optimize_save_area_alloca (rtx);
/* In emit-rtl.c */
-extern rtx gen_rtx PARAMS ((enum rtx_code,
- enum machine_mode, ...));
-extern rtvec gen_rtvec PARAMS ((int, ...));
-extern rtx copy_insn_1 PARAMS ((rtx));
-extern rtx copy_insn PARAMS ((rtx));
-extern rtx gen_int_mode PARAMS ((HOST_WIDE_INT,
- enum machine_mode));
-extern rtx emit_copy_of_insn_after PARAMS ((rtx, rtx));
+extern rtx gen_rtx (enum rtx_code, enum machine_mode, ...);
+extern rtvec gen_rtvec (int, ...);
+extern rtx copy_insn_1 (rtx);
+extern rtx copy_insn (rtx);
+extern rtx gen_int_mode (HOST_WIDE_INT, enum machine_mode);
+extern rtx emit_copy_of_insn_after (rtx, rtx);
+extern void set_reg_attrs_from_mem (rtx, rtx);
+extern void set_mem_attrs_from_reg (rtx, rtx);
+extern void set_reg_attrs_for_parm (rtx, rtx);
+extern int mem_expr_equal_p (tree, tree);
/* In rtl.c */
-extern rtx rtx_alloc PARAMS ((RTX_CODE));
-extern rtvec rtvec_alloc PARAMS ((int));
-extern rtx copy_rtx PARAMS ((rtx));
+extern rtx rtx_alloc (RTX_CODE);
+extern rtvec rtvec_alloc (int);
+extern rtx copy_rtx (rtx);
+extern void dump_rtx_statistics (void);
/* In emit-rtl.c */
-extern rtx copy_rtx_if_shared PARAMS ((rtx));
+extern rtx copy_rtx_if_shared (rtx);
/* In rtl.c */
-extern rtx copy_most_rtx PARAMS ((rtx, rtx));
-extern rtx shallow_copy_rtx PARAMS ((rtx));
-extern int rtx_equal_p PARAMS ((rtx, rtx));
+extern rtx copy_most_rtx (rtx, rtx);
+extern rtx shallow_copy_rtx (rtx);
+extern int rtx_equal_p (rtx, rtx);
/* In emit-rtl.c */
-extern rtvec gen_rtvec_v PARAMS ((int, rtx *));
-extern rtx gen_reg_rtx PARAMS ((enum machine_mode));
-extern rtx gen_label_rtx PARAMS ((void));
-extern int subreg_hard_regno PARAMS ((rtx, int));
-extern rtx gen_lowpart_common PARAMS ((enum machine_mode, rtx));
-extern rtx gen_lowpart PARAMS ((enum machine_mode, rtx));
+extern rtvec gen_rtvec_v (int, rtx *);
+extern rtx gen_reg_rtx (enum machine_mode);
+extern rtx gen_rtx_REG_offset (rtx, enum machine_mode, unsigned int, int);
+extern rtx gen_label_rtx (void);
+extern int subreg_hard_regno (rtx, int);
+extern rtx gen_lowpart_common (enum machine_mode, rtx);
+extern rtx gen_lowpart (enum machine_mode, rtx);
/* In cse.c */
-extern rtx gen_lowpart_if_possible PARAMS ((enum machine_mode, rtx));
+extern rtx gen_lowpart_if_possible (enum machine_mode, rtx);
/* In emit-rtl.c */
-extern rtx gen_highpart PARAMS ((enum machine_mode, rtx));
-extern rtx gen_highpart_mode PARAMS ((enum machine_mode,
- enum machine_mode, rtx));
-extern rtx gen_realpart PARAMS ((enum machine_mode, rtx));
-extern rtx gen_imagpart PARAMS ((enum machine_mode, rtx));
-extern rtx operand_subword PARAMS ((rtx, unsigned int, int,
- enum machine_mode));
-extern rtx constant_subword PARAMS ((rtx, int,
- enum machine_mode));
+extern rtx gen_highpart (enum machine_mode, rtx);
+extern rtx gen_highpart_mode (enum machine_mode, enum machine_mode, rtx);
+extern rtx gen_realpart (enum machine_mode, rtx);
+extern rtx gen_imagpart (enum machine_mode, rtx);
+extern rtx operand_subword (rtx, unsigned int, int, enum machine_mode);
/* In emit-rtl.c */
-extern rtx operand_subword_force PARAMS ((rtx, unsigned int,
- enum machine_mode));
-extern int subreg_lowpart_p PARAMS ((rtx));
-extern unsigned int subreg_lowpart_offset PARAMS ((enum machine_mode,
- enum machine_mode));
-extern unsigned int subreg_highpart_offset PARAMS ((enum machine_mode,
- enum machine_mode));
-extern rtx make_safe_from PARAMS ((rtx, rtx));
-extern rtx convert_memory_address PARAMS ((enum machine_mode, rtx));
-extern rtx get_insns PARAMS ((void));
-extern const char *get_insn_name PARAMS ((int));
-extern rtx get_last_insn PARAMS ((void));
-extern rtx get_last_insn_anywhere PARAMS ((void));
-extern rtx get_first_nonnote_insn PARAMS ((void));
-extern rtx get_last_nonnote_insn PARAMS ((void));
-extern void start_sequence PARAMS ((void));
-extern void push_to_sequence PARAMS ((rtx));
-extern void end_sequence PARAMS ((void));
-extern void push_to_full_sequence PARAMS ((rtx, rtx));
-extern void end_full_sequence PARAMS ((rtx*, rtx*));
+extern rtx operand_subword_force (rtx, unsigned int, enum machine_mode);
+extern int subreg_lowpart_p (rtx);
+extern unsigned int subreg_lowpart_offset (enum machine_mode,
+ enum machine_mode);
+extern unsigned int subreg_highpart_offset (enum machine_mode,
+ enum machine_mode);
+extern rtx make_safe_from (rtx, rtx);
+extern rtx convert_memory_address (enum machine_mode, rtx);
+extern rtx get_insns (void);
+extern const char *get_insn_name (int);
+extern rtx get_last_insn (void);
+extern rtx get_last_insn_anywhere (void);
+extern rtx get_first_nonnote_insn (void);
+extern rtx get_last_nonnote_insn (void);
+extern void start_sequence (void);
+extern void push_to_sequence (rtx);
+extern void end_sequence (void);
+extern void push_to_full_sequence (rtx, rtx);
+extern void end_full_sequence (rtx*, rtx*);
+extern rtx immed_double_const (HOST_WIDE_INT, HOST_WIDE_INT,
+ enum machine_mode);
/* In varasm.c */
-extern rtx immed_double_const PARAMS ((HOST_WIDE_INT, HOST_WIDE_INT, enum machine_mode));
-extern rtx mem_for_const_double PARAMS ((rtx));
-extern rtx force_const_mem PARAMS ((enum machine_mode, rtx));
+extern rtx force_const_mem (enum machine_mode, rtx);
/* In varasm.c */
-extern rtx get_pool_constant PARAMS ((rtx));
-extern rtx get_pool_constant_mark PARAMS ((rtx, bool *));
-extern enum machine_mode get_pool_mode PARAMS ((rtx));
-extern rtx get_pool_constant_for_function PARAMS ((struct function *, rtx));
-extern enum machine_mode get_pool_mode_for_function PARAMS ((struct function *, rtx));
-extern int get_pool_offset PARAMS ((rtx));
-extern rtx simplify_subtraction PARAMS ((rtx));
+extern rtx get_pool_constant (rtx);
+extern rtx get_pool_constant_mark (rtx, bool *);
+extern enum machine_mode get_pool_mode (rtx);
+extern rtx get_pool_constant_for_function (struct function *, rtx);
+extern enum machine_mode get_pool_mode_for_function (struct function *, rtx);
+extern int get_pool_offset (rtx);
+extern rtx simplify_subtraction (rtx);
/* In function.c */
-extern rtx assign_stack_local PARAMS ((enum machine_mode,
- HOST_WIDE_INT, int));
-extern rtx assign_stack_temp PARAMS ((enum machine_mode,
- HOST_WIDE_INT, int));
-extern rtx assign_stack_temp_for_type PARAMS ((enum machine_mode,
- HOST_WIDE_INT, int, tree));
-extern rtx assign_temp PARAMS ((tree, int, int, int));
+extern rtx assign_stack_local (enum machine_mode, HOST_WIDE_INT, int);
+extern rtx assign_stack_temp (enum machine_mode, HOST_WIDE_INT, int);
+extern rtx assign_stack_temp_for_type (enum machine_mode,
+ HOST_WIDE_INT, int, tree);
+extern rtx assign_temp (tree, int, int, int);
+
/* In emit-rtl.c */
-extern rtx emit_insn_before PARAMS ((rtx, rtx));
-extern rtx emit_insn_before_scope PARAMS ((rtx, rtx, tree));
-extern rtx emit_jump_insn_before PARAMS ((rtx, rtx));
-extern rtx emit_jump_insn_before_scope PARAMS ((rtx, rtx, tree));
-extern rtx emit_call_insn_before PARAMS ((rtx, rtx));
-extern rtx emit_call_insn_before_scope PARAMS ((rtx, rtx, tree));
-extern rtx emit_barrier_before PARAMS ((rtx));
-extern rtx emit_label_before PARAMS ((rtx, rtx));
-extern rtx emit_note_before PARAMS ((int, rtx));
-extern rtx emit_insn_after PARAMS ((rtx, rtx));
-extern rtx emit_insn_after_scope PARAMS ((rtx, rtx, tree));
-extern rtx emit_jump_insn_after PARAMS ((rtx, rtx));
-extern rtx emit_jump_insn_after_scope PARAMS ((rtx, rtx, tree));
-extern rtx emit_call_insn_after PARAMS ((rtx, rtx));
-extern rtx emit_call_insn_after_scope PARAMS ((rtx, rtx, tree));
-extern rtx emit_barrier_after PARAMS ((rtx));
-extern rtx emit_label_after PARAMS ((rtx, rtx));
-extern rtx emit_note_after PARAMS ((int, rtx));
-extern rtx emit_line_note_after PARAMS ((const char *, int, rtx));
-extern rtx emit_insn PARAMS ((rtx));
-extern rtx emit_jump_insn PARAMS ((rtx));
-extern rtx emit_call_insn PARAMS ((rtx));
-extern rtx emit_label PARAMS ((rtx));
-extern rtx emit_barrier PARAMS ((void));
-extern rtx emit_line_note PARAMS ((const char *, int));
-extern rtx emit_note PARAMS ((const char *, int));
-extern rtx emit_line_note_force PARAMS ((const char *, int));
-extern rtx make_insn_raw PARAMS ((rtx));
-extern rtx previous_insn PARAMS ((rtx));
-extern rtx next_insn PARAMS ((rtx));
-extern rtx prev_nonnote_insn PARAMS ((rtx));
-extern rtx next_nonnote_insn PARAMS ((rtx));
-extern rtx prev_real_insn PARAMS ((rtx));
-extern rtx next_real_insn PARAMS ((rtx));
-extern rtx prev_active_insn PARAMS ((rtx));
-extern rtx next_active_insn PARAMS ((rtx));
-extern int active_insn_p PARAMS ((rtx));
-extern rtx prev_label PARAMS ((rtx));
-extern rtx next_label PARAMS ((rtx));
-extern rtx next_cc0_user PARAMS ((rtx));
-extern rtx prev_cc0_setter PARAMS ((rtx));
+extern rtx emit_insn_before (rtx, rtx);
+extern rtx emit_insn_before_noloc (rtx, rtx);
+extern rtx emit_insn_before_setloc (rtx, rtx, int);
+extern rtx emit_jump_insn_before (rtx, rtx);
+extern rtx emit_jump_insn_before_noloc (rtx, rtx);
+extern rtx emit_jump_insn_before_setloc (rtx, rtx, int);
+extern rtx emit_call_insn_before (rtx, rtx);
+extern rtx emit_call_insn_before_noloc (rtx, rtx);
+extern rtx emit_call_insn_before_setloc (rtx, rtx, int);
+extern rtx emit_barrier_before (rtx);
+extern rtx emit_label_before (rtx, rtx);
+extern rtx emit_note_before (int, rtx);
+extern rtx emit_insn_after (rtx, rtx);
+extern rtx emit_insn_after_noloc (rtx, rtx);
+extern rtx emit_insn_after_setloc (rtx, rtx, int);
+extern rtx emit_jump_insn_after (rtx, rtx);
+extern rtx emit_jump_insn_after_noloc (rtx, rtx);
+extern rtx emit_jump_insn_after_setloc (rtx, rtx, int);
+extern rtx emit_call_insn_after (rtx, rtx);
+extern rtx emit_call_insn_after_noloc (rtx, rtx);
+extern rtx emit_call_insn_after_setloc (rtx, rtx, int);
+extern rtx emit_barrier_after (rtx);
+extern rtx emit_label_after (rtx, rtx);
+extern rtx emit_note_after (int, rtx);
+extern rtx emit_note_copy_after (rtx, rtx);
+extern rtx emit_insn (rtx);
+extern rtx emit_jump_insn (rtx);
+extern rtx emit_call_insn (rtx);
+extern rtx emit_label (rtx);
+extern rtx emit_barrier (void);
+extern rtx emit_note (int);
+extern rtx emit_note_copy (rtx);
+extern rtx emit_line_note (location_t);
+extern rtx make_insn_raw (rtx);
+extern void add_function_usage_to (rtx, rtx);
+extern rtx last_call_insn (void);
+extern rtx previous_insn (rtx);
+extern rtx next_insn (rtx);
+extern rtx prev_nonnote_insn (rtx);
+extern rtx next_nonnote_insn (rtx);
+extern rtx prev_real_insn (rtx);
+extern rtx next_real_insn (rtx);
+extern rtx prev_active_insn (rtx);
+extern rtx next_active_insn (rtx);
+extern int active_insn_p (rtx);
+extern rtx prev_label (rtx);
+extern rtx next_label (rtx);
+extern rtx next_cc0_user (rtx);
+extern rtx prev_cc0_setter (rtx);
/* In cfglayout.c */
-extern tree choose_inner_scope PARAMS ((tree, tree));
+extern tree choose_inner_scope (tree, tree);
+extern int insn_line (rtx);
+extern const char * insn_file (rtx);
+extern int locator_line (int);
+extern const char * locator_file (int);
+extern int prologue_locator, epilogue_locator;
/* In jump.c */
-extern rtx next_nondeleted_insn PARAMS ((rtx));
-extern enum rtx_code reverse_condition PARAMS ((enum rtx_code));
-extern enum rtx_code reverse_condition_maybe_unordered PARAMS ((enum rtx_code));
-extern enum rtx_code swap_condition PARAMS ((enum rtx_code));
-extern enum rtx_code unsigned_condition PARAMS ((enum rtx_code));
-extern enum rtx_code signed_condition PARAMS ((enum rtx_code));
-extern void mark_jump_label PARAMS ((rtx, rtx, int));
-extern void cleanup_barriers PARAMS ((void));
+extern enum rtx_code reverse_condition (enum rtx_code);
+extern enum rtx_code reverse_condition_maybe_unordered (enum rtx_code);
+extern enum rtx_code swap_condition (enum rtx_code);
+extern enum rtx_code unsigned_condition (enum rtx_code);
+extern enum rtx_code signed_condition (enum rtx_code);
+extern void mark_jump_label (rtx, rtx, int);
+extern void cleanup_barriers (void);
/* In jump.c */
-extern bool squeeze_notes PARAMS ((rtx *, rtx *));
-extern rtx delete_related_insns PARAMS ((rtx));
-extern void delete_jump PARAMS ((rtx));
-extern void delete_barrier PARAMS ((rtx));
-extern rtx get_label_before PARAMS ((rtx));
-extern rtx get_label_after PARAMS ((rtx));
-extern rtx follow_jumps PARAMS ((rtx));
+extern bool squeeze_notes (rtx *, rtx *);
+extern rtx delete_related_insns (rtx);
+extern void delete_jump (rtx);
+extern void delete_barrier (rtx);
+extern rtx get_label_before (rtx);
+extern rtx get_label_after (rtx);
+extern rtx follow_jumps (rtx);
/* In recog.c */
-extern rtx *find_constant_term_loc PARAMS ((rtx *));
+extern rtx *find_constant_term_loc (rtx *);
/* In emit-rtl.c */
-extern rtx try_split PARAMS ((rtx, rtx, int));
+extern rtx try_split (rtx, rtx, int);
extern int split_branch_probability;
/* In unknown file */
-extern rtx split_insns PARAMS ((rtx, rtx));
+extern rtx split_insns (rtx, rtx);
/* In simplify-rtx.c */
-extern rtx simplify_unary_operation PARAMS ((enum rtx_code,
- enum machine_mode, rtx,
- enum machine_mode));
-extern rtx simplify_binary_operation PARAMS ((enum rtx_code,
- enum machine_mode, rtx,
- rtx));
-extern rtx simplify_ternary_operation PARAMS ((enum rtx_code,
- enum machine_mode,
- enum machine_mode, rtx, rtx,
- rtx));
-extern rtx simplify_relational_operation PARAMS ((enum rtx_code,
- enum machine_mode, rtx,
- rtx));
-extern rtx simplify_gen_binary PARAMS ((enum rtx_code,
- enum machine_mode,
- rtx, rtx));
-extern rtx simplify_gen_unary PARAMS ((enum rtx_code,
- enum machine_mode, rtx,
- enum machine_mode));
-extern rtx simplify_gen_ternary PARAMS ((enum rtx_code,
- enum machine_mode,
- enum machine_mode,
- rtx, rtx, rtx));
-extern rtx simplify_gen_relational PARAMS ((enum rtx_code,
- enum machine_mode,
- enum machine_mode,
- rtx, rtx));
-extern rtx simplify_subreg PARAMS ((enum machine_mode,
- rtx,
- enum machine_mode,
- unsigned int));
-extern rtx simplify_gen_subreg PARAMS ((enum machine_mode,
- rtx,
- enum machine_mode,
- unsigned int));
-extern rtx simplify_replace_rtx PARAMS ((rtx, rtx, rtx));
-extern rtx simplify_rtx PARAMS ((rtx));
-extern rtx avoid_constant_pool_reference PARAMS ((rtx));
+extern rtx simplify_unary_operation (enum rtx_code, enum machine_mode, rtx,
+ enum machine_mode);
+extern rtx simplify_binary_operation (enum rtx_code, enum machine_mode, rtx,
+ rtx);
+extern rtx simplify_ternary_operation (enum rtx_code, enum machine_mode,
+ enum machine_mode, rtx, rtx, rtx);
+extern rtx simplify_relational_operation (enum rtx_code, enum machine_mode,
+ rtx, rtx);
+extern rtx simplify_gen_binary (enum rtx_code, enum machine_mode, rtx, rtx);
+extern rtx simplify_gen_unary (enum rtx_code, enum machine_mode, rtx,
+ enum machine_mode);
+extern rtx simplify_gen_ternary (enum rtx_code, enum machine_mode,
+ enum machine_mode, rtx, rtx, rtx);
+extern rtx simplify_gen_relational (enum rtx_code, enum machine_mode,
+ enum machine_mode, rtx, rtx);
+extern rtx simplify_subreg (enum machine_mode, rtx, enum machine_mode,
+ unsigned int);
+extern rtx simplify_gen_subreg (enum machine_mode, rtx, enum machine_mode,
+ unsigned int);
+extern rtx simplify_replace_rtx (rtx, rtx, rtx);
+extern rtx simplify_rtx (rtx);
+extern rtx avoid_constant_pool_reference (rtx);
/* In function.c */
-extern rtx gen_mem_addressof PARAMS ((rtx, tree, int));
+extern rtx gen_mem_addressof (rtx, tree, int);
/* In regclass.c */
-extern enum machine_mode choose_hard_reg_mode PARAMS ((unsigned int,
- unsigned int));
+extern enum machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
+ bool);
/* In emit-rtl.c */
-extern rtx set_unique_reg_note PARAMS ((rtx, enum reg_note, rtx));
+extern rtx set_unique_reg_note (rtx, enum reg_note, rtx);
/* Functions in rtlanal.c */
@@ -1582,113 +1659,117 @@ extern rtx set_unique_reg_note PARAMS ((rtx, enum reg_note, rtx));
: NULL_RTX)
#define single_set_1(I) single_set_2 (I, PATTERN (I))
-extern int rtx_addr_can_trap_p PARAMS ((rtx));
-extern int rtx_unstable_p PARAMS ((rtx));
-extern int rtx_varies_p PARAMS ((rtx, int));
-extern int rtx_addr_varies_p PARAMS ((rtx, int));
-extern HOST_WIDE_INT get_integer_term PARAMS ((rtx));
-extern rtx get_related_value PARAMS ((rtx));
-extern rtx get_jump_table_offset PARAMS ((rtx, rtx *));
-extern int global_reg_mentioned_p PARAMS ((rtx));
-extern int reg_mentioned_p PARAMS ((rtx, rtx));
-extern int count_occurrences PARAMS ((rtx, rtx, int));
-extern int reg_referenced_p PARAMS ((rtx, rtx));
-extern int reg_used_between_p PARAMS ((rtx, rtx, rtx));
-extern int reg_referenced_between_p PARAMS ((rtx, rtx, rtx));
-extern int reg_set_between_p PARAMS ((rtx, rtx, rtx));
-extern int regs_set_between_p PARAMS ((rtx, rtx, rtx));
-extern int commutative_operand_precedence PARAMS ((rtx));
-extern int swap_commutative_operands_p PARAMS ((rtx, rtx));
-extern int modified_between_p PARAMS ((rtx, rtx, rtx));
-extern int no_labels_between_p PARAMS ((rtx, rtx));
-extern int no_jumps_between_p PARAMS ((rtx, rtx));
-extern int modified_in_p PARAMS ((rtx, rtx));
-extern int insn_dependent_p PARAMS ((rtx, rtx));
-extern int reg_set_p PARAMS ((rtx, rtx));
-extern rtx single_set_2 PARAMS ((rtx, rtx));
-extern int multiple_sets PARAMS ((rtx));
-extern int set_noop_p PARAMS ((rtx));
-extern int noop_move_p PARAMS ((rtx));
-extern rtx find_last_value PARAMS ((rtx, rtx *, rtx, int));
-extern int refers_to_regno_p PARAMS ((unsigned int, unsigned int,
- rtx, rtx *));
-extern int reg_overlap_mentioned_p PARAMS ((rtx, rtx));
-extern rtx set_of PARAMS ((rtx, rtx));
-extern void note_stores PARAMS ((rtx,
- void (*) (rtx, rtx, void *),
- void *));
-extern void note_uses PARAMS ((rtx *,
- void (*) (rtx *, void *),
- void *));
-extern rtx reg_set_last PARAMS ((rtx, rtx));
-extern int dead_or_set_p PARAMS ((rtx, rtx));
-extern int dead_or_set_regno_p PARAMS ((rtx, unsigned int));
-extern rtx find_reg_note PARAMS ((rtx, enum reg_note, rtx));
-extern rtx find_regno_note PARAMS ((rtx, enum reg_note,
- unsigned int));
-extern rtx find_reg_equal_equiv_note PARAMS ((rtx));
-extern int find_reg_fusage PARAMS ((rtx, enum rtx_code, rtx));
-extern int find_regno_fusage PARAMS ((rtx, enum rtx_code,
- unsigned int));
-extern int pure_call_p PARAMS ((rtx));
-extern void remove_note PARAMS ((rtx, rtx));
-extern int side_effects_p PARAMS ((rtx));
-extern int volatile_refs_p PARAMS ((rtx));
-extern int volatile_insn_p PARAMS ((rtx));
-extern int may_trap_p PARAMS ((rtx));
-extern int inequality_comparisons_p PARAMS ((rtx));
-extern rtx replace_rtx PARAMS ((rtx, rtx, rtx));
-extern rtx replace_regs PARAMS ((rtx, rtx *, unsigned int,
- int));
-extern int computed_jump_p PARAMS ((rtx));
-typedef int (*rtx_function) PARAMS ((rtx *, void *));
-extern int for_each_rtx PARAMS ((rtx *, rtx_function, void *));
-extern rtx regno_use_in PARAMS ((unsigned int, rtx));
-extern int auto_inc_p PARAMS ((rtx));
-extern int in_expr_list_p PARAMS ((rtx, rtx));
-extern void remove_node_from_expr_list PARAMS ((rtx, rtx *));
-extern int insns_safe_to_move_p PARAMS ((rtx, rtx, rtx *));
-extern int loc_mentioned_in_p PARAMS ((rtx *, rtx));
-extern rtx find_first_parameter_load PARAMS ((rtx, rtx));
-extern bool keep_with_call_p PARAMS ((rtx));
+/* Structure used for passing data to REPLACE_LABEL. */
+typedef struct replace_label_data
+{
+ rtx r1;
+ rtx r2;
+ bool update_label_nuses;
+} replace_label_data;
+
+extern int rtx_addr_can_trap_p (rtx);
+extern bool nonzero_address_p (rtx);
+extern int rtx_unstable_p (rtx);
+extern int rtx_varies_p (rtx, int);
+extern int rtx_addr_varies_p (rtx, int);
+extern HOST_WIDE_INT get_integer_term (rtx);
+extern rtx get_related_value (rtx);
+extern rtx get_jump_table_offset (rtx, rtx *);
+extern int global_reg_mentioned_p (rtx);
+extern int reg_mentioned_p (rtx, rtx);
+extern int count_occurrences (rtx, rtx, int);
+extern int reg_referenced_p (rtx, rtx);
+extern int reg_used_between_p (rtx, rtx, rtx);
+extern int reg_referenced_between_p (rtx, rtx, rtx);
+extern int reg_set_between_p (rtx, rtx, rtx);
+extern int regs_set_between_p (rtx, rtx, rtx);
+extern int commutative_operand_precedence (rtx);
+extern int swap_commutative_operands_p (rtx, rtx);
+extern int modified_between_p (rtx, rtx, rtx);
+extern int no_labels_between_p (rtx, rtx);
+extern int no_jumps_between_p (rtx, rtx);
+extern int modified_in_p (rtx, rtx);
+extern int insn_dependent_p (rtx, rtx);
+extern int reg_set_p (rtx, rtx);
+extern rtx single_set_2 (rtx, rtx);
+extern int multiple_sets (rtx);
+extern int set_noop_p (rtx);
+extern int noop_move_p (rtx);
+extern rtx find_last_value (rtx, rtx *, rtx, int);
+extern int refers_to_regno_p (unsigned int, unsigned int, rtx, rtx *);
+extern int reg_overlap_mentioned_p (rtx, rtx);
+extern rtx set_of (rtx, rtx);
+extern void note_stores (rtx, void (*) (rtx, rtx, void *), void *);
+extern void note_uses (rtx *, void (*) (rtx *, void *), void *);
+extern rtx reg_set_last (rtx, rtx);
+extern int dead_or_set_p (rtx, rtx);
+extern int dead_or_set_regno_p (rtx, unsigned int);
+extern rtx find_reg_note (rtx, enum reg_note, rtx);
+extern rtx find_regno_note (rtx, enum reg_note, unsigned int);
+extern rtx find_reg_equal_equiv_note (rtx);
+extern int find_reg_fusage (rtx, enum rtx_code, rtx);
+extern int find_regno_fusage (rtx, enum rtx_code, unsigned int);
+extern int pure_call_p (rtx);
+extern void remove_note (rtx, rtx);
+extern int side_effects_p (rtx);
+extern int volatile_refs_p (rtx);
+extern int volatile_insn_p (rtx);
+extern int may_trap_p (rtx);
+extern int inequality_comparisons_p (rtx);
+extern rtx replace_rtx (rtx, rtx, rtx);
+extern rtx replace_regs (rtx, rtx *, unsigned int, int);
+extern int replace_label (rtx *, void *);
+extern int rtx_referenced_p (rtx, rtx);
+extern bool tablejump_p (rtx, rtx *, rtx *);
+extern int computed_jump_p (rtx);
+typedef int (*rtx_function) (rtx *, void *);
+extern int for_each_rtx (rtx *, rtx_function, void *);
+extern rtx regno_use_in (unsigned int, rtx);
+extern int auto_inc_p (rtx);
+extern int in_expr_list_p (rtx, rtx);
+extern void remove_node_from_expr_list (rtx, rtx *);
+extern int insns_safe_to_move_p (rtx, rtx, rtx *);
+extern int loc_mentioned_in_p (rtx *, rtx);
+extern rtx find_first_parameter_load (rtx, rtx);
+extern bool keep_with_call_p (rtx);
+extern bool label_is_jump_target_p (rtx, rtx);
/* flow.c */
-extern rtx find_use_as_address PARAMS ((rtx, rtx, HOST_WIDE_INT));
+extern rtx find_use_as_address (rtx, rtx, HOST_WIDE_INT);
/* lists.c */
-void free_EXPR_LIST_list PARAMS ((rtx *));
-void free_INSN_LIST_list PARAMS ((rtx *));
-void free_EXPR_LIST_node PARAMS ((rtx));
-void free_INSN_LIST_node PARAMS ((rtx));
-rtx alloc_INSN_LIST PARAMS ((rtx, rtx));
-rtx alloc_EXPR_LIST PARAMS ((int, rtx, rtx));
+void free_EXPR_LIST_list (rtx *);
+void free_INSN_LIST_list (rtx *);
+void free_EXPR_LIST_node (rtx);
+void free_INSN_LIST_node (rtx);
+rtx alloc_INSN_LIST (rtx, rtx);
+rtx alloc_EXPR_LIST (int, rtx, rtx);
/* regclass.c */
/* Maximum number of parallel sets and clobbers in any insn in this fn.
- Always at least 3, since the combiner could put that many togetherm
+ Always at least 3, since the combiner could put that many together
and we want this to remain correct for all the remaining passes. */
extern int max_parallel;
/* Free up register info memory. */
-extern void free_reg_info PARAMS ((void));
+extern void free_reg_info (void);
/* recog.c */
-extern int asm_noperands PARAMS ((rtx));
-extern const char *decode_asm_operands PARAMS ((rtx, rtx *, rtx **,
- const char **,
- enum machine_mode *));
+extern int asm_noperands (rtx);
+extern const char *decode_asm_operands (rtx, rtx *, rtx **, const char **,
+ enum machine_mode *);
-extern enum reg_class reg_preferred_class PARAMS ((int));
-extern enum reg_class reg_alternate_class PARAMS ((int));
+extern enum reg_class reg_preferred_class (int);
+extern enum reg_class reg_alternate_class (int);
-extern rtx get_first_nonparm_insn PARAMS ((void));
+extern rtx get_first_nonparm_insn (void);
-extern void split_all_insns PARAMS ((int));
-extern void split_all_insns_noflow PARAMS ((void));
+extern void split_all_insns (int);
+extern void split_all_insns_noflow (void);
#define MAX_SAVED_CONST_INT 64
extern GTY(()) rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
@@ -1771,8 +1852,6 @@ extern GTY(()) rtx global_rtl[GR_MAX];
#define arg_pointer_rtx (global_rtl[GR_ARG_POINTER])
extern GTY(()) rtx pic_offset_table_rtx;
-extern GTY(()) rtx struct_value_rtx;
-extern GTY(()) rtx struct_value_incoming_rtx;
extern GTY(()) rtx static_chain_rtx;
extern GTY(()) rtx static_chain_incoming_rtx;
extern GTY(()) rtx return_address_pointer_rtx;
@@ -1788,14 +1867,14 @@ extern GTY(()) rtx return_address_pointer_rtx;
add to this list, modify special_rtx in gengenrtl.c as well. You
should also modify gen_rtx to use the special function. */
-extern rtx gen_rtx_CONST_INT PARAMS ((enum machine_mode, HOST_WIDE_INT));
-extern rtx gen_rtx_CONST_VECTOR PARAMS ((enum machine_mode, rtvec));
-extern rtx gen_raw_REG PARAMS ((enum machine_mode, int));
-extern rtx gen_rtx_REG PARAMS ((enum machine_mode, unsigned));
-extern rtx gen_rtx_SUBREG PARAMS ((enum machine_mode, rtx, int));
-extern rtx gen_rtx_MEM PARAMS ((enum machine_mode, rtx));
+extern rtx gen_rtx_CONST_INT (enum machine_mode, HOST_WIDE_INT);
+extern rtx gen_rtx_CONST_VECTOR (enum machine_mode, rtvec);
+extern rtx gen_raw_REG (enum machine_mode, int);
+extern rtx gen_rtx_REG (enum machine_mode, unsigned);
+extern rtx gen_rtx_SUBREG (enum machine_mode, rtx, int);
+extern rtx gen_rtx_MEM (enum machine_mode, rtx);
-extern rtx gen_lowpart_SUBREG PARAMS ((enum machine_mode, rtx));
+extern rtx gen_lowpart_SUBREG (enum machine_mode, rtx);
/* We need the cast here to ensure that we get the same result both with
and without prototypes. */
@@ -1842,7 +1921,7 @@ extern rtx gen_lowpart_SUBREG PARAMS ((enum machine_mode, rtx));
#define VIRTUAL_OUTGOING_ARGS_REGNUM ((FIRST_VIRTUAL_REGISTER) + 3)
/* This points to the Canonical Frame Address of the function. This
- should corrospond to the CFA produced by INCOMING_FRAME_SP_OFFSET,
+ should correspond to the CFA produced by INCOMING_FRAME_SP_OFFSET,
but is calculated relative to the arg pointer for simplicity; the
frame pointer nor stack pointer are necessarily fixed relative to
the CFA until after reload. */
@@ -1854,7 +1933,7 @@ extern rtx gen_lowpart_SUBREG PARAMS ((enum machine_mode, rtx));
#define LAST_VIRTUAL_REGISTER ((FIRST_VIRTUAL_REGISTER) + 4)
/* Nonzero if REGNUM is a pointer into the stack frame. */
-#define REGNO_PTR_FRAME_P(REGNUM) \
+#define REGNO_PTR_FRAME_P(REGNUM) \
((REGNUM) == STACK_POINTER_REGNUM \
|| (REGNUM) == FRAME_POINTER_REGNUM \
|| (REGNUM) == HARD_FRAME_POINTER_REGNUM \
@@ -1865,15 +1944,11 @@ extern rtx gen_lowpart_SUBREG PARAMS ((enum machine_mode, rtx));
/* REGNUM never really appearing in the INSN stream. */
#define INVALID_REGNUM (~(unsigned int) 0)
-extern rtx find_next_ref PARAMS ((rtx, rtx));
+extern rtx output_constant_def (tree, int);
+extern rtx lookup_constant_def (tree);
-extern rtx output_constant_def PARAMS ((tree, int));
-
-/* Define a default value for STORE_FLAG_VALUE. */
-
-#ifndef STORE_FLAG_VALUE
-#define STORE_FLAG_VALUE 1
-#endif
+/* Called from integrate.c when a deferred constant is inlined. */
+extern void notice_rtl_inlining_of_deferred_constant (void);
/* Nonzero after the second flow pass has completed.
Set to 1 or 0 by toplev.c */
@@ -1884,6 +1959,9 @@ extern int flow2_completed;
extern int reload_completed;
+/* Nonzero after thread_prologue_and_epilogue_insns has run. */
+extern int epilogue_completed;
+
/* Set to 1 while reload_as_needed is operating.
Required by some machines to handle any generated moves differently. */
@@ -1905,11 +1983,7 @@ extern int no_new_pseudos;
REAL_ARITHMETIC. The function returns an int because the caller may not
know what `enum tree_code' means. */
-extern int rtx_to_tree_code PARAMS ((enum rtx_code));
-
-/* In tree.c */
-struct obstack;
-extern void gcc_obstack_init PARAMS ((struct obstack *));
+extern int rtx_to_tree_code (enum rtx_code);
/* In cse.c */
struct cse_basic_block_data;
@@ -1919,274 +1993,249 @@ struct cse_basic_block_data;
N times that of a fast register-to-register instruction. */
#define COSTS_N_INSNS(N) ((N) * 4)
-/* Maximum cost of a rtl expression. This value has the special meaning
+/* Maximum cost of an rtl expression. This value has the special meaning
not to use an rtx with this cost under any circumstances. */
#define MAX_COST INT_MAX
-extern int rtx_cost PARAMS ((rtx, enum rtx_code));
-extern int address_cost PARAMS ((rtx, enum machine_mode));
-extern int delete_trivially_dead_insns PARAMS ((rtx, int));
+extern int rtx_cost (rtx, enum rtx_code);
+extern int address_cost (rtx, enum machine_mode);
+extern int delete_trivially_dead_insns (rtx, int);
#ifdef BUFSIZ
-extern int cse_main PARAMS ((rtx, int, int, FILE *));
+extern int cse_main (rtx, int, int, FILE *);
#endif
-extern void cse_end_of_basic_block PARAMS ((rtx,
- struct cse_basic_block_data *,
- int, int, int));
+extern void cse_end_of_basic_block (rtx, struct cse_basic_block_data *,
+ int, int, int);
+extern void cse_condition_code_reg (void);
/* In jump.c */
-extern int comparison_dominates_p PARAMS ((enum rtx_code, enum rtx_code));
-extern int condjump_p PARAMS ((rtx));
-extern int any_condjump_p PARAMS ((rtx));
-extern int any_uncondjump_p PARAMS ((rtx));
-extern int safe_to_remove_jump_p PARAMS ((rtx));
-extern rtx pc_set PARAMS ((rtx));
-extern rtx condjump_label PARAMS ((rtx));
-extern int simplejump_p PARAMS ((rtx));
-extern int tablejump_p PARAMS ((rtx));
-extern int returnjump_p PARAMS ((rtx));
-extern int onlyjump_p PARAMS ((rtx));
-extern int only_sets_cc0_p PARAMS ((rtx));
-extern int sets_cc0_p PARAMS ((rtx));
-extern int invert_jump_1 PARAMS ((rtx, rtx));
-extern int invert_jump PARAMS ((rtx, rtx, int));
-extern int rtx_renumbered_equal_p PARAMS ((rtx, rtx));
-extern int true_regnum PARAMS ((rtx));
-extern unsigned int reg_or_subregno PARAMS ((rtx));
-extern int redirect_jump_1 PARAMS ((rtx, rtx));
-extern int redirect_jump PARAMS ((rtx, rtx, int));
-extern void rebuild_jump_labels PARAMS ((rtx));
-extern enum rtx_code reversed_comparison_code PARAMS ((rtx, rtx));
-extern enum rtx_code reversed_comparison_code_parts PARAMS ((enum rtx_code,
- rtx, rtx, rtx));
-extern void delete_for_peephole PARAMS ((rtx, rtx));
-extern int condjump_in_parallel_p PARAMS ((rtx));
-extern void never_reached_warning PARAMS ((rtx, rtx));
-extern void purge_line_number_notes PARAMS ((rtx));
-extern void copy_loop_headers PARAMS ((rtx));
+extern int comparison_dominates_p (enum rtx_code, enum rtx_code);
+extern int condjump_p (rtx);
+extern int any_condjump_p (rtx);
+extern int any_uncondjump_p (rtx);
+extern int safe_to_remove_jump_p (rtx);
+extern rtx pc_set (rtx);
+extern rtx condjump_label (rtx);
+extern int simplejump_p (rtx);
+extern int returnjump_p (rtx);
+extern int onlyjump_p (rtx);
+extern int only_sets_cc0_p (rtx);
+extern int sets_cc0_p (rtx);
+extern int invert_jump_1 (rtx, rtx);
+extern int invert_jump (rtx, rtx, int);
+extern int rtx_renumbered_equal_p (rtx, rtx);
+extern int true_regnum (rtx);
+extern unsigned int reg_or_subregno (rtx);
+extern int redirect_jump_1 (rtx, rtx);
+extern int redirect_jump (rtx, rtx, int);
+extern void rebuild_jump_labels (rtx);
+extern enum rtx_code reversed_comparison_code (rtx, rtx);
+extern enum rtx_code reversed_comparison_code_parts (enum rtx_code,
+ rtx, rtx, rtx);
+extern void delete_for_peephole (rtx, rtx);
+extern int condjump_in_parallel_p (rtx);
+extern void never_reached_warning (rtx, rtx);
+extern void purge_line_number_notes (rtx);
+extern void copy_loop_headers (rtx);
/* In emit-rtl.c. */
-extern int max_reg_num PARAMS ((void));
-extern int max_label_num PARAMS ((void));
-extern int get_first_label_num PARAMS ((void));
-extern void delete_insns_since PARAMS ((rtx));
-extern void mark_reg_pointer PARAMS ((rtx, int));
-extern void mark_user_reg PARAMS ((rtx));
-extern void reset_used_flags PARAMS ((rtx));
-extern void reorder_insns PARAMS ((rtx, rtx, rtx));
-extern void reorder_insns_nobb PARAMS ((rtx, rtx, rtx));
-extern int get_max_uid PARAMS ((void));
-extern int in_sequence_p PARAMS ((void));
-extern void force_next_line_note PARAMS ((void));
-extern void init_emit PARAMS ((void));
-extern void init_emit_once PARAMS ((int));
-extern void push_topmost_sequence PARAMS ((void));
-extern void pop_topmost_sequence PARAMS ((void));
-extern int subreg_realpart_p PARAMS ((rtx));
-extern void reverse_comparison PARAMS ((rtx));
-extern void set_new_first_and_last_insn PARAMS ((rtx, rtx));
-extern void set_new_first_and_last_label_num PARAMS ((int, int));
-extern void set_new_last_label_num PARAMS ((int));
-extern void unshare_all_rtl_again PARAMS ((rtx));
-extern void set_first_insn PARAMS ((rtx));
-extern void set_last_insn PARAMS ((rtx));
-extern void link_cc0_insns PARAMS ((rtx));
-extern void add_insn PARAMS ((rtx));
-extern void add_insn_before PARAMS ((rtx, rtx));
-extern void add_insn_after PARAMS ((rtx, rtx));
-extern void remove_insn PARAMS ((rtx));
-extern void reorder_insns_with_line_notes PARAMS ((rtx, rtx, rtx));
-extern void emit_insn_after_with_line_notes PARAMS ((rtx, rtx, rtx));
-extern enum rtx_code classify_insn PARAMS ((rtx));
-extern rtx emit PARAMS ((rtx));
+extern int max_reg_num (void);
+extern int max_label_num (void);
+extern int get_first_label_num (void);
+extern void delete_insns_since (rtx);
+extern void mark_reg_pointer (rtx, int);
+extern void mark_user_reg (rtx);
+extern void reset_used_flags (rtx);
+extern void set_used_flags (rtx);
+extern void reorder_insns (rtx, rtx, rtx);
+extern void reorder_insns_nobb (rtx, rtx, rtx);
+extern int get_max_uid (void);
+extern int in_sequence_p (void);
+extern void force_next_line_note (void);
+extern void init_emit (void);
+extern void init_emit_once (int);
+extern void push_topmost_sequence (void);
+extern void pop_topmost_sequence (void);
+extern int subreg_realpart_p (rtx);
+extern void reverse_comparison (rtx);
+extern void set_new_first_and_last_insn (rtx, rtx);
+extern void set_new_last_label_num (int);
+extern void unshare_all_rtl_again (rtx);
+extern void unshare_all_rtl_in_chain (rtx);
+extern void verify_rtl_sharing (void);
+extern void set_first_insn (rtx);
+extern void set_last_insn (rtx);
+extern void link_cc0_insns (rtx);
+extern void add_insn (rtx);
+extern void add_insn_before (rtx, rtx);
+extern void add_insn_after (rtx, rtx);
+extern void remove_insn (rtx);
+extern void reorder_insns_with_line_notes (rtx, rtx, rtx);
+extern void emit_insn_after_with_line_notes (rtx, rtx, rtx);
+extern enum rtx_code classify_insn (rtx);
+extern rtx emit (rtx);
/* Query and clear/ restore no_line_numbers. This is used by the
switch / case handling in stmt.c to give proper line numbers in
warnings about unreachable code. */
-int force_line_numbers PARAMS ((void));
-void restore_line_number_status PARAMS ((int old_value));
-extern void renumber_insns PARAMS ((FILE *));
-extern void remove_unnecessary_notes PARAMS ((void));
-extern rtx delete_insn PARAMS ((rtx));
-extern void delete_insn_chain PARAMS ((rtx, rtx));
-extern rtx delete_insn_and_edges PARAMS ((rtx));
-extern void delete_insn_chain_and_edges PARAMS ((rtx, rtx));
+int force_line_numbers (void);
+void restore_line_number_status (int old_value);
+extern void renumber_insns (FILE *);
+extern void remove_unnecessary_notes (void);
+extern rtx delete_insn (rtx);
+extern void delete_insn_chain (rtx, rtx);
+extern rtx unlink_insn_chain (rtx, rtx);
+extern rtx delete_insn_and_edges (rtx);
+extern void delete_insn_chain_and_edges (rtx, rtx);
/* In combine.c */
-extern int combine_instructions PARAMS ((rtx, unsigned int));
-extern unsigned int extended_count PARAMS ((rtx, enum machine_mode, int));
-extern rtx remove_death PARAMS ((unsigned int, rtx));
+extern int combine_instructions (rtx, unsigned int);
+extern unsigned int extended_count (rtx, enum machine_mode, int);
+extern rtx remove_death (unsigned int, rtx);
#ifdef BUFSIZ
-extern void dump_combine_stats PARAMS ((FILE *));
-extern void dump_combine_total_stats PARAMS ((FILE *));
+extern void dump_combine_stats (FILE *);
+extern void dump_combine_total_stats (FILE *);
#endif
+/* In web.c */
+extern void web_main (void);
/* In sched.c. */
#ifdef BUFSIZ
-extern void schedule_insns PARAMS ((FILE *));
-extern void schedule_ebbs PARAMS ((FILE *));
+extern void schedule_insns (FILE *);
+extern void schedule_ebbs (FILE *);
#endif
-extern void fix_sched_param PARAMS ((const char *, const char *));
+extern void fix_sched_param (const char *, const char *);
/* In print-rtl.c */
extern const char *print_rtx_head;
-extern void debug_rtx PARAMS ((rtx));
-extern void debug_rtx_list PARAMS ((rtx, int));
-extern void debug_rtx_range PARAMS ((rtx, rtx));
-extern rtx debug_rtx_find PARAMS ((rtx, int));
+extern void debug_rtx (rtx);
+extern void debug_rtx_list (rtx, int);
+extern void debug_rtx_range (rtx, rtx);
+extern rtx debug_rtx_find (rtx, int);
#ifdef BUFSIZ
-extern void print_mem_expr PARAMS ((FILE *, tree));
-extern void print_rtl PARAMS ((FILE *, rtx));
-extern void print_simple_rtl PARAMS ((FILE *, rtx));
-extern int print_rtl_single PARAMS ((FILE *, rtx));
-extern void print_inline_rtx PARAMS ((FILE *, rtx, int));
+extern void print_mem_expr (FILE *, tree);
+extern void print_rtl (FILE *, rtx);
+extern void print_simple_rtl (FILE *, rtx);
+extern int print_rtl_single (FILE *, rtx);
+extern void print_inline_rtx (FILE *, rtx, int);
#endif
/* In loop.c */
-extern void init_loop PARAMS ((void));
-extern rtx libcall_other_reg PARAMS ((rtx, rtx));
+extern void init_loop (void);
+extern rtx libcall_other_reg (rtx, rtx);
#ifdef BUFSIZ
-extern void loop_optimize PARAMS ((rtx, FILE *, int));
+extern void loop_optimize (rtx, FILE *, int);
#endif
-extern void record_excess_regs PARAMS ((rtx, rtx, rtx *));
+extern void branch_target_load_optimize (rtx, bool);
+extern void record_excess_regs (rtx, rtx, rtx *);
/* In function.c */
-extern void reposition_prologue_and_epilogue_notes PARAMS ((rtx));
-extern void thread_prologue_and_epilogue_insns PARAMS ((rtx));
-extern int prologue_epilogue_contains PARAMS ((rtx));
-extern int sibcall_epilogue_contains PARAMS ((rtx));
-extern void preserve_rtl_expr_result PARAMS ((rtx));
-extern void mark_temp_addr_taken PARAMS ((rtx));
-extern void update_temp_slot_address PARAMS ((rtx, rtx));
-extern void purge_addressof PARAMS ((rtx));
-extern void purge_hard_subreg_sets PARAMS ((rtx));
+extern void reposition_prologue_and_epilogue_notes (rtx);
+extern void thread_prologue_and_epilogue_insns (rtx);
+extern int prologue_epilogue_contains (rtx);
+extern int sibcall_epilogue_contains (rtx);
+extern void preserve_rtl_expr_result (rtx);
+extern void mark_temp_addr_taken (rtx);
+extern void update_temp_slot_address (rtx, rtx);
+extern void purge_addressof (rtx);
+extern void purge_hard_subreg_sets (rtx);
/* In stmt.c */
-extern void set_file_and_line_for_stmt PARAMS ((const char *, int));
-extern void expand_null_return PARAMS ((void));
-extern void emit_jump PARAMS ((rtx));
-extern int preserve_subexpressions_p PARAMS ((void));
+extern void set_file_and_line_for_stmt (location_t);
+extern void expand_null_return (void);
+extern void expand_naked_return (void);
+extern void emit_jump (rtx);
+extern int preserve_subexpressions_p (void);
/* In expr.c */
-extern void move_by_pieces PARAMS ((rtx, rtx,
- unsigned HOST_WIDE_INT,
- unsigned int));
+extern rtx move_by_pieces (rtx, rtx, unsigned HOST_WIDE_INT,
+ unsigned int, int);
/* In flow.c */
-extern void recompute_reg_usage PARAMS ((rtx, int));
-extern int initialize_uninitialized_subregs PARAMS ((void));
-extern void delete_dead_jumptables PARAMS ((void));
+extern void recompute_reg_usage (rtx, int);
+extern int initialize_uninitialized_subregs (void);
+extern void delete_dead_jumptables (void);
#ifdef BUFSIZ
-extern void print_rtl_with_bb PARAMS ((FILE *, rtx));
-extern void dump_flow_info PARAMS ((FILE *));
+extern void print_rtl_with_bb (FILE *, rtx);
+extern void dump_flow_info (FILE *);
#endif
/* In expmed.c */
-extern void init_expmed PARAMS ((void));
-extern void expand_inc PARAMS ((rtx, rtx));
-extern void expand_dec PARAMS ((rtx, rtx));
-extern rtx expand_mult_highpart PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT, rtx,
- int, int));
+extern void init_expmed (void);
+extern void expand_inc (rtx, rtx);
+extern void expand_dec (rtx, rtx);
+extern rtx expand_mult_highpart (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT, rtx, int, int);
/* In gcse.c */
+extern bool can_copy_p (enum machine_mode);
+extern rtx fis_get_condition (rtx);
#ifdef BUFSIZ
-extern int gcse_main PARAMS ((rtx, FILE *));
+extern int gcse_main (rtx, FILE *);
+extern int bypass_jumps (FILE *);
#endif
/* In global.c */
-extern void mark_elimination PARAMS ((int, int));
+extern void mark_elimination (int, int);
#ifdef BUFSIZ
-extern int global_alloc PARAMS ((FILE *));
-extern void dump_global_regs PARAMS ((FILE *));
+extern int global_alloc (FILE *);
+extern void dump_global_regs (FILE *);
#endif
#ifdef HARD_CONST
/* Yes, this ifdef is silly, but HARD_REG_SET is not always defined. */
-extern void retry_global_alloc PARAMS ((int, HARD_REG_SET));
+extern void retry_global_alloc (int, HARD_REG_SET);
#endif
-extern void build_insn_chain PARAMS ((rtx));
+extern void build_insn_chain (rtx);
/* In regclass.c */
-extern int reg_classes_intersect_p PARAMS ((enum reg_class, enum reg_class));
-extern int reg_class_subset_p PARAMS ((enum reg_class, enum reg_class));
-extern void globalize_reg PARAMS ((int));
-extern void init_regs PARAMS ((void));
-extern void init_fake_stack_mems PARAMS ((void));
-extern void init_reg_sets PARAMS ((void));
-extern void regset_release_memory PARAMS ((void));
-extern void regclass_init PARAMS ((void));
-extern void regclass PARAMS ((rtx, int, FILE *));
-extern void reg_scan PARAMS ((rtx, unsigned int, int));
-extern void reg_scan_update PARAMS ((rtx, rtx, unsigned int));
-extern void fix_register PARAMS ((const char *, int, int));
+extern int reg_classes_intersect_p (enum reg_class, enum reg_class);
+extern int reg_class_subset_p (enum reg_class, enum reg_class);
+extern void globalize_reg (int);
+extern void init_reg_modes_once (void);
+extern void init_regs (void);
+extern void init_fake_stack_mems (void);
+extern void init_reg_sets (void);
+extern void regset_release_memory (void);
+extern void regclass_init (void);
+extern void regclass (rtx, int, FILE *);
+extern void reg_scan (rtx, unsigned int, int);
+extern void reg_scan_update (rtx, rtx, unsigned int);
+extern void fix_register (const char *, int, int);
#ifdef HARD_CONST
-extern void cannot_change_mode_set_regs PARAMS ((HARD_REG_SET *,
- enum machine_mode,
- unsigned int));
+extern void cannot_change_mode_set_regs (HARD_REG_SET *,
+ enum machine_mode, unsigned int);
#endif
-extern bool invalid_mode_change_p PARAMS ((unsigned int,
- enum reg_class,
- enum machine_mode));
+extern bool invalid_mode_change_p (unsigned int, enum reg_class,
+ enum machine_mode);
-extern int delete_null_pointer_checks PARAMS ((rtx));
+extern int delete_null_pointer_checks (rtx);
/* In regmove.c */
#ifdef BUFSIZ
-extern void regmove_optimize PARAMS ((rtx, int, FILE *));
+extern void regmove_optimize (rtx, int, FILE *);
#endif
-extern void combine_stack_adjustments PARAMS ((void));
+extern void combine_stack_adjustments (void);
/* In reorg.c */
#ifdef BUFSIZ
-extern void dbr_schedule PARAMS ((rtx, FILE *));
+extern void dbr_schedule (rtx, FILE *);
#endif
/* In local-alloc.c */
#ifdef BUFSIZ
-extern void dump_local_alloc PARAMS ((FILE *));
+extern void dump_local_alloc (FILE *);
#endif
-extern int local_alloc PARAMS ((void));
-extern int function_invariant_p PARAMS ((rtx));
+extern int local_alloc (void);
+extern int function_invariant_p (rtx);
/* In profile.c */
-extern void init_branch_prob PARAMS ((const char *));
-extern void branch_prob PARAMS ((void));
-extern void end_branch_prob PARAMS ((void));
-extern void output_func_start_profiler PARAMS ((void));
+extern void init_branch_prob (void);
+extern void branch_prob (void);
+extern void end_branch_prob (void);
/* In reg-stack.c */
#ifdef BUFSIZ
-extern void reg_to_stack PARAMS ((rtx, FILE *));
+extern bool reg_to_stack (rtx, FILE *);
#endif
-/* In fold-const.c */
-extern int add_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *));
-extern int neg_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *));
-extern int mul_double PARAMS ((unsigned HOST_WIDE_INT,
- HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *));
-extern void lshift_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- HOST_WIDE_INT, unsigned int,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *, int));
-extern void rshift_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- HOST_WIDE_INT, unsigned int,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *, int));
-extern void lrotate_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- HOST_WIDE_INT, unsigned int,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *));
-extern void rrotate_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- HOST_WIDE_INT, unsigned int,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *));
-
/* In calls.c */
enum libcall_type
{
@@ -2201,29 +2250,26 @@ enum libcall_type
LCT_RETURNS_TWICE = 8
};
-extern void emit_library_call PARAMS ((rtx, enum libcall_type,
- enum machine_mode, int,
- ...));
-extern rtx emit_library_call_value PARAMS ((rtx, rtx, enum libcall_type,
- enum machine_mode, int,
- ...));
+extern void emit_library_call (rtx, enum libcall_type, enum machine_mode, int,
+ ...);
+extern rtx emit_library_call_value (rtx, rtx, enum libcall_type,
+ enum machine_mode, int, ...);
/* In unroll.c */
-extern int set_dominates_use PARAMS ((int, int, int, rtx, rtx));
+extern int set_dominates_use (int, int, int, rtx, rtx);
/* In varasm.c */
-extern int in_data_section PARAMS ((void));
-extern void init_varasm_once PARAMS ((void));
+extern int in_data_section (void);
+extern void init_varasm_once (void);
/* In rtl.c */
-extern void init_rtl PARAMS ((void));
-extern void traverse_md_constants PARAMS ((int (*) (void **, void *),
- void *));
+extern void init_rtl (void);
+extern void traverse_md_constants (int (*) (void **, void *), void *);
struct md_constant { char *name, *value; };
#ifdef BUFSIZ
-extern int read_skip_spaces PARAMS ((FILE *));
-extern rtx read_rtx PARAMS ((FILE *));
+extern int read_skip_spaces (FILE *);
+extern rtx read_rtx (FILE *);
#endif
extern const char *read_rtx_filename;
@@ -2235,26 +2281,30 @@ extern int read_rtx_lineno;
special abort includes one or both. toplev.h gets too few files,
system.h gets too many. */
-extern void fancy_abort PARAMS ((const char *, int, const char *))
+extern void fancy_abort (const char *, int, const char *)
ATTRIBUTE_NORETURN;
#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
/* In alias.c */
-extern void clear_reg_alias_info PARAMS ((rtx));
-extern rtx canon_rtx PARAMS ((rtx));
-extern int true_dependence PARAMS ((rtx, enum machine_mode, rtx,
- int (*)(rtx, int)));
-extern rtx get_addr PARAMS ((rtx));
-extern int canon_true_dependence PARAMS ((rtx, enum machine_mode, rtx,
- rtx, int (*)(rtx, int)));
-extern int read_dependence PARAMS ((rtx, rtx));
-extern int anti_dependence PARAMS ((rtx, rtx));
-extern int output_dependence PARAMS ((rtx, rtx));
-extern void mark_constant_function PARAMS ((void));
-extern void init_alias_once PARAMS ((void));
-extern void init_alias_analysis PARAMS ((void));
-extern void end_alias_analysis PARAMS ((void));
-extern rtx addr_side_effect_eval PARAMS ((rtx, int, int));
+extern void clear_reg_alias_info (rtx);
+extern rtx canon_rtx (rtx);
+extern int true_dependence (rtx, enum machine_mode, rtx, int (*)(rtx, int));
+extern rtx get_addr (rtx);
+extern int canon_true_dependence (rtx, enum machine_mode, rtx, rtx,
+ int (*)(rtx, int));
+extern int read_dependence (rtx, rtx);
+extern int anti_dependence (rtx, rtx);
+extern int output_dependence (rtx, rtx);
+extern int unchanging_anti_dependence (rtx, rtx);
+extern void mark_constant_function (void);
+extern void init_alias_once (void);
+extern void init_alias_analysis (void);
+extern void end_alias_analysis (void);
+extern rtx addr_side_effect_eval (rtx, int, int);
+extern bool memory_modified_in_insn_p (rtx, rtx);
+extern rtx find_base_term (rtx);
+extern rtx get_reg_known_value (unsigned int);
+extern bool get_reg_known_equiv_p (unsigned int);
/* In sibcall.c */
typedef enum {
@@ -2263,27 +2313,27 @@ typedef enum {
sibcall_use_sibcall
} sibcall_use_t;
-extern void optimize_sibling_and_tail_recursive_calls PARAMS ((void));
-extern void replace_call_placeholder PARAMS ((rtx, sibcall_use_t));
+extern void optimize_sibling_and_tail_recursive_calls (void);
+extern void replace_call_placeholder (rtx, sibcall_use_t);
#ifdef STACK_REGS
-extern int stack_regs_mentioned PARAMS ((rtx insn));
+extern int stack_regs_mentioned (rtx insn);
#endif
/* In toplev.c */
extern GTY(()) rtx stack_limit_rtx;
/* In regrename.c */
-extern void regrename_optimize PARAMS ((void));
-extern void copyprop_hardreg_forward PARAMS ((void));
+extern void regrename_optimize (void);
+extern void copyprop_hardreg_forward (void);
/* In ifcvt.c */
-extern void if_convert PARAMS ((int));
+extern void if_convert (int);
/* In predict.c */
-extern void invert_br_probabilities PARAMS ((rtx));
-extern bool expensive_function_p PARAMS ((int));
+extern void invert_br_probabilities (rtx);
+extern bool expensive_function_p (int);
/* In tracer.c */
-extern void tracer PARAMS ((void));
+extern void tracer (unsigned int);
#endif /* ! GCC_RTL_H */
diff --git a/contrib/gcc/rtlanal.c b/contrib/gcc/rtlanal.c
index 57b210e1d78d..fcb426db3de2 100644
--- a/contrib/gcc/rtlanal.c
+++ b/contrib/gcc/rtlanal.c
@@ -1,6 +1,6 @@
/* Analyze RTL for C-Compiler
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "hard-reg-set.h"
@@ -33,13 +35,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "real.h"
/* Forward declarations */
-static int global_reg_mentioned_p_1 PARAMS ((rtx *, void *));
-static void set_of_1 PARAMS ((rtx, rtx, void *));
-static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *));
-static int computed_jump_p_1 PARAMS ((rtx));
-static void parms_set PARAMS ((rtx, rtx, void *));
-static bool hoist_test_store PARAMS ((rtx, rtx, regset));
-static void hoist_update_store PARAMS ((rtx, rtx *, rtx, rtx));
+static int global_reg_mentioned_p_1 (rtx *, void *);
+static void set_of_1 (rtx, rtx, void *);
+static void insn_dependent_p_1 (rtx, rtx, void *);
+static int rtx_referenced_p_1 (rtx *, void *);
+static int computed_jump_p_1 (rtx);
+static void parms_set (rtx, rtx, void *);
+static bool hoist_test_store (rtx, rtx, regset);
+static void hoist_update_store (rtx, rtx *, rtx, rtx);
/* Bit flags that specify the machine subtype we are compiling for.
Bits are tested using macros TARGET_... defined in the tm.h file
@@ -53,8 +56,7 @@ int target_flags;
(within one function) and so is anything marked `unchanging'. */
int
-rtx_unstable_p (x)
- rtx x;
+rtx_unstable_p (rtx x)
{
RTX_CODE code = GET_CODE (x);
int i;
@@ -97,7 +99,7 @@ rtx_unstable_p (x)
if (MEM_VOLATILE_P (x))
return 1;
- /* FALLTHROUGH */
+ /* Fall through. */
default:
break;
@@ -129,14 +131,16 @@ rtx_unstable_p (x)
The frame pointer and the arg pointer are considered constant. */
int
-rtx_varies_p (x, for_alias)
- rtx x;
- int for_alias;
+rtx_varies_p (rtx x, int for_alias)
{
- RTX_CODE code = GET_CODE (x);
+ RTX_CODE code;
int i;
const char *fmt;
+ if (!x)
+ return 0;
+
+ code = GET_CODE (x);
switch (code)
{
case MEM:
@@ -153,6 +157,10 @@ rtx_varies_p (x, for_alias)
case LABEL_REF:
return 0;
+ case ADDRESSOF:
+ /* This will resolve to some offset from the frame pointer. */
+ return 0;
+
case REG:
/* Note that we have to test for the actual rtx used for the frame
and arg pointers and not just the register number in case we have
@@ -185,7 +193,7 @@ rtx_varies_p (x, for_alias)
if (MEM_VOLATILE_P (x))
return 1;
- /* FALLTHROUGH */
+ /* Fall through. */
default:
break;
@@ -212,8 +220,7 @@ rtx_varies_p (x, for_alias)
/* Return 0 if the use of X as an address in a MEM can cause a trap. */
int
-rtx_addr_can_trap_p (x)
- rtx x;
+rtx_addr_can_trap_p (rtx x)
{
enum rtx_code code = GET_CODE (x);
@@ -225,6 +232,10 @@ rtx_addr_can_trap_p (x)
case LABEL_REF:
return 0;
+ case ADDRESSOF:
+ /* This will resolve to some offset from the frame pointer. */
+ return 0;
+
case REG:
/* As in rtx_varies_p, we have to use the actual rtx, not reg number. */
if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
@@ -269,6 +280,89 @@ rtx_addr_can_trap_p (x)
return 1;
}
+/* Return true if X is an address that is known to not be zero. */
+
+bool
+nonzero_address_p (rtx x)
+{
+ enum rtx_code code = GET_CODE (x);
+
+ switch (code)
+ {
+ case SYMBOL_REF:
+ return !SYMBOL_REF_WEAK (x);
+
+ case LABEL_REF:
+ return true;
+
+ case ADDRESSOF:
+ /* This will resolve to some offset from the frame pointer. */
+ return true;
+
+ case REG:
+ /* As in rtx_varies_p, we have to use the actual rtx, not reg number. */
+ if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
+ || x == stack_pointer_rtx
+ || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]))
+ return true;
+ /* All of the virtual frame registers are stack references. */
+ if (REGNO (x) >= FIRST_VIRTUAL_REGISTER
+ && REGNO (x) <= LAST_VIRTUAL_REGISTER)
+ return true;
+ return false;
+
+ case CONST:
+ return nonzero_address_p (XEXP (x, 0));
+
+ case PLUS:
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT)
+ {
+ /* Pointers aren't allowed to wrap. If we've got a register
+ that is known to be a pointer, and a positive offset, then
+ the composite can't be zero. */
+ if (INTVAL (XEXP (x, 1)) > 0
+ && REG_P (XEXP (x, 0))
+ && REG_POINTER (XEXP (x, 0)))
+ return true;
+
+ return nonzero_address_p (XEXP (x, 0));
+ }
+ /* Handle PIC references. */
+ else if (XEXP (x, 0) == pic_offset_table_rtx
+ && CONSTANT_P (XEXP (x, 1)))
+ return true;
+ return false;
+
+ case PRE_MODIFY:
+ /* Similar to the above; allow positive offsets. Further, since
+ auto-inc is only allowed in memories, the register must be a
+ pointer. */
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && INTVAL (XEXP (x, 1)) > 0)
+ return true;
+ return nonzero_address_p (XEXP (x, 0));
+
+ case PRE_INC:
+ /* Similarly. Further, the offset is always positive. */
+ return true;
+
+ case PRE_DEC:
+ case POST_DEC:
+ case POST_INC:
+ case POST_MODIFY:
+ return nonzero_address_p (XEXP (x, 0));
+
+ case LO_SUM:
+ return nonzero_address_p (XEXP (x, 1));
+
+ default:
+ break;
+ }
+
+ /* If it isn't one of the case above, might be zero. */
+ return false;
+}
+
/* Return 1 if X refers to a memory location whose address
cannot be compared reliably with constant addresses,
or if X refers to a BLKmode memory object.
@@ -276,9 +370,7 @@ rtx_addr_can_trap_p (x)
zero, we are slightly more conservative. */
int
-rtx_addr_varies_p (x, for_alias)
- rtx x;
- int for_alias;
+rtx_addr_varies_p (rtx x, int for_alias)
{
enum rtx_code code;
int i;
@@ -314,8 +406,7 @@ rtx_addr_varies_p (x, for_alias)
This is used in cse.c with the `related_value' field. */
HOST_WIDE_INT
-get_integer_term (x)
- rtx x;
+get_integer_term (rtx x)
{
if (GET_CODE (x) == CONST)
x = XEXP (x, 0);
@@ -334,8 +425,7 @@ get_integer_term (x)
Only obvious integer terms are detected. */
rtx
-get_related_value (x)
- rtx x;
+get_related_value (rtx x)
{
if (GET_CODE (x) != CONST)
return 0;
@@ -357,9 +447,7 @@ get_related_value (x)
insn used in locating the offset was found. */
rtx
-get_jump_table_offset (insn, earliest)
- rtx insn;
- rtx *earliest;
+get_jump_table_offset (rtx insn, rtx *earliest)
{
rtx label;
rtx table;
@@ -371,13 +459,7 @@ get_jump_table_offset (insn, earliest)
rtx old_y;
int i;
- if (GET_CODE (insn) != JUMP_INSN
- || ! (label = JUMP_LABEL (insn))
- || ! (table = NEXT_INSN (label))
- || GET_CODE (table) != JUMP_INSN
- || (GET_CODE (PATTERN (table)) != ADDR_VEC
- && GET_CODE (PATTERN (table)) != ADDR_DIFF_VEC)
- || ! (set = single_set (insn)))
+ if (!tablejump_p (insn, &label, &table) || !(set = single_set (insn)))
return NULL_RTX;
x = SET_SRC (set);
@@ -493,9 +575,7 @@ get_jump_table_offset (insn, earliest)
a global register. */
static int
-global_reg_mentioned_p_1 (loc, data)
- rtx *loc;
- void *data ATTRIBUTE_UNUSED;
+global_reg_mentioned_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
int regno;
rtx x = *loc;
@@ -544,10 +624,8 @@ global_reg_mentioned_p_1 (loc, data)
/* Returns nonzero if X mentions a global register. */
int
-global_reg_mentioned_p (x)
- rtx x;
+global_reg_mentioned_p (rtx x)
{
-
if (INSN_P (x))
{
if (GET_CODE (x) == CALL_INSN)
@@ -569,9 +647,7 @@ global_reg_mentioned_p (x)
zero, we do not count occurrences inside the destination of a SET. */
int
-count_occurrences (x, find, count_dest)
- rtx x, find;
- int count_dest;
+count_occurrences (rtx x, rtx find, int count_dest)
{
int i, j;
enum rtx_code code;
@@ -634,8 +710,7 @@ count_occurrences (x, find, count_dest)
for a subexpression of IN that is Lisp "equal" to REG. */
int
-reg_mentioned_p (reg, in)
- rtx reg, in;
+reg_mentioned_p (rtx reg, rtx in)
{
const char *fmt;
int i;
@@ -666,8 +741,6 @@ reg_mentioned_p (reg, in)
return 0;
case CONST_INT:
- return GET_CODE (reg) == CONST_INT && INTVAL (in) == INTVAL (reg);
-
case CONST_VECTOR:
case CONST_DOUBLE:
/* These are kept unique for a given value. */
@@ -702,8 +775,7 @@ reg_mentioned_p (reg, in)
no CODE_LABEL insn. */
int
-no_labels_between_p (beg, end)
- rtx beg, end;
+no_labels_between_p (rtx beg, rtx end)
{
rtx p;
if (beg == end)
@@ -718,8 +790,7 @@ no_labels_between_p (beg, end)
no JUMP_INSN insn. */
int
-no_jumps_between_p (beg, end)
- rtx beg, end;
+no_jumps_between_p (rtx beg, rtx end)
{
rtx p;
for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p))
@@ -732,8 +803,7 @@ no_jumps_between_p (beg, end)
FROM_INSN and TO_INSN (exclusive of those two). */
int
-reg_used_between_p (reg, from_insn, to_insn)
- rtx reg, from_insn, to_insn;
+reg_used_between_p (rtx reg, rtx from_insn, rtx to_insn)
{
rtx insn;
@@ -755,9 +825,7 @@ reg_used_between_p (reg, from_insn, to_insn)
we do not consider it a reference. */
int
-reg_referenced_p (x, body)
- rtx x;
- rtx body;
+reg_referenced_p (rtx x, rtx body)
{
int i;
@@ -834,8 +902,7 @@ reg_referenced_p (x, body)
not count. */
int
-reg_referenced_between_p (reg, from_insn, to_insn)
- rtx reg, from_insn, to_insn;
+reg_referenced_between_p (rtx reg, rtx from_insn, rtx to_insn)
{
rtx insn;
@@ -855,8 +922,7 @@ reg_referenced_between_p (reg, from_insn, to_insn)
FROM_INSN and TO_INSN (exclusive of those two). */
int
-reg_set_between_p (reg, from_insn, to_insn)
- rtx reg, from_insn, to_insn;
+reg_set_between_p (rtx reg, rtx from_insn, rtx to_insn)
{
rtx insn;
@@ -871,16 +937,12 @@ reg_set_between_p (reg, from_insn, to_insn)
/* Internals of reg_set_between_p. */
int
-reg_set_p (reg, insn)
- rtx reg, insn;
+reg_set_p (rtx reg, rtx insn)
{
- rtx body = insn;
-
/* We can be passed an insn or part of one. If we are passed an insn,
check if a side-effect of the insn clobbers REG. */
- if (INSN_P (insn))
- {
- if (FIND_REG_INC_NOTE (insn, reg)
+ if (INSN_P (insn)
+ && (FIND_REG_INC_NOTE (insn, reg)
|| (GET_CODE (insn) == CALL_INSN
/* We'd like to test call_used_regs here, but rtlanal.c can't
reference that variable due to its use in genattrtab. So
@@ -891,11 +953,8 @@ reg_set_p (reg, insn)
&& ((GET_CODE (reg) == REG
&& REGNO (reg) < FIRST_PSEUDO_REGISTER)
|| GET_CODE (reg) == MEM
- || find_reg_fusage (insn, CLOBBER, reg))))
- return 1;
-
- body = PATTERN (insn);
- }
+ || find_reg_fusage (insn, CLOBBER, reg)))))
+ return 1;
return set_of (reg, insn) != NULL_RTX;
}
@@ -905,9 +964,7 @@ reg_set_p (reg, insn)
consider non-registers one way or the other. */
int
-regs_set_between_p (x, start, end)
- rtx x;
- rtx start, end;
+regs_set_between_p (rtx x, rtx start, rtx end)
{
enum rtx_code code = GET_CODE (x);
const char *fmt;
@@ -949,16 +1006,18 @@ regs_set_between_p (x, start, end)
/* Similar to reg_set_between_p, but check all registers in X. Return 0
only if none of them are modified between START and END. Return 1 if
- X contains a MEM; this routine does not perform any memory aliasing. */
+ X contains a MEM; this routine does usememory aliasing. */
int
-modified_between_p (x, start, end)
- rtx x;
- rtx start, end;
+modified_between_p (rtx x, rtx start, rtx end)
{
enum rtx_code code = GET_CODE (x);
const char *fmt;
int i, j;
+ rtx insn;
+
+ if (start == end)
+ return 0;
switch (code)
{
@@ -975,10 +1034,14 @@ modified_between_p (x, start, end)
return 1;
case MEM:
- /* If the memory is not constant, assume it is modified. If it is
- constant, we still have to check the address. */
- if (! RTX_UNCHANGING_P (x))
+ if (RTX_UNCHANGING_P (x))
+ return 0;
+ if (modified_between_p (XEXP (x, 0), start, end))
return 1;
+ for (insn = NEXT_INSN (start); insn != end; insn = NEXT_INSN (insn))
+ if (memory_modified_in_insn_p (x, insn))
+ return 1;
+ return 0;
break;
case REG:
@@ -1005,12 +1068,10 @@ modified_between_p (x, start, end)
/* Similar to reg_set_p, but check all registers in X. Return 0 only if none
of them are modified in INSN. Return 1 if X contains a MEM; this routine
- does not perform any memory aliasing. */
+ does use memory aliasing. */
int
-modified_in_p (x, insn)
- rtx x;
- rtx insn;
+modified_in_p (rtx x, rtx insn)
{
enum rtx_code code = GET_CODE (x);
const char *fmt;
@@ -1031,10 +1092,13 @@ modified_in_p (x, insn)
return 1;
case MEM:
- /* If the memory is not constant, assume it is modified. If it is
- constant, we still have to check the address. */
- if (! RTX_UNCHANGING_P (x))
+ if (RTX_UNCHANGING_P (x))
+ return 0;
+ if (modified_in_p (XEXP (x, 0), insn))
+ return 1;
+ if (memory_modified_in_insn_p (x, insn))
return 1;
+ return 0;
break;
case REG:
@@ -1063,8 +1127,7 @@ modified_in_p (x, insn)
anything in insn Y. */
int
-insn_dependent_p (x, y)
- rtx x, y;
+insn_dependent_p (rtx x, rtx y)
{
rtx tmp;
@@ -1087,10 +1150,7 @@ insn_dependent_p (x, y)
/* A helper routine for insn_dependent_p called through note_stores. */
static void
-insn_dependent_p_1 (x, pat, data)
- rtx x;
- rtx pat ATTRIBUTE_UNUSED;
- void *data;
+insn_dependent_p_1 (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
{
rtx * pinsn = (rtx *) data;
@@ -1106,10 +1166,7 @@ struct set_of_data
};
static void
-set_of_1 (x, pat, data1)
- rtx x;
- rtx pat;
- void *data1;
+set_of_1 (rtx x, rtx pat, void *data1)
{
struct set_of_data *data = (struct set_of_data *) (data1);
if (rtx_equal_p (x, data->pat)
@@ -1120,8 +1177,7 @@ set_of_1 (x, pat, data1)
/* Give an INSN, return a SET or CLOBBER expression that does modify PAT
(either directly or via STRICT_LOW_PART and similar modifiers). */
rtx
-set_of (pat, insn)
- rtx pat, insn;
+set_of (rtx pat, rtx insn)
{
struct set_of_data data;
data.found = NULL_RTX;
@@ -1135,8 +1191,7 @@ set_of (pat, insn)
will not be used, which we ignore. */
rtx
-single_set_2 (insn, pat)
- rtx insn, pat;
+single_set_2 (rtx insn, rtx pat)
{
rtx set = NULL;
int set_verified = 1;
@@ -1189,8 +1244,7 @@ single_set_2 (insn, pat)
zero. */
int
-multiple_sets (insn)
- rtx insn;
+multiple_sets (rtx insn)
{
int found;
int i;
@@ -1221,25 +1275,22 @@ multiple_sets (insn)
and there are no side effects. */
int
-set_noop_p (set)
- rtx set;
+set_noop_p (rtx set)
{
rtx src = SET_SRC (set);
rtx dst = SET_DEST (set);
- if (side_effects_p (src) || side_effects_p (dst))
- return 0;
-
- if (GET_CODE (dst) == MEM && GET_CODE (src) == MEM)
- return rtx_equal_p (dst, src);
-
if (dst == pc_rtx && src == pc_rtx)
return 1;
+ if (GET_CODE (dst) == MEM && GET_CODE (src) == MEM)
+ return rtx_equal_p (dst, src) && !side_effects_p (dst);
+
if (GET_CODE (dst) == SIGN_EXTRACT
|| GET_CODE (dst) == ZERO_EXTRACT)
return rtx_equal_p (XEXP (dst, 0), src)
- && ! BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx;
+ && ! BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx
+ && !side_effects_p (src);
if (GET_CODE (dst) == STRICT_LOW_PART)
dst = XEXP (dst, 0);
@@ -1260,8 +1311,7 @@ set_noop_p (set)
value to itself. */
int
-noop_move_p (insn)
- rtx insn;
+noop_move_p (rtx insn)
{
rtx pat = PATTERN (insn);
@@ -1311,11 +1361,7 @@ noop_move_p (insn)
be the src. */
rtx
-find_last_value (x, pinsn, valid_to, allow_hwreg)
- rtx x;
- rtx *pinsn;
- rtx valid_to;
- int allow_hwreg;
+find_last_value (rtx x, rtx *pinsn, rtx valid_to, int allow_hwreg)
{
rtx p;
@@ -1361,10 +1407,8 @@ find_last_value (x, pinsn, valid_to, allow_hwreg)
LOC may be zero, meaning don't ignore anything. */
int
-refers_to_regno_p (regno, endregno, x, loc)
- unsigned int regno, endregno;
- rtx x;
- rtx *loc;
+refers_to_regno_p (unsigned int regno, unsigned int endregno, rtx x,
+ rtx *loc)
{
int i;
unsigned int x_regno;
@@ -1459,7 +1503,7 @@ refers_to_regno_p (regno, endregno, x, loc)
else if (fmt[i] == 'E')
{
int j;
- for (j = XVECLEN (x, i) - 1; j >=0; j--)
+ for (j = XVECLEN (x, i) - 1; j >= 0; j--)
if (loc != &XVECEXP (x, i, j)
&& refers_to_regno_p (regno, endregno, XVECEXP (x, i, j), loc))
return 1;
@@ -1475,8 +1519,7 @@ refers_to_regno_p (regno, endregno, x, loc)
conflict because we expect this to be a rare case. */
int
-reg_overlap_mentioned_p (x, in)
- rtx x, in;
+reg_overlap_mentioned_p (rtx x, rtx in)
{
unsigned int regno, endregno;
@@ -1552,9 +1595,7 @@ reg_overlap_mentioned_p (x, in)
check if a MEM remains unchanged. */
rtx
-reg_set_last (x, insn)
- rtx x;
- rtx insn;
+reg_set_last (rtx x, rtx insn)
{
rtx orig_insn = insn;
@@ -1605,10 +1646,7 @@ reg_set_last (x, insn)
the SUBREG will be passed. */
void
-note_stores (x, fun, data)
- rtx x;
- void (*fun) PARAMS ((rtx, rtx, void *));
- void *data;
+note_stores (rtx x, void (*fun) (rtx, rtx, void *), void *data)
{
int i;
@@ -1654,10 +1692,7 @@ note_stores (x, fun, data)
partially set, while we do not. */
void
-note_uses (pbody, fun, data)
- rtx *pbody;
- void (*fun) PARAMS ((rtx *, void *));
- void *data;
+note_uses (rtx *pbody, void (*fun) (rtx *, void *), void *data)
{
rtx body = *pbody;
int i;
@@ -1749,9 +1784,7 @@ note_uses (pbody, fun, data)
by INSN. */
int
-dead_or_set_p (insn, x)
- rtx insn;
- rtx x;
+dead_or_set_p (rtx insn, rtx x)
{
unsigned int regno, last_regno;
unsigned int i;
@@ -1778,9 +1811,7 @@ dead_or_set_p (insn, x)
called from flow.c. */
int
-dead_or_set_regno_p (insn, test_regno)
- rtx insn;
- unsigned int test_regno;
+dead_or_set_regno_p (rtx insn, unsigned int test_regno)
{
unsigned int regno, endregno;
rtx pattern;
@@ -1863,10 +1894,7 @@ dead_or_set_regno_p (insn, test_regno)
If DATUM is nonzero, look for one whose datum is DATUM. */
rtx
-find_reg_note (insn, kind, datum)
- rtx insn;
- enum reg_note kind;
- rtx datum;
+find_reg_note (rtx insn, enum reg_note kind, rtx datum)
{
rtx link;
@@ -1887,10 +1915,7 @@ find_reg_note (insn, kind, datum)
it might be the case that the note overlaps REGNO. */
rtx
-find_regno_note (insn, kind, regno)
- rtx insn;
- enum reg_note kind;
- unsigned int regno;
+find_regno_note (rtx insn, enum reg_note kind, unsigned int regno)
{
rtx link;
@@ -1917,27 +1942,28 @@ find_regno_note (insn, kind, regno)
has such a note. */
rtx
-find_reg_equal_equiv_note (insn)
- rtx insn;
+find_reg_equal_equiv_note (rtx insn)
{
- rtx note;
+ rtx link;
- if (single_set (insn) == 0)
+ if (!INSN_P (insn))
return 0;
- else if ((note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) != 0)
- return note;
- else
- return find_reg_note (insn, REG_EQUAL, NULL_RTX);
+ for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
+ if (REG_NOTE_KIND (link) == REG_EQUAL
+ || REG_NOTE_KIND (link) == REG_EQUIV)
+ {
+ if (single_set (insn) == 0)
+ return 0;
+ return link;
+ }
+ return NULL;
}
/* Return true if DATUM, or any overlap of DATUM, of kind CODE is found
in the CALL_INSN_FUNCTION_USAGE information of INSN. */
int
-find_reg_fusage (insn, code, datum)
- rtx insn;
- enum rtx_code code;
- rtx datum;
+find_reg_fusage (rtx insn, enum rtx_code code, rtx datum)
{
/* If it's not a CALL_INSN, it can't possibly have a
CALL_INSN_FUNCTION_USAGE field, so don't bother checking. */
@@ -1984,10 +2010,7 @@ find_reg_fusage (insn, code, datum)
in the CALL_INSN_FUNCTION_USAGE information of INSN. */
int
-find_regno_fusage (insn, code, regno)
- rtx insn;
- enum rtx_code code;
- unsigned int regno;
+find_regno_fusage (rtx insn, enum rtx_code code, unsigned int regno)
{
rtx link;
@@ -2016,8 +2039,7 @@ find_regno_fusage (insn, code, regno)
/* Return true if INSN is a call to a pure function. */
int
-pure_call_p (insn)
- rtx insn;
+pure_call_p (rtx insn)
{
rtx link;
@@ -2041,9 +2063,7 @@ pure_call_p (insn)
/* Remove register note NOTE from the REG_NOTES of INSN. */
void
-remove_note (insn, note)
- rtx insn;
- rtx note;
+remove_note (rtx insn, rtx note)
{
rtx link;
@@ -2071,9 +2091,7 @@ remove_note (insn, note)
NODE matches. */
int
-in_expr_list_p (listp, node)
- rtx listp;
- rtx node;
+in_expr_list_p (rtx listp, rtx node)
{
rtx x;
@@ -2090,9 +2108,7 @@ in_expr_list_p (listp, node)
A simple equality test is used to determine if NODE matches. */
void
-remove_node_from_expr_list (node, listp)
- rtx node;
- rtx *listp;
+remove_node_from_expr_list (rtx node, rtx *listp)
{
rtx temp = *listp;
rtx prev = NULL_RTX;
@@ -2121,8 +2137,7 @@ remove_node_from_expr_list (node, listp)
only volatile asms and UNSPEC_VOLATILE instructions. */
int
-volatile_insn_p (x)
- rtx x;
+volatile_insn_p (rtx x)
{
RTX_CODE code;
@@ -2188,8 +2203,7 @@ volatile_insn_p (x)
UNSPEC_VOLATILE operations or volatile ASM_OPERANDS expressions. */
int
-volatile_refs_p (x)
- rtx x;
+volatile_refs_p (rtx x)
{
RTX_CODE code;
@@ -2253,8 +2267,7 @@ volatile_refs_p (x)
incrementing. */
int
-side_effects_p (x)
- rtx x;
+side_effects_p (rtx x)
{
RTX_CODE code;
@@ -2330,8 +2343,7 @@ side_effects_p (x)
/* Return nonzero if evaluating rtx X might cause a trap. */
int
-may_trap_p (x)
- rtx x;
+may_trap_p (rtx x)
{
int i;
enum rtx_code code;
@@ -2380,9 +2392,7 @@ may_trap_p (x)
|| (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT
&& flag_trapping_math))
return 1;
- /* This was const0_rtx, but by not using that,
- we can link this file into other programs. */
- if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0)
+ if (XEXP (x, 1) == const0_rtx)
return 1;
break;
@@ -2463,8 +2473,7 @@ may_trap_p (x)
i.e., an inequality. */
int
-inequality_comparisons_p (x)
- rtx x;
+inequality_comparisons_p (rtx x)
{
const char *fmt;
int len, i;
@@ -2527,8 +2536,7 @@ inequality_comparisons_p (x)
are to be modified. */
rtx
-replace_rtx (x, from, to)
- rtx x, from, to;
+replace_rtx (rtx x, rtx from, rtx to)
{
int i, j;
const char *fmt;
@@ -2605,11 +2613,7 @@ replace_rtx (x, from, to)
otherwise, only sources are replaced. */
rtx
-replace_regs (x, reg_map, nregs, replace_dest)
- rtx x;
- rtx *reg_map;
- unsigned int nregs;
- int replace_dest;
+replace_regs (rtx x, rtx *reg_map, unsigned int nregs, int replace_dest)
{
enum rtx_code code;
int i;
@@ -2696,13 +2700,130 @@ replace_regs (x, reg_map, nregs, replace_dest)
return x;
}
+/* Replace occurrences of the old label in *X with the new one.
+ DATA is a REPLACE_LABEL_DATA containing the old and new labels. */
+
+int
+replace_label (rtx *x, void *data)
+{
+ rtx l = *x;
+ rtx old_label = ((replace_label_data *) data)->r1;
+ rtx new_label = ((replace_label_data *) data)->r2;
+ bool update_label_nuses = ((replace_label_data *) data)->update_label_nuses;
+
+ if (l == NULL_RTX)
+ return 0;
+
+ if (GET_CODE (l) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (l))
+ {
+ rtx c = get_pool_constant (l);
+ if (rtx_referenced_p (old_label, c))
+ {
+ rtx new_c, new_l;
+ replace_label_data *d = (replace_label_data *) data;
+
+ /* Create a copy of constant C; replace the label inside
+ but do not update LABEL_NUSES because uses in constant pool
+ are not counted. */
+ new_c = copy_rtx (c);
+ d->update_label_nuses = false;
+ for_each_rtx (&new_c, replace_label, data);
+ d->update_label_nuses = update_label_nuses;
+
+ /* Add the new constant NEW_C to constant pool and replace
+ the old reference to constant by new reference. */
+ new_l = XEXP (force_const_mem (get_pool_mode (l), new_c), 0);
+ *x = replace_rtx (l, l, new_l);
+ }
+ return 0;
+ }
+
+ /* If this is a JUMP_INSN, then we also need to fix the JUMP_LABEL
+ field. This is not handled by for_each_rtx because it doesn't
+ handle unprinted ('0') fields. */
+ if (GET_CODE (l) == JUMP_INSN && JUMP_LABEL (l) == old_label)
+ JUMP_LABEL (l) = new_label;
+
+ if ((GET_CODE (l) == LABEL_REF
+ || GET_CODE (l) == INSN_LIST)
+ && XEXP (l, 0) == old_label)
+ {
+ XEXP (l, 0) = new_label;
+ if (update_label_nuses)
+ {
+ ++LABEL_NUSES (new_label);
+ --LABEL_NUSES (old_label);
+ }
+ return 0;
+ }
+
+ return 0;
+}
+
+/* When *BODY is equal to X or X is directly referenced by *BODY
+ return nonzero, thus FOR_EACH_RTX stops traversing and returns nonzero
+ too, otherwise FOR_EACH_RTX continues traversing *BODY. */
+
+static int
+rtx_referenced_p_1 (rtx *body, void *x)
+{
+ rtx y = (rtx) x;
+
+ if (*body == NULL_RTX)
+ return y == NULL_RTX;
+
+ /* Return true if a label_ref *BODY refers to label Y. */
+ if (GET_CODE (*body) == LABEL_REF && GET_CODE (y) == CODE_LABEL)
+ return XEXP (*body, 0) == y;
+
+ /* If *BODY is a reference to pool constant traverse the constant. */
+ if (GET_CODE (*body) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (*body))
+ return rtx_referenced_p (y, get_pool_constant (*body));
+
+ /* By default, compare the RTL expressions. */
+ return rtx_equal_p (*body, y);
+}
+
+/* Return true if X is referenced in BODY. */
+
+int
+rtx_referenced_p (rtx x, rtx body)
+{
+ return for_each_rtx (&body, rtx_referenced_p_1, x);
+}
+
+/* If INSN is a tablejump return true and store the label (before jump table) to
+ *LABELP and the jump table to *TABLEP. LABELP and TABLEP may be NULL. */
+
+bool
+tablejump_p (rtx insn, rtx *labelp, rtx *tablep)
+{
+ rtx label, table;
+
+ if (GET_CODE (insn) == JUMP_INSN
+ && (label = JUMP_LABEL (insn)) != NULL_RTX
+ && (table = next_active_insn (label)) != NULL_RTX
+ && GET_CODE (table) == JUMP_INSN
+ && (GET_CODE (PATTERN (table)) == ADDR_VEC
+ || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
+ {
+ if (labelp)
+ *labelp = label;
+ if (tablep)
+ *tablep = table;
+ return true;
+ }
+ return false;
+}
+
/* A subroutine of computed_jump_p, return 1 if X contains a REG or MEM or
constant that is not in the constant pool and not in the condition
of an IF_THEN_ELSE. */
static int
-computed_jump_p_1 (x)
- rtx x;
+computed_jump_p_1 (rtx x)
{
enum rtx_code code = GET_CODE (x);
int i, j;
@@ -2756,8 +2877,7 @@ computed_jump_p_1 (x)
we can recognize them by a (use (label_ref)). */
int
-computed_jump_p (insn)
- rtx insn;
+computed_jump_p (rtx insn)
{
int i;
if (GET_CODE (insn) == JUMP_INSN)
@@ -2806,10 +2926,7 @@ computed_jump_p (insn)
implement many of the other routines in this file. */
int
-for_each_rtx (x, f, data)
- rtx *x;
- rtx_function f;
- void *data;
+for_each_rtx (rtx *x, rtx_function f, void *data)
{
int result;
int length;
@@ -2870,9 +2987,7 @@ for_each_rtx (x, f, data)
reference found if any. Otherwise, returns NULL_RTX. */
rtx
-regno_use_in (regno, x)
- unsigned int regno;
- rtx x;
+regno_use_in (unsigned int regno, rtx x)
{
const char *fmt;
int i, j;
@@ -2905,8 +3020,7 @@ regno_use_in (regno, x)
and positive values for the second operand. */
int
-commutative_operand_precedence (op)
- rtx op;
+commutative_operand_precedence (rtx op)
{
/* Constants always come the second operand. Prefer "nice" constants. */
if (GET_CODE (op) == CONST_INT)
@@ -2940,8 +3054,7 @@ commutative_operand_precedence (op)
in order to canonicalize expression. */
int
-swap_commutative_operands_p (x, y)
- rtx x, y;
+swap_commutative_operands_p (rtx x, rtx y)
{
return (commutative_operand_precedence (x)
< commutative_operand_precedence (y));
@@ -2950,8 +3063,7 @@ swap_commutative_operands_p (x, y)
/* Return 1 if X is an autoincrement side effect and the register is
not the stack pointer. */
int
-auto_inc_p (x)
- rtx x;
+auto_inc_p (rtx x)
{
switch (GET_CODE (x))
{
@@ -2981,10 +3093,7 @@ auto_inc_p (x)
conditions as well. */
int
-insns_safe_to_move_p (from, to, new_to)
- rtx from;
- rtx to;
- rtx *new_to;
+insns_safe_to_move_p (rtx from, rtx to, rtx *new_to)
{
int eh_region_count = 0;
int past_to_p = 0;
@@ -3049,10 +3158,9 @@ insns_safe_to_move_p (from, to, new_to)
return 0;
}
-/* Return nonzero if IN contains a piece of rtl that has the address LOC */
+/* Return nonzero if IN contains a piece of rtl that has the address LOC. */
int
-loc_mentioned_in_p (loc, in)
- rtx *loc, in;
+loc_mentioned_in_p (rtx *loc, rtx in)
{
enum rtx_code code = GET_CODE (in);
const char *fmt = GET_RTX_FORMAT (code);
@@ -3060,7 +3168,7 @@ loc_mentioned_in_p (loc, in)
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
- if (loc == &in->fld[i].rtx)
+ if (loc == &in->u.fld[i].rtx)
return 1;
if (fmt[i] == 'e')
{
@@ -3079,8 +3187,7 @@ loc_mentioned_in_p (loc, in)
(counting from the least significant bit of the reg). */
unsigned int
-subreg_lsb (x)
- rtx x;
+subreg_lsb (rtx x)
{
enum machine_mode inner_mode = GET_MODE (SUBREG_REG (x));
enum machine_mode mode = GET_MODE (x);
@@ -3125,11 +3232,8 @@ subreg_lsb (x)
ymode - The mode of a top level SUBREG (or what may become one).
RETURN - The regno offset which would be used. */
unsigned int
-subreg_regno_offset (xregno, xmode, offset, ymode)
- unsigned int xregno;
- enum machine_mode xmode;
- unsigned int offset;
- enum machine_mode ymode;
+subreg_regno_offset (unsigned int xregno, enum machine_mode xmode,
+ unsigned int offset, enum machine_mode ymode)
{
int nregs_xmode, nregs_ymode;
int mode_multiple, nregs_multiple;
@@ -3171,11 +3275,8 @@ subreg_regno_offset (xregno, xmode, offset, ymode)
ymode - The mode of a top level SUBREG (or what may become one).
RETURN - The regno offset which would be used. */
bool
-subreg_offset_representable_p (xregno, xmode, offset, ymode)
- unsigned int xregno;
- enum machine_mode xmode;
- unsigned int offset;
- enum machine_mode ymode;
+subreg_offset_representable_p (unsigned int xregno, enum machine_mode xmode,
+ unsigned int offset, enum machine_mode ymode)
{
int nregs_xmode, nregs_ymode;
int mode_multiple, nregs_multiple;
@@ -3208,12 +3309,12 @@ subreg_offset_representable_p (xregno, xmode, offset, ymode)
abort ();
#endif
- /* The XMODE value can be seen as an vector of NREGS_XMODE
- values. The subreg must represent an lowpart of given field.
+ /* The XMODE value can be seen as a vector of NREGS_XMODE
+ values. The subreg must represent a lowpart of given field.
Compute what field it is. */
- offset -= subreg_lowpart_offset (ymode,
- mode_for_size (GET_MODE_BITSIZE (xmode)
- / nregs_xmode,
+ offset -= subreg_lowpart_offset (ymode,
+ mode_for_size (GET_MODE_BITSIZE (xmode)
+ / nregs_xmode,
MODE_INT, 0));
/* size of ymode must not be greater than the size of xmode. */
@@ -3233,8 +3334,7 @@ subreg_offset_representable_p (xregno, xmode, offset, ymode)
/* Return the final regno that a subreg expression refers to. */
unsigned int
-subreg_regno (x)
- rtx x;
+subreg_regno (rtx x)
{
unsigned int ret;
rtx subreg = SUBREG_REG (x);
@@ -3255,9 +3355,7 @@ struct parms_set_data
/* Helper function for noticing stores to parameter registers. */
static void
-parms_set (x, pat, data)
- rtx x, pat ATTRIBUTE_UNUSED;
- void *data;
+parms_set (rtx x, rtx pat ATTRIBUTE_UNUSED, void *data)
{
struct parms_set_data *d = data;
if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
@@ -3271,8 +3369,7 @@ parms_set (x, pat, data)
/* Look backward for first parameter to be loaded.
Do not skip BOUNDARY. */
rtx
-find_first_parameter_load (call_insn, boundary)
- rtx call_insn, boundary;
+find_first_parameter_load (rtx call_insn, rtx boundary)
{
struct parms_set_data parm;
rtx p, before;
@@ -3326,12 +3423,11 @@ find_first_parameter_load (call_insn, boundary)
return before;
}
-/* Return true if we should avoid inserting code between INSN and preceeding
+/* Return true if we should avoid inserting code between INSN and preceding
call instruction. */
bool
-keep_with_call_p (insn)
- rtx insn;
+keep_with_call_p (rtx insn)
{
rtx set;
@@ -3365,9 +3461,7 @@ keep_with_call_p (insn)
whose value will be used. */
static bool
-hoist_test_store (x, val, live)
- rtx x, val;
- regset live;
+hoist_test_store (rtx x, rtx val, regset live)
{
if (GET_CODE (x) == SCRATCH)
return true;
@@ -3375,7 +3469,7 @@ hoist_test_store (x, val, live)
if (rtx_equal_p (x, val))
return true;
- /* Allow subreg of X in case it is not writting just part of multireg pseudo.
+ /* Allow subreg of X in case it is not writing just part of multireg pseudo.
Then we would need to update all users to care hoisting the store too.
Caller may represent that by specifying whole subreg as val. */
@@ -3396,10 +3490,10 @@ hoist_test_store (x, val, live)
if (!REG_P (x))
return false;
- /* Pseudo registers can be allways replaced by another pseudo to avoid
+ /* Pseudo registers can be always replaced by another pseudo to avoid
the side effect, for hard register we must ensure that they are dead.
Eventually we may want to add code to try turn pseudos to hards, but it
- is unlikely usefull. */
+ is unlikely useful. */
if (REGNO (x) < FIRST_PSEUDO_REGISTER)
{
@@ -3423,9 +3517,7 @@ hoist_test_store (x, val, live)
and used by the hoisting pass. */
bool
-can_hoist_insn_p (insn, val, live)
- rtx insn, val;
- regset live;
+can_hoist_insn_p (rtx insn, rtx val, regset live)
{
rtx pat = PATTERN (insn);
int i;
@@ -3468,8 +3560,8 @@ can_hoist_insn_p (insn, val, live)
break;
case USE:
/* We need to fix callers to really ensure availability
- of all values inisn uses, but for now it is safe to prohibit
- hoisting of any insn having such a hiden uses. */
+ of all values insn uses, but for now it is safe to prohibit
+ hoisting of any insn having such a hidden uses. */
return false;
break;
case CLOBBER:
@@ -3492,8 +3584,7 @@ can_hoist_insn_p (insn, val, live)
be updated to NEW. */
static void
-hoist_update_store (insn, xp, val, new)
- rtx insn, *xp, val, new;
+hoist_update_store (rtx insn, rtx *xp, rtx val, rtx new)
{
rtx x = *xp;
@@ -3530,8 +3621,7 @@ hoist_update_store (insn, xp, val, new)
and each other side effect to pseudo register by new pseudo register. */
rtx
-hoist_insn_after (insn, after, val, new)
- rtx insn, after, val, new;
+hoist_insn_after (rtx insn, rtx after, rtx val, rtx new)
{
rtx pat;
int i;
@@ -3595,9 +3685,7 @@ hoist_insn_after (insn, after, val, new)
}
rtx
-hoist_insn_to_edge (insn, e, val, new)
- rtx insn, val, new;
- edge e;
+hoist_insn_to_edge (rtx insn, edge e, rtx val, rtx new)
{
rtx new_insn;
@@ -3611,7 +3699,7 @@ hoist_insn_to_edge (insn, e, val, new)
if (e->insns == NULL_RTX)
{
start_sequence ();
- emit_note (NULL, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
}
else
push_to_sequence (e->insns);
@@ -3622,3 +3710,31 @@ hoist_insn_to_edge (insn, e, val, new)
end_sequence ();
return new_insn;
}
+
+/* Return true if LABEL is a target of JUMP_INSN. This applies only
+ to non-complex jumps. That is, direct unconditional, conditional,
+ and tablejumps, but not computed jumps or returns. It also does
+ not apply to the fallthru case of a conditional jump. */
+
+bool
+label_is_jump_target_p (rtx label, rtx jump_insn)
+{
+ rtx tmp = JUMP_LABEL (jump_insn);
+
+ if (label == tmp)
+ return true;
+
+ if (tablejump_p (jump_insn, NULL, &tmp))
+ {
+ rtvec vec = XVEC (PATTERN (tmp),
+ GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC);
+ int i, veclen = GET_NUM_ELEM (vec);
+
+ for (i = 0; i < veclen; ++i)
+ if (XEXP (RTVEC_ELT (vec, i), 0) == label)
+ return true;
+ }
+
+ return false;
+}
+
diff --git a/contrib/gcc/sbitmap.c b/contrib/gcc/sbitmap.c
index 74c24c92855b..1d27a871097b 100644
--- a/contrib/gcc/sbitmap.c
+++ b/contrib/gcc/sbitmap.c
@@ -20,6 +20,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "flags.h"
#include "hard-reg-set.h"
@@ -30,8 +32,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Allocate a simple bitmap of N_ELMS bits. */
sbitmap
-sbitmap_alloc (n_elms)
- unsigned int n_elms;
+sbitmap_alloc (unsigned int n_elms)
{
unsigned int bytes, size, amt;
sbitmap bmap;
@@ -40,7 +41,7 @@ sbitmap_alloc (n_elms)
bytes = size * sizeof (SBITMAP_ELT_TYPE);
amt = (sizeof (struct simple_bitmap_def)
+ bytes - sizeof (SBITMAP_ELT_TYPE));
- bmap = (sbitmap) xmalloc (amt);
+ bmap = xmalloc (amt);
bmap->n_bits = n_elms;
bmap->size = size;
bmap->bytes = bytes;
@@ -52,10 +53,7 @@ sbitmap_alloc (n_elms)
is zero, and set them to one otherwise. */
sbitmap
-sbitmap_resize (bmap, n_elms, def)
- sbitmap bmap;
- unsigned int n_elms;
- int def;
+sbitmap_resize (sbitmap bmap, unsigned int n_elms, int def)
{
unsigned int bytes, size, amt;
unsigned int last_bit;
@@ -66,14 +64,14 @@ sbitmap_resize (bmap, n_elms, def)
{
amt = (sizeof (struct simple_bitmap_def)
+ bytes - sizeof (SBITMAP_ELT_TYPE));
- bmap = (sbitmap) xrealloc ((PTR) bmap, amt);
+ bmap = xrealloc (bmap, amt);
}
if (n_elms > bmap->n_bits)
{
if (def)
{
- memset ((PTR) (bmap->elms + bmap->size), -1, bytes - bmap->bytes);
+ memset (bmap->elms + bmap->size, -1, bytes - bmap->bytes);
/* Set the new bits if the original last element. */
last_bit = bmap->n_bits % SBITMAP_ELT_BITS;
@@ -88,11 +86,11 @@ sbitmap_resize (bmap, n_elms, def)
&= (SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit);
}
else
- memset ((PTR) (bmap->elms + bmap->size), 0, bytes - bmap->bytes);
+ memset (bmap->elms + bmap->size, 0, bytes - bmap->bytes);
}
else if (n_elms < bmap->n_bits)
{
- /* Clear the surplus bits in the last word. */
+ /* Clear the surplus bits in the last word. */
last_bit = n_elms % SBITMAP_ELT_BITS;
if (last_bit)
bmap->elms[size - 1]
@@ -108,8 +106,7 @@ sbitmap_resize (bmap, n_elms, def)
/* Allocate a vector of N_VECS bitmaps of N_ELMS bits. */
sbitmap *
-sbitmap_vector_alloc (n_vecs, n_elms)
- unsigned int n_vecs, n_elms;
+sbitmap_vector_alloc (unsigned int n_vecs, unsigned int n_elms)
{
unsigned int i, bytes, offset, elm_bytes, size, amt, vector_bytes;
sbitmap *bitmap_vector;
@@ -133,7 +130,7 @@ sbitmap_vector_alloc (n_vecs, n_elms)
}
amt = vector_bytes + (n_vecs * elm_bytes);
- bitmap_vector = (sbitmap *) xmalloc (amt);
+ bitmap_vector = xmalloc (amt);
for (i = 0, offset = vector_bytes; i < n_vecs; i++, offset += elm_bytes)
{
@@ -151,16 +148,14 @@ sbitmap_vector_alloc (n_vecs, n_elms)
/* Copy sbitmap SRC to DST. */
void
-sbitmap_copy (dst, src)
- sbitmap dst, src;
+sbitmap_copy (sbitmap dst, sbitmap src)
{
memcpy (dst->elms, src->elms, sizeof (SBITMAP_ELT_TYPE) * dst->size);
}
/* Determine if a == b. */
int
-sbitmap_equal (a, b)
- sbitmap a, b;
+sbitmap_equal (sbitmap a, sbitmap b)
{
return !memcmp (a->elms, b->elms, sizeof (SBITMAP_ELT_TYPE) * a->size);
}
@@ -168,21 +163,19 @@ sbitmap_equal (a, b)
/* Zero all elements in a bitmap. */
void
-sbitmap_zero (bmap)
- sbitmap bmap;
+sbitmap_zero (sbitmap bmap)
{
- memset ((PTR) bmap->elms, 0, bmap->bytes);
+ memset (bmap->elms, 0, bmap->bytes);
}
/* Set all elements in a bitmap to ones. */
void
-sbitmap_ones (bmap)
- sbitmap bmap;
+sbitmap_ones (sbitmap bmap)
{
unsigned int last_bit;
- memset ((PTR) bmap->elms, -1, bmap->bytes);
+ memset (bmap->elms, -1, bmap->bytes);
last_bit = bmap->n_bits % SBITMAP_ELT_BITS;
if (last_bit)
@@ -193,9 +186,7 @@ sbitmap_ones (bmap)
/* Zero a vector of N_VECS bitmaps. */
void
-sbitmap_vector_zero (bmap, n_vecs)
- sbitmap *bmap;
- unsigned int n_vecs;
+sbitmap_vector_zero (sbitmap *bmap, unsigned int n_vecs)
{
unsigned int i;
@@ -206,9 +197,7 @@ sbitmap_vector_zero (bmap, n_vecs)
/* Set a vector of N_VECS bitmaps to ones. */
void
-sbitmap_vector_ones (bmap, n_vecs)
- sbitmap *bmap;
- unsigned int n_vecs;
+sbitmap_vector_ones (sbitmap *bmap, unsigned int n_vecs)
{
unsigned int i;
@@ -221,8 +210,7 @@ sbitmap_vector_ones (bmap, n_vecs)
Returns true if any change is made. */
bool
-sbitmap_union_of_diff_cg (dst, a, b, c)
- sbitmap dst, a, b, c;
+sbitmap_union_of_diff_cg (sbitmap dst, sbitmap a, sbitmap b, sbitmap c)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
@@ -242,8 +230,7 @@ sbitmap_union_of_diff_cg (dst, a, b, c)
}
void
-sbitmap_union_of_diff (dst, a, b, c)
- sbitmap dst, a, b, c;
+sbitmap_union_of_diff (sbitmap dst, sbitmap a, sbitmap b, sbitmap c)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
@@ -258,30 +245,35 @@ sbitmap_union_of_diff (dst, a, b, c)
/* Set bitmap DST to the bitwise negation of the bitmap SRC. */
void
-sbitmap_not (dst, src)
- sbitmap dst, src;
+sbitmap_not (sbitmap dst, sbitmap src)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
sbitmap_ptr srcp = src->elms;
+ unsigned int last_bit;
for (i = 0; i < n; i++)
*dstp++ = ~*srcp++;
+
+ /* Zero all bits past n_bits, by ANDing dst with sbitmap_ones. */
+ last_bit = src->n_bits % SBITMAP_ELT_BITS;
+ if (last_bit)
+ dst->elms[n-1] = dst->elms[n-1]
+ & ((SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit));
}
/* Set the bits in DST to be the difference between the bits
in A and the bits in B. i.e. dst = a & (~b). */
void
-sbitmap_difference (dst, a, b)
- sbitmap dst, a, b;
+sbitmap_difference (sbitmap dst, sbitmap a, sbitmap b)
{
unsigned int i, dst_size = dst->size;
unsigned int min_size = dst->size;
sbitmap_ptr dstp = dst->elms;
sbitmap_ptr ap = a->elms;
sbitmap_ptr bp = b->elms;
-
+
/* A should be at least as large as DEST, to have a defined source. */
if (a->size < dst_size)
abort ();
@@ -302,8 +294,7 @@ sbitmap_difference (dst, a, b)
Return nonzero if any change is made. */
bool
-sbitmap_a_and_b_cg (dst, a, b)
- sbitmap dst, a, b;
+sbitmap_a_and_b_cg (sbitmap dst, sbitmap a, sbitmap b)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
@@ -314,7 +305,7 @@ sbitmap_a_and_b_cg (dst, a, b)
for (i = 0; i < n; i++)
{
SBITMAP_ELT_TYPE tmp = *ap++ & *bp++;
- changed = *dstp ^ tmp;
+ changed |= *dstp ^ tmp;
*dstp++ = tmp;
}
@@ -322,8 +313,7 @@ sbitmap_a_and_b_cg (dst, a, b)
}
void
-sbitmap_a_and_b (dst, a, b)
- sbitmap dst, a, b;
+sbitmap_a_and_b (sbitmap dst, sbitmap a, sbitmap b)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
@@ -338,8 +328,7 @@ sbitmap_a_and_b (dst, a, b)
Return nonzero if any change is made. */
bool
-sbitmap_a_xor_b_cg (dst, a, b)
- sbitmap dst, a, b;
+sbitmap_a_xor_b_cg (sbitmap dst, sbitmap a, sbitmap b)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
@@ -350,7 +339,7 @@ sbitmap_a_xor_b_cg (dst, a, b)
for (i = 0; i < n; i++)
{
SBITMAP_ELT_TYPE tmp = *ap++ ^ *bp++;
- changed = *dstp ^ tmp;
+ changed |= *dstp ^ tmp;
*dstp++ = tmp;
}
@@ -358,8 +347,7 @@ sbitmap_a_xor_b_cg (dst, a, b)
}
void
-sbitmap_a_xor_b (dst, a, b)
- sbitmap dst, a, b;
+sbitmap_a_xor_b (sbitmap dst, sbitmap a, sbitmap b)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
@@ -374,8 +362,7 @@ sbitmap_a_xor_b (dst, a, b)
Return nonzero if any change is made. */
bool
-sbitmap_a_or_b_cg (dst, a, b)
- sbitmap dst, a, b;
+sbitmap_a_or_b_cg (sbitmap dst, sbitmap a, sbitmap b)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
@@ -386,7 +373,7 @@ sbitmap_a_or_b_cg (dst, a, b)
for (i = 0; i < n; i++)
{
SBITMAP_ELT_TYPE tmp = *ap++ | *bp++;
- changed = *dstp ^ tmp;
+ changed |= *dstp ^ tmp;
*dstp++ = tmp;
}
@@ -394,8 +381,7 @@ sbitmap_a_or_b_cg (dst, a, b)
}
void
-sbitmap_a_or_b (dst, a, b)
- sbitmap dst, a, b;
+sbitmap_a_or_b (sbitmap dst, sbitmap a, sbitmap b)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
@@ -409,8 +395,7 @@ sbitmap_a_or_b (dst, a, b)
/* Return nonzero if A is a subset of B. */
bool
-sbitmap_a_subset_b_p (a, b)
- sbitmap a, b;
+sbitmap_a_subset_b_p (sbitmap a, sbitmap b)
{
unsigned int i, n = a->size;
sbitmap_ptr ap, bp;
@@ -426,8 +411,7 @@ sbitmap_a_subset_b_p (a, b)
Return nonzero if any change is made. */
bool
-sbitmap_a_or_b_and_c_cg (dst, a, b, c)
- sbitmap dst, a, b, c;
+sbitmap_a_or_b_and_c_cg (sbitmap dst, sbitmap a, sbitmap b, sbitmap c)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
@@ -447,8 +431,7 @@ sbitmap_a_or_b_and_c_cg (dst, a, b, c)
}
void
-sbitmap_a_or_b_and_c (dst, a, b, c)
- sbitmap dst, a, b, c;
+sbitmap_a_or_b_and_c (sbitmap dst, sbitmap a, sbitmap b, sbitmap c)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
@@ -464,8 +447,7 @@ sbitmap_a_or_b_and_c (dst, a, b, c)
Return nonzero if any change is made. */
bool
-sbitmap_a_and_b_or_c_cg (dst, a, b, c)
- sbitmap dst, a, b, c;
+sbitmap_a_and_b_or_c_cg (sbitmap dst, sbitmap a, sbitmap b, sbitmap c)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
@@ -485,8 +467,7 @@ sbitmap_a_and_b_or_c_cg (dst, a, b, c)
}
void
-sbitmap_a_and_b_or_c (dst, a, b, c)
- sbitmap dst, a, b, c;
+sbitmap_a_and_b_or_c (sbitmap dst, sbitmap a, sbitmap b, sbitmap c)
{
unsigned int i, n = dst->size;
sbitmap_ptr dstp = dst->elms;
@@ -503,10 +484,7 @@ sbitmap_a_and_b_or_c (dst, a, b, c)
block number BB, using the new flow graph structures. */
void
-sbitmap_intersection_of_succs (dst, src, bb)
- sbitmap dst;
- sbitmap *src;
- int bb;
+sbitmap_intersection_of_succs (sbitmap dst, sbitmap *src, int bb)
{
basic_block b = BASIC_BLOCK (bb);
unsigned int set_size = dst->size;
@@ -543,10 +521,7 @@ sbitmap_intersection_of_succs (dst, src, bb)
block number BB, using the new flow graph structures. */
void
-sbitmap_intersection_of_preds (dst, src, bb)
- sbitmap dst;
- sbitmap *src;
- int bb;
+sbitmap_intersection_of_preds (sbitmap dst, sbitmap *src, int bb)
{
basic_block b = BASIC_BLOCK (bb);
unsigned int set_size = dst->size;
@@ -583,10 +558,7 @@ sbitmap_intersection_of_preds (dst, src, bb)
block number BB, using the new flow graph structures. */
void
-sbitmap_union_of_succs (dst, src, bb)
- sbitmap dst;
- sbitmap *src;
- int bb;
+sbitmap_union_of_succs (sbitmap dst, sbitmap *src, int bb)
{
basic_block b = BASIC_BLOCK (bb);
unsigned int set_size = dst->size;
@@ -623,10 +595,7 @@ sbitmap_union_of_succs (dst, src, bb)
block number BB, using the new flow graph structures. */
void
-sbitmap_union_of_preds (dst, src, bb)
- sbitmap dst;
- sbitmap *src;
- int bb;
+sbitmap_union_of_preds (sbitmap dst, sbitmap *src, int bb)
{
basic_block b = BASIC_BLOCK (bb);
unsigned int set_size = dst->size;
@@ -663,8 +632,7 @@ sbitmap_union_of_preds (dst, src, bb)
/* Return number of first bit set in the bitmap, -1 if none. */
int
-sbitmap_first_set_bit (bmap)
- sbitmap bmap;
+sbitmap_first_set_bit (sbitmap bmap)
{
unsigned int n;
@@ -675,8 +643,7 @@ sbitmap_first_set_bit (bmap)
/* Return number of last bit set in the bitmap, -1 if none. */
int
-sbitmap_last_set_bit (bmap)
- sbitmap bmap;
+sbitmap_last_set_bit (sbitmap bmap)
{
int i;
SBITMAP_ELT_TYPE *ptr = bmap->elms;
@@ -706,9 +673,7 @@ sbitmap_last_set_bit (bmap)
}
void
-dump_sbitmap (file, bmap)
- FILE *file;
- sbitmap bmap;
+dump_sbitmap (FILE *file, sbitmap bmap)
{
unsigned int i, n, j;
unsigned int set_size = bmap->size;
@@ -729,9 +694,7 @@ dump_sbitmap (file, bmap)
}
void
-dump_sbitmap_file (file, bmap)
- FILE *file;
- sbitmap bmap;
+dump_sbitmap_file (FILE *file, sbitmap bmap)
{
unsigned int i, pos;
@@ -754,18 +717,14 @@ dump_sbitmap_file (file, bmap)
}
void
-debug_sbitmap (bmap)
- sbitmap bmap;
+debug_sbitmap (sbitmap bmap)
{
dump_sbitmap_file (stderr, bmap);
}
void
-dump_sbitmap_vector (file, title, subtitle, bmaps, n_maps)
- FILE *file;
- const char *title, *subtitle;
- sbitmap *bmaps;
- int n_maps;
+dump_sbitmap_vector (FILE *file, const char *title, const char *subtitle,
+ sbitmap *bmaps, int n_maps)
{
int bb;
diff --git a/contrib/gcc/sbitmap.h b/contrib/gcc/sbitmap.h
index 42e466e437ec..fecc49150837 100644
--- a/contrib/gcc/sbitmap.h
+++ b/contrib/gcc/sbitmap.h
@@ -19,7 +19,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#ifndef GCC_SBITMAP_H
-#define GCC_SBITMAP_H
+#define GCC_SBITMAP_H
/* It's not clear yet whether using bitmap.[ch] will be a win.
It should be straightforward to convert so for now we keep things simple
@@ -118,63 +118,56 @@ do { \
struct int_list;
-extern void dump_sbitmap PARAMS ((FILE *, sbitmap));
-extern void dump_sbitmap_file PARAMS ((FILE *, sbitmap));
-extern void dump_sbitmap_vector PARAMS ((FILE *, const char *,
- const char *, sbitmap *,
- int));
-extern sbitmap sbitmap_alloc PARAMS ((unsigned int));
-extern sbitmap *sbitmap_vector_alloc PARAMS ((unsigned int, unsigned int));
-extern sbitmap sbitmap_resize PARAMS ((sbitmap, unsigned int, int));
-extern void sbitmap_copy PARAMS ((sbitmap, sbitmap));
-extern int sbitmap_equal PARAMS ((sbitmap, sbitmap));
-extern void sbitmap_zero PARAMS ((sbitmap));
-extern void sbitmap_ones PARAMS ((sbitmap));
-extern void sbitmap_vector_zero PARAMS ((sbitmap *, unsigned int));
-extern void sbitmap_vector_ones PARAMS ((sbitmap *, unsigned int));
-
-extern void sbitmap_union_of_diff PARAMS ((sbitmap, sbitmap, sbitmap,
- sbitmap));
-extern bool sbitmap_union_of_diff_cg PARAMS ((sbitmap, sbitmap, sbitmap,
- sbitmap));
-extern void sbitmap_difference PARAMS ((sbitmap, sbitmap, sbitmap));
-extern void sbitmap_not PARAMS ((sbitmap, sbitmap));
-extern void sbitmap_a_or_b_and_c PARAMS ((sbitmap, sbitmap, sbitmap,
- sbitmap));
-extern bool sbitmap_a_or_b_and_c_cg PARAMS ((sbitmap, sbitmap, sbitmap,
- sbitmap));
-extern void sbitmap_a_and_b_or_c PARAMS ((sbitmap, sbitmap, sbitmap,
- sbitmap));
-extern bool sbitmap_a_and_b_or_c_cg PARAMS ((sbitmap, sbitmap, sbitmap,
- sbitmap));
-extern void sbitmap_a_and_b PARAMS ((sbitmap, sbitmap, sbitmap));
-extern bool sbitmap_a_and_b_cg PARAMS ((sbitmap, sbitmap, sbitmap));
-extern void sbitmap_a_or_b PARAMS ((sbitmap, sbitmap, sbitmap));
-extern bool sbitmap_a_or_b_cg PARAMS ((sbitmap, sbitmap, sbitmap));
-extern void sbitmap_a_xor_b PARAMS ((sbitmap, sbitmap, sbitmap));
-extern bool sbitmap_a_xor_b_cg PARAMS ((sbitmap, sbitmap, sbitmap));
-extern bool sbitmap_a_subset_b_p PARAMS ((sbitmap, sbitmap));
-
-extern int sbitmap_first_set_bit PARAMS ((sbitmap));
-extern int sbitmap_last_set_bit PARAMS ((sbitmap));
-
-extern void sbitmap_intersect_of_predsucc PARAMS ((sbitmap, sbitmap *,
- int, struct int_list **));
+extern void dump_sbitmap (FILE *, sbitmap);
+extern void dump_sbitmap_file (FILE *, sbitmap);
+extern void dump_sbitmap_vector (FILE *, const char *, const char *, sbitmap *,
+ int);
+extern sbitmap sbitmap_alloc (unsigned int);
+extern sbitmap *sbitmap_vector_alloc (unsigned int, unsigned int);
+extern sbitmap sbitmap_resize (sbitmap, unsigned int, int);
+extern void sbitmap_copy (sbitmap, sbitmap);
+extern int sbitmap_equal (sbitmap, sbitmap);
+extern void sbitmap_zero (sbitmap);
+extern void sbitmap_ones (sbitmap);
+extern void sbitmap_vector_zero (sbitmap *, unsigned int);
+extern void sbitmap_vector_ones (sbitmap *, unsigned int);
+
+extern void sbitmap_union_of_diff (sbitmap, sbitmap, sbitmap, sbitmap);
+extern bool sbitmap_union_of_diff_cg (sbitmap, sbitmap, sbitmap, sbitmap);
+extern void sbitmap_difference (sbitmap, sbitmap, sbitmap);
+extern void sbitmap_not (sbitmap, sbitmap);
+extern void sbitmap_a_or_b_and_c (sbitmap, sbitmap, sbitmap, sbitmap);
+extern bool sbitmap_a_or_b_and_c_cg (sbitmap, sbitmap, sbitmap, sbitmap);
+extern void sbitmap_a_and_b_or_c (sbitmap, sbitmap, sbitmap, sbitmap);
+extern bool sbitmap_a_and_b_or_c_cg (sbitmap, sbitmap, sbitmap, sbitmap);
+extern void sbitmap_a_and_b (sbitmap, sbitmap, sbitmap);
+extern bool sbitmap_a_and_b_cg (sbitmap, sbitmap, sbitmap);
+extern void sbitmap_a_or_b (sbitmap, sbitmap, sbitmap);
+extern bool sbitmap_a_or_b_cg (sbitmap, sbitmap, sbitmap);
+extern void sbitmap_a_xor_b (sbitmap, sbitmap, sbitmap);
+extern bool sbitmap_a_xor_b_cg (sbitmap, sbitmap, sbitmap);
+extern bool sbitmap_a_subset_b_p (sbitmap, sbitmap);
+
+extern int sbitmap_first_set_bit (sbitmap);
+extern int sbitmap_last_set_bit (sbitmap);
+
+extern void sbitmap_intersect_of_predsucc (sbitmap, sbitmap *, int,
+ struct int_list **);
#define sbitmap_intersect_of_predecessors sbitmap_intersect_of_predsucc
#define sbitmap_intersect_of_successors sbitmap_intersect_of_predsucc
-extern void sbitmap_union_of_predsucc PARAMS ((sbitmap, sbitmap *, int,
- struct int_list **));
+extern void sbitmap_union_of_predsucc (sbitmap, sbitmap *, int,
+ struct int_list **);
#define sbitmap_union_of_predecessors sbitmap_union_of_predsucc
#define sbitmap_union_of_successors sbitmap_union_of_predsucc
-/* Intersection and Union of preds/succs using the new flow graph
+/* Intersection and Union of preds/succs using the new flow graph
structure instead of the pred/succ arrays. */
-extern void sbitmap_intersection_of_succs PARAMS ((sbitmap, sbitmap *, int));
-extern void sbitmap_intersection_of_preds PARAMS ((sbitmap, sbitmap *, int));
-extern void sbitmap_union_of_succs PARAMS ((sbitmap, sbitmap *, int));
-extern void sbitmap_union_of_preds PARAMS ((sbitmap, sbitmap *, int));
+extern void sbitmap_intersection_of_succs (sbitmap, sbitmap *, int);
+extern void sbitmap_intersection_of_preds (sbitmap, sbitmap *, int);
+extern void sbitmap_union_of_succs (sbitmap, sbitmap *, int);
+extern void sbitmap_union_of_preds (sbitmap, sbitmap *, int);
-extern void debug_sbitmap PARAMS ((sbitmap));
+extern void debug_sbitmap (sbitmap);
#endif /* ! GCC_SBITMAP_H */
diff --git a/contrib/gcc/scan-decls.c b/contrib/gcc/scan-decls.c
index 4f99319cc70e..ebd69cb05c11 100644
--- a/contrib/gcc/scan-decls.c
+++ b/contrib/gcc/scan-decls.c
@@ -1,6 +1,6 @@
/* scan-decls.c - Extracts declarations from cpp output.
Copyright (C) 1993, 1995, 1997, 1998,
- 1999, 2000 Free Software Foundation, Inc.
+ 1999, 2000, 2003 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
@@ -18,13 +18,15 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Written by Per Bothner <bothner@cygnus.com>, July 1993. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "cpplib.h"
#include "scan.h"
-static void skip_to_closing_brace PARAMS ((cpp_reader *));
-static const cpp_token *get_a_token PARAMS ((cpp_reader *));
+static void skip_to_closing_brace (cpp_reader *);
+static const cpp_token *get_a_token (cpp_reader *);
int brace_nesting = 0;
@@ -43,8 +45,7 @@ int current_extern_C = 0;
/* Get a token but skip padding. */
static const cpp_token *
-get_a_token (pfile)
- cpp_reader *pfile;
+get_a_token (cpp_reader *pfile)
{
for (;;)
{
@@ -55,8 +56,7 @@ get_a_token (pfile)
}
static void
-skip_to_closing_brace (pfile)
- cpp_reader *pfile;
+skip_to_closing_brace (cpp_reader *pfile)
{
int nesting = 1;
for (;;)
@@ -95,10 +95,8 @@ Here dname is the actual name being declared.
*/
int
-scan_decls (pfile, argc, argv)
- cpp_reader *pfile;
- int argc ATTRIBUTE_UNUSED;
- char **argv ATTRIBUTE_UNUSED;
+scan_decls (cpp_reader *pfile, int argc ATTRIBUTE_UNUSED,
+ char **argv ATTRIBUTE_UNUSED)
{
int saw_extern, saw_inline;
cpp_token prev_id;
diff --git a/contrib/gcc/scan.c b/contrib/gcc/scan.c
index ac6b809799f7..f32606107979 100644
--- a/contrib/gcc/scan.c
+++ b/contrib/gcc/scan.c
@@ -1,5 +1,5 @@
/* Utility functions for scan-decls and fix-header programs.
- Copyright (C) 1993, 1994, 1998, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1998, 2002, 2003 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
@@ -15,8 +15,10 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#include "hconfig.h"
+#include "bconfig.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "scan.h"
int lineno = 1;
@@ -24,9 +26,7 @@ int source_lineno = 1;
sstring source_filename;
void
-make_sstring_space (str, count)
- sstring *str;
- int count;
+make_sstring_space (sstring *str, int count)
{
int cur_pos = str->ptr - str->base;
int cur_size = str->limit - str->base;
@@ -41,9 +41,7 @@ make_sstring_space (str, count)
}
void
-sstring_append (dst, src)
- sstring *dst;
- sstring *src;
+sstring_append (sstring *dst, sstring *src)
{
char *d, *s;
int count = SSTRING_LENGTH (src);
@@ -57,10 +55,7 @@ sstring_append (dst, src)
}
int
-scan_ident (fp, s, c)
- FILE *fp;
- sstring *s;
- int c;
+scan_ident (FILE *fp, sstring *s, int c)
{
s->ptr = s->base;
if (ISIDST (c))
@@ -79,10 +74,7 @@ scan_ident (fp, s, c)
}
int
-scan_string (fp, s, init)
- FILE *fp;
- sstring *s;
- int init;
+scan_string (FILE *fp, sstring *s, int init)
{
int c;
@@ -114,9 +106,7 @@ scan_string (fp, s, init)
/* Skip horizontal white spaces (spaces, tabs, and C-style comments). */
int
-skip_spaces (fp, c)
- FILE *fp;
- int c;
+skip_spaces (FILE *fp, int c)
{
for (;;)
{
@@ -152,10 +142,7 @@ skip_spaces (fp, c)
}
int
-read_upto (fp, str, delim)
- FILE *fp;
- sstring *str;
- int delim;
+read_upto (FILE *fp, sstring *str, int delim)
{
int ch;
@@ -172,9 +159,7 @@ read_upto (fp, str, delim)
}
int
-get_token (fp, s)
- FILE *fp;
- sstring *s;
+get_token (FILE *fp, sstring *s)
{
int c;
@@ -242,9 +227,7 @@ get_token (fp, s)
}
unsigned int
-hashstr (str, len)
- const char *str;
- unsigned int len;
+hashstr (const char *str, unsigned int len)
{
unsigned int n = len;
unsigned int r = 0;
diff --git a/contrib/gcc/scan.h b/contrib/gcc/scan.h
index 8b74f8e1246e..7062cdaf90ed 100644
--- a/contrib/gcc/scan.h
+++ b/contrib/gcc/scan.h
@@ -1,5 +1,5 @@
/* scan.h - Utility declarations for scan-decls and fix-header programs.
- Copyright (C) 1993, 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1998, 1999, 2003 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
@@ -33,14 +33,6 @@ typedef struct sstring
#define MAKE_SSTRING_SPACE(STR, COUNT) \
if ((STR)->limit - (STR)->ptr < (COUNT)) make_sstring_space (STR, COUNT);
-#ifndef _PARAMS
-#if defined(ANSI_PROTOTYPES) || defined(__cplusplus)
-#define _PARAMS(args) args
-#else
-#define _PARAMS(args) ()
-#endif
-#endif
-
struct partial_proto;
struct fn_decl
{
@@ -52,28 +44,26 @@ struct fn_decl
struct cpp_token;
-extern int lineno;
-extern void sstring_append _PARAMS((sstring *, sstring *));
-extern void make_sstring_space _PARAMS((sstring *, int));
-extern int skip_spaces _PARAMS((FILE *, int));
-extern int scan_ident _PARAMS((FILE *, sstring *, int));
-extern int scan_string _PARAMS((FILE *, sstring *, int));
-extern int read_upto _PARAMS((FILE *, sstring *, int));
-extern unsigned long hash _PARAMS((const char *));
-extern void recognized_function _PARAMS((const struct cpp_token *,
- unsigned int, int, int));
-extern void recognized_extern _PARAMS((const struct cpp_token *));
-extern unsigned int hashstr _PARAMS((const char *, unsigned int));
+extern void sstring_append (sstring *, sstring *);
+extern void make_sstring_space (sstring *, int);
+extern int skip_spaces (FILE *, int);
+extern int scan_ident (FILE *, sstring *, int);
+extern int scan_string (FILE *, sstring *, int);
+extern int read_upto (FILE *, sstring *, int);
+extern unsigned long hash (const char *);
+extern void recognized_function (const struct cpp_token *,
+ unsigned int, int, int);
+extern void recognized_extern (const struct cpp_token *);
+extern unsigned int hashstr (const char *, unsigned int);
-struct cpp_reader;
-extern int scan_decls _PARAMS((struct cpp_reader *, int, char **));
+extern int scan_decls (struct cpp_reader *, int, char **);
/* get_token is a simple C lexer. */
#define IDENTIFIER_TOKEN 300
#define CHAR_TOKEN 301
#define STRING_TOKEN 302
#define INT_TOKEN 303
-extern int get_token _PARAMS ((FILE *, sstring *));
+extern int get_token (FILE *, sstring *);
/* Current file and line numer, taking #-directives into account */
extern int source_lineno;
diff --git a/contrib/gcc/sched-deps.c b/contrib/gcc/sched-deps.c
index e261608cdfc5..0549e118fe1f 100644
--- a/contrib/gcc/sched-deps.c
+++ b/contrib/gcc/sched-deps.c
@@ -1,7 +1,7 @@
/* Instruction scheduling pass. This file computes dependencies between
instructions.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com)
@@ -24,6 +24,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "tm_p.h"
@@ -40,9 +42,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "sched-int.h"
#include "params.h"
#include "cselib.h"
+#include "df.h"
-extern char *reg_known_equiv_p;
-extern rtx *reg_known_value;
static regset_head reg_pending_sets_head;
static regset_head reg_pending_clobbers_head;
@@ -51,7 +52,18 @@ static regset_head reg_pending_uses_head;
static regset reg_pending_sets;
static regset reg_pending_clobbers;
static regset reg_pending_uses;
-static bool reg_pending_barrier;
+
+/* The following enumeration values tell us what dependencies we
+ should use to implement the barrier. We use true-dependencies for
+ TRUE_BARRIER and anti-dependencies for MOVE_BARRIER. */
+enum reg_pending_barrier_mode
+{
+ NOT_A_BARRIER = 0,
+ MOVE_BARRIER,
+ TRUE_BARRIER
+};
+
+static enum reg_pending_barrier_mode reg_pending_barrier;
/* To speed up the test for duplicate dependency links we keep a
record of dependencies created by add_dependence when the average
@@ -66,45 +78,45 @@ static bool reg_pending_barrier;
has enough entries to represent a dependency on any other insn in
the insn chain. All bitmap for true dependencies cache is
allocated then the rest two ones are also allocated. */
-static sbitmap *true_dependency_cache;
-static sbitmap *anti_dependency_cache;
-static sbitmap *output_dependency_cache;
+static bitmap_head *true_dependency_cache;
+static bitmap_head *anti_dependency_cache;
+static bitmap_head *output_dependency_cache;
+int cache_size;
/* To speed up checking consistency of formed forward insn
dependencies we use the following cache. Another possible solution
could be switching off checking duplication of insns in forward
dependencies. */
#ifdef ENABLE_CHECKING
-static sbitmap *forward_dependency_cache;
+static bitmap_head *forward_dependency_cache;
#endif
-static int deps_may_trap_p PARAMS ((rtx));
-static void add_dependence_list PARAMS ((rtx, rtx, enum reg_note));
-static void add_dependence_list_and_free PARAMS ((rtx, rtx *, enum reg_note));
-static void remove_dependence PARAMS ((rtx, rtx));
-static void set_sched_group_p PARAMS ((rtx));
+static int deps_may_trap_p (rtx);
+static void add_dependence_list (rtx, rtx, enum reg_note);
+static void add_dependence_list_and_free (rtx, rtx *, enum reg_note);
+static void set_sched_group_p (rtx);
-static void flush_pending_lists PARAMS ((struct deps *, rtx, int, int));
-static void sched_analyze_1 PARAMS ((struct deps *, rtx, rtx));
-static void sched_analyze_2 PARAMS ((struct deps *, rtx, rtx));
-static void sched_analyze_insn PARAMS ((struct deps *, rtx, rtx, rtx));
-static rtx group_leader PARAMS ((rtx));
+static void flush_pending_lists (struct deps *, rtx, int, int);
+static void sched_analyze_1 (struct deps *, rtx, rtx);
+static void sched_analyze_2 (struct deps *, rtx, rtx);
+static void sched_analyze_insn (struct deps *, rtx, rtx, rtx);
-static rtx get_condition PARAMS ((rtx));
-static int conditions_mutex_p PARAMS ((rtx, rtx));
+static rtx get_condition (rtx);
+static int conditions_mutex_p (rtx, rtx);
/* Return nonzero if a load of the memory reference MEM can cause a trap. */
static int
-deps_may_trap_p (mem)
- rtx mem;
+deps_may_trap_p (rtx mem)
{
rtx addr = XEXP (mem, 0);
- if (REG_P (addr)
- && REGNO (addr) >= FIRST_PSEUDO_REGISTER
- && reg_known_value[REGNO (addr)])
- addr = reg_known_value[REGNO (addr)];
+ if (REG_P (addr) && REGNO (addr) >= FIRST_PSEUDO_REGISTER)
+ {
+ rtx t = get_reg_known_value (REGNO (addr));
+ if (t)
+ addr = t;
+ }
return rtx_addr_can_trap_p (addr);
}
@@ -112,9 +124,7 @@ deps_may_trap_p (mem)
if LIST does not contain INSN. */
rtx
-find_insn_list (insn, list)
- rtx insn;
- rtx list;
+find_insn_list (rtx insn, rtx list)
{
while (list)
{
@@ -128,8 +138,7 @@ find_insn_list (insn, list)
/* Find the condition under which INSN is executed. */
static rtx
-get_condition (insn)
- rtx insn;
+get_condition (rtx insn)
{
rtx pat = PATTERN (insn);
rtx cond;
@@ -160,8 +169,7 @@ get_condition (insn)
/* Return nonzero if conditions COND1 and COND2 can never be both true. */
static int
-conditions_mutex_p (cond1, cond2)
- rtx cond1, cond2;
+conditions_mutex_p (rtx cond1, rtx cond2)
{
if (GET_RTX_CLASS (GET_CODE (cond1)) == '<'
&& GET_RTX_CLASS (GET_CODE (cond2)) == '<'
@@ -173,28 +181,26 @@ conditions_mutex_p (cond1, cond2)
}
/* Add ELEM wrapped in an INSN_LIST with reg note kind DEP_TYPE to the
- LOG_LINKS of INSN, if not already there. DEP_TYPE indicates the type
- of dependence that this link represents. */
+ LOG_LINKS of INSN, if not already there. DEP_TYPE indicates the
+ type of dependence that this link represents. The function returns
+ nonzero if a new entry has been added to insn's LOG_LINK. */
-void
-add_dependence (insn, elem, dep_type)
- rtx insn;
- rtx elem;
- enum reg_note dep_type;
+int
+add_dependence (rtx insn, rtx elem, enum reg_note dep_type)
{
- rtx link, next;
+ rtx link;
int present_p;
rtx cond1, cond2;
/* Don't depend an insn on itself. */
if (insn == elem)
- return;
+ return 0;
/* We can get a dependency on deleted insns due to optimizations in
the register allocation and reloading or due to splitting. Any
such dependency is useless and can be ignored. */
if (GET_CODE (elem) == NOTE)
- return;
+ return 0;
/* flow.c doesn't handle conditional lifetimes entirely correctly;
calls mess up the conditional lifetimes. */
@@ -213,38 +219,7 @@ add_dependence (insn, elem, dep_type)
/* Make sure second instruction doesn't affect condition of first
instruction if switched. */
&& !modified_in_p (cond2, insn))
- return;
- }
-
- /* If elem is part of a sequence that must be scheduled together, then
- make the dependence point to the last insn of the sequence.
- When HAVE_cc0, it is possible for NOTEs to exist between users and
- setters of the condition codes, so we must skip past notes here.
- Otherwise, NOTEs are impossible here. */
- next = next_nonnote_insn (elem);
- if (next && INSN_P (next) && SCHED_GROUP_P (next))
- {
- /* Notes will never intervene here though, so don't bother checking
- for them. */
- /* Hah! Wrong. */
- /* We must reject CODE_LABELs, so that we don't get confused by one
- that has LABEL_PRESERVE_P set, which is represented by the same
- bit in the rtl as SCHED_GROUP_P. A CODE_LABEL can never be
- SCHED_GROUP_P. */
-
- rtx nnext;
- while ((nnext = next_nonnote_insn (next)) != NULL
- && INSN_P (nnext)
- && SCHED_GROUP_P (nnext))
- next = nnext;
-
- /* Again, don't depend an insn on itself. */
- if (insn == next)
- return;
-
- /* Make the dependence to NEXT, the last insn of the group, instead
- of the original ELEM. */
- elem = next;
+ return 0;
}
present_p = 1;
@@ -258,7 +233,7 @@ add_dependence (insn, elem, dep_type)
elem is a CALL is still required. */
if (GET_CODE (insn) == CALL_INSN
&& (INSN_BB (elem) != INSN_BB (insn)))
- return;
+ return 0;
#endif
/* If we already have a dependency for ELEM, then we do not need to
@@ -270,19 +245,20 @@ add_dependence (insn, elem, dep_type)
if (anti_dependency_cache == NULL || output_dependency_cache == NULL)
abort ();
- if (TEST_BIT (true_dependency_cache[INSN_LUID (insn)], INSN_LUID (elem)))
+ if (bitmap_bit_p (&true_dependency_cache[INSN_LUID (insn)],
+ INSN_LUID (elem)))
/* Do nothing (present_set_type is already 0). */
;
- else if (TEST_BIT (anti_dependency_cache[INSN_LUID (insn)],
+ else if (bitmap_bit_p (&anti_dependency_cache[INSN_LUID (insn)],
INSN_LUID (elem)))
present_dep_type = REG_DEP_ANTI;
- else if (TEST_BIT (output_dependency_cache[INSN_LUID (insn)],
+ else if (bitmap_bit_p (&output_dependency_cache[INSN_LUID (insn)],
INSN_LUID (elem)))
present_dep_type = REG_DEP_OUTPUT;
else
present_p = 0;
if (present_p && (int) dep_type >= (int) present_dep_type)
- return;
+ return 0;
}
#endif
@@ -297,12 +273,12 @@ add_dependence (insn, elem, dep_type)
if (true_dependency_cache != NULL)
{
if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
- RESET_BIT (anti_dependency_cache[INSN_LUID (insn)],
- INSN_LUID (elem));
+ bitmap_clear_bit (&anti_dependency_cache[INSN_LUID (insn)],
+ INSN_LUID (elem));
else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT
&& output_dependency_cache)
- RESET_BIT (output_dependency_cache[INSN_LUID (insn)],
- INSN_LUID (elem));
+ bitmap_clear_bit (&output_dependency_cache[INSN_LUID (insn)],
+ INSN_LUID (elem));
else
abort ();
}
@@ -319,18 +295,18 @@ add_dependence (insn, elem, dep_type)
if (true_dependency_cache != NULL)
{
if ((int) REG_NOTE_KIND (link) == 0)
- SET_BIT (true_dependency_cache[INSN_LUID (insn)],
- INSN_LUID (elem));
+ bitmap_set_bit (&true_dependency_cache[INSN_LUID (insn)],
+ INSN_LUID (elem));
else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
- SET_BIT (anti_dependency_cache[INSN_LUID (insn)],
- INSN_LUID (elem));
+ bitmap_set_bit (&anti_dependency_cache[INSN_LUID (insn)],
+ INSN_LUID (elem));
else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
- SET_BIT (output_dependency_cache[INSN_LUID (insn)],
- INSN_LUID (elem));
+ bitmap_set_bit (&output_dependency_cache[INSN_LUID (insn)],
+ INSN_LUID (elem));
}
#endif
- return;
- }
+ return 0;
+ }
/* Might want to check one level of transitivity to save conses. */
link = alloc_INSN_LIST (elem, LOG_LINKS (insn));
@@ -345,21 +321,20 @@ add_dependence (insn, elem, dep_type)
if (true_dependency_cache != NULL)
{
if ((int) dep_type == 0)
- SET_BIT (true_dependency_cache[INSN_LUID (insn)], INSN_LUID (elem));
+ bitmap_set_bit (&true_dependency_cache[INSN_LUID (insn)], INSN_LUID (elem));
else if (dep_type == REG_DEP_ANTI)
- SET_BIT (anti_dependency_cache[INSN_LUID (insn)], INSN_LUID (elem));
+ bitmap_set_bit (&anti_dependency_cache[INSN_LUID (insn)], INSN_LUID (elem));
else if (dep_type == REG_DEP_OUTPUT)
- SET_BIT (output_dependency_cache[INSN_LUID (insn)], INSN_LUID (elem));
+ bitmap_set_bit (&output_dependency_cache[INSN_LUID (insn)], INSN_LUID (elem));
}
#endif
+ return 1;
}
/* A convenience wrapper to operate on an entire list. */
static void
-add_dependence_list (insn, list, dep_type)
- rtx insn, list;
- enum reg_note dep_type;
+add_dependence_list (rtx insn, rtx list, enum reg_note dep_type)
{
for (; list; list = XEXP (list, 1))
add_dependence (insn, XEXP (list, 0), dep_type);
@@ -368,10 +343,7 @@ add_dependence_list (insn, list, dep_type)
/* Similar, but free *LISTP at the same time. */
static void
-add_dependence_list_and_free (insn, listp, dep_type)
- rtx insn;
- rtx *listp;
- enum reg_note dep_type;
+add_dependence_list_and_free (rtx insn, rtx *listp, enum reg_note dep_type)
{
rtx list, next;
for (list = *listp, *listp = NULL; list ; list = next)
@@ -382,102 +354,18 @@ add_dependence_list_and_free (insn, listp, dep_type)
}
}
-/* Remove ELEM wrapped in an INSN_LIST from the LOG_LINKS
- of INSN. Abort if not found. */
-
-static void
-remove_dependence (insn, elem)
- rtx insn;
- rtx elem;
-{
- rtx prev, link, next;
- int found = 0;
-
- for (prev = 0, link = LOG_LINKS (insn); link; link = next)
- {
- next = XEXP (link, 1);
- if (XEXP (link, 0) == elem)
- {
- if (prev)
- XEXP (prev, 1) = next;
- else
- LOG_LINKS (insn) = next;
-
-#ifdef INSN_SCHEDULING
- /* If we are removing a dependency from the LOG_LINKS list,
- make sure to remove it from the cache too. */
- if (true_dependency_cache != NULL)
- {
- if (REG_NOTE_KIND (link) == 0)
- RESET_BIT (true_dependency_cache[INSN_LUID (insn)],
- INSN_LUID (elem));
- else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
- RESET_BIT (anti_dependency_cache[INSN_LUID (insn)],
- INSN_LUID (elem));
- else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
- RESET_BIT (output_dependency_cache[INSN_LUID (insn)],
- INSN_LUID (elem));
- }
-#endif
-
- free_INSN_LIST_node (link);
-
- found = 1;
- }
- else
- prev = link;
- }
-
- if (!found)
- abort ();
- return;
-}
-
-/* Return an insn which represents a SCHED_GROUP, which is
- the last insn in the group. */
-
-static rtx
-group_leader (insn)
- rtx insn;
-{
- rtx prev;
-
- do
- {
- prev = insn;
- insn = next_nonnote_insn (insn);
- }
- while (insn && INSN_P (insn) && SCHED_GROUP_P (insn));
-
- return prev;
-}
-
/* Set SCHED_GROUP_P and care for the rest of the bookkeeping that
goes along with that. */
static void
-set_sched_group_p (insn)
- rtx insn;
+set_sched_group_p (rtx insn)
{
- rtx link, prev;
+ rtx prev;
SCHED_GROUP_P (insn) = 1;
- /* There may be a note before this insn now, but all notes will
- be removed before we actually try to schedule the insns, so
- it won't cause a problem later. We must avoid it here though. */
prev = prev_nonnote_insn (insn);
-
- /* Make a copy of all dependencies on the immediately previous insn,
- and add to this insn. This is so that all the dependencies will
- apply to the group. Remove an explicit dependence on this insn
- as SCHED_GROUP_P now represents it. */
-
- if (find_insn_list (prev, LOG_LINKS (insn)))
- remove_dependence (insn, prev);
-
- for (link = LOG_LINKS (prev); link; link = XEXP (link, 1))
- add_dependence (insn, XEXP (link, 0), REG_NOTE_KIND (link));
+ add_dependence (insn, prev, REG_DEP_ANTI);
}
/* Process an insn's memory dependencies. There are four kinds of
@@ -496,9 +384,8 @@ set_sched_group_p (insn)
so that we can do memory aliasing on it. */
void
-add_insn_mem_dependence (deps, insn_list, mem_list, insn, mem)
- struct deps *deps;
- rtx *insn_list, *mem_list, insn, mem;
+add_insn_mem_dependence (struct deps *deps, rtx *insn_list, rtx *mem_list,
+ rtx insn, rtx mem)
{
rtx link;
@@ -510,7 +397,7 @@ add_insn_mem_dependence (deps, insn_list, mem_list, insn, mem)
mem = shallow_copy_rtx (mem);
XEXP (mem, 0) = cselib_subst_to_values (XEXP (mem, 0));
}
- link = alloc_EXPR_LIST (VOIDmode, mem, *mem_list);
+ link = alloc_EXPR_LIST (VOIDmode, canon_rtx (mem), *mem_list);
*mem_list = link;
deps->pending_lists_length++;
@@ -521,10 +408,8 @@ add_insn_mem_dependence (deps, insn_list, mem_list, insn, mem)
dependencies for a read operation, similarly with FOR_WRITE. */
static void
-flush_pending_lists (deps, insn, for_read, for_write)
- struct deps *deps;
- rtx insn;
- int for_read, for_write;
+flush_pending_lists (struct deps *deps, rtx insn, int for_read,
+ int for_write)
{
if (for_write)
{
@@ -549,10 +434,7 @@ flush_pending_lists (deps, insn, for_read, for_write)
destination of X, and reads of everything mentioned. */
static void
-sched_analyze_1 (deps, x, insn)
- struct deps *deps;
- rtx x;
- rtx insn;
+sched_analyze_1 (struct deps *deps, rtx x, rtx insn)
{
int regno;
rtx dest = XEXP (x, 0);
@@ -580,6 +462,19 @@ sched_analyze_1 (deps, x, insn)
while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT)
{
+ if (GET_CODE (dest) == STRICT_LOW_PART
+ || GET_CODE (dest) == ZERO_EXTRACT
+ || GET_CODE (dest) == SIGN_EXTRACT
+ || read_modify_subreg_p (dest))
+ {
+ /* These both read and modify the result. We must handle
+ them as writes to get proper dependencies for following
+ instructions. We must handle them as reads to get proper
+ dependencies from this to previous instructions.
+ Thus we need to call sched_analyze_2. */
+
+ sched_analyze_2 (deps, XEXP (dest, 0), insn);
+ }
if (GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT)
{
/* The second and third arguments are values read by this insn. */
@@ -628,10 +523,12 @@ sched_analyze_1 (deps, x, insn)
/* Pseudos that are REG_EQUIV to something may be replaced
by that during reloading. We need only add dependencies for
the address in the REG_EQUIV note. */
- if (!reload_completed
- && reg_known_equiv_p[regno]
- && GET_CODE (reg_known_value[regno]) == MEM)
- sched_analyze_2 (deps, XEXP (reg_known_value[regno], 0), insn);
+ if (!reload_completed && get_reg_known_equiv_p (regno))
+ {
+ rtx t = get_reg_known_value (regno);
+ if (GET_CODE (t) == MEM)
+ sched_analyze_2 (deps, XEXP (t, 0), insn);
+ }
/* Don't let it cross a call after scheduling if it doesn't
already cross one. */
@@ -650,6 +547,7 @@ sched_analyze_1 (deps, x, insn)
cselib_lookup (XEXP (t, 0), Pmode, 1);
XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0));
}
+ t = canon_rtx (t);
if (deps->pending_lists_length > MAX_PENDING_LIST_LENGTH)
{
@@ -703,10 +601,7 @@ sched_analyze_1 (deps, x, insn)
/* Analyze the uses of memory and registers in rtx X in INSN. */
static void
-sched_analyze_2 (deps, x, insn)
- struct deps *deps;
- rtx x;
- rtx insn;
+sched_analyze_2 (struct deps *deps, rtx x, rtx insn)
{
int i;
int j;
@@ -735,6 +630,9 @@ sched_analyze_2 (deps, x, insn)
case CC0:
/* User of CC0 depends on immediately preceding insn. */
set_sched_group_p (insn);
+ /* Don't move CC0 setter to another block (it can set up the
+ same flag for previous CC0 users which is safe). */
+ CANT_MOVE (prev_nonnote_insn (insn)) = 1;
return;
#endif
@@ -763,10 +661,12 @@ sched_analyze_2 (deps, x, insn)
/* Pseudos that are REG_EQUIV to something may be replaced
by that during reloading. We need only add dependencies for
the address in the REG_EQUIV note. */
- if (!reload_completed
- && reg_known_equiv_p[regno]
- && GET_CODE (reg_known_value[regno]) == MEM)
- sched_analyze_2 (deps, XEXP (reg_known_value[regno], 0), insn);
+ if (!reload_completed && get_reg_known_equiv_p (regno))
+ {
+ rtx t = get_reg_known_value (regno);
+ if (GET_CODE (t) == MEM)
+ sched_analyze_2 (deps, XEXP (t, 0), insn);
+ }
/* If the register does not already cross any calls, then add this
insn to the sched_before_next_call list so that it will still
@@ -791,6 +691,7 @@ sched_analyze_2 (deps, x, insn)
cselib_lookup (XEXP (t, 0), Pmode, 1);
XEXP (t, 0) = cselib_subst_to_values (XEXP (t, 0));
}
+ t = canon_rtx (t);
pending = deps->pending_read_insns;
pending_mem = deps->pending_read_mems;
while (pending)
@@ -846,7 +747,7 @@ sched_analyze_2 (deps, x, insn)
mode. An insn should not be moved across this even if it only uses
pseudo-regs because it might give an incorrectly rounded result. */
if (code != ASM_OPERANDS || MEM_VOLATILE_P (x))
- reg_pending_barrier = true;
+ reg_pending_barrier = TRUE_BARRIER;
/* For all ASM_OPERANDS, we must traverse the vector of input operands.
We can not just fall through here since then we would be confused
@@ -903,10 +804,7 @@ sched_analyze_2 (deps, x, insn)
/* Analyze an INSN with pattern X to find all dependencies. */
static void
-sched_analyze_insn (deps, x, insn, loop_notes)
- struct deps *deps;
- rtx x, insn;
- rtx loop_notes;
+sched_analyze_insn (struct deps *deps, rtx x, rtx insn, rtx loop_notes)
{
RTX_CODE code = GET_CODE (x);
rtx link;
@@ -965,7 +863,7 @@ sched_analyze_insn (deps, x, insn, loop_notes)
sched_analyze_2 (deps, XEXP (link, 0), insn);
}
if (find_reg_note (insn, REG_SETJMP, NULL))
- reg_pending_barrier = true;
+ reg_pending_barrier = MOVE_BARRIER;
}
if (GET_CODE (insn) == JUMP_INSN)
@@ -973,7 +871,7 @@ sched_analyze_insn (deps, x, insn, loop_notes)
rtx next;
next = next_nonnote_insn (insn);
if (next && GET_CODE (next) == BARRIER)
- reg_pending_barrier = true;
+ reg_pending_barrier = TRUE_BARRIER;
else
{
rtx pending, pending_mem;
@@ -983,7 +881,15 @@ sched_analyze_insn (deps, x, insn, loop_notes)
(*current_sched_info->compute_jump_reg_dependencies)
(insn, &deps->reg_conditional_sets, &tmp_uses, &tmp_sets);
- IOR_REG_SET (reg_pending_uses, &tmp_uses);
+ /* Make latency of jump equal to 0 by using anti-dependence. */
+ EXECUTE_IF_SET_IN_REG_SET (&tmp_uses, 0, i,
+ {
+ struct deps_reg *reg_last = &deps->reg_last[i];
+ add_dependence_list (insn, reg_last->sets, REG_DEP_ANTI);
+ add_dependence_list (insn, reg_last->clobbers, REG_DEP_ANTI);
+ reg_last->uses_length++;
+ reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
+ });
IOR_REG_SET (reg_pending_sets, &tmp_sets);
CLEAR_REG_SET (&tmp_uses);
@@ -1035,7 +941,7 @@ sched_analyze_insn (deps, x, insn, loop_notes)
|| INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_END
|| INTVAL (XEXP (link, 0)) == NOTE_INSN_EH_REGION_BEG
|| INTVAL (XEXP (link, 0)) == NOTE_INSN_EH_REGION_END)
- reg_pending_barrier = true;
+ reg_pending_barrier = MOVE_BARRIER;
link = XEXP (link, 1);
}
@@ -1047,19 +953,25 @@ sched_analyze_insn (deps, x, insn, loop_notes)
where block boundaries fall. This is mighty confusing elsewhere.
Therefore, prevent such an instruction from being moved. */
if (can_throw_internal (insn))
- reg_pending_barrier = true;
+ reg_pending_barrier = MOVE_BARRIER;
/* Add dependencies if a scheduling barrier was found. */
if (reg_pending_barrier)
{
+ /* In the case of barrier the most added dependencies are not
+ real, so we use anti-dependence here. */
if (GET_CODE (PATTERN (insn)) == COND_EXEC)
{
EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i,
{
struct deps_reg *reg_last = &deps->reg_last[i];
add_dependence_list (insn, reg_last->uses, REG_DEP_ANTI);
- add_dependence_list (insn, reg_last->sets, 0);
- add_dependence_list (insn, reg_last->clobbers, 0);
+ add_dependence_list
+ (insn, reg_last->sets,
+ reg_pending_barrier == TRUE_BARRIER ? 0 : REG_DEP_ANTI);
+ add_dependence_list
+ (insn, reg_last->clobbers,
+ reg_pending_barrier == TRUE_BARRIER ? 0 : REG_DEP_ANTI);
});
}
else
@@ -1069,8 +981,12 @@ sched_analyze_insn (deps, x, insn, loop_notes)
struct deps_reg *reg_last = &deps->reg_last[i];
add_dependence_list_and_free (insn, &reg_last->uses,
REG_DEP_ANTI);
- add_dependence_list_and_free (insn, &reg_last->sets, 0);
- add_dependence_list_and_free (insn, &reg_last->clobbers, 0);
+ add_dependence_list_and_free
+ (insn, &reg_last->sets,
+ reg_pending_barrier == TRUE_BARRIER ? 0 : REG_DEP_ANTI);
+ add_dependence_list_and_free
+ (insn, &reg_last->clobbers,
+ reg_pending_barrier == TRUE_BARRIER ? 0 : REG_DEP_ANTI);
reg_last->uses_length = 0;
reg_last->clobbers_length = 0;
});
@@ -1085,7 +1001,7 @@ sched_analyze_insn (deps, x, insn, loop_notes)
flush_pending_lists (deps, insn, true, true);
CLEAR_REG_SET (&deps->reg_conditional_sets);
- reg_pending_barrier = false;
+ reg_pending_barrier = NOT_A_BARRIER;
}
else
{
@@ -1238,9 +1154,7 @@ sched_analyze_insn (deps, x, insn, loop_notes)
for every dependency. */
void
-sched_analyze (deps, head, tail)
- struct deps *deps;
- rtx head, tail;
+sched_analyze (struct deps *deps, rtx head, rtx tail)
{
rtx insn;
rtx loop_notes = 0;
@@ -1284,7 +1198,7 @@ sched_analyze (deps, head, tail)
{
/* This is setjmp. Assume that all registers, not just
hard registers, may be clobbered by this call. */
- reg_pending_barrier = true;
+ reg_pending_barrier = MOVE_BARRIER;
}
else
{
@@ -1373,7 +1287,7 @@ sched_analyze (deps, head, tail)
/* Now that we have completed handling INSN, check and see if it is
a CLOBBER beginning a libcall block. If it is, record the
- end of the libcall sequence.
+ end of the libcall sequence.
We want to schedule libcall blocks as a unit before reload. While
this restricts scheduling, it preserves the meaning of a libcall
@@ -1384,7 +1298,7 @@ sched_analyze (deps, head, tail)
a libcall block. */
if (!reload_completed
/* Note we may have nested libcall sequences. We only care about
- the outermost libcall sequence. */
+ the outermost libcall sequence. */
&& deps->libcall_block_tail_insn == 0
/* The sequence must start with a clobber of a register. */
&& GET_CODE (insn) == INSN
@@ -1420,17 +1334,52 @@ sched_analyze (deps, head, tail)
abort ();
}
+
+/* The following function adds forward dependence (FROM, TO) with
+ given DEP_TYPE. The forward dependence should be not exist before. */
+
+void
+add_forward_dependence (rtx from, rtx to, enum reg_note dep_type)
+{
+ rtx new_link;
+
+#ifdef ENABLE_CHECKING
+ /* If add_dependence is working properly there should never
+ be notes, deleted insns or duplicates in the backward
+ links. Thus we need not check for them here.
+
+ However, if we have enabled checking we might as well go
+ ahead and verify that add_dependence worked properly. */
+ if (GET_CODE (from) == NOTE
+ || INSN_DELETED_P (from)
+ || (forward_dependency_cache != NULL
+ && bitmap_bit_p (&forward_dependency_cache[INSN_LUID (from)],
+ INSN_LUID (to)))
+ || (forward_dependency_cache == NULL
+ && find_insn_list (to, INSN_DEPEND (from))))
+ abort ();
+ if (forward_dependency_cache != NULL)
+ bitmap_bit_p (&forward_dependency_cache[INSN_LUID (from)],
+ INSN_LUID (to));
+#endif
+
+ new_link = alloc_INSN_LIST (to, INSN_DEPEND (from));
+
+ PUT_REG_NOTE_KIND (new_link, dep_type);
+
+ INSN_DEPEND (from) = new_link;
+ INSN_DEP_COUNT (to) += 1;
+}
+
/* Examine insns in the range [ HEAD, TAIL ] and Use the backward
dependences from LOG_LINKS to build forward dependences in
INSN_DEPEND. */
void
-compute_forward_dependences (head, tail)
- rtx head, tail;
+compute_forward_dependences (rtx head, rtx tail)
{
rtx insn, link;
rtx next_tail;
- enum reg_note dep_type;
next_tail = NEXT_INSN (tail);
for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
@@ -1438,44 +1387,8 @@ compute_forward_dependences (head, tail)
if (! INSN_P (insn))
continue;
- insn = group_leader (insn);
-
for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
- {
- rtx x = group_leader (XEXP (link, 0));
- rtx new_link;
-
- if (x != XEXP (link, 0))
- continue;
-
-#ifdef ENABLE_CHECKING
- /* If add_dependence is working properly there should never
- be notes, deleted insns or duplicates in the backward
- links. Thus we need not check for them here.
-
- However, if we have enabled checking we might as well go
- ahead and verify that add_dependence worked properly. */
- if (GET_CODE (x) == NOTE
- || INSN_DELETED_P (x)
- || (forward_dependency_cache != NULL
- && TEST_BIT (forward_dependency_cache[INSN_LUID (x)],
- INSN_LUID (insn)))
- || (forward_dependency_cache == NULL
- && find_insn_list (insn, INSN_DEPEND (x))))
- abort ();
- if (forward_dependency_cache != NULL)
- SET_BIT (forward_dependency_cache[INSN_LUID (x)],
- INSN_LUID (insn));
-#endif
-
- new_link = alloc_INSN_LIST (insn, INSN_DEPEND (x));
-
- dep_type = REG_NOTE_KIND (link);
- PUT_REG_NOTE_KIND (new_link, dep_type);
-
- INSN_DEPEND (x) = new_link;
- INSN_DEP_COUNT (insn) += 1;
- }
+ add_forward_dependence (XEXP (link, 0), insn, REG_NOTE_KIND (link));
}
}
@@ -1483,14 +1396,12 @@ compute_forward_dependences (head, tail)
n_bbs is the number of region blocks. */
void
-init_deps (deps)
- struct deps *deps;
+init_deps (struct deps *deps)
{
int max_reg = (reload_completed ? FIRST_PSEUDO_REGISTER : max_reg_num ());
deps->max_reg = max_reg;
- deps->reg_last = (struct deps_reg *)
- xcalloc (max_reg, sizeof (struct deps_reg));
+ deps->reg_last = xcalloc (max_reg, sizeof (struct deps_reg));
INIT_REG_SET (&deps->reg_last_in_use);
INIT_REG_SET (&deps->reg_conditional_sets);
@@ -1510,8 +1421,7 @@ init_deps (deps)
/* Free insn lists found in DEPS. */
void
-free_deps (deps)
- struct deps *deps;
+free_deps (struct deps *deps)
{
int i;
@@ -1522,7 +1432,7 @@ free_deps (deps)
free_INSN_LIST_list (&deps->last_pending_memory_flush);
/* Without the EXECUTE_IF_SET, this loop is executed max_reg * nr_regions
- times. For a test case with 42000 regs and 8000 small basic blocks,
+ times. For a testcase with 42000 regs and 8000 small basic blocks,
this loop accounted for nearly 60% (84 sec) of the total -O2 runtime. */
EXECUTE_IF_SET_IN_REG_SET (&deps->reg_last_in_use, 0, i,
{
@@ -1541,12 +1451,11 @@ free_deps (deps)
}
/* If it is profitable to use them, initialize caches for tracking
- dependency informatino. LUID is the number of insns to be scheduled,
+ dependency information. LUID is the number of insns to be scheduled,
it is used in the estimate of profitability. */
void
-init_dependency_caches (luid)
- int luid;
+init_dependency_caches (int luid)
{
/* ?!? We could save some memory by computing a per-region luid mapping
which could reduce both the number of vectors in the cache and the size
@@ -1556,34 +1465,52 @@ init_dependency_caches (luid)
what we consider "very high". */
if (luid / n_basic_blocks > 100 * 5)
{
- true_dependency_cache = sbitmap_vector_alloc (luid, luid);
- sbitmap_vector_zero (true_dependency_cache, luid);
- anti_dependency_cache = sbitmap_vector_alloc (luid, luid);
- sbitmap_vector_zero (anti_dependency_cache, luid);
- output_dependency_cache = sbitmap_vector_alloc (luid, luid);
- sbitmap_vector_zero (output_dependency_cache, luid);
+ int i;
+ true_dependency_cache = xmalloc (luid * sizeof (bitmap_head));
+ anti_dependency_cache = xmalloc (luid * sizeof (bitmap_head));
+ output_dependency_cache = xmalloc (luid * sizeof (bitmap_head));
#ifdef ENABLE_CHECKING
- forward_dependency_cache = sbitmap_vector_alloc (luid, luid);
- sbitmap_vector_zero (forward_dependency_cache, luid);
+ forward_dependency_cache = xmalloc (luid * sizeof (bitmap_head));
#endif
+ for (i = 0; i < luid; i++)
+ {
+ bitmap_initialize (&true_dependency_cache[i], 0);
+ bitmap_initialize (&anti_dependency_cache[i], 0);
+ bitmap_initialize (&output_dependency_cache[i], 0);
+#ifdef ENABLE_CHECKING
+ bitmap_initialize (&forward_dependency_cache[i], 0);
+#endif
+ }
+ cache_size = luid;
}
}
/* Free the caches allocated in init_dependency_caches. */
void
-free_dependency_caches ()
+free_dependency_caches (void)
{
if (true_dependency_cache)
{
- sbitmap_vector_free (true_dependency_cache);
+ int i;
+
+ for (i = 0; i < cache_size; i++)
+ {
+ bitmap_clear (&true_dependency_cache[i]);
+ bitmap_clear (&anti_dependency_cache[i]);
+ bitmap_clear (&output_dependency_cache[i]);
+#ifdef ENABLE_CHECKING
+ bitmap_clear (&forward_dependency_cache[i]);
+#endif
+ }
+ free (true_dependency_cache);
true_dependency_cache = NULL;
- sbitmap_vector_free (anti_dependency_cache);
+ free (anti_dependency_cache);
anti_dependency_cache = NULL;
- sbitmap_vector_free (output_dependency_cache);
+ free (output_dependency_cache);
output_dependency_cache = NULL;
#ifdef ENABLE_CHECKING
- sbitmap_vector_free (forward_dependency_cache);
+ free (forward_dependency_cache);
forward_dependency_cache = NULL;
#endif
}
@@ -1593,18 +1520,18 @@ free_dependency_caches ()
code. */
void
-init_deps_global ()
+init_deps_global (void)
{
reg_pending_sets = INITIALIZE_REG_SET (reg_pending_sets_head);
reg_pending_clobbers = INITIALIZE_REG_SET (reg_pending_clobbers_head);
reg_pending_uses = INITIALIZE_REG_SET (reg_pending_uses_head);
- reg_pending_barrier = false;
+ reg_pending_barrier = NOT_A_BARRIER;
}
/* Free everything used by the dependency analysis code. */
void
-finish_deps_global ()
+finish_deps_global (void)
{
FREE_REG_SET (reg_pending_sets);
FREE_REG_SET (reg_pending_clobbers);
diff --git a/contrib/gcc/sched-ebb.c b/contrib/gcc/sched-ebb.c
index 47dd83faf6fa..c95bb4537e64 100644
--- a/contrib/gcc/sched-ebb.c
+++ b/contrib/gcc/sched-ebb.c
@@ -1,6 +1,6 @@
/* Instruction scheduling pass.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com)
@@ -23,6 +23,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "tm_p.h"
@@ -37,7 +39,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "recog.h"
#include "cfglayout.h"
+#include "params.h"
#include "sched-int.h"
+#include "target.h"
/* The number of insns to be scheduled in total. */
static int target_n_insns;
@@ -45,21 +49,25 @@ static int target_n_insns;
static int sched_n_insns;
/* Implementations of the sched_info functions for region scheduling. */
-static void init_ready_list PARAMS ((struct ready_list *));
-static int can_schedule_ready_p PARAMS ((rtx));
-static int new_ready PARAMS ((rtx));
-static int schedule_more_p PARAMS ((void));
-static const char *ebb_print_insn PARAMS ((rtx, int));
-static int rank PARAMS ((rtx, rtx));
-static int contributes_to_priority PARAMS ((rtx, rtx));
-static void compute_jump_reg_dependencies PARAMS ((rtx, regset, regset,
- regset));
-static void schedule_ebb PARAMS ((rtx, rtx));
+static void init_ready_list (struct ready_list *);
+static int can_schedule_ready_p (rtx);
+static int new_ready (rtx);
+static int schedule_more_p (void);
+static const char *ebb_print_insn (rtx, int);
+static int rank (rtx, rtx);
+static int contributes_to_priority (rtx, rtx);
+static void compute_jump_reg_dependencies (rtx, regset, regset, regset);
+static basic_block earliest_block_with_similiar_load (basic_block, rtx);
+static void add_deps_for_risky_insns (rtx, rtx);
+static basic_block schedule_ebb (rtx, rtx);
+static basic_block fix_basic_block_boundaries (basic_block, basic_block, rtx,
+ rtx);
+static void add_missing_bbs (rtx, basic_block, basic_block);
/* Return nonzero if there are more insns that should be scheduled. */
static int
-schedule_more_p ()
+schedule_more_p (void)
{
return sched_n_insns < target_n_insns;
}
@@ -68,8 +76,7 @@ schedule_more_p ()
once before scheduling a set of insns. */
static void
-init_ready_list (ready)
- struct ready_list *ready;
+init_ready_list (struct ready_list *ready)
{
rtx prev_head = current_sched_info->prev_head;
rtx next_tail = current_sched_info->next_tail;
@@ -88,17 +95,9 @@ init_ready_list (ready)
Count number of insns in the target block being scheduled. */
for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
{
- rtx next;
-
- if (! INSN_P (insn))
- continue;
- next = NEXT_INSN (insn);
-
- if (INSN_DEP_COUNT (insn) == 0
- && (! INSN_P (next) || SCHED_GROUP_P (next) == 0))
+ if (INSN_DEP_COUNT (insn) == 0)
ready_add (ready, insn);
- if (!(SCHED_GROUP_P (insn)))
- target_n_insns++;
+ target_n_insns++;
}
}
@@ -106,8 +105,7 @@ init_ready_list (ready)
insn can be scheduled, nonzero if we should silently discard it. */
static int
-can_schedule_ready_p (insn)
- rtx insn ATTRIBUTE_UNUSED;
+can_schedule_ready_p (rtx insn ATTRIBUTE_UNUSED)
{
sched_n_insns++;
return 1;
@@ -117,8 +115,7 @@ can_schedule_ready_p (insn)
if it should be moved to the ready list or the queue, or zero if we
should silently discard it. */
static int
-new_ready (next)
- rtx next ATTRIBUTE_UNUSED;
+new_ready (rtx next ATTRIBUTE_UNUSED)
{
return 1;
}
@@ -129,9 +126,7 @@ new_ready (next)
to be formatted so that multiple output lines will line up nicely. */
static const char *
-ebb_print_insn (insn, aligned)
- rtx insn;
- int aligned ATTRIBUTE_UNUSED;
+ebb_print_insn (rtx insn, int aligned ATTRIBUTE_UNUSED)
{
static char tmp[80];
@@ -144,9 +139,17 @@ ebb_print_insn (insn, aligned)
is to be preferred. Zero if they are equally good. */
static int
-rank (insn1, insn2)
- rtx insn1 ATTRIBUTE_UNUSED, insn2 ATTRIBUTE_UNUSED;
+rank (rtx insn1, rtx insn2)
{
+ basic_block bb1 = BLOCK_FOR_INSN (insn1);
+ basic_block bb2 = BLOCK_FOR_INSN (insn2);
+
+ if (bb1->count > bb2->count
+ || bb1->frequency > bb2->frequency)
+ return -1;
+ if (bb1->count < bb2->count
+ || bb1->frequency < bb2->frequency)
+ return 1;
return 0;
}
@@ -155,21 +158,20 @@ rank (insn1, insn2)
calculations. */
static int
-contributes_to_priority (next, insn)
- rtx next ATTRIBUTE_UNUSED, insn ATTRIBUTE_UNUSED;
+contributes_to_priority (rtx next ATTRIBUTE_UNUSED,
+ rtx insn ATTRIBUTE_UNUSED)
{
return 1;
}
-/* INSN is a JUMP_INSN, COND_SET is the set of registers that are
- conditionally set before INSN. Store the set of registers that
- must be considered as used by this jump in USED and that of
- registers that must be considered as set in SET. */
+ /* INSN is a JUMP_INSN, COND_SET is the set of registers that are
+ conditionally set before INSN. Store the set of registers that
+ must be considered as used by this jump in USED and that of
+ registers that must be considered as set in SET. */
static void
-compute_jump_reg_dependencies (insn, cond_set, used, set)
- rtx insn;
- regset cond_set, used, set;
+compute_jump_reg_dependencies (rtx insn, regset cond_set, regset used,
+ regset set)
{
basic_block b = BLOCK_FOR_INSN (insn);
edge e;
@@ -203,21 +205,286 @@ static struct sched_info ebb_sched_info =
NULL, NULL,
NULL, NULL,
- 0, 1
+ 0, 1, 0
};
+/* It is possible that ebb scheduling eliminated some blocks.
+ Place blocks from FIRST to LAST before BEFORE. */
+
+static void
+add_missing_bbs (rtx before, basic_block first, basic_block last)
+{
+ for (; last != first->prev_bb; last = last->prev_bb)
+ {
+ before = emit_note_before (NOTE_INSN_BASIC_BLOCK, before);
+ NOTE_BASIC_BLOCK (before) = last;
+ BB_HEAD (last) = before;
+ BB_END (last) = before;
+ update_bb_for_insn (last);
+ }
+}
+
+/* Fixup the CFG after EBB scheduling. Re-recognize the basic
+ block boundaries in between HEAD and TAIL and update basic block
+ structures between BB and LAST. */
+
+static basic_block
+fix_basic_block_boundaries (basic_block bb, basic_block last, rtx head,
+ rtx tail)
+{
+ rtx insn = head;
+ rtx last_inside = BB_HEAD (bb);
+ rtx aftertail = NEXT_INSN (tail);
+
+ head = BB_HEAD (bb);
+
+ for (; insn != aftertail; insn = NEXT_INSN (insn))
+ {
+ if (GET_CODE (insn) == CODE_LABEL)
+ abort ();
+ /* Create new basic blocks just before first insn. */
+ if (inside_basic_block_p (insn))
+ {
+ if (!last_inside)
+ {
+ rtx note;
+
+ /* Re-emit the basic block note for newly found BB header. */
+ if (GET_CODE (insn) == CODE_LABEL)
+ {
+ note = emit_note_after (NOTE_INSN_BASIC_BLOCK, insn);
+ head = insn;
+ last_inside = note;
+ }
+ else
+ {
+ note = emit_note_before (NOTE_INSN_BASIC_BLOCK, insn);
+ head = note;
+ last_inside = insn;
+ }
+ }
+ else
+ last_inside = insn;
+ }
+ /* Control flow instruction terminate basic block. It is possible
+ that we've eliminated some basic blocks (made them empty).
+ Find the proper basic block using BLOCK_FOR_INSN and arrange things in
+ a sensible way by inserting empty basic blocks as needed. */
+ if (control_flow_insn_p (insn) || (insn == tail && last_inside))
+ {
+ basic_block curr_bb = BLOCK_FOR_INSN (insn);
+ rtx note;
+
+ if (!control_flow_insn_p (insn))
+ curr_bb = last;
+ if (bb == last->next_bb)
+ {
+ edge f;
+ rtx h;
+
+ /* An obscure special case, where we do have partially dead
+ instruction scheduled after last control flow instruction.
+ In this case we can create new basic block. It is
+ always exactly one basic block last in the sequence. Handle
+ it by splitting the edge and repositioning the block.
+ This is somewhat hackish, but at least avoid cut&paste
+
+ A safer solution can be to bring the code into sequence,
+ do the split and re-emit it back in case this will ever
+ trigger problem. */
+ f = bb->prev_bb->succ;
+ while (f && !(f->flags & EDGE_FALLTHRU))
+ f = f->succ_next;
+
+ if (f)
+ {
+ last = curr_bb = split_edge (f);
+ h = BB_HEAD (curr_bb);
+ BB_HEAD (curr_bb) = head;
+ BB_END (curr_bb) = insn;
+ /* Edge splitting created misplaced BASIC_BLOCK note, kill
+ it. */
+ delete_insn (h);
+ }
+ /* It may happen that code got moved past unconditional jump in
+ case the code is completely dead. Kill it. */
+ else
+ {
+ rtx next = next_nonnote_insn (insn);
+ delete_insn_chain (head, insn);
+ /* We keep some notes in the way that may split barrier from the
+ jump. */
+ if (GET_CODE (next) == BARRIER)
+ {
+ emit_barrier_after (prev_nonnote_insn (head));
+ delete_insn (next);
+ }
+ insn = NULL;
+ }
+ }
+ else
+ {
+ BB_HEAD (curr_bb) = head;
+ BB_END (curr_bb) = insn;
+ add_missing_bbs (BB_HEAD (curr_bb), bb, curr_bb->prev_bb);
+ }
+ note = GET_CODE (head) == CODE_LABEL ? NEXT_INSN (head) : head;
+ NOTE_BASIC_BLOCK (note) = curr_bb;
+ update_bb_for_insn (curr_bb);
+ bb = curr_bb->next_bb;
+ last_inside = NULL;
+ if (!insn)
+ break;
+ }
+ }
+ add_missing_bbs (BB_HEAD (last->next_bb), bb, last);
+ return bb->prev_bb;
+}
+
+/* Returns the earliest block in EBB currently being processed where a
+ "similar load" 'insn2' is found, and hence LOAD_INSN can move
+ speculatively into the found block. All the following must hold:
+
+ (1) both loads have 1 base register (PFREE_CANDIDATEs).
+ (2) load_insn and load2 have a def-use dependence upon
+ the same insn 'insn1'.
+
+ From all these we can conclude that the two loads access memory
+ addresses that differ at most by a constant, and hence if moving
+ load_insn would cause an exception, it would have been caused by
+ load2 anyhow.
+
+ The function uses list (given by LAST_BLOCK) of already processed
+ blocks in EBB. The list is formed in `add_deps_for_risky_insns'. */
+
+static basic_block
+earliest_block_with_similiar_load (basic_block last_block, rtx load_insn)
+{
+ rtx back_link;
+ basic_block bb, earliest_block = NULL;
+
+ for (back_link = LOG_LINKS (load_insn);
+ back_link;
+ back_link = XEXP (back_link, 1))
+ {
+ rtx insn1 = XEXP (back_link, 0);
+
+ if (GET_MODE (back_link) == VOIDmode)
+ {
+ /* Found a DEF-USE dependence (insn1, load_insn). */
+ rtx fore_link;
+
+ for (fore_link = INSN_DEPEND (insn1);
+ fore_link;
+ fore_link = XEXP (fore_link, 1))
+ {
+ rtx insn2 = XEXP (fore_link, 0);
+ basic_block insn2_block = BLOCK_FOR_INSN (insn2);
+
+ if (GET_MODE (fore_link) == VOIDmode)
+ {
+ if (earliest_block != NULL
+ && earliest_block->index < insn2_block->index)
+ continue;
+
+ /* Found a DEF-USE dependence (insn1, insn2). */
+ if (haifa_classify_insn (insn2) != PFREE_CANDIDATE)
+ /* insn2 not guaranteed to be a 1 base reg load. */
+ continue;
+
+ for (bb = last_block; bb; bb = bb->aux)
+ if (insn2_block == bb)
+ break;
+
+ if (!bb)
+ /* insn2 is the similar load. */
+ earliest_block = insn2_block;
+ }
+ }
+ }
+ }
+
+ return earliest_block;
+}
+
+/* The following function adds dependencies between jumps and risky
+ insns in given ebb. */
+
+static void
+add_deps_for_risky_insns (rtx head, rtx tail)
+{
+ rtx insn, prev;
+ int class;
+ rtx last_jump = NULL_RTX;
+ rtx next_tail = NEXT_INSN (tail);
+ basic_block last_block = NULL, bb;
+
+ for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == JUMP_INSN)
+ {
+ bb = BLOCK_FOR_INSN (insn);
+ bb->aux = last_block;
+ last_block = bb;
+ last_jump = insn;
+ }
+ else if (INSN_P (insn) && last_jump != NULL_RTX)
+ {
+ class = haifa_classify_insn (insn);
+ prev = last_jump;
+ switch (class)
+ {
+ case PFREE_CANDIDATE:
+ if (flag_schedule_speculative_load)
+ {
+ bb = earliest_block_with_similiar_load (last_block, insn);
+ if (bb)
+ {
+ bb = bb->aux;
+ if (!bb)
+ break;
+ prev = BB_END (bb);
+ }
+ }
+ /* Fall through. */
+ case TRAP_RISKY:
+ case IRISKY:
+ case PRISKY_CANDIDATE:
+ /* ??? We could implement better checking PRISKY_CANDIDATEs
+ analogous to sched-rgn.c. */
+ /* We can not change the mode of the backward
+ dependency because REG_DEP_ANTI has the lowest
+ rank. */
+ if (add_dependence (insn, prev, REG_DEP_ANTI))
+ add_forward_dependence (prev, insn, REG_DEP_ANTI);
+ break;
+
+ default:
+ break;
+ }
+ }
+ /* Maintain the invariant that bb->aux is clear after use. */
+ while (last_block)
+ {
+ bb = last_block->aux;
+ last_block->aux = NULL;
+ last_block = bb;
+ }
+}
+
/* Schedule a single extended basic block, defined by the boundaries HEAD
and TAIL. */
-static void
-schedule_ebb (head, tail)
- rtx head, tail;
+static basic_block
+schedule_ebb (rtx head, rtx tail)
{
int n_insns;
+ basic_block b;
struct deps tmp_deps;
+ basic_block first_bb = BLOCK_FOR_INSN (head);
+ basic_block last_bb = BLOCK_FOR_INSN (tail);
if (no_real_insns_p (head, tail))
- return;
+ return BLOCK_FOR_INSN (tail);
init_deps_global ();
@@ -229,6 +496,11 @@ schedule_ebb (head, tail)
/* Compute INSN_DEPEND. */
compute_forward_dependences (head, tail);
+ add_deps_for_risky_insns (head, tail);
+
+ if (targetm.sched.dependencies_evaluation_hook)
+ targetm.sched.dependencies_evaluation_hook (head, tail);
+
/* Set priorities. */
n_insns = set_priorities (head, tail);
@@ -237,7 +509,7 @@ schedule_ebb (head, tail)
if (write_symbols != NO_DEBUG)
{
- save_line_notes (0, head, tail);
+ save_line_notes (first_bb->index, head, tail);
rm_line_notes (head, tail);
}
@@ -277,18 +549,26 @@ schedule_ebb (head, tail)
if (write_symbols != NO_DEBUG)
restore_line_notes (head, tail);
+ b = fix_basic_block_boundaries (first_bb, last_bb, head, tail);
finish_deps_global ();
+ return b;
}
/* The one entry point in this file. DUMP_FILE is the dump file for
this pass. */
void
-schedule_ebbs (dump_file)
- FILE *dump_file;
+schedule_ebbs (FILE *dump_file)
{
basic_block bb;
+ int probability_cutoff;
+
+ if (profile_info && flag_branch_probabilities)
+ probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK);
+ else
+ probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY);
+ probability_cutoff = REG_BR_PROB_BASE / 100 * probability_cutoff;
/* Taking care of this degenerate case makes the rest of
this code simpler. */
@@ -305,32 +585,23 @@ schedule_ebbs (dump_file)
/* Schedule every region in the subroutine. */
FOR_EACH_BB (bb)
{
- rtx head = bb->head;
+ rtx head = BB_HEAD (bb);
rtx tail;
for (;;)
{
edge e;
- tail = bb->end;
+ tail = BB_END (bb);
if (bb->next_bb == EXIT_BLOCK_PTR
- || GET_CODE (bb->next_bb->head) == CODE_LABEL)
+ || GET_CODE (BB_HEAD (bb->next_bb)) == CODE_LABEL)
break;
for (e = bb->succ; e; e = e->succ_next)
if ((e->flags & EDGE_FALLTHRU) != 0)
break;
if (! e)
break;
- if (GET_CODE (tail) == JUMP_INSN)
- {
- rtx x = find_reg_note (tail, REG_BR_PROB, 0);
- if (x)
- {
- int pred_val = INTVAL (XEXP (x, 0));
- if (pred_val > REG_BR_PROB_BASE / 2)
- break;
- }
- }
-
+ if (e->probability <= probability_cutoff)
+ break;
bb = bb->next_bb;
}
@@ -348,11 +619,11 @@ schedule_ebbs (dump_file)
break;
}
- schedule_ebb (head, tail);
+ bb = schedule_ebb (head, tail);
}
- /* It doesn't make much sense to try and update life information here - we
- probably messed up even the flow graph. */
+ /* Updating life info can be done by local propagation over the modified
+ superblocks. */
/* Reposition the prologue and epilogue notes in case we moved the
prologue/epilogue insns. */
diff --git a/contrib/gcc/sched-int.h b/contrib/gcc/sched-int.h
index 765e1eb34fbe..ba056e051a49 100644
--- a/contrib/gcc/sched-int.h
+++ b/contrib/gcc/sched-int.h
@@ -1,7 +1,7 @@
/* Instruction scheduling pass. This file contains definitions used
internally in the scheduler.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -82,7 +82,7 @@ struct deps
scheduling is done. */
rtx sched_before_next_call;
- /* Used to keep post-call psuedo/hard reg movements together with
+ /* Used to keep post-call pseudo/hard reg movements together with
the call. */
bool in_post_call_group_p;
@@ -126,32 +126,32 @@ struct sched_info
{
/* Add all insns that are initially ready to the ready list. Called once
before scheduling a set of insns. */
- void (*init_ready_list) PARAMS ((struct ready_list *));
+ void (*init_ready_list) (struct ready_list *);
/* Called after taking an insn from the ready list. Returns nonzero if
this insn can be scheduled, nonzero if we should silently discard it. */
- int (*can_schedule_ready_p) PARAMS ((rtx));
+ int (*can_schedule_ready_p) (rtx);
/* Return nonzero if there are more insns that should be scheduled. */
- int (*schedule_more_p) PARAMS ((void));
+ int (*schedule_more_p) (void);
/* Called after an insn has all its dependencies resolved. Return nonzero
if it should be moved to the ready list or the queue, or zero if we
should silently discard it. */
- int (*new_ready) PARAMS ((rtx));
+ int (*new_ready) (rtx);
/* Compare priority of two insns. Return a positive number if the second
insn is to be preferred for scheduling, and a negative one if the first
is to be preferred. Zero if they are equally good. */
- int (*rank) PARAMS ((rtx, rtx));
+ int (*rank) (rtx, rtx);
/* Return a string that contains the insn uid and optionally anything else
necessary to identify this insn in an output. It's valid to use a
static buffer for this. The ALIGNED parameter should cause the string
to be formatted so that multiple output lines will line up nicely. */
- const char *(*print_insn) PARAMS ((rtx, int));
+ const char *(*print_insn) (rtx, int);
/* Return nonzero if an insn should be included in priority
calculations. */
- int (*contributes_to_priority) PARAMS ((rtx, rtx));
+ int (*contributes_to_priority) (rtx, rtx);
/* Called when computing dependencies for a JUMP_INSN. This function
- should store the set of registers that must be considered as used
- and the set of registers that must be considered as set by the jump. */
- void (*compute_jump_reg_dependencies) PARAMS ((rtx, regset, regset, regset));
+ should store the set of registers that must be considered as set by
+ the jump in the regset. */
+ void (*compute_jump_reg_dependencies) (rtx, regset, regset, regset);
/* The boundaries of the set of insns to be scheduled. */
rtx prev_head, next_tail;
@@ -167,6 +167,9 @@ struct sched_info
has completed, e.g. if we're using it to initialize state for successor
blocks in region scheduling. */
unsigned int use_cselib:1;
+
+ /* Maximum priority that has been assigned to an insn. */
+ int sched_max_insns_priority;
};
extern struct sched_info *current_sched_info;
@@ -191,7 +194,7 @@ struct haifa_insn_data
int priority;
/* The number of incoming edges in the forward dependency graph.
- As scheduling proceds, counts are decreased. An insn moves to
+ As scheduling proceeds, counts are decreased. An insn moves to
the ready queue when its counter reaches zero. */
int dep_count;
@@ -261,6 +264,76 @@ extern struct haifa_insn_data *h_i_d;
extern FILE *sched_dump;
extern int sched_verbose;
+/* Exception Free Loads:
+
+ We define five classes of speculative loads: IFREE, IRISKY,
+ PFREE, PRISKY, and MFREE.
+
+ IFREE loads are loads that are proved to be exception-free, just
+ by examining the load insn. Examples for such loads are loads
+ from TOC and loads of global data.
+
+ IRISKY loads are loads that are proved to be exception-risky,
+ just by examining the load insn. Examples for such loads are
+ volatile loads and loads from shared memory.
+
+ PFREE loads are loads for which we can prove, by examining other
+ insns, that they are exception-free. Currently, this class consists
+ of loads for which we are able to find a "similar load", either in
+ the target block, or, if only one split-block exists, in that split
+ block. Load2 is similar to load1 if both have same single base
+ register. We identify only part of the similar loads, by finding
+ an insn upon which both load1 and load2 have a DEF-USE dependence.
+
+ PRISKY loads are loads for which we can prove, by examining other
+ insns, that they are exception-risky. Currently we have two proofs for
+ such loads. The first proof detects loads that are probably guarded by a
+ test on the memory address. This proof is based on the
+ backward and forward data dependence information for the region.
+ Let load-insn be the examined load.
+ Load-insn is PRISKY iff ALL the following hold:
+
+ - insn1 is not in the same block as load-insn
+ - there is a DEF-USE dependence chain (insn1, ..., load-insn)
+ - test-insn is either a compare or a branch, not in the same block
+ as load-insn
+ - load-insn is reachable from test-insn
+ - there is a DEF-USE dependence chain (insn1, ..., test-insn)
+
+ This proof might fail when the compare and the load are fed
+ by an insn not in the region. To solve this, we will add to this
+ group all loads that have no input DEF-USE dependence.
+
+ The second proof detects loads that are directly or indirectly
+ fed by a speculative load. This proof is affected by the
+ scheduling process. We will use the flag fed_by_spec_load.
+ Initially, all insns have this flag reset. After a speculative
+ motion of an insn, if insn is either a load, or marked as
+ fed_by_spec_load, we will also mark as fed_by_spec_load every
+ insn1 for which a DEF-USE dependence (insn, insn1) exists. A
+ load which is fed_by_spec_load is also PRISKY.
+
+ MFREE (maybe-free) loads are all the remaining loads. They may be
+ exception-free, but we cannot prove it.
+
+ Now, all loads in IFREE and PFREE classes are considered
+ exception-free, while all loads in IRISKY and PRISKY classes are
+ considered exception-risky. As for loads in the MFREE class,
+ these are considered either exception-free or exception-risky,
+ depending on whether we are pessimistic or optimistic. We have
+ to take the pessimistic approach to assure the safety of
+ speculative scheduling, but we can take the optimistic approach
+ by invoking the -fsched_spec_load_dangerous option. */
+
+enum INSN_TRAP_CLASS
+{
+ TRAP_FREE = 0, IFREE = 1, PFREE_CANDIDATE = 2,
+ PRISKY_CANDIDATE = 3, IRISKY = 4, TRAP_RISKY = 5
+};
+
+#define WORST_CLASS(class1, class2) \
+((class1 > class2) ? class1 : class2)
+
#ifndef __GNUC__
#define __inline
#endif
@@ -270,54 +343,55 @@ extern int sched_verbose;
#endif
/* Functions in sched-vis.c. */
-extern void init_target_units PARAMS ((void));
-extern void insn_print_units PARAMS ((rtx));
-extern void init_block_visualization PARAMS ((void));
-extern void print_block_visualization PARAMS ((const char *));
-extern void visualize_scheduled_insns PARAMS ((int));
-extern void visualize_no_unit PARAMS ((rtx));
-extern void visualize_stall_cycles PARAMS ((int));
-extern void visualize_alloc PARAMS ((void));
-extern void visualize_free PARAMS ((void));
+extern void init_target_units (void);
+extern void insn_print_units (rtx);
+extern void init_block_visualization (void);
+extern void print_block_visualization (const char *);
+extern void visualize_scheduled_insns (int);
+extern void visualize_no_unit (rtx);
+extern void visualize_stall_cycles (int);
+extern void visualize_alloc (void);
+extern void visualize_free (void);
/* Functions in sched-deps.c. */
-extern void add_dependence PARAMS ((rtx, rtx, enum reg_note));
-extern void add_insn_mem_dependence PARAMS ((struct deps *, rtx *, rtx *, rtx,
- rtx));
-extern void sched_analyze PARAMS ((struct deps *, rtx, rtx));
-extern void init_deps PARAMS ((struct deps *));
-extern void free_deps PARAMS ((struct deps *));
-extern void init_deps_global PARAMS ((void));
-extern void finish_deps_global PARAMS ((void));
-extern void compute_forward_dependences PARAMS ((rtx, rtx));
-extern rtx find_insn_list PARAMS ((rtx, rtx));
-extern void init_dependency_caches PARAMS ((int));
-extern void free_dependency_caches PARAMS ((void));
+extern int add_dependence (rtx, rtx, enum reg_note);
+extern void add_insn_mem_dependence (struct deps *, rtx *, rtx *, rtx, rtx);
+extern void sched_analyze (struct deps *, rtx, rtx);
+extern void init_deps (struct deps *);
+extern void free_deps (struct deps *);
+extern void init_deps_global (void);
+extern void finish_deps_global (void);
+extern void add_forward_dependence (rtx, rtx, enum reg_note);
+extern void compute_forward_dependences (rtx, rtx);
+extern rtx find_insn_list (rtx, rtx);
+extern void init_dependency_caches (int);
+extern void free_dependency_caches (void);
/* Functions in haifa-sched.c. */
-extern void get_block_head_tail PARAMS ((int, rtx *, rtx *));
-extern int no_real_insns_p PARAMS ((rtx, rtx));
+extern int haifa_classify_insn (rtx);
+extern void get_block_head_tail (int, rtx *, rtx *);
+extern int no_real_insns_p (rtx, rtx);
-extern void rm_line_notes PARAMS ((rtx, rtx));
-extern void save_line_notes PARAMS ((int, rtx, rtx));
-extern void restore_line_notes PARAMS ((rtx, rtx));
-extern void rm_redundant_line_notes PARAMS ((void));
-extern void rm_other_notes PARAMS ((rtx, rtx));
+extern void rm_line_notes (rtx, rtx);
+extern void save_line_notes (int, rtx, rtx);
+extern void restore_line_notes (rtx, rtx);
+extern void rm_redundant_line_notes (void);
+extern void rm_other_notes (rtx, rtx);
-extern int insn_issue_delay PARAMS ((rtx));
-extern int set_priorities PARAMS ((rtx, rtx));
+extern int insn_issue_delay (rtx);
+extern int set_priorities (rtx, rtx);
-extern rtx sched_emit_insn PARAMS ((rtx));
-extern void schedule_block PARAMS ((int, int));
-extern void sched_init PARAMS ((FILE *));
-extern void sched_finish PARAMS ((void));
+extern rtx sched_emit_insn (rtx);
+extern void schedule_block (int, int);
+extern void sched_init (FILE *);
+extern void sched_finish (void);
-extern void ready_add PARAMS ((struct ready_list *, rtx));
+extern void ready_add (struct ready_list *, rtx);
/* The following are exported for the benefit of debugging functions. It
would be nicer to keep them private to haifa-sched.c. */
-extern int insn_unit PARAMS ((rtx));
-extern int insn_cost PARAMS ((rtx, rtx, rtx));
-extern rtx get_unit_last_insn PARAMS ((int));
-extern int actual_hazard_this_instance PARAMS ((int, int, rtx, int, int));
-extern void print_insn PARAMS ((char *, rtx, int));
+extern int insn_unit (rtx);
+extern int insn_cost (rtx, rtx, rtx);
+extern rtx get_unit_last_insn (int);
+extern int actual_hazard_this_instance (int, int, rtx, int, int);
+extern void print_insn (char *, rtx, int);
diff --git a/contrib/gcc/sched-rgn.c b/contrib/gcc/sched-rgn.c
index 935b8e22da62..b8e474d0b448 100644
--- a/contrib/gcc/sched-rgn.c
+++ b/contrib/gcc/sched-rgn.c
@@ -1,6 +1,6 @@
/* Instruction scheduling pass.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com)
@@ -47,6 +47,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "tm_p.h"
@@ -114,9 +116,9 @@ static int *out_edges;
#define IN_EDGES(block) (in_edges[block])
#define OUT_EDGES(block) (out_edges[block])
-static int is_cfg_nonregular PARAMS ((void));
-static int build_control_flow PARAMS ((struct edge_list *));
-static void new_edge PARAMS ((int, int));
+static int is_cfg_nonregular (void);
+static int build_control_flow (struct edge_list *);
+static void new_edge (int, int);
/* A region is the main entity for interblock scheduling: insns
are allowed to move between blocks in the same region, along
@@ -140,7 +142,7 @@ static int *rgn_bb_table;
/* Topological order of blocks in the region (if b2 is reachable from
b1, block_to_bb[b2] > block_to_bb[b1]). Note: A basic block is
always referred to by either block or b, while its topological
- order name (in the region) is refered to by bb. */
+ order name (in the region) is referred to by bb. */
static int *block_to_bb;
/* The number of the region containing a block. */
@@ -151,12 +153,12 @@ static int *containing_rgn;
#define BLOCK_TO_BB(block) (block_to_bb[block])
#define CONTAINING_RGN(block) (containing_rgn[block])
-void debug_regions PARAMS ((void));
-static void find_single_block_region PARAMS ((void));
-static void find_rgns PARAMS ((struct edge_list *, dominance_info));
-static int too_large PARAMS ((int, int *, int *));
+void debug_regions (void);
+static void find_single_block_region (void);
+static void find_rgns (struct edge_list *);
+static int too_large (int, int *, int *);
-extern void debug_live PARAMS ((int, int));
+extern void debug_live (int, int);
/* Blocks of the current region being scheduled. */
static int current_nr_blocks;
@@ -173,10 +175,9 @@ typedef struct
bitlst;
static int bitlst_table_last;
-static int bitlst_table_size;
static int *bitlst_table;
-static void extract_bitlst PARAMS ((sbitmap, bitlst *));
+static void extract_bitlst (sbitmap, bitlst *);
/* Target info declarations.
@@ -217,10 +218,10 @@ static int target_bb;
typedef bitlst edgelst;
/* Target info functions. */
-static void split_edges PARAMS ((int, int, edgelst *));
-static void compute_trg_info PARAMS ((int));
-void debug_candidate PARAMS ((int));
-void debug_candidates PARAMS ((int));
+static void split_edges (int, int, edgelst *);
+static void compute_trg_info (int);
+void debug_candidate (int);
+void debug_candidates (int);
/* Dominators array: dom[i] contains the sbitmap of dominators of
bb i in the region. */
@@ -268,42 +269,40 @@ static edgeset *pot_split;
/* For every bb, a set of its ancestor edges. */
static edgeset *ancestor_edges;
-static void compute_dom_prob_ps PARAMS ((int));
+static void compute_dom_prob_ps (int);
#define INSN_PROBABILITY(INSN) (SRC_PROB (BLOCK_TO_BB (BLOCK_NUM (INSN))))
#define IS_SPECULATIVE_INSN(INSN) (IS_SPECULATIVE (BLOCK_TO_BB (BLOCK_NUM (INSN))))
#define INSN_BB(INSN) (BLOCK_TO_BB (BLOCK_NUM (INSN)))
/* Parameters affecting the decision of rank_for_schedule().
- ??? Nope. But MIN_PROBABILITY is used in copmute_trg_info. */
+ ??? Nope. But MIN_PROBABILITY is used in compute_trg_info. */
#define MIN_PROBABILITY 40
/* Speculative scheduling functions. */
-static int check_live_1 PARAMS ((int, rtx));
-static void update_live_1 PARAMS ((int, rtx));
-static int check_live PARAMS ((rtx, int));
-static void update_live PARAMS ((rtx, int));
-static void set_spec_fed PARAMS ((rtx));
-static int is_pfree PARAMS ((rtx, int, int));
-static int find_conditional_protection PARAMS ((rtx, int));
-static int is_conditionally_protected PARAMS ((rtx, int, int));
-static int may_trap_exp PARAMS ((rtx, int));
-static int haifa_classify_insn PARAMS ((rtx));
-static int is_prisky PARAMS ((rtx, int, int));
-static int is_exception_free PARAMS ((rtx, int, int));
-
-static bool sets_likely_spilled PARAMS ((rtx));
-static void sets_likely_spilled_1 PARAMS ((rtx, rtx, void *));
-static void add_branch_dependences PARAMS ((rtx, rtx));
-static void compute_block_backward_dependences PARAMS ((int));
-void debug_dependencies PARAMS ((void));
-
-static void init_regions PARAMS ((void));
-static void schedule_region PARAMS ((int));
-static rtx concat_INSN_LIST PARAMS ((rtx, rtx));
-static void concat_insn_mem_list PARAMS ((rtx, rtx, rtx *, rtx *));
-static void propagate_deps PARAMS ((int, struct deps *));
-static void free_pending_lists PARAMS ((void));
+static int check_live_1 (int, rtx);
+static void update_live_1 (int, rtx);
+static int check_live (rtx, int);
+static void update_live (rtx, int);
+static void set_spec_fed (rtx);
+static int is_pfree (rtx, int, int);
+static int find_conditional_protection (rtx, int);
+static int is_conditionally_protected (rtx, int, int);
+static int is_prisky (rtx, int, int);
+static int is_exception_free (rtx, int, int);
+
+static bool sets_likely_spilled (rtx);
+static void sets_likely_spilled_1 (rtx, rtx, void *);
+static void add_branch_dependences (rtx, rtx);
+static void compute_block_backward_dependences (int);
+void debug_dependencies (void);
+
+static void init_regions (void);
+static void schedule_region (int);
+static rtx concat_INSN_LIST (rtx, rtx);
+static void concat_insn_mem_list (rtx, rtx, rtx *, rtx *);
+static void propagate_deps (int, struct deps *);
+static void free_pending_lists (void);
/* Functions for construction of the control flow graph. */
@@ -314,7 +313,7 @@ static void free_pending_lists PARAMS ((void));
have nonlocal gotos. */
static int
-is_cfg_nonregular ()
+is_cfg_nonregular (void)
{
basic_block b;
rtx insn;
@@ -344,7 +343,7 @@ is_cfg_nonregular ()
the cfg not well structured. */
/* Check for labels referred to other thn by jumps. */
FOR_EACH_BB (b)
- for (insn = b->head;; insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (b); ; insn = NEXT_INSN (insn))
{
code = GET_CODE (insn);
if (GET_RTX_CLASS (code) == 'i' && code != JUMP_INSN)
@@ -358,7 +357,7 @@ is_cfg_nonregular ()
return 1;
}
- if (insn == b->end)
+ if (insn == BB_END (b))
break;
}
@@ -375,8 +374,7 @@ is_cfg_nonregular ()
prevent cross block scheduling. */
static int
-build_control_flow (edge_list)
- struct edge_list *edge_list;
+build_control_flow (struct edge_list *edge_list)
{
int i, unreachable, num_edges;
basic_block b;
@@ -400,9 +398,9 @@ build_control_flow (edge_list)
}
/* ??? We can kill these soon. */
- in_edges = (int *) xcalloc (last_basic_block, sizeof (int));
- out_edges = (int *) xcalloc (last_basic_block, sizeof (int));
- edge_table = (haifa_edge *) xcalloc (num_edges, sizeof (haifa_edge));
+ in_edges = xcalloc (last_basic_block, sizeof (int));
+ out_edges = xcalloc (last_basic_block, sizeof (int));
+ edge_table = xcalloc (num_edges, sizeof (haifa_edge));
nr_edges = 0;
for (i = 0; i < num_edges; i++)
@@ -427,8 +425,7 @@ build_control_flow (edge_list)
integer lists. */
static void
-new_edge (source, target)
- int source, target;
+new_edge (int source, int target)
{
int e, next_edge;
int curr_edge, fst_edge;
@@ -482,9 +479,7 @@ new_edge (source, target)
/* Translate a bit-set SET to a list BL of the bit-set members. */
static void
-extract_bitlst (set, bl)
- sbitmap set;
- bitlst *bl;
+extract_bitlst (sbitmap set, bitlst *bl)
{
int i;
@@ -508,7 +503,7 @@ extract_bitlst (set, bl)
/* Print the regions, for debugging purposes. Callable from debugger. */
void
-debug_regions ()
+debug_regions (void)
{
int rgn, bb;
@@ -538,7 +533,7 @@ debug_regions ()
scheduling. */
static void
-find_single_block_region ()
+find_single_block_region (void)
{
basic_block bb;
@@ -560,12 +555,11 @@ find_single_block_region ()
scheduling (compile time considerations), otherwise return 0. */
static int
-too_large (block, num_bbs, num_insns)
- int block, *num_bbs, *num_insns;
+too_large (int block, int *num_bbs, int *num_insns)
{
(*num_bbs)++;
- (*num_insns) += (INSN_LUID (BLOCK_END (block)) -
- INSN_LUID (BLOCK_HEAD (block)));
+ (*num_insns) += (INSN_LUID (BB_END (BASIC_BLOCK (block))) -
+ INSN_LUID (BB_HEAD (BASIC_BLOCK (block))));
if ((*num_bbs > MAX_RGN_BLOCKS) || (*num_insns > MAX_RGN_INSNS))
return 1;
else
@@ -619,14 +613,13 @@ too_large (block, num_bbs, num_insns)
of edge tables. That would simplify it somewhat. */
static void
-find_rgns (edge_list, dom)
- struct edge_list *edge_list;
- dominance_info dom;
+find_rgns (struct edge_list *edge_list)
{
int *max_hdr, *dfs_nr, *stack, *degree;
char no_loops = 1;
int node, child, loop_head, i, head, tail;
- int count = 0, sp, idx = 0, current_edge = out_edges[0];
+ int count = 0, sp, idx = 0;
+ int current_edge = out_edges[ENTRY_BLOCK_PTR->succ->dest->index];
int num_bbs, num_insns, unreachable;
int too_large_failure;
basic_block bb;
@@ -658,9 +651,9 @@ find_rgns (edge_list, dom)
STACK, SP and DFS_NR are only used during the first traversal. */
/* Allocate and initialize variables for the first traversal. */
- max_hdr = (int *) xmalloc (last_basic_block * sizeof (int));
- dfs_nr = (int *) xcalloc (last_basic_block, sizeof (int));
- stack = (int *) xmalloc (nr_edges * sizeof (int));
+ max_hdr = xmalloc (last_basic_block * sizeof (int));
+ dfs_nr = xcalloc (last_basic_block, sizeof (int));
+ stack = xmalloc (nr_edges * sizeof (int));
inner = sbitmap_alloc (last_basic_block);
sbitmap_ones (inner);
@@ -801,10 +794,10 @@ find_rgns (edge_list, dom)
if (no_loops)
SET_BIT (header, 0);
- /* Second travsersal:find reducible inner loops and topologically sort
+ /* Second traversal:find reducible inner loops and topologically sort
block of each region. */
- queue = (int *) xmalloc (n_basic_blocks * sizeof (int));
+ queue = xmalloc (n_basic_blocks * sizeof (int));
/* Find blocks which are inner loop headers. We still have non-reducible
loops to consider at this point. */
@@ -834,7 +827,7 @@ find_rgns (edge_list, dom)
{
/* Now verify that the block is dominated by the loop
header. */
- if (!dominated_by_p (dom, jbb, bb))
+ if (!dominated_by_p (CDI_DOMINATORS, jbb, bb))
break;
}
}
@@ -859,8 +852,8 @@ find_rgns (edge_list, dom)
/* Estimate # insns, and count # blocks in the region. */
num_bbs = 1;
- num_insns = (INSN_LUID (bb->end)
- - INSN_LUID (bb->head));
+ num_insns = (INSN_LUID (BB_END (bb))
+ - INSN_LUID (BB_HEAD (bb)));
/* Find all loop latches (blocks with back edges to the loop
header) or all the leaf blocks in the cfg has no loops.
@@ -1045,8 +1038,7 @@ find_rgns (edge_list, dom)
Assume that these values were already computed for bb's predecessors. */
static void
-compute_dom_prob_ps (bb)
- int bb;
+compute_dom_prob_ps (int bb)
{
int nxt_in_edge, fst_in_edge, pred;
int fst_out_edge, nxt_out_edge, nr_out_edges, nr_rgn_out_edges;
@@ -1124,12 +1116,9 @@ compute_dom_prob_ps (bb)
Note that bb_trg dominates bb_src. */
static void
-split_edges (bb_src, bb_trg, bl)
- int bb_src;
- int bb_trg;
- edgelst *bl;
+split_edges (int bb_src, int bb_trg, edgelst *bl)
{
- sbitmap src = (edgeset) sbitmap_alloc (pot_split[bb_src]->n_bits);
+ sbitmap src = sbitmap_alloc (pot_split[bb_src]->n_bits);
sbitmap_copy (src, pot_split[bb_src]);
sbitmap_difference (src, src, pot_split[bb_trg]);
@@ -1142,8 +1131,7 @@ split_edges (bb_src, bb_trg, bl)
For speculative sources, compute their update-blocks and split-blocks. */
static void
-compute_trg_info (trg)
- int trg;
+compute_trg_info (int trg)
{
candidate *sp;
edgelst el;
@@ -1194,7 +1182,7 @@ compute_trg_info (trg)
add the TO block to the update block list. This list can end
up with a lot of duplicates. We need to weed them out to avoid
overrunning the end of the bblst_table. */
- update_blocks = (char *) alloca (last_basic_block);
+ update_blocks = alloca (last_basic_block);
memset (update_blocks, 0, last_basic_block);
update_idx = 0;
@@ -1241,8 +1229,7 @@ compute_trg_info (trg)
/* Print candidates info, for debugging purposes. Callable from debugger. */
void
-debug_candidate (i)
- int i;
+debug_candidate (int i)
{
if (!candidate_table[i].is_valid)
return;
@@ -1279,8 +1266,7 @@ debug_candidate (i)
/* Print candidates info, for debugging purposes. Callable from debugger. */
void
-debug_candidates (trg)
- int trg;
+debug_candidates (int trg)
{
int i;
@@ -1290,15 +1276,13 @@ debug_candidates (trg)
debug_candidate (i);
}
-/* Functions for speculative scheduing. */
+/* Functions for speculative scheduling. */
/* Return 0 if x is a set of a register alive in the beginning of one
of the split-blocks of src, otherwise return 1. */
static int
-check_live_1 (src, x)
- int src;
- rtx x;
+check_live_1 (int src, rtx x)
{
int i;
int regno;
@@ -1356,7 +1340,7 @@ check_live_1 (src, x)
}
else
{
- /* Check for psuedo registers. */
+ /* Check for pseudo registers. */
for (i = 0; i < candidate_table[src].split_bbs.nr_members; i++)
{
int b = candidate_table[src].split_bbs.first_member[i];
@@ -1376,9 +1360,7 @@ check_live_1 (src, x)
of every update-block of src. */
static void
-update_live_1 (src, x)
- int src;
- rtx x;
+update_live_1 (int src, rtx x)
{
int i;
int regno;
@@ -1444,9 +1426,7 @@ update_live_1 (src, x)
ready-list or before the scheduling. */
static int
-check_live (insn, src)
- rtx insn;
- int src;
+check_live (rtx insn, int src)
{
/* Find the registers set by instruction. */
if (GET_CODE (PATTERN (insn)) == SET
@@ -1471,9 +1451,7 @@ check_live (insn, src)
block src to trg. */
static void
-update_live (insn, src)
- rtx insn;
- int src;
+update_live (rtx insn, int src)
{
/* Find the registers set by instruction. */
if (GET_CODE (PATTERN (insn)) == SET
@@ -1489,96 +1467,17 @@ update_live (insn, src)
}
}
-/* Exception Free Loads:
-
- We define five classes of speculative loads: IFREE, IRISKY,
- PFREE, PRISKY, and MFREE.
-
- IFREE loads are loads that are proved to be exception-free, just
- by examining the load insn. Examples for such loads are loads
- from TOC and loads of global data.
-
- IRISKY loads are loads that are proved to be exception-risky,
- just by examining the load insn. Examples for such loads are
- volatile loads and loads from shared memory.
-
- PFREE loads are loads for which we can prove, by examining other
- insns, that they are exception-free. Currently, this class consists
- of loads for which we are able to find a "similar load", either in
- the target block, or, if only one split-block exists, in that split
- block. Load2 is similar to load1 if both have same single base
- register. We identify only part of the similar loads, by finding
- an insn upon which both load1 and load2 have a DEF-USE dependence.
-
- PRISKY loads are loads for which we can prove, by examining other
- insns, that they are exception-risky. Currently we have two proofs for
- such loads. The first proof detects loads that are probably guarded by a
- test on the memory address. This proof is based on the
- backward and forward data dependence information for the region.
- Let load-insn be the examined load.
- Load-insn is PRISKY iff ALL the following hold:
-
- - insn1 is not in the same block as load-insn
- - there is a DEF-USE dependence chain (insn1, ..., load-insn)
- - test-insn is either a compare or a branch, not in the same block
- as load-insn
- - load-insn is reachable from test-insn
- - there is a DEF-USE dependence chain (insn1, ..., test-insn)
-
- This proof might fail when the compare and the load are fed
- by an insn not in the region. To solve this, we will add to this
- group all loads that have no input DEF-USE dependence.
-
- The second proof detects loads that are directly or indirectly
- fed by a speculative load. This proof is affected by the
- scheduling process. We will use the flag fed_by_spec_load.
- Initially, all insns have this flag reset. After a speculative
- motion of an insn, if insn is either a load, or marked as
- fed_by_spec_load, we will also mark as fed_by_spec_load every
- insn1 for which a DEF-USE dependence (insn, insn1) exists. A
- load which is fed_by_spec_load is also PRISKY.
-
- MFREE (maybe-free) loads are all the remaining loads. They may be
- exception-free, but we cannot prove it.
-
- Now, all loads in IFREE and PFREE classes are considered
- exception-free, while all loads in IRISKY and PRISKY classes are
- considered exception-risky. As for loads in the MFREE class,
- these are considered either exception-free or exception-risky,
- depending on whether we are pessimistic or optimistic. We have
- to take the pessimistic approach to assure the safety of
- speculative scheduling, but we can take the optimistic approach
- by invoking the -fsched_spec_load_dangerous option. */
-
-enum INSN_TRAP_CLASS
-{
- TRAP_FREE = 0, IFREE = 1, PFREE_CANDIDATE = 2,
- PRISKY_CANDIDATE = 3, IRISKY = 4, TRAP_RISKY = 5
-};
-
-#define WORST_CLASS(class1, class2) \
-((class1 > class2) ? class1 : class2)
-
-/* Non-zero if block bb_to is equal to, or reachable from block bb_from. */
+/* Nonzero if block bb_to is equal to, or reachable from block bb_from. */
#define IS_REACHABLE(bb_from, bb_to) \
(bb_from == bb_to \
|| IS_RGN_ENTRY (bb_from) \
|| (TEST_BIT (ancestor_edges[bb_to], \
EDGE_TO_BIT (IN_EDGES (BB_TO_BLOCK (bb_from))))))
-/* Non-zero iff the address is comprised from at most 1 register. */
-#define CONST_BASED_ADDRESS_P(x) \
- (GET_CODE (x) == REG \
- || ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS \
- || (GET_CODE (x) == LO_SUM)) \
- && (CONSTANT_P (XEXP (x, 0)) \
- || CONSTANT_P (XEXP (x, 1)))))
-
/* Turns on the fed_by_spec_load flag for insns fed by load_insn. */
static void
-set_spec_fed (load_insn)
- rtx load_insn;
+set_spec_fed (rtx load_insn)
{
rtx link;
@@ -1591,9 +1490,7 @@ set_spec_fed (load_insn)
branch depending on insn, that guards the speculative load. */
static int
-find_conditional_protection (insn, load_insn_bb)
- rtx insn;
- int load_insn_bb;
+find_conditional_protection (rtx insn, int load_insn_bb)
{
rtx link;
@@ -1628,9 +1525,7 @@ find_conditional_protection (insn, load_insn_bb)
Locate the branch by following INSN_DEPEND from insn1. */
static int
-is_conditionally_protected (load_insn, bb_src, bb_trg)
- rtx load_insn;
- int bb_src, bb_trg;
+is_conditionally_protected (rtx load_insn, int bb_src, int bb_trg)
{
rtx link;
@@ -1680,9 +1575,7 @@ is_conditionally_protected (load_insn, bb_src, bb_trg)
load2 anyhow. */
static int
-is_pfree (load_insn, bb_src, bb_trg)
- rtx load_insn;
- int bb_src, bb_trg;
+is_pfree (rtx load_insn, int bb_src, int bb_trg)
{
rtx back_link;
candidate *candp = candidate_table + bb_src;
@@ -1728,168 +1621,12 @@ is_pfree (load_insn, bb_src, bb_trg)
return 0;
} /* is_pfree */
-/* Returns a class that insn with GET_DEST(insn)=x may belong to,
- as found by analyzing insn's expression. */
-
-static int
-may_trap_exp (x, is_store)
- rtx x;
- int is_store;
-{
- enum rtx_code code;
-
- if (x == 0)
- return TRAP_FREE;
- code = GET_CODE (x);
- if (is_store)
- {
- if (code == MEM && may_trap_p (x))
- return TRAP_RISKY;
- else
- return TRAP_FREE;
- }
- if (code == MEM)
- {
- /* The insn uses memory: a volatile load. */
- if (MEM_VOLATILE_P (x))
- return IRISKY;
- /* An exception-free load. */
- if (!may_trap_p (x))
- return IFREE;
- /* A load with 1 base register, to be further checked. */
- if (CONST_BASED_ADDRESS_P (XEXP (x, 0)))
- return PFREE_CANDIDATE;
- /* No info on the load, to be further checked. */
- return PRISKY_CANDIDATE;
- }
- else
- {
- const char *fmt;
- int i, insn_class = TRAP_FREE;
-
- /* Neither store nor load, check if it may cause a trap. */
- if (may_trap_p (x))
- return TRAP_RISKY;
- /* Recursive step: walk the insn... */
- fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
- {
- if (fmt[i] == 'e')
- {
- int tmp_class = may_trap_exp (XEXP (x, i), is_store);
- insn_class = WORST_CLASS (insn_class, tmp_class);
- }
- else if (fmt[i] == 'E')
- {
- int j;
- for (j = 0; j < XVECLEN (x, i); j++)
- {
- int tmp_class = may_trap_exp (XVECEXP (x, i, j), is_store);
- insn_class = WORST_CLASS (insn_class, tmp_class);
- if (insn_class == TRAP_RISKY || insn_class == IRISKY)
- break;
- }
- }
- if (insn_class == TRAP_RISKY || insn_class == IRISKY)
- break;
- }
- return insn_class;
- }
-}
-
-/* Classifies insn for the purpose of verifying that it can be
- moved speculatively, by examining it's patterns, returning:
- TRAP_RISKY: store, or risky non-load insn (e.g. division by variable).
- TRAP_FREE: non-load insn.
- IFREE: load from a globaly safe location.
- IRISKY: volatile load.
- PFREE_CANDIDATE, PRISKY_CANDIDATE: load that need to be checked for
- being either PFREE or PRISKY. */
-
-static int
-haifa_classify_insn (insn)
- rtx insn;
-{
- rtx pat = PATTERN (insn);
- int tmp_class = TRAP_FREE;
- int insn_class = TRAP_FREE;
- enum rtx_code code;
-
- if (GET_CODE (pat) == PARALLEL)
- {
- int i, len = XVECLEN (pat, 0);
-
- for (i = len - 1; i >= 0; i--)
- {
- code = GET_CODE (XVECEXP (pat, 0, i));
- switch (code)
- {
- case CLOBBER:
- /* Test if it is a 'store'. */
- tmp_class = may_trap_exp (XEXP (XVECEXP (pat, 0, i), 0), 1);
- break;
- case SET:
- /* Test if it is a store. */
- tmp_class = may_trap_exp (SET_DEST (XVECEXP (pat, 0, i)), 1);
- if (tmp_class == TRAP_RISKY)
- break;
- /* Test if it is a load. */
- tmp_class
- = WORST_CLASS (tmp_class,
- may_trap_exp (SET_SRC (XVECEXP (pat, 0, i)),
- 0));
- break;
- case COND_EXEC:
- case TRAP_IF:
- tmp_class = TRAP_RISKY;
- break;
- default:
- ;
- }
- insn_class = WORST_CLASS (insn_class, tmp_class);
- if (insn_class == TRAP_RISKY || insn_class == IRISKY)
- break;
- }
- }
- else
- {
- code = GET_CODE (pat);
- switch (code)
- {
- case CLOBBER:
- /* Test if it is a 'store'. */
- tmp_class = may_trap_exp (XEXP (pat, 0), 1);
- break;
- case SET:
- /* Test if it is a store. */
- tmp_class = may_trap_exp (SET_DEST (pat), 1);
- if (tmp_class == TRAP_RISKY)
- break;
- /* Test if it is a load. */
- tmp_class =
- WORST_CLASS (tmp_class,
- may_trap_exp (SET_SRC (pat), 0));
- break;
- case COND_EXEC:
- case TRAP_IF:
- tmp_class = TRAP_RISKY;
- break;
- default:;
- }
- insn_class = tmp_class;
- }
-
- return insn_class;
-}
-
/* Return 1 if load_insn is prisky (i.e. if load_insn is fed by
a load moved speculatively, or if load_insn is protected by
a compare on load_insn's address). */
static int
-is_prisky (load_insn, bb_src, bb_trg)
- rtx load_insn;
- int bb_src, bb_trg;
+is_prisky (rtx load_insn, int bb_src, int bb_trg)
{
if (FED_BY_SPEC_LOAD (load_insn))
return 1;
@@ -1909,9 +1646,7 @@ is_prisky (load_insn, bb_src, bb_trg)
and 0 otherwise. */
static int
-is_exception_free (insn, bb_src, bb_trg)
- rtx insn;
- int bb_src, bb_trg;
+is_exception_free (rtx insn, int bb_src, int bb_trg)
{
int insn_class = haifa_classify_insn (insn);
@@ -1960,20 +1695,19 @@ static int sched_n_insns;
static int last_was_jump;
/* Implementations of the sched_info functions for region scheduling. */
-static void init_ready_list PARAMS ((struct ready_list *));
-static int can_schedule_ready_p PARAMS ((rtx));
-static int new_ready PARAMS ((rtx));
-static int schedule_more_p PARAMS ((void));
-static const char *rgn_print_insn PARAMS ((rtx, int));
-static int rgn_rank PARAMS ((rtx, rtx));
-static int contributes_to_priority PARAMS ((rtx, rtx));
-static void compute_jump_reg_dependencies PARAMS ((rtx, regset, regset,
- regset));
+static void init_ready_list (struct ready_list *);
+static int can_schedule_ready_p (rtx);
+static int new_ready (rtx);
+static int schedule_more_p (void);
+static const char *rgn_print_insn (rtx, int);
+static int rgn_rank (rtx, rtx);
+static int contributes_to_priority (rtx, rtx);
+static void compute_jump_reg_dependencies (rtx, regset, regset, regset);
/* Return nonzero if there are more insns that should be scheduled. */
static int
-schedule_more_p ()
+schedule_more_p (void)
{
return ! last_was_jump && sched_target_n_insns < target_n_insns;
}
@@ -1982,8 +1716,7 @@ schedule_more_p ()
once before scheduling a set of insns. */
static void
-init_ready_list (ready)
- struct ready_list *ready;
+init_ready_list (struct ready_list *ready)
{
rtx prev_head = current_sched_info->prev_head;
rtx next_tail = current_sched_info->next_tail;
@@ -2002,8 +1735,7 @@ init_ready_list (ready)
/* Prepare current target block info. */
if (current_nr_blocks > 1)
{
- candidate_table = (candidate *) xmalloc (current_nr_blocks
- * sizeof (candidate));
+ candidate_table = xmalloc (current_nr_blocks * sizeof (candidate));
bblst_last = 0;
/* bblst_table holds split blocks and update blocks for each block after
@@ -2011,11 +1743,10 @@ init_ready_list (ready)
the TO blocks of region edges, so there can be at most rgn_nr_edges
of them. */
bblst_size = (current_nr_blocks - target_bb) * rgn_nr_edges;
- bblst_table = (int *) xmalloc (bblst_size * sizeof (int));
+ bblst_table = xmalloc (bblst_size * sizeof (int));
bitlst_table_last = 0;
- bitlst_table_size = rgn_nr_edges;
- bitlst_table = (int *) xmalloc (rgn_nr_edges * sizeof (int));
+ bitlst_table = xmalloc (rgn_nr_edges * sizeof (int));
compute_trg_info (target_bb);
}
@@ -2024,17 +1755,15 @@ init_ready_list (ready)
Count number of insns in the target block being scheduled. */
for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
{
- rtx next;
-
- if (! INSN_P (insn))
- continue;
- next = NEXT_INSN (insn);
+ if (INSN_DEP_COUNT (insn) == 0)
+ {
+ ready_add (ready, insn);
- if (INSN_DEP_COUNT (insn) == 0
- && (! INSN_P (next) || SCHED_GROUP_P (next) == 0))
- ready_add (ready, insn);
- if (!(SCHED_GROUP_P (insn)))
- target_n_insns++;
+ if (targetm.sched.adjust_priority)
+ INSN_PRIORITY (insn) =
+ (*targetm.sched.adjust_priority) (insn, INSN_PRIORITY (insn));
+ }
+ target_n_insns++;
}
/* Add to ready list all 'ready' insns in valid source blocks.
@@ -2068,19 +1797,14 @@ init_ready_list (ready)
insn, insn) <= 3)))
&& check_live (insn, bb_src)
&& is_exception_free (insn, bb_src, target_bb))))
- {
- rtx next;
-
- /* Note that we haven't squirreled away the notes for
- blocks other than the current. So if this is a
- speculative insn, NEXT might otherwise be a note. */
- next = next_nonnote_insn (insn);
- if (INSN_DEP_COUNT (insn) == 0
- && (! next
- || ! INSN_P (next)
- || SCHED_GROUP_P (next) == 0))
- ready_add (ready, insn);
- }
+ if (INSN_DEP_COUNT (insn) == 0)
+ {
+ ready_add (ready, insn);
+
+ if (targetm.sched.adjust_priority)
+ INSN_PRIORITY (insn) =
+ (*targetm.sched.adjust_priority) (insn, INSN_PRIORITY (insn));
+ }
}
}
}
@@ -2089,8 +1813,7 @@ init_ready_list (ready)
insn can be scheduled, nonzero if we should silently discard it. */
static int
-can_schedule_ready_p (insn)
- rtx insn;
+can_schedule_ready_p (rtx insn)
{
if (GET_CODE (insn) == JUMP_INSN)
last_was_jump = 1;
@@ -2098,7 +1821,6 @@ can_schedule_ready_p (insn)
/* An interblock motion? */
if (INSN_BB (insn) != target_bb)
{
- rtx temp;
basic_block b1;
if (IS_SPECULATIVE_INSN (insn))
@@ -2115,39 +1837,30 @@ can_schedule_ready_p (insn)
}
nr_inter++;
- /* Find the beginning of the scheduling group. */
- /* ??? Ought to update basic block here, but later bits of
- schedule_block assumes the original insn block is
- still intact. */
-
- temp = insn;
- while (SCHED_GROUP_P (temp))
- temp = PREV_INSN (temp);
-
/* Update source block boundaries. */
- b1 = BLOCK_FOR_INSN (temp);
- if (temp == b1->head && insn == b1->end)
+ b1 = BLOCK_FOR_INSN (insn);
+ if (insn == BB_HEAD (b1) && insn == BB_END (b1))
{
/* We moved all the insns in the basic block.
Emit a note after the last insn and update the
begin/end boundaries to point to the note. */
rtx note = emit_note_after (NOTE_INSN_DELETED, insn);
- b1->head = note;
- b1->end = note;
+ BB_HEAD (b1) = note;
+ BB_END (b1) = note;
}
- else if (insn == b1->end)
+ else if (insn == BB_END (b1))
{
/* We took insns from the end of the basic block,
so update the end of block boundary so that it
points to the first insn we did not move. */
- b1->end = PREV_INSN (temp);
+ BB_END (b1) = PREV_INSN (insn);
}
- else if (temp == b1->head)
+ else if (insn == BB_HEAD (b1))
{
/* We took insns from the start of the basic block,
so update the start of block boundary so that
it points to the first insn we did not move. */
- b1->head = NEXT_INSN (insn);
+ BB_HEAD (b1) = NEXT_INSN (insn);
}
}
else
@@ -2164,8 +1877,7 @@ can_schedule_ready_p (insn)
if it should be moved to the ready list or the queue, or zero if we
should silently discard it. */
static int
-new_ready (next)
- rtx next;
+new_ready (rtx next)
{
/* For speculative insns, before inserting to ready/queue,
check live, exception-free, and issue-delay. */
@@ -2194,9 +1906,7 @@ new_ready (next)
to be formatted so that multiple output lines will line up nicely. */
static const char *
-rgn_print_insn (insn, aligned)
- rtx insn;
- int aligned;
+rgn_print_insn (rtx insn, int aligned)
{
static char tmp[80];
@@ -2217,8 +1927,7 @@ rgn_print_insn (insn, aligned)
is to be preferred. Zero if they are equally good. */
static int
-rgn_rank (insn1, insn2)
- rtx insn1, insn2;
+rgn_rank (rtx insn1, rtx insn2)
{
/* Some comparison make sense in interblock scheduling only. */
if (INSN_BB (insn1) != INSN_BB (insn2))
@@ -2249,8 +1958,7 @@ rgn_rank (insn1, insn2)
calculations. */
static int
-contributes_to_priority (next, insn)
- rtx next, insn;
+contributes_to_priority (rtx next, rtx insn)
{
return BLOCK_NUM (next) == BLOCK_NUM (insn);
}
@@ -2261,11 +1969,10 @@ contributes_to_priority (next, insn)
registers that must be considered as set in SET. */
static void
-compute_jump_reg_dependencies (insn, cond_set, used, set)
- rtx insn ATTRIBUTE_UNUSED;
- regset cond_set ATTRIBUTE_UNUSED;
- regset used ATTRIBUTE_UNUSED;
- regset set ATTRIBUTE_UNUSED;
+compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED,
+ regset cond_exec ATTRIBUTE_UNUSED,
+ regset used ATTRIBUTE_UNUSED,
+ regset set ATTRIBUTE_UNUSED)
{
/* Nothing to do here, since we postprocess jumps in
add_branch_dependences. */
@@ -2287,14 +1994,13 @@ static struct sched_info region_sched_info =
NULL, NULL,
NULL, NULL,
- 0, 0
+ 0, 0, 0
};
/* Determine if PAT sets a CLASS_LIKELY_SPILLED_P register. */
static bool
-sets_likely_spilled (pat)
- rtx pat;
+sets_likely_spilled (rtx pat)
{
bool ret = false;
note_stores (pat, sets_likely_spilled_1, &ret);
@@ -2302,9 +2008,7 @@ sets_likely_spilled (pat)
}
static void
-sets_likely_spilled_1 (x, pat, data)
- rtx x, pat;
- void *data;
+sets_likely_spilled_1 (rtx x, rtx pat, void *data)
{
bool *ret = (bool *) data;
@@ -2319,8 +2023,7 @@ sets_likely_spilled_1 (x, pat, data)
block. */
static void
-add_branch_dependences (head, tail)
- rtx head, tail;
+add_branch_dependences (rtx head, rtx tail)
{
rtx insn, last;
@@ -2333,7 +2036,7 @@ add_branch_dependences (head, tail)
end since moving them results in worse register allocation. Uses remain
at the end to ensure proper register allocation.
- cc0 setters remaim at the end because they can't be moved away from
+ cc0 setters remain at the end because they can't be moved away from
their cc0 user.
Insns setting CLASS_LIKELY_SPILLED_P registers (usually return values)
@@ -2366,17 +2069,6 @@ add_branch_dependences (head, tail)
CANT_MOVE (insn) = 1;
last = insn;
- /* Skip over insns that are part of a group.
- Make each insn explicitly depend on the previous insn.
- This ensures that only the group header will ever enter
- the ready queue (and, when scheduled, will automatically
- schedule the SCHED_GROUP_P block). */
- while (SCHED_GROUP_P (insn))
- {
- rtx temp = prev_nonnote_insn (insn);
- add_dependence (insn, temp, REG_DEP_ANTI);
- insn = temp;
- }
}
/* Don't overrun the bounds of the basic block. */
@@ -2398,10 +2090,6 @@ add_branch_dependences (head, tail)
add_dependence (last, insn, REG_DEP_ANTI);
INSN_REF_COUNT (insn) = 1;
-
- /* Skip over insns that are part of a group. */
- while (SCHED_GROUP_P (insn))
- insn = prev_nonnote_insn (insn);
}
}
@@ -2416,8 +2104,7 @@ static struct deps *bb_deps;
/* Duplicate the INSN_LIST elements of COPY and prepend them to OLD. */
static rtx
-concat_INSN_LIST (copy, old)
- rtx copy, old;
+concat_INSN_LIST (rtx copy, rtx old)
{
rtx new = old;
for (; copy ; copy = XEXP (copy, 1))
@@ -2426,9 +2113,8 @@ concat_INSN_LIST (copy, old)
}
static void
-concat_insn_mem_list (copy_insns, copy_mems, old_insns_p, old_mems_p)
- rtx copy_insns, copy_mems;
- rtx *old_insns_p, *old_mems_p;
+concat_insn_mem_list (rtx copy_insns, rtx copy_mems, rtx *old_insns_p,
+ rtx *old_mems_p)
{
rtx new_insns = *old_insns_p;
rtx new_mems = *old_mems_p;
@@ -2448,9 +2134,7 @@ concat_insn_mem_list (copy_insns, copy_mems, old_insns_p, old_mems_p)
/* After computing the dependencies for block BB, propagate the dependencies
found in TMP_DEPS to the successors of the block. */
static void
-propagate_deps (bb, pred_deps)
- int bb;
- struct deps *pred_deps;
+propagate_deps (int bb, struct deps *pred_deps)
{
int b = BB_TO_BLOCK (bb);
int e, first_edge;
@@ -2536,7 +2220,7 @@ propagate_deps (bb, pred_deps)
/* Compute backward dependences inside bb. In a multiple blocks region:
(1) a bb is analyzed after its predecessors, and (2) the lists in
effect at the end of bb (after analyzing for bb) are inherited by
- bb's successrs.
+ bb's successors.
Specifically for reg-reg data dependences, the block insns are
scanned by sched_analyze () top-to-bottom. Two lists are
@@ -2551,8 +2235,7 @@ propagate_deps (bb, pred_deps)
similar, and the result is interblock dependences in the region. */
static void
-compute_block_backward_dependences (bb)
- int bb;
+compute_block_backward_dependences (int bb)
{
rtx head, tail;
struct deps tmp_deps;
@@ -2575,7 +2258,7 @@ compute_block_backward_dependences (bb)
them to the unused_*_list variables, so that they can be reused. */
static void
-free_pending_lists ()
+free_pending_lists (void)
{
int bb;
@@ -2591,7 +2274,7 @@ free_pending_lists ()
/* Print dependences for debugging, callable from debugger. */
void
-debug_dependencies ()
+debug_dependencies (void)
{
int bb;
@@ -2704,8 +2387,7 @@ debug_dependencies ()
scheduled after its flow predecessors. */
static void
-schedule_region (rgn)
- int rgn;
+schedule_region (int rgn)
{
int bb;
int rgn_n_insns = 0;
@@ -2717,8 +2399,8 @@ schedule_region (rgn)
init_deps_global ();
- /* Initializations for region data dependence analyisis. */
- bb_deps = (struct deps *) xmalloc (sizeof (struct deps) * current_nr_blocks);
+ /* Initializations for region data dependence analysis. */
+ bb_deps = xmalloc (sizeof (struct deps) * current_nr_blocks);
for (bb = 0; bb < current_nr_blocks; bb++)
init_deps (bb_deps + bb);
@@ -2733,6 +2415,10 @@ schedule_region (rgn)
get_block_head_tail (BB_TO_BLOCK (bb), &head, &tail);
compute_forward_dependences (head, tail);
+
+ if (targetm.sched.dependencies_evaluation_hook)
+ targetm.sched.dependencies_evaluation_hook (head, tail);
+
}
/* Set priorities. */
@@ -2749,17 +2435,17 @@ schedule_region (rgn)
{
int i;
- prob = (float *) xmalloc ((current_nr_blocks) * sizeof (float));
+ prob = xmalloc ((current_nr_blocks) * sizeof (float));
dom = sbitmap_vector_alloc (current_nr_blocks, current_nr_blocks);
sbitmap_vector_zero (dom, current_nr_blocks);
/* Edge to bit. */
rgn_nr_edges = 0;
- edge_to_bit = (int *) xmalloc (nr_edges * sizeof (int));
+ edge_to_bit = xmalloc (nr_edges * sizeof (int));
for (i = 1; i < nr_edges; i++)
if (CONTAINING_RGN (FROM_BLOCK (i)) == rgn)
EDGE_TO_BIT (i) = rgn_nr_edges++;
- rgn_edges = (int *) xmalloc (rgn_nr_edges * sizeof (int));
+ rgn_edges = xmalloc (rgn_nr_edges * sizeof (int));
rgn_nr_edges = 0;
for (i = 1; i < nr_edges; i++)
@@ -2799,7 +2485,7 @@ schedule_region (rgn)
/* rm_other_notes only removes notes which are _inside_ the
block---that is, it won't remove notes before the first real insn
- or after the last real insn of the block. So if the first insn
+ or after the last real insn of the block. So if the first insn
has a REG_SAVE_NOTE which would otherwise be emitted before the
insn, it is redundant with the note before the start of the
block, and so we have to take it out. */
@@ -2830,10 +2516,10 @@ schedule_region (rgn)
sched_rgn_n_insns += sched_n_insns;
/* Update target block boundaries. */
- if (head == BLOCK_HEAD (b))
- BLOCK_HEAD (b) = current_sched_info->head;
- if (tail == BLOCK_END (b))
- BLOCK_END (b) = current_sched_info->tail;
+ if (head == BB_HEAD (BASIC_BLOCK (b)))
+ BB_HEAD (BASIC_BLOCK (b)) = current_sched_info->head;
+ if (tail == BB_END (BASIC_BLOCK (b)))
+ BB_END (BASIC_BLOCK (b)) = current_sched_info->tail;
/* Clean up. */
if (current_nr_blocks > 1)
@@ -2884,16 +2570,16 @@ static int *deaths_in_region;
/* Initialize data structures for region scheduling. */
static void
-init_regions ()
+init_regions (void)
{
sbitmap blocks;
int rgn;
nr_regions = 0;
- rgn_table = (region *) xmalloc ((n_basic_blocks) * sizeof (region));
- rgn_bb_table = (int *) xmalloc ((n_basic_blocks) * sizeof (int));
- block_to_bb = (int *) xmalloc ((last_basic_block) * sizeof (int));
- containing_rgn = (int *) xmalloc ((last_basic_block) * sizeof (int));
+ rgn_table = xmalloc ((n_basic_blocks) * sizeof (region));
+ rgn_bb_table = xmalloc ((n_basic_blocks) * sizeof (int));
+ block_to_bb = xmalloc ((last_basic_block) * sizeof (int));
+ containing_rgn = xmalloc ((last_basic_block) * sizeof (int));
/* Compute regions for scheduling. */
if (reload_completed
@@ -2911,24 +2597,16 @@ init_regions ()
}
else
{
- dominance_info dom;
struct edge_list *edge_list;
- /* The scheduler runs after flow; therefore, we can't blindly call
- back into find_basic_blocks since doing so could invalidate the
- info in global_live_at_start.
-
- Consider a block consisting entirely of dead stores; after life
- analysis it would be a block of NOTE_INSN_DELETED notes. If
- we call find_basic_blocks again, then the block would be removed
- entirely and invalidate our the register live information.
-
- We could (should?) recompute register live information. Doing
- so may even be beneficial. */
+ /* The scheduler runs after estimate_probabilities; therefore, we
+ can't blindly call back into find_basic_blocks since doing so
+ could invalidate the branch probability info. We could,
+ however, call cleanup_cfg. */
edge_list = create_edge_list ();
/* Compute the dominators and post dominators. */
- dom = calculate_dominance_info (CDI_DOMINATORS);
+ calculate_dominance_info (CDI_DOMINATORS);
/* build_control_flow will return nonzero if it detects unreachable
blocks or any other irregularity with the cfg which prevents
@@ -2936,7 +2614,7 @@ init_regions ()
if (build_control_flow (edge_list) != 0)
find_single_block_region ();
else
- find_rgns (edge_list, dom);
+ find_rgns (edge_list);
if (sched_verbose >= 3)
debug_regions ();
@@ -2946,7 +2624,7 @@ init_regions ()
/* For now. This will move as more and more of haifa is converted
to using the cfg code in flow.c. */
- free_dominance_info (dom);
+ free_dominance_info (CDI_DOMINATORS);
}
}
@@ -2954,7 +2632,7 @@ init_regions ()
if (CHECK_DEAD_NOTES)
{
blocks = sbitmap_alloc (last_basic_block);
- deaths_in_region = (int *) xmalloc (sizeof (int) * nr_regions);
+ deaths_in_region = xmalloc (sizeof (int) * nr_regions);
/* Remove all death notes from the subroutine. */
for (rgn = 0; rgn < nr_regions; rgn++)
{
@@ -2976,8 +2654,7 @@ init_regions ()
this pass. */
void
-schedule_insns (dump_file)
- FILE *dump_file;
+schedule_insns (FILE *dump_file)
{
sbitmap large_region_blocks, blocks;
int rgn;
diff --git a/contrib/gcc/sched-vis.c b/contrib/gcc/sched-vis.c
index 237d4460d51a..9174c8bf2ff5 100644
--- a/contrib/gcc/sched-vis.c
+++ b/contrib/gcc/sched-vis.c
@@ -1,6 +1,6 @@
/* Instruction scheduling pass.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
and currently maintained by, Jim Wilson (wilson@cygnus.com)
@@ -23,6 +23,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "rtl.h"
#include "tm_p.h"
@@ -45,17 +47,16 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
static int target_units = 0;
-static char *safe_concat PARAMS ((char *, char *, const char *));
-static int get_visual_tbl_length PARAMS ((void));
-static void print_exp PARAMS ((char *, rtx, int));
-static void print_value PARAMS ((char *, rtx, int));
-static void print_pattern PARAMS ((char *, rtx, int));
+static char *safe_concat (char *, char *, const char *);
+static int get_visual_tbl_length (void);
+static void print_exp (char *, rtx, int);
+static void print_value (char *, rtx, int);
+static void print_pattern (char *, rtx, int);
/* Print names of units on which insn can/should execute, for debugging. */
void
-insn_print_units (insn)
- rtx insn;
+insn_print_units (rtx insn)
{
int i;
int unit = insn_unit (insn);
@@ -79,7 +80,7 @@ insn_print_units (insn)
}
/* MAX_VISUAL_LINES is the maximum number of lines in visualization table
- of a basic block. If more lines are needed, table is splitted to two.
+ of a basic block. If more lines are needed, table is split to two.
n_visual_lines is the number of lines printed so far for a block.
visual_tbl contains the block visualization info.
vis_no_unit holds insns in a cycle that are not mapped to any unit. */
@@ -96,7 +97,7 @@ rtx vis_no_unit[MAX_VISUAL_NO_UNIT];
for visualization. */
void
-init_target_units ()
+init_target_units (void)
{
rtx insn;
int unit;
@@ -118,7 +119,7 @@ init_target_units ()
/* Return the length of the visualization table. */
static int
-get_visual_tbl_length ()
+get_visual_tbl_length (void)
{
int unit, i;
int n, n1;
@@ -133,7 +134,7 @@ get_visual_tbl_length ()
}
/* Compute length of one field in line. */
- s = (char *) alloca (INSN_LEN + 6);
+ s = alloca (INSN_LEN + 6);
sprintf (s, " %33s", "uname");
n1 = strlen (s);
@@ -156,7 +157,7 @@ get_visual_tbl_length ()
/* Init block visualization debugging info. */
void
-init_block_visualization ()
+init_block_visualization (void)
{
strcpy (visual_tbl, "");
n_visual_lines = 0;
@@ -166,10 +167,7 @@ init_block_visualization ()
#define BUF_LEN 2048
static char *
-safe_concat (buf, cur, str)
- char *buf;
- char *cur;
- const char *str;
+safe_concat (char *buf, char *cur, const char *str)
{
char *end = buf + BUF_LEN - 2; /* Leave room for null. */
int c;
@@ -192,10 +190,7 @@ safe_concat (buf, cur, str)
may be stored in objects representing values. */
static void
-print_exp (buf, x, verbose)
- char *buf;
- rtx x;
- int verbose;
+print_exp (char *buf, rtx x, int verbose)
{
char tmp[BUF_LEN];
const char *st[4];
@@ -542,14 +537,11 @@ print_exp (buf, x, verbose)
cur = safe_concat (buf, cur, ")");
} /* print_exp */
-/* Prints rtxes, I customly classified as values. They're constants,
+/* Prints rtxes, I customarily classified as values. They're constants,
registers, labels, symbols and memory accesses. */
static void
-print_value (buf, x, verbose)
- char *buf;
- rtx x;
- int verbose;
+print_value (char *buf, rtx x, int verbose)
{
char t[BUF_LEN];
char *cur = buf;
@@ -639,10 +631,7 @@ print_value (buf, x, verbose)
/* The next step in insn detalization, its pattern recognition. */
static void
-print_pattern (buf, x, verbose)
- char *buf;
- rtx x;
- int verbose;
+print_pattern (char *buf, rtx x, int verbose)
{
char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
@@ -753,10 +742,7 @@ print_pattern (buf, x, verbose)
depends now on sched.c inner variables ...) */
void
-print_insn (buf, x, verbose)
- char *buf;
- rtx x;
- int verbose;
+print_insn (char *buf, rtx x, int verbose)
{
char t[BUF_LEN];
rtx insn = x;
@@ -822,8 +808,7 @@ print_insn (buf, x, verbose)
description should never use the following function. */
void
-print_block_visualization (s)
- const char *s;
+print_block_visualization (const char *s)
{
int unit, i;
@@ -852,8 +837,7 @@ print_block_visualization (s)
/* Print insns in the 'no_unit' column of visualization. */
void
-visualize_no_unit (insn)
- rtx insn;
+visualize_no_unit (rtx insn)
{
if (n_vis_no_unit < MAX_VISUAL_NO_UNIT)
{
@@ -865,8 +849,7 @@ visualize_no_unit (insn)
/* Print insns scheduled in clock, for visualization. */
void
-visualize_scheduled_insns (clock)
- int clock;
+visualize_scheduled_insns (int clock)
{
int i, unit;
@@ -912,8 +895,7 @@ visualize_scheduled_insns (clock)
/* Print stalled cycles. */
void
-visualize_stall_cycles (stalls)
- int stalls;
+visualize_stall_cycles (int stalls)
{
static const char *const prefix = ";; ";
const char *suffix = "\n";
@@ -948,7 +930,7 @@ visualize_stall_cycles (stalls)
/* Allocate data used for visualization during scheduling. */
void
-visualize_alloc ()
+visualize_alloc (void)
{
visual_tbl = xmalloc (get_visual_tbl_length ());
}
@@ -956,7 +938,7 @@ visualize_alloc ()
/* Free data used for visualization. */
void
-visualize_free ()
+visualize_free (void)
{
free (visual_tbl);
}
diff --git a/contrib/gcc/sdbout.c b/contrib/gcc/sdbout.c
index 9d5effd6f6ea..3d6204753150 100644
--- a/contrib/gcc/sdbout.c
+++ b/contrib/gcc/sdbout.c
@@ -1,6 +1,6 @@
/* Output sdb-format symbol table information from GNU compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -43,12 +43,22 @@ AT&T C compiler. From the example below I would conclude the following:
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "debug.h"
#include "tree.h"
#include "ggc.h"
static GTY(()) tree anonymous_types;
+/* Counter for sdbout_source_line. */
+
+static GTY(()) int sdbout_source_line_counter;
+
+/* Counter to generate unique "names" for nameless struct members. */
+
+static GTY(()) int unnamed_struct_number;
+
#ifdef SDB_DEBUGGING_INFO
#include "rtl.h"
@@ -61,6 +71,7 @@ static GTY(()) tree anonymous_types;
#include "tm_p.h"
#include "gsyms.h"
#include "langhooks.h"
+#include "target.h"
/* 1 if PARM is passed to this function in memory. */
@@ -85,9 +96,6 @@ static GTY(()) tree anonymous_types;
int sdb_begin_function_line = -1;
-/* Counter to generate unique "names" for nameless struct members. */
-
-static int unnamed_struct_number = 0;
extern FILE *asm_out_file;
@@ -95,45 +103,42 @@ extern tree current_function_decl;
#include "sdbout.h"
-static void sdbout_init PARAMS ((const char *));
-static void sdbout_finish PARAMS ((const char *));
-static void sdbout_start_source_file PARAMS ((unsigned int, const char *));
-static void sdbout_end_source_file PARAMS ((unsigned int));
-static void sdbout_begin_block PARAMS ((unsigned int, unsigned int));
-static void sdbout_end_block PARAMS ((unsigned int, unsigned int));
-static void sdbout_source_line PARAMS ((unsigned int, const char *));
-static void sdbout_end_epilogue PARAMS ((unsigned int, const char *));
-static void sdbout_global_decl PARAMS ((tree));
+static void sdbout_init (const char *);
+static void sdbout_finish (const char *);
+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_end_epilogue (unsigned int, const char *);
+static void sdbout_global_decl (tree);
#ifndef MIPS_DEBUGGING_INFO
-static void sdbout_begin_prologue PARAMS ((unsigned int, const char *));
+static void sdbout_begin_prologue (unsigned int, const char *);
#endif
-static void sdbout_end_prologue PARAMS ((unsigned int, const char *));
-static void sdbout_begin_function PARAMS ((tree));
-static void sdbout_end_function PARAMS ((unsigned int));
-static void sdbout_toplevel_data PARAMS ((tree));
-static void sdbout_label PARAMS ((rtx));
-static char *gen_fake_label PARAMS ((void));
-static int plain_type PARAMS ((tree));
-static int template_name_p PARAMS ((tree));
-static void sdbout_record_type_name PARAMS ((tree));
-static int plain_type_1 PARAMS ((tree, int));
-static void sdbout_block PARAMS ((tree));
-static void sdbout_syms PARAMS ((tree));
+static void sdbout_end_prologue (unsigned int, const char *);
+static void sdbout_begin_function (tree);
+static void sdbout_end_function (unsigned int);
+static void sdbout_toplevel_data (tree);
+static void sdbout_label (rtx);
+static char *gen_fake_label (void);
+static int plain_type (tree);
+static int template_name_p (tree);
+static void sdbout_record_type_name (tree);
+static int plain_type_1 (tree, int);
+static void sdbout_block (tree);
+static void sdbout_syms (tree);
#ifdef SDB_ALLOW_FORWARD_REFERENCES
-static void sdbout_queue_anonymous_type PARAMS ((tree));
-static void sdbout_dequeue_anonymous_types PARAMS ((void));
+static void sdbout_queue_anonymous_type (tree);
+static void sdbout_dequeue_anonymous_types (void);
#endif
-static void sdbout_type PARAMS ((tree));
-static void sdbout_field_types PARAMS ((tree));
-static void sdbout_one_type PARAMS ((tree));
-static void sdbout_parms PARAMS ((tree));
-static void sdbout_reg_parms PARAMS ((tree));
-static void sdbout_global_decl PARAMS ((tree));
-
-/* Random macros describing parts of SDB data. */
+static void sdbout_type (tree);
+static void sdbout_field_types (tree);
+static void sdbout_one_type (tree);
+static void sdbout_parms (tree);
+static void sdbout_reg_parms (tree);
+static void sdbout_global_decl (tree);
-/* Put something here if lines get too long */
-#define CONTIN
+/* Random macros describing parts of SDB data. */
/* Default value of delimiter is ";". */
#ifndef SDB_DELIM
@@ -152,9 +157,8 @@ static void sdbout_global_decl PARAMS ((tree));
#ifndef PUT_SDB_INT_VAL
#define PUT_SDB_INT_VAL(a) \
do { \
- fputs ("\t.val\t", asm_out_file); \
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) (a)); \
- fprintf (asm_out_file, "%s", SDB_DELIM); \
+ fprintf (asm_out_file, "\t.val\t" HOST_WIDE_INT_PRINT_DEC "%s", \
+ (HOST_WIDE_INT) (a), SDB_DELIM); \
} while (0)
#endif
@@ -169,7 +173,7 @@ static void sdbout_global_decl PARAMS ((tree));
#ifndef PUT_SDB_DEF
#define PUT_SDB_DEF(a) \
do { fprintf (asm_out_file, "\t.def\t"); \
- assemble_name (asm_out_file, a); \
+ assemble_name (asm_out_file, a); \
fprintf (asm_out_file, SDB_DELIM); } while (0)
#endif
@@ -188,9 +192,8 @@ do { fprintf (asm_out_file, "\t.def\t"); \
#ifndef PUT_SDB_SIZE
#define PUT_SDB_SIZE(a) \
do { \
- fputs ("\t.size\t", asm_out_file); \
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT) (a)); \
- fprintf (asm_out_file, "%s", SDB_DELIM); \
+ fprintf (asm_out_file, "\t.size\t" HOST_WIDE_INT_PRINT_DEC "%s", \
+ (HOST_WIDE_INT) (a), SDB_DELIM); \
} while(0)
#endif
@@ -254,7 +257,7 @@ do { fprintf (asm_out_file, "\t.tag\t"); \
/* Set the sdb tag identifier string for TYPE to NAME. */
#define SET_KNOWN_TYPE_TAG(TYPE, NAME) \
- TYPE_SYMTAB_POINTER (TYPE) = (NAME)
+ TYPE_SYMTAB_POINTER (TYPE) = (char *)(NAME)
/* Return the name (a string) of the struct, union or enum tag
described by the TREE_LIST node LINK. This is 0 for an anonymous one. */
@@ -300,7 +303,7 @@ struct sdb_file
static struct sdb_file *current_file;
#endif /* MIPS_DEBUGGING_INFO */
-
+
/* The debug hooks structure. */
const struct gcc_debug_hooks sdb_debug_hooks =
{
@@ -330,32 +333,14 @@ const struct gcc_debug_hooks sdb_debug_hooks =
sdbout_global_decl, /* global_decl */
debug_nothing_tree, /* deferred_inline_function */
debug_nothing_tree, /* outlining_inline_function */
- sdbout_label
+ sdbout_label, /* label */
+ debug_nothing_int /* handle_pch */
};
-
-#if 0
-
-/* return the tag identifier for type
- */
-
-char *
-tag_of_ru_type (type,link)
- tree type,link;
-{
- if (TYPE_SYMTAB_ADDRESS (type))
- return TYPE_SYMTAB_ADDRESS (type);
- if (link && TREE_PURPOSE (link)
- && IDENTIFIER_POINTER (TREE_PURPOSE (link)))
- TYPE_SYMTAB_ADDRESS (type) = IDENTIFIER_POINTER (TREE_PURPOSE (link));
- else
- return (char *) TYPE_SYMTAB_ADDRESS (type);
-}
-#endif
/* Return a unique string to name an anonymous type. */
static char *
-gen_fake_label ()
+gen_fake_label (void)
{
char label[10];
char *labelstr;
@@ -364,7 +349,7 @@ gen_fake_label ()
labelstr = xstrdup (label);
return labelstr;
}
-
+
/* Return the number which describes TYPE for SDB.
For pointers, etc., this function is recursive.
Each record, union or enumeral type must already have had a
@@ -397,8 +382,7 @@ static int sdb_dims[SDB_MAX_DIM];
static int sdb_type_size = -1;
static int
-plain_type (type)
- tree type;
+plain_type (tree type)
{
int val = plain_type_1 (type, 0);
@@ -428,8 +412,7 @@ plain_type (type)
}
static int
-template_name_p (name)
- tree name;
+template_name_p (tree name)
{
const char *ptr = IDENTIFIER_POINTER (name);
while (*ptr && *ptr != '<')
@@ -439,8 +422,7 @@ template_name_p (name)
}
static void
-sdbout_record_type_name (type)
- tree type;
+sdbout_record_type_name (tree type)
{
const char *name = 0;
int no_name;
@@ -490,9 +472,7 @@ sdbout_record_type_name (type)
infinite loop. */
static int
-plain_type_1 (type, level)
- tree type;
- int level;
+plain_type_1 (tree type, int level)
{
if (type == 0)
type = void_type_node;
@@ -654,7 +634,7 @@ plain_type_1 (type, level)
return 0;
}
}
-
+
/* Output the symbols defined in block number DO_BLOCK.
This function works by walking the tree structure of blocks,
@@ -663,8 +643,7 @@ plain_type_1 (type, level)
static int do_block = 0;
static void
-sdbout_block (block)
- tree block;
+sdbout_block (tree block)
{
while (block)
{
@@ -686,12 +665,11 @@ sdbout_block (block)
block = BLOCK_CHAIN (block);
}
}
-
+
/* Call sdbout_symbol on each decl in the chain SYMS. */
static void
-sdbout_syms (syms)
- tree syms;
+sdbout_syms (tree syms)
{
while (syms)
{
@@ -705,9 +683,7 @@ sdbout_syms (syms)
LOCAL is nonzero if the symbol is not file-scope. */
void
-sdbout_symbol (decl, local)
- tree decl;
- int local;
+sdbout_symbol (tree decl, int local)
{
tree type = TREE_TYPE (decl);
tree context = NULL_TREE;
@@ -717,12 +693,6 @@ sdbout_symbol (decl, local)
sdbout_one_type (type);
-#if 0 /* This loses when functions are marked to be ignored,
- which happens in the C++ front end. */
- if (DECL_IGNORED_P (decl))
- return;
-#endif
-
switch (TREE_CODE (decl))
{
case CONST_DECL:
@@ -937,13 +907,12 @@ sdbout_symbol (decl, local)
PUT_SDB_TYPE (plain_type (type));
PUT_SDB_ENDEF;
}
-
+
/* Output SDB information for a top-level initialized variable
that has been delayed. */
static void
-sdbout_toplevel_data (decl)
- tree decl;
+sdbout_toplevel_data (tree decl)
{
tree type = TREE_TYPE (decl);
@@ -968,20 +937,19 @@ sdbout_toplevel_data (decl)
PUT_SDB_TYPE (plain_type (type));
PUT_SDB_ENDEF;
}
-
+
#ifdef SDB_ALLOW_FORWARD_REFERENCES
/* Machinery to record and output anonymous types. */
static void
-sdbout_queue_anonymous_type (type)
- tree type;
+sdbout_queue_anonymous_type (tree type)
{
anonymous_types = tree_cons (NULL_TREE, type, anonymous_types);
}
static void
-sdbout_dequeue_anonymous_types ()
+sdbout_dequeue_anonymous_types (void)
{
tree types, link;
@@ -1001,13 +969,12 @@ sdbout_dequeue_anonymous_types ()
}
#endif
-
+
/* Given a chain of ..._TYPE nodes, all of which have names,
output definitions of those names, as typedefs. */
void
-sdbout_types (types)
- tree types;
+sdbout_types (tree types)
{
tree link;
@@ -1020,8 +987,7 @@ sdbout_types (types)
}
static void
-sdbout_type (type)
- tree type;
+sdbout_type (tree type)
{
if (type == error_mark_node)
type = integer_type_node;
@@ -1035,8 +1001,7 @@ sdbout_type (type)
Now james@bigtex.cactus.org says to try them. */
static void
-sdbout_field_types (type)
- tree type;
+sdbout_field_types (tree type)
{
tree tail;
@@ -1064,8 +1029,7 @@ sdbout_field_types (type)
It may NOT be called recursively. */
static void
-sdbout_one_type (type)
- tree type;
+sdbout_one_type (tree type)
{
if (current_function_decl != NULL_TREE
&& DECL_SECTION_NAME (current_function_decl) != NULL_TREE)
@@ -1090,11 +1054,11 @@ sdbout_one_type (type)
return;
TREE_ASM_WRITTEN (type) = 1;
-#if 1
+
/* This is reputed to cause trouble with the following case,
but perhaps checking TYPE_SIZE above will fix it. */
- /* Here is a test case:
+ /* Here is a testcase:
struct foo {
struct badstr *bbb;
@@ -1108,9 +1072,6 @@ sdbout_one_type (type)
int ccccc;
} badtype; */
-#if 0
- TREE_ASM_BEING_WRITTEN (type) = 1;
-#endif
/* This change, which ought to make better output,
used to make the COFF assembler unhappy.
Changes involving KNOWN_TYPE_TAG may fix the problem. */
@@ -1119,10 +1080,6 @@ sdbout_one_type (type)
are not used if forward references are in use. */
if (TREE_CODE (type) != ENUMERAL_TYPE)
sdbout_field_types (type);
-#if 0
- TREE_ASM_WRITTEN (type) = 1;
-#endif
-#endif
/* Output a structure type. */
{
@@ -1194,7 +1151,6 @@ sdbout_one_type (type)
else
continue;
- CONTIN;
PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name));
PUT_SDB_INT_VAL (tree_low_cst (BINFO_OFFSET (child), 0));
PUT_SDB_SCL (member_scl);
@@ -1203,7 +1159,7 @@ sdbout_one_type (type)
}
}
- /* output the individual fields */
+ /* Output the individual fields. */
if (TREE_CODE (type) == ENUMERAL_TYPE)
{
@@ -1233,7 +1189,6 @@ sdbout_one_type (type)
{
const char *name;
- CONTIN;
name = IDENTIFIER_POINTER (DECL_NAME (tem));
PUT_SDB_DEF (name);
if (DECL_BIT_FIELD_TYPE (tem))
@@ -1251,7 +1206,7 @@ sdbout_one_type (type)
}
PUT_SDB_ENDEF;
}
- /* output end of a structure,union, or enumeral definition */
+ /* Output end of a structure,union, or enumeral definition. */
PUT_SDB_PLAIN_DEF ("eos");
PUT_SDB_INT_VAL (size);
@@ -1266,7 +1221,7 @@ sdbout_one_type (type)
}
}
}
-
+
/* The following two functions output definitions of function parameters.
Each parameter gets a definition locating it in the parameter list.
Each parameter that is a register variable gets a second definition
@@ -1280,8 +1235,7 @@ sdbout_one_type (type)
of all the parms in PARMS, which is a chain of PARM_DECL nodes. */
static void
-sdbout_parms (parms)
- tree parms;
+sdbout_parms (tree parms)
{
for (; parms; parms = TREE_CHAIN (parms))
if (DECL_NAME (parms))
@@ -1413,8 +1367,7 @@ sdbout_parms (parms)
PARMS is a chain of PARM_DECL nodes. */
static void
-sdbout_reg_parms (parms)
- tree parms;
+sdbout_reg_parms (tree parms)
{
for (; parms; parms = TREE_CHAIN (parms))
if (DECL_NAME (parms))
@@ -1467,13 +1420,12 @@ sdbout_reg_parms (parms)
}
}
}
-
+
/* Output debug information for a global DECL. Called from toplev.c
after compilation proper has finished. */
static void
-sdbout_global_decl (decl)
- tree decl;
+sdbout_global_decl (tree decl)
{
if (TREE_CODE (decl) == VAR_DECL
&& !DECL_EXTERNAL (decl)
@@ -1496,12 +1448,11 @@ sdbout_global_decl (decl)
definition. See comment in sdbout_global_decl. */
static void
-sdbout_finish (main_filename)
- const char *main_filename ATTRIBUTE_UNUSED;
+sdbout_finish (const char *main_filename ATTRIBUTE_UNUSED)
{
tree decl = (*lang_hooks.decls.getdecls) ();
unsigned int len = list_length (decl);
- tree *vec = (tree *) xmalloc (sizeof (tree) * len);
+ tree *vec = xmalloc (sizeof (tree) * len);
unsigned int i;
/* Process the decls in reverse order--earliest first. Put them
@@ -1523,7 +1474,7 @@ sdbout_finish (main_filename)
free (vec);
}
-
+
/* Describe the beginning of an internal block within a function.
Also output descriptions of variables defined in this block.
@@ -1533,9 +1484,7 @@ sdbout_finish (main_filename)
if the count starts at 0 for the outermost one. */
static void
-sdbout_begin_block (line, n)
- unsigned int line;
- unsigned int n;
+sdbout_begin_block (unsigned int line, unsigned int n)
{
tree decl = current_function_decl;
MAKE_LINE_SAFE (line);
@@ -1570,9 +1519,7 @@ sdbout_begin_block (line, n)
/* Describe the end line-number of an internal block within a function. */
static void
-sdbout_end_block (line, n)
- unsigned int line;
- unsigned int n ATTRIBUTE_UNUSED;
+sdbout_end_block (unsigned int line, unsigned int n ATTRIBUTE_UNUSED)
{
MAKE_LINE_SAFE (line);
@@ -1585,16 +1532,18 @@ sdbout_end_block (line, n)
PUT_SDB_BLOCK_END (line - sdb_begin_function_line);
}
+/* Output a line number symbol entry for source file FILENAME and line
+ number LINE. */
+
static void
-sdbout_source_line (line, filename)
- unsigned int line;
- const char *filename ATTRIBUTE_UNUSED;
+sdbout_source_line (unsigned int line, const char *filename ATTRIBUTE_UNUSED)
{
/* COFF relative line numbers must be positive. */
if ((int) line > sdb_begin_function_line)
{
#ifdef ASM_OUTPUT_SOURCE_LINE
- ASM_OUTPUT_SOURCE_LINE (asm_out_file, line);
+ sdbout_source_line_counter += 1;
+ ASM_OUTPUT_SOURCE_LINE (asm_out_file, line, sdbout_source_line_counter);
#else
fprintf (asm_out_file, "\t.ln\t%d\n",
((sdb_begin_function_line > -1)
@@ -1607,8 +1556,7 @@ sdbout_source_line (line, filename)
Called from assemble_start_function. */
static void
-sdbout_begin_function (decl)
- tree decl ATTRIBUTE_UNUSED;
+sdbout_begin_function (tree decl ATTRIBUTE_UNUSED)
{
sdbout_symbol (current_function_decl, 0);
}
@@ -1621,18 +1569,14 @@ sdbout_begin_function (decl)
#ifndef MIPS_DEBUGGING_INFO
static void
-sdbout_begin_prologue (line, file)
- unsigned int line;
- const char *file ATTRIBUTE_UNUSED;
+sdbout_begin_prologue (unsigned int line, const char *file ATTRIBUTE_UNUSED)
{
sdbout_end_prologue (line, file);
}
#endif
static void
-sdbout_end_prologue (line, file)
- unsigned int line;
- const char *file ATTRIBUTE_UNUSED;
+sdbout_end_prologue (unsigned int line, const char *file ATTRIBUTE_UNUSED)
{
sdb_begin_function_line = line - 1;
PUT_SDB_FUNCTION_START (line);
@@ -1644,8 +1588,7 @@ sdbout_end_prologue (line, file)
Describe end of outermost block. */
static void
-sdbout_end_function (line)
- unsigned int line;
+sdbout_end_function (unsigned int line)
{
#ifdef SDB_ALLOW_FORWARD_REFERENCES
sdbout_dequeue_anonymous_types ();
@@ -1662,9 +1605,8 @@ sdbout_end_function (line)
Called after the epilogue is output. */
static void
-sdbout_end_epilogue (line, file)
- unsigned int line ATTRIBUTE_UNUSED;
- const char *file ATTRIBUTE_UNUSED;
+sdbout_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
+ const char *file ATTRIBUTE_UNUSED)
{
const char *const name ATTRIBUTE_UNUSED
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
@@ -1683,8 +1625,7 @@ sdbout_end_epilogue (line, file)
is present. */
static void
-sdbout_label (insn)
- rtx insn;
+sdbout_label (rtx insn)
{
PUT_SDB_DEF (LABEL_NAME (insn));
PUT_SDB_VAL (insn);
@@ -1696,12 +1637,11 @@ sdbout_label (insn)
/* Change to reading from a new source file. */
static void
-sdbout_start_source_file (line, filename)
- unsigned int line ATTRIBUTE_UNUSED;
- const char *filename ATTRIBUTE_UNUSED;
+sdbout_start_source_file (unsigned int line ATTRIBUTE_UNUSED,
+ const char *filename ATTRIBUTE_UNUSED)
{
#ifdef MIPS_DEBUGGING_INFO
- struct sdb_file *n = (struct sdb_file *) xmalloc (sizeof *n);
+ struct sdb_file *n = xmalloc (sizeof *n);
n->next = current_file;
n->name = filename;
@@ -1713,8 +1653,7 @@ sdbout_start_source_file (line, filename)
/* Revert to reading a previous source file. */
static void
-sdbout_end_source_file (line)
- unsigned int line ATTRIBUTE_UNUSED;
+sdbout_end_source_file (unsigned int line ATTRIBUTE_UNUSED)
{
#ifdef MIPS_DEBUGGING_INFO
struct sdb_file *next;
@@ -1729,22 +1668,13 @@ sdbout_end_source_file (line)
/* Set up for SDB output at the start of compilation. */
static void
-sdbout_init (input_file_name)
- const char *input_file_name ATTRIBUTE_UNUSED;
+sdbout_init (const char *input_file_name ATTRIBUTE_UNUSED)
{
#ifdef MIPS_DEBUGGING_INFO
- current_file = (struct sdb_file *) xmalloc (sizeof *current_file);
+ current_file = xmalloc (sizeof *current_file);
current_file->next = NULL;
current_file->name = input_file_name;
#endif
-
-#ifdef RMS_QUICK_HACK_1
- tree t;
- for (t = (*lang_hooks.decls.getdecls) (); t; t = TREE_CHAIN (t))
- if (DECL_NAME (t) && IDENTIFIER_POINTER (DECL_NAME (t)) != 0
- && !strcmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__vtbl_ptr_type"))
- sdbout_symbol (t, 0);
-#endif
}
#else /* SDB_DEBUGGING_INFO */
diff --git a/contrib/gcc/sdbout.h b/contrib/gcc/sdbout.h
index 92d9a73b4e76..5f2b47931e49 100644
--- a/contrib/gcc/sdbout.h
+++ b/contrib/gcc/sdbout.h
@@ -1,5 +1,5 @@
/* sdbout.h - Various declarations for functions found in sdbout.c
- Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2000, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -18,5 +18,5 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-extern void sdbout_symbol PARAMS ((tree, int));
-extern void sdbout_types PARAMS ((tree));
+extern void sdbout_symbol (tree, int);
+extern void sdbout_types (tree);
diff --git a/contrib/gcc/sibcall.c b/contrib/gcc/sibcall.c
index 90863b7142b3..81509ee9b56e 100644
--- a/contrib/gcc/sibcall.c
+++ b/contrib/gcc/sibcall.c
@@ -1,5 +1,6 @@
/* Generic sibling call optimization support
- Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -20,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "regs.h"
@@ -38,18 +41,18 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
return in the sibcall sequence. */
static rtx return_value_pseudo;
-static int identify_call_return_value PARAMS ((rtx, rtx *, rtx *));
-static rtx skip_copy_to_return_value PARAMS ((rtx));
-static rtx skip_use_of_return_value PARAMS ((rtx, enum rtx_code));
-static rtx skip_stack_adjustment PARAMS ((rtx));
-static rtx skip_pic_restore PARAMS ((rtx));
-static rtx skip_jump_insn PARAMS ((rtx));
-static int call_ends_block_p PARAMS ((rtx, rtx));
-static int uses_addressof PARAMS ((rtx));
-static int sequence_uses_addressof PARAMS ((rtx));
-static void purge_reg_equiv_notes PARAMS ((void));
-static void purge_mem_unchanging_flag PARAMS ((rtx));
-static rtx skip_unreturned_value PARAMS ((rtx));
+static int identify_call_return_value (rtx, rtx *, rtx *);
+static rtx skip_copy_to_return_value (rtx);
+static rtx skip_use_of_return_value (rtx, enum rtx_code);
+static rtx skip_stack_adjustment (rtx);
+static rtx skip_pic_restore (rtx);
+static rtx skip_jump_insn (rtx);
+static int call_ends_block_p (rtx, rtx);
+static int uses_addressof (rtx);
+static int sequence_uses_addressof (rtx);
+static void purge_reg_equiv_notes (void);
+static void purge_mem_unchanging_flag (rtx);
+static rtx skip_unreturned_value (rtx);
/* Examine a CALL_PLACEHOLDER pattern and determine where the call's
return value is located. P_HARD_RETURN receives the hard register
@@ -57,9 +60,7 @@ static rtx skip_unreturned_value PARAMS ((rtx));
that the sequence used. Return nonzero if the values were located. */
static int
-identify_call_return_value (cp, p_hard_return, p_soft_return)
- rtx cp;
- rtx *p_hard_return, *p_soft_return;
+identify_call_return_value (rtx cp, rtx *p_hard_return, rtx *p_soft_return)
{
rtx insn, set, hard, soft;
@@ -140,8 +141,7 @@ identify_call_return_value (cp, p_hard_return, p_soft_return)
copy. Otherwise return ORIG_INSN. */
static rtx
-skip_copy_to_return_value (orig_insn)
- rtx orig_insn;
+skip_copy_to_return_value (rtx orig_insn)
{
rtx insn, set = NULL_RTX;
rtx hardret, softret;
@@ -217,9 +217,7 @@ skip_copy_to_return_value (orig_insn)
value, return insn. Otherwise return ORIG_INSN. */
static rtx
-skip_use_of_return_value (orig_insn, code)
- rtx orig_insn;
- enum rtx_code code;
+skip_use_of_return_value (rtx orig_insn, enum rtx_code code)
{
rtx insn;
@@ -238,8 +236,7 @@ skip_use_of_return_value (orig_insn, code)
/* In case function does not return value, we get clobber of pseudo followed
by set to hard return value. */
static rtx
-skip_unreturned_value (orig_insn)
- rtx orig_insn;
+skip_unreturned_value (rtx orig_insn)
{
rtx insn = next_nonnote_insn (orig_insn);
@@ -269,8 +266,7 @@ skip_unreturned_value (orig_insn)
Otherwise return ORIG_INSN. */
static rtx
-skip_stack_adjustment (orig_insn)
- rtx orig_insn;
+skip_stack_adjustment (rtx orig_insn)
{
rtx insn, set = NULL_RTX;
@@ -294,8 +290,7 @@ skip_stack_adjustment (orig_insn)
return it. Otherwise return ORIG_INSN. */
static rtx
-skip_pic_restore (orig_insn)
- rtx orig_insn;
+skip_pic_restore (rtx orig_insn)
{
rtx insn, set = NULL_RTX;
@@ -314,8 +309,7 @@ skip_pic_restore (orig_insn)
Otherwise return ORIG_INSN. */
static rtx
-skip_jump_insn (orig_insn)
- rtx orig_insn;
+skip_jump_insn (rtx orig_insn)
{
rtx insn;
@@ -333,9 +327,7 @@ skip_jump_insn (orig_insn)
goes all the way to END, the end of a basic block. Return 1 if so. */
static int
-call_ends_block_p (insn, end)
- rtx insn;
- rtx end;
+call_ends_block_p (rtx insn, rtx end)
{
rtx new_insn;
/* END might be a note, so get the last nonnote insn of the block. */
@@ -392,8 +384,7 @@ call_ends_block_p (insn, end)
is found outside of some MEM expression, else return zero. */
static int
-uses_addressof (x)
- rtx x;
+uses_addressof (rtx x)
{
RTX_CODE code;
int i, j;
@@ -439,8 +430,7 @@ uses_addressof (x)
of insns. */
static int
-sequence_uses_addressof (seq)
- rtx seq;
+sequence_uses_addressof (rtx seq)
{
rtx insn;
@@ -472,7 +462,7 @@ sequence_uses_addressof (seq)
/* Remove all REG_EQUIV notes found in the insn chain. */
static void
-purge_reg_equiv_notes ()
+purge_reg_equiv_notes (void)
{
rtx insn;
@@ -496,8 +486,7 @@ purge_reg_equiv_notes ()
/* Clear RTX_UNCHANGING_P flag of incoming argument MEMs. */
static void
-purge_mem_unchanging_flag (x)
- rtx x;
+purge_mem_unchanging_flag (rtx x)
{
RTX_CODE code;
int i, j;
@@ -536,9 +525,7 @@ purge_mem_unchanging_flag (x)
the CALL_PLACEHOLDER insn; USE tells which child to use. */
void
-replace_call_placeholder (insn, use)
- rtx insn;
- sibcall_use_t use;
+replace_call_placeholder (rtx insn, sibcall_use_t use)
{
if (use == sibcall_use_tail_recursion)
emit_insn_before (XEXP (PATTERN (insn), 2), insn);
@@ -569,7 +556,7 @@ replace_call_placeholder (insn, use)
Replace the CALL_PLACEHOLDER with an appropriate insn chain. */
void
-optimize_sibling_and_tail_recursive_calls ()
+optimize_sibling_and_tail_recursive_calls (void)
{
rtx insn, insns;
basic_block alternate_exit = EXIT_BLOCK_PTR;
@@ -610,7 +597,7 @@ optimize_sibling_and_tail_recursive_calls ()
/* Walk forwards through the last normal block and see if it
does nothing except fall into the exit block. */
- for (insn = EXIT_BLOCK_PTR->prev_bb->head;
+ for (insn = BB_HEAD (EXIT_BLOCK_PTR->prev_bb);
insn;
insn = NEXT_INSN (insn))
{
@@ -691,14 +678,14 @@ optimize_sibling_and_tail_recursive_calls ()
|| current_function_calls_setjmp
/* Can't if more than one successor or single successor is not
exit block. These two tests prevent tail call optimization
- in the presense of active exception handlers. */
+ in the presence of active exception handlers. */
|| call_block->succ == NULL
|| call_block->succ->succ_next != NULL
|| (call_block->succ->dest != EXIT_BLOCK_PTR
&& call_block->succ->dest != alternate_exit)
/* If this call doesn't end the block, there are operations at
the end of the block which we must execute after returning. */
- || ! call_ends_block_p (insn, call_block->end))
+ || ! call_ends_block_p (insn, BB_END (call_block)))
sibcall = 0, tailrecursion = 0;
/* Select a set of insns to implement the call and emit them.
diff --git a/contrib/gcc/simplify-rtx.c b/contrib/gcc/simplify-rtx.c
index eca29457a8c9..a6c5007b8659 100644
--- a/contrib/gcc/simplify-rtx.c
+++ b/contrib/gcc/simplify-rtx.c
@@ -1,6 +1,6 @@
/* RTL simplification functions for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "tm_p.h"
@@ -36,44 +38,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "output.h"
#include "ggc.h"
+#include "target.h"
/* Simplification and canonicalization of RTL. */
-/* Nonzero if X has the form (PLUS frame-pointer integer). We check for
- virtual regs here because the simplify_*_operation routines are called
- by integrate.c, which is called before virtual register instantiation.
-
- ?!? NONZERO_BASE_PLUS_P needs to move into
- a header file so that their definitions can be shared with the
- simplification routines in simplify-rtx.c. Until then, do not
- change this macro without also changing the copy in simplify-rtx.c. */
-
-/* Allows reference to the stack pointer.
-
- This used to include FIXED_BASE_PLUS_P, however, we can't assume that
- arg_pointer_rtx by itself is nonzero, because on at least one machine,
- the i960, the arg pointer is zero when it is unused. */
-
-#define NONZERO_BASE_PLUS_P(X) \
- ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx \
- || (X) == virtual_stack_vars_rtx \
- || (X) == virtual_incoming_args_rtx \
- || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (XEXP (X, 0) == frame_pointer_rtx \
- || XEXP (X, 0) == hard_frame_pointer_rtx \
- || ((X) == arg_pointer_rtx \
- && fixed_regs[ARG_POINTER_REGNUM]) \
- || XEXP (X, 0) == virtual_stack_vars_rtx \
- || XEXP (X, 0) == virtual_incoming_args_rtx)) \
- || (X) == stack_pointer_rtx \
- || (X) == virtual_stack_dynamic_rtx \
- || (X) == virtual_outgoing_args_rtx \
- || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
- && (XEXP (X, 0) == stack_pointer_rtx \
- || XEXP (X, 0) == virtual_stack_dynamic_rtx \
- || XEXP (X, 0) == virtual_outgoing_args_rtx)) \
- || GET_CODE (X) == ADDRESSOF)
-
/* Much code operates on (low, high) pairs; the low value is an
unsigned wide int, the high value a signed wide int. We
occasionally need to sign extend from low to high as if low were a
@@ -81,19 +49,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define HWI_SIGN_EXTEND(low) \
((((HOST_WIDE_INT) low) < 0) ? ((HOST_WIDE_INT) -1) : ((HOST_WIDE_INT) 0))
-static rtx neg_const_int PARAMS ((enum machine_mode, rtx));
-static int simplify_plus_minus_op_data_cmp PARAMS ((const void *,
- const void *));
-static rtx simplify_plus_minus PARAMS ((enum rtx_code,
- enum machine_mode, rtx,
- rtx, int));
+static rtx neg_const_int (enum machine_mode, rtx);
+static int simplify_plus_minus_op_data_cmp (const void *, const void *);
+static rtx simplify_plus_minus (enum rtx_code, enum machine_mode, rtx,
+ rtx, int);
+static rtx simplify_immed_subreg (enum machine_mode, rtx, enum machine_mode,
+ unsigned int);
+static bool associative_constant_p (rtx);
+static rtx simplify_associative_operation (enum rtx_code, enum machine_mode,
+ rtx, rtx);
/* Negate a CONST_INT rtx, truncating (because a conversion from a
maximally negative number can overflow). */
static rtx
-neg_const_int (mode, i)
- enum machine_mode mode;
- rtx i;
+neg_const_int (enum machine_mode mode, rtx i)
{
return gen_int_mode (- INTVAL (i), mode);
}
@@ -103,10 +72,8 @@ neg_const_int (mode, i)
seeing if the expression folds. */
rtx
-simplify_gen_binary (code, mode, op0, op1)
- enum rtx_code code;
- enum machine_mode mode;
- rtx op0, op1;
+simplify_gen_binary (enum rtx_code code, enum machine_mode mode, rtx op0,
+ rtx op1)
{
rtx tem;
@@ -136,16 +103,38 @@ simplify_gen_binary (code, mode, op0, op1)
/* If X is a MEM referencing the constant pool, return the real value.
Otherwise return X. */
rtx
-avoid_constant_pool_reference (x)
- rtx x;
+avoid_constant_pool_reference (rtx x)
{
- rtx c, addr;
+ rtx c, tmp, addr;
enum machine_mode cmode;
- if (GET_CODE (x) != MEM)
- return x;
+ switch (GET_CODE (x))
+ {
+ case MEM:
+ break;
+
+ case FLOAT_EXTEND:
+ /* Handle float extensions of constant pool references. */
+ tmp = XEXP (x, 0);
+ c = avoid_constant_pool_reference (tmp);
+ if (c != tmp && GET_CODE (c) == CONST_DOUBLE)
+ {
+ REAL_VALUE_TYPE d;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (d, c);
+ return CONST_DOUBLE_FROM_REAL_VALUE (d, GET_MODE (x));
+ }
+ return x;
+
+ default:
+ return x;
+ }
+
addr = XEXP (x, 0);
+ /* Call target hook to avoid the effects of -fpic etc.... */
+ addr = (*targetm.delegitimize_address) (addr);
+
if (GET_CODE (addr) == LO_SUM)
addr = XEXP (addr, 1);
@@ -172,11 +161,8 @@ avoid_constant_pool_reference (x)
the specified operation. */
rtx
-simplify_gen_unary (code, mode, op, op_mode)
- enum rtx_code code;
- enum machine_mode mode;
- rtx op;
- enum machine_mode op_mode;
+simplify_gen_unary (enum rtx_code code, enum machine_mode mode, rtx op,
+ enum machine_mode op_mode)
{
rtx tem;
@@ -190,10 +176,8 @@ simplify_gen_unary (code, mode, op, op_mode)
/* Likewise for ternary operations. */
rtx
-simplify_gen_ternary (code, mode, op0_mode, op0, op1, op2)
- enum rtx_code code;
- enum machine_mode mode, op0_mode;
- rtx op0, op1, op2;
+simplify_gen_ternary (enum rtx_code code, enum machine_mode mode,
+ enum machine_mode op0_mode, rtx op0, rtx op1, rtx op2)
{
rtx tem;
@@ -210,46 +194,67 @@ simplify_gen_ternary (code, mode, op0_mode, op0, op1, op2)
*/
rtx
-simplify_gen_relational (code, mode, cmp_mode, op0, op1)
- enum rtx_code code;
- enum machine_mode mode;
- enum machine_mode cmp_mode;
- rtx op0, op1;
+simplify_gen_relational (enum rtx_code code, enum machine_mode mode,
+ enum machine_mode cmp_mode, rtx op0, rtx op1)
{
rtx tem;
- if ((tem = simplify_relational_operation (code, cmp_mode, op0, op1)) != 0)
- return tem;
+ if (cmp_mode == VOIDmode)
+ cmp_mode = GET_MODE (op0);
+ if (cmp_mode == VOIDmode)
+ cmp_mode = GET_MODE (op1);
+
+ if (cmp_mode != VOIDmode)
+ {
+ tem = simplify_relational_operation (code, cmp_mode, op0, op1);
+
+ if (tem)
+ {
+#ifdef FLOAT_STORE_FLAG_VALUE
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ REAL_VALUE_TYPE val;
+ if (tem == const0_rtx)
+ return CONST0_RTX (mode);
+ if (tem != const_true_rtx)
+ abort ();
+ val = FLOAT_STORE_FLAG_VALUE (mode);
+ return CONST_DOUBLE_FROM_REAL_VALUE (val, mode);
+ }
+#endif
+ return tem;
+ }
+ }
/* For the following tests, ensure const0_rtx is op1. */
- if (op0 == const0_rtx && swap_commutative_operands_p (op0, op1))
+ if (swap_commutative_operands_p (op0, op1)
+ || (op0 == const0_rtx && op1 != const0_rtx))
tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
/* If op0 is a compare, extract the comparison arguments from it. */
if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
- op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
+ return simplify_gen_relational (code, mode, VOIDmode,
+ XEXP (op0, 0), XEXP (op0, 1));
/* If op0 is a comparison, extract the comparison arguments form it. */
- if (code == NE && op1 == const0_rtx
- && GET_RTX_CLASS (GET_CODE (op0)) == '<')
- return op0;
- else if (code == EQ && op1 == const0_rtx)
+ if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && op1 == const0_rtx)
{
- /* The following tests GET_RTX_CLASS (GET_CODE (op0)) == '<'. */
- enum rtx_code new = reversed_comparison_code (op0, NULL_RTX);
- if (new != UNKNOWN)
- {
- code = new;
- mode = cmp_mode;
- op1 = XEXP (op0, 1);
- op0 = XEXP (op0, 0);
+ if (code == NE)
+ {
+ if (GET_MODE (op0) == mode)
+ return op0;
+ return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
+ XEXP (op0, 0), XEXP (op0, 1));
+ }
+ else if (code == EQ)
+ {
+ enum rtx_code new = reversed_comparison_code (op0, NULL_RTX);
+ if (new != UNKNOWN)
+ return simplify_gen_relational (new, mode, VOIDmode,
+ XEXP (op0, 0), XEXP (op0, 1));
}
}
- /* Put complex operands first and constants second. */
- if (swap_commutative_operands_p (op0, op1))
- tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
-
return gen_rtx_fmt_ee (code, mode, op0, op1);
}
@@ -257,13 +262,12 @@ simplify_gen_relational (code, mode, cmp_mode, op0, op1)
resulting RTX. Return a new RTX which is as simplified as possible. */
rtx
-simplify_replace_rtx (x, old, new)
- rtx x;
- rtx old;
- rtx new;
+simplify_replace_rtx (rtx x, rtx old, rtx new)
{
enum rtx_code code = GET_CODE (x);
enum machine_mode mode = GET_MODE (x);
+ enum machine_mode op_mode;
+ rtx op0, op1, op2;
/* If X is OLD, return NEW. Otherwise, if this is an expression, try
to build a new expression substituting recursively. If we can't do
@@ -275,83 +279,77 @@ simplify_replace_rtx (x, old, new)
switch (GET_RTX_CLASS (code))
{
case '1':
- {
- enum machine_mode op_mode = GET_MODE (XEXP (x, 0));
- rtx op = (XEXP (x, 0) == old
- ? new : simplify_replace_rtx (XEXP (x, 0), old, new));
-
- return simplify_gen_unary (code, mode, op, op_mode);
- }
+ op0 = XEXP (x, 0);
+ op_mode = GET_MODE (op0);
+ op0 = simplify_replace_rtx (op0, old, new);
+ if (op0 == XEXP (x, 0))
+ return x;
+ return simplify_gen_unary (code, mode, op0, op_mode);
case '2':
case 'c':
- return
- simplify_gen_binary (code, mode,
- simplify_replace_rtx (XEXP (x, 0), old, new),
- simplify_replace_rtx (XEXP (x, 1), old, new));
+ op0 = simplify_replace_rtx (XEXP (x, 0), old, new);
+ op1 = simplify_replace_rtx (XEXP (x, 1), old, new);
+ if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
+ return x;
+ return simplify_gen_binary (code, mode, op0, op1);
+
case '<':
- {
- enum machine_mode op_mode = (GET_MODE (XEXP (x, 0)) != VOIDmode
- ? GET_MODE (XEXP (x, 0))
- : GET_MODE (XEXP (x, 1)));
- rtx op0 = simplify_replace_rtx (XEXP (x, 0), old, new);
- rtx op1 = simplify_replace_rtx (XEXP (x, 1), old, new);
-
- return
- simplify_gen_relational (code, mode,
- (op_mode != VOIDmode
- ? op_mode
- : GET_MODE (op0) != VOIDmode
- ? GET_MODE (op0)
- : GET_MODE (op1)),
- op0, op1);
- }
+ op0 = XEXP (x, 0);
+ op1 = XEXP (x, 1);
+ op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
+ op0 = simplify_replace_rtx (op0, old, new);
+ op1 = simplify_replace_rtx (op1, old, new);
+ if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
+ return x;
+ return simplify_gen_relational (code, mode, op_mode, op0, op1);
case '3':
case 'b':
- {
- enum machine_mode op_mode = GET_MODE (XEXP (x, 0));
- rtx op0 = simplify_replace_rtx (XEXP (x, 0), old, new);
-
- return
- simplify_gen_ternary (code, mode,
- (op_mode != VOIDmode
- ? op_mode
- : GET_MODE (op0)),
- op0,
- simplify_replace_rtx (XEXP (x, 1), old, new),
- simplify_replace_rtx (XEXP (x, 2), old, new));
- }
+ op0 = XEXP (x, 0);
+ op_mode = GET_MODE (op0);
+ op0 = simplify_replace_rtx (op0, old, new);
+ op1 = simplify_replace_rtx (XEXP (x, 1), old, new);
+ op2 = simplify_replace_rtx (XEXP (x, 2), old, new);
+ if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
+ return x;
+ if (op_mode == VOIDmode)
+ op_mode = GET_MODE (op0);
+ return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
case 'x':
/* The only case we try to handle is a SUBREG. */
if (code == SUBREG)
{
- rtx exp;
- exp = simplify_gen_subreg (GET_MODE (x),
- simplify_replace_rtx (SUBREG_REG (x),
- old, new),
+ op0 = simplify_replace_rtx (SUBREG_REG (x), old, new);
+ if (op0 == SUBREG_REG (x))
+ return x;
+ op0 = simplify_gen_subreg (GET_MODE (x), op0,
GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x));
- if (exp)
- x = exp;
+ return op0 ? op0 : x;
}
- return x;
+ break;
case 'o':
if (code == MEM)
- return replace_equiv_address_nv (x,
- simplify_replace_rtx (XEXP (x, 0),
- old, new));
+ {
+ op0 = simplify_replace_rtx (XEXP (x, 0), old, new);
+ if (op0 == XEXP (x, 0))
+ return x;
+ return replace_equiv_address_nv (x, op0);
+ }
else if (code == LO_SUM)
{
- rtx op0 = simplify_replace_rtx (XEXP (x, 0), old, new);
- rtx op1 = simplify_replace_rtx (XEXP (x, 1), old, new);
+ op0 = simplify_replace_rtx (XEXP (x, 0), old, new);
+ op1 = simplify_replace_rtx (XEXP (x, 1), old, new);
/* (lo_sum (high x) x) -> x */
if (GET_CODE (op0) == HIGH && rtx_equal_p (XEXP (op0, 0), op1))
return op1;
+ if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
+ return x;
return gen_rtx_LO_SUM (mode, op0, op1);
}
else if (code == REG)
@@ -359,11 +357,10 @@ simplify_replace_rtx (x, old, new)
if (REG_P (old) && REGNO (x) == REGNO (old))
return new;
}
-
- return x;
+ break;
default:
- return x;
+ break;
}
return x;
}
@@ -372,11 +369,8 @@ simplify_replace_rtx (x, old, new)
MODE with input operand OP whose mode was originally OP_MODE.
Return zero if no simplification can be made. */
rtx
-simplify_unary_operation (code, mode, op, op_mode)
- enum rtx_code code;
- enum machine_mode mode;
- rtx op;
- enum machine_mode op_mode;
+simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
+ rtx op, enum machine_mode op_mode)
{
unsigned int width = GET_MODE_BITSIZE (mode);
rtx trueop = avoid_constant_pool_reference (op);
@@ -418,6 +412,33 @@ simplify_unary_operation (code, mode, op, op_mode)
return gen_rtx_CONST_VECTOR (mode, v);
}
}
+ else if (GET_CODE (op) == CONST)
+ return simplify_unary_operation (code, mode, XEXP (op, 0), op_mode);
+
+ if (VECTOR_MODE_P (mode) && GET_CODE (trueop) == CONST_VECTOR)
+ {
+ int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
+ unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
+ enum machine_mode opmode = GET_MODE (trueop);
+ int op_elt_size = GET_MODE_SIZE (GET_MODE_INNER (opmode));
+ unsigned op_n_elts = (GET_MODE_SIZE (opmode) / op_elt_size);
+ rtvec v = rtvec_alloc (n_elts);
+ unsigned int i;
+
+ if (op_n_elts != n_elts)
+ abort ();
+
+ for (i = 0; i < n_elts; i++)
+ {
+ rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
+ CONST_VECTOR_ELT (trueop, i),
+ GET_MODE_INNER (opmode));
+ if (!x)
+ return 0;
+ RTVEC_ELT (v, i) = x;
+ }
+ return gen_rtx_CONST_VECTOR (mode, v);
+ }
/* The order of these tests is critical so that, for example, we don't
check the wrong mode (input vs. output) for a conversion operation,
@@ -494,6 +515,42 @@ simplify_unary_operation (code, mode, op, op_mode)
val = exact_log2 (arg0 & (- arg0)) + 1;
break;
+ case CLZ:
+ arg0 &= GET_MODE_MASK (mode);
+ if (arg0 == 0 && CLZ_DEFINED_VALUE_AT_ZERO (mode, val))
+ ;
+ else
+ val = GET_MODE_BITSIZE (mode) - floor_log2 (arg0) - 1;
+ break;
+
+ case CTZ:
+ arg0 &= GET_MODE_MASK (mode);
+ if (arg0 == 0)
+ {
+ /* Even if the value at zero is undefined, we have to come
+ up with some replacement. Seems good enough. */
+ if (! CTZ_DEFINED_VALUE_AT_ZERO (mode, val))
+ val = GET_MODE_BITSIZE (mode);
+ }
+ else
+ val = exact_log2 (arg0 & -arg0);
+ break;
+
+ case POPCOUNT:
+ arg0 &= GET_MODE_MASK (mode);
+ val = 0;
+ while (arg0)
+ val++, arg0 &= arg0 - 1;
+ break;
+
+ case PARITY:
+ arg0 &= GET_MODE_MASK (mode);
+ val = 0;
+ while (arg0)
+ val++, arg0 &= arg0 - 1;
+ val &= 1;
+ break;
+
case TRUNCATE:
val = arg0;
break;
@@ -594,9 +651,54 @@ simplify_unary_operation (code, mode, op, op_mode)
case FFS:
hv = 0;
if (l1 == 0)
- lv = HOST_BITS_PER_WIDE_INT + exact_log2 (h1 & (-h1)) + 1;
+ {
+ if (h1 == 0)
+ lv = 0;
+ else
+ lv = HOST_BITS_PER_WIDE_INT + exact_log2 (h1 & -h1) + 1;
+ }
else
- lv = exact_log2 (l1 & (-l1)) + 1;
+ lv = exact_log2 (l1 & -l1) + 1;
+ break;
+
+ case CLZ:
+ hv = 0;
+ if (h1 != 0)
+ lv = GET_MODE_BITSIZE (mode) - floor_log2 (h1) - 1
+ - HOST_BITS_PER_WIDE_INT;
+ else if (l1 != 0)
+ lv = GET_MODE_BITSIZE (mode) - floor_log2 (l1) - 1;
+ else if (! CLZ_DEFINED_VALUE_AT_ZERO (mode, lv))
+ lv = GET_MODE_BITSIZE (mode);
+ break;
+
+ case CTZ:
+ hv = 0;
+ if (l1 != 0)
+ lv = exact_log2 (l1 & -l1);
+ else if (h1 != 0)
+ lv = HOST_BITS_PER_WIDE_INT + exact_log2 (h1 & -h1);
+ else if (! CTZ_DEFINED_VALUE_AT_ZERO (mode, lv))
+ lv = GET_MODE_BITSIZE (mode);
+ break;
+
+ case POPCOUNT:
+ hv = 0;
+ lv = 0;
+ while (l1)
+ lv++, l1 &= l1 - 1;
+ while (h1)
+ lv++, h1 &= h1 - 1;
+ break;
+
+ case PARITY:
+ hv = 0;
+ lv = 0;
+ while (l1)
+ lv++, l1 &= l1 - 1;
+ while (h1)
+ lv++, h1 &= h1 - 1;
+ lv &= 1;
break;
case TRUNCATE:
@@ -644,15 +746,17 @@ simplify_unary_operation (code, mode, op, op_mode)
else if (GET_CODE (trueop) == CONST_DOUBLE
&& GET_MODE_CLASS (mode) == MODE_FLOAT)
{
- REAL_VALUE_TYPE d;
+ REAL_VALUE_TYPE d, t;
REAL_VALUE_FROM_CONST_DOUBLE (d, trueop);
switch (code)
{
case SQRT:
- /* We don't attempt to optimize this. */
- return 0;
-
+ if (HONOR_SNANS (mode) && real_isnan (&d))
+ return 0;
+ real_sqrt (&t, mode, &d);
+ d = t;
+ break;
case ABS:
d = REAL_VALUE_ABS (d);
break;
@@ -678,19 +782,99 @@ simplify_unary_operation (code, mode, op, op_mode)
else if (GET_CODE (trueop) == CONST_DOUBLE
&& GET_MODE_CLASS (GET_MODE (trueop)) == MODE_FLOAT
&& GET_MODE_CLASS (mode) == MODE_INT
- && width <= HOST_BITS_PER_WIDE_INT && width > 0)
+ && width <= 2*HOST_BITS_PER_WIDE_INT && width > 0)
{
- HOST_WIDE_INT i;
- REAL_VALUE_TYPE d;
- REAL_VALUE_FROM_CONST_DOUBLE (d, trueop);
+ /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
+ operators are intentionally left unspecified (to ease implementation
+ by target backends), for consistency, this routine implements the
+ same semantics for constant folding as used by the middle-end. */
+
+ HOST_WIDE_INT xh, xl, th, tl;
+ REAL_VALUE_TYPE x, t;
+ REAL_VALUE_FROM_CONST_DOUBLE (x, trueop);
switch (code)
{
- case FIX: i = REAL_VALUE_FIX (d); break;
- case UNSIGNED_FIX: i = REAL_VALUE_UNSIGNED_FIX (d); break;
+ case FIX:
+ if (REAL_VALUE_ISNAN (x))
+ return const0_rtx;
+
+ /* Test against the signed upper bound. */
+ if (width > HOST_BITS_PER_WIDE_INT)
+ {
+ th = ((unsigned HOST_WIDE_INT) 1
+ << (width - HOST_BITS_PER_WIDE_INT - 1)) - 1;
+ tl = -1;
+ }
+ else
+ {
+ th = 0;
+ tl = ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1;
+ }
+ real_from_integer (&t, VOIDmode, tl, th, 0);
+ if (REAL_VALUES_LESS (t, x))
+ {
+ xh = th;
+ xl = tl;
+ break;
+ }
+
+ /* Test against the signed lower bound. */
+ if (width > HOST_BITS_PER_WIDE_INT)
+ {
+ th = (HOST_WIDE_INT) -1 << (width - HOST_BITS_PER_WIDE_INT - 1);
+ tl = 0;
+ }
+ else
+ {
+ th = -1;
+ tl = (HOST_WIDE_INT) -1 << (width - 1);
+ }
+ real_from_integer (&t, VOIDmode, tl, th, 0);
+ if (REAL_VALUES_LESS (x, t))
+ {
+ xh = th;
+ xl = tl;
+ break;
+ }
+ REAL_VALUE_TO_INT (&xl, &xh, x);
+ break;
+
+ case UNSIGNED_FIX:
+ if (REAL_VALUE_ISNAN (x) || REAL_VALUE_NEGATIVE (x))
+ return const0_rtx;
+
+ /* Test against the unsigned upper bound. */
+ if (width == 2*HOST_BITS_PER_WIDE_INT)
+ {
+ th = -1;
+ tl = -1;
+ }
+ else if (width >= HOST_BITS_PER_WIDE_INT)
+ {
+ th = ((unsigned HOST_WIDE_INT) 1
+ << (width - HOST_BITS_PER_WIDE_INT)) - 1;
+ tl = -1;
+ }
+ else
+ {
+ th = 0;
+ tl = ((unsigned HOST_WIDE_INT) 1 << width) - 1;
+ }
+ real_from_integer (&t, VOIDmode, tl, th, 1);
+ if (REAL_VALUES_LESS (t, x))
+ {
+ xh = th;
+ xl = tl;
+ break;
+ }
+
+ REAL_VALUE_TO_INT (&xl, &xh, x);
+ break;
+
default:
abort ();
}
- return gen_int_mode (i, mode);
+ return immed_double_const (xl, xh, mode);
}
/* This was formerly used only for non-IEEE float.
@@ -698,6 +882,8 @@ simplify_unary_operation (code, mode, op, op_mode)
else
{
enum rtx_code reversed;
+ rtx temp;
+
/* There are some simplifications we can do even if the operands
aren't constant. */
switch (code)
@@ -708,17 +894,131 @@ simplify_unary_operation (code, mode, op, op_mode)
return XEXP (op, 0);
/* (not (eq X Y)) == (ne X Y), etc. */
- if (mode == BImode && GET_RTX_CLASS (GET_CODE (op)) == '<'
+ if (GET_RTX_CLASS (GET_CODE (op)) == '<'
+ && (mode == BImode || STORE_FLAG_VALUE == -1)
&& ((reversed = reversed_comparison_code (op, NULL_RTX))
!= UNKNOWN))
- return gen_rtx_fmt_ee (reversed,
- op_mode, XEXP (op, 0), XEXP (op, 1));
+ return simplify_gen_relational (reversed, mode, VOIDmode,
+ XEXP (op, 0), XEXP (op, 1));
+
+ /* (not (plus X -1)) can become (neg X). */
+ if (GET_CODE (op) == PLUS
+ && XEXP (op, 1) == constm1_rtx)
+ return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
+
+ /* Similarly, (not (neg X)) is (plus X -1). */
+ if (GET_CODE (op) == NEG)
+ return plus_constant (XEXP (op, 0), -1);
+
+ /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
+ if (GET_CODE (op) == XOR
+ && GET_CODE (XEXP (op, 1)) == CONST_INT
+ && (temp = simplify_unary_operation (NOT, mode,
+ XEXP (op, 1),
+ mode)) != 0)
+ return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
+
+
+ /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for
+ operands other than 1, but that is not valid. We could do a
+ similar simplification for (not (lshiftrt C X)) where C is
+ just the sign bit, but this doesn't seem common enough to
+ bother with. */
+ if (GET_CODE (op) == ASHIFT
+ && XEXP (op, 0) == const1_rtx)
+ {
+ temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
+ return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
+ }
+
+ /* If STORE_FLAG_VALUE is -1, (not (comparison X Y)) can be done
+ by reversing the comparison code if valid. */
+ if (STORE_FLAG_VALUE == -1
+ && GET_RTX_CLASS (GET_CODE (op)) == '<'
+ && (reversed = reversed_comparison_code (op, NULL_RTX))
+ != UNKNOWN)
+ return simplify_gen_relational (reversed, mode, VOIDmode,
+ XEXP (op, 0), XEXP (op, 1));
+
+ /* (not (ashiftrt foo C)) where C is the number of bits in FOO
+ minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
+ so we can perform the above simplification. */
+
+ if (STORE_FLAG_VALUE == -1
+ && GET_CODE (op) == ASHIFTRT
+ && GET_CODE (XEXP (op, 1)) == CONST_INT
+ && INTVAL (XEXP (op, 1)) == GET_MODE_BITSIZE (mode) - 1)
+ return simplify_gen_relational (GE, mode, VOIDmode,
+ XEXP (op, 0), const0_rtx);
+
break;
case NEG:
/* (neg (neg X)) == X. */
if (GET_CODE (op) == NEG)
return XEXP (op, 0);
+
+ /* (neg (plus X 1)) can become (not X). */
+ if (GET_CODE (op) == PLUS
+ && XEXP (op, 1) == const1_rtx)
+ return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
+
+ /* Similarly, (neg (not X)) is (plus X 1). */
+ if (GET_CODE (op) == NOT)
+ return plus_constant (XEXP (op, 0), 1);
+
+ /* (neg (minus X Y)) can become (minus Y X). This transformation
+ isn't safe for modes with signed zeros, since if X and Y are
+ both +0, (minus Y X) is the same as (minus X Y). If the
+ rounding mode is towards +infinity (or -infinity) then the two
+ expressions will be rounded differently. */
+ if (GET_CODE (op) == MINUS
+ && !HONOR_SIGNED_ZEROS (mode)
+ && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
+ return simplify_gen_binary (MINUS, mode, XEXP (op, 1),
+ XEXP (op, 0));
+
+ if (GET_CODE (op) == PLUS
+ && !HONOR_SIGNED_ZEROS (mode)
+ && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
+ {
+ /* (neg (plus A C)) is simplified to (minus -C A). */
+ if (GET_CODE (XEXP (op, 1)) == CONST_INT
+ || GET_CODE (XEXP (op, 1)) == CONST_DOUBLE)
+ {
+ temp = simplify_unary_operation (NEG, mode, XEXP (op, 1),
+ mode);
+ if (temp)
+ return simplify_gen_binary (MINUS, mode, temp,
+ XEXP (op, 0));
+ }
+
+ /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
+ temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
+ return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
+ }
+
+ /* (neg (mult A B)) becomes (mult (neg A) B).
+ This works even for floating-point values. */
+ if (GET_CODE (op) == MULT
+ && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
+ {
+ temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
+ return simplify_gen_binary (MULT, mode, temp, XEXP (op, 1));
+ }
+
+ /* NEG commutes with ASHIFT since it is multiplication. Only do
+ this if we can then eliminate the NEG (e.g., if the operand
+ is a constant). */
+ if (GET_CODE (op) == ASHIFT)
+ {
+ temp = simplify_unary_operation (NEG, mode, XEXP (op, 0),
+ mode);
+ if (temp)
+ return simplify_gen_binary (ASHIFT, mode, temp,
+ XEXP (op, 1));
+ }
+
break;
case SIGN_EXTEND:
@@ -733,6 +1033,15 @@ simplify_unary_operation (code, mode, op, op_mode)
&& GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
return XEXP (op, 0);
+ /* Check for a sign extension of a subreg of a promoted
+ variable, where the promotion is sign-extended, and the
+ target mode is the same as the variable's promotion. */
+ if (GET_CODE (op) == SUBREG
+ && SUBREG_PROMOTED_VAR_P (op)
+ && ! SUBREG_PROMOTED_UNSIGNED_P (op)
+ && GET_MODE (XEXP (op, 0)) == mode)
+ return XEXP (op, 0);
+
#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
if (! POINTERS_EXTEND_UNSIGNED
&& mode == Pmode && GET_MODE (op) == ptr_mode
@@ -745,8 +1054,17 @@ simplify_unary_operation (code, mode, op, op_mode)
#endif
break;
-#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
case ZERO_EXTEND:
+ /* Check for a zero extension of a subreg of a promoted
+ variable, where the promotion is zero-extended, and the
+ target mode is the same as the variable's promotion. */
+ if (GET_CODE (op) == SUBREG
+ && SUBREG_PROMOTED_VAR_P (op)
+ && SUBREG_PROMOTED_UNSIGNED_P (op)
+ && GET_MODE (XEXP (op, 0)) == mode)
+ return XEXP (op, 0);
+
+#if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend)
if (POINTERS_EXTEND_UNSIGNED > 0
&& mode == Pmode && GET_MODE (op) == ptr_mode
&& (CONSTANT_P (op)
@@ -755,8 +1073,8 @@ simplify_unary_operation (code, mode, op, op_mode)
&& REG_POINTER (SUBREG_REG (op))
&& GET_MODE (SUBREG_REG (op)) == Pmode)))
return convert_memory_address (Pmode, op);
- break;
#endif
+ break;
default:
break;
@@ -766,16 +1084,80 @@ simplify_unary_operation (code, mode, op, op_mode)
}
}
+/* Subroutine of simplify_associative_operation. Return true if rtx OP
+ is a suitable integer or floating point immediate constant. */
+static bool
+associative_constant_p (rtx op)
+{
+ if (GET_CODE (op) == CONST_INT
+ || GET_CODE (op) == CONST_DOUBLE)
+ return true;
+ op = avoid_constant_pool_reference (op);
+ return GET_CODE (op) == CONST_INT
+ || GET_CODE (op) == CONST_DOUBLE;
+}
+
+/* Subroutine of simplify_binary_operation to simplify an associative
+ binary operation CODE with result mode MODE, operating on OP0 and OP1.
+ Return 0 if no simplification is possible. */
+static rtx
+simplify_associative_operation (enum rtx_code code, enum machine_mode mode,
+ rtx op0, rtx op1)
+{
+ rtx tem;
+
+ /* Simplify (x op c1) op c2 as x op (c1 op c2). */
+ if (GET_CODE (op0) == code
+ && associative_constant_p (op1)
+ && associative_constant_p (XEXP (op0, 1)))
+ {
+ tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
+ if (! tem)
+ return tem;
+ return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
+ }
+
+ /* Simplify (x op c1) op (y op c2) as (x op y) op (c1 op c2). */
+ if (GET_CODE (op0) == code
+ && GET_CODE (op1) == code
+ && associative_constant_p (XEXP (op0, 1))
+ && associative_constant_p (XEXP (op1, 1)))
+ {
+ rtx c = simplify_binary_operation (code, mode,
+ XEXP (op0, 1), XEXP (op1, 1));
+ if (! c)
+ return 0;
+ tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
+ return simplify_gen_binary (code, mode, tem, c);
+ }
+
+ /* Canonicalize (x op c) op y as (x op y) op c. */
+ if (GET_CODE (op0) == code
+ && associative_constant_p (XEXP (op0, 1)))
+ {
+ tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
+ return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
+ }
+
+ /* Canonicalize x op (y op c) as (x op y) op c. */
+ if (GET_CODE (op1) == code
+ && associative_constant_p (XEXP (op1, 1)))
+ {
+ tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
+ return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
+ }
+
+ return 0;
+}
+
/* Simplify a binary operation CODE with result mode MODE, operating on OP0
and OP1. Return 0 if no simplification is possible.
Don't use this for relational operations such as EQ or LT.
Use simplify_relational_operation instead. */
rtx
-simplify_binary_operation (code, mode, op0, op1)
- enum rtx_code code;
- enum machine_mode mode;
- rtx op0, op1;
+simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
+ rtx op0, rtx op1)
{
HOST_WIDE_INT arg0, arg1, arg0s, arg1s;
HOST_WIDE_INT val;
@@ -800,6 +1182,37 @@ simplify_binary_operation (code, mode, op0, op1)
tem = trueop0, trueop0 = trueop1, trueop1 = tem;
}
+ if (VECTOR_MODE_P (mode)
+ && GET_CODE (trueop0) == CONST_VECTOR
+ && GET_CODE (trueop1) == CONST_VECTOR)
+ {
+ int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
+ unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
+ enum machine_mode op0mode = GET_MODE (trueop0);
+ int op0_elt_size = GET_MODE_SIZE (GET_MODE_INNER (op0mode));
+ unsigned op0_n_elts = (GET_MODE_SIZE (op0mode) / op0_elt_size);
+ enum machine_mode op1mode = GET_MODE (trueop1);
+ int op1_elt_size = GET_MODE_SIZE (GET_MODE_INNER (op1mode));
+ unsigned op1_n_elts = (GET_MODE_SIZE (op1mode) / op1_elt_size);
+ rtvec v = rtvec_alloc (n_elts);
+ unsigned int i;
+
+ if (op0_n_elts != n_elts || op1_n_elts != n_elts)
+ abort ();
+
+ for (i = 0; i < n_elts; i++)
+ {
+ rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
+ CONST_VECTOR_ELT (trueop0, i),
+ CONST_VECTOR_ELT (trueop1, i));
+ if (!x)
+ return 0;
+ RTVEC_ELT (v, i) = x;
+ }
+
+ return gen_rtx_CONST_VECTOR (mode, v);
+ }
+
if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& GET_CODE (trueop0) == CONST_DOUBLE
&& GET_CODE (trueop1) == CONST_DOUBLE
@@ -812,9 +1225,47 @@ simplify_binary_operation (code, mode, op0, op1)
f0 = real_value_truncate (mode, f0);
f1 = real_value_truncate (mode, f1);
+ if (HONOR_SNANS (mode)
+ && (REAL_VALUE_ISNAN (f0) || REAL_VALUE_ISNAN (f1)))
+ return 0;
+
if (code == DIV
- && !MODE_HAS_INFINITIES (mode)
- && REAL_VALUES_EQUAL (f1, dconst0))
+ && REAL_VALUES_EQUAL (f1, dconst0)
+ && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
+ return 0;
+
+ if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
+ && flag_trapping_math
+ && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
+ {
+ int s0 = REAL_VALUE_NEGATIVE (f0);
+ int s1 = REAL_VALUE_NEGATIVE (f1);
+
+ switch (code)
+ {
+ case PLUS:
+ /* Inf + -Inf = NaN plus exception. */
+ if (s0 != s1)
+ return 0;
+ break;
+ case MINUS:
+ /* Inf - Inf = NaN plus exception. */
+ if (s0 == s1)
+ return 0;
+ break;
+ case DIV:
+ /* Inf / Inf = NaN plus exception. */
+ return 0;
+ default:
+ break;
+ }
+ }
+
+ if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
+ && flag_trapping_math
+ && ((REAL_VALUE_ISINF (f0) && REAL_VALUES_EQUAL (f1, dconst0))
+ || (REAL_VALUE_ISINF (f1) && REAL_VALUES_EQUAL (f0, dconst0))))
+ /* Inf * 0 = NaN plus exception. */
return 0;
REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1);
@@ -851,7 +1302,7 @@ simplify_binary_operation (code, mode, op0, op1)
neg_double (l2, h2, &lv, &hv);
l2 = lv, h2 = hv;
- /* .. fall through ... */
+ /* Fall through.... */
case PLUS:
add_double (l1, h1, l2, h2, &lv, &hv);
@@ -974,7 +1425,7 @@ simplify_binary_operation (code, mode, op0, op1)
if (INTEGRAL_MODE_P (mode)
&& GET_CODE (op0) == NOT
&& trueop1 == const1_rtx)
- return gen_rtx_NEG (mode, XEXP (op0, 0));
+ return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
/* Handle both-operands-constant cases. We can only add
CONST_INTs to constants since the sum of relocatable symbols
@@ -1058,6 +1509,16 @@ simplify_binary_operation (code, mode, op0, op1)
&& GET_CODE (XEXP (op1, 0)) == PLUS))
&& (tem = simplify_plus_minus (code, mode, op0, op1, 0)) != 0)
return tem;
+
+ /* Reassociate floating point addition only when the user
+ specifies unsafe math optimizations. */
+ if (FLOAT_MODE_P (mode)
+ && flag_unsafe_math_optimizations)
+ {
+ tem = simplify_associative_operation (code, mode, op0, op1);
+ if (tem)
+ return tem;
+ }
break;
case COMPARE:
@@ -1109,11 +1570,11 @@ simplify_binary_operation (code, mode, op0, op1)
But if the mode has signed zeros, and does not round towards
-infinity, then 0 - 0 is 0, not -0. */
if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
- return gen_rtx_NEG (mode, op1);
+ return simplify_gen_unary (NEG, mode, op1, mode);
/* (-1 - a) is ~a. */
if (trueop0 == constm1_rtx)
- return gen_rtx_NOT (mode, op1);
+ return simplify_gen_unary (NOT, mode, op1, mode);
/* Subtracting 0 has no effect unless the mode has signed zeros
and supports rounding towards -infinity. In such a case,
@@ -1181,6 +1642,16 @@ simplify_binary_operation (code, mode, op0, op1)
if (GET_CODE (op1) == NEG)
return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
+ /* (-x - c) may be simplified as (-c - x). */
+ if (GET_CODE (op0) == NEG
+ && (GET_CODE (op1) == CONST_INT
+ || GET_CODE (op1) == CONST_DOUBLE))
+ {
+ tem = simplify_unary_operation (NEG, mode, op1, mode);
+ if (tem)
+ return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
+ }
+
/* If one of the operands is a PLUS or a MINUS, see if we can
simplify this by the associative law.
Don't use the associative law for floating point.
@@ -1206,22 +1677,24 @@ simplify_binary_operation (code, mode, op0, op1)
/* (x - (x & y)) -> (x & ~y) */
if (GET_CODE (op1) == AND)
{
- if (rtx_equal_p (op0, XEXP (op1, 0)))
- return simplify_gen_binary (AND, mode, op0,
- gen_rtx_NOT (mode, XEXP (op1, 1)));
- if (rtx_equal_p (op0, XEXP (op1, 1)))
- return simplify_gen_binary (AND, mode, op0,
- gen_rtx_NOT (mode, XEXP (op1, 0)));
- }
+ if (rtx_equal_p (op0, XEXP (op1, 0)))
+ {
+ tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
+ GET_MODE (XEXP (op1, 1)));
+ return simplify_gen_binary (AND, mode, op0, tem);
+ }
+ if (rtx_equal_p (op0, XEXP (op1, 1)))
+ {
+ tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
+ GET_MODE (XEXP (op1, 0)));
+ return simplify_gen_binary (AND, mode, op0, tem);
+ }
+ }
break;
case MULT:
if (trueop1 == constm1_rtx)
- {
- tem = simplify_unary_operation (NEG, mode, op0, mode);
-
- return tem ? tem : gen_rtx_NEG (mode, op0);
- }
+ return simplify_gen_unary (NEG, mode, op0, mode);
/* Maybe simplify x * 0 to 0. The reduction is not valid if
x is NaN, since x * 0 is then also NaN. Nor is it valid
@@ -1249,7 +1722,7 @@ simplify_binary_operation (code, mode, op0, op1)
&& (width <= HOST_BITS_PER_WIDE_INT
|| val != HOST_BITS_PER_WIDE_INT - 1)
&& ! rtx_equal_function_value_matters)
- return gen_rtx_ASHIFT (mode, op0, GEN_INT (val));
+ return simplify_gen_binary (ASHIFT, mode, op0, GEN_INT (val));
/* x*2 is x+x and x*(-1) is -x */
if (GET_CODE (trueop1) == CONST_DOUBLE
@@ -1260,10 +1733,20 @@ simplify_binary_operation (code, mode, op0, op1)
REAL_VALUE_FROM_CONST_DOUBLE (d, trueop1);
if (REAL_VALUES_EQUAL (d, dconst2))
- return gen_rtx_PLUS (mode, op0, copy_rtx (op0));
+ return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
if (REAL_VALUES_EQUAL (d, dconstm1))
- return gen_rtx_NEG (mode, op0);
+ return simplify_gen_unary (NEG, mode, op0, mode);
+ }
+
+ /* Reassociate multiplication, but for floating point MULTs
+ only when the user specifies unsafe math optimizations. */
+ if (! FLOAT_MODE_P (mode)
+ || flag_unsafe_math_optimizations)
+ {
+ tem = simplify_associative_operation (code, mode, op0, op1);
+ if (tem)
+ return tem;
}
break;
@@ -1282,6 +1765,9 @@ simplify_binary_operation (code, mode, op0, op1)
&& ! side_effects_p (op0)
&& GET_MODE_CLASS (mode) != MODE_CC)
return constm1_rtx;
+ tem = simplify_associative_operation (code, mode, op0, op1);
+ if (tem)
+ return tem;
break;
case XOR:
@@ -1290,10 +1776,13 @@ simplify_binary_operation (code, mode, op0, op1)
if (GET_CODE (trueop1) == CONST_INT
&& ((INTVAL (trueop1) & GET_MODE_MASK (mode))
== GET_MODE_MASK (mode)))
- return gen_rtx_NOT (mode, op0);
+ return simplify_gen_unary (NOT, mode, op0, mode);
if (trueop0 == trueop1 && ! side_effects_p (op0)
&& GET_MODE_CLASS (mode) != MODE_CC)
return const0_rtx;
+ tem = simplify_associative_operation (code, mode, op0, op1);
+ if (tem)
+ return tem;
break;
case AND:
@@ -1312,6 +1801,9 @@ simplify_binary_operation (code, mode, op0, op1)
&& ! side_effects_p (op0)
&& GET_MODE_CLASS (mode) != MODE_CC)
return const0_rtx;
+ tem = simplify_associative_operation (code, mode, op0, op1);
+ if (tem)
+ return tem;
break;
case UDIV:
@@ -1319,9 +1811,9 @@ simplify_binary_operation (code, mode, op0, op1)
below). */
if (GET_CODE (trueop1) == CONST_INT
&& (arg1 = exact_log2 (INTVAL (trueop1))) > 0)
- return gen_rtx_LSHIFTRT (mode, op0, GEN_INT (arg1));
+ return simplify_gen_binary (LSHIFTRT, mode, op0, GEN_INT (arg1));
- /* ... fall through ... */
+ /* Fall through.... */
case DIV:
if (trueop1 == CONST1_RTX (mode))
@@ -1360,8 +1852,8 @@ simplify_binary_operation (code, mode, op0, op1)
if (! REAL_VALUES_EQUAL (d, dconst0))
{
REAL_ARITHMETIC (d, rtx_to_tree_code (DIV), dconst1, d);
- return gen_rtx_MULT (mode, op0,
- CONST_DOUBLE_FROM_REAL_VALUE (d, mode));
+ tem = CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
+ return simplify_gen_binary (MULT, mode, op0, tem);
}
}
break;
@@ -1370,9 +1862,10 @@ simplify_binary_operation (code, mode, op0, op1)
/* Handle modulus by power of two (mod with 1 handled below). */
if (GET_CODE (trueop1) == CONST_INT
&& exact_log2 (INTVAL (trueop1)) > 0)
- return gen_rtx_AND (mode, op0, GEN_INT (INTVAL (op1) - 1));
+ return simplify_gen_binary (AND, mode, op0,
+ GEN_INT (INTVAL (op1) - 1));
- /* ... fall through ... */
+ /* Fall through.... */
case MOD:
if ((trueop0 == const0_rtx || trueop1 == const1_rtx)
@@ -1382,16 +1875,16 @@ simplify_binary_operation (code, mode, op0, op1)
case ROTATERT:
case ROTATE:
+ case ASHIFTRT:
/* Rotating ~0 always results in ~0. */
if (GET_CODE (trueop0) == CONST_INT && width <= HOST_BITS_PER_WIDE_INT
&& (unsigned HOST_WIDE_INT) INTVAL (trueop0) == GET_MODE_MASK (mode)
&& ! side_effects_p (op1))
return op0;
- /* ... fall through ... */
+ /* Fall through.... */
case ASHIFT:
- case ASHIFTRT:
case LSHIFTRT:
if (trueop1 == const0_rtx)
return op0;
@@ -1400,36 +1893,50 @@ simplify_binary_operation (code, mode, op0, op1)
break;
case SMIN:
- if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (trueop1) == CONST_INT
+ if (width <= HOST_BITS_PER_WIDE_INT
+ && GET_CODE (trueop1) == CONST_INT
&& INTVAL (trueop1) == (HOST_WIDE_INT) 1 << (width -1)
&& ! side_effects_p (op0))
return op1;
- else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
+ if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
return op0;
+ tem = simplify_associative_operation (code, mode, op0, op1);
+ if (tem)
+ return tem;
break;
case SMAX:
- if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (trueop1) == CONST_INT
+ if (width <= HOST_BITS_PER_WIDE_INT
+ && GET_CODE (trueop1) == CONST_INT
&& ((unsigned HOST_WIDE_INT) INTVAL (trueop1)
== (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode) >> 1)
&& ! side_effects_p (op0))
return op1;
- else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
+ if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
return op0;
+ tem = simplify_associative_operation (code, mode, op0, op1);
+ if (tem)
+ return tem;
break;
case UMIN:
if (trueop1 == const0_rtx && ! side_effects_p (op0))
return op1;
- else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
+ if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
return op0;
+ tem = simplify_associative_operation (code, mode, op0, op1);
+ if (tem)
+ return tem;
break;
case UMAX:
if (trueop1 == constm1_rtx && ! side_effects_p (op0))
return op1;
- else if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
+ if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
return op0;
+ tem = simplify_associative_operation (code, mode, op0, op1);
+ if (tem)
+ return tem;
break;
case SS_PLUS:
@@ -1440,7 +1947,114 @@ simplify_binary_operation (code, mode, op0, op1)
return 0;
case VEC_SELECT:
+ if (!VECTOR_MODE_P (mode))
+ {
+ if (!VECTOR_MODE_P (GET_MODE (trueop0))
+ || (mode
+ != GET_MODE_INNER (GET_MODE (trueop0)))
+ || GET_CODE (trueop1) != PARALLEL
+ || XVECLEN (trueop1, 0) != 1
+ || GET_CODE (XVECEXP (trueop1, 0, 0)) != CONST_INT)
+ abort ();
+
+ if (GET_CODE (trueop0) == CONST_VECTOR)
+ return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP (trueop1, 0, 0)));
+ }
+ else
+ {
+ if (!VECTOR_MODE_P (GET_MODE (trueop0))
+ || (GET_MODE_INNER (mode)
+ != GET_MODE_INNER (GET_MODE (trueop0)))
+ || GET_CODE (trueop1) != PARALLEL)
+ abort ();
+
+ if (GET_CODE (trueop0) == CONST_VECTOR)
+ {
+ int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
+ unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
+ rtvec v = rtvec_alloc (n_elts);
+ unsigned int i;
+
+ if (XVECLEN (trueop1, 0) != (int) n_elts)
+ abort ();
+ for (i = 0; i < n_elts; i++)
+ {
+ rtx x = XVECEXP (trueop1, 0, i);
+
+ if (GET_CODE (x) != CONST_INT)
+ abort ();
+ RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, INTVAL (x));
+ }
+
+ return gen_rtx_CONST_VECTOR (mode, v);
+ }
+ }
+ return 0;
case VEC_CONCAT:
+ {
+ enum machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
+ ? GET_MODE (trueop0)
+ : GET_MODE_INNER (mode));
+ enum machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
+ ? GET_MODE (trueop1)
+ : GET_MODE_INNER (mode));
+
+ if (!VECTOR_MODE_P (mode)
+ || (GET_MODE_SIZE (op0_mode) + GET_MODE_SIZE (op1_mode)
+ != GET_MODE_SIZE (mode)))
+ abort ();
+
+ if ((VECTOR_MODE_P (op0_mode)
+ && (GET_MODE_INNER (mode)
+ != GET_MODE_INNER (op0_mode)))
+ || (!VECTOR_MODE_P (op0_mode)
+ && GET_MODE_INNER (mode) != op0_mode))
+ abort ();
+
+ if ((VECTOR_MODE_P (op1_mode)
+ && (GET_MODE_INNER (mode)
+ != GET_MODE_INNER (op1_mode)))
+ || (!VECTOR_MODE_P (op1_mode)
+ && GET_MODE_INNER (mode) != op1_mode))
+ abort ();
+
+ if ((GET_CODE (trueop0) == CONST_VECTOR
+ || GET_CODE (trueop0) == CONST_INT
+ || GET_CODE (trueop0) == CONST_DOUBLE)
+ && (GET_CODE (trueop1) == CONST_VECTOR
+ || GET_CODE (trueop1) == CONST_INT
+ || GET_CODE (trueop1) == CONST_DOUBLE))
+ {
+ int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
+ unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
+ rtvec v = rtvec_alloc (n_elts);
+ unsigned int i;
+ unsigned in_n_elts = 1;
+
+ if (VECTOR_MODE_P (op0_mode))
+ in_n_elts = (GET_MODE_SIZE (op0_mode) / elt_size);
+ for (i = 0; i < n_elts; i++)
+ {
+ if (i < in_n_elts)
+ {
+ if (!VECTOR_MODE_P (op0_mode))
+ RTVEC_ELT (v, i) = trueop0;
+ else
+ RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
+ }
+ else
+ {
+ if (!VECTOR_MODE_P (op1_mode))
+ RTVEC_ELT (v, i) = trueop1;
+ else
+ RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
+ i - in_n_elts);
+ }
+ }
+
+ return gen_rtx_CONST_VECTOR (mode, v);
+ }
+ }
return 0;
default:
@@ -1619,6 +2233,13 @@ simplify_binary_operation (code, mode, op0, op1)
> (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
break;
+ case SS_PLUS:
+ case US_PLUS:
+ case SS_MINUS:
+ case US_MINUS:
+ /* ??? There are simplifications that can be done. */
+ return 0;
+
default:
abort ();
}
@@ -1647,9 +2268,7 @@ struct simplify_plus_minus_op_data
};
static int
-simplify_plus_minus_op_data_cmp (p1, p2)
- const void *p1;
- const void *p2;
+simplify_plus_minus_op_data_cmp (const void *p1, const void *p2)
{
const struct simplify_plus_minus_op_data *d1 = p1;
const struct simplify_plus_minus_op_data *d2 = p2;
@@ -1659,19 +2278,16 @@ simplify_plus_minus_op_data_cmp (p1, p2)
}
static rtx
-simplify_plus_minus (code, mode, op0, op1, force)
- enum rtx_code code;
- enum machine_mode mode;
- rtx op0, op1;
- int force;
+simplify_plus_minus (enum rtx_code code, enum machine_mode mode, rtx op0,
+ rtx op1, int force)
{
struct simplify_plus_minus_op_data ops[8];
rtx result, tem;
int n_ops = 2, input_ops = 2, input_consts = 0, n_consts;
- int first, negate, changed;
+ int first, changed;
int i, j;
- memset ((char *) ops, 0, sizeof ops);
+ memset (ops, 0, sizeof ops);
/* Set up the two operands and then expand them until nothing has been
changed. If we run out of room in our array, give up; this should
@@ -1839,6 +2455,13 @@ simplify_plus_minus (code, mode, op0, op1, force)
/* Sort the operations based on swap_commutative_operands_p. */
qsort (ops, n_ops, sizeof (*ops), simplify_plus_minus_op_data_cmp);
+ /* Create (minus -C X) instead of (neg (const (plus X C))). */
+ if (n_ops == 2
+ && GET_CODE (ops[1].op) == CONST_INT
+ && CONSTANT_P (ops[0].op)
+ && ops[0].neg)
+ return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
+
/* We suppressed creation of trivial CONST expressions in the
combination loop to avoid recursion. Create one manually now.
The combination loop should have ensured that there is exactly
@@ -1871,18 +2494,12 @@ simplify_plus_minus (code, mode, op0, op1, force)
|| (n_ops + n_consts == input_ops && n_consts <= input_consts)))
return NULL_RTX;
- /* Put a non-negated operand first. If there aren't any, make all
- operands positive and negate the whole thing later. */
+ /* Put a non-negated operand first, if possible. */
- negate = 0;
for (i = 0; i < n_ops && ops[i].neg; i++)
continue;
if (i == n_ops)
- {
- for (i = 0; i < n_ops; i++)
- ops[i].neg = 0;
- negate = 1;
- }
+ ops[0].op = gen_rtx_NEG (mode, ops[0].op);
else if (i != 0)
{
tem = ops[0].op;
@@ -1897,7 +2514,7 @@ simplify_plus_minus (code, mode, op0, op1, force)
result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
mode, result, ops[i].op);
- return negate ? gen_rtx_NEG (mode, result) : result;
+ return result;
}
/* Like simplify_binary_operation except used for relational operators.
@@ -1909,10 +2526,8 @@ simplify_plus_minus (code, mode, op0, op1, force)
it returns either const_true_rtx or const0_rtx. */
rtx
-simplify_relational_operation (code, mode, op0, op1)
- enum rtx_code code;
- enum machine_mode mode;
- rtx op0, op1;
+simplify_relational_operation (enum rtx_code code, enum machine_mode mode,
+ rtx op0, rtx op1)
{
int equal, op0lt, op0ltu, op1lt, op1ltu;
rtx tem;
@@ -1933,11 +2548,7 @@ simplify_relational_operation (code, mode, op0, op1)
/* We can't simplify MODE_CC values since we don't know what the
actual comparison is. */
- if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC
-#ifdef HAVE_cc0
- || op0 == cc0_rtx
-#endif
- )
+ if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC || CC0_P (op0))
return 0;
/* Make sure the constant is second. */
@@ -1962,6 +2573,8 @@ simplify_relational_operation (code, mode, op0, op1)
&& ! ((GET_CODE (op0) == REG || GET_CODE (trueop0) == CONST_INT)
&& (GET_CODE (op1) == REG || GET_CODE (trueop1) == CONST_INT))
&& 0 != (tem = simplify_binary_operation (MINUS, mode, op0, op1))
+ /* We cannot do this for == or != if tem is a nonzero address. */
+ && ((code != EQ && code != NE) || ! nonzero_address_p (tem))
&& code != GTU && code != GEU && code != LTU && code != LEU)
return simplify_relational_operation (signed_condition (code),
mode, tem, const0_rtx);
@@ -1973,8 +2586,8 @@ simplify_relational_operation (code, mode, op0, op1)
return const0_rtx;
/* For modes without NaNs, if the two operands are equal, we know the
- result. Nevertheless, don't discard them if they have side-effects. */
- if (!HONOR_NANS (GET_MODE (trueop0))
+ result except if they have side-effects. */
+ if (! HONOR_NANS (GET_MODE (trueop0))
&& rtx_equal_p (trueop0, trueop1)
&& ! side_effects_p (trueop0))
equal = 1, op0lt = 0, op0ltu = 0, op1lt = 0, op1ltu = 0;
@@ -2082,25 +2695,12 @@ simplify_relational_operation (code, mode, op0, op1)
switch (code)
{
case EQ:
- /* References to the frame plus a constant or labels cannot
- be zero, but a SYMBOL_REF can due to #pragma weak. */
- if (((NONZERO_BASE_PLUS_P (op0) && trueop1 == const0_rtx)
- || GET_CODE (trueop0) == LABEL_REF)
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- /* On some machines, the ap reg can be 0 sometimes. */
- && op0 != arg_pointer_rtx
-#endif
- )
+ if (trueop1 == const0_rtx && nonzero_address_p (op0))
return const0_rtx;
break;
case NE:
- if (((NONZERO_BASE_PLUS_P (op0) && trueop1 == const0_rtx)
- || GET_CODE (trueop0) == LABEL_REF)
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- && op0 != arg_pointer_rtx
-#endif
- )
+ if (trueop1 == const0_rtx && nonzero_address_p (op0))
return const_true_rtx;
break;
@@ -2149,7 +2749,18 @@ simplify_relational_operation (code, mode, op0, op1)
tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
: trueop0;
if (GET_CODE (tem) == ABS)
- return const1_rtx;
+ return const_true_rtx;
+ }
+ break;
+
+ case UNGE:
+ /* Optimize ! (abs(x) < 0.0). */
+ if (trueop1 == CONST0_RTX (mode))
+ {
+ tem = GET_CODE (trueop0) == FLOAT_EXTEND ? XEXP (trueop0, 0)
+ : trueop0;
+ if (GET_CODE (tem) == ABS)
+ return const_true_rtx;
}
break;
@@ -2204,10 +2815,9 @@ simplify_relational_operation (code, mode, op0, op1)
a constant. Return 0 if no simplifications is possible. */
rtx
-simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
- enum rtx_code code;
- enum machine_mode mode, op0_mode;
- rtx op0, op1, op2;
+simplify_ternary_operation (enum rtx_code code, enum machine_mode mode,
+ enum machine_mode op0_mode, rtx op0, rtx op1,
+ rtx op2)
{
unsigned int width = GET_MODE_BITSIZE (mode);
@@ -2261,18 +2871,33 @@ simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
if (GET_CODE (op0) == CONST_INT)
return op0 != const0_rtx ? op1 : op2;
- /* Convert a == b ? b : a to "a". */
- if (GET_CODE (op0) == NE && ! side_effects_p (op0)
- && !HONOR_NANS (mode)
- && rtx_equal_p (XEXP (op0, 0), op1)
- && rtx_equal_p (XEXP (op0, 1), op2))
+ /* Convert c ? a : a into "a". */
+ if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
+ return op1;
+
+ /* Convert a != b ? a : b into "a". */
+ if (GET_CODE (op0) == NE
+ && ! side_effects_p (op0)
+ && ! HONOR_NANS (mode)
+ && ! HONOR_SIGNED_ZEROS (mode)
+ && ((rtx_equal_p (XEXP (op0, 0), op1)
+ && rtx_equal_p (XEXP (op0, 1), op2))
+ || (rtx_equal_p (XEXP (op0, 0), op2)
+ && rtx_equal_p (XEXP (op0, 1), op1))))
return op1;
- else if (GET_CODE (op0) == EQ && ! side_effects_p (op0)
- && !HONOR_NANS (mode)
- && rtx_equal_p (XEXP (op0, 1), op1)
- && rtx_equal_p (XEXP (op0, 0), op2))
+
+ /* Convert a == b ? a : b into "b". */
+ if (GET_CODE (op0) == EQ
+ && ! side_effects_p (op0)
+ && ! HONOR_NANS (mode)
+ && ! HONOR_SIGNED_ZEROS (mode)
+ && ((rtx_equal_p (XEXP (op0, 0), op1)
+ && rtx_equal_p (XEXP (op0, 1), op2))
+ || (rtx_equal_p (XEXP (op0, 0), op2)
+ && rtx_equal_p (XEXP (op0, 1), op1))))
return op2;
- else if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && ! side_effects_p (op0))
+
+ if (GET_RTX_CLASS (GET_CODE (op0)) == '<' && ! side_effects_p (op0))
{
enum machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
? GET_MODE (XEXP (op0, 1))
@@ -2286,10 +2911,10 @@ simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
/* See if any simplifications were possible. */
if (temp == const0_rtx)
return op2;
- else if (temp == const1_rtx)
+ else if (temp == const_true_rtx)
return op1;
else if (temp)
- op0 = temp;
+ abort ();
/* Look for happy constants in op1 and op2. */
if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
@@ -2314,28 +2939,38 @@ simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
}
}
break;
+
case VEC_MERGE:
if (GET_MODE (op0) != mode
|| GET_MODE (op1) != mode
|| !VECTOR_MODE_P (mode))
abort ();
- op0 = avoid_constant_pool_reference (op0);
- op1 = avoid_constant_pool_reference (op1);
op2 = avoid_constant_pool_reference (op2);
- if (GET_CODE (op0) == CONST_VECTOR
- && GET_CODE (op1) == CONST_VECTOR
- && GET_CODE (op2) == CONST_INT)
+ if (GET_CODE (op2) == CONST_INT)
{
int elt_size = GET_MODE_SIZE (GET_MODE_INNER (mode));
unsigned n_elts = (GET_MODE_SIZE (mode) / elt_size);
- rtvec v = rtvec_alloc (n_elts);
- unsigned int i;
+ int mask = (1 << n_elts) - 1;
- for (i = 0; i < n_elts; i++)
- RTVEC_ELT (v, i) = (INTVAL (op2) & (1 << i)
- ? CONST_VECTOR_ELT (op0, i)
- : CONST_VECTOR_ELT (op1, i));
- return gen_rtx_CONST_VECTOR (mode, v);
+ if (!(INTVAL (op2) & mask))
+ return op1;
+ if ((INTVAL (op2) & mask) == mask)
+ return op0;
+
+ op0 = avoid_constant_pool_reference (op0);
+ op1 = avoid_constant_pool_reference (op1);
+ if (GET_CODE (op0) == CONST_VECTOR
+ && GET_CODE (op1) == CONST_VECTOR)
+ {
+ rtvec v = rtvec_alloc (n_elts);
+ unsigned int i;
+
+ for (i = 0; i < n_elts; i++)
+ RTVEC_ELT (v, i) = (INTVAL (op2) & (1 << i)
+ ? CONST_VECTOR_ELT (op0, i)
+ : CONST_VECTOR_ELT (op1, i));
+ return gen_rtx_CONST_VECTOR (mode, v);
+ }
}
break;
@@ -2346,237 +2981,301 @@ simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
return 0;
}
-/* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
- Return 0 if no simplifications is possible. */
-rtx
-simplify_subreg (outermode, op, innermode, byte)
- rtx op;
- unsigned int byte;
- enum machine_mode outermode, innermode;
-{
- /* Little bit of sanity checking. */
- if (innermode == VOIDmode || outermode == VOIDmode
- || innermode == BLKmode || outermode == BLKmode)
- abort ();
-
- if (GET_MODE (op) != innermode
- && GET_MODE (op) != VOIDmode)
- abort ();
+/* Evaluate a SUBREG of a CONST_INT or CONST_DOUBLE or CONST_VECTOR,
+ returning another CONST_INT or CONST_DOUBLE or CONST_VECTOR.
- if (byte % GET_MODE_SIZE (outermode)
- || byte >= GET_MODE_SIZE (innermode))
- abort ();
+ Works by unpacking OP into a collection of 8-bit values
+ represented as a little-endian array of 'unsigned char', selecting by BYTE,
+ and then repacking them again for OUTERMODE. */
- if (outermode == innermode && !byte)
+static rtx
+simplify_immed_subreg (enum machine_mode outermode, rtx op,
+ enum machine_mode innermode, unsigned int byte)
+{
+ /* We support up to 512-bit values (for V8DFmode). */
+ enum {
+ max_bitsize = 512,
+ value_bit = 8,
+ value_mask = (1 << value_bit) - 1
+ };
+ unsigned char value[max_bitsize / value_bit];
+ int value_start;
+ int i;
+ int elem;
+
+ int num_elem;
+ rtx * elems;
+ int elem_bitsize;
+ rtx result_s;
+ rtvec result_v = NULL;
+ enum mode_class outer_class;
+ enum machine_mode outer_submode;
+
+ /* Some ports misuse CCmode. */
+ if (GET_MODE_CLASS (outermode) == MODE_CC && GET_CODE (op) == CONST_INT)
return op;
- /* Simplify subregs of vector constants. */
+ /* Unpack the value. */
+
if (GET_CODE (op) == CONST_VECTOR)
{
- int elt_size = GET_MODE_SIZE (GET_MODE_INNER (innermode));
- const unsigned int offset = byte / elt_size;
- rtx elt;
+ num_elem = CONST_VECTOR_NUNITS (op);
+ elems = &CONST_VECTOR_ELT (op, 0);
+ elem_bitsize = GET_MODE_BITSIZE (GET_MODE_INNER (innermode));
+ }
+ else
+ {
+ num_elem = 1;
+ elems = &op;
+ elem_bitsize = max_bitsize;
+ }
- if (GET_MODE_INNER (innermode) == outermode)
+ if (BITS_PER_UNIT % value_bit != 0)
+ abort (); /* Too complicated; reducing value_bit may help. */
+ if (elem_bitsize % BITS_PER_UNIT != 0)
+ abort (); /* I don't know how to handle endianness of sub-units. */
+
+ for (elem = 0; elem < num_elem; elem++)
+ {
+ unsigned char * vp;
+ rtx el = elems[elem];
+
+ /* Vectors are kept in target memory order. (This is probably
+ a mistake.) */
+ {
+ unsigned byte = (elem * elem_bitsize) / BITS_PER_UNIT;
+ unsigned ibyte = (((num_elem - 1 - elem) * elem_bitsize)
+ / BITS_PER_UNIT);
+ unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
+ unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
+ unsigned bytele = (subword_byte % UNITS_PER_WORD
+ + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
+ vp = value + (bytele * BITS_PER_UNIT) / value_bit;
+ }
+
+ switch (GET_CODE (el))
{
- elt = CONST_VECTOR_ELT (op, offset);
-
- /* ?? We probably don't need this copy_rtx because constants
- can be shared. ?? */
+ case CONST_INT:
+ for (i = 0;
+ i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
+ i += value_bit)
+ *vp++ = INTVAL (el) >> i;
+ /* CONST_INTs are always logically sign-extended. */
+ for (; i < elem_bitsize; i += value_bit)
+ *vp++ = INTVAL (el) < 0 ? -1 : 0;
+ break;
+
+ case CONST_DOUBLE:
+ if (GET_MODE (el) == VOIDmode)
+ {
+ /* If this triggers, someone should have generated a
+ CONST_INT instead. */
+ if (elem_bitsize <= HOST_BITS_PER_WIDE_INT)
+ abort ();
- return copy_rtx (elt);
- }
- else if (GET_MODE_INNER (innermode) == GET_MODE_INNER (outermode)
- && GET_MODE_SIZE (innermode) > GET_MODE_SIZE (outermode))
- {
- return (gen_rtx_CONST_VECTOR
- (outermode,
- gen_rtvec_v (GET_MODE_NUNITS (outermode),
- &CONST_VECTOR_ELT (op, offset))));
- }
- else if (GET_MODE_CLASS (outermode) == MODE_INT
- && (GET_MODE_SIZE (outermode) % elt_size == 0))
- {
- /* This happens when the target register size is smaller then
- the vector mode, and we synthesize operations with vectors
- of elements that are smaller than the register size. */
- HOST_WIDE_INT sum = 0, high = 0;
- unsigned n_elts = (GET_MODE_SIZE (outermode) / elt_size);
- unsigned i = BYTES_BIG_ENDIAN ? offset : offset + n_elts - 1;
- unsigned step = BYTES_BIG_ENDIAN ? 1 : -1;
- int shift = BITS_PER_UNIT * elt_size;
-
- for (; n_elts--; i += step)
+ for (i = 0; i < HOST_BITS_PER_WIDE_INT; i += value_bit)
+ *vp++ = CONST_DOUBLE_LOW (el) >> i;
+ while (i < HOST_BITS_PER_WIDE_INT * 2 && i < elem_bitsize)
+ {
+ *vp++
+ = CONST_DOUBLE_HIGH (el) >> (i - HOST_BITS_PER_WIDE_INT);
+ i += value_bit;
+ }
+ /* It shouldn't matter what's done here, so fill it with
+ zero. */
+ for (; i < max_bitsize; i += value_bit)
+ *vp++ = 0;
+ }
+ else if (GET_MODE_CLASS (GET_MODE (el)) == MODE_FLOAT)
{
- elt = CONST_VECTOR_ELT (op, i);
- if (GET_CODE (elt) == CONST_DOUBLE
- && GET_MODE_CLASS (GET_MODE (elt)) == MODE_FLOAT)
+ long tmp[max_bitsize / 32];
+ int bitsize = GET_MODE_BITSIZE (GET_MODE (el));
+
+ if (bitsize > elem_bitsize)
+ abort ();
+ if (bitsize % value_bit != 0)
+ abort ();
+
+ real_to_target (tmp, CONST_DOUBLE_REAL_VALUE (el),
+ GET_MODE (el));
+
+ /* real_to_target produces its result in words affected by
+ FLOAT_WORDS_BIG_ENDIAN. However, we ignore this,
+ and use WORDS_BIG_ENDIAN instead; see the documentation
+ of SUBREG in rtl.texi. */
+ for (i = 0; i < bitsize; i += value_bit)
{
- elt = gen_lowpart_common (int_mode_for_mode (GET_MODE (elt)),
- elt);
- if (! elt)
- return NULL_RTX;
+ int ibase;
+ if (WORDS_BIG_ENDIAN)
+ ibase = bitsize - 1 - i;
+ else
+ ibase = i;
+ *vp++ = tmp[ibase / 32] >> i % 32;
}
- if (GET_CODE (elt) != CONST_INT)
- return NULL_RTX;
- /* Avoid overflow. */
- if (high >> (HOST_BITS_PER_WIDE_INT - shift))
- return NULL_RTX;
- high = high << shift | sum >> (HOST_BITS_PER_WIDE_INT - shift);
- sum = (sum << shift) + INTVAL (elt);
+
+ /* It shouldn't matter what's done here, so fill it with
+ zero. */
+ for (; i < elem_bitsize; i += value_bit)
+ *vp++ = 0;
}
- if (GET_MODE_BITSIZE (outermode) <= HOST_BITS_PER_WIDE_INT)
- return GEN_INT (trunc_int_for_mode (sum, outermode));
- else if (GET_MODE_BITSIZE (outermode) == 2* HOST_BITS_PER_WIDE_INT)
- return immed_double_const (sum, high, outermode);
else
- return NULL_RTX;
- }
- else if (GET_MODE_CLASS (outermode) == MODE_INT
- && (elt_size % GET_MODE_SIZE (outermode) == 0))
- {
- enum machine_mode new_mode
- = int_mode_for_mode (GET_MODE_INNER (innermode));
- int subbyte = byte % elt_size;
-
- op = simplify_subreg (new_mode, op, innermode, byte - subbyte);
- if (! op)
- return NULL_RTX;
- return simplify_subreg (outermode, op, new_mode, subbyte);
+ abort ();
+ break;
+
+ default:
+ abort ();
}
- else if (GET_MODE_CLASS (outermode) == MODE_INT)
- /* This shouldn't happen, but let's not do anything stupid. */
- return NULL_RTX;
}
- /* Attempt to simplify constant to non-SUBREG expression. */
- if (CONSTANT_P (op))
+ /* Now, pick the right byte to start with. */
+ /* Renumber BYTE so that the least-significant byte is byte 0. A special
+ case is paradoxical SUBREGs, which shouldn't be adjusted since they
+ will already have offset 0. */
+ if (GET_MODE_SIZE (innermode) >= GET_MODE_SIZE (outermode))
{
- int offset, part;
- unsigned HOST_WIDE_INT val = 0;
+ unsigned ibyte = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode)
+ - byte);
+ unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
+ unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
+ byte = (subword_byte % UNITS_PER_WORD
+ + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
+ }
- if (GET_MODE_CLASS (outermode) == MODE_VECTOR_INT
- || GET_MODE_CLASS (outermode) == MODE_VECTOR_FLOAT)
- {
- /* Construct a CONST_VECTOR from individual subregs. */
- enum machine_mode submode = GET_MODE_INNER (outermode);
- int subsize = GET_MODE_UNIT_SIZE (outermode);
- int i, elts = GET_MODE_NUNITS (outermode);
- rtvec v = rtvec_alloc (elts);
- rtx elt;
-
- for (i = 0; i < elts; i++, byte += subsize)
- {
- /* This might fail, e.g. if taking a subreg from a SYMBOL_REF. */
- /* ??? It would be nice if we could actually make such subregs
- on targets that allow such relocations. */
- if (byte >= GET_MODE_UNIT_SIZE (innermode))
- elt = CONST0_RTX (submode);
- else
- elt = simplify_subreg (submode, op, innermode, byte);
- if (! elt)
- return NULL_RTX;
- RTVEC_ELT (v, i) = elt;
- }
- return gen_rtx_CONST_VECTOR (outermode, v);
- }
+ /* BYTE should still be inside OP. (Note that BYTE is unsigned,
+ so if it's become negative it will instead be very large.) */
+ if (byte >= GET_MODE_SIZE (innermode))
+ abort ();
- /* ??? This code is partly redundant with code below, but can handle
- the subregs of floats and similar corner cases.
- Later it we should move all simplification code here and rewrite
- GEN_LOWPART_IF_POSSIBLE, GEN_HIGHPART, OPERAND_SUBWORD and friends
- using SIMPLIFY_SUBREG. */
- if (subreg_lowpart_offset (outermode, innermode) == byte
- && GET_CODE (op) != CONST_VECTOR)
- {
- rtx new = gen_lowpart_if_possible (outermode, op);
- if (new)
- return new;
- }
+ /* Convert from bytes to chunks of size value_bit. */
+ value_start = byte * (BITS_PER_UNIT / value_bit);
- /* Similar comment as above apply here. */
- if (GET_MODE_SIZE (outermode) == UNITS_PER_WORD
- && GET_MODE_SIZE (innermode) > UNITS_PER_WORD
- && GET_MODE_CLASS (outermode) == MODE_INT)
- {
- rtx new = constant_subword (op,
- (byte / UNITS_PER_WORD),
- innermode);
- if (new)
- return new;
- }
+ /* Re-pack the value. */
+
+ if (VECTOR_MODE_P (outermode))
+ {
+ num_elem = GET_MODE_NUNITS (outermode);
+ result_v = rtvec_alloc (num_elem);
+ elems = &RTVEC_ELT (result_v, 0);
+ outer_submode = GET_MODE_INNER (outermode);
+ }
+ else
+ {
+ num_elem = 1;
+ elems = &result_s;
+ outer_submode = outermode;
+ }
- if (GET_MODE_CLASS (outermode) != MODE_INT
- && GET_MODE_CLASS (outermode) != MODE_CC)
- {
- enum machine_mode new_mode = int_mode_for_mode (outermode);
+ outer_class = GET_MODE_CLASS (outer_submode);
+ elem_bitsize = GET_MODE_BITSIZE (outer_submode);
- if (new_mode != innermode || byte != 0)
- {
- op = simplify_subreg (new_mode, op, innermode, byte);
- if (! op)
- return NULL_RTX;
- return simplify_subreg (outermode, op, new_mode, 0);
- }
- }
+ if (elem_bitsize % value_bit != 0)
+ abort ();
+ if (elem_bitsize + value_start * value_bit > max_bitsize)
+ abort ();
- offset = byte * BITS_PER_UNIT;
- switch (GET_CODE (op))
- {
- case CONST_DOUBLE:
- if (GET_MODE (op) != VOIDmode)
- break;
+ for (elem = 0; elem < num_elem; elem++)
+ {
+ unsigned char *vp;
+
+ /* Vectors are stored in target memory order. (This is probably
+ a mistake.) */
+ {
+ unsigned byte = (elem * elem_bitsize) / BITS_PER_UNIT;
+ unsigned ibyte = (((num_elem - 1 - elem) * elem_bitsize)
+ / BITS_PER_UNIT);
+ unsigned word_byte = WORDS_BIG_ENDIAN ? ibyte : byte;
+ unsigned subword_byte = BYTES_BIG_ENDIAN ? ibyte : byte;
+ unsigned bytele = (subword_byte % UNITS_PER_WORD
+ + (word_byte / UNITS_PER_WORD) * UNITS_PER_WORD);
+ vp = value + value_start + (bytele * BITS_PER_UNIT) / value_bit;
+ }
- /* We can't handle this case yet. */
- if (GET_MODE_BITSIZE (outermode) >= HOST_BITS_PER_WIDE_INT)
- return NULL_RTX;
+ switch (outer_class)
+ {
+ case MODE_INT:
+ case MODE_PARTIAL_INT:
+ {
+ unsigned HOST_WIDE_INT hi = 0, lo = 0;
+
+ for (i = 0;
+ i < HOST_BITS_PER_WIDE_INT && i < elem_bitsize;
+ i += value_bit)
+ lo |= (HOST_WIDE_INT)(*vp++ & value_mask) << i;
+ for (; i < elem_bitsize; i += value_bit)
+ hi |= ((HOST_WIDE_INT)(*vp++ & value_mask)
+ << (i - HOST_BITS_PER_WIDE_INT));
+
+ /* immed_double_const doesn't call trunc_int_for_mode. I don't
+ know why. */
+ if (elem_bitsize <= HOST_BITS_PER_WIDE_INT)
+ elems[elem] = gen_int_mode (lo, outer_submode);
+ else
+ elems[elem] = immed_double_const (lo, hi, outer_submode);
+ }
+ break;
+
+ case MODE_FLOAT:
+ {
+ REAL_VALUE_TYPE r;
+ long tmp[max_bitsize / 32];
+
+ /* real_from_target wants its input in words affected by
+ FLOAT_WORDS_BIG_ENDIAN. However, we ignore this,
+ and use WORDS_BIG_ENDIAN instead; see the documentation
+ of SUBREG in rtl.texi. */
+ for (i = 0; i < max_bitsize / 32; i++)
+ tmp[i] = 0;
+ for (i = 0; i < elem_bitsize; i += value_bit)
+ {
+ int ibase;
+ if (WORDS_BIG_ENDIAN)
+ ibase = elem_bitsize - 1 - i;
+ else
+ ibase = i;
+ tmp[ibase / 32] |= (*vp++ & value_mask) << i % 32;
+ }
- part = offset >= HOST_BITS_PER_WIDE_INT;
- if ((BITS_PER_WORD > HOST_BITS_PER_WIDE_INT
- && BYTES_BIG_ENDIAN)
- || (BITS_PER_WORD <= HOST_BITS_PER_WIDE_INT
- && WORDS_BIG_ENDIAN))
- part = !part;
- val = part ? CONST_DOUBLE_HIGH (op) : CONST_DOUBLE_LOW (op);
- offset %= HOST_BITS_PER_WIDE_INT;
+ real_from_target (&r, tmp, outer_submode);
+ elems[elem] = CONST_DOUBLE_FROM_REAL_VALUE (r, outer_submode);
+ }
+ break;
+
+ default:
+ abort ();
+ }
+ }
+ if (VECTOR_MODE_P (outermode))
+ return gen_rtx_CONST_VECTOR (outermode, result_v);
+ else
+ return result_s;
+}
- /* We've already picked the word we want from a double, so
- pretend this is actually an integer. */
- innermode = mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0);
+/* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
+ Return 0 if no simplifications are possible. */
+rtx
+simplify_subreg (enum machine_mode outermode, rtx op,
+ enum machine_mode innermode, unsigned int byte)
+{
+ /* Little bit of sanity checking. */
+ if (innermode == VOIDmode || outermode == VOIDmode
+ || innermode == BLKmode || outermode == BLKmode)
+ abort ();
- /* FALLTHROUGH */
- case CONST_INT:
- if (GET_CODE (op) == CONST_INT)
- val = INTVAL (op);
+ if (GET_MODE (op) != innermode
+ && GET_MODE (op) != VOIDmode)
+ abort ();
- /* We don't handle synthetizing of non-integral constants yet. */
- if (GET_MODE_CLASS (outermode) != MODE_INT)
- return NULL_RTX;
+ if (byte % GET_MODE_SIZE (outermode)
+ || byte >= GET_MODE_SIZE (innermode))
+ abort ();
- if (BYTES_BIG_ENDIAN || WORDS_BIG_ENDIAN)
- {
- if (WORDS_BIG_ENDIAN)
- offset = (GET_MODE_BITSIZE (innermode)
- - GET_MODE_BITSIZE (outermode) - offset);
- if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
- && GET_MODE_SIZE (outermode) < UNITS_PER_WORD)
- offset = (offset + BITS_PER_WORD - GET_MODE_BITSIZE (outermode)
- - 2 * (offset % BITS_PER_WORD));
- }
+ if (outermode == innermode && !byte)
+ return op;
- if (offset >= HOST_BITS_PER_WIDE_INT)
- return ((HOST_WIDE_INT) val < 0) ? constm1_rtx : const0_rtx;
- else
- {
- val >>= offset;
- if (GET_MODE_BITSIZE (outermode) < HOST_BITS_PER_WIDE_INT)
- val = trunc_int_for_mode (val, outermode);
- return GEN_INT (val);
- }
- default:
- break;
- }
- }
+ if (GET_CODE (op) == CONST_INT
+ || GET_CODE (op) == CONST_DOUBLE
+ || GET_CODE (op) == CONST_VECTOR)
+ return simplify_immed_subreg (outermode, op, innermode, byte);
/* Changing mode twice with SUBREG => just change it once,
or not at all if changing back op starting mode. */
@@ -2640,7 +3339,7 @@ simplify_subreg (outermode, op, innermode, byte)
return NULL_RTX;
}
- /* Recurse for futher possible simplifications. */
+ /* Recurse for further possible simplifications. */
new = simplify_subreg (outermode, SUBREG_REG (op),
GET_MODE (SUBREG_REG (op)),
final_offset);
@@ -2672,10 +3371,12 @@ simplify_subreg (outermode, op, innermode, byte)
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
&& REGNO (op) != ARG_POINTER_REGNUM
#endif
- && REGNO (op) != STACK_POINTER_REGNUM)
+ && REGNO (op) != STACK_POINTER_REGNUM
+ && subreg_offset_representable_p (REGNO (op), innermode,
+ byte, outermode))
{
- int final_regno = subreg_hard_regno (gen_rtx_SUBREG (outermode, op, byte),
- 0);
+ rtx tem = gen_rtx_SUBREG (outermode, op, byte);
+ int final_regno = subreg_hard_regno (tem, 0);
/* ??? We do allow it if the current REG is not valid for
its mode. This is a kludge to work around how float/complex
@@ -2683,10 +3384,10 @@ simplify_subreg (outermode, op, innermode, byte)
if (HARD_REGNO_MODE_OK (final_regno, outermode)
|| ! HARD_REGNO_MODE_OK (REGNO (op), innermode))
{
- rtx x = gen_rtx_REG (outermode, final_regno);
+ rtx x = gen_rtx_REG_offset (op, outermode, final_regno, byte);
/* Propagate original regno. We don't have any way to specify
- the offset inside orignal regno, so do so only for lowpart.
+ the offset inside original regno, so do so only for lowpart.
The information is used only by alias analysis that can not
grog partial register anyway. */
@@ -2714,7 +3415,7 @@ simplify_subreg (outermode, op, innermode, byte)
of real and imaginary part. */
if (GET_CODE (op) == CONCAT)
{
- int is_realpart = byte < GET_MODE_UNIT_SIZE (innermode);
+ int is_realpart = byte < (unsigned int) GET_MODE_UNIT_SIZE (innermode);
rtx part = is_realpart ? XEXP (op, 0) : XEXP (op, 1);
unsigned int final_offset;
rtx res;
@@ -2729,13 +3430,12 @@ simplify_subreg (outermode, op, innermode, byte)
return NULL_RTX;
}
+
/* Make a SUBREG operation or equivalent if it folds. */
rtx
-simplify_gen_subreg (outermode, op, innermode, byte)
- rtx op;
- unsigned int byte;
- enum machine_mode outermode, innermode;
+simplify_gen_subreg (enum machine_mode outermode, rtx op,
+ enum machine_mode innermode, unsigned int byte)
{
rtx new;
/* Little bit of sanity checking. */
@@ -2771,7 +3471,7 @@ simplify_gen_subreg (outermode, op, innermode, byte)
This is the preferred entry point into the simplification routines;
however, we still allow passes to call the more specific routines.
- Right now GCC has three (yes, three) major bodies of RTL simplficiation
+ Right now GCC has three (yes, three) major bodies of RTL simplification
code that need to be unified.
1. fold_rtx in cse.c. This code uses various CSE specific
@@ -2804,11 +3504,11 @@ simplify_gen_subreg (outermode, op, innermode, byte)
simplification and 1 for tree simplification. */
rtx
-simplify_rtx (x)
- rtx x;
+simplify_rtx (rtx x)
{
enum rtx_code code = GET_CODE (x);
enum machine_mode mode = GET_MODE (x);
+ rtx temp;
switch (GET_RTX_CLASS (code))
{
@@ -2817,15 +3517,9 @@ simplify_rtx (x)
XEXP (x, 0), GET_MODE (XEXP (x, 0)));
case 'c':
if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
- {
- rtx tem;
+ return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
- tem = XEXP (x, 0);
- XEXP (x, 0) = XEXP (x, 1);
- XEXP (x, 1) = tem;
- return simplify_binary_operation (code, mode,
- XEXP (x, 0), XEXP (x, 1));
- }
+ /* Fall through.... */
case '2':
return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
@@ -2837,20 +3531,48 @@ simplify_rtx (x)
XEXP (x, 2));
case '<':
- return simplify_relational_operation (code,
+ temp = simplify_relational_operation (code,
((GET_MODE (XEXP (x, 0))
!= VOIDmode)
? GET_MODE (XEXP (x, 0))
: GET_MODE (XEXP (x, 1))),
XEXP (x, 0), XEXP (x, 1));
+#ifdef FLOAT_STORE_FLAG_VALUE
+ if (temp != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ if (temp == const0_rtx)
+ temp = CONST0_RTX (mode);
+ else
+ temp = CONST_DOUBLE_FROM_REAL_VALUE (FLOAT_STORE_FLAG_VALUE (mode),
+ mode);
+ }
+#endif
+ return temp;
+
case 'x':
- /* The only case we try to handle is a SUBREG. */
if (code == SUBREG)
return simplify_gen_subreg (mode, SUBREG_REG (x),
GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x));
- return NULL;
+ if (code == CONSTANT_P_RTX)
+ {
+ if (CONSTANT_P (XEXP (x, 0)))
+ return const1_rtx;
+ }
+ break;
+
+ case 'o':
+ if (code == LO_SUM)
+ {
+ /* Convert (lo_sum (high FOO) FOO) to FOO. */
+ if (GET_CODE (XEXP (x, 0)) == HIGH
+ && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
+ return XEXP (x, 1);
+ }
+ break;
+
default:
- return NULL;
+ break;
}
+ return NULL;
}
diff --git a/contrib/gcc/splay-tree.c b/contrib/gcc/splay-tree.c
index 6f90fde05fba..fc98db167f32 100644
--- a/contrib/gcc/splay-tree.c
+++ b/contrib/gcc/splay-tree.c
@@ -472,7 +472,7 @@ splay_tree_predecessor (sp, key)
if (comparison < 0)
return sp->root;
- /* Otherwise, find the leftmost element of the right subtree. */
+ /* Otherwise, find the rightmost element of the left subtree. */
node = sp->root->left;
if (node)
while (node->right)
@@ -505,7 +505,7 @@ splay_tree_successor (sp, key)
if (comparison > 0)
return sp->root;
- /* Otherwise, find the rightmost element of the left subtree. */
+ /* Otherwise, find the leftmost element of the right subtree. */
node = sp->root->right;
if (node)
while (node->left)
diff --git a/contrib/gcc/splay-tree.h b/contrib/gcc/splay-tree.h
index 23f7ac69d42b..86707fc1d2ff 100644
--- a/contrib/gcc/splay-tree.h
+++ b/contrib/gcc/splay-tree.h
@@ -36,6 +36,10 @@ extern "C" {
#include "ansidecl.h"
+#ifndef GTY
+#define GTY(X)
+#endif
+
/* Use typedefs for the key and data types to facilitate changing
these types, if necessary. These types should be sufficiently wide
that any pointer or scalar can be cast to these types, and then
@@ -65,7 +69,7 @@ typedef int (*splay_tree_foreach_fn) PARAMS((splay_tree_node, void*));
node structures. The first argument is the number of bytes needed;
the second is a data pointer the splay tree functions pass through
to the allocator. This function must never return zero. */
-typedef void *(*splay_tree_allocate_fn) PARAMS((int, void *));
+typedef PTR (*splay_tree_allocate_fn) PARAMS((int, void *));
/* The type of a function used to free memory allocated using the
corresponding splay_tree_allocate_fn. The first argument is the
@@ -74,24 +78,24 @@ typedef void *(*splay_tree_allocate_fn) PARAMS((int, void *));
typedef void (*splay_tree_deallocate_fn) PARAMS((void *, void *));
/* The nodes in the splay tree. */
-struct splay_tree_node_s
+struct splay_tree_node_s GTY(())
{
/* The key. */
- splay_tree_key key;
+ splay_tree_key GTY ((use_param1 (""))) key;
/* The value. */
- splay_tree_value value;
+ splay_tree_value GTY ((use_param2 (""))) value;
/* The left and right children, respectively. */
- splay_tree_node left;
- splay_tree_node right;
+ splay_tree_node GTY ((use_params (""))) left;
+ splay_tree_node GTY ((use_params (""))) right;
};
/* The splay tree itself. */
-typedef struct splay_tree_s
+struct splay_tree_s GTY(())
{
/* The root of the tree. */
- splay_tree_node root;
+ splay_tree_node GTY ((use_params (""))) root;
/* The comparision function. */
splay_tree_compare_fn comp;
@@ -105,9 +109,10 @@ typedef struct splay_tree_s
/* Allocate/free functions, and a data pointer to pass to them. */
splay_tree_allocate_fn allocate;
splay_tree_deallocate_fn deallocate;
- void *allocate_data;
+ PTR GTY((skip (""))) allocate_data;
-} *splay_tree;
+};
+typedef struct splay_tree_s *splay_tree;
extern splay_tree splay_tree_new PARAMS((splay_tree_compare_fn,
splay_tree_delete_key_fn,
diff --git a/contrib/gcc/sreal.c b/contrib/gcc/sreal.c
new file mode 100644
index 000000000000..8980659c99bb
--- /dev/null
+++ b/contrib/gcc/sreal.c
@@ -0,0 +1,561 @@
+/* Simple data type for positive real numbers for the GNU compiler.
+ Copyright (C) 2002, 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* This library supports positive real numbers and 0;
+ inf and nan are NOT supported.
+ It is written to be simple and fast.
+
+ Value of sreal is
+ x = sig * 2 ^ exp
+ where
+ sig = significant
+ (for < 64-bit machines sig = sig_lo + sig_hi * 2 ^ SREAL_PART_BITS)
+ exp = exponent
+
+ One HOST_WIDE_INT is used for the significant on 64-bit (and more than
+ 64-bit) machines,
+ otherwise two HOST_WIDE_INTs are used for the significant.
+ Only a half of significant bits is used (in normalized sreals) so that we do
+ not have problems with overflow, for example when c->sig = a->sig * b->sig.
+ So the precision for 64-bit and 32-bit machines is 32-bit.
+
+ Invariant: The numbers are normalized before and after each call of sreal_*.
+
+ Normalized sreals:
+ All numbers (except zero) meet following conditions:
+ SREAL_MIN_SIG <= sig && sig <= SREAL_MAX_SIG
+ -SREAL_MAX_EXP <= exp && exp <= SREAL_MAX_EXP
+
+ If the number would be too large, it is set to upper bounds of these
+ conditions.
+
+ If the number is zero or would be too small it meets following conditions:
+ sig == 0 && exp == -SREAL_MAX_EXP
+*/
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "sreal.h"
+
+static inline void copy (sreal *, sreal *);
+static inline void shift_right (sreal *, int);
+static void normalize (sreal *);
+
+/* Print the content of struct sreal. */
+
+void
+dump_sreal (FILE *file, sreal *x)
+{
+#if SREAL_PART_BITS < 32
+ fprintf (file, "((" HOST_WIDE_INT_PRINT_UNSIGNED " * 2^16 + "
+ HOST_WIDE_INT_PRINT_UNSIGNED ") * 2^%d)",
+ x->sig_hi, x->sig_lo, x->exp);
+#else
+ fprintf (file, "(" HOST_WIDE_INT_PRINT_UNSIGNED " * 2^%d)", x->sig, x->exp);
+#endif
+}
+
+/* Copy the sreal number. */
+
+static inline void
+copy (sreal *r, sreal *a)
+{
+#if SREAL_PART_BITS < 32
+ r->sig_lo = a->sig_lo;
+ r->sig_hi = a->sig_hi;
+#else
+ r->sig = a->sig;
+#endif
+ r->exp = a->exp;
+}
+
+/* Shift X right by S bits. Needed: 0 < S <= SREAL_BITS.
+ When the most significant bit shifted out is 1, add 1 to X (rounding). */
+
+static inline void
+shift_right (sreal *x, int s)
+{
+#ifdef ENABLE_CHECKING
+ if (s <= 0 || s > SREAL_BITS)
+ abort ();
+ if (x->exp + s > SREAL_MAX_EXP)
+ {
+ /* Exponent should never be so large because shift_right is used only by
+ sreal_add and sreal_sub ant thus the number cannot be shifted out from
+ exponent range. */
+ abort ();
+ }
+#endif
+
+ x->exp += s;
+
+#if SREAL_PART_BITS < 32
+ if (s > SREAL_PART_BITS)
+ {
+ s -= SREAL_PART_BITS;
+ x->sig_hi += (uhwi) 1 << (s - 1);
+ x->sig_lo = x->sig_hi >> s;
+ x->sig_hi = 0;
+ }
+ else
+ {
+ x->sig_lo += (uhwi) 1 << (s - 1);
+ if (x->sig_lo & ((uhwi) 1 << SREAL_PART_BITS))
+ {
+ x->sig_hi++;
+ x->sig_lo -= (uhwi) 1 << SREAL_PART_BITS;
+ }
+ x->sig_lo >>= s;
+ x->sig_lo |= (x->sig_hi & (((uhwi) 1 << s) - 1)) << (SREAL_PART_BITS - s);
+ x->sig_hi >>= s;
+ }
+#else
+ x->sig += (uhwi) 1 << (s - 1);
+ x->sig >>= s;
+#endif
+}
+
+/* Normalize *X. */
+
+static void
+normalize (sreal *x)
+{
+#if SREAL_PART_BITS < 32
+ int shift;
+ HOST_WIDE_INT mask;
+
+ if (x->sig_lo == 0 && x->sig_hi == 0)
+ {
+ x->exp = -SREAL_MAX_EXP;
+ }
+ else if (x->sig_hi < SREAL_MIN_SIG)
+ {
+ if (x->sig_hi == 0)
+ {
+ /* Move lower part of significant to higher part. */
+ x->sig_hi = x->sig_lo;
+ x->sig_lo = 0;
+ x->exp -= SREAL_PART_BITS;
+ }
+ shift = 0;
+ while (x->sig_hi < SREAL_MIN_SIG)
+ {
+ x->sig_hi <<= 1;
+ x->exp--;
+ shift++;
+ }
+ /* Check underflow. */
+ if (x->exp < -SREAL_MAX_EXP)
+ {
+ x->exp = -SREAL_MAX_EXP;
+ x->sig_hi = 0;
+ x->sig_lo = 0;
+ }
+ else if (shift)
+ {
+ mask = (1 << SREAL_PART_BITS) - (1 << (SREAL_PART_BITS - shift));
+ x->sig_hi |= (x->sig_lo & mask) >> (SREAL_PART_BITS - shift);
+ x->sig_lo = (x->sig_lo << shift) & (((uhwi) 1 << SREAL_PART_BITS) - 1);
+ }
+ }
+ else if (x->sig_hi > SREAL_MAX_SIG)
+ {
+ unsigned HOST_WIDE_INT tmp = x->sig_hi;
+
+ /* Find out how many bits will be shifted. */
+ shift = 0;
+ do
+ {
+ tmp >>= 1;
+ shift++;
+ }
+ while (tmp > SREAL_MAX_SIG);
+
+ /* Round the number. */
+ x->sig_lo += (uhwi) 1 << (shift - 1);
+
+ x->sig_lo >>= shift;
+ x->sig_lo += ((x->sig_hi & (((uhwi) 1 << shift) - 1))
+ << (SREAL_PART_BITS - shift));
+ x->sig_hi >>= shift;
+ x->exp += shift;
+ if (x->sig_lo & ((uhwi) 1 << SREAL_PART_BITS))
+ {
+ x->sig_lo -= (uhwi) 1 << SREAL_PART_BITS;
+ x->sig_hi++;
+ if (x->sig_hi > SREAL_MAX_SIG)
+ {
+ /* x->sig_hi was SREAL_MAX_SIG before increment
+ so now last bit is zero. */
+ x->sig_hi >>= 1;
+ x->sig_lo >>= 1;
+ x->exp++;
+ }
+ }
+
+ /* Check overflow. */
+ if (x->exp > SREAL_MAX_EXP)
+ {
+ x->exp = SREAL_MAX_EXP;
+ x->sig_hi = SREAL_MAX_SIG;
+ x->sig_lo = SREAL_MAX_SIG;
+ }
+ }
+#else
+ if (x->sig == 0)
+ {
+ x->exp = -SREAL_MAX_EXP;
+ }
+ else if (x->sig < SREAL_MIN_SIG)
+ {
+ do
+ {
+ x->sig <<= 1;
+ x->exp--;
+ }
+ while (x->sig < SREAL_MIN_SIG);
+
+ /* Check underflow. */
+ if (x->exp < -SREAL_MAX_EXP)
+ {
+ x->exp = -SREAL_MAX_EXP;
+ x->sig = 0;
+ }
+ }
+ else if (x->sig > SREAL_MAX_SIG)
+ {
+ int last_bit;
+ do
+ {
+ last_bit = x->sig & 1;
+ x->sig >>= 1;
+ x->exp++;
+ }
+ while (x->sig > SREAL_MAX_SIG);
+
+ /* Round the number. */
+ x->sig += last_bit;
+ if (x->sig > SREAL_MAX_SIG)
+ {
+ x->sig >>= 1;
+ x->exp++;
+ }
+
+ /* Check overflow. */
+ if (x->exp > SREAL_MAX_EXP)
+ {
+ x->exp = SREAL_MAX_EXP;
+ x->sig = SREAL_MAX_SIG;
+ }
+ }
+#endif
+}
+
+/* Set *R to SIG * 2 ^ EXP. Return R. */
+
+sreal *
+sreal_init (sreal *r, unsigned HOST_WIDE_INT sig, signed int exp)
+{
+#if SREAL_PART_BITS < 32
+ r->sig_lo = 0;
+ r->sig_hi = sig;
+ r->exp = exp - 16;
+#else
+ r->sig = sig;
+ r->exp = exp;
+#endif
+ normalize (r);
+ return r;
+}
+
+/* Return integer value of *R. */
+
+HOST_WIDE_INT
+sreal_to_int (sreal *r)
+{
+#if SREAL_PART_BITS < 32
+ if (r->exp <= -SREAL_BITS)
+ return 0;
+ if (r->exp >= 0)
+ return MAX_HOST_WIDE_INT;
+ return ((r->sig_hi << SREAL_PART_BITS) + r->sig_lo) >> -r->exp;
+#else
+ if (r->exp <= -SREAL_BITS)
+ return 0;
+ if (r->exp >= SREAL_PART_BITS)
+ return MAX_HOST_WIDE_INT;
+ if (r->exp > 0)
+ return r->sig << r->exp;
+ if (r->exp < 0)
+ return r->sig >> -r->exp;
+ return r->sig;
+#endif
+}
+
+/* Compare *A and *B. Return -1 if *A < *B, 1 if *A > *B and 0 if *A == *B. */
+
+int
+sreal_compare (sreal *a, sreal *b)
+{
+ if (a->exp > b->exp)
+ return 1;
+ if (a->exp < b->exp)
+ return -1;
+#if SREAL_PART_BITS < 32
+ if (a->sig_hi > b->sig_hi)
+ return 1;
+ if (a->sig_hi < b->sig_hi)
+ return -1;
+ if (a->sig_lo > b->sig_lo)
+ return 1;
+ if (a->sig_lo < b->sig_lo)
+ return -1;
+#else
+ if (a->sig > b->sig)
+ return 1;
+ if (a->sig < b->sig)
+ return -1;
+#endif
+ return 0;
+}
+
+/* *R = *A + *B. Return R. */
+
+sreal *
+sreal_add (sreal *r, sreal *a, sreal *b)
+{
+ int dexp;
+ sreal tmp;
+ sreal *bb;
+
+ if (sreal_compare (a, b) < 0)
+ {
+ sreal *swap;
+ swap = a;
+ a = b;
+ b = swap;
+ }
+
+ dexp = a->exp - b->exp;
+ r->exp = a->exp;
+ if (dexp > SREAL_BITS)
+ {
+#if SREAL_PART_BITS < 32
+ r->sig_hi = a->sig_hi;
+ r->sig_lo = a->sig_lo;
+#else
+ r->sig = a->sig;
+#endif
+ return r;
+ }
+
+ if (dexp == 0)
+ bb = b;
+ else
+ {
+ copy (&tmp, b);
+ shift_right (&tmp, dexp);
+ bb = &tmp;
+ }
+
+#if SREAL_PART_BITS < 32
+ r->sig_hi = a->sig_hi + bb->sig_hi;
+ r->sig_lo = a->sig_lo + bb->sig_lo;
+ if (r->sig_lo & ((uhwi) 1 << SREAL_PART_BITS))
+ {
+ r->sig_hi++;
+ r->sig_lo -= (uhwi) 1 << SREAL_PART_BITS;
+ }
+#else
+ r->sig = a->sig + bb->sig;
+#endif
+ normalize (r);
+ return r;
+}
+
+/* *R = *A - *B. Return R. */
+
+sreal *
+sreal_sub (sreal *r, sreal *a, sreal *b)
+{
+ int dexp;
+ sreal tmp;
+ sreal *bb;
+
+ if (sreal_compare (a, b) < 0)
+ {
+ abort ();
+ }
+
+ dexp = a->exp - b->exp;
+ r->exp = a->exp;
+ if (dexp > SREAL_BITS)
+ {
+#if SREAL_PART_BITS < 32
+ r->sig_hi = a->sig_hi;
+ r->sig_lo = a->sig_lo;
+#else
+ r->sig = a->sig;
+#endif
+ return r;
+ }
+ if (dexp == 0)
+ bb = b;
+ else
+ {
+ copy (&tmp, b);
+ shift_right (&tmp, dexp);
+ bb = &tmp;
+ }
+
+#if SREAL_PART_BITS < 32
+ if (a->sig_lo < bb->sig_lo)
+ {
+ r->sig_hi = a->sig_hi - bb->sig_hi - 1;
+ r->sig_lo = a->sig_lo + ((uhwi) 1 << SREAL_PART_BITS) - bb->sig_lo;
+ }
+ else
+ {
+ r->sig_hi = a->sig_hi - bb->sig_hi;
+ r->sig_lo = a->sig_lo - bb->sig_lo;
+ }
+#else
+ r->sig = a->sig - bb->sig;
+#endif
+ normalize (r);
+ return r;
+}
+
+/* *R = *A * *B. Return R. */
+
+sreal *
+sreal_mul (sreal *r, sreal *a, sreal *b)
+{
+#if SREAL_PART_BITS < 32
+ if (a->sig_hi < SREAL_MIN_SIG || b->sig_hi < SREAL_MIN_SIG)
+ {
+ r->sig_lo = 0;
+ r->sig_hi = 0;
+ r->exp = -SREAL_MAX_EXP;
+ }
+ else
+ {
+ unsigned HOST_WIDE_INT tmp1, tmp2, tmp3;
+ if (sreal_compare (a, b) < 0)
+ {
+ sreal *swap;
+ swap = a;
+ a = b;
+ b = swap;
+ }
+
+ r->exp = a->exp + b->exp + SREAL_PART_BITS;
+
+ tmp1 = a->sig_lo * b->sig_lo;
+ tmp2 = a->sig_lo * b->sig_hi;
+ tmp3 = a->sig_hi * b->sig_lo + (tmp1 >> SREAL_PART_BITS);
+
+ r->sig_hi = a->sig_hi * b->sig_hi;
+ r->sig_hi += (tmp2 >> SREAL_PART_BITS) + (tmp3 >> SREAL_PART_BITS);
+ tmp2 &= ((uhwi) 1 << SREAL_PART_BITS) - 1;
+ tmp3 &= ((uhwi) 1 << SREAL_PART_BITS) - 1;
+ tmp1 = tmp2 + tmp3;
+
+ r->sig_lo = tmp1 & (((uhwi) 1 << SREAL_PART_BITS) - 1);
+ r->sig_hi += tmp1 >> SREAL_PART_BITS;
+
+ normalize (r);
+ }
+#else
+ if (a->sig < SREAL_MIN_SIG || b->sig < SREAL_MIN_SIG)
+ {
+ r->sig = 0;
+ r->exp = -SREAL_MAX_EXP;
+ }
+ else
+ {
+ r->sig = a->sig * b->sig;
+ r->exp = a->exp + b->exp;
+ normalize (r);
+ }
+#endif
+ return r;
+}
+
+/* *R = *A / *B. Return R. */
+
+sreal *
+sreal_div (sreal *r, sreal *a, sreal *b)
+{
+#if SREAL_PART_BITS < 32
+ unsigned HOST_WIDE_INT tmp, tmp1, tmp2;
+
+ if (b->sig_hi < SREAL_MIN_SIG)
+ {
+ abort ();
+ }
+ else if (a->sig_hi < SREAL_MIN_SIG)
+ {
+ r->sig_hi = 0;
+ r->sig_lo = 0;
+ r->exp = -SREAL_MAX_EXP;
+ }
+ else
+ {
+ /* Since division by the whole number is pretty ugly to write
+ we are dividing by first 3/4 of bits of number. */
+
+ tmp1 = (a->sig_hi << SREAL_PART_BITS) + a->sig_lo;
+ tmp2 = ((b->sig_hi << (SREAL_PART_BITS / 2))
+ + (b->sig_lo >> (SREAL_PART_BITS / 2)));
+ if (b->sig_lo & ((uhwi) 1 << ((SREAL_PART_BITS / 2) - 1)))
+ tmp2++;
+
+ r->sig_lo = 0;
+ tmp = tmp1 / tmp2;
+ tmp1 = (tmp1 % tmp2) << (SREAL_PART_BITS / 2);
+ r->sig_hi = tmp << SREAL_PART_BITS;
+
+ tmp = tmp1 / tmp2;
+ tmp1 = (tmp1 % tmp2) << (SREAL_PART_BITS / 2);
+ r->sig_hi += tmp << (SREAL_PART_BITS / 2);
+
+ tmp = tmp1 / tmp2;
+ r->sig_hi += tmp;
+
+ r->exp = a->exp - b->exp - SREAL_BITS - SREAL_PART_BITS / 2;
+ normalize (r);
+ }
+#else
+ if (b->sig == 0)
+ {
+ abort ();
+ }
+ else
+ {
+ r->sig = (a->sig << SREAL_PART_BITS) / b->sig;
+ r->exp = a->exp - b->exp - SREAL_PART_BITS;
+ normalize (r);
+ }
+#endif
+ return r;
+}
diff --git a/contrib/gcc/sreal.h b/contrib/gcc/sreal.h
new file mode 100644
index 000000000000..b24b29b58578
--- /dev/null
+++ b/contrib/gcc/sreal.h
@@ -0,0 +1,65 @@
+/* Definitions for simple data type for positive real numbers.
+ Copyright (C) 2002, 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#ifndef GCC_SREAL_H
+#define GCC_SREAL_H
+
+/* SREAL_PART_BITS has to be an even number. */
+#if (HOST_BITS_PER_WIDE_INT / 2) % 2 == 1
+#define SREAL_PART_BITS (HOST_BITS_PER_WIDE_INT / 2 - 1)
+#else
+#define SREAL_PART_BITS (HOST_BITS_PER_WIDE_INT / 2)
+#endif
+
+#define uhwi unsigned HOST_WIDE_INT
+#define MAX_HOST_WIDE_INT (((uhwi) 1 << (HOST_BITS_PER_WIDE_INT - 1)) - 1)
+
+#define SREAL_MIN_SIG ((uhwi) 1 << (SREAL_PART_BITS - 1))
+#define SREAL_MAX_SIG (((uhwi) 1 << SREAL_PART_BITS) - 1)
+#define SREAL_MAX_EXP (INT_MAX / 4)
+
+#if SREAL_PART_BITS < 32
+#define SREAL_BITS (SREAL_PART_BITS * 2)
+#else
+#define SREAL_BITS SREAL_PART_BITS
+#endif
+
+/* Structure for holding a simple real number. */
+typedef struct sreal
+{
+#if SREAL_PART_BITS < 32
+ unsigned HOST_WIDE_INT sig_lo; /* Significant (lower part). */
+ unsigned HOST_WIDE_INT sig_hi; /* Significant (higher part). */
+#else
+ unsigned HOST_WIDE_INT sig; /* Significant. */
+#endif
+ signed int exp; /* Exponent. */
+} sreal;
+
+extern void dump_sreal (FILE *, sreal *);
+extern sreal *sreal_init (sreal *, unsigned HOST_WIDE_INT, signed int);
+extern HOST_WIDE_INT sreal_to_int (sreal *);
+extern int sreal_compare (sreal *, sreal *);
+extern sreal *sreal_add (sreal *, sreal *, sreal *);
+extern sreal *sreal_sub (sreal *, sreal *, sreal *);
+extern sreal *sreal_mul (sreal *, sreal *, sreal *);
+extern sreal *sreal_div (sreal *, sreal *, sreal *);
+
+#endif
diff --git a/contrib/gcc/stack.h b/contrib/gcc/stack.h
index 018030c25575..121610366912 100644
--- a/contrib/gcc/stack.h
+++ b/contrib/gcc/stack.h
@@ -1,5 +1,5 @@
/* stack.h - structed access to object stacks
- Copyright (C) 1988, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1988, 2000, 2003 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
This program is free software; you can redistribute it and/or modify it
@@ -21,7 +21,7 @@ Boston, MA 02111-1307, USA. */
on top of obstacks for GNU C++. */
/* Stack of data placed on obstacks. */
-
+
struct stack_level
{
/* Pointer back to previous such level. */
@@ -38,5 +38,5 @@ struct stack_level
int limit;
};
-struct stack_level *push_stack_level PARAMS ((struct obstack *, char *, int));
-struct stack_level *pop_stack_level PARAMS ((struct stack_level *));
+struct stack_level *push_stack_level (struct obstack *, char *, int);
+struct stack_level *pop_stack_level (struct stack_level *);
diff --git a/contrib/gcc/stmt.c b/contrib/gcc/stmt.c
index 89b9840c25dd..382717510998 100644
--- a/contrib/gcc/stmt.c
+++ b/contrib/gcc/stmt.c
@@ -1,6 +1,6 @@
-/* Expands front end tree to back end RTL for GNU C-Compiler
+/* Expands front end tree to back end RTL for GCC
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -35,6 +35,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
@@ -54,6 +56,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "langhooks.h"
#include "predict.h"
+#include "optabs.h"
+#include "target.h"
/* Assume that case vectors are not pc-relative. */
#ifndef CASE_VECTOR_PC_RELATIVE
@@ -166,9 +170,6 @@ struct nesting GTY(())
rtx start_label;
/* Label at the end of the whole construct. */
rtx end_label;
- /* Label before a jump that branches to the end of the whole
- construct. This is where destructors go if any. */
- rtx alt_end_label;
/* Label for `continue' statement to jump to;
this is in front of the stepper of the loop. */
rtx continue_label;
@@ -204,8 +205,6 @@ struct nesting GTY(())
/* Chain of labels defined inside this binding contour.
For contours that have stack levels or cleanups. */
struct label_chain *label_chain;
- /* Number of function calls seen, as of start of this block. */
- int n_function_calls;
/* Nonzero if this is associated with an EH region. */
int exception_region;
/* The saved target_temp_slot_level from our outer block.
@@ -254,8 +253,7 @@ struct nesting GTY(())
/* Allocate and return a new `struct nesting'. */
-#define ALLOC_NESTING() \
- (struct nesting *) ggc_alloc (sizeof (struct nesting))
+#define ALLOC_NESTING() ggc_alloc (sizeof (struct nesting))
/* Pop the nesting stack element by element until we pop off
the element which is at the top of STACK.
@@ -363,15 +361,15 @@ struct stmt_status GTY(())
record the expr's type and its RTL value here. */
tree x_last_expr_type;
rtx x_last_expr_value;
+ rtx x_last_expr_alt_rtl;
/* Nonzero if within a ({...}) grouping, in which case we must
always compute a value for each expr-stmt in case it is the last one. */
int x_expr_stmts_for_value;
- /* Filename and line number of last line-number note,
- whether we actually emitted it or not. */
- const char *x_emit_filename;
- int x_emit_lineno;
+ /* Location of last line-number note, whether we actually
+ emitted it or not. */
+ location_t x_emit_locus;
struct goto_fixup *x_goto_fixup_chain;
};
@@ -386,107 +384,76 @@ struct stmt_status GTY(())
#define current_block_start_count (cfun->stmt->x_block_start_count)
#define last_expr_type (cfun->stmt->x_last_expr_type)
#define last_expr_value (cfun->stmt->x_last_expr_value)
+#define last_expr_alt_rtl (cfun->stmt->x_last_expr_alt_rtl)
#define expr_stmts_for_value (cfun->stmt->x_expr_stmts_for_value)
-#define emit_filename (cfun->stmt->x_emit_filename)
-#define emit_lineno (cfun->stmt->x_emit_lineno)
+#define emit_locus (cfun->stmt->x_emit_locus)
#define goto_fixup_chain (cfun->stmt->x_goto_fixup_chain)
-/* Non-zero if we are using EH to handle cleanups. */
+/* Nonzero if we are using EH to handle cleanups. */
static int using_eh_for_cleanups_p = 0;
-static int n_occurrences PARAMS ((int, const char *));
-static bool parse_input_constraint PARAMS ((const char **, int, int, int,
- int, const char * const *,
- bool *, bool *));
-static bool decl_conflicts_with_clobbers_p PARAMS ((tree, const HARD_REG_SET));
-static void expand_goto_internal PARAMS ((tree, rtx, rtx));
-static int expand_fixup PARAMS ((tree, rtx, rtx));
-static rtx expand_nl_handler_label PARAMS ((rtx, rtx));
-static void expand_nl_goto_receiver PARAMS ((void));
-static void expand_nl_goto_receivers PARAMS ((struct nesting *));
-static void fixup_gotos PARAMS ((struct nesting *, rtx, tree,
- rtx, int));
-static bool check_operand_nalternatives PARAMS ((tree, tree));
-static bool check_unique_operand_names PARAMS ((tree, tree));
-static tree resolve_operand_names PARAMS ((tree, tree, tree,
- const char **));
-static char *resolve_operand_name_1 PARAMS ((char *, tree, tree));
-static void expand_null_return_1 PARAMS ((rtx));
-static enum br_predictor return_prediction PARAMS ((rtx));
-static void expand_value_return PARAMS ((rtx));
-static int tail_recursion_args PARAMS ((tree, tree));
-static void expand_cleanups PARAMS ((tree, tree, int, int));
-static void check_seenlabel PARAMS ((void));
-static void do_jump_if_equal PARAMS ((rtx, rtx, rtx, int));
-static int estimate_case_costs PARAMS ((case_node_ptr));
-static void group_case_nodes PARAMS ((case_node_ptr));
-static void balance_case_nodes PARAMS ((case_node_ptr *,
- case_node_ptr));
-static int node_has_low_bound PARAMS ((case_node_ptr, tree));
-static int node_has_high_bound PARAMS ((case_node_ptr, tree));
-static int node_is_bounded PARAMS ((case_node_ptr, tree));
-static void emit_jump_if_reachable PARAMS ((rtx));
-static void emit_case_nodes PARAMS ((rtx, case_node_ptr, rtx, tree));
-static struct case_node *case_tree2list PARAMS ((case_node *, case_node *));
+static int n_occurrences (int, const char *);
+static bool decl_conflicts_with_clobbers_p (tree, const HARD_REG_SET);
+static void expand_goto_internal (tree, rtx, rtx);
+static int expand_fixup (tree, rtx, rtx);
+static rtx expand_nl_handler_label (rtx, rtx);
+static void expand_nl_goto_receiver (void);
+static void expand_nl_goto_receivers (struct nesting *);
+static void fixup_gotos (struct nesting *, rtx, tree, rtx, int);
+static bool check_operand_nalternatives (tree, tree);
+static bool check_unique_operand_names (tree, tree);
+static char *resolve_operand_name_1 (char *, tree, tree);
+static void expand_null_return_1 (rtx);
+static enum br_predictor return_prediction (rtx);
+static rtx shift_return_value (rtx);
+static void expand_value_return (rtx);
+static int tail_recursion_args (tree, tree);
+static void expand_cleanups (tree, int, int);
+static void check_seenlabel (void);
+static void do_jump_if_equal (rtx, rtx, rtx, int);
+static int estimate_case_costs (case_node_ptr);
+static bool same_case_target_p (rtx, rtx);
+static void strip_default_case_nodes (case_node_ptr *, rtx);
+static bool lshift_cheap_p (void);
+static int case_bit_test_cmp (const void *, const void *);
+static void emit_case_bit_tests (tree, tree, tree, tree, case_node_ptr, rtx);
+static void group_case_nodes (case_node_ptr);
+static void balance_case_nodes (case_node_ptr *, case_node_ptr);
+static int node_has_low_bound (case_node_ptr, tree);
+static int node_has_high_bound (case_node_ptr, tree);
+static int node_is_bounded (case_node_ptr, tree);
+static void emit_jump_if_reachable (rtx);
+static void emit_case_nodes (rtx, case_node_ptr, rtx, tree);
+static struct case_node *case_tree2list (case_node *, case_node *);
void
-using_eh_for_cleanups ()
+using_eh_for_cleanups (void)
{
using_eh_for_cleanups_p = 1;
}
void
-init_stmt_for_function ()
+init_stmt_for_function (void)
{
- cfun->stmt = ((struct stmt_status *)ggc_alloc (sizeof (struct stmt_status)));
-
- /* We are not currently within any block, conditional, loop or case. */
- block_stack = 0;
- stack_block_stack = 0;
- loop_stack = 0;
- case_stack = 0;
- cond_stack = 0;
- nesting_stack = 0;
- nesting_depth = 0;
-
- current_block_start_count = 0;
-
- /* No gotos have been expanded yet. */
- goto_fixup_chain = 0;
-
- /* We are not processing a ({...}) grouping. */
- expr_stmts_for_value = 0;
- clear_last_expr ();
+ cfun->stmt = ggc_alloc_cleared (sizeof (struct stmt_status));
}
-/* Return nonzero if anything is pushed on the loop, condition, or case
- stack. */
-int
-in_control_zone_p ()
-{
- return cond_stack || loop_stack || case_stack;
-}
-
/* Record the current file and line. Called from emit_line_note. */
+
void
-set_file_and_line_for_stmt (file, line)
- const char *file;
- int line;
+set_file_and_line_for_stmt (location_t location)
{
/* If we're outputting an inline function, and we add a line note,
there may be no CFUN->STMT information. So, there's no need to
update it. */
if (cfun->stmt)
- {
- emit_filename = file;
- emit_lineno = line;
- }
+ emit_locus = location;
}
/* Emit a no-op instruction. */
void
-emit_nop ()
+emit_nop (void)
{
rtx last_insn;
@@ -502,8 +469,7 @@ emit_nop ()
creating it if necessary. */
rtx
-label_rtx (label)
- tree label;
+label_rtx (tree label)
{
if (TREE_CODE (label) != LABEL_DECL)
abort ();
@@ -514,12 +480,33 @@ label_rtx (label)
return DECL_RTL (label);
}
+/* As above, but also put it on the forced-reference list of the
+ function that contains it. */
+rtx
+force_label_rtx (tree label)
+{
+ rtx ref = label_rtx (label);
+ tree function = decl_function_context (label);
+ struct function *p;
+
+ if (!function)
+ abort ();
+
+ if (function != current_function_decl
+ && function != inline_function_decl)
+ p = find_function_data (function);
+ else
+ p = cfun;
+
+ p->expr->x_forced_labels = gen_rtx_EXPR_LIST (VOIDmode, ref,
+ p->expr->x_forced_labels);
+ return ref;
+}
/* Add an unconditional jump to LABEL as the next sequential instruction. */
void
-emit_jump (label)
- rtx label;
+emit_jump (rtx label)
{
do_pending_stack_adjust ();
emit_jump_insn (gen_jump (label));
@@ -530,15 +517,11 @@ emit_jump (label)
specified by the pointer expression EXP. */
void
-expand_computed_goto (exp)
- tree exp;
+expand_computed_goto (tree exp)
{
rtx x = expand_expr (exp, NULL_RTX, VOIDmode, 0);
-#ifdef POINTERS_EXTEND_UNSIGNED
- if (GET_MODE (x) != Pmode)
- x = convert_memory_address (Pmode, x);
-#endif
+ x = convert_memory_address (Pmode, x);
emit_queue ();
@@ -546,9 +529,9 @@ expand_computed_goto (exp)
{
cfun->computed_goto_common_reg = copy_to_mode_reg (Pmode, x);
cfun->computed_goto_common_label = gen_label_rtx ();
- emit_label (cfun->computed_goto_common_label);
-
+
do_pending_stack_adjust ();
+ emit_label (cfun->computed_goto_common_label);
emit_indirect_jump (cfun->computed_goto_common_reg);
current_function_has_computed_jump = 1;
@@ -574,8 +557,7 @@ expand_computed_goto (exp)
Languages vary in how they do that and what that even means. */
void
-expand_label (label)
- tree label;
+expand_label (tree label)
{
struct label_chain *p;
@@ -586,7 +568,7 @@ expand_label (label)
if (stack_block_stack != 0)
{
- p = (struct label_chain *) ggc_alloc (sizeof (struct label_chain));
+ p = ggc_alloc (sizeof (struct label_chain));
p->next = stack_block_stack->data.block.label_chain;
stack_block_stack->data.block.label_chain = p;
p->label = label;
@@ -597,8 +579,7 @@ expand_label (label)
from nested functions. */
void
-declare_nonlocal_label (label)
- tree label;
+declare_nonlocal_label (tree label)
{
rtx slot = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
@@ -619,8 +600,7 @@ declare_nonlocal_label (label)
defined with `expand_label'. */
void
-expand_goto (label)
- tree label;
+expand_goto (tree label)
{
tree context;
@@ -669,6 +649,13 @@ expand_goto (label)
else
#endif
{
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ gen_rtx_SCRATCH (VOIDmode))));
+ emit_insn (gen_rtx_CLOBBER (VOIDmode,
+ gen_rtx_MEM (BLKmode,
+ hard_frame_pointer_rtx)));
+
/* Restore frame pointer for containing function.
This sets the actual hard register used for the frame pointer
to the location of the function's incoming static chain info.
@@ -708,10 +695,7 @@ expand_goto (label)
insn emitted (for the purposes of cleaning up a return). */
static void
-expand_goto_internal (body, label, last_insn)
- tree body;
- rtx label;
- rtx last_insn;
+expand_goto_internal (tree body, rtx label, rtx last_insn)
{
struct nesting *block;
rtx stack_level = 0;
@@ -737,7 +721,7 @@ expand_goto_internal (body, label, last_insn)
/* Execute the cleanups for blocks we are exiting. */
if (block->data.block.cleanups != 0)
{
- expand_cleanups (block->data.block.cleanups, NULL_TREE, 1, 1);
+ expand_cleanups (block->data.block.cleanups, 1, 1);
do_pending_stack_adjust ();
}
}
@@ -795,10 +779,7 @@ expand_goto_internal (body, label, last_insn)
Value is nonzero if a fixup is made. */
static int
-expand_fixup (tree_label, rtl_label, last_insn)
- tree tree_label;
- rtx rtl_label;
- rtx last_insn;
+expand_fixup (tree tree_label, rtx rtl_label, rtx last_insn)
{
struct nesting *block, *end_block;
@@ -857,8 +838,7 @@ expand_fixup (tree_label, rtl_label, last_insn)
if (block != end_block)
{
/* Ok, a fixup is needed. Add a fixup to the list of such. */
- struct goto_fixup *fixup
- = (struct goto_fixup *) ggc_alloc (sizeof (struct goto_fixup));
+ struct goto_fixup *fixup = ggc_alloc (sizeof (struct goto_fixup));
/* In case an old stack level is restored, make sure that comes
after any pending stack adjust. */
/* ?? If the fixup isn't to come at the present position,
@@ -903,11 +883,11 @@ expand_fixup (tree_label, rtl_label, last_insn)
}
start_sequence ();
- start = emit_note (NULL, NOTE_INSN_BLOCK_BEG);
+ start = emit_note (NOTE_INSN_BLOCK_BEG);
if (cfun->x_whole_function_mode_p)
NOTE_BLOCK (start) = block;
- fixup->before_jump = emit_note (NULL, NOTE_INSN_DELETED);
- end = emit_note (NULL, NOTE_INSN_BLOCK_END);
+ fixup->before_jump = emit_note (NOTE_INSN_DELETED);
+ end = emit_note (NOTE_INSN_BLOCK_END);
if (cfun->x_whole_function_mode_p)
NOTE_BLOCK (end) = block;
fixup->context = block;
@@ -934,8 +914,7 @@ expand_fixup (tree_label, rtl_label, last_insn)
function. FIRST_INSN is the first insn in the function. */
void
-expand_fixups (first_insn)
- rtx first_insn;
+expand_fixups (rtx first_insn)
{
fixup_gotos (NULL, NULL_RTX, NULL_TREE, first_insn, 0);
}
@@ -949,17 +928,13 @@ expand_fixups (first_insn)
Gotos that jump out of this contour must restore the
stack level and do the cleanups before actually jumping.
- DONT_JUMP_IN nonzero means report error there is a jump into this
- contour from before the beginning of the contour.
- This is also done if STACK_LEVEL is nonzero. */
+ DONT_JUMP_IN positive means report error if there is a jump into this
+ contour from before the beginning of the contour. This is also done if
+ STACK_LEVEL is nonzero unless DONT_JUMP_IN is negative. */
static void
-fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
- struct nesting *thisblock;
- rtx stack_level;
- tree cleanup_list;
- rtx first_insn;
- int dont_jump_in;
+fixup_gotos (struct nesting *thisblock, rtx stack_level,
+ tree cleanup_list, rtx first_insn, int dont_jump_in)
{
struct goto_fixup *f, *prev;
@@ -993,13 +968,14 @@ fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
It detects only a problem with the innermost block
around the label. */
if (f->target != 0
- && (dont_jump_in || stack_level || cleanup_list)
+ && (dont_jump_in > 0 || (dont_jump_in == 0 && stack_level)
+ || cleanup_list)
&& INSN_UID (first_insn) < INSN_UID (f->target_rtl)
&& INSN_UID (first_insn) > INSN_UID (f->before_jump)
&& ! DECL_ERROR_ISSUED (f->target))
{
- error_with_decl (f->target,
- "label `%s' used before containing binding contour");
+ error ("%Jlabel '%D' used before containing binding contour",
+ f->target, f->target);
/* Prevent multiple errors for one label. */
DECL_ERROR_ISSUED (f->target) = 1;
}
@@ -1027,7 +1003,7 @@ fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
if (TREE_ADDRESSABLE (lists)
&& TREE_VALUE (lists) != 0)
{
- expand_cleanups (TREE_VALUE (lists), NULL_TREE, 1, 1);
+ expand_cleanups (TREE_VALUE (lists), 1, 1);
/* Pop any pushes done in the cleanups,
in case function is about to return. */
do_pending_stack_adjust ();
@@ -1090,7 +1066,7 @@ fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
start_sequence ();
(*lang_hooks.decls.pushlevel) (0);
(*lang_hooks.decls.set_block) (f->context);
- expand_cleanups (TREE_VALUE (lists), NULL_TREE, 1, 1);
+ expand_cleanups (TREE_VALUE (lists), 1, 1);
do_pending_stack_adjust ();
cleanup_insns = get_insns ();
(*lang_hooks.decls.poplevel) (1, 0, 0);
@@ -1109,9 +1085,7 @@ fixup_gotos (thisblock, stack_level, cleanup_list, first_insn, dont_jump_in)
/* Return the number of times character C occurs in string S. */
static int
-n_occurrences (c, s)
- int c;
- const char *s;
+n_occurrences (int c, const char *s)
{
int n = 0;
while (*s)
@@ -1125,9 +1099,7 @@ n_occurrences (c, s)
insn is volatile; don't optimize it. */
void
-expand_asm (string, vol)
- tree string;
- int vol;
+expand_asm (tree string, int vol)
{
rtx body;
@@ -1139,7 +1111,7 @@ expand_asm (string, vol)
MEM_VOLATILE_P (body) = vol;
emit_insn (body);
-
+
clear_last_expr ();
}
@@ -1152,20 +1124,14 @@ expand_asm (string, vol)
will be true if the operand is read-write, i.e., if it is used as
an input as well as an output. If *CONSTRAINT_P is not in
canonical form, it will be made canonical. (Note that `+' will be
- rpelaced with `=' as part of this process.)
+ replaced with `=' as part of this process.)
Returns TRUE if all went well; FALSE if an error occurred. */
bool
-parse_output_constraint (constraint_p, operand_num, ninputs, noutputs,
- allows_mem, allows_reg, is_inout)
- const char **constraint_p;
- int operand_num;
- int ninputs;
- int noutputs;
- bool *allows_mem;
- bool *allows_reg;
- bool *is_inout;
+parse_output_constraint (const char **constraint_p, int operand_num,
+ int ninputs, int noutputs, bool *allows_mem,
+ bool *allows_reg, bool *is_inout)
{
const char *constraint = *constraint_p;
const char *p;
@@ -1219,7 +1185,7 @@ parse_output_constraint (constraint_p, operand_num, ninputs, noutputs,
}
/* Loop through the constraint string. */
- for (p = constraint + 1; *p; ++p)
+ for (p = constraint + 1; *p; p += CONSTRAINT_LEN (*p, p))
switch (*p)
{
case '+':
@@ -1271,12 +1237,12 @@ parse_output_constraint (constraint_p, operand_num, ninputs, noutputs,
default:
if (!ISALPHA (*p))
break;
- if (REG_CLASS_FROM_LETTER (*p) != NO_REGS)
+ if (REG_CLASS_FROM_CONSTRAINT (*p, p) != NO_REGS)
*allows_reg = true;
-#ifdef EXTRA_CONSTRAINT
- else if (EXTRA_ADDRESS_CONSTRAINT (*p))
+#ifdef EXTRA_CONSTRAINT_STR
+ else if (EXTRA_ADDRESS_CONSTRAINT (*p, p))
*allows_reg = true;
- else if (EXTRA_MEMORY_CONSTRAINT (*p))
+ else if (EXTRA_MEMORY_CONSTRAINT (*p, p))
*allows_mem = true;
else
{
@@ -1295,22 +1261,17 @@ parse_output_constraint (constraint_p, operand_num, ninputs, noutputs,
/* Similar, but for input constraints. */
-static bool
-parse_input_constraint (constraint_p, input_num, ninputs, noutputs, ninout,
- constraints, allows_mem, allows_reg)
- const char **constraint_p;
- int input_num;
- int ninputs;
- int noutputs;
- int ninout;
- const char * const * constraints;
- bool *allows_mem;
- bool *allows_reg;
+bool
+parse_input_constraint (const char **constraint_p, int input_num,
+ int ninputs, int noutputs, int ninout,
+ const char * const * constraints,
+ bool *allows_mem, bool *allows_reg)
{
const char *constraint = *constraint_p;
const char *orig_constraint = constraint;
size_t c_len = strlen (constraint);
size_t j;
+ bool saw_match = false;
/* Assume the constraint doesn't allow the use of either
a register or memory. */
@@ -1319,7 +1280,7 @@ parse_input_constraint (constraint_p, input_num, ninputs, noutputs, ninout,
/* Make sure constraint has neither `=', `+', nor '&'. */
- for (j = 0; j < c_len; j++)
+ for (j = 0; j < c_len; j += CONSTRAINT_LEN (constraint[j], constraint+j))
switch (constraint[j])
{
case '+': case '=': case '&':
@@ -1362,6 +1323,8 @@ parse_input_constraint (constraint_p, input_num, ninputs, noutputs, ninout,
char *end;
unsigned long match;
+ saw_match = true;
+
match = strtoul (constraint + j, &end, 10);
if (match >= (unsigned long) noutputs)
{
@@ -1378,10 +1341,16 @@ parse_input_constraint (constraint_p, input_num, ninputs, noutputs, ninout,
*constraint_p = constraint;
c_len = strlen (constraint);
j = 0;
+ /* ??? At the end of the loop, we will skip the first part of
+ the matched constraint. This assumes not only that the
+ other constraint is an output constraint, but also that
+ the '=' or '+' come first. */
break;
}
else
j = end - constraint;
+ /* Anticipate increment at end of loop. */
+ j--;
}
/* Fall through. */
@@ -1400,12 +1369,13 @@ parse_input_constraint (constraint_p, input_num, ninputs, noutputs, ninout,
error ("invalid punctuation `%c' in constraint", constraint[j]);
return false;
}
- if (REG_CLASS_FROM_LETTER (constraint[j]) != NO_REGS)
+ if (REG_CLASS_FROM_CONSTRAINT (constraint[j], constraint + j)
+ != NO_REGS)
*allows_reg = true;
-#ifdef EXTRA_CONSTRAINT
- else if (EXTRA_ADDRESS_CONSTRAINT (constraint[j]))
+#ifdef EXTRA_CONSTRAINT_STR
+ else if (EXTRA_ADDRESS_CONSTRAINT (constraint[j], constraint + j))
*allows_reg = true;
- else if (EXTRA_MEMORY_CONSTRAINT (constraint[j]))
+ else if (EXTRA_MEMORY_CONSTRAINT (constraint[j], constraint + j))
*allows_mem = true;
else
{
@@ -1419,6 +1389,9 @@ parse_input_constraint (constraint_p, input_num, ninputs, noutputs, ninout,
break;
}
+ if (saw_match && !*allows_reg)
+ warning ("matching constraint does not allow a register");
+
return true;
}
@@ -1427,9 +1400,7 @@ parse_input_constraint (constraint_p, input_num, ninputs, noutputs, ninout,
FALSE for ok. */
static bool
-decl_conflicts_with_clobbers_p (decl, clobbered_regs)
- tree decl;
- const HARD_REG_SET clobbered_regs;
+decl_conflicts_with_clobbers_p (tree decl, const HARD_REG_SET clobbered_regs)
{
/* Conflicts between asm-declared register variables and the clobber
list are not allowed. */
@@ -1477,11 +1448,8 @@ decl_conflicts_with_clobbers_p (decl, clobbered_regs)
VOL nonzero means the insn is volatile; don't optimize it. */
void
-expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
- tree string, outputs, inputs, clobbers;
- int vol;
- const char *filename;
- int line;
+expand_asm_operands (tree string, tree outputs, tree inputs,
+ tree clobbers, int vol, location_t locus)
{
rtvec argvec, constraintvec;
rtx body;
@@ -1492,17 +1460,16 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
HARD_REG_SET clobbered_regs;
int clobber_conflict_found = 0;
tree tail;
+ tree t;
int i;
/* Vector of RTX's of evaluated output operands. */
- rtx *output_rtx = (rtx *) alloca (noutputs * sizeof (rtx));
- int *inout_opnum = (int *) alloca (noutputs * sizeof (int));
- rtx *real_output_rtx = (rtx *) alloca (noutputs * sizeof (rtx));
+ rtx *output_rtx = alloca (noutputs * sizeof (rtx));
+ int *inout_opnum = alloca (noutputs * sizeof (int));
+ rtx *real_output_rtx = alloca (noutputs * sizeof (rtx));
enum machine_mode *inout_mode
- = (enum machine_mode *) alloca (noutputs * sizeof (enum machine_mode));
+ = alloca (noutputs * sizeof (enum machine_mode));
const char **constraints
- = (const char **) alloca ((noutputs + ninputs) * sizeof (const char *));
- /* The insn we have emitted. */
- rtx insn;
+ = alloca ((noutputs + ninputs) * sizeof (const char *));
int old_generating_concat_p = generating_concat_p;
/* An ASM with no outputs needs to be treated as volatile, for now. */
@@ -1512,10 +1479,14 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
if (! check_operand_nalternatives (outputs, inputs))
return;
- if (! check_unique_operand_names (outputs, inputs))
- return;
+ string = resolve_asm_operand_names (string, outputs, inputs);
- string = resolve_operand_names (string, outputs, inputs, constraints);
+ /* Collect constraints. */
+ i = 0;
+ for (t = outputs; t ; t = TREE_CHAIN (t), i++)
+ constraints[i] = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
+ for (t = inputs; t ; t = TREE_CHAIN (t), i++)
+ constraints[i] = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
#ifdef MD_ASM_CLOBBERS
/* Sometimes we wish to automatically clobber registers across an asm.
@@ -1541,7 +1512,16 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
/* Mark clobbered registers. */
if (i >= 0)
- SET_HARD_REG_BIT (clobbered_regs, i);
+ {
+ /* Clobbering the PIC register is an error */
+ if (i == (int) PIC_OFFSET_TABLE_REGNUM)
+ {
+ error ("PIC register `%s' clobbered in `asm'", regname);
+ return;
+ }
+
+ SET_HARD_REG_BIT (clobbered_regs, i);
+ }
}
clear_last_expr ();
@@ -1687,7 +1667,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
: GET_MODE (output_rtx[0])),
TREE_STRING_POINTER (string),
empty_string, 0, argvec, constraintvec,
- filename, line);
+ locus.file, locus.line);
MEM_VOLATILE_P (body) = vol;
@@ -1735,18 +1715,21 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
}
else
{
- warning ("use of memory input without lvalue in asm operand %d is deprecated",
- i + noutputs);
+ warning ("use of memory input without lvalue in "
+ "asm operand %d is deprecated", i + noutputs);
if (CONSTANT_P (op))
{
- op = force_const_mem (TYPE_MODE (type), op);
- op = validize_mem (op);
+ rtx mem = force_const_mem (TYPE_MODE (type), op);
+ if (mem)
+ op = validize_mem (mem);
+ else
+ op = force_reg (TYPE_MODE (type), op);
}
- else if (GET_CODE (op) == REG
- || GET_CODE (op) == SUBREG
- || GET_CODE (op) == ADDRESSOF
- || GET_CODE (op) == CONCAT)
+ if (GET_CODE (op) == REG
+ || GET_CODE (op) == SUBREG
+ || GET_CODE (op) == ADDRESSOF
+ || GET_CODE (op) == CONCAT)
{
tree qual_type = build_qualified_type (type,
(TYPE_QUALS (type)
@@ -1792,7 +1775,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
sprintf (buffer, "%d", j);
ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, ninputs - ninout + i)
- = gen_rtx_ASM_INPUT (inout_mode[i], ggc_alloc_string (buffer, -1));
+ = gen_rtx_ASM_INPUT (inout_mode[i], ggc_strdup (buffer));
}
generating_concat_p = old_generating_concat_p;
@@ -1805,13 +1788,13 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
if (noutputs == 1 && nclobbers == 0)
{
ASM_OPERANDS_OUTPUT_CONSTRAINT (body) = constraints[0];
- insn = emit_insn (gen_rtx_SET (VOIDmode, output_rtx[0], body));
+ emit_insn (gen_rtx_SET (VOIDmode, output_rtx[0], body));
}
else if (noutputs == 0 && nclobbers == 0)
{
/* No output operands: put in a raw ASM_OPERANDS rtx. */
- insn = emit_insn (body);
+ emit_insn (body);
}
else
@@ -1834,7 +1817,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
(GET_MODE (output_rtx[i]),
TREE_STRING_POINTER (string),
constraints[i], i, argvec, constraintvec,
- filename, line));
+ locus.file, locus.line));
MEM_VOLATILE_P (SET_SRC (XVECEXP (body, 0, i))) = vol;
}
@@ -1898,7 +1881,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
= gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
}
- insn = emit_insn (body);
+ emit_insn (body);
}
/* For any outputs that needed reloading into registers, spill them
@@ -1914,8 +1897,7 @@ expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
the same number of alternatives. Return true if so. */
static bool
-check_operand_nalternatives (outputs, inputs)
- tree outputs, inputs;
+check_operand_nalternatives (tree outputs, tree inputs)
{
if (outputs || inputs)
{
@@ -1958,8 +1940,7 @@ check_operand_nalternatives (outputs, inputs)
so all we need are pointer comparisons. */
static bool
-check_unique_operand_names (outputs, inputs)
- tree outputs, inputs;
+check_unique_operand_names (tree outputs, tree inputs)
{
tree i, j;
@@ -2000,60 +1981,73 @@ check_unique_operand_names (outputs, inputs)
in *POUTPUTS and *PINPUTS to numbers, and replace the name expansions in
STRING and in the constraints to those numbers. */
-static tree
-resolve_operand_names (string, outputs, inputs, pconstraints)
- tree string;
- tree outputs, inputs;
- const char **pconstraints;
+tree
+resolve_asm_operand_names (tree string, tree outputs, tree inputs)
{
- char *buffer = xstrdup (TREE_STRING_POINTER (string));
+ char *buffer;
char *p;
+ const char *c;
tree t;
- /* Assume that we will not need extra space to perform the substitution.
- This because we get to remove '[' and ']', which means we cannot have
- a problem until we have more than 999 operands. */
+ check_unique_operand_names (outputs, inputs);
+
+ /* Substitute [<name>] in input constraint strings. There should be no
+ named operands in output constraints. */
+ for (t = inputs; t ; t = TREE_CHAIN (t))
+ {
+ c = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
+ if (strchr (c, '[') != NULL)
+ {
+ p = buffer = xstrdup (c);
+ while ((p = strchr (p, '[')) != NULL)
+ p = resolve_operand_name_1 (p, outputs, inputs);
+ TREE_VALUE (TREE_PURPOSE (t))
+ = build_string (strlen (buffer), buffer);
+ free (buffer);
+ }
+ }
- p = buffer;
- while ((p = strchr (p, '%')) != NULL)
+ /* Now check for any needed substitutions in the template. */
+ c = TREE_STRING_POINTER (string);
+ while ((c = strchr (c, '%')) != NULL)
{
- if (p[1] == '[')
- p += 1;
- else if (ISALPHA (p[1]) && p[2] == '[')
- p += 2;
+ if (c[1] == '[')
+ break;
+ else if (ISALPHA (c[1]) && c[2] == '[')
+ break;
else
{
- p += 1;
+ c += 1;
continue;
}
-
- p = resolve_operand_name_1 (p, outputs, inputs);
}
- string = build_string (strlen (buffer), buffer);
- free (buffer);
-
- /* Collect output constraints here because it's convenient.
- There should be no named operands here; this is verified
- in expand_asm_operand. */
- for (t = outputs; t ; t = TREE_CHAIN (t), pconstraints++)
- *pconstraints = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
-
- /* Substitute [<name>] in input constraint strings. */
- for (t = inputs; t ; t = TREE_CHAIN (t), pconstraints++)
+ if (c)
{
- const char *c = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
- if (strchr (c, '[') == NULL)
- *pconstraints = c;
- else
+ /* OK, we need to make a copy so we can perform the substitutions.
+ Assume that we will not need extra space--we get to remove '['
+ and ']', which means we cannot have a problem until we have more
+ than 999 operands. */
+ buffer = xstrdup (TREE_STRING_POINTER (string));
+ p = buffer + (c - TREE_STRING_POINTER (string));
+
+ while ((p = strchr (p, '%')) != NULL)
{
- p = buffer = xstrdup (c);
- while ((p = strchr (p, '[')) != NULL)
- p = resolve_operand_name_1 (p, outputs, inputs);
+ if (p[1] == '[')
+ p += 1;
+ else if (ISALPHA (p[1]) && p[2] == '[')
+ p += 2;
+ else
+ {
+ p += 1;
+ continue;
+ }
- *pconstraints = ggc_alloc_string (buffer, -1);
- free (buffer);
+ p = resolve_operand_name_1 (p, outputs, inputs);
}
+
+ string = build_string (strlen (buffer), buffer);
+ free (buffer);
}
return string;
@@ -2065,9 +2059,7 @@ resolve_operand_names (string, outputs, inputs, pconstraints)
balance of the string after substitution. */
static char *
-resolve_operand_name_1 (p, outputs, inputs)
- char *p;
- tree outputs, inputs;
+resolve_operand_name_1 (char *p, tree outputs, tree inputs)
{
char *q;
int op;
@@ -2132,8 +2124,7 @@ resolve_operand_name_1 (p, outputs, inputs)
should be used for new code. */
void
-expand_expr_stmt (exp)
- tree exp;
+expand_expr_stmt (tree exp)
{
expand_expr_stmt_value (exp, -1, 1);
}
@@ -2144,33 +2135,27 @@ expand_expr_stmt (exp)
deprecated, and retained only for backward compatibility. */
void
-expand_expr_stmt_value (exp, want_value, maybe_last)
- tree exp;
- int want_value, maybe_last;
+expand_expr_stmt_value (tree exp, int want_value, int maybe_last)
{
rtx value;
tree type;
+ rtx alt_rtl = NULL;
if (want_value == -1)
want_value = expr_stmts_for_value != 0;
- /* If -W, warn about statements with no side effects,
+ /* If -Wextra, warn about statements with no side effects,
except for an explicit cast to void (e.g. for assert()), and
except for last statement in ({...}) where they may be useful. */
if (! want_value
&& (expr_stmts_for_value == 0 || ! maybe_last)
- && exp != error_mark_node)
+ && exp != error_mark_node
+ && warn_unused_value)
{
- if (! TREE_SIDE_EFFECTS (exp))
- {
- if ((extra_warnings || warn_unused_value)
- && !(TREE_CODE (exp) == CONVERT_EXPR
- && VOID_TYPE_P (TREE_TYPE (exp))))
- warning_with_file_and_line (emit_filename, emit_lineno,
- "statement with no effect");
- }
- else if (warn_unused_value)
+ if (TREE_SIDE_EFFECTS (exp))
warn_if_unused_value (exp);
+ else if (!VOID_TYPE_P (TREE_TYPE (exp)))
+ warning ("%Hstatement with no effect", &emit_locus);
}
/* If EXP is of function type and we are expanding statements for
@@ -2181,8 +2166,8 @@ expand_expr_stmt_value (exp, want_value, maybe_last)
/* The call to `expand_expr' could cause last_expr_type and
last_expr_value to get reset. Therefore, we set last_expr_value
and last_expr_type *after* calling expand_expr. */
- value = expand_expr (exp, want_value ? NULL_RTX : const0_rtx,
- VOIDmode, 0);
+ value = expand_expr_real (exp, want_value ? NULL_RTX : const0_rtx,
+ VOIDmode, 0, &alt_rtl);
type = TREE_TYPE (exp);
/* If all we do is reference a volatile value in memory,
@@ -2218,6 +2203,7 @@ expand_expr_stmt_value (exp, want_value, maybe_last)
if (want_value)
{
last_expr_value = value;
+ last_expr_alt_rtl = alt_rtl;
last_expr_type = type;
}
@@ -2228,8 +2214,7 @@ expand_expr_stmt_value (exp, want_value, maybe_last)
Return 1 if a warning is printed; 0 otherwise. */
int
-warn_if_unused_value (exp)
- tree exp;
+warn_if_unused_value (tree exp)
{
if (TREE_USED (exp))
return 0;
@@ -2250,7 +2235,6 @@ warn_if_unused_value (exp)
case INIT_EXPR:
case TARGET_EXPR:
case CALL_EXPR:
- case METHOD_CALL_EXPR:
case RTL_EXPR:
case TRY_CATCH_EXPR:
case WITH_CLEANUP_EXPR:
@@ -2327,8 +2311,7 @@ warn_if_unused_value (exp)
if (TREE_SIDE_EFFECTS (exp))
return 0;
- warning_with_file_and_line (emit_filename, emit_lineno,
- "value computed is not used");
+ warning ("%Hvalue computed is not used", &emit_locus);
return 1;
}
}
@@ -2336,10 +2319,11 @@ warn_if_unused_value (exp)
/* Clear out the memory of the last expression evaluated. */
void
-clear_last_expr ()
+clear_last_expr (void)
{
last_expr_type = NULL_TREE;
last_expr_value = NULL_RTX;
+ last_expr_alt_rtl = NULL_RTX;
}
/* Begin a statement-expression, i.e., a series of statements which
@@ -2350,8 +2334,7 @@ clear_last_expr ()
expression. */
tree
-expand_start_stmt_expr (has_scope)
- int has_scope;
+expand_start_stmt_expr (int has_scope)
{
tree t;
@@ -2381,14 +2364,14 @@ expand_start_stmt_expr (has_scope)
return something with type `void'. */
tree
-expand_end_stmt_expr (t)
- tree t;
+expand_end_stmt_expr (tree t)
{
OK_DEFER_POP;
if (! last_expr_value || ! last_expr_type)
{
last_expr_value = const0_rtx;
+ last_expr_alt_rtl = NULL_RTX;
last_expr_type = void_type_node;
}
else if (GET_CODE (last_expr_value) != REG && ! CONSTANT_P (last_expr_value))
@@ -2399,6 +2382,7 @@ expand_end_stmt_expr (t)
TREE_TYPE (t) = last_expr_type;
RTL_EXPR_RTL (t) = last_expr_value;
+ RTL_EXPR_ALT_RTL (t) = last_expr_alt_rtl;
RTL_EXPR_SEQUENCE (t) = get_insns ();
rtl_expr_chain = tree_cons (NULL_TREE, t, rtl_expr_chain);
@@ -2423,9 +2407,7 @@ expand_end_stmt_expr (t)
`exit_something'. */
void
-expand_start_cond (cond, exitflag)
- tree cond;
- int exitflag;
+expand_start_cond (tree cond, int exitflag)
{
struct nesting *thiscond = ALLOC_NESTING ();
@@ -2451,8 +2433,7 @@ expand_start_cond (cond, exitflag)
of an if-then-elseif-.... */
void
-expand_start_elseif (cond)
- tree cond;
+expand_start_elseif (tree cond)
{
if (cond_stack->data.cond.endif_label == 0)
cond_stack->data.cond.endif_label = gen_label_rtx ();
@@ -2466,7 +2447,7 @@ expand_start_elseif (cond)
of an if-then-else. */
void
-expand_start_else ()
+expand_start_else (void)
{
if (cond_stack->data.cond.endif_label == 0)
cond_stack->data.cond.endif_label = gen_label_rtx ();
@@ -2480,8 +2461,7 @@ expand_start_else ()
by providing another condition. */
void
-expand_elseif (cond)
- tree cond;
+expand_elseif (tree cond)
{
cond_stack->data.cond.next_label = gen_label_rtx ();
do_jump (cond, cond_stack->data.cond.next_label, NULL_RTX);
@@ -2491,7 +2471,7 @@ expand_elseif (cond)
Pop the record for it off of cond_stack. */
void
-expand_end_cond ()
+expand_end_cond (void)
{
struct nesting *thiscond = cond_stack;
@@ -2513,8 +2493,7 @@ expand_end_cond ()
this loop. */
struct nesting *
-expand_start_loop (exit_flag)
- int exit_flag;
+expand_start_loop (int exit_flag)
{
struct nesting *thisloop = ALLOC_NESTING ();
@@ -2526,7 +2505,6 @@ expand_start_loop (exit_flag)
thisloop->depth = ++nesting_depth;
thisloop->data.loop.start_label = gen_label_rtx ();
thisloop->data.loop.end_label = gen_label_rtx ();
- thisloop->data.loop.alt_end_label = 0;
thisloop->data.loop.continue_label = thisloop->data.loop.start_label;
thisloop->exit_label = exit_flag ? thisloop->data.loop.end_label : 0;
loop_stack = thisloop;
@@ -2534,7 +2512,7 @@ expand_start_loop (exit_flag)
do_pending_stack_adjust ();
emit_queue ();
- emit_note (NULL, NOTE_INSN_LOOP_BEG);
+ emit_note (NOTE_INSN_LOOP_BEG);
emit_label (thisloop->data.loop.start_label);
return thisloop;
@@ -2544,8 +2522,7 @@ expand_start_loop (exit_flag)
(for expand_continue_loop) will be specified explicitly. */
struct nesting *
-expand_start_loop_continue_elsewhere (exit_flag)
- int exit_flag;
+expand_start_loop_continue_elsewhere (int exit_flag)
{
struct nesting *thisloop = expand_start_loop (exit_flag);
loop_stack->data.loop.continue_label = gen_label_rtx ();
@@ -2556,7 +2533,7 @@ expand_start_loop_continue_elsewhere (exit_flag)
of said loop can still contain a break, we must frob the loop nest. */
struct nesting *
-expand_start_null_loop ()
+expand_start_null_loop (void)
{
struct nesting *thisloop = ALLOC_NESTING ();
@@ -2566,9 +2543,8 @@ expand_start_null_loop ()
thisloop->next = loop_stack;
thisloop->all = nesting_stack;
thisloop->depth = ++nesting_depth;
- thisloop->data.loop.start_label = emit_note (NULL, NOTE_INSN_DELETED);
+ thisloop->data.loop.start_label = emit_note (NOTE_INSN_DELETED);
thisloop->data.loop.end_label = gen_label_rtx ();
- thisloop->data.loop.alt_end_label = NULL_RTX;
thisloop->data.loop.continue_label = thisloop->data.loop.end_label;
thisloop->exit_label = thisloop->data.loop.end_label;
loop_stack = thisloop;
@@ -2583,10 +2559,10 @@ expand_start_null_loop ()
should jump. */
void
-expand_loop_continue_here ()
+expand_loop_continue_here (void)
{
do_pending_stack_adjust ();
- emit_note (NULL, NOTE_INSN_LOOP_CONT);
+ emit_note (NOTE_INSN_LOOP_CONT);
emit_label (loop_stack->data.loop.continue_label);
}
@@ -2594,11 +2570,12 @@ expand_loop_continue_here ()
Pop the block off of loop_stack. */
void
-expand_end_loop ()
+expand_end_loop (void)
{
rtx start_label = loop_stack->data.loop.start_label;
rtx etc_note;
int eh_regions, debug_blocks;
+ bool empty_test;
/* Mark the continue-point at the top of the loop if none elsewhere. */
if (start_label == loop_stack->data.loop.continue_label)
@@ -2631,7 +2608,7 @@ expand_end_loop ()
end_label:
We rely on the presence of NOTE_INSN_LOOP_END_TOP_COND to mark
- the end of the entry condtional. Without this, our lexical scan
+ the end of the entry conditional. Without this, our lexical scan
can't tell the difference between an entry conditional and a
body conditional that exits the loop. Mistaking the two means
that we can misplace the NOTE_INSN_LOOP_CONT note, which can
@@ -2642,6 +2619,7 @@ expand_end_loop ()
/* Scan insns from the top of the loop looking for the END_TOP_COND note. */
+ empty_test = true;
eh_regions = debug_blocks = 0;
for (etc_note = start_label; etc_note ; etc_note = NEXT_INSN (etc_note))
if (GET_CODE (etc_note) == NOTE)
@@ -2682,9 +2660,12 @@ expand_end_loop ()
else if (NOTE_LINE_NUMBER (etc_note) == NOTE_INSN_BLOCK_END)
debug_blocks--;
}
+ else if (INSN_P (etc_note))
+ empty_test = false;
if (etc_note
&& optimize
+ && ! empty_test
&& eh_regions == 0
&& (debug_blocks == 0 || optimize >= 2)
&& NEXT_INSN (etc_note) != NULL_RTX
@@ -2733,7 +2714,7 @@ expand_end_loop ()
}
emit_jump (start_label);
- emit_note (NULL, NOTE_INSN_LOOP_END);
+ emit_note (NOTE_INSN_LOOP_END);
emit_label (loop_stack->data.loop.end_label);
POPSTACK (loop_stack);
@@ -2744,7 +2725,7 @@ expand_end_loop ()
/* Finish a null loop, aka do { } while (0). */
void
-expand_end_null_loop ()
+expand_end_null_loop (void)
{
do_pending_stack_adjust ();
emit_label (loop_stack->data.loop.end_label);
@@ -2760,15 +2741,14 @@ expand_end_null_loop ()
return 0 and do nothing; caller will print an error message. */
int
-expand_continue_loop (whichloop)
- struct nesting *whichloop;
+expand_continue_loop (struct nesting *whichloop)
{
/* Emit information for branch prediction. */
rtx note;
if (flag_guess_branch_prob)
{
- note = emit_note (NULL, NOTE_INSN_PREDICTION);
+ note = emit_note (NOTE_INSN_PREDICTION);
NOTE_PREDICTION (note) = NOTE_PREDICT (PRED_CONTINUE, IS_TAKEN);
}
clear_last_expr ();
@@ -2785,8 +2765,7 @@ expand_continue_loop (whichloop)
return 0 and do nothing; caller will print an error message. */
int
-expand_exit_loop (whichloop)
- struct nesting *whichloop;
+expand_exit_loop (struct nesting *whichloop)
{
clear_last_expr ();
if (whichloop == 0)
@@ -2802,26 +2781,34 @@ expand_exit_loop (whichloop)
return 0 and do nothing; caller will print an error message. */
int
-expand_exit_loop_if_false (whichloop, cond)
- struct nesting *whichloop;
- tree cond;
+expand_exit_loop_if_false (struct nesting *whichloop, tree cond)
{
- rtx label = gen_label_rtx ();
- rtx last_insn;
+ rtx label;
clear_last_expr ();
if (whichloop == 0)
whichloop = loop_stack;
if (whichloop == 0)
return 0;
+
+ if (integer_nonzerop (cond))
+ return 1;
+ if (integer_zerop (cond))
+ return expand_exit_loop (whichloop);
+
+ /* Check if we definitely won't need a fixup. */
+ if (whichloop == nesting_stack)
+ {
+ jumpifnot (cond, whichloop->data.loop.end_label);
+ return 1;
+ }
+
/* In order to handle fixups, we actually create a conditional jump
around an unconditional branch to exit the loop. If fixups are
necessary, they go before the unconditional branch. */
- do_jump (cond, NULL_RTX, label);
- last_insn = get_last_insn ();
- if (GET_CODE (last_insn) == CODE_LABEL)
- whichloop->data.loop.alt_end_label = last_insn;
+ label = gen_label_rtx ();
+ jumpif (cond, label);
expand_goto_internal (NULL_TREE, whichloop->data.loop.end_label,
NULL_RTX);
emit_label (label);
@@ -2834,28 +2821,15 @@ expand_exit_loop_if_false (whichloop, cond)
after expand_loop_start. */
int
-expand_exit_loop_top_cond (whichloop, cond)
- struct nesting *whichloop;
- tree cond;
+expand_exit_loop_top_cond (struct nesting *whichloop, tree cond)
{
if (! expand_exit_loop_if_false (whichloop, cond))
return 0;
- emit_note (NULL, NOTE_INSN_LOOP_END_TOP_COND);
+ emit_note (NOTE_INSN_LOOP_END_TOP_COND);
return 1;
}
-/* Return nonzero if the loop nest is empty. Else return zero. */
-
-int
-stmt_loop_nest_empty ()
-{
- /* cfun->stmt can be NULL if we are building a call to get the
- EH context for a setjmp/longjmp EH target and the current
- function was a deferred inline function. */
- return (cfun->stmt == NULL || loop_stack == NULL);
-}
-
/* Return nonzero if we should preserve sub-expressions as separate
pseudos. We never do so if we aren't optimizing. We always do so
if -fexpensive-optimizations.
@@ -2864,7 +2838,7 @@ stmt_loop_nest_empty ()
the loop may still be a small one. */
int
-preserve_subexpressions_p ()
+preserve_subexpressions_p (void)
{
rtx insn;
@@ -2892,7 +2866,7 @@ preserve_subexpressions_p ()
return 0 and do nothing; caller will print an error message. */
int
-expand_exit_something ()
+expand_exit_something (void)
{
struct nesting *n;
clear_last_expr ();
@@ -2910,7 +2884,7 @@ expand_exit_something ()
(That is, we do not do anything about returning any value.) */
void
-expand_null_return ()
+expand_null_return (void)
{
rtx last_insn;
@@ -2924,10 +2898,29 @@ expand_null_return ()
expand_null_return_1 (last_insn);
}
+/* Generate RTL to return directly from the current function.
+ (That is, we bypass any return value.) */
+
+void
+expand_naked_return (void)
+{
+ rtx last_insn, end_label;
+
+ last_insn = get_last_insn ();
+ end_label = naked_return_label;
+
+ clear_pending_stack_adjust ();
+ do_pending_stack_adjust ();
+ clear_last_expr ();
+
+ if (end_label == 0)
+ end_label = naked_return_label = gen_label_rtx ();
+ expand_goto_internal (NULL_TREE, end_label, last_insn);
+}
+
/* Try to guess whether the value of return means error code. */
static enum br_predictor
-return_prediction (val)
- rtx val;
+return_prediction (rtx val)
{
/* Different heuristics for pointers and scalars. */
if (POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))))
@@ -2953,11 +2946,38 @@ return_prediction (val)
return PRED_NO_PREDICTION;
}
+
+/* If the current function returns values in the most significant part
+ of a register, shift return value VAL appropriately. The mode of
+ the function's return type is known not to be BLKmode. */
+
+static rtx
+shift_return_value (rtx val)
+{
+ tree type;
+
+ type = TREE_TYPE (DECL_RESULT (current_function_decl));
+ if (targetm.calls.return_in_msb (type))
+ {
+ rtx target;
+ HOST_WIDE_INT shift;
+
+ target = DECL_RTL (DECL_RESULT (current_function_decl));
+ shift = (GET_MODE_BITSIZE (GET_MODE (target))
+ - BITS_PER_UNIT * int_size_in_bytes (type));
+ if (shift > 0)
+ val = expand_binop (GET_MODE (target), ashl_optab,
+ gen_lowpart (GET_MODE (target), val),
+ GEN_INT (shift), target, 1, OPTAB_WIDEN);
+ }
+ return val;
+}
+
+
/* Generate RTL to return from the current function, with value VAL. */
static void
-expand_value_return (val)
- rtx val;
+expand_value_return (rtx val)
{
rtx last_insn;
rtx return_reg;
@@ -2969,7 +2989,7 @@ expand_value_return (val)
/* Emit information for branch prediction. */
rtx note;
- note = emit_note (NULL, NOTE_INSN_PREDICTION);
+ note = emit_note (NOTE_INSN_PREDICTION);
NOTE_PREDICTION (note) = NOTE_PREDICT (pred, NOT_TAKEN);
@@ -2984,18 +3004,19 @@ expand_value_return (val)
if (return_reg != val)
{
tree type = TREE_TYPE (DECL_RESULT (current_function_decl));
-#ifdef PROMOTE_FUNCTION_RETURN
- int unsignedp = TREE_UNSIGNED (type);
- enum machine_mode old_mode
- = DECL_MODE (DECL_RESULT (current_function_decl));
- enum machine_mode mode
- = promote_mode (type, old_mode, &unsignedp, 1);
-
- if (mode != old_mode)
- val = convert_modes (mode, old_mode, val, unsignedp);
-#endif
+ if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl)))
+ {
+ int unsignedp = TREE_UNSIGNED (type);
+ enum machine_mode old_mode
+ = DECL_MODE (DECL_RESULT (current_function_decl));
+ enum machine_mode mode
+ = promote_mode (type, old_mode, &unsignedp, 1);
+
+ if (mode != old_mode)
+ val = convert_modes (mode, old_mode, val, unsignedp);
+ }
if (GET_CODE (return_reg) == PARALLEL)
- emit_group_load (return_reg, val, int_size_in_bytes (type));
+ emit_group_load (return_reg, val, type, int_size_in_bytes (type));
else
emit_move_insn (return_reg, val);
}
@@ -3007,8 +3028,7 @@ expand_value_return (val)
pretend that the return takes place after LAST_INSN. */
static void
-expand_null_return_1 (last_insn)
- rtx last_insn;
+expand_null_return_1 (rtx last_insn)
{
rtx end_label = cleanup_label ? cleanup_label : return_label;
@@ -3025,8 +3045,7 @@ expand_null_return_1 (last_insn)
from the current function. */
void
-expand_return (retval)
- tree retval;
+expand_return (tree retval)
{
/* If there are any cleanups to be performed, then they will
be inserted following LAST_INSN. It is desirable
@@ -3119,13 +3138,13 @@ expand_return (retval)
{
int i;
unsigned HOST_WIDE_INT bitpos, xbitpos;
- unsigned HOST_WIDE_INT big_endian_correction = 0;
+ unsigned HOST_WIDE_INT padding_correction = 0;
unsigned HOST_WIDE_INT bytes
= int_size_in_bytes (TREE_TYPE (retval_rhs));
int n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
unsigned int bitsize
= MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)), BITS_PER_WORD);
- rtx *result_pseudos = (rtx *) alloca (sizeof (rtx) * n_regs);
+ rtx *result_pseudos = alloca (sizeof (rtx) * n_regs);
rtx result_reg, src = NULL_RTX, dst = NULL_RTX;
rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0);
enum machine_mode tmpmode, result_reg_mode;
@@ -3136,25 +3155,33 @@ expand_return (retval)
return;
}
- /* Structures whose size is not a multiple of a word are aligned
- to the least significant byte (to the right). On a BYTES_BIG_ENDIAN
- machine, this means we must skip the empty high order bytes when
- calculating the bit offset. */
- if (BYTES_BIG_ENDIAN
- && bytes % UNITS_PER_WORD)
- big_endian_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
- * BITS_PER_UNIT));
+ /* If the structure doesn't take up a whole number of words, see
+ whether the register value should be padded on the left or on
+ the right. Set PADDING_CORRECTION to the number of padding
+ bits needed on the left side.
+
+ In most ABIs, the structure will be returned at the least end of
+ the register, which translates to right padding on little-endian
+ targets and left padding on big-endian targets. The opposite
+ holds if the structure is returned at the most significant
+ end of the register. */
+ if (bytes % UNITS_PER_WORD != 0
+ && (targetm.calls.return_in_msb (TREE_TYPE (retval_rhs))
+ ? !BYTES_BIG_ENDIAN
+ : BYTES_BIG_ENDIAN))
+ padding_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
+ * BITS_PER_UNIT));
/* Copy the structure BITSIZE bits at a time. */
- for (bitpos = 0, xbitpos = big_endian_correction;
+ for (bitpos = 0, xbitpos = padding_correction;
bitpos < bytes * BITS_PER_UNIT;
bitpos += bitsize, xbitpos += bitsize)
{
/* We need a new destination pseudo each time xbitpos is
- on a word boundary and when xbitpos == big_endian_correction
+ on a word boundary and when xbitpos == padding_correction
(the first time through). */
if (xbitpos % BITS_PER_WORD == 0
- || xbitpos == big_endian_correction)
+ || xbitpos == padding_correction)
{
/* Generate an appropriate register. */
dst = gen_reg_rtx (word_mode);
@@ -3181,21 +3208,25 @@ expand_return (retval)
BITS_PER_WORD);
}
- /* Find the smallest integer mode large enough to hold the
- entire structure and use that mode instead of BLKmode
- on the USE insn for the return register. */
- for (tmpmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
- tmpmode != VOIDmode;
- tmpmode = GET_MODE_WIDER_MODE (tmpmode))
- /* Have we found a large enough mode? */
- if (GET_MODE_SIZE (tmpmode) >= bytes)
- break;
+ tmpmode = GET_MODE (result_rtl);
+ if (tmpmode == BLKmode)
+ {
+ /* Find the smallest integer mode large enough to hold the
+ entire structure and use that mode instead of BLKmode
+ on the USE insn for the return register. */
+ for (tmpmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+ tmpmode != VOIDmode;
+ tmpmode = GET_MODE_WIDER_MODE (tmpmode))
+ /* Have we found a large enough mode? */
+ if (GET_MODE_SIZE (tmpmode) >= bytes)
+ break;
- /* No suitable mode found. */
- if (tmpmode == VOIDmode)
- abort ();
+ /* No suitable mode found. */
+ if (tmpmode == VOIDmode)
+ abort ();
- PUT_MODE (result_rtl, tmpmode);
+ PUT_MODE (result_rtl, tmpmode);
+ }
if (GET_MODE_SIZE (tmpmode) < GET_MODE_SIZE (word_mode))
result_reg_mode = word_mode;
@@ -3228,7 +3259,7 @@ expand_return (retval)
val = force_not_mem (val);
emit_queue ();
/* Return the calculated value, doing cleanups first. */
- expand_value_return (val);
+ expand_value_return (shift_return_value (val));
}
else
{
@@ -3239,18 +3270,6 @@ expand_return (retval)
expand_value_return (result_rtl);
}
}
-
-/* Return 1 if the end of the generated RTX is not a barrier.
- This means code already compiled can drop through. */
-
-int
-drop_through_at_end_p ()
-{
- rtx insn = get_last_insn ();
- while (insn && GET_CODE (insn) == NOTE)
- insn = PREV_INSN (insn);
- return insn && GET_CODE (insn) != BARRIER;
-}
/* Attempt to optimize a potential tail recursion call into a goto.
ARGUMENTS are the arguments to a CALL_EXPR; LAST_INSN indicates
@@ -3259,9 +3278,7 @@ drop_through_at_end_p ()
Return TRUE if the call was optimized into a goto. */
int
-optimize_tail_recursion (arguments, last_insn)
- tree arguments;
- rtx last_insn;
+optimize_tail_recursion (tree arguments, rtx last_insn)
{
/* Finish checking validity, and if valid emit code to set the
argument variables for the new call. */
@@ -3288,8 +3305,7 @@ optimize_tail_recursion (arguments, last_insn)
otherwise return 0 and do not emit any code. */
static int
-tail_recursion_args (actuals, formals)
- tree actuals, formals;
+tail_recursion_args (tree actuals, tree formals)
{
tree a = actuals, f = formals;
int i;
@@ -3315,7 +3331,7 @@ tail_recursion_args (actuals, formals)
/* Compute all the actuals. */
- argvec = (rtx *) alloca (i * sizeof (rtx));
+ argvec = alloca (i * sizeof (rtx));
for (a = actuals, i = 0; a; a = TREE_CHAIN (a), i++)
argvec[i] = expand_expr (TREE_VALUE (a), NULL_RTX, VOIDmode, 0);
@@ -3384,9 +3400,7 @@ tail_recursion_args (actuals, formals)
note. */
void
-expand_start_bindings_and_block (flags, block)
- int flags;
- tree block;
+expand_start_bindings_and_block (int flags, tree block)
{
struct nesting *thisblock = ALLOC_NESTING ();
rtx note;
@@ -3401,11 +3415,11 @@ expand_start_bindings_and_block (flags, block)
/* Create a note to mark the beginning of the block. */
if (block_flag)
{
- note = emit_note (NULL, NOTE_INSN_BLOCK_BEG);
+ note = emit_note (NOTE_INSN_BLOCK_BEG);
NOTE_BLOCK (note) = block;
}
else
- note = emit_note (NULL, NOTE_INSN_DELETED);
+ note = emit_note (NOTE_INSN_DELETED);
/* Make an entry on block_stack for the block we are entering. */
@@ -3415,7 +3429,6 @@ expand_start_bindings_and_block (flags, block)
thisblock->depth = ++nesting_depth;
thisblock->data.block.stack_level = 0;
thisblock->data.block.cleanups = 0;
- thisblock->data.block.n_function_calls = 0;
thisblock->data.block.exception_region = 0;
thisblock->data.block.block_target_temp_slot_level = target_temp_slot_level;
@@ -3427,7 +3440,7 @@ expand_start_bindings_and_block (flags, block)
fix this is to just insert another instruction here, so that the
instructions inserted after the last unconditional cleanup are
never the last instruction. */
- emit_note (NULL, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
if (block_stack
&& !(block_stack->data.block.cleanups == NULL_TREE
@@ -3456,7 +3469,7 @@ expand_start_bindings_and_block (flags, block)
destroyed and their space freed for reuse. */
void
-expand_start_target_temps ()
+expand_start_target_temps (void)
{
/* This is so that even if the result is preserved, the space
allocated will be freed, as we know that it is no longer in use. */
@@ -3470,7 +3483,7 @@ expand_start_target_temps ()
}
void
-expand_end_target_temps ()
+expand_end_target_temps (void)
{
expand_end_bindings (NULL_TREE, 0, 0);
@@ -3490,9 +3503,11 @@ expand_end_target_temps ()
*that* node in turn will point to the relevant FUNCTION_DECL node. */
int
-is_body_block (stmt)
- tree stmt;
+is_body_block (tree stmt)
{
+ if (lang_hooks.no_body_blocks)
+ return 0;
+
if (TREE_CODE (stmt) == BLOCK)
{
tree parent = BLOCK_SUPERCONTEXT (stmt);
@@ -3514,7 +3529,7 @@ is_body_block (stmt)
the cleanup handling code to generate conditional cleanup actions. */
int
-conditional_context ()
+conditional_context (void)
{
return block_stack && block_stack->data.block.conditional_code;
}
@@ -3523,7 +3538,7 @@ conditional_context ()
can check its own sanity. */
struct nesting *
-current_nesting_level ()
+current_nesting_level (void)
{
return cfun ? block_stack : 0;
}
@@ -3532,8 +3547,7 @@ current_nesting_level ()
Also emit code to store the handler label in SLOT before BEFORE_INSN. */
static rtx
-expand_nl_handler_label (slot, before_insn)
- rtx slot, before_insn;
+expand_nl_handler_label (rtx slot, rtx before_insn)
{
rtx insns;
rtx handler_label = gen_label_rtx ();
@@ -3555,8 +3569,16 @@ expand_nl_handler_label (slot, before_insn)
/* Emit code to restore vital registers at the beginning of a nonlocal goto
handler. */
static void
-expand_nl_goto_receiver ()
+expand_nl_goto_receiver (void)
{
+ /* Clobber the FP when we get here, so we have to make sure it's
+ marked as used by this function. */
+ emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
+
+ /* Mark the static chain as clobbered here so life information
+ doesn't get messed up for it. */
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, static_chain_rtx));
+
#ifdef HAVE_nonlocal_goto
if (! HAVE_nonlocal_goto)
#endif
@@ -3605,14 +3627,20 @@ expand_nl_goto_receiver ()
if (HAVE_nonlocal_goto_receiver)
emit_insn (gen_nonlocal_goto_receiver ());
#endif
+
+ /* @@@ This is a kludge. Not all machine descriptions define a blockage
+ insn, but we must not allow the code we just generated to be reordered
+ by scheduling. Specifically, the update of the frame pointer must
+ happen immediately, not later. So emit an ASM_INPUT to act as blockage
+ insn. */
+ emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
}
/* Make handlers for nonlocal gotos taking place in the function calls in
block THISBLOCK. */
static void
-expand_nl_goto_receivers (thisblock)
- struct nesting *thisblock;
+expand_nl_goto_receivers (struct nesting *thisblock)
{
tree link;
rtx afterward = gen_label_rtx ();
@@ -3689,8 +3717,7 @@ expand_nl_goto_receivers (thisblock)
via the TREE_CHAIN field. */
void
-warn_about_unused_variables (vars)
- tree vars;
+warn_about_unused_variables (tree vars)
{
tree decl;
@@ -3700,7 +3727,7 @@ warn_about_unused_variables (vars)
&& ! TREE_USED (decl)
&& ! DECL_IN_SYSTEM_HEADER (decl)
&& DECL_NAME (decl) && ! DECL_ARTIFICIAL (decl))
- warning_with_decl (decl, "unused variable `%s'");
+ warning ("%Junused variable '%D'", decl, decl);
}
/* Generate RTL code to terminate a binding contour.
@@ -3712,14 +3739,13 @@ warn_about_unused_variables (vars)
MARK_ENDS is nonzero if we should put a note at the beginning
and end of this binding contour.
- DONT_JUMP_IN is nonzero if it is not valid to jump into this contour.
- (That is true automatically if the contour has a saved stack level.) */
+ DONT_JUMP_IN is positive if it is not valid to jump into this contour,
+ zero if we can jump into this contour only if it does not have a saved
+ stack level, and negative if we are not to check for invalid use of
+ labels (because the front end does that). */
void
-expand_end_bindings (vars, mark_ends, dont_jump_in)
- tree vars;
- int mark_ends;
- int dont_jump_in;
+expand_end_bindings (tree vars, int mark_ends, int dont_jump_in)
{
struct nesting *thisblock = block_stack;
@@ -3735,8 +3761,7 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
/* If necessary, make handlers for nonlocal gotos taking
place in the function calls in this block. */
- if (function_call_count != thisblock->data.block.n_function_calls
- && nonlocal_labels
+ if (function_call_count != 0 && nonlocal_labels
/* Make handler for outermost block
if there were any nonlocal gotos to this function. */
&& (thisblock->next == 0 ? current_function_has_nonlocal_label
@@ -3748,8 +3773,8 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
/* Don't allow jumping into a block that has a stack level.
Cleanups are allowed, though. */
- if (dont_jump_in
- || thisblock->data.block.stack_level != 0)
+ if (dont_jump_in > 0
+ || (dont_jump_in == 0 && thisblock->data.block.stack_level != 0))
{
struct label_chain *chain;
@@ -3762,8 +3787,8 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
that must be an error, because gotos without fixups
come from outside all saved stack-levels. */
if (TREE_ADDRESSABLE (chain->label))
- error_with_decl (chain->label,
- "label `%s' used before containing binding contour");
+ error ("%Jlabel '%D' used before containing binding contour",
+ chain->label, chain->label);
}
}
@@ -3780,6 +3805,7 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
/* Don't let cleanups affect ({...}) constructs. */
int old_expr_stmts_for_value = expr_stmts_for_value;
rtx old_last_expr_value = last_expr_value;
+ rtx old_last_expr_alt_rtl = last_expr_alt_rtl;
tree old_last_expr_type = last_expr_type;
expr_stmts_for_value = 0;
@@ -3790,12 +3816,13 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
reachable = (! insn || GET_CODE (insn) != BARRIER);
/* Do the cleanups. */
- expand_cleanups (thisblock->data.block.cleanups, NULL_TREE, 0, reachable);
+ expand_cleanups (thisblock->data.block.cleanups, 0, reachable);
if (reachable)
do_pending_stack_adjust ();
expr_stmts_for_value = old_expr_stmts_for_value;
last_expr_value = old_last_expr_value;
+ last_expr_alt_rtl = old_last_expr_alt_rtl;
last_expr_type = old_last_expr_type;
/* Restore the stack level. */
@@ -3825,7 +3852,7 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
if (mark_ends)
{
- rtx note = emit_note (NULL, NOTE_INSN_BLOCK_END);
+ rtx note = emit_note (NOTE_INSN_BLOCK_END);
NOTE_BLOCK (note) = NOTE_BLOCK (thisblock->data.block.first_insn);
}
else
@@ -3848,7 +3875,7 @@ expand_end_bindings (vars, mark_ends, dont_jump_in)
and set up to restore it on exit. */
void
-save_stack_pointer ()
+save_stack_pointer (void)
{
struct nesting *thisblock = block_stack;
@@ -3865,10 +3892,8 @@ save_stack_pointer ()
(Other kinds of declarations are simply ignored if seen here.) */
void
-expand_decl (decl)
- tree decl;
+expand_decl (tree decl)
{
- struct nesting *thisblock;
tree type;
type = TREE_TYPE (decl);
@@ -3894,8 +3919,6 @@ expand_decl (decl)
if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
return;
- thisblock = block_stack;
-
/* Create the RTL representation for the variable. */
if (type == error_mark_node)
@@ -3923,7 +3946,7 @@ expand_decl (decl)
&& TREE_CODE (type) == REAL_TYPE)
&& ! TREE_THIS_VOLATILE (decl)
&& ! DECL_NONLOCAL (decl)
- && (DECL_REGISTER (decl) || optimize))
+ && (DECL_REGISTER (decl) || DECL_ARTIFICIAL (decl) || optimize))
{
/* Automatic variable that can go in a register. */
int unsignedp = TREE_UNSIGNED (type);
@@ -3932,15 +3955,8 @@ expand_decl (decl)
SET_DECL_RTL (decl, gen_reg_rtx (reg_mode));
- if (GET_CODE (DECL_RTL (decl)) == REG)
- REGNO_DECL (REGNO (DECL_RTL (decl))) = decl;
- else if (GET_CODE (DECL_RTL (decl)) == CONCAT)
- {
- REGNO_DECL (REGNO (XEXP (DECL_RTL (decl), 0))) = decl;
- REGNO_DECL (REGNO (XEXP (DECL_RTL (decl), 1))) = decl;
- }
-
- mark_user_reg (DECL_RTL (decl));
+ if (!DECL_ARTIFICIAL (decl))
+ mark_user_reg (DECL_RTL (decl));
if (POINTER_TYPE_P (type))
mark_reg_pointer (DECL_RTL (decl),
@@ -4037,8 +4053,7 @@ expand_decl (decl)
/* Emit code to perform the initialization of a declaration DECL. */
void
-expand_decl_init (decl)
- tree decl;
+expand_decl_init (tree decl)
{
int was_used = TREE_USED (decl);
@@ -4059,13 +4074,13 @@ expand_decl_init (decl)
if (code == INTEGER_TYPE || code == REAL_TYPE || code == ENUMERAL_TYPE
|| code == POINTER_TYPE || code == REFERENCE_TYPE)
expand_assignment (decl, convert (TREE_TYPE (decl), integer_zero_node),
- 0, 0);
+ 0);
emit_queue ();
}
else if (DECL_INITIAL (decl) && TREE_CODE (DECL_INITIAL (decl)) != TREE_LIST)
{
- emit_line_note (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
- expand_assignment (decl, DECL_INITIAL (decl), 0, 0);
+ emit_line_note (DECL_SOURCE_LOCATION (decl));
+ expand_assignment (decl, DECL_INITIAL (decl), 0);
emit_queue ();
}
@@ -4090,8 +4105,7 @@ expand_decl_init (decl)
that is not associated with any particular variable. */
int
-expand_decl_cleanup (decl, cleanup)
- tree decl, cleanup;
+expand_decl_cleanup (tree decl, tree cleanup)
{
struct nesting *thisblock;
@@ -4177,7 +4191,7 @@ expand_decl_cleanup (decl, cleanup)
fix this is to just insert another instruction here, so that the
instructions inserted after the last unconditional cleanup are
never the last instruction. */
- emit_note (NULL, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
}
}
return 1;
@@ -4187,9 +4201,7 @@ expand_decl_cleanup (decl, cleanup)
is thrown. */
int
-expand_decl_cleanup_eh (decl, cleanup, eh_only)
- tree decl, cleanup;
- int eh_only;
+expand_decl_cleanup_eh (tree decl, tree cleanup, int eh_only)
{
int ret = expand_decl_cleanup (decl, cleanup);
if (cleanup && ret)
@@ -4205,8 +4217,7 @@ expand_decl_cleanup_eh (decl, cleanup, eh_only)
In each, the TREE_VALUE is a VAR_DECL, and the TREE_PURPOSE a cleanup. */
void
-expand_anon_union_decl (decl, cleanup, decl_elts)
- tree decl, cleanup, decl_elts;
+expand_anon_union_decl (tree decl, tree cleanup, tree decl_elts)
{
struct nesting *thisblock = cfun == 0 ? 0 : block_stack;
rtx x;
@@ -4278,11 +4289,6 @@ expand_anon_union_decl (decl, cleanup, decl_elts)
/* Expand a list of cleanups LIST.
Elements may be expressions or may be nested lists.
- If DONT_DO is nonnull, then any list-element
- whose TREE_PURPOSE matches DONT_DO is omitted.
- This is sometimes used to avoid a cleanup associated with
- a value that is being returned out of the scope.
-
If IN_FIXUP is nonzero, we are generating this cleanup for a fixup
goto and handle protection regions specially in that case.
@@ -4290,48 +4296,41 @@ expand_anon_union_decl (decl, cleanup, decl_elts)
code about this finalization. */
static void
-expand_cleanups (list, dont_do, in_fixup, reachable)
- tree list;
- tree dont_do;
- int in_fixup;
- int reachable;
+expand_cleanups (tree list, int in_fixup, int reachable)
{
tree tail;
for (tail = list; tail; tail = TREE_CHAIN (tail))
- if (dont_do == 0 || TREE_PURPOSE (tail) != dont_do)
+ if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
+ expand_cleanups (TREE_VALUE (tail), in_fixup, reachable);
+ else
{
- if (TREE_CODE (TREE_VALUE (tail)) == TREE_LIST)
- expand_cleanups (TREE_VALUE (tail), dont_do, in_fixup, reachable);
- else
- {
- if (! in_fixup && using_eh_for_cleanups_p)
- expand_eh_region_end_cleanup (TREE_VALUE (tail));
+ if (! in_fixup && using_eh_for_cleanups_p)
+ expand_eh_region_end_cleanup (TREE_VALUE (tail));
- if (reachable && !CLEANUP_EH_ONLY (tail))
+ if (reachable && !CLEANUP_EH_ONLY (tail))
+ {
+ /* Cleanups may be run multiple times. For example,
+ when exiting a binding contour, we expand the
+ cleanups associated with that contour. When a goto
+ within that binding contour has a target outside that
+ contour, it will expand all cleanups from its scope to
+ the target. Though the cleanups are expanded multiple
+ times, the control paths are non-overlapping so the
+ cleanups will not be executed twice. */
+
+ /* We may need to protect from outer cleanups. */
+ if (in_fixup && using_eh_for_cleanups_p)
{
- /* Cleanups may be run multiple times. For example,
- when exiting a binding contour, we expand the
- cleanups associated with that contour. When a goto
- within that binding contour has a target outside that
- contour, it will expand all cleanups from its scope to
- the target. Though the cleanups are expanded multiple
- times, the control paths are non-overlapping so the
- cleanups will not be executed twice. */
-
- /* We may need to protect from outer cleanups. */
- if (in_fixup && using_eh_for_cleanups_p)
- {
- expand_eh_region_start ();
-
- expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
+ expand_eh_region_start ();
- expand_eh_region_end_fixup (TREE_VALUE (tail));
- }
- else
- expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
+ expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
- free_temp_slots ();
+ expand_eh_region_end_fixup (TREE_VALUE (tail));
}
+ else
+ expand_expr (TREE_VALUE (tail), const0_rtx, VOIDmode, 0);
+
+ free_temp_slots ();
}
}
}
@@ -4343,7 +4342,7 @@ expand_cleanups (list, dont_do, in_fixup, reachable)
expression (tree) is expanded that is within a conditional context. */
void
-start_cleanup_deferral ()
+start_cleanup_deferral (void)
{
/* block_stack can be NULL if we are inside the parameter list. It is
OK to do nothing, because cleanups aren't possible here. */
@@ -4357,7 +4356,7 @@ start_cleanup_deferral ()
deferred cleanups, are we back in unconditional code. */
void
-end_cleanup_deferral ()
+end_cleanup_deferral (void)
{
/* block_stack can be NULL if we are inside the parameter list. It is
OK to do nothing, because cleanups aren't possible here. */
@@ -4365,26 +4364,8 @@ end_cleanup_deferral ()
--block_stack->data.block.conditional_code;
}
-/* Move all cleanups from the current block_stack
- to the containing block_stack, where they are assumed to
- have been created. If anything can cause a temporary to
- be created, but not expanded for more than one level of
- block_stacks, then this code will have to change. */
-
-void
-move_cleanups_up ()
-{
- struct nesting *block = block_stack;
- struct nesting *outer = block->next;
-
- outer->data.block.cleanups
- = chainon (block->data.block.cleanups,
- outer->data.block.cleanups);
- block->data.block.cleanups = 0;
-}
-
tree
-last_cleanup_this_contour ()
+last_cleanup_this_contour (void)
{
if (block_stack == 0)
return 0;
@@ -4393,22 +4374,21 @@ last_cleanup_this_contour ()
}
/* Return 1 if there are any pending cleanups at this point.
- If THIS_CONTOUR is nonzero, check the current contour as well.
- Otherwise, look only at the contours that enclose this one. */
+ Check the current contour as well as contours that enclose
+ the current contour. */
int
-any_pending_cleanups (this_contour)
- int this_contour;
+any_pending_cleanups (void)
{
struct nesting *block;
if (cfun == NULL || cfun->stmt == NULL || block_stack == 0)
return 0;
- if (this_contour && block_stack->data.block.cleanups != NULL)
+ if (block_stack->data.block.cleanups != NULL)
return 1;
- if (block_stack->data.block.cleanups == 0
- && block_stack->data.block.outer_cleanups == 0)
+
+ if (block_stack->data.block.outer_cleanups == 0)
return 0;
for (block = block_stack->next; block; block = block->next)
@@ -4431,11 +4411,8 @@ any_pending_cleanups (this_contour)
but instead we take short cuts. */
void
-expand_start_case (exit_flag, expr, type, printname)
- int exit_flag;
- tree expr;
- tree type;
- const char *printname;
+expand_start_case (int exit_flag, tree expr, tree type,
+ const char *printname)
{
struct nesting *thiscase = ALLOC_NESTING ();
@@ -4461,7 +4438,7 @@ expand_start_case (exit_flag, expr, type, printname)
/* Make sure case_stmt.start points to something that won't
need any transformation before expand_end_case. */
if (GET_CODE (get_last_insn ()) != NOTE)
- emit_note (NULL, NOTE_INSN_DELETED);
+ emit_note (NOTE_INSN_DELETED);
thiscase->data.case_stmt.start = get_last_insn ();
@@ -4474,7 +4451,7 @@ expand_start_case (exit_flag, expr, type, printname)
into the middle of certain kinds of constructs. */
void
-expand_start_case_dummy ()
+expand_start_case_dummy (void)
{
struct nesting *thiscase = ALLOC_NESTING ();
@@ -4493,29 +4470,9 @@ expand_start_case_dummy ()
nesting_stack = thiscase;
start_cleanup_deferral ();
}
-
-/* End a dummy case statement. */
-
-void
-expand_end_case_dummy ()
-{
- end_cleanup_deferral ();
- POPSTACK (case_stack);
-}
-
-/* Return the data type of the index-expression
- of the innermost case statement, or null if none. */
-
-tree
-case_index_expr_type ()
-{
- if (case_stack)
- return TREE_TYPE (case_stack->data.case_stmt.index_expr);
- return 0;
-}
static void
-check_seenlabel ()
+check_seenlabel (void)
{
/* If this is the first label, warn if any insns have been emitted. */
if (case_stack->data.case_stmt.line_number_status >= 0)
@@ -4541,10 +4498,13 @@ check_seenlabel ()
/* If insn is zero, then there must have been a syntax error. */
if (insn)
- warning_with_file_and_line (NOTE_SOURCE_FILE (insn),
- NOTE_LINE_NUMBER (insn),
- "unreachable code at beginning of %s",
- case_stack->data.case_stmt.printname);
+ {
+ location_t locus;
+ locus.file = NOTE_SOURCE_FILE (insn);
+ locus.line = NOTE_LINE_NUMBER (insn);
+ warning ("%Hunreachable code at beginning of %s", &locus,
+ case_stack->data.case_stmt.printname);
+ }
break;
}
}
@@ -4567,11 +4527,8 @@ check_seenlabel ()
Extended to handle range statements. */
int
-pushcase (value, converter, label, duplicate)
- tree value;
- tree (*converter) PARAMS ((tree, tree));
- tree label;
- tree *duplicate;
+pushcase (tree value, tree (*converter) (tree, tree), tree label,
+ tree *duplicate)
{
tree index_type;
tree nominal_type;
@@ -4617,11 +4574,8 @@ pushcase (value, converter, label, duplicate)
additional error code: 4 means the specified range was empty. */
int
-pushcase_range (value1, value2, converter, label, duplicate)
- tree value1, value2;
- tree (*converter) PARAMS ((tree, tree));
- tree label;
- tree *duplicate;
+pushcase_range (tree value1, tree value2, tree (*converter) (tree, tree),
+ tree label, tree *duplicate)
{
tree index_type;
tree nominal_type;
@@ -4681,10 +4635,7 @@ pushcase_range (value1, value2, converter, label, duplicate)
slowdown for large switch statements. */
int
-add_case_node (low, high, label, duplicate)
- tree low, high;
- tree label;
- tree *duplicate;
+add_case_node (tree low, tree high, tree label, tree *duplicate)
{
struct case_node *p, **q, *r;
@@ -4732,7 +4683,7 @@ add_case_node (low, high, label, duplicate)
/* Add this label to the chain, and succeed. */
- r = (struct case_node *) ggc_alloc (sizeof (struct case_node));
+ r = ggc_alloc (sizeof (struct case_node));
r->low = low;
/* If the bounds are equal, turn this into the one-value case. */
@@ -4928,9 +4879,7 @@ add_case_node (low, high, label, duplicate)
otherwise sets it to 0. */
HOST_WIDE_INT
-all_cases_count (type, sparseness)
- tree type;
- int *sparseness;
+all_cases_count (tree type, int *sparseness)
{
tree t;
HOST_WIDE_INT count, minval, lastval;
@@ -5003,11 +4952,8 @@ all_cases_count (type, sparseness)
SPARSENESS is 2, in which case quadratic time is needed. */
void
-mark_seen_cases (type, cases_seen, count, sparseness)
- tree type;
- unsigned char *cases_seen;
- HOST_WIDE_INT count;
- int sparseness;
+mark_seen_cases (tree type, unsigned char *cases_seen, HOST_WIDE_INT count,
+ int sparseness)
{
tree next_node_to_try = NULL_TREE;
HOST_WIDE_INT next_node_offset = 0;
@@ -5145,8 +5091,7 @@ mark_seen_cases (type, cases_seen, count, sparseness)
is the same as one of the enumeration literals.'' */
void
-check_for_full_enumeration_handling (type)
- tree type;
+check_for_full_enumeration_handling (tree type)
{
struct case_node *n;
tree chain;
@@ -5171,8 +5116,7 @@ check_for_full_enumeration_handling (type)
/* We deliberately use calloc here, not cmalloc, so that we can suppress
this optimization if we don't have enough memory rather than
aborting, as xmalloc would do. */
- && (cases_seen =
- (unsigned char *) really_call_calloc (bytes_needed, 1)) != NULL)
+ && (cases_seen = really_call_calloc (bytes_needed, 1)) != NULL)
{
HOST_WIDE_INT i;
tree v = TYPE_VALUES (type);
@@ -5246,6 +5190,151 @@ check_for_full_enumeration_handling (type)
}
+/* Maximum number of case bit tests. */
+#define MAX_CASE_BIT_TESTS 3
+
+/* By default, enable case bit tests on targets with ashlsi3. */
+#ifndef CASE_USE_BIT_TESTS
+#define CASE_USE_BIT_TESTS (ashl_optab->handlers[word_mode].insn_code \
+ != CODE_FOR_nothing)
+#endif
+
+
+/* A case_bit_test represents a set of case nodes that may be
+ selected from using a bit-wise comparison. HI and LO hold
+ the integer to be tested against, LABEL contains the label
+ to jump to upon success and BITS counts the number of case
+ nodes handled by this test, typically the number of bits
+ set in HI:LO. */
+
+struct case_bit_test
+{
+ HOST_WIDE_INT hi;
+ HOST_WIDE_INT lo;
+ rtx label;
+ int bits;
+};
+
+/* Determine whether "1 << x" is relatively cheap in word_mode. */
+
+static
+bool lshift_cheap_p (void)
+{
+ static bool init = false;
+ static bool cheap = true;
+
+ if (!init)
+ {
+ rtx reg = gen_rtx_REG (word_mode, 10000);
+ int cost = rtx_cost (gen_rtx_ASHIFT (word_mode, const1_rtx, reg), SET);
+ cheap = cost < COSTS_N_INSNS (3);
+ init = true;
+ }
+
+ return cheap;
+}
+
+/* Comparison function for qsort to order bit tests by decreasing
+ number of case nodes, i.e. the node with the most cases gets
+ tested first. */
+
+static
+int case_bit_test_cmp (const void *p1, const void *p2)
+{
+ const struct case_bit_test *d1 = p1;
+ const struct case_bit_test *d2 = p2;
+
+ return d2->bits - d1->bits;
+}
+
+/* Expand a switch statement by a short sequence of bit-wise
+ comparisons. "switch(x)" is effectively converted into
+ "if ((1 << (x-MINVAL)) & CST)" where CST and MINVAL are
+ integer constants.
+
+ INDEX_EXPR is the value being switched on, which is of
+ type INDEX_TYPE. MINVAL is the lowest case value of in
+ the case nodes, of INDEX_TYPE type, and RANGE is highest
+ value minus MINVAL, also of type INDEX_TYPE. NODES is
+ the set of case nodes, and DEFAULT_LABEL is the label to
+ branch to should none of the cases match.
+
+ There *MUST* be MAX_CASE_BIT_TESTS or less unique case
+ node targets. */
+
+static void
+emit_case_bit_tests (tree index_type, tree index_expr, tree minval,
+ tree range, case_node_ptr nodes, rtx default_label)
+{
+ struct case_bit_test test[MAX_CASE_BIT_TESTS];
+ enum machine_mode mode;
+ rtx expr, index, label;
+ unsigned int i,j,lo,hi;
+ struct case_node *n;
+ unsigned int count;
+
+ count = 0;
+ for (n = nodes; n; n = n->right)
+ {
+ label = label_rtx (n->code_label);
+ for (i = 0; i < count; i++)
+ if (same_case_target_p (label, test[i].label))
+ break;
+
+ if (i == count)
+ {
+ if (count >= MAX_CASE_BIT_TESTS)
+ abort ();
+ test[i].hi = 0;
+ test[i].lo = 0;
+ test[i].label = label;
+ test[i].bits = 1;
+ count++;
+ }
+ else
+ test[i].bits++;
+
+ lo = tree_low_cst (fold (build (MINUS_EXPR, index_type,
+ n->low, minval)), 1);
+ hi = tree_low_cst (fold (build (MINUS_EXPR, index_type,
+ n->high, minval)), 1);
+ for (j = lo; j <= hi; j++)
+ if (j >= HOST_BITS_PER_WIDE_INT)
+ test[i].hi |= (HOST_WIDE_INT) 1 << (j - HOST_BITS_PER_INT);
+ else
+ test[i].lo |= (HOST_WIDE_INT) 1 << j;
+ }
+
+ qsort (test, count, sizeof(*test), case_bit_test_cmp);
+
+ index_expr = fold (build (MINUS_EXPR, index_type,
+ convert (index_type, index_expr),
+ convert (index_type, minval)));
+ index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
+ emit_queue ();
+ index = protect_from_queue (index, 0);
+ do_pending_stack_adjust ();
+
+ mode = TYPE_MODE (index_type);
+ expr = expand_expr (range, NULL_RTX, VOIDmode, 0);
+ emit_cmp_and_jump_insns (index, expr, GTU, NULL_RTX, mode, 1,
+ default_label);
+
+ index = convert_to_mode (word_mode, index, 0);
+ index = expand_binop (word_mode, ashl_optab, const1_rtx,
+ index, NULL_RTX, 1, OPTAB_WIDEN);
+
+ for (i = 0; i < count; i++)
+ {
+ expr = immed_double_const (test[i].lo, test[i].hi, word_mode);
+ expr = expand_binop (word_mode, and_optab, index, expr,
+ NULL_RTX, 1, OPTAB_WIDEN);
+ emit_cmp_and_jump_insns (expr, const0_rtx, NE, NULL_RTX,
+ word_mode, 1, test[i].label);
+ }
+
+ emit_jump (default_label);
+}
/* Terminate a case (Pascal) or switch (C) statement
in which ORIG_INDEX is the expression to be tested.
@@ -5254,28 +5343,27 @@ check_for_full_enumeration_handling (type)
Generate the code to test it and jump to the right place. */
void
-expand_end_case_type (orig_index, orig_type)
- tree orig_index, orig_type;
+expand_end_case_type (tree orig_index, tree orig_type)
{
tree minval = NULL_TREE, maxval = NULL_TREE, range = NULL_TREE;
rtx default_label = 0;
- struct case_node *n;
- unsigned int count;
+ struct case_node *n, *m;
+ unsigned int count, uniq;
rtx index;
rtx table_label;
int ncases;
rtx *labelvec;
int i;
- rtx before_case, end;
+ rtx before_case, end, lab;
struct nesting *thiscase = case_stack;
tree index_expr, index_type;
+ bool exit_done = false;
int unsignedp;
/* Don't crash due to previous errors. */
if (thiscase == NULL)
return;
- table_label = gen_label_rtx ();
index_expr = thiscase->data.case_stmt.index_expr;
index_type = TREE_TYPE (index_expr);
unsignedp = TREE_UNSIGNED (index_type);
@@ -5315,6 +5403,13 @@ expand_end_case_type (orig_index, orig_type)
{
thiscase->data.case_stmt.default_label
= build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
+ /* Share the exit label if possible. */
+ if (thiscase->exit_label)
+ {
+ SET_DECL_RTL (thiscase->data.case_stmt.default_label,
+ thiscase->exit_label);
+ exit_done = true;
+ }
expand_label (thiscase->data.case_stmt.default_label);
}
default_label = label_rtx (thiscase->data.case_stmt.default_label);
@@ -5328,10 +5423,13 @@ expand_end_case_type (orig_index, orig_type)
/* Simplify the case-list before we count it. */
group_case_nodes (thiscase->data.case_stmt.case_list);
+ strip_default_case_nodes (&thiscase->data.case_stmt.case_list,
+ default_label);
/* Get upper and lower bounds of case values.
Also convert all the case values to the index expr's data type. */
+ uniq = 0;
count = 0;
for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
{
@@ -5361,6 +5459,16 @@ expand_end_case_type (orig_index, orig_type)
/* A range counts double, since it requires two compares. */
if (! tree_int_cst_equal (n->low, n->high))
count++;
+
+ /* Count the number of unique case node targets. */
+ uniq++;
+ lab = label_rtx (n->code_label);
+ for (m = thiscase->data.case_stmt.case_list; m != n; m = m->right)
+ if (same_case_target_p (label_rtx (m->code_label), lab))
+ {
+ uniq--;
+ break;
+ }
}
/* Compute span of values. */
@@ -5376,22 +5484,47 @@ expand_end_case_type (orig_index, orig_type)
emit_jump (default_label);
}
+ /* Try implementing this switch statement by a short sequence of
+ bit-wise comparisons. However, we let the binary-tree case
+ below handle constant index expressions. */
+ else if (CASE_USE_BIT_TESTS
+ && ! TREE_CONSTANT (index_expr)
+ && compare_tree_int (range, GET_MODE_BITSIZE (word_mode)) < 0
+ && compare_tree_int (range, 0) > 0
+ && lshift_cheap_p ()
+ && ((uniq == 1 && count >= 3)
+ || (uniq == 2 && count >= 5)
+ || (uniq == 3 && count >= 6)))
+ {
+ /* Optimize the case where all the case values fit in a
+ word without having to subtract MINVAL. In this case,
+ we can optimize away the subtraction. */
+ if (compare_tree_int (minval, 0) > 0
+ && compare_tree_int (maxval, GET_MODE_BITSIZE (word_mode)) < 0)
+ {
+ minval = integer_zero_node;
+ range = maxval;
+ }
+ emit_case_bit_tests (index_type, index_expr, minval, range,
+ thiscase->data.case_stmt.case_list,
+ default_label);
+ }
+
/* If range of values is much bigger than number of values,
make a sequence of conditional branches instead of a dispatch.
If the switch-index is a constant, do it this way
because we can optimize it. */
else if (count < case_values_threshold ()
- || compare_tree_int (range, 10 * count) > 0
+ || compare_tree_int (range,
+ (optimize_size ? 3 : 10) * count) > 0
/* RANGE may be signed, and really large ranges will show up
as negative numbers. */
|| compare_tree_int (range, 0) < 0
#ifndef ASM_OUTPUT_ADDR_DIFF_ELT
|| flag_pic
#endif
- || TREE_CODE (index_expr) == INTEGER_CST
- || (TREE_CODE (index_expr) == COMPOUND_EXPR
- && TREE_CODE (TREE_OPERAND (index_expr, 1)) == INTEGER_CST))
+ || TREE_CONSTANT (index_expr))
{
index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
@@ -5435,7 +5568,7 @@ expand_end_case_type (orig_index, orig_type)
/* For constant index expressions we need only
issue an unconditional branch to the appropriate
target code. The job of removing any unreachable
- code is left to the optimisation phase if the
+ code is left to the optimization phase if the
"-O" option is specified. */
for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
if (! tree_int_cst_lt (index_expr, n->low)
@@ -5474,6 +5607,7 @@ expand_end_case_type (orig_index, orig_type)
}
else
{
+ table_label = gen_label_rtx ();
if (! try_casesi (index_type, index_expr, minval, range,
table_label, default_label))
{
@@ -5497,8 +5631,8 @@ expand_end_case_type (orig_index, orig_type)
/* Get table of labels to jump to, in order of case index. */
ncases = tree_low_cst (range, 0) + 1;
- labelvec = (rtx *) alloca (ncases * sizeof (rtx));
- memset ((char *) labelvec, 0, ncases * sizeof (rtx));
+ labelvec = alloca (ncases * sizeof (rtx));
+ memset (labelvec, 0, ncases * sizeof (rtx));
for (n = thiscase->data.case_stmt.case_list; n; n = n->right)
{
@@ -5523,7 +5657,7 @@ expand_end_case_type (orig_index, orig_type)
if (labelvec[i] == 0)
labelvec[i] = gen_rtx_LABEL_REF (Pmode, default_label);
- /* Output the table */
+ /* Output the table. */
emit_label (table_label);
if (CASE_VECTOR_PC_RELATIVE || flag_pic)
@@ -5555,7 +5689,7 @@ expand_end_case_type (orig_index, orig_type)
else
end_cleanup_deferral ();
- if (thiscase->exit_label)
+ if (thiscase->exit_label && !exit_done)
emit_label (thiscase->exit_label);
POPSTACK (case_stack);
@@ -5568,8 +5702,7 @@ expand_end_case_type (orig_index, orig_type)
rightmost in the resulting list. */
static struct case_node *
-case_tree2list (node, right)
- struct case_node *node, *right;
+case_tree2list (struct case_node *node, struct case_node *right)
{
struct case_node *left;
@@ -5589,13 +5722,11 @@ case_tree2list (node, right)
/* Generate code to jump to LABEL if OP1 and OP2 are equal. */
static void
-do_jump_if_equal (op1, op2, label, unsignedp)
- rtx op1, op2, label;
- int unsignedp;
+do_jump_if_equal (rtx op1, rtx op2, rtx label, int unsignedp)
{
if (GET_CODE (op1) == CONST_INT && GET_CODE (op2) == CONST_INT)
{
- if (INTVAL (op1) == INTVAL (op2))
+ if (op1 == op2)
emit_jump (label);
}
else
@@ -5629,8 +5760,7 @@ do_jump_if_equal (op1, op2, label, unsignedp)
return 0. */
static int
-estimate_case_costs (node)
- case_node_ptr node;
+estimate_case_costs (case_node_ptr node)
{
tree min_ascii = integer_minus_one_node;
tree max_ascii = convert (TREE_TYPE (node->high), build_int_2 (127, 0));
@@ -5685,32 +5815,70 @@ estimate_case_costs (node)
return 1;
}
+/* Determine whether two case labels branch to the same target. */
+
+static bool
+same_case_target_p (rtx l1, rtx l2)
+{
+ rtx i1, i2;
+
+ if (l1 == l2)
+ return true;
+
+ i1 = next_real_insn (l1);
+ i2 = next_real_insn (l2);
+ if (i1 == i2)
+ return true;
+
+ if (i1 && simplejump_p (i1))
+ {
+ l1 = XEXP (SET_SRC (PATTERN (i1)), 0);
+ }
+
+ if (i2 && simplejump_p (i2))
+ {
+ l2 = XEXP (SET_SRC (PATTERN (i2)), 0);
+ }
+ return l1 == l2;
+}
+
+/* Delete nodes that branch to the default label from a list of
+ case nodes. Eg. case 5: default: becomes just default: */
+
+static void
+strip_default_case_nodes (case_node_ptr *prev, rtx deflab)
+{
+ case_node_ptr ptr;
+
+ while (*prev)
+ {
+ ptr = *prev;
+ if (same_case_target_p (label_rtx (ptr->code_label), deflab))
+ *prev = ptr->right;
+ else
+ prev = &ptr->right;
+ }
+}
+
/* Scan an ordered list of case nodes
combining those with consecutive values or ranges.
Eg. three separate entries 1: 2: 3: become one entry 1..3: */
static void
-group_case_nodes (head)
- case_node_ptr head;
+group_case_nodes (case_node_ptr head)
{
case_node_ptr node = head;
while (node)
{
- rtx lb = next_real_insn (label_rtx (node->code_label));
- rtx lb2;
+ rtx lab = label_rtx (node->code_label);
case_node_ptr np = node;
/* Try to group the successors of NODE with NODE. */
while (((np = np->right) != 0)
/* Do they jump to the same place? */
- && ((lb2 = next_real_insn (label_rtx (np->code_label))) == lb
- || (lb != 0 && lb2 != 0
- && simplejump_p (lb)
- && simplejump_p (lb2)
- && rtx_equal_p (SET_SRC (PATTERN (lb)),
- SET_SRC (PATTERN (lb2)))))
+ && same_case_target_p (label_rtx (np->code_label), lab)
/* Are their ranges consecutive? */
&& tree_int_cst_equal (np->low,
fold (build (PLUS_EXPR,
@@ -5744,9 +5912,7 @@ group_case_nodes (head)
branch is then transformed recursively. */
static void
-balance_case_nodes (head, parent)
- case_node_ptr *head;
- case_node_ptr parent;
+balance_case_nodes (case_node_ptr *head, case_node_ptr parent)
{
case_node_ptr np;
@@ -5863,9 +6029,7 @@ balance_case_nodes (head, parent)
span. Thus the test would be redundant. */
static int
-node_has_low_bound (node, index_type)
- case_node_ptr node;
- tree index_type;
+node_has_low_bound (case_node_ptr node, tree index_type)
{
tree low_minus_one;
case_node_ptr pnode;
@@ -5910,9 +6074,7 @@ node_has_low_bound (node, index_type)
span. Thus the test would be redundant. */
static int
-node_has_high_bound (node, index_type)
- case_node_ptr node;
- tree index_type;
+node_has_high_bound (case_node_ptr node, tree index_type)
{
tree high_plus_one;
case_node_ptr pnode;
@@ -5956,9 +6118,7 @@ node_has_high_bound (node, index_type)
bounds of NODE would be redundant. */
static int
-node_is_bounded (node, index_type)
- case_node_ptr node;
- tree index_type;
+node_is_bounded (case_node_ptr node, tree index_type)
{
return (node_has_low_bound (node, index_type)
&& node_has_high_bound (node, index_type));
@@ -5967,8 +6127,7 @@ node_is_bounded (node, index_type)
/* Emit an unconditional jump to LABEL unless it would be dead code. */
static void
-emit_jump_if_reachable (label)
- rtx label;
+emit_jump_if_reachable (rtx label)
{
if (GET_CODE (get_last_insn ()) != BARRIER)
emit_jump (label);
@@ -6001,11 +6160,8 @@ emit_jump_if_reachable (label)
tests for the value 50, then this node need not test anything. */
static void
-emit_case_nodes (index, node, default_label, index_type)
- rtx index;
- case_node_ptr node;
- rtx default_label;
- tree index_type;
+emit_case_nodes (rtx index, case_node_ptr node, rtx default_label,
+ tree index_type)
{
/* If INDEX has an unsigned type, we must make unsigned branches. */
int unsignedp = TREE_UNSIGNED (index_type);
diff --git a/contrib/gcc/stor-layout.c b/contrib/gcc/stor-layout.c
index 835cb7cb1e88..4527fe493fa8 100644
--- a/contrib/gcc/stor-layout.c
+++ b/contrib/gcc/stor-layout.c
@@ -22,6 +22,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
@@ -57,13 +59,16 @@ unsigned int set_alignment = 0;
called only by a front end. */
static int reference_types_internal = 0;
-static void finalize_record_size PARAMS ((record_layout_info));
-static void finalize_type_size PARAMS ((tree));
-static void place_union_field PARAMS ((record_layout_info, tree));
-static unsigned int update_alignment_for_field
- PARAMS ((record_layout_info, tree,
- unsigned int));
-extern void debug_rli PARAMS ((record_layout_info));
+static void finalize_record_size (record_layout_info);
+static void finalize_type_size (tree);
+static void place_union_field (record_layout_info, tree);
+#if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
+static int excess_unit_span (HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT,
+ HOST_WIDE_INT, tree);
+#endif
+static unsigned int update_alignment_for_field (record_layout_info, tree,
+ unsigned int);
+extern void debug_rli (record_layout_info);
/* SAVE_EXPRs for sizes of types and decls, waiting to be expanded. */
@@ -78,7 +83,7 @@ int immediate_size_expand;
by front end. */
void
-internal_reference_types ()
+internal_reference_types (void)
{
reference_types_internal = 1;
}
@@ -86,7 +91,7 @@ internal_reference_types ()
/* Get a list of all the objects put on the pending sizes list. */
tree
-get_pending_sizes ()
+get_pending_sizes (void)
{
tree chain = pending_sizes;
tree t;
@@ -102,8 +107,7 @@ get_pending_sizes ()
/* Return nonzero if EXPR is present on the pending sizes list. */
int
-is_pending_size (expr)
- tree expr;
+is_pending_size (tree expr)
{
tree t;
@@ -116,15 +120,11 @@ is_pending_size (expr)
/* Add EXPR to the pending sizes list. */
void
-put_pending_size (expr)
- tree expr;
+put_pending_size (tree expr)
{
/* Strip any simple arithmetic from EXPR to see if it has an underlying
SAVE_EXPR. */
- while (TREE_CODE_CLASS (TREE_CODE (expr)) == '1'
- || (TREE_CODE_CLASS (TREE_CODE (expr)) == '2'
- && TREE_CONSTANT (TREE_OPERAND (expr, 1))))
- expr = TREE_OPERAND (expr, 0);
+ expr = skip_simple_arithmetic (expr);
if (TREE_CODE (expr) == SAVE_EXPR)
pending_sizes = tree_cons (NULL_TREE, expr, pending_sizes);
@@ -134,8 +134,7 @@ put_pending_size (expr)
empty. */
void
-put_pending_sizes (chain)
- tree chain;
+put_pending_sizes (tree chain)
{
if (pending_sizes)
abort ();
@@ -147,19 +146,25 @@ put_pending_sizes (chain)
to serve as the actual size-expression for a type or decl. */
tree
-variable_size (size)
- tree size;
+variable_size (tree size)
{
+ tree save;
+
/* If the language-processor is to take responsibility for variable-sized
items (e.g., languages which have elaboration procedures like Ada),
just return SIZE unchanged. Likewise for self-referential sizes and
constant sizes. */
if (TREE_CONSTANT (size)
|| (*lang_hooks.decls.global_bindings_p) () < 0
- || contains_placeholder_p (size))
+ || CONTAINS_PLACEHOLDER_P (size))
return size;
- size = save_expr (size);
+ if (TREE_CODE (size) == MINUS_EXPR && integer_onep (TREE_OPERAND (size, 1)))
+ /* If this is the upper bound of a C array, leave the minus 1 outside
+ the SAVE_EXPR so it can be folded away. */
+ TREE_OPERAND (size, 0) = save = save_expr (TREE_OPERAND (size, 0));
+ else
+ size = save = save_expr (size);
/* If an array with a variable number of elements is declared, and
the elements require destruction, we will emit a cleanup for the
@@ -169,8 +174,8 @@ variable_size (size)
`unsaved', i.e., all SAVE_EXPRs are recalculated. However, we do
not wish to do that here; the array-size is the same in both
places. */
- if (TREE_CODE (size) == SAVE_EXPR)
- SAVE_EXPR_PERSISTENT_P (size) = 1;
+ if (TREE_CODE (save) == SAVE_EXPR)
+ SAVE_EXPR_PERSISTENT_P (save) = 1;
if ((*lang_hooks.decls.global_bindings_p) ())
{
@@ -183,16 +188,13 @@ variable_size (size)
}
if (immediate_size_expand)
- /* NULL_RTX is not defined; neither is the rtx type.
- Also, we would like to pass const0_rtx here, but don't have it. */
- expand_expr (size, expand_expr (integer_zero_node, NULL_RTX, VOIDmode, 0),
- VOIDmode, 0);
+ expand_expr (save, const0_rtx, VOIDmode, 0);
else if (cfun != 0 && cfun->x_dont_save_pending_sizes_p)
/* The front-end doesn't want us to keep a list of the expressions
that determine sizes for variable size objects. */
;
else
- put_pending_size (size);
+ put_pending_size (save);
return size;
}
@@ -201,16 +203,13 @@ variable_size (size)
#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode)
#endif
-/* Return the machine mode to use for a nonscalar of SIZE bits.
- The mode must be in class CLASS, and have exactly that many bits.
- If LIMIT is nonzero, modes of wider than MAX_FIXED_MODE_SIZE will not
- be used. */
+/* Return the machine mode to use for a nonscalar of SIZE bits. The
+ mode must be in class CLASS, and have exactly that many value bits;
+ it may have padding as well. If LIMIT is nonzero, modes of wider
+ than MAX_FIXED_MODE_SIZE will not be used. */
enum machine_mode
-mode_for_size (size, class, limit)
- unsigned int size;
- enum mode_class class;
- int limit;
+mode_for_size (unsigned int size, enum mode_class class, int limit)
{
enum machine_mode mode;
@@ -220,7 +219,7 @@ mode_for_size (size, class, limit)
/* Get the first mode which has this size, in the specified class. */
for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
- if (GET_MODE_BITSIZE (mode) == size)
+ if (GET_MODE_PRECISION (mode) == size)
return mode;
return BLKmode;
@@ -229,28 +228,24 @@ mode_for_size (size, class, limit)
/* Similar, except passed a tree node. */
enum machine_mode
-mode_for_size_tree (size, class, limit)
- tree size;
- enum mode_class class;
- int limit;
+mode_for_size_tree (tree size, enum mode_class class, int limit)
{
if (TREE_CODE (size) != INTEGER_CST
+ || TREE_OVERFLOW (size)
/* What we really want to say here is that the size can fit in a
host integer, but we know there's no way we'd find a mode for
this many bits, so there's no point in doing the precise test. */
|| compare_tree_int (size, 1000) > 0)
return BLKmode;
else
- return mode_for_size (TREE_INT_CST_LOW (size), class, limit);
+ return mode_for_size (tree_low_cst (size, 1), class, limit);
}
/* Similar, but never return BLKmode; return the narrowest mode that
- contains at least the requested number of bits. */
+ contains at least the requested number of value bits. */
enum machine_mode
-smallest_mode_for_size (size, class)
- unsigned int size;
- enum mode_class class;
+smallest_mode_for_size (unsigned int size, enum mode_class class)
{
enum machine_mode mode;
@@ -258,7 +253,7 @@ smallest_mode_for_size (size, class)
specified class. */
for (mode = GET_CLASS_NARROWEST_MODE (class); mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
- if (GET_MODE_BITSIZE (mode) >= size)
+ if (GET_MODE_PRECISION (mode) >= size)
return mode;
abort ();
@@ -267,8 +262,7 @@ smallest_mode_for_size (size, class)
/* Find an integer mode of the exact same size, or BLKmode on failure. */
enum machine_mode
-int_mode_for_mode (mode)
- enum machine_mode mode;
+int_mode_for_mode (enum machine_mode mode)
{
switch (GET_MODE_CLASS (mode))
{
@@ -302,32 +296,16 @@ int_mode_for_mode (mode)
BIGGEST_ALIGNMENT. */
unsigned int
-get_mode_alignment (mode)
- enum machine_mode mode;
+get_mode_alignment (enum machine_mode mode)
{
- unsigned int alignment;
-
- if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
- || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
- alignment = GET_MODE_UNIT_SIZE (mode);
- else
- alignment = GET_MODE_SIZE (mode);
-
- /* Extract the LSB of the size. */
- alignment = alignment & -alignment;
- alignment *= BITS_PER_UNIT;
-
- alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment));
- return alignment;
+ return MIN (BIGGEST_ALIGNMENT, MAX (1, mode_base_align[mode]*BITS_PER_UNIT));
}
/* Return the value of VALUE, rounded up to a multiple of DIVISOR.
This can only be applied to objects of a sizetype. */
tree
-round_up (value, divisor)
- tree value;
- int divisor;
+round_up (tree value, int divisor)
{
tree arg = size_int_type (divisor, TREE_TYPE (value));
@@ -337,15 +315,27 @@ round_up (value, divisor)
/* Likewise, but round down. */
tree
-round_down (value, divisor)
- tree value;
- int divisor;
+round_down (tree value, int divisor)
{
tree arg = size_int_type (divisor, TREE_TYPE (value));
return size_binop (MULT_EXPR, size_binop (FLOOR_DIV_EXPR, value, arg), arg);
}
+/* Subroutine of layout_decl: Force alignment required for the data type.
+ But if the decl itself wants greater alignment, don't override that. */
+
+static inline void
+do_type_align (tree type, tree decl)
+{
+ if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
+ {
+ DECL_ALIGN (decl) = TYPE_ALIGN (type);
+ if (TREE_CODE (decl) == FIELD_DECL)
+ DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
+ }
+}
+
/* Set the size, mode and alignment of a ..._DECL node.
TYPE_DECL does need this for C++.
Note that LABEL_DECL and CONST_DECL nodes do not need this,
@@ -360,9 +350,7 @@ round_down (value, divisor)
the record will be aligned to suit. */
void
-layout_decl (decl, known_align)
- tree decl;
- unsigned int known_align;
+layout_decl (tree decl, unsigned int known_align)
{
tree type = TREE_TYPE (decl);
enum tree_code code = TREE_CODE (decl);
@@ -398,72 +386,112 @@ layout_decl (decl, known_align)
DECL_SIZE (decl) = TYPE_SIZE (type);
DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
}
- else
+ else if (DECL_SIZE_UNIT (decl) == 0)
DECL_SIZE_UNIT (decl)
= convert (sizetype, size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
bitsize_unit_node));
- /* Force alignment required for the data type.
- But if the decl itself wants greater alignment, don't override that.
- Likewise, if the decl is packed, don't override it. */
- if (! (code == FIELD_DECL && DECL_BIT_FIELD (decl))
- && (DECL_ALIGN (decl) == 0
- || (! (code == FIELD_DECL && DECL_PACKED (decl))
- && TYPE_ALIGN (type) > DECL_ALIGN (decl))))
+ if (code != FIELD_DECL)
+ /* For non-fields, update the alignment from the type. */
+ do_type_align (type, decl);
+ else
+ /* For fields, it's a bit more complicated... */
{
- DECL_ALIGN (decl) = TYPE_ALIGN (type);
- DECL_USER_ALIGN (decl) = 0;
- }
+ bool old_user_align = DECL_USER_ALIGN (decl);
- /* For fields, set the bit field type and update the alignment. */
- if (code == FIELD_DECL)
- {
- DECL_BIT_FIELD_TYPE (decl) = DECL_BIT_FIELD (decl) ? type : 0;
- if (maximum_field_alignment != 0)
- DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
+ if (DECL_BIT_FIELD (decl))
+ {
+ DECL_BIT_FIELD_TYPE (decl) = type;
+
+ /* A zero-length bit-field affects the alignment of the next
+ field. */
+ if (integer_zerop (DECL_SIZE (decl))
+ && ! DECL_PACKED (decl)
+ && ! (*targetm.ms_bitfield_layout_p) (DECL_FIELD_CONTEXT (decl)))
+ {
+#ifdef PCC_BITFIELD_TYPE_MATTERS
+ if (PCC_BITFIELD_TYPE_MATTERS)
+ do_type_align (type, decl);
+ else
+#endif
+ {
+#ifdef EMPTY_FIELD_BOUNDARY
+ if (EMPTY_FIELD_BOUNDARY > DECL_ALIGN (decl))
+ {
+ DECL_ALIGN (decl) = EMPTY_FIELD_BOUNDARY;
+ DECL_USER_ALIGN (decl) = 0;
+ }
+#endif
+ }
+ }
+
+ /* See if we can use an ordinary integer mode for a bit-field.
+ Conditions are: a fixed size that is correct for another mode
+ and occupying a complete byte or bytes on proper boundary. */
+ if (TYPE_SIZE (type) != 0
+ && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
+ && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
+ {
+ enum machine_mode xmode
+ = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
+
+ if (xmode != BLKmode
+ && (known_align == 0
+ || known_align >= GET_MODE_ALIGNMENT (xmode)))
+ {
+ DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
+ DECL_ALIGN (decl));
+ DECL_MODE (decl) = xmode;
+ DECL_BIT_FIELD (decl) = 0;
+ }
+ }
+
+ /* Turn off DECL_BIT_FIELD if we won't need it set. */
+ if (TYPE_MODE (type) == BLKmode && DECL_MODE (decl) == BLKmode
+ && known_align >= TYPE_ALIGN (type)
+ && DECL_ALIGN (decl) >= TYPE_ALIGN (type))
+ DECL_BIT_FIELD (decl) = 0;
+ }
+ else if (DECL_PACKED (decl) && DECL_USER_ALIGN (decl))
+ /* Don't touch DECL_ALIGN. For other packed fields, go ahead and
+ round up; we'll reduce it again below. We want packing to
+ supersede USER_ALIGN inherited from the type, but defer to
+ alignment explicitly specified on the field decl. */;
+ else
+ do_type_align (type, decl);
/* If the field is of variable size, we can't misalign it since we
have no way to make a temporary to align the result. But this
isn't an issue if the decl is not addressable. Likewise if it
- is of unknown size. */
- else if (DECL_PACKED (decl)
- && (DECL_NONADDRESSABLE_P (decl)
- || DECL_SIZE_UNIT (decl) == 0
- || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
- {
- DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
- DECL_USER_ALIGN (decl) = 0;
- }
- }
-
- /* See if we can use an ordinary integer mode for a bit-field.
- Conditions are: a fixed size that is correct for another mode
- and occupying a complete byte or bytes on proper boundary. */
- if (code == FIELD_DECL && DECL_BIT_FIELD (decl)
- && TYPE_SIZE (type) != 0
- && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
- && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
- {
- enum machine_mode xmode
- = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
-
- if (xmode != BLKmode && known_align >= GET_MODE_ALIGNMENT (xmode))
+ is of unknown size.
+
+ Note that do_type_align may set DECL_USER_ALIGN, so we need to
+ check old_user_align instead. */
+ if (DECL_PACKED (decl)
+ && !old_user_align
+ && (DECL_NONADDRESSABLE_P (decl)
+ || DECL_SIZE_UNIT (decl) == 0
+ || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
+ DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
+
+ /* Should this be controlled by DECL_USER_ALIGN, too? */
+ if (maximum_field_alignment != 0)
+ DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
+ if (! DECL_USER_ALIGN (decl))
{
- DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
- DECL_ALIGN (decl));
- DECL_MODE (decl) = xmode;
- DECL_BIT_FIELD (decl) = 0;
+ /* Some targets (i.e. i386, VMS) limit struct field alignment
+ to a lower boundary than alignment of variables unless
+ it was overridden by attribute aligned. */
+#ifdef BIGGEST_FIELD_ALIGNMENT
+ DECL_ALIGN (decl)
+ = MIN (DECL_ALIGN (decl), (unsigned) BIGGEST_FIELD_ALIGNMENT);
+#endif
+#ifdef ADJUST_FIELD_ALIGN
+ DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl));
+#endif
}
}
- /* Turn off DECL_BIT_FIELD if we won't need it set. */
- if (code == FIELD_DECL && DECL_BIT_FIELD (decl)
- && TYPE_MODE (type) == BLKmode && DECL_MODE (decl) == BLKmode
- && known_align >= TYPE_ALIGN (type)
- && DECL_ALIGN (decl) >= TYPE_ALIGN (type)
- && DECL_SIZE_UNIT (decl) != 0)
- DECL_BIT_FIELD (decl) = 0;
-
/* Evaluate nonconstant size only once, either now or as soon as safe. */
if (DECL_SIZE (decl) != 0 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
DECL_SIZE (decl) = variable_size (DECL_SIZE (decl));
@@ -481,13 +509,13 @@ layout_decl (decl, known_align)
if (size != 0 && TREE_CODE (size) == INTEGER_CST
&& compare_tree_int (size, larger_than_size) > 0)
{
- unsigned int size_as_int = TREE_INT_CST_LOW (size);
+ int size_as_int = TREE_INT_CST_LOW (size);
if (compare_tree_int (size, size_as_int) == 0)
- warning_with_decl (decl, "size of `%s' is %d bytes", size_as_int);
+ warning ("%Jsize of '%D' is %d bytes", decl, decl, size_as_int);
else
- warning_with_decl (decl, "size of `%s' is larger than %d bytes",
- larger_than_size);
+ warning ("%Jsize of '%D' is larger than %d bytes",
+ decl, decl, larger_than_size);
}
}
@@ -504,11 +532,10 @@ layout_decl (decl, known_align)
/* Hook for a front-end function that can modify the record layout as needed
immediately before it is finalized. */
-void (*lang_adjust_rli) PARAMS ((record_layout_info)) = 0;
+void (*lang_adjust_rli) (record_layout_info) = 0;
void
-set_lang_adjust_rli (f)
- void (*f) PARAMS ((record_layout_info));
+set_lang_adjust_rli (void (*f) (record_layout_info))
{
lang_adjust_rli = f;
}
@@ -521,11 +548,9 @@ set_lang_adjust_rli (f)
out the record. */
record_layout_info
-start_record_layout (t)
- tree t;
+start_record_layout (tree t)
{
- record_layout_info rli
- = (record_layout_info) xmalloc (sizeof (struct record_layout_info_s));
+ record_layout_info rli = xmalloc (sizeof (struct record_layout_info_s));
rli->t = t;
@@ -533,13 +558,13 @@ start_record_layout (t)
declaration, for example) use it -- otherwise, start with a
one-byte alignment. */
rli->record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (t));
- rli->unpacked_align = rli->unpadded_align = rli->record_align;
+ rli->unpacked_align = rli->record_align;
rli->offset_align = MAX (rli->record_align, BIGGEST_ALIGNMENT);
#ifdef STRUCTURE_SIZE_BOUNDARY
/* Packed structures don't need to have minimum size. */
if (! TYPE_PACKED (t))
- rli->record_align = MAX (rli->record_align, STRUCTURE_SIZE_BOUNDARY);
+ rli->record_align = MAX (rli->record_align, (unsigned) STRUCTURE_SIZE_BOUNDARY);
#endif
rli->offset = size_zero_node;
@@ -555,8 +580,7 @@ start_record_layout (t)
the offset/bitpos forms and byte and bit offsets. */
tree
-bit_from_pos (offset, bitpos)
- tree offset, bitpos;
+bit_from_pos (tree offset, tree bitpos)
{
return size_binop (PLUS_EXPR, bitpos,
size_binop (MULT_EXPR, convert (bitsizetype, offset),
@@ -564,8 +588,7 @@ bit_from_pos (offset, bitpos)
}
tree
-byte_from_pos (offset, bitpos)
- tree offset, bitpos;
+byte_from_pos (tree offset, tree bitpos)
{
return size_binop (PLUS_EXPR, offset,
convert (sizetype,
@@ -574,29 +597,8 @@ byte_from_pos (offset, bitpos)
}
void
-pos_from_byte (poffset, pbitpos, off_align, pos)
- tree *poffset, *pbitpos;
- unsigned int off_align;
- tree pos;
-{
- *poffset
- = size_binop (MULT_EXPR,
- convert (sizetype,
- size_binop (FLOOR_DIV_EXPR, pos,
- bitsize_int (off_align
- / BITS_PER_UNIT))),
- size_int (off_align / BITS_PER_UNIT));
- *pbitpos = size_binop (MULT_EXPR,
- size_binop (FLOOR_MOD_EXPR, pos,
- bitsize_int (off_align / BITS_PER_UNIT)),
- bitsize_unit_node);
-}
-
-void
-pos_from_bit (poffset, pbitpos, off_align, pos)
- tree *poffset, *pbitpos;
- unsigned int off_align;
- tree pos;
+pos_from_bit (tree *poffset, tree *pbitpos, unsigned int off_align,
+ tree pos)
{
*poffset = size_binop (MULT_EXPR,
convert (sizetype,
@@ -610,9 +612,7 @@ pos_from_bit (poffset, pbitpos, off_align, pos)
normalize the offsets so they are within the alignment. */
void
-normalize_offset (poffset, pbitpos, off_align)
- tree *poffset, *pbitpos;
- unsigned int off_align;
+normalize_offset (tree *poffset, tree *pbitpos, unsigned int off_align)
{
/* If the bit position is now larger than it should be, adjust it
downwards. */
@@ -634,15 +634,14 @@ normalize_offset (poffset, pbitpos, off_align)
/* Print debugging information about the information in RLI. */
void
-debug_rli (rli)
- record_layout_info rli;
+debug_rli (record_layout_info rli)
{
print_node_brief (stderr, "type", rli->t, 0);
print_node_brief (stderr, "\noffset", rli->offset, 0);
print_node_brief (stderr, " bitpos", rli->bitpos, 0);
- fprintf (stderr, "\naligns: rec = %u, unpack = %u, unpad = %u, off = %u\n",
- rli->record_align, rli->unpacked_align, rli->unpadded_align,
+ fprintf (stderr, "\naligns: rec = %u, unpack = %u, off = %u\n",
+ rli->record_align, rli->unpacked_align,
rli->offset_align);
if (rli->packed_maybe_necessary)
fprintf (stderr, "packed may be necessary\n");
@@ -658,8 +657,7 @@ debug_rli (rli)
BITPOS if necessary to keep BITPOS below OFFSET_ALIGN. */
void
-normalize_rli (rli)
- record_layout_info rli;
+normalize_rli (record_layout_info rli)
{
normalize_offset (&rli->offset, &rli->bitpos, rli->offset_align);
}
@@ -667,8 +665,7 @@ normalize_rli (rli)
/* Returns the size in bytes allocated so far. */
tree
-rli_size_unit_so_far (rli)
- record_layout_info rli;
+rli_size_unit_so_far (record_layout_info rli)
{
return byte_from_pos (rli->offset, rli->bitpos);
}
@@ -676,8 +673,7 @@ rli_size_unit_so_far (rli)
/* Returns the size in bits allocated so far. */
tree
-rli_size_so_far (rli)
- record_layout_info rli;
+rli_size_so_far (record_layout_info rli)
{
return bit_from_pos (rli->offset, rli->bitpos);
}
@@ -688,10 +684,8 @@ rli_size_so_far (rli)
the FIELD. */
static unsigned int
-update_alignment_for_field (rli, field, known_align)
- record_layout_info rli;
- tree field;
- unsigned int known_align;
+update_alignment_for_field (record_layout_info rli, tree field,
+ unsigned int known_align)
{
/* The alignment required for FIELD. */
unsigned int desired_align;
@@ -699,43 +693,21 @@ update_alignment_for_field (rli, field, known_align)
tree type = TREE_TYPE (field);
/* True if the field was explicitly aligned by the user. */
bool user_align;
+ bool is_bitfield;
- /* Lay out the field so we know what alignment it needs. For a
- packed field, use the alignment as specified, disregarding what
- the type would want. */
+ /* Lay out the field so we know what alignment it needs. */
+ layout_decl (field, known_align);
desired_align = DECL_ALIGN (field);
user_align = DECL_USER_ALIGN (field);
- layout_decl (field, known_align);
- if (! DECL_PACKED (field))
- {
- desired_align = DECL_ALIGN (field);
- user_align = DECL_USER_ALIGN (field);
- }
- else if (!DECL_BIT_FIELD_TYPE (field))
- /* Even packed non-bit-fields get byte alignment. */
- desired_align = MAX (desired_align, BITS_PER_UNIT);
-
- /* Some targets (i.e. i386, VMS) limit struct field alignment
- to a lower boundary than alignment of variables unless
- it was overridden by attribute aligned. */
-#ifdef BIGGEST_FIELD_ALIGNMENT
- if (!user_align)
- desired_align
- = MIN (desired_align, (unsigned) BIGGEST_FIELD_ALIGNMENT);
-#endif
-#ifdef ADJUST_FIELD_ALIGN
- if (!user_align)
- desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
-#endif
+ is_bitfield = (type != error_mark_node
+ && DECL_BIT_FIELD_TYPE (field)
+ && ! integer_zerop (TYPE_SIZE (type)));
/* Record must have at least as much alignment as any field.
Otherwise, the alignment of the field within the record is
meaningless. */
- if ((* targetm.ms_bitfield_layout_p) (rli->t)
- && type != error_mark_node
- && DECL_BIT_FIELD_TYPE (field)
- && ! integer_zerop (TYPE_SIZE (type)))
+ if (is_bitfield && (* targetm.ms_bitfield_layout_p) (rli->t))
{
/* Here, the alignment of the underlying type of a bitfield can
affect the alignment of a record; even a zero-sized field
@@ -744,10 +716,10 @@ update_alignment_for_field (rli, field, known_align)
applies if there was an immediately prior, nonzero-size
bitfield. (That's the way it is, experimentally.) */
if (! integer_zerop (DECL_SIZE (field))
- ? ! DECL_PACKED (field)
- : (rli->prev_field
- && DECL_BIT_FIELD_TYPE (rli->prev_field)
- && ! integer_zerop (DECL_SIZE (rli->prev_field))))
+ ? ! DECL_PACKED (field)
+ : (rli->prev_field
+ && DECL_BIT_FIELD_TYPE (rli->prev_field)
+ && ! integer_zerop (DECL_SIZE (rli->prev_field))))
{
unsigned int type_align = TYPE_ALIGN (type);
type_align = MAX (type_align, desired_align);
@@ -755,29 +727,13 @@ update_alignment_for_field (rli, field, known_align)
type_align = MIN (type_align, maximum_field_alignment);
rli->record_align = MAX (rli->record_align, type_align);
rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
- rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field));
}
- else
- desired_align = 1;
}
- else
#ifdef PCC_BITFIELD_TYPE_MATTERS
- if (PCC_BITFIELD_TYPE_MATTERS && type != error_mark_node
- && ! (* targetm.ms_bitfield_layout_p) (rli->t)
- && DECL_BIT_FIELD_TYPE (field)
- && ! integer_zerop (TYPE_SIZE (type)))
+ else if (is_bitfield && PCC_BITFIELD_TYPE_MATTERS)
{
- /* For these machines, a zero-length field does not
- affect the alignment of the structure as a whole.
- It does, however, affect the alignment of the next field
- within the structure. */
- if (! integer_zerop (DECL_SIZE (field)))
- rli->record_align = MAX (rli->record_align, desired_align);
- else if (! DECL_PACKED (field) && !user_align)
- desired_align = TYPE_ALIGN (type);
-
- /* A named bit field of declared type `int'
- forces the entire structure to have `int' alignment. */
+ /* Named bit-fields cause the entire structure to have the
+ alignment implied by their type. */
if (DECL_NAME (field) != 0)
{
unsigned int type_align = TYPE_ALIGN (type);
@@ -792,34 +748,35 @@ update_alignment_for_field (rli, field, known_align)
else if (DECL_PACKED (field))
type_align = MIN (type_align, BITS_PER_UNIT);
+ /* The alignment of the record is increased to the maximum
+ of the current alignment, the alignment indicated on the
+ field (i.e., the alignment specified by an __aligned__
+ attribute), and the alignment indicated by the type of
+ the field. */
+ rli->record_align = MAX (rli->record_align, desired_align);
rli->record_align = MAX (rli->record_align, type_align);
- rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field));
+
if (warn_packed)
rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
user_align |= TYPE_USER_ALIGN (type);
}
}
- else
#endif
+ else
{
rli->record_align = MAX (rli->record_align, desired_align);
rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
- rli->unpadded_align = MAX (rli->unpadded_align, DECL_ALIGN (field));
}
TYPE_USER_ALIGN (rli->t) |= user_align;
- DECL_ALIGN (field) = desired_align;
-
return desired_align;
}
/* Called from place_field to handle unions. */
static void
-place_union_field (rli, field)
- record_layout_info rli;
- tree field;
+place_union_field (record_layout_info rli, tree field)
{
update_alignment_for_field (rli, field, /*known_align=*/0);
@@ -837,15 +794,32 @@ place_union_field (rli, field)
DECL_SIZE_UNIT (field), rli->offset));
}
+#if defined (PCC_BITFIELD_TYPE_MATTERS) || defined (BITFIELD_NBYTES_LIMITED)
+/* A bitfield of SIZE with a required access alignment of ALIGN is allocated
+ at BYTE_OFFSET / BIT_OFFSET. Return nonzero if the field would span more
+ units of alignment than the underlying TYPE. */
+static int
+excess_unit_span (HOST_WIDE_INT byte_offset, HOST_WIDE_INT bit_offset,
+ HOST_WIDE_INT size, HOST_WIDE_INT align, tree type)
+{
+ /* Note that the calculation of OFFSET might overflow; we calculate it so
+ that we still get the right result as long as ALIGN is a power of two. */
+ unsigned HOST_WIDE_INT offset = byte_offset * BITS_PER_UNIT + bit_offset;
+
+ offset = offset % align;
+ return ((offset + size + align - 1) / align
+ > ((unsigned HOST_WIDE_INT) tree_low_cst (TYPE_SIZE (type), 1)
+ / align));
+}
+#endif
+
/* RLI contains information about the layout of a RECORD_TYPE. FIELD
is a FIELD_DECL to be added after those fields already present in
T. (FIELD is not actually added to the TYPE_FIELDS list here;
callers that desire that behavior must manually perform that step.) */
void
-place_field (rli, field)
- record_layout_info rli;
- tree field;
+place_field (record_layout_info rli, tree field)
{
/* The alignment required for FIELD. */
unsigned int desired_align;
@@ -896,19 +870,21 @@ place_field (rli, field)
& - tree_low_cst (rli->offset, 1)));
else
known_align = rli->offset_align;
-
+
desired_align = update_alignment_for_field (rli, field, known_align);
if (warn_packed && DECL_PACKED (field))
{
- if (known_align > TYPE_ALIGN (type))
+ if (known_align >= TYPE_ALIGN (type))
{
if (TYPE_ALIGN (type) > desired_align)
{
if (STRICT_ALIGNMENT)
- warning_with_decl (field, "packed attribute causes inefficient alignment for `%s'");
+ warning ("%Jpacked attribute causes inefficient alignment "
+ "for '%D'", field, field);
else
- warning_with_decl (field, "packed attribute is unnecessary for `%s'");
+ warning ("%Jpacked attribute is unnecessary for '%D'",
+ field, field);
}
}
else
@@ -923,7 +899,7 @@ place_field (rli, field)
Bump the cumulative size to multiple of field alignment. */
if (warn_padded)
- warning_with_decl (field, "padding struct to align `%s'");
+ warning ("%Jpadding struct to align '%D'", field, field);
/* If the alignment is still within offset_align, just align
the bit position. */
@@ -975,11 +951,7 @@ place_field (rli, field)
/* A bit field may not span more units of alignment of its type
than its type itself. Advance to next boundary if necessary. */
- if ((((offset * BITS_PER_UNIT + bit_offset + field_size +
- type_align - 1)
- / type_align)
- - (offset * BITS_PER_UNIT + bit_offset) / type_align)
- > tree_low_cst (TYPE_SIZE (type), 1) / type_align)
+ if (excess_unit_span (offset, bit_offset, field_size, type_align, type))
rli->bitpos = round_up (rli->bitpos, type_align);
TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
@@ -1018,11 +990,7 @@ place_field (rli, field)
/* A bit field may not span the unit of alignment of its type.
Advance to next boundary if necessary. */
- /* ??? This code should match the code above for the
- PCC_BITFIELD_TYPE_MATTERS case. */
- if ((offset * BITS_PER_UNIT + bit_offset) / type_align
- != ((offset * BITS_PER_UNIT + bit_offset + field_size - 1)
- / type_align))
+ if (excess_unit_span (offset, bit_offset, field_size, type_align, type))
rli->bitpos = round_up (rli->bitpos, type_align);
TYPE_USER_ALIGN (rli->t) |= TYPE_USER_ALIGN (type);
@@ -1033,19 +1001,19 @@ place_field (rli, field)
A subtlety:
When a bit field is inserted into a packed record, the whole
size of the underlying type is used by one or more same-size
- adjacent bitfields. (That is, if its long:3, 32 bits is
+ adjacent bitfields. (That is, if its long:3, 32 bits is
used in the record, and any additional adjacent long bitfields are
packed into the same chunk of 32 bits. However, if the size
changes, a new field of that size is allocated.) In an unpacked
- record, this is the same as using alignment, but not eqivalent
- when packing.
+ record, this is the same as using alignment, but not equivalent
+ when packing.
- Note: for compatability, we use the type size, not the type alignment
+ Note: for compatibility, we use the type size, not the type alignment
to determine alignment, since that matches the documentation */
if ((* targetm.ms_bitfield_layout_p) (rli->t)
&& ((DECL_BIT_FIELD_TYPE (field) && ! DECL_PACKED (field))
- || (rli->prev_field && ! DECL_PACKED (rli->prev_field))))
+ || (rli->prev_field && ! DECL_PACKED (rli->prev_field))))
{
/* At this point, either the prior or current are bitfields,
(possibly both), and we're dealing with MS packing. */
@@ -1064,31 +1032,34 @@ place_field (rli, field)
if (DECL_BIT_FIELD_TYPE (field)
&& !integer_zerop (DECL_SIZE (field))
&& !integer_zerop (DECL_SIZE (rli->prev_field))
+ && host_integerp (DECL_SIZE (rli->prev_field), 0)
+ && host_integerp (TYPE_SIZE (type), 0)
&& simple_cst_equal (TYPE_SIZE (type),
- TYPE_SIZE (TREE_TYPE (rli->prev_field))) )
+ TYPE_SIZE (TREE_TYPE (rli->prev_field))))
{
/* We're in the middle of a run of equal type size fields; make
sure we realign if we run out of bits. (Not decl size,
type size!) */
- int bitsize = TREE_INT_CST_LOW (DECL_SIZE (field));
- tree type_size = TYPE_SIZE(TREE_TYPE(rli->prev_field));
+ HOST_WIDE_INT bitsize = tree_low_cst (DECL_SIZE (field), 0);
if (rli->remaining_in_alignment < bitsize)
{
/* out of bits; bump up to next 'word'. */
rli->offset = DECL_FIELD_OFFSET (rli->prev_field);
- rli->bitpos = size_binop (PLUS_EXPR,
- type_size,
- DECL_FIELD_BIT_OFFSET(rli->prev_field));
+ rli->bitpos
+ = size_binop (PLUS_EXPR, TYPE_SIZE (type),
+ DECL_FIELD_BIT_OFFSET (rli->prev_field));
rli->prev_field = field;
- rli->remaining_in_alignment = TREE_INT_CST_LOW (type_size);
+ rli->remaining_in_alignment
+ = tree_low_cst (TYPE_SIZE (type), 0);
}
+
rli->remaining_in_alignment -= bitsize;
}
else
{
- /* End of a run: if leaving a run of bitfields of the same type
- size, we have to "use up" the rest of the bits of the type
+ /* End of a run: if leaving a run of bitfields of the same type
+ size, we have to "use up" the rest of the bits of the type
size.
Compute the new position as the sum of the size for the prior
@@ -1098,32 +1069,30 @@ place_field (rli, field)
if (!integer_zerop (DECL_SIZE (rli->prev_field)))
{
- tree type_size = TYPE_SIZE(TREE_TYPE(rli->prev_field));
- rli->bitpos = size_binop (PLUS_EXPR,
- type_size,
- DECL_FIELD_BIT_OFFSET(rli->prev_field));
+ tree type_size = TYPE_SIZE (TREE_TYPE (rli->prev_field));
+
+ rli->bitpos
+ = size_binop (PLUS_EXPR, type_size,
+ DECL_FIELD_BIT_OFFSET (rli->prev_field));
}
else
- {
- /* We "use up" size zero fields; the code below should behave
- as if the prior field was not a bitfield. */
- prev_saved = NULL;
- }
+ /* We "use up" size zero fields; the code below should behave
+ as if the prior field was not a bitfield. */
+ prev_saved = NULL;
- /* Cause a new bitfield to be captured, either this time (if
+ /* Cause a new bitfield to be captured, either this time (if
currently a bitfield) or next time we see one. */
if (!DECL_BIT_FIELD_TYPE(field)
|| integer_zerop (DECL_SIZE (field)))
- {
- rli->prev_field = NULL;
- }
+ rli->prev_field = NULL;
}
+
normalize_rli (rli);
}
/* If we're starting a new run of same size type bitfields
(or a run of non-bitfields), set up the "first of the run"
- fields.
+ fields.
That is, if the current field is not a bitfield, or if there
was a prior bitfield the type sizes differ, or if there wasn't
@@ -1134,26 +1103,28 @@ place_field (rli, field)
there wasn't. */
if (!DECL_BIT_FIELD_TYPE (field)
- || ( prev_saved != NULL
+ || ( prev_saved != NULL
? !simple_cst_equal (TYPE_SIZE (type),
- TYPE_SIZE (TREE_TYPE (prev_saved)))
- : !integer_zerop (DECL_SIZE (field)) ))
+ TYPE_SIZE (TREE_TYPE (prev_saved)))
+ : !integer_zerop (DECL_SIZE (field)) ))
{
- unsigned int type_align = 8; /* Never below 8 for compatability */
+ /* Never smaller than a byte for compatibility. */
+ unsigned int type_align = BITS_PER_UNIT;
- /* (When not a bitfield), we could be seeing a flex array (with
+ /* (When not a bitfield), we could be seeing a flex array (with
no DECL_SIZE). Since we won't be using remaining_in_alignment
- until we see a bitfield (and come by here again) we just skip
+ until we see a bitfield (and come by here again) we just skip
calculating it. */
-
- if (DECL_SIZE (field) != NULL)
- rli->remaining_in_alignment
- = TREE_INT_CST_LOW (TYPE_SIZE(TREE_TYPE(field)))
- - TREE_INT_CST_LOW (DECL_SIZE (field));
+ if (DECL_SIZE (field) != NULL
+ && host_integerp (TYPE_SIZE (TREE_TYPE (field)), 0)
+ && host_integerp (DECL_SIZE (field), 0))
+ rli->remaining_in_alignment
+ = tree_low_cst (TYPE_SIZE (TREE_TYPE(field)), 0)
+ - tree_low_cst (DECL_SIZE (field), 0);
/* Now align (conventionally) for the new type. */
if (!DECL_PACKED(field))
- type_align = MAX(TYPE_ALIGN (type), type_align);
+ type_align = MAX(TYPE_ALIGN (type), type_align);
if (prev_saved
&& DECL_BIT_FIELD_TYPE (prev_saved)
@@ -1168,6 +1139,7 @@ place_field (rli, field)
type_align = MIN (type_align, maximum_field_alignment);
rli->bitpos = round_up (rli->bitpos, type_align);
+
/* If we really aligned, don't allow subsequent bitfields
to undo that. */
rli->prev_field = NULL;
@@ -1222,7 +1194,7 @@ place_field (rli, field)
rli->offset
= size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field));
rli->bitpos = bitsize_zero_node;
- rli->offset_align = MIN (rli->offset_align, DECL_ALIGN (field));
+ rli->offset_align = MIN (rli->offset_align, desired_align);
}
else
{
@@ -1233,11 +1205,10 @@ place_field (rli, field)
/* Assuming that all the fields have been laid out, this function uses
RLI to compute the final TYPE_SIZE, TYPE_ALIGN, etc. for the type
- inidicated by RLI. */
+ indicated by RLI. */
static void
-finalize_record_size (rli)
- record_layout_info rli;
+finalize_record_size (record_layout_info rli)
{
tree unpadded_size, unpadded_size_unit;
@@ -1263,26 +1234,10 @@ finalize_record_size (rli)
unpadded_size_unit
= size_binop (PLUS_EXPR, unpadded_size_unit, size_one_node);
- /* Record the un-rounded size in the binfo node. But first we check
- the size of TYPE_BINFO to make sure that BINFO_SIZE is available. */
- if (TYPE_BINFO (rli->t) && TREE_VEC_LENGTH (TYPE_BINFO (rli->t)) > 6)
- {
- TYPE_BINFO_SIZE (rli->t) = unpadded_size;
- TYPE_BINFO_SIZE_UNIT (rli->t) = unpadded_size_unit;
- }
-
- /* Round the size up to be a multiple of the required alignment */
-#ifdef ROUND_TYPE_SIZE
- TYPE_SIZE (rli->t) = ROUND_TYPE_SIZE (rli->t, unpadded_size,
- TYPE_ALIGN (rli->t));
- TYPE_SIZE_UNIT (rli->t)
- = ROUND_TYPE_SIZE_UNIT (rli->t, unpadded_size_unit,
- TYPE_ALIGN (rli->t) / BITS_PER_UNIT);
-#else
+ /* Round the size up to be a multiple of the required alignment. */
TYPE_SIZE (rli->t) = round_up (unpadded_size, TYPE_ALIGN (rli->t));
TYPE_SIZE_UNIT (rli->t) = round_up (unpadded_size_unit,
TYPE_ALIGN (rli->t) / BITS_PER_UNIT);
-#endif
if (warn_padded && TREE_CONSTANT (unpadded_size)
&& simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0)
@@ -1301,13 +1256,7 @@ finalize_record_size (rli)
rli->unpacked_align = MAX (TYPE_ALIGN (rli->t), rli->unpacked_align);
#endif
-#ifdef ROUND_TYPE_SIZE
- unpacked_size = ROUND_TYPE_SIZE (rli->t, TYPE_SIZE (rli->t),
- rli->unpacked_align);
-#else
unpacked_size = round_up (TYPE_SIZE (rli->t), rli->unpacked_align);
-#endif
-
if (simple_cst_equal (unpacked_size, TYPE_SIZE (rli->t)))
{
TYPE_PACKED (rli->t) = 0;
@@ -1340,8 +1289,7 @@ finalize_record_size (rli)
/* Compute the TYPE_MODE for the TYPE (which is a RECORD_TYPE). */
void
-compute_record_mode (type)
- tree type;
+compute_record_mode (tree type)
{
tree field;
enum machine_mode mode = VOIDmode;
@@ -1360,30 +1308,19 @@ compute_record_mode (type)
BLKmode only because it isn't aligned. */
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{
- unsigned HOST_WIDE_INT bitpos;
-
if (TREE_CODE (field) != FIELD_DECL)
continue;
if (TREE_CODE (TREE_TYPE (field)) == ERROR_MARK
|| (TYPE_MODE (TREE_TYPE (field)) == BLKmode
- && ! TYPE_NO_FORCE_BLK (TREE_TYPE (field)))
+ && ! TYPE_NO_FORCE_BLK (TREE_TYPE (field))
+ && !(TYPE_SIZE (TREE_TYPE (field)) != 0
+ && integer_zerop (TYPE_SIZE (TREE_TYPE (field)))))
|| ! host_integerp (bit_position (field), 1)
|| DECL_SIZE (field) == 0
|| ! host_integerp (DECL_SIZE (field), 1))
return;
- bitpos = int_bit_position (field);
-
- /* Must be BLKmode if any field crosses a word boundary,
- since extract_bit_field can't handle that in registers. */
- if (bitpos / BITS_PER_WORD
- != ((tree_low_cst (DECL_SIZE (field), 1) + bitpos - 1)
- / BITS_PER_WORD)
- /* But there is no problem if the field is entire words. */
- && tree_low_cst (DECL_SIZE (field), 1) % BITS_PER_WORD != 0)
- return;
-
/* If this field is the whole struct, remember its mode so
that, say, we can put a double in a class into a DF
register instead of forcing it to live in the stack. */
@@ -1424,8 +1361,7 @@ compute_record_mode (type)
out. */
static void
-finalize_type_size (type)
- tree type;
+finalize_type_size (tree type)
{
/* Normally, use the alignment corresponding to the mode chosen.
However, where strict alignment is not required, avoid
@@ -1461,17 +1397,9 @@ finalize_type_size (type)
if (TYPE_SIZE (type) != 0)
{
-#ifdef ROUND_TYPE_SIZE
- TYPE_SIZE (type)
- = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));
- TYPE_SIZE_UNIT (type)
- = ROUND_TYPE_SIZE_UNIT (type, TYPE_SIZE_UNIT (type),
- TYPE_ALIGN (type) / BITS_PER_UNIT);
-#else
TYPE_SIZE (type) = round_up (TYPE_SIZE (type), TYPE_ALIGN (type));
TYPE_SIZE_UNIT (type)
= round_up (TYPE_SIZE_UNIT (type), TYPE_ALIGN (type) / BITS_PER_UNIT);
-#endif
}
/* Evaluate nonconstant sizes only once, either now or as soon as safe. */
@@ -1514,9 +1442,7 @@ finalize_type_size (type)
G++ 3.2 ABI. */
void
-finish_record_layout (rli, free_p)
- record_layout_info rli;
- int free_p;
+finish_record_layout (record_layout_info rli, int free_p)
{
/* Compute the final size. */
finalize_record_size (rli);
@@ -1540,6 +1466,43 @@ finish_record_layout (rli, free_p)
free (rli);
}
+
+/* Finish processing a builtin RECORD_TYPE type TYPE. It's name is
+ NAME, its fields are chained in reverse on FIELDS.
+
+ If ALIGN_TYPE is non-null, it is given the same alignment as
+ ALIGN_TYPE. */
+
+void
+finish_builtin_struct (tree type, const char *name, tree fields,
+ tree align_type)
+{
+ tree tail, next;
+
+ for (tail = NULL_TREE; fields; tail = fields, fields = next)
+ {
+ DECL_FIELD_CONTEXT (fields) = type;
+ next = TREE_CHAIN (fields);
+ TREE_CHAIN (fields) = tail;
+ }
+ TYPE_FIELDS (type) = tail;
+
+ if (align_type)
+ {
+ TYPE_ALIGN (type) = TYPE_ALIGN (align_type);
+ TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (align_type);
+ }
+
+ layout_type (type);
+#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);
+#endif
+ TYPE_STUB_DECL (type) = TYPE_NAME (type);
+ layout_decl (TYPE_NAME (type), 0);
+}
+
/* Calculate the mode, size, and alignment for TYPE.
For an array type, calculate the element separation as well.
Record TYPE on the chain of permanent or temporary types
@@ -1551,8 +1514,7 @@ finish_record_layout (rli, free_p)
If the type is incomplete, its TYPE_SIZE remains zero. */
void
-layout_type (type)
- tree type;
+layout_type (tree type)
{
if (type == 0)
abort ();
@@ -1640,13 +1602,15 @@ layout_type (type)
case POINTER_TYPE:
case REFERENCE_TYPE:
{
- int nbits = ((TREE_CODE (type) == REFERENCE_TYPE
- && reference_types_internal)
- ? GET_MODE_BITSIZE (Pmode) : POINTER_SIZE);
- TYPE_MODE (type) = nbits == POINTER_SIZE ? ptr_mode : Pmode;
+ enum machine_mode mode = ((TREE_CODE (type) == REFERENCE_TYPE
+ && reference_types_internal)
+ ? Pmode : TYPE_MODE (type));
+
+ int nbits = GET_MODE_BITSIZE (mode);
+
TYPE_SIZE (type) = bitsize_int (nbits);
- TYPE_SIZE_UNIT (type) = size_int (nbits / BITS_PER_UNIT);
+ TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
TREE_UNSIGNED (type) = 1;
TYPE_PRECISION (type) = nbits;
}
@@ -1693,6 +1657,15 @@ layout_type (type)
element_size = integer_one_node;
}
+ /* If neither bound is a constant and sizetype is signed, make
+ sure the size is never negative. We should really do this
+ if *either* bound is non-constant, but this is the best
+ compromise between C and Ada. */
+ if (! TREE_UNSIGNED (sizetype)
+ && TREE_CODE (TYPE_MIN_VALUE (index)) != INTEGER_CST
+ && TREE_CODE (TYPE_MAX_VALUE (index)) != INTEGER_CST)
+ length = size_binop (MAX_EXPR, length, size_zero_node);
+
TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size,
convert (bitsizetype, length));
@@ -1719,22 +1692,6 @@ layout_type (type)
TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT);
#endif
TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element);
-
-#ifdef ROUND_TYPE_SIZE
- if (TYPE_SIZE (type) != 0)
- {
- tree tmp
- = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));
-
- /* If the rounding changed the size of the type, remove any
- pre-calculated TYPE_SIZE_UNIT. */
- if (simple_cst_equal (TYPE_SIZE (type), tmp) != 1)
- TYPE_SIZE_UNIT (type) = NULL;
-
- TYPE_SIZE (type) = tmp;
- }
-#endif
-
TYPE_MODE (type) = BLKmode;
if (TYPE_SIZE (type) != 0
#ifdef MEMBER_TYPE_FORCES_BLK
@@ -1807,10 +1764,10 @@ layout_type (type)
#endif
unsigned int alignment
= set_alignment ? set_alignment : SET_WORD_SIZE;
- int size_in_bits
- = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
- - TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) + 1);
- int rounded_size
+ HOST_WIDE_INT size_in_bits
+ = (tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)
+ - tree_low_cst (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), 0) + 1);
+ HOST_WIDE_INT rounded_size
= ((size_in_bits + alignment - 1) / alignment) * alignment;
if (rounded_size > (int) alignment)
@@ -1863,8 +1820,7 @@ layout_type (type)
/* Create and return a type for signed integers of PRECISION bits. */
tree
-make_signed_type (precision)
- int precision;
+make_signed_type (int precision)
{
tree type = make_node (INTEGER_TYPE);
@@ -1877,8 +1833,7 @@ make_signed_type (precision)
/* Create and return a type for unsigned integers of PRECISION bits. */
tree
-make_unsigned_type (precision)
- int precision;
+make_unsigned_type (int precision)
{
tree type = make_node (INTEGER_TYPE);
@@ -1892,7 +1847,7 @@ make_unsigned_type (precision)
value to enable integer types to be created. */
void
-initialize_sizetypes ()
+initialize_sizetypes (void)
{
tree t = make_node (INTEGER_TYPE);
@@ -1925,8 +1880,7 @@ initialize_sizetypes ()
Also update the type of any standard type's sizes made so far. */
void
-set_sizetype (type)
- tree type;
+set_sizetype (tree type)
{
int oprecision = TYPE_PRECISION (type);
/* The *bitsizetype types use a precision that avoids overflows when
@@ -1988,7 +1942,8 @@ set_sizetype (type)
for the sizes in them. */
for (t = early_type_list; t != 0; t = TREE_CHAIN (t))
{
- if (TREE_CODE (TREE_VALUE (t)) != INTEGER_TYPE)
+ if (TREE_CODE (TREE_VALUE (t)) != INTEGER_TYPE
+ && TREE_CODE (TREE_VALUE (t)) != BOOLEAN_TYPE)
abort ();
TREE_TYPE (TYPE_SIZE (TREE_VALUE (t))) = bitsizetype;
@@ -1999,14 +1954,65 @@ set_sizetype (type)
sizetype_set = 1;
}
+/* TYPE is an integral type, i.e., an INTEGRAL_TYPE, ENUMERAL_TYPE,
+ BOOLEAN_TYPE, or CHAR_TYPE. Set TYPE_MIN_VALUE and TYPE_MAX_VALUE
+ for TYPE, based on the PRECISION and whether or not the TYPE
+ IS_UNSIGNED. PRECISION need not correspond to a width supported
+ natively by the hardware; for example, on a machine with 8-bit,
+ 16-bit, and 32-bit register modes, PRECISION might be 7, 23, or
+ 61. */
+
+void
+set_min_and_max_values_for_integral_type (tree type,
+ int precision,
+ bool is_unsigned)
+{
+ tree min_value;
+ tree max_value;
+
+ if (is_unsigned)
+ {
+ min_value = build_int_2 (0, 0);
+ max_value
+ = build_int_2 (precision - HOST_BITS_PER_WIDE_INT >= 0
+ ? -1 : ((HOST_WIDE_INT) 1 << precision) - 1,
+ precision - HOST_BITS_PER_WIDE_INT > 0
+ ? ((unsigned HOST_WIDE_INT) ~0
+ >> (HOST_BITS_PER_WIDE_INT
+ - (precision - HOST_BITS_PER_WIDE_INT)))
+ : 0);
+ }
+ else
+ {
+ min_value
+ = build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
+ ? 0 : (HOST_WIDE_INT) (-1) << (precision - 1)),
+ (((HOST_WIDE_INT) (-1)
+ << (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
+ ? precision - HOST_BITS_PER_WIDE_INT - 1
+ : 0))));
+ max_value
+ = build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
+ ? -1 : ((HOST_WIDE_INT) 1 << (precision - 1)) - 1),
+ (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
+ ? (((HOST_WIDE_INT) 1
+ << (precision - HOST_BITS_PER_WIDE_INT - 1))) - 1
+ : 0));
+ }
+
+ TREE_TYPE (min_value) = type;
+ TREE_TYPE (max_value) = type;
+ TYPE_MIN_VALUE (type) = min_value;
+ TYPE_MAX_VALUE (type) = max_value;
+}
+
/* Set the extreme values of TYPE based on its precision in bits,
then lay it out. Used when make_signed_type won't do
because the tree code is not INTEGER_TYPE.
E.g. for Pascal, when the -fsigned-char option is given. */
void
-fixup_signed_type (type)
- tree type;
+fixup_signed_type (tree type)
{
int precision = TYPE_PRECISION (type);
@@ -2016,23 +2022,8 @@ fixup_signed_type (type)
if (precision > HOST_BITS_PER_WIDE_INT * 2)
precision = HOST_BITS_PER_WIDE_INT * 2;
- TYPE_MIN_VALUE (type)
- = build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
- ? 0 : (HOST_WIDE_INT) (-1) << (precision - 1)),
- (((HOST_WIDE_INT) (-1)
- << (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
- ? precision - HOST_BITS_PER_WIDE_INT - 1
- : 0))));
- TYPE_MAX_VALUE (type)
- = build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0
- ? -1 : ((HOST_WIDE_INT) 1 << (precision - 1)) - 1),
- (precision - HOST_BITS_PER_WIDE_INT - 1 > 0
- ? (((HOST_WIDE_INT) 1
- << (precision - HOST_BITS_PER_WIDE_INT - 1))) - 1
- : 0));
-
- TREE_TYPE (TYPE_MIN_VALUE (type)) = type;
- TREE_TYPE (TYPE_MAX_VALUE (type)) = type;
+ set_min_and_max_values_for_integral_type (type, precision,
+ /*is_unsigned=*/false);
/* Lay out the type: set its alignment, size, etc. */
layout_type (type);
@@ -2043,8 +2034,7 @@ fixup_signed_type (type)
and for enumeral types. */
void
-fixup_unsigned_type (type)
- tree type;
+fixup_unsigned_type (tree type)
{
int precision = TYPE_PRECISION (type);
@@ -2054,17 +2044,8 @@ fixup_unsigned_type (type)
if (precision > HOST_BITS_PER_WIDE_INT * 2)
precision = HOST_BITS_PER_WIDE_INT * 2;
- TYPE_MIN_VALUE (type) = build_int_2 (0, 0);
- TYPE_MAX_VALUE (type)
- = build_int_2 (precision - HOST_BITS_PER_WIDE_INT >= 0
- ? -1 : ((HOST_WIDE_INT) 1 << precision) - 1,
- precision - HOST_BITS_PER_WIDE_INT > 0
- ? ((unsigned HOST_WIDE_INT) ~0
- >> (HOST_BITS_PER_WIDE_INT
- - (precision - HOST_BITS_PER_WIDE_INT)))
- : 0);
- TREE_TYPE (TYPE_MIN_VALUE (type)) = type;
- TREE_TYPE (TYPE_MAX_VALUE (type)) = type;
+ set_min_and_max_values_for_integral_type (type, precision,
+ /*is_unsigned=*/true);
/* Lay out the type: set its alignment, size, etc. */
layout_type (type);
@@ -2086,11 +2067,8 @@ fixup_unsigned_type (type)
all the conditions. */
enum machine_mode
-get_best_mode (bitsize, bitpos, align, largest_mode, volatilep)
- int bitsize, bitpos;
- unsigned int align;
- enum machine_mode largest_mode;
- int volatilep;
+get_best_mode (int bitsize, int bitpos, unsigned int align,
+ enum machine_mode largest_mode, int volatilep)
{
enum machine_mode mode;
unsigned int unit = 0;
diff --git a/contrib/gcc/stringpool.c b/contrib/gcc/stringpool.c
index 639048625d96..0cf3be14f880 100644
--- a/contrib/gcc/stringpool.c
+++ b/contrib/gcc/stringpool.c
@@ -1,5 +1,5 @@
/* String pool for GCC.
- Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -29,9 +29,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "ggc.h"
#include "tree.h"
#include "hashtable.h"
+#include "cpplib.h"
/* The "" allocated string. */
const char empty_string[] = "";
@@ -46,25 +49,23 @@ const char digit_vector[] = {
struct ht *ident_hash;
static struct obstack string_stack;
-static hashnode alloc_node PARAMS ((hash_table *));
-static int mark_ident PARAMS ((struct cpp_reader *, hashnode, const PTR));
-static void mark_ident_hash PARAMS ((void *));
+static hashnode alloc_node (hash_table *);
+static int mark_ident (struct cpp_reader *, hashnode, const void *);
+static int ht_copy_and_clear (struct cpp_reader *, hashnode, const void *);
/* Initialize the string pool. */
void
-init_stringpool ()
+init_stringpool (void)
{
/* Create with 16K (2^14) entries. */
ident_hash = ht_create (14);
ident_hash->alloc_node = alloc_node;
gcc_obstack_init (&string_stack);
- ggc_add_root (&ident_hash, 1, sizeof ident_hash, mark_ident_hash);
}
/* Allocate a hash node. */
static hashnode
-alloc_node (table)
- hash_table *table ATTRIBUTE_UNUSED;
+alloc_node (hash_table *table ATTRIBUTE_UNUSED)
{
return GCC_IDENT_TO_HT_IDENT (make_node (IDENTIFIER_NODE));
}
@@ -76,9 +77,7 @@ alloc_node (table)
returned this time too. */
const char *
-ggc_alloc_string (contents, length)
- const char *contents;
- int length;
+ggc_alloc_string (const char *contents, int length)
{
if (length == -1)
length = strlen (contents);
@@ -96,9 +95,10 @@ ggc_alloc_string (contents, length)
If an identifier with that name has previously been referred to,
the same node is returned this time. */
+#undef get_identifier
+
tree
-get_identifier (text)
- const char *text;
+get_identifier (const char *text)
{
hashnode ht_node = ht_lookup (ident_hash,
(const unsigned char *) text,
@@ -112,9 +112,7 @@ get_identifier (text)
known. */
tree
-get_identifier_with_length (text, length)
- const char *text;
- unsigned int length;
+get_identifier_with_length (const char *text, size_t length)
{
hashnode ht_node = ht_lookup (ident_hash,
(const unsigned char *) text,
@@ -129,8 +127,7 @@ get_identifier_with_length (text, length)
NULL_TREE. */
tree
-maybe_get_identifier (text)
- const char *text;
+maybe_get_identifier (const char *text)
{
hashnode ht_node;
@@ -145,7 +142,7 @@ maybe_get_identifier (text)
/* Report some basic statistics about the string pool. */
void
-stringpool_statistics ()
+stringpool_statistics (void)
{
ht_dump_statistics (ident_hash);
}
@@ -153,20 +150,129 @@ stringpool_statistics ()
/* Mark an identifier for GC. */
static int
-mark_ident (pfile, h, v)
- struct cpp_reader *pfile ATTRIBUTE_UNUSED;
- hashnode h;
- const PTR v ATTRIBUTE_UNUSED;
+mark_ident (struct cpp_reader *pfile ATTRIBUTE_UNUSED, hashnode h,
+ const void *v ATTRIBUTE_UNUSED)
{
- ggc_mark_tree (HT_IDENT_TO_GCC_IDENT (h));
+ gt_ggc_m_9tree_node (HT_IDENT_TO_GCC_IDENT (h));
return 1;
}
-/* Mark all identifiers for GC. */
+/* Mark the trees hanging off the identifier node for GGC. These are
+ handled specially (not using gengtype) because of the special
+ treatment for strings. */
-static void
-mark_ident_hash (arg)
- PTR arg ATTRIBUTE_UNUSED;
+void
+ggc_mark_stringpool (void)
{
ht_forall (ident_hash, mark_ident, NULL);
}
+
+/* Strings are _not_ GCed, but this routine exists so that a separate
+ roots table isn't needed for the few global variables that refer
+ to strings. */
+
+void
+gt_ggc_m_S (void *x ATTRIBUTE_UNUSED)
+{
+}
+
+/* Pointer-walking routine for strings (not very interesting, since
+ strings don't contain pointers). */
+
+void
+gt_pch_p_S (void *obj ATTRIBUTE_UNUSED, void *x ATTRIBUTE_UNUSED,
+ gt_pointer_operator op ATTRIBUTE_UNUSED,
+ void *cookie ATTRIBUTE_UNUSED)
+{
+}
+
+/* PCH pointer-walking routine for strings. */
+
+void
+gt_pch_n_S (const void *x)
+{
+ gt_pch_note_object ((void *)x, (void *)x, &gt_pch_p_S);
+}
+
+/* Handle saving and restoring the string pool for PCH. */
+
+struct string_pool_data GTY(())
+{
+ tree * GTY((length ("%h.nslots"))) entries;
+ unsigned int nslots;
+ unsigned int nelements;
+};
+
+static GTY(()) struct string_pool_data * spd;
+
+static int
+ht_copy_and_clear (cpp_reader *r ATTRIBUTE_UNUSED, hashnode hp, const void *ht2_p)
+{
+ cpp_hashnode *h = CPP_HASHNODE (hp);
+ struct ht *ht2 = (struct ht *) ht2_p;
+
+ if (h->type != NT_VOID
+ && (h->flags & NODE_BUILTIN) == 0)
+ {
+ cpp_hashnode *h2 = CPP_HASHNODE (ht_lookup (ht2,
+ NODE_NAME (h),
+ NODE_LEN (h),
+ HT_ALLOC));
+ h2->type = h->type;
+ memcpy (&h2->value, &h->value, sizeof (h->value));
+
+ h->type = NT_VOID;
+ memset (&h->value, 0, sizeof (h->value));
+ }
+ return 1;
+}
+
+static struct ht *saved_ident_hash;
+
+void
+gt_pch_save_stringpool (void)
+{
+ unsigned int i;
+
+ spd = ggc_alloc (sizeof (*spd));
+ spd->nslots = ident_hash->nslots;
+ spd->nelements = ident_hash->nelements;
+ spd->entries = ggc_alloc (sizeof (tree *) * spd->nslots);
+ for (i = 0; i < spd->nslots; i++)
+ if (ident_hash->entries[i] != NULL)
+ spd->entries[i] = HT_IDENT_TO_GCC_IDENT (ident_hash->entries[i]);
+ else
+ spd->entries[i] = NULL;
+
+ saved_ident_hash = ht_create (14);
+ saved_ident_hash->alloc_node = alloc_node;
+ ht_forall (ident_hash, ht_copy_and_clear, saved_ident_hash);
+}
+
+void
+gt_pch_fixup_stringpool (void)
+{
+ ht_forall (saved_ident_hash, ht_copy_and_clear, ident_hash);
+ ht_destroy (saved_ident_hash);
+ saved_ident_hash = 0;
+}
+
+void
+gt_pch_restore_stringpool (void)
+{
+ unsigned int i;
+
+ ident_hash->nslots = spd->nslots;
+ ident_hash->nelements = spd->nelements;
+ ident_hash->entries = xrealloc (ident_hash->entries,
+ sizeof (hashnode) * spd->nslots);
+ for (i = 0; i < spd->nslots; i++)
+ if (spd->entries[i] != NULL)
+ ident_hash->entries[i] = GCC_IDENT_TO_HT_IDENT (spd->entries[i]);
+ else
+ ident_hash->entries[i] = NULL;
+
+ spd = NULL;
+}
+
+#include "gt-stringpool.h"
diff --git a/contrib/gcc/stub-objc.c b/contrib/gcc/stub-objc.c
new file mode 100644
index 000000000000..4e7a1987a390
--- /dev/null
+++ b/contrib/gcc/stub-objc.c
@@ -0,0 +1,71 @@
+/* Stub functions for Objective-C and Objective-C++ routines
+ that are called from within the C and C++ front-ends,
+ respectively.
+ Copyright (C) 1991, 1995, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "c-common.h"
+
+tree
+lookup_interface (tree arg ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+tree
+is_class_name (tree arg ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+tree
+objc_is_object_ptr (tree arg ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+tree
+lookup_objc_ivar (tree arg ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+void
+objc_check_decl (tree decl ATTRIBUTE_UNUSED)
+{
+}
+
+int
+objc_comptypes (tree lhs ATTRIBUTE_UNUSED, tree rhs ATTRIBUTE_UNUSED,
+ int reflexive ATTRIBUTE_UNUSED)
+{
+ return -1;
+}
+
+tree
+objc_message_selector (void)
+{
+ return 0;
+}
+
diff --git a/contrib/gcc/system.h b/contrib/gcc/system.h
index c9598ab0580a..e19de3f8e4e1 100644
--- a/contrib/gcc/system.h
+++ b/contrib/gcc/system.h
@@ -1,6 +1,7 @@
/* Get common system includes and various definitions and declarations based
on autoconf macros.
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -23,12 +24,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_SYSTEM_H
#define GCC_SYSTEM_H
-/* We must include stdarg.h/varargs.h before stdio.h. */
-#ifdef ANSI_PROTOTYPES
+/* We must include stdarg.h before stdio.h. */
#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
#ifndef va_copy
# ifdef __va_copy
@@ -57,7 +54,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
HAVE_DECL_PUTC_UNLOCKED actually indicates whether or not the stdio
code is multi-thread safe by default. If it is set to 0, then do
not worry about using the _unlocked functions.
-
+
fputs_unlocked, fwrite_unlocked, and fprintf_unlocked are
extensions and need to be prototyped by hand (since we do not
define _GNU_SOURCE). */
@@ -77,14 +74,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
# undef fputs
# define fputs(String, Stream) fputs_unlocked (String, Stream)
# if defined (HAVE_DECL_FPUTS_UNLOCKED) && !HAVE_DECL_FPUTS_UNLOCKED
-extern int fputs_unlocked PARAMS ((const char *, FILE *));
+extern int fputs_unlocked (const char *, FILE *);
# endif
# endif
# ifdef HAVE_FWRITE_UNLOCKED
# undef fwrite
# define fwrite(Ptr, Size, N, Stream) fwrite_unlocked (Ptr, Size, N, Stream)
# if defined (HAVE_DECL_FWRITE_UNLOCKED) && !HAVE_DECL_FWRITE_UNLOCKED
-extern int fwrite_unlocked PARAMS ((const PTR, size_t, size_t, FILE *));
+extern int fwrite_unlocked (const void *, size_t, size_t, FILE *);
# endif
# endif
# ifdef HAVE_FPRINTF_UNLOCKED
@@ -93,12 +90,17 @@ extern int fwrite_unlocked PARAMS ((const PTR, size_t, size_t, FILE *));
we have varargs macros. */
# define fprintf fprintf_unlocked
# if defined (HAVE_DECL_FPRINTF_UNLOCKED) && !HAVE_DECL_FPRINTF_UNLOCKED
-extern int fprintf_unlocked PARAMS ((FILE *, const char *, ...));
+extern int fprintf_unlocked (FILE *, const char *, ...);
# endif
# endif
#endif
+/* ??? Glibc's fwrite/fread_unlocked macros cause
+ "warning: signed and unsigned type in conditional expression". */
+#undef fread_unlocked
+#undef fwrite_unlocked
+
/* There are an extraordinary number of issues with <ctype.h>.
The last straw is that it varies with the locale. Use libiberty's
replacement instead. */
@@ -112,6 +114,10 @@ extern int fprintf_unlocked PARAMS ((FILE *, const char *, ...));
extern int errno;
#endif
+/* Some of glibc's string inlines cause warnings. Plus we'd rather
+ rely on (and therefore test) GCC's string builtins. */
+#define __NO_STRING_INLINES
+
#ifdef STRING_WITH_STRINGS
# include <string.h>
# include <strings.h>
@@ -274,39 +280,39 @@ extern int errno;
is running so be careful to test "defined (HAVE_DECL_*)". */
#if defined (HAVE_DECL_ATOF) && !HAVE_DECL_ATOF
-extern double atof PARAMS ((const char *));
+extern double atof (const char *);
#endif
#if defined (HAVE_DECL_ATOL) && !HAVE_DECL_ATOL
-extern long atol PARAMS ((const char *));
+extern long atol (const char *);
#endif
#if defined (HAVE_DECL_FREE) && !HAVE_DECL_FREE
-extern void free PARAMS ((PTR));
+extern void free (void *);
#endif
#if defined (HAVE_DECL_GETCWD) && !HAVE_DECL_GETCWD
-extern char *getcwd PARAMS ((char *, size_t));
+extern char *getcwd (char *, size_t);
#endif
#if defined (HAVE_DECL_GETENV) && !HAVE_DECL_GETENV
-extern char *getenv PARAMS ((const char *));
+extern char *getenv (const char *);
#endif
#if defined (HAVE_DECL_GETOPT) && !HAVE_DECL_GETOPT
-extern int getopt PARAMS ((int, char * const *, const char *));
+extern int getopt (int, char * const *, const char *);
#endif
#if defined (HAVE_DECL_GETWD) && !HAVE_DECL_GETWD
-extern char *getwd PARAMS ((char *));
+extern char *getwd (char *);
#endif
#if defined (HAVE_DECL_SBRK) && !HAVE_DECL_SBRK
-extern PTR sbrk PARAMS ((int));
+extern void *sbrk (int);
#endif
#if defined (HAVE_DECL_STRSTR) && !HAVE_DECL_STRSTR
-extern char *strstr PARAMS ((const char *, const char *));
+extern char *strstr (const char *, const char *);
#endif
#ifdef HAVE_MALLOC_H
@@ -314,32 +320,31 @@ extern char *strstr PARAMS ((const char *, const char *));
#endif
#if defined (HAVE_DECL_MALLOC) && !HAVE_DECL_MALLOC
-extern PTR malloc PARAMS ((size_t));
+extern void *malloc (size_t);
#endif
#if defined (HAVE_DECL_CALLOC) && !HAVE_DECL_CALLOC
-extern PTR calloc PARAMS ((size_t, size_t));
+extern void *calloc (size_t, size_t);
#endif
#if defined (HAVE_DECL_REALLOC) && !HAVE_DECL_REALLOC
-extern PTR realloc PARAMS ((PTR, size_t));
+extern void *realloc (void *, size_t);
#endif
/* If the system doesn't provide strsignal, we get it defined in
libiberty but no declaration is supplied. */
-#ifndef HAVE_STRSIGNAL
+#if !defined (HAVE_STRSIGNAL) \
+ || (defined (HAVE_DECL_STRSIGNAL) && !HAVE_DECL_STRSIGNAL)
# ifndef strsignal
-extern const char *strsignal PARAMS ((int));
+extern const char *strsignal (int);
# endif
#endif
#ifdef HAVE_GETRLIMIT
# if defined (HAVE_DECL_GETRLIMIT) && !HAVE_DECL_GETRLIMIT
# ifndef getrlimit
-# ifdef ANSI_PROTOTYPES
struct rlimit;
-# endif
-extern int getrlimit PARAMS ((int, struct rlimit *));
+extern int getrlimit (int, struct rlimit *);
# endif
# endif
#endif
@@ -347,22 +352,18 @@ extern int getrlimit PARAMS ((int, struct rlimit *));
#ifdef HAVE_SETRLIMIT
# if defined (HAVE_DECL_SETRLIMIT) && !HAVE_DECL_SETRLIMIT
# ifndef setrlimit
-# ifdef ANSI_PROTOTYPES
struct rlimit;
-# endif
-extern int setrlimit PARAMS ((int, const struct rlimit *));
+extern int setrlimit (int, const struct rlimit *);
# endif
# endif
#endif
-/* HAVE_VOLATILE only refers to the stage1 compiler. We also check
- __STDC__ and assume gcc sets it and has volatile in stage >=2. */
-#if !defined(HAVE_VOLATILE) && !defined(__STDC__) && !defined(volatile)
-#define volatile
+#if defined (HAVE_DECL_ABORT) && !HAVE_DECL_ABORT
+extern void abort (void);
#endif
-#if defined (HAVE_DECL_ABORT) && !HAVE_DECL_ABORT
-extern void abort PARAMS ((void));
+#if defined (HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF
+extern int snprintf (char *, size_t, const char *, ...);
#endif
/* 1 if we have C99 designated initializers. */
@@ -450,10 +451,12 @@ extern void abort PARAMS ((void));
#ifndef HOST_PTR_PRINTF
# ifdef HAVE_PRINTF_PTR
# define HOST_PTR_PRINTF "%p"
+# elif SIZEOF_INT == SIZEOF_VOID_P
+# define HOST_PTR_PRINTF "%x"
+# elif SIZEOF_LONG == SIZEOF_VOID_P
+# define HOST_PTR_PRINTF "%lx"
# else
-# define HOST_PTR_PRINTF \
- (sizeof (int) == sizeof (char *) ? "%x" \
- : sizeof (long) == sizeof (char *) ? "%lx" : "%llx")
+# define HOST_PTR_PRINTF "%llx"
# endif
#endif /* ! HOST_PTR_PRINTF */
@@ -462,34 +465,19 @@ extern void abort PARAMS ((void));
#define PATH_SEPARATOR ':'
#endif
+/* Filename handling macros. */
+#include "filenames.h"
+
+/* These should be phased out in favor of IS_DIR_SEPARATOR, where possible. */
#ifndef DIR_SEPARATOR
-#define DIR_SEPARATOR '/'
-#endif
-
-/* Define IS_DIR_SEPARATOR. */
-#ifndef DIR_SEPARATOR_2
-# define IS_DIR_SEPARATOR(CH) ((CH) == DIR_SEPARATOR)
-#else /* DIR_SEPARATOR_2 */
-# define IS_DIR_SEPARATOR(CH) \
- (((CH) == DIR_SEPARATOR) || ((CH) == DIR_SEPARATOR_2))
-#endif /* DIR_SEPARATOR_2 */
-
-/* Say how to test for an absolute pathname. On Unix systems, this is if
- it starts with a leading slash or a '$', the latter meaning the value of
- an environment variable is to be used. On machien with DOS-based
- file systems, it is also absolute if it starts with a drive identifier. */
-#ifdef HAVE_DOS_BASED_FILE_SYSTEM
-#define IS_ABSOLUTE_PATHNAME(STR) \
- (IS_DIR_SEPARATOR ((STR)[0]) || (STR)[0] == '$' \
- || ((STR)[0] != '\0' && (STR)[1] == ':' && IS_DIR_SEPARATOR ((STR)[2])))
-#else
-#define IS_ABSOLUTE_PATHNAME(STR) \
- (IS_DIR_SEPARATOR ((STR)[0]) || (STR)[0] == '$')
+# define DIR_SEPARATOR '/'
+# ifdef HAVE_DOS_BASED_FILE_SYSTEM
+# define DIR_SEPARATOR_2 '\\'
+# endif
#endif
/* Get libiberty declarations. */
#include "libiberty.h"
-#include "symcat.h"
/* Provide a default for the HOST_BIT_BUCKET.
This suffices for POSIX-like hosts. */
@@ -502,23 +490,21 @@ extern void abort PARAMS ((void));
FIXME: provide a complete autoconf test for buggy enum bitfields. */
#if (GCC_VERSION > 2000)
-#define ENUM_BITFIELD(TYPE) enum TYPE
+#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE
#else
#define ENUM_BITFIELD(TYPE) unsigned int
#endif
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER)
+/* We only use bool bitfields with gcc3. Some supposedly C99
+ compilers don't handle them correctly. */
+#if (GCC_VERSION >= 3000)
+#define BOOL_BITFIELD _Bool
+#else
+#define BOOL_BITFIELD unsigned int
#endif
-/* Traditional C cannot initialize union members of structs. Provide
- a macro which expands appropriately to handle it. This only works
- if you intend to initialize the union member to zero since it relies
- on default initialization to zero in the traditional C case. */
-#ifdef __STDC__
-#define UNION_INIT_ZERO , {0}
-#else
-#define UNION_INIT_ZERO
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER)
#endif
/* Various error reporting routines want to use __FUNCTION__. */
@@ -573,6 +559,13 @@ typedef char _Bool;
#define really_call_calloc calloc
#define really_call_realloc realloc
+#if defined(FLEX_SCANNER) || defined(YYBISON) || defined(YYBYACC)
+/* Flex and bison use malloc and realloc. Yuk. Note that this means
+ really_call_* cannot be used in a .l or .y file. */
+#define malloc xmalloc
+#define realloc xrealloc
+#endif
+
#if (GCC_VERSION >= 3000)
/* Note autoconf checks for prototype declarations and includes
@@ -584,11 +577,7 @@ typedef char _Bool;
#undef strdup
#pragma GCC poison calloc strdup
-#if defined(FLEX_SCANNER) || defined (YYBISON)
-/* Flex and bison use malloc and realloc. Yuk. */
-#define malloc xmalloc
-#define realloc xrealloc
-#else
+#if !defined(FLEX_SCANNER) && !defined(YYBISON)
#undef malloc
#undef realloc
#pragma GCC poison malloc realloc
@@ -606,13 +595,20 @@ typedef char _Bool;
ASM_OUTPUT_DESTRUCTOR SIGNED_CHAR_SPEC MAX_CHAR_TYPE_SIZE \
WCHAR_UNSIGNED UNIQUE_SECTION SELECT_SECTION SELECT_RTX_SECTION \
ENCODE_SECTION_INFO STRIP_NAME_ENCODING ASM_GLOBALIZE_LABEL \
- ASM_OUTPUT_MI_THUNK
+ ASM_OUTPUT_MI_THUNK CONST_COSTS RTX_COSTS DEFAULT_RTX_COSTS \
+ ADDRESS_COST MACHINE_DEPENDENT_REORG ASM_FILE_START ASM_FILE_END \
+ ASM_SIMPLIFY_DWARF_ADDR INIT_TARGET_OPTABS INIT_SUBTARGET_OPTABS \
+ INIT_GOFAST_OPTABS MULSI3_LIBCALL MULDI3_LIBCALL DIVSI3_LIBCALL \
+ DIVDI3_LIBCALL UDIVSI3_LIBCALL UDIVDI3_LIBCALL MODSI3_LIBCALL \
+ MODDI3_LIBCALL UMODSI3_LIBCALL UMODDI3_LIBCALL BUILD_VA_LIST_TYPE \
+ PRETEND_OUTGOING_VARARGS_NAMED STRUCT_VALUE_INCOMING_REGNUM \
+ SPLIT_COMPLEX_ARGS
/* Other obsolete target macros, or macros that used to be in target
headers and were not used, and may be obsolete or may never have
been used. */
- #pragma GCC poison INT_ASM_OP ASM_OUTPUT_EH_REGION_BEG \
- ASM_OUTPUT_EH_REGION_END ASM_OUTPUT_LABELREF_AS_INT \
+ #pragma GCC poison INT_ASM_OP ASM_OUTPUT_EH_REGION_BEG CPP_PREDEFINES \
+ ASM_OUTPUT_EH_REGION_END ASM_OUTPUT_LABELREF_AS_INT SMALL_STACK \
DOESNT_NEED_UNWINDER EH_TABLE_LOOKUP OBJC_SELECTORS_WITHOUT_LABELS \
OMIT_EH_TABLE EASY_DIV_EXPR IMPLICIT_FIX_EXPR \
LONGJMP_RESTORE_FROM_STACK MAX_INT_TYPE_SIZE ASM_IDENTIFY_GCC \
@@ -623,12 +619,35 @@ typedef char _Bool;
BLOCK_PROFILER BLOCK_PROFILER_CODE FUNCTION_BLOCK_PROFILER \
FUNCTION_BLOCK_PROFILER_EXIT MACHINE_STATE_SAVE \
MACHINE_STATE_RESTORE SCCS_DIRECTIVE SECTION_ASM_OP \
- ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL
+ ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL ASM_OUTPUT_INTERNAL_LABEL \
+ OBJC_PROLOGUE ALLOCATE_TRAMPOLINE HANDLE_PRAGMA ROUND_TYPE_SIZE \
+ ROUND_TYPE_SIZE_UNIT CONST_SECTION_ASM_OP CRT_GET_RFIB_TEXT \
+ DBX_LBRAC_FIRST DBX_OUTPUT_ENUM DBX_OUTPUT_SOURCE_FILENAME \
+ DBX_WORKING_DIRECTORY INSN_CACHE_DEPTH INSN_CACHE_SIZE \
+ INSN_CACHE_LINE_WIDTH INIT_SECTION_PREAMBLE NEED_ATEXIT ON_EXIT \
+ EXIT_BODY OBJECT_FORMAT_ROSE MULTIBYTE_CHARS MAP_CHARACTER \
+ LIBGCC_NEEDS_DOUBLE FINAL_PRESCAN_LABEL DEFAULT_CALLER_SAVES \
+ LOAD_ARGS_REVERSED MAX_INTEGER_COMPUTATION_MODE \
+ CONVERT_HARD_REGISTER_TO_SSA_P ASM_OUTPUT_MAIN_SOURCE_FILENAME \
+ FIRST_INSN_ADDRESS TEXT_SECTION SHARED_BSS_SECTION_ASM_OP \
+ PROMOTED_MODE EXPAND_BUILTIN_VA_END \
+ LINKER_DOES_NOT_WORK_WITH_DWARF2
/* Hooks that are no longer used. */
#pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \
- LANG_HOOKS_MARK_TREE
-
+ LANG_HOOKS_MARK_TREE LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES
+
+/* Libiberty macros that are no longer used in GCC. */
+#undef ANSI_PROTOTYPES
+#undef PTR_CONST
+#undef LONG_DOUBLE
+#undef VPARAMS
+#undef VA_OPEN
+#undef VA_FIXEDARG
+#undef VA_CLOSE
+#undef VA_START
+ #pragma GCC poison ANSI_PROTOTYPES PTR_CONST LONG_DOUBLE VPARAMS VA_OPEN \
+ VA_FIXEDARG VA_CLOSE VA_START
#endif /* IN_GCC */
/* Note: not all uses of the `index' token (e.g. variable names and
diff --git a/contrib/gcc/target-def.h b/contrib/gcc/target-def.h
index 154d58d47e9a..f21025af255f 100644
--- a/contrib/gcc/target-def.h
+++ b/contrib/gcc/target-def.h
@@ -1,5 +1,5 @@
/* Default initializers for a generic GCC target.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 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
@@ -40,7 +40,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TARGET_ASM_ALIGNED_TI_OP NULL
/* GAS and SYSV4 assemblers accept these. */
-#if defined (OBJECT_FORMAT_ELF) || defined (OBJECT_FORMAT_ROSE)
+#if defined (OBJECT_FORMAT_ELF)
#define TARGET_ASM_UNALIGNED_HI_OP "\t.2byte\t"
#define TARGET_ASM_UNALIGNED_SI_OP "\t.4byte\t"
#define TARGET_ASM_UNALIGNED_DI_OP "\t.8byte\t"
@@ -50,13 +50,16 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TARGET_ASM_UNALIGNED_SI_OP NULL
#define TARGET_ASM_UNALIGNED_DI_OP NULL
#define TARGET_ASM_UNALIGNED_TI_OP NULL
-#endif /* OBJECT_FORMAT_ELF || OBJECT_FORMAT_ROSE */
+#endif /* OBJECT_FORMAT_ELF */
#define TARGET_ASM_INTEGER default_assemble_integer
#ifndef TARGET_ASM_GLOBALIZE_LABEL
#define TARGET_ASM_GLOBALIZE_LABEL default_globalize_label
#endif
+#ifndef TARGET_ASM_INTERNAL_LABEL
+#define TARGET_ASM_INTERNAL_LABEL default_internal_label
+#endif
#ifndef TARGET_ASM_ASSEMBLE_VISIBILITY
#define TARGET_ASM_ASSEMBLE_VISIBILITY default_assemble_visibility
@@ -137,6 +140,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#endif
#endif
+#define TARGET_DWARF_REGISTER_SPAN hook_rtx_rtx_null
+
#ifndef TARGET_ASM_EXCEPTION_SECTION
#define TARGET_ASM_EXCEPTION_SECTION default_exception_section
#endif
@@ -145,6 +150,26 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TARGET_ASM_EH_FRAME_SECTION default_eh_frame_section
#endif
+#ifndef TARGET_ASM_FILE_START
+#define TARGET_ASM_FILE_START default_file_start
+#endif
+
+#ifndef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END hook_void_void
+#endif
+
+#ifndef TARGET_ASM_FILE_START_APP_OFF
+#define TARGET_ASM_FILE_START_APP_OFF false
+#endif
+
+#ifndef TARGET_ASM_FILE_START_FILE_DIRECTIVE
+#define TARGET_ASM_FILE_START_FILE_DIRECTIVE false
+#endif
+
+#ifndef TARGET_ASM_EXTERNAL_LIBCALL
+#define TARGET_ASM_EXTERNAL_LIBCALL default_external_libcall
+#endif
+
#define TARGET_ASM_ALIGNED_INT_OP \
{TARGET_ASM_ALIGNED_HI_OP, \
TARGET_ASM_ALIGNED_SI_OP, \
@@ -164,6 +189,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_ASM_UNALIGNED_INT_OP, \
TARGET_ASM_INTEGER, \
TARGET_ASM_GLOBALIZE_LABEL, \
+ TARGET_ASM_INTERNAL_LABEL, \
TARGET_ASM_ASSEMBLE_VISIBILITY, \
TARGET_ASM_FUNCTION_PROLOGUE, \
TARGET_ASM_FUNCTION_END_PROLOGUE, \
@@ -178,7 +204,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_ASM_CONSTRUCTOR, \
TARGET_ASM_DESTRUCTOR, \
TARGET_ASM_OUTPUT_MI_THUNK, \
- TARGET_ASM_CAN_OUTPUT_MI_THUNK }
+ TARGET_ASM_CAN_OUTPUT_MI_THUNK, \
+ TARGET_ASM_FILE_START, \
+ TARGET_ASM_FILE_END, \
+ TARGET_ASM_EXTERNAL_LIBCALL}
/* Scheduler hooks. All of these default to null pointers, which
haifa-sched.c looks for and handles. */
@@ -190,14 +219,18 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TARGET_SCHED_FINISH 0
#define TARGET_SCHED_REORDER 0
#define TARGET_SCHED_REORDER2 0
+#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK 0
#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE 0
#define TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN 0
#define TARGET_SCHED_DFA_PRE_CYCLE_INSN 0
#define TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN 0
#define TARGET_SCHED_DFA_POST_CYCLE_INSN 0
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD 0
+#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD 0
+#define TARGET_SCHED_DFA_NEW_CYCLE 0
#define TARGET_SCHED_INIT_DFA_BUBBLES 0
#define TARGET_SCHED_DFA_BUBBLE 0
+#define TARGET_SCHED_IS_COSTLY_DEPENDENCE 0
#define TARGET_SCHED \
{TARGET_SCHED_ADJUST_COST, \
@@ -208,22 +241,29 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_SCHED_FINISH, \
TARGET_SCHED_REORDER, \
TARGET_SCHED_REORDER2, \
+ TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK, \
TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE, \
TARGET_SCHED_INIT_DFA_PRE_CYCLE_INSN, \
TARGET_SCHED_DFA_PRE_CYCLE_INSN, \
TARGET_SCHED_INIT_DFA_POST_CYCLE_INSN, \
TARGET_SCHED_DFA_POST_CYCLE_INSN, \
TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD, \
+ TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD, \
+ TARGET_SCHED_DFA_NEW_CYCLE, \
TARGET_SCHED_INIT_DFA_BUBBLES, \
- TARGET_SCHED_DFA_BUBBLE}
+ TARGET_SCHED_DFA_BUBBLE, \
+ TARGET_SCHED_IS_COSTLY_DEPENDENCE}
-/* All in tree.c. */
+/* In tree.c. */
#define TARGET_MERGE_DECL_ATTRIBUTES merge_decl_attributes
#define TARGET_MERGE_TYPE_ATTRIBUTES merge_type_attributes
#define TARGET_ATTRIBUTE_TABLE NULL
+/* In cse.c. */
+#define TARGET_ADDRESS_COST default_address_cost
+
/* In builtins.c. */
-#define TARGET_INIT_BUILTINS default_init_builtins
+#define TARGET_INIT_BUILTINS hook_void_void
#define TARGET_EXPAND_BUILTIN default_expand_builtin
/* In varasm.c. */
@@ -239,23 +279,81 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TARGET_BINDS_LOCAL_P default_binds_local_p
#endif
+#ifndef TARGET_VALID_POINTER_MODE
+#define TARGET_VALID_POINTER_MODE default_valid_pointer_mode
+#endif
+
+#ifndef TARGET_VECTOR_OPAQUE_P
+#define TARGET_VECTOR_OPAQUE_P hook_bool_tree_false
+#endif
+
/* In hook.c. */
#define TARGET_CANNOT_MODIFY_JUMPS_P hook_bool_void_false
+#define TARGET_BRANCH_TARGET_REGISTER_CLASS hook_int_void_no_regs
+#define TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED hook_bool_bool_false
#define TARGET_CANNOT_FORCE_CONST_MEM hook_bool_rtx_false
+#define TARGET_CANNOT_COPY_INSN_P NULL
+#define TARGET_DELEGITIMIZE_ADDRESS hook_rtx_rtx_identity
+#define TARGET_FUNCTION_OK_FOR_SIBCALL hook_bool_tree_tree_false
#define TARGET_COMP_TYPE_ATTRIBUTES hook_int_tree_tree_1
#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES hook_void_tree
#define TARGET_INSERT_ATTRIBUTES hook_void_tree_treeptr
#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_tree_false
#define TARGET_MS_BITFIELD_LAYOUT_P hook_bool_tree_false
+#define TARGET_RTX_COSTS hook_bool_rtx_int_int_intp_false
+
+#ifndef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS hook_void_void
+#endif
#ifndef TARGET_IN_SMALL_DATA_P
#define TARGET_IN_SMALL_DATA_P hook_bool_tree_false
#endif
#ifndef TARGET_ENCODE_SECTION_INFO
-#define TARGET_ENCODE_SECTION_INFO hook_void_tree_int
+#define TARGET_ENCODE_SECTION_INFO default_encode_section_info
#endif
+#define TARGET_FIXED_CONDITION_CODE_REGS hook_bool_uintp_uintp_false
+
+#define TARGET_CC_MODES_COMPATIBLE default_cc_modes_compatible
+
+#define TARGET_MACHINE_DEPENDENT_REORG 0
+
+#define TARGET_BUILD_BUILTIN_VA_LIST std_build_builtin_va_list
+
+#define TARGET_GET_PCH_VALIDITY default_get_pch_validity
+#define TARGET_PCH_VALID_P default_pch_valid_p
+
+#define TARGET_PROMOTE_FUNCTION_ARGS default_promote_function_args
+#define TARGET_PROMOTE_FUNCTION_RETURN default_promote_function_return
+#define TARGET_PROMOTE_PROTOTYPES default_promote_prototypes
+
+#define TARGET_STRUCT_VALUE_RTX default_struct_value_rtx
+#define TARGET_RETURN_IN_MEMORY default_return_in_memory
+#define TARGET_RETURN_IN_MSB hook_bool_tree_false
+
+#define TARGET_EXPAND_BUILTIN_SAVEREGS default_expand_builtin_saveregs
+#define TARGET_SETUP_INCOMING_VARARGS default_setup_incoming_varargs
+#define TARGET_STRICT_ARGUMENT_NAMING default_strict_argument_naming
+#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED \
+ default_pretend_outgoing_varargs_named
+#define TARGET_SPLIT_COMPLEX_ARG NULL
+
+#define TARGET_CALLS { \
+ TARGET_PROMOTE_FUNCTION_ARGS, \
+ TARGET_PROMOTE_FUNCTION_RETURN, \
+ TARGET_PROMOTE_PROTOTYPES, \
+ TARGET_STRUCT_VALUE_RTX, \
+ TARGET_RETURN_IN_MEMORY, \
+ TARGET_RETURN_IN_MSB, \
+ TARGET_EXPAND_BUILTIN_SAVEREGS, \
+ TARGET_SETUP_INCOMING_VARARGS, \
+ TARGET_STRICT_ARGUMENT_NAMING, \
+ TARGET_PRETEND_OUTGOING_VARARGS_NAMED, \
+ TARGET_SPLIT_COMPLEX_ARG, \
+ }
+
/* The whole shebang. */
#define TARGET_INITIALIZER \
{ \
@@ -271,18 +369,39 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_MS_BITFIELD_LAYOUT_P, \
TARGET_INIT_BUILTINS, \
TARGET_EXPAND_BUILTIN, \
+ TARGET_INIT_LIBFUNCS, \
TARGET_SECTION_TYPE_FLAGS, \
TARGET_CANNOT_MODIFY_JUMPS_P, \
+ TARGET_BRANCH_TARGET_REGISTER_CLASS, \
+ TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED, \
TARGET_CANNOT_FORCE_CONST_MEM, \
+ TARGET_CANNOT_COPY_INSN_P, \
+ TARGET_DELEGITIMIZE_ADDRESS, \
+ TARGET_FUNCTION_OK_FOR_SIBCALL, \
TARGET_IN_SMALL_DATA_P, \
TARGET_BINDS_LOCAL_P, \
TARGET_ENCODE_SECTION_INFO, \
TARGET_STRIP_NAME_ENCODING, \
+ TARGET_VALID_POINTER_MODE, \
+ TARGET_VECTOR_OPAQUE_P, \
+ TARGET_RTX_COSTS, \
+ TARGET_ADDRESS_COST, \
+ TARGET_DWARF_REGISTER_SPAN, \
+ TARGET_FIXED_CONDITION_CODE_REGS, \
+ TARGET_CC_MODES_COMPATIBLE, \
+ TARGET_MACHINE_DEPENDENT_REORG, \
+ TARGET_BUILD_BUILTIN_VA_LIST, \
+ TARGET_GET_PCH_VALIDITY, \
+ TARGET_PCH_VALID_P, \
+ TARGET_CALLS, \
TARGET_HAVE_NAMED_SECTIONS, \
TARGET_HAVE_CTORS_DTORS, \
TARGET_HAVE_TLS, \
TARGET_HAVE_SRODATA_SECTION, \
- TARGET_TERMINATE_DW2_EH_FRAME_INFO \
+ TARGET_TERMINATE_DW2_EH_FRAME_INFO, \
+ TARGET_ASM_FILE_START_APP_OFF, \
+ TARGET_ASM_FILE_START_FILE_DIRECTIVE, \
}
#include "hooks.h"
+#include "targhooks.h"
diff --git a/contrib/gcc/target.h b/contrib/gcc/target.h
index 0ac1c5aa17b6..d7729ba0f179 100644
--- a/contrib/gcc/target.h
+++ b/contrib/gcc/target.h
@@ -1,5 +1,5 @@
/* Data structure definitions for a generic GCC target.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 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
@@ -44,6 +44,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
to gradually reduce the amount of conditional compilation that is
scattered throughout GCC. */
+#include "tm.h"
+
struct gcc_target
{
/* Functions that output assembler for the target. */
@@ -67,68 +69,69 @@ struct gcc_target
ALIGNED_P indicates whether it is aligned. Return true if
successful. Only handles cases for which BYTE_OP, ALIGNED_OP
and UNALIGNED_OP are NULL. */
- bool (* integer) PARAMS ((rtx x, unsigned int size, int aligned_p));
+ bool (* integer) (rtx x, unsigned int size, int aligned_p);
/* Output code that will globalize a label. */
- void (* globalize_label) PARAMS ((FILE *, const char *));
+ void (* globalize_label) (FILE *, const char *);
+
+ /* Output an internal label. */
+ void (* internal_label) (FILE *, const char *, unsigned long);
/* Emit an assembler directive to set visibility for the symbol
associated with the tree decl. */
- void (* visibility) PARAMS ((tree, int));
+ void (* visibility) (tree, int);
/* Output the assembler code for entry to a function. */
- void (* function_prologue) PARAMS ((FILE *, HOST_WIDE_INT));
+ void (* function_prologue) (FILE *, HOST_WIDE_INT);
/* Output the assembler code for end of prologue. */
- void (* function_end_prologue) PARAMS ((FILE *));
+ void (* function_end_prologue) (FILE *);
/* Output the assembler code for start of epilogue. */
- void (* function_begin_epilogue) PARAMS ((FILE *));
+ void (* function_begin_epilogue) (FILE *);
/* Output the assembler code for function exit. */
- void (* function_epilogue) PARAMS ((FILE *, HOST_WIDE_INT));
+ void (* function_epilogue) (FILE *, HOST_WIDE_INT);
/* Switch to an arbitrary section NAME with attributes as
specified by FLAGS. */
- void (* named_section) PARAMS ((const char *, unsigned int));
+ void (* named_section) (const char *, unsigned int);
/* Switch to the section that holds the exception table. */
- void (* exception_section) PARAMS ((void));
+ void (* exception_section) (void);
/* Switch to the section that holds the exception frames. */
- void (* eh_frame_section) PARAMS ((void));
+ void (* eh_frame_section) (void);
/* Select and switch to a section for EXP. It may be a DECL or a
- constant for which TREE_CST_RTL is valid. RELOC is nonzero if
- runtime relocations must be applied; bit 1 will be set if the
- runtime relocations require non-local name resolution. ALIGN is
- the required alignment of the data. */
- void (* select_section) PARAMS ((tree, int, unsigned HOST_WIDE_INT));
+ constant. RELOC is nonzero if runtime relocations must be applied;
+ bit 1 will be set if the runtime relocations require non-local
+ name resolution. ALIGN is the required alignment of the data. */
+ void (* select_section) (tree, int, unsigned HOST_WIDE_INT);
/* Select and switch to a section for X with MODE. ALIGN is
the desired alignment of the data. */
- void (* select_rtx_section) PARAMS ((enum machine_mode, rtx,
- unsigned HOST_WIDE_INT));
+ void (* select_rtx_section) (enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT);
/* Select a unique section name for DECL. RELOC is the same as
for SELECT_SECTION. */
- void (* unique_section) PARAMS ((tree, int));
+ void (* unique_section) (tree, int);
/* Output a constructor for a symbol with a given priority. */
- void (* constructor) PARAMS ((rtx, int));
+ void (* constructor) (rtx, int);
/* Output a destructor for a symbol with a given priority. */
- void (* destructor) PARAMS ((rtx, int));
+ void (* destructor) (rtx, int);
/* Output the assembler code for a thunk function. THUNK_DECL is the
declaration for the thunk function itself, FUNCTION is the decl for
the target function. DELTA is an immediate constant offset to be
added to THIS. If VCALL_OFFSET is nonzero, the word at
*(*this + vcall_offset) should be added to THIS. */
- void (* output_mi_thunk) PARAMS ((FILE *file, tree thunk_decl,
- HOST_WIDE_INT delta,
- HOST_WIDE_INT vcall_offset,
- tree function_decl));
+ void (* output_mi_thunk) (FILE *file, tree thunk_decl,
+ HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
+ tree function_decl);
/* Determine whether output_mi_thunk would succeed. */
/* ??? Ideally, this hook would not exist, and success or failure
@@ -136,10 +139,21 @@ struct gcc_target
too much undo-able setup involved in invoking output_mi_thunk.
Could be fixed by making output_mi_thunk emit rtl instead of
text to the output file. */
- bool (* can_output_mi_thunk) PARAMS ((tree thunk_decl,
- HOST_WIDE_INT delta,
- HOST_WIDE_INT vcall_offset,
- tree function_decl));
+ bool (* can_output_mi_thunk) (tree thunk_decl, HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset,
+ tree function_decl);
+
+ /* Output any boilerplate text needed at the beginning of a
+ translation unit. */
+ void (*file_start) (void);
+
+ /* Output any boilerplate text needed at the end of a
+ translation unit. */
+ void (*file_end) (void);
+
+ /* Output an assembler pseudo-op to declare a library function name
+ external. */
+ void (*external_libcall) (rtx);
} asm_out;
/* Functions relating to instruction scheduling. */
@@ -148,36 +162,41 @@ struct gcc_target
/* Given the current cost, COST, of an insn, INSN, calculate and
return a new cost based on its relationship to DEP_INSN through
the dependence LINK. The default is to make no adjustment. */
- int (* adjust_cost) PARAMS ((rtx insn, rtx link, rtx def_insn, int cost));
+ int (* adjust_cost) (rtx insn, rtx link, rtx def_insn, int cost);
/* Adjust the priority of an insn as you see fit. Returns the new
priority. */
- int (* adjust_priority) PARAMS ((rtx, int));
+ int (* adjust_priority) (rtx, int);
/* Function which returns the maximum number of insns that can be
scheduled in the same machine cycle. This must be constant
over an entire compilation. The default is 1. */
- int (* issue_rate) PARAMS ((void));
+ int (* issue_rate) (void);
/* Calculate how much this insn affects how many more insns we
can emit this cycle. Default is they all cost the same. */
- int (* variable_issue) PARAMS ((FILE *, int, rtx, int));
+ int (* variable_issue) (FILE *, int, rtx, int);
/* Initialize machine-dependent scheduling code. */
- void (* md_init) PARAMS ((FILE *, int, int));
+ void (* md_init) (FILE *, int, int);
/* Finalize machine-dependent scheduling code. */
- void (* md_finish) PARAMS ((FILE *, int));
+ void (* md_finish) (FILE *, int);
/* Reorder insns in a machine-dependent fashion, in two different
places. Default does nothing. */
- int (* reorder) PARAMS ((FILE *, int, rtx *, int *, int));
- int (* reorder2) PARAMS ((FILE *, int, rtx *, int *, int));
+ int (* reorder) (FILE *, int, rtx *, int *, int);
+ int (* reorder2) (FILE *, int, rtx *, int *, int);
+
+ /* The following member value is a pointer to a function called
+ after evaluation forward dependencies of insns in chain given
+ by two parameter values (head and tail correspondingly). */
+ void (* dependencies_evaluation_hook) (rtx, rtx);
/* The following member value is a pointer to a function returning
nonzero if we should use DFA based scheduling. The default is
to use the old pipeline scheduler. */
- int (* use_dfa_pipeline_interface) PARAMS ((void));
+ int (* use_dfa_pipeline_interface) (void);
/* The values of all the following members are used only for the
DFA based scheduler: */
/* The values of the following four members are pointers to
@@ -188,13 +207,13 @@ struct gcc_target
correspondingly starts and finishes. The function defined by
init_dfa_pre_cycle_insn and init_dfa_post_cycle_insn are used
to initialize the corresponding insns. The default values of
- the memebers result in not changing the automaton state when
+ the members result in not changing the automaton state when
the new simulated processor cycle correspondingly starts and
finishes. */
- void (* init_dfa_pre_cycle_insn) PARAMS ((void));
- rtx (* dfa_pre_cycle_insn) PARAMS ((void));
- void (* init_dfa_post_cycle_insn) PARAMS ((void));
- rtx (* dfa_post_cycle_insn) PARAMS ((void));
+ void (* init_dfa_pre_cycle_insn) (void);
+ rtx (* dfa_pre_cycle_insn) (void);
+ void (* init_dfa_post_cycle_insn) (void);
+ rtx (* dfa_post_cycle_insn) (void);
/* The following member value is a pointer to a function returning value
which defines how many insns in queue `ready' will we try for
multi-pass scheduling. if the member value is nonzero and the
@@ -202,7 +221,26 @@ struct gcc_target
multi-pass scheduling for the first cycle. In other words, we will
try to choose ready insn which permits to start maximum number of
insns on the same cycle. */
- int (* first_cycle_multipass_dfa_lookahead) PARAMS ((void));
+ int (* first_cycle_multipass_dfa_lookahead) (void);
+ /* The following member value is pointer to a function controlling
+ what insns from the ready insn queue will be considered for the
+ multipass insn scheduling. If the hook returns zero for insn
+ passed as the parameter, the insn will be not chosen to be
+ issued. */
+ int (* first_cycle_multipass_dfa_lookahead_guard) (rtx);
+ /* The following member value is pointer to a function called by
+ the insn scheduler before issuing insn passed as the third
+ parameter on given cycle. If the hook returns nonzero, the
+ insn is not issued on given processors cycle. Instead of that,
+ the processor cycle is advanced. If the value passed through
+ the last parameter is zero, the insn ready queue is not sorted
+ on the new cycle start as usually. The first parameter passes
+ file for debugging output. The second one passes the scheduler
+ verbose level of the debugging output. The forth and the fifth
+ parameter values are correspondingly processor cycle on which
+ the previous insn has been issued and the current processor
+ cycle. */
+ int (* dfa_new_cycle) (FILE *, int, rtx, int, int, int *);
/* The values of the following members are pointers to functions
used to improve the first cycle multipass scheduling by
inserting nop insns. dfa_scheduler_bubble gives a function
@@ -213,15 +251,26 @@ struct gcc_target
init_dfa_scheduler_bubbles is used. The default values of the
members result in not inserting nop insns during the multipass
scheduling. */
- void (* init_dfa_bubbles) PARAMS ((void));
- rtx (* dfa_bubble) PARAMS ((int));
+ void (* init_dfa_bubbles) (void);
+ rtx (* dfa_bubble) (int);
+ /* The following member value is a pointer to a function called
+ by the insn scheduler. It should return true if there exists a
+ dependence which is considered costly by the target, between
+ the insn passed as the first parameter, and the insn passed as
+ the second parameter. The third parameter is the INSN_DEPEND
+ link that represents the dependence between the two insns. The
+ fourth argument is the cost of the dependence as estimated by
+ the scheduler. The last argument is the distance in cycles
+ between the already scheduled insn (first parameter) and the
+ the second insn (second parameter). */
+ bool (* is_costly_dependence) (rtx, rtx, rtx, int, int);
} sched;
/* Given two decls, merge their attributes and return the result. */
- tree (* merge_decl_attributes) PARAMS ((tree, tree));
+ tree (* merge_decl_attributes) (tree, tree);
/* Given two types, merge their attributes and return the result. */
- tree (* merge_type_attributes) PARAMS ((tree, tree));
+ tree (* merge_type_attributes) (tree, tree);
/* Table of machine attributes and functions to handle them.
Ignored if NULL. */
@@ -230,54 +279,159 @@ struct gcc_target
/* Return zero if the attributes on TYPE1 and TYPE2 are incompatible,
one if they are compatible and two if they are nearly compatible
(which causes a warning to be generated). */
- int (* comp_type_attributes) PARAMS ((tree type1, tree type2));
+ int (* comp_type_attributes) (tree type1, tree type2);
/* Assign default attributes to the newly defined TYPE. */
- void (* set_default_type_attributes) PARAMS ((tree type));
+ void (* set_default_type_attributes) (tree type);
/* Insert attributes on the newly created DECL. */
- void (* insert_attributes) PARAMS ((tree decl, tree *attributes));
+ void (* insert_attributes) (tree decl, tree *attributes);
/* Return true if FNDECL (which has at least one machine attribute)
can be inlined despite its machine attributes, false otherwise. */
- bool (* function_attribute_inlinable_p) PARAMS ((tree fndecl));
+ bool (* function_attribute_inlinable_p) (tree fndecl);
/* Return true if bitfields in RECORD_TYPE should follow the
Microsoft Visual C++ bitfield layout rules. */
- bool (* ms_bitfield_layout_p) PARAMS ((tree record_type));
+ bool (* ms_bitfield_layout_p) (tree record_type);
/* Set up target-specific built-in functions. */
- void (* init_builtins) PARAMS ((void));
+ void (* init_builtins) (void);
/* Expand a target-specific builtin. */
- rtx (* expand_builtin) PARAMS ((tree exp, rtx target, rtx subtarget,
- enum machine_mode mode, int ignore));
+ rtx (* expand_builtin) (tree exp, rtx target, rtx subtarget,
+ enum machine_mode mode, int ignore);
+
+ /* Make any adjustments to libfunc names needed for this target. */
+ void (* init_libfuncs) (void);
/* Given a decl, a section name, and whether the decl initializer
has relocs, choose attributes for the section. */
/* ??? Should be merged with SELECT_SECTION and UNIQUE_SECTION. */
- unsigned int (* section_type_flags) PARAMS ((tree, const char *, int));
+ unsigned int (* section_type_flags) (tree, const char *, int);
/* True if new jumps cannot be created, to replace existing ones or
not, at the current point in the compilation. */
- bool (* cannot_modify_jumps_p) PARAMS ((void));
+ bool (* cannot_modify_jumps_p) (void);
+
+ /* Return a register class for which branch target register
+ optimizations should be applied. */
+ int (* branch_target_register_class) (void);
+
+ /* Return true if branch target register optimizations should include
+ callee-saved registers that are not already live during the current
+ function. AFTER_PE_GEN is true if prologues and epilogues have
+ already been generated. */
+ bool (* branch_target_register_callee_saved) (bool after_pe_gen);
/* True if the constant X cannot be placed in the constant pool. */
- bool (* cannot_force_const_mem) PARAMS ((rtx));
+ bool (* cannot_force_const_mem) (rtx);
+
+ /* True if the insn X cannot be duplicated. */
+ bool (* cannot_copy_insn_p) (rtx);
+
+ /* Given an address RTX, undo the effects of LEGITIMIZE_ADDRESS. */
+ rtx (* delegitimize_address) (rtx);
+
+ /* True if it is OK to do sibling call optimization for the specified
+ call expression EXP. DECL will be the called function, or NULL if
+ this is an indirect call. */
+ bool (*function_ok_for_sibcall) (tree decl, tree exp);
/* True if EXP should be placed in a "small data" section. */
- bool (* in_small_data_p) PARAMS ((tree));
+ bool (* in_small_data_p) (tree);
/* True if EXP names an object for which name resolution must resolve
to the current module. */
- bool (* binds_local_p) PARAMS ((tree));
+ bool (* binds_local_p) (tree);
/* Do something target-specific to record properties of the DECL into
the associated SYMBOL_REF. */
- void (* encode_section_info) PARAMS ((tree, int));
+ void (* encode_section_info) (tree, rtx, int);
/* Undo the effects of encode_section_info on the symbol string. */
- const char * (* strip_name_encoding) PARAMS ((const char *));
+ const char * (* strip_name_encoding) (const char *);
+
+ /* True if MODE is valid for a pointer in __attribute__((mode("MODE"))). */
+ bool (* valid_pointer_mode) (enum machine_mode mode);
+
+ /* True if a vector is opaque. */
+ bool (* vector_opaque_p) (tree);
+
+ /* 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. */
+ /* Note that CODE and OUTER_CODE ought to be RTX_CODE, but that's
+ not necessarily defined at this point. */
+ bool (* rtx_costs) (rtx x, int code, int outer_code, int *total);
+
+ /* Compute the cost of X, used as an address. Never called with
+ invalid addresses. */
+ int (* address_cost) (rtx x);
+
+ /* Given a register, this hook should return a parallel of registers
+ to represent where to find the register pieces. Define this hook
+ if the register and its mode are represented in Dwarf in
+ non-contiguous locations, or if the register should be
+ represented in more than one register in Dwarf. Otherwise, this
+ hook should return NULL_RTX. */
+ rtx (* dwarf_register_span) (rtx);
+
+ /* Fetch the fixed register(s) which hold condition codes, for
+ targets where it makes sense to look for duplicate assignments to
+ the condition codes. This should return true if there is such a
+ register, false otherwise. The arguments should be set to the
+ fixed register numbers. Up to two condition code registers are
+ supported. If there is only one for this target, the int pointed
+ at by the second argument should be set to -1. */
+ bool (* fixed_condition_code_regs) (unsigned int *, unsigned int *);
+
+ /* If two condition code modes are compatible, return a condition
+ code mode which is compatible with both, such that a comparison
+ done in the returned mode will work for both of the original
+ modes. If the condition code modes are not compatible, return
+ VOIDmode. */
+ enum machine_mode (* cc_modes_compatible) (enum machine_mode,
+ enum machine_mode);
+
+ /* Do machine-dependent code transformations. Called just before
+ delayed-branch scheduling. */
+ void (* machine_dependent_reorg) (void);
+
+ /* Create the __builtin_va_list type. */
+ tree (* build_builtin_va_list) (void);
+
+ /* Validity-checking routines for PCH files, target-specific.
+ get_pch_validity returns a pointer to the data to be stored,
+ and stores the size in its argument. pch_valid_p gets the same
+ information back and returns NULL if the PCH is valid,
+ or an error message if not.
+ */
+ void * (* get_pch_validity) (size_t *);
+ const char * (* pch_valid_p) (const void *, size_t);
+
+ /* Functions relating to calls - argument passing, returns, etc. */
+ struct calls {
+ bool (*promote_function_args) (tree fntype);
+ bool (*promote_function_return) (tree fntype);
+ bool (*promote_prototypes) (tree fntype);
+ rtx (*struct_value_rtx) (tree fndecl, int incoming);
+ bool (*return_in_memory) (tree type, tree fndecl);
+ bool (*return_in_msb) (tree type);
+ rtx (*expand_builtin_saveregs) (void);
+ /* Returns pretend_argument_size. */
+ void (*setup_incoming_varargs) (CUMULATIVE_ARGS *ca, enum machine_mode mode,
+ tree type, int *pretend_arg_size,
+ int second_time);
+ bool (*strict_argument_naming) (CUMULATIVE_ARGS *ca);
+ /* Returns true if we should use SETUP_INCOMING_VARARGS and/or
+ targetm.calls.strict_argument_naming(). */
+ bool (*pretend_outgoing_varargs_named) (CUMULATIVE_ARGS *ca);
+
+ /* Given a complex type T, return true if a parameter of type T
+ should be passed as two scalars. */
+ bool (* split_complex_arg) (tree type);
+ } calls;
/* Leave the boolean fields at the end. */
@@ -296,6 +450,16 @@ struct gcc_target
/* True if EH frame info sections should be zero-terminated. */
bool terminate_dw2_eh_frame_info;
+
+ /* True if #NO_APP should be emitted at the beginning of
+ assembly output. */
+ bool file_start_app_off;
+
+ /* True if output_file_directive should be called for main_input_filename
+ at the beginning of assembly output. */
+ bool file_start_file_directive;
+
+ /* Leave the boolean fields at the end. */
};
extern struct gcc_target targetm;
diff --git a/contrib/gcc/targhooks.c b/contrib/gcc/targhooks.c
new file mode 100644
index 000000000000..308ada6057c0
--- /dev/null
+++ b/contrib/gcc/targhooks.c
@@ -0,0 +1,213 @@
+/* Default target hook functions.
+ Copyright (C) 2003, 2004 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* The migration of target macros to target hooks works as follows:
+
+ 1. Create a target hook that uses the existing target macros to
+ implement the same functionality.
+
+ 2. Convert all the MI files to use the hook instead of the macro.
+
+ 3. Repeat for a majority of the remaining target macros. This will
+ take some time.
+
+ 4. Tell target maintainers to start migrating.
+
+ 5. Eventually convert the backends to override the hook instead of
+ defining the macros. This will take some time too.
+
+ 6. TBD when, poison the macros. Unmigrated targets will break at
+ this point.
+
+ Note that we expect steps 1-3 to be done by the people that
+ understand what the MI does with each macro, and step 5 to be done
+ by the target maintainers for their respective targets.
+
+ Note that steps 1 and 2 don't have to be done together, but no
+ target can override the new hook until step 2 is complete for it.
+
+ Once the macros are poisoned, we will revert to the old migration
+ rules - migrate the macro, callers, and targets all at once. This
+ comment can thus be removed at that point. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "machmode.h"
+#include "rtl.h"
+#include "tree.h"
+#include "expr.h"
+#include "output.h"
+#include "toplev.h"
+#include "function.h"
+#include "target.h"
+#include "tm_p.h"
+#include "target-def.h"
+
+void
+default_external_libcall (rtx fun ATTRIBUTE_UNUSED)
+{
+#ifdef ASM_OUTPUT_EXTERNAL_LIBCALL
+ ASM_OUTPUT_EXTERNAL_LIBCALL(asm_out_file, fun);
+#endif
+}
+
+enum machine_mode
+default_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
+{
+ if (m1 == m2)
+ return m1;
+ return VOIDmode;
+}
+
+bool
+default_promote_function_args (tree fntype ATTRIBUTE_UNUSED)
+{
+#ifdef PROMOTE_FUNCTION_ARGS
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool
+default_promote_function_return (tree fntype ATTRIBUTE_UNUSED)
+{
+#ifdef PROMOTE_FUNCTION_RETURN
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool
+default_promote_prototypes (tree fntype ATTRIBUTE_UNUSED)
+{
+ if (PROMOTE_PROTOTYPES)
+ return true;
+ else
+ return false;
+}
+
+rtx
+default_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED, int incoming)
+{
+ rtx rv = 0;
+ if (incoming)
+ {
+#ifdef STRUCT_VALUE_INCOMING
+ rv = STRUCT_VALUE_INCOMING;
+#else
+#ifdef STRUCT_VALUE
+ rv = STRUCT_VALUE;
+#else
+#ifndef STRUCT_VALUE_REGNUM
+ abort();
+#else
+ rv = gen_rtx_REG (Pmode, STRUCT_VALUE_REGNUM);
+#endif
+#endif
+#endif
+ }
+ else
+ {
+#ifdef STRUCT_VALUE
+ rv = STRUCT_VALUE;
+#else
+#ifndef STRUCT_VALUE_REGNUM
+ abort();
+#else
+ rv = gen_rtx_REG (Pmode, STRUCT_VALUE_REGNUM);
+#endif
+#endif
+ }
+ return rv;
+}
+
+bool
+default_return_in_memory (tree type,
+ tree fntype ATTRIBUTE_UNUSED)
+{
+#ifndef RETURN_IN_MEMORY
+ return (TYPE_MODE (type) == BLKmode);
+#else
+ return RETURN_IN_MEMORY (type);
+#endif
+}
+
+rtx
+default_expand_builtin_saveregs (void)
+{
+#ifdef EXPAND_BUILTIN_SAVEREGS
+ return EXPAND_BUILTIN_SAVEREGS ();
+#else
+ error ("__builtin_saveregs not supported by this target");
+ return const0_rtx;
+#endif
+}
+
+void
+default_setup_incoming_varargs (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED,
+ tree type ATTRIBUTE_UNUSED,
+ int *pretend_arg_size ATTRIBUTE_UNUSED,
+ int second_time ATTRIBUTE_UNUSED)
+{
+#ifdef SETUP_INCOMING_VARARGS
+ SETUP_INCOMING_VARARGS ((*ca), mode, type, (*pretend_arg_size), second_time);
+#endif
+}
+
+bool
+default_strict_argument_naming (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
+{
+#ifdef STRICT_ARGUMENT_NAMING
+ return STRICT_ARGUMENT_NAMING;
+#else
+ return 0;
+#endif
+}
+
+bool
+default_pretend_outgoing_varargs_named(CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
+{
+#ifdef SETUP_INCOMING_VARARGS
+ return 1;
+#else
+ return (targetm.calls.setup_incoming_varargs != default_setup_incoming_varargs);
+#endif
+}
+
+/* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true. */
+
+bool
+hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED)
+{
+ return true;
+}
+
+/* Generic hook that takes a machine mode and returns true. */
+
+bool
+hook_bool_machine_mode_true (enum machine_mode a ATTRIBUTE_UNUSED)
+{
+ return true;
+}
diff --git a/contrib/gcc/targhooks.h b/contrib/gcc/targhooks.h
new file mode 100644
index 000000000000..63525fe04b70
--- /dev/null
+++ b/contrib/gcc/targhooks.h
@@ -0,0 +1,39 @@
+/* Default target hook functions.
+ Copyright (C) 2003, 2004 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+extern void default_external_libcall (rtx);
+
+extern enum machine_mode default_cc_modes_compatible (enum machine_mode,
+ enum machine_mode);
+
+extern bool default_promote_function_args (tree);
+extern bool default_promote_function_return (tree);
+extern bool default_promote_prototypes (tree);
+
+extern rtx default_struct_value_rtx (tree, int);
+extern bool default_return_in_memory (tree, tree);
+
+extern rtx default_expand_builtin_saveregs (void);
+extern void default_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int);
+extern bool default_strict_argument_naming (CUMULATIVE_ARGS *);
+extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *);
+
+extern bool hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS *);
+extern bool hook_bool_machine_mode_true (enum machine_mode);
diff --git a/contrib/gcc/timevar.c b/contrib/gcc/timevar.c
index 47f2a68b89aa..9746488c649b 100644
--- a/contrib/gcc/timevar.c
+++ b/contrib/gcc/timevar.c
@@ -1,5 +1,5 @@
/* Timing variables for measuring compiler performance.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
Contributed by Alex Samuel <samuel@codesourcery.com>
This file is part of GCC.
@@ -21,15 +21,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
-#include "intl.h"
-#include "rtl.h"
-
#ifdef HAVE_SYS_TIMES_H
# include <sys/times.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
+#include "coretypes.h"
+#include "tm.h"
+#include "intl.h"
+#include "rtl.h"
+#include "toplev.h"
#ifndef HAVE_CLOCK_T
typedef int clock_t;
@@ -45,16 +47,6 @@ struct tms
};
#endif
-#if defined HAVE_DECL_GETRUSAGE && !HAVE_DECL_GETRUSAGE
-extern int getrusage PARAMS ((int, struct rusage *));
-#endif
-#if defined HAVE_DECL_TIMES && !HAVE_DECL_TIMES
-extern clock_t times PARAMS ((struct tms *));
-#endif
-#if defined HAVE_DECL_CLOCK && !HAVE_DECL_CLOCK
-extern clock_t clock PARAMS ((void));
-#endif
-
#ifndef RUSAGE_SELF
# define RUSAGE_SELF 0
#endif
@@ -78,17 +70,26 @@ extern clock_t clock PARAMS ((void));
/* Prefer times to getrusage to clock (each gives successively less
information). */
#ifdef HAVE_TIMES
+# if defined HAVE_DECL_TIMES && !HAVE_DECL_TIMES
+ extern clock_t times (struct tms *);
+# endif
# define USE_TIMES
# define HAVE_USER_TIME
# define HAVE_SYS_TIME
# define HAVE_WALL_TIME
#else
#ifdef HAVE_GETRUSAGE
+# if defined HAVE_DECL_GETRUSAGE && !HAVE_DECL_GETRUSAGE
+ extern int getrusage (int, struct rusage *);
+# endif
# define USE_GETRUSAGE
# define HAVE_USER_TIME
# define HAVE_SYS_TIME
#else
#ifdef HAVE_CLOCK
+# if defined HAVE_DECL_CLOCK && !HAVE_DECL_CLOCK
+ extern clock_t clock (void);
+# endif
# define USE_CLOCK
# define HAVE_USER_TIME
#endif
@@ -100,23 +101,21 @@ extern clock_t clock PARAMS ((void));
precompute them. Whose wonderful idea was it to make all those
_constants_ variable at run time, anyway? */
#ifdef USE_TIMES
-static float ticks_to_msec;
-#define TICKS_TO_MSEC (1 / (float)TICKS_PER_SECOND)
+static double ticks_to_msec;
+#define TICKS_TO_MSEC (1 / (double)TICKS_PER_SECOND)
#endif
#ifdef USE_CLOCK
-static float clocks_to_msec;
-#define CLOCKS_TO_MSEC (1 / (float)CLOCKS_PER_SEC)
+static double clocks_to_msec;
+#define CLOCKS_TO_MSEC (1 / (double)CLOCKS_PER_SEC)
#endif
#include "flags.h"
#include "timevar.h"
-#include "toplev.h"
-/* See timevar.h for an explanation of timing variables. */
+static bool timevar_enable;
-/* This macro evaluates to nonzero if timing variables are enabled. */
-#define TIMEVAR_ENABLE (time_report)
+/* See timevar.h for an explanation of timing variables. */
/* A timing variable. */
@@ -132,11 +131,11 @@ struct timevar_def
/* The name of this timing variable. */
const char *name;
- /* Non-zero if this timing variable is running as a standalone
+ /* Nonzero if this timing variable is running as a standalone
timer. */
unsigned standalone : 1;
- /* Non-zero if this timing variable was ever started or pushed onto
+ /* Nonzero if this timing variable was ever started or pushed onto
the timing stack. */
unsigned used : 1;
};
@@ -169,25 +168,23 @@ static struct timevar_stack_def *unused_stack_instances;
element. */
static struct timevar_time_def start_time;
-static void get_time
- PARAMS ((struct timevar_time_def *));
-static void timevar_accumulate
- PARAMS ((struct timevar_time_def *, struct timevar_time_def *,
- struct timevar_time_def *));
+static void get_time (struct timevar_time_def *);
+static void timevar_accumulate (struct timevar_time_def *,
+ struct timevar_time_def *,
+ struct timevar_time_def *);
/* Fill the current times into TIME. The definition of this function
also defines any or all of the HAVE_USER_TIME, HAVE_SYS_TIME, and
HAVE_WALL_TIME macros. */
static void
-get_time (now)
- struct timevar_time_def *now;
+get_time (struct timevar_time_def *now)
{
now->user = 0;
now->sys = 0;
now->wall = 0;
- if (!TIMEVAR_ENABLE)
+ if (!timevar_enable)
return;
{
@@ -212,10 +209,9 @@ get_time (now)
/* Add the difference between STOP_TIME and START_TIME to TIMER. */
static void
-timevar_accumulate (timer, start_time, stop_time)
- struct timevar_time_def *timer;
- struct timevar_time_def *start_time;
- struct timevar_time_def *stop_time;
+timevar_accumulate (struct timevar_time_def *timer,
+ struct timevar_time_def *start_time,
+ struct timevar_time_def *stop_time)
{
timer->user += stop_time->user - start_time->user;
timer->sys += stop_time->sys - start_time->sys;
@@ -225,13 +221,12 @@ timevar_accumulate (timer, start_time, stop_time)
/* Initialize timing variables. */
void
-init_timevar ()
+timevar_init (void)
{
- if (!TIMEVAR_ENABLE)
- return;
+ timevar_enable = true;
/* Zero all elapsed times. */
- memset ((void *) timevars, 0, sizeof (timevars));
+ memset (timevars, 0, sizeof (timevars));
/* Initialize the names of timing variables. */
#define DEFTIMEVAR(identifier__, name__) \
@@ -255,14 +250,13 @@ init_timevar ()
TIMEVAR cannot be running as a standalone timer. */
void
-timevar_push (timevar)
- timevar_id_t timevar;
+timevar_push (timevar_id_t timevar)
{
struct timevar_def *tv = &timevars[timevar];
struct timevar_stack_def *context;
struct timevar_time_def now;
- if (!TIMEVAR_ENABLE)
+ if (!timevar_enable)
return;
/* Mark this timing variable as used. */
@@ -292,8 +286,7 @@ timevar_push (timevar)
unused_stack_instances = unused_stack_instances->next;
}
else
- context = (struct timevar_stack_def *)
- xmalloc (sizeof (struct timevar_stack_def));
+ context = xmalloc (sizeof (struct timevar_stack_def));
/* Fill it in and put it on the stack. */
context->timevar = tv;
@@ -308,13 +301,12 @@ timevar_push (timevar)
timing variable. */
void
-timevar_pop (timevar)
- timevar_id_t timevar;
+timevar_pop (timevar_id_t timevar)
{
struct timevar_time_def now;
struct timevar_stack_def *popped = stack;
- if (!TIMEVAR_ENABLE)
+ if (!timevar_enable)
return;
if (&timevars[timevar] != stack->timevar)
@@ -348,12 +340,11 @@ timevar_pop (timevar)
attributed to TIMEVAR. */
void
-timevar_start (timevar)
- timevar_id_t timevar;
+timevar_start (timevar_id_t timevar)
{
struct timevar_def *tv = &timevars[timevar];
- if (!TIMEVAR_ENABLE)
+ if (!timevar_enable)
return;
/* Mark this timing variable as used. */
@@ -372,13 +363,12 @@ timevar_start (timevar)
is attributed to it. */
void
-timevar_stop (timevar)
- timevar_id_t timevar;
+timevar_stop (timevar_id_t timevar)
{
struct timevar_def *tv = &timevars[timevar];
struct timevar_time_def now;
- if (!TIMEVAR_ENABLE)
+ if (!timevar_enable)
return;
/* TIMEVAR must have been started via timevar_start. */
@@ -393,9 +383,7 @@ timevar_stop (timevar)
update-to-date information even if TIMEVAR is currently running. */
void
-timevar_get (timevar, elapsed)
- timevar_id_t timevar;
- struct timevar_time_def *elapsed;
+timevar_get (timevar_id_t timevar, struct timevar_time_def *elapsed)
{
struct timevar_def *tv = &timevars[timevar];
struct timevar_time_def now;
@@ -421,8 +409,7 @@ timevar_get (timevar, elapsed)
for normalizing the others, and is displayed last. */
void
-timevar_print (fp)
- FILE *fp;
+timevar_print (FILE *fp)
{
/* Only print stuff if we have some sort of time information. */
#if defined (HAVE_USER_TIME) || defined (HAVE_SYS_TIME) || defined (HAVE_WALL_TIME)
@@ -430,7 +417,7 @@ timevar_print (fp)
struct timevar_time_def *total = &timevars[TV_TOTAL].elapsed;
struct timevar_time_def now;
- if (!TIMEVAR_ENABLE)
+ if (!timevar_enable)
return;
/* Update timing information in case we're calling this from GDB. */
@@ -454,7 +441,7 @@ timevar_print (fp)
for (id = 0; id < (unsigned int) TIMEVAR_LAST; ++id)
{
struct timevar_def *tv = &timevars[(timevar_id_t) id];
- const float tiny = 5e-3;
+ const double tiny = 5e-3;
/* Don't print the total execution time here; that goes at the
end. */
@@ -515,24 +502,11 @@ timevar_print (fp)
|| defined (HAVE_WALL_TIME) */
}
-/* Returns time (user + system) used so far by the compiler process,
- in microseconds. */
-
-long
-get_run_time ()
-{
- struct timevar_time_def total_elapsed;
- timevar_get (TV_TOTAL, &total_elapsed);
- return total_elapsed.user + total_elapsed.sys;
-}
-
/* Prints a message to stderr stating that time elapsed in STR is
TOTAL (given in microseconds). */
void
-print_time (str, total)
- const char *str;
- long total;
+print_time (const char *str, long total)
{
long all_time = get_run_time ();
fprintf (stderr,
diff --git a/contrib/gcc/timevar.def b/contrib/gcc/timevar.def
index d26f10a6599f..6fab782c0527 100644
--- a/contrib/gcc/timevar.def
+++ b/contrib/gcc/timevar.def
@@ -1,6 +1,6 @@
/* This file contains the definitions for timing variables used to
measure run-time performance of the compiler.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Alex Samuel <samuel@codesourcery.com>
This file is part of GCC.
@@ -39,6 +39,8 @@ DEFTIMEVAR (TV_GC , "garbage collection")
/* Time spent generating dump files. */
DEFTIMEVAR (TV_DUMP , "dump files")
+DEFTIMEVAR (TV_CGRAPH , "callgraph construction")
+DEFTIMEVAR (TV_CGRAPHOPT , "callgraph optimization")
/* Time spent by constructing CFG. */
DEFTIMEVAR (TV_CFG , "cfg construction")
/* Time spent by cleaning up CFG. */
@@ -47,6 +49,10 @@ DEFTIMEVAR (TV_DELETE_TRIVIALLY_DEAD , "trivially dead code")
/* Time spent by life analysis. */
DEFTIMEVAR (TV_LIFE , "life analysis")
DEFTIMEVAR (TV_LIFE_UPDATE , "life info update")
+
+DEFTIMEVAR (TV_ALIAS_ANALYSIS , "alias analysis")
+DEFTIMEVAR (TV_REG_SCAN , "register scan")
+DEFTIMEVAR (TV_REBUILD_JUMP , "rebuild jump labels")
/* Timing in various stages of the compiler. */
DEFTIMEVAR (TV_CPP , "preprocessing")
DEFTIMEVAR (TV_LEX , "lexical analysis")
@@ -61,9 +67,12 @@ DEFTIMEVAR (TV_JUMP , "jump")
DEFTIMEVAR (TV_CSE , "CSE")
DEFTIMEVAR (TV_GCSE , "global CSE")
DEFTIMEVAR (TV_LOOP , "loop analysis")
+DEFTIMEVAR (TV_BYPASS , "bypass jumps")
DEFTIMEVAR (TV_TRACER , "tracer")
+DEFTIMEVAR (TV_WEB , "web")
DEFTIMEVAR (TV_CSE2 , "CSE 2")
DEFTIMEVAR (TV_BRANCH_PROB , "branch prediction")
+DEFTIMEVAR (TV_VPT , "value profile opts")
DEFTIMEVAR (TV_FLOW , "flow analysis")
DEFTIMEVAR (TV_COMBINE , "combiner")
DEFTIMEVAR (TV_IFCVT , "if-conversion")
@@ -83,10 +92,6 @@ DEFTIMEVAR (TV_DBR_SCHED , "delay branch sched")
DEFTIMEVAR (TV_REORDER_BLOCKS , "reorder blocks")
DEFTIMEVAR (TV_SHORTEN_BRANCH , "shorten branches")
DEFTIMEVAR (TV_REG_STACK , "reg stack")
-DEFTIMEVAR (TV_TO_SSA , "convert to SSA")
-DEFTIMEVAR (TV_SSA_CCP , "SSA CCP")
-DEFTIMEVAR (TV_SSA_DCE , "SSA aggressive DCE")
-DEFTIMEVAR (TV_FROM_SSA , "convert from SSA")
DEFTIMEVAR (TV_FINAL , "final")
DEFTIMEVAR (TV_SYMOUT , "symout")
diff --git a/contrib/gcc/timevar.h b/contrib/gcc/timevar.h
index dcf1701aef9f..6f40ec0abd97 100644
--- a/contrib/gcc/timevar.h
+++ b/contrib/gcc/timevar.h
@@ -1,5 +1,5 @@
/* Timing variables for measuring compiler performance.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003 Free Software Foundation, Inc.
Contributed by Alex Samuel <samuel@codesourcery.com>
This file is part of GCC.
@@ -53,14 +53,14 @@
struct timevar_time_def
{
/* User time in this process. */
- float user;
+ double user;
/* System time (if applicable for this host platform) in this
process. */
- float sys;
+ double sys;
/* Wall clock time. */
- float wall;
+ double wall;
};
/* An enumeration of timing variable identifiers. Constructed from
@@ -79,16 +79,15 @@ timevar_id_t;
/* Execute the sequence: timevar_pop (TV), return (E); */
#define POP_TIMEVAR_AND_RETURN(TV, E) return (timevar_pop (TV), (E))
-extern void init_timevar PARAMS ((void));
-extern void timevar_push PARAMS ((timevar_id_t));
-extern void timevar_pop PARAMS ((timevar_id_t));
-extern void timevar_start PARAMS ((timevar_id_t));
-extern void timevar_stop PARAMS ((timevar_id_t));
-extern void timevar_get PARAMS ((timevar_id_t, struct timevar_time_def *));
-extern void timevar_print PARAMS ((FILE *));
+extern void timevar_init (void);
+extern void timevar_push (timevar_id_t);
+extern void timevar_pop (timevar_id_t);
+extern void timevar_start (timevar_id_t);
+extern void timevar_stop (timevar_id_t);
+extern void timevar_get (timevar_id_t, struct timevar_time_def *);
+extern void timevar_print (FILE *);
/* Provided for backward compatibility. */
-extern long get_run_time PARAMS ((void));
-extern void print_time PARAMS ((const char *, long));
+extern void print_time (const char *, long);
#endif /* ! GCC_TIMEVAR_H */
diff --git a/contrib/gcc/tlink.c b/contrib/gcc/tlink.c
index f1ad176a6d25..6406615b5e3e 100644
--- a/contrib/gcc/tlink.c
+++ b/contrib/gcc/tlink.c
@@ -1,7 +1,8 @@
/* Scan linker error messages for missing template instantiations and provide
them.
- Copyright (C) 1995, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1998, 1999, 2000, 2001, 2003
+ Free Software Foundation, Inc.
Contributed by Jason Merrill (jason@cygnus.com).
This file is part of GCC.
@@ -23,6 +24,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "intl.h"
#include "obstack.h"
#include "hashtab.h"
@@ -65,13 +68,11 @@ typedef struct demangled_hash_entry
/* Hash and comparison functions for these hash tables. */
-static int hash_string_eq PARAMS ((const void *, const void *));
-static hashval_t hash_string_hash PARAMS ((const void *));
+static int hash_string_eq (const void *, const void *);
+static hashval_t hash_string_hash (const void *);
static int
-hash_string_eq (s1_p, s2_p)
- const void *s1_p;
- const void *s2_p;
+hash_string_eq (const void *s1_p, const void *s2_p)
{
const char *const *s1 = (const char *const *) s1_p;
const char *s2 = (const char *) s2_p;
@@ -79,8 +80,7 @@ hash_string_eq (s1_p, s2_p)
}
static hashval_t
-hash_string_hash (s_p)
- const void *s_p;
+hash_string_hash (const void *s_p)
{
const char *const *s = (const char *const *) s_p;
return (*htab_hash_string) (*s);
@@ -88,37 +88,33 @@ hash_string_hash (s_p)
static htab_t symbol_table;
-static struct symbol_hash_entry * symbol_hash_lookup PARAMS ((const char *,
- int));
-static struct file_hash_entry * file_hash_lookup PARAMS ((const char *));
-static struct demangled_hash_entry *
- demangled_hash_lookup PARAMS ((const char *, int));
-static void symbol_push PARAMS ((symbol *));
-static symbol * symbol_pop PARAMS ((void));
-static void file_push PARAMS ((file *));
-static file * file_pop PARAMS ((void));
-static void tlink_init PARAMS ((void));
-static int tlink_execute PARAMS ((const char *, char **, const char *));
-static char * frob_extension PARAMS ((const char *, const char *));
-static char * obstack_fgets PARAMS ((FILE *, struct obstack *));
-static char * tfgets PARAMS ((FILE *));
-static char * pfgets PARAMS ((FILE *));
-static void freadsym PARAMS ((FILE *, file *, int));
-static void read_repo_file PARAMS ((file *));
-static void maybe_tweak PARAMS ((char *, file *));
-static int recompile_files PARAMS ((void));
-static int read_repo_files PARAMS ((char **));
-static void demangle_new_symbols PARAMS ((void));
-static int scan_linker_output PARAMS ((const char *));
+static struct symbol_hash_entry * symbol_hash_lookup (const char *, int);
+static struct file_hash_entry * file_hash_lookup (const char *);
+static struct demangled_hash_entry *demangled_hash_lookup (const char *, int);
+static void symbol_push (symbol *);
+static symbol * symbol_pop (void);
+static void file_push (file *);
+static file * file_pop (void);
+static void tlink_init (void);
+static int tlink_execute (const char *, char **, const char *);
+static char * frob_extension (const char *, const char *);
+static char * obstack_fgets (FILE *, struct obstack *);
+static char * tfgets (FILE *);
+static char * pfgets (FILE *);
+static void freadsym (FILE *, file *, int);
+static void read_repo_file (file *);
+static void maybe_tweak (char *, file *);
+static int recompile_files (void);
+static int read_repo_files (char **);
+static void demangle_new_symbols (void);
+static int scan_linker_output (const char *);
/* Look up an entry in the symbol hash table. */
static struct symbol_hash_entry *
-symbol_hash_lookup (string, create)
- const char *string;
- int create;
+symbol_hash_lookup (const char *string, int create)
{
- PTR *e;
+ void **e;
e = htab_find_slot_with_hash (symbol_table, string,
(*htab_hash_string) (string),
create ? INSERT : NO_INSERT);
@@ -138,10 +134,9 @@ static htab_t file_table;
/* Look up an entry in the file hash table. */
static struct file_hash_entry *
-file_hash_lookup (string)
- const char *string;
+file_hash_lookup (const char *string)
{
- PTR *e;
+ void **e;
e = htab_find_slot_with_hash (file_table, string,
(*htab_hash_string) (string),
INSERT);
@@ -159,11 +154,9 @@ static htab_t demangled_table;
/* Look up an entry in the demangled name hash table. */
static struct demangled_hash_entry *
-demangled_hash_lookup (string, create)
- const char *string;
- int create;
+demangled_hash_lookup (const char *string, int create)
{
- PTR *e;
+ void **e;
e = htab_find_slot_with_hash (demangled_table, string,
(*htab_hash_string) (string),
create ? INSERT : NO_INSERT);
@@ -197,10 +190,9 @@ struct obstack file_stack_obstack;
struct file_stack_entry *file_stack;
static void
-symbol_push (p)
- symbol *p;
+symbol_push (symbol *p)
{
- struct symbol_stack_entry *ep = (struct symbol_stack_entry *) obstack_alloc
+ struct symbol_stack_entry *ep = obstack_alloc
(&symbol_stack_obstack, sizeof (struct symbol_stack_entry));
ep->value = p;
ep->next = symbol_stack;
@@ -208,7 +200,7 @@ symbol_push (p)
}
static symbol *
-symbol_pop ()
+symbol_pop (void)
{
struct symbol_stack_entry *ep = symbol_stack;
symbol *p;
@@ -221,15 +213,14 @@ symbol_pop ()
}
static void
-file_push (p)
- file *p;
+file_push (file *p)
{
struct file_stack_entry *ep;
if (p->tweaking)
return;
- ep = (struct file_stack_entry *) obstack_alloc
+ ep = obstack_alloc
(&file_stack_obstack, sizeof (struct file_stack_entry));
ep->value = p;
ep->next = file_stack;
@@ -238,7 +229,7 @@ file_push (p)
}
static file *
-file_pop ()
+file_pop (void)
{
struct file_stack_entry *ep = file_stack;
file *p;
@@ -256,7 +247,7 @@ file_pop ()
/* Initialize the tlink machinery. Called from do_tlink. */
static void
-tlink_init ()
+tlink_init (void)
{
const char *p;
@@ -266,7 +257,7 @@ tlink_init ()
NULL);
demangled_table = htab_create (500, hash_string_hash, hash_string_eq,
NULL);
-
+
obstack_begin (&symbol_stack_obstack, 0);
obstack_begin (&file_stack_obstack, 0);
@@ -284,19 +275,14 @@ tlink_init ()
}
static int
-tlink_execute (prog, argv, redir)
- const char *prog;
- char **argv;
- const char *redir;
+tlink_execute (const char *prog, char **argv, const char *redir)
{
collect_execute (prog, argv, redir);
return collect_wait (prog);
}
static char *
-frob_extension (s, ext)
- const char *s;
- const char *ext;
+frob_extension (const char *s, const char *ext)
{
const char *p = strrchr (s, '/');
if (! p)
@@ -310,9 +296,7 @@ frob_extension (s, ext)
}
static char *
-obstack_fgets (stream, ob)
- FILE *stream;
- struct obstack *ob;
+obstack_fgets (FILE *stream, struct obstack *ob)
{
int c;
while ((c = getc (stream)) != EOF && c != '\n')
@@ -324,15 +308,13 @@ obstack_fgets (stream, ob)
}
static char *
-tfgets (stream)
- FILE *stream;
+tfgets (FILE *stream)
{
return obstack_fgets (stream, &temporary_obstack);
}
static char *
-pfgets (stream)
- FILE *stream;
+pfgets (FILE *stream)
{
return xstrdup (tfgets (stream));
}
@@ -341,15 +323,12 @@ pfgets (stream)
/* Subroutine of read_repo_file. We are reading the repo file for file F,
which is coming in on STREAM, and the symbol that comes next in STREAM
- is offerred, chosen or provided if CHOSEN is 0, 1 or 2, respectively.
+ is offered, chosen or provided if CHOSEN is 0, 1 or 2, respectively.
XXX "provided" is unimplemented, both here and in the compiler. */
static void
-freadsym (stream, f, chosen)
- FILE *stream;
- file *f;
- int chosen;
+freadsym (FILE *stream, file *f, int chosen)
{
symbol *sym;
@@ -389,8 +368,7 @@ freadsym (stream, f, chosen)
/* Read in the repo file denoted by F, and record all its information. */
static void
-read_repo_file (f)
- file *f;
+read_repo_file (file *f)
{
char c;
FILE *stream = fopen (f->key, "r");
@@ -436,9 +414,7 @@ read_repo_file (f)
this one wants to emit it as well. */
static void
-maybe_tweak (line, f)
- char *line;
- file *f;
+maybe_tweak (char *line, file *f)
{
symbol *sym = symbol_hash_lookup (line + 2, false);
@@ -461,7 +437,7 @@ maybe_tweak (line, f)
XXX Should this use collect_execute instead of system? */
static int
-recompile_files ()
+recompile_files (void)
{
file *f;
@@ -517,8 +493,7 @@ recompile_files ()
.rpo files associated with them, and read in the information. */
static int
-read_repo_files (object_lst)
- char **object_lst;
+read_repo_files (char **object_lst)
{
char **object = object_lst;
@@ -550,7 +525,7 @@ read_repo_files (object_lst)
/* Add the demangled forms of any new symbols to the hash table. */
static void
-demangle_new_symbols ()
+demangle_new_symbols (void)
{
symbol *sym;
@@ -571,8 +546,7 @@ demangle_new_symbols ()
adjust the settings for each symbol encountered. */
static int
-scan_linker_output (fname)
- const char *fname;
+scan_linker_output (const char *fname)
{
FILE *stream = fopen (fname, "r");
char *line;
@@ -630,6 +604,12 @@ scan_linker_output (fname)
/* Then try "double quotes". */
else if (p = strchr (oldq, '"'), p)
p++, q = strchr (p, '"');
+ else {
+ /* Then try entire line. */
+ q = strchr (oldq, 0);
+ if (q != oldq)
+ p = (char *)oldq;
+ }
if (p)
{
@@ -694,8 +674,7 @@ scan_linker_output (fname)
to provide missing definitions. Currently ignored. */
void
-do_tlink (ld_argv, object_lst)
- char **ld_argv, **object_lst ATTRIBUTE_UNUSED;
+do_tlink (char **ld_argv, char **object_lst ATTRIBUTE_UNUSED)
{
int exit = tlink_execute ("ld", ld_argv, ldout);
diff --git a/contrib/gcc/toplev.c b/contrib/gcc/toplev.c
index adccdc40361c..4e7a73a205f0 100644
--- a/contrib/gcc/toplev.c
+++ b/contrib/gcc/toplev.c
@@ -1,6 +1,6 @@
-/* Top level of GNU C compiler
+/* Top level of GCC compilers (cc1, cc1plus, etc.)
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -28,6 +28,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#undef FLOAT /* This is for hpux. They should change hpux. */
#undef FFS /* Some systems define this in param.h. */
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include <signal.h>
#ifdef HAVE_SYS_RESOURCE_H
@@ -61,7 +63,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "regs.h"
#include "timevar.h"
#include "diagnostic.h"
-#include "ssa.h"
#include "params.h"
#include "reload.h"
#include "dwarf2asm.h"
@@ -71,6 +72,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "target.h"
#include "langhooks.h"
#include "cfglayout.h"
+#include "cfgloop.h"
+#include "hosthooks.h"
+#include "cgraph.h"
+#include "opts.h"
+#include "coverage.h"
+#include "value-prof.h"
+#include "alloc-pool.h"
#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
#include "dwarf2out.h"
@@ -88,47 +96,80 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "xcoffout.h" /* Needed for external data
declarations for e.g. AIX 4.x. */
#endif
-
+
+#ifndef HAVE_conditional_execution
+#define HAVE_conditional_execution 0
+#endif
+
/* Carry information from ASM_DECLARE_OBJECT_NAME
to ASM_FINISH_DECLARE_OBJECT. */
extern int size_directive_output;
extern tree last_assemble_variable_decl;
-extern void reg_alloc PARAMS ((void));
-
-static void general_init PARAMS ((char *));
-static void parse_options_and_default_flags PARAMS ((int, char **));
-static void do_compile PARAMS ((void));
-static void process_options PARAMS ((void));
-static void backend_init PARAMS ((void));
-static int lang_dependent_init PARAMS ((const char *));
-static void init_asm_output PARAMS ((const char *));
-static void finalize PARAMS ((void));
-
-static void set_target_switch PARAMS ((const char *));
-
-static void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
-static void compile_file PARAMS ((void));
-static void display_help PARAMS ((void));
-static void display_target_options PARAMS ((void));
-
-static void decode_d_option PARAMS ((const char *));
-static int decode_f_option PARAMS ((const char *));
-static int decode_W_option PARAMS ((const char *));
-static int decode_g_option PARAMS ((const char *));
-static unsigned int independent_decode_option PARAMS ((int, char **));
-
-static void print_version PARAMS ((FILE *, const char *));
-static int print_single_switch PARAMS ((FILE *, int, int, const char *,
- const char *, const char *,
- const char *, const char *));
-static void print_switch_values PARAMS ((FILE *, int, int, const char *,
- const char *, const char *));
+extern void reg_alloc (void);
+
+static void general_init (const char *);
+static void do_compile (void);
+static void process_options (void);
+static void backend_init (void);
+static int lang_dependent_init (const char *);
+static void init_asm_output (const char *);
+static void finalize (void);
+
+static void crash_signal (int) ATTRIBUTE_NORETURN;
+static void setup_core_dumping (void);
+static void compile_file (void);
+
+static int print_single_switch (FILE *, int, int, const char *,
+ const char *, const char *,
+ const char *, const char *);
+static void print_switch_values (FILE *, int, int, const char *,
+ const char *, const char *);
+
+/* Rest of compilation helper functions. */
+static bool rest_of_handle_inlining (tree);
+static void rest_of_handle_cse (tree, rtx);
+static void rest_of_handle_cse2 (tree, rtx);
+static void rest_of_handle_gcse (tree, rtx);
+static void rest_of_handle_life (tree, rtx);
+static void rest_of_handle_loop_optimize (tree, rtx);
+static void rest_of_handle_loop2 (tree, rtx);
+static void rest_of_handle_jump_bypass (tree, rtx);
+static void rest_of_handle_sibling_calls (rtx);
+static void rest_of_handle_null_pointer (tree, rtx);
+static void rest_of_handle_addressof (tree, rtx);
+static void rest_of_handle_cfg (tree, rtx);
+static void rest_of_handle_branch_prob (tree, rtx);
+static void rest_of_handle_value_profile_transformations (tree, rtx);
+static void rest_of_handle_if_conversion (tree, rtx);
+static void rest_of_handle_if_after_combine (tree, rtx);
+static void rest_of_handle_tracer (tree, rtx);
+static void rest_of_handle_combine (tree, rtx);
+static void rest_of_handle_regmove (tree, rtx);
+#ifdef INSN_SCHEDULING
+static void rest_of_handle_sched (tree, rtx);
+static void rest_of_handle_sched2 (tree, rtx);
+#endif
+static bool rest_of_handle_new_regalloc (tree, rtx);
+static bool rest_of_handle_old_regalloc (tree, rtx);
+static void rest_of_handle_regrename (tree, rtx);
+static void rest_of_handle_reorder_blocks (tree, rtx);
+#ifdef STACK_REGS
+static void rest_of_handle_stack_regs (tree, rtx);
+#endif
+static void rest_of_handle_machine_reorg (tree, rtx);
+#ifdef DELAY_SLOTS
+static void rest_of_handle_delay_slots (tree, rtx);
+#endif
+static void rest_of_handle_final (tree, rtx);
/* Nonzero to dump debug info whilst parsing (-dy option). */
static int set_yydebug;
+/* True if we don't need a backend (e.g. preprocessing only). */
+static bool no_backend;
+
/* Length of line when printing switch values. */
#define MAX_LINE 75
@@ -136,14 +177,8 @@ static int set_yydebug;
const char *progname;
-/* Copy of arguments to toplev_main. */
-int save_argc;
-char **save_argv;
-
-/* Name of current original source file (what was input to cpp).
- This comes from each #-command in the actual input. */
-
-const char *input_filename;
+/* Copy of argument vector to toplev_main. */
+static const char **save_argv;
/* Name of top-level original source file (what was input to cpp).
This comes from the #-command at the beginning of the actual input.
@@ -151,9 +186,9 @@ const char *input_filename;
const char *main_input_filename;
-/* Current line number in real source file. */
+/* Current position in real source file. */
-int lineno;
+location_t input_location;
/* Nonzero if it is unsafe to create any new pseudo registers. */
int no_new_pseudos;
@@ -191,7 +226,7 @@ int target_flags_explicit;
/* Debug hooks - dependent upon command line options. */
-const struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks;
+const struct gcc_debug_hooks *debug_hooks;
/* Describes a dump file. */
@@ -217,23 +252,24 @@ struct dump_file_info
enum dump_file_index
{
+ DFI_cgraph,
DFI_rtl,
DFI_sibling,
DFI_eh,
DFI_jump,
- DFI_ssa,
- DFI_ssa_ccp,
- DFI_ssa_dce,
- DFI_ussa,
DFI_null,
DFI_cse,
DFI_addressof,
DFI_gcse,
DFI_loop,
+ DFI_bypass,
DFI_cfg,
DFI_bp,
+ DFI_vpt,
DFI_ce1,
DFI_tracer,
+ DFI_loop2,
+ DFI_web,
DFI_cse2,
DFI_life,
DFI_combine,
@@ -245,11 +281,12 @@ enum dump_file_index
DFI_postreload,
DFI_flow2,
DFI_peephole2,
- DFI_rnreg,
DFI_ce3,
+ DFI_rnreg,
+ DFI_bbro,
+ DFI_branch_target_load,
DFI_sched2,
DFI_stack,
- DFI_bbro,
DFI_mach,
DFI_dbr,
DFI_MAX
@@ -260,29 +297,30 @@ enum dump_file_index
Remaining -d letters:
- " o q "
- " H JK OPQ TUV YZ"
+ " e m q "
+ " JK O Q WXY "
*/
static struct dump_file_info dump_file[DFI_MAX] =
{
+ { "cgraph", 'U', 0, 0, 0 },
{ "rtl", 'r', 0, 0, 0 },
{ "sibling", 'i', 0, 0, 0 },
{ "eh", 'h', 0, 0, 0 },
{ "jump", 'j', 0, 0, 0 },
- { "ssa", 'e', 1, 0, 0 },
- { "ssaccp", 'W', 1, 0, 0 },
- { "ssadce", 'X', 1, 0, 0 },
- { "ussa", 'e', 1, 0, 0 }, /* Yes, duplicate enable switch. */
{ "null", 'u', 0, 0, 0 },
{ "cse", 's', 0, 0, 0 },
{ "addressof", 'F', 0, 0, 0 },
{ "gcse", 'G', 1, 0, 0 },
{ "loop", 'L', 1, 0, 0 },
+ { "bypass", 'G', 1, 0, 0 }, /* Yes, duplicate enable switch. */
{ "cfg", 'f', 1, 0, 0 },
{ "bp", 'b', 1, 0, 0 },
+ { "vpt", 'V', 1, 0, 0 },
{ "ce1", 'C', 1, 0, 0 },
{ "tracer", 'T', 1, 0, 0 },
+ { "loop2", 'L', 1, 0, 0 },
+ { "web", 'Z', 0, 0, 0 },
{ "cse2", 't', 1, 0, 0 },
{ "life", 'f', 1, 0, 0 }, /* Yes, duplicate enable switch. */
{ "combine", 'c', 1, 0, 0 },
@@ -294,49 +332,29 @@ static struct dump_file_info dump_file[DFI_MAX] =
{ "postreload", 'o', 1, 0, 0 },
{ "flow2", 'w', 1, 0, 0 },
{ "peephole2", 'z', 1, 0, 0 },
- { "rnreg", 'n', 1, 0, 0 },
{ "ce3", 'E', 1, 0, 0 },
+ { "rnreg", 'n', 1, 0, 0 },
+ { "bbro", 'B', 1, 0, 0 },
+ { "btl", 'd', 1, 0, 0 }, /* Yes, duplicate enable switch. */
{ "sched2", 'R', 1, 0, 0 },
{ "stack", 'k', 1, 0, 0 },
- { "bbro", 'B', 1, 0, 0 },
{ "mach", 'M', 1, 0, 0 },
{ "dbr", 'd', 0, 0, 0 },
};
-static int open_dump_file PARAMS ((enum dump_file_index, tree));
-static void close_dump_file PARAMS ((enum dump_file_index,
- void (*) (FILE *, rtx), rtx));
+static int open_dump_file (enum dump_file_index, tree);
+static void close_dump_file (enum dump_file_index,
+ void (*) (FILE *, rtx), rtx);
/* Other flags saying which kinds of debugging dump have been requested. */
int rtl_dump_and_exit;
int flag_print_asm_name;
-static int version_flag;
-static char *filename;
enum graph_dump_types graph_dump_format;
/* Name for output file of assembly code, specified with -o. */
-char *asm_file_name;
-
-/* Value of the -G xx switch, and whether it was passed or not. */
-int g_switch_value;
-int g_switch_set;
-
-/* Type(s) of debugging information we are producing (if any).
- See flags.h for the definitions of the different possible
- types of debugging information. */
-enum debug_info_type write_symbols = NO_DEBUG;
-
-/* Level of debugging information we are producing. See flags.h
- for the definitions of the different possible levels. */
-enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
-
-/* Nonzero means use GNU-only extensions in the generated symbolic
- debugging information. */
-/* Currently, this only has an effect when write_symbols is set to
- DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG. */
-int use_gnu_debug_info_extensions = 0;
+const char *asm_file_name;
/* Nonzero means do optimizations. -O.
Particular numeric values stand for particular amounts of optimization;
@@ -354,9 +372,6 @@ int optimize = 0;
int optimize_size = 0;
-/* Nonzero if we should exit after parsing options. */
-static int exit_after_options = 0;
-
/* The FUNCTION_DECL for the function currently being compiled,
or 0 if between functions. */
tree current_function_decl;
@@ -369,6 +384,13 @@ tree current_function_func_begin_label;
int flag_eliminate_dwarf2_dups = 0;
+/* Nonzero if doing unused type elimination. */
+
+int flag_eliminate_unused_debug_types = 1;
+
+/* Nonzero means emit debugging information only for symbols which are used. */
+int flag_debug_only_used_symbols = 0;
+
/* Nonzero if generating code to do profiling. */
int profile_flag = 0;
@@ -377,6 +399,13 @@ int profile_flag = 0;
int profile_arc_flag = 0;
+/* Nonzero if value histograms should be measured. */
+
+int flag_profile_values = 0;
+
+/* Nonzero if value histograms should be used to optimize code. */
+int flag_value_profile_transformations = 0;
+
/* Nonzero if generating info for gcov to calculate line test coverage. */
int flag_test_coverage = 0;
@@ -421,11 +450,18 @@ int time_report = 0;
int mem_report = 0;
-/* Non-zero means to collect statistics which might be expensive
+/* Nonzero means to collect statistics which might be expensive
and to print them when we are done. */
int flag_detailed_statistics = 0;
-
+/* A random sequence of characters, unless overridden by user. */
+const char *flag_random_seed;
+
+/* A local time stamp derived from the time of compilation. It will be
+ zero if the system cannot provide a time. It will be -1u, if the
+ user has specified a particular random seed. */
+unsigned local_tick;
+
/* -f flags. */
/* Nonzero means `char' should be signed. */
@@ -440,11 +476,7 @@ int flag_short_enums;
be saved across function calls, if that produces overall better code.
Optional now, so people can test it. */
-#ifdef DEFAULT_CALLER_SAVES
-int flag_caller_saves = 1;
-#else
int flag_caller_saves = 0;
-#endif
/* Nonzero if structures and unions should be returned in memory.
@@ -506,13 +538,25 @@ int flag_strength_reduce = 0;
UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are
unrolled. */
-int flag_unroll_loops;
+int flag_old_unroll_loops;
/* Nonzero enables loop unrolling in unroll.c. All loops are unrolled.
This is generally not a win. */
+int flag_old_unroll_all_loops;
+
+/* Enables unrolling of simple loops in loop-unroll.c. */
+int flag_unroll_loops;
+
+/* Enables unrolling of all loops in loop-unroll.c. */
int flag_unroll_all_loops;
+/* Nonzero enables loop peeling. */
+int flag_peel_loops;
+
+/* Nonzero enables loop unswitching. */
+int flag_unswitch_loops;
+
/* Nonzero enables prefetch optimizations for arrays in loops. */
int flag_prefetch_loop_arrays;
@@ -584,13 +628,18 @@ int flag_finite_math_only = 0;
/* Zero means that floating-point math operations cannot generate a
(user-visible) trap. This is the case, for example, in nonstop
IEEE 754 arithmetic. Trapping conditions include division by zero,
- overflow, underflow, invalid and inexact, but does not include
+ overflow, underflow, invalid and inexact, but does not include
operations on signaling NaNs (see below). */
int flag_trapping_math = 1;
+/* Nonzero means disable transformations that assume default floating
+ point rounding behavior. */
+
+int flag_rounding_math = 0;
+
/* Nonzero means disable transformations observable by signaling NaNs.
- This option implies that any operation on a IEEE signaling NaN can
+ This option implies that any operation on an IEEE signaling NaN can
generate a (user-visible) trap. */
int flag_signaling_nans = 0;
@@ -601,46 +650,38 @@ int flag_signaling_nans = 0;
int flag_complex_divide_method = 0;
-/* Nonzero means all references through pointers are volatile. */
-
-int flag_volatile;
-
-/* Nonzero means treat all global and extern variables as volatile. */
-
-int flag_volatile_global;
-
-/* Nonzero means treat all static variables as volatile. */
-
-int flag_volatile_static;
-
/* Nonzero means just do syntax checking; don't output anything. */
int flag_syntax_only = 0;
-/* Nonzero means perform global cse. */
+/* Nonzero means performs web construction pass. */
-static int flag_gcse;
+int flag_web;
/* Nonzero means perform loop optimizer. */
-static int flag_loop_optimize;
+int flag_loop_optimize;
/* Nonzero means perform crossjumping. */
-static int flag_crossjumping;
+int flag_crossjumping;
/* Nonzero means perform if conversion. */
-static int flag_if_conversion;
+int flag_if_conversion;
/* Nonzero means perform if conversion after reload. */
-static int flag_if_conversion2;
+int flag_if_conversion2;
/* Nonzero means to use global dataflow analysis to eliminate
useless null pointer tests. */
-static int flag_delete_null_pointer_checks;
+int flag_delete_null_pointer_checks;
+
+/* Nonzero means perform global CSE. */
+
+int flag_gcse = 0;
/* Nonzero means to do the enhanced load motion during gcse, which trys
to hoist loads by not killing them when a store to the same location
@@ -654,10 +695,25 @@ int flag_gcse_lm = 1;
int flag_gcse_sm = 1;
+/* Nonzero if we want to perfrom redundant load after store elimination
+ in gcse. */
+
+int flag_gcse_las = 1;
+
+/* Perform target register optimization before prologue / epilogue
+ threading. */
+
+int flag_branch_target_load_optimize = 0;
+
+/* Perform target register optimization after prologue / epilogue
+ threading and jump2. */
+
+int flag_branch_target_load_optimize2 = 0;
+
/* Nonzero means to rerun cse after loop optimization. This increases
compilation time about 20% and picks up a few more common expressions. */
-static int flag_rerun_cse_after_loop;
+int flag_rerun_cse_after_loop;
/* Nonzero means to run loop optimizations twice. */
@@ -694,7 +750,7 @@ int flag_gen_aux_info = 0;
/* Specified name of aux-info file. */
-static char *aux_info_file_name;
+const char *aux_info_file_name;
/* Nonzero means make the text shared if supported. */
@@ -710,6 +766,17 @@ int flag_delayed_branch;
int flag_pic;
+/* Nonzero if we are compiling position independent code for executable.
+ The value is 1 if we are doing "small" pic; value is 2 if we're doing
+ "large" pic. */
+
+int flag_pie;
+
+/* Nonzero if we are compiling code for a shared library, zero for
+ executable. */
+
+int flag_shlib;
+
/* Set to the default thread-local storage (tls) model to use. */
enum tls_model flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
@@ -723,7 +790,8 @@ int flag_exceptions;
int flag_unwind_tables = 0;
-/* Nonzero means generate frame unwind info table exact at each insn boundary */
+/* Nonzero means generate frame unwind info table exact at each insn
+ boundary. */
int flag_asynchronous_unwind_tables = 0;
@@ -745,10 +813,17 @@ int flag_pedantic_errors = 0;
int flag_schedule_insns = 0;
int flag_schedule_insns_after_reload = 0;
+/* When flag_schedule_insns_after_reload is set, use EBB scheduler. */
+int flag_sched2_use_superblocks = 0;
+
+/* When flag_schedule_insns_after_reload is set, construct traces and EBB
+ scheduler. */
+int flag_sched2_use_traces = 0;
+
/* The following flags have effect only for scheduling before register
allocation:
- flag_schedule_interblock means schedule insns accross basic blocks.
+ flag_schedule_interblock means schedule insns across basic blocks.
flag_schedule_speculative means allow speculative motion of non-load insns.
flag_schedule_speculative_load means allow speculative motion of some
load insns.
@@ -760,6 +835,20 @@ int flag_schedule_speculative = 1;
int flag_schedule_speculative_load = 0;
int flag_schedule_speculative_load_dangerous = 0;
+/* The following flags have an effect during scheduling after register
+ allocation:
+
+ flag_sched_stalled_insns means that insns can be moved prematurely from the queue
+ of stalled insns into the ready list.
+
+ flag_sched_stalled_insns_dep controls how many insn groups will be examined
+ for a dependency on a stalled insn that is candidate for premature removal
+ from the queue of stalled insns into the ready list (has an effect only if
+ the flag 'sched_stalled_insns' is set). */
+
+int flag_sched_stalled_insns = 0;
+int flag_sched_stalled_insns_dep = 1;
+
int flag_single_precision_constant;
/* flag_branch_on_count_reg means try to replace add-1,compare,branch tupple
@@ -794,27 +883,9 @@ int flag_debug_asm = 0;
int flag_dump_rtl_in_asm = 0;
-/* -fgnu-linker specifies use of the GNU linker for initializations.
- (Or, more generally, a linker that handles initializations.)
- -fno-gnu-linker says that collect2 will be used. */
-#ifdef USE_COLLECT2
-int flag_gnu_linker = 0;
-#else
-int flag_gnu_linker = 1;
-#endif
-
/* Nonzero means put zero initialized data in the bss section. */
int flag_zero_initialized_in_bss = 1;
-/* Enable SSA. */
-int flag_ssa = 0;
-
-/* Enable ssa conditional constant propagation. */
-int flag_ssa_ccp = 0;
-
-/* Enable ssa aggressive dead code elimination. */
-int flag_ssa_dce = 0;
-
/* Tag all structures with __attribute__(packed). */
int flag_pack_struct = 0;
@@ -883,6 +954,10 @@ int flag_new_regalloc = 0;
int flag_tracer = 0;
+/* Nonzero if we perform whole unit at a time compilation. */
+
+int flag_unit_at_a_time = 0;
+
/* Values of the -falign-* flags: how much to align labels in code.
0 means `use default', 1 means `don't align'.
For each variable, there is an _log variant which is the power
@@ -904,60 +979,43 @@ int align_functions_log;
minimum function alignment. Zero means no alignment is forced. */
int force_align_functions_log;
-/* Table of supported debugging formats. */
-static const struct
-{
- const char *const arg;
- /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
- constant expression, we use NO_DEBUG in its place. */
- const enum debug_info_type debug_type;
- const int use_extensions_p;
- const char *const description;
-} *da,
-debug_args[] =
-{
- { "", NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
- N_("Generate debugging info in default format") },
- { "gdb", NO_DEBUG, 1, N_("Generate debugging info in default extended format") },
-#ifdef DBX_DEBUGGING_INFO
- { "stabs", DBX_DEBUG, 0, N_("Generate STABS format debug info") },
- { "stabs+", DBX_DEBUG, 1, N_("Generate extended STABS format debug info") },
-#endif
-#ifdef DWARF_DEBUGGING_INFO
- { "dwarf", DWARF_DEBUG, 0, N_("Generate DWARF-1 format debug info") },
- { "dwarf+", DWARF_DEBUG, 1,
- N_("Generate extended DWARF-1 format debug info") },
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
- { "dwarf-2", DWARF2_DEBUG, 0, N_("Generate DWARF-2 debug info") },
-#endif
-#ifdef XCOFF_DEBUGGING_INFO
- { "xcoff", XCOFF_DEBUG, 0, N_("Generate XCOFF format debug info") },
- { "xcoff+", XCOFF_DEBUG, 1, N_("Generate extended XCOFF format debug info") },
-#endif
-#ifdef SDB_DEBUGGING_INFO
- { "coff", SDB_DEBUG, 0, N_("Generate COFF format debug info") },
-#endif
-#ifdef VMS_DEBUGGING_INFO
- { "vms", VMS_DEBUG, 0, N_("Generate VMS format debug info") },
-#endif
- { 0, 0, 0, 0 }
-};
-
typedef struct
{
const char *const string;
int *const variable;
const int on_value;
- const char *const description;
}
lang_independent_options;
+/* Nonzero if signed arithmetic overflow should trap. */
int flag_trapv = 0;
+/* Nonzero if signed arithmetic overflow should wrap around. */
+int flag_wrapv = 0;
+
+/* Nonzero if subexpressions must be evaluated from left-to-right. */
+int flag_evaluation_order = 0;
+
/* Add or remove a leading underscore from user symbols. */
int flag_leading_underscore = -1;
+/* The version of the C++ ABI in use. The following values are
+ allowed:
+
+ 0: The version of the ABI believed most conformant with the
+ C++ ABI specification. This ABI may change as bugs are
+ discovered and fixed. Therefore, 0 will not necessarily
+ indicate the same ABI in different versions of G++.
+
+ 1: The version of the ABI first used in G++ 3.2.
+
+ 2: The version of the ABI first used in G++ 3.4.
+
+ Additional positive integers will be assigned as new versions of
+ the ABI become the default version of the ABI. */
+
+int flag_abi_version = 2;
+
/* The user symbol prefix after having resolved same. */
const char *user_label_prefix;
@@ -977,396 +1035,126 @@ static const param_info lang_independent_params[] = {
static const lang_independent_options f_options[] =
{
- {"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1,
- N_("Perform DWARF2 duplicate elimination") },
- {"float-store", &flag_float_store, 1,
- N_("Do not store floats in registers") },
- {"volatile", &flag_volatile, 1,
- N_("Consider all mem refs through pointers as volatile") },
- {"volatile-global", &flag_volatile_global, 1,
- N_("Consider all mem refs to global data to be volatile") },
- {"volatile-static", &flag_volatile_static, 1,
- N_("Consider all mem refs to static data to be volatile") },
- {"defer-pop", &flag_defer_pop, 1,
- N_("Defer popping functions args from stack until later") },
- {"omit-frame-pointer", &flag_omit_frame_pointer, 1,
- N_("When possible do not generate stack frames") },
- {"optimize-sibling-calls", &flag_optimize_sibling_calls, 1,
- N_("Optimize sibling and tail recursive calls") },
- {"tracer", &flag_tracer, 1,
- N_("Perform superblock formation via tail duplication") },
- {"cse-follow-jumps", &flag_cse_follow_jumps, 1,
- N_("When running CSE, follow jumps to their targets") },
- {"cse-skip-blocks", &flag_cse_skip_blocks, 1,
- N_("When running CSE, follow conditional jumps") },
- {"expensive-optimizations", &flag_expensive_optimizations, 1,
- N_("Perform a number of minor, expensive optimizations") },
- {"thread-jumps", &flag_thread_jumps, 1,
- N_("Perform jump threading optimizations") },
- {"strength-reduce", &flag_strength_reduce, 1,
- N_("Perform strength reduction optimizations") },
- {"unroll-loops", &flag_unroll_loops, 1,
- N_("Perform loop unrolling when iteration count is known") },
- {"unroll-all-loops", &flag_unroll_all_loops, 1,
- N_("Perform loop unrolling for all loops") },
- {"prefetch-loop-arrays", &flag_prefetch_loop_arrays, 1,
- N_("Generate prefetch instructions, if available, for arrays in loops") },
- {"move-all-movables", &flag_move_all_movables, 1,
- N_("Force all loop invariant computations out of loops") },
- {"reduce-all-givs", &flag_reduce_all_givs, 1,
- N_("Strength reduce all loop general induction variables") },
- {"writable-strings", &flag_writable_strings, 1,
- N_("Store strings in writable data section") },
- {"peephole", &flag_no_peephole, 0,
- N_("Enable machine specific peephole optimizations") },
- {"force-mem", &flag_force_mem, 1,
- N_("Copy memory operands into registers before using") },
- {"force-addr", &flag_force_addr, 1,
- N_("Copy memory address constants into regs before using") },
- {"function-cse", &flag_no_function_cse, 0,
- N_("Allow function addresses to be held in registers") },
- {"inline-functions", &flag_inline_functions, 1,
- N_("Integrate simple functions into their callers") },
- {"keep-inline-functions", &flag_keep_inline_functions, 1,
- N_("Generate code for funcs even if they are fully inlined") },
- {"inline", &flag_no_inline, 0,
- N_("Pay attention to the 'inline' keyword") },
- {"keep-static-consts", &flag_keep_static_consts, 1,
- N_("Emit static const variables even if they are not used") },
- {"syntax-only", &flag_syntax_only, 1,
- N_("Check for syntax errors, then stop") },
- {"shared-data", &flag_shared_data, 1,
- N_("Mark data as shared rather than private") },
- {"caller-saves", &flag_caller_saves, 1,
- N_("Enable saving registers around function calls") },
- {"pcc-struct-return", &flag_pcc_struct_return, 1,
- N_("Return 'short' aggregates in memory, not registers") },
- {"reg-struct-return", &flag_pcc_struct_return, 0,
- N_("Return 'short' aggregates in registers") },
- {"delayed-branch", &flag_delayed_branch, 1,
- N_("Attempt to fill delay slots of branch instructions") },
- {"gcse", &flag_gcse, 1,
- N_("Perform the global common subexpression elimination") },
- {"gcse-lm", &flag_gcse_lm, 1,
- N_("Perform enhanced load motion during global subexpression elimination") },
- {"gcse-sm", &flag_gcse_sm, 1,
- N_("Perform store motion after global subexpression elimination") },
- {"loop-optimize", &flag_loop_optimize, 1,
- N_("Perform the loop optimizations") },
- {"crossjumping", &flag_crossjumping, 1,
- N_("Perform cross-jumping optimization") },
- {"if-conversion", &flag_if_conversion, 1,
- N_("Perform conversion of conditional jumps to branchless equivalents") },
- {"if-conversion2", &flag_if_conversion2, 1,
- N_("Perform conversion of conditional jumps to conditional execution") },
- {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
- N_("Run CSE pass after loop optimizations") },
- {"rerun-loop-opt", &flag_rerun_loop_opt, 1,
- N_("Run the loop optimizer twice") },
- {"delete-null-pointer-checks", &flag_delete_null_pointer_checks, 1,
- N_("Delete useless null pointer checks") },
- {"schedule-insns", &flag_schedule_insns, 1,
- N_("Reschedule instructions before register allocation") },
- {"schedule-insns2", &flag_schedule_insns_after_reload, 1,
- N_("Reschedule instructions after register allocation") },
- {"sched-interblock",&flag_schedule_interblock, 1,
- N_("Enable scheduling across basic blocks") },
- {"sched-spec",&flag_schedule_speculative, 1,
- N_("Allow speculative motion of non-loads") },
- {"sched-spec-load",&flag_schedule_speculative_load, 1,
- N_("Allow speculative motion of some loads") },
- {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
- N_("Allow speculative motion of more loads") },
- {"branch-count-reg",&flag_branch_on_count_reg, 1,
- N_("Replace add,compare,branch with branch on count reg") },
- {"pic", &flag_pic, 1,
- N_("Generate position independent code, if possible") },
- {"PIC", &flag_pic, 2, ""},
- {"exceptions", &flag_exceptions, 1,
- N_("Enable exception handling") },
- {"unwind-tables", &flag_unwind_tables, 1,
- N_("Just generate unwind tables for exception handling") },
- {"asynchronous-unwind-tables", &flag_asynchronous_unwind_tables, 1,
- N_("Generate unwind tables exact at each instruction boundary") },
- {"non-call-exceptions", &flag_non_call_exceptions, 1,
- N_("Support synchronous non-call exceptions") },
- {"profile-arcs", &profile_arc_flag, 1,
- N_("Insert arc based program profiling code") },
- {"test-coverage", &flag_test_coverage, 1,
- N_("Create data files needed by gcov") },
- {"branch-probabilities", &flag_branch_probabilities, 1,
- N_("Use profiling information for branch probabilities") },
- {"profile", &profile_flag, 1,
- N_("Enable basic program profiling code") },
- {"reorder-blocks", &flag_reorder_blocks, 1,
- N_("Reorder basic blocks to improve code placement") },
- {"reorder-functions", &flag_reorder_functions, 1,
- N_("Reorder functions to improve code placement") },
- {"rename-registers", &flag_rename_registers, 1,
- N_("Do the register renaming optimization pass") },
- {"cprop-registers", &flag_cprop_registers, 1,
- N_("Do the register copy-propagation optimization pass") },
- {"common", &flag_no_common, 0,
- N_("Do not put uninitialized globals in the common section") },
- {"inhibit-size-directive", &flag_inhibit_size_directive, 1,
- N_("Do not generate .size directives") },
- {"function-sections", &flag_function_sections, 1,
- N_("place each function into its own section") },
- {"data-sections", &flag_data_sections, 1,
- N_("place data items into their own section") },
- {"verbose-asm", &flag_verbose_asm, 1,
- N_("Add extra commentary to assembler output") },
- {"gnu-linker", &flag_gnu_linker, 1,
- N_("Output GNU ld formatted global initializers") },
- {"regmove", &flag_regmove, 1,
- N_("Enables a register move optimization") },
- {"optimize-register-move", &flag_regmove, 1,
- N_("Do the full regmove optimization pass") },
- {"pack-struct", &flag_pack_struct, 1,
- N_("Pack structure members together without holes") },
- {"stack-check", &flag_stack_check, 1,
- N_("Insert stack checking code into the program") },
- {"argument-alias", &flag_argument_noalias, 0,
- N_("Specify that arguments may alias each other & globals") },
- {"argument-noalias", &flag_argument_noalias, 1,
- N_("Assume arguments may alias globals but not each other") },
- {"argument-noalias-global", &flag_argument_noalias, 2,
- N_("Assume arguments do not alias each other or globals") },
- {"strict-aliasing", &flag_strict_aliasing, 1,
- N_("Assume strict aliasing rules apply") },
- {"align-loops", &align_loops, 0,
- N_("Align the start of loops") },
- {"align-jumps", &align_jumps, 0,
- N_("Align labels which are only reached by jumping") },
- {"align-labels", &align_labels, 0,
- N_("Align all labels") },
- {"align-functions", &align_functions, 0,
- N_("Align the start of functions") },
- {"merge-constants", &flag_merge_constants, 1,
- N_("Attempt to merge identical constants across compilation units") },
- {"merge-all-constants", &flag_merge_constants, 2,
- N_("Attempt to merge identical constants and constant variables") },
- {"dump-unnumbered", &flag_dump_unnumbered, 1,
- N_("Suppress output of instruction numbers and line number notes in debugging dumps") },
- {"instrument-functions", &flag_instrument_function_entry_exit, 1,
- N_("Instrument function entry/exit with profiling calls") },
- {"zero-initialized-in-bss", &flag_zero_initialized_in_bss, 1,
- N_("Put zero initialized data in the bss section") },
- {"ssa", &flag_ssa, 1,
- N_("Enable SSA optimizations") },
- {"ssa-ccp", &flag_ssa_ccp, 1,
- N_("Enable SSA conditional constant propagation") },
- {"ssa-dce", &flag_ssa_dce, 1,
- N_("Enable aggressive SSA dead code elimination") },
- {"leading-underscore", &flag_leading_underscore, 1,
- N_("External symbols have a leading underscore") },
- {"ident", &flag_no_ident, 0,
- N_("Process #ident directives") },
- { "peephole2", &flag_peephole2, 1,
- N_("Enables an rtl peephole pass run before sched2") },
- {"finite-math-only", &flag_finite_math_only, 1,
- N_("Assume no NaNs or +-Infs are generated") },
- { "guess-branch-probability", &flag_guess_branch_prob, 1,
- N_("Enables guessing of branch probabilities") },
- {"math-errno", &flag_errno_math, 1,
- N_("Set errno after built-in math functions") },
- {"trapping-math", &flag_trapping_math, 1,
- N_("Floating-point operations can trap") },
- {"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1,
- N_("Allow math optimizations that may violate IEEE or ANSI standards") },
- {"signaling-nans", &flag_signaling_nans, 1,
- N_("Disable optimizations observable by IEEE signaling NaNs") },
- {"bounds-check", &flag_bounds_check, 1,
- N_("Generate code to check bounds before indexing arrays") },
- {"single-precision-constant", &flag_single_precision_constant, 1,
- N_("Convert floating point constant to single precision constant") },
- {"time-report", &time_report, 1,
- N_("Report time taken by each compiler pass at end of run") },
- {"mem-report", &mem_report, 1,
- N_("Report on permanent memory allocation at end of run") },
- { "trapv", &flag_trapv, 1,
- N_("Trap for signed overflow in addition / subtraction / multiplication") },
- { "new-ra", &flag_new_regalloc, 1,
- N_("Use graph coloring register allocation.") },
-};
-
-/* Table of language-specific options. */
-
-static const struct lang_opt
-{
- const char *const option;
- const char *const description;
-}
-documented_lang_options[] =
-{
- /* In order not to overload the --help output, the convention
- used here is to only describe those options which are not
- enabled by default. */
-
- { "-ansi",
- N_("Compile just for ISO C90") },
- { "-std= ",
- N_("Determine language standard") },
-
- { "-fsigned-bitfields", "" },
- { "-funsigned-bitfields",
- N_("Make bit-fields by unsigned by default") },
- { "-fno-signed-bitfields", "" },
- { "-fno-unsigned-bitfields","" },
- { "-fsigned-char",
- N_("Make 'char' be signed by default") },
- { "-funsigned-char",
- N_("Make 'char' be unsigned by default") },
- { "-fno-signed-char", "" },
- { "-fno-unsigned-char", "" },
-
- { "-fasm", "" },
- { "-fno-asm",
- N_("Do not recognize the 'asm' keyword") },
- { "-fbuiltin", "" },
- { "-fno-builtin",
- N_("Do not recognize any built in functions") },
- { "-fhosted",
- N_("Assume normal C execution environment") },
- { "-fno-hosted", "" },
- { "-ffreestanding",
- N_("Assume that standard libraries & main might not exist") },
- { "-fno-freestanding", "" },
- { "-fcond-mismatch",
- N_("Allow different types as args of ? operator") },
- { "-fno-cond-mismatch", "" },
- { "-fdollars-in-identifiers",
- N_("Allow the use of $ inside identifiers") },
- { "-fno-dollars-in-identifiers", "" },
- { "-fpreprocessed", "" },
- { "-fno-preprocessed", "" },
- { "-fshort-double",
- N_("Use the same size for double as for float") },
- { "-fno-short-double", "" },
- { "-fshort-enums",
- N_("Use the smallest fitting integer to hold enums") },
- { "-fno-short-enums", "" },
- { "-fshort-wchar",
- N_("Override the underlying type for wchar_t to `unsigned short'") },
- { "-fno-short-wchar", "" },
-
- { "-Wall",
- N_("Enable most warning messages") },
- { "-Wbad-function-cast",
- N_("Warn about casting functions to incompatible types") },
- { "-Wno-bad-function-cast", "" },
- { "-Wmissing-format-attribute",
- N_("Warn about functions which might be candidates for format attributes") },
- { "-Wno-missing-format-attribute", "" },
- { "-Wcast-qual",
- N_("Warn about casts which discard qualifiers") },
- { "-Wno-cast-qual", "" },
- { "-Wchar-subscripts",
- N_("Warn about subscripts whose type is 'char'") },
- { "-Wno-char-subscripts", "" },
- { "-Wcomment",
- N_("Warn if nested comments are detected") },
- { "-Wno-comment", "" },
- { "-Wcomments",
- N_("Warn if nested comments are detected") },
- { "-Wno-comments", "" },
- { "-Wconversion",
- N_("Warn about possibly confusing type conversions") },
- { "-Wno-conversion", "" },
- { "-Wdiv-by-zero", "" },
- { "-Wno-div-by-zero",
- N_("Do not warn about compile-time integer division by zero") },
- { "-Wfloat-equal",
- N_("Warn about testing equality of floating point numbers") },
- { "-Wno-float-equal", "" },
- { "-Wformat",
- N_("Warn about printf/scanf/strftime/strfmon format anomalies") },
- { "-Wno-format", "" },
- { "-Wformat-extra-args", "" },
- { "-Wno-format-extra-args",
- N_("Don't warn about too many arguments to format functions") },
- { "-Wformat-nonliteral",
- N_("Warn about non-string-literal format strings") },
- { "-Wno-format-nonliteral", "" },
- { "-Wformat-security",
- N_("Warn about possible security problems with format functions") },
- { "-Wno-format-security", "" },
- { "-Wformat-y2k", "" },
- { "-Wno-format-y2k",
- N_("Don't warn about strftime formats yielding 2 digit years") },
- { "-Wimplicit-function-declaration",
- N_("Warn about implicit function declarations") },
- { "-Wno-implicit-function-declaration", "" },
- { "-Werror-implicit-function-declaration", "" },
- { "-Wimplicit-int",
- N_("Warn when a declaration does not specify a type") },
- { "-Wno-implicit-int", "" },
- { "-Wimplicit", "" },
- { "-Wno-implicit", "" },
- { "-Wimport",
- N_("Warn about the use of the #import directive") },
- { "-Wno-import", "" },
- { "-Wlong-long","" },
- { "-Wno-long-long",
- N_("Do not warn about using 'long long' when -pedantic") },
- { "-Wmain",
- N_("Warn about suspicious declarations of main") },
- { "-Wno-main", "" },
- { "-Wmissing-braces",
- N_("Warn about possibly missing braces around initializers") },
- { "-Wno-missing-braces", "" },
- { "-Wmissing-declarations",
- N_("Warn about global funcs without previous declarations") },
- { "-Wno-missing-declarations", "" },
- { "-Wmissing-prototypes",
- N_("Warn about global funcs without prototypes") },
- { "-Wno-missing-prototypes", "" },
- { "-Wmultichar",
- N_("Warn about use of multicharacter literals") },
- { "-Wno-multichar", "" },
- { "-Wnested-externs",
- N_("Warn about externs not at file scope level") },
- { "-Wno-nested-externs", "" },
- { "-Wparentheses",
- N_("Warn about possible missing parentheses") },
- { "-Wno-parentheses", "" },
- { "-Wpointer-arith",
- N_("Warn about function pointer arithmetic") },
- { "-Wno-pointer-arith", "" },
- { "-Wredundant-decls",
- N_("Warn about multiple declarations of the same object") },
- { "-Wno-redundant-decls", "" },
- { "-Wreturn-type",
- N_("Warn whenever a function's return-type defaults to int") },
- { "-Wno-return-type", "" },
- { "-Wsequence-point",
- N_("Warn about possible violations of sequence point rules") },
- { "-Wno-sequence-point", "" },
- { "-Wsign-compare",
- N_("Warn about signed/unsigned comparisons") },
- { "-Wno-sign-compare", "" },
- { "-Wstrict-prototypes",
- N_("Warn about non-prototyped function decls") },
- { "-Wno-strict-prototypes", "" },
- { "-Wtraditional",
- N_("Warn about constructs whose meanings change in ISO C") },
- { "-Wno-traditional", "" },
- { "-Wtrigraphs",
- N_("Warn when trigraphs are encountered") },
- { "-Wno-trigraphs", "" },
- { "-Wundef", "" },
- { "-Wno-undef", "" },
- { "-Wunknown-pragmas",
- N_("Warn about unrecognized pragmas") },
- { "-Wno-unknown-pragmas", "" },
- { "-Wwrite-strings",
- N_("Mark strings as 'const char *'") },
- { "-Wno-write-strings", "" },
-
-#define DEFINE_LANG_NAME(NAME) { NULL, NAME },
-
-#include "options.h"
-
+ {"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1 },
+ {"eliminate-unused-debug-symbols", &flag_debug_only_used_symbols, 1 },
+ {"eliminate-unused-debug-types", &flag_eliminate_unused_debug_types, 1 },
+ {"float-store", &flag_float_store, 1 },
+ {"defer-pop", &flag_defer_pop, 1 },
+ {"omit-frame-pointer", &flag_omit_frame_pointer, 1 },
+ {"optimize-sibling-calls", &flag_optimize_sibling_calls, 1 },
+ {"tracer", &flag_tracer, 1 },
+ {"unit-at-a-time", &flag_unit_at_a_time, 1 },
+ {"cse-follow-jumps", &flag_cse_follow_jumps, 1 },
+ {"cse-skip-blocks", &flag_cse_skip_blocks, 1 },
+ {"expensive-optimizations", &flag_expensive_optimizations, 1 },
+ {"thread-jumps", &flag_thread_jumps, 1 },
+ {"strength-reduce", &flag_strength_reduce, 1 },
+ {"unroll-loops", &flag_unroll_loops, 1 },
+ {"unroll-all-loops", &flag_unroll_all_loops, 1 },
+ {"old-unroll-loops", &flag_old_unroll_loops, 1 },
+ {"old-unroll-all-loops", &flag_old_unroll_all_loops, 1 },
+ {"peel-loops", &flag_peel_loops, 1 },
+ {"unswitch-loops", &flag_unswitch_loops, 1 },
+ {"prefetch-loop-arrays", &flag_prefetch_loop_arrays, 1 },
+ {"move-all-movables", &flag_move_all_movables, 1 },
+ {"reduce-all-givs", &flag_reduce_all_givs, 1 },
+ {"writable-strings", &flag_writable_strings, 1 },
+ {"peephole", &flag_no_peephole, 0 },
+ {"force-mem", &flag_force_mem, 1 },
+ {"force-addr", &flag_force_addr, 1 },
+ {"function-cse", &flag_no_function_cse, 0 },
+ {"inline-functions", &flag_inline_functions, 1 },
+ {"keep-inline-functions", &flag_keep_inline_functions, 1 },
+ {"inline", &flag_no_inline, 0 },
+ {"keep-static-consts", &flag_keep_static_consts, 1 },
+ {"syntax-only", &flag_syntax_only, 1 },
+ {"shared-data", &flag_shared_data, 1 },
+ {"caller-saves", &flag_caller_saves, 1 },
+ {"pcc-struct-return", &flag_pcc_struct_return, 1 },
+ {"reg-struct-return", &flag_pcc_struct_return, 0 },
+ {"delayed-branch", &flag_delayed_branch, 1 },
+ {"web", &flag_web, 1},
+ {"gcse", &flag_gcse, 1 },
+ {"gcse-lm", &flag_gcse_lm, 1 },
+ {"gcse-sm", &flag_gcse_sm, 1 },
+ {"gcse-las", &flag_gcse_las, 1 },
+ {"branch-target-load-optimize", &flag_branch_target_load_optimize, 1 },
+ {"branch-target-load-optimize2", &flag_branch_target_load_optimize2, 1 },
+ {"loop-optimize", &flag_loop_optimize, 1 },
+ {"crossjumping", &flag_crossjumping, 1 },
+ {"if-conversion", &flag_if_conversion, 1 },
+ {"if-conversion2", &flag_if_conversion2, 1 },
+ {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1 },
+ {"rerun-loop-opt", &flag_rerun_loop_opt, 1 },
+ {"delete-null-pointer-checks", &flag_delete_null_pointer_checks, 1 },
+ {"schedule-insns", &flag_schedule_insns, 1 },
+ {"schedule-insns2", &flag_schedule_insns_after_reload, 1 },
+ {"sched-interblock",&flag_schedule_interblock, 1 },
+ {"sched-spec",&flag_schedule_speculative, 1 },
+ {"sched-spec-load",&flag_schedule_speculative_load, 1 },
+ {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1 },
+ {"sched-stalled-insns", &flag_sched_stalled_insns, 0 },
+ {"sched-stalled-insns-dep", &flag_sched_stalled_insns_dep, 1 },
+ {"sched2-use-superblocks", &flag_sched2_use_superblocks, 1 },
+ {"sched2-use-traces", &flag_sched2_use_traces, 1 },
+ {"branch-count-reg",&flag_branch_on_count_reg, 1 },
+ {"pic", &flag_pic, 1 },
+ {"PIC", &flag_pic, 2 },
+ {"pie", &flag_pie, 1 },
+ {"PIE", &flag_pie, 2 },
+ {"exceptions", &flag_exceptions, 1 },
+ {"unwind-tables", &flag_unwind_tables, 1 },
+ {"asynchronous-unwind-tables", &flag_asynchronous_unwind_tables, 1 },
+ {"non-call-exceptions", &flag_non_call_exceptions, 1 },
+ {"profile-arcs", &profile_arc_flag, 1 },
+ {"profile-values", &flag_profile_values, 1 },
+ {"vpt", &flag_value_profile_transformations, 1 },
+ {"test-coverage", &flag_test_coverage, 1 },
+ {"branch-probabilities", &flag_branch_probabilities, 1 },
+ {"profile", &profile_flag, 1 },
+ {"reorder-blocks", &flag_reorder_blocks, 1 },
+ {"reorder-functions", &flag_reorder_functions, 1 },
+ {"rename-registers", &flag_rename_registers, 1 },
+ {"cprop-registers", &flag_cprop_registers, 1 },
+ {"common", &flag_no_common, 0 },
+ {"inhibit-size-directive", &flag_inhibit_size_directive, 1 },
+ {"function-sections", &flag_function_sections, 1 },
+ {"data-sections", &flag_data_sections, 1 },
+ {"verbose-asm", &flag_verbose_asm, 1 },
+ {"regmove", &flag_regmove, 1 },
+ {"optimize-register-move", &flag_regmove, 1 },
+ {"pack-struct", &flag_pack_struct, 1 },
+ {"stack-check", &flag_stack_check, 1 },
+ {"argument-alias", &flag_argument_noalias, 0 },
+ {"argument-noalias", &flag_argument_noalias, 1 },
+ {"argument-noalias-global", &flag_argument_noalias, 2 },
+ {"strict-aliasing", &flag_strict_aliasing, 1 },
+ {"align-loops", &align_loops, 0 },
+ {"align-jumps", &align_jumps, 0 },
+ {"align-labels", &align_labels, 0 },
+ {"align-functions", &align_functions, 0 },
+ {"merge-constants", &flag_merge_constants, 1 },
+ {"merge-all-constants", &flag_merge_constants, 2 },
+ {"dump-unnumbered", &flag_dump_unnumbered, 1 },
+ {"instrument-functions", &flag_instrument_function_entry_exit, 1 },
+ {"zero-initialized-in-bss", &flag_zero_initialized_in_bss, 1 },
+ {"leading-underscore", &flag_leading_underscore, 1 },
+ {"ident", &flag_no_ident, 0 },
+ { "peephole2", &flag_peephole2, 1 },
+ {"finite-math-only", &flag_finite_math_only, 1 },
+ { "guess-branch-probability", &flag_guess_branch_prob, 1 },
+ {"math-errno", &flag_errno_math, 1 },
+ {"trapping-math", &flag_trapping_math, 1 },
+ {"rounding-math", &flag_rounding_math, 1 },
+ {"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1 },
+ {"signaling-nans", &flag_signaling_nans, 1 },
+ {"bounds-check", &flag_bounds_check, 1 },
+ {"single-precision-constant", &flag_single_precision_constant, 1 },
+ {"time-report", &time_report, 1 },
+ {"mem-report", &mem_report, 1 },
+ { "trapv", &flag_trapv, 1 },
+ { "wrapv", &flag_wrapv, 1 },
+ { "new-ra", &flag_new_regalloc, 1 }
};
/* Here is a table, controlled by the tm.h file, listing each -m switch
@@ -1391,214 +1179,112 @@ static const struct
const char *const prefix;
const char **const variable;
const char *const description;
+ const char *const value;
}
target_options[] = TARGET_OPTIONS;
#endif
-
-/* Options controlling warnings. */
-
-/* Don't print warning messages. -w. */
-
-int inhibit_warnings = 0;
-
-/* Don't suppress warnings from system headers. -Wsystem-headers. */
-
-int warn_system_headers = 0;
-
-/* Print various extra warnings. -W. */
-
-int extra_warnings = 0;
-
-/* Treat warnings as errors. -Werror. */
-
-int warnings_are_errors = 0;
-
-/* Nonzero to warn about unused variables, functions et.al. */
-
-int warn_unused_function;
-int warn_unused_label;
-int warn_unused_parameter;
-int warn_unused_variable;
-int warn_unused_value;
-
-/* Nonzero to warn about code which is never reached. */
-
-int warn_notreached;
-
-/* Nonzero to warn about variables used before they are initialized. */
-
-int warn_uninitialized;
-
-/* Nonzero means warn about all declarations which shadow others. */
-
-int warn_shadow;
-
-/* Warn if a switch on an enum, that does not have a default case,
- fails to have a case for every enum value. */
-
-int warn_switch;
-
-/* Warn if a switch does not have a default case. */
-
-int warn_switch_default;
-
-/* Warn if a switch on an enum fails to have a case for every enum
- value (regardless of the presence or otherwise of a default case). */
-
-int warn_switch_enum;
/* Nonzero means warn about function definitions that default the return type
or that use a null return and have a return-type other than void. */
int warn_return_type;
-/* Nonzero means warn about pointer casts that increase the required
- alignment of the target type (and might therefore lead to a crash
- due to a misaligned access). */
-
-int warn_cast_align;
-
-/* Nonzero means warn about any objects definitions whose size is larger
- than N bytes. Also want about function definitions whose returned
- values are larger than N bytes. The value N is in `larger_than_size'. */
-
-int warn_larger_than;
-HOST_WIDE_INT larger_than_size;
-
-/* Nonzero means warn if inline function is too large. */
-
-int warn_inline;
-
-/* Warn if a function returns an aggregate,
- since there are often incompatible calling conventions for doing this. */
-
-int warn_aggregate_return;
-
-/* Warn if packed attribute on struct is unnecessary and inefficient. */
-
-int warn_packed;
-
-/* Warn when gcc pads a structure to an alignment boundary. */
-
-int warn_padded;
-
-/* Warn when an optimization pass is disabled. */
-
-int warn_disabled_optimization;
+/* Output files for assembler code (real compiler output)
+ and debugging dumps. */
-/* Warn about functions which might be candidates for attribute noreturn. */
+FILE *asm_out_file;
+FILE *aux_info_file;
+FILE *rtl_dump_file = NULL;
+FILE *cgraph_dump_file = NULL;
-int warn_missing_noreturn;
+/* The current working directory of a translation. It's generally the
+ directory from which compilation was initiated, but a preprocessed
+ file may specify the original directory in which it was
+ created. */
-/* Nonzero means warn about uses of __attribute__((deprecated))
- declarations. */
+static const char *src_pwd;
-int warn_deprecated_decl = 1;
+/* Initialize src_pwd with the given string, and return true. If it
+ was already initialized, return false. As a special case, it may
+ be called with a NULL argument to test whether src_pwd has NOT been
+ initialized yet. */
-/* Nonzero means warn about constructs which might not be
- strict-aliasing safe. */
+bool
+set_src_pwd (const char *pwd)
+{
+ if (src_pwd)
+ return false;
-int warn_strict_aliasing;
+ src_pwd = xstrdup (pwd);
+ return true;
+}
-/* Likewise for -W. */
+/* Return the directory from which the translation unit was initiated,
+ in case set_src_pwd() was not called before to assign it a
+ different value. */
-static const lang_independent_options W_options[] =
+const char *
+get_src_pwd (void)
{
- {"unused-function", &warn_unused_function, 1,
- N_("Warn when a function is unused") },
- {"unused-label", &warn_unused_label, 1,
- N_("Warn when a label is unused") },
- {"unused-parameter", &warn_unused_parameter, 1,
- N_("Warn when a function parameter is unused") },
- {"unused-variable", &warn_unused_variable, 1,
- N_("Warn when a variable is unused") },
- {"unused-value", &warn_unused_value, 1,
- N_("Warn when an expression value is unused") },
- {"system-headers", &warn_system_headers, 1,
- N_("Do not suppress warnings from system headers") },
- {"error", &warnings_are_errors, 1,
- N_("Treat all warnings as errors") },
- {"shadow", &warn_shadow, 1,
- N_("Warn when one local variable shadows another") },
- {"switch", &warn_switch, 1,
- N_("Warn about enumerated switches, with no default, missing a case") },
- {"switch-default", &warn_switch_default, 1,
- N_("Warn about enumerated switches missing a default case") },
- {"switch-enum", &warn_switch_enum, 1,
- N_("Warn about all enumerated switches missing a specific case") },
- {"aggregate-return", &warn_aggregate_return, 1,
- N_("Warn about returning structures, unions or arrays") },
- {"cast-align", &warn_cast_align, 1,
- N_("Warn about pointer casts which increase alignment") },
- {"unreachable-code", &warn_notreached, 1,
- N_("Warn about code that will never be executed") },
- {"uninitialized", &warn_uninitialized, 1,
- N_("Warn about uninitialized automatic variables") },
- {"inline", &warn_inline, 1,
- N_("Warn when an inlined function cannot be inlined") },
- {"packed", &warn_packed, 1,
- N_("Warn when the packed attribute has no effect on struct layout") },
- {"padded", &warn_padded, 1,
- N_("Warn when padding is required to align struct members") },
- {"disabled-optimization", &warn_disabled_optimization, 1,
- N_("Warn when an optimization pass is disabled") },
- {"deprecated-declarations", &warn_deprecated_decl, 1,
- N_("Warn about uses of __attribute__((deprecated)) declarations") },
- {"missing-noreturn", &warn_missing_noreturn, 1,
- N_("Warn about functions which might be candidates for attribute noreturn") },
- {"strict-aliasing", &warn_strict_aliasing, 1,
- N_ ("Warn about code which might break the strict aliasing rules") }
-};
+ if (! src_pwd)
+ src_pwd = getpwd ();
-void
-set_Wunused (setting)
- int setting;
-{
- warn_unused_function = setting;
- warn_unused_label = setting;
- /* Unused function parameter warnings are reported when either ``-W
- -Wunused'' or ``-Wunused-parameter'' is specified. Differentiate
- -Wunused by setting WARN_UNUSED_PARAMETER to -1. */
- if (!setting)
- warn_unused_parameter = 0;
- else if (!warn_unused_parameter)
- warn_unused_parameter = -1;
- warn_unused_variable = setting;
- warn_unused_value = setting;
+ return src_pwd;
}
-/* The following routines are useful in setting all the flags that
- -ffast-math and -fno-fast-math imply. */
-
+/* Called when the start of a function definition is parsed,
+ this function prints on stderr the name of the function. */
void
-set_fast_math_flags (set)
- int set;
+announce_function (tree decl)
{
- flag_trapping_math = !set;
- flag_unsafe_math_optimizations = set;
- flag_finite_math_only = set;
- flag_errno_math = !set;
- if (set)
- flag_signaling_nans = 0;
+ if (!quiet_flag)
+ {
+ if (rtl_dump_and_exit)
+ verbatim ("%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
+ else
+ verbatim (" %s", (*lang_hooks.decl_printable_name) (decl, 2));
+ fflush (stderr);
+ pp_needs_newline (global_dc->printer) = true;
+ diagnostic_set_last_function (global_dc);
+ }
}
-/* Return true iff flags are set as if -ffast-math. */
-bool
-fast_math_flags_set_p ()
+/* Set up a default flag_random_seed and local_tick, unless the user
+ already specified one. */
+
+static void
+randomize (void)
{
- return (!flag_trapping_math
- && flag_unsafe_math_optimizations
- && flag_finite_math_only
- && !flag_errno_math);
-}
+ if (!flag_random_seed)
+ {
+ unsigned HOST_WIDE_INT value;
+ static char random_seed[HOST_BITS_PER_WIDE_INT / 4 + 3];
-
-/* Output files for assembler code (real compiler output)
- and debugging dumps. */
+ /* Get some more or less random data. */
+#ifdef HAVE_GETTIMEOFDAY
+ {
+ struct timeval tv;
+
+ gettimeofday (&tv, NULL);
+ local_tick = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+ }
+#else
+ {
+ time_t now = time (NULL);
+
+ if (now != (time_t)-1)
+ local_tick = (unsigned) now;
+ }
+#endif
+ value = local_tick ^ getpid ();
+
+ sprintf (random_seed, HOST_WIDE_INT_PRINT_HEX, value);
+ flag_random_seed = random_seed;
+ }
+ else if (!local_tick)
+ local_tick = -1;
+}
-FILE *asm_out_file;
-FILE *aux_info_file;
-FILE *rtl_dump_file = NULL;
/* Decode the string P as an integral parameter.
If the string is indeed an integer return its numeric value else
@@ -1606,10 +1292,7 @@ FILE *rtl_dump_file = NULL;
If PNAME is zero just return DEFVAL, do not call error. */
int
-read_integral_parameter (p, pname, defval)
- const char *p;
- const char *pname;
- const int defval;
+read_integral_parameter (const char *p, const char *pname, const int defval)
{
const char *endp = p;
@@ -1624,40 +1307,20 @@ read_integral_parameter (p, pname, defval)
if (*endp != 0)
{
if (pname != 0)
- error ("invalid option `%s'", pname);
+ error ("invalid option argument `%s'", pname);
return defval;
}
return atoi (p);
}
-
-/* This calls abort and is used to avoid problems when abort is a macro.
- It is used when we need to pass the address of abort. */
-
-void
-do_abort ()
-{
- abort ();
-}
-/* When `malloc.c' is compiled with `rcheck' defined,
- it calls this function to report clobberage. */
-
-void
-botch (s)
- const char *s ATTRIBUTE_UNUSED;
-{
- abort ();
-}
-
/* Return the logarithm of X, base 2, considering X unsigned,
if X is a power of 2. Otherwise, returns -1.
This should be used via the `exact_log2' macro. */
int
-exact_log2_wide (x)
- unsigned HOST_WIDE_INT x;
+exact_log2_wide (unsigned HOST_WIDE_INT x)
{
int log = 0;
/* Test for 0 or a power of 2. */
@@ -1674,8 +1337,7 @@ exact_log2_wide (x)
This should be used via the floor_log2 macro. */
int
-floor_log2_wide (x)
- unsigned HOST_WIDE_INT x;
+floor_log2_wide (unsigned HOST_WIDE_INT x)
{
int log = -1;
while (x != 0)
@@ -1685,24 +1347,46 @@ floor_log2_wide (x)
}
/* Handler for fatal signals, such as SIGSEGV. These are transformed
- into ICE messages, which is much more user friendly. */
+ into ICE messages, which is much more user friendly. In case the
+ error printer crashes, reset the signal to prevent infinite recursion. */
static void
-crash_signal (signo)
- int signo;
+crash_signal (int signo)
{
+ signal (signo, SIG_DFL);
internal_error ("%s", strsignal (signo));
}
+/* Arrange to dump core on error. (The regular error message is still
+ printed first, except in the case of abort().) */
+
+static void
+setup_core_dumping (void)
+{
+#ifdef SIGABRT
+ signal (SIGABRT, SIG_DFL);
+#endif
+#if defined(HAVE_SETRLIMIT)
+ {
+ struct rlimit rlim;
+ if (getrlimit (RLIMIT_CORE, &rlim) != 0)
+ fatal_error ("getting core file size maximum limit: %m");
+ rlim.rlim_cur = rlim.rlim_max;
+ if (setrlimit (RLIMIT_CORE, &rlim) != 0)
+ fatal_error ("setting core file size limit to maximum: %m");
+ }
+#endif
+ diagnostic_abort_on_error (global_dc);
+}
+
+
/* Strip off a legitimate source ending from the input string NAME of
length LEN. Rather than having to know the names used by all of
our front ends, we strip off an ending of a period followed by
up to five characters. (Java uses ".class".) */
void
-strip_off_ending (name, len)
- char *name;
- int len;
+strip_off_ending (char *name, int len)
{
int i;
for (i = 2; i < 6 && len > i; i++)
@@ -1718,9 +1402,7 @@ strip_off_ending (name, len)
/* Output a quoted string. */
void
-output_quoted_string (asm_file, string)
- FILE *asm_file;
- const char *string;
+output_quoted_string (FILE *asm_file, const char *string)
{
#ifdef OUTPUT_QUOTED_STRING
OUTPUT_QUOTED_STRING (asm_file, string);
@@ -1743,33 +1425,19 @@ output_quoted_string (asm_file, string)
#endif
}
-/* Output NAME into FILE after having turned it into something
- usable as an identifier in a target's assembly file. */
-void
-output_clean_symbol_name (file, name)
- FILE *file;
- const char *name;
-{
- /* Make a copy of NAME. */
- char *id = xstrdup (name);
-
- /* Make it look like a valid identifier for an assembler. */
- clean_symbol_name (id);
-
- fputs (id, file);
- free (id);
-}
-
-
/* Output a file name in the form wanted by System V. */
void
-output_file_directive (asm_file, input_name)
- FILE *asm_file;
- const char *input_name;
+output_file_directive (FILE *asm_file, const char *input_name)
{
- int len = strlen (input_name);
- const char *na = input_name + len;
+ int len;
+ const char *na;
+
+ if (input_name == NULL)
+ input_name = "<stdin>";
+
+ len = strlen (input_name);
+ na = input_name + len;
/* NA gets INPUT_NAME sans directory names. */
while (na > input_name)
@@ -1779,9 +1447,6 @@ output_file_directive (asm_file, input_name)
na--;
}
-#ifdef ASM_OUTPUT_MAIN_SOURCE_FILENAME
- ASM_OUTPUT_MAIN_SOURCE_FILENAME (asm_file, na);
-#else
#ifdef ASM_OUTPUT_SOURCE_FILENAME
ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);
#else
@@ -1789,15 +1454,12 @@ output_file_directive (asm_file, input_name)
output_quoted_string (asm_file, na);
fputc ('\n', asm_file);
#endif
-#endif
}
-
+
/* Routine to open a dump file. Return true if the dump file is enabled. */
static int
-open_dump_file (index, decl)
- enum dump_file_index index;
- tree decl;
+open_dump_file (enum dump_file_index index, tree decl)
{
char *dump_name;
const char *open_arg;
@@ -1833,7 +1495,7 @@ open_dump_file (index, decl)
rtl_dump_file = fopen (dump_name, open_arg);
if (rtl_dump_file == NULL)
- fatal_io_error ("can't open %s", dump_name);
+ fatal_error ("can't open %s: %m", dump_name);
free (dump_name);
@@ -1853,10 +1515,9 @@ open_dump_file (index, decl)
/* Routine to close a dump file. */
static void
-close_dump_file (index, func, insns)
- enum dump_file_index index;
- void (*func) PARAMS ((FILE *, rtx));
- rtx insns;
+close_dump_file (enum dump_file_index index,
+ void (*func) (FILE *, rtx),
+ rtx insns)
{
if (! rtl_dump_file)
return;
@@ -1891,9 +1552,7 @@ close_dump_file (index, func, insns)
Returns nonzero if anything was put out. */
int
-wrapup_global_declarations (vec, len)
- tree *vec;
- int len;
+wrapup_global_declarations (tree *vec, int len)
{
tree decl;
int i;
@@ -1905,7 +1564,7 @@ wrapup_global_declarations (vec, len)
decl = vec[i];
/* We're not deferring this any longer. Assignment is
- conditional to avoid needlessly dirtying PCH pages. */
+ conditional to avoid needlessly dirtying PCH pages. */
if (DECL_DEFER_OUTPUT (decl) != 0)
DECL_DEFER_OUTPUT (decl) = 0;
@@ -1955,7 +1614,14 @@ wrapup_global_declarations (vec, len)
{
bool needed = 1;
- if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
+ if (flag_unit_at_a_time
+ && cgraph_varpool_node (decl)->finalized)
+ needed = 0;
+ else if ((flag_unit_at_a_time && !cgraph_global_info_ready)
+ && (TREE_USED (decl)
+ || TREE_USED (DECL_ASSEMBLER_NAME (decl))))
+ /* needed */;
+ else if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
/* needed */;
else if (DECL_COMDAT (decl))
needed = 0;
@@ -1974,6 +1640,7 @@ wrapup_global_declarations (vec, len)
if (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_INITIAL (decl) != 0
&& DECL_SAVED_INSNS (decl) != 0
+ && DECL_SAVED_INSNS (decl)->saved_for_inline
&& (flag_keep_inline_functions
|| (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
@@ -1995,9 +1662,7 @@ wrapup_global_declarations (vec, len)
which there are LEN). Output debugging information for them. */
void
-check_global_declarations (vec, len)
- tree *vec;
- int len;
+check_global_declarations (tree *vec, int len)
{
tree decl;
int i;
@@ -2027,11 +1692,9 @@ check_global_declarations (vec, len)
&& ! TREE_PUBLIC (decl))
{
if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
- pedwarn_with_decl (decl,
- "`%s' used but never defined");
+ pedwarn ("%J'%F' used but never defined", decl, decl);
else
- warning_with_decl (decl,
- "`%s' declared `static' but never defined");
+ warning ("%J'%F' declared `static' but never defined", decl, decl);
/* This symbol is effectively an "extern" declaration now. */
TREE_PUBLIC (decl) = 1;
assemble_external (decl);
@@ -2050,11 +1713,13 @@ check_global_declarations (vec, len)
&& ! TREE_USED (DECL_NAME (decl))
&& ! DECL_EXTERNAL (decl)
&& ! TREE_PUBLIC (decl)
+ /* A volatile variable might be used in some non-obvious way. */
+ && ! TREE_THIS_VOLATILE (decl)
/* Global register variables must be declared to reserve them. */
&& ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))
/* Otherwise, ask the language. */
&& (*lang_hooks.decls.warn_unused_global) (decl))
- warning_with_decl (decl, "`%s' defined but not used");
+ warning ("%J'%D' defined but not used", decl, decl);
/* Avoid confusing the debug information machinery when there are
errors. */
@@ -2067,61 +1732,88 @@ check_global_declarations (vec, len)
}
}
-/* Save the current INPUT_FILENAME and LINENO on the top entry in the
- INPUT_FILE_STACK. Push a new entry for FILE and LINE, and set the
- INPUT_FILENAME and LINENO accordingly. */
-
+/* Warn about a use of an identifier which was marked deprecated. */
void
-push_srcloc (file, line)
- const char *file;
- int line;
+warn_deprecated_use (tree node)
{
- struct file_stack *fs;
+ if (node == 0 || !warn_deprecated_decl)
+ return;
- if (input_file_stack)
+ if (DECL_P (node))
+ warning ("`%s' is deprecated (declared at %s:%d)",
+ IDENTIFIER_POINTER (DECL_NAME (node)),
+ DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
+ else if (TYPE_P (node))
{
- input_file_stack->name = input_filename;
- input_file_stack->line = lineno;
+ const char *what = NULL;
+ tree decl = TYPE_STUB_DECL (node);
+
+ if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
+ what = IDENTIFIER_POINTER (TYPE_NAME (node));
+ else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
+ && DECL_NAME (TYPE_NAME (node)))
+ what = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node)));
+
+ if (what)
+ {
+ if (decl)
+ warning ("`%s' is deprecated (declared at %s:%d)", what,
+ DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
+ else
+ warning ("`%s' is deprecated", what);
+ }
+ else if (decl)
+ warning ("type is deprecated (declared at %s:%d)",
+ DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
+ else
+ warning ("type is deprecated");
}
+}
+
+/* Save the current INPUT_LOCATION on the top entry in the
+ INPUT_FILE_STACK. Push a new entry for FILE and LINE, and set the
+ INPUT_LOCATION accordingly. */
+
+void
+push_srcloc (const char *file, int line)
+{
+ struct file_stack *fs;
- fs = (struct file_stack *) xmalloc (sizeof (struct file_stack));
- fs->name = input_filename = file;
- fs->line = lineno = line;
+ fs = xmalloc (sizeof (struct file_stack));
+ fs->location = input_location;
fs->next = input_file_stack;
+ input_filename = file;
+ input_line = line;
input_file_stack = fs;
input_file_stack_tick++;
}
/* Pop the top entry off the stack of presently open source files.
- Restore the INPUT_FILENAME and LINENO from the new topmost entry on
- the stack. */
+ Restore the INPUT_LOCATION from the new topmost entry on the
+ stack. */
void
-pop_srcloc ()
+pop_srcloc (void)
{
struct file_stack *fs;
fs = input_file_stack;
+ input_location = fs->location;
input_file_stack = fs->next;
free (fs);
input_file_stack_tick++;
- /* The initial source file is never popped. */
- if (!input_file_stack)
- abort ();
- input_filename = input_file_stack->name;
- lineno = input_file_stack->line;
}
/* Compile an entire translation unit. Write a file of assembly
output and various debugging dumps. */
static void
-compile_file ()
+compile_file (void)
{
/* Initialize yet another pass. */
init_final (main_input_filename);
- init_branch_prob (aux_base_name);
+ coverage_init (aux_base_name);
timevar_push (TV_PARSE);
@@ -2142,14 +1834,12 @@ compile_file ()
(*lang_hooks.decls.final_write_globals)();
- /* This must occur after the loop to output deferred functions. Else
- the profiler initializer would not be emitted if all the functions
- in this compilation unit were deferred.
+ cgraph_varpool_assemble_pending_decls ();
- output_func_start_profiler can not cause any additional functions or
- data to need to be output, so it need not be in the deferred function
- loop above. */
- output_func_start_profiler ();
+ /* This must occur after the loop to output deferred functions.
+ Else the coverage initializer would not be emitted if all the
+ functions in this compilation unit were deferred. */
+ coverage_finish ();
/* Write out any pending weak symbol declarations. */
@@ -2170,8 +1860,6 @@ compile_file ()
dw2_output_indirect_constants ();
- end_final (aux_base_name);
-
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
timevar_push (TV_DUMP);
@@ -2183,9 +1871,7 @@ compile_file ()
timevar_pop (TV_DUMP);
}
-#ifdef ASM_FILE_END
- ASM_FILE_END (asm_out_file);
-#endif
+ targetm.asm_out.file_end ();
/* Attach a special .ident directive to the end of the file to identify
the version of GCC which compiled this code. The format of the .ident
@@ -2204,7 +1890,7 @@ compile_file ()
timevar_pop (TV_DUMP);
}
}
-
+
/* This is called from various places for FUNCTION_DECL, VAR_DECL,
and TYPE_DECL nodes.
@@ -2219,20 +1905,11 @@ compile_file ()
if this declaration is not within a function. */
void
-rest_of_decl_compilation (decl, asmspec, top_level, at_end)
- tree decl;
- const char *asmspec;
- int top_level;
- int at_end;
+rest_of_decl_compilation (tree decl,
+ const char *asmspec,
+ int top_level,
+ int at_end)
{
- /* Declarations of variables, and of functions defined elsewhere. */
-
-/* The most obvious approach, to put an #ifndef around where
- this macro is used, doesn't work since it's inside a macro call. */
-#ifndef ASM_FINISH_DECLARE_OBJECT
-#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)
-#endif
-
/* We deferred calling assemble_alias so that we could collect
other attributes such as visibility. Emit the alias now. */
{
@@ -2257,14 +1934,30 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
make_decl_rtl (decl, asmspec);
/* Don't output anything when a tentative file-scope definition
- is seen. But at end of compilation, do output code for them. */
- if (at_end || !DECL_DEFER_OUTPUT (decl))
- assemble_variable (decl, top_level, at_end, 0);
+ is seen. But at end of compilation, do output code for them.
+
+ We do output all variables when unit-at-a-time is active and rely on
+ callgraph code to defer them except for forward declarations
+ (see gcc.c-torture/compile/920624-1.c) */
+ if ((at_end
+ || !DECL_DEFER_OUTPUT (decl)
+ || (flag_unit_at_a_time && DECL_INITIAL (decl)))
+ && !DECL_EXTERNAL (decl))
+ {
+ if (flag_unit_at_a_time && !cgraph_global_info_ready
+ && TREE_CODE (decl) != FUNCTION_DECL && top_level)
+ cgraph_varpool_finalize_decl (decl);
+ else
+ assemble_variable (decl, top_level, at_end, 0);
+ }
+
+#ifdef ASM_FINISH_DECLARE_OBJECT
if (decl == last_assemble_variable_decl)
{
ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
top_level, at_end);
}
+#endif
timevar_pop (TV_VARCONST);
}
@@ -2317,14 +2010,16 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
/* Called after finishing a record, union or enumeral type. */
void
-rest_of_type_compilation (type, toplev)
-#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO)
- tree type;
- int toplev;
+rest_of_type_compilation (
+#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) \
+ || defined (SDB_DEBUGGING_INFO) || defined (DWARF2_DEBUGGING_INFO)
+ tree type,
+ int toplev
#else
- tree type ATTRIBUTE_UNUSED;
- int toplev ATTRIBUTE_UNUSED;
+ tree type ATTRIBUTE_UNUSED,
+ int toplev ATTRIBUTE_UNUSED
#endif
+ )
{
/* Avoid confusing the debug information machinery when there are
errors. */
@@ -2349,6 +2044,1060 @@ rest_of_type_compilation (type, toplev)
timevar_pop (TV_SYMOUT);
}
+/* Turn the RTL into assembly. */
+static void
+rest_of_handle_final (tree decl, rtx insns)
+{
+ timevar_push (TV_FINAL);
+ {
+ rtx x;
+ const char *fnname;
+
+ /* Get the function's name, as described by its RTL. This may be
+ different from the DECL_NAME name used in the source file. */
+
+ x = DECL_RTL (decl);
+ if (GET_CODE (x) != MEM)
+ abort ();
+ x = XEXP (x, 0);
+ if (GET_CODE (x) != SYMBOL_REF)
+ abort ();
+ fnname = XSTR (x, 0);
+
+ assemble_start_function (decl, fnname);
+ final_start_function (insns, asm_out_file, optimize);
+ final (insns, asm_out_file, optimize, 0);
+ final_end_function ();
+
+#ifdef IA64_UNWIND_INFO
+ /* ??? The IA-64 ".handlerdata" directive must be issued before
+ the ".endp" directive that closes the procedure descriptor. */
+ output_function_exception_table ();
+#endif
+
+ assemble_end_function (decl, fnname);
+
+#ifndef IA64_UNWIND_INFO
+ /* Otherwise, it feels unclean to switch sections in the middle. */
+ output_function_exception_table ();
+#endif
+
+ if (! quiet_flag)
+ fflush (asm_out_file);
+
+ /* Release all memory allocated by flow. */
+ free_basic_block_vars (0);
+
+ /* Release all memory held by regsets now. */
+ regset_release_memory ();
+ }
+ timevar_pop (TV_FINAL);
+
+ ggc_collect ();
+}
+
+#ifdef DELAY_SLOTS
+/* Run delay slot optimization. */
+static void
+rest_of_handle_delay_slots (tree decl, rtx insns)
+{
+ timevar_push (TV_DBR_SCHED);
+ open_dump_file (DFI_dbr, decl);
+
+ dbr_schedule (insns, rtl_dump_file);
+
+ close_dump_file (DFI_dbr, print_rtl, insns);
+ timevar_pop (TV_DBR_SCHED);
+
+ ggc_collect ();
+}
+#endif
+
+#ifdef STACK_REGS
+/* Convert register usage from flat register file usage to a stack
+ register file. */
+static void
+rest_of_handle_stack_regs (tree decl, rtx insns)
+{
+#if defined (HAVE_ATTR_length)
+ /* If flow2 creates new instructions which need splitting
+ and scheduling after reload is not done, they might not be
+ split until final which doesn't allow splitting
+ if HAVE_ATTR_length. */
+#ifdef INSN_SCHEDULING
+ if (optimize && !flag_schedule_insns_after_reload)
+#else
+ if (optimize)
+#endif
+ {
+ timevar_push (TV_SHORTEN_BRANCH);
+ split_all_insns (1);
+ timevar_pop (TV_SHORTEN_BRANCH);
+ }
+#endif
+
+ timevar_push (TV_REG_STACK);
+ open_dump_file (DFI_stack, decl);
+
+ if (reg_to_stack (insns, rtl_dump_file) && optimize)
+ {
+ if (cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
+ | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0))
+ && flag_reorder_blocks)
+ {
+ reorder_basic_blocks (0);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
+ }
+ }
+
+ close_dump_file (DFI_stack, print_rtl_with_bb, insns);
+ timevar_pop (TV_REG_STACK);
+
+ ggc_collect ();
+}
+#endif
+
+
+/* Machine independent reorg pass. */
+static void
+rest_of_handle_machine_reorg (tree decl, rtx insns)
+{
+ timevar_push (TV_MACH_DEP);
+ open_dump_file (DFI_mach, decl);
+
+ (*targetm.machine_dependent_reorg) ();
+
+ close_dump_file (DFI_mach, print_rtl, insns);
+ timevar_pop (TV_MACH_DEP);
+
+ ggc_collect ();
+}
+
+
+/* Run new register allocator. Return TRUE if we must exit
+ rest_of_compilation upon return. */
+static bool
+rest_of_handle_new_regalloc (tree decl, rtx insns)
+{
+ int failure;
+
+ delete_trivially_dead_insns (insns, max_reg_num ());
+ reg_alloc ();
+
+ timevar_pop (TV_LOCAL_ALLOC);
+ if (dump_file[DFI_lreg].enabled)
+ {
+ timevar_push (TV_DUMP);
+
+ close_dump_file (DFI_lreg, NULL, NULL);
+ timevar_pop (TV_DUMP);
+ }
+
+ /* XXX clean up the whole mess to bring live info in shape again. */
+ timevar_push (TV_GLOBAL_ALLOC);
+ open_dump_file (DFI_greg, decl);
+
+ build_insn_chain (insns);
+ failure = reload (insns, 0);
+
+ timevar_pop (TV_GLOBAL_ALLOC);
+
+ if (dump_file[DFI_greg].enabled)
+ {
+ timevar_push (TV_DUMP);
+
+ dump_global_regs (rtl_dump_file);
+
+ close_dump_file (DFI_greg, print_rtl_with_bb, insns);
+ timevar_pop (TV_DUMP);
+ }
+
+ if (failure)
+ return true;
+
+ reload_completed = 1;
+
+ return false;
+}
+
+/* Run old register allocator. Return TRUE if we must exit
+ rest_of_compilation upon return. */
+static bool
+rest_of_handle_old_regalloc (tree decl, rtx insns)
+{
+ int failure;
+ int rebuild_notes;
+
+ /* Allocate the reg_renumber array. */
+ allocate_reg_info (max_regno, FALSE, TRUE);
+
+ /* And the reg_equiv_memory_loc array. */
+ reg_equiv_memory_loc = xcalloc (max_regno, sizeof (rtx));
+
+ allocate_initial_values (reg_equiv_memory_loc);
+
+ regclass (insns, max_reg_num (), rtl_dump_file);
+ rebuild_notes = local_alloc ();
+
+ timevar_pop (TV_LOCAL_ALLOC);
+
+ /* Local allocation may have turned an indirect jump into a direct
+ jump. If so, we must rebuild the JUMP_LABEL fields of jumping
+ instructions. */
+ if (rebuild_notes)
+ {
+ timevar_push (TV_JUMP);
+
+ rebuild_jump_labels (insns);
+ purge_all_dead_edges (0);
+
+ timevar_pop (TV_JUMP);
+ }
+
+ if (dump_file[DFI_lreg].enabled)
+ {
+ timevar_push (TV_DUMP);
+
+ dump_flow_info (rtl_dump_file);
+ dump_local_alloc (rtl_dump_file);
+
+ close_dump_file (DFI_lreg, print_rtl_with_bb, insns);
+ timevar_pop (TV_DUMP);
+ }
+
+ ggc_collect ();
+
+ timevar_push (TV_GLOBAL_ALLOC);
+ open_dump_file (DFI_greg, decl);
+
+ /* If optimizing, allocate remaining pseudo-regs. Do the reload
+ pass fixing up any insns that are invalid. */
+
+ if (optimize)
+ failure = global_alloc (rtl_dump_file);
+ else
+ {
+ build_insn_chain (insns);
+ failure = reload (insns, 0);
+ }
+
+ timevar_pop (TV_GLOBAL_ALLOC);
+
+ if (dump_file[DFI_greg].enabled)
+ {
+ timevar_push (TV_DUMP);
+
+ dump_global_regs (rtl_dump_file);
+
+ close_dump_file (DFI_greg, print_rtl_with_bb, insns);
+ timevar_pop (TV_DUMP);
+ }
+
+ return failure;
+}
+
+/* Run the regrename and cprop passes. */
+static void
+rest_of_handle_regrename (tree decl, rtx insns)
+{
+ timevar_push (TV_RENAME_REGISTERS);
+ open_dump_file (DFI_rnreg, decl);
+
+ if (flag_rename_registers)
+ regrename_optimize ();
+ if (flag_cprop_registers)
+ copyprop_hardreg_forward ();
+
+ close_dump_file (DFI_rnreg, print_rtl_with_bb, insns);
+ timevar_pop (TV_RENAME_REGISTERS);
+}
+
+/* Reorder basic blocks. */
+static void
+rest_of_handle_reorder_blocks (tree decl, rtx insns)
+{
+ bool changed;
+ unsigned int liveness_flags;
+
+ open_dump_file (DFI_bbro, decl);
+
+ /* Last attempt to optimize CFG, as scheduling, peepholing and insn
+ splitting possibly introduced more crossjumping opportunities. */
+ liveness_flags = (!HAVE_conditional_execution ? CLEANUP_UPDATE_LIFE : 0);
+ changed = cleanup_cfg (CLEANUP_EXPENSIVE | liveness_flags);
+
+ if (flag_sched2_use_traces && flag_schedule_insns_after_reload)
+ tracer (liveness_flags);
+ if (flag_reorder_blocks)
+ reorder_basic_blocks (liveness_flags);
+ if (flag_reorder_blocks
+ || (flag_sched2_use_traces && flag_schedule_insns_after_reload))
+ changed |= cleanup_cfg (CLEANUP_EXPENSIVE | liveness_flags);
+
+ /* On conditional execution targets we can not update the life cheaply, so
+ we deffer the updating to after both cleanups. This may lose some cases
+ but should not be terribly bad. */
+ if (changed && HAVE_conditional_execution)
+ update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
+ PROP_DEATH_NOTES | PROP_REG_INFO);
+ close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
+}
+
+#ifdef INSN_SCHEDULING
+/* Run instruction scheduler. */
+static void
+rest_of_handle_sched (tree decl, rtx insns)
+{
+ timevar_push (TV_SCHED);
+
+ /* Print function header into sched dump now
+ because doing the sched analysis makes some of the dump. */
+ if (optimize > 0 && flag_schedule_insns)
+ {
+ open_dump_file (DFI_sched, decl);
+
+ /* Do control and data sched analysis,
+ and write some of the results to dump file. */
+
+ schedule_insns (rtl_dump_file);
+
+ close_dump_file (DFI_sched, print_rtl_with_bb, insns);
+ }
+ timevar_pop (TV_SCHED);
+
+ ggc_collect ();
+}
+
+/* Run second scheduling pass after reload. */
+static void
+rest_of_handle_sched2 (tree decl, rtx insns)
+{
+ timevar_push (TV_SCHED2);
+ open_dump_file (DFI_sched2, decl);
+
+ /* Do control and data sched analysis again,
+ and write some more of the results to dump file. */
+
+ split_all_insns (1);
+
+ if (flag_sched2_use_superblocks || flag_sched2_use_traces)
+ {
+ schedule_ebbs (rtl_dump_file);
+ /* No liveness updating code yet, but it should be easy to do.
+ reg-stack recompute the liveness when needed for now. */
+ count_or_remove_death_notes (NULL, 1);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ }
+ else
+ schedule_insns (rtl_dump_file);
+
+ close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
+ timevar_pop (TV_SCHED2);
+
+ ggc_collect ();
+}
+#endif
+
+/* Register allocation pre-pass, to reduce number of moves necessary
+ for two-address machines. */
+static void
+rest_of_handle_regmove (tree decl, rtx insns)
+{
+ timevar_push (TV_REGMOVE);
+ open_dump_file (DFI_regmove, decl);
+
+ regmove_optimize (insns, max_reg_num (), rtl_dump_file);
+
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
+ close_dump_file (DFI_regmove, print_rtl_with_bb, insns);
+ timevar_pop (TV_REGMOVE);
+
+ ggc_collect ();
+}
+
+/* Run tracer. */
+static void
+rest_of_handle_tracer (tree decl, rtx insns)
+{
+ open_dump_file (DFI_tracer, decl);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+ tracer (0);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ reg_scan (insns, max_reg_num (), 0);
+ close_dump_file (DFI_tracer, print_rtl_with_bb, get_insns ());
+}
+
+/* If-conversion and CFG cleanup. */
+static void
+rest_of_handle_if_conversion (tree decl, rtx insns)
+{
+ open_dump_file (DFI_ce1, decl);
+ if (flag_if_conversion)
+ {
+ timevar_push (TV_IFCVT);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ reg_scan (insns, max_reg_num (), 0);
+ if_convert (0);
+ timevar_pop (TV_IFCVT);
+ }
+ timevar_push (TV_JUMP);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ reg_scan (insns, max_reg_num (), 0);
+ timevar_pop (TV_JUMP);
+ close_dump_file (DFI_ce1, print_rtl_with_bb, get_insns ());
+}
+
+/* Rerun if-conversion, as combine may have simplified things enough
+ to now meet sequence length restrictions. */
+static void
+rest_of_handle_if_after_combine (tree decl, rtx insns)
+{
+ timevar_push (TV_IFCVT);
+ open_dump_file (DFI_ce2, decl);
+
+ no_new_pseudos = 0;
+ if_convert (1);
+ no_new_pseudos = 1;
+
+ close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
+ timevar_pop (TV_IFCVT);
+}
+
+static void
+rest_of_handle_web (tree decl, rtx insns)
+{
+ open_dump_file (DFI_web, decl);
+ timevar_push (TV_WEB);
+ web_main ();
+ delete_trivially_dead_insns (insns, max_reg_num ());
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+
+ timevar_pop (TV_WEB);
+ close_dump_file (DFI_web, print_rtl_with_bb, insns);
+ reg_scan (get_insns (), max_reg_num (), 0);
+}
+
+/* Do branch profiling and static profile estimation passes. */
+static void
+rest_of_handle_branch_prob (tree decl, rtx insns)
+{
+ struct loops loops;
+
+ timevar_push (TV_BRANCH_PROB);
+ open_dump_file (DFI_bp, decl);
+
+ if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
+ branch_prob ();
+
+ /* Discover and record the loop depth at the head of each basic
+ block. The loop infrastructure does the real job for us. */
+ flow_loops_find (&loops, LOOP_TREE);
+
+ if (rtl_dump_file)
+ flow_loops_dump (&loops, rtl_dump_file, NULL, 0);
+
+ /* Estimate using heuristics if no profiling info is available. */
+ if (flag_guess_branch_prob)
+ estimate_probability (&loops);
+
+ flow_loops_free (&loops);
+ free_dominance_info (CDI_DOMINATORS);
+ close_dump_file (DFI_bp, print_rtl_with_bb, insns);
+ timevar_pop (TV_BRANCH_PROB);
+}
+
+/* Do optimizations based on expression value profiles. */
+static void
+rest_of_handle_value_profile_transformations (tree decl, rtx insns)
+{
+ open_dump_file (DFI_vpt, decl);
+ timevar_push (TV_VPT);
+
+ if (value_profile_transformations ())
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+
+ timevar_pop (TV_VPT);
+ close_dump_file (DFI_vpt, print_rtl_with_bb, insns);
+}
+
+/* Do control and data flow analysis; write some of the results to the
+ dump file. */
+static void
+rest_of_handle_cfg (tree decl, rtx insns)
+{
+ open_dump_file (DFI_cfg, decl);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+ if (optimize)
+ cleanup_cfg (CLEANUP_EXPENSIVE
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
+
+ /* It may make more sense to mark constant functions after dead code is
+ eliminated by life_analysis, but we need to do it early, as -fprofile-arcs
+ may insert code making function non-constant, but we still must consider
+ it as constant, otherwise -fbranch-probabilities will not read data back.
+
+ life_analysis rarely eliminates modification of external memory.
+ */
+ if (optimize)
+ {
+ /* Alias analysis depends on this information and mark_constant_function
+ depends on alias analysis. */
+ reg_scan (insns, max_reg_num (), 1);
+ mark_constant_function ();
+ }
+
+ close_dump_file (DFI_cfg, print_rtl_with_bb, insns);
+}
+
+/* Purge addressofs. */
+static void
+rest_of_handle_addressof (tree decl, rtx insns)
+{
+ open_dump_file (DFI_addressof, decl);
+
+ purge_addressof (insns);
+ if (optimize && purge_all_dead_edges (0))
+ delete_unreachable_blocks ();
+ reg_scan (insns, max_reg_num (), 1);
+
+ close_dump_file (DFI_addressof, print_rtl, insns);
+}
+
+/* We may have potential sibling or tail recursion sites. Select one
+ (of possibly multiple) methods of performing the call. */
+static void
+rest_of_handle_sibling_calls (rtx insns)
+{
+ rtx insn;
+ optimize_sibling_and_tail_recursive_calls ();
+
+ /* Recompute the CFG as sibling optimization clobbers it randomly. */
+ free_bb_for_insn ();
+ find_exception_handler_labels ();
+ rebuild_jump_labels (insns);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+
+ /* There is pass ordering problem - we must lower NOTE_INSN_PREDICTION
+ notes before simplifying cfg and we must do lowering after sibcall
+ that unhides parts of RTL chain and cleans up the CFG.
+
+ Until sibcall is replaced by tree-level optimizer, lets just
+ sweep away the NOTE_INSN_PREDICTION notes that leaked out. */
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ if (GET_CODE (insn) == NOTE
+ && NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION)
+ delete_insn (insn);
+
+ close_dump_file (DFI_sibling, print_rtl, get_insns ());
+}
+
+/* Perform jump bypassing and control flow optimizations. */
+static void
+rest_of_handle_jump_bypass (tree decl, rtx insns)
+{
+ timevar_push (TV_BYPASS);
+ open_dump_file (DFI_bypass, decl);
+
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ reg_scan (insns, max_reg_num (), 1);
+
+ if (bypass_jumps (rtl_dump_file))
+ {
+ rebuild_jump_labels (insns);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ delete_trivially_dead_insns (insns, max_reg_num ());
+ }
+
+ close_dump_file (DFI_bypass, print_rtl_with_bb, insns);
+ timevar_pop (TV_BYPASS);
+
+ ggc_collect ();
+
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+}
+
+/* Handle inlining of functions in rest_of_compilation. Return TRUE
+ if we must exit rest_of_compilation upon return. */
+static bool
+rest_of_handle_inlining (tree decl)
+{
+ rtx insns;
+ int inlinable = 0;
+ tree parent;
+ const char *lose;
+
+ /* If we are reconsidering an inline function at the end of
+ compilation, skip the stuff for making it inline. */
+ if (cfun->rtl_inline_init)
+ return 0;
+ cfun->rtl_inline_init = 1;
+
+ /* If this is nested inside an inlined external function, pretend
+ it was only declared. Since we cannot inline such functions,
+ generating code for this one is not only not necessary but will
+ confuse some debugging output writers. */
+ for (parent = DECL_CONTEXT (current_function_decl);
+ parent != NULL_TREE;
+ parent = get_containing_scope (parent))
+ if (TREE_CODE (parent) == FUNCTION_DECL
+ && DECL_INLINE (parent) && DECL_EXTERNAL (parent))
+ {
+ DECL_INITIAL (decl) = 0;
+ return true;
+ }
+ else if (TYPE_P (parent))
+ /* A function in a local class should be treated normally. */
+ break;
+
+ /* If requested, consider whether to make this function inline. */
+ if ((DECL_INLINE (decl) && !flag_no_inline)
+ || flag_inline_functions)
+ {
+ timevar_push (TV_INTEGRATION);
+ lose = function_cannot_inline_p (decl);
+ timevar_pop (TV_INTEGRATION);
+ if (lose || ! optimize)
+ {
+ if (warn_inline && lose && DECL_INLINE (decl))
+ {
+ char *msg = concat ("%J", lose, NULL);
+ warning (msg, decl);
+ free (msg);
+ }
+ DECL_ABSTRACT_ORIGIN (decl) = 0;
+ /* Don't really compile an extern inline function.
+ If we can't make it inline, pretend
+ it was only declared. */
+ if (DECL_EXTERNAL (decl))
+ {
+ DECL_INITIAL (decl) = 0;
+ return true;
+ }
+ }
+ else
+ inlinable = DECL_INLINE (decl) = 1;
+ }
+
+ insns = get_insns ();
+
+ /* Dump the rtl code if we are dumping rtl. */
+
+ if (open_dump_file (DFI_rtl, decl))
+ {
+ if (DECL_SAVED_INSNS (decl) && DECL_SAVED_INSNS (decl)->saved_for_inline)
+ fprintf (rtl_dump_file, ";; (integrable)\n\n");
+ close_dump_file (DFI_rtl, print_rtl, insns);
+ }
+
+ /* Convert from NOTE_INSN_EH_REGION style notes, and do other
+ sorts of eh initialization. Delay this until after the
+ initial rtl dump so that we can see the original nesting. */
+ convert_from_eh_region_ranges ();
+
+ /* If function is inline, and we don't yet know whether to
+ compile it by itself, defer decision till end of compilation.
+ wrapup_global_declarations will (indirectly) call
+ rest_of_compilation again for those functions that need to
+ be output. Also defer those functions that we are supposed
+ to defer. */
+
+ if (inlinable
+ || (DECL_INLINE (decl)
+ /* Egad. This RTL deferral test conflicts with Fortran assumptions
+ for unreferenced symbols. See g77.f-torture/execute/980520-1.f.
+ But removing this line from the check breaks all languages that
+ use the call graph to output symbols. This hard-coded check is
+ the least invasive work-around. Nested functions need to be
+ deferred too. */
+ && (flag_inline_functions
+ || strcmp (lang_hooks.name, "GNU F77") == 0
+ || (cgraph_n_nodes > 0 && cgraph_node (decl)->origin))
+ && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
+ && ! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
+ && ! flag_keep_inline_functions)
+ || DECL_EXTERNAL (decl))))
+ DECL_DEFER_OUTPUT (decl) = 1;
+
+ if (DECL_INLINE (decl))
+ /* DWARF wants separate debugging info for abstract and
+ concrete instances of all inline functions, including those
+ declared inline but not inlined, and those inlined even
+ though they weren't declared inline. Conveniently, that's
+ what DECL_INLINE means at this point. */
+ (*debug_hooks->deferred_inline_function) (decl);
+
+ if (DECL_DEFER_OUTPUT (decl))
+ {
+ /* If -Wreturn-type, we have to do a bit of compilation. We just
+ want to call cleanup the cfg to figure out whether or not we can
+ fall off the end of the function; we do the minimum amount of
+ work necessary to make that safe. */
+ if (warn_return_type)
+ {
+ int saved_optimize = optimize;
+
+ optimize = 0;
+ rebuild_jump_labels (insns);
+ find_exception_handler_labels ();
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);
+ optimize = saved_optimize;
+
+ /* CFG is no longer maintained up-to-date. */
+ free_bb_for_insn ();
+ }
+
+ set_nothrow_function_flags ();
+ if (current_function_nothrow)
+ /* Now we know that this can't throw; set the flag for the benefit
+ of other functions later in this translation unit. */
+ TREE_NOTHROW (current_function_decl) = 1;
+
+ timevar_push (TV_INTEGRATION);
+ save_for_inline (decl);
+ timevar_pop (TV_INTEGRATION);
+ DECL_SAVED_INSNS (decl)->inlinable = inlinable;
+ return true;
+ }
+
+ /* If specified extern inline but we aren't inlining it, we are
+ done. This goes for anything that gets here with DECL_EXTERNAL
+ set, not just things with DECL_INLINE. */
+ return (bool) DECL_EXTERNAL (decl);
+}
+
+/* Try to identify useless null pointer tests and delete them. */
+static void
+rest_of_handle_null_pointer (tree decl, rtx insns)
+{
+ open_dump_file (DFI_null, decl);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+
+ if (delete_null_pointer_checks (insns))
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+
+ close_dump_file (DFI_null, print_rtl_with_bb, insns);
+}
+
+/* Try combining insns through substitution. */
+static void
+rest_of_handle_combine (tree decl, rtx insns)
+{
+ int rebuild_jump_labels_after_combine = 0;
+
+ timevar_push (TV_COMBINE);
+ open_dump_file (DFI_combine, decl);
+
+ rebuild_jump_labels_after_combine
+ = combine_instructions (insns, max_reg_num ());
+
+ /* Combining insns may have turned an indirect jump into a
+ direct jump. Rebuild the JUMP_LABEL fields of jumping
+ instructions. */
+ if (rebuild_jump_labels_after_combine)
+ {
+ timevar_push (TV_JUMP);
+ rebuild_jump_labels (insns);
+ timevar_pop (TV_JUMP);
+
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
+ }
+
+ close_dump_file (DFI_combine, print_rtl_with_bb, insns);
+ timevar_pop (TV_COMBINE);
+
+ ggc_collect ();
+}
+
+/* Perform life analysis. */
+static void
+rest_of_handle_life (tree decl, rtx insns)
+{
+ open_dump_file (DFI_life, decl);
+ regclass_init ();
+
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+ life_analysis (insns, rtl_dump_file, PROP_FINAL);
+ if (optimize)
+ cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_UPDATE_LIFE
+ | CLEANUP_LOG_LINKS
+ | (flag_thread_jumps ? CLEANUP_THREADING : 0));
+ timevar_pop (TV_FLOW);
+
+ if (warn_uninitialized)
+ {
+ uninitialized_vars_warning (DECL_INITIAL (decl));
+ if (extra_warnings)
+ setjmp_args_warning ();
+ }
+
+ if (optimize)
+ {
+ if (!flag_new_regalloc && initialize_uninitialized_subregs ())
+ {
+ /* Insns were inserted, and possibly pseudos created, so
+ things might look a bit different. */
+ insns = get_insns ();
+ allocate_reg_life_data ();
+ update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
+ PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES);
+ }
+ }
+
+ no_new_pseudos = 1;
+
+ close_dump_file (DFI_life, print_rtl_with_bb, insns);
+
+ ggc_collect ();
+}
+
+/* Perform common subexpression elimination. Nonzero value from
+ `cse_main' means that jumps were simplified and some code may now
+ be unreachable, so do jump optimization again. */
+static void
+rest_of_handle_cse (tree decl, rtx insns)
+{
+ int tem;
+
+ open_dump_file (DFI_cse, decl);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+ timevar_push (TV_CSE);
+
+ reg_scan (insns, max_reg_num (), 1);
+
+ tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
+ if (tem)
+ rebuild_jump_labels (insns);
+ if (purge_all_dead_edges (0))
+ delete_unreachable_blocks ();
+
+ delete_trivially_dead_insns (insns, max_reg_num ());
+
+ /* If we are not running more CSE passes, then we are no longer
+ expecting CSE to be run. But always rerun it in a cheap mode. */
+ cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse;
+
+ if (tem || optimize > 1)
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+ /* Try to identify useless null pointer tests and delete them. */
+ if (flag_delete_null_pointer_checks)
+ {
+ timevar_push (TV_JUMP);
+
+ if (delete_null_pointer_checks (insns))
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+ timevar_pop (TV_JUMP);
+ }
+
+ /* The second pass of jump optimization is likely to have
+ removed a bunch more instructions. */
+ renumber_insns (rtl_dump_file);
+
+ timevar_pop (TV_CSE);
+ close_dump_file (DFI_cse, print_rtl_with_bb, insns);
+}
+
+/* Run second CSE pass after loop optimizations. */
+static void
+rest_of_handle_cse2 (tree decl, rtx insns)
+{
+ int tem;
+
+ timevar_push (TV_CSE2);
+ open_dump_file (DFI_cse2, decl);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+ /* CFG is no longer maintained up-to-date. */
+ tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file);
+
+ /* Run a pass to eliminate duplicated assignments to condition code
+ registers. We have to run this after bypass_jumps, because it
+ makes it harder for that pass to determine whether a jump can be
+ bypassed safely. */
+ cse_condition_code_reg ();
+
+ purge_all_dead_edges (0);
+ delete_trivially_dead_insns (insns, max_reg_num ());
+
+ if (tem)
+ {
+ timevar_push (TV_JUMP);
+ rebuild_jump_labels (insns);
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ timevar_pop (TV_JUMP);
+ }
+ reg_scan (insns, max_reg_num (), 0);
+ close_dump_file (DFI_cse2, print_rtl_with_bb, insns);
+ ggc_collect ();
+ timevar_pop (TV_CSE2);
+}
+
+/* Perform global cse. */
+static void
+rest_of_handle_gcse (tree decl, rtx insns)
+{
+ int save_csb, save_cfj;
+ int tem2 = 0, tem;
+
+ timevar_push (TV_GCSE);
+ open_dump_file (DFI_gcse, decl);
+
+ tem = gcse_main (insns, rtl_dump_file);
+ rebuild_jump_labels (insns);
+ delete_trivially_dead_insns (insns, max_reg_num ());
+
+ save_csb = flag_cse_skip_blocks;
+ save_cfj = flag_cse_follow_jumps;
+ flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
+
+ /* Instantiate any remaining CONSTANT_P_RTX nodes. */
+ if (current_function_calls_constant_p)
+ purge_builtin_constant_p ();
+
+ /* If -fexpensive-optimizations, re-run CSE to clean up things done
+ by gcse. */
+ if (flag_expensive_optimizations)
+ {
+ timevar_push (TV_CSE);
+ reg_scan (insns, max_reg_num (), 1);
+ tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
+ purge_all_dead_edges (0);
+ delete_trivially_dead_insns (insns, max_reg_num ());
+ timevar_pop (TV_CSE);
+ cse_not_expected = !flag_rerun_cse_after_loop;
+ }
+
+ /* If gcse or cse altered any jumps, rerun jump optimizations to clean
+ things up. Then possibly re-run CSE again. */
+ while (tem || tem2)
+ {
+ tem = tem2 = 0;
+ timevar_push (TV_JUMP);
+ rebuild_jump_labels (insns);
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+ timevar_pop (TV_JUMP);
+
+ if (flag_expensive_optimizations)
+ {
+ timevar_push (TV_CSE);
+ reg_scan (insns, max_reg_num (), 1);
+ tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
+ purge_all_dead_edges (0);
+ delete_trivially_dead_insns (insns, max_reg_num ());
+ timevar_pop (TV_CSE);
+ }
+ }
+
+ close_dump_file (DFI_gcse, print_rtl_with_bb, insns);
+ timevar_pop (TV_GCSE);
+
+ ggc_collect ();
+ flag_cse_skip_blocks = save_csb;
+ flag_cse_follow_jumps = save_cfj;
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
+}
+
+/* Move constant computations out of loops. */
+static void
+rest_of_handle_loop_optimize (tree decl, rtx insns)
+{
+ int do_unroll, do_prefetch;
+
+ timevar_push (TV_LOOP);
+ delete_dead_jumptables ();
+ cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+ open_dump_file (DFI_loop, decl);
+
+ /* CFG is no longer maintained up-to-date. */
+ free_bb_for_insn ();
+
+ if (flag_unroll_loops)
+ do_unroll = LOOP_AUTO_UNROLL; /* Having two unrollers is useless. */
+ else
+ do_unroll = flag_old_unroll_loops ? LOOP_UNROLL : LOOP_AUTO_UNROLL;
+ do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0;
+
+ if (flag_rerun_loop_opt)
+ {
+ cleanup_barriers ();
+
+ /* We only want to perform unrolling once. */
+ loop_optimize (insns, rtl_dump_file, do_unroll);
+ do_unroll = 0;
+
+ /* The first call to loop_optimize makes some instructions
+ trivially dead. We delete those instructions now in the
+ hope that doing so will make the heuristics in loop work
+ better and possibly speed up compilation. */
+ delete_trivially_dead_insns (insns, max_reg_num ());
+
+ /* The regscan pass is currently necessary as the alias
+ analysis code depends on this information. */
+ reg_scan (insns, max_reg_num (), 1);
+ }
+ cleanup_barriers ();
+ loop_optimize (insns, rtl_dump_file, do_unroll | LOOP_BCT | do_prefetch);
+
+ /* Loop can create trivially dead instructions. */
+ delete_trivially_dead_insns (insns, max_reg_num ());
+ close_dump_file (DFI_loop, print_rtl, insns);
+ timevar_pop (TV_LOOP);
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+
+ ggc_collect ();
+}
+
+/* Perform loop optimizations. It might be better to do them a bit
+ sooner, but we want the profile feedback to work more
+ efficiently. */
+static void
+rest_of_handle_loop2 (tree decl, rtx insns)
+{
+ struct loops *loops;
+ timevar_push (TV_LOOP);
+ open_dump_file (DFI_loop2, decl);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+
+ loops = loop_optimizer_init (rtl_dump_file);
+
+ if (loops)
+ {
+ /* The optimizations: */
+ if (flag_unswitch_loops)
+ unswitch_loops (loops);
+
+ if (flag_peel_loops || flag_unroll_loops)
+ unroll_and_peel_loops (loops,
+ (flag_peel_loops ? UAP_PEEL : 0) |
+ (flag_unroll_loops ? UAP_UNROLL : 0) |
+ (flag_unroll_all_loops ? UAP_UNROLL_ALL : 0));
+
+ loop_optimizer_finalize (loops, rtl_dump_file);
+ }
+
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+ delete_trivially_dead_insns (insns, max_reg_num ());
+ reg_scan (insns, max_reg_num (), 0);
+ if (rtl_dump_file)
+ dump_flow_info (rtl_dump_file);
+ close_dump_file (DFI_loop2, print_rtl_with_bb, get_insns ());
+ timevar_pop (TV_LOOP);
+ ggc_collect ();
+}
+
/* This is called from finish_function (within langhooks.parse_file)
after each top-level definition is parsed.
It is supposed to compile that function or variable
@@ -2356,17 +3105,15 @@ rest_of_type_compilation (type, toplev)
After we return, the tree storage is freed. */
void
-rest_of_compilation (decl)
- tree decl;
+rest_of_compilation (tree decl)
{
rtx insns;
- int tem;
- int failure = 0;
- int rebuild_label_notes_after_reload;
- int register_life_up_to_date;
timevar_push (TV_REST_OF_COMPILATION);
+ /* Register rtl specific functions for cfg. */
+ rtl_register_cfg_hooks ();
+
/* Now that we're out of the frontend, we shouldn't have any more
CONCATs anywhere. */
generating_concat_p = 0;
@@ -2387,145 +3134,8 @@ rest_of_compilation (decl)
init_flow ();
- /* If we are reconsidering an inline function
- at the end of compilation, skip the stuff for making it inline. */
-
- if (DECL_SAVED_INSNS (decl) == 0)
- {
- int inlinable = 0;
- tree parent;
- const char *lose;
-
- /* If this is nested inside an inlined external function, pretend
- it was only declared. Since we cannot inline such functions,
- generating code for this one is not only not necessary but will
- confuse some debugging output writers. */
- for (parent = DECL_CONTEXT (current_function_decl);
- parent != NULL_TREE;
- parent = get_containing_scope (parent))
- if (TREE_CODE (parent) == FUNCTION_DECL
- && DECL_INLINE (parent) && DECL_EXTERNAL (parent))
- {
- DECL_INITIAL (decl) = 0;
- goto exit_rest_of_compilation;
- }
- else if (TYPE_P (parent))
- /* A function in a local class should be treated normally. */
- break;
-
- /* If requested, consider whether to make this function inline. */
- if ((DECL_INLINE (decl) && !flag_no_inline)
- || flag_inline_functions)
- {
- timevar_push (TV_INTEGRATION);
- lose = function_cannot_inline_p (decl);
- timevar_pop (TV_INTEGRATION);
- if (lose || ! optimize)
- {
- if (warn_inline && DECL_INLINE (decl))
- warning_with_decl (decl, lose);
- DECL_ABSTRACT_ORIGIN (decl) = 0;
- /* Don't really compile an extern inline function.
- If we can't make it inline, pretend
- it was only declared. */
- if (DECL_EXTERNAL (decl))
- {
- DECL_INITIAL (decl) = 0;
- goto exit_rest_of_compilation;
- }
- }
- else
- {
- /* ??? Note that we used to just make it look like if
- the "inline" keyword was specified when we decide
- to inline it (because of -finline-functions).
- garloff at suse dot de, 2002-04-24: Add another flag to
- actually record this piece of information. */
- if (!DECL_INLINE (decl))
- DID_INLINE_FUNC (decl) = 1;
- inlinable = DECL_INLINE (decl) = 1;
- }
- }
-
- insns = get_insns ();
-
- /* Dump the rtl code if we are dumping rtl. */
-
- if (open_dump_file (DFI_rtl, decl))
- {
- if (DECL_SAVED_INSNS (decl))
- fprintf (rtl_dump_file, ";; (integrable)\n\n");
- close_dump_file (DFI_rtl, print_rtl, insns);
- }
-
- /* Convert from NOTE_INSN_EH_REGION style notes, and do other
- sorts of eh initialization. Delay this until after the
- initial rtl dump so that we can see the original nesting. */
- convert_from_eh_region_ranges ();
-
- /* If function is inline, and we don't yet know whether to
- compile it by itself, defer decision till end of compilation.
- wrapup_global_declarations will (indirectly) call
- rest_of_compilation again for those functions that need to
- be output. Also defer those functions that we are supposed
- to defer. */
-
- if (inlinable
- || (DECL_INLINE (decl)
- && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
- && ! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
- && ! flag_keep_inline_functions)
- || DECL_EXTERNAL (decl))))
- DECL_DEFER_OUTPUT (decl) = 1;
-
- if (DECL_INLINE (decl))
- /* DWARF wants separate debugging info for abstract and
- concrete instances of all inline functions, including those
- declared inline but not inlined, and those inlined even
- though they weren't declared inline. Conveniently, that's
- what DECL_INLINE means at this point. */
- (*debug_hooks->deferred_inline_function) (decl);
-
- if (DECL_DEFER_OUTPUT (decl))
- {
- /* If -Wreturn-type, we have to do a bit of compilation. We just
- want to call cleanup the cfg to figure out whether or not we can
- fall off the end of the function; we do the minimum amount of
- work necessary to make that safe. */
- if (warn_return_type)
- {
- int saved_optimize = optimize;
-
- optimize = 0;
- rebuild_jump_labels (insns);
- find_exception_handler_labels ();
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
- cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);
- optimize = saved_optimize;
-
- /* CFG is no longer maintained up-to-date. */
- free_bb_for_insn ();
- }
-
- set_nothrow_function_flags ();
- if (current_function_nothrow)
- /* Now we know that this can't throw; set the flag for the benefit
- of other functions later in this translation unit. */
- TREE_NOTHROW (current_function_decl) = 1;
-
- timevar_push (TV_INTEGRATION);
- save_for_inline (decl);
- timevar_pop (TV_INTEGRATION);
- DECL_SAVED_INSNS (decl)->inlinable = inlinable;
- goto exit_rest_of_compilation;
- }
-
- /* If specified extern inline but we aren't inlining it, we are
- done. This goes for anything that gets here with DECL_EXTERNAL
- set, not just things with DECL_INLINE. */
- if (DECL_EXTERNAL (decl))
- goto exit_rest_of_compilation;
- }
+ if (rest_of_handle_inlining (decl))
+ goto exit_rest_of_compilation;
/* If we're emitting a nested function, make sure its parent gets
emitted as well. Doing otherwise confuses debug info. */
@@ -2541,7 +3151,7 @@ rest_of_compilation (decl)
/* We are now committed to emitting code for this function. Do any
preparation, such as emitting abstract debug info for the inline
before it gets mangled by optimization. */
- if (DECL_INLINE (decl))
+ if (cgraph_function_possibly_inlined_p (decl))
(*debug_hooks->outlining_inline_function) (decl);
/* Remove any notes we don't need. That will make iterating
@@ -2583,10 +3193,6 @@ rest_of_compilation (decl)
delete_unreachable_blocks ();
- /* We have to issue these warnings now already, because CFG cleanups
- further down may destroy the required information. */
- check_function_return_warnings ();
-
/* Turn NOTE_INSN_PREDICTIONs into branch predictions. */
if (flag_guess_branch_prob)
{
@@ -2595,34 +3201,20 @@ rest_of_compilation (decl)
timevar_pop (TV_BRANCH_PROB);
}
- /* We may have potential sibling or tail recursion sites. Select one
- (of possibly multiple) methods of performing the call. */
if (flag_optimize_sibling_calls)
- {
- rtx insn;
- optimize_sibling_and_tail_recursive_calls ();
+ rest_of_handle_sibling_calls (insns);
- /* Recompute the CFG as sibling optimization clobbers it randomly. */
- free_bb_for_insn ();
- find_exception_handler_labels ();
- rebuild_jump_labels (insns);
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-
- /* There is pass ordering problem - we must lower NOTE_INSN_PREDICTION
- notes before simplifying cfg and we must do lowering after sibcall
- that unhides parts of RTL chain and cleans up the CFG.
+ /* We have to issue these warnings now already, because CFG cleanups
+ further down may destroy the required information. However, this
+ must be done after the sibcall optimization pass because the barrier
+ emitted for noreturn calls that are candidate for the optimization
+ is folded into the CALL_PLACEHOLDER until after this pass, so the
+ CFG is inaccurate. */
+ check_function_return_warnings ();
- Until sibcall is replaced by tree-level optimizer, lets just
- sweep away the NOTE_INSN_PREDICTION notes that leaked out. */
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- if (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_PREDICTION)
- delete_insn (insn);
- }
- close_dump_file (DFI_sibling, print_rtl, get_insns ());
timevar_pop (TV_JUMP);
- scope_to_insns_initialize ();
+ insn_locators_initialize ();
/* Complete generation of exception handling code. */
if (doing_eh (0))
{
@@ -2686,7 +3278,6 @@ rest_of_compilation (decl)
cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP
| (flag_thread_jumps ? CLEANUP_THREADING : 0));
- /* CFG is no longer maintained up-to-date. */
if (optimize)
{
free_bb_for_insn ();
@@ -2700,92 +3291,15 @@ rest_of_compilation (decl)
/* Now is when we stop if -fsyntax-only and -Wreturn-type. */
if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
- {
- goto exit_rest_of_compilation;
- }
-
- /* Long term, this should probably move before the jump optimizer too,
- but I didn't want to disturb the rtl_dump_and_exit and related
- stuff at this time. */
- if (optimize > 0 && flag_ssa)
- {
- /* Convert to SSA form. */
-
- timevar_push (TV_TO_SSA);
- open_dump_file (DFI_ssa, decl);
-
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
- convert_to_ssa ();
-
- close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
- timevar_pop (TV_TO_SSA);
-
- /* Perform sparse conditional constant propagation, if requested. */
- if (flag_ssa_ccp)
- {
- timevar_push (TV_SSA_CCP);
- open_dump_file (DFI_ssa_ccp, decl);
-
- ssa_const_prop ();
-
- close_dump_file (DFI_ssa_ccp, print_rtl_with_bb, get_insns ());
- timevar_pop (TV_SSA_CCP);
- }
-
- /* It would be useful to cleanup the CFG at this point, but block
- merging and possibly other transformations might leave a PHI
- node in the middle of a basic block, which is a strict no-no. */
-
- /* The SSA implementation uses basic block numbers in its phi
- nodes. Thus, changing the control-flow graph or the basic
- blocks, e.g., calling find_basic_blocks () or cleanup_cfg (),
- may cause problems. */
-
- if (flag_ssa_dce)
- {
- /* Remove dead code. */
-
- timevar_push (TV_SSA_DCE);
- open_dump_file (DFI_ssa_dce, decl);
-
- insns = get_insns ();
- ssa_eliminate_dead_code ();
-
- close_dump_file (DFI_ssa_dce, print_rtl_with_bb, insns);
- timevar_pop (TV_SSA_DCE);
- }
-
- /* Convert from SSA form. */
-
- timevar_push (TV_FROM_SSA);
- open_dump_file (DFI_ussa, decl);
-
- convert_from_ssa ();
- /* New registers have been created. Rescan their usage. */
- reg_scan (insns, max_reg_num (), 1);
-
- close_dump_file (DFI_ussa, print_rtl_with_bb, insns);
- timevar_pop (TV_FROM_SSA);
-
- ggc_collect ();
- }
+ goto exit_rest_of_compilation;
timevar_push (TV_JUMP);
+
if (optimize)
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
- /* Try to identify useless null pointer tests and delete them. */
if (flag_delete_null_pointer_checks)
- {
- open_dump_file (DFI_null, decl);
- if (rtl_dump_file)
- dump_flow_info (rtl_dump_file);
-
- if (delete_null_pointer_checks (insns))
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
-
- close_dump_file (DFI_null, print_rtl_with_bb, insns);
- }
+ rest_of_handle_null_pointer (decl, insns);
/* Jump optimization, and the removal of NULL pointer checks, may
have reduced the number of instructions substantially. CSE, and
@@ -2799,384 +3313,79 @@ rest_of_compilation (decl)
ggc_collect ();
- /* Perform common subexpression elimination.
- Nonzero value from `cse_main' means that jumps were simplified
- and some code may now be unreachable, so do
- jump optimization again. */
-
if (optimize > 0)
- {
- open_dump_file (DFI_cse, decl);
- if (rtl_dump_file)
- dump_flow_info (rtl_dump_file);
- timevar_push (TV_CSE);
-
- reg_scan (insns, max_reg_num (), 1);
-
- tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
- if (tem)
- rebuild_jump_labels (insns);
- if (purge_all_dead_edges (0))
- delete_unreachable_blocks ();
-
- delete_trivially_dead_insns (insns, max_reg_num ());
-
- /* If we are not running more CSE passes, then we are no longer
- expecting CSE to be run. But always rerun it in a cheap mode. */
- cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse;
-
- if (tem || optimize > 1)
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
- /* Try to identify useless null pointer tests and delete them. */
- if (flag_delete_null_pointer_checks)
- {
- timevar_push (TV_JUMP);
-
- if (delete_null_pointer_checks (insns))
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
- timevar_pop (TV_JUMP);
- }
-
- /* The second pass of jump optimization is likely to have
- removed a bunch more instructions. */
- renumber_insns (rtl_dump_file);
-
- timevar_pop (TV_CSE);
- close_dump_file (DFI_cse, print_rtl_with_bb, insns);
- }
-
- open_dump_file (DFI_addressof, decl);
-
- purge_addressof (insns);
- if (optimize && purge_all_dead_edges (0))
- delete_unreachable_blocks ();
- reg_scan (insns, max_reg_num (), 1);
+ rest_of_handle_cse (decl, insns);
- close_dump_file (DFI_addressof, print_rtl, insns);
+ rest_of_handle_addressof (decl, insns);
ggc_collect ();
- /* Perform global cse. */
-
- if (optimize > 0 && flag_gcse)
- {
- int save_csb, save_cfj;
- int tem2 = 0;
-
- timevar_push (TV_GCSE);
- open_dump_file (DFI_gcse, decl);
-
- tem = gcse_main (insns, rtl_dump_file);
- rebuild_jump_labels (insns);
- delete_trivially_dead_insns (insns, max_reg_num ());
-
- save_csb = flag_cse_skip_blocks;
- save_cfj = flag_cse_follow_jumps;
- flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
-
- /* If -fexpensive-optimizations, re-run CSE to clean up things done
- by gcse. */
- if (flag_expensive_optimizations)
- {
- timevar_push (TV_CSE);
- reg_scan (insns, max_reg_num (), 1);
- tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
- purge_all_dead_edges (0);
- delete_trivially_dead_insns (insns, max_reg_num ());
- timevar_pop (TV_CSE);
- cse_not_expected = !flag_rerun_cse_after_loop;
- }
-
- /* If gcse or cse altered any jumps, rerun jump optimizations to clean
- things up. Then possibly re-run CSE again. */
- while (tem || tem2)
- {
- tem = tem2 = 0;
- timevar_push (TV_JUMP);
- rebuild_jump_labels (insns);
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
- timevar_pop (TV_JUMP);
-
- if (flag_expensive_optimizations)
- {
- timevar_push (TV_CSE);
- reg_scan (insns, max_reg_num (), 1);
- tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
- purge_all_dead_edges (0);
- delete_trivially_dead_insns (insns, max_reg_num ());
- timevar_pop (TV_CSE);
- }
- }
-
- close_dump_file (DFI_gcse, print_rtl_with_bb, insns);
- timevar_pop (TV_GCSE);
-
- ggc_collect ();
- flag_cse_skip_blocks = save_csb;
- flag_cse_follow_jumps = save_cfj;
-#ifdef ENABLE_CHECKING
- verify_flow_info ();
-#endif
- }
-
- /* Move constant computations out of loops. */
-
- if (optimize > 0 && flag_loop_optimize)
+ if (optimize > 0)
{
- int do_unroll, do_prefetch;
-
- timevar_push (TV_LOOP);
- delete_dead_jumptables ();
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
- open_dump_file (DFI_loop, decl);
- /* CFG is no longer maintained up-to-date. */
- free_bb_for_insn ();
-
- do_unroll = flag_unroll_loops ? LOOP_UNROLL : LOOP_AUTO_UNROLL;
- do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0;
- if (flag_rerun_loop_opt)
- {
- cleanup_barriers ();
-
- /* We only want to perform unrolling once. */
- loop_optimize (insns, rtl_dump_file, do_unroll);
- do_unroll = 0;
-
- /* The first call to loop_optimize makes some instructions
- trivially dead. We delete those instructions now in the
- hope that doing so will make the heuristics in loop work
- better and possibly speed up compilation. */
- delete_trivially_dead_insns (insns, max_reg_num ());
-
- /* The regscan pass is currently necessary as the alias
- analysis code depends on this information. */
- reg_scan (insns, max_reg_num (), 1);
- }
- cleanup_barriers ();
- loop_optimize (insns, rtl_dump_file, do_unroll | LOOP_BCT | do_prefetch);
+ if (flag_gcse)
+ rest_of_handle_gcse (decl, insns);
- /* Loop can create trivially dead instructions. */
- delete_trivially_dead_insns (insns, max_reg_num ());
- close_dump_file (DFI_loop, print_rtl, insns);
- timevar_pop (TV_LOOP);
- find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ if (flag_loop_optimize)
+ rest_of_handle_loop_optimize (decl, insns);
- ggc_collect ();
+ if (flag_gcse)
+ rest_of_handle_jump_bypass (decl, insns);
}
- /* Do control and data flow analysis; wrote some of the results to
- the dump file. */
-
timevar_push (TV_FLOW);
- open_dump_file (DFI_cfg, decl);
- if (rtl_dump_file)
- dump_flow_info (rtl_dump_file);
- if (optimize)
- cleanup_cfg (CLEANUP_EXPENSIVE
- | (flag_thread_jumps ? CLEANUP_THREADING : 0));
-
- /* It may make more sense to mark constant functions after dead code is
- eliminated by life_analyzis, but we need to do it early, as -fprofile-arcs
- may insert code making function non-constant, but we still must consider
- it as constant, otherwise -fbranch-probabilities will not read data back.
-
- life_analyzis rarely eliminates modification of external memory.
- */
- if (optimize)
- mark_constant_function ();
-
- close_dump_file (DFI_cfg, print_rtl_with_bb, insns);
-
- /* Do branch profiling and static profile estimation passes. */
- if (optimize > 0 || cfun->arc_profile || flag_branch_probabilities)
- {
- struct loops loops;
-
- timevar_push (TV_BRANCH_PROB);
- open_dump_file (DFI_bp, decl);
- if (cfun->arc_profile || flag_branch_probabilities)
- branch_prob ();
- /* Discover and record the loop depth at the head of each basic
- block. The loop infrastructure does the real job for us. */
- flow_loops_find (&loops, LOOP_TREE);
+ rest_of_handle_cfg (decl, insns);
- if (rtl_dump_file)
- flow_loops_dump (&loops, rtl_dump_file, NULL, 0);
-
- /* Estimate using heuristics if no profiling info is available. */
- if (flag_guess_branch_prob)
- estimate_probability (&loops);
-
- flow_loops_free (&loops);
- close_dump_file (DFI_bp, print_rtl_with_bb, insns);
- timevar_pop (TV_BRANCH_PROB);
- }
- if (optimize > 0)
- {
- open_dump_file (DFI_ce1, decl);
- if (flag_if_conversion)
- {
- timevar_push (TV_IFCVT);
- if (rtl_dump_file)
- dump_flow_info (rtl_dump_file);
- cleanup_cfg (CLEANUP_EXPENSIVE);
- reg_scan (insns, max_reg_num (), 0);
- if_convert (0);
- timevar_pop (TV_IFCVT);
- }
- timevar_push (TV_JUMP);
- cleanup_cfg (CLEANUP_EXPENSIVE);
- reg_scan (insns, max_reg_num (), 0);
- timevar_pop (TV_JUMP);
- close_dump_file (DFI_ce1, print_rtl_with_bb, get_insns ());
- }
- if (flag_tracer)
+ if (optimize > 0
+ || profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
- timevar_push (TV_TRACER);
- open_dump_file (DFI_tracer, decl);
- if (rtl_dump_file)
- dump_flow_info (rtl_dump_file);
- tracer ();
- cleanup_cfg (CLEANUP_EXPENSIVE);
- reg_scan (insns, max_reg_num (), 0);
- close_dump_file (DFI_tracer, print_rtl_with_bb, get_insns ());
- timevar_pop (TV_TRACER);
- }
+ rest_of_handle_branch_prob (decl, insns);
- if (flag_rerun_cse_after_loop)
- {
- timevar_push (TV_CSE2);
- open_dump_file (DFI_cse2, decl);
- if (rtl_dump_file)
- dump_flow_info (rtl_dump_file);
- /* CFG is no longer maintained up-to-date. */
- tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file);
- purge_all_dead_edges (0);
- delete_trivially_dead_insns (insns, max_reg_num ());
+ if (flag_branch_probabilities
+ && flag_profile_values
+ && flag_value_profile_transformations)
+ rest_of_handle_value_profile_transformations (decl, insns);
- if (tem)
- {
- timevar_push (TV_JUMP);
- rebuild_jump_labels (insns);
- cleanup_cfg (CLEANUP_EXPENSIVE);
- timevar_pop (TV_JUMP);
- }
- reg_scan (insns, max_reg_num (), 0);
- close_dump_file (DFI_cse2, print_rtl_with_bb, insns);
- ggc_collect ();
- timevar_pop (TV_CSE2);
+ /* Remove the death notes created for vpt. */
+ if (flag_profile_values)
+ count_or_remove_death_notes (NULL, 1);
}
- cse_not_expected = 1;
-
- open_dump_file (DFI_life, decl);
- regclass_init ();
-
-#ifdef ENABLE_CHECKING
- verify_flow_info ();
-#endif
- life_analysis (insns, rtl_dump_file, PROP_FINAL);
- if (optimize)
- cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_UPDATE_LIFE
- | (flag_thread_jumps ? CLEANUP_THREADING : 0));
- timevar_pop (TV_FLOW);
+ if (optimize > 0)
+ rest_of_handle_if_conversion (decl, insns);
- if (warn_uninitialized || extra_warnings)
- {
- uninitialized_vars_warning (DECL_INITIAL (decl));
- if (extra_warnings)
- setjmp_args_warning ();
- }
+ if (flag_tracer)
+ rest_of_handle_tracer (decl, insns);
- if (optimize)
- {
- if (!flag_new_regalloc && initialize_uninitialized_subregs ())
- {
- /* Insns were inserted, and possibly pseudos created, so
- things might look a bit different. */
- insns = get_insns ();
- allocate_reg_life_data ();
- update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
- PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES);
- }
- }
+ if (optimize > 0
+ && (flag_unswitch_loops
+ || flag_peel_loops
+ || flag_unroll_loops))
+ rest_of_handle_loop2 (decl, insns);
- no_new_pseudos = 1;
+ if (flag_web)
+ rest_of_handle_web (decl, insns);
- close_dump_file (DFI_life, print_rtl_with_bb, insns);
+ if (flag_rerun_cse_after_loop)
+ rest_of_handle_cse2 (decl, insns);
- ggc_collect ();
+ cse_not_expected = 1;
- /* If -opt, try combining insns through substitution. */
+ rest_of_handle_life (decl, insns);
if (optimize > 0)
- {
- int rebuild_jump_labels_after_combine = 0;
-
- timevar_push (TV_COMBINE);
- open_dump_file (DFI_combine, decl);
-
- rebuild_jump_labels_after_combine
- = combine_instructions (insns, max_reg_num ());
-
- /* Combining insns may have turned an indirect jump into a
- direct jump. Rebuid the JUMP_LABEL fields of jumping
- instructions. */
- if (rebuild_jump_labels_after_combine)
- {
- timevar_push (TV_JUMP);
- rebuild_jump_labels (insns);
- timevar_pop (TV_JUMP);
+ rest_of_handle_combine (decl, insns);
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
- }
-
- close_dump_file (DFI_combine, print_rtl_with_bb, insns);
- timevar_pop (TV_COMBINE);
-
- ggc_collect ();
- }
-
- /* Rerun if-conversion, as combine may have simplified things enough to
- now meet sequence length restrictions. */
if (flag_if_conversion)
- {
- timevar_push (TV_IFCVT);
- open_dump_file (DFI_ce2, decl);
-
- no_new_pseudos = 0;
- if_convert (1);
- no_new_pseudos = 1;
+ rest_of_handle_if_after_combine (decl, insns);
- close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
- timevar_pop (TV_IFCVT);
- }
-
- /* Register allocation pre-pass, to reduce number of moves
- necessary for two-address machines. */
if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
- {
- timevar_push (TV_REGMOVE);
- open_dump_file (DFI_regmove, decl);
-
- regmove_optimize (insns, max_reg_num (), rtl_dump_file);
-
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
- close_dump_file (DFI_regmove, print_rtl_with_bb, insns);
- timevar_pop (TV_REGMOVE);
-
- ggc_collect ();
- }
+ rest_of_handle_regmove (decl, insns);
/* Do unconditional splitting before register allocation to allow machine
description to add extra information not needed previously. */
split_all_insns (1);
- /* Any of the several passes since flow1 will have munged register
- lifetime data a bit. */
- register_life_up_to_date = 0;
-
#ifdef OPTIMIZE_MODE_SWITCHING
timevar_push (TV_MODE_SWITCH);
@@ -3187,31 +3396,14 @@ rest_of_compilation (decl)
timevar_pop (TV_MODE_SWITCH);
#endif
- timevar_push (TV_SCHED);
+ /* Any of the several passes since flow1 will have munged register
+ lifetime data a bit. We need it to be up to date for scheduling
+ (see handling of reg_known_equiv in init_alias_analysis). */
+ recompute_reg_usage (insns, !optimize_size);
#ifdef INSN_SCHEDULING
-
- /* Print function header into sched dump now
- because doing the sched analysis makes some of the dump. */
- if (optimize > 0 && flag_schedule_insns)
- {
- open_dump_file (DFI_sched, decl);
-
- /* Do control and data sched analysis,
- and write some of the results to dump file. */
-
- schedule_insns (rtl_dump_file);
-
- close_dump_file (DFI_sched, print_rtl_with_bb, insns);
-
- /* Register lifetime information was updated as part of verifying
- the schedule. */
- register_life_up_to_date = 1;
- }
+ rest_of_handle_sched (decl, insns);
#endif
- timevar_pop (TV_SCHED);
-
- ggc_collect ();
/* Determine if the current function is a leaf before running reload
since this can impact optimizations done by the prologue and
@@ -3221,107 +3413,14 @@ rest_of_compilation (decl)
timevar_push (TV_LOCAL_ALLOC);
open_dump_file (DFI_lreg, decl);
- /* Allocate pseudo-regs that are used only within 1 basic block.
-
- RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
- jump optimizer after register allocation and reloading are finished. */
-
- if (! register_life_up_to_date)
- recompute_reg_usage (insns, ! optimize_size);
-
if (flag_new_regalloc)
{
- delete_trivially_dead_insns (insns, max_reg_num ());
- reg_alloc ();
-
- timevar_pop (TV_LOCAL_ALLOC);
- if (dump_file[DFI_lreg].enabled)
- {
- timevar_push (TV_DUMP);
-
- close_dump_file (DFI_lreg, NULL, NULL);
- timevar_pop (TV_DUMP);
- }
-
- /* XXX clean up the whole mess to bring live info in shape again. */
- timevar_push (TV_GLOBAL_ALLOC);
- open_dump_file (DFI_greg, decl);
-
- build_insn_chain (insns);
- failure = reload (insns, 0);
-
- timevar_pop (TV_GLOBAL_ALLOC);
-
- if (dump_file[DFI_greg].enabled)
- {
- timevar_push (TV_DUMP);
-
- dump_global_regs (rtl_dump_file);
-
- close_dump_file (DFI_greg, print_rtl_with_bb, insns);
- timevar_pop (TV_DUMP);
- }
-
- if (failure)
- goto exit_rest_of_compilation;
- reload_completed = 1;
- rebuild_label_notes_after_reload = 0;
+ if (rest_of_handle_new_regalloc (decl, insns))
+ goto exit_rest_of_compilation;
}
else
{
- /* Allocate the reg_renumber array. */
- allocate_reg_info (max_regno, FALSE, TRUE);
-
- /* And the reg_equiv_memory_loc array. */
- reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx));
-
- allocate_initial_values (reg_equiv_memory_loc);
-
- regclass (insns, max_reg_num (), rtl_dump_file);
- rebuild_label_notes_after_reload = local_alloc ();
-
- timevar_pop (TV_LOCAL_ALLOC);
-
- if (dump_file[DFI_lreg].enabled)
- {
- timevar_push (TV_DUMP);
-
- dump_flow_info (rtl_dump_file);
- dump_local_alloc (rtl_dump_file);
-
- close_dump_file (DFI_lreg, print_rtl_with_bb, insns);
- timevar_pop (TV_DUMP);
- }
-
- ggc_collect ();
-
- timevar_push (TV_GLOBAL_ALLOC);
- open_dump_file (DFI_greg, decl);
-
- /* If optimizing, allocate remaining pseudo-regs. Do the reload
- pass fixing up any insns that are invalid. */
-
- if (optimize)
- failure = global_alloc (rtl_dump_file);
- else
- {
- build_insn_chain (insns);
- failure = reload (insns, 0);
- }
-
- timevar_pop (TV_GLOBAL_ALLOC);
-
- if (dump_file[DFI_greg].enabled)
- {
- timevar_push (TV_DUMP);
-
- dump_global_regs (rtl_dump_file);
-
- close_dump_file (DFI_greg, print_rtl_with_bb, insns);
- timevar_pop (TV_DUMP);
- }
-
- if (failure)
+ if (rest_of_handle_old_regalloc (decl, insns))
goto exit_rest_of_compilation;
}
@@ -3334,22 +3433,13 @@ rest_of_compilation (decl)
{
timevar_push (TV_RELOAD_CSE_REGS);
reload_cse_regs (insns);
+ /* reload_cse_regs can eliminate potentially-trapping MEMs.
+ Remove any EH edges associated with them. */
+ if (flag_non_call_exceptions)
+ purge_all_dead_edges (0);
timevar_pop (TV_RELOAD_CSE_REGS);
}
- /* Register allocation and reloading may have turned an indirect jump into
- a direct jump. If so, we must rebuild the JUMP_LABEL fields of
- jumping instructions. */
- if (rebuild_label_notes_after_reload)
- {
- timevar_push (TV_JUMP);
-
- rebuild_jump_labels (insns);
- purge_all_dead_edges (0);
-
- timevar_pop (TV_JUMP);
- }
-
close_dump_file (DFI_postreload, print_rtl_with_bb, insns);
/* Re-create the death notes which were deleted during reload. */
@@ -3366,6 +3456,17 @@ rest_of_compilation (decl)
#endif
split_all_insns (0);
+ if (flag_branch_target_load_optimize)
+ {
+ open_dump_file (DFI_branch_target_load, decl);
+
+ branch_target_load_optimize (insns, false);
+
+ close_dump_file (DFI_branch_target_load, print_rtl_with_bb, insns);
+
+ ggc_collect ();
+ }
+
if (optimize)
cleanup_cfg (CLEANUP_EXPENSIVE);
@@ -3374,10 +3475,11 @@ rest_of_compilation (decl)
it and the rest of the code and also allows delayed branch
scheduling to operate in the epilogue. */
thread_prologue_and_epilogue_insns (insns);
+ epilogue_completed = 1;
if (optimize)
{
- life_analysis (insns, rtl_dump_file, PROP_FINAL);
+ life_analysis (insns, rtl_dump_file, PROP_POSTRELOAD);
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE
| (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
@@ -3411,49 +3513,52 @@ rest_of_compilation (decl)
}
#endif
- if (optimize > 0 && (flag_rename_registers || flag_cprop_registers))
- {
- timevar_push (TV_RENAME_REGISTERS);
- open_dump_file (DFI_rnreg, decl);
-
- if (flag_rename_registers)
- regrename_optimize ();
- if (flag_cprop_registers)
- copyprop_hardreg_forward ();
-
- close_dump_file (DFI_rnreg, print_rtl_with_bb, insns);
- timevar_pop (TV_RENAME_REGISTERS);
- }
-
+ open_dump_file (DFI_ce3, decl);
+ if (optimize)
+ /* Last attempt to optimize CFG, as scheduling, peepholing and insn
+ splitting possibly introduced more crossjumping opportunities. */
+ cleanup_cfg (CLEANUP_EXPENSIVE
+ | CLEANUP_UPDATE_LIFE
+ | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
if (flag_if_conversion2)
{
timevar_push (TV_IFCVT2);
- open_dump_file (DFI_ce3, decl);
if_convert (1);
- close_dump_file (DFI_ce3, print_rtl_with_bb, insns);
timevar_pop (TV_IFCVT2);
}
+ close_dump_file (DFI_ce3, print_rtl_with_bb, insns);
-#ifdef INSN_SCHEDULING
- if (optimize > 0 && flag_schedule_insns_after_reload)
+ if (optimize > 0)
{
- timevar_push (TV_SCHED2);
- open_dump_file (DFI_sched2, decl);
+ if (flag_rename_registers || flag_cprop_registers)
+ rest_of_handle_regrename (decl, insns);
- /* Do control and data sched analysis again,
- and write some more of the results to dump file. */
+ rest_of_handle_reorder_blocks (decl, insns);
+ }
- split_all_insns (1);
+ if (flag_branch_target_load_optimize2)
+ {
+ /* Leave this a warning for now so that it is possible to experiment
+ with running this pass twice. In 3.6, we should either make this
+ an error, or use separate dump files. */
+ if (flag_branch_target_load_optimize)
+ warning ("branch target register load optimization is not intended "
+ "to be run twice");
- schedule_insns (rtl_dump_file);
+ open_dump_file (DFI_branch_target_load, decl);
- close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
- timevar_pop (TV_SCHED2);
+ branch_target_load_optimize (insns, true);
+
+ close_dump_file (DFI_branch_target_load, print_rtl_with_bb, insns);
ggc_collect ();
}
+
+#ifdef INSN_SCHEDULING
+ if (optimize > 0 && flag_schedule_insns_after_reload)
+ rest_of_handle_sched2 (decl, insns);
#endif
#ifdef LEAF_REGISTERS
@@ -3462,90 +3567,23 @@ rest_of_compilation (decl)
#endif
#ifdef STACK_REGS
-#if defined (HAVE_ATTR_length)
- /* If flow2 creates new instructions which need splitting
- and scheduling after reload is not done, they might not be
- splitten until final which doesn't allow splitting
- if HAVE_ATTR_length. */
-#ifdef INSN_SCHEDULING
- if (optimize && !flag_schedule_insns_after_reload)
-#else
- if (optimize)
-#endif
- {
- timevar_push (TV_SHORTEN_BRANCH);
- split_all_insns (1);
- timevar_pop (TV_SHORTEN_BRANCH);
- }
-#endif
-
- timevar_push (TV_REG_STACK);
- open_dump_file (DFI_stack, decl);
-
- reg_to_stack (insns, rtl_dump_file);
-
- close_dump_file (DFI_stack, print_rtl_with_bb, insns);
- timevar_pop (TV_REG_STACK);
-
- ggc_collect ();
+ rest_of_handle_stack_regs (decl, insns);
#endif
- if (optimize > 0)
- {
- timevar_push (TV_REORDER_BLOCKS);
- open_dump_file (DFI_bbro, decl);
-
- /* Last attempt to optimize CFG, as scheduling, peepholing and insn
- splitting possibly introduced more crossjumping oppurtuntities.
- Except that we can't actually run crossjumping without running
- another DCE pass, which we can't do after reg-stack. */
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
- | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
- if (flag_reorder_blocks)
- {
- reorder_basic_blocks ();
- cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
- }
- close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
- timevar_pop (TV_REORDER_BLOCKS);
- }
compute_alignments ();
/* CFG is no longer maintained up-to-date. */
free_bb_for_insn ();
- /* If a machine dependent reorganization is needed, call it. */
-#ifdef MACHINE_DEPENDENT_REORG
- timevar_push (TV_MACH_DEP);
- open_dump_file (DFI_mach, decl);
-
- MACHINE_DEPENDENT_REORG (insns);
-
- close_dump_file (DFI_mach, print_rtl, insns);
- timevar_pop (TV_MACH_DEP);
-
- ggc_collect ();
-#endif
+ if (targetm.machine_dependent_reorg != 0)
+ rest_of_handle_machine_reorg (decl, insns);
purge_line_number_notes (insns);
cleanup_barriers ();
- /* If a scheduling pass for delayed branches is to be done,
- call the scheduling code. */
-
#ifdef DELAY_SLOTS
if (optimize > 0 && flag_delayed_branch)
- {
- timevar_push (TV_DBR_SCHED);
- open_dump_file (DFI_dbr, decl);
-
- dbr_schedule (insns, rtl_dump_file);
-
- close_dump_file (DFI_dbr, print_rtl, insns);
- timevar_pop (TV_DBR_SCHED);
-
- ggc_collect ();
- }
+ rest_of_handle_delay_slots (decl, insns);
#endif
#if defined (HAVE_ATTR_length) && !defined (STACK_REGS)
@@ -3567,54 +3605,7 @@ rest_of_compilation (decl)
of other functions later in this translation unit. */
TREE_NOTHROW (current_function_decl) = 1;
- /* Now turn the rtl into assembler code. */
-
- timevar_push (TV_FINAL);
- {
- rtx x;
- const char *fnname;
-
- /* Get the function's name, as described by its RTL. This may be
- different from the DECL_NAME name used in the source file. */
-
- x = DECL_RTL (decl);
- if (GET_CODE (x) != MEM)
- abort ();
- x = XEXP (x, 0);
- if (GET_CODE (x) != SYMBOL_REF)
- abort ();
- fnname = XSTR (x, 0);
-
- assemble_start_function (decl, fnname);
- final_start_function (insns, asm_out_file, optimize);
- final (insns, asm_out_file, optimize, 0);
- final_end_function ();
-
-#ifdef IA64_UNWIND_INFO
- /* ??? The IA-64 ".handlerdata" directive must be issued before
- the ".endp" directive that closes the procedure descriptor. */
- output_function_exception_table ();
-#endif
-
- assemble_end_function (decl, fnname);
-
-#ifndef IA64_UNWIND_INFO
- /* Otherwise, it feels unclean to switch sections in the middle. */
- output_function_exception_table ();
-#endif
-
- if (! quiet_flag)
- fflush (asm_out_file);
-
- /* Release all memory allocated by flow. */
- free_basic_block_vars (0);
-
- /* Release all memory held by regsets now. */
- regset_release_memory ();
- }
- timevar_pop (TV_FINAL);
-
- ggc_collect ();
+ rest_of_handle_final (decl, insns);
/* Write DBX symbols if requested. */
@@ -3633,6 +3624,8 @@ rest_of_compilation (decl)
exit_rest_of_compilation:
+ coverage_end_function ();
+
/* In case the function was not output,
don't leave any temporary anonymous types
queued up for sdb output. */
@@ -3642,6 +3635,7 @@ rest_of_compilation (decl)
#endif
reload_completed = 0;
+ epilogue_completed = 0;
flow2_completed = 0;
no_new_pseudos = 0;
@@ -3659,6 +3653,16 @@ rest_of_compilation (decl)
timevar_pop (TV_FINAL);
+ if ((*targetm.binds_local_p) (current_function_decl))
+ {
+ int pref = cfun->preferred_stack_boundary;
+ if (cfun->recursive_call_emit
+ && cfun->stack_alignment_needed > cfun->preferred_stack_boundary)
+ pref = cfun->stack_alignment_needed;
+ cgraph_rtl_info (current_function_decl)->preferred_incoming_stack_boundary
+ = pref;
+ }
+
/* Make sure volatile mem refs aren't considered valid operands for
arithmetic insns. We must call this here if this is a nested inline
function, since the above code leaves us in the init_recog state
@@ -3675,9 +3679,6 @@ rest_of_compilation (decl)
if (! DECL_DEFER_OUTPUT (decl))
{
free_after_compilation (cfun);
-
- /* Clear integrate.c's pointer to the cfun structure we just
- destroyed. */
DECL_SAVED_INSNS (decl) = 0;
}
cfun = 0;
@@ -3686,142 +3687,10 @@ rest_of_compilation (decl)
timevar_pop (TV_REST_OF_COMPILATION);
}
-
-static void
-display_help ()
-{
- int undoc;
- unsigned long i;
- const char *lang;
-
- printf (_(" -ffixed-<register> Mark <register> as being unavailable to the compiler\n"));
- printf (_(" -fcall-used-<register> Mark <register> as being corrupted by function calls\n"));
- printf (_(" -fcall-saved-<register> Mark <register> as being preserved across functions\n"));
- printf (_(" -finline-limit=<number> Limits the size of inlined functions to <number>\n"));
- printf (_(" -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line. 0 suppresses line-wrapping\n"));
- printf (_(" -fdiagnostics-show-location=[once | every-line] Indicates how often source location information should be emitted, as prefix, at the beginning of diagnostics when line-wrapping\n"));
- printf (_(" -ftls-model=[global-dynamic | local-dynamic | initial-exec | local-exec] Indicates the default thread-local storage code generation model\n"));
- printf (_(" -fstack-limit-register=<register> Trap if the stack goes past <register>\n"));
- printf (_(" -fstack-limit-symbol=<name> Trap if the stack goes past symbol <name>\n"));
- printf (_(" -frandom-seed=<string> Make compile reproducible using <string>\n"));
-
-
- for (i = ARRAY_SIZE (f_options); i--;)
- {
- const char *description = f_options[i].description;
-
- if (description != NULL && *description != 0)
- printf (" -f%-21s %s\n",
- f_options[i].string, _(description));
- }
-
- printf (_(" -O[number] Set optimization level to [number]\n"));
- printf (_(" -Os Optimize for space rather than speed\n"));
- for (i = LAST_PARAM; i--;)
- {
- const char *description = compiler_params[i].help;
- const int length = 21 - strlen (compiler_params[i].option);
-
- if (description != NULL && *description != 0)
- printf (" --param %s=<value>%.*s%s\n",
- compiler_params[i].option,
- length > 0 ? length : 1, " ",
- _(description));
- }
- printf (_(" -pedantic Issue warnings needed by strict compliance to ISO C\n"));
- printf (_(" -pedantic-errors Like -pedantic except that errors are produced\n"));
- printf (_(" -w Suppress warnings\n"));
- printf (_(" -W Enable extra warnings\n"));
- for (i = ARRAY_SIZE (W_options); i--;)
- {
- const char *description = W_options[i].description;
-
- if (description != NULL && *description != 0)
- printf (" -W%-21s %s\n",
- W_options[i].string, _(description));
- }
-
- printf (_(" -Wunused Enable unused warnings\n"));
- printf (_(" -Wlarger-than-<number> Warn if an object is larger than <number> bytes\n"));
- printf (_(" -p Enable function profiling\n"));
- printf (_(" -o <file> Place output into <file> \n"));
- printf (_("\
- -G <number> Put global and static data smaller than <number>\n\
- bytes into a special section (on some targets)\n"));
-
- for (i = ARRAY_SIZE (debug_args); i--;)
- {
- if (debug_args[i].description != NULL)
- printf (" -g%-21s %s\n",
- debug_args[i].arg, _(debug_args[i].description));
- }
-
- printf (_(" -aux-info <file> Emit declaration info into <file>\n"));
- printf (_(" -quiet Do not display functions compiled or elapsed time\n"));
- printf (_(" -version Display the compiler's version\n"));
- printf (_(" -d[letters] Enable dumps from specific passes of the compiler\n"));
- printf (_(" -dumpbase <file> Base name to be used for dumps from specific passes\n"));
-#if defined INSN_SCHEDULING
- printf (_(" -fsched-verbose=<number> Set the verbosity level of the scheduler\n"));
-#endif
- printf (_(" --help Display this information\n"));
-
- undoc = 0;
- lang = "language";
-
- /* Display descriptions of language specific options.
- If there is no description, note that there is an undocumented option.
- If the description is empty, do not display anything. (This allows
- options to be deliberately undocumented, for whatever reason).
- If the option string is missing, then this is a marker, indicating
- that the description string is in fact the name of a language, whose
- language specific options are to follow. */
-
- if (ARRAY_SIZE (documented_lang_options) > 1)
- {
- printf (_("\nLanguage specific options:\n"));
-
- for (i = 0; i < ARRAY_SIZE (documented_lang_options); i++)
- {
- const char *description = documented_lang_options[i].description;
- const char *option = documented_lang_options[i].option;
-
- if (description == NULL)
- {
- undoc = 1;
-
- if (extra_warnings)
- printf (_(" %-23.23s [undocumented]\n"), option);
- }
- else if (*description == 0)
- continue;
- else if (option == NULL)
- {
- if (undoc)
- printf
- (_("\nThere are undocumented %s specific options as well.\n"),
- lang);
- undoc = 0;
-
- printf (_("\n Options for %s:\n"), description);
-
- lang = description;
- }
- else
- printf (" %-23.23s %s\n", option, _(description));
- }
- }
-
- if (undoc)
- printf (_("\nThere are undocumented %s specific options as well.\n"),
- lang);
-
- display_target_options ();
-}
-
-static void
-display_target_options ()
+/* Display help for target options. */
+void
+display_target_options (void)
{
int undoc, i;
static bool displayed = false;
@@ -3829,6 +3698,7 @@ display_target_options ()
/* Avoid double printing for --help --target-help. */
if (displayed)
return;
+
displayed = true;
if (ARRAY_SIZE (target_switches) > 1
@@ -3855,10 +3725,10 @@ display_target_options ()
undoc = 1;
if (extra_warnings)
- printf (_(" -m%-23.23s [undocumented]\n"), option);
+ printf (_(" -m%-23s [undocumented]\n"), option);
}
else if (*description != 0)
- doc += printf (" -m%-23.23s %s\n", option, _(description));
+ doc += printf (" -m%-23s %s\n", option, _(description));
}
#ifdef TARGET_OPTIONS
@@ -3874,10 +3744,10 @@ display_target_options ()
undoc = 1;
if (extra_warnings)
- printf (_(" -m%-23.23s [undocumented]\n"), option);
+ printf (_(" -m%-23s [undocumented]\n"), option);
}
else if (*description != 0)
- doc += printf (" -m%-23.23s %s\n", option, _(description));
+ doc += printf (" -m%-23s %s\n", option, _(description));
}
#endif
if (undoc)
@@ -3889,12 +3759,11 @@ display_target_options ()
}
}
}
-
+
/* Parse a -d... command line switch. */
-static void
-decode_d_option (arg)
- const char *arg;
+void
+decode_d_option (const char *arg)
{
int i, c, matched;
@@ -3927,6 +3796,9 @@ decode_d_option (arg)
case 'D': /* These are handled by the preprocessor. */
case 'I':
break;
+ case 'H':
+ setup_core_dumping();
+ break;
default:
matched = 0;
@@ -3943,573 +3815,17 @@ decode_d_option (arg)
}
}
-/* Parse a -f... command line switch. ARG is the value after the -f.
- It is safe to access 'ARG - 2' to generate the full switch name.
- Return the number of strings consumed. */
-
-static int
-decode_f_option (arg)
- const char *arg;
-{
- int j;
- const char *option_value = NULL;
-
- /* Search for the option in the table of binary f options. */
- for (j = ARRAY_SIZE (f_options); j--;)
- {
- if (!strcmp (arg, f_options[j].string))
- {
- *f_options[j].variable = f_options[j].on_value;
- return 1;
- }
-
- if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-'
- && ! strcmp (arg + 3, f_options[j].string))
- {
- *f_options[j].variable = ! f_options[j].on_value;
- return 1;
- }
- }
-
- if (!strcmp (arg, "fast-math"))
- set_fast_math_flags (1);
- else if (!strcmp (arg, "no-fast-math"))
- set_fast_math_flags (0);
- else if ((option_value = skip_leading_substring (arg, "inline-limit-"))
- || (option_value = skip_leading_substring (arg, "inline-limit=")))
- {
- int val =
- read_integral_parameter (option_value, arg - 2,
- MAX_INLINE_INSNS);
- set_param_value ("max-inline-insns", val);
- set_param_value ("max-inline-insns-single", val/2);
- set_param_value ("max-inline-insns-auto", val/2);
- set_param_value ("max-inline-insns-rtl", val);
- if (val/4 < MIN_INLINE_INSNS)
- {
- if (val/4 > 10)
- set_param_value ("min-inline-insns", val/4);
- else
- set_param_value ("min-inline-insns", 10);
- }
- }
- else if ((option_value = skip_leading_substring (arg, "tls-model=")))
- {
- if (strcmp (option_value, "global-dynamic") == 0)
- flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
- else if (strcmp (option_value, "local-dynamic") == 0)
- flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC;
- else if (strcmp (option_value, "initial-exec") == 0)
- flag_tls_default = TLS_MODEL_INITIAL_EXEC;
- else if (strcmp (option_value, "local-exec") == 0)
- flag_tls_default = TLS_MODEL_LOCAL_EXEC;
- else
- warning ("`%s': unknown tls-model option", arg - 2);
- }
-#ifdef INSN_SCHEDULING
- else if ((option_value = skip_leading_substring (arg, "sched-verbose=")))
- fix_sched_param ("verbose", option_value);
-#endif
- else if ((option_value = skip_leading_substring (arg, "fixed-")))
- fix_register (option_value, 1, 1);
- else if ((option_value = skip_leading_substring (arg, "call-used-")))
- fix_register (option_value, 0, 1);
- else if ((option_value = skip_leading_substring (arg, "call-saved-")))
- fix_register (option_value, 0, 0);
- else if ((option_value = skip_leading_substring (arg, "align-loops=")))
- align_loops = read_integral_parameter (option_value, arg - 2, align_loops);
- else if ((option_value = skip_leading_substring (arg, "align-functions=")))
- align_functions
- = read_integral_parameter (option_value, arg - 2, align_functions);
- else if ((option_value = skip_leading_substring (arg, "align-jumps=")))
- align_jumps = read_integral_parameter (option_value, arg - 2, align_jumps);
- else if ((option_value = skip_leading_substring (arg, "align-labels=")))
- align_labels
- = read_integral_parameter (option_value, arg - 2, align_labels);
- else if ((option_value
- = skip_leading_substring (arg, "stack-limit-register=")))
- {
- int reg = decode_reg_name (option_value);
- if (reg < 0)
- error ("unrecognized register name `%s'", option_value);
- else
- stack_limit_rtx = gen_rtx_REG (Pmode, reg);
- }
- else if ((option_value
- = skip_leading_substring (arg, "stack-limit-symbol=")))
- {
- const char *nm;
- nm = ggc_strdup (option_value);
- stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, nm);
- }
- else if ((option_value
- = skip_leading_substring (arg, "message-length=")))
- output_set_maximum_length
- (&global_dc->buffer, read_integral_parameter
- (option_value, arg - 2, diagnostic_line_cutoff (global_dc)));
- else if ((option_value
- = skip_leading_substring (arg, "diagnostics-show-location=")))
- {
- if (!strcmp (option_value, "once"))
- diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
- else if (!strcmp (option_value, "every-line"))
- diagnostic_prefixing_rule (global_dc)
- = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
- else
- error ("unrecognized option `%s'", arg - 2);
- }
- else if (!strcmp (arg, "no-stack-limit"))
- stack_limit_rtx = NULL_RTX;
- else if ((option_value = skip_leading_substring (arg, "random-seed=")))
- flag_random_seed = option_value;
- else if (!strcmp (arg, "no-random-seed"))
- flag_random_seed = NULL;
- else if (!strcmp (arg, "preprocessed"))
- /* Recognize this switch but do nothing. This prevents warnings
- about an unrecognized switch if cpplib has not been linked in. */
- ;
- else
- return 0;
-
- return 1;
-}
-
-/* Parse a -W... command line switch. ARG is the value after the -W.
- It is safe to access 'ARG - 2' to generate the full switch name.
- Return the number of strings consumed. */
-
-static int
-decode_W_option (arg)
- const char *arg;
-{
- const char *option_value = NULL;
- int j;
-
- /* Search for the option in the table of binary W options. */
-
- for (j = ARRAY_SIZE (W_options); j--;)
- {
- if (!strcmp (arg, W_options[j].string))
- {
- *W_options[j].variable = W_options[j].on_value;
- return 1;
- }
-
- if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-'
- && ! strcmp (arg + 3, W_options[j].string))
- {
- *W_options[j].variable = ! W_options[j].on_value;
- return 1;
- }
- }
-
- if ((option_value = skip_leading_substring (arg, "id-clash-")))
- warning ("-Wid-clash-LEN is no longer supported");
- else if ((option_value = skip_leading_substring (arg, "larger-than-")))
- {
- larger_than_size = read_integral_parameter (option_value, arg - 2, -1);
-
- warn_larger_than = larger_than_size != -1;
- }
- else if (!strcmp (arg, "unused"))
- {
- set_Wunused (1);
- }
- else if (!strcmp (arg, "no-unused"))
- {
- set_Wunused (0);
- }
- else
- return 0;
-
- return 1;
-}
-
-/* Parse a -g... command line switch. ARG is the value after the -g.
- It is safe to access 'ARG - 2' to generate the full switch name.
- Return the number of strings consumed. */
-
-static int
-decode_g_option (arg)
- const char *arg;
-{
- static unsigned level = 0;
- /* A lot of code assumes write_symbols == NO_DEBUG if the
- debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
- of what debugging type has been selected). This records the
- selected type. It is an error to specify more than one
- debugging type. */
- static enum debug_info_type selected_debug_type = NO_DEBUG;
- /* Non-zero if debugging format has been explicitly set.
- -g and -ggdb don't explicitly set the debugging format so
- -gdwarf -g3 is equivalent to -gdwarf3. */
- static int type_explicitly_set_p = 0;
- /* Indexed by enum debug_info_type. */
- static const char *const debug_type_names[] =
- {
- "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff", "vms"
- };
-
- /* The maximum admissible debug level value. */
- static const unsigned max_debug_level = 3;
-
- /* Look up ARG in the table. */
- for (da = debug_args; da->arg; da++)
- {
- const int da_len = strlen (da->arg);
-
- if (da_len == 0 || ! strncmp (arg, da->arg, da_len))
- {
- enum debug_info_type type = da->debug_type;
- const char *p = arg + da_len;
-
- if (*p && ! ISDIGIT (*p))
- continue;
-
- /* A debug flag without a level defaults to level 2.
- Note we do not want to call read_integral_parameter
- for that case since it will call atoi which
- will return zero.
-
- ??? We may want to generalize the interface to
- read_integral_parameter to better handle this case
- if this case shows up often. */
- if (*p)
- level = read_integral_parameter (p, 0, max_debug_level + 1);
- else
- level = (level == 0) ? 2 : level;
-
- if (da_len > 1 && *p && !strncmp (arg, "dwarf", da_len))
- {
- error ("use -gdwarf -g%d for DWARF v1, level %d",
- level, level);
- if (level == 2)
- error ("use -gdwarf-2 for DWARF v2");
- }
-
- if (level > max_debug_level)
- {
- warning ("\
-ignoring option `%s' due to invalid debug level specification",
- arg - 2);
- level = debug_info_level;
- }
-
- if (type == NO_DEBUG)
- {
- type = PREFERRED_DEBUGGING_TYPE;
-
- if (da_len > 1 && strncmp (arg, "gdb", da_len) == 0)
- {
-#ifdef DWARF2_DEBUGGING_INFO
- type = DWARF2_DEBUG;
-#else
-#ifdef DBX_DEBUGGING_INFO
- type = DBX_DEBUG;
-#endif
-#endif
- }
- }
-
- if (type == NO_DEBUG)
- warning ("`%s': unknown or unsupported -g option", arg - 2);
-
- /* Does it conflict with an already selected type? */
- if (type_explicitly_set_p
- /* -g/-ggdb don't conflict with anything. */
- && da->debug_type != NO_DEBUG
- && type != selected_debug_type)
- warning ("`%s' ignored, conflicts with `-g%s'",
- arg - 2, debug_type_names[(int) selected_debug_type]);
- else
- {
- /* If the format has already been set, -g/-ggdb
- only change the debug level. */
- if (type_explicitly_set_p && da->debug_type == NO_DEBUG)
- /* Don't change debugging type. */
- ;
- else
- {
- selected_debug_type = type;
- type_explicitly_set_p = da->debug_type != NO_DEBUG;
- }
-
- write_symbols = (level == 0
- ? NO_DEBUG
- : selected_debug_type);
- use_gnu_debug_info_extensions = da->use_extensions_p;
- debug_info_level = (enum debug_info_level) level;
- }
-
- break;
- }
- }
-
- if (! da->arg)
- return 0;
-
- return 1;
-}
-
-/* Decode the first argument in the argv as a language-independent option.
- Return the number of strings consumed. */
-
-static unsigned int
-independent_decode_option (argc, argv)
- int argc;
- char **argv;
+/* Indexed by enum debug_info_type. */
+const char *const debug_type_names[] =
{
- char *arg = argv[0];
-
- if (arg[0] != '-' || arg[1] == 0)
- {
- if (arg[0] == '+')
- return 0;
-
- filename = arg;
-
- return 1;
- }
-
- arg++;
-
- if (!strcmp (arg, "-help"))
- {
- display_help ();
- exit_after_options = 1;
- return 1;
- }
-
- if (!strcmp (arg, "-target-help"))
- {
- display_target_options ();
- exit_after_options = 1;
- return 1;
- }
-
- if (!strcmp (arg, "-version"))
- {
- print_version (stderr, "");
- exit_after_options = 1;
- return 1;
- }
-
- /* Handle '--param <name>=<value>'. */
- if (strcmp (arg, "-param") == 0)
- {
- char *equal;
-
- if (argc == 1)
- {
- error ("-param option missing argument");
- return 1;
- }
-
- /* Get the '<name>=<value>' parameter. */
- arg = argv[1];
- /* Look for the `='. */
- equal = strchr (arg, '=');
- if (!equal)
- error ("invalid --param option: %s", arg);
- else
- {
- int val;
-
- /* Zero out the `=' sign so that we get two separate strings. */
- *equal = '\0';
- /* Figure out what value is specified. */
- val = read_integral_parameter (equal + 1, NULL, INVALID_PARAM_VAL);
- if (val != INVALID_PARAM_VAL)
- set_param_value (arg, val);
- else
- error ("invalid parameter value `%s'", equal + 1);
- }
-
- return 2;
- }
-
- if (*arg == 'Y')
- arg++;
-
- switch (*arg)
- {
- default:
- return 0;
-
- case 'O':
- /* Already been treated in main (). Do nothing. */
- break;
-
- case 'm':
- set_target_switch (arg + 1);
- break;
-
- case 'f':
- return decode_f_option (arg + 1);
-
- case 'g':
- return decode_g_option (arg + 1);
-
- case 'd':
- if (!strcmp (arg, "dumpbase"))
- {
- if (argc == 1)
- return 0;
-
- if (argv[1][0])
- dump_base_name = argv[1];
-
- return 2;
- }
- else
- decode_d_option (arg + 1);
- break;
-
- case 'p':
- if (!strcmp (arg, "pedantic"))
- pedantic = 1;
- else if (!strcmp (arg, "pedantic-errors"))
- flag_pedantic_errors = pedantic = 1;
- else if (arg[1] == 0)
- profile_flag = 1;
- else
- return 0;
- break;
-
- case 'q':
- if (!strcmp (arg, "quiet"))
- quiet_flag = 1;
- else
- return 0;
- break;
-
- case 'v':
- if (!strcmp (arg, "version"))
- version_flag = 1;
- else
- return 0;
- break;
-
- case 'w':
- if (arg[1] == 0)
- inhibit_warnings = 1;
- else
- return 0;
- break;
-
- case 'W':
- if (arg[1] == 0)
- {
- extra_warnings = 1;
- /* We save the value of warn_uninitialized, since if they put
- -Wuninitialized on the command line, we need to generate a
- warning about not using it without also specifying -O. */
- if (warn_uninitialized != 1)
- warn_uninitialized = 2;
- }
- else
- return decode_W_option (arg + 1);
- break;
-
- case 'a':
- if (!strncmp (arg, "aux-info", 8))
- {
- if (arg[8] == '\0')
- {
- if (argc == 1)
- return 0;
-
- aux_info_file_name = argv[1];
- flag_gen_aux_info = 1;
- return 2;
- }
- else if (arg[8] == '=')
- {
- aux_info_file_name = arg + 9;
- flag_gen_aux_info = 1;
- }
- else
- return 0;
- }
- else if (!strcmp (arg, "auxbase"))
- {
- if (argc == 1)
- return 0;
-
- if (argv[1][0])
- aux_base_name = argv[1];
-
- return 2;
- }
- else if (!strcmp (arg, "auxbase-strip"))
- {
- if (argc == 1)
- return 0;
-
- if (argv[1][0])
- {
- strip_off_ending (argv[1], strlen (argv[1]));
- if (argv[1][0])
- aux_base_name = argv[1];
- }
-
- return 2;
- }
- else
- return 0;
- break;
-
- case 'o':
- if (arg[1] == 0)
- {
- if (argc == 1)
- return 0;
-
- asm_file_name = argv[1];
- return 2;
- }
- return 0;
-
- case 'G':
- {
- int g_switch_val;
- int return_val;
-
- if (arg[1] == 0)
- {
- if (argc == 1)
- return 0;
-
- g_switch_val = read_integral_parameter (argv[1], 0, -1);
- return_val = 2;
- }
- else
- {
- g_switch_val = read_integral_parameter (arg + 1, 0, -1);
- return_val = 1;
- }
-
- if (g_switch_val == -1)
- return_val = 0;
- else
- {
- g_switch_set = TRUE;
- g_switch_value = g_switch_val;
- }
-
- return return_val;
- }
- }
+ "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff", "vms"
+};
- return 1;
-}
-
/* Decode -m switches. */
/* Decode the switch -mNAME. */
-static void
-set_target_switch (name)
- const char *name;
+void
+set_target_switch (const char *name)
{
size_t j;
int valid_target_option = 0;
@@ -4536,10 +3852,21 @@ set_target_switch (name)
for (j = 0; j < ARRAY_SIZE (target_options); j++)
{
int len = strlen (target_options[j].prefix);
- if (!strncmp (target_options[j].prefix, name, len))
+ if (target_options[j].value)
+ {
+ if (!strcmp (target_options[j].prefix, name))
+ {
+ *target_options[j].variable = target_options[j].value;
+ valid_target_option = 1;
+ }
+ }
+ else
{
- *target_options[j].variable = name + len;
- valid_target_option = 1;
+ if (!strncmp (target_options[j].prefix, name, len))
+ {
+ *target_options[j].variable = name + len;
+ valid_target_option = 1;
+ }
}
}
#endif
@@ -4547,15 +3874,13 @@ set_target_switch (name)
if (!valid_target_option)
error ("invalid option `%s'", name);
}
-
+
/* Print version information to FILE.
Each line begins with INDENT (for the case where FILE is the
assembler output file). */
-static void
-print_version (file, indent)
- FILE *file;
- const char *indent;
+void
+print_version (FILE *file, const char *indent)
{
#ifndef __VERSION__
#define __VERSION__ "[?]"
@@ -4579,10 +3904,9 @@ print_version (file, indent)
other code will catch a disk full though. */
static int
-print_single_switch (file, pos, max, indent, sep, term, type, name)
- FILE *file;
- int pos, max;
- const char *indent, *sep, *term, *type, *name;
+print_single_switch (FILE *file, int pos, int max,
+ const char *indent, const char *sep, const char *term,
+ const char *type, const char *name)
{
/* The ultrix fprintf returns 0 on success, so compute the result we want
here since we need it for the following test. */
@@ -4610,22 +3934,17 @@ print_single_switch (file, pos, max, indent, sep, term, type, name)
Each switch is separated from the next by SEP. */
static void
-print_switch_values (file, pos, max, indent, sep, term)
- FILE *file;
- int pos, max;
- const char *indent, *sep, *term;
+print_switch_values (FILE *file, int pos, int max,
+ const char *indent, const char *sep, const char *term)
{
size_t j;
- char **p;
+ const char **p;
/* Fill in the -frandom-seed option, if the user didn't pass it, so
- that it can be printed below. This helps reproducibility. Of
- course, the string may never be used, but we can't tell that at
- this point in the compile. */
- default_flag_random_seed ();
+ that it can be printed below. This helps reproducibility. */
+ randomize ();
/* Print the options as passed. */
-
pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
_("options passed: "), "");
@@ -4688,14 +4007,13 @@ print_switch_values (file, pos, max, indent, sep, term)
fprintf (file, "%s", term);
}
-
+
/* Open assembly code output file. Do this even if -fsyntax-only is
on, because then the driver will have provided the name of a
temporary file or bit bucket for us. NAME is the file specified on
the command line, possibly NULL. */
static void
-init_asm_output (name)
- const char *name;
+init_asm_output (const char *name)
{
if (name == NULL && asm_file_name == 0)
asm_out_file = stdout;
@@ -4704,7 +4022,7 @@ init_asm_output (name)
if (asm_file_name == 0)
{
int len = strlen (dump_base_name);
- char *dumpname = (char *) xmalloc (len + 6);
+ char *dumpname = xmalloc (len + 6);
memcpy (dumpname, dump_base_name, len + 1);
strip_off_ending (dumpname, len);
strcat (dumpname, ".s");
@@ -4713,21 +4031,19 @@ init_asm_output (name)
if (!strcmp (asm_file_name, "-"))
asm_out_file = stdout;
else
- asm_out_file = fopen (asm_file_name, "w");
+ asm_out_file = fopen (asm_file_name, "w+");
if (asm_out_file == 0)
- fatal_io_error ("can't open %s for writing", asm_file_name);
+ fatal_error ("can't open %s for writing: %m", asm_file_name);
}
#ifdef IO_BUFFER_SIZE
- setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
+ setvbuf (asm_out_file, xmalloc (IO_BUFFER_SIZE),
_IOFBF, IO_BUFFER_SIZE);
#endif
if (!flag_syntax_only)
{
-#ifdef ASM_FILE_START
- ASM_FILE_START (asm_out_file);
-#endif
+ targetm.asm_out.file_start ();
#ifdef ASM_COMMENT_START
if (flag_verbose_asm)
@@ -4743,15 +4059,154 @@ init_asm_output (name)
#endif
}
}
-
+
+/* Default version of get_pch_validity.
+ By default, every flag difference is fatal; that will be mostly right for
+ most targets, but completely right for very few. */
+
+void *
+default_get_pch_validity (size_t *len)
+{
+#ifdef TARGET_OPTIONS
+ size_t i;
+#endif
+ char *result, *r;
+
+ *len = sizeof (target_flags) + 2;
+#ifdef TARGET_OPTIONS
+ for (i = 0; i < ARRAY_SIZE (target_options); i++)
+ {
+ *len += 1;
+ if (*target_options[i].variable)
+ *len += strlen (*target_options[i].variable);
+ }
+#endif
+
+ result = r = xmalloc (*len);
+ r[0] = flag_pic;
+ r[1] = flag_pie;
+ r += 2;
+ memcpy (r, &target_flags, sizeof (target_flags));
+ r += sizeof (target_flags);
+
+#ifdef TARGET_OPTIONS
+ for (i = 0; i < ARRAY_SIZE (target_options); i++)
+ {
+ const char *str = *target_options[i].variable;
+ size_t l;
+ if (! str)
+ str = "";
+ l = strlen (str) + 1;
+ memcpy (r, str, l);
+ r += l;
+ }
+#endif
+
+ return result;
+}
+
+/* Default version of pch_valid_p. */
+
+const char *
+default_pch_valid_p (const void *data_p, size_t len)
+{
+ const char *data = (const char *)data_p;
+ const char *flag_that_differs = NULL;
+ size_t i;
+
+ /* -fpic and -fpie also usually make a PCH invalid. */
+ if (data[0] != flag_pic)
+ return _("created and used with different settings of -fpic");
+ if (data[1] != flag_pie)
+ return _("created and used with different settings of -fpie");
+ data += 2;
+
+ /* Check target_flags. */
+ if (memcmp (data, &target_flags, sizeof (target_flags)) != 0)
+ {
+ for (i = 0; i < ARRAY_SIZE (target_switches); i++)
+ {
+ int bits;
+ int tf;
+
+ memcpy (&tf, data, sizeof (target_flags));
+
+ bits = target_switches[i].value;
+ if (bits < 0)
+ bits = -bits;
+ if ((target_flags & bits) != (tf & bits))
+ {
+ flag_that_differs = target_switches[i].name;
+ goto make_message;
+ }
+ }
+ abort ();
+ }
+ data += sizeof (target_flags);
+ len -= sizeof (target_flags);
+
+ /* Check string options. */
+#ifdef TARGET_OPTIONS
+ for (i = 0; i < ARRAY_SIZE (target_options); i++)
+ {
+ const char *str = *target_options[i].variable;
+ size_t l;
+ if (! str)
+ str = "";
+ l = strlen (str) + 1;
+ if (len < l || memcmp (data, str, l) != 0)
+ {
+ flag_that_differs = target_options[i].prefix;
+ goto make_message;
+ }
+ data += l;
+ len -= l;
+ }
+#endif
+
+ return NULL;
+
+ make_message:
+ {
+ char *r;
+ asprintf (&r, _("created and used with differing settings of `-m%s'"),
+ flag_that_differs);
+ if (r == NULL)
+ return _("out of memory");
+ return r;
+ }
+}
+
+/* Default tree printer. Handles declarations only. */
+static bool
+default_tree_printer (pretty_printer * pp, text_info *text)
+{
+ switch (*text->format_spec)
+ {
+ case 'D':
+ case 'F':
+ case 'T':
+ {
+ tree t = va_arg (*text->args_ptr, tree);
+ const char *n = DECL_NAME (t)
+ ? (*lang_hooks.decl_printable_name) (t, 2)
+ : "<anonymous>";
+ pp_string (pp, n);
+ }
+ return true;
+
+ default:
+ return false;
+ }
+}
+
/* Initialization of the front end environment, before command line
options are parsed. Signal handlers, internationalization etc.
ARGV0 is main's argv[0]. */
static void
-general_init (argv0)
- char *argv0;
+general_init (const char *argv0)
{
- char *p;
+ const char *p;
p = argv0 + strlen (argv0);
while (p != argv0 && !IS_DIR_SEPARATOR (p[-1]))
@@ -4764,6 +4219,13 @@ general_init (argv0)
gcc_init_libintl ();
+ /* Initialize the diagnostics reporting machinery, so option parsing
+ can give warnings and errors. */
+ diagnostic_initialize (global_dc);
+ /* Set a default printer. Language specific initializations will
+ override it later. */
+ pp_format_decoder (global_dc->printer) = &default_tree_printer;
+
/* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages. */
#ifdef SIGSEGV
signal (SIGSEGV, crash_signal);
@@ -4784,33 +4246,14 @@ general_init (argv0)
signal (SIGFPE, crash_signal);
#endif
- /* Initialize the diagnostics reporting machinery, so option parsing
- can give warnings and errors. */
- diagnostic_initialize (global_dc);
+ /* Other host-specific signal setup. */
+ (*host_hooks.extra_signals)();
/* Initialize the garbage-collector, string pools and tree type hash
table. */
init_ggc ();
init_stringpool ();
init_ttree ();
-}
-
-/* Parse command line options and set default flag values, called
- after language-independent option-independent initialization. Do
- minimal options processing. Outputting diagnostics is OK, but GC
- and identifier hashtables etc. are not initialized yet.
-
- Return nonzero to suppress compiler back end initialization. */
-static void
-parse_options_and_default_flags (argc, argv)
- int argc;
- char **argv;
-{
- int i;
-
- /* Save in case md file wants to emit args as a comment. */
- save_argc = argc;
- save_argv = argv;
/* Initialize register usage now so switches may override. */
init_reg_sets ();
@@ -4820,238 +4263,37 @@ parse_options_and_default_flags (argc, argv)
/* This must be done after add_params but before argument processing. */
init_ggc_heuristics();
-
- /* Perform language-specific options initialization. */
- (*lang_hooks.init_options) ();
-
- /* Scan to see what optimization level has been specified. That will
- determine the default value of many flags. */
- for (i = 1; i < argc; i++)
- {
- if (!strcmp (argv[i], "-O"))
- {
- optimize = 1;
- optimize_size = 0;
- }
- else if (argv[i][0] == '-' && argv[i][1] == 'O')
- {
- /* Handle -Os, -O2, -O3, -O69, ... */
- char *p = &argv[i][2];
-
- if ((p[0] == 's') && (p[1] == 0))
- {
- optimize_size = 1;
-
- /* Optimizing for size forces optimize to be 2. */
- optimize = 2;
- }
- else
- {
- const int optimize_val = read_integral_parameter (p, p - 2, -1);
- if (optimize_val != -1)
- {
- optimize = optimize_val;
- optimize_size = 0;
- }
- }
- }
- }
-
- if (!optimize)
- {
- flag_merge_constants = 0;
- }
-
- if (optimize >= 1)
- {
- flag_defer_pop = 1;
- flag_thread_jumps = 1;
-#ifdef DELAY_SLOTS
- flag_delayed_branch = 1;
-#endif
-#ifdef CAN_DEBUG_WITHOUT_FP
- flag_omit_frame_pointer = 1;
-#endif
- flag_guess_branch_prob = 1;
- flag_cprop_registers = 1;
- flag_loop_optimize = 1;
- flag_crossjumping = 1;
- flag_if_conversion = 1;
- flag_if_conversion2 = 1;
- }
-
- if (optimize >= 2)
- {
- flag_optimize_sibling_calls = 1;
- flag_cse_follow_jumps = 1;
- flag_cse_skip_blocks = 1;
- flag_gcse = 1;
- flag_expensive_optimizations = 1;
- flag_strength_reduce = 1;
- flag_rerun_cse_after_loop = 1;
- flag_rerun_loop_opt = 1;
- flag_caller_saves = 1;
- flag_force_mem = 1;
- flag_peephole2 = 1;
-#ifdef INSN_SCHEDULING
- flag_schedule_insns = 1;
- flag_schedule_insns_after_reload = 1;
-#endif
- flag_regmove = 1;
- flag_strict_aliasing = 1;
- flag_delete_null_pointer_checks = 1;
- flag_reorder_blocks = 1;
- flag_reorder_functions = 1;
- }
-
- if (optimize >= 3)
- {
- flag_inline_functions = 1;
- flag_rename_registers = 1;
- }
-
- if (optimize < 2 || optimize_size)
- {
- align_loops = 1;
- align_jumps = 1;
- align_labels = 1;
- align_functions = 1;
-
- /* Don't reorder blocks when optimizing for size because extra
- jump insns may be created; also barrier may create extra padding.
-
- More correctly we should have a block reordering mode that tried
- to minimize the combined size of all the jumps. This would more
- or less automatically remove extra jumps, but would also try to
- use more short jumps instead of long jumps. */
- flag_reorder_blocks = 0;
- }
-
- /* Initialize whether `char' is signed. */
- flag_signed_char = DEFAULT_SIGNED_CHAR;
-#ifdef DEFAULT_SHORT_ENUMS
- /* Initialize how much space enums occupy, by default. */
- flag_short_enums = DEFAULT_SHORT_ENUMS;
-#endif
-
- /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
- modify it. */
- target_flags = 0;
- set_target_switch ("");
-
- /* Unwind tables are always present in an ABI-conformant IA-64
- object file, so the default should be ON. */
-#ifdef IA64_UNWIND_INFO
- flag_unwind_tables = IA64_UNWIND_INFO;
-#endif
-
-#ifdef OPTIMIZATION_OPTIONS
- /* Allow default optimizations to be specified on a per-machine basis. */
- OPTIMIZATION_OPTIONS (optimize, optimize_size);
-#endif
-
- /* Perform normal command line switch decoding. */
- for (i = 1; i < argc;)
- {
- int lang_processed;
- int indep_processed;
-
- /* Give the language a chance to decode the option for itself. */
- lang_processed = (*lang_hooks.decode_option) (argc - i, argv + i);
-
- if (lang_processed >= 0)
- /* Now see if the option also has a language independent meaning.
- Some options are both language specific and language independent,
- eg --help. */
- indep_processed = independent_decode_option (argc - i, argv + i);
- else
- {
- lang_processed = -lang_processed;
- indep_processed = 0;
- }
-
- if (lang_processed || indep_processed)
- i += MAX (lang_processed, indep_processed);
- else
- {
- const char *option = NULL;
- const char *lang = NULL;
- unsigned int j;
-
- /* It is possible that the command line switch is not valid for the
- current language, but it is valid for another language. In order
- to be compatible with previous versions of the compiler (which
- did not issue an error message in this case) we check for this
- possibility here. If we do find a match, then if extra_warnings
- is set we generate a warning message, otherwise we will just
- ignore the option. */
- for (j = 0; j < ARRAY_SIZE (documented_lang_options); j++)
- {
- option = documented_lang_options[j].option;
-
- if (option == NULL)
- lang = documented_lang_options[j].description;
- else if (! strncmp (argv[i], option, strlen (option)))
- break;
- }
-
- if (j != ARRAY_SIZE (documented_lang_options))
- {
- if (extra_warnings)
- {
- warning ("ignoring command line option '%s'", argv[i]);
- if (lang)
- warning
- ("(it is valid for %s but not the selected language)",
- lang);
- }
- }
- else if (argv[i][0] == '-' && argv[i][1] == 'g')
- warning ("`%s': unknown or unsupported -g option", &argv[i][2]);
- else
- error ("unrecognized option `%s'", argv[i]);
-
- i++;
- }
- }
-
- if (flag_no_inline == 2)
- flag_no_inline = 0;
- else
- flag_really_no_inline = flag_no_inline;
-
- /* Set flag_no_inline before the post_options () hook. The C front
- ends use it to determine tree inlining defaults. FIXME: such
- code should be lang-independent when all front ends use tree
- inlining, in which case it, and this condition, should be moved
- to the top of process_options() instead. */
- if (optimize == 0)
- {
- /* Inlining does not work if not optimizing,
- so force it not to be done. */
- flag_no_inline = 1;
- warn_inline = 0;
-
- /* The c_decode_option function and decode_option hook set
- this to `2' if -Wall is used, so we can avoid giving out
- lots of errors for people who don't realize what -Wall does. */
- if (warn_uninitialized == 1)
- warning ("-Wuninitialized is not supported without -O");
- }
-
- if (flag_really_no_inline == 2)
- flag_really_no_inline = flag_no_inline;
}
-
+
/* Process the options that have been parsed. */
static void
-process_options ()
+process_options (void)
{
+ /* Allow the front end to perform consistency checks and do further
+ initialization based on the command line options. This hook also
+ sets the original filename if appropriate (e.g. foo.i -> foo.c)
+ so we can correctly initialize debug output. */
+ no_backend = (*lang_hooks.post_options) (&main_input_filename);
+ input_filename = main_input_filename;
+
#ifdef OVERRIDE_OPTIONS
/* Some machines may reject certain combinations of options. */
OVERRIDE_OPTIONS;
#endif
+ /* Set aux_base_name if not already set. */
+ if (aux_base_name)
+ ;
+ else if (main_input_filename)
+ {
+ char *name = xstrdup (lbasename (main_input_filename));
+
+ strip_off_ending (name, strlen (name));
+ aux_base_name = name;
+ }
+ else
+ aux_base_name = "gccaux";
+
/* Set up the align_*_log variables, defaulting them to 1 if they
were still unset. */
if (align_loops <= 0) align_loops = 1;
@@ -5073,21 +4315,41 @@ process_options ()
be done. */
if (flag_unroll_all_loops)
flag_unroll_loops = 1;
- /* Loop unrolling requires that strength_reduction be on also. Silently
+
+ if (flag_unroll_loops)
+ {
+ flag_old_unroll_loops = 0;
+ flag_old_unroll_all_loops = 0;
+ }
+
+ if (flag_old_unroll_all_loops)
+ flag_old_unroll_loops = 1;
+
+ /* Old loop unrolling requires that strength_reduction be on also. Silently
turn on strength reduction here if it isn't already on. Also, the loop
unrolling code assumes that cse will be run after loop, so that must
be turned on also. */
- if (flag_unroll_loops)
+ if (flag_old_unroll_loops)
{
flag_strength_reduce = 1;
flag_rerun_cse_after_loop = 1;
}
+ if (flag_unroll_loops || flag_peel_loops)
+ flag_rerun_cse_after_loop = 1;
if (flag_non_call_exceptions)
flag_asynchronous_unwind_tables = 1;
if (flag_asynchronous_unwind_tables)
flag_unwind_tables = 1;
+ /* Disable unit-at-a-time mode for frontends not supporting callgraph
+ interface. */
+ if (flag_unit_at_a_time && ! lang_hooks.callgraph.expand_function)
+ flag_unit_at_a_time = 0;
+
+ if (flag_value_profile_transformations)
+ flag_profile_values = 1;
+
/* Warn about options that are not supported on this machine. */
#ifndef INSN_SCHEDULING
if (flag_schedule_insns || flag_schedule_insns_after_reload)
@@ -5122,41 +4384,44 @@ process_options ()
print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
}
- if (! quiet_flag || flag_detailed_statistics)
- time_report = 1;
-
if (flag_syntax_only)
{
write_symbols = NO_DEBUG;
profile_flag = 0;
}
+ /* A lot of code assumes write_symbols == NO_DEBUG if the debugging
+ level is 0. */
+ if (debug_info_level == DINFO_LEVEL_NONE)
+ write_symbols = NO_DEBUG;
+
/* Now we know write_symbols, set up the debug hooks based on it.
By default we do nothing for debug output. */
+ if (write_symbols == NO_DEBUG)
+ debug_hooks = &do_nothing_debug_hooks;
#if defined(DBX_DEBUGGING_INFO)
- if (write_symbols == DBX_DEBUG)
+ else if (write_symbols == DBX_DEBUG)
debug_hooks = &dbx_debug_hooks;
#endif
#if defined(XCOFF_DEBUGGING_INFO)
- if (write_symbols == XCOFF_DEBUG)
+ else if (write_symbols == XCOFF_DEBUG)
debug_hooks = &xcoff_debug_hooks;
#endif
#ifdef SDB_DEBUGGING_INFO
- if (write_symbols == SDB_DEBUG)
+ else if (write_symbols == SDB_DEBUG)
debug_hooks = &sdb_debug_hooks;
#endif
-#ifdef DWARF_DEBUGGING_INFO
- if (write_symbols == DWARF_DEBUG)
- debug_hooks = &dwarf_debug_hooks;
-#endif
#ifdef DWARF2_DEBUGGING_INFO
- if (write_symbols == DWARF2_DEBUG)
+ else if (write_symbols == DWARF2_DEBUG)
debug_hooks = &dwarf2_debug_hooks;
#endif
#ifdef VMS_DEBUGGING_INFO
- if (write_symbols == VMS_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
+ else if (write_symbols == VMS_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
debug_hooks = &vmsdbg_debug_hooks;
#endif
+ else
+ error ("target system does not support the \"%s\" debug format",
+ debug_type_names[write_symbols]);
/* If auxiliary info generation is desired, open the output file.
This goes in the same directory as the source file--unlike
@@ -5165,7 +4430,7 @@ process_options ()
{
aux_info_file = fopen (aux_info_file_name, "w");
if (aux_info_file == 0)
- fatal_io_error ("can't open %s", aux_info_file_name);
+ fatal_error ("can't open %s: %m", aux_info_file_name);
}
if (! targetm.have_named_sections)
@@ -5219,22 +4484,23 @@ process_options ()
if (flag_signaling_nans)
flag_trapping_math = 1;
}
-
+
/* Initialize the compiler back end. */
static void
-backend_init ()
+backend_init (void)
{
- /* init_emit_once uses reg_raw_mode and therefore must be called
- after init_regs which initialized reg_raw_mode. */
- init_regs ();
+ init_adjust_machine_modes ();
+
init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
|| debug_info_level == DINFO_LEVEL_VERBOSE
#ifdef VMS_DEBUGGING_INFO
- /* Enable line number info for traceback */
+ /* Enable line number info for traceback. */
|| debug_info_level > DINFO_LEVEL_NONE
#endif
|| flag_test_coverage
|| warn_notreached);
+
+ init_regs ();
init_fake_stack_mems ();
init_alias_once ();
init_loop ();
@@ -5250,26 +4516,18 @@ backend_init ()
init_caller_save ();
expand_dummy_function_end ();
}
-
+
/* Language-dependent initialization. Returns nonzero on success. */
static int
-lang_dependent_init (name)
- const char *name;
+lang_dependent_init (const char *name)
{
if (dump_base_name == 0)
dump_base_name = name ? name : "gccdump";
-
- /* Front-end initialization. This hook can assume that GC,
- identifier hashes etc. are set up, but debug initialization is
- not done yet. This routine must return the original filename
- (e.g. foo.i -> foo.c) so can correctly initialize debug output. */
- name = (*lang_hooks.init) (name);
- if (name == NULL)
+
+ /* Other front-end initialization. */
+ if ((*lang_hooks.init) () == 0)
return 0;
- /* Is this duplication necessary? */
- name = ggc_strdup (name);
- main_input_filename = input_filename = name;
init_asm_output (name);
/* These create various _DECL nodes, so need to be called after the
@@ -5283,9 +4541,6 @@ lang_dependent_init (name)
init_expr_once ();
expand_dummy_function_end ();
- /* Put an entry on the input file stack for the main input file. */
- push_srcloc (input_filename, 0);
-
/* If dbx symbol table desired, initialize writing it and output the
predefined types. */
timevar_push (TV_SYMOUT);
@@ -5303,11 +4558,11 @@ lang_dependent_init (name)
return 1;
}
-
+
/* Clean up: close opened files, etc. */
static void
-finalize ()
+finalize (void)
{
/* Close the dump files. */
if (flag_gen_aux_info)
@@ -5324,9 +4579,9 @@ finalize ()
if (asm_out_file)
{
if (ferror (asm_out_file) != 0)
- fatal_io_error ("error writing to %s", asm_file_name);
+ fatal_error ("error writing to %s: %m", asm_file_name);
if (fclose (asm_out_file) != 0)
- fatal_io_error ("error closing %s", asm_file_name);
+ fatal_error ("error closing %s: %m", asm_file_name);
}
/* Do whatever is necessary to finish printing the graphs. */
@@ -5352,6 +4607,9 @@ finalize ()
ggc_print_statistics ();
stringpool_statistics ();
dump_tree_statistics ();
+ dump_rtx_statistics ();
+ dump_varray_statistics ();
+ dump_alloc_pool_statistics ();
}
/* Free up memory for the benefit of leak detectors. */
@@ -5360,72 +4618,73 @@ finalize ()
/* Language-specific end of compilation actions. */
(*lang_hooks.finish) ();
}
-
+
/* Initialize the compiler, and compile the input file. */
static void
-do_compile ()
+do_compile (void)
{
- /* All command line options have been parsed; allow the front end to
- perform consistency checks, etc. */
- bool no_backend = (*lang_hooks.post_options) ();
+ /* Initialize timing first. The C front ends read the main file in
+ the post_options hook, and C++ does file timings. */
+ if (time_report || !quiet_flag || flag_detailed_statistics)
+ timevar_init ();
+ timevar_start (TV_TOTAL);
- /* The bulk of command line switch processing. */
process_options ();
- /* If an error has already occurred, give up. */
- if (errorcount)
- return;
-
- if (aux_base_name)
- /*NOP*/;
- else if (filename)
+ /* Don't do any more if an error has already occurred. */
+ if (!errorcount)
{
- char *name = xstrdup (lbasename (filename));
-
- aux_base_name = name;
- strip_off_ending (name, strlen (name));
- }
- else
- aux_base_name = "gccaux";
+ /* Set up the back-end if requested. */
+ if (!no_backend)
+ backend_init ();
- /* We cannot start timing until after options are processed since that
- says if we run timers or not. */
- init_timevar ();
- timevar_start (TV_TOTAL);
+ /* Language-dependent initialization. Returns true on success. */
+ if (lang_dependent_init (main_input_filename))
+ {
+ if (flag_unit_at_a_time)
+ {
+ open_dump_file (DFI_cgraph, NULL);
+ cgraph_dump_file = rtl_dump_file;
+ rtl_dump_file = NULL;
+ }
- /* Set up the back-end if requested. */
- if (!no_backend)
- backend_init ();
+ compile_file ();
- /* Language-dependent initialization. Returns true on success. */
- if (lang_dependent_init (filename))
- compile_file ();
+ if (flag_unit_at_a_time)
+ {
+ rtl_dump_file = cgraph_dump_file;
+ cgraph_dump_file = NULL;
+ close_dump_file (DFI_cgraph, NULL, NULL_RTX);
+ }
+ }
- finalize ();
+ finalize ();
+ }
/* Stop timing and print the times. */
timevar_stop (TV_TOTAL);
timevar_print (stderr);
}
-
+
/* Entry point of cc1, cc1plus, jc1, f771, etc.
- Decode command args, then call compile_file.
Exit code is FATAL_EXIT_CODE if can't open files or if there were
any errors, or SUCCESS_EXIT_CODE if compilation succeeded.
It is not safe to call this function more than once. */
int
-toplev_main (argc, argv)
- int argc;
- char **argv;
+toplev_main (unsigned int argc, const char **argv)
{
+ save_argv = 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. */
- parse_options_and_default_flags (argc, argv);
+ decode_options (argc, argv);
+
+ randomize ();
/* Exit early if we can (e.g. -help). */
if (!exit_after_options)
diff --git a/contrib/gcc/toplev.h b/contrib/gcc/toplev.h
index 2dab2447a857..d823d54353d6 100644
--- a/contrib/gcc/toplev.h
+++ b/contrib/gcc/toplev.h
@@ -1,5 +1,6 @@
/* toplev.h - Various declarations for functions found in toplev.c
- Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -26,102 +27,121 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define skip_leading_substring(whole, part) \
(strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
-extern int toplev_main PARAMS ((int, char **));
-extern int read_integral_parameter PARAMS ((const char *, const char *,
- const int));
-extern void strip_off_ending PARAMS ((char *, int));
-extern void print_time PARAMS ((const char *, long));
-extern const char *trim_filename PARAMS ((const char *));
-extern void internal_error PARAMS ((const char *, ...))
- ATTRIBUTE_NORETURN;
-extern void fatal_io_error PARAMS ((const char *, ...))
- ATTRIBUTE_NORETURN;
-extern void _fatal_insn_not_found PARAMS ((struct rtx_def *,
- const char *, int,
- const char *))
- ATTRIBUTE_NORETURN;
-extern void _fatal_insn PARAMS ((const char *,
- struct rtx_def *,
- const char *, int,
- const char *))
- ATTRIBUTE_NORETURN;
+extern int toplev_main (unsigned int, const char **);
+extern int read_integral_parameter (const char *, const char *, const int);
+extern void strip_off_ending (char *, int);
+extern const char *trim_filename (const char *);
+extern void _fatal_insn_not_found (rtx, const char *, int, const char *)
+ ATTRIBUTE_NORETURN;
+extern void _fatal_insn (const char *, rtx, const char *, int, const char *)
+ ATTRIBUTE_NORETURN;
#define fatal_insn(msgid, insn) \
_fatal_insn (msgid, insn, __FILE__, __LINE__, __FUNCTION__)
#define fatal_insn_not_found(insn) \
_fatal_insn_not_found (insn, __FILE__, __LINE__, __FUNCTION__)
+/* If we haven't already defined a frontend specific diagnostics
+ style, use the generic one. */
+#ifndef GCC_DIAG_STYLE
+#define GCC_DIAG_STYLE __gcc_diag__
+#endif
/* None of these functions are suitable for ATTRIBUTE_PRINTF, because
each language front end can extend them with its own set of format
- specifiers. */
-extern void warning PARAMS ((const char *, ...));
-extern void error PARAMS ((const char *, ...));
-extern void fatal_error PARAMS ((const char *, ...))
- ATTRIBUTE_NORETURN;
-extern void pedwarn PARAMS ((const char *, ...));
-extern void pedwarn_with_file_and_line PARAMS ((const char *, int,
- const char *, ...));
-extern void warning_with_file_and_line PARAMS ((const char *, int,
- const char *, ...));
-extern void error_with_file_and_line PARAMS ((const char *, int,
- const char *, ...));
-extern void sorry PARAMS ((const char *, ...));
-
-extern void rest_of_decl_compilation PARAMS ((union tree_node *,
- const char *, int, int));
-extern void rest_of_type_compilation PARAMS ((union tree_node *, int));
-extern void rest_of_compilation PARAMS ((union tree_node *));
-
-extern void pedwarn_with_decl PARAMS ((union tree_node *,
- const char *, ...));
-extern void warning_with_decl PARAMS ((union tree_node *,
- const char *, ...));
-extern void error_with_decl PARAMS ((union tree_node *,
- const char *, ...));
-
-extern void announce_function PARAMS ((union tree_node *));
-
-extern void error_for_asm PARAMS ((struct rtx_def *,
- const char *, ...));
-extern void warning_for_asm PARAMS ((struct rtx_def *,
- const char *, ...));
-extern void warn_deprecated_use PARAMS ((union tree_node *));
-
-extern void output_clean_symbol_name PARAMS ((FILE *, const char *));
+ specifiers. We must use custom format checks. */
+#if GCC_VERSION >= 3004
+#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)
+#endif
+extern void internal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
+ ATTRIBUTE_NORETURN;
+extern void warning (const char *, ...);
+extern void error (const char *, ...);
+extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2)
+ ATTRIBUTE_NORETURN;
+extern void pedwarn (const char *, ...);
+extern void sorry (const char *, ...);
+extern void inform (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2);
+
+extern void rest_of_decl_compilation (tree, const char *, int, int);
+extern void rest_of_type_compilation (tree, int);
+extern void rest_of_compilation (tree);
+extern void tree_rest_of_compilation (tree, bool);
+
+extern void announce_function (tree);
+
+extern void error_for_asm (rtx, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
+extern void warning_for_asm (rtx, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3);
+extern void warn_deprecated_use (tree);
+
#ifdef BUFSIZ
-extern void output_quoted_string PARAMS ((FILE *, const char *));
-extern void output_file_directive PARAMS ((FILE *, const char *));
+extern void output_quoted_string (FILE *, const char *);
+extern void output_file_directive (FILE *, const char *);
#endif
-extern void do_abort PARAMS ((void)) ATTRIBUTE_NORETURN;
-extern void botch PARAMS ((const char *))
- ATTRIBUTE_NORETURN;
#ifdef BUFSIZ
/* N.B. Unlike all the others, fnotice is just gettext+fprintf, and
therefore it can have ATTRIBUTE_PRINTF. */
-extern void fnotice PARAMS ((FILE *, const char *, ...))
- ATTRIBUTE_PRINTF_2;
+extern void fnotice (FILE *, const char *, ...)
+ ATTRIBUTE_PRINTF_2;
#endif
-extern int wrapup_global_declarations PARAMS ((union tree_node **, int));
-extern void check_global_declarations PARAMS ((union tree_node **, int));
+extern int wrapup_global_declarations (tree *, int);
+extern void check_global_declarations (tree *, int);
+extern void write_global_declarations (void);
+
+/* A unique local time stamp, might be zero if none is available. */
+extern unsigned local_tick;
extern const char *progname;
extern const char *dump_base_name;
extern const char *aux_base_name;
+extern const char *aux_info_file_name;
+extern const char *asm_file_name;
+extern bool exit_after_options;
+extern bool version_flag;
extern int target_flags_explicit;
+/* See toplev.c. */
+extern int flag_loop_optimize;
+extern int flag_crossjumping;
+extern int flag_if_conversion;
+extern int flag_if_conversion2;
+extern int flag_delete_null_pointer_checks;
+extern int flag_keep_static_consts;
+extern int flag_peel_loops;
+extern int flag_rerun_cse_after_loop;
+extern int flag_thread_jumps;
+extern int flag_tracer;
+extern int flag_unroll_loops;
+extern int flag_unroll_all_loops;
+extern int flag_unswitch_loops;
+extern int flag_cprop_registers;
+extern int time_report;
+extern int flag_new_regalloc;
+
+/* Things to do with target switches. */
+extern void display_target_options (void);
+extern void print_version (FILE *, const char *);
+extern void set_target_switch (const char *);
+extern void * default_get_pch_validity (size_t *);
+extern const char * default_pch_valid_p (const void *, size_t);
+
/* The hashtable, so that the C front ends can pass it to cpplib. */
extern struct ht *ident_hash;
/* This function can be used by targets to set the flags originally
implied by -ffast-math and -fno-fast-math. */
-extern void set_fast_math_flags PARAMS ((int));
+extern void set_fast_math_flags (int);
+
+/* Handle -d switch. */
+extern void decode_d_option (const char *);
/* Return true iff flags are set as if -ffast-math. */
-extern bool fast_math_flags_set_p PARAMS ((void));
+extern bool fast_math_flags_set_p (void);
/* The following functions accept a wide integer argument. Rather
than having to cast on every function call, we use a macro instead. */
@@ -130,7 +150,13 @@ extern bool fast_math_flags_set_p PARAMS ((void));
#define exact_log2(N) exact_log2_wide ((unsigned HOST_WIDE_INT) (N))
#define floor_log2(N) floor_log2_wide ((unsigned HOST_WIDE_INT) (N))
#endif
-extern int exact_log2_wide PARAMS ((unsigned HOST_WIDE_INT));
-extern int floor_log2_wide PARAMS ((unsigned HOST_WIDE_INT));
+extern int exact_log2_wide (unsigned HOST_WIDE_INT);
+extern int floor_log2_wide (unsigned HOST_WIDE_INT);
+
+/* Functions used to get and set GCC's notion of in what directory
+ compilation was started. */
+
+extern const char *get_src_pwd (void);
+extern bool set_src_pwd (const char *);
#endif /* ! GCC_TOPLEV_H */
diff --git a/contrib/gcc/tracer.c b/contrib/gcc/tracer.c
index 970b5f46b40a..b01238e003a9 100644
--- a/contrib/gcc/tracer.c
+++ b/contrib/gcc/tracer.c
@@ -1,6 +1,6 @@
/* The tracer pass for the GNU compiler.
Contributed by Jan Hubicka, SuSE Labs.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -35,6 +35,8 @@
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "hard-reg-set.h"
@@ -43,18 +45,18 @@
#include "cfglayout.h"
#include "fibheap.h"
#include "flags.h"
+#include "timevar.h"
#include "params.h"
-#include "profile.h"
-
-static int count_insns PARAMS ((basic_block));
-static bool ignore_bb_p PARAMS ((basic_block));
-static bool better_p PARAMS ((edge, edge));
-static edge find_best_successor PARAMS ((basic_block));
-static edge find_best_predecessor PARAMS ((basic_block));
-static int find_trace PARAMS ((basic_block, basic_block *));
-static void tail_duplicate PARAMS ((void));
-static void layout_superblocks PARAMS ((void));
-static bool ignore_bb_p PARAMS ((basic_block));
+#include "coverage.h"
+
+static int count_insns (basic_block);
+static bool ignore_bb_p (basic_block);
+static bool better_p (edge, edge);
+static edge find_best_successor (basic_block);
+static edge find_best_predecessor (basic_block);
+static int find_trace (basic_block, basic_block *);
+static void tail_duplicate (void);
+static void layout_superblocks (void);
/* Minimal outgoing edge probability considered for superblock formation. */
static int probability_cutoff;
@@ -63,12 +65,11 @@ static int branch_ratio_cutoff;
/* Return true if BB has been seen - it is connected to some trace
already. */
-#define seen(bb) (RBI (bb)->visited || RBI (bb)->next)
+#define seen(bb) (bb->rbi->visited || bb->rbi->next)
/* Return true if we should ignore the basic block for purposes of tracing. */
static bool
-ignore_bb_p (bb)
- basic_block bb;
+ignore_bb_p (basic_block bb)
{
if (bb->index < 0)
return true;
@@ -80,13 +81,14 @@ ignore_bb_p (bb)
/* Return number of instructions in the block. */
static int
-count_insns (bb)
- basic_block bb;
+count_insns (basic_block bb)
{
rtx insn;
int n = 0;
- for (insn = bb->head; insn != NEXT_INSN (bb->end); insn = NEXT_INSN (insn))
+ for (insn = BB_HEAD (bb);
+ insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
if (active_insn_p (insn))
n++;
return n;
@@ -94,8 +96,7 @@ count_insns (bb)
/* Return true if E1 is more frequent than E2. */
static bool
-better_p (e1, e2)
- edge e1, e2;
+better_p (edge e1, edge e2)
{
if (e1->count != e2->count)
return e1->count > e2->count;
@@ -113,8 +114,7 @@ better_p (e1, e2)
/* Return most frequent successor of basic block BB. */
static edge
-find_best_successor (bb)
- basic_block bb;
+find_best_successor (basic_block bb)
{
edge e;
edge best = NULL;
@@ -132,8 +132,7 @@ find_best_successor (bb)
/* Return most frequent predecessor of basic block BB. */
static edge
-find_best_predecessor (bb)
- basic_block bb;
+find_best_predecessor (basic_block bb)
{
edge e;
edge best = NULL;
@@ -153,9 +152,7 @@ find_best_predecessor (bb)
Return number of basic blocks recorded. */
static int
-find_trace (bb, trace)
- basic_block bb;
- basic_block *trace;
+find_trace (basic_block bb, basic_block *trace)
{
int i = 0;
edge e;
@@ -197,7 +194,7 @@ find_trace (bb, trace)
if profitable. */
static void
-tail_duplicate ()
+tail_duplicate (void)
{
fibnode_t *blocks = xcalloc (last_basic_block, sizeof (fibnode_t));
basic_block *trace = xmalloc (sizeof (basic_block) * n_basic_blocks);
@@ -209,7 +206,7 @@ tail_duplicate ()
int max_dup_insns;
basic_block bb;
- if (profile_info.count_profiles_merged && flag_branch_probabilities)
+ if (profile_info && flag_branch_probabilities)
probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK);
else
probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY);
@@ -230,7 +227,7 @@ tail_duplicate ()
weighted_insns += n * bb->frequency;
}
- if (profile_info.count_profiles_merged && flag_branch_probabilities)
+ if (profile_info && flag_branch_probabilities)
cover_insns = PARAM_VALUE (TRACER_DYNAMIC_COVERAGE_FEEDBACK);
else
cover_insns = PARAM_VALUE (TRACER_DYNAMIC_COVERAGE);
@@ -285,7 +282,7 @@ tail_duplicate ()
bb2 = cfg_layout_duplicate_bb (bb2, e);
/* Reconsider the original copy of block we've duplicated.
- Removing the most common predecesor may make it to be
+ Removing the most common predecessor may make it to be
head. */
blocks[old->index] =
fibheap_insert (heap, -old->frequency, old);
@@ -294,8 +291,8 @@ tail_duplicate ()
fprintf (rtl_dump_file, "Duplicated %i as %i [%i]\n",
old->index, bb2->index, bb2->frequency);
}
- RBI (bb)->next = bb2;
- RBI (bb2)->visited = 1;
+ bb->rbi->next = bb2;
+ bb2->rbi->visited = 1;
bb = bb2;
/* In case the trace became infrequent, stop duplicating. */
if (ignore_bb_p (bb))
@@ -315,13 +312,13 @@ tail_duplicate ()
fibheap_delete (heap);
}
-/* Connect the superblocks into linear seuqence. At the moment we attempt to keep
+/* Connect the superblocks into linear sequence. At the moment we attempt to keep
the original order as much as possible, but the algorithm may be made smarter
later if needed. BB reordering pass should void most of the benefits of such
change though. */
static void
-layout_superblocks ()
+layout_superblocks (void)
{
basic_block end = ENTRY_BLOCK_PTR->succ->dest;
basic_block bb = ENTRY_BLOCK_PTR->succ->dest->next_bb;
@@ -329,42 +326,46 @@ layout_superblocks ()
while (bb != EXIT_BLOCK_PTR)
{
edge e, best = NULL;
- while (RBI (end)->next)
- end = RBI (end)->next;
+ while (end->rbi->next)
+ end = end->rbi->next;
for (e = end->succ; e; e = e->succ_next)
if (e->dest != EXIT_BLOCK_PTR
&& e->dest != ENTRY_BLOCK_PTR->succ->dest
- && !RBI (e->dest)->visited
+ && !e->dest->rbi->visited
&& (!best || EDGE_FREQUENCY (e) > EDGE_FREQUENCY (best)))
best = e;
if (best)
{
- RBI (end)->next = best->dest;
- RBI (best->dest)->visited = 1;
+ end->rbi->next = best->dest;
+ best->dest->rbi->visited = 1;
}
else
- for (; bb != EXIT_BLOCK_PTR; bb=bb->next_bb)
+ for (; bb != EXIT_BLOCK_PTR; bb = bb->next_bb)
{
- if (!RBI (bb)->visited)
+ if (!bb->rbi->visited)
{
- RBI (end)->next = bb;
- RBI (bb)->visited = 1;
+ end->rbi->next = bb;
+ bb->rbi->visited = 1;
break;
}
}
}
}
-/* Main entry point to this file. */
+/* Main entry point to this file. FLAGS is the set of flags to pass
+ to cfg_layout_initialize(). */
void
-tracer ()
+tracer (unsigned int flags)
{
if (n_basic_blocks <= 1)
return;
- cfg_layout_initialize ();
+
+ timevar_push (TV_TRACER);
+
+ cfg_layout_initialize (flags);
mark_dfs_back_edges ();
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
@@ -373,6 +374,9 @@ tracer ()
if (rtl_dump_file)
dump_flow_info (rtl_dump_file);
cfg_layout_finalize ();
+
/* Merge basic blocks in duplicated traces. */
cleanup_cfg (CLEANUP_EXPENSIVE);
+
+ timevar_pop (TV_TRACER);
}
diff --git a/contrib/gcc/tree-dump.c b/contrib/gcc/tree-dump.c
index 5b9f4f58ab6f..6f958cf90fd4 100644
--- a/contrib/gcc/tree-dump.c
+++ b/contrib/gcc/tree-dump.c
@@ -1,5 +1,5 @@
/* Tree-dumping functionality for intermediate representation.
- Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
Written by Mark Mitchell <mark@codesourcery.com>
This file is part of GCC.
@@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "splay-tree.h"
#include "diagnostic.h"
@@ -28,21 +30,18 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tree-dump.h"
#include "langhooks.h"
-static unsigned int queue PARAMS ((dump_info_p, tree, int));
-static void dump_index PARAMS ((dump_info_p, unsigned int));
-static void dequeue_and_dump PARAMS ((dump_info_p));
-static void dump_new_line PARAMS ((dump_info_p));
-static void dump_maybe_newline PARAMS ((dump_info_p));
-static void dump_string_field PARAMS ((dump_info_p, const char *, const char *));
+static unsigned int queue (dump_info_p, tree, int);
+static void dump_index (dump_info_p, unsigned int);
+static void dequeue_and_dump (dump_info_p);
+static void dump_new_line (dump_info_p);
+static void dump_maybe_newline (dump_info_p);
+static void dump_string_field (dump_info_p, const char *, const char *);
/* Add T to the end of the queue of nodes to dump. Returns the index
assigned to T. */
static unsigned int
-queue (di, t, flags)
- dump_info_p di;
- tree t;
- int flags;
+queue (dump_info_p di, tree t, int flags)
{
dump_queue_p dq;
dump_node_info_p dni;
@@ -58,10 +57,10 @@ queue (di, t, flags)
di->free_list = dq->next;
}
else
- dq = (dump_queue_p) xmalloc (sizeof (struct dump_queue));
+ dq = xmalloc (sizeof (struct dump_queue));
/* Create a new entry in the splay-tree. */
- dni = (dump_node_info_p) xmalloc (sizeof (struct dump_node_info));
+ dni = xmalloc (sizeof (struct dump_node_info));
dni->index = index;
dni->binfo_p = ((flags & DUMP_BINFO) != 0);
dq->node = splay_tree_insert (di->nodes, (splay_tree_key) t,
@@ -80,9 +79,7 @@ queue (di, t, flags)
}
static void
-dump_index (di, index)
- dump_info_p di;
- unsigned int index;
+dump_index (dump_info_p di, unsigned int index)
{
fprintf (di->stream, "@%-6u ", index);
di->column += 8;
@@ -93,11 +90,7 @@ dump_index (di, index)
index of T is printed. */
void
-queue_and_dump_index (di, field, t, flags)
- dump_info_p di;
- const char *field;
- tree t;
- int flags;
+queue_and_dump_index (dump_info_p di, const char *field, tree t, int flags)
{
unsigned int index;
splay_tree_node n;
@@ -125,9 +118,7 @@ queue_and_dump_index (di, field, t, flags)
/* Dump the type of T. */
void
-queue_and_dump_type (di, t)
- dump_info_p di;
- tree t;
+queue_and_dump_type (dump_info_p di, tree t)
{
queue_and_dump_index (di, "type", TREE_TYPE (t), DUMP_NONE);
}
@@ -141,8 +132,7 @@ queue_and_dump_type (di, t)
place to start printing more fields. */
static void
-dump_new_line (di)
- dump_info_p di;
+dump_new_line (dump_info_p di)
{
fprintf (di->stream, "\n%*s", SOL_COLUMN, "");
di->column = SOL_COLUMN;
@@ -151,8 +141,7 @@ dump_new_line (di)
/* If necessary, insert a new line. */
static void
-dump_maybe_newline (di)
- dump_info_p di;
+dump_maybe_newline (dump_info_p di)
{
int extra;
@@ -170,10 +159,7 @@ dump_maybe_newline (di)
/* Dump pointer PTR using FIELD to identify it. */
void
-dump_pointer (di, field, ptr)
- dump_info_p di;
- const char *field;
- void *ptr;
+dump_pointer (dump_info_p di, const char *field, void *ptr)
{
dump_maybe_newline (di);
fprintf (di->stream, "%-4s: %-8lx ", field, (long) ptr);
@@ -183,10 +169,7 @@ dump_pointer (di, field, ptr)
/* Dump integer I using FIELD to identify it. */
void
-dump_int (di, field, i)
- dump_info_p di;
- const char *field;
- int i;
+dump_int (dump_info_p di, const char *field, int i)
{
dump_maybe_newline (di);
fprintf (di->stream, "%-4s: %-7d ", field, i);
@@ -196,9 +179,7 @@ dump_int (di, field, i)
/* Dump the string S. */
void
-dump_string (di, string)
- dump_info_p di;
- const char *string;
+dump_string (dump_info_p di, const char *string)
{
dump_maybe_newline (di);
fprintf (di->stream, "%-13s ", string);
@@ -211,10 +192,7 @@ dump_string (di, string)
/* Dump the string field S. */
static void
-dump_string_field (di, field, string)
- dump_info_p di;
- const char *field;
- const char *string;
+dump_string_field (dump_info_p di, const char *field, const char *string)
{
dump_maybe_newline (di);
fprintf (di->stream, "%-4s: %-7s ", field, string);
@@ -227,8 +205,7 @@ dump_string_field (di, field, string)
/* Dump the next node in the queue. */
static void
-dequeue_and_dump (di)
- dump_info_p di;
+dequeue_and_dump (dump_info_p di)
{
dump_queue_p dq;
splay_tree_node stn;
@@ -271,17 +248,36 @@ dequeue_and_dump (di)
more informative. */
if (dni->binfo_p)
{
- if (TREE_VIA_PUBLIC (t))
- dump_string (di, "pub");
- else if (TREE_VIA_PROTECTED (t))
- dump_string (di, "prot");
- else if (TREE_VIA_PRIVATE (t))
- dump_string (di, "priv");
+ unsigned ix;
+ tree bases = BINFO_BASETYPES (t);
+ unsigned n_bases = bases ? TREE_VEC_LENGTH (bases): 0;
+ tree accesses = BINFO_BASEACCESSES (t);
+
+ dump_child ("type", BINFO_TYPE (t));
+
if (TREE_VIA_VIRTUAL (t))
dump_string (di, "virt");
- dump_child ("type", BINFO_TYPE (t));
- dump_child ("base", BINFO_BASETYPES (t));
+ dump_int (di, "bases", n_bases);
+ for (ix = 0; ix != n_bases; ix++)
+ {
+ tree base = TREE_VEC_ELT (bases, ix);
+ tree access = (accesses ? TREE_VEC_ELT (accesses, ix)
+ : access_public_node);
+ const char *string = NULL;
+
+ if (access == access_public_node)
+ string = "pub";
+ else if (access == access_protected_node)
+ string = "prot";
+ else if (access == access_private_node)
+ string = "priv";
+ else
+ abort ();
+
+ dump_string (di, string);
+ queue_and_dump_index (di, "binf", base, DUMP_BINFO);
+ }
goto done;
}
@@ -306,6 +302,8 @@ dequeue_and_dump (di)
break;
case 'e':
+ case 'r':
+ case 's':
/* These nodes are handled explicitly below. */
break;
@@ -548,7 +546,7 @@ dequeue_and_dump (di)
break;
case CONSTRUCTOR:
- dump_child ("elts", TREE_OPERAND (t, 1));
+ dump_child ("elts", CONSTRUCTOR_ELTS (t));
break;
case BIND_EXPR:
@@ -595,10 +593,7 @@ dequeue_and_dump (di)
/* Return nonzero if FLAG has been specified for the dump, and NODE
is not the root node of the dump. */
-int dump_flag (di, flag, node)
- dump_info_p di;
- int flag;
- tree node;
+int dump_flag (dump_info_p di, int flag, tree node)
{
return (di->flags & flag) && (node != di->node);
}
@@ -606,10 +601,7 @@ int dump_flag (di, flag, node)
/* Dump T, and all its children, on STREAM. */
void
-dump_node (t, flags, stream)
- tree t;
- int flags;
- FILE *stream;
+dump_node (tree t, int flags, FILE *stream)
{
struct dump_info di;
dump_queue_p dq;
@@ -656,11 +648,11 @@ struct dump_file_info
TREE_DUMP_INDEX enumeration in tree.h */
static struct dump_file_info dump_files[TDI_end] =
{
- {".tu", "dump-translation-unit", 0, 0},
- {".class", "dump-class-hierarchy", 0, 0},
- {".original", "dump-tree-original", 0, 0},
- {".optimized", "dump-tree-optimized", 0, 0},
- {".inlined", "dump-tree-inlined", 0, 0},
+ {".tu", "translation-unit", 0, 0},
+ {".class", "class-hierarchy", 0, 0},
+ {".original", "tree-original", 0, 0},
+ {".optimized", "tree-optimized", 0, 0},
+ {".inlined", "tree-inlined", 0, 0},
};
/* Define a name->number mapping for a dump flag value. */
@@ -686,9 +678,7 @@ static const struct dump_option_value_info dump_options[] =
Multiple calls will reopen and append to the dump file. */
FILE *
-dump_begin (phase, flag_ptr)
- enum tree_dump_index phase;
- int *flag_ptr;
+dump_begin (enum tree_dump_index phase, int *flag_ptr)
{
FILE *stream;
char *name;
@@ -712,8 +702,7 @@ dump_begin (phase, flag_ptr)
/* Returns nonzero if tree dump PHASE is enabled. */
int
-dump_enabled_p (phase)
- enum tree_dump_index phase;
+dump_enabled_p (enum tree_dump_index phase)
{
return dump_files[phase].state;
}
@@ -721,8 +710,7 @@ dump_enabled_p (phase)
/* Returns the switch name of PHASE. */
const char *
-dump_flag_name (phase)
- enum tree_dump_index phase;
+dump_flag_name (enum tree_dump_index phase)
{
return dump_files[phase].swtch;
}
@@ -731,9 +719,7 @@ dump_flag_name (phase)
dump_begin. */
void
-dump_end (phase, stream)
- enum tree_dump_index phase ATTRIBUTE_UNUSED;
- FILE *stream;
+dump_end (enum tree_dump_index phase ATTRIBUTE_UNUSED, FILE *stream)
{
fclose (stream);
}
@@ -742,8 +728,7 @@ dump_end (phase, stream)
relevant details in the dump_files array. */
int
-dump_switch_p (arg)
- const char *arg;
+dump_switch_p (const char *arg)
{
unsigned ix;
const char *option_value;
@@ -775,7 +760,7 @@ dump_switch_p (arg)
flags |= option_ptr->value;
goto found;
}
- warning ("ignoring unknown option `%.*s' in `-f%s'",
+ warning ("ignoring unknown option `%.*s' in `-fdump-%s'",
length, ptr, dump_files[ix].swtch);
found:;
ptr = end_ptr;
diff --git a/contrib/gcc/tree-dump.h b/contrib/gcc/tree-dump.h
index d4951d9f5054..3f6497b23f89 100644
--- a/contrib/gcc/tree-dump.h
+++ b/contrib/gcc/tree-dump.h
@@ -1,5 +1,5 @@
/* Tree-dumping functionality for intermediate representation.
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc.
Written by Mark Mitchell <mark@codesourcery.com>
This file is part of GCC.
@@ -77,19 +77,12 @@ struct dump_info
#define dump_child(field, child) \
queue_and_dump_index (di, field, child, DUMP_NONE)
-extern void dump_pointer
- PARAMS ((dump_info_p, const char *, void *));
-extern void dump_int
- PARAMS ((dump_info_p, const char *, int));
-extern void dump_string
- PARAMS ((dump_info_p, const char *));
-extern void dump_stmt
- PARAMS ((dump_info_p, tree));
-extern void dump_next_stmt
- PARAMS ((dump_info_p, tree));
-extern void queue_and_dump_index
- PARAMS ((dump_info_p, const char *, tree, int));
-extern void queue_and_dump_type
- PARAMS ((dump_info_p, tree));
+extern void dump_pointer (dump_info_p, const char *, void *);
+extern void dump_int (dump_info_p, const char *, int);
+extern void dump_string (dump_info_p, const char *);
+extern void dump_stmt (dump_info_p, tree);
+extern void dump_next_stmt (dump_info_p, tree);
+extern void queue_and_dump_index (dump_info_p, const char *, tree, int);
+extern void queue_and_dump_type (dump_info_p, tree);
#endif /* ! GCC_TREE_DUMP_H */
diff --git a/contrib/gcc/tree-inline.c b/contrib/gcc/tree-inline.c
index 4dc7e67f5faf..dac0f040e4ff 100644
--- a/contrib/gcc/tree-inline.c
+++ b/contrib/gcc/tree-inline.c
@@ -1,26 +1,28 @@
/* Control and data flow functions for trees.
- Copyright 2001, 2002 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <aoliva@redhat.com>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "toplev.h"
#include "tree.h"
#include "tree-inline.h"
@@ -35,6 +37,9 @@ Boston, MA 02111-1307, USA. */
#include "hashtab.h"
#include "splay-tree.h"
#include "langhooks.h"
+#include "cgraph.h"
+#include "intl.h"
+#include "diagnostic.h"
/* This should be eventually be generalized to other languages, but
this would require a shared function-as-trees infrastructure. */
@@ -88,13 +93,8 @@ typedef struct inline_data
/* Nonzero if we are currently within the cleanup for a
TARGET_EXPR. */
int in_target_cleanup_p;
- /* A stack of the TARGET_EXPRs that we are currently processing. */
- varray_type target_exprs;
/* A list of the functions current function has inlined. */
varray_type inlined_fns;
- /* The approximate number of statements we have inlined in the
- current call stack. */
- int inlined_stmts;
/* We use the same mechanism to build clones that we do to perform
inlining. However, there are a few places where we need to
distinguish between those two situations. This flag is true if
@@ -103,42 +103,35 @@ typedef struct inline_data
/* Hash table used to prevent walk_tree from visiting the same node
umpteen million times. */
htab_t tree_pruner;
+ /* Decl of function we are inlining into. */
+ tree decl;
+ tree current_decl;
} inline_data;
/* Prototypes. */
-static tree declare_return_variable PARAMS ((inline_data *, tree *));
-static tree copy_body_r PARAMS ((tree *, int *, void *));
-static tree copy_body PARAMS ((inline_data *));
-static tree expand_call_inline PARAMS ((tree *, int *, void *));
-static void expand_calls_inline PARAMS ((tree *, inline_data *));
-static int inlinable_function_p PARAMS ((tree, inline_data *));
-static tree remap_decl PARAMS ((tree, inline_data *));
+static tree declare_return_variable (inline_data *, tree, tree *);
+static tree copy_body_r (tree *, int *, void *);
+static tree copy_body (inline_data *);
+static tree expand_call_inline (tree *, int *, void *);
+static void expand_calls_inline (tree *, inline_data *);
+static bool inlinable_function_p (tree);
+static tree remap_decl (tree, inline_data *);
+static tree remap_type (tree, inline_data *);
#ifndef INLINER_FOR_JAVA
-static tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree));
-static void remap_block PARAMS ((tree, tree, inline_data *));
-static void copy_scope_stmt PARAMS ((tree *, int *, inline_data *));
+static tree initialize_inlined_parameters (inline_data *, tree, tree);
+static void remap_block (tree, tree, inline_data *);
+static void copy_scope_stmt (tree *, int *, inline_data *);
#else /* INLINER_FOR_JAVA */
-static tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree, tree));
-static void remap_block PARAMS ((tree *, tree, inline_data *));
-static tree add_stmt_to_compound PARAMS ((tree, tree, tree));
+static tree initialize_inlined_parameters (inline_data *, tree, tree, tree);
+static void remap_block (tree *, tree, inline_data *);
+static tree add_stmt_to_compound (tree, tree, tree);
#endif /* INLINER_FOR_JAVA */
-static tree find_alloca_call_1 PARAMS ((tree *, int *, void *));
-static tree find_alloca_call PARAMS ((tree));
-static tree find_builtin_longjmp_call_1 PARAMS ((tree *, int *, void *));
-static tree find_builtin_longjmp_call PARAMS ((tree));
-
-/* The approximate number of instructions per statement. This number
- need not be particularly accurate; it is used only to make
- decisions about when a function is too big to inline. */
-#define INSNS_PER_STMT (10)
/* Remap DECL during the copying of the BLOCK tree for the function. */
static tree
-remap_decl (decl, id)
- tree decl;
- inline_data *id;
+remap_decl (tree decl, inline_data *id)
{
splay_tree_node n;
tree fn;
@@ -150,6 +143,7 @@ remap_decl (decl, id)
/* See if we have remapped this declaration. */
n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
+
/* If we didn't already have an equivalent for this declaration,
create one now. */
if (!n)
@@ -157,29 +151,26 @@ remap_decl (decl, id)
tree t;
/* Make a copy of the variable or label. */
- t = copy_decl_for_inlining (decl, fn,
- VARRAY_TREE (id->fns, 0));
-
- /* The decl T could be a dynamic array or other variable size type,
- in which case some fields need to be remapped because they may
- contain SAVE_EXPRs. */
- if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
- && TYPE_DOMAIN (TREE_TYPE (t)))
- {
- TREE_TYPE (t) = copy_node (TREE_TYPE (t));
- TYPE_DOMAIN (TREE_TYPE (t))
- = copy_node (TYPE_DOMAIN (TREE_TYPE (t)));
- walk_tree (&TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t))),
- copy_body_r, id, NULL);
- }
+ t = copy_decl_for_inlining (decl, fn, VARRAY_TREE (id->fns, 0));
+
+ /* Remap types, if necessary. */
+ TREE_TYPE (t) = remap_type (TREE_TYPE (t), id);
+ if (TREE_CODE (t) == TYPE_DECL)
+ DECL_ORIGINAL_TYPE (t) = remap_type (DECL_ORIGINAL_TYPE (t), id);
+ else if (TREE_CODE (t) == PARM_DECL)
+ DECL_ARG_TYPE_AS_WRITTEN (t)
+ = remap_type (DECL_ARG_TYPE_AS_WRITTEN (t), id);
+
+ /* Remap sizes as necessary. */
+ walk_tree (&DECL_SIZE (t), copy_body_r, id, NULL);
+ walk_tree (&DECL_SIZE_UNIT (t), copy_body_r, id, NULL);
#ifndef INLINER_FOR_JAVA
if (! DECL_NAME (t) && TREE_TYPE (t)
&& (*lang_hooks.tree_inlining.anon_aggr_type_p) (TREE_TYPE (t)))
{
/* For a VAR_DECL of anonymous type, we must also copy the
- member VAR_DECLS here and rechain the
- DECL_ANON_UNION_ELEMS. */
+ member VAR_DECLS here and rechain the DECL_ANON_UNION_ELEMS. */
tree members = NULL;
tree src;
@@ -206,6 +197,111 @@ remap_decl (decl, id)
return (tree) n->value;
}
+static tree
+remap_type (tree type, inline_data *id)
+{
+ splay_tree_node node;
+ tree new, t;
+
+ if (type == NULL)
+ return type;
+
+ /* See if we have remapped this type. */
+ node = splay_tree_lookup (id->decl_map, (splay_tree_key) type);
+ if (node)
+ return (tree) node->value;
+
+ /* The type only needs remapping if it's variably modified. */
+ if (! variably_modified_type_p (type))
+ {
+ splay_tree_insert (id->decl_map, (splay_tree_key) type,
+ (splay_tree_value) type);
+ return type;
+ }
+
+ /* We do need a copy. build and register it now. */
+ new = copy_node (type);
+ splay_tree_insert (id->decl_map, (splay_tree_key) type,
+ (splay_tree_value) new);
+
+ /* This is a new type, not a copy of an old type. Need to reassociate
+ variants. We can handle everything except the main variant lazily. */
+ t = TYPE_MAIN_VARIANT (type);
+ if (type != t)
+ {
+ t = remap_type (t, id);
+ TYPE_MAIN_VARIANT (new) = t;
+ TYPE_NEXT_VARIANT (new) = TYPE_MAIN_VARIANT (t);
+ TYPE_NEXT_VARIANT (t) = new;
+ }
+ else
+ {
+ TYPE_MAIN_VARIANT (new) = new;
+ TYPE_NEXT_VARIANT (new) = NULL;
+ }
+
+ /* Lazily create pointer and reference types. */
+ TYPE_POINTER_TO (new) = NULL;
+ TYPE_REFERENCE_TO (new) = NULL;
+
+ switch (TREE_CODE (new))
+ {
+ case INTEGER_TYPE:
+ case REAL_TYPE:
+ case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
+ case CHAR_TYPE:
+ t = TYPE_MIN_VALUE (new);
+ if (t && TREE_CODE (t) != INTEGER_CST)
+ walk_tree (&TYPE_MIN_VALUE (new), copy_body_r, id, NULL);
+ t = TYPE_MAX_VALUE (new);
+ if (t && TREE_CODE (t) != INTEGER_CST)
+ walk_tree (&TYPE_MAX_VALUE (new), copy_body_r, id, NULL);
+ return new;
+
+ case POINTER_TYPE:
+ TREE_TYPE (new) = t = remap_type (TREE_TYPE (new), id);
+ if (TYPE_MODE (new) == ptr_mode)
+ TYPE_POINTER_TO (t) = new;
+ return new;
+
+ case REFERENCE_TYPE:
+ TREE_TYPE (new) = t = remap_type (TREE_TYPE (new), id);
+ if (TYPE_MODE (new) == ptr_mode)
+ TYPE_REFERENCE_TO (t) = new;
+ return new;
+
+ case METHOD_TYPE:
+ case FUNCTION_TYPE:
+ TREE_TYPE (new) = remap_type (TREE_TYPE (new), id);
+ walk_tree (&TYPE_ARG_TYPES (new), copy_body_r, id, NULL);
+ return new;
+
+ case ARRAY_TYPE:
+ TREE_TYPE (new) = remap_type (TREE_TYPE (new), id);
+ TYPE_DOMAIN (new) = remap_type (TYPE_DOMAIN (new), id);
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ walk_tree (&TYPE_FIELDS (new), copy_body_r, id, NULL);
+ break;
+
+ case FILE_TYPE:
+ case SET_TYPE:
+ case OFFSET_TYPE:
+ default:
+ /* Shouldn't have been thought variable sized. */
+ abort ();
+ }
+
+ walk_tree (&TYPE_SIZE (new), copy_body_r, id, NULL);
+ walk_tree (&TYPE_SIZE_UNIT (new), copy_body_r, id, NULL);
+
+ return new;
+}
+
#ifndef INLINER_FOR_JAVA
/* Copy the SCOPE_STMT_BLOCK associated with SCOPE_STMT to contain
remapped versions of the variables therein. And hook the new block
@@ -218,14 +314,10 @@ remap_decl (decl, id)
static void
#ifndef INLINER_FOR_JAVA
-remap_block (scope_stmt, decls, id)
- tree scope_stmt;
+remap_block (tree scope_stmt, tree decls, inline_data *id)
#else /* INLINER_FOR_JAVA */
-remap_block (block, decls, id)
- tree *block;
+remap_block (tree *block, tree decls, inline_data *id)
#endif /* INLINER_FOR_JAVA */
- tree decls;
- inline_data *id;
{
#ifndef INLINER_FOR_JAVA
/* We cannot do this in the cleanup for a TARGET_EXPR since we do
@@ -386,10 +478,7 @@ remap_block (block, decls, id)
/* Copy the SCOPE_STMT pointed to by TP. */
static void
-copy_scope_stmt (tp, walk_subtrees, id)
- tree *tp;
- int *walk_subtrees;
- inline_data *id;
+copy_scope_stmt (tree *tp, int *walk_subtrees, inline_data *id)
{
tree block;
@@ -411,10 +500,7 @@ copy_scope_stmt (tp, walk_subtrees, id)
/* Called from copy_body via walk_tree. DATA is really an
`inline_data *'. */
static tree
-copy_body_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees;
- void *data;
+copy_body_r (tree *tp, int *walk_subtrees, void *data)
{
inline_data* id;
tree fn;
@@ -486,8 +572,11 @@ copy_body_r (tp, walk_subtrees, data)
/* Local variables and labels need to be replaced by equivalent
variables. We don't want to copy static variables; there's only
one of those, no matter how many times we inline the containing
- function. */
- else if ((*lang_hooks.tree_inlining.auto_var_in_fn_p) (*tp, fn))
+ function.
+ We do not also want to copy the label which we put into
+ GOTO_STMT which replaced RETURN_STMT. */
+ else if (*tp != id->ret_label
+ && (*lang_hooks.tree_inlining.auto_var_in_fn_p) (*tp, fn))
{
tree new_decl;
@@ -539,23 +628,18 @@ copy_body_r (tp, walk_subtrees, data)
TREE_OPERAND (*tp, 0) = (tree) n->value;
}
#endif /* INLINER_FOR_JAVA */
+ /* Types may need remapping as well. */
+ else if (TYPE_P (*tp))
+ *tp = remap_type (*tp, id);
+
/* Otherwise, just copy the node. Note that copy_tree_r already
knows not to copy VAR_DECLs, etc., so this is safe. */
else
{
- copy_tree_r (tp, walk_subtrees, NULL);
-
- /* The copied TARGET_EXPR has never been expanded, even if the
- original node was expanded already. */
- if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3))
- {
- TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3);
- TREE_OPERAND (*tp, 3) = NULL_TREE;
- }
- else if (TREE_CODE (*tp) == MODIFY_EXPR
- && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1)
- && ((*lang_hooks.tree_inlining.auto_var_in_fn_p)
- (TREE_OPERAND (*tp, 0), fn)))
+ if (TREE_CODE (*tp) == MODIFY_EXPR
+ && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1)
+ && ((*lang_hooks.tree_inlining.auto_var_in_fn_p)
+ (TREE_OPERAND (*tp, 0), fn)))
{
/* Some assignments VAR = VAR; don't generate any rtl code
and thus don't count as variable modification. Avoid
@@ -569,9 +653,45 @@ copy_body_r (tp, walk_subtrees, data)
value = (tree) n->value;
STRIP_TYPE_NOPS (value);
if (TREE_CONSTANT (value) || TREE_READONLY_DECL_P (value))
- *tp = value;
+ {
+ *tp = value;
+ return copy_body_r (tp, walk_subtrees, data);
+ }
+ }
+ }
+ else if (TREE_CODE (*tp) == ADDR_EXPR
+ && ((*lang_hooks.tree_inlining.auto_var_in_fn_p)
+ (TREE_OPERAND (*tp, 0), fn)))
+ {
+ /* Get rid of &* from inline substitutions. It can occur when
+ someone takes the address of a parm or return slot passed by
+ invisible reference. */
+ tree decl = TREE_OPERAND (*tp, 0), value;
+ splay_tree_node n;
+
+ n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
+ if (n)
+ {
+ value = (tree) n->value;
+ if (TREE_CODE (value) == INDIRECT_REF)
+ {
+ *tp = convert (TREE_TYPE (*tp), TREE_OPERAND (value, 0));
+ return copy_body_r (tp, walk_subtrees, data);
+ }
}
}
+
+ copy_tree_r (tp, walk_subtrees, NULL);
+
+ TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id);
+
+ /* The copied TARGET_EXPR has never been expanded, even if the
+ original node was expanded already. */
+ if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3))
+ {
+ TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3);
+ TREE_OPERAND (*tp, 3) = NULL_TREE;
+ }
}
/* Keep iterating. */
@@ -582,8 +702,7 @@ copy_body_r (tp, walk_subtrees, data)
another function. */
static tree
-copy_body (id)
- inline_data *id;
+copy_body (inline_data *id)
{
tree body;
@@ -598,15 +717,9 @@ copy_body (id)
static tree
#ifndef INLINER_FOR_JAVA
-initialize_inlined_parameters (id, args, fn)
+initialize_inlined_parameters (inline_data *id, tree args, tree fn)
#else /* INLINER_FOR_JAVA */
-initialize_inlined_parameters (id, args, fn, block)
-#endif /* INLINER_FOR_JAVA */
- inline_data *id;
- tree args;
- tree fn;
-#ifdef INLINER_FOR_JAVA
- tree block;
+initialize_inlined_parameters (inline_data *id, tree args, tree fn, tree block)
#endif /* INLINER_FOR_JAVA */
{
tree init_stmts;
@@ -616,9 +729,11 @@ initialize_inlined_parameters (id, args, fn, block)
#ifdef INLINER_FOR_JAVA
tree vars = NULL_TREE;
#endif /* INLINER_FOR_JAVA */
+ int argnum = 0;
/* Figure out what the parameters are. */
- parms = DECL_ARGUMENTS (fn);
+ parms =
+DECL_ARGUMENTS (fn);
/* Start with no initializations whatsoever. */
init_stmts = NULL_TREE;
@@ -636,9 +751,11 @@ initialize_inlined_parameters (id, args, fn, block)
tree value;
tree var_sub;
+ ++argnum;
+
/* Find the initializer. */
value = (*lang_hooks.tree_inlining.convert_parm_for_inlining)
- (p, a ? TREE_VALUE (a) : NULL_TREE, fn);
+ (p, a ? TREE_VALUE (a) : NULL_TREE, fn, argnum);
/* If the parameter is never assigned to, we may not need to
create a new variable here at all. Instead, we may be able
@@ -795,14 +912,12 @@ initialize_inlined_parameters (id, args, fn, block)
#ifndef INLINER_FOR_JAVA
static tree
-declare_return_variable (id, use_stmt)
- struct inline_data *id;
- tree *use_stmt;
+declare_return_variable (struct inline_data *id, tree return_slot_addr,
+ tree *use_stmt)
#else /* INLINER_FOR_JAVA */
static tree
-declare_return_variable (id, var)
- struct inline_data *id;
- tree *var;
+declare_return_variable (struct inline_data *id, tree return_slot_addr,
+ tree *var)
#endif /* INLINER_FOR_JAVA */
{
tree fn = VARRAY_TOP_TREE (id->fns);
@@ -827,7 +942,7 @@ declare_return_variable (id, var)
#ifndef INLINER_FOR_JAVA
var = ((*lang_hooks.tree_inlining.copy_res_decl_for_inlining)
(result, fn, VARRAY_TREE (id->fns, 0), id->decl_map,
- &need_return_decl, &id->target_exprs));
+ &need_return_decl, return_slot_addr));
/* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
way, when the RESULT_DECL is encountered, it will be
@@ -853,7 +968,7 @@ declare_return_variable (id, var)
#else /* INLINER_FOR_JAVA */
*var = ((*lang_hooks.tree_inlining.copy_res_decl_for_inlining)
(result, fn, VARRAY_TREE (id->fns, 0), id->decl_map,
- &need_return_decl, NULL_TREE));
+ &need_return_decl, return_slot_addr));
splay_tree_insert (id->decl_map,
(splay_tree_key) result,
@@ -870,206 +985,253 @@ declare_return_variable (id, var)
/* Returns nonzero if a function can be inlined as a tree. */
-int
-tree_inlinable_function_p (fn)
- tree fn;
+bool
+tree_inlinable_function_p (tree fn)
{
- return inlinable_function_p (fn, NULL);
+ return inlinable_function_p (fn);
}
-/* If *TP is possibly call to alloca, return nonzero. */
-static tree
-find_alloca_call_1 (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
-{
- if (alloca_call_p (*tp))
- return *tp;
- return NULL;
-}
+static const char *inline_forbidden_reason;
-/* Return subexpression representing possible alloca call, if any. */
static tree
-find_alloca_call (exp)
- tree exp;
+inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *fnp)
{
- return walk_tree_without_duplicates (&exp, find_alloca_call_1, NULL);
-}
+ tree node = *nodep;
+ tree fn = (tree) fnp;
+ tree t;
-static tree
-find_builtin_longjmp_call_1 (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees ATTRIBUTE_UNUSED;
- void *data ATTRIBUTE_UNUSED;
-{
- tree exp = *tp, decl;
+ switch (TREE_CODE (node))
+ {
+ case CALL_EXPR:
+ /* Refuse to inline alloca call unless user explicitly forced so as
+ this may change program's memory overhead drastically when the
+ function using alloca is called in loop. In GCC present in
+ SPEC2000 inlining into schedule_block cause it to require 2GB of
+ RAM instead of 256MB. */
+ if (alloca_call_p (node)
+ && !lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)))
+ {
+ inline_forbidden_reason
+ = N_("%Jfunction '%F' can never be inlined because it uses "
+ "alloca (override using the always_inline attribute)");
+ return node;
+ }
+ t = get_callee_fndecl (node);
+ if (! t)
+ break;
+
+
+ /* We cannot inline functions that call setjmp. */
+ if (setjmp_call_p (t))
+ {
+ inline_forbidden_reason
+ = N_("%Jfunction '%F' can never be inlined because it uses setjmp");
+ return node;
+ }
+
+ if (DECL_BUILT_IN (t))
+ switch (DECL_FUNCTION_CODE (t))
+ {
+ /* We cannot inline functions that take a variable number of
+ arguments. */
+ case BUILT_IN_VA_START:
+ case BUILT_IN_STDARG_START:
+ case BUILT_IN_NEXT_ARG:
+ case BUILT_IN_VA_END:
+ {
+ inline_forbidden_reason
+ = N_("%Jfunction '%F' can never be inlined because it "
+ "uses variable argument lists");
+ return node;
+ }
+ case BUILT_IN_LONGJMP:
+ {
+ /* We can't inline functions that call __builtin_longjmp at
+ all. The non-local goto machinery really requires the
+ destination be in a different function. If we allow the
+ function calling __builtin_longjmp to be inlined into the
+ function calling __builtin_setjmp, Things will Go Awry. */
+ /* ??? Need front end help to identify "regular" non-local
+ goto. */
+ if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL)
+ {
+ inline_forbidden_reason
+ = N_("%Jfunction '%F' can never be inlined because "
+ "it uses setjmp-longjmp exception handling");
+ return node;
+ }
+ }
+
+ default:
+ break;
+ }
+ break;
- if (TREE_CODE (exp) == CALL_EXPR
- && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
- && (decl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
- TREE_CODE (decl) == FUNCTION_DECL)
- && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (decl) == BUILT_IN_LONGJMP)
- return decl;
+#ifndef INLINER_FOR_JAVA
+ case DECL_STMT:
+ /* We cannot inline functions that contain other functions. */
+ if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
+ && DECL_INITIAL (TREE_OPERAND (node, 0)))
+ {
+ inline_forbidden_reason
+ = N_("%Jfunction '%F' can never be inlined "
+ "because it contains a nested function");
+ return node;
+ }
+ break;
+
+ case GOTO_STMT:
+ case GOTO_EXPR:
+ t = TREE_OPERAND (node, 0);
+
+ /* We will not inline a function which uses computed goto. The
+ addresses of its local labels, which may be tucked into
+ global storage, are of course not constant across
+ instantiations, which causes unexpected behavior. */
+ if (TREE_CODE (t) != LABEL_DECL)
+ {
+ inline_forbidden_reason
+ = N_("%Jfunction '%F' can never be inlined "
+ "because it contains a computed goto");
+ return node;
+ }
+
+ /* We cannot inline a nested function that jumps to a nonlocal
+ label. */
+ if (TREE_CODE (t) == LABEL_DECL && DECL_CONTEXT (t) != fn)
+ {
+ inline_forbidden_reason
+ = N_("%Jfunction '%F' can never be inlined "
+ "because it contains a nonlocal goto");
+ return node;
+ }
+
+ break;
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ /* We cannot inline a function of the form
+
+ void F (int i) { struct S { int ar[i]; } s; }
+
+ Attempting to do so produces a catch-22.
+ If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
+ UNION_TYPE nodes, then it goes into infinite recursion on a
+ structure containing a pointer to its own type. If it doesn't,
+ then the type node for S doesn't get adjusted properly when
+ F is inlined, and we abort in find_function_data. */
+ for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
+ if (variably_modified_type_p (TREE_TYPE (t)))
+ {
+ inline_forbidden_reason
+ = N_("%Jfunction '%F' can never be inlined "
+ "because it uses variable sized variables");
+ return node;
+ }
+#endif
+ default:
+ break;
+ }
- return NULL;
+ return NULL_TREE;
}
+/* Return subexpression representing possible alloca call, if any. */
static tree
-find_builtin_longjmp_call (exp)
- tree exp;
+inline_forbidden_p (tree fndecl)
{
- return walk_tree_without_duplicates (&exp, find_builtin_longjmp_call_1, NULL);
+ location_t saved_loc = input_location;
+ tree ret = walk_tree_without_duplicates
+ (&DECL_SAVED_TREE (fndecl), inline_forbidden_p_1, fndecl);
+ input_location = saved_loc;
+ return ret;
}
-/* Returns nonzero if FN is a function that can be inlined into the
- inlining context ID_. If ID_ is NULL, check whether the function
- can be inlined at all. */
+/* Returns nonzero if FN is a function that does not have any
+ fundamental inline blocking properties. */
-static int
-inlinable_function_p (fn, id)
- tree fn;
- inline_data *id;
+static bool
+inlinable_function_p (tree fn)
{
- int inlinable;
- int currfn_insns;
- int max_inline_insns_single = MAX_INLINE_INSNS_SINGLE;
+ bool inlinable = true;
/* If we've already decided this function shouldn't be inlined,
there's no need to check again. */
if (DECL_UNINLINABLE (fn))
- return 0;
-
- /* Assume it is not inlinable. */
- inlinable = 0;
-
- /* We may be here either because fn is declared inline or because
- we use -finline-functions. For the second case, we are more
- restrictive. */
- if (DID_INLINE_FUNC (fn))
- max_inline_insns_single = MAX_INLINE_INSNS_AUTO;
-
- /* The number of instructions (estimated) of current function. */
- currfn_insns = DECL_NUM_STMTS (fn) * INSNS_PER_STMT;
-
- /* If we're not inlining things, then nothing is inlinable. */
- if (! flag_inline_trees)
- ;
- /* If we're not inlining all functions and the function was not
- declared `inline', we don't inline it. Don't think of
- disregarding DECL_INLINE when flag_inline_trees == 2; it's the
- front-end that must set DECL_INLINE in this case, because
- dwarf2out loses if a function is inlined that doesn't have
- DECL_INLINE set. */
- else if (! DECL_INLINE (fn))
- ;
+ return false;
+
+ /* See if there is any language-specific reason it cannot be
+ inlined. (It is important that this hook be called early because
+ in C++ it may result in template instantiation.)
+ If the function is not inlinable for language-specific reasons,
+ it is left up to the langhook to explain why. */
+ inlinable = !(*lang_hooks.tree_inlining.cannot_inline_tree_fn) (&fn);
+
+ /* If we don't have the function body available, we can't inline it.
+ However, this should not be recorded since we also get here for
+ forward declared inline functions. Therefore, return at once. */
+ if (!DECL_SAVED_TREE (fn))
+ return false;
+
+ /* If we're not inlining at all, then we cannot inline this function. */
+ else if (!flag_inline_trees)
+ inlinable = false;
+
+ /* Only try to inline functions if DECL_INLINE is set. This should be
+ true for all functions declared `inline', and for all other functions
+ as well with -finline-functions.
+
+ Don't think of disregarding DECL_INLINE when flag_inline_trees == 2;
+ it's the front-end that must set DECL_INLINE in this case, because
+ dwarf2out loses if a function that does not have DECL_INLINE set is
+ inlined anyway. That is why we have both DECL_INLINE and
+ DECL_DECLARED_INLINE_P. */
+ /* FIXME: When flag_inline_trees dies, the check for flag_unit_at_a_time
+ here should be redundant. */
+ else if (!DECL_INLINE (fn) && !flag_unit_at_a_time)
+ inlinable = false;
+
#ifdef INLINER_FOR_JAVA
/* Synchronized methods can't be inlined. This is a bug. */
else if (METHOD_SYNCHRONIZED (fn))
- ;
+ inlinable = false;
#endif /* INLINER_FOR_JAVA */
- /* We can't inline functions that are too big. Only allow a single
- function to be of MAX_INLINE_INSNS_SINGLE size. Make special
- allowance for extern inline functions, though. */
- else if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
- && currfn_insns > max_inline_insns_single)
- ;
- /* We can't inline functions that call __builtin_longjmp at all.
- The non-local goto machenery really requires the destination
- be in a different function. If we allow the function calling
- __builtin_longjmp to be inlined into the function calling
- __builtin_setjmp, Things will Go Awry. */
- /* ??? Need front end help to identify "regular" non-local goto. */
- else if (find_builtin_longjmp_call (DECL_SAVED_TREE (fn)))
- ;
- /* Refuse to inline alloca call unless user explicitly forced so as this may
- change program's memory overhead drastically when the function using alloca
- is called in loop. In GCC present in SPEC2000 inlining into schedule_block
- cause it to require 2GB of ram instead of 256MB. */
- else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL
- && find_alloca_call (DECL_SAVED_TREE (fn)))
- ;
- /* All is well. We can inline this function. Traditionally, GCC
- has refused to inline functions using alloca, or functions whose
- values are returned in a PARALLEL, and a few other such obscure
- conditions. We are not equally constrained at the tree level. */
- else
- inlinable = 1;
- /* Squirrel away the result so that we don't have to check again. */
- DECL_UNINLINABLE (fn) = ! inlinable;
-
- /* In case we don't disregard the inlining limits and we basically
- can inline this function, investigate further. */
- if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
- && inlinable
- && currfn_insns > MIN_INLINE_INSNS)
+ else if (inline_forbidden_p (fn))
{
- int sum_insns = (id ? id->inlined_stmts : 0) * INSNS_PER_STMT
- + currfn_insns;
- /* In the extreme case that we have exceeded the recursive inlining
- limit by a huge factor (128), we just say no. Should not happen
- in real life. */
- if (sum_insns > MAX_INLINE_INSNS * 128)
- inlinable = 0;
- /* If we did not hit the extreme limit, we use a linear function
- with slope -1/MAX_INLINE_SLOPE to exceedingly decrease the
- allowable size. We always allow a size of MIN_INLINE_INSNS
- though. */
- else if (sum_insns > MAX_INLINE_INSNS)
- {
- int max_curr = MAX_INLINE_INSNS_SINGLE
- - (sum_insns - MAX_INLINE_INSNS) / MAX_INLINE_SLOPE;
- if (currfn_insns > max_curr)
- inlinable = 0;
- }
+ /* See if we should warn about uninlinable functions. Previously,
+ some of these warnings would be issued while trying to expand
+ the function inline, but that would cause multiple warnings
+ about functions that would for example call alloca. But since
+ this a property of the function, just one warning is enough.
+ As a bonus we can now give more details about the reason why a
+ function is not inlinable.
+ We only warn for functions declared `inline' by the user. */
+ bool do_warning = (warn_inline
+ && DECL_INLINE (fn)
+ && DECL_DECLARED_INLINE_P (fn)
+ && !DECL_IN_SYSTEM_HEADER (fn));
+
+ if (lookup_attribute ("always_inline",
+ DECL_ATTRIBUTES (fn)))
+ sorry (inline_forbidden_reason, fn, fn);
+ else if (do_warning)
+ warning (inline_forbidden_reason, fn, fn);
+
+ inlinable = false;
}
- if (inlinable && (*lang_hooks.tree_inlining.cannot_inline_tree_fn) (&fn))
- inlinable = 0;
-
- /* If we don't have the function body available, we can't inline
- it. */
- if (! DECL_SAVED_TREE (fn))
- inlinable = 0;
-
- /* Check again, language hooks may have modified it. */
- if (! inlinable || DECL_UNINLINABLE (fn))
- return 0;
-
- /* Don't do recursive inlining, either. We don't record this in
- DECL_UNINLINABLE; we may be able to inline this function later. */
- if (id)
- {
- size_t i;
-
- for (i = 0; i < VARRAY_ACTIVE_SIZE (id->fns); ++i)
- if (VARRAY_TREE (id->fns, i) == fn)
- return 0;
-
- if (DECL_INLINED_FNS (fn))
- {
- int j;
- tree inlined_fns = DECL_INLINED_FNS (fn);
-
- for (j = 0; j < TREE_VEC_LENGTH (inlined_fns); ++j)
- if (TREE_VEC_ELT (inlined_fns, j) == VARRAY_TREE (id->fns, 0))
- return 0;
- }
- }
+ /* Squirrel away the result so that we don't have to check again. */
+ DECL_UNINLINABLE (fn) = !inlinable;
- /* Return the result. */
return inlinable;
}
/* If *TP is a CALL_EXPR, replace it with its inline expansion. */
static tree
-expand_call_inline (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees;
- void *data;
+expand_call_inline (tree *tp, int *walk_subtrees, void *data)
{
inline_data *id;
tree t;
@@ -1086,6 +1248,9 @@ expand_call_inline (tp, walk_subtrees, data)
tree arg_inits;
tree *inlined_body;
splay_tree st;
+ tree args;
+ tree return_slot_addr;
+ const char *reason;
/* See what we've got. */
id = (inline_data *) data;
@@ -1101,9 +1266,6 @@ expand_call_inline (tp, walk_subtrees, data)
/* We're walking our own subtrees. */
*walk_subtrees = 0;
- /* Push *TP on the stack of pending TARGET_EXPRs. */
- VARRAY_PUSH_TREE (id->target_exprs, *tp);
-
/* Actually walk over them. This loop is the body of
walk_trees, omitting the case where the TARGET_EXPR
itself is handled. */
@@ -1117,9 +1279,6 @@ expand_call_inline (tp, walk_subtrees, data)
--id->in_target_cleanup_p;
}
- /* We're done with this TARGET_EXPR now. */
- VARRAY_POP (id->target_exprs);
-
return NULL_TREE;
#else /* INLINER_FOR_JAVA */
abort ();
@@ -1131,7 +1290,7 @@ expand_call_inline (tp, walk_subtrees, data)
*walk_subtrees = 0;
/* Update the source position. */
push_srcloc (EXPR_WFL_FILENAME (t), EXPR_WFL_LINENO (t));
- walk_tree (&EXPR_WFL_NODE (t), expand_call_inline, data,
+ walk_tree (&EXPR_WFL_NODE (t), expand_call_inline, data,
id->tree_pruner);
/* Restore the original source position. */
pop_srcloc ();
@@ -1155,6 +1314,9 @@ expand_call_inline (tp, walk_subtrees, data)
if (!fn)
return NULL_TREE;
+ /* Turn forward declarations into real ones. */
+ fn = cgraph_node (fn)->decl;
+
/* If fn is a declaration of a function in a nested scope that was
globally declared inline, we don't set its DECL_INITIAL.
However, we can't blindly follow DECL_ABSTRACT_ORIGIN because the
@@ -1169,12 +1331,18 @@ expand_call_inline (tp, walk_subtrees, data)
/* Don't try to inline functions that are not well-suited to
inlining. */
- if (!inlinable_function_p (fn, id))
+ if (!cgraph_inline_p (id->current_decl, fn, &reason))
{
- if (warn_inline && DECL_INLINE (fn) && !DID_INLINE_FUNC (fn)
- && !DECL_IN_SYSTEM_HEADER (fn))
+ if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)))
{
- warning_with_decl (fn, "inlining failed in call to `%s'");
+ sorry ("%Jinlining failed in call to '%F': %s", fn, fn, reason);
+ sorry ("called from here");
+ }
+ else if (warn_inline && DECL_DECLARED_INLINE_P (fn)
+ && !DECL_IN_SYSTEM_HEADER (fn)
+ && strlen (reason))
+ {
+ warning ("%Jinlining failed in call to '%F': %s", fn, fn, reason);
warning ("called from here");
}
return NULL_TREE;
@@ -1199,6 +1367,9 @@ expand_call_inline (tp, walk_subtrees, data)
expr = build1 (STMT_EXPR, TREE_TYPE (TREE_TYPE (fn)), make_node (COMPOUND_STMT));
/* There is no scope associated with the statement-expression. */
STMT_EXPR_NO_SCOPE (expr) = 1;
+ if (lookup_attribute ("warn_unused_result",
+ TYPE_ATTRIBUTES (TREE_TYPE (fn))))
+ STMT_EXPR_WARN_UNUSED_RESULT (expr) = 1;
stmt = STMT_EXPR_STMT (expr);
#else /* INLINER_FOR_JAVA */
/* Build a block containing code to initialize the arguments, the
@@ -1216,8 +1387,16 @@ expand_call_inline (tp, walk_subtrees, data)
NULL, NULL);
/* Initialize the parameters. */
+ args = TREE_OPERAND (t, 1);
+ return_slot_addr = NULL_TREE;
+ if (CALL_EXPR_HAS_RETURN_SLOT_ADDR (t))
+ {
+ return_slot_addr = TREE_VALUE (args);
+ args = TREE_CHAIN (args);
+ }
+
#ifndef INLINER_FOR_JAVA
- arg_inits = initialize_inlined_parameters (id, TREE_OPERAND (t, 1), fn);
+ arg_inits = initialize_inlined_parameters (id, args, fn);
/* Expand any inlined calls in the initializers. Do this before we
push FN on the stack of functions we are inlining; we want to
inline calls to FN that appear in the initializers for the
@@ -1226,7 +1405,7 @@ expand_call_inline (tp, walk_subtrees, data)
/* And add them to the tree. */
COMPOUND_BODY (stmt) = chainon (COMPOUND_BODY (stmt), arg_inits);
#else /* INLINER_FOR_JAVA */
- arg_inits = initialize_inlined_parameters (id, TREE_OPERAND (t, 1), fn, expr);
+ arg_inits = initialize_inlined_parameters (id, args, fn, expr);
if (arg_inits)
{
/* Expand any inlined calls in the initializers. Do this before we
@@ -1287,11 +1466,11 @@ expand_call_inline (tp, walk_subtrees, data)
/* Declare the return variable for the function. */
COMPOUND_BODY (stmt)
= chainon (COMPOUND_BODY (stmt),
- declare_return_variable (id, &use_stmt));
+ declare_return_variable (id, return_slot_addr, &use_stmt));
#else /* INLINER_FOR_JAVA */
{
/* Declare the return variable for the function. */
- tree decl = declare_return_variable (id, &retvar);
+ tree decl = declare_return_variable (id, return_slot_addr, &retvar);
if (retvar)
{
tree *next = &BLOCK_VARS (expr);
@@ -1323,7 +1502,7 @@ expand_call_inline (tp, walk_subtrees, data)
#endif /* INLINER_FOR_JAVA */
/* After the body of the function comes the RET_LABEL. This must come
- before we evaluate the returned value below, because that evalulation
+ before we evaluate the returned value below, because that evaluation
may cause RTL to be generated. */
#ifndef INLINER_FOR_JAVA
COMPOUND_BODY (stmt)
@@ -1376,13 +1555,9 @@ expand_call_inline (tp, walk_subtrees, data)
pointing to the right place. */
#ifndef INLINER_FOR_JAVA
chain = TREE_CHAIN (*tp);
+#endif /* INLINER_FOR_JAVA */
*tp = build_expr_wfl (expr, DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn),
/*col=*/0);
-#else /* INLINER_FOR_JAVA */
- *tp = build_expr_wfl (expr, DECL_SOURCE_FILE (fn),
- DECL_SOURCE_LINE_FIRST(fn),
- /*col=*/0);
-#endif /* INLINER_FOR_JAVA */
EXPR_WFL_EMIT_LINE_NOTE (*tp) = 1;
#ifndef INLINER_FOR_JAVA
TREE_CHAIN (*tp) = chain;
@@ -1394,20 +1569,22 @@ expand_call_inline (tp, walk_subtrees, data)
the equivalent inlined version either. */
TREE_USED (*tp) = 1;
- /* Our function now has more statements than it did before. */
- DECL_NUM_STMTS (VARRAY_TREE (id->fns, 0)) += DECL_NUM_STMTS (fn);
- /* For accounting, subtract one for the saved call/ret. */
- id->inlined_stmts += DECL_NUM_STMTS (fn) - 1;
+ /* Update callgraph if needed. */
+ if (id->decl)
+ {
+ cgraph_remove_call (id->decl, fn);
+ cgraph_create_edges (id->decl, *inlined_body);
+ }
/* Recurse into the body of the just inlined function. */
- expand_calls_inline (inlined_body, id);
+ {
+ tree old_decl = id->current_decl;
+ id->current_decl = fn;
+ expand_calls_inline (inlined_body, id);
+ id->current_decl = old_decl;
+ }
VARRAY_POP (id->fns);
- /* If we've returned to the top level, clear out the record of how
- much inlining has been done. */
- if (VARRAY_ACTIVE_SIZE (id->fns) == id->first_inlined_fn)
- id->inlined_stmts = 0;
-
/* Don't walk into subtrees. We've already handled them above. */
*walk_subtrees = 0;
@@ -1420,9 +1597,7 @@ expand_call_inline (tp, walk_subtrees, data)
expansions as appropriate. */
static void
-expand_calls_inline (tp, id)
- tree *tp;
- inline_data *id;
+expand_calls_inline (tree *tp, inline_data *id)
{
/* Search through *TP, replacing all calls to inline functions by
appropriate equivalents. Use walk_tree in no-duplicates mode
@@ -1436,15 +1611,22 @@ expand_calls_inline (tp, id)
/* Expand calls to inline functions in the body of FN. */
void
-optimize_inline_calls (fn)
- tree fn;
+optimize_inline_calls (tree fn)
{
inline_data id;
tree prev_fn;
+ /* There is no point in performing inlining if errors have already
+ occurred -- and we might crash if we try to inline invalid
+ code. */
+ if (errorcount || sorrycount)
+ return;
+
/* Clear out ID. */
memset (&id, 0, sizeof (id));
+ id.decl = fn;
+ id.current_decl = fn;
/* Don't allow recursion into FN. */
VARRAY_TREE_INIT (id.fns, 32, "fns");
VARRAY_PUSH_TREE (id.fns, fn);
@@ -1459,9 +1641,6 @@ optimize_inline_calls (fn)
prev_fn = ((*lang_hooks.tree_inlining.add_pending_fn_decls)
(&id.fns, prev_fn));
- /* Create the stack of TARGET_EXPRs. */
- VARRAY_TREE_INIT (id.target_exprs, 32, "target_exprs");
-
/* Create the list of functions this call will inline. */
VARRAY_TREE_INIT (id.inlined_fns, 32, "inlined_fns");
@@ -1493,9 +1672,7 @@ optimize_inline_calls (fn)
declarations according to the ARG_MAP splay_tree. */
void
-clone_body (clone, fn, arg_map)
- tree clone, fn;
- void *arg_map;
+clone_body (tree clone, tree fn, void *arg_map)
{
inline_data id;
@@ -1525,11 +1702,7 @@ clone_body (clone, fn, arg_map)
once. */
tree
-walk_tree (tp, func, data, htab_)
- tree *tp;
- walk_tree_fn func;
- void *data;
- void *htab_;
+walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
{
htab_t htab = (htab_t) htab_;
enum tree_code code;
@@ -1585,7 +1758,7 @@ walk_tree (tp, func, data, htab_)
interesting below this point in the tree. */
if (!walk_subtrees)
{
- if (statement_code_p (code) || code == TREE_LIST
+ if (STATEMENT_CODE_P (code) || code == TREE_LIST
|| (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp))
/* But we still need to check our siblings. */
WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
@@ -1594,15 +1767,11 @@ walk_tree (tp, func, data, htab_)
}
/* Handle common cases up front. */
- if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
- || TREE_CODE_CLASS (code) == 'r'
- || TREE_CODE_CLASS (code) == 's')
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
#else /* INLINER_FOR_JAVA */
if (code != EXIT_BLOCK_EXPR
&& code != SAVE_EXPR
- && (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
- || TREE_CODE_CLASS (code) == 'r'
- || TREE_CODE_CLASS (code) == 's'))
+ && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
#endif /* INLINER_FOR_JAVA */
{
int i, len;
@@ -1610,8 +1779,8 @@ walk_tree (tp, func, data, htab_)
#ifndef INLINER_FOR_JAVA
/* Set lineno here so we get the right instantiation context
if we call instantiate_decl from inlinable_function_p. */
- if (statement_code_p (code) && !STMT_LINENO_FOR_FN_P (*tp))
- lineno = STMT_LINENO (*tp);
+ if (STATEMENT_CODE_P (code) && !STMT_LINENO_FOR_FN_P (*tp))
+ input_line = STMT_LINENO (*tp);
#endif /* not INLINER_FOR_JAVA */
/* Walk over all the sub-trees of this operand. */
@@ -1629,7 +1798,7 @@ walk_tree (tp, func, data, htab_)
#ifndef INLINER_FOR_JAVA
/* For statements, we also walk the chain so that we cover the
entire statement tree. */
- if (statement_code_p (code))
+ if (STATEMENT_CODE_P (code))
{
if (code == DECL_STMT
&& DECL_STMT_DECL (*tp)
@@ -1643,6 +1812,7 @@ walk_tree (tp, func, data, htab_)
WALK_SUBTREE (DECL_INITIAL (DECL_STMT_DECL (*tp)));
WALK_SUBTREE (DECL_SIZE (DECL_STMT_DECL (*tp)));
WALK_SUBTREE (DECL_SIZE_UNIT (DECL_STMT_DECL (*tp)));
+ WALK_SUBTREE (TREE_TYPE (*tp));
}
/* This can be tail-recursion optimized if we write it this way. */
@@ -1689,7 +1859,8 @@ walk_tree (tp, func, data, htab_)
case BLOCK:
case RECORD_TYPE:
case CHAR_TYPE:
- /* None of thse have subtrees other than those already walked
+ case PLACEHOLDER_EXPR:
+ /* None of these have subtrees other than those already walked
above. */
break;
@@ -1775,10 +1946,7 @@ walk_tree (tp, func, data, htab_)
once. */
tree
-walk_tree_without_duplicates (tp, func, data)
- tree *tp;
- walk_tree_fn func;
- void *data;
+walk_tree_without_duplicates (tree *tp, walk_tree_fn func, void *data)
{
tree result;
htab_t htab;
@@ -1792,18 +1960,13 @@ walk_tree_without_duplicates (tp, func, data)
/* Passed to walk_tree. Copies the node pointed to, if appropriate. */
tree
-copy_tree_r (tp, walk_subtrees, data)
- tree *tp;
- int *walk_subtrees;
- void *data ATTRIBUTE_UNUSED;
+copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
enum tree_code code = TREE_CODE (*tp);
/* We make copies of most nodes. */
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
- || TREE_CODE_CLASS (code) == 'r'
|| TREE_CODE_CLASS (code) == 'c'
- || TREE_CODE_CLASS (code) == 's'
|| code == TREE_LIST
|| code == TREE_VEC
|| (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp))
@@ -1820,7 +1983,7 @@ copy_tree_r (tp, walk_subtrees, data)
if (code == PARM_DECL || code == TREE_LIST
#ifndef INLINER_FOR_JAVA
|| (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp)
- || statement_code_p (code))
+ || STATEMENT_CODE_P (code))
TREE_CHAIN (*tp) = chain;
/* For now, we don't update BLOCKs when we make copies. So, we
@@ -1832,8 +1995,7 @@ copy_tree_r (tp, walk_subtrees, data)
TREE_CHAIN (*tp) = chain;
#endif /* INLINER_FOR_JAVA */
}
- else if (TREE_CODE_CLASS (code) == 't' && !variably_modified_type_p (*tp))
- /* Types only need to be copied if they are variably modified. */
+ else if (TREE_CODE_CLASS (code) == 't')
*walk_subtrees = 0;
return NULL_TREE;
@@ -1845,11 +2007,7 @@ copy_tree_r (tp, walk_subtrees, data)
ST. FN is the function into which the copy will be placed. */
void
-remap_save_expr (tp, st_, fn, walk_subtrees)
- tree *tp;
- void *st_;
- tree fn;
- int *walk_subtrees;
+remap_save_expr (tree *tp, void *st_, tree fn, int *walk_subtrees)
{
splay_tree st = (splay_tree) st_;
splay_tree_node n;
@@ -1872,8 +2030,7 @@ remap_save_expr (tp, st_, fn, walk_subtrees)
(splay_tree_key) *tp,
(splay_tree_value) t);
/* Make sure we don't remap an already-remapped SAVE_EXPR. */
- splay_tree_insert (st, (splay_tree_key) t,
- (splay_tree_value) error_mark_node);
+ splay_tree_insert (st, (splay_tree_key) t, (splay_tree_value) t);
}
else
/* We've already walked into this SAVE_EXPR, so we needn't do it
@@ -1889,8 +2046,7 @@ remap_save_expr (tp, st_, fn, walk_subtrees)
COMPOUND_EXPR and add STMT to it. */
static tree
-add_stmt_to_compound (existing, type, stmt)
- tree existing, type, stmt;
+add_stmt_to_compound (tree existing, tree type, tree stmt)
{
if (!stmt)
return existing;
diff --git a/contrib/gcc/tree-inline.h b/contrib/gcc/tree-inline.h
index 9c11436f3999..febf9e7bc20e 100644
--- a/contrib/gcc/tree-inline.h
+++ b/contrib/gcc/tree-inline.h
@@ -1,21 +1,21 @@
/* Tree inlining hooks and declarations.
- Copyright 2001 Free Software Foundation, Inc.
+ Copyright 2001, 2003 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <aoliva@redhat.com>
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+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 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+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 GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -24,13 +24,13 @@ Boston, MA 02111-1307, USA. */
/* Function prototypes. */
-void optimize_inline_calls PARAMS ((tree));
-int tree_inlinable_function_p PARAMS ((tree));
-tree walk_tree PARAMS ((tree*, walk_tree_fn, void*, void*));
-tree walk_tree_without_duplicates PARAMS ((tree*, walk_tree_fn, void*));
-tree copy_tree_r PARAMS ((tree*, int*, void*));
-void clone_body PARAMS ((tree, tree, void*));
-void remap_save_expr PARAMS ((tree*, void*, tree, int*));
+void optimize_inline_calls (tree);
+bool tree_inlinable_function_p (tree);
+tree walk_tree (tree*, walk_tree_fn, void*, void*);
+tree walk_tree_without_duplicates (tree*, walk_tree_fn, void*);
+tree copy_tree_r (tree*, int*, void*);
+void clone_body (tree, tree, void*);
+void remap_save_expr (tree*, void*, tree, int*);
/* 0 if we should not perform inlining.
1 if we should expand functions calls inline at the tree level.
diff --git a/contrib/gcc/tree-optimize.c b/contrib/gcc/tree-optimize.c
new file mode 100644
index 000000000000..bc08e03f199f
--- /dev/null
+++ b/contrib/gcc/tree-optimize.c
@@ -0,0 +1,231 @@
+/* Control and data flow functions for trees.
+ Copyright 2001, 2002, 2003, 2004 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "toplev.h"
+#include "tree.h"
+#include "tree-inline.h"
+#include "flags.h"
+#include "langhooks.h"
+#include "cgraph.h"
+#include "timevar.h"
+#include "tm.h"
+#include "function.h"
+#include "ggc.h"
+
+
+/* Called to move the SAVE_EXPRs for parameter declarations in a
+ nested function into the nested function. DATA is really the
+ nested FUNCTION_DECL. */
+
+static tree
+set_save_expr_context (tree *tp,
+ int *walk_subtrees,
+ void *data)
+{
+ if (TREE_CODE (*tp) == SAVE_EXPR && !SAVE_EXPR_CONTEXT (*tp))
+ SAVE_EXPR_CONTEXT (*tp) = (tree) data;
+ /* Do not walk back into the SAVE_EXPR_CONTEXT; that will cause
+ circularity. */
+ else if (DECL_P (*tp))
+ *walk_subtrees = 0;
+
+ return NULL;
+}
+
+/* Clear out the DECL_RTL for the non-static local variables in BLOCK and
+ its sub-blocks. DATA is the decl of the function being processed. */
+
+static tree
+clear_decl_rtl (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
+{
+ bool nonstatic_p, local_p;
+ tree t = *tp;
+
+ switch (TREE_CODE (t))
+ {
+ case VAR_DECL:
+ nonstatic_p = !TREE_STATIC (t) && !DECL_EXTERNAL (t);
+ local_p = decl_function_context (t) == data;
+ break;
+
+ case PARM_DECL:
+ case LABEL_DECL:
+ nonstatic_p = true;
+ local_p = decl_function_context (t) == data;
+ break;
+
+ case RESULT_DECL:
+ nonstatic_p = local_p = true;
+ break;
+
+ default:
+ nonstatic_p = local_p = false;
+ break;
+ }
+
+ if (nonstatic_p && local_p)
+ SET_DECL_RTL (t, NULL);
+
+ return NULL;
+}
+
+/* For functions-as-trees languages, this performs all optimization and
+ compilation for FNDECL. */
+
+void
+tree_rest_of_compilation (tree fndecl, bool nested_p)
+{
+ location_t saved_loc;
+
+ timevar_push (TV_EXPAND);
+
+ if (flag_unit_at_a_time && !cgraph_global_info_ready)
+ abort ();
+
+ /* Initialize the RTL code for the function. */
+ current_function_decl = fndecl;
+ saved_loc = input_location;
+ input_location = DECL_SOURCE_LOCATION (fndecl);
+ init_function_start (fndecl);
+
+ /* This function is being processed in whole-function mode. */
+ cfun->x_whole_function_mode_p = 1;
+
+ /* Even though we're inside a function body, we still don't want to
+ call expand_expr to calculate the size of a variable-sized array.
+ We haven't necessarily assigned RTL to all variables yet, so it's
+ not safe to try to expand expressions involving them. */
+ immediate_size_expand = 0;
+ cfun->x_dont_save_pending_sizes_p = 1;
+
+ /* If the function has a variably modified type, there may be
+ SAVE_EXPRs in the parameter types. Their context must be set to
+ refer to this function; they cannot be expanded in the containing
+ function. */
+ if (decl_function_context (fndecl)
+ && variably_modified_type_p (TREE_TYPE (fndecl)))
+ walk_tree (&TREE_TYPE (fndecl), set_save_expr_context, fndecl,
+ NULL);
+
+ /* Set up parameters and prepare for return, for the function. */
+ expand_function_start (fndecl, 0);
+
+ /* Allow language dialects to perform special processing. */
+ (*lang_hooks.rtl_expand.start) ();
+
+ /* If this function is `main', emit a call to `__main'
+ to run global initializers, etc. */
+ if (DECL_NAME (fndecl)
+ && MAIN_NAME_P (DECL_NAME (fndecl))
+ && DECL_FILE_SCOPE_P (fndecl))
+ expand_main_function ();
+
+ /* Generate the RTL for this function. */
+ (*lang_hooks.rtl_expand.stmt) (DECL_SAVED_TREE (fndecl));
+
+ /* We hard-wired immediate_size_expand to zero above.
+ expand_function_end will decrement this variable. So, we set the
+ variable to one here, so that after the decrement it will remain
+ zero. */
+ immediate_size_expand = 1;
+
+ /* Allow language dialects to perform special processing. */
+ (*lang_hooks.rtl_expand.end) ();
+
+ /* Generate rtl for function exit. */
+ expand_function_end ();
+
+ /* If this is a nested function, protect the local variables in the stack
+ above us from being collected while we're compiling this function. */
+ if (nested_p)
+ ggc_push_context ();
+
+ /* There's no need to defer outputting this function any more; we
+ know we want to output it. */
+ DECL_DEFER_OUTPUT (fndecl) = 0;
+
+ /* Run the optimizers and output the assembler code for this function. */
+ rest_of_compilation (fndecl);
+
+ /* Undo the GC context switch. */
+ if (nested_p)
+ ggc_pop_context ();
+
+ /* If requested, warn about function definitions where the function will
+ return a value (usually of some struct or union type) which itself will
+ take up a lot of stack space. */
+ if (warn_larger_than && !DECL_EXTERNAL (fndecl) && TREE_TYPE (fndecl))
+ {
+ tree ret_type = TREE_TYPE (TREE_TYPE (fndecl));
+
+ if (ret_type && TYPE_SIZE_UNIT (ret_type)
+ && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST
+ && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type),
+ larger_than_size))
+ {
+ unsigned int size_as_int
+ = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type));
+
+ if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0)
+ warning ("%Jsize of return value of '%D' is %u bytes",
+ fndecl, fndecl, size_as_int);
+ else
+ warning ("%Jsize of return value of '%D' is larger than %wd bytes",
+ fndecl, fndecl, larger_than_size);
+ }
+ }
+
+ if (! DECL_DEFER_OUTPUT (fndecl) || !cgraph_node (fndecl)->origin)
+ {
+ /* Since we don't need the RTL for this function anymore, stop pointing
+ to it. That's especially important for LABEL_DECLs, since you can
+ reach all the instructions in the function from the CODE_LABEL stored
+ in the DECL_RTL for the LABEL_DECL. Walk the BLOCK-tree, clearing
+ DECL_RTL for LABEL_DECLs and non-static local variables. Note that
+ we must check the context of the variables, otherwise processing a
+ nested function can kill the rtl of a variable from an outer
+ function. */
+ walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
+ clear_decl_rtl,
+ fndecl);
+ if (!cgraph_function_possibly_inlined_p (fndecl))
+ {
+ DECL_SAVED_TREE (fndecl) = NULL;
+ if (DECL_SAVED_INSNS (fndecl) == 0
+ && !cgraph_node (fndecl)->origin)
+ {
+ /* Stop pointing to the local nodes about to be freed.
+ But DECL_INITIAL must remain nonzero so we know this
+ was an actual function definition.
+ For a nested function, this is done in c_pop_function_context.
+ If rest_of_compilation set this to 0, leave it 0. */
+ if (DECL_INITIAL (fndecl) != 0)
+ DECL_INITIAL (fndecl) = error_mark_node;
+ }
+ }
+ }
+
+ input_location = saved_loc;
+
+ timevar_pop (TV_EXPAND);
+}
diff --git a/contrib/gcc/tree.c b/contrib/gcc/tree.c
index e8c2541c1d99..32f1c1890497 100644
--- a/contrib/gcc/tree.c
+++ b/contrib/gcc/tree.c
@@ -1,6 +1,6 @@
/* Language-independent node constructors for parse phase of GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -31,6 +31,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "flags.h"
#include "tree.h"
#include "real.h"
@@ -45,32 +47,15 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "langhooks.h"
/* obstack.[ch] explicitly declined to prototype this. */
-extern int _obstack_allocated_p PARAMS ((struct obstack *h, PTR obj));
+extern int _obstack_allocated_p (struct obstack *h, void *obj);
#ifdef GATHER_STATISTICS
/* Statistics-gathering stuff. */
-typedef enum
-{
- d_kind,
- t_kind,
- b_kind,
- s_kind,
- r_kind,
- e_kind,
- c_kind,
- id_kind,
- perm_list_kind,
- temp_list_kind,
- vec_kind,
- x_kind,
- lang_decl,
- lang_type,
- all_kinds
-} tree_node_kind;
int tree_node_counts[(int) all_kinds];
int tree_node_sizes[(int) all_kinds];
+/* Keep in sync with tree.h:enum tree_node_kind. */
static const char * const tree_node_kind_names[] = {
"decls",
"types",
@@ -90,9 +75,9 @@ static const char * const tree_node_kind_names[] = {
#endif /* GATHER_STATISTICS */
/* Unique id for next decl created. */
-static int next_decl_uid;
+static GTY(()) int next_decl_uid;
/* Unique id for next type created. */
-static int next_type_uid = 1;
+static GTY(()) int next_type_uid = 1;
/* Since we cannot rehash a type after it is in the table, we have to
keep the hash code. */
@@ -116,14 +101,13 @@ struct type_hash GTY(())
static GTY ((if_marked ("type_hash_marked_p"), param_is (struct type_hash)))
htab_t type_hash_table;
-static void set_type_quals PARAMS ((tree, int));
-static void append_random_chars PARAMS ((char *));
-static int type_hash_eq PARAMS ((const void *, const void *));
-static hashval_t type_hash_hash PARAMS ((const void *));
-static void print_type_hash_statistics PARAMS((void));
-static void finish_vector_type PARAMS((tree));
-static tree make_vector PARAMS ((enum machine_mode, tree, int));
-static int type_hash_marked_p PARAMS ((const void *));
+static void set_type_quals (tree, int);
+static int type_hash_eq (const void *, const void *);
+static hashval_t type_hash_hash (const void *);
+static void print_type_hash_statistics (void);
+static void finish_vector_type (tree);
+static tree make_vector (enum machine_mode, tree, int);
+static int type_hash_marked_p (const void *);
tree global_trees[TI_MAX];
tree integer_types[itk_none];
@@ -131,11 +115,11 @@ tree integer_types[itk_none];
/* Init tree.c. */
void
-init_ttree ()
+init_ttree (void)
{
/* Initialize the hash table of types. */
- type_hash_table = htab_create (TYPE_HASH_INITIAL_SIZE, type_hash_hash,
- type_hash_eq, 0);
+ type_hash_table = htab_create_ggc (TYPE_HASH_INITIAL_SIZE, type_hash_hash,
+ type_hash_eq, 0);
}
@@ -143,8 +127,7 @@ init_ttree ()
translations made by ASM_OUTPUT_LABELREF). Often this is the same
as DECL_NAME. It is an IDENTIFIER_NODE. */
tree
-decl_assembler_name (decl)
- tree decl;
+decl_assembler_name (tree decl)
{
if (!DECL_ASSEMBLER_NAME_SET_P (decl))
(*lang_hooks.set_decl_assembler_name) (decl);
@@ -154,8 +137,7 @@ decl_assembler_name (decl)
/* Compute the number of bytes occupied by 'node'. This routine only
looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH. */
size_t
-tree_size (node)
- tree node;
+tree_size (tree node)
{
enum tree_code code = TREE_CODE (node);
@@ -180,28 +162,32 @@ tree_size (node)
+ TREE_CODE_LENGTH (code) * sizeof (char *) - sizeof (char *));
case 'c': /* a constant */
- /* We can't use TREE_CODE_LENGTH for INTEGER_CST, since the number of
- words is machine-dependent due to varying length of HOST_WIDE_INT,
- which might be wider than a pointer (e.g., long long). Similarly
- for REAL_CST, since the number of words is machine-dependent due
- to varying size and alignment of `double'. */
- if (code == INTEGER_CST)
- return sizeof (struct tree_int_cst);
- else if (code == REAL_CST)
- return sizeof (struct tree_real_cst);
- else
- return (sizeof (struct tree_common)
- + TREE_CODE_LENGTH (code) * sizeof (char *));
+ switch (code)
+ {
+ case INTEGER_CST: return sizeof (struct tree_int_cst);
+ case REAL_CST: return sizeof (struct tree_real_cst);
+ case COMPLEX_CST: return sizeof (struct tree_complex);
+ case VECTOR_CST: return sizeof (struct tree_vector);
+ case STRING_CST: return sizeof (struct tree_string);
+ default:
+ return (*lang_hooks.tree_size) (code);
+ }
case 'x': /* something random, like an identifier. */
- {
- size_t length;
- length = (sizeof (struct tree_common)
- + TREE_CODE_LENGTH (code) * sizeof (char *));
- if (code == TREE_VEC)
- length += TREE_VEC_LENGTH (node) * sizeof (char *) - sizeof (char *);
- return length;
- }
+ switch (code)
+ {
+ case IDENTIFIER_NODE: return lang_hooks.identifier_size;
+ case TREE_LIST: return sizeof (struct tree_list);
+ case TREE_VEC: return (sizeof (struct tree_vec)
+ + TREE_VEC_LENGTH(node) * sizeof(char *)
+ - sizeof (char *));
+
+ case ERROR_MARK:
+ case PLACEHOLDER_EXPR: return sizeof (struct tree_common);
+
+ default:
+ return (*lang_hooks.tree_size) (code);
+ }
default:
abort ();
@@ -215,8 +201,7 @@ tree_size (node)
Achoo! I got a code in the node. */
tree
-make_node (code)
- enum tree_code code;
+make_node (enum tree_code code)
{
tree t;
int type = TREE_CODE_CLASS (code);
@@ -287,7 +272,7 @@ make_node (code)
t = ggc_alloc_tree (length);
- memset ((PTR) t, 0, length);
+ memset (t, 0, length);
TREE_SET_CODE (t, code);
@@ -295,7 +280,6 @@ make_node (code)
{
case 's':
TREE_SIDE_EFFECTS (t) = 1;
- TREE_TYPE (t) = void_type_node;
break;
case 'd':
@@ -303,9 +287,7 @@ make_node (code)
DECL_ALIGN (t) = 1;
DECL_USER_ALIGN (t) = 0;
DECL_IN_SYSTEM_HEADER (t) = in_system_header;
- DECL_SOURCE_LINE (t) = lineno;
- DECL_SOURCE_FILE (t) =
- (input_filename) ? input_filename : "<built-in>";
+ DECL_SOURCE_LOCATION (t) = input_location;
DECL_UID (t) = next_decl_uid++;
/* We have not yet computed the alias set for this declaration. */
@@ -359,8 +341,7 @@ make_node (code)
TREE_CHAIN is zero and it has a fresh uid. */
tree
-copy_node (node)
- tree node;
+copy_node (tree node)
{
tree t;
enum tree_code code = TREE_CODE (node);
@@ -394,8 +375,7 @@ copy_node (node)
For example, this can copy a list made of TREE_LIST nodes. */
tree
-copy_list (list)
- tree list;
+copy_list (tree list)
{
tree head;
tree prev, next;
@@ -422,9 +402,7 @@ copy_list (list)
This function should be used via the `build_int_2' macro. */
tree
-build_int_2_wide (low, hi)
- unsigned HOST_WIDE_INT low;
- HOST_WIDE_INT hi;
+build_int_2_wide (unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
{
tree t = make_node (INTEGER_CST);
@@ -438,8 +416,7 @@ build_int_2_wide (low, hi)
are in a list pointed by VALS. */
tree
-build_vector (type, vals)
- tree type, vals;
+build_vector (tree type, tree vals)
{
tree v = make_node (VECTOR_CST);
int over1 = 0, over2 = 0;
@@ -463,12 +440,32 @@ build_vector (type, vals)
return v;
}
+/* Return a new CONSTRUCTOR node whose type is TYPE and whose values
+ are in a list pointed to by VALS. */
+tree
+build_constructor (tree type, tree vals)
+{
+ tree c = make_node (CONSTRUCTOR);
+ TREE_TYPE (c) = type;
+ CONSTRUCTOR_ELTS (c) = vals;
+
+ /* ??? May not be necessary. Mirrors what build does. */
+ if (vals)
+ {
+ TREE_SIDE_EFFECTS (c) = TREE_SIDE_EFFECTS (vals);
+ TREE_READONLY (c) = TREE_READONLY (vals);
+ TREE_CONSTANT (c) = TREE_CONSTANT (vals);
+ }
+ else
+ TREE_CONSTANT (c) = 0; /* safe side */
+
+ return c;
+}
+
/* Return a new REAL_CST node whose type is TYPE and value is D. */
tree
-build_real (type, d)
- tree type;
- REAL_VALUE_TYPE d;
+build_real (tree type, REAL_VALUE_TYPE d)
{
tree v;
REAL_VALUE_TYPE *dp;
@@ -491,21 +488,17 @@ build_real (type, d)
and whose value is the integer value of the INTEGER_CST node I. */
REAL_VALUE_TYPE
-real_value_from_int_cst (type, i)
- tree type ATTRIBUTE_UNUSED, i;
+real_value_from_int_cst (tree type, tree i)
{
REAL_VALUE_TYPE d;
/* Clear all bits of the real value type so that we can later do
bitwise comparisons to see if two values are the same. */
- memset ((char *) &d, 0, sizeof d);
+ memset (&d, 0, sizeof d);
- if (! TREE_UNSIGNED (TREE_TYPE (i)))
- REAL_VALUE_FROM_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i),
- TYPE_MODE (type));
- else
- REAL_VALUE_FROM_UNSIGNED_INT (d, TREE_INT_CST_LOW (i),
- TREE_INT_CST_HIGH (i), TYPE_MODE (type));
+ real_from_integer (&d, type ? TYPE_MODE (type) : VOIDmode,
+ TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i),
+ TREE_UNSIGNED (TREE_TYPE (i)));
return d;
}
@@ -513,9 +506,7 @@ real_value_from_int_cst (type, i)
representing the same value as a floating-point constant of type TYPE. */
tree
-build_real_from_int_cst (type, i)
- tree type;
- tree i;
+build_real_from_int_cst (tree type, tree i)
{
tree v;
int overflow = TREE_OVERFLOW (i);
@@ -532,9 +523,7 @@ build_real_from_int_cst (type, i)
The TREE_TYPE is not initialized. */
tree
-build_string (len, str)
- int len;
- const char *str;
+build_string (int len, const char *str)
{
tree s = make_node (STRING_CST);
@@ -550,9 +539,7 @@ build_string (len, str)
will be the type of the COMPLEX_CST; otherwise a new type will be made. */
tree
-build_complex (type, real, imag)
- tree type;
- tree real, imag;
+build_complex (tree type, tree real, tree imag)
{
tree t = make_node (COMPLEX_CST);
@@ -568,8 +555,7 @@ build_complex (type, real, imag)
/* Build a newly constructed TREE_VEC node of length LEN. */
tree
-make_tree_vec (len)
- int len;
+make_tree_vec (int len)
{
tree t;
int length = (len - 1) * sizeof (tree) + sizeof (struct tree_vec);
@@ -581,7 +567,7 @@ make_tree_vec (len)
t = ggc_alloc_tree (length);
- memset ((PTR) t, 0, length);
+ memset (t, 0, length);
TREE_SET_CODE (t, TREE_VEC);
TREE_VEC_LENGTH (t) = len;
@@ -592,8 +578,7 @@ make_tree_vec (len)
of zero. */
int
-integer_zerop (expr)
- tree expr;
+integer_zerop (tree expr)
{
STRIP_NOPS (expr);
@@ -610,8 +595,7 @@ integer_zerop (expr)
complex constant. */
int
-integer_onep (expr)
- tree expr;
+integer_onep (tree expr)
{
STRIP_NOPS (expr);
@@ -628,8 +612,7 @@ integer_onep (expr)
it contains. Likewise for the corresponding complex constant. */
int
-integer_all_onesp (expr)
- tree expr;
+integer_all_onesp (tree expr)
{
int prec;
int uns;
@@ -681,8 +664,7 @@ integer_all_onesp (expr)
one bit on). */
int
-integer_pow2p (expr)
- tree expr;
+integer_pow2p (tree expr)
{
int prec;
HOST_WIDE_INT high, low;
@@ -723,12 +705,28 @@ integer_pow2p (expr)
|| (low == 0 && (high & (high - 1)) == 0));
}
+/* Return 1 if EXPR is an integer constant other than zero or a
+ complex constant other than zero. */
+
+int
+integer_nonzerop (tree expr)
+{
+ STRIP_NOPS (expr);
+
+ return ((TREE_CODE (expr) == INTEGER_CST
+ && ! TREE_CONSTANT_OVERFLOW (expr)
+ && (TREE_INT_CST_LOW (expr) != 0
+ || TREE_INT_CST_HIGH (expr) != 0))
+ || (TREE_CODE (expr) == COMPLEX_CST
+ && (integer_nonzerop (TREE_REALPART (expr))
+ || integer_nonzerop (TREE_IMAGPART (expr)))));
+}
+
/* Return the power of two represented by a tree node known to be a
power of two. */
int
-tree_log2 (expr)
- tree expr;
+tree_log2 (tree expr)
{
int prec;
HOST_WIDE_INT high, low;
@@ -766,8 +764,7 @@ tree_log2 (expr)
than or equal to EXPR. */
int
-tree_floor_log2 (expr)
- tree expr;
+tree_floor_log2 (tree expr)
{
int prec;
HOST_WIDE_INT high, low;
@@ -805,8 +802,7 @@ tree_floor_log2 (expr)
/* Return 1 if EXPR is the real constant zero. */
int
-real_zerop (expr)
- tree expr;
+real_zerop (tree expr)
{
STRIP_NOPS (expr);
@@ -821,8 +817,7 @@ real_zerop (expr)
/* Return 1 if EXPR is the real constant one in real or complex form. */
int
-real_onep (expr)
- tree expr;
+real_onep (tree expr)
{
STRIP_NOPS (expr);
@@ -837,8 +832,7 @@ real_onep (expr)
/* Return 1 if EXPR is the real constant two. */
int
-real_twop (expr)
- tree expr;
+real_twop (tree expr)
{
STRIP_NOPS (expr);
@@ -853,8 +847,7 @@ real_twop (expr)
/* Return 1 if EXPR is the real constant minus one. */
int
-real_minus_onep (expr)
- tree expr;
+real_minus_onep (tree expr)
{
STRIP_NOPS (expr);
@@ -869,8 +862,7 @@ real_minus_onep (expr)
/* Nonzero if EXP is a constant or a cast of a constant. */
int
-really_constant_p (exp)
- tree exp;
+really_constant_p (tree exp)
{
/* This is not quite the same as STRIP_NOPS. It does more. */
while (TREE_CODE (exp) == NOP_EXPR
@@ -884,8 +876,7 @@ really_constant_p (exp)
Return 0 if ELEM is not in LIST. */
tree
-value_member (elem, list)
- tree elem, list;
+value_member (tree elem, tree list)
{
while (list)
{
@@ -900,8 +891,7 @@ value_member (elem, list)
Return 0 if ELEM is not in LIST. */
tree
-purpose_member (elem, list)
- tree elem, list;
+purpose_member (tree elem, tree list)
{
while (list)
{
@@ -916,8 +906,7 @@ purpose_member (elem, list)
Return 0 if ELEM is not in LIST. */
tree
-binfo_member (elem, list)
- tree elem, list;
+binfo_member (tree elem, tree list)
{
while (list)
{
@@ -931,8 +920,7 @@ binfo_member (elem, list)
/* Return nonzero if ELEM is part of the chain CHAIN. */
int
-chain_member (elem, chain)
- tree elem, chain;
+chain_member (tree elem, tree chain)
{
while (chain)
{
@@ -944,48 +932,12 @@ chain_member (elem, chain)
return 0;
}
-/* Return nonzero if ELEM is equal to TREE_VALUE (CHAIN) for any piece of
- chain CHAIN. This and the next function are currently unused, but
- are retained for completeness. */
-
-int
-chain_member_value (elem, chain)
- tree elem, chain;
-{
- while (chain)
- {
- if (elem == TREE_VALUE (chain))
- return 1;
- chain = TREE_CHAIN (chain);
- }
-
- return 0;
-}
-
-/* Return nonzero if ELEM is equal to TREE_PURPOSE (CHAIN)
- for any piece of chain CHAIN. */
-
-int
-chain_member_purpose (elem, chain)
- tree elem, chain;
-{
- while (chain)
- {
- if (elem == TREE_PURPOSE (chain))
- return 1;
- chain = TREE_CHAIN (chain);
- }
-
- return 0;
-}
-
/* Return the length of a chain of nodes chained through TREE_CHAIN.
We expect a null pointer to mark the end of the chain.
This is the Lisp primitive `length'. */
int
-list_length (t)
- tree t;
+list_length (tree t)
{
tree tail;
int len = 0;
@@ -999,8 +951,7 @@ list_length (t)
/* Returns the number of FIELD_DECLs in TYPE. */
int
-fields_length (type)
- tree type;
+fields_length (tree type)
{
tree t = TYPE_FIELDS (type);
int count = 0;
@@ -1017,36 +968,35 @@ fields_length (type)
This is the Lisp primitive `nconc'. */
tree
-chainon (op1, op2)
- tree op1, op2;
+chainon (tree op1, tree op2)
{
+ tree t1;
- if (op1)
- {
- tree t1;
-#ifdef ENABLE_TREE_CHECKING
- tree t2;
-#endif
+ if (!op1)
+ return op2;
+ if (!op2)
+ return op1;
+
+ for (t1 = op1; TREE_CHAIN (t1); t1 = TREE_CHAIN (t1))
+ continue;
+ TREE_CHAIN (t1) = op2;
- for (t1 = op1; TREE_CHAIN (t1); t1 = TREE_CHAIN (t1))
- ;
- TREE_CHAIN (t1) = op2;
#ifdef ENABLE_TREE_CHECKING
- for (t2 = op2; t2; t2 = TREE_CHAIN (t2))
- if (t2 == t1)
- abort (); /* Circularity created. */
+ {
+ tree t2;
+ for (t2 = op2; t2; t2 = TREE_CHAIN (t2))
+ if (t2 == t1)
+ abort (); /* Circularity created. */
+ }
#endif
- return op1;
- }
- else
- return op2;
+
+ return op1;
}
/* Return the last node in a chain of nodes (chained through TREE_CHAIN). */
tree
-tree_last (chain)
- tree chain;
+tree_last (tree chain)
{
tree next;
if (chain)
@@ -1059,8 +1009,7 @@ tree_last (chain)
and return the new head of the chain (old last element). */
tree
-nreverse (t)
- tree t;
+nreverse (tree t)
{
tree prev = 0, decl, next;
for (decl = t; decl; decl = next)
@@ -1071,38 +1020,12 @@ nreverse (t)
}
return prev;
}
-
-/* Given a chain CHAIN of tree nodes,
- construct and return a list of those nodes. */
-
-tree
-listify (chain)
- tree chain;
-{
- tree result = NULL_TREE;
- tree in_tail = chain;
- tree out_tail = NULL_TREE;
-
- while (in_tail)
- {
- tree next = tree_cons (NULL_TREE, in_tail, NULL_TREE);
- if (out_tail)
- TREE_CHAIN (out_tail) = next;
- else
- result = next;
- out_tail = next;
- in_tail = TREE_CHAIN (in_tail);
- }
-
- return result;
-}
/* Return a newly created TREE_LIST node whose
purpose and value fields are PARM and VALUE. */
tree
-build_tree_list (parm, value)
- tree parm, value;
+build_tree_list (tree parm, tree value)
{
tree t = make_node (TREE_LIST);
TREE_PURPOSE (t) = parm;
@@ -1111,12 +1034,11 @@ build_tree_list (parm, value)
}
/* Return a newly created TREE_LIST node whose
- purpose and value fields are PARM and VALUE
+ purpose and value fields are PURPOSE and VALUE
and whose TREE_CHAIN is CHAIN. */
tree
-tree_cons (purpose, value, chain)
- tree purpose, value, chain;
+tree_cons (tree purpose, tree value, tree chain)
{
tree node;
@@ -1136,6 +1058,44 @@ tree_cons (purpose, value, chain)
return node;
}
+/* Return the first expression in a sequence of COMPOUND_EXPRs. */
+
+tree
+expr_first (tree expr)
+{
+ if (expr == NULL_TREE)
+ return expr;
+ while (TREE_CODE (expr) == COMPOUND_EXPR)
+ expr = TREE_OPERAND (expr, 0);
+ return expr;
+}
+
+/* Return the last expression in a sequence of COMPOUND_EXPRs. */
+
+tree
+expr_last (tree expr)
+{
+ if (expr == NULL_TREE)
+ return expr;
+ while (TREE_CODE (expr) == COMPOUND_EXPR)
+ expr = TREE_OPERAND (expr, 1);
+ return expr;
+}
+
+/* Return the number of subexpressions in a sequence of COMPOUND_EXPRs. */
+
+int
+expr_length (tree expr)
+{
+ int len = 0;
+
+ if (expr == NULL_TREE)
+ return 0;
+ for (; TREE_CODE (expr) == COMPOUND_EXPR; expr = TREE_OPERAND (expr, 1))
+ len += expr_length (TREE_OPERAND (expr, 0));
+ ++len;
+ return len;
+}
/* Return the size nominally occupied by an object of type TYPE
when it resides in memory. The value is measured in units of bytes,
@@ -1144,8 +1104,7 @@ tree_cons (purpose, value, chain)
make_unsigned_type). */
tree
-size_in_bytes (type)
- tree type;
+size_in_bytes (tree type)
{
tree t;
@@ -1171,8 +1130,7 @@ size_in_bytes (type)
or return -1 if the size can vary or is larger than an integer. */
HOST_WIDE_INT
-int_size_in_bytes (type)
- tree type;
+int_size_in_bytes (tree type)
{
tree t;
@@ -1196,10 +1154,8 @@ int_size_in_bytes (type)
This is a tree of type bitsizetype. */
tree
-bit_position (field)
- tree field;
+bit_position (tree field)
{
-
return bit_from_pos (DECL_FIELD_OFFSET (field),
DECL_FIELD_BIT_OFFSET (field));
}
@@ -1209,8 +1165,7 @@ bit_position (field)
of returning -1 like int_size_in_byte can. */
HOST_WIDE_INT
-int_bit_position (field)
- tree field;
+int_bit_position (tree field)
{
return tree_low_cst (bit_position (field), 0);
}
@@ -1219,8 +1174,7 @@ int_bit_position (field)
This is a tree of type sizetype. */
tree
-byte_position (field)
- tree field;
+byte_position (tree field)
{
return byte_from_pos (DECL_FIELD_OFFSET (field),
DECL_FIELD_BIT_OFFSET (field));
@@ -1231,8 +1185,7 @@ byte_position (field)
of returning -1 like int_size_in_byte can. */
HOST_WIDE_INT
-int_byte_position (field)
- tree field;
+int_byte_position (tree field)
{
return tree_low_cst (byte_position (field), 0);
}
@@ -1240,8 +1193,7 @@ int_byte_position (field)
/* Return the strictest alignment, in bits, that T is known to have. */
unsigned int
-expr_align (t)
- tree t;
+expr_align (tree t)
{
unsigned int align0, align1;
@@ -1288,8 +1240,7 @@ expr_align (t)
ARRAY_TYPE) minus one. This counts only elements of the top array. */
tree
-array_type_nelts (type)
- tree type;
+array_type_nelts (tree type)
{
tree index_type, min, max;
@@ -1311,8 +1262,7 @@ array_type_nelts (type)
static storage. This is not the same as the C meaning of `static'. */
int
-staticp (arg)
- tree arg;
+staticp (tree arg)
{
switch (TREE_CODE (arg))
{
@@ -1389,39 +1339,24 @@ staticp (arg)
are used for. */
tree
-save_expr (expr)
- tree expr;
+save_expr (tree expr)
{
tree t = fold (expr);
tree inner;
- /* We don't care about whether this can be used as an lvalue in this
- context. */
- while (TREE_CODE (t) == NON_LVALUE_EXPR)
- t = TREE_OPERAND (t, 0);
-
- /* If we have simple operations applied to a SAVE_EXPR or to a SAVE_EXPR and
- a constant, it will be more efficient to not make another SAVE_EXPR since
- it will allow better simplification and GCSE will be able to merge the
- computations if they actualy occur. */
- for (inner = t;
- (TREE_CODE_CLASS (TREE_CODE (inner)) == '1'
- || (TREE_CODE_CLASS (TREE_CODE (inner)) == '2'
- && TREE_CONSTANT (TREE_OPERAND (inner, 1))));
- inner = TREE_OPERAND (inner, 0))
- ;
-
/* If the tree evaluates to a constant, then we don't want to hide that
fact (i.e. this allows further folding, and direct checks for constants).
However, a read-only object that has side effects cannot be bypassed.
Since it is no problem to reevaluate literals, we just return the
literal node. */
+ inner = skip_simple_arithmetic (t);
if (TREE_CONSTANT (inner)
|| (TREE_READONLY (inner) && ! TREE_SIDE_EFFECTS (inner))
- || TREE_CODE (inner) == SAVE_EXPR || TREE_CODE (inner) == ERROR_MARK)
+ || TREE_CODE (inner) == SAVE_EXPR
+ || TREE_CODE (inner) == ERROR_MARK)
return t;
- /* If T contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
+ /* If INNER contains a PLACEHOLDER_EXPR, we must evaluate it each time, since
it means that the size or offset of some field of an object depends on
the value within another field.
@@ -1430,7 +1365,7 @@ save_expr (expr)
evaluated more than once. Front-ends must assure this case cannot
happen by surrounding any such subexpressions in their own SAVE_EXPR
and forcing evaluation at the proper time. */
- if (contains_placeholder_p (t))
+ if (contains_placeholder_p (inner))
return t;
t = build (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl, NULL_TREE);
@@ -1443,13 +1378,59 @@ save_expr (expr)
return t;
}
+/* Look inside EXPR and into any simple arithmetic operations. Return
+ the innermost non-arithmetic node. */
+
+tree
+skip_simple_arithmetic (tree expr)
+{
+ tree inner;
+
+ /* We don't care about whether this can be used as an lvalue in this
+ context. */
+ while (TREE_CODE (expr) == NON_LVALUE_EXPR)
+ expr = TREE_OPERAND (expr, 0);
+
+ /* If we have simple operations applied to a SAVE_EXPR or to a SAVE_EXPR and
+ a constant, it will be more efficient to not make another SAVE_EXPR since
+ it will allow better simplification and GCSE will be able to merge the
+ computations if they actually occur. */
+ inner = expr;
+ while (1)
+ {
+ if (TREE_CODE_CLASS (TREE_CODE (inner)) == '1')
+ inner = TREE_OPERAND (inner, 0);
+ else if (TREE_CODE_CLASS (TREE_CODE (inner)) == '2')
+ {
+ if (TREE_CONSTANT (TREE_OPERAND (inner, 1)))
+ inner = TREE_OPERAND (inner, 0);
+ else if (TREE_CONSTANT (TREE_OPERAND (inner, 0)))
+ inner = TREE_OPERAND (inner, 1);
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ return inner;
+}
+
+/* Return TRUE if EXPR is a SAVE_EXPR or wraps simple arithmetic around a
+ SAVE_EXPR. Return FALSE otherwise. */
+
+bool
+saved_expr_p (tree expr)
+{
+ return TREE_CODE (skip_simple_arithmetic (expr)) == SAVE_EXPR;
+}
+
/* Arrange for an expression to be expanded multiple independent
times. This is useful for cleanup actions, as the backend can
expand them multiple times in different places. */
tree
-unsave_expr (expr)
- tree expr;
+unsave_expr (tree expr)
{
tree t;
@@ -1466,8 +1447,7 @@ unsave_expr (expr)
of operands if all are trees. */
int
-first_rtl_op (code)
- enum tree_code code;
+first_rtl_op (enum tree_code code)
{
switch (code)
{
@@ -1478,8 +1458,6 @@ first_rtl_op (code)
return 0;
case WITH_CLEANUP_EXPR:
return 2;
- case METHOD_CALL_EXPR:
- return 3;
default:
return TREE_CODE_LENGTH (code);
}
@@ -1488,17 +1466,16 @@ first_rtl_op (code)
/* Return which tree structure is used by T. */
enum tree_node_structure_enum
-tree_node_structure (t)
- tree t;
+tree_node_structure (tree t)
{
enum tree_code code = TREE_CODE (t);
-
+
switch (TREE_CODE_CLASS (code))
{
case 'd': return TS_DECL;
case 't': return TS_TYPE;
case 'b': return TS_BLOCK;
- case 'r': case '<': case '1': case '2': case 'e': case 's':
+ case 'r': case '<': case '1': case '2': case 'e': case 's':
return TS_EXP;
default: /* 'c' and 'x' */
break;
@@ -1527,8 +1504,7 @@ tree_node_structure (t)
not recurse into EXPR's subtrees. */
void
-unsave_expr_1 (expr)
- tree expr;
+unsave_expr_1 (tree expr)
{
switch (TREE_CODE (expr))
{
@@ -1563,8 +1539,7 @@ unsave_expr_1 (expr)
/* Default lang hook for "unsave_expr_now". */
tree
-lhd_unsave_expr_now (expr)
- tree expr;
+lhd_unsave_expr_now (tree expr)
{
enum tree_code code;
@@ -1629,8 +1604,7 @@ lhd_unsave_expr_now (expr)
never possible to unsave them. */
int
-unsafe_for_reeval (expr)
- tree expr;
+unsafe_for_reeval (tree expr)
{
int unsafeness = 0;
enum tree_code code;
@@ -1648,6 +1622,7 @@ unsafe_for_reeval (expr)
{
case SAVE_EXPR:
case RTL_EXPR:
+ case TRY_CATCH_EXPR:
return 2;
case TREE_LIST:
@@ -1668,6 +1643,13 @@ unsafe_for_reeval (expr)
unsafeness = 1;
break;
+ case EXIT_BLOCK_EXPR:
+ /* EXIT_BLOCK_LABELED_BLOCK, a.k.a. TREE_OPERAND (expr, 0), holds
+ a reference to an ancestor LABELED_BLOCK, so we need to avoid
+ unbounded recursion in the 'e' traversal code below. */
+ exp = EXIT_BLOCK_RETURN (expr);
+ return exp ? unsafe_for_reeval (exp) : 0;
+
default:
tmp = (*lang_hooks.unsafe_for_reeval) (expr);
if (tmp >= 0)
@@ -1706,9 +1688,8 @@ unsafe_for_reeval (expr)
/* Return 1 if EXP contains a PLACEHOLDER_EXPR; i.e., if it represents a size
or offset that depends on a field within a record. */
-int
-contains_placeholder_p (exp)
- tree exp;
+bool
+contains_placeholder_p (tree exp)
{
enum tree_code code;
int result;
@@ -1731,13 +1712,12 @@ contains_placeholder_p (exp)
position computations since they will be converted into a
WITH_RECORD_EXPR involving the reference, which will assume
here will be valid. */
- return contains_placeholder_p (TREE_OPERAND (exp, 0));
+ return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
case 'x':
if (code == TREE_LIST)
- return (contains_placeholder_p (TREE_VALUE (exp))
- || (TREE_CHAIN (exp) != 0
- && contains_placeholder_p (TREE_CHAIN (exp))));
+ return (CONTAINS_PLACEHOLDER_P (TREE_VALUE (exp))
+ || CONTAINS_PLACEHOLDER_P (TREE_CHAIN (exp)));
break;
case '1':
@@ -1747,16 +1727,16 @@ contains_placeholder_p (exp)
{
case COMPOUND_EXPR:
/* Ignoring the first operand isn't quite right, but works best. */
- return contains_placeholder_p (TREE_OPERAND (exp, 1));
+ return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
case RTL_EXPR:
case CONSTRUCTOR:
return 0;
case COND_EXPR:
- return (contains_placeholder_p (TREE_OPERAND (exp, 0))
- || contains_placeholder_p (TREE_OPERAND (exp, 1))
- || contains_placeholder_p (TREE_OPERAND (exp, 2)));
+ return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
+ || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1))
+ || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 2)));
case SAVE_EXPR:
/* If we already know this doesn't have a placeholder, don't
@@ -1765,15 +1745,14 @@ contains_placeholder_p (exp)
return 0;
SAVE_EXPR_NOPLACEHOLDER (exp) = 1;
- result = contains_placeholder_p (TREE_OPERAND (exp, 0));
+ result = CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
if (result)
SAVE_EXPR_NOPLACEHOLDER (exp) = 0;
return result;
case CALL_EXPR:
- return (TREE_OPERAND (exp, 1) != 0
- && contains_placeholder_p (TREE_OPERAND (exp, 1)));
+ return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
default:
break;
@@ -1782,10 +1761,10 @@ contains_placeholder_p (exp)
switch (TREE_CODE_LENGTH (code))
{
case 1:
- return contains_placeholder_p (TREE_OPERAND (exp, 0));
+ return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
case 2:
- return (contains_placeholder_p (TREE_OPERAND (exp, 0))
- || contains_placeholder_p (TREE_OPERAND (exp, 1)));
+ return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
+ || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1)));
default:
return 0;
}
@@ -1796,12 +1775,113 @@ contains_placeholder_p (exp)
return 0;
}
+/* Return 1 if any part of the computation of TYPE involves a PLACEHOLDER_EXPR.
+ This includes size, bounds, qualifiers (for QUAL_UNION_TYPE) and field
+ positions. */
+
+bool
+type_contains_placeholder_p (tree type)
+{
+ /* If the size contains a placeholder or the parent type (component type in
+ the case of arrays) type involves a placeholder, this type does. */
+ if (CONTAINS_PLACEHOLDER_P (TYPE_SIZE (type))
+ || CONTAINS_PLACEHOLDER_P (TYPE_SIZE_UNIT (type))
+ || (TREE_TYPE (type) != 0
+ && type_contains_placeholder_p (TREE_TYPE (type))))
+ return 1;
+
+ /* Now do type-specific checks. Note that the last part of the check above
+ greatly limits what we have to do below. */
+ switch (TREE_CODE (type))
+ {
+ case VOID_TYPE:
+ case COMPLEX_TYPE:
+ case VECTOR_TYPE:
+ case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
+ case CHAR_TYPE:
+ case POINTER_TYPE:
+ case OFFSET_TYPE:
+ case REFERENCE_TYPE:
+ case METHOD_TYPE:
+ case FILE_TYPE:
+ case FUNCTION_TYPE:
+ return 0;
+
+ case INTEGER_TYPE:
+ case REAL_TYPE:
+ /* Here we just check the bounds. */
+ return (CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (type))
+ || CONTAINS_PLACEHOLDER_P (TYPE_MAX_VALUE (type)));
+
+ case ARRAY_TYPE:
+ case SET_TYPE:
+ /* We're already checked the component type (TREE_TYPE), so just check
+ the index type. */
+ return type_contains_placeholder_p (TYPE_DOMAIN (type));
+
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
+ {
+ static tree seen_types = 0;
+ tree field;
+ bool ret = 0;
+
+ /* We have to be careful here that we don't end up in infinite
+ recursions due to a field of a type being a pointer to that type
+ or to a mutually-recursive type. So we store a list of record
+ types that we've seen and see if this type is in them. To save
+ memory, we don't use a list for just one type. Here we check
+ whether we've seen this type before and store it if not. */
+ if (seen_types == 0)
+ seen_types = type;
+ else if (TREE_CODE (seen_types) != TREE_LIST)
+ {
+ if (seen_types == type)
+ return 0;
+
+ seen_types = tree_cons (NULL_TREE, type,
+ build_tree_list (NULL_TREE, seen_types));
+ }
+ else
+ {
+ if (value_member (type, seen_types) != 0)
+ return 0;
+
+ seen_types = tree_cons (NULL_TREE, type, seen_types);
+ }
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL
+ && (CONTAINS_PLACEHOLDER_P (DECL_FIELD_OFFSET (field))
+ || (TREE_CODE (type) == QUAL_UNION_TYPE
+ && CONTAINS_PLACEHOLDER_P (DECL_QUALIFIER (field)))
+ || type_contains_placeholder_p (TREE_TYPE (field))))
+ {
+ ret = true;
+ break;
+ }
+
+ /* Now remove us from seen_types and return the result. */
+ if (seen_types == type)
+ seen_types = 0;
+ else
+ seen_types = TREE_CHAIN (seen_types);
+
+ return ret;
+ }
+
+ default:
+ abort ();
+ }
+}
+
/* Return 1 if EXP contains any expressions that produce cleanups for an
outer scope to deal with. Used by fold. */
int
-has_cleanups (exp)
- tree exp;
+has_cleanups (tree exp)
{
int i, nops, cmp;
@@ -1862,10 +1942,7 @@ has_cleanups (exp)
PLACEHOLDER_EXPR occurring only in its arglist. */
tree
-substitute_in_expr (exp, f, r)
- tree exp;
- tree f;
- tree r;
+substitute_in_expr (tree exp, tree f, tree r)
{
enum tree_code code = TREE_CODE (exp);
tree op0, op1, op2;
@@ -1919,8 +1996,13 @@ substitute_in_expr (exp, f, r)
else if (code == CONSTRUCTOR)
abort ();
- op0 = substitute_in_expr (TREE_OPERAND (exp, 0), f, r);
- op1 = substitute_in_expr (TREE_OPERAND (exp, 1), f, r);
+ op0 = TREE_OPERAND (exp, 0);
+ op1 = TREE_OPERAND (exp, 1);
+ if (CONTAINS_PLACEHOLDER_P (op0))
+ op0 = substitute_in_expr (op0, f, r);
+ if (CONTAINS_PLACEHOLDER_P (op1))
+ op1 = substitute_in_expr (op1, f, r);
+
if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1))
return exp;
@@ -1946,9 +2028,17 @@ substitute_in_expr (exp, f, r)
else if (code != COND_EXPR)
abort ();
- op0 = substitute_in_expr (TREE_OPERAND (exp, 0), f, r);
- op1 = substitute_in_expr (TREE_OPERAND (exp, 1), f, r);
- op2 = substitute_in_expr (TREE_OPERAND (exp, 2), f, r);
+ op0 = TREE_OPERAND (exp, 0);
+ op1 = TREE_OPERAND (exp, 1);
+ op2 = TREE_OPERAND (exp, 2);
+
+ if (CONTAINS_PLACEHOLDER_P (op0))
+ op0 = substitute_in_expr (op0, f, r);
+ if (CONTAINS_PLACEHOLDER_P (op1))
+ op1 = substitute_in_expr (op1, f, r);
+ if (CONTAINS_PLACEHOLDER_P (op2))
+ op2 = substitute_in_expr (op2, f, r);
+
if (op0 == TREE_OPERAND (exp, 0) && op1 == TREE_OPERAND (exp, 1)
&& op2 == TREE_OPERAND (exp, 2))
return exp;
@@ -2032,8 +2122,7 @@ substitute_in_expr (exp, f, r)
Any other kind of expression is returned unchanged. */
tree
-stabilize_reference (ref)
- tree ref;
+stabilize_reference (tree ref)
{
tree result;
enum tree_code code = TREE_CODE (ref);
@@ -2130,8 +2219,7 @@ stabilize_reference (ref)
multiple utterances of the same expression should that prove fruitful. */
tree
-stabilize_reference_1 (e)
- tree e;
+stabilize_reference_1 (tree e)
{
tree result;
enum tree_code code = TREE_CODE (e);
@@ -2206,17 +2294,17 @@ stabilize_reference_1 (e)
Constants, decls, types and misc nodes cannot be. */
tree
-build VPARAMS ((enum tree_code code, tree tt, ...))
+build (enum tree_code code, tree tt, ...)
{
tree t;
int length;
int i;
int fro;
int constant;
+ va_list p;
+ tree node;
- VA_OPEN (p, tt);
- VA_FIXEDARG (p, enum tree_code, code);
- VA_FIXEDARG (p, tree, tt);
+ va_start (p, tt);
t = make_node (code);
length = TREE_CODE_LENGTH (code);
@@ -2293,9 +2381,27 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
}
}
}
- VA_CLOSE (p);
+ va_end (p);
TREE_CONSTANT (t) = constant;
+
+ if (code == CALL_EXPR && !TREE_SIDE_EFFECTS (t))
+ {
+ /* Calls have side-effects, except those to const or
+ pure functions. */
+ i = call_expr_flags (t);
+ if (!(i & (ECF_CONST | ECF_PURE)))
+ TREE_SIDE_EFFECTS (t) = 1;
+
+ /* And even those have side-effects if their arguments do. */
+ else for (node = TREE_OPERAND (t, 1); node; node = TREE_CHAIN (node))
+ if (TREE_SIDE_EFFECTS (TREE_VALUE (node)))
+ {
+ TREE_SIDE_EFFECTS (t) = 1;
+ break;
+ }
+ }
+
return t;
}
@@ -2304,22 +2410,30 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
of varargs, which is expensive for RISC machines. */
tree
-build1 (code, type, node)
- enum tree_code code;
- tree type;
- tree node;
+build1 (enum tree_code code, tree type, tree node)
{
- int length;
+ int length = sizeof (struct tree_exp);
#ifdef GATHER_STATISTICS
tree_node_kind kind;
#endif
tree t;
#ifdef GATHER_STATISTICS
- if (TREE_CODE_CLASS (code) == 'r')
- kind = r_kind;
- else
- kind = e_kind;
+ switch (TREE_CODE_CLASS (code))
+ {
+ case 's': /* an expression with side effects */
+ kind = s_kind;
+ break;
+ case 'r': /* a reference */
+ kind = r_kind;
+ break;
+ default:
+ kind = e_kind;
+ break;
+ }
+
+ tree_node_counts[(int) kind]++;
+ tree_node_sizes[(int) kind] += length;
#endif
#ifdef ENABLE_CHECKING
@@ -2329,16 +2443,9 @@ build1 (code, type, node)
abort ();
#endif /* ENABLE_CHECKING */
- length = sizeof (struct tree_exp);
-
t = ggc_alloc_tree (length);
- memset ((PTR) t, 0, sizeof (struct tree_common));
-
-#ifdef GATHER_STATISTICS
- tree_node_counts[(int) kind]++;
- tree_node_sizes[(int) kind] += length;
-#endif
+ memset (t, 0, sizeof (struct tree_common));
TREE_SET_CODE (t, code);
@@ -2351,7 +2458,9 @@ build1 (code, type, node)
TREE_READONLY (t) = TREE_READONLY (node);
}
- switch (code)
+ if (TREE_CODE_CLASS (code) == 's')
+ TREE_SIDE_EFFECTS (t) = 1;
+ else switch (code)
{
case INIT_EXPR:
case MODIFY_EXPR:
@@ -2373,6 +2482,29 @@ build1 (code, type, node)
TREE_READONLY (t) = 0;
break;
+ case ADDR_EXPR:
+ if (node)
+ {
+ /* The address of a volatile decl or reference does not have
+ side-effects. But be careful not to ignore side-effects from
+ other sources deeper in the expression--if node is a _REF and
+ one of its operands has side-effects, so do we. */
+ if (TREE_THIS_VOLATILE (node))
+ {
+ TREE_SIDE_EFFECTS (t) = 0;
+ if (!DECL_P (node))
+ {
+ int i = first_rtl_op (TREE_CODE (node)) - 1;
+ for (; i >= 0; --i)
+ {
+ if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, i)))
+ TREE_SIDE_EFFECTS (t) = 1;
+ }
+ }
+ }
+ }
+ break;
+
default:
if (TREE_CODE_CLASS (code) == '1' && node && TREE_CONSTANT (node))
TREE_CONSTANT (t) = 1;
@@ -2388,14 +2520,14 @@ build1 (code, type, node)
or even garbage if their values do not matter. */
tree
-build_nt VPARAMS ((enum tree_code code, ...))
+build_nt (enum tree_code code, ...)
{
tree t;
int length;
int i;
+ va_list p;
- VA_OPEN (p, code);
- VA_FIXEDARG (p, enum tree_code, code);
+ va_start (p, code);
t = make_node (code);
length = TREE_CODE_LENGTH (code);
@@ -2403,7 +2535,7 @@ build_nt VPARAMS ((enum tree_code code, ...))
for (i = 0; i < length; i++)
TREE_OPERAND (t, i) = va_arg (p, tree);
- VA_CLOSE (p);
+ va_end (p);
return t;
}
@@ -2414,9 +2546,7 @@ build_nt VPARAMS ((enum tree_code code, ...))
Other slots are initialized to 0 or null pointers. */
tree
-build_decl (code, name, type)
- enum tree_code code;
- tree name, type;
+build_decl (enum tree_code code, tree name, tree type)
{
tree t;
@@ -2443,8 +2573,8 @@ build_decl (code, name, type)
compiled. This information is used for outputting debugging info. */
tree
-build_block (vars, tags, subblocks, supercontext, chain)
- tree vars, tags ATTRIBUTE_UNUSED, subblocks, supercontext, chain;
+build_block (tree vars, tree tags ATTRIBUTE_UNUSED, tree subblocks,
+ tree supercontext, tree chain)
{
tree block = make_node (BLOCK);
@@ -2461,10 +2591,7 @@ build_block (vars, tags, subblocks, supercontext, chain)
recursively more than one file (Java is one of them). */
tree
-build_expr_wfl (node, file, line, col)
- tree node;
- const char *file;
- int line, col;
+build_expr_wfl (tree node, const char *file, int line, int col)
{
static const char *last_file = 0;
static tree last_filenode = NULL_TREE;
@@ -2492,8 +2619,7 @@ build_expr_wfl (node, file, line, col)
is ATTRIBUTE. */
tree
-build_decl_attribute_variant (ddecl, attribute)
- tree ddecl, attribute;
+build_decl_attribute_variant (tree ddecl, tree attribute)
{
DECL_ATTRIBUTES (ddecl) = attribute;
return ddecl;
@@ -2505,8 +2631,7 @@ build_decl_attribute_variant (ddecl, attribute)
Record such modified types already made so we don't make duplicates. */
tree
-build_type_attribute_variant (ttype, attribute)
- tree ttype, attribute;
+build_type_attribute_variant (tree ttype, tree attribute)
{
if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute))
{
@@ -2562,9 +2687,7 @@ build_type_attribute_variant (ttype, attribute)
their canonicalized form. */
int
-is_attribute_p (attr, ident)
- const char *attr;
- tree ident;
+is_attribute_p (const char *attr, tree ident)
{
int ident_len, attr_len;
const char *p;
@@ -2609,9 +2732,7 @@ is_attribute_p (attr, ident)
be passed back in if further occurrences are wanted. */
tree
-lookup_attribute (attr_name, list)
- const char *attr_name;
- tree list;
+lookup_attribute (const char *attr_name, tree list)
{
tree l;
@@ -2629,8 +2750,7 @@ lookup_attribute (attr_name, list)
/* Return an attribute list that is the union of a1 and a2. */
tree
-merge_attributes (a1, a2)
- tree a1, a2;
+merge_attributes (tree a1, tree a2)
{
tree attributes;
@@ -2680,8 +2800,7 @@ merge_attributes (a1, a2)
the result. */
tree
-merge_type_attributes (t1, t2)
- tree t1, t2;
+merge_type_attributes (tree t1, tree t2)
{
return merge_attributes (TYPE_ATTRIBUTES (t1),
TYPE_ATTRIBUTES (t2));
@@ -2691,8 +2810,7 @@ merge_type_attributes (t1, t2)
the result. */
tree
-merge_decl_attributes (olddecl, newdecl)
- tree olddecl, newdecl;
+merge_decl_attributes (tree olddecl, tree newdecl)
{
return merge_attributes (DECL_ATTRIBUTES (olddecl),
DECL_ATTRIBUTES (newdecl));
@@ -2710,9 +2828,7 @@ merge_decl_attributes (olddecl, newdecl)
The second instance of `foo' nullifies the dllimport. */
tree
-merge_dllimport_decl_attributes (old, new)
- tree old;
- tree new;
+merge_dllimport_decl_attributes (tree old, tree new)
{
tree a;
int delete_dllimport_p;
@@ -2759,9 +2875,7 @@ merge_dllimport_decl_attributes (old, new)
of the various TYPE_QUAL values. */
static void
-set_type_quals (type, type_quals)
- tree type;
- int type_quals;
+set_type_quals (tree type, int type_quals)
{
TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0;
TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
@@ -2773,9 +2887,7 @@ set_type_quals (type, type_quals)
return NULL_TREE. */
tree
-get_qualified_type (type, type_quals)
- tree type;
- int type_quals;
+get_qualified_type (tree type, int type_quals)
{
tree t;
@@ -2784,7 +2896,8 @@ get_qualified_type (type, type_quals)
preserve the TYPE_NAME, since there is code that depends on this. */
for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
if (TYPE_QUALS (t) == type_quals && TYPE_NAME (t) == TYPE_NAME (type)
- && TYPE_CONTEXT (t) == TYPE_CONTEXT (type))
+ && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
+ && attribute_list_equal (TYPE_ATTRIBUTES (t), TYPE_ATTRIBUTES (type)))
return t;
return NULL_TREE;
@@ -2794,9 +2907,7 @@ get_qualified_type (type, type_quals)
exist. This function never returns NULL_TREE. */
tree
-build_qualified_type (type, type_quals)
- tree type;
- int type_quals;
+build_qualified_type (tree type, int type_quals)
{
tree t;
@@ -2817,8 +2928,7 @@ build_qualified_type (type, type_quals)
This is so the caller can modify it. */
tree
-build_type_copy (type)
- tree type;
+build_type_copy (tree type)
{
tree t, m = TYPE_MAIN_VARIANT (type);
@@ -2842,8 +2952,7 @@ build_type_copy (type)
of the individual types. */
unsigned int
-type_hash_list (list)
- tree list;
+type_hash_list (tree list)
{
unsigned int hashcode;
tree tail;
@@ -2859,9 +2968,7 @@ type_hash_list (list)
/* Returns true if the types are equal. */
static int
-type_hash_eq (va, vb)
- const void *va;
- const void *vb;
+type_hash_eq (const void *va, const void *vb)
{
const struct type_hash *a = va, *b = vb;
if (a->hash == b->hash
@@ -2891,8 +2998,7 @@ type_hash_eq (va, vb)
/* Return the cached hash value. */
static hashval_t
-type_hash_hash (item)
- const void *item;
+type_hash_hash (const void *item)
{
return ((const struct type_hash *) item)->hash;
}
@@ -2901,9 +3007,7 @@ type_hash_hash (item)
If one is found, return it. Otherwise return 0. */
tree
-type_hash_lookup (hashcode, type)
- unsigned int hashcode;
- tree type;
+type_hash_lookup (unsigned int hashcode, tree type)
{
struct type_hash *h, in;
@@ -2924,14 +3028,12 @@ type_hash_lookup (hashcode, type)
for a type TYPE whose hash code is HASHCODE. */
void
-type_hash_add (hashcode, type)
- unsigned int hashcode;
- tree type;
+type_hash_add (unsigned int hashcode, tree type)
{
struct type_hash *h;
void **loc;
- h = (struct type_hash *) ggc_alloc (sizeof (struct type_hash));
+ h = ggc_alloc (sizeof (struct type_hash));
h->hash = hashcode;
h->type = type;
loc = htab_find_slot_with_hash (type_hash_table, h, hashcode, INSERT);
@@ -2953,9 +3055,7 @@ type_hash_add (hashcode, type)
int debug_no_type_hash = 0;
tree
-type_hash_canon (hashcode, type)
- unsigned int hashcode;
- tree type;
+type_hash_canon (unsigned int hashcode, tree type)
{
tree t1;
@@ -2987,8 +3087,7 @@ type_hash_canon (hashcode, type)
the number of garbage collections. */
static int
-type_hash_marked_p (p)
- const void *p;
+type_hash_marked_p (const void *p)
{
tree type = ((struct type_hash *) p)->type;
@@ -2996,7 +3095,7 @@ type_hash_marked_p (p)
}
static void
-print_type_hash_statistics ()
+print_type_hash_statistics (void)
{
fprintf (stderr, "Type hash: size %ld, %ld elements, %f collisions\n",
(long) htab_size (type_hash_table),
@@ -3009,8 +3108,7 @@ print_type_hash_statistics ()
by adding the hash codes of the individual attributes. */
unsigned int
-attribute_hash_list (list)
- tree list;
+attribute_hash_list (tree list)
{
unsigned int hashcode;
tree tail;
@@ -3025,8 +3123,7 @@ attribute_hash_list (list)
equivalent to l1. */
int
-attribute_list_equal (l1, l2)
- tree l1, l2;
+attribute_list_equal (tree l1, tree l2)
{
return attribute_list_contained (l1, l2)
&& attribute_list_contained (l2, l1);
@@ -3041,8 +3138,7 @@ attribute_list_equal (l1, l2)
correctly. */
int
-attribute_list_contained (l1, l2)
- tree l1, l2;
+attribute_list_contained (tree l1, tree l2)
{
tree t1, t2;
@@ -3089,8 +3185,7 @@ attribute_list_contained (l1, l2)
Also, the TREE_PURPOSEs must match. */
int
-type_list_equal (l1, l2)
- tree l1, l2;
+type_list_equal (tree l1, tree l2)
{
tree t1, t2;
@@ -3110,8 +3205,7 @@ type_list_equal (l1, l2)
then this function counts only the ordinary arguments. */
int
-type_num_arguments (type)
- tree type;
+type_num_arguments (tree type)
{
int i = 0;
tree t;
@@ -3131,8 +3225,7 @@ type_num_arguments (type)
represent the same constant value. */
int
-tree_int_cst_equal (t1, t2)
- tree t1, t2;
+tree_int_cst_equal (tree t1, tree t2)
{
if (t1 == t2)
return 1;
@@ -3153,8 +3246,7 @@ tree_int_cst_equal (t1, t2)
The precise way of comparison depends on their data type. */
int
-tree_int_cst_lt (t1, t2)
- tree t1, t2;
+tree_int_cst_lt (tree t1, tree t2)
{
if (t1 == t2)
return 0;
@@ -3181,9 +3273,7 @@ tree_int_cst_lt (t1, t2)
/* Returns -1 if T1 < T2, 0 if T1 == T2, and 1 if T1 > T2. */
int
-tree_int_cst_compare (t1, t2)
- tree t1;
- tree t2;
+tree_int_cst_compare (tree t1, tree t2)
{
if (tree_int_cst_lt (t1, t2))
return -1;
@@ -3199,9 +3289,7 @@ tree_int_cst_compare (t1, t2)
be represented in a single unsigned HOST_WIDE_INT. */
int
-host_integerp (t, pos)
- tree t;
- int pos;
+host_integerp (tree t, int pos)
{
return (TREE_CODE (t) == INTEGER_CST
&& ! TREE_OVERFLOW (t)
@@ -3218,9 +3306,7 @@ host_integerp (t, pos)
be positive. Abort if we cannot satisfy the above conditions. */
HOST_WIDE_INT
-tree_low_cst (t, pos)
- tree t;
- int pos;
+tree_low_cst (tree t, int pos)
{
if (host_integerp (t, pos))
return TREE_INT_CST_LOW (t);
@@ -3231,8 +3317,7 @@ tree_low_cst (t, pos)
/* Return the most significant bit of the integer constant T. */
int
-tree_int_cst_msb (t)
- tree t;
+tree_int_cst_msb (tree t)
{
int prec;
HOST_WIDE_INT h;
@@ -3251,8 +3336,7 @@ tree_int_cst_msb (t)
Note that -1 will never be returned it T's type is unsigned. */
int
-tree_int_cst_sgn (t)
- tree t;
+tree_int_cst_sgn (tree t)
{
if (TREE_INT_CST_LOW (t) == 0 && TREE_INT_CST_HIGH (t) == 0)
return 0;
@@ -3268,8 +3352,7 @@ tree_int_cst_sgn (t)
are known to be equal; otherwise return 0. */
int
-simple_cst_list_equal (l1, l2)
- tree l1, l2;
+simple_cst_list_equal (tree l1, tree l2)
{
while (l1 != NULL_TREE && l2 != NULL_TREE)
{
@@ -3290,8 +3373,7 @@ simple_cst_list_equal (l1, l2)
this function. */
int
-simple_cst_equal (t1, t2)
- tree t1, t2;
+simple_cst_equal (tree t1, tree t2)
{
enum tree_code code1, code2;
int cmp;
@@ -3429,9 +3511,7 @@ simple_cst_equal (t1, t2)
than U, respectively. */
int
-compare_tree_int (t, u)
- tree t;
- unsigned HOST_WIDE_INT u;
+compare_tree_int (tree t, unsigned HOST_WIDE_INT u)
{
if (tree_int_cst_sgn (t) < 0)
return -1;
@@ -3444,31 +3524,123 @@ compare_tree_int (t, u)
else
return 1;
}
+
+/* Generate a hash value for an expression. This can be used iteratively
+ by passing a previous result as the "val" argument.
+
+ This function is intended to produce the same hash for expressions which
+ would compare equal using operand_equal_p. */
+
+hashval_t
+iterative_hash_expr (tree t, hashval_t val)
+{
+ int i;
+ enum tree_code code;
+ char class;
+
+ if (t == NULL_TREE)
+ return iterative_hash_object (t, val);
+
+ code = TREE_CODE (t);
+ class = TREE_CODE_CLASS (code);
+
+ if (class == 'd')
+ {
+ /* Decls we can just compare by pointer. */
+ val = iterative_hash_object (t, val);
+ }
+ else if (class == 'c')
+ {
+ /* Alas, constants aren't shared, so we can't rely on pointer
+ identity. */
+ if (code == INTEGER_CST)
+ {
+ val = iterative_hash_object (TREE_INT_CST_LOW (t), val);
+ val = iterative_hash_object (TREE_INT_CST_HIGH (t), val);
+ }
+ else if (code == REAL_CST)
+ val = iterative_hash (TREE_REAL_CST_PTR (t),
+ sizeof (REAL_VALUE_TYPE), val);
+ else if (code == STRING_CST)
+ val = iterative_hash (TREE_STRING_POINTER (t),
+ TREE_STRING_LENGTH (t), val);
+ else if (code == COMPLEX_CST)
+ {
+ val = iterative_hash_expr (TREE_REALPART (t), val);
+ val = iterative_hash_expr (TREE_IMAGPART (t), val);
+ }
+ else if (code == VECTOR_CST)
+ val = iterative_hash_expr (TREE_VECTOR_CST_ELTS (t), val);
+ else
+ abort ();
+ }
+ else if (IS_EXPR_CODE_CLASS (class))
+ {
+ val = iterative_hash_object (code, val);
+
+ if (code == NOP_EXPR || code == CONVERT_EXPR
+ || code == NON_LVALUE_EXPR)
+ val = iterative_hash_object (TREE_TYPE (t), val);
+
+ if (code == PLUS_EXPR || code == MULT_EXPR || code == MIN_EXPR
+ || code == MAX_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR
+ || code == BIT_AND_EXPR || code == NE_EXPR || code == EQ_EXPR)
+ {
+ /* It's a commutative expression. We want to hash it the same
+ however it appears. We do this by first hashing both operands
+ and then rehashing based on the order of their independent
+ hashes. */
+ hashval_t one = iterative_hash_expr (TREE_OPERAND (t, 0), 0);
+ hashval_t two = iterative_hash_expr (TREE_OPERAND (t, 1), 0);
+ hashval_t t;
+
+ if (one > two)
+ t = one, one = two, two = t;
+
+ val = iterative_hash_object (one, val);
+ val = iterative_hash_object (two, val);
+ }
+ else
+ for (i = first_rtl_op (code) - 1; i >= 0; --i)
+ val = iterative_hash_expr (TREE_OPERAND (t, i), val);
+ }
+ else if (code == TREE_LIST)
+ {
+ /* A list of expressions, for a CALL_EXPR or as the elements of a
+ VECTOR_CST. */
+ for (; t; t = TREE_CHAIN (t))
+ val = iterative_hash_expr (TREE_VALUE (t), val);
+ }
+ else
+ abort ();
+
+ return val;
+}
/* Constructors for pointer, array and function types.
(RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are
constructed by language-dependent code, not here.) */
-/* Construct, lay out and return the type of pointers to TO_TYPE.
- If such a type has already been constructed, reuse it. */
+/* Construct, lay out and return the type of pointers to TO_TYPE
+ with mode MODE. If such a type has already been constructed,
+ reuse it. */
tree
-build_pointer_type (to_type)
- tree to_type;
+build_pointer_type_for_mode (tree to_type, enum machine_mode mode)
{
tree t = TYPE_POINTER_TO (to_type);
/* First, if we already have a type for pointers to TO_TYPE, use it. */
-
- if (t != 0)
+ if (t != 0 && mode == ptr_mode)
return t;
- /* We need a new one. */
t = make_node (POINTER_TYPE);
TREE_TYPE (t) = to_type;
+ TYPE_MODE (t) = mode;
/* Record this type as the pointer to TO_TYPE. */
+ if (mode == ptr_mode)
TYPE_POINTER_TO (to_type) = t;
/* Lay out the type. This function has many callers that are concerned
@@ -3479,25 +3651,34 @@ build_pointer_type (to_type)
return t;
}
-/* Build the node for the type of references-to-TO_TYPE. */
+/* By default build pointers in ptr_mode. */
tree
-build_reference_type (to_type)
- tree to_type;
+build_pointer_type (tree to_type)
+{
+ return build_pointer_type_for_mode (to_type, ptr_mode);
+}
+
+/* Construct, lay out and return the type of references to TO_TYPE
+ with mode MODE. If such a type has already been constructed,
+ reuse it. */
+
+tree
+build_reference_type_for_mode (tree to_type, enum machine_mode mode)
{
tree t = TYPE_REFERENCE_TO (to_type);
/* First, if we already have a type for pointers to TO_TYPE, use it. */
-
- if (t)
+ if (t != 0 && mode == ptr_mode)
return t;
- /* We need a new one. */
t = make_node (REFERENCE_TYPE);
TREE_TYPE (t) = to_type;
+ TYPE_MODE (t) = mode;
/* Record this type as the pointer to TO_TYPE. */
+ if (mode == ptr_mode)
TYPE_REFERENCE_TO (to_type) = t;
layout_type (t);
@@ -3505,14 +3686,23 @@ build_reference_type (to_type)
return t;
}
+
+/* Build the node for the type of references-to-TO_TYPE by default
+ in ptr_mode. */
+
+tree
+build_reference_type (tree to_type)
+{
+ return build_reference_type_for_mode (to_type, ptr_mode);
+}
+
/* Build a type that is compatible with t but has no cv quals anywhere
in its type, thus
const char *const *const * -> char ***. */
tree
-build_type_no_quals (t)
- tree t;
+build_type_no_quals (tree t)
{
switch (TREE_CODE (t))
{
@@ -3535,8 +3725,7 @@ build_type_no_quals (t)
sizes that use more than one HOST_WIDE_INT. */
tree
-build_index_type (maxval)
- tree maxval;
+build_index_type (tree maxval)
{
tree itype = make_node (INTEGER_TYPE);
@@ -3562,8 +3751,7 @@ build_index_type (maxval)
if TYPE==NULL_TREE, sizetype is used. */
tree
-build_range_type (type, lowval, highval)
- tree type, lowval, highval;
+build_range_type (tree type, tree lowval, tree highval)
{
tree itype = make_node (INTEGER_TYPE);
@@ -3593,49 +3781,17 @@ build_range_type (type, lowval, highval)
of just highval (maxval). */
tree
-build_index_2_type (lowval, highval)
- tree lowval, highval;
+build_index_2_type (tree lowval, tree highval)
{
return build_range_type (sizetype, lowval, highval);
}
-/* Return nonzero iff ITYPE1 and ITYPE2 are equal (in the LISP sense).
- Needed because when index types are not hashed, equal index types
- built at different times appear distinct, even though structurally,
- they are not. */
-
-int
-index_type_equal (itype1, itype2)
- tree itype1, itype2;
-{
- if (TREE_CODE (itype1) != TREE_CODE (itype2))
- return 0;
-
- if (TREE_CODE (itype1) == INTEGER_TYPE)
- {
- if (TYPE_PRECISION (itype1) != TYPE_PRECISION (itype2)
- || TYPE_MODE (itype1) != TYPE_MODE (itype2)
- || simple_cst_equal (TYPE_SIZE (itype1), TYPE_SIZE (itype2)) != 1
- || TYPE_ALIGN (itype1) != TYPE_ALIGN (itype2))
- return 0;
-
- if (1 == simple_cst_equal (TYPE_MIN_VALUE (itype1),
- TYPE_MIN_VALUE (itype2))
- && 1 == simple_cst_equal (TYPE_MAX_VALUE (itype1),
- TYPE_MAX_VALUE (itype2)))
- return 1;
- }
-
- return 0;
-}
-
/* Construct, lay out and return the type of arrays of elements with ELT_TYPE
and number of elements specified by the range of values of INDEX_TYPE.
If such a type has already been constructed, reuse it. */
tree
-build_array_type (elt_type, index_type)
- tree elt_type, index_type;
+build_array_type (tree elt_type, tree index_type)
{
tree t;
unsigned int hashcode;
@@ -3672,8 +3828,7 @@ build_array_type (elt_type, index_type)
the innermost dimension of ARRAY. */
tree
-get_inner_array_type (array)
- tree array;
+get_inner_array_type (tree array)
{
tree type = TREE_TYPE (array);
@@ -3691,8 +3846,7 @@ get_inner_array_type (array)
If such a type has already been constructed, reuse it. */
tree
-build_function_type (value_type, arg_types)
- tree value_type, arg_types;
+build_function_type (tree value_type, tree arg_types)
{
tree t;
unsigned int hashcode;
@@ -3717,18 +3871,18 @@ build_function_type (value_type, arg_types)
return t;
}
-/* Build a function type. The RETURN_TYPE is the type retured by the
+/* Build a function type. The RETURN_TYPE is the type returned by the
function. If additional arguments are provided, they are
additional argument types. The list of argument types must always
be terminated by NULL_TREE. */
tree
-build_function_type_list VPARAMS ((tree return_type, ...))
+build_function_type_list (tree return_type, ...)
{
tree t, args, last;
+ va_list p;
- VA_OPEN (p, return_type);
- VA_FIXEDARG (p, tree, return_type);
+ va_start (p, return_type);
t = va_arg (p, tree);
for (args = NULL_TREE; t != NULL_TREE; t = va_arg (p, tree))
@@ -3739,40 +3893,41 @@ build_function_type_list VPARAMS ((tree return_type, ...))
TREE_CHAIN (last) = void_list_node;
args = build_function_type (return_type, args);
- VA_CLOSE (p);
+ va_end (p);
return args;
}
-/* Construct, lay out and return the type of methods belonging to class
- BASETYPE and whose arguments and values are described by TYPE.
- If that type exists already, reuse it.
- TYPE must be a FUNCTION_TYPE node. */
+/* Build a METHOD_TYPE for a member of BASETYPE. The RETTYPE (a TYPE)
+ and ARGTYPES (a TREE_LIST) are the return type and arguments types
+ for the method. An implicit additional parameter (of type
+ pointer-to-BASETYPE) is added to the ARGTYPES. */
tree
-build_method_type (basetype, type)
- tree basetype, type;
+build_method_type_directly (tree basetype,
+ tree rettype,
+ tree argtypes)
{
tree t;
- unsigned int hashcode;
+ tree ptype;
+ int hashcode;
/* Make a node of the sort we want. */
t = make_node (METHOD_TYPE);
- if (TREE_CODE (type) != FUNCTION_TYPE)
- abort ();
-
TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype);
- TREE_TYPE (t) = TREE_TYPE (type);
+ TREE_TYPE (t) = rettype;
+ ptype = build_pointer_type (basetype);
/* The actual arglist for this function includes a "hidden" argument
which is "this". Put it into the list of argument types. */
+ argtypes = tree_cons (NULL_TREE, ptype, argtypes);
+ TYPE_ARG_TYPES (t) = argtypes;
- TYPE_ARG_TYPES (t)
- = tree_cons (NULL_TREE,
- build_pointer_type (basetype), TYPE_ARG_TYPES (type));
+ /* If we already have such a type, use the old one and free this one.
+ Note that it also frees up the above cons cell if found. */
+ hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) +
+ type_hash_list (argtypes);
- /* If we already have such a type, use the old one and free this one. */
- hashcode = TYPE_HASH (basetype) + TYPE_HASH (type);
t = type_hash_canon (hashcode, t);
if (!COMPLETE_TYPE_P (t))
@@ -3781,13 +3936,28 @@ build_method_type (basetype, type)
return t;
}
+/* Construct, lay out and return the type of methods belonging to class
+ BASETYPE and whose arguments and values are described by TYPE.
+ If that type exists already, reuse it.
+ TYPE must be a FUNCTION_TYPE node. */
+
+tree
+build_method_type (tree basetype, tree type)
+{
+ if (TREE_CODE (type) != FUNCTION_TYPE)
+ abort ();
+
+ return build_method_type_directly (basetype,
+ TREE_TYPE (type),
+ TYPE_ARG_TYPES (type));
+}
+
/* Construct, lay out and return the type of offsets to a value
of type TYPE, within an object of type BASETYPE.
If a suitable offset type exists already, reuse it. */
tree
-build_offset_type (basetype, type)
- tree basetype, type;
+build_offset_type (tree basetype, tree type)
{
tree t;
unsigned int hashcode;
@@ -3811,8 +3981,7 @@ build_offset_type (basetype, type)
/* Create a complex type whose components are COMPONENT_TYPE. */
tree
-build_complex_type (component_type)
- tree component_type;
+build_complex_type (tree component_type)
{
tree t;
unsigned int hashcode;
@@ -3892,9 +4061,7 @@ build_complex_type (component_type)
is different from (int) OP. */
tree
-get_unwidened (op, for_type)
- tree op;
- tree for_type;
+get_unwidened (tree op, tree for_type)
{
/* Set UNS initially if converting OP to FOR_TYPE is a zero-extension. */
tree type = TREE_TYPE (op);
@@ -3954,7 +4121,8 @@ get_unwidened (op, for_type)
{
unsigned int innerprec
= tree_low_cst (DECL_SIZE (TREE_OPERAND (op, 1)), 1);
- int unsignedp = TREE_UNSIGNED (TREE_OPERAND (op, 1));
+ int unsignedp = (TREE_UNSIGNED (TREE_OPERAND (op, 1))
+ || TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 1))));
type = (*lang_hooks.types.type_for_size) (innerprec, unsignedp);
/* We can get this structure field in the narrowest type it fits in.
@@ -3963,10 +4131,10 @@ get_unwidened (op, for_type)
The resulting extension to its nominal type (a fullword type)
must fit the same conditions as for other extensions. */
- if (innerprec < TYPE_PRECISION (TREE_TYPE (op))
+ if (type != 0
+ && INT_CST_LT_UNSIGNED (TYPE_SIZE (type), TYPE_SIZE (TREE_TYPE (op)))
&& (for_type || ! DECL_BIT_FIELD (TREE_OPERAND (op, 1)))
- && (! uns || final_prec <= innerprec || unsignedp)
- && type != 0)
+ && (! uns || final_prec <= innerprec || unsignedp))
{
win = build (COMPONENT_REF, type, TREE_OPERAND (op, 0),
TREE_OPERAND (op, 1));
@@ -3984,9 +4152,7 @@ get_unwidened (op, for_type)
or 0 if the value should be sign-extended. */
tree
-get_narrower (op, unsignedp_ptr)
- tree op;
- int *unsignedp_ptr;
+get_narrower (tree op, int *unsignedp_ptr)
{
int uns = 0;
int first = 1;
@@ -4040,8 +4206,9 @@ get_narrower (op, unsignedp_ptr)
{
unsigned HOST_WIDE_INT innerprec
= tree_low_cst (DECL_SIZE (TREE_OPERAND (op, 1)), 1);
- tree type = (*lang_hooks.types.type_for_size) (innerprec,
- TREE_UNSIGNED (op));
+ int unsignedp = (TREE_UNSIGNED (TREE_OPERAND (op, 1))
+ || TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 1))));
+ tree type = (*lang_hooks.types.type_for_size) (innerprec, unsignedp);
/* We can get this structure field in a narrower type that fits it,
but the resulting extension to its nominal type (a fullword type)
@@ -4072,32 +4239,60 @@ get_narrower (op, unsignedp_ptr)
for type TYPE (an INTEGER_TYPE). */
int
-int_fits_type_p (c, type)
- tree c, type;
-{
- /* If the bounds of the type are integers, we can check ourselves.
- If not, but this type is a subtype, try checking against that.
- Otherwise, use force_fit_type, which checks against the precision. */
- if (TYPE_MAX_VALUE (type) != NULL_TREE
- && TYPE_MIN_VALUE (type) != NULL_TREE
- && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST
- && TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST)
+int_fits_type_p (tree c, tree type)
+{
+ tree type_low_bound = TYPE_MIN_VALUE (type);
+ tree type_high_bound = TYPE_MAX_VALUE (type);
+ int ok_for_low_bound, ok_for_high_bound;
+
+ /* Perform some generic filtering first, which may allow making a decision
+ even if the bounds are not constant. First, negative integers never fit
+ in unsigned types, */
+ if ((TREE_UNSIGNED (type) && tree_int_cst_sgn (c) < 0)
+ /* Also, unsigned integers with top bit set never fit signed types. */
+ || (! TREE_UNSIGNED (type)
+ && TREE_UNSIGNED (TREE_TYPE (c)) && tree_int_cst_msb (c)))
+ return 0;
+
+ /* If at least one bound of the type is a constant integer, we can check
+ ourselves and maybe make a decision. If no such decision is possible, but
+ this type is a subtype, try checking against that. Otherwise, use
+ force_fit_type, which checks against the precision.
+
+ Compute the status for each possibly constant bound, and return if we see
+ one does not match. Use ok_for_xxx_bound for this purpose, assigning -1
+ for "unknown if constant fits", 0 for "constant known *not* to fit" and 1
+ for "constant known to fit". */
+
+ ok_for_low_bound = -1;
+ ok_for_high_bound = -1;
+
+ /* Check if C >= type_low_bound. */
+ if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
{
- if (TREE_UNSIGNED (type))
- return (! INT_CST_LT_UNSIGNED (TYPE_MAX_VALUE (type), c)
- && ! INT_CST_LT_UNSIGNED (c, TYPE_MIN_VALUE (type))
- /* Negative ints never fit unsigned types. */
- && ! (TREE_INT_CST_HIGH (c) < 0
- && ! TREE_UNSIGNED (TREE_TYPE (c))));
- else
- return (! INT_CST_LT (TYPE_MAX_VALUE (type), c)
- && ! INT_CST_LT (c, TYPE_MIN_VALUE (type))
- /* Unsigned ints with top bit set never fit signed types. */
- && ! (TREE_INT_CST_HIGH (c) < 0
- && TREE_UNSIGNED (TREE_TYPE (c))));
+ ok_for_low_bound = ! tree_int_cst_lt (c, type_low_bound);
+ if (! ok_for_low_bound)
+ return 0;
}
+
+ /* Check if c <= type_high_bound. */
+ if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST)
+ {
+ ok_for_high_bound = ! tree_int_cst_lt (type_high_bound, c);
+ if (! ok_for_high_bound)
+ return 0;
+ }
+
+ /* If the constant fits both bounds, the result is known. */
+ if (ok_for_low_bound == 1 && ok_for_high_bound == 1)
+ return 1;
+
+ /* If we haven't been able to decide at this point, there nothing more we
+ can check ourselves here. Look at the base type if we have one. */
else if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != 0)
return int_fits_type_p (c, TREE_TYPE (type));
+
+ /* Or to force_fit_type, if nothing else. */
else
{
c = copy_node (c);
@@ -4111,56 +4306,68 @@ int_fits_type_p (c, type)
modified types': in C99, a struct type is never variably modified
because a VLA may not appear as a structure member. However, in
GNU C code like:
-
+
struct S { int i[f()]; };
is valid, and other languages may define similar constructs. */
bool
-variably_modified_type_p (type)
- tree type;
+variably_modified_type_p (tree type)
{
+ tree t;
+
if (type == error_mark_node)
return false;
- /* If TYPE itself has variable size, it is variably modified.
+ /* If TYPE itself has variable size, it is variably modified.
We do not yet have a representation of the C99 '[*]' syntax.
When a representation is chosen, this function should be modified
to test for that case as well. */
- if (TYPE_SIZE (type)
- && TYPE_SIZE (type) != error_mark_node
- && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
- return true;
-
- /* If TYPE is a pointer or reference, it is variably modified if
- the type pointed to is variably modified. */
- if ((TREE_CODE (type) == POINTER_TYPE
- || TREE_CODE (type) == REFERENCE_TYPE)
- && variably_modified_type_p (TREE_TYPE (type)))
- return true;
-
- /* If TYPE is an array, it is variably modified if the array
- elements are. (Note that the VLA case has already been checked
- above.) */
- if (TREE_CODE (type) == ARRAY_TYPE
- && variably_modified_type_p (TREE_TYPE (type)))
+ t = TYPE_SIZE (type);
+ if (t && t != error_mark_node && TREE_CODE (t) != INTEGER_CST)
return true;
- /* If TYPE is a function type, it is variably modified if any of the
- parameters or the return type are variably modified. */
- if (TREE_CODE (type) == FUNCTION_TYPE
- || TREE_CODE (type) == METHOD_TYPE)
+ switch (TREE_CODE (type))
{
- tree parm;
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ case ARRAY_TYPE:
+ /* If TYPE is a pointer or reference, it is variably modified if
+ the type pointed to is variably modified. Similarly for arrays;
+ note that VLAs are handled by the TYPE_SIZE check above. */
+ return variably_modified_type_p (TREE_TYPE (type));
+
+ case FUNCTION_TYPE:
+ case METHOD_TYPE:
+ /* If TYPE is a function type, it is variably modified if any of the
+ parameters or the return type are variably modified. */
+ {
+ tree parm;
- if (variably_modified_type_p (TREE_TYPE (type)))
- return true;
- for (parm = TYPE_ARG_TYPES (type);
- parm && parm != void_list_node;
- parm = TREE_CHAIN (parm))
- if (variably_modified_type_p (TREE_VALUE (parm)))
+ if (variably_modified_type_p (TREE_TYPE (type)))
return true;
+ for (parm = TYPE_ARG_TYPES (type);
+ parm && parm != void_list_node;
+ parm = TREE_CHAIN (parm))
+ if (variably_modified_type_p (TREE_VALUE (parm)))
+ return true;
+ }
+ break;
+
+ case INTEGER_TYPE:
+ /* Scalar types are variably modified if their end points
+ aren't constant. */
+ t = TYPE_MIN_VALUE (type);
+ if (t && t != error_mark_node && TREE_CODE (t) != INTEGER_CST)
+ return true;
+ t = TYPE_MAX_VALUE (type);
+ if (t && t != error_mark_node && TREE_CODE (t) != INTEGER_CST)
+ return true;
+ return false;
+
+ default:
+ break;
}
/* The current language may have other cases to check, but in general,
@@ -4172,8 +4379,7 @@ variably_modified_type_p (type)
NULL_TREE if there is no containing scope. */
tree
-get_containing_scope (t)
- tree t;
+get_containing_scope (tree t)
{
return (TYPE_P (t) ? TYPE_CONTEXT (t) : DECL_CONTEXT (t));
}
@@ -4182,8 +4388,7 @@ get_containing_scope (t)
a FUNCTION_DECL, or zero if none. */
tree
-decl_function_context (decl)
- tree decl;
+decl_function_context (tree decl)
{
tree context;
@@ -4222,32 +4427,35 @@ decl_function_context (decl)
TYPE_DECLs and FUNCTION_DECLs are transparent to this function. */
tree
-decl_type_context (decl)
- tree decl;
+decl_type_context (tree decl)
{
tree context = DECL_CONTEXT (decl);
while (context)
- {
- if (TREE_CODE (context) == NAMESPACE_DECL)
+ switch (TREE_CODE (context))
+ {
+ case NAMESPACE_DECL:
+ case TRANSLATION_UNIT_DECL:
return NULL_TREE;
- if (TREE_CODE (context) == RECORD_TYPE
- || TREE_CODE (context) == UNION_TYPE
- || TREE_CODE (context) == QUAL_UNION_TYPE)
+ case RECORD_TYPE:
+ case UNION_TYPE:
+ case QUAL_UNION_TYPE:
return context;
-
- if (TREE_CODE (context) == TYPE_DECL
- || TREE_CODE (context) == FUNCTION_DECL)
+
+ case TYPE_DECL:
+ case FUNCTION_DECL:
context = DECL_CONTEXT (context);
-
- else if (TREE_CODE (context) == BLOCK)
+ break;
+
+ case BLOCK:
context = BLOCK_SUPERCONTEXT (context);
-
- else
- /* Unhandled CONTEXT!? */
+ break;
+
+ default:
abort ();
- }
+ }
+
return NULL_TREE;
}
@@ -4256,8 +4464,7 @@ decl_type_context (decl)
determined. */
tree
-get_callee_fndecl (call)
- tree call;
+get_callee_fndecl (tree call)
{
tree addr;
@@ -4283,39 +4490,17 @@ get_callee_fndecl (call)
if (TREE_CODE (addr) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
return TREE_OPERAND (addr, 0);
-
- /* We couldn't figure out what was being called. */
- return NULL_TREE;
-}
-
-/* Print debugging information about the obstack O, named STR. */
-
-void
-print_obstack_statistics (str, o)
- const char *str;
- struct obstack *o;
-{
- struct _obstack_chunk *chunk = o->chunk;
- int n_chunks = 1;
- int n_alloc = 0;
-
- n_alloc += o->next_free - chunk->contents;
- chunk = chunk->prev;
- while (chunk)
- {
- n_chunks += 1;
- n_alloc += chunk->limit - &chunk->contents[0];
- chunk = chunk->prev;
- }
- fprintf (stderr, "obstack %s: %u bytes, %d chunks\n",
- str, n_alloc, n_chunks);
+
+ /* We couldn't figure out what was being called. Maybe the front
+ end has some idea. */
+ return (*lang_hooks.lang_get_callee_fndecl) (call);
}
/* Print debugging information about tree nodes generated during the compile,
and any language-specific information. */
void
-dump_tree_statistics ()
+dump_tree_statistics (void)
{
#ifdef GATHER_STATISTICS
int i;
@@ -4324,19 +4509,19 @@ dump_tree_statistics ()
fprintf (stderr, "\n??? tree nodes created\n\n");
#ifdef GATHER_STATISTICS
- fprintf (stderr, "Kind Nodes Bytes\n");
- fprintf (stderr, "-------------------------------------\n");
+ fprintf (stderr, "Kind Nodes Bytes\n");
+ fprintf (stderr, "---------------------------------------\n");
total_nodes = total_bytes = 0;
for (i = 0; i < (int) all_kinds; i++)
{
- fprintf (stderr, "%-20s %6d %9d\n", tree_node_kind_names[i],
+ fprintf (stderr, "%-20s %7d %10d\n", tree_node_kind_names[i],
tree_node_counts[i], tree_node_sizes[i]);
total_nodes += tree_node_counts[i];
total_bytes += tree_node_sizes[i];
}
- fprintf (stderr, "-------------------------------------\n");
- fprintf (stderr, "%-20s %6d %9d\n", "Total", total_nodes, total_bytes);
- fprintf (stderr, "-------------------------------------\n");
+ fprintf (stderr, "---------------------------------------\n");
+ fprintf (stderr, "%-20s %7d %10d\n", "Total", total_nodes, total_bytes);
+ fprintf (stderr, "---------------------------------------\n");
#else
fprintf (stderr, "(No per-node statistics)\n");
#endif
@@ -4346,85 +4531,34 @@ dump_tree_statistics ()
#define FILE_FUNCTION_FORMAT "_GLOBAL__%s_%s"
-const char *flag_random_seed;
-
-/* Set up a default flag_random_seed value, if there wasn't one already. */
-
-void
-default_flag_random_seed ()
-{
- unsigned HOST_WIDE_INT value;
- char *new_random_seed;
-
- if (flag_random_seed != NULL)
- return;
-
- /* Get some more or less random data. */
-#ifdef HAVE_GETTIMEOFDAY
- {
- struct timeval tv;
-
- gettimeofday (&tv, NULL);
- value = (((unsigned HOST_WIDE_INT) tv.tv_usec << 16)
- ^ tv.tv_sec ^ getpid ());
- }
-#else
- value = getpid ();
-#endif
-
- /* This slightly overestimates the space required. */
- new_random_seed = xmalloc (HOST_BITS_PER_WIDE_INT / 3 + 2);
- sprintf (new_random_seed, HOST_WIDE_INT_PRINT_UNSIGNED, value);
- flag_random_seed = new_random_seed;
-}
-
-/* Appends 6 random characters to TEMPLATE to (hopefully) avoid name
- clashes in cases where we can't reliably choose a unique name.
-
- Derived from mkstemp.c in libiberty. */
+/* Generate a crc32 of a string. */
-static void
-append_random_chars (template)
- char *template;
+unsigned
+crc32_string (unsigned chksum, const char *string)
{
- static const char letters[]
- = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- unsigned HOST_WIDE_INT v;
- size_t i;
-
- default_flag_random_seed ();
-
- /* This isn't a very good hash, but it does guarantee no collisions
- when the random string is generated by the code above and the time
- delta is small. */
- v = 0;
- for (i = 0; i < strlen (flag_random_seed); i++)
- v = (v << 4) ^ (v >> (HOST_BITS_PER_WIDE_INT - 4)) ^ flag_random_seed[i];
-
- template += strlen (template);
-
- /* Fill in the random bits. */
- template[0] = letters[v % 62];
- v /= 62;
- template[1] = letters[v % 62];
- v /= 62;
- template[2] = letters[v % 62];
- v /= 62;
- template[3] = letters[v % 62];
- v /= 62;
- template[4] = letters[v % 62];
- v /= 62;
- template[5] = letters[v % 62];
-
- template[6] = '\0';
+ do
+ {
+ unsigned value = *string << 24;
+ unsigned ix;
+
+ for (ix = 8; ix--; value <<= 1)
+ {
+ unsigned feedback;
+
+ feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
+ chksum <<= 1;
+ chksum ^= feedback;
+ }
+ }
+ while (*string++);
+ return chksum;
}
/* P is a string that will be used in a symbol. Mask out any characters
that are not valid in that context. */
void
-clean_symbol_name (p)
- char *p;
+clean_symbol_name (char *p)
{
for (; *p; p++)
if (! (ISALNUM (*p)
@@ -4443,8 +4577,7 @@ clean_symbol_name (p)
linker or collect2. */
tree
-get_file_function_name_long (type)
- const char *type;
+get_file_function_name_long (const char *type)
{
char *buf;
const char *p;
@@ -4456,7 +4589,7 @@ get_file_function_name_long (type)
{
/* We don't have anything that we know to be unique to this translation
unit, so use what we do have and throw in some randomness. */
-
+ unsigned len;
const char *name = weak_global_object_name;
const char *file = main_input_filename;
@@ -4465,15 +4598,18 @@ get_file_function_name_long (type)
if (! file)
file = input_filename;
- q = (char *) alloca (7 + strlen (name) + strlen (file));
+ len = strlen (file);
+ q = alloca (9 * 2 + len + 1);
+ memcpy (q, file, len + 1);
+ clean_symbol_name (q);
+
+ sprintf (q + len, "_%08X_%08X", crc32_string (0, name),
+ crc32_string (0, flag_random_seed));
- sprintf (q, "%s%s", name, file);
- append_random_chars (q);
p = q;
}
- buf = (char *) alloca (sizeof (FILE_FUNCTION_FORMAT) + strlen (p)
- + strlen (type));
+ buf = alloca (sizeof (FILE_FUNCTION_FORMAT) + strlen (p) + strlen (type));
/* Set up the name of the file-level functions we may need.
Use a global object (which is already required to be unique over
@@ -4481,10 +4617,6 @@ get_file_function_name_long (type)
constraints). */
sprintf (buf, FILE_FUNCTION_FORMAT, type, p);
- /* Don't need to pull weird characters out of global names. */
- if (p != first_global_object_name)
- clean_symbol_name (buf + 11);
-
return get_identifier (buf);
}
@@ -4492,8 +4624,7 @@ get_file_function_name_long (type)
If KIND=='D', return a suitable global clean-up (destructor) name. */
tree
-get_file_function_name (kind)
- int kind;
+get_file_function_name (int kind)
{
char p[2];
@@ -4511,10 +4642,7 @@ get_file_function_name (kind)
Otherwise, a TREE_LIST of the non-constant elements is emitted. */
tree
-get_set_constructor_bits (init, buffer, bit_size)
- tree init;
- char *buffer;
- int bit_size;
+get_set_constructor_bits (tree init, char *buffer, int bit_size)
{
int i;
tree vals;
@@ -4569,17 +4697,14 @@ get_set_constructor_bits (init, buffer, bit_size)
Otherwise, a TREE_LIST of the non-constant elements is emitted. */
tree
-get_set_constructor_bytes (init, buffer, wd_size)
- tree init;
- unsigned char *buffer;
- int wd_size;
+get_set_constructor_bytes (tree init, unsigned char *buffer, int wd_size)
{
int i;
int set_word_size = BITS_PER_UNIT;
int bit_size = wd_size * set_word_size;
int bit_pos = 0;
unsigned char *bytep = buffer;
- char *bit_buffer = (char *) alloca (bit_size);
+ char *bit_buffer = alloca (bit_size);
tree non_const_bits = get_set_constructor_bits (init, bit_buffer, bit_size);
for (i = 0; i < wd_size; i++)
@@ -4606,12 +4731,8 @@ get_set_constructor_bytes (init, buffer, wd_size)
FILE, LINE, and FUNCTION are of the caller. */
void
-tree_check_failed (node, code, file, line, function)
- const tree node;
- enum tree_code code;
- const char *file;
- int line;
- const char *function;
+tree_check_failed (const tree node, enum tree_code code, const char *file,
+ int line, const char *function)
{
internal_error ("tree check: expected %s, have %s in %s, at %s:%d",
tree_code_name[code], tree_code_name[TREE_CODE (node)],
@@ -4622,12 +4743,8 @@ tree_check_failed (node, code, file, line, function)
code, given in CL. */
void
-tree_class_check_failed (node, cl, file, line, function)
- const tree node;
- int cl;
- const char *file;
- int line;
- const char *function;
+tree_class_check_failed (const tree node, int cl, const char *file,
+ int line, const char *function)
{
internal_error
("tree check: expected class '%c', have '%c' (%s) in %s, at %s:%d",
@@ -4639,26 +4756,33 @@ tree_class_check_failed (node, cl, file, line, function)
(dynamically sized) vector. */
void
-tree_vec_elt_check_failed (idx, len, file, line, function)
- int idx;
- int len;
- const char *file;
- int line;
- const char *function;
+tree_vec_elt_check_failed (int idx, int len, const char *file, int line,
+ const char *function)
{
internal_error
("tree check: accessed elt %d of tree_vec with %d elts in %s, at %s:%d",
idx + 1, len, function, trim_filename (file), line);
}
+/* Similar to above, except that the check is for the bounds of the operand
+ vector of an expression node. */
+
+void
+tree_operand_check_failed (int idx, enum tree_code code, const char *file,
+ int line, const char *function)
+{
+ internal_error
+ ("tree check: accessed operand %d of %s with %d operands in %s, at %s:%d",
+ idx + 1, tree_code_name[code], TREE_CODE_LENGTH (code),
+ function, trim_filename (file), line);
+}
#endif /* ENABLE_TREE_CHECKING */
/* For a new vector type node T, build the information necessary for
debugging output. */
static void
-finish_vector_type (t)
- tree t;
+finish_vector_type (tree t)
{
layout_type (t);
@@ -4685,8 +4809,7 @@ finish_vector_type (t)
this function to select one of the types as sizetype. */
void
-build_common_tree_nodes (signed_char)
- int signed_char;
+build_common_tree_nodes (int signed_char)
{
error_mark_node = make_node (ERROR_MARK);
TREE_TYPE (error_mark_node) = error_mark_node;
@@ -4713,6 +4836,16 @@ build_common_tree_nodes (signed_char)
long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE);
long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE);
+ /* Define a boolean type. This type only represents boolean values but
+ may be larger than char depending on the value of BOOL_TYPE_SIZE.
+ Front ends which want to override this size (i.e. Java) can redefine
+ boolean_type_node before calling build_common_tree_nodes_2. */
+ boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
+ TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
+ TYPE_MAX_VALUE (boolean_type_node) = build_int_2 (1, 0);
+ TREE_TYPE (TYPE_MAX_VALUE (boolean_type_node)) = boolean_type_node;
+ TYPE_PRECISION (boolean_type_node) = 1;
+
intQI_type_node = make_signed_type (GET_MODE_BITSIZE (QImode));
intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode));
intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode));
@@ -4724,14 +4857,17 @@ build_common_tree_nodes (signed_char)
unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode));
unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode));
unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode));
+
+ access_public_node = get_identifier ("public");
+ access_protected_node = get_identifier ("protected");
+ access_private_node = get_identifier ("private");
}
/* Call this function after calling build_common_tree_nodes and set_sizetype.
It will create several other common tree nodes. */
void
-build_common_tree_nodes_2 (short_double)
- int short_double;
+build_common_tree_nodes_2 (int short_double)
{
/* Define these next since types below may used them. */
integer_zero_node = build_int_2 (0, 0);
@@ -4744,6 +4880,9 @@ build_common_tree_nodes_2 (short_double)
bitsize_one_node = bitsize_int (1);
bitsize_unit_node = bitsize_int (BITS_PER_UNIT);
+ boolean_false_node = TYPE_MIN_VALUE (boolean_type_node);
+ boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
+
void_type_node = make_node (VOID_TYPE);
layout_type (void_type_node);
@@ -4775,6 +4914,11 @@ build_common_tree_nodes_2 (short_double)
TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE;
layout_type (long_double_type_node);
+ float_ptr_type_node = build_pointer_type (float_type_node);
+ double_ptr_type_node = build_pointer_type (double_type_node);
+ long_double_ptr_type_node = build_pointer_type (long_double_type_node);
+ integer_ptr_type_node = build_pointer_type (integer_type_node);
+
complex_integer_type_node = make_node (COMPLEX_TYPE);
TREE_TYPE (complex_integer_type_node) = integer_type_node;
layout_type (complex_integer_type_node);
@@ -4792,10 +4936,9 @@ build_common_tree_nodes_2 (short_double)
layout_type (complex_long_double_type_node);
{
- tree t;
- BUILD_VA_LIST_TYPE (t);
+ tree t = (*targetm.build_builtin_va_list) ();
- /* Many back-ends define record types without seting TYPE_NAME.
+ /* Many back-ends define record types without setting TYPE_NAME.
If we copied the record type here, we'd keep the original
record type without a name. This breaks name mangling. So,
don't copy record types and let c_common_nodes_and_builtins()
@@ -4838,16 +4981,14 @@ build_common_tree_nodes_2 (short_double)
V2DF_type_node = make_vector (V2DFmode, double_type_node, 0);
V16QI_type_node = make_vector (V16QImode, intQI_type_node, 0);
V1DI_type_node = make_vector (V1DImode, intDI_type_node, 0);
+ V4DF_type_node = make_vector (V4DFmode, double_type_node, 0);
}
/* Returns a vector tree node given a vector mode, the inner type, and
the signness. */
static tree
-make_vector (mode, innertype, unsignedp)
- enum machine_mode mode;
- tree innertype;
- int unsignedp;
+make_vector (enum machine_mode mode, tree innertype, int unsignedp)
{
tree t;
@@ -4864,8 +5005,7 @@ make_vector (mode, innertype, unsignedp)
aggregate of zeros. Otherwise return FALSE. */
bool
-initializer_zerop (init)
- tree init;
+initializer_zerop (tree init)
{
STRIP_NOPS (init);
@@ -4883,9 +5023,14 @@ initializer_zerop (init)
&& ! REAL_VALUE_MINUS_ZERO (TREE_REAL_CST (TREE_IMAGPART (init))));
case CONSTRUCTOR:
{
+ /* Set is empty if it has no elements. */
+ if ((TREE_CODE (TREE_TYPE (init)) == SET_TYPE)
+ && CONSTRUCTOR_ELTS (init))
+ return false;
+
if (AGGREGATE_TYPE_P (TREE_TYPE (init)))
{
- tree aggr_init = TREE_OPERAND (init, 1);
+ tree aggr_init = CONSTRUCTOR_ELTS (init);
while (aggr_init)
{
diff --git a/contrib/gcc/tree.def b/contrib/gcc/tree.def
index e05ec281dc4b..78919740da33 100644
--- a/contrib/gcc/tree.def
+++ b/contrib/gcc/tree.def
@@ -1,6 +1,6 @@
/* This file contains the definitions and documentation for the
- tree codes used in the GNU C compiler.
- Copyright (C) 1987, 1988, 1993, 1995, 1997, 1998, 2000, 2001
+ tree codes used in GCC.
+ Copyright (C) 1987, 1988, 1993, 1995, 1997, 1998, 2000, 2001, 2004
Free Software Foundation, Inc.
This file is part of GCC.
@@ -31,12 +31,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
'<' for codes for comparison expressions.
'1' for codes for unary arithmetic expressions.
'2' for codes for binary arithmetic expressions.
- 's' for codes for expressions with inherent side effects.
+ 's' for codes for "statement" expressions, which have side-effects,
+ but usually no interesting value.
'e' for codes for other kinds of expressions. */
-/* For `r', `e', `<', `1', `2', `s' and `x' nodes,
- the 4th element is the number of argument slots to allocate.
- This determines the size of the tree node object. */
+/* For `r', `e', `<', `1', `2', and `s' nodes, which use struct
+ tree_exp, the 4th element is the number of argument slots to
+ allocate. This determines the size of the tree node object.
+ Other nodes use different structures, and the size is determined
+ by the tree_union member structure; the 4th element should be
+ zero. Languages that define language-specific 'x' or 'c' codes
+ must define the tree_size langhook to say how big they are. */
/* Any erroneous construct is parsed into a node of this type.
This type of node is accepted without complaint in all contexts
@@ -49,17 +54,17 @@ DEFTREECODE (ERROR_MARK, "error_mark", 'x', 0)
Internally it looks like a STRING_CST node.
There is only one IDENTIFIER_NODE ever made for any particular name.
Use `get_identifier' to get it (or create it, the first time). */
-DEFTREECODE (IDENTIFIER_NODE, "identifier_node", 'x', ((LANG_HOOKS_IDENTIFIER_SIZE - sizeof (struct tree_common) + sizeof (tree) - 1) / sizeof (tree)))
+DEFTREECODE (IDENTIFIER_NODE, "identifier_node", 'x', 0)
/* Has the TREE_VALUE and TREE_PURPOSE fields. */
/* These nodes are made into lists by chaining through the
TREE_CHAIN field. The elements of the list live in the
TREE_VALUE fields, while TREE_PURPOSE fields are occasionally
used as well to get the effect of Lisp association lists. */
-DEFTREECODE (TREE_LIST, "tree_list", 'x', 2)
+DEFTREECODE (TREE_LIST, "tree_list", 'x', 0)
/* These nodes contain an array of tree nodes. */
-DEFTREECODE (TREE_VEC, "tree_vec", 'x', 2)
+DEFTREECODE (TREE_VEC, "tree_vec", 'x', 0)
/* A symbol binding block. These are arranged in a tree,
where the BLOCK_SUBBLOCKS field contains a chain of subblocks
@@ -257,34 +262,33 @@ DEFTREECODE (LANG_TYPE, "lang_type", 't', 0)
Note: constants of type char in Pascal are INTEGER_CST,
and so are pointer constants such as nil in Pascal or NULL in C.
`(int *) 1' in C also results in an INTEGER_CST. */
-DEFTREECODE (INTEGER_CST, "integer_cst", 'c', 2)
+DEFTREECODE (INTEGER_CST, "integer_cst", 'c', 0)
-/* Contents are in TREE_REAL_CST field. Also there is TREE_CST_RTL. */
-DEFTREECODE (REAL_CST, "real_cst", 'c', 3)
+/* Contents are in TREE_REAL_CST field. */
+DEFTREECODE (REAL_CST, "real_cst", 'c', 0)
/* Contents are in TREE_REALPART and TREE_IMAGPART fields,
- whose contents are other constant nodes.
- Also there is TREE_CST_RTL. */
-DEFTREECODE (COMPLEX_CST, "complex_cst", 'c', 3)
+ whose contents are other constant nodes. */
+DEFTREECODE (COMPLEX_CST, "complex_cst", 'c', 0)
/* Contents are in TREE_VECTOR_CST_ELTS field. */
-DEFTREECODE (VECTOR_CST, "vector_cst", 'c', 3)
-
-/* Contents are TREE_STRING_LENGTH and TREE_STRING_POINTER fields.
- Also there is TREE_CST_RTL. */
-DEFTREECODE (STRING_CST, "string_cst", 'c', 3)
-
-/* Declarations. All references to names are represented as ..._DECL nodes.
- The decls in one binding context are chained through the TREE_CHAIN field.
- Each DECL has a DECL_NAME field which contains an IDENTIFIER_NODE.
- (Some decls, most often labels, may have zero as the DECL_NAME).
- DECL_CONTEXT points to the node representing the context in which
- this declaration has its scope. For FIELD_DECLs, this is the
- RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE node that the field
- is a member of. For VAR_DECL, PARM_DECL, FUNCTION_DECL, LABEL_DECL,
- and CONST_DECL nodes, this points to either the FUNCTION_DECL for the
- containing function, the RECORD_TYPE or UNION_TYPE for the containing
- type, or NULL_TREE if the given decl has "file scope".
+DEFTREECODE (VECTOR_CST, "vector_cst", 'c', 0)
+
+/* Contents are TREE_STRING_LENGTH and TREE_STRING_POINTER fields. */
+DEFTREECODE (STRING_CST, "string_cst", 'c', 0)
+
+/* Declarations. All references to names are represented as ..._DECL
+ nodes. The decls in one binding context are chained through the
+ TREE_CHAIN field. Each DECL has a DECL_NAME field which contains
+ an IDENTIFIER_NODE. (Some decls, most often labels, may have zero
+ as the DECL_NAME). DECL_CONTEXT points to the node representing
+ the context in which this declaration has its scope. For
+ FIELD_DECLs, this is the RECORD_TYPE, UNION_TYPE, or
+ QUAL_UNION_TYPE node that the field is a member of. For VAR_DECL,
+ PARM_DECL, FUNCTION_DECL, LABEL_DECL, and CONST_DECL nodes, this
+ points to either the FUNCTION_DECL for the containing function, the
+ RECORD_TYPE or UNION_TYPE for the containing type, or NULL_TREE or
+ a TRANSLATION_UNIT_DECL if the given decl has "file scope".
DECL_ABSTRACT_ORIGIN, if non-NULL, points to the original (abstract)
..._DECL node of which this decl is an (inlined or template expanded)
instance.
@@ -295,9 +299,9 @@ DEFTREECODE (STRING_CST, "string_cst", 'c', 3)
and DECL_MODE fields exist in decl nodes just as in type nodes.
They are unused in LABEL_DECL, TYPE_DECL and CONST_DECL nodes.
- DECL_OFFSET holds an integer number of bits offset for the location.
- DECL_VOFFSET holds an expression for a variable offset; it is
- to be multiplied by DECL_VOFFSET_UNIT (an integer).
+ DECL_FIELD_BIT_OFFSET holds an integer number of bits offset for
+ the location. DECL_VOFFSET holds an expression for a variable
+ offset; it is to be multiplied by DECL_VOFFSET_UNIT (an integer).
These fields are relevant only in FIELD_DECLs and PARM_DECLs.
DECL_INITIAL holds the value to initialize a variable to,
@@ -343,6 +347,10 @@ DEFTREECODE (FIELD_DECL, "field_decl", 'd', 0)
/* A namespace declaration. Namespaces appear in DECL_CONTEXT of other
_DECLs, providing a hierarchy of names. */
DEFTREECODE (NAMESPACE_DECL, "namespace_decl", 'd', 0)
+
+/* A translation unit. This is not technically a declaration, since it
+ can't be looked up, but it's close enough. */
+DEFTREECODE (TRANSLATION_UNIT_DECL, "translation_unit_decl", 'd', 0)
/* References to storage. */
@@ -385,10 +393,8 @@ DEFTREECODE (VTABLE_REF, "vtable_ref", 'r', 3)
/* Constructor: return an aggregate value made from specified components.
In C, this is used only for structure and array initializers.
Also used for SET_TYPE in Chill (and potentially Pascal).
- The first "operand" is really a pointer to the RTL,
- for constant constructors only.
- The second operand is a list of component values
- made out of a chain of TREE_LIST nodes.
+ The operand is a list of component values made out of a chain of
+ TREE_LIST nodes.
For ARRAY_TYPE:
The TREE_PURPOSE of each node is the corresponding index.
@@ -404,7 +410,7 @@ DEFTREECODE (VTABLE_REF, "vtable_ref", 'r', 3)
The TREE_VALUE specifies a value (index) in the set that is true.
If TREE_PURPOSE is non-NULL, it specifies the lower limit of a
range of true values. Elements not listed are false (not in the set). */
-DEFTREECODE (CONSTRUCTOR, "constructor", 'e', 2)
+DEFTREECODE (CONSTRUCTOR, "constructor", 'e', 1)
/* The expression types are mostly straightforward, with the fourth argument
of DEFTREECODE saying how many operands there are.
@@ -468,11 +474,6 @@ DEFTREECODE (BIND_EXPR, "bind_expr", 'e', 3)
made out of a chain of TREE_LIST nodes. */
DEFTREECODE (CALL_EXPR, "call_expr", 'e', 2)
-/* Call a method. Operand 0 is the method, whose type is a METHOD_TYPE.
- Operand 1 is the expression for "self".
- Operand 2 is the list of explicit arguments. */
-DEFTREECODE (METHOD_CALL_EXPR, "method_call_expr", 'e', 4)
-
/* Specify a value to compute along with its corresponding cleanup.
Operand 0 argument is an expression whose value needs a cleanup.
Operand 1 is the cleanup expression for the object.
@@ -508,7 +509,8 @@ DEFTREECODE (CLEANUP_POINT_EXPR, "cleanup_point_expr", 'e', 1)
some field in an object of the type contains a value that is used in
the computation of another field's offset or size and/or the size of
the type. The positions and/or sizes of fields can vary from object
- to object of the same type.
+ to object of the same type or even for one and the same object within
+ its scope.
Record types with discriminants in Ada or schema types in Pascal are
examples of such types. This mechanism is also used to create "fat
@@ -532,7 +534,16 @@ DEFTREECODE (CLEANUP_POINT_EXPR, "cleanup_point_expr", 'e', 1)
For example, if your type FOO is a RECORD_TYPE with a field BAR,
and you need the value of <variable>.BAR to calculate TYPE_SIZE
(FOO), just substitute <variable> above with a PLACEHOLDER_EXPR
- what contains both the expression we wish to
+ whose TREE_TYPE is FOO. Then construct your COMPONENT_REF with
+ the PLACEHOLDER_EXPR as the first operand (which has the correct
+ type). Later, when the size is needed in the program, the back-end
+ will find this PLACEHOLDER_EXPR and generate code to calculate the
+ actual size at run-time. In the following, we describe how this
+ calculation is done.
+
+ When we wish to evaluate a size or offset, we check whether it
+ contains a PLACEHOLDER_EXPR. If it does, we construct a
+ WITH_RECORD_EXPR that contains both the expression we wish to
evaluate and an expression within which the object may be found.
The latter expression is the object itself in the simple case of an
Ada record with discriminant, but it can be the array in the case of
@@ -614,8 +625,6 @@ DEFTREECODE (MAX_EXPR, "max_expr", '2', 2)
operand of the ABS_EXPR must have the same type. */
DEFTREECODE (ABS_EXPR, "abs_expr", '1', 1)
-DEFTREECODE (FFS_EXPR, "ffs_expr", '1', 1)
-
/* Shift operations for shift and rotate.
Shift means logical shift if done on an
unsigned type, arithmetic shift if done on a signed type.
@@ -632,7 +641,6 @@ DEFTREECODE (RROTATE_EXPR, "rrotate_expr", '2', 2)
DEFTREECODE (BIT_IOR_EXPR, "bit_ior_expr", '2', 2)
DEFTREECODE (BIT_XOR_EXPR, "bit_xor_expr", '2', 2)
DEFTREECODE (BIT_AND_EXPR, "bit_and_expr", '2', 2)
-DEFTREECODE (BIT_ANDTC_EXPR, "bit_andtc_expr", '2', 2)
DEFTREECODE (BIT_NOT_EXPR, "bit_not_expr", '1', 1)
/* ANDIF and ORIF allow the second operand not to be computed if the
@@ -722,11 +730,15 @@ DEFTREECODE (UNSAVE_EXPR, "unsave_expr", 'e', 1)
/* Represents something whose RTL has already been expanded as a
sequence which should be emitted when this expression is expanded.
The first operand is the RTL to emit. It is the first of a chain
- of insns. The second is the RTL expression for the result. Any
- temporaries created during the building of the RTL_EXPR can be
- reused once the RTL_EXPR has been expanded, with the exception of
- the RTL_EXPR_RTL. */
-DEFTREECODE (RTL_EXPR, "rtl_expr", 'e', 2)
+ of insns. The second is the RTL expression for the result. The
+ third operand is the "alternate RTL expression" for the result, if
+ any; if the second argument is the DECL_RTL for a VAR_DECL, but
+ with an invalid memory address replaced by a valid one, then the
+ third operand will be the original DECL_RTL. Any temporaries
+ created during the building of the RTL_EXPR can be reused once the
+ RTL_EXPR has been expanded, with the exception of the
+ RTL_EXPR_RTL. */
+DEFTREECODE (RTL_EXPR, "rtl_expr", 'e', 3)
/* & in C. Value is the address at which the operand's value resides.
Operand may have any mode. Result mode is Pmode. */
@@ -775,16 +787,7 @@ DEFTREECODE (TRY_CATCH_EXPR, "try_catch_expr", 'e', 2)
/* Evaluate the first operand.
The second operand is a cleanup expression which is evaluated
- before an exit (normal, exception, or jump out) from this expression.
-
- Like a CLEANUP_POINT_EXPR/WITH_CLEANUP_EXPR combination, but those
- always copy the cleanup expression where needed. In contrast,
- TRY_FINALLY_EXPR generates a jump to a cleanup subroutine.
- (At least conceptually; the optimizer could inline the cleanup
- subroutine in the same way it could inline normal subroutines.)
- TRY_FINALLY_EXPR should be used when the cleanup is actual statements
- in the source of the current function (which people might want to
- set breakpoints in). */
+ on any exit (normal, exception, or jump out) from this expression. */
DEFTREECODE (TRY_FINALLY_EXPR, "try_finally", 'e', 2)
/* Used internally for cleanups in the implementation of TRY_FINALLY_EXPR.
diff --git a/contrib/gcc/tree.h b/contrib/gcc/tree.h
index 1ad4b142c78a..96de4a46760d 100644
--- a/contrib/gcc/tree.h
+++ b/contrib/gcc/tree.h
@@ -1,6 +1,6 @@
/* Front-end tree definitions for GNU compiler.
Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -24,7 +24,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "machmode.h"
#include "version.h"
-#include "location.h"
+#include "input.h"
/* Codes of tree nodes */
@@ -56,8 +56,11 @@ extern const char tree_code_type[];
/* Returns nonzero iff CLASS is the tree-code class of an
expression. */
-#define IS_EXPR_CODE_CLASS(CLASS) \
- ((CLASS) == '<' || (CLASS) == '1' || (CLASS) == '2' || (CLASS) == 'e')
+#define IS_EXPR_CODE_CLASS(CLASS) (strchr ("<12ers", (CLASS)) != 0)
+
+/* Returns nonzero iff NODE is an expression of some kind. */
+
+#define EXPR_P(NODE) IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (NODE)))
/* Number of argument-words in each kind of tree-node. */
@@ -84,7 +87,7 @@ extern const char *const built_in_class_names[4];
/* Codes that identify the various built in functions
so that expand_call can identify them quickly. */
-#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT) ENUM,
+#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM) ENUM,
enum built_in_function
{
#include "builtins.def"
@@ -98,7 +101,8 @@ enum built_in_function
extern const char *const built_in_names[(int) END_BUILTINS];
/* An array of _DECL trees for the above. */
-extern tree built_in_decls[(int) END_BUILTINS];
+extern GTY(()) tree built_in_decls[(int) END_BUILTINS];
+extern GTY(()) tree implicit_built_in_decls[(int) END_BUILTINS];
/* The definition of tree nodes fills the next several pages. */
@@ -144,8 +148,8 @@ struct tree_common GTY(())
unsigned public_flag : 1;
unsigned private_flag : 1;
unsigned protected_flag : 1;
- unsigned bounded_flag : 1;
unsigned deprecated_flag : 1;
+ unsigned unused_1 : 1;
unsigned lang_flag_0 : 1;
unsigned lang_flag_1 : 1;
@@ -154,7 +158,7 @@ struct tree_common GTY(())
unsigned lang_flag_4 : 1;
unsigned lang_flag_5 : 1;
unsigned lang_flag_6 : 1;
- unsigned unused_1 : 1;
+ unsigned unused_2 : 1;
};
/* The following table lists the uses of each of the above flags and
@@ -164,7 +168,7 @@ struct tree_common GTY(())
addressable_flag:
TREE_ADDRESSABLE in
- VAR_DECL, FUNCTION_DECL, FIELD_DECL, CONSTRUCTOR, LABEL_DECL,
+ VAR_DECL, FUNCTION_DECL, FIELD_DECL, CONSTRUCTOR, LABEL_DECL,
..._TYPE, IDENTIFIER_NODE.
In a STMT_EXPR, it means we want the result of the enclosed
expression.
@@ -174,7 +178,7 @@ struct tree_common GTY(())
TREE_STATIC in
VAR_DECL, FUNCTION_DECL, CONSTRUCTOR, ADDR_EXPR
TREE_NO_UNUSED_WARNING in
- CONVERT_EXPR, NOP_EXPR, COMPOUND_EXPR, NON_LVALUE_EXPR
+ CONVERT_EXPR, NOP_EXPR, COMPOUND_EXPR
TREE_VIA_VIRTUAL in
TREE_LIST or TREE_VEC
TREE_CONSTANT_OVERFLOW in
@@ -191,26 +195,23 @@ struct tree_common GTY(())
INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST
TREE_PUBLIC in
VAR_DECL or FUNCTION_DECL or IDENTIFIER_NODE
- TREE_VIA_PUBLIC in
- TREE_LIST or TREE_VEC
EXPR_WFL_EMIT_LINE_NOTE in
EXPR_WITH_FILE_LOCATION
private_flag:
- TREE_VIA_PRIVATE in
- TREE_LIST or TREE_VEC
TREE_PRIVATE in
..._DECL
+ CALL_EXPR_HAS_RETURN_SLOT_ADDR in
+ CALL_EXPR
protected_flag:
- TREE_VIA_PROTECTED in
- TREE_LIST
- TREE_VEC
TREE_PROTECTED in
BLOCK
..._DECL
+ CALL_FROM_THUNK_P in
+ CALL_EXPR
side_effects_flag:
@@ -240,8 +241,6 @@ struct tree_common GTY(())
TREE_UNSIGNED in
INTEGER_TYPE, ENUMERAL_TYPE, FIELD_DECL
- DECL_BUILT_IN_NONANSI in
- FUNCTION_DECL
SAVE_EXPR_NOPLACEHOLDER in
SAVE_EXPR
@@ -261,18 +260,14 @@ struct tree_common GTY(())
TREE_NOTHROW in
CALL_EXPR, FUNCTION_DECL
- bounded_flag:
-
- TREE_BOUNDED in
- expressions, VAR_DECL, PARM_DECL, FIELD_DECL, FUNCTION_DECL,
- IDENTIFIER_NODE
- TYPE_BOUNDED in
+ TYPE_ALIGN_OK in
..._TYPE
deprecated_flag:
TREE_DEPRECATED in
..._DECL
+
*/
/* Define accessors for the fields that all tree nodes have
@@ -281,45 +276,37 @@ struct tree_common GTY(())
/* The tree-code says what kind of node it is.
Codes are defined in tree.def. */
#define TREE_CODE(NODE) ((enum tree_code) (NODE)->common.code)
-#define TREE_SET_CODE(NODE, VALUE) \
-((NODE)->common.code = (ENUM_BITFIELD (tree_code)) (VALUE))
+#define TREE_SET_CODE(NODE, VALUE) ((NODE)->common.code = (VALUE))
/* When checking is enabled, errors will be generated if a tree node
is accessed incorrectly. The macros abort with a fatal error. */
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
-#define TREE_CHECK(t, code) __extension__ \
-({ const tree __t = (t); \
- if (TREE_CODE(__t) != (code)) \
- tree_check_failed (__t, code, __FILE__, __LINE__, __FUNCTION__); \
+#define TREE_CHECK(T, CODE) __extension__ \
+({ const tree __t = (T); \
+ if (TREE_CODE (__t) != (CODE)) \
+ tree_check_failed (__t, (CODE), __FILE__, __LINE__, __FUNCTION__); \
__t; })
-#define TREE_CLASS_CHECK(t, class) __extension__ \
-({ const tree __t = (t); \
- if (TREE_CODE_CLASS(TREE_CODE(__t)) != (class)) \
- tree_class_check_failed (__t, class, __FILE__, __LINE__, \
+
+#define TREE_CLASS_CHECK(T, CLASS) __extension__ \
+({ const tree __t = (T); \
+ if (TREE_CODE_CLASS (TREE_CODE(__t)) != (CLASS)) \
+ tree_class_check_failed (__t, (CLASS), __FILE__, __LINE__, \
__FUNCTION__); \
__t; })
/* These checks have to be special cased. */
-#define CST_OR_CONSTRUCTOR_CHECK(t) __extension__ \
-({ const tree __t = (t); \
- enum tree_code const __c = TREE_CODE(__t); \
- if (__c != CONSTRUCTOR && TREE_CODE_CLASS(__c) != 'c') \
- tree_check_failed (__t, CONSTRUCTOR, __FILE__, __LINE__, \
- __FUNCTION__); \
- __t; })
-#define EXPR_CHECK(t) __extension__ \
-({ const tree __t = (t); \
- char const __c = TREE_CODE_CLASS(TREE_CODE(__t)); \
- if (__c != 'r' && __c != 's' && __c != '<' \
- && __c != '1' && __c != '2' && __c != 'e') \
+#define EXPR_CHECK(T) __extension__ \
+({ const tree __t = (T); \
+ char const __c = TREE_CODE_CLASS (TREE_CODE (__t)); \
+ if (!IS_EXPR_CODE_CLASS (__c)) \
tree_class_check_failed (__t, 'e', __FILE__, __LINE__, \
__FUNCTION__); \
__t; })
-#define TREE_VEC_ELT_CHECK(t, i) __extension__ \
-(*({const tree __t = t; \
- const int __i = (i); \
+#define TREE_VEC_ELT_CHECK(T, I) __extension__ \
+(*({const tree __t = (T); \
+ const int __i = (I); \
if (TREE_CODE (__t) != TREE_VEC) \
tree_check_failed (__t, TREE_VEC, \
__FILE__, __LINE__, __FUNCTION__); \
@@ -328,31 +315,68 @@ struct tree_common GTY(())
__FILE__, __LINE__, __FUNCTION__); \
&__t->vec.a[__i]; }))
-extern void tree_check_failed PARAMS ((const tree, enum tree_code,
- const char *, int, const char *))
+/* Special checks for TREE_OPERANDs. */
+#define TREE_OPERAND_CHECK(T, I) __extension__ \
+(*({const tree __t = EXPR_CHECK (T); \
+ const int __i = (I); \
+ if (__i < 0 || __i >= TREE_CODE_LENGTH (TREE_CODE (__t))) \
+ tree_operand_check_failed (__i, TREE_CODE (__t), \
+ __FILE__, __LINE__, __FUNCTION__); \
+ &__t->exp.operands[__i]; }))
+
+#define TREE_OPERAND_CHECK_CODE(T, CODE, I) __extension__ \
+(*({const tree __t = (T); \
+ const int __i = (I); \
+ if (TREE_CODE (__t) != CODE) \
+ tree_check_failed (__t, CODE, __FILE__, __LINE__, __FUNCTION__); \
+ if (__i < 0 || __i >= TREE_CODE_LENGTH (CODE)) \
+ tree_operand_check_failed (__i, (CODE), \
+ __FILE__, __LINE__, __FUNCTION__); \
+ &__t->exp.operands[__i]; }))
+
+#define TREE_RTL_OPERAND_CHECK(T, CODE, I) __extension__ \
+(*(rtx *) \
+ ({const tree __t = (T); \
+ const int __i = (I); \
+ if (TREE_CODE (__t) != (CODE)) \
+ tree_check_failed (__t, (CODE), __FILE__, __LINE__, __FUNCTION__); \
+ if (__i < 0 || __i >= TREE_CODE_LENGTH ((CODE))) \
+ tree_operand_check_failed (__i, (CODE), \
+ __FILE__, __LINE__, __FUNCTION__); \
+ &__t->exp.operands[__i]; }))
+
+extern void tree_check_failed (const tree, enum tree_code,
+ const char *, int, const char *)
ATTRIBUTE_NORETURN;
-extern void tree_class_check_failed PARAMS ((const tree, int,
- const char *, int, const char *))
+extern void tree_class_check_failed (const tree, int,
+ const char *, int, const char *)
ATTRIBUTE_NORETURN;
-extern void tree_vec_elt_check_failed PARAMS ((int, int, const char *,
- int, const char *))
+extern void tree_vec_elt_check_failed (int, int, const char *,
+ int, const char *)
+ ATTRIBUTE_NORETURN;
+
+extern void tree_operand_check_failed (int, enum tree_code,
+ const char *, int, const char *)
ATTRIBUTE_NORETURN;
#else /* not ENABLE_TREE_CHECKING, or not gcc */
-#define TREE_CHECK(t, code) (t)
-#define TREE_CLASS_CHECK(t, code) (t)
-#define CST_OR_CONSTRUCTOR_CHECK(t) (t)
-#define EXPR_CHECK(t) (t)
-#define TREE_VEC_ELT_CHECK(t, i) ((t)->vec.a[i])
+#define TREE_CHECK(T, CODE) (T)
+#define TREE_CLASS_CHECK(T, CODE) (T)
+#define EXPR_CHECK(T) (T)
+#define TREE_VEC_ELT_CHECK(T, I) ((T)->vec.a[I])
+#define TREE_OPERAND_CHECK(T, I) ((T)->exp.operands[I])
+#define TREE_OPERAND_CHECK_CODE(T, CODE, I) ((T)->exp.operands[I])
+#define TREE_RTL_OPERAND_CHECK(T, CODE, I) (*(rtx *) &((T)->exp.operands[I]))
#endif
#include "tree-check.h"
-#define TYPE_CHECK(tree) TREE_CLASS_CHECK (tree, 't')
-#define DECL_CHECK(tree) TREE_CLASS_CHECK (tree, 'd')
-#define CST_CHECK(tree) TREE_CLASS_CHECK (tree, 'c')
+#define TYPE_CHECK(T) TREE_CLASS_CHECK (T, 't')
+#define DECL_CHECK(T) TREE_CLASS_CHECK (T, 'd')
+#define CST_CHECK(T) TREE_CLASS_CHECK (T, 'c')
+#define STMT_CHECK(T) TREE_CLASS_CHECK (T, 's')
/* In all nodes that are expressions, this is the data type of the expression.
In POINTER_TYPE nodes, this is the type that the pointer points to.
@@ -400,6 +424,17 @@ extern void tree_vec_elt_check_failed PARAMS ((int, int, const char *,
== TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \
(EXP) = TREE_OPERAND (EXP, 0)
+/* Like STRIP_NOPS, but don't alter the TREE_TYPE main variant either. */
+
+#define STRIP_MAIN_TYPE_NOPS(EXP) \
+ while ((TREE_CODE (EXP) == NOP_EXPR \
+ || TREE_CODE (EXP) == CONVERT_EXPR \
+ || TREE_CODE (EXP) == NON_LVALUE_EXPR) \
+ && TREE_OPERAND (EXP, 0) != error_mark_node \
+ && (TYPE_MAIN_VARIANT (TREE_TYPE (EXP)) \
+ == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \
+ (EXP) = TREE_OPERAND (EXP, 0)
+
/* Like STRIP_NOPS, but don't alter the TREE_TYPE either. */
#define STRIP_TYPE_NOPS(EXP) \
@@ -418,13 +453,21 @@ extern void tree_vec_elt_check_failed PARAMS ((int, int, const char *,
(TREE_CODE (TYPE) == INTEGER_TYPE || TREE_CODE (TYPE) == ENUMERAL_TYPE \
|| TREE_CODE (TYPE) == BOOLEAN_TYPE || TREE_CODE (TYPE) == CHAR_TYPE)
+/* Nonzero if TYPE represents a scalar floating-point type. */
+
+#define SCALAR_FLOAT_TYPE_P(TYPE) (TREE_CODE (TYPE) == REAL_TYPE)
+
+/* Nonzero if TYPE represents a complex floating-point type. */
+
+#define COMPLEX_FLOAT_TYPE_P(TYPE) \
+ (TREE_CODE (TYPE) == COMPLEX_TYPE \
+ && TREE_CODE (TREE_TYPE (TYPE)) == REAL_TYPE)
+
/* Nonzero if TYPE represents a floating-point type, including complex
floating-point types. */
#define FLOAT_TYPE_P(TYPE) \
- (TREE_CODE (TYPE) == REAL_TYPE \
- || (TREE_CODE (TYPE) == COMPLEX_TYPE \
- && TREE_CODE (TREE_TYPE (TYPE)) == REAL_TYPE))
+ (SCALAR_FLOAT_TYPE_P (TYPE) || COMPLEX_FLOAT_TYPE_P (TYPE))
/* Nonzero if TYPE represents an aggregate (multi-component) type. */
@@ -433,56 +476,12 @@ extern void tree_vec_elt_check_failed PARAMS ((int, int, const char *,
|| TREE_CODE (TYPE) == UNION_TYPE || TREE_CODE (TYPE) == QUAL_UNION_TYPE \
|| TREE_CODE (TYPE) == SET_TYPE)
-/* Nonzero if TYPE represents an unbounded pointer or unbounded
- reference type. (It should be renamed to INDIRECT_TYPE_P.) */
+/* Nonzero if TYPE represents a pointer or reference type.
+ (It should be renamed to INDIRECT_TYPE_P.) */
#define POINTER_TYPE_P(TYPE) \
(TREE_CODE (TYPE) == POINTER_TYPE || TREE_CODE (TYPE) == REFERENCE_TYPE)
-/* Nonzero if TYPE represents a bounded pointer or bounded reference type. */
-
-#define BOUNDED_INDIRECT_TYPE_P(TYPE) \
- (TREE_CODE (TYPE) == RECORD_TYPE && TREE_TYPE (TYPE))
-
-/* Nonzero if TYPE represents a bounded pointer type. */
-
-#define BOUNDED_POINTER_TYPE_P(TYPE) \
- (BOUNDED_INDIRECT_TYPE_P (TYPE) \
- && TREE_CODE (TYPE_BOUNDED_SUBTYPE (TYPE)) == POINTER_TYPE)
-
-/* Nonzero if TYPE represents a bounded reference type. Bounded
- reference types have two specific uses: (1) When a reference is
- seated to a variable-length RECORD_TYPE that has an array of
- indeterminate length as its final field. For all other objects, it
- is sufficient to check bounds at the time the reference is seated,
- and assume that all future uses of the reference are safe, since
- the address of references cannot change. (2) When a reference
- supertype is seated to a subtype object. The bounds "remember"
- the true size of the complete object, so that subsequent upcasts of
- the address of the reference will be checked properly (is such a
- thing valid C++?). */
-
-#define BOUNDED_REFERENCE_TYPE_P(TYPE) \
- (BOUNDED_INDIRECT_TYPE_P (TYPE) \
- && TREE_CODE (TYPE_BOUNDED_SUBTYPE (TYPE)) == REFERENCE_TYPE)
-
-/* Nonzero if TYPE represents a pointer or reference type, either
- bounded or unbounded. */
-
-#define MAYBE_BOUNDED_INDIRECT_TYPE_P(TYPE) \
- (POINTER_TYPE_P (TYPE) || BOUNDED_INDIRECT_TYPE_P (TYPE))
-
-/* Nonzero if TYPE represents a pointer type, either bounded or unbounded. */
-
-#define MAYBE_BOUNDED_POINTER_TYPE_P(TYPE) \
- (TREE_CODE (TYPE) == POINTER_TYPE || BOUNDED_POINTER_TYPE_P (TYPE))
-
-/* Nonzero if TYPE represents a reference type, either bounded or
- unbounded. */
-
-#define MAYBE_BOUNDED_REFERENCE_TYPE_P(TYPE) \
- (TREE_CODE (TYPE) == REFERENCE_TYPE || BOUNDED_REFERENCE_TYPE_P (TYPE))
-
/* Nonzero if this type is a complete type. */
#define COMPLETE_TYPE_P(NODE) (TYPE_SIZE (NODE) != NULL_TREE)
@@ -562,20 +561,6 @@ extern void tree_vec_elt_check_failed PARAMS ((int, int, const char *,
for this name in an inner scope. */
#define TREE_PUBLIC(NODE) ((NODE)->common.public_flag)
-/* Nonzero for TREE_LIST or TREE_VEC node means that the path to the
- base class is via a `public' declaration, which preserves public
- fields from the base class as public. */
-#define TREE_VIA_PUBLIC(NODE) ((NODE)->common.public_flag)
-
-/* Ditto, for `private' declarations. */
-#define TREE_VIA_PRIVATE(NODE) ((NODE)->common.private_flag)
-
-/* Nonzero for TREE_LIST or TREE_VEC node means that the path to the
- base class is via a `protected' declaration, which preserves
- protected fields from the base class as protected.
- OVERLOADED. */
-#define TREE_VIA_PROTECTED(NODE) ((NODE)->common.protected_flag)
-
/* In any expression, nonzero means it has side effects or reevaluation
of the whole expression could produce a different value.
This is set if any subexpression is a function call, a side effect
@@ -602,7 +587,7 @@ extern void tree_vec_elt_check_failed PARAMS ((int, int, const char *,
when the node is a type). */
#define TREE_READONLY(NODE) ((NODE)->common.readonly_flag)
-/* Non-zero if NODE is a _DECL with TREE_READONLY set. */
+/* Nonzero if NODE is a _DECL with TREE_READONLY set. */
#define TREE_READONLY_DECL_P(NODE) (TREE_READONLY (NODE) && DECL_P (NODE))
/* Value of expression is constant.
@@ -612,8 +597,7 @@ extern void tree_vec_elt_check_failed PARAMS ((int, int, const char *,
#define TREE_CONSTANT(NODE) ((NODE)->common.constant_flag)
/* In INTEGER_TYPE or ENUMERAL_TYPE nodes, means an unsigned type.
- In FIELD_DECL nodes, means an unsigned bit field.
- The same bit is used in functions as DECL_BUILT_IN_NONANSI. */
+ In FIELD_DECL nodes, means an unsigned bit field. */
#define TREE_UNSIGNED(NODE) ((NODE)->common.unsigned_flag)
#define TYPE_TRAP_SIGNED(NODE) \
@@ -638,6 +622,14 @@ extern void tree_vec_elt_check_failed PARAMS ((int, int, const char *,
an exception. In a CALL_EXPR, nonzero means the call cannot throw. */
#define TREE_NOTHROW(NODE) ((NODE)->common.nothrow_flag)
+/* In a CALL_EXPR, means that the address of the return slot is part of the
+ argument list. */
+#define CALL_EXPR_HAS_RETURN_SLOT_ADDR(NODE) ((NODE)->common.private_flag)
+
+/* In a CALL_EXPR, means that the call is the jump from a thunk to the
+ thunked-to function. */
+#define CALL_FROM_THUNK_P(NODE) ((NODE)->common.protected_flag)
+
/* In a type, nonzero means that all objects of the type are guaranteed by the
language or front-end to be properly aligned, so we can indicate that a MEM
of this type is aligned at least to the alignment of the type, even if it
@@ -652,40 +644,6 @@ extern void tree_vec_elt_check_failed PARAMS ((int, int, const char *,
In a BLOCK node, this is BLOCK_HANDLER_BLOCK. */
#define TREE_PROTECTED(NODE) ((NODE)->common.protected_flag)
-/* In a ..._TYPE node, nonzero means that the type's size and layout,
- (or the size and layout of its arguments and/or return value in the
- case of a FUNCTION_TYPE or METHOD_TYPE) was changed by the presence
- of pointer bounds. Use TYPE_BOUNDED instead of this macro when the
- node is a type, because eventually we may make that a different
- bit. TYPE_BOUNDED doesn't mean that this type is a bounded indirect
- type--use BOUNDED_POINTER_TYPE_P, BOUNDED_REFERENCE_TYPE_P,
- BOUNDED_INDIRECT_TYPE_P to test for that.
-
- In a FUNCTION_DECL, nonzero means that the size and layout of one
- of its arguments and/or return value was changed by the presence of
- pointer bounds. This value can differ from the value of
- TYPE_BOUNDED (TREE_TYPE (fundecl)) if the function was implicitly
- declared, then later called with pointer args, or was declared with
- a variable argument list and is later called with pointer values in
- the variable argument list.
-
- In a VAR_DECL, PARM_DECL or FIELD_DECL, TREE_BOUNDED matches the value
- of the decl's type's BOUNDED_POINTER_TYPE_P.
-
- In a CONSTRUCTOR or other expression, nonzero means the value is a
- bounded pointer. It is insufficient to determine the boundedness
- of an expression EXP with BOUNDED_POINTER_TYPE_P (TREE_TYPE (EXP)),
- since we allow pointer to be temporarily cast to integer for
- rounding up to an alignment boudary in a way that preserves the
- pointer's bounds.
-
- In an IDENTIFIER_NODE, nonzero means that the name is prefixed with
- BP_PREFIX (see varasm.c). This occurs for the DECL_ASSEMBLER_NAME
- of a function that has bounded pointer(s) for its return type and/or
- argument type(s). */
-
-#define TREE_BOUNDED(NODE) ((NODE)->common.bounded_flag)
-
/* Nonzero in an IDENTIFIER_NODE if the use of the name is defined as a
deprecated feature by __attribute__((deprecated)). */
#define TREE_DEPRECATED(NODE) ((NODE)->common.deprecated_flag)
@@ -720,12 +678,10 @@ extern void tree_vec_elt_check_failed PARAMS ((int, int, const char *,
|| (((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (A) \
== (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (B)) \
&& TREE_INT_CST_LOW (A) < TREE_INT_CST_LOW (B)))
-
+
struct tree_int_cst GTY(())
{
struct tree_common common;
- rtx rtl; /* acts as link to register transfer language
- (rtl) info */
/* A sub-struct is necessary here because the function `const_hash'
wants to scan both words as a unit and taking the address of the
sub-struct yields the properly inclusive bounded pointer. */
@@ -735,12 +691,6 @@ struct tree_int_cst GTY(())
} int_cst;
};
-/* In REAL_CST, STRING_CST, COMPLEX_CST, VECTOR_CST nodes, and
- CONSTRUCTOR nodes, and generally in all kinds of constants that
- could be given labels (rather than being immediate). */
-
-#define TREE_CST_RTL(NODE) (CST_OR_CONSTRUCTOR_CHECK (NODE)->real_cst.rtl)
-
/* In a REAL_CST node. struct real_value is an opaque entity, with
manipulators defined in real.h. We don't want tree.h depending on
real.h and transitively on tm.h. */
@@ -752,7 +702,6 @@ struct real_value;
struct tree_real_cst GTY(())
{
struct tree_common common;
- rtx rtl; /* acts as link to register transfer language (rtl) info */
struct real_value * real_cst_ptr;
};
@@ -763,7 +712,6 @@ struct tree_real_cst GTY(())
struct tree_string GTY(())
{
struct tree_common common;
- rtx rtl; /* acts as link to register transfer language (rtl) info */
int length;
const char *pointer;
};
@@ -775,7 +723,6 @@ struct tree_string GTY(())
struct tree_complex GTY(())
{
struct tree_common common;
- rtx rtl; /* acts as link to register transfer language (rtl) info */
tree real;
tree imag;
};
@@ -786,7 +733,6 @@ struct tree_complex GTY(())
struct tree_vector GTY(())
{
struct tree_common common;
- rtx rtl;
tree elements;
};
@@ -842,52 +788,53 @@ struct tree_vec GTY(())
/* Define fields and accessors for some nodes that represent expressions. */
/* In a SAVE_EXPR node. */
-#define SAVE_EXPR_CONTEXT(NODE) TREE_OPERAND (SAVE_EXPR_CHECK (NODE), 1)
-#define SAVE_EXPR_RTL(NODE) (*(rtx *) &SAVE_EXPR_CHECK (NODE)->exp.operands[2])
+#define SAVE_EXPR_CONTEXT(NODE) TREE_OPERAND_CHECK_CODE (NODE, SAVE_EXPR, 1)
+#define SAVE_EXPR_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, SAVE_EXPR, 2)
+
#define SAVE_EXPR_NOPLACEHOLDER(NODE) TREE_UNSIGNED (SAVE_EXPR_CHECK (NODE))
/* Nonzero if the SAVE_EXPRs value should be kept, even if it occurs
both in normal code and in a handler. (Normally, in a handler, all
- SAVE_EXPRs are unsaved, meaning that there values are
+ SAVE_EXPRs are unsaved, meaning that their values are
recalculated.) */
#define SAVE_EXPR_PERSISTENT_P(NODE) TREE_ASM_WRITTEN (SAVE_EXPR_CHECK (NODE))
/* In a RTL_EXPR node. */
-#define RTL_EXPR_SEQUENCE(NODE) \
- (*(rtx *) &RTL_EXPR_CHECK (NODE)->exp.operands[0])
-#define RTL_EXPR_RTL(NODE) (*(rtx *) &RTL_EXPR_CHECK (NODE)->exp.operands[1])
+#define RTL_EXPR_SEQUENCE(NODE) TREE_RTL_OPERAND_CHECK (NODE, RTL_EXPR, 0)
+#define RTL_EXPR_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, RTL_EXPR, 1)
+#define RTL_EXPR_ALT_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, RTL_EXPR, 2)
/* In a WITH_CLEANUP_EXPR node. */
#define WITH_CLEANUP_EXPR_RTL(NODE) \
- (*(rtx *) &WITH_CLEANUP_EXPR_CHECK (NODE)->exp.operands[2])
+ TREE_RTL_OPERAND_CHECK (NODE, WITH_CLEANUP_EXPR, 2)
/* In a CONSTRUCTOR node. */
-#define CONSTRUCTOR_ELTS(NODE) TREE_OPERAND (CONSTRUCTOR_CHECK (NODE), 1)
+#define CONSTRUCTOR_ELTS(NODE) TREE_OPERAND_CHECK_CODE (NODE, CONSTRUCTOR, 0)
/* In ordinary expression nodes. */
-#define TREE_OPERAND(NODE, I) (EXPR_CHECK (NODE)->exp.operands[I])
+#define TREE_OPERAND(NODE, I) TREE_OPERAND_CHECK (NODE, I)
#define TREE_COMPLEXITY(NODE) (EXPR_CHECK (NODE)->exp.complexity)
/* In a LABELED_BLOCK_EXPR node. */
#define LABELED_BLOCK_LABEL(NODE) \
- TREE_OPERAND (LABELED_BLOCK_EXPR_CHECK (NODE), 0)
+ TREE_OPERAND_CHECK_CODE (NODE, LABELED_BLOCK_EXPR, 0)
#define LABELED_BLOCK_BODY(NODE) \
- TREE_OPERAND (LABELED_BLOCK_EXPR_CHECK (NODE), 1)
+ TREE_OPERAND_CHECK_CODE (NODE, LABELED_BLOCK_EXPR, 1)
/* In an EXIT_BLOCK_EXPR node. */
#define EXIT_BLOCK_LABELED_BLOCK(NODE) \
- TREE_OPERAND (EXIT_BLOCK_EXPR_CHECK (NODE), 0)
-#define EXIT_BLOCK_RETURN(NODE) TREE_OPERAND (EXIT_BLOCK_EXPR_CHECK (NODE), 1)
+ TREE_OPERAND_CHECK_CODE (NODE, EXIT_BLOCK_EXPR, 0)
+#define EXIT_BLOCK_RETURN(NODE) TREE_OPERAND_CHECK_CODE (NODE, EXIT_BLOCK_EXPR, 1)
/* In a LOOP_EXPR node. */
-#define LOOP_EXPR_BODY(NODE) TREE_OPERAND (LOOP_EXPR_CHECK (NODE), 0)
+#define LOOP_EXPR_BODY(NODE) TREE_OPERAND_CHECK_CODE (NODE, LOOP_EXPR, 0)
/* In an EXPR_WITH_FILE_LOCATION node. */
#define EXPR_WFL_EMIT_LINE_NOTE(NODE) \
(EXPR_WITH_FILE_LOCATION_CHECK (NODE)->common.public_flag)
#define EXPR_WFL_NODE(NODE) \
- TREE_OPERAND (EXPR_WITH_FILE_LOCATION_CHECK (NODE), 0)
+ TREE_OPERAND_CHECK_CODE (NODE, EXPR_WITH_FILE_LOCATION, 0)
#define EXPR_WFL_FILENAME_NODE(NODE) \
- TREE_OPERAND (EXPR_WITH_FILE_LOCATION_CHECK (NODE), 1)
+ TREE_OPERAND_CHECK_CODE (NODE, EXPR_WITH_FILE_LOCATION, 1)
#define EXPR_WFL_FILENAME(NODE) \
IDENTIFIER_POINTER (EXPR_WFL_FILENAME_NODE (NODE))
/* ??? Java uses this in all expressions. */
@@ -898,16 +845,16 @@ struct tree_vec GTY(())
(EXPR_WFL_LINECOL(NODE) = ((LINE) << 12) | ((COL) & 0xfff))
/* In a TARGET_EXPR node. */
-#define TARGET_EXPR_SLOT(NODE) TREE_OPERAND (TARGET_EXPR_CHECK (NODE), 0)
-#define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND (TARGET_EXPR_CHECK (NODE), 1)
-#define TARGET_EXPR_CLEANUP(NODE) TREE_OPERAND (TARGET_EXPR_CHECK (NODE), 2)
+#define TARGET_EXPR_SLOT(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 0)
+#define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 1)
+#define TARGET_EXPR_CLEANUP(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 2)
struct tree_exp GTY(())
{
struct tree_common common;
int complexity;
- tree GTY ((special ("tree_exp"),
- desc ("TREE_CODE ((tree) &%0)")))
+ tree GTY ((special ("tree_exp"),
+ desc ("TREE_CODE ((tree) &%0)")))
operands[1];
};
@@ -1008,26 +955,6 @@ struct tree_block GTY(())
structure containing an array. */
#define TYPE_DEBUG_REPRESENTATION_TYPE(NODE) (TYPE_CHECK (NODE)->type.values)
-/* Indirect types present difficulties because they may be represented
- as either POINTER_TYPE/REFERENCE_TYPE nodes (unbounded) or as
- RECORD_TYPE nodes (bounded). Bounded and unbounded pointers might
- be logically equivalent, but physically different. Simple
- comparison of the main variant only tells if the types are
- logically equivalent. Use this predicate to compare for physical
- equivalency. */
-
-/* Types have the same main variant, and have the same boundedness. */
-#define TYPE_MAIN_VARIANTS_PHYSICALLY_EQUAL_P(TYPE1, TYPE2) \
- (TYPE_MAIN_VARIANT (TYPE1) == TYPE_MAIN_VARIANT (TYPE2) \
- && TREE_CODE (TYPE1) == TREE_CODE (TYPE2))
-
-/* Return the type variant that has no qualifiers (i.e., the main variant),
- except that the boundedness qualifier is preserved. */
-#define TYPE_MAIN_PHYSICAL_VARIANT(TYPE) \
- (BOUNDED_POINTER_TYPE_P (TYPE) \
- ? build_qualified_type (TYPE, TYPE_QUAL_BOUNDED) \
- : TYPE_MAIN_VARIANT (TYPE))
-
/* For aggregate types, information about this type, as a base type
for itself. Used in a language-dependent way for types that are
neither a RECORD_TYPE, QUAL_UNION_TYPE, nor a UNION_TYPE. */
@@ -1099,11 +1026,6 @@ struct tree_block GTY(())
the term. */
#define TYPE_RESTRICT(NODE) (TYPE_CHECK (NODE)->type.restrict_flag)
-/* If nonzero, this type's size and layout, (or the size and layout of
- its arguments and/or return value in the case of a FUNCTION_TYPE or
- METHOD_TYPE) was changed by the presence of pointer bounds. */
-#define TYPE_BOUNDED(NODE) (TYPE_CHECK (NODE)->common.bounded_flag)
-
/* There is a TYPE_QUAL value for each type qualifier. They can be
combined by bitwise-or to form the complete set of qualifiers for a
type. */
@@ -1112,25 +1034,12 @@ struct tree_block GTY(())
#define TYPE_QUAL_CONST 0x1
#define TYPE_QUAL_VOLATILE 0x2
#define TYPE_QUAL_RESTRICT 0x4
-#define TYPE_QUAL_BOUNDED 0x8
/* The set of type qualifiers for this type. */
#define TYPE_QUALS(NODE) \
((TYPE_READONLY (NODE) * TYPE_QUAL_CONST) \
| (TYPE_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \
- | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT) \
- | (BOUNDED_INDIRECT_TYPE_P (NODE) * TYPE_QUAL_BOUNDED))
-
-/* The set of qualifiers pertinent to an expression node. */
-#define TREE_EXPR_QUALS(NODE) \
- ((TREE_READONLY (NODE) * TYPE_QUAL_CONST) \
- | (TREE_THIS_VOLATILE (NODE) * TYPE_QUAL_VOLATILE) \
- | (TREE_BOUNDED (NODE) * TYPE_QUAL_BOUNDED))
-
-/* The set of qualifiers pertinent to a FUNCTION_DECL node. */
-#define TREE_FUNC_QUALS(NODE) \
- ((TREE_READONLY (NODE) * TYPE_QUAL_CONST) \
- | (TREE_THIS_VOLATILE (NODE) * TYPE_QUAL_VOLATILE))
+ | (TYPE_RESTRICT (NODE) * TYPE_QUAL_RESTRICT))
/* These flags are available for each language front end to use internally. */
#define TYPE_LANG_FLAG_0(NODE) (TYPE_CHECK (NODE)->type.lang_flag_0)
@@ -1175,65 +1084,6 @@ struct tree_block GTY(())
compact a way as possible. */
#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->type.packed_flag)
-/* A bounded pointer or bounded reference type (collectively called
- indirect types) is represented as a RECORD_TYPE node containing
- three pointer fields whose type is the corresponding unbounded
- POINTER_TYPE or REFERENCE_TYPE. A RECORD_TYPE node that represents
- a bounded indirect type differs from a normal RECORD_TYPE node in
- that its TREE_TYPE is non-NULL and has the pointed-to type just as
- a POINTER_TYPE or REFERENCE_TYPE node has. The bounded RECORD_TYPE
- nodes are stored on the same type variant chain alongside the
- variants of the underlaying indirect types nodes. The main variant
- of such chains is always the unbounded type. */
-
-/* Access the field decls of a bounded-pointer type. */
-#define TYPE_BOUNDED_VALUE(TYPE) TYPE_FIELDS (TYPE)
-#define TYPE_BOUNDED_BASE(TYPE) TREE_CHAIN (TYPE_BOUNDED_VALUE (TYPE))
-#define TYPE_BOUNDED_EXTENT(TYPE) TREE_CHAIN (TYPE_BOUNDED_BASE (TYPE))
-
-/* Access the simple-pointer subtype of a bounded-pointer type. */
-#define TYPE_BOUNDED_SUBTYPE(TYPE) TREE_TYPE (TYPE_BOUNDED_VALUE (TYPE))
-
-/* Find the unbounded counterpart to a type, or return TYPE if it is
- already unbounded. */
-#define TYPE_UNBOUNDED_VARIANT(TYPE) \
- (BOUNDED_POINTER_TYPE_P (TYPE) ? TYPE_BOUNDED_SUBTYPE (TYPE) : (TYPE))
-
-/* This field comprises two bits, for values in the range 0..3:
-
- depth=0 means that type is a scalar, or an aggregate that contains
- only depth=0 types, or a function that has only depth=0 types for
- its return value and argument types.
-
- depth=1 means that type is a pointer to a depth=0 type, or an
- aggregate that contains only depth=0 and depth=1 types, or a
- function that has only depth=0 and depth=1 types for its return
- value and argument types.
-
- The meanings of depth=2 and depth=3 are obvious by induction.
- Varargs functions are depth=3. The type `va_list' is depth=3.
-
- The purpose of measuring pointer depth of a type is to determine
- the eligibility of a function for an automatically-generated
- bounded-pointer thunk. A depth=0 functions needs no thunk. A
- depth=1 function is eligible for an automatic thunk. Functions
- with depth 2 or more are too complex to get automatic thunks.
-
- Function decls also have a pointer_depth field, since we also
- consider the actual argument types for functions. */
-
-#define TYPE_POINTER_DEPTH(TYPE) (TYPE_CHECK (TYPE)->type.pointer_depth)
-
-/* In a FUNCTION_TYPE node, this bit stores the value of
- default_pointer_boundedness at the time TYPE was created. It is
- useful for choosing default boundedness of function arguments for
- non-prototype function decls and for varargs/stdarg lists. */
-#define TYPE_AMBIENT_BOUNDEDNESS(TYPE) \
- (FUNCTION_TYPE_CHECK (TYPE)->type.transparent_union_flag)
-
-#define MAX_POINTER_DEPTH 2
-#define VA_LIST_POINTER_DEPTH 3
-
struct die_struct;
struct tree_type GTY(())
@@ -1254,7 +1104,7 @@ struct tree_type GTY(())
unsigned transparent_union_flag : 1;
unsigned packed_flag : 1;
unsigned restrict_flag : 1;
- unsigned pointer_depth : 2;
+ unsigned spare : 2;
unsigned lang_flag_0 : 1;
unsigned lang_flag_1 : 1;
@@ -1269,10 +1119,10 @@ struct tree_type GTY(())
tree pointer_to;
tree reference_to;
union tree_type_symtab {
- int address;
- char * GTY ((tag ("1"))) pointer;
- struct die_struct * GTY ((tag ("2"), skip (""))) die;
- } GTY ((desc ("debug_hooks == &sdb_debug_hooks ? 1 : debug_hooks == &dwarf2_debug_hooks ? 2 : 0"),
+ int GTY ((tag ("0"))) address;
+ char * GTY ((tag ("1"))) pointer;
+ struct die_struct * GTY ((tag ("2"))) die;
+ } GTY ((desc ("debug_hooks == &sdb_debug_hooks ? 1 : debug_hooks == &dwarf2_debug_hooks ? 2 : 0"),
descbits ("2"))) symtab;
tree name;
tree minval;
@@ -1352,19 +1202,21 @@ struct tree_type GTY(())
/* For a BINFO record describing a virtual base class, i.e., one where
TREE_VIA_VIRTUAL is set, this field assists in locating the virtual
- base. The actual contents are language-dependent. Under the old
- ABI, the C++ front-end uses a FIELD_DECL whose contents are a
- pointer to the virtual base; under the new ABI this field is
- instead an INTEGER_CST giving an offset into the vtable where the
- offset to the virtual base can be found. */
+ base. The actual contents are language-dependent. In the C++
+ front-end this field is an INTEGER_CST giving an offset into the
+ vtable where the offset to the virtual base can be found. */
#define BINFO_VPTR_FIELD(NODE) TREE_VEC_ELT (NODE, 5)
-/* The size of a base class subobject of this type. Not all frontends
- currently allocate the space for these fields. */
-#define BINFO_SIZE(NODE) TREE_VEC_ELT (NODE, 6)
-#define BINFO_SIZE_UNIT(NODE) TREE_VEC_ELT (NODE, 7)
-#define TYPE_BINFO_SIZE(NODE) BINFO_SIZE (TYPE_BINFO (NODE))
-#define TYPE_BINFO_SIZE_UNIT(NODE) BINFO_SIZE_UNIT (TYPE_BINFO (NODE))
+/* Indicates the accesses this binfo has to its bases. The values are
+ access_public_node, access_protected_node or access_private_node.
+ If this array is not present, public access is implied. */
+#define BINFO_BASEACCESSES(NODE) TREE_VEC_ELT ((NODE), 6)
+#define BINFO_BASEACCESS(NODE,N) TREE_VEC_ELT (BINFO_BASEACCESSES(NODE), (N))
+
+/* Number of language independent elements in a binfo. Languages may
+ add additional trailing elements. */
+
+#define BINFO_ELTS 7
/* Slot used to build a chain that represents a use of inheritance.
For example, if X is derived from Y, and Y is derived from Z,
@@ -1422,12 +1274,13 @@ struct tree_type GTY(())
the name from decl_attributes to make_function_rtl and make_decl_rtl. */
#define DECL_SECTION_NAME(NODE) (DECL_CHECK (NODE)->decl.section_name)
-/* For FIELD_DECLs, this is the
- RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE node that the field is
- a member of. For VAR_DECL, PARM_DECL, FUNCTION_DECL, LABEL_DECL,
- and CONST_DECL nodes, this points to either the FUNCTION_DECL for the
- containing function, the RECORD_TYPE or UNION_TYPE for the containing
- type, or NULL_TREE if the given decl has "file scope". */
+/* For FIELD_DECLs, this is the RECORD_TYPE, UNION_TYPE, or
+ QUAL_UNION_TYPE node that the field is a member of. For VAR_DECL,
+ PARM_DECL, FUNCTION_DECL, LABEL_DECL, and CONST_DECL nodes, this
+ points to either the FUNCTION_DECL for the containing function,
+ the RECORD_TYPE or UNION_TYPE for the containing type, or
+ NULL_TREE or a TRANSLATION_UNIT_DECL if the given decl has "file
+ scope". */
#define DECL_CONTEXT(NODE) (DECL_CHECK (NODE)->decl.context)
#define DECL_FIELD_CONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->decl.context)
/* In a DECL this is the field where attributes are stored. */
@@ -1456,6 +1309,7 @@ struct tree_type GTY(())
/* In PARM_DECL, holds the type as written (perhaps a function or array). */
#define DECL_ARG_TYPE_AS_WRITTEN(NODE) (PARM_DECL_CHECK (NODE)->decl.result)
/* For a FUNCTION_DECL, holds the tree of BINDINGs.
+ For a TRANSLATION_UNIT_DECL, holds the namespace's BLOCK.
For a VAR_DECL, holds the initial value.
For a PARM_DECL, not used--default
values for parameters are encoded in the type of the function,
@@ -1499,12 +1353,7 @@ struct tree_type GTY(())
field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a
FIELD_DECL. */
#define DECL_MODE(NODE) (DECL_CHECK (NODE)->decl.mode)
-/* Holds the RTL expression for the value of a variable or function. If
- PROMOTED_MODE is defined, the mode of this expression may not be same
- as DECL_MODE. In that case, DECL_MODE contains the mode corresponding
- to the variable's data type, while the mode
- of DECL_RTL is the mode actually used to contain the data.
-
+/* Holds the RTL expression for the value of a variable or function.
This value can be evaluated lazily for functions, variables with
static storage duration, and labels. */
#define DECL_RTL(NODE) \
@@ -1512,7 +1361,7 @@ struct tree_type GTY(())
? (NODE)->decl.rtl \
: (make_decl_rtl (NODE, NULL), (NODE)->decl.rtl))
/* Set the DECL_RTL for NODE to RTL. */
-#define SET_DECL_RTL(NODE, RTL) (DECL_CHECK (NODE)->decl.rtl = (RTL))
+#define SET_DECL_RTL(NODE, RTL) set_decl_rtl (NODE, RTL)
/* Returns nonzero if the DECL_RTL for NODE has already been set. */
#define DECL_RTL_SET_P(NODE) (DECL_CHECK (NODE)->decl.rtl != NULL)
/* Copy the RTL from NODE1 to NODE2. If the RTL was not set for
@@ -1522,10 +1371,6 @@ struct tree_type GTY(())
/* The DECL_RTL for NODE, if it is set, or NULL, if it is not set. */
#define DECL_RTL_IF_SET(NODE) (DECL_RTL_SET_P (NODE) ? DECL_RTL (NODE) : NULL)
-/* Holds an INSN_LIST of all of the live ranges in which the variable
- has been moved to a possibly different register. */
-#define DECL_LIVE_RANGE_RTL(NODE) (DECL_CHECK (NODE)->decl.live_range_rtl)
-
/* For PARM_DECL, holds an RTL for the stack slot or register
where the data was actually passed. */
#define DECL_INCOMING_RTL(NODE) (PARM_DECL_CHECK (NODE)->decl.u2.r)
@@ -1604,7 +1449,7 @@ struct tree_type GTY(())
#define DECL_EXTERNAL(NODE) (DECL_CHECK (NODE)->decl.external_flag)
/* In a VAR_DECL for a RECORD_TYPE, sets number for non-init_priority
- initializatons. */
+ initializations. */
#define DEFAULT_INIT_PRIORITY 65535
#define MAX_INIT_PRIORITY 65535
#define MAX_RESERVED_INIT_PRIORITY 100
@@ -1644,10 +1489,15 @@ struct tree_type GTY(())
where it is called. */
#define DECL_INLINE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.inline_flag)
-/* Nonzero in a FUNCTION_DECL means this function has been found inlinable
- only by virtue of -finline-functions */
-#define DID_INLINE_FUNC(NODE) \
- (FUNCTION_DECL_CHECK (NODE)->decl.inlined_function_flag)
+/* Nonzero in a FUNCTION_DECL means that this function was declared inline,
+ such as via the `inline' keyword in C/C++. This flag controls the linkage
+ semantics of 'inline'; whether or not the function is inlined is
+ controlled by DECL_INLINE. */
+#define DECL_DECLARED_INLINE_P(NODE) \
+ (FUNCTION_DECL_CHECK (NODE)->decl.declared_inline_flag)
+
+/* Value of the decls's visibility attribute */
+#define DECL_VISIBILITY(NODE) (DECL_CHECK (NODE)->decl.visibility)
/* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */
#define DECL_UNINLINABLE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.uninlinable)
@@ -1664,12 +1514,6 @@ struct tree_type GTY(())
/* List of FUNCTION_DECLs inlined into this function's body. */
#define DECL_INLINED_FNS(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.inlined_fns)
-/* Nonzero in a FUNCTION_DECL means this is a built-in function
- that is not specified by ansi C and that users are supposed to be allowed
- to redefine for any purpose whatever. */
-#define DECL_BUILT_IN_NONANSI(NODE) \
- (FUNCTION_DECL_CHECK (NODE)->common.unsigned_flag)
-
/* Nonzero in a FUNCTION_DECL means this function should be treated
as if it were a malloc, meaning it returns a pointer that is
not an alias. */
@@ -1783,15 +1627,20 @@ struct tree_type GTY(())
#define DECL_POINTER_ALIAS_SET_KNOWN_P(NODE) \
(DECL_POINTER_ALIAS_SET (NODE) != - 1)
-/* The pointer_depth field comprises two bits for values in the range
- 0..3. The value is normally equal to TYPE_POINTER_DEPTH of decl's
- type node, but for functions it migth be greater. For example,
- this can happen when the function is declared to accept a parameter
- of type void* (depth=1), but is actually called with an argument of
- type foo** (depth=2). The function type will get the formal
- parameter's depth, but the function decl will get the actual
- argument's depth. */
-#define DECL_POINTER_DEPTH(DECL) (DECL_CHECK (DECL)->decl.pointer_depth)
+/* Nonzero for a decl which is at file scope. */
+#define DECL_FILE_SCOPE_P(EXP) \
+ (! DECL_CONTEXT (EXP) \
+ || TREE_CODE (DECL_CONTEXT (EXP)) == TRANSLATION_UNIT_DECL)
+
+/* Enumerate visibility settings. */
+
+enum symbol_visibility
+{
+ VISIBILITY_DEFAULT,
+ VISIBILITY_INTERNAL,
+ VISIBILITY_HIDDEN,
+ VISIBILITY_PROTECTED
+};
struct function;
@@ -1829,13 +1678,14 @@ struct tree_decl GTY(())
ENUM_BITFIELD(built_in_class) built_in_class : 2;
unsigned pure_flag : 1;
- unsigned pointer_depth : 2;
unsigned non_addressable : 1;
unsigned user_align : 1;
unsigned uninlinable : 1;
unsigned thread_local_flag : 1;
- unsigned inlined_function_flag : 1;
- /* One unused bit. */
+ unsigned declared_inline_flag : 1;
+ ENUM_BITFIELD(symbol_visibility) visibility : 2;
+ unsigned unused : 1;
+ /* one unused bit. */
unsigned lang_flag_0 : 1;
unsigned lang_flag_1 : 1;
@@ -1856,7 +1706,7 @@ struct tree_decl GTY(())
/* DECL_ALIGN and DECL_OFFSET_ALIGN. (These are not used for
FUNCTION_DECLs). */
struct tree_decl_u1_a {
- unsigned int align : 24;
+ unsigned int align : 24;
unsigned int off_align : 8;
} a;
} GTY ((skip (""))) u1;
@@ -1872,7 +1722,6 @@ struct tree_decl GTY(())
tree section_name;
tree attributes;
rtx rtl; /* RTL representation for object. */
- rtx live_range_rtl;
/* In FUNCTION_DECL, if it is inline, holds the saved insn chain.
In FIELD_DECL, is DECL_FIELD_BIT_OFFSET.
@@ -1883,7 +1732,7 @@ struct tree_decl GTY(())
struct function * GTY ((tag ("FUNCTION_DECL"))) f;
rtx GTY ((tag ("PARM_DECL"))) r;
tree GTY ((tag ("FIELD_DECL"))) t;
- int i;
+ int GTY ((tag ("VAR_DECL"))) i;
} GTY ((desc ("TREE_CODE((tree) &(%0))"))) u2;
/* In a FUNCTION_DECL, this is DECL_SAVED_TREE. */
@@ -1967,6 +1816,13 @@ enum tree_index
TI_BITSIZE_ONE,
TI_BITSIZE_UNIT,
+ TI_PUBLIC,
+ TI_PROTECTED,
+ TI_PRIVATE,
+
+ TI_BOOLEAN_FALSE,
+ TI_BOOLEAN_TRUE,
+
TI_COMPLEX_INTEGER_TYPE,
TI_COMPLEX_FLOAT_TYPE,
TI_COMPLEX_DOUBLE_TYPE,
@@ -1976,12 +1832,18 @@ enum tree_index
TI_DOUBLE_TYPE,
TI_LONG_DOUBLE_TYPE,
+ TI_FLOAT_PTR_TYPE,
+ TI_DOUBLE_PTR_TYPE,
+ TI_LONG_DOUBLE_PTR_TYPE,
+ TI_INTEGER_PTR_TYPE,
+
TI_VOID_TYPE,
TI_PTR_TYPE,
TI_CONST_PTR_TYPE,
TI_SIZE_TYPE,
TI_PTRDIFF_TYPE,
TI_VA_LIST_TYPE,
+ TI_BOOLEAN_TYPE,
TI_VOID_LIST_NODE,
@@ -2010,6 +1872,7 @@ enum tree_index
TI_V2DI_TYPE,
TI_V1DI_TYPE,
TI_V16QI_TYPE,
+ TI_V4DF_TYPE,
TI_MAIN_IDENTIFIER,
@@ -2041,12 +1904,22 @@ extern GTY(()) tree global_trees[TI_MAX];
#define bitsize_one_node global_trees[TI_BITSIZE_ONE]
#define bitsize_unit_node global_trees[TI_BITSIZE_UNIT]
+/* Base access nodes. */
+#define access_public_node global_trees[TI_PUBLIC]
+#define access_protected_node global_trees[TI_PROTECTED]
+#define access_private_node global_trees[TI_PRIVATE]
+
#define null_pointer_node global_trees[TI_NULL_POINTER]
#define float_type_node global_trees[TI_FLOAT_TYPE]
#define double_type_node global_trees[TI_DOUBLE_TYPE]
#define long_double_type_node global_trees[TI_LONG_DOUBLE_TYPE]
+#define float_ptr_type_node global_trees[TI_FLOAT_PTR_TYPE]
+#define double_ptr_type_node global_trees[TI_DOUBLE_PTR_TYPE]
+#define long_double_ptr_type_node global_trees[TI_LONG_DOUBLE_PTR_TYPE]
+#define integer_ptr_type_node global_trees[TI_INTEGER_PTR_TYPE]
+
#define complex_integer_type_node global_trees[TI_COMPLEX_INTEGER_TYPE]
#define complex_float_type_node global_trees[TI_COMPLEX_FLOAT_TYPE]
#define complex_double_type_node global_trees[TI_COMPLEX_DOUBLE_TYPE]
@@ -2062,6 +1935,10 @@ extern GTY(()) tree global_trees[TI_MAX];
#define ptrdiff_type_node global_trees[TI_PTRDIFF_TYPE]
#define va_list_type_node global_trees[TI_VA_LIST_TYPE]
+#define boolean_type_node global_trees[TI_BOOLEAN_TYPE]
+#define boolean_false_node global_trees[TI_BOOLEAN_FALSE]
+#define boolean_true_node global_trees[TI_BOOLEAN_TRUE]
+
/* The node that should be placed at the end of a parameter list to
indicate that the function does not take a variable number of
arguments. The TREE_VALUE will be void_type_node and there will be
@@ -2095,6 +1972,7 @@ extern GTY(()) tree global_trees[TI_MAX];
#define V2DF_type_node global_trees[TI_V2DF_TYPE]
#define V16SF_type_node global_trees[TI_V16SF_TYPE]
#define V1DI_type_node global_trees[TI_V1DI_TYPE]
+#define V4DF_type_node global_trees[TI_V4DF_TYPE]
/* An enumeration of the standard C integer types. These must be
ordered so that shorter types appear before longer ones, and so
@@ -2145,15 +2023,6 @@ enum tls_model {
extern enum tls_model flag_tls_default;
-/* Enumerate visibility settings. */
-
-enum symbol_visibility
-{
- VISIBILITY_DEFAULT,
- VISIBILITY_INTERNAL,
- VISIBILITY_HIDDEN,
- VISIBILITY_PROTECTED
-};
/* A pointer-to-function member type looks like:
@@ -2184,113 +2053,120 @@ enum ptrmemfunc_vbit_where_t
#define NULL_TREE (tree) NULL
-/* Approximate positive square root of a host double. This is for
- statistical reports, not code generation. */
-extern double approx_sqrt PARAMS ((double));
-
-extern tree decl_assembler_name PARAMS ((tree));
+extern tree decl_assembler_name (tree);
/* Compute the number of bytes occupied by 'node'. This routine only
looks at TREE_CODE and, if the code is TREE_VEC, TREE_VEC_LENGTH. */
-extern size_t tree_size PARAMS ((tree));
+extern size_t tree_size (tree);
/* Lowest level primitive for allocating a node.
The TREE_CODE is the only argument. Contents are initialized
to zero except for a few of the common fields. */
-extern tree make_node PARAMS ((enum tree_code));
+extern tree make_node (enum tree_code);
/* Make a copy of a node, with all the same contents. */
-extern tree copy_node PARAMS ((tree));
+extern tree copy_node (tree);
/* Make a copy of a chain of TREE_LIST nodes. */
-extern tree copy_list PARAMS ((tree));
+extern tree copy_list (tree);
/* Make a TREE_VEC. */
-extern tree make_tree_vec PARAMS ((int));
+extern tree make_tree_vec (int);
/* Return the (unique) IDENTIFIER_NODE node for a given name.
The name is supplied as a char *. */
-extern tree get_identifier PARAMS ((const char *));
+extern tree get_identifier (const char *);
+
+#if GCC_VERSION >= 3000
+#define get_identifier(str) \
+ (__builtin_constant_p (str) \
+ ? get_identifier_with_length ((str), strlen (str)) \
+ : get_identifier (str))
+#endif
+
/* Identical to get_identifier, except that the length is assumed
known. */
-extern tree get_identifier_with_length PARAMS ((const char *, unsigned int));
+extern tree get_identifier_with_length (const char *, size_t);
/* If an identifier with the name TEXT (a null-terminated string) has
previously been referred to, return that node; otherwise return
NULL_TREE. */
-extern tree maybe_get_identifier PARAMS ((const char *));
+extern tree maybe_get_identifier (const char *);
/* Construct various types of nodes. */
#define build_int_2(LO, HI) \
build_int_2_wide ((unsigned HOST_WIDE_INT) (LO), (HOST_WIDE_INT) (HI))
-extern tree build PARAMS ((enum tree_code, tree, ...));
-extern tree build_nt PARAMS ((enum tree_code, ...));
-
-extern tree build_int_2_wide PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT));
-extern tree build_vector PARAMS ((tree, tree));
-extern tree build_real_from_int_cst PARAMS ((tree, tree));
-extern tree build_complex PARAMS ((tree, tree, tree));
-extern tree build_string PARAMS ((int, const char *));
-extern tree build1 PARAMS ((enum tree_code, tree, tree));
-extern tree build_tree_list PARAMS ((tree, tree));
-extern tree build_decl PARAMS ((enum tree_code, tree, tree));
-extern tree build_block PARAMS ((tree, tree, tree, tree, tree));
-extern tree build_expr_wfl PARAMS ((tree, const char *, int, int));
+extern tree build (enum tree_code, tree, ...);
+extern tree build_nt (enum tree_code, ...);
+
+extern tree build_int_2_wide (unsigned HOST_WIDE_INT, HOST_WIDE_INT);
+extern tree build_vector (tree, tree);
+extern tree build_constructor (tree, tree);
+extern tree build_real_from_int_cst (tree, tree);
+extern tree build_complex (tree, tree, tree);
+extern tree build_string (int, const char *);
+extern tree build1 (enum tree_code, tree, tree);
+extern tree build_tree_list (tree, tree);
+extern tree build_decl (enum tree_code, tree, tree);
+extern tree build_block (tree, tree, tree, tree, tree);
+extern tree build_expr_wfl (tree, const char *, int, int);
/* Construct various nodes representing data types. */
-extern tree make_signed_type PARAMS ((int));
-extern tree make_unsigned_type PARAMS ((int));
-extern void initialize_sizetypes PARAMS ((void));
-extern void set_sizetype PARAMS ((tree));
-extern void fixup_unsigned_type PARAMS ((tree));
-extern tree build_pointer_type PARAMS ((tree));
-extern tree build_reference_type PARAMS ((tree));
-extern tree build_type_no_quals PARAMS ((tree));
-extern tree build_index_type PARAMS ((tree));
-extern tree build_index_2_type PARAMS ((tree, tree));
-extern tree build_array_type PARAMS ((tree, tree));
-extern tree build_function_type PARAMS ((tree, tree));
-extern tree build_function_type_list PARAMS ((tree, ...));
-extern tree build_method_type PARAMS ((tree, tree));
-extern tree build_offset_type PARAMS ((tree, tree));
-extern tree build_complex_type PARAMS ((tree));
-extern tree array_type_nelts PARAMS ((tree));
-
-extern tree value_member PARAMS ((tree, tree));
-extern tree purpose_member PARAMS ((tree, tree));
-extern tree binfo_member PARAMS ((tree, tree));
-extern unsigned int attribute_hash_list PARAMS ((tree));
-extern int attribute_list_equal PARAMS ((tree, tree));
-extern int attribute_list_contained PARAMS ((tree, tree));
-extern int tree_int_cst_equal PARAMS ((tree, tree));
-extern int tree_int_cst_lt PARAMS ((tree, tree));
-extern int tree_int_cst_compare PARAMS ((tree, tree));
-extern int host_integerp PARAMS ((tree, int));
-extern HOST_WIDE_INT tree_low_cst PARAMS ((tree, int));
-extern int tree_int_cst_msb PARAMS ((tree));
-extern int tree_int_cst_sgn PARAMS ((tree));
-extern int tree_expr_nonnegative_p PARAMS ((tree));
-extern int rtl_expr_nonnegative_p PARAMS ((rtx));
-extern int index_type_equal PARAMS ((tree, tree));
-extern tree get_inner_array_type PARAMS ((tree));
+extern tree make_signed_type (int);
+extern tree make_unsigned_type (int);
+extern void initialize_sizetypes (void);
+extern void set_sizetype (tree);
+extern void fixup_unsigned_type (tree);
+extern tree build_pointer_type_for_mode (tree, enum machine_mode);
+extern tree build_pointer_type (tree);
+extern tree build_reference_type_for_mode (tree, enum machine_mode);
+extern tree build_reference_type (tree);
+extern tree build_type_no_quals (tree);
+extern tree build_index_type (tree);
+extern tree build_index_2_type (tree, tree);
+extern tree build_array_type (tree, tree);
+extern tree build_function_type (tree, tree);
+extern tree build_function_type_list (tree, ...);
+extern tree build_method_type_directly (tree, tree, tree);
+extern tree build_method_type (tree, tree);
+extern tree build_offset_type (tree, tree);
+extern tree build_complex_type (tree);
+extern tree array_type_nelts (tree);
+
+extern tree value_member (tree, tree);
+extern tree purpose_member (tree, tree);
+extern tree binfo_member (tree, tree);
+extern unsigned int attribute_hash_list (tree);
+extern int attribute_list_equal (tree, tree);
+extern int attribute_list_contained (tree, tree);
+extern int tree_int_cst_equal (tree, tree);
+extern int tree_int_cst_lt (tree, tree);
+extern int tree_int_cst_compare (tree, tree);
+extern int host_integerp (tree, int);
+extern HOST_WIDE_INT tree_low_cst (tree, int);
+extern int tree_int_cst_msb (tree);
+extern int tree_int_cst_sgn (tree);
+extern int tree_expr_nonnegative_p (tree);
+extern int rtl_expr_nonnegative_p (rtx);
+extern tree get_inner_array_type (tree);
/* From expmed.c. Since rtl.h is included after tree.h, we can't
put the prototype here. Rtl.h does declare the prototype if
tree.h had been included. */
-extern tree make_tree PARAMS ((tree, rtx));
+extern tree make_tree (tree, rtx);
/* Return a type like TTYPE except that its TYPE_ATTRIBUTES
is ATTRIBUTE.
@@ -2298,8 +2174,8 @@ extern tree make_tree PARAMS ((tree, rtx));
Such modified types already made are recorded so that duplicates
are not made. */
-extern tree build_type_attribute_variant PARAMS ((tree, tree));
-extern tree build_decl_attribute_variant PARAMS ((tree, tree));
+extern tree build_type_attribute_variant (tree, tree);
+extern tree build_decl_attribute_variant (tree, tree);
/* Structure describing an attribute and a function to handle it. */
struct attribute_spec
@@ -2342,8 +2218,8 @@ struct attribute_spec
otherwise the return value should be NULL_TREE. This pointer may be
NULL if no special handling is required beyond the checks implied
by the rest of this structure. */
- tree (*const handler) PARAMS ((tree *node, tree name, tree args,
- int flags, bool *no_add_attrs));
+ tree (*const handler) (tree *node, tree name, tree args,
+ int flags, bool *no_add_attrs);
};
/* Flags that may be passed in the third argument of decl_attributes, and
@@ -2373,57 +2249,56 @@ enum attribute_flags
/* Default versions of target-overridable functions. */
-extern tree merge_decl_attributes PARAMS ((tree, tree));
-extern tree merge_type_attributes PARAMS ((tree, tree));
-struct cpp_reader;
-extern void default_register_cpp_builtins PARAMS ((struct cpp_reader *));
+extern tree merge_decl_attributes (tree, tree);
+extern tree merge_type_attributes (tree, tree);
+extern void default_register_cpp_builtins (struct cpp_reader *);
/* Split a list of declspecs and attributes into two. */
-extern void split_specs_attrs PARAMS ((tree, tree *, tree *));
+extern void split_specs_attrs (tree, tree *, tree *);
/* Strip attributes from a list of combined specs and attrs. */
-extern tree strip_attrs PARAMS ((tree));
+extern tree strip_attrs (tree);
/* Return 1 if an attribute and its arguments are valid for a decl or type. */
-extern int valid_machine_attribute PARAMS ((tree, tree, tree, tree));
+extern int valid_machine_attribute (tree, tree, tree, tree);
/* Given a tree node and a string, return nonzero if the tree node is
a valid attribute name for the string. */
-extern int is_attribute_p PARAMS ((const char *, tree));
+extern int is_attribute_p (const char *, tree);
/* Given an attribute name and a list of attributes, return the list element
of the attribute or NULL_TREE if not found. */
-extern tree lookup_attribute PARAMS ((const char *, tree));
+extern tree lookup_attribute (const char *, tree);
/* Given two attributes lists, return a list of their union. */
-extern tree merge_attributes PARAMS ((tree, tree));
+extern tree merge_attributes (tree, tree);
#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
/* Given two Windows decl attributes lists, possibly including
dllimport, return a list of their union . */
-extern tree merge_dllimport_decl_attributes PARAMS ((tree, tree));
+extern tree merge_dllimport_decl_attributes (tree, tree);
#endif
/* Return a version of the TYPE, qualified as indicated by the
TYPE_QUALS, if one exists. If no qualified version exists yet,
return NULL_TREE. */
-extern tree get_qualified_type PARAMS ((tree, int));
+extern tree get_qualified_type (tree, int);
/* Like get_qualified_type, but creates the type if it does not
exist. This function never returns NULL_TREE. */
-extern tree build_qualified_type PARAMS ((tree, int));
+extern tree build_qualified_type (tree, int);
/* Like build_qualified_type, but only deals with the `const' and
`volatile' qualifiers. This interface is retained for backwards
- compatiblity with the various front-ends; new code should use
+ compatibility with the various front-ends; new code should use
build_qualified_type instead. */
#define build_type_variant(TYPE, CONST_P, VOLATILE_P) \
@@ -2433,13 +2308,19 @@ extern tree build_qualified_type PARAMS ((tree, int));
/* Make a copy of a type node. */
-extern tree build_type_copy PARAMS ((tree));
+extern tree build_type_copy (tree);
+
+/* Finish up a builtin RECORD_TYPE. Give it a name and provide its
+ fields. Optionally specify an alignment, and then lsy it out. */
+
+extern void finish_builtin_struct (tree, const char *,
+ tree, tree);
/* Given a ..._TYPE node, calculate the TYPE_SIZE, TYPE_SIZE_UNIT,
TYPE_ALIGN and TYPE_MODE fields. If called more than once on one
node, does nothing except for the first time. */
-extern void layout_type PARAMS ((tree));
+extern void layout_type (tree);
/* These functions allow a front-end to perform a manual layout of a
RECORD_TYPE. (For instance, if the placement of subsequent fields
@@ -2461,11 +2342,9 @@ typedef struct record_layout_info_s
tree bitpos;
/* The alignment of the record so far, in bits. */
unsigned int record_align;
- /* The alignment of the record so far, not including padding, in bits. */
+ /* The alignment of the record so far, ignoring #pragma pack and
+ __attribute__ ((packed)), in bits. */
unsigned int unpacked_align;
- /* The alignment of the record so far, allowing for the record to be
- padded only at the end, in bits. */
- unsigned int unpadded_align;
/* The previous field layed out. */
tree prev_field;
/* The static variables (i.e., class variables, as opposed to
@@ -2473,33 +2352,30 @@ typedef struct record_layout_info_s
tree pending_statics;
/* Bits remaining in the current alignment group */
int remaining_in_alignment;
+ /* True if we've seen a packed field that didn't have normal
+ alignment anyway. */
int packed_maybe_necessary;
} *record_layout_info;
-extern void set_lang_adjust_rli PARAMS ((void (*) PARAMS
- ((record_layout_info))));
-extern record_layout_info start_record_layout PARAMS ((tree));
-extern tree bit_from_pos PARAMS ((tree, tree));
-extern tree byte_from_pos PARAMS ((tree, tree));
-extern void pos_from_byte PARAMS ((tree *, tree *, unsigned int,
- tree));
-extern void pos_from_bit PARAMS ((tree *, tree *, unsigned int,
- tree));
-extern void normalize_offset PARAMS ((tree *, tree *,
- unsigned int));
-extern tree rli_size_unit_so_far PARAMS ((record_layout_info));
-extern tree rli_size_so_far PARAMS ((record_layout_info));
-extern void normalize_rli PARAMS ((record_layout_info));
-extern void place_field PARAMS ((record_layout_info, tree));
-extern void compute_record_mode PARAMS ((tree));
-extern void finish_record_layout PARAMS ((record_layout_info, int));
+extern void set_lang_adjust_rli (void (*) (record_layout_info));
+extern record_layout_info start_record_layout (tree);
+extern tree bit_from_pos (tree, tree);
+extern tree byte_from_pos (tree, tree);
+extern void pos_from_bit (tree *, tree *, unsigned int, tree);
+extern void normalize_offset (tree *, tree *, unsigned int);
+extern tree rli_size_unit_so_far (record_layout_info);
+extern tree rli_size_so_far (record_layout_info);
+extern void normalize_rli (record_layout_info);
+extern void place_field (record_layout_info, tree);
+extern void compute_record_mode (tree);
+extern void finish_record_layout (record_layout_info, int);
/* Given a hashcode and a ..._TYPE node (for which the hashcode was made),
return a canonicalized ..._TYPE node, so that duplicates are not made.
How the hash code is computed is up to the caller, as long as any two
callers that could hash identical-looking type nodes agree. */
-extern tree type_hash_canon PARAMS ((unsigned int, tree));
+extern tree type_hash_canon (unsigned int, tree);
/* Given a VAR_DECL, PARM_DECL, RESULT_DECL or FIELD_DECL node,
calculates the DECL_SIZE, DECL_SIZE_UNIT, DECL_ALIGN and DECL_MODE
@@ -2509,29 +2385,31 @@ extern tree type_hash_canon PARAMS ((unsigned int, tree));
be starting at (in bits). Zero means it can be assumed aligned
on any boundary that may be needed. */
-extern void layout_decl PARAMS ((tree, unsigned));
+extern void layout_decl (tree, unsigned);
/* Return the mode for data of a given size SIZE and mode class CLASS.
If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE.
The value is BLKmode if no other mode is found. This is like
mode_for_size, but is passed a tree. */
-extern enum machine_mode mode_for_size_tree PARAMS ((tree, enum mode_class,
- int));
+extern enum machine_mode mode_for_size_tree (tree, enum mode_class, int);
/* Return an expr equal to X but certainly not valid as an lvalue. */
-extern tree non_lvalue PARAMS ((tree));
-extern tree pedantic_non_lvalue PARAMS ((tree));
-
-extern tree convert PARAMS ((tree, tree));
-extern unsigned int expr_align PARAMS ((tree));
-extern tree size_in_bytes PARAMS ((tree));
-extern HOST_WIDE_INT int_size_in_bytes PARAMS ((tree));
-extern tree bit_position PARAMS ((tree));
-extern HOST_WIDE_INT int_bit_position PARAMS ((tree));
-extern tree byte_position PARAMS ((tree));
-extern HOST_WIDE_INT int_byte_position PARAMS ((tree));
+extern tree non_lvalue (tree);
+extern tree pedantic_non_lvalue (tree);
+
+extern tree convert (tree, tree);
+extern unsigned int expr_align (tree);
+extern tree expr_first (tree);
+extern tree expr_last (tree);
+extern int expr_length (tree);
+extern tree size_in_bytes (tree);
+extern HOST_WIDE_INT int_size_in_bytes (tree);
+extern tree bit_position (tree);
+extern HOST_WIDE_INT int_bit_position (tree);
+extern tree byte_position (tree);
+extern HOST_WIDE_INT int_byte_position (tree);
/* Define data structures, macros, and functions for handling sizes
and the various types used to represent sizes. */
@@ -2543,7 +2421,7 @@ enum size_type_kind
USIZETYPE, /* Unsigned representation of sizes in bytes. */
BITSIZETYPE, /* Normal representation of sizes in bits. */
SBITSIZETYPE, /* Signed representation of sizes in bits. */
- UBITSIZETYPE, /* Unsifgned representation of sizes in bits. */
+ UBITSIZETYPE, /* Unsigned representation of sizes in bits. */
TYPE_KIND_LAST};
extern GTY(()) tree sizetype_tab[(int) TYPE_KIND_LAST];
@@ -2555,11 +2433,10 @@ extern GTY(()) tree sizetype_tab[(int) TYPE_KIND_LAST];
#define sbitsizetype sizetype_tab[(int) SBITSIZETYPE]
#define ubitsizetype sizetype_tab[(int) UBITSIZETYPE]
-extern tree size_binop PARAMS ((enum tree_code, tree, tree));
-extern tree size_diffop PARAMS ((tree, tree));
-extern tree size_int_wide PARAMS ((HOST_WIDE_INT,
- enum size_type_kind));
-extern tree size_int_type_wide PARAMS ((HOST_WIDE_INT, tree));
+extern tree size_binop (enum tree_code, tree, tree);
+extern tree size_diffop (tree, tree);
+extern tree size_int_wide (HOST_WIDE_INT, enum size_type_kind);
+extern tree size_int_type_wide (HOST_WIDE_INT, tree);
#define size_int_type(L, T) size_int_type_wide ((HOST_WIDE_INT) (L), T)
#define size_int(L) size_int_wide ((HOST_WIDE_INT) (L), SIZETYPE)
@@ -2567,12 +2444,12 @@ extern tree size_int_type_wide PARAMS ((HOST_WIDE_INT, tree));
#define bitsize_int(L) size_int_wide ((HOST_WIDE_INT) (L), BITSIZETYPE)
#define sbitsize_int(L) size_int_wide ((HOST_WIDE_INT) (L), SBITSIZETYPE)
-extern tree round_up PARAMS ((tree, int));
-extern tree round_down PARAMS ((tree, int));
-extern tree get_pending_sizes PARAMS ((void));
-extern int is_pending_size PARAMS ((tree));
-extern void put_pending_size PARAMS ((tree));
-extern void put_pending_sizes PARAMS ((tree));
+extern tree round_up (tree, int);
+extern tree round_down (tree, int);
+extern tree get_pending_sizes (void);
+extern int is_pending_size (tree);
+extern void put_pending_size (tree);
+extern void put_pending_sizes (tree);
/* Type for sizes of data-type. */
@@ -2591,92 +2468,112 @@ extern unsigned int set_alignment;
by making the last node in X point to Y.
Returns X, except if X is 0 returns Y. */
-extern tree chainon PARAMS ((tree, tree));
+extern tree chainon (tree, tree);
/* Make a new TREE_LIST node from specified PURPOSE, VALUE and CHAIN. */
-extern tree tree_cons PARAMS ((tree, tree, tree));
+extern tree tree_cons (tree, tree, tree);
/* Return the last tree node in a chain. */
-extern tree tree_last PARAMS ((tree));
+extern tree tree_last (tree);
/* Reverse the order of elements in a chain, and return the new head. */
-extern tree nreverse PARAMS ((tree));
+extern tree nreverse (tree);
/* Returns the length of a chain of nodes
(number of chain pointers to follow before reaching a null pointer). */
-extern int list_length PARAMS ((tree));
+extern int list_length (tree);
/* Returns the number of FIELD_DECLs in a type. */
-extern int fields_length PARAMS ((tree));
+extern int fields_length (tree);
/* Given an initializer INIT, return TRUE if INIT is zero or some
aggregate of zeros. Otherwise return FALSE. */
-extern bool initializer_zerop PARAMS ((tree));
+extern bool initializer_zerop (tree);
+
+/* Given an initializer INIT, return TRUE if INIT is at least 3/4 zeros.
+ Otherwise return FALSE. */
+
+extern int mostly_zeros_p (tree);
/* integer_zerop (tree x) is nonzero if X is an integer constant of value 0 */
-extern int integer_zerop PARAMS ((tree));
+extern int integer_zerop (tree);
/* integer_onep (tree x) is nonzero if X is an integer constant of value 1 */
-extern int integer_onep PARAMS ((tree));
+extern int integer_onep (tree);
/* integer_all_onesp (tree x) is nonzero if X is an integer constant
all of whose significant bits are 1. */
-extern int integer_all_onesp PARAMS ((tree));
+extern int integer_all_onesp (tree);
/* integer_pow2p (tree x) is nonzero is X is an integer constant with
exactly one bit 1. */
-extern int integer_pow2p PARAMS ((tree));
+extern int integer_pow2p (tree);
+
+/* integer_nonzerop (tree x) is nonzero if X is an integer constant
+ with a nonzero value. */
+
+extern int integer_nonzerop (tree);
/* staticp (tree x) is nonzero if X is a reference to data allocated
at a fixed address in memory. */
-extern int staticp PARAMS ((tree));
+extern int staticp (tree);
/* Gets an error if argument X is not an lvalue.
Also returns 1 if X is an lvalue, 0 if not. */
-extern int lvalue_or_else PARAMS ((tree, const char *));
+extern int lvalue_or_else (tree, const char *);
/* save_expr (EXP) returns an expression equivalent to EXP
but it can be used multiple times within context CTX
and only evaluate EXP once. */
-extern tree save_expr PARAMS ((tree));
+extern tree save_expr (tree);
+
+/* Look inside EXPR and into any simple arithmetic operations. Return
+ the innermost non-arithmetic node. */
+
+extern tree skip_simple_arithmetic (tree);
+
+/* Return TRUE if EXPR is a SAVE_EXPR or wraps simple arithmetic around a
+ SAVE_EXPR. Return FALSE otherwise. */
+
+extern bool saved_expr_p (tree);
/* Returns the index of the first non-tree operand for CODE, or the number
of operands if all are trees. */
-extern int first_rtl_op PARAMS ((enum tree_code));
+extern int first_rtl_op (enum tree_code);
/* Return which tree structure is used by T. */
-enum tree_node_structure_enum tree_node_structure PARAMS ((tree));
+enum tree_node_structure_enum tree_node_structure (tree);
/* unsave_expr (EXP) returns an expression equivalent to EXP but it
can be used multiple times and will evaluate EXP in its entirety
each time. */
-extern tree unsave_expr PARAMS ((tree));
+extern tree unsave_expr (tree);
-/* Reset EXP in place so that it can be expaned again. Does not
+/* Reset EXP in place so that it can be expanded again. Does not
recurse into subtrees. */
-extern void unsave_expr_1 PARAMS ((tree));
+extern void unsave_expr_1 (tree);
/* Return 0 if it is safe to evaluate EXPR multiple times,
return 1 if it is safe if EXPR is unsaved afterward, or
return 2 if it is completely unsafe. */
-extern int unsafe_for_reeval PARAMS ((tree));
+extern int unsafe_for_reeval (tree);
/* Return 1 if EXP contains a PLACEHOLDER_EXPR; i.e., if it represents a size
or offset that depends on a field within a record.
@@ -2684,19 +2581,31 @@ extern int unsafe_for_reeval PARAMS ((tree));
Note that we only allow such expressions within simple arithmetic
or a COND_EXPR. */
-extern int contains_placeholder_p PARAMS ((tree));
+extern bool contains_placeholder_p (tree);
+
+/* This macro calls the above function but short-circuits the common
+ case of a constant to save time. Also check for null. */
+
+#define CONTAINS_PLACEHOLDER_P(EXP) \
+ ((EXP) != 0 && ! TREE_CONSTANT (EXP) && contains_placeholder_p (EXP))
+
+/* Return 1 if any part of the computation of TYPE involves a PLACEHOLDER_EXPR.
+ This includes size, bounds, qualifiers (for QUAL_UNION_TYPE) and field
+ positions. */
+
+extern bool type_contains_placeholder_p (tree);
/* Return 1 if EXP contains any expressions that produce cleanups for an
outer scope to deal with. Used by fold. */
-extern int has_cleanups PARAMS ((tree));
+extern int has_cleanups (tree);
/* Given a tree EXP, a FIELD_DECL F, and a replacement value R,
return a tree with all occurrences of references to F in a
PLACEHOLDER_EXPR replaced by R. Note that we assume here that EXP
contains only arithmetic expressions. */
-extern tree substitute_in_expr PARAMS ((tree, tree, tree));
+extern tree substitute_in_expr (tree, tree, tree);
/* variable_size (EXP) is like save_expr (EXP) except that it
is for the special case of something that is part of a
@@ -2704,79 +2613,70 @@ extern tree substitute_in_expr PARAMS ((tree, tree, tree));
to compute the value at the right time when the data type
belongs to a function parameter. */
-extern tree variable_size PARAMS ((tree));
+extern tree variable_size (tree);
-/* stabilize_reference (EXP) returns an reference equivalent to EXP
+/* stabilize_reference (EXP) returns a reference equivalent to EXP
but it can be used multiple times
and only evaluate the subexpressions once. */
-extern tree stabilize_reference PARAMS ((tree));
+extern tree stabilize_reference (tree);
/* Subroutine of stabilize_reference; this is called for subtrees of
references. Any expression with side-effects must be put in a SAVE_EXPR
to ensure that it is only evaluated once. */
-extern tree stabilize_reference_1 PARAMS ((tree));
+extern tree stabilize_reference_1 (tree);
/* Return EXP, stripped of any conversions to wider types
in such a way that the result of converting to type FOR_TYPE
is the same as if EXP were converted to FOR_TYPE.
If FOR_TYPE is 0, it signifies EXP's type. */
-extern tree get_unwidened PARAMS ((tree, tree));
+extern tree get_unwidened (tree, tree);
/* Return OP or a simpler expression for a narrower value
which can be sign-extended or zero-extended to give back OP.
Store in *UNSIGNEDP_PTR either 1 if the value should be zero-extended
or 0 if the value should be sign-extended. */
-extern tree get_narrower PARAMS ((tree, int *));
+extern tree get_narrower (tree, int *);
/* Given an expression EXP that may be a COMPONENT_REF or an ARRAY_REF,
look for nested component-refs or array-refs at constant positions
and find the ultimate containing object, which is returned. */
-extern tree get_inner_reference PARAMS ((tree, HOST_WIDE_INT *,
- HOST_WIDE_INT *, tree *,
- enum machine_mode *, int *,
- int *));
+extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
+ tree *, enum machine_mode *, int *, int *);
/* Return 1 if T is an expression that get_inner_reference handles. */
-extern int handled_component_p PARAMS ((tree));
+extern int handled_component_p (tree);
/* Given a DECL or TYPE, return the scope in which it was declared, or
NUL_TREE if there is no containing scope. */
-extern tree get_containing_scope PARAMS ((tree));
+extern tree get_containing_scope (tree);
/* Return the FUNCTION_DECL which provides this _DECL with its context,
or zero if none. */
-extern tree decl_function_context PARAMS ((tree));
+extern tree decl_function_context (tree);
/* Return the RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE which provides
this _DECL with its context, or zero if none. */
-extern tree decl_type_context PARAMS ((tree));
+extern tree decl_type_context (tree);
/* Given the FUNCTION_DECL for the current function,
return zero if it is ok for this function to be inline.
Otherwise return a warning message with a single %s
for the function's name. */
-extern const char *function_cannot_inline_p PARAMS ((tree));
+extern const char *function_cannot_inline_p (tree);
/* Return 1 if EXPR is the real constant zero. */
-extern int real_zerop PARAMS ((tree));
+extern int real_zerop (tree);
/* Declare commonly used variables for tree structure. */
-/* Points to the name of the input file from which the current input
- being parsed originally came (before it went into cpp). */
-extern const char *input_filename;
-
-/* Current line number in input file. */
-extern int lineno;
-
/* Nonzero means lvalues are limited to those valid in pedantic ANSI C.
Zero means allow extended lvalues. */
@@ -2798,84 +2698,77 @@ extern GTY(()) tree current_function_func_begin_label;
extern int all_types_permanent;
+/* Exit a binding level. This function is provided by each language
+ frontend. */
+extern tree poplevel (int, int, int);
+
/* Declare a predefined function. Return the declaration. This function is
provided by each language frontend. */
-extern tree builtin_function PARAMS ((const char *, tree, int,
- enum built_in_class,
- const char *, tree));
+extern tree builtin_function (const char *, tree, int, enum built_in_class,
+ const char *, tree);
/* In tree.c */
-extern void clean_symbol_name PARAMS ((char *));
-extern tree get_file_function_name_long PARAMS ((const char *));
-extern tree get_set_constructor_bits PARAMS ((tree, char *, int));
-extern tree get_set_constructor_bytes PARAMS ((tree,
- unsigned char *, int));
-extern tree get_callee_fndecl PARAMS ((tree));
-extern void set_decl_assembler_name PARAMS ((tree));
-extern int type_num_arguments PARAMS ((tree));
-extern tree lhd_unsave_expr_now PARAMS ((tree));
+extern unsigned crc32_string (unsigned, const char *);
+extern void clean_symbol_name (char *);
+extern tree get_file_function_name_long (const char *);
+extern tree get_set_constructor_bits (tree, char *, int);
+extern tree get_set_constructor_bytes (tree, unsigned char *, int);
+extern tree get_callee_fndecl (tree);
+extern void change_decl_assembler_name (tree, tree);
+extern int type_num_arguments (tree);
+extern tree lhd_unsave_expr_now (tree);
/* In stmt.c */
-extern int in_control_zone_p PARAMS ((void));
-extern void expand_fixups PARAMS ((rtx));
-extern tree expand_start_stmt_expr PARAMS ((int));
-extern tree expand_end_stmt_expr PARAMS ((tree));
-extern void expand_expr_stmt PARAMS ((tree));
-extern void expand_expr_stmt_value PARAMS ((tree, int, int));
-extern int warn_if_unused_value PARAMS ((tree));
-extern void expand_decl_init PARAMS ((tree));
-extern void clear_last_expr PARAMS ((void));
-extern void expand_label PARAMS ((tree));
-extern void expand_goto PARAMS ((tree));
-extern void expand_asm PARAMS ((tree, int));
-extern void expand_start_cond PARAMS ((tree, int));
-extern void expand_end_cond PARAMS ((void));
-extern void expand_start_else PARAMS ((void));
-extern void expand_start_elseif PARAMS ((tree));
-extern struct nesting *expand_start_loop PARAMS ((int));
-extern struct nesting *expand_start_loop_continue_elsewhere PARAMS ((int));
-extern struct nesting *expand_start_null_loop PARAMS ((void));
-extern void expand_loop_continue_here PARAMS ((void));
-extern void expand_end_loop PARAMS ((void));
-extern void expand_end_null_loop PARAMS ((void));
-extern int expand_continue_loop PARAMS ((struct nesting *));
-extern int expand_exit_loop PARAMS ((struct nesting *));
-extern int expand_exit_loop_if_false PARAMS ((struct nesting *,
- tree));
-extern int expand_exit_loop_top_cond PARAMS ((struct nesting *,
- tree));
-extern int expand_exit_something PARAMS ((void));
-
-extern void expand_return PARAMS ((tree));
-extern int optimize_tail_recursion PARAMS ((tree, rtx));
-extern void expand_start_bindings_and_block PARAMS ((int, tree));
+extern void expand_fixups (rtx);
+extern tree expand_start_stmt_expr (int);
+extern tree expand_end_stmt_expr (tree);
+extern void expand_expr_stmt (tree);
+extern void expand_expr_stmt_value (tree, int, int);
+extern int warn_if_unused_value (tree);
+extern void expand_decl_init (tree);
+extern void clear_last_expr (void);
+extern void expand_label (tree);
+extern void expand_goto (tree);
+extern void expand_asm (tree, int);
+extern void expand_start_cond (tree, int);
+extern void expand_end_cond (void);
+extern void expand_start_else (void);
+extern void expand_start_elseif (tree);
+extern struct nesting *expand_start_loop (int);
+extern struct nesting *expand_start_loop_continue_elsewhere (int);
+extern struct nesting *expand_start_null_loop (void);
+extern void expand_loop_continue_here (void);
+extern void expand_end_loop (void);
+extern void expand_end_null_loop (void);
+extern int expand_continue_loop (struct nesting *);
+extern int expand_exit_loop (struct nesting *);
+extern int expand_exit_loop_if_false (struct nesting *,tree);
+extern int expand_exit_loop_top_cond (struct nesting *, tree);
+extern int expand_exit_something (void);
+
+extern void expand_return (tree);
+extern int optimize_tail_recursion (tree, rtx);
+extern void expand_start_bindings_and_block (int, tree);
#define expand_start_bindings(flags) \
expand_start_bindings_and_block(flags, NULL_TREE)
-extern void expand_end_bindings PARAMS ((tree, int, int));
-extern void warn_about_unused_variables PARAMS ((tree));
-extern void start_cleanup_deferral PARAMS ((void));
-extern void end_cleanup_deferral PARAMS ((void));
-extern int is_body_block PARAMS ((tree));
-
-extern int conditional_context PARAMS ((void));
-extern struct nesting * current_nesting_level PARAMS ((void));
-extern tree last_cleanup_this_contour PARAMS ((void));
-extern void expand_start_case PARAMS ((int, tree, tree,
- const char *));
-extern void expand_end_case_type PARAMS ((tree, tree));
+extern void expand_end_bindings (tree, int, int);
+extern void warn_about_unused_variables (tree);
+extern void start_cleanup_deferral (void);
+extern void end_cleanup_deferral (void);
+extern int is_body_block (tree);
+
+extern int conditional_context (void);
+extern struct nesting * current_nesting_level (void);
+extern tree last_cleanup_this_contour (void);
+extern void expand_start_case (int, tree, tree, const char *);
+extern void expand_end_case_type (tree, tree);
#define expand_end_case(cond) expand_end_case_type (cond, NULL)
-extern int add_case_node PARAMS ((tree, tree,
- tree, tree *));
-extern int pushcase PARAMS ((tree,
- tree (*) (tree, tree),
- tree, tree *));
-extern int pushcase_range PARAMS ((tree, tree,
- tree (*) (tree, tree),
- tree, tree *));
-extern void using_eh_for_cleanups PARAMS ((void));
-extern int stmt_loop_nest_empty PARAMS ((void));
+extern int add_case_node (tree, tree, tree, tree *);
+extern int pushcase (tree, tree (*) (tree, tree), tree, tree *);
+extern int pushcase_range (tree, tree, tree (*) (tree, tree), tree, tree *);
+extern void using_eh_for_cleanups (void);
/* In fold-const.c */
@@ -2885,151 +2778,175 @@ extern int stmt_loop_nest_empty PARAMS ((void));
if the argument itself cannot be simplified, its
subexpressions are not changed. */
-extern tree fold PARAMS ((tree));
-
-extern int force_fit_type PARAMS ((tree, int));
-extern int add_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *));
-extern int neg_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *));
-extern int mul_double PARAMS ((unsigned HOST_WIDE_INT,
- HOST_WIDE_INT,
- unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *));
-extern void lshift_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- HOST_WIDE_INT, unsigned int,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *, int));
-extern void rshift_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- HOST_WIDE_INT, unsigned int,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *, int));
-extern void lrotate_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- HOST_WIDE_INT, unsigned int,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *));
-extern void rrotate_double PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT,
- HOST_WIDE_INT, unsigned int,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *));
-extern int operand_equal_p PARAMS ((tree, tree, int));
-extern tree invert_truthvalue PARAMS ((tree));
-
-extern tree fold_builtin PARAMS ((tree));
-
-extern tree build_range_type PARAMS ((tree, tree, tree));
+extern tree fold (tree);
+extern tree fold_initializer (tree);
+extern tree fold_single_bit_test (enum tree_code, tree, tree, tree);
+
+extern int force_fit_type (tree, int);
+extern int add_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
+extern int neg_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
+extern int mul_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
+extern void lshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
+ HOST_WIDE_INT, unsigned int,
+ unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, int);
+extern void rshift_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
+ HOST_WIDE_INT, unsigned int,
+ unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, int);
+extern void lrotate_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
+ HOST_WIDE_INT, unsigned int,
+ unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
+extern void rrotate_double (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
+ HOST_WIDE_INT, unsigned int,
+ unsigned HOST_WIDE_INT *, HOST_WIDE_INT *);
+
+extern int div_and_round_double (enum tree_code, int, unsigned HOST_WIDE_INT,
+ HOST_WIDE_INT, unsigned HOST_WIDE_INT,
+ HOST_WIDE_INT, unsigned HOST_WIDE_INT *,
+ HOST_WIDE_INT *, unsigned HOST_WIDE_INT *,
+ HOST_WIDE_INT *);
+
+extern int operand_equal_p (tree, tree, int);
+extern tree omit_one_operand (tree, tree, tree);
+extern tree invert_truthvalue (tree);
+
+/* In builtins.c */
+extern tree fold_builtin (tree);
+extern enum built_in_function builtin_mathfn_code (tree);
+extern tree build_function_call_expr (tree, tree);
+extern tree mathfn_built_in (tree, enum built_in_function fn);
+
+/* In convert.c */
+extern tree strip_float_extensions (tree);
/* In alias.c */
-extern void record_component_aliases PARAMS ((tree));
-extern HOST_WIDE_INT get_alias_set PARAMS ((tree));
-extern int alias_sets_conflict_p PARAMS ((HOST_WIDE_INT,
- HOST_WIDE_INT));
-extern int readonly_fields_p PARAMS ((tree));
-extern int objects_must_conflict_p PARAMS ((tree, tree));
-
-struct obstack;
+extern void record_component_aliases (tree);
+extern HOST_WIDE_INT get_alias_set (tree);
+extern int alias_sets_conflict_p (HOST_WIDE_INT, HOST_WIDE_INT);
+extern int readonly_fields_p (tree);
+extern int objects_must_conflict_p (tree, tree);
/* In tree.c */
-extern int really_constant_p PARAMS ((tree));
-extern int int_fits_type_p PARAMS ((tree, tree));
-extern bool variably_modified_type_p PARAMS ((tree));
-extern int tree_log2 PARAMS ((tree));
-extern int tree_floor_log2 PARAMS ((tree));
-extern int simple_cst_equal PARAMS ((tree, tree));
-extern int compare_tree_int PARAMS ((tree,
- unsigned HOST_WIDE_INT));
-extern int type_list_equal PARAMS ((tree, tree));
-extern int chain_member PARAMS ((tree, tree));
-extern int chain_member_purpose PARAMS ((tree, tree));
-extern int chain_member_value PARAMS ((tree, tree));
-extern tree listify PARAMS ((tree));
-extern tree type_hash_lookup PARAMS ((unsigned int, tree));
-extern void type_hash_add PARAMS ((unsigned int, tree));
-extern unsigned int type_hash_list PARAMS ((tree));
-extern int simple_cst_list_equal PARAMS ((tree, tree));
-extern void dump_tree_statistics PARAMS ((void));
-extern void print_obstack_statistics PARAMS ((const char *,
- struct obstack *));
-#ifdef BUFSIZ
-extern void print_obstack_name PARAMS ((char *, FILE *,
- const char *));
-#endif
-extern void expand_function_end PARAMS ((const char *, int, int));
-extern void expand_function_start PARAMS ((tree, int));
-extern void expand_pending_sizes PARAMS ((tree));
-
-extern int real_onep PARAMS ((tree));
-extern int real_twop PARAMS ((tree));
-extern int real_minus_onep PARAMS ((tree));
-extern void gcc_obstack_init PARAMS ((struct obstack *));
-extern void init_ttree PARAMS ((void));
-extern void build_common_tree_nodes PARAMS ((int));
-extern void build_common_tree_nodes_2 PARAMS ((int));
+extern int really_constant_p (tree);
+extern int int_fits_type_p (tree, tree);
+extern bool variably_modified_type_p (tree);
+extern int tree_log2 (tree);
+extern int tree_floor_log2 (tree);
+extern int simple_cst_equal (tree, tree);
+extern unsigned int iterative_hash_expr (tree, unsigned int);
+extern int compare_tree_int (tree, unsigned HOST_WIDE_INT);
+extern int type_list_equal (tree, tree);
+extern int chain_member (tree, tree);
+extern tree type_hash_lookup (unsigned int, tree);
+extern void type_hash_add (unsigned int, tree);
+extern unsigned int type_hash_list (tree);
+extern int simple_cst_list_equal (tree, tree);
+extern void dump_tree_statistics (void);
+extern void expand_function_end (void);
+extern void expand_function_start (tree, int);
+extern void expand_pending_sizes (tree);
+
+extern int real_onep (tree);
+extern int real_twop (tree);
+extern int real_minus_onep (tree);
+extern void init_ttree (void);
+extern void build_common_tree_nodes (int);
+extern void build_common_tree_nodes_2 (int);
+extern tree build_range_type (tree, tree, tree);
/* In function.c */
-extern void setjmp_protect_args PARAMS ((void));
-extern void setjmp_protect PARAMS ((tree));
-extern void expand_main_function PARAMS ((void));
-extern void init_dummy_function_start PARAMS ((void));
-extern void expand_dummy_function_end PARAMS ((void));
-extern void init_function_for_compilation PARAMS ((void));
-extern void init_function_start PARAMS ((tree, const char *, int));
-extern void assign_parms PARAMS ((tree));
-extern void put_var_into_stack PARAMS ((tree, int));
-extern void flush_addressof PARAMS ((tree));
-extern void uninitialized_vars_warning PARAMS ((tree));
-extern void setjmp_args_warning PARAMS ((void));
-extern void mark_all_temps_used PARAMS ((void));
-extern void init_temp_slots PARAMS ((void));
-extern void combine_temp_slots PARAMS ((void));
-extern void free_temp_slots PARAMS ((void));
-extern void pop_temp_slots PARAMS ((void));
-extern void push_temp_slots PARAMS ((void));
-extern void preserve_temp_slots PARAMS ((rtx));
-extern void preserve_rtl_expr_temps PARAMS ((tree));
-extern int aggregate_value_p PARAMS ((tree));
-extern void free_temps_for_rtl_expr PARAMS ((tree));
-extern void instantiate_virtual_regs PARAMS ((tree, rtx));
-extern void unshare_all_rtl PARAMS ((tree, rtx));
-extern int max_parm_reg_num PARAMS ((void));
-extern void push_function_context PARAMS ((void));
-extern void pop_function_context PARAMS ((void));
-extern void push_function_context_to PARAMS ((tree));
-extern void pop_function_context_from PARAMS ((tree));
+extern void setjmp_protect_args (void);
+extern void setjmp_protect (tree);
+extern void expand_main_function (void);
+extern void init_dummy_function_start (void);
+extern void expand_dummy_function_end (void);
+extern void init_function_for_compilation (void);
+extern void allocate_struct_function (tree);
+extern void init_function_start (tree);
+extern void assign_parms (tree);
+extern void put_var_into_stack (tree, int);
+extern void flush_addressof (tree);
+extern void uninitialized_vars_warning (tree);
+extern void setjmp_args_warning (void);
+extern void mark_all_temps_used (void);
+extern void init_temp_slots (void);
+extern void combine_temp_slots (void);
+extern void free_temp_slots (void);
+extern void pop_temp_slots (void);
+extern void push_temp_slots (void);
+extern void preserve_temp_slots (rtx);
+extern void preserve_rtl_expr_temps (tree);
+extern int aggregate_value_p (tree, tree);
+extern void free_temps_for_rtl_expr (tree);
+extern void instantiate_virtual_regs (tree, rtx);
+extern void unshare_all_rtl (tree, rtx);
+extern void push_function_context (void);
+extern void pop_function_context (void);
+extern void push_function_context_to (tree);
+extern void pop_function_context_from (tree);
/* In print-rtl.c */
#ifdef BUFSIZ
-extern void print_rtl PARAMS ((FILE *, rtx));
+extern void print_rtl (FILE *, rtx);
#endif
/* In print-tree.c */
-extern void debug_tree PARAMS ((tree));
+extern void debug_tree (tree);
#ifdef BUFSIZ
-extern void print_node PARAMS ((FILE *, const char *, tree,
- int));
-extern void print_node_brief PARAMS ((FILE *, const char *, tree,
- int));
-extern void indent_to PARAMS ((FILE *, int));
+extern void print_node (FILE *, const char *, tree, int);
+extern void print_node_brief (FILE *, const char *, tree, int);
+extern void indent_to (FILE *, int);
#endif
/* In expr.c */
-extern int apply_args_register_offset PARAMS ((int));
-extern rtx expand_builtin_return_addr
- PARAMS ((enum built_in_function, int, rtx));
-extern void check_max_integer_computation_mode PARAMS ((tree));
+extern int apply_args_register_offset (int);
+extern rtx expand_builtin_return_addr (enum built_in_function, int, rtx);
+extern void check_max_integer_computation_mode (tree);
/* In emit-rtl.c */
-extern void start_sequence_for_rtl_expr PARAMS ((tree));
-extern rtx emit_line_note PARAMS ((const char *, int));
+extern void start_sequence_for_rtl_expr (tree);
+extern rtx emit_line_note (location_t);
/* In calls.c */
-extern int setjmp_call_p PARAMS ((tree));
-extern bool alloca_call_p PARAMS ((tree));
+/* Nonzero if this is a call to a `const' function. */
+#define ECF_CONST 1
+/* Nonzero if this is a call to a `volatile' function. */
+#define ECF_NORETURN 2
+/* Nonzero if this is a call to malloc or a related function. */
+#define ECF_MALLOC 4
+/* Nonzero if it is plausible that this is a call to alloca. */
+#define ECF_MAY_BE_ALLOCA 8
+/* Nonzero if this is a call to a function that won't throw an exception. */
+#define ECF_NOTHROW 16
+/* Nonzero if this is a call to setjmp or a related function. */
+#define ECF_RETURNS_TWICE 32
+/* Nonzero if this is a call to `longjmp'. */
+#define ECF_LONGJMP 64
+/* Nonzero if this is a syscall that makes a new process in the image of
+ the current one. */
+#define ECF_FORK_OR_EXEC 128
+#define ECF_SIBCALL 256
+/* Nonzero if this is a call to "pure" function (like const function,
+ but may read memory. */
+#define ECF_PURE 512
+/* Nonzero if this is a call to a function that returns with the stack
+ pointer depressed. */
+#define ECF_SP_DEPRESSED 1024
+/* Nonzero if this call is known to always return. */
+#define ECF_ALWAYS_RETURN 2048
+/* Create libcall block around the call. */
+#define ECF_LIBCALL_BLOCK 4096
+
+extern int flags_from_decl_or_type (tree);
+extern int call_expr_flags (tree);
+
+extern int setjmp_call_p (tree);
+extern bool alloca_call_p (tree);
/* In attribs.c. */
@@ -3041,103 +2958,91 @@ extern bool alloca_call_p PARAMS ((tree));
from tree.h. Depending on these flags, some attributes may be
returned to be applied at a later stage (for example, to apply
a decl attribute to the declaration rather than to its type). */
-extern tree decl_attributes PARAMS ((tree *, tree, int));
+extern tree decl_attributes (tree *, tree, int);
/* In integrate.c */
-extern void save_for_inline PARAMS ((tree));
-extern void set_decl_abstract_flags PARAMS ((tree, int));
-extern void output_inline_function PARAMS ((tree));
-extern void set_decl_origin_self PARAMS ((tree));
+extern void save_for_inline (tree);
+extern void set_decl_abstract_flags (tree, int);
+extern void output_inline_function (tree);
+extern void set_decl_origin_self (tree);
/* In stor-layout.c */
-extern void fixup_signed_type PARAMS ((tree));
-extern void internal_reference_types PARAMS ((void));
+extern void set_min_and_max_values_for_integral_type (tree, int, bool);
+extern void fixup_signed_type (tree);
+extern void internal_reference_types (void);
/* varasm.c */
-extern void make_decl_rtl PARAMS ((tree, const char *));
-extern void make_decl_one_only PARAMS ((tree));
-extern int supports_one_only PARAMS ((void));
-extern void variable_section PARAMS ((tree, int));
-enum tls_model decl_tls_model PARAMS ((tree));
-enum symbol_visibility decl_visibility PARAMS ((tree));
-
-/* In fold-const.c */
-extern int div_and_round_double PARAMS ((enum tree_code, int,
- unsigned HOST_WIDE_INT,
- HOST_WIDE_INT,
- unsigned HOST_WIDE_INT,
- HOST_WIDE_INT,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *,
- unsigned HOST_WIDE_INT *,
- HOST_WIDE_INT *));
+extern void make_decl_rtl (tree, const char *);
+extern void make_decl_one_only (tree);
+extern int supports_one_only (void);
+extern void variable_section (tree, int);
+enum tls_model decl_tls_model (tree);
+extern void resolve_unique_section (tree, int, int);
+extern void mark_referenced (tree);
+extern void notice_global_symbol (tree);
/* In stmt.c */
-extern void emit_nop PARAMS ((void));
-extern void expand_computed_goto PARAMS ((tree));
-extern bool parse_output_constraint PARAMS ((const char **,
- int, int, int,
- bool *, bool *, bool *));
-extern void expand_asm_operands PARAMS ((tree, tree, tree, tree, int,
- const char *, int));
-extern int any_pending_cleanups PARAMS ((int));
-extern void init_stmt_for_function PARAMS ((void));
-extern int drop_through_at_end_p PARAMS ((void));
-extern void expand_start_target_temps PARAMS ((void));
-extern void expand_end_target_temps PARAMS ((void));
-extern void expand_elseif PARAMS ((tree));
-extern void save_stack_pointer PARAMS ((void));
-extern void expand_decl PARAMS ((tree));
-extern int expand_decl_cleanup PARAMS ((tree, tree));
-extern int expand_decl_cleanup_eh PARAMS ((tree, tree, int));
-extern void expand_anon_union_decl PARAMS ((tree, tree, tree));
-extern void move_cleanups_up PARAMS ((void));
-extern void expand_start_case_dummy PARAMS ((void));
-extern void expand_end_case_dummy PARAMS ((void));
-extern tree case_index_expr_type PARAMS ((void));
-extern HOST_WIDE_INT all_cases_count PARAMS ((tree, int *));
-extern void check_for_full_enumeration_handling PARAMS ((tree));
-extern void declare_nonlocal_label PARAMS ((tree));
-extern void default_flag_random_seed PARAMS ((void));
+extern void emit_nop (void);
+extern void expand_computed_goto (tree);
+extern bool parse_output_constraint (const char **, int, int, int,
+ bool *, bool *, bool *);
+extern bool parse_input_constraint (const char **, int, int, int, int,
+ const char * const *, bool *, bool *);
+extern void expand_asm_operands (tree, tree, tree, tree, int, location_t);
+extern tree resolve_asm_operand_names (tree, tree, tree);
+extern int any_pending_cleanups (void);
+extern void init_stmt_for_function (void);
+extern void expand_start_target_temps (void);
+extern void expand_end_target_temps (void);
+extern void expand_elseif (tree);
+extern void save_stack_pointer (void);
+extern void expand_decl (tree);
+extern int expand_decl_cleanup (tree, tree);
+extern int expand_decl_cleanup_eh (tree, tree, int);
+extern void expand_anon_union_decl (tree, tree, tree);
+extern void expand_start_case_dummy (void);
+extern HOST_WIDE_INT all_cases_count (tree, int *);
+extern void check_for_full_enumeration_handling (tree);
+extern void declare_nonlocal_label (tree);
/* If KIND=='I', return a suitable global initializer (constructor) name.
If KIND=='D', return a suitable global clean-up (destructor) name. */
-extern tree get_file_function_name PARAMS ((int));
+extern tree get_file_function_name (int);
/* Interface of the DWARF2 unwind info support. */
/* Generate a new label for the CFI info to refer to. */
-extern char *dwarf2out_cfi_label PARAMS ((void));
+extern char *dwarf2out_cfi_label (void);
/* Entry point to update the canonical frame address (CFA). */
-extern void dwarf2out_def_cfa PARAMS ((const char *, unsigned, long));
+extern void dwarf2out_def_cfa (const char *, unsigned, HOST_WIDE_INT);
/* Add the CFI for saving a register window. */
-extern void dwarf2out_window_save PARAMS ((const char *));
+extern void dwarf2out_window_save (const char *);
/* Add a CFI to update the running total of the size of arguments pushed
onto the stack. */
-extern void dwarf2out_args_size PARAMS ((const char *, long));
+extern void dwarf2out_args_size (const char *, HOST_WIDE_INT);
/* Entry point for saving a register to the stack. */
-extern void dwarf2out_reg_save PARAMS ((const char *, unsigned, long));
+extern void dwarf2out_reg_save (const char *, unsigned, HOST_WIDE_INT);
/* Entry point for saving the return address in the stack. */
-extern void dwarf2out_return_save PARAMS ((const char *, long));
+extern void dwarf2out_return_save (const char *, HOST_WIDE_INT);
/* Entry point for saving the return address in a register. */
-extern void dwarf2out_return_reg PARAMS ((const char *, unsigned));
+extern void dwarf2out_return_reg (const char *, unsigned);
/* The type of a function that walks over tree structure. */
-typedef tree (*walk_tree_fn) PARAMS ((tree *, int *, void *));
+typedef tree (*walk_tree_fn) (tree *, int *, void *);
/* In tree-dump.c */
@@ -3162,14 +3067,16 @@ enum tree_dump_index
typedef struct dump_info *dump_info_p;
-extern int dump_flag PARAMS ((dump_info_p, int, tree));
-extern int dump_enabled_p PARAMS ((enum tree_dump_index));
-extern FILE *dump_begin PARAMS ((enum tree_dump_index, int *));
-extern void dump_end PARAMS ((enum tree_dump_index, FILE *));
-extern void dump_node PARAMS ((tree, int, FILE *));
-extern int dump_switch_p PARAMS ((const char *));
-extern const char *dump_flag_name PARAMS ((enum tree_dump_index));
+extern int dump_flag (dump_info_p, int, tree);
+extern int dump_enabled_p (enum tree_dump_index);
+extern FILE *dump_begin (enum tree_dump_index, int *);
+extern void dump_end (enum tree_dump_index, FILE *);
+extern void dump_node (tree, int, FILE *);
+extern int dump_switch_p (const char *);
+extern const char *dump_flag_name (enum tree_dump_index);
+/* Assign the RTX to declaration. */
+extern void set_decl_rtl (tree, rtx);
/* Redefine abort to report an internal error w/o coredump, and
reporting the location of the error in the source file. This logic
@@ -3177,8 +3084,32 @@ extern const char *dump_flag_name PARAMS ((enum tree_dump_index));
special abort includes one or both. toplev.h gets too few files,
system.h gets too many. */
-extern void fancy_abort PARAMS ((const char *, int, const char *))
+extern void fancy_abort (const char *, int, const char *)
ATTRIBUTE_NORETURN;
#define abort() fancy_abort (__FILE__, __LINE__, __FUNCTION__)
+/* Enum and arrays used for tree allocation stats.
+ Keep in sync with tree.c:tree_node_kind_names. */
+typedef enum
+{
+ d_kind,
+ t_kind,
+ b_kind,
+ s_kind,
+ r_kind,
+ e_kind,
+ c_kind,
+ id_kind,
+ perm_list_kind,
+ temp_list_kind,
+ vec_kind,
+ x_kind,
+ lang_decl,
+ lang_type,
+ all_kinds
+} tree_node_kind;
+
+extern int tree_node_counts[];
+extern int tree_node_sizes[];
+
#endif /* GCC_TREE_H */
diff --git a/contrib/gcc/tsystem.h b/contrib/gcc/tsystem.h
index 5b81e48c7321..f24bab78cc5e 100644
--- a/contrib/gcc/tsystem.h
+++ b/contrib/gcc/tsystem.h
@@ -26,7 +26,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
-
#ifndef GCC_TSYSTEM_H
#define GCC_TSYSTEM_H
@@ -59,6 +58,14 @@ extern void free (void *);
extern int atexit (void (*)(void));
#endif
+#ifndef abort
+extern void abort (void) __attribute__ ((__noreturn__));
+#endif
+
+#ifndef strlen
+extern size_t strlen (const char *);
+#endif
+
#else /* ! inhibit_libc */
/* We disable this when inhibit_libc, so that gcc can still be built without
needing header files first. */
@@ -81,20 +88,16 @@ extern int atexit (void (*)(void));
extern int errno;
#endif
-#ifdef POSIX
-#include <string.h>
-#endif
-
/* GCC (fixproto) guarantees these system headers exist. */
+#include <string.h>
#include <stdlib.h>
#include <unistd.h>
/* GCC supplies this header. */
#include <limits.h>
-#ifdef POSIX
+/* GCC (fixproto) guarantees this system headers exists. */
#include <time.h>
-#endif
#endif /* inhibit_libc */
diff --git a/contrib/gcc/unroll.c b/contrib/gcc/unroll.c
index 5a15208d5d7c..518e4a1168ed 100644
--- a/contrib/gcc/unroll.c
+++ b/contrib/gcc/unroll.c
@@ -1,5 +1,6 @@
/* Try to unroll loops, and split induction variables.
- Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003
Free Software Foundation, Inc.
Contributed by James E. Wilson, Cygnus Support/UC Berkeley.
@@ -69,7 +70,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* ??? Improve control of which loops get unrolled. Could use profiling
info to only unroll the most commonly executed loops. Perhaps have
- a user specifyable option to control the amount of code expansion,
+ a user specifiable option to control the amount of code expansion,
or the percent of loops to consider for unrolling. Etc. */
/* ??? Look at the register copies inside the loop to see if they form a
@@ -133,6 +134,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "insn-config.h"
@@ -148,6 +151,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "basic-block.h"
#include "predict.h"
#include "params.h"
+#include "cfgloop.h"
/* The prime factors looked for when trying to unroll a loop by some
number which is modulo the total number of iterations. Just checking
@@ -193,28 +197,26 @@ static int *splittable_regs_updates;
/* Forward declarations. */
-static rtx simplify_cmp_and_jump_insns PARAMS ((enum rtx_code,
- enum machine_mode,
- rtx, rtx, rtx));
-static void init_reg_map PARAMS ((struct inline_remap *, int));
-static rtx calculate_giv_inc PARAMS ((rtx, rtx, unsigned int));
-static rtx initial_reg_note_copy PARAMS ((rtx, struct inline_remap *));
-static void final_reg_note_copy PARAMS ((rtx *, struct inline_remap *));
-static void copy_loop_body PARAMS ((struct loop *, rtx, rtx,
- struct inline_remap *, rtx, int,
- enum unroll_types, rtx, rtx, rtx, rtx));
-static int find_splittable_regs PARAMS ((const struct loop *,
- enum unroll_types, int));
-static int find_splittable_givs PARAMS ((const struct loop *,
- struct iv_class *, enum unroll_types,
- rtx, int));
-static int reg_dead_after_loop PARAMS ((const struct loop *, rtx));
-static rtx fold_rtx_mult_add PARAMS ((rtx, rtx, rtx, enum machine_mode));
-static rtx remap_split_bivs PARAMS ((struct loop *, rtx));
-static rtx find_common_reg_term PARAMS ((rtx, rtx));
-static rtx subtract_reg_term PARAMS ((rtx, rtx));
-static rtx loop_find_equiv_value PARAMS ((const struct loop *, rtx));
-static rtx ujump_to_loop_cont PARAMS ((rtx, rtx));
+static rtx simplify_cmp_and_jump_insns (enum rtx_code, enum machine_mode,
+ rtx, rtx, rtx);
+static void init_reg_map (struct inline_remap *, int);
+static rtx calculate_giv_inc (rtx, rtx, unsigned int);
+static rtx initial_reg_note_copy (rtx, struct inline_remap *);
+static void final_reg_note_copy (rtx *, struct inline_remap *);
+static void copy_loop_body (struct loop *, rtx, rtx,
+ struct inline_remap *, rtx, int,
+ enum unroll_types, rtx, rtx, rtx, rtx);
+static int find_splittable_regs (const struct loop *, enum unroll_types,
+ int);
+static int find_splittable_givs (const struct loop *, struct iv_class *,
+ enum unroll_types, rtx, int);
+static int reg_dead_after_loop (const struct loop *, rtx);
+static rtx fold_rtx_mult_add (rtx, rtx, rtx, enum machine_mode);
+static rtx remap_split_bivs (struct loop *, rtx);
+static rtx find_common_reg_term (rtx, rtx);
+static rtx subtract_reg_term (rtx, rtx);
+static rtx loop_find_equiv_value (const struct loop *, rtx);
+static rtx ujump_to_loop_cont (rtx, rtx);
/* Try to unroll one loop and split induction variables in the loop.
@@ -226,10 +228,7 @@ static rtx ujump_to_loop_cont PARAMS ((rtx, rtx));
in loop.c. */
void
-unroll_loop (loop, insn_count, strength_reduce_p)
- struct loop *loop;
- int insn_count;
- int strength_reduce_p;
+unroll_loop (struct loop *loop, int insn_count, int strength_reduce_p)
{
struct loop_info *loop_info = LOOP_INFO (loop);
struct loop_ivs *ivs = LOOP_IVS (loop);
@@ -282,12 +281,8 @@ unroll_loop (loop, insn_count, strength_reduce_p)
loop_info->n_iterations = 0;
if (loop_dump_stream && loop_info->n_iterations > 0)
- {
- fputs ("Loop unrolling: ", loop_dump_stream);
- fprintf (loop_dump_stream, HOST_WIDE_INT_PRINT_DEC,
- loop_info->n_iterations);
- fputs (" iterations.\n", loop_dump_stream);
- }
+ fprintf (loop_dump_stream, "Loop unrolling: " HOST_WIDE_INT_PRINT_DEC
+ " iterations.\n", loop_info->n_iterations);
/* Find and save a pointer to the last nonnote insn in the loop. */
@@ -676,14 +671,14 @@ unroll_loop (loop, insn_count, strength_reduce_p)
without initializing fields within the map structure.
To be safe, we use xcalloc to zero the memory. */
- map = (struct inline_remap *) xcalloc (1, sizeof (struct inline_remap));
+ map = xcalloc (1, sizeof (struct inline_remap));
/* Allocate the label map. */
if (max_labelno > 0)
{
- map->label_map = (rtx *) xcalloc (max_labelno, sizeof (rtx));
- local_label = (char *) xcalloc (max_labelno, sizeof (char));
+ map->label_map = xcalloc (max_labelno, sizeof (rtx));
+ local_label = xcalloc (max_labelno, sizeof (char));
}
/* Search the loop and mark all local labels, i.e. the ones which have to
@@ -727,7 +722,7 @@ unroll_loop (loop, insn_count, strength_reduce_p)
/* Allocate space for the insn map. */
- map->insn_map = (rtx *) xmalloc (max_insnno * sizeof (rtx));
+ map->insn_map = xmalloc (max_insnno * sizeof (rtx));
/* Set this to zero, to indicate that we are doing loop unrolling,
not function inlining. */
@@ -753,11 +748,10 @@ unroll_loop (loop, insn_count, strength_reduce_p)
preconditioning code and find_splittable_regs will never be used
to access the splittable_regs[] and addr_combined_regs[] arrays. */
- splittable_regs = (rtx *) xcalloc (maxregnum, sizeof (rtx));
- splittable_regs_updates = (int *) xcalloc (maxregnum, sizeof (int));
- addr_combined_regs
- = (struct induction **) xcalloc (maxregnum, sizeof (struct induction *));
- local_regno = (char *) xcalloc (maxregnum, sizeof (char));
+ splittable_regs = xcalloc (maxregnum, sizeof (rtx));
+ splittable_regs_updates = xcalloc (maxregnum, sizeof (int));
+ addr_combined_regs = xcalloc (maxregnum, sizeof (struct induction *));
+ local_regno = xcalloc (maxregnum, sizeof (char));
/* Mark all local registers, i.e. the ones which are referenced only
inside the loop. */
@@ -859,7 +853,7 @@ unroll_loop (loop, insn_count, strength_reduce_p)
int less_p = (cc == LE || cc == LEU || cc == LT || cc == LTU);
int unsigned_p = (cc == LEU || cc == GEU || cc == LTU || cc == GTU);
- map->reg_map = (rtx *) xmalloc (maxregnum * sizeof (rtx));
+ map->reg_map = xmalloc (maxregnum * sizeof (rtx));
VARRAY_CONST_EQUIV_INIT (map->const_equiv_varray, maxregnum,
"unroll_loop_precondition");
@@ -926,7 +920,7 @@ unroll_loop (loop, insn_count, strength_reduce_p)
/* Now emit a sequence of branches to jump to the proper precond
loop entry point. */
- labels = (rtx *) xmalloc (sizeof (rtx) * unroll_number);
+ labels = xmalloc (sizeof (rtx) * unroll_number);
for (i = 0; i < unroll_number; i++)
labels[i] = gen_label_rtx ();
@@ -1059,8 +1053,8 @@ unroll_loop (loop, insn_count, strength_reduce_p)
emit_label_after (labels[unroll_number - i],
PREV_INSN (loop_start));
- memset ((char *) map->insn_map, 0, max_insnno * sizeof (rtx));
- memset ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0),
+ memset (map->insn_map, 0, max_insnno * sizeof (rtx));
+ memset (&VARRAY_CONST_EQUIV (map->const_equiv_varray, 0),
0, (VARRAY_SIZE (map->const_equiv_varray)
* sizeof (struct const_equiv_data)));
map->const_age = 0;
@@ -1126,7 +1120,7 @@ unroll_loop (loop, insn_count, strength_reduce_p)
/* If reach here, and the loop type is UNROLL_NAIVE, then don't unroll
the loop unless all loops are being unrolled. */
- if (unroll_type == UNROLL_NAIVE && ! flag_unroll_all_loops)
+ if (unroll_type == UNROLL_NAIVE && ! flag_old_unroll_all_loops)
{
if (loop_dump_stream)
fprintf (loop_dump_stream,
@@ -1163,7 +1157,7 @@ unroll_loop (loop, insn_count, strength_reduce_p)
the constant maps also. */
maxregnum = max_reg_num ();
- map->reg_map = (rtx *) xmalloc (maxregnum * sizeof (rtx));
+ map->reg_map = xmalloc (maxregnum * sizeof (rtx));
init_reg_map (map, maxregnum);
@@ -1211,8 +1205,8 @@ unroll_loop (loop, insn_count, strength_reduce_p)
for (i = 0; i < unroll_number; i++)
{
- memset ((char *) map->insn_map, 0, max_insnno * sizeof (rtx));
- memset ((char *) &VARRAY_CONST_EQUIV (map->const_equiv_varray, 0), 0,
+ memset (map->insn_map, 0, max_insnno * sizeof (rtx));
+ memset (&VARRAY_CONST_EQUIV (map->const_equiv_varray, 0), 0,
VARRAY_SIZE (map->const_equiv_varray) * sizeof (struct const_equiv_data));
map->const_age = 0;
@@ -1333,16 +1327,14 @@ unroll_loop (loop, insn_count, strength_reduce_p)
free (map);
}
-/* A helper function for unroll_loop. Emit a compare and branch to
+/* A helper function for unroll_loop. Emit a compare and branch to
satisfy (CMP OP1 OP2), but pass this through the simplifier first.
If the branch turned out to be conditional, return it, otherwise
return NULL. */
static rtx
-simplify_cmp_and_jump_insns (code, mode, op0, op1, label)
- enum rtx_code code;
- enum machine_mode mode;
- rtx op0, op1, label;
+simplify_cmp_and_jump_insns (enum rtx_code code, enum machine_mode mode,
+ rtx op0, rtx op1, rtx label)
{
rtx t, insn;
@@ -1388,10 +1380,9 @@ simplify_cmp_and_jump_insns (code, mode, op0, op1, label)
reflected in RTX_COST. */
int
-precondition_loop_p (loop, initial_value, final_value, increment, mode)
- const struct loop *loop;
- rtx *initial_value, *final_value, *increment;
- enum machine_mode *mode;
+precondition_loop_p (const struct loop *loop, rtx *initial_value,
+ rtx *final_value, rtx *increment,
+ enum machine_mode *mode)
{
rtx loop_start = loop->start;
struct loop_info *loop_info = LOOP_INFO (loop);
@@ -1413,13 +1404,10 @@ precondition_loop_p (loop, initial_value, final_value, increment, mode)
*mode = word_mode;
if (loop_dump_stream)
- {
- fputs ("Preconditioning: Success, number of iterations known, ",
- loop_dump_stream);
- fprintf (loop_dump_stream, HOST_WIDE_INT_PRINT_DEC,
- loop_info->n_iterations);
- fputs (".\n", loop_dump_stream);
- }
+ fprintf (loop_dump_stream,
+ "Preconditioning: Success, number of iterations known, "
+ HOST_WIDE_INT_PRINT_DEC ".\n",
+ loop_info->n_iterations);
return 1;
}
@@ -1551,9 +1539,7 @@ precondition_loop_p (loop, initial_value, final_value, increment, mode)
modes. */
static void
-init_reg_map (map, maxregnum)
- struct inline_remap *map;
- int maxregnum;
+init_reg_map (struct inline_remap *map, int maxregnum)
{
int i;
@@ -1578,9 +1564,7 @@ init_reg_map (map, maxregnum)
The return value is the amount that the giv is incremented by. */
static rtx
-calculate_giv_inc (pattern, src_insn, regno)
- rtx pattern, src_insn;
- unsigned int regno;
+calculate_giv_inc (rtx pattern, rtx src_insn, unsigned int regno)
{
rtx increment;
rtx increment_total = 0;
@@ -1701,9 +1685,7 @@ calculate_giv_inc (pattern, src_insn, regno)
the reg_map entries can change during copying. */
static rtx
-initial_reg_note_copy (notes, map)
- rtx notes;
- struct inline_remap *map;
+initial_reg_note_copy (rtx notes, struct inline_remap *map)
{
rtx copy;
@@ -1729,9 +1711,7 @@ initial_reg_note_copy (notes, map)
/* Fixup insn references in copied REG_NOTES. */
static void
-final_reg_note_copy (notesp, map)
- rtx *notesp;
- struct inline_remap *map;
+final_reg_note_copy (rtx *notesp, struct inline_remap *map)
{
while (*notesp)
{
@@ -1739,29 +1719,18 @@ final_reg_note_copy (notesp, map)
if (GET_CODE (note) == INSN_LIST)
{
- /* Sometimes, we have a REG_WAS_0 note that points to a
- deleted instruction. In that case, we can just delete the
- note. */
- if (REG_NOTE_KIND (note) == REG_WAS_0)
+ rtx insn = map->insn_map[INSN_UID (XEXP (note, 0))];
+
+ /* If we failed to remap the note, something is awry.
+ Allow REG_LABEL as it may reference label outside
+ the unrolled loop. */
+ if (!insn)
{
- *notesp = XEXP (note, 1);
- continue;
+ if (REG_NOTE_KIND (note) != REG_LABEL)
+ abort ();
}
else
- {
- rtx insn = map->insn_map[INSN_UID (XEXP (note, 0))];
-
- /* If we failed to remap the note, something is awry.
- Allow REG_LABEL as it may reference label outside
- the unrolled loop. */
- if (!insn)
- {
- if (REG_NOTE_KIND (note) != REG_LABEL)
- abort ();
- }
- else
- XEXP (note, 0) = insn;
- }
+ XEXP (note, 0) = insn;
}
notesp = &XEXP (note, 1);
@@ -1772,16 +1741,11 @@ final_reg_note_copy (notesp, map)
This is very similar to a loop in expand_inline_function. */
static void
-copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
- unroll_type, start_label, loop_end, insert_before,
- copy_notes_from)
- struct loop *loop;
- rtx copy_start, copy_end;
- struct inline_remap *map;
- rtx exit_label;
- int last_iteration;
- enum unroll_types unroll_type;
- rtx start_label, loop_end, insert_before, copy_notes_from;
+copy_loop_body (struct loop *loop, rtx copy_start, rtx copy_end,
+ struct inline_remap *map, rtx exit_label,
+ int last_iteration, enum unroll_types unroll_type,
+ rtx start_label, rtx loop_end, rtx insert_before,
+ rtx copy_notes_from)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
rtx insn, pattern;
@@ -2044,7 +2008,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
copy = emit_insn (pattern);
}
REG_NOTES (copy) = initial_reg_note_copy (REG_NOTES (insn), map);
- INSN_SCOPE (copy) = INSN_SCOPE (insn);
+ INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
/* If there is a REG_EQUAL note present whose value
is not loop invariant, then delete it, since it
@@ -2098,7 +2062,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
pattern = copy_rtx_and_substitute (PATTERN (insn), map, 0);
copy = emit_jump_insn (pattern);
REG_NOTES (copy) = initial_reg_note_copy (REG_NOTES (insn), map);
- INSN_SCOPE (copy) = INSN_SCOPE (insn);
+ INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
if (JUMP_LABEL (insn))
{
@@ -2222,7 +2186,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
pattern = copy_rtx_and_substitute (PATTERN (insn), map, 0);
copy = emit_call_insn (pattern);
REG_NOTES (copy) = initial_reg_note_copy (REG_NOTES (insn), map);
- INSN_SCOPE (copy) = INSN_SCOPE (insn);
+ INSN_LOCATOR (copy) = INSN_LOCATOR (insn);
SIBLING_CALL_P (copy) = SIBLING_CALL_P (insn);
CONST_OR_PURE_CALL_P (copy) = CONST_OR_PURE_CALL_P (insn);
@@ -2268,13 +2232,13 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
this new block. */
if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED_LABEL
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK
- && ((NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_VTOP
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_CONT)
- || (last_iteration && unroll_type != UNROLL_COMPLETELY)))
- copy = emit_note (NOTE_SOURCE_FILE (insn),
- NOTE_LINE_NUMBER (insn));
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED_LABEL
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK
+ && ((NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_VTOP
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_CONT)
+ || (last_iteration
+ && unroll_type != UNROLL_COMPLETELY)))
+ copy = emit_note_copy (insn);
else
copy = 0;
break;
@@ -2320,11 +2284,11 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
can be a NOTE_INSN_LOOP_CONT note if there is no VTOP note,
as in a do .. while loop. */
if (GET_CODE (insn) == NOTE
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_VTOP
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_CONT)
- emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
+ && ((NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_VTOP
+ && NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_CONT)))
+ emit_note_copy (insn);
}
}
@@ -2341,8 +2305,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration,
won't fit in the immediate field of a PLUS insns. */
void
-emit_unrolled_add (dest_reg, src_reg, increment)
- rtx dest_reg, src_reg, increment;
+emit_unrolled_add (rtx dest_reg, rtx src_reg, rtx increment)
{
rtx result;
@@ -2362,9 +2325,7 @@ emit_unrolled_add (dest_reg, src_reg, increment)
and uses a negligible amount of CPU time on average. */
int
-back_branch_in_range_p (loop, insn)
- const struct loop *loop;
- rtx insn;
+back_branch_in_range_p (const struct loop *loop, rtx insn)
{
rtx p, q, target_insn;
rtx loop_start = loop->start;
@@ -2410,9 +2371,7 @@ back_branch_in_range_p (loop, insn)
value of giv's. */
static rtx
-fold_rtx_mult_add (mult1, mult2, add1, mode)
- rtx mult1, mult2, add1;
- enum machine_mode mode;
+fold_rtx_mult_add (rtx mult1, rtx mult2, rtx add1, enum machine_mode mode)
{
rtx temp, mult_res;
rtx result;
@@ -2459,8 +2418,7 @@ fold_rtx_mult_add (mult1, mult2, add1, mode)
if it can be calculated. Otherwise, returns 0. */
rtx
-biv_total_increment (bl)
- const struct iv_class *bl;
+biv_total_increment (const struct iv_class *bl)
{
struct induction *v;
rtx result;
@@ -2517,10 +2475,8 @@ biv_total_increment (bl)
times, since multiplies by small integers (1,2,3,4) are very cheap. */
static int
-find_splittable_regs (loop, unroll_type, unroll_number)
- const struct loop *loop;
- enum unroll_types unroll_type;
- int unroll_number;
+find_splittable_regs (const struct loop *loop,
+ enum unroll_types unroll_type, int unroll_number)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
struct iv_class *bl;
@@ -2676,12 +2632,9 @@ find_splittable_regs (loop, unroll_type, unroll_number)
Return the number of instructions that set splittable registers. */
static int
-find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
- const struct loop *loop;
- struct iv_class *bl;
- enum unroll_types unroll_type;
- rtx increment;
- int unroll_number ATTRIBUTE_UNUSED;
+find_splittable_givs (const struct loop *loop, struct iv_class *bl,
+ enum unroll_types unroll_type, rtx increment,
+ int unroll_number ATTRIBUTE_UNUSED)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
struct induction *v, *v2;
@@ -2844,8 +2797,9 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
{
rtx tem = gen_reg_rtx (v->mode);
record_base_value (REGNO (tem), v->add_val, 0);
- loop_iv_add_mult_hoist (loop, bl->initial_value, v->mult_val,
- v->add_val, tem);
+ loop_iv_add_mult_hoist (loop,
+ extend_value_for_giv (v, bl->initial_value),
+ v->mult_val, v->add_val, tem);
value = tem;
}
@@ -2915,9 +2869,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number)
it can search past if statements and other similar structures. */
static int
-reg_dead_after_loop (loop, reg)
- const struct loop *loop;
- rtx reg;
+reg_dead_after_loop (const struct loop *loop, rtx reg)
{
rtx insn, label;
enum rtx_code code;
@@ -2991,9 +2943,7 @@ reg_dead_after_loop (loop, reg)
the end of the loop. If we can do it, return that value. */
rtx
-final_biv_value (loop, bl)
- const struct loop *loop;
- struct iv_class *bl;
+final_biv_value (const struct loop *loop, struct iv_class *bl)
{
unsigned HOST_WIDE_INT n_iterations = LOOP_INFO (loop)->n_iterations;
rtx increment, tem;
@@ -3065,9 +3015,7 @@ final_biv_value (loop, bl)
the end of the loop. If we can do it, return that value. */
rtx
-final_giv_value (loop, v)
- const struct loop *loop;
- struct induction *v;
+final_giv_value (const struct loop *loop, struct induction *v)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
struct iv_class *bl;
@@ -3194,9 +3142,7 @@ final_giv_value (loop, v)
the SET_SRC of REG. */
static rtx
-loop_find_equiv_value (loop, reg)
- const struct loop *loop;
- rtx reg;
+loop_find_equiv_value (const struct loop *loop, rtx reg)
{
rtx loop_start = loop->start;
rtx insn, set;
@@ -3249,8 +3195,7 @@ loop_find_equiv_value (loop, reg)
the proper form. */
static rtx
-subtract_reg_term (op, reg)
- rtx op, reg;
+subtract_reg_term (rtx op, rtx reg)
{
if (op == reg)
return const0_rtx;
@@ -3270,8 +3215,7 @@ subtract_reg_term (op, reg)
REG or a PLUS of a REG. */
static rtx
-find_common_reg_term (op0, op1)
- rtx op0, op1;
+find_common_reg_term (rtx op0, rtx op1)
{
if ((GET_CODE (op0) == REG || GET_CODE (op0) == PLUS)
&& (GET_CODE (op1) == REG || GET_CODE (op1) == PLUS))
@@ -3307,8 +3251,7 @@ find_common_reg_term (op0, op1)
be calculated, otherwise returns zero. */
unsigned HOST_WIDE_INT
-loop_iterations (loop)
- struct loop *loop;
+loop_iterations (struct loop *loop)
{
struct loop_info *loop_info = LOOP_INFO (loop);
struct loop_ivs *ivs = LOOP_IVS (loop);
@@ -3479,7 +3422,20 @@ loop_iterations (loop)
"Loop iterations: Iteration var not an integer.\n");
return 0;
}
- else if (REG_IV_TYPE (ivs, REGNO (iteration_var)) == BASIC_INDUCT)
+
+ /* Try swapping the comparison to identify a suitable iv. */
+ if (REG_IV_TYPE (ivs, REGNO (iteration_var)) != BASIC_INDUCT
+ && REG_IV_TYPE (ivs, REGNO (iteration_var)) != GENERAL_INDUCT
+ && GET_CODE (comparison_value) == REG
+ && REGNO (comparison_value) < ivs->n_regs)
+ {
+ rtx temp = comparison_value;
+ comparison_code = swap_condition (comparison_code);
+ comparison_value = iteration_var;
+ iteration_var = temp;
+ }
+
+ if (REG_IV_TYPE (ivs, REGNO (iteration_var)) == BASIC_INDUCT)
{
if (REGNO (iteration_var) >= ivs->n_regs)
abort ();
@@ -3606,6 +3562,7 @@ loop_iterations (loop)
unsigned_p = 1;
case GT:
compare_dir = -1;
+ break;
case NE:
compare_dir = 0;
break;
@@ -3814,7 +3771,7 @@ loop_iterations (loop)
if (inc_once == final_value)
{
/* The iterator value once through the loop is equal to the
- comparision value. Either we have an infinite loop, or
+ comparison value. Either we have an infinite loop, or
we'll loop twice. */
if (increment == const0_rtx)
return 0;
@@ -3940,9 +3897,7 @@ loop_iterations (loop)
copying. */
static rtx
-remap_split_bivs (loop, x)
- struct loop *loop;
- rtx x;
+remap_split_bivs (struct loop *loop, rtx x)
{
struct loop_ivs *ivs = LOOP_IVS (loop);
enum rtx_code code;
@@ -4010,12 +3965,8 @@ remap_split_bivs (loop, x)
must dominate LAST_UID. */
int
-set_dominates_use (regno, first_uid, last_uid, copy_start, copy_end)
- int regno;
- int first_uid;
- int last_uid;
- rtx copy_start;
- rtx copy_end;
+set_dominates_use (int regno, int first_uid, int last_uid, rtx copy_start,
+ rtx copy_end)
{
int passed_jump = 0;
rtx p = NEXT_INSN (copy_start);
@@ -4062,9 +4013,7 @@ set_dominates_use (regno, first_uid, last_uid, copy_start, copy_end)
deleted so that we execute the single iteration. */
static rtx
-ujump_to_loop_cont (loop_start, loop_cont)
- rtx loop_start;
- rtx loop_cont;
+ujump_to_loop_cont (rtx loop_start, rtx loop_cont)
{
rtx x, label, label_ref;
diff --git a/contrib/gcc/unwind-c.c b/contrib/gcc/unwind-c.c
index 2730536d5df3..c066a13070db 100644
--- a/contrib/gcc/unwind-c.c
+++ b/contrib/gcc/unwind-c.c
@@ -10,6 +10,15 @@ 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.
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combined
+executable.)
+
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
@@ -23,6 +32,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tconfig.h"
#include "tsystem.h"
#include "unwind.h"
+#define NO_SIZE_OF_ENCODED_VALUE
#include "unwind-pe.h"
typedef struct
diff --git a/contrib/gcc/unwind-dw2-fde-darwin.c b/contrib/gcc/unwind-dw2-fde-darwin.c
index 630ffafab6da..24cf3bca7e99 100644
--- a/contrib/gcc/unwind-dw2-fde-darwin.c
+++ b/contrib/gcc/unwind-dw2-fde-darwin.c
@@ -1,19 +1,19 @@
-/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -41,8 +41,8 @@ typedef int __gthread_mutex_t;
#define __gthread_mutex_lock(x) (void)(x)
#define __gthread_mutex_unlock(x) (void)(x)
-static fde * _Unwind_Find_registered_FDE (void *pc,
- struct dwarf_eh_bases *bases);
+static const fde * _Unwind_Find_registered_FDE (void *pc,
+ struct dwarf_eh_bases *bases);
#define _Unwind_Find_FDE _Unwind_Find_registered_FDE
#include "unwind-dw2-fde.c"
@@ -99,13 +99,28 @@ enum {
because this object might be about to be unloaded. Called by
KeyMgr. */
-static void
+static void
live_image_destructor (struct live_images *image)
{
if (image->object_info)
{
- /* Free any sorted arrays. */
- __deregister_frame_info_bases (image->fde);
+ struct km_object_info *the_obj_info;
+
+ the_obj_info =
+ _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST);
+ if (the_obj_info)
+ {
+ seen_objects = the_obj_info->seen_objects;
+ unseen_objects = the_obj_info->unseen_objects;
+
+ /* Free any sorted arrays. */
+ __deregister_frame_info_bases (image->fde);
+
+ the_obj_info->seen_objects = seen_objects;
+ the_obj_info->unseen_objects = unseen_objects;
+ }
+ _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST,
+ the_obj_info);
free (image->object_info);
image->object_info = NULL;
@@ -121,11 +136,11 @@ live_image_destructor (struct live_images *image)
give each unseen image a new `struct object'. Even if we can't,
check whether the PC is inside the FDE of each unseen image.
*/
-
-static inline fde *
+
+static inline const fde *
examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc)
{
- fde *result = NULL;
+ const fde *result = NULL;
struct live_images *image;
image = _keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_LIVE_IMAGE_LIST);
@@ -135,7 +150,7 @@ examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc)
{
char *fde;
unsigned long sz;
-
+
fde = getsectdatafromheader (image->mh, "__DATA", "__eh_frame", &sz);
if (fde == NULL)
{
@@ -144,20 +159,20 @@ examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc)
if (fde != NULL)
image->examined_p |= IMAGE_IS_TEXT_MASK;
}
-
+
/* If .eh_frame is empty, don't register at all. */
if (fde != NULL && sz > 0)
{
char *real_fde = (fde + image->vm_slide);
struct object *ob = NULL;
struct object panicob;
-
+
if (! dont_alloc)
ob = calloc (1, sizeof (struct object));
dont_alloc |= ob == NULL;
if (dont_alloc)
ob = &panicob;
-
+
ob->pc_begin = (void *)-1;
ob->tbase = 0;
ob->dbase = 0;
@@ -165,34 +180,42 @@ examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc)
ob->s.i = 0;
ob->s.b.encoding = DW_EH_PE_omit;
ob->fde_end = real_fde + sz;
-
+
+ image->fde = real_fde;
+
+ result = search_object (ob, pc);
+
if (! dont_alloc)
{
- ob->next = unseen_objects;
- unseen_objects = ob;
-
+ struct object **p;
+
image->destructor = live_image_destructor;
image->object_info = ob;
-
- image->examined_p |= (EXAMINED_IMAGE_MASK
+
+ image->examined_p |= (EXAMINED_IMAGE_MASK
| DESTRUCTOR_MAY_BE_CALLED_LIVE);
+
+ /* Insert the object into the classified list. */
+ for (p = &seen_objects; *p ; p = &(*p)->next)
+ if ((*p)->pc_begin < ob->pc_begin)
+ break;
+ ob->next = *p;
+ *p = ob;
}
- image->fde = real_fde;
-
- result = search_object (ob, pc);
+
if (result)
{
int encoding;
-
+
bases->tbase = ob->tbase;
bases->dbase = ob->dbase;
-
+
encoding = ob->s.b.encoding;
if (ob->s.b.mixed_encoding)
encoding = get_fde_encoding (result);
- read_encoded_value_with_base (encoding,
+ read_encoded_value_with_base (encoding,
base_from_object (encoding, ob),
- result->pc_begin,
+ result->pc_begin,
(_Unwind_Ptr *)&bases->func);
break;
}
@@ -206,25 +229,25 @@ examine_objects (void *pc, struct dwarf_eh_bases *bases, int dont_alloc)
return result;
}
-fde *
+const fde *
_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
{
struct km_object_info *the_obj_info;
- fde *ret = NULL;
+ const fde *ret = NULL;
- the_obj_info =
+ the_obj_info =
_keymgr_get_and_lock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST);
if (! the_obj_info)
the_obj_info = calloc (1, sizeof (*the_obj_info));
-
+
if (the_obj_info != NULL)
{
seen_objects = the_obj_info->seen_objects;
unseen_objects = the_obj_info->unseen_objects;
-
+
ret = _Unwind_Find_registered_FDE (pc, bases);
}
-
+
/* OK, didn't find it in the list of FDEs we've seen before,
so go through and look at the new ones. */
if (ret == NULL)
@@ -234,8 +257,8 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
{
the_obj_info->seen_objects = seen_objects;
the_obj_info->unseen_objects = unseen_objects;
- _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST,
- the_obj_info);
}
+ _keymgr_set_and_unlock_processwide_ptr (KEYMGR_GCC3_DW2_OBJ_LIST,
+ the_obj_info);
return ret;
}
diff --git a/contrib/gcc/unwind-dw2-fde-glibc.c b/contrib/gcc/unwind-dw2-fde-glibc.c
index 21b3321ceb62..71fbf6144da4 100644
--- a/contrib/gcc/unwind-dw2-fde-glibc.c
+++ b/contrib/gcc/unwind-dw2-fde-glibc.c
@@ -1,20 +1,20 @@
-/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>.
- This file is part of GNU CC.
+ This file is part of GCC.
- GNU CC is free software; you can redistribute it and/or modify
+ 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 2, or (at your option)
any later version.
- GNU CC is distributed in the hope that it will be useful,
+ 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 GNU CC; see the file COPYING. If not, write to
+ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -35,12 +35,12 @@
#include "auto-host.h" /* For HAVE_LD_EH_FRAME_HDR. */
#include "tconfig.h"
+#include "tsystem.h"
#ifndef inhibit_libc
-#include <stddef.h>
-#include <stdlib.h>
#include <link.h>
#endif
-#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
#include "dwarf2.h"
#include "unwind.h"
#define NO_BASE_OF_ENCODED_VALUE
@@ -52,7 +52,7 @@
&& (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
-static fde * _Unwind_Find_registered_FDE (void *pc, struct dwarf_eh_bases *bases);
+static const fde * _Unwind_Find_registered_FDE (void *pc, struct dwarf_eh_bases *bases);
#define _Unwind_Find_FDE _Unwind_Find_registered_FDE
#include "unwind-dw2-fde.c"
@@ -68,7 +68,7 @@ struct unw_eh_callback_data
void *tbase;
void *dbase;
void *func;
- fde *ret;
+ const fde *ret;
};
struct unw_eh_frame_hdr
@@ -155,7 +155,7 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
data->dbase = NULL;
if (p_dynamic)
{
- /* For dynamicly linked executables and shared libraries,
+ /* For dynamically linked executables and shared libraries,
DT_PLTGOT is the gp value for that object. */
ElfW(Dyn) *dyn = (ElfW(Dyn) *) (p_dynamic->p_vaddr + load_base);
for (; dyn->d_tag != DT_NULL ; dyn++)
@@ -170,9 +170,6 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
# error What is DW_EH_PE_datarel base on this platform?
# endif
#endif
-#ifdef CRT_GET_RFIB_TEXT
-# error What is DW_EH_PE_textrel base on this platform?
-#endif
p = read_encoded_value_with_base (hdr->eh_frame_ptr_enc,
base_from_cb_data (hdr->eh_frame_ptr_enc,
@@ -264,11 +261,11 @@ _Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr)
return 1;
}
-fde *
+const fde *
_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
{
struct unw_eh_callback_data data;
- fde *ret;
+ const fde *ret;
ret = _Unwind_Find_registered_FDE (pc, bases);
if (ret != NULL)
diff --git a/contrib/gcc/unwind-dw2-fde.c b/contrib/gcc/unwind-dw2-fde.c
index f4cb4bb45e9e..74e64e5eb800 100644
--- a/contrib/gcc/unwind-dw2-fde.c
+++ b/contrib/gcc/unwind-dw2-fde.c
@@ -1,5 +1,5 @@
/* Subroutines needed for unwinding stack frames for exception handling. */
-/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Jason Merrill <jason@cygnus.com>.
This file is part of GCC.
@@ -31,6 +31,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef _Unwind_Find_FDE
#include "tconfig.h"
#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
#include "dwarf2.h"
#include "unwind.h"
#define NO_BASE_OF_ENCODED_VALUE
@@ -72,11 +74,11 @@ init_object_mutex_once (void)
/* Called from crtbegin.o to register the unwind info for an object. */
void
-__register_frame_info_bases (void *begin, struct object *ob,
+__register_frame_info_bases (const void *begin, struct object *ob,
void *tbase, void *dbase)
{
/* If .eh_frame is empty, don't register at all. */
- if (*(uword *) begin == 0)
+ if ((uword *) begin == 0 || *(uword *) begin == 0)
return;
ob->pc_begin = (void *)-1;
@@ -99,7 +101,7 @@ __register_frame_info_bases (void *begin, struct object *ob,
}
void
-__register_frame_info (void *begin, struct object *ob)
+__register_frame_info (const void *begin, struct object *ob)
{
__register_frame_info_bases (begin, ob, 0, 0);
}
@@ -113,7 +115,7 @@ __register_frame (void *begin)
if (*(uword *) begin == 0)
return;
- ob = (struct object *) malloc (sizeof (struct object));
+ ob = malloc (sizeof (struct object));
__register_frame_info (begin, ob);
}
@@ -151,7 +153,7 @@ __register_frame_info_table (void *begin, struct object *ob)
void
__register_frame_table (void *begin)
{
- struct object *ob = (struct object *) malloc (sizeof (struct object));
+ struct object *ob = malloc (sizeof (struct object));
__register_frame_info_table (begin, ob);
}
@@ -168,13 +170,13 @@ __register_frame_table (void *begin)
implements __register_frame_info_bases. */
void *
-__deregister_frame_info_bases (void *begin)
+__deregister_frame_info_bases (const void *begin)
{
struct object **p;
struct object *ob = 0;
/* If .eh_frame is empty, we haven't registered. */
- if (*(uword *) begin == 0)
+ if ((uword *) begin == 0 || *(uword *) begin == 0)
return ob;
init_object_mutex_once ();
@@ -218,7 +220,7 @@ __deregister_frame_info_bases (void *begin)
}
void *
-__deregister_frame_info (void *begin)
+__deregister_frame_info (const void *begin)
{
return __deregister_frame_info_bases (begin);
}
@@ -260,7 +262,7 @@ base_from_object (unsigned char encoding, struct object *ob)
/* ??? This is a subset of extract_cie_info from unwind-dw2.c. */
static int
-get_cie_encoding (struct dwarf_cie *cie)
+get_cie_encoding (const struct dwarf_cie *cie)
{
const unsigned char *aug, *p;
_Unwind_Ptr dummy;
@@ -302,7 +304,7 @@ get_cie_encoding (struct dwarf_cie *cie)
}
static inline int
-get_fde_encoding (struct dwarf_fde *f)
+get_fde_encoding (const struct dwarf_fde *f)
{
return get_cie_encoding (get_cie (f));
}
@@ -316,7 +318,7 @@ get_fde_encoding (struct dwarf_fde *f)
static int
fde_unencoded_compare (struct object *ob __attribute__((unused)),
- fde *x, fde *y)
+ const fde *x, const fde *y)
{
_Unwind_Ptr x_ptr = *(_Unwind_Ptr *) x->pc_begin;
_Unwind_Ptr y_ptr = *(_Unwind_Ptr *) y->pc_begin;
@@ -329,7 +331,7 @@ fde_unencoded_compare (struct object *ob __attribute__((unused)),
}
static int
-fde_single_encoding_compare (struct object *ob, fde *x, fde *y)
+fde_single_encoding_compare (struct object *ob, const fde *x, const fde *y)
{
_Unwind_Ptr base, x_ptr, y_ptr;
@@ -345,7 +347,7 @@ fde_single_encoding_compare (struct object *ob, fde *x, fde *y)
}
static int
-fde_mixed_encoding_compare (struct object *ob, fde *x, fde *y)
+fde_mixed_encoding_compare (struct object *ob, const fde *x, const fde *y)
{
int x_encoding, y_encoding;
_Unwind_Ptr x_ptr, y_ptr;
@@ -365,7 +367,7 @@ fde_mixed_encoding_compare (struct object *ob, fde *x, fde *y)
return 0;
}
-typedef int (*fde_compare_t) (struct object *, fde *, fde *);
+typedef int (*fde_compare_t) (struct object *, const fde *, const fde *);
/* This is a special mix of insertion sort and heap sort, optimized for
@@ -392,11 +394,11 @@ start_fde_sort (struct fde_accumulator *accu, size_t count)
if (! count)
return 0;
- size = sizeof (struct fde_vector) + sizeof (fde *) * count;
- if ((accu->linear = (struct fde_vector *) malloc (size)))
+ size = sizeof (struct fde_vector) + sizeof (const fde *) * count;
+ if ((accu->linear = malloc (size)))
{
accu->linear->count = 0;
- if ((accu->erratic = (struct fde_vector *) malloc (size)))
+ if ((accu->erratic = malloc (size)))
accu->erratic->count = 0;
return 1;
}
@@ -405,7 +407,7 @@ start_fde_sort (struct fde_accumulator *accu, size_t count)
}
static inline void
-fde_insert (struct fde_accumulator *accu, fde *this_fde)
+fde_insert (struct fde_accumulator *accu, const fde *this_fde)
{
if (accu->linear)
accu->linear->array[accu->linear->count++] = this_fde;
@@ -427,29 +429,29 @@ static inline void
fde_split (struct object *ob, fde_compare_t fde_compare,
struct fde_vector *linear, struct fde_vector *erratic)
{
- static fde *marker;
+ static const fde *marker;
size_t count = linear->count;
- fde **chain_end = &marker;
+ const fde **chain_end = &marker;
size_t i, j, k;
/* This should optimize out, but it is wise to make sure this assumption
is correct. Should these have different sizes, we cannot cast between
them and the overlaying onto ERRATIC will not work. */
- if (sizeof (fde *) != sizeof (fde **))
+ if (sizeof (const fde *) != sizeof (const fde **))
abort ();
for (i = 0; i < count; i++)
{
- fde **probe;
+ const fde **probe;
for (probe = chain_end;
probe != &marker && fde_compare (ob, linear->array[i], *probe) < 0;
probe = chain_end)
{
- chain_end = (fde **) erratic->array[probe - linear->array];
+ chain_end = (const fde **) erratic->array[probe - linear->array];
erratic->array[probe - linear->array] = NULL;
}
- erratic->array[i] = (fde *) chain_end;
+ erratic->array[i] = (const fde *) chain_end;
chain_end = &linear->array[i];
}
@@ -465,6 +467,34 @@ fde_split (struct object *ob, fde_compare_t fde_compare,
erratic->count = k;
}
+#define SWAP(x,y) do { const fde * tmp = x; x = y; y = tmp; } while (0)
+
+/* Convert a semi-heap to a heap. A semi-heap is a heap except possibly
+ for the first (root) node; push it down to its rightful place. */
+
+static void
+frame_downheap (struct object *ob, fde_compare_t fde_compare, const fde **a,
+ int lo, int hi)
+{
+ int i, j;
+
+ for (i = lo, j = 2*i+1;
+ j < hi;
+ j = 2*i+1)
+ {
+ if (j+1 < hi && fde_compare (ob, a[j], a[j+1]) < 0)
+ ++j;
+
+ if (fde_compare (ob, a[i], a[j]) < 0)
+ {
+ SWAP (a[i], a[j]);
+ i = j;
+ }
+ else
+ break;
+ }
+}
+
/* This is O(n log(n)). BSD/OS defines heapsort in stdlib.h, so we must
use a name that does not conflict. */
@@ -475,59 +505,26 @@ frame_heapsort (struct object *ob, fde_compare_t fde_compare,
/* For a description of this algorithm, see:
Samuel P. Harbison, Guy L. Steele Jr.: C, a reference manual, 2nd ed.,
p. 60-61. */
- fde ** a = erratic->array;
+ const fde ** a = erratic->array;
/* A portion of the array is called a "heap" if for all i>=0:
If i and 2i+1 are valid indices, then a[i] >= a[2i+1].
If i and 2i+2 are valid indices, then a[i] >= a[2i+2]. */
-#define SWAP(x,y) do { fde * tmp = x; x = y; y = tmp; } while (0)
size_t n = erratic->count;
- size_t m = n;
- size_t i;
-
- while (m > 0)
+ int m;
+
+ /* Expand our heap incrementally from the end of the array, heapifying
+ each resulting semi-heap as we go. After each step, a[m] is the top
+ of a heap. */
+ for (m = n/2-1; m >= 0; --m)
+ frame_downheap (ob, fde_compare, a, m, n);
+
+ /* Shrink our heap incrementally from the end of the array, first
+ swapping out the largest element a[0] and then re-heapifying the
+ resulting semi-heap. After each step, a[0..m) is a heap. */
+ for (m = n-1; m >= 1; --m)
{
- /* Invariant: a[m..n-1] is a heap. */
- m--;
- for (i = m; 2*i+1 < n; )
- {
- if (2*i+2 < n
- && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
- && fde_compare (ob, a[2*i+2], a[i]) > 0)
- {
- SWAP (a[i], a[2*i+2]);
- i = 2*i+2;
- }
- else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
- {
- SWAP (a[i], a[2*i+1]);
- i = 2*i+1;
- }
- else
- break;
- }
- }
- while (n > 1)
- {
- /* Invariant: a[0..n-1] is a heap. */
- n--;
- SWAP (a[0], a[n]);
- for (i = 0; 2*i+1 < n; )
- {
- if (2*i+2 < n
- && fde_compare (ob, a[2*i+2], a[2*i+1]) > 0
- && fde_compare (ob, a[2*i+2], a[i]) > 0)
- {
- SWAP (a[i], a[2*i+2]);
- i = 2*i+2;
- }
- else if (fde_compare (ob, a[2*i+1], a[i]) > 0)
- {
- SWAP (a[i], a[2*i+1]);
- i = 2*i+1;
- }
- else
- break;
- }
+ SWAP (a[0], a[m]);
+ frame_downheap (ob, fde_compare, a, 0, m);
}
#undef SWAP
}
@@ -538,7 +535,7 @@ fde_merge (struct object *ob, fde_compare_t fde_compare,
struct fde_vector *v1, struct fde_vector *v2)
{
size_t i1, i2;
- fde * fde2;
+ const fde * fde2;
i2 = v2->count;
if (i2 > 0)
@@ -598,16 +595,16 @@ end_fde_sort (struct object *ob, struct fde_accumulator *accu, size_t count)
encountered along the way. */
static size_t
-classify_object_over_fdes (struct object *ob, fde *this_fde)
+classify_object_over_fdes (struct object *ob, const fde *this_fde)
{
- struct dwarf_cie *last_cie = 0;
+ const struct dwarf_cie *last_cie = 0;
size_t count = 0;
int encoding = DW_EH_PE_absptr;
_Unwind_Ptr base = 0;
for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
{
- struct dwarf_cie *this_cie;
+ const struct dwarf_cie *this_cie;
_Unwind_Ptr mask, pc_begin;
/* Skip CIEs. */
@@ -653,15 +650,15 @@ classify_object_over_fdes (struct object *ob, fde *this_fde)
}
static void
-add_fdes (struct object *ob, struct fde_accumulator *accu, fde *this_fde)
+add_fdes (struct object *ob, struct fde_accumulator *accu, const fde *this_fde)
{
- struct dwarf_cie *last_cie = 0;
+ const struct dwarf_cie *last_cie = 0;
int encoding = ob->s.b.encoding;
_Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
{
- struct dwarf_cie *this_cie;
+ const struct dwarf_cie *this_cie;
/* Skip CIEs. */
if (this_fde->CIE_delta == 0)
@@ -769,16 +766,16 @@ init_object (struct object* ob)
used when there was insufficient memory to allocate and sort an
array. */
-static fde *
-linear_search_fdes (struct object *ob, fde *this_fde, void *pc)
+static const fde *
+linear_search_fdes (struct object *ob, const fde *this_fde, void *pc)
{
- struct dwarf_cie *last_cie = 0;
+ const struct dwarf_cie *last_cie = 0;
int encoding = ob->s.b.encoding;
_Unwind_Ptr base = base_from_object (ob->s.b.encoding, ob);
for (; ! last_fde (ob, this_fde); this_fde = next_fde (this_fde))
{
- struct dwarf_cie *this_cie;
+ const struct dwarf_cie *this_cie;
_Unwind_Ptr pc_begin, pc_range;
/* Skip CIEs. */
@@ -838,7 +835,7 @@ linear_search_fdes (struct object *ob, fde *this_fde, void *pc)
/* Binary search for an FDE containing the given PC. Here are three
implementations of increasing complexity. */
-static inline fde *
+static inline const fde *
binary_search_unencoded_fdes (struct object *ob, void *pc)
{
struct fde_vector *vec = ob->u.sort;
@@ -847,7 +844,7 @@ binary_search_unencoded_fdes (struct object *ob, void *pc)
for (lo = 0, hi = vec->count; lo < hi; )
{
size_t i = (lo + hi) / 2;
- fde *f = vec->array[i];
+ const fde *f = vec->array[i];
void *pc_begin;
uaddr pc_range;
@@ -865,7 +862,7 @@ binary_search_unencoded_fdes (struct object *ob, void *pc)
return NULL;
}
-static inline fde *
+static inline const fde *
binary_search_single_encoding_fdes (struct object *ob, void *pc)
{
struct fde_vector *vec = ob->u.sort;
@@ -876,7 +873,7 @@ binary_search_single_encoding_fdes (struct object *ob, void *pc)
for (lo = 0, hi = vec->count; lo < hi; )
{
size_t i = (lo + hi) / 2;
- fde *f = vec->array[i];
+ const fde *f = vec->array[i];
_Unwind_Ptr pc_begin, pc_range;
const char *p;
@@ -895,7 +892,7 @@ binary_search_single_encoding_fdes (struct object *ob, void *pc)
return NULL;
}
-static inline fde *
+static inline const fde *
binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
{
struct fde_vector *vec = ob->u.sort;
@@ -904,7 +901,7 @@ binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
for (lo = 0, hi = vec->count; lo < hi; )
{
size_t i = (lo + hi) / 2;
- fde *f = vec->array[i];
+ const fde *f = vec->array[i];
_Unwind_Ptr pc_begin, pc_range;
const char *p;
int encoding;
@@ -926,7 +923,7 @@ binary_search_mixed_encoding_fdes (struct object *ob, void *pc)
return NULL;
}
-static fde *
+static const fde *
search_object (struct object* ob, void *pc)
{
/* If the data hasn't been sorted, try to do this now. We may have
@@ -959,7 +956,7 @@ search_object (struct object* ob, void *pc)
fde **p;
for (p = ob->u.array; *p ; p++)
{
- fde *f = linear_search_fdes (ob, *p, pc);
+ const fde *f = linear_search_fdes (ob, *p, pc);
if (f)
return f;
}
@@ -970,11 +967,11 @@ search_object (struct object* ob, void *pc)
}
}
-fde *
+const fde *
_Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
{
struct object *ob;
- fde *f = NULL;
+ const fde *f = NULL;
init_object_mutex_once ();
__gthread_mutex_lock (&object_mutex);
diff --git a/contrib/gcc/unwind-dw2-fde.h b/contrib/gcc/unwind-dw2-fde.h
index 7565c49f7547..16ffa9496c27 100644
--- a/contrib/gcc/unwind-dw2-fde.h
+++ b/contrib/gcc/unwind-dw2-fde.h
@@ -1,5 +1,5 @@
/* Subroutines needed for unwinding stack frames for exception handling. */
-/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004
Free Software Foundation, Inc.
Contributed by Jason Merrill <jason@cygnus.com>.
@@ -29,12 +29,14 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
+#ifndef GCC_UNWIND_DW2_FDE_H
+#define GCC_UNWIND_DW2_FDE_H
struct fde_vector
{
- void *orig_data;
+ const void *orig_data;
size_t count;
- struct dwarf_fde *array[];
+ const struct dwarf_fde *array[];
};
struct object
@@ -43,7 +45,7 @@ struct object
void *tbase;
void *dbase;
union {
- struct dwarf_fde *single;
+ const struct dwarf_fde *single;
struct dwarf_fde **array;
struct fde_vector *sort;
} u;
@@ -90,16 +92,16 @@ struct dwarf_eh_bases
};
-extern void __register_frame_info_bases (void *, struct object *,
+extern void __register_frame_info_bases (const void *, struct object *,
void *, void *);
-extern void __register_frame_info (void *, struct object *);
+extern void __register_frame_info (const void *, struct object *);
extern void __register_frame (void *);
extern void __register_frame_info_table_bases (void *, struct object *,
void *, void *);
extern void __register_frame_info_table (void *, struct object *);
extern void __register_frame_table (void *);
-extern void *__deregister_frame_info (void *);
-extern void *__deregister_frame_info_bases (void *);
+extern void *__deregister_frame_info (const void *);
+extern void *__deregister_frame_info_bases (const void *);
extern void __deregister_frame (void *);
@@ -151,22 +153,22 @@ typedef struct dwarf_fde fde;
/* Locate the CIE for a given FDE. */
-static inline struct dwarf_cie *
-get_cie (struct dwarf_fde *f)
+static inline const struct dwarf_cie *
+get_cie (const struct dwarf_fde *f)
{
return (void *)&f->CIE_delta - f->CIE_delta;
}
-static inline fde *
-next_fde (fde *f)
+static inline const fde *
+next_fde (const fde *f)
{
- return (fde *) ((char *) f + f->length + sizeof (f->length));
+ return (const fde *) ((char *) f + f->length + sizeof (f->length));
}
-extern fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
+extern const fde * _Unwind_Find_FDE (void *, struct dwarf_eh_bases *);
static inline int
-last_fde (struct object *obj __attribute__ ((__unused__)), fde *f)
+last_fde (struct object *obj __attribute__ ((__unused__)), const fde *f)
{
#ifdef DWARF2_OBJECT_END_PTR_EXTENSION
return (char *)f == obj->fde_end || f->length == 0;
@@ -174,3 +176,5 @@ last_fde (struct object *obj __attribute__ ((__unused__)), fde *f)
return f->length == 0;
#endif
}
+
+#endif /* unwind-dw2-fde.h */
diff --git a/contrib/gcc/unwind-dw2.c b/contrib/gcc/unwind-dw2.c
index 0e59c7b2ba26..70d32215c7f3 100644
--- a/contrib/gcc/unwind-dw2.c
+++ b/contrib/gcc/unwind-dw2.c
@@ -9,6 +9,15 @@
the Free Software Foundation; either version 2, or (at your option)
any later version.
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+ compiled version of this file into combinations with other programs,
+ and to distribute those combinations without any restriction coming
+ from the use of this file. (The General Public License restrictions
+ do apply in other respects; for example, they cover modification of
+ the file, and distribution when not linked into a combined
+ executable.)
+
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
@@ -21,8 +30,13 @@
#include "tconfig.h"
#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
#include "dwarf2.h"
#include "unwind.h"
+#ifdef __USING_SJLJ_EXCEPTIONS__
+# define NO_SIZE_OF_ENCODED_VALUE
+#endif
#include "unwind-pe.h"
#include "unwind-dw2-fde.h"
#include "gthr.h"
@@ -48,6 +62,15 @@
#define PRE_GCC3_DWARF_FRAME_REGISTERS DWARF_FRAME_REGISTERS
#endif
+#ifndef DWARF_REG_TO_UNWIND_COLUMN
+#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
+#endif
+
+/* A target can do some update context frobbing. */
+#ifndef MD_FROB_UPDATE_CONTEXT
+#define MD_FROB_UPDATE_CONTEXT(CTX, FS) do { } while (0)
+#endif
+
/* This is the register and unwind state for a particular frame. This
provides the information necessary to unwind up past a frame and return
to its caller. */
@@ -84,7 +107,7 @@ typedef struct
REG_UNSAVED,
REG_SAVED_OFFSET,
REG_SAVED_REG,
- REG_SAVED_EXP,
+ REG_SAVED_EXP
} how;
} reg[DWARF_FRAME_REGISTERS+1];
@@ -100,7 +123,7 @@ typedef struct
enum {
CFA_UNSET,
CFA_REG_OFFSET,
- CFA_EXP,
+ CFA_EXP
} cfa_how;
/* The PC described by the current frame state. */
@@ -162,8 +185,29 @@ read_8s (const void *p) { const union unaligned *up = p; return up->s8; }
inline _Unwind_Word
_Unwind_GetGR (struct _Unwind_Context *context, int index)
{
+ int size;
+ void *ptr;
+
+ index = DWARF_REG_TO_UNWIND_COLUMN (index);
+ if (index >= (int) sizeof(dwarf_reg_size_table))
+ abort ();
+ size = dwarf_reg_size_table[index];
+ ptr = context->reg[index];
+
/* This will segfault if the register hasn't been saved. */
- return * (_Unwind_Word *) context->reg[index];
+ if (size == sizeof(_Unwind_Ptr))
+ return * (_Unwind_Ptr *) ptr;
+
+ if (size == sizeof(_Unwind_Word))
+ return * (_Unwind_Word *) ptr;
+
+ abort ();
+}
+
+static inline void *
+_Unwind_GetPtr (struct _Unwind_Context *context, int index)
+{
+ return (void *)(_Unwind_Ptr) _Unwind_GetGR (context, index);
}
/* Get the value of the CFA as saved in CONTEXT. */
@@ -171,7 +215,7 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
_Unwind_Word
_Unwind_GetCFA (struct _Unwind_Context *context)
{
- return (_Unwind_Word) context->cfa;
+ return (_Unwind_Ptr) context->cfa;
}
/* Overwrite the saved value for register REG in CONTEXT with VAL. */
@@ -179,7 +223,39 @@ _Unwind_GetCFA (struct _Unwind_Context *context)
inline void
_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
{
- * (_Unwind_Word *) context->reg[index] = val;
+ int size;
+ void *ptr;
+
+ index = DWARF_REG_TO_UNWIND_COLUMN (index);
+ if (index >= (int) sizeof(dwarf_reg_size_table))
+ abort ();
+ size = dwarf_reg_size_table[index];
+ ptr = context->reg[index];
+
+ if (size == sizeof(_Unwind_Ptr))
+ * (_Unwind_Ptr *) ptr = val;
+ else if (size == sizeof(_Unwind_Word))
+ * (_Unwind_Word *) ptr = val;
+ else
+ abort ();
+}
+
+/* Get the pointer to a register INDEX as saved in CONTEXT. */
+
+static inline void *
+_Unwind_GetGRPtr (struct _Unwind_Context *context, int index)
+{
+ index = DWARF_REG_TO_UNWIND_COLUMN (index);
+ return context->reg[index];
+}
+
+/* Set the pointer to a register INDEX as saved in CONTEXT. */
+
+static inline void
+_Unwind_SetGRPtr (struct _Unwind_Context *context, int index, void *p)
+{
+ index = DWARF_REG_TO_UNWIND_COLUMN (index);
+ context->reg[index] = p;
}
/* Retrieve the return address for CONTEXT. */
@@ -214,7 +290,7 @@ void *
_Unwind_FindEnclosingFunction (void *pc)
{
struct dwarf_eh_bases bases;
- struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
+ const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases);
if (fde)
return bases.func;
else
@@ -240,7 +316,7 @@ _Unwind_GetTextRelBase (struct _Unwind_Context *context)
or NULL if we encountered an undecipherable augmentation. */
static const unsigned char *
-extract_cie_info (struct dwarf_cie *cie, struct _Unwind_Context *context,
+extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
const unsigned char *aug = cie->augmentation;
@@ -747,13 +823,14 @@ execute_cfa_program (const unsigned char *insn_ptr,
reg = insn & 0x3f;
insn_ptr = read_uleb128 (insn_ptr, &utmp);
offset = (_Unwind_Sword) utmp * fs->data_align;
- fs->regs.reg[reg].how = REG_SAVED_OFFSET;
- fs->regs.reg[reg].loc.offset = offset;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
+ = REG_SAVED_OFFSET;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
}
else if ((insn & 0xc0) == DW_CFA_restore)
{
reg = insn & 0x3f;
- fs->regs.reg[reg].how = REG_UNSAVED;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_UNSAVED;
}
else switch (insn)
{
@@ -779,13 +856,14 @@ execute_cfa_program (const unsigned char *insn_ptr,
insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_uleb128 (insn_ptr, &utmp);
offset = (_Unwind_Sword) utmp * fs->data_align;
- fs->regs.reg[reg].how = REG_SAVED_OFFSET;
- fs->regs.reg[reg].loc.offset = offset;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
+ = REG_SAVED_OFFSET;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
break;
case DW_CFA_restore_extended:
insn_ptr = read_uleb128 (insn_ptr, &reg);
- fs->regs.reg[reg].how = REG_UNSAVED;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN(reg)].how = REG_UNSAVED;
break;
case DW_CFA_undefined:
@@ -801,8 +879,8 @@ execute_cfa_program (const unsigned char *insn_ptr,
_Unwind_Word reg2;
insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_uleb128 (insn_ptr, &reg2);
- fs->regs.reg[reg].how = REG_SAVED_REG;
- fs->regs.reg[reg].loc.reg = reg2;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_REG;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.reg = reg2;
}
break;
@@ -858,8 +936,8 @@ execute_cfa_program (const unsigned char *insn_ptr,
case DW_CFA_expression:
insn_ptr = read_uleb128 (insn_ptr, &reg);
- fs->regs.reg[reg].how = REG_SAVED_EXP;
- fs->regs.reg[reg].loc.exp = insn_ptr;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how = REG_SAVED_EXP;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.exp = insn_ptr;
insn_ptr = read_uleb128 (insn_ptr, &utmp);
insn_ptr += utmp;
break;
@@ -869,8 +947,9 @@ execute_cfa_program (const unsigned char *insn_ptr,
insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_sleb128 (insn_ptr, &stmp);
offset = stmp * fs->data_align;
- fs->regs.reg[reg].how = REG_SAVED_OFFSET;
- fs->regs.reg[reg].loc.offset = offset;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
+ = REG_SAVED_OFFSET;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = offset;
break;
case DW_CFA_def_cfa_sf:
@@ -903,8 +982,9 @@ execute_cfa_program (const unsigned char *insn_ptr,
insn_ptr = read_uleb128 (insn_ptr, &reg);
insn_ptr = read_uleb128 (insn_ptr, &utmp);
offset = (_Unwind_Word) utmp * fs->data_align;
- fs->regs.reg[reg].how = REG_SAVED_OFFSET;
- fs->regs.reg[reg].loc.offset = -offset;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].how
+ = REG_SAVED_OFFSET;
+ fs->regs.reg[DWARF_REG_TO_UNWIND_COLUMN (reg)].loc.offset = -offset;
break;
default:
@@ -921,8 +1001,8 @@ execute_cfa_program (const unsigned char *insn_ptr,
static _Unwind_Reason_Code
uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
- struct dwarf_fde *fde;
- struct dwarf_cie *cie;
+ const struct dwarf_fde *fde;
+ const struct dwarf_cie *cie;
const unsigned char *aug, *insn, *end;
memset (fs, 0, sizeof (*fs));
@@ -1045,6 +1125,23 @@ __frame_state_for (void *pc_target, struct frame_state *state_in)
return state_in;
}
+typedef union { _Unwind_Ptr ptr; _Unwind_Word word; } _Unwind_SpTmp;
+
+static inline void
+_Unwind_SetSpColumn (struct _Unwind_Context *context, void *cfa,
+ _Unwind_SpTmp *tmp_sp)
+{
+ int size = dwarf_reg_size_table[__builtin_dwarf_sp_column ()];
+
+ if (size == sizeof(_Unwind_Ptr))
+ tmp_sp->ptr = (_Unwind_Ptr) cfa;
+ else if (size == sizeof(_Unwind_Word))
+ tmp_sp->word = (_Unwind_Ptr) cfa;
+ else
+ abort ();
+ _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), tmp_sp);
+}
+
static void
uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
{
@@ -1068,21 +1165,18 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
Always zap the saved stack pointer value for the next frame; carrying
the value over from one frame to another doesn't make sense. */
- _Unwind_Word tmp_sp;
+ _Unwind_SpTmp tmp_sp;
- if (!orig_context.reg[__builtin_dwarf_sp_column ()])
- {
- tmp_sp = (_Unwind_Ptr) context->cfa;
- orig_context.reg[__builtin_dwarf_sp_column ()] = &tmp_sp;
- }
- context->reg[__builtin_dwarf_sp_column ()] = NULL;
+ if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
+ _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
+ _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
#endif
/* Compute this frame's CFA. */
switch (fs->cfa_how)
{
case CFA_REG_OFFSET:
- cfa = (void *) (_Unwind_Ptr) _Unwind_GetGR (&orig_context, fs->cfa_reg);
+ cfa = _Unwind_GetPtr (&orig_context, fs->cfa_reg);
cfa += fs->cfa_offset;
break;
@@ -1110,11 +1204,14 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
break;
case REG_SAVED_OFFSET:
- context->reg[i] = cfa + fs->regs.reg[i].loc.offset;
+ _Unwind_SetGRPtr (context, i,
+ (void *) (cfa + fs->regs.reg[i].loc.offset));
break;
case REG_SAVED_REG:
- context->reg[i] = orig_context.reg[fs->regs.reg[i].loc.reg];
+ _Unwind_SetGRPtr
+ (context, i,
+ _Unwind_GetGRPtr (&orig_context, fs->regs.reg[i].loc.reg));
break;
case REG_SAVED_EXP:
@@ -1126,10 +1223,12 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
exp = read_uleb128 (exp, &len);
val = execute_stack_op (exp, exp + len, &orig_context,
(_Unwind_Ptr) cfa);
- context->reg[i] = (void *) val;
+ _Unwind_SetGRPtr (context, i, (void *) val);
}
break;
}
+
+ MD_FROB_UPDATE_CONTEXT (context, fs);
}
/* CONTEXT describes the unwind state for a frame, and FS describes the FDE
@@ -1145,7 +1244,7 @@ uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
/* Compute the return address now, since the return address column
can change from frame to frame. */
context->ra = __builtin_extract_return_addr
- ((void *) (_Unwind_Ptr) _Unwind_GetGR (context, fs->retaddr_column));
+ (_Unwind_GetPtr (context, fs->retaddr_column));
}
/* Fill in CONTEXT for top-of-stack. The only valid registers at this
@@ -1162,13 +1261,19 @@ uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
} \
while (0)
+static inline void
+init_dwarf_reg_size_table (void)
+{
+ __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
+}
+
static void
uw_init_context_1 (struct _Unwind_Context *context,
void *outer_cfa, void *outer_ra)
{
void *ra = __builtin_extract_return_addr (__builtin_return_address (0));
_Unwind_FrameState fs;
- _Unwind_Word sp_slot;
+ _Unwind_SpTmp sp_slot;
memset (context, 0, sizeof (struct _Unwind_Context));
context->ra = ra;
@@ -1176,9 +1281,20 @@ uw_init_context_1 (struct _Unwind_Context *context,
if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
abort ();
+#if __GTHREADS
+ {
+ static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
+ if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
+ || dwarf_reg_size_table[0] == 0)
+ init_dwarf_reg_size_table ();
+ }
+#else
+ if (dwarf_reg_size_table[0] == 0)
+ init_dwarf_reg_size_table ();
+#endif
+
/* Force the frame state to use the known cfa value. */
- sp_slot = (_Unwind_Ptr) outer_cfa;
- context->reg[__builtin_dwarf_sp_column ()] = &sp_slot;
+ _Unwind_SetSpColumn (context, outer_cfa, &sp_slot);
fs.cfa_how = CFA_REG_OFFSET;
fs.cfa_reg = __builtin_dwarf_sp_column ();
fs.cfa_offset = 0;
@@ -1205,34 +1321,17 @@ uw_init_context_1 (struct _Unwind_Context *context,
} \
while (0)
-static inline void
-init_dwarf_reg_size_table (void)
-{
- __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
-}
-
static long
uw_install_context_1 (struct _Unwind_Context *current,
struct _Unwind_Context *target)
{
long i;
-#if __GTHREADS
- {
- static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
- if (__gthread_once (&once_regsizes, init_dwarf_reg_size_table) != 0
- || dwarf_reg_size_table[0] == 0)
- init_dwarf_reg_size_table ();
- }
-#else
- if (dwarf_reg_size_table[0] == 0)
- init_dwarf_reg_size_table ();
-#endif
-
for (i = 0; i < DWARF_FRAME_REGISTERS; ++i)
{
void *c = current->reg[i];
void *t = target->reg[i];
+
if (t && c && t != c)
memcpy (c, t, dwarf_reg_size_table[i]);
}
@@ -1242,9 +1341,8 @@ uw_install_context_1 (struct _Unwind_Context *current,
void *target_cfa;
/* If the last frame records a saved stack pointer, use it. */
- if (target->reg[__builtin_dwarf_sp_column ()])
- target_cfa = (void *)(_Unwind_Ptr)
- _Unwind_GetGR (target, __builtin_dwarf_sp_column ());
+ if (_Unwind_GetGRPtr (target, __builtin_dwarf_sp_column ()))
+ target_cfa = _Unwind_GetPtr (target, __builtin_dwarf_sp_column ());
else
target_cfa = target->cfa;
diff --git a/contrib/gcc/unwind-pe.h b/contrib/gcc/unwind-pe.h
index d32e506667d6..398165749a5f 100644
--- a/contrib/gcc/unwind-pe.h
+++ b/contrib/gcc/unwind-pe.h
@@ -1,5 +1,5 @@
/* Exception handling and frame unwind runtime interface routines.
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -8,6 +8,15 @@
the Free Software Foundation; either version 2, or (at your option)
any later version.
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+ compiled version of this file into combinations with other programs,
+ and to distribute those combinations without any restriction coming
+ from the use of this file. (The General Public License restrictions
+ do apply in other respects; for example, they cover modification of
+ the file, and distribution when not linked into a combined
+ executable.)
+
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
@@ -22,6 +31,9 @@
compatibility problems with the base ABI. This is slightly better
than duplicating code, however. */
+#ifndef GCC_UNWIND_PE_H
+#define GCC_UNWIND_PE_H
+
/* If using C++, references to abort have to be qualified with std::. */
#if __cplusplus
#define __gxx_abort std::abort
@@ -52,6 +64,8 @@
#define DW_EH_PE_indirect 0x80
+#ifndef NO_SIZE_OF_ENCODED_VALUE
+
/* Given an encoding, return the number of bytes the format occupies.
This is only defined for fixed-size encodings, and so does not
include leb128. */
@@ -76,6 +90,8 @@ size_of_encoded_value (unsigned char encoding)
__gxx_abort ();
}
+#endif
+
#ifndef NO_BASE_OF_ENCODED_VALUE
/* Given an encoding and an _Unwind_Context, return the base to which
@@ -124,7 +140,7 @@ read_uleb128 (const unsigned char *p, _Unwind_Word *val)
do
{
byte = *p++;
- result |= (byte & 0x7f) << shift;
+ result |= ((_Unwind_Word)byte & 0x7f) << shift;
shift += 7;
}
while (byte & 0x80);
@@ -146,14 +162,14 @@ read_sleb128 (const unsigned char *p, _Unwind_Sword *val)
do
{
byte = *p++;
- result |= (byte & 0x7f) << shift;
+ result |= ((_Unwind_Word)byte & 0x7f) << shift;
shift += 7;
}
while (byte & 0x80);
/* Sign-extend a negative value. */
if (shift < 8 * sizeof(result) && (byte & 0x40) != 0)
- result |= -(1L << shift);
+ result |= -(((_Unwind_Word)1L) << shift);
*val = (_Unwind_Sword) result;
return p;
@@ -178,7 +194,7 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
signed s8 __attribute__ ((mode (DI)));
} __attribute__((__packed__));
- union unaligned *u = (union unaligned *) p;
+ const union unaligned *u = (const union unaligned *) p;
_Unwind_Internal_Ptr result;
if (encoding == DW_EH_PE_aligned)
@@ -186,7 +202,7 @@ read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
_Unwind_Internal_Ptr a = (_Unwind_Internal_Ptr) p;
a = (a + sizeof (void *) - 1) & - sizeof(void *);
result = *(_Unwind_Internal_Ptr *) a;
- p = (const unsigned char *) (a + sizeof (void *));
+ p = (const unsigned char *) (_Unwind_Internal_Ptr) (a + sizeof (void *));
}
else
{
@@ -271,3 +287,5 @@ read_encoded_value (struct _Unwind_Context *context, unsigned char encoding,
}
#endif
+
+#endif /* unwind-pe.h */
diff --git a/contrib/gcc/unwind-sjlj.c b/contrib/gcc/unwind-sjlj.c
index 7b523384647f..505bb86dc5ae 100644
--- a/contrib/gcc/unwind-sjlj.c
+++ b/contrib/gcc/unwind-sjlj.c
@@ -1,5 +1,5 @@
-/* DWARF2 exception handling and frame unwind runtime interface routines.
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002
+/* SJLJ exception handling and frame unwind runtime interface routines.
+ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
This file is part of GCC.
@@ -9,6 +9,15 @@
the Free Software Foundation; either version 2, or (at your option)
any later version.
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+ compiled version of this file into combinations with other programs,
+ and to distribute those combinations without any restriction coming
+ from the use of this file. (The General Public License restrictions
+ do apply in other respects; for example, they cover modification of
+ the file, and distribution when not linked into a combined
+ executable.)
+
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
@@ -21,6 +30,8 @@
#include "tconfig.h"
#include "tsystem.h"
+#include "coretypes.h"
+#include "tm.h"
#include "unwind.h"
#include "gthr.h"
@@ -92,15 +103,9 @@ static __gthread_key_t fc_key;
static int use_fc_key = -1;
static void
-fc_key_dtor (void *ptr)
-{
- __gthread_key_dtor (fc_key, ptr);
-}
-
-static void
fc_key_init (void)
{
- use_fc_key = __gthread_key_create (&fc_key, fc_key_dtor) == 0;
+ use_fc_key = __gthread_key_create (&fc_key, 0) == 0;
}
static void
@@ -177,10 +182,10 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index)
/* Get the value of the CFA as saved in CONTEXT. */
_Unwind_Word
-_Unwind_GetCFA (struct _Unwind_Context *context)
+_Unwind_GetCFA (struct _Unwind_Context *context __attribute__((unused)))
{
/* ??? Ideally __builtin_setjmp places the CFA in the jmpbuf. */
- return NULL;
+ return (_Unwind_Word) 0;
}
void
@@ -218,7 +223,7 @@ _Unwind_GetRegionStart (struct _Unwind_Context *context __attribute__((unused))
}
void *
-_Unwind_FindEnclosingFunction (void *pc)
+_Unwind_FindEnclosingFunction (void *pc __attribute__((unused)))
{
return NULL;
}
diff --git a/contrib/gcc/unwind.h b/contrib/gcc/unwind.h
index 4f39223b03ec..21f3feb86bc9 100644
--- a/contrib/gcc/unwind.h
+++ b/contrib/gcc/unwind.h
@@ -1,5 +1,5 @@
/* Exception handling and frame unwind runtime interface routines.
- Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -28,6 +28,9 @@
/* This is derived from the C++ ABI for IA-64. Where we diverge
for cross-architecture compatibility are noted with "@@@". */
+#ifndef _UNWIND_H
+#define _UNWIND_H
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -205,7 +208,7 @@ _Unwind_GetDataRelBase (struct _Unwind_Context *_C)
}
static inline _Unwind_Ptr
-_Unwind_GetTextRelBase (struct _Unwind_Context *_C)
+_Unwind_GetTextRelBase (struct _Unwind_Context *_C __attribute__ ((__unused__)))
{
abort ();
return 0;
@@ -225,3 +228,5 @@ extern void * _Unwind_FindEnclosingFunction (void *pc);
#ifdef __cplusplus
}
#endif
+
+#endif /* unwind.h */
diff --git a/contrib/gcc/unwind.inc b/contrib/gcc/unwind.inc
index 0938d501f5fb..683e94a121df 100644
--- a/contrib/gcc/unwind.inc
+++ b/contrib/gcc/unwind.inc
@@ -1,5 +1,5 @@
/* Exception handling and frame unwind runtime interface routines. -*- C -*-
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2003 Free Software Foundation, Inc.
This file is part of GCC.
@@ -8,6 +8,15 @@
the Free Software Foundation; either version 2, or (at your option)
any later version.
+ In addition to the permissions in the GNU General Public License, the
+ Free Software Foundation gives you unlimited permission to link the
+ compiled version of this file into combinations with other programs,
+ and to distribute those combinations without any restriction coming
+ from the use of this file. (The General Public License restrictions
+ do apply in other respects; for example, they cover modification of
+ the file, and distribution when not linked into a combined
+ executable.)
+
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
diff --git a/contrib/gcc/value-prof.c b/contrib/gcc/value-prof.c
new file mode 100644
index 000000000000..4f6f3da599a9
--- /dev/null
+++ b/contrib/gcc/value-prof.c
@@ -0,0 +1,708 @@
+/* Transformations based on profile information for values.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "expr.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "value-prof.h"
+#include "output.h"
+#include "flags.h"
+#include "insn-config.h"
+#include "recog.h"
+#include "optabs.h"
+#include "regs.h"
+
+/* In this file value profile based optimizations will be placed (none are
+ here just now, but they are hopefully coming soon).
+
+ Every such optimization should add its requirements for profiled values to
+ insn_values_to_profile function. This function is called from branch_prob
+ in profile.c and the requested values are instrumented by it in the first
+ compilation with -fprofile-arcs. The optimization may then read the
+ gathered data in the second compilation with -fbranch-probabilities.
+ The measured data is appended as REG_VALUE_PROFILE note to the instrumented
+ insn. The argument to the note consists of an EXPR_LIST where its
+ members have the following meaning (from the first to the last):
+
+ -- type of information gathered (HIST_TYPE*)
+ -- the expression that is profiled
+ -- list of counters starting from the first one. */
+
+static void insn_divmod_values_to_profile (rtx, unsigned *,
+ struct histogram_value **);
+static void insn_values_to_profile (rtx, unsigned *, struct histogram_value **);
+static rtx gen_divmod_fixed_value (enum machine_mode, enum rtx_code, rtx, rtx,
+ rtx, gcov_type);
+static rtx gen_mod_pow2 (enum machine_mode, enum rtx_code, rtx, rtx, rtx);
+static rtx gen_mod_subtract (enum machine_mode, enum rtx_code, rtx, rtx, rtx,
+ int);
+static bool divmod_fixed_value_transform (rtx insn);
+static bool mod_pow2_value_transform (rtx);
+static bool mod_subtract_transform (rtx);
+
+/* Release the list of VALUES of length N_VALUES for that we want to measure
+ histograms. */
+void
+free_profiled_values (unsigned n_values ATTRIBUTE_UNUSED,
+ struct histogram_value *values)
+{
+ free (values);
+}
+
+/* Find values inside INSN for that we want to measure histograms for
+ division/modulo optimization. */
+static void
+insn_divmod_values_to_profile (rtx insn, unsigned *n_values,
+ struct histogram_value **values)
+{
+ rtx set, set_src, op1, op2;
+ enum machine_mode mode;
+
+ if (!INSN_P (insn))
+ return;
+
+ set = single_set (insn);
+ if (!set)
+ return;
+
+ mode = GET_MODE (SET_DEST (set));
+ if (!INTEGRAL_MODE_P (mode))
+ return;
+
+ set_src = SET_SRC (set);
+ switch (GET_CODE (set_src))
+ {
+ case DIV:
+ case MOD:
+ case UDIV:
+ case UMOD:
+ op1 = XEXP (set_src, 0);
+ op2 = XEXP (set_src, 1);
+ if (side_effects_p (op2))
+ return;
+
+ /* Check for a special case where the divisor is power of 2. */
+ if ((GET_CODE (set_src) == UMOD) && !CONSTANT_P (op2))
+ {
+ *values = xrealloc (*values,
+ (*n_values + 1)
+ * sizeof (struct histogram_value));
+ (*values)[*n_values].value = op2;
+ (*values)[*n_values].seq = NULL_RTX;
+ (*values)[*n_values].mode = mode;
+ (*values)[*n_values].insn = insn;
+ (*values)[*n_values].type = HIST_TYPE_POW2;
+ (*values)[*n_values].hdata.pow2.may_be_other = 1;
+ (*n_values)++;
+ }
+
+ /* Check whether the divisor is not in fact a constant. */
+ if (!CONSTANT_P (op2))
+ {
+ *values = xrealloc (*values,
+ (*n_values + 1)
+ * sizeof (struct histogram_value));
+ (*values)[*n_values].value = op2;
+ (*values)[*n_values].mode = mode;
+ (*values)[*n_values].seq = NULL_RTX;
+ (*values)[*n_values].insn = insn;
+ (*values)[*n_values].type = HIST_TYPE_SINGLE_VALUE;
+ (*n_values)++;
+ }
+
+ /* For mod, check whether it is not often a noop (or replaceable by
+ a few subtractions). */
+ if (GET_CODE (set_src) == UMOD && !side_effects_p (op1))
+ {
+ rtx tmp;
+
+ *values = xrealloc (*values,
+ (*n_values + 1)
+ * sizeof (struct histogram_value));
+ start_sequence ();
+ tmp = simplify_gen_binary (DIV, mode, copy_rtx (op1), copy_rtx (op2));
+ (*values)[*n_values].value = force_operand (tmp, NULL_RTX);
+ (*values)[*n_values].seq = get_insns ();
+ end_sequence ();
+ (*values)[*n_values].mode = mode;
+ (*values)[*n_values].insn = insn;
+ (*values)[*n_values].type = HIST_TYPE_INTERVAL;
+ (*values)[*n_values].hdata.intvl.int_start = 0;
+ (*values)[*n_values].hdata.intvl.steps = 2;
+ (*values)[*n_values].hdata.intvl.may_be_less = 1;
+ (*values)[*n_values].hdata.intvl.may_be_more = 1;
+ (*n_values)++;
+ }
+ return;
+
+ default:
+ return;
+ }
+}
+
+/* Find values inside INSN for that we want to measure histograms and adds
+ them to list VALUES (increasing the record of its length in N_VALUES). */
+static void
+insn_values_to_profile (rtx insn,
+ unsigned *n_values,
+ struct histogram_value **values)
+{
+ if (flag_value_profile_transformations)
+ insn_divmod_values_to_profile (insn, n_values, values);
+}
+
+/* Find list of values for that we want to measure histograms. */
+void
+find_values_to_profile (unsigned *n_values, struct histogram_value **values)
+{
+ rtx insn;
+ unsigned i;
+
+ *n_values = 0;
+ *values = NULL;
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ insn_values_to_profile (insn, n_values, values);
+
+ for (i = 0; i < *n_values; i++)
+ {
+ switch ((*values)[i].type)
+ {
+ case HIST_TYPE_INTERVAL:
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "Interval counter for insn %d, range %d -- %d.\n",
+ INSN_UID ((*values)[i].insn),
+ (*values)[i].hdata.intvl.int_start,
+ ((*values)[i].hdata.intvl.int_start
+ + (*values)[i].hdata.intvl.steps - 1));
+ (*values)[i].n_counters = (*values)[i].hdata.intvl.steps +
+ ((*values)[i].hdata.intvl.may_be_less ? 1 : 0) +
+ ((*values)[i].hdata.intvl.may_be_more ? 1 : 0);
+ break;
+
+ case HIST_TYPE_POW2:
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "Pow2 counter for insn %d.\n",
+ INSN_UID ((*values)[i].insn));
+ (*values)[i].n_counters = GET_MODE_BITSIZE ((*values)[i].mode) +
+ ((*values)[i].hdata.pow2.may_be_other ? 1 : 0);
+ break;
+
+ case HIST_TYPE_SINGLE_VALUE:
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "Single value counter for insn %d.\n",
+ INSN_UID ((*values)[i].insn));
+ (*values)[i].n_counters = 3;
+ break;
+
+ case HIST_TYPE_CONST_DELTA:
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "Constant delta counter for insn %d.\n",
+ INSN_UID ((*values)[i].insn));
+ (*values)[i].n_counters = 4;
+ break;
+
+ default:
+ abort ();
+ }
+ }
+}
+
+/* Main entry point. Finds REG_VALUE_PROFILE notes from profiler and uses
+ them to identify and exploit properties of values that are hard to analyze
+ statically.
+
+ We do following transformations:
+
+ 1)
+
+ x = a / b;
+
+ where b is almost always a constant N is transformed to
+
+ if (b == N)
+ x = a / N;
+ else
+ x = a / b;
+
+ Analogically with %
+
+ 2)
+
+ x = a % b
+
+ where b is almost always a power of 2 and the division is unsigned
+ TODO -- handle signed case as well
+
+ if ((b & (b - 1)) == 0)
+ x = a & (b - 1);
+ else
+ x = x % b;
+
+ Note that when b = 0, no error will occur and x = a; this is correct,
+ as result of such operation is undefined.
+
+ 3)
+
+ x = a % b
+
+ where a is almost always less then b and the division is unsigned
+ TODO -- handle signed case as well
+
+ x = a;
+ if (x >= b)
+ x %= b;
+
+ 4)
+
+ x = a % b
+
+ where a is almost always less then 2 * b and the division is unsigned
+ TODO -- handle signed case as well
+
+ x = a;
+ if (x >= b)
+ x -= b;
+ if (x >= b)
+ x %= b;
+
+ It would be possible to continue analogically for K * b for other small
+ K's, but it is probably not useful.
+
+ TODO:
+
+ There are other useful cases that could be handled by a similar mechanism,
+ for example:
+
+ for (i = 0; i < n; i++)
+ ...
+
+ transform to (for constant N):
+
+ if (n == N)
+ for (i = 0; i < N; i++)
+ ...
+ else
+ for (i = 0; i < n; i++)
+ ...
+ making unroller happy. Since this may grow the code significantly,
+ we would have to be very careful here. */
+
+bool
+value_profile_transformations (void)
+{
+ rtx insn, next;
+ int changed = false;
+
+ for (insn = get_insns (); insn; insn = next)
+ {
+ next = NEXT_INSN (insn);
+
+ if (!INSN_P (insn))
+ continue;
+
+ /* Scan for insn carrying a histogram. */
+ if (!find_reg_note (insn, REG_VALUE_PROFILE, 0))
+ continue;
+
+ /* Ignore cold areas -- we are growing a code. */
+ if (!maybe_hot_bb_p (BLOCK_FOR_INSN (insn)))
+ continue;
+
+ if (rtl_dump_file)
+ {
+ fprintf (rtl_dump_file, "Trying transformations on insn %d\n",
+ INSN_UID (insn));
+ print_rtl_single (rtl_dump_file, insn);
+ }
+
+ /* Transformations: */
+ if (flag_value_profile_transformations
+ && (mod_subtract_transform (insn)
+ || divmod_fixed_value_transform (insn)
+ || mod_pow2_value_transform (insn)))
+ changed = true;
+ }
+
+ if (changed)
+ {
+ commit_edge_insertions ();
+ allocate_reg_info (max_reg_num (), FALSE, FALSE);
+ }
+
+ return changed;
+}
+
+/* Generate code for transformation 1 (with MODE and OPERATION, operands OP1
+ and OP2 whose value is expected to be VALUE and result TARGET). */
+static rtx
+gen_divmod_fixed_value (enum machine_mode mode, enum rtx_code operation,
+ rtx target, rtx op1, rtx op2, gcov_type value)
+{
+ rtx tmp, tmp1;
+ rtx neq_label = gen_label_rtx ();
+ rtx end_label = gen_label_rtx ();
+ rtx sequence;
+
+ start_sequence ();
+
+ if (!REG_P (op2))
+ {
+ tmp = gen_reg_rtx (mode);
+ emit_move_insn (tmp, copy_rtx (op2));
+ }
+ else
+ tmp = op2;
+
+ do_compare_rtx_and_jump (tmp, GEN_INT (value), NE, 0, mode, NULL_RTX,
+ NULL_RTX, neq_label);
+ tmp1 = simplify_gen_binary (operation, mode, copy_rtx (op1), GEN_INT (value));
+ tmp1 = force_operand (tmp1, target);
+ if (tmp1 != target)
+ emit_move_insn (copy_rtx (target), copy_rtx (tmp1));
+
+ emit_jump_insn (gen_jump (end_label));
+ emit_barrier ();
+
+ emit_label (neq_label);
+ tmp1 = simplify_gen_binary (operation, mode, copy_rtx (op1), copy_rtx (tmp));
+ tmp1 = force_operand (tmp1, target);
+ if (tmp1 != target)
+ emit_move_insn (copy_rtx (target), copy_rtx (tmp1));
+
+ emit_label (end_label);
+
+ sequence = get_insns ();
+ end_sequence ();
+ rebuild_jump_labels (sequence);
+ return sequence;
+}
+
+/* Do transform 1) on INSN if applicable. */
+static bool
+divmod_fixed_value_transform (rtx insn)
+{
+ rtx set, set_src, set_dest, op1, op2, value, histogram;
+ enum rtx_code code;
+ enum machine_mode mode;
+ gcov_type val, count, all;
+ edge e;
+
+ set = single_set (insn);
+ if (!set)
+ return false;
+
+ set_src = SET_SRC (set);
+ set_dest = SET_DEST (set);
+ code = GET_CODE (set_src);
+ mode = GET_MODE (set_dest);
+
+ if (code != DIV && code != MOD && code != UDIV && code != UMOD)
+ return false;
+ op1 = XEXP (set_src, false);
+ op2 = XEXP (set_src, 1);
+
+ for (histogram = REG_NOTES (insn);
+ histogram;
+ histogram = XEXP (histogram, 1))
+ if (REG_NOTE_KIND (histogram) == REG_VALUE_PROFILE
+ && XEXP (XEXP (histogram, 0), 0) == GEN_INT (HIST_TYPE_SINGLE_VALUE))
+ break;
+
+ if (!histogram)
+ return false;
+
+ histogram = XEXP (XEXP (histogram, 0), 1);
+ value = XEXP (histogram, 0);
+ histogram = XEXP (histogram, 1);
+ val = INTVAL (XEXP (histogram, 0));
+ histogram = XEXP (histogram, 1);
+ count = INTVAL (XEXP (histogram, 0));
+ histogram = XEXP (histogram, 1);
+ all = INTVAL (XEXP (histogram, 0));
+
+ /* We require that count is at least half of all; this means
+ that for the transformation to fire the value must be constant
+ at least 50% of time (and 75% gives the guarantee of usage). */
+ if (!rtx_equal_p (op2, value) || 2 * count < all)
+ return false;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Div/mod by constant transformation on insn %d\n",
+ INSN_UID (insn));
+
+ e = split_block (BLOCK_FOR_INSN (insn), PREV_INSN (insn));
+ delete_insn (insn);
+
+ insert_insn_on_edge (
+ gen_divmod_fixed_value (mode, code, set_dest, op1, op2, val), e);
+
+ return true;
+}
+
+/* Generate code for transformation 2 (with MODE and OPERATION, operands OP1
+ and OP2 and result TARGET). */
+static rtx
+gen_mod_pow2 (enum machine_mode mode, enum rtx_code operation, rtx target,
+ rtx op1, rtx op2)
+{
+ rtx tmp, tmp1, tmp2, tmp3;
+ rtx neq_label = gen_label_rtx ();
+ rtx end_label = gen_label_rtx ();
+ rtx sequence;
+
+ start_sequence ();
+
+ if (!REG_P (op2))
+ {
+ tmp = gen_reg_rtx (mode);
+ emit_move_insn (tmp, copy_rtx (op2));
+ }
+ else
+ tmp = op2;
+
+ tmp1 = expand_simple_binop (mode, PLUS, tmp, constm1_rtx, NULL_RTX,
+ 0, OPTAB_WIDEN);
+ tmp2 = expand_simple_binop (mode, AND, tmp, tmp1, NULL_RTX,
+ 0, OPTAB_WIDEN);
+ do_compare_rtx_and_jump (tmp2, const0_rtx, NE, 0, mode, NULL_RTX,
+ NULL_RTX, neq_label);
+ tmp3 = expand_simple_binop (mode, AND, op1, tmp1, target,
+ 0, OPTAB_WIDEN);
+ if (tmp3 != target)
+ emit_move_insn (copy_rtx (target), tmp3);
+ emit_jump_insn (gen_jump (end_label));
+ emit_barrier ();
+
+ emit_label (neq_label);
+ tmp1 = simplify_gen_binary (operation, mode, copy_rtx (op1), copy_rtx (tmp));
+ tmp1 = force_operand (tmp1, target);
+ if (tmp1 != target)
+ emit_move_insn (target, tmp1);
+
+ emit_label (end_label);
+
+ sequence = get_insns ();
+ end_sequence ();
+ rebuild_jump_labels (sequence);
+ return sequence;
+}
+
+/* Do transform 2) on INSN if applicable. */
+static bool
+mod_pow2_value_transform (rtx insn)
+{
+ rtx set, set_src, set_dest, op1, op2, value, histogram;
+ enum rtx_code code;
+ enum machine_mode mode;
+ gcov_type wrong_values, count;
+ edge e;
+ int i;
+
+ set = single_set (insn);
+ if (!set)
+ return false;
+
+ set_src = SET_SRC (set);
+ set_dest = SET_DEST (set);
+ code = GET_CODE (set_src);
+ mode = GET_MODE (set_dest);
+
+ if (code != UMOD)
+ return false;
+ op1 = XEXP (set_src, 0);
+ op2 = XEXP (set_src, 1);
+
+ for (histogram = REG_NOTES (insn);
+ histogram;
+ histogram = XEXP (histogram, 1))
+ if (REG_NOTE_KIND (histogram) == REG_VALUE_PROFILE
+ && XEXP (XEXP (histogram, 0), 0) == GEN_INT (HIST_TYPE_POW2))
+ break;
+
+ if (!histogram)
+ return false;
+
+ histogram = XEXP (XEXP (histogram, 0), 1);
+ value = XEXP (histogram, 0);
+ histogram = XEXP (histogram, 1);
+ wrong_values =INTVAL (XEXP (histogram, 0));
+ histogram = XEXP (histogram, 1);
+
+ count = 0;
+ for (i = 0; i < GET_MODE_BITSIZE (mode); i++)
+ {
+ count += INTVAL (XEXP (histogram, 0));
+ histogram = XEXP (histogram, 1);
+ }
+
+ if (!rtx_equal_p (op2, value))
+ return false;
+
+ /* We require that we hit a power of two at least half of all evaluations. */
+ if (count < wrong_values)
+ return false;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Mod power of 2 transformation on insn %d\n",
+ INSN_UID (insn));
+
+ e = split_block (BLOCK_FOR_INSN (insn), PREV_INSN (insn));
+ delete_insn (insn);
+
+ insert_insn_on_edge (
+ gen_mod_pow2 (mode, code, set_dest, op1, op2), e);
+
+ return true;
+}
+
+/* Generate code for transformations 3 and 4 (with MODE and OPERATION,
+ operands OP1 and OP2, result TARGET and at most SUB subtractions). */
+static rtx
+gen_mod_subtract (enum machine_mode mode, enum rtx_code operation,
+ rtx target, rtx op1, rtx op2, int sub)
+{
+ rtx tmp, tmp1;
+ rtx end_label = gen_label_rtx ();
+ rtx sequence;
+ int i;
+
+ start_sequence ();
+
+ if (!REG_P (op2))
+ {
+ tmp = gen_reg_rtx (mode);
+ emit_move_insn (tmp, copy_rtx (op2));
+ }
+ else
+ tmp = op2;
+
+ emit_move_insn (target, copy_rtx (op1));
+ do_compare_rtx_and_jump (target, tmp, LTU, 0, mode, NULL_RTX,
+ NULL_RTX, end_label);
+
+
+ for (i = 0; i < sub; i++)
+ {
+ tmp1 = expand_simple_binop (mode, MINUS, target, tmp, target,
+ 0, OPTAB_WIDEN);
+ if (tmp1 != target)
+ emit_move_insn (target, tmp1);
+ do_compare_rtx_and_jump (target, tmp, LTU, 0, mode, NULL_RTX,
+ NULL_RTX, end_label);
+ }
+
+ tmp1 = simplify_gen_binary (operation, mode, copy_rtx (target), copy_rtx (tmp));
+ tmp1 = force_operand (tmp1, target);
+ if (tmp1 != target)
+ emit_move_insn (target, tmp1);
+
+ emit_label (end_label);
+
+ sequence = get_insns ();
+ end_sequence ();
+ rebuild_jump_labels (sequence);
+ return sequence;
+}
+
+/* Do transforms 3) and 4) on INSN if applicable. */
+static bool
+mod_subtract_transform (rtx insn)
+{
+ rtx set, set_src, set_dest, op1, op2, value, histogram;
+ enum rtx_code code;
+ enum machine_mode mode;
+ gcov_type wrong_values, counts[2], count, all;
+ edge e;
+ int i;
+
+ set = single_set (insn);
+ if (!set)
+ return false;
+
+ set_src = SET_SRC (set);
+ set_dest = SET_DEST (set);
+ code = GET_CODE (set_src);
+ mode = GET_MODE (set_dest);
+
+ if (code != UMOD)
+ return false;
+ op1 = XEXP (set_src, 0);
+ op2 = XEXP (set_src, 1);
+
+ for (histogram = REG_NOTES (insn);
+ histogram;
+ histogram = XEXP (histogram, 1))
+ if (REG_NOTE_KIND (histogram) == REG_VALUE_PROFILE
+ && XEXP (XEXP (histogram, 0), 0) == GEN_INT (HIST_TYPE_INTERVAL))
+ break;
+
+ if (!histogram)
+ return false;
+
+ histogram = XEXP (XEXP (histogram, 0), 1);
+ value = XEXP (histogram, 0);
+ histogram = XEXP (histogram, 1);
+
+ all = 0;
+ for (i = 0; i < 2; i++)
+ {
+ counts[i] = INTVAL (XEXP (histogram, 0));
+ all += counts[i];
+ histogram = XEXP (histogram, 1);
+ }
+ wrong_values = INTVAL (XEXP (histogram, 0));
+ histogram = XEXP (histogram, 1);
+ wrong_values += INTVAL (XEXP (histogram, 0));
+ all += wrong_values;
+
+ /* We require that we use just subtractions in at least 50% of all
+ evaluations. */
+ count = 0;
+ for (i = 0; i < 2; i++)
+ {
+ count += counts[i];
+ if (count * 2 >= all)
+ break;
+ }
+
+ if (i == 2)
+ return false;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Mod subtract transformation on insn %d\n",
+ INSN_UID (insn));
+
+ e = split_block (BLOCK_FOR_INSN (insn), PREV_INSN (insn));
+ delete_insn (insn);
+
+ insert_insn_on_edge (
+ gen_mod_subtract (mode, code, set_dest, op1, op2, i), e);
+
+ return true;
+}
diff --git a/contrib/gcc/value-prof.h b/contrib/gcc/value-prof.h
new file mode 100644
index 000000000000..afbeb916eb85
--- /dev/null
+++ b/contrib/gcc/value-prof.h
@@ -0,0 +1,64 @@
+/* Definitions for transformations based on profile information for values.
+ Copyright (C) 2003 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Supported histogram types. */
+enum hist_type
+{
+ HIST_TYPE_INTERVAL, /* Measures histogram of values inside a specified
+ interval. */
+ HIST_TYPE_POW2, /* Histogram of power of 2 values. */
+ HIST_TYPE_SINGLE_VALUE, /* Tries to identify the value that is (almost)
+ always constant. */
+ HIST_TYPE_CONST_DELTA /* Tries to identify the (almost) always constant
+ difference between two evaluations of a value. */
+};
+
+#define COUNTER_FOR_HIST_TYPE(TYPE) ((int) (TYPE) + GCOV_FIRST_VALUE_COUNTER)
+#define HIST_TYPE_FOR_COUNTER(COUNTER) \
+ ((enum hist_type) ((COUNTER) - GCOV_FIRST_VALUE_COUNTER))
+
+/* The value to measure. */
+struct histogram_value
+{
+ rtx value; /* The value to profile. */
+ enum machine_mode mode; /* And its mode. */
+ rtx seq; /* Insns required to count the profiled value. */
+ rtx insn; /* Insn before that to measure. */
+ enum hist_type type; /* Type of information to measure. */
+ unsigned n_counters; /* Number of required counters. */
+ union
+ {
+ struct
+ {
+ int int_start; /* First value in interval. */
+ int steps; /* Number of values in it. */
+ int may_be_less; /* May the value be below? */
+ int may_be_more; /* Or above. */
+ } intvl; /* Interval histogram data. */
+ struct
+ {
+ int may_be_other; /* If the value may be non-positive or not 2^k. */
+ } pow2; /* Power of 2 histogram data. */
+ } hdata; /* Profiled information specific data. */
+};
+
+extern void find_values_to_profile (unsigned *, struct histogram_value **);
+extern void free_profiled_values (unsigned, struct histogram_value *);
+extern bool value_profile_transformations (void);
diff --git a/contrib/gcc/varasm.c b/contrib/gcc/varasm.c
index 9a760998f620..e61b5b4a8110 100644
--- a/contrib/gcc/varasm.c
+++ b/contrib/gcc/varasm.c
@@ -1,6 +1,6 @@
/* Output variables, constants and external declarations, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GCC.
@@ -29,6 +29,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "flags.h"
@@ -41,12 +43,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "hashtab.h"
#include "c-pragma.h"
-#include "c-tree.h"
#include "ggc.h"
#include "langhooks.h"
#include "tm_p.h"
#include "debug.h"
#include "target.h"
+#include "cgraph.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data
@@ -94,6 +96,10 @@ struct varasm_status GTY(())
/* Current offset in constant pool (does not include any machine-specific
header). */
HOST_WIDE_INT x_pool_offset;
+
+ /* Number of tree-constants deferred during the expansion of this
+ function. */
+ unsigned int deferred_constants;
};
#define const_rtx_hash_table (cfun->varasm->x_const_rtx_hash_table)
@@ -101,16 +107,12 @@ struct varasm_status GTY(())
#define first_pool (cfun->varasm->x_first_pool)
#define last_pool (cfun->varasm->x_last_pool)
#define pool_offset (cfun->varasm->x_pool_offset)
+#define n_deferred_constants (cfun->varasm->deferred_constants)
/* Number for making the label on the next
constant that is stored in memory. */
-int const_labelno;
-
-/* Number for making the label on the next
- static variable internal to a function. */
-
-int var_labelno;
+static GTY(()) int const_labelno;
/* Carry information from ASM_DECLARE_OBJECT_NAME
to ASM_FINISH_DECLARE_OBJECT. */
@@ -133,51 +135,53 @@ tree last_assemble_variable_decl;
static HOST_WIDE_INT const_alias_set;
-static const char *strip_reg_name PARAMS ((const char *));
-static int contains_pointers_p PARAMS ((tree));
-static void decode_addr_const PARAMS ((tree, struct addr_const *));
-static unsigned int const_hash PARAMS ((tree));
-static unsigned int const_hash_1 PARAMS ((tree));
-static int compare_constant PARAMS ((tree, tree));
-static tree copy_constant PARAMS ((tree));
-static void output_constant_def_contents PARAMS ((tree, int, int));
-static void decode_rtx_const PARAMS ((enum machine_mode, rtx,
- struct rtx_const *));
-static unsigned int const_hash_rtx PARAMS ((enum machine_mode, rtx));
-static int compare_constant_rtx
- PARAMS ((enum machine_mode, rtx, struct constant_descriptor_rtx *));
+static const char *strip_reg_name (const char *);
+static int contains_pointers_p (tree);
+#ifdef ASM_OUTPUT_EXTERNAL
+static bool incorporeal_function_p (tree);
+#endif
+static void decode_addr_const (tree, struct addr_const *);
+static hashval_t const_desc_hash (const void *);
+static int const_desc_eq (const void *, const void *);
+static hashval_t const_hash_1 (const tree);
+static int compare_constant (const tree, const tree);
+static tree copy_constant (tree);
+static void output_constant_def_contents (rtx);
+static void decode_rtx_const (enum machine_mode, rtx, struct rtx_const *);
+static unsigned int const_hash_rtx (enum machine_mode, rtx);
+static int compare_constant_rtx (enum machine_mode, rtx,
+ struct constant_descriptor_rtx *);
static struct constant_descriptor_rtx * record_constant_rtx
- PARAMS ((enum machine_mode, rtx));
-static struct pool_constant *find_pool_constant PARAMS ((struct function *, rtx));
-static void mark_constant_pool PARAMS ((void));
-static void mark_constants PARAMS ((rtx));
-static int mark_constant PARAMS ((rtx *current_rtx, void *data));
-static int output_addressed_constants PARAMS ((tree));
-static void output_after_function_constants PARAMS ((void));
-static unsigned HOST_WIDE_INT array_size_for_constructor PARAMS ((tree));
-static unsigned min_align PARAMS ((unsigned, unsigned));
-static void output_constructor PARAMS ((tree, HOST_WIDE_INT,
- unsigned int));
-static void globalize_decl PARAMS ((tree));
-static void maybe_assemble_visibility PARAMS ((tree));
-static int in_named_entry_eq PARAMS ((const PTR, const PTR));
-static hashval_t in_named_entry_hash PARAMS ((const PTR));
+ (enum machine_mode, rtx);
+static struct pool_constant *find_pool_constant (struct function *, rtx);
+static void mark_constant_pool (void);
+static void mark_constants (rtx);
+static int mark_constant (rtx *current_rtx, void *data);
+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);
+static void maybe_assemble_visibility (tree);
+static int in_named_entry_eq (const void *, const void *);
+static hashval_t in_named_entry_hash (const void *);
#ifdef ASM_OUTPUT_BSS
-static void asm_output_bss PARAMS ((FILE *, tree, const char *, int, int));
+static void asm_output_bss (FILE *, tree, const char *,
+ unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT);
#endif
#ifdef BSS_SECTION_ASM_OP
#ifdef ASM_OUTPUT_ALIGNED_BSS
-static void asm_output_aligned_bss PARAMS ((FILE *, tree, const char *,
- int, int));
+static void asm_output_aligned_bss (FILE *, tree, const char *,
+ unsigned HOST_WIDE_INT, int)
+ ATTRIBUTE_UNUSED;
#endif
#endif /* BSS_SECTION_ASM_OP */
-static hashval_t const_str_htab_hash PARAMS ((const void *x));
-static int const_str_htab_eq PARAMS ((const void *x, const void *y));
-static bool asm_emit_uninitialised PARAMS ((tree, const char*, int, int));
-static void resolve_unique_section PARAMS ((tree, int, int));
-static void mark_weak PARAMS ((tree));
+static bool asm_emit_uninitialised (tree, const char*,
+ unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT);
+static void mark_weak (tree);
-static enum in_section { no_section, in_text, in_data, in_named
+enum in_section { no_section, in_text, in_data, in_named
#ifdef BSS_SECTION_ASM_OP
, in_bss
#endif
@@ -193,7 +197,8 @@ static enum in_section { no_section, in_text, in_data, in_named
#ifdef EXTRA_SECTIONS
, EXTRA_SECTIONS
#endif
-} in_section = no_section;
+};
+static GTY(()) enum in_section in_section = no_section;
/* Return a nonzero value if DECL has a section attribute. */
#ifndef IN_NAMED_SECTION
@@ -203,18 +208,18 @@ static enum in_section { no_section, in_text, in_data, in_named
#endif
/* Text of section name when in_section == in_named. */
-static const char *in_named_name;
+static GTY(()) const char *in_named_name;
/* Hash table of flags that have been used for a particular named section. */
-struct in_named_entry
+struct in_named_entry GTY(())
{
const char *name;
unsigned int flags;
bool declared;
};
-static htab_t in_named_htab;
+static GTY((param_is (struct in_named_entry))) htab_t in_named_htab;
/* Define functions like text_section for any extra sections. */
#ifdef EXTRA_SECTION_FUNCTIONS
@@ -224,23 +229,19 @@ EXTRA_SECTION_FUNCTIONS
/* Tell assembler to switch to text section. */
void
-text_section ()
+text_section (void)
{
if (in_section != in_text)
{
in_section = in_text;
-#ifdef TEXT_SECTION
- TEXT_SECTION ();
-#else
fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
-#endif
}
}
/* Tell assembler to switch to data section. */
void
-data_section ()
+data_section (void)
{
if (in_section != in_data)
{
@@ -258,21 +259,11 @@ data_section ()
}
}
-/* Tell assembler to ALWAYS switch to data section, in case
- it's not sure where it is. */
-
-void
-force_data_section ()
-{
- in_section = no_section;
- data_section ();
-}
-
/* Tell assembler to switch to read-only data section. This is normally
the text section. */
void
-readonly_data_section ()
+readonly_data_section (void)
{
#ifdef READONLY_DATA_SECTION
READONLY_DATA_SECTION (); /* Note this can call data_section. */
@@ -293,7 +284,7 @@ readonly_data_section ()
/* Determine if we're in the text section. */
int
-in_text_section ()
+in_text_section (void)
{
return in_section == in_text;
}
@@ -301,7 +292,7 @@ in_text_section ()
/* Determine if we're in the data section. */
int
-in_data_section ()
+in_data_section (void)
{
return in_section == in_data;
}
@@ -309,9 +300,7 @@ in_data_section ()
/* Helper routines for maintaining in_named_htab. */
static int
-in_named_entry_eq (p1, p2)
- const PTR p1;
- const PTR p2;
+in_named_entry_eq (const void *p1, const void *p2)
{
const struct in_named_entry *old = p1;
const char *new = p2;
@@ -320,8 +309,7 @@ in_named_entry_eq (p1, p2)
}
static hashval_t
-in_named_entry_hash (p)
- const PTR p;
+in_named_entry_hash (const void *p)
{
const struct in_named_entry *old = p;
return htab_hash_string (old->name);
@@ -333,8 +321,7 @@ in_named_entry_hash (p)
has not been seen. */
unsigned int
-get_named_section_flags (section)
- const char *section;
+get_named_section_flags (const char *section)
{
struct in_named_entry **slot;
@@ -350,8 +337,7 @@ get_named_section_flags (section)
section will return false. */
bool
-named_section_first_declaration (name)
- const char *name;
+named_section_first_declaration (const char *name)
{
struct in_named_entry **slot;
@@ -374,9 +360,7 @@ named_section_first_declaration (name)
different set of flags, return false. */
bool
-set_named_section_flags (section, flags)
- const char *section;
- unsigned int flags;
+set_named_section_flags (const char *section, unsigned int flags)
{
struct in_named_entry **slot, *entry;
@@ -387,7 +371,7 @@ set_named_section_flags (section, flags)
if (!entry)
{
- entry = (struct in_named_entry *) xmalloc (sizeof (*entry));
+ entry = ggc_alloc (sizeof (*entry));
*slot = entry;
entry->name = ggc_strdup (section);
entry->flags = flags;
@@ -402,9 +386,7 @@ set_named_section_flags (section, flags)
/* Tell assembler to change to section NAME with attributes FLAGS. */
void
-named_section_flags (name, flags)
- const char *name;
- unsigned int flags;
+named_section_flags (const char *name, unsigned int flags)
{
if (in_section != in_named || strcmp (name, in_named_name) != 0)
{
@@ -429,10 +411,7 @@ named_section_flags (name, flags)
If RELOC is 1, the initializer for DECL contains relocs. */
void
-named_section (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
+named_section (tree decl, const char *name, int reloc)
{
unsigned int flags;
@@ -452,7 +431,7 @@ named_section (decl, name, reloc)
{
flags = get_named_section_flags (name);
if ((flags & SECTION_OVERRIDE) == 0)
- error_with_decl (decl, "%s causes a section type conflict");
+ error ("%J%D causes a section type conflict", decl, decl);
}
named_section_flags (name, flags);
@@ -460,11 +439,9 @@ named_section (decl, name, reloc)
/* If required, set DECL_SECTION_NAME to a unique name. */
-static void
-resolve_unique_section (decl, reloc, flag_function_or_data_sections)
- tree decl;
- int reloc ATTRIBUTE_UNUSED;
- int flag_function_or_data_sections;
+void
+resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED,
+ int flag_function_or_data_sections)
{
if (DECL_SECTION_NAME (decl) == NULL_TREE
&& targetm.have_named_sections
@@ -478,17 +455,11 @@ resolve_unique_section (decl, reloc, flag_function_or_data_sections)
/* Tell the assembler to switch to the bss section. */
void
-bss_section ()
+bss_section (void)
{
if (in_section != in_bss)
{
-#ifdef SHARED_BSS_SECTION_ASM_OP
- if (flag_shared_data)
- fprintf (asm_out_file, "%s\n", SHARED_BSS_SECTION_ASM_OP);
- else
-#endif
- fprintf (asm_out_file, "%s\n", BSS_SECTION_ASM_OP);
-
+ fprintf (asm_out_file, "%s\n", BSS_SECTION_ASM_OP);
in_section = in_bss;
}
}
@@ -501,11 +472,10 @@ bss_section ()
support is localized here. */
static void
-asm_output_bss (file, decl, name, size, rounded)
- FILE *file;
- tree decl ATTRIBUTE_UNUSED;
- const char *name;
- int size ATTRIBUTE_UNUSED, rounded;
+asm_output_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
+ const char *name,
+ unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT rounded)
{
(*targetm.asm_out.globalize_label) (file, name);
bss_section ();
@@ -529,11 +499,9 @@ asm_output_bss (file, decl, name, size, rounded)
support is localized here. */
static void
-asm_output_aligned_bss (file, decl, name, size, align)
- FILE *file;
- tree decl ATTRIBUTE_UNUSED;
- const char *name;
- int size, align;
+asm_output_aligned_bss (FILE *file, tree decl ATTRIBUTE_UNUSED,
+ const char *name, unsigned HOST_WIDE_INT size,
+ int align)
{
bss_section ();
ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
@@ -558,8 +526,7 @@ asm_output_aligned_bss (file, decl, name, size, align)
safer to handle it. */
void
-function_section (decl)
- tree decl;
+function_section (tree decl)
{
if (decl != NULL_TREE
&& DECL_SECTION_NAME (decl) != NULL_TREE)
@@ -572,9 +539,7 @@ function_section (decl)
argument to SELECT_SECTION. */
void
-variable_section (decl, reloc)
- tree decl;
- int reloc;
+variable_section (tree decl, int reloc)
{
if (IN_NAMED_SECTION (decl))
named_section (decl, NULL, reloc);
@@ -585,13 +550,11 @@ variable_section (decl, reloc)
/* Tell assembler to switch to the section for string merging. */
void
-mergeable_string_section (decl, align, flags)
- tree decl ATTRIBUTE_UNUSED;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
- unsigned int flags ATTRIBUTE_UNUSED;
+mergeable_string_section (tree decl ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED,
+ unsigned int flags ATTRIBUTE_UNUSED)
{
-#ifdef HAVE_GAS_SHF_MERGE
- if (flag_merge_constants
+ if (HAVE_GAS_SHF_MERGE && flag_merge_constants
&& TREE_CODE (decl) == STRING_CST
&& TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
&& align <= 256
@@ -653,22 +616,20 @@ mergeable_string_section (decl, align, flags)
}
}
}
-#endif
+
readonly_data_section ();
}
/* Tell assembler to switch to the section for constant merging. */
void
-mergeable_constant_section (mode, align, flags)
- enum machine_mode mode ATTRIBUTE_UNUSED;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
- unsigned int flags ATTRIBUTE_UNUSED;
+mergeable_constant_section (enum machine_mode mode ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED,
+ unsigned int flags ATTRIBUTE_UNUSED)
{
-#ifdef HAVE_GAS_SHF_MERGE
unsigned int modesize = GET_MODE_BITSIZE (mode);
- if (flag_merge_constants
+ if (HAVE_GAS_SHF_MERGE && flag_merge_constants
&& mode != VOIDmode
&& mode != BLKmode
&& modesize <= align
@@ -683,15 +644,14 @@ mergeable_constant_section (mode, align, flags)
named_section_flags (name, flags);
return;
}
-#endif
+
readonly_data_section ();
}
/* Given NAME, a putative register name, discard any customary prefixes. */
static const char *
-strip_reg_name (name)
- const char *name;
+strip_reg_name (const char *name)
{
#ifdef REGISTER_PREFIX
if (!strncmp (name, REGISTER_PREFIX, strlen (REGISTER_PREFIX)))
@@ -711,8 +671,7 @@ strip_reg_name (name)
Prefixes such as % are optional. */
int
-decode_reg_name (asmspec)
- const char *asmspec;
+decode_reg_name (const char *asmspec)
{
if (asmspec != 0)
{
@@ -775,13 +734,9 @@ decode_reg_name (asmspec)
This is never called for PARM_DECL nodes. */
void
-make_decl_rtl (decl, asmspec)
- tree decl;
- const char *asmspec;
+make_decl_rtl (tree decl, const char *asmspec)
{
- int top_level = (DECL_CONTEXT (decl) == NULL_TREE);
const char *name = 0;
- const char *new_name = 0;
int reg_number;
rtx x;
@@ -817,12 +772,10 @@ make_decl_rtl (decl, asmspec)
/* Let the target reassign the RTL if it wants.
This is necessary, for example, when one machine specific
decl attribute overrides another. */
- (* targetm.encode_section_info) (decl, false);
+ (* targetm.encode_section_info) (decl, DECL_RTL (decl), false);
return;
}
- new_name = name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-
reg_number = decode_reg_name (asmspec);
if (reg_number == -2)
{
@@ -831,22 +784,24 @@ make_decl_rtl (decl, asmspec)
char *starred = alloca (strlen (asmspec) + 2);
starred[0] = '*';
strcpy (starred + 1, asmspec);
- new_name = starred;
+ change_decl_assembler_name (decl, get_identifier (starred));
}
+ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
{
/* First detect errors in declaring global registers. */
if (reg_number == -1)
- error_with_decl (decl, "register name not specified for `%s'");
+ error ("%Jregister name not specified for '%D'", decl, decl);
else if (reg_number < 0)
- error_with_decl (decl, "invalid register name for `%s'");
+ error ("%Jinvalid register name for '%D'", decl, decl);
else if (TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
- error_with_decl (decl,
- "data type of `%s' isn't suitable for a register");
+ error ("%Jdata type of '%D' isn't suitable for a register",
+ decl, decl);
else if (! HARD_REGNO_MODE_OK (reg_number, TYPE_MODE (TREE_TYPE (decl))))
- error_with_decl (decl,
- "register specified for `%s' isn't suitable for data type");
+ error ("%Jregister specified for '%D' isn't suitable for data type",
+ decl, decl);
/* Now handle properly declared static register variables. */
else
{
@@ -890,8 +845,7 @@ make_decl_rtl (decl, asmspec)
Also handle vars declared register invalidly. */
if (reg_number >= 0 || reg_number == -3)
- error_with_decl (decl,
- "register name given for non-register variable `%s'");
+ error ("%Jregister name given for non-register variable '%D'", decl, decl);
/* Specifying a section attribute on a variable forces it into a
non-.bss section, and thus it cannot be common. */
@@ -905,38 +859,11 @@ make_decl_rtl (decl, asmspec)
if (TREE_CODE (decl) == VAR_DECL && DECL_WEAK (decl))
DECL_COMMON (decl) = 0;
- /* Can't use just the variable's own name for a variable
- whose scope is less than the whole file, unless it's a member
- of a local class (which will already be unambiguous).
- Concatenate a distinguishing number. */
- if (!top_level && !TREE_PUBLIC (decl)
- && ! (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
- && asmspec == 0
- && name == IDENTIFIER_POINTER (DECL_NAME (decl)))
- {
- char *label;
-
- ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
- var_labelno++;
- new_name = label;
- }
-
- if (name != new_name)
- {
- SET_DECL_ASSEMBLER_NAME (decl, get_identifier (new_name));
- name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
- }
-
- /* If this variable is to be treated as volatile, show its
- tree node has side effects. */
- if ((flag_volatile_global && TREE_CODE (decl) == VAR_DECL
- && TREE_PUBLIC (decl))
- || ((flag_volatile_static && TREE_CODE (decl) == VAR_DECL
- && (TREE_PUBLIC (decl) || TREE_STATIC (decl)))))
- TREE_SIDE_EFFECTS (decl) = 1;
+ x = gen_rtx_SYMBOL_REF (Pmode, name);
+ SYMBOL_REF_WEAK (x) = DECL_WEAK (decl);
+ SYMBOL_REF_DECL (x) = decl;
- x = gen_rtx_MEM (DECL_MODE (decl), gen_rtx_SYMBOL_REF (Pmode, name));
- SYMBOL_REF_WEAK (XEXP (x, 0)) = DECL_WEAK (decl);
+ x = gen_rtx_MEM (DECL_MODE (decl), x);
if (TREE_CODE (decl) != FUNCTION_DECL)
set_mem_attributes (x, decl, 1);
SET_DECL_RTL (decl, x);
@@ -945,15 +872,14 @@ make_decl_rtl (decl, asmspec)
such as that it is a function name.
If the name is changed, the macro ASM_OUTPUT_LABELREF
will have to know how to strip this information. */
- (* targetm.encode_section_info) (decl, true);
+ (* targetm.encode_section_info) (decl, DECL_RTL (decl), true);
}
/* Make the rtl for variable VAR be volatile.
Use this only for static variables. */
void
-make_var_volatile (var)
- tree var;
+make_var_volatile (tree var)
{
if (GET_CODE (DECL_RTL (var)) != MEM)
abort ();
@@ -961,32 +887,11 @@ make_var_volatile (var)
MEM_VOLATILE_P (DECL_RTL (var)) = 1;
}
-/* Output alignment directive to align for constant expression EXP. */
-
-void
-assemble_constant_align (exp)
- tree exp;
-{
- int align;
-
- /* Align the location counter as required by EXP's data type. */
- align = TYPE_ALIGN (TREE_TYPE (exp));
-#ifdef CONSTANT_ALIGNMENT
- align = CONSTANT_ALIGNMENT (exp, align);
-#endif
-
- if (align > BITS_PER_UNIT)
- {
- ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
- }
-}
-
/* Output a string of literal assembler code
for an `asm' keyword used between functions. */
void
-assemble_asm (string)
- tree string;
+assemble_asm (tree string)
{
app_enable ();
@@ -1001,9 +906,7 @@ assemble_asm (string)
between 0 and MAX_INIT_PRIORITY. */
void
-default_stabs_asm_out_destructor (symbol, priority)
- rtx symbol;
- int priority ATTRIBUTE_UNUSED;
+default_stabs_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
/* Tell GNU LD that this is part of the static destructor set.
This will work for any system that uses stabs, most usefully
@@ -1014,9 +917,7 @@ default_stabs_asm_out_destructor (symbol, priority)
}
void
-default_named_section_asm_out_destructor (symbol, priority)
- rtx symbol;
- int priority;
+default_named_section_asm_out_destructor (rtx symbol, int priority)
{
const char *section = ".dtors";
char buf[16];
@@ -1039,7 +940,7 @@ default_named_section_asm_out_destructor (symbol, priority)
#ifdef DTORS_SECTION_ASM_OP
void
-dtors_section ()
+dtors_section (void)
{
if (in_section != in_dtors)
{
@@ -1050,9 +951,8 @@ dtors_section ()
}
void
-default_dtor_section_asm_out_destructor (symbol, priority)
- rtx symbol;
- int priority ATTRIBUTE_UNUSED;
+default_dtor_section_asm_out_destructor (rtx symbol,
+ int priority ATTRIBUTE_UNUSED)
{
dtors_section ();
assemble_align (POINTER_SIZE);
@@ -1063,9 +963,7 @@ default_dtor_section_asm_out_destructor (symbol, priority)
/* Likewise for global constructors. */
void
-default_stabs_asm_out_constructor (symbol, priority)
- rtx symbol;
- int priority ATTRIBUTE_UNUSED;
+default_stabs_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
{
/* Tell GNU LD that this is part of the static destructor set.
This will work for any system that uses stabs, most usefully
@@ -1076,9 +974,7 @@ default_stabs_asm_out_constructor (symbol, priority)
}
void
-default_named_section_asm_out_constructor (symbol, priority)
- rtx symbol;
- int priority;
+default_named_section_asm_out_constructor (rtx symbol, int priority)
{
const char *section = ".ctors";
char buf[16];
@@ -1101,7 +997,7 @@ default_named_section_asm_out_constructor (symbol, priority)
#ifdef CTORS_SECTION_ASM_OP
void
-ctors_section ()
+ctors_section (void)
{
if (in_section != in_ctors)
{
@@ -1112,9 +1008,8 @@ ctors_section ()
}
void
-default_ctor_section_asm_out_constructor (symbol, priority)
- rtx symbol;
- int priority ATTRIBUTE_UNUSED;
+default_ctor_section_asm_out_constructor (rtx symbol,
+ int priority ATTRIBUTE_UNUSED)
{
ctors_section ();
assemble_align (POINTER_SIZE);
@@ -1132,15 +1027,51 @@ default_ctor_section_asm_out_constructor (symbol, priority)
#define CONSTANT_POOL_BEFORE_FUNCTION 1
#endif
+/* DECL is an object (either VAR_DECL or FUNCTION_DECL) which is going
+ to be output to assembler.
+ Set first_global_object_name and weak_global_object_name as appropriate. */
+
+void
+notice_global_symbol (tree decl)
+{
+ const char **type = &first_global_object_name;
+
+ if (first_global_object_name
+ || !TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)
+ || !DECL_NAME (decl)
+ || (TREE_CODE (decl) != FUNCTION_DECL
+ && (TREE_CODE (decl) != VAR_DECL
+ || (DECL_COMMON (decl)
+ && (DECL_INITIAL (decl) == 0
+ || DECL_INITIAL (decl) == error_mark_node))))
+ || GET_CODE (DECL_RTL (decl)) != MEM)
+ return;
+
+ /* We win when global object is found, but it is usefull to know about weak
+ symbol as well so we can produce nicer unique names. */
+ if (DECL_WEAK (decl) || DECL_ONE_ONLY (decl))
+ type = &weak_global_object_name;
+
+ if (!*type)
+ {
+ const char *p;
+ char *name;
+ rtx decl_rtl = DECL_RTL (decl);
+
+ p = (* targetm.strip_name_encoding) (XSTR (XEXP (decl_rtl, 0), 0));
+ name = xstrdup (p);
+
+ *type = name;
+ }
+}
+
/* Output assembler code for the constant pool of a function and associated
with defining the name of the function. DECL describes the function.
NAME is the function's name. For the constant pool, we use the current
constant pool data. */
void
-assemble_start_function (decl, fnname)
- tree decl;
- const char *fnname;
+assemble_start_function (tree decl, const char *fnname)
{
int align;
@@ -1187,26 +1118,14 @@ assemble_start_function (decl, fnname)
if (TREE_PUBLIC (decl))
{
- if (! first_global_object_name)
- {
- const char *p;
- char *name;
-
- p = (* targetm.strip_name_encoding) (fnname);
- name = xstrdup (p);
-
- if (! DECL_WEAK (decl) && ! DECL_ONE_ONLY (decl))
- first_global_object_name = name;
- else
- weak_global_object_name = name;
- }
+ notice_global_symbol (decl);
globalize_decl (decl);
maybe_assemble_visibility (decl);
}
- /* Do any machine/system dependent processing of the function name */
+ /* Do any machine/system dependent processing of the function name. */
#ifdef ASM_DECLARE_FUNCTION_NAME
ASM_DECLARE_FUNCTION_NAME (asm_out_file, fnname, current_function_decl);
#else
@@ -1219,9 +1138,7 @@ assemble_start_function (decl, fnname)
function. DECL describes the function. NAME is the function's name. */
void
-assemble_end_function (decl, fnname)
- tree decl;
- const char *fnname;
+assemble_end_function (tree decl, const char *fnname)
{
#ifdef ASM_DECLARE_FUNCTION_SIZE
ASM_DECLARE_FUNCTION_SIZE (asm_out_file, fnname, decl);
@@ -1231,16 +1148,12 @@ assemble_end_function (decl, fnname)
output_constant_pool (fnname, decl);
function_section (decl); /* need to switch back */
}
-
- /* Output any constants which should appear after the function. */
- output_after_function_constants ();
}
/* Assemble code to leave SIZE bytes of zeros. */
void
-assemble_zeros (size)
- int size;
+assemble_zeros (unsigned HOST_WIDE_INT size)
{
/* Do no output if -fsyntax-only. */
if (flag_syntax_only)
@@ -1251,7 +1164,7 @@ assemble_zeros (size)
so we must output 0s explicitly in the text section. */
if (ASM_NO_SKIP_IN_TEXT && in_text_section ())
{
- int i;
+ unsigned HOST_WIDE_INT i;
for (i = 0; i < size; i++)
assemble_integer (const0_rtx, 1, BITS_PER_UNIT, 1);
}
@@ -1264,8 +1177,7 @@ assemble_zeros (size)
/* Assemble an alignment pseudo op for an ALIGN-bit boundary. */
void
-assemble_align (align)
- int align;
+assemble_align (int align)
{
if (align > BITS_PER_UNIT)
{
@@ -1276,9 +1188,7 @@ assemble_align (align)
/* Assemble a string constant with the specified C string as contents. */
void
-assemble_string (p, size)
- const char *p;
- int size;
+assemble_string (const char *p, int size)
{
int pos = 0;
int maximum = 2000;
@@ -1338,11 +1248,9 @@ assemble_string (p, size)
#endif
static bool
-asm_emit_uninitialised (decl, name, size, rounded)
- tree decl;
- const char *name;
- int size ATTRIBUTE_UNUSED;
- int rounded ATTRIBUTE_UNUSED;
+asm_emit_uninitialised (tree decl, const char *name,
+ unsigned HOST_WIDE_INT size ATTRIBUTE_UNUSED,
+ unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED)
{
enum
{
@@ -1425,17 +1333,17 @@ asm_emit_uninitialised (decl, name, size, rounded)
initial value (that will be done by the caller). */
void
-assemble_variable (decl, top_level, at_end, dont_output_data)
- tree decl;
- int top_level ATTRIBUTE_UNUSED;
- int at_end ATTRIBUTE_UNUSED;
- int dont_output_data;
+assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
+ int at_end ATTRIBUTE_UNUSED, int dont_output_data)
{
const char *name;
unsigned int align;
int reloc = 0;
rtx decl_rtl;
+ if (lang_hooks.decls.prepare_assemble_variable)
+ (*lang_hooks.decls.prepare_assemble_variable) (decl);
+
last_assemble_variable_decl = 0;
/* Normally no need to say anything here for external references,
@@ -1469,10 +1377,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
if (!dont_output_data && DECL_SIZE (decl) == 0)
{
- error_with_file_and_line (DECL_SOURCE_FILE (decl),
- DECL_SOURCE_LINE (decl),
- "storage size of `%s' isn't known",
- IDENTIFIER_POINTER (DECL_NAME (decl)));
+ error ("%Jstorage size of `%D' isn't known", decl, decl);
TREE_ASM_WRITTEN (decl) = 1;
return;
}
@@ -1500,25 +1405,13 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
if (! dont_output_data
&& ! host_integerp (DECL_SIZE_UNIT (decl), 1))
{
- error_with_decl (decl, "size of variable `%s' is too large");
+ error ("%Jsize of variable '%D' is too large", decl, decl);
return;
}
name = XSTR (XEXP (decl_rtl, 0), 0);
- if (TREE_PUBLIC (decl) && DECL_NAME (decl)
- && ! first_global_object_name
- && ! (DECL_COMMON (decl) && (DECL_INITIAL (decl) == 0
- || DECL_INITIAL (decl) == error_mark_node))
- && ! DECL_WEAK (decl)
- && ! DECL_ONE_ONLY (decl))
- {
- const char *p;
- char *xname;
-
- p = (* targetm.strip_name_encoding) (name);
- xname = xstrdup (p);
- first_global_object_name = xname;
- }
+ if (TREE_PUBLIC (decl) && DECL_NAME (decl))
+ notice_global_symbol (decl);
/* Compute the alignment of this data. */
@@ -1538,9 +1431,9 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
#endif
if (align > MAX_OFILE_ALIGNMENT)
{
- warning_with_decl (decl,
- "alignment of `%s' is greater than maximum object file alignment. Using %d",
- MAX_OFILE_ALIGNMENT/BITS_PER_UNIT);
+ warning ("%Jalignment of '%D' is greater than maximum object "
+ "file alignment. Using %d", decl, decl,
+ MAX_OFILE_ALIGNMENT/BITS_PER_UNIT);
align = MAX_OFILE_ALIGNMENT;
}
@@ -1568,7 +1461,10 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
if (DECL_INITIAL (decl) == error_mark_node)
reloc = contains_pointers_p (TREE_TYPE (decl)) ? 3 : 0;
else if (DECL_INITIAL (decl))
- reloc = output_addressed_constants (DECL_INITIAL (decl));
+ {
+ reloc = compute_reloc_for_constant (DECL_INITIAL (decl));
+ output_addressed_constants (DECL_INITIAL (decl));
+ }
resolve_unique_section (decl, reloc, flag_data_sections);
/* Handle uninitialized definitions. */
@@ -1606,8 +1502,8 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
#if !defined(ASM_OUTPUT_ALIGNED_COMMON) && !defined(ASM_OUTPUT_ALIGNED_DECL_COMMON) && !defined(ASM_OUTPUT_ALIGNED_BSS)
if ((unsigned HOST_WIDE_INT) DECL_ALIGN (decl) / BITS_PER_UNIT > rounded)
- warning_with_decl
- (decl, "requested alignment for %s is greater than implemented alignment of %d",rounded);
+ warning ("%Jrequested alignment for '%D' is greater than "
+ "implemented alignment of %d", decl, decl, rounded);
#endif
/* If the target cannot output uninitialized but not common global data
@@ -1663,8 +1559,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
/* Return 1 if type TYPE contains any pointers. */
static int
-contains_pointers_p (type)
- tree type;
+contains_pointers_p (tree type)
{
switch (TREE_CODE (type))
{
@@ -1697,13 +1592,35 @@ contains_pointers_p (type)
}
}
+#ifdef ASM_OUTPUT_EXTERNAL
+/* True if DECL is a function decl for which no out-of-line copy exists.
+ It is assumed that DECL's assembler name has been set. */
+
+static bool
+incorporeal_function_p (tree decl)
+{
+ if (TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl))
+ {
+ const char *name;
+
+ if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
+ && DECL_FUNCTION_CODE (decl) == BUILT_IN_ALLOCA)
+ return true;
+
+ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ if (strncmp (name, "__builtin_", strlen ("__builtin_")) == 0)
+ return true;
+ }
+ return false;
+}
+#endif
+
/* Output something to declare an external symbol to the assembler.
(Most assemblers don't need this, so we normally output nothing.)
Do nothing if DECL is not external. */
void
-assemble_external (decl)
- tree decl ATTRIBUTE_UNUSED;
+assemble_external (tree decl ATTRIBUTE_UNUSED)
{
/* Because most platforms do not define ASM_OUTPUT_EXTERNAL, the
main body of this code is only rarely exercised. To provide some
@@ -1718,7 +1635,8 @@ assemble_external (decl)
rtx rtl = DECL_RTL (decl);
if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
- && ! SYMBOL_REF_USED (XEXP (rtl, 0)))
+ && !SYMBOL_REF_USED (XEXP (rtl, 0))
+ && !incorporeal_function_p (decl))
{
/* Some systems do require some output. */
SYMBOL_REF_USED (XEXP (rtl, 0)) = 1;
@@ -1731,28 +1649,47 @@ assemble_external (decl)
/* Similar, for calling a library function FUN. */
void
-assemble_external_libcall (fun)
- rtx fun ATTRIBUTE_UNUSED;
+assemble_external_libcall (rtx fun)
{
-#ifdef ASM_OUTPUT_EXTERNAL_LIBCALL
/* Declare library function name external when first used, if nec. */
if (! SYMBOL_REF_USED (fun))
{
SYMBOL_REF_USED (fun) = 1;
- ASM_OUTPUT_EXTERNAL_LIBCALL (asm_out_file, fun);
+ (*targetm.asm_out.external_libcall) (fun);
}
-#endif
}
/* Assemble a label named NAME. */
void
-assemble_label (name)
- const char *name;
+assemble_label (const char *name)
{
ASM_OUTPUT_LABEL (asm_out_file, name);
}
+/* Set the symbol_referenced flag for ID and notify callgraph code. */
+void
+mark_referenced (tree id)
+{
+ if (!TREE_SYMBOL_REFERENCED (id))
+ {
+ struct cgraph_node *node;
+ struct cgraph_varpool_node *vnode;
+
+ if (!cgraph_global_info_ready)
+ {
+ node = cgraph_node_for_identifier (id);
+ if (node)
+ cgraph_mark_needed_node (node);
+ }
+
+ vnode = cgraph_varpool_node_for_identifier (id);
+ if (vnode)
+ cgraph_varpool_mark_needed_node (vnode);
+ }
+ TREE_SYMBOL_REFERENCED (id) = 1;
+}
+
/* Output to FILE a reference to the assembler name of a C-level name NAME.
If NAME starts with a *, the rest of NAME is output verbatim.
Otherwise NAME is transformed in an implementation-defined way
@@ -1760,9 +1697,7 @@ assemble_label (name)
Many macros in the tm file are defined to call this function. */
void
-assemble_name (file, name)
- FILE *file;
- const char *name;
+assemble_name (FILE *file, const char *name)
{
const char *real_name;
tree id;
@@ -1771,7 +1706,7 @@ assemble_name (file, name)
id = maybe_get_identifier (real_name);
if (id)
- TREE_SYMBOL_REFERENCED (id) = 1;
+ mark_referenced (id);
if (name[0] == '*')
fputs (&name[1], file);
@@ -1783,8 +1718,7 @@ assemble_name (file, name)
and return an RTX to refer to its address. */
rtx
-assemble_static_space (size)
- int size;
+assemble_static_space (unsigned HOST_WIDE_INT size)
{
char name[12];
const char *namestring;
@@ -1800,6 +1734,7 @@ assemble_static_space (size)
namestring = ggc_strdup (name);
x = gen_rtx_SYMBOL_REF (Pmode, namestring);
+ SYMBOL_REF_FLAGS (x) = SYMBOL_FLAG_LOCAL;
#ifdef ASM_OUTPUT_ALIGNED_DECL_LOCAL
ASM_OUTPUT_ALIGNED_DECL_LOCAL (asm_out_file, NULL_TREE, name, size,
@@ -1812,7 +1747,7 @@ assemble_static_space (size)
/* Round size up to multiple of BIGGEST_ALIGNMENT bits
so that each uninitialized object starts on such a boundary. */
/* Variable `rounded' might or might not be used in ASM_OUTPUT_LOCAL. */
- int rounded ATTRIBUTE_UNUSED
+ unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED
= ((size + (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1)
/ (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
* (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
@@ -1829,11 +1764,12 @@ assemble_static_space (size)
#ifdef TRAMPOLINE_TEMPLATE
rtx
-assemble_trampoline_template ()
+assemble_trampoline_template (void)
{
char label[256];
const char *name;
int align;
+ rtx symbol;
/* By default, put trampoline templates in read-only data section. */
@@ -1850,13 +1786,16 @@ assemble_trampoline_template ()
ASM_OUTPUT_ALIGN (asm_out_file, align);
}
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LTRAMP", 0);
+ (*targetm.asm_out.internal_label) (asm_out_file, "LTRAMP", 0);
TRAMPOLINE_TEMPLATE (asm_out_file);
/* Record the rtl to refer to it. */
ASM_GENERATE_INTERNAL_LABEL (label, "LTRAMP", 0);
name = ggc_strdup (label);
- return gen_rtx_SYMBOL_REF (Pmode, name);
+ symbol = gen_rtx_SYMBOL_REF (Pmode, name);
+ SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL;
+
+ return symbol;
}
#endif
@@ -1864,8 +1803,7 @@ assemble_trampoline_template ()
that may be assumed after adding the two together. */
static inline unsigned
-min_align (a, b)
- unsigned int a, b;
+min_align (unsigned int a, unsigned int b)
{
return (a | b) & -(a | b);
}
@@ -1879,9 +1817,7 @@ min_align (a, b)
be followed immediately by the object's initial value. */
const char *
-integer_asm_op (size, aligned_p)
- int size;
- int aligned_p;
+integer_asm_op (int size, int aligned_p)
{
struct asm_int_op *ops;
@@ -1911,9 +1847,7 @@ integer_asm_op (size, aligned_p)
start of the line, followed immediately by the value of X. */
void
-assemble_integer_with_op (op, x)
- const char *op;
- rtx x;
+assemble_integer_with_op (const char *op, rtx x)
{
fputs (op, asm_out_file);
output_addr_const (asm_out_file, x);
@@ -1923,10 +1857,9 @@ assemble_integer_with_op (op, x)
/* The default implementation of the asm_out.integer target hook. */
bool
-default_assemble_integer (x, size, aligned_p)
- rtx x ATTRIBUTE_UNUSED;
- unsigned int size ATTRIBUTE_UNUSED;
- int aligned_p ATTRIBUTE_UNUSED;
+default_assemble_integer (rtx x ATTRIBUTE_UNUSED,
+ unsigned int size ATTRIBUTE_UNUSED,
+ int aligned_p ATTRIBUTE_UNUSED)
{
const char *op = integer_asm_op (size, aligned_p);
return op && (assemble_integer_with_op (op, x), true);
@@ -1938,11 +1871,7 @@ default_assemble_integer (x, size, aligned_p)
the constant. */
bool
-assemble_integer (x, size, align, force)
- rtx x;
- unsigned int size;
- unsigned int align;
- int force;
+assemble_integer (rtx x, unsigned int size, unsigned int align, int force)
{
int aligned_p;
@@ -1987,83 +1916,42 @@ assemble_integer (x, size, align, force)
}
void
-assemble_real (d, mode, align)
- REAL_VALUE_TYPE d;
- enum machine_mode mode;
- unsigned int align;
+assemble_real (REAL_VALUE_TYPE d, enum machine_mode mode, unsigned int align)
{
long data[4];
- long l;
- unsigned int nalign = min_align (align, 32);
+ int i;
+ int bitsize, nelts, nunits, units_per;
- switch (BITS_PER_UNIT)
- {
- case 8:
- switch (mode)
- {
- case SFmode:
- REAL_VALUE_TO_TARGET_SINGLE (d, l);
- assemble_integer (GEN_INT (l), 4, align, 1);
- break;
- case DFmode:
- REAL_VALUE_TO_TARGET_DOUBLE (d, data);
- assemble_integer (GEN_INT (data[0]), 4, align, 1);
- assemble_integer (GEN_INT (data[1]), 4, nalign, 1);
- break;
- case XFmode:
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (d, data);
- assemble_integer (GEN_INT (data[0]), 4, align, 1);
- assemble_integer (GEN_INT (data[1]), 4, nalign, 1);
- assemble_integer (GEN_INT (data[2]), 4, nalign, 1);
- break;
- case TFmode:
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (d, data);
- assemble_integer (GEN_INT (data[0]), 4, align, 1);
- assemble_integer (GEN_INT (data[1]), 4, nalign, 1);
- assemble_integer (GEN_INT (data[2]), 4, nalign, 1);
- assemble_integer (GEN_INT (data[3]), 4, nalign, 1);
- break;
- default:
- abort ();
- }
- break;
+ /* This is hairy. We have a quantity of known size. real_to_target
+ will put it into an array of *host* longs, 32 bits per element
+ (even if long is more than 32 bits). We need to determine the
+ number of array elements that are occupied (nelts) and the number
+ of *target* min-addressable units that will be occupied in the
+ object file (nunits). We cannot assume that 32 divides the
+ mode's bitsize (size * BITS_PER_UNIT) evenly.
- case 16:
- switch (mode)
- {
- case HFmode:
- REAL_VALUE_TO_TARGET_SINGLE (d, l);
- assemble_integer (GEN_INT (l), 2, align, 1);
- break;
- case TQFmode:
- REAL_VALUE_TO_TARGET_DOUBLE (d, data);
- assemble_integer (GEN_INT (data[0]), 2, align, 1);
- assemble_integer (GEN_INT (data[1]), 1, nalign, 1);
- break;
- default:
- abort ();
- }
- break;
+ size * BITS_PER_UNIT is used here to make sure that padding bits
+ (which might appear at either end of the value; real_to_target
+ will include the padding bits in its output array) are included. */
- case 32:
- switch (mode)
- {
- case QFmode:
- REAL_VALUE_TO_TARGET_SINGLE (d, l);
- assemble_integer (GEN_INT (l), 1, align, 1);
- break;
- case HFmode:
- REAL_VALUE_TO_TARGET_DOUBLE (d, data);
- assemble_integer (GEN_INT (data[0]), 1, align, 1);
- assemble_integer (GEN_INT (data[1]), 1, nalign, 1);
- break;
- default:
- abort ();
- }
- break;
+ nunits = GET_MODE_SIZE (mode);
+ bitsize = nunits * BITS_PER_UNIT;
+ nelts = CEIL (bitsize, 32);
+ units_per = 32 / BITS_PER_UNIT;
- default:
- abort ();
+ real_to_target (data, &d, mode);
+
+ /* Put out the first word with the specified alignment. */
+ assemble_integer (GEN_INT (data[0]), MIN (nunits, units_per), align, 1);
+ nunits -= units_per;
+
+ /* Subsequent words need only 32-bit alignment. */
+ align = min_align (align, 32);
+
+ for (i = 1; i < nelts; i++)
+ {
+ assemble_integer (GEN_INT (data[i]), MIN (nunits, units_per), align, 1);
+ nunits -= units_per;
}
}
@@ -2079,9 +1967,7 @@ struct addr_const GTY(())
};
static void
-decode_addr_const (exp, value)
- tree exp;
- struct addr_const *value;
+decode_addr_const (tree exp, struct addr_const *value)
{
tree target = TREE_OPERAND (exp, 0);
int offset = 0;
@@ -2116,8 +2002,7 @@ decode_addr_const (exp, value)
case LABEL_DECL:
x = gen_rtx_MEM (FUNCTION_MODE,
- gen_rtx_LABEL_REF (VOIDmode,
- label_rtx (TREE_OPERAND (exp, 0))));
+ gen_rtx_LABEL_REF (VOIDmode, force_label_rtx (target)));
break;
case REAL_CST:
@@ -2125,8 +2010,6 @@ decode_addr_const (exp, value)
case COMPLEX_CST:
case CONSTRUCTOR:
case INTEGER_CST:
- /* This constant should have been output already, but we can't simply
- use TREE_CST_RTL since INTEGER_CST doesn't have one. */
x = output_constant_def (target, 1);
break;
@@ -2149,7 +2032,7 @@ struct rtx_const GTY(())
ENUM_BITFIELD(kind) kind : 16;
ENUM_BITFIELD(machine_mode) mode : 16;
union rtx_const_un {
- REAL_VALUE_TYPE du;
+ REAL_VALUE_TYPE GTY ((tag ("4"))) du;
struct rtx_const_u_addr {
rtx base;
const char *symbol;
@@ -2174,16 +2057,10 @@ struct rtx_const GTY(())
/* Uniquize all constants that appear in memory.
Each constant in memory thus far output is recorded
- in `const_hash_table'. */
+ in `const_desc_table'. */
struct constant_descriptor_tree GTY(())
{
- /* More constant_descriptors with the same hash code. */
- struct constant_descriptor_tree *next;
-
- /* The label of the constant. */
- const char *label;
-
/* A MEM for the constant. */
rtx rtl;
@@ -2191,63 +2068,25 @@ struct constant_descriptor_tree GTY(())
tree value;
};
-#define MAX_HASH_TABLE 1009
-static GTY(()) struct constant_descriptor_tree *
- const_hash_table[MAX_HASH_TABLE];
-
-/* We maintain a hash table of STRING_CST values. Unless we are asked to force
- out a string constant, we defer output of the constants until we know
- they are actually used. This will be if something takes its address or if
- there is a usage of the string in the RTL of a function. */
-
-#define STRHASH(x) htab_hash_pointer (x)
-
-struct deferred_string GTY(())
-{
- const char *label;
- tree exp;
- int labelno;
-};
-
-static GTY ((param_is (struct deferred_string))) htab_t const_str_htab;
-
-/* Returns a hash code for X (which is a really a
- struct deferred_string *). */
-
-static hashval_t
-const_str_htab_hash (x)
- const void *x;
-{
- return STRHASH (((const struct deferred_string *) x)->label);
-}
+static GTY((param_is (struct constant_descriptor_tree)))
+ htab_t const_desc_htab;
-/* Returns nonzero if the value represented by X (which is really a
- struct deferred_string *) is the same as that given by Y
- (which is really a char *). */
-
-static int
-const_str_htab_eq (x, y)
- const void *x;
- const void *y;
-{
- return (((const struct deferred_string *) x)->label == (const char *) y);
-}
+static struct constant_descriptor_tree * build_constant_desc (tree);
+static void maybe_output_constant_def_contents (struct constant_descriptor_tree *, int);
/* Compute a hash code for a constant expression. */
-static unsigned int
-const_hash (exp)
- tree exp;
+static hashval_t
+const_desc_hash (const void *ptr)
{
- return const_hash_1 (exp) % MAX_HASH_TABLE;
+ return const_hash_1 (((struct constant_descriptor_tree *)ptr)->value);
}
-static unsigned int
-const_hash_1 (exp)
- tree exp;
+static hashval_t
+const_hash_1 (const tree exp)
{
const char *p;
- unsigned int hi;
+ hashval_t hi;
int len, i;
enum tree_code code = TREE_CODE (exp);
@@ -2265,8 +2104,16 @@ const_hash_1 (exp)
return real_hash (TREE_REAL_CST_PTR (exp));
case STRING_CST:
- p = TREE_STRING_POINTER (exp);
- len = TREE_STRING_LENGTH (exp);
+ if (flag_writable_strings)
+ {
+ p = (char *) &exp;
+ len = sizeof exp;
+ }
+ else
+ {
+ p = TREE_STRING_POINTER (exp);
+ len = TREE_STRING_LENGTH (exp);
+ }
break;
case COMPLEX_CST:
@@ -2279,7 +2126,7 @@ const_hash_1 (exp)
char *tmp;
len = int_size_in_bytes (TREE_TYPE (exp));
- tmp = (char *) alloca (len);
+ tmp = alloca (len);
get_set_constructor_bytes (exp, (unsigned char *) tmp, len);
p = tmp;
break;
@@ -2334,7 +2181,7 @@ const_hash_1 (exp)
return code;
}
- /* Compute hashing function */
+ /* Compute hashing function. */
hi = len;
for (i = 0; i < len; i++)
hi = ((hi * 613) + (unsigned) (p[i]));
@@ -2342,13 +2189,19 @@ const_hash_1 (exp)
return hi;
}
+/* Wrapper of compare_constant, for the htab interface. */
+static int
+const_desc_eq (const void *p1, const void *p2)
+{
+ return compare_constant (((struct constant_descriptor_tree *)p1)->value,
+ ((struct constant_descriptor_tree *)p2)->value);
+}
+
/* Compare t1 and t2, and return 1 only if they are known to result in
the same bit pattern on output. */
static int
-compare_constant (t1, t2)
- tree t1;
- tree t2;
+compare_constant (const tree t1, const tree t2)
{
enum tree_code typecode;
@@ -2377,7 +2230,7 @@ compare_constant (t1, t2)
case STRING_CST:
if (flag_writable_strings)
- return 0;
+ return t1 == t2;
if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
return 0;
@@ -2403,8 +2256,8 @@ compare_constant (t1, t2)
if (int_size_in_bytes (TREE_TYPE (t1)) != len)
return 0;
- tmp1 = (unsigned char *) alloca (len);
- tmp2 = (unsigned char *) alloca (len);
+ tmp1 = alloca (len);
+ tmp2 = alloca (len);
if (get_set_constructor_bytes (t1, tmp1, len) != NULL_TREE)
return 0;
@@ -2496,81 +2349,11 @@ compare_constant (t1, t2)
abort ();
}
-/* Record a list of constant expressions that were passed to
- output_constant_def but that could not be output right away. */
-
-struct deferred_constant
-{
- struct deferred_constant *next;
- tree exp;
- int reloc;
- int labelno;
-};
-
-static struct deferred_constant *deferred_constants;
-
-/* Another list of constants which should be output after the
- function. */
-static struct deferred_constant *after_function_constants;
-
-/* Nonzero means defer output of addressed subconstants
- (i.e., those for which output_constant_def is called.) */
-static int defer_addressed_constants_flag;
-
-/* Start deferring output of subconstants. */
-
-void
-defer_addressed_constants ()
-{
- defer_addressed_constants_flag++;
-}
-
-/* Stop deferring output of subconstants,
- and output now all those that have been deferred. */
-
-void
-output_deferred_addressed_constants ()
-{
- struct deferred_constant *p, *next;
-
- defer_addressed_constants_flag--;
-
- if (defer_addressed_constants_flag > 0)
- return;
-
- for (p = deferred_constants; p; p = next)
- {
- output_constant_def_contents (p->exp, p->reloc, p->labelno);
- next = p->next;
- free (p);
- }
-
- deferred_constants = 0;
-}
-
-/* Output any constants which should appear after a function. */
-
-static void
-output_after_function_constants ()
-{
- struct deferred_constant *p, *next;
-
- for (p = after_function_constants; p; p = next)
- {
- output_constant_def_contents (p->exp, p->reloc, p->labelno);
- next = p->next;
- free (p);
- }
-
- after_function_constants = 0;
-}
-
/* Make a copy of the whole tree structure for a constant. This
handles the same types of nodes that compare_constant handles. */
static tree
-copy_constant (exp)
- tree exp;
+copy_constant (tree exp)
{
switch (TREE_CODE (exp))
{
@@ -2602,6 +2385,7 @@ copy_constant (exp)
case NOP_EXPR:
case CONVERT_EXPR:
case NON_LVALUE_EXPR:
+ case VIEW_CONVERT_EXPR:
return build1 (TREE_CODE (exp), TREE_TYPE (exp),
copy_constant (TREE_OPERAND (exp, 0)));
@@ -2633,207 +2417,149 @@ copy_constant (exp)
}
}
+/* Subroutine of output_constant_def:
+ No constant equal to EXP is known to have been output.
+ Make a constant descriptor to enter EXP in the hash table.
+ Assign the label number and construct RTL to refer to the
+ constant's location in memory.
+ Caller is responsible for updating the hash table. */
+
+static struct constant_descriptor_tree *
+build_constant_desc (tree exp)
+{
+ rtx symbol;
+ rtx rtl;
+ char label[256];
+ int labelno;
+ struct constant_descriptor_tree *desc;
+
+ desc = ggc_alloc (sizeof (*desc));
+ if (flag_writable_strings && TREE_CODE (exp) == STRING_CST)
+ desc->value = exp;
+ else
+ desc->value = copy_constant (exp);
+
+ /* Create a string containing the label name, in LABEL. */
+ labelno = const_labelno++;
+ ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno);
+
+ /* We have a symbol name; construct the SYMBOL_REF and the MEM. */
+ symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label));
+ SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL;
+ SYMBOL_REF_DECL (symbol) = desc->value;
+ TREE_CONSTANT_POOL_ADDRESS_P (symbol) = 1;
+
+ rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), symbol);
+ set_mem_attributes (rtl, exp, 1);
+ set_mem_alias_set (rtl, 0);
+ set_mem_alias_set (rtl, const_alias_set);
+
+ /* Set flags or add text to the name to record information, such as
+ that it is a local symbol. If the name is changed, the macro
+ ASM_OUTPUT_LABELREF will have to know how to strip this
+ information. This call might invalidate our local variable
+ SYMBOL; we can't use it afterward. */
+
+ (*targetm.encode_section_info) (exp, rtl, true);
+
+ desc->rtl = rtl;
+
+ return desc;
+}
+
/* Return an rtx representing a reference to constant data in memory
for the constant expression EXP.
If assembler code for such a constant has already been output,
return an rtx to refer to it.
- Otherwise, output such a constant in memory (or defer it for later)
+ Otherwise, output such a constant in memory
and generate an rtx for it.
- If DEFER is nonzero, the output of string constants can be deferred
- and output only if referenced in the function after all optimizations.
+ If DEFER is nonzero, this constant can be deferred and output only
+ if referenced in the function after all optimizations.
- The TREE_CST_RTL of EXP is set up to point to that rtx.
- The const_hash_table records which constants already have label strings. */
+ `const_desc_table' records which constants already have label strings. */
rtx
-output_constant_def (exp, defer)
- tree exp;
- int defer;
+output_constant_def (tree exp, int defer)
{
- int hash;
struct constant_descriptor_tree *desc;
- struct deferred_string **defstr;
- char label[256];
- int reloc;
- int found = 1;
- int after_function = 0;
- int labelno = -1;
- rtx rtl;
-
-
- /* We can't just use the saved RTL if this is a deferred string constant
- and we are not to defer anymore. */
- if (TREE_CODE (exp) != INTEGER_CST && TREE_CST_RTL (exp)
- && (defer || !STRING_POOL_ADDRESS_P (XEXP (TREE_CST_RTL (exp), 0))))
- return TREE_CST_RTL (exp);
-
- /* Make sure any other constants whose addresses appear in EXP
- are assigned label numbers. */
-
- reloc = output_addressed_constants (exp);
+ struct constant_descriptor_tree key;
+ void **loc;
- /* Compute hash code of EXP. Search the descriptors for that hash code
- to see if any of them describes EXP. If yes, the descriptor records
- the label number already assigned. */
-
- hash = const_hash (exp);
-
- for (desc = const_hash_table[hash]; desc; desc = desc->next)
- if (compare_constant (exp, desc->value))
- break;
+ /* Look up EXP in the table of constant descriptors. If we didn't find
+ it, create a new one. */
+ key.value = exp;
+ loc = htab_find_slot (const_desc_htab, &key, INSERT);
+ desc = *loc;
if (desc == 0)
{
- /* No constant equal to EXP is known to have been output.
- Make a constant descriptor to enter EXP in the hash table.
- Assign the label number and record it in the descriptor for
- future calls to this function to find. */
-
- /* Create a string containing the label name, in LABEL. */
- labelno = const_labelno++;
- ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno);
-
- desc = ggc_alloc (sizeof (*desc));
- desc->next = const_hash_table[hash];
- desc->label = ggc_strdup (label);
- desc->value = copy_constant (exp);
- const_hash_table[hash] = desc;
-
- /* We have a symbol name; construct the SYMBOL_REF and the MEM. */
- rtl = desc->rtl
- = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
- gen_rtx_SYMBOL_REF (Pmode, desc->label));
-
- set_mem_attributes (rtl, exp, 1);
- set_mem_alias_set (rtl, 0);
- set_mem_alias_set (rtl, const_alias_set);
-
- found = 0;
+ desc = build_constant_desc (exp);
+ *loc = desc;
}
- else
- rtl = desc->rtl;
- if (TREE_CODE (exp) != INTEGER_CST)
- TREE_CST_RTL (exp) = rtl;
-
- /* Optionally set flags or add text to the name to record information
- such as that it is a function name. If the name is changed, the macro
- ASM_OUTPUT_LABELREF will have to know how to strip this information. */
- /* A previously-processed constant would already have section info
- encoded in it. */
- if (! found)
- {
- /* Take care not to invoke targetm.encode_section_info for
- constants which don't have a TREE_CST_RTL. */
- if (TREE_CODE (exp) != INTEGER_CST)
- (*targetm.encode_section_info) (exp, true);
+ maybe_output_constant_def_contents (desc, defer);
+ return desc->rtl;
+}
- desc->rtl = rtl;
- desc->label = XSTR (XEXP (desc->rtl, 0), 0);
- }
+/* Subroutine of output_constant_def: Decide whether or not we need to
+ output the constant DESC now, and if so, do it. */
+static void
+maybe_output_constant_def_contents (struct constant_descriptor_tree *desc,
+ int defer)
+{
+ rtx symbol = XEXP (desc->rtl, 0);
+ tree exp = desc->value;
-#ifdef CONSTANT_AFTER_FUNCTION_P
- if (current_function_decl != 0
- && CONSTANT_AFTER_FUNCTION_P (exp))
- after_function = 1;
-#endif
+ if (flag_syntax_only)
+ return;
- if (found
- && STRING_POOL_ADDRESS_P (XEXP (rtl, 0))
- && (!defer || defer_addressed_constants_flag || after_function))
- {
- defstr = (struct deferred_string **)
- htab_find_slot_with_hash (const_str_htab, desc->label,
- STRHASH (desc->label), NO_INSERT);
- if (defstr)
- {
- /* If the string is currently deferred but we need to output it now,
- remove it from deferred string hash table. */
- found = 0;
- labelno = (*defstr)->labelno;
- STRING_POOL_ADDRESS_P (XEXP (rtl, 0)) = 0;
- htab_clear_slot (const_str_htab, (void **) defstr);
- }
- }
+ if (TREE_ASM_WRITTEN (exp))
+ /* Already output; don't do it again. */
+ return;
- /* If this is the first time we've seen this particular constant,
- output it (or defer its output for later). */
- if (! found)
+ /* The only constants that cannot safely be deferred, assuming the
+ context allows it, are strings under flag_writable_strings. */
+ if (defer && (TREE_CODE (exp) != STRING_CST || !flag_writable_strings))
{
- if (defer_addressed_constants_flag || after_function)
- {
- struct deferred_constant *p
- = (struct deferred_constant *)
- xmalloc (sizeof (struct deferred_constant));
-
- p->exp = desc->value;
- p->reloc = reloc;
- p->labelno = labelno;
- if (after_function)
- {
- p->next = after_function_constants;
- after_function_constants = p;
- }
- else
- {
- p->next = deferred_constants;
- deferred_constants = p;
- }
- }
- else
- {
- /* Do no output if -fsyntax-only. */
- if (! flag_syntax_only)
- {
- if (TREE_CODE (exp) != STRING_CST
- || !defer
- || flag_writable_strings
- || (defstr = (struct deferred_string **)
- htab_find_slot_with_hash (const_str_htab,
- desc->label,
- STRHASH (desc->label),
- INSERT)) == NULL)
- output_constant_def_contents (exp, reloc, labelno);
- else
- {
- struct deferred_string *p;
-
- p = (struct deferred_string *)
- ggc_alloc (sizeof (struct deferred_string));
-
- p->exp = desc->value;
- p->label = desc->label;
- p->labelno = labelno;
- *defstr = p;
- STRING_POOL_ADDRESS_P (XEXP (rtl, 0)) = 1;
- }
- }
- }
+ /* Increment n_deferred_constants if it exists. It needs to be at
+ least as large as the number of constants actually referred to
+ by the function. If it's too small we'll stop looking too early
+ and fail to emit constants; if it's too large we'll only look
+ through the entire function when we could have stopped earlier. */
+ if (cfun)
+ n_deferred_constants++;
+ return;
}
- return rtl;
+ output_constant_def_contents (symbol);
}
-/* Now output assembler code to define the label for EXP,
- and follow it with the data of EXP. */
+/* We must output the constant data referred to by SYMBOL; do so. */
static void
-output_constant_def_contents (exp, reloc, labelno)
- tree exp;
- int reloc;
- int labelno;
+output_constant_def_contents (rtx symbol)
{
- int align;
+ tree exp = SYMBOL_REF_DECL (symbol);
+ const char *label = XSTR (symbol, 0);
HOST_WIDE_INT size;
+ /* Make sure any other constants whose addresses appear in EXP
+ are assigned label numbers. */
+ int reloc = compute_reloc_for_constant (exp);
+
/* Align the location counter as required by EXP's data type. */
- align = TYPE_ALIGN (TREE_TYPE (exp));
+ int align = TYPE_ALIGN (TREE_TYPE (exp));
#ifdef CONSTANT_ALIGNMENT
align = CONSTANT_ALIGNMENT (exp, align);
#endif
+ output_addressed_constants (exp);
+
+ /* We are no longer deferring this constant. */
+ TREE_ASM_WRITTEN (exp) = 1;
+
if (IN_NAMED_SECTION (exp))
named_section (exp, NULL, reloc);
else
@@ -2850,19 +2576,39 @@ output_constant_def_contents (exp, reloc, labelno)
/* Do any machine/system dependent processing of the constant. */
#ifdef ASM_DECLARE_CONSTANT_NAME
- {
- char label[256];
- ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno);
- ASM_DECLARE_CONSTANT_NAME (asm_out_file, label, exp, size);
- }
+ ASM_DECLARE_CONSTANT_NAME (asm_out_file, label, exp, size);
#else
/* Standard thing is just output label for the constant. */
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", labelno);
+ ASM_OUTPUT_LABEL (asm_out_file, label);
#endif /* ASM_DECLARE_CONSTANT_NAME */
/* Output the value of EXP. */
output_constant (exp, size, align);
}
+
+/* A constant which was deferred in its original location has been
+ inserted by the RTL inliner into a different function. The
+ current function's deferred constant count must be incremented. */
+void
+notice_rtl_inlining_of_deferred_constant (void)
+{
+ n_deferred_constants++;
+}
+
+/* Look up EXP in the table of constant descriptors. Return the rtl
+ if it has been emitted, else null. */
+
+rtx
+lookup_constant_def (tree exp)
+{
+ struct constant_descriptor_tree *desc;
+ struct constant_descriptor_tree key;
+
+ key.value = exp;
+ desc = htab_find (const_desc_htab, &key);
+
+ return (desc ? desc->rtl : NULL_RTX);
+}
/* Used in the hash tables to avoid outputting the same constant
twice. Unlike 'struct constant_descriptor_tree', RTX constants
@@ -2907,23 +2653,21 @@ struct pool_constant GTY(())
/* Initialize constant pool hashing for a new function. */
void
-init_varasm_status (f)
- struct function *f;
+init_varasm_status (struct function *f)
{
struct varasm_status *p;
- p = (struct varasm_status *) ggc_alloc (sizeof (struct varasm_status));
+ p = ggc_alloc (sizeof (struct varasm_status));
f->varasm = p;
p->x_const_rtx_hash_table
- = ((struct constant_descriptor_rtx **)
- ggc_alloc_cleared (MAX_RTX_HASH_TABLE
- * sizeof (struct constant_descriptor_rtx *)));
+ = ggc_alloc_cleared (MAX_RTX_HASH_TABLE
+ * sizeof (struct constant_descriptor_rtx *));
p->x_const_rtx_sym_hash_table
- = ((struct pool_constant **)
- ggc_alloc_cleared (MAX_RTX_HASH_TABLE
- * sizeof (struct pool_constant *)));
+ = ggc_alloc_cleared (MAX_RTX_HASH_TABLE
+ * sizeof (struct pool_constant *));
p->x_first_pool = p->x_last_pool = 0;
p->x_pool_offset = 0;
+ p->deferred_constants = 0;
}
@@ -2932,10 +2676,7 @@ init_varasm_status (f)
They are stored into VALUE. */
static void
-decode_rtx_const (mode, x, value)
- enum machine_mode mode;
- rtx x;
- struct rtx_const *value;
+decode_rtx_const (enum machine_mode mode, rtx x, struct rtx_const *value)
{
/* Clear the whole structure, including any gaps. */
memset (value, 0, sizeof (struct rtx_const));
@@ -2965,7 +2706,7 @@ decode_rtx_const (mode, x, value)
break;
case rvc_normal:
value->un.du.exp = r->exp;
- /* FALLTHRU */
+ /* Fall through. */
case rvc_nan:
memcpy (value->un.du.sig, r->sig, sizeof (r->sig));
break;
@@ -3025,7 +2766,7 @@ decode_rtx_const (mode, x, value)
break;
case rvc_normal:
d->exp = r->exp;
- /* FALLTHRU */
+ /* Fall through. */
case rvc_nan:
memcpy (d->sig, r->sig, sizeof (r->sig));
break;
@@ -3113,8 +2854,7 @@ decode_rtx_const (mode, x, value)
include the same symbol. */
rtx
-simplify_subtraction (x)
- rtx x;
+simplify_subtraction (rtx x)
{
struct rtx_const val0, val1;
@@ -3133,9 +2873,7 @@ simplify_subtraction (x)
/* Compute a hash code for a constant RTL expression. */
static unsigned int
-const_hash_rtx (mode, x)
- enum machine_mode mode;
- rtx x;
+const_hash_rtx (enum machine_mode mode, rtx x)
{
union {
struct rtx_const value;
@@ -3147,7 +2885,7 @@ const_hash_rtx (mode, x)
decode_rtx_const (mode, x, &u.value);
- /* Compute hashing function */
+ /* Compute hashing function. */
hi = 0;
for (i = 0; i < ARRAY_SIZE (u.data); i++)
hi = hi * 613 + u.data[i];
@@ -3159,10 +2897,8 @@ const_hash_rtx (mode, x)
Return 1 if DESC describes a constant with the same value as X. */
static int
-compare_constant_rtx (mode, x, desc)
- enum machine_mode mode;
- rtx x;
- struct constant_descriptor_rtx *desc;
+compare_constant_rtx (enum machine_mode mode, rtx x,
+ struct constant_descriptor_rtx *desc)
{
struct rtx_const value;
@@ -3176,48 +2912,26 @@ compare_constant_rtx (mode, x, desc)
It is up to the caller to enter the descriptor in the hash table. */
static struct constant_descriptor_rtx *
-record_constant_rtx (mode, x)
- enum machine_mode mode;
- rtx x;
+record_constant_rtx (enum machine_mode mode, rtx x)
{
struct constant_descriptor_rtx *ptr;
- ptr = (struct constant_descriptor_rtx *) ggc_alloc (sizeof (*ptr));
+ ptr = ggc_alloc (sizeof (*ptr));
decode_rtx_const (mode, x, &ptr->value);
return ptr;
}
-/* Given a constant rtx X, return a MEM for the location in memory at which
- this constant has been placed. Return 0 if it not has been placed yet. */
-
-rtx
-mem_for_const_double (x)
- rtx x;
-{
- enum machine_mode mode = GET_MODE (x);
- struct constant_descriptor_rtx *desc;
-
- for (desc = const_rtx_hash_table[const_hash_rtx (mode, x)]; desc;
- desc = desc->next)
- if (compare_constant_rtx (mode, x, desc))
- return desc->rtl;
-
- return 0;
-}
-
/* Given a constant rtx X, make (or find) a memory constant for its value
and return a MEM rtx to refer to it in memory. */
rtx
-force_const_mem (mode, x)
- enum machine_mode mode;
- rtx x;
+force_const_mem (enum machine_mode mode, rtx x)
{
int hash;
struct constant_descriptor_rtx *desc;
char label[256];
- rtx def;
+ rtx def, symbol;
struct pool_constant *pool;
unsigned int align;
@@ -3230,7 +2944,7 @@ force_const_mem (mode, x)
hash = const_hash_rtx (mode, x);
for (desc = const_rtx_hash_table[hash]; desc; desc = desc->next)
if (compare_constant_rtx (mode, x, desc))
- return desc->rtl;
+ return copy_rtx (desc->rtl);
/* No constant equal to X is known to have been output.
Make a constant descriptor to enter X in the hash table
@@ -3242,8 +2956,11 @@ force_const_mem (mode, x)
/* Align the location counter as required by EXP's data type. */
align = GET_MODE_ALIGNMENT (mode == VOIDmode ? word_mode : mode);
#ifdef CONSTANT_ALIGNMENT
- align = CONSTANT_ALIGNMENT (make_tree ((*lang_hooks.types.type_for_mode)
- (mode, 0), x), align);
+ {
+ tree type = (*lang_hooks.types.type_for_mode) (mode, 0);
+ if (type != NULL_TREE)
+ align = CONSTANT_ALIGNMENT (make_tree (type, x), align);
+ }
#endif
pool_offset += (align / BITS_PER_UNIT) - 1;
@@ -3253,7 +2970,7 @@ force_const_mem (mode, x)
LABEL_PRESERVE_P (XEXP (x, 0)) = 1;
/* Allocate a pool constant descriptor, fill it in, and chain it in. */
- pool = (struct pool_constant *) ggc_alloc (sizeof (struct pool_constant));
+ pool = ggc_alloc (sizeof (struct pool_constant));
pool->desc = desc;
pool->constant = x;
pool->mode = mode;
@@ -3278,31 +2995,31 @@ force_const_mem (mode, x)
/* Construct the SYMBOL_REF and the MEM. */
- pool->desc->rtl = def
- = gen_rtx_MEM (mode, gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label)));
- set_mem_alias_set (def, const_alias_set);
+ symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label));
+ SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL;
+
+ pool->desc->rtl = def = gen_rtx_MEM (mode, symbol);
set_mem_attributes (def, (*lang_hooks.types.type_for_mode) (mode, 0), 1);
RTX_UNCHANGING_P (def) = 1;
/* Add label to symbol hash table. */
- hash = SYMHASH (XSTR (XEXP (def, 0), 0));
+ hash = SYMHASH (XSTR (symbol, 0));
pool->next_sym = const_rtx_sym_hash_table[hash];
const_rtx_sym_hash_table[hash] = pool;
/* Mark the symbol_ref as belonging to this constants pool. */
- CONSTANT_POOL_ADDRESS_P (XEXP (def, 0)) = 1;
+ CONSTANT_POOL_ADDRESS_P (symbol) = 1;
+ SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL;
current_function_uses_const_pool = 1;
- return def;
+ return copy_rtx (def);
}
/* Given a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true, return a pointer to
the corresponding pool_constant structure. */
static struct pool_constant *
-find_pool_constant (f, addr)
- struct function *f;
- rtx addr;
+find_pool_constant (struct function *f, rtx addr)
{
struct pool_constant *pool;
const char *label = XSTR (addr, 0);
@@ -3318,8 +3035,7 @@ find_pool_constant (f, addr)
/* Given a constant pool SYMBOL_REF, return the corresponding constant. */
rtx
-get_pool_constant (addr)
- rtx addr;
+get_pool_constant (rtx addr)
{
return (find_pool_constant (cfun, addr))->constant;
}
@@ -3328,9 +3044,7 @@ get_pool_constant (addr)
and whether it has been output or not. */
rtx
-get_pool_constant_mark (addr, pmarked)
- rtx addr;
- bool *pmarked;
+get_pool_constant_mark (rtx addr, bool *pmarked)
{
struct pool_constant *pool = find_pool_constant (cfun, addr);
*pmarked = (pool->mark != 0);
@@ -3340,9 +3054,7 @@ get_pool_constant_mark (addr, pmarked)
/* Likewise, but for the constant pool of a specific function. */
rtx
-get_pool_constant_for_function (f, addr)
- struct function *f;
- rtx addr;
+get_pool_constant_for_function (struct function *f, rtx addr)
{
return (find_pool_constant (f, addr))->constant;
}
@@ -3350,16 +3062,13 @@ get_pool_constant_for_function (f, addr)
/* Similar, return the mode. */
enum machine_mode
-get_pool_mode (addr)
- rtx addr;
+get_pool_mode (rtx addr)
{
return (find_pool_constant (cfun, addr))->mode;
}
enum machine_mode
-get_pool_mode_for_function (f, addr)
- struct function *f;
- rtx addr;
+get_pool_mode_for_function (struct function *f, rtx addr)
{
return (find_pool_constant (f, addr))->mode;
}
@@ -3367,8 +3076,7 @@ get_pool_mode_for_function (f, addr)
/* Similar, return the offset in the constant pool. */
int
-get_pool_offset (addr)
- rtx addr;
+get_pool_offset (rtx addr)
{
return (find_pool_constant (cfun, addr))->offset;
}
@@ -3376,7 +3084,7 @@ get_pool_offset (addr)
/* Return the size of the constant pool. */
int
-get_pool_size ()
+get_pool_size (void)
{
return pool_offset;
}
@@ -3384,9 +3092,8 @@ get_pool_size ()
/* Write all the constants in the constant pool. */
void
-output_constant_pool (fnname, fndecl)
- const char *fnname ATTRIBUTE_UNUSED;
- tree fndecl ATTRIBUTE_UNUSED;
+output_constant_pool (const char *fnname ATTRIBUTE_UNUSED,
+ tree fndecl ATTRIBUTE_UNUSED)
{
struct pool_constant *pool;
rtx x;
@@ -3427,7 +3134,7 @@ output_constant_pool (fnname, fndecl)
|| GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
break;
tmp = XEXP (XEXP (x, 0), 0);
- /* FALLTHRU */
+ /* Fall through. */
case LABEL_REF:
tmp = XEXP (x, 0);
@@ -3455,7 +3162,7 @@ output_constant_pool (fnname, fndecl)
assemble_align (pool->align);
/* Output the label. */
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LC", pool->labelno);
+ (*targetm.asm_out.internal_label) (asm_out_file, "LC", pool->labelno);
/* Output the value of the constant itself. */
switch (GET_MODE_CLASS (pool->mode))
@@ -3536,17 +3243,17 @@ output_constant_pool (fnname, fndecl)
}
/* Look through the instructions for this function, and mark all the
- entries in the constant pool which are actually being used.
- Emit used deferred strings. */
+ entries in the constant pool which are actually being used. Emit
+ deferred constants which have indeed been used. */
static void
-mark_constant_pool ()
+mark_constant_pool (void)
{
rtx insn;
rtx link;
struct pool_constant *pool;
- if (first_pool == 0 && htab_elements (const_str_htab) == 0)
+ if (first_pool == 0 && n_deferred_constants == 0)
return;
for (pool = first_pool; pool; pool = pool->next)
@@ -3573,8 +3280,7 @@ mark_constant_pool ()
deferred strings that are used. */
static void
-mark_constants (x)
- rtx x;
+mark_constants (rtx x)
{
int i;
const char *format_ptr;
@@ -3638,9 +3344,7 @@ mark_constants (x)
be used with for_each_rtx to mark all SYMBOL_REFs in an rtx. */
static int
-mark_constant (current_rtx, data)
- rtx *current_rtx;
- void *data ATTRIBUTE_UNUSED;
+mark_constant (rtx *current_rtx, void *data ATTRIBUTE_UNUSED)
{
rtx x = *current_rtx;
@@ -3660,33 +3364,23 @@ mark_constant (current_rtx, data)
else
return -1;
}
- else if (STRING_POOL_ADDRESS_P (x))
+ else if (TREE_CONSTANT_POOL_ADDRESS_P (x))
{
- struct deferred_string **defstr;
-
- defstr = (struct deferred_string **)
- htab_find_slot_with_hash (const_str_htab, XSTR (x, 0),
- STRHASH (XSTR (x, 0)), NO_INSERT);
- if (defstr)
+ tree exp = SYMBOL_REF_DECL (x);
+ if (!TREE_ASM_WRITTEN (exp))
{
- struct deferred_string *p = *defstr;
-
- STRING_POOL_ADDRESS_P (x) = 0;
- output_constant_def_contents (p->exp, 0, p->labelno);
- htab_clear_slot (const_str_htab, (void **) defstr);
+ n_deferred_constants--;
+ output_constant_def_contents (x);
}
}
}
return 0;
}
-/* Find all the constants whose addresses are referenced inside of EXP,
- and make sure assembler code with a label has been output for each one.
- Indicate whether an ADDR_EXPR has been encountered. */
+/* Determine what kind of relocations EXP may need. */
-static int
-output_addressed_constants (exp)
- tree exp;
+int
+compute_reloc_for_constant (tree exp)
{
int reloc = 0, reloc2;
tree tem;
@@ -3706,10 +3400,6 @@ output_addressed_constants (exp)
tem = TREE_OPERAND (tem, 0))
;
- if (TREE_CODE_CLASS (TREE_CODE (tem)) == 'c'
- || TREE_CODE (tem) == CONSTRUCTOR)
- output_constant_def (tem, 0);
-
if (TREE_PUBLIC (tem))
reloc |= 2;
else
@@ -3717,13 +3407,13 @@ output_addressed_constants (exp)
break;
case PLUS_EXPR:
- reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
- reloc |= output_addressed_constants (TREE_OPERAND (exp, 1));
+ reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
+ reloc |= compute_reloc_for_constant (TREE_OPERAND (exp, 1));
break;
case MINUS_EXPR:
- reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
- reloc2 = output_addressed_constants (TREE_OPERAND (exp, 1));
+ reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
+ reloc2 = compute_reloc_for_constant (TREE_OPERAND (exp, 1));
/* The difference of two local labels is computable at link time. */
if (reloc == 1 && reloc2 == 1)
reloc = 0;
@@ -3734,13 +3424,13 @@ output_addressed_constants (exp)
case NOP_EXPR:
case CONVERT_EXPR:
case NON_LVALUE_EXPR:
- reloc = output_addressed_constants (TREE_OPERAND (exp, 0));
+ reloc = compute_reloc_for_constant (TREE_OPERAND (exp, 0));
break;
case CONSTRUCTOR:
for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem))
if (TREE_VALUE (tem) != 0)
- reloc |= output_addressed_constants (TREE_VALUE (tem));
+ reloc |= compute_reloc_for_constant (TREE_VALUE (tem));
break;
@@ -3749,6 +3439,58 @@ output_addressed_constants (exp)
}
return reloc;
}
+
+/* Find all the constants whose addresses are referenced inside of EXP,
+ and make sure assembler code with a label has been output for each one.
+ Indicate whether an ADDR_EXPR has been encountered. */
+
+static void
+output_addressed_constants (tree exp)
+{
+ tree tem;
+
+ /* Give the front-end a chance to convert VALUE to something that
+ looks more like a constant to the back-end. */
+ exp = (*lang_hooks.expand_constant) (exp);
+
+ switch (TREE_CODE (exp))
+ {
+ case ADDR_EXPR:
+ case FDESC_EXPR:
+ /* Go inside any operations that get_inner_reference can handle and see
+ if what's inside is a constant: no need to do anything here for
+ addresses of variables or functions. */
+ for (tem = TREE_OPERAND (exp, 0); handled_component_p (tem);
+ tem = TREE_OPERAND (tem, 0))
+ ;
+
+ if (TREE_CODE_CLASS (TREE_CODE (tem)) == 'c'
+ || TREE_CODE (tem) == CONSTRUCTOR)
+ output_constant_def (tem, 0);
+ break;
+
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ output_addressed_constants (TREE_OPERAND (exp, 1));
+ /* Fall through. */
+
+ case NOP_EXPR:
+ case CONVERT_EXPR:
+ case NON_LVALUE_EXPR:
+ output_addressed_constants (TREE_OPERAND (exp, 0));
+ break;
+
+ case CONSTRUCTOR:
+ for (tem = CONSTRUCTOR_ELTS (exp); tem; tem = TREE_CHAIN (tem))
+ if (TREE_VALUE (tem) != 0)
+ output_addressed_constants (TREE_VALUE (tem));
+
+ break;
+
+ default:
+ break;
+ }
+}
/* Return nonzero if VALUE is a valid constant-valued expression
for use in initializing a static variable; one that can be an
@@ -3761,9 +3503,7 @@ output_addressed_constants (exp)
arithmetic-combinations of integers. */
tree
-initializer_constant_valid_p (value, endtype)
- tree value;
- tree endtype;
+initializer_constant_valid_p (tree value, tree endtype)
{
/* Give the front-end a chance to convert VALUE to something that
looks more like a constant to the back-end. */
@@ -3854,7 +3594,8 @@ initializer_constant_valid_p (value, endtype)
/* Likewise conversions from int to pointers, but also allow
conversions from 0. */
- if (POINTER_TYPE_P (TREE_TYPE (value))
+ if ((POINTER_TYPE_P (TREE_TYPE (value))
+ || TREE_CODE (TREE_TYPE (value)) == OFFSET_TYPE)
&& INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))))
{
if (integer_zerop (TREE_OPERAND (value, 0)))
@@ -3865,8 +3606,10 @@ initializer_constant_valid_p (value, endtype)
endtype);
}
- /* Allow conversions to union types if the value inside is okay. */
- if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
+ /* Allow conversions to struct or union types if the value
+ inside is okay. */
+ if (TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE
+ || TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
return initializer_constant_valid_p (TREE_OPERAND (value, 0),
endtype);
break;
@@ -3920,7 +3663,7 @@ initializer_constant_valid_p (value, endtype)
op1 = TREE_OPERAND (value, 1);
/* Like STRIP_NOPS except allow the operand mode to widen.
- This works around a feature of fold that simplfies
+ This works around a feature of fold that simplifies
(int)(p1 - p2) to ((int)p1 - (int)p2) under the theory
that the narrower operation is cheaper. */
@@ -3986,15 +3729,12 @@ initializer_constant_valid_p (value, endtype)
ALIGN is the alignment of the data in bits. */
void
-output_constant (exp, size, align)
- tree exp;
- HOST_WIDE_INT size;
- unsigned int align;
+output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align)
{
enum tree_code code;
- HOST_WIDE_INT thissize;
+ unsigned HOST_WIDE_INT thissize;
- /* Some front-ends use constants other than the standard language-indepdent
+ /* Some front-ends use constants other than the standard language-independent
varieties, but which may still be output directly. Give the front-end a
chance to convert EXP to a language-independent representation. */
exp = (*lang_hooks.expand_constant) (exp);
@@ -4042,6 +3782,7 @@ output_constant (exp, size, align)
case ENUMERAL_TYPE:
case POINTER_TYPE:
case REFERENCE_TYPE:
+ case OFFSET_TYPE:
if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode,
EXPAND_INITIALIZER),
size, align, 0))
@@ -4052,9 +3793,7 @@ output_constant (exp, size, align)
if (TREE_CODE (exp) != REAL_CST)
error ("initializer for floating value is not a floating constant");
- assemble_real (TREE_REAL_CST (exp),
- mode_for_size (size * BITS_PER_UNIT, MODE_FLOAT, 0),
- align);
+ assemble_real (TREE_REAL_CST (exp), TYPE_MODE (TREE_TYPE (exp)), align);
break;
case COMPLEX_TYPE:
@@ -4072,7 +3811,8 @@ output_constant (exp, size, align)
}
else if (TREE_CODE (exp) == STRING_CST)
{
- thissize = MIN (TREE_STRING_LENGTH (exp), size);
+ thissize = MIN ((unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp),
+ size);
assemble_string (TREE_STRING_POINTER (exp), thissize);
}
else if (TREE_CODE (exp) == VECTOR_CST)
@@ -4111,7 +3851,7 @@ output_constant (exp, size, align)
thissize, align, 1);
else if (TREE_CODE (exp) == CONSTRUCTOR)
{
- unsigned char *buffer = (unsigned char *) alloca (thissize);
+ unsigned char *buffer = alloca (thissize);
if (get_set_constructor_bytes (exp, buffer, thissize))
abort ();
assemble_string ((char *) buffer, thissize);
@@ -4127,9 +3867,8 @@ output_constant (exp, size, align)
abort ();
}
- size -= thissize;
- if (size > 0)
- assemble_zeros (size);
+ if (size > thissize)
+ assemble_zeros (size - thissize);
}
@@ -4138,8 +3877,7 @@ output_constant (exp, size, align)
type with an unspecified upper bound. */
static unsigned HOST_WIDE_INT
-array_size_for_constructor (val)
- tree val;
+array_size_for_constructor (tree val)
{
tree max_index, i;
@@ -4179,10 +3917,8 @@ array_size_for_constructor (val)
Generate at least SIZE bytes, padding if necessary. */
static void
-output_constructor (exp, size, align)
- tree exp;
- HOST_WIDE_INT size;
- unsigned int align;
+output_constructor (tree exp, unsigned HOST_WIDE_INT size,
+ unsigned int align)
{
tree type = TREE_TYPE (exp);
tree link, field = 0;
@@ -4190,7 +3926,7 @@ output_constructor (exp, size, align)
/* Number of bytes output or skipped so far.
In other words, current position within the constructor. */
HOST_WIDE_INT total_bytes = 0;
- /* Non-zero means BYTE contains part of a byte, to be output. */
+ /* Nonzero means BYTE contains part of a byte, to be output. */
int byte_buffer_in_use = 0;
int byte = 0;
@@ -4231,6 +3967,15 @@ output_constructor (exp, size, align)
else if (TREE_CODE (type) == ARRAY_TYPE)
index = TREE_PURPOSE (link);
+#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
+
/* Eliminate the marker that makes a cast not be an lvalue. */
if (val != 0)
STRIP_NOPS (val);
@@ -4477,7 +4222,7 @@ output_constructor (exp, size, align)
total_bytes++;
}
- if (total_bytes < size)
+ if ((unsigned HOST_WIDE_INT)total_bytes < size)
assemble_zeros (size - total_bytes);
}
@@ -4488,8 +4233,7 @@ static GTY(()) tree weak_decls;
/* Mark DECL as weak. */
static void
-mark_weak (decl)
- tree decl;
+mark_weak (tree decl)
{
DECL_WEAK (decl) = 1;
@@ -4503,9 +4247,7 @@ mark_weak (decl)
/* Merge weak status between NEWDECL and OLDDECL. */
void
-merge_weak (newdecl, olddecl)
- tree newdecl;
- tree olddecl;
+merge_weak (tree newdecl, tree olddecl)
{
if (DECL_WEAK (newdecl) == DECL_WEAK (olddecl))
return;
@@ -4521,15 +4263,16 @@ merge_weak (newdecl, olddecl)
declare_weak because the NEWDECL and OLDDECL was not yet
been merged; therefore, TREE_ASM_WRITTEN was not set. */
if (TREE_ASM_WRITTEN (olddecl))
- error_with_decl (newdecl,
- "weak declaration of `%s' must precede definition");
+ error ("%Jweak declaration of '%D' must precede definition",
+ newdecl, newdecl);
/* If we've already generated rtl referencing OLDDECL, we may
have done so in a way that will not function properly with
a weak symbol. */
else if (TREE_USED (olddecl)
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (olddecl)))
- warning_with_decl (newdecl, "weak declaration of `%s' after first use results in unspecified behavior");
+ warning ("%Jweak declaration of '%D' after first use results "
+ "in unspecified behavior", newdecl, newdecl);
if (SUPPORTS_WEAK)
{
@@ -4559,20 +4302,19 @@ merge_weak (newdecl, olddecl)
/* Declare DECL to be a weak symbol. */
void
-declare_weak (decl)
- tree decl;
+declare_weak (tree decl)
{
if (! TREE_PUBLIC (decl))
- error_with_decl (decl, "weak declaration of `%s' must be public");
+ error ("%Jweak declaration of '%D' must be public", decl, decl);
else if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl))
- error_with_decl (decl, "weak declaration of `%s' must precede definition");
+ error ("%Jweak declaration of '%D' must precede definition", decl, decl);
else if (SUPPORTS_WEAK)
{
if (! DECL_WEAK (decl))
weak_decls = tree_cons (NULL, decl, weak_decls);
}
else
- warning_with_decl (decl, "weak declaration of `%s' not supported");
+ warning ("%Jweak declaration of '%D' not supported", decl, decl);
mark_weak (decl);
}
@@ -4580,14 +4322,16 @@ declare_weak (decl)
/* Emit any pending weak declarations. */
void
-weak_finish ()
+weak_finish (void)
{
tree t;
for (t = weak_decls; t; t = TREE_CHAIN (t))
{
tree decl = TREE_VALUE (t);
- const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+#if defined (ASM_WEAKEN_DECL) || defined (ASM_WEAKEN_LABEL)
+ const char *const name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+#endif
if (! TREE_USED (decl))
continue;
@@ -4610,8 +4354,7 @@ weak_finish ()
/* Emit the assembly bits to indicate that DECL is globally visible. */
static void
-globalize_decl (decl)
- tree decl;
+globalize_decl (tree decl)
{
const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
@@ -4646,8 +4389,7 @@ globalize_decl (decl)
the symbol for TARGET. */
void
-assemble_alias (decl, target)
- tree decl, target ATTRIBUTE_UNUSED;
+assemble_alias (tree decl, tree target ATTRIBUTE_UNUSED)
{
const char *name;
@@ -4673,14 +4415,26 @@ assemble_alias (decl, target)
#endif
#else /* !ASM_OUTPUT_DEF */
#if defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL)
- if (! DECL_WEAK (decl))
- warning ("only weak aliases are supported in this configuration");
-
+ if (DECL_WEAK (decl))
+ {
+ tree *p, t;
#ifdef ASM_WEAKEN_DECL
- ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target));
+ ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target));
#else
- ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
+ ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
#endif
+ /* Remove this function from the pending weak list so that
+ we do not emit multiple .weak directives for it. */
+ for (p = &weak_decls; (t = *p) ; )
+ if (DECL_ASSEMBLER_NAME (decl)
+ == DECL_ASSEMBLER_NAME (TREE_VALUE (t)))
+ *p = TREE_CHAIN (t);
+ else
+ p = &TREE_CHAIN (t);
+ }
+ else
+ warning ("only weak aliases are supported in this configuration");
+
#else
warning ("alias definitions not supported in this configuration; ignored");
#endif
@@ -4695,9 +4449,7 @@ assemble_alias (decl, target)
the visibility type VIS, which must not be VISIBILITY_DEFAULT. */
void
-default_assemble_visibility (decl, vis)
- tree decl;
- int vis;
+default_assemble_visibility (tree decl, int vis)
{
static const char * const visibility_types[] = {
NULL, "internal", "hidden", "protected"
@@ -4720,10 +4472,9 @@ default_assemble_visibility (decl, vis)
/* A helper function to call assemble_visibility when needed for a decl. */
static void
-maybe_assemble_visibility (decl)
- tree decl;
+maybe_assemble_visibility (tree decl)
{
- enum symbol_visibility vis = decl_visibility (decl);
+ enum symbol_visibility vis = DECL_VISIBILITY (decl);
if (vis != VISIBILITY_DEFAULT)
(* targetm.asm_out.visibility) (decl, vis);
@@ -4735,7 +4486,7 @@ maybe_assemble_visibility (decl)
a target-specific mechanism for having duplicates discarded. */
int
-supports_one_only ()
+supports_one_only (void)
{
if (SUPPORTS_ONE_ONLY)
return 1;
@@ -4746,24 +4497,23 @@ supports_one_only ()
translation units without generating a linker error. */
void
-make_decl_one_only (decl)
- tree decl;
+make_decl_one_only (tree decl)
{
if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
abort ();
TREE_PUBLIC (decl) = 1;
- if (TREE_CODE (decl) == VAR_DECL
- && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
- DECL_COMMON (decl) = 1;
- else if (SUPPORTS_ONE_ONLY)
+ if (SUPPORTS_ONE_ONLY)
{
#ifdef MAKE_DECL_ONE_ONLY
MAKE_DECL_ONE_ONLY (decl);
#endif
DECL_ONE_ONLY (decl) = 1;
}
+ else if (TREE_CODE (decl) == VAR_DECL
+ && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
+ DECL_COMMON (decl) = 1;
else if (SUPPORTS_WEAK)
DECL_WEAK (decl) = 1;
else
@@ -4771,19 +4521,18 @@ make_decl_one_only (decl)
}
void
-init_varasm_once ()
+init_varasm_once (void)
{
- const_str_htab = htab_create_ggc (128, const_str_htab_hash,
- const_str_htab_eq, NULL);
- in_named_htab = htab_create (31, in_named_entry_hash,
- in_named_entry_eq, NULL);
+ in_named_htab = htab_create_ggc (31, in_named_entry_hash,
+ in_named_entry_eq, NULL);
+ const_desc_htab = htab_create_ggc (1009, const_desc_hash,
+ const_desc_eq, NULL);
const_alias_set = new_alias_set ();
}
enum tls_model
-decl_tls_model (decl)
- tree decl;
+decl_tls_model (tree decl)
{
enum tls_model kind;
tree attr = lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl));
@@ -4827,31 +4576,6 @@ decl_tls_model (decl)
return kind;
}
-enum symbol_visibility
-decl_visibility (decl)
- tree decl;
-{
- tree attr = lookup_attribute ("visibility", DECL_ATTRIBUTES (decl));
-
- if (attr)
- {
- const char *which = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr)));
-
- if (strcmp (which, "default") == 0)
- return VISIBILITY_DEFAULT;
- if (strcmp (which, "internal") == 0)
- return VISIBILITY_INTERNAL;
- if (strcmp (which, "hidden") == 0)
- return VISIBILITY_HIDDEN;
- if (strcmp (which, "protected") == 0)
- return VISIBILITY_PROTECTED;
-
- abort ();
- }
-
- return VISIBILITY_DEFAULT;
-}
-
/* Select a set of attributes for section NAME based on the properties
of DECL and whether or not RELOC indicates that DECL's initializer
might contain runtime relocations.
@@ -4860,20 +4584,14 @@ decl_visibility (decl)
read-only for a const data decl, and writable for a non-const data decl. */
unsigned int
-default_section_type_flags (decl, name, reloc)
- tree decl;
- const char *name;
- int reloc;
+default_section_type_flags (tree decl, const char *name, int reloc)
{
return default_section_type_flags_1 (decl, name, reloc, flag_pic);
}
unsigned int
-default_section_type_flags_1 (decl, name, reloc, shlib)
- tree decl;
- const char *name;
- int reloc;
- int shlib;
+default_section_type_flags_1 (tree decl, const char *name, int reloc,
+ int shlib)
{
unsigned int flags;
@@ -4924,9 +4642,8 @@ default_section_type_flags_1 (decl, name, reloc, shlib)
Four variants for common object file formats. */
void
-default_no_named_section (name, flags)
- const char *name ATTRIBUTE_UNUSED;
- unsigned int flags ATTRIBUTE_UNUSED;
+default_no_named_section (const char *name ATTRIBUTE_UNUSED,
+ unsigned int flags ATTRIBUTE_UNUSED)
{
/* Some object formats don't support named sections at all. The
front-end should already have flagged this as an error. */
@@ -4934,9 +4651,7 @@ default_no_named_section (name, flags)
}
void
-default_elf_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+default_elf_asm_named_section (const char *name, unsigned int flags)
{
char flagchars[10], *f = flagchars;
@@ -4983,9 +4698,7 @@ default_elf_asm_named_section (name, flags)
}
void
-default_coff_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+default_coff_asm_named_section (const char *name, unsigned int flags)
{
char flagchars[8], *f = flagchars;
@@ -4999,9 +4712,7 @@ default_coff_asm_named_section (name, flags)
}
void
-default_pe_asm_named_section (name, flags)
- const char *name;
- unsigned int flags;
+default_pe_asm_named_section (const char *name, unsigned int flags)
{
default_coff_asm_named_section (name, flags);
@@ -5015,42 +4726,11 @@ default_pe_asm_named_section (name, flags)
}
}
-/* Used for vtable gc in GNU binutils. Record that the pointer at OFFSET
- from SYMBOL is used in all classes derived from SYMBOL. */
-
-void
-assemble_vtable_entry (symbol, offset)
- rtx symbol;
- HOST_WIDE_INT offset;
-{
- fputs ("\t.vtable_entry ", asm_out_file);
- output_addr_const (asm_out_file, symbol);
- fputs (", ", asm_out_file);
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, offset);
- fputc ('\n', asm_out_file);
-}
-
-/* Used for vtable gc in GNU binutils. Record the class hierarchy by noting
- that the vtable symbol CHILD is derived from the vtable symbol PARENT. */
-
-void
-assemble_vtable_inherit (child, parent)
- rtx child, parent;
-{
- fputs ("\t.vtable_inherit ", asm_out_file);
- output_addr_const (asm_out_file, child);
- fputs (", ", asm_out_file);
- output_addr_const (asm_out_file, parent);
- fputc ('\n', asm_out_file);
-}
-
/* The lame default section selector. */
void
-default_select_section (decl, reloc, align)
- tree decl;
- int reloc;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+default_select_section (tree decl, int reloc,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
bool readonly = false;
@@ -5116,13 +4796,10 @@ enum section_category
};
static enum section_category
-categorize_decl_for_section PARAMS ((tree, int, int));
+categorize_decl_for_section (tree, int, int);
static enum section_category
-categorize_decl_for_section (decl, reloc, shlib)
- tree decl;
- int reloc;
- int shlib;
+categorize_decl_for_section (tree decl, int reloc, int shlib)
{
enum section_category ret;
@@ -5201,18 +4878,13 @@ categorize_decl_for_section (decl, reloc, shlib)
}
bool
-decl_readonly_section (decl, reloc)
- tree decl;
- int reloc;
+decl_readonly_section (tree decl, int reloc)
{
return decl_readonly_section_1 (decl, reloc, flag_pic);
}
bool
-decl_readonly_section_1 (decl, reloc, shlib)
- tree decl;
- int reloc;
- int shlib;
+decl_readonly_section_1 (tree decl, int reloc, int shlib)
{
switch (categorize_decl_for_section (decl, reloc, shlib))
{
@@ -5232,20 +4904,15 @@ decl_readonly_section_1 (decl, reloc, shlib)
/* Select a section based on the above categorization. */
void
-default_elf_select_section (decl, reloc, align)
- tree decl;
- int reloc;
- unsigned HOST_WIDE_INT align;
+default_elf_select_section (tree decl, int reloc,
+ unsigned HOST_WIDE_INT align)
{
default_elf_select_section_1 (decl, reloc, align, flag_pic);
}
void
-default_elf_select_section_1 (decl, reloc, align, shlib)
- tree decl;
- int reloc;
- unsigned HOST_WIDE_INT align;
- int shlib;
+default_elf_select_section_1 (tree decl, int reloc,
+ unsigned HOST_WIDE_INT align, int shlib)
{
switch (categorize_decl_for_section (decl, reloc, shlib))
{
@@ -5310,18 +4977,13 @@ default_elf_select_section_1 (decl, reloc, align, shlib)
categorization performed above. */
void
-default_unique_section (decl, reloc)
- tree decl;
- int reloc;
+default_unique_section (tree decl, int reloc)
{
default_unique_section_1 (decl, reloc, flag_pic);
}
void
-default_unique_section_1 (decl, reloc, shlib)
- tree decl;
- int reloc;
- int shlib;
+default_unique_section_1 (tree decl, int reloc, int shlib)
{
bool one_only = DECL_ONE_ONLY (decl);
const char *prefix, *name;
@@ -5381,10 +5043,9 @@ default_unique_section_1 (decl, reloc, shlib)
}
void
-default_select_rtx_section (mode, x, align)
- enum machine_mode mode ATTRIBUTE_UNUSED;
- rtx x;
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
+default_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx x,
+ unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
{
if (flag_pic)
switch (GET_CODE (x))
@@ -5403,10 +5064,8 @@ default_select_rtx_section (mode, x, align)
}
void
-default_elf_select_rtx_section (mode, x, align)
- enum machine_mode mode;
- rtx x;
- unsigned HOST_WIDE_INT align;
+default_elf_select_rtx_section (enum machine_mode mode, rtx x,
+ unsigned HOST_WIDE_INT align)
{
/* ??? Handle small data here somehow. */
@@ -5429,12 +5088,44 @@ default_elf_select_rtx_section (mode, x, align)
mergeable_constant_section (mode, align, 0);
}
+/* Set the generally applicable flags on the SYMBOL_REF for EXP. */
+
+void
+default_encode_section_info (tree decl, rtx rtl, int first ATTRIBUTE_UNUSED)
+{
+ rtx symbol;
+ int flags;
+
+ /* Careful not to prod global register variables. */
+ if (GET_CODE (rtl) != MEM)
+ return;
+ symbol = XEXP (rtl, 0);
+ if (GET_CODE (symbol) != SYMBOL_REF)
+ return;
+
+ flags = 0;
+ if (TREE_CODE (decl) == FUNCTION_DECL)
+ flags |= SYMBOL_FLAG_FUNCTION;
+ if ((*targetm.binds_local_p) (decl))
+ flags |= SYMBOL_FLAG_LOCAL;
+ if ((*targetm.in_small_data_p) (decl))
+ flags |= SYMBOL_FLAG_SMALL;
+ if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
+ flags |= decl_tls_model (decl) << SYMBOL_FLAG_TLS_SHIFT;
+ /* ??? Why is DECL_EXTERNAL ever set for non-PUBLIC names? Without
+ being PUBLIC, the thing *must* be defined in this translation unit.
+ Prevent this buglet from being propagated into rtl code as well. */
+ if (DECL_P (decl) && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
+ flags |= SYMBOL_FLAG_EXTERNAL;
+
+ SYMBOL_REF_FLAGS (symbol) = flags;
+}
+
/* By default, we do nothing for encode_section_info, so we need not
do anything but discard the '*' marker. */
const char *
-default_strip_name_encoding (str)
- const char *str;
+default_strip_name_encoding (const char *str)
{
return str + (*str == '*');
}
@@ -5443,16 +5134,13 @@ default_strip_name_encoding (str)
wrt cross-module name binding. */
bool
-default_binds_local_p (exp)
- tree exp;
+default_binds_local_p (tree exp)
{
- return default_binds_local_p_1 (exp, flag_pic);
+ return default_binds_local_p_1 (exp, flag_shlib);
}
bool
-default_binds_local_p_1 (exp, shlib)
- tree exp;
- int shlib;
+default_binds_local_p_1 (tree exp, int shlib)
{
bool local_p;
@@ -5463,7 +5151,7 @@ default_binds_local_p_1 (exp, shlib)
else if (! TREE_PUBLIC (exp))
local_p = true;
/* A variable is local if the user tells us so. */
- else if (decl_visibility (exp) != VISIBILITY_DEFAULT)
+ else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT)
local_p = true;
/* Otherwise, variables defined outside this object may not be local. */
else if (DECL_EXTERNAL (exp))
@@ -5489,19 +5177,63 @@ default_binds_local_p_1 (exp, shlib)
return local_p;
}
+/* Determine whether or not a pointer mode is valid. Assume defaults
+ of ptr_mode or Pmode - can be overridden. */
+bool
+default_valid_pointer_mode (enum machine_mode mode)
+{
+ return (mode == ptr_mode || mode == Pmode);
+}
+
/* Default function to output code that will globalize a label. A
target must define GLOBAL_ASM_OP or provide it's own function to
globalize a label. */
#ifdef GLOBAL_ASM_OP
void
-default_globalize_label (stream, name)
- FILE * stream;
- const char *name;
+default_globalize_label (FILE * stream, const char *name)
{
fputs (GLOBAL_ASM_OP, stream);
assemble_name (stream, name);
putc ('\n', stream);
}
#endif /* GLOBAL_ASM_OP */
-
+
+/* This is how to output an internal numbered label where PREFIX is
+ the class of label and LABELNO is the number within the class. */
+
+void
+default_internal_label (FILE *stream, const char *prefix,
+ unsigned long labelno)
+{
+ char *const buf = alloca (40 + strlen (prefix));
+ ASM_GENERATE_INTERNAL_LABEL (buf, prefix, labelno);
+ ASM_OUTPUT_LABEL (stream, buf);
+}
+
+/* This is the default behavior at the beginning of a file. It's
+ controlled by two other target-hook toggles. */
+void
+default_file_start (void)
+{
+ if (targetm.file_start_app_off && !flag_verbose_asm)
+ fputs (ASM_APP_OFF, asm_out_file);
+
+ if (targetm.file_start_file_directive)
+ output_file_directive (asm_out_file, main_input_filename);
+}
+
+/* This is a generic routine suitable for use as TARGET_ASM_FILE_END
+ which emits a special section directive used to indicate whether or
+ not this object file needs an executable stack. This is primarily
+ a GNU extension to ELF but could be used on other targets. */
+void
+file_end_indicate_exec_stack (void)
+{
+ unsigned int flags = SECTION_DEBUG;
+ if (trampolines_created)
+ flags |= SECTION_CODE;
+
+ named_section_flags (".note.GNU-stack", flags);
+}
+
#include "gt-varasm.h"
diff --git a/contrib/gcc/varray.c b/contrib/gcc/varray.c
index 51e3e8bc142e..177d2f16f185 100644
--- a/contrib/gcc/varray.c
+++ b/contrib/gcc/varray.c
@@ -1,5 +1,6 @@
/* Virtual array support.
- Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
This file is part of GCC.
@@ -22,55 +23,111 @@
#include "config.h"
#include "errors.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "varray.h"
#include "ggc.h"
+#include "hashtab.h"
#define VARRAY_HDR_SIZE (sizeof (struct varray_head_tag) - sizeof (varray_data))
-static const size_t element_size[NUM_VARRAY_DATA] = {
- sizeof (char),
- sizeof (unsigned char),
- sizeof (short),
- sizeof (unsigned short),
- sizeof (int),
- sizeof (unsigned int),
- sizeof (long),
- sizeof (unsigned long),
- sizeof (HOST_WIDE_INT),
- sizeof (unsigned HOST_WIDE_INT),
- sizeof (PTR),
- sizeof (char *),
- sizeof (struct rtx_def *),
- sizeof (struct rtvec_def *),
- sizeof (union tree_node *),
- sizeof (struct bitmap_head_def *),
- sizeof (struct reg_info_def *),
- sizeof (struct const_equiv_data),
- sizeof (struct basic_block_def *),
- sizeof (struct elt_list *)
+#ifdef GATHER_STATISTICS
+
+/* Store infromation about each particular varray. */
+struct varray_descriptor
+{
+ const char *name;
+ int allocated;
+ int created;
+ int resized;
+ int copied;
};
-static const int uses_ggc[NUM_VARRAY_DATA] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* unsigned HOST_WIDE_INT */
- 1, /* PTR */
- 1, 1, 1, 1, 1, /* bitmap_head_def */
- 0, 0, 0, 1
+/* Hashtable mapping varray names to descriptors. */
+static htab_t varray_hash;
+
+/* Hashtable helpers. */
+static hashval_t
+hash_descriptor (const void *p)
+{
+ const struct varray_descriptor *d = p;
+ return htab_hash_pointer (d->name);
+}
+static int
+eq_descriptor (const void *p1, const void *p2)
+{
+ const struct varray_descriptor *d = p1;
+ return d->name == p2;
+}
+
+/* For given name, return descriptor, create new if needed. */
+static struct varray_descriptor *
+varray_descriptor (const char *name)
+{
+ struct varray_descriptor **slot;
+
+ if (!varray_hash)
+ varray_hash = htab_create (10, hash_descriptor, eq_descriptor, NULL);
+
+ slot = (struct varray_descriptor **)
+ htab_find_slot_with_hash (varray_hash, name,
+ htab_hash_pointer (name),
+ 1);
+ if (*slot)
+ return *slot;
+ *slot = xcalloc (sizeof (**slot), 1);
+ (*slot)->name = name;
+ return *slot;
+}
+#endif
+
+/* Do not add any more non-GC items here. Please either remove or GC
+ those items that are not GCed. */
+
+static const struct {
+ unsigned char size;
+ bool uses_ggc;
+} element[NUM_VARRAY_DATA] = {
+ { sizeof (char), 1 },
+ { sizeof (unsigned char), 1 },
+ { sizeof (short), 1 },
+ { sizeof (unsigned short), 1 },
+ { sizeof (int), 1 },
+ { sizeof (unsigned int), 1 },
+ { sizeof (long), 1 },
+ { sizeof (unsigned long), 1 },
+ { sizeof (HOST_WIDE_INT), 1 },
+ { sizeof (unsigned HOST_WIDE_INT), 1 },
+ { sizeof (void *), 1 },
+ { sizeof (char *), 1 },
+ { sizeof (struct rtx_def *), 1 },
+ { sizeof (struct rtvec_def *), 1 },
+ { sizeof (union tree_node *), 1 },
+ { sizeof (struct bitmap_head_def *), 1 },
+ { sizeof (struct reg_info_def *), 0 },
+ { sizeof (struct const_equiv_data), 0 },
+ { sizeof (struct basic_block_def *), 0 },
+ { sizeof (struct elt_list *), 1 },
};
/* Allocate a virtual array with NUM_ELEMENT elements, each of which is
ELEMENT_SIZE bytes long, named NAME. Array elements are zeroed. */
varray_type
-varray_init (num_elements, element_kind, name)
- size_t num_elements;
- enum varray_data_enum element_kind;
- const char *name;
+varray_init (size_t num_elements, enum varray_data_enum element_kind,
+ const char *name)
{
- size_t data_size = num_elements * element_size[element_kind];
+ size_t data_size = num_elements * element[element_kind].size;
varray_type ptr;
- if (uses_ggc [element_kind])
- ptr = (varray_type) ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);
+#ifdef GATHER_STATISTICS
+ struct varray_descriptor *desc = varray_descriptor (name);
+
+ desc->created++;
+ desc->allocated += data_size + VARRAY_HDR_SIZE;
+#endif
+ if (element[element_kind].uses_ggc)
+ ptr = ggc_alloc_cleared (VARRAY_HDR_SIZE + data_size);
else
- ptr = (varray_type) xcalloc (VARRAY_HDR_SIZE + data_size, 1);
+ ptr = xcalloc (VARRAY_HDR_SIZE + data_size, 1);
ptr->num_elements = num_elements;
ptr->elements_used = 0;
@@ -82,25 +139,35 @@ varray_init (num_elements, element_kind, name)
/* Grow/shrink the virtual array VA to N elements. Zero any new elements
allocated. */
varray_type
-varray_grow (va, n)
- varray_type va;
- size_t n;
+varray_grow (varray_type va, size_t n)
{
size_t old_elements = va->num_elements;
-
if (n != old_elements)
{
- size_t elem_size = element_size[va->type];
+ size_t elem_size = element[va->type].size;
size_t old_data_size = old_elements * elem_size;
size_t data_size = n * elem_size;
+#ifdef GATHER_STATISTICS
+ struct varray_descriptor *desc = varray_descriptor (va->name);
+ varray_type oldva = va;
+
+ if (data_size > old_data_size)
+ desc->allocated += data_size - old_data_size;
+ desc->resized ++;
+#endif
+
- if (uses_ggc[va->type])
- va = (varray_type) ggc_realloc (va, VARRAY_HDR_SIZE + data_size);
+ if (element[va->type].uses_ggc)
+ va = ggc_realloc (va, VARRAY_HDR_SIZE + data_size);
else
- va = (varray_type) xrealloc ((char *) va, VARRAY_HDR_SIZE + data_size);
+ va = xrealloc (va, VARRAY_HDR_SIZE + data_size);
va->num_elements = n;
if (n > old_elements)
memset (&va->data.c[old_data_size], 0, data_size - old_data_size);
+#ifdef GATHER_STATISTICS
+ if (oldva != va)
+ desc->copied++;
+#endif
}
return va;
@@ -108,10 +175,9 @@ varray_grow (va, n)
/* Reset a varray to its original state. */
void
-varray_clear (va)
- varray_type va;
+varray_clear (varray_type va)
{
- size_t data_size = element_size[va->type] * va->num_elements;
+ size_t data_size = element[va->type].size * va->num_elements;
memset (va->data.c, 0, data_size);
va->elements_used = 0;
@@ -121,19 +187,62 @@ varray_clear (va)
#if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
-extern void error PARAMS ((const char *, ...)) ATTRIBUTE_PRINTF_1;
-
void
-varray_check_failed (va, n, file, line, function)
- varray_type va;
- size_t n;
- const char *file;
- int line;
- const char *function;
+varray_check_failed (varray_type va, size_t n, const char *file, int line,
+ const char *function)
{
- internal_error ("virtual array %s[%lu]: element %lu out of bounds in %s, at %s:%d",
+ internal_error ("virtual array %s[%lu]: element %lu out of bounds "
+ "in %s, at %s:%d",
va->name, (unsigned long) va->num_elements, (unsigned long) n,
function, trim_filename (file), line);
}
+void
+varray_underflow (varray_type va, const char *file, int line,
+ const char *function)
+{
+ internal_error ("underflowed virtual array %s in %s, at %s:%d",
+ va->name, function, trim_filename (file), line);
+}
+
+#endif
+
+/* Output per-varray statistics. */
+#ifdef GATHER_STATISTICS
+struct output_info
+{
+ int count;
+ int size;
+};
+static int
+print_statistics (void **slot, void *b)
+{
+ struct varray_descriptor *d = (struct varray_descriptor *) *slot;
+ struct output_info *i = (struct output_info *) b;
+
+ if (d->allocated)
+ {
+ fprintf (stderr, "%-21s %6d %10d %7d %7d\n", d->name,
+ d->created, d->allocated, d->resized, d->copied);
+ i->size += d->allocated;
+ i->count += d->created;
+ }
+ return 1;
+}
+#endif
+void dump_varray_statistics (void)
+{
+#ifdef GATHER_STATISTICS
+ struct output_info info;
+
+ fprintf (stderr, "\nVARRAY Kind Count Bytes Resized copied\n");
+ fprintf (stderr, "-------------------------------------------------------\n");
+ info.count = 0;
+ info.size = 0;
+ htab_traverse (varray_hash, print_statistics, &info);
+ fprintf (stderr, "-------------------------------------------------------\n");
+ fprintf (stderr, "%-20s %7d %10d\n",
+ "Total", info.count, info.size);
+ fprintf (stderr, "-------------------------------------------------------\n");
#endif
+}
diff --git a/contrib/gcc/varray.h b/contrib/gcc/varray.h
index 8d4dafb6ca66..194d10cd563d 100644
--- a/contrib/gcc/varray.h
+++ b/contrib/gcc/varray.h
@@ -1,5 +1,6 @@
/* Virtual array support.
- Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Cygnus Solutions.
This file is part of GCC.
@@ -28,6 +29,8 @@
#ifndef GCC_SYSTEM_H
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#endif
/* Auxiliary structure used inside the varray structure, used for
@@ -47,15 +50,15 @@ struct const_equiv_data GTY(()) {
pseudos that contain pointers into the replacement area allocated for
this inline instance. These pseudos are then marked as being equivalent
to the appropriate address and substituted if valid. */
- struct rtx_def *rtx;
+ rtx rtx;
/* Record the valid age for each entry. The entry is invalid if its
age is less than const_age. */
unsigned age;
};
-/* Enum indicating what the varray contains.
- If this is changed, `element_size' in varray.c needs to be updated. */
+/* Enum indicating what the varray contains.
+ If this is changed, `element' in varray.c needs to be updated. */
enum varray_data_enum {
VARRAY_DATA_C,
@@ -107,18 +110,18 @@ typedef union varray_data_tag GTY (()) {
tag ("VARRAY_DATA_GENERIC"))) generic[1];
char *GTY ((length ("%0.num_elements"),
tag ("VARRAY_DATA_CPTR"))) cptr[1];
- struct rtx_def *GTY ((length ("%0.num_elements"),
+ rtx GTY ((length ("%0.num_elements"),
tag ("VARRAY_DATA_RTX"))) rtx[1];
- struct rtvec_def *GTY ((length ("%0.num_elements"),
+ rtvec GTY ((length ("%0.num_elements"),
tag ("VARRAY_DATA_RTVEC"))) rtvec[1];
- union tree_node *GTY ((length ("%0.num_elements"),
+ tree GTY ((length ("%0.num_elements"),
tag ("VARRAY_DATA_TREE"))) tree[1];
struct bitmap_head_def *GTY ((length ("%0.num_elements"),
tag ("VARRAY_DATA_BITMAP"))) bitmap[1];
struct reg_info_def *GTY ((length ("%0.num_elements"), skip (""),
tag ("VARRAY_DATA_REG"))) reg[1];
struct const_equiv_data GTY ((length ("%0.num_elements"),
- tag ("VARRAY_DATA_CONST_EQUIV"))) const_equiv[1];
+ tag ("VARRAY_DATA_CONST_EQUIV"))) const_equiv[1];
struct basic_block_def *GTY ((length ("%0.num_elements"), skip (""),
tag ("VARRAY_DATA_BB"))) bb[1];
struct elt_list *GTY ((length ("%0.num_elements"),
@@ -132,15 +135,14 @@ struct varray_head_tag GTY(()) {
using VARRAY_PUSH/VARRAY_POP. */
enum varray_data_enum type; /* The kind of elements in the varray. */
const char *name; /* name of the varray for reporting errors */
- varray_data GTY ((desc ("%0.type"))) data; /* The data elements follow,
+ varray_data GTY ((desc ("%0.type"))) data; /* The data elements follow,
must be last. */
};
typedef struct varray_head_tag *varray_type;
/* Allocate a virtual array with NUM elements, each of which is SIZE bytes
long, named NAME. Array elements are zeroed. */
-extern varray_type varray_init PARAMS ((size_t, enum varray_data_enum,
- const char *));
+extern varray_type varray_init (size_t, enum varray_data_enum, const char *);
#define VARRAY_CHAR_INIT(va, num, name) \
va = varray_init (num, VARRAY_DATA_C, name)
@@ -208,7 +210,7 @@ extern varray_type varray_init PARAMS ((size_t, enum varray_data_enum,
do { if (vp) { free (vp); vp = (varray_type) 0; } } while (0)
/* Grow/shrink the virtual array VA to N elements. */
-extern varray_type varray_grow PARAMS ((varray_type, size_t));
+extern varray_type varray_grow (varray_type, size_t);
#define VARRAY_GROW(VA, N) ((VA) = varray_grow (VA, N))
@@ -219,21 +221,35 @@ extern varray_type varray_grow PARAMS ((varray_type, size_t));
#define VARRAY_CLEAR(VA) varray_clear(VA)
-extern void varray_clear PARAMS ((varray_type));
+extern void varray_clear (varray_type);
+
+extern void dump_varray_statistics (void);
/* Check for VARRAY_xxx macros being in bound. */
#if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
-extern void varray_check_failed PARAMS ((varray_type, size_t,
- const char *, int,
- const char *)) ATTRIBUTE_NORETURN;
+extern void varray_check_failed (varray_type, size_t, const char *, int,
+ const char *) ATTRIBUTE_NORETURN;
+extern void varray_underflow (varray_type, const char *, int, const char *)
+ ATTRIBUTE_NORETURN;
#define VARRAY_CHECK(VA, N, T) __extension__ \
(*({ varray_type const _va = (VA); \
- const size_t _n = (N); \
+ const size_t _n = (N); \
if (_n >= _va->num_elements) \
varray_check_failed (_va, _n, __FILE__, __LINE__, __FUNCTION__); \
&_va->data.T[_n]; }))
+
+#define VARRAY_POP(VA) do { \
+ varray_type const _va = (VA); \
+ if (_va->elements_used == 0) \
+ varray_underflow (_va, __FILE__, __LINE__, __FUNCTION__); \
+ else \
+ _va->elements_used--; \
+} while (0)
+
#else
#define VARRAY_CHECK(VA, N, T) ((VA)->data.T[N])
+/* Pop the top element of VA. */
+#define VARRAY_POP(VA) do { ((VA)->elements_used--); } while (0)
#endif
/* Push X onto VA. T is the name of the field in varray_data
@@ -247,14 +263,6 @@ extern void varray_check_failed PARAMS ((varray_type, size_t,
} \
while (0)
-/* Pop the top element of VA. */
-#define VARRAY_POP(VA) \
- ((VA)->elements_used--)
-
-/* Return the top element of VA. */
-#define VARRAY_TOP(VA, T) \
- ((VA)->data.T[(VA)->elements_used - 1])
-
#define VARRAY_CHAR(VA, N) VARRAY_CHECK (VA, N, c)
#define VARRAY_UCHAR(VA, N) VARRAY_CHECK (VA, N, uc)
#define VARRAY_SHORT(VA, N) VARRAY_CHECK (VA, N, s)
@@ -298,6 +306,8 @@ extern void varray_check_failed PARAMS ((varray_type, size_t,
#define VARRAY_PUSH_BB(VA, X) VARRAY_PUSH (VA, bb, X)
/* Return the last element of VA. */
+#define VARRAY_TOP(VA, T) VARRAY_CHECK(VA, (VA)->elements_used - 1, T)
+
#define VARRAY_TOP_CHAR(VA) VARRAY_TOP (VA, c)
#define VARRAY_TOP_UCHAR(VA) VARRAY_TOP (VA, uc)
#define VARRAY_TOP_SHORT(VA) VARRAY_TOP (VA, s)
diff --git a/contrib/gcc/version.c b/contrib/gcc/version.c
index 19f7d763d98e..67a2de4ef237 100644
--- a/contrib/gcc/version.c
+++ b/contrib/gcc/version.c
@@ -1,4 +1,3 @@
-#include "ansidecl.h"
#include "version.h"
/* This is the string reported as the version number by all components
@@ -6,7 +5,7 @@
please modify this string to indicate that, e.g. by putting your
organization's name in parentheses at the end of the string. */
-const char version_string[] = "3.3.3 20031106 (prerelease)";
+const char version_string[] = "3.4.2 20040728 (prerelease)";
/* This is the location of the online document giving instructions for
reporting bugs. If you distribute a modified version of GCC,
diff --git a/contrib/gcc/vmsdbgout.c b/contrib/gcc/vmsdbgout.c
index 3b8b8f893318..4f7f62d2e976 100644
--- a/contrib/gcc/vmsdbgout.c
+++ b/contrib/gcc/vmsdbgout.c
@@ -1,9 +1,9 @@
-/* Output VMS debug format symbol table information from the GNU C compiler.
+/* Output VMS debug format symbol table information from GCC.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Douglas B. Rupp (rupp@gnat.com).
-This file is part of GNU CC.
+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
@@ -21,9 +21,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#ifdef VMS_DEBUGGING_INFO
-#include "system.h"
#include "tree.h"
#include "flags.h"
#include "rtl.h"
@@ -32,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "debug.h"
#include "langhooks.h"
#include "function.h"
+#include "target.h"
/* Difference in seconds between the VMS Epoch and the Unix Epoch */
static const long long vms_epoch_offset = 3506716800ll;
@@ -125,44 +128,43 @@ static unsigned int line_info_table_in_use;
#define LINE_INFO_TABLE_INCREMENT 1024
/* Forward declarations for functions defined in this file. */
-static char *full_name PARAMS ((const char *));
-static unsigned int lookup_filename PARAMS ((const char *));
-static void addr_const_to_string PARAMS ((char *, rtx));
-static int write_debug_header PARAMS ((DST_HEADER *, const char *, int));
-static int write_debug_addr PARAMS ((char *, const char *, int));
-static int write_debug_data1 PARAMS ((unsigned int, const char *, int));
-static int write_debug_data2 PARAMS ((unsigned int, const char *, int));
-static int write_debug_data4 PARAMS ((unsigned long, const char *, int));
-static int write_debug_data8 PARAMS ((unsigned long long, const char *,
- int));
-static int write_debug_delta4 PARAMS ((char *, char *, const char *, int));
-static int write_debug_string PARAMS ((char *, const char *, int));
-static int write_modbeg PARAMS ((int));
-static int write_modend PARAMS ((int));
-static int write_rtnbeg PARAMS ((int, int));
-static int write_rtnend PARAMS ((int, int));
-static int write_pclines PARAMS ((int));
-static int write_srccorr PARAMS ((int, dst_file_info_entry, int));
-static int write_srccorrs PARAMS ((int));
-
-static void vmsdbgout_init PARAMS ((const char *));
-static void vmsdbgout_finish PARAMS ((const char *));
-static void vmsdbgout_define PARAMS ((unsigned int, const char *));
-static void vmsdbgout_undef PARAMS ((unsigned int, const char *));
-static void vmsdbgout_start_source_file PARAMS ((unsigned int, const char *));
-static void vmsdbgout_end_source_file PARAMS ((unsigned int));
-static void vmsdbgout_begin_block PARAMS ((unsigned int, unsigned int));
-static void vmsdbgout_end_block PARAMS ((unsigned int, unsigned int));
-static bool vmsdbgout_ignore_block PARAMS ((tree));
-static void vmsdbgout_source_line PARAMS ((unsigned int, const char *));
-static void vmsdbgout_begin_prologue PARAMS ((unsigned int, const char *));
-static void vmsdbgout_end_prologue PARAMS ((unsigned int, const char *));
-static void vmsdbgout_end_function PARAMS ((unsigned int));
-static void vmsdbgout_end_epilogue PARAMS ((unsigned int, const char *));
-static void vmsdbgout_begin_function PARAMS ((tree));
-static void vmsdbgout_decl PARAMS ((tree));
-static void vmsdbgout_global_decl PARAMS ((tree));
-static void vmsdbgout_abstract_function PARAMS ((tree));
+static char *full_name (const char *);
+static unsigned int lookup_filename (const char *);
+static void addr_const_to_string (char *, rtx);
+static int write_debug_header (DST_HEADER *, const char *, int);
+static int write_debug_addr (char *, const char *, int);
+static int write_debug_data1 (unsigned int, const char *, int);
+static int write_debug_data2 (unsigned int, const char *, int);
+static int write_debug_data4 (unsigned long, const char *, int);
+static int write_debug_data8 (unsigned long long, const char *, int);
+static int write_debug_delta4 (char *, char *, const char *, int);
+static int write_debug_string (char *, const char *, int);
+static int write_modbeg (int);
+static int write_modend (int);
+static int write_rtnbeg (int, int);
+static int write_rtnend (int, int);
+static int write_pclines (int);
+static int write_srccorr (int, dst_file_info_entry, int);
+static int write_srccorrs (int);
+
+static void vmsdbgout_init (const char *);
+static void vmsdbgout_finish (const char *);
+static void vmsdbgout_define (unsigned int, const char *);
+static void vmsdbgout_undef (unsigned int, const char *);
+static void vmsdbgout_start_source_file (unsigned int, const char *);
+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 (tree);
+static void vmsdbgout_source_line (unsigned int, const char *);
+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);
+static void vmsdbgout_end_epilogue (unsigned int, const char *);
+static void vmsdbgout_begin_function (tree);
+static void vmsdbgout_decl (tree);
+static void vmsdbgout_global_decl (tree);
+static void vmsdbgout_abstract_function (tree);
/* The debug hooks structure. */
@@ -186,7 +188,8 @@ const struct gcc_debug_hooks vmsdbg_debug_hooks
vmsdbgout_global_decl,
debug_nothing_tree, /* deferred_inline_function */
vmsdbgout_abstract_function,
- debug_nothing_rtx /* label */
+ debug_nothing_rtx, /* label */
+ debug_nothing_int /* handle_pch */
};
/* Definitions of defaults for assembler-dependent names of various
@@ -349,7 +352,7 @@ static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
#endif
/* This is similar to the default ASM_OUTPUT_ASCII, except that no trailing
- newline is produced. When flag_verbose_asm is asserted, we add commnetary
+ newline is produced. When flag_verbose_asm is asserted, we add commentary
at the end of the line, so we must avoid output of a newline here. */
#ifndef ASM_OUTPUT_DEBUG_STRING
#define ASM_OUTPUT_DEBUG_STRING(FILE,P) \
@@ -378,7 +381,7 @@ static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
macro has the same effect as ASM_OUTPUT_LABELREF, but copies to
a string rather than writing to a file. */
#ifndef ASM_NAME_TO_STRING
-#define ASM_NAME_TO_STRING(STR, NAME) \
+#define ASM_NAME_TO_STRING(STR, NAME) \
do \
{ \
if ((NAME)[0] == '*') \
@@ -399,9 +402,7 @@ static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
directly, because it writes to a file. */
static void
-addr_const_to_string (str, x)
- char *str;
- rtx x;
+addr_const_to_string (char *str, rtx x)
{
char buf1[256];
char buf2[256];
@@ -529,10 +530,7 @@ restart:
nonzero. */
static int
-write_debug_header (header, comment, dosizeonly)
- DST_HEADER *header;
- const char *comment;
- int dosizeonly;
+write_debug_header (DST_HEADER *header, const char *comment, int dosizeonly)
{
if (!dosizeonly)
{
@@ -561,10 +559,7 @@ write_debug_header (header, comment, dosizeonly)
nonzero. */
static int
-write_debug_addr (symbol, comment, dosizeonly)
- char *symbol;
- const char *comment;
- int dosizeonly;
+write_debug_addr (char *symbol, const char *comment, int dosizeonly)
{
if (!dosizeonly)
{
@@ -582,10 +577,7 @@ write_debug_addr (symbol, comment, dosizeonly)
nonzero. */
static int
-write_debug_data1 (data1, comment, dosizeonly)
- unsigned int data1;
- const char *comment;
- int dosizeonly;
+write_debug_data1 (unsigned int data1, const char *comment, int dosizeonly)
{
if (!dosizeonly)
{
@@ -603,10 +595,7 @@ write_debug_data1 (data1, comment, dosizeonly)
nonzero. */
static int
-write_debug_data2 (data2, comment, dosizeonly)
- unsigned int data2;
- const char *comment;
- int dosizeonly;
+write_debug_data2 (unsigned int data2, const char *comment, int dosizeonly)
{
if (!dosizeonly)
{
@@ -623,10 +612,7 @@ write_debug_data2 (data2, comment, dosizeonly)
Return the data size. Just return the size if DOSIZEONLY is nonzero. */
static int
-write_debug_data4 (data4, comment, dosizeonly)
- unsigned long data4;
- const char *comment;
- int dosizeonly;
+write_debug_data4 (unsigned long data4, const char *comment, int dosizeonly)
{
if (!dosizeonly)
{
@@ -643,10 +629,8 @@ write_debug_data4 (data4, comment, dosizeonly)
Return the data size. Just return the size if DOSIZEONLY is nonzero. */
static int
-write_debug_data8 (data8, comment, dosizeonly)
- unsigned long long data8;
- const char *comment;
- int dosizeonly;
+write_debug_data8 (unsigned long long data8, const char *comment,
+ int dosizeonly)
{
if (!dosizeonly)
{
@@ -664,11 +648,8 @@ write_debug_data8 (data8, comment, dosizeonly)
DOSIZEONLY is nonzero. */
static int
-write_debug_delta4 (label1, label2, comment, dosizeonly)
- char *label1;
- char *label2;
- const char *comment;
- int dosizeonly;
+write_debug_delta4 (char *label1, char *label2, const char *comment,
+ int dosizeonly)
{
if (!dosizeonly)
{
@@ -686,10 +667,7 @@ write_debug_delta4 (label1, label2, comment, dosizeonly)
nonzero. */
static int
-write_debug_string (string, comment, dosizeonly)
- char *string;
- const char *comment;
- int dosizeonly;
+write_debug_string (char *string, const char *comment, int dosizeonly)
{
if (!dosizeonly)
{
@@ -706,8 +684,7 @@ write_debug_string (string, comment, dosizeonly)
size if DOSIZEONLY is nonzero. */
static int
-write_modbeg (dosizeonly)
- int dosizeonly;
+write_modbeg (int dosizeonly)
{
DST_MODULE_BEGIN modbeg;
DST_MB_TRLR mb_trlr;
@@ -770,8 +747,7 @@ write_modbeg (dosizeonly)
the size if DOSIZEONLY is nonzero. */
static int
-write_modend (dosizeonly)
- int dosizeonly;
+write_modend (int dosizeonly)
{
DST_MODULE_END modend;
int totsize = 0;
@@ -790,9 +766,7 @@ write_modend (dosizeonly)
Just return the size if DOSIZEONLY is nonzero. */
static int
-write_rtnbeg (rtnnum, dosizeonly)
- int rtnnum;
- int dosizeonly;
+write_rtnbeg (int rtnnum, int dosizeonly)
{
char *rtnname;
int rtnnamelen;
@@ -833,7 +807,7 @@ write_rtnbeg (rtnnum, dosizeonly)
totsize += write_debug_string ((char *) go, "main name", dosizeonly);
}
- /* The header length never includes the length byte */
+ /* The header length never includes the length byte. */
rtnbeg.dst_a_rtnbeg_header.dst__header_length.dst_w_length
= DST_K_RTNBEG_SIZE + rtnnamelen - 1;
rtnbeg.dst_a_rtnbeg_header.dst__header_type.dst_w_type = DST_K_RTNBEG;
@@ -885,9 +859,7 @@ write_rtnbeg (rtnnum, dosizeonly)
Just return the size if DOSIZEONLY is nonzero. */
static int
-write_rtnend (rtnnum, dosizeonly)
- int rtnnum;
- int dosizeonly;
+write_rtnend (int rtnnum, int dosizeonly)
{
DST_ROUTINE_END rtnend;
char label1[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -929,8 +901,7 @@ write_rtnend (rtnnum, dosizeonly)
the size if DOSIZEONLY is nonzero */
static int
-write_pclines (dosizeonly)
- int dosizeonly;
+write_pclines (int dosizeonly)
{
unsigned i;
int fn;
@@ -955,7 +926,7 @@ write_pclines (dosizeonly)
linestart = linestart + ((max_line / 10000) + 1) * 10000;
}
- /* Set starting address to beginning of text section */
+ /* Set starting address to beginning of text section. */
line_num.dst_a_line_num_header.dst__header_length.dst_w_length = 8;
line_num.dst_a_line_num_header.dst__header_type.dst_w_type = DST_K_LINE_NUM;
pcline.dst_b_pcline_command = DST_K_SET_ABS_PC;
@@ -1060,10 +1031,8 @@ write_pclines (dosizeonly)
nonzero. */
static int
-write_srccorr (fileid, file_info_entry, dosizeonly)
- int fileid;
- dst_file_info_entry file_info_entry;
- int dosizeonly;
+write_srccorr (int fileid, dst_file_info_entry file_info_entry,
+ int dosizeonly)
{
int src_command_size;
int linesleft = file_info_entry.max_line;
@@ -1255,8 +1224,7 @@ write_srccorr (fileid, file_info_entry, dosizeonly)
the size if DOSIZEONLY is nonzero. */
static int
-write_srccorrs (dosizeonly)
- int dosizeonly;
+write_srccorrs (int dosizeonly)
{
unsigned int i;
int totsize = 0;
@@ -1271,9 +1239,7 @@ write_srccorrs (dosizeonly)
the prologue. */
static void
-vmsdbgout_begin_prologue (line, file)
- unsigned int line;
- const char *file;
+vmsdbgout_begin_prologue (unsigned int line, const char *file)
{
char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -1292,9 +1258,7 @@ vmsdbgout_begin_prologue (line, file)
the prologue. */
static void
-vmsdbgout_end_prologue (line, file)
- unsigned int line;
- const char *file;
+vmsdbgout_end_prologue (unsigned int line, const char *file)
{
char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -1307,7 +1271,7 @@ vmsdbgout_end_prologue (line, file)
current_function_funcdef_no);
ASM_OUTPUT_LABEL (asm_out_file, label);
- /* VMS PCA expects every PC range to correlate to some line and file */
+ /* VMS PCA expects every PC range to correlate to some line and file. */
vmsdbgout_source_line (line, file);
}
}
@@ -1315,8 +1279,7 @@ vmsdbgout_end_prologue (line, file)
/* No output for VMS debug, but make obligatory call to Dwarf2 debug */
static void
-vmsdbgout_end_function (line)
- unsigned int line;
+vmsdbgout_end_function (unsigned int line)
{
if (write_symbols == VMS_AND_DWARF2_DEBUG)
(*dwarf2_debug_hooks.end_function) (line);
@@ -1327,9 +1290,7 @@ vmsdbgout_end_function (line)
been generated. */
static void
-vmsdbgout_end_epilogue (line, file)
- unsigned int line;
- const char *file;
+vmsdbgout_end_epilogue (unsigned int line, const char *file)
{
char label[MAX_ARTIFICIAL_LABEL_BYTES];
@@ -1344,7 +1305,7 @@ vmsdbgout_end_epilogue (line, file)
current_function_funcdef_no);
ASM_OUTPUT_LABEL (asm_out_file, label);
- /* VMS PCA expects every PC range to correlate to some line and file */
+ /* VMS PCA expects every PC range to correlate to some line and file. */
vmsdbgout_source_line (line, file);
}
}
@@ -1353,37 +1314,32 @@ vmsdbgout_end_epilogue (line, file)
a lexical block. */
static void
-vmsdbgout_begin_block (line, blocknum)
- register unsigned line;
- register unsigned blocknum;
+vmsdbgout_begin_block (register unsigned line, register unsigned blocknum)
{
if (write_symbols == VMS_AND_DWARF2_DEBUG)
(*dwarf2_debug_hooks.begin_block) (line, blocknum);
if (debug_info_level > DINFO_LEVEL_TERSE)
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
+ (*targetm.asm_out.internal_label) (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
}
/* Output a marker (i.e. a label) for the end of the generated code for a
lexical block. */
static void
-vmsdbgout_end_block (line, blocknum)
- register unsigned line;
- register unsigned blocknum;
+vmsdbgout_end_block (register unsigned line, register unsigned blocknum)
{
if (write_symbols == VMS_AND_DWARF2_DEBUG)
(*dwarf2_debug_hooks.end_block) (line, blocknum);
if (debug_info_level > DINFO_LEVEL_TERSE)
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum);
+ (*targetm.asm_out.internal_label) (asm_out_file, BLOCK_END_LABEL, blocknum);
}
/* Not implemented in VMS Debug. */
static bool
-vmsdbgout_ignore_block (block)
- tree block;
+vmsdbgout_ignore_block (tree block)
{
bool retval = 0;
@@ -1396,8 +1352,7 @@ vmsdbgout_ignore_block (block)
/* Add an entry for function DECL into the func_table. */
static void
-vmsdbgout_begin_function (decl)
- tree decl;
+vmsdbgout_begin_function (tree decl)
{
const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
@@ -1407,8 +1362,8 @@ vmsdbgout_begin_function (decl)
if (func_table_in_use == func_table_allocated)
{
func_table_allocated += FUNC_TABLE_INCREMENT;
- func_table = (char **) xrealloc (func_table,
- func_table_allocated * sizeof (char *));
+ func_table = xrealloc (func_table,
+ func_table_allocated * sizeof (char *));
}
/* Add the new entry to the end of the function name table. */
@@ -1421,8 +1376,7 @@ static char fullname_buff [4096];
in VMS syntax in order to be processed by VMS Debug. */
static char *
-full_name (filename)
- const char *filename;
+full_name (const char *filename)
{
#ifdef VMS
FILE *fp = fopen (filename, "r");
@@ -1453,8 +1407,7 @@ full_name (filename)
all searches. */
static unsigned int
-lookup_filename (file_name)
- const char *file_name;
+lookup_filename (const char *file_name)
{
static unsigned int last_file_lookup_index = 0;
register char *fn;
@@ -1473,17 +1426,17 @@ lookup_filename (file_name)
#ifdef VMS
struct tm *ts;
- /* Adjust for GMT */
+ /* Adjust for GMT. */
ts = (struct tm *) localtime (&statbuf.st_ctime);
gmtoff = ts->tm_gmtoff;
- /* VMS has multiple file format types */
+ /* VMS has multiple file format types. */
rfo = statbuf.st_fab_rfm;
#else
/* Is GMT adjustment an issue with a cross-compiler? */
gmtoff = 0;
- /* Assume stream LF type file */
+ /* Assume stream LF type file. */
rfo = 2;
#endif
cdt = 10000000 * (statbuf.st_ctime + gmtoff + vms_epoch_offset);
@@ -1528,10 +1481,9 @@ lookup_filename (file_name)
{
file_info_table_allocated += FILE_TABLE_INCREMENT;
- file_info_table
- = (dst_file_info_ref) xrealloc (file_info_table,
- (file_info_table_allocated
- * sizeof (dst_file_info_entry)));
+ file_info_table = xrealloc (file_info_table,
+ (file_info_table_allocated
+ * sizeof (dst_file_info_entry)));
}
/* Add the new entry to the end of the filename table. */
@@ -1552,9 +1504,7 @@ lookup_filename (file_name)
'line_info_table' for later output of the .debug_line section. */
static void
-vmsdbgout_source_line (line, filename)
- register unsigned line;
- register const char *filename;
+vmsdbgout_source_line (register unsigned line, register const char *filename)
{
if (write_symbols == VMS_AND_DWARF2_DEBUG)
(*dwarf2_debug_hooks.source_line) (line, filename);
@@ -1563,17 +1513,16 @@ vmsdbgout_source_line (line, filename)
{
dst_line_info_ref line_info;
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, LINE_CODE_LABEL,
+ (*targetm.asm_out.internal_label) (asm_out_file, LINE_CODE_LABEL,
line_info_table_in_use);
/* Expand the line info table if necessary. */
if (line_info_table_in_use == line_info_table_allocated)
{
line_info_table_allocated += LINE_INFO_TABLE_INCREMENT;
- line_info_table
- = (dst_line_info_ref) xrealloc (line_info_table,
- (line_info_table_allocated
- * sizeof (dst_line_info_entry)));
+ line_info_table = xrealloc (line_info_table,
+ (line_info_table_allocated
+ * sizeof (dst_line_info_entry)));
}
/* Add the new entry at the end of the line_info_table. */
@@ -1589,9 +1538,7 @@ vmsdbgout_source_line (line, filename)
At present, unimplemented. */
static void
-vmsdbgout_start_source_file (lineno, filename)
- unsigned int lineno;
- const char *filename;
+vmsdbgout_start_source_file (unsigned int lineno, const char *filename)
{
if (write_symbols == VMS_AND_DWARF2_DEBUG)
(*dwarf2_debug_hooks.start_source_file) (lineno, filename);
@@ -1601,8 +1548,7 @@ vmsdbgout_start_source_file (lineno, filename)
At present, unimplemented. */
static void
-vmsdbgout_end_source_file (lineno)
- unsigned int lineno ATTRIBUTE_UNUSED;
+vmsdbgout_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED)
{
if (write_symbols == VMS_AND_DWARF2_DEBUG)
(*dwarf2_debug_hooks.end_source_file) (lineno);
@@ -1611,8 +1557,7 @@ vmsdbgout_end_source_file (lineno)
/* Set up for Debug output at the start of compilation. */
static void
-vmsdbgout_init (main_input_filename)
- const char *main_input_filename;
+vmsdbgout_init (const char *main_input_filename)
{
const char *language_string = lang_hooks.name;
@@ -1627,21 +1572,19 @@ vmsdbgout_init (main_input_filename)
/* Allocate the initial hunk of the file_info_table. */
file_info_table
- = (dst_file_info_ref) xcalloc (FILE_TABLE_INCREMENT,
- sizeof (dst_file_info_entry));
+ = xcalloc (FILE_TABLE_INCREMENT, sizeof (dst_file_info_entry));
file_info_table_allocated = FILE_TABLE_INCREMENT;
/* Skip the first entry - file numbers begin at 1 */
file_info_table_in_use = 1;
- func_table = (char **) xcalloc (FUNC_TABLE_INCREMENT, sizeof (char *));
+ func_table = xcalloc (FUNC_TABLE_INCREMENT, sizeof (char *));
func_table_allocated = FUNC_TABLE_INCREMENT;
func_table_in_use = 1;
/* Allocate the initial hunk of the line_info_table. */
line_info_table
- = (dst_line_info_ref) xcalloc (LINE_INFO_TABLE_INCREMENT,
- sizeof (dst_line_info_entry));
+ = xcalloc (LINE_INFO_TABLE_INCREMENT, sizeof (dst_line_info_entry));
line_info_table_allocated = LINE_INFO_TABLE_INCREMENT;
/* zero-th entry is allocated, but unused */
line_info_table_in_use = 1;
@@ -1668,9 +1611,7 @@ vmsdbgout_init (main_input_filename)
/* Not implemented in VMS Debug. */
static void
-vmsdbgout_define (lineno, buffer)
- unsigned int lineno;
- const char *buffer;
+vmsdbgout_define (unsigned int lineno, const char *buffer)
{
if (write_symbols == VMS_AND_DWARF2_DEBUG)
(*dwarf2_debug_hooks.define) (lineno, buffer);
@@ -1679,9 +1620,7 @@ vmsdbgout_define (lineno, buffer)
/* Not implemented in VMS Debug. */
static void
-vmsdbgout_undef (lineno, buffer)
- unsigned int lineno;
- const char *buffer;
+vmsdbgout_undef (unsigned int lineno, const char *buffer)
{
if (write_symbols == VMS_AND_DWARF2_DEBUG)
(*dwarf2_debug_hooks.undef) (lineno, buffer);
@@ -1690,8 +1629,7 @@ vmsdbgout_undef (lineno, buffer)
/* Not implemented in VMS Debug. */
static void
-vmsdbgout_decl (decl)
- tree decl;
+vmsdbgout_decl (tree decl)
{
if (write_symbols == VMS_AND_DWARF2_DEBUG)
(*dwarf2_debug_hooks.function_decl) (decl);
@@ -1700,8 +1638,7 @@ vmsdbgout_decl (decl)
/* Not implemented in VMS Debug. */
static void
-vmsdbgout_global_decl (decl)
- tree decl;
+vmsdbgout_global_decl (tree decl)
{
if (write_symbols == VMS_AND_DWARF2_DEBUG)
(*dwarf2_debug_hooks.global_decl) (decl);
@@ -1710,8 +1647,7 @@ vmsdbgout_global_decl (decl)
/* Not implemented in VMS Debug. */
static void
-vmsdbgout_abstract_function (decl)
- tree decl;
+vmsdbgout_abstract_function (tree decl)
{
if (write_symbols == VMS_AND_DWARF2_DEBUG)
(*dwarf2_debug_hooks.outlining_inline_function) (decl);
@@ -1721,21 +1657,20 @@ vmsdbgout_abstract_function (decl)
VMS Debug debugging info. */
static void
-vmsdbgout_finish (input_filename)
- const char *input_filename ATTRIBUTE_UNUSED;
+vmsdbgout_finish (const char *main_input_filename ATTRIBUTE_UNUSED)
{
unsigned int i;
int totsize;
if (write_symbols == VMS_AND_DWARF2_DEBUG)
- (*dwarf2_debug_hooks.finish) (input_filename);
+ (*dwarf2_debug_hooks.finish) (main_input_filename);
if (debug_info_level == DINFO_LEVEL_NONE)
return;
/* Output a terminator label for the .text section. */
text_section ();
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, TEXT_END_LABEL, 0);
+ (*targetm.asm_out.internal_label) (asm_out_file, TEXT_END_LABEL, 0);
/* Output debugging information.
Warning! Do not change the name of the .vmsdebug section without
diff --git a/contrib/gcc/web.c b/contrib/gcc/web.c
new file mode 100644
index 000000000000..e846ee1d2fc7
--- /dev/null
+++ b/contrib/gcc/web.c
@@ -0,0 +1,306 @@
+/* Web construction code for GNU compiler.
+ Contributed by Jan Hubicka.
+ Copyright (C) 2001, 2002 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 2, 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 COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+/* Simple optimization pass that splits independent uses of each pseudo,
+ increasing effectiveness of other optimizations. The optimization can
+ serve as an example of use for the dataflow module.
+
+ We don't split registers with REG_USERVAR set unless -fmessy-debugging
+ is specified, because debugging information about such split variables
+ is almost unusable.
+
+ TODO
+ - Add code to keep debugging up-to-date after splitting user variable
+ pseudos. This can be done by keeping track of all the pseudos used
+ for the variable and using life analysis information before reload
+ to determine which one is live and, in case more than one are live,
+ choose the one with the latest definition.
+
+ Other optimization passes can benefit from the infrastructure too.
+
+ - We may use profile information and ignore infrequent use for the
+ purpose of web unifying, inserting the compensation code later to
+ implement full induction variable expansion for loops (currently
+ we expand only if the induction variable is dead afterward, which
+ is often the case). */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "toplev.h"
+
+#include "rtl.h"
+#include "hard-reg-set.h"
+#include "flags.h"
+#include "basic-block.h"
+#include "output.h"
+#include "df.h"
+#include "function.h"
+
+
+/* This entry is allocated for each reference in the insn stream. */
+struct web_entry
+{
+ /* Pointer to the parent in the union/find tree. */
+ struct web_entry *pred;
+ /* Newly assigned register to the entry. Set only for roots. */
+ rtx reg;
+};
+
+static struct web_entry *unionfind_root (struct web_entry *);
+static void unionfind_union (struct web_entry *, struct web_entry *);
+static void union_defs (struct df *, struct ref *, struct web_entry *,
+ struct web_entry *);
+static rtx entry_register (struct web_entry *, struct ref *, char *, char *);
+static void replace_ref (struct ref *, rtx);
+static int mark_addressof (rtx *, void *);
+
+/* Find the root of unionfind tree (the representative of set). */
+
+static struct web_entry *
+unionfind_root (struct web_entry *element)
+{
+ struct web_entry *element1 = element, *element2;
+
+ while (element->pred)
+ element = element->pred;
+ while (element1->pred)
+ {
+ element2 = element1->pred;
+ element1->pred = element;
+ element1 = element2;
+ }
+ return element;
+}
+
+/* Union sets. */
+
+static void
+unionfind_union (struct web_entry *first, struct web_entry *second)
+{
+ first = unionfind_root (first);
+ second = unionfind_root (second);
+ if (first == second)
+ return;
+ second->pred = first;
+}
+
+/* For each use, all possible defs reaching it must come in the same
+ register, union them. */
+
+static void
+union_defs (struct df *df, struct ref *use, struct web_entry *def_entry,
+ struct web_entry *use_entry)
+{
+ rtx insn = DF_REF_INSN (use);
+ struct df_link *link = DF_REF_CHAIN (use);
+ struct df_link *use_link = DF_INSN_USES (df, insn);
+ struct df_link *def_link = DF_INSN_DEFS (df, insn);
+ rtx set = single_set (insn);
+
+ /* Some instructions may use match_dup for their operands. In case the
+ operands are dead, we will assign them different pseudos, creating
+ invalid instructions, so union all uses of the same operand for each
+ insn. */
+
+ while (use_link)
+ {
+ if (use != use_link->ref
+ && DF_REF_REAL_REG (use) == DF_REF_REAL_REG (use_link->ref))
+ unionfind_union (use_entry + DF_REF_ID (use),
+ use_entry + DF_REF_ID (use_link->ref));
+ use_link = use_link->next;
+ }
+
+ /* Recognize trivial noop moves and attempt to keep them as noop.
+ While most of noop moves should be removed, we still keep some
+ of them at libcall boundaries and such. */
+
+ if (set
+ && SET_SRC (set) == DF_REF_REG (use)
+ && SET_SRC (set) == SET_DEST (set))
+ {
+ while (def_link)
+ {
+ if (DF_REF_REAL_REG (use) == DF_REF_REAL_REG (def_link->ref))
+ unionfind_union (use_entry + DF_REF_ID (use),
+ def_entry + DF_REF_ID (def_link->ref));
+ def_link = def_link->next;
+ }
+ }
+ while (link)
+ {
+ unionfind_union (use_entry + DF_REF_ID (use),
+ def_entry + DF_REF_ID (link->ref));
+ link = link->next;
+ }
+
+ /* A READ_WRITE use requires the corresponding def to be in the same
+ register. Find it and union. */
+ if (use->flags & DF_REF_READ_WRITE)
+ {
+ struct df_link *link = DF_INSN_DEFS (df, DF_REF_INSN (use));
+
+ while (DF_REF_REAL_REG (link->ref) != DF_REF_REAL_REG (use))
+ link = link->next;
+
+ unionfind_union (use_entry + DF_REF_ID (use),
+ def_entry + DF_REF_ID (link->ref));
+ }
+}
+
+/* Find the corresponding register for the given entry. */
+
+static rtx
+entry_register (struct web_entry *entry, struct ref *ref, char *used,
+ char *use_addressof)
+{
+ struct web_entry *root;
+ rtx reg, newreg;
+
+ /* Find the corresponding web and see if it has been visited. */
+ root = unionfind_root (entry);
+ if (root->reg)
+ return root->reg;
+
+ /* We are seeing this web for the first time, do the assignment. */
+ reg = DF_REF_REAL_REG (ref);
+
+ /* In case the original register is already assigned, generate new one. */
+ if (!used[REGNO (reg)])
+ newreg = reg, used[REGNO (reg)] = 1;
+ else if (REG_USERVAR_P (reg) && 0/*&& !flag_messy_debugging*/)
+ {
+ newreg = reg;
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "New web forced to keep reg=%i (user variable)\n",
+ REGNO (reg));
+ }
+ else if (use_addressof [REGNO (reg)])
+ {
+ newreg = reg;
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "New web forced to keep reg=%i (address taken)\n",
+ REGNO (reg));
+ }
+ else
+ {
+ newreg = gen_reg_rtx (GET_MODE (reg));
+ REG_USERVAR_P (newreg) = REG_USERVAR_P (reg);
+ REG_POINTER (newreg) = REG_POINTER (reg);
+ REG_LOOP_TEST_P (newreg) = REG_LOOP_TEST_P (reg);
+ RTX_UNCHANGING_P (newreg) = RTX_UNCHANGING_P (reg);
+ REG_ATTRS (newreg) = REG_ATTRS (reg);
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Web oldreg=%i newreg=%i\n", REGNO (reg),
+ REGNO (newreg));
+ }
+
+ root->reg = newreg;
+ return newreg;
+}
+
+/* Replace the reference by REG. */
+
+static void
+replace_ref (struct ref *ref, rtx reg)
+{
+ rtx oldreg = DF_REF_REAL_REG (ref);
+ rtx *loc = DF_REF_REAL_LOC (ref);
+
+ if (oldreg == reg)
+ return;
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Updating insn %i (%i->%i)\n",
+ INSN_UID (DF_REF_INSN (ref)), REGNO (oldreg), REGNO (reg));
+ *loc = reg;
+}
+
+/* Mark each pseudo whose address is taken. */
+
+static int
+mark_addressof (rtx *rtl, void *data)
+{
+ if (!*rtl)
+ return 0;
+ if (GET_CODE (*rtl) == ADDRESSOF
+ && REG_P (XEXP (*rtl, 0)))
+ ((char *)data)[REGNO (XEXP (*rtl, 0))] = 1;
+ return 0;
+}
+
+/* Main entry point. */
+
+void
+web_main (void)
+{
+ struct df *df;
+ struct web_entry *def_entry;
+ struct web_entry *use_entry;
+ unsigned int i;
+ int max = max_reg_num ();
+ char *used;
+ char *use_addressof;
+ rtx insn;
+
+ df = df_init ();
+ df_analyse (df, 0, DF_UD_CHAIN | DF_EQUIV_NOTES);
+
+ def_entry =
+ (struct web_entry *) xcalloc (df->n_defs, sizeof (struct web_entry));
+ use_entry =
+ (struct web_entry *) xcalloc (df->n_uses, sizeof (struct web_entry));
+ used = (char *) xcalloc (max, sizeof (char));
+ use_addressof = (char *) xcalloc (max, sizeof (char));
+
+ if (rtl_dump_file)
+ df_dump (df, DF_UD_CHAIN | DF_DU_CHAIN, rtl_dump_file);
+
+ /* Produce the web. */
+ for (i = 0; i < df->n_uses; i++)
+ union_defs (df, df->uses[i], def_entry, use_entry);
+
+ /* We can not safely rename registers whose address is taken. */
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ for_each_rtx (&PATTERN (insn), mark_addressof, use_addressof);
+
+ /* Update the instruction stream, allocating new registers for split pseudos
+ in progress. */
+ for (i = 0; i < df->n_uses; i++)
+ replace_ref (df->uses[i], entry_register (use_entry + i, df->uses[i],
+ used, use_addressof));
+ for (i = 0; i < df->n_defs; i++)
+ replace_ref (df->defs[i], entry_register (def_entry + i, df->defs[i],
+ used, use_addressof));
+
+ /* Dataflow information is corrupt here, but it can be easily updated
+ by creating new entries for new registers and updates or calling
+ df_insns_modify. */
+ free (def_entry);
+ free (use_entry);
+ free (used);
+ free (use_addressof);
+ df_finish (df);
+}
diff --git a/contrib/gcc/xcoff.h b/contrib/gcc/xcoff.h
new file mode 100644
index 000000000000..2d003fed3bb3
--- /dev/null
+++ b/contrib/gcc/xcoff.h
@@ -0,0 +1,17 @@
+/* Storage classes in XCOFF object file format designed for DBX's use.
+ This info is from the `Files Reference' manual for IBM's AIX version 3
+ for the RS6000. */
+
+#define C_GSYM 0x80
+#define C_LSYM 0x81
+#define C_PSYM 0x82
+#define C_RSYM 0x83
+#define C_RPSYM 0x84
+#define C_STSYM 0x85
+
+#define C_BCOMM 0x87
+#define C_ECOML 0x88
+#define C_ECOMM 0x89
+#define C_DECL 0x8c
+#define C_ENTRY 0x8d
+#define C_FUN 0x8e
diff --git a/contrib/gcc/xcoffout.c b/contrib/gcc/xcoffout.c
index 528bd7cf6c98..324c5d5fa5b6 100644
--- a/contrib/gcc/xcoffout.c
+++ b/contrib/gcc/xcoffout.c
@@ -1,5 +1,5 @@
/* Output xcoff-format symbol table information from GNU compiler.
- Copyright (C) 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002
+ Copyright (C) 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003
Free Software Foundation, Inc.
This file is part of GCC.
@@ -26,6 +26,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "flags.h"
@@ -37,7 +39,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifdef XCOFF_DEBUGGING_INFO
/* This defines the C_* storage classes. */
-#include "dbxstclass.h"
+#include "xcoff.h"
#include "xcoffout.h"
#include "dbxout.h"
#include "gstab.h"
@@ -76,7 +78,7 @@ const char *xcoff_lastfile;
((xcoff_inlining) ? (LINENO) : (LINENO) - xcoff_begin_function_line)
/* Output source line numbers via ".line" rather than ".stabd". */
-#define ASM_OUTPUT_SOURCE_LINE(FILE,LINENUM) \
+#define ASM_OUTPUT_SOURCE_LINE(FILE,LINENUM,COUNTER) \
do \
{ \
if (xcoff_begin_function_line >= 0) \
@@ -96,7 +98,7 @@ const char *xcoff_lastfile;
? xcoff_current_include_file : main_input_filename); \
}
-#define ASM_OUTPUT_LFE(FILE,LINENUM) \
+#define ASM_OUTPUT_LFE(FILE,LINENUM) \
do \
{ \
fprintf (FILE, "\t.ef\t%d\n", (LINENUM)); \
@@ -110,9 +112,9 @@ const char *xcoff_lastfile;
#define ASM_OUTPUT_LBE(FILE,LINENUM,BLOCKNUM) \
fprintf (FILE, "\t.eb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM))
-static void assign_type_number PARAMS ((tree, const char *, int));
-static void xcoffout_block PARAMS ((tree, int, tree));
-static void xcoffout_source_file PARAMS ((FILE *, const char *, int));
+static void assign_type_number (tree, const char *, int);
+static void xcoffout_block (tree, int, tree);
+static void xcoffout_source_file (FILE *, const char *, int);
/* Support routines for XCOFF debugging info. */
@@ -120,10 +122,7 @@ static void xcoffout_source_file PARAMS ((FILE *, const char *, int));
Search all decls in the list SYMS to find the type NAME. */
static void
-assign_type_number (syms, name, number)
- tree syms;
- const char *name;
- int number;
+assign_type_number (tree syms, const char *name, int number)
{
tree decl;
@@ -140,8 +139,7 @@ assign_type_number (syms, name, number)
possible. */
void
-xcoff_output_standard_types (syms)
- tree syms;
+xcoff_output_standard_types (tree syms)
{
/* Handle built-in C types here. */
@@ -177,8 +175,7 @@ xcoff_output_standard_types (syms)
/* Conversion routine from BSD stabs to AIX storage classes. */
int
-stab_to_sclass (stab)
- int stab;
+stab_to_sclass (int stab)
{
switch (stab)
{
@@ -280,10 +277,7 @@ stab_to_sclass (stab)
INLINE_P is true if this is from an inlined function. */
static void
-xcoffout_source_file (file, filename, inline_p)
- FILE *file;
- const char *filename;
- int inline_p;
+xcoffout_source_file (FILE *file, const char *filename, int inline_p)
{
if (filename
&& (xcoff_lastfile == 0 || strcmp (filename, xcoff_lastfile)
@@ -312,16 +306,14 @@ xcoffout_source_file (file, filename, inline_p)
/* Output a line number symbol entry for location (FILENAME, LINE). */
void
-xcoffout_source_line (line, filename)
- unsigned int line;
- const char *filename;
+xcoffout_source_line (unsigned int line, const char *filename)
{
bool inline_p = (strcmp (xcoff_current_function_file, filename) != 0
|| (int) line < xcoff_begin_function_line);
xcoffout_source_file (asm_out_file, filename, inline_p);
- ASM_OUTPUT_SOURCE_LINE (asm_out_file, line);
+ ASM_OUTPUT_SOURCE_LINE (asm_out_file, line, 0);
}
/* Output the symbols defined in block number DO_BLOCK.
@@ -332,10 +324,7 @@ xcoffout_source_line (line, filename)
static int do_block = 0;
static void
-xcoffout_block (block, depth, args)
- tree block;
- int depth;
- tree args;
+xcoffout_block (tree block, int depth, tree args)
{
while (block)
{
@@ -374,9 +363,7 @@ xcoffout_block (block, depth, args)
if the count starts at 0 for the outermost one. */
void
-xcoffout_begin_block (line, n)
- unsigned int line;
- unsigned int n;
+xcoffout_begin_block (unsigned int line, unsigned int n)
{
tree decl = current_function_decl;
@@ -392,9 +379,7 @@ xcoffout_begin_block (line, n)
/* Describe the end line-number of an internal block within a function. */
void
-xcoffout_end_block (line, n)
- unsigned int line;
- unsigned int n;
+xcoffout_end_block (unsigned int line, unsigned int n)
{
if (n != 1)
ASM_OUTPUT_LBE (asm_out_file, line, n);
@@ -404,10 +389,7 @@ xcoffout_end_block (line, n)
Declare function as needed for debugging. */
void
-xcoffout_declare_function (file, decl, name)
- FILE *file;
- tree decl;
- const char *name;
+xcoffout_declare_function (FILE *file, tree decl, const char *name)
{
int i;
@@ -418,7 +400,7 @@ xcoffout_declare_function (file, decl, name)
{
if (name[i] == '[')
{
- char *n = (char *) alloca (i + 1);
+ char *n = alloca (i + 1);
strncpy (n, name, i);
n[i] = '\0';
name = n;
@@ -444,9 +426,8 @@ xcoffout_declare_function (file, decl, name)
Record the file name that this function is contained in. */
void
-xcoffout_begin_prologue (line, file)
- unsigned int line;
- const char *file ATTRIBUTE_UNUSED;
+xcoffout_begin_prologue (unsigned int line,
+ const char *file ATTRIBUTE_UNUSED)
{
ASM_OUTPUT_LFB (asm_out_file, line);
dbxout_parms (DECL_ARGUMENTS (current_function_decl));
@@ -459,15 +440,14 @@ xcoffout_begin_prologue (line, file)
xcoffout_block (DECL_INITIAL (current_function_decl), 0,
DECL_ARGUMENTS (current_function_decl));
- ASM_OUTPUT_SOURCE_LINE (asm_out_file, line);
+ ASM_OUTPUT_SOURCE_LINE (asm_out_file, line, 0);
}
/* Called at end of function (before epilogue).
Describe end of outermost block. */
void
-xcoffout_end_function (last_linenum)
- unsigned int last_linenum;
+xcoffout_end_function (unsigned int last_linenum)
{
ASM_OUTPUT_LFE (asm_out_file, last_linenum);
}
@@ -476,9 +456,8 @@ xcoffout_end_function (last_linenum)
Called after the epilogue is output. */
void
-xcoffout_end_epilogue (line, file)
- unsigned int line ATTRIBUTE_UNUSED;
- const char *file ATTRIBUTE_UNUSED;
+xcoffout_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
+ const char *file ATTRIBUTE_UNUSED)
{
/* We need to pass the correct function size to .function, otherwise,
the xas assembler can't figure out the correct size for the function
diff --git a/contrib/gcc/xcoffout.h b/contrib/gcc/xcoffout.h
index dd630c937499..2b830484febf 100644
--- a/contrib/gcc/xcoffout.h
+++ b/contrib/gcc/xcoffout.h
@@ -1,6 +1,7 @@
/* XCOFF definitions. These are needed in dbxout.c, final.c,
and xcoffout.h.
- Copyright (C) 1998, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2000, 2002, 2003
+ Free Software Foundation, Inc.
This file is part of GCC.
@@ -138,8 +139,8 @@ extern const char *xcoff_lastfile;
/* Write out main source file name using ".file" rather than ".stabs".
We don't actually do this here, because the assembler gets confused if there
- is more than one .file directive. ASM_FILE_START in config/rs6000/rs6000.h
- is already emitting a .file directory, so we don't output one here also.
+ is more than one .file directive. rs6000_xcoff_file_start is already
+ emitting a .file directory, so we don't output one here also.
Initialize xcoff_lastfile. */
#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(FILE,FILENAME) \
xcoff_lastfile = (FILENAME)
@@ -181,27 +182,24 @@ extern const char *xcoff_lastfile;
/* Prototype functions in xcoffout.c. */
-extern int stab_to_sclass PARAMS ((int));
+extern int stab_to_sclass (int);
#ifdef BUFSIZ
-extern void xcoffout_begin_prologue PARAMS ((unsigned int,
- const char *));
-extern void xcoffout_begin_block PARAMS ((unsigned, unsigned));
-extern void xcoffout_end_epilogue PARAMS ((unsigned int,
- const char *));
-extern void xcoffout_end_function PARAMS ((unsigned int));
-extern void xcoffout_end_block PARAMS ((unsigned, unsigned));
+extern void xcoffout_begin_prologue (unsigned int, const char *);
+extern void xcoffout_begin_block (unsigned, unsigned);
+extern void xcoffout_end_epilogue (unsigned int, const char *);
+extern void xcoffout_end_function (unsigned int);
+extern void xcoffout_end_block (unsigned, unsigned);
#endif /* BUFSIZ */
#ifdef TREE_CODE
-extern void xcoff_output_standard_types PARAMS ((tree));
+extern void xcoff_output_standard_types (tree);
#ifdef BUFSIZ
-extern void xcoffout_declare_function PARAMS ((FILE *, tree, const char *));
+extern void xcoffout_declare_function (FILE *, tree, const char *);
#endif /* BUFSIZ */
#endif /* TREE_CODE */
#ifdef RTX_CODE
#ifdef BUFSIZ
-extern void xcoffout_source_line PARAMS ((unsigned int,
- const char *));
+extern void xcoffout_source_line (unsigned int, const char *);
#endif /* BUFSIZ */
#endif /* RTX_CODE */
diff --git a/contrib/gcc/xexit.c b/contrib/gcc/xexit.c
new file mode 100644
index 000000000000..a65690f09c30
--- /dev/null
+++ b/contrib/gcc/xexit.c
@@ -0,0 +1,53 @@
+/* xexit.c -- Run any exit handlers, then exit.
+ Copyright (C) 1994, 95, 1997 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If not, write
+to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/*
+
+@deftypefn Replacement void xexit (int @var{code})
+
+Terminates the program. If any functions have been registered with
+the @code{xatexit} replacement function, they will be called first.
+Termination is handled via the system's normal @code{exit} call.
+
+@end deftypefn
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include "libiberty.h"
+
+
+/* This variable is set by xatexit if it is called. This way, xmalloc
+ doesn't drag xatexit into the link. */
+void (*_xexit_cleanup) PARAMS ((void));
+
+void
+xexit (code)
+ int code;
+{
+ if (_xexit_cleanup != NULL)
+ (*_xexit_cleanup) ();
+ exit (code);
+}
diff --git a/contrib/gcc/xmalloc.c b/contrib/gcc/xmalloc.c
new file mode 100644
index 000000000000..c3fe1a84f4d2
--- /dev/null
+++ b/contrib/gcc/xmalloc.c
@@ -0,0 +1,183 @@
+/* memory allocation routines with error checking.
+ Copyright 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/*
+
+@deftypefn Replacement void* xmalloc (size_t)
+
+Allocate memory without fail. If @code{malloc} fails, this will print
+a message to @code{stderr} (using the name set by
+@code{xmalloc_set_program_name},
+if any) and then call @code{xexit}. Note that it is therefore safe for
+a program to contain @code{#define malloc xmalloc} in its source.
+
+@end deftypefn
+
+@deftypefn Replacement void* xrealloc (void *@var{ptr}, size_t @var{size})
+Reallocate memory without fail. This routine functions like @code{realloc},
+but will behave the same as @code{xmalloc} if memory cannot be found.
+
+@end deftypefn
+
+@deftypefn Replacement void* xcalloc (size_t @var{nelem}, size_t @var{elsize})
+
+Allocate memory without fail, and set it to zero. This routine functions
+like @code{calloc}, but will behave the same as @code{xmalloc} if memory
+cannot be found.
+
+@end deftypefn
+
+@deftypefn Replacement void xmalloc_set_program_name (const char *@var{name})
+
+You can use this to set the name of the program used by
+@code{xmalloc_failed} when printing a failure message.
+
+@end deftypefn
+
+@deftypefn Replacement void xmalloc_failed (size_t)
+
+This function is not meant to be called by client code, and is listed
+here for completeness only. If any of the allocation routines fail, this
+function will be called to print an error message and terminate execution.
+
+@end deftypefn
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#include <stdio.h>
+
+#ifdef ANSI_PROTOTYPES
+#include <stddef.h>
+#else
+#define size_t unsigned long
+#define ptrdiff_t long
+#endif
+
+#if VMS
+#include <stdlib.h>
+#include <unixlib.h>
+#else
+/* For systems with larger pointers than ints, these must be declared. */
+PTR malloc PARAMS ((size_t));
+PTR realloc PARAMS ((PTR, size_t));
+PTR calloc PARAMS ((size_t, size_t));
+PTR sbrk PARAMS ((ptrdiff_t));
+#endif
+
+/* The program name if set. */
+static const char *name = "";
+
+#ifdef HAVE_SBRK
+/* The initial sbrk, set when the program name is set. Not used for win32
+ ports other than cygwin32. */
+static char *first_break = NULL;
+#endif /* HAVE_SBRK */
+
+void
+xmalloc_set_program_name (s)
+ const char *s;
+{
+ name = s;
+#ifdef HAVE_SBRK
+ /* Win32 ports other than cygwin32 don't have brk() */
+ if (first_break == NULL)
+ first_break = (char *) sbrk (0);
+#endif /* HAVE_SBRK */
+}
+
+void
+xmalloc_failed (size)
+ size_t size;
+{
+#ifdef HAVE_SBRK
+ extern char **environ;
+ size_t allocated;
+
+ if (first_break != NULL)
+ allocated = (char *) sbrk (0) - first_break;
+ else
+ allocated = (char *) sbrk (0) - (char *) &environ;
+ fprintf (stderr,
+ "\n%s%sout of memory allocating %lu bytes after a total of %lu bytes\n",
+ name, *name ? ": " : "",
+ (unsigned long) size, (unsigned long) allocated);
+#else /* HAVE_SBRK */
+ fprintf (stderr,
+ "\n%s%sout of memory allocating %lu bytes\n",
+ name, *name ? ": " : "",
+ (unsigned long) size);
+#endif /* HAVE_SBRK */
+ xexit (1);
+}
+
+PTR
+xmalloc (size)
+ size_t size;
+{
+ PTR newmem;
+
+ if (size == 0)
+ size = 1;
+ newmem = malloc (size);
+ if (!newmem)
+ xmalloc_failed (size);
+
+ return (newmem);
+}
+
+PTR
+xcalloc (nelem, elsize)
+ size_t nelem, elsize;
+{
+ PTR newmem;
+
+ if (nelem == 0 || elsize == 0)
+ nelem = elsize = 1;
+
+ newmem = calloc (nelem, elsize);
+ if (!newmem)
+ xmalloc_failed (nelem * elsize);
+
+ return (newmem);
+}
+
+PTR
+xrealloc (oldmem, size)
+ PTR oldmem;
+ size_t size;
+{
+ PTR newmem;
+
+ if (size == 0)
+ size = 1;
+ if (!oldmem)
+ newmem = malloc (size);
+ else
+ newmem = realloc (oldmem, size);
+ if (!newmem)
+ xmalloc_failed (size);
+
+ return (newmem);
+}
diff --git a/contrib/gcc/xstrdup.c b/contrib/gcc/xstrdup.c
new file mode 100644
index 000000000000..5aa084a76879
--- /dev/null
+++ b/contrib/gcc/xstrdup.c
@@ -0,0 +1,34 @@
+/* xstrdup.c -- Duplicate a string in memory, using xmalloc.
+ This trivial function is in the public domain.
+ Ian Lance Taylor, Cygnus Support, December 1995. */
+
+/*
+
+@deftypefn Replacement char* xstrdup (const char *@var{s})
+
+Duplicates a character string without fail, using @code{xmalloc} to
+obtain memory.
+
+@end deftypefn
+
+*/
+
+#include <sys/types.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#include "ansidecl.h"
+#include "libiberty.h"
+
+char *
+xstrdup (s)
+ const char *s;
+{
+ register size_t len = strlen (s) + 1;
+ register char *ret = xmalloc (len);
+ memcpy (ret, s, len);
+ return ret;
+}
diff --git a/contrib/gcc/xstrerror.c b/contrib/gcc/xstrerror.c
new file mode 100644
index 000000000000..9000d178f9c2
--- /dev/null
+++ b/contrib/gcc/xstrerror.c
@@ -0,0 +1,67 @@
+/* xstrerror.c -- jacket routine for more robust strerror() usage.
+ Fri Jun 16 18:30:00 1995 Pat Rankin <rankin@eql.caltech.edu>
+ This code is in the public domain. */
+
+/*
+
+@deftypefn Replacement char* xstrerror (int @var{errnum})
+
+Behaves exactly like the standard @code{strerror} function, but
+will never return a @code{NULL} pointer.
+
+@end deftypefn
+
+*/
+
+#include <stdio.h>
+
+#include "libiberty.h"
+#include "config.h"
+
+#ifdef VMS
+#include <errno.h>
+#if !defined (__STRICT_ANSI__) && !defined (__HIDE_FORBIDDEN_NAMES)
+extern char *strerror PARAMS ((int,...));
+#define DONT_DECLARE_STRERROR
+#endif
+#endif /* VMS */
+
+#ifndef DONT_DECLARE_STRERROR
+extern char *strerror PARAMS ((int));
+#endif
+
+/* If strerror returns NULL, we'll format the number into a static buffer. */
+
+#define ERRSTR_FMT "undocumented error #%d"
+static char xstrerror_buf[sizeof ERRSTR_FMT + 20];
+
+/* Like strerror, but result is never a null pointer. */
+
+char *
+xstrerror (errnum)
+ int errnum;
+{
+ char *errstr;
+#ifdef VMS
+ char *(*vmslib_strerror) PARAMS ((int,...));
+
+ /* Override any possibly-conflicting declaration from system header. */
+ vmslib_strerror = (char *(*) PARAMS ((int,...))) strerror;
+ /* Second argument matters iff first is EVMSERR, but it's simpler to
+ pass it unconditionally. `vaxc$errno' is declared in <errno.h>
+ and maintained by the run-time library in parallel to `errno'.
+ We assume that `errnum' corresponds to the last value assigned to
+ errno by the run-time library, hence vaxc$errno will be relevant. */
+ errstr = (*vmslib_strerror) (errnum, vaxc$errno);
+#else
+ errstr = strerror (errnum);
+#endif
+
+ /* If `errnum' is out of range, result might be NULL. We'll fix that. */
+ if (!errstr)
+ {
+ sprintf (xstrerror_buf, ERRSTR_FMT, errnum);
+ errstr = xstrerror_buf;
+ }
+ return errstr;
+}